Commit ba059590 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull ata fix from Damien Le Moal:

 - Fix ata_find_dev() use of the device number to find a struct
   ata_device for a port. This addresses issues with some passthrough
   commands with libsas managed devices.

* tag 'ata-6.4-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/dlemoal/libata:
  ata: libata-scsi: Use correct device no in ata_find_dev()
parents 88280037 7f875850
Loading
Loading
Loading
Loading
+26 −8
Original line number Diff line number Diff line
@@ -2694,18 +2694,36 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc)
	return 0;
}

static struct ata_device *ata_find_dev(struct ata_port *ap, int devno)
static struct ata_device *ata_find_dev(struct ata_port *ap, unsigned int devno)
{
	if (!sata_pmp_attached(ap)) {
		if (likely(devno >= 0 &&
			   devno < ata_link_max_devices(&ap->link)))
	/*
	 * For the non-PMP case, ata_link_max_devices() returns 1 (SATA case),
	 * or 2 (IDE master + slave case). However, the former case includes
	 * libsas hosted devices which are numbered per scsi host, leading
	 * to devno potentially being larger than 0 but with each struct
	 * ata_device having its own struct ata_port and struct ata_link.
	 * To accommodate these, ignore devno and always use device number 0.
	 */
	if (likely(!sata_pmp_attached(ap))) {
		int link_max_devices = ata_link_max_devices(&ap->link);

		if (link_max_devices == 1)
			return &ap->link.device[0];

		if (devno < link_max_devices)
			return &ap->link.device[devno];
	} else {
		if (likely(devno >= 0 &&
			   devno < ap->nr_pmp_links))
			return &ap->pmp_link[devno].device[0];

		return NULL;
	}

	/*
	 * For PMP-attached devices, the device number corresponds to C
	 * (channel) of SCSI [H:C:I:L], indicating the port pmp link
	 * for the device.
	 */
	if (devno < ap->nr_pmp_links)
		return &ap->pmp_link[devno].device[0];

	return NULL;
}