aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/ata_piix.c2
-rw-r--r--drivers/scsi/libata-bmdma.c135
-rw-r--r--drivers/scsi/libata-core.c59
3 files changed, 100 insertions, 96 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
933static void piix_host_stop(struct ata_host_set *host_set) 933static 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
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)
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
5539err_out_free_irq:
5540 free_irq(ent->irq, host_set);
5517err_out: 5541err_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 */