aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2007-04-17 10:44:07 -0400
committerJeff Garzik <jeff@garzik.org>2007-04-28 14:16:03 -0400
commit21b0ad4fb8306ac2bf5a249ffc978b1b8924c7d0 (patch)
tree9f82cc6a4bca146ce1021f0825cc12f18f9063b9 /drivers
parentd491b27b1959565671e2c05dff09b5f535a854ce (diff)
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>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/ata/libata-core.c6
-rw-r--r--drivers/ata/libata-sff.c67
2 files changed, 71 insertions, 2 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 8d3ae66572e9..2a38aa2841fd 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -6623,6 +6623,10 @@ const struct ata_port_operations ata_dummy_port_ops = {
6623 .port_stop = ata_dummy_noret, 6623 .port_stop = ata_dummy_noret,
6624}; 6624};
6625 6625
6626const struct ata_port_info ata_dummy_port_info = {
6627 .port_ops = &ata_dummy_port_ops,
6628};
6629
6626/* 6630/*
6627 * libata is essentially a library of internal helper functions for 6631 * libata is essentially a library of internal helper functions for
6628 * low-level ATA host controller drivers. As such, the API/ABI is 6632 * low-level ATA host controller drivers. As such, the API/ABI is
@@ -6634,6 +6638,7 @@ EXPORT_SYMBOL_GPL(sata_deb_timing_normal);
6634EXPORT_SYMBOL_GPL(sata_deb_timing_hotplug); 6638EXPORT_SYMBOL_GPL(sata_deb_timing_hotplug);
6635EXPORT_SYMBOL_GPL(sata_deb_timing_long); 6639EXPORT_SYMBOL_GPL(sata_deb_timing_long);
6636EXPORT_SYMBOL_GPL(ata_dummy_port_ops); 6640EXPORT_SYMBOL_GPL(ata_dummy_port_ops);
6641EXPORT_SYMBOL_GPL(ata_dummy_port_info);
6637EXPORT_SYMBOL_GPL(ata_std_bios_param); 6642EXPORT_SYMBOL_GPL(ata_std_bios_param);
6638EXPORT_SYMBOL_GPL(ata_std_ports); 6643EXPORT_SYMBOL_GPL(ata_std_ports);
6639EXPORT_SYMBOL_GPL(ata_host_init); 6644EXPORT_SYMBOL_GPL(ata_host_init);
@@ -6727,6 +6732,7 @@ EXPORT_SYMBOL_GPL(ata_timing_merge);
6727EXPORT_SYMBOL_GPL(pci_test_config_bits); 6732EXPORT_SYMBOL_GPL(pci_test_config_bits);
6728EXPORT_SYMBOL_GPL(ata_pci_init_native_mode); 6733EXPORT_SYMBOL_GPL(ata_pci_init_native_mode);
6729EXPORT_SYMBOL_GPL(ata_pci_init_native_host); 6734EXPORT_SYMBOL_GPL(ata_pci_init_native_host);
6735EXPORT_SYMBOL_GPL(ata_pci_prepare_native_host);
6730EXPORT_SYMBOL_GPL(ata_pci_init_one); 6736EXPORT_SYMBOL_GPL(ata_pci_init_one);
6731EXPORT_SYMBOL_GPL(ata_pci_remove_one); 6737EXPORT_SYMBOL_GPL(ata_pci_remove_one);
6732#ifdef CONFIG_PM 6738#ifdef CONFIG_PM
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index d551fa1cb104..142120cab874 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -663,13 +663,12 @@ static int ata_pci_init_bmdma(struct ata_host *host)
663 663
664 for (i = 0; i < 2; i++) { 664 for (i = 0; i < 2; i++) {
665 struct ata_port *ap = host->ports[i]; 665 struct ata_port *ap = host->ports[i];
666 struct ata_ioports *ioaddr = &ap->ioaddr;
667 void __iomem *bmdma = host->iomap[4] + 8 * i; 666 void __iomem *bmdma = host->iomap[4] + 8 * i;
668 667
669 if (ata_port_is_dummy(ap)) 668 if (ata_port_is_dummy(ap))
670 continue; 669 continue;
671 670
672 ioaddr->bmdma_addr = bmdma; 671 ap->ioaddr.bmdma_addr = bmdma;
673 if ((!(ap->flags & ATA_FLAG_IGN_SIMPLEX)) && 672 if ((!(ap->flags & ATA_FLAG_IGN_SIMPLEX)) &&
674 (ioread8(bmdma + 2) & 0x80)) 673 (ioread8(bmdma + 2) & 0x80))
675 host->flags |= ATA_HOST_SIMPLEX; 674 host->flags |= ATA_HOST_SIMPLEX;
@@ -742,6 +741,70 @@ int ata_pci_init_native_host(struct ata_host *host, unsigned int port_mask)
742 return 0; 741 return 0;
743} 742}
744 743
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 */
760int 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
745struct ata_legacy_devres { 808struct ata_legacy_devres {
746 unsigned int mask; 809 unsigned int mask;
747 unsigned long cmd_port[2]; 810 unsigned long cmd_port[2];