aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/sata_sil24.c68
1 files changed, 47 insertions, 21 deletions
diff --git a/drivers/scsi/sata_sil24.c b/drivers/scsi/sata_sil24.c
index 6e7728cfaf6b..4c76f05d9b65 100644
--- a/drivers/scsi/sata_sil24.c
+++ b/drivers/scsi/sata_sil24.c
@@ -216,6 +216,8 @@ enum {
216 SGE_DRD = (1 << 29), /* discard data read (/dev/null) 216 SGE_DRD = (1 << 29), /* discard data read (/dev/null)
217 data address ignored */ 217 data address ignored */
218 218
219 SIL24_MAX_CMDS = 31,
220
219 /* board id */ 221 /* board id */
220 BID_SIL3124 = 0, 222 BID_SIL3124 = 0,
221 BID_SIL3132 = 1, 223 BID_SIL3132 = 1,
@@ -223,7 +225,8 @@ enum {
223 225
224 /* host flags */ 226 /* host flags */
225 SIL24_COMMON_FLAGS = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | 227 SIL24_COMMON_FLAGS = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
226 ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA, 228 ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
229 ATA_FLAG_NCQ,
227 SIL24_FLAG_PCIX_IRQ_WOC = (1 << 24), /* IRQ loss errata on PCI-X */ 230 SIL24_FLAG_PCIX_IRQ_WOC = (1 << 24), /* IRQ loss errata on PCI-X */
228 231
229 IRQ_STAT_4PORTS = 0xf, 232 IRQ_STAT_4PORTS = 0xf,
@@ -355,7 +358,8 @@ static struct scsi_host_template sil24_sht = {
355 .name = DRV_NAME, 358 .name = DRV_NAME,
356 .ioctl = ata_scsi_ioctl, 359 .ioctl = ata_scsi_ioctl,
357 .queuecommand = ata_scsi_queuecmd, 360 .queuecommand = ata_scsi_queuecmd,
358 .can_queue = ATA_DEF_QUEUE, 361 .change_queue_depth = ata_scsi_change_queue_depth,
362 .can_queue = SIL24_MAX_CMDS,
359 .this_id = ATA_SHT_THIS_ID, 363 .this_id = ATA_SHT_THIS_ID,
360 .sg_tablesize = LIBATA_MAX_PRD, 364 .sg_tablesize = LIBATA_MAX_PRD,
361 .cmd_per_lun = ATA_SHT_CMD_PER_LUN, 365 .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
@@ -437,6 +441,13 @@ static struct ata_port_info sil24_port_info[] = {
437 }, 441 },
438}; 442};
439 443
444static int sil24_tag(int tag)
445{
446 if (unlikely(ata_tag_internal(tag)))
447 return 0;
448 return tag;
449}
450
440static void sil24_dev_config(struct ata_port *ap, struct ata_device *dev) 451static void sil24_dev_config(struct ata_port *ap, struct ata_device *dev)
441{ 452{
442 void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr; 453 void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
@@ -649,14 +660,17 @@ static void sil24_qc_prep(struct ata_queued_cmd *qc)
649{ 660{
650 struct ata_port *ap = qc->ap; 661 struct ata_port *ap = qc->ap;
651 struct sil24_port_priv *pp = ap->private_data; 662 struct sil24_port_priv *pp = ap->private_data;
652 union sil24_cmd_block *cb = pp->cmd_block + qc->tag; 663 union sil24_cmd_block *cb;
653 struct sil24_prb *prb; 664 struct sil24_prb *prb;
654 struct sil24_sge *sge; 665 struct sil24_sge *sge;
655 u16 ctrl = 0; 666 u16 ctrl = 0;
656 667
668 cb = &pp->cmd_block[sil24_tag(qc->tag)];
669
657 switch (qc->tf.protocol) { 670 switch (qc->tf.protocol) {
658 case ATA_PROT_PIO: 671 case ATA_PROT_PIO:
659 case ATA_PROT_DMA: 672 case ATA_PROT_DMA:
673 case ATA_PROT_NCQ:
660 case ATA_PROT_NODATA: 674 case ATA_PROT_NODATA:
661 prb = &cb->ata.prb; 675 prb = &cb->ata.prb;
662 sge = cb->ata.sge; 676 sge = cb->ata.sge;
@@ -694,12 +708,17 @@ static void sil24_qc_prep(struct ata_queued_cmd *qc)
694static unsigned int sil24_qc_issue(struct ata_queued_cmd *qc) 708static unsigned int sil24_qc_issue(struct ata_queued_cmd *qc)
695{ 709{
696 struct ata_port *ap = qc->ap; 710 struct ata_port *ap = qc->ap;
697 void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
698 struct sil24_port_priv *pp = ap->private_data; 711 struct sil24_port_priv *pp = ap->private_data;
699 dma_addr_t paddr = pp->cmd_block_dma + qc->tag * sizeof(*pp->cmd_block); 712 void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
713 unsigned int tag = sil24_tag(qc->tag);
714 dma_addr_t paddr;
715 void __iomem *activate;
700 716
701 writel((u32)paddr, port + PORT_CMD_ACTIVATE); 717 paddr = pp->cmd_block_dma + tag * sizeof(*pp->cmd_block);
702 writel((u64)paddr >> 32, port + PORT_CMD_ACTIVATE + 4); 718 activate = port + PORT_CMD_ACTIVATE + tag * 8;
719
720 writel((u32)paddr, activate);
721 writel((u64)paddr >> 32, activate + 4);
703 722
704 return 0; 723 return 0;
705} 724}
@@ -791,9 +810,6 @@ static void sil24_error_intr(struct ata_port *ap)
791 /* record error info */ 810 /* record error info */
792 qc = ata_qc_from_tag(ap, ap->active_tag); 811 qc = ata_qc_from_tag(ap, ap->active_tag);
793 if (qc) { 812 if (qc) {
794 int tag = qc->tag;
795 if (unlikely(ata_tag_internal(tag)))
796 tag = 0;
797 sil24_update_tf(ap); 813 sil24_update_tf(ap);
798 qc->err_mask |= err_mask; 814 qc->err_mask |= err_mask;
799 } else 815 } else
@@ -809,11 +825,17 @@ static void sil24_error_intr(struct ata_port *ap)
809 ata_port_abort(ap); 825 ata_port_abort(ap);
810} 826}
811 827
828static void sil24_finish_qc(struct ata_queued_cmd *qc)
829{
830 if (qc->flags & ATA_QCFLAG_RESULT_TF)
831 sil24_update_tf(qc->ap);
832}
833
812static inline void sil24_host_intr(struct ata_port *ap) 834static inline void sil24_host_intr(struct ata_port *ap)
813{ 835{
814 void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr; 836 void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
815 struct ata_queued_cmd *qc; 837 u32 slot_stat, qc_active;
816 u32 slot_stat; 838 int rc;
817 839
818 slot_stat = readl(port + PORT_SLOT_STAT); 840 slot_stat = readl(port + PORT_SLOT_STAT);
819 841
@@ -825,18 +847,22 @@ static inline void sil24_host_intr(struct ata_port *ap)
825 if (ap->flags & SIL24_FLAG_PCIX_IRQ_WOC) 847 if (ap->flags & SIL24_FLAG_PCIX_IRQ_WOC)
826 writel(PORT_IRQ_COMPLETE, port + PORT_IRQ_STAT); 848 writel(PORT_IRQ_COMPLETE, port + PORT_IRQ_STAT);
827 849
828 qc = ata_qc_from_tag(ap, ap->active_tag); 850 qc_active = slot_stat & ~HOST_SSTAT_ATTN;
829 if (qc) { 851 rc = ata_qc_complete_multiple(ap, qc_active, sil24_finish_qc);
830 if (qc->flags & ATA_QCFLAG_RESULT_TF) 852 if (rc > 0)
831 sil24_update_tf(ap); 853 return;
832 ata_qc_complete(qc); 854 if (rc < 0) {
855 struct ata_eh_info *ehi = &ap->eh_info;
856 ehi->err_mask |= AC_ERR_HSM;
857 ehi->action |= ATA_EH_SOFTRESET;
858 ata_port_freeze(ap);
833 return; 859 return;
834 } 860 }
835 861
836 if (ata_ratelimit()) 862 if (ata_ratelimit())
837 ata_port_printk(ap, KERN_INFO, "spurious interrupt " 863 ata_port_printk(ap, KERN_INFO, "spurious interrupt "
838 "(slot_stat 0x%x active_tag %d)\n", 864 "(slot_stat 0x%x active_tag %d sactive 0x%x)\n",
839 slot_stat, ap->active_tag); 865 slot_stat, ap->active_tag, ap->sactive);
840} 866}
841 867
842static irqreturn_t sil24_interrupt(int irq, void *dev_instance, struct pt_regs *regs) 868static irqreturn_t sil24_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
@@ -903,7 +929,7 @@ static void sil24_post_internal_cmd(struct ata_queued_cmd *qc)
903 929
904static inline void sil24_cblk_free(struct sil24_port_priv *pp, struct device *dev) 930static inline void sil24_cblk_free(struct sil24_port_priv *pp, struct device *dev)
905{ 931{
906 const size_t cb_size = sizeof(*pp->cmd_block); 932 const size_t cb_size = sizeof(*pp->cmd_block) * SIL24_MAX_CMDS;
907 933
908 dma_free_coherent(dev, cb_size, pp->cmd_block, pp->cmd_block_dma); 934 dma_free_coherent(dev, cb_size, pp->cmd_block, pp->cmd_block_dma);
909} 935}
@@ -913,7 +939,7 @@ static int sil24_port_start(struct ata_port *ap)
913 struct device *dev = ap->host_set->dev; 939 struct device *dev = ap->host_set->dev;
914 struct sil24_port_priv *pp; 940 struct sil24_port_priv *pp;
915 union sil24_cmd_block *cb; 941 union sil24_cmd_block *cb;
916 size_t cb_size = sizeof(*cb); 942 size_t cb_size = sizeof(*cb) * SIL24_MAX_CMDS;
917 dma_addr_t cb_dma; 943 dma_addr_t cb_dma;
918 int rc = -ENOMEM; 944 int rc = -ENOMEM;
919 945