Re: [PATCH] libata: rewrite SCSI host scheme to be one per ATA host

From: Grant Grundler
Date: Wed Apr 22 2009 - 15:09:30 EST


On Wed, Apr 22, 2009 at 2:09 AM, Jeff Garzik <jeff@xxxxxxxxxx> wrote:
>
> Currently, libata creates a Scsi_Host per port. ÂThis was originally
> done to leverage SCSI's infrastructure to arbitrate among master/slave
> devices, but is not needed for most modern SATA controllers. Â And I
> _think_ it is not needed for master/slave if done properly, either.
>
> The patch below converts libata such that there is now a 1:1
> correspondence between struct Scsi_Host and struct ata_host. ÂATA ports
> are represented as SCSI layer 'channels', which is more natural.

Jeff,
So far in reading this, the only reasons I gather for changing this
mapping are "not needed" and "is more natural". Data Center
environments (not just Google's) like to track disks in many different
ways, including the SCSI identifiers since this one "key" for physical
location. Breaking the current mappings is going to cause some people
a world of pain since they will need to manually build (and integrate)
old->new maps of the SCSI identifiers. Can you propose some real,
tangible benefit to making this change? (e.g. enables some other
feature)

Mark already pointed out this might cause issues with Error Handling
(forcing a review of all that code). So before triggering other
developers (e.g. HW vendors) do that kind of work I'd like to hear
what the reward is going to be at the end.

thanks,
grant

>
> This patch is an experiment, and not meant for upstream anytime soon.
> I just wanted to see what kind of effort would be required to get it
> to work.
>
> I was able to successfully boot the following patch on
> AHCI/x86-64/Fedora.
>
> It may work with other controllers -- TRY AT YOUR OWN RISK. ÂIt will
> probably fail for master/slave configurations, and SAS & PMP also
> need looking at. ÂIt yielded this lsscsi output on my AHCI box:
>
> [0:0:0:0]  Âdisk  ÂATA   ÂST3500320AS   ÂSD15 Â/dev/sda
> [0:2:0:0]  Âdisk  ÂATA   ÂG.SKILL 128GB SS 02.1 Â/dev/sdb
> [0:5:0:0] Â Âcd/dvd ÂPIONEER ÂBD-ROM ÂBDC-202 Â1.04 Â/dev/sr0
>
> NOT-signed-off-by: me
>
> Âdrivers/ata/ahci.c      Â|  Â4
> Âdrivers/ata/libata-core.c   |  17 +--
> Âdrivers/ata/libata-eh.c    |  47 ++++++--
> Âdrivers/ata/libata-scsi.c   | Â237 +++++++++++++++++++++---------------------
> Âdrivers/ata/libata.h     Â|  Â3
> Âdrivers/scsi/libsas/sas_ata.c | Â Â2
> Âinclude/linux/libata.h    Â|  Â9 -
> Â7 files changed, 184 insertions(+), 135 deletions(-)
>
> diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
> index 08186ec..b0468a8 100644
> --- a/drivers/ata/ahci.c
> +++ b/drivers/ata/ahci.c
> @@ -326,14 +326,18 @@ static ssize_t ahci_activity_store(struct ata_device *dev,
> Âstatic void ahci_init_sw_activity(struct ata_link *link);
>
> Âstatic struct device_attribute *ahci_shost_attrs[] = {
> +#if 0
> Â Â Â Â&dev_attr_link_power_management_policy,
> Â Â Â Â&dev_attr_em_message_type,
> Â Â Â Â&dev_attr_em_message,
> +#endif
> Â Â Â ÂNULL
> Â};
>
> Âstatic struct device_attribute *ahci_sdev_attrs[] = {
> +#if 0
> Â Â Â Â&dev_attr_sw_activity,
> +#endif
> Â Â Â Â&dev_attr_unload_heads,
> Â Â Â ÂNULL
> Â};
> diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
> index 17c5d48..71f32dc 100644
> --- a/drivers/ata/libata-core.c
> +++ b/drivers/ata/libata-core.c
> @@ -95,6 +95,7 @@ static void ata_dev_xfermask(struct ata_device *dev);
> Âstatic unsigned long ata_dev_blacklisted(const struct ata_device *dev);
>
> Âunsigned int ata_print_id = 1;
> +unsigned int ata_host_print_id = 1;
> Âstatic struct workqueue_struct *ata_wq;
>
> Âstruct workqueue_struct *ata_aux_wq;
> @@ -2308,7 +2309,7 @@ static void ata_dev_config_ncq(struct ata_device *dev,
> Â Â Â Â Â Â Â Âreturn;
> Â Â Â Â}
> Â Â Â Âif (ap->flags & ATA_FLAG_NCQ) {
> - Â Â Â Â Â Â Â hdepth = min(ap->scsi_host->can_queue, ATA_MAX_QUEUE - 1);
> + Â Â Â Â Â Â Â hdepth = min(ap->host->scsi_host->can_queue, ATA_MAX_QUEUE - 1);
> Â Â Â Â Â Â Â Âdev->flags |= ATA_DFLAG_NCQ;
> Â Â Â Â}
>
> @@ -5635,15 +5636,15 @@ static void ata_host_release(struct device *gendev, void *res)
> Â Â Â Â Â Â Â Âif (!ap)
> Â Â Â Â Â Â Â Â Â Â Â Âcontinue;
>
> - Â Â Â Â Â Â Â if (ap->scsi_host)
> - Â Â Â Â Â Â Â Â Â Â Â scsi_host_put(ap->scsi_host);
> -
> Â Â Â Â Â Â Â Âkfree(ap->pmp_link);
> Â Â Â Â Â Â Â Âkfree(ap->slave_link);
> Â Â Â Â Â Â Â Âkfree(ap);
> Â Â Â Â Â Â Â Âhost->ports[i] = NULL;
> Â Â Â Â}
>
> + Â Â Â if (host->scsi_host)
> + Â Â Â Â Â Â Â scsi_host_put(host->scsi_host);
> +
> Â Â Â Âdev_set_drvdata(gendev, NULL);
> Â}
>
> @@ -6089,6 +6090,8 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
> Â Â Â Âfor (i = 0; i < host->n_ports; i++)
> Â Â Â Â Â Â Â Âhost->ports[i]->print_id = ata_print_id++;
>
> + Â Â Â host->print_id = ata_host_print_id++;
> +
> Â Â Â Ârc = ata_scsi_add_hosts(host, sht);
> Â Â Â Âif (rc)
> Â Â Â Â Â Â Â Âreturn rc;
> @@ -6222,8 +6225,7 @@ static void ata_port_detach(struct ata_port *ap)
> Â Â Â Âcancel_rearming_delayed_work(&ap->hotplug_task);
>
> Âskip_eh:
> - Â Â Â /* remove the associated SCSI host */
> - Â Â Â scsi_remove_host(ap->scsi_host);
> + Â Â Â return;
> Â}
>
> Â/**
> @@ -6242,6 +6244,9 @@ void ata_host_detach(struct ata_host *host)
> Â Â Â Âfor (i = 0; i < host->n_ports; i++)
> Â Â Â Â Â Â Â Âata_port_detach(host->ports[i]);
>
> + Â Â Â /* remove the associated SCSI host */
> + Â Â Â scsi_remove_host(host->scsi_host);
> +
> Â Â Â Â/* the host is dead now, dissociate ACPI */
> Â Â Â Âata_acpi_dissociate(host);
> Â}
> diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
> index 0183131..db8a66f 100644
> --- a/drivers/ata/libata-eh.c
> +++ b/drivers/ata/libata-eh.c
> @@ -466,14 +466,22 @@ static void ata_eh_clear_action(struct ata_link *link, struct ata_device *dev,
> Â*/
> Âenum blk_eh_timer_return ata_scsi_timed_out(struct scsi_cmnd *cmd)
> Â{
> - Â Â Â struct Scsi_Host *host = cmd->device->host;
> - Â Â Â struct ata_port *ap = ata_shost_to_port(host);
> + Â Â Â struct Scsi_Host *shost = cmd->device->host;
> + Â Â Â struct ata_port *ap;
> + Â Â Â struct ata_host *host;
> + Â Â Â struct ata_device *atadev;
> Â Â Â Âunsigned long flags;
> Â Â Â Âstruct ata_queued_cmd *qc;
> - Â Â Â enum blk_eh_timer_return ret;
> + Â Â Â enum blk_eh_timer_return ret = BLK_EH_NOT_HANDLED;
>
> Â Â Â ÂDPRINTK("ENTER\n");
>
> + Â Â Â host = ata_shost_to_host(shost);
> + Â Â Â atadev = ata_scsi_find_dev(host, cmd->device);
> + Â Â Â if (!atadev)
> + Â Â Â Â Â Â Â goto out;
> + Â Â Â ap = atadev->link->ap;
> +
> Â Â Â Âif (ap->ops->error_handler) {
> Â Â Â Â Â Â Â Âret = BLK_EH_NOT_HANDLED;
> Â Â Â Â Â Â Â Âgoto out;
> @@ -532,13 +540,12 @@ static void ata_eh_unload(struct ata_port *ap)
> Â* Â Â RETURNS:
> Â* Â Â Zero.
> Â*/
> -void ata_scsi_error(struct Scsi_Host *host)
> +static void __ata_scsi_error(struct Scsi_Host *shost, struct ata_port *ap)
> Â{
> - Â Â Â struct ata_port *ap = ata_shost_to_port(host);
> Â Â Â Âint i;
> Â Â Â Âunsigned long flags;
>
> - Â Â Â DPRINTK("ENTER\n");
> + Â Â Â DPRINTK("ENTER, port_no %u\n", ap->port_no);
>
> Â Â Â Â/* synchronize with port task */
> Â Â Â Âata_port_flush_task(ap);
> @@ -575,7 +582,7 @@ void ata_scsi_error(struct Scsi_Host *host)
> Â Â Â Â Â Â Â Âif (ap->ops->lost_interrupt)
> Â Â Â Â Â Â Â Â Â Â Â Âap->ops->lost_interrupt(ap);
>
> - Â Â Â Â Â Â Â list_for_each_entry_safe(scmd, tmp, &host->eh_cmd_q, eh_entry) {
> + Â Â Â Â Â Â Â list_for_each_entry_safe(scmd, tmp, &shost->eh_cmd_q, eh_entry) {
> Â Â Â Â Â Â Â Â Â Â Â Âstruct ata_queued_cmd *qc;
>
> Â Â Â Â Â Â Â Â Â Â Â Âfor (i = 0; i < ATA_MAX_QUEUE; i++) {
> @@ -698,7 +705,7 @@ void ata_scsi_error(struct Scsi_Host *host)
> Â Â Â Â Â Â Â Â * before EH completion, SCSI midlayer will
> Â Â Â Â Â Â Â Â * re-initiate EH.
> Â Â Â Â Â Â Â Â */
> - Â Â Â Â Â Â Â host->host_eh_scheduled = 0;
> + Â Â Â Â Â Â Â shost->host_eh_scheduled = 0;
>
> Â Â Â Â Â Â Â Âspin_unlock_irqrestore(ap->lock, flags);
> Â Â Â Â} else {
> @@ -707,7 +714,7 @@ void ata_scsi_error(struct Scsi_Host *host)
> Â Â Â Â}
>
> Â Â Â Â/* finish or retry handled scmd's and clean up */
> - Â Â Â WARN_ON(host->host_failed || !list_empty(&host->eh_cmd_q));
> + Â Â Â WARN_ON(shost->host_failed || !list_empty(&shost->eh_cmd_q));
>
> Â Â Â Âscsi_eh_flush_done_q(&ap->eh_done_q);
>
> @@ -733,6 +740,24 @@ void ata_scsi_error(struct Scsi_Host *host)
> Â Â Â ÂDPRINTK("EXIT\n");
> Â}
>
> +void ata_scsi_error(struct Scsi_Host *shost)
> +{
> + Â Â Â struct ata_host *host = ata_shost_to_host(shost);
> + Â Â Â unsigned int i;
> +
> + Â Â Â DPRINTK("ENTER\n");
> +
> + Â Â Â for (i = 0; i < host->n_ports; i++) {
> + Â Â Â Â Â Â Â struct ata_port *ap = host->ports[i];
> +
> + Â Â Â Â Â Â Â if (ap->pflags & ATA_PFLAG_EH_PENDING)
> + Â Â Â Â Â Â Â Â Â Â Â __ata_scsi_error(shost, ap);
> + Â Â Â }
> +
> + Â Â Â DPRINTK("EXIT\n");
> +}
> +
> +
> Â/**
> Â* Â Â ata_port_wait_eh - Wait for the currently pending EH to complete
> Â* Â Â @ap: Port to wait EH for
> @@ -761,7 +786,7 @@ void ata_port_wait_eh(struct ata_port *ap)
> Â Â Â Âspin_unlock_irqrestore(ap->lock, flags);
>
> Â Â Â Â/* make sure SCSI EH is complete */
> - Â Â Â if (scsi_host_in_recovery(ap->scsi_host)) {
> + Â Â Â if (scsi_host_in_recovery(ap->host->scsi_host)) {
> Â Â Â Â Â Â Â Âmsleep(10);
> Â Â Â Â Â Â Â Âgoto retry;
> Â Â Â Â}
> @@ -901,7 +926,7 @@ void ata_port_schedule_eh(struct ata_port *ap)
> Â Â Â Â Â Â Â Âreturn;
>
> Â Â Â Âata_eh_set_pending(ap, 1);
> - Â Â Â scsi_schedule_eh(ap->scsi_host);
> + Â Â Â scsi_schedule_eh(ap->host->scsi_host);
>
> Â Â Â ÂDPRINTK("port EH scheduled\n");
> Â}
> diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
> index 2733b0c..7aa6aa6 100644
> --- a/drivers/ata/libata-scsi.c
> +++ b/drivers/ata/libata-scsi.c
> @@ -58,10 +58,8 @@ static u8 ata_scsi_rbuf[ATA_SCSI_RBUF_SIZE];
>
> Âtypedef unsigned int (*ata_xlat_func_t)(struct ata_queued_cmd *qc);
>
> -static struct ata_device *__ata_scsi_find_dev(struct ata_port *ap,
> +static struct ata_device *__ata_scsi_find_dev(struct ata_host *,
> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Âconst struct scsi_device *scsidev);
> -static struct ata_device *ata_scsi_find_dev(struct ata_port *ap,
> - Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â const struct scsi_device *scsidev);
> Âstatic int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel,
> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Âunsigned int id, unsigned int lun);
>
> @@ -136,6 +134,7 @@ static const char *ata_scsi_lpm_get(enum link_pm policy)
> Â Â Â Âreturn NULL;
> Â}
>
> +#if 0
> Âstatic ssize_t ata_scsi_lpm_put(struct device *dev,
> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Âstruct device_attribute *attr,
> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Âconst char *buf, size_t count)
> @@ -183,6 +182,7 @@ ata_scsi_lpm_show(struct device *dev, struct device_attribute *attr, char *buf)
> ÂDEVICE_ATTR(link_power_management_policy, S_IRUGO | S_IWUSR,
> Â Â Â Â Â Â Â Âata_scsi_lpm_show, ata_scsi_lpm_put);
> ÂEXPORT_SYMBOL_GPL(dev_attr_link_power_management_policy);
> +#endif
>
> Âstatic ssize_t ata_scsi_park_show(struct device *device,
> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Âstruct device_attribute *attr, char *buf)
> @@ -190,19 +190,21 @@ static ssize_t ata_scsi_park_show(struct device *device,
> Â Â Â Âstruct scsi_device *sdev = to_scsi_device(device);
> Â Â Â Âstruct ata_port *ap;
> Â Â Â Âstruct ata_link *link;
> + Â Â Â struct ata_host *host;
> Â Â Â Âstruct ata_device *dev;
> Â Â Â Âunsigned long flags, now;
> Â Â Â Âunsigned int uninitialized_var(msecs);
> Â Â Â Âint rc = 0;
>
> - Â Â Â ap = ata_shost_to_port(sdev->host);
> + Â Â Â host = ata_shost_to_host(sdev->host);
>
> - Â Â Â spin_lock_irqsave(ap->lock, flags);
> - Â Â Â dev = ata_scsi_find_dev(ap, sdev);
> + Â Â Â spin_lock_irqsave(&host->lock, flags);
> + Â Â Â dev = ata_scsi_find_dev(host, sdev);
> Â Â Â Âif (!dev) {
> Â Â Â Â Â Â Â Ârc = -ENODEV;
> Â Â Â Â Â Â Â Âgoto unlock;
> Â Â Â Â}
> + Â Â Â ap = dev->link->ap;
> Â Â Â Âif (dev->flags & ATA_DFLAG_NO_UNLOAD) {
> Â Â Â Â Â Â Â Ârc = -EOPNOTSUPP;
> Â Â Â Â Â Â Â Âgoto unlock;
> @@ -218,7 +220,7 @@ static ssize_t ata_scsi_park_show(struct device *device,
> Â Â Â Â Â Â Â Âmsecs = 0;
>
> Âunlock:
> - Â Â Â spin_unlock_irq(ap->lock);
> + Â Â Â spin_unlock_irq(&host->lock);
>
> Â Â Â Âreturn rc ? rc : snprintf(buf, 20, "%u\n", msecs);
> Â}
> @@ -230,6 +232,7 @@ static ssize_t ata_scsi_park_store(struct device *device,
> Â Â Â Âstruct scsi_device *sdev = to_scsi_device(device);
> Â Â Â Âstruct ata_port *ap;
> Â Â Â Âstruct ata_device *dev;
> + Â Â Â struct ata_host *host;
> Â Â Â Âlong int input;
> Â Â Â Âunsigned long flags;
> Â Â Â Âint rc;
> @@ -242,14 +245,15 @@ static ssize_t ata_scsi_park_store(struct device *device,
> Â Â Â Â Â Â Â Âinput = ATA_TMOUT_MAX_PARK;
> Â Â Â Â}
>
> - Â Â Â ap = ata_shost_to_port(sdev->host);
> + Â Â Â host = ata_shost_to_host(sdev->host);
>
> - Â Â Â spin_lock_irqsave(ap->lock, flags);
> - Â Â Â dev = ata_scsi_find_dev(ap, sdev);
> + Â Â Â spin_lock_irqsave(&host->lock, flags);
> + Â Â Â dev = ata_scsi_find_dev(host, sdev);
> Â Â Â Âif (unlikely(!dev)) {
> Â Â Â Â Â Â Â Ârc = -ENODEV;
> Â Â Â Â Â Â Â Âgoto unlock;
> Â Â Â Â}
> + Â Â Â ap = dev->link->ap;
> Â Â Â Âif (dev->class != ATA_DEV_ATA) {
> Â Â Â Â Â Â Â Ârc = -EOPNOTSUPP;
> Â Â Â Â Â Â Â Âgoto unlock;
> @@ -276,7 +280,7 @@ static ssize_t ata_scsi_park_store(struct device *device,
> Â Â Â Â Â Â Â Â}
> Â Â Â Â}
> Âunlock:
> - Â Â Â spin_unlock_irqrestore(ap->lock, flags);
> + Â Â Â spin_unlock_irqrestore(&host->lock, flags);
>
> Â Â Â Âreturn rc ? rc : len;
> Â}
> @@ -291,6 +295,7 @@ static void ata_scsi_set_sense(struct scsi_cmnd *cmd, u8 sk, u8 asc, u8 ascq)
> Â Â Â Âscsi_build_sense_buffer(0, cmd->sense_buffer, sk, asc, ascq);
> Â}
>
> +#if 0
> Âstatic ssize_t
> Âata_scsi_em_message_store(struct device *dev, struct device_attribute *attr,
> Â Â Â Â Â Â Â Â Â Â Â Â Âconst char *buf, size_t count)
> @@ -335,8 +340,9 @@ ata_scsi_activity_show(struct device *dev, struct device_attribute *attr,
> Â Â Â Â Â Â Â Âchar *buf)
> Â{
> Â Â Â Âstruct scsi_device *sdev = to_scsi_device(dev);
> - Â Â Â struct ata_port *ap = ata_shost_to_port(sdev->host);
> - Â Â Â struct ata_device *atadev = ata_scsi_find_dev(ap, sdev);
> + Â Â Â struct ata_host *host = ata_shost_to_host(sdev->host);
> + Â Â Â struct ata_device *atadev = ata_scsi_find_dev(host, sdev);
> + Â Â Â struct ata_port *ap = atadev->ap;
>
> Â Â Â Âif (ap->ops->sw_activity_show && (ap->flags & ATA_FLAG_SW_ACTIVITY))
> Â Â Â Â Â Â Â Âreturn ap->ops->sw_activity_show(atadev, buf);
> @@ -348,8 +354,9 @@ ata_scsi_activity_store(struct device *dev, struct device_attribute *attr,
> Â Â Â Âconst char *buf, size_t count)
> Â{
> Â Â Â Âstruct scsi_device *sdev = to_scsi_device(dev);
> - Â Â Â struct ata_port *ap = ata_shost_to_port(sdev->host);
> - Â Â Â struct ata_device *atadev = ata_scsi_find_dev(ap, sdev);
> + Â Â Â struct ata_host *host = ata_shost_to_host(sdev->host);
> + Â Â Â struct ata_device *atadev = ata_scsi_find_dev(host, sdev);
> + Â Â Â struct ata_port *ap = atadev->ap;
> Â Â Â Âenum sw_activity val;
> Â Â Â Âint rc;
>
> @@ -369,6 +376,7 @@ ata_scsi_activity_store(struct device *dev, struct device_attribute *attr,
> ÂDEVICE_ATTR(sw_activity, S_IWUGO | S_IRUGO, ata_scsi_activity_show,
> Â Â Â Â Â Â Â Â Â Â Â Âata_scsi_activity_store);
> ÂEXPORT_SYMBOL_GPL(dev_attr_sw_activity);
> +#endif
>
> Âstruct device_attribute *ata_common_sdev_attrs[] = {
> Â Â Â Â&dev_attr_unload_heads,
> @@ -425,10 +433,10 @@ int ata_std_bios_param(struct scsi_device *sdev, struct block_device *bdev,
> Â* Â Â RETURNS:
> Â* Â Â Zero on success, negative errno on error.
> Â*/
> -static int ata_get_identity(struct ata_port *ap, struct scsi_device *sdev,
> +static int ata_get_identity(struct ata_host *host, struct scsi_device *sdev,
> Â Â Â Â Â Â Â Â Â Â Â Â Â Âvoid __user *arg)
> Â{
> - Â Â Â struct ata_device *dev = ata_scsi_find_dev(ap, sdev);
> + Â Â Â struct ata_device *dev = ata_scsi_find_dev(host, sdev);
> Â Â Â Âu16 __user *dst = arg;
> Â Â Â Âchar buf[40];
>
> @@ -656,11 +664,18 @@ static int ata_ioc32(struct ata_port *ap)
> Â Â Â Âreturn 0;
> Â}
>
> -int ata_sas_scsi_ioctl(struct ata_port *ap, struct scsi_device *scsidev,
> +int ata_sas_scsi_ioctl(struct ata_host *host, struct scsi_device *scsidev,
> Â Â Â Â Â Â Â Â Â Â int cmd, void __user *arg)
> Â{
> Â Â Â Âint val = -EINVAL, rc = -EINVAL;
> Â Â Â Âunsigned long flags;
> + Â Â Â struct ata_port *ap;
> + Â Â Â struct ata_device *atadev;
> +
> + Â Â Â atadev = ata_scsi_find_dev(host, scsidev);
> + Â Â Â if (!atadev)
> + Â Â Â Â Â Â Â return -ENOENT;
> + Â Â Â ap = atadev->link->ap;
>
> Â Â Â Âswitch (cmd) {
> Â Â Â Âcase ATA_IOC_GET_IO32:
> @@ -688,7 +703,7 @@ int ata_sas_scsi_ioctl(struct ata_port *ap, struct scsi_device *scsidev,
> Â Â Â Â Â Â Â Âreturn rc;
>
> Â Â Â Âcase HDIO_GET_IDENTITY:
> - Â Â Â Â Â Â Â return ata_get_identity(ap, scsidev, arg);
> + Â Â Â Â Â Â Â return ata_get_identity(host, scsidev, arg);
>
> Â Â Â Âcase HDIO_DRIVE_CMD:
> Â Â Â Â Â Â Â Âif (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
> @@ -711,7 +726,7 @@ EXPORT_SYMBOL_GPL(ata_sas_scsi_ioctl);
>
> Âint ata_scsi_ioctl(struct scsi_device *scsidev, int cmd, void __user *arg)
> Â{
> - Â Â Â return ata_sas_scsi_ioctl(ata_shost_to_port(scsidev->host),
> + Â Â Â return ata_sas_scsi_ioctl(ata_shost_to_host(scsidev->host),
> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Âscsidev, cmd, arg);
> Â}
> ÂEXPORT_SYMBOL_GPL(ata_scsi_ioctl);
> @@ -1157,8 +1172,8 @@ static int ata_scsi_dev_config(struct scsi_device *sdev,
>
> Âint ata_scsi_slave_config(struct scsi_device *sdev)
> Â{
> - Â Â Â struct ata_port *ap = ata_shost_to_port(sdev->host);
> - Â Â Â struct ata_device *dev = __ata_scsi_find_dev(ap, sdev);
> + Â Â Â struct ata_host *host = ata_shost_to_host(sdev->host);
> + Â Â Â struct ata_device *dev = __ata_scsi_find_dev(host, sdev);
> Â Â Â Âint rc = 0;
>
> Â Â Â Âata_scsi_sdev_config(sdev);
> @@ -1185,27 +1200,34 @@ int ata_scsi_slave_config(struct scsi_device *sdev)
> Â*/
> Âvoid ata_scsi_slave_destroy(struct scsi_device *sdev)
> Â{
> - Â Â Â struct ata_port *ap = ata_shost_to_port(sdev->host);
> + Â Â Â struct ata_host *host = ata_shost_to_host(sdev->host);
> Â Â Â Âstruct request_queue *q = sdev->request_queue;
> Â Â Â Âunsigned long flags;
> Â Â Â Âstruct ata_device *dev;
> + Â Â Â bool new_eh = true;
>
> - Â Â Â if (!ap->ops->error_handler)
> - Â Â Â Â Â Â Â return;
> -
> - Â Â Â spin_lock_irqsave(ap->lock, flags);
> - Â Â Â dev = __ata_scsi_find_dev(ap, sdev);
> + Â Â Â spin_lock_irqsave(&host->lock, flags);
> + Â Â Â dev = __ata_scsi_find_dev(host, sdev);
> Â Â Â Âif (dev && dev->sdev) {
> + Â Â Â Â Â Â Â struct ata_port *ap = dev->link->ap;
> +
> + Â Â Â Â Â Â Â if (!ap->ops->error_handler)
> + Â Â Â Â Â Â Â Â Â Â Â new_eh = false;
> +
> + Â Â Â Â Â Â Â else {
> Â Â Â Â Â Â Â Â/* SCSI device already in CANCEL state, no need to offline it */
> Â Â Â Â Â Â Â Âdev->sdev = NULL;
> Â Â Â Â Â Â Â Âdev->flags |= ATA_DFLAG_DETACH;
> Â Â Â Â Â Â Â Âata_port_schedule_eh(ap);
> + Â Â Â Â Â Â Â }
> Â Â Â Â}
> - Â Â Â spin_unlock_irqrestore(ap->lock, flags);
> + Â Â Â spin_unlock_irqrestore(&host->lock, flags);
>
> - Â Â Â kfree(q->dma_drain_buffer);
> - Â Â Â q->dma_drain_buffer = NULL;
> - Â Â Â q->dma_drain_size = 0;
> + Â Â Â if (new_eh) {
> + Â Â Â Â Â Â Â kfree(q->dma_drain_buffer);
> + Â Â Â Â Â Â Â q->dma_drain_buffer = NULL;
> + Â Â Â Â Â Â Â q->dma_drain_size = 0;
> + Â Â Â }
> Â}
>
> Â/**
> @@ -1225,25 +1247,25 @@ void ata_scsi_slave_destroy(struct scsi_device *sdev)
> Â*/
> Âint ata_scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth)
> Â{
> - Â Â Â struct ata_port *ap = ata_shost_to_port(sdev->host);
> + Â Â Â struct ata_host *host = ata_shost_to_host(sdev->host);
> Â Â Â Âstruct ata_device *dev;
> Â Â Â Âunsigned long flags;
>
> Â Â Â Âif (queue_depth < 1 || queue_depth == sdev->queue_depth)
> Â Â Â Â Â Â Â Âreturn sdev->queue_depth;
>
> - Â Â Â dev = ata_scsi_find_dev(ap, sdev);
> + Â Â Â dev = ata_scsi_find_dev(host, sdev);
> Â Â Â Âif (!dev || !ata_dev_enabled(dev))
> Â Â Â Â Â Â Â Âreturn sdev->queue_depth;
>
> Â Â Â Â/* NCQ enabled? */
> - Â Â Â spin_lock_irqsave(ap->lock, flags);
> + Â Â Â spin_lock_irqsave(&host->lock, flags);
> Â Â Â Âdev->flags &= ~ATA_DFLAG_NCQ_OFF;
> Â Â Â Âif (queue_depth == 1 || !ata_ncq_enabled(dev)) {
> Â Â Â Â Â Â Â Âdev->flags |= ATA_DFLAG_NCQ_OFF;
> Â Â Â Â Â Â Â Âqueue_depth = 1;
> Â Â Â Â}
> - Â Â Â spin_unlock_irqrestore(ap->lock, flags);
> + Â Â Â spin_unlock_irqrestore(&host->lock, flags);
>
> Â Â Â Â/* limit and apply queue depth */
> Â Â Â Âqueue_depth = min(queue_depth, sdev->host->can_queue);
> @@ -2690,21 +2712,20 @@ static struct ata_device *ata_find_dev(struct ata_port *ap, int devno)
> Â Â Â Âreturn NULL;
> Â}
>
> -static struct ata_device *__ata_scsi_find_dev(struct ata_port *ap,
> +static struct ata_device *__ata_scsi_find_dev(struct ata_host *host,
> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Âconst struct scsi_device *scsidev)
> Â{
> Â Â Â Âint devno;
> + Â Â Â struct ata_port *ap;
>
> - Â Â Â /* skip commands not addressed to targets we simulate */
> - Â Â Â if (!sata_pmp_attached(ap)) {
> - Â Â Â Â Â Â Â if (unlikely(scsidev->channel || scsidev->lun))
> - Â Â Â Â Â Â Â Â Â Â Â return NULL;
> - Â Â Â Â Â Â Â devno = scsidev->id;
> - Â Â Â } else {
> - Â Â Â Â Â Â Â if (unlikely(scsidev->id || scsidev->lun))
> - Â Â Â Â Â Â Â Â Â Â Â return NULL;
> - Â Â Â Â Â Â Â devno = scsidev->channel;
> - Â Â Â }
> + Â Â Â if (scsidev->channel > host->n_ports)
> + Â Â Â Â Â Â Â return NULL;
> +
> + Â Â Â ap = host->ports[scsidev->channel];
> + Â Â Â if (ata_port_is_dummy(ap))
> + Â Â Â Â Â Â Â return NULL;
> +
> + Â Â Â devno = scsidev->id;
>
> Â Â Â Âreturn ata_find_dev(ap, devno);
> Â}
> @@ -2725,10 +2746,10 @@ static struct ata_device *__ata_scsi_find_dev(struct ata_port *ap,
> Â* Â Â RETURNS:
> Â* Â Â Associated ATA device, or %NULL if not found.
> Â*/
> -static struct ata_device *
> -ata_scsi_find_dev(struct ata_port *ap, const struct scsi_device *scsidev)
> +struct ata_device *
> +ata_scsi_find_dev(struct ata_host *host, const struct scsi_device *scsidev)
> Â{
> - Â Â Â struct ata_device *dev = __ata_scsi_find_dev(ap, scsidev);
> + Â Â Â struct ata_device *dev = __ata_scsi_find_dev(host, scsidev);
>
> Â Â Â Âif (unlikely(!dev || !ata_dev_enabled(dev)))
> Â Â Â Â Â Â Â Âreturn NULL;
> @@ -2983,15 +3004,13 @@ static inline ata_xlat_func_t ata_get_xlat_func(struct ata_device *dev, u8 cmd)
> Â* Â Â Prints the contents of a SCSI command via printk().
> Â*/
>
> -static inline void ata_scsi_dump_cdb(struct ata_port *ap,
> - Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Âstruct scsi_cmnd *cmd)
> +static inline void ata_scsi_dump_cdb(struct scsi_cmnd *cmd)
> Â{
> Â#ifdef ATA_DEBUG
> Â Â Â Âstruct scsi_device *scsidev = cmd->device;
> Â Â Â Âu8 *scsicmd = cmd->cmnd;
>
> - Â Â Â DPRINTK("CDB (%u:%d,%d,%d) %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
> - Â Â Â Â Â Â Â ap->print_id,
> + Â Â Â DPRINTK("CDB (%d,%d,%d) %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
> Â Â Â Â Â Â Â Âscsidev->channel, scsidev->id, scsidev->lun,
> Â Â Â Â Â Â Â Âscsicmd[0], scsicmd[1], scsicmd[2], scsicmd[3],
> Â Â Â Â Â Â Â Âscsicmd[4], scsicmd[5], scsicmd[6], scsicmd[7],
> @@ -3069,20 +3088,20 @@ static inline int __ata_scsi_queuecmd(struct scsi_cmnd *scmd,
> Â*/
> Âint ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
> Â{
> - Â Â Â struct ata_port *ap;
> Â Â Â Âstruct ata_device *dev;
> + Â Â Â struct ata_host *host;
> Â Â Â Âstruct scsi_device *scsidev = cmd->device;
> Â Â Â Âstruct Scsi_Host *shost = scsidev->host;
> Â Â Â Âint rc = 0;
>
> - Â Â Â ap = ata_shost_to_port(shost);
> + Â Â Â host = ata_shost_to_host(shost);
>
> Â Â Â Âspin_unlock(shost->host_lock);
> - Â Â Â spin_lock(ap->lock);
> + Â Â Â spin_lock(&host->lock);
>
> - Â Â Â ata_scsi_dump_cdb(ap, cmd);
> + Â Â Â ata_scsi_dump_cdb(cmd);
>
> - Â Â Â dev = ata_scsi_find_dev(ap, scsidev);
> + Â Â Â dev = ata_scsi_find_dev(host, scsidev);
> Â Â Â Âif (likely(dev))
> Â Â Â Â Â Â Â Ârc = __ata_scsi_queuecmd(cmd, done, dev);
> Â Â Â Âelse {
> @@ -3090,7 +3109,7 @@ int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
> Â Â Â Â Â Â Â Âdone(cmd);
> Â Â Â Â}
>
> - Â Â Â spin_unlock(ap->lock);
> + Â Â Â spin_unlock(&host->lock);
> Â Â Â Âspin_lock(shost->host_lock);
> Â Â Â Âreturn rc;
> Â}
> @@ -3217,56 +3236,43 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd,
>
> Âint ata_scsi_add_hosts(struct ata_host *host, struct scsi_host_template *sht)
> Â{
> - Â Â Â int i, rc;
> -
> - Â Â Â for (i = 0; i < host->n_ports; i++) {
> - Â Â Â Â Â Â Â struct ata_port *ap = host->ports[i];
> - Â Â Â Â Â Â Â struct Scsi_Host *shost;
> + Â Â Â int rc;
> + Â Â Â struct Scsi_Host *shost;
>
> - Â Â Â Â Â Â Â rc = -ENOMEM;
> - Â Â Â Â Â Â Â shost = scsi_host_alloc(sht, sizeof(struct ata_port *));
> - Â Â Â Â Â Â Â if (!shost)
> - Â Â Â Â Â Â Â Â Â Â Â goto err_alloc;
> + Â Â Â shost = scsi_host_alloc(sht, sizeof(struct ata_host *));
> + Â Â Â if (!shost)
> + Â Â Â Â Â Â Â return -ENOMEM;
>
> - Â Â Â Â Â Â Â *(struct ata_port **)&shost->hostdata[0] = ap;
> - Â Â Â Â Â Â Â ap->scsi_host = shost;
> + Â Â Â *(struct ata_host **)&shost->hostdata[0] = host;
> + Â Â Â host->scsi_host = shost;
>
> - Â Â Â Â Â Â Â shost->transportt = &ata_scsi_transport_template;
> - Â Â Â Â Â Â Â shost->unique_id = ap->print_id;
> - Â Â Â Â Â Â Â shost->max_id = 16;
> - Â Â Â Â Â Â Â shost->max_lun = 1;
> - Â Â Â Â Â Â Â shost->max_channel = 1;
> - Â Â Â Â Â Â Â shost->max_cmd_len = 16;
> + Â Â Â shost->transportt = &ata_scsi_transport_template;
> + Â Â Â shost->unique_id = host->print_id;
> + Â Â Â shost->max_id = 32;
> + Â Â Â shost->max_lun = 1;
> + Â Â Â shost->max_channel = 32;
> + Â Â Â shost->max_cmd_len = 16;
>
> - Â Â Â Â Â Â Â /* Schedule policy is determined by ->qc_defer()
> - Â Â Â Â Â Â Â Â* callback and it needs to see every deferred qc.
> - Â Â Â Â Â Â Â Â* Set host_blocked to 1 to prevent SCSI midlayer from
> - Â Â Â Â Â Â Â Â* automatically deferring requests.
> - Â Â Â Â Â Â Â Â*/
> - Â Â Â Â Â Â Â shost->max_host_blocked = 1;
> + Â Â Â /* Schedule policy is determined by ->qc_defer()
> + Â Â Â Â* callback and it needs to see every deferred qc.
> + Â Â Â Â* Set host_blocked to 1 to prevent SCSI midlayer from
> + Â Â Â Â* automatically deferring requests.
> + Â Â Â Â*/
> + Â Â Â shost->max_host_blocked = 1;
>
> - Â Â Â Â Â Â Â rc = scsi_add_host(ap->scsi_host, ap->host->dev);
> - Â Â Â Â Â Â Â if (rc)
> - Â Â Â Â Â Â Â Â Â Â Â goto err_add;
> + Â Â Â rc = scsi_add_host(shost, host->dev);
> + Â Â Â if (rc) {
> + Â Â Â Â Â Â Â scsi_host_put(shost);
> + Â Â Â Â Â Â Â return rc;
> Â Â Â Â}
>
> Â Â Â Âreturn 0;
> -
> - err_add:
> - Â Â Â scsi_host_put(host->ports[i]->scsi_host);
> - err_alloc:
> - Â Â Â while (--i >= 0) {
> - Â Â Â Â Â Â Â struct Scsi_Host *shost = host->ports[i]->scsi_host;
> -
> - Â Â Â Â Â Â Â scsi_remove_host(shost);
> - Â Â Â Â Â Â Â scsi_host_put(shost);
> - Â Â Â }
> - Â Â Â return rc;
> Â}
>
> Âvoid ata_scsi_scan_host(struct ata_port *ap, int sync)
> Â{
> Â Â Â Âint tries = 5;
> + Â Â Â struct ata_host *host = ap->host;
> Â Â Â Âstruct ata_device *last_failed_dev = NULL;
> Â Â Â Âstruct ata_link *link;
> Â Â Â Âstruct ata_device *dev;
> @@ -3278,7 +3284,7 @@ void ata_scsi_scan_host(struct ata_port *ap, int sync)
> Â Â Â Âata_for_each_link(link, ap, EDGE) {
> Â Â Â Â Â Â Â Âata_for_each_dev(dev, link, ENABLED) {
> Â Â Â Â Â Â Â Â Â Â Â Âstruct scsi_device *sdev;
> - Â Â Â Â Â Â Â Â Â Â Â int channel = 0, id = 0;
> + Â Â Â Â Â Â Â Â Â Â Â int id = 0;
>
> Â Â Â Â Â Â Â Â Â Â Â Âif (dev->sdev)
> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Âcontinue;
> @@ -3286,9 +3292,10 @@ void ata_scsi_scan_host(struct ata_port *ap, int sync)
> Â Â Â Â Â Â Â Â Â Â Â Âif (ata_is_host_link(link))
> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Âid = dev->devno;
> Â Â Â Â Â Â Â Â Â Â Â Âelse
> - Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â channel = link->pmp;
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â id = link->pmp;
>
> - Â Â Â Â Â Â Â Â Â Â Â sdev = __scsi_add_device(ap->scsi_host, channel, id, 0,
> + Â Â Â Â Â Â Â Â Â Â Â sdev = __scsi_add_device(host->scsi_host,
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Âap->port_no, id, 0,
> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â NULL);
> Â Â Â Â Â Â Â Â Â Â Â Âif (!IS_ERR(sdev)) {
> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Âdev->sdev = sdev;
> @@ -3376,6 +3383,7 @@ int ata_scsi_offline_dev(struct ata_device *dev)
> Âstatic void ata_scsi_remove_dev(struct ata_device *dev)
> Â{
> Â Â Â Âstruct ata_port *ap = dev->link->ap;
> + Â Â Â struct ata_host *host = ap->host;
> Â Â Â Âstruct scsi_device *sdev;
> Â Â Â Âunsigned long flags;
>
> @@ -3385,7 +3393,7 @@ static void ata_scsi_remove_dev(struct ata_device *dev)
> Â Â Â Â * be removed if there is __scsi_device_get() interface which
> Â Â Â Â * increments reference counts regardless of device state.
> Â Â Â Â */
> - Â Â Â mutex_lock(&ap->scsi_host->scan_mutex);
> + Â Â Â mutex_lock(&host->scsi_host->scan_mutex);
> Â Â Â Âspin_lock_irqsave(ap->lock, flags);
>
> Â Â Â Â/* clearing dev->sdev is protected by host lock */
> @@ -3411,7 +3419,7 @@ static void ata_scsi_remove_dev(struct ata_device *dev)
> Â Â Â Â}
>
> Â Â Â Âspin_unlock_irqrestore(ap->lock, flags);
> - Â Â Â mutex_unlock(&ap->scsi_host->scan_mutex);
> + Â Â Â mutex_unlock(&host->scsi_host->scan_mutex);
>
> Â Â Â Âif (sdev) {
> Â Â Â Â Â Â Â Âata_dev_printk(dev, KERN_INFO, "detaching (SCSI %s)\n",
> @@ -3517,25 +3525,28 @@ void ata_scsi_hotplug(struct work_struct *work)
> Âstatic int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel,
> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Âunsigned int id, unsigned int lun)
> Â{
> - Â Â Â struct ata_port *ap = ata_shost_to_port(shost);
> + Â Â Â struct ata_port *ap;
> + Â Â Â struct ata_host *host = ata_shost_to_host(shost);
> Â Â Â Âunsigned long flags;
> Â Â Â Âint devno, rc = 0;
>
> + Â Â Â if (channel == SCAN_WILD_CARD)
> + Â Â Â Â Â Â Â ap = host->ports[0];
> + Â Â Â else {
> + Â Â Â Â Â Â Â if (channel > host->n_ports)
> + Â Â Â Â Â Â Â Â Â Â Â return -EINVAL;
> + Â Â Â Â Â Â Â ap = host->ports[channel];
> + Â Â Â }
> +
> Â Â Â Âif (!ap->ops->error_handler)
> Â Â Â Â Â Â Â Âreturn -EOPNOTSUPP;
>
> Â Â Â Âif (lun != SCAN_WILD_CARD && lun)
> Â Â Â Â Â Â Â Âreturn -EINVAL;
>
> - Â Â Â if (!sata_pmp_attached(ap)) {
> - Â Â Â Â Â Â Â if (channel != SCAN_WILD_CARD && channel)
> - Â Â Â Â Â Â Â Â Â Â Â return -EINVAL;
> - Â Â Â Â Â Â Â devno = id;
> - Â Â Â } else {
> - Â Â Â Â Â Â Â if (id != SCAN_WILD_CARD && id)
> - Â Â Â Â Â Â Â Â Â Â Â return -EINVAL;
> - Â Â Â Â Â Â Â devno = channel;
> - Â Â Â }
> + Â Â Â if (id != SCAN_WILD_CARD && id)
> + Â Â Â Â Â Â Â return -EINVAL;
> + Â Â Â devno = id;
>
> Â Â Â Âspin_lock_irqsave(ap->lock, flags);
>
> @@ -3749,7 +3760,7 @@ int ata_sas_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *),
> Â{
> Â Â Â Âint rc = 0;
>
> - Â Â Â ata_scsi_dump_cdb(ap, cmd);
> + Â Â Â ata_scsi_dump_cdb(cmd);
>
> Â Â Â Âif (likely(ata_dev_enabled(ap->link.device)))
> Â Â Â Â Â Â Â Ârc = __ata_scsi_queuecmd(cmd, done, ap->link.device);
> diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h
> index 89a1e00..af890b4 100644
> --- a/drivers/ata/libata.h
> +++ b/drivers/ata/libata.h
> @@ -205,4 +205,7 @@ extern u8 ata_irq_on(struct ata_port *ap);
> Âextern void ata_pio_task(struct work_struct *work);
> Â#endif /* CONFIG_ATA_SFF */
>
> +struct ata_device *
> +ata_scsi_find_dev(struct ata_host *host, const struct scsi_device *scsidev);
> +
> Â#endif /* __LIBATA_H__ */
> diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c
> index e155011..758df0b 100644
> --- a/drivers/scsi/libsas/sas_ata.c
> +++ b/drivers/scsi/libsas/sas_ata.c
> @@ -375,6 +375,7 @@ int sas_ata_init_host_and_port(struct domain_device *found_dev,
> Â Â Â Â Â Â Â Â Â Â Âha->dev,
> Â Â Â Â Â Â Â Â Â Â Âsata_port_info.flags,
> Â Â Â Â Â Â Â Â Â Â Â&sas_sata_ops);
> + Â Â Â found_dev->sata_dev.ata_host.scsi_host = shost;
> Â Â Â Âap = ata_sas_port_alloc(&found_dev->sata_dev.ata_host,
> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â&sata_port_info,
> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Âshost);
> @@ -385,7 +386,6 @@ int sas_ata_init_host_and_port(struct domain_device *found_dev,
>
> Â Â Â Âap->private_data = found_dev;
> Â Â Â Âap->cbl = ATA_CBL_SATA;
> - Â Â Â ap->scsi_host = shost;
> Â Â Â Âfound_dev->sata_dev.ap = ap;
>
> Â Â Â Âreturn 0;
> diff --git a/include/linux/libata.h b/include/linux/libata.h
> index 3d501db..2ea4dce 100644
> --- a/include/linux/libata.h
> +++ b/include/linux/libata.h
> @@ -507,10 +507,12 @@ struct ata_ioports {
> Â#endif /* CONFIG_ATA_SFF */
>
> Âstruct ata_host {
> +    struct Scsi_Host    Â*scsi_host; /* our co-allocated scsi host */
>    Âspinlock_t       Âlock;
>    Âstruct device      *dev;
>    Âvoid __iomem * const  Â*iomap;
>    Âunsigned int      Ân_ports;
> +    unsigned int      Âprint_id; /* user visible unique host ID */
>    Âvoid          Â*private_data;
> Â Â Â Âstruct ata_port_operations *ops;
>    Âunsigned long      flags;
> @@ -690,7 +692,6 @@ struct ata_link {
> Â};
>
> Âstruct ata_port {
> -    struct Scsi_Host    Â*scsi_host; /* our co-allocated scsi host */
> Â Â Â Âstruct ata_port_operations *ops;
>    Âspinlock_t       Â*lock;
> Â Â Â Â/* Flags owned by the EH context. Only EH should touch these once the
> @@ -947,7 +948,7 @@ extern void ata_host_init(struct ata_host *, struct device *,
> Âextern int ata_scsi_detect(struct scsi_host_template *sht);
> Âextern int ata_scsi_ioctl(struct scsi_device *dev, int cmd, void __user *arg);
> Âextern int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *));
> -extern int ata_sas_scsi_ioctl(struct ata_port *ap, struct scsi_device *dev,
> +extern int ata_sas_scsi_ioctl(struct ata_host *, struct scsi_device *dev,
> Â Â Â Â Â Â Â Â Â Â Â Â Â Âint cmd, void __user *arg);
> Âextern void ata_sas_port_destroy(struct ata_port *);
> Âextern struct ata_port *ata_sas_port_alloc(struct ata_host *,
> @@ -1472,9 +1473,9 @@ static inline unsigned int __ac_err_mask(u8 status)
> Â Â Â Âreturn mask;
> Â}
>
> -static inline struct ata_port *ata_shost_to_port(struct Scsi_Host *host)
> +static inline struct ata_host *ata_shost_to_host(struct Scsi_Host *host)
> Â{
> - Â Â Â return *(struct ata_port **)&host->hostdata[0];
> + Â Â Â return *(struct ata_host **)&host->hostdata[0];
> Â}
>
> Âstatic inline int ata_check_ready(u8 status)
>
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/