aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorChad Dupuis <chad.dupuis@qlogic.com>2013-02-08 01:58:01 -0500
committerJames Bottomley <JBottomley@Parallels.com>2013-02-22 09:31:24 -0500
commitbb4cf5b73b47fe78502b16bc3dc4af612aa37ad7 (patch)
tree52571a3d3ea98c29762ef03bd9fbe25ced7b8c86 /drivers
parent3a11711ad00caebee07e262d188cea66f3473c38 (diff)
[SCSI] qla2xxx: Don't process RSCNs for a vport on the same physical adapter.
Currently,the driver is processes RSCNs for each new NPIV ports that is created. Processing the RSCN includes a name server query to see what has changed at the name server side. The name server query is performed by the physical port and each virtual port on the physical adapter (since the RSCN is passed to each virtual port for processing). As the number of virtual ports being created increases, this causes a lot of traffic and busies the firmware. Processing the RSCN for a virtual port we already have a priori knowledge of is not necessary so check the 24-bit fabric ID of the RSCN entry and skip processing it if the RSCN is for a virtual port we already know about. Signed-off-by: Chad Dupuis <chad.dupuis@qlogic.com> Signed-off-by: Saurav Kashyap <saurav.kashyap@qlogic.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/qla2xxx/qla_gbl.h1
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c21
-rw-r--r--drivers/scsi/qla2xxx/qla_isr.c29
3 files changed, 33 insertions, 18 deletions
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index 617771ba6cbc..02f11de0ff01 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -446,6 +446,7 @@ extern uint8_t *qla25xx_read_nvram_data(scsi_qla_host_t *, uint8_t *, uint32_t,
446 uint32_t); 446 uint32_t);
447extern int qla25xx_write_nvram_data(scsi_qla_host_t *, uint8_t *, uint32_t, 447extern int qla25xx_write_nvram_data(scsi_qla_host_t *, uint8_t *, uint32_t,
448 uint32_t); 448 uint32_t);
449extern int qla2x00_is_a_vp_did(scsi_qla_host_t *, uint32_t);
449 450
450extern int qla2x00_beacon_on(struct scsi_qla_host *); 451extern int qla2x00_beacon_on(struct scsi_qla_host *);
451extern int qla2x00_beacon_off(struct scsi_qla_host *); 452extern int qla2x00_beacon_off(struct scsi_qla_host *);
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 891b8f1c03e9..a1e584842b85 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -3368,8 +3368,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha,
3368 int first_dev, last_dev; 3368 int first_dev, last_dev;
3369 port_id_t wrap = {}, nxt_d_id; 3369 port_id_t wrap = {}, nxt_d_id;
3370 struct qla_hw_data *ha = vha->hw; 3370 struct qla_hw_data *ha = vha->hw;
3371 struct scsi_qla_host *vp, *base_vha = pci_get_drvdata(ha->pdev); 3371 struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
3372 struct scsi_qla_host *tvp;
3373 3372
3374 rval = QLA_SUCCESS; 3373 rval = QLA_SUCCESS;
3375 3374
@@ -3482,22 +3481,8 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha,
3482 continue; 3481 continue;
3483 3482
3484 /* Bypass virtual ports of the same host. */ 3483 /* Bypass virtual ports of the same host. */
3485 found = 0; 3484 if (qla2x00_is_a_vp_did(vha, new_fcport->d_id.b24))
3486 if (ha->num_vhosts) { 3485 continue;
3487 unsigned long flags;
3488
3489 spin_lock_irqsave(&ha->vport_slock, flags);
3490 list_for_each_entry_safe(vp, tvp, &ha->vp_list, list) {
3491 if (new_fcport->d_id.b24 == vp->d_id.b24) {
3492 found = 1;
3493 break;
3494 }
3495 }
3496 spin_unlock_irqrestore(&ha->vport_slock, flags);
3497
3498 if (found)
3499 continue;
3500 }
3501 3486
3502 /* Bypass if same domain and area of adapter. */ 3487 /* Bypass if same domain and area of adapter. */
3503 if (((new_fcport->d_id.b24 & 0xffff00) == 3488 if (((new_fcport->d_id.b24 & 0xffff00) ==
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index fa738cddd4d5..d62fd1a78fa8 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -495,6 +495,31 @@ qla83xx_handle_8200_aen(scsi_qla_host_t *vha, uint16_t *mb)
495 } 495 }
496} 496}
497 497
498int
499qla2x00_is_a_vp_did(scsi_qla_host_t *vha, uint32_t rscn_entry)
500{
501 struct qla_hw_data *ha = vha->hw;
502 scsi_qla_host_t *vp;
503 uint32_t vp_did;
504 unsigned long flags;
505 int ret = 0;
506
507 if (!ha->num_vhosts)
508 return ret;
509
510 spin_lock_irqsave(&ha->vport_slock, flags);
511 list_for_each_entry(vp, &ha->vp_list, list) {
512 vp_did = vp->d_id.b24;
513 if (vp_did == rscn_entry) {
514 ret = 1;
515 break;
516 }
517 }
518 spin_unlock_irqrestore(&ha->vport_slock, flags);
519
520 return ret;
521}
522
498/** 523/**
499 * qla2x00_async_event() - Process aynchronous events. 524 * qla2x00_async_event() - Process aynchronous events.
500 * @ha: SCSI driver HA context 525 * @ha: SCSI driver HA context
@@ -901,6 +926,10 @@ skip_rio:
901 /* Ignore reserved bits from RSCN-payload. */ 926 /* Ignore reserved bits from RSCN-payload. */
902 rscn_entry = ((mb[1] & 0x3ff) << 16) | mb[2]; 927 rscn_entry = ((mb[1] & 0x3ff) << 16) | mb[2];
903 928
929 /* Skip RSCNs for virtual ports on the same physical port */
930 if (qla2x00_is_a_vp_did(vha, rscn_entry))
931 break;
932
904 atomic_set(&vha->loop_down_timer, 0); 933 atomic_set(&vha->loop_down_timer, 0);
905 vha->flags.management_server_logged_in = 0; 934 vha->flags.management_server_logged_in = 0;
906 935