1010#include "mpi3mr.h"
1111#include <linux/io-64-nonatomic-lo-hi.h>
1212
13+ static int
14+ mpi3mr_issue_reset (struct mpi3mr_ioc * mrioc , u16 reset_type , u32 reset_reason );
15+ static int mpi3mr_setup_admin_qpair (struct mpi3mr_ioc * mrioc );
16+
1317#if defined(writeq ) && defined(CONFIG_64BIT )
1418static inline void mpi3mr_writeq (__u64 b , volatile void __iomem * addr )
1519{
@@ -992,26 +996,105 @@ static int mpi3mr_issue_and_process_mur(struct mpi3mr_ioc *mrioc,
992996 * Set Enable IOC bit in IOC configuration register and wait for
993997 * the controller to become ready.
994998 *
995- * Return: 0 on success, -1 on failure.
999+ * Return: 0 on success, appropriate error on failure.
9961000 */
9971001static int mpi3mr_bring_ioc_ready (struct mpi3mr_ioc * mrioc )
9981002{
999- u32 ioc_config , timeout ;
1000- enum mpi3mr_iocstate current_state ;
1003+ u32 ioc_config , ioc_status , timeout ;
1004+ int retval = 0 ;
1005+ enum mpi3mr_iocstate ioc_state ;
1006+ u64 base_info ;
10011007
1008+ ioc_status = readl (& mrioc -> sysif_regs -> ioc_status );
1009+ ioc_config = readl (& mrioc -> sysif_regs -> ioc_configuration );
1010+ base_info = lo_hi_readq (& mrioc -> sysif_regs -> ioc_information );
1011+ ioc_info (mrioc , "ioc_status(0x%08x), ioc_config(0x%08x), ioc_info(0x%016llx) at the bringup\n" ,
1012+ ioc_status , ioc_config , base_info );
1013+
1014+ /*The timeout value is in 2sec unit, changing it to seconds*/
1015+ mrioc -> ready_timeout =
1016+ ((base_info & MPI3_SYSIF_IOC_INFO_LOW_TIMEOUT_MASK ) >>
1017+ MPI3_SYSIF_IOC_INFO_LOW_TIMEOUT_SHIFT ) * 2 ;
1018+
1019+ ioc_info (mrioc , "ready timeout: %d seconds\n" , mrioc -> ready_timeout );
1020+
1021+ ioc_state = mpi3mr_get_iocstate (mrioc );
1022+ ioc_info (mrioc , "controller is in %s state during detection\n" ,
1023+ mpi3mr_iocstate_name (ioc_state ));
1024+
1025+ if (ioc_state == MRIOC_STATE_BECOMING_READY ||
1026+ ioc_state == MRIOC_STATE_RESET_REQUESTED ) {
1027+ timeout = mrioc -> ready_timeout * 10 ;
1028+ do {
1029+ msleep (100 );
1030+ } while (-- timeout );
1031+
1032+ ioc_state = mpi3mr_get_iocstate (mrioc );
1033+ ioc_info (mrioc ,
1034+ "controller is in %s state after waiting to reset\n" ,
1035+ mpi3mr_iocstate_name (ioc_state ));
1036+ }
1037+
1038+ if (ioc_state == MRIOC_STATE_READY ) {
1039+ ioc_info (mrioc , "issuing message unit reset (MUR) to bring to reset state\n" );
1040+ retval = mpi3mr_issue_and_process_mur (mrioc ,
1041+ MPI3MR_RESET_FROM_BRINGUP );
1042+ ioc_state = mpi3mr_get_iocstate (mrioc );
1043+ if (retval )
1044+ ioc_err (mrioc ,
1045+ "message unit reset failed with error %d current state %s\n" ,
1046+ retval , mpi3mr_iocstate_name (ioc_state ));
1047+ }
1048+ if (ioc_state != MRIOC_STATE_RESET ) {
1049+ mpi3mr_print_fault_info (mrioc );
1050+ ioc_info (mrioc , "issuing soft reset to bring to reset state\n" );
1051+ retval = mpi3mr_issue_reset (mrioc ,
1052+ MPI3_SYSIF_HOST_DIAG_RESET_ACTION_SOFT_RESET ,
1053+ MPI3MR_RESET_FROM_BRINGUP );
1054+ if (retval ) {
1055+ ioc_err (mrioc ,
1056+ "soft reset failed with error %d\n" , retval );
1057+ goto out_failed ;
1058+ }
1059+ }
1060+ ioc_state = mpi3mr_get_iocstate (mrioc );
1061+ if (ioc_state != MRIOC_STATE_RESET ) {
1062+ ioc_err (mrioc ,
1063+ "cannot bring controller to reset state, current state: %s\n" ,
1064+ mpi3mr_iocstate_name (ioc_state ));
1065+ goto out_failed ;
1066+ }
1067+ mpi3mr_clear_reset_history (mrioc );
1068+ retval = mpi3mr_setup_admin_qpair (mrioc );
1069+ if (retval ) {
1070+ ioc_err (mrioc , "failed to setup admin queues: error %d\n" ,
1071+ retval );
1072+ goto out_failed ;
1073+ }
1074+
1075+ ioc_info (mrioc , "bringing controller to ready state\n" );
10021076 ioc_config = readl (& mrioc -> sysif_regs -> ioc_configuration );
10031077 ioc_config |= MPI3_SYSIF_IOC_CONFIG_ENABLE_IOC ;
10041078 writel (ioc_config , & mrioc -> sysif_regs -> ioc_configuration );
10051079
10061080 timeout = mrioc -> ready_timeout * 10 ;
10071081 do {
1008- current_state = mpi3mr_get_iocstate (mrioc );
1009- if (current_state == MRIOC_STATE_READY )
1082+ ioc_state = mpi3mr_get_iocstate (mrioc );
1083+ if (ioc_state == MRIOC_STATE_READY ) {
1084+ ioc_info (mrioc ,
1085+ "successfully transistioned to %s state\n" ,
1086+ mpi3mr_iocstate_name (ioc_state ));
10101087 return 0 ;
1088+ }
10111089 msleep (100 );
10121090 } while (-- timeout );
10131091
1014- return -1 ;
1092+ out_failed :
1093+ ioc_state = mpi3mr_get_iocstate (mrioc );
1094+ ioc_err (mrioc ,
1095+ "failed to bring to ready state, current state: %s\n" ,
1096+ mpi3mr_iocstate_name (ioc_state ));
1097+ return retval ;
10151098}
10161099
10171100/**
@@ -3372,10 +3455,6 @@ static int mpi3mr_enable_events(struct mpi3mr_ioc *mrioc)
33723455int mpi3mr_init_ioc (struct mpi3mr_ioc * mrioc , u8 init_type )
33733456{
33743457 int retval = 0 ;
3375- enum mpi3mr_iocstate ioc_state ;
3376- u64 base_info ;
3377- u32 timeout ;
3378- u32 ioc_status , ioc_config ;
33793458 struct mpi3_ioc_facts_data facts_data ;
33803459
33813460 mrioc -> irqpoll_sleep = MPI3MR_IRQ_POLL_SLEEP ;
@@ -3390,74 +3469,6 @@ int mpi3mr_init_ioc(struct mpi3mr_ioc *mrioc, u8 init_type)
33903469 }
33913470 }
33923471
3393- ioc_status = readl (& mrioc -> sysif_regs -> ioc_status );
3394- ioc_config = readl (& mrioc -> sysif_regs -> ioc_configuration );
3395-
3396- ioc_info (mrioc , "SOD status %x configuration %x\n" ,
3397- ioc_status , ioc_config );
3398-
3399- base_info = lo_hi_readq (& mrioc -> sysif_regs -> ioc_information );
3400- ioc_info (mrioc , "SOD base_info %llx\n" , base_info );
3401-
3402- /*The timeout value is in 2sec unit, changing it to seconds*/
3403- mrioc -> ready_timeout =
3404- ((base_info & MPI3_SYSIF_IOC_INFO_LOW_TIMEOUT_MASK ) >>
3405- MPI3_SYSIF_IOC_INFO_LOW_TIMEOUT_SHIFT ) * 2 ;
3406-
3407- ioc_info (mrioc , "IOC ready timeout %d\n" , mrioc -> ready_timeout );
3408-
3409- ioc_state = mpi3mr_get_iocstate (mrioc );
3410- ioc_info (mrioc , "IOC in %s state during detection\n" ,
3411- mpi3mr_iocstate_name (ioc_state ));
3412-
3413- if (ioc_state == MRIOC_STATE_BECOMING_READY ||
3414- ioc_state == MRIOC_STATE_RESET_REQUESTED ) {
3415- timeout = mrioc -> ready_timeout * 10 ;
3416- do {
3417- msleep (100 );
3418- } while (-- timeout );
3419-
3420- ioc_state = mpi3mr_get_iocstate (mrioc );
3421- ioc_info (mrioc ,
3422- "IOC in %s state after waiting for reset time\n" ,
3423- mpi3mr_iocstate_name (ioc_state ));
3424- }
3425-
3426- if (ioc_state == MRIOC_STATE_READY ) {
3427- retval = mpi3mr_issue_and_process_mur (mrioc ,
3428- MPI3MR_RESET_FROM_BRINGUP );
3429- if (retval ) {
3430- ioc_err (mrioc , "Failed to MU reset IOC error %d\n" ,
3431- retval );
3432- }
3433- ioc_state = mpi3mr_get_iocstate (mrioc );
3434- }
3435- if (ioc_state != MRIOC_STATE_RESET ) {
3436- mpi3mr_print_fault_info (mrioc );
3437- retval = mpi3mr_issue_reset (mrioc ,
3438- MPI3_SYSIF_HOST_DIAG_RESET_ACTION_SOFT_RESET ,
3439- MPI3MR_RESET_FROM_BRINGUP );
3440- if (retval ) {
3441- ioc_err (mrioc ,
3442- "%s :Failed to soft reset IOC error %d\n" ,
3443- __func__ , retval );
3444- goto out_failed ;
3445- }
3446- }
3447- ioc_state = mpi3mr_get_iocstate (mrioc );
3448- if (ioc_state != MRIOC_STATE_RESET ) {
3449- retval = -1 ;
3450- ioc_err (mrioc , "Cannot bring IOC to reset state\n" );
3451- goto out_failed ;
3452- }
3453-
3454- retval = mpi3mr_setup_admin_qpair (mrioc );
3455- if (retval ) {
3456- ioc_err (mrioc , "Failed to setup admin Qs: error %d\n" ,
3457- retval );
3458- goto out_failed ;
3459- }
3460-
34613472 retval = mpi3mr_bring_ioc_ready (mrioc );
34623473 if (retval ) {
34633474 ioc_err (mrioc , "Failed to bring ioc ready: error %d\n" ,
0 commit comments