diff options
author | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2008-07-24 22:53:19 +0200 |
---|---|---|
committer | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2008-07-24 22:53:19 +0200 |
commit | ef0b04276d8f719d754c092434fbd62c2aeb5307 (patch) | |
tree | 8e39ed4e4f35dcfcb83c0331a68d4e3a2deb823c | |
parent | 37525bebcfc15a1fe5a9cb50bf49b21bf43559c1 (diff) |
ide: add ide_pci_remove() helper
* Add 'unsigned long host_flags' field to struct ide_host.
* Set ->host_flags in ide_host_alloc_all().
* Always set PCI dev's ->driver_data in ide_pci_init_{one,two}().
* Add ide_pci_remove() helper (the default implementation for
struct pci_driver's ->remove method).
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
-rw-r--r-- | drivers/ide/ide-probe.c | 3 | ||||
-rw-r--r-- | drivers/ide/setup-pci.c | 39 | ||||
-rw-r--r-- | include/linux/ide.h | 2 |
3 files changed, 38 insertions, 6 deletions
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 9ab5892eaea..f0c162488ec 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c @@ -1609,6 +1609,9 @@ struct ide_host *ide_host_alloc_all(const struct ide_port_info *d, if (hws[0]) host->dev[0] = hws[0]->dev; + if (d) + host->host_flags = d->host_flags; + return host; } EXPORT_SYMBOL_GPL(ide_host_alloc_all); diff --git a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c index ca17bf8896d..20f0ee00469 100644 --- a/drivers/ide/setup-pci.c +++ b/drivers/ide/setup-pci.c @@ -548,8 +548,7 @@ int ide_pci_init_one(struct pci_dev *dev, const struct ide_port_info *d, host->host_priv = priv; - if (priv) - pci_set_drvdata(dev, host); + pci_set_drvdata(dev, host); ret = do_ide_setup_pci_device(dev, d, 1); if (ret < 0) @@ -593,10 +592,8 @@ int ide_pci_init_two(struct pci_dev *dev1, struct pci_dev *dev2, host->host_priv = priv; - if (priv) { - pci_set_drvdata(pdev[0], host); - pci_set_drvdata(pdev[1], host); - } + pci_set_drvdata(pdev[0], host); + pci_set_drvdata(pdev[1], host); for (i = 0; i < 2; i++) { ret = do_ide_setup_pci_device(pdev[i], d, !i); @@ -619,3 +616,33 @@ out: return ret; } EXPORT_SYMBOL_GPL(ide_pci_init_two); + +void ide_pci_remove(struct pci_dev *dev) +{ + struct ide_host *host = pci_get_drvdata(dev); + struct pci_dev *dev2 = host->dev[1] ? to_pci_dev(host->dev[1]) : NULL; + int bars; + + if (host->host_flags & IDE_HFLAG_SINGLE) + bars = (1 << 2) - 1; + else + bars = (1 << 4) - 1; + + if ((host->host_flags & IDE_HFLAG_NO_DMA) == 0) { + if (host->host_flags & IDE_HFLAG_CS5520) + bars |= (1 << 2); + else + bars |= (1 << 4); + } + + ide_host_remove(host); + + if (dev2) + pci_release_selected_regions(dev2, bars); + pci_release_selected_regions(dev, bars); + + if (dev2) + pci_disable_device(dev2); + pci_disable_device(dev); +} +EXPORT_SYMBOL_GPL(ide_pci_remove); diff --git a/include/linux/ide.h b/include/linux/ide.h index 3eccac0a2a3..dbd0aeb3a56 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -631,6 +631,7 @@ struct ide_host { ide_hwif_t *ports[MAX_HWIFS]; unsigned int n_ports; struct device *dev[2]; + unsigned long host_flags; void *host_priv; }; @@ -1213,6 +1214,7 @@ struct ide_port_info { int ide_pci_init_one(struct pci_dev *, const struct ide_port_info *, void *); int ide_pci_init_two(struct pci_dev *, struct pci_dev *, const struct ide_port_info *, void *); +void ide_pci_remove(struct pci_dev *); void ide_map_sg(ide_drive_t *, struct request *); void ide_init_sg_cmd(ide_drive_t *, struct request *); |