aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_init.c
diff options
context:
space:
mode:
authorJames Smart <James.Smart@Emulex.Com>2008-01-11 01:52:54 -0500
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-01-23 12:29:22 -0500
commit0937282036d9ae798e02c9c69a8b2ef044048855 (patch)
tree55c8ef65c9c55e74e8985b58396516b3d3b925ad /drivers/scsi/lpfc/lpfc_init.c
parent13815c8344a238c204e4f4339b22dc4833c6df0f (diff)
[SCSI] lpfc 8.2.4 : Miscellaneous Fixes
Miscellaneous Fixes: - Fix a couple of sparse complaints - Reset the FCP recovery flag when the node is not a FCP2 device. - Speed up offline prep delays - Fixed a memory leak in lpfc_mem_alloc failure path - Fixed external loopback test. - Fixed error code returned from the driver when HBA is over heated. - Correct Max NPIV vport to limits read from adapter - Add missing locks around fc_flag and FC_NEEDS_REG_VPI - Add missing hba ids for device identification - Added support for SET_VARIABLE and MBX_WRITE_WWN mailbox commands - Changed all temperature event messages from warning to error - Fix reporting of link speed when link is down - Added support for MBX_WRITE_WWN mailbox command - Change del_timer_sync() in ISR to del_timer() in interrupt handler - Correct instances of beXX_to_cpu() that should be cpu_to_beXX() - Perform target flush before releasing node references on module unload - Avoid bogus devloss_tmo messages when driver unloads - Fix panic when HBA generates ERATT interupt - Fix mbox race condition and a workaround on back-to-back mailbox commands - Force NPIV off for pt2pt mode between 2 NPorts - Stop worker thread before removing fc_host. - Fix up discovery timeout error case due to missing clear_la - Tighten mailbox polling code to speed up detection of fast completions - Only allow DUMP_MEMORY if adapter offline due to overtemp errors - Added extended error information to the log messages in chip init. Signed-off-by: James Smart <James.Smart@emulex.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_init.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c119
1 files changed, 80 insertions, 39 deletions
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index c6b30a8617bc..e17bb900aad1 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -484,6 +484,9 @@ lpfc_hba_down_post(struct lpfc_hba *phba)
484 struct lpfc_sli *psli = &phba->sli; 484 struct lpfc_sli *psli = &phba->sli;
485 struct lpfc_sli_ring *pring; 485 struct lpfc_sli_ring *pring;
486 struct lpfc_dmabuf *mp, *next_mp; 486 struct lpfc_dmabuf *mp, *next_mp;
487 struct lpfc_iocbq *iocb;
488 IOCB_t *cmd = NULL;
489 LIST_HEAD(completions);
487 int i; 490 int i;
488 491
489 if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) 492 if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED)
@@ -499,10 +502,36 @@ lpfc_hba_down_post(struct lpfc_hba *phba)
499 } 502 }
500 } 503 }
501 504
505 spin_lock_irq(&phba->hbalock);
502 for (i = 0; i < psli->num_rings; i++) { 506 for (i = 0; i < psli->num_rings; i++) {
503 pring = &psli->ring[i]; 507 pring = &psli->ring[i];
508
509 /* At this point in time the HBA is either reset or DOA. Either
510 * way, nothing should be on txcmplq as it will NEVER complete.
511 */
512 list_splice_init(&pring->txcmplq, &completions);
513 pring->txcmplq_cnt = 0;
514 spin_unlock_irq(&phba->hbalock);
515
516 while (!list_empty(&completions)) {
517 iocb = list_get_first(&completions, struct lpfc_iocbq,
518 list);
519 cmd = &iocb->iocb;
520 list_del_init(&iocb->list);
521
522 if (!iocb->iocb_cmpl)
523 lpfc_sli_release_iocbq(phba, iocb);
524 else {
525 cmd->ulpStatus = IOSTAT_LOCAL_REJECT;
526 cmd->un.ulpWord[4] = IOERR_SLI_ABORTED;
527 (iocb->iocb_cmpl) (phba, iocb, iocb);
528 }
529 }
530
504 lpfc_sli_abort_iocb_ring(phba, pring); 531 lpfc_sli_abort_iocb_ring(phba, pring);
532 spin_lock_irq(&phba->hbalock);
505 } 533 }
534 spin_unlock_irq(&phba->hbalock);
506 535
507 return 0; 536 return 0;
508} 537}
@@ -641,6 +670,26 @@ lpfc_hb_timeout_handler(struct lpfc_hba *phba)
641 } 670 }
642} 671}
643 672
673static void
674lpfc_offline_eratt(struct lpfc_hba *phba)
675{
676 struct lpfc_sli *psli = &phba->sli;
677
678 spin_lock_irq(&phba->hbalock);
679 psli->sli_flag &= ~LPFC_SLI2_ACTIVE;
680 spin_unlock_irq(&phba->hbalock);
681 lpfc_offline_prep(phba);
682
683 lpfc_offline(phba);
684 lpfc_reset_barrier(phba);
685 lpfc_sli_brdreset(phba);
686 lpfc_hba_down_post(phba);
687 lpfc_sli_brdready(phba, HS_MBRDY);
688 lpfc_unblock_mgmt_io(phba);
689 phba->link_state = LPFC_HBA_ERROR;
690 return;
691}
692
644/************************************************************************/ 693/************************************************************************/
645/* */ 694/* */
646/* lpfc_handle_eratt */ 695/* lpfc_handle_eratt */
@@ -681,14 +730,14 @@ lpfc_handle_eratt(struct lpfc_hba *phba)
681 vports = lpfc_create_vport_work_array(phba); 730 vports = lpfc_create_vport_work_array(phba);
682 if (vports != NULL) 731 if (vports != NULL)
683 for(i = 0; 732 for(i = 0;
684 i < LPFC_MAX_VPORTS && vports[i] != NULL; 733 i <= phba->max_vpi && vports[i] != NULL;
685 i++){ 734 i++){
686 shost = lpfc_shost_from_vport(vports[i]); 735 shost = lpfc_shost_from_vport(vports[i]);
687 spin_lock_irq(shost->host_lock); 736 spin_lock_irq(shost->host_lock);
688 vports[i]->fc_flag |= FC_ESTABLISH_LINK; 737 vports[i]->fc_flag |= FC_ESTABLISH_LINK;
689 spin_unlock_irq(shost->host_lock); 738 spin_unlock_irq(shost->host_lock);
690 } 739 }
691 lpfc_destroy_vport_work_array(vports); 740 lpfc_destroy_vport_work_array(phba, vports);
692 spin_lock_irq(&phba->hbalock); 741 spin_lock_irq(&phba->hbalock);
693 psli->sli_flag &= ~LPFC_SLI2_ACTIVE; 742 psli->sli_flag &= ~LPFC_SLI2_ACTIVE;
694 spin_unlock_irq(&phba->hbalock); 743 spin_unlock_irq(&phba->hbalock);
@@ -737,14 +786,9 @@ lpfc_handle_eratt(struct lpfc_hba *phba)
737 | PCI_VENDOR_ID_EMULEX); 786 | PCI_VENDOR_ID_EMULEX);
738 787
739 spin_lock_irq(&phba->hbalock); 788 spin_lock_irq(&phba->hbalock);
740 psli->sli_flag &= ~LPFC_SLI2_ACTIVE;
741 phba->over_temp_state = HBA_OVER_TEMP; 789 phba->over_temp_state = HBA_OVER_TEMP;
742 spin_unlock_irq(&phba->hbalock); 790 spin_unlock_irq(&phba->hbalock);
743 lpfc_offline_prep(phba); 791 lpfc_offline_eratt(phba);
744 lpfc_offline(phba);
745 lpfc_unblock_mgmt_io(phba);
746 phba->link_state = LPFC_HBA_ERROR;
747 lpfc_hba_down_post(phba);
748 792
749 } else { 793 } else {
750 /* The if clause above forces this code path when the status 794 /* The if clause above forces this code path when the status
@@ -763,14 +807,7 @@ lpfc_handle_eratt(struct lpfc_hba *phba)
763 sizeof(event_data), (char *) &event_data, 807 sizeof(event_data), (char *) &event_data,
764 SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_EMULEX); 808 SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_EMULEX);
765 809
766 spin_lock_irq(&phba->hbalock); 810 lpfc_offline_eratt(phba);
767 psli->sli_flag &= ~LPFC_SLI2_ACTIVE;
768 spin_unlock_irq(&phba->hbalock);
769 lpfc_offline_prep(phba);
770 lpfc_offline(phba);
771 lpfc_unblock_mgmt_io(phba);
772 phba->link_state = LPFC_HBA_ERROR;
773 lpfc_hba_down_post(phba);
774 } 811 }
775} 812}
776 813
@@ -790,21 +827,25 @@ lpfc_handle_latt(struct lpfc_hba *phba)
790 LPFC_MBOXQ_t *pmb; 827 LPFC_MBOXQ_t *pmb;
791 volatile uint32_t control; 828 volatile uint32_t control;
792 struct lpfc_dmabuf *mp; 829 struct lpfc_dmabuf *mp;
793 int rc = -ENOMEM; 830 int rc = 0;
794 831
795 pmb = (LPFC_MBOXQ_t *)mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); 832 pmb = (LPFC_MBOXQ_t *)mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
796 if (!pmb) 833 if (!pmb) {
834 rc = 1;
797 goto lpfc_handle_latt_err_exit; 835 goto lpfc_handle_latt_err_exit;
836 }
798 837
799 mp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL); 838 mp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
800 if (!mp) 839 if (!mp) {
840 rc = 2;
801 goto lpfc_handle_latt_free_pmb; 841 goto lpfc_handle_latt_free_pmb;
842 }
802 843
803 mp->virt = lpfc_mbuf_alloc(phba, 0, &mp->phys); 844 mp->virt = lpfc_mbuf_alloc(phba, 0, &mp->phys);
804 if (!mp->virt) 845 if (!mp->virt) {
846 rc = 3;
805 goto lpfc_handle_latt_free_mp; 847 goto lpfc_handle_latt_free_mp;
806 848 }
807 rc = -EIO;
808 849
809 /* Cleanup any outstanding ELS commands */ 850 /* Cleanup any outstanding ELS commands */
810 lpfc_els_flush_all_cmd(phba); 851 lpfc_els_flush_all_cmd(phba);
@@ -814,8 +855,10 @@ lpfc_handle_latt(struct lpfc_hba *phba)
814 pmb->mbox_cmpl = lpfc_mbx_cmpl_read_la; 855 pmb->mbox_cmpl = lpfc_mbx_cmpl_read_la;
815 pmb->vport = vport; 856 pmb->vport = vport;
816 rc = lpfc_sli_issue_mbox (phba, pmb, MBX_NOWAIT); 857 rc = lpfc_sli_issue_mbox (phba, pmb, MBX_NOWAIT);
817 if (rc == MBX_NOT_FINISHED) 858 if (rc == MBX_NOT_FINISHED) {
859 rc = 4;
818 goto lpfc_handle_latt_free_mbuf; 860 goto lpfc_handle_latt_free_mbuf;
861 }
819 862
820 /* Clear Link Attention in HA REG */ 863 /* Clear Link Attention in HA REG */
821 spin_lock_irq(&phba->hbalock); 864 spin_lock_irq(&phba->hbalock);
@@ -847,10 +890,8 @@ lpfc_handle_latt_err_exit:
847 lpfc_linkdown(phba); 890 lpfc_linkdown(phba);
848 phba->link_state = LPFC_HBA_ERROR; 891 phba->link_state = LPFC_HBA_ERROR;
849 892
850 /* The other case is an error from issue_mbox */ 893 lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
851 if (rc == -ENOMEM) 894 "0300 LATT: Cannot issue READ_LA: Data:%d\n", rc);
852 lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX,
853 "0300 READ_LA: no buffers\n");
854 895
855 return; 896 return;
856} 897}
@@ -1421,14 +1462,14 @@ lpfc_establish_link_tmo(unsigned long ptr)
1421 phba->pport->fc_flag, phba->pport->port_state); 1462 phba->pport->fc_flag, phba->pport->port_state);
1422 vports = lpfc_create_vport_work_array(phba); 1463 vports = lpfc_create_vport_work_array(phba);
1423 if (vports != NULL) 1464 if (vports != NULL)
1424 for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) { 1465 for(i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) {
1425 struct Scsi_Host *shost; 1466 struct Scsi_Host *shost;
1426 shost = lpfc_shost_from_vport(vports[i]); 1467 shost = lpfc_shost_from_vport(vports[i]);
1427 spin_lock_irqsave(shost->host_lock, iflag); 1468 spin_lock_irqsave(shost->host_lock, iflag);
1428 vports[i]->fc_flag &= ~FC_ESTABLISH_LINK; 1469 vports[i]->fc_flag &= ~FC_ESTABLISH_LINK;
1429 spin_unlock_irqrestore(shost->host_lock, iflag); 1470 spin_unlock_irqrestore(shost->host_lock, iflag);
1430 } 1471 }
1431 lpfc_destroy_vport_work_array(vports); 1472 lpfc_destroy_vport_work_array(phba, vports);
1432} 1473}
1433 1474
1434void 1475void
@@ -1493,7 +1534,7 @@ lpfc_online(struct lpfc_hba *phba)
1493 1534
1494 vports = lpfc_create_vport_work_array(phba); 1535 vports = lpfc_create_vport_work_array(phba);
1495 if (vports != NULL) 1536 if (vports != NULL)
1496 for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) { 1537 for(i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) {
1497 struct Scsi_Host *shost; 1538 struct Scsi_Host *shost;
1498 shost = lpfc_shost_from_vport(vports[i]); 1539 shost = lpfc_shost_from_vport(vports[i]);
1499 spin_lock_irq(shost->host_lock); 1540 spin_lock_irq(shost->host_lock);
@@ -1502,7 +1543,7 @@ lpfc_online(struct lpfc_hba *phba)
1502 vports[i]->fc_flag |= FC_VPORT_NEEDS_REG_VPI; 1543 vports[i]->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
1503 spin_unlock_irq(shost->host_lock); 1544 spin_unlock_irq(shost->host_lock);
1504 } 1545 }
1505 lpfc_destroy_vport_work_array(vports); 1546 lpfc_destroy_vport_work_array(phba, vports);
1506 1547
1507 lpfc_unblock_mgmt_io(phba); 1548 lpfc_unblock_mgmt_io(phba);
1508 return 0; 1549 return 0;
@@ -1536,7 +1577,7 @@ lpfc_offline_prep(struct lpfc_hba * phba)
1536 /* Issue an unreg_login to all nodes on all vports */ 1577 /* Issue an unreg_login to all nodes on all vports */
1537 vports = lpfc_create_vport_work_array(phba); 1578 vports = lpfc_create_vport_work_array(phba);
1538 if (vports != NULL) { 1579 if (vports != NULL) {
1539 for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) { 1580 for(i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) {
1540 struct Scsi_Host *shost; 1581 struct Scsi_Host *shost;
1541 1582
1542 if (vports[i]->load_flag & FC_UNLOADING) 1583 if (vports[i]->load_flag & FC_UNLOADING)
@@ -1560,7 +1601,7 @@ lpfc_offline_prep(struct lpfc_hba * phba)
1560 } 1601 }
1561 } 1602 }
1562 } 1603 }
1563 lpfc_destroy_vport_work_array(vports); 1604 lpfc_destroy_vport_work_array(phba, vports);
1564 1605
1565 lpfc_sli_flush_mbox_queue(phba); 1606 lpfc_sli_flush_mbox_queue(phba);
1566} 1607}
@@ -1579,9 +1620,9 @@ lpfc_offline(struct lpfc_hba *phba)
1579 lpfc_stop_phba_timers(phba); 1620 lpfc_stop_phba_timers(phba);
1580 vports = lpfc_create_vport_work_array(phba); 1621 vports = lpfc_create_vport_work_array(phba);
1581 if (vports != NULL) 1622 if (vports != NULL)
1582 for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) 1623 for(i = 0; i <= phba->max_vpi && vports[i] != NULL; i++)
1583 lpfc_stop_vport_timers(vports[i]); 1624 lpfc_stop_vport_timers(vports[i]);
1584 lpfc_destroy_vport_work_array(vports); 1625 lpfc_destroy_vport_work_array(phba, vports);
1585 lpfc_printf_log(phba, KERN_WARNING, LOG_INIT, 1626 lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
1586 "0460 Bring Adapter offline\n"); 1627 "0460 Bring Adapter offline\n");
1587 /* Bring down the SLI Layer and cleanup. The HBA is offline 1628 /* Bring down the SLI Layer and cleanup. The HBA is offline
@@ -1592,14 +1633,14 @@ lpfc_offline(struct lpfc_hba *phba)
1592 spin_unlock_irq(&phba->hbalock); 1633 spin_unlock_irq(&phba->hbalock);
1593 vports = lpfc_create_vport_work_array(phba); 1634 vports = lpfc_create_vport_work_array(phba);
1594 if (vports != NULL) 1635 if (vports != NULL)
1595 for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) { 1636 for(i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) {
1596 shost = lpfc_shost_from_vport(vports[i]); 1637 shost = lpfc_shost_from_vport(vports[i]);
1597 spin_lock_irq(shost->host_lock); 1638 spin_lock_irq(shost->host_lock);
1598 vports[i]->work_port_events = 0; 1639 vports[i]->work_port_events = 0;
1599 vports[i]->fc_flag |= FC_OFFLINE_MODE; 1640 vports[i]->fc_flag |= FC_OFFLINE_MODE;
1600 spin_unlock_irq(shost->host_lock); 1641 spin_unlock_irq(shost->host_lock);
1601 } 1642 }
1602 lpfc_destroy_vport_work_array(vports); 1643 lpfc_destroy_vport_work_array(phba, vports);
1603} 1644}
1604 1645
1605/****************************************************************************** 1646/******************************************************************************
@@ -2149,6 +2190,8 @@ lpfc_pci_remove_one(struct pci_dev *pdev)
2149 kfree(vport->vname); 2190 kfree(vport->vname);
2150 lpfc_free_sysfs_attr(vport); 2191 lpfc_free_sysfs_attr(vport);
2151 2192
2193 kthread_stop(phba->worker_thread);
2194
2152 fc_remove_host(shost); 2195 fc_remove_host(shost);
2153 scsi_remove_host(shost); 2196 scsi_remove_host(shost);
2154 lpfc_cleanup(vport); 2197 lpfc_cleanup(vport);
@@ -2168,8 +2211,6 @@ lpfc_pci_remove_one(struct pci_dev *pdev)
2168 2211
2169 lpfc_debugfs_terminate(vport); 2212 lpfc_debugfs_terminate(vport);
2170 2213
2171 kthread_stop(phba->worker_thread);
2172
2173 /* Release the irq reservation */ 2214 /* Release the irq reservation */
2174 free_irq(phba->pcidev->irq, phba); 2215 free_irq(phba->pcidev->irq, phba);
2175 if (phba->using_msi) 2216 if (phba->using_msi)