Linux – Match PCI address of SATA controller and SCSI address of attached disks

linuxpcisatascsi

I have a PCI-attached SATA controller connected to a (variable) number of disks on a machine with a Linux 2.6.39 kernel. I am trying to find the physical location of the disk, knowing the PCI address of the controller.

In this case, controller is at address 0000:01:00.0, and there are two disks, with SCSI addresses 6:0.0.0.0 and 8:0.0.0 (though these last two aren't necessarily fixed, this is just what they are right now).

lshw -c storage shows the controller and the SCSI devices (system disk and controller trimmed):

*-storage               
   description: SATA controller
   product: Marvell Technology Group Ltd.
   vendor: Marvell Technology Group Ltd.
   physical id: 0
   bus info: pci@0000:01:00.0
   version: 10
   width: 32 bits
   clock: 33MHz
   capabilities: storage pm msi pciexpress ahci_1.0 bus_master cap_list rom
   configuration: driver=ahci latency=0
   resources: irq:51 ioport:e050(size=8) ioport:e040(size=4) ioport:e030(size=8) ioport:e020(size=4) ioport:e000(size=32) memory:f7b10000-f7b107ff memory:f7b00000-f7b0ffff
*-scsi:1
   physical id: 2
   logical name: scsi6
   capabilities: emulated
*-scsi:2
   physical id: 3
   logical name: scsi8
   capabilities: emulated

lshw -c disk shows the disks:

*-disk
   description: ATA Disk
   product: TOSHIBA THNSNF25
   vendor: Toshiba
   physical id: 0.0.0
   bus info: scsi@6:0.0.0
   logical name: /dev/sdb
   version: FSXA
   serial: 824S105DT15Y
   size: 238GiB (256GB)
   capabilities: gpt-1.00 partitioned partitioned:gpt
   configuration: ansiversion=5 guid=79a679b1-3c04-4306-a498-9a959e2df371 sectorsize=4096
*-disk
   description: ATA Disk
   product: TOSHIBA THNSNF25
   vendor: Toshiba
   physical id: 0.0.0
   bus info: scsi@8:0.0.0
   logical name: /dev/sdc
   version: FSXA
   serial: 824S1055T15Y
   size: 238GiB (256GB)
   capabilities: gpt-1.00 partitioned partitioned:gpt
   configuration: ansiversion=5 guid=79a679b1-3c04-4306-a498-9a959e2df371 sectorsize=4096

However, there does not seem to be a way to go from the PCI address to the SCSI address. I have also looked under the sysfs entries for the PCI and SCSI devices and no been able to find an entry which makes the connection. When the disks are plugged into different physical ports on the controller, the SCSI address doesn't necessarily change, so this cannot be used with an offset to correctly determine the location of the disk.

Listing disks by ID also doesn't work – ls -lah /dev/disks/by-path shows that the entry for pci-0000:01:00.0-scsi-0:0:0:0 points to /dev/sdc (or in general, the last disk connected), and there are no other paths that start in pci-0000:01:00.0 that aren't just links to partitions of that drive.

Are there any other ways to map the controller address into something that can be used to locate the disks?

Best Answer

I think you can get what you want by cross referencing the output from lshw -c disk and this command, udevadm info -q all -n <device>.

For example

My /dev/sda device shows the following output for lshw:

$ sudo lshw -c disk
  *-disk                  
       description: ATA Disk
       product: ST9500420AS
       vendor: Seagate
       physical id: 0
       bus info: scsi@0:0.0.0
       logical name: /dev/sda
       version: 0003
       serial: 5XA1A2CZ
       size: 465GiB (500GB)
       capabilities: partitioned partitioned:dos
       configuration: ansiversion=5 signature=ebc57757

If I interrogate the same device using devadm I can find out what it's DEVPATH is:

$ sudo udevadm info -q all -n /dev/sda | grep DEVPATH
E: DEVPATH=/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda

This string has all the info you're looking for regarding this device. The PCI address, "0000:00:1f.2", along with the SCSI address, "0:0:0:0". The SCSI address is the data in the 6th position if you break this data up on the forward slashes ("/").

Related Question