aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/sata_mv.c
diff options
context:
space:
mode:
authorJeff Garzik <jgarzik@pobox.com>2005-11-17 10:59:48 -0500
committerJeff Garzik <jgarzik@pobox.com>2005-11-17 10:59:48 -0500
commit22374677d18c5eeefd3a283431d312b8c44fef02 (patch)
tree4d923291cdab7c84e0346a8500f090f2b11e2bc1 /drivers/scsi/sata_mv.c
parent64f043d80752a8e5f0d55255e7bb9a1a05af206f (diff)
[libata sata_mv] SATA probe, DMA boundary fixes
- DMA boundary was being handled incorrectly. Copied the code from ata_fill_sg(), since Marvell has the same DMA boundary needs. (we can't use ata_fill_sg directly since we have different hardware descriptors) - cleaned up the SATA phy reset code, to deal with various errata
Diffstat (limited to 'drivers/scsi/sata_mv.c')
-rw-r--r--drivers/scsi/sata_mv.c88
1 files changed, 70 insertions, 18 deletions
diff --git a/drivers/scsi/sata_mv.c b/drivers/scsi/sata_mv.c
index 722ab537b7a6..ee0634da0872 100644
--- a/drivers/scsi/sata_mv.c
+++ b/drivers/scsi/sata_mv.c
@@ -321,6 +321,7 @@ static void mv_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val);
321static u32 mv5_scr_read(struct ata_port *ap, unsigned int sc_reg_in); 321static u32 mv5_scr_read(struct ata_port *ap, unsigned int sc_reg_in);
322static void mv5_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val); 322static void mv5_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val);
323static void mv_phy_reset(struct ata_port *ap); 323static void mv_phy_reset(struct ata_port *ap);
324static void __mv_phy_reset(struct ata_port *ap, int can_sleep);
324static void mv_host_stop(struct ata_host_set *host_set); 325static void mv_host_stop(struct ata_host_set *host_set);
325static int mv_port_start(struct ata_port *ap); 326static int mv_port_start(struct ata_port *ap);
326static void mv_port_stop(struct ata_port *ap); 327static void mv_port_stop(struct ata_port *ap);
@@ -362,7 +363,7 @@ static struct scsi_host_template mv_sht = {
362 .eh_strategy_handler = ata_scsi_error, 363 .eh_strategy_handler = ata_scsi_error,
363 .can_queue = MV_USE_Q_DEPTH, 364 .can_queue = MV_USE_Q_DEPTH,
364 .this_id = ATA_SHT_THIS_ID, 365 .this_id = ATA_SHT_THIS_ID,
365 .sg_tablesize = MV_MAX_SG_CT, 366 .sg_tablesize = MV_MAX_SG_CT / 2,
366 .max_sectors = ATA_MAX_SECTORS, 367 .max_sectors = ATA_MAX_SECTORS,
367 .cmd_per_lun = ATA_SHT_CMD_PER_LUN, 368 .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
368 .emulated = ATA_SHT_EMULATED, 369 .emulated = ATA_SHT_EMULATED,
@@ -893,20 +894,30 @@ static void mv_fill_sg(struct ata_queued_cmd *qc)
893 struct scatterlist *sg; 894 struct scatterlist *sg;
894 895
895 ata_for_each_sg(sg, qc) { 896 ata_for_each_sg(sg, qc) {
896 u32 sg_len;
897 dma_addr_t addr; 897 dma_addr_t addr;
898 u32 sg_len, len, offset;
898 899
899 addr = sg_dma_address(sg); 900 addr = sg_dma_address(sg);
900 sg_len = sg_dma_len(sg); 901 sg_len = sg_dma_len(sg);
901 902
902 pp->sg_tbl[i].addr = cpu_to_le32(addr & 0xffffffff); 903 while (sg_len) {
903 pp->sg_tbl[i].addr_hi = cpu_to_le32((addr >> 16) >> 16); 904 offset = addr & MV_DMA_BOUNDARY;
904 assert(0 == (sg_len & ~MV_DMA_BOUNDARY)); 905 len = sg_len;
905 pp->sg_tbl[i].flags_size = cpu_to_le32(sg_len); 906 if ((offset + sg_len) > 0x10000)
906 if (ata_sg_is_last(sg, qc)) 907 len = 0x10000 - offset;
907 pp->sg_tbl[i].flags_size |= cpu_to_le32(EPRD_FLAG_END_OF_TBL);
908 908
909 i++; 909 pp->sg_tbl[i].addr = cpu_to_le32(addr & 0xffffffff);
910 pp->sg_tbl[i].addr_hi = cpu_to_le32((addr >> 16) >> 16);
911 pp->sg_tbl[i].flags_size = cpu_to_le32(len);
912
913 sg_len -= len;
914 addr += len;
915
916 if (!sg_len && ata_sg_is_last(sg, qc))
917 pp->sg_tbl[i].flags_size |= cpu_to_le32(EPRD_FLAG_END_OF_TBL);
918
919 i++;
920 }
910 } 921 }
911} 922}
912 923
@@ -1693,11 +1704,19 @@ static void mv_stop_and_reset(struct ata_port *ap)
1693 1704
1694 mv_channel_reset(hpriv, mmio, ap->port_no); 1705 mv_channel_reset(hpriv, mmio, ap->port_no);
1695 1706
1696 mv_phy_reset(ap); 1707 __mv_phy_reset(ap, 0);
1708}
1709
1710static inline void __msleep(unsigned int msec, int can_sleep)
1711{
1712 if (can_sleep)
1713 msleep(msec);
1714 else
1715 mdelay(msec);
1697} 1716}
1698 1717
1699/** 1718/**
1700 * mv_phy_reset - Perform eDMA reset followed by COMRESET 1719 * __mv_phy_reset - Perform eDMA reset followed by COMRESET
1701 * @ap: ATA channel to manipulate 1720 * @ap: ATA channel to manipulate
1702 * 1721 *
1703 * Part of this is taken from __sata_phy_reset and modified to 1722 * Part of this is taken from __sata_phy_reset and modified to
@@ -1707,13 +1726,16 @@ static void mv_stop_and_reset(struct ata_port *ap)
1707 * Inherited from caller. This is coded to safe to call at 1726 * Inherited from caller. This is coded to safe to call at
1708 * interrupt level, i.e. it does not sleep. 1727 * interrupt level, i.e. it does not sleep.
1709 */ 1728 */
1710static void mv_phy_reset(struct ata_port *ap) 1729static void __mv_phy_reset(struct ata_port *ap, int can_sleep)
1711{ 1730{
1712 struct mv_port_priv *pp = ap->private_data; 1731 struct mv_port_priv *pp = ap->private_data;
1732 struct mv_host_priv *hpriv = ap->host_set->private_data;
1713 void __iomem *port_mmio = mv_ap_base(ap); 1733 void __iomem *port_mmio = mv_ap_base(ap);
1714 struct ata_taskfile tf; 1734 struct ata_taskfile tf;
1715 struct ata_device *dev = &ap->device[0]; 1735 struct ata_device *dev = &ap->device[0];
1716 unsigned long timeout; 1736 unsigned long timeout;
1737 int retry = 5;
1738 u32 sstatus;
1717 1739
1718 VPRINTK("ENTER, port %u, mmio 0x%p\n", ap->port_no, port_mmio); 1740 VPRINTK("ENTER, port %u, mmio 0x%p\n", ap->port_no, port_mmio);
1719 1741
@@ -1721,18 +1743,28 @@ static void mv_phy_reset(struct ata_port *ap)
1721 "SCtrl 0x%08x\n", mv_scr_read(ap, SCR_STATUS), 1743 "SCtrl 0x%08x\n", mv_scr_read(ap, SCR_STATUS),
1722 mv_scr_read(ap, SCR_ERROR), mv_scr_read(ap, SCR_CONTROL)); 1744 mv_scr_read(ap, SCR_ERROR), mv_scr_read(ap, SCR_CONTROL));
1723 1745
1724 /* proceed to init communications via the scr_control reg */ 1746 /* Issue COMRESET via SControl */
1747comreset_retry:
1725 scr_write_flush(ap, SCR_CONTROL, 0x301); 1748 scr_write_flush(ap, SCR_CONTROL, 0x301);
1726 mdelay(1); 1749 __msleep(1, can_sleep);
1750
1727 scr_write_flush(ap, SCR_CONTROL, 0x300); 1751 scr_write_flush(ap, SCR_CONTROL, 0x300);
1728 timeout = jiffies + (HZ * 1); 1752 __msleep(20, can_sleep);
1753
1754 timeout = jiffies + msecs_to_jiffies(200);
1729 do { 1755 do {
1730 mdelay(10); 1756 sstatus = scr_read(ap, SCR_STATUS) & 0x3;
1731 if ((scr_read(ap, SCR_STATUS) & 0xf) != 1) 1757 if ((sstatus == 3) || (sstatus == 0))
1732 break; 1758 break;
1759
1760 __msleep(1, can_sleep);
1733 } while (time_before(jiffies, timeout)); 1761 } while (time_before(jiffies, timeout));
1734 1762
1735 mv_scr_write(ap, SCR_ERROR, mv_scr_read(ap, SCR_ERROR)); 1763 /* work around errata */
1764 if (IS_60XX(hpriv) &&
1765 (sstatus != 0x0) && (sstatus != 0x113) && (sstatus != 0x123) &&
1766 (retry-- > 0))
1767 goto comreset_retry;
1736 1768
1737 DPRINTK("S-regs after PHY wake: SStat 0x%08x SErr 0x%08x " 1769 DPRINTK("S-regs after PHY wake: SStat 0x%08x SErr 0x%08x "
1738 "SCtrl 0x%08x\n", mv_scr_read(ap, SCR_STATUS), 1770 "SCtrl 0x%08x\n", mv_scr_read(ap, SCR_STATUS),
@@ -1748,6 +1780,21 @@ static void mv_phy_reset(struct ata_port *ap)
1748 } 1780 }
1749 ap->cbl = ATA_CBL_SATA; 1781 ap->cbl = ATA_CBL_SATA;
1750 1782
1783 /* even after SStatus reflects that device is ready,
1784 * it seems to take a while for link to be fully
1785 * established (and thus Status no longer 0x80/0x7F),
1786 * so we poll a bit for that, here.
1787 */
1788 retry = 20;
1789 while (1) {
1790 u8 drv_stat = ata_check_status(ap);
1791 if ((drv_stat != 0x80) && (drv_stat != 0x7f))
1792 break;
1793 __msleep(500, can_sleep);
1794 if (retry-- <= 0)
1795 break;
1796 }
1797
1751 tf.lbah = readb((void __iomem *) ap->ioaddr.lbah_addr); 1798 tf.lbah = readb((void __iomem *) ap->ioaddr.lbah_addr);
1752 tf.lbam = readb((void __iomem *) ap->ioaddr.lbam_addr); 1799 tf.lbam = readb((void __iomem *) ap->ioaddr.lbam_addr);
1753 tf.lbal = readb((void __iomem *) ap->ioaddr.lbal_addr); 1800 tf.lbal = readb((void __iomem *) ap->ioaddr.lbal_addr);
@@ -1766,6 +1813,11 @@ static void mv_phy_reset(struct ata_port *ap)
1766 VPRINTK("EXIT\n"); 1813 VPRINTK("EXIT\n");
1767} 1814}
1768 1815
1816static void mv_phy_reset(struct ata_port *ap)
1817{
1818 __mv_phy_reset(ap, 1);
1819}
1820
1769/** 1821/**
1770 * mv_eng_timeout - Routine called by libata when SCSI times out I/O 1822 * mv_eng_timeout - Routine called by libata when SCSI times out I/O
1771 * @ap: ATA channel to manipulate 1823 * @ap: ATA channel to manipulate