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

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi

Pull SCSI updates from James Bottomley:
"Updates to the usual drivers (qla2xxx, lpfc, ufs, hisi_sas, mpi3mr,
mpt3sas, target). The biggest change (from my biased viewpoint) being
that the mpi3mr now attached to the SAS transport class, making it the
first fusion type device to do so.

Beyond the usual bug fixing and security class reworks, there aren't a
huge number of core changes"

* tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (141 commits)
scsi: iscsi: iscsi_tcp: Fix null-ptr-deref while calling getpeername()
scsi: mpi3mr: Remove unnecessary cast
scsi: stex: Properly zero out the passthrough command structure
scsi: mpi3mr: Update driver version to 8.2.0.3.0
scsi: mpi3mr: Fix scheduling while atomic type bug
scsi: mpi3mr: Scan the devices during resume time
scsi: mpi3mr: Free enclosure objects during driver unload
scsi: mpi3mr: Handle 0xF003 Fault Code
scsi: mpi3mr: Graceful handling of surprise removal of PCIe HBA
scsi: mpi3mr: Schedule IRQ kthreads only on non-RT kernels
scsi: mpi3mr: Support new power management framework
scsi: mpi3mr: Update mpi3 header files
scsi: mpt3sas: Revert "scsi: mpt3sas: Fix ioc->base_readl() use"
scsi: mpt3sas: Revert "scsi: mpt3sas: Fix writel() use"
scsi: wd33c93: Remove dead code related to the long-gone config WD33C93_PIO
scsi: core: Add I/O timeout count for SCSI device
scsi: qedf: Populate sysfs attributes for vport
scsi: pm8001: Replace one-element array with flexible-array member
scsi: 3w-xxxx: Replace one-element array with flexible-array member
scsi: hptiop: Replace one-element array with flexible-array member in struct hpt_iop_request_ioctl_command()
...

+7802 -2315
+46
Documentation/ABI/testing/sysfs-driver-ufs
··· 1417 1417 platform that doesn't support UFSHCD_CAP_CLK_SCALING, we can 1418 1418 disable/enable WriteBooster through this sysfs node. 1419 1419 1420 + What: /sys/bus/platform/drivers/ufshcd/*/enable_wb_buf_flush 1421 + What: /sys/bus/platform/devices/*.ufs/enable_wb_buf_flush 1422 + Date: July 2022 1423 + Contact: Jinyoung Choi <j-young.choi@samsung.com> 1424 + Description: This entry shows the status of WriteBooster buffer flushing 1425 + and it can be used to enable or disable the flushing. 1426 + If flushing is enabled, the device executes the flush 1427 + operation when the command queue is empty. 1428 + 1420 1429 What: /sys/bus/platform/drivers/ufshcd/*/device_descriptor/hpb_version 1421 1430 What: /sys/bus/platform/devices/*.ufs/device_descriptor/hpb_version 1422 1431 Date: June 2021 ··· 1596 1587 == ============================ 1597 1588 0 HPB is not enabled. 1598 1589 1 HPB is enabled 1590 + == ============================ 1591 + 1592 + The file is read only. 1593 + 1594 + Contact: Daniil Lunev <dlunev@chromium.org> 1595 + What: /sys/bus/platform/drivers/ufshcd/*/capabilities/ 1596 + What: /sys/bus/platform/devices/*.ufs/capabilities/ 1597 + Date: August 2022 1598 + Description: The group represents the effective capabilities of the 1599 + host-device pair. i.e. the capabilities which are enabled in the 1600 + driver for the specific host controller, supported by the host 1601 + controller and are supported and/or have compatible 1602 + configuration on the device side. 1603 + 1604 + Contact: Daniil Lunev <dlunev@chromium.org> 1605 + What: /sys/bus/platform/drivers/ufshcd/*/capabilities/clock_scaling 1606 + What: /sys/bus/platform/devices/*.ufs/capabilities/clock_scaling 1607 + Date: August 2022 1608 + Contact: Daniil Lunev <dlunev@chromium.org> 1609 + Description: Indicates status of clock scaling. 1610 + 1611 + == ============================ 1612 + 0 Clock scaling is not supported. 1613 + 1 Clock scaling is supported. 1614 + == ============================ 1615 + 1616 + The file is read only. 1617 + 1618 + What: /sys/bus/platform/drivers/ufshcd/*/capabilities/write_booster 1619 + What: /sys/bus/platform/devices/*.ufs/capabilities/write_booster 1620 + Date: August 2022 1621 + Contact: Daniil Lunev <dlunev@chromium.org> 1622 + Description: Indicates status of Write Booster. 1623 + 1624 + == ============================ 1625 + 0 Write Booster can not be enabled. 1626 + 1 Write Booster can be enabled. 1599 1627 == ============================ 1600 1628 1601 1629 The file is read only.
+1 -1
Documentation/scsi/ChangeLog.lpfc
··· 401 401 structure. 402 402 * Integrated patch from Christoph Hellwig <hch@lst.de> Kill 403 403 compile warnings on 64 bit platforms: %variables for %llx format 404 - specifiers must be caste to long long because %(u)int64_t can 404 + specifiers must be cast to long long because %(u)int64_t can 405 405 just be long on 64bit platforms. 406 406 * Integrated patch from Christoph Hellwig <hch@lst.de> Removes 407 407 dead code.
+2 -4
drivers/message/fusion/mptctl.c
··· 620 620 { 621 621 mpt_ioctl_header __user *uhdr = (void __user *) arg; 622 622 mpt_ioctl_header khdr; 623 - int iocnum; 624 623 unsigned iocnumX; 625 624 int nonblock = (file->f_flags & O_NONBLOCK); 626 625 int ret; ··· 633 634 } 634 635 ret = -ENXIO; /* (-6) No such device or address */ 635 636 636 - /* Verify intended MPT adapter - set iocnum and the adapter 637 + /* Verify intended MPT adapter - set iocnumX and the adapter 637 638 * pointer (iocp) 638 639 */ 639 640 iocnumX = khdr.iocnum & 0xFF; 640 - if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) || 641 - (iocp == NULL)) 641 + if ((mpt_verify_adapter(iocnumX, &iocp) < 0) || (iocp == NULL)) 642 642 return -ENODEV; 643 643 644 644 if (!iocp->active) {
+1 -1
drivers/scsi/3w-9xxx.c
··· 2006 2006 retval = pci_enable_device(pdev); 2007 2007 if (retval) { 2008 2008 TW_PRINTK(host, TW_DRIVER, 0x34, "Failed to enable pci device"); 2009 - goto out_disable_device; 2009 + return -ENODEV; 2010 2010 } 2011 2011 2012 2012 pci_set_master(pdev);
+7 -7
drivers/scsi/3w-xxxx.c
··· 912 912 data_buffer_length_adjusted = (data_buffer_length + 511) & ~511; 913 913 914 914 /* Now allocate ioctl buf memory */ 915 - cpu_addr = dma_alloc_coherent(&tw_dev->tw_pci_dev->dev, data_buffer_length_adjusted+sizeof(TW_New_Ioctl) - 1, &dma_handle, GFP_KERNEL); 915 + cpu_addr = dma_alloc_coherent(&tw_dev->tw_pci_dev->dev, data_buffer_length_adjusted + sizeof(TW_New_Ioctl), &dma_handle, GFP_KERNEL); 916 916 if (cpu_addr == NULL) { 917 917 retval = -ENOMEM; 918 918 goto out; ··· 921 921 tw_ioctl = (TW_New_Ioctl *)cpu_addr; 922 922 923 923 /* Now copy down the entire ioctl */ 924 - if (copy_from_user(tw_ioctl, argp, data_buffer_length + sizeof(TW_New_Ioctl) - 1)) 924 + if (copy_from_user(tw_ioctl, argp, data_buffer_length + sizeof(TW_New_Ioctl))) 925 925 goto out2; 926 926 927 927 passthru = (TW_Passthru *)&tw_ioctl->firmware_command; ··· 966 966 /* Load the sg list */ 967 967 switch (TW_SGL_OUT(tw_ioctl->firmware_command.opcode__sgloffset)) { 968 968 case 2: 969 - tw_ioctl->firmware_command.byte8.param.sgl[0].address = dma_handle + sizeof(TW_New_Ioctl) - 1; 969 + tw_ioctl->firmware_command.byte8.param.sgl[0].address = dma_handle + sizeof(TW_New_Ioctl); 970 970 tw_ioctl->firmware_command.byte8.param.sgl[0].length = data_buffer_length_adjusted; 971 971 break; 972 972 case 3: 973 - tw_ioctl->firmware_command.byte8.io.sgl[0].address = dma_handle + sizeof(TW_New_Ioctl) - 1; 973 + tw_ioctl->firmware_command.byte8.io.sgl[0].address = dma_handle + sizeof(TW_New_Ioctl); 974 974 tw_ioctl->firmware_command.byte8.io.sgl[0].length = data_buffer_length_adjusted; 975 975 break; 976 976 case 5: 977 - passthru->sg_list[0].address = dma_handle + sizeof(TW_New_Ioctl) - 1; 977 + passthru->sg_list[0].address = dma_handle + sizeof(TW_New_Ioctl); 978 978 passthru->sg_list[0].length = data_buffer_length_adjusted; 979 979 break; 980 980 } ··· 1017 1017 } 1018 1018 1019 1019 /* Now copy the response to userspace */ 1020 - if (copy_to_user(argp, tw_ioctl, sizeof(TW_New_Ioctl) + data_buffer_length - 1)) 1020 + if (copy_to_user(argp, tw_ioctl, sizeof(TW_New_Ioctl) + data_buffer_length)) 1021 1021 goto out2; 1022 1022 retval = 0; 1023 1023 out2: 1024 1024 /* Now free ioctl buf memory */ 1025 - dma_free_coherent(&tw_dev->tw_pci_dev->dev, data_buffer_length_adjusted+sizeof(TW_New_Ioctl) - 1, cpu_addr, dma_handle); 1025 + dma_free_coherent(&tw_dev->tw_pci_dev->dev, data_buffer_length_adjusted + sizeof(TW_New_Ioctl), cpu_addr, dma_handle); 1026 1026 out: 1027 1027 mutex_unlock(&tw_dev->ioctl_lock); 1028 1028 mutex_unlock(&tw_mutex);
+1 -1
drivers/scsi/3w-xxxx.h
··· 348 348 unsigned int data_buffer_length; 349 349 unsigned char padding [508]; 350 350 TW_Command firmware_command; 351 - char data_buffer[1]; 351 + char data_buffer[]; 352 352 } TW_New_Ioctl; 353 353 354 354 /* GetParam descriptor */
+4 -3
drivers/scsi/Kconfig
··· 2 2 menu "SCSI device support" 3 3 4 4 config SCSI_MOD 5 - tristate 6 - default y if SCSI=n || SCSI=y 7 - default m if SCSI=m 5 + tristate 6 + default y if SCSI=n || SCSI=y 7 + default m if SCSI=m 8 + depends on BLOCK 8 9 9 10 config RAID_ATTRS 10 11 tristate "RAID Transport Class"
+1 -1
drivers/scsi/aic7xxx/aic79xx_osm.c
··· 194 194 #define AIC79XX_PRECOMP_INDEX 0 195 195 #define AIC79XX_SLEWRATE_INDEX 1 196 196 #define AIC79XX_AMPLITUDE_INDEX 2 197 - static const struct ahd_linux_iocell_opts aic79xx_iocell_info[] = 197 + static struct ahd_linux_iocell_opts aic79xx_iocell_info[] __ro_after_init = 198 198 { 199 199 AIC79XX_DEFAULT_IOOPTS, 200 200 AIC79XX_DEFAULT_IOOPTS,
+5 -5
drivers/scsi/csiostor/csio_scsi.c
··· 1366 1366 struct csio_hw *hw = csio_lnode_to_hw(ln); 1367 1367 1368 1368 if (csio_is_hw_ready(hw)) 1369 - return snprintf(buf, PAGE_SIZE, "ready\n"); 1370 - else 1371 - return snprintf(buf, PAGE_SIZE, "not ready\n"); 1369 + return sysfs_emit(buf, "ready\n"); 1370 + 1371 + return sysfs_emit(buf, "not ready\n"); 1372 1372 } 1373 1373 1374 1374 /* Device reset */ ··· 1430 1430 { 1431 1431 struct csio_lnode *ln = shost_priv(class_to_shost(dev)); 1432 1432 1433 - return snprintf(buf, PAGE_SIZE, "%x\n", ln->params.log_level); 1433 + return sysfs_emit(buf, "%x\n", ln->params.log_level); 1434 1434 } 1435 1435 1436 1436 /* Store debug level */ ··· 1476 1476 { 1477 1477 struct csio_lnode *ln = shost_priv(class_to_shost(dev)); 1478 1478 1479 - return snprintf(buf, PAGE_SIZE, "%d\n", ln->num_reg_rnodes); 1479 + return sysfs_emit(buf, "%d\n", ln->num_reg_rnodes); 1480 1480 } 1481 1481 1482 1482 static DEVICE_ATTR(num_reg_rnodes, S_IRUGO, csio_show_num_reg_rnodes, NULL);
+1 -1
drivers/scsi/cxlflash/main.c
··· 132 132 break; 133 133 case SISL_AFU_RC_OUT_OF_DATA_BUFS: 134 134 /* Retry */ 135 - scp->result = (DID_ALLOC_FAILURE << 16); 135 + scp->result = (DID_ERROR << 16); 136 136 break; 137 137 default: 138 138 scp->result = (DID_ERROR << 16);
+1
drivers/scsi/esas2r/atioctl.h
··· 831 831 u32 total_length; 832 832 u32 trace_mask; 833 833 u8 reserved2[48]; 834 + u8 contents[]; 834 835 }; 835 836 836 837 #define ATTO_FUNC_SCSI_PASS_THRU 0x04
+1 -2
drivers/scsi/esas2r/esas2r_ioctl.c
··· 947 947 break; 948 948 } 949 949 950 - memcpy(trc + 1, 950 + memcpy(trc->contents, 951 951 a->fw_coredump_buff + offset, 952 952 len); 953 - 954 953 hi->data_length = len; 955 954 } else if (trc->trace_func == ATTO_TRC_TF_RESET) { 956 955 memset(a->fw_coredump_buff, 0,
+1
drivers/scsi/hisi_sas/hisi_sas.h
··· 649 649 int enable); 650 650 extern void hisi_sas_phy_down(struct hisi_hba *hisi_hba, int phy_no, int rdy, 651 651 gfp_t gfp_flags); 652 + extern void hisi_sas_phy_bcast(struct hisi_sas_phy *phy); 652 653 extern void hisi_sas_slot_task_free(struct hisi_hba *hisi_hba, 653 654 struct sas_task *task, 654 655 struct hisi_sas_slot *slot);
+32 -5
drivers/scsi/hisi_sas/hisi_sas_main.c
··· 1341 1341 1342 1342 static void hisi_sas_rescan_topology(struct hisi_hba *hisi_hba, u32 state) 1343 1343 { 1344 + struct sas_ha_struct *sas_ha = &hisi_hba->sha; 1344 1345 struct asd_sas_port *_sas_port = NULL; 1345 1346 int phy_no; 1346 1347 ··· 1370 1369 hisi_sas_phy_down(hisi_hba, phy_no, 0, GFP_KERNEL); 1371 1370 } 1372 1371 } 1372 + /* 1373 + * Ensure any bcast events are processed prior to calling async nexus 1374 + * reset calls from hisi_sas_clear_nexus_ha() -> 1375 + * hisi_sas_async_I_T_nexus_reset() 1376 + */ 1377 + sas_drain_work(sas_ha); 1373 1378 } 1374 1379 1375 1380 static void hisi_sas_reset_init_all_devices(struct hisi_hba *hisi_hba) ··· 1534 1527 clear_bit(HISI_SAS_RESETTING_BIT, &hisi_hba->flags); 1535 1528 return rc; 1536 1529 } 1530 + clear_bit(HISI_SAS_HW_FAULT_BIT, &hisi_hba->flags); 1537 1531 1538 1532 hisi_sas_controller_reset_done(hisi_hba); 1539 - clear_bit(HISI_SAS_HW_FAULT_BIT, &hisi_hba->flags); 1540 1533 dev_info(dev, "controller reset complete\n"); 1541 1534 1542 1535 return 0; ··· 1823 1816 struct hisi_hba *hisi_hba = sas_ha->lldd_ha; 1824 1817 HISI_SAS_DECLARE_RST_WORK_ON_STACK(r); 1825 1818 ASYNC_DOMAIN_EXCLUSIVE(async); 1826 - int i; 1819 + int i, ret; 1827 1820 1828 1821 queue_work(hisi_hba->wq, &r.work); 1829 1822 wait_for_completion(r.completion); 1830 - if (!r.done) 1831 - return TMF_RESP_FUNC_FAILED; 1823 + if (!r.done) { 1824 + ret = TMF_RESP_FUNC_FAILED; 1825 + goto out; 1826 + } 1832 1827 1833 1828 for (i = 0; i < HISI_SAS_MAX_DEVICES; i++) { 1834 1829 struct hisi_sas_device *sas_dev = &hisi_hba->devices[i]; ··· 1847 1838 async_synchronize_full_domain(&async); 1848 1839 hisi_sas_release_tasks(hisi_hba); 1849 1840 1850 - return TMF_RESP_FUNC_COMPLETE; 1841 + ret = TMF_RESP_FUNC_COMPLETE; 1842 + out: 1843 + return ret; 1851 1844 } 1852 1845 1853 1846 static int hisi_sas_query_task(struct sas_task *task) ··· 1992 1981 } 1993 1982 } 1994 1983 EXPORT_SYMBOL_GPL(hisi_sas_phy_down); 1984 + 1985 + void hisi_sas_phy_bcast(struct hisi_sas_phy *phy) 1986 + { 1987 + struct asd_sas_phy *sas_phy = &phy->sas_phy; 1988 + struct hisi_hba *hisi_hba = phy->hisi_hba; 1989 + struct sas_ha_struct *sha = &hisi_hba->sha; 1990 + 1991 + if (test_bit(HISI_SAS_RESETTING_BIT, &hisi_hba->flags)) 1992 + return; 1993 + 1994 + if (test_bit(SAS_HA_FROZEN, &sha->state)) 1995 + return; 1996 + 1997 + sas_notify_port_event(sas_phy, PORTE_BROADCAST_RCVD, GFP_ATOMIC); 1998 + } 1999 + EXPORT_SYMBOL_GPL(hisi_sas_phy_bcast); 1995 2000 1996 2001 void hisi_sas_sync_irqs(struct hisi_hba *hisi_hba) 1997 2002 {
+1 -3
drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
··· 1412 1412 goto end; 1413 1413 } 1414 1414 1415 - if (!test_bit(HISI_SAS_RESETTING_BIT, &hisi_hba->flags)) 1416 - sas_notify_port_event(sas_phy, PORTE_BROADCAST_RCVD, 1417 - GFP_ATOMIC); 1415 + hisi_sas_phy_bcast(phy); 1418 1416 1419 1417 end: 1420 1418 hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT2,
+2 -5
drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
··· 2811 2811 static void phy_bcast_v2_hw(int phy_no, struct hisi_hba *hisi_hba) 2812 2812 { 2813 2813 struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; 2814 - struct asd_sas_phy *sas_phy = &phy->sas_phy; 2815 2814 u32 bcast_status; 2816 2815 2817 2816 hisi_sas_phy_write32(hisi_hba, phy_no, SL_RX_BCAST_CHK_MSK, 1); 2818 2817 bcast_status = hisi_sas_phy_read32(hisi_hba, phy_no, RX_PRIMS_STATUS); 2819 - if ((bcast_status & RX_BCAST_CHG_MSK) && 2820 - !test_bit(HISI_SAS_RESETTING_BIT, &hisi_hba->flags)) 2821 - sas_notify_port_event(sas_phy, PORTE_BROADCAST_RCVD, 2822 - GFP_ATOMIC); 2818 + if (bcast_status & RX_BCAST_CHG_MSK) 2819 + hisi_sas_phy_bcast(phy); 2823 2820 hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT0, 2824 2821 CHL_INT0_SL_RX_BCST_ACK_MSK); 2825 2822 hisi_sas_phy_write32(hisi_hba, phy_no, SL_RX_BCAST_CHK_MSK, 0);
+2 -12
drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
··· 1626 1626 static irqreturn_t phy_bcast_v3_hw(int phy_no, struct hisi_hba *hisi_hba) 1627 1627 { 1628 1628 struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; 1629 - struct asd_sas_phy *sas_phy = &phy->sas_phy; 1630 1629 u32 bcast_status; 1631 1630 1632 1631 hisi_sas_phy_write32(hisi_hba, phy_no, SL_RX_BCAST_CHK_MSK, 1); 1633 1632 bcast_status = hisi_sas_phy_read32(hisi_hba, phy_no, RX_PRIMS_STATUS); 1634 - if ((bcast_status & RX_BCAST_CHG_MSK) && 1635 - !test_bit(HISI_SAS_RESETTING_BIT, &hisi_hba->flags)) 1636 - sas_notify_port_event(sas_phy, PORTE_BROADCAST_RCVD, 1637 - GFP_ATOMIC); 1633 + if (bcast_status & RX_BCAST_CHG_MSK) 1634 + hisi_sas_phy_bcast(phy); 1638 1635 hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT0, 1639 1636 CHL_INT0_SL_RX_BCST_ACK_MSK); 1640 1637 hisi_sas_phy_write32(hisi_hba, phy_no, SL_RX_BCAST_CHK_MSK, 0); ··· 2783 2786 struct hisi_hba *hisi_hba = shost_priv(shost); 2784 2787 int ret = hisi_sas_slave_configure(sdev); 2785 2788 struct device *dev = hisi_hba->dev; 2786 - unsigned int max_sectors; 2787 2789 2788 2790 if (ret) 2789 2791 return ret; ··· 2797 2801 pm_runtime_disable(dev); 2798 2802 } 2799 2803 } 2800 - 2801 - /* Set according to IOMMU IOVA caching limit */ 2802 - max_sectors = min_t(size_t, queue_max_hw_sectors(sdev->request_queue), 2803 - (PAGE_SIZE * 32) >> SECTOR_SHIFT); 2804 - 2805 - blk_queue_max_hw_sectors(sdev->request_queue, max_sectors); 2806 2804 2807 2805 return 0; 2808 2806 }
+4 -8
drivers/scsi/hpsa.c
··· 6233 6233 offset = (i + 1) % HPSA_NRESERVED_CMDS; 6234 6234 continue; 6235 6235 } 6236 - set_bit(i & (BITS_PER_LONG - 1), 6237 - h->cmd_pool_bits + (i / BITS_PER_LONG)); 6236 + set_bit(i, h->cmd_pool_bits); 6238 6237 break; /* it's ours now. */ 6239 6238 } 6240 6239 hpsa_cmd_partial_init(h, i, c); ··· 6260 6261 int i; 6261 6262 6262 6263 i = c - h->cmd_pool; 6263 - clear_bit(i & (BITS_PER_LONG - 1), 6264 - h->cmd_pool_bits + (i / BITS_PER_LONG)); 6264 + clear_bit(i, h->cmd_pool_bits); 6265 6265 } 6266 6266 } 6267 6267 ··· 8028 8030 8029 8031 static void hpsa_free_cmd_pool(struct ctlr_info *h) 8030 8032 { 8031 - kfree(h->cmd_pool_bits); 8033 + bitmap_free(h->cmd_pool_bits); 8032 8034 h->cmd_pool_bits = NULL; 8033 8035 if (h->cmd_pool) { 8034 8036 dma_free_coherent(&h->pdev->dev, ··· 8050 8052 8051 8053 static int hpsa_alloc_cmd_pool(struct ctlr_info *h) 8052 8054 { 8053 - h->cmd_pool_bits = kcalloc(DIV_ROUND_UP(h->nr_cmds, BITS_PER_LONG), 8054 - sizeof(unsigned long), 8055 - GFP_KERNEL); 8055 + h->cmd_pool_bits = bitmap_zalloc(h->nr_cmds, GFP_KERNEL); 8056 8056 h->cmd_pool = dma_alloc_coherent(&h->pdev->dev, 8057 8057 h->nr_cmds * sizeof(*h->cmd_pool), 8058 8058 &h->cmd_pool_dhandle, GFP_KERNEL);
+3 -6
drivers/scsi/hptiop.c
··· 1044 1044 req->channel = scp->device->channel; 1045 1045 req->target = scp->device->id; 1046 1046 req->lun = scp->device->lun; 1047 - req->header.size = cpu_to_le32( 1048 - sizeof(struct hpt_iop_request_scsi_command) 1049 - - sizeof(struct hpt_iopsg) 1050 - + sg_count * sizeof(struct hpt_iopsg)); 1047 + req->header.size = cpu_to_le32(struct_size(req, sg_list, sg_count)); 1051 1048 1052 1049 memcpy(req->cdb, scp->cmnd, sizeof(req->cdb)); 1053 1050 hba->ops->post_req(hba, _req); ··· 1394 1397 host->cmd_per_lun = le32_to_cpu(iop_config.max_requests); 1395 1398 host->max_cmd_len = 16; 1396 1399 1397 - req_size = sizeof(struct hpt_iop_request_scsi_command) 1398 - + sizeof(struct hpt_iopsg) * (hba->max_sg_descriptors - 1); 1400 + req_size = struct_size((struct hpt_iop_request_scsi_command *)0, 1401 + sg_list, hba->max_sg_descriptors); 1399 1402 if ((req_size & 0x1f) != 0) 1400 1403 req_size = (req_size + 0x1f) & ~0x1f; 1401 1404
+2 -2
drivers/scsi/hptiop.h
··· 228 228 u8 pad1; 229 229 u8 cdb[16]; 230 230 __le32 dataxfer_length; 231 - struct hpt_iopsg sg_list[1]; 231 + struct hpt_iopsg sg_list[]; 232 232 }; 233 233 234 234 struct hpt_iop_request_ioctl_command { ··· 237 237 __le32 inbuf_size; 238 238 __le32 outbuf_size; 239 239 __le32 bytes_returned; 240 - u8 buf[1]; 240 + u8 buf[]; 241 241 /* out data should be put at buf[(inbuf_size+3)&~3] */ 242 242 }; 243 243
+1 -1
drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
··· 444 444 break; 445 445 446 446 /* 447 - * Can transition from this state to to unconfiguring 447 + * Can transition from this state to unconfiguring 448 448 * or err disconnect. 449 449 */ 450 450 case ERR_DISCONNECT_RECONNECT:
+1 -1
drivers/scsi/initio.c
··· 1166 1166 return; 1167 1167 } 1168 1168 if (host->jsint & (TSS_FUNC_COMP | TSS_BUS_SERV)) { /* func complete or Bus service */ 1169 - if ((scb = host->active) != NULL) 1169 + if (host->active) 1170 1170 initio_next_state(host); 1171 1171 return; 1172 1172 }
+52 -21
drivers/scsi/iscsi_tcp.c
··· 595 595 INIT_WORK(&conn->recvwork, iscsi_sw_tcp_recv_data_work); 596 596 tcp_sw_conn->queue_recv = iscsi_recv_from_iscsi_q; 597 597 598 + mutex_init(&tcp_sw_conn->sock_lock); 599 + 598 600 tfm = crypto_alloc_ahash("crc32c", 0, CRYPTO_ALG_ASYNC); 599 601 if (IS_ERR(tfm)) 600 602 goto free_conn; ··· 631 629 632 630 static void iscsi_sw_tcp_release_conn(struct iscsi_conn *conn) 633 631 { 634 - struct iscsi_session *session = conn->session; 635 632 struct iscsi_tcp_conn *tcp_conn = conn->dd_data; 636 633 struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data; 637 634 struct socket *sock = tcp_sw_conn->sock; 638 635 636 + /* 637 + * The iscsi transport class will make sure we are not called in 638 + * parallel with start, stop, bind and destroys. However, this can be 639 + * called twice if userspace does a stop then a destroy. 640 + */ 639 641 if (!sock) 640 642 return; 641 643 ··· 655 649 656 650 iscsi_suspend_rx(conn); 657 651 658 - spin_lock_bh(&session->frwd_lock); 652 + mutex_lock(&tcp_sw_conn->sock_lock); 659 653 tcp_sw_conn->sock = NULL; 660 - spin_unlock_bh(&session->frwd_lock); 654 + mutex_unlock(&tcp_sw_conn->sock_lock); 661 655 sockfd_put(sock); 662 656 } 663 657 ··· 709 703 struct iscsi_cls_conn *cls_conn, uint64_t transport_eph, 710 704 int is_leading) 711 705 { 712 - struct iscsi_session *session = cls_session->dd_data; 713 706 struct iscsi_conn *conn = cls_conn->dd_data; 714 707 struct iscsi_tcp_conn *tcp_conn = conn->dd_data; 715 708 struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data; ··· 728 723 if (err) 729 724 goto free_socket; 730 725 731 - spin_lock_bh(&session->frwd_lock); 726 + mutex_lock(&tcp_sw_conn->sock_lock); 732 727 /* bind iSCSI connection and socket */ 733 728 tcp_sw_conn->sock = sock; 734 - spin_unlock_bh(&session->frwd_lock); 729 + mutex_unlock(&tcp_sw_conn->sock_lock); 735 730 736 731 /* setup Socket parameters */ 737 732 sk = sock->sk; ··· 768 763 break; 769 764 case ISCSI_PARAM_DATADGST_EN: 770 765 iscsi_set_param(cls_conn, param, buf, buflen); 766 + 767 + mutex_lock(&tcp_sw_conn->sock_lock); 768 + if (!tcp_sw_conn->sock) { 769 + mutex_unlock(&tcp_sw_conn->sock_lock); 770 + return -ENOTCONN; 771 + } 771 772 tcp_sw_conn->sendpage = conn->datadgst_en ? 772 773 sock_no_sendpage : tcp_sw_conn->sock->ops->sendpage; 774 + mutex_unlock(&tcp_sw_conn->sock_lock); 773 775 break; 774 776 case ISCSI_PARAM_MAX_R2T: 775 777 return iscsi_tcp_set_max_r2t(conn, buf); ··· 791 779 enum iscsi_param param, char *buf) 792 780 { 793 781 struct iscsi_conn *conn = cls_conn->dd_data; 794 - struct iscsi_tcp_conn *tcp_conn = conn->dd_data; 795 - struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data; 782 + struct iscsi_sw_tcp_conn *tcp_sw_conn; 783 + struct iscsi_tcp_conn *tcp_conn; 796 784 struct sockaddr_in6 addr; 797 785 struct socket *sock; 798 786 int rc; ··· 802 790 case ISCSI_PARAM_CONN_ADDRESS: 803 791 case ISCSI_PARAM_LOCAL_PORT: 804 792 spin_lock_bh(&conn->session->frwd_lock); 805 - if (!tcp_sw_conn || !tcp_sw_conn->sock) { 793 + if (!conn->session->leadconn) { 806 794 spin_unlock_bh(&conn->session->frwd_lock); 807 795 return -ENOTCONN; 808 796 } 809 - sock = tcp_sw_conn->sock; 810 - sock_hold(sock->sk); 797 + /* 798 + * The conn has been setup and bound, so just grab a ref 799 + * incase a destroy runs while we are in the net layer. 800 + */ 801 + iscsi_get_conn(conn->cls_conn); 811 802 spin_unlock_bh(&conn->session->frwd_lock); 803 + 804 + tcp_conn = conn->dd_data; 805 + tcp_sw_conn = tcp_conn->dd_data; 806 + 807 + mutex_lock(&tcp_sw_conn->sock_lock); 808 + sock = tcp_sw_conn->sock; 809 + if (!sock) { 810 + rc = -ENOTCONN; 811 + goto sock_unlock; 812 + } 812 813 813 814 if (param == ISCSI_PARAM_LOCAL_PORT) 814 815 rc = kernel_getsockname(sock, ··· 829 804 else 830 805 rc = kernel_getpeername(sock, 831 806 (struct sockaddr *)&addr); 832 - sock_put(sock->sk); 807 + sock_unlock: 808 + mutex_unlock(&tcp_sw_conn->sock_lock); 809 + iscsi_put_conn(conn->cls_conn); 833 810 if (rc < 0) 834 811 return rc; 835 812 ··· 869 842 } 870 843 tcp_conn = conn->dd_data; 871 844 tcp_sw_conn = tcp_conn->dd_data; 872 - sock = tcp_sw_conn->sock; 873 - if (!sock) { 874 - spin_unlock_bh(&session->frwd_lock); 875 - return -ENOTCONN; 876 - } 877 - sock_hold(sock->sk); 845 + /* 846 + * The conn has been setup and bound, so just grab a ref 847 + * incase a destroy runs while we are in the net layer. 848 + */ 849 + iscsi_get_conn(conn->cls_conn); 878 850 spin_unlock_bh(&session->frwd_lock); 879 851 880 - rc = kernel_getsockname(sock, 881 - (struct sockaddr *)&addr); 882 - sock_put(sock->sk); 852 + mutex_lock(&tcp_sw_conn->sock_lock); 853 + sock = tcp_sw_conn->sock; 854 + if (!sock) 855 + rc = -ENOTCONN; 856 + else 857 + rc = kernel_getsockname(sock, (struct sockaddr *)&addr); 858 + mutex_unlock(&tcp_sw_conn->sock_lock); 859 + iscsi_put_conn(conn->cls_conn); 883 860 if (rc < 0) 884 861 return rc; 885 862
+3
drivers/scsi/iscsi_tcp.h
··· 28 28 29 29 struct iscsi_sw_tcp_conn { 30 30 struct socket *sock; 31 + /* Taken when accessing the sock from the netlink/sysfs interface */ 32 + struct mutex sock_lock; 33 + 31 34 struct work_struct recvwork; 32 35 bool queue_recv; 33 36
+1 -1
drivers/scsi/libsas/sas_expander.c
··· 67 67 res = i->dft->lldd_execute_task(task, GFP_KERNEL); 68 68 69 69 if (res) { 70 - del_timer(&task->slow_task->timer); 70 + del_timer_sync(&task->slow_task->timer); 71 71 pr_notice("executing SMP task failed:%d\n", res); 72 72 break; 73 73 }
+16 -21
drivers/scsi/lpfc/lpfc.h
··· 68 68 #define LPFC_MIN_TGT_QDEPTH 10 69 69 #define LPFC_MAX_TGT_QDEPTH 0xFFFF 70 70 71 - #define LPFC_MAX_BUCKET_COUNT 20 /* Maximum no. of buckets for stat data 72 - collection. */ 73 71 /* 74 72 * Following time intervals are used of adjusting SCSI device 75 73 * queue depths when there are driver resource error or Firmware ··· 403 405 link1, 404 406 link2, 405 407 link3; 408 + u32 phy_lnk_speed; 406 409 }; 407 410 408 411 /* Format of congestion module parameters */ ··· 731 732 struct lpfc_debugfs_trc *disc_trc; 732 733 atomic_t disc_trc_cnt; 733 734 #endif 734 - uint8_t stat_data_enabled; 735 - uint8_t stat_data_blocked; 736 735 struct list_head rcv_buffer_list; 737 736 unsigned long rcv_buffer_time_stamp; 738 737 uint32_t vport_flag; ··· 1433 1436 */ 1434 1437 #define QUE_BUFTAG_BIT (1<<31) 1435 1438 uint32_t buffer_tag_count; 1436 - /* data structure used for latency data collection */ 1437 - #define LPFC_NO_BUCKET 0 1438 - #define LPFC_LINEAR_BUCKET 1 1439 - #define LPFC_POWER2_BUCKET 2 1440 - uint8_t bucket_type; 1441 - uint32_t bucket_base; 1442 - uint32_t bucket_step; 1443 1439 1444 1440 /* Maximum number of events that can be outstanding at any time*/ 1445 1441 #define LPFC_MAX_EVT_COUNT 512 ··· 1554 1564 /* cgn_reg_signal and cgn_init_reg_signal use 1555 1565 * enum fc_edc_cg_signal_cap_types 1556 1566 */ 1557 - u16 cgn_fpin_frequency; 1567 + u16 cgn_fpin_frequency; /* In units of msecs */ 1558 1568 #define LPFC_FPIN_INIT_FREQ 0xffff 1559 1569 u32 cgn_sig_freq; 1560 1570 u32 cgn_acqe_cnt; 1561 1571 1562 1572 /* RX monitor handling for CMF */ 1563 - struct rxtable_entry *rxtable; /* RX_monitor information */ 1564 - atomic_t rxtable_idx_head; 1565 - #define LPFC_RXMONITOR_TABLE_IN_USE (LPFC_MAX_RXMONITOR_ENTRY + 73) 1566 - atomic_t rxtable_idx_tail; 1573 + struct lpfc_rx_info_monitor *rx_monitor; 1567 1574 atomic_t rx_max_read_cnt; /* Maximum read bytes */ 1568 1575 uint64_t rx_block_cnt; 1569 1576 ··· 1597 1610 1598 1611 char os_host_name[MAXHOSTNAMELEN]; 1599 1612 1600 - /* SCSI host template information - for physical port */ 1601 - struct scsi_host_template port_template; 1602 - /* SCSI host template information - for all vports */ 1603 - struct scsi_host_template vport_template; 1613 + /* LD Signaling */ 1614 + u32 degrade_activate_threshold; 1615 + u32 degrade_deactivate_threshold; 1616 + u32 fec_degrade_interval; 1617 + 1604 1618 atomic_t dbg_log_idx; 1605 1619 atomic_t dbg_log_cnt; 1606 1620 atomic_t dbg_log_dmping; ··· 1610 1622 1611 1623 #define LPFC_MAX_RXMONITOR_ENTRY 800 1612 1624 #define LPFC_MAX_RXMONITOR_DUMP 32 1613 - struct rxtable_entry { 1625 + struct rx_info_entry { 1614 1626 uint64_t cmf_bytes; /* Total no of read bytes for CMF_SYNC_WQE */ 1615 1627 uint64_t total_bytes; /* Total no of read bytes requested */ 1616 1628 uint64_t rcv_bytes; /* Total no of read bytes completed */ ··· 1623 1635 uint32_t io_cnt; 1624 1636 uint32_t timer_utilization; 1625 1637 uint32_t timer_interval; 1638 + }; 1639 + 1640 + struct lpfc_rx_info_monitor { 1641 + struct rx_info_entry *ring; /* info organized in a circular buffer */ 1642 + u32 head_idx, tail_idx; /* index to head/tail of ring */ 1643 + spinlock_t lock; /* spinlock for ring */ 1644 + u32 entries; /* storing number entries/size of ring */ 1626 1645 }; 1627 1646 1628 1647 static inline struct Scsi_Host *
+4 -340
drivers/scsi/lpfc/lpfc_attr.c
··· 4093 4093 */ 4094 4094 static DEVICE_ATTR_RO(lpfc_static_vport); 4095 4095 4096 - /** 4097 - * lpfc_stat_data_ctrl_store - write call back for lpfc_stat_data_ctrl sysfs file 4098 - * @dev: Pointer to class device. 4099 - * @attr: Unused. 4100 - * @buf: Data buffer. 4101 - * @count: Size of the data buffer. 4102 - * 4103 - * This function get called when a user write to the lpfc_stat_data_ctrl 4104 - * sysfs file. This function parse the command written to the sysfs file 4105 - * and take appropriate action. These commands are used for controlling 4106 - * driver statistical data collection. 4107 - * Following are the command this function handles. 4108 - * 4109 - * setbucket <bucket_type> <base> <step> 4110 - * = Set the latency buckets. 4111 - * destroybucket = destroy all the buckets. 4112 - * start = start data collection 4113 - * stop = stop data collection 4114 - * reset = reset the collected data 4115 - **/ 4116 - static ssize_t 4117 - lpfc_stat_data_ctrl_store(struct device *dev, struct device_attribute *attr, 4118 - const char *buf, size_t count) 4119 - { 4120 - struct Scsi_Host *shost = class_to_shost(dev); 4121 - struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; 4122 - struct lpfc_hba *phba = vport->phba; 4123 - #define LPFC_MAX_DATA_CTRL_LEN 1024 4124 - static char bucket_data[LPFC_MAX_DATA_CTRL_LEN]; 4125 - unsigned long i; 4126 - char *str_ptr, *token; 4127 - struct lpfc_vport **vports; 4128 - struct Scsi_Host *v_shost; 4129 - char *bucket_type_str, *base_str, *step_str; 4130 - unsigned long base, step, bucket_type; 4131 - 4132 - if (!strncmp(buf, "setbucket", strlen("setbucket"))) { 4133 - if (strlen(buf) > (LPFC_MAX_DATA_CTRL_LEN - 1)) 4134 - return -EINVAL; 4135 - 4136 - strncpy(bucket_data, buf, LPFC_MAX_DATA_CTRL_LEN); 4137 - str_ptr = &bucket_data[0]; 4138 - /* Ignore this token - this is command token */ 4139 - token = strsep(&str_ptr, "\t "); 4140 - if (!token) 4141 - return -EINVAL; 4142 - 4143 - bucket_type_str = strsep(&str_ptr, "\t "); 4144 - if (!bucket_type_str) 4145 - return -EINVAL; 4146 - 4147 - if (!strncmp(bucket_type_str, "linear", strlen("linear"))) 4148 - bucket_type = LPFC_LINEAR_BUCKET; 4149 - else if (!strncmp(bucket_type_str, "power2", strlen("power2"))) 4150 - bucket_type = LPFC_POWER2_BUCKET; 4151 - else 4152 - return -EINVAL; 4153 - 4154 - base_str = strsep(&str_ptr, "\t "); 4155 - if (!base_str) 4156 - return -EINVAL; 4157 - base = simple_strtoul(base_str, NULL, 0); 4158 - 4159 - step_str = strsep(&str_ptr, "\t "); 4160 - if (!step_str) 4161 - return -EINVAL; 4162 - step = simple_strtoul(step_str, NULL, 0); 4163 - if (!step) 4164 - return -EINVAL; 4165 - 4166 - /* Block the data collection for every vport */ 4167 - vports = lpfc_create_vport_work_array(phba); 4168 - if (vports == NULL) 4169 - return -ENOMEM; 4170 - 4171 - for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) { 4172 - v_shost = lpfc_shost_from_vport(vports[i]); 4173 - spin_lock_irq(v_shost->host_lock); 4174 - /* Block and reset data collection */ 4175 - vports[i]->stat_data_blocked = 1; 4176 - if (vports[i]->stat_data_enabled) 4177 - lpfc_vport_reset_stat_data(vports[i]); 4178 - spin_unlock_irq(v_shost->host_lock); 4179 - } 4180 - 4181 - /* Set the bucket attributes */ 4182 - phba->bucket_type = bucket_type; 4183 - phba->bucket_base = base; 4184 - phba->bucket_step = step; 4185 - 4186 - for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) { 4187 - v_shost = lpfc_shost_from_vport(vports[i]); 4188 - 4189 - /* Unblock data collection */ 4190 - spin_lock_irq(v_shost->host_lock); 4191 - vports[i]->stat_data_blocked = 0; 4192 - spin_unlock_irq(v_shost->host_lock); 4193 - } 4194 - lpfc_destroy_vport_work_array(phba, vports); 4195 - return strlen(buf); 4196 - } 4197 - 4198 - if (!strncmp(buf, "destroybucket", strlen("destroybucket"))) { 4199 - vports = lpfc_create_vport_work_array(phba); 4200 - if (vports == NULL) 4201 - return -ENOMEM; 4202 - 4203 - for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) { 4204 - v_shost = lpfc_shost_from_vport(vports[i]); 4205 - spin_lock_irq(shost->host_lock); 4206 - vports[i]->stat_data_blocked = 1; 4207 - lpfc_free_bucket(vport); 4208 - vport->stat_data_enabled = 0; 4209 - vports[i]->stat_data_blocked = 0; 4210 - spin_unlock_irq(shost->host_lock); 4211 - } 4212 - lpfc_destroy_vport_work_array(phba, vports); 4213 - phba->bucket_type = LPFC_NO_BUCKET; 4214 - phba->bucket_base = 0; 4215 - phba->bucket_step = 0; 4216 - return strlen(buf); 4217 - } 4218 - 4219 - if (!strncmp(buf, "start", strlen("start"))) { 4220 - /* If no buckets configured return error */ 4221 - if (phba->bucket_type == LPFC_NO_BUCKET) 4222 - return -EINVAL; 4223 - spin_lock_irq(shost->host_lock); 4224 - if (vport->stat_data_enabled) { 4225 - spin_unlock_irq(shost->host_lock); 4226 - return strlen(buf); 4227 - } 4228 - lpfc_alloc_bucket(vport); 4229 - vport->stat_data_enabled = 1; 4230 - spin_unlock_irq(shost->host_lock); 4231 - return strlen(buf); 4232 - } 4233 - 4234 - if (!strncmp(buf, "stop", strlen("stop"))) { 4235 - spin_lock_irq(shost->host_lock); 4236 - if (vport->stat_data_enabled == 0) { 4237 - spin_unlock_irq(shost->host_lock); 4238 - return strlen(buf); 4239 - } 4240 - lpfc_free_bucket(vport); 4241 - vport->stat_data_enabled = 0; 4242 - spin_unlock_irq(shost->host_lock); 4243 - return strlen(buf); 4244 - } 4245 - 4246 - if (!strncmp(buf, "reset", strlen("reset"))) { 4247 - if ((phba->bucket_type == LPFC_NO_BUCKET) 4248 - || !vport->stat_data_enabled) 4249 - return strlen(buf); 4250 - spin_lock_irq(shost->host_lock); 4251 - vport->stat_data_blocked = 1; 4252 - lpfc_vport_reset_stat_data(vport); 4253 - vport->stat_data_blocked = 0; 4254 - spin_unlock_irq(shost->host_lock); 4255 - return strlen(buf); 4256 - } 4257 - return -EINVAL; 4258 - } 4259 - 4260 - 4261 - /** 4262 - * lpfc_stat_data_ctrl_show - Read function for lpfc_stat_data_ctrl sysfs file 4263 - * @dev: Pointer to class device. 4264 - * @attr: Unused. 4265 - * @buf: Data buffer. 4266 - * 4267 - * This function is the read call back function for 4268 - * lpfc_stat_data_ctrl sysfs file. This function report the 4269 - * current statistical data collection state. 4270 - **/ 4271 - static ssize_t 4272 - lpfc_stat_data_ctrl_show(struct device *dev, struct device_attribute *attr, 4273 - char *buf) 4274 - { 4275 - struct Scsi_Host *shost = class_to_shost(dev); 4276 - struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; 4277 - struct lpfc_hba *phba = vport->phba; 4278 - int index = 0; 4279 - int i; 4280 - char *bucket_type; 4281 - unsigned long bucket_value; 4282 - 4283 - switch (phba->bucket_type) { 4284 - case LPFC_LINEAR_BUCKET: 4285 - bucket_type = "linear"; 4286 - break; 4287 - case LPFC_POWER2_BUCKET: 4288 - bucket_type = "power2"; 4289 - break; 4290 - default: 4291 - bucket_type = "No Bucket"; 4292 - break; 4293 - } 4294 - 4295 - sprintf(&buf[index], "Statistical Data enabled :%d, " 4296 - "blocked :%d, Bucket type :%s, Bucket base :%d," 4297 - " Bucket step :%d\nLatency Ranges :", 4298 - vport->stat_data_enabled, vport->stat_data_blocked, 4299 - bucket_type, phba->bucket_base, phba->bucket_step); 4300 - index = strlen(buf); 4301 - if (phba->bucket_type != LPFC_NO_BUCKET) { 4302 - for (i = 0; i < LPFC_MAX_BUCKET_COUNT; i++) { 4303 - if (phba->bucket_type == LPFC_LINEAR_BUCKET) 4304 - bucket_value = phba->bucket_base + 4305 - phba->bucket_step * i; 4306 - else 4307 - bucket_value = phba->bucket_base + 4308 - (1 << i) * phba->bucket_step; 4309 - 4310 - if (index + 10 > PAGE_SIZE) 4311 - break; 4312 - sprintf(&buf[index], "%08ld ", bucket_value); 4313 - index = strlen(buf); 4314 - } 4315 - } 4316 - sprintf(&buf[index], "\n"); 4317 - return strlen(buf); 4318 - } 4319 - 4320 - /* 4321 - * Sysfs attribute to control the statistical data collection. 4322 - */ 4323 - static DEVICE_ATTR_RW(lpfc_stat_data_ctrl); 4324 - 4325 - /* 4326 - * lpfc_drvr_stat_data: sysfs attr to get driver statistical data. 4327 - */ 4328 - 4329 - /* 4330 - * Each Bucket takes 11 characters and 1 new line + 17 bytes WWN 4331 - * for each target. 4332 - */ 4333 - #define STAT_DATA_SIZE_PER_TARGET(NUM_BUCKETS) ((NUM_BUCKETS) * 11 + 18) 4334 - #define MAX_STAT_DATA_SIZE_PER_TARGET \ 4335 - STAT_DATA_SIZE_PER_TARGET(LPFC_MAX_BUCKET_COUNT) 4336 - 4337 - 4338 - /** 4339 - * sysfs_drvr_stat_data_read - Read function for lpfc_drvr_stat_data attribute 4340 - * @filp: sysfs file 4341 - * @kobj: Pointer to the kernel object 4342 - * @bin_attr: Attribute object 4343 - * @buf: Buffer pointer 4344 - * @off: File offset 4345 - * @count: Buffer size 4346 - * 4347 - * This function is the read call back function for lpfc_drvr_stat_data 4348 - * sysfs file. This function export the statistical data to user 4349 - * applications. 4350 - **/ 4351 - static ssize_t 4352 - sysfs_drvr_stat_data_read(struct file *filp, struct kobject *kobj, 4353 - struct bin_attribute *bin_attr, 4354 - char *buf, loff_t off, size_t count) 4355 - { 4356 - struct device *dev = container_of(kobj, struct device, 4357 - kobj); 4358 - struct Scsi_Host *shost = class_to_shost(dev); 4359 - struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; 4360 - struct lpfc_hba *phba = vport->phba; 4361 - int i = 0, index = 0; 4362 - unsigned long nport_index; 4363 - struct lpfc_nodelist *ndlp = NULL; 4364 - nport_index = (unsigned long)off / 4365 - MAX_STAT_DATA_SIZE_PER_TARGET; 4366 - 4367 - if (!vport->stat_data_enabled || vport->stat_data_blocked 4368 - || (phba->bucket_type == LPFC_NO_BUCKET)) 4369 - return 0; 4370 - 4371 - spin_lock_irq(shost->host_lock); 4372 - list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) { 4373 - if (!ndlp->lat_data) 4374 - continue; 4375 - 4376 - if (nport_index > 0) { 4377 - nport_index--; 4378 - continue; 4379 - } 4380 - 4381 - if ((index + MAX_STAT_DATA_SIZE_PER_TARGET) 4382 - > count) 4383 - break; 4384 - 4385 - if (!ndlp->lat_data) 4386 - continue; 4387 - 4388 - /* Print the WWN */ 4389 - sprintf(&buf[index], "%02x%02x%02x%02x%02x%02x%02x%02x:", 4390 - ndlp->nlp_portname.u.wwn[0], 4391 - ndlp->nlp_portname.u.wwn[1], 4392 - ndlp->nlp_portname.u.wwn[2], 4393 - ndlp->nlp_portname.u.wwn[3], 4394 - ndlp->nlp_portname.u.wwn[4], 4395 - ndlp->nlp_portname.u.wwn[5], 4396 - ndlp->nlp_portname.u.wwn[6], 4397 - ndlp->nlp_portname.u.wwn[7]); 4398 - 4399 - index = strlen(buf); 4400 - 4401 - for (i = 0; i < LPFC_MAX_BUCKET_COUNT; i++) { 4402 - sprintf(&buf[index], "%010u,", 4403 - ndlp->lat_data[i].cmd_count); 4404 - index = strlen(buf); 4405 - } 4406 - sprintf(&buf[index], "\n"); 4407 - index = strlen(buf); 4408 - } 4409 - spin_unlock_irq(shost->host_lock); 4410 - return index; 4411 - } 4412 - 4413 - static struct bin_attribute sysfs_drvr_stat_data_attr = { 4414 - .attr = { 4415 - .name = "lpfc_drvr_stat_data", 4416 - .mode = S_IRUSR, 4417 - }, 4418 - .size = LPFC_MAX_TARGET * MAX_STAT_DATA_SIZE_PER_TARGET, 4419 - .read = sysfs_drvr_stat_data_read, 4420 - .write = NULL, 4421 - }; 4422 - 4423 4096 /* 4424 4097 # lpfc_link_speed: Link speed selection for initializing the Fibre Channel 4425 4098 # connection. ··· 5946 6273 &dev_attr_lpfc_xlane_priority.attr, 5947 6274 &dev_attr_lpfc_sg_seg_cnt.attr, 5948 6275 &dev_attr_lpfc_max_scsicmpl_time.attr, 5949 - &dev_attr_lpfc_stat_data_ctrl.attr, 5950 6276 &dev_attr_lpfc_aer_support.attr, 5951 6277 &dev_attr_lpfc_aer_state_cleanup.attr, 5952 6278 &dev_attr_lpfc_sriov_nr_virtfn.attr, ··· 6004 6332 &dev_attr_npiv_info.attr, 6005 6333 &dev_attr_lpfc_enable_da_id.attr, 6006 6334 &dev_attr_lpfc_max_scsicmpl_time.attr, 6007 - &dev_attr_lpfc_stat_data_ctrl.attr, 6008 6335 &dev_attr_lpfc_static_vport.attr, 6009 6336 &dev_attr_cmf_info.attr, 6010 6337 NULL, ··· 6216 6545 struct Scsi_Host *shost = lpfc_shost_from_vport(vport); 6217 6546 int error; 6218 6547 6219 - error = sysfs_create_bin_file(&shost->shost_dev.kobj, 6220 - &sysfs_drvr_stat_data_attr); 6221 - 6222 6548 /* Virtual ports do not need ctrl_reg and mbox */ 6223 - if (error || vport->port_type == LPFC_NPIV_PORT) 6224 - goto out; 6549 + if (vport->port_type == LPFC_NPIV_PORT) 6550 + return 0; 6225 6551 6226 6552 error = sysfs_create_bin_file(&shost->shost_dev.kobj, 6227 6553 &sysfs_ctlreg_attr); 6228 6554 if (error) 6229 - goto out_remove_stat_attr; 6555 + goto out; 6230 6556 6231 6557 error = sysfs_create_bin_file(&shost->shost_dev.kobj, 6232 6558 &sysfs_mbox_attr); ··· 6233 6565 return 0; 6234 6566 out_remove_ctlreg_attr: 6235 6567 sysfs_remove_bin_file(&shost->shost_dev.kobj, &sysfs_ctlreg_attr); 6236 - out_remove_stat_attr: 6237 - sysfs_remove_bin_file(&shost->shost_dev.kobj, 6238 - &sysfs_drvr_stat_data_attr); 6239 6568 out: 6240 6569 return error; 6241 6570 } ··· 6245 6580 lpfc_free_sysfs_attr(struct lpfc_vport *vport) 6246 6581 { 6247 6582 struct Scsi_Host *shost = lpfc_shost_from_vport(vport); 6248 - sysfs_remove_bin_file(&shost->shost_dev.kobj, 6249 - &sysfs_drvr_stat_data_attr); 6583 + 6250 6584 /* Virtual ports do not need ctrl_reg and mbox */ 6251 6585 if (vport->port_type == LPFC_NPIV_PORT) 6252 6586 return;
+1 -4
drivers/scsi/lpfc/lpfc_bsg.c
··· 1977 1977 static int 1978 1978 lpfc_sli4_diag_fcport_reg_setup(struct lpfc_hba *phba) 1979 1979 { 1980 - int rc; 1981 - 1982 1980 if (phba->pport->fc_flag & FC_VFI_REGISTERED) { 1983 1981 lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC, 1984 1982 "3136 Port still had vfi registered: " ··· 1986 1988 phba->vpi_ids[phba->pport->vpi]); 1987 1989 return -EINVAL; 1988 1990 } 1989 - rc = lpfc_issue_reg_vfi(phba->pport); 1990 - return rc; 1991 + return lpfc_issue_reg_vfi(phba->pport); 1991 1992 } 1992 1993 1993 1994 /**
+10
drivers/scsi/lpfc/lpfc_crtn.h
··· 78 78 void lpfc_free_iocb_list(struct lpfc_hba *phba); 79 79 int lpfc_post_rq_buffer(struct lpfc_hba *phba, struct lpfc_queue *hrq, 80 80 struct lpfc_queue *drq, int count, int idx); 81 + int lpfc_read_lds_params(struct lpfc_hba *phba); 81 82 uint32_t lpfc_calc_cmf_latency(struct lpfc_hba *phba); 82 83 void lpfc_cmf_signal_init(struct lpfc_hba *phba); 83 84 void lpfc_cmf_start(struct lpfc_hba *phba); ··· 93 92 void lpfc_cgn_update_stat(struct lpfc_hba *phba, uint32_t dtag); 94 93 void lpfc_unblock_requests(struct lpfc_hba *phba); 95 94 void lpfc_block_requests(struct lpfc_hba *phba); 95 + int lpfc_rx_monitor_create_ring(struct lpfc_rx_info_monitor *rx_monitor, 96 + u32 entries); 97 + void lpfc_rx_monitor_destroy_ring(struct lpfc_rx_info_monitor *rx_monitor); 98 + void lpfc_rx_monitor_record(struct lpfc_rx_info_monitor *rx_monitor, 99 + struct rx_info_entry *entry); 100 + u32 lpfc_rx_monitor_report(struct lpfc_hba *phba, 101 + struct lpfc_rx_info_monitor *rx_monitor, char *buf, 102 + u32 buf_len, u32 max_read_entries); 96 103 97 104 void lpfc_mbx_cmpl_local_config_link(struct lpfc_hba *, LPFC_MBOXQ_t *); 98 105 void lpfc_mbx_cmpl_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *); ··· 463 454 extern const struct attribute_group *lpfc_vport_groups[]; 464 455 extern struct scsi_host_template lpfc_template; 465 456 extern struct scsi_host_template lpfc_template_nvme; 457 + extern struct scsi_host_template lpfc_vport_template; 466 458 extern struct fc_function_template lpfc_transport_functions; 467 459 extern struct fc_function_template lpfc_vport_transport_functions; 468 460
+388 -724
drivers/scsi/lpfc/lpfc_ct.c
··· 1509 1509 struct lpfc_sli_ct_request *CTrsp; 1510 1510 int did; 1511 1511 struct lpfc_nodelist *ndlp = NULL; 1512 - struct lpfc_nodelist *ns_ndlp = NULL; 1512 + struct lpfc_nodelist *ns_ndlp = cmdiocb->ndlp; 1513 1513 uint32_t fc4_data_0, fc4_data_1; 1514 1514 u32 ulp_status = get_job_ulpstatus(phba, rspiocb); 1515 1515 u32 ulp_word4 = get_job_word4(phba, rspiocb); ··· 1522 1522 ulp_status, ulp_word4, did); 1523 1523 1524 1524 /* Ignore response if link flipped after this request was made */ 1525 - if ((uint32_t) cmdiocb->event_tag != phba->fc_eventTag) { 1525 + if ((uint32_t)cmdiocb->event_tag != phba->fc_eventTag) { 1526 1526 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, 1527 1527 "9046 Event tag mismatch. Ignoring NS rsp\n"); 1528 1528 goto out; 1529 1529 } 1530 - 1531 - /* Preserve the nameserver node to release the reference. */ 1532 - ns_ndlp = cmdiocb->ndlp; 1533 1530 1534 1531 if (ulp_status == IOSTAT_SUCCESS) { 1535 1532 /* Good status, continue checking */ ··· 2501 2504 } 2502 2505 } 2503 2506 2504 - /* Routines for all individual HBA attributes */ 2505 - static int 2506 - lpfc_fdmi_hba_attr_wwnn(struct lpfc_vport *vport, struct lpfc_fdmi_attr_def *ad) 2507 + static inline int 2508 + lpfc_fdmi_set_attr_u32(void *attr, uint16_t attrtype, uint32_t attrval) 2507 2509 { 2508 - struct lpfc_fdmi_attr_entry *ae; 2509 - uint32_t size; 2510 + struct lpfc_fdmi_attr_u32 *ae = attr; 2511 + int size = sizeof(*ae); 2510 2512 2511 - ae = &ad->AttrValue; 2512 - memset(ae, 0, sizeof(*ae)); 2513 + ae->type = cpu_to_be16(attrtype); 2514 + ae->len = cpu_to_be16(size); 2515 + ae->value_u32 = cpu_to_be32(attrval); 2513 2516 2514 - memcpy(&ae->un.AttrWWN, &vport->fc_sparam.nodeName, 2515 - sizeof(struct lpfc_name)); 2516 - size = FOURBYTES + sizeof(struct lpfc_name); 2517 - ad->AttrLen = cpu_to_be16(size); 2518 - ad->AttrType = cpu_to_be16(RHBA_NODENAME); 2519 2517 return size; 2520 2518 } 2521 - static int 2522 - lpfc_fdmi_hba_attr_manufacturer(struct lpfc_vport *vport, 2523 - struct lpfc_fdmi_attr_def *ad) 2519 + 2520 + static inline int 2521 + lpfc_fdmi_set_attr_wwn(void *attr, uint16_t attrtype, struct lpfc_name *wwn) 2524 2522 { 2525 - struct lpfc_fdmi_attr_entry *ae; 2526 - uint32_t len, size; 2523 + struct lpfc_fdmi_attr_wwn *ae = attr; 2524 + int size = sizeof(*ae); 2527 2525 2528 - ae = &ad->AttrValue; 2529 - memset(ae, 0, sizeof(*ae)); 2526 + ae->type = cpu_to_be16(attrtype); 2527 + ae->len = cpu_to_be16(size); 2528 + /* WWN's assumed to be bytestreams - Big Endian presentation */ 2529 + memcpy(ae->name, wwn, 2530 + min_t(size_t, sizeof(struct lpfc_name), sizeof(__be64))); 2530 2531 2532 + return size; 2533 + } 2534 + 2535 + static inline int 2536 + lpfc_fdmi_set_attr_fullwwn(void *attr, uint16_t attrtype, 2537 + struct lpfc_name *wwnn, struct lpfc_name *wwpn) 2538 + { 2539 + struct lpfc_fdmi_attr_fullwwn *ae = attr; 2540 + u8 *nname = ae->nname; 2541 + u8 *pname = ae->pname; 2542 + int size = sizeof(*ae); 2543 + 2544 + ae->type = cpu_to_be16(attrtype); 2545 + ae->len = cpu_to_be16(size); 2546 + /* WWN's assumed to be bytestreams - Big Endian presentation */ 2547 + memcpy(nname, wwnn, 2548 + min_t(size_t, sizeof(struct lpfc_name), sizeof(__be64))); 2549 + memcpy(pname, wwpn, 2550 + min_t(size_t, sizeof(struct lpfc_name), sizeof(__be64))); 2551 + 2552 + return size; 2553 + } 2554 + 2555 + static inline int 2556 + lpfc_fdmi_set_attr_string(void *attr, uint16_t attrtype, char *attrstring) 2557 + { 2558 + struct lpfc_fdmi_attr_string *ae = attr; 2559 + int len, size; 2560 + 2561 + /* 2562 + * We are trusting the caller that if a fdmi string field 2563 + * is capped at 64 bytes, the caller passes in a string of 2564 + * 64 bytes or less. 2565 + */ 2566 + 2567 + strncpy(ae->value_string, attrstring, sizeof(ae->value_string)); 2568 + len = strnlen(ae->value_string, sizeof(ae->value_string)); 2569 + /* round string length to a 32bit boundary. Ensure there's a NULL */ 2570 + len += (len & 3) ? (4 - (len & 3)) : 4; 2571 + /* size is Type/Len (4 bytes) plus string length */ 2572 + size = FOURBYTES + len; 2573 + 2574 + ae->type = cpu_to_be16(attrtype); 2575 + ae->len = cpu_to_be16(size); 2576 + 2577 + return size; 2578 + } 2579 + 2580 + /* Bitfields for FC4 Types that can be reported */ 2581 + #define ATTR_FC4_CT 0x00000001 2582 + #define ATTR_FC4_FCP 0x00000002 2583 + #define ATTR_FC4_NVME 0x00000004 2584 + 2585 + static inline int 2586 + lpfc_fdmi_set_attr_fc4types(void *attr, uint16_t attrtype, uint32_t typemask) 2587 + { 2588 + struct lpfc_fdmi_attr_fc4types *ae = attr; 2589 + int size = sizeof(*ae); 2590 + 2591 + ae->type = cpu_to_be16(attrtype); 2592 + ae->len = cpu_to_be16(size); 2593 + 2594 + if (typemask & ATTR_FC4_FCP) 2595 + ae->value_types[2] = 0x01; /* Type 0x8 - FCP */ 2596 + 2597 + if (typemask & ATTR_FC4_CT) 2598 + ae->value_types[7] = 0x01; /* Type 0x20 - CT */ 2599 + 2600 + if (typemask & ATTR_FC4_NVME) 2601 + ae->value_types[6] = 0x01; /* Type 0x28 - NVME */ 2602 + 2603 + return size; 2604 + } 2605 + 2606 + /* Routines for all individual HBA attributes */ 2607 + static int 2608 + lpfc_fdmi_hba_attr_wwnn(struct lpfc_vport *vport, void *attr) 2609 + { 2610 + return lpfc_fdmi_set_attr_wwn(attr, RHBA_NODENAME, 2611 + &vport->fc_sparam.nodeName); 2612 + } 2613 + 2614 + static int 2615 + lpfc_fdmi_hba_attr_manufacturer(struct lpfc_vport *vport, void *attr) 2616 + { 2531 2617 /* This string MUST be consistent with other FC platforms 2532 2618 * supported by Broadcom. 2533 2619 */ 2534 - strncpy(ae->un.AttrString, 2535 - "Emulex Corporation", 2536 - sizeof(ae->un.AttrString)); 2537 - len = strnlen(ae->un.AttrString, 2538 - sizeof(ae->un.AttrString)); 2539 - len += (len & 3) ? (4 - (len & 3)) : 4; 2540 - size = FOURBYTES + len; 2541 - ad->AttrLen = cpu_to_be16(size); 2542 - ad->AttrType = cpu_to_be16(RHBA_MANUFACTURER); 2543 - return size; 2620 + return lpfc_fdmi_set_attr_string(attr, RHBA_MANUFACTURER, 2621 + "Emulex Corporation"); 2544 2622 } 2545 2623 2546 2624 static int 2547 - lpfc_fdmi_hba_attr_sn(struct lpfc_vport *vport, struct lpfc_fdmi_attr_def *ad) 2625 + lpfc_fdmi_hba_attr_sn(struct lpfc_vport *vport, void *attr) 2548 2626 { 2549 2627 struct lpfc_hba *phba = vport->phba; 2550 - struct lpfc_fdmi_attr_entry *ae; 2551 - uint32_t len, size; 2552 2628 2553 - ae = &ad->AttrValue; 2554 - memset(ae, 0, sizeof(*ae)); 2555 - 2556 - strncpy(ae->un.AttrString, phba->SerialNumber, 2557 - sizeof(ae->un.AttrString)); 2558 - len = strnlen(ae->un.AttrString, 2559 - sizeof(ae->un.AttrString)); 2560 - len += (len & 3) ? (4 - (len & 3)) : 4; 2561 - size = FOURBYTES + len; 2562 - ad->AttrLen = cpu_to_be16(size); 2563 - ad->AttrType = cpu_to_be16(RHBA_SERIAL_NUMBER); 2564 - return size; 2629 + return lpfc_fdmi_set_attr_string(attr, RHBA_SERIAL_NUMBER, 2630 + phba->SerialNumber); 2565 2631 } 2566 2632 2567 2633 static int 2568 - lpfc_fdmi_hba_attr_model(struct lpfc_vport *vport, 2569 - struct lpfc_fdmi_attr_def *ad) 2634 + lpfc_fdmi_hba_attr_model(struct lpfc_vport *vport, void *attr) 2570 2635 { 2571 2636 struct lpfc_hba *phba = vport->phba; 2572 - struct lpfc_fdmi_attr_entry *ae; 2573 - uint32_t len, size; 2574 2637 2575 - ae = &ad->AttrValue; 2576 - memset(ae, 0, sizeof(*ae)); 2577 - 2578 - strncpy(ae->un.AttrString, phba->ModelName, 2579 - sizeof(ae->un.AttrString)); 2580 - len = strnlen(ae->un.AttrString, sizeof(ae->un.AttrString)); 2581 - len += (len & 3) ? (4 - (len & 3)) : 4; 2582 - size = FOURBYTES + len; 2583 - ad->AttrLen = cpu_to_be16(size); 2584 - ad->AttrType = cpu_to_be16(RHBA_MODEL); 2585 - return size; 2638 + return lpfc_fdmi_set_attr_string(attr, RHBA_MODEL, 2639 + phba->ModelName); 2586 2640 } 2587 2641 2588 2642 static int 2589 - lpfc_fdmi_hba_attr_description(struct lpfc_vport *vport, 2590 - struct lpfc_fdmi_attr_def *ad) 2643 + lpfc_fdmi_hba_attr_description(struct lpfc_vport *vport, void *attr) 2591 2644 { 2592 2645 struct lpfc_hba *phba = vport->phba; 2593 - struct lpfc_fdmi_attr_entry *ae; 2594 - uint32_t len, size; 2595 2646 2596 - ae = &ad->AttrValue; 2597 - memset(ae, 0, sizeof(*ae)); 2598 - 2599 - strncpy(ae->un.AttrString, phba->ModelDesc, 2600 - sizeof(ae->un.AttrString)); 2601 - len = strnlen(ae->un.AttrString, 2602 - sizeof(ae->un.AttrString)); 2603 - len += (len & 3) ? (4 - (len & 3)) : 4; 2604 - size = FOURBYTES + len; 2605 - ad->AttrLen = cpu_to_be16(size); 2606 - ad->AttrType = cpu_to_be16(RHBA_MODEL_DESCRIPTION); 2607 - return size; 2647 + return lpfc_fdmi_set_attr_string(attr, RHBA_MODEL_DESCRIPTION, 2648 + phba->ModelDesc); 2608 2649 } 2609 2650 2610 2651 static int 2611 - lpfc_fdmi_hba_attr_hdw_ver(struct lpfc_vport *vport, 2612 - struct lpfc_fdmi_attr_def *ad) 2652 + lpfc_fdmi_hba_attr_hdw_ver(struct lpfc_vport *vport, void *attr) 2613 2653 { 2614 2654 struct lpfc_hba *phba = vport->phba; 2615 2655 lpfc_vpd_t *vp = &phba->vpd; 2616 - struct lpfc_fdmi_attr_entry *ae; 2617 - uint32_t i, j, incr, size; 2656 + char buf[16] = { 0 }; 2618 2657 2619 - ae = &ad->AttrValue; 2620 - memset(ae, 0, sizeof(*ae)); 2658 + snprintf(buf, sizeof(buf), "%08x", vp->rev.biuRev); 2621 2659 2622 - /* Convert JEDEC ID to ascii for hardware version */ 2623 - incr = vp->rev.biuRev; 2624 - for (i = 0; i < 8; i++) { 2625 - j = (incr & 0xf); 2626 - if (j <= 9) 2627 - ae->un.AttrString[7 - i] = 2628 - (char)((uint8_t) 0x30 + 2629 - (uint8_t) j); 2630 - else 2631 - ae->un.AttrString[7 - i] = 2632 - (char)((uint8_t) 0x61 + 2633 - (uint8_t) (j - 10)); 2634 - incr = (incr >> 4); 2660 + return lpfc_fdmi_set_attr_string(attr, RHBA_HARDWARE_VERSION, buf); 2661 + } 2662 + 2663 + static int 2664 + lpfc_fdmi_hba_attr_drvr_ver(struct lpfc_vport *vport, void *attr) 2665 + { 2666 + return lpfc_fdmi_set_attr_string(attr, RHBA_DRIVER_VERSION, 2667 + lpfc_release_version); 2668 + } 2669 + 2670 + static int 2671 + lpfc_fdmi_hba_attr_rom_ver(struct lpfc_vport *vport, void *attr) 2672 + { 2673 + struct lpfc_hba *phba = vport->phba; 2674 + char buf[64] = { 0 }; 2675 + 2676 + if (phba->sli_rev == LPFC_SLI_REV4) { 2677 + lpfc_decode_firmware_rev(phba, buf, 1); 2678 + 2679 + return lpfc_fdmi_set_attr_string(attr, RHBA_OPTION_ROM_VERSION, 2680 + buf); 2635 2681 } 2636 - size = FOURBYTES + 8; 2637 - ad->AttrLen = cpu_to_be16(size); 2638 - ad->AttrType = cpu_to_be16(RHBA_HARDWARE_VERSION); 2639 - return size; 2682 + 2683 + return lpfc_fdmi_set_attr_string(attr, RHBA_OPTION_ROM_VERSION, 2684 + phba->OptionROMVersion); 2640 2685 } 2641 2686 2642 2687 static int 2643 - lpfc_fdmi_hba_attr_drvr_ver(struct lpfc_vport *vport, 2644 - struct lpfc_fdmi_attr_def *ad) 2645 - { 2646 - struct lpfc_fdmi_attr_entry *ae; 2647 - uint32_t len, size; 2648 - 2649 - ae = &ad->AttrValue; 2650 - memset(ae, 0, sizeof(*ae)); 2651 - 2652 - strncpy(ae->un.AttrString, lpfc_release_version, 2653 - sizeof(ae->un.AttrString)); 2654 - len = strnlen(ae->un.AttrString, 2655 - sizeof(ae->un.AttrString)); 2656 - len += (len & 3) ? (4 - (len & 3)) : 4; 2657 - size = FOURBYTES + len; 2658 - ad->AttrLen = cpu_to_be16(size); 2659 - ad->AttrType = cpu_to_be16(RHBA_DRIVER_VERSION); 2660 - return size; 2661 - } 2662 - 2663 - static int 2664 - lpfc_fdmi_hba_attr_rom_ver(struct lpfc_vport *vport, 2665 - struct lpfc_fdmi_attr_def *ad) 2688 + lpfc_fdmi_hba_attr_fmw_ver(struct lpfc_vport *vport, void *attr) 2666 2689 { 2667 2690 struct lpfc_hba *phba = vport->phba; 2668 - struct lpfc_fdmi_attr_entry *ae; 2669 - uint32_t len, size; 2691 + char buf[64] = { 0 }; 2670 2692 2671 - ae = &ad->AttrValue; 2672 - memset(ae, 0, sizeof(*ae)); 2693 + lpfc_decode_firmware_rev(phba, buf, 1); 2673 2694 2674 - if (phba->sli_rev == LPFC_SLI_REV4) 2675 - lpfc_decode_firmware_rev(phba, ae->un.AttrString, 1); 2676 - else 2677 - strncpy(ae->un.AttrString, phba->OptionROMVersion, 2678 - sizeof(ae->un.AttrString)); 2679 - len = strnlen(ae->un.AttrString, 2680 - sizeof(ae->un.AttrString)); 2681 - len += (len & 3) ? (4 - (len & 3)) : 4; 2682 - size = FOURBYTES + len; 2683 - ad->AttrLen = cpu_to_be16(size); 2684 - ad->AttrType = cpu_to_be16(RHBA_OPTION_ROM_VERSION); 2685 - return size; 2695 + return lpfc_fdmi_set_attr_string(attr, RHBA_FIRMWARE_VERSION, buf); 2686 2696 } 2687 2697 2688 2698 static int 2689 - lpfc_fdmi_hba_attr_fmw_ver(struct lpfc_vport *vport, 2690 - struct lpfc_fdmi_attr_def *ad) 2699 + lpfc_fdmi_hba_attr_os_ver(struct lpfc_vport *vport, void *attr) 2691 2700 { 2692 - struct lpfc_hba *phba = vport->phba; 2693 - struct lpfc_fdmi_attr_entry *ae; 2694 - uint32_t len, size; 2701 + char buf[256] = { 0 }; 2695 2702 2696 - ae = &ad->AttrValue; 2697 - memset(ae, 0, sizeof(*ae)); 2698 - 2699 - lpfc_decode_firmware_rev(phba, ae->un.AttrString, 1); 2700 - len = strnlen(ae->un.AttrString, 2701 - sizeof(ae->un.AttrString)); 2702 - len += (len & 3) ? (4 - (len & 3)) : 4; 2703 - size = FOURBYTES + len; 2704 - ad->AttrLen = cpu_to_be16(size); 2705 - ad->AttrType = cpu_to_be16(RHBA_FIRMWARE_VERSION); 2706 - return size; 2707 - } 2708 - 2709 - static int 2710 - lpfc_fdmi_hba_attr_os_ver(struct lpfc_vport *vport, 2711 - struct lpfc_fdmi_attr_def *ad) 2712 - { 2713 - struct lpfc_fdmi_attr_entry *ae; 2714 - uint32_t len, size; 2715 - 2716 - ae = &ad->AttrValue; 2717 - memset(ae, 0, sizeof(*ae)); 2718 - 2719 - snprintf(ae->un.AttrString, sizeof(ae->un.AttrString), "%s %s %s", 2703 + snprintf(buf, sizeof(buf), "%s %s %s", 2720 2704 init_utsname()->sysname, 2721 2705 init_utsname()->release, 2722 2706 init_utsname()->version); 2723 2707 2724 - len = strnlen(ae->un.AttrString, sizeof(ae->un.AttrString)); 2725 - len += (len & 3) ? (4 - (len & 3)) : 4; 2726 - size = FOURBYTES + len; 2727 - ad->AttrLen = cpu_to_be16(size); 2728 - ad->AttrType = cpu_to_be16(RHBA_OS_NAME_VERSION); 2729 - return size; 2708 + return lpfc_fdmi_set_attr_string(attr, RHBA_OS_NAME_VERSION, buf); 2730 2709 } 2731 2710 2732 2711 static int 2733 - lpfc_fdmi_hba_attr_ct_len(struct lpfc_vport *vport, 2734 - struct lpfc_fdmi_attr_def *ad) 2712 + lpfc_fdmi_hba_attr_ct_len(struct lpfc_vport *vport, void *attr) 2735 2713 { 2736 - struct lpfc_fdmi_attr_entry *ae; 2737 - uint32_t size; 2738 - 2739 - ae = &ad->AttrValue; 2740 - 2741 - ae->un.AttrInt = cpu_to_be32(LPFC_MAX_CT_SIZE); 2742 - size = FOURBYTES + sizeof(uint32_t); 2743 - ad->AttrLen = cpu_to_be16(size); 2744 - ad->AttrType = cpu_to_be16(RHBA_MAX_CT_PAYLOAD_LEN); 2745 - return size; 2714 + return lpfc_fdmi_set_attr_u32(attr, RHBA_MAX_CT_PAYLOAD_LEN, 2715 + LPFC_MAX_CT_SIZE); 2746 2716 } 2747 2717 2748 2718 static int 2749 - lpfc_fdmi_hba_attr_symbolic_name(struct lpfc_vport *vport, 2750 - struct lpfc_fdmi_attr_def *ad) 2719 + lpfc_fdmi_hba_attr_symbolic_name(struct lpfc_vport *vport, void *attr) 2751 2720 { 2752 - struct lpfc_fdmi_attr_entry *ae; 2753 - uint32_t len, size; 2721 + char buf[256] = { 0 }; 2754 2722 2755 - ae = &ad->AttrValue; 2756 - memset(ae, 0, sizeof(*ae)); 2723 + lpfc_vport_symbolic_node_name(vport, buf, sizeof(buf)); 2757 2724 2758 - len = lpfc_vport_symbolic_node_name(vport, 2759 - ae->un.AttrString, 256); 2760 - len += (len & 3) ? (4 - (len & 3)) : 4; 2761 - size = FOURBYTES + len; 2762 - ad->AttrLen = cpu_to_be16(size); 2763 - ad->AttrType = cpu_to_be16(RHBA_SYM_NODENAME); 2764 - return size; 2725 + return lpfc_fdmi_set_attr_string(attr, RHBA_SYM_NODENAME, buf); 2765 2726 } 2766 2727 2767 2728 static int 2768 - lpfc_fdmi_hba_attr_vendor_info(struct lpfc_vport *vport, 2769 - struct lpfc_fdmi_attr_def *ad) 2729 + lpfc_fdmi_hba_attr_vendor_info(struct lpfc_vport *vport, void *attr) 2770 2730 { 2771 - struct lpfc_fdmi_attr_entry *ae; 2772 - uint32_t size; 2773 - 2774 - ae = &ad->AttrValue; 2775 - 2776 - /* Nothing is defined for this currently */ 2777 - ae->un.AttrInt = cpu_to_be32(0); 2778 - size = FOURBYTES + sizeof(uint32_t); 2779 - ad->AttrLen = cpu_to_be16(size); 2780 - ad->AttrType = cpu_to_be16(RHBA_VENDOR_INFO); 2781 - return size; 2731 + return lpfc_fdmi_set_attr_u32(attr, RHBA_VENDOR_INFO, 0); 2782 2732 } 2783 2733 2784 2734 static int 2785 - lpfc_fdmi_hba_attr_num_ports(struct lpfc_vport *vport, 2786 - struct lpfc_fdmi_attr_def *ad) 2735 + lpfc_fdmi_hba_attr_num_ports(struct lpfc_vport *vport, void *attr) 2787 2736 { 2788 - struct lpfc_fdmi_attr_entry *ae; 2789 - uint32_t size; 2790 - 2791 - ae = &ad->AttrValue; 2792 - 2793 2737 /* Each driver instance corresponds to a single port */ 2794 - ae->un.AttrInt = cpu_to_be32(1); 2795 - size = FOURBYTES + sizeof(uint32_t); 2796 - ad->AttrLen = cpu_to_be16(size); 2797 - ad->AttrType = cpu_to_be16(RHBA_NUM_PORTS); 2798 - return size; 2738 + return lpfc_fdmi_set_attr_u32(attr, RHBA_NUM_PORTS, 1); 2799 2739 } 2800 2740 2801 2741 static int 2802 - lpfc_fdmi_hba_attr_fabric_wwnn(struct lpfc_vport *vport, 2803 - struct lpfc_fdmi_attr_def *ad) 2742 + lpfc_fdmi_hba_attr_fabric_wwnn(struct lpfc_vport *vport, void *attr) 2804 2743 { 2805 - struct lpfc_fdmi_attr_entry *ae; 2806 - uint32_t size; 2807 - 2808 - ae = &ad->AttrValue; 2809 - memset(ae, 0, sizeof(*ae)); 2810 - 2811 - memcpy(&ae->un.AttrWWN, &vport->fabric_nodename, 2812 - sizeof(struct lpfc_name)); 2813 - size = FOURBYTES + sizeof(struct lpfc_name); 2814 - ad->AttrLen = cpu_to_be16(size); 2815 - ad->AttrType = cpu_to_be16(RHBA_FABRIC_WWNN); 2816 - return size; 2744 + return lpfc_fdmi_set_attr_wwn(attr, RHBA_FABRIC_WWNN, 2745 + &vport->fabric_nodename); 2817 2746 } 2818 2747 2819 2748 static int 2820 - lpfc_fdmi_hba_attr_bios_ver(struct lpfc_vport *vport, 2821 - struct lpfc_fdmi_attr_def *ad) 2749 + lpfc_fdmi_hba_attr_bios_ver(struct lpfc_vport *vport, void *attr) 2822 2750 { 2823 2751 struct lpfc_hba *phba = vport->phba; 2824 - struct lpfc_fdmi_attr_entry *ae; 2825 - uint32_t len, size; 2826 2752 2827 - ae = &ad->AttrValue; 2828 - memset(ae, 0, sizeof(*ae)); 2829 - 2830 - strlcat(ae->un.AttrString, phba->BIOSVersion, 2831 - sizeof(ae->un.AttrString)); 2832 - len = strnlen(ae->un.AttrString, 2833 - sizeof(ae->un.AttrString)); 2834 - len += (len & 3) ? (4 - (len & 3)) : 4; 2835 - size = FOURBYTES + len; 2836 - ad->AttrLen = cpu_to_be16(size); 2837 - ad->AttrType = cpu_to_be16(RHBA_BIOS_VERSION); 2838 - return size; 2753 + return lpfc_fdmi_set_attr_string(attr, RHBA_BIOS_VERSION, 2754 + phba->BIOSVersion); 2839 2755 } 2840 2756 2841 2757 static int 2842 - lpfc_fdmi_hba_attr_bios_state(struct lpfc_vport *vport, 2843 - struct lpfc_fdmi_attr_def *ad) 2758 + lpfc_fdmi_hba_attr_bios_state(struct lpfc_vport *vport, void *attr) 2844 2759 { 2845 - struct lpfc_fdmi_attr_entry *ae; 2846 - uint32_t size; 2847 - 2848 - ae = &ad->AttrValue; 2849 - 2850 2760 /* Driver doesn't have access to this information */ 2851 - ae->un.AttrInt = cpu_to_be32(0); 2852 - size = FOURBYTES + sizeof(uint32_t); 2853 - ad->AttrLen = cpu_to_be16(size); 2854 - ad->AttrType = cpu_to_be16(RHBA_BIOS_STATE); 2855 - return size; 2761 + return lpfc_fdmi_set_attr_u32(attr, RHBA_BIOS_STATE, 0); 2856 2762 } 2857 2763 2858 2764 static int 2859 - lpfc_fdmi_hba_attr_vendor_id(struct lpfc_vport *vport, 2860 - struct lpfc_fdmi_attr_def *ad) 2765 + lpfc_fdmi_hba_attr_vendor_id(struct lpfc_vport *vport, void *attr) 2861 2766 { 2862 - struct lpfc_fdmi_attr_entry *ae; 2863 - uint32_t len, size; 2864 - 2865 - ae = &ad->AttrValue; 2866 - memset(ae, 0, sizeof(*ae)); 2867 - 2868 - strncpy(ae->un.AttrString, "EMULEX", 2869 - sizeof(ae->un.AttrString)); 2870 - len = strnlen(ae->un.AttrString, 2871 - sizeof(ae->un.AttrString)); 2872 - len += (len & 3) ? (4 - (len & 3)) : 4; 2873 - size = FOURBYTES + len; 2874 - ad->AttrLen = cpu_to_be16(size); 2875 - ad->AttrType = cpu_to_be16(RHBA_VENDOR_ID); 2876 - return size; 2767 + return lpfc_fdmi_set_attr_string(attr, RHBA_VENDOR_ID, "EMULEX"); 2877 2768 } 2878 2769 2879 - /* Routines for all individual PORT attributes */ 2770 + /* 2771 + * Routines for all individual PORT attributes 2772 + */ 2773 + 2880 2774 static int 2881 - lpfc_fdmi_port_attr_fc4type(struct lpfc_vport *vport, 2882 - struct lpfc_fdmi_attr_def *ad) 2775 + lpfc_fdmi_port_attr_fc4type(struct lpfc_vport *vport, void *attr) 2883 2776 { 2884 2777 struct lpfc_hba *phba = vport->phba; 2885 - struct lpfc_fdmi_attr_entry *ae; 2886 - uint32_t size; 2778 + u32 fc4types; 2887 2779 2888 - ae = &ad->AttrValue; 2889 - memset(ae, 0, sizeof(*ae)); 2890 - 2891 - ae->un.AttrTypes[2] = 0x01; /* Type 0x8 - FCP */ 2892 - ae->un.AttrTypes[7] = 0x01; /* Type 0x20 - CT */ 2780 + fc4types = (ATTR_FC4_CT | ATTR_FC4_FCP); 2893 2781 2894 2782 /* Check to see if Firmware supports NVME and on physical port */ 2895 2783 if ((phba->sli_rev == LPFC_SLI_REV4) && (vport == phba->pport) && 2896 2784 phba->sli4_hba.pc_sli4_params.nvme) 2897 - ae->un.AttrTypes[6] = 0x01; /* Type 0x28 - NVME */ 2785 + fc4types |= ATTR_FC4_NVME; 2898 2786 2899 - size = FOURBYTES + 32; 2900 - ad->AttrLen = cpu_to_be16(size); 2901 - ad->AttrType = cpu_to_be16(RPRT_SUPPORTED_FC4_TYPES); 2902 - return size; 2787 + return lpfc_fdmi_set_attr_fc4types(attr, RPRT_SUPPORTED_FC4_TYPES, 2788 + fc4types); 2903 2789 } 2904 2790 2905 2791 static int 2906 - lpfc_fdmi_port_attr_support_speed(struct lpfc_vport *vport, 2907 - struct lpfc_fdmi_attr_def *ad) 2792 + lpfc_fdmi_port_attr_support_speed(struct lpfc_vport *vport, void *attr) 2908 2793 { 2909 - struct lpfc_hba *phba = vport->phba; 2910 - struct lpfc_fdmi_attr_entry *ae; 2911 - uint32_t size; 2794 + struct lpfc_hba *phba = vport->phba; 2795 + u32 speeds = 0; 2912 2796 u32 tcfg; 2913 2797 u8 i, cnt; 2914 2798 2915 - ae = &ad->AttrValue; 2916 - 2917 - ae->un.AttrInt = 0; 2918 2799 if (!(phba->hba_flag & HBA_FCOE_MODE)) { 2919 2800 cnt = 0; 2920 2801 if (phba->sli_rev == LPFC_SLI_REV4) { ··· 2804 2929 2805 2930 if (cnt > 2) { /* 4 lane trunk group */ 2806 2931 if (phba->lmt & LMT_64Gb) 2807 - ae->un.AttrInt |= HBA_PORTSPEED_256GFC; 2932 + speeds |= HBA_PORTSPEED_256GFC; 2808 2933 if (phba->lmt & LMT_32Gb) 2809 - ae->un.AttrInt |= HBA_PORTSPEED_128GFC; 2934 + speeds |= HBA_PORTSPEED_128GFC; 2810 2935 if (phba->lmt & LMT_16Gb) 2811 - ae->un.AttrInt |= HBA_PORTSPEED_64GFC; 2936 + speeds |= HBA_PORTSPEED_64GFC; 2812 2937 } else if (cnt) { /* 2 lane trunk group */ 2813 2938 if (phba->lmt & LMT_128Gb) 2814 - ae->un.AttrInt |= HBA_PORTSPEED_256GFC; 2939 + speeds |= HBA_PORTSPEED_256GFC; 2815 2940 if (phba->lmt & LMT_64Gb) 2816 - ae->un.AttrInt |= HBA_PORTSPEED_128GFC; 2941 + speeds |= HBA_PORTSPEED_128GFC; 2817 2942 if (phba->lmt & LMT_32Gb) 2818 - ae->un.AttrInt |= HBA_PORTSPEED_64GFC; 2943 + speeds |= HBA_PORTSPEED_64GFC; 2819 2944 if (phba->lmt & LMT_16Gb) 2820 - ae->un.AttrInt |= HBA_PORTSPEED_32GFC; 2945 + speeds |= HBA_PORTSPEED_32GFC; 2821 2946 } else { 2822 2947 if (phba->lmt & LMT_256Gb) 2823 - ae->un.AttrInt |= HBA_PORTSPEED_256GFC; 2948 + speeds |= HBA_PORTSPEED_256GFC; 2824 2949 if (phba->lmt & LMT_128Gb) 2825 - ae->un.AttrInt |= HBA_PORTSPEED_128GFC; 2950 + speeds |= HBA_PORTSPEED_128GFC; 2826 2951 if (phba->lmt & LMT_64Gb) 2827 - ae->un.AttrInt |= HBA_PORTSPEED_64GFC; 2952 + speeds |= HBA_PORTSPEED_64GFC; 2828 2953 if (phba->lmt & LMT_32Gb) 2829 - ae->un.AttrInt |= HBA_PORTSPEED_32GFC; 2954 + speeds |= HBA_PORTSPEED_32GFC; 2830 2955 if (phba->lmt & LMT_16Gb) 2831 - ae->un.AttrInt |= HBA_PORTSPEED_16GFC; 2956 + speeds |= HBA_PORTSPEED_16GFC; 2832 2957 if (phba->lmt & LMT_10Gb) 2833 - ae->un.AttrInt |= HBA_PORTSPEED_10GFC; 2958 + speeds |= HBA_PORTSPEED_10GFC; 2834 2959 if (phba->lmt & LMT_8Gb) 2835 - ae->un.AttrInt |= HBA_PORTSPEED_8GFC; 2960 + speeds |= HBA_PORTSPEED_8GFC; 2836 2961 if (phba->lmt & LMT_4Gb) 2837 - ae->un.AttrInt |= HBA_PORTSPEED_4GFC; 2962 + speeds |= HBA_PORTSPEED_4GFC; 2838 2963 if (phba->lmt & LMT_2Gb) 2839 - ae->un.AttrInt |= HBA_PORTSPEED_2GFC; 2964 + speeds |= HBA_PORTSPEED_2GFC; 2840 2965 if (phba->lmt & LMT_1Gb) 2841 - ae->un.AttrInt |= HBA_PORTSPEED_1GFC; 2966 + speeds |= HBA_PORTSPEED_1GFC; 2842 2967 } 2843 2968 } else { 2844 2969 /* FCoE links support only one speed */ 2845 2970 switch (phba->fc_linkspeed) { 2846 2971 case LPFC_ASYNC_LINK_SPEED_10GBPS: 2847 - ae->un.AttrInt = HBA_PORTSPEED_10GE; 2972 + speeds = HBA_PORTSPEED_10GE; 2848 2973 break; 2849 2974 case LPFC_ASYNC_LINK_SPEED_25GBPS: 2850 - ae->un.AttrInt = HBA_PORTSPEED_25GE; 2975 + speeds = HBA_PORTSPEED_25GE; 2851 2976 break; 2852 2977 case LPFC_ASYNC_LINK_SPEED_40GBPS: 2853 - ae->un.AttrInt = HBA_PORTSPEED_40GE; 2978 + speeds = HBA_PORTSPEED_40GE; 2854 2979 break; 2855 2980 case LPFC_ASYNC_LINK_SPEED_100GBPS: 2856 - ae->un.AttrInt = HBA_PORTSPEED_100GE; 2981 + speeds = HBA_PORTSPEED_100GE; 2857 2982 break; 2858 2983 } 2859 2984 } 2860 - ae->un.AttrInt = cpu_to_be32(ae->un.AttrInt); 2861 - size = FOURBYTES + sizeof(uint32_t); 2862 - ad->AttrLen = cpu_to_be16(size); 2863 - ad->AttrType = cpu_to_be16(RPRT_SUPPORTED_SPEED); 2864 - return size; 2985 + 2986 + return lpfc_fdmi_set_attr_u32(attr, RPRT_SUPPORTED_SPEED, speeds); 2865 2987 } 2866 2988 2867 2989 static int 2868 - lpfc_fdmi_port_attr_speed(struct lpfc_vport *vport, 2869 - struct lpfc_fdmi_attr_def *ad) 2990 + lpfc_fdmi_port_attr_speed(struct lpfc_vport *vport, void *attr) 2870 2991 { 2871 2992 struct lpfc_hba *phba = vport->phba; 2872 - struct lpfc_fdmi_attr_entry *ae; 2873 - uint32_t size; 2874 - 2875 - ae = &ad->AttrValue; 2993 + u32 speeds = 0; 2876 2994 2877 2995 if (!(phba->hba_flag & HBA_FCOE_MODE)) { 2878 2996 switch (phba->fc_linkspeed) { 2879 2997 case LPFC_LINK_SPEED_1GHZ: 2880 - ae->un.AttrInt = HBA_PORTSPEED_1GFC; 2998 + speeds = HBA_PORTSPEED_1GFC; 2881 2999 break; 2882 3000 case LPFC_LINK_SPEED_2GHZ: 2883 - ae->un.AttrInt = HBA_PORTSPEED_2GFC; 3001 + speeds = HBA_PORTSPEED_2GFC; 2884 3002 break; 2885 3003 case LPFC_LINK_SPEED_4GHZ: 2886 - ae->un.AttrInt = HBA_PORTSPEED_4GFC; 3004 + speeds = HBA_PORTSPEED_4GFC; 2887 3005 break; 2888 3006 case LPFC_LINK_SPEED_8GHZ: 2889 - ae->un.AttrInt = HBA_PORTSPEED_8GFC; 3007 + speeds = HBA_PORTSPEED_8GFC; 2890 3008 break; 2891 3009 case LPFC_LINK_SPEED_10GHZ: 2892 - ae->un.AttrInt = HBA_PORTSPEED_10GFC; 3010 + speeds = HBA_PORTSPEED_10GFC; 2893 3011 break; 2894 3012 case LPFC_LINK_SPEED_16GHZ: 2895 - ae->un.AttrInt = HBA_PORTSPEED_16GFC; 3013 + speeds = HBA_PORTSPEED_16GFC; 2896 3014 break; 2897 3015 case LPFC_LINK_SPEED_32GHZ: 2898 - ae->un.AttrInt = HBA_PORTSPEED_32GFC; 3016 + speeds = HBA_PORTSPEED_32GFC; 2899 3017 break; 2900 3018 case LPFC_LINK_SPEED_64GHZ: 2901 - ae->un.AttrInt = HBA_PORTSPEED_64GFC; 3019 + speeds = HBA_PORTSPEED_64GFC; 2902 3020 break; 2903 3021 case LPFC_LINK_SPEED_128GHZ: 2904 - ae->un.AttrInt = HBA_PORTSPEED_128GFC; 3022 + speeds = HBA_PORTSPEED_128GFC; 2905 3023 break; 2906 3024 case LPFC_LINK_SPEED_256GHZ: 2907 - ae->un.AttrInt = HBA_PORTSPEED_256GFC; 3025 + speeds = HBA_PORTSPEED_256GFC; 2908 3026 break; 2909 3027 default: 2910 - ae->un.AttrInt = HBA_PORTSPEED_UNKNOWN; 3028 + speeds = HBA_PORTSPEED_UNKNOWN; 2911 3029 break; 2912 3030 } 2913 3031 } else { 2914 3032 switch (phba->fc_linkspeed) { 2915 3033 case LPFC_ASYNC_LINK_SPEED_10GBPS: 2916 - ae->un.AttrInt = HBA_PORTSPEED_10GE; 3034 + speeds = HBA_PORTSPEED_10GE; 2917 3035 break; 2918 3036 case LPFC_ASYNC_LINK_SPEED_25GBPS: 2919 - ae->un.AttrInt = HBA_PORTSPEED_25GE; 3037 + speeds = HBA_PORTSPEED_25GE; 2920 3038 break; 2921 3039 case LPFC_ASYNC_LINK_SPEED_40GBPS: 2922 - ae->un.AttrInt = HBA_PORTSPEED_40GE; 3040 + speeds = HBA_PORTSPEED_40GE; 2923 3041 break; 2924 3042 case LPFC_ASYNC_LINK_SPEED_100GBPS: 2925 - ae->un.AttrInt = HBA_PORTSPEED_100GE; 3043 + speeds = HBA_PORTSPEED_100GE; 2926 3044 break; 2927 3045 default: 2928 - ae->un.AttrInt = HBA_PORTSPEED_UNKNOWN; 3046 + speeds = HBA_PORTSPEED_UNKNOWN; 2929 3047 break; 2930 3048 } 2931 3049 } 2932 3050 2933 - ae->un.AttrInt = cpu_to_be32(ae->un.AttrInt); 2934 - size = FOURBYTES + sizeof(uint32_t); 2935 - ad->AttrLen = cpu_to_be16(size); 2936 - ad->AttrType = cpu_to_be16(RPRT_PORT_SPEED); 2937 - return size; 3051 + return lpfc_fdmi_set_attr_u32(attr, RPRT_PORT_SPEED, speeds); 2938 3052 } 2939 3053 2940 3054 static int 2941 - lpfc_fdmi_port_attr_max_frame(struct lpfc_vport *vport, 2942 - struct lpfc_fdmi_attr_def *ad) 3055 + lpfc_fdmi_port_attr_max_frame(struct lpfc_vport *vport, void *attr) 2943 3056 { 2944 - struct serv_parm *hsp; 2945 - struct lpfc_fdmi_attr_entry *ae; 2946 - uint32_t size; 3057 + struct serv_parm *hsp = (struct serv_parm *)&vport->fc_sparam; 2947 3058 2948 - ae = &ad->AttrValue; 2949 - 2950 - hsp = (struct serv_parm *)&vport->fc_sparam; 2951 - ae->un.AttrInt = (((uint32_t) hsp->cmn.bbRcvSizeMsb & 0x0F) << 8) | 2952 - (uint32_t) hsp->cmn.bbRcvSizeLsb; 2953 - ae->un.AttrInt = cpu_to_be32(ae->un.AttrInt); 2954 - size = FOURBYTES + sizeof(uint32_t); 2955 - ad->AttrLen = cpu_to_be16(size); 2956 - ad->AttrType = cpu_to_be16(RPRT_MAX_FRAME_SIZE); 2957 - return size; 3059 + return lpfc_fdmi_set_attr_u32(attr, RPRT_MAX_FRAME_SIZE, 3060 + (((uint32_t)hsp->cmn.bbRcvSizeMsb & 0x0F) << 8) | 3061 + (uint32_t)hsp->cmn.bbRcvSizeLsb); 2958 3062 } 2959 3063 2960 3064 static int 2961 - lpfc_fdmi_port_attr_os_devname(struct lpfc_vport *vport, 2962 - struct lpfc_fdmi_attr_def *ad) 3065 + lpfc_fdmi_port_attr_os_devname(struct lpfc_vport *vport, void *attr) 2963 3066 { 2964 3067 struct Scsi_Host *shost = lpfc_shost_from_vport(vport); 2965 - struct lpfc_fdmi_attr_entry *ae; 2966 - uint32_t len, size; 3068 + char buf[64] = { 0 }; 2967 3069 2968 - ae = &ad->AttrValue; 2969 - memset(ae, 0, sizeof(*ae)); 3070 + snprintf(buf, sizeof(buf), "/sys/class/scsi_host/host%d", 3071 + shost->host_no); 2970 3072 2971 - snprintf(ae->un.AttrString, sizeof(ae->un.AttrString), 2972 - "/sys/class/scsi_host/host%d", shost->host_no); 2973 - len = strnlen((char *)ae->un.AttrString, 2974 - sizeof(ae->un.AttrString)); 2975 - len += (len & 3) ? (4 - (len & 3)) : 4; 2976 - size = FOURBYTES + len; 2977 - ad->AttrLen = cpu_to_be16(size); 2978 - ad->AttrType = cpu_to_be16(RPRT_OS_DEVICE_NAME); 2979 - return size; 3073 + return lpfc_fdmi_set_attr_string(attr, RPRT_OS_DEVICE_NAME, buf); 2980 3074 } 2981 3075 2982 3076 static int 2983 - lpfc_fdmi_port_attr_host_name(struct lpfc_vport *vport, 2984 - struct lpfc_fdmi_attr_def *ad) 3077 + lpfc_fdmi_port_attr_host_name(struct lpfc_vport *vport, void *attr) 2985 3078 { 2986 - struct lpfc_fdmi_attr_entry *ae; 2987 - uint32_t len, size; 3079 + char buf[64] = { 0 }; 2988 3080 2989 - ae = &ad->AttrValue; 2990 - memset(ae, 0, sizeof(*ae)); 3081 + scnprintf(buf, sizeof(buf), "%s", vport->phba->os_host_name); 2991 3082 2992 - scnprintf(ae->un.AttrString, sizeof(ae->un.AttrString), "%s", 2993 - vport->phba->os_host_name); 2994 - 2995 - len = strnlen(ae->un.AttrString, sizeof(ae->un.AttrString)); 2996 - len += (len & 3) ? (4 - (len & 3)) : 4; 2997 - size = FOURBYTES + len; 2998 - ad->AttrLen = cpu_to_be16(size); 2999 - ad->AttrType = cpu_to_be16(RPRT_HOST_NAME); 3000 - return size; 3083 + return lpfc_fdmi_set_attr_string(attr, RPRT_HOST_NAME, buf); 3001 3084 } 3002 3085 3003 3086 static int 3004 - lpfc_fdmi_port_attr_wwnn(struct lpfc_vport *vport, 3005 - struct lpfc_fdmi_attr_def *ad) 3087 + lpfc_fdmi_port_attr_wwnn(struct lpfc_vport *vport, void *attr) 3006 3088 { 3007 - struct lpfc_fdmi_attr_entry *ae; 3008 - uint32_t size; 3009 - 3010 - ae = &ad->AttrValue; 3011 - memset(ae, 0, sizeof(*ae)); 3012 - 3013 - memcpy(&ae->un.AttrWWN, &vport->fc_sparam.nodeName, 3014 - sizeof(struct lpfc_name)); 3015 - size = FOURBYTES + sizeof(struct lpfc_name); 3016 - ad->AttrLen = cpu_to_be16(size); 3017 - ad->AttrType = cpu_to_be16(RPRT_NODENAME); 3018 - return size; 3089 + return lpfc_fdmi_set_attr_wwn(attr, RPRT_NODENAME, 3090 + &vport->fc_sparam.nodeName); 3019 3091 } 3020 3092 3021 3093 static int 3022 - lpfc_fdmi_port_attr_wwpn(struct lpfc_vport *vport, 3023 - struct lpfc_fdmi_attr_def *ad) 3094 + lpfc_fdmi_port_attr_wwpn(struct lpfc_vport *vport, void *attr) 3024 3095 { 3025 - struct lpfc_fdmi_attr_entry *ae; 3026 - uint32_t size; 3027 - 3028 - ae = &ad->AttrValue; 3029 - memset(ae, 0, sizeof(*ae)); 3030 - 3031 - memcpy(&ae->un.AttrWWN, &vport->fc_sparam.portName, 3032 - sizeof(struct lpfc_name)); 3033 - size = FOURBYTES + sizeof(struct lpfc_name); 3034 - ad->AttrLen = cpu_to_be16(size); 3035 - ad->AttrType = cpu_to_be16(RPRT_PORTNAME); 3036 - return size; 3096 + return lpfc_fdmi_set_attr_wwn(attr, RPRT_PORTNAME, 3097 + &vport->fc_sparam.portName); 3037 3098 } 3038 3099 3039 3100 static int 3040 - lpfc_fdmi_port_attr_symbolic_name(struct lpfc_vport *vport, 3041 - struct lpfc_fdmi_attr_def *ad) 3101 + lpfc_fdmi_port_attr_symbolic_name(struct lpfc_vport *vport, void *attr) 3042 3102 { 3043 - struct lpfc_fdmi_attr_entry *ae; 3044 - uint32_t len, size; 3103 + char buf[256] = { 0 }; 3045 3104 3046 - ae = &ad->AttrValue; 3047 - memset(ae, 0, sizeof(*ae)); 3105 + lpfc_vport_symbolic_port_name(vport, buf, sizeof(buf)); 3048 3106 3049 - len = lpfc_vport_symbolic_port_name(vport, ae->un.AttrString, 256); 3050 - len += (len & 3) ? (4 - (len & 3)) : 4; 3051 - size = FOURBYTES + len; 3052 - ad->AttrLen = cpu_to_be16(size); 3053 - ad->AttrType = cpu_to_be16(RPRT_SYM_PORTNAME); 3054 - return size; 3107 + return lpfc_fdmi_set_attr_string(attr, RPRT_SYM_PORTNAME, buf); 3055 3108 } 3056 3109 3057 3110 static int 3058 - lpfc_fdmi_port_attr_port_type(struct lpfc_vport *vport, 3059 - struct lpfc_fdmi_attr_def *ad) 3111 + lpfc_fdmi_port_attr_port_type(struct lpfc_vport *vport, void *attr) 3060 3112 { 3061 3113 struct lpfc_hba *phba = vport->phba; 3062 - struct lpfc_fdmi_attr_entry *ae; 3063 - uint32_t size; 3064 3114 3065 - ae = &ad->AttrValue; 3066 - if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) 3067 - ae->un.AttrInt = cpu_to_be32(LPFC_FDMI_PORTTYPE_NLPORT); 3068 - else 3069 - ae->un.AttrInt = cpu_to_be32(LPFC_FDMI_PORTTYPE_NPORT); 3070 - size = FOURBYTES + sizeof(uint32_t); 3071 - ad->AttrLen = cpu_to_be16(size); 3072 - ad->AttrType = cpu_to_be16(RPRT_PORT_TYPE); 3073 - return size; 3115 + return lpfc_fdmi_set_attr_u32(attr, RPRT_PORT_TYPE, 3116 + (phba->fc_topology == LPFC_TOPOLOGY_LOOP) ? 3117 + LPFC_FDMI_PORTTYPE_NLPORT : 3118 + LPFC_FDMI_PORTTYPE_NPORT); 3074 3119 } 3075 3120 3076 3121 static int 3077 - lpfc_fdmi_port_attr_class(struct lpfc_vport *vport, 3078 - struct lpfc_fdmi_attr_def *ad) 3122 + lpfc_fdmi_port_attr_class(struct lpfc_vport *vport, void *attr) 3079 3123 { 3080 - struct lpfc_fdmi_attr_entry *ae; 3081 - uint32_t size; 3082 - 3083 - ae = &ad->AttrValue; 3084 - ae->un.AttrInt = cpu_to_be32(FC_COS_CLASS2 | FC_COS_CLASS3); 3085 - size = FOURBYTES + sizeof(uint32_t); 3086 - ad->AttrLen = cpu_to_be16(size); 3087 - ad->AttrType = cpu_to_be16(RPRT_SUPPORTED_CLASS); 3088 - return size; 3124 + return lpfc_fdmi_set_attr_u32(attr, RPRT_SUPPORTED_CLASS, 3125 + FC_COS_CLASS2 | FC_COS_CLASS3); 3089 3126 } 3090 3127 3091 3128 static int 3092 - lpfc_fdmi_port_attr_fabric_wwpn(struct lpfc_vport *vport, 3093 - struct lpfc_fdmi_attr_def *ad) 3129 + lpfc_fdmi_port_attr_fabric_wwpn(struct lpfc_vport *vport, void *attr) 3094 3130 { 3095 - struct lpfc_fdmi_attr_entry *ae; 3096 - uint32_t size; 3097 - 3098 - ae = &ad->AttrValue; 3099 - memset(ae, 0, sizeof(*ae)); 3100 - 3101 - memcpy(&ae->un.AttrWWN, &vport->fabric_portname, 3102 - sizeof(struct lpfc_name)); 3103 - size = FOURBYTES + sizeof(struct lpfc_name); 3104 - ad->AttrLen = cpu_to_be16(size); 3105 - ad->AttrType = cpu_to_be16(RPRT_FABRICNAME); 3106 - return size; 3131 + return lpfc_fdmi_set_attr_wwn(attr, RPRT_FABRICNAME, 3132 + &vport->fabric_portname); 3107 3133 } 3108 3134 3109 3135 static int 3110 - lpfc_fdmi_port_attr_active_fc4type(struct lpfc_vport *vport, 3111 - struct lpfc_fdmi_attr_def *ad) 3136 + lpfc_fdmi_port_attr_active_fc4type(struct lpfc_vport *vport, void *attr) 3112 3137 { 3113 3138 struct lpfc_hba *phba = vport->phba; 3114 - struct lpfc_fdmi_attr_entry *ae; 3115 - uint32_t size; 3139 + u32 fc4types; 3116 3140 3117 - ae = &ad->AttrValue; 3118 - memset(ae, 0, sizeof(*ae)); 3119 - 3120 - ae->un.AttrTypes[2] = 0x01; /* Type 0x8 - FCP */ 3121 - ae->un.AttrTypes[7] = 0x01; /* Type 0x20 - CT */ 3141 + fc4types = (ATTR_FC4_CT | ATTR_FC4_FCP); 3122 3142 3123 3143 /* Check to see if NVME is configured or not */ 3124 3144 if (vport == phba->pport && 3125 3145 phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) 3126 - ae->un.AttrTypes[6] = 0x1; /* Type 0x28 - NVME */ 3146 + fc4types |= ATTR_FC4_NVME; 3127 3147 3128 - size = FOURBYTES + 32; 3129 - ad->AttrLen = cpu_to_be16(size); 3130 - ad->AttrType = cpu_to_be16(RPRT_ACTIVE_FC4_TYPES); 3131 - return size; 3148 + return lpfc_fdmi_set_attr_fc4types(attr, RPRT_ACTIVE_FC4_TYPES, 3149 + fc4types); 3132 3150 } 3133 3151 3134 3152 static int 3135 - lpfc_fdmi_port_attr_port_state(struct lpfc_vport *vport, 3136 - struct lpfc_fdmi_attr_def *ad) 3153 + lpfc_fdmi_port_attr_port_state(struct lpfc_vport *vport, void *attr) 3137 3154 { 3138 - struct lpfc_fdmi_attr_entry *ae; 3139 - uint32_t size; 3140 - 3141 - ae = &ad->AttrValue; 3142 - /* Link Up - operational */ 3143 - ae->un.AttrInt = cpu_to_be32(LPFC_FDMI_PORTSTATE_ONLINE); 3144 - size = FOURBYTES + sizeof(uint32_t); 3145 - ad->AttrLen = cpu_to_be16(size); 3146 - ad->AttrType = cpu_to_be16(RPRT_PORT_STATE); 3147 - return size; 3155 + return lpfc_fdmi_set_attr_u32(attr, RPRT_PORT_STATE, 3156 + LPFC_FDMI_PORTSTATE_ONLINE); 3148 3157 } 3149 3158 3150 3159 static int 3151 - lpfc_fdmi_port_attr_num_disc(struct lpfc_vport *vport, 3152 - struct lpfc_fdmi_attr_def *ad) 3160 + lpfc_fdmi_port_attr_num_disc(struct lpfc_vport *vport, void *attr) 3153 3161 { 3154 - struct lpfc_fdmi_attr_entry *ae; 3155 - uint32_t size; 3156 - 3157 - ae = &ad->AttrValue; 3158 3162 vport->fdmi_num_disc = lpfc_find_map_node(vport); 3159 - ae->un.AttrInt = cpu_to_be32(vport->fdmi_num_disc); 3160 - size = FOURBYTES + sizeof(uint32_t); 3161 - ad->AttrLen = cpu_to_be16(size); 3162 - ad->AttrType = cpu_to_be16(RPRT_DISC_PORT); 3163 - return size; 3163 + 3164 + return lpfc_fdmi_set_attr_u32(attr, RPRT_DISC_PORT, 3165 + vport->fdmi_num_disc); 3164 3166 } 3165 3167 3166 3168 static int 3167 - lpfc_fdmi_port_attr_nportid(struct lpfc_vport *vport, 3168 - struct lpfc_fdmi_attr_def *ad) 3169 + lpfc_fdmi_port_attr_nportid(struct lpfc_vport *vport, void *attr) 3169 3170 { 3170 - struct lpfc_fdmi_attr_entry *ae; 3171 - uint32_t size; 3172 - 3173 - ae = &ad->AttrValue; 3174 - ae->un.AttrInt = cpu_to_be32(vport->fc_myDID); 3175 - size = FOURBYTES + sizeof(uint32_t); 3176 - ad->AttrLen = cpu_to_be16(size); 3177 - ad->AttrType = cpu_to_be16(RPRT_PORT_ID); 3178 - return size; 3171 + return lpfc_fdmi_set_attr_u32(attr, RPRT_PORT_ID, vport->fc_myDID); 3179 3172 } 3180 3173 3181 3174 static int 3182 - lpfc_fdmi_smart_attr_service(struct lpfc_vport *vport, 3183 - struct lpfc_fdmi_attr_def *ad) 3175 + lpfc_fdmi_smart_attr_service(struct lpfc_vport *vport, void *attr) 3184 3176 { 3185 - struct lpfc_fdmi_attr_entry *ae; 3186 - uint32_t len, size; 3187 - 3188 - ae = &ad->AttrValue; 3189 - memset(ae, 0, sizeof(*ae)); 3190 - 3191 - strncpy(ae->un.AttrString, "Smart SAN Initiator", 3192 - sizeof(ae->un.AttrString)); 3193 - len = strnlen(ae->un.AttrString, 3194 - sizeof(ae->un.AttrString)); 3195 - len += (len & 3) ? (4 - (len & 3)) : 4; 3196 - size = FOURBYTES + len; 3197 - ad->AttrLen = cpu_to_be16(size); 3198 - ad->AttrType = cpu_to_be16(RPRT_SMART_SERVICE); 3199 - return size; 3177 + return lpfc_fdmi_set_attr_string(attr, RPRT_SMART_SERVICE, 3178 + "Smart SAN Initiator"); 3200 3179 } 3201 3180 3202 3181 static int 3203 - lpfc_fdmi_smart_attr_guid(struct lpfc_vport *vport, 3204 - struct lpfc_fdmi_attr_def *ad) 3182 + lpfc_fdmi_smart_attr_guid(struct lpfc_vport *vport, void *attr) 3205 3183 { 3206 - struct lpfc_fdmi_attr_entry *ae; 3207 - uint32_t size; 3208 - 3209 - ae = &ad->AttrValue; 3210 - memset(ae, 0, sizeof(*ae)); 3211 - 3212 - memcpy(&ae->un.AttrString, &vport->fc_sparam.nodeName, 3213 - sizeof(struct lpfc_name)); 3214 - memcpy((((uint8_t *)&ae->un.AttrString) + 3215 - sizeof(struct lpfc_name)), 3216 - &vport->fc_sparam.portName, sizeof(struct lpfc_name)); 3217 - size = FOURBYTES + (2 * sizeof(struct lpfc_name)); 3218 - ad->AttrLen = cpu_to_be16(size); 3219 - ad->AttrType = cpu_to_be16(RPRT_SMART_GUID); 3220 - return size; 3184 + return lpfc_fdmi_set_attr_fullwwn(attr, RPRT_SMART_GUID, 3185 + &vport->fc_sparam.nodeName, 3186 + &vport->fc_sparam.portName); 3221 3187 } 3222 3188 3223 3189 static int 3224 - lpfc_fdmi_smart_attr_version(struct lpfc_vport *vport, 3225 - struct lpfc_fdmi_attr_def *ad) 3190 + lpfc_fdmi_smart_attr_version(struct lpfc_vport *vport, void *attr) 3226 3191 { 3227 - struct lpfc_fdmi_attr_entry *ae; 3228 - uint32_t len, size; 3229 - 3230 - ae = &ad->AttrValue; 3231 - memset(ae, 0, sizeof(*ae)); 3232 - 3233 - strncpy(ae->un.AttrString, "Smart SAN Version 2.0", 3234 - sizeof(ae->un.AttrString)); 3235 - len = strnlen(ae->un.AttrString, 3236 - sizeof(ae->un.AttrString)); 3237 - len += (len & 3) ? (4 - (len & 3)) : 4; 3238 - size = FOURBYTES + len; 3239 - ad->AttrLen = cpu_to_be16(size); 3240 - ad->AttrType = cpu_to_be16(RPRT_SMART_VERSION); 3241 - return size; 3192 + return lpfc_fdmi_set_attr_string(attr, RPRT_SMART_VERSION, 3193 + "Smart SAN Version 2.0"); 3242 3194 } 3243 3195 3244 3196 static int 3245 - lpfc_fdmi_smart_attr_model(struct lpfc_vport *vport, 3246 - struct lpfc_fdmi_attr_def *ad) 3197 + lpfc_fdmi_smart_attr_model(struct lpfc_vport *vport, void *attr) 3247 3198 { 3248 3199 struct lpfc_hba *phba = vport->phba; 3249 - struct lpfc_fdmi_attr_entry *ae; 3250 - uint32_t len, size; 3251 3200 3252 - ae = &ad->AttrValue; 3253 - memset(ae, 0, sizeof(*ae)); 3254 - 3255 - strncpy(ae->un.AttrString, phba->ModelName, 3256 - sizeof(ae->un.AttrString)); 3257 - len = strnlen(ae->un.AttrString, sizeof(ae->un.AttrString)); 3258 - len += (len & 3) ? (4 - (len & 3)) : 4; 3259 - size = FOURBYTES + len; 3260 - ad->AttrLen = cpu_to_be16(size); 3261 - ad->AttrType = cpu_to_be16(RPRT_SMART_MODEL); 3262 - return size; 3201 + return lpfc_fdmi_set_attr_string(attr, RPRT_SMART_MODEL, 3202 + phba->ModelName); 3263 3203 } 3264 3204 3265 3205 static int 3266 - lpfc_fdmi_smart_attr_port_info(struct lpfc_vport *vport, 3267 - struct lpfc_fdmi_attr_def *ad) 3206 + lpfc_fdmi_smart_attr_port_info(struct lpfc_vport *vport, void *attr) 3268 3207 { 3269 - struct lpfc_fdmi_attr_entry *ae; 3270 - uint32_t size; 3271 - 3272 - ae = &ad->AttrValue; 3273 - 3274 3208 /* SRIOV (type 3) is not supported */ 3275 - if (vport->vpi) 3276 - ae->un.AttrInt = cpu_to_be32(2); /* NPIV */ 3277 - else 3278 - ae->un.AttrInt = cpu_to_be32(1); /* Physical */ 3279 - size = FOURBYTES + sizeof(uint32_t); 3280 - ad->AttrLen = cpu_to_be16(size); 3281 - ad->AttrType = cpu_to_be16(RPRT_SMART_PORT_INFO); 3282 - return size; 3209 + 3210 + return lpfc_fdmi_set_attr_u32(attr, RPRT_SMART_PORT_INFO, 3211 + (vport->vpi) ? 2 /* NPIV */ : 1 /* Physical */); 3283 3212 } 3284 3213 3285 3214 static int 3286 - lpfc_fdmi_smart_attr_qos(struct lpfc_vport *vport, 3287 - struct lpfc_fdmi_attr_def *ad) 3215 + lpfc_fdmi_smart_attr_qos(struct lpfc_vport *vport, void *attr) 3288 3216 { 3289 - struct lpfc_fdmi_attr_entry *ae; 3290 - uint32_t size; 3291 - 3292 - ae = &ad->AttrValue; 3293 - ae->un.AttrInt = cpu_to_be32(0); 3294 - size = FOURBYTES + sizeof(uint32_t); 3295 - ad->AttrLen = cpu_to_be16(size); 3296 - ad->AttrType = cpu_to_be16(RPRT_SMART_QOS); 3297 - return size; 3217 + return lpfc_fdmi_set_attr_u32(attr, RPRT_SMART_QOS, 0); 3298 3218 } 3299 3219 3300 3220 static int 3301 - lpfc_fdmi_smart_attr_security(struct lpfc_vport *vport, 3302 - struct lpfc_fdmi_attr_def *ad) 3221 + lpfc_fdmi_smart_attr_security(struct lpfc_vport *vport, void *attr) 3303 3222 { 3304 - struct lpfc_fdmi_attr_entry *ae; 3305 - uint32_t size; 3306 - 3307 - ae = &ad->AttrValue; 3308 - ae->un.AttrInt = cpu_to_be32(1); 3309 - size = FOURBYTES + sizeof(uint32_t); 3310 - ad->AttrLen = cpu_to_be16(size); 3311 - ad->AttrType = cpu_to_be16(RPRT_SMART_SECURITY); 3312 - return size; 3223 + return lpfc_fdmi_set_attr_u32(attr, RPRT_SMART_SECURITY, 1); 3313 3224 } 3314 3225 3315 3226 static int 3316 - lpfc_fdmi_vendor_attr_mi(struct lpfc_vport *vport, 3317 - struct lpfc_fdmi_attr_def *ad) 3227 + lpfc_fdmi_vendor_attr_mi(struct lpfc_vport *vport, void *attr) 3318 3228 { 3319 3229 struct lpfc_hba *phba = vport->phba; 3320 - struct lpfc_fdmi_attr_entry *ae; 3321 - uint32_t len, size; 3322 - char mibrevision[16]; 3230 + char buf[32] = { 0 }; 3323 3231 3324 - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 3325 - memset(ae, 0, 256); 3326 - sprintf(mibrevision, "ELXE2EM:%04d", 3327 - phba->sli4_hba.pc_sli4_params.mi_ver); 3328 - strncpy(ae->un.AttrString, &mibrevision[0], sizeof(ae->un.AttrString)); 3329 - len = strnlen(ae->un.AttrString, sizeof(ae->un.AttrString)); 3330 - len += (len & 3) ? (4 - (len & 3)) : 4; 3331 - size = FOURBYTES + len; 3332 - ad->AttrLen = cpu_to_be16(size); 3333 - ad->AttrType = cpu_to_be16(RPRT_VENDOR_MI); 3334 - return size; 3232 + sprintf(buf, "ELXE2EM:%04d", phba->sli4_hba.pc_sli4_params.mi_ver); 3233 + 3234 + return lpfc_fdmi_set_attr_string(attr, RPRT_VENDOR_MI, buf); 3335 3235 } 3336 3236 3337 3237 /* RHBA attribute jump table */ 3338 3238 int (*lpfc_fdmi_hba_action[]) 3339 - (struct lpfc_vport *vport, struct lpfc_fdmi_attr_def *ad) = { 3239 + (struct lpfc_vport *vport, void *attrbuf) = { 3340 3240 /* Action routine Mask bit Attribute type */ 3341 3241 lpfc_fdmi_hba_attr_wwnn, /* bit0 RHBA_NODENAME */ 3342 3242 lpfc_fdmi_hba_attr_manufacturer, /* bit1 RHBA_MANUFACTURER */ ··· 3135 3485 3136 3486 /* RPA / RPRT attribute jump table */ 3137 3487 int (*lpfc_fdmi_port_action[]) 3138 - (struct lpfc_vport *vport, struct lpfc_fdmi_attr_def *ad) = { 3488 + (struct lpfc_vport *vport, void *attrbuf) = { 3139 3489 /* Action routine Mask bit Attribute type */ 3140 3490 lpfc_fdmi_port_attr_fc4type, /* bit0 RPRT_SUPPORT_FC4_TYPES */ 3141 3491 lpfc_fdmi_port_attr_support_speed, /* bit1 RPRT_SUPPORTED_SPEED */ ··· 3177 3527 int cmdcode, uint32_t new_mask) 3178 3528 { 3179 3529 struct lpfc_hba *phba = vport->phba; 3180 - struct lpfc_dmabuf *mp, *bmp; 3530 + struct lpfc_dmabuf *rq, *rsp; 3181 3531 struct lpfc_sli_ct_request *CtReq; 3182 - struct ulp_bde64 *bpl; 3532 + struct ulp_bde64_le *bde; 3183 3533 uint32_t bit_pos; 3184 - uint32_t size; 3534 + uint32_t size, addsz; 3185 3535 uint32_t rsp_size; 3186 3536 uint32_t mask; 3187 3537 struct lpfc_fdmi_reg_hba *rh; 3188 3538 struct lpfc_fdmi_port_entry *pe; 3189 - struct lpfc_fdmi_reg_portattr *pab = NULL; 3539 + struct lpfc_fdmi_reg_portattr *pab = NULL, *base = NULL; 3190 3540 struct lpfc_fdmi_attr_block *ab = NULL; 3191 - int (*func)(struct lpfc_vport *vport, struct lpfc_fdmi_attr_def *ad); 3192 - void (*cmpl)(struct lpfc_hba *, struct lpfc_iocbq *, 3193 - struct lpfc_iocbq *); 3541 + int (*func)(struct lpfc_vport *vport, void *attrbuf); 3542 + void (*cmpl)(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, 3543 + struct lpfc_iocbq *rspiocb); 3194 3544 3195 3545 if (!ndlp) 3196 3546 return 0; ··· 3199 3549 3200 3550 /* fill in BDEs for command */ 3201 3551 /* Allocate buffer for command payload */ 3202 - mp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL); 3203 - if (!mp) 3552 + rq = kmalloc(sizeof(*rq), GFP_KERNEL); 3553 + if (!rq) 3204 3554 goto fdmi_cmd_exit; 3205 3555 3206 - mp->virt = lpfc_mbuf_alloc(phba, 0, &(mp->phys)); 3207 - if (!mp->virt) 3208 - goto fdmi_cmd_free_mp; 3556 + rq->virt = lpfc_mbuf_alloc(phba, 0, &rq->phys); 3557 + if (!rq->virt) 3558 + goto fdmi_cmd_free_rq; 3209 3559 3210 3560 /* Allocate buffer for Buffer ptr list */ 3211 - bmp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL); 3212 - if (!bmp) 3213 - goto fdmi_cmd_free_mpvirt; 3561 + rsp = kmalloc(sizeof(*rsp), GFP_KERNEL); 3562 + if (!rsp) 3563 + goto fdmi_cmd_free_rqvirt; 3214 3564 3215 - bmp->virt = lpfc_mbuf_alloc(phba, 0, &(bmp->phys)); 3216 - if (!bmp->virt) 3217 - goto fdmi_cmd_free_bmp; 3565 + rsp->virt = lpfc_mbuf_alloc(phba, 0, &rsp->phys); 3566 + if (!rsp->virt) 3567 + goto fdmi_cmd_free_rsp; 3218 3568 3219 - INIT_LIST_HEAD(&mp->list); 3220 - INIT_LIST_HEAD(&bmp->list); 3569 + INIT_LIST_HEAD(&rq->list); 3570 + INIT_LIST_HEAD(&rsp->list); 3571 + 3572 + /* mbuf buffers are 1K in length - aka LPFC_BPL_SIZE */ 3573 + memset(rq->virt, 0, LPFC_BPL_SIZE); 3574 + rsp_size = LPFC_BPL_SIZE; 3221 3575 3222 3576 /* FDMI request */ 3223 3577 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, ··· 3229 3575 cmdcode, new_mask, vport->fdmi_port_mask, 3230 3576 vport->fc_flag, vport->port_state); 3231 3577 3232 - CtReq = (struct lpfc_sli_ct_request *)mp->virt; 3578 + CtReq = (struct lpfc_sli_ct_request *)rq->virt; 3233 3579 3234 3580 /* First populate the CT_IU preamble */ 3235 - memset(CtReq, 0, sizeof(struct lpfc_sli_ct_request)); 3236 3581 CtReq->RevisionId.bits.Revision = SLI_CT_REVISION; 3237 3582 CtReq->RevisionId.bits.InId = 0; 3238 3583 ··· 3239 3586 CtReq->FsSubType = SLI_CT_FDMI_Subtypes; 3240 3587 3241 3588 CtReq->CommandResponse.bits.CmdRsp = cpu_to_be16(cmdcode); 3242 - rsp_size = LPFC_BPL_SIZE; 3589 + 3243 3590 size = 0; 3244 3591 3245 3592 /* Next fill in the specific FDMI cmd information */ 3246 3593 switch (cmdcode) { 3247 3594 case SLI_MGMT_RHAT: 3248 3595 case SLI_MGMT_RHBA: 3249 - rh = (struct lpfc_fdmi_reg_hba *)&CtReq->un.PortID; 3596 + rh = (struct lpfc_fdmi_reg_hba *)&CtReq->un; 3250 3597 /* HBA Identifier */ 3251 3598 memcpy(&rh->hi.PortName, &phba->pport->fc_sparam.portName, 3252 3599 sizeof(struct lpfc_name)); 3600 + size += sizeof(struct lpfc_fdmi_hba_ident); 3253 3601 3254 3602 if (cmdcode == SLI_MGMT_RHBA) { 3255 3603 /* Registered Port List */ ··· 3259 3605 memcpy(&rh->rpl.pe.PortName, 3260 3606 &phba->pport->fc_sparam.portName, 3261 3607 sizeof(struct lpfc_name)); 3262 - 3263 - /* point to the HBA attribute block */ 3264 - size = 2 * sizeof(struct lpfc_name) + 3265 - FOURBYTES; 3266 - } else { 3267 - size = sizeof(struct lpfc_name); 3608 + size += sizeof(struct lpfc_fdmi_reg_port_list); 3268 3609 } 3610 + 3269 3611 ab = (struct lpfc_fdmi_attr_block *)((uint8_t *)rh + size); 3270 3612 ab->EntryCnt = 0; 3271 - size += FOURBYTES; 3613 + size += FOURBYTES; /* add length of EntryCnt field */ 3614 + 3272 3615 bit_pos = 0; 3273 3616 if (new_mask) 3274 3617 mask = new_mask; ··· 3276 3625 while (mask) { 3277 3626 if (mask & 0x1) { 3278 3627 func = lpfc_fdmi_hba_action[bit_pos]; 3279 - size += func(vport, 3280 - (struct lpfc_fdmi_attr_def *) 3281 - ((uint8_t *)rh + size)); 3282 - ab->EntryCnt++; 3283 - if ((size + 256) > 3628 + addsz = func(vport, ((uint8_t *)rh + size)); 3629 + if (addsz) { 3630 + ab->EntryCnt++; 3631 + size += addsz; 3632 + } 3633 + /* check if another attribute fits */ 3634 + if ((size + FDMI_MAX_ATTRLEN) > 3284 3635 (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) 3285 3636 goto hba_out; 3286 3637 } ··· 3292 3639 hba_out: 3293 3640 ab->EntryCnt = cpu_to_be32(ab->EntryCnt); 3294 3641 /* Total size */ 3295 - size = GID_REQUEST_SZ - 4 + size; 3642 + size += GID_REQUEST_SZ - 4; 3296 3643 break; 3297 3644 3298 3645 case SLI_MGMT_RPRT: ··· 3303 3650 } 3304 3651 fallthrough; 3305 3652 case SLI_MGMT_RPA: 3306 - pab = (struct lpfc_fdmi_reg_portattr *)&CtReq->un.PortID; 3653 + /* Store base ptr right after preamble */ 3654 + base = (struct lpfc_fdmi_reg_portattr *)&CtReq->un; 3655 + 3307 3656 if (cmdcode == SLI_MGMT_RPRT) { 3308 - rh = (struct lpfc_fdmi_reg_hba *)pab; 3657 + rh = (struct lpfc_fdmi_reg_hba *)base; 3309 3658 /* HBA Identifier */ 3310 3659 memcpy(&rh->hi.PortName, 3311 3660 &phba->pport->fc_sparam.portName, 3312 3661 sizeof(struct lpfc_name)); 3313 3662 pab = (struct lpfc_fdmi_reg_portattr *) 3314 - ((uint8_t *)pab + sizeof(struct lpfc_name)); 3663 + ((uint8_t *)base + sizeof(struct lpfc_name)); 3664 + size += sizeof(struct lpfc_name); 3665 + } else { 3666 + pab = base; 3315 3667 } 3316 3668 3317 3669 memcpy((uint8_t *)&pab->PortName, 3318 3670 (uint8_t *)&vport->fc_sparam.portName, 3319 3671 sizeof(struct lpfc_name)); 3320 - size += sizeof(struct lpfc_name) + FOURBYTES; 3321 3672 pab->ab.EntryCnt = 0; 3673 + /* add length of name and EntryCnt field */ 3674 + size += sizeof(struct lpfc_name) + FOURBYTES; 3675 + 3322 3676 bit_pos = 0; 3323 3677 if (new_mask) 3324 3678 mask = new_mask; ··· 3336 3676 while (mask) { 3337 3677 if (mask & 0x1) { 3338 3678 func = lpfc_fdmi_port_action[bit_pos]; 3339 - size += func(vport, 3340 - (struct lpfc_fdmi_attr_def *) 3341 - ((uint8_t *)pab + size)); 3342 - pab->ab.EntryCnt++; 3343 - if ((size + 256) > 3679 + addsz = func(vport, ((uint8_t *)base + size)); 3680 + if (addsz) { 3681 + pab->ab.EntryCnt++; 3682 + size += addsz; 3683 + } 3684 + /* check if another attribute fits */ 3685 + if ((size + FDMI_MAX_ATTRLEN) > 3344 3686 (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) 3345 3687 goto port_out; 3346 3688 } ··· 3351 3689 } 3352 3690 port_out: 3353 3691 pab->ab.EntryCnt = cpu_to_be32(pab->ab.EntryCnt); 3354 - /* Total size */ 3355 - if (cmdcode == SLI_MGMT_RPRT) 3356 - size += sizeof(struct lpfc_name); 3357 - size = GID_REQUEST_SZ - 4 + size; 3692 + size += GID_REQUEST_SZ - 4; 3358 3693 break; 3359 3694 3360 3695 case SLI_MGMT_GHAT: ··· 3360 3701 fallthrough; 3361 3702 case SLI_MGMT_DHBA: 3362 3703 case SLI_MGMT_DHAT: 3363 - pe = (struct lpfc_fdmi_port_entry *)&CtReq->un.PortID; 3704 + pe = (struct lpfc_fdmi_port_entry *)&CtReq->un; 3364 3705 memcpy((uint8_t *)&pe->PortName, 3365 3706 (uint8_t *)&vport->fc_sparam.portName, 3366 3707 sizeof(struct lpfc_name)); ··· 3379 3720 } 3380 3721 fallthrough; 3381 3722 case SLI_MGMT_DPA: 3382 - pe = (struct lpfc_fdmi_port_entry *)&CtReq->un.PortID; 3723 + pe = (struct lpfc_fdmi_port_entry *)&CtReq->un; 3383 3724 memcpy((uint8_t *)&pe->PortName, 3384 3725 (uint8_t *)&vport->fc_sparam.portName, 3385 3726 sizeof(struct lpfc_name)); ··· 3392 3733 lpfc_printf_vlog(vport, KERN_WARNING, LOG_DISCOVERY, 3393 3734 "0298 FDMI cmdcode x%x not supported\n", 3394 3735 cmdcode); 3395 - goto fdmi_cmd_free_bmpvirt; 3736 + goto fdmi_cmd_free_rspvirt; 3396 3737 } 3397 3738 CtReq->CommandResponse.bits.Size = cpu_to_be16(rsp_size); 3398 3739 3399 - bpl = (struct ulp_bde64 *)bmp->virt; 3400 - bpl->addrHigh = le32_to_cpu(putPaddrHigh(mp->phys)); 3401 - bpl->addrLow = le32_to_cpu(putPaddrLow(mp->phys)); 3402 - bpl->tus.f.bdeFlags = 0; 3403 - bpl->tus.f.bdeSize = size; 3740 + bde = (struct ulp_bde64_le *)rsp->virt; 3741 + bde->addr_high = cpu_to_le32(putPaddrHigh(rq->phys)); 3742 + bde->addr_low = cpu_to_le32(putPaddrLow(rq->phys)); 3743 + bde->type_size = cpu_to_le32(ULP_BDE64_TYPE_BDE_64 << 3744 + ULP_BDE64_TYPE_SHIFT); 3745 + bde->type_size |= cpu_to_le32(size); 3404 3746 3405 3747 /* 3406 3748 * The lpfc_ct_cmd/lpfc_get_req shall increment ndlp reference count 3407 3749 * to hold ndlp reference for the corresponding callback function. 3408 3750 */ 3409 - if (!lpfc_ct_cmd(vport, mp, bmp, ndlp, cmpl, rsp_size, 0)) 3751 + if (!lpfc_ct_cmd(vport, rq, rsp, ndlp, cmpl, rsp_size, 0)) 3410 3752 return 0; 3411 3753 3412 - fdmi_cmd_free_bmpvirt: 3413 - lpfc_mbuf_free(phba, bmp->virt, bmp->phys); 3414 - fdmi_cmd_free_bmp: 3415 - kfree(bmp); 3416 - fdmi_cmd_free_mpvirt: 3417 - lpfc_mbuf_free(phba, mp->virt, mp->phys); 3418 - fdmi_cmd_free_mp: 3419 - kfree(mp); 3754 + fdmi_cmd_free_rspvirt: 3755 + lpfc_mbuf_free(phba, rsp->virt, rsp->phys); 3756 + fdmi_cmd_free_rsp: 3757 + kfree(rsp); 3758 + fdmi_cmd_free_rqvirt: 3759 + lpfc_mbuf_free(phba, rq->virt, rq->phys); 3760 + fdmi_cmd_free_rq: 3761 + kfree(rq); 3420 3762 fdmi_cmd_exit: 3421 3763 /* Issue FDMI request failed */ 3422 3764 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, ··· 3572 3912 struct lpfc_sli_ct_request *ctrsp = outp->virt; 3573 3913 u16 rsp = ctrsp->CommandResponse.bits.CmdRsp; 3574 3914 struct app_id_object *app; 3915 + struct lpfc_nodelist *ndlp = cmdiocb->ndlp; 3575 3916 u32 cmd, hash, bucket; 3576 3917 struct lpfc_vmid *vmp, *cur; 3577 3918 u8 *data = outp->virt; ··· 3584 3923 3585 3924 if (lpfc_els_chk_latt(vport) || get_job_ulpstatus(phba, rspiocb)) { 3586 3925 if (cmd != SLI_CTAS_DALLAPP_ID) 3587 - return; 3926 + goto free_res; 3588 3927 } 3589 3928 /* Check for a CT LS_RJT response */ 3590 3929 if (rsp == be16_to_cpu(SLI_CT_RESPONSE_FS_RJT)) { ··· 3599 3938 /* If DALLAPP_ID failed retry later */ 3600 3939 if (cmd == SLI_CTAS_DALLAPP_ID) 3601 3940 vport->load_flag |= FC_DEREGISTER_ALL_APP_ID; 3602 - return; 3941 + goto free_res; 3603 3942 } 3604 3943 } 3605 3944 ··· 3613 3952 app->obj.entity_id_len); 3614 3953 3615 3954 if (app->obj.entity_id_len == 0 || app->port_id == 0) 3616 - return; 3955 + goto free_res; 3617 3956 3618 3957 hash = lpfc_vmid_hash_fn(app->obj.entity_id, 3619 3958 app->obj.entity_id_len); ··· 3660 3999 lpfc_printf_vlog(vport, KERN_DEBUG, LOG_DISCOVERY, 3661 4000 "8857 Invalid command code\n"); 3662 4001 } 4002 + free_res: 4003 + lpfc_ct_free_iocb(phba, cmdiocb); 4004 + lpfc_nlp_put(ndlp); 3663 4005 } 3664 4006 3665 4007 /**
+11 -50
drivers/scsi/lpfc/lpfc_debugfs.c
··· 5156 5156 static int 5157 5157 lpfc_idiag_extacc_avail_get(struct lpfc_hba *phba, char *pbuffer, int len) 5158 5158 { 5159 - uint16_t ext_cnt, ext_size; 5159 + uint16_t ext_cnt = 0, ext_size = 0; 5160 5160 5161 5161 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, 5162 5162 "\nAvailable Extents Information:\n"); ··· 5531 5531 if (!debug) 5532 5532 goto out; 5533 5533 5534 - debug->buffer = vmalloc(MAX_DEBUGFS_RX_TABLE_SIZE); 5534 + debug->buffer = vmalloc(MAX_DEBUGFS_RX_INFO_SIZE); 5535 5535 if (!debug->buffer) { 5536 5536 kfree(debug); 5537 5537 goto out; ··· 5552 5552 struct lpfc_rx_monitor_debug *debug = file->private_data; 5553 5553 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private; 5554 5554 char *buffer = debug->buffer; 5555 - struct rxtable_entry *entry; 5556 - int i, len = 0, head, tail, last, start; 5557 5555 5558 - head = atomic_read(&phba->rxtable_idx_head); 5559 - while (head == LPFC_RXMONITOR_TABLE_IN_USE) { 5560 - /* Table is getting updated */ 5561 - msleep(20); 5562 - head = atomic_read(&phba->rxtable_idx_head); 5556 + if (!phba->rx_monitor) { 5557 + scnprintf(buffer, MAX_DEBUGFS_RX_INFO_SIZE, 5558 + "Rx Monitor Info is empty.\n"); 5559 + } else { 5560 + lpfc_rx_monitor_report(phba, phba->rx_monitor, buffer, 5561 + MAX_DEBUGFS_RX_INFO_SIZE, 5562 + LPFC_MAX_RXMONITOR_ENTRY); 5563 5563 } 5564 5564 5565 - tail = atomic_xchg(&phba->rxtable_idx_tail, head); 5566 - if (!phba->rxtable || head == tail) { 5567 - len += scnprintf(buffer + len, MAX_DEBUGFS_RX_TABLE_SIZE - len, 5568 - "Rxtable is empty\n"); 5569 - goto out; 5570 - } 5571 - last = (head > tail) ? head : LPFC_MAX_RXMONITOR_ENTRY; 5572 - start = tail; 5573 - 5574 - len += scnprintf(buffer + len, MAX_DEBUGFS_RX_TABLE_SIZE - len, 5575 - " MaxBPI Tot_Data_CMF Tot_Data_Cmd " 5576 - "Tot_Data_Cmpl Lat(us) Avg_IO Max_IO " 5577 - "Bsy IO_cnt Info BWutil(ms)\n"); 5578 - get_table: 5579 - for (i = start; i < last; i++) { 5580 - entry = &phba->rxtable[i]; 5581 - len += scnprintf(buffer + len, MAX_DEBUGFS_RX_TABLE_SIZE - len, 5582 - "%3d:%12lld %12lld %12lld %12lld " 5583 - "%7lldus %8lld %7lld " 5584 - "%2d %4d %2d %2d(%2d)\n", 5585 - i, entry->max_bytes_per_interval, 5586 - entry->cmf_bytes, 5587 - entry->total_bytes, 5588 - entry->rcv_bytes, 5589 - entry->avg_io_latency, 5590 - entry->avg_io_size, 5591 - entry->max_read_cnt, 5592 - entry->cmf_busy, 5593 - entry->io_cnt, 5594 - entry->cmf_info, 5595 - entry->timer_utilization, 5596 - entry->timer_interval); 5597 - } 5598 - 5599 - if (head != last) { 5600 - start = 0; 5601 - last = head; 5602 - goto get_table; 5603 - } 5604 - out: 5605 - return simple_read_from_buffer(buf, nbytes, ppos, buffer, len); 5565 + return simple_read_from_buffer(buf, nbytes, ppos, buffer, 5566 + strlen(buffer)); 5606 5567 } 5607 5568 5608 5569 static int
+2 -2
drivers/scsi/lpfc/lpfc_debugfs.h
··· 1 1 /******************************************************************* 2 2 * This file is part of the Emulex Linux Device Driver for * 3 3 * Fibre Channel Host Bus Adapters. * 4 - * Copyright (C) 2017-2021 Broadcom. All Rights Reserved. The term * 4 + * Copyright (C) 2017-2022 Broadcom. All Rights Reserved. The term * 5 5 * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. * 6 6 * Copyright (C) 2007-2011 Emulex. All rights reserved. * 7 7 * EMULEX and SLI are trademarks of Emulex. * ··· 282 282 void *ptr_private; 283 283 }; 284 284 285 - #define MAX_DEBUGFS_RX_TABLE_SIZE (128 * LPFC_MAX_RXMONITOR_ENTRY) 285 + #define MAX_DEBUGFS_RX_INFO_SIZE (128 * LPFC_MAX_RXMONITOR_ENTRY) 286 286 struct lpfc_rx_monitor_debug { 287 287 char *i_private; 288 288 char *buffer;
+1 -3
drivers/scsi/lpfc/lpfc_disc.h
··· 1 1 /******************************************************************* 2 2 * This file is part of the Emulex Linux Device Driver for * 3 3 * Fibre Channel Host Bus Adapters. * 4 - * Copyright (C) 2017-2021 Broadcom. All Rights Reserved. The term * 4 + * Copyright (C) 2017-2022 Broadcom. All Rights Reserved. The term * 5 5 * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. * 6 6 * Copyright (C) 2004-2013 Emulex. All rights reserved. * 7 7 * EMULEX and SLI are trademarks of Emulex. * ··· 149 149 uint32_t cmd_qdepth; 150 150 unsigned long last_change_time; 151 151 unsigned long *active_rrqs_xri_bitmap; 152 - struct lpfc_scsicmd_bkt *lat_data; /* Latency data */ 153 152 uint32_t fc4_prli_sent; 154 153 155 154 /* flags to keep ndlp alive until special conditions are met */ ··· 187 188 #define NLP_RNID_SND 0x00000400 /* sent RNID request for this entry */ 188 189 #define NLP_ELS_SND_MASK 0x000007e0 /* sent ELS request for this entry */ 189 190 #define NLP_NVMET_RECOV 0x00001000 /* NVMET auditing node for recovery. */ 190 - #define NLP_FCP_PRLI_RJT 0x00002000 /* Rport does not support FCP PRLI. */ 191 191 #define NLP_UNREG_INP 0x00008000 /* UNREG_RPI cmd is in progress */ 192 192 #define NLP_DROPPED 0x00010000 /* Init ref count has been dropped */ 193 193 #define NLP_DELAY_TMO 0x00020000 /* delay timeout is running for node */
+155 -91
drivers/scsi/lpfc/lpfc_els.c
··· 2200 2200 if (!elsiocb) 2201 2201 return 1; 2202 2202 2203 - spin_lock_irq(&ndlp->lock); 2204 - ndlp->nlp_flag &= ~NLP_FCP_PRLI_RJT; 2205 - spin_unlock_irq(&ndlp->lock); 2206 - 2207 2203 pcmd = (uint8_t *)elsiocb->cmd_dmabuf->virt; 2208 2204 2209 2205 /* For PLOGI request, remainder of payload is service parameters */ ··· 3988 3992 goto out; 3989 3993 3990 3994 /* ELS cmd tag <ulpIoTag> completes */ 3991 - lpfc_printf_log(phba, KERN_INFO, LOG_ELS | LOG_CGN_MGMT, 3995 + lpfc_printf_log(phba, KERN_INFO, 3996 + LOG_ELS | LOG_CGN_MGMT | LOG_LDS_EVENT, 3992 3997 "4676 Fabric EDC Rsp: " 3993 3998 "0x%02x, 0x%08x\n", 3994 3999 edc_rsp->acc_hdr.la_cmd, ··· 4026 4029 if (bytes_remain < FC_TLV_DESC_SZ_FROM_LENGTH(tlv) || 4027 4030 FC_TLV_DESC_SZ_FROM_LENGTH(tlv) != 4028 4031 sizeof(struct fc_diag_lnkflt_desc)) { 4029 - lpfc_printf_log( 4030 - phba, KERN_WARNING, LOG_CGN_MGMT, 4032 + lpfc_printf_log(phba, KERN_WARNING, 4033 + LOG_ELS | LOG_CGN_MGMT | LOG_LDS_EVENT, 4031 4034 "6462 Truncated Link Fault Diagnostic " 4032 4035 "descriptor[%d]: %d vs 0x%zx 0x%zx\n", 4033 4036 desc_cnt, bytes_remain, 4034 4037 FC_TLV_DESC_SZ_FROM_LENGTH(tlv), 4035 - sizeof(struct fc_diag_cg_sig_desc)); 4038 + sizeof(struct fc_diag_lnkflt_desc)); 4036 4039 goto out; 4037 4040 } 4038 4041 plnkflt = (struct fc_diag_lnkflt_desc *)tlv; 4039 - lpfc_printf_log( 4040 - phba, KERN_INFO, LOG_ELS | LOG_CGN_MGMT, 4042 + lpfc_printf_log(phba, KERN_INFO, 4043 + LOG_ELS | LOG_LDS_EVENT, 4041 4044 "4617 Link Fault Desc Data: 0x%08x 0x%08x " 4042 4045 "0x%08x 0x%08x 0x%08x\n", 4043 4046 be32_to_cpu(plnkflt->desc_tag), ··· 4117 4120 } 4118 4121 4119 4122 static void 4120 - lpfc_format_edc_cgn_desc(struct lpfc_hba *phba, struct fc_diag_cg_sig_desc *cgd) 4123 + lpfc_format_edc_lft_desc(struct lpfc_hba *phba, struct fc_tlv_desc *tlv) 4121 4124 { 4125 + struct fc_diag_lnkflt_desc *lft = (struct fc_diag_lnkflt_desc *)tlv; 4126 + 4127 + lft->desc_tag = cpu_to_be32(ELS_DTAG_LNK_FAULT_CAP); 4128 + lft->desc_len = cpu_to_be32( 4129 + FC_TLV_DESC_LENGTH_FROM_SZ(struct fc_diag_lnkflt_desc)); 4130 + 4131 + lft->degrade_activate_threshold = 4132 + cpu_to_be32(phba->degrade_activate_threshold); 4133 + lft->degrade_deactivate_threshold = 4134 + cpu_to_be32(phba->degrade_deactivate_threshold); 4135 + lft->fec_degrade_interval = cpu_to_be32(phba->fec_degrade_interval); 4136 + } 4137 + 4138 + static void 4139 + lpfc_format_edc_cgn_desc(struct lpfc_hba *phba, struct fc_tlv_desc *tlv) 4140 + { 4141 + struct fc_diag_cg_sig_desc *cgd = (struct fc_diag_cg_sig_desc *)tlv; 4142 + 4122 4143 /* We are assuming cgd was zero'ed before calling this routine */ 4123 4144 4124 4145 /* Configure the congestion detection capability */ ··· 4180 4165 cpu_to_be16(EDC_CG_SIGFREQ_MSEC); 4181 4166 } 4182 4167 4168 + static bool 4169 + lpfc_link_is_lds_capable(struct lpfc_hba *phba) 4170 + { 4171 + if (!(phba->lmt & LMT_64Gb)) 4172 + return false; 4173 + if (phba->sli_rev != LPFC_SLI_REV4) 4174 + return false; 4175 + 4176 + if (phba->sli4_hba.conf_trunk) { 4177 + if (phba->trunk_link.phy_lnk_speed == LPFC_USER_LINK_SPEED_64G) 4178 + return true; 4179 + } else if (phba->fc_linkspeed == LPFC_LINK_SPEED_64GHZ) { 4180 + return true; 4181 + } 4182 + return false; 4183 + } 4184 + 4183 4185 /** 4184 4186 * lpfc_issue_els_edc - Exchange Diagnostic Capabilities with the fabric. 4185 4187 * @vport: pointer to a host virtual N_Port data structure. ··· 4224 4192 { 4225 4193 struct lpfc_hba *phba = vport->phba; 4226 4194 struct lpfc_iocbq *elsiocb; 4227 - struct lpfc_els_edc_req *edc_req; 4228 - struct fc_diag_cg_sig_desc *cgn_desc; 4195 + struct fc_els_edc *edc_req; 4196 + struct fc_tlv_desc *tlv; 4229 4197 u16 cmdsize; 4230 4198 struct lpfc_nodelist *ndlp; 4231 4199 u8 *pcmd = NULL; 4232 - u32 edc_req_size, cgn_desc_size; 4200 + u32 cgn_desc_size, lft_desc_size; 4233 4201 int rc; 4234 4202 4235 4203 if (vport->port_type == LPFC_NPIV_PORT) ··· 4239 4207 if (!ndlp || ndlp->nlp_state != NLP_STE_UNMAPPED_NODE) 4240 4208 return -ENODEV; 4241 4209 4242 - /* If HBA doesn't support signals, drop into RDF */ 4243 - if (!phba->cgn_init_reg_signal) 4210 + cgn_desc_size = (phba->cgn_init_reg_signal) ? 4211 + sizeof(struct fc_diag_cg_sig_desc) : 0; 4212 + lft_desc_size = (lpfc_link_is_lds_capable(phba)) ? 4213 + sizeof(struct fc_diag_lnkflt_desc) : 0; 4214 + cmdsize = cgn_desc_size + lft_desc_size; 4215 + 4216 + /* Skip EDC if no applicable descriptors */ 4217 + if (!cmdsize) 4244 4218 goto try_rdf; 4245 4219 4246 - edc_req_size = sizeof(struct fc_els_edc); 4247 - cgn_desc_size = sizeof(struct fc_diag_cg_sig_desc); 4248 - cmdsize = edc_req_size + cgn_desc_size; 4220 + cmdsize += sizeof(struct fc_els_edc); 4249 4221 elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp, 4250 4222 ndlp->nlp_DID, ELS_CMD_EDC); 4251 4223 if (!elsiocb) ··· 4258 4222 /* Configure the payload for the supported Diagnostics capabilities. */ 4259 4223 pcmd = (u8 *)elsiocb->cmd_dmabuf->virt; 4260 4224 memset(pcmd, 0, cmdsize); 4261 - edc_req = (struct lpfc_els_edc_req *)pcmd; 4262 - edc_req->edc.desc_len = cpu_to_be32(cgn_desc_size); 4263 - edc_req->edc.edc_cmd = ELS_EDC; 4225 + edc_req = (struct fc_els_edc *)pcmd; 4226 + edc_req->desc_len = cpu_to_be32(cgn_desc_size + lft_desc_size); 4227 + edc_req->edc_cmd = ELS_EDC; 4228 + tlv = edc_req->desc; 4264 4229 4265 - cgn_desc = &edc_req->cgn_desc; 4230 + if (cgn_desc_size) { 4231 + lpfc_format_edc_cgn_desc(phba, tlv); 4232 + phba->cgn_sig_freq = lpfc_fabric_cgn_frequency; 4233 + tlv = fc_tlv_next_desc(tlv); 4234 + } 4266 4235 4267 - lpfc_format_edc_cgn_desc(phba, cgn_desc); 4268 - 4269 - phba->cgn_sig_freq = lpfc_fabric_cgn_frequency; 4236 + if (lft_desc_size) 4237 + lpfc_format_edc_lft_desc(phba, tlv); 4270 4238 4271 4239 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS | LOG_CGN_MGMT, 4272 4240 "4623 Xmit EDC to remote " ··· 4716 4676 } 4717 4677 switch (stat.un.b.lsRjtRsnCode) { 4718 4678 case LSRJT_UNABLE_TPC: 4719 - /* The driver has a VALID PLOGI but the rport has 4720 - * rejected the PRLI - can't do it now. Delay 4721 - * for 1 second and try again. 4722 - * 4723 - * However, if explanation is REQ_UNSUPPORTED there's 4724 - * no point to retry PRLI. 4679 + /* Special case for PRLI LS_RJTs. Recall that lpfc 4680 + * uses a single routine to issue both PRLI FC4 types. 4681 + * If the PRLI is rejected because that FC4 type 4682 + * isn't really supported, don't retry and cause 4683 + * multiple transport registrations. Otherwise, parse 4684 + * the reason code/reason code explanation and take the 4685 + * appropriate action. 4725 4686 */ 4726 - if ((cmd == ELS_CMD_PRLI || cmd == ELS_CMD_NVMEPRLI) && 4727 - stat.un.b.lsRjtRsnCodeExp != 4728 - LSEXP_REQ_UNSUPPORTED) { 4729 - delay = 1000; 4730 - maxretry = lpfc_max_els_tries + 1; 4687 + lpfc_printf_vlog(vport, KERN_INFO, 4688 + LOG_DISCOVERY | LOG_ELS | LOG_NODE, 4689 + "0153 ELS cmd x%x LS_RJT by x%x. " 4690 + "RsnCode x%x RsnCodeExp x%x\n", 4691 + cmd, did, stat.un.b.lsRjtRsnCode, 4692 + stat.un.b.lsRjtRsnCodeExp); 4693 + 4694 + switch (stat.un.b.lsRjtRsnCodeExp) { 4695 + case LSEXP_CANT_GIVE_DATA: 4696 + case LSEXP_CMD_IN_PROGRESS: 4697 + if (cmd == ELS_CMD_PLOGI) { 4698 + delay = 1000; 4699 + maxretry = 48; 4700 + } 4731 4701 retry = 1; 4702 + break; 4703 + case LSEXP_REQ_UNSUPPORTED: 4704 + case LSEXP_NO_RSRC_ASSIGN: 4705 + /* These explanation codes get no retry. */ 4706 + if (cmd == ELS_CMD_PRLI || 4707 + cmd == ELS_CMD_NVMEPRLI) 4708 + break; 4709 + fallthrough; 4710 + default: 4711 + /* Limit the delay and retry action to a limited 4712 + * cmd set. There are other ELS commands where 4713 + * a retry is not expected. 4714 + */ 4715 + if (cmd == ELS_CMD_PLOGI || 4716 + cmd == ELS_CMD_PRLI || 4717 + cmd == ELS_CMD_NVMEPRLI) { 4718 + delay = 1000; 4719 + maxretry = lpfc_max_els_tries + 1; 4720 + retry = 1; 4721 + } 4732 4722 break; 4733 4723 } 4734 4724 4735 - /* Legacy bug fix code for targets with PLOGI delays. */ 4736 - if (stat.un.b.lsRjtRsnCodeExp == 4737 - LSEXP_CMD_IN_PROGRESS) { 4738 - if (cmd == ELS_CMD_PLOGI) { 4739 - delay = 1000; 4740 - maxretry = 48; 4741 - } 4742 - retry = 1; 4743 - break; 4744 - } 4745 - if (stat.un.b.lsRjtRsnCodeExp == 4746 - LSEXP_CANT_GIVE_DATA) { 4747 - if (cmd == ELS_CMD_PLOGI) { 4748 - delay = 1000; 4749 - maxretry = 48; 4750 - } 4751 - retry = 1; 4752 - break; 4753 - } 4754 - if (cmd == ELS_CMD_PLOGI) { 4755 - delay = 1000; 4756 - maxretry = lpfc_max_els_tries + 1; 4757 - retry = 1; 4758 - break; 4759 - } 4760 4725 if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) && 4761 4726 (cmd == ELS_CMD_FDISC) && 4762 4727 (stat.un.b.lsRjtRsnCodeExp == LSEXP_OUT_OF_RESOURCE)){ ··· 4842 4797 */ 4843 4798 if (stat.un.b.lsRjtRsnCodeExp == 4844 4799 LSEXP_REQ_UNSUPPORTED) { 4845 - if (cmd == ELS_CMD_PRLI) { 4846 - spin_lock_irq(&ndlp->lock); 4847 - ndlp->nlp_flag |= NLP_FCP_PRLI_RJT; 4848 - spin_unlock_irq(&ndlp->lock); 4849 - retry = 0; 4800 + if (cmd == ELS_CMD_PRLI) 4850 4801 goto out_retry; 4851 - } 4852 4802 } 4853 4803 break; 4854 4804 } ··· 5824 5784 struct lpfc_nodelist *ndlp) 5825 5785 { 5826 5786 struct lpfc_hba *phba = vport->phba; 5827 - struct lpfc_els_edc_rsp *edc_rsp; 5787 + struct fc_els_edc_resp *edc_rsp; 5788 + struct fc_tlv_desc *tlv; 5828 5789 struct lpfc_iocbq *elsiocb; 5829 5790 IOCB_t *icmd, *cmd; 5830 5791 union lpfc_wqe128 *wqe; 5792 + u32 cgn_desc_size, lft_desc_size; 5793 + u16 cmdsize; 5831 5794 uint8_t *pcmd; 5832 - int cmdsize, rc; 5795 + int rc; 5833 5796 5834 - cmdsize = sizeof(struct lpfc_els_edc_rsp); 5797 + cmdsize = sizeof(struct fc_els_edc_resp); 5798 + cgn_desc_size = sizeof(struct fc_diag_cg_sig_desc); 5799 + lft_desc_size = (lpfc_link_is_lds_capable(phba)) ? 5800 + sizeof(struct fc_diag_lnkflt_desc) : 0; 5801 + cmdsize += cgn_desc_size + lft_desc_size; 5835 5802 elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, cmdiocb->retry, 5836 5803 ndlp, ndlp->nlp_DID, ELS_CMD_ACC); 5837 5804 if (!elsiocb) ··· 5860 5813 pcmd = elsiocb->cmd_dmabuf->virt; 5861 5814 memset(pcmd, 0, cmdsize); 5862 5815 5863 - edc_rsp = (struct lpfc_els_edc_rsp *)pcmd; 5864 - edc_rsp->edc_rsp.acc_hdr.la_cmd = ELS_LS_ACC; 5865 - edc_rsp->edc_rsp.desc_list_len = cpu_to_be32( 5866 - FC_TLV_DESC_LENGTH_FROM_SZ(struct lpfc_els_edc_rsp)); 5867 - edc_rsp->edc_rsp.lsri.desc_tag = cpu_to_be32(ELS_DTAG_LS_REQ_INFO); 5868 - edc_rsp->edc_rsp.lsri.desc_len = cpu_to_be32( 5816 + edc_rsp = (struct fc_els_edc_resp *)pcmd; 5817 + edc_rsp->acc_hdr.la_cmd = ELS_LS_ACC; 5818 + edc_rsp->desc_list_len = cpu_to_be32(sizeof(struct fc_els_lsri_desc) + 5819 + cgn_desc_size + lft_desc_size); 5820 + edc_rsp->lsri.desc_tag = cpu_to_be32(ELS_DTAG_LS_REQ_INFO); 5821 + edc_rsp->lsri.desc_len = cpu_to_be32( 5869 5822 FC_TLV_DESC_LENGTH_FROM_SZ(struct fc_els_lsri_desc)); 5870 - edc_rsp->edc_rsp.lsri.rqst_w0.cmd = ELS_EDC; 5871 - lpfc_format_edc_cgn_desc(phba, &edc_rsp->cgn_desc); 5823 + edc_rsp->lsri.rqst_w0.cmd = ELS_EDC; 5824 + tlv = edc_rsp->desc; 5825 + lpfc_format_edc_cgn_desc(phba, tlv); 5826 + tlv = fc_tlv_next_desc(tlv); 5827 + if (lft_desc_size) 5828 + lpfc_format_edc_lft_desc(phba, tlv); 5872 5829 5873 5830 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP, 5874 5831 "Issue EDC ACC: did:x%x flg:x%x refcnt %d", ··· 6057 6006 if (prli_fc4_req == PRLI_FCP_TYPE) { 6058 6007 cmdsize = sizeof(uint32_t) + sizeof(PRLI); 6059 6008 elsrspcmd = (ELS_CMD_ACC | (ELS_CMD_PRLI & ~ELS_RSP_MASK)); 6060 - } else if (prli_fc4_req & PRLI_NVME_TYPE) { 6009 + } else if (prli_fc4_req == PRLI_NVME_TYPE) { 6061 6010 cmdsize = sizeof(uint32_t) + sizeof(struct lpfc_nvme_prli); 6062 6011 elsrspcmd = (ELS_CMD_ACC | (ELS_CMD_NVMEPRLI & ~ELS_RSP_MASK)); 6063 6012 } else { ··· 6120 6069 npr->ConfmComplAllowed = 1; 6121 6070 npr->prliType = PRLI_FCP_TYPE; 6122 6071 npr->initiatorFunc = 1; 6123 - } else if (prli_fc4_req & PRLI_NVME_TYPE) { 6072 + } else if (prli_fc4_req == PRLI_NVME_TYPE) { 6124 6073 /* Respond with an NVME PRLI Type */ 6125 6074 npr_nvme = (struct lpfc_nvme_prli *) pcmd; 6126 6075 bf_set(prli_type_code, npr_nvme, PRLI_NVME_TYPE); ··· 9137 9086 uint32_t *ptr, dtag; 9138 9087 const char *dtag_nm; 9139 9088 int desc_cnt = 0, bytes_remain; 9140 - bool rcv_cap_desc = false; 9089 + struct fc_diag_lnkflt_desc *plnkflt; 9141 9090 9142 9091 payload = cmdiocb->cmd_dmabuf->virt; 9143 9092 ··· 9145 9094 bytes_remain = be32_to_cpu(edc_req->desc_len); 9146 9095 9147 9096 ptr = (uint32_t *)payload; 9148 - lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS | LOG_CGN_MGMT, 9097 + lpfc_printf_vlog(vport, KERN_INFO, 9098 + LOG_ELS | LOG_CGN_MGMT | LOG_LDS_EVENT, 9149 9099 "3319 Rcv EDC payload len %d: x%x x%x x%x\n", 9150 9100 bytes_remain, be32_to_cpu(*ptr), 9151 9101 be32_to_cpu(*(ptr + 1)), be32_to_cpu(*(ptr + 2))); ··· 9165 9113 * cycle through EDC diagnostic descriptors to find the 9166 9114 * congestion signaling capability descriptor 9167 9115 */ 9168 - while (bytes_remain && !rcv_cap_desc) { 9116 + while (bytes_remain) { 9169 9117 if (bytes_remain < FC_TLV_DESC_HDR_SZ) { 9170 - lpfc_printf_log(phba, KERN_WARNING, LOG_CGN_MGMT, 9118 + lpfc_printf_log(phba, KERN_WARNING, 9119 + LOG_ELS | LOG_CGN_MGMT | LOG_LDS_EVENT, 9171 9120 "6464 Truncated TLV hdr on " 9172 9121 "Diagnostic descriptor[%d]\n", 9173 9122 desc_cnt); ··· 9181 9128 if (bytes_remain < FC_TLV_DESC_SZ_FROM_LENGTH(tlv) || 9182 9129 FC_TLV_DESC_SZ_FROM_LENGTH(tlv) != 9183 9130 sizeof(struct fc_diag_lnkflt_desc)) { 9184 - lpfc_printf_log( 9185 - phba, KERN_WARNING, LOG_CGN_MGMT, 9131 + lpfc_printf_log(phba, KERN_WARNING, 9132 + LOG_ELS | LOG_CGN_MGMT | LOG_LDS_EVENT, 9186 9133 "6465 Truncated Link Fault Diagnostic " 9187 9134 "descriptor[%d]: %d vs 0x%zx 0x%zx\n", 9188 9135 desc_cnt, bytes_remain, 9189 9136 FC_TLV_DESC_SZ_FROM_LENGTH(tlv), 9190 - sizeof(struct fc_diag_cg_sig_desc)); 9137 + sizeof(struct fc_diag_lnkflt_desc)); 9191 9138 goto out; 9192 9139 } 9193 - /* No action for Link Fault descriptor for now */ 9140 + plnkflt = (struct fc_diag_lnkflt_desc *)tlv; 9141 + lpfc_printf_log(phba, KERN_INFO, 9142 + LOG_ELS | LOG_LDS_EVENT, 9143 + "4626 Link Fault Desc Data: x%08x len x%x " 9144 + "da x%x dd x%x interval x%x\n", 9145 + be32_to_cpu(plnkflt->desc_tag), 9146 + be32_to_cpu(plnkflt->desc_len), 9147 + be32_to_cpu( 9148 + plnkflt->degrade_activate_threshold), 9149 + be32_to_cpu( 9150 + plnkflt->degrade_deactivate_threshold), 9151 + be32_to_cpu(plnkflt->fec_degrade_interval)); 9194 9152 break; 9195 9153 case ELS_DTAG_CG_SIGNAL_CAP: 9196 9154 if (bytes_remain < FC_TLV_DESC_SZ_FROM_LENGTH(tlv) || ··· 9228 9164 9229 9165 lpfc_least_capable_settings( 9230 9166 phba, (struct fc_diag_cg_sig_desc *)tlv); 9231 - rcv_cap_desc = true; 9232 9167 break; 9233 9168 default: 9234 9169 dtag_nm = lpfc_get_tlv_dtag_nm(dtag); 9235 - lpfc_printf_log(phba, KERN_WARNING, LOG_CGN_MGMT, 9170 + lpfc_printf_log(phba, KERN_WARNING, 9171 + LOG_ELS | LOG_CGN_MGMT | LOG_LDS_EVENT, 9236 9172 "6467 unknown Diagnostic " 9237 9173 "Descriptor[%d]: tag x%x (%s)\n", 9238 9174 desc_cnt, dtag, dtag_nm);
+18 -23
drivers/scsi/lpfc/lpfc_hbadisc.c
··· 1242 1242 phba->trunk_link.link1.state = 0; 1243 1243 phba->trunk_link.link2.state = 0; 1244 1244 phba->trunk_link.link3.state = 0; 1245 + phba->trunk_link.phy_lnk_speed = 1246 + LPFC_LINK_SPEED_UNKNOWN; 1245 1247 phba->sli4_hba.link_state.logical_speed = 1246 1248 LPFC_LINK_SPEED_UNKNOWN; 1247 1249 } ··· 1355 1353 FCH_EVT_LINKUP, 0); 1356 1354 1357 1355 spin_lock_irq(shost->host_lock); 1358 - vport->fc_flag &= ~(FC_PT2PT | FC_PT2PT_PLOGI | FC_ABORT_DISCOVERY | 1359 - FC_RSCN_MODE | FC_NLP_MORE | FC_RSCN_DISCOVERY); 1356 + if (phba->defer_flogi_acc_flag) 1357 + vport->fc_flag &= ~(FC_ABORT_DISCOVERY | FC_RSCN_MODE | 1358 + FC_NLP_MORE | FC_RSCN_DISCOVERY); 1359 + else 1360 + vport->fc_flag &= ~(FC_PT2PT | FC_PT2PT_PLOGI | 1361 + FC_ABORT_DISCOVERY | FC_RSCN_MODE | 1362 + FC_NLP_MORE | FC_RSCN_DISCOVERY); 1360 1363 vport->fc_flag |= FC_NDISC_ACTIVE; 1361 1364 vport->fc_ns_retry = 0; 1362 1365 spin_unlock_irq(shost->host_lock); ··· 1399 1392 1400 1393 /* reinitialize initial HBA flag */ 1401 1394 phba->hba_flag &= ~(HBA_FLOGI_ISSUED | HBA_RHBA_CMPL); 1402 - phba->defer_flogi_acc_flag = false; 1403 1395 1404 1396 return 0; 1405 1397 } ··· 2970 2964 uint32_t boot_flag, addr_mode; 2971 2965 uint16_t next_fcf_index, fcf_index; 2972 2966 uint16_t current_fcf_index; 2973 - uint16_t vlan_id; 2967 + uint16_t vlan_id = LPFC_FCOE_NULL_VID; 2974 2968 int rc; 2975 2969 2976 2970 /* If link state is not up, stop the roundrobin failover process */ ··· 3075 3069 struct fcf_record *new_fcf_record; 3076 3070 uint32_t boot_flag, addr_mode; 3077 3071 uint16_t fcf_index, next_fcf_index; 3078 - uint16_t vlan_id; 3072 + uint16_t vlan_id = LPFC_FCOE_NULL_VID; 3079 3073 int rc; 3080 3074 3081 3075 /* If link state is not up, no need to proceed */ ··· 3796 3790 if (phba->cmf_active_mode != LPFC_CFG_OFF) 3797 3791 lpfc_cmf_signal_init(phba); 3798 3792 3793 + if (phba->lmt & LMT_64Gb) 3794 + lpfc_read_lds_params(phba); 3795 + 3799 3796 } else if (attn_type == LPFC_ATT_LINK_DOWN || 3800 3797 attn_type == LPFC_ATT_UNEXP_WWPN) { 3801 3798 phba->fc_stat.LinkDown++; ··· 4398 4389 rc = lpfc_issue_els_edc(vport, 0); 4399 4390 lpfc_printf_log(phba, KERN_INFO, 4400 4391 LOG_INIT | LOG_ELS | LOG_DISCOVERY, 4401 - "4220 EDC issue error x%x, Data: x%x\n", 4392 + "4220 Issue EDC status x%x Data x%x\n", 4402 4393 rc, phba->cgn_init_reg_signal); 4394 + } else if (phba->lmt & LMT_64Gb) { 4395 + /* may send link fault capability descriptor */ 4396 + lpfc_issue_els_edc(vport, 0); 4403 4397 } else { 4404 4398 lpfc_issue_els_rdf(vport, 0); 4405 4399 } ··· 4800 4788 new_state == NLP_STE_UNMAPPED_NODE) 4801 4789 lpfc_nlp_reg_node(vport, ndlp); 4802 4790 4803 - if ((new_state == NLP_STE_MAPPED_NODE) && 4804 - (vport->stat_data_enabled)) { 4805 - /* 4806 - * A new target is discovered, if there is no buffer for 4807 - * statistical data collection allocate buffer. 4808 - */ 4809 - ndlp->lat_data = kcalloc(LPFC_MAX_BUCKET_COUNT, 4810 - sizeof(struct lpfc_scsicmd_bkt), 4811 - GFP_KERNEL); 4812 - 4813 - if (!ndlp->lat_data) 4814 - lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT, 4815 - "0286 lpfc_nlp_state_cleanup failed to " 4816 - "allocate statistical data buffer DID " 4817 - "0x%x\n", ndlp->nlp_DID); 4818 - } 4819 4791 /* 4820 4792 * If the node just added to Mapped list was an FCP target, 4821 4793 * but the remote port registration failed or assigned a target ··· 6644 6648 ndlp->fc4_xpt_flags = 0; 6645 6649 6646 6650 /* free ndlp memory for final ndlp release */ 6647 - kfree(ndlp->lat_data); 6648 6651 if (ndlp->phba->sli_rev == LPFC_SLI_REV4) 6649 6652 mempool_free(ndlp->active_rrqs_xri_bitmap, 6650 6653 ndlp->phba->active_rrq_pool);
+43 -16
drivers/scsi/lpfc/lpfc_hw.h
··· 703 703 #define LSEXP_OUT_OF_RESOURCE 0x29 704 704 #define LSEXP_CANT_GIVE_DATA 0x2A 705 705 #define LSEXP_REQ_UNSUPPORTED 0x2C 706 + #define LSEXP_NO_RSRC_ASSIGN 0x52 706 707 uint8_t vendorUnique; /* FC Word 0, bit 0: 7 */ 707 708 } b; 708 709 } un; ··· 1442 1441 1443 1442 /* Definitions for HBA / Port attribute entries */ 1444 1443 1445 - /* Attribute Entry */ 1446 - struct lpfc_fdmi_attr_entry { 1447 - union { 1448 - uint32_t AttrInt; 1449 - uint8_t AttrTypes[32]; 1450 - uint8_t AttrString[256]; 1451 - struct lpfc_name AttrWWN; 1452 - } un; 1444 + /* Attribute Entry Structures */ 1445 + 1446 + struct lpfc_fdmi_attr_u32 { 1447 + __be16 type; 1448 + __be16 len; 1449 + __be32 value_u32; 1453 1450 }; 1454 1451 1455 - struct lpfc_fdmi_attr_def { /* Defined in TLV format */ 1456 - /* Structure is in Big Endian format */ 1457 - uint32_t AttrType:16; 1458 - uint32_t AttrLen:16; 1459 - /* Marks start of Value (ATTRIBUTE_ENTRY) */ 1460 - struct lpfc_fdmi_attr_entry AttrValue; 1461 - } __packed; 1452 + struct lpfc_fdmi_attr_wwn { 1453 + __be16 type; 1454 + __be16 len; 1455 + 1456 + /* Keep as u8[8] instead of __be64 to avoid accidental zero padding 1457 + * by compiler 1458 + */ 1459 + u8 name[8]; 1460 + }; 1461 + 1462 + struct lpfc_fdmi_attr_fullwwn { 1463 + __be16 type; 1464 + __be16 len; 1465 + 1466 + /* Keep as u8[8] instead of __be64 to avoid accidental zero padding 1467 + * by compiler 1468 + */ 1469 + u8 nname[8]; 1470 + u8 pname[8]; 1471 + }; 1472 + 1473 + struct lpfc_fdmi_attr_fc4types { 1474 + __be16 type; 1475 + __be16 len; 1476 + u8 value_types[32]; 1477 + }; 1478 + 1479 + struct lpfc_fdmi_attr_string { 1480 + __be16 type; 1481 + __be16 len; 1482 + char value_string[256]; 1483 + }; 1484 + 1485 + /* Maximum FDMI attribute length is Type+Len (4 bytes) + 256 byte string */ 1486 + #define FDMI_MAX_ATTRLEN sizeof(struct lpfc_fdmi_attr_string) 1462 1487 1463 1488 /* 1464 1489 * HBA Attribute Block 1465 1490 */ 1466 1491 struct lpfc_fdmi_attr_block { 1467 1492 uint32_t EntryCnt; /* Number of HBA attribute entries */ 1468 - struct lpfc_fdmi_attr_entry Entry; /* Variable-length array */ 1493 + /* Variable Length Attribute Entry TLV's follow */ 1469 1494 }; 1470 1495 1471 1496 /*
+15 -19
drivers/scsi/lpfc/lpfc_hw4.h
··· 738 738 #define lpfc_sliport_eqdelay_id_WORD word0 739 739 #define LPFC_SEC_TO_USEC 1000000 740 740 #define LPFC_SEC_TO_MSEC 1000 741 + #define LPFC_MSECS_TO_SECS(msecs) ((msecs) / 1000) 741 742 742 743 /* The following Registers apply to SLI4 if_type 0 UCNAs. They typically 743 744 * reside in BAR 2. ··· 3484 3483 3485 3484 #define LPFC_SET_UE_RECOVERY 0x10 3486 3485 #define LPFC_SET_MDS_DIAGS 0x12 3487 - #define LPFC_SET_CGN_SIGNAL 0x1f 3488 3486 #define LPFC_SET_DUAL_DUMP 0x1e 3487 + #define LPFC_SET_CGN_SIGNAL 0x1f 3489 3488 #define LPFC_SET_ENABLE_MI 0x21 3489 + #define LPFC_SET_LD_SIGNAL 0x23 3490 3490 #define LPFC_SET_ENABLE_CMF 0x24 3491 3491 struct lpfc_mbx_set_feature { 3492 3492 struct mbox_header header; ··· 3518 3516 #define lpfc_mbx_set_feature_cmf_SHIFT 0 3519 3517 #define lpfc_mbx_set_feature_cmf_MASK 0x00000001 3520 3518 #define lpfc_mbx_set_feature_cmf_WORD word6 3519 + #define lpfc_mbx_set_feature_lds_qry_SHIFT 0 3520 + #define lpfc_mbx_set_feature_lds_qry_MASK 0x00000001 3521 + #define lpfc_mbx_set_feature_lds_qry_WORD word6 3522 + #define LPFC_QUERY_LDS_OP 1 3521 3523 #define lpfc_mbx_set_feature_mi_SHIFT 0 3522 3524 #define lpfc_mbx_set_feature_mi_MASK 0x0000ffff 3523 3525 #define lpfc_mbx_set_feature_mi_WORD word6 3524 3526 #define lpfc_mbx_set_feature_milunq_SHIFT 16 3525 3527 #define lpfc_mbx_set_feature_milunq_MASK 0x0000ffff 3526 3528 #define lpfc_mbx_set_feature_milunq_WORD word6 3527 - uint32_t word7; 3529 + u32 word7; 3528 3530 #define lpfc_mbx_set_feature_UERP_SHIFT 0 3529 3531 #define lpfc_mbx_set_feature_UERP_MASK 0x0000ffff 3530 3532 #define lpfc_mbx_set_feature_UERP_WORD word7 ··· 3542 3536 #define lpfc_mbx_set_feature_CGN_acqe_freq_SHIFT 0 3543 3537 #define lpfc_mbx_set_feature_CGN_acqe_freq_MASK 0x000000ff 3544 3538 #define lpfc_mbx_set_feature_CGN_acqe_freq_WORD word8 3539 + u32 word9; 3540 + u32 word10; 3545 3541 }; 3546 3542 3547 3543 ··· 4321 4313 struct lpfc_acqe_sli { 4322 4314 uint32_t event_data1; 4323 4315 uint32_t event_data2; 4324 - uint32_t reserved; 4316 + uint32_t event_data3; 4325 4317 uint32_t trailer; 4326 4318 #define LPFC_SLI_EVENT_TYPE_PORT_ERROR 0x1 4327 4319 #define LPFC_SLI_EVENT_TYPE_OVER_TEMP 0x2 ··· 4334 4326 #define LPFC_SLI_EVENT_TYPE_MISCONF_FAWWN 0xF 4335 4327 #define LPFC_SLI_EVENT_TYPE_EEPROM_FAILURE 0x10 4336 4328 #define LPFC_SLI_EVENT_TYPE_CGN_SIGNAL 0x11 4329 + #define LPFC_SLI_EVENT_TYPE_RD_SIGNAL 0x12 4337 4330 }; 4338 4331 4339 4332 /* ··· 4807 4798 #define cmf_sync_cqid_WORD word11 4808 4799 uint32_t read_bytes; 4809 4800 uint32_t word13; 4801 + #define cmf_sync_period_SHIFT 16 4802 + #define cmf_sync_period_MASK 0x0000ffff 4803 + #define cmf_sync_period_WORD word13 4810 4804 uint32_t word14; 4811 4805 uint32_t word15; 4812 4806 }; ··· 5057 5045 { FPIN_CONGN_SEVERITY_WARNING, "Warning" }, \ 5058 5046 { FPIN_CONGN_SEVERITY_ERROR, "Alarm" }, \ 5059 5047 } 5060 - 5061 - /* EDC supports two descriptors. When allocated, it is the 5062 - * size of this structure plus each supported descriptor. 5063 - */ 5064 - struct lpfc_els_edc_req { 5065 - struct fc_els_edc edc; /* hdr up to descriptors */ 5066 - struct fc_diag_cg_sig_desc cgn_desc; /* 1st descriptor */ 5067 - }; 5068 - 5069 - /* Minimum structure defines for the EDC response. 5070 - * Balance is in buffer. 5071 - */ 5072 - struct lpfc_els_edc_rsp { 5073 - struct fc_els_edc_resp edc_rsp; /* hdr up to descriptors */ 5074 - struct fc_diag_cg_sig_desc cgn_desc; /* 1st descriptor */ 5075 - }; 5076 5048 5077 5049 /* Used for logging FPIN messages */ 5078 5050 #define LPFC_FPIN_WWPN_LINE_SZ 128
+226 -210
drivers/scsi/lpfc/lpfc_init.c
··· 325 325 prog_id_word = pmboxq->u.mb.un.varWords[7]; 326 326 327 327 /* Decode the Option rom version word to a readable string */ 328 - if (prg->dist < 4) 329 - dist = dist_char[prg->dist]; 328 + dist = dist_char[prg->dist]; 330 329 331 330 if ((prg->dist == 3) && (prg->num == 0)) 332 331 snprintf(phba->OptionROMVersion, 32, "%d.%d%d", ··· 2257 2258 return; 2258 2259 } 2259 2260 2261 + static void 2262 + lpfc_fill_vpd(struct lpfc_hba *phba, uint8_t *vpd, int length, int *pindex) 2263 + { 2264 + int i, j; 2265 + 2266 + while (length > 0) { 2267 + /* Look for Serial Number */ 2268 + if ((vpd[*pindex] == 'S') && (vpd[*pindex + 1] == 'N')) { 2269 + *pindex += 2; 2270 + i = vpd[*pindex]; 2271 + *pindex += 1; 2272 + j = 0; 2273 + length -= (3+i); 2274 + while (i--) { 2275 + phba->SerialNumber[j++] = vpd[(*pindex)++]; 2276 + if (j == 31) 2277 + break; 2278 + } 2279 + phba->SerialNumber[j] = 0; 2280 + continue; 2281 + } else if ((vpd[*pindex] == 'V') && (vpd[*pindex + 1] == '1')) { 2282 + phba->vpd_flag |= VPD_MODEL_DESC; 2283 + *pindex += 2; 2284 + i = vpd[*pindex]; 2285 + *pindex += 1; 2286 + j = 0; 2287 + length -= (3+i); 2288 + while (i--) { 2289 + phba->ModelDesc[j++] = vpd[(*pindex)++]; 2290 + if (j == 255) 2291 + break; 2292 + } 2293 + phba->ModelDesc[j] = 0; 2294 + continue; 2295 + } else if ((vpd[*pindex] == 'V') && (vpd[*pindex + 1] == '2')) { 2296 + phba->vpd_flag |= VPD_MODEL_NAME; 2297 + *pindex += 2; 2298 + i = vpd[*pindex]; 2299 + *pindex += 1; 2300 + j = 0; 2301 + length -= (3+i); 2302 + while (i--) { 2303 + phba->ModelName[j++] = vpd[(*pindex)++]; 2304 + if (j == 79) 2305 + break; 2306 + } 2307 + phba->ModelName[j] = 0; 2308 + continue; 2309 + } else if ((vpd[*pindex] == 'V') && (vpd[*pindex + 1] == '3')) { 2310 + phba->vpd_flag |= VPD_PROGRAM_TYPE; 2311 + *pindex += 2; 2312 + i = vpd[*pindex]; 2313 + *pindex += 1; 2314 + j = 0; 2315 + length -= (3+i); 2316 + while (i--) { 2317 + phba->ProgramType[j++] = vpd[(*pindex)++]; 2318 + if (j == 255) 2319 + break; 2320 + } 2321 + phba->ProgramType[j] = 0; 2322 + continue; 2323 + } else if ((vpd[*pindex] == 'V') && (vpd[*pindex + 1] == '4')) { 2324 + phba->vpd_flag |= VPD_PORT; 2325 + *pindex += 2; 2326 + i = vpd[*pindex]; 2327 + *pindex += 1; 2328 + j = 0; 2329 + length -= (3 + i); 2330 + while (i--) { 2331 + if ((phba->sli_rev == LPFC_SLI_REV4) && 2332 + (phba->sli4_hba.pport_name_sta == 2333 + LPFC_SLI4_PPNAME_GET)) { 2334 + j++; 2335 + (*pindex)++; 2336 + } else 2337 + phba->Port[j++] = vpd[(*pindex)++]; 2338 + if (j == 19) 2339 + break; 2340 + } 2341 + if ((phba->sli_rev != LPFC_SLI_REV4) || 2342 + (phba->sli4_hba.pport_name_sta == 2343 + LPFC_SLI4_PPNAME_NON)) 2344 + phba->Port[j] = 0; 2345 + continue; 2346 + } else { 2347 + *pindex += 2; 2348 + i = vpd[*pindex]; 2349 + *pindex += 1; 2350 + *pindex += i; 2351 + length -= (3 + i); 2352 + } 2353 + } 2354 + } 2355 + 2260 2356 /** 2261 2357 * lpfc_parse_vpd - Parse VPD (Vital Product Data) 2262 2358 * @phba: pointer to lpfc hba data structure. ··· 2371 2277 { 2372 2278 uint8_t lenlo, lenhi; 2373 2279 int Length; 2374 - int i, j; 2280 + int i; 2375 2281 int finished = 0; 2376 2282 int index = 0; 2377 2283 ··· 2404 2310 Length = ((((unsigned short)lenhi) << 8) + lenlo); 2405 2311 if (Length > len - index) 2406 2312 Length = len - index; 2407 - while (Length > 0) { 2408 - /* Look for Serial Number */ 2409 - if ((vpd[index] == 'S') && (vpd[index+1] == 'N')) { 2410 - index += 2; 2411 - i = vpd[index]; 2412 - index += 1; 2413 - j = 0; 2414 - Length -= (3+i); 2415 - while(i--) { 2416 - phba->SerialNumber[j++] = vpd[index++]; 2417 - if (j == 31) 2418 - break; 2419 - } 2420 - phba->SerialNumber[j] = 0; 2421 - continue; 2422 - } 2423 - else if ((vpd[index] == 'V') && (vpd[index+1] == '1')) { 2424 - phba->vpd_flag |= VPD_MODEL_DESC; 2425 - index += 2; 2426 - i = vpd[index]; 2427 - index += 1; 2428 - j = 0; 2429 - Length -= (3+i); 2430 - while(i--) { 2431 - phba->ModelDesc[j++] = vpd[index++]; 2432 - if (j == 255) 2433 - break; 2434 - } 2435 - phba->ModelDesc[j] = 0; 2436 - continue; 2437 - } 2438 - else if ((vpd[index] == 'V') && (vpd[index+1] == '2')) { 2439 - phba->vpd_flag |= VPD_MODEL_NAME; 2440 - index += 2; 2441 - i = vpd[index]; 2442 - index += 1; 2443 - j = 0; 2444 - Length -= (3+i); 2445 - while(i--) { 2446 - phba->ModelName[j++] = vpd[index++]; 2447 - if (j == 79) 2448 - break; 2449 - } 2450 - phba->ModelName[j] = 0; 2451 - continue; 2452 - } 2453 - else if ((vpd[index] == 'V') && (vpd[index+1] == '3')) { 2454 - phba->vpd_flag |= VPD_PROGRAM_TYPE; 2455 - index += 2; 2456 - i = vpd[index]; 2457 - index += 1; 2458 - j = 0; 2459 - Length -= (3+i); 2460 - while(i--) { 2461 - phba->ProgramType[j++] = vpd[index++]; 2462 - if (j == 255) 2463 - break; 2464 - } 2465 - phba->ProgramType[j] = 0; 2466 - continue; 2467 - } 2468 - else if ((vpd[index] == 'V') && (vpd[index+1] == '4')) { 2469 - phba->vpd_flag |= VPD_PORT; 2470 - index += 2; 2471 - i = vpd[index]; 2472 - index += 1; 2473 - j = 0; 2474 - Length -= (3+i); 2475 - while(i--) { 2476 - if ((phba->sli_rev == LPFC_SLI_REV4) && 2477 - (phba->sli4_hba.pport_name_sta == 2478 - LPFC_SLI4_PPNAME_GET)) { 2479 - j++; 2480 - index++; 2481 - } else 2482 - phba->Port[j++] = vpd[index++]; 2483 - if (j == 19) 2484 - break; 2485 - } 2486 - if ((phba->sli_rev != LPFC_SLI_REV4) || 2487 - (phba->sli4_hba.pport_name_sta == 2488 - LPFC_SLI4_PPNAME_NON)) 2489 - phba->Port[j] = 0; 2490 - continue; 2491 - } 2492 - else { 2493 - index += 2; 2494 - i = vpd[index]; 2495 - index += 1; 2496 - index += i; 2497 - Length -= (3 + i); 2498 - } 2499 - } 2500 - finished = 0; 2501 - break; 2313 + 2314 + lpfc_fill_vpd(phba, vpd, Length, &index); 2315 + finished = 0; 2316 + break; 2502 2317 case 0x78: 2503 2318 finished = 1; 2504 2319 break; ··· 4617 4614 return rol64(wwn, 32); 4618 4615 } 4619 4616 4617 + static unsigned short lpfc_get_sg_tablesize(struct lpfc_hba *phba) 4618 + { 4619 + if (phba->sli_rev == LPFC_SLI_REV4) 4620 + if (phba->cfg_xpsgl && !phba->nvmet_support) 4621 + return LPFC_MAX_SG_TABLESIZE; 4622 + else 4623 + return phba->cfg_scsi_seg_cnt; 4624 + else 4625 + return phba->cfg_sg_seg_cnt; 4626 + } 4627 + 4620 4628 /** 4621 4629 * lpfc_vmid_res_alloc - Allocates resources for VMID 4622 4630 * @phba: pointer to lpfc hba data structure. ··· 4730 4716 4731 4717 /* Seed template for SCSI host registration */ 4732 4718 if (dev == &phba->pcidev->dev) { 4733 - template = &phba->port_template; 4734 - 4735 4719 if (phba->cfg_enable_fc4_type & LPFC_ENABLE_FCP) { 4736 4720 /* Seed physical port template */ 4737 - memcpy(template, &lpfc_template, sizeof(*template)); 4721 + template = &lpfc_template; 4738 4722 4739 4723 if (use_no_reset_hba) 4740 4724 /* template is for a no reset SCSI Host */ 4741 4725 template->eh_host_reset_handler = NULL; 4742 4726 4743 - /* Template for all vports this physical port creates */ 4744 - memcpy(&phba->vport_template, &lpfc_template, 4745 - sizeof(*template)); 4746 - phba->vport_template.shost_groups = lpfc_vport_groups; 4747 - phba->vport_template.eh_bus_reset_handler = NULL; 4748 - phba->vport_template.eh_host_reset_handler = NULL; 4749 - phba->vport_template.vendor_id = 0; 4750 - 4751 - /* Initialize the host templates with updated value */ 4752 - if (phba->sli_rev == LPFC_SLI_REV4) { 4753 - template->sg_tablesize = phba->cfg_scsi_seg_cnt; 4754 - phba->vport_template.sg_tablesize = 4755 - phba->cfg_scsi_seg_cnt; 4756 - } else { 4757 - template->sg_tablesize = phba->cfg_sg_seg_cnt; 4758 - phba->vport_template.sg_tablesize = 4759 - phba->cfg_sg_seg_cnt; 4760 - } 4761 - 4727 + /* Seed updated value of sg_tablesize */ 4728 + template->sg_tablesize = lpfc_get_sg_tablesize(phba); 4762 4729 } else { 4763 4730 /* NVMET is for physical port only */ 4764 - memcpy(template, &lpfc_template_nvme, 4765 - sizeof(*template)); 4731 + template = &lpfc_template_nvme; 4766 4732 } 4767 4733 } else { 4768 - template = &phba->vport_template; 4734 + /* Seed vport template */ 4735 + template = &lpfc_vport_template; 4736 + 4737 + /* Seed updated value of sg_tablesize */ 4738 + template->sg_tablesize = lpfc_get_sg_tablesize(phba); 4769 4739 } 4770 4740 4771 4741 shost = scsi_host_alloc(template, sizeof(struct lpfc_vport)); ··· 4782 4784 4783 4785 shost->dma_boundary = 4784 4786 phba->sli4_hba.pc_sli4_params.sge_supp_len-1; 4785 - 4786 - if (phba->cfg_xpsgl && !phba->nvmet_support) 4787 - shost->sg_tablesize = LPFC_MAX_SG_TABLESIZE; 4788 - else 4789 - shost->sg_tablesize = phba->cfg_scsi_seg_cnt; 4790 4787 } else 4791 4788 /* SLI-3 has a limited number of hardware queues (3), 4792 4789 * thus there is only one for FCP processing. ··· 5562 5569 void 5563 5570 lpfc_cgn_dump_rxmonitor(struct lpfc_hba *phba) 5564 5571 { 5565 - struct rxtable_entry *entry; 5566 - int cnt = 0, head, tail, last, start; 5567 - 5568 - head = atomic_read(&phba->rxtable_idx_head); 5569 - tail = atomic_read(&phba->rxtable_idx_tail); 5570 - if (!phba->rxtable || head == tail) { 5571 - lpfc_printf_log(phba, KERN_ERR, LOG_CGN_MGMT, 5572 - "4411 Rxtable is empty\n"); 5573 - return; 5574 - } 5575 - last = tail; 5576 - start = head; 5577 - 5578 - /* Display the last LPFC_MAX_RXMONITOR_DUMP entries from the rxtable */ 5579 - while (start != last) { 5580 - if (start) 5581 - start--; 5582 - else 5583 - start = LPFC_MAX_RXMONITOR_ENTRY - 1; 5584 - entry = &phba->rxtable[start]; 5572 + if (!phba->rx_monitor) { 5585 5573 lpfc_printf_log(phba, KERN_INFO, LOG_CGN_MGMT, 5586 - "4410 %02d: MBPI %lld Xmit %lld Cmpl %lld " 5587 - "Lat %lld ASz %lld Info %02d BWUtil %d " 5588 - "Int %d slot %d\n", 5589 - cnt, entry->max_bytes_per_interval, 5590 - entry->total_bytes, entry->rcv_bytes, 5591 - entry->avg_io_latency, entry->avg_io_size, 5592 - entry->cmf_info, entry->timer_utilization, 5593 - entry->timer_interval, start); 5594 - cnt++; 5595 - if (cnt >= LPFC_MAX_RXMONITOR_DUMP) 5596 - return; 5574 + "4411 Rx Monitor Info is empty.\n"); 5575 + } else { 5576 + lpfc_rx_monitor_report(phba, phba->rx_monitor, NULL, 0, 5577 + LPFC_MAX_RXMONITOR_DUMP); 5597 5578 } 5598 5579 } 5599 5580 ··· 5974 6007 { 5975 6008 struct lpfc_hba *phba = container_of(timer, struct lpfc_hba, 5976 6009 cmf_timer); 5977 - struct rxtable_entry *entry; 6010 + struct rx_info_entry entry; 5978 6011 uint32_t io_cnt; 5979 - uint32_t head, tail; 5980 6012 uint32_t busy, max_read; 5981 6013 uint64_t total, rcv, lat, mbpi, extra, cnt; 5982 6014 int timer_interval = LPFC_CMF_INTERVAL; ··· 6095 6129 } 6096 6130 6097 6131 /* Save rxmonitor information for debug */ 6098 - if (phba->rxtable) { 6099 - head = atomic_xchg(&phba->rxtable_idx_head, 6100 - LPFC_RXMONITOR_TABLE_IN_USE); 6101 - entry = &phba->rxtable[head]; 6102 - entry->total_bytes = total; 6103 - entry->cmf_bytes = total + extra; 6104 - entry->rcv_bytes = rcv; 6105 - entry->cmf_busy = busy; 6106 - entry->cmf_info = phba->cmf_active_info; 6132 + if (phba->rx_monitor) { 6133 + entry.total_bytes = total; 6134 + entry.cmf_bytes = total + extra; 6135 + entry.rcv_bytes = rcv; 6136 + entry.cmf_busy = busy; 6137 + entry.cmf_info = phba->cmf_active_info; 6107 6138 if (io_cnt) { 6108 - entry->avg_io_latency = div_u64(lat, io_cnt); 6109 - entry->avg_io_size = div_u64(rcv, io_cnt); 6139 + entry.avg_io_latency = div_u64(lat, io_cnt); 6140 + entry.avg_io_size = div_u64(rcv, io_cnt); 6110 6141 } else { 6111 - entry->avg_io_latency = 0; 6112 - entry->avg_io_size = 0; 6142 + entry.avg_io_latency = 0; 6143 + entry.avg_io_size = 0; 6113 6144 } 6114 - entry->max_read_cnt = max_read; 6115 - entry->io_cnt = io_cnt; 6116 - entry->max_bytes_per_interval = mbpi; 6145 + entry.max_read_cnt = max_read; 6146 + entry.io_cnt = io_cnt; 6147 + entry.max_bytes_per_interval = mbpi; 6117 6148 if (phba->cmf_active_mode == LPFC_CFG_MANAGED) 6118 - entry->timer_utilization = phba->cmf_last_ts; 6149 + entry.timer_utilization = phba->cmf_last_ts; 6119 6150 else 6120 - entry->timer_utilization = ms; 6121 - entry->timer_interval = ms; 6151 + entry.timer_utilization = ms; 6152 + entry.timer_interval = ms; 6122 6153 phba->cmf_last_ts = 0; 6123 6154 6124 - /* Increment rxtable index */ 6125 - head = (head + 1) % LPFC_MAX_RXMONITOR_ENTRY; 6126 - tail = atomic_read(&phba->rxtable_idx_tail); 6127 - if (head == tail) { 6128 - tail = (tail + 1) % LPFC_MAX_RXMONITOR_ENTRY; 6129 - atomic_set(&phba->rxtable_idx_tail, tail); 6130 - } 6131 - atomic_set(&phba->rxtable_idx_head, head); 6155 + lpfc_rx_monitor_record(phba->rx_monitor, &entry); 6132 6156 } 6133 6157 6134 6158 if (phba->cmf_active_mode == LPFC_CFG_MONITOR) { ··· 6188 6232 { 6189 6233 uint8_t port_fault = bf_get(lpfc_acqe_fc_la_trunk_linkmask, acqe_fc); 6190 6234 uint8_t err = bf_get(lpfc_acqe_fc_la_trunk_fault, acqe_fc); 6235 + u8 cnt = 0; 6191 6236 6192 6237 phba->sli4_hba.link_state.speed = 6193 6238 lpfc_sli4_port_speed_parse(phba, LPFC_TRAILER_CODE_FC, ··· 6207 6250 bf_get(lpfc_acqe_fc_la_trunk_link_status_port0, acqe_fc) 6208 6251 ? LPFC_LINK_UP : LPFC_LINK_DOWN; 6209 6252 phba->trunk_link.link0.fault = port_fault & 0x1 ? err : 0; 6253 + cnt++; 6210 6254 } 6211 6255 if (bf_get(lpfc_acqe_fc_la_trunk_config_port1, acqe_fc)) { 6212 6256 phba->trunk_link.link1.state = 6213 6257 bf_get(lpfc_acqe_fc_la_trunk_link_status_port1, acqe_fc) 6214 6258 ? LPFC_LINK_UP : LPFC_LINK_DOWN; 6215 6259 phba->trunk_link.link1.fault = port_fault & 0x2 ? err : 0; 6260 + cnt++; 6216 6261 } 6217 6262 if (bf_get(lpfc_acqe_fc_la_trunk_config_port2, acqe_fc)) { 6218 6263 phba->trunk_link.link2.state = 6219 6264 bf_get(lpfc_acqe_fc_la_trunk_link_status_port2, acqe_fc) 6220 6265 ? LPFC_LINK_UP : LPFC_LINK_DOWN; 6221 6266 phba->trunk_link.link2.fault = port_fault & 0x4 ? err : 0; 6267 + cnt++; 6222 6268 } 6223 6269 if (bf_get(lpfc_acqe_fc_la_trunk_config_port3, acqe_fc)) { 6224 6270 phba->trunk_link.link3.state = 6225 6271 bf_get(lpfc_acqe_fc_la_trunk_link_status_port3, acqe_fc) 6226 6272 ? LPFC_LINK_UP : LPFC_LINK_DOWN; 6227 6273 phba->trunk_link.link3.fault = port_fault & 0x8 ? err : 0; 6274 + cnt++; 6228 6275 } 6276 + 6277 + if (cnt) 6278 + phba->trunk_link.phy_lnk_speed = 6279 + phba->sli4_hba.link_state.logical_speed / (cnt * 1000); 6280 + else 6281 + phba->trunk_link.phy_lnk_speed = LPFC_LINK_SPEED_UNKNOWN; 6229 6282 6230 6283 lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT, 6231 6284 "2910 Async FC Trunking Event - Speed:%d\n" ··· 6314 6347 if (bf_get(lpfc_acqe_fc_la_att_type, acqe_fc) == 6315 6348 LPFC_FC_LA_TYPE_LINK_DOWN) 6316 6349 phba->sli4_hba.link_state.logical_speed = 0; 6317 - else if (!phba->sli4_hba.conf_trunk) 6350 + else if (!phba->sli4_hba.conf_trunk) 6318 6351 phba->sli4_hba.link_state.logical_speed = 6319 6352 bf_get(lpfc_acqe_fc_la_llink_spd, acqe_fc) * 10; 6320 6353 ··· 6432 6465 "2901 Async SLI event - Type:%d, Event Data: x%08x " 6433 6466 "x%08x x%08x x%08x\n", evt_type, 6434 6467 acqe_sli->event_data1, acqe_sli->event_data2, 6435 - acqe_sli->reserved, acqe_sli->trailer); 6468 + acqe_sli->event_data3, acqe_sli->trailer); 6436 6469 6437 6470 port_name = phba->Port[0]; 6438 6471 if (port_name == 0x00) ··· 6461 6494 temp_event_data.event_code = LPFC_NORMAL_TEMP; 6462 6495 temp_event_data.data = (uint32_t)acqe_sli->event_data1; 6463 6496 6464 - lpfc_printf_log(phba, KERN_INFO, LOG_SLI, 6497 + lpfc_printf_log(phba, KERN_INFO, LOG_SLI | LOG_LDS_EVENT, 6465 6498 "3191 Normal Temperature:%d Celsius - Port Name %c\n", 6466 6499 acqe_sli->event_data1, port_name); 6467 6500 ··· 6638 6671 atomic_add(cnt, &phba->cgn_sync_warn_cnt); 6639 6672 } 6640 6673 } 6674 + break; 6675 + case LPFC_SLI_EVENT_TYPE_RD_SIGNAL: 6676 + /* May be accompanied by a temperature event */ 6677 + lpfc_printf_log(phba, KERN_INFO, 6678 + LOG_SLI | LOG_LINK_EVENT | LOG_LDS_EVENT, 6679 + "2902 Remote Degrade Signaling: x%08x x%08x " 6680 + "x%08x\n", 6681 + acqe_sli->event_data1, acqe_sli->event_data2, 6682 + acqe_sli->event_data3); 6641 6683 break; 6642 6684 default: 6643 6685 lpfc_printf_log(phba, KERN_INFO, LOG_SLI, ··· 7061 7085 spin_unlock_irq(&phba->hbalock); 7062 7086 } 7063 7087 7088 + static const char * const lpfc_cmf_mode_to_str[] = { 7089 + "OFF", 7090 + "MANAGED", 7091 + "MONITOR", 7092 + }; 7093 + 7064 7094 /** 7065 7095 * lpfc_cgn_params_parse - Process a FW cong parm change event 7066 7096 * @phba: pointer to lpfc hba data structure. ··· 7086 7104 { 7087 7105 struct lpfc_cgn_info *cp; 7088 7106 uint32_t crc, oldmode; 7107 + char acr_string[4] = {0}; 7089 7108 7090 7109 /* Make sure the FW has encoded the correct magic number to 7091 7110 * validate the congestion parameter in FW memory. ··· 7163 7180 lpfc_issue_els_edc(phba->pport, 0); 7164 7181 break; 7165 7182 case LPFC_CFG_MONITOR: 7166 - lpfc_printf_log(phba, KERN_INFO, LOG_CGN_MGMT, 7167 - "4661 Switch from MANAGED to " 7168 - "`MONITOR mode\n"); 7169 7183 phba->cmf_max_bytes_per_interval = 7170 7184 phba->cmf_link_byte_count; 7171 7185 ··· 7181 7201 lpfc_issue_els_edc(phba->pport, 0); 7182 7202 break; 7183 7203 case LPFC_CFG_MANAGED: 7184 - lpfc_printf_log(phba, KERN_INFO, LOG_CGN_MGMT, 7185 - "4662 Switch from MONITOR to " 7186 - "MANAGED mode\n"); 7187 7204 lpfc_cmf_signal_init(phba); 7188 7205 break; 7189 7206 } 7190 7207 break; 7208 + } 7209 + if (oldmode != LPFC_CFG_OFF || 7210 + oldmode != phba->cgn_p.cgn_param_mode) { 7211 + if (phba->cgn_p.cgn_param_mode == LPFC_CFG_MANAGED) 7212 + scnprintf(acr_string, sizeof(acr_string), "%u", 7213 + phba->cgn_p.cgn_param_level0); 7214 + else 7215 + scnprintf(acr_string, sizeof(acr_string), "NA"); 7216 + 7217 + dev_info(&phba->pcidev->dev, "%d: " 7218 + "4663 CMF: Mode %s acr %s\n", 7219 + phba->brd_no, 7220 + lpfc_cmf_mode_to_str 7221 + [phba->cgn_p.cgn_param_mode], 7222 + acr_string); 7191 7223 } 7192 7224 } else { 7193 7225 lpfc_printf_log(phba, KERN_ERR, LOG_CGN_MGMT | LOG_INIT, ··· 8307 8315 &phba->pcidev->dev, 8308 8316 phba->cfg_sg_dma_buf_size, 8309 8317 i, 0); 8310 - if (!phba->lpfc_sg_dma_buf_pool) 8318 + if (!phba->lpfc_sg_dma_buf_pool) { 8319 + rc = -ENOMEM; 8311 8320 goto out_free_bsmbx; 8321 + } 8312 8322 8313 8323 phba->lpfc_cmd_rsp_buf_pool = 8314 8324 dma_pool_create("lpfc_cmd_rsp_buf_pool", ··· 8318 8324 sizeof(struct fcp_cmnd) + 8319 8325 sizeof(struct fcp_rsp), 8320 8326 i, 0); 8321 - if (!phba->lpfc_cmd_rsp_buf_pool) 8327 + if (!phba->lpfc_cmd_rsp_buf_pool) { 8328 + rc = -ENOMEM; 8322 8329 goto out_free_sg_dma_buf; 8330 + } 8323 8331 8324 8332 mempool_free(mboxq, phba->mbox_mem_pool); 8325 8333 ··· 12412 12416 12413 12417 for (i = 0; i < phba->cfg_irq_chann; i++) { 12414 12418 eqhdl = lpfc_get_eq_hdl(i); 12415 - eqhdl->irq = LPFC_VECTOR_MAP_EMPTY; 12419 + eqhdl->irq = LPFC_IRQ_EMPTY; 12416 12420 eqhdl->phba = phba; 12417 12421 } 12418 12422 } ··· 12785 12789 12786 12790 static void lpfc_cpuhp_remove(struct lpfc_hba *phba) 12787 12791 { 12788 - if (phba->pport->fc_flag & FC_OFFLINE_MODE) 12792 + if (phba->pport && (phba->pport->fc_flag & FC_OFFLINE_MODE)) 12789 12793 return; 12790 12794 12791 12795 __lpfc_cpuhp_remove(phba); ··· 13049 13053 LPFC_DRIVER_HANDLER_NAME"%d", index); 13050 13054 13051 13055 eqhdl->idx = index; 13052 - rc = request_irq(pci_irq_vector(phba->pcidev, index), 13053 - &lpfc_sli4_hba_intr_handler, 0, 13054 - name, eqhdl); 13056 + rc = pci_irq_vector(phba->pcidev, index); 13057 + if (rc < 0) { 13058 + lpfc_printf_log(phba, KERN_WARNING, LOG_INIT, 13059 + "0489 MSI-X fast-path (%d) " 13060 + "pci_irq_vec failed (%d)\n", index, rc); 13061 + goto cfg_fail_out; 13062 + } 13063 + eqhdl->irq = rc; 13064 + 13065 + rc = request_irq(eqhdl->irq, &lpfc_sli4_hba_intr_handler, 0, 13066 + name, eqhdl); 13055 13067 if (rc) { 13056 13068 lpfc_printf_log(phba, KERN_WARNING, LOG_INIT, 13057 13069 "0486 MSI-X fast-path (%d) " 13058 13070 "request_irq failed (%d)\n", index, rc); 13059 13071 goto cfg_fail_out; 13060 13072 } 13061 - 13062 - eqhdl->irq = pci_irq_vector(phba->pcidev, index); 13063 13073 13064 13074 if (aff_mask) { 13065 13075 /* If found a neighboring online cpu, set affinity */ ··· 13183 13181 } 13184 13182 13185 13183 eqhdl = lpfc_get_eq_hdl(0); 13186 - eqhdl->irq = pci_irq_vector(phba->pcidev, 0); 13184 + rc = pci_irq_vector(phba->pcidev, 0); 13185 + if (rc < 0) { 13186 + pci_free_irq_vectors(phba->pcidev); 13187 + lpfc_printf_log(phba, KERN_WARNING, LOG_INIT, 13188 + "0496 MSI pci_irq_vec failed (%d)\n", rc); 13189 + return rc; 13190 + } 13191 + eqhdl->irq = rc; 13187 13192 13188 13193 cpu = cpumask_first(cpu_present_mask); 13189 13194 lpfc_assign_eq_map_info(phba, 0, LPFC_CPU_FIRST_IRQ, cpu); ··· 13217 13208 * MSI-X -> MSI -> IRQ. 13218 13209 * 13219 13210 * Return codes 13220 - * 0 - successful 13221 - * other values - error 13211 + * Interrupt mode (2, 1, 0) - successful 13212 + * LPFC_INTR_ERROR - error 13222 13213 **/ 13223 13214 static uint32_t 13224 13215 lpfc_sli4_enable_intr(struct lpfc_hba *phba, uint32_t cfg_mode) ··· 13263 13254 intr_mode = 0; 13264 13255 13265 13256 eqhdl = lpfc_get_eq_hdl(0); 13266 - eqhdl->irq = pci_irq_vector(phba->pcidev, 0); 13257 + retval = pci_irq_vector(phba->pcidev, 0); 13258 + if (retval < 0) { 13259 + lpfc_printf_log(phba, KERN_WARNING, LOG_INIT, 13260 + "0502 INTR pci_irq_vec failed (%d)\n", 13261 + retval); 13262 + return LPFC_INTR_ERROR; 13263 + } 13264 + eqhdl->irq = retval; 13267 13265 13268 13266 cpu = cpumask_first(cpu_present_mask); 13269 13267 lpfc_assign_eq_map_info(phba, 0, LPFC_CPU_FIRST_IRQ,
+1 -1
drivers/scsi/lpfc/lpfc_logmsg.h
··· 35 35 #define LOG_FCP_ERROR 0x00001000 /* log errors, not underruns */ 36 36 #define LOG_LIBDFC 0x00002000 /* Libdfc events */ 37 37 #define LOG_VPORT 0x00004000 /* NPIV events */ 38 - #define LOG_SECURITY 0x00008000 /* Security events */ 38 + #define LOG_LDS_EVENT 0x00008000 /* Link Degrade Signaling events */ 39 39 #define LOG_EVENT 0x00010000 /* CT,TEMP,DUMP, logging */ 40 40 #define LOG_FIP 0x00020000 /* FIP events */ 41 41 #define LOG_FCP_UNDER 0x00040000 /* FCP underruns errors */
+7 -4
drivers/scsi/lpfc/lpfc_mem.c
··· 1 1 /******************************************************************* 2 2 * This file is part of the Emulex Linux Device Driver for * 3 3 * Fibre Channel Host Bus Adapters. * 4 - * Copyright (C) 2017-2021 Broadcom. All Rights Reserved. The term * 4 + * Copyright (C) 2017-2022 Broadcom. All Rights Reserved. The term * 5 5 * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. * 6 6 * Copyright (C) 2004-2014 Emulex. All rights reserved. * 7 7 * EMULEX and SLI are trademarks of Emulex. * ··· 344 344 phba->cgn_i = NULL; 345 345 } 346 346 347 - /* Free RX table */ 348 - kfree(phba->rxtable); 349 - phba->rxtable = NULL; 347 + /* Free RX Monitor */ 348 + if (phba->rx_monitor) { 349 + lpfc_rx_monitor_destroy_ring(phba->rx_monitor); 350 + kfree(phba->rx_monitor); 351 + phba->rx_monitor = NULL; 352 + } 350 353 351 354 /* Free the iocb lookup array */ 352 355 kfree(psli->iocbq_lookup);
+27 -59
drivers/scsi/lpfc/lpfc_scsi.c
··· 112 112 #define LPFC_INVALID_REFTAG ((u32)-1) 113 113 114 114 /** 115 - * lpfc_update_stats - Update statistical data for the command completion 116 - * @vport: The virtual port on which this call is executing. 117 - * @lpfc_cmd: lpfc scsi command object pointer. 118 - * 119 - * This function is called when there is a command completion and this 120 - * function updates the statistical data for the command completion. 121 - **/ 122 - static void 123 - lpfc_update_stats(struct lpfc_vport *vport, struct lpfc_io_buf *lpfc_cmd) 124 - { 125 - struct lpfc_hba *phba = vport->phba; 126 - struct lpfc_rport_data *rdata; 127 - struct lpfc_nodelist *pnode; 128 - struct scsi_cmnd *cmd = lpfc_cmd->pCmd; 129 - unsigned long flags; 130 - struct Scsi_Host *shost = lpfc_shost_from_vport(vport); 131 - unsigned long latency; 132 - int i; 133 - 134 - if (!vport->stat_data_enabled || 135 - vport->stat_data_blocked || 136 - (cmd->result)) 137 - return; 138 - 139 - latency = jiffies_to_msecs((long)jiffies - (long)lpfc_cmd->start_time); 140 - rdata = lpfc_cmd->rdata; 141 - pnode = rdata->pnode; 142 - 143 - spin_lock_irqsave(shost->host_lock, flags); 144 - if (!pnode || 145 - !pnode->lat_data || 146 - (phba->bucket_type == LPFC_NO_BUCKET)) { 147 - spin_unlock_irqrestore(shost->host_lock, flags); 148 - return; 149 - } 150 - 151 - if (phba->bucket_type == LPFC_LINEAR_BUCKET) { 152 - i = (latency + phba->bucket_step - 1 - phba->bucket_base)/ 153 - phba->bucket_step; 154 - /* check array subscript bounds */ 155 - if (i < 0) 156 - i = 0; 157 - else if (i >= LPFC_MAX_BUCKET_COUNT) 158 - i = LPFC_MAX_BUCKET_COUNT - 1; 159 - } else { 160 - for (i = 0; i < LPFC_MAX_BUCKET_COUNT-1; i++) 161 - if (latency <= (phba->bucket_base + 162 - ((1<<i)*phba->bucket_step))) 163 - break; 164 - } 165 - 166 - pnode->lat_data[i].cmd_count++; 167 - spin_unlock_irqrestore(shost->host_lock, flags); 168 - } 169 - 170 - /** 171 115 * lpfc_rampdown_queue_depth - Post RAMP_DOWN_QUEUE event to worker thread 172 116 * @phba: The Hba for which this call is being executed. 173 117 * ··· 4279 4335 cmd->retries, scsi_get_resid(cmd)); 4280 4336 } 4281 4337 4282 - lpfc_update_stats(vport, lpfc_cmd); 4283 - 4284 4338 if (vport->cfg_max_scsicmpl_time && 4285 4339 time_after(jiffies, lpfc_cmd->start_time + 4286 4340 msecs_to_jiffies(vport->cfg_max_scsicmpl_time))) { ··· 4559 4617 scsi_get_resid(cmd)); 4560 4618 } 4561 4619 4562 - lpfc_update_stats(vport, lpfc_cmd); 4563 4620 if (vport->cfg_max_scsicmpl_time && 4564 4621 time_after(jiffies, lpfc_cmd->start_time + 4565 4622 msecs_to_jiffies(vport->cfg_max_scsicmpl_time))) { ··· 6791 6850 .shost_groups = lpfc_hba_groups, 6792 6851 .max_sectors = 0xFFFFFFFF, 6793 6852 .vendor_id = LPFC_NL_VENDOR_ID, 6853 + .change_queue_depth = scsi_change_queue_depth, 6854 + .track_queue_depth = 1, 6855 + }; 6856 + 6857 + struct scsi_host_template lpfc_vport_template = { 6858 + .module = THIS_MODULE, 6859 + .name = LPFC_DRIVER_NAME, 6860 + .proc_name = LPFC_DRIVER_NAME, 6861 + .info = lpfc_info, 6862 + .queuecommand = lpfc_queuecommand, 6863 + .eh_timed_out = fc_eh_timed_out, 6864 + .eh_should_retry_cmd = fc_eh_should_retry_cmd, 6865 + .eh_abort_handler = lpfc_abort_handler, 6866 + .eh_device_reset_handler = lpfc_device_reset_handler, 6867 + .eh_target_reset_handler = lpfc_target_reset_handler, 6868 + .eh_bus_reset_handler = NULL, 6869 + .eh_host_reset_handler = NULL, 6870 + .slave_alloc = lpfc_slave_alloc, 6871 + .slave_configure = lpfc_slave_configure, 6872 + .slave_destroy = lpfc_slave_destroy, 6873 + .scan_finished = lpfc_scan_finished, 6874 + .this_id = -1, 6875 + .sg_tablesize = LPFC_DEFAULT_SG_SEG_CNT, 6876 + .cmd_per_lun = LPFC_CMD_PER_LUN, 6877 + .shost_groups = lpfc_vport_groups, 6878 + .max_sectors = 0xFFFFFFFF, 6879 + .vendor_id = 0, 6794 6880 .change_queue_depth = scsi_change_queue_depth, 6795 6881 .track_queue_depth = 1, 6796 6882 };
+1 -5
drivers/scsi/lpfc/lpfc_scsi.h
··· 1 1 /******************************************************************* 2 2 * This file is part of the Emulex Linux Device Driver for * 3 3 * Fibre Channel Host Bus Adapters. * 4 - * Copyright (C) 2017-2021 Broadcom. All Rights Reserved. The term * 4 + * Copyright (C) 2017-2022 Broadcom. All Rights Reserved. The term * 5 5 * “Broadcom” refers to Broadcom Inc and/or its subsidiaries. * 6 6 * Copyright (C) 2004-2016 Emulex. All rights reserved. * 7 7 * EMULEX and SLI are trademarks of Emulex. * ··· 124 124 uint8_t fcpCdb[LPFC_FCP_CDB_LEN]; /* SRB cdb field is copied here */ 125 125 uint32_t fcpDl; /* Total transfer length */ 126 126 127 - }; 128 - 129 - struct lpfc_scsicmd_bkt { 130 - uint32_t cmd_count; 131 127 }; 132 128 133 129 #define LPFC_SCSI_DMA_EXT_SIZE 264
+262 -11
drivers/scsi/lpfc/lpfc_sli.c
··· 1916 1916 unsigned long iflags; 1917 1917 u32 ret_val; 1918 1918 u32 atot, wtot, max; 1919 + u16 warn_sync_period = 0; 1919 1920 1920 1921 /* First address any alarm / warning activity */ 1921 1922 atot = atomic_xchg(&phba->cgn_sync_alarm_cnt, 0); ··· 1971 1970 lpfc_acqe_cgn_frequency; 1972 1971 bf_set(cmf_sync_wsigmax, &wqe->cmf_sync, max); 1973 1972 bf_set(cmf_sync_wsigcnt, &wqe->cmf_sync, wtot); 1973 + warn_sync_period = lpfc_acqe_cgn_frequency; 1974 1974 } else { 1975 1975 /* We hit a FPIN warning condition */ 1976 1976 bf_set(cmf_sync_wfpinmax, &wqe->cmf_sync, 1); 1977 1977 bf_set(cmf_sync_wfpincnt, &wqe->cmf_sync, 1); 1978 + if (phba->cgn_fpin_frequency != LPFC_FPIN_INIT_FREQ) 1979 + warn_sync_period = 1980 + LPFC_MSECS_TO_SECS(phba->cgn_fpin_frequency); 1978 1981 } 1979 1982 } 1980 1983 ··· 1994 1989 bf_set(cmf_sync_reqtag, &wqe->cmf_sync, sync_buf->iotag); 1995 1990 1996 1991 bf_set(cmf_sync_qosd, &wqe->cmf_sync, 1); 1992 + bf_set(cmf_sync_period, &wqe->cmf_sync, warn_sync_period); 1997 1993 1998 1994 bf_set(cmf_sync_cmd_type, &wqe->cmf_sync, CMF_SYNC_COMMAND); 1999 1995 bf_set(cmf_sync_wqec, &wqe->cmf_sync, 1); ··· 2856 2850 lpfc_sli_def_mbox_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) 2857 2851 { 2858 2852 struct lpfc_vport *vport = pmb->vport; 2853 + struct lpfc_dmabuf *mp; 2859 2854 struct lpfc_nodelist *ndlp; 2860 2855 struct Scsi_Host *shost; 2861 2856 uint16_t rpi, vpi; ··· 2869 2862 if (!(phba->pport->load_flag & FC_UNLOADING) && 2870 2863 pmb->u.mb.mbxCommand == MBX_REG_LOGIN64 && 2871 2864 !pmb->u.mb.mbxStatus) { 2865 + mp = (struct lpfc_dmabuf *)pmb->ctx_buf; 2866 + if (mp) { 2867 + pmb->ctx_buf = NULL; 2868 + lpfc_mbuf_free(phba, mp->virt, mp->phys); 2869 + kfree(mp); 2870 + } 2872 2871 rpi = pmb->u.mb.un.varWords[0]; 2873 2872 vpi = pmb->u.mb.un.varRegLogin.vpi; 2874 2873 if (phba->sli_rev == LPFC_SLI_REV4) ··· 6215 6202 struct lpfc_mbx_get_rsrc_extent_info *rsrc_info; 6216 6203 LPFC_MBOXQ_t *mbox; 6217 6204 6205 + *extnt_count = 0; 6206 + *extnt_size = 0; 6207 + 6218 6208 mbox = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); 6219 6209 if (!mbox) 6220 6210 return -ENOMEM; ··· 6833 6817 bf_set(lpfc_mbx_set_feature_mi, &mbox->u.mqe.un.set_feature, 6834 6818 phba->sli4_hba.pc_sli4_params.mi_ver); 6835 6819 break; 6820 + case LPFC_SET_LD_SIGNAL: 6821 + mbox->u.mqe.un.set_feature.feature = LPFC_SET_LD_SIGNAL; 6822 + mbox->u.mqe.un.set_feature.param_len = 16; 6823 + bf_set(lpfc_mbx_set_feature_lds_qry, 6824 + &mbox->u.mqe.un.set_feature, LPFC_QUERY_LDS_OP); 6825 + break; 6836 6826 case LPFC_SET_ENABLE_CMF: 6837 - bf_set(lpfc_mbx_set_feature_dd, &mbox->u.mqe.un.set_feature, 1); 6838 6827 mbox->u.mqe.un.set_feature.feature = LPFC_SET_ENABLE_CMF; 6839 6828 mbox->u.mqe.un.set_feature.param_len = 4; 6840 6829 bf_set(lpfc_mbx_set_feature_cmf, ··· 7835 7814 } 7836 7815 7837 7816 static void 7817 + lpfc_mbx_cmpl_read_lds_params(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) 7818 + { 7819 + union lpfc_sli4_cfg_shdr *shdr; 7820 + u32 shdr_status, shdr_add_status; 7821 + 7822 + shdr = (union lpfc_sli4_cfg_shdr *) 7823 + &pmb->u.mqe.un.sli4_config.header.cfg_shdr; 7824 + shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response); 7825 + shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response); 7826 + if (shdr_status || shdr_add_status || pmb->u.mb.mbxStatus) { 7827 + lpfc_printf_log(phba, KERN_INFO, LOG_LDS_EVENT | LOG_MBOX, 7828 + "4622 SET_FEATURE (x%x) mbox failed, " 7829 + "status x%x add_status x%x, mbx status x%x\n", 7830 + LPFC_SET_LD_SIGNAL, shdr_status, 7831 + shdr_add_status, pmb->u.mb.mbxStatus); 7832 + phba->degrade_activate_threshold = 0; 7833 + phba->degrade_deactivate_threshold = 0; 7834 + phba->fec_degrade_interval = 0; 7835 + goto out; 7836 + } 7837 + 7838 + phba->degrade_activate_threshold = pmb->u.mqe.un.set_feature.word7; 7839 + phba->degrade_deactivate_threshold = pmb->u.mqe.un.set_feature.word8; 7840 + phba->fec_degrade_interval = pmb->u.mqe.un.set_feature.word10; 7841 + 7842 + lpfc_printf_log(phba, KERN_INFO, LOG_LDS_EVENT, 7843 + "4624 Success: da x%x dd x%x interval x%x\n", 7844 + phba->degrade_activate_threshold, 7845 + phba->degrade_deactivate_threshold, 7846 + phba->fec_degrade_interval); 7847 + out: 7848 + mempool_free(pmb, phba->mbox_mem_pool); 7849 + } 7850 + 7851 + int 7852 + lpfc_read_lds_params(struct lpfc_hba *phba) 7853 + { 7854 + LPFC_MBOXQ_t *mboxq; 7855 + int rc; 7856 + 7857 + mboxq = (LPFC_MBOXQ_t *)mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); 7858 + if (!mboxq) 7859 + return -ENOMEM; 7860 + 7861 + lpfc_set_features(phba, mboxq, LPFC_SET_LD_SIGNAL); 7862 + mboxq->vport = phba->pport; 7863 + mboxq->mbox_cmpl = lpfc_mbx_cmpl_read_lds_params; 7864 + rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_NOWAIT); 7865 + if (rc == MBX_NOT_FINISHED) { 7866 + mempool_free(mboxq, phba->mbox_mem_pool); 7867 + return -EIO; 7868 + } 7869 + return 0; 7870 + } 7871 + 7872 + static void 7838 7873 lpfc_mbx_cmpl_cgn_set_ftrs(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) 7839 7874 { 7840 7875 struct lpfc_vport *vport = pmb->vport; ··· 8034 7957 "2904 Firmware Dump Image Present" 8035 7958 " on Adapter"); 8036 7959 } 7960 + } 7961 + 7962 + /** 7963 + * lpfc_rx_monitor_create_ring - Initialize ring buffer for rx_monitor 7964 + * @rx_monitor: Pointer to lpfc_rx_info_monitor object 7965 + * @entries: Number of rx_info_entry objects to allocate in ring 7966 + * 7967 + * Return: 7968 + * 0 - Success 7969 + * ENOMEM - Failure to kmalloc 7970 + **/ 7971 + int lpfc_rx_monitor_create_ring(struct lpfc_rx_info_monitor *rx_monitor, 7972 + u32 entries) 7973 + { 7974 + rx_monitor->ring = kmalloc_array(entries, sizeof(struct rx_info_entry), 7975 + GFP_KERNEL); 7976 + if (!rx_monitor->ring) 7977 + return -ENOMEM; 7978 + 7979 + rx_monitor->head_idx = 0; 7980 + rx_monitor->tail_idx = 0; 7981 + spin_lock_init(&rx_monitor->lock); 7982 + rx_monitor->entries = entries; 7983 + 7984 + return 0; 7985 + } 7986 + 7987 + /** 7988 + * lpfc_rx_monitor_destroy_ring - Free ring buffer for rx_monitor 7989 + * @rx_monitor: Pointer to lpfc_rx_info_monitor object 7990 + **/ 7991 + void lpfc_rx_monitor_destroy_ring(struct lpfc_rx_info_monitor *rx_monitor) 7992 + { 7993 + spin_lock(&rx_monitor->lock); 7994 + kfree(rx_monitor->ring); 7995 + rx_monitor->ring = NULL; 7996 + rx_monitor->entries = 0; 7997 + rx_monitor->head_idx = 0; 7998 + rx_monitor->tail_idx = 0; 7999 + spin_unlock(&rx_monitor->lock); 8000 + } 8001 + 8002 + /** 8003 + * lpfc_rx_monitor_record - Insert an entry into rx_monitor's ring 8004 + * @rx_monitor: Pointer to lpfc_rx_info_monitor object 8005 + * @entry: Pointer to rx_info_entry 8006 + * 8007 + * Used to insert an rx_info_entry into rx_monitor's ring. Note that this is a 8008 + * deep copy of rx_info_entry not a shallow copy of the rx_info_entry ptr. 8009 + * 8010 + * This is called from lpfc_cmf_timer, which is in timer/softirq context. 8011 + * 8012 + * In cases of old data overflow, we do a best effort of FIFO order. 8013 + **/ 8014 + void lpfc_rx_monitor_record(struct lpfc_rx_info_monitor *rx_monitor, 8015 + struct rx_info_entry *entry) 8016 + { 8017 + struct rx_info_entry *ring = rx_monitor->ring; 8018 + u32 *head_idx = &rx_monitor->head_idx; 8019 + u32 *tail_idx = &rx_monitor->tail_idx; 8020 + spinlock_t *ring_lock = &rx_monitor->lock; 8021 + u32 ring_size = rx_monitor->entries; 8022 + 8023 + spin_lock(ring_lock); 8024 + memcpy(&ring[*tail_idx], entry, sizeof(*entry)); 8025 + *tail_idx = (*tail_idx + 1) % ring_size; 8026 + 8027 + /* Best effort of FIFO saved data */ 8028 + if (*tail_idx == *head_idx) 8029 + *head_idx = (*head_idx + 1) % ring_size; 8030 + 8031 + spin_unlock(ring_lock); 8032 + } 8033 + 8034 + /** 8035 + * lpfc_rx_monitor_report - Read out rx_monitor's ring 8036 + * @phba: Pointer to lpfc_hba object 8037 + * @rx_monitor: Pointer to lpfc_rx_info_monitor object 8038 + * @buf: Pointer to char buffer that will contain rx monitor info data 8039 + * @buf_len: Length buf including null char 8040 + * @max_read_entries: Maximum number of entries to read out of ring 8041 + * 8042 + * Used to dump/read what's in rx_monitor's ring buffer. 8043 + * 8044 + * If buf is NULL || buf_len == 0, then it is implied that we want to log the 8045 + * information to kmsg instead of filling out buf. 8046 + * 8047 + * Return: 8048 + * Number of entries read out of the ring 8049 + **/ 8050 + u32 lpfc_rx_monitor_report(struct lpfc_hba *phba, 8051 + struct lpfc_rx_info_monitor *rx_monitor, char *buf, 8052 + u32 buf_len, u32 max_read_entries) 8053 + { 8054 + struct rx_info_entry *ring = rx_monitor->ring; 8055 + struct rx_info_entry *entry; 8056 + u32 *head_idx = &rx_monitor->head_idx; 8057 + u32 *tail_idx = &rx_monitor->tail_idx; 8058 + spinlock_t *ring_lock = &rx_monitor->lock; 8059 + u32 ring_size = rx_monitor->entries; 8060 + u32 cnt = 0; 8061 + char tmp[DBG_LOG_STR_SZ] = {0}; 8062 + bool log_to_kmsg = (!buf || !buf_len) ? true : false; 8063 + 8064 + if (!log_to_kmsg) { 8065 + /* clear the buffer to be sure */ 8066 + memset(buf, 0, buf_len); 8067 + 8068 + scnprintf(buf, buf_len, "\t%-16s%-16s%-16s%-16s%-8s%-8s%-8s" 8069 + "%-8s%-8s%-8s%-16s\n", 8070 + "MaxBPI", "Tot_Data_CMF", 8071 + "Tot_Data_Cmd", "Tot_Data_Cmpl", 8072 + "Lat(us)", "Avg_IO", "Max_IO", "Bsy", 8073 + "IO_cnt", "Info", "BWutil(ms)"); 8074 + } 8075 + 8076 + /* Needs to be _bh because record is called from timer interrupt 8077 + * context 8078 + */ 8079 + spin_lock_bh(ring_lock); 8080 + while (*head_idx != *tail_idx) { 8081 + entry = &ring[*head_idx]; 8082 + 8083 + /* Read out this entry's data. */ 8084 + if (!log_to_kmsg) { 8085 + /* If !log_to_kmsg, then store to buf. */ 8086 + scnprintf(tmp, sizeof(tmp), 8087 + "%03d:\t%-16llu%-16llu%-16llu%-16llu%-8llu" 8088 + "%-8llu%-8llu%-8u%-8u%-8u%u(%u)\n", 8089 + *head_idx, entry->max_bytes_per_interval, 8090 + entry->cmf_bytes, entry->total_bytes, 8091 + entry->rcv_bytes, entry->avg_io_latency, 8092 + entry->avg_io_size, entry->max_read_cnt, 8093 + entry->cmf_busy, entry->io_cnt, 8094 + entry->cmf_info, entry->timer_utilization, 8095 + entry->timer_interval); 8096 + 8097 + /* Check for buffer overflow */ 8098 + if ((strlen(buf) + strlen(tmp)) >= buf_len) 8099 + break; 8100 + 8101 + /* Append entry's data to buffer */ 8102 + strlcat(buf, tmp, buf_len); 8103 + } else { 8104 + lpfc_printf_log(phba, KERN_INFO, LOG_CGN_MGMT, 8105 + "4410 %02u: MBPI %llu Xmit %llu " 8106 + "Cmpl %llu Lat %llu ASz %llu Info %02u " 8107 + "BWUtil %u Int %u slot %u\n", 8108 + cnt, entry->max_bytes_per_interval, 8109 + entry->total_bytes, entry->rcv_bytes, 8110 + entry->avg_io_latency, 8111 + entry->avg_io_size, entry->cmf_info, 8112 + entry->timer_utilization, 8113 + entry->timer_interval, *head_idx); 8114 + } 8115 + 8116 + *head_idx = (*head_idx + 1) % ring_size; 8117 + 8118 + /* Don't feed more than max_read_entries */ 8119 + cnt++; 8120 + if (cnt >= max_read_entries) 8121 + break; 8122 + } 8123 + spin_unlock_bh(ring_lock); 8124 + 8125 + return cnt; 8037 8126 } 8038 8127 8039 8128 /** ··· 8376 8133 phba->cmf_interval_rate = LPFC_CMF_INTERVAL; 8377 8134 8378 8135 /* Allocate RX Monitor Buffer */ 8379 - if (!phba->rxtable) { 8380 - phba->rxtable = kmalloc_array(LPFC_MAX_RXMONITOR_ENTRY, 8381 - sizeof(struct rxtable_entry), 8382 - GFP_KERNEL); 8383 - if (!phba->rxtable) { 8136 + if (!phba->rx_monitor) { 8137 + phba->rx_monitor = kzalloc(sizeof(*phba->rx_monitor), 8138 + GFP_KERNEL); 8139 + 8140 + if (!phba->rx_monitor) { 8384 8141 lpfc_printf_log(phba, KERN_ERR, LOG_INIT, 8385 8142 "2644 Failed to alloc memory " 8386 8143 "for RX Monitor Buffer\n"); 8387 8144 return -ENOMEM; 8388 8145 } 8146 + 8147 + /* Instruct the rx_monitor object to instantiate its ring */ 8148 + if (lpfc_rx_monitor_create_ring(phba->rx_monitor, 8149 + LPFC_MAX_RXMONITOR_ENTRY)) { 8150 + kfree(phba->rx_monitor); 8151 + phba->rx_monitor = NULL; 8152 + lpfc_printf_log(phba, KERN_ERR, LOG_INIT, 8153 + "2645 Failed to alloc memory " 8154 + "for RX Monitor's Ring\n"); 8155 + return -ENOMEM; 8156 + } 8389 8157 } 8390 - atomic_set(&phba->rxtable_idx_head, 0); 8391 - atomic_set(&phba->rxtable_idx_tail, 0); 8158 + 8392 8159 return 0; 8393 8160 } 8394 8161 ··· 10575 10322 __lpfc_sli_issue_fcp_io_s4(struct lpfc_hba *phba, uint32_t ring_number, 10576 10323 struct lpfc_iocbq *piocb, uint32_t flag) 10577 10324 { 10578 - int rc; 10579 10325 struct lpfc_io_buf *lpfc_cmd = piocb->io_buf; 10580 10326 10581 10327 lpfc_prep_embed_io(phba, lpfc_cmd); 10582 - rc = lpfc_sli4_issue_wqe(phba, lpfc_cmd->hdwq, piocb); 10583 - return rc; 10328 + return lpfc_sli4_issue_wqe(phba, lpfc_cmd->hdwq, piocb); 10584 10329 } 10585 10330 10586 10331 void
+3 -1
drivers/scsi/lpfc/lpfc_sli4.h
··· 489 489 #define LPFC_SLI4_HANDLER_NAME_SZ 16 490 490 struct lpfc_hba_eq_hdl { 491 491 uint32_t idx; 492 - uint16_t irq; 492 + int irq; 493 493 char handler_name[LPFC_SLI4_HANDLER_NAME_SZ]; 494 494 struct lpfc_hba *phba; 495 495 struct lpfc_queue *eq; ··· 610 610 #define LPFC_CPU_FIRST_IRQ 0x4 611 611 }; 612 612 #define LPFC_VECTOR_MAP_EMPTY 0xffff 613 + 614 + #define LPFC_IRQ_EMPTY 0xffffffff 613 615 614 616 /* Multi-XRI pool */ 615 617 #define XRI_BATCH 8
+1 -1
drivers/scsi/lpfc/lpfc_version.h
··· 20 20 * included with this package. * 21 21 *******************************************************************/ 22 22 23 - #define LPFC_DRIVER_VERSION "14.2.0.5" 23 + #define LPFC_DRIVER_VERSION "14.2.0.7" 24 24 #define LPFC_DRIVER_NAME "lpfc" 25 25 26 26 /* Used for SLI 2/3 */
+1 -3
drivers/scsi/lpfc/lpfc_vmid.c
··· 245 245 /* allocate the per cpu variable for holding */ 246 246 /* the last access time stamp only if VMID is enabled */ 247 247 if (!vmp->last_io_time) 248 - vmp->last_io_time = __alloc_percpu(sizeof(u64), 249 - __alignof__(struct 250 - lpfc_vmid)); 248 + vmp->last_io_time = alloc_percpu_gfp(u64, GFP_ATOMIC); 251 249 if (!vmp->last_io_time) { 252 250 hash_del(&vmp->hnode); 253 251 vmp->flag = LPFC_VMID_SLOT_FREE;
-71
drivers/scsi/lpfc/lpfc_vport.c
··· 809 809 kfree(vports); 810 810 } 811 811 812 - 813 - /** 814 - * lpfc_vport_reset_stat_data - Reset the statistical data for the vport 815 - * @vport: Pointer to vport object. 816 - * 817 - * This function resets the statistical data for the vport. This function 818 - * is called with the host_lock held 819 - **/ 820 - void 821 - lpfc_vport_reset_stat_data(struct lpfc_vport *vport) 822 - { 823 - struct lpfc_nodelist *ndlp = NULL, *next_ndlp = NULL; 824 - 825 - list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) { 826 - if (ndlp->lat_data) 827 - memset(ndlp->lat_data, 0, LPFC_MAX_BUCKET_COUNT * 828 - sizeof(struct lpfc_scsicmd_bkt)); 829 - } 830 - } 831 - 832 - 833 - /** 834 - * lpfc_alloc_bucket - Allocate data buffer required for statistical data 835 - * @vport: Pointer to vport object. 836 - * 837 - * This function allocates data buffer required for all the FC 838 - * nodes of the vport to collect statistical data. 839 - **/ 840 - void 841 - lpfc_alloc_bucket(struct lpfc_vport *vport) 842 - { 843 - struct lpfc_nodelist *ndlp = NULL, *next_ndlp = NULL; 844 - 845 - list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) { 846 - 847 - kfree(ndlp->lat_data); 848 - ndlp->lat_data = NULL; 849 - 850 - if (ndlp->nlp_state == NLP_STE_MAPPED_NODE) { 851 - ndlp->lat_data = kcalloc(LPFC_MAX_BUCKET_COUNT, 852 - sizeof(struct lpfc_scsicmd_bkt), 853 - GFP_ATOMIC); 854 - 855 - if (!ndlp->lat_data) 856 - lpfc_printf_vlog(vport, KERN_ERR, 857 - LOG_TRACE_EVENT, 858 - "0287 lpfc_alloc_bucket failed to " 859 - "allocate statistical data buffer DID " 860 - "0x%x\n", ndlp->nlp_DID); 861 - } 862 - } 863 - } 864 - 865 - /** 866 - * lpfc_free_bucket - Free data buffer required for statistical data 867 - * @vport: Pointer to vport object. 868 - * 869 - * Th function frees statistical data buffer of all the FC 870 - * nodes of the vport. 871 - **/ 872 - void 873 - lpfc_free_bucket(struct lpfc_vport *vport) 874 - { 875 - struct lpfc_nodelist *ndlp = NULL, *next_ndlp = NULL; 876 - 877 - list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) { 878 - 879 - kfree(ndlp->lat_data); 880 - ndlp->lat_data = NULL; 881 - } 882 - }
+1 -5
drivers/scsi/lpfc/lpfc_vport.h
··· 1 1 /******************************************************************* 2 2 * This file is part of the Emulex Linux Device Driver for * 3 3 * Fibre Channel Host Bus Adapters. * 4 - * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term * 4 + * Copyright (C) 2017-2022 Broadcom. All Rights Reserved. The term * 5 5 * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. * 6 6 * Copyright (C) 2004-2006 Emulex. All rights reserved. * 7 7 * EMULEX and SLI are trademarks of Emulex. * ··· 114 114 115 115 void lpfc_vport_set_state(struct lpfc_vport *vport, 116 116 enum fc_vport_state new_state); 117 - 118 - void lpfc_vport_reset_stat_data(struct lpfc_vport *); 119 - void lpfc_alloc_bucket(struct lpfc_vport *); 120 - void lpfc_free_bucket(struct lpfc_vport *); 121 117 122 118 #endif /* H_LPFC_VPORT */
+2 -2
drivers/scsi/megaraid/megaraid_mbox.c
··· 3979 3979 3980 3980 app_hndl = mraid_mm_adapter_app_handle(adapter->unique_id); 3981 3981 3982 - return snprintf(buf, 8, "%u\n", app_hndl); 3982 + return sysfs_emit(buf, "%u\n", app_hndl); 3983 3983 } 3984 3984 3985 3985 ··· 4048 4048 } 4049 4049 } 4050 4050 4051 - return snprintf(buf, 36, "%d %d %d %d\n", scsi_id, logical_drv, 4051 + return sysfs_emit(buf, "%d %d %d %d\n", scsi_id, logical_drv, 4052 4052 ldid_map, app_hndl); 4053 4053 } 4054 4054
+11 -13
drivers/scsi/megaraid/megaraid_sas_base.c
··· 4021 4021 u32 mfiStatus; 4022 4022 u32 fw_state; 4023 4023 4024 - if ((mfiStatus = instance->instancet->check_reset(instance, 4025 - instance->reg_set)) == 1) { 4024 + if (instance->instancet->check_reset(instance, instance->reg_set) == 1) 4026 4025 return IRQ_HANDLED; 4027 - } 4028 4026 4029 4027 mfiStatus = instance->instancet->clear_intr(instance); 4030 4028 if (mfiStatus == 0) { ··· 5153 5155 fusion->current_map_sz = ventura_map_sz; 5154 5156 fusion->max_map_sz = ventura_map_sz; 5155 5157 } else { 5156 - fusion->old_map_sz = sizeof(struct MR_FW_RAID_MAP) + 5157 - (sizeof(struct MR_LD_SPAN_MAP) * 5158 - (instance->fw_supported_vd_count - 1)); 5158 + fusion->old_map_sz = 5159 + struct_size((struct MR_FW_RAID_MAP *)0, ldSpanMap, 5160 + instance->fw_supported_vd_count); 5159 5161 fusion->new_map_sz = sizeof(struct MR_FW_RAID_MAP_EXT); 5160 5162 5161 5163 fusion->max_map_sz = ··· 5788 5790 { 5789 5791 int i; 5790 5792 struct fusion_context *fusion = instance->ctrl_context; 5791 - u32 pd_seq_map_sz; 5793 + size_t pd_seq_map_sz; 5792 5794 5793 - pd_seq_map_sz = sizeof(struct MR_PD_CFG_SEQ_NUM_SYNC) + 5794 - (sizeof(struct MR_PD_CFG_SEQ) * (MAX_PHYSICAL_DEVICES - 1)); 5795 + pd_seq_map_sz = struct_size((struct MR_PD_CFG_SEQ_NUM_SYNC *)0, seq, 5796 + MAX_PHYSICAL_DEVICES); 5795 5797 5796 5798 instance->use_seqnum_jbod_fp = 5797 5799 instance->support_seqnum_jbod_fp; ··· 7966 7968 struct Scsi_Host *host; 7967 7969 struct megasas_instance *instance; 7968 7970 struct fusion_context *fusion; 7969 - u32 pd_seq_map_sz; 7971 + size_t pd_seq_map_sz; 7970 7972 7971 7973 instance = pci_get_drvdata(pdev); 7972 7974 ··· 8038 8040 8039 8041 if (instance->adapter_type != MFI_SERIES) { 8040 8042 megasas_release_fusion(instance); 8041 - pd_seq_map_sz = sizeof(struct MR_PD_CFG_SEQ_NUM_SYNC) + 8042 - (sizeof(struct MR_PD_CFG_SEQ) * 8043 - (MAX_PHYSICAL_DEVICES - 1)); 8043 + pd_seq_map_sz = 8044 + struct_size((struct MR_PD_CFG_SEQ_NUM_SYNC *)0, 8045 + seq, MAX_PHYSICAL_DEVICES); 8044 8046 for (i = 0; i < 2 ; i++) { 8045 8047 if (fusion->ld_map[i]) 8046 8048 dma_free_coherent(&instance->pdev->dev,
+3 -3
drivers/scsi/megaraid/megaraid_sas_fp.c
··· 326 326 else if (instance->supportmax256vd) 327 327 expected_size = sizeof(struct MR_FW_RAID_MAP_EXT); 328 328 else 329 - expected_size = 330 - (sizeof(struct MR_FW_RAID_MAP) - sizeof(struct MR_LD_SPAN_MAP) + 331 - (sizeof(struct MR_LD_SPAN_MAP) * le16_to_cpu(pDrvRaidMap->ldCount))); 329 + expected_size = struct_size((struct MR_FW_RAID_MAP *)0, 330 + ldSpanMap, 331 + le16_to_cpu(pDrvRaidMap->ldCount)); 332 332 333 333 if (le32_to_cpu(pDrvRaidMap->totalSize) != expected_size) { 334 334 dev_dbg(&instance->pdev->dev, "megasas: map info structure size 0x%x",
+1 -1
drivers/scsi/megaraid/megaraid_sas_fusion.c
··· 1310 1310 1311 1311 pd_sync = (void *)fusion->pd_seq_sync[(instance->pd_seq_map_id & 1)]; 1312 1312 pd_seq_h = fusion->pd_seq_phys[(instance->pd_seq_map_id & 1)]; 1313 - pd_seq_map_sz = struct_size(pd_sync, seq, MAX_PHYSICAL_DEVICES - 1); 1313 + pd_seq_map_sz = struct_size(pd_sync, seq, MAX_PHYSICAL_DEVICES); 1314 1314 1315 1315 cmd = megasas_get_cmd(instance); 1316 1316 if (!cmd) {
+6 -6
drivers/scsi/megaraid/megaraid_sas_fusion.h
··· 942 942 u8 reserved2[7]; 943 943 struct MR_ARRAY_INFO arMapInfo[MAX_RAIDMAP_ARRAYS]; 944 944 struct MR_DEV_HANDLE_INFO devHndlInfo[MAX_RAIDMAP_PHYSICAL_DEVICES]; 945 - struct MR_LD_SPAN_MAP ldSpanMap[1]; 945 + struct MR_LD_SPAN_MAP ldSpanMap[]; 946 946 }; 947 947 948 948 struct IO_REQUEST_INFO { ··· 1053 1053 struct MR_RAID_MAP_DESC_TABLE 1054 1054 raid_map_desc_table[RAID_MAP_DESC_TYPE_COUNT]; 1055 1055 /* Variable Size buffer containing all data */ 1056 - u32 raid_map_desc_data[1]; 1056 + u32 raid_map_desc_data[]; 1057 1057 }; /* Dynamicaly sized RAID MAp structure */ 1058 1058 1059 1059 #define IEEE_SGE_FLAGS_ADDR_MASK (0x03) ··· 1148 1148 1149 1149 struct MR_FW_RAID_MAP_ALL { 1150 1150 struct MR_FW_RAID_MAP raidMap; 1151 - struct MR_LD_SPAN_MAP ldSpanMap[MAX_LOGICAL_DRIVES - 1]; 1151 + struct MR_LD_SPAN_MAP ldSpanMap[MAX_LOGICAL_DRIVES]; 1152 1152 } __attribute__ ((packed)); 1153 1153 1154 1154 struct MR_DRV_RAID_MAP { ··· 1182 1182 devHndlInfo[MAX_RAIDMAP_PHYSICAL_DEVICES_DYN]; 1183 1183 u16 ldTgtIdToLd[MAX_LOGICAL_DRIVES_DYN]; 1184 1184 struct MR_ARRAY_INFO arMapInfo[MAX_API_ARRAYS_DYN]; 1185 - struct MR_LD_SPAN_MAP ldSpanMap[1]; 1185 + struct MR_LD_SPAN_MAP ldSpanMap[]; 1186 1186 1187 1187 }; 1188 1188 ··· 1193 1193 struct MR_DRV_RAID_MAP_ALL { 1194 1194 1195 1195 struct MR_DRV_RAID_MAP raidMap; 1196 - struct MR_LD_SPAN_MAP ldSpanMap[MAX_LOGICAL_DRIVES_DYN - 1]; 1196 + struct MR_LD_SPAN_MAP ldSpanMap[MAX_LOGICAL_DRIVES_DYN]; 1197 1197 } __packed; 1198 1198 1199 1199 ··· 1249 1249 struct MR_PD_CFG_SEQ_NUM_SYNC { 1250 1250 __le32 size; 1251 1251 __le32 count; 1252 - struct MR_PD_CFG_SEQ seq[1]; 1252 + struct MR_PD_CFG_SEQ seq[]; 1253 1253 } __packed; 1254 1254 1255 1255 /* stream detection */
+1
drivers/scsi/mpi3mr/Makefile
··· 3 3 mpi3mr-y += mpi3mr_os.o \ 4 4 mpi3mr_fw.o \ 5 5 mpi3mr_app.o \ 6 + mpi3mr_transport.o
+133 -38
drivers/scsi/mpi3mr/mpi/mpi30_cnfg.h
··· 1 1 /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 2 /* 3 - * Copyright 2017-2021 Broadcom Inc. All rights reserved. 4 - * 3 + * Copyright 2017-2022 Broadcom Inc. All rights reserved. 5 4 */ 6 5 #ifndef MPI30_CNFG_H 7 6 #define MPI30_CNFG_H 1 ··· 99 100 #define MPI3_SAS_NEG_LINK_RATE_LOGICAL_MASK (0xf0) 100 101 #define MPI3_SAS_NEG_LINK_RATE_LOGICAL_SHIFT (4) 101 102 #define MPI3_SAS_NEG_LINK_RATE_PHYSICAL_MASK (0x0f) 103 + #define MPI3_SAS_NEG_LINK_RATE_PHYSICAL_SHIFT (0) 102 104 #define MPI3_SAS_NEG_LINK_RATE_UNKNOWN_LINK_RATE (0x00) 103 105 #define MPI3_SAS_NEG_LINK_RATE_PHY_DISABLED (0x01) 104 106 #define MPI3_SAS_NEG_LINK_RATE_NEGOTIATION_FAILED (0x02) ··· 135 135 #define MPI3_SAS_PHYINFO_PHY_POWER_CONDITION_ACTIVE (0x00000000) 136 136 #define MPI3_SAS_PHYINFO_PHY_POWER_CONDITION_PARTIAL (0x08000000) 137 137 #define MPI3_SAS_PHYINFO_PHY_POWER_CONDITION_SLUMBER (0x10000000) 138 + #define MPI3_SAS_NEG_LINK_RATE_PHYSICAL_SHIFT (0) 139 + #define MPI3_SAS_PHYINFO_REQUESTED_INSIDE_ZPSDS_CHANGED_MASK (0x04000000) 140 + #define MPI3_SAS_PHYINFO_REQUESTED_INSIDE_ZPSDS_CHANGED_SHIFT (26) 141 + #define MPI3_SAS_PHYINFO_INSIDE_ZPSDS_PERSISTENT_MASK (0x02000000) 142 + #define MPI3_SAS_PHYINFO_INSIDE_ZPSDS_PERSISTENT_SHIFT (25) 143 + #define MPI3_SAS_PHYINFO_REQUESTED_INSIDE_ZPSDS_MASK (0x01000000) 144 + #define MPI3_SAS_PHYINFO_REQUESTED_INSIDE_ZPSDS_SHIFT (24) 145 + #define MPI3_SAS_PHYINFO_ZONE_GROUP_PERSISTENT (0x00400000) 146 + #define MPI3_SAS_PHYINFO_INSIDE_ZPSDS_WITHIN (0x00200000) 147 + #define MPI3_SAS_PHYINFO_ZONING_ENABLED (0x00100000) 138 148 #define MPI3_SAS_PHYINFO_REASON_MASK (0x000f0000) 139 149 #define MPI3_SAS_PHYINFO_REASON_UNKNOWN (0x00000000) 140 150 #define MPI3_SAS_PHYINFO_REASON_POWER_ON (0x00010000) ··· 220 210 u8 board_rework_day; 221 211 u8 board_rework_month; 222 212 __le16 board_rework_year; 223 - __le64 board_revision; 213 + u8 board_revision[8]; 224 214 u8 e_pack_fru[16]; 225 215 u8 product_name[256]; 226 216 }; ··· 236 226 }; 237 227 238 228 #define MPI3_MAN1_PAGEVERSION (0x00) 229 + struct mpi3_man_page2 { 230 + struct mpi3_config_page_header header; 231 + u8 flags; 232 + u8 reserved09[3]; 233 + __le32 reserved0c[3]; 234 + u8 oem_board_tracer_number[32]; 235 + }; 236 + #define MPI3_MAN2_PAGEVERSION (0x00) 237 + #define MPI3_MAN2_FLAGS_TRACER_PRESENT (0x01) 239 238 struct mpi3_man5_phy_entry { 240 239 __le64 ioc_wwid; 241 240 __le64 device_name; ··· 357 338 #define MPI3_MAN7_LOCATION_INTERNAL (0x01) 358 339 #define MPI3_MAN7_LOCATION_EXTERNAL (0x02) 359 340 #define MPI3_MAN7_LOCATION_VIRTUAL (0x03) 341 + #define MPI3_MAN7_LOCATION_HOST (0x04) 342 + #define MPI3_MAN7_CONNECTOR_TYPE_NO_INFO (0x00) 360 343 #define MPI3_MAN7_PEDCLK_ROUTING_MASK (0x10) 361 344 #define MPI3_MAN7_PEDCLK_ROUTING_DIRECT (0x00) 362 345 #define MPI3_MAN7_PEDCLK_ROUTING_CLOCK_BUFFER (0x10) ··· 390 369 __le32 reserved0c; 391 370 }; 392 371 393 - #define MPI3_MAN8_PHY_INFO_RECEPTACLE_ID_HOST_PHY (0xff) 372 + #define MPI3_MAN8_PHY_INFO_RECEPTACLE_ID_NOT_ASSOCIATED (0xff) 373 + #define MPI3_MAN8_PHY_INFO_CONNECTOR_LANE_NOT_ASSOCIATED (0xff) 394 374 #ifndef MPI3_MAN8_PHY_INFO_MAX 395 375 #define MPI3_MAN8_PHY_INFO_MAX (1) 396 376 #endif ··· 558 536 #define MPI3_MAN11_BKPLANE_NON_UBM_FLAGS_GROUP_MASK (0xf000) 559 537 #define MPI3_MAN11_BKPLANE_NON_UBM_FLAGS_GROUP_SHIFT (12) 560 538 #define MPI3_MAN11_BKPLANE_NON_UBM_FLAGS_REFCLK_POLICY_ALWAYS_ENABLED (0x0200) 539 + #define MPI3_MAN11_BKPLANE_NON_UBM_FLAGS_LINKWIDTH_MASK (0x00c0) 540 + #define MPI3_MAN11_BKPLANE_NON_UBM_FLAGS_LINKWIDTH_4 (0x0000) 541 + #define MPI3_MAN11_BKPLANE_NON_UBM_FLAGS_LINKWIDTH_2 (0x0040) 542 + #define MPI3_MAN11_BKPLANE_NON_UBM_FLAGS_LINKWIDTH_1 (0x0080) 561 543 #define MPI3_MAN11_BKPLANE_NON_UBM_FLAGS_PRESENCE_DETECT_MASK (0x0030) 562 544 #define MPI3_MAN11_BKPLANE_NON_UBM_FLAGS_PRESENCE_DETECT_GPIO (0x0000) 563 545 #define MPI3_MAN11_BKPLANE_NON_UBM_FLAGS_PRESENCE_DETECT_REG (0x0010) ··· 851 825 }; 852 826 853 827 #define MPI3_MAN21_PAGEVERSION (0x00) 854 - #define MPI3_MAN21_FLAGS_HOST_METADATA_CAPABILITY_MASK (0x80) 855 - #define MPI3_MAN21_FLAGS_HOST_METADATA_CAPABILITY_ENABLED (0x80) 856 - #define MPI3_MAN21_FLAGS_HOST_METADATA_CAPABILITY_DISABLED (0x00) 857 - #define MPI3_MAN21_FLAGS_UNCERTIFIED_DRIVES_MASK (0x60) 858 - #define MPI3_MAN21_FLAGS_UNCERTIFIED_DRIVES_BLOCK (0x00) 859 - #define MPI3_MAN21_FLAGS_UNCERTIFIED_DRIVES_ALLOW (0x20) 860 - #define MPI3_MAN21_FLAGS_UNCERTIFIED_DRIVES_WARN (0x40) 861 - #define MPI3_MAN21_FLAGS_BLOCK_SSD_WR_CACHE_CHANGE_MASK (0x08) 862 - #define MPI3_MAN21_FLAGS_BLOCK_SSD_WR_CACHE_CHANGE_ALLOW (0x00) 863 - #define MPI3_MAN21_FLAGS_BLOCK_SSD_WR_CACHE_CHANGE_PREVENT (0x08) 864 - #define MPI3_MAN21_FLAGS_SES_VPD_ASSOC_MASK (0x01) 865 - #define MPI3_MAN21_FLAGS_SES_VPD_ASSOC_DEFAULT (0x00) 866 - #define MPI3_MAN21_FLAGS_SES_VPD_ASSOC_OEM_SPECIFIC (0x01) 828 + #define MPI3_MAN21_FLAGS_UNCERTIFIED_DRIVES_MASK (0x00000060) 829 + #define MPI3_MAN21_FLAGS_UNCERTIFIED_DRIVES_BLOCK (0x00000000) 830 + #define MPI3_MAN21_FLAGS_UNCERTIFIED_DRIVES_ALLOW (0x00000020) 831 + #define MPI3_MAN21_FLAGS_UNCERTIFIED_DRIVES_WARN (0x00000040) 832 + #define MPI3_MAN21_FLAGS_BLOCK_SSD_WR_CACHE_CHANGE_MASK (0x00000008) 833 + #define MPI3_MAN21_FLAGS_BLOCK_SSD_WR_CACHE_CHANGE_ALLOW (0x00000000) 834 + #define MPI3_MAN21_FLAGS_BLOCK_SSD_WR_CACHE_CHANGE_PREVENT (0x00000008) 835 + #define MPI3_MAN21_FLAGS_SES_VPD_ASSOC_MASK (0x00000001) 836 + #define MPI3_MAN21_FLAGS_SES_VPD_ASSOC_DEFAULT (0x00000000) 837 + #define MPI3_MAN21_FLAGS_SES_VPD_ASSOC_OEM_SPECIFIC (0x00000001) 867 838 #ifndef MPI3_MAN_PROD_SPECIFIC_MAX 868 839 #define MPI3_MAN_PROD_SPECIFIC_MAX (1) 869 840 #endif ··· 1018 995 #define MPI3_IOUNIT5_DEVICE_SHUTDOWN_SATA_SSD_MASK (0x000c) 1019 996 #define MPI3_IOUNIT5_DEVICE_SHUTDOWN_SATA_SSD_SHIFT (2) 1020 997 #define MPI3_IOUNIT5_DEVICE_SHUTDOWN_SAS_SSD_MASK (0x0003) 1021 - #define MPI3_IOUNIT5_DEVICE_SHUTDOWN_SAA_SSD_SHIFT (0) 998 + #define MPI3_IOUNIT5_DEVICE_SHUTDOWN_SAS_SSD_SHIFT (0) 999 + #define MPI3_IOUNIT5_FLAGS_SATAPUIS_MASK (0x0c) 1000 + #define MPI3_IOUNIT5_FLAGS_SATAPUIS_NOT_SUPPORTED (0x00) 1001 + #define MPI3_IOUNIT5_FLAGS_SATAPUIS_OS_CONTROLLED (0x04) 1002 + #define MPI3_IOUNIT5_FLAGS_SATAPUIS_APP_CONTROLLED (0x08) 1003 + #define MPI3_IOUNIT5_FLAGS_SATAPUIS_BLOCKED (0x0c) 1022 1004 #define MPI3_IOUNIT5_FLAGS_POWER_CAPABLE_SPINUP (0x02) 1023 1005 #define MPI3_IOUNIT5_FLAGS_AUTO_PORT_ENABLE (0x01) 1024 1006 #define MPI3_IOUNIT5_PHY_SPINUP_GROUP_MASK (0x03) ··· 1055 1027 u8 slots_available; 1056 1028 u8 current_key_encryption_algo; 1057 1029 u8 key_digest_hash_algo; 1058 - __le32 reserved10[2]; 1030 + union mpi3_version_union current_svn; 1031 + __le32 reserved14; 1059 1032 __le32 current_key[128]; 1060 1033 union mpi3_iounit8_digest digest[MPI3_IOUNIT8_DIGEST_MAX]; 1061 1034 }; ··· 1065 1036 #define MPI3_IOUNIT8_SBMODE_SECURE_DEBUG (0x04) 1066 1037 #define MPI3_IOUNIT8_SBMODE_HARD_SECURE (0x02) 1067 1038 #define MPI3_IOUNIT8_SBMODE_CONFIG_SECURE (0x01) 1039 + #define MPI3_IOUNIT8_SBSTATE_SVN_UPDATE_PENDING (0x04) 1068 1040 #define MPI3_IOUNIT8_SBSTATE_KEY_UPDATE_PENDING (0x02) 1069 1041 #define MPI3_IOUNIT8_SBSTATE_SECURE_BOOT_ENABLED (0x01) 1070 1042 struct mpi3_io_unit_page9 { ··· 1075 1045 __le16 reserved0e; 1076 1046 }; 1077 1047 1078 - #define MPI3_IOUNIT9_PAGEVERSION (0x00) 1079 - #define MPI3_IOUNIT9_FLAGS_VDFIRST_ENABLED (0x01) 1080 - #define MPI3_IOUNIT9_FIRSTDEVICE_UNKNOWN (0xffff) 1048 + #define MPI3_IOUNIT9_PAGEVERSION (0x00) 1049 + #define MPI3_IOUNIT9_FLAGS_UBM_ENCLOSURE_ORDER_MASK (0x00000006) 1050 + #define MPI3_IOUNIT9_FLAGS_UBM_ENCLOSURE_ORDER_SHIFT (1) 1051 + #define MPI3_IOUNIT9_FLAGS_UBM_ENCLOSURE_ORDER_NONE (0x00000000) 1052 + #define MPI3_IOUNIT9_FLAGS_UBM_ENCLOSURE_ORDER_RECEPTACLE (0x00000002) 1053 + #define MPI3_IOUNIT9_FLAGS_UBM_ENCLOSURE_ORDER_BACKPLANE_TYPE (0x00000004) 1054 + #define MPI3_IOUNIT9_FLAGS_VDFIRST_ENABLED (0x00000001) 1055 + #define MPI3_IOUNIT9_FIRSTDEVICE_UNKNOWN (0xffff) 1081 1056 struct mpi3_io_unit_page10 { 1082 1057 struct mpi3_config_page_header header; 1083 1058 u8 flags; ··· 1125 1090 struct mpi3_iounit11_profile profile[MPI3_IOUNIT11_PROFILE_MAX]; 1126 1091 }; 1127 1092 #define MPI3_IOUNIT11_PAGEVERSION (0x00) 1093 + #ifndef MPI3_IOUNIT12_BUCKET_MAX 1094 + #define MPI3_IOUNIT12_BUCKET_MAX (1) 1095 + #endif 1096 + struct mpi3_iounit12_bucket { 1097 + u8 coalescing_depth; 1098 + u8 coalescing_timeout; 1099 + __le16 io_count_low_boundary; 1100 + __le32 reserved04; 1101 + }; 1102 + struct mpi3_io_unit_page12 { 1103 + struct mpi3_config_page_header header; 1104 + __le32 flags; 1105 + __le32 reserved0c[4]; 1106 + u8 num_buckets; 1107 + u8 reserved1d[3]; 1108 + struct mpi3_iounit12_bucket bucket[MPI3_IOUNIT12_BUCKET_MAX]; 1109 + }; 1110 + #define MPI3_IOUNIT12_PAGEVERSION (0x00) 1111 + #define MPI3_IOUNIT12_FLAGS_NUMPASSES_MASK (0x00000300) 1112 + #define MPI3_IOUNIT12_FLAGS_NUMPASSES_SHIFT (8) 1113 + #define MPI3_IOUNIT12_FLAGS_NUMPASSES_8 (0x00000000) 1114 + #define MPI3_IOUNIT12_FLAGS_NUMPASSES_16 (0x00000100) 1115 + #define MPI3_IOUNIT12_FLAGS_NUMPASSES_32 (0x00000200) 1116 + #define MPI3_IOUNIT12_FLAGS_NUMPASSES_64 (0x00000300) 1117 + #define MPI3_IOUNIT12_FLAGS_PASSPERIOD_MASK (0x00000003) 1118 + #define MPI3_IOUNIT12_FLAGS_PASSPERIOD_DISABLED (0x00000000) 1119 + #define MPI3_IOUNIT12_FLAGS_PASSPERIOD_500US (0x00000001) 1120 + #define MPI3_IOUNIT12_FLAGS_PASSPERIOD_1MS (0x00000002) 1121 + #define MPI3_IOUNIT12_FLAGS_PASSPERIOD_2MS (0x00000003) 1122 + #ifndef MPI3_IOUNIT13_FUNC_MAX 1123 + #define MPI3_IOUNIT13_FUNC_MAX (1) 1124 + #endif 1125 + struct mpi3_iounit13_allowed_function { 1126 + __le16 sub_function; 1127 + u8 function_code; 1128 + u8 fuction_flags; 1129 + }; 1130 + #define MPI3_IOUNIT13_FUNCTION_FLAGS_ADMIN_BLOCKED (0x04) 1131 + #define MPI3_IOUNIT13_FUNCTION_FLAGS_OOB_BLOCKED (0x02) 1132 + #define MPI3_IOUNIT13_FUNCTION_FLAGS_CHECK_SUBFUNCTION_ENABLED (0x01) 1133 + struct mpi3_io_unit_page13 { 1134 + struct mpi3_config_page_header header; 1135 + __le16 flags; 1136 + __le16 reserved0a; 1137 + u8 num_allowed_functions; 1138 + u8 reserved0d[3]; 1139 + struct mpi3_iounit13_allowed_function allowed_function[MPI3_IOUNIT13_FUNC_MAX]; 1140 + }; 1141 + #define MPI3_IOUNIT13_PAGEVERSION (0x00) 1142 + #define MPI3_IOUNIT13_FLAGS_ADMIN_BLOCKED (0x0002) 1143 + #define MPI3_IOUNIT13_FLAGS_OOB_BLOCKED (0x0001) 1128 1144 struct mpi3_ioc_page0 { 1129 1145 struct mpi3_config_page_header header; 1130 1146 __le32 reserved08; ··· 1268 1182 __le32 reserved18; 1269 1183 }; 1270 1184 #define MPI3_DRIVER0_PAGEVERSION (0x00) 1185 + #define MPI3_DRIVER0_BSDOPTS_HEADLESS_MODE_ENABLE (0x00000008) 1271 1186 #define MPI3_DRIVER0_BSDOPTS_DIS_HII_CONFIG_UTIL (0x00000004) 1272 1187 #define MPI3_DRIVER0_BSDOPTS_REGISTRATION_MASK (0x00000003) 1273 1188 #define MPI3_DRIVER0_BSDOPTS_REGISTRATION_IOC_AND_DEVS (0x00000000) ··· 1993 1906 }; 1994 1907 1995 1908 #define MPI3_PCIEIOUNIT1_PAGEVERSION (0x00) 1996 - #define MPI3_PCIEIOUNIT1_CONTROL_FLAGS_LINK_OVERRIDE_DISABLE (0x80) 1997 - #define MPI3_PCIEIOUNIT1_CONTROL_FLAGS_CLOCK_OVERRIDE_DISABLE (0x40) 1998 - #define MPI3_PCIEIOUNIT1_CONTROL_FLAGS_CLOCK_OVERRIDE_MODE_MASK (0x30) 1909 + #define MPI3_PCIEIOUNIT1_CONTROL_FLAGS_PERST_OVERRIDE_MASK (0xe0000000) 1910 + #define MPI3_PCIEIOUNIT1_CONTROL_FLAGS_PERST_OVERRIDE_NONE (0x00000000) 1911 + #define MPI3_PCIEIOUNIT1_CONTROL_FLAGS_PERST_OVERRIDE_DEASSERT (0x20000000) 1912 + #define MPI3_PCIEIOUNIT1_CONTROL_FLAGS_PERST_OVERRIDE_ASSERT (0x40000000) 1913 + #define MPI3_PCIEIOUNIT1_CONTROL_FLAGS_PERST_OVERRIDE_BACKPLANE_ERROR (0x60000000) 1914 + #define MPI3_PCIEIOUNIT1_CONTROL_FLAGS_REFCLK_OVERRIDE_MASK (0x1c000000) 1915 + #define MPI3_PCIEIOUNIT1_CONTROL_FLAGS_REFCLK_OVERRIDE_NONE (0x00000000) 1916 + #define MPI3_PCIEIOUNIT1_CONTROL_FLAGS_REFCLK_OVERRIDE_DEASSERT (0x04000000) 1917 + #define MPI3_PCIEIOUNIT1_CONTROL_FLAGS_REFCLK_OVERRIDE_ASSERT (0x08000000) 1918 + #define MPI3_PCIEIOUNIT1_CONTROL_FLAGS_REFCLK_OVERRIDE_BACKPLANE_ERROR (0x0c000000) 1919 + #define MPI3_PCIEIOUNIT1_CONTROL_FLAGS_LINK_OVERRIDE_DISABLE (0x00000080) 1920 + #define MPI3_PCIEIOUNIT1_CONTROL_FLAGS_CLOCK_OVERRIDE_DISABLE (0x00000040) 1921 + #define MPI3_PCIEIOUNIT1_CONTROL_FLAGS_CLOCK_OVERRIDE_MODE_MASK (0x00000030) 1999 1922 #define MPI3_PCIEIOUNIT1_CONTROL_FLAGS_CLOCK_OVERRIDE_MODE_SHIFT (4) 2000 - #define MPI3_PCIEIOUNIT1_CONTROL_FLAGS_CLOCK_OVERRIDE_MODE_SRIS_SRNS_DISABLED (0x00) 2001 - #define MPI3_PCIEIOUNIT1_CONTROL_FLAGS_CLOCK_OVERRIDE_MODE_SRIS_ENABLED (0x10) 2002 - #define MPI3_PCIEIOUNIT1_CONTROL_FLAGS_CLOCK_OVERRIDE_MODE_SRNS_ENABLED (0x20) 2003 - #define MPI3_PCIEIOUNIT1_CONTROL_FLAGS_LINK_RATE_OVERRIDE_MASK (0x0f) 2004 - #define MPI3_PCIEIOUNIT1_CONTROL_FLAGS_LINK_RATE_OVERRIDE_MAX_2_5 (0x02) 2005 - #define MPI3_PCIEIOUNIT1_CONTROL_FLAGS_LINK_RATE_OVERRIDE_MAX_5_0 (0x03) 2006 - #define MPI3_PCIEIOUNIT1_CONTROL_FLAGS_LINK_RATE_OVERRIDE_MAX_8_0 (0x04) 2007 - #define MPI3_PCIEIOUNIT1_CONTROL_FLAGS_LINK_RATE_OVERRIDE_MAX_16_0 (0x05) 2008 - #define MPI3_PCIEIOUNIT1_CONTROL_FLAGS_LINK_RATE_OVERRIDE_MAX_32_0 (0x06) 1923 + #define MPI3_PCIEIOUNIT1_CONTROL_FLAGS_CLOCK_OVERRIDE_MODE_SRIS_SRNS_DISABLED (0x00000000) 1924 + #define MPI3_PCIEIOUNIT1_CONTROL_FLAGS_CLOCK_OVERRIDE_MODE_SRIS_ENABLED (0x00000010) 1925 + #define MPI3_PCIEIOUNIT1_CONTROL_FLAGS_CLOCK_OVERRIDE_MODE_SRNS_ENABLED (0x00000020) 1926 + #define MPI3_PCIEIOUNIT1_CONTROL_FLAGS_LINK_RATE_OVERRIDE_MASK (0x0000000f) 1927 + #define MPI3_PCIEIOUNIT1_CONTROL_FLAGS_LINK_RATE_OVERRIDE_USE_BACKPLANE (0x00000000) 1928 + #define MPI3_PCIEIOUNIT1_CONTROL_FLAGS_LINK_RATE_OVERRIDE_MAX_2_5 (0x00000002) 1929 + #define MPI3_PCIEIOUNIT1_CONTROL_FLAGS_LINK_RATE_OVERRIDE_MAX_5_0 (0x00000003) 1930 + #define MPI3_PCIEIOUNIT1_CONTROL_FLAGS_LINK_RATE_OVERRIDE_MAX_8_0 (0x00000004) 1931 + #define MPI3_PCIEIOUNIT1_CONTROL_FLAGS_LINK_RATE_OVERRIDE_MAX_16_0 (0x00000005) 1932 + #define MPI3_PCIEIOUNIT1_CONTROL_FLAGS_LINK_RATE_OVERRIDE_MAX_32_0 (0x00000006) 2009 1933 #define MPI3_PCIEIOUNIT1_ASPM_SWITCH_MASK (0x0c) 2010 1934 #define MPI3_PCIEIOUNIT1_ASPM_SWITCH_SHIFT (2) 2011 1935 #define MPI3_PCIEIOUNIT1_ASPM_DIRECT_MASK (0x03) ··· 2267 2169 #define MPI3_DEVICE0_VD_DEVICE_INFO_SATA (0x0002) 2268 2170 #define MPI3_DEVICE0_VD_DEVICE_INFO_SAS (0x0001) 2269 2171 #define MPI3_DEVICE0_VD_FLAGS_IO_THROTTLE_GROUP_QD_MASK (0xf000) 2270 - #define MPI3_DEVICE0_VD_FLAGS_METADATA_MODE_MASK (0x0003) 2271 - #define MPI3_DEVICE0_VD_FLAGS_METADATA_MODE_NONE (0x0000) 2272 - #define MPI3_DEVICE0_VD_FLAGS_METADATA_MODE_HOST (0x0001) 2273 - #define MPI3_DEVICE0_VD_FLAGS_METADATA_MODE_IOC (0x0002) 2172 + #define MPI3_DEVICE0_VD_FLAGS_IO_THROTTLE_GROUP_QD_SHIFT (12) 2274 2173 union mpi3_device0_dev_spec_format { 2275 2174 struct mpi3_device0_sas_sata_format sas_sata_format; 2276 2175 struct mpi3_device0_pcie_format pcie_format;
+4 -2
drivers/scsi/mpi3mr/mpi/mpi30_image.h
··· 1 1 /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 2 /* 3 - * Copyright 2018-2021 Broadcom Inc. All rights reserved. 4 - * 3 + * Copyright 2018-2022 Broadcom Inc. All rights reserved. 5 4 */ 6 5 #ifndef MPI30_IMAGE_H 7 6 #define MPI30_IMAGE_H 1 ··· 62 63 #define MPI3_IMAGE_HEADER_SIGNATURE1_PBLP (0x504c4250) 63 64 #define MPI3_IMAGE_HEADER_SIGNATURE1_MANIFEST (0x464e414d) 64 65 #define MPI3_IMAGE_HEADER_SIGNATURE1_OEM (0x204d454f) 66 + #define MPI3_IMAGE_HEADER_SIGNATURE1_RMC (0x20434d52) 67 + #define MPI3_IMAGE_HEADER_SIGNATURE1_SMM (0x204d4d53) 68 + #define MPI3_IMAGE_HEADER_SIGNATURE1_PSW (0x20575350) 65 69 #define MPI3_IMAGE_HEADER_SIGNATURE2_VALUE (0x50584546) 66 70 #define MPI3_IMAGE_HEADER_FLAGS_DEVICE_KEY_BASIS_MASK (0x00000030) 67 71 #define MPI3_IMAGE_HEADER_FLAGS_DEVICE_KEY_BASIS_CDI (0x00000000)
+2 -3
drivers/scsi/mpi3mr/mpi/mpi30_init.h
··· 1 1 /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 2 /* 3 - * Copyright 2016-2021 Broadcom Inc. All rights reserved. 4 - * 3 + * Copyright 2016-2022 Broadcom Inc. All rights reserved. 5 4 */ 6 5 #ifndef MPI30_INIT_H 7 6 #define MPI30_INIT_H 1 8 7 struct mpi3_scsi_io_cdb_eedp32 { 9 8 u8 cdb[20]; 10 - __be32 primary_reference_tag; 9 + __be32 primary_reference_tag; 11 10 __le16 primary_application_tag; 12 11 __le16 primary_application_tag_mask; 13 12 __le32 transfer_length;
+20 -2
drivers/scsi/mpi3mr/mpi/mpi30_ioc.h
··· 1 1 /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 2 /* 3 - * Copyright 2016-2021 Broadcom Inc. All rights reserved. 4 - * 3 + * Copyright 2016-2022 Broadcom Inc. All rights reserved. 5 4 */ 6 5 #ifndef MPI30_IOC_H 7 6 #define MPI30_IOC_H 1 ··· 157 158 #define MPI3_IOCFACTS_FLAGS_PERSONALITY_EHBA (0x00000000) 158 159 #define MPI3_IOCFACTS_FLAGS_PERSONALITY_RAID_DDR (0x00000002) 159 160 #define MPI3_IOCFACTS_IO_THROTTLE_DATA_LENGTH_NOT_REQUIRED (0x0000) 161 + #define MPI3_IOCFACTS_MAX_IO_THROTTLE_GROUP_NOT_REQUIRED (0x0000) 160 162 struct mpi3_mgmt_passthrough_request { 161 163 __le16 host_tag; 162 164 u8 ioc_use_only02; ··· 637 637 #define MPI3_EVENT_DIAG_BUFFER_STATUS_CHANGE_RC_RELEASED (0x01) 638 638 #define MPI3_EVENT_DIAG_BUFFER_STATUS_CHANGE_RC_PAUSED (0x02) 639 639 #define MPI3_EVENT_DIAG_BUFFER_STATUS_CHANGE_RC_RESUMED (0x03) 640 + #define MPI3_PEL_LOCALE_FLAGS_NON_BLOCKING_BOOT_EVENT (0x0200) 641 + #define MPI3_PEL_LOCALE_FLAGS_BLOCKING_BOOT_EVENT (0x0100) 642 + #define MPI3_PEL_LOCALE_FLAGS_PCIE (0x0080) 643 + #define MPI3_PEL_LOCALE_FLAGS_CONFIGURATION (0x0040) 644 + #define MPI3_PEL_LOCALE_FLAGS_CONTROLER (0x0020) 645 + #define MPI3_PEL_LOCALE_FLAGS_SAS (0x0010) 646 + #define MPI3_PEL_LOCALE_FLAGS_EPACK (0x0008) 647 + #define MPI3_PEL_LOCALE_FLAGS_ENCLOSURE (0x0004) 648 + #define MPI3_PEL_LOCALE_FLAGS_PD (0x0002) 649 + #define MPI3_PEL_LOCALE_FLAGS_VD (0x0001) 650 + #define MPI3_PEL_CLASS_DEBUG (0x00) 651 + #define MPI3_PEL_CLASS_PROGRESS (0x01) 652 + #define MPI3_PEL_CLASS_INFORMATIONAL (0x02) 653 + #define MPI3_PEL_CLASS_WARNING (0x03) 654 + #define MPI3_PEL_CLASS_CRITICAL (0x04) 655 + #define MPI3_PEL_CLASS_FATAL (0x05) 656 + #define MPI3_PEL_CLASS_FAULT (0x06) 640 657 #define MPI3_PEL_CLEARTYPE_CLEAR (0x00) 641 658 #define MPI3_PEL_WAITTIME_INFINITE_WAIT (0x00) 642 659 #define MPI3_PEL_ACTION_GET_SEQNUM (0x01) ··· 941 924 }; 942 925 943 926 #define MPI3_CI_DOWNLOAD_FLAGS_DOWNLOAD_IN_PROGRESS (0x80) 927 + #define MPI3_CI_DOWNLOAD_FLAGS_ACTIVATION_FAILURE (0x40) 944 928 #define MPI3_CI_DOWNLOAD_FLAGS_OFFLINE_ACTIVATION_REQUIRED (0x20) 945 929 #define MPI3_CI_DOWNLOAD_FLAGS_KEY_UPDATE_PENDING (0x10) 946 930 #define MPI3_CI_DOWNLOAD_FLAGS_ACTIVATION_STATUS_MASK (0x0e)
+1 -1
drivers/scsi/mpi3mr/mpi/mpi30_pci.h
··· 1 1 /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 2 /* 3 - * Copyright 2016-2021 Broadcom Inc. All rights reserved. 3 + * Copyright 2016-2022 Broadcom Inc. All rights reserved. 4 4 * 5 5 */ 6 6 #ifndef MPI30_PCI_H
+1 -2
drivers/scsi/mpi3mr/mpi/mpi30_sas.h
··· 1 1 /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 2 /* 3 - * Copyright 2016-2021 Broadcom Inc. All rights reserved. 4 - * 3 + * Copyright 2016-2022 Broadcom Inc. All rights reserved. 5 4 */ 6 5 #ifndef MPI30_SAS_H 7 6 #define MPI30_SAS_H 1
+4 -4
drivers/scsi/mpi3mr/mpi/mpi30_transport.h
··· 1 1 /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 2 /* 3 - * Copyright 2016-2021 Broadcom Inc. All rights reserved. 4 - * 3 + * Copyright 2016-2022 Broadcom Inc. All rights reserved. 5 4 */ 6 5 #ifndef MPI30_TRANSPORT_H 7 6 #define MPI30_TRANSPORT_H 1 ··· 18 19 19 20 #define MPI3_VERSION_MAJOR (3) 20 21 #define MPI3_VERSION_MINOR (0) 21 - #define MPI3_VERSION_UNIT (23) 22 - #define MPI3_VERSION_DEV (1) 22 + #define MPI3_VERSION_UNIT (26) 23 + #define MPI3_VERSION_DEV (0) 23 24 #define MPI3_DEVHANDLE_INVALID (0xffff) 24 25 struct mpi3_sysif_oper_queue_indexes { 25 26 __le16 producer_index; ··· 211 212 #define MPI3_REPLY_DESCRIPT_FLAGS_TYPE_SUCCESS (0x1000) 212 213 #define MPI3_REPLY_DESCRIPT_FLAGS_TYPE_TARGET_COMMAND_BUFFER (0x2000) 213 214 #define MPI3_REPLY_DESCRIPT_FLAGS_TYPE_STATUS (0x3000) 215 + #define MPI3_REPLY_DESCRIPT_REQUEST_QUEUE_ID_INVALID (0xffff) 214 216 struct mpi3_address_reply_descriptor { 215 217 __le64 reply_frame_address; 216 218 __le16 request_queue_ci;
+249 -3
drivers/scsi/mpi3mr/mpi3mr.h
··· 39 39 #include <scsi/scsi_host.h> 40 40 #include <scsi/scsi_tcq.h> 41 41 #include <uapi/scsi/scsi_bsg_mpi3mr.h> 42 + #include <scsi/scsi_transport_sas.h> 42 43 43 44 #include "mpi/mpi30_transport.h" 44 45 #include "mpi/mpi30_cnfg.h" ··· 56 55 extern int prot_mask; 57 56 extern atomic64_t event_counter; 58 57 59 - #define MPI3MR_DRIVER_VERSION "8.0.0.69.0" 60 - #define MPI3MR_DRIVER_RELDATE "16-March-2022" 58 + #define MPI3MR_DRIVER_VERSION "8.2.0.3.0" 59 + #define MPI3MR_DRIVER_RELDATE "08-September-2022" 61 60 62 61 #define MPI3MR_DRIVER_NAME "mpi3mr" 63 62 #define MPI3MR_DRIVER_LICENSE "GPL" ··· 98 97 #define MPI3MR_HOSTTAG_PEL_ABORT 3 99 98 #define MPI3MR_HOSTTAG_PEL_WAIT 4 100 99 #define MPI3MR_HOSTTAG_BLK_TMS 5 100 + #define MPI3MR_HOSTTAG_CFG_CMDS 6 101 + #define MPI3MR_HOSTTAG_TRANSPORT_CMDS 7 101 102 102 103 #define MPI3MR_NUM_DEVRMCMD 16 103 - #define MPI3MR_HOSTTAG_DEVRMCMD_MIN (MPI3MR_HOSTTAG_BLK_TMS + 1) 104 + #define MPI3MR_HOSTTAG_DEVRMCMD_MIN (MPI3MR_HOSTTAG_TRANSPORT_CMDS + 1) 104 105 #define MPI3MR_HOSTTAG_DEVRMCMD_MAX (MPI3MR_HOSTTAG_DEVRMCMD_MIN + \ 105 106 MPI3MR_NUM_DEVRMCMD - 1) 106 107 ··· 118 115 /* command/controller interaction timeout definitions in seconds */ 119 116 #define MPI3MR_INTADMCMD_TIMEOUT 60 120 117 #define MPI3MR_PORTENABLE_TIMEOUT 300 118 + #define MPI3MR_PORTENABLE_POLL_INTERVAL 5 121 119 #define MPI3MR_ABORTTM_TIMEOUT 60 122 120 #define MPI3MR_RESETTM_TIMEOUT 60 123 121 #define MPI3MR_RESET_HOST_IOWAIT_TIMEOUT 5 ··· 129 125 #define MPI3MR_RESET_ACK_TIMEOUT 30 130 126 131 127 #define MPI3MR_WATCHDOG_INTERVAL 1000 /* in milli seconds */ 128 + 129 + #define MPI3MR_DEFAULT_CFG_PAGE_SZ 1024 /* in bytes */ 130 + 131 + #define MPI3MR_RESET_TOPOLOGY_SETTLE_TIME 10 132 132 133 133 #define MPI3MR_SCMD_TIMEOUT (60 * HZ) 134 134 #define MPI3MR_EH_SCMD_TIMEOUT (60 * HZ) ··· 282 274 MPI3MR_RESET_FROM_SYSFS = 23, 283 275 MPI3MR_RESET_FROM_SYSFS_TIMEOUT = 24, 284 276 MPI3MR_RESET_FROM_FIRMWARE = 27, 277 + MPI3MR_RESET_FROM_CFG_REQ_TIMEOUT = 29, 278 + MPI3MR_RESET_FROM_SAS_TRANSPORT_TIMEOUT = 30, 285 279 }; 286 280 287 281 /* Queue type definitions */ ··· 431 421 * struct mpi3mr_intr_info - Interrupt cookie information 432 422 * 433 423 * @mrioc: Adapter instance reference 424 + * @os_irq: irq number 434 425 * @msix_index: MSIx index 435 426 * @op_reply_q: Associated operational reply queue 436 427 * @name: Dev name for the irq claiming device 437 428 */ 438 429 struct mpi3mr_intr_info { 439 430 struct mpi3mr_ioc *mrioc; 431 + int os_irq; 440 432 u16 msix_index; 441 433 struct op_reply_qinfo *op_reply_q; 442 434 char name[MPI3MR_NAME_LENGTH]; ··· 469 457 atomic_t pend_large_data_sz; 470 458 }; 471 459 460 + /* HBA port flags */ 461 + #define MPI3MR_HBA_PORT_FLAG_DIRTY 0x01 462 + 463 + /** 464 + * struct mpi3mr_hba_port - HBA's port information 465 + * @port_id: Port number 466 + * @flags: HBA port flags 467 + */ 468 + struct mpi3mr_hba_port { 469 + struct list_head list; 470 + u8 port_id; 471 + u8 flags; 472 + }; 473 + 474 + /** 475 + * struct mpi3mr_sas_port - Internal SAS port information 476 + * @port_list: List of ports belonging to a SAS node 477 + * @num_phys: Number of phys associated with port 478 + * @marked_responding: used while refresing the sas ports 479 + * @lowest_phy: lowest phy ID of current sas port 480 + * @phy_mask: phy_mask of current sas port 481 + * @hba_port: HBA port entry 482 + * @remote_identify: Attached device identification 483 + * @rphy: SAS transport layer rphy object 484 + * @port: SAS transport layer port object 485 + * @phy_list: mpi3mr_sas_phy objects belonging to this port 486 + */ 487 + struct mpi3mr_sas_port { 488 + struct list_head port_list; 489 + u8 num_phys; 490 + u8 marked_responding; 491 + int lowest_phy; 492 + u32 phy_mask; 493 + struct mpi3mr_hba_port *hba_port; 494 + struct sas_identify remote_identify; 495 + struct sas_rphy *rphy; 496 + struct sas_port *port; 497 + struct list_head phy_list; 498 + }; 499 + 500 + /** 501 + * struct mpi3mr_sas_phy - Internal SAS Phy information 502 + * @port_siblings: List of phys belonging to a port 503 + * @identify: Phy identification 504 + * @remote_identify: Attached device identification 505 + * @phy: SAS transport layer Phy object 506 + * @phy_id: Unique phy id within a port 507 + * @handle: Firmware device handle for this phy 508 + * @attached_handle: Firmware device handle for attached device 509 + * @phy_belongs_to_port: Flag to indicate phy belongs to port 510 + @hba_port: HBA port entry 511 + */ 512 + struct mpi3mr_sas_phy { 513 + struct list_head port_siblings; 514 + struct sas_identify identify; 515 + struct sas_identify remote_identify; 516 + struct sas_phy *phy; 517 + u8 phy_id; 518 + u16 handle; 519 + u16 attached_handle; 520 + u8 phy_belongs_to_port; 521 + struct mpi3mr_hba_port *hba_port; 522 + }; 523 + 524 + /** 525 + * struct mpi3mr_sas_node - SAS host/expander information 526 + * @list: List of sas nodes in a controller 527 + * @parent_dev: Parent device class 528 + * @num_phys: Number phys belonging to sas_node 529 + * @sas_address: SAS address of sas_node 530 + * @handle: Firmware device handle for this sas_host/expander 531 + * @sas_address_parent: SAS address of parent expander or host 532 + * @enclosure_handle: Firmware handle of enclosure of this node 533 + * @device_info: Capabilities of this sas_host/expander 534 + * @non_responding: used to refresh the expander devices during reset 535 + * @host_node: Flag to indicate this is a host_node 536 + * @hba_port: HBA port entry 537 + * @phy: A list of phys that make up this sas_host/expander 538 + * @sas_port_list: List of internal ports of this node 539 + * @rphy: sas_rphy object of this expander node 540 + */ 541 + struct mpi3mr_sas_node { 542 + struct list_head list; 543 + struct device *parent_dev; 544 + u8 num_phys; 545 + u64 sas_address; 546 + u16 handle; 547 + u64 sas_address_parent; 548 + u16 enclosure_handle; 549 + u64 enclosure_logical_id; 550 + u8 non_responding; 551 + u8 host_node; 552 + struct mpi3mr_hba_port *hba_port; 553 + struct mpi3mr_sas_phy *phy; 554 + struct list_head sas_port_list; 555 + struct sas_rphy *rphy; 556 + }; 557 + 558 + /** 559 + * struct mpi3mr_enclosure_node - enclosure information 560 + * @list: List of enclosures 561 + * @pg0: Enclosure page 0; 562 + */ 563 + struct mpi3mr_enclosure_node { 564 + struct list_head list; 565 + struct mpi3_enclosure_page0 pg0; 566 + }; 567 + 472 568 /** 473 569 * struct tgt_dev_sas_sata - SAS/SATA device specific 474 570 * information cached from firmware given data 475 571 * 476 572 * @sas_address: World wide unique SAS address 573 + * @sas_address_parent: Sas address of parent expander or host 477 574 * @dev_info: Device information bits 575 + * @phy_id: Phy identifier provided in device page 0 576 + * @attached_phy_id: Attached phy identifier provided in device page 0 577 + * @sas_transport_attached: Is this device exposed to transport 578 + * @pend_sas_rphy_add: Flag to check device is in process of add 579 + * @hba_port: HBA port entry 580 + * @rphy: SAS transport layer rphy object 478 581 */ 479 582 struct tgt_dev_sas_sata { 480 583 u64 sas_address; 584 + u64 sas_address_parent; 481 585 u16 dev_info; 586 + u8 phy_id; 587 + u8 attached_phy_id; 588 + u8 sas_transport_attached; 589 + u8 pend_sas_rphy_add; 590 + struct mpi3mr_hba_port *hba_port; 591 + struct sas_rphy *rphy; 482 592 }; 483 593 484 594 /** ··· 665 531 * @slot: Slot number 666 532 * @encl_handle: FW enclosure handle 667 533 * @perst_id: FW assigned Persistent ID 534 + * @devpg0_flag: Device Page0 flag 668 535 * @dev_type: SAS/SATA/PCIE device type 669 536 * @is_hidden: Should be exposed to upper layers or not 670 537 * @host_exposed: Already exposed to host or not 538 + * @io_unit_port: IO Unit port ID 539 + * @non_stl: Is this device not to be attached with SAS TL 671 540 * @io_throttle_enabled: I/O throttling needed or not 672 541 * @q_depth: Device specific Queue Depth 673 542 * @wwid: World wide ID 543 + * @enclosure_logical_id: Enclosure logical identifier 674 544 * @dev_spec: Device type specific information 675 545 * @ref_count: Reference count 676 546 */ ··· 686 548 u16 slot; 687 549 u16 encl_handle; 688 550 u16 perst_id; 551 + u16 devpg0_flag; 689 552 u8 dev_type; 690 553 u8 is_hidden; 691 554 u8 host_exposed; 555 + u8 io_unit_port; 556 + u8 non_stl; 692 557 u8 io_throttle_enabled; 693 558 u16 q_depth; 694 559 u64 wwid; 560 + u64 enclosure_logical_id; 695 561 union _form_spec_inf dev_spec; 696 562 struct kref ref_count; 697 563 }; ··· 821 679 struct mpi3mr_drv_cmd *drv_cmd); 822 680 }; 823 681 682 + /** 683 + * struct dma_memory_desc - memory descriptor structure to store 684 + * virtual address, dma address and size for any generic dma 685 + * memory allocations in the driver. 686 + * 687 + * @size: buffer size 688 + * @addr: virtual address 689 + * @dma_addr: dma address 690 + */ 691 + struct dma_memory_desc { 692 + u32 size; 693 + void *addr; 694 + dma_addr_t dma_addr; 695 + }; 696 + 824 697 825 698 /** 826 699 * struct chain_element - memory descriptor structure to store ··· 913 756 * @num_op_reply_q: Number of operational reply queues 914 757 * @op_reply_qinfo: Operational reply queue info pointer 915 758 * @init_cmds: Command tracker for initialization commands 759 + * @cfg_cmds: Command tracker for configuration requests 916 760 * @facts: Cached IOC facts data 917 761 * @op_reply_desc_sz: Operational reply descriptor size 918 762 * @num_reply_bufs: Number of reply buffers allocated ··· 950 792 * @scan_started: Async scan started 951 793 * @scan_failed: Asycn scan failed 952 794 * @stop_drv_processing: Stop all command processing 795 + * @device_refresh_on: Don't process the events until devices are refreshed 953 796 * @max_host_ios: Maximum host I/O count 954 797 * @chain_buf_count: Chain buffer count 955 798 * @chain_buf_pool: Chain buffer pool ··· 1013 854 * @io_throttle_low: I/O size to stop throttle in 512b blocks 1014 855 * @num_io_throttle_group: Maximum number of throttle groups 1015 856 * @throttle_groups: Pointer to throttle group info structures 857 + * @cfg_page: Default memory for configuration pages 858 + * @cfg_page_dma: Configuration page DMA address 859 + * @cfg_page_sz: Default configuration page memory size 860 + * @sas_transport_enabled: SAS transport enabled or not 861 + * @scsi_device_channel: Channel ID for SCSI devices 862 + * @transport_cmds: Command tracker for SAS transport commands 863 + * @sas_hba: SAS node for the controller 864 + * @sas_expander_list: SAS node list of expanders 865 + * @sas_node_lock: Lock to protect SAS node list 866 + * @hba_port_table_list: List of HBA Ports 867 + * @enclosure_list: List of Enclosure objects 1016 868 */ 1017 869 struct mpi3mr_ioc { 1018 870 struct list_head list; ··· 1074 904 struct op_reply_qinfo *op_reply_qinfo; 1075 905 1076 906 struct mpi3mr_drv_cmd init_cmds; 907 + struct mpi3mr_drv_cmd cfg_cmds; 1077 908 struct mpi3mr_ioc_facts facts; 1078 909 u16 op_reply_desc_sz; 1079 910 ··· 1119 948 u8 scan_started; 1120 949 u16 scan_failed; 1121 950 u8 stop_drv_processing; 951 + u8 device_refresh_on; 1122 952 1123 953 u16 max_host_ios; 1124 954 spinlock_t tgtdev_lock; ··· 1197 1025 u32 io_throttle_low; 1198 1026 u16 num_io_throttle_group; 1199 1027 struct mpi3mr_throttle_group_info *throttle_groups; 1028 + 1029 + void *cfg_page; 1030 + dma_addr_t cfg_page_dma; 1031 + u16 cfg_page_sz; 1032 + 1033 + u8 sas_transport_enabled; 1034 + u8 scsi_device_channel; 1035 + struct mpi3mr_drv_cmd transport_cmds; 1036 + struct mpi3mr_sas_node sas_hba; 1037 + struct list_head sas_expander_list; 1038 + spinlock_t sas_node_lock; 1039 + struct list_head hba_port_table_list; 1040 + struct list_head enclosure_list; 1200 1041 }; 1201 1042 1202 1043 /** ··· 1334 1149 struct mpi3mr_drv_cmd *drv_cmd); 1335 1150 void mpi3mr_app_save_logdata(struct mpi3mr_ioc *mrioc, char *event_data, 1336 1151 u16 event_data_size); 1152 + struct mpi3mr_enclosure_node *mpi3mr_enclosure_find_by_handle( 1153 + struct mpi3mr_ioc *mrioc, u16 handle); 1337 1154 extern const struct attribute_group *mpi3mr_host_groups[]; 1338 1155 extern const struct attribute_group *mpi3mr_dev_groups[]; 1156 + 1157 + extern struct sas_function_template mpi3mr_transport_functions; 1158 + extern struct scsi_transport_template *mpi3mr_transport_template; 1159 + 1160 + int mpi3mr_cfg_get_dev_pg0(struct mpi3mr_ioc *mrioc, u16 *ioc_status, 1161 + struct mpi3_device_page0 *dev_pg0, u16 pg_sz, u32 form, u32 form_spec); 1162 + int mpi3mr_cfg_get_sas_phy_pg0(struct mpi3mr_ioc *mrioc, u16 *ioc_status, 1163 + struct mpi3_sas_phy_page0 *phy_pg0, u16 pg_sz, u32 form, 1164 + u32 form_spec); 1165 + int mpi3mr_cfg_get_sas_phy_pg1(struct mpi3mr_ioc *mrioc, u16 *ioc_status, 1166 + struct mpi3_sas_phy_page1 *phy_pg1, u16 pg_sz, u32 form, 1167 + u32 form_spec); 1168 + int mpi3mr_cfg_get_sas_exp_pg0(struct mpi3mr_ioc *mrioc, u16 *ioc_status, 1169 + struct mpi3_sas_expander_page0 *exp_pg0, u16 pg_sz, u32 form, 1170 + u32 form_spec); 1171 + int mpi3mr_cfg_get_sas_exp_pg1(struct mpi3mr_ioc *mrioc, u16 *ioc_status, 1172 + struct mpi3_sas_expander_page1 *exp_pg1, u16 pg_sz, u32 form, 1173 + u32 form_spec); 1174 + int mpi3mr_cfg_get_enclosure_pg0(struct mpi3mr_ioc *mrioc, u16 *ioc_status, 1175 + struct mpi3_enclosure_page0 *encl_pg0, u16 pg_sz, u32 form, 1176 + u32 form_spec); 1177 + int mpi3mr_cfg_get_sas_io_unit_pg0(struct mpi3mr_ioc *mrioc, 1178 + struct mpi3_sas_io_unit_page0 *sas_io_unit_pg0, u16 pg_sz); 1179 + int mpi3mr_cfg_get_sas_io_unit_pg1(struct mpi3mr_ioc *mrioc, 1180 + struct mpi3_sas_io_unit_page1 *sas_io_unit_pg1, u16 pg_sz); 1181 + int mpi3mr_cfg_set_sas_io_unit_pg1(struct mpi3mr_ioc *mrioc, 1182 + struct mpi3_sas_io_unit_page1 *sas_io_unit_pg1, u16 pg_sz); 1183 + int mpi3mr_cfg_get_driver_pg1(struct mpi3mr_ioc *mrioc, 1184 + struct mpi3_driver_page1 *driver_pg1, u16 pg_sz); 1185 + 1186 + u8 mpi3mr_is_expander_device(u16 device_info); 1187 + int mpi3mr_expander_add(struct mpi3mr_ioc *mrioc, u16 handle); 1188 + void mpi3mr_expander_remove(struct mpi3mr_ioc *mrioc, u64 sas_address, 1189 + struct mpi3mr_hba_port *hba_port); 1190 + struct mpi3mr_sas_node *__mpi3mr_expander_find_by_handle(struct mpi3mr_ioc 1191 + *mrioc, u16 handle); 1192 + struct mpi3mr_hba_port *mpi3mr_get_hba_port_by_id(struct mpi3mr_ioc *mrioc, 1193 + u8 port_id); 1194 + void mpi3mr_sas_host_refresh(struct mpi3mr_ioc *mrioc); 1195 + void mpi3mr_sas_host_add(struct mpi3mr_ioc *mrioc); 1196 + void mpi3mr_update_links(struct mpi3mr_ioc *mrioc, 1197 + u64 sas_address_parent, u16 handle, u8 phy_number, u8 link_rate, 1198 + struct mpi3mr_hba_port *hba_port); 1199 + void mpi3mr_remove_tgtdev_from_host(struct mpi3mr_ioc *mrioc, 1200 + struct mpi3mr_tgt_dev *tgtdev); 1201 + int mpi3mr_report_tgtdev_to_sas_transport(struct mpi3mr_ioc *mrioc, 1202 + struct mpi3mr_tgt_dev *tgtdev); 1203 + void mpi3mr_remove_tgtdev_from_sas_transport(struct mpi3mr_ioc *mrioc, 1204 + struct mpi3mr_tgt_dev *tgtdev); 1205 + struct mpi3mr_tgt_dev *__mpi3mr_get_tgtdev_by_addr_and_rphy( 1206 + struct mpi3mr_ioc *mrioc, u64 sas_address, struct sas_rphy *rphy); 1207 + void mpi3mr_print_device_event_notice(struct mpi3mr_ioc *mrioc, 1208 + bool device_add); 1209 + void mpi3mr_refresh_sas_ports(struct mpi3mr_ioc *mrioc); 1210 + void mpi3mr_refresh_expanders(struct mpi3mr_ioc *mrioc); 1211 + void mpi3mr_add_event_wait_for_device_refresh(struct mpi3mr_ioc *mrioc); 1212 + void mpi3mr_flush_drv_cmds(struct mpi3mr_ioc *mrioc); 1213 + void mpi3mr_flush_cmds_for_unrecovered_controller(struct mpi3mr_ioc *mrioc); 1214 + void mpi3mr_free_enclosure_list(struct mpi3mr_ioc *mrioc); 1339 1215 #endif /*MPI3MR_H_INCLUDED*/
+27
drivers/scsi/mpi3mr/mpi3mr_debug.h
··· 23 23 #define MPI3_DEBUG_RESET 0x00000020 24 24 #define MPI3_DEBUG_SCSI_ERROR 0x00000040 25 25 #define MPI3_DEBUG_REPLY 0x00000080 26 + #define MPI3_DEBUG_CFG_ERROR 0x00000100 27 + #define MPI3_DEBUG_TRANSPORT_ERROR 0x00000200 26 28 #define MPI3_DEBUG_BSG_ERROR 0x00008000 27 29 #define MPI3_DEBUG_BSG_INFO 0x00010000 28 30 #define MPI3_DEBUG_SCSI_INFO 0x00020000 31 + #define MPI3_DEBUG_CFG_INFO 0x00040000 32 + #define MPI3_DEBUG_TRANSPORT_INFO 0x00080000 29 33 #define MPI3_DEBUG 0x01000000 30 34 #define MPI3_DEBUG_SG 0x02000000 31 35 ··· 123 119 #define dprint_bsg_err(ioc, fmt, ...) \ 124 120 do { \ 125 121 if (ioc->logging_level & MPI3_DEBUG_BSG_ERROR) \ 122 + pr_info("%s: " fmt, (ioc)->name, ##__VA_ARGS__); \ 123 + } while (0) 124 + 125 + #define dprint_cfg_info(ioc, fmt, ...) \ 126 + do { \ 127 + if (ioc->logging_level & MPI3_DEBUG_CFG_INFO) \ 128 + pr_info("%s: " fmt, (ioc)->name, ##__VA_ARGS__); \ 129 + } while (0) 130 + 131 + #define dprint_cfg_err(ioc, fmt, ...) \ 132 + do { \ 133 + if (ioc->logging_level & MPI3_DEBUG_CFG_ERROR) \ 134 + pr_info("%s: " fmt, (ioc)->name, ##__VA_ARGS__); \ 135 + } while (0) 136 + #define dprint_transport_info(ioc, fmt, ...) \ 137 + do { \ 138 + if (ioc->logging_level & MPI3_DEBUG_TRANSPORT_INFO) \ 139 + pr_info("%s: " fmt, (ioc)->name, ##__VA_ARGS__); \ 140 + } while (0) 141 + 142 + #define dprint_transport_err(ioc, fmt, ...) \ 143 + do { \ 144 + if (ioc->logging_level & MPI3_DEBUG_TRANSPORT_ERROR) \ 126 145 pr_info("%s: " fmt, (ioc)->name, ##__VA_ARGS__); \ 127 146 } while (0) 128 147
+1012 -20
drivers/scsi/mpi3mr/mpi3mr_fw.c
··· 244 244 case MPI3_EVENT_ENCL_DEVICE_STATUS_CHANGE: 245 245 desc = "Enclosure Device Status Change"; 246 246 break; 247 + case MPI3_EVENT_ENCL_DEVICE_ADDED: 248 + desc = "Enclosure Added"; 249 + break; 247 250 case MPI3_EVENT_HARD_RESET_RECEIVED: 248 251 desc = "Hard Reset Received"; 249 252 break; ··· 302 299 switch (host_tag) { 303 300 case MPI3MR_HOSTTAG_INITCMDS: 304 301 return &mrioc->init_cmds; 302 + case MPI3MR_HOSTTAG_CFG_CMDS: 303 + return &mrioc->cfg_cmds; 305 304 case MPI3MR_HOSTTAG_BSG_CMDS: 306 305 return &mrioc->bsg_cmds; 307 306 case MPI3MR_HOSTTAG_BLK_TMS: ··· 312 307 return &mrioc->pel_abort_cmd; 313 308 case MPI3MR_HOSTTAG_PEL_WAIT: 314 309 return &mrioc->pel_cmds; 310 + case MPI3MR_HOSTTAG_TRANSPORT_CMDS: 311 + return &mrioc->transport_cmds; 315 312 case MPI3MR_HOSTTAG_INVALID: 316 313 if (def_reply && def_reply->function == 317 314 MPI3_FUNCTION_EVENT_NOTIFICATION) ··· 431 424 return 0; 432 425 433 426 do { 427 + if (mrioc->unrecoverable) 428 + break; 429 + 434 430 mrioc->admin_req_ci = le16_to_cpu(reply_desc->request_queue_ci); 435 431 mpi3mr_process_admin_reply_desc(mrioc, reply_desc, &reply_dma); 436 432 if (reply_dma) ··· 519 509 } 520 510 521 511 do { 512 + if (mrioc->unrecoverable) 513 + break; 514 + 522 515 req_q_idx = le16_to_cpu(reply_desc->request_queue_id) - 1; 523 516 op_req_q = &mrioc->req_qinfo[req_q_idx]; 524 517 ··· 543 530 if ((le16_to_cpu(reply_desc->reply_flags) & 544 531 MPI3_REPLY_DESCRIPT_FLAGS_PHASE_MASK) != exp_phase) 545 532 break; 533 + #ifndef CONFIG_PREEMPT_RT 546 534 /* 547 535 * Exit completion loop to avoid CPU lockup 548 536 * Ensure remaining completion happens from threaded ISR. ··· 552 538 op_reply_q->enable_irq_poll = true; 553 539 break; 554 540 } 555 - 541 + #endif 556 542 } while (1); 557 543 558 544 writel(reply_ci, ··· 583 569 584 570 mrioc = (struct mpi3mr_ioc *)shost->hostdata; 585 571 586 - if ((mrioc->reset_in_progress || mrioc->prepare_for_reset)) 572 + if ((mrioc->reset_in_progress || mrioc->prepare_for_reset || 573 + mrioc->unrecoverable)) 587 574 return 0; 588 575 589 576 num_entries = mpi3mr_process_op_reply_q(mrioc, ··· 622 607 return IRQ_NONE; 623 608 } 624 609 610 + #ifndef CONFIG_PREEMPT_RT 611 + 625 612 static irqreturn_t mpi3mr_isr(int irq, void *privdata) 626 613 { 627 614 struct mpi3mr_intr_info *intr_info = privdata; 628 - struct mpi3mr_ioc *mrioc; 629 - u16 midx; 630 615 int ret; 631 616 632 617 if (!intr_info) 633 618 return IRQ_NONE; 634 619 635 - mrioc = intr_info->mrioc; 636 - midx = intr_info->msix_index; 637 620 /* Call primary ISR routine */ 638 621 ret = mpi3mr_isr_primary(irq, privdata); 639 622 ··· 646 633 !atomic_read(&intr_info->op_reply_q->pend_ios)) 647 634 return ret; 648 635 649 - disable_irq_nosync(pci_irq_vector(mrioc->pdev, midx)); 636 + disable_irq_nosync(intr_info->os_irq); 650 637 651 638 return IRQ_WAKE_THREAD; 652 639 } ··· 676 663 677 664 /* Poll for pending IOs completions */ 678 665 do { 679 - if (!mrioc->intr_enabled) 666 + if (!mrioc->intr_enabled || mrioc->unrecoverable) 680 667 break; 681 668 682 669 if (!midx) ··· 692 679 (num_op_reply < mrioc->max_host_ios)); 693 680 694 681 intr_info->op_reply_q->enable_irq_poll = false; 695 - enable_irq(pci_irq_vector(mrioc->pdev, midx)); 682 + enable_irq(intr_info->os_irq); 696 683 697 684 return IRQ_HANDLED; 698 685 } 686 + 687 + #endif 699 688 700 689 /** 701 690 * mpi3mr_request_irq - Request IRQ and register ISR ··· 721 706 snprintf(intr_info->name, MPI3MR_NAME_LENGTH, "%s%d-msix%d", 722 707 mrioc->driver_name, mrioc->id, index); 723 708 709 + #ifndef CONFIG_PREEMPT_RT 724 710 retval = request_threaded_irq(pci_irq_vector(pdev, index), mpi3mr_isr, 725 711 mpi3mr_isr_poll, IRQF_SHARED, intr_info->name, intr_info); 712 + #else 713 + retval = request_threaded_irq(pci_irq_vector(pdev, index), mpi3mr_isr_primary, 714 + NULL, IRQF_SHARED, intr_info->name, intr_info); 715 + #endif 726 716 if (retval) { 727 717 ioc_err(mrioc, "%s: Unable to allocate interrupt %d!\n", 728 718 intr_info->name, pci_irq_vector(pdev, index)); 729 719 return retval; 730 720 } 731 721 722 + intr_info->os_irq = pci_irq_vector(pdev, index); 732 723 return retval; 733 724 } 734 725 ··· 928 907 { MPI3MR_RESET_FROM_SYSFS, "sysfs invocation" }, 929 908 { MPI3MR_RESET_FROM_SYSFS_TIMEOUT, "sysfs TM timeout" }, 930 909 { MPI3MR_RESET_FROM_FIRMWARE, "firmware asynchronous reset" }, 910 + { MPI3MR_RESET_FROM_CFG_REQ_TIMEOUT, "configuration request timeout"}, 911 + { MPI3MR_RESET_FROM_SAS_TRANSPORT_TIMEOUT, "timeout of a SAS transport layer request" }, 931 912 }; 932 913 933 914 /** ··· 1153 1130 return -EPERM; 1154 1131 } 1155 1132 1133 + if ((mrioc->sas_transport_enabled) && (mrioc->facts.ioc_capabilities & 1134 + MPI3_IOCFACTS_CAPABILITY_MULTIPATH_ENABLED)) 1135 + ioc_err(mrioc, 1136 + "critical error: multipath capability is enabled at the\n" 1137 + "\tcontroller while sas transport support is enabled at the\n" 1138 + "\tdriver, please reboot the system or reload the driver\n"); 1139 + 1156 1140 dev_handle_bitmap_sz = mrioc->facts.max_devhandle / 8; 1157 1141 if (mrioc->facts.max_devhandle % 8) 1158 1142 dev_handle_bitmap_sz++; ··· 1224 1194 msleep(100); 1225 1195 } while (--timeout); 1226 1196 1197 + if (!pci_device_is_present(mrioc->pdev)) { 1198 + mrioc->unrecoverable = 1; 1199 + ioc_err(mrioc, 1200 + "controller is not present while waiting to reset\n"); 1201 + retval = -1; 1202 + goto out_device_not_present; 1203 + } 1204 + 1227 1205 ioc_state = mpi3mr_get_iocstate(mrioc); 1228 1206 ioc_info(mrioc, 1229 1207 "controller is in %s state after waiting to reset\n", ··· 1289 1251 mpi3mr_iocstate_name(ioc_state)); 1290 1252 return 0; 1291 1253 } 1254 + if (!pci_device_is_present(mrioc->pdev)) { 1255 + mrioc->unrecoverable = 1; 1256 + ioc_err(mrioc, 1257 + "controller is not present at the bringup\n"); 1258 + retval = -1; 1259 + goto out_device_not_present; 1260 + } 1292 1261 msleep(100); 1293 1262 } while (--timeout); 1294 1263 ··· 1304 1259 ioc_err(mrioc, 1305 1260 "failed to bring to ready state, current state: %s\n", 1306 1261 mpi3mr_iocstate_name(ioc_state)); 1262 + out_device_not_present: 1307 1263 return retval; 1308 1264 } 1309 1265 ··· 2209 2163 pi = 0; 2210 2164 op_req_q->pi = pi; 2211 2165 2166 + #ifndef CONFIG_PREEMPT_RT 2212 2167 if (atomic_inc_return(&mrioc->op_reply_qinfo[reply_qidx].pend_ios) 2213 2168 > MPI3MR_IRQ_POLL_TRIGGER_IOCOUNT) 2214 2169 mrioc->op_reply_qinfo[reply_qidx].enable_irq_poll = true; 2170 + #else 2171 + atomic_inc_return(&mrioc->op_reply_qinfo[reply_qidx].pend_ios); 2172 + #endif 2215 2173 2216 2174 writel(op_req_q->pi, 2217 2175 &mrioc->sysif_regs->oper_queue_indexes[reply_qidx].producer_index); ··· 2242 2192 void mpi3mr_check_rh_fault_ioc(struct mpi3mr_ioc *mrioc, u32 reason_code) 2243 2193 { 2244 2194 u32 ioc_status, host_diagnostic, timeout; 2195 + 2196 + if (mrioc->unrecoverable) { 2197 + ioc_err(mrioc, "controller is unrecoverable\n"); 2198 + return; 2199 + } 2200 + 2201 + if (!pci_device_is_present(mrioc->pdev)) { 2202 + mrioc->unrecoverable = 1; 2203 + ioc_err(mrioc, "controller is not present\n"); 2204 + return; 2205 + } 2245 2206 2246 2207 ioc_status = readl(&mrioc->sysif_regs->ioc_status); 2247 2208 if ((ioc_status & MPI3_SYSIF_IOC_STATUS_RESET_HISTORY) || ··· 2445 2384 u32 fault, host_diagnostic, ioc_status; 2446 2385 u32 reset_reason = MPI3MR_RESET_FROM_FAULT_WATCH; 2447 2386 2448 - if (mrioc->reset_in_progress || mrioc->unrecoverable) 2387 + if (mrioc->reset_in_progress) 2449 2388 return; 2389 + 2390 + if (!mrioc->unrecoverable && !pci_device_is_present(mrioc->pdev)) { 2391 + ioc_err(mrioc, "watchdog could not detect the controller\n"); 2392 + mrioc->unrecoverable = 1; 2393 + } 2394 + 2395 + if (mrioc->unrecoverable) { 2396 + ioc_err(mrioc, 2397 + "flush pending commands for unrecoverable controller\n"); 2398 + mpi3mr_flush_cmds_for_unrecovered_controller(mrioc); 2399 + return; 2400 + } 2450 2401 2451 2402 if (mrioc->ts_update_counter++ >= MPI3MR_TSUPDATE_INTERVAL) { 2452 2403 mrioc->ts_update_counter = 0; ··· 2499 2426 mrioc->diagsave_timeout = 0; 2500 2427 2501 2428 switch (fault) { 2429 + case MPI3_SYSIF_FAULT_CODE_COMPLETE_RESET_NEEDED: 2502 2430 case MPI3_SYSIF_FAULT_CODE_POWER_CYCLE_REQUIRED: 2503 - ioc_info(mrioc, 2431 + ioc_warn(mrioc, 2504 2432 "controller requires system power cycle, marking controller as unrecoverable\n"); 2505 2433 mrioc->unrecoverable = 1; 2506 - return; 2434 + goto schedule_work; 2507 2435 case MPI3_SYSIF_FAULT_CODE_SOFT_RESET_IN_PROGRESS: 2508 2436 return; 2509 2437 case MPI3_SYSIF_FAULT_CODE_CI_ACTIVATION_RESET: ··· 2925 2851 2926 2852 mrioc->bsg_cmds.reply = kzalloc(mrioc->reply_sz, GFP_KERNEL); 2927 2853 if (!mrioc->bsg_cmds.reply) 2854 + goto out_failed; 2855 + 2856 + mrioc->transport_cmds.reply = kzalloc(mrioc->reply_sz, GFP_KERNEL); 2857 + if (!mrioc->transport_cmds.reply) 2928 2858 goto out_failed; 2929 2859 2930 2860 for (i = 0; i < MPI3MR_NUM_DEVRMCMD; i++) { ··· 3440 3362 static void mpi3mr_port_enable_complete(struct mpi3mr_ioc *mrioc, 3441 3363 struct mpi3mr_drv_cmd *drv_cmd) 3442 3364 { 3443 - drv_cmd->state = MPI3MR_CMD_NOTUSED; 3444 3365 drv_cmd->callback = NULL; 3445 - mrioc->scan_failed = drv_cmd->ioc_status; 3446 3366 mrioc->scan_started = 0; 3367 + if (drv_cmd->state & MPI3MR_CMD_RESET) 3368 + mrioc->scan_failed = MPI3_IOCSTATUS_INTERNAL_ERROR; 3369 + else 3370 + mrioc->scan_failed = drv_cmd->ioc_status; 3371 + drv_cmd->state = MPI3MR_CMD_NOTUSED; 3447 3372 } 3448 3373 3449 3374 /** ··· 3528 3447 char *name; 3529 3448 } mpi3mr_capabilities[] = { 3530 3449 { MPI3_IOCFACTS_CAPABILITY_RAID_CAPABLE, "RAID" }, 3450 + { MPI3_IOCFACTS_CAPABILITY_MULTIPATH_ENABLED, "MultiPath" }, 3531 3451 }; 3532 3452 3533 3453 /** ··· 3739 3657 mpi3mr_unmask_events(mrioc, MPI3_EVENT_DEVICE_INFO_CHANGED); 3740 3658 mpi3mr_unmask_events(mrioc, MPI3_EVENT_DEVICE_STATUS_CHANGE); 3741 3659 mpi3mr_unmask_events(mrioc, MPI3_EVENT_ENCL_DEVICE_STATUS_CHANGE); 3660 + mpi3mr_unmask_events(mrioc, MPI3_EVENT_ENCL_DEVICE_ADDED); 3742 3661 mpi3mr_unmask_events(mrioc, MPI3_EVENT_SAS_TOPOLOGY_CHANGE_LIST); 3743 3662 mpi3mr_unmask_events(mrioc, MPI3_EVENT_SAS_DISCOVERY); 3744 3663 mpi3mr_unmask_events(mrioc, MPI3_EVENT_SAS_DEVICE_DISCOVERY_ERROR); ··· 3810 3727 mrioc->max_host_ios = min_t(int, mrioc->max_host_ios, 3811 3728 MPI3MR_HOST_IOS_KDUMP); 3812 3729 3730 + if (!(mrioc->facts.ioc_capabilities & 3731 + MPI3_IOCFACTS_CAPABILITY_MULTIPATH_ENABLED)) { 3732 + mrioc->sas_transport_enabled = 1; 3733 + mrioc->scsi_device_channel = 1; 3734 + mrioc->shost->max_channel = 1; 3735 + mrioc->shost->transportt = mpi3mr_transport_template; 3736 + } 3737 + 3813 3738 mrioc->reply_sz = mrioc->facts.reply_sz; 3814 3739 3815 3740 retval = mpi3mr_check_reset_dma_mask(mrioc); ··· 3828 3737 } 3829 3738 3830 3739 mpi3mr_print_ioc_info(mrioc); 3740 + 3741 + dprint_init(mrioc, "allocating config page buffers\n"); 3742 + mrioc->cfg_page = dma_alloc_coherent(&mrioc->pdev->dev, 3743 + MPI3MR_DEFAULT_CFG_PAGE_SZ, &mrioc->cfg_page_dma, GFP_KERNEL); 3744 + if (!mrioc->cfg_page) 3745 + goto out_failed_noretry; 3746 + 3747 + mrioc->cfg_page_sz = MPI3MR_DEFAULT_CFG_PAGE_SZ; 3831 3748 3832 3749 retval = mpi3mr_alloc_reply_sense_bufs(mrioc); 3833 3750 if (retval) { ··· 3894 3795 if (!mrioc->throttle_groups && mrioc->num_io_throttle_group) { 3895 3796 dprint_init(mrioc, "allocating memory for throttle groups\n"); 3896 3797 sz = sizeof(struct mpi3mr_throttle_group_info); 3897 - mrioc->throttle_groups = (struct mpi3mr_throttle_group_info *) 3898 - kcalloc(mrioc->num_io_throttle_group, sz, GFP_KERNEL); 3798 + mrioc->throttle_groups = kcalloc(mrioc->num_io_throttle_group, sz, GFP_KERNEL); 3899 3799 if (!mrioc->throttle_groups) 3900 3800 goto out_failed_noretry; 3901 3801 } ··· 3943 3845 int retval = 0; 3944 3846 u8 retry = 0; 3945 3847 struct mpi3_ioc_facts_data facts_data; 3848 + u32 pe_timeout, ioc_status; 3946 3849 3947 3850 retry_init: 3851 + pe_timeout = 3852 + (MPI3MR_PORTENABLE_TIMEOUT / MPI3MR_PORTENABLE_POLL_INTERVAL); 3853 + 3948 3854 dprint_reset(mrioc, "bringing up the controller to ready state\n"); 3949 3855 retval = mpi3mr_bring_ioc_ready(mrioc); 3950 3856 if (retval) { ··· 4038 3936 goto out_failed; 4039 3937 } 4040 3938 3939 + mrioc->device_refresh_on = 1; 3940 + mpi3mr_add_event_wait_for_device_refresh(mrioc); 3941 + 4041 3942 ioc_info(mrioc, "sending port enable\n"); 4042 - retval = mpi3mr_issue_port_enable(mrioc, 0); 3943 + retval = mpi3mr_issue_port_enable(mrioc, 1); 4043 3944 if (retval) { 4044 3945 ioc_err(mrioc, "failed to issue port enable\n"); 4045 3946 goto out_failed; 4046 3947 } 3948 + do { 3949 + ssleep(MPI3MR_PORTENABLE_POLL_INTERVAL); 3950 + if (mrioc->init_cmds.state == MPI3MR_CMD_NOTUSED) 3951 + break; 3952 + if (!pci_device_is_present(mrioc->pdev)) 3953 + mrioc->unrecoverable = 1; 3954 + if (mrioc->unrecoverable) { 3955 + retval = -1; 3956 + goto out_failed_noretry; 3957 + } 3958 + ioc_status = readl(&mrioc->sysif_regs->ioc_status); 3959 + if ((ioc_status & MPI3_SYSIF_IOC_STATUS_RESET_HISTORY) || 3960 + (ioc_status & MPI3_SYSIF_IOC_STATUS_FAULT)) { 3961 + mpi3mr_print_fault_info(mrioc); 3962 + mrioc->init_cmds.is_waiting = 0; 3963 + mrioc->init_cmds.callback = NULL; 3964 + mrioc->init_cmds.state = MPI3MR_CMD_NOTUSED; 3965 + goto out_failed; 3966 + } 3967 + } while (--pe_timeout); 3968 + 3969 + if (!pe_timeout) { 3970 + ioc_err(mrioc, "port enable timed out\n"); 3971 + mpi3mr_check_rh_fault_ioc(mrioc, 3972 + MPI3MR_RESET_FROM_PE_TIMEOUT); 3973 + mrioc->init_cmds.is_waiting = 0; 3974 + mrioc->init_cmds.callback = NULL; 3975 + mrioc->init_cmds.state = MPI3MR_CMD_NOTUSED; 3976 + goto out_failed; 3977 + } else if (mrioc->scan_failed) { 3978 + ioc_err(mrioc, 3979 + "port enable failed with status=0x%04x\n", 3980 + mrioc->scan_failed); 3981 + } else 3982 + ioc_info(mrioc, "port enable completed successfully\n"); 4047 3983 4048 3984 ioc_info(mrioc, "controller %s completed successfully\n", 4049 3985 (is_resume)?"resume":"re-initialization"); ··· 4182 4042 sizeof(*mrioc->pel_cmds.reply)); 4183 4043 memset(mrioc->pel_abort_cmd.reply, 0, 4184 4044 sizeof(*mrioc->pel_abort_cmd.reply)); 4045 + memset(mrioc->transport_cmds.reply, 0, 4046 + sizeof(*mrioc->transport_cmds.reply)); 4185 4047 for (i = 0; i < MPI3MR_NUM_DEVRMCMD; i++) 4186 4048 memset(mrioc->dev_rmhs_cmds[i].reply, 0, 4187 4049 sizeof(*mrioc->dev_rmhs_cmds[i].reply)); ··· 4243 4101 { 4244 4102 u16 i; 4245 4103 struct mpi3mr_intr_info *intr_info; 4104 + 4105 + mpi3mr_free_enclosure_list(mrioc); 4246 4106 4247 4107 if (mrioc->sense_buf_pool) { 4248 4108 if (mrioc->sense_buf) ··· 4330 4186 4331 4187 kfree(mrioc->chain_bitmap); 4332 4188 mrioc->chain_bitmap = NULL; 4189 + 4190 + kfree(mrioc->transport_cmds.reply); 4191 + mrioc->transport_cmds.reply = NULL; 4333 4192 4334 4193 for (i = 0; i < MPI3MR_NUM_DEVRMCMD; i++) { 4335 4194 kfree(mrioc->dev_rmhs_cmds[i].reply); ··· 4502 4355 * 4503 4356 * Return: Nothing. 4504 4357 */ 4505 - static void mpi3mr_flush_drv_cmds(struct mpi3mr_ioc *mrioc) 4358 + void mpi3mr_flush_drv_cmds(struct mpi3mr_ioc *mrioc) 4506 4359 { 4507 4360 struct mpi3mr_drv_cmd *cmdptr; 4508 4361 u8 i; 4509 4362 4510 4363 cmdptr = &mrioc->init_cmds; 4511 4364 mpi3mr_drv_cmd_comp_reset(mrioc, cmdptr); 4365 + 4366 + cmdptr = &mrioc->cfg_cmds; 4367 + mpi3mr_drv_cmd_comp_reset(mrioc, cmdptr); 4368 + 4512 4369 cmdptr = &mrioc->bsg_cmds; 4513 4370 mpi3mr_drv_cmd_comp_reset(mrioc, cmdptr); 4514 4371 cmdptr = &mrioc->host_tm_cmds; ··· 4534 4383 cmdptr = &mrioc->pel_abort_cmd; 4535 4384 mpi3mr_drv_cmd_comp_reset(mrioc, cmdptr); 4536 4385 4386 + cmdptr = &mrioc->transport_cmds; 4387 + mpi3mr_drv_cmd_comp_reset(mrioc, cmdptr); 4537 4388 } 4538 4389 4539 4390 /** ··· 4834 4681 ioc_info(mrioc, "controller reset is triggered by %s\n", 4835 4682 mpi3mr_reset_rc_name(reset_reason)); 4836 4683 4684 + mrioc->device_refresh_on = 0; 4837 4685 mrioc->reset_in_progress = 1; 4838 4686 mrioc->stop_bsgs = 1; 4839 4687 mrioc->prev_reset_result = -1; ··· 4893 4739 mpi3mr_flush_host_io(mrioc); 4894 4740 mpi3mr_cleanup_fwevt_list(mrioc); 4895 4741 mpi3mr_invalidate_devhandles(mrioc); 4742 + mpi3mr_free_enclosure_list(mrioc); 4743 + 4896 4744 if (mrioc->prepare_for_reset) { 4897 4745 mrioc->prepare_for_reset = 0; 4898 4746 mrioc->prepare_for_reset_timeout_counter = 0; ··· 4906 4750 mrioc->name, reset_reason); 4907 4751 goto out; 4908 4752 } 4909 - ssleep(10); 4753 + ssleep(MPI3MR_RESET_TOPOLOGY_SETTLE_TIME); 4910 4754 4911 4755 out: 4912 4756 if (!retval) { ··· 4918 4762 mpi3mr_pel_wait_post(mrioc, &mrioc->pel_cmds); 4919 4763 } 4920 4764 4921 - mpi3mr_rfresh_tgtdevs(mrioc); 4765 + mrioc->device_refresh_on = 0; 4766 + 4922 4767 mrioc->ts_update_counter = 0; 4923 4768 spin_lock_irqsave(&mrioc->watchdog_lock, flags); 4924 4769 if (mrioc->watchdog_work_q) ··· 4933 4776 } else { 4934 4777 mpi3mr_issue_reset(mrioc, 4935 4778 MPI3_SYSIF_HOST_DIAG_RESET_ACTION_DIAG_FAULT, reset_reason); 4779 + mrioc->device_refresh_on = 0; 4936 4780 mrioc->unrecoverable = 1; 4937 4781 mrioc->reset_in_progress = 0; 4938 4782 retval = -1; 4783 + mpi3mr_flush_cmds_for_unrecovered_controller(mrioc); 4939 4784 } 4940 4785 mrioc->prev_reset_result = retval; 4941 4786 mutex_unlock(&mrioc->reset_mutex); 4942 4787 ioc_info(mrioc, "controller reset is %s\n", 4943 4788 ((retval == 0) ? "successful" : "failed")); 4944 4789 return retval; 4790 + } 4791 + 4792 + 4793 + /** 4794 + * mpi3mr_free_config_dma_memory - free memory for config page 4795 + * @mrioc: Adapter instance reference 4796 + * @mem_desc: memory descriptor structure 4797 + * 4798 + * Check whether the size of the buffer specified by the memory 4799 + * descriptor is greater than the default page size if so then 4800 + * free the memory pointed by the descriptor. 4801 + * 4802 + * Return: Nothing. 4803 + */ 4804 + static void mpi3mr_free_config_dma_memory(struct mpi3mr_ioc *mrioc, 4805 + struct dma_memory_desc *mem_desc) 4806 + { 4807 + if ((mem_desc->size > mrioc->cfg_page_sz) && mem_desc->addr) { 4808 + dma_free_coherent(&mrioc->pdev->dev, mem_desc->size, 4809 + mem_desc->addr, mem_desc->dma_addr); 4810 + mem_desc->addr = NULL; 4811 + } 4812 + } 4813 + 4814 + /** 4815 + * mpi3mr_alloc_config_dma_memory - Alloc memory for config page 4816 + * @mrioc: Adapter instance reference 4817 + * @mem_desc: Memory descriptor to hold dma memory info 4818 + * 4819 + * This function allocates new dmaable memory or provides the 4820 + * default config page dmaable memory based on the memory size 4821 + * described by the descriptor. 4822 + * 4823 + * Return: 0 on success, non-zero on failure. 4824 + */ 4825 + static int mpi3mr_alloc_config_dma_memory(struct mpi3mr_ioc *mrioc, 4826 + struct dma_memory_desc *mem_desc) 4827 + { 4828 + if (mem_desc->size > mrioc->cfg_page_sz) { 4829 + mem_desc->addr = dma_alloc_coherent(&mrioc->pdev->dev, 4830 + mem_desc->size, &mem_desc->dma_addr, GFP_KERNEL); 4831 + if (!mem_desc->addr) 4832 + return -ENOMEM; 4833 + } else { 4834 + mem_desc->addr = mrioc->cfg_page; 4835 + mem_desc->dma_addr = mrioc->cfg_page_dma; 4836 + memset(mem_desc->addr, 0, mrioc->cfg_page_sz); 4837 + } 4838 + return 0; 4839 + } 4840 + 4841 + /** 4842 + * mpi3mr_post_cfg_req - Issue config requests and wait 4843 + * @mrioc: Adapter instance reference 4844 + * @cfg_req: Configuration request 4845 + * @timeout: Timeout in seconds 4846 + * @ioc_status: Pointer to return ioc status 4847 + * 4848 + * A generic function for posting MPI3 configuration request to 4849 + * the firmware. This blocks for the completion of request for 4850 + * timeout seconds and if the request times out this function 4851 + * faults the controller with proper reason code. 4852 + * 4853 + * On successful completion of the request this function returns 4854 + * appropriate ioc status from the firmware back to the caller. 4855 + * 4856 + * Return: 0 on success, non-zero on failure. 4857 + */ 4858 + static int mpi3mr_post_cfg_req(struct mpi3mr_ioc *mrioc, 4859 + struct mpi3_config_request *cfg_req, int timeout, u16 *ioc_status) 4860 + { 4861 + int retval = 0; 4862 + 4863 + mutex_lock(&mrioc->cfg_cmds.mutex); 4864 + if (mrioc->cfg_cmds.state & MPI3MR_CMD_PENDING) { 4865 + retval = -1; 4866 + ioc_err(mrioc, "sending config request failed due to command in use\n"); 4867 + mutex_unlock(&mrioc->cfg_cmds.mutex); 4868 + goto out; 4869 + } 4870 + mrioc->cfg_cmds.state = MPI3MR_CMD_PENDING; 4871 + mrioc->cfg_cmds.is_waiting = 1; 4872 + mrioc->cfg_cmds.callback = NULL; 4873 + mrioc->cfg_cmds.ioc_status = 0; 4874 + mrioc->cfg_cmds.ioc_loginfo = 0; 4875 + 4876 + cfg_req->host_tag = cpu_to_le16(MPI3MR_HOSTTAG_CFG_CMDS); 4877 + cfg_req->function = MPI3_FUNCTION_CONFIG; 4878 + 4879 + init_completion(&mrioc->cfg_cmds.done); 4880 + dprint_cfg_info(mrioc, "posting config request\n"); 4881 + if (mrioc->logging_level & MPI3_DEBUG_CFG_INFO) 4882 + dprint_dump(cfg_req, sizeof(struct mpi3_config_request), 4883 + "mpi3_cfg_req"); 4884 + retval = mpi3mr_admin_request_post(mrioc, cfg_req, sizeof(*cfg_req), 1); 4885 + if (retval) { 4886 + ioc_err(mrioc, "posting config request failed\n"); 4887 + goto out_unlock; 4888 + } 4889 + wait_for_completion_timeout(&mrioc->cfg_cmds.done, (timeout * HZ)); 4890 + if (!(mrioc->cfg_cmds.state & MPI3MR_CMD_COMPLETE)) { 4891 + mpi3mr_check_rh_fault_ioc(mrioc, 4892 + MPI3MR_RESET_FROM_CFG_REQ_TIMEOUT); 4893 + ioc_err(mrioc, "config request timed out\n"); 4894 + retval = -1; 4895 + goto out_unlock; 4896 + } 4897 + *ioc_status = mrioc->cfg_cmds.ioc_status & MPI3_IOCSTATUS_STATUS_MASK; 4898 + if ((*ioc_status) != MPI3_IOCSTATUS_SUCCESS) 4899 + dprint_cfg_err(mrioc, 4900 + "cfg_page request returned with ioc_status(0x%04x), log_info(0x%08x)\n", 4901 + *ioc_status, mrioc->cfg_cmds.ioc_loginfo); 4902 + 4903 + out_unlock: 4904 + mrioc->cfg_cmds.state = MPI3MR_CMD_NOTUSED; 4905 + mutex_unlock(&mrioc->cfg_cmds.mutex); 4906 + 4907 + out: 4908 + return retval; 4909 + } 4910 + 4911 + /** 4912 + * mpi3mr_process_cfg_req - config page request processor 4913 + * @mrioc: Adapter instance reference 4914 + * @cfg_req: Configuration request 4915 + * @cfg_hdr: Configuration page header 4916 + * @timeout: Timeout in seconds 4917 + * @ioc_status: Pointer to return ioc status 4918 + * @cfg_buf: Memory pointer to copy config page or header 4919 + * @cfg_buf_sz: Size of the memory to get config page or header 4920 + * 4921 + * This is handler for config page read, write and config page 4922 + * header read operations. 4923 + * 4924 + * This function expects the cfg_req to be populated with page 4925 + * type, page number, action for the header read and with page 4926 + * address for all other operations. 4927 + * 4928 + * The cfg_hdr can be passed as null for reading required header 4929 + * details for read/write pages the cfg_hdr should point valid 4930 + * configuration page header. 4931 + * 4932 + * This allocates dmaable memory based on the size of the config 4933 + * buffer and set the SGE of the cfg_req. 4934 + * 4935 + * For write actions, the config page data has to be passed in 4936 + * the cfg_buf and size of the data has to be mentioned in the 4937 + * cfg_buf_sz. 4938 + * 4939 + * For read/header actions, on successful completion of the 4940 + * request with successful ioc_status the data will be copied 4941 + * into the cfg_buf limited to a minimum of actual page size and 4942 + * cfg_buf_sz 4943 + * 4944 + * 4945 + * Return: 0 on success, non-zero on failure. 4946 + */ 4947 + static int mpi3mr_process_cfg_req(struct mpi3mr_ioc *mrioc, 4948 + struct mpi3_config_request *cfg_req, 4949 + struct mpi3_config_page_header *cfg_hdr, int timeout, u16 *ioc_status, 4950 + void *cfg_buf, u32 cfg_buf_sz) 4951 + { 4952 + struct dma_memory_desc mem_desc; 4953 + int retval = -1; 4954 + u8 invalid_action = 0; 4955 + u8 sgl_flags = MPI3MR_SGEFLAGS_SYSTEM_SIMPLE_END_OF_LIST; 4956 + 4957 + memset(&mem_desc, 0, sizeof(struct dma_memory_desc)); 4958 + 4959 + if (cfg_req->action == MPI3_CONFIG_ACTION_PAGE_HEADER) 4960 + mem_desc.size = sizeof(struct mpi3_config_page_header); 4961 + else { 4962 + if (!cfg_hdr) { 4963 + ioc_err(mrioc, "null config header passed for config action(%d), page_type(0x%02x), page_num(%d)\n", 4964 + cfg_req->action, cfg_req->page_type, 4965 + cfg_req->page_number); 4966 + goto out; 4967 + } 4968 + switch (cfg_hdr->page_attribute & MPI3_CONFIG_PAGEATTR_MASK) { 4969 + case MPI3_CONFIG_PAGEATTR_READ_ONLY: 4970 + if (cfg_req->action 4971 + != MPI3_CONFIG_ACTION_READ_CURRENT) 4972 + invalid_action = 1; 4973 + break; 4974 + case MPI3_CONFIG_PAGEATTR_CHANGEABLE: 4975 + if ((cfg_req->action == 4976 + MPI3_CONFIG_ACTION_READ_PERSISTENT) || 4977 + (cfg_req->action == 4978 + MPI3_CONFIG_ACTION_WRITE_PERSISTENT)) 4979 + invalid_action = 1; 4980 + break; 4981 + case MPI3_CONFIG_PAGEATTR_PERSISTENT: 4982 + default: 4983 + break; 4984 + } 4985 + if (invalid_action) { 4986 + ioc_err(mrioc, 4987 + "config action(%d) is not allowed for page_type(0x%02x), page_num(%d) with page_attribute(0x%02x)\n", 4988 + cfg_req->action, cfg_req->page_type, 4989 + cfg_req->page_number, cfg_hdr->page_attribute); 4990 + goto out; 4991 + } 4992 + mem_desc.size = le16_to_cpu(cfg_hdr->page_length) * 4; 4993 + cfg_req->page_length = cfg_hdr->page_length; 4994 + cfg_req->page_version = cfg_hdr->page_version; 4995 + } 4996 + if (mpi3mr_alloc_config_dma_memory(mrioc, &mem_desc)) 4997 + goto out; 4998 + 4999 + mpi3mr_add_sg_single(&cfg_req->sgl, sgl_flags, mem_desc.size, 5000 + mem_desc.dma_addr); 5001 + 5002 + if ((cfg_req->action == MPI3_CONFIG_ACTION_WRITE_PERSISTENT) || 5003 + (cfg_req->action == MPI3_CONFIG_ACTION_WRITE_CURRENT)) { 5004 + memcpy(mem_desc.addr, cfg_buf, min_t(u16, mem_desc.size, 5005 + cfg_buf_sz)); 5006 + dprint_cfg_info(mrioc, "config buffer to be written\n"); 5007 + if (mrioc->logging_level & MPI3_DEBUG_CFG_INFO) 5008 + dprint_dump(mem_desc.addr, mem_desc.size, "cfg_buf"); 5009 + } 5010 + 5011 + if (mpi3mr_post_cfg_req(mrioc, cfg_req, timeout, ioc_status)) 5012 + goto out; 5013 + 5014 + retval = 0; 5015 + if ((*ioc_status == MPI3_IOCSTATUS_SUCCESS) && 5016 + (cfg_req->action != MPI3_CONFIG_ACTION_WRITE_PERSISTENT) && 5017 + (cfg_req->action != MPI3_CONFIG_ACTION_WRITE_CURRENT)) { 5018 + memcpy(cfg_buf, mem_desc.addr, min_t(u16, mem_desc.size, 5019 + cfg_buf_sz)); 5020 + dprint_cfg_info(mrioc, "config buffer read\n"); 5021 + if (mrioc->logging_level & MPI3_DEBUG_CFG_INFO) 5022 + dprint_dump(mem_desc.addr, mem_desc.size, "cfg_buf"); 5023 + } 5024 + 5025 + out: 5026 + mpi3mr_free_config_dma_memory(mrioc, &mem_desc); 5027 + return retval; 5028 + } 5029 + 5030 + /** 5031 + * mpi3mr_cfg_get_dev_pg0 - Read current device page0 5032 + * @mrioc: Adapter instance reference 5033 + * @ioc_status: Pointer to return ioc status 5034 + * @dev_pg0: Pointer to return device page 0 5035 + * @pg_sz: Size of the memory allocated to the page pointer 5036 + * @form: The form to be used for addressing the page 5037 + * @form_spec: Form specific information like device handle 5038 + * 5039 + * This is handler for config page read for a specific device 5040 + * page0. The ioc_status has the controller returned ioc_status. 5041 + * This routine doesn't check ioc_status to decide whether the 5042 + * page read is success or not and it is the callers 5043 + * responsibility. 5044 + * 5045 + * Return: 0 on success, non-zero on failure. 5046 + */ 5047 + int mpi3mr_cfg_get_dev_pg0(struct mpi3mr_ioc *mrioc, u16 *ioc_status, 5048 + struct mpi3_device_page0 *dev_pg0, u16 pg_sz, u32 form, u32 form_spec) 5049 + { 5050 + struct mpi3_config_page_header cfg_hdr; 5051 + struct mpi3_config_request cfg_req; 5052 + u32 page_address; 5053 + 5054 + memset(dev_pg0, 0, pg_sz); 5055 + memset(&cfg_hdr, 0, sizeof(cfg_hdr)); 5056 + memset(&cfg_req, 0, sizeof(cfg_req)); 5057 + 5058 + cfg_req.function = MPI3_FUNCTION_CONFIG; 5059 + cfg_req.action = MPI3_CONFIG_ACTION_PAGE_HEADER; 5060 + cfg_req.page_type = MPI3_CONFIG_PAGETYPE_DEVICE; 5061 + cfg_req.page_number = 0; 5062 + cfg_req.page_address = 0; 5063 + 5064 + if (mpi3mr_process_cfg_req(mrioc, &cfg_req, NULL, 5065 + MPI3MR_INTADMCMD_TIMEOUT, ioc_status, &cfg_hdr, sizeof(cfg_hdr))) { 5066 + ioc_err(mrioc, "device page0 header read failed\n"); 5067 + goto out_failed; 5068 + } 5069 + if (*ioc_status != MPI3_IOCSTATUS_SUCCESS) { 5070 + ioc_err(mrioc, "device page0 header read failed with ioc_status(0x%04x)\n", 5071 + *ioc_status); 5072 + goto out_failed; 5073 + } 5074 + cfg_req.action = MPI3_CONFIG_ACTION_READ_CURRENT; 5075 + page_address = ((form & MPI3_DEVICE_PGAD_FORM_MASK) | 5076 + (form_spec & MPI3_DEVICE_PGAD_HANDLE_MASK)); 5077 + cfg_req.page_address = cpu_to_le32(page_address); 5078 + if (mpi3mr_process_cfg_req(mrioc, &cfg_req, &cfg_hdr, 5079 + MPI3MR_INTADMCMD_TIMEOUT, ioc_status, dev_pg0, pg_sz)) { 5080 + ioc_err(mrioc, "device page0 read failed\n"); 5081 + goto out_failed; 5082 + } 5083 + return 0; 5084 + out_failed: 5085 + return -1; 5086 + } 5087 + 5088 + 5089 + /** 5090 + * mpi3mr_cfg_get_sas_phy_pg0 - Read current SAS Phy page0 5091 + * @mrioc: Adapter instance reference 5092 + * @ioc_status: Pointer to return ioc status 5093 + * @phy_pg0: Pointer to return SAS Phy page 0 5094 + * @pg_sz: Size of the memory allocated to the page pointer 5095 + * @form: The form to be used for addressing the page 5096 + * @form_spec: Form specific information like phy number 5097 + * 5098 + * This is handler for config page read for a specific SAS Phy 5099 + * page0. The ioc_status has the controller returned ioc_status. 5100 + * This routine doesn't check ioc_status to decide whether the 5101 + * page read is success or not and it is the callers 5102 + * responsibility. 5103 + * 5104 + * Return: 0 on success, non-zero on failure. 5105 + */ 5106 + int mpi3mr_cfg_get_sas_phy_pg0(struct mpi3mr_ioc *mrioc, u16 *ioc_status, 5107 + struct mpi3_sas_phy_page0 *phy_pg0, u16 pg_sz, u32 form, 5108 + u32 form_spec) 5109 + { 5110 + struct mpi3_config_page_header cfg_hdr; 5111 + struct mpi3_config_request cfg_req; 5112 + u32 page_address; 5113 + 5114 + memset(phy_pg0, 0, pg_sz); 5115 + memset(&cfg_hdr, 0, sizeof(cfg_hdr)); 5116 + memset(&cfg_req, 0, sizeof(cfg_req)); 5117 + 5118 + cfg_req.function = MPI3_FUNCTION_CONFIG; 5119 + cfg_req.action = MPI3_CONFIG_ACTION_PAGE_HEADER; 5120 + cfg_req.page_type = MPI3_CONFIG_PAGETYPE_SAS_PHY; 5121 + cfg_req.page_number = 0; 5122 + cfg_req.page_address = 0; 5123 + 5124 + if (mpi3mr_process_cfg_req(mrioc, &cfg_req, NULL, 5125 + MPI3MR_INTADMCMD_TIMEOUT, ioc_status, &cfg_hdr, sizeof(cfg_hdr))) { 5126 + ioc_err(mrioc, "sas phy page0 header read failed\n"); 5127 + goto out_failed; 5128 + } 5129 + if (*ioc_status != MPI3_IOCSTATUS_SUCCESS) { 5130 + ioc_err(mrioc, "sas phy page0 header read failed with ioc_status(0x%04x)\n", 5131 + *ioc_status); 5132 + goto out_failed; 5133 + } 5134 + cfg_req.action = MPI3_CONFIG_ACTION_READ_CURRENT; 5135 + page_address = ((form & MPI3_SAS_PHY_PGAD_FORM_MASK) | 5136 + (form_spec & MPI3_SAS_PHY_PGAD_PHY_NUMBER_MASK)); 5137 + cfg_req.page_address = cpu_to_le32(page_address); 5138 + if (mpi3mr_process_cfg_req(mrioc, &cfg_req, &cfg_hdr, 5139 + MPI3MR_INTADMCMD_TIMEOUT, ioc_status, phy_pg0, pg_sz)) { 5140 + ioc_err(mrioc, "sas phy page0 read failed\n"); 5141 + goto out_failed; 5142 + } 5143 + return 0; 5144 + out_failed: 5145 + return -1; 5146 + } 5147 + 5148 + /** 5149 + * mpi3mr_cfg_get_sas_phy_pg1 - Read current SAS Phy page1 5150 + * @mrioc: Adapter instance reference 5151 + * @ioc_status: Pointer to return ioc status 5152 + * @phy_pg1: Pointer to return SAS Phy page 1 5153 + * @pg_sz: Size of the memory allocated to the page pointer 5154 + * @form: The form to be used for addressing the page 5155 + * @form_spec: Form specific information like phy number 5156 + * 5157 + * This is handler for config page read for a specific SAS Phy 5158 + * page1. The ioc_status has the controller returned ioc_status. 5159 + * This routine doesn't check ioc_status to decide whether the 5160 + * page read is success or not and it is the callers 5161 + * responsibility. 5162 + * 5163 + * Return: 0 on success, non-zero on failure. 5164 + */ 5165 + int mpi3mr_cfg_get_sas_phy_pg1(struct mpi3mr_ioc *mrioc, u16 *ioc_status, 5166 + struct mpi3_sas_phy_page1 *phy_pg1, u16 pg_sz, u32 form, 5167 + u32 form_spec) 5168 + { 5169 + struct mpi3_config_page_header cfg_hdr; 5170 + struct mpi3_config_request cfg_req; 5171 + u32 page_address; 5172 + 5173 + memset(phy_pg1, 0, pg_sz); 5174 + memset(&cfg_hdr, 0, sizeof(cfg_hdr)); 5175 + memset(&cfg_req, 0, sizeof(cfg_req)); 5176 + 5177 + cfg_req.function = MPI3_FUNCTION_CONFIG; 5178 + cfg_req.action = MPI3_CONFIG_ACTION_PAGE_HEADER; 5179 + cfg_req.page_type = MPI3_CONFIG_PAGETYPE_SAS_PHY; 5180 + cfg_req.page_number = 1; 5181 + cfg_req.page_address = 0; 5182 + 5183 + if (mpi3mr_process_cfg_req(mrioc, &cfg_req, NULL, 5184 + MPI3MR_INTADMCMD_TIMEOUT, ioc_status, &cfg_hdr, sizeof(cfg_hdr))) { 5185 + ioc_err(mrioc, "sas phy page1 header read failed\n"); 5186 + goto out_failed; 5187 + } 5188 + if (*ioc_status != MPI3_IOCSTATUS_SUCCESS) { 5189 + ioc_err(mrioc, "sas phy page1 header read failed with ioc_status(0x%04x)\n", 5190 + *ioc_status); 5191 + goto out_failed; 5192 + } 5193 + cfg_req.action = MPI3_CONFIG_ACTION_READ_CURRENT; 5194 + page_address = ((form & MPI3_SAS_PHY_PGAD_FORM_MASK) | 5195 + (form_spec & MPI3_SAS_PHY_PGAD_PHY_NUMBER_MASK)); 5196 + cfg_req.page_address = cpu_to_le32(page_address); 5197 + if (mpi3mr_process_cfg_req(mrioc, &cfg_req, &cfg_hdr, 5198 + MPI3MR_INTADMCMD_TIMEOUT, ioc_status, phy_pg1, pg_sz)) { 5199 + ioc_err(mrioc, "sas phy page1 read failed\n"); 5200 + goto out_failed; 5201 + } 5202 + return 0; 5203 + out_failed: 5204 + return -1; 5205 + } 5206 + 5207 + 5208 + /** 5209 + * mpi3mr_cfg_get_sas_exp_pg0 - Read current SAS Expander page0 5210 + * @mrioc: Adapter instance reference 5211 + * @ioc_status: Pointer to return ioc status 5212 + * @exp_pg0: Pointer to return SAS Expander page 0 5213 + * @pg_sz: Size of the memory allocated to the page pointer 5214 + * @form: The form to be used for addressing the page 5215 + * @form_spec: Form specific information like device handle 5216 + * 5217 + * This is handler for config page read for a specific SAS 5218 + * Expander page0. The ioc_status has the controller returned 5219 + * ioc_status. This routine doesn't check ioc_status to decide 5220 + * whether the page read is success or not and it is the callers 5221 + * responsibility. 5222 + * 5223 + * Return: 0 on success, non-zero on failure. 5224 + */ 5225 + int mpi3mr_cfg_get_sas_exp_pg0(struct mpi3mr_ioc *mrioc, u16 *ioc_status, 5226 + struct mpi3_sas_expander_page0 *exp_pg0, u16 pg_sz, u32 form, 5227 + u32 form_spec) 5228 + { 5229 + struct mpi3_config_page_header cfg_hdr; 5230 + struct mpi3_config_request cfg_req; 5231 + u32 page_address; 5232 + 5233 + memset(exp_pg0, 0, pg_sz); 5234 + memset(&cfg_hdr, 0, sizeof(cfg_hdr)); 5235 + memset(&cfg_req, 0, sizeof(cfg_req)); 5236 + 5237 + cfg_req.function = MPI3_FUNCTION_CONFIG; 5238 + cfg_req.action = MPI3_CONFIG_ACTION_PAGE_HEADER; 5239 + cfg_req.page_type = MPI3_CONFIG_PAGETYPE_SAS_EXPANDER; 5240 + cfg_req.page_number = 0; 5241 + cfg_req.page_address = 0; 5242 + 5243 + if (mpi3mr_process_cfg_req(mrioc, &cfg_req, NULL, 5244 + MPI3MR_INTADMCMD_TIMEOUT, ioc_status, &cfg_hdr, sizeof(cfg_hdr))) { 5245 + ioc_err(mrioc, "expander page0 header read failed\n"); 5246 + goto out_failed; 5247 + } 5248 + if (*ioc_status != MPI3_IOCSTATUS_SUCCESS) { 5249 + ioc_err(mrioc, "expander page0 header read failed with ioc_status(0x%04x)\n", 5250 + *ioc_status); 5251 + goto out_failed; 5252 + } 5253 + cfg_req.action = MPI3_CONFIG_ACTION_READ_CURRENT; 5254 + page_address = ((form & MPI3_SAS_EXPAND_PGAD_FORM_MASK) | 5255 + (form_spec & (MPI3_SAS_EXPAND_PGAD_PHYNUM_MASK | 5256 + MPI3_SAS_EXPAND_PGAD_HANDLE_MASK))); 5257 + cfg_req.page_address = cpu_to_le32(page_address); 5258 + if (mpi3mr_process_cfg_req(mrioc, &cfg_req, &cfg_hdr, 5259 + MPI3MR_INTADMCMD_TIMEOUT, ioc_status, exp_pg0, pg_sz)) { 5260 + ioc_err(mrioc, "expander page0 read failed\n"); 5261 + goto out_failed; 5262 + } 5263 + return 0; 5264 + out_failed: 5265 + return -1; 5266 + } 5267 + 5268 + /** 5269 + * mpi3mr_cfg_get_sas_exp_pg1 - Read current SAS Expander page1 5270 + * @mrioc: Adapter instance reference 5271 + * @ioc_status: Pointer to return ioc status 5272 + * @exp_pg1: Pointer to return SAS Expander page 1 5273 + * @pg_sz: Size of the memory allocated to the page pointer 5274 + * @form: The form to be used for addressing the page 5275 + * @form_spec: Form specific information like phy number 5276 + * 5277 + * This is handler for config page read for a specific SAS 5278 + * Expander page1. The ioc_status has the controller returned 5279 + * ioc_status. This routine doesn't check ioc_status to decide 5280 + * whether the page read is success or not and it is the callers 5281 + * responsibility. 5282 + * 5283 + * Return: 0 on success, non-zero on failure. 5284 + */ 5285 + int mpi3mr_cfg_get_sas_exp_pg1(struct mpi3mr_ioc *mrioc, u16 *ioc_status, 5286 + struct mpi3_sas_expander_page1 *exp_pg1, u16 pg_sz, u32 form, 5287 + u32 form_spec) 5288 + { 5289 + struct mpi3_config_page_header cfg_hdr; 5290 + struct mpi3_config_request cfg_req; 5291 + u32 page_address; 5292 + 5293 + memset(exp_pg1, 0, pg_sz); 5294 + memset(&cfg_hdr, 0, sizeof(cfg_hdr)); 5295 + memset(&cfg_req, 0, sizeof(cfg_req)); 5296 + 5297 + cfg_req.function = MPI3_FUNCTION_CONFIG; 5298 + cfg_req.action = MPI3_CONFIG_ACTION_PAGE_HEADER; 5299 + cfg_req.page_type = MPI3_CONFIG_PAGETYPE_SAS_EXPANDER; 5300 + cfg_req.page_number = 1; 5301 + cfg_req.page_address = 0; 5302 + 5303 + if (mpi3mr_process_cfg_req(mrioc, &cfg_req, NULL, 5304 + MPI3MR_INTADMCMD_TIMEOUT, ioc_status, &cfg_hdr, sizeof(cfg_hdr))) { 5305 + ioc_err(mrioc, "expander page1 header read failed\n"); 5306 + goto out_failed; 5307 + } 5308 + if (*ioc_status != MPI3_IOCSTATUS_SUCCESS) { 5309 + ioc_err(mrioc, "expander page1 header read failed with ioc_status(0x%04x)\n", 5310 + *ioc_status); 5311 + goto out_failed; 5312 + } 5313 + cfg_req.action = MPI3_CONFIG_ACTION_READ_CURRENT; 5314 + page_address = ((form & MPI3_SAS_EXPAND_PGAD_FORM_MASK) | 5315 + (form_spec & (MPI3_SAS_EXPAND_PGAD_PHYNUM_MASK | 5316 + MPI3_SAS_EXPAND_PGAD_HANDLE_MASK))); 5317 + cfg_req.page_address = cpu_to_le32(page_address); 5318 + if (mpi3mr_process_cfg_req(mrioc, &cfg_req, &cfg_hdr, 5319 + MPI3MR_INTADMCMD_TIMEOUT, ioc_status, exp_pg1, pg_sz)) { 5320 + ioc_err(mrioc, "expander page1 read failed\n"); 5321 + goto out_failed; 5322 + } 5323 + return 0; 5324 + out_failed: 5325 + return -1; 5326 + } 5327 + 5328 + /** 5329 + * mpi3mr_cfg_get_enclosure_pg0 - Read current Enclosure page0 5330 + * @mrioc: Adapter instance reference 5331 + * @ioc_status: Pointer to return ioc status 5332 + * @encl_pg0: Pointer to return Enclosure page 0 5333 + * @pg_sz: Size of the memory allocated to the page pointer 5334 + * @form: The form to be used for addressing the page 5335 + * @form_spec: Form specific information like device handle 5336 + * 5337 + * This is handler for config page read for a specific Enclosure 5338 + * page0. The ioc_status has the controller returned ioc_status. 5339 + * This routine doesn't check ioc_status to decide whether the 5340 + * page read is success or not and it is the callers 5341 + * responsibility. 5342 + * 5343 + * Return: 0 on success, non-zero on failure. 5344 + */ 5345 + int mpi3mr_cfg_get_enclosure_pg0(struct mpi3mr_ioc *mrioc, u16 *ioc_status, 5346 + struct mpi3_enclosure_page0 *encl_pg0, u16 pg_sz, u32 form, 5347 + u32 form_spec) 5348 + { 5349 + struct mpi3_config_page_header cfg_hdr; 5350 + struct mpi3_config_request cfg_req; 5351 + u32 page_address; 5352 + 5353 + memset(encl_pg0, 0, pg_sz); 5354 + memset(&cfg_hdr, 0, sizeof(cfg_hdr)); 5355 + memset(&cfg_req, 0, sizeof(cfg_req)); 5356 + 5357 + cfg_req.function = MPI3_FUNCTION_CONFIG; 5358 + cfg_req.action = MPI3_CONFIG_ACTION_PAGE_HEADER; 5359 + cfg_req.page_type = MPI3_CONFIG_PAGETYPE_ENCLOSURE; 5360 + cfg_req.page_number = 0; 5361 + cfg_req.page_address = 0; 5362 + 5363 + if (mpi3mr_process_cfg_req(mrioc, &cfg_req, NULL, 5364 + MPI3MR_INTADMCMD_TIMEOUT, ioc_status, &cfg_hdr, sizeof(cfg_hdr))) { 5365 + ioc_err(mrioc, "enclosure page0 header read failed\n"); 5366 + goto out_failed; 5367 + } 5368 + if (*ioc_status != MPI3_IOCSTATUS_SUCCESS) { 5369 + ioc_err(mrioc, "enclosure page0 header read failed with ioc_status(0x%04x)\n", 5370 + *ioc_status); 5371 + goto out_failed; 5372 + } 5373 + cfg_req.action = MPI3_CONFIG_ACTION_READ_CURRENT; 5374 + page_address = ((form & MPI3_ENCLOS_PGAD_FORM_MASK) | 5375 + (form_spec & MPI3_ENCLOS_PGAD_HANDLE_MASK)); 5376 + cfg_req.page_address = cpu_to_le32(page_address); 5377 + if (mpi3mr_process_cfg_req(mrioc, &cfg_req, &cfg_hdr, 5378 + MPI3MR_INTADMCMD_TIMEOUT, ioc_status, encl_pg0, pg_sz)) { 5379 + ioc_err(mrioc, "enclosure page0 read failed\n"); 5380 + goto out_failed; 5381 + } 5382 + return 0; 5383 + out_failed: 5384 + return -1; 5385 + } 5386 + 5387 + 5388 + /** 5389 + * mpi3mr_cfg_get_sas_io_unit_pg0 - Read current SASIOUnit page0 5390 + * @mrioc: Adapter instance reference 5391 + * @sas_io_unit_pg0: Pointer to return SAS IO Unit page 0 5392 + * @pg_sz: Size of the memory allocated to the page pointer 5393 + * 5394 + * This is handler for config page read for the SAS IO Unit 5395 + * page0. This routine checks ioc_status to decide whether the 5396 + * page read is success or not. 5397 + * 5398 + * Return: 0 on success, non-zero on failure. 5399 + */ 5400 + int mpi3mr_cfg_get_sas_io_unit_pg0(struct mpi3mr_ioc *mrioc, 5401 + struct mpi3_sas_io_unit_page0 *sas_io_unit_pg0, u16 pg_sz) 5402 + { 5403 + struct mpi3_config_page_header cfg_hdr; 5404 + struct mpi3_config_request cfg_req; 5405 + u16 ioc_status = 0; 5406 + 5407 + memset(sas_io_unit_pg0, 0, pg_sz); 5408 + memset(&cfg_hdr, 0, sizeof(cfg_hdr)); 5409 + memset(&cfg_req, 0, sizeof(cfg_req)); 5410 + 5411 + cfg_req.function = MPI3_FUNCTION_CONFIG; 5412 + cfg_req.action = MPI3_CONFIG_ACTION_PAGE_HEADER; 5413 + cfg_req.page_type = MPI3_CONFIG_PAGETYPE_SAS_IO_UNIT; 5414 + cfg_req.page_number = 0; 5415 + cfg_req.page_address = 0; 5416 + 5417 + if (mpi3mr_process_cfg_req(mrioc, &cfg_req, NULL, 5418 + MPI3MR_INTADMCMD_TIMEOUT, &ioc_status, &cfg_hdr, sizeof(cfg_hdr))) { 5419 + ioc_err(mrioc, "sas io unit page0 header read failed\n"); 5420 + goto out_failed; 5421 + } 5422 + if (ioc_status != MPI3_IOCSTATUS_SUCCESS) { 5423 + ioc_err(mrioc, "sas io unit page0 header read failed with ioc_status(0x%04x)\n", 5424 + ioc_status); 5425 + goto out_failed; 5426 + } 5427 + cfg_req.action = MPI3_CONFIG_ACTION_READ_CURRENT; 5428 + 5429 + if (mpi3mr_process_cfg_req(mrioc, &cfg_req, &cfg_hdr, 5430 + MPI3MR_INTADMCMD_TIMEOUT, &ioc_status, sas_io_unit_pg0, pg_sz)) { 5431 + ioc_err(mrioc, "sas io unit page0 read failed\n"); 5432 + goto out_failed; 5433 + } 5434 + if (ioc_status != MPI3_IOCSTATUS_SUCCESS) { 5435 + ioc_err(mrioc, "sas io unit page0 read failed with ioc_status(0x%04x)\n", 5436 + ioc_status); 5437 + goto out_failed; 5438 + } 5439 + return 0; 5440 + out_failed: 5441 + return -1; 5442 + } 5443 + 5444 + /** 5445 + * mpi3mr_cfg_get_sas_io_unit_pg1 - Read current SASIOUnit page1 5446 + * @mrioc: Adapter instance reference 5447 + * @sas_io_unit_pg1: Pointer to return SAS IO Unit page 1 5448 + * @pg_sz: Size of the memory allocated to the page pointer 5449 + * 5450 + * This is handler for config page read for the SAS IO Unit 5451 + * page1. This routine checks ioc_status to decide whether the 5452 + * page read is success or not. 5453 + * 5454 + * Return: 0 on success, non-zero on failure. 5455 + */ 5456 + int mpi3mr_cfg_get_sas_io_unit_pg1(struct mpi3mr_ioc *mrioc, 5457 + struct mpi3_sas_io_unit_page1 *sas_io_unit_pg1, u16 pg_sz) 5458 + { 5459 + struct mpi3_config_page_header cfg_hdr; 5460 + struct mpi3_config_request cfg_req; 5461 + u16 ioc_status = 0; 5462 + 5463 + memset(sas_io_unit_pg1, 0, pg_sz); 5464 + memset(&cfg_hdr, 0, sizeof(cfg_hdr)); 5465 + memset(&cfg_req, 0, sizeof(cfg_req)); 5466 + 5467 + cfg_req.function = MPI3_FUNCTION_CONFIG; 5468 + cfg_req.action = MPI3_CONFIG_ACTION_PAGE_HEADER; 5469 + cfg_req.page_type = MPI3_CONFIG_PAGETYPE_SAS_IO_UNIT; 5470 + cfg_req.page_number = 1; 5471 + cfg_req.page_address = 0; 5472 + 5473 + if (mpi3mr_process_cfg_req(mrioc, &cfg_req, NULL, 5474 + MPI3MR_INTADMCMD_TIMEOUT, &ioc_status, &cfg_hdr, sizeof(cfg_hdr))) { 5475 + ioc_err(mrioc, "sas io unit page1 header read failed\n"); 5476 + goto out_failed; 5477 + } 5478 + if (ioc_status != MPI3_IOCSTATUS_SUCCESS) { 5479 + ioc_err(mrioc, "sas io unit page1 header read failed with ioc_status(0x%04x)\n", 5480 + ioc_status); 5481 + goto out_failed; 5482 + } 5483 + cfg_req.action = MPI3_CONFIG_ACTION_READ_CURRENT; 5484 + 5485 + if (mpi3mr_process_cfg_req(mrioc, &cfg_req, &cfg_hdr, 5486 + MPI3MR_INTADMCMD_TIMEOUT, &ioc_status, sas_io_unit_pg1, pg_sz)) { 5487 + ioc_err(mrioc, "sas io unit page1 read failed\n"); 5488 + goto out_failed; 5489 + } 5490 + if (ioc_status != MPI3_IOCSTATUS_SUCCESS) { 5491 + ioc_err(mrioc, "sas io unit page1 read failed with ioc_status(0x%04x)\n", 5492 + ioc_status); 5493 + goto out_failed; 5494 + } 5495 + return 0; 5496 + out_failed: 5497 + return -1; 5498 + } 5499 + 5500 + /** 5501 + * mpi3mr_cfg_set_sas_io_unit_pg1 - Write SASIOUnit page1 5502 + * @mrioc: Adapter instance reference 5503 + * @sas_io_unit_pg1: Pointer to the SAS IO Unit page 1 to write 5504 + * @pg_sz: Size of the memory allocated to the page pointer 5505 + * 5506 + * This is handler for config page write for the SAS IO Unit 5507 + * page1. This routine checks ioc_status to decide whether the 5508 + * page read is success or not. This will modify both current 5509 + * and persistent page. 5510 + * 5511 + * Return: 0 on success, non-zero on failure. 5512 + */ 5513 + int mpi3mr_cfg_set_sas_io_unit_pg1(struct mpi3mr_ioc *mrioc, 5514 + struct mpi3_sas_io_unit_page1 *sas_io_unit_pg1, u16 pg_sz) 5515 + { 5516 + struct mpi3_config_page_header cfg_hdr; 5517 + struct mpi3_config_request cfg_req; 5518 + u16 ioc_status = 0; 5519 + 5520 + memset(&cfg_hdr, 0, sizeof(cfg_hdr)); 5521 + memset(&cfg_req, 0, sizeof(cfg_req)); 5522 + 5523 + cfg_req.function = MPI3_FUNCTION_CONFIG; 5524 + cfg_req.action = MPI3_CONFIG_ACTION_PAGE_HEADER; 5525 + cfg_req.page_type = MPI3_CONFIG_PAGETYPE_SAS_IO_UNIT; 5526 + cfg_req.page_number = 1; 5527 + cfg_req.page_address = 0; 5528 + 5529 + if (mpi3mr_process_cfg_req(mrioc, &cfg_req, NULL, 5530 + MPI3MR_INTADMCMD_TIMEOUT, &ioc_status, &cfg_hdr, sizeof(cfg_hdr))) { 5531 + ioc_err(mrioc, "sas io unit page1 header read failed\n"); 5532 + goto out_failed; 5533 + } 5534 + if (ioc_status != MPI3_IOCSTATUS_SUCCESS) { 5535 + ioc_err(mrioc, "sas io unit page1 header read failed with ioc_status(0x%04x)\n", 5536 + ioc_status); 5537 + goto out_failed; 5538 + } 5539 + cfg_req.action = MPI3_CONFIG_ACTION_WRITE_CURRENT; 5540 + 5541 + if (mpi3mr_process_cfg_req(mrioc, &cfg_req, &cfg_hdr, 5542 + MPI3MR_INTADMCMD_TIMEOUT, &ioc_status, sas_io_unit_pg1, pg_sz)) { 5543 + ioc_err(mrioc, "sas io unit page1 write current failed\n"); 5544 + goto out_failed; 5545 + } 5546 + if (ioc_status != MPI3_IOCSTATUS_SUCCESS) { 5547 + ioc_err(mrioc, "sas io unit page1 write current failed with ioc_status(0x%04x)\n", 5548 + ioc_status); 5549 + goto out_failed; 5550 + } 5551 + 5552 + cfg_req.action = MPI3_CONFIG_ACTION_WRITE_PERSISTENT; 5553 + 5554 + if (mpi3mr_process_cfg_req(mrioc, &cfg_req, &cfg_hdr, 5555 + MPI3MR_INTADMCMD_TIMEOUT, &ioc_status, sas_io_unit_pg1, pg_sz)) { 5556 + ioc_err(mrioc, "sas io unit page1 write persistent failed\n"); 5557 + goto out_failed; 5558 + } 5559 + if (ioc_status != MPI3_IOCSTATUS_SUCCESS) { 5560 + ioc_err(mrioc, "sas io unit page1 write persistent failed with ioc_status(0x%04x)\n", 5561 + ioc_status); 5562 + goto out_failed; 5563 + } 5564 + return 0; 5565 + out_failed: 5566 + return -1; 5567 + } 5568 + 5569 + /** 5570 + * mpi3mr_cfg_get_driver_pg1 - Read current Driver page1 5571 + * @mrioc: Adapter instance reference 5572 + * @driver_pg1: Pointer to return Driver page 1 5573 + * @pg_sz: Size of the memory allocated to the page pointer 5574 + * 5575 + * This is handler for config page read for the Driver page1. 5576 + * This routine checks ioc_status to decide whether the page 5577 + * read is success or not. 5578 + * 5579 + * Return: 0 on success, non-zero on failure. 5580 + */ 5581 + int mpi3mr_cfg_get_driver_pg1(struct mpi3mr_ioc *mrioc, 5582 + struct mpi3_driver_page1 *driver_pg1, u16 pg_sz) 5583 + { 5584 + struct mpi3_config_page_header cfg_hdr; 5585 + struct mpi3_config_request cfg_req; 5586 + u16 ioc_status = 0; 5587 + 5588 + memset(driver_pg1, 0, pg_sz); 5589 + memset(&cfg_hdr, 0, sizeof(cfg_hdr)); 5590 + memset(&cfg_req, 0, sizeof(cfg_req)); 5591 + 5592 + cfg_req.function = MPI3_FUNCTION_CONFIG; 5593 + cfg_req.action = MPI3_CONFIG_ACTION_PAGE_HEADER; 5594 + cfg_req.page_type = MPI3_CONFIG_PAGETYPE_DRIVER; 5595 + cfg_req.page_number = 1; 5596 + cfg_req.page_address = 0; 5597 + 5598 + if (mpi3mr_process_cfg_req(mrioc, &cfg_req, NULL, 5599 + MPI3MR_INTADMCMD_TIMEOUT, &ioc_status, &cfg_hdr, sizeof(cfg_hdr))) { 5600 + ioc_err(mrioc, "driver page1 header read failed\n"); 5601 + goto out_failed; 5602 + } 5603 + if (ioc_status != MPI3_IOCSTATUS_SUCCESS) { 5604 + ioc_err(mrioc, "driver page1 header read failed with ioc_status(0x%04x)\n", 5605 + ioc_status); 5606 + goto out_failed; 5607 + } 5608 + cfg_req.action = MPI3_CONFIG_ACTION_READ_CURRENT; 5609 + 5610 + if (mpi3mr_process_cfg_req(mrioc, &cfg_req, &cfg_hdr, 5611 + MPI3MR_INTADMCMD_TIMEOUT, &ioc_status, driver_pg1, pg_sz)) { 5612 + ioc_err(mrioc, "driver page1 read failed\n"); 5613 + goto out_failed; 5614 + } 5615 + if (ioc_status != MPI3_IOCSTATUS_SUCCESS) { 5616 + ioc_err(mrioc, "driver page1 read failed with ioc_status(0x%04x)\n", 5617 + ioc_status); 5618 + goto out_failed; 5619 + } 5620 + return 0; 5621 + out_failed: 5622 + return -1; 4945 5623 }
+475 -70
drivers/scsi/mpi3mr/mpi3mr_os.c
··· 40 40 41 41 #define MPI3MR_DRIVER_EVENT_TG_QD_REDUCTION (0xFFFF) 42 42 43 + #define MPI3_EVENT_WAIT_FOR_DEVICES_TO_REFRESH (0xFFFE) 44 + 43 45 /** 44 46 * mpi3mr_host_tag_for_scmd - Get host tag for a scmd 45 47 * @mrioc: Adapter instance reference ··· 424 422 tgt_priv->io_throttle_enabled = 0; 425 423 tgt_priv->io_divert = 0; 426 424 tgt_priv->throttle_group = NULL; 425 + if (tgtdev->host_exposed) 426 + atomic_set(&tgt_priv->block_io, 1); 427 427 } 428 428 } 429 429 } ··· 580 576 mpi3mr_flush_scmd, (void *)mrioc); 581 577 ioc_info(mrioc, "%s :Flushed %d Host I/O cmds\n", __func__, 582 578 mrioc->flush_io_count); 579 + } 580 + 581 + /** 582 + * mpi3mr_flush_cmds_for_unrecovered_controller - Flush all pending cmds 583 + * @mrioc: Adapter instance reference 584 + * 585 + * This function waits for currently running IO poll threads to 586 + * exit and then flushes all host I/Os and any internal pending 587 + * cmds. This is executed after controller is marked as 588 + * unrecoverable. 589 + * 590 + * Return: Nothing. 591 + */ 592 + void mpi3mr_flush_cmds_for_unrecovered_controller(struct mpi3mr_ioc *mrioc) 593 + { 594 + struct Scsi_Host *shost = mrioc->shost; 595 + int i; 596 + 597 + if (!mrioc->unrecoverable) 598 + return; 599 + 600 + if (mrioc->op_reply_qinfo) { 601 + for (i = 0; i < mrioc->num_queues; i++) { 602 + while (atomic_read(&mrioc->op_reply_qinfo[i].in_use)) 603 + udelay(500); 604 + atomic_set(&mrioc->op_reply_qinfo[i].pend_ios, 0); 605 + } 606 + } 607 + mrioc->flush_io_count = 0; 608 + blk_mq_tagset_busy_iter(&shost->tag_set, 609 + mpi3mr_flush_scmd, (void *)mrioc); 610 + mpi3mr_flush_delayed_cmd_lists(mrioc); 611 + mpi3mr_flush_drv_cmds(mrioc); 583 612 } 584 613 585 614 /** ··· 833 796 * 834 797 * Return: None. 835 798 */ 836 - static void mpi3mr_print_device_event_notice(struct mpi3mr_ioc *mrioc, 799 + void mpi3mr_print_device_event_notice(struct mpi3mr_ioc *mrioc, 837 800 bool device_add) 838 801 { 839 802 ioc_notice(mrioc, "Device %s was in progress before the reset and\n", ··· 853 816 * 854 817 * Return: 0 on success, non zero on failure. 855 818 */ 856 - static void mpi3mr_remove_tgtdev_from_host(struct mpi3mr_ioc *mrioc, 819 + void mpi3mr_remove_tgtdev_from_host(struct mpi3mr_ioc *mrioc, 857 820 struct mpi3mr_tgt_dev *tgtdev) 858 821 { 859 822 struct mpi3mr_stgt_priv_data *tgt_priv; ··· 862 825 __func__, tgtdev->dev_handle, (unsigned long long)tgtdev->wwid); 863 826 if (tgtdev->starget && tgtdev->starget->hostdata) { 864 827 tgt_priv = tgtdev->starget->hostdata; 828 + atomic_set(&tgt_priv->block_io, 0); 865 829 tgt_priv->dev_handle = MPI3MR_INVALID_DEV_HANDLE; 866 830 } 867 831 868 - if (tgtdev->starget) { 869 - if (mrioc->current_event) 870 - mrioc->current_event->pending_at_sml = 1; 871 - scsi_remove_target(&tgtdev->starget->dev); 872 - tgtdev->host_exposed = 0; 873 - if (mrioc->current_event) { 874 - mrioc->current_event->pending_at_sml = 0; 875 - if (mrioc->current_event->discard) { 876 - mpi3mr_print_device_event_notice(mrioc, false); 877 - return; 832 + if (!mrioc->sas_transport_enabled || (tgtdev->dev_type != 833 + MPI3_DEVICE_DEVFORM_SAS_SATA) || tgtdev->non_stl) { 834 + if (tgtdev->starget) { 835 + if (mrioc->current_event) 836 + mrioc->current_event->pending_at_sml = 1; 837 + scsi_remove_target(&tgtdev->starget->dev); 838 + tgtdev->host_exposed = 0; 839 + if (mrioc->current_event) { 840 + mrioc->current_event->pending_at_sml = 0; 841 + if (mrioc->current_event->discard) { 842 + mpi3mr_print_device_event_notice(mrioc, 843 + false); 844 + return; 845 + } 878 846 } 879 847 } 880 - } 848 + } else 849 + mpi3mr_remove_tgtdev_from_sas_transport(mrioc, tgtdev); 850 + 881 851 ioc_info(mrioc, "%s :Removed handle(0x%04x), wwid(0x%016llx)\n", 882 852 __func__, tgtdev->dev_handle, (unsigned long long)tgtdev->wwid); 883 853 } ··· 906 862 int retval = 0; 907 863 struct mpi3mr_tgt_dev *tgtdev; 908 864 865 + if (mrioc->reset_in_progress) 866 + return -1; 867 + 909 868 tgtdev = mpi3mr_get_tgtdev_by_perst_id(mrioc, perst_id); 910 869 if (!tgtdev) { 911 870 retval = -1; 912 871 goto out; 913 872 } 914 - if (tgtdev->is_hidden) { 873 + if (tgtdev->is_hidden || tgtdev->host_exposed) { 915 874 retval = -1; 916 875 goto out; 917 876 } 918 - if (!tgtdev->host_exposed && !mrioc->reset_in_progress) { 877 + if (!mrioc->sas_transport_enabled || (tgtdev->dev_type != 878 + MPI3_DEVICE_DEVFORM_SAS_SATA) || tgtdev->non_stl){ 919 879 tgtdev->host_exposed = 1; 920 880 if (mrioc->current_event) 921 881 mrioc->current_event->pending_at_sml = 1; 922 - scsi_scan_target(&mrioc->shost->shost_gendev, 0, 923 - tgtdev->perst_id, 882 + scsi_scan_target(&mrioc->shost->shost_gendev, 883 + mrioc->scsi_device_channel, tgtdev->perst_id, 924 884 SCAN_WILD_CARD, SCSI_SCAN_INITIAL); 925 885 if (!tgtdev->starget) 926 886 tgtdev->host_exposed = 0; ··· 935 887 goto out; 936 888 } 937 889 } 938 - } 890 + } else 891 + mpi3mr_report_tgtdev_to_sas_transport(mrioc, tgtdev); 939 892 out: 940 893 if (tgtdev) 941 894 mpi3mr_tgtdev_put(tgtdev); ··· 1067 1018 { 1068 1019 u16 flags = 0; 1069 1020 struct mpi3mr_stgt_priv_data *scsi_tgt_priv_data = NULL; 1021 + struct mpi3mr_enclosure_node *enclosure_dev = NULL; 1070 1022 u8 prot_mask = 0; 1071 1023 1072 1024 tgtdev->perst_id = le16_to_cpu(dev_pg0->persistent_id); 1073 1025 tgtdev->dev_handle = le16_to_cpu(dev_pg0->dev_handle); 1074 1026 tgtdev->dev_type = dev_pg0->device_form; 1027 + tgtdev->io_unit_port = dev_pg0->io_unit_port; 1075 1028 tgtdev->encl_handle = le16_to_cpu(dev_pg0->enclosure_handle); 1076 1029 tgtdev->parent_handle = le16_to_cpu(dev_pg0->parent_dev_handle); 1077 1030 tgtdev->slot = le16_to_cpu(dev_pg0->slot); 1078 1031 tgtdev->q_depth = le16_to_cpu(dev_pg0->queue_depth); 1079 1032 tgtdev->wwid = le64_to_cpu(dev_pg0->wwid); 1033 + tgtdev->devpg0_flag = le16_to_cpu(dev_pg0->flags); 1080 1034 1081 - flags = le16_to_cpu(dev_pg0->flags); 1035 + if (tgtdev->encl_handle) 1036 + enclosure_dev = mpi3mr_enclosure_find_by_handle(mrioc, 1037 + tgtdev->encl_handle); 1038 + if (enclosure_dev) 1039 + tgtdev->enclosure_logical_id = le64_to_cpu( 1040 + enclosure_dev->pg0.enclosure_logical_id); 1041 + 1042 + flags = tgtdev->devpg0_flag; 1043 + 1082 1044 tgtdev->is_hidden = (flags & MPI3_DEVICE0_FLAGS_HIDDEN); 1083 1045 1084 1046 if (is_added == true) ··· 1105 1045 scsi_tgt_priv_data->dev_type = tgtdev->dev_type; 1106 1046 scsi_tgt_priv_data->io_throttle_enabled = 1107 1047 tgtdev->io_throttle_enabled; 1048 + if (is_added == true) 1049 + atomic_set(&scsi_tgt_priv_data->block_io, 0); 1108 1050 } 1109 1051 1110 1052 switch (dev_pg0->access_status) { ··· 1130 1068 tgtdev->dev_spec.sas_sata_inf.dev_info = dev_info; 1131 1069 tgtdev->dev_spec.sas_sata_inf.sas_address = 1132 1070 le64_to_cpu(sasinf->sas_address); 1071 + tgtdev->dev_spec.sas_sata_inf.phy_id = sasinf->phy_num; 1072 + tgtdev->dev_spec.sas_sata_inf.attached_phy_id = 1073 + sasinf->attached_phy_identifier; 1133 1074 if ((dev_info & MPI3_SAS_DEVICE_INFO_DEVICE_TYPE_MASK) != 1134 1075 MPI3_SAS_DEVICE_INFO_DEVICE_TYPE_END_DEVICE) 1135 1076 tgtdev->is_hidden = 1; 1136 1077 else if (!(dev_info & (MPI3_SAS_DEVICE_INFO_STP_SATA_TARGET | 1137 1078 MPI3_SAS_DEVICE_INFO_SSP_TARGET))) 1138 1079 tgtdev->is_hidden = 1; 1080 + 1081 + if (((tgtdev->devpg0_flag & 1082 + MPI3_DEVICE0_FLAGS_ATT_METHOD_DIR_ATTACHED) 1083 + && (tgtdev->devpg0_flag & 1084 + MPI3_DEVICE0_FLAGS_ATT_METHOD_VIRTUAL)) || 1085 + (tgtdev->parent_handle == 0xFFFF)) 1086 + tgtdev->non_stl = 1; 1087 + if (tgtdev->dev_spec.sas_sata_inf.hba_port) 1088 + tgtdev->dev_spec.sas_sata_inf.hba_port->port_id = 1089 + dev_pg0->io_unit_port; 1139 1090 break; 1140 1091 } 1141 1092 case MPI3_DEVICE_DEVFORM_PCIE: ··· 1181 1106 ((dev_info & MPI3_DEVICE0_PCIE_DEVICE_INFO_TYPE_MASK) != 1182 1107 MPI3_DEVICE0_PCIE_DEVICE_INFO_TYPE_SCSI_DEVICE)) 1183 1108 tgtdev->is_hidden = 1; 1109 + tgtdev->non_stl = 1; 1184 1110 if (!mrioc->shost) 1185 1111 break; 1186 1112 prot_mask = scsi_host_get_prot(mrioc->shost); ··· 1205 1129 tgtdev->dev_spec.vd_inf.state = vdinf->vd_state; 1206 1130 if (vdinf->vd_state == MPI3_DEVICE0_VD_STATE_OFFLINE) 1207 1131 tgtdev->is_hidden = 1; 1132 + tgtdev->non_stl = 1; 1208 1133 tgtdev->dev_spec.vd_inf.tg_id = vdinf_io_throttle_group; 1209 1134 tgtdev->dev_spec.vd_inf.tg_high = 1210 1135 le16_to_cpu(vdinf->io_throttle_group_high) * 2048; ··· 1335 1258 } 1336 1259 1337 1260 /** 1261 + * mpi3mr_free_enclosure_list - release enclosures 1262 + * @mrioc: Adapter instance reference 1263 + * 1264 + * Free memory allocated during encloure add. 1265 + * 1266 + * Return nothing. 1267 + */ 1268 + void mpi3mr_free_enclosure_list(struct mpi3mr_ioc *mrioc) 1269 + { 1270 + struct mpi3mr_enclosure_node *enclosure_dev, *enclosure_dev_next; 1271 + 1272 + list_for_each_entry_safe(enclosure_dev, 1273 + enclosure_dev_next, &mrioc->enclosure_list, list) { 1274 + list_del(&enclosure_dev->list); 1275 + kfree(enclosure_dev); 1276 + } 1277 + } 1278 + 1279 + /** 1280 + * mpi3mr_enclosure_find_by_handle - enclosure search by handle 1281 + * @mrioc: Adapter instance reference 1282 + * @handle: Firmware device handle of the enclosure 1283 + * 1284 + * This searches for enclosure device based on handle, then returns the 1285 + * enclosure object. 1286 + * 1287 + * Return: Enclosure object reference or NULL 1288 + */ 1289 + struct mpi3mr_enclosure_node *mpi3mr_enclosure_find_by_handle( 1290 + struct mpi3mr_ioc *mrioc, u16 handle) 1291 + { 1292 + struct mpi3mr_enclosure_node *enclosure_dev, *r = NULL; 1293 + 1294 + list_for_each_entry(enclosure_dev, &mrioc->enclosure_list, list) { 1295 + if (le16_to_cpu(enclosure_dev->pg0.enclosure_handle) != handle) 1296 + continue; 1297 + r = enclosure_dev; 1298 + goto out; 1299 + } 1300 + out: 1301 + return r; 1302 + } 1303 + 1304 + /** 1305 + * mpi3mr_encldev_add_chg_evt_debug - debug for enclosure event 1306 + * @mrioc: Adapter instance reference 1307 + * @encl_pg0: Enclosure page 0. 1308 + * @is_added: Added event or not 1309 + * 1310 + * Return nothing. 1311 + */ 1312 + static void mpi3mr_encldev_add_chg_evt_debug(struct mpi3mr_ioc *mrioc, 1313 + struct mpi3_enclosure_page0 *encl_pg0, u8 is_added) 1314 + { 1315 + char *reason_str = NULL; 1316 + 1317 + if (!(mrioc->logging_level & MPI3_DEBUG_EVENT_WORK_TASK)) 1318 + return; 1319 + 1320 + if (is_added) 1321 + reason_str = "enclosure added"; 1322 + else 1323 + reason_str = "enclosure dev status changed"; 1324 + 1325 + ioc_info(mrioc, 1326 + "%s: handle(0x%04x), enclosure logical id(0x%016llx)\n", 1327 + reason_str, le16_to_cpu(encl_pg0->enclosure_handle), 1328 + (unsigned long long)le64_to_cpu(encl_pg0->enclosure_logical_id)); 1329 + ioc_info(mrioc, 1330 + "number of slots(%d), port(%d), flags(0x%04x), present(%d)\n", 1331 + le16_to_cpu(encl_pg0->num_slots), encl_pg0->io_unit_port, 1332 + le16_to_cpu(encl_pg0->flags), 1333 + ((le16_to_cpu(encl_pg0->flags) & 1334 + MPI3_ENCLS0_FLAGS_ENCL_DEV_PRESENT_MASK) >> 4)); 1335 + } 1336 + 1337 + /** 1338 + * mpi3mr_encldev_add_chg_evt_bh - Enclosure evt bottomhalf 1339 + * @mrioc: Adapter instance reference 1340 + * @fwevt: Firmware event reference 1341 + * 1342 + * Prints information about the Enclosure device status or 1343 + * Enclosure add events if logging is enabled and add or remove 1344 + * the enclosure from the controller's internal list of 1345 + * enclosures. 1346 + * 1347 + * Return: Nothing. 1348 + */ 1349 + static void mpi3mr_encldev_add_chg_evt_bh(struct mpi3mr_ioc *mrioc, 1350 + struct mpi3mr_fwevt *fwevt) 1351 + { 1352 + struct mpi3mr_enclosure_node *enclosure_dev = NULL; 1353 + struct mpi3_enclosure_page0 *encl_pg0; 1354 + u16 encl_handle; 1355 + u8 added, present; 1356 + 1357 + encl_pg0 = (struct mpi3_enclosure_page0 *) fwevt->event_data; 1358 + added = (fwevt->event_id == MPI3_EVENT_ENCL_DEVICE_ADDED) ? 1 : 0; 1359 + mpi3mr_encldev_add_chg_evt_debug(mrioc, encl_pg0, added); 1360 + 1361 + 1362 + encl_handle = le16_to_cpu(encl_pg0->enclosure_handle); 1363 + present = ((le16_to_cpu(encl_pg0->flags) & 1364 + MPI3_ENCLS0_FLAGS_ENCL_DEV_PRESENT_MASK) >> 4); 1365 + 1366 + if (encl_handle) 1367 + enclosure_dev = mpi3mr_enclosure_find_by_handle(mrioc, 1368 + encl_handle); 1369 + if (!enclosure_dev && present) { 1370 + enclosure_dev = 1371 + kzalloc(sizeof(struct mpi3mr_enclosure_node), 1372 + GFP_KERNEL); 1373 + if (!enclosure_dev) 1374 + return; 1375 + list_add_tail(&enclosure_dev->list, 1376 + &mrioc->enclosure_list); 1377 + } 1378 + if (enclosure_dev) { 1379 + if (!present) { 1380 + list_del(&enclosure_dev->list); 1381 + kfree(enclosure_dev); 1382 + } else 1383 + memcpy(&enclosure_dev->pg0, encl_pg0, 1384 + sizeof(enclosure_dev->pg0)); 1385 + 1386 + } 1387 + } 1388 + 1389 + /** 1338 1390 * mpi3mr_sastopochg_evt_debug - SASTopoChange details 1339 1391 * @mrioc: Adapter instance reference 1340 1392 * @event_data: SAS topology change list event data ··· 1502 1296 ioc_info(mrioc, "%s :sas topology change: (%s)\n", 1503 1297 __func__, status_str); 1504 1298 ioc_info(mrioc, 1505 - "%s :\texpander_handle(0x%04x), enclosure_handle(0x%04x) start_phy(%02d), num_entries(%d)\n", 1299 + "%s :\texpander_handle(0x%04x), port(%d), enclosure_handle(0x%04x) start_phy(%02d), num_entries(%d)\n", 1506 1300 __func__, le16_to_cpu(event_data->expander_dev_handle), 1301 + event_data->io_unit_port, 1507 1302 le16_to_cpu(event_data->enclosure_handle), 1508 1303 event_data->start_phy_num, event_data->num_entries); 1509 1304 for (i = 0; i < event_data->num_entries; i++) { ··· 1562 1355 int i; 1563 1356 u16 handle; 1564 1357 u8 reason_code; 1358 + u64 exp_sas_address = 0, parent_sas_address = 0; 1359 + struct mpi3mr_hba_port *hba_port = NULL; 1565 1360 struct mpi3mr_tgt_dev *tgtdev = NULL; 1361 + struct mpi3mr_sas_node *sas_expander = NULL; 1362 + unsigned long flags; 1363 + u8 link_rate, prev_link_rate, parent_phy_number; 1566 1364 1567 1365 mpi3mr_sastopochg_evt_debug(mrioc, event_data); 1366 + if (mrioc->sas_transport_enabled) { 1367 + hba_port = mpi3mr_get_hba_port_by_id(mrioc, 1368 + event_data->io_unit_port); 1369 + if (le16_to_cpu(event_data->expander_dev_handle)) { 1370 + spin_lock_irqsave(&mrioc->sas_node_lock, flags); 1371 + sas_expander = __mpi3mr_expander_find_by_handle(mrioc, 1372 + le16_to_cpu(event_data->expander_dev_handle)); 1373 + if (sas_expander) { 1374 + exp_sas_address = sas_expander->sas_address; 1375 + hba_port = sas_expander->hba_port; 1376 + } 1377 + spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); 1378 + parent_sas_address = exp_sas_address; 1379 + } else 1380 + parent_sas_address = mrioc->sas_hba.sas_address; 1381 + } 1568 1382 1569 1383 for (i = 0; i < event_data->num_entries; i++) { 1570 1384 if (fwevt->discard) ··· 1607 1379 mpi3mr_tgtdev_del_from_list(mrioc, tgtdev); 1608 1380 mpi3mr_tgtdev_put(tgtdev); 1609 1381 break; 1382 + case MPI3_EVENT_SAS_TOPO_PHY_RC_RESPONDING: 1383 + case MPI3_EVENT_SAS_TOPO_PHY_RC_PHY_CHANGED: 1384 + case MPI3_EVENT_SAS_TOPO_PHY_RC_NO_CHANGE: 1385 + { 1386 + if (!mrioc->sas_transport_enabled || tgtdev->non_stl 1387 + || tgtdev->is_hidden) 1388 + break; 1389 + link_rate = event_data->phy_entry[i].link_rate >> 4; 1390 + prev_link_rate = event_data->phy_entry[i].link_rate & 0xF; 1391 + if (link_rate == prev_link_rate) 1392 + break; 1393 + if (!parent_sas_address) 1394 + break; 1395 + parent_phy_number = event_data->start_phy_num + i; 1396 + mpi3mr_update_links(mrioc, parent_sas_address, handle, 1397 + parent_phy_number, link_rate, hba_port); 1398 + break; 1399 + } 1610 1400 default: 1611 1401 break; 1612 1402 } 1613 1403 if (tgtdev) 1614 1404 mpi3mr_tgtdev_put(tgtdev); 1405 + } 1406 + 1407 + if (mrioc->sas_transport_enabled && (event_data->exp_status == 1408 + MPI3_EVENT_SAS_TOPO_ES_NOT_RESPONDING)) { 1409 + if (sas_expander) 1410 + mpi3mr_expander_remove(mrioc, exp_sas_address, 1411 + hba_port); 1615 1412 } 1616 1413 } 1617 1414 ··· 1857 1604 static void mpi3mr_fwevt_bh(struct mpi3mr_ioc *mrioc, 1858 1605 struct mpi3mr_fwevt *fwevt) 1859 1606 { 1607 + struct mpi3_device_page0 *dev_pg0 = NULL; 1608 + u16 perst_id, handle, dev_info; 1609 + struct mpi3_device0_sas_sata_format *sasinf = NULL; 1610 + 1860 1611 mpi3mr_fwevt_del_from_list(mrioc, fwevt); 1861 1612 mrioc->current_event = fwevt; 1862 1613 1863 1614 if (mrioc->stop_drv_processing) 1864 1615 goto out; 1616 + 1617 + if (mrioc->unrecoverable) { 1618 + dprint_event_bh(mrioc, 1619 + "ignoring event(0x%02x) in bottom half handler due to unrecoverable controller\n", 1620 + fwevt->event_id); 1621 + goto out; 1622 + } 1865 1623 1866 1624 if (!fwevt->process_evt) 1867 1625 goto evt_ack; ··· 1880 1616 switch (fwevt->event_id) { 1881 1617 case MPI3_EVENT_DEVICE_ADDED: 1882 1618 { 1883 - struct mpi3_device_page0 *dev_pg0 = 1884 - (struct mpi3_device_page0 *)fwevt->event_data; 1885 - mpi3mr_report_tgtdev_to_host(mrioc, 1886 - le16_to_cpu(dev_pg0->persistent_id)); 1619 + dev_pg0 = (struct mpi3_device_page0 *)fwevt->event_data; 1620 + perst_id = le16_to_cpu(dev_pg0->persistent_id); 1621 + handle = le16_to_cpu(dev_pg0->dev_handle); 1622 + if (perst_id != MPI3_DEVICE0_PERSISTENTID_INVALID) 1623 + mpi3mr_report_tgtdev_to_host(mrioc, perst_id); 1624 + else if (mrioc->sas_transport_enabled && 1625 + (dev_pg0->device_form == MPI3_DEVICE_DEVFORM_SAS_SATA)) { 1626 + sasinf = &dev_pg0->device_specific.sas_sata_format; 1627 + dev_info = le16_to_cpu(sasinf->device_info); 1628 + if (!mrioc->sas_hba.num_phys) 1629 + mpi3mr_sas_host_add(mrioc); 1630 + else 1631 + mpi3mr_sas_host_refresh(mrioc); 1632 + 1633 + if (mpi3mr_is_expander_device(dev_info)) 1634 + mpi3mr_expander_add(mrioc, handle); 1635 + } 1887 1636 break; 1888 1637 } 1889 1638 case MPI3_EVENT_DEVICE_INFO_CHANGED: 1890 1639 { 1891 - mpi3mr_devinfochg_evt_bh(mrioc, 1892 - (struct mpi3_device_page0 *)fwevt->event_data); 1640 + dev_pg0 = (struct mpi3_device_page0 *)fwevt->event_data; 1641 + perst_id = le16_to_cpu(dev_pg0->persistent_id); 1642 + if (perst_id != MPI3_DEVICE0_PERSISTENTID_INVALID) 1643 + mpi3mr_devinfochg_evt_bh(mrioc, dev_pg0); 1893 1644 break; 1894 1645 } 1895 1646 case MPI3_EVENT_DEVICE_STATUS_CHANGE: ··· 1912 1633 mpi3mr_devstatuschg_evt_bh(mrioc, fwevt); 1913 1634 break; 1914 1635 } 1636 + case MPI3_EVENT_ENCL_DEVICE_ADDED: 1637 + case MPI3_EVENT_ENCL_DEVICE_STATUS_CHANGE: 1638 + { 1639 + mpi3mr_encldev_add_chg_evt_bh(mrioc, fwevt); 1640 + break; 1641 + } 1642 + 1915 1643 case MPI3_EVENT_SAS_TOPOLOGY_CHANGE_LIST: 1916 1644 { 1917 1645 mpi3mr_sastopochg_evt_bh(mrioc, fwevt); ··· 1946 1660 mpi3mr_set_qd_for_all_vd_in_tg(mrioc, tg); 1947 1661 tg->need_qd_reduction = 0; 1948 1662 } 1663 + break; 1664 + } 1665 + case MPI3_EVENT_WAIT_FOR_DEVICES_TO_REFRESH: 1666 + { 1667 + while (mrioc->device_refresh_on) 1668 + msleep(500); 1669 + 1670 + dprint_event_bh(mrioc, 1671 + "scan for non responding and newly added devices after soft reset started\n"); 1672 + if (mrioc->sas_transport_enabled) { 1673 + mpi3mr_refresh_sas_ports(mrioc); 1674 + mpi3mr_refresh_expanders(mrioc); 1675 + } 1676 + mpi3mr_rfresh_tgtdevs(mrioc); 1677 + ioc_info(mrioc, 1678 + "scan for non responding and newly added devices after soft reset completed\n"); 1949 1679 break; 1950 1680 } 1951 1681 default: ··· 2018 1716 u16 perst_id = 0; 2019 1717 2020 1718 perst_id = le16_to_cpu(dev_pg0->persistent_id); 1719 + if (perst_id == MPI3_DEVICE0_PERSISTENTID_INVALID) 1720 + return retval; 1721 + 2021 1722 tgtdev = mpi3mr_get_tgtdev_by_perst_id(mrioc, perst_id); 2022 1723 if (tgtdev) { 2023 1724 mpi3mr_update_tgtdev(mrioc, tgtdev, dev_pg0, true); ··· 2734 2429 } 2735 2430 2736 2431 /** 2432 + * mpi3mr_add_event_wait_for_device_refresh - Add Wait for Device Refresh Event 2433 + * @mrioc: Adapter instance reference 2434 + * 2435 + * Add driver specific event to make sure that the driver won't process the 2436 + * events until all the devices are refreshed during soft reset. 2437 + * 2438 + * Return: Nothing 2439 + */ 2440 + void mpi3mr_add_event_wait_for_device_refresh(struct mpi3mr_ioc *mrioc) 2441 + { 2442 + struct mpi3mr_fwevt *fwevt = NULL; 2443 + 2444 + fwevt = mpi3mr_alloc_fwevt(0); 2445 + if (!fwevt) { 2446 + dprint_event_th(mrioc, 2447 + "failed to schedule bottom half handler for event(0x%02x)\n", 2448 + MPI3_EVENT_WAIT_FOR_DEVICES_TO_REFRESH); 2449 + return; 2450 + } 2451 + fwevt->mrioc = mrioc; 2452 + fwevt->event_id = MPI3_EVENT_WAIT_FOR_DEVICES_TO_REFRESH; 2453 + fwevt->send_ack = 0; 2454 + fwevt->process_evt = 1; 2455 + fwevt->evt_ctx = 0; 2456 + fwevt->event_data_size = 0; 2457 + mpi3mr_fwevt_add_to_list(mrioc, fwevt); 2458 + } 2459 + 2460 + /** 2737 2461 * mpi3mr_os_handle_events - Firmware event handler 2738 2462 * @mrioc: Adapter instance reference 2739 2463 * @event_reply: event data ··· 2828 2494 } 2829 2495 case MPI3_EVENT_DEVICE_INFO_CHANGED: 2830 2496 case MPI3_EVENT_LOG_DATA: 2497 + case MPI3_EVENT_ENCL_DEVICE_STATUS_CHANGE: 2498 + case MPI3_EVENT_ENCL_DEVICE_ADDED: 2831 2499 { 2832 2500 process_evt_bh = 1; 2833 2501 break; ··· 2844 2508 mpi3mr_cablemgmt_evt_th(mrioc, event_reply); 2845 2509 break; 2846 2510 } 2847 - case MPI3_EVENT_ENCL_DEVICE_STATUS_CHANGE: 2848 2511 case MPI3_EVENT_SAS_DISCOVERY: 2849 2512 case MPI3_EVENT_SAS_DEVICE_DISCOVERY_ERROR: 2850 2513 case MPI3_EVENT_SAS_BROADCAST_PRIMITIVE: ··· 4184 3849 struct Scsi_Host *shost; 4185 3850 struct mpi3mr_ioc *mrioc; 4186 3851 struct mpi3mr_stgt_priv_data *scsi_tgt_priv_data; 4187 - struct mpi3mr_tgt_dev *tgt_dev; 3852 + struct mpi3mr_tgt_dev *tgt_dev = NULL; 4188 3853 unsigned long flags; 4189 3854 struct scsi_target *starget; 3855 + struct sas_rphy *rphy = NULL; 4190 3856 4191 3857 if (!sdev->hostdata) 4192 3858 return; ··· 4200 3864 scsi_tgt_priv_data->num_luns--; 4201 3865 4202 3866 spin_lock_irqsave(&mrioc->tgtdev_lock, flags); 4203 - tgt_dev = __mpi3mr_get_tgtdev_by_perst_id(mrioc, starget->id); 3867 + if (starget->channel == mrioc->scsi_device_channel) 3868 + tgt_dev = __mpi3mr_get_tgtdev_by_perst_id(mrioc, starget->id); 3869 + else if (mrioc->sas_transport_enabled && !starget->channel) { 3870 + rphy = dev_to_rphy(starget->dev.parent); 3871 + tgt_dev = __mpi3mr_get_tgtdev_by_addr_and_rphy(mrioc, 3872 + rphy->identify.sas_address, rphy); 3873 + } 3874 + 4204 3875 if (tgt_dev && (!scsi_tgt_priv_data->num_luns)) 4205 3876 tgt_dev->starget = NULL; 4206 3877 if (tgt_dev) ··· 4272 3929 struct scsi_target *starget; 4273 3930 struct Scsi_Host *shost; 4274 3931 struct mpi3mr_ioc *mrioc; 4275 - struct mpi3mr_tgt_dev *tgt_dev; 3932 + struct mpi3mr_tgt_dev *tgt_dev = NULL; 4276 3933 unsigned long flags; 4277 3934 int retval = 0; 3935 + struct sas_rphy *rphy = NULL; 4278 3936 4279 3937 starget = scsi_target(sdev); 4280 3938 shost = dev_to_shost(&starget->dev); 4281 3939 mrioc = shost_priv(shost); 4282 3940 4283 3941 spin_lock_irqsave(&mrioc->tgtdev_lock, flags); 4284 - tgt_dev = __mpi3mr_get_tgtdev_by_perst_id(mrioc, starget->id); 3942 + if (starget->channel == mrioc->scsi_device_channel) 3943 + tgt_dev = __mpi3mr_get_tgtdev_by_perst_id(mrioc, starget->id); 3944 + else if (mrioc->sas_transport_enabled && !starget->channel) { 3945 + rphy = dev_to_rphy(starget->dev.parent); 3946 + tgt_dev = __mpi3mr_get_tgtdev_by_addr_and_rphy(mrioc, 3947 + rphy->identify.sas_address, rphy); 3948 + } 4285 3949 spin_unlock_irqrestore(&mrioc->tgtdev_lock, flags); 4286 3950 if (!tgt_dev) 4287 3951 return -ENXIO; ··· 4336 3986 struct Scsi_Host *shost; 4337 3987 struct mpi3mr_ioc *mrioc; 4338 3988 struct mpi3mr_stgt_priv_data *scsi_tgt_priv_data; 4339 - struct mpi3mr_tgt_dev *tgt_dev; 3989 + struct mpi3mr_tgt_dev *tgt_dev = NULL; 4340 3990 struct mpi3mr_sdev_priv_data *scsi_dev_priv_data; 4341 3991 unsigned long flags; 4342 3992 struct scsi_target *starget; 4343 3993 int retval = 0; 3994 + struct sas_rphy *rphy = NULL; 4344 3995 4345 3996 starget = scsi_target(sdev); 4346 3997 shost = dev_to_shost(&starget->dev); ··· 4349 3998 scsi_tgt_priv_data = starget->hostdata; 4350 3999 4351 4000 spin_lock_irqsave(&mrioc->tgtdev_lock, flags); 4352 - tgt_dev = __mpi3mr_get_tgtdev_by_perst_id(mrioc, starget->id); 4001 + 4002 + if (starget->channel == mrioc->scsi_device_channel) 4003 + tgt_dev = __mpi3mr_get_tgtdev_by_perst_id(mrioc, starget->id); 4004 + else if (mrioc->sas_transport_enabled && !starget->channel) { 4005 + rphy = dev_to_rphy(starget->dev.parent); 4006 + tgt_dev = __mpi3mr_get_tgtdev_by_addr_and_rphy(mrioc, 4007 + rphy->identify.sas_address, rphy); 4008 + } 4353 4009 4354 4010 if (tgt_dev) { 4355 4011 if (tgt_dev->starget == NULL) ··· 4399 4041 struct mpi3mr_tgt_dev *tgt_dev; 4400 4042 unsigned long flags; 4401 4043 int retval = 0; 4044 + struct sas_rphy *rphy = NULL; 4045 + bool update_stgt_priv_data = false; 4402 4046 4403 4047 scsi_tgt_priv_data = kzalloc(sizeof(*scsi_tgt_priv_data), GFP_KERNEL); 4404 4048 if (!scsi_tgt_priv_data) ··· 4409 4049 starget->hostdata = scsi_tgt_priv_data; 4410 4050 4411 4051 spin_lock_irqsave(&mrioc->tgtdev_lock, flags); 4412 - tgt_dev = __mpi3mr_get_tgtdev_by_perst_id(mrioc, starget->id); 4413 - if (tgt_dev && !tgt_dev->is_hidden) { 4052 + 4053 + if (starget->channel == mrioc->scsi_device_channel) { 4054 + tgt_dev = __mpi3mr_get_tgtdev_by_perst_id(mrioc, starget->id); 4055 + if (tgt_dev && !tgt_dev->is_hidden) 4056 + update_stgt_priv_data = true; 4057 + else 4058 + retval = -ENXIO; 4059 + } else if (mrioc->sas_transport_enabled && !starget->channel) { 4060 + rphy = dev_to_rphy(starget->dev.parent); 4061 + tgt_dev = __mpi3mr_get_tgtdev_by_addr_and_rphy(mrioc, 4062 + rphy->identify.sas_address, rphy); 4063 + if (tgt_dev && !tgt_dev->is_hidden && !tgt_dev->non_stl && 4064 + (tgt_dev->dev_type == MPI3_DEVICE_DEVFORM_SAS_SATA)) 4065 + update_stgt_priv_data = true; 4066 + else 4067 + retval = -ENXIO; 4068 + } 4069 + 4070 + if (update_stgt_priv_data) { 4414 4071 scsi_tgt_priv_data->starget = starget; 4415 4072 scsi_tgt_priv_data->dev_handle = tgt_dev->dev_handle; 4416 4073 scsi_tgt_priv_data->perst_id = tgt_dev->perst_id; ··· 4441 4064 if (tgt_dev->dev_type == MPI3_DEVICE_DEVFORM_VD) 4442 4065 scsi_tgt_priv_data->throttle_group = 4443 4066 tgt_dev->dev_spec.vd_inf.tg; 4444 - } else 4445 - retval = -ENXIO; 4067 + } 4446 4068 spin_unlock_irqrestore(&mrioc->tgtdev_lock, flags); 4447 4069 4448 4070 return retval; ··· 4630 4254 4631 4255 stgt_priv_data = sdev_priv_data->tgt_priv_data; 4632 4256 4257 + if (atomic_read(&stgt_priv_data->block_io)) { 4258 + if (mrioc->stop_drv_processing) { 4259 + scmd->result = DID_NO_CONNECT << 16; 4260 + scsi_done(scmd); 4261 + goto out; 4262 + } 4263 + retval = SCSI_MLQUEUE_DEVICE_BUSY; 4264 + goto out; 4265 + } 4266 + 4633 4267 dev_handle = stgt_priv_data->dev_handle; 4634 4268 if (dev_handle == MPI3MR_INVALID_DEV_HANDLE) { 4635 4269 scmd->result = DID_NO_CONNECT << 16; ··· 4649 4263 if (stgt_priv_data->dev_removed) { 4650 4264 scmd->result = DID_NO_CONNECT << 16; 4651 4265 scsi_done(scmd); 4652 - goto out; 4653 - } 4654 - 4655 - if (atomic_read(&stgt_priv_data->block_io)) { 4656 - if (mrioc->stop_drv_processing) { 4657 - scmd->result = DID_NO_CONNECT << 16; 4658 - scsi_done(scmd); 4659 - goto out; 4660 - } 4661 - retval = SCSI_MLQUEUE_DEVICE_BUSY; 4662 4266 goto out; 4663 4267 } 4664 4268 ··· 4929 4553 spin_lock_init(&mrioc->tgtdev_lock); 4930 4554 spin_lock_init(&mrioc->watchdog_lock); 4931 4555 spin_lock_init(&mrioc->chain_buf_lock); 4556 + spin_lock_init(&mrioc->sas_node_lock); 4932 4557 4933 4558 INIT_LIST_HEAD(&mrioc->fwevt_list); 4934 4559 INIT_LIST_HEAD(&mrioc->tgtdev_list); 4935 4560 INIT_LIST_HEAD(&mrioc->delayed_rmhs_list); 4936 4561 INIT_LIST_HEAD(&mrioc->delayed_evtack_cmds_list); 4562 + INIT_LIST_HEAD(&mrioc->sas_expander_list); 4563 + INIT_LIST_HEAD(&mrioc->hba_port_table_list); 4564 + INIT_LIST_HEAD(&mrioc->enclosure_list); 4937 4565 4938 4566 mutex_init(&mrioc->reset_mutex); 4939 4567 mpi3mr_init_drv_cmd(&mrioc->init_cmds, MPI3MR_HOSTTAG_INITCMDS); 4940 4568 mpi3mr_init_drv_cmd(&mrioc->host_tm_cmds, MPI3MR_HOSTTAG_BLK_TMS); 4941 4569 mpi3mr_init_drv_cmd(&mrioc->bsg_cmds, MPI3MR_HOSTTAG_BSG_CMDS); 4570 + mpi3mr_init_drv_cmd(&mrioc->cfg_cmds, MPI3MR_HOSTTAG_CFG_CMDS); 4571 + mpi3mr_init_drv_cmd(&mrioc->transport_cmds, 4572 + MPI3MR_HOSTTAG_TRANSPORT_CMDS); 4942 4573 4943 4574 for (i = 0; i < MPI3MR_NUM_DEVRMCMD; i++) 4944 4575 mpi3mr_init_drv_cmd(&mrioc->dev_rmhs_cmds[i], ··· 5080 4697 while (mrioc->reset_in_progress || mrioc->is_driver_loading) 5081 4698 ssleep(1); 5082 4699 4700 + if (!pci_device_is_present(mrioc->pdev)) { 4701 + mrioc->unrecoverable = 1; 4702 + mpi3mr_flush_cmds_for_unrecovered_controller(mrioc); 4703 + } 4704 + 5083 4705 mpi3mr_bsg_exit(mrioc); 5084 4706 mrioc->stop_drv_processing = 1; 5085 4707 mpi3mr_cleanup_fwevt_list(mrioc); ··· 5094 4706 spin_unlock_irqrestore(&mrioc->fwevt_lock, flags); 5095 4707 if (wq) 5096 4708 destroy_workqueue(wq); 5097 - scsi_remove_host(shost); 4709 + 4710 + if (mrioc->sas_transport_enabled) 4711 + sas_remove_host(shost); 4712 + else 4713 + scsi_remove_host(shost); 5098 4714 5099 4715 list_for_each_entry_safe(tgtdev, tgtdev_next, &mrioc->tgtdev_list, 5100 4716 list) { ··· 5155 4763 mpi3mr_cleanup_resources(mrioc); 5156 4764 } 5157 4765 5158 - #ifdef CONFIG_PM 5159 4766 /** 5160 4767 * mpi3mr_suspend - PCI power management suspend callback 5161 - * @pdev: PCI device instance 5162 - * @state: New power state 4768 + * @dev: Device struct 5163 4769 * 5164 4770 * Change the power state to the given value and cleanup the IOC 5165 4771 * by issuing MUR and shutdown notification 5166 4772 * 5167 4773 * Return: 0 always. 5168 4774 */ 5169 - static int mpi3mr_suspend(struct pci_dev *pdev, pm_message_t state) 4775 + static int __maybe_unused 4776 + mpi3mr_suspend(struct device *dev) 5170 4777 { 4778 + struct pci_dev *pdev = to_pci_dev(dev); 5171 4779 struct Scsi_Host *shost = pci_get_drvdata(pdev); 5172 4780 struct mpi3mr_ioc *mrioc; 5173 - pci_power_t device_state; 5174 4781 5175 4782 if (!shost) 5176 4783 return 0; ··· 5183 4792 mpi3mr_stop_watchdog(mrioc); 5184 4793 mpi3mr_cleanup_ioc(mrioc); 5185 4794 5186 - device_state = pci_choose_state(pdev, state); 5187 - ioc_info(mrioc, "pdev=0x%p, slot=%s, entering operating state [D%d]\n", 5188 - pdev, pci_name(pdev), device_state); 5189 - pci_save_state(pdev); 4795 + ioc_info(mrioc, "pdev=0x%p, slot=%s, entering operating state\n", 4796 + pdev, pci_name(pdev)); 5190 4797 mpi3mr_cleanup_resources(mrioc); 5191 - pci_set_power_state(pdev, device_state); 5192 4798 5193 4799 return 0; 5194 4800 } 5195 4801 5196 4802 /** 5197 4803 * mpi3mr_resume - PCI power management resume callback 5198 - * @pdev: PCI device instance 4804 + * @dev: Device struct 5199 4805 * 5200 4806 * Restore the power state to D0 and reinitialize the controller 5201 4807 * and resume I/O operations to the target devices 5202 4808 * 5203 4809 * Return: 0 on success, non-zero on failure 5204 4810 */ 5205 - static int mpi3mr_resume(struct pci_dev *pdev) 4811 + static int __maybe_unused 4812 + mpi3mr_resume(struct device *dev) 5206 4813 { 4814 + struct pci_dev *pdev = to_pci_dev(dev); 5207 4815 struct Scsi_Host *shost = pci_get_drvdata(pdev); 5208 4816 struct mpi3mr_ioc *mrioc; 5209 4817 pci_power_t device_state = pdev->current_state; ··· 5215 4825 5216 4826 ioc_info(mrioc, "pdev=0x%p, slot=%s, previous operating state [D%d]\n", 5217 4827 pdev, pci_name(pdev), device_state); 5218 - pci_set_power_state(pdev, PCI_D0); 5219 - pci_enable_wake(pdev, PCI_D0, 0); 5220 - pci_restore_state(pdev); 5221 4828 mrioc->pdev = pdev; 5222 4829 mrioc->cpu_count = num_online_cpus(); 5223 4830 r = mpi3mr_setup_resources(mrioc); ··· 5225 4838 } 5226 4839 5227 4840 mrioc->stop_drv_processing = 0; 4841 + mpi3mr_invalidate_devhandles(mrioc); 4842 + mpi3mr_free_enclosure_list(mrioc); 5228 4843 mpi3mr_memset_buffers(mrioc); 5229 4844 r = mpi3mr_reinit_ioc(mrioc, 1); 5230 4845 if (r) { 5231 4846 ioc_err(mrioc, "resuming controller failed[%d]\n", r); 5232 4847 return r; 5233 4848 } 4849 + ssleep(MPI3MR_RESET_TOPOLOGY_SETTLE_TIME); 5234 4850 scsi_unblock_requests(shost); 4851 + mrioc->device_refresh_on = 0; 5235 4852 mpi3mr_start_watchdog(mrioc); 5236 4853 5237 4854 return 0; 5238 4855 } 5239 - #endif 5240 4856 5241 4857 static const struct pci_device_id mpi3mr_pci_id_table[] = { 5242 4858 { ··· 5250 4860 }; 5251 4861 MODULE_DEVICE_TABLE(pci, mpi3mr_pci_id_table); 5252 4862 4863 + static SIMPLE_DEV_PM_OPS(mpi3mr_pm_ops, mpi3mr_suspend, mpi3mr_resume); 4864 + 5253 4865 static struct pci_driver mpi3mr_pci_driver = { 5254 4866 .name = MPI3MR_DRIVER_NAME, 5255 4867 .id_table = mpi3mr_pci_id_table, 5256 4868 .probe = mpi3mr_probe, 5257 4869 .remove = mpi3mr_remove, 5258 4870 .shutdown = mpi3mr_shutdown, 5259 - #ifdef CONFIG_PM 5260 - .suspend = mpi3mr_suspend, 5261 - .resume = mpi3mr_resume, 5262 - #endif 4871 + .driver.pm = &mpi3mr_pm_ops, 5263 4872 }; 5264 4873 5265 4874 static ssize_t event_counter_show(struct device_driver *dd, char *buf) ··· 5274 4885 pr_info("Loading %s version %s\n", MPI3MR_DRIVER_NAME, 5275 4886 MPI3MR_DRIVER_VERSION); 5276 4887 4888 + mpi3mr_transport_template = 4889 + sas_attach_transport(&mpi3mr_transport_functions); 4890 + if (!mpi3mr_transport_template) { 4891 + pr_err("%s failed to load due to sas transport attach failure\n", 4892 + MPI3MR_DRIVER_NAME); 4893 + return -ENODEV; 4894 + } 4895 + 5277 4896 ret_val = pci_register_driver(&mpi3mr_pci_driver); 5278 4897 if (ret_val) { 5279 4898 pr_err("%s failed to load due to pci register driver failure\n", 5280 4899 MPI3MR_DRIVER_NAME); 5281 - return ret_val; 4900 + goto err_pci_reg_fail; 5282 4901 } 5283 4902 5284 4903 ret_val = driver_create_file(&mpi3mr_pci_driver.driver, 5285 4904 &driver_attr_event_counter); 5286 4905 if (ret_val) 5287 - pci_unregister_driver(&mpi3mr_pci_driver); 4906 + goto err_event_counter; 5288 4907 4908 + return ret_val; 4909 + 4910 + err_event_counter: 4911 + pci_unregister_driver(&mpi3mr_pci_driver); 4912 + 4913 + err_pci_reg_fail: 4914 + sas_release_transport(mpi3mr_transport_template); 5289 4915 return ret_val; 5290 4916 } 5291 4917 ··· 5317 4913 driver_remove_file(&mpi3mr_pci_driver.driver, 5318 4914 &driver_attr_event_counter); 5319 4915 pci_unregister_driver(&mpi3mr_pci_driver); 4916 + sas_release_transport(mpi3mr_transport_template); 5320 4917 } 5321 4918 5322 4919 module_init(mpi3mr_init);
+3291
drivers/scsi/mpi3mr/mpi3mr_transport.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* 3 + * Driver for Broadcom MPI3 Storage Controllers 4 + * 5 + * Copyright (C) 2017-2022 Broadcom Inc. 6 + * (mailto: mpi3mr-linuxdrv.pdl@broadcom.com) 7 + * 8 + */ 9 + 10 + #include "mpi3mr.h" 11 + 12 + static void mpi3mr_expander_node_remove(struct mpi3mr_ioc *mrioc, 13 + struct mpi3mr_sas_node *sas_expander); 14 + 15 + /** 16 + * mpi3mr_post_transport_req - Issue transport requests and wait 17 + * @mrioc: Adapter instance reference 18 + * @request: Properly populated MPI3 request 19 + * @request_sz: Size of the MPI3 request 20 + * @reply: Pointer to return MPI3 reply 21 + * @reply_sz: Size of the MPI3 reply buffer 22 + * @timeout: Timeout in seconds 23 + * @ioc_status: Pointer to return ioc status 24 + * 25 + * A generic function for posting MPI3 requests from the SAS 26 + * transport layer that uses transport command infrastructure. 27 + * This blocks for the completion of request for timeout seconds 28 + * and if the request times out this function faults the 29 + * controller with proper reason code. 30 + * 31 + * On successful completion of the request this function returns 32 + * appropriate ioc status from the firmware back to the caller. 33 + * 34 + * Return: 0 on success, non-zero on failure. 35 + */ 36 + static int mpi3mr_post_transport_req(struct mpi3mr_ioc *mrioc, void *request, 37 + u16 request_sz, void *reply, u16 reply_sz, int timeout, 38 + u16 *ioc_status) 39 + { 40 + int retval = 0; 41 + 42 + mutex_lock(&mrioc->transport_cmds.mutex); 43 + if (mrioc->transport_cmds.state & MPI3MR_CMD_PENDING) { 44 + retval = -1; 45 + ioc_err(mrioc, "sending transport request failed due to command in use\n"); 46 + mutex_unlock(&mrioc->transport_cmds.mutex); 47 + goto out; 48 + } 49 + mrioc->transport_cmds.state = MPI3MR_CMD_PENDING; 50 + mrioc->transport_cmds.is_waiting = 1; 51 + mrioc->transport_cmds.callback = NULL; 52 + mrioc->transport_cmds.ioc_status = 0; 53 + mrioc->transport_cmds.ioc_loginfo = 0; 54 + 55 + init_completion(&mrioc->transport_cmds.done); 56 + dprint_cfg_info(mrioc, "posting transport request\n"); 57 + if (mrioc->logging_level & MPI3_DEBUG_TRANSPORT_INFO) 58 + dprint_dump(request, request_sz, "transport_req"); 59 + retval = mpi3mr_admin_request_post(mrioc, request, request_sz, 1); 60 + if (retval) { 61 + ioc_err(mrioc, "posting transport request failed\n"); 62 + goto out_unlock; 63 + } 64 + wait_for_completion_timeout(&mrioc->transport_cmds.done, 65 + (timeout * HZ)); 66 + if (!(mrioc->transport_cmds.state & MPI3MR_CMD_COMPLETE)) { 67 + mpi3mr_check_rh_fault_ioc(mrioc, 68 + MPI3MR_RESET_FROM_SAS_TRANSPORT_TIMEOUT); 69 + ioc_err(mrioc, "transport request timed out\n"); 70 + retval = -1; 71 + goto out_unlock; 72 + } 73 + *ioc_status = mrioc->transport_cmds.ioc_status & 74 + MPI3_IOCSTATUS_STATUS_MASK; 75 + if ((*ioc_status) != MPI3_IOCSTATUS_SUCCESS) 76 + dprint_transport_err(mrioc, 77 + "transport request returned with ioc_status(0x%04x), log_info(0x%08x)\n", 78 + *ioc_status, mrioc->transport_cmds.ioc_loginfo); 79 + 80 + if ((reply) && (mrioc->transport_cmds.state & MPI3MR_CMD_REPLY_VALID)) 81 + memcpy((u8 *)reply, mrioc->transport_cmds.reply, reply_sz); 82 + 83 + out_unlock: 84 + mrioc->transport_cmds.state = MPI3MR_CMD_NOTUSED; 85 + mutex_unlock(&mrioc->transport_cmds.mutex); 86 + 87 + out: 88 + return retval; 89 + } 90 + 91 + /* report manufacture request structure */ 92 + struct rep_manu_request { 93 + u8 smp_frame_type; 94 + u8 function; 95 + u8 reserved; 96 + u8 request_length; 97 + }; 98 + 99 + /* report manufacture reply structure */ 100 + struct rep_manu_reply { 101 + u8 smp_frame_type; /* 0x41 */ 102 + u8 function; /* 0x01 */ 103 + u8 function_result; 104 + u8 response_length; 105 + u16 expander_change_count; 106 + u8 reserved0[2]; 107 + u8 sas_format; 108 + u8 reserved2[3]; 109 + u8 vendor_id[SAS_EXPANDER_VENDOR_ID_LEN]; 110 + u8 product_id[SAS_EXPANDER_PRODUCT_ID_LEN]; 111 + u8 product_rev[SAS_EXPANDER_PRODUCT_REV_LEN]; 112 + u8 component_vendor_id[SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN]; 113 + u16 component_id; 114 + u8 component_revision_id; 115 + u8 reserved3; 116 + u8 vendor_specific[8]; 117 + }; 118 + 119 + /** 120 + * mpi3mr_report_manufacture - obtain SMP report_manufacture 121 + * @mrioc: Adapter instance reference 122 + * @sas_address: SAS address of the expander device 123 + * @edev: SAS transport layer sas_expander_device object 124 + * @port_id: ID of the HBA port 125 + * 126 + * Fills in the sas_expander_device with manufacturing info. 127 + * 128 + * Return: 0 for success, non-zero for failure. 129 + */ 130 + static int mpi3mr_report_manufacture(struct mpi3mr_ioc *mrioc, 131 + u64 sas_address, struct sas_expander_device *edev, u8 port_id) 132 + { 133 + struct mpi3_smp_passthrough_request mpi_request; 134 + struct mpi3_smp_passthrough_reply mpi_reply; 135 + struct rep_manu_reply *manufacture_reply; 136 + struct rep_manu_request *manufacture_request; 137 + int rc = 0; 138 + void *psge; 139 + void *data_out = NULL; 140 + dma_addr_t data_out_dma; 141 + dma_addr_t data_in_dma; 142 + size_t data_in_sz; 143 + size_t data_out_sz; 144 + u8 sgl_flags = MPI3MR_SGEFLAGS_SYSTEM_SIMPLE_END_OF_LIST; 145 + u16 request_sz = sizeof(struct mpi3_smp_passthrough_request); 146 + u16 reply_sz = sizeof(struct mpi3_smp_passthrough_reply); 147 + u16 ioc_status; 148 + u8 *tmp; 149 + 150 + if (mrioc->reset_in_progress) { 151 + ioc_err(mrioc, "%s: host reset in progress!\n", __func__); 152 + return -EFAULT; 153 + } 154 + 155 + data_out_sz = sizeof(struct rep_manu_request); 156 + data_in_sz = sizeof(struct rep_manu_reply); 157 + data_out = dma_alloc_coherent(&mrioc->pdev->dev, 158 + data_out_sz + data_in_sz, &data_out_dma, GFP_KERNEL); 159 + if (!data_out) { 160 + rc = -ENOMEM; 161 + goto out; 162 + } 163 + 164 + data_in_dma = data_out_dma + data_out_sz; 165 + manufacture_reply = data_out + data_out_sz; 166 + 167 + manufacture_request = data_out; 168 + manufacture_request->smp_frame_type = 0x40; 169 + manufacture_request->function = 1; 170 + manufacture_request->reserved = 0; 171 + manufacture_request->request_length = 0; 172 + 173 + memset(&mpi_request, 0, request_sz); 174 + memset(&mpi_reply, 0, reply_sz); 175 + mpi_request.host_tag = cpu_to_le16(MPI3MR_HOSTTAG_TRANSPORT_CMDS); 176 + mpi_request.function = MPI3_FUNCTION_SMP_PASSTHROUGH; 177 + mpi_request.io_unit_port = (u8) port_id; 178 + mpi_request.sas_address = cpu_to_le64(sas_address); 179 + 180 + psge = &mpi_request.request_sge; 181 + mpi3mr_add_sg_single(psge, sgl_flags, data_out_sz, data_out_dma); 182 + 183 + psge = &mpi_request.response_sge; 184 + mpi3mr_add_sg_single(psge, sgl_flags, data_in_sz, data_in_dma); 185 + 186 + dprint_transport_info(mrioc, 187 + "sending report manufacturer SMP request to sas_address(0x%016llx), port(%d)\n", 188 + (unsigned long long)sas_address, port_id); 189 + 190 + rc = mpi3mr_post_transport_req(mrioc, &mpi_request, request_sz, 191 + &mpi_reply, reply_sz, 192 + MPI3MR_INTADMCMD_TIMEOUT, &ioc_status); 193 + if (rc) 194 + goto out; 195 + 196 + dprint_transport_info(mrioc, 197 + "report manufacturer SMP request completed with ioc_status(0x%04x)\n", 198 + ioc_status); 199 + 200 + if (ioc_status != MPI3_IOCSTATUS_SUCCESS) { 201 + rc = -EINVAL; 202 + goto out; 203 + } 204 + 205 + dprint_transport_info(mrioc, 206 + "report manufacturer - reply data transfer size(%d)\n", 207 + le16_to_cpu(mpi_reply.response_data_length)); 208 + 209 + if (le16_to_cpu(mpi_reply.response_data_length) != 210 + sizeof(struct rep_manu_reply)) { 211 + rc = -EINVAL; 212 + goto out; 213 + } 214 + 215 + strscpy(edev->vendor_id, manufacture_reply->vendor_id, 216 + SAS_EXPANDER_VENDOR_ID_LEN); 217 + strscpy(edev->product_id, manufacture_reply->product_id, 218 + SAS_EXPANDER_PRODUCT_ID_LEN); 219 + strscpy(edev->product_rev, manufacture_reply->product_rev, 220 + SAS_EXPANDER_PRODUCT_REV_LEN); 221 + edev->level = manufacture_reply->sas_format & 1; 222 + if (edev->level) { 223 + strscpy(edev->component_vendor_id, 224 + manufacture_reply->component_vendor_id, 225 + SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN); 226 + tmp = (u8 *)&manufacture_reply->component_id; 227 + edev->component_id = tmp[0] << 8 | tmp[1]; 228 + edev->component_revision_id = 229 + manufacture_reply->component_revision_id; 230 + } 231 + 232 + out: 233 + if (data_out) 234 + dma_free_coherent(&mrioc->pdev->dev, data_out_sz + data_in_sz, 235 + data_out, data_out_dma); 236 + 237 + return rc; 238 + } 239 + 240 + /** 241 + * __mpi3mr_expander_find_by_handle - expander search by handle 242 + * @mrioc: Adapter instance reference 243 + * @handle: Firmware device handle of the expander 244 + * 245 + * Context: The caller should acquire sas_node_lock 246 + * 247 + * This searches for expander device based on handle, then 248 + * returns the sas_node object. 249 + * 250 + * Return: Expander sas_node object reference or NULL 251 + */ 252 + struct mpi3mr_sas_node *__mpi3mr_expander_find_by_handle(struct mpi3mr_ioc 253 + *mrioc, u16 handle) 254 + { 255 + struct mpi3mr_sas_node *sas_expander, *r; 256 + 257 + r = NULL; 258 + list_for_each_entry(sas_expander, &mrioc->sas_expander_list, list) { 259 + if (sas_expander->handle != handle) 260 + continue; 261 + r = sas_expander; 262 + goto out; 263 + } 264 + out: 265 + return r; 266 + } 267 + 268 + /** 269 + * mpi3mr_is_expander_device - if device is an expander 270 + * @device_info: Bitfield providing information about the device 271 + * 272 + * Return: 1 if the device is expander device, else 0. 273 + */ 274 + u8 mpi3mr_is_expander_device(u16 device_info) 275 + { 276 + if ((device_info & MPI3_SAS_DEVICE_INFO_DEVICE_TYPE_MASK) == 277 + MPI3_SAS_DEVICE_INFO_DEVICE_TYPE_EXPANDER) 278 + return 1; 279 + else 280 + return 0; 281 + } 282 + 283 + /** 284 + * mpi3mr_get_sas_address - retrieve sas_address for handle 285 + * @mrioc: Adapter instance reference 286 + * @handle: Firmware device handle 287 + * @sas_address: Address to hold sas address 288 + * 289 + * This function issues device page0 read for a given device 290 + * handle and gets the SAS address and return it back 291 + * 292 + * Return: 0 for success, non-zero for failure 293 + */ 294 + static int mpi3mr_get_sas_address(struct mpi3mr_ioc *mrioc, u16 handle, 295 + u64 *sas_address) 296 + { 297 + struct mpi3_device_page0 dev_pg0; 298 + u16 ioc_status; 299 + struct mpi3_device0_sas_sata_format *sasinf; 300 + 301 + *sas_address = 0; 302 + 303 + if ((mpi3mr_cfg_get_dev_pg0(mrioc, &ioc_status, &dev_pg0, 304 + sizeof(dev_pg0), MPI3_DEVICE_PGAD_FORM_HANDLE, 305 + handle))) { 306 + ioc_err(mrioc, "%s: device page0 read failed\n", __func__); 307 + return -ENXIO; 308 + } 309 + 310 + if (ioc_status != MPI3_IOCSTATUS_SUCCESS) { 311 + ioc_err(mrioc, "device page read failed for handle(0x%04x), with ioc_status(0x%04x) failure at %s:%d/%s()!\n", 312 + handle, ioc_status, __FILE__, __LINE__, __func__); 313 + return -ENXIO; 314 + } 315 + 316 + if (le16_to_cpu(dev_pg0.flags) & 317 + MPI3_DEVICE0_FLAGS_CONTROLLER_DEV_HANDLE) 318 + *sas_address = mrioc->sas_hba.sas_address; 319 + else if (dev_pg0.device_form == MPI3_DEVICE_DEVFORM_SAS_SATA) { 320 + sasinf = &dev_pg0.device_specific.sas_sata_format; 321 + *sas_address = le64_to_cpu(sasinf->sas_address); 322 + } else { 323 + ioc_err(mrioc, "%s: device_form(%d) is not SAS_SATA\n", 324 + __func__, dev_pg0.device_form); 325 + return -ENXIO; 326 + } 327 + return 0; 328 + } 329 + 330 + /** 331 + * __mpi3mr_get_tgtdev_by_addr - target device search 332 + * @mrioc: Adapter instance reference 333 + * @sas_address: SAS address of the device 334 + * @hba_port: HBA port entry 335 + * 336 + * This searches for target device from sas address and hba port 337 + * pointer then return mpi3mr_tgt_dev object. 338 + * 339 + * Return: Valid tget_dev or NULL 340 + */ 341 + static struct mpi3mr_tgt_dev *__mpi3mr_get_tgtdev_by_addr(struct mpi3mr_ioc *mrioc, 342 + u64 sas_address, struct mpi3mr_hba_port *hba_port) 343 + { 344 + struct mpi3mr_tgt_dev *tgtdev; 345 + 346 + assert_spin_locked(&mrioc->tgtdev_lock); 347 + 348 + list_for_each_entry(tgtdev, &mrioc->tgtdev_list, list) 349 + if ((tgtdev->dev_type == MPI3_DEVICE_DEVFORM_SAS_SATA) && 350 + (tgtdev->dev_spec.sas_sata_inf.sas_address == sas_address) 351 + && (tgtdev->dev_spec.sas_sata_inf.hba_port == hba_port)) 352 + goto found_device; 353 + return NULL; 354 + found_device: 355 + mpi3mr_tgtdev_get(tgtdev); 356 + return tgtdev; 357 + } 358 + 359 + /** 360 + * mpi3mr_get_tgtdev_by_addr - target device search 361 + * @mrioc: Adapter instance reference 362 + * @sas_address: SAS address of the device 363 + * @hba_port: HBA port entry 364 + * 365 + * This searches for target device from sas address and hba port 366 + * pointer then return mpi3mr_tgt_dev object. 367 + * 368 + * Context: This function will acquire tgtdev_lock and will 369 + * release before returning the mpi3mr_tgt_dev object. 370 + * 371 + * Return: Valid tget_dev or NULL 372 + */ 373 + static struct mpi3mr_tgt_dev *mpi3mr_get_tgtdev_by_addr(struct mpi3mr_ioc *mrioc, 374 + u64 sas_address, struct mpi3mr_hba_port *hba_port) 375 + { 376 + struct mpi3mr_tgt_dev *tgtdev = NULL; 377 + unsigned long flags; 378 + 379 + if (!hba_port) 380 + goto out; 381 + 382 + spin_lock_irqsave(&mrioc->tgtdev_lock, flags); 383 + tgtdev = __mpi3mr_get_tgtdev_by_addr(mrioc, sas_address, hba_port); 384 + spin_unlock_irqrestore(&mrioc->tgtdev_lock, flags); 385 + 386 + out: 387 + return tgtdev; 388 + } 389 + 390 + /** 391 + * mpi3mr_remove_device_by_sas_address - remove the device 392 + * @mrioc: Adapter instance reference 393 + * @sas_address: SAS address of the device 394 + * @hba_port: HBA port entry 395 + * 396 + * This searches for target device using sas address and hba 397 + * port pointer then removes it from the OS. 398 + * 399 + * Return: None 400 + */ 401 + static void mpi3mr_remove_device_by_sas_address(struct mpi3mr_ioc *mrioc, 402 + u64 sas_address, struct mpi3mr_hba_port *hba_port) 403 + { 404 + struct mpi3mr_tgt_dev *tgtdev = NULL; 405 + unsigned long flags; 406 + u8 was_on_tgtdev_list = 0; 407 + 408 + if (!hba_port) 409 + return; 410 + 411 + spin_lock_irqsave(&mrioc->tgtdev_lock, flags); 412 + tgtdev = __mpi3mr_get_tgtdev_by_addr(mrioc, 413 + sas_address, hba_port); 414 + if (tgtdev) { 415 + if (!list_empty(&tgtdev->list)) { 416 + list_del_init(&tgtdev->list); 417 + was_on_tgtdev_list = 1; 418 + mpi3mr_tgtdev_put(tgtdev); 419 + } 420 + } 421 + spin_unlock_irqrestore(&mrioc->tgtdev_lock, flags); 422 + if (was_on_tgtdev_list) { 423 + if (tgtdev->host_exposed) 424 + mpi3mr_remove_tgtdev_from_host(mrioc, tgtdev); 425 + mpi3mr_tgtdev_put(tgtdev); 426 + } 427 + } 428 + 429 + /** 430 + * __mpi3mr_get_tgtdev_by_addr_and_rphy - target device search 431 + * @mrioc: Adapter instance reference 432 + * @sas_address: SAS address of the device 433 + * @rphy: SAS transport layer rphy object 434 + * 435 + * This searches for target device from sas address and rphy 436 + * pointer then return mpi3mr_tgt_dev object. 437 + * 438 + * Return: Valid tget_dev or NULL 439 + */ 440 + struct mpi3mr_tgt_dev *__mpi3mr_get_tgtdev_by_addr_and_rphy( 441 + struct mpi3mr_ioc *mrioc, u64 sas_address, struct sas_rphy *rphy) 442 + { 443 + struct mpi3mr_tgt_dev *tgtdev; 444 + 445 + assert_spin_locked(&mrioc->tgtdev_lock); 446 + 447 + list_for_each_entry(tgtdev, &mrioc->tgtdev_list, list) 448 + if ((tgtdev->dev_type == MPI3_DEVICE_DEVFORM_SAS_SATA) && 449 + (tgtdev->dev_spec.sas_sata_inf.sas_address == sas_address) 450 + && (tgtdev->dev_spec.sas_sata_inf.rphy == rphy)) 451 + goto found_device; 452 + return NULL; 453 + found_device: 454 + mpi3mr_tgtdev_get(tgtdev); 455 + return tgtdev; 456 + } 457 + 458 + /** 459 + * mpi3mr_expander_find_by_sas_address - sas expander search 460 + * @mrioc: Adapter instance reference 461 + * @sas_address: SAS address of expander 462 + * @hba_port: HBA port entry 463 + * 464 + * Return: A valid SAS expander node or NULL. 465 + * 466 + */ 467 + static struct mpi3mr_sas_node *mpi3mr_expander_find_by_sas_address( 468 + struct mpi3mr_ioc *mrioc, u64 sas_address, 469 + struct mpi3mr_hba_port *hba_port) 470 + { 471 + struct mpi3mr_sas_node *sas_expander, *r = NULL; 472 + 473 + if (!hba_port) 474 + goto out; 475 + 476 + list_for_each_entry(sas_expander, &mrioc->sas_expander_list, list) { 477 + if ((sas_expander->sas_address != sas_address) || 478 + (sas_expander->hba_port != hba_port)) 479 + continue; 480 + r = sas_expander; 481 + goto out; 482 + } 483 + out: 484 + return r; 485 + } 486 + 487 + /** 488 + * __mpi3mr_sas_node_find_by_sas_address - sas node search 489 + * @mrioc: Adapter instance reference 490 + * @sas_address: SAS address of expander or sas host 491 + * @hba_port: HBA port entry 492 + * Context: Caller should acquire mrioc->sas_node_lock. 493 + * 494 + * If the SAS address indicates the device is direct attached to 495 + * the controller (controller's SAS address) then the SAS node 496 + * associated with the controller is returned back else the SAS 497 + * address and hba port are used to identify the exact expander 498 + * and the associated sas_node object is returned. If there is 499 + * no match NULL is returned. 500 + * 501 + * Return: A valid SAS node or NULL. 502 + * 503 + */ 504 + static struct mpi3mr_sas_node *__mpi3mr_sas_node_find_by_sas_address( 505 + struct mpi3mr_ioc *mrioc, u64 sas_address, 506 + struct mpi3mr_hba_port *hba_port) 507 + { 508 + 509 + if (mrioc->sas_hba.sas_address == sas_address) 510 + return &mrioc->sas_hba; 511 + return mpi3mr_expander_find_by_sas_address(mrioc, sas_address, 512 + hba_port); 513 + } 514 + 515 + /** 516 + * mpi3mr_parent_present - Is parent present for a phy 517 + * @mrioc: Adapter instance reference 518 + * @phy: SAS transport layer phy object 519 + * 520 + * Return: 0 if parent is present else non-zero 521 + */ 522 + static int mpi3mr_parent_present(struct mpi3mr_ioc *mrioc, struct sas_phy *phy) 523 + { 524 + unsigned long flags; 525 + struct mpi3mr_hba_port *hba_port = phy->hostdata; 526 + 527 + spin_lock_irqsave(&mrioc->sas_node_lock, flags); 528 + if (__mpi3mr_sas_node_find_by_sas_address(mrioc, 529 + phy->identify.sas_address, 530 + hba_port) == NULL) { 531 + spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); 532 + return -1; 533 + } 534 + spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); 535 + return 0; 536 + } 537 + 538 + /** 539 + * mpi3mr_convert_phy_link_rate - 540 + * @link_rate: link rate as defined in the MPI header 541 + * 542 + * Convert link_rate from mpi format into sas_transport layer 543 + * form. 544 + * 545 + * Return: A valid SAS transport layer defined link rate 546 + */ 547 + static enum sas_linkrate mpi3mr_convert_phy_link_rate(u8 link_rate) 548 + { 549 + enum sas_linkrate rc; 550 + 551 + switch (link_rate) { 552 + case MPI3_SAS_NEG_LINK_RATE_1_5: 553 + rc = SAS_LINK_RATE_1_5_GBPS; 554 + break; 555 + case MPI3_SAS_NEG_LINK_RATE_3_0: 556 + rc = SAS_LINK_RATE_3_0_GBPS; 557 + break; 558 + case MPI3_SAS_NEG_LINK_RATE_6_0: 559 + rc = SAS_LINK_RATE_6_0_GBPS; 560 + break; 561 + case MPI3_SAS_NEG_LINK_RATE_12_0: 562 + rc = SAS_LINK_RATE_12_0_GBPS; 563 + break; 564 + case MPI3_SAS_NEG_LINK_RATE_22_5: 565 + rc = SAS_LINK_RATE_22_5_GBPS; 566 + break; 567 + case MPI3_SAS_NEG_LINK_RATE_PHY_DISABLED: 568 + rc = SAS_PHY_DISABLED; 569 + break; 570 + case MPI3_SAS_NEG_LINK_RATE_NEGOTIATION_FAILED: 571 + rc = SAS_LINK_RATE_FAILED; 572 + break; 573 + case MPI3_SAS_NEG_LINK_RATE_PORT_SELECTOR: 574 + rc = SAS_SATA_PORT_SELECTOR; 575 + break; 576 + case MPI3_SAS_NEG_LINK_RATE_SMP_RESET_IN_PROGRESS: 577 + rc = SAS_PHY_RESET_IN_PROGRESS; 578 + break; 579 + case MPI3_SAS_NEG_LINK_RATE_SATA_OOB_COMPLETE: 580 + case MPI3_SAS_NEG_LINK_RATE_UNKNOWN_LINK_RATE: 581 + default: 582 + rc = SAS_LINK_RATE_UNKNOWN; 583 + break; 584 + } 585 + return rc; 586 + } 587 + 588 + /** 589 + * mpi3mr_delete_sas_phy - Remove a single phy from port 590 + * @mrioc: Adapter instance reference 591 + * @mr_sas_port: Internal Port object 592 + * @mr_sas_phy: Internal Phy object 593 + * 594 + * Return: None. 595 + */ 596 + static void mpi3mr_delete_sas_phy(struct mpi3mr_ioc *mrioc, 597 + struct mpi3mr_sas_port *mr_sas_port, 598 + struct mpi3mr_sas_phy *mr_sas_phy) 599 + { 600 + u64 sas_address = mr_sas_port->remote_identify.sas_address; 601 + 602 + dev_info(&mr_sas_phy->phy->dev, 603 + "remove: sas_address(0x%016llx), phy(%d)\n", 604 + (unsigned long long) sas_address, mr_sas_phy->phy_id); 605 + 606 + list_del(&mr_sas_phy->port_siblings); 607 + mr_sas_port->num_phys--; 608 + mr_sas_port->phy_mask &= ~(1 << mr_sas_phy->phy_id); 609 + if (mr_sas_port->lowest_phy == mr_sas_phy->phy_id) 610 + mr_sas_port->lowest_phy = ffs(mr_sas_port->phy_mask) - 1; 611 + sas_port_delete_phy(mr_sas_port->port, mr_sas_phy->phy); 612 + mr_sas_phy->phy_belongs_to_port = 0; 613 + } 614 + 615 + /** 616 + * mpi3mr_add_sas_phy - Adding a single phy to a port 617 + * @mrioc: Adapter instance reference 618 + * @mr_sas_port: Internal Port object 619 + * @mr_sas_phy: Internal Phy object 620 + * 621 + * Return: None. 622 + */ 623 + static void mpi3mr_add_sas_phy(struct mpi3mr_ioc *mrioc, 624 + struct mpi3mr_sas_port *mr_sas_port, 625 + struct mpi3mr_sas_phy *mr_sas_phy) 626 + { 627 + u64 sas_address = mr_sas_port->remote_identify.sas_address; 628 + 629 + dev_info(&mr_sas_phy->phy->dev, 630 + "add: sas_address(0x%016llx), phy(%d)\n", (unsigned long long) 631 + sas_address, mr_sas_phy->phy_id); 632 + 633 + list_add_tail(&mr_sas_phy->port_siblings, &mr_sas_port->phy_list); 634 + mr_sas_port->num_phys++; 635 + mr_sas_port->phy_mask |= (1 << mr_sas_phy->phy_id); 636 + if (mr_sas_phy->phy_id < mr_sas_port->lowest_phy) 637 + mr_sas_port->lowest_phy = ffs(mr_sas_port->phy_mask) - 1; 638 + sas_port_add_phy(mr_sas_port->port, mr_sas_phy->phy); 639 + mr_sas_phy->phy_belongs_to_port = 1; 640 + } 641 + 642 + /** 643 + * mpi3mr_add_phy_to_an_existing_port - add phy to existing port 644 + * @mrioc: Adapter instance reference 645 + * @mr_sas_node: Internal sas node object (expander or host) 646 + * @mr_sas_phy: Internal Phy object * 647 + * @sas_address: SAS address of device/expander were phy needs 648 + * to be added to 649 + * @hba_port: HBA port entry 650 + * 651 + * Return: None. 652 + */ 653 + static void mpi3mr_add_phy_to_an_existing_port(struct mpi3mr_ioc *mrioc, 654 + struct mpi3mr_sas_node *mr_sas_node, struct mpi3mr_sas_phy *mr_sas_phy, 655 + u64 sas_address, struct mpi3mr_hba_port *hba_port) 656 + { 657 + struct mpi3mr_sas_port *mr_sas_port; 658 + struct mpi3mr_sas_phy *srch_phy; 659 + 660 + if (mr_sas_phy->phy_belongs_to_port == 1) 661 + return; 662 + 663 + if (!hba_port) 664 + return; 665 + 666 + list_for_each_entry(mr_sas_port, &mr_sas_node->sas_port_list, 667 + port_list) { 668 + if (mr_sas_port->remote_identify.sas_address != 669 + sas_address) 670 + continue; 671 + if (mr_sas_port->hba_port != hba_port) 672 + continue; 673 + list_for_each_entry(srch_phy, &mr_sas_port->phy_list, 674 + port_siblings) { 675 + if (srch_phy == mr_sas_phy) 676 + return; 677 + } 678 + mpi3mr_add_sas_phy(mrioc, mr_sas_port, mr_sas_phy); 679 + return; 680 + } 681 + } 682 + 683 + /** 684 + * mpi3mr_delete_sas_port - helper function to removing a port 685 + * @mrioc: Adapter instance reference 686 + * @mr_sas_port: Internal Port object 687 + * 688 + * Return: None. 689 + */ 690 + static void mpi3mr_delete_sas_port(struct mpi3mr_ioc *mrioc, 691 + struct mpi3mr_sas_port *mr_sas_port) 692 + { 693 + u64 sas_address = mr_sas_port->remote_identify.sas_address; 694 + struct mpi3mr_hba_port *hba_port = mr_sas_port->hba_port; 695 + enum sas_device_type device_type = 696 + mr_sas_port->remote_identify.device_type; 697 + 698 + dev_info(&mr_sas_port->port->dev, 699 + "remove: sas_address(0x%016llx)\n", 700 + (unsigned long long) sas_address); 701 + 702 + if (device_type == SAS_END_DEVICE) 703 + mpi3mr_remove_device_by_sas_address(mrioc, sas_address, 704 + hba_port); 705 + 706 + else if (device_type == SAS_EDGE_EXPANDER_DEVICE || 707 + device_type == SAS_FANOUT_EXPANDER_DEVICE) 708 + mpi3mr_expander_remove(mrioc, sas_address, hba_port); 709 + } 710 + 711 + /** 712 + * mpi3mr_del_phy_from_an_existing_port - del phy from a port 713 + * @mrioc: Adapter instance reference 714 + * @mr_sas_node: Internal sas node object (expander or host) 715 + * @mr_sas_phy: Internal Phy object 716 + * 717 + * Return: None. 718 + */ 719 + static void mpi3mr_del_phy_from_an_existing_port(struct mpi3mr_ioc *mrioc, 720 + struct mpi3mr_sas_node *mr_sas_node, struct mpi3mr_sas_phy *mr_sas_phy) 721 + { 722 + struct mpi3mr_sas_port *mr_sas_port, *next; 723 + struct mpi3mr_sas_phy *srch_phy; 724 + 725 + if (mr_sas_phy->phy_belongs_to_port == 0) 726 + return; 727 + 728 + list_for_each_entry_safe(mr_sas_port, next, &mr_sas_node->sas_port_list, 729 + port_list) { 730 + list_for_each_entry(srch_phy, &mr_sas_port->phy_list, 731 + port_siblings) { 732 + if (srch_phy != mr_sas_phy) 733 + continue; 734 + if ((mr_sas_port->num_phys == 1) && 735 + !mrioc->reset_in_progress) 736 + mpi3mr_delete_sas_port(mrioc, mr_sas_port); 737 + else 738 + mpi3mr_delete_sas_phy(mrioc, mr_sas_port, 739 + mr_sas_phy); 740 + return; 741 + } 742 + } 743 + } 744 + 745 + /** 746 + * mpi3mr_sas_port_sanity_check - sanity check while adding port 747 + * @mrioc: Adapter instance reference 748 + * @mr_sas_node: Internal sas node object (expander or host) 749 + * @sas_address: SAS address of device/expander 750 + * @hba_port: HBA port entry 751 + * 752 + * Verifies whether the Phys attached to a device with the given 753 + * SAS address already belongs to an existing sas port if so 754 + * will remove those phys from the sas port 755 + * 756 + * Return: None. 757 + */ 758 + static void mpi3mr_sas_port_sanity_check(struct mpi3mr_ioc *mrioc, 759 + struct mpi3mr_sas_node *mr_sas_node, u64 sas_address, 760 + struct mpi3mr_hba_port *hba_port) 761 + { 762 + int i; 763 + 764 + for (i = 0; i < mr_sas_node->num_phys; i++) { 765 + if ((mr_sas_node->phy[i].remote_identify.sas_address != 766 + sas_address) || (mr_sas_node->phy[i].hba_port != hba_port)) 767 + continue; 768 + if (mr_sas_node->phy[i].phy_belongs_to_port == 1) 769 + mpi3mr_del_phy_from_an_existing_port(mrioc, 770 + mr_sas_node, &mr_sas_node->phy[i]); 771 + } 772 + } 773 + 774 + /** 775 + * mpi3mr_set_identify - set identify for phys and end devices 776 + * @mrioc: Adapter instance reference 777 + * @handle: Firmware device handle 778 + * @identify: SAS transport layer's identify info 779 + * 780 + * Populates sas identify info for a specific device. 781 + * 782 + * Return: 0 for success, non-zero for failure. 783 + */ 784 + static int mpi3mr_set_identify(struct mpi3mr_ioc *mrioc, u16 handle, 785 + struct sas_identify *identify) 786 + { 787 + 788 + struct mpi3_device_page0 device_pg0; 789 + struct mpi3_device0_sas_sata_format *sasinf; 790 + u16 device_info; 791 + u16 ioc_status; 792 + 793 + if (mrioc->reset_in_progress) { 794 + ioc_err(mrioc, "%s: host reset in progress!\n", __func__); 795 + return -EFAULT; 796 + } 797 + 798 + if ((mpi3mr_cfg_get_dev_pg0(mrioc, &ioc_status, &device_pg0, 799 + sizeof(device_pg0), MPI3_DEVICE_PGAD_FORM_HANDLE, handle))) { 800 + ioc_err(mrioc, "%s: device page0 read failed\n", __func__); 801 + return -ENXIO; 802 + } 803 + 804 + if (ioc_status != MPI3_IOCSTATUS_SUCCESS) { 805 + ioc_err(mrioc, "device page read failed for handle(0x%04x), with ioc_status(0x%04x) failure at %s:%d/%s()!\n", 806 + handle, ioc_status, __FILE__, __LINE__, __func__); 807 + return -EIO; 808 + } 809 + 810 + memset(identify, 0, sizeof(struct sas_identify)); 811 + sasinf = &device_pg0.device_specific.sas_sata_format; 812 + device_info = le16_to_cpu(sasinf->device_info); 813 + 814 + /* sas_address */ 815 + identify->sas_address = le64_to_cpu(sasinf->sas_address); 816 + 817 + /* phy number of the parent device this device is linked to */ 818 + identify->phy_identifier = sasinf->phy_num; 819 + 820 + /* device_type */ 821 + switch (device_info & MPI3_SAS_DEVICE_INFO_DEVICE_TYPE_MASK) { 822 + case MPI3_SAS_DEVICE_INFO_DEVICE_TYPE_NO_DEVICE: 823 + identify->device_type = SAS_PHY_UNUSED; 824 + break; 825 + case MPI3_SAS_DEVICE_INFO_DEVICE_TYPE_END_DEVICE: 826 + identify->device_type = SAS_END_DEVICE; 827 + break; 828 + case MPI3_SAS_DEVICE_INFO_DEVICE_TYPE_EXPANDER: 829 + identify->device_type = SAS_EDGE_EXPANDER_DEVICE; 830 + break; 831 + } 832 + 833 + /* initiator_port_protocols */ 834 + if (device_info & MPI3_SAS_DEVICE_INFO_SSP_INITIATOR) 835 + identify->initiator_port_protocols |= SAS_PROTOCOL_SSP; 836 + /* MPI3.0 doesn't have define for SATA INIT so setting both here*/ 837 + if (device_info & MPI3_SAS_DEVICE_INFO_STP_INITIATOR) 838 + identify->initiator_port_protocols |= (SAS_PROTOCOL_STP | 839 + SAS_PROTOCOL_SATA); 840 + if (device_info & MPI3_SAS_DEVICE_INFO_SMP_INITIATOR) 841 + identify->initiator_port_protocols |= SAS_PROTOCOL_SMP; 842 + 843 + /* target_port_protocols */ 844 + if (device_info & MPI3_SAS_DEVICE_INFO_SSP_TARGET) 845 + identify->target_port_protocols |= SAS_PROTOCOL_SSP; 846 + /* MPI3.0 doesn't have define for STP Target so setting both here*/ 847 + if (device_info & MPI3_SAS_DEVICE_INFO_STP_SATA_TARGET) 848 + identify->target_port_protocols |= (SAS_PROTOCOL_STP | 849 + SAS_PROTOCOL_SATA); 850 + if (device_info & MPI3_SAS_DEVICE_INFO_SMP_TARGET) 851 + identify->target_port_protocols |= SAS_PROTOCOL_SMP; 852 + return 0; 853 + } 854 + 855 + /** 856 + * mpi3mr_add_host_phy - report sas_host phy to SAS transport 857 + * @mrioc: Adapter instance reference 858 + * @mr_sas_phy: Internal Phy object 859 + * @phy_pg0: SAS phy page 0 860 + * @parent_dev: Prent device class object 861 + * 862 + * Return: 0 for success, non-zero for failure. 863 + */ 864 + static int mpi3mr_add_host_phy(struct mpi3mr_ioc *mrioc, 865 + struct mpi3mr_sas_phy *mr_sas_phy, struct mpi3_sas_phy_page0 phy_pg0, 866 + struct device *parent_dev) 867 + { 868 + struct sas_phy *phy; 869 + int phy_index = mr_sas_phy->phy_id; 870 + 871 + 872 + INIT_LIST_HEAD(&mr_sas_phy->port_siblings); 873 + phy = sas_phy_alloc(parent_dev, phy_index); 874 + if (!phy) { 875 + ioc_err(mrioc, "failure at %s:%d/%s()!\n", 876 + __FILE__, __LINE__, __func__); 877 + return -1; 878 + } 879 + if ((mpi3mr_set_identify(mrioc, mr_sas_phy->handle, 880 + &mr_sas_phy->identify))) { 881 + ioc_err(mrioc, "failure at %s:%d/%s()!\n", 882 + __FILE__, __LINE__, __func__); 883 + sas_phy_free(phy); 884 + return -1; 885 + } 886 + phy->identify = mr_sas_phy->identify; 887 + mr_sas_phy->attached_handle = le16_to_cpu(phy_pg0.attached_dev_handle); 888 + if (mr_sas_phy->attached_handle) 889 + mpi3mr_set_identify(mrioc, mr_sas_phy->attached_handle, 890 + &mr_sas_phy->remote_identify); 891 + phy->identify.phy_identifier = mr_sas_phy->phy_id; 892 + phy->negotiated_linkrate = mpi3mr_convert_phy_link_rate( 893 + (phy_pg0.negotiated_link_rate & 894 + MPI3_SAS_NEG_LINK_RATE_LOGICAL_MASK) >> 895 + MPI3_SAS_NEG_LINK_RATE_LOGICAL_SHIFT); 896 + phy->minimum_linkrate_hw = mpi3mr_convert_phy_link_rate( 897 + phy_pg0.hw_link_rate & MPI3_SAS_HWRATE_MIN_RATE_MASK); 898 + phy->maximum_linkrate_hw = mpi3mr_convert_phy_link_rate( 899 + phy_pg0.hw_link_rate >> 4); 900 + phy->minimum_linkrate = mpi3mr_convert_phy_link_rate( 901 + phy_pg0.programmed_link_rate & MPI3_SAS_PRATE_MIN_RATE_MASK); 902 + phy->maximum_linkrate = mpi3mr_convert_phy_link_rate( 903 + phy_pg0.programmed_link_rate >> 4); 904 + phy->hostdata = mr_sas_phy->hba_port; 905 + 906 + if ((sas_phy_add(phy))) { 907 + ioc_err(mrioc, "failure at %s:%d/%s()!\n", 908 + __FILE__, __LINE__, __func__); 909 + sas_phy_free(phy); 910 + return -1; 911 + } 912 + if ((mrioc->logging_level & MPI3_DEBUG_TRANSPORT_INFO)) 913 + dev_info(&phy->dev, 914 + "add: handle(0x%04x), sas_address(0x%016llx)\n" 915 + "\tattached_handle(0x%04x), sas_address(0x%016llx)\n", 916 + mr_sas_phy->handle, (unsigned long long) 917 + mr_sas_phy->identify.sas_address, 918 + mr_sas_phy->attached_handle, 919 + (unsigned long long) 920 + mr_sas_phy->remote_identify.sas_address); 921 + mr_sas_phy->phy = phy; 922 + return 0; 923 + } 924 + 925 + /** 926 + * mpi3mr_add_expander_phy - report expander phy to transport 927 + * @mrioc: Adapter instance reference 928 + * @mr_sas_phy: Internal Phy object 929 + * @expander_pg1: SAS Expander page 1 930 + * @parent_dev: Parent device class object 931 + * 932 + * Return: 0 for success, non-zero for failure. 933 + */ 934 + static int mpi3mr_add_expander_phy(struct mpi3mr_ioc *mrioc, 935 + struct mpi3mr_sas_phy *mr_sas_phy, 936 + struct mpi3_sas_expander_page1 expander_pg1, 937 + struct device *parent_dev) 938 + { 939 + struct sas_phy *phy; 940 + int phy_index = mr_sas_phy->phy_id; 941 + 942 + INIT_LIST_HEAD(&mr_sas_phy->port_siblings); 943 + phy = sas_phy_alloc(parent_dev, phy_index); 944 + if (!phy) { 945 + ioc_err(mrioc, "failure at %s:%d/%s()!\n", 946 + __FILE__, __LINE__, __func__); 947 + return -1; 948 + } 949 + if ((mpi3mr_set_identify(mrioc, mr_sas_phy->handle, 950 + &mr_sas_phy->identify))) { 951 + ioc_err(mrioc, "failure at %s:%d/%s()!\n", 952 + __FILE__, __LINE__, __func__); 953 + sas_phy_free(phy); 954 + return -1; 955 + } 956 + phy->identify = mr_sas_phy->identify; 957 + mr_sas_phy->attached_handle = 958 + le16_to_cpu(expander_pg1.attached_dev_handle); 959 + if (mr_sas_phy->attached_handle) 960 + mpi3mr_set_identify(mrioc, mr_sas_phy->attached_handle, 961 + &mr_sas_phy->remote_identify); 962 + phy->identify.phy_identifier = mr_sas_phy->phy_id; 963 + phy->negotiated_linkrate = mpi3mr_convert_phy_link_rate( 964 + (expander_pg1.negotiated_link_rate & 965 + MPI3_SAS_NEG_LINK_RATE_LOGICAL_MASK) >> 966 + MPI3_SAS_NEG_LINK_RATE_LOGICAL_SHIFT); 967 + phy->minimum_linkrate_hw = mpi3mr_convert_phy_link_rate( 968 + expander_pg1.hw_link_rate & MPI3_SAS_HWRATE_MIN_RATE_MASK); 969 + phy->maximum_linkrate_hw = mpi3mr_convert_phy_link_rate( 970 + expander_pg1.hw_link_rate >> 4); 971 + phy->minimum_linkrate = mpi3mr_convert_phy_link_rate( 972 + expander_pg1.programmed_link_rate & MPI3_SAS_PRATE_MIN_RATE_MASK); 973 + phy->maximum_linkrate = mpi3mr_convert_phy_link_rate( 974 + expander_pg1.programmed_link_rate >> 4); 975 + phy->hostdata = mr_sas_phy->hba_port; 976 + 977 + if ((sas_phy_add(phy))) { 978 + ioc_err(mrioc, "failure at %s:%d/%s()!\n", 979 + __FILE__, __LINE__, __func__); 980 + sas_phy_free(phy); 981 + return -1; 982 + } 983 + if ((mrioc->logging_level & MPI3_DEBUG_TRANSPORT_INFO)) 984 + dev_info(&phy->dev, 985 + "add: handle(0x%04x), sas_address(0x%016llx)\n" 986 + "\tattached_handle(0x%04x), sas_address(0x%016llx)\n", 987 + mr_sas_phy->handle, (unsigned long long) 988 + mr_sas_phy->identify.sas_address, 989 + mr_sas_phy->attached_handle, 990 + (unsigned long long) 991 + mr_sas_phy->remote_identify.sas_address); 992 + mr_sas_phy->phy = phy; 993 + return 0; 994 + } 995 + 996 + /** 997 + * mpi3mr_alloc_hba_port - alloc hba port object 998 + * @mrioc: Adapter instance reference 999 + * @port_id: Port number 1000 + * 1001 + * Alloc memory for hba port object. 1002 + */ 1003 + static struct mpi3mr_hba_port * 1004 + mpi3mr_alloc_hba_port(struct mpi3mr_ioc *mrioc, u16 port_id) 1005 + { 1006 + struct mpi3mr_hba_port *hba_port; 1007 + 1008 + hba_port = kzalloc(sizeof(struct mpi3mr_hba_port), 1009 + GFP_KERNEL); 1010 + if (!hba_port) 1011 + return NULL; 1012 + hba_port->port_id = port_id; 1013 + ioc_info(mrioc, "hba_port entry: %p, port: %d is added to hba_port list\n", 1014 + hba_port, hba_port->port_id); 1015 + list_add_tail(&hba_port->list, &mrioc->hba_port_table_list); 1016 + return hba_port; 1017 + } 1018 + 1019 + /** 1020 + * mpi3mr_get_hba_port_by_id - find hba port by id 1021 + * @mrioc: Adapter instance reference 1022 + * @port_id - Port ID to search 1023 + * 1024 + * Return: mpi3mr_hba_port reference for the matched port 1025 + */ 1026 + 1027 + struct mpi3mr_hba_port *mpi3mr_get_hba_port_by_id(struct mpi3mr_ioc *mrioc, 1028 + u8 port_id) 1029 + { 1030 + struct mpi3mr_hba_port *port, *port_next; 1031 + 1032 + list_for_each_entry_safe(port, port_next, 1033 + &mrioc->hba_port_table_list, list) { 1034 + if (port->port_id != port_id) 1035 + continue; 1036 + if (port->flags & MPI3MR_HBA_PORT_FLAG_DIRTY) 1037 + continue; 1038 + return port; 1039 + } 1040 + 1041 + return NULL; 1042 + } 1043 + 1044 + /** 1045 + * mpi3mr_update_links - refreshing SAS phy link changes 1046 + * @mrioc: Adapter instance reference 1047 + * @sas_address_parent: SAS address of parent expander or host 1048 + * @handle: Firmware device handle of attached device 1049 + * @phy_number: Phy number 1050 + * @link_rate: New link rate 1051 + * @hba_port: HBA port entry 1052 + * 1053 + * Return: None. 1054 + */ 1055 + void mpi3mr_update_links(struct mpi3mr_ioc *mrioc, 1056 + u64 sas_address_parent, u16 handle, u8 phy_number, u8 link_rate, 1057 + struct mpi3mr_hba_port *hba_port) 1058 + { 1059 + unsigned long flags; 1060 + struct mpi3mr_sas_node *mr_sas_node; 1061 + struct mpi3mr_sas_phy *mr_sas_phy; 1062 + 1063 + if (mrioc->reset_in_progress) 1064 + return; 1065 + 1066 + spin_lock_irqsave(&mrioc->sas_node_lock, flags); 1067 + mr_sas_node = __mpi3mr_sas_node_find_by_sas_address(mrioc, 1068 + sas_address_parent, hba_port); 1069 + if (!mr_sas_node) { 1070 + spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); 1071 + return; 1072 + } 1073 + 1074 + mr_sas_phy = &mr_sas_node->phy[phy_number]; 1075 + mr_sas_phy->attached_handle = handle; 1076 + spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); 1077 + if (handle && (link_rate >= MPI3_SAS_NEG_LINK_RATE_1_5)) { 1078 + mpi3mr_set_identify(mrioc, handle, 1079 + &mr_sas_phy->remote_identify); 1080 + mpi3mr_add_phy_to_an_existing_port(mrioc, mr_sas_node, 1081 + mr_sas_phy, mr_sas_phy->remote_identify.sas_address, 1082 + hba_port); 1083 + } else 1084 + memset(&mr_sas_phy->remote_identify, 0, sizeof(struct 1085 + sas_identify)); 1086 + 1087 + if (mr_sas_phy->phy) 1088 + mr_sas_phy->phy->negotiated_linkrate = 1089 + mpi3mr_convert_phy_link_rate(link_rate); 1090 + 1091 + if ((mrioc->logging_level & MPI3_DEBUG_TRANSPORT_INFO)) 1092 + dev_info(&mr_sas_phy->phy->dev, 1093 + "refresh: parent sas_address(0x%016llx),\n" 1094 + "\tlink_rate(0x%02x), phy(%d)\n" 1095 + "\tattached_handle(0x%04x), sas_address(0x%016llx)\n", 1096 + (unsigned long long)sas_address_parent, 1097 + link_rate, phy_number, handle, (unsigned long long) 1098 + mr_sas_phy->remote_identify.sas_address); 1099 + } 1100 + 1101 + /** 1102 + * mpi3mr_sas_host_refresh - refreshing sas host object contents 1103 + * @mrioc: Adapter instance reference 1104 + * 1105 + * This function refreshes the controllers phy information and 1106 + * updates the SAS transport layer with updated information, 1107 + * this is executed for each device addition or device info 1108 + * change events 1109 + * 1110 + * Return: None. 1111 + */ 1112 + void mpi3mr_sas_host_refresh(struct mpi3mr_ioc *mrioc) 1113 + { 1114 + int i; 1115 + u8 link_rate; 1116 + u16 sz, port_id, attached_handle; 1117 + struct mpi3_sas_io_unit_page0 *sas_io_unit_pg0 = NULL; 1118 + 1119 + dprint_transport_info(mrioc, 1120 + "updating handles for sas_host(0x%016llx)\n", 1121 + (unsigned long long)mrioc->sas_hba.sas_address); 1122 + 1123 + sz = offsetof(struct mpi3_sas_io_unit_page0, phy_data) + 1124 + (mrioc->sas_hba.num_phys * 1125 + sizeof(struct mpi3_sas_io_unit0_phy_data)); 1126 + sas_io_unit_pg0 = kzalloc(sz, GFP_KERNEL); 1127 + if (!sas_io_unit_pg0) 1128 + return; 1129 + if (mpi3mr_cfg_get_sas_io_unit_pg0(mrioc, sas_io_unit_pg0, sz)) { 1130 + ioc_err(mrioc, "failure at %s:%d/%s()!\n", 1131 + __FILE__, __LINE__, __func__); 1132 + goto out; 1133 + } 1134 + 1135 + mrioc->sas_hba.handle = 0; 1136 + for (i = 0; i < mrioc->sas_hba.num_phys; i++) { 1137 + if (sas_io_unit_pg0->phy_data[i].phy_flags & 1138 + (MPI3_SASIOUNIT0_PHYFLAGS_HOST_PHY | 1139 + MPI3_SASIOUNIT0_PHYFLAGS_VIRTUAL_PHY)) 1140 + continue; 1141 + link_rate = 1142 + sas_io_unit_pg0->phy_data[i].negotiated_link_rate >> 4; 1143 + if (!mrioc->sas_hba.handle) 1144 + mrioc->sas_hba.handle = le16_to_cpu( 1145 + sas_io_unit_pg0->phy_data[i].controller_dev_handle); 1146 + port_id = sas_io_unit_pg0->phy_data[i].io_unit_port; 1147 + if (!(mpi3mr_get_hba_port_by_id(mrioc, port_id))) 1148 + if (!mpi3mr_alloc_hba_port(mrioc, port_id)) 1149 + goto out; 1150 + 1151 + mrioc->sas_hba.phy[i].handle = mrioc->sas_hba.handle; 1152 + attached_handle = le16_to_cpu( 1153 + sas_io_unit_pg0->phy_data[i].attached_dev_handle); 1154 + if (attached_handle && link_rate < MPI3_SAS_NEG_LINK_RATE_1_5) 1155 + link_rate = MPI3_SAS_NEG_LINK_RATE_1_5; 1156 + mrioc->sas_hba.phy[i].hba_port = 1157 + mpi3mr_get_hba_port_by_id(mrioc, port_id); 1158 + mpi3mr_update_links(mrioc, mrioc->sas_hba.sas_address, 1159 + attached_handle, i, link_rate, 1160 + mrioc->sas_hba.phy[i].hba_port); 1161 + } 1162 + out: 1163 + kfree(sas_io_unit_pg0); 1164 + } 1165 + 1166 + /** 1167 + * mpi3mr_sas_host_add - create sas host object 1168 + * @mrioc: Adapter instance reference 1169 + * 1170 + * This function creates the controllers phy information and 1171 + * updates the SAS transport layer with updated information, 1172 + * this is executed for first device addition or device info 1173 + * change event. 1174 + * 1175 + * Return: None. 1176 + */ 1177 + void mpi3mr_sas_host_add(struct mpi3mr_ioc *mrioc) 1178 + { 1179 + int i; 1180 + u16 sz, num_phys = 1, port_id, ioc_status; 1181 + struct mpi3_sas_io_unit_page0 *sas_io_unit_pg0 = NULL; 1182 + struct mpi3_sas_phy_page0 phy_pg0; 1183 + struct mpi3_device_page0 dev_pg0; 1184 + struct mpi3_enclosure_page0 encl_pg0; 1185 + struct mpi3_device0_sas_sata_format *sasinf; 1186 + 1187 + sz = offsetof(struct mpi3_sas_io_unit_page0, phy_data) + 1188 + (num_phys * sizeof(struct mpi3_sas_io_unit0_phy_data)); 1189 + sas_io_unit_pg0 = kzalloc(sz, GFP_KERNEL); 1190 + if (!sas_io_unit_pg0) 1191 + return; 1192 + 1193 + if (mpi3mr_cfg_get_sas_io_unit_pg0(mrioc, sas_io_unit_pg0, sz)) { 1194 + ioc_err(mrioc, "failure at %s:%d/%s()!\n", 1195 + __FILE__, __LINE__, __func__); 1196 + goto out; 1197 + } 1198 + num_phys = sas_io_unit_pg0->num_phys; 1199 + kfree(sas_io_unit_pg0); 1200 + 1201 + mrioc->sas_hba.host_node = 1; 1202 + INIT_LIST_HEAD(&mrioc->sas_hba.sas_port_list); 1203 + mrioc->sas_hba.parent_dev = &mrioc->shost->shost_gendev; 1204 + mrioc->sas_hba.phy = kcalloc(num_phys, 1205 + sizeof(struct mpi3mr_sas_phy), GFP_KERNEL); 1206 + if (!mrioc->sas_hba.phy) 1207 + return; 1208 + 1209 + mrioc->sas_hba.num_phys = num_phys; 1210 + 1211 + sz = offsetof(struct mpi3_sas_io_unit_page0, phy_data) + 1212 + (num_phys * sizeof(struct mpi3_sas_io_unit0_phy_data)); 1213 + sas_io_unit_pg0 = kzalloc(sz, GFP_KERNEL); 1214 + if (!sas_io_unit_pg0) 1215 + return; 1216 + 1217 + if (mpi3mr_cfg_get_sas_io_unit_pg0(mrioc, sas_io_unit_pg0, sz)) { 1218 + ioc_err(mrioc, "failure at %s:%d/%s()!\n", 1219 + __FILE__, __LINE__, __func__); 1220 + goto out; 1221 + } 1222 + 1223 + mrioc->sas_hba.handle = 0; 1224 + for (i = 0; i < mrioc->sas_hba.num_phys; i++) { 1225 + if (sas_io_unit_pg0->phy_data[i].phy_flags & 1226 + (MPI3_SASIOUNIT0_PHYFLAGS_HOST_PHY | 1227 + MPI3_SASIOUNIT0_PHYFLAGS_VIRTUAL_PHY)) 1228 + continue; 1229 + if (mpi3mr_cfg_get_sas_phy_pg0(mrioc, &ioc_status, &phy_pg0, 1230 + sizeof(struct mpi3_sas_phy_page0), 1231 + MPI3_SAS_PHY_PGAD_FORM_PHY_NUMBER, i)) { 1232 + ioc_err(mrioc, "failure at %s:%d/%s()!\n", 1233 + __FILE__, __LINE__, __func__); 1234 + goto out; 1235 + } 1236 + if (ioc_status != MPI3_IOCSTATUS_SUCCESS) { 1237 + ioc_err(mrioc, "failure at %s:%d/%s()!\n", 1238 + __FILE__, __LINE__, __func__); 1239 + goto out; 1240 + } 1241 + 1242 + if (!mrioc->sas_hba.handle) 1243 + mrioc->sas_hba.handle = le16_to_cpu( 1244 + sas_io_unit_pg0->phy_data[i].controller_dev_handle); 1245 + port_id = sas_io_unit_pg0->phy_data[i].io_unit_port; 1246 + 1247 + if (!(mpi3mr_get_hba_port_by_id(mrioc, port_id))) 1248 + if (!mpi3mr_alloc_hba_port(mrioc, port_id)) 1249 + goto out; 1250 + 1251 + mrioc->sas_hba.phy[i].handle = mrioc->sas_hba.handle; 1252 + mrioc->sas_hba.phy[i].phy_id = i; 1253 + mrioc->sas_hba.phy[i].hba_port = 1254 + mpi3mr_get_hba_port_by_id(mrioc, port_id); 1255 + mpi3mr_add_host_phy(mrioc, &mrioc->sas_hba.phy[i], 1256 + phy_pg0, mrioc->sas_hba.parent_dev); 1257 + } 1258 + if ((mpi3mr_cfg_get_dev_pg0(mrioc, &ioc_status, &dev_pg0, 1259 + sizeof(dev_pg0), MPI3_DEVICE_PGAD_FORM_HANDLE, 1260 + mrioc->sas_hba.handle))) { 1261 + ioc_err(mrioc, "%s: device page0 read failed\n", __func__); 1262 + goto out; 1263 + } 1264 + if (ioc_status != MPI3_IOCSTATUS_SUCCESS) { 1265 + ioc_err(mrioc, "device page read failed for handle(0x%04x), with ioc_status(0x%04x) failure at %s:%d/%s()!\n", 1266 + mrioc->sas_hba.handle, ioc_status, __FILE__, __LINE__, 1267 + __func__); 1268 + goto out; 1269 + } 1270 + mrioc->sas_hba.enclosure_handle = 1271 + le16_to_cpu(dev_pg0.enclosure_handle); 1272 + sasinf = &dev_pg0.device_specific.sas_sata_format; 1273 + mrioc->sas_hba.sas_address = 1274 + le64_to_cpu(sasinf->sas_address); 1275 + ioc_info(mrioc, 1276 + "host_add: handle(0x%04x), sas_addr(0x%016llx), phys(%d)\n", 1277 + mrioc->sas_hba.handle, 1278 + (unsigned long long) mrioc->sas_hba.sas_address, 1279 + mrioc->sas_hba.num_phys); 1280 + 1281 + if (mrioc->sas_hba.enclosure_handle) { 1282 + if (!(mpi3mr_cfg_get_enclosure_pg0(mrioc, &ioc_status, 1283 + &encl_pg0, sizeof(dev_pg0), 1284 + MPI3_ENCLOS_PGAD_FORM_HANDLE, 1285 + mrioc->sas_hba.enclosure_handle)) && 1286 + (ioc_status == MPI3_IOCSTATUS_SUCCESS)) 1287 + mrioc->sas_hba.enclosure_logical_id = 1288 + le64_to_cpu(encl_pg0.enclosure_logical_id); 1289 + } 1290 + 1291 + out: 1292 + kfree(sas_io_unit_pg0); 1293 + } 1294 + 1295 + /** 1296 + * mpi3mr_sas_port_add - Expose the SAS device to the SAS TL 1297 + * @mrioc: Adapter instance reference 1298 + * @handle: Firmware device handle of the attached device 1299 + * @sas_address_parent: sas address of parent expander or host 1300 + * @hba_port: HBA port entry 1301 + * 1302 + * This function creates a new sas port object for the given end 1303 + * device matching sas address and hba_port and adds it to the 1304 + * sas_node's sas_port_list and expose the attached sas device 1305 + * to the SAS transport layer through sas_rphy_add. 1306 + * 1307 + * Returns a valid mpi3mr_sas_port reference or NULL. 1308 + */ 1309 + static struct mpi3mr_sas_port *mpi3mr_sas_port_add(struct mpi3mr_ioc *mrioc, 1310 + u16 handle, u64 sas_address_parent, struct mpi3mr_hba_port *hba_port) 1311 + { 1312 + struct mpi3mr_sas_phy *mr_sas_phy, *next; 1313 + struct mpi3mr_sas_port *mr_sas_port; 1314 + unsigned long flags; 1315 + struct mpi3mr_sas_node *mr_sas_node; 1316 + struct sas_rphy *rphy; 1317 + struct mpi3mr_tgt_dev *tgtdev = NULL; 1318 + int i; 1319 + struct sas_port *port; 1320 + 1321 + if (!hba_port) { 1322 + ioc_err(mrioc, "failure at %s:%d/%s()!\n", 1323 + __FILE__, __LINE__, __func__); 1324 + return NULL; 1325 + } 1326 + 1327 + mr_sas_port = kzalloc(sizeof(struct mpi3mr_sas_port), GFP_KERNEL); 1328 + if (!mr_sas_port) 1329 + return NULL; 1330 + 1331 + INIT_LIST_HEAD(&mr_sas_port->port_list); 1332 + INIT_LIST_HEAD(&mr_sas_port->phy_list); 1333 + spin_lock_irqsave(&mrioc->sas_node_lock, flags); 1334 + mr_sas_node = __mpi3mr_sas_node_find_by_sas_address(mrioc, 1335 + sas_address_parent, hba_port); 1336 + spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); 1337 + 1338 + if (!mr_sas_node) { 1339 + ioc_err(mrioc, "%s:could not find parent sas_address(0x%016llx)!\n", 1340 + __func__, (unsigned long long)sas_address_parent); 1341 + goto out_fail; 1342 + } 1343 + 1344 + if ((mpi3mr_set_identify(mrioc, handle, 1345 + &mr_sas_port->remote_identify))) { 1346 + ioc_err(mrioc, "failure at %s:%d/%s()!\n", 1347 + __FILE__, __LINE__, __func__); 1348 + goto out_fail; 1349 + } 1350 + 1351 + if (mr_sas_port->remote_identify.device_type == SAS_PHY_UNUSED) { 1352 + ioc_err(mrioc, "failure at %s:%d/%s()!\n", 1353 + __FILE__, __LINE__, __func__); 1354 + goto out_fail; 1355 + } 1356 + 1357 + mr_sas_port->hba_port = hba_port; 1358 + mpi3mr_sas_port_sanity_check(mrioc, mr_sas_node, 1359 + mr_sas_port->remote_identify.sas_address, hba_port); 1360 + 1361 + for (i = 0; i < mr_sas_node->num_phys; i++) { 1362 + if ((mr_sas_node->phy[i].remote_identify.sas_address != 1363 + mr_sas_port->remote_identify.sas_address) || 1364 + (mr_sas_node->phy[i].hba_port != hba_port)) 1365 + continue; 1366 + list_add_tail(&mr_sas_node->phy[i].port_siblings, 1367 + &mr_sas_port->phy_list); 1368 + mr_sas_port->num_phys++; 1369 + mr_sas_port->phy_mask |= (1 << i); 1370 + } 1371 + 1372 + if (!mr_sas_port->num_phys) { 1373 + ioc_err(mrioc, "failure at %s:%d/%s()!\n", 1374 + __FILE__, __LINE__, __func__); 1375 + goto out_fail; 1376 + } 1377 + 1378 + mr_sas_port->lowest_phy = ffs(mr_sas_port->phy_mask) - 1; 1379 + 1380 + if (mr_sas_port->remote_identify.device_type == SAS_END_DEVICE) { 1381 + tgtdev = mpi3mr_get_tgtdev_by_addr(mrioc, 1382 + mr_sas_port->remote_identify.sas_address, 1383 + mr_sas_port->hba_port); 1384 + 1385 + if (!tgtdev) { 1386 + ioc_err(mrioc, "failure at %s:%d/%s()!\n", 1387 + __FILE__, __LINE__, __func__); 1388 + goto out_fail; 1389 + } 1390 + tgtdev->dev_spec.sas_sata_inf.pend_sas_rphy_add = 1; 1391 + } 1392 + 1393 + if (!mr_sas_node->parent_dev) { 1394 + ioc_err(mrioc, "failure at %s:%d/%s()!\n", 1395 + __FILE__, __LINE__, __func__); 1396 + goto out_fail; 1397 + } 1398 + 1399 + port = sas_port_alloc_num(mr_sas_node->parent_dev); 1400 + if ((sas_port_add(port))) { 1401 + ioc_err(mrioc, "failure at %s:%d/%s()!\n", 1402 + __FILE__, __LINE__, __func__); 1403 + goto out_fail; 1404 + } 1405 + 1406 + list_for_each_entry(mr_sas_phy, &mr_sas_port->phy_list, 1407 + port_siblings) { 1408 + if ((mrioc->logging_level & MPI3_DEBUG_TRANSPORT_INFO)) 1409 + dev_info(&port->dev, 1410 + "add: handle(0x%04x), sas_address(0x%016llx), phy(%d)\n", 1411 + handle, (unsigned long long) 1412 + mr_sas_port->remote_identify.sas_address, 1413 + mr_sas_phy->phy_id); 1414 + sas_port_add_phy(port, mr_sas_phy->phy); 1415 + mr_sas_phy->phy_belongs_to_port = 1; 1416 + mr_sas_phy->hba_port = hba_port; 1417 + } 1418 + 1419 + mr_sas_port->port = port; 1420 + if (mr_sas_port->remote_identify.device_type == SAS_END_DEVICE) { 1421 + rphy = sas_end_device_alloc(port); 1422 + tgtdev->dev_spec.sas_sata_inf.rphy = rphy; 1423 + } else { 1424 + rphy = sas_expander_alloc(port, 1425 + mr_sas_port->remote_identify.device_type); 1426 + } 1427 + rphy->identify = mr_sas_port->remote_identify; 1428 + 1429 + if (mrioc->current_event) 1430 + mrioc->current_event->pending_at_sml = 1; 1431 + 1432 + if ((sas_rphy_add(rphy))) { 1433 + ioc_err(mrioc, "failure at %s:%d/%s()!\n", 1434 + __FILE__, __LINE__, __func__); 1435 + } 1436 + if (mr_sas_port->remote_identify.device_type == SAS_END_DEVICE) { 1437 + tgtdev->dev_spec.sas_sata_inf.pend_sas_rphy_add = 0; 1438 + tgtdev->dev_spec.sas_sata_inf.sas_transport_attached = 1; 1439 + mpi3mr_tgtdev_put(tgtdev); 1440 + } 1441 + 1442 + dev_info(&rphy->dev, 1443 + "%s: added: handle(0x%04x), sas_address(0x%016llx)\n", 1444 + __func__, handle, (unsigned long long) 1445 + mr_sas_port->remote_identify.sas_address); 1446 + 1447 + mr_sas_port->rphy = rphy; 1448 + spin_lock_irqsave(&mrioc->sas_node_lock, flags); 1449 + list_add_tail(&mr_sas_port->port_list, &mr_sas_node->sas_port_list); 1450 + spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); 1451 + 1452 + if (mrioc->current_event) { 1453 + mrioc->current_event->pending_at_sml = 0; 1454 + if (mrioc->current_event->discard) 1455 + mpi3mr_print_device_event_notice(mrioc, true); 1456 + } 1457 + 1458 + /* fill in report manufacture */ 1459 + if (mr_sas_port->remote_identify.device_type == 1460 + SAS_EDGE_EXPANDER_DEVICE || 1461 + mr_sas_port->remote_identify.device_type == 1462 + SAS_FANOUT_EXPANDER_DEVICE) 1463 + mpi3mr_report_manufacture(mrioc, 1464 + mr_sas_port->remote_identify.sas_address, 1465 + rphy_to_expander_device(rphy), hba_port->port_id); 1466 + 1467 + return mr_sas_port; 1468 + 1469 + out_fail: 1470 + list_for_each_entry_safe(mr_sas_phy, next, &mr_sas_port->phy_list, 1471 + port_siblings) 1472 + list_del(&mr_sas_phy->port_siblings); 1473 + kfree(mr_sas_port); 1474 + return NULL; 1475 + } 1476 + 1477 + /** 1478 + * mpi3mr_sas_port_remove - remove port from the list 1479 + * @mrioc: Adapter instance reference 1480 + * @sas_address: SAS address of attached device 1481 + * @sas_address_parent: SAS address of parent expander or host 1482 + * @hba_port: HBA port entry 1483 + * 1484 + * Removing object and freeing associated memory from the 1485 + * sas_port_list. 1486 + * 1487 + * Return: None 1488 + */ 1489 + static void mpi3mr_sas_port_remove(struct mpi3mr_ioc *mrioc, u64 sas_address, 1490 + u64 sas_address_parent, struct mpi3mr_hba_port *hba_port) 1491 + { 1492 + int i; 1493 + unsigned long flags; 1494 + struct mpi3mr_sas_port *mr_sas_port, *next; 1495 + struct mpi3mr_sas_node *mr_sas_node; 1496 + u8 found = 0; 1497 + struct mpi3mr_sas_phy *mr_sas_phy, *next_phy; 1498 + struct mpi3mr_hba_port *srch_port, *hba_port_next = NULL; 1499 + 1500 + if (!hba_port) 1501 + return; 1502 + 1503 + spin_lock_irqsave(&mrioc->sas_node_lock, flags); 1504 + mr_sas_node = __mpi3mr_sas_node_find_by_sas_address(mrioc, 1505 + sas_address_parent, hba_port); 1506 + if (!mr_sas_node) { 1507 + spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); 1508 + return; 1509 + } 1510 + list_for_each_entry_safe(mr_sas_port, next, &mr_sas_node->sas_port_list, 1511 + port_list) { 1512 + if (mr_sas_port->remote_identify.sas_address != sas_address) 1513 + continue; 1514 + if (mr_sas_port->hba_port != hba_port) 1515 + continue; 1516 + found = 1; 1517 + list_del(&mr_sas_port->port_list); 1518 + goto out; 1519 + } 1520 + 1521 + out: 1522 + if (!found) { 1523 + spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); 1524 + return; 1525 + } 1526 + 1527 + if (mr_sas_node->host_node) { 1528 + list_for_each_entry_safe(srch_port, hba_port_next, 1529 + &mrioc->hba_port_table_list, list) { 1530 + if (srch_port != hba_port) 1531 + continue; 1532 + ioc_info(mrioc, 1533 + "removing hba_port entry: %p port: %d from hba_port list\n", 1534 + srch_port, srch_port->port_id); 1535 + list_del(&hba_port->list); 1536 + kfree(hba_port); 1537 + break; 1538 + } 1539 + } 1540 + 1541 + for (i = 0; i < mr_sas_node->num_phys; i++) { 1542 + if (mr_sas_node->phy[i].remote_identify.sas_address == 1543 + sas_address) 1544 + memset(&mr_sas_node->phy[i].remote_identify, 0, 1545 + sizeof(struct sas_identify)); 1546 + } 1547 + 1548 + spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); 1549 + 1550 + if (mrioc->current_event) 1551 + mrioc->current_event->pending_at_sml = 1; 1552 + 1553 + list_for_each_entry_safe(mr_sas_phy, next_phy, 1554 + &mr_sas_port->phy_list, port_siblings) { 1555 + if ((mrioc->logging_level & MPI3_DEBUG_TRANSPORT_INFO)) 1556 + dev_info(&mr_sas_port->port->dev, 1557 + "remove: sas_address(0x%016llx), phy(%d)\n", 1558 + (unsigned long long) 1559 + mr_sas_port->remote_identify.sas_address, 1560 + mr_sas_phy->phy_id); 1561 + mr_sas_phy->phy_belongs_to_port = 0; 1562 + if (!mrioc->stop_drv_processing) 1563 + sas_port_delete_phy(mr_sas_port->port, 1564 + mr_sas_phy->phy); 1565 + list_del(&mr_sas_phy->port_siblings); 1566 + } 1567 + if (!mrioc->stop_drv_processing) 1568 + sas_port_delete(mr_sas_port->port); 1569 + ioc_info(mrioc, "%s: removed sas_address(0x%016llx)\n", 1570 + __func__, (unsigned long long)sas_address); 1571 + 1572 + if (mrioc->current_event) { 1573 + mrioc->current_event->pending_at_sml = 0; 1574 + if (mrioc->current_event->discard) 1575 + mpi3mr_print_device_event_notice(mrioc, false); 1576 + } 1577 + 1578 + kfree(mr_sas_port); 1579 + } 1580 + 1581 + /** 1582 + * struct host_port - host port details 1583 + * @sas_address: SAS Address of the attached device 1584 + * @phy_mask: phy mask of host port 1585 + * @handle: Device Handle of attached device 1586 + * @iounit_port_id: port ID 1587 + * @used: host port is already matched with sas port from sas_port_list 1588 + * @lowest_phy: lowest phy ID of host port 1589 + */ 1590 + struct host_port { 1591 + u64 sas_address; 1592 + u32 phy_mask; 1593 + u16 handle; 1594 + u8 iounit_port_id; 1595 + u8 used; 1596 + u8 lowest_phy; 1597 + }; 1598 + 1599 + /** 1600 + * mpi3mr_update_mr_sas_port - update sas port objects during reset 1601 + * @mrioc: Adapter instance reference 1602 + * @h_port: host_port object 1603 + * @mr_sas_port: sas_port objects which needs to be updated 1604 + * 1605 + * Update the port ID of sas port object. Also add the phys if new phys got 1606 + * added to current sas port and remove the phys if some phys are moved 1607 + * out of the current sas port. 1608 + * 1609 + * Return: Nothing. 1610 + */ 1611 + static void 1612 + mpi3mr_update_mr_sas_port(struct mpi3mr_ioc *mrioc, struct host_port *h_port, 1613 + struct mpi3mr_sas_port *mr_sas_port) 1614 + { 1615 + struct mpi3mr_sas_phy *mr_sas_phy; 1616 + u32 phy_mask_xor; 1617 + u64 phys_to_be_added, phys_to_be_removed; 1618 + int i; 1619 + 1620 + h_port->used = 1; 1621 + mr_sas_port->marked_responding = 1; 1622 + 1623 + dev_info(&mr_sas_port->port->dev, 1624 + "sas_address(0x%016llx), old: port_id %d phy_mask 0x%x, new: port_id %d phy_mask:0x%x\n", 1625 + mr_sas_port->remote_identify.sas_address, 1626 + mr_sas_port->hba_port->port_id, mr_sas_port->phy_mask, 1627 + h_port->iounit_port_id, h_port->phy_mask); 1628 + 1629 + mr_sas_port->hba_port->port_id = h_port->iounit_port_id; 1630 + mr_sas_port->hba_port->flags &= ~MPI3MR_HBA_PORT_FLAG_DIRTY; 1631 + 1632 + /* Get the newly added phys bit map & removed phys bit map */ 1633 + phy_mask_xor = mr_sas_port->phy_mask ^ h_port->phy_mask; 1634 + phys_to_be_added = h_port->phy_mask & phy_mask_xor; 1635 + phys_to_be_removed = mr_sas_port->phy_mask & phy_mask_xor; 1636 + 1637 + /* 1638 + * Register these new phys to current mr_sas_port's port. 1639 + * if these phys are previously registered with another port 1640 + * then delete these phys from that port first. 1641 + */ 1642 + for_each_set_bit(i, (ulong *) &phys_to_be_added, BITS_PER_TYPE(u32)) { 1643 + mr_sas_phy = &mrioc->sas_hba.phy[i]; 1644 + if (mr_sas_phy->phy_belongs_to_port) 1645 + mpi3mr_del_phy_from_an_existing_port(mrioc, 1646 + &mrioc->sas_hba, mr_sas_phy); 1647 + mpi3mr_add_phy_to_an_existing_port(mrioc, 1648 + &mrioc->sas_hba, mr_sas_phy, 1649 + mr_sas_port->remote_identify.sas_address, 1650 + mr_sas_port->hba_port); 1651 + } 1652 + 1653 + /* Delete the phys which are not part of current mr_sas_port's port. */ 1654 + for_each_set_bit(i, (ulong *) &phys_to_be_removed, BITS_PER_TYPE(u32)) { 1655 + mr_sas_phy = &mrioc->sas_hba.phy[i]; 1656 + if (mr_sas_phy->phy_belongs_to_port) 1657 + mpi3mr_del_phy_from_an_existing_port(mrioc, 1658 + &mrioc->sas_hba, mr_sas_phy); 1659 + } 1660 + } 1661 + 1662 + /** 1663 + * mpi3mr_refresh_sas_ports - update host's sas ports during reset 1664 + * @mrioc: Adapter instance reference 1665 + * 1666 + * Update the host's sas ports during reset by checking whether 1667 + * sas ports are still intact or not. Add/remove phys if any hba 1668 + * phys are (moved in)/(moved out) of sas port. Also update 1669 + * io_unit_port if it got changed during reset. 1670 + * 1671 + * Return: Nothing. 1672 + */ 1673 + void 1674 + mpi3mr_refresh_sas_ports(struct mpi3mr_ioc *mrioc) 1675 + { 1676 + struct host_port h_port[32]; 1677 + int i, j, found, host_port_count = 0, port_idx; 1678 + u16 sz, attached_handle, ioc_status; 1679 + struct mpi3_sas_io_unit_page0 *sas_io_unit_pg0 = NULL; 1680 + struct mpi3_device_page0 dev_pg0; 1681 + struct mpi3_device0_sas_sata_format *sasinf; 1682 + struct mpi3mr_sas_port *mr_sas_port; 1683 + 1684 + sz = offsetof(struct mpi3_sas_io_unit_page0, phy_data) + 1685 + (mrioc->sas_hba.num_phys * 1686 + sizeof(struct mpi3_sas_io_unit0_phy_data)); 1687 + sas_io_unit_pg0 = kzalloc(sz, GFP_KERNEL); 1688 + if (!sas_io_unit_pg0) 1689 + return; 1690 + if (mpi3mr_cfg_get_sas_io_unit_pg0(mrioc, sas_io_unit_pg0, sz)) { 1691 + ioc_err(mrioc, "failure at %s:%d/%s()!\n", 1692 + __FILE__, __LINE__, __func__); 1693 + goto out; 1694 + } 1695 + 1696 + /* Create a new expander port table */ 1697 + for (i = 0; i < mrioc->sas_hba.num_phys; i++) { 1698 + attached_handle = le16_to_cpu( 1699 + sas_io_unit_pg0->phy_data[i].attached_dev_handle); 1700 + if (!attached_handle) 1701 + continue; 1702 + found = 0; 1703 + for (j = 0; j < host_port_count; j++) { 1704 + if (h_port[j].handle == attached_handle) { 1705 + h_port[j].phy_mask |= (1 << i); 1706 + found = 1; 1707 + break; 1708 + } 1709 + } 1710 + if (found) 1711 + continue; 1712 + if ((mpi3mr_cfg_get_dev_pg0(mrioc, &ioc_status, &dev_pg0, 1713 + sizeof(dev_pg0), MPI3_DEVICE_PGAD_FORM_HANDLE, 1714 + attached_handle))) { 1715 + dprint_reset(mrioc, 1716 + "failed to read dev_pg0 for handle(0x%04x) at %s:%d/%s()!\n", 1717 + attached_handle, __FILE__, __LINE__, __func__); 1718 + continue; 1719 + } 1720 + if (ioc_status != MPI3_IOCSTATUS_SUCCESS) { 1721 + dprint_reset(mrioc, 1722 + "ioc_status(0x%x) while reading dev_pg0 for handle(0x%04x) at %s:%d/%s()!\n", 1723 + ioc_status, attached_handle, 1724 + __FILE__, __LINE__, __func__); 1725 + continue; 1726 + } 1727 + sasinf = &dev_pg0.device_specific.sas_sata_format; 1728 + 1729 + port_idx = host_port_count; 1730 + h_port[port_idx].sas_address = le64_to_cpu(sasinf->sas_address); 1731 + h_port[port_idx].handle = attached_handle; 1732 + h_port[port_idx].phy_mask = (1 << i); 1733 + h_port[port_idx].iounit_port_id = sas_io_unit_pg0->phy_data[i].io_unit_port; 1734 + h_port[port_idx].lowest_phy = sasinf->phy_num; 1735 + h_port[port_idx].used = 0; 1736 + host_port_count++; 1737 + } 1738 + 1739 + if (!host_port_count) 1740 + goto out; 1741 + 1742 + if (mrioc->logging_level & MPI3_DEBUG_RESET) { 1743 + ioc_info(mrioc, "Host port details before reset\n"); 1744 + list_for_each_entry(mr_sas_port, &mrioc->sas_hba.sas_port_list, 1745 + port_list) { 1746 + ioc_info(mrioc, 1747 + "port_id:%d, sas_address:(0x%016llx), phy_mask:(0x%x), lowest phy id:%d\n", 1748 + mr_sas_port->hba_port->port_id, 1749 + mr_sas_port->remote_identify.sas_address, 1750 + mr_sas_port->phy_mask, mr_sas_port->lowest_phy); 1751 + } 1752 + mr_sas_port = NULL; 1753 + ioc_info(mrioc, "Host port details after reset\n"); 1754 + for (i = 0; i < host_port_count; i++) { 1755 + ioc_info(mrioc, 1756 + "port_id:%d, sas_address:(0x%016llx), phy_mask:(0x%x), lowest phy id:%d\n", 1757 + h_port[i].iounit_port_id, h_port[i].sas_address, 1758 + h_port[i].phy_mask, h_port[i].lowest_phy); 1759 + } 1760 + } 1761 + 1762 + /* mark all host sas port entries as dirty */ 1763 + list_for_each_entry(mr_sas_port, &mrioc->sas_hba.sas_port_list, 1764 + port_list) { 1765 + mr_sas_port->marked_responding = 0; 1766 + mr_sas_port->hba_port->flags |= MPI3MR_HBA_PORT_FLAG_DIRTY; 1767 + } 1768 + 1769 + /* First check for matching lowest phy */ 1770 + for (i = 0; i < host_port_count; i++) { 1771 + mr_sas_port = NULL; 1772 + list_for_each_entry(mr_sas_port, &mrioc->sas_hba.sas_port_list, 1773 + port_list) { 1774 + if (mr_sas_port->marked_responding) 1775 + continue; 1776 + if (h_port[i].sas_address != mr_sas_port->remote_identify.sas_address) 1777 + continue; 1778 + if (h_port[i].lowest_phy == mr_sas_port->lowest_phy) { 1779 + mpi3mr_update_mr_sas_port(mrioc, &h_port[i], mr_sas_port); 1780 + break; 1781 + } 1782 + } 1783 + } 1784 + 1785 + /* In case if lowest phy is got enabled or disabled during reset */ 1786 + for (i = 0; i < host_port_count; i++) { 1787 + if (h_port[i].used) 1788 + continue; 1789 + mr_sas_port = NULL; 1790 + list_for_each_entry(mr_sas_port, &mrioc->sas_hba.sas_port_list, 1791 + port_list) { 1792 + if (mr_sas_port->marked_responding) 1793 + continue; 1794 + if (h_port[i].sas_address != mr_sas_port->remote_identify.sas_address) 1795 + continue; 1796 + if (h_port[i].phy_mask & mr_sas_port->phy_mask) { 1797 + mpi3mr_update_mr_sas_port(mrioc, &h_port[i], mr_sas_port); 1798 + break; 1799 + } 1800 + } 1801 + } 1802 + 1803 + /* In case if expander cable is removed & connected to another HBA port during reset */ 1804 + for (i = 0; i < host_port_count; i++) { 1805 + if (h_port[i].used) 1806 + continue; 1807 + mr_sas_port = NULL; 1808 + list_for_each_entry(mr_sas_port, &mrioc->sas_hba.sas_port_list, 1809 + port_list) { 1810 + if (mr_sas_port->marked_responding) 1811 + continue; 1812 + if (h_port[i].sas_address != mr_sas_port->remote_identify.sas_address) 1813 + continue; 1814 + mpi3mr_update_mr_sas_port(mrioc, &h_port[i], mr_sas_port); 1815 + break; 1816 + } 1817 + } 1818 + out: 1819 + kfree(sas_io_unit_pg0); 1820 + } 1821 + 1822 + /** 1823 + * mpi3mr_refresh_expanders - Refresh expander device exposure 1824 + * @mrioc: Adapter instance reference 1825 + * 1826 + * This is executed post controller reset to identify any 1827 + * missing expander devices during reset and remove from the upper layers 1828 + * or expose any newly detected expander device to the upper layers. 1829 + * 1830 + * Return: Nothing. 1831 + */ 1832 + void 1833 + mpi3mr_refresh_expanders(struct mpi3mr_ioc *mrioc) 1834 + { 1835 + struct mpi3mr_sas_node *sas_expander, *sas_expander_next; 1836 + struct mpi3_sas_expander_page0 expander_pg0; 1837 + u16 ioc_status, handle; 1838 + u64 sas_address; 1839 + int i; 1840 + unsigned long flags; 1841 + struct mpi3mr_hba_port *hba_port; 1842 + 1843 + spin_lock_irqsave(&mrioc->sas_node_lock, flags); 1844 + list_for_each_entry(sas_expander, &mrioc->sas_expander_list, list) { 1845 + sas_expander->non_responding = 1; 1846 + } 1847 + spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); 1848 + 1849 + sas_expander = NULL; 1850 + 1851 + handle = 0xffff; 1852 + 1853 + /* Search for responding expander devices and add them if they are newly got added */ 1854 + while (true) { 1855 + if ((mpi3mr_cfg_get_sas_exp_pg0(mrioc, &ioc_status, &expander_pg0, 1856 + sizeof(struct mpi3_sas_expander_page0), 1857 + MPI3_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE, handle))) { 1858 + dprint_reset(mrioc, 1859 + "failed to read exp pg0 for handle(0x%04x) at %s:%d/%s()!\n", 1860 + handle, __FILE__, __LINE__, __func__); 1861 + break; 1862 + } 1863 + 1864 + if (ioc_status != MPI3_IOCSTATUS_SUCCESS) { 1865 + dprint_reset(mrioc, 1866 + "ioc_status(0x%x) while reading exp pg0 for handle:(0x%04x), %s:%d/%s()!\n", 1867 + ioc_status, handle, __FILE__, __LINE__, __func__); 1868 + break; 1869 + } 1870 + 1871 + handle = le16_to_cpu(expander_pg0.dev_handle); 1872 + sas_address = le64_to_cpu(expander_pg0.sas_address); 1873 + hba_port = mpi3mr_get_hba_port_by_id(mrioc, expander_pg0.io_unit_port); 1874 + 1875 + if (!hba_port) { 1876 + mpi3mr_sas_host_refresh(mrioc); 1877 + mpi3mr_expander_add(mrioc, handle); 1878 + continue; 1879 + } 1880 + 1881 + spin_lock_irqsave(&mrioc->sas_node_lock, flags); 1882 + sas_expander = 1883 + mpi3mr_expander_find_by_sas_address(mrioc, 1884 + sas_address, hba_port); 1885 + spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); 1886 + 1887 + if (!sas_expander) { 1888 + mpi3mr_sas_host_refresh(mrioc); 1889 + mpi3mr_expander_add(mrioc, handle); 1890 + continue; 1891 + } 1892 + 1893 + sas_expander->non_responding = 0; 1894 + if (sas_expander->handle == handle) 1895 + continue; 1896 + 1897 + sas_expander->handle = handle; 1898 + for (i = 0 ; i < sas_expander->num_phys ; i++) 1899 + sas_expander->phy[i].handle = handle; 1900 + } 1901 + 1902 + /* 1903 + * Delete non responding expander devices and the corresponding 1904 + * hba_port if the non responding expander device's parent device 1905 + * is a host node. 1906 + */ 1907 + sas_expander = NULL; 1908 + spin_lock_irqsave(&mrioc->sas_node_lock, flags); 1909 + list_for_each_entry_safe_reverse(sas_expander, sas_expander_next, 1910 + &mrioc->sas_expander_list, list) { 1911 + if (sas_expander->non_responding) { 1912 + spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); 1913 + mpi3mr_expander_node_remove(mrioc, sas_expander); 1914 + spin_lock_irqsave(&mrioc->sas_node_lock, flags); 1915 + } 1916 + } 1917 + spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); 1918 + } 1919 + 1920 + /** 1921 + * mpi3mr_expander_node_add - insert an expander to the list. 1922 + * @mrioc: Adapter instance reference 1923 + * @sas_expander: Expander sas node 1924 + * Context: This function will acquire sas_node_lock. 1925 + * 1926 + * Adding new object to the ioc->sas_expander_list. 1927 + * 1928 + * Return: None. 1929 + */ 1930 + static void mpi3mr_expander_node_add(struct mpi3mr_ioc *mrioc, 1931 + struct mpi3mr_sas_node *sas_expander) 1932 + { 1933 + unsigned long flags; 1934 + 1935 + spin_lock_irqsave(&mrioc->sas_node_lock, flags); 1936 + list_add_tail(&sas_expander->list, &mrioc->sas_expander_list); 1937 + spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); 1938 + } 1939 + 1940 + /** 1941 + * mpi3mr_expander_add - Create expander object 1942 + * @mrioc: Adapter instance reference 1943 + * @handle: Expander firmware device handle 1944 + * 1945 + * This function creating expander object, stored in 1946 + * sas_expander_list and expose it to the SAS transport 1947 + * layer. 1948 + * 1949 + * Return: 0 for success, non-zero for failure. 1950 + */ 1951 + int mpi3mr_expander_add(struct mpi3mr_ioc *mrioc, u16 handle) 1952 + { 1953 + struct mpi3mr_sas_node *sas_expander; 1954 + struct mpi3mr_enclosure_node *enclosure_dev; 1955 + struct mpi3_sas_expander_page0 expander_pg0; 1956 + struct mpi3_sas_expander_page1 expander_pg1; 1957 + u16 ioc_status, parent_handle, temp_handle; 1958 + u64 sas_address, sas_address_parent = 0; 1959 + int i; 1960 + unsigned long flags; 1961 + u8 port_id, link_rate; 1962 + struct mpi3mr_sas_port *mr_sas_port = NULL; 1963 + struct mpi3mr_hba_port *hba_port; 1964 + u32 phynum_handle; 1965 + int rc = 0; 1966 + 1967 + if (!handle) 1968 + return -1; 1969 + 1970 + if (mrioc->reset_in_progress) 1971 + return -1; 1972 + 1973 + if ((mpi3mr_cfg_get_sas_exp_pg0(mrioc, &ioc_status, &expander_pg0, 1974 + sizeof(expander_pg0), MPI3_SAS_EXPAND_PGAD_FORM_HANDLE, handle))) { 1975 + ioc_err(mrioc, "failure at %s:%d/%s()!\n", 1976 + __FILE__, __LINE__, __func__); 1977 + return -1; 1978 + } 1979 + 1980 + if (ioc_status != MPI3_IOCSTATUS_SUCCESS) { 1981 + ioc_err(mrioc, "failure at %s:%d/%s()!\n", 1982 + __FILE__, __LINE__, __func__); 1983 + return -1; 1984 + } 1985 + 1986 + parent_handle = le16_to_cpu(expander_pg0.parent_dev_handle); 1987 + if (mpi3mr_get_sas_address(mrioc, parent_handle, &sas_address_parent) 1988 + != 0) { 1989 + ioc_err(mrioc, "failure at %s:%d/%s()!\n", 1990 + __FILE__, __LINE__, __func__); 1991 + return -1; 1992 + } 1993 + 1994 + port_id = expander_pg0.io_unit_port; 1995 + hba_port = mpi3mr_get_hba_port_by_id(mrioc, port_id); 1996 + if (!hba_port) { 1997 + ioc_err(mrioc, "failure at %s:%d/%s()!\n", 1998 + __FILE__, __LINE__, __func__); 1999 + return -1; 2000 + } 2001 + 2002 + if (sas_address_parent != mrioc->sas_hba.sas_address) { 2003 + spin_lock_irqsave(&mrioc->sas_node_lock, flags); 2004 + sas_expander = 2005 + mpi3mr_expander_find_by_sas_address(mrioc, 2006 + sas_address_parent, hba_port); 2007 + spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); 2008 + if (!sas_expander) { 2009 + rc = mpi3mr_expander_add(mrioc, parent_handle); 2010 + if (rc != 0) 2011 + return rc; 2012 + } else { 2013 + /* 2014 + * When there is a parent expander present, update it's 2015 + * phys where child expander is connected with the link 2016 + * speed, attached dev handle and sas address. 2017 + */ 2018 + for (i = 0 ; i < sas_expander->num_phys ; i++) { 2019 + phynum_handle = 2020 + (i << MPI3_SAS_EXPAND_PGAD_PHYNUM_SHIFT) | 2021 + parent_handle; 2022 + if (mpi3mr_cfg_get_sas_exp_pg1(mrioc, 2023 + &ioc_status, &expander_pg1, 2024 + sizeof(expander_pg1), 2025 + MPI3_SAS_EXPAND_PGAD_FORM_HANDLE_PHY_NUM, 2026 + phynum_handle)) { 2027 + ioc_err(mrioc, "failure at %s:%d/%s()!\n", 2028 + __FILE__, __LINE__, __func__); 2029 + rc = -1; 2030 + return rc; 2031 + } 2032 + if (ioc_status != MPI3_IOCSTATUS_SUCCESS) { 2033 + ioc_err(mrioc, "failure at %s:%d/%s()!\n", 2034 + __FILE__, __LINE__, __func__); 2035 + rc = -1; 2036 + return rc; 2037 + } 2038 + temp_handle = le16_to_cpu( 2039 + expander_pg1.attached_dev_handle); 2040 + if (temp_handle != handle) 2041 + continue; 2042 + link_rate = (expander_pg1.negotiated_link_rate & 2043 + MPI3_SAS_NEG_LINK_RATE_LOGICAL_MASK) >> 2044 + MPI3_SAS_NEG_LINK_RATE_LOGICAL_SHIFT; 2045 + mpi3mr_update_links(mrioc, sas_address_parent, 2046 + handle, i, link_rate, hba_port); 2047 + } 2048 + } 2049 + } 2050 + 2051 + spin_lock_irqsave(&mrioc->sas_node_lock, flags); 2052 + sas_address = le64_to_cpu(expander_pg0.sas_address); 2053 + sas_expander = mpi3mr_expander_find_by_sas_address(mrioc, 2054 + sas_address, hba_port); 2055 + spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); 2056 + 2057 + if (sas_expander) 2058 + return 0; 2059 + 2060 + sas_expander = kzalloc(sizeof(struct mpi3mr_sas_node), 2061 + GFP_KERNEL); 2062 + if (!sas_expander) 2063 + return -1; 2064 + 2065 + sas_expander->handle = handle; 2066 + sas_expander->num_phys = expander_pg0.num_phys; 2067 + sas_expander->sas_address_parent = sas_address_parent; 2068 + sas_expander->sas_address = sas_address; 2069 + sas_expander->hba_port = hba_port; 2070 + 2071 + ioc_info(mrioc, 2072 + "expander_add: handle(0x%04x), parent(0x%04x), sas_addr(0x%016llx), phys(%d)\n", 2073 + handle, parent_handle, (unsigned long long) 2074 + sas_expander->sas_address, sas_expander->num_phys); 2075 + 2076 + if (!sas_expander->num_phys) { 2077 + rc = -1; 2078 + goto out_fail; 2079 + } 2080 + sas_expander->phy = kcalloc(sas_expander->num_phys, 2081 + sizeof(struct mpi3mr_sas_phy), GFP_KERNEL); 2082 + if (!sas_expander->phy) { 2083 + rc = -1; 2084 + goto out_fail; 2085 + } 2086 + 2087 + INIT_LIST_HEAD(&sas_expander->sas_port_list); 2088 + mr_sas_port = mpi3mr_sas_port_add(mrioc, handle, sas_address_parent, 2089 + sas_expander->hba_port); 2090 + if (!mr_sas_port) { 2091 + ioc_err(mrioc, "failure at %s:%d/%s()!\n", 2092 + __FILE__, __LINE__, __func__); 2093 + rc = -1; 2094 + goto out_fail; 2095 + } 2096 + sas_expander->parent_dev = &mr_sas_port->rphy->dev; 2097 + sas_expander->rphy = mr_sas_port->rphy; 2098 + 2099 + for (i = 0 ; i < sas_expander->num_phys ; i++) { 2100 + phynum_handle = (i << MPI3_SAS_EXPAND_PGAD_PHYNUM_SHIFT) | 2101 + handle; 2102 + if (mpi3mr_cfg_get_sas_exp_pg1(mrioc, &ioc_status, 2103 + &expander_pg1, sizeof(expander_pg1), 2104 + MPI3_SAS_EXPAND_PGAD_FORM_HANDLE_PHY_NUM, 2105 + phynum_handle)) { 2106 + ioc_err(mrioc, "failure at %s:%d/%s()!\n", 2107 + __FILE__, __LINE__, __func__); 2108 + rc = -1; 2109 + goto out_fail; 2110 + } 2111 + if (ioc_status != MPI3_IOCSTATUS_SUCCESS) { 2112 + ioc_err(mrioc, "failure at %s:%d/%s()!\n", 2113 + __FILE__, __LINE__, __func__); 2114 + rc = -1; 2115 + goto out_fail; 2116 + } 2117 + 2118 + sas_expander->phy[i].handle = handle; 2119 + sas_expander->phy[i].phy_id = i; 2120 + sas_expander->phy[i].hba_port = hba_port; 2121 + 2122 + if ((mpi3mr_add_expander_phy(mrioc, &sas_expander->phy[i], 2123 + expander_pg1, sas_expander->parent_dev))) { 2124 + ioc_err(mrioc, "failure at %s:%d/%s()!\n", 2125 + __FILE__, __LINE__, __func__); 2126 + rc = -1; 2127 + goto out_fail; 2128 + } 2129 + } 2130 + 2131 + if (sas_expander->enclosure_handle) { 2132 + enclosure_dev = 2133 + mpi3mr_enclosure_find_by_handle(mrioc, 2134 + sas_expander->enclosure_handle); 2135 + if (enclosure_dev) 2136 + sas_expander->enclosure_logical_id = le64_to_cpu( 2137 + enclosure_dev->pg0.enclosure_logical_id); 2138 + } 2139 + 2140 + mpi3mr_expander_node_add(mrioc, sas_expander); 2141 + return 0; 2142 + 2143 + out_fail: 2144 + 2145 + if (mr_sas_port) 2146 + mpi3mr_sas_port_remove(mrioc, 2147 + sas_expander->sas_address, 2148 + sas_address_parent, sas_expander->hba_port); 2149 + kfree(sas_expander->phy); 2150 + kfree(sas_expander); 2151 + return rc; 2152 + } 2153 + 2154 + /** 2155 + * mpi3mr_expander_node_remove - recursive removal of expander. 2156 + * @mrioc: Adapter instance reference 2157 + * @sas_expander: Expander device object 2158 + * 2159 + * Removes expander object and freeing associated memory from 2160 + * the sas_expander_list and removes the same from SAS TL, if 2161 + * one of the attached device is an expander then it recursively 2162 + * removes the expander device too. 2163 + * 2164 + * Return nothing. 2165 + */ 2166 + static void mpi3mr_expander_node_remove(struct mpi3mr_ioc *mrioc, 2167 + struct mpi3mr_sas_node *sas_expander) 2168 + { 2169 + struct mpi3mr_sas_port *mr_sas_port, *next; 2170 + unsigned long flags; 2171 + u8 port_id; 2172 + 2173 + /* remove sibling ports attached to this expander */ 2174 + list_for_each_entry_safe(mr_sas_port, next, 2175 + &sas_expander->sas_port_list, port_list) { 2176 + if (mrioc->reset_in_progress) 2177 + return; 2178 + if (mr_sas_port->remote_identify.device_type == 2179 + SAS_END_DEVICE) 2180 + mpi3mr_remove_device_by_sas_address(mrioc, 2181 + mr_sas_port->remote_identify.sas_address, 2182 + mr_sas_port->hba_port); 2183 + else if (mr_sas_port->remote_identify.device_type == 2184 + SAS_EDGE_EXPANDER_DEVICE || 2185 + mr_sas_port->remote_identify.device_type == 2186 + SAS_FANOUT_EXPANDER_DEVICE) 2187 + mpi3mr_expander_remove(mrioc, 2188 + mr_sas_port->remote_identify.sas_address, 2189 + mr_sas_port->hba_port); 2190 + } 2191 + 2192 + port_id = sas_expander->hba_port->port_id; 2193 + mpi3mr_sas_port_remove(mrioc, sas_expander->sas_address, 2194 + sas_expander->sas_address_parent, sas_expander->hba_port); 2195 + 2196 + ioc_info(mrioc, "expander_remove: handle(0x%04x), sas_addr(0x%016llx), port:%d\n", 2197 + sas_expander->handle, (unsigned long long) 2198 + sas_expander->sas_address, port_id); 2199 + 2200 + spin_lock_irqsave(&mrioc->sas_node_lock, flags); 2201 + list_del(&sas_expander->list); 2202 + spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); 2203 + 2204 + kfree(sas_expander->phy); 2205 + kfree(sas_expander); 2206 + } 2207 + 2208 + /** 2209 + * mpi3mr_expander_remove - Remove expander object 2210 + * @mrioc: Adapter instance reference 2211 + * @sas_address: Remove expander sas_address 2212 + * @hba_port: HBA port reference 2213 + * 2214 + * This function remove expander object, stored in 2215 + * mrioc->sas_expander_list and removes it from the SAS TL by 2216 + * calling mpi3mr_expander_node_remove(). 2217 + * 2218 + * Return: None 2219 + */ 2220 + void mpi3mr_expander_remove(struct mpi3mr_ioc *mrioc, u64 sas_address, 2221 + struct mpi3mr_hba_port *hba_port) 2222 + { 2223 + struct mpi3mr_sas_node *sas_expander; 2224 + unsigned long flags; 2225 + 2226 + if (mrioc->reset_in_progress) 2227 + return; 2228 + 2229 + if (!hba_port) 2230 + return; 2231 + 2232 + spin_lock_irqsave(&mrioc->sas_node_lock, flags); 2233 + sas_expander = mpi3mr_expander_find_by_sas_address(mrioc, sas_address, 2234 + hba_port); 2235 + spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); 2236 + if (sas_expander) 2237 + mpi3mr_expander_node_remove(mrioc, sas_expander); 2238 + 2239 + } 2240 + 2241 + /** 2242 + * mpi3mr_get_sas_negotiated_logical_linkrate - get linkrate 2243 + * @mrioc: Adapter instance reference 2244 + * @tgtdev: Target device 2245 + * 2246 + * This function identifies whether the target device is 2247 + * attached directly or through expander and issues sas phy 2248 + * page0 or expander phy page1 and gets the link rate, if there 2249 + * is any failure in reading the pages then this returns link 2250 + * rate of 1.5. 2251 + * 2252 + * Return: logical link rate. 2253 + */ 2254 + static u8 mpi3mr_get_sas_negotiated_logical_linkrate(struct mpi3mr_ioc *mrioc, 2255 + struct mpi3mr_tgt_dev *tgtdev) 2256 + { 2257 + u8 link_rate = MPI3_SAS_NEG_LINK_RATE_1_5, phy_number; 2258 + struct mpi3_sas_expander_page1 expander_pg1; 2259 + struct mpi3_sas_phy_page0 phy_pg0; 2260 + u32 phynum_handle; 2261 + u16 ioc_status; 2262 + 2263 + phy_number = tgtdev->dev_spec.sas_sata_inf.phy_id; 2264 + if (!(tgtdev->devpg0_flag & MPI3_DEVICE0_FLAGS_ATT_METHOD_DIR_ATTACHED)) { 2265 + phynum_handle = ((phy_number<<MPI3_SAS_EXPAND_PGAD_PHYNUM_SHIFT) 2266 + | tgtdev->parent_handle); 2267 + if (mpi3mr_cfg_get_sas_exp_pg1(mrioc, &ioc_status, 2268 + &expander_pg1, sizeof(expander_pg1), 2269 + MPI3_SAS_EXPAND_PGAD_FORM_HANDLE_PHY_NUM, 2270 + phynum_handle)) { 2271 + ioc_err(mrioc, "failure at %s:%d/%s()!\n", 2272 + __FILE__, __LINE__, __func__); 2273 + goto out; 2274 + } 2275 + if (ioc_status != MPI3_IOCSTATUS_SUCCESS) { 2276 + ioc_err(mrioc, "failure at %s:%d/%s()!\n", 2277 + __FILE__, __LINE__, __func__); 2278 + goto out; 2279 + } 2280 + link_rate = (expander_pg1.negotiated_link_rate & 2281 + MPI3_SAS_NEG_LINK_RATE_LOGICAL_MASK) >> 2282 + MPI3_SAS_NEG_LINK_RATE_LOGICAL_SHIFT; 2283 + goto out; 2284 + } 2285 + if (mpi3mr_cfg_get_sas_phy_pg0(mrioc, &ioc_status, &phy_pg0, 2286 + sizeof(struct mpi3_sas_phy_page0), 2287 + MPI3_SAS_PHY_PGAD_FORM_PHY_NUMBER, phy_number)) { 2288 + ioc_err(mrioc, "failure at %s:%d/%s()!\n", 2289 + __FILE__, __LINE__, __func__); 2290 + goto out; 2291 + } 2292 + if (ioc_status != MPI3_IOCSTATUS_SUCCESS) { 2293 + ioc_err(mrioc, "failure at %s:%d/%s()!\n", 2294 + __FILE__, __LINE__, __func__); 2295 + goto out; 2296 + } 2297 + link_rate = (phy_pg0.negotiated_link_rate & 2298 + MPI3_SAS_NEG_LINK_RATE_LOGICAL_MASK) >> 2299 + MPI3_SAS_NEG_LINK_RATE_LOGICAL_SHIFT; 2300 + out: 2301 + return link_rate; 2302 + } 2303 + 2304 + /** 2305 + * mpi3mr_report_tgtdev_to_sas_transport - expose dev to SAS TL 2306 + * @mrioc: Adapter instance reference 2307 + * @tgtdev: Target device 2308 + * 2309 + * This function exposes the target device after 2310 + * preparing host_phy, setting up link rate etc. 2311 + * 2312 + * Return: 0 on success, non-zero for failure. 2313 + */ 2314 + int mpi3mr_report_tgtdev_to_sas_transport(struct mpi3mr_ioc *mrioc, 2315 + struct mpi3mr_tgt_dev *tgtdev) 2316 + { 2317 + int retval = 0; 2318 + u8 link_rate, parent_phy_number; 2319 + u64 sas_address_parent, sas_address; 2320 + struct mpi3mr_hba_port *hba_port; 2321 + u8 port_id; 2322 + 2323 + if ((tgtdev->dev_type != MPI3_DEVICE_DEVFORM_SAS_SATA) || 2324 + !mrioc->sas_transport_enabled) 2325 + return -1; 2326 + 2327 + sas_address = tgtdev->dev_spec.sas_sata_inf.sas_address; 2328 + if (!mrioc->sas_hba.num_phys) 2329 + mpi3mr_sas_host_add(mrioc); 2330 + else 2331 + mpi3mr_sas_host_refresh(mrioc); 2332 + 2333 + if (mpi3mr_get_sas_address(mrioc, tgtdev->parent_handle, 2334 + &sas_address_parent) != 0) { 2335 + ioc_err(mrioc, "failure at %s:%d/%s()!\n", 2336 + __FILE__, __LINE__, __func__); 2337 + return -1; 2338 + } 2339 + tgtdev->dev_spec.sas_sata_inf.sas_address_parent = sas_address_parent; 2340 + 2341 + parent_phy_number = tgtdev->dev_spec.sas_sata_inf.phy_id; 2342 + port_id = tgtdev->io_unit_port; 2343 + 2344 + hba_port = mpi3mr_get_hba_port_by_id(mrioc, port_id); 2345 + if (!hba_port) { 2346 + ioc_err(mrioc, "failure at %s:%d/%s()!\n", 2347 + __FILE__, __LINE__, __func__); 2348 + return -1; 2349 + } 2350 + tgtdev->dev_spec.sas_sata_inf.hba_port = hba_port; 2351 + 2352 + link_rate = mpi3mr_get_sas_negotiated_logical_linkrate(mrioc, tgtdev); 2353 + 2354 + mpi3mr_update_links(mrioc, sas_address_parent, tgtdev->dev_handle, 2355 + parent_phy_number, link_rate, hba_port); 2356 + 2357 + tgtdev->host_exposed = 1; 2358 + if (!mpi3mr_sas_port_add(mrioc, tgtdev->dev_handle, 2359 + sas_address_parent, hba_port)) { 2360 + tgtdev->host_exposed = 0; 2361 + retval = -1; 2362 + } else if ((!tgtdev->starget)) { 2363 + if (!mrioc->is_driver_loading) 2364 + mpi3mr_sas_port_remove(mrioc, sas_address, 2365 + sas_address_parent, hba_port); 2366 + tgtdev->host_exposed = 0; 2367 + retval = -1; 2368 + } 2369 + return retval; 2370 + } 2371 + 2372 + /** 2373 + * mpi3mr_remove_tgtdev_from_sas_transport - remove from SAS TL 2374 + * @mrioc: Adapter instance reference 2375 + * @tgtdev: Target device 2376 + * 2377 + * This function removes the target device 2378 + * 2379 + * Return: None. 2380 + */ 2381 + void mpi3mr_remove_tgtdev_from_sas_transport(struct mpi3mr_ioc *mrioc, 2382 + struct mpi3mr_tgt_dev *tgtdev) 2383 + { 2384 + u64 sas_address_parent, sas_address; 2385 + struct mpi3mr_hba_port *hba_port; 2386 + 2387 + if ((tgtdev->dev_type != MPI3_DEVICE_DEVFORM_SAS_SATA) || 2388 + !mrioc->sas_transport_enabled) 2389 + return; 2390 + 2391 + hba_port = tgtdev->dev_spec.sas_sata_inf.hba_port; 2392 + sas_address = tgtdev->dev_spec.sas_sata_inf.sas_address; 2393 + sas_address_parent = tgtdev->dev_spec.sas_sata_inf.sas_address_parent; 2394 + mpi3mr_sas_port_remove(mrioc, sas_address, sas_address_parent, 2395 + hba_port); 2396 + tgtdev->host_exposed = 0; 2397 + } 2398 + 2399 + /** 2400 + * mpi3mr_get_port_id_by_sas_phy - Get port ID of the given phy 2401 + * @phy: SAS transport layer phy object 2402 + * 2403 + * Return: Port number for valid ID else 0xFFFF 2404 + */ 2405 + static inline u8 mpi3mr_get_port_id_by_sas_phy(struct sas_phy *phy) 2406 + { 2407 + u8 port_id = 0xFF; 2408 + struct mpi3mr_hba_port *hba_port = phy->hostdata; 2409 + 2410 + if (hba_port) 2411 + port_id = hba_port->port_id; 2412 + 2413 + return port_id; 2414 + } 2415 + 2416 + /** 2417 + * mpi3mr_get_port_id_by_rphy - Get Port number from SAS rphy 2418 + * 2419 + * @mrioc: Adapter instance reference 2420 + * @rphy: SAS transport layer remote phy object 2421 + * 2422 + * Retrieves HBA port number in which the device pointed by the 2423 + * rphy object is attached with. 2424 + * 2425 + * Return: Valid port number on success else OxFFFF. 2426 + */ 2427 + static u8 mpi3mr_get_port_id_by_rphy(struct mpi3mr_ioc *mrioc, struct sas_rphy *rphy) 2428 + { 2429 + struct mpi3mr_sas_node *sas_expander; 2430 + struct mpi3mr_tgt_dev *tgtdev; 2431 + unsigned long flags; 2432 + u8 port_id = 0xFF; 2433 + 2434 + if (!rphy) 2435 + return port_id; 2436 + 2437 + if (rphy->identify.device_type == SAS_EDGE_EXPANDER_DEVICE || 2438 + rphy->identify.device_type == SAS_FANOUT_EXPANDER_DEVICE) { 2439 + spin_lock_irqsave(&mrioc->sas_node_lock, flags); 2440 + list_for_each_entry(sas_expander, &mrioc->sas_expander_list, 2441 + list) { 2442 + if (sas_expander->rphy == rphy) { 2443 + port_id = sas_expander->hba_port->port_id; 2444 + break; 2445 + } 2446 + } 2447 + spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); 2448 + } else if (rphy->identify.device_type == SAS_END_DEVICE) { 2449 + spin_lock_irqsave(&mrioc->tgtdev_lock, flags); 2450 + 2451 + tgtdev = __mpi3mr_get_tgtdev_by_addr_and_rphy(mrioc, 2452 + rphy->identify.sas_address, rphy); 2453 + if (tgtdev) { 2454 + port_id = 2455 + tgtdev->dev_spec.sas_sata_inf.hba_port->port_id; 2456 + mpi3mr_tgtdev_put(tgtdev); 2457 + } 2458 + spin_unlock_irqrestore(&mrioc->tgtdev_lock, flags); 2459 + } 2460 + return port_id; 2461 + } 2462 + 2463 + static inline struct mpi3mr_ioc *phy_to_mrioc(struct sas_phy *phy) 2464 + { 2465 + struct Scsi_Host *shost = dev_to_shost(phy->dev.parent); 2466 + 2467 + return shost_priv(shost); 2468 + } 2469 + 2470 + static inline struct mpi3mr_ioc *rphy_to_mrioc(struct sas_rphy *rphy) 2471 + { 2472 + struct Scsi_Host *shost = dev_to_shost(rphy->dev.parent->parent); 2473 + 2474 + return shost_priv(shost); 2475 + } 2476 + 2477 + /* report phy error log structure */ 2478 + struct phy_error_log_request { 2479 + u8 smp_frame_type; /* 0x40 */ 2480 + u8 function; /* 0x11 */ 2481 + u8 allocated_response_length; 2482 + u8 request_length; /* 02 */ 2483 + u8 reserved_1[5]; 2484 + u8 phy_identifier; 2485 + u8 reserved_2[2]; 2486 + }; 2487 + 2488 + /* report phy error log reply structure */ 2489 + struct phy_error_log_reply { 2490 + u8 smp_frame_type; /* 0x41 */ 2491 + u8 function; /* 0x11 */ 2492 + u8 function_result; 2493 + u8 response_length; 2494 + __be16 expander_change_count; 2495 + u8 reserved_1[3]; 2496 + u8 phy_identifier; 2497 + u8 reserved_2[2]; 2498 + __be32 invalid_dword; 2499 + __be32 running_disparity_error; 2500 + __be32 loss_of_dword_sync; 2501 + __be32 phy_reset_problem; 2502 + }; 2503 + 2504 + 2505 + /** 2506 + * mpi3mr_get_expander_phy_error_log - return expander counters: 2507 + * @mrioc: Adapter instance reference 2508 + * @phy: The SAS transport layer phy object 2509 + * 2510 + * Return: 0 for success, non-zero for failure. 2511 + * 2512 + */ 2513 + static int mpi3mr_get_expander_phy_error_log(struct mpi3mr_ioc *mrioc, 2514 + struct sas_phy *phy) 2515 + { 2516 + struct mpi3_smp_passthrough_request mpi_request; 2517 + struct mpi3_smp_passthrough_reply mpi_reply; 2518 + struct phy_error_log_request *phy_error_log_request; 2519 + struct phy_error_log_reply *phy_error_log_reply; 2520 + int rc; 2521 + void *psge; 2522 + void *data_out = NULL; 2523 + dma_addr_t data_out_dma, data_in_dma; 2524 + u32 data_out_sz, data_in_sz, sz; 2525 + u8 sgl_flags = MPI3MR_SGEFLAGS_SYSTEM_SIMPLE_END_OF_LIST; 2526 + u16 request_sz = sizeof(struct mpi3_smp_passthrough_request); 2527 + u16 reply_sz = sizeof(struct mpi3_smp_passthrough_reply); 2528 + u16 ioc_status; 2529 + 2530 + if (mrioc->reset_in_progress) { 2531 + ioc_err(mrioc, "%s: host reset in progress!\n", __func__); 2532 + return -EFAULT; 2533 + } 2534 + 2535 + data_out_sz = sizeof(struct phy_error_log_request); 2536 + data_in_sz = sizeof(struct phy_error_log_reply); 2537 + sz = data_out_sz + data_in_sz; 2538 + data_out = dma_alloc_coherent(&mrioc->pdev->dev, sz, &data_out_dma, 2539 + GFP_KERNEL); 2540 + if (!data_out) { 2541 + rc = -ENOMEM; 2542 + goto out; 2543 + } 2544 + 2545 + data_in_dma = data_out_dma + data_out_sz; 2546 + phy_error_log_reply = data_out + data_out_sz; 2547 + 2548 + rc = -EINVAL; 2549 + memset(data_out, 0, sz); 2550 + phy_error_log_request = data_out; 2551 + phy_error_log_request->smp_frame_type = 0x40; 2552 + phy_error_log_request->function = 0x11; 2553 + phy_error_log_request->request_length = 2; 2554 + phy_error_log_request->allocated_response_length = 0; 2555 + phy_error_log_request->phy_identifier = phy->number; 2556 + 2557 + memset(&mpi_request, 0, request_sz); 2558 + memset(&mpi_reply, 0, reply_sz); 2559 + mpi_request.host_tag = cpu_to_le16(MPI3MR_HOSTTAG_TRANSPORT_CMDS); 2560 + mpi_request.function = MPI3_FUNCTION_SMP_PASSTHROUGH; 2561 + mpi_request.io_unit_port = (u8) mpi3mr_get_port_id_by_sas_phy(phy); 2562 + mpi_request.sas_address = cpu_to_le64(phy->identify.sas_address); 2563 + 2564 + psge = &mpi_request.request_sge; 2565 + mpi3mr_add_sg_single(psge, sgl_flags, data_out_sz, data_out_dma); 2566 + 2567 + psge = &mpi_request.response_sge; 2568 + mpi3mr_add_sg_single(psge, sgl_flags, data_in_sz, data_in_dma); 2569 + 2570 + dprint_transport_info(mrioc, 2571 + "sending phy error log SMP request to sas_address(0x%016llx), phy_id(%d)\n", 2572 + (unsigned long long)phy->identify.sas_address, phy->number); 2573 + 2574 + if (mpi3mr_post_transport_req(mrioc, &mpi_request, request_sz, 2575 + &mpi_reply, reply_sz, MPI3MR_INTADMCMD_TIMEOUT, &ioc_status)) 2576 + goto out; 2577 + 2578 + dprint_transport_info(mrioc, 2579 + "phy error log SMP request completed with ioc_status(0x%04x)\n", 2580 + ioc_status); 2581 + 2582 + if (ioc_status == MPI3_IOCSTATUS_SUCCESS) { 2583 + dprint_transport_info(mrioc, 2584 + "phy error log - reply data transfer size(%d)\n", 2585 + le16_to_cpu(mpi_reply.response_data_length)); 2586 + 2587 + if (le16_to_cpu(mpi_reply.response_data_length) != 2588 + sizeof(struct phy_error_log_reply)) 2589 + goto out; 2590 + 2591 + dprint_transport_info(mrioc, 2592 + "phy error log - function_result(%d)\n", 2593 + phy_error_log_reply->function_result); 2594 + 2595 + phy->invalid_dword_count = 2596 + be32_to_cpu(phy_error_log_reply->invalid_dword); 2597 + phy->running_disparity_error_count = 2598 + be32_to_cpu(phy_error_log_reply->running_disparity_error); 2599 + phy->loss_of_dword_sync_count = 2600 + be32_to_cpu(phy_error_log_reply->loss_of_dword_sync); 2601 + phy->phy_reset_problem_count = 2602 + be32_to_cpu(phy_error_log_reply->phy_reset_problem); 2603 + rc = 0; 2604 + } 2605 + 2606 + out: 2607 + if (data_out) 2608 + dma_free_coherent(&mrioc->pdev->dev, sz, data_out, 2609 + data_out_dma); 2610 + 2611 + return rc; 2612 + } 2613 + 2614 + /** 2615 + * mpi3mr_transport_get_linkerrors - return phy error counters 2616 + * @phy: The SAS transport layer phy object 2617 + * 2618 + * This function retrieves the phy error log information of the 2619 + * HBA or expander for which the phy belongs to 2620 + * 2621 + * Return: 0 for success, non-zero for failure. 2622 + */ 2623 + static int mpi3mr_transport_get_linkerrors(struct sas_phy *phy) 2624 + { 2625 + struct mpi3mr_ioc *mrioc = phy_to_mrioc(phy); 2626 + struct mpi3_sas_phy_page1 phy_pg1; 2627 + int rc = 0; 2628 + u16 ioc_status; 2629 + 2630 + rc = mpi3mr_parent_present(mrioc, phy); 2631 + if (rc) 2632 + return rc; 2633 + 2634 + if (phy->identify.sas_address != mrioc->sas_hba.sas_address) 2635 + return mpi3mr_get_expander_phy_error_log(mrioc, phy); 2636 + 2637 + memset(&phy_pg1, 0, sizeof(struct mpi3_sas_phy_page1)); 2638 + /* get hba phy error logs */ 2639 + if ((mpi3mr_cfg_get_sas_phy_pg1(mrioc, &ioc_status, &phy_pg1, 2640 + sizeof(struct mpi3_sas_phy_page1), 2641 + MPI3_SAS_PHY_PGAD_FORM_PHY_NUMBER, phy->number))) { 2642 + ioc_err(mrioc, "failure at %s:%d/%s()!\n", 2643 + __FILE__, __LINE__, __func__); 2644 + return -ENXIO; 2645 + } 2646 + 2647 + if (ioc_status != MPI3_IOCSTATUS_SUCCESS) { 2648 + ioc_err(mrioc, "failure at %s:%d/%s()!\n", 2649 + __FILE__, __LINE__, __func__); 2650 + return -ENXIO; 2651 + } 2652 + phy->invalid_dword_count = le32_to_cpu(phy_pg1.invalid_dword_count); 2653 + phy->running_disparity_error_count = 2654 + le32_to_cpu(phy_pg1.running_disparity_error_count); 2655 + phy->loss_of_dword_sync_count = 2656 + le32_to_cpu(phy_pg1.loss_dword_synch_count); 2657 + phy->phy_reset_problem_count = 2658 + le32_to_cpu(phy_pg1.phy_reset_problem_count); 2659 + return 0; 2660 + } 2661 + 2662 + /** 2663 + * mpi3mr_transport_get_enclosure_identifier - Get Enclosure ID 2664 + * @rphy: The SAS transport layer remote phy object 2665 + * @identifier: Enclosure identifier to be returned 2666 + * 2667 + * Returns the enclosure id for the device pointed by the remote 2668 + * phy object. 2669 + * 2670 + * Return: 0 on success or -ENXIO 2671 + */ 2672 + static int 2673 + mpi3mr_transport_get_enclosure_identifier(struct sas_rphy *rphy, 2674 + u64 *identifier) 2675 + { 2676 + struct mpi3mr_ioc *mrioc = rphy_to_mrioc(rphy); 2677 + struct mpi3mr_tgt_dev *tgtdev = NULL; 2678 + unsigned long flags; 2679 + int rc; 2680 + 2681 + spin_lock_irqsave(&mrioc->tgtdev_lock, flags); 2682 + tgtdev = __mpi3mr_get_tgtdev_by_addr_and_rphy(mrioc, 2683 + rphy->identify.sas_address, rphy); 2684 + if (tgtdev) { 2685 + *identifier = 2686 + tgtdev->enclosure_logical_id; 2687 + rc = 0; 2688 + mpi3mr_tgtdev_put(tgtdev); 2689 + } else { 2690 + *identifier = 0; 2691 + rc = -ENXIO; 2692 + } 2693 + spin_unlock_irqrestore(&mrioc->tgtdev_lock, flags); 2694 + 2695 + return rc; 2696 + } 2697 + 2698 + /** 2699 + * mpi3mr_transport_get_bay_identifier - Get bay ID 2700 + * @rphy: The SAS transport layer remote phy object 2701 + * 2702 + * Returns the slot id for the device pointed by the remote phy 2703 + * object. 2704 + * 2705 + * Return: Valid slot ID on success or -ENXIO 2706 + */ 2707 + static int 2708 + mpi3mr_transport_get_bay_identifier(struct sas_rphy *rphy) 2709 + { 2710 + struct mpi3mr_ioc *mrioc = rphy_to_mrioc(rphy); 2711 + struct mpi3mr_tgt_dev *tgtdev = NULL; 2712 + unsigned long flags; 2713 + int rc; 2714 + 2715 + spin_lock_irqsave(&mrioc->tgtdev_lock, flags); 2716 + tgtdev = __mpi3mr_get_tgtdev_by_addr_and_rphy(mrioc, 2717 + rphy->identify.sas_address, rphy); 2718 + if (tgtdev) { 2719 + rc = tgtdev->slot; 2720 + mpi3mr_tgtdev_put(tgtdev); 2721 + } else 2722 + rc = -ENXIO; 2723 + spin_unlock_irqrestore(&mrioc->tgtdev_lock, flags); 2724 + 2725 + return rc; 2726 + } 2727 + 2728 + /* phy control request structure */ 2729 + struct phy_control_request { 2730 + u8 smp_frame_type; /* 0x40 */ 2731 + u8 function; /* 0x91 */ 2732 + u8 allocated_response_length; 2733 + u8 request_length; /* 0x09 */ 2734 + u16 expander_change_count; 2735 + u8 reserved_1[3]; 2736 + u8 phy_identifier; 2737 + u8 phy_operation; 2738 + u8 reserved_2[13]; 2739 + u64 attached_device_name; 2740 + u8 programmed_min_physical_link_rate; 2741 + u8 programmed_max_physical_link_rate; 2742 + u8 reserved_3[6]; 2743 + }; 2744 + 2745 + /* phy control reply structure */ 2746 + struct phy_control_reply { 2747 + u8 smp_frame_type; /* 0x41 */ 2748 + u8 function; /* 0x11 */ 2749 + u8 function_result; 2750 + u8 response_length; 2751 + }; 2752 + 2753 + #define SMP_PHY_CONTROL_LINK_RESET (0x01) 2754 + #define SMP_PHY_CONTROL_HARD_RESET (0x02) 2755 + #define SMP_PHY_CONTROL_DISABLE (0x03) 2756 + 2757 + /** 2758 + * mpi3mr_expander_phy_control - expander phy control 2759 + * @mrioc: Adapter instance reference 2760 + * @phy: The SAS transport layer phy object 2761 + * @phy_operation: The phy operation to be executed 2762 + * 2763 + * Issues SMP passthru phy control request to execute a specific 2764 + * phy operation for a given expander device. 2765 + * 2766 + * Return: 0 for success, non-zero for failure. 2767 + */ 2768 + static int 2769 + mpi3mr_expander_phy_control(struct mpi3mr_ioc *mrioc, 2770 + struct sas_phy *phy, u8 phy_operation) 2771 + { 2772 + struct mpi3_smp_passthrough_request mpi_request; 2773 + struct mpi3_smp_passthrough_reply mpi_reply; 2774 + struct phy_control_request *phy_control_request; 2775 + struct phy_control_reply *phy_control_reply; 2776 + int rc; 2777 + void *psge; 2778 + void *data_out = NULL; 2779 + dma_addr_t data_out_dma; 2780 + dma_addr_t data_in_dma; 2781 + size_t data_in_sz; 2782 + size_t data_out_sz; 2783 + u8 sgl_flags = MPI3MR_SGEFLAGS_SYSTEM_SIMPLE_END_OF_LIST; 2784 + u16 request_sz = sizeof(struct mpi3_smp_passthrough_request); 2785 + u16 reply_sz = sizeof(struct mpi3_smp_passthrough_reply); 2786 + u16 ioc_status; 2787 + u16 sz; 2788 + 2789 + if (mrioc->reset_in_progress) { 2790 + ioc_err(mrioc, "%s: host reset in progress!\n", __func__); 2791 + return -EFAULT; 2792 + } 2793 + 2794 + data_out_sz = sizeof(struct phy_control_request); 2795 + data_in_sz = sizeof(struct phy_control_reply); 2796 + sz = data_out_sz + data_in_sz; 2797 + data_out = dma_alloc_coherent(&mrioc->pdev->dev, sz, &data_out_dma, 2798 + GFP_KERNEL); 2799 + if (!data_out) { 2800 + rc = -ENOMEM; 2801 + goto out; 2802 + } 2803 + 2804 + data_in_dma = data_out_dma + data_out_sz; 2805 + phy_control_reply = data_out + data_out_sz; 2806 + 2807 + rc = -EINVAL; 2808 + memset(data_out, 0, sz); 2809 + 2810 + phy_control_request = data_out; 2811 + phy_control_request->smp_frame_type = 0x40; 2812 + phy_control_request->function = 0x91; 2813 + phy_control_request->request_length = 9; 2814 + phy_control_request->allocated_response_length = 0; 2815 + phy_control_request->phy_identifier = phy->number; 2816 + phy_control_request->phy_operation = phy_operation; 2817 + phy_control_request->programmed_min_physical_link_rate = 2818 + phy->minimum_linkrate << 4; 2819 + phy_control_request->programmed_max_physical_link_rate = 2820 + phy->maximum_linkrate << 4; 2821 + 2822 + memset(&mpi_request, 0, request_sz); 2823 + memset(&mpi_reply, 0, reply_sz); 2824 + mpi_request.host_tag = cpu_to_le16(MPI3MR_HOSTTAG_TRANSPORT_CMDS); 2825 + mpi_request.function = MPI3_FUNCTION_SMP_PASSTHROUGH; 2826 + mpi_request.io_unit_port = (u8) mpi3mr_get_port_id_by_sas_phy(phy); 2827 + mpi_request.sas_address = cpu_to_le64(phy->identify.sas_address); 2828 + 2829 + psge = &mpi_request.request_sge; 2830 + mpi3mr_add_sg_single(psge, sgl_flags, data_out_sz, data_out_dma); 2831 + 2832 + psge = &mpi_request.response_sge; 2833 + mpi3mr_add_sg_single(psge, sgl_flags, data_in_sz, data_in_dma); 2834 + 2835 + dprint_transport_info(mrioc, 2836 + "sending phy control SMP request to sas_address(0x%016llx), phy_id(%d) opcode(%d)\n", 2837 + (unsigned long long)phy->identify.sas_address, phy->number, 2838 + phy_operation); 2839 + 2840 + if (mpi3mr_post_transport_req(mrioc, &mpi_request, request_sz, 2841 + &mpi_reply, reply_sz, MPI3MR_INTADMCMD_TIMEOUT, &ioc_status)) 2842 + goto out; 2843 + 2844 + dprint_transport_info(mrioc, 2845 + "phy control SMP request completed with ioc_status(0x%04x)\n", 2846 + ioc_status); 2847 + 2848 + if (ioc_status == MPI3_IOCSTATUS_SUCCESS) { 2849 + dprint_transport_info(mrioc, 2850 + "phy control - reply data transfer size(%d)\n", 2851 + le16_to_cpu(mpi_reply.response_data_length)); 2852 + 2853 + if (le16_to_cpu(mpi_reply.response_data_length) != 2854 + sizeof(struct phy_control_reply)) 2855 + goto out; 2856 + dprint_transport_info(mrioc, 2857 + "phy control - function_result(%d)\n", 2858 + phy_control_reply->function_result); 2859 + rc = 0; 2860 + } 2861 + out: 2862 + if (data_out) 2863 + dma_free_coherent(&mrioc->pdev->dev, sz, data_out, 2864 + data_out_dma); 2865 + 2866 + return rc; 2867 + } 2868 + 2869 + /** 2870 + * mpi3mr_transport_phy_reset - Reset a given phy 2871 + * @phy: The SAS transport layer phy object 2872 + * @hard_reset: Flag to indicate the type of reset 2873 + * 2874 + * Return: 0 for success, non-zero for failure. 2875 + */ 2876 + static int 2877 + mpi3mr_transport_phy_reset(struct sas_phy *phy, int hard_reset) 2878 + { 2879 + struct mpi3mr_ioc *mrioc = phy_to_mrioc(phy); 2880 + struct mpi3_iounit_control_request mpi_request; 2881 + struct mpi3_iounit_control_reply mpi_reply; 2882 + u16 request_sz = sizeof(struct mpi3_iounit_control_request); 2883 + u16 reply_sz = sizeof(struct mpi3_iounit_control_reply); 2884 + int rc = 0; 2885 + u16 ioc_status; 2886 + 2887 + rc = mpi3mr_parent_present(mrioc, phy); 2888 + if (rc) 2889 + return rc; 2890 + 2891 + /* handle expander phys */ 2892 + if (phy->identify.sas_address != mrioc->sas_hba.sas_address) 2893 + return mpi3mr_expander_phy_control(mrioc, phy, 2894 + (hard_reset == 1) ? SMP_PHY_CONTROL_HARD_RESET : 2895 + SMP_PHY_CONTROL_LINK_RESET); 2896 + 2897 + /* handle hba phys */ 2898 + memset(&mpi_request, 0, request_sz); 2899 + mpi_request.host_tag = cpu_to_le16(MPI3MR_HOSTTAG_TRANSPORT_CMDS); 2900 + mpi_request.function = MPI3_FUNCTION_IO_UNIT_CONTROL; 2901 + mpi_request.operation = MPI3_CTRL_OP_SAS_PHY_CONTROL; 2902 + mpi_request.param8[MPI3_CTRL_OP_SAS_PHY_CONTROL_PARAM8_ACTION_INDEX] = 2903 + (hard_reset ? MPI3_CTRL_ACTION_HARD_RESET : 2904 + MPI3_CTRL_ACTION_LINK_RESET); 2905 + mpi_request.param8[MPI3_CTRL_OP_SAS_PHY_CONTROL_PARAM8_PHY_INDEX] = 2906 + phy->number; 2907 + 2908 + dprint_transport_info(mrioc, 2909 + "sending phy reset request to sas_address(0x%016llx), phy_id(%d) hard_reset(%d)\n", 2910 + (unsigned long long)phy->identify.sas_address, phy->number, 2911 + hard_reset); 2912 + 2913 + if (mpi3mr_post_transport_req(mrioc, &mpi_request, request_sz, 2914 + &mpi_reply, reply_sz, MPI3MR_INTADMCMD_TIMEOUT, &ioc_status)) { 2915 + rc = -EAGAIN; 2916 + goto out; 2917 + } 2918 + 2919 + dprint_transport_info(mrioc, 2920 + "phy reset request completed with ioc_status(0x%04x)\n", 2921 + ioc_status); 2922 + out: 2923 + return rc; 2924 + } 2925 + 2926 + /** 2927 + * mpi3mr_transport_phy_enable - enable/disable phys 2928 + * @phy: The SAS transport layer phy object 2929 + * @enable: flag to enable/disable, enable phy when true 2930 + * 2931 + * This function enables/disables a given by executing required 2932 + * configuration page changes or expander phy control command 2933 + * 2934 + * Return: 0 for success, non-zero for failure. 2935 + */ 2936 + static int 2937 + mpi3mr_transport_phy_enable(struct sas_phy *phy, int enable) 2938 + { 2939 + struct mpi3mr_ioc *mrioc = phy_to_mrioc(phy); 2940 + struct mpi3_sas_io_unit_page0 *sas_io_unit_pg0 = NULL; 2941 + struct mpi3_sas_io_unit_page1 *sas_io_unit_pg1 = NULL; 2942 + u16 sz; 2943 + int rc = 0; 2944 + int i, discovery_active; 2945 + 2946 + rc = mpi3mr_parent_present(mrioc, phy); 2947 + if (rc) 2948 + return rc; 2949 + 2950 + /* handle expander phys */ 2951 + if (phy->identify.sas_address != mrioc->sas_hba.sas_address) 2952 + return mpi3mr_expander_phy_control(mrioc, phy, 2953 + (enable == 1) ? SMP_PHY_CONTROL_LINK_RESET : 2954 + SMP_PHY_CONTROL_DISABLE); 2955 + 2956 + /* handle hba phys */ 2957 + sz = offsetof(struct mpi3_sas_io_unit_page0, phy_data) + 2958 + (mrioc->sas_hba.num_phys * 2959 + sizeof(struct mpi3_sas_io_unit0_phy_data)); 2960 + sas_io_unit_pg0 = kzalloc(sz, GFP_KERNEL); 2961 + if (!sas_io_unit_pg0) { 2962 + rc = -ENOMEM; 2963 + goto out; 2964 + } 2965 + if (mpi3mr_cfg_get_sas_io_unit_pg0(mrioc, sas_io_unit_pg0, sz)) { 2966 + ioc_err(mrioc, "failure at %s:%d/%s()!\n", 2967 + __FILE__, __LINE__, __func__); 2968 + rc = -ENXIO; 2969 + goto out; 2970 + } 2971 + 2972 + /* unable to enable/disable phys when discovery is active */ 2973 + for (i = 0, discovery_active = 0; i < mrioc->sas_hba.num_phys ; i++) { 2974 + if (sas_io_unit_pg0->phy_data[i].port_flags & 2975 + MPI3_SASIOUNIT0_PORTFLAGS_DISC_IN_PROGRESS) { 2976 + ioc_err(mrioc, 2977 + "discovery is active on port = %d, phy = %d\n" 2978 + "\tunable to enable/disable phys, try again later!\n", 2979 + sas_io_unit_pg0->phy_data[i].io_unit_port, i); 2980 + discovery_active = 1; 2981 + } 2982 + } 2983 + 2984 + if (discovery_active) { 2985 + rc = -EAGAIN; 2986 + goto out; 2987 + } 2988 + 2989 + if ((sas_io_unit_pg0->phy_data[phy->number].phy_flags & 2990 + (MPI3_SASIOUNIT0_PHYFLAGS_HOST_PHY | 2991 + MPI3_SASIOUNIT0_PHYFLAGS_VIRTUAL_PHY))) { 2992 + ioc_err(mrioc, "failure at %s:%d/%s()!\n", 2993 + __FILE__, __LINE__, __func__); 2994 + rc = -ENXIO; 2995 + goto out; 2996 + } 2997 + 2998 + /* read sas_iounit page 1 */ 2999 + sz = offsetof(struct mpi3_sas_io_unit_page1, phy_data) + 3000 + (mrioc->sas_hba.num_phys * 3001 + sizeof(struct mpi3_sas_io_unit1_phy_data)); 3002 + sas_io_unit_pg1 = kzalloc(sz, GFP_KERNEL); 3003 + if (!sas_io_unit_pg1) { 3004 + rc = -ENOMEM; 3005 + goto out; 3006 + } 3007 + 3008 + if (mpi3mr_cfg_get_sas_io_unit_pg1(mrioc, sas_io_unit_pg1, sz)) { 3009 + ioc_err(mrioc, "failure at %s:%d/%s()!\n", 3010 + __FILE__, __LINE__, __func__); 3011 + rc = -ENXIO; 3012 + goto out; 3013 + } 3014 + 3015 + if (enable) 3016 + sas_io_unit_pg1->phy_data[phy->number].phy_flags 3017 + &= ~MPI3_SASIOUNIT1_PHYFLAGS_PHY_DISABLE; 3018 + else 3019 + sas_io_unit_pg1->phy_data[phy->number].phy_flags 3020 + |= MPI3_SASIOUNIT1_PHYFLAGS_PHY_DISABLE; 3021 + 3022 + mpi3mr_cfg_set_sas_io_unit_pg1(mrioc, sas_io_unit_pg1, sz); 3023 + 3024 + /* link reset */ 3025 + if (enable) 3026 + mpi3mr_transport_phy_reset(phy, 0); 3027 + 3028 + out: 3029 + kfree(sas_io_unit_pg1); 3030 + kfree(sas_io_unit_pg0); 3031 + return rc; 3032 + } 3033 + 3034 + /** 3035 + * mpi3mr_transport_phy_speed - set phy min/max speed 3036 + * @phy: The SAS transport later phy object 3037 + * @rates: Rates defined as in sas_phy_linkrates 3038 + * 3039 + * This function sets the link rates given in the rates 3040 + * argument to the given phy by executing required configuration 3041 + * page changes or expander phy control command 3042 + * 3043 + * Return: 0 for success, non-zero for failure. 3044 + */ 3045 + static int 3046 + mpi3mr_transport_phy_speed(struct sas_phy *phy, struct sas_phy_linkrates *rates) 3047 + { 3048 + struct mpi3mr_ioc *mrioc = phy_to_mrioc(phy); 3049 + struct mpi3_sas_io_unit_page1 *sas_io_unit_pg1 = NULL; 3050 + struct mpi3_sas_phy_page0 phy_pg0; 3051 + u16 sz, ioc_status; 3052 + int rc = 0; 3053 + 3054 + rc = mpi3mr_parent_present(mrioc, phy); 3055 + if (rc) 3056 + return rc; 3057 + 3058 + if (!rates->minimum_linkrate) 3059 + rates->minimum_linkrate = phy->minimum_linkrate; 3060 + else if (rates->minimum_linkrate < phy->minimum_linkrate_hw) 3061 + rates->minimum_linkrate = phy->minimum_linkrate_hw; 3062 + 3063 + if (!rates->maximum_linkrate) 3064 + rates->maximum_linkrate = phy->maximum_linkrate; 3065 + else if (rates->maximum_linkrate > phy->maximum_linkrate_hw) 3066 + rates->maximum_linkrate = phy->maximum_linkrate_hw; 3067 + 3068 + /* handle expander phys */ 3069 + if (phy->identify.sas_address != mrioc->sas_hba.sas_address) { 3070 + phy->minimum_linkrate = rates->minimum_linkrate; 3071 + phy->maximum_linkrate = rates->maximum_linkrate; 3072 + return mpi3mr_expander_phy_control(mrioc, phy, 3073 + SMP_PHY_CONTROL_LINK_RESET); 3074 + } 3075 + 3076 + /* handle hba phys */ 3077 + sz = offsetof(struct mpi3_sas_io_unit_page1, phy_data) + 3078 + (mrioc->sas_hba.num_phys * 3079 + sizeof(struct mpi3_sas_io_unit1_phy_data)); 3080 + sas_io_unit_pg1 = kzalloc(sz, GFP_KERNEL); 3081 + if (!sas_io_unit_pg1) { 3082 + rc = -ENOMEM; 3083 + goto out; 3084 + } 3085 + 3086 + if (mpi3mr_cfg_get_sas_io_unit_pg1(mrioc, sas_io_unit_pg1, sz)) { 3087 + ioc_err(mrioc, "failure at %s:%d/%s()!\n", 3088 + __FILE__, __LINE__, __func__); 3089 + rc = -ENXIO; 3090 + goto out; 3091 + } 3092 + 3093 + sas_io_unit_pg1->phy_data[phy->number].max_min_link_rate = 3094 + (rates->minimum_linkrate + (rates->maximum_linkrate << 4)); 3095 + 3096 + if (mpi3mr_cfg_set_sas_io_unit_pg1(mrioc, sas_io_unit_pg1, sz)) { 3097 + ioc_err(mrioc, "failure at %s:%d/%s()!\n", 3098 + __FILE__, __LINE__, __func__); 3099 + rc = -ENXIO; 3100 + goto out; 3101 + } 3102 + 3103 + /* link reset */ 3104 + mpi3mr_transport_phy_reset(phy, 0); 3105 + 3106 + /* read phy page 0, then update the rates in the sas transport phy */ 3107 + if (!mpi3mr_cfg_get_sas_phy_pg0(mrioc, &ioc_status, &phy_pg0, 3108 + sizeof(struct mpi3_sas_phy_page0), 3109 + MPI3_SAS_PHY_PGAD_FORM_PHY_NUMBER, phy->number) && 3110 + (ioc_status == MPI3_IOCSTATUS_SUCCESS)) { 3111 + phy->minimum_linkrate = mpi3mr_convert_phy_link_rate( 3112 + phy_pg0.programmed_link_rate & 3113 + MPI3_SAS_PRATE_MIN_RATE_MASK); 3114 + phy->maximum_linkrate = mpi3mr_convert_phy_link_rate( 3115 + phy_pg0.programmed_link_rate >> 4); 3116 + phy->negotiated_linkrate = 3117 + mpi3mr_convert_phy_link_rate( 3118 + (phy_pg0.negotiated_link_rate & 3119 + MPI3_SAS_NEG_LINK_RATE_LOGICAL_MASK) 3120 + >> MPI3_SAS_NEG_LINK_RATE_LOGICAL_SHIFT); 3121 + } 3122 + 3123 + out: 3124 + kfree(sas_io_unit_pg1); 3125 + return rc; 3126 + } 3127 + 3128 + /** 3129 + * mpi3mr_map_smp_buffer - map BSG dma buffer 3130 + * @dev: Generic device reference 3131 + * @buf: BSG buffer pointer 3132 + * @dma_addr: Physical address holder 3133 + * @dma_len: Mapped DMA buffer length. 3134 + * @p: Virtual address holder 3135 + * 3136 + * This function maps the DMAable buffer 3137 + * 3138 + * Return: 0 on success, non-zero on failure 3139 + */ 3140 + static int 3141 + mpi3mr_map_smp_buffer(struct device *dev, struct bsg_buffer *buf, 3142 + dma_addr_t *dma_addr, size_t *dma_len, void **p) 3143 + { 3144 + /* Check if the request is split across multiple segments */ 3145 + if (buf->sg_cnt > 1) { 3146 + *p = dma_alloc_coherent(dev, buf->payload_len, dma_addr, 3147 + GFP_KERNEL); 3148 + if (!*p) 3149 + return -ENOMEM; 3150 + *dma_len = buf->payload_len; 3151 + } else { 3152 + if (!dma_map_sg(dev, buf->sg_list, 1, DMA_BIDIRECTIONAL)) 3153 + return -ENOMEM; 3154 + *dma_addr = sg_dma_address(buf->sg_list); 3155 + *dma_len = sg_dma_len(buf->sg_list); 3156 + *p = NULL; 3157 + } 3158 + 3159 + return 0; 3160 + } 3161 + 3162 + /** 3163 + * mpi3mr_unmap_smp_buffer - unmap BSG dma buffer 3164 + * @dev: Generic device reference 3165 + * @buf: BSG buffer pointer 3166 + * @dma_addr: Physical address to be unmapped 3167 + * @p: Virtual address 3168 + * 3169 + * This function unmaps the DMAable buffer 3170 + */ 3171 + static void 3172 + mpi3mr_unmap_smp_buffer(struct device *dev, struct bsg_buffer *buf, 3173 + dma_addr_t dma_addr, void *p) 3174 + { 3175 + if (p) 3176 + dma_free_coherent(dev, buf->payload_len, p, dma_addr); 3177 + else 3178 + dma_unmap_sg(dev, buf->sg_list, 1, DMA_BIDIRECTIONAL); 3179 + } 3180 + 3181 + /** 3182 + * mpi3mr_transport_smp_handler - handler for smp passthru 3183 + * @job: BSG job reference 3184 + * @shost: SCSI host object reference 3185 + * @rphy: SAS transport rphy object pointing the expander 3186 + * 3187 + * This is used primarily by smp utils for sending the SMP 3188 + * commands to the expanders attached to the controller 3189 + */ 3190 + static void 3191 + mpi3mr_transport_smp_handler(struct bsg_job *job, struct Scsi_Host *shost, 3192 + struct sas_rphy *rphy) 3193 + { 3194 + struct mpi3mr_ioc *mrioc = shost_priv(shost); 3195 + struct mpi3_smp_passthrough_request mpi_request; 3196 + struct mpi3_smp_passthrough_reply mpi_reply; 3197 + int rc; 3198 + void *psge; 3199 + dma_addr_t dma_addr_in; 3200 + dma_addr_t dma_addr_out; 3201 + void *addr_in = NULL; 3202 + void *addr_out = NULL; 3203 + size_t dma_len_in; 3204 + size_t dma_len_out; 3205 + unsigned int reslen = 0; 3206 + u16 request_sz = sizeof(struct mpi3_smp_passthrough_request); 3207 + u16 reply_sz = sizeof(struct mpi3_smp_passthrough_reply); 3208 + u8 sgl_flags = MPI3MR_SGEFLAGS_SYSTEM_SIMPLE_END_OF_LIST; 3209 + u16 ioc_status; 3210 + 3211 + if (mrioc->reset_in_progress) { 3212 + ioc_err(mrioc, "%s: host reset in progress!\n", __func__); 3213 + rc = -EFAULT; 3214 + goto out; 3215 + } 3216 + 3217 + rc = mpi3mr_map_smp_buffer(&mrioc->pdev->dev, &job->request_payload, 3218 + &dma_addr_out, &dma_len_out, &addr_out); 3219 + if (rc) 3220 + goto out; 3221 + 3222 + if (addr_out) 3223 + sg_copy_to_buffer(job->request_payload.sg_list, 3224 + job->request_payload.sg_cnt, addr_out, 3225 + job->request_payload.payload_len); 3226 + 3227 + rc = mpi3mr_map_smp_buffer(&mrioc->pdev->dev, &job->reply_payload, 3228 + &dma_addr_in, &dma_len_in, &addr_in); 3229 + if (rc) 3230 + goto unmap_out; 3231 + 3232 + memset(&mpi_request, 0, request_sz); 3233 + memset(&mpi_reply, 0, reply_sz); 3234 + mpi_request.host_tag = cpu_to_le16(MPI3MR_HOSTTAG_TRANSPORT_CMDS); 3235 + mpi_request.function = MPI3_FUNCTION_SMP_PASSTHROUGH; 3236 + mpi_request.io_unit_port = (u8) mpi3mr_get_port_id_by_rphy(mrioc, rphy); 3237 + mpi_request.sas_address = ((rphy) ? 3238 + cpu_to_le64(rphy->identify.sas_address) : 3239 + cpu_to_le64(mrioc->sas_hba.sas_address)); 3240 + psge = &mpi_request.request_sge; 3241 + mpi3mr_add_sg_single(psge, sgl_flags, dma_len_out - 4, dma_addr_out); 3242 + 3243 + psge = &mpi_request.response_sge; 3244 + mpi3mr_add_sg_single(psge, sgl_flags, dma_len_in - 4, dma_addr_in); 3245 + 3246 + dprint_transport_info(mrioc, "sending SMP request\n"); 3247 + 3248 + rc = mpi3mr_post_transport_req(mrioc, &mpi_request, request_sz, 3249 + &mpi_reply, reply_sz, 3250 + MPI3MR_INTADMCMD_TIMEOUT, &ioc_status); 3251 + if (rc) 3252 + goto unmap_in; 3253 + 3254 + dprint_transport_info(mrioc, 3255 + "SMP request completed with ioc_status(0x%04x)\n", ioc_status); 3256 + 3257 + dprint_transport_info(mrioc, 3258 + "SMP request - reply data transfer size(%d)\n", 3259 + le16_to_cpu(mpi_reply.response_data_length)); 3260 + 3261 + memcpy(job->reply, &mpi_reply, reply_sz); 3262 + job->reply_len = reply_sz; 3263 + reslen = le16_to_cpu(mpi_reply.response_data_length); 3264 + 3265 + if (addr_in) 3266 + sg_copy_from_buffer(job->reply_payload.sg_list, 3267 + job->reply_payload.sg_cnt, addr_in, 3268 + job->reply_payload.payload_len); 3269 + 3270 + rc = 0; 3271 + unmap_in: 3272 + mpi3mr_unmap_smp_buffer(&mrioc->pdev->dev, &job->reply_payload, 3273 + dma_addr_in, addr_in); 3274 + unmap_out: 3275 + mpi3mr_unmap_smp_buffer(&mrioc->pdev->dev, &job->request_payload, 3276 + dma_addr_out, addr_out); 3277 + out: 3278 + bsg_job_done(job, rc, reslen); 3279 + } 3280 + 3281 + struct sas_function_template mpi3mr_transport_functions = { 3282 + .get_linkerrors = mpi3mr_transport_get_linkerrors, 3283 + .get_enclosure_identifier = mpi3mr_transport_get_enclosure_identifier, 3284 + .get_bay_identifier = mpi3mr_transport_get_bay_identifier, 3285 + .phy_reset = mpi3mr_transport_phy_reset, 3286 + .phy_enable = mpi3mr_transport_phy_enable, 3287 + .set_phy_speed = mpi3mr_transport_phy_speed, 3288 + .smp_handler = mpi3mr_transport_smp_handler, 3289 + }; 3290 + 3291 + struct scsi_transport_template *mpi3mr_transport_template;
+1
drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h
··· 534 534 ****************************************************************************/ 535 535 536 536 #define MPI2_MFGPAGE_VENDORID_LSI (0x1000) 537 + #define MPI2_MFGPAGE_VENDORID_ATTO (0x117C) 537 538 538 539 /*MPI v2.0 SAS products */ 539 540 #define MPI2_MFGPAGE_DEVID_SAS2004 (0x0070)
+193 -24
drivers/scsi/mpt3sas/mpt3sas_base.c
··· 2990 2990 _base_config_dma_addressing(struct MPT3SAS_ADAPTER *ioc, struct pci_dev *pdev) 2991 2991 { 2992 2992 struct sysinfo s; 2993 + u64 coherent_dma_mask, dma_mask; 2993 2994 2994 - if (ioc->is_mcpu_endpoint || 2995 - sizeof(dma_addr_t) == 4 || ioc->use_32bit_dma || 2996 - dma_get_required_mask(&pdev->dev) <= DMA_BIT_MASK(32)) 2995 + if (ioc->is_mcpu_endpoint || sizeof(dma_addr_t) == 4 || 2996 + dma_get_required_mask(&pdev->dev) <= 32) { 2997 2997 ioc->dma_mask = 32; 2998 + coherent_dma_mask = dma_mask = DMA_BIT_MASK(32); 2998 2999 /* Set 63 bit DMA mask for all SAS3 and SAS35 controllers */ 2999 - else if (ioc->hba_mpi_version_belonged > MPI2_VERSION) 3000 + } else if (ioc->hba_mpi_version_belonged > MPI2_VERSION) { 3000 3001 ioc->dma_mask = 63; 3001 - else 3002 + coherent_dma_mask = dma_mask = DMA_BIT_MASK(63); 3003 + } else { 3002 3004 ioc->dma_mask = 64; 3005 + coherent_dma_mask = dma_mask = DMA_BIT_MASK(64); 3006 + } 3003 3007 3004 - if (dma_set_mask(&pdev->dev, DMA_BIT_MASK(ioc->dma_mask)) || 3005 - dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(ioc->dma_mask))) 3008 + if (ioc->use_32bit_dma) 3009 + coherent_dma_mask = DMA_BIT_MASK(32); 3010 + 3011 + if (dma_set_mask(&pdev->dev, dma_mask) || 3012 + dma_set_coherent_mask(&pdev->dev, coherent_dma_mask)) 3006 3013 return -ENODEV; 3007 3014 3008 3015 if (ioc->dma_mask > 32) { ··· 4320 4313 descriptor.MSIxIndex = _base_set_and_get_msix_index(ioc, smid); 4321 4314 descriptor.SMID = cpu_to_le16(smid); 4322 4315 4323 - writel(*request, &ioc->chip->AtomicRequestDescriptorPost); 4316 + writel(cpu_to_le32(*request), &ioc->chip->AtomicRequestDescriptorPost); 4324 4317 } 4325 4318 4326 4319 /** ··· 4342 4335 descriptor.MSIxIndex = _base_set_and_get_msix_index(ioc, smid); 4343 4336 descriptor.SMID = cpu_to_le16(smid); 4344 4337 4345 - writel(*request, &ioc->chip->AtomicRequestDescriptorPost); 4338 + writel(cpu_to_le32(*request), &ioc->chip->AtomicRequestDescriptorPost); 4346 4339 } 4347 4340 4348 4341 /** ··· 4365 4358 descriptor.MSIxIndex = msix_task; 4366 4359 descriptor.SMID = cpu_to_le16(smid); 4367 4360 4368 - writel(*request, &ioc->chip->AtomicRequestDescriptorPost); 4361 + writel(cpu_to_le32(*request), &ioc->chip->AtomicRequestDescriptorPost); 4369 4362 } 4370 4363 4371 4364 /** ··· 4386 4379 descriptor.MSIxIndex = _base_set_and_get_msix_index(ioc, smid); 4387 4380 descriptor.SMID = cpu_to_le16(smid); 4388 4381 4389 - writel(*request, &ioc->chip->AtomicRequestDescriptorPost); 4382 + writel(cpu_to_le32(*request), &ioc->chip->AtomicRequestDescriptorPost); 4390 4383 } 4391 4384 4392 4385 /** ··· 5432 5425 } 5433 5426 5434 5427 /** 5428 + * mpt3sas_atto_validate_nvram - validate the ATTO nvram read from mfg pg1 5429 + * 5430 + * @ioc : per adapter object 5431 + * @n : ptr to the ATTO nvram structure 5432 + * Return: 0 for success, non-zero for failure. 5433 + */ 5434 + static int 5435 + mpt3sas_atto_validate_nvram(struct MPT3SAS_ADAPTER *ioc, 5436 + struct ATTO_SAS_NVRAM *n) 5437 + { 5438 + int r = -EINVAL; 5439 + union ATTO_SAS_ADDRESS *s1; 5440 + u32 len; 5441 + u8 *pb; 5442 + u8 ckSum; 5443 + 5444 + /* validate nvram checksum */ 5445 + pb = (u8 *) n; 5446 + ckSum = ATTO_SASNVR_CKSUM_SEED; 5447 + len = sizeof(struct ATTO_SAS_NVRAM); 5448 + 5449 + while (len--) 5450 + ckSum = ckSum + pb[len]; 5451 + 5452 + if (ckSum) { 5453 + ioc_err(ioc, "Invalid ATTO NVRAM checksum\n"); 5454 + return r; 5455 + } 5456 + 5457 + s1 = (union ATTO_SAS_ADDRESS *) n->SasAddr; 5458 + 5459 + if (n->Signature[0] != 'E' 5460 + || n->Signature[1] != 'S' 5461 + || n->Signature[2] != 'A' 5462 + || n->Signature[3] != 'S') 5463 + ioc_err(ioc, "Invalid ATTO NVRAM signature\n"); 5464 + else if (n->Version > ATTO_SASNVR_VERSION) 5465 + ioc_info(ioc, "Invalid ATTO NVRAM version"); 5466 + else if ((n->SasAddr[7] & (ATTO_SAS_ADDR_ALIGN - 1)) 5467 + || s1->b[0] != 0x50 5468 + || s1->b[1] != 0x01 5469 + || s1->b[2] != 0x08 5470 + || (s1->b[3] & 0xF0) != 0x60 5471 + || ((s1->b[3] & 0x0F) | le32_to_cpu(s1->d[1])) == 0) { 5472 + ioc_err(ioc, "Invalid ATTO SAS address\n"); 5473 + } else 5474 + r = 0; 5475 + return r; 5476 + } 5477 + 5478 + /** 5479 + * mpt3sas_atto_get_sas_addr - get the ATTO SAS address from mfg page 1 5480 + * 5481 + * @ioc : per adapter object 5482 + * @*sas_addr : return sas address 5483 + * Return: 0 for success, non-zero for failure. 5484 + */ 5485 + static int 5486 + mpt3sas_atto_get_sas_addr(struct MPT3SAS_ADAPTER *ioc, union ATTO_SAS_ADDRESS *sas_addr) 5487 + { 5488 + Mpi2ManufacturingPage1_t mfg_pg1; 5489 + Mpi2ConfigReply_t mpi_reply; 5490 + struct ATTO_SAS_NVRAM *nvram; 5491 + int r; 5492 + __be64 addr; 5493 + 5494 + r = mpt3sas_config_get_manufacturing_pg1(ioc, &mpi_reply, &mfg_pg1); 5495 + if (r) { 5496 + ioc_err(ioc, "Failed to read manufacturing page 1\n"); 5497 + return r; 5498 + } 5499 + 5500 + /* validate nvram */ 5501 + nvram = (struct ATTO_SAS_NVRAM *) mfg_pg1.VPD; 5502 + r = mpt3sas_atto_validate_nvram(ioc, nvram); 5503 + if (r) 5504 + return r; 5505 + 5506 + addr = *((__be64 *) nvram->SasAddr); 5507 + sas_addr->q = cpu_to_le64(be64_to_cpu(addr)); 5508 + return r; 5509 + } 5510 + 5511 + /** 5512 + * mpt3sas_atto_init - perform initializaion for ATTO branded 5513 + * adapter. 5514 + * @ioc : per adapter object 5515 + *5 5516 + * Return: 0 for success, non-zero for failure. 5517 + */ 5518 + static int 5519 + mpt3sas_atto_init(struct MPT3SAS_ADAPTER *ioc) 5520 + { 5521 + int sz = 0; 5522 + Mpi2BiosPage4_t *bios_pg4 = NULL; 5523 + Mpi2ConfigReply_t mpi_reply; 5524 + int r; 5525 + int ix; 5526 + union ATTO_SAS_ADDRESS sas_addr; 5527 + union ATTO_SAS_ADDRESS temp; 5528 + union ATTO_SAS_ADDRESS bias; 5529 + 5530 + r = mpt3sas_atto_get_sas_addr(ioc, &sas_addr); 5531 + if (r) 5532 + return r; 5533 + 5534 + /* get header first to get size */ 5535 + r = mpt3sas_config_get_bios_pg4(ioc, &mpi_reply, NULL, 0); 5536 + if (r) { 5537 + ioc_err(ioc, "Failed to read ATTO bios page 4 header.\n"); 5538 + return r; 5539 + } 5540 + 5541 + sz = mpi_reply.Header.PageLength * sizeof(u32); 5542 + bios_pg4 = kzalloc(sz, GFP_KERNEL); 5543 + if (!bios_pg4) { 5544 + ioc_err(ioc, "Failed to allocate memory for ATTO bios page.\n"); 5545 + return -ENOMEM; 5546 + } 5547 + 5548 + /* read bios page 4 */ 5549 + r = mpt3sas_config_get_bios_pg4(ioc, &mpi_reply, bios_pg4, sz); 5550 + if (r) { 5551 + ioc_err(ioc, "Failed to read ATTO bios page 4\n"); 5552 + goto out; 5553 + } 5554 + 5555 + /* Update bios page 4 with the ATTO WWID */ 5556 + bias.q = sas_addr.q; 5557 + bias.b[7] += ATTO_SAS_ADDR_DEVNAME_BIAS; 5558 + 5559 + for (ix = 0; ix < bios_pg4->NumPhys; ix++) { 5560 + temp.q = sas_addr.q; 5561 + temp.b[7] += ix; 5562 + bios_pg4->Phy[ix].ReassignmentWWID = temp.q; 5563 + bios_pg4->Phy[ix].ReassignmentDeviceName = bias.q; 5564 + } 5565 + r = mpt3sas_config_set_bios_pg4(ioc, &mpi_reply, bios_pg4, sz); 5566 + 5567 + out: 5568 + kfree(bios_pg4); 5569 + return r; 5570 + } 5571 + 5572 + /** 5435 5573 * _base_static_config_pages - static start of day config pages 5436 5574 * @ioc: per adapter object 5437 5575 */ ··· 5599 5447 if (rc) 5600 5448 return rc; 5601 5449 } 5450 + 5451 + if (ioc->pdev->vendor == MPI2_MFGPAGE_VENDORID_ATTO) { 5452 + rc = mpt3sas_atto_init(ioc); 5453 + if (rc) 5454 + return rc; 5455 + } 5456 + 5602 5457 /* 5603 5458 * Ensure correct T10 PI operation if vendor left EEDPTagMode 5604 5459 * flag unset in NVDATA. ··· 5655 5496 rc = _base_assign_fw_reported_qd(ioc); 5656 5497 if (rc) 5657 5498 return rc; 5658 - rc = mpt3sas_config_get_bios_pg2(ioc, &mpi_reply, &ioc->bios_pg2); 5659 - if (rc) 5660 - return rc; 5661 - rc = mpt3sas_config_get_bios_pg3(ioc, &mpi_reply, &ioc->bios_pg3); 5662 - if (rc) 5663 - return rc; 5499 + 5500 + /* 5501 + * ATTO doesn't use bios page 2 and 3 for bios settings. 5502 + */ 5503 + if (ioc->pdev->vendor == MPI2_MFGPAGE_VENDORID_ATTO) 5504 + ioc->bios_pg3.BiosVersion = 0; 5505 + else { 5506 + rc = mpt3sas_config_get_bios_pg2(ioc, &mpi_reply, &ioc->bios_pg2); 5507 + if (rc) 5508 + return rc; 5509 + rc = mpt3sas_config_get_bios_pg3(ioc, &mpi_reply, &ioc->bios_pg3); 5510 + if (rc) 5511 + return rc; 5512 + } 5513 + 5664 5514 rc = mpt3sas_config_get_ioc_pg8(ioc, &mpi_reply, &ioc->ioc_pg8); 5665 5515 if (rc) 5666 5516 return rc; ··· 7063 6895 7064 6896 /* send message 32-bits at a time */ 7065 6897 for (i = 0, failed = 0; i < request_bytes/4 && !failed; i++) { 7066 - writel(request[i], &ioc->chip->Doorbell); 6898 + writel(cpu_to_le32(request[i]), &ioc->chip->Doorbell); 7067 6899 if ((_base_wait_for_doorbell_ack(ioc, 5))) 7068 6900 failed = 1; 7069 6901 } ··· 7082 6914 } 7083 6915 7084 6916 /* read the first two 16-bits, it gives the total length of the reply */ 7085 - reply[0] = ioc->base_readl(&ioc->chip->Doorbell) 7086 - & MPI2_DOORBELL_DATA_MASK; 6917 + reply[0] = le16_to_cpu(ioc->base_readl(&ioc->chip->Doorbell) 6918 + & MPI2_DOORBELL_DATA_MASK); 7087 6919 writel(0, &ioc->chip->HostInterruptStatus); 7088 6920 if ((_base_wait_for_doorbell_int(ioc, 5))) { 7089 6921 ioc_err(ioc, "doorbell handshake int failed (line=%d)\n", 7090 6922 __LINE__); 7091 6923 return -EFAULT; 7092 6924 } 7093 - reply[1] = ioc->base_readl(&ioc->chip->Doorbell) 7094 - & MPI2_DOORBELL_DATA_MASK; 6925 + reply[1] = le16_to_cpu(ioc->base_readl(&ioc->chip->Doorbell) 6926 + & MPI2_DOORBELL_DATA_MASK); 7095 6927 writel(0, &ioc->chip->HostInterruptStatus); 7096 6928 7097 6929 for (i = 2; i < default_reply->MsgLength * 2; i++) { ··· 7103 6935 if (i >= reply_bytes/2) /* overflow case */ 7104 6936 ioc->base_readl(&ioc->chip->Doorbell); 7105 6937 else 7106 - reply[i] = ioc->base_readl(&ioc->chip->Doorbell) 7107 - & MPI2_DOORBELL_DATA_MASK; 6938 + reply[i] = le16_to_cpu( 6939 + ioc->base_readl(&ioc->chip->Doorbell) 6940 + & MPI2_DOORBELL_DATA_MASK); 7108 6941 writel(0, &ioc->chip->HostInterruptStatus); 7109 6942 } 7110 6943
+37 -2
drivers/scsi/mpt3sas/mpt3sas_base.h
··· 77 77 #define MPT3SAS_DRIVER_NAME "mpt3sas" 78 78 #define MPT3SAS_AUTHOR "Avago Technologies <MPT-FusionLinux.pdl@avagotech.com>" 79 79 #define MPT3SAS_DESCRIPTION "LSI MPT Fusion SAS 3.0 Device Driver" 80 - #define MPT3SAS_DRIVER_VERSION "42.100.00.00" 81 - #define MPT3SAS_MAJOR_VERSION 42 80 + #define MPT3SAS_DRIVER_VERSION "43.100.00.00" 81 + #define MPT3SAS_MAJOR_VERSION 43 82 82 #define MPT3SAS_MINOR_VERSION 100 83 83 #define MPT3SAS_BUILD_VERSION 0 84 84 #define MPT3SAS_RELEASE_VERSION 00 ··· 1652 1652 typedef u8 (*MPT_CALLBACK)(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, 1653 1653 u32 reply); 1654 1654 1655 + /* 1656 + * struct ATTO_SAS_NVRAM - ATTO NVRAM settings stored 1657 + * in Manufacturing page 1 used to get 1658 + * ATTO SasAddr. 1659 + */ 1660 + struct ATTO_SAS_NVRAM { 1661 + u8 Signature[4]; 1662 + u8 Version; 1663 + #define ATTO_SASNVR_VERSION 0 1664 + 1665 + u8 Checksum; 1666 + #define ATTO_SASNVR_CKSUM_SEED 0x5A 1667 + u8 Pad[10]; 1668 + u8 SasAddr[8]; 1669 + #define ATTO_SAS_ADDR_ALIGN 64 1670 + u8 Reserved[232]; 1671 + }; 1672 + 1673 + #define ATTO_SAS_ADDR_DEVNAME_BIAS 63 1674 + 1675 + union ATTO_SAS_ADDRESS { 1676 + U8 b[8]; 1677 + U16 w[4]; 1678 + U32 d[2]; 1679 + U64 q; 1680 + }; 1655 1681 1656 1682 /* base shared API */ 1657 1683 extern struct list_head mpt3sas_ioc_list; ··· 1854 1828 u8 *num_phys); 1855 1829 int mpt3sas_config_get_manufacturing_pg0(struct MPT3SAS_ADAPTER *ioc, 1856 1830 Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage0_t *config_page); 1831 + int mpt3sas_config_get_manufacturing_pg1(struct MPT3SAS_ADAPTER *ioc, 1832 + Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage1_t *config_page); 1833 + 1857 1834 int mpt3sas_config_get_manufacturing_pg7(struct MPT3SAS_ADAPTER *ioc, 1858 1835 Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage7_t *config_page, 1859 1836 u16 sz); ··· 1875 1846 *mpi_reply, Mpi2BiosPage2_t *config_page); 1876 1847 int mpt3sas_config_get_bios_pg3(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t 1877 1848 *mpi_reply, Mpi2BiosPage3_t *config_page); 1849 + int mpt3sas_config_set_bios_pg4(struct MPT3SAS_ADAPTER *ioc, 1850 + Mpi2ConfigReply_t *mpi_reply, Mpi2BiosPage4_t *config_page, 1851 + int sz_config_page); 1852 + int mpt3sas_config_get_bios_pg4(struct MPT3SAS_ADAPTER *ioc, 1853 + Mpi2ConfigReply_t *mpi_reply, Mpi2BiosPage4_t *config_page, 1854 + int sz_config_page); 1878 1855 int mpt3sas_config_get_iounit_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t 1879 1856 *mpi_reply, Mpi2IOUnitPage0_t *config_page); 1880 1857 int mpt3sas_config_get_sas_device_pg0(struct MPT3SAS_ADAPTER *ioc,
+124
drivers/scsi/mpt3sas/mpt3sas_config.c
··· 541 541 } 542 542 543 543 /** 544 + * mpt3sas_config_get_manufacturing_pg1 - obtain manufacturing page 1 545 + * @ioc: per adapter object 546 + * @mpi_reply: reply mf payload returned from firmware 547 + * @config_page: contents of the config page 548 + * Context: sleep. 549 + * 550 + * Return: 0 for success, non-zero for failure. 551 + */ 552 + int 553 + mpt3sas_config_get_manufacturing_pg1(struct MPT3SAS_ADAPTER *ioc, 554 + Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage1_t *config_page) 555 + { 556 + Mpi2ConfigRequest_t mpi_request; 557 + int r; 558 + 559 + memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 560 + mpi_request.Function = MPI2_FUNCTION_CONFIG; 561 + mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 562 + mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING; 563 + mpi_request.Header.PageNumber = 1; 564 + mpi_request.Header.PageVersion = MPI2_MANUFACTURING1_PAGEVERSION; 565 + ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 566 + r = _config_request(ioc, &mpi_request, mpi_reply, 567 + MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 568 + if (r) 569 + goto out; 570 + 571 + mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 572 + r = _config_request(ioc, &mpi_request, mpi_reply, 573 + MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 574 + sizeof(*config_page)); 575 + out: 576 + return r; 577 + } 578 + 579 + /** 544 580 * mpt3sas_config_get_manufacturing_pg7 - obtain manufacturing page 7 545 581 * @ioc: per adapter object 546 582 * @mpi_reply: reply mf payload returned from firmware ··· 793 757 r = _config_request(ioc, &mpi_request, mpi_reply, 794 758 MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 795 759 sizeof(*config_page)); 760 + 796 761 out: 762 + return r; 763 + } 764 + 765 + /** 766 + * mpt3sas_config_set_bios_pg4 - write out bios page 4 767 + * @ioc: per adapter object 768 + * @mpi_reply: reply mf payload returned from firmware 769 + * @config_page: contents of the config page 770 + * @sz_config_pg: sizeof the config page 771 + * Context: sleep. 772 + * 773 + * Return: 0 for success, non-zero for failure. 774 + */ 775 + int 776 + mpt3sas_config_set_bios_pg4(struct MPT3SAS_ADAPTER *ioc, 777 + Mpi2ConfigReply_t *mpi_reply, Mpi2BiosPage4_t *config_page, 778 + int sz_config_pg) 779 + { 780 + Mpi2ConfigRequest_t mpi_request; 781 + int r; 782 + 783 + memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 784 + 785 + mpi_request.Function = MPI2_FUNCTION_CONFIG; 786 + mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 787 + mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS; 788 + mpi_request.Header.PageNumber = 4; 789 + mpi_request.Header.PageVersion = MPI2_BIOSPAGE4_PAGEVERSION; 790 + 791 + ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 792 + 793 + r = _config_request(ioc, &mpi_request, mpi_reply, 794 + MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 795 + if (r) 796 + goto out; 797 + 798 + mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT; 799 + r = _config_request(ioc, &mpi_request, mpi_reply, 800 + MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 801 + sz_config_pg); 802 + out: 803 + return r; 804 + } 805 + 806 + /** 807 + * mpt3sas_config_get_bios_pg4 - read bios page 4 808 + * @ioc: per adapter object 809 + * @mpi_reply: reply mf payload returned from firmware 810 + * @config_page: contents of the config page 811 + * @sz_config_pg: sizeof the config page 812 + * Context: sleep. 813 + * 814 + * Return: 0 for success, non-zero for failure. 815 + */ 816 + int 817 + mpt3sas_config_get_bios_pg4(struct MPT3SAS_ADAPTER *ioc, 818 + Mpi2ConfigReply_t *mpi_reply, Mpi2BiosPage4_t *config_page, 819 + int sz_config_pg) 820 + { 821 + Mpi2ConfigRequest_t mpi_request; 822 + int r; 823 + 824 + memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 825 + mpi_request.Function = MPI2_FUNCTION_CONFIG; 826 + mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; 827 + mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS; 828 + mpi_request.Header.PageNumber = 4; 829 + mpi_request.Header.PageVersion = MPI2_BIOSPAGE4_PAGEVERSION; 830 + ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); 831 + r = _config_request(ioc, &mpi_request, mpi_reply, 832 + MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); 833 + if (r) 834 + goto out; 835 + 836 + /* 837 + * The sizeof the page is variable. Allow for just the 838 + * size to be returned 839 + */ 840 + if (config_page && sz_config_pg) { 841 + mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 842 + 843 + r = _config_request(ioc, &mpi_request, mpi_reply, 844 + MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, 845 + sz_config_pg); 846 + } 847 + 848 + out: 797 849 return r; 798 850 } 799 851
+12
drivers/scsi/mpt3sas/mpt3sas_ctl.c
··· 948 948 break; 949 949 } 950 950 case MPI2_FUNCTION_FW_DOWNLOAD: 951 + { 952 + if (ioc->pdev->vendor == MPI2_MFGPAGE_VENDORID_ATTO) { 953 + ioc_info(ioc, "Firmware download not supported for ATTO HBA.\n"); 954 + ret = -EPERM; 955 + break; 956 + } 957 + fallthrough; 958 + } 951 959 case MPI2_FUNCTION_FW_UPLOAD: 952 960 { 953 961 ioc->build_sg(ioc, psge, data_out_dma, data_out_sz, data_in_dma, ··· 1694 1686 ioc->ctl_cmds.status = MPT3_CMD_PENDING; 1695 1687 memset(ioc->ctl_cmds.reply, 0, ioc->reply_sz); 1696 1688 mpi_request = mpt3sas_base_get_msg_frame(ioc, smid); 1689 + memset(mpi_request, 0, ioc->request_sz); 1697 1690 ioc->ctl_cmds.smid = smid; 1698 1691 1699 1692 request_data = ioc->diag_buffer[buffer_type]; ··· 1796 1787 if (rc && request_data) { 1797 1788 dma_free_coherent(&ioc->pdev->dev, request_data_sz, 1798 1789 request_data, request_data_dma); 1790 + ioc->diag_buffer[buffer_type] = NULL; 1799 1791 ioc->diag_buffer_status[buffer_type] &= 1800 1792 ~MPT3_DIAG_BUFFER_IS_DRIVER_ALLOCATED; 1801 1793 } ··· 2173 2163 ioc->ctl_cmds.status = MPT3_CMD_PENDING; 2174 2164 memset(ioc->ctl_cmds.reply, 0, ioc->reply_sz); 2175 2165 mpi_request = mpt3sas_base_get_msg_frame(ioc, smid); 2166 + memset(mpi_request, 0, ioc->request_sz); 2176 2167 ioc->ctl_cmds.smid = smid; 2177 2168 2178 2169 mpi_request->Function = MPI2_FUNCTION_DIAG_RELEASE; ··· 2428 2417 ioc->ctl_cmds.status = MPT3_CMD_PENDING; 2429 2418 memset(ioc->ctl_cmds.reply, 0, ioc->reply_sz); 2430 2419 mpi_request = mpt3sas_base_get_msg_frame(ioc, smid); 2420 + memset(mpi_request, 0, ioc->request_sz); 2431 2421 ioc->ctl_cmds.smid = smid; 2432 2422 2433 2423 mpi_request->Function = MPI2_FUNCTION_DIAG_BUFFER_POST;
+20 -1
drivers/scsi/mpt3sas/mpt3sas_scsih.c
··· 5156 5156 5157 5157 /* invalid device handle */ 5158 5158 handle = sas_target_priv_data->handle; 5159 + 5160 + /* 5161 + * Avoid error handling escallation when device is disconnected 5162 + */ 5163 + if (handle == MPT3SAS_INVALID_DEVICE_HANDLE || sas_device_priv_data->block) { 5164 + if (scmd->device->host->shost_state == SHOST_RECOVERY && 5165 + scmd->cmnd[0] == TEST_UNIT_READY) { 5166 + scsi_build_sense(scmd, 0, UNIT_ATTENTION, 0x29, 0x07); 5167 + scsi_done(scmd); 5168 + return 0; 5169 + } 5170 + } 5171 + 5159 5172 if (handle == MPT3SAS_INVALID_DEVICE_HANDLE) { 5160 5173 scmd->result = DID_NO_CONNECT << 16; 5161 5174 scsi_done(scmd); ··· 11987 11974 .sg_tablesize = MPT3SAS_SG_DEPTH, 11988 11975 .max_sectors = 32767, 11989 11976 .max_segment_size = 0xffffffff, 11990 - .cmd_per_lun = 7, 11977 + .cmd_per_lun = 128, 11991 11978 .shost_groups = mpt3sas_host_groups, 11992 11979 .sdev_groups = mpt3sas_dev_groups, 11993 11980 .track_queue_depth = 1, ··· 12742 12729 { MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_CFG_SEC_3816, 12743 12730 PCI_ANY_ID, PCI_ANY_ID }, 12744 12731 { MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_HARD_SEC_3816, 12732 + PCI_ANY_ID, PCI_ANY_ID }, 12733 + 12734 + /* 12735 + * ATTO Branded ExpressSAS H12xx GT 12736 + */ 12737 + { MPI2_MFGPAGE_VENDORID_ATTO, MPI26_MFGPAGE_DEVID_HARD_SEC_3816, 12745 12738 PCI_ANY_ID, PCI_ANY_ID }, 12746 12739 12747 12740 /*
+4
drivers/scsi/pm8001/pm8001_hwi.c
··· 3612 3612 pm8001_dbg(pm8001_ha, FAIL, " TASK NULL. RETURNING !!!\n"); 3613 3613 return -1; 3614 3614 } 3615 + 3616 + if (t->task_proto == SAS_PROTOCOL_INTERNAL_ABORT) 3617 + atomic_dec(&pm8001_dev->running_req); 3618 + 3615 3619 ts = &t->task_status; 3616 3620 if (status != 0) 3617 3621 pm8001_dbg(pm8001_ha, FAIL, "task abort failed status 0x%x ,tag = 0x%x, scp= 0x%x\n",
+1 -1
drivers/scsi/pm8001/pm8001_sas.h
··· 612 612 operations.*/ 613 613 u32 reserved;/* padding required for 64 bit 614 614 alignment */ 615 - u8 buffer[1];/* Start of buffer */ 615 + u8 buffer[];/* Start of buffer */ 616 616 }; 617 617 struct fw_control_ex { 618 618 struct fw_control_info *fw_control;
+21
drivers/scsi/qedf/qedf_main.c
··· 1921 1921 fc_vport_setlink(vn_port); 1922 1922 } 1923 1923 1924 + /* Set symbolic node name */ 1925 + if (base_qedf->pdev->device == QL45xxx) 1926 + snprintf(fc_host_symbolic_name(vn_port->host), 256, 1927 + "Marvell FastLinQ 45xxx FCoE v%s", QEDF_VERSION); 1928 + 1929 + if (base_qedf->pdev->device == QL41xxx) 1930 + snprintf(fc_host_symbolic_name(vn_port->host), 256, 1931 + "Marvell FastLinQ 41xxx FCoE v%s", QEDF_VERSION); 1932 + 1933 + /* Set supported speed */ 1934 + fc_host_supported_speeds(vn_port->host) = n_port->link_supported_speeds; 1935 + 1936 + /* Set speed */ 1937 + vn_port->link_speed = n_port->link_speed; 1938 + 1939 + /* Set port type */ 1940 + fc_host_port_type(vn_port->host) = FC_PORTTYPE_NPIV; 1941 + 1942 + /* Set maxframe size */ 1943 + fc_host_maxframe_size(vn_port->host) = n_port->mfs; 1944 + 1924 1945 QEDF_INFO(&(base_qedf->dbg_ctx), QEDF_LOG_NPIV, "vn_port=%p.\n", 1925 1946 vn_port); 1926 1947
+6 -2
drivers/scsi/qla2xxx/qla_bsg.c
··· 2519 2519 qla27xx_get_active_image(vha, &active_regions); 2520 2520 regions.global_image = active_regions.global; 2521 2521 2522 + if (IS_QLA27XX(ha)) 2523 + regions.nvme_params = QLA27XX_PRIMARY_IMAGE; 2524 + 2522 2525 if (IS_QLA28XX(ha)) { 2523 2526 qla28xx_get_aux_images(vha, &active_regions); 2524 2527 regions.board_config = active_regions.aux.board_config; 2525 2528 regions.vpd_nvram = active_regions.aux.vpd_nvram; 2526 2529 regions.npiv_config_0_1 = active_regions.aux.npiv_config_0_1; 2527 2530 regions.npiv_config_2_3 = active_regions.aux.npiv_config_2_3; 2531 + regions.nvme_params = active_regions.aux.nvme_params; 2528 2532 } 2529 2533 2530 2534 ql_dbg(ql_dbg_user, vha, 0x70e1, 2531 - "%s(%lu): FW=%u BCFG=%u VPDNVR=%u NPIV01=%u NPIV02=%u\n", 2535 + "%s(%lu): FW=%u BCFG=%u VPDNVR=%u NPIV01=%u NPIV02=%u NVME_PARAMS=%u\n", 2532 2536 __func__, vha->host_no, regions.global_image, 2533 2537 regions.board_config, regions.vpd_nvram, 2534 - regions.npiv_config_0_1, regions.npiv_config_2_3); 2538 + regions.npiv_config_0_1, regions.npiv_config_2_3, regions.nvme_params); 2535 2539 2536 2540 sg_copy_from_buffer(bsg_job->reply_payload.sg_list, 2537 2541 bsg_job->reply_payload.sg_cnt, &regions, sizeof(regions));
+2 -1
drivers/scsi/qla2xxx/qla_bsg.h
··· 314 314 uint8_t vpd_nvram; 315 315 uint8_t npiv_config_0_1; 316 316 uint8_t npiv_config_2_3; 317 - uint8_t reserved[32]; 317 + uint8_t nvme_params; 318 + uint8_t reserved[31]; 318 319 } __packed; 319 320 320 321 #include "qla_edif_bsg.h"
+36 -14
drivers/scsi/qla2xxx/qla_dbg.c
··· 2455 2455 /****************************************************************************/ 2456 2456 2457 2457 /* Write the debug message prefix into @pbuf. */ 2458 - static void ql_dbg_prefix(char *pbuf, int pbuf_size, 2458 + static void ql_dbg_prefix(char *pbuf, int pbuf_size, struct pci_dev *pdev, 2459 2459 const scsi_qla_host_t *vha, uint msg_id) 2460 2460 { 2461 2461 if (vha) { ··· 2464 2464 /* <module-name> [<dev-name>]-<msg-id>:<host>: */ 2465 2465 snprintf(pbuf, pbuf_size, "%s [%s]-%04x:%lu: ", QL_MSGHDR, 2466 2466 dev_name(&(pdev->dev)), msg_id, vha->host_no); 2467 + } else if (pdev) { 2468 + snprintf(pbuf, pbuf_size, "%s [%s]-%04x: : ", QL_MSGHDR, 2469 + dev_name(&pdev->dev), msg_id); 2467 2470 } else { 2468 2471 /* <module-name> [<dev-name>]-<msg-id>: : */ 2469 2472 snprintf(pbuf, pbuf_size, "%s [%s]-%04x: : ", QL_MSGHDR, ··· 2494 2491 struct va_format vaf; 2495 2492 char pbuf[64]; 2496 2493 2497 - if (!ql_mask_match(level) && !trace_ql_dbg_log_enabled()) 2494 + ql_ktrace(1, level, pbuf, NULL, vha, id, fmt); 2495 + 2496 + if (!ql_mask_match(level)) 2498 2497 return; 2498 + 2499 + if (!pbuf[0]) /* set by ql_ktrace */ 2500 + ql_dbg_prefix(pbuf, ARRAY_SIZE(pbuf), NULL, vha, id); 2499 2501 2500 2502 va_start(va, fmt); 2501 2503 2502 2504 vaf.fmt = fmt; 2503 2505 vaf.va = &va; 2504 2506 2505 - ql_dbg_prefix(pbuf, ARRAY_SIZE(pbuf), vha, id); 2506 - 2507 - if (!ql_mask_match(level)) 2508 - trace_ql_dbg_log(pbuf, &vaf); 2509 - else 2510 - pr_warn("%s%pV", pbuf, &vaf); 2507 + pr_warn("%s%pV", pbuf, &vaf); 2511 2508 2512 2509 va_end(va); 2513 2510 ··· 2536 2533 2537 2534 if (pdev == NULL) 2538 2535 return; 2536 + 2537 + ql_ktrace(1, level, pbuf, pdev, NULL, id, fmt); 2538 + 2539 2539 if (!ql_mask_match(level)) 2540 2540 return; 2541 2541 ··· 2547 2541 vaf.fmt = fmt; 2548 2542 vaf.va = &va; 2549 2543 2550 - ql_dbg_prefix(pbuf, ARRAY_SIZE(pbuf), NULL, id + ql_dbg_offset); 2544 + if (!pbuf[0]) /* set by ql_ktrace */ 2545 + ql_dbg_prefix(pbuf, ARRAY_SIZE(pbuf), pdev, NULL, 2546 + id + ql_dbg_offset); 2551 2547 pr_warn("%s%pV", pbuf, &vaf); 2552 2548 2553 2549 va_end(va); ··· 2578 2570 if (level > ql_errlev) 2579 2571 return; 2580 2572 2581 - ql_dbg_prefix(pbuf, ARRAY_SIZE(pbuf), vha, id); 2573 + ql_ktrace(0, level, pbuf, NULL, vha, id, fmt); 2574 + 2575 + if (!pbuf[0]) /* set by ql_ktrace */ 2576 + ql_dbg_prefix(pbuf, ARRAY_SIZE(pbuf), NULL, vha, id); 2582 2577 2583 2578 va_start(va, fmt); 2584 2579 ··· 2632 2621 if (level > ql_errlev) 2633 2622 return; 2634 2623 2635 - ql_dbg_prefix(pbuf, ARRAY_SIZE(pbuf), NULL, id); 2624 + ql_ktrace(0, level, pbuf, pdev, NULL, id, fmt); 2625 + 2626 + if (!pbuf[0]) /* set by ql_ktrace */ 2627 + ql_dbg_prefix(pbuf, ARRAY_SIZE(pbuf), pdev, NULL, id); 2636 2628 2637 2629 va_start(va, fmt); 2638 2630 ··· 2730 2716 if (level > ql_errlev) 2731 2717 return; 2732 2718 2733 - ql_dbg_prefix(pbuf, ARRAY_SIZE(pbuf), qpair ? qpair->vha : NULL, id); 2719 + ql_ktrace(0, level, pbuf, NULL, qpair ? qpair->vha : NULL, id, fmt); 2720 + 2721 + if (!pbuf[0]) /* set by ql_ktrace */ 2722 + ql_dbg_prefix(pbuf, ARRAY_SIZE(pbuf), NULL, 2723 + qpair ? qpair->vha : NULL, id); 2734 2724 2735 2725 va_start(va, fmt); 2736 2726 ··· 2780 2762 struct va_format vaf; 2781 2763 char pbuf[128]; 2782 2764 2765 + ql_ktrace(1, level, pbuf, NULL, qpair ? qpair->vha : NULL, id, fmt); 2766 + 2783 2767 if (!ql_mask_match(level)) 2784 2768 return; 2785 2769 ··· 2790 2770 vaf.fmt = fmt; 2791 2771 vaf.va = &va; 2792 2772 2793 - ql_dbg_prefix(pbuf, ARRAY_SIZE(pbuf), qpair ? qpair->vha : NULL, 2794 - id + ql_dbg_offset); 2773 + if (!pbuf[0]) /* set by ql_ktrace */ 2774 + ql_dbg_prefix(pbuf, ARRAY_SIZE(pbuf), NULL, 2775 + qpair ? qpair->vha : NULL, id + ql_dbg_offset); 2776 + 2795 2777 pr_warn("%s%pV", pbuf, &vaf); 2796 2778 2797 2779 va_end(va);
+43
drivers/scsi/qla2xxx/qla_dbg.h
··· 385 385 386 386 return level && ((level & ql2xextended_error_logging) == level); 387 387 } 388 + 389 + static inline int 390 + ql_mask_match_ext(uint level, int *log_tunable) 391 + { 392 + if (*log_tunable == 1) 393 + *log_tunable = QL_DBG_DEFAULT1_MASK; 394 + 395 + return (level & *log_tunable) == level; 396 + } 397 + 398 + /* Assumes local variable pbuf and pbuf_ready present. */ 399 + #define ql_ktrace(dbg_msg, level, pbuf, pdev, vha, id, fmt) do { \ 400 + struct va_format _vaf; \ 401 + va_list _va; \ 402 + u32 dbg_off = dbg_msg ? ql_dbg_offset : 0; \ 403 + \ 404 + pbuf[0] = 0; \ 405 + if (!trace_ql_dbg_log_enabled()) \ 406 + break; \ 407 + \ 408 + if (dbg_msg && !ql_mask_match_ext(level, \ 409 + &ql2xextended_error_logging_ktrace)) \ 410 + break; \ 411 + \ 412 + ql_dbg_prefix(pbuf, ARRAY_SIZE(pbuf), pdev, vha, id + dbg_off); \ 413 + \ 414 + va_start(_va, fmt); \ 415 + _vaf.fmt = fmt; \ 416 + _vaf.va = &_va; \ 417 + \ 418 + trace_ql_dbg_log(pbuf, &_vaf); \ 419 + \ 420 + va_end(_va); \ 421 + } while (0) 422 + 423 + #define QLA_ENABLE_KERNEL_TRACING 424 + 425 + #ifdef QLA_ENABLE_KERNEL_TRACING 426 + #define QLA_TRACE_ENABLE(_tr) \ 427 + trace_array_set_clr_event(_tr, "qla", NULL, true) 428 + #else /* QLA_ENABLE_KERNEL_TRACING */ 429 + #define QLA_TRACE_ENABLE(_tr) 430 + #endif /* QLA_ENABLE_KERNEL_TRACING */
+7
drivers/scsi/qla2xxx/qla_def.h
··· 35 35 36 36 #include <uapi/scsi/fc/fc_els.h> 37 37 38 + #define QLA_DFS_DEFINE_DENTRY(_debugfs_file_name) \ 39 + struct dentry *dfs_##_debugfs_file_name 40 + #define QLA_DFS_ROOT_DEFINE_DENTRY(_debugfs_file_name) \ 41 + struct dentry *qla_dfs_##_debugfs_file_name 42 + 38 43 /* Big endian Fibre Channel S_ID (source ID) or D_ID (destination ID). */ 39 44 typedef struct { 40 45 uint8_t domain; ··· 4773 4768 uint8_t vpd_nvram; 4774 4769 uint8_t npiv_config_0_1; 4775 4770 uint8_t npiv_config_2_3; 4771 + uint8_t nvme_params; 4776 4772 } aux; 4777 4773 }; 4778 4774 ··· 5058 5052 #define QLA28XX_AUX_IMG_VPD_NVRAM BIT_1 5059 5053 #define QLA28XX_AUX_IMG_NPIV_CONFIG_0_1 BIT_2 5060 5054 #define QLA28XX_AUX_IMG_NPIV_CONFIG_2_3 BIT_3 5055 + #define QLA28XX_AUX_IMG_NVME_PARAMS BIT_4 5061 5056 5062 5057 #define SET_VP_IDX 1 5063 5058 #define SET_AL_PA 2
+93
drivers/scsi/qla2xxx/qla_dfs.c
··· 489 489 return 0; 490 490 } 491 491 492 + /* 493 + * Helper macros for setting up debugfs entries. 494 + * _name: The name of the debugfs entry 495 + * _ctx_struct: The context that was passed when creating the debugfs file 496 + * 497 + * QLA_DFS_SETUP_RD could be used when there is only a show function. 498 + * - show function take the name qla_dfs_<sysfs-name>_show 499 + * 500 + * QLA_DFS_SETUP_RW could be used when there are both show and write functions. 501 + * - show function take the name qla_dfs_<sysfs-name>_show 502 + * - write function take the name qla_dfs_<sysfs-name>_write 503 + * 504 + * To have a new debugfs entry, do: 505 + * 1. Create a "struct dentry *" in the appropriate structure in the format 506 + * dfs_<sysfs-name> 507 + * 2. Setup debugfs entries using QLA_DFS_SETUP_RD / QLA_DFS_SETUP_RW 508 + * 3. Create debugfs file in qla2x00_dfs_setup() using QLA_DFS_CREATE_FILE 509 + * or QLA_DFS_ROOT_CREATE_FILE 510 + * 4. Remove debugfs file in qla2x00_dfs_remove() using QLA_DFS_REMOVE_FILE 511 + * or QLA_DFS_ROOT_REMOVE_FILE 512 + * 513 + * Example for creating "TEST" sysfs file: 514 + * 1. struct qla_hw_data { ... struct dentry *dfs_TEST; } 515 + * 2. QLA_DFS_SETUP_RD(TEST, scsi_qla_host_t); 516 + * 3. In qla2x00_dfs_setup(): 517 + * QLA_DFS_CREATE_FILE(ha, TEST, 0600, ha->dfs_dir, vha); 518 + * 4. In qla2x00_dfs_remove(): 519 + * QLA_DFS_REMOVE_FILE(ha, TEST); 520 + */ 521 + #define QLA_DFS_SETUP_RD(_name, _ctx_struct) \ 522 + static int \ 523 + qla_dfs_##_name##_open(struct inode *inode, struct file *file) \ 524 + { \ 525 + _ctx_struct *__ctx = inode->i_private; \ 526 + \ 527 + return single_open(file, qla_dfs_##_name##_show, __ctx); \ 528 + } \ 529 + \ 530 + static const struct file_operations qla_dfs_##_name##_ops = { \ 531 + .open = qla_dfs_##_name##_open, \ 532 + .read = seq_read, \ 533 + .llseek = seq_lseek, \ 534 + .release = single_release, \ 535 + }; 536 + 537 + #define QLA_DFS_SETUP_RW(_name, _ctx_struct) \ 538 + static int \ 539 + qla_dfs_##_name##_open(struct inode *inode, struct file *file) \ 540 + { \ 541 + _ctx_struct *__ctx = inode->i_private; \ 542 + \ 543 + return single_open(file, qla_dfs_##_name##_show, __ctx); \ 544 + } \ 545 + \ 546 + static const struct file_operations qla_dfs_##_name##_ops = { \ 547 + .open = qla_dfs_##_name##_open, \ 548 + .read = seq_read, \ 549 + .llseek = seq_lseek, \ 550 + .release = single_release, \ 551 + .write = qla_dfs_##_name##_write, \ 552 + }; 553 + 554 + #define QLA_DFS_ROOT_CREATE_FILE(_name, _perm, _ctx) \ 555 + do { \ 556 + if (!qla_dfs_##_name) \ 557 + qla_dfs_##_name = debugfs_create_file(#_name, \ 558 + _perm, qla2x00_dfs_root, _ctx, \ 559 + &qla_dfs_##_name##_ops); \ 560 + } while (0) 561 + 562 + #define QLA_DFS_ROOT_REMOVE_FILE(_name) \ 563 + do { \ 564 + if (qla_dfs_##_name) { \ 565 + debugfs_remove(qla_dfs_##_name); \ 566 + qla_dfs_##_name = NULL; \ 567 + } \ 568 + } while (0) 569 + 570 + #define QLA_DFS_CREATE_FILE(_struct, _name, _perm, _parent, _ctx) \ 571 + do { \ 572 + (_struct)->dfs_##_name = debugfs_create_file(#_name, \ 573 + _perm, _parent, _ctx, \ 574 + &qla_dfs_##_name##_ops) \ 575 + } while (0) 576 + 577 + #define QLA_DFS_REMOVE_FILE(_struct, _name) \ 578 + do { \ 579 + if ((_struct)->dfs_##_name) { \ 580 + debugfs_remove((_struct)->dfs_##_name); \ 581 + (_struct)->dfs_##_name = NULL; \ 582 + } \ 583 + } while (0) 584 + 492 585 static int 493 586 qla_dfs_naqp_open(struct inode *inode, struct file *file) 494 587 {
+1 -1
drivers/scsi/qla2xxx/qla_edif.c
··· 1551 1551 ql_dbg(ql_dbg_edif, vha, 0x70a3, "Failed to find port= %06x\n", 1552 1552 sa_frame.port_id.b24); 1553 1553 rval = -EINVAL; 1554 - SET_DID_STATUS(bsg_reply->result, DID_TARGET_FAILURE); 1554 + SET_DID_STATUS(bsg_reply->result, DID_NO_CONNECT); 1555 1555 goto done; 1556 1556 } 1557 1557
+3
drivers/scsi/qla2xxx/qla_fw.h
··· 1675 1675 #define FLT_REG_VPD_SEC_27XX_1 0x52 1676 1676 #define FLT_REG_VPD_SEC_27XX_2 0xD8 1677 1677 #define FLT_REG_VPD_SEC_27XX_3 0xDA 1678 + #define FLT_REG_NVME_PARAMS_27XX 0x21 1678 1679 1679 1680 /* 28xx */ 1680 1681 #define FLT_REG_AUX_IMG_PRI_28XX 0x125 ··· 1692 1691 #define FLT_REG_MPI_SEC_28XX 0xF0 1693 1692 #define FLT_REG_PEP_PRI_28XX 0xD1 1694 1693 #define FLT_REG_PEP_SEC_28XX 0xF1 1694 + #define FLT_REG_NVME_PARAMS_PRI_28XX 0x14E 1695 + #define FLT_REG_NVME_PARAMS_SEC_28XX 0x179 1695 1696 1696 1697 struct qla_flt_region { 1697 1698 __le16 code;
+1 -14
drivers/scsi/qla2xxx/qla_gbl.h
··· 70 70 extern int qla2x00_async_adisc(struct scsi_qla_host *, fc_port_t *, 71 71 uint16_t *); 72 72 extern int qla2x00_async_tm_cmd(fc_port_t *, uint32_t, uint32_t, uint32_t); 73 - extern void qla2x00_async_login_done(struct scsi_qla_host *, fc_port_t *, 74 - uint16_t *); 75 73 struct qla_work_evt *qla2x00_alloc_work(struct scsi_qla_host *, 76 74 enum qla_work_type); 77 75 extern int qla24xx_async_gnl(struct scsi_qla_host *, fc_port_t *); ··· 161 163 extern int ql2xsmartsan; 162 164 extern int ql2xallocfwdump; 163 165 extern int ql2xextended_error_logging; 166 + extern int ql2xextended_error_logging_ktrace; 164 167 extern int ql2xiidmaenable; 165 168 extern int ql2xmqsupport; 166 169 extern int ql2xfwloadbin; ··· 192 193 extern int ql2xenforce_iocb_limit; 193 194 extern int ql2xabts_wait_nvme; 194 195 extern u32 ql2xnvme_queues; 195 - extern int ql2xrspq_follow_inptr; 196 - extern int ql2xrspq_follow_inptr_legacy; 197 196 198 197 extern int qla2x00_loop_reset(scsi_qla_host_t *); 199 198 extern void qla2x00_abort_all_cmds(scsi_qla_host_t *, int); ··· 276 279 extern scsi_qla_host_t *qla24xx_create_vhost(struct fc_vport *); 277 280 278 281 extern void qla2x00_sp_free_dma(srb_t *sp); 279 - extern char *qla2x00_get_fw_version_str(struct scsi_qla_host *, char *); 280 282 281 283 extern void qla2x00_mark_device_lost(scsi_qla_host_t *, fc_port_t *, int); 282 284 extern void qla2x00_mark_all_devices_lost(scsi_qla_host_t *); ··· 612 616 /* 613 617 * Global Function Prototypes in qla_sup.c source file. 614 618 */ 615 - extern void qla2x00_release_nvram_protection(scsi_qla_host_t *); 616 619 extern int qla24xx_read_flash_data(scsi_qla_host_t *, uint32_t *, 617 620 uint32_t, uint32_t); 618 621 extern uint8_t *qla2x00_read_nvram_data(scsi_qla_host_t *, void *, uint32_t, ··· 783 788 extern int qla25xx_delete_req_que(struct scsi_qla_host *, struct req_que *); 784 789 extern int qla25xx_delete_rsp_que(struct scsi_qla_host *, struct rsp_que *); 785 790 extern int qla25xx_delete_queues(struct scsi_qla_host *); 786 - extern uint16_t qla24xx_rd_req_reg(struct qla_hw_data *, uint16_t); 787 - extern uint16_t qla25xx_rd_req_reg(struct qla_hw_data *, uint16_t); 788 - extern void qla24xx_wrt_req_reg(struct qla_hw_data *, uint16_t, uint16_t); 789 - extern void qla25xx_wrt_req_reg(struct qla_hw_data *, uint16_t, uint16_t); 790 - extern void qla25xx_wrt_rsp_reg(struct qla_hw_data *, uint16_t, uint16_t); 791 - extern void qla24xx_wrt_rsp_reg(struct qla_hw_data *, uint16_t, uint16_t); 792 791 793 792 /* qlafx00 related functions */ 794 793 extern int qlafx00_pci_config(struct scsi_qla_host *); ··· 867 878 extern void qla82xx_set_drv_active(scsi_qla_host_t *); 868 879 extern int qla82xx_wr_32(struct qla_hw_data *, ulong, u32); 869 880 extern int qla82xx_rd_32(struct qla_hw_data *, ulong); 870 - extern int qla82xx_rdmem(struct qla_hw_data *, u64, void *, int); 871 - extern int qla82xx_wrmem(struct qla_hw_data *, u64, void *, int); 872 881 873 882 /* ISP 8021 IDC */ 874 883 extern void qla82xx_clear_drv_active(struct qla_hw_data *);
+6 -2
drivers/scsi/qla2xxx/qla_init.c
··· 7933 7933 7934 7934 active_regions->aux.npiv_config_2_3 = 7935 7935 qla28xx_component_bitmask(aux, QLA28XX_AUX_IMG_NPIV_CONFIG_2_3); 7936 + 7937 + active_regions->aux.nvme_params = 7938 + qla28xx_component_bitmask(aux, QLA28XX_AUX_IMG_NVME_PARAMS); 7936 7939 } 7937 7940 7938 7941 static int ··· 8044 8041 } 8045 8042 8046 8043 ql_dbg(ql_dbg_init, vha, 0x018f, 8047 - "aux images active: BCFG=%u VPD/NVR=%u NPIV0/1=%u NPIV2/3=%u\n", 8044 + "aux images active: BCFG=%u VPD/NVR=%u NPIV0/1=%u NPIV2/3=%u, NVME=%u\n", 8048 8045 active_regions->aux.board_config, 8049 8046 active_regions->aux.vpd_nvram, 8050 8047 active_regions->aux.npiv_config_0_1, 8051 - active_regions->aux.npiv_config_2_3); 8048 + active_regions->aux.npiv_config_2_3, 8049 + active_regions->aux.nvme_params); 8052 8050 } 8053 8051 8054 8052 void
+7 -15
drivers/scsi/qla2xxx/qla_isr.c
··· 3764 3764 struct purex_entry_24xx *purex_entry; 3765 3765 struct purex_item *pure_item; 3766 3766 u16 rsp_in = 0, cur_ring_index; 3767 - int follow_inptr, is_shadow_hba; 3767 + int is_shadow_hba; 3768 3768 3769 3769 if (!ha->flags.fw_started) 3770 3770 return; ··· 3774 3774 qla_cpu_update(rsp->qpair, smp_processor_id()); 3775 3775 } 3776 3776 3777 - #define __update_rsp_in(_update, _is_shadow_hba, _rsp, _rsp_in) \ 3777 + #define __update_rsp_in(_is_shadow_hba, _rsp, _rsp_in) \ 3778 3778 do { \ 3779 - if (_update) { \ 3780 - _rsp_in = _is_shadow_hba ? *(_rsp)->in_ptr : \ 3779 + _rsp_in = _is_shadow_hba ? *(_rsp)->in_ptr : \ 3781 3780 rd_reg_dword_relaxed((_rsp)->rsp_q_in); \ 3782 - } \ 3783 3781 } while (0) 3784 3782 3785 3783 is_shadow_hba = IS_SHADOW_REG_CAPABLE(ha); 3786 - follow_inptr = is_shadow_hba ? ql2xrspq_follow_inptr : 3787 - ql2xrspq_follow_inptr_legacy; 3788 3784 3789 - __update_rsp_in(follow_inptr, is_shadow_hba, rsp, rsp_in); 3785 + __update_rsp_in(is_shadow_hba, rsp, rsp_in); 3790 3786 3791 - while ((likely(follow_inptr && 3792 - rsp->ring_index != rsp_in && 3793 - rsp->ring_ptr->signature != RESPONSE_PROCESSED)) || 3794 - (!follow_inptr && 3795 - rsp->ring_ptr->signature != RESPONSE_PROCESSED)) { 3787 + while (rsp->ring_index != rsp_in && 3788 + rsp->ring_ptr->signature != RESPONSE_PROCESSED) { 3796 3789 pkt = (struct sts_entry_24xx *)rsp->ring_ptr; 3797 3790 cur_ring_index = rsp->ring_index; 3798 3791 ··· 3899 3906 } 3900 3907 pure_item = qla27xx_copy_fpin_pkt(vha, 3901 3908 (void **)&pkt, &rsp); 3902 - __update_rsp_in(follow_inptr, is_shadow_hba, 3903 - rsp, rsp_in); 3909 + __update_rsp_in(is_shadow_hba, rsp, rsp_in); 3904 3910 if (!pure_item) 3905 3911 break; 3906 3912 qla24xx_queue_purex_item(vha, pure_item,
+37 -12
drivers/scsi/qla2xxx/qla_os.c
··· 15 15 #include <linux/blk-mq-pci.h> 16 16 #include <linux/refcount.h> 17 17 #include <linux/crash_dump.h> 18 + #include <linux/trace_events.h> 19 + #include <linux/trace.h> 18 20 19 21 #include <scsi/scsi_tcq.h> 20 22 #include <scsi/scsicam.h> ··· 36 34 * SRB allocation cache 37 35 */ 38 36 struct kmem_cache *srb_cachep; 37 + 38 + static struct trace_array *qla_trc_array; 39 39 40 40 int ql2xfulldump_on_mpifail; 41 41 module_param(ql2xfulldump_on_mpifail, int, S_IRUGO | S_IWUSR); ··· 120 116 "debug information (equivalent to old " 121 117 "ql2xextended_error_logging=1).\n" 122 118 "\t\tDo LOGICAL OR of the value to enable more than one level"); 119 + 120 + int ql2xextended_error_logging_ktrace = 1; 121 + module_param(ql2xextended_error_logging_ktrace, int, S_IRUGO|S_IWUSR); 122 + MODULE_PARM_DESC(ql2xextended_error_logging_ktrace, 123 + "Same BIT definition as ql2xextended_error_logging, but used to control logging to kernel trace buffer (default=1).\n"); 123 124 124 125 int ql2xshiftctondsd = 6; 125 126 module_param(ql2xshiftctondsd, int, S_IRUGO); ··· 342 333 "To wait for ABTS response on I/O timeouts for NVMe. (default: 1)"); 343 334 344 335 345 - u32 ql2xdelay_before_pci_error_handling = 5; 336 + static u32 ql2xdelay_before_pci_error_handling = 5; 346 337 module_param(ql2xdelay_before_pci_error_handling, uint, 0644); 347 338 MODULE_PARM_DESC(ql2xdelay_before_pci_error_handling, 348 339 "Number of seconds delayed before qla begin PCI error self-handling (default: 5).\n"); 349 - 350 - int ql2xrspq_follow_inptr = 1; 351 - module_param(ql2xrspq_follow_inptr, int, 0644); 352 - MODULE_PARM_DESC(ql2xrspq_follow_inptr, 353 - "Follow RSP IN pointer for RSP updates for HBAs 27xx and newer (default: 1)."); 354 - 355 - int ql2xrspq_follow_inptr_legacy = 1; 356 - module_param(ql2xrspq_follow_inptr_legacy, int, 0644); 357 - MODULE_PARM_DESC(ql2xrspq_follow_inptr_legacy, 358 - "Follow RSP IN pointer for RSP updates for HBAs older than 27XX. (default: 1)."); 359 340 360 341 static void qla2x00_clear_drv_active(struct qla_hw_data *); 361 342 static void qla2x00_free_device(scsi_qla_host_t *); ··· 2848 2849 spin_unlock_irqrestore(&vha->work_lock, flags); 2849 2850 } 2850 2851 2852 + static void 2853 + qla_trace_init(void) 2854 + { 2855 + qla_trc_array = trace_array_get_by_name("qla2xxx"); 2856 + if (!qla_trc_array) { 2857 + ql_log(ql_log_fatal, NULL, 0x0001, 2858 + "Unable to create qla2xxx trace instance, instance logging will be disabled.\n"); 2859 + return; 2860 + } 2861 + 2862 + QLA_TRACE_ENABLE(qla_trc_array); 2863 + } 2864 + 2865 + static void 2866 + qla_trace_uninit(void) 2867 + { 2868 + if (!qla_trc_array) 2869 + return; 2870 + trace_array_put(qla_trc_array); 2871 + } 2872 + 2851 2873 /* 2852 2874 * PCI driver interface 2853 2875 */ ··· 3550 3530 qla_dual_mode_enabled(base_vha)) 3551 3531 scsi_scan_host(host); 3552 3532 else 3553 - ql_dbg(ql_dbg_init, base_vha, 0x0122, 3533 + ql_log(ql_log_info, base_vha, 0x0122, 3554 3534 "skipping scsi_scan_host() for non-initiator port\n"); 3555 3535 3556 3536 qla2x00_alloc_sysfs_attr(base_vha); ··· 8209 8189 BUILD_BUG_ON(sizeof(sw_info_t) != 32); 8210 8190 BUILD_BUG_ON(sizeof(target_id_t) != 2); 8211 8191 8192 + qla_trace_init(); 8193 + 8212 8194 /* Allocate cache for SRBs. */ 8213 8195 srb_cachep = kmem_cache_create("qla2xxx_srbs", sizeof(srb_t), 0, 8214 8196 SLAB_HWCACHE_ALIGN, NULL); ··· 8289 8267 8290 8268 destroy_cache: 8291 8269 kmem_cache_destroy(srb_cachep); 8270 + 8271 + qla_trace_uninit(); 8292 8272 return ret; 8293 8273 } 8294 8274 ··· 8309 8285 fc_release_transport(qla2xxx_transport_template); 8310 8286 qlt_exit(); 8311 8287 kmem_cache_destroy(srb_cachep); 8288 + qla_trace_uninit(); 8312 8289 } 8313 8290 8314 8291 module_init(qla2x00_module_init);
+3 -70
drivers/scsi/qla2xxx/qla_target.c
··· 1557 1557 ql_dbg(ql_dbg_tgt_mgt, vha, 0xf009, 1558 1558 "Waiting for sess works (tgt %p)", tgt); 1559 1559 spin_lock_irqsave(&tgt->sess_work_lock, flags); 1560 - while (!list_empty(&tgt->sess_works_list)) { 1560 + do { 1561 1561 spin_unlock_irqrestore(&tgt->sess_work_lock, flags); 1562 - flush_scheduled_work(); 1562 + flush_work(&tgt->sess_work); 1563 1563 spin_lock_irqsave(&tgt->sess_work_lock, flags); 1564 - } 1564 + } while (!list_empty(&tgt->sess_works_list)); 1565 1565 spin_unlock_irqrestore(&tgt->sess_work_lock, flags); 1566 1566 1567 1567 ql_dbg(ql_dbg_tgt_mgt, vha, 0xf00a, ··· 6336 6336 spin_unlock_irqrestore(&ha->hardware_lock, flags); 6337 6337 } 6338 6338 6339 - static void qlt_tmr_work(struct qla_tgt *tgt, 6340 - struct qla_tgt_sess_work_param *prm) 6341 - { 6342 - struct atio_from_isp *a = &prm->tm_iocb2; 6343 - struct scsi_qla_host *vha = tgt->vha; 6344 - struct qla_hw_data *ha = vha->hw; 6345 - struct fc_port *sess; 6346 - unsigned long flags; 6347 - be_id_t s_id; 6348 - int rc; 6349 - u64 unpacked_lun; 6350 - int fn; 6351 - void *iocb; 6352 - 6353 - spin_lock_irqsave(&ha->tgt.sess_lock, flags); 6354 - 6355 - if (tgt->tgt_stop) 6356 - goto out_term2; 6357 - 6358 - s_id = prm->tm_iocb2.u.isp24.fcp_hdr.s_id; 6359 - sess = ha->tgt.tgt_ops->find_sess_by_s_id(vha, s_id); 6360 - if (!sess) { 6361 - spin_unlock_irqrestore(&ha->tgt.sess_lock, flags); 6362 - 6363 - sess = qlt_make_local_sess(vha, s_id); 6364 - /* sess has got an extra creation ref */ 6365 - 6366 - spin_lock_irqsave(&ha->tgt.sess_lock, flags); 6367 - if (!sess) 6368 - goto out_term2; 6369 - } else { 6370 - if (sess->deleted) { 6371 - goto out_term2; 6372 - } 6373 - 6374 - if (!kref_get_unless_zero(&sess->sess_kref)) { 6375 - ql_dbg(ql_dbg_tgt_tmr, vha, 0xf020, 6376 - "%s: kref_get fail %8phC\n", 6377 - __func__, sess->port_name); 6378 - goto out_term2; 6379 - } 6380 - } 6381 - 6382 - iocb = a; 6383 - fn = a->u.isp24.fcp_cmnd.task_mgmt_flags; 6384 - unpacked_lun = 6385 - scsilun_to_int((struct scsi_lun *)&a->u.isp24.fcp_cmnd.lun); 6386 - 6387 - rc = qlt_issue_task_mgmt(sess, unpacked_lun, fn, iocb, 0); 6388 - spin_unlock_irqrestore(&ha->tgt.sess_lock, flags); 6389 - 6390 - ha->tgt.tgt_ops->put_sess(sess); 6391 - 6392 - if (rc != 0) 6393 - goto out_term; 6394 - return; 6395 - 6396 - out_term2: 6397 - spin_unlock_irqrestore(&ha->tgt.sess_lock, flags); 6398 - out_term: 6399 - qlt_send_term_exchange(ha->base_qpair, NULL, &prm->tm_iocb2, 1, 0); 6400 - } 6401 - 6402 6339 static void qlt_sess_work_fn(struct work_struct *work) 6403 6340 { 6404 6341 struct qla_tgt *tgt = container_of(work, struct qla_tgt, sess_work); ··· 6361 6424 switch (prm->type) { 6362 6425 case QLA_TGT_SESS_WORK_ABORT: 6363 6426 qlt_abort_work(tgt, prm); 6364 - break; 6365 - case QLA_TGT_SESS_WORK_TM: 6366 - qlt_tmr_work(tgt, prm); 6367 6427 break; 6368 6428 default: 6369 6429 BUG_ON(1); ··· 6448 6514 tgt->ha = ha; 6449 6515 tgt->vha = base_vha; 6450 6516 init_waitqueue_head(&tgt->waitQ); 6451 - INIT_LIST_HEAD(&tgt->del_sess_list); 6452 6517 spin_lock_init(&tgt->sess_work_lock); 6453 6518 INIT_WORK(&tgt->sess_work, qlt_sess_work_fn); 6454 6519 INIT_LIST_HEAD(&tgt->sess_works_list);
-6
drivers/scsi/qla2xxx/qla_target.h
··· 813 813 /* Count of sessions refering qla_tgt. Protected by hardware_lock. */ 814 814 int sess_count; 815 815 816 - /* Protected by hardware_lock */ 817 - struct list_head del_sess_list; 818 - 819 816 spinlock_t sess_work_lock; 820 817 struct list_head sess_works_list; 821 818 struct work_struct sess_work; ··· 942 945 struct list_head sess_works_list_entry; 943 946 944 947 #define QLA_TGT_SESS_WORK_ABORT 1 945 - #define QLA_TGT_SESS_WORK_TM 2 946 948 int type; 947 949 948 950 union { ··· 1075 1079 struct init_cb_81xx *); 1076 1080 extern void qlt_81xx_config_nvram_stage1(struct scsi_qla_host *, 1077 1081 struct nvram_81xx *); 1078 - extern int qlt_24xx_process_response_error(struct scsi_qla_host *, 1079 - struct sts_entry_24xx *); 1080 1082 extern void qlt_modify_vp_config(struct scsi_qla_host *, 1081 1083 struct vp_config_entry_24xx *); 1082 1084 extern void qlt_probe_one_stage1(struct scsi_qla_host *, struct qla_hw_data *);
+2 -2
drivers/scsi/qla2xxx/qla_version.h
··· 6 6 /* 7 7 * Driver version 8 8 */ 9 - #define QLA2XXX_VERSION "10.02.07.800-k" 9 + #define QLA2XXX_VERSION "10.02.07.900-k" 10 10 11 11 #define QLA_DRIVER_MAJOR_VER 10 12 12 #define QLA_DRIVER_MINOR_VER 2 13 13 #define QLA_DRIVER_PATCH_VER 7 14 - #define QLA_DRIVER_BETA_VER 800 14 + #define QLA_DRIVER_BETA_VER 900
+2 -1
drivers/scsi/qlogicpti.c
··· 909 909 sg_count = dma_map_sg(&qpti->op->dev, sg, 910 910 scsi_sg_count(Cmnd), 911 911 Cmnd->sc_data_direction); 912 - 912 + if (!sg_count) 913 + return -1; 913 914 ds = cmd->dataseg; 914 915 cmd->segment_cnt = sg_count; 915 916
+12 -6
drivers/scsi/scsi_error.c
··· 334 334 trace_scsi_dispatch_cmd_timeout(scmd); 335 335 scsi_log_completion(scmd, TIMEOUT_ERROR); 336 336 337 + atomic_inc(&scmd->device->iotmo_cnt); 337 338 if (host->eh_deadline != -1 && !host->last_reset) 338 339 host->last_reset = jiffies; 339 340 ··· 515 514 } 516 515 } 517 516 517 + static inline void set_scsi_ml_byte(struct scsi_cmnd *cmd, u8 status) 518 + { 519 + cmd->result = (cmd->result & 0xffff00ff) | (status << 8); 520 + } 521 + 518 522 /** 519 523 * scsi_check_sense - Examine scsi cmd sense 520 524 * @scmd: Cmd to have sense checked. ··· 650 644 case DATA_PROTECT: 651 645 if (sshdr.asc == 0x27 && sshdr.ascq == 0x07) { 652 646 /* Thin provisioning hard threshold reached */ 653 - set_host_byte(scmd, DID_ALLOC_FAILURE); 647 + set_scsi_ml_byte(scmd, SCSIML_STAT_NOSPC); 654 648 return SUCCESS; 655 649 } 656 650 fallthrough; ··· 658 652 case VOLUME_OVERFLOW: 659 653 case MISCOMPARE: 660 654 case BLANK_CHECK: 661 - set_host_byte(scmd, DID_TARGET_FAILURE); 655 + set_scsi_ml_byte(scmd, SCSIML_STAT_TGT_FAILURE); 662 656 return SUCCESS; 663 657 664 658 case MEDIUM_ERROR: 665 659 if (sshdr.asc == 0x11 || /* UNRECOVERED READ ERR */ 666 660 sshdr.asc == 0x13 || /* AMNF DATA FIELD */ 667 661 sshdr.asc == 0x14) { /* RECORD NOT FOUND */ 668 - set_host_byte(scmd, DID_MEDIUM_ERROR); 662 + set_scsi_ml_byte(scmd, SCSIML_STAT_MED_ERROR); 669 663 return SUCCESS; 670 664 } 671 665 return NEEDS_RETRY; ··· 674 668 if (scmd->device->retry_hwerror) 675 669 return ADD_TO_MLQUEUE; 676 670 else 677 - set_host_byte(scmd, DID_TARGET_FAILURE); 671 + set_scsi_ml_byte(scmd, SCSIML_STAT_TGT_FAILURE); 678 672 fallthrough; 679 673 680 674 case ILLEGAL_REQUEST: ··· 684 678 sshdr.asc == 0x24 || /* Invalid field in cdb */ 685 679 sshdr.asc == 0x26 || /* Parameter value invalid */ 686 680 sshdr.asc == 0x27) { /* Write protected */ 687 - set_host_byte(scmd, DID_TARGET_FAILURE); 681 + set_scsi_ml_byte(scmd, SCSIML_STAT_TGT_FAILURE); 688 682 } 689 683 return SUCCESS; 690 684 ··· 1989 1983 case SAM_STAT_RESERVATION_CONFLICT: 1990 1984 sdev_printk(KERN_INFO, scmd->device, 1991 1985 "reservation conflict\n"); 1992 - set_host_byte(scmd, DID_NEXUS_FAILURE); 1986 + set_scsi_ml_byte(scmd, SCSIML_STAT_RESV_CONFLICT); 1993 1987 return SUCCESS; /* causes immediate i/o error */ 1994 1988 } 1995 1989 return FAILED;
+27 -19
drivers/scsi/scsi_lib.c
··· 581 581 return false; 582 582 } 583 583 584 + static inline u8 get_scsi_ml_byte(int result) 585 + { 586 + return (result >> 8) & 0xff; 587 + } 588 + 584 589 /** 585 590 * scsi_result_to_blk_status - translate a SCSI result code into blk_status_t 586 - * @cmd: SCSI command 587 591 * @result: scsi error code 588 592 * 589 - * Translate a SCSI result code into a blk_status_t value. May reset the host 590 - * byte of @cmd->result. 593 + * Translate a SCSI result code into a blk_status_t value. 591 594 */ 592 - static blk_status_t scsi_result_to_blk_status(struct scsi_cmnd *cmd, int result) 595 + static blk_status_t scsi_result_to_blk_status(int result) 593 596 { 597 + /* 598 + * Check the scsi-ml byte first in case we converted a host or status 599 + * byte. 600 + */ 601 + switch (get_scsi_ml_byte(result)) { 602 + case SCSIML_STAT_OK: 603 + break; 604 + case SCSIML_STAT_RESV_CONFLICT: 605 + return BLK_STS_NEXUS; 606 + case SCSIML_STAT_NOSPC: 607 + return BLK_STS_NOSPC; 608 + case SCSIML_STAT_MED_ERROR: 609 + return BLK_STS_MEDIUM; 610 + case SCSIML_STAT_TGT_FAILURE: 611 + return BLK_STS_TARGET; 612 + } 613 + 594 614 switch (host_byte(result)) { 595 615 case DID_OK: 596 616 if (scsi_status_is_good(result)) ··· 619 599 case DID_TRANSPORT_FAILFAST: 620 600 case DID_TRANSPORT_MARGINAL: 621 601 return BLK_STS_TRANSPORT; 622 - case DID_TARGET_FAILURE: 623 - set_host_byte(cmd, DID_OK); 624 - return BLK_STS_TARGET; 625 - case DID_NEXUS_FAILURE: 626 - set_host_byte(cmd, DID_OK); 627 - return BLK_STS_NEXUS; 628 - case DID_ALLOC_FAILURE: 629 - set_host_byte(cmd, DID_OK); 630 - return BLK_STS_NOSPC; 631 - case DID_MEDIUM_ERROR: 632 - set_host_byte(cmd, DID_OK); 633 - return BLK_STS_MEDIUM; 634 602 default: 635 603 return BLK_STS_IOERR; 636 604 } ··· 705 697 if (sense_valid) 706 698 sense_current = !scsi_sense_is_deferred(&sshdr); 707 699 708 - blk_stat = scsi_result_to_blk_status(cmd, result); 700 + blk_stat = scsi_result_to_blk_status(result); 709 701 710 702 if (host_byte(result) == DID_RESET) { 711 703 /* Third party bus reset or reset for error recovery ··· 886 878 SCSI_SENSE_BUFFERSIZE); 887 879 } 888 880 if (sense_current) 889 - *blk_statp = scsi_result_to_blk_status(cmd, result); 881 + *blk_statp = scsi_result_to_blk_status(result); 890 882 } else if (blk_rq_bytes(req) == 0 && sense_current) { 891 883 /* 892 884 * Flush commands do not transfers any data, and thus cannot use 893 885 * good_bytes != blk_rq_bytes(req) as the signal for an error. 894 886 * This sets *blk_statp explicitly for the problem case. 895 887 */ 896 - *blk_statp = scsi_result_to_blk_status(cmd, result); 888 + *blk_statp = scsi_result_to_blk_status(result); 897 889 } 898 890 /* 899 891 * Recovered errors need reporting, but they're always treated as
+11
drivers/scsi/scsi_priv.h
··· 19 19 #define SCSI_CMD_RETRIES_NO_LIMIT -1 20 20 21 21 /* 22 + * Error codes used by scsi-ml internally. These must not be used by drivers. 23 + */ 24 + enum scsi_ml_status { 25 + SCSIML_STAT_OK = 0x00, 26 + SCSIML_STAT_RESV_CONFLICT = 0x01, /* Reservation conflict */ 27 + SCSIML_STAT_NOSPC = 0x02, /* Space allocation on the dev failed */ 28 + SCSIML_STAT_MED_ERROR = 0x03, /* Medium error */ 29 + SCSIML_STAT_TGT_FAILURE = 0x04, /* Permanent target failure */ 30 + }; 31 + 32 + /* 22 33 * Scsi Error Handler Flags 23 34 */ 24 35 #define SCSI_EH_ABORT_SCHEDULED 0x0002 /* Abort has been scheduled */
+2
drivers/scsi/scsi_sysfs.c
··· 976 976 show_sdev_iostat(iorequest_cnt); 977 977 show_sdev_iostat(iodone_cnt); 978 978 show_sdev_iostat(ioerr_cnt); 979 + show_sdev_iostat(iotmo_cnt); 979 980 980 981 static ssize_t 981 982 sdev_show_modalias(struct device *dev, struct device_attribute *attr, char *buf) ··· 1296 1295 &dev_attr_iorequest_cnt.attr, 1297 1296 &dev_attr_iodone_cnt.attr, 1298 1297 &dev_attr_ioerr_cnt.attr, 1298 + &dev_attr_iotmo_cnt.attr, 1299 1299 &dev_attr_modalias.attr, 1300 1300 &dev_attr_queue_depth.attr, 1301 1301 &dev_attr_queue_type.attr,
+6 -4
drivers/scsi/scsi_transport_fc.c
··· 543 543 struct nlmsghdr *nlh; 544 544 struct fc_nl_event *event; 545 545 const char *name; 546 - u32 len; 546 + size_t len, padding; 547 547 int err; 548 548 549 549 if (!data_buf || data_len < 4) ··· 554 554 goto send_fail; 555 555 } 556 556 557 - len = FC_NL_MSGALIGN(sizeof(*event) + data_len); 557 + len = FC_NL_MSGALIGN(sizeof(*event) - sizeof(event->event_data) + data_len); 558 558 559 559 skb = nlmsg_new(len, GFP_KERNEL); 560 560 if (!skb) { ··· 578 578 event->event_num = event_number; 579 579 event->event_code = event_code; 580 580 if (data_len) 581 - memcpy(&event->event_data, data_buf, data_len); 581 + memcpy(event->event_data_flex, data_buf, data_len); 582 + padding = len - offsetof(typeof(*event), event_data_flex) - data_len; 583 + memset(event->event_data_flex + data_len, 0, padding); 582 584 583 585 nlmsg_multicast(scsi_nl_sock, skb, 0, SCSI_NL_GRP_FC_EVENTS, 584 586 GFP_KERNEL); ··· 1172 1170 return 0; 1173 1171 } 1174 1172 1175 - fc_rport_show_function(dev_loss_tmo, "%d\n", 20, ) 1173 + fc_rport_show_function(dev_loss_tmo, "%u\n", 20, ) 1176 1174 static ssize_t 1177 1175 store_fc_rport_dev_loss_tmo(struct device *dev, struct device_attribute *attr, 1178 1176 const char *buf, size_t count)
+1 -2
drivers/scsi/st.c
··· 4248 4248 struct st_partstat *STps; 4249 4249 struct st_buffer *buffer; 4250 4250 int i, error; 4251 - char *stp; 4252 4251 4253 4252 if (SDp->type != TYPE_TAPE) 4254 4253 return -ENODEV; 4255 - if ((stp = st_incompatible(SDp))) { 4254 + if (st_incompatible(SDp)) { 4256 4255 sdev_printk(KERN_INFO, SDp, 4257 4256 "OnStream tapes are no longer supported;\n"); 4258 4257 sdev_printk(KERN_INFO, SDp,
+9 -8
drivers/scsi/stex.c
··· 665 665 return 0; 666 666 case PASSTHRU_CMD: 667 667 if (cmd->cmnd[1] == PASSTHRU_GET_DRVVER) { 668 - struct st_drvver ver; 668 + const struct st_drvver ver = { 669 + .major = ST_VER_MAJOR, 670 + .minor = ST_VER_MINOR, 671 + .oem = ST_OEM, 672 + .build = ST_BUILD_VER, 673 + .signature[0] = PASSTHRU_SIGNATURE, 674 + .console_id = host->max_id - 1, 675 + .host_no = hba->host->host_no, 676 + }; 669 677 size_t cp_len = sizeof(ver); 670 678 671 - ver.major = ST_VER_MAJOR; 672 - ver.minor = ST_VER_MINOR; 673 - ver.oem = ST_OEM; 674 - ver.build = ST_BUILD_VER; 675 - ver.signature[0] = PASSTHRU_SIGNATURE; 676 - ver.console_id = host->max_id - 1; 677 - ver.host_no = hba->host->host_no; 678 679 cp_len = scsi_sg_copy_from_buffer(cmd, &ver, cp_len); 679 680 if (sizeof(ver) == cp_len) 680 681 cmd->result = DID_OK << 16;
+1 -1
drivers/scsi/storvsc_drv.c
··· 1029 1029 */ 1030 1030 wrk = kmalloc(sizeof(struct storvsc_scan_work), GFP_ATOMIC); 1031 1031 if (!wrk) { 1032 - set_host_byte(scmnd, DID_TARGET_FAILURE); 1032 + set_host_byte(scmnd, DID_BAD_TARGET); 1033 1033 return; 1034 1034 } 1035 1035
+2 -2
drivers/scsi/virtio_scsi.c
··· 141 141 set_host_byte(sc, DID_TRANSPORT_DISRUPTED); 142 142 break; 143 143 case VIRTIO_SCSI_S_TARGET_FAILURE: 144 - set_host_byte(sc, DID_TARGET_FAILURE); 144 + set_host_byte(sc, DID_BAD_TARGET); 145 145 break; 146 146 case VIRTIO_SCSI_S_NEXUS_FAILURE: 147 - set_host_byte(sc, DID_NEXUS_FAILURE); 147 + set_status_byte(sc, SAM_STAT_RESERVATION_CONFLICT); 148 148 break; 149 149 default: 150 150 scmd_printk(KERN_WARNING, sc, "Unknown response %d",
-60
drivers/scsi/wd33c93.c
··· 162 162 163 163 static void wd33c93_execute(struct Scsi_Host *instance); 164 164 165 - #ifdef CONFIG_WD33C93_PIO 166 - static inline uchar 167 - read_wd33c93(const wd33c93_regs regs, uchar reg_num) 168 - { 169 - uchar data; 170 - 171 - outb(reg_num, regs.SASR); 172 - data = inb(regs.SCMD); 173 - return data; 174 - } 175 - 176 - static inline unsigned long 177 - read_wd33c93_count(const wd33c93_regs regs) 178 - { 179 - unsigned long value; 180 - 181 - outb(WD_TRANSFER_COUNT_MSB, regs.SASR); 182 - value = inb(regs.SCMD) << 16; 183 - value |= inb(regs.SCMD) << 8; 184 - value |= inb(regs.SCMD); 185 - return value; 186 - } 187 - 188 - static inline uchar 189 - read_aux_stat(const wd33c93_regs regs) 190 - { 191 - return inb(regs.SASR); 192 - } 193 - 194 - static inline void 195 - write_wd33c93(const wd33c93_regs regs, uchar reg_num, uchar value) 196 - { 197 - outb(reg_num, regs.SASR); 198 - outb(value, regs.SCMD); 199 - } 200 - 201 - static inline void 202 - write_wd33c93_count(const wd33c93_regs regs, unsigned long value) 203 - { 204 - outb(WD_TRANSFER_COUNT_MSB, regs.SASR); 205 - outb((value >> 16) & 0xff, regs.SCMD); 206 - outb((value >> 8) & 0xff, regs.SCMD); 207 - outb( value & 0xff, regs.SCMD); 208 - } 209 - 210 - #define write_wd33c93_cmd(regs, cmd) \ 211 - write_wd33c93((regs), WD_COMMAND, (cmd)) 212 - 213 - static inline void 214 - write_wd33c93_cdb(const wd33c93_regs regs, uint len, uchar cmnd[]) 215 - { 216 - int i; 217 - 218 - outb(WD_CDB_1, regs.SASR); 219 - for (i=0; i<len; i++) 220 - outb(cmnd[i], regs.SCMD); 221 - } 222 - 223 - #else /* CONFIG_WD33C93_PIO */ 224 165 static inline uchar 225 166 read_wd33c93(const wd33c93_regs regs, uchar reg_num) 226 167 { ··· 228 287 for (i = 0; i < len; i++) 229 288 *regs.SCMD = cmnd[i]; 230 289 } 231 - #endif /* CONFIG_WD33C93_PIO */ 232 290 233 291 static inline uchar 234 292 read_1_byte(const wd33c93_regs regs)
-5
drivers/scsi/wd33c93.h
··· 180 180 181 181 /* This is what the 3393 chip looks like to us */ 182 182 typedef struct { 183 - #ifdef CONFIG_WD33C93_PIO 184 - unsigned int SASR; 185 - unsigned int SCMD; 186 - #else 187 183 volatile unsigned char *SASR; 188 184 volatile unsigned char *SCMD; 189 - #endif 190 185 } wd33c93_regs; 191 186 192 187
-8
drivers/scsi/xen-scsifront.c
··· 289 289 return DID_TRANSPORT_DISRUPTED; 290 290 case XEN_VSCSIIF_RSLT_HOST_TRANSPORT_FAILFAST: 291 291 return DID_TRANSPORT_FAILFAST; 292 - case XEN_VSCSIIF_RSLT_HOST_TARGET_FAILURE: 293 - return DID_TARGET_FAILURE; 294 - case XEN_VSCSIIF_RSLT_HOST_NEXUS_FAILURE: 295 - return DID_NEXUS_FAILURE; 296 - case XEN_VSCSIIF_RSLT_HOST_ALLOC_FAILURE: 297 - return DID_ALLOC_FAILURE; 298 - case XEN_VSCSIIF_RSLT_HOST_MEDIUM_ERROR: 299 - return DID_MEDIUM_ERROR; 300 292 case XEN_VSCSIIF_RSLT_HOST_TRANSPORT_MARGINAL: 301 293 return DID_TRANSPORT_MARGINAL; 302 294 default:
+3
drivers/target/target_core_alua.c
··· 164 164 spin_lock(&dev->t10_alua.tg_pt_gps_lock); 165 165 list_for_each_entry(tg_pt_gp, &dev->t10_alua.tg_pt_gps_list, 166 166 tg_pt_gp_list) { 167 + /* Skip empty port groups */ 168 + if (!tg_pt_gp->tg_pt_gp_members) 169 + continue; 167 170 /* 168 171 * Check if the Target port group and Target port descriptor list 169 172 * based on tg_pt_gp_members count will fit into the response payload.
-2
drivers/target/target_core_internal.h
··· 133 133 void core_tpg_del_initiator_node_acl(struct se_node_acl *acl); 134 134 135 135 /* target_core_transport.c */ 136 - extern struct kmem_cache *se_tmr_req_cache; 137 - 138 136 int init_se_kmem_caches(void); 139 137 void release_se_kmem_caches(void); 140 138 u32 scsi_get_new_index(scsi_index_t);
+1 -1
drivers/target/target_core_pscsi.c
··· 500 500 continue; 501 501 /* 502 502 * Functions will release the held struct scsi_host->host_lock 503 - * before calling calling pscsi_add_device_to_list() to register 503 + * before calling pscsi_add_device_to_list() to register 504 504 * struct scsi_device with target_core_mod. 505 505 */ 506 506 switch (sd->type) {
+6
drivers/target/target_core_spc.c
··· 115 115 buf[5] |= 0x1; 116 116 } 117 117 118 + /* 119 + * Set MULTIP bit to indicate presence of multiple SCSI target ports 120 + */ 121 + if (dev->export_count > 1) 122 + buf[6] |= 0x10; 123 + 118 124 buf[7] = 0x2; /* CmdQue=1 */ 119 125 120 126 /*
+83 -2
drivers/ufs/core/ufs-sysfs.c
··· 225 225 unsigned int wb_enable; 226 226 ssize_t res; 227 227 228 - if (!ufshcd_is_wb_allowed(hba) || ufshcd_is_clkscaling_supported(hba)) { 228 + if (!ufshcd_is_wb_allowed(hba) || (ufshcd_is_clkscaling_supported(hba) 229 + && ufshcd_enable_wb_if_scaling_up(hba))) { 229 230 /* 230 231 * If the platform supports UFSHCD_CAP_CLK_SCALING, turn WB 231 232 * on/off will be done while clock scaling up/down. 232 233 */ 233 - dev_warn(dev, "To control WB through wb_on is not allowed!\n"); 234 + dev_warn(dev, "It is not allowed to configure WB!\n"); 234 235 return -EOPNOTSUPP; 235 236 } 236 237 ··· 255 254 return res < 0 ? res : count; 256 255 } 257 256 257 + static ssize_t enable_wb_buf_flush_show(struct device *dev, 258 + struct device_attribute *attr, 259 + char *buf) 260 + { 261 + struct ufs_hba *hba = dev_get_drvdata(dev); 262 + 263 + return sysfs_emit(buf, "%d\n", hba->dev_info.wb_buf_flush_enabled); 264 + } 265 + 266 + static ssize_t enable_wb_buf_flush_store(struct device *dev, 267 + struct device_attribute *attr, 268 + const char *buf, size_t count) 269 + { 270 + struct ufs_hba *hba = dev_get_drvdata(dev); 271 + unsigned int enable_wb_buf_flush; 272 + ssize_t res; 273 + 274 + if (!ufshcd_is_wb_buf_flush_allowed(hba)) { 275 + dev_warn(dev, "It is not allowed to configure WB buf flushing!\n"); 276 + return -EOPNOTSUPP; 277 + } 278 + 279 + if (kstrtouint(buf, 0, &enable_wb_buf_flush)) 280 + return -EINVAL; 281 + 282 + if (enable_wb_buf_flush != 0 && enable_wb_buf_flush != 1) 283 + return -EINVAL; 284 + 285 + down(&hba->host_sem); 286 + if (!ufshcd_is_user_access_allowed(hba)) { 287 + res = -EBUSY; 288 + goto out; 289 + } 290 + 291 + ufshcd_rpm_get_sync(hba); 292 + res = ufshcd_wb_toggle_buf_flush(hba, enable_wb_buf_flush); 293 + ufshcd_rpm_put_sync(hba); 294 + 295 + out: 296 + up(&hba->host_sem); 297 + return res < 0 ? res : count; 298 + } 299 + 258 300 static DEVICE_ATTR_RW(rpm_lvl); 259 301 static DEVICE_ATTR_RO(rpm_target_dev_state); 260 302 static DEVICE_ATTR_RO(rpm_target_link_state); ··· 306 262 static DEVICE_ATTR_RO(spm_target_link_state); 307 263 static DEVICE_ATTR_RW(auto_hibern8); 308 264 static DEVICE_ATTR_RW(wb_on); 265 + static DEVICE_ATTR_RW(enable_wb_buf_flush); 309 266 310 267 static struct attribute *ufs_sysfs_ufshcd_attrs[] = { 311 268 &dev_attr_rpm_lvl.attr, ··· 317 272 &dev_attr_spm_target_link_state.attr, 318 273 &dev_attr_auto_hibern8.attr, 319 274 &dev_attr_wb_on.attr, 275 + &dev_attr_enable_wb_buf_flush.attr, 320 276 NULL 321 277 }; 322 278 323 279 static const struct attribute_group ufs_sysfs_default_group = { 324 280 .attrs = ufs_sysfs_ufshcd_attrs, 281 + }; 282 + 283 + static ssize_t clock_scaling_show(struct device *dev, struct device_attribute *attr, 284 + char *buf) 285 + { 286 + struct ufs_hba *hba = dev_get_drvdata(dev); 287 + 288 + return sysfs_emit(buf, "%d\n", ufshcd_is_clkscaling_supported(hba)); 289 + } 290 + 291 + static ssize_t write_booster_show(struct device *dev, struct device_attribute *attr, 292 + char *buf) 293 + { 294 + struct ufs_hba *hba = dev_get_drvdata(dev); 295 + 296 + return sysfs_emit(buf, "%d\n", ufshcd_is_wb_allowed(hba)); 297 + } 298 + 299 + static DEVICE_ATTR_RO(clock_scaling); 300 + static DEVICE_ATTR_RO(write_booster); 301 + 302 + /* 303 + * See Documentation/ABI/testing/sysfs-driver-ufs for the semantics of this 304 + * group. 305 + */ 306 + static struct attribute *ufs_sysfs_capabilities_attrs[] = { 307 + &dev_attr_clock_scaling.attr, 308 + &dev_attr_write_booster.attr, 309 + NULL 310 + }; 311 + 312 + static const struct attribute_group ufs_sysfs_capabilities_group = { 313 + .name = "capabilities", 314 + .attrs = ufs_sysfs_capabilities_attrs, 325 315 }; 326 316 327 317 static ssize_t monitor_enable_show(struct device *dev, ··· 1214 1134 1215 1135 static const struct attribute_group *ufs_sysfs_groups[] = { 1216 1136 &ufs_sysfs_default_group, 1137 + &ufs_sysfs_capabilities_group, 1217 1138 &ufs_sysfs_monitor_group, 1218 1139 &ufs_sysfs_device_descriptor_group, 1219 1140 &ufs_sysfs_interconnect_descriptor_group,
+11
drivers/ufs/core/ufshcd-priv.h
··· 26 26 return 0; 27 27 } 28 28 29 + static inline bool ufshcd_is_wb_buf_flush_allowed(struct ufs_hba *hba) 30 + { 31 + return ufshcd_is_wb_allowed(hba) && 32 + !(hba->quirks & UFSHCI_QUIRK_SKIP_MANUAL_WB_FLUSH_CTRL); 33 + } 34 + 29 35 #ifdef CONFIG_SCSI_UFS_HWMON 30 36 void ufs_hwmon_probe(struct ufs_hba *hba, u8 mask); 31 37 void ufs_hwmon_remove(struct ufs_hba *hba); ··· 42 36 static inline void ufs_hwmon_notify_event(struct ufs_hba *hba, u8 ee_mask) {} 43 37 #endif 44 38 39 + int ufshcd_query_descriptor_retry(struct ufs_hba *hba, 40 + enum query_opcode opcode, 41 + enum desc_idn idn, u8 index, 42 + u8 selector, 43 + u8 *desc_buf, int *buf_len); 45 44 int ufshcd_read_desc_param(struct ufs_hba *hba, 46 45 enum desc_idn desc_id, 47 46 int desc_index,
+52 -43
drivers/ufs/core/ufshcd.c
··· 21 21 #include <linux/interrupt.h> 22 22 #include <linux/module.h> 23 23 #include <linux/regulator/consumer.h> 24 + #include <linux/sched/clock.h> 24 25 #include <scsi/scsi_cmnd.h> 25 26 #include <scsi/scsi_dbg.h> 26 27 #include <scsi/scsi_driver.h> ··· 266 265 static inline int ufshcd_config_vreg_hpm(struct ufs_hba *hba, 267 266 struct ufs_vreg *vreg); 268 267 static int ufshcd_try_to_abort_task(struct ufs_hba *hba, int tag); 269 - static void ufshcd_wb_toggle_flush_during_h8(struct ufs_hba *hba, bool set); 270 - static inline void ufshcd_wb_toggle_flush(struct ufs_hba *hba, bool enable); 268 + static void ufshcd_wb_toggle_buf_flush_during_h8(struct ufs_hba *hba, 269 + bool enable); 271 270 static void ufshcd_hba_vreg_set_lpm(struct ufs_hba *hba); 272 271 static void ufshcd_hba_vreg_set_hpm(struct ufs_hba *hba); 273 272 ··· 287 286 } 288 287 } 289 288 290 - static inline void ufshcd_wb_config(struct ufs_hba *hba) 289 + static void ufshcd_configure_wb(struct ufs_hba *hba) 291 290 { 292 291 if (!ufshcd_is_wb_allowed(hba)) 293 292 return; 294 293 295 294 ufshcd_wb_toggle(hba, true); 296 295 297 - ufshcd_wb_toggle_flush_during_h8(hba, true); 298 - if (!(hba->quirks & UFSHCI_QUIRK_SKIP_MANUAL_WB_FLUSH_CTRL)) 299 - ufshcd_wb_toggle_flush(hba, true); 296 + ufshcd_wb_toggle_buf_flush_during_h8(hba, true); 297 + 298 + if (ufshcd_is_wb_buf_flush_allowed(hba)) 299 + ufshcd_wb_toggle_buf_flush(hba, true); 300 300 } 301 301 302 302 static void ufshcd_scsi_unblock_requests(struct ufs_hba *hba) ··· 459 457 if (e->tstamp[p] == 0) 460 458 continue; 461 459 dev_err(hba->dev, "%s[%d] = 0x%x at %lld us\n", err_name, p, 462 - e->val[p], ktime_to_us(e->tstamp[p])); 460 + e->val[p], div_u64(e->tstamp[p], 1000)); 463 461 found = true; 464 462 } 465 463 ··· 504 502 lrbp = &hba->lrb[tag]; 505 503 506 504 dev_err(hba->dev, "UPIU[%d] - issue time %lld us\n", 507 - tag, ktime_to_us(lrbp->issue_time_stamp)); 505 + tag, div_u64(lrbp->issue_time_stamp_local_clock, 1000)); 508 506 dev_err(hba->dev, "UPIU[%d] - complete time %lld us\n", 509 - tag, ktime_to_us(lrbp->compl_time_stamp)); 507 + tag, div_u64(lrbp->compl_time_stamp_local_clock, 1000)); 510 508 dev_err(hba->dev, 511 509 "UPIU[%d] - Transfer Request Descriptor phys@0x%llx\n", 512 510 tag, (u64)lrbp->utrd_dma_addr); ··· 568 566 dev_err(hba->dev, "Clk gate=%d\n", hba->clk_gating.state); 569 567 dev_err(hba->dev, 570 568 "last_hibern8_exit_tstamp at %lld us, hibern8_exit_cnt=%d\n", 571 - ktime_to_us(hba->ufs_stats.last_hibern8_exit_tstamp), 569 + div_u64(hba->ufs_stats.last_hibern8_exit_tstamp, 1000), 572 570 hba->ufs_stats.hibern8_exit_cnt); 573 571 dev_err(hba->dev, "last intr at %lld us, last intr status=0x%x\n", 574 - ktime_to_us(hba->ufs_stats.last_intr_ts), 572 + div_u64(hba->ufs_stats.last_intr_ts, 1000), 575 573 hba->ufs_stats.last_intr_status); 576 574 dev_err(hba->dev, "error handling flags=0x%x, req. abort count=%d\n", 577 575 hba->eh_flags, hba->req_abort_count); ··· 1300 1298 } 1301 1299 1302 1300 /* Enable Write Booster if we have scaled up else disable it */ 1303 - downgrade_write(&hba->clk_scaling_lock); 1304 - is_writelock = false; 1305 - ufshcd_wb_toggle(hba, scale_up); 1301 + if (ufshcd_enable_wb_if_scaling_up(hba)) { 1302 + downgrade_write(&hba->clk_scaling_lock); 1303 + is_writelock = false; 1304 + ufshcd_wb_toggle(hba, scale_up); 1305 + } 1306 1306 1307 1307 out_unprepare: 1308 1308 ufshcd_clock_scaling_unprepare(hba, is_writelock); ··· 2144 2140 unsigned long flags; 2145 2141 2146 2142 lrbp->issue_time_stamp = ktime_get(); 2143 + lrbp->issue_time_stamp_local_clock = local_clock(); 2147 2144 lrbp->compl_time_stamp = ktime_set(0, 0); 2145 + lrbp->compl_time_stamp_local_clock = 0; 2148 2146 ufshcd_add_command_trace(hba, task_tag, UFS_CMD_SEND); 2149 2147 ufshcd_clk_scaling_start_busy(hba); 2150 2148 if (unlikely(ufshcd_should_inform_monitor(hba, lrbp))) ··· 4225 4219 } else { 4226 4220 ufshcd_vops_hibern8_notify(hba, UIC_CMD_DME_HIBER_EXIT, 4227 4221 POST_CHANGE); 4228 - hba->ufs_stats.last_hibern8_exit_tstamp = ktime_get(); 4222 + hba->ufs_stats.last_hibern8_exit_tstamp = local_clock(); 4229 4223 hba->ufs_stats.hibern8_exit_cnt++; 4230 4224 } 4231 4225 ··· 4727 4721 4728 4722 e = &hba->ufs_stats.event[id]; 4729 4723 e->val[e->pos] = val; 4730 - e->tstamp[e->pos] = ktime_get(); 4724 + e->tstamp[e->pos] = local_clock(); 4731 4725 e->cnt += 1; 4732 4726 e->pos = (e->pos + 1) % UFS_EVENT_HIST_LENGTH; 4733 4727 ··· 5360 5354 for_each_set_bit(index, &completed_reqs, hba->nutrs) { 5361 5355 lrbp = &hba->lrb[index]; 5362 5356 lrbp->compl_time_stamp = ktime_get(); 5357 + lrbp->compl_time_stamp_local_clock = local_clock(); 5363 5358 cmd = lrbp->cmd; 5364 5359 if (cmd) { 5365 5360 if (unlikely(ufshcd_should_inform_monitor(hba, lrbp))) ··· 5756 5749 { 5757 5750 int ret; 5758 5751 5759 - if (!ufshcd_is_wb_allowed(hba)) 5760 - return 0; 5761 - 5762 - if (!(enable ^ hba->dev_info.wb_enabled)) 5752 + if (!ufshcd_is_wb_allowed(hba) || 5753 + hba->dev_info.wb_enabled == enable) 5763 5754 return 0; 5764 5755 5765 5756 ret = __ufshcd_wb_toggle(hba, enable, QUERY_FLAG_IDN_WB_EN); 5766 5757 if (ret) { 5767 - dev_err(hba->dev, "%s Write Booster %s failed %d\n", 5768 - __func__, enable ? "enable" : "disable", ret); 5758 + dev_err(hba->dev, "%s: Write Booster %s failed %d\n", 5759 + __func__, enable ? "enabling" : "disabling", ret); 5769 5760 return ret; 5770 5761 } 5771 5762 5772 5763 hba->dev_info.wb_enabled = enable; 5773 - dev_dbg(hba->dev, "%s Write Booster %s\n", 5764 + dev_dbg(hba->dev, "%s: Write Booster %s\n", 5774 5765 __func__, enable ? "enabled" : "disabled"); 5775 5766 5776 5767 return ret; 5777 5768 } 5778 5769 5779 - static void ufshcd_wb_toggle_flush_during_h8(struct ufs_hba *hba, bool set) 5770 + static void ufshcd_wb_toggle_buf_flush_during_h8(struct ufs_hba *hba, 5771 + bool enable) 5780 5772 { 5781 5773 int ret; 5782 5774 5783 - ret = __ufshcd_wb_toggle(hba, set, 5775 + ret = __ufshcd_wb_toggle(hba, enable, 5784 5776 QUERY_FLAG_IDN_WB_BUFF_FLUSH_DURING_HIBERN8); 5785 5777 if (ret) { 5786 - dev_err(hba->dev, "%s: WB-Buf Flush during H8 %s failed: %d\n", 5787 - __func__, set ? "enable" : "disable", ret); 5778 + dev_err(hba->dev, "%s: WB-Buf Flush during H8 %s failed %d\n", 5779 + __func__, enable ? "enabling" : "disabling", ret); 5788 5780 return; 5789 5781 } 5790 - dev_dbg(hba->dev, "%s WB-Buf Flush during H8 %s\n", 5791 - __func__, set ? "enabled" : "disabled"); 5782 + dev_dbg(hba->dev, "%s: WB-Buf Flush during H8 %s\n", 5783 + __func__, enable ? "enabled" : "disabled"); 5792 5784 } 5793 5785 5794 - static inline void ufshcd_wb_toggle_flush(struct ufs_hba *hba, bool enable) 5786 + int ufshcd_wb_toggle_buf_flush(struct ufs_hba *hba, bool enable) 5795 5787 { 5796 5788 int ret; 5797 5789 5798 5790 if (!ufshcd_is_wb_allowed(hba) || 5799 5791 hba->dev_info.wb_buf_flush_enabled == enable) 5800 - return; 5792 + return 0; 5801 5793 5802 5794 ret = __ufshcd_wb_toggle(hba, enable, QUERY_FLAG_IDN_WB_BUFF_FLUSH_EN); 5803 5795 if (ret) { 5804 - dev_err(hba->dev, "%s WB-Buf Flush %s failed %d\n", __func__, 5805 - enable ? "enable" : "disable", ret); 5806 - return; 5796 + dev_err(hba->dev, "%s: WB-Buf Flush %s failed %d\n", 5797 + __func__, enable ? "enabling" : "disabling", ret); 5798 + return ret; 5807 5799 } 5808 5800 5809 5801 hba->dev_info.wb_buf_flush_enabled = enable; 5810 - 5811 - dev_dbg(hba->dev, "%s WB-Buf Flush %s\n", 5802 + dev_dbg(hba->dev, "%s: WB-Buf Flush %s\n", 5812 5803 __func__, enable ? "enabled" : "disabled"); 5804 + 5805 + return ret; 5813 5806 } 5814 5807 5815 5808 static bool ufshcd_wb_presrv_usrspc_keep_vcc_on(struct ufs_hba *hba, ··· 5824 5817 QUERY_ATTR_IDN_CURR_WB_BUFF_SIZE, 5825 5818 index, 0, &cur_buf); 5826 5819 if (ret) { 5827 - dev_err(hba->dev, "%s dCurWriteBoosterBufferSize read failed %d\n", 5820 + dev_err(hba->dev, "%s: dCurWriteBoosterBufferSize read failed %d\n", 5828 5821 __func__, ret); 5829 5822 return false; 5830 5823 } ··· 5840 5833 5841 5834 static void ufshcd_wb_force_disable(struct ufs_hba *hba) 5842 5835 { 5843 - if (!(hba->quirks & UFSHCI_QUIRK_SKIP_MANUAL_WB_FLUSH_CTRL)) 5844 - ufshcd_wb_toggle_flush(hba, false); 5836 + if (ufshcd_is_wb_buf_flush_allowed(hba)) 5837 + ufshcd_wb_toggle_buf_flush(hba, false); 5845 5838 5846 - ufshcd_wb_toggle_flush_during_h8(hba, false); 5839 + ufshcd_wb_toggle_buf_flush_during_h8(hba, false); 5847 5840 ufshcd_wb_toggle(hba, false); 5848 5841 hba->caps &= ~UFSHCD_CAP_WB_EN; 5849 5842 ··· 5909 5902 QUERY_ATTR_IDN_AVAIL_WB_BUFF_SIZE, 5910 5903 index, 0, &avail_buf); 5911 5904 if (ret) { 5912 - dev_warn(hba->dev, "%s dAvailableWriteBoosterBufferSize read failed %d\n", 5905 + dev_warn(hba->dev, "%s: dAvailableWriteBoosterBufferSize read failed %d\n", 5913 5906 __func__, ret); 5914 5907 return false; 5915 5908 } ··· 6649 6642 6650 6643 intr_status = ufshcd_readl(hba, REG_INTERRUPT_STATUS); 6651 6644 hba->ufs_stats.last_intr_status = intr_status; 6652 - hba->ufs_stats.last_intr_ts = ktime_get(); 6645 + hba->ufs_stats.last_intr_ts = local_clock(); 6653 6646 6654 6647 /* 6655 6648 * There could be max of hba->nutrs reqs in flight and in worst case ··· 8240 8233 */ 8241 8234 ufshcd_set_active_icc_lvl(hba); 8242 8235 8243 - ufshcd_wb_config(hba); 8236 + /* Enable UFS Write Booster if supported */ 8237 + ufshcd_configure_wb(hba); 8238 + 8244 8239 if (hba->ee_usr_mask) 8245 8240 ufshcd_write_ee_control(hba); 8246 8241 /* Enable Auto-Hibernate if configured */
+25 -2
drivers/ufs/host/ufs-mediatek-trace.h
··· 24 24 __entry->data = data; 25 25 ), 26 26 27 - TP_printk("ufs:event=%u data=%u", 27 + TP_printk("ufs: event=%u data=%u", 28 28 __entry->type, __entry->data) 29 - ); 29 + ); 30 + 31 + TRACE_EVENT(ufs_mtk_clk_scale, 32 + TP_PROTO(const char *name, bool scale_up, unsigned long clk_rate), 33 + TP_ARGS(name, scale_up, clk_rate), 34 + 35 + TP_STRUCT__entry( 36 + __field(const char*, name) 37 + __field(bool, scale_up) 38 + __field(unsigned long, clk_rate) 39 + ), 40 + 41 + TP_fast_assign( 42 + __entry->name = name; 43 + __entry->scale_up = scale_up; 44 + __entry->clk_rate = clk_rate; 45 + ), 46 + 47 + TP_printk("ufs: clk (%s) scaled %s @ %lu", 48 + __entry->name, 49 + __entry->scale_up ? "up" : "down", 50 + __entry->clk_rate) 51 + ); 52 + 30 53 #endif 31 54 32 55 #undef TRACE_INCLUDE_PATH
+198 -7
drivers/ufs/host/ufs-mediatek.c
··· 19 19 #include <linux/pm_qos.h> 20 20 #include <linux/regulator/consumer.h> 21 21 #include <linux/reset.h> 22 - #include <linux/sched/clock.h> 23 22 #include <linux/soc/mediatek/mtk_sip_svc.h> 24 23 25 24 #include <ufs/ufshcd.h> ··· 44 45 static const struct of_device_id ufs_mtk_of_match[] = { 45 46 { .compatible = "mediatek,mt8183-ufshci" }, 46 47 {}, 48 + }; 49 + 50 + /* 51 + * Details of UIC Errors 52 + */ 53 + static const char *const ufs_uic_err_str[] = { 54 + "PHY Adapter Layer", 55 + "Data Link Layer", 56 + "Network Link Layer", 57 + "Transport Link Layer", 58 + "DME" 59 + }; 60 + 61 + static const char *const ufs_uic_pa_err_str[] = { 62 + "PHY error on Lane 0", 63 + "PHY error on Lane 1", 64 + "PHY error on Lane 2", 65 + "PHY error on Lane 3", 66 + "Generic PHY Adapter Error. This should be the LINERESET indication" 67 + }; 68 + 69 + static const char *const ufs_uic_dl_err_str[] = { 70 + "NAC_RECEIVED", 71 + "TCx_REPLAY_TIMER_EXPIRED", 72 + "AFCx_REQUEST_TIMER_EXPIRED", 73 + "FCx_PROTECTION_TIMER_EXPIRED", 74 + "CRC_ERROR", 75 + "RX_BUFFER_OVERFLOW", 76 + "MAX_FRAME_LENGTH_EXCEEDED", 77 + "WRONG_SEQUENCE_NUMBER", 78 + "AFC_FRAME_SYNTAX_ERROR", 79 + "NAC_FRAME_SYNTAX_ERROR", 80 + "EOF_SYNTAX_ERROR", 81 + "FRAME_SYNTAX_ERROR", 82 + "BAD_CTRL_SYMBOL_TYPE", 83 + "PA_INIT_ERROR", 84 + "PA_ERROR_IND_RECEIVED", 85 + "PA_INIT" 47 86 }; 48 87 49 88 static bool ufs_mtk_is_boost_crypt_enabled(struct ufs_hba *hba) ··· 635 598 boost ? 0 : PM_QOS_DEFAULT_VALUE); 636 599 } 637 600 601 + static void ufs_mtk_scale_perf(struct ufs_hba *hba, bool scale_up) 602 + { 603 + ufs_mtk_boost_crypt(hba, scale_up); 604 + ufs_mtk_boost_pm_qos(hba, scale_up); 605 + } 606 + 638 607 static void ufs_mtk_pwr_ctrl(struct ufs_hba *hba, bool on) 639 608 { 640 609 struct ufs_mtk_host *host = ufshcd_get_variant(hba); ··· 648 605 if (on) { 649 606 phy_power_on(host->mphy); 650 607 ufs_mtk_setup_ref_clk(hba, on); 651 - ufs_mtk_boost_crypt(hba, on); 652 - ufs_mtk_boost_pm_qos(hba, on); 608 + if (!ufshcd_is_clkscaling_supported(hba)) 609 + ufs_mtk_scale_perf(hba, on); 653 610 } else { 654 - ufs_mtk_boost_pm_qos(hba, on); 655 - ufs_mtk_boost_crypt(hba, on); 611 + if (!ufshcd_is_clkscaling_supported(hba)) 612 + ufs_mtk_scale_perf(hba, on); 656 613 ufs_mtk_setup_ref_clk(hba, on); 657 614 phy_power_off(host->mphy); 658 615 } ··· 736 693 static u32 ufs_mtk_get_ufs_hci_version(struct ufs_hba *hba) 737 694 { 738 695 return hba->ufs_version; 696 + } 697 + 698 + /** 699 + * ufs_mtk_init_clocks - Init mtk driver private clocks 700 + * 701 + * @hba: per adapter instance 702 + */ 703 + static void ufs_mtk_init_clocks(struct ufs_hba *hba) 704 + { 705 + struct ufs_mtk_host *host = ufshcd_get_variant(hba); 706 + struct list_head *head = &hba->clk_list_head; 707 + struct ufs_mtk_clk *mclk = &host->mclk; 708 + struct ufs_clk_info *clki, *clki_tmp; 709 + 710 + /* 711 + * Find private clocks and store them in struct ufs_mtk_clk. 712 + * Remove "ufs_sel_min_src" and "ufs_sel_min_src" from list to avoid 713 + * being switched on/off in clock gating. 714 + */ 715 + list_for_each_entry_safe(clki, clki_tmp, head, list) { 716 + if (!strcmp(clki->name, "ufs_sel")) { 717 + host->mclk.ufs_sel_clki = clki; 718 + } else if (!strcmp(clki->name, "ufs_sel_max_src")) { 719 + host->mclk.ufs_sel_max_clki = clki; 720 + clk_disable_unprepare(clki->clk); 721 + list_del(&clki->list); 722 + } else if (!strcmp(clki->name, "ufs_sel_min_src")) { 723 + host->mclk.ufs_sel_min_clki = clki; 724 + clk_disable_unprepare(clki->clk); 725 + list_del(&clki->list); 726 + } 727 + } 728 + 729 + if (!mclk->ufs_sel_clki || !mclk->ufs_sel_max_clki || 730 + !mclk->ufs_sel_min_clki) { 731 + hba->caps &= ~UFSHCD_CAP_CLK_SCALING; 732 + dev_info(hba->dev, 733 + "%s: Clk-scaling not ready. Feature disabled.", 734 + __func__); 735 + } 739 736 } 740 737 741 738 #define MAX_VCC_NAME 30 ··· 898 815 899 816 /* Enable WriteBooster */ 900 817 hba->caps |= UFSHCD_CAP_WB_EN; 818 + 819 + /* Enable clk scaling*/ 820 + hba->caps |= UFSHCD_CAP_CLK_SCALING; 821 + 901 822 hba->quirks |= UFSHCI_QUIRK_SKIP_MANUAL_WB_FLUSH_CTRL; 902 823 hba->vps->wb_flush_threshold = UFS_WB_BUF_REMAIN_PERCENT(80); 903 824 904 825 if (host->caps & UFS_MTK_CAP_DISABLE_AH8) 905 826 hba->caps |= UFSHCD_CAP_HIBERN8_WITH_CLK_GATING; 827 + 828 + ufs_mtk_init_clocks(hba); 906 829 907 830 /* 908 831 * ufshcd_vops_init() is invoked after ··· 921 832 ufs_mtk_setup_clocks(hba, true, POST_CHANGE); 922 833 923 834 host->ip_ver = ufshcd_readl(hba, REG_UFS_MTK_IP_VER); 835 + 836 + /* Initialize pm-qos request */ 837 + cpu_latency_qos_add_request(&host->pm_qos_req, PM_QOS_DEFAULT_VALUE); 838 + host->pm_qos_init = true; 924 839 925 840 goto out; 926 841 ··· 1340 1247 1341 1248 static void ufs_mtk_dbg_register_dump(struct ufs_hba *hba) 1342 1249 { 1343 - ufshcd_dump_regs(hba, REG_UFS_REFCLK_CTRL, 0x4, "Ref-Clk Ctrl "); 1250 + /* Dump ufshci register 0x140 ~ 0x14C */ 1251 + ufshcd_dump_regs(hba, REG_UFS_XOUFS_CTRL, 0x10, 1252 + "XOUFS Ctrl (0x140): "); 1344 1253 1345 1254 ufshcd_dump_regs(hba, REG_UFS_EXTREG, 0x4, "Ext Reg "); 1346 1255 1256 + /* Dump ufshci register 0x2200 ~ 0x22AC */ 1347 1257 ufshcd_dump_regs(hba, REG_UFS_MPHYCTRL, 1348 1258 REG_UFS_REJECT_MON - REG_UFS_MPHYCTRL + 4, 1349 - "MPHY Ctrl "); 1259 + "MPHY Ctrl (0x2200): "); 1350 1260 1351 1261 /* Direct debugging information to REG_MTK_PROBE */ 1352 1262 ufs_mtk_dbg_sel(hba); ··· 1406 1310 enum ufs_event_type evt, void *data) 1407 1311 { 1408 1312 unsigned int val = *(u32 *)data; 1313 + unsigned long reg; 1314 + u8 bit; 1409 1315 1410 1316 trace_ufs_mtk_event(evt, val); 1317 + 1318 + /* Print details of UIC Errors */ 1319 + if (evt <= UFS_EVT_DME_ERR) { 1320 + dev_info(hba->dev, 1321 + "Host UIC Error Code (%s): %08x\n", 1322 + ufs_uic_err_str[evt], val); 1323 + reg = val; 1324 + } 1325 + 1326 + if (evt == UFS_EVT_PA_ERR) { 1327 + for_each_set_bit(bit, &reg, ARRAY_SIZE(ufs_uic_pa_err_str)) 1328 + dev_info(hba->dev, "%s\n", ufs_uic_pa_err_str[bit]); 1329 + } 1330 + 1331 + if (evt == UFS_EVT_DL_ERR) { 1332 + for_each_set_bit(bit, &reg, ARRAY_SIZE(ufs_uic_dl_err_str)) 1333 + dev_info(hba->dev, "%s\n", ufs_uic_dl_err_str[bit]); 1334 + } 1335 + } 1336 + 1337 + static void ufs_mtk_config_scaling_param(struct ufs_hba *hba, 1338 + struct devfreq_dev_profile *profile, 1339 + struct devfreq_simple_ondemand_data *data) 1340 + { 1341 + /* Customize min gear in clk scaling */ 1342 + hba->clk_scaling.min_gear = UFS_HS_G4; 1343 + 1344 + hba->vps->devfreq_profile.polling_ms = 200; 1345 + hba->vps->ondemand_data.upthreshold = 50; 1346 + hba->vps->ondemand_data.downdifferential = 20; 1347 + } 1348 + 1349 + /** 1350 + * ufs_mtk_clk_scale - Internal clk scaling operation 1351 + * 1352 + * MTK platform supports clk scaling by switching parent of ufs_sel(mux). 1353 + * The ufs_sel downstream to ufs_ck which feeds directly to UFS hardware. 1354 + * Max and min clocks rate of ufs_sel defined in dts should match rate of 1355 + * "ufs_sel_max_src" and "ufs_sel_min_src" respectively. 1356 + * This prevent changing rate of pll clock that is shared between modules. 1357 + * 1358 + * @hba: per adapter instance 1359 + * @scale_up: True for scaling up and false for scaling down 1360 + */ 1361 + static void ufs_mtk_clk_scale(struct ufs_hba *hba, bool scale_up) 1362 + { 1363 + struct ufs_mtk_host *host = ufshcd_get_variant(hba); 1364 + struct ufs_mtk_clk *mclk = &host->mclk; 1365 + struct ufs_clk_info *clki = mclk->ufs_sel_clki; 1366 + int ret = 0; 1367 + 1368 + ret = clk_prepare_enable(clki->clk); 1369 + if (ret) { 1370 + dev_info(hba->dev, 1371 + "clk_prepare_enable() fail, ret: %d\n", ret); 1372 + return; 1373 + } 1374 + 1375 + if (scale_up) { 1376 + ret = clk_set_parent(clki->clk, mclk->ufs_sel_max_clki->clk); 1377 + clki->curr_freq = clki->max_freq; 1378 + } else { 1379 + ret = clk_set_parent(clki->clk, mclk->ufs_sel_min_clki->clk); 1380 + clki->curr_freq = clki->min_freq; 1381 + } 1382 + 1383 + if (ret) { 1384 + dev_info(hba->dev, 1385 + "Failed to set ufs_sel_clki, ret: %d\n", ret); 1386 + } 1387 + 1388 + clk_disable_unprepare(clki->clk); 1389 + 1390 + trace_ufs_mtk_clk_scale(clki->name, scale_up, clk_get_rate(clki->clk)); 1391 + } 1392 + 1393 + static int ufs_mtk_clk_scale_notify(struct ufs_hba *hba, bool scale_up, 1394 + enum ufs_notify_change_status status) 1395 + { 1396 + if (!ufshcd_is_clkscaling_supported(hba)) 1397 + return 0; 1398 + 1399 + if (status == PRE_CHANGE) { 1400 + /* Switch parent before clk_set_rate() */ 1401 + ufs_mtk_clk_scale(hba, scale_up); 1402 + } else { 1403 + /* Request interrupt latency QoS accordingly */ 1404 + ufs_mtk_scale_perf(hba, scale_up); 1405 + } 1406 + 1407 + return 0; 1411 1408 } 1412 1409 1413 1410 /* ··· 1524 1335 .dbg_register_dump = ufs_mtk_dbg_register_dump, 1525 1336 .device_reset = ufs_mtk_device_reset, 1526 1337 .event_notify = ufs_mtk_event_notify, 1338 + .config_scaling_param = ufs_mtk_config_scaling_param, 1339 + .clk_scale_notify = ufs_mtk_clk_scale_notify, 1527 1340 }; 1528 1341 1529 1342 /**
+7
drivers/ufs/host/ufs-mediatek.h
··· 124 124 int vcore_volt; 125 125 }; 126 126 127 + struct ufs_mtk_clk { 128 + struct ufs_clk_info *ufs_sel_clki; /* Mux */ 129 + struct ufs_clk_info *ufs_sel_max_clki; /* Max src */ 130 + struct ufs_clk_info *ufs_sel_min_clki; /* Min src */ 131 + }; 132 + 127 133 struct ufs_mtk_hw_ver { 128 134 u8 step; 129 135 u8 minor; ··· 145 139 struct reset_control *crypto_reset; 146 140 struct ufs_hba *hba; 147 141 struct ufs_mtk_crypt_cfg *crypt; 142 + struct ufs_mtk_clk mclk; 148 143 struct ufs_mtk_hw_ver hw_ver; 149 144 enum ufs_mtk_host_caps caps; 150 145 bool mphy_powered_on;
+1 -1
drivers/ufs/host/ufs-qcom.c
··· 846 846 struct ufs_qcom_host *host = ufshcd_get_variant(hba); 847 847 848 848 hba->caps |= UFSHCD_CAP_CLK_GATING | UFSHCD_CAP_HIBERN8_WITH_CLK_GATING; 849 - hba->caps |= UFSHCD_CAP_CLK_SCALING; 849 + hba->caps |= UFSHCD_CAP_CLK_SCALING | UFSHCD_CAP_WB_WITH_CLK_SCALING; 850 850 hba->caps |= UFSHCD_CAP_AUTO_BKOPS_SUSPEND; 851 851 hba->caps |= UFSHCD_CAP_WB_EN; 852 852 hba->caps |= UFSHCD_CAP_CRYPTO;
+1 -1
drivers/usb/storage/uas.c
··· 283 283 set_host_byte(cmnd, DID_OK); 284 284 break; 285 285 case RC_TMF_NOT_SUPPORTED: 286 - set_host_byte(cmnd, DID_TARGET_FAILURE); 286 + set_host_byte(cmnd, DID_BAD_TARGET); 287 287 break; 288 288 default: 289 289 uas_log_cmd_state(cmnd, "response iu", response_code);
-12
drivers/xen/xen-scsiback.c
··· 333 333 case DID_TRANSPORT_FAILFAST: 334 334 host_status = XEN_VSCSIIF_RSLT_HOST_TRANSPORT_FAILFAST; 335 335 break; 336 - case DID_TARGET_FAILURE: 337 - host_status = XEN_VSCSIIF_RSLT_HOST_TARGET_FAILURE; 338 - break; 339 - case DID_NEXUS_FAILURE: 340 - host_status = XEN_VSCSIIF_RSLT_HOST_NEXUS_FAILURE; 341 - break; 342 - case DID_ALLOC_FAILURE: 343 - host_status = XEN_VSCSIIF_RSLT_HOST_ALLOC_FAILURE; 344 - break; 345 - case DID_MEDIUM_ERROR: 346 - host_status = XEN_VSCSIIF_RSLT_HOST_MEDIUM_ERROR; 347 - break; 348 336 case DID_TRANSPORT_MARGINAL: 349 337 host_status = XEN_VSCSIIF_RSLT_HOST_TRANSPORT_MARGINAL; 350 338 break;
+34 -2
include/linux/trace.h
··· 2 2 #ifndef _LINUX_TRACE_H 3 3 #define _LINUX_TRACE_H 4 4 5 - #ifdef CONFIG_TRACING 6 - 7 5 #define TRACE_EXPORT_FUNCTION BIT(0) 8 6 #define TRACE_EXPORT_EVENT BIT(1) 9 7 #define TRACE_EXPORT_MARKER BIT(2) ··· 26 28 int flags; 27 29 }; 28 30 31 + #ifdef CONFIG_TRACING 32 + 29 33 int register_ftrace_export(struct trace_export *export); 30 34 int unregister_ftrace_export(struct trace_export *export); 31 35 ··· 48 48 void osnoise_trace_irq_entry(int id); 49 49 void osnoise_trace_irq_exit(int id, const char *desc); 50 50 51 + #else /* CONFIG_TRACING */ 52 + static inline int register_ftrace_export(struct trace_export *export) 53 + { 54 + return -EINVAL; 55 + } 56 + static inline int unregister_ftrace_export(struct trace_export *export) 57 + { 58 + return 0; 59 + } 60 + static inline void trace_printk_init_buffers(void) 61 + { 62 + } 63 + static inline int trace_array_printk(struct trace_array *tr, unsigned long ip, 64 + const char *fmt, ...) 65 + { 66 + return 0; 67 + } 68 + static inline int trace_array_init_printk(struct trace_array *tr) 69 + { 70 + return -EINVAL; 71 + } 72 + static inline void trace_array_put(struct trace_array *tr) 73 + { 74 + } 75 + static inline struct trace_array *trace_array_get_by_name(const char *name) 76 + { 77 + return NULL; 78 + } 79 + static inline int trace_array_destroy(struct trace_array *tr) 80 + { 81 + return 0; 82 + } 51 83 #endif /* CONFIG_TRACING */ 52 84 53 85 #endif /* _LINUX_TRACE_H */
+1 -1
include/scsi/scsi_cmnd.h
··· 201 201 for_each_sg(scsi_sglist(cmd), sg, nseg, __i) 202 202 203 203 static inline int scsi_sg_copy_from_buffer(struct scsi_cmnd *cmd, 204 - void *buf, int buflen) 204 + const void *buf, int buflen) 205 205 { 206 206 return sg_copy_from_buffer(scsi_sglist(cmd), scsi_sg_count(cmd), 207 207 buf, buflen);
+1
include/scsi/scsi_device.h
··· 231 231 atomic_t iorequest_cnt; 232 232 atomic_t iodone_cnt; 233 233 atomic_t ioerr_cnt; 234 + atomic_t iotmo_cnt; 234 235 235 236 struct device sdev_gendev, 236 237 sdev_dev;
+6 -6
include/scsi/scsi_status.h
··· 62 62 * recover the link. Transport class will 63 63 * retry or fail IO */ 64 64 DID_TRANSPORT_FAILFAST = 0x0f, /* Transport class fastfailed the io */ 65 - DID_TARGET_FAILURE = 0x10, /* Permanent target failure, do not retry on 66 - * other paths */ 67 - DID_NEXUS_FAILURE = 0x11, /* Permanent nexus failure, retry on other 68 - * paths might yield different results */ 69 - DID_ALLOC_FAILURE = 0x12, /* Space allocation on the device failed */ 70 - DID_MEDIUM_ERROR = 0x13, /* Medium error */ 65 + /* 66 + * We used to have DID_TARGET_FAILURE, DID_NEXUS_FAILURE, 67 + * DID_ALLOC_FAILURE and DID_MEDIUM_ERROR at 0x10 - 0x13. For compat 68 + * with userspace apps that parse the host byte for SG IO, we leave 69 + * that block of codes unused and start at 0x14 below. 70 + */ 71 71 DID_TRANSPORT_MARGINAL = 0x14, /* Transport marginal errors */ 72 72 }; 73 73
+21 -25
include/ufs/ufshcd.h
··· 160 160 * @task_tag: Task tag of the command 161 161 * @lun: LUN of the command 162 162 * @intr_cmd: Interrupt command (doesn't participate in interrupt aggregation) 163 - * @issue_time_stamp: time stamp for debug purposes 164 - * @compl_time_stamp: time stamp for statistics 163 + * @issue_time_stamp: time stamp for debug purposes (CLOCK_MONOTONIC) 164 + * @issue_time_stamp_local_clock: time stamp for debug purposes (local_clock) 165 + * @compl_time_stamp: time stamp for statistics (CLOCK_MONOTONIC) 166 + * @compl_time_stamp_local_clock: time stamp for debug purposes (local_clock) 165 167 * @crypto_key_slot: the key slot to use for inline crypto (-1 if none) 166 168 * @data_unit_num: the data unit number for the first block for inline crypto 167 169 * @req_abort_skip: skip request abort task flag ··· 187 185 u8 lun; /* UPIU LUN id field is only 8-bit wide */ 188 186 bool intr_cmd; 189 187 ktime_t issue_time_stamp; 188 + u64 issue_time_stamp_local_clock; 190 189 ktime_t compl_time_stamp; 190 + u64 compl_time_stamp_local_clock; 191 191 #ifdef CONFIG_SCSI_UFS_CRYPTO 192 192 int crypto_key_slot; 193 193 u64 data_unit_num; ··· 434 430 struct ufs_event_hist { 435 431 int pos; 436 432 u32 val[UFS_EVENT_HIST_LENGTH]; 437 - ktime_t tstamp[UFS_EVENT_HIST_LENGTH]; 433 + u64 tstamp[UFS_EVENT_HIST_LENGTH]; 438 434 unsigned long long cnt; 439 435 }; 440 436 ··· 450 446 */ 451 447 struct ufs_stats { 452 448 u32 last_intr_status; 453 - ktime_t last_intr_ts; 449 + u64 last_intr_ts; 454 450 455 451 u32 hibern8_exit_cnt; 456 - ktime_t last_hibern8_exit_tstamp; 452 + u64 last_hibern8_exit_tstamp; 457 453 struct ufs_event_hist event[UFS_EVT_CNT]; 458 454 }; 459 455 ··· 664 660 * notification if it is supported by the UFS device. 665 661 */ 666 662 UFSHCD_CAP_TEMP_NOTIF = 1 << 11, 663 + 664 + /* 665 + * Enable WriteBooster when scaling up the clock and disable 666 + * WriteBooster when scaling the clock down. 667 + */ 668 + UFSHCD_CAP_WB_WITH_CLK_SCALING = 1 << 12, 667 669 }; 668 670 669 671 struct ufs_hba_variant_params { ··· 1027 1017 return hba->caps & UFSHCD_CAP_WB_EN; 1028 1018 } 1029 1019 1020 + static inline bool ufshcd_enable_wb_if_scaling_up(struct ufs_hba *hba) 1021 + { 1022 + return hba->caps & UFSHCD_CAP_WB_WITH_CLK_SCALING; 1023 + } 1024 + 1030 1025 #define ufshcd_writel(hba, val, reg) \ 1031 1026 writel((val), (hba)->mmio_base + (reg)) 1032 1027 #define ufshcd_readl(hba, reg) \ ··· 1175 1160 return ufshcd_dme_set(hba, UIC_ARG_MIB(PA_LOCAL_TX_LCC_ENABLE), 0); 1176 1161 } 1177 1162 1178 - /* Expose Query-Request API */ 1179 - int ufshcd_query_descriptor_retry(struct ufs_hba *hba, 1180 - enum query_opcode opcode, 1181 - enum desc_idn idn, u8 index, 1182 - u8 selector, 1183 - u8 *desc_buf, int *buf_len); 1184 - int ufshcd_read_desc_param(struct ufs_hba *hba, 1185 - enum desc_idn desc_id, 1186 - int desc_index, 1187 - u8 param_offset, 1188 - u8 *param_read_buf, 1189 - u8 param_size); 1190 - int ufshcd_query_attr_retry(struct ufs_hba *hba, enum query_opcode opcode, 1191 - enum attr_idn idn, u8 index, u8 selector, 1192 - u32 *attr_val); 1193 - int ufshcd_query_attr(struct ufs_hba *hba, enum query_opcode opcode, 1194 - enum attr_idn idn, u8 index, u8 selector, u32 *attr_val); 1195 - int ufshcd_query_flag(struct ufs_hba *hba, enum query_opcode opcode, 1196 - enum flag_idn idn, u8 index, bool *flag_res); 1197 - 1198 1163 void ufshcd_auto_hibern8_enable(struct ufs_hba *hba); 1199 1164 void ufshcd_auto_hibern8_update(struct ufs_hba *hba, u32 ahit); 1200 1165 void ufshcd_fixup_dev_quirks(struct ufs_hba *hba, ··· 1206 1211 enum query_opcode desc_op); 1207 1212 1208 1213 int ufshcd_wb_toggle(struct ufs_hba *hba, bool enable); 1214 + int ufshcd_wb_toggle_buf_flush(struct ufs_hba *hba, bool enable); 1209 1215 int ufshcd_suspend_prepare(struct device *dev); 1210 1216 int __ufshcd_suspend_prepare(struct device *dev, bool rpm_ok_for_spm); 1211 1217 void ufshcd_resume_complete(struct device *dev);