aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAndrew Vasquez <andrew.vasquez@qlogic.com>2009-08-25 14:36:19 -0400
committerJames Bottomley <James.Bottomley@suse.de>2009-09-12 10:35:22 -0400
commit0d6e61bc6a4f3f54444b088ae6d447f1703a21dd (patch)
tree20594eed50ae777518a1b5d9f3c6dd81cb110dfc /drivers
parentd970432c48ab8dd28216e80942723aeb505b623e (diff)
[SCSI] qla2xxx: Correct various NPIV issues.
* Consolidate vport-count processing. * Correct vp_idx restrictions during RSCN processing. * Push topology verification check to qla2x00_do_dpc_all_vps(). * Don't skip vport full-login-lip/lip-reset mailbox handling. Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com> Signed-off-by: Giridhar Malavali <giridhar.malavali@qlogic.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/qla2xxx/qla_attr.c5
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c2
-rw-r--r--drivers/scsi/qla2xxx/qla_isr.c3
-rw-r--r--drivers/scsi/qla2xxx/qla_mid.c30
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c21
5 files changed, 32 insertions, 29 deletions
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index 5b0a222241bb..fbcb82a2f7f4 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -1736,6 +1736,11 @@ qla24xx_vport_delete(struct fc_vport *fc_vport)
1736 1736
1737 qla24xx_deallocate_vp_id(vha); 1737 qla24xx_deallocate_vp_id(vha);
1738 1738
1739 mutex_lock(&ha->vport_lock);
1740 ha->cur_vport_count--;
1741 clear_bit(vha->vp_idx, ha->vp_idx_map);
1742 mutex_unlock(&ha->vport_lock);
1743
1739 if (vha->timer_active) { 1744 if (vha->timer_active) {
1740 qla2x00_vp_stop_timer(vha); 1745 qla2x00_vp_stop_timer(vha);
1741 DEBUG15(printk ("scsi(%ld): timer for the vport[%d] = %p " 1746 DEBUG15(printk ("scsi(%ld): timer for the vport[%d] = %p "
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 825700ae5041..f74d07a9e945 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -3540,8 +3540,6 @@ qla2x00_abort_isp(scsi_qla_host_t *vha)
3540 if (atomic_read(&vha->loop_state) != LOOP_DOWN) { 3540 if (atomic_read(&vha->loop_state) != LOOP_DOWN) {
3541 atomic_set(&vha->loop_state, LOOP_DOWN); 3541 atomic_set(&vha->loop_state, LOOP_DOWN);
3542 qla2x00_mark_all_devices_lost(vha, 0); 3542 qla2x00_mark_all_devices_lost(vha, 0);
3543 list_for_each_entry_safe(vp, tvp, &ha->vp_list, list)
3544 qla2x00_mark_all_devices_lost(vp, 0);
3545 } else { 3543 } else {
3546 if (!atomic_read(&vha->loop_down_timer)) 3544 if (!atomic_read(&vha->loop_down_timer))
3547 atomic_set(&vha->loop_down_timer, 3545 atomic_set(&vha->loop_down_timer,
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index 27db6246ca3e..b20a7169aac2 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -685,8 +685,9 @@ skip_rio:
685 if (vha->vp_idx && test_bit(VP_SCR_NEEDED, &vha->vp_flags)) 685 if (vha->vp_idx && test_bit(VP_SCR_NEEDED, &vha->vp_flags))
686 break; 686 break;
687 /* Only handle SCNs for our Vport index. */ 687 /* Only handle SCNs for our Vport index. */
688 if (vha->vp_idx != (mb[3] & 0xff)) 688 if (ha->flags.npiv_supported && vha->vp_idx != (mb[3] & 0xff))
689 break; 689 break;
690
690 DEBUG2(printk("scsi(%ld): Asynchronous RSCR UPDATE.\n", 691 DEBUG2(printk("scsi(%ld): Asynchronous RSCR UPDATE.\n",
691 vha->host_no)); 692 vha->host_no));
692 DEBUG(printk(KERN_INFO 693 DEBUG(printk(KERN_INFO
diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c
index a748a95efb10..42b799abba57 100644
--- a/drivers/scsi/qla2xxx/qla_mid.c
+++ b/drivers/scsi/qla2xxx/qla_mid.c
@@ -42,7 +42,6 @@ qla24xx_allocate_vp_id(scsi_qla_host_t *vha)
42 42
43 set_bit(vp_id, ha->vp_idx_map); 43 set_bit(vp_id, ha->vp_idx_map);
44 ha->num_vhosts++; 44 ha->num_vhosts++;
45 ha->cur_vport_count++;
46 vha->vp_idx = vp_id; 45 vha->vp_idx = vp_id;
47 list_add_tail(&vha->list, &ha->vp_list); 46 list_add_tail(&vha->list, &ha->vp_list);
48 mutex_unlock(&ha->vport_lock); 47 mutex_unlock(&ha->vport_lock);
@@ -58,7 +57,6 @@ qla24xx_deallocate_vp_id(scsi_qla_host_t *vha)
58 mutex_lock(&ha->vport_lock); 57 mutex_lock(&ha->vport_lock);
59 vp_id = vha->vp_idx; 58 vp_id = vha->vp_idx;
60 ha->num_vhosts--; 59 ha->num_vhosts--;
61 ha->cur_vport_count--;
62 clear_bit(vp_id, ha->vp_idx_map); 60 clear_bit(vp_id, ha->vp_idx_map);
63 list_del(&vha->list); 61 list_del(&vha->list);
64 mutex_unlock(&ha->vport_lock); 62 mutex_unlock(&ha->vport_lock);
@@ -235,7 +233,11 @@ qla2x00_vp_abort_isp(scsi_qla_host_t *vha)
235 atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME); 233 atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME);
236 } 234 }
237 235
238 /* To exclusively reset vport, we need to log it out first.*/ 236 /*
237 * To exclusively reset vport, we need to log it out first. Note: this
238 * control_vp can fail if ISP reset is already issued, this is
239 * expected, as the vp would be already logged out due to ISP reset.
240 */
239 if (!test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags)) 241 if (!test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags))
240 qla24xx_control_vp(vha, VCE_COMMAND_DISABLE_VPS_LOGO_ALL); 242 qla24xx_control_vp(vha, VCE_COMMAND_DISABLE_VPS_LOGO_ALL);
241 243
@@ -247,23 +249,11 @@ qla2x00_vp_abort_isp(scsi_qla_host_t *vha)
247static int 249static int
248qla2x00_do_dpc_vp(scsi_qla_host_t *vha) 250qla2x00_do_dpc_vp(scsi_qla_host_t *vha)
249{ 251{
250 struct qla_hw_data *ha = vha->hw;
251 scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
252
253 if (!(ha->current_topology & ISP_CFG_F))
254 return 0;
255
256 qla2x00_do_work(vha); 252 qla2x00_do_work(vha);
257 253
258 if (test_and_clear_bit(VP_IDX_ACQUIRED, &vha->vp_flags)) { 254 if (test_and_clear_bit(VP_IDX_ACQUIRED, &vha->vp_flags)) {
259 /* VP acquired. complete port configuration */ 255 /* VP acquired. complete port configuration */
260 if (atomic_read(&base_vha->loop_state) == LOOP_READY) { 256 qla24xx_configure_vp(vha);
261 qla24xx_configure_vp(vha);
262 } else {
263 set_bit(VP_IDX_ACQUIRED, &vha->vp_flags);
264 set_bit(VP_DPC_NEEDED, &base_vha->dpc_flags);
265 }
266
267 return 0; 257 return 0;
268 } 258 }
269 259
@@ -314,6 +304,9 @@ qla2x00_do_dpc_all_vps(scsi_qla_host_t *vha)
314 304
315 clear_bit(VP_DPC_NEEDED, &vha->dpc_flags); 305 clear_bit(VP_DPC_NEEDED, &vha->dpc_flags);
316 306
307 if (!(ha->current_topology & ISP_CFG_F))
308 return;
309
317 list_for_each_entry_safe(vp, tvp, &ha->vp_list, list) { 310 list_for_each_entry_safe(vp, tvp, &ha->vp_list, list) {
318 if (vp->vp_idx) 311 if (vp->vp_idx)
319 ret = qla2x00_do_dpc_vp(vp); 312 ret = qla2x00_do_dpc_vp(vp);
@@ -418,6 +411,11 @@ qla24xx_create_vhost(struct fc_vport *fc_vport)
418 411
419 vha->flags.init_done = 1; 412 vha->flags.init_done = 1;
420 413
414 mutex_lock(&ha->vport_lock);
415 set_bit(vha->vp_idx, ha->vp_idx_map);
416 ha->cur_vport_count++;
417 mutex_unlock(&ha->vport_lock);
418
421 return vha; 419 return vha;
422 420
423create_vhost_failed: 421create_vhost_failed:
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index ea9f91756c1e..210229019588 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -1119,8 +1119,7 @@ qla2x00_loop_reset(scsi_qla_host_t *vha)
1119 struct fc_port *fcport; 1119 struct fc_port *fcport;
1120 struct qla_hw_data *ha = vha->hw; 1120 struct qla_hw_data *ha = vha->hw;
1121 1121
1122 if (ha->flags.enable_lip_full_login && !vha->vp_idx && 1122 if (ha->flags.enable_lip_full_login && !IS_QLA81XX(ha)) {
1123 !IS_QLA81XX(ha)) {
1124 ret = qla2x00_full_login_lip(vha); 1123 ret = qla2x00_full_login_lip(vha);
1125 if (ret != QLA_SUCCESS) { 1124 if (ret != QLA_SUCCESS) {
1126 DEBUG2_3(printk("%s(%ld): failed: " 1125 DEBUG2_3(printk("%s(%ld): failed: "
@@ -1133,7 +1132,7 @@ qla2x00_loop_reset(scsi_qla_host_t *vha)
1133 qla2x00_wait_for_loop_ready(vha); 1132 qla2x00_wait_for_loop_ready(vha);
1134 } 1133 }
1135 1134
1136 if (ha->flags.enable_lip_reset && !vha->vp_idx) { 1135 if (ha->flags.enable_lip_reset) {
1137 ret = qla2x00_lip_reset(vha); 1136 ret = qla2x00_lip_reset(vha);
1138 if (ret != QLA_SUCCESS) { 1137 if (ret != QLA_SUCCESS) {
1139 DEBUG2_3(printk("%s(%ld): failed: " 1138 DEBUG2_3(printk("%s(%ld): failed: "
@@ -2264,8 +2263,9 @@ qla2x00_mark_all_devices_lost(scsi_qla_host_t *vha, int defer)
2264 fc_port_t *fcport; 2263 fc_port_t *fcport;
2265 2264
2266 list_for_each_entry(fcport, &vha->vp_fcports, list) { 2265 list_for_each_entry(fcport, &vha->vp_fcports, list) {
2267 if (vha->vp_idx != fcport->vp_idx) 2266 if (vha->vp_idx != 0 && vha->vp_idx != fcport->vp_idx)
2268 continue; 2267 continue;
2268
2269 /* 2269 /*
2270 * No point in marking the device as lost, if the device is 2270 * No point in marking the device as lost, if the device is
2271 * already DEAD. 2271 * already DEAD.
@@ -2273,10 +2273,12 @@ qla2x00_mark_all_devices_lost(scsi_qla_host_t *vha, int defer)
2273 if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD) 2273 if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD)
2274 continue; 2274 continue;
2275 if (atomic_read(&fcport->state) == FCS_ONLINE) { 2275 if (atomic_read(&fcport->state) == FCS_ONLINE) {
2276 atomic_set(&fcport->state, FCS_DEVICE_LOST); 2276 if (defer)
2277 qla2x00_schedule_rport_del(vha, fcport, defer); 2277 qla2x00_schedule_rport_del(vha, fcport, defer);
2278 } else 2278 else if (vha->vp_idx == fcport->vp_idx)
2279 atomic_set(&fcport->state, FCS_DEVICE_LOST); 2279 qla2x00_schedule_rport_del(vha, fcport, defer);
2280 }
2281 atomic_set(&fcport->state, FCS_DEVICE_LOST);
2280 } 2282 }
2281} 2283}
2282 2284
@@ -3069,8 +3071,7 @@ qla2x00_timer(scsi_qla_host_t *vha)
3069 3071
3070 /* if the loop has been down for 4 minutes, reinit adapter */ 3072 /* if the loop has been down for 4 minutes, reinit adapter */
3071 if (atomic_dec_and_test(&vha->loop_down_timer) != 0) { 3073 if (atomic_dec_and_test(&vha->loop_down_timer) != 0) {
3072 if (!(vha->device_flags & DFLG_NO_CABLE) && 3074 if (!(vha->device_flags & DFLG_NO_CABLE)) {
3073 !vha->vp_idx) {
3074 DEBUG(printk("scsi(%ld): Loop down - " 3075 DEBUG(printk("scsi(%ld): Loop down - "
3075 "aborting ISP.\n", 3076 "aborting ISP.\n",
3076 vha->host_no)); 3077 vha->host_no));