aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMoore, Eric Dean <Eric.Moore@lsil.com>2005-12-01 12:50:32 -0500
committerJames Bottomley <jejb@mulgrave.(none)>2005-12-01 16:59:51 -0500
commit2a238ea5fbf2bd9a18a4ffb607418a4b9394647e (patch)
treedc505a831abdb22879e86187b3ae01912a02f604
parent8b2f81385aa02e9405990b7fe44462dfceb75ef7 (diff)
[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>
-rw-r--r--drivers/message/fusion/mptbase.c64
-rw-r--r--drivers/message/fusion/mptbase.h3
-rw-r--r--drivers/message/fusion/mptscsih.c10
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
1121int
1122mpt_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 */
1158static int
1159mpt_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
1177return 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);
6296EXPORT_SYMBOL(mpt_alloc_fw_memory); 6355EXPORT_SYMBOL(mpt_alloc_fw_memory);
6297EXPORT_SYMBOL(mpt_free_fw_memory); 6356EXPORT_SYMBOL(mpt_free_fw_memory);
6298EXPORT_SYMBOL(mptbase_sas_persist_operation); 6357EXPORT_SYMBOL(mptbase_sas_persist_operation);
6358EXPORT_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);
1001extern int mpt_findImVolumes(MPT_ADAPTER *ioc); 1003extern int mpt_findImVolumes(MPT_ADAPTER *ioc);
1002extern int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc); 1004extern int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc);
1003extern int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode); 1005extern int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
1006extern 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)) {