Skip to content

Commit 21b0ad4

Browse files
htejunJeff Garzik
authored andcommitted
libata: add init helpers including ata_pci_prepare_native_host()
These will be used to convert LLDs to new init model. * Add irq_handler field to port_info. In new init model, requesting IRQ is LLD's responsibility and libata doesn't need to know about irq_handler. Most LLDs can simply register their irq_handler but some need different irq_handler depending on specific chip. The added port_info->irq_handler field can be used by LLDs to select the matching IRQ handler in such cases. * Add ata_dummy_port_info. * Implement ata_pci_prepare_native_host(), a helper to alloc ATA host, acquire all resources and init the host in one go. Signed-off-by: Tejun Heo <htejun@gmail.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
1 parent d491b27 commit 21b0ad4

File tree

3 files changed

+76
-2
lines changed

3 files changed

+76
-2
lines changed

drivers/ata/libata-core.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6623,6 +6623,10 @@ const struct ata_port_operations ata_dummy_port_ops = {
66236623
.port_stop = ata_dummy_noret,
66246624
};
66256625

6626+
const struct ata_port_info ata_dummy_port_info = {
6627+
.port_ops = &ata_dummy_port_ops,
6628+
};
6629+
66266630
/*
66276631
* libata is essentially a library of internal helper functions for
66286632
* low-level ATA host controller drivers. As such, the API/ABI is
@@ -6634,6 +6638,7 @@ EXPORT_SYMBOL_GPL(sata_deb_timing_normal);
66346638
EXPORT_SYMBOL_GPL(sata_deb_timing_hotplug);
66356639
EXPORT_SYMBOL_GPL(sata_deb_timing_long);
66366640
EXPORT_SYMBOL_GPL(ata_dummy_port_ops);
6641+
EXPORT_SYMBOL_GPL(ata_dummy_port_info);
66376642
EXPORT_SYMBOL_GPL(ata_std_bios_param);
66386643
EXPORT_SYMBOL_GPL(ata_std_ports);
66396644
EXPORT_SYMBOL_GPL(ata_host_init);
@@ -6727,6 +6732,7 @@ EXPORT_SYMBOL_GPL(ata_timing_merge);
67276732
EXPORT_SYMBOL_GPL(pci_test_config_bits);
67286733
EXPORT_SYMBOL_GPL(ata_pci_init_native_mode);
67296734
EXPORT_SYMBOL_GPL(ata_pci_init_native_host);
6735+
EXPORT_SYMBOL_GPL(ata_pci_prepare_native_host);
67306736
EXPORT_SYMBOL_GPL(ata_pci_init_one);
67316737
EXPORT_SYMBOL_GPL(ata_pci_remove_one);
67326738
#ifdef CONFIG_PM

drivers/ata/libata-sff.c

Lines changed: 65 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -663,13 +663,12 @@ static int ata_pci_init_bmdma(struct ata_host *host)
663663

664664
for (i = 0; i < 2; i++) {
665665
struct ata_port *ap = host->ports[i];
666-
struct ata_ioports *ioaddr = &ap->ioaddr;
667666
void __iomem *bmdma = host->iomap[4] + 8 * i;
668667

669668
if (ata_port_is_dummy(ap))
670669
continue;
671670

672-
ioaddr->bmdma_addr = bmdma;
671+
ap->ioaddr.bmdma_addr = bmdma;
673672
if ((!(ap->flags & ATA_FLAG_IGN_SIMPLEX)) &&
674673
(ioread8(bmdma + 2) & 0x80))
675674
host->flags |= ATA_HOST_SIMPLEX;
@@ -742,6 +741,70 @@ int ata_pci_init_native_host(struct ata_host *host, unsigned int port_mask)
742741
return 0;
743742
}
744743

744+
/**
745+
* ata_pci_prepare_native_host - helper to prepare native PCI ATA host
746+
* @pdev: target PCI device
747+
* @ppi: array of port_info
748+
* @n_ports: number of ports to allocate
749+
* @r_host: out argument for the initialized ATA host
750+
*
751+
* Helper to allocate ATA host for @pdev, acquire all native PCI
752+
* resources and initialize it accordingly in one go.
753+
*
754+
* LOCKING:
755+
* Inherited from calling layer (may sleep).
756+
*
757+
* RETURNS:
758+
* 0 on success, -errno otherwise.
759+
*/
760+
int ata_pci_prepare_native_host(struct pci_dev *pdev,
761+
const struct ata_port_info * const * ppi,
762+
int n_ports, struct ata_host **r_host)
763+
{
764+
struct ata_host *host;
765+
unsigned int port_mask;
766+
int rc;
767+
768+
if (!devres_open_group(&pdev->dev, NULL, GFP_KERNEL))
769+
return -ENOMEM;
770+
771+
host = ata_host_alloc_pinfo(&pdev->dev, ppi, 2);
772+
if (!host) {
773+
dev_printk(KERN_ERR, &pdev->dev,
774+
"failed to allocate ATA host\n");
775+
rc = -ENOMEM;
776+
goto err_out;
777+
}
778+
779+
port_mask = ATA_PORT_PRIMARY;
780+
if (n_ports > 1)
781+
port_mask |= ATA_PORT_SECONDARY;
782+
783+
rc = ata_pci_init_native_host(host, port_mask);
784+
if (rc)
785+
goto err_out;
786+
787+
/* init DMA related stuff */
788+
rc = ata_pci_init_bmdma(host);
789+
if (rc)
790+
goto err_bmdma;
791+
792+
devres_remove_group(&pdev->dev, NULL);
793+
*r_host = host;
794+
return 0;
795+
796+
err_bmdma:
797+
/* This is necessary because PCI and iomap resources are
798+
* merged and releasing the top group won't release the
799+
* acquired resources if some of those have been acquired
800+
* before entering this function.
801+
*/
802+
pcim_iounmap_regions(pdev, 0xf);
803+
err_out:
804+
devres_release_group(&pdev->dev, NULL);
805+
return rc;
806+
}
807+
745808
struct ata_legacy_devres {
746809
unsigned int mask;
747810
unsigned long cmd_port[2];

include/linux/libata.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -668,6 +668,7 @@ struct ata_port_info {
668668
unsigned long mwdma_mask;
669669
unsigned long udma_mask;
670670
const struct ata_port_operations *port_ops;
671+
irq_handler_t irq_handler;
671672
void *private_data;
672673
};
673674

@@ -690,6 +691,7 @@ extern const unsigned long sata_deb_timing_hotplug[];
690691
extern const unsigned long sata_deb_timing_long[];
691692

692693
extern const struct ata_port_operations ata_dummy_port_ops;
694+
extern const struct ata_port_info ata_dummy_port_info;
693695

694696
static inline const unsigned long *
695697
sata_ehc_deb_timing(struct ata_eh_context *ehc)
@@ -894,6 +896,9 @@ extern struct ata_probe_ent *
894896
ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int portmask);
895897
extern int ata_pci_init_native_host(struct ata_host *host,
896898
unsigned int port_mask);
899+
extern int ata_pci_prepare_native_host(struct pci_dev *pdev,
900+
const struct ata_port_info * const * ppi,
901+
int n_ports, struct ata_host **r_host);
897902
extern int pci_test_config_bits(struct pci_dev *pdev, const struct pci_bits *bits);
898903
extern unsigned long ata_pci_default_filter(struct ata_device *, unsigned long);
899904
#endif /* CONFIG_PCI */

0 commit comments

Comments
 (0)