ses: fix discovery of SATA devices in SAS enclosures
authorJames Bottomley <James.Bottomley@HansenPartnership.com>
Wed, 9 Dec 2015 20:56:07 +0000 (12:56 -0800)
committerJames Bottomley <James.Bottomley@HansenPartnership.com>
Sat, 19 Dec 2015 03:29:50 +0000 (19:29 -0800)
The current discovery routines use the VPD 0x83 inquiry page to find
the device SAS address and match it to the end point in the enclosure.
This doesn't work for SATA devices because expanders (or hosts) simply
make up an endpoint address for STP and thus the address returned by
the VPD page never matches.  Instead of doing this, for SAS attached
devices, match by the direct endpoint address instead.

Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
drivers/scsi/Kconfig
drivers/scsi/ses.c

index 64eed87d34a87840d5da60d267383589541e1d73..90cd7cd6d130b1d55cd8a068de0165b1488a4726 100644 (file)
@@ -194,6 +194,7 @@ config CHR_DEV_SCH
 config SCSI_ENCLOSURE
        tristate "SCSI Enclosure Support"
        depends on SCSI && ENCLOSURE_SERVICES
+       depends on m || SCSI_SAS_ATTRS != m
        help
          Enclosures are devices sitting on or in SCSI backplanes that
          manage devices.  If you have a disk cage, the chances are that
index 044d06410d4c86c0dc88071bb0de668dd91bb0e2..53ef1cb6418e33f0ce9542468359d2ad0297444d 100644 (file)
@@ -34,6 +34,8 @@
 #include <scsi/scsi_driver.h>
 #include <scsi/scsi_host.h>
 
+#include <scsi/scsi_transport_sas.h>
+
 struct ses_device {
        unsigned char *page1;
        unsigned char *page1_types;
@@ -579,31 +581,15 @@ static void ses_enclosure_data_process(struct enclosure_device *edev,
 static void ses_match_to_enclosure(struct enclosure_device *edev,
                                   struct scsi_device *sdev)
 {
-       unsigned char *desc;
        struct efd efd = {
                .addr = 0,
        };
 
        ses_enclosure_data_process(edev, to_scsi_device(edev->edev.parent), 0);
 
-       if (!sdev->vpd_pg83_len)
-               return;
-
-       desc = sdev->vpd_pg83 + 4;
-       while (desc < sdev->vpd_pg83 + sdev->vpd_pg83_len) {
-               enum scsi_protocol proto = desc[0] >> 4;
-               u8 code_set = desc[0] & 0x0f;
-               u8 piv = desc[1] & 0x80;
-               u8 assoc = (desc[1] & 0x30) >> 4;
-               u8 type = desc[1] & 0x0f;
-               u8 len = desc[3];
-
-               if (piv && code_set == 1 && assoc == 1
-                   && proto == SCSI_PROTOCOL_SAS && type == 3 && len == 8)
-                       efd.addr = get_unaligned_be64(&desc[4]);
+       if (is_sas_attached(sdev))
+               efd.addr = sas_get_address(sdev);
 
-               desc += len + 4;
-       }
        if (efd.addr) {
                efd.dev = &sdev->sdev_gendev;