[SCSI] mptfusion : dv performance fix

Syncronization for Domain Validation workqueue and the initiation of the
alternate controller. Its possible that dv could be terminated if the
workqueue on the 1st channel doesn complete in time before the 2nd channel
begins initialization.

Signed-off-by: Eric Moore <Eric.Moore@lsil.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>

authored by Moore, Eric Dean and committed by James Bottomley 2a238ea5 8b2f8138

+75 -2
+62 -2
drivers/message/fusion/mptbase.c
··· 1118 return -1; 1119 } 1120 1121 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1122 /* 1123 * mpt_attach - Install a PCI intelligent MPT adapter. ··· 1245 ioc->pcidev = pdev; 1246 ioc->diagPending = 0; 1247 spin_lock_init(&ioc->diagLock); 1248 1249 /* Initialize the event logging. 1250 */ ··· 1468 */ 1469 mpt_detect_bound_ports(ioc, pdev); 1470 1471 - if ((r = mpt_do_ioc_recovery(ioc, 1472 - MPT_HOSTEVENT_IOC_BRINGUP, CAN_SLEEP)) != 0) { 1473 printk(KERN_WARNING MYNAM 1474 ": WARNING - %s did not initialize properly! (%d)\n", 1475 ioc->name, r); ··· 6355 EXPORT_SYMBOL(mpt_alloc_fw_memory); 6356 EXPORT_SYMBOL(mpt_free_fw_memory); 6357 EXPORT_SYMBOL(mptbase_sas_persist_operation); 6358 6359 6360 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
··· 1118 return -1; 1119 } 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 + 1180 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1181 /* 1182 * mpt_attach - Install a PCI intelligent MPT adapter. ··· 1186 ioc->pcidev = pdev; 1187 ioc->diagPending = 0; 1188 spin_lock_init(&ioc->diagLock); 1189 + spin_lock_init(&ioc->initializing_hba_lock); 1190 1191 /* Initialize the event logging. 1192 */ ··· 1408 */ 1409 mpt_detect_bound_ports(ioc, pdev); 1410 1411 + if ((r = mpt_bringup_adapter(ioc, CAN_SLEEP)) != 0){ 1412 printk(KERN_WARNING MYNAM 1413 ": WARNING - %s did not initialize properly! (%d)\n", 1414 ioc->name, r); ··· 6296 EXPORT_SYMBOL(mpt_alloc_fw_memory); 6297 EXPORT_SYMBOL(mpt_free_fw_memory); 6298 EXPORT_SYMBOL(mptbase_sas_persist_operation); 6299 + EXPORT_SYMBOL(mpt_alt_ioc_wait); 6300 6301 6302 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+3
drivers/message/fusion/mptbase.h
··· 611 int DoneCtx; 612 int TaskCtx; 613 int InternalCtx; 614 struct list_head list; 615 struct net_device *netdev; 616 struct list_head sas_topology; ··· 1003 extern int mpt_findImVolumes(MPT_ADAPTER *ioc); 1004 extern int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc); 1005 extern int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode); 1006 1007 /* 1008 * Public data decl's...
··· 611 int DoneCtx; 612 int TaskCtx; 613 int InternalCtx; 614 + spinlock_t initializing_hba_lock; 615 + int initializing_hba_lock_flag; 616 struct list_head list; 617 struct net_device *netdev; 618 struct list_head sas_topology; ··· 1001 extern int mpt_findImVolumes(MPT_ADAPTER *ioc); 1002 extern int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc); 1003 extern int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode); 1004 + extern int mpt_alt_ioc_wait(MPT_ADAPTER *ioc); 1005 1006 /* 1007 * Public data decl's...
+10
drivers/message/fusion/mptscsih.c
··· 4162 } 4163 } 4164 4165 if (mptscsih_doDv(hd, 0, id) == 1) { 4166 /* Untagged device was busy, try again 4167 */ ··· 4178 */ 4179 hd->ioc->spi_data.dvStatus[id] &= ~(MPT_SCSICFG_DV_NOT_DONE | MPT_SCSICFG_DV_PENDING); 4180 } 4181 4182 if (isPhysDisk) { 4183 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
··· 4162 } 4163 } 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 + 4171 if (mptscsih_doDv(hd, 0, id) == 1) { 4172 /* Untagged device was busy, try again 4173 */ ··· 4172 */ 4173 hd->ioc->spi_data.dvStatus[id] &= ~(MPT_SCSICFG_DV_NOT_DONE | MPT_SCSICFG_DV_PENDING); 4174 } 4175 + 4176 + spin_lock(&hd->ioc->initializing_hba_lock); 4177 + hd->ioc->initializing_hba_lock_flag=0; 4178 + spin_unlock(&hd->ioc->initializing_hba_lock); 4179 4180 if (isPhysDisk) { 4181 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {