diff options
Diffstat (limited to 'drivers/scsi/ahci.c')
-rw-r--r-- | drivers/scsi/ahci.c | 89 |
1 files changed, 58 insertions, 31 deletions
diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c index 9f974dbcd7ed..45fd71d80128 100644 --- a/drivers/scsi/ahci.c +++ b/drivers/scsi/ahci.c | |||
@@ -56,9 +56,9 @@ enum { | |||
56 | AHCI_MAX_SG = 168, /* hardware max is 64K */ | 56 | AHCI_MAX_SG = 168, /* hardware max is 64K */ |
57 | AHCI_DMA_BOUNDARY = 0xffffffff, | 57 | AHCI_DMA_BOUNDARY = 0xffffffff, |
58 | AHCI_USE_CLUSTERING = 0, | 58 | AHCI_USE_CLUSTERING = 0, |
59 | AHCI_MAX_CMDS = 1, | 59 | AHCI_MAX_CMDS = 32, |
60 | AHCI_CMD_SZ = 32, | 60 | AHCI_CMD_SZ = 32, |
61 | AHCI_CMD_SLOT_SZ = 32 * AHCI_CMD_SZ, | 61 | AHCI_CMD_SLOT_SZ = AHCI_MAX_CMDS * AHCI_CMD_SZ, |
62 | AHCI_RX_FIS_SZ = 256, | 62 | AHCI_RX_FIS_SZ = 256, |
63 | AHCI_CMD_TBL_CDB = 0x40, | 63 | AHCI_CMD_TBL_CDB = 0x40, |
64 | AHCI_CMD_TBL_HDR_SZ = 0x80, | 64 | AHCI_CMD_TBL_HDR_SZ = 0x80, |
@@ -218,7 +218,8 @@ static struct scsi_host_template ahci_sht = { | |||
218 | .name = DRV_NAME, | 218 | .name = DRV_NAME, |
219 | .ioctl = ata_scsi_ioctl, | 219 | .ioctl = ata_scsi_ioctl, |
220 | .queuecommand = ata_scsi_queuecmd, | 220 | .queuecommand = ata_scsi_queuecmd, |
221 | .can_queue = ATA_DEF_QUEUE, | 221 | .change_queue_depth = ata_scsi_change_queue_depth, |
222 | .can_queue = AHCI_MAX_CMDS - 1, | ||
222 | .this_id = ATA_SHT_THIS_ID, | 223 | .this_id = ATA_SHT_THIS_ID, |
223 | .sg_tablesize = AHCI_MAX_SG, | 224 | .sg_tablesize = AHCI_MAX_SG, |
224 | .cmd_per_lun = ATA_SHT_CMD_PER_LUN, | 225 | .cmd_per_lun = ATA_SHT_CMD_PER_LUN, |
@@ -533,12 +534,17 @@ static unsigned int ahci_dev_classify(struct ata_port *ap) | |||
533 | return ata_dev_classify(&tf); | 534 | return ata_dev_classify(&tf); |
534 | } | 535 | } |
535 | 536 | ||
536 | static void ahci_fill_cmd_slot(struct ahci_port_priv *pp, u32 opts) | 537 | static void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag, |
538 | u32 opts) | ||
537 | { | 539 | { |
538 | pp->cmd_slot[0].opts = cpu_to_le32(opts); | 540 | dma_addr_t cmd_tbl_dma; |
539 | pp->cmd_slot[0].status = 0; | 541 | |
540 | pp->cmd_slot[0].tbl_addr = cpu_to_le32(pp->cmd_tbl_dma & 0xffffffff); | 542 | cmd_tbl_dma = pp->cmd_tbl_dma + tag * AHCI_CMD_TBL_SZ; |
541 | pp->cmd_slot[0].tbl_addr_hi = cpu_to_le32((pp->cmd_tbl_dma >> 16) >> 16); | 543 | |
544 | pp->cmd_slot[tag].opts = cpu_to_le32(opts); | ||
545 | pp->cmd_slot[tag].status = 0; | ||
546 | pp->cmd_slot[tag].tbl_addr = cpu_to_le32(cmd_tbl_dma & 0xffffffff); | ||
547 | pp->cmd_slot[tag].tbl_addr_hi = cpu_to_le32((cmd_tbl_dma >> 16) >> 16); | ||
542 | } | 548 | } |
543 | 549 | ||
544 | static int ahci_clo(struct ata_port *ap) | 550 | static int ahci_clo(struct ata_port *ap) |
@@ -610,7 +616,8 @@ static int ahci_softreset(struct ata_port *ap, unsigned int *class) | |||
610 | fis = pp->cmd_tbl; | 616 | fis = pp->cmd_tbl; |
611 | 617 | ||
612 | /* issue the first D2H Register FIS */ | 618 | /* issue the first D2H Register FIS */ |
613 | ahci_fill_cmd_slot(pp, cmd_fis_len | AHCI_CMD_RESET | AHCI_CMD_CLR_BUSY); | 619 | ahci_fill_cmd_slot(pp, 0, |
620 | cmd_fis_len | AHCI_CMD_RESET | AHCI_CMD_CLR_BUSY); | ||
614 | 621 | ||
615 | tf.ctl |= ATA_SRST; | 622 | tf.ctl |= ATA_SRST; |
616 | ata_tf_to_fis(&tf, fis, 0); | 623 | ata_tf_to_fis(&tf, fis, 0); |
@@ -629,7 +636,7 @@ static int ahci_softreset(struct ata_port *ap, unsigned int *class) | |||
629 | msleep(1); | 636 | msleep(1); |
630 | 637 | ||
631 | /* issue the second D2H Register FIS */ | 638 | /* issue the second D2H Register FIS */ |
632 | ahci_fill_cmd_slot(pp, cmd_fis_len); | 639 | ahci_fill_cmd_slot(pp, 0, cmd_fis_len); |
633 | 640 | ||
634 | tf.ctl &= ~ATA_SRST; | 641 | tf.ctl &= ~ATA_SRST; |
635 | ata_tf_to_fis(&tf, fis, 0); | 642 | ata_tf_to_fis(&tf, fis, 0); |
@@ -734,9 +741,8 @@ static void ahci_tf_read(struct ata_port *ap, struct ata_taskfile *tf) | |||
734 | ata_tf_from_fis(d2h_fis, tf); | 741 | ata_tf_from_fis(d2h_fis, tf); |
735 | } | 742 | } |
736 | 743 | ||
737 | static unsigned int ahci_fill_sg(struct ata_queued_cmd *qc) | 744 | static unsigned int ahci_fill_sg(struct ata_queued_cmd *qc, void *cmd_tbl) |
738 | { | 745 | { |
739 | struct ahci_port_priv *pp = qc->ap->private_data; | ||
740 | struct scatterlist *sg; | 746 | struct scatterlist *sg; |
741 | struct ahci_sg *ahci_sg; | 747 | struct ahci_sg *ahci_sg; |
742 | unsigned int n_sg = 0; | 748 | unsigned int n_sg = 0; |
@@ -746,7 +752,7 @@ static unsigned int ahci_fill_sg(struct ata_queued_cmd *qc) | |||
746 | /* | 752 | /* |
747 | * Next, the S/G list. | 753 | * Next, the S/G list. |
748 | */ | 754 | */ |
749 | ahci_sg = pp->cmd_tbl + AHCI_CMD_TBL_HDR_SZ; | 755 | ahci_sg = cmd_tbl + AHCI_CMD_TBL_HDR_SZ; |
750 | ata_for_each_sg(sg, qc) { | 756 | ata_for_each_sg(sg, qc) { |
751 | dma_addr_t addr = sg_dma_address(sg); | 757 | dma_addr_t addr = sg_dma_address(sg); |
752 | u32 sg_len = sg_dma_len(sg); | 758 | u32 sg_len = sg_dma_len(sg); |
@@ -767,6 +773,7 @@ static void ahci_qc_prep(struct ata_queued_cmd *qc) | |||
767 | struct ata_port *ap = qc->ap; | 773 | struct ata_port *ap = qc->ap; |
768 | struct ahci_port_priv *pp = ap->private_data; | 774 | struct ahci_port_priv *pp = ap->private_data; |
769 | int is_atapi = is_atapi_taskfile(&qc->tf); | 775 | int is_atapi = is_atapi_taskfile(&qc->tf); |
776 | void *cmd_tbl; | ||
770 | u32 opts; | 777 | u32 opts; |
771 | const u32 cmd_fis_len = 5; /* five dwords */ | 778 | const u32 cmd_fis_len = 5; /* five dwords */ |
772 | unsigned int n_elem; | 779 | unsigned int n_elem; |
@@ -775,16 +782,17 @@ static void ahci_qc_prep(struct ata_queued_cmd *qc) | |||
775 | * Fill in command table information. First, the header, | 782 | * Fill in command table information. First, the header, |
776 | * a SATA Register - Host to Device command FIS. | 783 | * a SATA Register - Host to Device command FIS. |
777 | */ | 784 | */ |
778 | ata_tf_to_fis(&qc->tf, pp->cmd_tbl, 0); | 785 | cmd_tbl = pp->cmd_tbl + qc->tag * AHCI_CMD_TBL_SZ; |
786 | |||
787 | ata_tf_to_fis(&qc->tf, cmd_tbl, 0); | ||
779 | if (is_atapi) { | 788 | if (is_atapi) { |
780 | memset(pp->cmd_tbl + AHCI_CMD_TBL_CDB, 0, 32); | 789 | memset(cmd_tbl + AHCI_CMD_TBL_CDB, 0, 32); |
781 | memcpy(pp->cmd_tbl + AHCI_CMD_TBL_CDB, qc->cdb, | 790 | memcpy(cmd_tbl + AHCI_CMD_TBL_CDB, qc->cdb, qc->dev->cdb_len); |
782 | qc->dev->cdb_len); | ||
783 | } | 791 | } |
784 | 792 | ||
785 | n_elem = 0; | 793 | n_elem = 0; |
786 | if (qc->flags & ATA_QCFLAG_DMAMAP) | 794 | if (qc->flags & ATA_QCFLAG_DMAMAP) |
787 | n_elem = ahci_fill_sg(qc); | 795 | n_elem = ahci_fill_sg(qc, cmd_tbl); |
788 | 796 | ||
789 | /* | 797 | /* |
790 | * Fill in command slot information. | 798 | * Fill in command slot information. |
@@ -795,7 +803,7 @@ static void ahci_qc_prep(struct ata_queued_cmd *qc) | |||
795 | if (is_atapi) | 803 | if (is_atapi) |
796 | opts |= AHCI_CMD_ATAPI | AHCI_CMD_PREFETCH; | 804 | opts |= AHCI_CMD_ATAPI | AHCI_CMD_PREFETCH; |
797 | 805 | ||
798 | ahci_fill_cmd_slot(pp, opts); | 806 | ahci_fill_cmd_slot(pp, qc->tag, opts); |
799 | } | 807 | } |
800 | 808 | ||
801 | static void ahci_error_intr(struct ata_port *ap, u32 irq_stat) | 809 | static void ahci_error_intr(struct ata_port *ap, u32 irq_stat) |
@@ -865,8 +873,9 @@ static void ahci_host_intr(struct ata_port *ap) | |||
865 | { | 873 | { |
866 | void __iomem *mmio = ap->host_set->mmio_base; | 874 | void __iomem *mmio = ap->host_set->mmio_base; |
867 | void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); | 875 | void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); |
868 | struct ata_queued_cmd *qc; | 876 | struct ata_eh_info *ehi = &ap->eh_info; |
869 | u32 status, ci; | 877 | u32 status, qc_active; |
878 | int rc; | ||
870 | 879 | ||
871 | status = readl(port_mmio + PORT_IRQ_STAT); | 880 | status = readl(port_mmio + PORT_IRQ_STAT); |
872 | writel(status, port_mmio + PORT_IRQ_STAT); | 881 | writel(status, port_mmio + PORT_IRQ_STAT); |
@@ -876,16 +885,27 @@ static void ahci_host_intr(struct ata_port *ap) | |||
876 | return; | 885 | return; |
877 | } | 886 | } |
878 | 887 | ||
879 | if ((qc = ata_qc_from_tag(ap, ap->active_tag))) { | 888 | if (ap->sactive) |
880 | ci = readl(port_mmio + PORT_CMD_ISSUE); | 889 | qc_active = readl(port_mmio + PORT_SCR_ACT); |
881 | if ((ci & 0x1) == 0) { | 890 | else |
882 | ata_qc_complete(qc); | 891 | qc_active = readl(port_mmio + PORT_CMD_ISSUE); |
883 | return; | 892 | |
884 | } | 893 | rc = ata_qc_complete_multiple(ap, qc_active, NULL); |
894 | if (rc > 0) | ||
895 | return; | ||
896 | if (rc < 0) { | ||
897 | ehi->err_mask |= AC_ERR_HSM; | ||
898 | ehi->action |= ATA_EH_SOFTRESET; | ||
899 | ata_port_freeze(ap); | ||
900 | return; | ||
885 | } | 901 | } |
886 | 902 | ||
887 | /* hmmm... a spurious interupt */ | 903 | /* hmmm... a spurious interupt */ |
888 | 904 | ||
905 | /* some devices send D2H reg with I bit set during NCQ command phase */ | ||
906 | if (ap->sactive && status & PORT_IRQ_D2H_REG_FIS) | ||
907 | return; | ||
908 | |||
889 | /* ignore interim PIO setup fis interrupts */ | 909 | /* ignore interim PIO setup fis interrupts */ |
890 | if (ata_tag_valid(ap->active_tag)) { | 910 | if (ata_tag_valid(ap->active_tag)) { |
891 | struct ata_queued_cmd *qc = | 911 | struct ata_queued_cmd *qc = |
@@ -898,8 +918,8 @@ static void ahci_host_intr(struct ata_port *ap) | |||
898 | 918 | ||
899 | if (ata_ratelimit()) | 919 | if (ata_ratelimit()) |
900 | ata_port_printk(ap, KERN_INFO, "spurious interrupt " | 920 | ata_port_printk(ap, KERN_INFO, "spurious interrupt " |
901 | "(irq_stat 0x%x active_tag %d)\n", | 921 | "(irq_stat 0x%x active_tag %d sactive 0x%x)\n", |
902 | status, ap->active_tag); | 922 | status, ap->active_tag, ap->sactive); |
903 | } | 923 | } |
904 | 924 | ||
905 | static void ahci_irq_clear(struct ata_port *ap) | 925 | static void ahci_irq_clear(struct ata_port *ap) |
@@ -907,7 +927,7 @@ static void ahci_irq_clear(struct ata_port *ap) | |||
907 | /* TODO */ | 927 | /* TODO */ |
908 | } | 928 | } |
909 | 929 | ||
910 | static irqreturn_t ahci_interrupt (int irq, void *dev_instance, struct pt_regs *regs) | 930 | static irqreturn_t ahci_interrupt(int irq, void *dev_instance, struct pt_regs *regs) |
911 | { | 931 | { |
912 | struct ata_host_set *host_set = dev_instance; | 932 | struct ata_host_set *host_set = dev_instance; |
913 | struct ahci_host_priv *hpriv; | 933 | struct ahci_host_priv *hpriv; |
@@ -965,7 +985,9 @@ static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc) | |||
965 | struct ata_port *ap = qc->ap; | 985 | struct ata_port *ap = qc->ap; |
966 | void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr; | 986 | void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr; |
967 | 987 | ||
968 | writel(1, port_mmio + PORT_CMD_ISSUE); | 988 | if (qc->tf.protocol == ATA_PROT_NCQ) |
989 | writel(1 << qc->tag, port_mmio + PORT_SCR_ACT); | ||
990 | writel(1 << qc->tag, port_mmio + PORT_CMD_ISSUE); | ||
969 | readl(port_mmio + PORT_CMD_ISSUE); /* flush */ | 991 | readl(port_mmio + PORT_CMD_ISSUE); /* flush */ |
970 | 992 | ||
971 | return 0; | 993 | return 0; |
@@ -1262,6 +1284,8 @@ static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1262 | 1284 | ||
1263 | VPRINTK("ENTER\n"); | 1285 | VPRINTK("ENTER\n"); |
1264 | 1286 | ||
1287 | WARN_ON(ATA_MAX_QUEUE > AHCI_MAX_CMDS); | ||
1288 | |||
1265 | if (!printed_version++) | 1289 | if (!printed_version++) |
1266 | dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); | 1290 | dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); |
1267 | 1291 | ||
@@ -1329,6 +1353,9 @@ static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1329 | if (rc) | 1353 | if (rc) |
1330 | goto err_out_hpriv; | 1354 | goto err_out_hpriv; |
1331 | 1355 | ||
1356 | if (hpriv->cap & HOST_CAP_NCQ) | ||
1357 | probe_ent->host_flags |= ATA_FLAG_NCQ; | ||
1358 | |||
1332 | ahci_print_info(probe_ent); | 1359 | ahci_print_info(probe_ent); |
1333 | 1360 | ||
1334 | /* FIXME: check ata_device_add return value */ | 1361 | /* FIXME: check ata_device_add return value */ |