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: James Bottomley <James.Bottomley@HansenPartnership.com>
This commit is contained in:
Родитель
bcf508c133
Коммит
3f8d6f2a07
|
@ -194,6 +194,7 @@ config CHR_DEV_SCH
|
||||||
config SCSI_ENCLOSURE
|
config SCSI_ENCLOSURE
|
||||||
tristate "SCSI Enclosure Support"
|
tristate "SCSI Enclosure Support"
|
||||||
depends on SCSI && ENCLOSURE_SERVICES
|
depends on SCSI && ENCLOSURE_SERVICES
|
||||||
|
depends on m || SCSI_SAS_ATTRS != m
|
||||||
help
|
help
|
||||||
Enclosures are devices sitting on or in SCSI backplanes that
|
Enclosures are devices sitting on or in SCSI backplanes that
|
||||||
manage devices. If you have a disk cage, the chances are that
|
manage devices. If you have a disk cage, the chances are that
|
||||||
|
|
|
@ -34,6 +34,8 @@
|
||||||
#include <scsi/scsi_driver.h>
|
#include <scsi/scsi_driver.h>
|
||||||
#include <scsi/scsi_host.h>
|
#include <scsi/scsi_host.h>
|
||||||
|
|
||||||
|
#include <scsi/scsi_transport_sas.h>
|
||||||
|
|
||||||
struct ses_device {
|
struct ses_device {
|
||||||
unsigned char *page1;
|
unsigned char *page1;
|
||||||
unsigned char *page1_types;
|
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,
|
static void ses_match_to_enclosure(struct enclosure_device *edev,
|
||||||
struct scsi_device *sdev)
|
struct scsi_device *sdev)
|
||||||
{
|
{
|
||||||
unsigned char *desc;
|
|
||||||
struct efd efd = {
|
struct efd efd = {
|
||||||
.addr = 0,
|
.addr = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
ses_enclosure_data_process(edev, to_scsi_device(edev->edev.parent), 0);
|
ses_enclosure_data_process(edev, to_scsi_device(edev->edev.parent), 0);
|
||||||
|
|
||||||
if (!sdev->vpd_pg83_len)
|
if (is_sas_attached(sdev))
|
||||||
return;
|
efd.addr = sas_get_address(sdev);
|
||||||
|
|
||||||
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]);
|
|
||||||
|
|
||||||
desc += len + 4;
|
|
||||||
}
|
|
||||||
if (efd.addr) {
|
if (efd.addr) {
|
||||||
efd.dev = &sdev->sdev_gendev;
|
efd.dev = &sdev->sdev_gendev;
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче