aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc
diff options
context:
space:
mode:
authorJames Smart <James.Smart@Emulex.Com>2007-08-02 11:09:51 -0400
committerJames Bottomley <jejb@mulgrave.localdomain>2007-08-01 13:18:23 -0400
commit549e55cd2a1b83ea45ac17fb6c309654a3d371a4 (patch)
tree0abf10a28b177e129932c62b3b94994ce4f3aadb /drivers/scsi/lpfc
parenta58cbd5212fff2d4bba0bf58e778f02069597294 (diff)
[SCSI] lpfc 8.2.2 : Fix locking around HBA's port_list
Cleans up a lot of bad behaviors that have been in this area a while Signed-off-by: James Smart <James.Smart@emulex.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/lpfc')
-rw-r--r--drivers/scsi/lpfc/lpfc.h9
-rw-r--r--drivers/scsi/lpfc/lpfc_attr.c21
-rw-r--r--drivers/scsi/lpfc/lpfc_crtn.h2
-rw-r--r--drivers/scsi/lpfc/lpfc_ct.c12
-rw-r--r--drivers/scsi/lpfc/lpfc_els.c61
-rw-r--r--drivers/scsi/lpfc/lpfc_hbadisc.c157
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c134
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.c92
-rw-r--r--drivers/scsi/lpfc/lpfc_vport.c41
-rw-r--r--drivers/scsi/lpfc/lpfc_vport.h2
10 files changed, 308 insertions, 223 deletions
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index 3f64c4b81b0c..6127635e6275 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -528,10 +528,11 @@ struct lpfc_hba {
528 struct fc_host_statistics link_stats; 528 struct fc_host_statistics link_stats;
529 529
530 struct list_head port_list; 530 struct list_head port_list;
531 struct lpfc_vport *pport; /* physical lpfc_vport pointer */ 531 struct lpfc_vport *pport; /* physical lpfc_vport pointer */
532 uint16_t max_vpi; /* Maximum virtual nports */ 532 uint16_t max_vpi; /* Maximum virtual nports */
533#define LPFC_MAX_VPI 100 /* Max number of VPorts supported */ 533#define LPFC_MAX_VPI 100 /* Max number of VPI supported */
534 unsigned long *vpi_bmask; /* vpi allocation table */ 534#define LPFC_MAX_VPORTS (LPFC_MAX_VPI+1)/* Max number of VPorts supported */
535 unsigned long *vpi_bmask; /* vpi allocation table */
535 536
536 /* Data structure used by fabric iocb scheduler */ 537 /* Data structure used by fabric iocb scheduler */
537 struct list_head fabric_iocb_list; 538 struct list_head fabric_iocb_list;
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index 860a52c090f4..dbced066a361 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -1060,19 +1060,24 @@ lpfc_nodev_tmo_init(struct lpfc_hba *phba, int val)
1060static void 1060static void
1061lpfc_update_rport_devloss_tmo(struct lpfc_hba *phba) 1061lpfc_update_rport_devloss_tmo(struct lpfc_hba *phba)
1062{ 1062{
1063 struct lpfc_vport *vport; 1063 struct lpfc_vport **vports;
1064 struct Scsi_Host *shost; 1064 struct Scsi_Host *shost;
1065 struct lpfc_nodelist *ndlp; 1065 struct lpfc_nodelist *ndlp;
1066 int i;
1066 1067
1067 list_for_each_entry(vport, &phba->port_list, listentry) { 1068 vports = lpfc_create_vport_work_array(phba);
1068 shost = lpfc_shost_from_vport(vport); 1069 if (vports != NULL)
1069 spin_lock_irq(shost->host_lock); 1070 for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) {
1070 list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) 1071 shost = lpfc_shost_from_vport(vports[i]);
1072 spin_lock_irq(shost->host_lock);
1073 list_for_each_entry(ndlp, &vports[i]->fc_nodes,
1074 nlp_listp)
1071 if (ndlp->rport) 1075 if (ndlp->rport)
1072 ndlp->rport->dev_loss_tmo = 1076 ndlp->rport->dev_loss_tmo =
1073 phba->cfg_devloss_tmo; 1077 phba->cfg_devloss_tmo;
1074 spin_unlock_irq(shost->host_lock); 1078 spin_unlock_irq(shost->host_lock);
1075 } 1079 }
1080 lpfc_destroy_vport_work_array(vports);
1076} 1081}
1077 1082
1078static int 1083static int
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h
index f9fdc862028a..6689d6f85adc 100644
--- a/drivers/scsi/lpfc/lpfc_crtn.h
+++ b/drivers/scsi/lpfc/lpfc_crtn.h
@@ -40,6 +40,7 @@ void lpfc_reg_vpi(struct lpfc_hba *, uint16_t, uint32_t, LPFC_MBOXQ_t *);
40void lpfc_unreg_vpi(struct lpfc_hba *, uint16_t, LPFC_MBOXQ_t *); 40void lpfc_unreg_vpi(struct lpfc_hba *, uint16_t, LPFC_MBOXQ_t *);
41void lpfc_init_link(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t, uint32_t); 41void lpfc_init_link(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t, uint32_t);
42 42
43struct lpfc_vport *lpfc_find_vport_by_did(struct lpfc_hba *, uint32_t);
43void lpfc_cleanup_rpis(struct lpfc_vport *vport, int remove); 44void lpfc_cleanup_rpis(struct lpfc_vport *vport, int remove);
44int lpfc_linkdown(struct lpfc_hba *); 45int lpfc_linkdown(struct lpfc_hba *);
45void lpfc_mbx_cmpl_read_la(struct lpfc_hba *, LPFC_MBOXQ_t *); 46void lpfc_mbx_cmpl_read_la(struct lpfc_hba *, LPFC_MBOXQ_t *);
@@ -117,6 +118,7 @@ void lpfc_els_unsol_event(struct lpfc_hba *, struct lpfc_sli_ring *,
117int lpfc_els_handle_rscn(struct lpfc_vport *); 118int lpfc_els_handle_rscn(struct lpfc_vport *);
118void lpfc_els_flush_rscn(struct lpfc_vport *); 119void lpfc_els_flush_rscn(struct lpfc_vport *);
119int lpfc_rscn_payload_check(struct lpfc_vport *, uint32_t); 120int lpfc_rscn_payload_check(struct lpfc_vport *, uint32_t);
121void lpfc_els_flush_all_cmd(struct lpfc_hba *);
120void lpfc_els_flush_cmd(struct lpfc_vport *); 122void lpfc_els_flush_cmd(struct lpfc_vport *);
121int lpfc_els_disc_adisc(struct lpfc_vport *); 123int lpfc_els_disc_adisc(struct lpfc_vport *);
122int lpfc_els_disc_plogi(struct lpfc_vport *); 124int lpfc_els_disc_plogi(struct lpfc_vport *);
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c
index edbebffa26cf..43e2e33f9a07 100644
--- a/drivers/scsi/lpfc/lpfc_ct.c
+++ b/drivers/scsi/lpfc/lpfc_ct.c
@@ -390,17 +390,19 @@ lpfc_ct_cmd(struct lpfc_vport *vport, struct lpfc_dmabuf *inmp,
390 return 0; 390 return 0;
391} 391}
392 392
393static struct lpfc_vport * 393struct lpfc_vport *
394lpfc_find_vport_by_did(struct lpfc_hba *phba, uint32_t did) { 394lpfc_find_vport_by_did(struct lpfc_hba *phba, uint32_t did) {
395
396 struct lpfc_vport *vport_curr; 395 struct lpfc_vport *vport_curr;
396 unsigned long flags;
397 397
398 spin_lock_irqsave(&phba->hbalock, flags);
398 list_for_each_entry(vport_curr, &phba->port_list, listentry) { 399 list_for_each_entry(vport_curr, &phba->port_list, listentry) {
399 if ((vport_curr->fc_myDID) && 400 if ((vport_curr->fc_myDID) && (vport_curr->fc_myDID == did)) {
400 (vport_curr->fc_myDID == did)) 401 spin_unlock_irqrestore(&phba->hbalock, flags);
401 return vport_curr; 402 return vport_curr;
403 }
402 } 404 }
403 405 spin_unlock_irqrestore(&phba->hbalock, flags);
404 return NULL; 406 return NULL;
405} 407}
406 408
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index 68fc975d4e52..b8e048a467d2 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -2800,7 +2800,6 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
2800 struct Scsi_Host *shost = lpfc_shost_from_vport(vport); 2800 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2801 struct lpfc_hba *phba = vport->phba; 2801 struct lpfc_hba *phba = vport->phba;
2802 struct lpfc_dmabuf *pcmd; 2802 struct lpfc_dmabuf *pcmd;
2803 struct lpfc_vport *next_vport;
2804 uint32_t *lp, *datap; 2803 uint32_t *lp, *datap;
2805 IOCB_t *icmd; 2804 IOCB_t *icmd;
2806 uint32_t payload_len, length, nportid, *cmd; 2805 uint32_t payload_len, length, nportid, *cmd;
@@ -2850,13 +2849,8 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
2850 nportid = ((be32_to_cpu(nportid)) & Mask_DID); 2849 nportid = ((be32_to_cpu(nportid)) & Mask_DID);
2851 i -= sizeof(uint32_t); 2850 i -= sizeof(uint32_t);
2852 rscn_id++; 2851 rscn_id++;
2853 list_for_each_entry(next_vport, &phba->port_list, 2852 if (lpfc_find_vport_by_did(phba, nportid))
2854 listentry) { 2853 hba_id++;
2855 if (nportid == next_vport->fc_myDID) {
2856 hba_id++;
2857 break;
2858 }
2859 }
2860 } 2854 }
2861 if (rscn_id == hba_id) { 2855 if (rscn_id == hba_id) {
2862 /* ALL NPortIDs in RSCN are on HBA */ 2856 /* ALL NPortIDs in RSCN are on HBA */
@@ -3740,6 +3734,50 @@ lpfc_els_flush_cmd(struct lpfc_vport *vport)
3740 return; 3734 return;
3741} 3735}
3742 3736
3737void
3738lpfc_els_flush_all_cmd(struct lpfc_hba *phba)
3739{
3740 LIST_HEAD(completions);
3741 struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_ELS_RING];
3742 struct lpfc_iocbq *tmp_iocb, *piocb;
3743 IOCB_t *cmd = NULL;
3744
3745 lpfc_fabric_abort_hba(phba);
3746 spin_lock_irq(&phba->hbalock);
3747 list_for_each_entry_safe(piocb, tmp_iocb, &pring->txq, list) {
3748 cmd = &piocb->iocb;
3749 if (piocb->iocb_flag & LPFC_IO_LIBDFC)
3750 continue;
3751 /* Do not flush out the QUE_RING and ABORT/CLOSE iocbs */
3752 if (cmd->ulpCommand == CMD_QUE_RING_BUF_CN ||
3753 cmd->ulpCommand == CMD_QUE_RING_BUF64_CN ||
3754 cmd->ulpCommand == CMD_CLOSE_XRI_CN ||
3755 cmd->ulpCommand == CMD_ABORT_XRI_CN)
3756 continue;
3757 list_move_tail(&piocb->list, &completions);
3758 pring->txq_cnt--;
3759 }
3760 list_for_each_entry_safe(piocb, tmp_iocb, &pring->txcmplq, list) {
3761 if (piocb->iocb_flag & LPFC_IO_LIBDFC)
3762 continue;
3763 lpfc_sli_issue_abort_iotag(phba, pring, piocb);
3764 }
3765 spin_unlock_irq(&phba->hbalock);
3766 while (!list_empty(&completions)) {
3767 piocb = list_get_first(&completions, struct lpfc_iocbq, list);
3768 cmd = &piocb->iocb;
3769 list_del_init(&piocb->list);
3770 if (!piocb->iocb_cmpl)
3771 lpfc_sli_release_iocbq(phba, piocb);
3772 else {
3773 cmd->ulpStatus = IOSTAT_LOCAL_REJECT;
3774 cmd->un.ulpWord[4] = IOERR_SLI_ABORTED;
3775 (piocb->iocb_cmpl) (phba, piocb, piocb);
3776 }
3777 }
3778 return;
3779}
3780
3743static void 3781static void
3744lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, 3782lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
3745 struct lpfc_vport *vport, struct lpfc_iocbq *elsiocb) 3783 struct lpfc_vport *vport, struct lpfc_iocbq *elsiocb)
@@ -4009,11 +4047,16 @@ static struct lpfc_vport *
4009lpfc_find_vport_by_vpid(struct lpfc_hba *phba, uint16_t vpi) 4047lpfc_find_vport_by_vpid(struct lpfc_hba *phba, uint16_t vpi)
4010{ 4048{
4011 struct lpfc_vport *vport; 4049 struct lpfc_vport *vport;
4050 unsigned long flags;
4012 4051
4052 spin_lock_irqsave(&phba->hbalock, flags);
4013 list_for_each_entry(vport, &phba->port_list, listentry) { 4053 list_for_each_entry(vport, &phba->port_list, listentry) {
4014 if (vport->vpi == vpi) 4054 if (vport->vpi == vpi) {
4055 spin_unlock_irqrestore(&phba->hbalock, flags);
4015 return vport; 4056 return vport;
4057 }
4016 } 4058 }
4059 spin_unlock_irqrestore(&phba->hbalock, flags);
4017 return NULL; 4060 return NULL;
4018} 4061}
4019 4062
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index ea27bbb81552..556d55fc9456 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -349,7 +349,8 @@ lpfc_work_done(struct lpfc_hba *phba)
349{ 349{
350 struct lpfc_sli_ring *pring; 350 struct lpfc_sli_ring *pring;
351 uint32_t ha_copy, status, control, work_port_events; 351 uint32_t ha_copy, status, control, work_port_events;
352 struct lpfc_vport *vport; 352 struct lpfc_vport **vports;
353 int i;
353 354
354 spin_lock_irq(&phba->hbalock); 355 spin_lock_irq(&phba->hbalock);
355 ha_copy = phba->work_ha; 356 ha_copy = phba->work_ha;
@@ -364,48 +365,31 @@ lpfc_work_done(struct lpfc_hba *phba)
364 365
365 if (ha_copy & HA_LATT) 366 if (ha_copy & HA_LATT)
366 lpfc_handle_latt(phba); 367 lpfc_handle_latt(phba);
367 368 vports = lpfc_create_vport_work_array(phba);
368 spin_lock_irq(&phba->hbalock); 369 if (vports != NULL)
369 list_for_each_entry(vport, &phba->port_list, listentry) { 370 for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) {
370 struct Scsi_Host *shost = lpfc_shost_from_vport(vport); 371 work_port_events = vports[i]->work_port_events;
371 372 if (work_port_events & WORKER_DISC_TMO)
372 if (!scsi_host_get(shost)) { 373 lpfc_disc_timeout_handler(vports[i]);
373 continue; 374 if (work_port_events & WORKER_ELS_TMO)
375 lpfc_els_timeout_handler(vports[i]);
376 if (work_port_events & WORKER_HB_TMO)
377 lpfc_hb_timeout_handler(phba);
378 if (work_port_events & WORKER_MBOX_TMO)
379 lpfc_mbox_timeout_handler(phba);
380 if (work_port_events & WORKER_FABRIC_BLOCK_TMO)
381 lpfc_unblock_fabric_iocbs(phba);
382 if (work_port_events & WORKER_FDMI_TMO)
383 lpfc_fdmi_timeout_handler(vports[i]);
384 if (work_port_events & WORKER_RAMP_DOWN_QUEUE)
385 lpfc_ramp_down_queue_handler(phba);
386 if (work_port_events & WORKER_RAMP_UP_QUEUE)
387 lpfc_ramp_up_queue_handler(phba);
388 spin_lock_irq(&vports[i]->work_port_lock);
389 vports[i]->work_port_events &= ~work_port_events;
390 spin_unlock_irq(&vports[i]->work_port_lock);
374 } 391 }
375 spin_unlock_irq(&phba->hbalock); 392 lpfc_destroy_vport_work_array(vports);
376 work_port_events = vport->work_port_events;
377
378 if (work_port_events & WORKER_DISC_TMO)
379 lpfc_disc_timeout_handler(vport);
380
381 if (work_port_events & WORKER_ELS_TMO)
382 lpfc_els_timeout_handler(vport);
383
384 if (work_port_events & WORKER_HB_TMO)
385 lpfc_hb_timeout_handler(phba);
386
387 if (work_port_events & WORKER_MBOX_TMO)
388 lpfc_mbox_timeout_handler(phba);
389
390 if (work_port_events & WORKER_FABRIC_BLOCK_TMO)
391 lpfc_unblock_fabric_iocbs(phba);
392
393 if (work_port_events & WORKER_FDMI_TMO)
394 lpfc_fdmi_timeout_handler(vport);
395
396 if (work_port_events & WORKER_RAMP_DOWN_QUEUE)
397 lpfc_ramp_down_queue_handler(phba);
398
399 if (work_port_events & WORKER_RAMP_UP_QUEUE)
400 lpfc_ramp_up_queue_handler(phba);
401
402 spin_lock_irq(&vport->work_port_lock);
403 vport->work_port_events &= ~work_port_events;
404 spin_unlock_irq(&vport->work_port_lock);
405 scsi_host_put(shost);
406 spin_lock_irq(&phba->hbalock);
407 }
408 spin_unlock_irq(&phba->hbalock);
409 393
410 pring = &phba->sli.ring[LPFC_ELS_RING]; 394 pring = &phba->sli.ring[LPFC_ELS_RING];
411 status = (ha_copy & (HA_RXMASK << (4*LPFC_ELS_RING))); 395 status = (ha_copy & (HA_RXMASK << (4*LPFC_ELS_RING)));
@@ -448,32 +432,22 @@ static int
448check_work_wait_done(struct lpfc_hba *phba) 432check_work_wait_done(struct lpfc_hba *phba)
449{ 433{
450 struct lpfc_vport *vport; 434 struct lpfc_vport *vport;
451 struct lpfc_sli_ring *pring; 435 struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_ELS_RING];
452 int rc = 0; 436 int rc = 0;
453 437
454 spin_lock_irq(&phba->hbalock); 438 spin_lock_irq(&phba->hbalock);
455 list_for_each_entry(vport, &phba->port_list, listentry) { 439 list_for_each_entry(vport, &phba->port_list, listentry) {
456 if (vport->work_port_events) { 440 if (vport->work_port_events) {
457 rc = 1; 441 rc = 1;
458 goto exit; 442 break;
459 } 443 }
460 } 444 }
461 445 if (rc || phba->work_ha || (!list_empty(&phba->work_list)) ||
462 if (phba->work_ha || (!list_empty(&phba->work_list)) || 446 kthread_should_stop() || pring->flag & LPFC_DEFERRED_RING_EVENT) {
463 kthread_should_stop()) {
464 rc = 1;
465 goto exit;
466 }
467
468 pring = &phba->sli.ring[LPFC_ELS_RING];
469 if (pring->flag & LPFC_DEFERRED_RING_EVENT)
470 rc = 1; 447 rc = 1;
471exit:
472 if (rc)
473 phba->work_found++; 448 phba->work_found++;
474 else 449 } else
475 phba->work_found = 0; 450 phba->work_found = 0;
476
477 spin_unlock_irq(&phba->hbalock); 451 spin_unlock_irq(&phba->hbalock);
478 return rc; 452 return rc;
479} 453}
@@ -601,7 +575,6 @@ lpfc_linkdown_port(struct lpfc_vport *vport)
601 575
602 /* free any ndlp's on unused list */ 576 /* free any ndlp's on unused list */
603 list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) 577 list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp)
604 /* free any ndlp's in unused state */
605 if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) 578 if (ndlp->nlp_state == NLP_STE_UNUSED_NODE)
606 lpfc_drop_node(vport, ndlp); 579 lpfc_drop_node(vport, ndlp);
607 580
@@ -614,8 +587,9 @@ lpfc_linkdown(struct lpfc_hba *phba)
614{ 587{
615 struct lpfc_vport *vport = phba->pport; 588 struct lpfc_vport *vport = phba->pport;
616 struct Scsi_Host *shost = lpfc_shost_from_vport(vport); 589 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
617 struct lpfc_vport *port_iterator; 590 struct lpfc_vport **vports;
618 LPFC_MBOXQ_t *mb; 591 LPFC_MBOXQ_t *mb;
592 int i;
619 593
620 if (phba->link_state == LPFC_LINK_DOWN) { 594 if (phba->link_state == LPFC_LINK_DOWN) {
621 return 0; 595 return 0;
@@ -626,13 +600,13 @@ lpfc_linkdown(struct lpfc_hba *phba)
626 phba->pport->fc_flag &= ~FC_LBIT; 600 phba->pport->fc_flag &= ~FC_LBIT;
627 } 601 }
628 spin_unlock_irq(&phba->hbalock); 602 spin_unlock_irq(&phba->hbalock);
629 603 vports = lpfc_create_vport_work_array(phba);
630 list_for_each_entry(port_iterator, &phba->port_list, listentry) { 604 if (vports != NULL)
631 605 for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) {
632 /* Issue a LINK DOWN event to all nodes */ 606 /* Issue a LINK DOWN event to all nodes */
633 lpfc_linkdown_port(port_iterator); 607 lpfc_linkdown_port(vports[i]);
634 } 608 }
635 609 lpfc_destroy_vport_work_array(vports);
636 /* Clean up any firmware default rpi's */ 610 /* Clean up any firmware default rpi's */
637 mb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); 611 mb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
638 if (mb) { 612 if (mb) {
@@ -733,7 +707,8 @@ lpfc_linkup_port(struct lpfc_vport *vport)
733static int 707static int
734lpfc_linkup(struct lpfc_hba *phba) 708lpfc_linkup(struct lpfc_hba *phba)
735{ 709{
736 struct lpfc_vport *vport; 710 struct lpfc_vport **vports;
711 int i;
737 712
738 phba->link_state = LPFC_LINK_UP; 713 phba->link_state = LPFC_LINK_UP;
739 714
@@ -741,9 +716,11 @@ lpfc_linkup(struct lpfc_hba *phba)
741 clear_bit(FABRIC_COMANDS_BLOCKED, &phba->bit_flags); 716 clear_bit(FABRIC_COMANDS_BLOCKED, &phba->bit_flags);
742 del_timer_sync(&phba->fabric_block_timer); 717 del_timer_sync(&phba->fabric_block_timer);
743 718
744 list_for_each_entry(vport, &phba->port_list, listentry) { 719 vports = lpfc_create_vport_work_array(phba);
745 lpfc_linkup_port(vport); 720 if (vports != NULL)
746 } 721 for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++)
722 lpfc_linkup_port(vports[i]);
723 lpfc_destroy_vport_work_array(vports);
747 if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) 724 if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED)
748 lpfc_issue_clear_la(phba, phba->pport); 725 lpfc_issue_clear_la(phba, phba->pport);
749 726
@@ -1298,15 +1275,15 @@ void
1298lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) 1275lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
1299{ 1276{
1300 struct lpfc_vport *vport = pmb->vport; 1277 struct lpfc_vport *vport = pmb->vport;
1301 struct lpfc_vport *next_vport;
1302 MAILBOX_t *mb = &pmb->mb; 1278 MAILBOX_t *mb = &pmb->mb;
1303 struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) (pmb->context1); 1279 struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) (pmb->context1);
1304 struct lpfc_nodelist *ndlp; 1280 struct lpfc_nodelist *ndlp;
1305 ndlp = (struct lpfc_nodelist *) pmb->context2; 1281 struct lpfc_vport **vports;
1282 int i;
1306 1283
1284 ndlp = (struct lpfc_nodelist *) pmb->context2;
1307 pmb->context1 = NULL; 1285 pmb->context1 = NULL;
1308 pmb->context2 = NULL; 1286 pmb->context2 = NULL;
1309
1310 if (mb->mbxStatus) { 1287 if (mb->mbxStatus) {
1311 lpfc_mbuf_free(phba, mp->virt, mp->phys); 1288 lpfc_mbuf_free(phba, mp->virt, mp->phys);
1312 kfree(mp); 1289 kfree(mp);
@@ -1337,21 +1314,27 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
1337 lpfc_nlp_put(ndlp); /* Drop the reference from the mbox */ 1314 lpfc_nlp_put(ndlp); /* Drop the reference from the mbox */
1338 1315
1339 if (vport->port_state == LPFC_FABRIC_CFG_LINK) { 1316 if (vport->port_state == LPFC_FABRIC_CFG_LINK) {
1340 list_for_each_entry(next_vport, &phba->port_list, listentry) { 1317 vports = lpfc_create_vport_work_array(phba);
1341 if (next_vport->port_type == LPFC_PHYSICAL_PORT) 1318 if (vports != NULL)
1342 continue; 1319 for(i = 0;
1343 1320 i < LPFC_MAX_VPORTS && vports[i] != NULL;
1344 if (phba->link_flag & LS_NPIV_FAB_SUPPORTED) 1321 i++) {
1345 lpfc_initial_fdisc(next_vport); 1322 if (vports[i]->port_type == LPFC_PHYSICAL_PORT)
1346 else if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) { 1323 continue;
1347 lpfc_vport_set_state(vport, 1324 if (phba->link_flag & LS_NPIV_FAB_SUPPORTED)
1348 FC_VPORT_NO_FABRIC_SUPP); 1325 lpfc_initial_fdisc(vports[i]);
1349 lpfc_printf_log(phba, KERN_ERR, LOG_ELS, 1326 else if (phba->sli3_options &
1350 "%d (%d):0259 No NPIV Fabric " 1327 LPFC_SLI3_NPIV_ENABLED) {
1351 "support\n", 1328 lpfc_vport_set_state(vports[i],
1352 phba->brd_no, vport->vpi); 1329 FC_VPORT_NO_FABRIC_SUPP);
1330 lpfc_printf_log(phba, KERN_ERR, LOG_ELS,
1331 "%d (%d):0259 No NPIV "
1332 "Fabric support\n",
1333 phba->brd_no,
1334 vports[i]->vpi);
1335 }
1353 } 1336 }
1354 } 1337 lpfc_destroy_vport_work_array(vports);
1355 lpfc_do_scr_ns_plogi(phba, vport); 1338 lpfc_do_scr_ns_plogi(phba, vport);
1356 } 1339 }
1357 1340
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 07bd0dcdf0d6..484070c82974 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -437,16 +437,18 @@ lpfc_config_port_post(struct lpfc_hba *phba)
437int 437int
438lpfc_hba_down_prep(struct lpfc_hba *phba) 438lpfc_hba_down_prep(struct lpfc_hba *phba)
439{ 439{
440 struct lpfc_vport *vport = phba->pport; 440 struct lpfc_vport **vports;
441 int i;
441 442
442 /* Disable interrupts */ 443 /* Disable interrupts */
443 writel(0, phba->HCregaddr); 444 writel(0, phba->HCregaddr);
444 readl(phba->HCregaddr); /* flush */ 445 readl(phba->HCregaddr); /* flush */
445 446
446 list_for_each_entry(vport, &phba->port_list, listentry) { 447 vports = lpfc_create_vport_work_array(phba);
447 lpfc_cleanup_discovery_resources(vport); 448 if (vports != NULL)
448 } 449 for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++)
449 450 lpfc_cleanup_discovery_resources(vports[i]);
451 lpfc_destroy_vport_work_array(vports);
450 return 0; 452 return 0;
451} 453}
452 454
@@ -615,9 +617,10 @@ lpfc_handle_eratt(struct lpfc_hba *phba)
615 struct lpfc_vport *vport = phba->pport; 617 struct lpfc_vport *vport = phba->pport;
616 struct lpfc_sli *psli = &phba->sli; 618 struct lpfc_sli *psli = &phba->sli;
617 struct lpfc_sli_ring *pring; 619 struct lpfc_sli_ring *pring;
618 struct lpfc_vport *port_iterator; 620 struct lpfc_vport **vports;
619 uint32_t event_data; 621 uint32_t event_data;
620 struct Scsi_Host *shost; 622 struct Scsi_Host *shost;
623 int i;
621 624
622 /* If the pci channel is offline, ignore possible errors, 625 /* If the pci channel is offline, ignore possible errors,
623 * since we cannot communicate with the pci card anyway. */ 626 * since we cannot communicate with the pci card anyway. */
@@ -632,14 +635,17 @@ lpfc_handle_eratt(struct lpfc_hba *phba)
632 "Data: x%x x%x x%x\n", 635 "Data: x%x x%x x%x\n",
633 phba->brd_no, phba->work_hs, 636 phba->brd_no, phba->work_hs,
634 phba->work_status[0], phba->work_status[1]); 637 phba->work_status[0], phba->work_status[1]);
635 list_for_each_entry(port_iterator, &phba->port_list, 638 vports = lpfc_create_vport_work_array(phba);
636 listentry) { 639 if (vports != NULL)
637 shost = lpfc_shost_from_vport(port_iterator); 640 for(i = 0;
638 641 i < LPFC_MAX_VPORTS && vports[i] != NULL;
639 spin_lock_irq(shost->host_lock); 642 i++){
640 port_iterator->fc_flag |= FC_ESTABLISH_LINK; 643 shost = lpfc_shost_from_vport(vports[i]);
641 spin_unlock_irq(shost->host_lock); 644 spin_lock_irq(shost->host_lock);
642 } 645 vports[i]->fc_flag |= FC_ESTABLISH_LINK;
646 spin_unlock_irq(shost->host_lock);
647 }
648 lpfc_destroy_vport_work_array(vports);
643 spin_lock_irq(&phba->hbalock); 649 spin_lock_irq(&phba->hbalock);
644 psli->sli_flag &= ~LPFC_SLI2_ACTIVE; 650 psli->sli_flag &= ~LPFC_SLI2_ACTIVE;
645 spin_unlock_irq(&phba->hbalock); 651 spin_unlock_irq(&phba->hbalock);
@@ -708,7 +714,6 @@ lpfc_handle_latt(struct lpfc_hba *phba)
708{ 714{
709 struct lpfc_vport *vport = phba->pport; 715 struct lpfc_vport *vport = phba->pport;
710 struct lpfc_sli *psli = &phba->sli; 716 struct lpfc_sli *psli = &phba->sli;
711 struct lpfc_vport *port_iterator;
712 LPFC_MBOXQ_t *pmb; 717 LPFC_MBOXQ_t *pmb;
713 volatile uint32_t control; 718 volatile uint32_t control;
714 struct lpfc_dmabuf *mp; 719 struct lpfc_dmabuf *mp;
@@ -729,8 +734,7 @@ lpfc_handle_latt(struct lpfc_hba *phba)
729 rc = -EIO; 734 rc = -EIO;
730 735
731 /* Cleanup any outstanding ELS commands */ 736 /* Cleanup any outstanding ELS commands */
732 list_for_each_entry(port_iterator, &phba->port_list, listentry) 737 lpfc_els_flush_all_cmd(phba);
733 lpfc_els_flush_cmd(port_iterator);
734 738
735 psli->slistat.link_event++; 739 psli->slistat.link_event++;
736 lpfc_read_la(phba, pmb, mp); 740 lpfc_read_la(phba, pmb, mp);
@@ -1313,22 +1317,26 @@ static void
1313lpfc_establish_link_tmo(unsigned long ptr) 1317lpfc_establish_link_tmo(unsigned long ptr)
1314{ 1318{
1315 struct lpfc_hba *phba = (struct lpfc_hba *) ptr; 1319 struct lpfc_hba *phba = (struct lpfc_hba *) ptr;
1316 struct lpfc_vport *vport = phba->pport; 1320 struct lpfc_vport **vports;
1317 unsigned long iflag; 1321 unsigned long iflag;
1322 int i;
1318 1323
1319 /* Re-establishing Link, timer expired */ 1324 /* Re-establishing Link, timer expired */
1320 lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT, 1325 lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT,
1321 "%d:1300 Re-establishing Link, timer expired " 1326 "%d:1300 Re-establishing Link, timer expired "
1322 "Data: x%x x%x\n", 1327 "Data: x%x x%x\n",
1323 phba->brd_no, vport->fc_flag, 1328 phba->brd_no, phba->pport->fc_flag,
1324 vport->port_state); 1329 phba->pport->port_state);
1325 list_for_each_entry(vport, &phba->port_list, listentry) { 1330 vports = lpfc_create_vport_work_array(phba);
1326 struct Scsi_Host *shost = lpfc_shost_from_vport(vport); 1331 if (vports != NULL)
1327 1332 for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) {
1328 spin_lock_irqsave(shost->host_lock, iflag); 1333 struct Scsi_Host *shost;
1329 vport->fc_flag &= ~FC_ESTABLISH_LINK; 1334 shost = lpfc_shost_from_vport(vports[i]);
1330 spin_unlock_irqrestore(shost->host_lock, iflag); 1335 spin_lock_irqsave(shost->host_lock, iflag);
1331 } 1336 vports[i]->fc_flag &= ~FC_ESTABLISH_LINK;
1337 spin_unlock_irqrestore(shost->host_lock, iflag);
1338 }
1339 lpfc_destroy_vport_work_array(vports);
1332} 1340}
1333 1341
1334void 1342void
@@ -1343,12 +1351,16 @@ lpfc_stop_vport_timers(struct lpfc_vport *vport)
1343static void 1351static void
1344lpfc_stop_phba_timers(struct lpfc_hba *phba) 1352lpfc_stop_phba_timers(struct lpfc_hba *phba)
1345{ 1353{
1346 struct lpfc_vport *vport; 1354 struct lpfc_vport **vports;
1355 int i;
1347 1356
1348 del_timer_sync(&phba->fcp_poll_timer); 1357 del_timer_sync(&phba->fcp_poll_timer);
1349 del_timer_sync(&phba->fc_estabtmo); 1358 del_timer_sync(&phba->fc_estabtmo);
1350 list_for_each_entry(vport, &phba->port_list, listentry) 1359 vports = lpfc_create_vport_work_array(phba);
1351 lpfc_stop_vport_timers(vport); 1360 if (vports != NULL)
1361 for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++)
1362 lpfc_stop_vport_timers(vports[i]);
1363 lpfc_destroy_vport_work_array(vports);
1352 del_timer_sync(&phba->sli.mbox_tmo); 1364 del_timer_sync(&phba->sli.mbox_tmo);
1353 del_timer_sync(&phba->fabric_block_timer); 1365 del_timer_sync(&phba->fabric_block_timer);
1354 phba->hb_outstanding = 0; 1366 phba->hb_outstanding = 0;
@@ -1360,6 +1372,8 @@ int
1360lpfc_online(struct lpfc_hba *phba) 1372lpfc_online(struct lpfc_hba *phba)
1361{ 1373{
1362 struct lpfc_vport *vport = phba->pport; 1374 struct lpfc_vport *vport = phba->pport;
1375 struct lpfc_vport **vports;
1376 int i;
1363 1377
1364 if (!phba) 1378 if (!phba)
1365 return 0; 1379 return 0;
@@ -1383,14 +1397,18 @@ lpfc_online(struct lpfc_hba *phba)
1383 return 1; 1397 return 1;
1384 } 1398 }
1385 1399
1386 list_for_each_entry(vport, &phba->port_list, listentry) { 1400 vports = lpfc_create_vport_work_array(phba);
1387 struct Scsi_Host *shost = lpfc_shost_from_vport(vport); 1401 if (vports != NULL)
1388 spin_lock_irq(shost->host_lock); 1402 for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) {
1389 vport->fc_flag &= ~FC_OFFLINE_MODE; 1403 struct Scsi_Host *shost;
1390 if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) 1404 shost = lpfc_shost_from_vport(vports[i]);
1391 vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; 1405 spin_lock_irq(shost->host_lock);
1392 spin_unlock_irq(shost->host_lock); 1406 vports[i]->fc_flag &= ~FC_OFFLINE_MODE;
1393 } 1407 if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED)
1408 vports[i]->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
1409 spin_unlock_irq(shost->host_lock);
1410 }
1411 lpfc_destroy_vport_work_array(vports);
1394 1412
1395 lpfc_unblock_mgmt_io(phba); 1413 lpfc_unblock_mgmt_io(phba);
1396 return 0; 1414 return 0;
@@ -1440,39 +1458,35 @@ lpfc_offline_prep(struct lpfc_hba * phba)
1440void 1458void
1441lpfc_offline(struct lpfc_hba *phba) 1459lpfc_offline(struct lpfc_hba *phba)
1442{ 1460{
1443 struct lpfc_vport *vport = phba->pport; 1461 struct Scsi_Host *shost;
1444 struct Scsi_Host *shost = lpfc_shost_from_vport(vport); 1462 struct lpfc_vport **vports;
1445 struct lpfc_vport *port_iterator; 1463 int i;
1446 1464
1447 if (vport->fc_flag & FC_OFFLINE_MODE) 1465 if (phba->pport->fc_flag & FC_OFFLINE_MODE)
1448 return; 1466 return;
1449 1467
1450 /* stop all timers associated with this hba */ 1468 /* stop all timers associated with this hba */
1451 lpfc_stop_phba_timers(phba); 1469 lpfc_stop_phba_timers(phba);
1452 list_for_each_entry(port_iterator, &phba->port_list, listentry) {
1453 port_iterator->work_port_events = 0;
1454 }
1455
1456 lpfc_printf_log(phba, KERN_WARNING, LOG_INIT, 1470 lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
1457 "%d:0460 Bring Adapter offline\n", 1471 "%d:0460 Bring Adapter offline\n",
1458 phba->brd_no); 1472 phba->brd_no);
1459
1460 /* Bring down the SLI Layer and cleanup. The HBA is offline 1473 /* Bring down the SLI Layer and cleanup. The HBA is offline
1461 now. */ 1474 now. */
1462 lpfc_sli_hba_down(phba); 1475 lpfc_sli_hba_down(phba);
1463 spin_lock_irq(&phba->hbalock); 1476 spin_lock_irq(&phba->hbalock);
1464 phba->work_ha = 0; 1477 phba->work_ha = 0;
1465 vport->fc_flag |= FC_OFFLINE_MODE;
1466 spin_unlock_irq(&phba->hbalock); 1478 spin_unlock_irq(&phba->hbalock);
1467 list_for_each_entry(port_iterator, &phba->port_list, listentry) { 1479 vports = lpfc_create_vport_work_array(phba);
1468 shost = lpfc_shost_from_vport(port_iterator); 1480 if (vports != NULL)
1469 1481 for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) {
1470 lpfc_cleanup(port_iterator); 1482 shost = lpfc_shost_from_vport(vports[i]);
1471 spin_lock_irq(shost->host_lock); 1483 lpfc_cleanup(vports[i]);
1472 vport->work_port_events = 0; 1484 spin_lock_irq(shost->host_lock);
1473 vport->fc_flag |= FC_OFFLINE_MODE; 1485 vports[i]->work_port_events = 0;
1474 spin_unlock_irq(shost->host_lock); 1486 vports[i]->fc_flag |= FC_OFFLINE_MODE;
1475 } 1487 spin_unlock_irq(shost->host_lock);
1488 }
1489 lpfc_destroy_vport_work_array(vports);
1476} 1490}
1477 1491
1478/****************************************************************************** 1492/******************************************************************************
@@ -1509,7 +1523,6 @@ lpfc_scsi_free(struct lpfc_hba *phba)
1509 return 0; 1523 return 0;
1510} 1524}
1511 1525
1512
1513struct lpfc_vport * 1526struct lpfc_vport *
1514lpfc_create_port(struct lpfc_hba *phba, int instance, struct fc_vport *fc_vport) 1527lpfc_create_port(struct lpfc_hba *phba, int instance, struct fc_vport *fc_vport)
1515{ 1528{
@@ -1570,7 +1583,9 @@ lpfc_create_port(struct lpfc_hba *phba, int instance, struct fc_vport *fc_vport)
1570 if (error) 1583 if (error)
1571 goto out_put_shost; 1584 goto out_put_shost;
1572 1585
1586 spin_lock_irq(&phba->hbalock);
1573 list_add_tail(&vport->listentry, &phba->port_list); 1587 list_add_tail(&vport->listentry, &phba->port_list);
1588 spin_unlock_irq(&phba->hbalock);
1574 return vport; 1589 return vport;
1575 1590
1576out_put_shost: 1591out_put_shost:
@@ -1990,8 +2005,10 @@ lpfc_pci_remove_one(struct pci_dev *pdev)
1990 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; 2005 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
1991 struct lpfc_hba *phba = vport->phba; 2006 struct lpfc_hba *phba = vport->phba;
1992 struct lpfc_vport *port_iterator; 2007 struct lpfc_vport *port_iterator;
2008 spin_lock_irq(&phba->hbalock);
1993 list_for_each_entry(port_iterator, &phba->port_list, listentry) 2009 list_for_each_entry(port_iterator, &phba->port_list, listentry)
1994 port_iterator->load_flag |= FC_UNLOADING; 2010 port_iterator->load_flag |= FC_UNLOADING;
2011 spin_unlock_irq(&phba->hbalock);
1995 2012
1996 kfree(vport->vname); 2013 kfree(vport->vname);
1997 lpfc_free_sysfs_attr(vport); 2014 lpfc_free_sysfs_attr(vport);
@@ -2012,7 +2029,6 @@ lpfc_pci_remove_one(struct pci_dev *pdev)
2012 list_del_init(&vport->listentry); 2029 list_del_init(&vport->listentry);
2013 spin_unlock_irq(&phba->hbalock); 2030 spin_unlock_irq(&phba->hbalock);
2014 2031
2015
2016 lpfc_debugfs_terminate(vport); 2032 lpfc_debugfs_terminate(vport);
2017 lpfc_cleanup(vport); 2033 lpfc_cleanup(vport);
2018 2034
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index 8f45bbc42126..0284ded96bad 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -119,42 +119,40 @@ lpfc_rampup_queue_depth(struct lpfc_hba *phba,
119void 119void
120lpfc_ramp_down_queue_handler(struct lpfc_hba *phba) 120lpfc_ramp_down_queue_handler(struct lpfc_hba *phba)
121{ 121{
122 struct lpfc_vport *vport; 122 struct lpfc_vport **vports;
123 struct Scsi_Host *host; 123 struct Scsi_Host *shost;
124 struct scsi_device *sdev; 124 struct scsi_device *sdev;
125 unsigned long new_queue_depth; 125 unsigned long new_queue_depth;
126 unsigned long num_rsrc_err, num_cmd_success; 126 unsigned long num_rsrc_err, num_cmd_success;
127 int i;
127 128
128 num_rsrc_err = atomic_read(&phba->num_rsrc_err); 129 num_rsrc_err = atomic_read(&phba->num_rsrc_err);
129 num_cmd_success = atomic_read(&phba->num_cmd_success); 130 num_cmd_success = atomic_read(&phba->num_cmd_success);
130 131
131 spin_lock_irq(&phba->hbalock); 132 vports = lpfc_create_vport_work_array(phba);
132 list_for_each_entry(vport, &phba->port_list, listentry) { 133 if (vports != NULL)
133 host = lpfc_shost_from_vport(vport); 134 for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) {
134 if (!scsi_host_get(host)) 135 shost = lpfc_shost_from_vport(vports[i]);
135 continue; 136 shost_for_each_device(sdev, shost) {
136
137 spin_unlock_irq(&phba->hbalock);
138
139 shost_for_each_device(sdev, host) {
140 new_queue_depth = sdev->queue_depth * num_rsrc_err /
141 (num_rsrc_err + num_cmd_success);
142 if (!new_queue_depth)
143 new_queue_depth = sdev->queue_depth - 1;
144 else
145 new_queue_depth = 137 new_queue_depth =
146 sdev->queue_depth - new_queue_depth; 138 sdev->queue_depth * num_rsrc_err /
147 139 (num_rsrc_err + num_cmd_success);
148 if (sdev->ordered_tags) 140 if (!new_queue_depth)
149 scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, 141 new_queue_depth = sdev->queue_depth - 1;
150 new_queue_depth); 142 else
151 else 143 new_queue_depth = sdev->queue_depth -
152 scsi_adjust_queue_depth(sdev, MSG_SIMPLE_TAG, 144 new_queue_depth;
153 new_queue_depth); 145 if (sdev->ordered_tags)
146 scsi_adjust_queue_depth(sdev,
147 MSG_ORDERED_TAG,
148 new_queue_depth);
149 else
150 scsi_adjust_queue_depth(sdev,
151 MSG_SIMPLE_TAG,
152 new_queue_depth);
153 }
154 } 154 }
155 spin_lock_irq(&phba->hbalock); 155 lpfc_destroy_vport_work_array(vports);
156 scsi_host_put(host);
157 }
158 spin_unlock_irq(&phba->hbalock); 156 spin_unlock_irq(&phba->hbalock);
159 atomic_set(&phba->num_rsrc_err, 0); 157 atomic_set(&phba->num_rsrc_err, 0);
160 atomic_set(&phba->num_cmd_success, 0); 158 atomic_set(&phba->num_cmd_success, 0);
@@ -163,29 +161,27 @@ lpfc_ramp_down_queue_handler(struct lpfc_hba *phba)
163void 161void
164lpfc_ramp_up_queue_handler(struct lpfc_hba *phba) 162lpfc_ramp_up_queue_handler(struct lpfc_hba *phba)
165{ 163{
166 struct lpfc_vport *vport; 164 struct lpfc_vport **vports;
167 struct Scsi_Host *host; 165 struct Scsi_Host *shost;
168 struct scsi_device *sdev; 166 struct scsi_device *sdev;
169 167 int i;
170 spin_lock_irq(&phba->hbalock); 168
171 list_for_each_entry(vport, &phba->port_list, listentry) { 169 vports = lpfc_create_vport_work_array(phba);
172 host = lpfc_shost_from_vport(vport); 170 if (vports != NULL)
173 if (!scsi_host_get(host)) 171 for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) {
174 continue; 172 shost = lpfc_shost_from_vport(vports[i]);
175 173 shost_for_each_device(sdev, shost) {
176 spin_unlock_irq(&phba->hbalock); 174 if (sdev->ordered_tags)
177 shost_for_each_device(sdev, host) { 175 scsi_adjust_queue_depth(sdev,
178 if (sdev->ordered_tags) 176 MSG_ORDERED_TAG,
179 scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, 177 sdev->queue_depth+1);
180 sdev->queue_depth+1); 178 else
181 else 179 scsi_adjust_queue_depth(sdev,
182 scsi_adjust_queue_depth(sdev, MSG_SIMPLE_TAG, 180 MSG_SIMPLE_TAG,
183 sdev->queue_depth+1); 181 sdev->queue_depth+1);
182 }
184 } 183 }
185 spin_lock_irq(&phba->hbalock); 184 lpfc_destroy_vport_work_array(vports);
186 scsi_host_put(host);
187 }
188 spin_unlock_irq(&phba->hbalock);
189 atomic_set(&phba->num_rsrc_err, 0); 185 atomic_set(&phba->num_rsrc_err, 0);
190 atomic_set(&phba->num_cmd_success, 0); 186 atomic_set(&phba->num_cmd_success, 0);
191} 187}
diff --git a/drivers/scsi/lpfc/lpfc_vport.c b/drivers/scsi/lpfc/lpfc_vport.c
index c5918a643014..e066855b0783 100644
--- a/drivers/scsi/lpfc/lpfc_vport.c
+++ b/drivers/scsi/lpfc/lpfc_vport.c
@@ -176,16 +176,21 @@ static int
176lpfc_unique_wwpn(struct lpfc_hba *phba, struct lpfc_vport *new_vport) 176lpfc_unique_wwpn(struct lpfc_hba *phba, struct lpfc_vport *new_vport)
177{ 177{
178 struct lpfc_vport *vport; 178 struct lpfc_vport *vport;
179 unsigned long flags;
179 180
181 spin_lock_irqsave(&phba->hbalock, flags);
180 list_for_each_entry(vport, &phba->port_list, listentry) { 182 list_for_each_entry(vport, &phba->port_list, listentry) {
181 if (vport == new_vport) 183 if (vport == new_vport)
182 continue; 184 continue;
183 /* If they match, return not unique */ 185 /* If they match, return not unique */
184 if (memcmp(&vport->fc_sparam.portName, 186 if (memcmp(&vport->fc_sparam.portName,
185 &new_vport->fc_sparam.portName, 187 &new_vport->fc_sparam.portName,
186 sizeof(struct lpfc_name)) == 0) 188 sizeof(struct lpfc_name)) == 0) {
189 spin_unlock_irqrestore(&phba->hbalock, flags);
187 return 0; 190 return 0;
191 }
188 } 192 }
193 spin_unlock_irqrestore(&phba->hbalock, flags);
189 return 1; 194 return 1;
190} 195}
191 196
@@ -524,6 +529,36 @@ out:
524 return rc; 529 return rc;
525} 530}
526 531
527
528EXPORT_SYMBOL(lpfc_vport_create); 532EXPORT_SYMBOL(lpfc_vport_create);
529EXPORT_SYMBOL(lpfc_vport_delete); 533EXPORT_SYMBOL(lpfc_vport_delete);
534
535struct lpfc_vport **
536lpfc_create_vport_work_array(struct lpfc_hba *phba)
537{
538 struct lpfc_vport *port_iterator;
539 struct lpfc_vport **vports;
540 int index = 0;
541 vports = kzalloc(LPFC_MAX_VPORTS * sizeof(struct lpfc_vport *),
542 GFP_KERNEL);
543 if (vports == NULL)
544 return NULL;
545 spin_lock_irq(&phba->hbalock);
546 list_for_each_entry(port_iterator, &phba->port_list, listentry) {
547 if (!scsi_host_get(lpfc_shost_from_vport(port_iterator)))
548 continue;
549 vports[index++] = port_iterator;
550 }
551 spin_unlock_irq(&phba->hbalock);
552 return vports;
553}
554
555void
556lpfc_destroy_vport_work_array(struct lpfc_vport **vports)
557{
558 int i;
559 if (vports == NULL)
560 return;
561 for (i=0; vports[i] != NULL && i < LPFC_MAX_VPORTS; i++)
562 scsi_host_put(lpfc_shost_from_vport(vports[i]));
563 kfree(vports);
564}
diff --git a/drivers/scsi/lpfc/lpfc_vport.h b/drivers/scsi/lpfc/lpfc_vport.h
index f223550f8cba..91da17751a37 100644
--- a/drivers/scsi/lpfc/lpfc_vport.h
+++ b/drivers/scsi/lpfc/lpfc_vport.h
@@ -88,6 +88,8 @@ int lpfc_vport_create(struct fc_vport *, bool);
88int lpfc_vport_delete(struct fc_vport *); 88int lpfc_vport_delete(struct fc_vport *);
89int lpfc_vport_getinfo(struct Scsi_Host *, struct vport_info *); 89int lpfc_vport_getinfo(struct Scsi_Host *, struct vport_info *);
90int lpfc_vport_tgt_remove(struct Scsi_Host *, uint, uint); 90int lpfc_vport_tgt_remove(struct Scsi_Host *, uint, uint);
91struct lpfc_vport **lpfc_create_vport_work_array(struct lpfc_hba *);
92void lpfc_destroy_vport_work_array(struct lpfc_vport **);
91 93
92/* 94/*
93 * queuecommand VPORT-specific return codes. Specified in the host byte code. 95 * queuecommand VPORT-specific return codes. Specified in the host byte code.