diff options
| -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 */ |
