aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2006-03-05 14:31:57 -0500
committerJeff Garzik <jeff@garzik.org>2006-03-11 19:03:39 -0500
commita6d5a51cf1bf5d83ddd2e06fd372a79b395fb393 (patch)
tree4dd9a341ed20444d9b66b9032b8d332069f54220
parent23e71c3d3e88b9f554ecd47d6f9aec76e89e2e6d (diff)
[PATCH] libata: reimplement ata_set_mode() using xfer_mask helpers
Use xfer_mask helpers to determine transfer mode. This rewrite also makes transfer mode determination done before any actual configuration. This patch doesn't result in any functional changes. Signed-off-by: Tejun Heo <htejun@gmail.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
-rw-r--r--drivers/scsi/libata-core.c233
1 files changed, 79 insertions, 154 deletions
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index 88495127efb2..d211f0b1d721 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -65,11 +65,9 @@ static unsigned int ata_dev_init_params(struct ata_port *ap,
65 struct ata_device *dev); 65 struct ata_device *dev);
66static void ata_set_mode(struct ata_port *ap); 66static void ata_set_mode(struct ata_port *ap);
67static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev); 67static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev);
68static unsigned int ata_get_mode_mask(const struct ata_port *ap, int shift); 68static unsigned int ata_dev_xfermask(struct ata_port *ap,
69 struct ata_device *dev);
69static int fgb(u32 bitmap); 70static int fgb(u32 bitmap);
70static int ata_choose_xfer_mode(const struct ata_port *ap,
71 u8 *xfer_mode_out,
72 unsigned int *xfer_shift_out);
73 71
74static unsigned int ata_unique_id = 1; 72static unsigned int ata_unique_id = 1;
75static struct workqueue_struct *ata_wq; 73static struct workqueue_struct *ata_wq;
@@ -1776,51 +1774,42 @@ static void ata_dev_set_mode(struct ata_port *ap, struct ata_device *dev)
1776 1774
1777static int ata_host_set_pio(struct ata_port *ap) 1775static int ata_host_set_pio(struct ata_port *ap)
1778{ 1776{
1779 unsigned int mask; 1777 int i;
1780 int x, i;
1781 u8 base, xfer_mode;
1782
1783 mask = ata_get_mode_mask(ap, ATA_SHIFT_PIO);
1784 x = fgb(mask);
1785 if (x < 0) {
1786 printk(KERN_WARNING "ata%u: no PIO support\n", ap->id);
1787 return -1;
1788 }
1789
1790 base = base_from_shift(ATA_SHIFT_PIO);
1791 xfer_mode = base + x;
1792
1793 DPRINTK("base 0x%x xfer_mode 0x%x mask 0x%x x %d\n",
1794 (int)base, (int)xfer_mode, mask, x);
1795 1778
1796 for (i = 0; i < ATA_MAX_DEVICES; i++) { 1779 for (i = 0; i < ATA_MAX_DEVICES; i++) {
1797 struct ata_device *dev = &ap->device[i]; 1780 struct ata_device *dev = &ap->device[i];
1798 if (ata_dev_present(dev)) { 1781
1799 dev->pio_mode = xfer_mode; 1782 if (!ata_dev_present(dev))
1800 dev->xfer_mode = xfer_mode; 1783 continue;
1801 dev->xfer_shift = ATA_SHIFT_PIO; 1784
1802 if (ap->ops->set_piomode) 1785 if (!dev->pio_mode) {
1803 ap->ops->set_piomode(ap, dev); 1786 printk(KERN_WARNING "ata%u: no PIO support\n", ap->id);
1787 return -1;
1804 } 1788 }
1789
1790 dev->xfer_mode = dev->pio_mode;
1791 dev->xfer_shift = ATA_SHIFT_PIO;
1792 if (ap->ops->set_piomode)
1793 ap->ops->set_piomode(ap, dev);
1805 } 1794 }
1806 1795
1807 return 0; 1796 return 0;
1808} 1797}
1809 1798
1810static void ata_host_set_dma(struct ata_port *ap, u8 xfer_mode, 1799static void ata_host_set_dma(struct ata_port *ap)
1811 unsigned int xfer_shift)
1812{ 1800{
1813 int i; 1801 int i;
1814 1802
1815 for (i = 0; i < ATA_MAX_DEVICES; i++) { 1803 for (i = 0; i < ATA_MAX_DEVICES; i++) {
1816 struct ata_device *dev = &ap->device[i]; 1804 struct ata_device *dev = &ap->device[i];
1817 if (ata_dev_present(dev)) { 1805
1818 dev->dma_mode = xfer_mode; 1806 if (!ata_dev_present(dev) || !dev->dma_mode)
1819 dev->xfer_mode = xfer_mode; 1807 continue;
1820 dev->xfer_shift = xfer_shift; 1808
1821 if (ap->ops->set_dmamode) 1809 dev->xfer_mode = dev->dma_mode;
1822 ap->ops->set_dmamode(ap, dev); 1810 dev->xfer_shift = ata_xfer_mode2shift(dev->dma_mode);
1823 } 1811 if (ap->ops->set_dmamode)
1812 ap->ops->set_dmamode(ap, dev);
1824 } 1813 }
1825} 1814}
1826 1815
@@ -1835,28 +1824,34 @@ static void ata_host_set_dma(struct ata_port *ap, u8 xfer_mode,
1835 */ 1824 */
1836static void ata_set_mode(struct ata_port *ap) 1825static void ata_set_mode(struct ata_port *ap)
1837{ 1826{
1838 unsigned int xfer_shift; 1827 int i, rc;
1839 u8 xfer_mode;
1840 int rc;
1841 1828
1842 /* step 1: always set host PIO timings */ 1829 /* step 1: calculate xfer_mask */
1843 rc = ata_host_set_pio(ap); 1830 for (i = 0; i < ATA_MAX_DEVICES; i++) {
1844 if (rc) 1831 struct ata_device *dev = &ap->device[i];
1845 goto err_out; 1832 unsigned int xfer_mask;
1833
1834 if (!ata_dev_present(dev))
1835 continue;
1846 1836
1847 /* step 2: choose the best data xfer mode */ 1837 xfer_mask = ata_dev_xfermask(ap, dev);
1848 xfer_mode = xfer_shift = 0; 1838
1849 rc = ata_choose_xfer_mode(ap, &xfer_mode, &xfer_shift); 1839 dev->pio_mode = ata_xfer_mask2mode(xfer_mask & ATA_MASK_PIO);
1840 dev->dma_mode = ata_xfer_mask2mode(xfer_mask & (ATA_MASK_MWDMA |
1841 ATA_MASK_UDMA));
1842 }
1843
1844 /* step 2: always set host PIO timings */
1845 rc = ata_host_set_pio(ap);
1850 if (rc) 1846 if (rc)
1851 goto err_out; 1847 goto err_out;
1852 1848
1853 /* step 3: if that xfer mode isn't PIO, set host DMA timings */ 1849 /* step 3: set host DMA timings */
1854 if (xfer_shift != ATA_SHIFT_PIO) 1850 ata_host_set_dma(ap);
1855 ata_host_set_dma(ap, xfer_mode, xfer_shift);
1856 1851
1857 /* step 4: update devices' xfer mode */ 1852 /* step 4: update devices' xfer mode */
1858 ata_dev_set_mode(ap, &ap->device[0]); 1853 for (i = 0; i < ATA_MAX_DEVICES; i++)
1859 ata_dev_set_mode(ap, &ap->device[1]); 1854 ata_dev_set_mode(ap, &ap->device[i]);
1860 1855
1861 if (ap->flags & ATA_FLAG_PORT_DISABLED) 1856 if (ap->flags & ATA_FLAG_PORT_DISABLED)
1862 return; 1857 return;
@@ -2654,77 +2649,45 @@ static int ata_dma_blacklisted(const struct ata_device *dev)
2654 return 0; 2649 return 0;
2655} 2650}
2656 2651
2657static unsigned int ata_get_mode_mask(const struct ata_port *ap, int shift) 2652/**
2653 * ata_dev_xfermask - Compute supported xfermask of the given device
2654 * @ap: Port on which the device to compute xfermask for resides
2655 * @dev: Device to compute xfermask for
2656 *
2657 * Compute supported xfermask of @dev. This function is
2658 * responsible for applying all known limits including host
2659 * controller limits, device blacklist, etc...
2660 *
2661 * LOCKING:
2662 * None.
2663 *
2664 * RETURNS:
2665 * Computed xfermask.
2666 */
2667static unsigned int ata_dev_xfermask(struct ata_port *ap,
2668 struct ata_device *dev)
2658{ 2669{
2659 const struct ata_device *master, *slave; 2670 unsigned long xfer_mask;
2660 unsigned int mask; 2671 int i;
2661
2662 master = &ap->device[0];
2663 slave = &ap->device[1];
2664 2672
2665 WARN_ON(!ata_dev_present(master) && !ata_dev_present(slave)); 2673 xfer_mask = ata_pack_xfermask(ap->pio_mask, ap->mwdma_mask,
2674 ap->udma_mask);
2666 2675
2667 if (shift == ATA_SHIFT_UDMA) { 2676 /* use port-wide xfermask for now */
2668 mask = ap->udma_mask; 2677 for (i = 0; i < ATA_MAX_DEVICES; i++) {
2669 if (ata_dev_present(master)) { 2678 struct ata_device *d = &ap->device[i];
2670 mask &= (master->id[ATA_ID_UDMA_MODES] & 0xff); 2679 if (!ata_dev_present(d))
2671 if (ata_dma_blacklisted(master)) { 2680 continue;
2672 mask = 0; 2681 xfer_mask &= ata_id_xfermask(d->id);
2673 ata_pr_blacklisted(ap, master); 2682 if (ata_dma_blacklisted(d))
2674 } 2683 xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA);
2675 }
2676 if (ata_dev_present(slave)) {
2677 mask &= (slave->id[ATA_ID_UDMA_MODES] & 0xff);
2678 if (ata_dma_blacklisted(slave)) {
2679 mask = 0;
2680 ata_pr_blacklisted(ap, slave);
2681 }
2682 }
2683 }
2684 else if (shift == ATA_SHIFT_MWDMA) {
2685 mask = ap->mwdma_mask;
2686 if (ata_dev_present(master)) {
2687 mask &= (master->id[ATA_ID_MWDMA_MODES] & 0x07);
2688 if (ata_dma_blacklisted(master)) {
2689 mask = 0;
2690 ata_pr_blacklisted(ap, master);
2691 }
2692 }
2693 if (ata_dev_present(slave)) {
2694 mask &= (slave->id[ATA_ID_MWDMA_MODES] & 0x07);
2695 if (ata_dma_blacklisted(slave)) {
2696 mask = 0;
2697 ata_pr_blacklisted(ap, slave);
2698 }
2699 }
2700 }
2701 else if (shift == ATA_SHIFT_PIO) {
2702 mask = ap->pio_mask;
2703 if (ata_dev_present(master)) {
2704 /* spec doesn't return explicit support for
2705 * PIO0-2, so we fake it
2706 */
2707 u16 tmp_mode = master->id[ATA_ID_PIO_MODES] & 0x03;
2708 tmp_mode <<= 3;
2709 tmp_mode |= 0x7;
2710 mask &= tmp_mode;
2711 }
2712 if (ata_dev_present(slave)) {
2713 /* spec doesn't return explicit support for
2714 * PIO0-2, so we fake it
2715 */
2716 u16 tmp_mode = slave->id[ATA_ID_PIO_MODES] & 0x03;
2717 tmp_mode <<= 3;
2718 tmp_mode |= 0x7;
2719 mask &= tmp_mode;
2720 }
2721 }
2722 else {
2723 mask = 0xffffffff; /* shut up compiler warning */
2724 BUG();
2725 } 2684 }
2726 2685
2727 return mask; 2686 if (ata_dma_blacklisted(dev))
2687 printk(KERN_WARNING "ata%u: dev %u is on DMA blacklist, "
2688 "disabling DMA\n", ap->id, dev->devno);
2689
2690 return xfer_mask;
2728} 2691}
2729 2692
2730/* find greatest bit */ 2693/* find greatest bit */
@@ -2741,44 +2704,6 @@ static int fgb(u32 bitmap)
2741} 2704}
2742 2705
2743/** 2706/**
2744 * ata_choose_xfer_mode - attempt to find best transfer mode
2745 * @ap: Port for which an xfer mode will be selected
2746 * @xfer_mode_out: (output) SET FEATURES - XFER MODE code
2747 * @xfer_shift_out: (output) bit shift that selects this mode
2748 *
2749 * Based on host and device capabilities, determine the
2750 * maximum transfer mode that is amenable to all.
2751 *
2752 * LOCKING:
2753 * PCI/etc. bus probe sem.
2754 *
2755 * RETURNS:
2756 * Zero on success, negative on error.
2757 */
2758
2759static int ata_choose_xfer_mode(const struct ata_port *ap,
2760 u8 *xfer_mode_out,
2761 unsigned int *xfer_shift_out)
2762{
2763 unsigned int mask, shift;
2764 int x, i;
2765
2766 for (i = 0; i < ARRAY_SIZE(xfer_mode_classes); i++) {
2767 shift = xfer_mode_classes[i].shift;
2768 mask = ata_get_mode_mask(ap, shift);
2769
2770 x = fgb(mask);
2771 if (x >= 0) {
2772 *xfer_mode_out = xfer_mode_classes[i].base + x;
2773 *xfer_shift_out = shift;
2774 return 0;
2775 }
2776 }
2777
2778 return -1;
2779}
2780
2781/**
2782 * ata_dev_set_xfermode - Issue SET FEATURES - XFER MODE command 2707 * ata_dev_set_xfermode - Issue SET FEATURES - XFER MODE command
2783 * @ap: Port associated with device @dev 2708 * @ap: Port associated with device @dev
2784 * @dev: Device to which command will be sent 2709 * @dev: Device to which command will be sent