Closed rbicelli closed 4 years ago
Hi,
We have several MD1220 enclosures. lsscsi and sas2ircu both show all the needed information. Check the attached screenshots.
Thanks, didn't think about sas2ircu. My problems were locating disks.
Seems that while the device type is the expected 0x0d, the EncServ bit in the inquiry data isn't set so the scsi_device_enclosure check doesn't think it's supported (as expected, the enclosure is the non-standards compliant one here).
[nix-shell:~/sdled]# sg_inq /dev/sg5
standard INQUIRY:
PQual=0 Device_type=13 RMB=0 LU_CONG=0 version=0x05 [SPC-3]
[AERC=0] [TrmTsk=0] NormACA=0 HiSUP=1 Resp_data_format=2
SCCS=0 ACC=0 TPGS=0 3PC=0 Protect=0 [BQue=1]
EncServ=0 MultiP=1 (VS=0) [MChngr=0] [ACKREQQ=0] Addr16=0
[RelAdr=0] WBus16=0 Sync=0 [Linked=0] [TranDis=0] CmdQue=0
[SPI: Clocking=0x0 QAS=0 IUS=0]
length=66 (0x42) Peripheral device type: enclosure services device
Vendor identification: DELL
Product identification: MD1220
Product revision level: 1.06
I'm not sure what issues might be encountered long term, but using some hacky string comparisons we can pretend it supports SES.
diff --git a/drivers/scsi/ses.c b/drivers/scsi/ses.c
index c2afba2a5..cfb7b6a39 100644
--- a/drivers/scsi/ses.c
+++ b/drivers/scsi/ses.c
@@ -620,6 +620,26 @@ static void ses_match_to_enclosure(struct enclosure_device *edev,
}
}
+static int ses_device_enclosure(struct scsi_device *sdev)
+{
+ int sde = scsi_device_enclosure(sdev);
+ if (sde)
+ return sde;
+
+ if (sdev->type != TYPE_ENCLOSURE)
+ return 0;
+
+ if (strncmp(sdev->vendor, "DELL ", 5) == 0) {
+ if ((strncmp(sdev->model, "MD1200 ", 7) == 0)
+ || (strncmp(sdev->model, "MD1220 ", 7) == 0)) {
+ sdev_printk(KERN_NOTICE, sdev, "Enclosure supports SES, ignoring EncServ=0 as claimed by the device\n");
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
static int ses_intf_add(struct device *cdev,
struct class_interface *intf)
{
@@ -634,7 +654,7 @@ static int ses_intf_add(struct device *cdev,
struct enclosure_device *edev;
struct ses_component *scomp = NULL;
- if (!scsi_device_enclosure(sdev)) {
+ if (!ses_device_enclosure(sdev)) {
/* not an enclosure, but might be in one */
struct enclosure_device *prev = NULL;
@@ -753,7 +773,7 @@ static int ses_intf_add(struct device *cdev,
/* see if there are any devices matching before
* we found the enclosure */
shost_for_each_device(tmp_sdev, sdev->host) {
- if (tmp_sdev->lun != 0 || scsi_device_enclosure(tmp_sdev))
+ if (tmp_sdev->lun != 0 || ses_device_enclosure(tmp_sdev))
continue;
ses_match_to_enclosure(edev, tmp_sdev, 0);
}
@@ -824,7 +844,7 @@ static void ses_intf_remove(struct device *cdev,
{
struct scsi_device *sdev = to_scsi_device(cdev->parent);
- if (!scsi_device_enclosure(sdev))
+ if (!ses_device_enclosure(sdev))
ses_intf_remove_component(sdev);
else
ses_intf_remove_enclosure(sdev);
--
2.31.1
With that patch in place, tools like sdled/encled work. Although with multipath, the dev name isn't correct for the second connected controller, but the LED status is correct. (edit: looks like device detachment updates correctly, new attachments aren't picked up. Can't tell if it's my setup/kernel/etc, or the non-standard SES implementation being forced into service.)
[nix-shell:~/sdled]# python ./encled
ENCLOSURE/SLOT DEV FAULT_LED LOCATION_LED
----------------------------------------------------
0:0:2:0/Slot 5 ---- fault_off locate_off
0:0:2:0/Slot 6 sdc FAULT_ON locate_off
0:0:2:0/Slot 13 ---- fault_off locate_off
0:0:2:0/Slot 12 sdd fault_off LOCATE_ON
[--snip--]
4:0:2:0/Slot 5 ---- fault_off locate_off
4:0:2:0/Slot 6 ---- FAULT_ON locate_off
4:0:2:0/Slot 13 ---- fault_off locate_off
4:0:2:0/Slot 12 ---- fault_off LOCATE_ON
[--snip--]
First of all, thanks for this beautiful and elegant solution. Using it for my XenServer pool and works great! The only downside is that with Dell MD1220 there's no way to identify drives because /sys/class/enclosure isn't populated. Any clue?