aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/libata-core.c
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2007-01-20 02:00:28 -0500
committerJeff Garzik <jeff@garzik.org>2007-02-09 17:39:37 -0500
commitf0d36efdc624beb3d9e29b9ab9e9537bf0f25d5b (patch)
treeeac4efb465aa682d6eaac61f76b3174ffd9fd8cd /drivers/ata/libata-core.c
parent0529c159dbdd79794796c1b50b39442d72efbe97 (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/ata/libata-core.c')
-rw-r--r--drivers/ata/libata-core.c177
1 files changed, 75 insertions, 102 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index a927c4c8bef..20b2409a0d2 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 5489int ata_port_start(struct ata_port *ap)
5490int 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
5523void ata_port_stop (struct ata_port *ap) 5519void 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
5706static 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
5920err_out_free_irq: 5945 err_out:
5921 free_irq(ent->irq, host); 5946 devres_release_group(dev, ata_device_add);
5922err_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
6022void ata_host_remove(struct ata_host *host) 6037void 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
6070int 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
6083struct ata_probe_ent * 6043struct 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 6126void ata_pci_remove_one(struct pci_dev *pdev)
6159void 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);
6458EXPORT_SYMBOL_GPL(ata_scsi_slave_config); 6432EXPORT_SYMBOL_GPL(ata_scsi_slave_config);
6459EXPORT_SYMBOL_GPL(ata_scsi_slave_destroy); 6433EXPORT_SYMBOL_GPL(ata_scsi_slave_destroy);
6460EXPORT_SYMBOL_GPL(ata_scsi_change_queue_depth); 6434EXPORT_SYMBOL_GPL(ata_scsi_change_queue_depth);
6461EXPORT_SYMBOL_GPL(ata_scsi_release);
6462EXPORT_SYMBOL_GPL(ata_host_intr); 6435EXPORT_SYMBOL_GPL(ata_host_intr);
6463EXPORT_SYMBOL_GPL(sata_scr_valid); 6436EXPORT_SYMBOL_GPL(sata_scr_valid);
6464EXPORT_SYMBOL_GPL(sata_scr_read); 6437EXPORT_SYMBOL_GPL(sata_scr_read);