diff options
-rw-r--r-- | drivers/message/fusion/mptbase.c | 64 | ||||
-rw-r--r-- | drivers/message/fusion/mptbase.h | 3 | ||||
-rw-r--r-- | drivers/message/fusion/mptscsih.c | 10 |
3 files changed, 75 insertions, 2 deletions
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index 74022316fc63..cabf35373cfd 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c | |||
@@ -1118,6 +1118,65 @@ mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp) | |||
1118 | return -1; | 1118 | return -1; |
1119 | } | 1119 | } |
1120 | 1120 | ||
1121 | int | ||
1122 | mpt_alt_ioc_wait(MPT_ADAPTER *ioc) | ||
1123 | { | ||
1124 | int loop_count = 30 * 4; /* Wait 30 seconds */ | ||
1125 | int status = -1; /* -1 means failed to get board READY */ | ||
1126 | |||
1127 | do { | ||
1128 | spin_lock(&ioc->initializing_hba_lock); | ||
1129 | if (ioc->initializing_hba_lock_flag == 0) { | ||
1130 | ioc->initializing_hba_lock_flag=1; | ||
1131 | spin_unlock(&ioc->initializing_hba_lock); | ||
1132 | status = 0; | ||
1133 | break; | ||
1134 | } | ||
1135 | spin_unlock(&ioc->initializing_hba_lock); | ||
1136 | set_current_state(TASK_INTERRUPTIBLE); | ||
1137 | schedule_timeout(HZ/4); | ||
1138 | } while (--loop_count); | ||
1139 | |||
1140 | return status; | ||
1141 | } | ||
1142 | |||
1143 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | ||
1144 | /* | ||
1145 | * mpt_bringup_adapter - This is a wrapper function for mpt_do_ioc_recovery | ||
1146 | * @ioc: Pointer to MPT adapter structure | ||
1147 | * @sleepFlag: Use schedule if CAN_SLEEP else use udelay. | ||
1148 | * | ||
1149 | * This routine performs all the steps necessary to bring the IOC | ||
1150 | * to a OPERATIONAL state. | ||
1151 | * | ||
1152 | * Special Note: This function was added with spin lock's so as to allow | ||
1153 | * the dv(domain validation) work thread to succeed on the other channel | ||
1154 | * that maybe occuring at the same time when this function is called. | ||
1155 | * Without this lock, the dv would fail when message frames were | ||
1156 | * requested during hba bringup on the alternate ioc. | ||
1157 | */ | ||
1158 | static int | ||
1159 | mpt_bringup_adapter(MPT_ADAPTER *ioc, int sleepFlag) | ||
1160 | { | ||
1161 | int r; | ||
1162 | |||
1163 | if(ioc->alt_ioc) { | ||
1164 | if((r=mpt_alt_ioc_wait(ioc->alt_ioc)!=0)) | ||
1165 | return r; | ||
1166 | } | ||
1167 | |||
1168 | r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP, | ||
1169 | CAN_SLEEP); | ||
1170 | |||
1171 | if(ioc->alt_ioc) { | ||
1172 | spin_lock(&ioc->alt_ioc->initializing_hba_lock); | ||
1173 | ioc->alt_ioc->initializing_hba_lock_flag=0; | ||
1174 | spin_unlock(&ioc->alt_ioc->initializing_hba_lock); | ||
1175 | } | ||
1176 | |||
1177 | return r; | ||
1178 | } | ||
1179 | |||
1121 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 1180 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
1122 | /* | 1181 | /* |
1123 | * mpt_attach - Install a PCI intelligent MPT adapter. | 1182 | * mpt_attach - Install a PCI intelligent MPT adapter. |
@@ -1186,6 +1245,7 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1186 | ioc->pcidev = pdev; | 1245 | ioc->pcidev = pdev; |
1187 | ioc->diagPending = 0; | 1246 | ioc->diagPending = 0; |
1188 | spin_lock_init(&ioc->diagLock); | 1247 | spin_lock_init(&ioc->diagLock); |
1248 | spin_lock_init(&ioc->initializing_hba_lock); | ||
1189 | 1249 | ||
1190 | /* Initialize the event logging. | 1250 | /* Initialize the event logging. |
1191 | */ | 1251 | */ |
@@ -1408,8 +1468,7 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1408 | */ | 1468 | */ |
1409 | mpt_detect_bound_ports(ioc, pdev); | 1469 | mpt_detect_bound_ports(ioc, pdev); |
1410 | 1470 | ||
1411 | if ((r = mpt_do_ioc_recovery(ioc, | 1471 | if ((r = mpt_bringup_adapter(ioc, CAN_SLEEP)) != 0){ |
1412 | MPT_HOSTEVENT_IOC_BRINGUP, CAN_SLEEP)) != 0) { | ||
1413 | printk(KERN_WARNING MYNAM | 1472 | printk(KERN_WARNING MYNAM |
1414 | ": WARNING - %s did not initialize properly! (%d)\n", | 1473 | ": WARNING - %s did not initialize properly! (%d)\n", |
1415 | ioc->name, r); | 1474 | ioc->name, r); |
@@ -6296,6 +6355,7 @@ EXPORT_SYMBOL(mpt_read_ioc_pg_3); | |||
6296 | EXPORT_SYMBOL(mpt_alloc_fw_memory); | 6355 | EXPORT_SYMBOL(mpt_alloc_fw_memory); |
6297 | EXPORT_SYMBOL(mpt_free_fw_memory); | 6356 | EXPORT_SYMBOL(mpt_free_fw_memory); |
6298 | EXPORT_SYMBOL(mptbase_sas_persist_operation); | 6357 | EXPORT_SYMBOL(mptbase_sas_persist_operation); |
6358 | EXPORT_SYMBOL(mpt_alt_ioc_wait); | ||
6299 | 6359 | ||
6300 | 6360 | ||
6301 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 6361 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h index 8ad277a9afa1..a564ae36a2c2 100644 --- a/drivers/message/fusion/mptbase.h +++ b/drivers/message/fusion/mptbase.h | |||
@@ -611,6 +611,8 @@ typedef struct _MPT_ADAPTER | |||
611 | int DoneCtx; | 611 | int DoneCtx; |
612 | int TaskCtx; | 612 | int TaskCtx; |
613 | int InternalCtx; | 613 | int InternalCtx; |
614 | spinlock_t initializing_hba_lock; | ||
615 | int initializing_hba_lock_flag; | ||
614 | struct list_head list; | 616 | struct list_head list; |
615 | struct net_device *netdev; | 617 | struct net_device *netdev; |
616 | struct list_head sas_topology; | 618 | struct list_head sas_topology; |
@@ -1001,6 +1003,7 @@ extern void mpt_free_fw_memory(MPT_ADAPTER *ioc); | |||
1001 | extern int mpt_findImVolumes(MPT_ADAPTER *ioc); | 1003 | extern int mpt_findImVolumes(MPT_ADAPTER *ioc); |
1002 | extern int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc); | 1004 | extern int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc); |
1003 | extern int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode); | 1005 | extern int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode); |
1006 | extern int mpt_alt_ioc_wait(MPT_ADAPTER *ioc); | ||
1004 | 1007 | ||
1005 | /* | 1008 | /* |
1006 | * Public data decl's... | 1009 | * Public data decl's... |
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c index 4330ed0cedaa..b7b9846ff3fd 100644 --- a/drivers/message/fusion/mptscsih.c +++ b/drivers/message/fusion/mptscsih.c | |||
@@ -4162,6 +4162,12 @@ mptscsih_domainValidation(void *arg) | |||
4162 | } | 4162 | } |
4163 | } | 4163 | } |
4164 | 4164 | ||
4165 | if(mpt_alt_ioc_wait(hd->ioc)!=0) { | ||
4166 | ddvprintk((MYIOC_s_WARN_FMT "alt_ioc busy!\n", | ||
4167 | hd->ioc->name)); | ||
4168 | continue; | ||
4169 | } | ||
4170 | |||
4165 | if (mptscsih_doDv(hd, 0, id) == 1) { | 4171 | if (mptscsih_doDv(hd, 0, id) == 1) { |
4166 | /* Untagged device was busy, try again | 4172 | /* Untagged device was busy, try again |
4167 | */ | 4173 | */ |
@@ -4173,6 +4179,10 @@ mptscsih_domainValidation(void *arg) | |||
4173 | hd->ioc->spi_data.dvStatus[id] &= ~(MPT_SCSICFG_DV_NOT_DONE | MPT_SCSICFG_DV_PENDING); | 4179 | hd->ioc->spi_data.dvStatus[id] &= ~(MPT_SCSICFG_DV_NOT_DONE | MPT_SCSICFG_DV_PENDING); |
4174 | } | 4180 | } |
4175 | 4181 | ||
4182 | spin_lock(&hd->ioc->initializing_hba_lock); | ||
4183 | hd->ioc->initializing_hba_lock_flag=0; | ||
4184 | spin_unlock(&hd->ioc->initializing_hba_lock); | ||
4185 | |||
4176 | if (isPhysDisk) { | 4186 | if (isPhysDisk) { |
4177 | for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) { | 4187 | for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) { |
4178 | if (hd->ioc->raid_data.isRaid & (1 << ii)) { | 4188 | if (hd->ioc->raid_data.isRaid & (1 << ii)) { |