diff options
author | Tejun Heo <htejun@gmail.com> | 2007-04-17 10:44:07 -0400 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2007-04-28 14:16:03 -0400 |
commit | d491b27b1959565671e2c05dff09b5f535a854ce (patch) | |
tree | 207711a735f7460649f21bd9eedff04eb55afa11 /drivers/ata/libata-sff.c | |
parent | 0f834de3ea61aacacf1fac59ba9e82680f83c846 (diff) |
libata: convert native PCI host handling to new init model
Convert native PCI host handling to alloc-init-register model. New
function ata_pci_init_native_host() follows the new init model and
replaces ata_pci_init_native_mode(). As there are remaining LLD
users, the old function isn't removed yet.
ata_pci_init_one() is reimplemented using the new function and now
fully converted to new init model.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/ata/libata-sff.c')
-rw-r--r-- | drivers/ata/libata-sff.c | 151 |
1 files changed, 101 insertions, 50 deletions
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index d48e1544a0bb..d551fa1cb104 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c | |||
@@ -678,6 +678,70 @@ static int ata_pci_init_bmdma(struct ata_host *host) | |||
678 | return 0; | 678 | return 0; |
679 | } | 679 | } |
680 | 680 | ||
681 | /** | ||
682 | * ata_pci_init_native_host - acquire native ATA resources and init host | ||
683 | * @host: target ATA host | ||
684 | * @port_mask: ports to consider | ||
685 | * | ||
686 | * Acquire native PCI ATA resources for @host and initialize | ||
687 | * @host accordoingly. | ||
688 | * | ||
689 | * LOCKING: | ||
690 | * Inherited from calling layer (may sleep). | ||
691 | * | ||
692 | * RETURNS: | ||
693 | * 0 on success, -errno otherwise. | ||
694 | */ | ||
695 | int ata_pci_init_native_host(struct ata_host *host, unsigned int port_mask) | ||
696 | { | ||
697 | struct device *gdev = host->dev; | ||
698 | struct pci_dev *pdev = to_pci_dev(gdev); | ||
699 | int i, rc; | ||
700 | |||
701 | /* Discard disabled ports. Some controllers show their unused | ||
702 | * channels this way. Disabled ports are made dummy. | ||
703 | */ | ||
704 | for (i = 0; i < 2; i++) { | ||
705 | if ((port_mask & (1 << i)) && !ata_resources_present(pdev, i)) { | ||
706 | host->ports[i]->ops = &ata_dummy_port_ops; | ||
707 | port_mask &= ~(1 << i); | ||
708 | } | ||
709 | } | ||
710 | |||
711 | if (!port_mask) { | ||
712 | dev_printk(KERN_ERR, gdev, "no available port\n"); | ||
713 | return -ENODEV; | ||
714 | } | ||
715 | |||
716 | /* request, iomap BARs and init port addresses accordingly */ | ||
717 | for (i = 0; i < 2; i++) { | ||
718 | struct ata_port *ap = host->ports[i]; | ||
719 | int base = i * 2; | ||
720 | void __iomem * const *iomap; | ||
721 | |||
722 | if (!(port_mask & (1 << i))) | ||
723 | continue; | ||
724 | |||
725 | rc = pcim_iomap_regions(pdev, 0x3 << base, DRV_NAME); | ||
726 | if (rc) { | ||
727 | dev_printk(KERN_ERR, gdev, "failed to request/iomap " | ||
728 | "BARs for port %d (errno=%d)\n", i, rc); | ||
729 | if (rc == -EBUSY) | ||
730 | pcim_pin_device(pdev); | ||
731 | return rc; | ||
732 | } | ||
733 | host->iomap = iomap = pcim_iomap_table(pdev); | ||
734 | |||
735 | ap->ioaddr.cmd_addr = iomap[base]; | ||
736 | ap->ioaddr.altstatus_addr = | ||
737 | ap->ioaddr.ctl_addr = (void __iomem *) | ||
738 | ((unsigned long)iomap[base + 1] | ATA_PCI_CTL_OFS); | ||
739 | ata_std_ports(&ap->ioaddr); | ||
740 | } | ||
741 | |||
742 | return 0; | ||
743 | } | ||
744 | |||
681 | struct ata_legacy_devres { | 745 | struct ata_legacy_devres { |
682 | unsigned int mask; | 746 | unsigned int mask; |
683 | unsigned long cmd_port[2]; | 747 | unsigned long cmd_port[2]; |
@@ -917,7 +981,6 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info, | |||
917 | unsigned int n_ports) | 981 | unsigned int n_ports) |
918 | { | 982 | { |
919 | struct device *dev = &pdev->dev; | 983 | struct device *dev = &pdev->dev; |
920 | struct ata_probe_ent *probe_ent = NULL; | ||
921 | struct ata_host *host = NULL; | 984 | struct ata_host *host = NULL; |
922 | const struct ata_port_info *port[2]; | 985 | const struct ata_port_info *port[2]; |
923 | u8 mask; | 986 | u8 mask; |
@@ -943,7 +1006,7 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info, | |||
943 | 1006 | ||
944 | Checking dev->is_enabled is insufficient as this is not set at | 1007 | Checking dev->is_enabled is insufficient as this is not set at |
945 | boot for the primary video which is BIOS enabled | 1008 | boot for the primary video which is BIOS enabled |
946 | */ | 1009 | */ |
947 | 1010 | ||
948 | rc = pcim_enable_device(pdev); | 1011 | rc = pcim_enable_device(pdev); |
949 | if (rc) | 1012 | if (rc) |
@@ -969,30 +1032,28 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info, | |||
969 | #endif | 1032 | #endif |
970 | } | 1033 | } |
971 | 1034 | ||
1035 | /* alloc and init host */ | ||
1036 | host = ata_host_alloc_pinfo(dev, port, 2); | ||
1037 | if (!host) { | ||
1038 | dev_printk(KERN_ERR, &pdev->dev, | ||
1039 | "failed to allocate ATA host\n"); | ||
1040 | rc = -ENOMEM; | ||
1041 | goto err_out; | ||
1042 | } | ||
1043 | |||
972 | if (!legacy_mode) { | 1044 | if (!legacy_mode) { |
973 | rc = pci_request_regions(pdev, DRV_NAME); | 1045 | unsigned int port_mask; |
974 | if (rc) { | ||
975 | pcim_pin_device(pdev); | ||
976 | goto err_out; | ||
977 | } | ||
978 | 1046 | ||
979 | /* TODO: If we get no DMA mask we should fall back to PIO */ | 1047 | port_mask = ATA_PORT_PRIMARY; |
980 | rc = pci_set_dma_mask(pdev, ATA_DMA_MASK); | 1048 | if (n_ports > 1) |
981 | if (rc) | 1049 | port_mask |= ATA_PORT_SECONDARY; |
982 | goto err_out; | 1050 | |
983 | rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK); | 1051 | rc = ata_pci_init_native_host(host, port_mask); |
984 | if (rc) | 1052 | if (rc) |
985 | goto err_out; | 1053 | goto err_out; |
986 | |||
987 | pci_set_master(pdev); | ||
988 | } else { | 1054 | } else { |
989 | int was_busy = 0; | 1055 | int was_busy = 0; |
990 | 1056 | ||
991 | rc = -ENOMEM; | ||
992 | host = ata_host_alloc_pinfo(dev, port, 2); | ||
993 | if (!host) | ||
994 | goto err_out; | ||
995 | |||
996 | rc = ata_init_legacy_host(host, &legacy_mode, &was_busy); | 1057 | rc = ata_init_legacy_host(host, &legacy_mode, &was_busy); |
997 | if (was_busy) | 1058 | if (was_busy) |
998 | pcim_pin_device(pdev); | 1059 | pcim_pin_device(pdev); |
@@ -1002,47 +1063,37 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info, | |||
1002 | /* request respective PCI regions, may fail */ | 1063 | /* request respective PCI regions, may fail */ |
1003 | rc = pci_request_region(pdev, 1, DRV_NAME); | 1064 | rc = pci_request_region(pdev, 1, DRV_NAME); |
1004 | rc = pci_request_region(pdev, 3, DRV_NAME); | 1065 | rc = pci_request_region(pdev, 3, DRV_NAME); |
1005 | |||
1006 | /* init bmdma */ | ||
1007 | ata_pci_init_bmdma(host); | ||
1008 | pci_set_master(pdev); | ||
1009 | } | 1066 | } |
1010 | 1067 | ||
1011 | if (legacy_mode) { | 1068 | /* init BMDMA, may fail */ |
1069 | ata_pci_init_bmdma(host); | ||
1070 | pci_set_master(pdev); | ||
1071 | |||
1072 | /* start host and request IRQ */ | ||
1073 | rc = ata_host_start(host); | ||
1074 | if (rc) | ||
1075 | goto err_out; | ||
1076 | |||
1077 | if (!legacy_mode) | ||
1078 | rc = devm_request_irq(dev, pdev->irq, | ||
1079 | port_info[0]->port_ops->irq_handler, | ||
1080 | IRQF_SHARED, DRV_NAME, host); | ||
1081 | else { | ||
1012 | irq_handler_t handler[2] = { host->ops->irq_handler, | 1082 | irq_handler_t handler[2] = { host->ops->irq_handler, |
1013 | host->ops->irq_handler }; | 1083 | host->ops->irq_handler }; |
1014 | unsigned int irq_flags[2] = { IRQF_SHARED, IRQF_SHARED }; | 1084 | unsigned int irq_flags[2] = { IRQF_SHARED, IRQF_SHARED }; |
1015 | void *dev_id[2] = { host, host }; | 1085 | void *dev_id[2] = { host, host }; |
1016 | 1086 | ||
1017 | rc = ata_host_start(host); | ||
1018 | if (rc) | ||
1019 | goto err_out; | ||
1020 | |||
1021 | rc = ata_request_legacy_irqs(host, handler, irq_flags, dev_id); | 1087 | rc = ata_request_legacy_irqs(host, handler, irq_flags, dev_id); |
1022 | if (rc) | 1088 | } |
1023 | goto err_out; | 1089 | if (rc) |
1024 | 1090 | goto err_out; | |
1025 | rc = ata_host_register(host, port_info[0]->sht); | ||
1026 | if (rc) | ||
1027 | goto err_out; | ||
1028 | } else { | ||
1029 | if (n_ports == 2) | ||
1030 | probe_ent = ata_pci_init_native_mode(pdev, (struct ata_port_info **)port, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY); | ||
1031 | else | ||
1032 | probe_ent = ata_pci_init_native_mode(pdev, (struct ata_port_info **)port, ATA_PORT_PRIMARY); | ||
1033 | |||
1034 | if (!probe_ent) { | ||
1035 | rc = -ENOMEM; | ||
1036 | goto err_out; | ||
1037 | } | ||
1038 | 1091 | ||
1039 | if (!ata_device_add(probe_ent)) { | 1092 | /* register */ |
1040 | rc = -ENODEV; | 1093 | rc = ata_host_register(host, port_info[0]->sht); |
1041 | goto err_out; | 1094 | if (rc) |
1042 | } | 1095 | goto err_out; |
1043 | 1096 | ||
1044 | devm_kfree(dev, probe_ent); | ||
1045 | } | ||
1046 | devres_remove_group(dev, NULL); | 1097 | devres_remove_group(dev, NULL); |
1047 | return 0; | 1098 | return 0; |
1048 | 1099 | ||