aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/ahci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/ahci.c')
-rw-r--r--drivers/scsi/ahci.c103
1 files changed, 78 insertions, 25 deletions
diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c
index da5bd33d982d..9a547ca9c864 100644
--- a/drivers/scsi/ahci.c
+++ b/drivers/scsi/ahci.c
@@ -32,13 +32,14 @@
32#include <linux/delay.h> 32#include <linux/delay.h>
33#include <linux/interrupt.h> 33#include <linux/interrupt.h>
34#include <linux/sched.h> 34#include <linux/sched.h>
35#include <linux/dma-mapping.h>
35#include "scsi.h" 36#include "scsi.h"
36#include <scsi/scsi_host.h> 37#include <scsi/scsi_host.h>
37#include <linux/libata.h> 38#include <linux/libata.h>
38#include <asm/io.h> 39#include <asm/io.h>
39 40
40#define DRV_NAME "ahci" 41#define DRV_NAME "ahci"
41#define DRV_VERSION "1.00" 42#define DRV_VERSION "1.01"
42 43
43 44
44enum { 45enum {
@@ -49,6 +50,7 @@ enum {
49 AHCI_CMD_SLOT_SZ = 32 * 32, 50 AHCI_CMD_SLOT_SZ = 32 * 32,
50 AHCI_RX_FIS_SZ = 256, 51 AHCI_RX_FIS_SZ = 256,
51 AHCI_CMD_TBL_HDR = 0x80, 52 AHCI_CMD_TBL_HDR = 0x80,
53 AHCI_CMD_TBL_CDB = 0x40,
52 AHCI_CMD_TBL_SZ = AHCI_CMD_TBL_HDR + (AHCI_MAX_SG * 16), 54 AHCI_CMD_TBL_SZ = AHCI_CMD_TBL_HDR + (AHCI_MAX_SG * 16),
53 AHCI_PORT_PRIV_DMA_SZ = AHCI_CMD_SLOT_SZ + AHCI_CMD_TBL_SZ + 55 AHCI_PORT_PRIV_DMA_SZ = AHCI_CMD_SLOT_SZ + AHCI_CMD_TBL_SZ +
54 AHCI_RX_FIS_SZ, 56 AHCI_RX_FIS_SZ,
@@ -133,6 +135,9 @@ enum {
133 PORT_CMD_ICC_ACTIVE = (0x1 << 28), /* Put i/f in active state */ 135 PORT_CMD_ICC_ACTIVE = (0x1 << 28), /* Put i/f in active state */
134 PORT_CMD_ICC_PARTIAL = (0x2 << 28), /* Put i/f in partial state */ 136 PORT_CMD_ICC_PARTIAL = (0x2 << 28), /* Put i/f in partial state */
135 PORT_CMD_ICC_SLUMBER = (0x6 << 28), /* Put i/f in slumber state */ 137 PORT_CMD_ICC_SLUMBER = (0x6 << 28), /* Put i/f in slumber state */
138
139 /* hpriv->flags bits */
140 AHCI_FLAG_MSI = (1 << 0),
136}; 141};
137 142
138struct ahci_cmd_hdr { 143struct ahci_cmd_hdr {
@@ -182,6 +187,7 @@ static void ahci_qc_prep(struct ata_queued_cmd *qc);
182static u8 ahci_check_status(struct ata_port *ap); 187static u8 ahci_check_status(struct ata_port *ap);
183static u8 ahci_check_err(struct ata_port *ap); 188static u8 ahci_check_err(struct ata_port *ap);
184static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc); 189static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc);
190static void ahci_remove_one (struct pci_dev *pdev);
185 191
186static Scsi_Host_Template ahci_sht = { 192static Scsi_Host_Template ahci_sht = {
187 .module = THIS_MODULE, 193 .module = THIS_MODULE,
@@ -271,7 +277,7 @@ static struct pci_driver ahci_pci_driver = {
271 .name = DRV_NAME, 277 .name = DRV_NAME,
272 .id_table = ahci_pci_tbl, 278 .id_table = ahci_pci_tbl,
273 .probe = ahci_init_one, 279 .probe = ahci_init_one,
274 .remove = ata_pci_remove_one, 280 .remove = ahci_remove_one,
275}; 281};
276 282
277 283
@@ -289,6 +295,8 @@ static void ahci_host_stop(struct ata_host_set *host_set)
289{ 295{
290 struct ahci_host_priv *hpriv = host_set->private_data; 296 struct ahci_host_priv *hpriv = host_set->private_data;
291 kfree(hpriv); 297 kfree(hpriv);
298
299 ata_host_stop(host_set);
292} 300}
293 301
294static int ahci_port_start(struct ata_port *ap) 302static int ahci_port_start(struct ata_port *ap)
@@ -503,7 +511,8 @@ static void ahci_fill_sg(struct ata_queued_cmd *qc)
503 511
504static void ahci_qc_prep(struct ata_queued_cmd *qc) 512static void ahci_qc_prep(struct ata_queued_cmd *qc)
505{ 513{
506 struct ahci_port_priv *pp = qc->ap->private_data; 514 struct ata_port *ap = qc->ap;
515 struct ahci_port_priv *pp = ap->private_data;
507 u32 opts; 516 u32 opts;
508 const u32 cmd_fis_len = 5; /* five dwords */ 517 const u32 cmd_fis_len = 5; /* five dwords */
509 518
@@ -515,18 +524,8 @@ static void ahci_qc_prep(struct ata_queued_cmd *qc)
515 opts = (qc->n_elem << 16) | cmd_fis_len; 524 opts = (qc->n_elem << 16) | cmd_fis_len;
516 if (qc->tf.flags & ATA_TFLAG_WRITE) 525 if (qc->tf.flags & ATA_TFLAG_WRITE)
517 opts |= AHCI_CMD_WRITE; 526 opts |= AHCI_CMD_WRITE;
518 527 if (is_atapi_taskfile(&qc->tf))
519 switch (qc->tf.protocol) {
520 case ATA_PROT_ATAPI:
521 case ATA_PROT_ATAPI_NODATA:
522 case ATA_PROT_ATAPI_DMA:
523 opts |= AHCI_CMD_ATAPI; 528 opts |= AHCI_CMD_ATAPI;
524 break;
525
526 default:
527 /* do nothing */
528 break;
529 }
530 529
531 pp->cmd_slot[0].opts = cpu_to_le32(opts); 530 pp->cmd_slot[0].opts = cpu_to_le32(opts);
532 pp->cmd_slot[0].status = 0; 531 pp->cmd_slot[0].status = 0;
@@ -538,6 +537,10 @@ static void ahci_qc_prep(struct ata_queued_cmd *qc)
538 * a SATA Register - Host to Device command FIS. 537 * a SATA Register - Host to Device command FIS.
539 */ 538 */
540 ata_tf_to_fis(&qc->tf, pp->cmd_tbl, 0); 539 ata_tf_to_fis(&qc->tf, pp->cmd_tbl, 0);
540 if (opts & AHCI_CMD_ATAPI) {
541 memset(pp->cmd_tbl + AHCI_CMD_TBL_CDB, 0, 32);
542 memcpy(pp->cmd_tbl + AHCI_CMD_TBL_CDB, qc->cdb, ap->cdb_len);
543 }
541 544
542 if (!(qc->flags & ATA_QCFLAG_DMAMAP)) 545 if (!(qc->flags & ATA_QCFLAG_DMAMAP))
543 return; 546 return;
@@ -792,8 +795,6 @@ static int ahci_host_init(struct ata_probe_ent *probe_ent)
792 return rc; 795 return rc;
793 } 796 }
794 } 797 }
795
796 hpriv->flags |= HOST_CAP_64;
797 } else { 798 } else {
798 rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK); 799 rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
799 if (rc) { 800 if (rc) {
@@ -876,15 +877,19 @@ static int ahci_host_init(struct ata_probe_ent *probe_ent)
876} 877}
877 878
878/* move to PCI layer, integrate w/ MSI stuff */ 879/* move to PCI layer, integrate w/ MSI stuff */
879static void pci_enable_intx(struct pci_dev *pdev) 880static void pci_intx(struct pci_dev *pdev, int enable)
880{ 881{
881 u16 pci_command; 882 u16 pci_command, new;
882 883
883 pci_read_config_word(pdev, PCI_COMMAND, &pci_command); 884 pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
884 if (pci_command & PCI_COMMAND_INTX_DISABLE) { 885
885 pci_command &= ~PCI_COMMAND_INTX_DISABLE; 886 if (enable)
887 new = pci_command & ~PCI_COMMAND_INTX_DISABLE;
888 else
889 new = pci_command | PCI_COMMAND_INTX_DISABLE;
890
891 if (new != pci_command)
886 pci_write_config_word(pdev, PCI_COMMAND, pci_command); 892 pci_write_config_word(pdev, PCI_COMMAND, pci_command);
887 }
888} 893}
889 894
890static void ahci_print_info(struct ata_probe_ent *probe_ent) 895static void ahci_print_info(struct ata_probe_ent *probe_ent)
@@ -966,7 +971,7 @@ static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
966 unsigned long base; 971 unsigned long base;
967 void *mmio_base; 972 void *mmio_base;
968 unsigned int board_idx = (unsigned int) ent->driver_data; 973 unsigned int board_idx = (unsigned int) ent->driver_data;
969 int pci_dev_busy = 0; 974 int have_msi, pci_dev_busy = 0;
970 int rc; 975 int rc;
971 976
972 VPRINTK("ENTER\n"); 977 VPRINTK("ENTER\n");
@@ -984,12 +989,17 @@ static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
984 goto err_out; 989 goto err_out;
985 } 990 }
986 991
987 pci_enable_intx(pdev); 992 if (pci_enable_msi(pdev) == 0)
993 have_msi = 1;
994 else {
995 pci_intx(pdev, 1);
996 have_msi = 0;
997 }
988 998
989 probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL); 999 probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL);
990 if (probe_ent == NULL) { 1000 if (probe_ent == NULL) {
991 rc = -ENOMEM; 1001 rc = -ENOMEM;
992 goto err_out_regions; 1002 goto err_out_msi;
993 } 1003 }
994 1004
995 memset(probe_ent, 0, sizeof(*probe_ent)); 1005 memset(probe_ent, 0, sizeof(*probe_ent));
@@ -1022,6 +1032,9 @@ static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
1022 probe_ent->mmio_base = mmio_base; 1032 probe_ent->mmio_base = mmio_base;
1023 probe_ent->private_data = hpriv; 1033 probe_ent->private_data = hpriv;
1024 1034
1035 if (have_msi)
1036 hpriv->flags |= AHCI_FLAG_MSI;
1037
1025 /* initialize adapter */ 1038 /* initialize adapter */
1026 rc = ahci_host_init(probe_ent); 1039 rc = ahci_host_init(probe_ent);
1027 if (rc) 1040 if (rc)
@@ -1041,7 +1054,11 @@ err_out_iounmap:
1041 iounmap(mmio_base); 1054 iounmap(mmio_base);
1042err_out_free_ent: 1055err_out_free_ent:
1043 kfree(probe_ent); 1056 kfree(probe_ent);
1044err_out_regions: 1057err_out_msi:
1058 if (have_msi)
1059 pci_disable_msi(pdev);
1060 else
1061 pci_intx(pdev, 0);
1045 pci_release_regions(pdev); 1062 pci_release_regions(pdev);
1046err_out: 1063err_out:
1047 if (!pci_dev_busy) 1064 if (!pci_dev_busy)
@@ -1049,6 +1066,42 @@ err_out:
1049 return rc; 1066 return rc;
1050} 1067}
1051 1068
1069static void ahci_remove_one (struct pci_dev *pdev)
1070{
1071 struct device *dev = pci_dev_to_dev(pdev);
1072 struct ata_host_set *host_set = dev_get_drvdata(dev);
1073 struct ahci_host_priv *hpriv = host_set->private_data;
1074 struct ata_port *ap;
1075 unsigned int i;
1076 int have_msi;
1077
1078 for (i = 0; i < host_set->n_ports; i++) {
1079 ap = host_set->ports[i];
1080
1081 scsi_remove_host(ap->host);
1082 }
1083
1084 have_msi = hpriv->flags & AHCI_FLAG_MSI;
1085 free_irq(host_set->irq, host_set);
1086
1087 for (i = 0; i < host_set->n_ports; i++) {
1088 ap = host_set->ports[i];
1089
1090 ata_scsi_release(ap->host);
1091 scsi_host_put(ap->host);
1092 }
1093
1094 host_set->ops->host_stop(host_set);
1095 kfree(host_set);
1096
1097 if (have_msi)
1098 pci_disable_msi(pdev);
1099 else
1100 pci_intx(pdev, 0);
1101 pci_release_regions(pdev);
1102 pci_disable_device(pdev);
1103 dev_set_drvdata(dev, NULL);
1104}
1052 1105
1053static int __init ahci_init(void) 1106static int __init ahci_init(void)
1054{ 1107{