summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2008-07-24 20:53:19 (GMT)
committerBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2008-07-24 20:53:19 (GMT)
commitef0b04276d8f719d754c092434fbd62c2aeb5307 (patch)
tree8e39ed4e4f35dcfcb83c0331a68d4e3a2deb823c
parent37525bebcfc15a1fe5a9cb50bf49b21bf43559c1 (diff)
downloadlinux-ef0b04276d8f719d754c092434fbd62c2aeb5307.tar.xz
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.c3
-rw-r--r--drivers/ide/setup-pci.c39
-rw-r--r--include/linux/ide.h2
3 files changed, 38 insertions, 6 deletions
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index 9ab5892..f0c1624 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 ca17bf8..20f0ee0 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 3eccac0..dbd0aeb 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 *);