diff options
author | Alan Cox <alan@lxorguk.ukuu.org.uk> | 2006-08-10 03:59:10 -0400 |
---|---|---|
committer | Tejun Heo <htejun@gmail.com> | 2006-08-10 03:59:10 -0400 |
commit | 2ec7df0457b710d9201f211dbccdbecf0ad38b7e (patch) | |
tree | 4fbffc3e05aa65fd9ed63b4ac809712719e19cda | |
parent | 37deecb5139ee431233781a9a093d9fcaab54c5b (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>
-rw-r--r-- | drivers/scsi/ata_piix.c | 2 | ||||
-rw-r--r-- | drivers/scsi/libata-bmdma.c | 135 | ||||
-rw-r--r-- | drivers/scsi/libata-core.c | 59 | ||||
-rw-r--r-- | include/asm-alpha/libata-portmap.h | 1 | ||||
-rw-r--r-- | include/asm-generic/libata-portmap.h | 12 | ||||
-rw-r--r-- | include/asm-i386/libata-portmap.h | 1 | ||||
-rw-r--r-- | include/asm-ia64/libata-portmap.h | 1 | ||||
-rw-r--r-- | include/asm-powerpc/libata-portmap.h | 1 | ||||
-rw-r--r-- | include/asm-sparc/libata-portmap.h | 1 | ||||
-rw-r--r-- | include/asm-sparc64/libata-portmap.h | 1 | ||||
-rw-r--r-- | include/asm-x86_64/libata-portmap.h | 1 | ||||
-rw-r--r-- | include/linux/libata.h | 5 |
12 files changed, 123 insertions, 97 deletions
diff --git a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c index 5e8afc876980..40ecab5793e3 100644 --- a/drivers/scsi/ata_piix.c +++ b/drivers/scsi/ata_piix.c | |||
@@ -932,8 +932,6 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | |||
932 | 932 | ||
933 | static void piix_host_stop(struct ata_host_set *host_set) | 933 | static void piix_host_stop(struct ata_host_set *host_set) |
934 | { | 934 | { |
935 | if (host_set->next == NULL) | ||
936 | kfree(host_set->private_data); | ||
937 | ata_host_stop(host_set); | 935 | ata_host_stop(host_set); |
938 | } | 936 | } |
939 | 937 | ||
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 | ||
869 | static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev, | 869 | static 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, | |||
934 | int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info, | 949 | int 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 | ||
1074 | err_out_regions: | 1067 | err_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); |
1080 | err_out: | 1073 | err_out: |
1081 | if (disable_dev_on_err) | 1074 | if (disable_dev_on_err) |
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index 4e6c2e8ac0f6..3634279d896d 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c | |||
@@ -5223,8 +5223,9 @@ void ata_port_init(struct ata_port *ap, struct ata_host_set *host_set, | |||
5223 | ap->host_set = host_set; | 5223 | ap->host_set = host_set; |
5224 | ap->dev = ent->dev; | 5224 | ap->dev = ent->dev; |
5225 | ap->port_no = port_no; | 5225 | ap->port_no = port_no; |
5226 | ap->hard_port_no = | 5226 | ap->hard_port_no = port_no; |
5227 | ent->legacy_mode ? ent->hard_port_no : port_no; | 5227 | if (ent->legacy_mode) |
5228 | ap->hard_port_no += ent->hard_port_no; | ||
5228 | ap->pio_mask = ent->pio_mask; | 5229 | ap->pio_mask = ent->pio_mask; |
5229 | ap->mwdma_mask = ent->mwdma_mask; | 5230 | ap->mwdma_mask = ent->mwdma_mask; |
5230 | ap->udma_mask = ent->udma_mask; | 5231 | ap->udma_mask = ent->udma_mask; |
@@ -5400,6 +5401,7 @@ int ata_device_add(const struct ata_probe_ent *ent) | |||
5400 | ata_host_set_init(host_set, dev, ent->host_set_flags, ent->port_ops); | 5401 | ata_host_set_init(host_set, dev, ent->host_set_flags, ent->port_ops); |
5401 | host_set->n_ports = ent->n_ports; | 5402 | host_set->n_ports = ent->n_ports; |
5402 | host_set->irq = ent->irq; | 5403 | host_set->irq = ent->irq; |
5404 | host_set->irq2 = ent->irq2; | ||
5403 | host_set->mmio_base = ent->mmio_base; | 5405 | host_set->mmio_base = ent->mmio_base; |
5404 | host_set->private_data = ent->private_data; | 5406 | host_set->private_data = ent->private_data; |
5405 | 5407 | ||
@@ -5407,11 +5409,16 @@ int ata_device_add(const struct ata_probe_ent *ent) | |||
5407 | for (i = 0; i < host_set->n_ports; i++) { | 5409 | for (i = 0; i < host_set->n_ports; i++) { |
5408 | struct ata_port *ap; | 5410 | struct ata_port *ap; |
5409 | unsigned long xfer_mode_mask; | 5411 | unsigned long xfer_mode_mask; |
5412 | int irq_line = ent->irq; | ||
5410 | 5413 | ||
5411 | ap = ata_port_add(ent, host_set, i); | 5414 | ap = ata_port_add(ent, host_set, i); |
5412 | if (!ap) | 5415 | if (!ap) |
5413 | goto err_out; | 5416 | goto err_out; |
5414 | 5417 | ||
5418 | /* Report the secondary IRQ for second channel legacy */ | ||
5419 | if (i == 1 && ent->irq2) | ||
5420 | irq_line = ent->irq2; | ||
5421 | |||
5415 | host_set->ports[i] = ap; | 5422 | host_set->ports[i] = ap; |
5416 | xfer_mode_mask =(ap->udma_mask << ATA_SHIFT_UDMA) | | 5423 | xfer_mode_mask =(ap->udma_mask << ATA_SHIFT_UDMA) | |
5417 | (ap->mwdma_mask << ATA_SHIFT_MWDMA) | | 5424 | (ap->mwdma_mask << ATA_SHIFT_MWDMA) | |
@@ -5419,20 +5426,20 @@ int ata_device_add(const struct ata_probe_ent *ent) | |||
5419 | 5426 | ||
5420 | /* print per-port info to dmesg */ | 5427 | /* print per-port info to dmesg */ |
5421 | ata_port_printk(ap, KERN_INFO, "%cATA max %s cmd 0x%lX " | 5428 | ata_port_printk(ap, KERN_INFO, "%cATA max %s cmd 0x%lX " |
5422 | "ctl 0x%lX bmdma 0x%lX irq %lu\n", | 5429 | "ctl 0x%lX bmdma 0x%lX irq %d\n", |
5423 | ap->flags & ATA_FLAG_SATA ? 'S' : 'P', | 5430 | ap->flags & ATA_FLAG_SATA ? 'S' : 'P', |
5424 | ata_mode_string(xfer_mode_mask), | 5431 | ata_mode_string(xfer_mode_mask), |
5425 | ap->ioaddr.cmd_addr, | 5432 | ap->ioaddr.cmd_addr, |
5426 | ap->ioaddr.ctl_addr, | 5433 | ap->ioaddr.ctl_addr, |
5427 | ap->ioaddr.bmdma_addr, | 5434 | ap->ioaddr.bmdma_addr, |
5428 | ent->irq); | 5435 | irq_line); |
5429 | 5436 | ||
5430 | ata_chk_status(ap); | 5437 | ata_chk_status(ap); |
5431 | host_set->ops->irq_clear(ap); | 5438 | host_set->ops->irq_clear(ap); |
5432 | ata_eh_freeze_port(ap); /* freeze port before requesting IRQ */ | 5439 | ata_eh_freeze_port(ap); /* freeze port before requesting IRQ */ |
5433 | } | 5440 | } |
5434 | 5441 | ||
5435 | /* obtain irq, that is shared between channels */ | 5442 | /* obtain irq, that may be shared between channels */ |
5436 | rc = request_irq(ent->irq, ent->port_ops->irq_handler, ent->irq_flags, | 5443 | rc = request_irq(ent->irq, ent->port_ops->irq_handler, ent->irq_flags, |
5437 | DRV_NAME, host_set); | 5444 | DRV_NAME, host_set); |
5438 | if (rc) { | 5445 | if (rc) { |
@@ -5441,6 +5448,21 @@ int ata_device_add(const struct ata_probe_ent *ent) | |||
5441 | goto err_out; | 5448 | goto err_out; |
5442 | } | 5449 | } |
5443 | 5450 | ||
5451 | /* do we have a second IRQ for the other channel, eg legacy mode */ | ||
5452 | if (ent->irq2) { | ||
5453 | /* We will get weird core code crashes later if this is true | ||
5454 | so trap it now */ | ||
5455 | BUG_ON(ent->irq == ent->irq2); | ||
5456 | |||
5457 | rc = request_irq(ent->irq2, ent->port_ops->irq_handler, ent->irq_flags, | ||
5458 | DRV_NAME, host_set); | ||
5459 | if (rc) { | ||
5460 | dev_printk(KERN_ERR, dev, "irq %lu request failed: %d\n", | ||
5461 | ent->irq2, rc); | ||
5462 | goto err_out_free_irq; | ||
5463 | } | ||
5464 | } | ||
5465 | |||
5444 | /* perform each probe synchronously */ | 5466 | /* perform each probe synchronously */ |
5445 | DPRINTK("probe begin\n"); | 5467 | DPRINTK("probe begin\n"); |
5446 | for (i = 0; i < host_set->n_ports; i++) { | 5468 | for (i = 0; i < host_set->n_ports; i++) { |
@@ -5514,6 +5536,8 @@ int ata_device_add(const struct ata_probe_ent *ent) | |||
5514 | VPRINTK("EXIT, returning %u\n", ent->n_ports); | 5536 | VPRINTK("EXIT, returning %u\n", ent->n_ports); |
5515 | return ent->n_ports; /* success */ | 5537 | return ent->n_ports; /* success */ |
5516 | 5538 | ||
5539 | err_out_free_irq: | ||
5540 | free_irq(ent->irq, host_set); | ||
5517 | err_out: | 5541 | err_out: |
5518 | for (i = 0; i < host_set->n_ports; i++) { | 5542 | for (i = 0; i < host_set->n_ports; i++) { |
5519 | struct ata_port *ap = host_set->ports[i]; | 5543 | struct ata_port *ap = host_set->ports[i]; |
@@ -5605,6 +5629,8 @@ void ata_host_set_remove(struct ata_host_set *host_set) | |||
5605 | ata_port_detach(host_set->ports[i]); | 5629 | ata_port_detach(host_set->ports[i]); |
5606 | 5630 | ||
5607 | free_irq(host_set->irq, host_set); | 5631 | free_irq(host_set->irq, host_set); |
5632 | if (host_set->irq2) | ||
5633 | free_irq(host_set->irq2, host_set); | ||
5608 | 5634 | ||
5609 | for (i = 0; i < host_set->n_ports; i++) { | 5635 | for (i = 0; i < host_set->n_ports; i++) { |
5610 | struct ata_port *ap = host_set->ports[i]; | 5636 | struct ata_port *ap = host_set->ports[i]; |
@@ -5614,10 +5640,11 @@ void ata_host_set_remove(struct ata_host_set *host_set) | |||
5614 | if ((ap->flags & ATA_FLAG_NO_LEGACY) == 0) { | 5640 | if ((ap->flags & ATA_FLAG_NO_LEGACY) == 0) { |
5615 | struct ata_ioports *ioaddr = &ap->ioaddr; | 5641 | struct ata_ioports *ioaddr = &ap->ioaddr; |
5616 | 5642 | ||
5617 | if (ioaddr->cmd_addr == 0x1f0) | 5643 | /* FIXME: Add -ac IDE pci mods to remove these special cases */ |
5618 | release_region(0x1f0, 8); | 5644 | if (ioaddr->cmd_addr == ATA_PRIMARY_CMD) |
5619 | else if (ioaddr->cmd_addr == 0x170) | 5645 | release_region(ATA_PRIMARY_CMD, 8); |
5620 | release_region(0x170, 8); | 5646 | else if (ioaddr->cmd_addr == ATA_SECONDARY_CMD) |
5647 | release_region(ATA_SECONDARY_CMD, 8); | ||
5621 | } | 5648 | } |
5622 | 5649 | ||
5623 | scsi_host_put(ap->host); | 5650 | scsi_host_put(ap->host); |
@@ -5735,11 +5762,8 @@ void ata_pci_remove_one (struct pci_dev *pdev) | |||
5735 | { | 5762 | { |
5736 | struct device *dev = pci_dev_to_dev(pdev); | 5763 | struct device *dev = pci_dev_to_dev(pdev); |
5737 | struct ata_host_set *host_set = dev_get_drvdata(dev); | 5764 | struct ata_host_set *host_set = dev_get_drvdata(dev); |
5738 | struct ata_host_set *host_set2 = host_set->next; | ||
5739 | 5765 | ||
5740 | ata_host_set_remove(host_set); | 5766 | ata_host_set_remove(host_set); |
5741 | if (host_set2) | ||
5742 | ata_host_set_remove(host_set2); | ||
5743 | 5767 | ||
5744 | pci_release_regions(pdev); | 5768 | pci_release_regions(pdev); |
5745 | pci_disable_device(pdev); | 5769 | pci_disable_device(pdev); |
@@ -5807,14 +5831,6 @@ int ata_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg) | |||
5807 | if (rc) | 5831 | if (rc) |
5808 | return rc; | 5832 | return rc; |
5809 | 5833 | ||
5810 | if (host_set->next) { | ||
5811 | rc = ata_host_set_suspend(host_set->next, mesg); | ||
5812 | if (rc) { | ||
5813 | ata_host_set_resume(host_set); | ||
5814 | return rc; | ||
5815 | } | ||
5816 | } | ||
5817 | |||
5818 | ata_pci_device_do_suspend(pdev, mesg); | 5834 | ata_pci_device_do_suspend(pdev, mesg); |
5819 | 5835 | ||
5820 | return 0; | 5836 | return 0; |
@@ -5826,9 +5842,6 @@ int ata_pci_device_resume(struct pci_dev *pdev) | |||
5826 | 5842 | ||
5827 | ata_pci_device_do_resume(pdev); | 5843 | ata_pci_device_do_resume(pdev); |
5828 | ata_host_set_resume(host_set); | 5844 | ata_host_set_resume(host_set); |
5829 | if (host_set->next) | ||
5830 | ata_host_set_resume(host_set->next); | ||
5831 | |||
5832 | return 0; | 5845 | return 0; |
5833 | } | 5846 | } |
5834 | #endif /* CONFIG_PCI */ | 5847 | #endif /* CONFIG_PCI */ |
diff --git a/include/asm-alpha/libata-portmap.h b/include/asm-alpha/libata-portmap.h new file mode 100644 index 000000000000..75484ef0c743 --- /dev/null +++ b/include/asm-alpha/libata-portmap.h | |||
@@ -0,0 +1 @@ | |||
#include <asm-generic/libata-portmap.h> | |||
diff --git a/include/asm-generic/libata-portmap.h b/include/asm-generic/libata-portmap.h new file mode 100644 index 000000000000..9202fd02d5be --- /dev/null +++ b/include/asm-generic/libata-portmap.h | |||
@@ -0,0 +1,12 @@ | |||
1 | #ifndef __ASM_GENERIC_LIBATA_PORTMAP_H | ||
2 | #define __ASM_GENERIC_LIBATA_PORTMAP_H | ||
3 | |||
4 | #define ATA_PRIMARY_CMD 0x1F0 | ||
5 | #define ATA_PRIMARY_CTL 0x3F6 | ||
6 | #define ATA_PRIMARY_IRQ 14 | ||
7 | |||
8 | #define ATA_SECONDARY_CMD 0x170 | ||
9 | #define ATA_SECONDARY_CTL 0x376 | ||
10 | #define ATA_SECONDARY_IRQ 15 | ||
11 | |||
12 | #endif | ||
diff --git a/include/asm-i386/libata-portmap.h b/include/asm-i386/libata-portmap.h new file mode 100644 index 000000000000..75484ef0c743 --- /dev/null +++ b/include/asm-i386/libata-portmap.h | |||
@@ -0,0 +1 @@ | |||
#include <asm-generic/libata-portmap.h> | |||
diff --git a/include/asm-ia64/libata-portmap.h b/include/asm-ia64/libata-portmap.h new file mode 100644 index 000000000000..75484ef0c743 --- /dev/null +++ b/include/asm-ia64/libata-portmap.h | |||
@@ -0,0 +1 @@ | |||
#include <asm-generic/libata-portmap.h> | |||
diff --git a/include/asm-powerpc/libata-portmap.h b/include/asm-powerpc/libata-portmap.h new file mode 100644 index 000000000000..75484ef0c743 --- /dev/null +++ b/include/asm-powerpc/libata-portmap.h | |||
@@ -0,0 +1 @@ | |||
#include <asm-generic/libata-portmap.h> | |||
diff --git a/include/asm-sparc/libata-portmap.h b/include/asm-sparc/libata-portmap.h new file mode 100644 index 000000000000..75484ef0c743 --- /dev/null +++ b/include/asm-sparc/libata-portmap.h | |||
@@ -0,0 +1 @@ | |||
#include <asm-generic/libata-portmap.h> | |||
diff --git a/include/asm-sparc64/libata-portmap.h b/include/asm-sparc64/libata-portmap.h new file mode 100644 index 000000000000..75484ef0c743 --- /dev/null +++ b/include/asm-sparc64/libata-portmap.h | |||
@@ -0,0 +1 @@ | |||
#include <asm-generic/libata-portmap.h> | |||
diff --git a/include/asm-x86_64/libata-portmap.h b/include/asm-x86_64/libata-portmap.h new file mode 100644 index 000000000000..75484ef0c743 --- /dev/null +++ b/include/asm-x86_64/libata-portmap.h | |||
@@ -0,0 +1 @@ | |||
#include <asm-generic/libata-portmap.h> | |||
diff --git a/include/linux/libata.h b/include/linux/libata.h index cf5eb1da3e32..4504776570e4 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h | |||
@@ -36,6 +36,8 @@ | |||
36 | #include <linux/workqueue.h> | 36 | #include <linux/workqueue.h> |
37 | #include <scsi/scsi_host.h> | 37 | #include <scsi/scsi_host.h> |
38 | 38 | ||
39 | #include <asm/libata-portmap.h> | ||
40 | |||
39 | /* | 41 | /* |
40 | * compile-time options: to be removed as soon as all the drivers are | 42 | * compile-time options: to be removed as soon as all the drivers are |
41 | * converted to the new debugging mechanism | 43 | * converted to the new debugging mechanism |
@@ -356,6 +358,7 @@ struct ata_probe_ent { | |||
356 | unsigned int udma_mask; | 358 | unsigned int udma_mask; |
357 | unsigned int legacy_mode; | 359 | unsigned int legacy_mode; |
358 | unsigned long irq; | 360 | unsigned long irq; |
361 | unsigned long irq2; | ||
359 | unsigned int irq_flags; | 362 | unsigned int irq_flags; |
360 | unsigned long host_flags; | 363 | unsigned long host_flags; |
361 | unsigned long host_set_flags; | 364 | unsigned long host_set_flags; |
@@ -367,6 +370,7 @@ struct ata_host_set { | |||
367 | spinlock_t lock; | 370 | spinlock_t lock; |
368 | struct device *dev; | 371 | struct device *dev; |
369 | unsigned long irq; | 372 | unsigned long irq; |
373 | unsigned long irq2; | ||
370 | void __iomem *mmio_base; | 374 | void __iomem *mmio_base; |
371 | unsigned int n_ports; | 375 | unsigned int n_ports; |
372 | void *private_data; | 376 | void *private_data; |
@@ -374,7 +378,6 @@ struct ata_host_set { | |||
374 | unsigned long flags; | 378 | unsigned long flags; |
375 | int simplex_claimed; /* Keep seperate in case we | 379 | int simplex_claimed; /* Keep seperate in case we |
376 | ever need to do this locked */ | 380 | ever need to do this locked */ |
377 | struct ata_host_set *next; /* for legacy mode */ | ||
378 | struct ata_port *ports[0]; | 381 | struct ata_port *ports[0]; |
379 | }; | 382 | }; |
380 | 383 | ||