aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/smartpqi
diff options
context:
space:
mode:
authorDave Carroll <david.carroll@microsemi.com>2018-12-07 17:28:47 -0500
committerMartin K. Petersen <martin.petersen@oracle.com>2018-12-19 22:23:34 -0500
commitcd128244162c8afbf50e93b88daa02b05faa4c0a (patch)
treeefc21b4b7bb34aaa1184f7ff1e539605ea670fd6 /drivers/scsi/smartpqi
parent02133b68d51d09bd91b0d2c1fa5318e2f23e4559 (diff)
scsi: smartpqi: add sysfs attributes
- add sysfs device attributes, unique_id, lunid and path_info. Reviewed-by: Scott Teel <scott.teel@microsemi.com> Reviewed-by: Kevin Barnett <kevin.barnett@microsemi.com> Signed-off-by: Dave Carroll <david.carroll@microsemi.com> Signed-off-by: Don Brace <don.brace@microsemi.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/smartpqi')
-rw-r--r--drivers/scsi/smartpqi/smartpqi.h3
-rw-r--r--drivers/scsi/smartpqi/smartpqi_init.c232
2 files changed, 235 insertions, 0 deletions
diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h
index fcc4b937de71..a39c324dedab 100644
--- a/drivers/scsi/smartpqi/smartpqi.h
+++ b/drivers/scsi/smartpqi/smartpqi.h
@@ -852,6 +852,7 @@ struct pqi_scsi_dev {
852 u8 scsi3addr[8]; 852 u8 scsi3addr[8];
853 __be64 wwid; 853 __be64 wwid;
854 u8 volume_id[16]; 854 u8 volume_id[16];
855 u8 unique_id[16];
855 u8 is_physical_device : 1; 856 u8 is_physical_device : 1;
856 u8 is_external_raid_device : 1; 857 u8 is_external_raid_device : 1;
857 u8 target_lun_valid : 1; 858 u8 target_lun_valid : 1;
@@ -898,6 +899,8 @@ struct pqi_scsi_dev {
898#define CISS_VPD_LV_DEVICE_GEOMETRY 0xc1 /* vendor-specific page */ 899#define CISS_VPD_LV_DEVICE_GEOMETRY 0xc1 /* vendor-specific page */
899#define CISS_VPD_LV_BYPASS_STATUS 0xc2 /* vendor-specific page */ 900#define CISS_VPD_LV_BYPASS_STATUS 0xc2 /* vendor-specific page */
900#define CISS_VPD_LV_STATUS 0xc3 /* vendor-specific page */ 901#define CISS_VPD_LV_STATUS 0xc3 /* vendor-specific page */
902#define SCSI_VPD_HEADER_SZ 4
903#define SCSI_VPD_DEVICE_ID_IDX 8 /* Index of page id in page */
901 904
902#define VPD_PAGE (1 << 8) 905#define VPD_PAGE (1 << 8)
903 906
diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
index 2a90d515b972..f6c83cb155b0 100644
--- a/drivers/scsi/smartpqi/smartpqi_init.c
+++ b/drivers/scsi/smartpqi/smartpqi_init.c
@@ -573,6 +573,79 @@ static inline int pqi_scsi_inquiry(struct pqi_ctrl_info *ctrl_info,
573 buffer, buffer_length, vpd_page, NULL, NO_TIMEOUT); 573 buffer, buffer_length, vpd_page, NULL, NO_TIMEOUT);
574} 574}
575 575
576static bool pqi_vpd_page_supported(struct pqi_ctrl_info *ctrl_info,
577 u8 *scsi3addr, u16 vpd_page)
578{
579 int rc;
580 int i;
581 int pages;
582 unsigned char *buf, bufsize;
583
584 buf = kzalloc(256, GFP_KERNEL);
585 if (!buf)
586 return false;
587
588 /* Get the size of the page list first */
589 rc = pqi_scsi_inquiry(ctrl_info, scsi3addr,
590 VPD_PAGE | SCSI_VPD_SUPPORTED_PAGES,
591 buf, SCSI_VPD_HEADER_SZ);
592 if (rc != 0)
593 goto exit_unsupported;
594
595 pages = buf[3];
596 if ((pages + SCSI_VPD_HEADER_SZ) <= 255)
597 bufsize = pages + SCSI_VPD_HEADER_SZ;
598 else
599 bufsize = 255;
600
601 /* Get the whole VPD page list */
602 rc = pqi_scsi_inquiry(ctrl_info, scsi3addr,
603 VPD_PAGE | SCSI_VPD_SUPPORTED_PAGES,
604 buf, bufsize);
605 if (rc != 0)
606 goto exit_unsupported;
607
608 pages = buf[3];
609 for (i = 1; i <= pages; i++)
610 if (buf[3 + i] == vpd_page)
611 goto exit_supported;
612
613exit_unsupported:
614 kfree(buf);
615 return false;
616
617exit_supported:
618 kfree(buf);
619 return true;
620}
621
622static int pqi_get_device_id(struct pqi_ctrl_info *ctrl_info,
623 u8 *scsi3addr, u8 *device_id, int buflen)
624{
625 int rc;
626 unsigned char *buf;
627
628 if (!pqi_vpd_page_supported(ctrl_info, scsi3addr, SCSI_VPD_DEVICE_ID))
629 return 1; /* function not supported */
630
631 buf = kzalloc(64, GFP_KERNEL);
632 if (!buf)
633 return -ENOMEM;
634
635 rc = pqi_scsi_inquiry(ctrl_info, scsi3addr,
636 VPD_PAGE | SCSI_VPD_DEVICE_ID,
637 buf, 64);
638 if (rc == 0) {
639 if (buflen > 16)
640 buflen = 16;
641 memcpy(device_id, &buf[SCSI_VPD_DEVICE_ID_IDX], buflen);
642 }
643
644 kfree(buf);
645
646 return rc;
647}
648
576static int pqi_identify_physical_device(struct pqi_ctrl_info *ctrl_info, 649static int pqi_identify_physical_device(struct pqi_ctrl_info *ctrl_info,
577 struct pqi_scsi_dev *device, 650 struct pqi_scsi_dev *device,
578 struct bmic_identify_physical_device *buffer, 651 struct bmic_identify_physical_device *buffer,
@@ -1244,6 +1317,14 @@ static int pqi_get_device_info(struct pqi_ctrl_info *ctrl_info,
1244 } 1317 }
1245 } 1318 }
1246 1319
1320 if (pqi_get_device_id(ctrl_info, device->scsi3addr,
1321 device->unique_id, sizeof(device->unique_id)) < 0)
1322 dev_warn(&ctrl_info->pci_dev->dev,
1323 "Can't get device id for scsi %d:%d:%d:%d\n",
1324 ctrl_info->scsi_host->host_no,
1325 device->bus, device->target,
1326 device->lun);
1327
1247out: 1328out:
1248 kfree(buffer); 1329 kfree(buffer);
1249 1330
@@ -1775,6 +1856,12 @@ static inline bool pqi_skip_device(u8 *scsi3addr)
1775 return false; 1856 return false;
1776} 1857}
1777 1858
1859static inline bool pqi_expose_device(struct pqi_scsi_dev *device)
1860{
1861 return !device->is_physical_device ||
1862 !pqi_skip_device(device->scsi3addr);
1863}
1864
1778static int pqi_update_scsi_devices(struct pqi_ctrl_info *ctrl_info) 1865static int pqi_update_scsi_devices(struct pqi_ctrl_info *ctrl_info)
1779{ 1866{
1780 int i; 1867 int i;
@@ -5722,6 +5809,145 @@ static struct device_attribute *pqi_shost_attrs[] = {
5722 NULL 5809 NULL
5723}; 5810};
5724 5811
5812static ssize_t pqi_unique_id_show(struct device *dev,
5813 struct device_attribute *attr, char *buffer)
5814{
5815 struct pqi_ctrl_info *ctrl_info;
5816 struct scsi_device *sdev;
5817 struct pqi_scsi_dev *device;
5818 unsigned long flags;
5819 unsigned char uid[16];
5820
5821 sdev = to_scsi_device(dev);
5822 ctrl_info = shost_to_hba(sdev->host);
5823
5824 spin_lock_irqsave(&ctrl_info->scsi_device_list_lock, flags);
5825
5826 device = sdev->hostdata;
5827 if (!device) {
5828 spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock,
5829 flags);
5830 return -ENODEV;
5831 }
5832 memcpy(uid, device->unique_id, sizeof(uid));
5833
5834 spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags);
5835
5836 return snprintf(buffer, PAGE_SIZE, "%16phN", uid);
5837}
5838
5839static ssize_t pqi_lunid_show(struct device *dev,
5840 struct device_attribute *attr, char *buffer)
5841{
5842 struct pqi_ctrl_info *ctrl_info;
5843 struct scsi_device *sdev;
5844 struct pqi_scsi_dev *device;
5845 unsigned long flags;
5846 u8 lunid[8];
5847
5848 sdev = to_scsi_device(dev);
5849 ctrl_info = shost_to_hba(sdev->host);
5850
5851 spin_lock_irqsave(&ctrl_info->scsi_device_list_lock, flags);
5852
5853 device = sdev->hostdata;
5854 if (!device) {
5855 spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock,
5856 flags);
5857 return -ENODEV;
5858 }
5859 memcpy(lunid, device->scsi3addr, sizeof(lunid));
5860
5861 spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags);
5862
5863 return snprintf(buffer, PAGE_SIZE, "0x%8phN\n", lunid);
5864}
5865
5866#define MAX_PATHS 8
5867static ssize_t pqi_path_info_show(struct device *dev,
5868 struct device_attribute *attr, char *buf)
5869{
5870 struct pqi_ctrl_info *ctrl_info;
5871 struct scsi_device *sdev;
5872 struct pqi_scsi_dev *device;
5873 unsigned long flags;
5874 int i;
5875 int output_len = 0;
5876 u8 box;
5877 u8 bay;
5878 u8 path_map_index = 0;
5879 char *active;
5880 unsigned char phys_connector[2];
5881
5882 sdev = to_scsi_device(dev);
5883 ctrl_info = shost_to_hba(sdev->host);
5884
5885 spin_lock_irqsave(&ctrl_info->scsi_device_list_lock, flags);
5886
5887 device = sdev->hostdata;
5888 if (!device) {
5889 spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock,
5890 flags);
5891 return -ENODEV;
5892 }
5893
5894 bay = device->bay;
5895 for (i = 0; i < MAX_PATHS; i++) {
5896 path_map_index = 1<<i;
5897 if (i == device->active_path_index)
5898 active = "Active";
5899 else if (device->path_map & path_map_index)
5900 active = "Inactive";
5901 else
5902 continue;
5903
5904 output_len += scnprintf(buf + output_len,
5905 PAGE_SIZE - output_len,
5906 "[%d:%d:%d:%d] %20.20s ",
5907 ctrl_info->scsi_host->host_no,
5908 device->bus, device->target,
5909 device->lun,
5910 scsi_device_type(device->devtype));
5911
5912 if (device->devtype == TYPE_RAID ||
5913 pqi_is_logical_device(device))
5914 goto end_buffer;
5915
5916 memcpy(&phys_connector, &device->phys_connector[i],
5917 sizeof(phys_connector));
5918 if (phys_connector[0] < '0')
5919 phys_connector[0] = '0';
5920 if (phys_connector[1] < '0')
5921 phys_connector[1] = '0';
5922
5923 output_len += scnprintf(buf + output_len,
5924 PAGE_SIZE - output_len,
5925 "PORT: %.2s ", phys_connector);
5926
5927 box = device->box[i];
5928 if (box != 0 && box != 0xFF)
5929 output_len += scnprintf(buf + output_len,
5930 PAGE_SIZE - output_len,
5931 "BOX: %hhu ", box);
5932
5933 if ((device->devtype == TYPE_DISK ||
5934 device->devtype == TYPE_ZBC) &&
5935 pqi_expose_device(device))
5936 output_len += scnprintf(buf + output_len,
5937 PAGE_SIZE - output_len,
5938 "BAY: %hhu ", bay);
5939
5940end_buffer:
5941 output_len += scnprintf(buf + output_len,
5942 PAGE_SIZE - output_len,
5943 "%s\n", active);
5944 }
5945
5946 spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags);
5947 return output_len;
5948}
5949
5950
5725static ssize_t pqi_sas_address_show(struct device *dev, 5951static ssize_t pqi_sas_address_show(struct device *dev,
5726 struct device_attribute *attr, char *buffer) 5952 struct device_attribute *attr, char *buffer)
5727{ 5953{
@@ -5798,12 +6024,18 @@ static ssize_t pqi_raid_level_show(struct device *dev,
5798 return snprintf(buffer, PAGE_SIZE, "%s\n", raid_level); 6024 return snprintf(buffer, PAGE_SIZE, "%s\n", raid_level);
5799} 6025}
5800 6026
6027static DEVICE_ATTR(lunid, 0444, pqi_lunid_show, NULL);
6028static DEVICE_ATTR(unique_id, 0444, pqi_unique_id_show, NULL);
6029static DEVICE_ATTR(path_info, 0444, pqi_path_info_show, NULL);
5801static DEVICE_ATTR(sas_address, 0444, pqi_sas_address_show, NULL); 6030static DEVICE_ATTR(sas_address, 0444, pqi_sas_address_show, NULL);
5802static DEVICE_ATTR(ssd_smart_path_enabled, 0444, 6031static DEVICE_ATTR(ssd_smart_path_enabled, 0444,
5803 pqi_ssd_smart_path_enabled_show, NULL); 6032 pqi_ssd_smart_path_enabled_show, NULL);
5804static DEVICE_ATTR(raid_level, 0444, pqi_raid_level_show, NULL); 6033static DEVICE_ATTR(raid_level, 0444, pqi_raid_level_show, NULL);
5805 6034
5806static struct device_attribute *pqi_sdev_attrs[] = { 6035static struct device_attribute *pqi_sdev_attrs[] = {
6036 &dev_attr_lunid,
6037 &dev_attr_unique_id,
6038 &dev_attr_path_info,
5807 &dev_attr_sas_address, 6039 &dev_attr_sas_address,
5808 &dev_attr_ssd_smart_path_enabled, 6040 &dev_attr_ssd_smart_path_enabled,
5809 &dev_attr_raid_level, 6041 &dev_attr_raid_level,