Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3f8d6f2a authored by James Bottomley's avatar James Bottomley
Browse files

ses: fix discovery of SATA devices in SAS enclosures



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: default avatarJames Bottomley <James.Bottomley@HansenPartnership.com>
parent bcf508c1
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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
+4 −18
Original line number Diff line number Diff line
@@ -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;