Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[SCSI] lpfc 8.3.0 : Fix several minor issues

- Avoid polling HBA Error Attention when HBA's PCI channel is offline
due to PCI EEH

- Fix handling of RSCN with non-zero event qualifiers

- Remove unnecessary sleeps during HBA initialization which slow down
driver load

- Fix internal and external loopback on FCoE HBAs

- Fix incorrect decrement of cmd_pending count in lpfc_queuecomand
error path

- Fix reporting of port busy events to management application

- Rename lpfc_adjust_queue_depth() to lpfc_rampdown_queue_depth() for
consistency with its partner lpfc_rampup_queue_depth()

- Delete redundant lpfc_cmd->start_time = jiffies assignment in
lpfc_queuecommand()

- Fix handling for ELS, mailbox and heartbeat time outs in the worker
thread by removing unnecessary checking of the work_port_events
flags.

- Fix NULL pointer dereference in lpfc_prep_els_iocb

- In lpfc_device_recov_npr_node(), move clearing of NLP_NPR_2B_DISC
flag after call to lpfc_cancel_retry_delay_tmo() to keep
targets-in-discovery count correct

- Remove lpfc_probe_one()'s call to scsi_scan_host() which could cause
concurrent SCSI scans to step on each other

Signed-off-by: James Smart <James.Smart@emulex.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>

authored by

James Smart and committed by
James Bottomley
eaf15d5b 8f34f4ce

+41 -50
+1 -1
drivers/scsi/lpfc/lpfc_crtn.h
··· 290 290 void lpfc_fabric_abort_hba(struct lpfc_hba *); 291 291 void lpfc_fabric_block_timeout(unsigned long); 292 292 void lpfc_unblock_fabric_iocbs(struct lpfc_hba *); 293 - void lpfc_adjust_queue_depth(struct lpfc_hba *); 293 + void lpfc_rampdown_queue_depth(struct lpfc_hba *); 294 294 void lpfc_ramp_down_queue_handler(struct lpfc_hba *); 295 295 void lpfc_ramp_up_queue_handler(struct lpfc_hba *); 296 296 void lpfc_scsi_dev_block(struct lpfc_hba *);
+16 -16
drivers/scsi/lpfc/lpfc_els.c
··· 275 275 return elsiocb; 276 276 277 277 els_iocb_free_pbuf_exit: 278 - lpfc_mbuf_free(phba, prsp->virt, prsp->phys); 278 + if (expectRsp) 279 + lpfc_mbuf_free(phba, prsp->virt, prsp->phys); 279 280 kfree(pbuflist); 280 281 281 282 els_iocb_free_prsp_exit: ··· 2473 2472 case IOSTAT_LOCAL_REJECT: 2474 2473 switch ((irsp->un.ulpWord[4] & 0xff)) { 2475 2474 case IOERR_LOOP_OPEN_FAILURE: 2475 + if (cmd == ELS_CMD_FLOGI) { 2476 + if (PCI_DEVICE_ID_HORNET == 2477 + phba->pcidev->device) { 2478 + phba->fc_topology = TOPOLOGY_LOOP; 2479 + phba->pport->fc_myDID = 0; 2480 + phba->alpa_map[0] = 0; 2481 + phba->alpa_map[1] = 0; 2482 + } 2483 + } 2476 2484 if (cmd == ELS_CMD_PLOGI && cmdiocb->retry == 0) 2477 2485 delay = 1000; 2478 2486 retry = 1; ··· 3837 3827 while (payload_len) { 3838 3828 rscn_did.un.word = be32_to_cpu(*lp++); 3839 3829 payload_len -= sizeof(uint32_t); 3840 - switch (rscn_did.un.b.resv) { 3841 - case 0: /* Single N_Port ID effected */ 3830 + switch (rscn_did.un.b.resv & RSCN_ADDRESS_FORMAT_MASK) { 3831 + case RSCN_ADDRESS_FORMAT_PORT: 3842 3832 if (ns_did.un.word == rscn_did.un.word) 3843 3833 goto return_did_out; 3844 3834 break; 3845 - case 1: /* Whole N_Port Area effected */ 3835 + case RSCN_ADDRESS_FORMAT_AREA: 3846 3836 if ((ns_did.un.b.domain == rscn_did.un.b.domain) 3847 3837 && (ns_did.un.b.area == rscn_did.un.b.area)) 3848 3838 goto return_did_out; 3849 3839 break; 3850 - case 2: /* Whole N_Port Domain effected */ 3840 + case RSCN_ADDRESS_FORMAT_DOMAIN: 3851 3841 if (ns_did.un.b.domain == rscn_did.un.b.domain) 3852 3842 goto return_did_out; 3853 3843 break; 3854 - default: 3855 - /* Unknown Identifier in RSCN node */ 3856 - lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY, 3857 - "0217 Unknown Identifier in " 3858 - "RSCN payload Data: x%x\n", 3859 - rscn_did.un.word); 3860 - case 3: /* Whole Fabric effected */ 3844 + case RSCN_ADDRESS_FORMAT_FABRIC: 3861 3845 goto return_did_out; 3862 3846 } 3863 3847 } ··· 4939 4935 uint32_t timeout; 4940 4936 uint32_t remote_ID = 0xffffffff; 4941 4937 4942 - /* If the timer is already canceled do nothing */ 4943 - if ((vport->work_port_events & WORKER_ELS_TMO) == 0) { 4944 - return; 4945 - } 4946 4938 spin_lock_irq(&phba->hbalock); 4947 4939 timeout = (uint32_t)(phba->fc_ratov << 1); 4948 4940
+1 -1
drivers/scsi/lpfc/lpfc_hbadisc.c
··· 350 350 evt_data_size = sizeof(fast_evt_data->un. 351 351 read_check_error); 352 352 } else if ((evt_sub_category == LPFC_EVENT_FABRIC_BUSY) || 353 - (evt_sub_category == IOSTAT_NPORT_BSY)) { 353 + (evt_sub_category == LPFC_EVENT_PORT_BUSY)) { 354 354 evt_data = (char *) &fast_evt_data->un.fabric_evt; 355 355 evt_data_size = sizeof(fast_evt_data->un.fabric_evt); 356 356 } else {
+6
drivers/scsi/lpfc/lpfc_hw.h
··· 869 869 } un; 870 870 } D_ID; 871 871 872 + #define RSCN_ADDRESS_FORMAT_PORT 0x0 873 + #define RSCN_ADDRESS_FORMAT_AREA 0x1 874 + #define RSCN_ADDRESS_FORMAT_DOMAIN 0x2 875 + #define RSCN_ADDRESS_FORMAT_FABRIC 0x3 876 + #define RSCN_ADDRESS_FORMAT_MASK 0x3 877 + 872 878 /* 873 879 * Structure to define all ELS Payload types 874 880 */
-7
drivers/scsi/lpfc/lpfc_init.c
··· 742 742 return; 743 743 744 744 spin_lock_irq(&phba->pport->work_port_lock); 745 - /* If the timer is already canceled do nothing */ 746 - if (!(phba->pport->work_port_events & WORKER_HB_TMO)) { 747 - spin_unlock_irq(&phba->pport->work_port_lock); 748 - return; 749 - } 750 745 751 746 if (time_after(phba->last_completion_time + LPFC_HB_MBOX_INTERVAL * HZ, 752 747 jiffies)) { ··· 2696 2701 sizeof(adapter_event), 2697 2702 (char *) &adapter_event, 2698 2703 LPFC_NL_VENDOR_ID); 2699 - 2700 - scsi_scan_host(shost); 2701 2704 2702 2705 return 0; 2703 2706
+1 -1
drivers/scsi/lpfc/lpfc_nportdisc.c
··· 1929 1929 if (vport->fc_flag & FC_RSCN_DEFERRED) 1930 1930 return ndlp->nlp_state; 1931 1931 1932 + lpfc_cancel_retry_delay_tmo(vport, ndlp); 1932 1933 spin_lock_irq(shost->host_lock); 1933 1934 ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC); 1934 1935 spin_unlock_irq(shost->host_lock); 1935 - lpfc_cancel_retry_delay_tmo(vport, ndlp); 1936 1936 return ndlp->nlp_state; 1937 1937 } 1938 1938
+6 -7
drivers/scsi/lpfc/lpfc_scsi.c
··· 148 148 } 149 149 150 150 /** 151 - * lpfc_adjust_queue_depth: Post RAMP_DOWN_QUEUE event for worker thread. 151 + * lpfc_rampdown_queue_depth: Post RAMP_DOWN_QUEUE event to worker thread. 152 152 * @phba: The Hba for which this call is being executed. 153 153 * 154 154 * This routine is called when there is resource error in driver or firmware. ··· 159 159 * This routine should be called with no lock held. 160 160 **/ 161 161 void 162 - lpfc_adjust_queue_depth(struct lpfc_hba *phba) 162 + lpfc_rampdown_queue_depth(struct lpfc_hba *phba) 163 163 { 164 164 unsigned long flags; 165 165 uint32_t evt_posted; ··· 1551 1551 1552 1552 lpfc_cmd = lpfc_get_scsi_buf(phba); 1553 1553 if (lpfc_cmd == NULL) { 1554 - lpfc_adjust_queue_depth(phba); 1554 + lpfc_rampdown_queue_depth(phba); 1555 1555 1556 1556 lpfc_printf_vlog(vport, KERN_INFO, LOG_FCP, 1557 1557 "0707 driver's buffer pool is empty, " ··· 1559 1559 goto out_host_busy; 1560 1560 } 1561 1561 1562 - lpfc_cmd->start_time = jiffies; 1563 1562 /* 1564 1563 * Store the midlayer's command structure for the completion phase 1565 1564 * and complete the command initialization. ··· 1579 1580 atomic_inc(&ndlp->cmd_pending); 1580 1581 err = lpfc_sli_issue_iocb(phba, &phba->sli.ring[psli->fcp_ring], 1581 1582 &lpfc_cmd->cur_iocbq, SLI_IOCB_RET_IOCB); 1582 - if (err) 1583 + if (err) { 1584 + atomic_dec(&ndlp->cmd_pending); 1583 1585 goto out_host_busy_free_buf; 1584 - 1586 + } 1585 1587 if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) { 1586 1588 lpfc_sli_poll_fcp_ring(phba); 1587 1589 if (phba->cfg_poll & DISABLE_FCP_RING_INT) ··· 1592 1592 return 0; 1593 1593 1594 1594 out_host_busy_free_buf: 1595 - atomic_dec(&ndlp->cmd_pending); 1596 1595 lpfc_scsi_unprep_dma_buf(phba, lpfc_cmd); 1597 1596 lpfc_release_scsi_buf(phba, lpfc_cmd); 1598 1597 out_host_busy:
+10 -17
drivers/scsi/lpfc/lpfc_sli.c
··· 1982 1982 if ((irsp->ulpStatus == IOSTAT_LOCAL_REJECT) && 1983 1983 (irsp->un.ulpWord[4] == IOERR_NO_RESOURCES)) { 1984 1984 spin_unlock_irqrestore(&phba->hbalock, iflag); 1985 - lpfc_adjust_queue_depth(phba); 1985 + lpfc_rampdown_queue_depth(phba); 1986 1986 spin_lock_irqsave(&phba->hbalock, iflag); 1987 1987 } 1988 1988 ··· 2225 2225 if ((irsp->ulpStatus == IOSTAT_LOCAL_REJECT) && 2226 2226 (irsp->un.ulpWord[4] == IOERR_NO_RESOURCES)) { 2227 2227 spin_unlock_irqrestore(&phba->hbalock, iflag); 2228 - lpfc_adjust_queue_depth(phba); 2228 + lpfc_rampdown_queue_depth(phba); 2229 2229 spin_lock_irqsave(&phba->hbalock, iflag); 2230 2230 } 2231 2231 ··· 2790 2790 { 2791 2791 MAILBOX_t *mb; 2792 2792 struct lpfc_sli *psli; 2793 - uint16_t skip_post; 2794 2793 volatile uint32_t word0; 2795 2794 void __iomem *to_slim; 2796 2795 ··· 2814 2815 readl(to_slim); /* flush */ 2815 2816 2816 2817 /* Only skip post after fc_ffinit is completed */ 2817 - if (phba->pport->port_state) { 2818 - skip_post = 1; 2818 + if (phba->pport->port_state) 2819 2819 word0 = 1; /* This is really setting up word1 */ 2820 - } else { 2821 - skip_post = 0; 2820 + else 2822 2821 word0 = 0; /* This is really setting up word1 */ 2823 - } 2824 2822 to_slim = phba->MBslimaddr + sizeof (uint32_t); 2825 2823 writel(*(uint32_t *) mb, to_slim); 2826 2824 readl(to_slim); /* flush */ ··· 2831 2835 memset(&psli->lnk_stat_offsets, 0, sizeof(psli->lnk_stat_offsets)); 2832 2836 psli->stats_start = get_seconds(); 2833 2837 2834 - if (skip_post) 2835 - mdelay(100); 2836 - else 2837 - mdelay(2000); 2838 + /* Give the INITFF and Post time to settle. */ 2839 + mdelay(100); 2838 2840 2839 2841 lpfc_hba_down_post(phba); 2840 2842 ··· 3078 3084 spin_unlock_irq(&phba->hbalock); 3079 3085 phba->pport->port_state = LPFC_VPORT_UNKNOWN; 3080 3086 lpfc_sli_brdrestart(phba); 3081 - msleep(2500); 3082 3087 rc = lpfc_sli_chipset_init(phba); 3083 3088 if (rc) 3084 3089 break; ··· 3300 3307 MAILBOX_t *mb = &pmbox->mb; 3301 3308 struct lpfc_sli *psli = &phba->sli; 3302 3309 struct lpfc_sli_ring *pring; 3303 - 3304 - if (!(phba->pport->work_port_events & WORKER_MBOX_TMO)) { 3305 - return; 3306 - } 3307 3310 3308 3311 /* Mbox cmd <mbxCommand> timeout */ 3309 3312 lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI, ··· 5175 5186 lpfc_sli_check_eratt(struct lpfc_hba *phba) 5176 5187 { 5177 5188 uint32_t ha_copy; 5189 + 5190 + /* If PCI channel is offline, don't process it */ 5191 + if (unlikely(pci_channel_offline(phba->pcidev))) 5192 + return 0; 5178 5193 5179 5194 /* If somebody is waiting to handle an eratt, don't process it 5180 5195 * here. The brdkill function will do this.