diff options
-rw-r--r-- | drivers/scsi/ahci.c | 80 | ||||
-rw-r--r-- | drivers/scsi/sata_promise.c | 26 | ||||
-rw-r--r-- | drivers/scsi/sata_svw.c | 25 |
3 files changed, 108 insertions, 23 deletions
diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c index fc5263c6b102..1799233dcf9f 100644 --- a/drivers/scsi/ahci.c +++ b/drivers/scsi/ahci.c | |||
@@ -39,7 +39,7 @@ | |||
39 | #include <asm/io.h> | 39 | #include <asm/io.h> |
40 | 40 | ||
41 | #define DRV_NAME "ahci" | 41 | #define DRV_NAME "ahci" |
42 | #define DRV_VERSION "1.00" | 42 | #define DRV_VERSION "1.01" |
43 | 43 | ||
44 | 44 | ||
45 | enum { | 45 | enum { |
@@ -134,6 +134,9 @@ enum { | |||
134 | PORT_CMD_ICC_ACTIVE = (0x1 << 28), /* Put i/f in active state */ | 134 | PORT_CMD_ICC_ACTIVE = (0x1 << 28), /* Put i/f in active state */ |
135 | PORT_CMD_ICC_PARTIAL = (0x2 << 28), /* Put i/f in partial state */ | 135 | PORT_CMD_ICC_PARTIAL = (0x2 << 28), /* Put i/f in partial state */ |
136 | PORT_CMD_ICC_SLUMBER = (0x6 << 28), /* Put i/f in slumber state */ | 136 | PORT_CMD_ICC_SLUMBER = (0x6 << 28), /* Put i/f in slumber state */ |
137 | |||
138 | /* hpriv->flags bits */ | ||
139 | AHCI_FLAG_MSI = (1 << 0), | ||
137 | }; | 140 | }; |
138 | 141 | ||
139 | struct ahci_cmd_hdr { | 142 | struct ahci_cmd_hdr { |
@@ -183,6 +186,7 @@ static void ahci_qc_prep(struct ata_queued_cmd *qc); | |||
183 | static u8 ahci_check_status(struct ata_port *ap); | 186 | static u8 ahci_check_status(struct ata_port *ap); |
184 | static u8 ahci_check_err(struct ata_port *ap); | 187 | static u8 ahci_check_err(struct ata_port *ap); |
185 | static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc); | 188 | static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc); |
189 | static void ahci_remove_one (struct pci_dev *pdev); | ||
186 | 190 | ||
187 | static Scsi_Host_Template ahci_sht = { | 191 | static Scsi_Host_Template ahci_sht = { |
188 | .module = THIS_MODULE, | 192 | .module = THIS_MODULE, |
@@ -272,7 +276,7 @@ static struct pci_driver ahci_pci_driver = { | |||
272 | .name = DRV_NAME, | 276 | .name = DRV_NAME, |
273 | .id_table = ahci_pci_tbl, | 277 | .id_table = ahci_pci_tbl, |
274 | .probe = ahci_init_one, | 278 | .probe = ahci_init_one, |
275 | .remove = ata_pci_remove_one, | 279 | .remove = ahci_remove_one, |
276 | }; | 280 | }; |
277 | 281 | ||
278 | 282 | ||
@@ -795,8 +799,6 @@ static int ahci_host_init(struct ata_probe_ent *probe_ent) | |||
795 | return rc; | 799 | return rc; |
796 | } | 800 | } |
797 | } | 801 | } |
798 | |||
799 | hpriv->flags |= HOST_CAP_64; | ||
800 | } else { | 802 | } else { |
801 | rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK); | 803 | rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK); |
802 | if (rc) { | 804 | if (rc) { |
@@ -879,15 +881,19 @@ static int ahci_host_init(struct ata_probe_ent *probe_ent) | |||
879 | } | 881 | } |
880 | 882 | ||
881 | /* move to PCI layer, integrate w/ MSI stuff */ | 883 | /* move to PCI layer, integrate w/ MSI stuff */ |
882 | static void pci_enable_intx(struct pci_dev *pdev) | 884 | static void pci_intx(struct pci_dev *pdev, int enable) |
883 | { | 885 | { |
884 | u16 pci_command; | 886 | u16 pci_command, new; |
885 | 887 | ||
886 | pci_read_config_word(pdev, PCI_COMMAND, &pci_command); | 888 | pci_read_config_word(pdev, PCI_COMMAND, &pci_command); |
887 | if (pci_command & PCI_COMMAND_INTX_DISABLE) { | 889 | |
888 | pci_command &= ~PCI_COMMAND_INTX_DISABLE; | 890 | if (enable) |
891 | new = pci_command & ~PCI_COMMAND_INTX_DISABLE; | ||
892 | else | ||
893 | new = pci_command | PCI_COMMAND_INTX_DISABLE; | ||
894 | |||
895 | if (new != pci_command) | ||
889 | pci_write_config_word(pdev, PCI_COMMAND, pci_command); | 896 | pci_write_config_word(pdev, PCI_COMMAND, pci_command); |
890 | } | ||
891 | } | 897 | } |
892 | 898 | ||
893 | static void ahci_print_info(struct ata_probe_ent *probe_ent) | 899 | static void ahci_print_info(struct ata_probe_ent *probe_ent) |
@@ -969,7 +975,7 @@ static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | |||
969 | unsigned long base; | 975 | unsigned long base; |
970 | void *mmio_base; | 976 | void *mmio_base; |
971 | unsigned int board_idx = (unsigned int) ent->driver_data; | 977 | unsigned int board_idx = (unsigned int) ent->driver_data; |
972 | int pci_dev_busy = 0; | 978 | int have_msi, pci_dev_busy = 0; |
973 | int rc; | 979 | int rc; |
974 | 980 | ||
975 | VPRINTK("ENTER\n"); | 981 | VPRINTK("ENTER\n"); |
@@ -987,12 +993,17 @@ static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | |||
987 | goto err_out; | 993 | goto err_out; |
988 | } | 994 | } |
989 | 995 | ||
990 | pci_enable_intx(pdev); | 996 | if (pci_enable_msi(pdev) == 0) |
997 | have_msi = 1; | ||
998 | else { | ||
999 | pci_intx(pdev, 1); | ||
1000 | have_msi = 0; | ||
1001 | } | ||
991 | 1002 | ||
992 | probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL); | 1003 | probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL); |
993 | if (probe_ent == NULL) { | 1004 | if (probe_ent == NULL) { |
994 | rc = -ENOMEM; | 1005 | rc = -ENOMEM; |
995 | goto err_out_regions; | 1006 | goto err_out_msi; |
996 | } | 1007 | } |
997 | 1008 | ||
998 | memset(probe_ent, 0, sizeof(*probe_ent)); | 1009 | memset(probe_ent, 0, sizeof(*probe_ent)); |
@@ -1025,6 +1036,9 @@ static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1025 | probe_ent->mmio_base = mmio_base; | 1036 | probe_ent->mmio_base = mmio_base; |
1026 | probe_ent->private_data = hpriv; | 1037 | probe_ent->private_data = hpriv; |
1027 | 1038 | ||
1039 | if (have_msi) | ||
1040 | hpriv->flags |= AHCI_FLAG_MSI; | ||
1041 | |||
1028 | /* initialize adapter */ | 1042 | /* initialize adapter */ |
1029 | rc = ahci_host_init(probe_ent); | 1043 | rc = ahci_host_init(probe_ent); |
1030 | if (rc) | 1044 | if (rc) |
@@ -1044,7 +1058,11 @@ err_out_iounmap: | |||
1044 | iounmap(mmio_base); | 1058 | iounmap(mmio_base); |
1045 | err_out_free_ent: | 1059 | err_out_free_ent: |
1046 | kfree(probe_ent); | 1060 | kfree(probe_ent); |
1047 | err_out_regions: | 1061 | err_out_msi: |
1062 | if (have_msi) | ||
1063 | pci_disable_msi(pdev); | ||
1064 | else | ||
1065 | pci_intx(pdev, 0); | ||
1048 | pci_release_regions(pdev); | 1066 | pci_release_regions(pdev); |
1049 | err_out: | 1067 | err_out: |
1050 | if (!pci_dev_busy) | 1068 | if (!pci_dev_busy) |
@@ -1052,6 +1070,42 @@ err_out: | |||
1052 | return rc; | 1070 | return rc; |
1053 | } | 1071 | } |
1054 | 1072 | ||
1073 | static void ahci_remove_one (struct pci_dev *pdev) | ||
1074 | { | ||
1075 | struct device *dev = pci_dev_to_dev(pdev); | ||
1076 | struct ata_host_set *host_set = dev_get_drvdata(dev); | ||
1077 | struct ahci_host_priv *hpriv = host_set->private_data; | ||
1078 | struct ata_port *ap; | ||
1079 | unsigned int i; | ||
1080 | int have_msi; | ||
1081 | |||
1082 | for (i = 0; i < host_set->n_ports; i++) { | ||
1083 | ap = host_set->ports[i]; | ||
1084 | |||
1085 | scsi_remove_host(ap->host); | ||
1086 | } | ||
1087 | |||
1088 | have_msi = hpriv->flags & AHCI_FLAG_MSI; | ||
1089 | free_irq(host_set->irq, host_set); | ||
1090 | |||
1091 | for (i = 0; i < host_set->n_ports; i++) { | ||
1092 | ap = host_set->ports[i]; | ||
1093 | |||
1094 | ata_scsi_release(ap->host); | ||
1095 | scsi_host_put(ap->host); | ||
1096 | } | ||
1097 | |||
1098 | host_set->ops->host_stop(host_set); | ||
1099 | kfree(host_set); | ||
1100 | |||
1101 | if (have_msi) | ||
1102 | pci_disable_msi(pdev); | ||
1103 | else | ||
1104 | pci_intx(pdev, 0); | ||
1105 | pci_release_regions(pdev); | ||
1106 | pci_disable_device(pdev); | ||
1107 | dev_set_drvdata(dev, NULL); | ||
1108 | } | ||
1055 | 1109 | ||
1056 | static int __init ahci_init(void) | 1110 | static int __init ahci_init(void) |
1057 | { | 1111 | { |
diff --git a/drivers/scsi/sata_promise.c b/drivers/scsi/sata_promise.c index b18c90582e67..5c1d4411457a 100644 --- a/drivers/scsi/sata_promise.c +++ b/drivers/scsi/sata_promise.c | |||
@@ -59,6 +59,7 @@ enum { | |||
59 | 59 | ||
60 | board_2037x = 0, /* FastTrak S150 TX2plus */ | 60 | board_2037x = 0, /* FastTrak S150 TX2plus */ |
61 | board_20319 = 1, /* FastTrak S150 TX4 */ | 61 | board_20319 = 1, /* FastTrak S150 TX4 */ |
62 | board_20619 = 2, /* FastTrak TX4000 */ | ||
62 | 63 | ||
63 | PDC_HAS_PATA = (1 << 1), /* PDC20375 has PATA */ | 64 | PDC_HAS_PATA = (1 << 1), /* PDC20375 has PATA */ |
64 | 65 | ||
@@ -147,6 +148,17 @@ static struct ata_port_info pdc_port_info[] = { | |||
147 | .udma_mask = 0x7f, /* udma0-6 ; FIXME */ | 148 | .udma_mask = 0x7f, /* udma0-6 ; FIXME */ |
148 | .port_ops = &pdc_ata_ops, | 149 | .port_ops = &pdc_ata_ops, |
149 | }, | 150 | }, |
151 | |||
152 | /* board_20619 */ | ||
153 | { | ||
154 | .sht = &pdc_ata_sht, | ||
155 | .host_flags = ATA_FLAG_NO_LEGACY | ATA_FLAG_SRST | | ||
156 | ATA_FLAG_MMIO | ATA_FLAG_SLAVE_POSS, | ||
157 | .pio_mask = 0x1f, /* pio0-4 */ | ||
158 | .mwdma_mask = 0x07, /* mwdma0-2 */ | ||
159 | .udma_mask = 0x7f, /* udma0-6 ; FIXME */ | ||
160 | .port_ops = &pdc_ata_ops, | ||
161 | }, | ||
150 | }; | 162 | }; |
151 | 163 | ||
152 | static struct pci_device_id pdc_ata_pci_tbl[] = { | 164 | static struct pci_device_id pdc_ata_pci_tbl[] = { |
@@ -172,6 +184,9 @@ static struct pci_device_id pdc_ata_pci_tbl[] = { | |||
172 | { PCI_VENDOR_ID_PROMISE, 0x3d18, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 184 | { PCI_VENDOR_ID_PROMISE, 0x3d18, PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
173 | board_20319 }, | 185 | board_20319 }, |
174 | 186 | ||
187 | { PCI_VENDOR_ID_PROMISE, 0x6629, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
188 | board_20619 }, | ||
189 | |||
175 | { } /* terminate list */ | 190 | { } /* terminate list */ |
176 | }; | 191 | }; |
177 | 192 | ||
@@ -636,6 +651,15 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e | |||
636 | case board_2037x: | 651 | case board_2037x: |
637 | probe_ent->n_ports = 2; | 652 | probe_ent->n_ports = 2; |
638 | break; | 653 | break; |
654 | case board_20619: | ||
655 | probe_ent->n_ports = 4; | ||
656 | |||
657 | pdc_ata_setup_port(&probe_ent->port[2], base + 0x300); | ||
658 | pdc_ata_setup_port(&probe_ent->port[3], base + 0x380); | ||
659 | |||
660 | probe_ent->port[2].scr_addr = base + 0x600; | ||
661 | probe_ent->port[3].scr_addr = base + 0x700; | ||
662 | break; | ||
639 | default: | 663 | default: |
640 | BUG(); | 664 | BUG(); |
641 | break; | 665 | break; |
@@ -676,7 +700,7 @@ static void __exit pdc_ata_exit(void) | |||
676 | 700 | ||
677 | 701 | ||
678 | MODULE_AUTHOR("Jeff Garzik"); | 702 | MODULE_AUTHOR("Jeff Garzik"); |
679 | MODULE_DESCRIPTION("Promise SATA TX2/TX4 low-level driver"); | 703 | MODULE_DESCRIPTION("Promise ATA TX2/TX4/TX4000 low-level driver"); |
680 | MODULE_LICENSE("GPL"); | 704 | MODULE_LICENSE("GPL"); |
681 | MODULE_DEVICE_TABLE(pci, pdc_ata_pci_tbl); | 705 | MODULE_DEVICE_TABLE(pci, pdc_ata_pci_tbl); |
682 | MODULE_VERSION(DRV_VERSION); | 706 | MODULE_VERSION(DRV_VERSION); |
diff --git a/drivers/scsi/sata_svw.c b/drivers/scsi/sata_svw.c index edef1fa969fc..189744887628 100644 --- a/drivers/scsi/sata_svw.c +++ b/drivers/scsi/sata_svw.c | |||
@@ -344,6 +344,7 @@ static int k2_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *e | |||
344 | void *mmio_base; | 344 | void *mmio_base; |
345 | int pci_dev_busy = 0; | 345 | int pci_dev_busy = 0; |
346 | int rc; | 346 | int rc; |
347 | int i; | ||
347 | 348 | ||
348 | if (!printed_version++) | 349 | if (!printed_version++) |
349 | printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n"); | 350 | printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n"); |
@@ -421,11 +422,11 @@ static int k2_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *e | |||
421 | probe_ent->mwdma_mask = 0x7; | 422 | probe_ent->mwdma_mask = 0x7; |
422 | probe_ent->udma_mask = 0x7f; | 423 | probe_ent->udma_mask = 0x7f; |
423 | 424 | ||
424 | /* We have 4 ports per PCI function */ | 425 | /* different controllers have different number of ports - currently 4 or 8 */ |
425 | k2_sata_setup_port(&probe_ent->port[0], base + 0 * K2_SATA_PORT_OFFSET); | 426 | /* All ports are on the same function. Multi-function device is no |
426 | k2_sata_setup_port(&probe_ent->port[1], base + 1 * K2_SATA_PORT_OFFSET); | 427 | * longer available. This should not be seen in any system. */ |
427 | k2_sata_setup_port(&probe_ent->port[2], base + 2 * K2_SATA_PORT_OFFSET); | 428 | for (i = 0; i < ent->driver_data; i++) |
428 | k2_sata_setup_port(&probe_ent->port[3], base + 3 * K2_SATA_PORT_OFFSET); | 429 | k2_sata_setup_port(&probe_ent->port[i], base + i * K2_SATA_PORT_OFFSET); |
429 | 430 | ||
430 | pci_set_master(pdev); | 431 | pci_set_master(pdev); |
431 | 432 | ||
@@ -445,11 +446,17 @@ err_out: | |||
445 | return rc; | 446 | return rc; |
446 | } | 447 | } |
447 | 448 | ||
448 | 449 | /* 0x240 is device ID for Apple K2 device | |
450 | * 0x241 is device ID for Serverworks Frodo4 | ||
451 | * 0x242 is device ID for Serverworks Frodo8 | ||
452 | * 0x24a is device ID for BCM5785 (aka HT1000) HT southbridge integrated SATA | ||
453 | * controller | ||
454 | * */ | ||
449 | static struct pci_device_id k2_sata_pci_tbl[] = { | 455 | static struct pci_device_id k2_sata_pci_tbl[] = { |
450 | { 0x1166, 0x0240, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, | 456 | { 0x1166, 0x0240, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 }, |
451 | { 0x1166, 0x0241, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, | 457 | { 0x1166, 0x0241, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 }, |
452 | { 0x1166, 0x0242, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, | 458 | { 0x1166, 0x0242, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8 }, |
459 | { 0x1166, 0x024a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 }, | ||
453 | { } | 460 | { } |
454 | }; | 461 | }; |
455 | 462 | ||