Commit 3a35ed51 authored by James Bottomley's avatar James Bottomley Committed by James Bottomley

SCSI: fix multiple HBA problem with transport classes

All of the transport class patches contain a thinko in device matching
(and, unfortunately, one I exhorted everyone not to make in the generic
transport class comments): The match matches every container in the
class instead of the specific container belonging to the HBA.  This
causes a oops when there are two or more HBAs in the system.
Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent 21efc2e6
......@@ -728,6 +728,7 @@ static int fc_host_match(struct attribute_container *cont,
struct device *dev)
{
struct Scsi_Host *shost;
struct fc_internal *i;
if (!scsi_is_host_device(dev))
return 0;
......@@ -736,13 +737,17 @@ static int fc_host_match(struct attribute_container *cont,
if (!shost->transportt || shost->transportt->host_attrs.class
!= &fc_host_class.class)
return 0;
return 1;
i = to_fc_internal(shost->transportt);
return &i->t.host_attrs == cont;
}
static int fc_target_match(struct attribute_container *cont,
struct device *dev)
{
struct Scsi_Host *shost;
struct fc_internal *i;
if (!scsi_is_target_device(dev))
return 0;
......@@ -751,7 +756,10 @@ static int fc_target_match(struct attribute_container *cont,
if (!shost->transportt || shost->transportt->host_attrs.class
!= &fc_host_class.class)
return 0;
return 1;
i = to_fc_internal(shost->transportt);
return &i->t.target_attrs == cont;
}
......
......@@ -258,6 +258,7 @@ static int iscsi_host_match(struct attribute_container *cont,
struct device *dev)
{
struct Scsi_Host *shost;
struct iscsi_internal *i;
if (!scsi_is_host_device(dev))
return 0;
......@@ -266,13 +267,17 @@ static int iscsi_host_match(struct attribute_container *cont,
if (!shost->transportt || shost->transportt->host_attrs.class
!= &iscsi_host_class.class)
return 0;
return 1;
i = to_iscsi_internal(shost->transportt);
return &i->t.host_attrs == cont;
}
static int iscsi_target_match(struct attribute_container *cont,
struct device *dev)
{
struct Scsi_Host *shost;
struct iscsi_internal *i;
if (!scsi_is_target_device(dev))
return 0;
......@@ -281,7 +286,10 @@ static int iscsi_target_match(struct attribute_container *cont,
if (!shost->transportt || shost->transportt->host_attrs.class
!= &iscsi_host_class.class)
return 0;
return 1;
i = to_iscsi_internal(shost->transportt);
return &i->t.target_attrs == cont;
}
struct scsi_transport_template *
......
......@@ -136,6 +136,7 @@ static int spi_host_match(struct attribute_container *cont,
struct device *dev)
{
struct Scsi_Host *shost;
struct spi_internal *i;
if (!scsi_is_host_device(dev))
return 0;
......@@ -144,7 +145,10 @@ static int spi_host_match(struct attribute_container *cont,
if (!shost->transportt || shost->transportt->host_attrs.class
!= &spi_host_class.class)
return 0;
return 1;
i = to_spi_internal(shost->transportt);
return &i->t.host_attrs == cont;
}
static int spi_device_configure(struct device *dev)
......@@ -824,6 +828,9 @@ static int spi_device_match(struct attribute_container *cont,
if (!shost->transportt || shost->transportt->host_attrs.class
!= &spi_host_class.class)
return 0;
/* Note: this class has no device attributes, so it has
* no per-HBA allocation and thus we don't need to distinguish
* the attribute containers for the device */
return 1;
}
......@@ -831,6 +838,7 @@ static int spi_target_match(struct attribute_container *cont,
struct device *dev)
{
struct Scsi_Host *shost;
struct spi_internal *i;
if (!scsi_is_target_device(dev))
return 0;
......@@ -839,7 +847,10 @@ static int spi_target_match(struct attribute_container *cont,
if (!shost->transportt || shost->transportt->host_attrs.class
!= &spi_host_class.class)
return 0;
return 1;
i = to_spi_internal(shost->transportt);
return &i->t.target_attrs == cont;
}
static DECLARE_TRANSPORT_CLASS(spi_transport_class,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment