aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx
diff options
context:
space:
mode:
authorLalit Chandivade <lalit.chandivade@qlogic.com>2009-03-24 12:08:07 -0400
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2009-04-03 10:22:49 -0400
commit2533cf671da0603129c8af9c31c735e1d2654e20 (patch)
tree3ef7f6c0b4266823c07bc0687ac9009e1cc281c0 /drivers/scsi/qla2xxx
parent1d2874de809a14e6780246b99a18bbc0fc0a8f2a (diff)
[SCSI] qla2xxx: Correct ISP abort semantics for NVRAM, VPD, and flash update.
Ensure that an ISP-abort has completed before performing any update. After the update do not wait for an ISP-abort completion, instead just wait until the ISP is reset. This avoids long delays due to waiting for loop ready in qla2x00_abort_isp(). Signed-off-by: Lalit Chandivade <lalit.chandivade@qlogic.com> Additional cleanups and Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi/qla2xxx')
-rw-r--r--drivers/scsi/qla2xxx/qla_attr.c21
-rw-r--r--drivers/scsi/qla2xxx/qla_def.h1
-rw-r--r--drivers/scsi/qla2xxx/qla_gbl.h1
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c5
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c28
-rw-r--r--drivers/scsi/qla2xxx/qla_sup.c2
6 files changed, 57 insertions, 1 deletions
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index 41ce1c6e56b3..117517dcbe44 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -137,12 +137,21 @@ qla2x00_sysfs_write_nvram(struct kobject *kobj,
137 *iter = chksum; 137 *iter = chksum;
138 } 138 }
139 139
140 if (qla2x00_wait_for_hba_online(vha) != QLA_SUCCESS) {
141 qla_printk(KERN_WARNING, ha,
142 "HBA not online, failing NVRAM update.\n");
143 return -EAGAIN;
144 }
145
140 /* Write NVRAM. */ 146 /* Write NVRAM. */
141 ha->isp_ops->write_nvram(vha, (uint8_t *)buf, ha->nvram_base, count); 147 ha->isp_ops->write_nvram(vha, (uint8_t *)buf, ha->nvram_base, count);
142 ha->isp_ops->read_nvram(vha, (uint8_t *)ha->nvram, ha->nvram_base, 148 ha->isp_ops->read_nvram(vha, (uint8_t *)ha->nvram, ha->nvram_base,
143 count); 149 count);
144 150
151 /* NVRAM settings take effect immediately. */
145 set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); 152 set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
153 qla2xxx_wake_dpc(vha);
154 qla2x00_wait_for_chip_reset(vha);
146 155
147 return (count); 156 return (count);
148} 157}
@@ -330,6 +339,12 @@ qla2x00_sysfs_write_optrom_ctl(struct kobject *kobj,
330 if (ha->optrom_state != QLA_SWRITING) 339 if (ha->optrom_state != QLA_SWRITING)
331 break; 340 break;
332 341
342 if (qla2x00_wait_for_hba_online(vha) != QLA_SUCCESS) {
343 qla_printk(KERN_WARNING, ha,
344 "HBA not online, failing flash update.\n");
345 return -EAGAIN;
346 }
347
333 DEBUG2(qla_printk(KERN_INFO, ha, 348 DEBUG2(qla_printk(KERN_INFO, ha,
334 "Writing flash region -- 0x%x/0x%x.\n", 349 "Writing flash region -- 0x%x/0x%x.\n",
335 ha->optrom_region_start, ha->optrom_region_size)); 350 ha->optrom_region_start, ha->optrom_region_size));
@@ -380,6 +395,12 @@ qla2x00_sysfs_write_vpd(struct kobject *kobj,
380 if (!capable(CAP_SYS_ADMIN) || off != 0 || count != ha->vpd_size) 395 if (!capable(CAP_SYS_ADMIN) || off != 0 || count != ha->vpd_size)
381 return 0; 396 return 0;
382 397
398 if (qla2x00_wait_for_hba_online(vha) != QLA_SUCCESS) {
399 qla_printk(KERN_WARNING, ha,
400 "HBA not online, failing VPD update.\n");
401 return -EAGAIN;
402 }
403
383 /* Write NVRAM. */ 404 /* Write NVRAM. */
384 ha->isp_ops->write_nvram(vha, (uint8_t *)buf, ha->vpd_base, count); 405 ha->isp_ops->write_nvram(vha, (uint8_t *)buf, ha->vpd_base, count);
385 ha->isp_ops->read_nvram(vha, (uint8_t *)ha->vpd, ha->vpd_base, count); 406 ha->isp_ops->read_nvram(vha, (uint8_t *)ha->vpd, ha->vpd_base, count);
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index bca572f93bcc..421c6343e1c1 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -2261,6 +2261,7 @@ struct qla_hw_data {
2261 uint32_t npiv_supported :1; 2261 uint32_t npiv_supported :1;
2262 uint32_t fce_enabled :1; 2262 uint32_t fce_enabled :1;
2263 uint32_t fac_supported :1; 2263 uint32_t fac_supported :1;
2264 uint32_t chip_reset_done :1;
2264 } flags; 2265 } flags;
2265 2266
2266 /* This spinlock is used to protect "io transactions", you must 2267 /* This spinlock is used to protect "io transactions", you must
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index 4d52bf1c2ada..c75e7f98c242 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -110,6 +110,7 @@ extern void qla2x00_mark_all_devices_lost(scsi_qla_host_t *, int);
110extern struct fw_blob *qla2x00_request_firmware(scsi_qla_host_t *); 110extern struct fw_blob *qla2x00_request_firmware(scsi_qla_host_t *);
111 111
112extern int qla2x00_wait_for_hba_online(scsi_qla_host_t *); 112extern int qla2x00_wait_for_hba_online(scsi_qla_host_t *);
113extern int qla2x00_wait_for_chip_reset(scsi_qla_host_t *);
113 114
114extern void qla2xxx_wake_dpc(struct scsi_qla_host *); 115extern void qla2xxx_wake_dpc(struct scsi_qla_host *);
115extern void qla2x00_alert_all_vps(struct rsp_que *, uint16_t *); 116extern void qla2x00_alert_all_vps(struct rsp_que *, uint16_t *);
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index c37888e8747d..a2747501fdde 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -61,8 +61,10 @@ qla2x00_initialize_adapter(scsi_qla_host_t *vha)
61 int rval; 61 int rval;
62 struct qla_hw_data *ha = vha->hw; 62 struct qla_hw_data *ha = vha->hw;
63 struct req_que *req = ha->req_q_map[0]; 63 struct req_que *req = ha->req_q_map[0];
64
64 /* Clear adapter flags. */ 65 /* Clear adapter flags. */
65 vha->flags.online = 0; 66 vha->flags.online = 0;
67 ha->flags.chip_reset_done = 0;
66 vha->flags.reset_active = 0; 68 vha->flags.reset_active = 0;
67 atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME); 69 atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME);
68 atomic_set(&vha->loop_state, LOOP_DOWN); 70 atomic_set(&vha->loop_state, LOOP_DOWN);
@@ -131,6 +133,7 @@ qla2x00_initialize_adapter(scsi_qla_host_t *vha)
131 } 133 }
132 } 134 }
133 rval = qla2x00_init_rings(vha); 135 rval = qla2x00_init_rings(vha);
136 ha->flags.chip_reset_done = 1;
134 137
135 return (rval); 138 return (rval);
136} 139}
@@ -3321,6 +3324,7 @@ qla2x00_abort_isp(scsi_qla_host_t *vha)
3321 3324
3322 if (vha->flags.online) { 3325 if (vha->flags.online) {
3323 vha->flags.online = 0; 3326 vha->flags.online = 0;
3327 ha->flags.chip_reset_done = 0;
3324 clear_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); 3328 clear_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
3325 ha->qla_stats.total_isp_aborts++; 3329 ha->qla_stats.total_isp_aborts++;
3326 3330
@@ -3470,6 +3474,7 @@ qla2x00_restart_isp(scsi_qla_host_t *vha)
3470 3474
3471 if (!status && !(status = qla2x00_init_rings(vha))) { 3475 if (!status && !(status = qla2x00_init_rings(vha))) {
3472 clear_bit(RESET_MARKER_NEEDED, &vha->dpc_flags); 3476 clear_bit(RESET_MARKER_NEEDED, &vha->dpc_flags);
3477 ha->flags.chip_reset_done = 1;
3473 /* Initialize the queues in use */ 3478 /* Initialize the queues in use */
3474 qla25xx_init_queues(ha); 3479 qla25xx_init_queues(ha);
3475 3480
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index c7954612ef11..1c3d165c035b 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -535,6 +535,34 @@ qla2x00_wait_for_hba_online(scsi_qla_host_t *vha)
535 return (return_status); 535 return (return_status);
536} 536}
537 537
538int
539qla2x00_wait_for_chip_reset(scsi_qla_host_t *vha)
540{
541 int return_status;
542 unsigned long wait_reset;
543 struct qla_hw_data *ha = vha->hw;
544 scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
545
546 wait_reset = jiffies + (MAX_LOOP_TIMEOUT * HZ);
547 while (((test_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags)) ||
548 test_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags) ||
549 test_bit(ISP_ABORT_RETRY, &base_vha->dpc_flags) ||
550 ha->dpc_active) && time_before(jiffies, wait_reset)) {
551
552 msleep(1000);
553
554 if (!test_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags) &&
555 ha->flags.chip_reset_done)
556 break;
557 }
558 if (ha->flags.chip_reset_done)
559 return_status = QLA_SUCCESS;
560 else
561 return_status = QLA_FUNCTION_FAILED;
562
563 return return_status;
564}
565
538/* 566/*
539 * qla2x00_wait_for_loop_ready 567 * qla2x00_wait_for_loop_ready
540 * Wait for MAX_LOOP_TIMEOUT(5 min) value for loop 568 * Wait for MAX_LOOP_TIMEOUT(5 min) value for loop
diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c
index ff5aa75109fc..09f893dc572d 100644
--- a/drivers/scsi/qla2xxx/qla_sup.c
+++ b/drivers/scsi/qla2xxx/qla_sup.c
@@ -1949,7 +1949,7 @@ qla2x00_resume_hba(struct scsi_qla_host *vha)
1949 clear_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags); 1949 clear_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags);
1950 set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); 1950 set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
1951 qla2xxx_wake_dpc(vha); 1951 qla2xxx_wake_dpc(vha);
1952 qla2x00_wait_for_hba_online(vha); 1952 qla2x00_wait_for_chip_reset(vha);
1953 scsi_unblock_requests(vha->host); 1953 scsi_unblock_requests(vha->host);
1954} 1954}
1955 1955