Skip to content

Commit

Permalink
ses: fix discovery of SATA devices in SAS enclosures
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
James Bottomley authored and James Bottomley committed Dec 19, 2015
1 parent bcf508c commit 3f8d6f2
Show file tree
Hide file tree
Showing 2 changed files with 5 additions and 18 deletions.
1 change: 1 addition & 0 deletions drivers/scsi/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
22 changes: 4 additions & 18 deletions drivers/scsi/ses.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;

Expand Down

0 comments on commit 3f8d6f2

Please sign in to comment.