diff options
Diffstat (limited to 'drivers/ata')
-rw-r--r-- | drivers/ata/libata-core.c | 27 | ||||
-rw-r--r-- | drivers/ata/libata-eh.c | 5 | ||||
-rw-r--r-- | drivers/ata/libata-scsi.c | 3 | ||||
-rw-r--r-- | drivers/ata/libata.h | 1 |
4 files changed, 24 insertions, 12 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 32325a1c07af..bfd452b0d46d 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -5977,6 +5977,21 @@ int ata_host_activate(struct ata_host *host, int irq, EXPORT_SYMBOL_GPL(ata_host_activate); /** + * ata_dev_free_resources - Free a device resources + * @dev: Target ATA device + * + * Free resources allocated to support a device features. + * + * LOCKING: + * Kernel thread context (may sleep). + */ +void ata_dev_free_resources(struct ata_device *dev) +{ + if (zpodd_dev_enabled(dev)) + zpodd_exit(dev); +} + +/** * ata_port_detach - Detach ATA port in preparation of device removal * @ap: ATA port to be detached * @@ -6030,19 +6045,15 @@ static void ata_port_detach(struct ata_port *ap) cancel_delayed_work_sync(&ap->hotplug_task); cancel_delayed_work_sync(&ap->scsi_rescan_task); - /* clean up zpodd on port removal */ - ata_for_each_link(link, ap, HOST_FIRST) { - ata_for_each_dev(dev, link, ALL) { - if (zpodd_dev_enabled(dev)) - zpodd_exit(dev); - } - } + /* Delete port multiplier link transport devices */ if (ap->pmp_link) { int i; + for (i = 0; i < SATA_PMP_MAX_PORTS; i++) ata_tlink_delete(&ap->pmp_link[i]); } - /* remove the associated SCSI host */ + + /* Remove the associated SCSI host */ scsi_remove_host(ap->scsi_host); ata_tport_delete(ap); } diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index ed535e1b4225..364828b8a22d 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -500,10 +500,13 @@ static void ata_eh_dev_disable(struct ata_device *dev) ata_down_xfermask_limit(dev, ATA_DNXFER_FORCE_PIO0 | ATA_DNXFER_QUIET); dev->class++; - /* From now till the next successful probe, ering is used to + /* + * From now till the next successful probe, ering is used to * track probe failures. Clear accumulated device error info. */ ata_ering_clear(&dev->ering); + + ata_dev_free_resources(dev); } static void ata_eh_unload(struct ata_port *ap) diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 6bd7ab27fcbb..4fb45565c142 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -4614,9 +4614,6 @@ static void ata_scsi_handle_link_detach(struct ata_link *link) dev->flags &= ~ATA_DFLAG_DETACHED; spin_unlock_irqrestore(ap->lock, flags); - if (zpodd_dev_enabled(dev)) - zpodd_exit(dev); - ata_scsi_remove_dev(dev); } } diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index 2a9d1bbf2482..927d77bde7ef 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h @@ -71,6 +71,7 @@ extern bool ata_dev_power_init_tf(struct ata_device *dev, struct ata_taskfile *tf, bool set_active); extern void ata_dev_power_set_standby(struct ata_device *dev); extern void ata_dev_power_set_active(struct ata_device *dev); +void ata_dev_free_resources(struct ata_device *dev); extern int ata_down_xfermask_limit(struct ata_device *dev, unsigned int sel); extern unsigned int ata_dev_set_feature(struct ata_device *dev, u8 subcmd, u8 action); |