diff options
author | James Smart <James.Smart@Emulex.Com> | 2009-04-06 18:48:10 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2009-04-27 10:42:47 -0400 |
commit | a257bf905efd22fd2c055580b0ab2e8e7ed1b6a1 (patch) | |
tree | e0f2ef6b9627d86456c92d56fa2c088c6d6544bf /drivers/scsi/lpfc/lpfc_init.c | |
parent | 3621a710a7dbb2d22a8e95d94bcf0c2d13ef57fc (diff) |
[SCSI] lpfc 8.3.1: misc fixes/changes
8.3.1 Fixes/Changes :
- Fix incorrect byte-swapping on word 4 of IOCB (data length) which
caused LUNs to not be discovered on big-endian (e.g. PPC)
- Remove a bad cast of MBslimaddr which loses the __iomem (sparse)
- Make lpfc_debugfs_mask_disc_trc static (sparse)
- Correct misspelled word BlockGuard in lpfc_logmsg.h comment
- Replaced repeated code segment for canceling IOCBs from a list with
a function call, lpfc_sli_cancel_iocbs().
- Increased HBQ buffers to support 40KB SSC sequences.
- Added sysfs interface to update speed and topology parameter without
link bounce.
- Fixed bug with sysfs fc_host WWNs not being updated after changing
the WWNs.
- Check if the active mailbox is NULL in the beginning of the mailbox
timeout handler - fixes panic in the mailbox timeout handler while
running IO stress test
- Fixed system panic in lpfc_pci_remove_one() due to ndlp indirect
reference to phba through vport
- Removed de-reference of scsi device after call to scsi_done() to fix
panic in scsi completion path while accessing scsi device after
scsi_done is called.
- Fixed "Nodelist not empty" message when unloading the driver after
target reboot test
- Added LP2105 HBA model description
- Added code to print all 16 words of unrecognized ASYNC events
- Fixed memory leak in vport create + delete loop
- Added support for handling dual error bit from HBA
- Fixed a driver NULL pointer dereference in lpfc_sli_process_sol_iocb
- Fixed a discovery bug with FC switch reboot in lpfc_setup_disc_node
- Take NULL termintator into account when calculating available buffer space
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.c | 104 |
1 files changed, 85 insertions, 19 deletions
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index e3645e8f3487..86d1bdcbf2d8 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c | |||
@@ -302,6 +302,7 @@ int | |||
302 | lpfc_config_port_post(struct lpfc_hba *phba) | 302 | lpfc_config_port_post(struct lpfc_hba *phba) |
303 | { | 303 | { |
304 | struct lpfc_vport *vport = phba->pport; | 304 | struct lpfc_vport *vport = phba->pport; |
305 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
305 | LPFC_MBOXQ_t *pmb; | 306 | LPFC_MBOXQ_t *pmb; |
306 | MAILBOX_t *mb; | 307 | MAILBOX_t *mb; |
307 | struct lpfc_dmabuf *mp; | 308 | struct lpfc_dmabuf *mp; |
@@ -359,6 +360,11 @@ lpfc_config_port_post(struct lpfc_hba *phba) | |||
359 | sizeof (struct lpfc_name)); | 360 | sizeof (struct lpfc_name)); |
360 | memcpy(&vport->fc_portname, &vport->fc_sparam.portName, | 361 | memcpy(&vport->fc_portname, &vport->fc_sparam.portName, |
361 | sizeof (struct lpfc_name)); | 362 | sizeof (struct lpfc_name)); |
363 | |||
364 | /* Update the fc_host data structures with new wwn. */ | ||
365 | fc_host_node_name(shost) = wwn_to_u64(vport->fc_nodename.u.wwn); | ||
366 | fc_host_port_name(shost) = wwn_to_u64(vport->fc_portname.u.wwn); | ||
367 | |||
362 | /* If no serial number in VPD data, use low 6 bytes of WWNN */ | 368 | /* If no serial number in VPD data, use low 6 bytes of WWNN */ |
363 | /* This should be consolidated into parse_vpd ? - mr */ | 369 | /* This should be consolidated into parse_vpd ? - mr */ |
364 | if (phba->SerialNumber[0] == 0) { | 370 | if (phba->SerialNumber[0] == 0) { |
@@ -598,8 +604,6 @@ lpfc_hba_down_post(struct lpfc_hba *phba) | |||
598 | struct lpfc_sli *psli = &phba->sli; | 604 | struct lpfc_sli *psli = &phba->sli; |
599 | struct lpfc_sli_ring *pring; | 605 | struct lpfc_sli_ring *pring; |
600 | struct lpfc_dmabuf *mp, *next_mp; | 606 | struct lpfc_dmabuf *mp, *next_mp; |
601 | struct lpfc_iocbq *iocb; | ||
602 | IOCB_t *cmd = NULL; | ||
603 | LIST_HEAD(completions); | 607 | LIST_HEAD(completions); |
604 | int i; | 608 | int i; |
605 | 609 | ||
@@ -627,20 +631,9 @@ lpfc_hba_down_post(struct lpfc_hba *phba) | |||
627 | pring->txcmplq_cnt = 0; | 631 | pring->txcmplq_cnt = 0; |
628 | spin_unlock_irq(&phba->hbalock); | 632 | spin_unlock_irq(&phba->hbalock); |
629 | 633 | ||
630 | while (!list_empty(&completions)) { | 634 | /* Cancel all the IOCBs from the completions list */ |
631 | iocb = list_get_first(&completions, struct lpfc_iocbq, | 635 | lpfc_sli_cancel_iocbs(phba, &completions, IOSTAT_LOCAL_REJECT, |
632 | list); | 636 | IOERR_SLI_ABORTED); |
633 | cmd = &iocb->iocb; | ||
634 | list_del_init(&iocb->list); | ||
635 | |||
636 | if (!iocb->iocb_cmpl) | ||
637 | lpfc_sli_release_iocbq(phba, iocb); | ||
638 | else { | ||
639 | cmd->ulpStatus = IOSTAT_LOCAL_REJECT; | ||
640 | cmd->un.ulpWord[4] = IOERR_SLI_ABORTED; | ||
641 | (iocb->iocb_cmpl) (phba, iocb, iocb); | ||
642 | } | ||
643 | } | ||
644 | 637 | ||
645 | lpfc_sli_abort_iocb_ring(phba, pring); | 638 | lpfc_sli_abort_iocb_ring(phba, pring); |
646 | spin_lock_irq(&phba->hbalock); | 639 | spin_lock_irq(&phba->hbalock); |
@@ -856,6 +849,72 @@ lpfc_offline_eratt(struct lpfc_hba *phba) | |||
856 | } | 849 | } |
857 | 850 | ||
858 | /** | 851 | /** |
852 | * lpfc_handle_deferred_eratt - The HBA hardware deferred error handler | ||
853 | * @phba: pointer to lpfc hba data structure. | ||
854 | * | ||
855 | * This routine is invoked to handle the deferred HBA hardware error | ||
856 | * conditions. This type of error is indicated by HBA by setting ER1 | ||
857 | * and another ER bit in the host status register. The driver will | ||
858 | * wait until the ER1 bit clears before handling the error condition. | ||
859 | **/ | ||
860 | static void | ||
861 | lpfc_handle_deferred_eratt(struct lpfc_hba *phba) | ||
862 | { | ||
863 | uint32_t old_host_status = phba->work_hs; | ||
864 | struct lpfc_sli_ring *pring; | ||
865 | struct lpfc_sli *psli = &phba->sli; | ||
866 | |||
867 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
868 | "0479 Deferred Adapter Hardware Error " | ||
869 | "Data: x%x x%x x%x\n", | ||
870 | phba->work_hs, | ||
871 | phba->work_status[0], phba->work_status[1]); | ||
872 | |||
873 | spin_lock_irq(&phba->hbalock); | ||
874 | psli->sli_flag &= ~LPFC_SLI2_ACTIVE; | ||
875 | spin_unlock_irq(&phba->hbalock); | ||
876 | |||
877 | |||
878 | /* | ||
879 | * Firmware stops when it triggred erratt. That could cause the I/Os | ||
880 | * dropped by the firmware. Error iocb (I/O) on txcmplq and let the | ||
881 | * SCSI layer retry it after re-establishing link. | ||
882 | */ | ||
883 | pring = &psli->ring[psli->fcp_ring]; | ||
884 | lpfc_sli_abort_iocb_ring(phba, pring); | ||
885 | |||
886 | /* | ||
887 | * There was a firmware error. Take the hba offline and then | ||
888 | * attempt to restart it. | ||
889 | */ | ||
890 | lpfc_offline_prep(phba); | ||
891 | lpfc_offline(phba); | ||
892 | |||
893 | /* Wait for the ER1 bit to clear.*/ | ||
894 | while (phba->work_hs & HS_FFER1) { | ||
895 | msleep(100); | ||
896 | phba->work_hs = readl(phba->HSregaddr); | ||
897 | /* If driver is unloading let the worker thread continue */ | ||
898 | if (phba->pport->load_flag & FC_UNLOADING) { | ||
899 | phba->work_hs = 0; | ||
900 | break; | ||
901 | } | ||
902 | } | ||
903 | |||
904 | /* | ||
905 | * This is to ptrotect against a race condition in which | ||
906 | * first write to the host attention register clear the | ||
907 | * host status register. | ||
908 | */ | ||
909 | if ((!phba->work_hs) && (!(phba->pport->load_flag & FC_UNLOADING))) | ||
910 | phba->work_hs = old_host_status & ~HS_FFER1; | ||
911 | |||
912 | phba->hba_flag &= ~DEFER_ERATT; | ||
913 | phba->work_status[0] = readl(phba->MBslimaddr + 0xa8); | ||
914 | phba->work_status[1] = readl(phba->MBslimaddr + 0xac); | ||
915 | } | ||
916 | |||
917 | /** | ||
859 | * lpfc_handle_eratt - The HBA hardware error handler | 918 | * lpfc_handle_eratt - The HBA hardware error handler |
860 | * @phba: pointer to lpfc hba data structure. | 919 | * @phba: pointer to lpfc hba data structure. |
861 | * | 920 | * |
@@ -894,6 +953,9 @@ lpfc_handle_eratt(struct lpfc_hba *phba) | |||
894 | (char *) &board_event, | 953 | (char *) &board_event, |
895 | LPFC_NL_VENDOR_ID); | 954 | LPFC_NL_VENDOR_ID); |
896 | 955 | ||
956 | if (phba->hba_flag & DEFER_ERATT) | ||
957 | lpfc_handle_deferred_eratt(phba); | ||
958 | |||
897 | if (phba->work_hs & HS_FFER6) { | 959 | if (phba->work_hs & HS_FFER6) { |
898 | /* Re-establishing Link */ | 960 | /* Re-establishing Link */ |
899 | lpfc_printf_log(phba, KERN_INFO, LOG_LINK_EVENT, | 961 | lpfc_printf_log(phba, KERN_INFO, LOG_LINK_EVENT, |
@@ -1321,7 +1383,8 @@ lpfc_get_hba_model_desc(struct lpfc_hba *phba, uint8_t *mdp, uint8_t *descp) | |||
1321 | m = (typeof(m)){"LPe11000", max_speed, "PCIe"}; | 1383 | m = (typeof(m)){"LPe11000", max_speed, "PCIe"}; |
1322 | break; | 1384 | break; |
1323 | case PCI_DEVICE_ID_ZEPHYR_DCSP: | 1385 | case PCI_DEVICE_ID_ZEPHYR_DCSP: |
1324 | m = (typeof(m)){"LPe11002-SP", max_speed, "PCIe"}; | 1386 | m = (typeof(m)){"LP2105", max_speed, "PCIe"}; |
1387 | GE = 1; | ||
1325 | break; | 1388 | break; |
1326 | case PCI_DEVICE_ID_ZMID: | 1389 | case PCI_DEVICE_ID_ZMID: |
1327 | m = (typeof(m)){"LPe1150", max_speed, "PCIe"}; | 1390 | m = (typeof(m)){"LPe1150", max_speed, "PCIe"}; |
@@ -3032,8 +3095,6 @@ lpfc_pci_remove_one(struct pci_dev *pdev) | |||
3032 | 3095 | ||
3033 | lpfc_free_sysfs_attr(vport); | 3096 | lpfc_free_sysfs_attr(vport); |
3034 | 3097 | ||
3035 | kthread_stop(phba->worker_thread); | ||
3036 | |||
3037 | /* Release all the vports against this physical port */ | 3098 | /* Release all the vports against this physical port */ |
3038 | vports = lpfc_create_vport_work_array(phba); | 3099 | vports = lpfc_create_vport_work_array(phba); |
3039 | if (vports != NULL) | 3100 | if (vports != NULL) |
@@ -3051,7 +3112,12 @@ lpfc_pci_remove_one(struct pci_dev *pdev) | |||
3051 | * clears the rings, discards all mailbox commands, and resets | 3112 | * clears the rings, discards all mailbox commands, and resets |
3052 | * the HBA. | 3113 | * the HBA. |
3053 | */ | 3114 | */ |
3115 | |||
3116 | /* HBA interrupt will be diabled after this call */ | ||
3054 | lpfc_sli_hba_down(phba); | 3117 | lpfc_sli_hba_down(phba); |
3118 | /* Stop kthread signal shall trigger work_done one more time */ | ||
3119 | kthread_stop(phba->worker_thread); | ||
3120 | /* Final cleanup of txcmplq and reset the HBA */ | ||
3055 | lpfc_sli_brdrestart(phba); | 3121 | lpfc_sli_brdrestart(phba); |
3056 | 3122 | ||
3057 | lpfc_stop_phba_timers(phba); | 3123 | lpfc_stop_phba_timers(phba); |