aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide/it8172.c
diff options
context:
space:
mode:
authorShane McDonald <mcdonald.shane@gmail.com>2009-01-06 11:21:01 -0500
committerBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2009-01-06 11:21:01 -0500
commit391ad1908a9c13d457ea12ce1508d6b8a7ba72ad (patch)
tree3ca36ed65d3dced7de8d2e6e6cebe60624936434 /drivers/ide/it8172.c
parent7ee98034d6402b9ba31d749ffb66534a44177ba9 (diff)
Resurrect IT8172 IDE controller driver
Support for the IT8172 IDE controller was removed from the kernel sometime after 2.6.18. Support for the only boards that used the IT8172 was removed from the kernel after 2.6.18, as they had never compiled since 2.6.0. However, there are a couple of platforms that use this chip: the PMC-Sierra Xiao Hu thin-client computer, which is no longer in production, and the Linksys NSS4000 Network Attached Storage box, which is based on the Xiao Hu board. I am attempting to add support for the Xiao Hu to the kernel, and this IT8172 IDE controller is the first bit of code in this effort. This patch resurrects the IT8172 IDE controller code. I began with the 2.6.18 version of the it8172.c file, and have moved it forward so that it works with the latest version of the kernel. I have run this driver on a PMC-Sierra Xiao Hu board with the 2.6.28 kernel, and I have had no problems with it in my configuration. The attached patch applies cleanly against 2.6.28. Signed-off-by: Shane McDonald <mcdonald.shane@gmail.com> Acked-by: Sergei Shtylyov <sshtylyov@ru.mvista.com> Cc: alan@lxorguk.ukuu.org.uk [bart: s/HWIF(drive)/drive->hwif/] Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Diffstat (limited to 'drivers/ide/it8172.c')
-rw-r--r--drivers/ide/it8172.c166
1 files changed, 166 insertions, 0 deletions
diff --git a/drivers/ide/it8172.c b/drivers/ide/it8172.c
new file mode 100644
index 000000000000..e021078cd06b
--- /dev/null
+++ b/drivers/ide/it8172.c
@@ -0,0 +1,166 @@
1/*
2 *
3 * BRIEF MODULE DESCRIPTION
4 * IT8172 IDE controller support
5 *
6 * Copyright (C) 2000 MontaVista Software Inc.
7 * Copyright (C) 2008 Shane McDonald
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
13 *
14 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
15 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
17 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
20 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
21 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 *
25 * You should have received a copy of the GNU General Public License along
26 * with this program; if not, write to the Free Software Foundation, Inc.,
27 * 675 Mass Ave, Cambridge, MA 02139, USA.
28 */
29
30#include <linux/module.h>
31#include <linux/types.h>
32#include <linux/kernel.h>
33#include <linux/ioport.h>
34#include <linux/pci.h>
35#include <linux/ide.h>
36#include <linux/init.h>
37
38#define DRV_NAME "IT8172"
39
40static void it8172_set_pio_mode(ide_drive_t *drive, const u8 pio)
41{
42 ide_hwif_t *hwif = drive->hwif;
43 struct pci_dev *dev = to_pci_dev(hwif->dev);
44 u16 drive_enables;
45 u32 drive_timing;
46
47 /*
48 * The highest value of DIOR/DIOW pulse width and recovery time
49 * that can be set in the IT8172 is 8 PCI clock cycles. As a result,
50 * it cannot be configured for PIO mode 0. This table sets these
51 * parameters to the maximum supported by the IT8172.
52 */
53 static const u8 timings[] = { 0x3f, 0x3c, 0x1b, 0x12, 0x0a };
54
55 pci_read_config_word(dev, 0x40, &drive_enables);
56 pci_read_config_dword(dev, 0x44, &drive_timing);
57
58 /*
59 * Enable port 0x44. The IT8172 spec is confused; it calls
60 * this register the "Slave IDE Timing Register", but in fact,
61 * it controls timing for both master and slave drives.
62 */
63 drive_enables |= 0x4000;
64
65 drive_enables &= drive->dn ? 0xc006 : 0xc060;
66 if (drive->media == ide_disk)
67 /* enable prefetch */
68 drive_enables |= 0x0004 << (drive->dn * 4);
69 if (ata_id_has_iordy(drive->id))
70 /* enable IORDY sample-point */
71 drive_enables |= 0x0002 << (drive->dn * 4);
72
73 drive_timing &= drive->dn ? 0x00003f00 : 0x000fc000;
74 drive_timing |= timings[pio] << (drive->dn * 6 + 8);
75
76 pci_write_config_word(dev, 0x40, drive_enables);
77 pci_write_config_dword(dev, 0x44, drive_timing);
78}
79
80static void it8172_set_dma_mode(ide_drive_t *drive, const u8 speed)
81{
82 ide_hwif_t *hwif = drive->hwif;
83 struct pci_dev *dev = to_pci_dev(hwif->dev);
84 int a_speed = 3 << (drive->dn * 4);
85 int u_flag = 1 << drive->dn;
86 int u_speed = 0;
87 u8 reg48, reg4a;
88
89 pci_read_config_byte(dev, 0x48, &reg48);
90 pci_read_config_byte(dev, 0x4a, &reg4a);
91
92 if (speed >= XFER_UDMA_0) {
93 u8 udma = speed - XFER_UDMA_0;
94 u_speed = udma << (drive->dn * 4);
95
96 pci_write_config_byte(dev, 0x48, reg48 | u_flag);
97 reg4a &= ~a_speed;
98 pci_write_config_byte(dev, 0x4a, reg4a | u_speed);
99 } else {
100 const u8 mwdma_to_pio[] = { 0, 3, 4 };
101 u8 pio;
102
103 pci_write_config_byte(dev, 0x48, reg48 & ~u_flag);
104 pci_write_config_byte(dev, 0x4a, reg4a & ~a_speed);
105
106 pio = mwdma_to_pio[speed - XFER_MW_DMA_0];
107
108 it8172_set_pio_mode(drive, pio);
109 }
110}
111
112
113static const struct ide_port_ops it8172_port_ops = {
114 .set_pio_mode = it8172_set_pio_mode,
115 .set_dma_mode = it8172_set_dma_mode,
116};
117
118static const struct ide_port_info it8172_port_info __devinitdata = {
119 .name = DRV_NAME,
120 .port_ops = &it8172_port_ops,
121 .enablebits = { {0x41, 0x80, 0x80}, {0x00, 0x00, 0x00} },
122 .host_flags = IDE_HFLAG_SINGLE,
123 .pio_mask = ATA_PIO4 & ~ATA_PIO0,
124 .mwdma_mask = ATA_MWDMA2,
125 .udma_mask = ATA_UDMA2,
126};
127
128static int __devinit it8172_init_one(struct pci_dev *dev,
129 const struct pci_device_id *id)
130{
131 if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE)
132 return -ENODEV; /* IT8172 is more than an IDE controller */
133 return ide_pci_init_one(dev, &it8172_port_info, NULL);
134}
135
136static struct pci_device_id it8172_pci_tbl[] = {
137 { PCI_VDEVICE(ITE, PCI_DEVICE_ID_ITE_8172), 0 },
138 { 0, },
139};
140MODULE_DEVICE_TABLE(pci, it8172_pci_tbl);
141
142static struct pci_driver it8172_pci_driver = {
143 .name = "IT8172_IDE",
144 .id_table = it8172_pci_tbl,
145 .probe = it8172_init_one,
146 .remove = ide_pci_remove,
147 .suspend = ide_pci_suspend,
148 .resume = ide_pci_resume,
149};
150
151static int __init it8172_ide_init(void)
152{
153 return ide_pci_register_driver(&it8172_pci_driver);
154}
155
156static void __exit it8172_ide_exit(void)
157{
158 pci_unregister_driver(&it8172_pci_driver);
159}
160
161module_init(it8172_ide_init);
162module_exit(it8172_ide_exit);
163
164MODULE_AUTHOR("Steve Longerbeam");
165MODULE_DESCRIPTION("PCI driver module for ITE 8172 IDE");
166MODULE_LICENSE("GPL");