diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c index da5bd33d982d7e521b6b0603adcb0911395b184d..fc5263c6b10267b2869cf8b3a1967b97490b392b 100644 --- a/drivers/scsi/ahci.c +++ b/drivers/scsi/ahci.c @@ -32,6 +32,7 @@ #include #include #include +#include #include "scsi.h" #include #include @@ -289,6 +290,8 @@ static void ahci_host_stop(struct ata_host_set *host_set) { struct ahci_host_priv *hpriv = host_set->private_data; kfree(hpriv); + + ata_host_stop(host_set); } static int ahci_port_start(struct ata_port *ap) diff --git a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c index 3867f91ef8c7bebe3d0edf0bd2e3b326a1d4061b..54c52349adc53297971c6e04067d931aabf3148d 100644 --- a/drivers/scsi/ata_piix.c +++ b/drivers/scsi/ata_piix.c @@ -153,6 +153,7 @@ static struct ata_port_operations piix_pata_ops = { .port_start = ata_port_start, .port_stop = ata_port_stop, + .host_stop = ata_host_stop, }; static struct ata_port_operations piix_sata_ops = { @@ -180,6 +181,7 @@ static struct ata_port_operations piix_sata_ops = { .port_start = ata_port_start, .port_stop = ata_port_stop, + .host_stop = ata_host_stop, }; static struct ata_port_info piix_port_info[] = { diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index 63d3f70d06e17b917d1e6e0da9169a50fea340d2..30a88f0e7bd61b4c6a1c2f5919da0c4df656e87e 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c @@ -3322,6 +3322,13 @@ void ata_port_stop (struct ata_port *ap) dma_free_coherent(dev, ATA_PRD_TBL_SZ, ap->prd, ap->prd_dma); } +void ata_host_stop (struct ata_host_set *host_set) +{ + if (host_set->mmio_base) + iounmap(host_set->mmio_base); +} + + /** * ata_host_remove - Unregister SCSI host structure with upper layers * @ap: Port to unregister @@ -3878,10 +3885,6 @@ void ata_pci_remove_one (struct pci_dev *pdev) } free_irq(host_set->irq, host_set); - if (host_set->ops->host_stop) - host_set->ops->host_stop(host_set); - if (host_set->mmio_base) - iounmap(host_set->mmio_base); for (i = 0; i < host_set->n_ports; i++) { ap = host_set->ports[i]; @@ -3900,6 +3903,9 @@ void ata_pci_remove_one (struct pci_dev *pdev) scsi_host_put(ap->host); } + if (host_set->ops->host_stop) + host_set->ops->host_stop(host_set); + kfree(host_set); pci_release_regions(pdev); @@ -3997,6 +4003,7 @@ EXPORT_SYMBOL_GPL(ata_chk_err); EXPORT_SYMBOL_GPL(ata_exec_command); EXPORT_SYMBOL_GPL(ata_port_start); EXPORT_SYMBOL_GPL(ata_port_stop); +EXPORT_SYMBOL_GPL(ata_host_stop); EXPORT_SYMBOL_GPL(ata_interrupt); EXPORT_SYMBOL_GPL(ata_qc_prep); EXPORT_SYMBOL_GPL(ata_bmdma_setup); diff --git a/drivers/scsi/libata.h b/drivers/scsi/libata.h index 6518226b8f87f2e92d75694420d593498cba00e1..d90430bbb0de1032bc40e6835550962ac4dbdd5f 100644 --- a/drivers/scsi/libata.h +++ b/drivers/scsi/libata.h @@ -26,7 +26,7 @@ #define __LIBATA_H__ #define DRV_NAME "libata" -#define DRV_VERSION "1.10" /* must be exactly four chars */ +#define DRV_VERSION "1.11" /* must be exactly four chars */ struct ata_scsi_args { u16 *id; diff --git a/drivers/scsi/sata_nv.c b/drivers/scsi/sata_nv.c index 69009f853a4917f54a88aa0c2cf3e6fb0428c8f7..b0403ccd8a25d97aec9e220d175844dd45448076 100644 --- a/drivers/scsi/sata_nv.c +++ b/drivers/scsi/sata_nv.c @@ -329,6 +329,8 @@ static void nv_host_stop (struct ata_host_set *host_set) host->host_desc->disable_hotplug(host_set); kfree(host); + + ata_host_stop(host_set); } static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) diff --git a/drivers/scsi/sata_promise.c b/drivers/scsi/sata_promise.c index c4e9e0298122334c272c4a33569d34fc6bee42be..b18c90582e67cf32216049f7aca031024779c966 100644 --- a/drivers/scsi/sata_promise.c +++ b/drivers/scsi/sata_promise.c @@ -122,6 +122,7 @@ static struct ata_port_operations pdc_ata_ops = { .scr_write = pdc_sata_scr_write, .port_start = pdc_port_start, .port_stop = pdc_port_stop, + .host_stop = ata_host_stop, }; static struct ata_port_info pdc_port_info[] = { diff --git a/drivers/scsi/sata_qstor.c b/drivers/scsi/sata_qstor.c index dfd3621047171dc748ba9a11c82a418f89faaed6..1383e8a28d728b34e936c0b9c7e04ffbf9a5818c 100644 --- a/drivers/scsi/sata_qstor.c +++ b/drivers/scsi/sata_qstor.c @@ -536,6 +536,8 @@ static void qs_host_stop(struct ata_host_set *host_set) writeb(0, mmio_base + QS_HCT_CTRL); /* disable host interrupts */ writeb(QS_CNFG3_GSRST, mmio_base + QS_HCF_CNFG3); /* global reset */ + + ata_host_stop(host_set); } static void qs_host_init(unsigned int chip_id, struct ata_probe_ent *pe) diff --git a/drivers/scsi/sata_sil.c b/drivers/scsi/sata_sil.c index 2b2ff48be3960b14464e19018acb1b458c91819f..238580d244e697ec22427cda94ce1418a945aa2b 100644 --- a/drivers/scsi/sata_sil.c +++ b/drivers/scsi/sata_sil.c @@ -161,6 +161,7 @@ static struct ata_port_operations sil_ops = { .scr_write = sil_scr_write, .port_start = ata_port_start, .port_stop = ata_port_stop, + .host_stop = ata_host_stop, }; static struct ata_port_info sil_port_info[] = { diff --git a/drivers/scsi/sata_sis.c b/drivers/scsi/sata_sis.c index 5105ddd08447807df3710492f70c31bf6f0d8767..e418b89c6b9d8cf67c57a1b03431b91a19b585f2 100644 --- a/drivers/scsi/sata_sis.c +++ b/drivers/scsi/sata_sis.c @@ -114,6 +114,7 @@ static struct ata_port_operations sis_ops = { .scr_write = sis_scr_write, .port_start = ata_port_start, .port_stop = ata_port_stop, + .host_stop = ata_host_stop, }; static struct ata_port_info sis_port_info = { diff --git a/drivers/scsi/sata_svw.c b/drivers/scsi/sata_svw.c index 05075bd3a89309e2b8f39e18cef5dfb27191dcea..edef1fa969fcecba6907ae49b84bf81a5ecae7c3 100644 --- a/drivers/scsi/sata_svw.c +++ b/drivers/scsi/sata_svw.c @@ -313,6 +313,7 @@ static struct ata_port_operations k2_sata_ops = { .scr_write = k2_sata_scr_write, .port_start = ata_port_start, .port_stop = ata_port_stop, + .host_stop = ata_host_stop, }; static void k2_sata_setup_port(struct ata_ioports *port, unsigned long base) diff --git a/drivers/scsi/sata_sx4.c b/drivers/scsi/sata_sx4.c index 70118650c461e9d5d10ff0c3053ae5b49c6755a0..140cea05de3f23cdfa8d204af0d49b9f52f32913 100644 --- a/drivers/scsi/sata_sx4.c +++ b/drivers/scsi/sata_sx4.c @@ -245,6 +245,8 @@ static void pdc20621_host_stop(struct ata_host_set *host_set) iounmap(dimm_mmio); kfree(hpriv); + + ata_host_stop(host_set); } static int pdc_port_start(struct ata_port *ap) diff --git a/drivers/scsi/sata_uli.c b/drivers/scsi/sata_uli.c index 0bff4f475f262c5c40254aecf85bd6a7137bd04e..a71fb54eebd301e07240310964a323b240db670d 100644 --- a/drivers/scsi/sata_uli.c +++ b/drivers/scsi/sata_uli.c @@ -113,6 +113,7 @@ static struct ata_port_operations uli_ops = { .port_start = ata_port_start, .port_stop = ata_port_stop, + .host_stop = ata_host_stop, }; static struct ata_port_info uli_port_info = { diff --git a/drivers/scsi/sata_via.c b/drivers/scsi/sata_via.c index 3a7830667277f35f71a83db5705b8cb2d376bafc..f43183c19a12184ebd6902eadf154bc836a7e249 100644 --- a/drivers/scsi/sata_via.c +++ b/drivers/scsi/sata_via.c @@ -134,6 +134,7 @@ static struct ata_port_operations svia_sata_ops = { .port_start = ata_port_start, .port_stop = ata_port_stop, + .host_stop = ata_host_stop, }; static struct ata_port_info svia_port_info = { diff --git a/drivers/scsi/sata_vsc.c b/drivers/scsi/sata_vsc.c index 2c28f0ad73c204420aa4b419a60341a8b801d7fa..c5e09dc6f3de67b3250250d7f064ff873d679bb6 100644 --- a/drivers/scsi/sata_vsc.c +++ b/drivers/scsi/sata_vsc.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "scsi.h" #include #include @@ -230,6 +231,7 @@ static struct ata_port_operations vsc_sata_ops = { .scr_write = vsc_sata_scr_write, .port_start = ata_port_start, .port_stop = ata_port_stop, + .host_stop = ata_host_stop, }; static void __devinit vsc_sata_setup_port(struct ata_ioports *port, unsigned long base) diff --git a/include/linux/libata.h b/include/linux/libata.h index 1f7e2039a04e38bb0235c489301c1cfc094f611b..e74f301e9baea59df14efbbd75943a61b496651c 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -410,6 +410,7 @@ extern u8 ata_chk_err(struct ata_port *ap); extern void ata_exec_command(struct ata_port *ap, struct ata_taskfile *tf); extern int ata_port_start (struct ata_port *ap); extern void ata_port_stop (struct ata_port *ap); +extern void ata_host_stop (struct ata_host_set *host_set); extern irqreturn_t ata_interrupt (int irq, void *dev_instance, struct pt_regs *regs); extern void ata_qc_prep(struct ata_queued_cmd *qc); extern int ata_qc_issue_prot(struct ata_queued_cmd *qc);