aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libata-bmdma.c
diff options
context:
space:
mode:
authorAlan Cox <alan@lxorguk.ukuu.org.uk>2006-08-10 03:59:10 -0400
committerTejun Heo <htejun@gmail.com>2006-08-10 03:59:10 -0400
commit2ec7df0457b710d9201f211dbccdbecf0ad38b7e (patch)
tree4fbffc3e05aa65fd9ed63b4ac809712719e19cda /drivers/scsi/libata-bmdma.c
parent37deecb5139ee431233781a9a093d9fcaab54c5b (diff)
[PATCH] libata: rework legacy handling to remove much of the cruft
Kill host_set->next Fix simplex support Allow per platform setting of IDE legacy bases Some of this can be tidied further later on, in particular all the legacy port gunge belongs as a PCI quirk/PCI header decode to understand the special legacy IDE rules in the PCI spec. Longer term Jeff also wants to move the request_irq/free_irq out of core which will make this even cleaner. tj: folded in three followup patches - ata_piix-fix, broken-arch-fix and fix-new-legacy-handling, and separated per-dev xfermask into separate patch preceding this one. Folded in fixes are... * ata_piix-fix: fix build failure due to host_set->next removal * broken-arch-fix: add missing include/asm-*/libata-portmap.h * fix-new-legacy-handling: * In ata_pci_init_legacy_port(), probe_num was incorrectly incremented during initialization of the secondary port and probe_ent->n_ports was incorrectly fixed to 1. * Both legacy ports ended up having the same hard_port_no. * When printing port information, both legacy ports printed the first irq. Signed-off-by: Alan Cox <alan@redhat.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Tejun Heo <htejun@gmail.com>
Diffstat (limited to 'drivers/scsi/libata-bmdma.c')
-rw-r--r--drivers/scsi/libata-bmdma.c135
1 files changed, 64 insertions, 71 deletions
diff --git a/drivers/scsi/libata-bmdma.c b/drivers/scsi/libata-bmdma.c
index 3268cf5375ea..e694f6075c3b 100644
--- a/drivers/scsi/libata-bmdma.c
+++ b/drivers/scsi/libata-bmdma.c
@@ -854,7 +854,7 @@ ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int
854 if (bmdma) { 854 if (bmdma) {
855 bmdma += 8; 855 bmdma += 8;
856 if(inb(bmdma + 2) & 0x80) 856 if(inb(bmdma + 2) & 0x80)
857 probe_ent->host_set_flags |= ATA_HOST_SIMPLEX; 857 probe_ent->host_set_flags |= ATA_HOST_SIMPLEX;
858 probe_ent->port[p].bmdma_addr = bmdma; 858 probe_ent->port[p].bmdma_addr = bmdma;
859 } 859 }
860 ata_std_ports(&probe_ent->port[p]); 860 ata_std_ports(&probe_ent->port[p]);
@@ -867,44 +867,55 @@ ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int
867 867
868 868
869static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev, 869static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev,
870 struct ata_port_info *port, int port_num) 870 struct ata_port_info **port, int port_mask)
871{ 871{
872 struct ata_probe_ent *probe_ent; 872 struct ata_probe_ent *probe_ent;
873 unsigned long bmdma; 873 unsigned long bmdma = pci_resource_start(pdev, 4);
874 874
875 probe_ent = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port); 875 int port_num = 0;
876
877 probe_ent = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[0]);
876 if (!probe_ent) 878 if (!probe_ent)
877 return NULL; 879 return NULL;
878 880
879 probe_ent->legacy_mode = 1; 881 probe_ent->legacy_mode = 1;
880 probe_ent->n_ports = 1; 882 probe_ent->hard_port_no = 0;
881 probe_ent->hard_port_no = port_num; 883 probe_ent->private_data = port[0]->private_data;
882 probe_ent->private_data = port->private_data; 884
883 885 if (port_mask & ATA_PORT_PRIMARY) {
884 switch(port_num) 886 probe_ent->irq = 14;
885 { 887 probe_ent->port[port_num].cmd_addr = ATA_PRIMARY_CMD;
886 case 0: 888 probe_ent->port[port_num].altstatus_addr =
887 probe_ent->irq = 14; 889 probe_ent->port[port_num].ctl_addr = ATA_PRIMARY_CTL;
888 probe_ent->port[0].cmd_addr = 0x1f0; 890 if (bmdma) {
889 probe_ent->port[0].altstatus_addr = 891 probe_ent->port[0].bmdma_addr = bmdma;
890 probe_ent->port[0].ctl_addr = 0x3f6; 892 if (inb(bmdma + 2) & 0x80)
891 break; 893 probe_ent->host_set_flags |= ATA_HOST_SIMPLEX;
892 case 1: 894 }
895 ata_std_ports(&probe_ent->port[port_num]);
896 port_num ++;
897 }
898 if (port_mask & ATA_PORT_SECONDARY) {
899 if (port_num == 1)
900 probe_ent->irq2 = 15;
901 else {
902 /* Secondary only. IRQ 15 only and "first" port is port 1 */
893 probe_ent->irq = 15; 903 probe_ent->irq = 15;
894 probe_ent->port[0].cmd_addr = 0x170; 904 probe_ent->hard_port_no = 1;
895 probe_ent->port[0].altstatus_addr = 905 }
896 probe_ent->port[0].ctl_addr = 0x376; 906 probe_ent->port[port_num].cmd_addr = ATA_SECONDARY_CMD;
897 break; 907 probe_ent->port[port_num].altstatus_addr =
908 probe_ent->port[port_num].ctl_addr = ATA_SECONDARY_CTL;
909 if (bmdma) {
910 probe_ent->port[port_num].bmdma_addr = bmdma + 8;
911 if (inb(bmdma + 10) & 0x80)
912 probe_ent->host_set_flags |= ATA_HOST_SIMPLEX;
913 }
914 ata_std_ports(&probe_ent->port[port_num]);
915 port_num ++;
898 } 916 }
899 917
900 bmdma = pci_resource_start(pdev, 4); 918 probe_ent->n_ports = port_num;
901 if (bmdma != 0) {
902 bmdma += 8 * port_num;
903 probe_ent->port[0].bmdma_addr = bmdma;
904 if (inb(bmdma + 2) & 0x80)
905 probe_ent->host_set_flags |= ATA_HOST_SIMPLEX;
906 }
907 ata_std_ports(&probe_ent->port[0]);
908 919
909 return probe_ent; 920 return probe_ent;
910} 921}
@@ -924,6 +935,10 @@ static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev,
924 * regions, sets the dma mask, enables bus master mode, and calls 935 * regions, sets the dma mask, enables bus master mode, and calls
925 * ata_device_add() 936 * ata_device_add()
926 * 937 *
938 * ASSUMPTION:
939 * Nobody makes a single channel controller that appears solely as
940 * the secondary legacy port on PCI.
941 *
927 * LOCKING: 942 * LOCKING:
928 * Inherited from PCI layer (may sleep). 943 * Inherited from PCI layer (may sleep).
929 * 944 *
@@ -934,7 +949,7 @@ static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev,
934int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info, 949int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
935 unsigned int n_ports) 950 unsigned int n_ports)
936{ 951{
937 struct ata_probe_ent *probe_ent = NULL, *probe_ent2 = NULL; 952 struct ata_probe_ent *probe_ent = NULL;
938 struct ata_port_info *port[2]; 953 struct ata_port_info *port[2];
939 u8 tmp8, mask; 954 u8 tmp8, mask;
940 unsigned int legacy_mode = 0; 955 unsigned int legacy_mode = 0;
@@ -983,35 +998,34 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
983 goto err_out; 998 goto err_out;
984 } 999 }
985 1000
986 /* FIXME: Should use platform specific mappers for legacy port ranges */
987 if (legacy_mode) { 1001 if (legacy_mode) {
988 if (!request_region(0x1f0, 8, "libata")) { 1002 if (!request_region(ATA_PRIMARY_CMD, 8, "libata")) {
989 struct resource *conflict, res; 1003 struct resource *conflict, res;
990 res.start = 0x1f0; 1004 res.start = ATA_PRIMARY_CMD;
991 res.end = 0x1f0 + 8 - 1; 1005 res.end = ATA_PRIMARY_CMD + 8 - 1;
992 conflict = ____request_resource(&ioport_resource, &res); 1006 conflict = ____request_resource(&ioport_resource, &res);
993 if (!strcmp(conflict->name, "libata")) 1007 if (!strcmp(conflict->name, "libata"))
994 legacy_mode |= (1 << 0); 1008 legacy_mode |= ATA_PORT_PRIMARY;
995 else { 1009 else {
996 disable_dev_on_err = 0; 1010 disable_dev_on_err = 0;
997 printk(KERN_WARNING "ata: 0x1f0 IDE port busy\n"); 1011 printk(KERN_WARNING "ata: 0x%0X IDE port busy\n", ATA_PRIMARY_CMD);
998 } 1012 }
999 } else 1013 } else
1000 legacy_mode |= (1 << 0); 1014 legacy_mode |= ATA_PORT_PRIMARY;
1001 1015
1002 if (!request_region(0x170, 8, "libata")) { 1016 if (!request_region(ATA_SECONDARY_CMD, 8, "libata")) {
1003 struct resource *conflict, res; 1017 struct resource *conflict, res;
1004 res.start = 0x170; 1018 res.start = ATA_SECONDARY_CMD;
1005 res.end = 0x170 + 8 - 1; 1019 res.end = ATA_SECONDARY_CMD + 8 - 1;
1006 conflict = ____request_resource(&ioport_resource, &res); 1020 conflict = ____request_resource(&ioport_resource, &res);
1007 if (!strcmp(conflict->name, "libata")) 1021 if (!strcmp(conflict->name, "libata"))
1008 legacy_mode |= (1 << 1); 1022 legacy_mode |= ATA_PORT_SECONDARY;
1009 else { 1023 else {
1010 disable_dev_on_err = 0; 1024 disable_dev_on_err = 0;
1011 printk(KERN_WARNING "ata: 0x170 IDE port busy\n"); 1025 printk(KERN_WARNING "ata: 0x%X IDE port busy\n", ATA_SECONDARY_CMD);
1012 } 1026 }
1013 } else 1027 } else
1014 legacy_mode |= (1 << 1); 1028 legacy_mode |= ATA_PORT_SECONDARY;
1015 } 1029 }
1016 1030
1017 /* we have legacy mode, but all ports are unavailable */ 1031 /* we have legacy mode, but all ports are unavailable */
@@ -1029,17 +1043,14 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
1029 goto err_out_regions; 1043 goto err_out_regions;
1030 1044
1031 if (legacy_mode) { 1045 if (legacy_mode) {
1032 if (legacy_mode & (1 << 0)) 1046 probe_ent = ata_pci_init_legacy_port(pdev, port, legacy_mode);
1033 probe_ent = ata_pci_init_legacy_port(pdev, port[0], 0);
1034 if (legacy_mode & (1 << 1))
1035 probe_ent2 = ata_pci_init_legacy_port(pdev, port[1], 1);
1036 } else { 1047 } else {
1037 if (n_ports == 2) 1048 if (n_ports == 2)
1038 probe_ent = ata_pci_init_native_mode(pdev, port, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY); 1049 probe_ent = ata_pci_init_native_mode(pdev, port, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY);
1039 else 1050 else
1040 probe_ent = ata_pci_init_native_mode(pdev, port, ATA_PORT_PRIMARY); 1051 probe_ent = ata_pci_init_native_mode(pdev, port, ATA_PORT_PRIMARY);
1041 } 1052 }
1042 if (!probe_ent && !probe_ent2) { 1053 if (!probe_ent) {
1043 rc = -ENOMEM; 1054 rc = -ENOMEM;
1044 goto err_out_regions; 1055 goto err_out_regions;
1045 } 1056 }
@@ -1047,35 +1058,17 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
1047 pci_set_master(pdev); 1058 pci_set_master(pdev);
1048 1059
1049 /* FIXME: check ata_device_add return */ 1060 /* FIXME: check ata_device_add return */
1050 if (legacy_mode) { 1061 ata_device_add(probe_ent);
1051 struct device *dev = &pdev->dev;
1052 struct ata_host_set *host_set = NULL;
1053
1054 if (legacy_mode & (1 << 0)) {
1055 ata_device_add(probe_ent);
1056 host_set = dev_get_drvdata(dev);
1057 }
1058
1059 if (legacy_mode & (1 << 1)) {
1060 ata_device_add(probe_ent2);
1061 if (host_set) {
1062 host_set->next = dev_get_drvdata(dev);
1063 dev_set_drvdata(dev, host_set);
1064 }
1065 }
1066 } else
1067 ata_device_add(probe_ent);
1068 1062
1069 kfree(probe_ent); 1063 kfree(probe_ent);
1070 kfree(probe_ent2);
1071 1064
1072 return 0; 1065 return 0;
1073 1066
1074err_out_regions: 1067err_out_regions:
1075 if (legacy_mode & (1 << 0)) 1068 if (legacy_mode & ATA_PORT_PRIMARY)
1076 release_region(0x1f0, 8); 1069 release_region(ATA_PRIMARY_CMD, 8);
1077 if (legacy_mode & (1 << 1)) 1070 if (legacy_mode & ATA_PORT_SECONDARY)
1078 release_region(0x170, 8); 1071 release_region(ATA_SECONDARY_CMD, 8);
1079 pci_release_regions(pdev); 1072 pci_release_regions(pdev);
1080err_out: 1073err_out:
1081 if (disable_dev_on_err) 1074 if (disable_dev_on_err)