diff options
author | Tejun Heo <htejun@gmail.com> | 2007-01-20 02:00:28 -0500 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2007-02-09 17:39:37 -0500 |
commit | f0d36efdc624beb3d9e29b9ab9e9537bf0f25d5b (patch) | |
tree | eac4efb465aa682d6eaac61f76b3174ffd9fd8cd /drivers | |
parent | 0529c159dbdd79794796c1b50b39442d72efbe97 (diff) |
libata: update libata core layer to use devres
Update libata core layer to use devres.
* ata_device_add() acquires all resources in managed mode.
* ata_host is allocated as devres associated with ata_host_release.
* Port attached status is handled as devres associated with
ata_host_attach_release().
* Initialization failure and host removal is handedl by releasing
devres group.
* Except for ata_scsi_release() removal, LLD interface remains the
same. Some functions use hacky is_managed test to support both
managed and unmanaged devices. These will go away once all LLDs are
updated to use devres.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/ata/ahci.c | 21 | ||||
-rw-r--r-- | drivers/ata/libata-core.c | 177 | ||||
-rw-r--r-- | drivers/ata/libata-scsi.c | 3 | ||||
-rw-r--r-- | drivers/ata/libata-sff.c | 56 |
4 files changed, 102 insertions, 155 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 649dfa57e51c..d72568392e6c 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
@@ -1784,37 +1784,24 @@ err_out: | |||
1784 | return rc; | 1784 | return rc; |
1785 | } | 1785 | } |
1786 | 1786 | ||
1787 | static void ahci_remove_one (struct pci_dev *pdev) | 1787 | static void ahci_remove_one(struct pci_dev *pdev) |
1788 | { | 1788 | { |
1789 | struct device *dev = pci_dev_to_dev(pdev); | 1789 | struct device *dev = pci_dev_to_dev(pdev); |
1790 | struct ata_host *host = dev_get_drvdata(dev); | 1790 | struct ata_host *host = dev_get_drvdata(dev); |
1791 | struct ahci_host_priv *hpriv = host->private_data; | 1791 | struct ahci_host_priv *hpriv = host->private_data; |
1792 | unsigned int i; | ||
1793 | int have_msi; | ||
1794 | 1792 | ||
1795 | ata_host_detach(host); | 1793 | ata_host_remove(host); |
1796 | 1794 | ||
1797 | have_msi = hpriv->flags & AHCI_FLAG_MSI; | ||
1798 | free_irq(host->irq, host); | ||
1799 | |||
1800 | for (i = 0; i < host->n_ports; i++) { | ||
1801 | struct ata_port *ap = host->ports[i]; | ||
1802 | |||
1803 | ata_scsi_release(ap->scsi_host); | ||
1804 | scsi_host_put(ap->scsi_host); | ||
1805 | } | ||
1806 | |||
1807 | kfree(hpriv); | ||
1808 | pci_iounmap(pdev, host->mmio_base); | 1795 | pci_iounmap(pdev, host->mmio_base); |
1809 | kfree(host); | ||
1810 | 1796 | ||
1811 | if (have_msi) | 1797 | if (hpriv->flags & AHCI_FLAG_MSI) |
1812 | pci_disable_msi(pdev); | 1798 | pci_disable_msi(pdev); |
1813 | else | 1799 | else |
1814 | pci_intx(pdev, 0); | 1800 | pci_intx(pdev, 0); |
1815 | pci_release_regions(pdev); | 1801 | pci_release_regions(pdev); |
1816 | pci_disable_device(pdev); | 1802 | pci_disable_device(pdev); |
1817 | dev_set_drvdata(dev, NULL); | 1803 | dev_set_drvdata(dev, NULL); |
1804 | kfree(hpriv); | ||
1818 | } | 1805 | } |
1819 | 1806 | ||
1820 | static int __init ahci_init(void) | 1807 | static int __init ahci_init(void) |
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index a927c4c8bef3..20b2409a0d20 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
@@ -5486,28 +5486,25 @@ void ata_host_resume(struct ata_host *host) | |||
5486 | * LOCKING: | 5486 | * LOCKING: |
5487 | * Inherited from caller. | 5487 | * Inherited from caller. |
5488 | */ | 5488 | */ |
5489 | 5489 | int ata_port_start(struct ata_port *ap) | |
5490 | int ata_port_start (struct ata_port *ap) | ||
5491 | { | 5490 | { |
5492 | struct device *dev = ap->dev; | 5491 | struct device *dev = ap->dev; |
5493 | int rc; | 5492 | int rc; |
5494 | 5493 | ||
5495 | ap->prd = dma_alloc_coherent(dev, ATA_PRD_TBL_SZ, &ap->prd_dma, GFP_KERNEL); | 5494 | ap->prd = dmam_alloc_coherent(dev, ATA_PRD_TBL_SZ, &ap->prd_dma, |
5495 | GFP_KERNEL); | ||
5496 | if (!ap->prd) | 5496 | if (!ap->prd) |
5497 | return -ENOMEM; | 5497 | return -ENOMEM; |
5498 | 5498 | ||
5499 | rc = ata_pad_alloc(ap, dev); | 5499 | rc = ata_pad_alloc(ap, dev); |
5500 | if (rc) { | 5500 | if (rc) |
5501 | dma_free_coherent(dev, ATA_PRD_TBL_SZ, ap->prd, ap->prd_dma); | ||
5502 | return rc; | 5501 | return rc; |
5503 | } | ||
5504 | |||
5505 | DPRINTK("prd alloc, virt %p, dma %llx\n", ap->prd, (unsigned long long) ap->prd_dma); | ||
5506 | 5502 | ||
5503 | DPRINTK("prd alloc, virt %p, dma %llx\n", ap->prd, | ||
5504 | (unsigned long long)ap->prd_dma); | ||
5507 | return 0; | 5505 | return 0; |
5508 | } | 5506 | } |
5509 | 5507 | ||
5510 | |||
5511 | /** | 5508 | /** |
5512 | * ata_port_stop - Undo ata_port_start() | 5509 | * ata_port_stop - Undo ata_port_start() |
5513 | * @ap: Port to shut down | 5510 | * @ap: Port to shut down |
@@ -5519,12 +5516,11 @@ int ata_port_start (struct ata_port *ap) | |||
5519 | * LOCKING: | 5516 | * LOCKING: |
5520 | * Inherited from caller. | 5517 | * Inherited from caller. |
5521 | */ | 5518 | */ |
5522 | |||
5523 | void ata_port_stop (struct ata_port *ap) | 5519 | void ata_port_stop (struct ata_port *ap) |
5524 | { | 5520 | { |
5525 | struct device *dev = ap->dev; | 5521 | struct device *dev = ap->dev; |
5526 | 5522 | ||
5527 | dma_free_coherent(dev, ATA_PRD_TBL_SZ, ap->prd, ap->prd_dma); | 5523 | dmam_free_coherent(dev, ATA_PRD_TBL_SZ, ap->prd, ap->prd_dma); |
5528 | ata_pad_free(ap, dev); | 5524 | ata_pad_free(ap, dev); |
5529 | } | 5525 | } |
5530 | 5526 | ||
@@ -5707,6 +5703,27 @@ static struct ata_port * ata_port_add(const struct ata_probe_ent *ent, | |||
5707 | return ap; | 5703 | return ap; |
5708 | } | 5704 | } |
5709 | 5705 | ||
5706 | static void ata_host_release(struct device *gendev, void *res) | ||
5707 | { | ||
5708 | struct ata_host *host = dev_get_drvdata(gendev); | ||
5709 | int i; | ||
5710 | |||
5711 | for (i = 0; i < host->n_ports; i++) { | ||
5712 | struct ata_port *ap = host->ports[i]; | ||
5713 | |||
5714 | if (!ap) | ||
5715 | continue; | ||
5716 | |||
5717 | if (ap->ops->port_stop) | ||
5718 | ap->ops->port_stop(ap); | ||
5719 | |||
5720 | scsi_host_put(ap->scsi_host); | ||
5721 | } | ||
5722 | |||
5723 | if (host->ops->host_stop) | ||
5724 | host->ops->host_stop(host); | ||
5725 | } | ||
5726 | |||
5710 | /** | 5727 | /** |
5711 | * ata_sas_host_init - Initialize a host struct | 5728 | * ata_sas_host_init - Initialize a host struct |
5712 | * @host: host to initialize | 5729 | * @host: host to initialize |
@@ -5759,11 +5776,17 @@ int ata_device_add(const struct ata_probe_ent *ent) | |||
5759 | dev_printk(KERN_ERR, dev, "is not available: No interrupt assigned.\n"); | 5776 | dev_printk(KERN_ERR, dev, "is not available: No interrupt assigned.\n"); |
5760 | return 0; | 5777 | return 0; |
5761 | } | 5778 | } |
5779 | |||
5780 | if (!devres_open_group(dev, ata_device_add, GFP_KERNEL)) | ||
5781 | return 0; | ||
5782 | |||
5762 | /* alloc a container for our list of ATA ports (buses) */ | 5783 | /* alloc a container for our list of ATA ports (buses) */ |
5763 | host = kzalloc(sizeof(struct ata_host) + | 5784 | host = devres_alloc(ata_host_release, sizeof(struct ata_host) + |
5764 | (ent->n_ports * sizeof(void *)), GFP_KERNEL); | 5785 | (ent->n_ports * sizeof(void *)), GFP_KERNEL); |
5765 | if (!host) | 5786 | if (!host) |
5766 | return 0; | 5787 | goto err_out; |
5788 | devres_add(dev, host); | ||
5789 | dev_set_drvdata(dev, host); | ||
5767 | 5790 | ||
5768 | ata_host_init(host, dev, ent->_host_flags, ent->port_ops); | 5791 | ata_host_init(host, dev, ent->_host_flags, ent->port_ops); |
5769 | host->n_ports = ent->n_ports; | 5792 | host->n_ports = ent->n_ports; |
@@ -5821,8 +5844,8 @@ int ata_device_add(const struct ata_probe_ent *ent) | |||
5821 | } | 5844 | } |
5822 | 5845 | ||
5823 | /* obtain irq, that may be shared between channels */ | 5846 | /* obtain irq, that may be shared between channels */ |
5824 | rc = request_irq(ent->irq, ent->port_ops->irq_handler, ent->irq_flags, | 5847 | rc = devm_request_irq(dev, ent->irq, ent->port_ops->irq_handler, |
5825 | DRV_NAME, host); | 5848 | ent->irq_flags, DRV_NAME, host); |
5826 | if (rc) { | 5849 | if (rc) { |
5827 | dev_printk(KERN_ERR, dev, "irq %lu request failed: %d\n", | 5850 | dev_printk(KERN_ERR, dev, "irq %lu request failed: %d\n", |
5828 | ent->irq, rc); | 5851 | ent->irq, rc); |
@@ -5835,15 +5858,19 @@ int ata_device_add(const struct ata_probe_ent *ent) | |||
5835 | so trap it now */ | 5858 | so trap it now */ |
5836 | BUG_ON(ent->irq == ent->irq2); | 5859 | BUG_ON(ent->irq == ent->irq2); |
5837 | 5860 | ||
5838 | rc = request_irq(ent->irq2, ent->port_ops->irq_handler, ent->irq_flags, | 5861 | rc = devm_request_irq(dev, ent->irq2, |
5839 | DRV_NAME, host); | 5862 | ent->port_ops->irq_handler, ent->irq_flags, |
5863 | DRV_NAME, host); | ||
5840 | if (rc) { | 5864 | if (rc) { |
5841 | dev_printk(KERN_ERR, dev, "irq %lu request failed: %d\n", | 5865 | dev_printk(KERN_ERR, dev, "irq %lu request failed: %d\n", |
5842 | ent->irq2, rc); | 5866 | ent->irq2, rc); |
5843 | goto err_out_free_irq; | 5867 | goto err_out; |
5844 | } | 5868 | } |
5845 | } | 5869 | } |
5846 | 5870 | ||
5871 | /* resource acquisition complete */ | ||
5872 | devres_close_group(dev, ata_device_add); | ||
5873 | |||
5847 | /* perform each probe synchronously */ | 5874 | /* perform each probe synchronously */ |
5848 | DPRINTK("probe begin\n"); | 5875 | DPRINTK("probe begin\n"); |
5849 | for (i = 0; i < host->n_ports; i++) { | 5876 | for (i = 0; i < host->n_ports; i++) { |
@@ -5912,24 +5939,13 @@ int ata_device_add(const struct ata_probe_ent *ent) | |||
5912 | ata_scsi_scan_host(ap); | 5939 | ata_scsi_scan_host(ap); |
5913 | } | 5940 | } |
5914 | 5941 | ||
5915 | dev_set_drvdata(dev, host); | ||
5916 | |||
5917 | VPRINTK("EXIT, returning %u\n", ent->n_ports); | 5942 | VPRINTK("EXIT, returning %u\n", ent->n_ports); |
5918 | return ent->n_ports; /* success */ | 5943 | return ent->n_ports; /* success */ |
5919 | 5944 | ||
5920 | err_out_free_irq: | 5945 | err_out: |
5921 | free_irq(ent->irq, host); | 5946 | devres_release_group(dev, ata_device_add); |
5922 | err_out: | 5947 | dev_set_drvdata(dev, NULL); |
5923 | for (i = 0; i < host->n_ports; i++) { | 5948 | VPRINTK("EXIT, returning %d\n", rc); |
5924 | struct ata_port *ap = host->ports[i]; | ||
5925 | if (ap) { | ||
5926 | ap->ops->port_stop(ap); | ||
5927 | scsi_host_put(ap->scsi_host); | ||
5928 | } | ||
5929 | } | ||
5930 | |||
5931 | kfree(host); | ||
5932 | VPRINTK("EXIT, returning 0\n"); | ||
5933 | return 0; | 5949 | return 0; |
5934 | } | 5950 | } |
5935 | 5951 | ||
@@ -6018,66 +6034,10 @@ void ata_host_detach(struct ata_host *host) | |||
6018 | * LOCKING: | 6034 | * LOCKING: |
6019 | * Inherited from calling layer (may sleep). | 6035 | * Inherited from calling layer (may sleep). |
6020 | */ | 6036 | */ |
6021 | |||
6022 | void ata_host_remove(struct ata_host *host) | 6037 | void ata_host_remove(struct ata_host *host) |
6023 | { | 6038 | { |
6024 | unsigned int i; | ||
6025 | |||
6026 | ata_host_detach(host); | 6039 | ata_host_detach(host); |
6027 | 6040 | devres_release_group(host->dev, ata_device_add); | |
6028 | free_irq(host->irq, host); | ||
6029 | if (host->irq2) | ||
6030 | free_irq(host->irq2, host); | ||
6031 | |||
6032 | for (i = 0; i < host->n_ports; i++) { | ||
6033 | struct ata_port *ap = host->ports[i]; | ||
6034 | |||
6035 | ata_scsi_release(ap->scsi_host); | ||
6036 | |||
6037 | if ((ap->flags & ATA_FLAG_NO_LEGACY) == 0) { | ||
6038 | struct ata_ioports *ioaddr = &ap->ioaddr; | ||
6039 | |||
6040 | /* FIXME: Add -ac IDE pci mods to remove these special cases */ | ||
6041 | if (ioaddr->cmd_addr == ATA_PRIMARY_CMD) | ||
6042 | release_region(ATA_PRIMARY_CMD, 8); | ||
6043 | else if (ioaddr->cmd_addr == ATA_SECONDARY_CMD) | ||
6044 | release_region(ATA_SECONDARY_CMD, 8); | ||
6045 | } | ||
6046 | |||
6047 | scsi_host_put(ap->scsi_host); | ||
6048 | } | ||
6049 | |||
6050 | if (host->ops->host_stop) | ||
6051 | host->ops->host_stop(host); | ||
6052 | |||
6053 | kfree(host); | ||
6054 | } | ||
6055 | |||
6056 | /** | ||
6057 | * ata_scsi_release - SCSI layer callback hook for host unload | ||
6058 | * @shost: libata host to be unloaded | ||
6059 | * | ||
6060 | * Performs all duties necessary to shut down a libata port... | ||
6061 | * Kill port kthread, disable port, and release resources. | ||
6062 | * | ||
6063 | * LOCKING: | ||
6064 | * Inherited from SCSI layer. | ||
6065 | * | ||
6066 | * RETURNS: | ||
6067 | * One. | ||
6068 | */ | ||
6069 | |||
6070 | int ata_scsi_release(struct Scsi_Host *shost) | ||
6071 | { | ||
6072 | struct ata_port *ap = ata_shost_to_port(shost); | ||
6073 | |||
6074 | DPRINTK("ENTER\n"); | ||
6075 | |||
6076 | ap->ops->port_disable(ap); | ||
6077 | ap->ops->port_stop(ap); | ||
6078 | |||
6079 | DPRINTK("EXIT\n"); | ||
6080 | return 1; | ||
6081 | } | 6041 | } |
6082 | 6042 | ||
6083 | struct ata_probe_ent * | 6043 | struct ata_probe_ent * |
@@ -6085,7 +6045,11 @@ ata_probe_ent_alloc(struct device *dev, const struct ata_port_info *port) | |||
6085 | { | 6045 | { |
6086 | struct ata_probe_ent *probe_ent; | 6046 | struct ata_probe_ent *probe_ent; |
6087 | 6047 | ||
6088 | probe_ent = kzalloc(sizeof(*probe_ent), GFP_KERNEL); | 6048 | /* XXX - the following if can go away once all LLDs are managed */ |
6049 | if (!list_empty(&dev->devres_head)) | ||
6050 | probe_ent = devm_kzalloc(dev, sizeof(*probe_ent), GFP_KERNEL); | ||
6051 | else | ||
6052 | probe_ent = kzalloc(sizeof(*probe_ent), GFP_KERNEL); | ||
6089 | if (!probe_ent) { | 6053 | if (!probe_ent) { |
6090 | printk(KERN_ERR DRV_NAME "(%s): out of memory\n", | 6054 | printk(KERN_ERR DRV_NAME "(%s): out of memory\n", |
6091 | kobject_name(&(dev->kobj))); | 6055 | kobject_name(&(dev->kobj))); |
@@ -6139,7 +6103,11 @@ void ata_pci_host_stop (struct ata_host *host) | |||
6139 | { | 6103 | { |
6140 | struct pci_dev *pdev = to_pci_dev(host->dev); | 6104 | struct pci_dev *pdev = to_pci_dev(host->dev); |
6141 | 6105 | ||
6142 | pci_iounmap(pdev, host->mmio_base); | 6106 | /* XXX - the following if can go away once all LLDs are managed */ |
6107 | if (!list_empty(&host->dev->devres_head)) | ||
6108 | pcim_iounmap(pdev, host->mmio_base); | ||
6109 | else | ||
6110 | pci_iounmap(pdev, host->mmio_base); | ||
6143 | } | 6111 | } |
6144 | 6112 | ||
6145 | /** | 6113 | /** |
@@ -6155,17 +6123,19 @@ void ata_pci_host_stop (struct ata_host *host) | |||
6155 | * LOCKING: | 6123 | * LOCKING: |
6156 | * Inherited from PCI layer (may sleep). | 6124 | * Inherited from PCI layer (may sleep). |
6157 | */ | 6125 | */ |
6158 | 6126 | void ata_pci_remove_one(struct pci_dev *pdev) | |
6159 | void ata_pci_remove_one (struct pci_dev *pdev) | ||
6160 | { | 6127 | { |
6161 | struct device *dev = pci_dev_to_dev(pdev); | 6128 | struct device *dev = pci_dev_to_dev(pdev); |
6162 | struct ata_host *host = dev_get_drvdata(dev); | 6129 | struct ata_host *host = dev_get_drvdata(dev); |
6163 | 6130 | ||
6164 | ata_host_remove(host); | 6131 | /* XXX - the following if can go away once all LLDs are managed */ |
6165 | 6132 | if (!list_empty(&host->dev->devres_head)) { | |
6166 | pci_release_regions(pdev); | 6133 | ata_host_remove(host); |
6167 | pci_disable_device(pdev); | 6134 | pci_release_regions(pdev); |
6168 | dev_set_drvdata(dev, NULL); | 6135 | pci_disable_device(pdev); |
6136 | dev_set_drvdata(dev, NULL); | ||
6137 | } else | ||
6138 | ata_host_detach(host); | ||
6169 | } | 6139 | } |
6170 | 6140 | ||
6171 | /* move to PCI subsystem */ | 6141 | /* move to PCI subsystem */ |
@@ -6219,7 +6189,11 @@ int ata_pci_device_do_resume(struct pci_dev *pdev) | |||
6219 | pci_set_power_state(pdev, PCI_D0); | 6189 | pci_set_power_state(pdev, PCI_D0); |
6220 | pci_restore_state(pdev); | 6190 | pci_restore_state(pdev); |
6221 | 6191 | ||
6222 | rc = pci_enable_device(pdev); | 6192 | /* XXX - the following if can go away once all LLDs are managed */ |
6193 | if (!list_empty(&pdev->dev.devres_head)) | ||
6194 | rc = pcim_enable_device(pdev); | ||
6195 | else | ||
6196 | rc = pci_enable_device(pdev); | ||
6223 | if (rc) { | 6197 | if (rc) { |
6224 | dev_printk(KERN_ERR, &pdev->dev, | 6198 | dev_printk(KERN_ERR, &pdev->dev, |
6225 | "failed to enable device after resume (%d)\n", rc); | 6199 | "failed to enable device after resume (%d)\n", rc); |
@@ -6458,7 +6432,6 @@ EXPORT_SYMBOL_GPL(ata_scsi_queuecmd); | |||
6458 | EXPORT_SYMBOL_GPL(ata_scsi_slave_config); | 6432 | EXPORT_SYMBOL_GPL(ata_scsi_slave_config); |
6459 | EXPORT_SYMBOL_GPL(ata_scsi_slave_destroy); | 6433 | EXPORT_SYMBOL_GPL(ata_scsi_slave_destroy); |
6460 | EXPORT_SYMBOL_GPL(ata_scsi_change_queue_depth); | 6434 | EXPORT_SYMBOL_GPL(ata_scsi_change_queue_depth); |
6461 | EXPORT_SYMBOL_GPL(ata_scsi_release); | ||
6462 | EXPORT_SYMBOL_GPL(ata_host_intr); | 6435 | EXPORT_SYMBOL_GPL(ata_host_intr); |
6463 | EXPORT_SYMBOL_GPL(sata_scr_valid); | 6436 | EXPORT_SYMBOL_GPL(sata_scr_valid); |
6464 | EXPORT_SYMBOL_GPL(sata_scr_read); | 6437 | EXPORT_SYMBOL_GPL(sata_scr_read); |
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index cc229e31432f..0009818a4306 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c | |||
@@ -3305,7 +3305,8 @@ EXPORT_SYMBOL_GPL(ata_sas_port_init); | |||
3305 | 3305 | ||
3306 | void ata_sas_port_destroy(struct ata_port *ap) | 3306 | void ata_sas_port_destroy(struct ata_port *ap) |
3307 | { | 3307 | { |
3308 | ap->ops->port_stop(ap); | 3308 | if (ap->ops->port_stop) |
3309 | ap->ops->port_stop(ap); | ||
3309 | kfree(ap); | 3310 | kfree(ap); |
3310 | } | 3311 | } |
3311 | EXPORT_SYMBOL_GPL(ata_sas_port_destroy); | 3312 | EXPORT_SYMBOL_GPL(ata_sas_port_destroy); |
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index 9bbc8749620a..21efe92a7135 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c | |||
@@ -1006,15 +1006,18 @@ static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev, | |||
1006 | int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info, | 1006 | int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info, |
1007 | unsigned int n_ports) | 1007 | unsigned int n_ports) |
1008 | { | 1008 | { |
1009 | struct device *dev = &pdev->dev; | ||
1009 | struct ata_probe_ent *probe_ent = NULL; | 1010 | struct ata_probe_ent *probe_ent = NULL; |
1010 | struct ata_port_info *port[2]; | 1011 | struct ata_port_info *port[2]; |
1011 | u8 mask; | 1012 | u8 mask; |
1012 | unsigned int legacy_mode = 0; | 1013 | unsigned int legacy_mode = 0; |
1013 | int disable_dev_on_err = 1; | ||
1014 | int rc; | 1014 | int rc; |
1015 | 1015 | ||
1016 | DPRINTK("ENTER\n"); | 1016 | DPRINTK("ENTER\n"); |
1017 | 1017 | ||
1018 | if (!devres_open_group(dev, NULL, GFP_KERNEL)) | ||
1019 | return -ENOMEM; | ||
1020 | |||
1018 | BUG_ON(n_ports < 1 || n_ports > 2); | 1021 | BUG_ON(n_ports < 1 || n_ports > 2); |
1019 | 1022 | ||
1020 | port[0] = port_info[0]; | 1023 | port[0] = port_info[0]; |
@@ -1031,9 +1034,9 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info, | |||
1031 | boot for the primary video which is BIOS enabled | 1034 | boot for the primary video which is BIOS enabled |
1032 | */ | 1035 | */ |
1033 | 1036 | ||
1034 | rc = pci_enable_device(pdev); | 1037 | rc = pcim_enable_device(pdev); |
1035 | if (rc) | 1038 | if (rc) |
1036 | return rc; | 1039 | goto err_out; |
1037 | 1040 | ||
1038 | if ((pdev->class >> 8) == PCI_CLASS_STORAGE_IDE) { | 1041 | if ((pdev->class >> 8) == PCI_CLASS_STORAGE_IDE) { |
1039 | u8 tmp8; | 1042 | u8 tmp8; |
@@ -1049,7 +1052,8 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info, | |||
1049 | left a device in compatibility mode */ | 1052 | left a device in compatibility mode */ |
1050 | if (legacy_mode) { | 1053 | if (legacy_mode) { |
1051 | printk(KERN_ERR "ata: Compatibility mode ATA is not supported on this platform, skipping.\n"); | 1054 | printk(KERN_ERR "ata: Compatibility mode ATA is not supported on this platform, skipping.\n"); |
1052 | return -EOPNOTSUPP; | 1055 | rc = -EOPNOTSUPP; |
1056 | goto err_out; | ||
1053 | } | 1057 | } |
1054 | #endif | 1058 | #endif |
1055 | } | 1059 | } |
@@ -1057,13 +1061,13 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info, | |||
1057 | if (!legacy_mode) { | 1061 | if (!legacy_mode) { |
1058 | rc = pci_request_regions(pdev, DRV_NAME); | 1062 | rc = pci_request_regions(pdev, DRV_NAME); |
1059 | if (rc) { | 1063 | if (rc) { |
1060 | disable_dev_on_err = 0; | 1064 | pcim_pin_device(pdev); |
1061 | goto err_out; | 1065 | goto err_out; |
1062 | } | 1066 | } |
1063 | } else { | 1067 | } else { |
1064 | /* Deal with combined mode hack. This side of the logic all | 1068 | /* Deal with combined mode hack. This side of the logic all |
1065 | goes away once the combined mode hack is killed in 2.6.21 */ | 1069 | goes away once the combined mode hack is killed in 2.6.21 */ |
1066 | if (!request_region(ATA_PRIMARY_CMD, 8, "libata")) { | 1070 | if (!devm_request_region(dev, ATA_PRIMARY_CMD, 8, "libata")) { |
1067 | struct resource *conflict, res; | 1071 | struct resource *conflict, res; |
1068 | res.start = ATA_PRIMARY_CMD; | 1072 | res.start = ATA_PRIMARY_CMD; |
1069 | res.end = ATA_PRIMARY_CMD + 8 - 1; | 1073 | res.end = ATA_PRIMARY_CMD + 8 - 1; |
@@ -1073,7 +1077,7 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info, | |||
1073 | if (!strcmp(conflict->name, "libata")) | 1077 | if (!strcmp(conflict->name, "libata")) |
1074 | legacy_mode |= ATA_PORT_PRIMARY; | 1078 | legacy_mode |= ATA_PORT_PRIMARY; |
1075 | else { | 1079 | else { |
1076 | disable_dev_on_err = 0; | 1080 | pcim_pin_device(pdev); |
1077 | printk(KERN_WARNING "ata: 0x%0X IDE port busy\n" \ | 1081 | printk(KERN_WARNING "ata: 0x%0X IDE port busy\n" \ |
1078 | "ata: conflict with %s\n", | 1082 | "ata: conflict with %s\n", |
1079 | ATA_PRIMARY_CMD, | 1083 | ATA_PRIMARY_CMD, |
@@ -1082,7 +1086,7 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info, | |||
1082 | } else | 1086 | } else |
1083 | legacy_mode |= ATA_PORT_PRIMARY; | 1087 | legacy_mode |= ATA_PORT_PRIMARY; |
1084 | 1088 | ||
1085 | if (!request_region(ATA_SECONDARY_CMD, 8, "libata")) { | 1089 | if (!devm_request_region(dev, ATA_SECONDARY_CMD, 8, "libata")) { |
1086 | struct resource *conflict, res; | 1090 | struct resource *conflict, res; |
1087 | res.start = ATA_SECONDARY_CMD; | 1091 | res.start = ATA_SECONDARY_CMD; |
1088 | res.end = ATA_SECONDARY_CMD + 8 - 1; | 1092 | res.end = ATA_SECONDARY_CMD + 8 - 1; |
@@ -1092,7 +1096,7 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info, | |||
1092 | if (!strcmp(conflict->name, "libata")) | 1096 | if (!strcmp(conflict->name, "libata")) |
1093 | legacy_mode |= ATA_PORT_SECONDARY; | 1097 | legacy_mode |= ATA_PORT_SECONDARY; |
1094 | else { | 1098 | else { |
1095 | disable_dev_on_err = 0; | 1099 | pcim_pin_device(pdev); |
1096 | printk(KERN_WARNING "ata: 0x%X IDE port busy\n" \ | 1100 | printk(KERN_WARNING "ata: 0x%X IDE port busy\n" \ |
1097 | "ata: conflict with %s\n", | 1101 | "ata: conflict with %s\n", |
1098 | ATA_SECONDARY_CMD, | 1102 | ATA_SECONDARY_CMD, |
@@ -1112,16 +1116,16 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info, | |||
1112 | /* we have legacy mode, but all ports are unavailable */ | 1116 | /* we have legacy mode, but all ports are unavailable */ |
1113 | if (legacy_mode == (1 << 3)) { | 1117 | if (legacy_mode == (1 << 3)) { |
1114 | rc = -EBUSY; | 1118 | rc = -EBUSY; |
1115 | goto err_out_regions; | 1119 | goto err_out; |
1116 | } | 1120 | } |
1117 | 1121 | ||
1118 | /* TODO: If we get no DMA mask we should fall back to PIO */ | 1122 | /* TODO: If we get no DMA mask we should fall back to PIO */ |
1119 | rc = pci_set_dma_mask(pdev, ATA_DMA_MASK); | 1123 | rc = pci_set_dma_mask(pdev, ATA_DMA_MASK); |
1120 | if (rc) | 1124 | if (rc) |
1121 | goto err_out_regions; | 1125 | goto err_out; |
1122 | rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK); | 1126 | rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK); |
1123 | if (rc) | 1127 | if (rc) |
1124 | goto err_out_regions; | 1128 | goto err_out; |
1125 | 1129 | ||
1126 | if (legacy_mode) { | 1130 | if (legacy_mode) { |
1127 | probe_ent = ata_pci_init_legacy_port(pdev, port, legacy_mode); | 1131 | probe_ent = ata_pci_init_legacy_port(pdev, port, legacy_mode); |
@@ -1133,40 +1137,22 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info, | |||
1133 | } | 1137 | } |
1134 | if (!probe_ent) { | 1138 | if (!probe_ent) { |
1135 | rc = -ENOMEM; | 1139 | rc = -ENOMEM; |
1136 | goto err_out_regions; | 1140 | goto err_out; |
1137 | } | 1141 | } |
1138 | 1142 | ||
1139 | pci_set_master(pdev); | 1143 | pci_set_master(pdev); |
1140 | 1144 | ||
1141 | if (!ata_device_add(probe_ent)) { | 1145 | if (!ata_device_add(probe_ent)) { |
1142 | rc = -ENODEV; | 1146 | rc = -ENODEV; |
1143 | goto err_out_ent; | 1147 | goto err_out; |
1144 | } | 1148 | } |
1145 | 1149 | ||
1146 | kfree(probe_ent); | 1150 | devm_kfree(dev, probe_ent); |
1147 | 1151 | devres_remove_group(dev, NULL); | |
1148 | return 0; | 1152 | return 0; |
1149 | 1153 | ||
1150 | err_out_ent: | ||
1151 | kfree(probe_ent); | ||
1152 | err_out_regions: | ||
1153 | /* All this conditional stuff is needed for the combined mode hack | ||
1154 | until 2.6.21 when it can go */ | ||
1155 | if (legacy_mode) { | ||
1156 | pci_release_region(pdev, 4); | ||
1157 | if (legacy_mode & ATA_PORT_PRIMARY) { | ||
1158 | release_region(ATA_PRIMARY_CMD, 8); | ||
1159 | pci_release_region(pdev, 1); | ||
1160 | } | ||
1161 | if (legacy_mode & ATA_PORT_SECONDARY) { | ||
1162 | release_region(ATA_SECONDARY_CMD, 8); | ||
1163 | pci_release_region(pdev, 3); | ||
1164 | } | ||
1165 | } else | ||
1166 | pci_release_regions(pdev); | ||
1167 | err_out: | 1154 | err_out: |
1168 | if (disable_dev_on_err) | 1155 | devres_release_group(dev, NULL); |
1169 | pci_disable_device(pdev); | ||
1170 | return rc; | 1156 | return rc; |
1171 | } | 1157 | } |
1172 | 1158 | ||