diff options
Diffstat (limited to 'drivers/ata/libata-core.c')
-rw-r--r-- | drivers/ata/libata-core.c | 177 |
1 files changed, 75 insertions, 102 deletions
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); |