提交 f0d36efd 编写于 作者: T Tejun Heo 提交者: Jeff Garzik

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: NTejun Heo <htejun@gmail.com>
Signed-off-by: NJeff Garzik <jeff@garzik.org>
上级 0529c159
...@@ -1784,37 +1784,24 @@ static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -1784,37 +1784,24 @@ static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
return rc; return rc;
} }
static void ahci_remove_one (struct pci_dev *pdev) static void ahci_remove_one(struct pci_dev *pdev)
{ {
struct device *dev = pci_dev_to_dev(pdev); struct device *dev = pci_dev_to_dev(pdev);
struct ata_host *host = dev_get_drvdata(dev); struct ata_host *host = dev_get_drvdata(dev);
struct ahci_host_priv *hpriv = host->private_data; struct ahci_host_priv *hpriv = host->private_data;
unsigned int i;
int have_msi;
ata_host_detach(host); ata_host_remove(host);
have_msi = hpriv->flags & AHCI_FLAG_MSI;
free_irq(host->irq, host);
for (i = 0; i < host->n_ports; i++) {
struct ata_port *ap = host->ports[i];
ata_scsi_release(ap->scsi_host);
scsi_host_put(ap->scsi_host);
}
kfree(hpriv);
pci_iounmap(pdev, host->mmio_base); pci_iounmap(pdev, host->mmio_base);
kfree(host);
if (have_msi) if (hpriv->flags & AHCI_FLAG_MSI)
pci_disable_msi(pdev); pci_disable_msi(pdev);
else else
pci_intx(pdev, 0); pci_intx(pdev, 0);
pci_release_regions(pdev); pci_release_regions(pdev);
pci_disable_device(pdev); pci_disable_device(pdev);
dev_set_drvdata(dev, NULL); dev_set_drvdata(dev, NULL);
kfree(hpriv);
} }
static int __init ahci_init(void) static int __init ahci_init(void)
......
...@@ -5486,28 +5486,25 @@ void ata_host_resume(struct ata_host *host) ...@@ -5486,28 +5486,25 @@ void ata_host_resume(struct ata_host *host)
* LOCKING: * LOCKING:
* Inherited from caller. * Inherited from caller.
*/ */
int ata_port_start(struct ata_port *ap)
int ata_port_start (struct ata_port *ap)
{ {
struct device *dev = ap->dev; struct device *dev = ap->dev;
int rc; int rc;
ap->prd = dma_alloc_coherent(dev, ATA_PRD_TBL_SZ, &ap->prd_dma, GFP_KERNEL); ap->prd = dmam_alloc_coherent(dev, ATA_PRD_TBL_SZ, &ap->prd_dma,
GFP_KERNEL);
if (!ap->prd) if (!ap->prd)
return -ENOMEM; return -ENOMEM;
rc = ata_pad_alloc(ap, dev); rc = ata_pad_alloc(ap, dev);
if (rc) { if (rc)
dma_free_coherent(dev, ATA_PRD_TBL_SZ, ap->prd, ap->prd_dma);
return rc; return rc;
}
DPRINTK("prd alloc, virt %p, dma %llx\n", ap->prd, (unsigned long long) ap->prd_dma);
DPRINTK("prd alloc, virt %p, dma %llx\n", ap->prd,
(unsigned long long)ap->prd_dma);
return 0; return 0;
} }
/** /**
* ata_port_stop - Undo ata_port_start() * ata_port_stop - Undo ata_port_start()
* @ap: Port to shut down * @ap: Port to shut down
...@@ -5519,12 +5516,11 @@ int ata_port_start (struct ata_port *ap) ...@@ -5519,12 +5516,11 @@ int ata_port_start (struct ata_port *ap)
* LOCKING: * LOCKING:
* Inherited from caller. * Inherited from caller.
*/ */
void ata_port_stop (struct ata_port *ap) void ata_port_stop (struct ata_port *ap)
{ {
struct device *dev = ap->dev; struct device *dev = ap->dev;
dma_free_coherent(dev, ATA_PRD_TBL_SZ, ap->prd, ap->prd_dma); dmam_free_coherent(dev, ATA_PRD_TBL_SZ, ap->prd, ap->prd_dma);
ata_pad_free(ap, dev); ata_pad_free(ap, dev);
} }
...@@ -5707,6 +5703,27 @@ static struct ata_port * ata_port_add(const struct ata_probe_ent *ent, ...@@ -5707,6 +5703,27 @@ static struct ata_port * ata_port_add(const struct ata_probe_ent *ent,
return ap; return ap;
} }
static void ata_host_release(struct device *gendev, void *res)
{
struct ata_host *host = dev_get_drvdata(gendev);
int i;
for (i = 0; i < host->n_ports; i++) {
struct ata_port *ap = host->ports[i];
if (!ap)
continue;
if (ap->ops->port_stop)
ap->ops->port_stop(ap);
scsi_host_put(ap->scsi_host);
}
if (host->ops->host_stop)
host->ops->host_stop(host);
}
/** /**
* ata_sas_host_init - Initialize a host struct * ata_sas_host_init - Initialize a host struct
* @host: host to initialize * @host: host to initialize
...@@ -5759,11 +5776,17 @@ int ata_device_add(const struct ata_probe_ent *ent) ...@@ -5759,11 +5776,17 @@ int ata_device_add(const struct ata_probe_ent *ent)
dev_printk(KERN_ERR, dev, "is not available: No interrupt assigned.\n"); dev_printk(KERN_ERR, dev, "is not available: No interrupt assigned.\n");
return 0; return 0;
} }
if (!devres_open_group(dev, ata_device_add, GFP_KERNEL))
return 0;
/* alloc a container for our list of ATA ports (buses) */ /* alloc a container for our list of ATA ports (buses) */
host = kzalloc(sizeof(struct ata_host) + host = devres_alloc(ata_host_release, sizeof(struct ata_host) +
(ent->n_ports * sizeof(void *)), GFP_KERNEL); (ent->n_ports * sizeof(void *)), GFP_KERNEL);
if (!host) if (!host)
return 0; goto err_out;
devres_add(dev, host);
dev_set_drvdata(dev, host);
ata_host_init(host, dev, ent->_host_flags, ent->port_ops); ata_host_init(host, dev, ent->_host_flags, ent->port_ops);
host->n_ports = ent->n_ports; host->n_ports = ent->n_ports;
...@@ -5821,8 +5844,8 @@ int ata_device_add(const struct ata_probe_ent *ent) ...@@ -5821,8 +5844,8 @@ int ata_device_add(const struct ata_probe_ent *ent)
} }
/* obtain irq, that may be shared between channels */ /* obtain irq, that may be shared between channels */
rc = request_irq(ent->irq, ent->port_ops->irq_handler, ent->irq_flags, rc = devm_request_irq(dev, ent->irq, ent->port_ops->irq_handler,
DRV_NAME, host); ent->irq_flags, DRV_NAME, host);
if (rc) { if (rc) {
dev_printk(KERN_ERR, dev, "irq %lu request failed: %d\n", dev_printk(KERN_ERR, dev, "irq %lu request failed: %d\n",
ent->irq, rc); ent->irq, rc);
...@@ -5835,15 +5858,19 @@ int ata_device_add(const struct ata_probe_ent *ent) ...@@ -5835,15 +5858,19 @@ int ata_device_add(const struct ata_probe_ent *ent)
so trap it now */ so trap it now */
BUG_ON(ent->irq == ent->irq2); BUG_ON(ent->irq == ent->irq2);
rc = request_irq(ent->irq2, ent->port_ops->irq_handler, ent->irq_flags, rc = devm_request_irq(dev, ent->irq2,
DRV_NAME, host); ent->port_ops->irq_handler, ent->irq_flags,
DRV_NAME, host);
if (rc) { if (rc) {
dev_printk(KERN_ERR, dev, "irq %lu request failed: %d\n", dev_printk(KERN_ERR, dev, "irq %lu request failed: %d\n",
ent->irq2, rc); ent->irq2, rc);
goto err_out_free_irq; goto err_out;
} }
} }
/* resource acquisition complete */
devres_close_group(dev, ata_device_add);
/* perform each probe synchronously */ /* perform each probe synchronously */
DPRINTK("probe begin\n"); DPRINTK("probe begin\n");
for (i = 0; i < host->n_ports; i++) { for (i = 0; i < host->n_ports; i++) {
...@@ -5912,24 +5939,13 @@ int ata_device_add(const struct ata_probe_ent *ent) ...@@ -5912,24 +5939,13 @@ int ata_device_add(const struct ata_probe_ent *ent)
ata_scsi_scan_host(ap); ata_scsi_scan_host(ap);
} }
dev_set_drvdata(dev, host);
VPRINTK("EXIT, returning %u\n", ent->n_ports); VPRINTK("EXIT, returning %u\n", ent->n_ports);
return ent->n_ports; /* success */ return ent->n_ports; /* success */
err_out_free_irq: err_out:
free_irq(ent->irq, host); devres_release_group(dev, ata_device_add);
err_out: dev_set_drvdata(dev, NULL);
for (i = 0; i < host->n_ports; i++) { VPRINTK("EXIT, returning %d\n", rc);
struct ata_port *ap = host->ports[i];
if (ap) {
ap->ops->port_stop(ap);
scsi_host_put(ap->scsi_host);
}
}
kfree(host);
VPRINTK("EXIT, returning 0\n");
return 0; return 0;
} }
...@@ -6018,66 +6034,10 @@ void ata_host_detach(struct ata_host *host) ...@@ -6018,66 +6034,10 @@ void ata_host_detach(struct ata_host *host)
* LOCKING: * LOCKING:
* Inherited from calling layer (may sleep). * Inherited from calling layer (may sleep).
*/ */
void ata_host_remove(struct ata_host *host) void ata_host_remove(struct ata_host *host)
{ {
unsigned int i;
ata_host_detach(host); ata_host_detach(host);
devres_release_group(host->dev, ata_device_add);
free_irq(host->irq, host);
if (host->irq2)
free_irq(host->irq2, host);
for (i = 0; i < host->n_ports; i++) {
struct ata_port *ap = host->ports[i];
ata_scsi_release(ap->scsi_host);
if ((ap->flags & ATA_FLAG_NO_LEGACY) == 0) {
struct ata_ioports *ioaddr = &ap->ioaddr;
/* FIXME: Add -ac IDE pci mods to remove these special cases */
if (ioaddr->cmd_addr == ATA_PRIMARY_CMD)
release_region(ATA_PRIMARY_CMD, 8);
else if (ioaddr->cmd_addr == ATA_SECONDARY_CMD)
release_region(ATA_SECONDARY_CMD, 8);
}
scsi_host_put(ap->scsi_host);
}
if (host->ops->host_stop)
host->ops->host_stop(host);
kfree(host);
}
/**
* ata_scsi_release - SCSI layer callback hook for host unload
* @shost: libata host to be unloaded
*
* Performs all duties necessary to shut down a libata port...
* Kill port kthread, disable port, and release resources.
*
* LOCKING:
* Inherited from SCSI layer.
*
* RETURNS:
* One.
*/
int ata_scsi_release(struct Scsi_Host *shost)
{
struct ata_port *ap = ata_shost_to_port(shost);
DPRINTK("ENTER\n");
ap->ops->port_disable(ap);
ap->ops->port_stop(ap);
DPRINTK("EXIT\n");
return 1;
} }
struct ata_probe_ent * struct ata_probe_ent *
...@@ -6085,7 +6045,11 @@ ata_probe_ent_alloc(struct device *dev, const struct ata_port_info *port) ...@@ -6085,7 +6045,11 @@ ata_probe_ent_alloc(struct device *dev, const struct ata_port_info *port)
{ {
struct ata_probe_ent *probe_ent; struct ata_probe_ent *probe_ent;
probe_ent = kzalloc(sizeof(*probe_ent), GFP_KERNEL); /* XXX - the following if can go away once all LLDs are managed */
if (!list_empty(&dev->devres_head))
probe_ent = devm_kzalloc(dev, sizeof(*probe_ent), GFP_KERNEL);
else
probe_ent = kzalloc(sizeof(*probe_ent), GFP_KERNEL);
if (!probe_ent) { if (!probe_ent) {
printk(KERN_ERR DRV_NAME "(%s): out of memory\n", printk(KERN_ERR DRV_NAME "(%s): out of memory\n",
kobject_name(&(dev->kobj))); kobject_name(&(dev->kobj)));
...@@ -6139,7 +6103,11 @@ void ata_pci_host_stop (struct ata_host *host) ...@@ -6139,7 +6103,11 @@ void ata_pci_host_stop (struct ata_host *host)
{ {
struct pci_dev *pdev = to_pci_dev(host->dev); struct pci_dev *pdev = to_pci_dev(host->dev);
pci_iounmap(pdev, host->mmio_base); /* XXX - the following if can go away once all LLDs are managed */
if (!list_empty(&host->dev->devres_head))
pcim_iounmap(pdev, host->mmio_base);
else
pci_iounmap(pdev, host->mmio_base);
} }
/** /**
...@@ -6155,17 +6123,19 @@ void ata_pci_host_stop (struct ata_host *host) ...@@ -6155,17 +6123,19 @@ void ata_pci_host_stop (struct ata_host *host)
* LOCKING: * LOCKING:
* Inherited from PCI layer (may sleep). * Inherited from PCI layer (may sleep).
*/ */
void ata_pci_remove_one(struct pci_dev *pdev)
void ata_pci_remove_one (struct pci_dev *pdev)
{ {
struct device *dev = pci_dev_to_dev(pdev); struct device *dev = pci_dev_to_dev(pdev);
struct ata_host *host = dev_get_drvdata(dev); struct ata_host *host = dev_get_drvdata(dev);
ata_host_remove(host); /* XXX - the following if can go away once all LLDs are managed */
if (!list_empty(&host->dev->devres_head)) {
pci_release_regions(pdev); ata_host_remove(host);
pci_disable_device(pdev); pci_release_regions(pdev);
dev_set_drvdata(dev, NULL); pci_disable_device(pdev);
dev_set_drvdata(dev, NULL);
} else
ata_host_detach(host);
} }
/* move to PCI subsystem */ /* move to PCI subsystem */
...@@ -6219,7 +6189,11 @@ int ata_pci_device_do_resume(struct pci_dev *pdev) ...@@ -6219,7 +6189,11 @@ int ata_pci_device_do_resume(struct pci_dev *pdev)
pci_set_power_state(pdev, PCI_D0); pci_set_power_state(pdev, PCI_D0);
pci_restore_state(pdev); pci_restore_state(pdev);
rc = pci_enable_device(pdev); /* XXX - the following if can go away once all LLDs are managed */
if (!list_empty(&pdev->dev.devres_head))
rc = pcim_enable_device(pdev);
else
rc = pci_enable_device(pdev);
if (rc) { if (rc) {
dev_printk(KERN_ERR, &pdev->dev, dev_printk(KERN_ERR, &pdev->dev,
"failed to enable device after resume (%d)\n", rc); "failed to enable device after resume (%d)\n", rc);
...@@ -6458,7 +6432,6 @@ EXPORT_SYMBOL_GPL(ata_scsi_queuecmd); ...@@ -6458,7 +6432,6 @@ EXPORT_SYMBOL_GPL(ata_scsi_queuecmd);
EXPORT_SYMBOL_GPL(ata_scsi_slave_config); EXPORT_SYMBOL_GPL(ata_scsi_slave_config);
EXPORT_SYMBOL_GPL(ata_scsi_slave_destroy); EXPORT_SYMBOL_GPL(ata_scsi_slave_destroy);
EXPORT_SYMBOL_GPL(ata_scsi_change_queue_depth); EXPORT_SYMBOL_GPL(ata_scsi_change_queue_depth);
EXPORT_SYMBOL_GPL(ata_scsi_release);
EXPORT_SYMBOL_GPL(ata_host_intr); EXPORT_SYMBOL_GPL(ata_host_intr);
EXPORT_SYMBOL_GPL(sata_scr_valid); EXPORT_SYMBOL_GPL(sata_scr_valid);
EXPORT_SYMBOL_GPL(sata_scr_read); EXPORT_SYMBOL_GPL(sata_scr_read);
......
...@@ -3305,7 +3305,8 @@ EXPORT_SYMBOL_GPL(ata_sas_port_init); ...@@ -3305,7 +3305,8 @@ EXPORT_SYMBOL_GPL(ata_sas_port_init);
void ata_sas_port_destroy(struct ata_port *ap) void ata_sas_port_destroy(struct ata_port *ap)
{ {
ap->ops->port_stop(ap); if (ap->ops->port_stop)
ap->ops->port_stop(ap);
kfree(ap); kfree(ap);
} }
EXPORT_SYMBOL_GPL(ata_sas_port_destroy); EXPORT_SYMBOL_GPL(ata_sas_port_destroy);
......
...@@ -1006,15 +1006,18 @@ static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev, ...@@ -1006,15 +1006,18 @@ static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev,
int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info, int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
unsigned int n_ports) unsigned int n_ports)
{ {
struct device *dev = &pdev->dev;
struct ata_probe_ent *probe_ent = NULL; struct ata_probe_ent *probe_ent = NULL;
struct ata_port_info *port[2]; struct ata_port_info *port[2];
u8 mask; u8 mask;
unsigned int legacy_mode = 0; unsigned int legacy_mode = 0;
int disable_dev_on_err = 1;
int rc; int rc;
DPRINTK("ENTER\n"); DPRINTK("ENTER\n");
if (!devres_open_group(dev, NULL, GFP_KERNEL))
return -ENOMEM;
BUG_ON(n_ports < 1 || n_ports > 2); BUG_ON(n_ports < 1 || n_ports > 2);
port[0] = port_info[0]; 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,9 +1034,9 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
boot for the primary video which is BIOS enabled boot for the primary video which is BIOS enabled
*/ */
rc = pci_enable_device(pdev); rc = pcim_enable_device(pdev);
if (rc) if (rc)
return rc; goto err_out;
if ((pdev->class >> 8) == PCI_CLASS_STORAGE_IDE) { if ((pdev->class >> 8) == PCI_CLASS_STORAGE_IDE) {
u8 tmp8; u8 tmp8;
...@@ -1049,7 +1052,8 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info, ...@@ -1049,7 +1052,8 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
left a device in compatibility mode */ left a device in compatibility mode */
if (legacy_mode) { if (legacy_mode) {
printk(KERN_ERR "ata: Compatibility mode ATA is not supported on this platform, skipping.\n"); printk(KERN_ERR "ata: Compatibility mode ATA is not supported on this platform, skipping.\n");
return -EOPNOTSUPP; rc = -EOPNOTSUPP;
goto err_out;
} }
#endif #endif
} }
...@@ -1057,13 +1061,13 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info, ...@@ -1057,13 +1061,13 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
if (!legacy_mode) { if (!legacy_mode) {
rc = pci_request_regions(pdev, DRV_NAME); rc = pci_request_regions(pdev, DRV_NAME);
if (rc) { if (rc) {
disable_dev_on_err = 0; pcim_pin_device(pdev);
goto err_out; goto err_out;
} }
} else { } else {
/* Deal with combined mode hack. This side of the logic all /* Deal with combined mode hack. This side of the logic all
goes away once the combined mode hack is killed in 2.6.21 */ goes away once the combined mode hack is killed in 2.6.21 */
if (!request_region(ATA_PRIMARY_CMD, 8, "libata")) { if (!devm_request_region(dev, ATA_PRIMARY_CMD, 8, "libata")) {
struct resource *conflict, res; struct resource *conflict, res;
res.start = ATA_PRIMARY_CMD; res.start = ATA_PRIMARY_CMD;
res.end = ATA_PRIMARY_CMD + 8 - 1; 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,7 +1077,7 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
if (!strcmp(conflict->name, "libata")) if (!strcmp(conflict->name, "libata"))
legacy_mode |= ATA_PORT_PRIMARY; legacy_mode |= ATA_PORT_PRIMARY;
else { else {
disable_dev_on_err = 0; pcim_pin_device(pdev);
printk(KERN_WARNING "ata: 0x%0X IDE port busy\n" \ printk(KERN_WARNING "ata: 0x%0X IDE port busy\n" \
"ata: conflict with %s\n", "ata: conflict with %s\n",
ATA_PRIMARY_CMD, ATA_PRIMARY_CMD,
...@@ -1082,7 +1086,7 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info, ...@@ -1082,7 +1086,7 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
} else } else
legacy_mode |= ATA_PORT_PRIMARY; legacy_mode |= ATA_PORT_PRIMARY;
if (!request_region(ATA_SECONDARY_CMD, 8, "libata")) { if (!devm_request_region(dev, ATA_SECONDARY_CMD, 8, "libata")) {
struct resource *conflict, res; struct resource *conflict, res;
res.start = ATA_SECONDARY_CMD; res.start = ATA_SECONDARY_CMD;
res.end = ATA_SECONDARY_CMD + 8 - 1; 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,7 +1096,7 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
if (!strcmp(conflict->name, "libata")) if (!strcmp(conflict->name, "libata"))
legacy_mode |= ATA_PORT_SECONDARY; legacy_mode |= ATA_PORT_SECONDARY;
else { else {
disable_dev_on_err = 0; pcim_pin_device(pdev);
printk(KERN_WARNING "ata: 0x%X IDE port busy\n" \ printk(KERN_WARNING "ata: 0x%X IDE port busy\n" \
"ata: conflict with %s\n", "ata: conflict with %s\n",
ATA_SECONDARY_CMD, ATA_SECONDARY_CMD,
...@@ -1112,16 +1116,16 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info, ...@@ -1112,16 +1116,16 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
/* we have legacy mode, but all ports are unavailable */ /* we have legacy mode, but all ports are unavailable */
if (legacy_mode == (1 << 3)) { if (legacy_mode == (1 << 3)) {
rc = -EBUSY; rc = -EBUSY;
goto err_out_regions; goto err_out;
} }
/* TODO: If we get no DMA mask we should fall back to PIO */ /* TODO: If we get no DMA mask we should fall back to PIO */
rc = pci_set_dma_mask(pdev, ATA_DMA_MASK); rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
if (rc) if (rc)
goto err_out_regions; goto err_out;
rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK); rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
if (rc) if (rc)
goto err_out_regions; goto err_out;
if (legacy_mode) { if (legacy_mode) {
probe_ent = ata_pci_init_legacy_port(pdev, port, legacy_mode); 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,40 +1137,22 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
} }
if (!probe_ent) { if (!probe_ent) {
rc = -ENOMEM; rc = -ENOMEM;
goto err_out_regions; goto err_out;
} }
pci_set_master(pdev); pci_set_master(pdev);
if (!ata_device_add(probe_ent)) { if (!ata_device_add(probe_ent)) {
rc = -ENODEV; rc = -ENODEV;
goto err_out_ent; goto err_out;
} }
kfree(probe_ent); devm_kfree(dev, probe_ent);
devres_remove_group(dev, NULL);
return 0; return 0;
err_out_ent:
kfree(probe_ent);
err_out_regions:
/* All this conditional stuff is needed for the combined mode hack
until 2.6.21 when it can go */
if (legacy_mode) {
pci_release_region(pdev, 4);
if (legacy_mode & ATA_PORT_PRIMARY) {
release_region(ATA_PRIMARY_CMD, 8);
pci_release_region(pdev, 1);
}
if (legacy_mode & ATA_PORT_SECONDARY) {
release_region(ATA_SECONDARY_CMD, 8);
pci_release_region(pdev, 3);
}
} else
pci_release_regions(pdev);
err_out: err_out:
if (disable_dev_on_err) devres_release_group(dev, NULL);
pci_disable_device(pdev);
return rc; return rc;
} }
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/dma-mapping.h> #include <linux/dma-mapping.h>
#include <asm/scatterlist.h> #include <asm/scatterlist.h>
#include <asm/io.h> #include <linux/io.h>
#include <linux/ata.h> #include <linux/ata.h>
#include <linux/workqueue.h> #include <linux/workqueue.h>
#include <scsi/scsi_host.h> #include <scsi/scsi_host.h>
...@@ -726,7 +726,6 @@ extern void ata_host_remove(struct ata_host *host); ...@@ -726,7 +726,6 @@ extern void ata_host_remove(struct ata_host *host);
extern int ata_scsi_detect(struct scsi_host_template *sht); extern int ata_scsi_detect(struct scsi_host_template *sht);
extern int ata_scsi_ioctl(struct scsi_device *dev, int cmd, void __user *arg); extern int ata_scsi_ioctl(struct scsi_device *dev, int cmd, void __user *arg);
extern int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)); extern int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *));
extern int ata_scsi_release(struct Scsi_Host *host);
extern void ata_sas_port_destroy(struct ata_port *); extern void ata_sas_port_destroy(struct ata_port *);
extern struct ata_port *ata_sas_port_alloc(struct ata_host *, extern struct ata_port *ata_sas_port_alloc(struct ata_host *,
struct ata_port_info *, struct Scsi_Host *); struct ata_port_info *, struct Scsi_Host *);
...@@ -1227,14 +1226,14 @@ static inline unsigned int __ac_err_mask(u8 status) ...@@ -1227,14 +1226,14 @@ static inline unsigned int __ac_err_mask(u8 status)
static inline int ata_pad_alloc(struct ata_port *ap, struct device *dev) static inline int ata_pad_alloc(struct ata_port *ap, struct device *dev)
{ {
ap->pad_dma = 0; ap->pad_dma = 0;
ap->pad = dma_alloc_coherent(dev, ATA_DMA_PAD_BUF_SZ, ap->pad = dmam_alloc_coherent(dev, ATA_DMA_PAD_BUF_SZ,
&ap->pad_dma, GFP_KERNEL); &ap->pad_dma, GFP_KERNEL);
return (ap->pad == NULL) ? -ENOMEM : 0; return (ap->pad == NULL) ? -ENOMEM : 0;
} }
static inline void ata_pad_free(struct ata_port *ap, struct device *dev) static inline void ata_pad_free(struct ata_port *ap, struct device *dev)
{ {
dma_free_coherent(dev, ATA_DMA_PAD_BUF_SZ, ap->pad, ap->pad_dma); dmam_free_coherent(dev, ATA_DMA_PAD_BUF_SZ, ap->pad, ap->pad_dma);
} }
static inline struct ata_port *ata_shost_to_port(struct Scsi_Host *host) static inline struct ata_port *ata_shost_to_port(struct Scsi_Host *host)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册