]>
Commit | Line | Data |
---|---|---|
964949d0 | 1 | diff -Nur linux.org/drivers/ide/Config.in linux/drivers/ide/Config.in |
2 | --- linux.org/drivers/ide/Config.in Mon Oct 8 20:40:13 2001 | |
3 | +++ linux/drivers/ide/Config.in Thu Jul 18 14:24:32 2002 | |
4 | @@ -14,6 +14,7 @@ | |
5 | ||
6 | dep_tristate ' Include IDE/ATA-2 DISK support' CONFIG_BLK_DEV_IDEDISK $CONFIG_BLK_DEV_IDE | |
7 | dep_mbool ' Use multi-mode by default' CONFIG_IDEDISK_MULTI_MODE $CONFIG_BLK_DEV_IDEDISK | |
8 | + dep_mbool ' Auto-Geometry Resizing support' CONFIG_IDEDISK_STROKE $CONFIG_BLK_DEV_IDEDISK | |
9 | ||
10 | define_bool CONFIG_BLK_DEV_IDEDISK_VENDOR n | |
11 | dep_mbool ' Fujitsu Vendor Specific' CONFIG_BLK_DEV_IDEDISK_FUJITSU $CONFIG_BLK_DEV_IDEDISK_VENDOR | |
12 | @@ -32,6 +33,9 @@ | |
13 | dep_tristate ' Include IDE/ATAPI FLOPPY support' CONFIG_BLK_DEV_IDEFLOPPY $CONFIG_BLK_DEV_IDE | |
14 | dep_tristate ' SCSI emulation support' CONFIG_BLK_DEV_IDESCSI $CONFIG_BLK_DEV_IDE $CONFIG_SCSI | |
15 | ||
16 | + bool ' IDE Taskfile Access' CONFIG_IDE_TASK_IOCTL | |
17 | + bool ' IDE Taskfile IO' CONFIG_IDE_TASKFILE_IO | |
18 | + | |
19 | comment 'IDE chipset support/bugfixes' | |
20 | if [ "$CONFIG_BLK_DEV_IDE" != "n" ]; then | |
21 | dep_bool ' CMD640 chipset bugfix/support' CONFIG_BLK_DEV_CMD640 $CONFIG_X86 | |
22 | @@ -43,27 +47,27 @@ | |
23 | if [ "$CONFIG_BLK_DEV_IDEPCI" = "y" ]; then | |
24 | bool ' Sharing PCI IDE interrupts support' CONFIG_IDEPCI_SHARE_IRQ | |
25 | bool ' Generic PCI bus-master DMA support' CONFIG_BLK_DEV_IDEDMA_PCI | |
26 | -# bool ' Asynchronous DMA support (EXPERIMENTAL)' CONFIG_BLK_DEV_ADMA $CONFIG_BLK_DEV_IDEDMA_PCI | |
27 | - define_bool CONFIG_BLK_DEV_ADMA $CONFIG_BLK_DEV_IDEDMA_PCI | |
28 | bool ' Boot off-board chipsets first support' CONFIG_BLK_DEV_OFFBOARD | |
29 | + dep_bool ' Force enable legacy 2.0.X HOSTS to use DMA' CONFIG_BLK_DEV_IDEDMA_FORCED $CONFIG_BLK_DEV_IDEDMA_PCI | |
30 | dep_bool ' Use PCI DMA by default when available' CONFIG_IDEDMA_PCI_AUTO $CONFIG_BLK_DEV_IDEDMA_PCI | |
31 | + dep_bool ' Enable DMA only for disks ' CONFIG_IDEDMA_ONLYDISK $CONFIG_IDEDMA_PCI_AUTO | |
32 | define_bool CONFIG_BLK_DEV_IDEDMA $CONFIG_BLK_DEV_IDEDMA_PCI | |
33 | dep_bool ' ATA Work(s) In Progress (EXPERIMENTAL)' CONFIG_IDEDMA_PCI_WIP $CONFIG_BLK_DEV_IDEDMA_PCI $CONFIG_EXPERIMENTAL | |
34 | -# dep_bool ' Attempt to HACK around Chipsets that TIMEOUT (WIP)' CONFIG_BLK_DEV_IDEDMA_TIMEOUT $CONFIG_IDEDMA_PCI_WIP | |
35 | + dep_bool ' Attempt to HACK around Chipsets that TIMEOUT (WIP)' CONFIG_BLK_DEV_IDEDMA_TIMEOUT $CONFIG_IDEDMA_PCI_WIP | |
36 | dep_bool ' Good-Bad DMA Model-Firmware (WIP)' CONFIG_IDEDMA_NEW_DRIVE_LISTINGS $CONFIG_IDEDMA_PCI_WIP | |
37 | - | |
38 | dep_bool ' AEC62XX chipset support' CONFIG_BLK_DEV_AEC62XX $CONFIG_BLK_DEV_IDEDMA_PCI | |
39 | dep_mbool ' AEC62XX Tuning support' CONFIG_AEC62XX_TUNING $CONFIG_BLK_DEV_AEC62XX | |
40 | dep_bool ' ALI M15x3 chipset support' CONFIG_BLK_DEV_ALI15X3 $CONFIG_BLK_DEV_IDEDMA_PCI | |
41 | dep_mbool ' ALI M15x3 WDC support (DANGEROUS)' CONFIG_WDC_ALI15X3 $CONFIG_BLK_DEV_ALI15X3 | |
42 | dep_bool ' AMD Viper support' CONFIG_BLK_DEV_AMD74XX $CONFIG_BLK_DEV_IDEDMA_PCI | |
43 | dep_mbool ' AMD Viper ATA-66 Override (WIP)' CONFIG_AMD74XX_OVERRIDE $CONFIG_BLK_DEV_AMD74XX $CONFIG_IDEDMA_PCI_WIP | |
44 | - dep_bool ' CMD64X chipset support' CONFIG_BLK_DEV_CMD64X $CONFIG_BLK_DEV_IDEDMA_PCI | |
45 | + dep_bool ' CMD64X, CMD680 chipset support' CONFIG_BLK_DEV_CMD64X $CONFIG_BLK_DEV_IDEDMA_PCI | |
46 | + dep_bool ' CMD680 chipset tuning support' CONFIG_BLK_DEV_CMD680 $CONFIG_BLK_DEV_CMD64X | |
47 | dep_bool ' CY82C693 chipset support' CONFIG_BLK_DEV_CY82C693 $CONFIG_BLK_DEV_IDEDMA_PCI | |
48 | dep_bool ' Cyrix CS5530 MediaGX chipset support' CONFIG_BLK_DEV_CS5530 $CONFIG_BLK_DEV_IDEDMA_PCI | |
49 | dep_bool ' HPT34X chipset support' CONFIG_BLK_DEV_HPT34X $CONFIG_BLK_DEV_IDEDMA_PCI | |
50 | dep_mbool ' HPT34X AUTODMA support (WIP)' CONFIG_HPT34X_AUTODMA $CONFIG_BLK_DEV_HPT34X $CONFIG_IDEDMA_PCI_WIP | |
51 | - dep_bool ' HPT366 chipset support' CONFIG_BLK_DEV_HPT366 $CONFIG_BLK_DEV_IDEDMA_PCI | |
52 | + dep_bool ' HPT366/368/370 chipset support' CONFIG_BLK_DEV_HPT366 $CONFIG_BLK_DEV_IDEDMA_PCI | |
53 | if [ "$CONFIG_X86" = "y" -o "$CONFIG_IA64" = "y" ]; then | |
54 | dep_mbool ' Intel PIIXn chipsets support' CONFIG_BLK_DEV_PIIX $CONFIG_BLK_DEV_IDEDMA_PCI | |
55 | dep_mbool ' PIIXn Tuning support' CONFIG_PIIX_TUNING $CONFIG_BLK_DEV_PIIX $CONFIG_IDEDMA_PCI_AUTO | |
56 | @@ -72,23 +76,22 @@ | |
57 | dep_mbool ' IT8172 IDE support' CONFIG_BLK_DEV_IT8172 $CONFIG_BLK_DEV_IDEDMA_PCI | |
58 | dep_mbool ' IT8172 IDE Tuning support' CONFIG_IT8172_TUNING $CONFIG_BLK_DEV_IT8172 $CONFIG_IDEDMA_PCI_AUTO | |
59 | fi | |
60 | - dep_bool ' NS87415 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_NS87415 $CONFIG_BLK_DEV_IDEDMA_PCI | |
61 | + dep_bool ' NS87415 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_NS87415 $CONFIG_BLK_DEV_IDEDMA_PCI $CONFIG_EXPERIMENTAL | |
62 | dep_bool ' OPTi 82C621 chipset enhanced support (EXPERIMENTAL)' CONFIG_BLK_DEV_OPTI621 $CONFIG_EXPERIMENTAL | |
63 | - dep_bool ' PROMISE PDC202{46|62|65|67|68} support' CONFIG_BLK_DEV_PDC202XX $CONFIG_BLK_DEV_IDEDMA_PCI | |
64 | + dep_bool ' Pacific Digital ADMA100 basic support' CONFIG_BLK_DEV_ADMA100 $CONFIG_BLK_DEV_IDEDMA_PCI | |
65 | + dep_bool ' PROMISE PDC202{46|62|65|67|68|69|70} support' CONFIG_BLK_DEV_PDC202XX $CONFIG_BLK_DEV_IDEDMA_PCI | |
66 | dep_bool ' Special UDMA Feature' CONFIG_PDC202XX_BURST $CONFIG_BLK_DEV_PDC202XX | |
67 | dep_bool ' Special FastTrak Feature' CONFIG_PDC202XX_FORCE $CONFIG_BLK_DEV_PDC202XX | |
68 | - dep_bool ' ServerWorks OSB4/CSB5 chipsets support' CONFIG_BLK_DEV_SVWKS $CONFIG_BLK_DEV_IDEDMA_PCI $CONFIG_X86 | |
69 | + dep_bool ' RZ1000 chipset bugfix/support' CONFIG_BLK_DEV_RZ1000 $CONFIG_BLK_DEV_IDEDMA_PCI $CONFIG_X86 | |
70 | + dep_bool ' ServerWorks OSB4/CSB5/CSB6 chipsets support' CONFIG_BLK_DEV_SVWKS $CONFIG_BLK_DEV_IDEDMA_PCI | |
71 | dep_bool ' SiS5513 chipset support' CONFIG_BLK_DEV_SIS5513 $CONFIG_BLK_DEV_IDEDMA_PCI $CONFIG_X86 | |
72 | dep_bool ' SLC90E66 chipset support' CONFIG_BLK_DEV_SLC90E66 $CONFIG_BLK_DEV_IDEDMA_PCI $CONFIG_X86 | |
73 | - dep_bool ' Tekram TRM290 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_TRM290 $CONFIG_BLK_DEV_IDEDMA_PCI | |
74 | + dep_bool ' Tekram TRM290 chipset support' CONFIG_BLK_DEV_TRM290 $CONFIG_BLK_DEV_IDEDMA_PCI | |
75 | dep_bool ' VIA82CXXX chipset support' CONFIG_BLK_DEV_VIA82CXXX $CONFIG_BLK_DEV_IDEDMA_PCI | |
76 | + if [ "$CONFIG_PPC" = "y" -o "$CONFIG_ARM" = "y" ]; then | |
77 | + bool ' Winbond SL82c105 support' CONFIG_BLK_DEV_SL82C105 | |
78 | + fi | |
79 | fi | |
80 | - | |
81 | -# dep_mbool ' Pacific Digital A-DMA support (EXPERIMENTAL)' CONFIG_BLK_DEV_PDC_ADMA $CONFIG_BLK_DEV_ADMA $CONFIG_IDEDMA_PCI_WIP | |
82 | - | |
83 | - if [ "$CONFIG_PPC" = "y" -o "$CONFIG_ARM" = "y" ]; then | |
84 | - bool ' Winbond SL82c105 support' CONFIG_BLK_DEV_SL82C105 | |
85 | - fi | |
86 | fi | |
87 | if [ "$CONFIG_ALL_PPC" = "y" ]; then | |
88 | bool ' Builtin PowerMac IDE support' CONFIG_BLK_DEV_IDE_PMAC | |
89 | @@ -101,6 +104,9 @@ | |
90 | define_bool CONFIG_BLK_DEV_IDEPCI $CONFIG_BLK_DEV_IDEDMA_PMAC | |
91 | fi | |
92 | fi | |
93 | + if [ "$CONFIG_SIBYTE_SWARM" = "y" ]; then | |
94 | + bool ' SWARM onboard IDE support' CONFIG_BLK_DEV_IDE_SWARM | |
95 | + fi | |
96 | if [ "$CONFIG_ARCH_ACORN" = "y" ]; then | |
97 | dep_bool ' ICS IDE interface support' CONFIG_BLK_DEV_IDE_ICSIDE $CONFIG_ARCH_ACORN | |
98 | dep_bool ' ICS DMA support' CONFIG_BLK_DEV_IDEDMA_ICS $CONFIG_BLK_DEV_IDE_ICSIDE | |
99 | @@ -113,7 +119,7 @@ | |
100 | dep_mbool ' Amiga IDE Doubler support (EXPERIMENTAL)' CONFIG_BLK_DEV_IDEDOUBLER $CONFIG_BLK_DEV_GAYLE $CONFIG_EXPERIMENTAL | |
101 | fi | |
102 | if [ "$CONFIG_ZORRO" = "y" -a "$CONFIG_EXPERIMENTAL" = "y" ]; then | |
103 | - dep_mbool ' Buddha/Catweasel IDE interface support (EXPERIMENTAL)' CONFIG_BLK_DEV_BUDDHA $CONFIG_ZORRO $CONFIG_EXPERIMENTAL | |
104 | + dep_mbool ' Buddha/Catweasel/X-Surf IDE interface support (EXPERIMENTAL)' CONFIG_BLK_DEV_BUDDHA $CONFIG_ZORRO $CONFIG_EXPERIMENTAL | |
105 | fi | |
106 | if [ "$CONFIG_ATARI" = "y" ]; then | |
107 | dep_bool ' Falcon IDE interface support' CONFIG_BLK_DEV_FALCON_IDE $CONFIG_ATARI | |
108 | @@ -173,6 +179,7 @@ | |
109 | else | |
110 | define_bool CONFIG_DMA_NONPCI n | |
111 | fi | |
112 | + | |
113 | if [ "$CONFIG_IDE_CHIPSETS" = "y" -o \ | |
114 | "$CONFIG_BLK_DEV_AEC62XX" = "y" -o \ | |
115 | "$CONFIG_BLK_DEV_ALI15X3" = "y" -o \ | |
116 | diff -Nur linux.org/drivers/ide/Makefile linux/drivers/ide/Makefile | |
117 | --- linux.org/drivers/ide/Makefile Tue Oct 9 18:18:37 2001 | |
118 | +++ linux/drivers/ide/Makefile Thu Jul 18 14:24:33 2002 | |
119 | @@ -10,7 +10,7 @@ | |
120 | ||
121 | O_TARGET := idedriver.o | |
122 | ||
123 | -export-objs := ide.o ide-features.o ataraid.o | |
124 | +export-objs := ide-taskfile.o ide.o ide-probe.o ataraid.o | |
125 | list-multi := ide-mod.o ide-probe-mod.o | |
126 | ||
127 | obj-y := | |
128 | @@ -24,8 +24,10 @@ | |
129 | obj-$(CONFIG_BLK_DEV_IDECD) += ide-cd.o | |
130 | obj-$(CONFIG_BLK_DEV_IDETAPE) += ide-tape.o | |
131 | obj-$(CONFIG_BLK_DEV_IDEFLOPPY) += ide-floppy.o | |
132 | + | |
133 | obj-$(CONFIG_BLK_DEV_IT8172) += it8172.o | |
134 | ||
135 | +ide-obj-$(CONFIG_BLK_DEV_ADMA100) += adma100.o | |
136 | ide-obj-$(CONFIG_BLK_DEV_AEC62XX) += aec62xx.o | |
137 | ide-obj-$(CONFIG_BLK_DEV_ALI14XX) += ali14xx.o | |
138 | ide-obj-$(CONFIG_BLK_DEV_ALI15X3) += alim15x3.o | |
139 | @@ -43,18 +45,18 @@ | |
140 | ide-obj-$(CONFIG_BLK_DEV_HPT366) += hpt366.o | |
141 | ide-obj-$(CONFIG_BLK_DEV_HT6560B) += ht6560b.o | |
142 | ide-obj-$(CONFIG_BLK_DEV_IDE_ICSIDE) += icside.o | |
143 | -ide-obj-$(CONFIG_BLK_DEV_ADMA) += ide-adma.o | |
144 | ide-obj-$(CONFIG_BLK_DEV_IDEDMA_PCI) += ide-dma.o | |
145 | +ide-obj-$(CONFIG_BLK_DEV_MPC8xx_IDE) += ide-m8xx.o | |
146 | ide-obj-$(CONFIG_BLK_DEV_IDEPCI) += ide-pci.o | |
147 | ide-obj-$(CONFIG_BLK_DEV_ISAPNP) += ide-pnp.o | |
148 | ide-obj-$(CONFIG_BLK_DEV_IDE_PMAC) += ide-pmac.o | |
149 | +ide-obj-$(CONFIG_BLK_DEV_IDE_SWARM) += ide-swarm.o | |
150 | ide-obj-$(CONFIG_BLK_DEV_MAC_IDE) += macide.o | |
151 | ide-obj-$(CONFIG_BLK_DEV_NS87415) += ns87415.o | |
152 | ide-obj-$(CONFIG_BLK_DEV_OPTI621) += opti621.o | |
153 | ide-obj-$(CONFIG_BLK_DEV_SVWKS) += serverworks.o | |
154 | ide-obj-$(CONFIG_BLK_DEV_PDC202XX) += pdc202xx.o | |
155 | ide-obj-$(CONFIG_BLK_DEV_PDC4030) += pdc4030.o | |
156 | -ide-obj-$(CONFIG_BLK_DEV_PDC_ADMA) += pdcadma.o | |
157 | ide-obj-$(CONFIG_BLK_DEV_PIIX) += piix.o | |
158 | ide-obj-$(CONFIG_BLK_DEV_QD65XX) += qd65xx.o | |
159 | ide-obj-$(CONFIG_BLK_DEV_IDE_RAPIDE) += rapide.o | |
160 | @@ -65,17 +67,16 @@ | |
161 | ide-obj-$(CONFIG_BLK_DEV_TRM290) += trm290.o | |
162 | ide-obj-$(CONFIG_BLK_DEV_UMC8672) += umc8672.o | |
163 | ide-obj-$(CONFIG_BLK_DEV_VIA82CXXX) += via82cxxx.o | |
164 | -ide-obj-$(CONFIG_BLK_DEV_MPC8xx_IDE) += ide-m8xx.o | |
165 | ||
166 | # The virtualised raid layers MUST come after the ide itself or bad stuff | |
167 | # will happen. | |
168 | -obj-$(CONFIG_BLK_DEV_ATARAID) += ataraid.o | |
169 | +obj-$(CONFIG_BLK_DEV_ATARAID) += ataraid.o | |
170 | obj-$(CONFIG_BLK_DEV_ATARAID_PDC) += pdcraid.o | |
171 | obj-$(CONFIG_BLK_DEV_ATARAID_HPT) += hptraid.o | |
172 | ||
173 | ide-obj-$(CONFIG_PROC_FS) += ide-proc.o | |
174 | ||
175 | -ide-mod-objs := ide.o ide-features.o $(ide-obj-y) | |
176 | +ide-mod-objs := ide-taskfile.o ide.o $(ide-obj-y) | |
177 | ide-probe-mod-objs := ide-probe.o ide-geometry.o | |
178 | ||
179 | include $(TOPDIR)/Rules.make | |
180 | diff -Nur linux.org/drivers/ide/adma100.c linux/drivers/ide/adma100.c | |
181 | --- linux.org/drivers/ide/adma100.c Thu Jan 1 01:00:00 1970 | |
182 | +++ linux/drivers/ide/adma100.c Thu Jul 18 14:24:33 2002 | |
183 | @@ -0,0 +1,30 @@ | |
184 | +/* | |
185 | + * linux/drivers/ide/adma100.c -- basic support for Pacific Digital ADMA-100 boards | |
186 | + * | |
187 | + * Created 09 Apr 2002 by Mark Lord | |
188 | + * | |
189 | + * This file is subject to the terms and conditions of the GNU General Public | |
190 | + * License. See the file COPYING in the main directory of this archive for | |
191 | + * more details. | |
192 | + */ | |
193 | + | |
194 | +#include <linux/mm.h> | |
195 | +#include <linux/blkdev.h> | |
196 | +#include <linux/hdreg.h> | |
197 | +#include <linux/ide.h> | |
198 | +#include <linux/init.h> | |
199 | +#include <linux/pci.h> | |
200 | +#include <asm/io.h> | |
201 | + | |
202 | +void __init ide_init_adma100 (ide_hwif_t *hwif) | |
203 | +{ | |
204 | + u32 phy_admctl = pci_resource_start(hwif->pci_dev, 4) + 0x80 + (hwif->channel * 0x20); | |
205 | + void *v_admctl; | |
206 | + | |
207 | + hwif->autodma = 0; // not compatible with normal IDE DMA transfers | |
208 | + hwif->dma_base = 0; // disable DMA completely | |
209 | + hwif->io_ports[IDE_CONTROL_OFFSET] += 4; // chip needs offset of 6 instead of 2 | |
210 | + v_admctl = ioremap_nocache(phy_admctl, 1024); // map config regs, so we can turn on drive IRQs | |
211 | + *((unsigned short *)v_admctl) &= 3; // enable aIEN; preserve PIO mode | |
212 | + iounmap(v_admctl); // all done; unmap config regs | |
213 | +} | |
214 | diff -Nur linux.org/drivers/ide/aec62xx.c linux/drivers/ide/aec62xx.c | |
215 | --- linux.org/drivers/ide/aec62xx.c Tue Jun 20 16:52:36 2000 | |
216 | +++ linux/drivers/ide/aec62xx.c Thu Jul 18 14:24:33 2002 | |
217 | @@ -1,8 +1,7 @@ | |
218 | /* | |
219 | - * linux/drivers/ide/aec62xx.c Version 0.09 June. 9, 2000 | |
220 | + * linux/drivers/ide/aec62xx.c Version 0.11 March 27, 2002 | |
221 | * | |
222 | - * Copyright (C) 1999-2000 Andre Hedrick (andre@linux-ide.org) | |
223 | - * May be copied or modified under the terms of the GNU General Public License | |
224 | + * Copyright (C) 1999-2002 Andre Hedrick <andre@linux-ide.org> | |
225 | * | |
226 | */ | |
227 | ||
228 | @@ -48,154 +47,209 @@ | |
229 | ||
230 | static int aec62xx_get_info(char *, char **, off_t, int); | |
231 | extern int (*aec62xx_display_info)(char *, char **, off_t, int); /* ide-proc.c */ | |
232 | -extern char *ide_media_verbose(ide_drive_t *); | |
233 | -static struct pci_dev *bmide_dev; | |
234 | ||
235 | -static int aec62xx_get_info (char *buffer, char **addr, off_t offset, int count) | |
236 | -{ | |
237 | - char *p = buffer; | |
238 | - | |
239 | - u32 bibma = pci_resource_start(bmide_dev, 4); | |
240 | - u8 c0 = 0, c1 = 0; | |
241 | - u8 art = 0, uart = 0; | |
242 | +#define AEC_MAX_DEVS 5 | |
243 | ||
244 | - switch(bmide_dev->device) { | |
245 | - case PCI_DEVICE_ID_ARTOP_ATP850UF: | |
246 | - p += sprintf(p, "\n AEC6210 Chipset.\n"); | |
247 | - break; | |
248 | - case PCI_DEVICE_ID_ARTOP_ATP860: | |
249 | - p += sprintf(p, "\n AEC6260 No Bios Chipset.\n"); | |
250 | - break; | |
251 | - case PCI_DEVICE_ID_ARTOP_ATP860R: | |
252 | - p += sprintf(p, "\n AEC6260 Chipset.\n"); | |
253 | - break; | |
254 | - default: | |
255 | - p += sprintf(p, "\n AEC62?? Chipset.\n"); | |
256 | - break; | |
257 | - } | |
258 | +static struct pci_dev *aec_devs[AEC_MAX_DEVS]; | |
259 | +static int n_aec_devs; | |
260 | ||
261 | - /* | |
262 | - * at that point bibma+0x2 et bibma+0xa are byte registers | |
263 | - * to investigate: | |
264 | - */ | |
265 | - c0 = inb_p((unsigned short)bibma + 0x02); | |
266 | - c1 = inb_p((unsigned short)bibma + 0x0a); | |
267 | - | |
268 | - p += sprintf(p, "--------------- Primary Channel ---------------- Secondary Channel -------------\n"); | |
269 | - (void) pci_read_config_byte(bmide_dev, 0x4a, &art); | |
270 | - p += sprintf(p, " %sabled %sabled\n", | |
271 | - (art&0x02)?" en":"dis",(art&0x04)?" en":"dis"); | |
272 | - p += sprintf(p, "--------------- drive0 --------- drive1 -------- drive0 ---------- drive1 ------\n"); | |
273 | - p += sprintf(p, "DMA enabled: %s %s %s %s\n", | |
274 | - (c0&0x20)?"yes":"no ",(c0&0x40)?"yes":"no ",(c1&0x20)?"yes":"no ",(c1&0x40)?"yes":"no "); | |
275 | +#undef DEBUG_AEC_REGS | |
276 | ||
277 | - switch(bmide_dev->device) { | |
278 | - case PCI_DEVICE_ID_ARTOP_ATP850UF: | |
279 | - (void) pci_read_config_byte(bmide_dev, 0x54, &art); | |
280 | - p += sprintf(p, "DMA Mode: %s(%s) %s(%s) %s(%s) %s(%s)\n", | |
281 | +static int aec62xx_get_info (char *buffer, char **addr, off_t offset, int count) | |
282 | +{ | |
283 | + char *p = buffer; | |
284 | + char *chipset_nums[] = {"error", "error", "error", "error", | |
285 | + "error", "error", "850UF", "860", | |
286 | + "860R", "865", "865R", "error" }; | |
287 | +// char *modes_33[] = {}; | |
288 | +// char *modes_34[] = {}; | |
289 | + int i; | |
290 | + | |
291 | + for (i = 0; i < n_aec_devs; i++) { | |
292 | + struct pci_dev *dev = aec_devs[i]; | |
293 | + // u32 iobase = dev->resource[4].start; | |
294 | + u32 iobase = pci_resource_start(dev, 4); | |
295 | + u8 c0 = inb_p(iobase + 0x02); | |
296 | + u8 c1 = inb_p(iobase + 0x0a); | |
297 | + u8 art = 0; | |
298 | +#ifdef DEBUG_AEC_REGS | |
299 | + u8 uart = 0; | |
300 | +#endif /* DEBUG_AEC_REGS */ | |
301 | + | |
302 | + p += sprintf(p, "\nController: %d\n", i); | |
303 | + p += sprintf(p, "Chipset: AEC%s\n", chipset_nums[dev->device]); | |
304 | + | |
305 | + p += sprintf(p, "--------------- Primary Channel " | |
306 | + "---------------- Secondary Channel " | |
307 | + "-------------\n"); | |
308 | + (void) pci_read_config_byte(dev, 0x4a, &art); | |
309 | + p += sprintf(p, " %sabled ", | |
310 | + (art&0x02)?" en":"dis"); | |
311 | + p += sprintf(p, " %sabled\n", | |
312 | + (art&0x04)?" en":"dis"); | |
313 | + p += sprintf(p, "--------------- drive0 --------- drive1 " | |
314 | + "-------- drive0 ---------- drive1 ------\n"); | |
315 | + p += sprintf(p, "DMA enabled: %s %s ", | |
316 | + (c0&0x20)?"yes":"no ",(c0&0x40)?"yes":"no "); | |
317 | + p += sprintf(p, " %s %s\n", | |
318 | + (c1&0x20)?"yes":"no ",(c1&0x40)?"yes":"no "); | |
319 | + | |
320 | + if (dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF) { | |
321 | + (void) pci_read_config_byte(dev, 0x54, &art); | |
322 | + p += sprintf(p, "DMA Mode: %s(%s)", | |
323 | (c0&0x20)?((art&0x03)?"UDMA":" DMA"):" PIO", | |
324 | - (art&0x02)?"2":(art&0x01)?"1":"0", | |
325 | + (art&0x02)?"2":(art&0x01)?"1":"0"); | |
326 | + p += sprintf(p, " %s(%s)", | |
327 | (c0&0x40)?((art&0x0c)?"UDMA":" DMA"):" PIO", | |
328 | - (art&0x08)?"2":(art&0x04)?"1":"0", | |
329 | + (art&0x08)?"2":(art&0x04)?"1":"0"); | |
330 | + p += sprintf(p, " %s(%s)", | |
331 | (c1&0x20)?((art&0x30)?"UDMA":" DMA"):" PIO", | |
332 | - (art&0x20)?"2":(art&0x10)?"1":"0", | |
333 | + (art&0x20)?"2":(art&0x10)?"1":"0"); | |
334 | + p += sprintf(p, " %s(%s)\n", | |
335 | (c1&0x40)?((art&0xc0)?"UDMA":" DMA"):" PIO", | |
336 | (art&0x80)?"2":(art&0x40)?"1":"0"); | |
337 | - (void) pci_read_config_byte(bmide_dev, 0x40, &art); | |
338 | +#ifdef DEBUG_AEC_REGS | |
339 | + (void) pci_read_config_byte(dev, 0x40, &art); | |
340 | p += sprintf(p, "Active: 0x%02x", art); | |
341 | - (void) pci_read_config_byte(bmide_dev, 0x42, &art); | |
342 | + (void) pci_read_config_byte(dev, 0x42, &art); | |
343 | p += sprintf(p, " 0x%02x", art); | |
344 | - (void) pci_read_config_byte(bmide_dev, 0x44, &art); | |
345 | + (void) pci_read_config_byte(dev, 0x44, &art); | |
346 | p += sprintf(p, " 0x%02x", art); | |
347 | - (void) pci_read_config_byte(bmide_dev, 0x46, &art); | |
348 | + (void) pci_read_config_byte(dev, 0x46, &art); | |
349 | p += sprintf(p, " 0x%02x\n", art); | |
350 | - (void) pci_read_config_byte(bmide_dev, 0x41, &art); | |
351 | + (void) pci_read_config_byte(dev, 0x41, &art); | |
352 | p += sprintf(p, "Recovery: 0x%02x", art); | |
353 | - (void) pci_read_config_byte(bmide_dev, 0x43, &art); | |
354 | + (void) pci_read_config_byte(dev, 0x43, &art); | |
355 | p += sprintf(p, " 0x%02x", art); | |
356 | - (void) pci_read_config_byte(bmide_dev, 0x45, &art); | |
357 | + (void) pci_read_config_byte(dev, 0x45, &art); | |
358 | p += sprintf(p, " 0x%02x", art); | |
359 | - (void) pci_read_config_byte(bmide_dev, 0x47, &art); | |
360 | + (void) pci_read_config_byte(dev, 0x47, &art); | |
361 | p += sprintf(p, " 0x%02x\n", art); | |
362 | - break; | |
363 | - case PCI_DEVICE_ID_ARTOP_ATP860: | |
364 | - case PCI_DEVICE_ID_ARTOP_ATP860R: | |
365 | - (void) pci_read_config_byte(bmide_dev, 0x44, &art); | |
366 | - p += sprintf(p, "DMA Mode: %s(%s) %s(%s)", | |
367 | +#endif /* DEBUG_AEC_REGS */ | |
368 | + } else { | |
369 | + /* | |
370 | + * case PCI_DEVICE_ID_ARTOP_ATP860: | |
371 | + * case PCI_DEVICE_ID_ARTOP_ATP860R: | |
372 | + * case PCI_DEVICE_ID_ARTOP_ATP865: | |
373 | + * case PCI_DEVICE_ID_ARTOP_ATP865R: | |
374 | + */ | |
375 | + (void) pci_read_config_byte(dev, 0x44, &art); | |
376 | + p += sprintf(p, "DMA Mode: %s(%s)", | |
377 | (c0&0x20)?((art&0x07)?"UDMA":" DMA"):" PIO", | |
378 | - ((art&0x06)==0x06)?"4":((art&0x05)==0x05)?"4":((art&0x04)==0x04)?"3":((art&0x03)==0x03)?"2":((art&0x02)==0x02)?"1":((art&0x01)==0x01)?"0":"?", | |
379 | + ((art&0x07)==0x07)?"6": | |
380 | + ((art&0x06)==0x06)?"5": | |
381 | + ((art&0x05)==0x05)?"4": | |
382 | + ((art&0x04)==0x04)?"3": | |
383 | + ((art&0x03)==0x03)?"2": | |
384 | + ((art&0x02)==0x02)?"1": | |
385 | + ((art&0x01)==0x01)?"0":"?"); | |
386 | + p += sprintf(p, " %s(%s)", | |
387 | (c0&0x40)?((art&0x70)?"UDMA":" DMA"):" PIO", | |
388 | - ((art&0x60)==0x60)?"4":((art&0x50)==0x50)?"4":((art&0x40)==0x40)?"3":((art&0x30)==0x30)?"2":((art&0x20)==0x20)?"1":((art&0x10)==0x10)?"0":"?"); | |
389 | - (void) pci_read_config_byte(bmide_dev, 0x45, &art); | |
390 | - p += sprintf(p, " %s(%s) %s(%s)\n", | |
391 | + ((art&0x70)==0x70)?"6": | |
392 | + ((art&0x60)==0x60)?"5": | |
393 | + ((art&0x50)==0x50)?"4": | |
394 | + ((art&0x40)==0x40)?"3": | |
395 | + ((art&0x30)==0x30)?"2": | |
396 | + ((art&0x20)==0x20)?"1": | |
397 | + ((art&0x10)==0x10)?"0":"?"); | |
398 | + (void) pci_read_config_byte(dev, 0x45, &art); | |
399 | + p += sprintf(p, " %s(%s)", | |
400 | (c1&0x20)?((art&0x07)?"UDMA":" DMA"):" PIO", | |
401 | - ((art&0x06)==0x06)?"4":((art&0x05)==0x05)?"4":((art&0x04)==0x04)?"3":((art&0x03)==0x03)?"2":((art&0x02)==0x02)?"1":((art&0x01)==0x01)?"0":"?", | |
402 | + ((art&0x07)==0x07)?"6": | |
403 | + ((art&0x06)==0x06)?"5": | |
404 | + ((art&0x05)==0x05)?"4": | |
405 | + ((art&0x04)==0x04)?"3": | |
406 | + ((art&0x03)==0x03)?"2": | |
407 | + ((art&0x02)==0x02)?"1": | |
408 | + ((art&0x01)==0x01)?"0":"?"); | |
409 | + p += sprintf(p, " %s(%s)\n", | |
410 | (c1&0x40)?((art&0x70)?"UDMA":" DMA"):" PIO", | |
411 | - ((art&0x60)==0x60)?"4":((art&0x50)==0x50)?"4":((art&0x40)==0x40)?"3":((art&0x30)==0x30)?"2":((art&0x20)==0x20)?"1":((art&0x10)==0x10)?"0":"?"); | |
412 | - (void) pci_read_config_byte(bmide_dev, 0x40, &art); | |
413 | + ((art&0x70)==0x70)?"6": | |
414 | + ((art&0x60)==0x60)?"5": | |
415 | + ((art&0x50)==0x50)?"4": | |
416 | + ((art&0x40)==0x40)?"3": | |
417 | + ((art&0x30)==0x30)?"2": | |
418 | + ((art&0x20)==0x20)?"1": | |
419 | + ((art&0x10)==0x10)?"0":"?"); | |
420 | +#ifdef DEBUG_AEC_REGS | |
421 | + (void) pci_read_config_byte(dev, 0x40, &art); | |
422 | p += sprintf(p, "Active: 0x%02x", HIGH_4(art)); | |
423 | - (void) pci_read_config_byte(bmide_dev, 0x41, &art); | |
424 | + (void) pci_read_config_byte(dev, 0x41, &art); | |
425 | p += sprintf(p, " 0x%02x", HIGH_4(art)); | |
426 | - (void) pci_read_config_byte(bmide_dev, 0x42, &art); | |
427 | + (void) pci_read_config_byte(dev, 0x42, &art); | |
428 | p += sprintf(p, " 0x%02x", HIGH_4(art)); | |
429 | - (void) pci_read_config_byte(bmide_dev, 0x43, &art); | |
430 | + (void) pci_read_config_byte(dev, 0x43, &art); | |
431 | p += sprintf(p, " 0x%02x\n", HIGH_4(art)); | |
432 | - (void) pci_read_config_byte(bmide_dev, 0x40, &art); | |
433 | + (void) pci_read_config_byte(dev, 0x40, &art); | |
434 | p += sprintf(p, "Recovery: 0x%02x", LOW_4(art)); | |
435 | - (void) pci_read_config_byte(bmide_dev, 0x41, &art); | |
436 | + (void) pci_read_config_byte(dev, 0x41, &art); | |
437 | p += sprintf(p, " 0x%02x", LOW_4(art)); | |
438 | - (void) pci_read_config_byte(bmide_dev, 0x42, &art); | |
439 | + (void) pci_read_config_byte(dev, 0x42, &art); | |
440 | p += sprintf(p, " 0x%02x", LOW_4(art)); | |
441 | - (void) pci_read_config_byte(bmide_dev, 0x43, &art); | |
442 | + (void) pci_read_config_byte(dev, 0x43, &art); | |
443 | p += sprintf(p, " 0x%02x\n", LOW_4(art)); | |
444 | - (void) pci_read_config_byte(bmide_dev, 0x49, &uart); | |
445 | + (void) pci_read_config_byte(dev, 0x49, &uart); | |
446 | p += sprintf(p, "reg49h = 0x%02x ", uart); | |
447 | - (void) pci_read_config_byte(bmide_dev, 0x4a, &uart); | |
448 | + (void) pci_read_config_byte(dev, 0x4a, &uart); | |
449 | p += sprintf(p, "reg4ah = 0x%02x\n", uart); | |
450 | - break; | |
451 | - default: | |
452 | - break; | |
453 | +#endif /* DEBUG_AEC_REGS */ | |
454 | + } | |
455 | } | |
456 | - | |
457 | return p-buffer;/* => must be less than 4k! */ | |
458 | } | |
459 | #endif /* defined(DISPLAY_AEC62xx_TIMINGS) && defined(CONFIG_PROC_FS) */ | |
460 | ||
461 | byte aec62xx_proc = 0; | |
462 | ||
463 | -#ifdef CONFIG_AEC62XX_TUNING | |
464 | - | |
465 | struct chipset_bus_clock_list_entry { | |
466 | byte xfer_speed; | |
467 | - | |
468 | - byte chipset_settings_34; | |
469 | - byte ultra_settings_34; | |
470 | - | |
471 | - byte chipset_settings_33; | |
472 | - byte ultra_settings_33; | |
473 | + byte chipset_settings; | |
474 | + byte ultra_settings; | |
475 | }; | |
476 | ||
477 | -struct chipset_bus_clock_list_entry aec62xx_base [] = { | |
478 | +struct chipset_bus_clock_list_entry aec6xxx_33_base [] = { | |
479 | #ifdef CONFIG_BLK_DEV_IDEDMA | |
480 | - { XFER_UDMA_4, 0x41, 0x04, 0x31, 0x05 }, | |
481 | - { XFER_UDMA_3, 0x41, 0x03, 0x31, 0x04 }, | |
482 | - { XFER_UDMA_2, 0x41, 0x02, 0x31, 0x03 }, | |
483 | - { XFER_UDMA_1, 0x41, 0x01, 0x31, 0x02 }, | |
484 | - { XFER_UDMA_0, 0x41, 0x01, 0x31, 0x01 }, | |
485 | - | |
486 | - { XFER_MW_DMA_2, 0x41, 0x00, 0x31, 0x00 }, | |
487 | - { XFER_MW_DMA_1, 0x42, 0x00, 0x31, 0x00 }, | |
488 | - { XFER_MW_DMA_0, 0x7a, 0x00, 0x0a, 0x00 }, | |
489 | + { XFER_UDMA_6, 0x31, 0x07 }, | |
490 | + { XFER_UDMA_5, 0x31, 0x06 }, | |
491 | + { XFER_UDMA_4, 0x31, 0x05 }, | |
492 | + { XFER_UDMA_3, 0x31, 0x04 }, | |
493 | + { XFER_UDMA_2, 0x31, 0x03 }, | |
494 | + { XFER_UDMA_1, 0x31, 0x02 }, | |
495 | + { XFER_UDMA_0, 0x31, 0x01 }, | |
496 | + | |
497 | + { XFER_MW_DMA_2, 0x31, 0x00 }, | |
498 | + { XFER_MW_DMA_1, 0x31, 0x00 }, | |
499 | + { XFER_MW_DMA_0, 0x0a, 0x00 }, | |
500 | #endif /* CONFIG_BLK_DEV_IDEDMA */ | |
501 | - { XFER_PIO_4, 0x41, 0x00, 0x31, 0x00 }, | |
502 | - { XFER_PIO_3, 0x43, 0x00, 0x33, 0x00 }, | |
503 | - { XFER_PIO_2, 0x78, 0x00, 0x08, 0x00 }, | |
504 | - { XFER_PIO_1, 0x7a, 0x00, 0x0a, 0x00 }, | |
505 | - { XFER_PIO_0, 0x70, 0x00, 0x00, 0x00 }, | |
506 | - { 0, 0x00, 0x00, 0x00, 0x00 } | |
507 | + { XFER_PIO_4, 0x31, 0x00 }, | |
508 | + { XFER_PIO_3, 0x33, 0x00 }, | |
509 | + { XFER_PIO_2, 0x08, 0x00 }, | |
510 | + { XFER_PIO_1, 0x0a, 0x00 }, | |
511 | + { XFER_PIO_0, 0x00, 0x00 }, | |
512 | + { 0, 0x00, 0x00 } | |
513 | }; | |
514 | ||
515 | -extern char *ide_xfer_verbose (byte xfer_rate); | |
516 | +struct chipset_bus_clock_list_entry aec6xxx_34_base [] = { | |
517 | +#ifdef CONFIG_BLK_DEV_IDEDMA | |
518 | + { XFER_UDMA_6, 0x41, 0x06 }, | |
519 | + { XFER_UDMA_5, 0x41, 0x05 }, | |
520 | + { XFER_UDMA_4, 0x41, 0x04 }, | |
521 | + { XFER_UDMA_3, 0x41, 0x03 }, | |
522 | + { XFER_UDMA_2, 0x41, 0x02 }, | |
523 | + { XFER_UDMA_1, 0x41, 0x01 }, | |
524 | + { XFER_UDMA_0, 0x41, 0x01 }, | |
525 | + | |
526 | + { XFER_MW_DMA_2, 0x41, 0x00 }, | |
527 | + { XFER_MW_DMA_1, 0x42, 0x00 }, | |
528 | + { XFER_MW_DMA_0, 0x7a, 0x00 }, | |
529 | +#endif /* CONFIG_BLK_DEV_IDEDMA */ | |
530 | + { XFER_PIO_4, 0x41, 0x00 }, | |
531 | + { XFER_PIO_3, 0x43, 0x00 }, | |
532 | + { XFER_PIO_2, 0x78, 0x00 }, | |
533 | + { XFER_PIO_1, 0x7a, 0x00 }, | |
534 | + { XFER_PIO_0, 0x70, 0x00 }, | |
535 | + { 0, 0x00, 0x00 } | |
536 | +}; | |
537 | ||
538 | /* | |
539 | * TO DO: active tuning and correction of cards without a bios. | |
540 | @@ -203,31 +257,73 @@ | |
541 | ||
542 | static byte pci_bus_clock_list (byte speed, struct chipset_bus_clock_list_entry * chipset_table) | |
543 | { | |
544 | - int bus_speed = system_bus_clock(); | |
545 | - | |
546 | for ( ; chipset_table->xfer_speed ; chipset_table++) | |
547 | if (chipset_table->xfer_speed == speed) { | |
548 | - return ((byte) ((bus_speed <= 33) ? chipset_table->chipset_settings_33 : chipset_table->chipset_settings_34)); | |
549 | + return chipset_table->chipset_settings; | |
550 | } | |
551 | - return 0x00; | |
552 | + return chipset_table->chipset_settings; | |
553 | } | |
554 | ||
555 | static byte pci_bus_clock_list_ultra (byte speed, struct chipset_bus_clock_list_entry * chipset_table) | |
556 | { | |
557 | - int bus_speed = system_bus_clock(); | |
558 | - | |
559 | for ( ; chipset_table->xfer_speed ; chipset_table++) | |
560 | if (chipset_table->xfer_speed == speed) { | |
561 | - return ((byte) ((bus_speed <= 33) ? chipset_table->ultra_settings_33 : chipset_table->ultra_settings_34)); | |
562 | + return chipset_table->ultra_settings; | |
563 | } | |
564 | - return 0x00; | |
565 | + return chipset_table->ultra_settings; | |
566 | +} | |
567 | + | |
568 | +static byte aec62xx_ratemask (ide_drive_t *drive) | |
569 | +{ | |
570 | + struct pci_dev *dev = HWIF(drive)->pci_dev; | |
571 | + byte mode = 0x00; | |
572 | + | |
573 | + if (dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF) { | |
574 | + mode |= 0x01; | |
575 | + } else if ((dev->device == PCI_DEVICE_ID_ARTOP_ATP860) || | |
576 | + (dev->device == PCI_DEVICE_ID_ARTOP_ATP860R)) { | |
577 | + mode |= 0x02; | |
578 | + } else if ((dev->device == PCI_DEVICE_ID_ARTOP_ATP865) || | |
579 | + (dev->device == PCI_DEVICE_ID_ARTOP_ATP865R)) { | |
580 | + u32 bmide = pci_resource_start(dev, 4); | |
581 | + if (IN_BYTE(bmide+2) & 0x10) | |
582 | + mode |= 0x04; | |
583 | + else | |
584 | + mode |= 0x03; | |
585 | + } | |
586 | + if (!eighty_ninty_three(drive)) { | |
587 | + mode &= ~0xFE; | |
588 | + mode |= 0x01; | |
589 | + } | |
590 | + return (mode &= ~0xF8); | |
591 | +} | |
592 | + | |
593 | +static byte aec62xx_ratefilter (ide_drive_t *drive, byte speed) | |
594 | +{ | |
595 | +#ifdef CONFIG_BLK_DEV_IDEDMA | |
596 | + byte mode = aec62xx_ratemask(drive); | |
597 | + | |
598 | + switch(mode) { | |
599 | + case 0x04: while (speed > XFER_UDMA_6) speed--; break; | |
600 | + case 0x03: while (speed > XFER_UDMA_5) speed--; break; | |
601 | + case 0x02: while (speed > XFER_UDMA_4) speed--; break; | |
602 | + case 0x01: while (speed > XFER_UDMA_2) speed--; break; | |
603 | + case 0x00: | |
604 | + default: while (speed > XFER_MW_DMA_2) speed--; break; | |
605 | + break; | |
606 | + } | |
607 | +#else | |
608 | + while (speed > XFER_PIO_4) speed--; | |
609 | +#endif /* CONFIG_BLK_DEV_IDEDMA */ | |
610 | +// printk("%s: mode == %02x speed == %02x\n", drive->name, mode, speed); | |
611 | + return speed; | |
612 | } | |
613 | ||
614 | -static int aec6210_tune_chipset (ide_drive_t *drive, byte speed) | |
615 | +static int aec6210_tune_chipset (ide_drive_t *drive, byte xferspeed) | |
616 | { | |
617 | ide_hwif_t *hwif = HWIF(drive); | |
618 | struct pci_dev *dev = hwif->pci_dev; | |
619 | - int err = 0; | |
620 | + byte speed = aec62xx_ratefilter(drive, xferspeed); | |
621 | unsigned short d_conf = 0x0000; | |
622 | byte ultra = 0x00; | |
623 | byte ultra_conf = 0x00; | |
624 | @@ -236,11 +332,10 @@ | |
625 | byte tmp2 = 0x00; | |
626 | unsigned long flags; | |
627 | ||
628 | - __save_flags(flags); /* local CPU only */ | |
629 | - __cli(); /* local CPU only */ | |
630 | - | |
631 | + local_irq_save(flags); | |
632 | pci_read_config_word(dev, 0x40|(2*drive->dn), &d_conf); | |
633 | - tmp0 = pci_bus_clock_list(speed, aec62xx_base); | |
634 | + tmp0 = pci_bus_clock_list(speed, | |
635 | + (struct chipset_bus_clock_list_entry *) dev->driver_data); | |
636 | SPLIT_BYTE(tmp0,tmp1,tmp2); | |
637 | MAKE_WORD(d_conf,tmp1,tmp2); | |
638 | pci_write_config_word(dev, 0x40|(2*drive->dn), d_conf); | |
639 | @@ -249,23 +344,21 @@ | |
640 | tmp2 = 0x00; | |
641 | pci_read_config_byte(dev, 0x54, &ultra); | |
642 | tmp1 = ((0x00 << (2*drive->dn)) | (ultra & ~(3 << (2*drive->dn)))); | |
643 | - ultra_conf = pci_bus_clock_list_ultra(speed, aec62xx_base); | |
644 | + ultra_conf = pci_bus_clock_list_ultra(speed, | |
645 | + (struct chipset_bus_clock_list_entry *) dev->driver_data); | |
646 | tmp2 = ((ultra_conf << (2*drive->dn)) | (tmp1 & ~(3 << (2*drive->dn)))); | |
647 | pci_write_config_byte(dev, 0x54, tmp2); | |
648 | - | |
649 | - __restore_flags(flags); /* local CPU only */ | |
650 | - | |
651 | - err = ide_config_drive_speed(drive, speed); | |
652 | - return(err); | |
653 | + local_irq_restore(flags); | |
654 | + return(ide_config_drive_speed(drive, speed)); | |
655 | } | |
656 | ||
657 | -static int aec6260_tune_chipset (ide_drive_t *drive, byte speed) | |
658 | +static int aec6260_tune_chipset (ide_drive_t *drive, byte xferspeed) | |
659 | { | |
660 | ide_hwif_t *hwif = HWIF(drive); | |
661 | struct pci_dev *dev = hwif->pci_dev; | |
662 | byte unit = (drive->select.b.unit & 0x01); | |
663 | byte ultra_pci = hwif->channel ? 0x45 : 0x44; | |
664 | - int err = 0; | |
665 | + byte speed = aec62xx_ratefilter(drive, xferspeed); | |
666 | byte drive_conf = 0x00; | |
667 | byte ultra_conf = 0x00; | |
668 | byte ultra = 0x00; | |
669 | @@ -273,143 +366,91 @@ | |
670 | byte tmp2 = 0x00; | |
671 | unsigned long flags; | |
672 | ||
673 | - __save_flags(flags); /* local CPU only */ | |
674 | - __cli(); /* local CPU only */ | |
675 | - | |
676 | + local_irq_save(flags); | |
677 | pci_read_config_byte(dev, 0x40|drive->dn, &drive_conf); | |
678 | - drive_conf = pci_bus_clock_list(speed, aec62xx_base); | |
679 | + drive_conf = pci_bus_clock_list(speed, | |
680 | + (struct chipset_bus_clock_list_entry *) dev->driver_data); | |
681 | pci_write_config_byte(dev, 0x40|drive->dn, drive_conf); | |
682 | ||
683 | pci_read_config_byte(dev, ultra_pci, &ultra); | |
684 | tmp1 = ((0x00 << (4*unit)) | (ultra & ~(7 << (4*unit)))); | |
685 | - ultra_conf = pci_bus_clock_list_ultra(speed, aec62xx_base); | |
686 | + ultra_conf = pci_bus_clock_list_ultra(speed, | |
687 | + (struct chipset_bus_clock_list_entry *) dev->driver_data); | |
688 | tmp2 = ((ultra_conf << (4*unit)) | (tmp1 & ~(7 << (4*unit)))); | |
689 | pci_write_config_byte(dev, ultra_pci, tmp2); | |
690 | - __restore_flags(flags); /* local CPU only */ | |
691 | - | |
692 | - if (!drive->init_speed) | |
693 | - drive->init_speed = speed; | |
694 | - | |
695 | - err = ide_config_drive_speed(drive, speed); | |
696 | - drive->current_speed = speed; | |
697 | - return(err); | |
698 | + local_irq_restore(flags); | |
699 | + return(ide_config_drive_speed(drive, speed)); | |
700 | } | |
701 | ||
702 | - | |
703 | static int aec62xx_tune_chipset (ide_drive_t *drive, byte speed) | |
704 | { | |
705 | - if (HWIF(drive)->pci_dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF) { | |
706 | - return ((int) aec6210_tune_chipset(drive, speed)); | |
707 | - } else { | |
708 | - return ((int) aec6260_tune_chipset(drive, speed)); | |
709 | + switch (HWIF(drive)->pci_dev->device) { | |
710 | + case PCI_DEVICE_ID_ARTOP_ATP865: | |
711 | + case PCI_DEVICE_ID_ARTOP_ATP865R: | |
712 | + case PCI_DEVICE_ID_ARTOP_ATP860: | |
713 | + case PCI_DEVICE_ID_ARTOP_ATP860R: | |
714 | + return ((int) aec6260_tune_chipset(drive, speed)); | |
715 | + case PCI_DEVICE_ID_ARTOP_ATP850UF: | |
716 | + return ((int) aec6210_tune_chipset(drive, speed)); | |
717 | + default: | |
718 | + return -1; | |
719 | } | |
720 | } | |
721 | ||
722 | #ifdef CONFIG_BLK_DEV_IDEDMA | |
723 | -static int config_aec6210_chipset_for_dma (ide_drive_t *drive, byte ultra) | |
724 | +static int config_chipset_for_dma (ide_drive_t *drive) | |
725 | { | |
726 | struct hd_driveid *id = drive->id; | |
727 | - ide_hwif_t *hwif = HWIF(drive); | |
728 | - byte unit = (drive->select.b.unit & 0x01); | |
729 | - unsigned long dma_base = hwif->dma_base; | |
730 | - byte speed = -1; | |
731 | - | |
732 | - if (drive->media != ide_disk) | |
733 | - return ((int) ide_dma_off_quietly); | |
734 | - | |
735 | - if (((id->dma_ultra & 0x0010) || | |
736 | - (id->dma_ultra & 0x0008) || | |
737 | - (id->dma_ultra & 0x0004)) && (ultra)) { | |
738 | - speed = XFER_UDMA_2; | |
739 | - } else if ((id->dma_ultra & 0x0002) && (ultra)) { | |
740 | - speed = XFER_UDMA_1; | |
741 | - } else if ((id->dma_ultra & 0x0001) && (ultra)) { | |
742 | - speed = XFER_UDMA_0; | |
743 | - } else if (id->dma_mword & 0x0004) { | |
744 | - speed = XFER_MW_DMA_2; | |
745 | - } else if (id->dma_mword & 0x0002) { | |
746 | - speed = XFER_MW_DMA_1; | |
747 | - } else if (id->dma_mword & 0x0001) { | |
748 | - speed = XFER_MW_DMA_0; | |
749 | - } else if (id->dma_1word & 0x0004) { | |
750 | - speed = XFER_SW_DMA_2; | |
751 | - } else if (id->dma_1word & 0x0002) { | |
752 | - speed = XFER_SW_DMA_1; | |
753 | - } else if (id->dma_1word & 0x0001) { | |
754 | - speed = XFER_SW_DMA_0; | |
755 | - } else { | |
756 | - return ((int) ide_dma_off_quietly); | |
757 | - } | |
758 | - | |
759 | - outb(inb(dma_base+2) & ~(1<<(5+unit)), dma_base+2); | |
760 | - (void) aec6210_tune_chipset(drive, speed); | |
761 | - | |
762 | - return ((int) ((id->dma_ultra >> 11) & 3) ? ide_dma_off : | |
763 | - ((id->dma_ultra >> 8) & 7) ? ide_dma_on : | |
764 | - ((id->dma_mword >> 8) & 7) ? ide_dma_on : | |
765 | - ((id->dma_1word >> 8) & 7) ? ide_dma_on : | |
766 | - ide_dma_off_quietly); | |
767 | -} | |
768 | - | |
769 | -static int config_aec6260_chipset_for_dma (ide_drive_t *drive, byte ultra) | |
770 | -{ | |
771 | - struct hd_driveid *id = drive->id; | |
772 | - ide_hwif_t *hwif = HWIF(drive); | |
773 | - byte unit = (drive->select.b.unit & 0x01); | |
774 | - unsigned long dma_base = hwif->dma_base; | |
775 | - byte speed = -1; | |
776 | - byte ultra66 = eighty_ninty_three(drive); | |
777 | + byte mode = aec62xx_ratemask(drive); | |
778 | + byte speed; | |
779 | ||
780 | if (drive->media != ide_disk) | |
781 | return ((int) ide_dma_off_quietly); | |
782 | - | |
783 | - if ((id->dma_ultra & 0x0010) && (ultra) && (ultra66)) { | |
784 | - speed = XFER_UDMA_4; | |
785 | - } else if ((id->dma_ultra & 0x0008) && (ultra) && (ultra66)) { | |
786 | - speed = XFER_UDMA_3; | |
787 | - } else if ((id->dma_ultra & 0x0004) && (ultra)) { | |
788 | - speed = XFER_UDMA_2; | |
789 | - } else if ((id->dma_ultra & 0x0002) && (ultra)) { | |
790 | - speed = XFER_UDMA_1; | |
791 | - } else if ((id->dma_ultra & 0x0001) && (ultra)) { | |
792 | - speed = XFER_UDMA_0; | |
793 | - } else if (id->dma_mword & 0x0004) { | |
794 | - speed = XFER_MW_DMA_2; | |
795 | - } else if (id->dma_mword & 0x0002) { | |
796 | - speed = XFER_MW_DMA_1; | |
797 | - } else if (id->dma_mword & 0x0001) { | |
798 | - speed = XFER_MW_DMA_0; | |
799 | - } else if (id->dma_1word & 0x0004) { | |
800 | - speed = XFER_SW_DMA_2; | |
801 | - } else if (id->dma_1word & 0x0002) { | |
802 | - speed = XFER_SW_DMA_1; | |
803 | - } else if (id->dma_1word & 0x0001) { | |
804 | - speed = XFER_SW_DMA_0; | |
805 | - } else { | |
806 | - return ((int) ide_dma_off_quietly); | |
807 | + | |
808 | + switch(mode) { | |
809 | + case 0x04: | |
810 | + if (id->dma_ultra & 0x0040) | |
811 | + { speed = XFER_UDMA_6; break; } | |
812 | + case 0x03: | |
813 | + if (id->dma_ultra & 0x0020) | |
814 | + { speed = XFER_UDMA_5; break; } | |
815 | + case 0x02: | |
816 | + if (id->dma_ultra & 0x0010) | |
817 | + { speed = XFER_UDMA_4; break; } | |
818 | + if (id->dma_ultra & 0x0008) | |
819 | + { speed = XFER_UDMA_3; break; } | |
820 | + case 0x01: | |
821 | + if (id->dma_ultra & 0x0004) | |
822 | + { speed = XFER_UDMA_2; break; } | |
823 | + if (id->dma_ultra & 0x0002) | |
824 | + { speed = XFER_UDMA_1; break; } | |
825 | + if (id->dma_ultra & 0x0001) | |
826 | + { speed = XFER_UDMA_0; break; } | |
827 | + case 0x00: | |
828 | + if (id->dma_mword & 0x0004) | |
829 | + { speed = XFER_MW_DMA_2; break; } | |
830 | + if (id->dma_mword & 0x0002) | |
831 | + { speed = XFER_MW_DMA_1; break; } | |
832 | + if (id->dma_mword & 0x0001) | |
833 | + { speed = XFER_MW_DMA_0; break; } | |
834 | + if (id->dma_1word & 0x0004) | |
835 | + { speed = XFER_SW_DMA_2; break; } | |
836 | + if (id->dma_1word & 0x0002) | |
837 | + { speed = XFER_SW_DMA_1; break; } | |
838 | + if (id->dma_1word & 0x0001) | |
839 | + { speed = XFER_SW_DMA_0; break; } | |
840 | + default: | |
841 | + return ((int) ide_dma_off_quietly); | |
842 | } | |
843 | ||
844 | - outb(inb(dma_base+2) & ~(1<<(5+unit)), dma_base+2); | |
845 | - (void) aec6260_tune_chipset(drive, speed); | |
846 | + (void) aec62xx_tune_chipset(drive, speed); | |
847 | ||
848 | - return ((int) ((id->dma_ultra >> 11) & 3) ? ide_dma_on : | |
849 | + return ((int) ((id->dma_ultra >> 11) & 15) ? ide_dma_on : | |
850 | ((id->dma_ultra >> 8) & 7) ? ide_dma_on : | |
851 | ((id->dma_mword >> 8) & 7) ? ide_dma_on : | |
852 | ((id->dma_1word >> 8) & 7) ? ide_dma_on : | |
853 | ide_dma_off_quietly); | |
854 | -} | |
855 | - | |
856 | -static int config_chipset_for_dma (ide_drive_t *drive, byte ultra) | |
857 | -{ | |
858 | - switch(HWIF(drive)->pci_dev->device) { | |
859 | - case PCI_DEVICE_ID_ARTOP_ATP850UF: | |
860 | - return config_aec6210_chipset_for_dma(drive, ultra); | |
861 | - case PCI_DEVICE_ID_ARTOP_ATP860: | |
862 | - case PCI_DEVICE_ID_ARTOP_ATP860R: | |
863 | - return config_aec6260_chipset_for_dma(drive, ultra); | |
864 | - default: | |
865 | - return ((int) ide_dma_off_quietly); | |
866 | - } | |
867 | +// return ((int) ide_dma_on); | |
868 | } | |
869 | ||
870 | #endif /* CONFIG_BLK_DEV_IDEDMA */ | |
871 | @@ -427,16 +468,7 @@ | |
872 | case 1: speed = XFER_PIO_1; break; | |
873 | default: speed = XFER_PIO_0; break; | |
874 | } | |
875 | - | |
876 | - switch(HWIF(drive)->pci_dev->device) { | |
877 | - case PCI_DEVICE_ID_ARTOP_ATP850UF: | |
878 | - (void) aec6210_tune_chipset(drive, speed); | |
879 | - case PCI_DEVICE_ID_ARTOP_ATP860: | |
880 | - case PCI_DEVICE_ID_ARTOP_ATP860R: | |
881 | - (void) aec6260_tune_chipset(drive, speed); | |
882 | - default: | |
883 | - break; | |
884 | - } | |
885 | + (void) aec62xx_tune_chipset(drive, speed); | |
886 | } | |
887 | ||
888 | #ifdef CONFIG_BLK_DEV_IDEDMA | |
889 | @@ -453,9 +485,9 @@ | |
890 | } | |
891 | dma_func = ide_dma_off_quietly; | |
892 | if (id->field_valid & 4) { | |
893 | - if (id->dma_ultra & 0x001F) { | |
894 | + if (id->dma_ultra & 0x007F) { | |
895 | /* Force if Capable UltraDMA */ | |
896 | - dma_func = config_chipset_for_dma(drive, 1); | |
897 | + dma_func = config_chipset_for_dma(drive); | |
898 | if ((id->field_valid & 2) && | |
899 | (dma_func != ide_dma_on)) | |
900 | goto try_dma_modes; | |
901 | @@ -465,7 +497,7 @@ | |
902 | if ((id->dma_mword & 0x0007) || | |
903 | (id->dma_1word & 0x0007)) { | |
904 | /* Force if Capable regular DMA modes */ | |
905 | - dma_func = config_chipset_for_dma(drive, 0); | |
906 | + dma_func = config_chipset_for_dma(drive); | |
907 | if (dma_func != ide_dma_on) | |
908 | goto no_dma_set; | |
909 | } | |
910 | @@ -474,7 +506,7 @@ | |
911 | goto no_dma_set; | |
912 | } | |
913 | /* Consult the list of known "good" drives */ | |
914 | - dma_func = config_chipset_for_dma(drive, 0); | |
915 | + dma_func = config_chipset_for_dma(drive); | |
916 | if (dma_func != ide_dma_on) | |
917 | goto no_dma_set; | |
918 | } else { | |
919 | @@ -494,49 +526,81 @@ | |
920 | */ | |
921 | int aec62xx_dmaproc (ide_dma_action_t func, ide_drive_t *drive) | |
922 | { | |
923 | + ide_hwif_t *hwif = HWIF(drive); | |
924 | + struct pci_dev *dev = hwif->pci_dev; | |
925 | + | |
926 | switch (func) { | |
927 | case ide_dma_check: | |
928 | return config_drive_xfer_rate(drive); | |
929 | case ide_dma_lostirq: | |
930 | case ide_dma_timeout: | |
931 | - switch(HWIF(drive)->pci_dev->device) { | |
932 | + switch(dev->device) { | |
933 | case PCI_DEVICE_ID_ARTOP_ATP860: | |
934 | case PCI_DEVICE_ID_ARTOP_ATP860R: | |
935 | -// { | |
936 | -// int i = 0; | |
937 | -// byte reg49h = 0; | |
938 | -// pci_read_config_byte(HWIF(drive)->pci_dev, 0x49, ®49h); | |
939 | -// for (i=0;i<256;i++) | |
940 | -// pci_write_config_byte(HWIF(drive)->pci_dev, 0x49, reg49h|0x10); | |
941 | -// pci_write_config_byte(HWIF(drive)->pci_dev, 0x49, reg49h & ~0x10); | |
942 | -// } | |
943 | -// return 0; | |
944 | + case PCI_DEVICE_ID_ARTOP_ATP865: | |
945 | + case PCI_DEVICE_ID_ARTOP_ATP865R: | |
946 | + printk(" AEC62XX time out "); | |
947 | +#if 0 | |
948 | + { | |
949 | + int i = 0; | |
950 | + byte reg49h = 0; | |
951 | + pci_read_config_byte(HWIF(drive)->pci_dev, 0x49, ®49h); | |
952 | + for (i=0;i<256;i++) | |
953 | + pci_write_config_byte(HWIF(drive)->pci_dev, 0x49, reg49h|0x10); | |
954 | + pci_write_config_byte(HWIF(drive)->pci_dev, 0x49, reg49h & ~0x10); | |
955 | + } | |
956 | + return 0; | |
957 | +#endif | |
958 | default: | |
959 | break; | |
960 | } | |
961 | default: | |
962 | break; | |
963 | } | |
964 | +#if 0 | |
965 | + { | |
966 | + ide_hwif_t *hwif = HWIF(drive); | |
967 | + struct pci_dev *dev = hwif->pci_dev; | |
968 | + unsigned long dma_base = hwif->dma_base; | |
969 | + byte tmp1 = 0x00; | |
970 | + byte tmp2 = 0x00; | |
971 | + | |
972 | + pci_read_config_byte(dev, 0x44, &tmp1); | |
973 | + pci_read_config_byte(dev, 0x45, &tmp2); | |
974 | + printk(" AEC6280 r44=%x r45=%x ",tmp1,tmp2); | |
975 | + if (hwif->channel) | |
976 | + dma_base -= 0x08; | |
977 | + tmp1=IN_BYTE(dma_base+2) & 0x10; | |
978 | + printk(" AEC6280 133=%x ",tmp1); | |
979 | + } | |
980 | +#endif | |
981 | return ide_dmaproc(func, drive); /* use standard DMA stuff */ | |
982 | } | |
983 | #endif /* CONFIG_BLK_DEV_IDEDMA */ | |
984 | -#endif /* CONFIG_AEC62XX_TUNING */ | |
985 | ||
986 | unsigned int __init pci_init_aec62xx (struct pci_dev *dev, const char *name) | |
987 | { | |
988 | + int bus_speed = system_bus_clock(); | |
989 | + | |
990 | if (dev->resource[PCI_ROM_RESOURCE].start) { | |
991 | pci_write_config_dword(dev, PCI_ROM_ADDRESS, dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE); | |
992 | printk("%s: ROM enabled at 0x%08lx\n", name, dev->resource[PCI_ROM_RESOURCE].start); | |
993 | } | |
994 | ||
995 | + aec_devs[n_aec_devs++] = dev; | |
996 | + | |
997 | #if defined(DISPLAY_AEC62XX_TIMINGS) && defined(CONFIG_PROC_FS) | |
998 | if (!aec62xx_proc) { | |
999 | aec62xx_proc = 1; | |
1000 | - bmide_dev = dev; | |
1001 | aec62xx_display_info = &aec62xx_get_info; | |
1002 | } | |
1003 | #endif /* DISPLAY_AEC62XX_TIMINGS && CONFIG_PROC_FS */ | |
1004 | ||
1005 | + if (bus_speed <= 33) | |
1006 | + dev->driver_data = (void *) aec6xxx_33_base; | |
1007 | + else | |
1008 | + dev->driver_data = (void *) aec6xxx_34_base; | |
1009 | + | |
1010 | return dev->irq; | |
1011 | } | |
1012 | ||
1013 | @@ -551,32 +615,56 @@ | |
1014 | ||
1015 | void __init ide_init_aec62xx (ide_hwif_t *hwif) | |
1016 | { | |
1017 | -#ifdef CONFIG_AEC62XX_TUNING | |
1018 | + hwif->autodma = 0; | |
1019 | hwif->tuneproc = &aec62xx_tune_drive; | |
1020 | hwif->speedproc = &aec62xx_tune_chipset; | |
1021 | -#ifdef CONFIG_BLK_DEV_IDEDMA | |
1022 | - if (hwif->dma_base) | |
1023 | - hwif->dmaproc = &aec62xx_dmaproc; | |
1024 | -#else /* !CONFIG_BLK_DEV_IDEDMA */ | |
1025 | hwif->drives[0].autotune = 1; | |
1026 | hwif->drives[1].autotune = 1; | |
1027 | + | |
1028 | + if (!hwif->dma_base) | |
1029 | + return; | |
1030 | + | |
1031 | +#ifdef CONFIG_BLK_DEV_IDEDMA | |
1032 | + hwif->dmaproc = &aec62xx_dmaproc; | |
1033 | +#ifdef CONFIG_IDEDMA_AUTO | |
1034 | + if (!noautodma) | |
1035 | + hwif->autodma = 1; | |
1036 | +#endif /* CONFIG_IDEDMA_AUTO */ | |
1037 | #endif /* CONFIG_BLK_DEV_IDEDMA */ | |
1038 | -#endif /* CONFIG_AEC62XX_TUNING */ | |
1039 | + | |
1040 | + | |
1041 | } | |
1042 | ||
1043 | void __init ide_dmacapable_aec62xx (ide_hwif_t *hwif, unsigned long dmabase) | |
1044 | { | |
1045 | -#ifdef CONFIG_AEC62XX_TUNING | |
1046 | + struct pci_dev *dev = hwif->pci_dev; | |
1047 | + byte reg54h = 0; | |
1048 | unsigned long flags; | |
1049 | - byte reg54h = 0; | |
1050 | ||
1051 | - __save_flags(flags); /* local CPU only */ | |
1052 | - __cli(); /* local CPU only */ | |
1053 | + spin_lock_irqsave(&io_request_lock, flags); | |
1054 | + pci_read_config_byte(dev, 0x54, ®54h); | |
1055 | + pci_write_config_byte(dev, 0x54, reg54h & ~(hwif->channel ? 0xF0 : 0x0F)); | |
1056 | + spin_unlock_irqrestore(&io_request_lock, flags); | |
1057 | + ide_setup_dma(hwif, dmabase, 8); | |
1058 | +} | |
1059 | ||
1060 | - pci_read_config_byte(hwif->pci_dev, 0x54, ®54h); | |
1061 | - pci_write_config_byte(hwif->pci_dev, 0x54, reg54h & ~(hwif->channel ? 0xF0 : 0x0F)); | |
1062 | +extern void ide_setup_pci_device(struct pci_dev *, ide_pci_device_t *); | |
1063 | ||
1064 | - __restore_flags(flags); /* local CPU only */ | |
1065 | -#endif /* CONFIG_AEC62XX_TUNING */ | |
1066 | - ide_setup_dma(hwif, dmabase, 8); | |
1067 | +void __init fixup_device_aec6x80 (struct pci_dev *dev, ide_pci_device_t *d) | |
1068 | +{ | |
1069 | + u32 bar4reg = pci_resource_start(dev, 4); | |
1070 | + | |
1071 | + if (IN_BYTE(bar4reg+2) & 0x10) { | |
1072 | + strcpy(d->name, "AEC6880"); | |
1073 | + if (dev->device == PCI_DEVICE_ID_ARTOP_ATP865R) | |
1074 | + strcpy(d->name, "AEC6880R"); | |
1075 | + } else { | |
1076 | + strcpy(d->name, "AEC6280"); | |
1077 | + if (dev->device == PCI_DEVICE_ID_ARTOP_ATP865R) | |
1078 | + strcpy(d->name, "AEC6280R"); | |
1079 | + } | |
1080 | + | |
1081 | + printk("%s: IDE controller on PCI bus %02x dev %02x\n", | |
1082 | + d->name, dev->bus->number, dev->devfn); | |
1083 | + ide_setup_pci_device(dev, d); | |
1084 | } | |
1085 | diff -Nur linux.org/drivers/ide/ali14xx.c linux/drivers/ide/ali14xx.c | |
1086 | --- linux.org/drivers/ide/ali14xx.c Mon Jul 16 01:22:23 2001 | |
1087 | +++ linux/drivers/ide/ali14xx.c Thu Jul 18 14:24:33 2002 | |
1088 | @@ -95,7 +95,7 @@ | |
1089 | static inline byte inReg (byte reg) | |
1090 | { | |
1091 | outb_p(reg, regPort); | |
1092 | - return inb(dataPort); | |
1093 | + return IN_BYTE(dataPort); | |
1094 | } | |
1095 | ||
1096 | /* | |
1097 | @@ -137,15 +137,14 @@ | |
1098 | ||
1099 | /* stuff timing parameters into controller registers */ | |
1100 | driveNum = (HWIF(drive)->index << 1) + drive->select.b.unit; | |
1101 | - save_flags(flags); /* all CPUs */ | |
1102 | - cli(); /* all CPUs */ | |
1103 | + spin_lock_irqsave(&io_request_lock, flags); | |
1104 | outb_p(regOn, basePort); | |
1105 | outReg(param1, regTab[driveNum].reg1); | |
1106 | outReg(param2, regTab[driveNum].reg2); | |
1107 | outReg(param3, regTab[driveNum].reg3); | |
1108 | outReg(param4, regTab[driveNum].reg4); | |
1109 | outb_p(regOff, basePort); | |
1110 | - restore_flags(flags); /* all CPUs */ | |
1111 | + spin_unlock_irqrestore(&io_request_lock, flags); | |
1112 | } | |
1113 | ||
1114 | /* | |
1115 | @@ -157,19 +156,18 @@ | |
1116 | byte t; | |
1117 | unsigned long flags; | |
1118 | ||
1119 | - __save_flags(flags); /* local CPU only */ | |
1120 | - __cli(); /* local CPU only */ | |
1121 | + local_irq_save(flags); | |
1122 | for (i = 0; i < ALI_NUM_PORTS; ++i) { | |
1123 | basePort = ports[i]; | |
1124 | - regOff = inb(basePort); | |
1125 | + regOff = IN_BYTE(basePort); | |
1126 | for (regOn = 0x30; regOn <= 0x33; ++regOn) { | |
1127 | outb_p(regOn, basePort); | |
1128 | - if (inb(basePort) == regOn) { | |
1129 | + if (IN_BYTE(basePort) == regOn) { | |
1130 | regPort = basePort + 4; | |
1131 | dataPort = basePort + 8; | |
1132 | t = inReg(0) & 0xf0; | |
1133 | outb_p(regOff, basePort); | |
1134 | - __restore_flags(flags); /* local CPU only */ | |
1135 | + local_irq_restore(flags); | |
1136 | if (t != 0x50) | |
1137 | return 0; | |
1138 | return 1; /* success */ | |
1139 | @@ -177,7 +175,7 @@ | |
1140 | } | |
1141 | outb_p(regOff, basePort); | |
1142 | } | |
1143 | - __restore_flags(flags); /* local CPU only */ | |
1144 | + local_irq_restore(flags); | |
1145 | return 0; | |
1146 | } | |
1147 | ||
1148 | @@ -189,15 +187,14 @@ | |
1149 | byte t; | |
1150 | unsigned long flags; | |
1151 | ||
1152 | - __save_flags(flags); /* local CPU only */ | |
1153 | - __cli(); /* local CPU only */ | |
1154 | + local_irq_save(flags); | |
1155 | outb_p(regOn, basePort); | |
1156 | for (p = initData; p->reg != 0; ++p) | |
1157 | outReg(p->data, p->reg); | |
1158 | outb_p(0x01, regPort); | |
1159 | - t = inb(regPort) & 0x01; | |
1160 | + t = IN_BYTE(regPort) & 0x01; | |
1161 | outb_p(regOff, basePort); | |
1162 | - __restore_flags(flags); /* local CPU only */ | |
1163 | + local_irq_restore(flags); | |
1164 | return t; | |
1165 | } | |
1166 | ||
1167 | diff -Nur linux.org/drivers/ide/alim15x3.c linux/drivers/ide/alim15x3.c | |
1168 | --- linux.org/drivers/ide/alim15x3.c Mon Jul 16 01:22:23 2001 | |
1169 | +++ linux/drivers/ide/alim15x3.c Thu Jul 18 14:24:33 2002 | |
1170 | @@ -89,8 +89,8 @@ | |
1171 | * at that point bibma+0x2 et bibma+0xa are byte | |
1172 | * registers to investigate: | |
1173 | */ | |
1174 | - c0 = inb((unsigned short)bibma + 0x02); | |
1175 | - c1 = inb((unsigned short)bibma + 0x0a); | |
1176 | + c0 = IN_BYTE((unsigned short)bibma + 0x02); | |
1177 | + c1 = IN_BYTE((unsigned short)bibma + 0x0a); | |
1178 | ||
1179 | p += sprintf(p, | |
1180 | "\n Ali M15x3 Chipset.\n"); | |
1181 | @@ -112,16 +112,20 @@ | |
1182 | (reg53h & 0x80) ? " OVERRD." : "." ); | |
1183 | ||
1184 | p += sprintf(p, | |
1185 | - "-------------------primary channel-------------------secondary channel---------\n\n"); | |
1186 | + "-------------------primary channel" | |
1187 | + "-------------------secondary channel" | |
1188 | + "---------\n\n"); | |
1189 | ||
1190 | pci_read_config_byte(bmide_dev, 0x09, ®53h); | |
1191 | p += sprintf(p, | |
1192 | - "channel status: %s %s\n", | |
1193 | + "channel status: %s" | |
1194 | + " %s\n", | |
1195 | (reg53h & 0x20) ? "On " : "Off", | |
1196 | (reg53h & 0x10) ? "On " : "Off" ); | |
1197 | ||
1198 | p += sprintf(p, | |
1199 | - "both channels togth: %s %s\n", | |
1200 | + "both channels togth: %s" | |
1201 | + " %s\n", | |
1202 | (c0&0x80) ? "No " : "Yes", | |
1203 | (c1&0x80) ? "No " : "Yes" ); | |
1204 | ||
1205 | @@ -134,24 +138,29 @@ | |
1206 | pci_read_config_byte(bmide_dev, 0x58, ®5xh); | |
1207 | pci_read_config_byte(bmide_dev, 0x5c, ®5yh); | |
1208 | p += sprintf(p, | |
1209 | - "Add. Setup Timing: %dT %dT\n", | |
1210 | + "Add. Setup Timing: %dT" | |
1211 | + " %dT\n", | |
1212 | (reg5xh & 0x07) ? (reg5xh & 0x07) : 8, | |
1213 | (reg5yh & 0x07) ? (reg5yh & 0x07) : 8 ); | |
1214 | ||
1215 | pci_read_config_byte(bmide_dev, 0x59, ®5xh); | |
1216 | pci_read_config_byte(bmide_dev, 0x5d, ®5yh); | |
1217 | p += sprintf(p, | |
1218 | - "Command Act. Count: %dT %dT\n" | |
1219 | - "Command Rec. Count: %dT %dT\n\n", | |
1220 | + "Command Act. Count: %dT" | |
1221 | + " %dT\n" | |
1222 | + "Command Rec. Count: %dT" | |
1223 | + " %dT\n\n", | |
1224 | (reg5xh & 0x70) ? ((reg5xh & 0x70) >> 4) : 8, | |
1225 | (reg5yh & 0x70) ? ((reg5yh & 0x70) >> 4) : 8, | |
1226 | (reg5xh & 0x0f) ? (reg5xh & 0x0f) : 16, | |
1227 | (reg5yh & 0x0f) ? (reg5yh & 0x0f) : 16 ); | |
1228 | ||
1229 | p += sprintf(p, | |
1230 | - "----------------drive0-----------drive1------------drive0-----------drive1------\n\n"); | |
1231 | + "----------------drive0-----------drive1" | |
1232 | + "------------drive0-----------drive1------\n\n"); | |
1233 | p += sprintf(p, | |
1234 | - "DMA enabled: %s %s %s %s\n", | |
1235 | + "DMA enabled: %s %s" | |
1236 | + " %s %s\n", | |
1237 | (c0&0x20) ? "Yes" : "No ", | |
1238 | (c0&0x40) ? "Yes" : "No ", | |
1239 | (c1&0x20) ? "Yes" : "No ", | |
1240 | @@ -159,7 +168,8 @@ | |
1241 | ||
1242 | pci_read_config_byte(bmide_dev, 0x54, ®5xh); | |
1243 | pci_read_config_byte(bmide_dev, 0x55, ®5yh); | |
1244 | - q = "FIFO threshold: %2d Words %2d Words %2d Words %2d Words\n"; | |
1245 | + q = "FIFO threshold: %2d Words %2d Words" | |
1246 | + " %2d Words %2d Words\n"; | |
1247 | if (rev < 0xc1) { | |
1248 | if ((rev == 0x20) && (pci_read_config_byte(bmide_dev, 0x4f, &tmp), (tmp &= 0x20))) { | |
1249 | p += sprintf(p, q, 8, 8, 8, 8); | |
1250 | @@ -180,7 +190,8 @@ | |
1251 | ||
1252 | #if 0 | |
1253 | p += sprintf(p, | |
1254 | - "FIFO threshold: %2d Words %2d Words %2d Words %2d Words\n", | |
1255 | + "FIFO threshold: %2d Words %2d Words" | |
1256 | + " %2d Words %2d Words\n", | |
1257 | (reg5xh & 0x03) + 12, | |
1258 | ((reg5xh & 0x30)>>4) + 12, | |
1259 | (reg5yh & 0x03) + 12, | |
1260 | @@ -200,9 +211,12 @@ | |
1261 | pci_read_config_byte(bmide_dev, 0x5f, ®5yh1); | |
1262 | ||
1263 | p += sprintf(p,/* | |
1264 | - "------------------drive0-----------drive1------------drive0-----------drive1------\n")*/ | |
1265 | - "Dt RW act. Cnt %2dT %2dT %2dT %2dT\n" | |
1266 | - "Dt RW rec. Cnt %2dT %2dT %2dT %2dT\n\n", | |
1267 | + "------------------drive0-----------drive1" | |
1268 | + "------------drive0-----------drive1------\n")*/ | |
1269 | + "Dt RW act. Cnt %2dT %2dT" | |
1270 | + " %2dT %2dT\n" | |
1271 | + "Dt RW rec. Cnt %2dT %2dT" | |
1272 | + " %2dT %2dT\n\n", | |
1273 | (reg5xh & 0x70) ? ((reg5xh & 0x70) >> 4) : 8, | |
1274 | (reg5xh1 & 0x70) ? ((reg5xh1 & 0x70) >> 4) : 8, | |
1275 | (reg5yh & 0x70) ? ((reg5yh & 0x70) >> 4) : 8, | |
1276 | @@ -213,13 +227,16 @@ | |
1277 | (reg5yh1 & 0x0f) ? (reg5yh1 & 0x0f) : 16 ); | |
1278 | ||
1279 | p += sprintf(p, | |
1280 | - "-----------------------------------UDMA Timings--------------------------------\n\n"); | |
1281 | + "-----------------------------------UDMA Timings" | |
1282 | + "--------------------------------\n\n"); | |
1283 | ||
1284 | pci_read_config_byte(bmide_dev, 0x56, ®5xh); | |
1285 | pci_read_config_byte(bmide_dev, 0x57, ®5yh); | |
1286 | p += sprintf(p, | |
1287 | - "UDMA: %s %s %s %s\n" | |
1288 | - "UDMA timings: %s %s %s %s\n\n", | |
1289 | + "UDMA: %s %s" | |
1290 | + " %s %s\n" | |
1291 | + "UDMA timings: %s %s" | |
1292 | + " %s %s\n\n", | |
1293 | (reg5xh & 0x08) ? "OK" : "No", | |
1294 | (reg5xh & 0x80) ? "OK" : "No", | |
1295 | (reg5yh & 0x08) ? "OK" : "No", | |
1296 | @@ -248,7 +265,7 @@ | |
1297 | byte s_clc, a_clc, r_clc; | |
1298 | unsigned long flags; | |
1299 | int bus_speed = system_bus_clock(); | |
1300 | - int port = hwif->index ? 0x5c : 0x58; | |
1301 | + int port = hwif->channel ? 0x5c : 0x58; | |
1302 | int portFIFO = hwif->channel ? 0x55 : 0x54; | |
1303 | byte cd_dma_fifo = 0; | |
1304 | ||
1305 | @@ -272,21 +289,20 @@ | |
1306 | if (r_clc >= 16) | |
1307 | r_clc = 0; | |
1308 | } | |
1309 | - __save_flags(flags); | |
1310 | - __cli(); | |
1311 | + local_irq_save(flags); | |
1312 | ||
1313 | /* | |
1314 | * PIO mode => ATA FIFO on, ATAPI FIFO off | |
1315 | */ | |
1316 | pci_read_config_byte(dev, portFIFO, &cd_dma_fifo); | |
1317 | if (drive->media==ide_disk) { | |
1318 | - if (hwif->index) { | |
1319 | + if (hwif->channel) { | |
1320 | pci_write_config_byte(dev, portFIFO, (cd_dma_fifo & 0x0F) | 0x50); | |
1321 | } else { | |
1322 | pci_write_config_byte(dev, portFIFO, (cd_dma_fifo & 0xF0) | 0x05); | |
1323 | } | |
1324 | } else { | |
1325 | - if (hwif->index) { | |
1326 | + if (hwif->channel) { | |
1327 | pci_write_config_byte(dev, portFIFO, cd_dma_fifo & 0x0F); | |
1328 | } else { | |
1329 | pci_write_config_byte(dev, portFIFO, cd_dma_fifo & 0xF0); | |
1330 | @@ -295,7 +311,7 @@ | |
1331 | ||
1332 | pci_write_config_byte(dev, port, s_clc); | |
1333 | pci_write_config_byte(dev, port+drive->select.b.unit+2, (a_clc << 4) | r_clc); | |
1334 | - __restore_flags(flags); | |
1335 | + local_irq_restore(flags); | |
1336 | ||
1337 | /* | |
1338 | * setup active rec | |
1339 | @@ -309,14 +325,79 @@ | |
1340 | ||
1341 | } | |
1342 | ||
1343 | -static int ali15x3_tune_chipset (ide_drive_t *drive, byte speed) | |
1344 | +static byte ali15x3_can_ultra (ide_drive_t *drive) | |
1345 | { | |
1346 | - ide_hwif_t *hwif = HWIF(drive); | |
1347 | +#ifndef CONFIG_WDC_ALI15X3 | |
1348 | + struct hd_driveid *id = drive->id; | |
1349 | +#endif /* CONFIG_WDC_ALI15X3 */ | |
1350 | + | |
1351 | + if (m5229_revision <= 0x20) { | |
1352 | + return 0; | |
1353 | + } else if ((m5229_revision < 0xC2) && | |
1354 | +#ifndef CONFIG_WDC_ALI15X3 | |
1355 | + ((chip_is_1543c_e && strstr(id->model, "WDC ")) || | |
1356 | + (drive->media!=ide_disk))) { | |
1357 | +#else /* CONFIG_WDC_ALI15X3 */ | |
1358 | + (drive->media!=ide_disk)) { | |
1359 | +#endif /* CONFIG_WDC_ALI15X3 */ | |
1360 | + return 0; | |
1361 | + } else { | |
1362 | + return 1; | |
1363 | + } | |
1364 | +} | |
1365 | + | |
1366 | +static byte ali15x3_ratemask (ide_drive_t *drive) | |
1367 | +{ | |
1368 | +// struct pci_dev *dev = HWIF(drive)->pci_dev; | |
1369 | + byte mode = 0x00; | |
1370 | + byte can_ultra = ali15x3_can_ultra(drive); | |
1371 | + | |
1372 | + if ((m5229_revision >= 0xC4) && (can_ultra)) { | |
1373 | + mode |= 0x03; | |
1374 | + } else if ((m5229_revision >= 0xC2) && (can_ultra)) { | |
1375 | + mode |= 0x02; | |
1376 | + } else if (can_ultra) { | |
1377 | + mode |= 0x01; | |
1378 | + } else { | |
1379 | + return (mode &= ~0xFF); | |
1380 | + } | |
1381 | + | |
1382 | + if (!eighty_ninty_three(drive)) { | |
1383 | + mode &= ~0xFE; | |
1384 | + mode |= 0x01; | |
1385 | + } | |
1386 | + return (mode &= ~0xF8); | |
1387 | +} | |
1388 | + | |
1389 | +static byte ali15x3_ratefilter (ide_drive_t *drive, byte speed) | |
1390 | +{ | |
1391 | +#ifdef CONFIG_BLK_DEV_IDEDMA | |
1392 | + byte mode = ali15x3_ratemask(drive); | |
1393 | + | |
1394 | + switch(mode) { | |
1395 | + case 0x04: while (speed > XFER_UDMA_6) speed--; break; | |
1396 | + case 0x03: while (speed > XFER_UDMA_5) speed--; break; | |
1397 | + case 0x02: while (speed > XFER_UDMA_4) speed--; break; | |
1398 | + case 0x01: while (speed > XFER_UDMA_2) speed--; break; | |
1399 | + case 0x00: | |
1400 | + default: while (speed > XFER_MW_DMA_2) speed--; break; | |
1401 | + break; | |
1402 | + } | |
1403 | +#else | |
1404 | + while (speed > XFER_PIO_4) speed--; | |
1405 | +#endif /* CONFIG_BLK_DEV_IDEDMA */ | |
1406 | +// printk("%s: mode == %02x speed == %02x\n", drive->name, mode, speed); | |
1407 | + return speed; | |
1408 | +} | |
1409 | + | |
1410 | +static int ali15x3_tune_chipset (ide_drive_t *drive, byte xferspeed) | |
1411 | +{ | |
1412 | + ide_hwif_t *hwif = HWIF(drive); | |
1413 | struct pci_dev *dev = hwif->pci_dev; | |
1414 | + byte speed = ali15x3_ratefilter(drive, xferspeed); | |
1415 | byte unit = (drive->select.b.unit & 0x01); | |
1416 | byte tmpbyte = 0x00; | |
1417 | - int m5229_udma = hwif->channel? 0x57 : 0x56; | |
1418 | - int err = 0; | |
1419 | + int m5229_udma = (hwif->channel) ? 0x57 : 0x56; | |
1420 | ||
1421 | if (speed < XFER_UDMA_0) { | |
1422 | byte ultra_enable = (unit) ? 0x7f : 0xf7; | |
1423 | @@ -326,18 +407,11 @@ | |
1424 | pci_read_config_byte(dev, m5229_udma, &tmpbyte); | |
1425 | tmpbyte &= ultra_enable; | |
1426 | pci_write_config_byte(dev, m5229_udma, tmpbyte); | |
1427 | - } | |
1428 | - | |
1429 | - err = ide_config_drive_speed(drive, speed); | |
1430 | ||
1431 | + if (speed < XFER_SW_DMA_0) | |
1432 | + ali15x3_tune_drive(drive, speed); | |
1433 | #ifdef CONFIG_BLK_DEV_IDEDMA | |
1434 | - if (speed >= XFER_SW_DMA_0) { | |
1435 | - unsigned long dma_base = hwif->dma_base; | |
1436 | - | |
1437 | - outb(inb(dma_base+2)|(1<<(5+unit)), dma_base+2); | |
1438 | - } | |
1439 | - | |
1440 | - if (speed >= XFER_UDMA_0) { | |
1441 | + } else { | |
1442 | pci_read_config_byte(dev, m5229_udma, &tmpbyte); | |
1443 | tmpbyte &= (0x0f << ((1-unit) << 2)); | |
1444 | /* | |
1445 | @@ -350,89 +424,58 @@ | |
1446 | tmpbyte |= 1; | |
1447 | pci_write_config_byte(dev, 0x4b, tmpbyte); | |
1448 | } | |
1449 | - } | |
1450 | #endif /* CONFIG_BLK_DEV_IDEDMA */ | |
1451 | - | |
1452 | - drive->current_speed = speed; | |
1453 | - | |
1454 | - return (err); | |
1455 | -} | |
1456 | - | |
1457 | -static void config_chipset_for_pio (ide_drive_t *drive) | |
1458 | -{ | |
1459 | - ali15x3_tune_drive(drive, 5); | |
1460 | + } | |
1461 | + return (ide_config_drive_speed(drive, speed)); | |
1462 | } | |
1463 | ||
1464 | #ifdef CONFIG_BLK_DEV_IDEDMA | |
1465 | -static int config_chipset_for_dma (ide_drive_t *drive, byte ultra33) | |
1466 | +static int config_chipset_for_dma (ide_drive_t *drive) | |
1467 | { | |
1468 | struct hd_driveid *id = drive->id; | |
1469 | - byte speed = 0x00; | |
1470 | - byte ultra66 = eighty_ninty_three(drive); | |
1471 | - byte ultra100 = (m5229_revision>=0xc4) ? 1 : 0; | |
1472 | - int rval; | |
1473 | - | |
1474 | - if ((id->dma_ultra & 0x0020) && (ultra100) && (ultra66) && (ultra33)) { | |
1475 | - speed = XFER_UDMA_5; | |
1476 | - } else if ((id->dma_ultra & 0x0010) && (ultra66) && (ultra33)) { | |
1477 | - speed = XFER_UDMA_4; | |
1478 | - } else if ((id->dma_ultra & 0x0008) && (ultra66) && (ultra33)) { | |
1479 | - speed = XFER_UDMA_3; | |
1480 | - } else if ((id->dma_ultra & 0x0004) && (ultra33)) { | |
1481 | - speed = XFER_UDMA_2; | |
1482 | - } else if ((id->dma_ultra & 0x0002) && (ultra33)) { | |
1483 | - speed = XFER_UDMA_1; | |
1484 | - } else if ((id->dma_ultra & 0x0001) && (ultra33)) { | |
1485 | - speed = XFER_UDMA_0; | |
1486 | - } else if (id->dma_mword & 0x0004) { | |
1487 | - speed = XFER_MW_DMA_2; | |
1488 | - } else if (id->dma_mword & 0x0002) { | |
1489 | - speed = XFER_MW_DMA_1; | |
1490 | - } else if (id->dma_mword & 0x0001) { | |
1491 | - speed = XFER_MW_DMA_0; | |
1492 | - } else if (id->dma_1word & 0x0004) { | |
1493 | - speed = XFER_SW_DMA_2; | |
1494 | - } else if (id->dma_1word & 0x0002) { | |
1495 | - speed = XFER_SW_DMA_1; | |
1496 | - } else if (id->dma_1word & 0x0001) { | |
1497 | - speed = XFER_SW_DMA_0; | |
1498 | - } else { | |
1499 | - return ((int) ide_dma_off_quietly); | |
1500 | + byte mode = ali15x3_ratemask(drive); | |
1501 | + byte speed = 0; | |
1502 | + | |
1503 | + switch(mode) { | |
1504 | + case 0x03: | |
1505 | + if (id->dma_ultra & 0x0020) | |
1506 | + { speed = XFER_UDMA_5; break; } | |
1507 | + case 0x02: | |
1508 | + if (id->dma_ultra & 0x0010) | |
1509 | + { speed = XFER_UDMA_4; break; } | |
1510 | + if (id->dma_ultra & 0x0008) | |
1511 | + { speed = XFER_UDMA_3; break; } | |
1512 | + case 0x01: | |
1513 | + if (id->dma_ultra & 0x0004) | |
1514 | + { speed = XFER_UDMA_2; break; } | |
1515 | + if (id->dma_ultra & 0x0002) | |
1516 | + { speed = XFER_UDMA_1; break; } | |
1517 | + if (id->dma_ultra & 0x0001) | |
1518 | + { speed = XFER_UDMA_0; break; } | |
1519 | + case 0x00: | |
1520 | + if (id->dma_mword & 0x0004) | |
1521 | + { speed = XFER_MW_DMA_2; break; } | |
1522 | + if (id->dma_mword & 0x0002) | |
1523 | + { speed = XFER_MW_DMA_1; break; } | |
1524 | + if (id->dma_mword & 0x0001) | |
1525 | + { speed = XFER_MW_DMA_0; break; } | |
1526 | + if (id->dma_1word & 0x0004) | |
1527 | + { speed = XFER_SW_DMA_2; break; } | |
1528 | + if (id->dma_1word & 0x0002) | |
1529 | + { speed = XFER_SW_DMA_1; break; } | |
1530 | + if (id->dma_1word & 0x0001) | |
1531 | + { speed = XFER_SW_DMA_0; break; } | |
1532 | + default: | |
1533 | + return ((int) ide_dma_off_quietly); | |
1534 | } | |
1535 | ||
1536 | (void) ali15x3_tune_chipset(drive, speed); | |
1537 | - | |
1538 | - if (!drive->init_speed) | |
1539 | - drive->init_speed = speed; | |
1540 | - | |
1541 | - rval = (int)( ((id->dma_ultra >> 11) & 3) ? ide_dma_on : | |
1542 | +// return ((int) (dma) ? ide_dma_on : ide_dma_off_quietly); | |
1543 | + return ((int) ((id->dma_ultra >> 11) & 7) ? ide_dma_on : | |
1544 | ((id->dma_ultra >> 8) & 7) ? ide_dma_on : | |
1545 | ((id->dma_mword >> 8) & 7) ? ide_dma_on : | |
1546 | ((id->dma_1word >> 8) & 7) ? ide_dma_on : | |
1547 | ide_dma_off_quietly); | |
1548 | - | |
1549 | - return rval; | |
1550 | -} | |
1551 | - | |
1552 | -static byte ali15x3_can_ultra (ide_drive_t *drive) | |
1553 | -{ | |
1554 | -#ifndef CONFIG_WDC_ALI15X3 | |
1555 | - struct hd_driveid *id = drive->id; | |
1556 | -#endif /* CONFIG_WDC_ALI15X3 */ | |
1557 | - | |
1558 | - if (m5229_revision <= 0x20) { | |
1559 | - return 0; | |
1560 | - } else if ((m5229_revision < 0xC2) && | |
1561 | -#ifndef CONFIG_WDC_ALI15X3 | |
1562 | - ((chip_is_1543c_e && strstr(id->model, "WDC ")) || | |
1563 | - (drive->media!=ide_disk))) { | |
1564 | -#else /* CONFIG_WDC_ALI15X3 */ | |
1565 | - (drive->media!=ide_disk)) { | |
1566 | -#endif /* CONFIG_WDC_ALI15X3 */ | |
1567 | - return 0; | |
1568 | - } else { | |
1569 | - return 1; | |
1570 | - } | |
1571 | } | |
1572 | ||
1573 | static int ali15x3_config_drive_for_dma(ide_drive_t *drive) | |
1574 | @@ -440,11 +483,12 @@ | |
1575 | struct hd_driveid *id = drive->id; | |
1576 | ide_hwif_t *hwif = HWIF(drive); | |
1577 | ide_dma_action_t dma_func = ide_dma_on; | |
1578 | - byte can_ultra_dma = ali15x3_can_ultra(drive); | |
1579 | ||
1580 | if ((m5229_revision<=0x20) && (drive->media!=ide_disk)) | |
1581 | return hwif->dmaproc(ide_dma_off_quietly, drive); | |
1582 | ||
1583 | + drive->init_speed = 0; | |
1584 | + | |
1585 | if ((id != NULL) && ((id->capability & 1) != 0) && hwif->autodma) { | |
1586 | /* Consult the list of known "bad" drives */ | |
1587 | if (ide_dmaproc(ide_dma_bad_drive, drive)) { | |
1588 | @@ -453,9 +497,9 @@ | |
1589 | } | |
1590 | dma_func = ide_dma_off_quietly; | |
1591 | if ((id->field_valid & 4) && (m5229_revision >= 0xC2)) { | |
1592 | - if (id->dma_ultra & 0x002F) { | |
1593 | + if (id->dma_ultra & 0x003F) { | |
1594 | /* Force if Capable UltraDMA */ | |
1595 | - dma_func = config_chipset_for_dma(drive, can_ultra_dma); | |
1596 | + dma_func = config_chipset_for_dma(drive); | |
1597 | if ((id->field_valid & 2) && | |
1598 | (dma_func != ide_dma_on)) | |
1599 | goto try_dma_modes; | |
1600 | @@ -465,7 +509,7 @@ | |
1601 | if ((id->dma_mword & 0x0007) || | |
1602 | (id->dma_1word & 0x0007)) { | |
1603 | /* Force if Capable regular DMA modes */ | |
1604 | - dma_func = config_chipset_for_dma(drive, can_ultra_dma); | |
1605 | + dma_func = config_chipset_for_dma(drive); | |
1606 | if (dma_func != ide_dma_on) | |
1607 | goto no_dma_set; | |
1608 | } | |
1609 | @@ -474,7 +518,7 @@ | |
1610 | goto no_dma_set; | |
1611 | } | |
1612 | /* Consult the list of known "good" drives */ | |
1613 | - dma_func = config_chipset_for_dma(drive, can_ultra_dma); | |
1614 | + dma_func = config_chipset_for_dma(drive); | |
1615 | if (dma_func != ide_dma_on) | |
1616 | goto no_dma_set; | |
1617 | } else { | |
1618 | @@ -484,7 +528,7 @@ | |
1619 | fast_ata_pio: | |
1620 | dma_func = ide_dma_off_quietly; | |
1621 | no_dma_set: | |
1622 | - config_chipset_for_pio(drive); | |
1623 | + hwif->tuneproc(drive, 5); | |
1624 | } | |
1625 | return hwif->dmaproc(dma_func, drive); | |
1626 | } | |
1627 | @@ -495,7 +539,8 @@ | |
1628 | case ide_dma_check: | |
1629 | return ali15x3_config_drive_for_dma(drive); | |
1630 | case ide_dma_write: | |
1631 | - if ((m5229_revision < 0xC2) && (drive->media != ide_disk)) | |
1632 | + if ((m5229_revision < 0xC2) && | |
1633 | + (drive->media != ide_disk)) | |
1634 | return 1; /* try PIO instead of DMA */ | |
1635 | break; | |
1636 | default: | |
1637 | @@ -505,10 +550,17 @@ | |
1638 | } | |
1639 | #endif /* CONFIG_BLK_DEV_IDEDMA */ | |
1640 | ||
1641 | +#define ALI_INIT_CODE_TEST | |
1642 | + | |
1643 | unsigned int __init pci_init_ali15x3 (struct pci_dev *dev, const char *name) | |
1644 | { | |
1645 | unsigned long fixdma_base = pci_resource_start(dev, 4); | |
1646 | ||
1647 | +#ifdef ALI_INIT_CODE_TEST | |
1648 | + unsigned long flags; | |
1649 | + byte tmpbyte; | |
1650 | +#endif /* ALI_INIT_CODE_TEST */ | |
1651 | + | |
1652 | pci_read_config_byte(dev, PCI_REVISION_ID, &m5229_revision); | |
1653 | ||
1654 | isa_dev = pci_find_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL); | |
1655 | @@ -521,9 +573,9 @@ | |
1656 | /* | |
1657 | * enable DMA capable bit, and "not" simplex only | |
1658 | */ | |
1659 | - outb(inb(fixdma_base+2) & 0x60, fixdma_base+2); | |
1660 | + OUT_BYTE(IN_BYTE(fixdma_base+2) & 0x60, fixdma_base+2); | |
1661 | ||
1662 | - if (inb(fixdma_base+2) & 0x80) | |
1663 | + if (IN_BYTE(fixdma_base+2) & 0x80) | |
1664 | printk("%s: simplex device: DMA will fail!!\n", name); | |
1665 | } | |
1666 | ||
1667 | @@ -535,6 +587,55 @@ | |
1668 | } | |
1669 | #endif /* defined(DISPLAY_ALI_TIMINGS) && defined(CONFIG_PROC_FS) */ | |
1670 | ||
1671 | +#ifdef ALI_INIT_CODE_TEST | |
1672 | + local_irq_save(flags); | |
1673 | + | |
1674 | + if (m5229_revision >= 0xC2) { | |
1675 | + /* | |
1676 | + * 1543C-B?, 1535, 1535D, 1553 | |
1677 | + * Note 1: not all "motherboard" support this detection | |
1678 | + * Note 2: if no udma 66 device, the detection may "error". | |
1679 | + * but in this case, we will not set the device to | |
1680 | + * ultra 66, the detection result is not important | |
1681 | + */ | |
1682 | + | |
1683 | + /* | |
1684 | + * enable "Cable Detection", m5229, 0x4b, bit3 | |
1685 | + */ | |
1686 | + pci_read_config_byte(dev, 0x4b, &tmpbyte); | |
1687 | + pci_write_config_byte(dev, 0x4b, tmpbyte | 0x08); | |
1688 | + | |
1689 | + /* | |
1690 | + * set south-bridge's enable bit, m1533, 0x79 | |
1691 | + */ | |
1692 | + pci_read_config_byte(isa_dev, 0x79, &tmpbyte); | |
1693 | + if (m5229_revision == 0xC2) { | |
1694 | + /* | |
1695 | + * 1543C-B0 (m1533, 0x79, bit 2) | |
1696 | + */ | |
1697 | + pci_write_config_byte(isa_dev, 0x79, tmpbyte | 0x04); | |
1698 | + } else if (m5229_revision >= 0xC3) { | |
1699 | + /* | |
1700 | + * 1553/1535 (m1533, 0x79, bit 1) | |
1701 | + */ | |
1702 | + pci_write_config_byte(isa_dev, 0x79, tmpbyte | 0x02); | |
1703 | + } | |
1704 | + } else { | |
1705 | + /* | |
1706 | + * revision 0x20 (1543-E, 1543-F) | |
1707 | + * revision 0xC0, 0xC1 (1543C-C, 1543C-D, 1543C-E) | |
1708 | + * clear CD-ROM DMA write bit, m5229, 0x4b, bit 7 | |
1709 | + */ | |
1710 | + pci_read_config_byte(dev, 0x4b, &tmpbyte); | |
1711 | + /* | |
1712 | + * clear bit 7 | |
1713 | + */ | |
1714 | + pci_write_config_byte(dev, 0x4b, tmpbyte & 0x7F); | |
1715 | + } | |
1716 | + | |
1717 | + local_irq_save(flags); | |
1718 | +#endif /* ALI_INIT_CODE_TEST */ | |
1719 | + | |
1720 | return 0; | |
1721 | } | |
1722 | ||
1723 | @@ -552,10 +653,10 @@ | |
1724 | unsigned long flags; | |
1725 | byte tmpbyte; | |
1726 | ||
1727 | - __save_flags(flags); | |
1728 | - __cli(); | |
1729 | + local_irq_save(flags); | |
1730 | ||
1731 | if (m5229_revision >= 0xC2) { | |
1732 | +#ifndef ALI_INIT_CODE_TEST | |
1733 | /* | |
1734 | * 1543C-B?, 1535, 1535D, 1553 | |
1735 | * Note 1: not all "motherboard" support this detection | |
1736 | @@ -585,6 +686,7 @@ | |
1737 | */ | |
1738 | pci_write_config_byte(isa_dev, 0x79, tmpbyte | 0x02); | |
1739 | } | |
1740 | +#endif /* ALI_INIT_CODE_TEST */ | |
1741 | /* | |
1742 | * Ultra66 cable detection (from Host View) | |
1743 | * m5229, 0x4a, bit0: primary, bit1: secondary 80 pin | |
1744 | @@ -605,6 +707,7 @@ | |
1745 | */ | |
1746 | ata66 = (hwif->channel)?cable_80_pin[1]:cable_80_pin[0]; | |
1747 | } else { | |
1748 | +#ifndef ALI_INIT_CODE_TEST | |
1749 | /* | |
1750 | * revision 0x20 (1543-E, 1543-F) | |
1751 | * revision 0xC0, 0xC1 (1543C-C, 1543C-D, 1543C-E) | |
1752 | @@ -615,6 +718,7 @@ | |
1753 | * clear bit 7 | |
1754 | */ | |
1755 | pci_write_config_byte(dev, 0x4b, tmpbyte & 0x7F); | |
1756 | +#endif /* ALI_INIT_CODE_TEST */ | |
1757 | /* | |
1758 | * check m1533, 0x5e, bit 1~4 == 1001 => & 00011110 = 00010010 | |
1759 | */ | |
1760 | @@ -633,7 +737,7 @@ | |
1761 | ||
1762 | pci_write_config_byte(dev, 0x53, tmpbyte); | |
1763 | ||
1764 | - __restore_flags(flags); | |
1765 | + local_irq_restore(flags); | |
1766 | ||
1767 | return(ata66); | |
1768 | } | |
1769 | @@ -657,7 +761,8 @@ | |
1770 | ideic = ideic & 0x03; | |
1771 | ||
1772 | /* get IRQ for IDE Controller */ | |
1773 | - if ((hwif->channel && ideic == 0x03) || (!hwif->channel && !ideic)) { | |
1774 | + if ((hwif->channel && ideic == 0x03) || | |
1775 | + (!hwif->channel && !ideic)) { | |
1776 | /* | |
1777 | * get SIRQ1 routing table | |
1778 | */ | |
1779 | @@ -675,24 +780,26 @@ | |
1780 | } | |
1781 | #endif /* CONFIG_SPARC64 */ | |
1782 | ||
1783 | + hwif->autodma = 0; | |
1784 | hwif->tuneproc = &ali15x3_tune_drive; | |
1785 | hwif->drives[0].autotune = 1; | |
1786 | hwif->drives[1].autotune = 1; | |
1787 | hwif->speedproc = &ali15x3_tune_chipset; | |
1788 | ||
1789 | + if (!hwif->dma_base) | |
1790 | + return; | |
1791 | + | |
1792 | #ifdef CONFIG_BLK_DEV_IDEDMA | |
1793 | - if ((hwif->dma_base) && (m5229_revision >= 0x20)) { | |
1794 | + if (m5229_revision >= 0x20) { | |
1795 | /* | |
1796 | * M1543C or newer for DMAing | |
1797 | */ | |
1798 | hwif->dmaproc = &ali15x3_dmaproc; | |
1799 | - hwif->autodma = 1; | |
1800 | +#ifdef CONFIG_IDEDMA_AUTO | |
1801 | + if (!noautodma) | |
1802 | + hwif->autodma = 1; | |
1803 | +#endif /* CONFIG_IDEDMA_AUTO */ | |
1804 | } | |
1805 | - | |
1806 | - if (noautodma) | |
1807 | - hwif->autodma = 0; | |
1808 | -#else | |
1809 | - hwif->autodma = 0; | |
1810 | #endif /* CONFIG_BLK_DEV_IDEDMA */ | |
1811 | } | |
1812 | ||
1813 | @@ -703,3 +810,16 @@ | |
1814 | } | |
1815 | ide_setup_dma(hwif, dmabase, 8); | |
1816 | } | |
1817 | + | |
1818 | +extern void ide_setup_pci_device (struct pci_dev *dev, ide_pci_device_t *d); | |
1819 | + | |
1820 | +void __init fixup_device_ali15x3 (struct pci_dev *dev, ide_pci_device_t *d) | |
1821 | +{ | |
1822 | + if (dev->resource[0].start != 0x01F1) | |
1823 | + ide_register_xp_fix(dev); | |
1824 | + | |
1825 | + printk("%s: IDE controller on PCI bus %02x dev %02x\n", | |
1826 | + d->name, dev->bus->number, dev->devfn); | |
1827 | + ide_setup_pci_device(dev, d); | |
1828 | +} | |
1829 | + | |
1830 | diff -Nur linux.org/drivers/ide/amd74xx.c linux/drivers/ide/amd74xx.c | |
1831 | --- linux.org/drivers/ide/amd74xx.c Mon Aug 13 23:56:19 2001 | |
1832 | +++ linux/drivers/ide/amd74xx.c Thu Jul 18 14:24:33 2002 | |
1833 | @@ -34,7 +34,6 @@ | |
1834 | ||
1835 | static int amd74xx_get_info(char *, char **, off_t, int); | |
1836 | extern int (*amd74xx_display_info)(char *, char **, off_t, int); /* ide-proc.c */ | |
1837 | -extern char *ide_media_verbose(ide_drive_t *); | |
1838 | static struct pci_dev *bmide_dev; | |
1839 | ||
1840 | static int amd74xx_get_info (char *buffer, char **addr, off_t offset, int count) | |
1841 | @@ -47,16 +46,22 @@ | |
1842 | * at that point bibma+0x2 et bibma+0xa are byte registers | |
1843 | * to investigate: | |
1844 | */ | |
1845 | - c0 = inb_p((unsigned short)bibma + 0x02); | |
1846 | - c1 = inb_p((unsigned short)bibma + 0x0a); | |
1847 | + c0 = IN_BYTE((unsigned short)bibma + 0x02); | |
1848 | + c1 = IN_BYTE((unsigned short)bibma + 0x0a); | |
1849 | ||
1850 | - p += sprintf(p, "\n AMD %04X VIPER Chipset.\n", bmide_dev->device); | |
1851 | - p += sprintf(p, "--------------- Primary Channel ---------------- Secondary Channel -------------\n"); | |
1852 | - p += sprintf(p, " %sabled %sabled\n", | |
1853 | + p += sprintf(p, "\n " | |
1854 | + "AMD %04X VIPER Chipset.\n", bmide_dev->device); | |
1855 | + p += sprintf(p, "--------------- Primary Channel " | |
1856 | + "---------------- Secondary Channel " | |
1857 | + "-------------\n"); | |
1858 | + p += sprintf(p, " %sabled " | |
1859 | + " %sabled\n", | |
1860 | (c0&0x80) ? "dis" : " en", | |
1861 | (c1&0x80) ? "dis" : " en"); | |
1862 | - p += sprintf(p, "--------------- drive0 --------- drive1 -------- drive0 ---------- drive1 ------\n"); | |
1863 | - p += sprintf(p, "DMA enabled: %s %s %s %s\n", | |
1864 | + p += sprintf(p, "--------------- drive0 --------- drive1 " | |
1865 | + "-------- drive0 ---------- drive1 ------\n"); | |
1866 | + p += sprintf(p, "DMA enabled: %s %s " | |
1867 | + " %s %s\n", | |
1868 | (c0&0x20) ? "yes" : "no ", (c0&0x40) ? "yes" : "no ", | |
1869 | (c1&0x20) ? "yes" : "no ", (c1&0x40) ? "yes" : "no " ); | |
1870 | p += sprintf(p, "UDMA\n"); | |
1871 | @@ -69,39 +74,85 @@ | |
1872 | ||
1873 | byte amd74xx_proc = 0; | |
1874 | ||
1875 | -extern char *ide_xfer_verbose (byte xfer_rate); | |
1876 | +static int amd74xx_mode5_check (struct pci_dev *dev) | |
1877 | +{ | |
1878 | + switch(dev->device) { | |
1879 | + case PCI_DEVICE_ID_AMD_VIPER_7411: | |
1880 | + case PCI_DEVICE_ID_AMD_VIPER_7441: | |
1881 | + return 1; | |
1882 | + default: | |
1883 | + return 0; | |
1884 | + } | |
1885 | +} | |
1886 | ||
1887 | static unsigned int amd74xx_swdma_check (struct pci_dev *dev) | |
1888 | { | |
1889 | unsigned int class_rev; | |
1890 | ||
1891 | - if (dev->device == PCI_DEVICE_ID_AMD_VIPER_7411) | |
1892 | - return 0; | |
1893 | + if (amd74xx_mode5_check(dev)) | |
1894 | + return 1; | |
1895 | ||
1896 | pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); | |
1897 | class_rev &= 0xff; | |
1898 | return ((int) (class_rev >= 7) ? 1 : 0); | |
1899 | } | |
1900 | ||
1901 | -static int amd74xx_swdma_error(ide_drive_t *drive) | |
1902 | +static int amd74xx_swdma_error (ide_drive_t *drive) | |
1903 | { | |
1904 | printk("%s: single-word DMA not support (revision < C4)\n", drive->name); | |
1905 | return 0; | |
1906 | } | |
1907 | ||
1908 | +static byte amd74xx_ratemask (ide_drive_t *drive) | |
1909 | +{ | |
1910 | + struct pci_dev *dev = HWIF(drive)->pci_dev; | |
1911 | + byte mode = 0x00; | |
1912 | + | |
1913 | + switch(dev->device) { | |
1914 | + case PCI_DEVICE_ID_AMD_VIPER_7441: | |
1915 | + case PCI_DEVICE_ID_AMD_VIPER_7411: { mode |= 0x03; break; } | |
1916 | + case PCI_DEVICE_ID_AMD_VIPER_7409: { mode |= 0x02; break; } | |
1917 | + case PCI_DEVICE_ID_AMD_COBRA_7401: { mode |= 0x01; break; } | |
1918 | + default: | |
1919 | + return (mode &= ~0xFF); | |
1920 | + } | |
1921 | + | |
1922 | + if (!eighty_ninty_three(drive)) { | |
1923 | + mode &= ~0xFE; | |
1924 | + mode |= 0x01; | |
1925 | + } | |
1926 | + return (mode &= ~0xF8); | |
1927 | +} | |
1928 | + | |
1929 | +static byte amd74xx_ratefilter (ide_drive_t *drive, byte speed) | |
1930 | +{ | |
1931 | +#ifdef CONFIG_BLK_DEV_IDEDMA | |
1932 | + byte mode = amd74xx_ratemask(drive); | |
1933 | + | |
1934 | + switch(mode) { | |
1935 | + case 0x04: // while (speed > XFER_UDMA_6) speed--; break; | |
1936 | + case 0x03: while (speed > XFER_UDMA_5) speed--; break; | |
1937 | + case 0x02: while (speed > XFER_UDMA_4) speed--; break; | |
1938 | + case 0x01: while (speed > XFER_UDMA_2) speed--; break; | |
1939 | + case 0x00: | |
1940 | + default: while (speed > XFER_MW_DMA_2) speed--; break; | |
1941 | + break; | |
1942 | + } | |
1943 | +#else | |
1944 | + while (speed > XFER_PIO_4) speed--; | |
1945 | +#endif /* CONFIG_BLK_DEV_IDEDMA */ | |
1946 | +// printk("%s: mode == %02x speed == %02x\n", drive->name, mode, speed); | |
1947 | + return speed; | |
1948 | +} | |
1949 | + | |
1950 | /* | |
1951 | * Here is where all the hard work goes to program the chipset. | |
1952 | - * | |
1953 | */ | |
1954 | -static int amd74xx_tune_chipset (ide_drive_t *drive, byte speed) | |
1955 | +static int amd74xx_tune_chipset (ide_drive_t *drive, byte xferspeed) | |
1956 | { | |
1957 | ide_hwif_t *hwif = HWIF(drive); | |
1958 | struct pci_dev *dev = hwif->pci_dev; | |
1959 | - int err = 0; | |
1960 | - byte unit = (drive->select.b.unit & 0x01); | |
1961 | -#ifdef CONFIG_BLK_DEV_IDEDMA | |
1962 | - unsigned long dma_base = hwif->dma_base; | |
1963 | -#endif /* CONFIG_BLK_DEV_IDEDMA */ | |
1964 | + byte speed = amd74xx_ratefilter(drive, xferspeed); | |
1965 | byte drive_pci = 0x00; | |
1966 | byte drive_pci2 = 0x00; | |
1967 | byte ultra_timing = 0x00; | |
1968 | @@ -121,32 +172,19 @@ | |
1969 | pci_read_config_byte(dev, drive_pci2, &dma_pio_timing); | |
1970 | pci_read_config_byte(dev, 0x4c, &pio_timing); | |
1971 | ||
1972 | -#ifdef DEBUG | |
1973 | - printk("%s: UDMA 0x%02x DMAPIO 0x%02x PIO 0x%02x ", | |
1974 | - drive->name, ultra_timing, dma_pio_timing, pio_timing); | |
1975 | -#endif | |
1976 | - | |
1977 | ultra_timing &= ~0xC7; | |
1978 | dma_pio_timing &= ~0xFF; | |
1979 | pio_timing &= ~(0x03 << drive->dn); | |
1980 | ||
1981 | -#ifdef DEBUG | |
1982 | - printk(":: UDMA 0x%02x DMAPIO 0x%02x PIO 0x%02x ", | |
1983 | - ultra_timing, dma_pio_timing, pio_timing); | |
1984 | -#endif | |
1985 | - | |
1986 | switch(speed) { | |
1987 | #ifdef CONFIG_BLK_DEV_IDEDMA | |
1988 | + case XFER_UDMA_7: | |
1989 | + case XFER_UDMA_6: | |
1990 | + speed = XFER_UDMA_5; | |
1991 | case XFER_UDMA_5: | |
1992 | -#undef __CAN_MODE_5 | |
1993 | -#ifdef __CAN_MODE_5 | |
1994 | ultra_timing |= 0x46; | |
1995 | dma_pio_timing |= 0x20; | |
1996 | break; | |
1997 | -#else | |
1998 | - printk("%s: setting to mode 4, driver problems in mode 5.\n", drive->name); | |
1999 | - speed = XFER_UDMA_4; | |
2000 | -#endif /* __CAN_MODE_5 */ | |
2001 | case XFER_UDMA_4: | |
2002 | ultra_timing |= 0x45; | |
2003 | dma_pio_timing |= 0x20; | |
2004 | @@ -212,75 +250,19 @@ | |
2005 | ||
2006 | pio_timing |= (0x03 << drive->dn); | |
2007 | ||
2008 | - if (!drive->init_speed) | |
2009 | - drive->init_speed = speed; | |
2010 | - | |
2011 | #ifdef CONFIG_BLK_DEV_IDEDMA | |
2012 | pci_write_config_byte(dev, drive_pci, ultra_timing); | |
2013 | #endif /* CONFIG_BLK_DEV_IDEDMA */ | |
2014 | pci_write_config_byte(dev, drive_pci2, dma_pio_timing); | |
2015 | pci_write_config_byte(dev, 0x4c, pio_timing); | |
2016 | ||
2017 | -#ifdef DEBUG | |
2018 | - printk(":: UDMA 0x%02x DMAPIO 0x%02x PIO 0x%02x\n", | |
2019 | - ultra_timing, dma_pio_timing, pio_timing); | |
2020 | -#endif | |
2021 | - | |
2022 | -#ifdef CONFIG_BLK_DEV_IDEDMA | |
2023 | - if (speed > XFER_PIO_4) { | |
2024 | - outb(inb(dma_base+2)|(1<<(5+unit)), dma_base+2); | |
2025 | - } else { | |
2026 | - outb(inb(dma_base+2) & ~(1<<(5+unit)), dma_base+2); | |
2027 | - } | |
2028 | -#endif /* CONFIG_BLK_DEV_IDEDMA */ | |
2029 | - | |
2030 | - err = ide_config_drive_speed(drive, speed); | |
2031 | - drive->current_speed = speed; | |
2032 | - return (err); | |
2033 | -} | |
2034 | - | |
2035 | -static void config_chipset_for_pio (ide_drive_t *drive) | |
2036 | -{ | |
2037 | - unsigned short eide_pio_timing[6] = {960, 480, 240, 180, 120, 90}; | |
2038 | - unsigned short xfer_pio = drive->id->eide_pio_modes; | |
2039 | - byte timing, speed, pio; | |
2040 | - | |
2041 | - pio = ide_get_best_pio_mode(drive, 255, 5, NULL); | |
2042 | - | |
2043 | - if (xfer_pio> 4) | |
2044 | - xfer_pio = 0; | |
2045 | - | |
2046 | - if (drive->id->eide_pio_iordy > 0) { | |
2047 | - for (xfer_pio = 5; | |
2048 | - xfer_pio>0 && | |
2049 | - drive->id->eide_pio_iordy>eide_pio_timing[xfer_pio]; | |
2050 | - xfer_pio--); | |
2051 | - } else { | |
2052 | - xfer_pio = (drive->id->eide_pio_modes & 4) ? 0x05 : | |
2053 | - (drive->id->eide_pio_modes & 2) ? 0x04 : | |
2054 | - (drive->id->eide_pio_modes & 1) ? 0x03 : | |
2055 | - (drive->id->tPIO & 2) ? 0x02 : | |
2056 | - (drive->id->tPIO & 1) ? 0x01 : xfer_pio; | |
2057 | - } | |
2058 | - | |
2059 | - timing = (xfer_pio >= pio) ? xfer_pio : pio; | |
2060 | - | |
2061 | - switch(timing) { | |
2062 | - case 4: speed = XFER_PIO_4;break; | |
2063 | - case 3: speed = XFER_PIO_3;break; | |
2064 | - case 2: speed = XFER_PIO_2;break; | |
2065 | - case 1: speed = XFER_PIO_1;break; | |
2066 | - default: | |
2067 | - speed = (!drive->id->tPIO) ? XFER_PIO_0 : XFER_PIO_SLOW; | |
2068 | - break; | |
2069 | - } | |
2070 | - (void) amd74xx_tune_chipset(drive, speed); | |
2071 | - drive->current_speed = speed; | |
2072 | + return (ide_config_drive_speed(drive, speed)); | |
2073 | } | |
2074 | ||
2075 | static void amd74xx_tune_drive (ide_drive_t *drive, byte pio) | |
2076 | { | |
2077 | byte speed; | |
2078 | + pio = ide_get_best_pio_mode(drive, pio, 5, NULL); | |
2079 | switch(pio) { | |
2080 | case 4: speed = XFER_PIO_4;break; | |
2081 | case 3: speed = XFER_PIO_3;break; | |
2082 | @@ -299,52 +281,69 @@ | |
2083 | */ | |
2084 | static int config_chipset_for_dma (ide_drive_t *drive) | |
2085 | { | |
2086 | - ide_hwif_t *hwif = HWIF(drive); | |
2087 | - struct pci_dev *dev = hwif->pci_dev; | |
2088 | - struct hd_driveid *id = drive->id; | |
2089 | - byte udma_66 = eighty_ninty_three(drive); | |
2090 | - byte udma_100 = (dev->device==PCI_DEVICE_ID_AMD_VIPER_7411) ? 1 : 0; | |
2091 | - byte speed = 0x00; | |
2092 | + struct hd_driveid *id = drive->id; | |
2093 | + byte mode = amd74xx_ratemask(drive); | |
2094 | + byte swdma = amd74xx_swdma_check(HWIF(drive)->pci_dev); | |
2095 | + byte speed = 0; | |
2096 | int rval; | |
2097 | ||
2098 | - if ((id->dma_ultra & 0x0020) && (udma_66)&& (udma_100)) { | |
2099 | - speed = XFER_UDMA_5; | |
2100 | - } else if ((id->dma_ultra & 0x0010) && (udma_66)) { | |
2101 | - speed = XFER_UDMA_4; | |
2102 | - } else if ((id->dma_ultra & 0x0008) && (udma_66)) { | |
2103 | - speed = XFER_UDMA_3; | |
2104 | - } else if (id->dma_ultra & 0x0004) { | |
2105 | - speed = XFER_UDMA_2; | |
2106 | - } else if (id->dma_ultra & 0x0002) { | |
2107 | - speed = XFER_UDMA_1; | |
2108 | - } else if (id->dma_ultra & 0x0001) { | |
2109 | - speed = XFER_UDMA_0; | |
2110 | - } else if (id->dma_mword & 0x0004) { | |
2111 | - speed = XFER_MW_DMA_2; | |
2112 | - } else if (id->dma_mword & 0x0002) { | |
2113 | - speed = XFER_MW_DMA_1; | |
2114 | - } else if (id->dma_mword & 0x0001) { | |
2115 | - speed = XFER_MW_DMA_0; | |
2116 | - } else { | |
2117 | - return ((int) ide_dma_off_quietly); | |
2118 | + amd74xx_tune_drive(drive, 5); | |
2119 | + | |
2120 | + switch(mode) { | |
2121 | + case 0x04: | |
2122 | + if (id->dma_ultra & 0x0040) | |
2123 | + { speed = XFER_UDMA_6; break; } | |
2124 | + case 0x03: | |
2125 | + if (id->dma_ultra & 0x0020) | |
2126 | + { speed = XFER_UDMA_5; break; } | |
2127 | + case 0x02: | |
2128 | + if (id->dma_ultra & 0x0010) | |
2129 | + { speed = XFER_UDMA_4; break; } | |
2130 | + if (id->dma_ultra & 0x0008) | |
2131 | + { speed = XFER_UDMA_3; break; } | |
2132 | + case 0x01: | |
2133 | + if (id->dma_ultra & 0x0004) | |
2134 | + { speed = XFER_UDMA_2; break; } | |
2135 | + if (id->dma_ultra & 0x0002) | |
2136 | + { speed = XFER_UDMA_1; break; } | |
2137 | + if (id->dma_ultra & 0x0001) | |
2138 | + { speed = XFER_UDMA_0; break; } | |
2139 | + case 0x00: | |
2140 | + if (id->dma_mword & 0x0004) | |
2141 | + { speed = XFER_MW_DMA_2; break; } | |
2142 | + if (id->dma_mword & 0x0002) | |
2143 | + { speed = XFER_MW_DMA_1; break; } | |
2144 | + if (id->dma_mword & 0x0001) | |
2145 | + { speed = XFER_MW_DMA_0; break; } | |
2146 | + if ((id->dma_1word & 0x0004) && (swdma)) | |
2147 | + { speed = XFER_SW_DMA_2; break; } | |
2148 | + if ((id->dma_1word & 0x0002) && (swdma)) | |
2149 | + { speed = XFER_SW_DMA_1; break; } | |
2150 | + if ((id->dma_1word & 0x0001) && (swdma)) | |
2151 | + { speed = XFER_SW_DMA_0; break; } | |
2152 | + default: | |
2153 | + return ((int) ide_dma_off_quietly); | |
2154 | } | |
2155 | ||
2156 | (void) amd74xx_tune_chipset(drive, speed); | |
2157 | - | |
2158 | - rval = (int)( ((id->dma_ultra >> 11) & 3) ? ide_dma_on : | |
2159 | - ((id->dma_ultra >> 8) & 7) ? ide_dma_on : | |
2160 | - ((id->dma_mword >> 8) & 7) ? ide_dma_on : | |
2161 | +// return ((int) (dma) ? ide_dma_on : ide_dma_off_quietly); | |
2162 | + rval = (int)( ((id->dma_ultra >> 11) & 7) ? ide_dma_on : | |
2163 | + ((id->dma_ultra >> 8) & 7) ? ide_dma_on : | |
2164 | + ((id->dma_mword >> 8) & 7) ? ide_dma_on : | |
2165 | + (((id->dma_1word >> 8) & 7) && (swdma)) ? ide_dma_on : | |
2166 | ide_dma_off_quietly); | |
2167 | - | |
2168 | return rval; | |
2169 | } | |
2170 | ||
2171 | static int config_drive_xfer_rate (ide_drive_t *drive) | |
2172 | { | |
2173 | - struct hd_driveid *id = drive->id; | |
2174 | + struct hd_driveid *id = drive->id; | |
2175 | + ide_hwif_t *hwif = HWIF(drive); | |
2176 | ide_dma_action_t dma_func = ide_dma_on; | |
2177 | ||
2178 | - if (id && (id->capability & 1) && HWIF(drive)->autodma) { | |
2179 | + drive->init_speed = 0; | |
2180 | + | |
2181 | + if (id && (id->capability & 1) && hwif->autodma) { | |
2182 | /* Consult the list of known "bad" drives */ | |
2183 | if (ide_dmaproc(ide_dma_bad_drive, drive)) { | |
2184 | dma_func = ide_dma_off; | |
2185 | @@ -352,7 +351,7 @@ | |
2186 | } | |
2187 | dma_func = ide_dma_off_quietly; | |
2188 | if (id->field_valid & 4) { | |
2189 | - if (id->dma_ultra & 0x002F) { | |
2190 | + if (id->dma_ultra & 0x003F) { | |
2191 | /* Force if Capable UltraDMA */ | |
2192 | dma_func = config_chipset_for_dma(drive); | |
2193 | if ((id->field_valid & 2) && | |
2194 | @@ -385,8 +384,7 @@ | |
2195 | fast_ata_pio: | |
2196 | dma_func = ide_dma_off_quietly; | |
2197 | no_dma_set: | |
2198 | - | |
2199 | - config_chipset_for_pio(drive); | |
2200 | + amd74xx_tune_drive(drive, 5); | |
2201 | } | |
2202 | return HWIF(drive)->dmaproc(dma_func, drive); | |
2203 | } | |
2204 | @@ -424,9 +422,9 @@ | |
2205 | /* | |
2206 | * enable DMA capable bit, and "not" simplex only | |
2207 | */ | |
2208 | - outb(inb(fixdma_base+2) & 0x60, fixdma_base+2); | |
2209 | + OUT_BYTE(IN_BYTE(fixdma_base+2) & 0x60, fixdma_base+2); | |
2210 | ||
2211 | - if (inb(fixdma_base+2) & 0x80) | |
2212 | + if (IN_BYTE(fixdma_base+2) & 0x80) | |
2213 | printk("%s: simplex device: DMA will fail!!\n", name); | |
2214 | } | |
2215 | #if defined(DISPLAY_VIPER_TIMINGS) && defined(CONFIG_PROC_FS) | |
2216 | @@ -442,17 +440,43 @@ | |
2217 | ||
2218 | unsigned int __init ata66_amd74xx (ide_hwif_t *hwif) | |
2219 | { | |
2220 | + struct pci_dev *dev = hwif->pci_dev; | |
2221 | + byte cable_80_pin[2] = { 0, 0 }; | |
2222 | + byte ata66 = 0; | |
2223 | + byte tmpbyte; | |
2224 | + | |
2225 | + /* | |
2226 | + * Ultra66 cable detection (from Host View) | |
2227 | + * 7411, 7441, 0x42, bit0: primary, bit2: secondary 80 pin | |
2228 | + */ | |
2229 | + pci_read_config_byte(dev, 0x42, &tmpbyte); | |
2230 | + | |
2231 | + /* | |
2232 | + * 0x42, bit0 is 1 => primary channel | |
2233 | + * has 80-pin (from host view) | |
2234 | + */ | |
2235 | + if (tmpbyte & 0x01) cable_80_pin[0] = 1; | |
2236 | + | |
2237 | + /* | |
2238 | + * 0x42, bit2 is 1 => secondary channel | |
2239 | + * has 80-pin (from host view) | |
2240 | + */ | |
2241 | + if (tmpbyte & 0x04) cable_80_pin[1] = 1; | |
2242 | + | |
2243 | + switch(dev->device) { | |
2244 | + case PCI_DEVICE_ID_AMD_VIPER_7441: | |
2245 | + case PCI_DEVICE_ID_AMD_VIPER_7411: | |
2246 | + ata66 = (hwif->channel) ? | |
2247 | + cable_80_pin[1] : | |
2248 | + cable_80_pin[0]; | |
2249 | + default: | |
2250 | + break; | |
2251 | + } | |
2252 | #ifdef CONFIG_AMD74XX_OVERRIDE | |
2253 | - byte ata66 = 1; | |
2254 | + return(1); | |
2255 | #else | |
2256 | - byte ata66 = 0; | |
2257 | + return (unsigned int) ata66; | |
2258 | #endif /* CONFIG_AMD74XX_OVERRIDE */ | |
2259 | - | |
2260 | -#if 0 | |
2261 | - pci_read_config_byte(hwif->pci_dev, 0x48, &ata66); | |
2262 | - return ((ata66 & 0x02) ? 0 : 1); | |
2263 | -#endif | |
2264 | - return ata66; | |
2265 | } | |
2266 | ||
2267 | void __init ide_init_amd74xx (ide_hwif_t *hwif) | |
2268 | @@ -460,22 +484,19 @@ | |
2269 | hwif->tuneproc = &amd74xx_tune_drive; | |
2270 | hwif->speedproc = &amd74xx_tune_chipset; | |
2271 | ||
2272 | -#ifndef CONFIG_BLK_DEV_IDEDMA | |
2273 | - hwif->drives[0].autotune = 1; | |
2274 | - hwif->drives[1].autotune = 1; | |
2275 | - hwif->autodma = 0; | |
2276 | - return; | |
2277 | -#else | |
2278 | - | |
2279 | - if (hwif->dma_base) { | |
2280 | - hwif->dmaproc = &amd74xx_dmaproc; | |
2281 | - if (!noautodma) | |
2282 | - hwif->autodma = 1; | |
2283 | - } else { | |
2284 | - hwif->autodma = 0; | |
2285 | + if (!hwif->dma_base) { | |
2286 | hwif->drives[0].autotune = 1; | |
2287 | hwif->drives[1].autotune = 1; | |
2288 | + hwif->autodma = 0; | |
2289 | + return; | |
2290 | } | |
2291 | + | |
2292 | +#ifndef CONFIG_BLK_DEV_IDEDMA | |
2293 | + hwif->dmaproc = &amd74xx_dmaproc; | |
2294 | +#ifdef CONFIG_IDEDMA_AUTO | |
2295 | + if (!noautodma) | |
2296 | + hwif->autodma = 1; | |
2297 | +#endif /* CONFIG_IDEDMA_AUTO */ | |
2298 | #endif /* CONFIG_BLK_DEV_IDEDMA */ | |
2299 | } | |
2300 | ||
2301 | @@ -483,3 +504,16 @@ | |
2302 | { | |
2303 | ide_setup_dma(hwif, dmabase, 8); | |
2304 | } | |
2305 | + | |
2306 | +extern void ide_setup_pci_device (struct pci_dev *dev, ide_pci_device_t *d); | |
2307 | + | |
2308 | +void __init fixup_device_amd74xx (struct pci_dev *dev, ide_pci_device_t *d) | |
2309 | +{ | |
2310 | + if (dev->resource[0].start != 0x01F1) | |
2311 | + ide_register_xp_fix(dev); | |
2312 | + | |
2313 | + printk("%s: IDE controller on PCI bus %02x dev %02x\n", | |
2314 | + d->name, dev->bus->number, dev->devfn); | |
2315 | + ide_setup_pci_device(dev, d); | |
2316 | +} | |
2317 | + | |
2318 | diff -Nur linux.org/drivers/ide/ataraid.c linux/drivers/ide/ataraid.c | |
2319 | --- linux.org/drivers/ide/ataraid.c Thu Oct 25 22:58:35 2001 | |
2320 | +++ linux/drivers/ide/ataraid.c Thu Jul 18 14:24:33 2002 | |
2321 | @@ -123,8 +123,7 @@ | |
2322 | ptr=kmalloc(sizeof(struct buffer_head),GFP_NOIO); | |
2323 | if (!ptr) { | |
2324 | __set_current_state(TASK_RUNNING); | |
2325 | - current->policy |= SCHED_YIELD; | |
2326 | - schedule(); | |
d141e43a | 2327 | + sys_sched_yield(); |
964949d0 | 2328 | } |
2329 | } | |
2330 | return ptr; | |
2331 | @@ -139,8 +138,7 @@ | |
2332 | ptr=kmalloc(sizeof(struct ataraid_bh_private),GFP_NOIO); | |
2333 | if (!ptr) { | |
2334 | __set_current_state(TASK_RUNNING); | |
2335 | - current->policy |= SCHED_YIELD; | |
2336 | - schedule(); | |
d141e43a | 2337 | + sys_sched_yield(); |
964949d0 | 2338 | } |
2339 | } | |
2340 | return ptr; | |
2341 | diff -Nur linux.org/drivers/ide/buddha.c linux/drivers/ide/buddha.c | |
2342 | --- linux.org/drivers/ide/buddha.c Thu Oct 25 22:53:47 2001 | |
2343 | +++ linux/drivers/ide/buddha.c Thu Jul 18 14:23:00 2002 | |
2344 | @@ -1,10 +1,10 @@ | |
2345 | /* | |
2346 | * linux/drivers/ide/buddha.c -- Amiga Buddha, Catweasel and X-Surf IDE Driver | |
2347 | * | |
2348 | - * Copyright (C) 1997 by Geert Uytterhoeven | |
2349 | + * Copyright (C) 1997, 2001 by Geert Uytterhoeven and others | |
2350 | * | |
2351 | - * This driver was written by based on the specifications in README.buddha and | |
2352 | - * the X-Surf info from Inside_XSurf.txt available at | |
2353 | + * This driver was written based on the specifications in README.buddha and | |
2354 | + * the X-Surf info from Inside_XSurf.txt available at | |
2355 | * http://www.jschoenfeld.com | |
2356 | * | |
2357 | * This file is subject to the terms and conditions of the GNU General Public | |
2358 | @@ -52,7 +52,7 @@ | |
2359 | BUDDHA_BASE1, BUDDHA_BASE2, BUDDHA_BASE3 | |
2360 | }; | |
2361 | ||
2362 | -static const u_int xsurf_bases[XSURF_NUM_HWIFS] __initdata = { | |
2363 | +static u_int xsurf_bases[XSURF_NUM_HWIFS] __initdata = { | |
2364 | XSURF_BASE1, XSURF_BASE2 | |
2365 | }; | |
2366 | ||
2367 | @@ -97,7 +97,7 @@ | |
2368 | BUDDHA_IRQ1, BUDDHA_IRQ2, BUDDHA_IRQ3 | |
2369 | }; | |
2370 | ||
2371 | -static const int xsurf_irqports[XSURF_NUM_HWIFS] __initdata = { | |
2372 | +static int xsurf_irqports[XSURF_NUM_HWIFS] __initdata = { | |
2373 | XSURF_IRQ1, XSURF_IRQ2 | |
2374 | }; | |
2375 | ||
2376 | @@ -108,8 +108,9 @@ | |
2377 | * Board information | |
2378 | */ | |
2379 | ||
2380 | -enum BuddhaType_Enum {BOARD_BUDDHA, BOARD_CATWEASEL, BOARD_XSURF}; | |
2381 | -typedef enum BuddhaType_Enum BuddhaType; | |
2382 | +typedef enum BuddhaType_Enum { | |
2383 | + BOARD_BUDDHA, BOARD_CATWEASEL, BOARD_XSURF | |
2384 | +} BuddhaType; | |
2385 | ||
2386 | ||
2387 | /* | |
2388 | @@ -175,15 +176,20 @@ | |
2389 | if (!request_mem_region(board+XSURF_BASE1, 0x1000, "IDE")) | |
2390 | continue; | |
2391 | if (!request_mem_region(board+XSURF_BASE2, 0x1000, "IDE")) | |
2392 | + goto fail_base2; | |
2393 | + if (!request_mem_region(board+XSURF_IRQ1, 0x8, "IDE")) { | |
2394 | + release_mem_region(board+XSURF_BASE2, 0x1000); | |
2395 | +fail_base2: | |
2396 | + release_mem_region(board+XSURF_BASE1, 0x1000); | |
2397 | continue; | |
2398 | - if (!request_mem_region(board+XSURF_IRQ1, 0x8, "IDE")) | |
2399 | - continue; | |
2400 | + } | |
2401 | } | |
2402 | buddha_board = ZTWO_VADDR(board); | |
2403 | ||
2404 | /* write to BUDDHA_IRQ_MR to enable the board IRQ */ | |
2405 | /* X-Surf doesn't have this. IRQs are always on */ | |
2406 | - if(type != BOARD_XSURF) *(char *)(buddha_board+BUDDHA_IRQ_MR) = 0; | |
2407 | + if (type != BOARD_XSURF) | |
2408 | + z_writeb(0, buddha_board+BUDDHA_IRQ_MR); | |
2409 | ||
2410 | for(i=0;i<buddha_num_hwifs;i++) { | |
2411 | if(type != BOARD_XSURF) { | |
2412 | diff -Nur linux.org/drivers/ide/cmd640.c linux/drivers/ide/cmd640.c | |
2413 | --- linux.org/drivers/ide/cmd640.c Sat Feb 17 01:02:36 2001 | |
2414 | +++ linux/drivers/ide/cmd640.c Thu Jul 18 14:24:33 2002 | |
2415 | @@ -217,11 +217,10 @@ | |
2416 | { | |
2417 | unsigned long flags; | |
2418 | ||
2419 | - save_flags(flags); | |
2420 | - cli(); | |
2421 | - outl_p((reg & 0xfc) | cmd640_key, 0xcf8); | |
2422 | + spin_lock_irqsave(&io_request_lock, flags); | |
2423 | + outb_p((reg & 0xfc) | cmd640_key, 0xcf8); | |
2424 | outb_p(val, (reg & 3) | 0xcfc); | |
2425 | - restore_flags(flags); | |
2426 | + spin_unlock_irqrestore(&io_request_lock, flags); | |
2427 | } | |
2428 | ||
2429 | static byte get_cmd640_reg_pci1 (unsigned short reg) | |
2430 | @@ -229,11 +228,10 @@ | |
2431 | byte b; | |
2432 | unsigned long flags; | |
2433 | ||
2434 | - save_flags(flags); | |
2435 | - cli(); | |
2436 | - outl_p((reg & 0xfc) | cmd640_key, 0xcf8); | |
2437 | + spin_lock_irqsave(&io_request_lock, flags); | |
2438 | + outb_p((reg & 0xfc) | cmd640_key, 0xcf8); | |
2439 | b = inb_p((reg & 3) | 0xcfc); | |
2440 | - restore_flags(flags); | |
2441 | + spin_unlock_irqrestore(&io_request_lock, flags); | |
2442 | return b; | |
2443 | } | |
2444 | ||
2445 | @@ -243,12 +241,11 @@ | |
2446 | { | |
2447 | unsigned long flags; | |
2448 | ||
2449 | - save_flags(flags); | |
2450 | - cli(); | |
2451 | + spin_lock_irqsave(&io_request_lock, flags); | |
2452 | outb_p(0x10, 0xcf8); | |
2453 | outb_p(val, cmd640_key + reg); | |
2454 | outb_p(0, 0xcf8); | |
2455 | - restore_flags(flags); | |
2456 | + spin_unlock_irqrestore(&io_request_lock, flags); | |
2457 | } | |
2458 | ||
2459 | static byte get_cmd640_reg_pci2 (unsigned short reg) | |
2460 | @@ -256,12 +253,11 @@ | |
2461 | byte b; | |
2462 | unsigned long flags; | |
2463 | ||
2464 | - save_flags(flags); | |
2465 | - cli(); | |
2466 | + spin_lock_irqsave(&io_request_lock, flags); | |
2467 | outb_p(0x10, 0xcf8); | |
2468 | b = inb_p(cmd640_key + reg); | |
2469 | outb_p(0, 0xcf8); | |
2470 | - restore_flags(flags); | |
2471 | + spin_unlock_irqrestore(&io_request_lock, flags); | |
2472 | return b; | |
2473 | } | |
2474 | ||
2475 | @@ -271,11 +267,10 @@ | |
2476 | { | |
2477 | unsigned long flags; | |
2478 | ||
2479 | - save_flags(flags); | |
2480 | - cli(); | |
2481 | + spin_lock_irqsave(&io_request_lock, flags); | |
2482 | outb_p(reg, cmd640_key); | |
2483 | outb_p(val, cmd640_key + 4); | |
2484 | - restore_flags(flags); | |
2485 | + spin_unlock_irqrestore(&io_request_lock, flags); | |
2486 | } | |
2487 | ||
2488 | static byte get_cmd640_reg_vlb (unsigned short reg) | |
2489 | @@ -283,11 +278,10 @@ | |
2490 | byte b; | |
2491 | unsigned long flags; | |
2492 | ||
2493 | - save_flags(flags); | |
2494 | - cli(); | |
2495 | + spin_lock_irqsave(&io_request_lock, flags); | |
2496 | outb_p(reg, cmd640_key); | |
2497 | b = inb_p(cmd640_key + 4); | |
2498 | - restore_flags(flags); | |
2499 | + spin_unlock_irqrestore(&io_request_lock, flags); | |
2500 | return b; | |
2501 | } | |
2502 | ||
2503 | @@ -315,7 +309,9 @@ | |
2504 | { | |
2505 | get_cmd640_reg = get_cmd640_reg_pci1; | |
2506 | put_cmd640_reg = put_cmd640_reg_pci1; | |
2507 | - for (cmd640_key = 0x80000000; cmd640_key <= 0x8000f800; cmd640_key += 0x800) { | |
2508 | + for (cmd640_key = 0x80000000; | |
2509 | + cmd640_key <= 0x8000f800; | |
2510 | + cmd640_key += 0x800) { | |
2511 | if (match_pci_cmd640_device()) | |
2512 | return 1; /* success */ | |
2513 | } | |
2514 | @@ -364,8 +360,7 @@ | |
2515 | { | |
2516 | unsigned long flags; | |
2517 | ||
2518 | - save_flags(flags); | |
2519 | - cli(); | |
2520 | + spin_lock_irqsave(&io_request_lock, flags); | |
2521 | ||
2522 | outb_p(0x0a, 0x170 + IDE_SELECT_OFFSET); /* select drive0 */ | |
2523 | udelay(100); | |
2524 | @@ -373,11 +368,11 @@ | |
2525 | outb_p(0x1a, 0x170 + IDE_SELECT_OFFSET); /* select drive1 */ | |
2526 | udelay(100); | |
2527 | if ((inb_p(0x170 + IDE_SELECT_OFFSET) & 0x1f) != 0x1a) { | |
2528 | - restore_flags(flags); | |
2529 | + spin_unlock_irqrestore(&io_request_lock, flags); | |
2530 | return 0; /* nothing responded */ | |
2531 | } | |
2532 | } | |
2533 | - restore_flags(flags); | |
2534 | + spin_unlock_irqrestore(&io_request_lock, flags); | |
2535 | return 1; /* success */ | |
2536 | } | |
2537 | ||
2538 | @@ -458,8 +453,7 @@ | |
2539 | byte b; | |
2540 | unsigned long flags; | |
2541 | ||
2542 | - save_flags(flags); | |
2543 | - cli(); | |
2544 | + spin_lock_irqsave(&io_request_lock, flags); | |
2545 | b = get_cmd640_reg(reg); | |
2546 | if (mode) { /* want prefetch on? */ | |
2547 | #if CMD640_PREFETCH_MASKS | |
2548 | @@ -475,7 +469,7 @@ | |
2549 | b |= prefetch_masks[index]; /* disable prefetch */ | |
2550 | } | |
2551 | put_cmd640_reg(reg, b); | |
2552 | - restore_flags(flags); | |
2553 | + spin_unlock_irqrestore(&io_request_lock, flags); | |
2554 | } | |
2555 | ||
2556 | /* | |
2557 | @@ -576,8 +570,7 @@ | |
2558 | /* | |
2559 | * Now that everything is ready, program the new timings | |
2560 | */ | |
2561 | - save_flags (flags); | |
2562 | - cli(); | |
2563 | + spin_lock_irqsave(&io_request_lock, flags); | |
2564 | /* | |
2565 | * Program the address_setup clocks into ARTTIM reg, | |
2566 | * and then the active/recovery counts into the DRWTIM reg | |
2567 | @@ -586,7 +579,7 @@ | |
2568 | setup_count |= get_cmd640_reg(arttim_regs[index]) & 0x3f; | |
2569 | put_cmd640_reg(arttim_regs[index], setup_count); | |
2570 | put_cmd640_reg(drwtim_regs[index], pack_nibbles(active_count, recovery_count)); | |
2571 | - restore_flags(flags); | |
2572 | + spin_unlock_irqrestore(&io_request_lock, flags); | |
2573 | } | |
2574 | ||
2575 | /* | |
2576 | @@ -692,6 +685,41 @@ | |
2577 | ||
2578 | #endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */ | |
2579 | ||
2580 | +static int pci_conf1(void) | |
2581 | +{ | |
2582 | + u32 tmp; | |
2583 | + unsigned long flags; | |
2584 | + | |
2585 | + spin_lock_irqsave(&io_request_lock, flags); | |
2586 | + OUT_BYTE(0x01, 0xCFB); | |
2587 | + tmp = inl(0xCF8); | |
2588 | + outl(0x80000000, 0xCF8); | |
2589 | + if (inl(0xCF8) == 0x80000000) { | |
2590 | + outl(tmp, 0xCF8); | |
2591 | + spin_unlock_irqrestore(&io_request_lock, flags); | |
2592 | + return 1; | |
2593 | + } | |
2594 | + outl(tmp, 0xCF8); | |
2595 | + spin_unlock_irqrestore(&io_request_lock, flags); | |
2596 | + return 0; | |
2597 | +} | |
2598 | + | |
2599 | +static int pci_conf2(void) | |
2600 | +{ | |
2601 | + unsigned long flags; | |
2602 | + | |
2603 | + spin_lock_irqsave(&io_request_lock, flags); | |
2604 | + OUT_BYTE(0x00, 0xCFB); | |
2605 | + OUT_BYTE(0x00, 0xCF8); | |
2606 | + OUT_BYTE(0x00, 0xCFA); | |
2607 | + if (IN_BYTE(0xCF8) == 0x00 && IN_BYTE(0xCF8) == 0x00) { | |
2608 | + spin_unlock_irqrestore(&io_request_lock, flags); | |
2609 | + return 1; | |
2610 | + } | |
2611 | + spin_unlock_irqrestore(&io_request_lock, flags); | |
2612 | + return 0; | |
2613 | +} | |
2614 | + | |
2615 | /* | |
2616 | * Probe for a cmd640 chipset, and initialize it if found. Called from ide.c | |
2617 | */ | |
2618 | @@ -709,9 +737,11 @@ | |
2619 | bus_type = "VLB"; | |
2620 | } else { | |
2621 | cmd640_vlb = 0; | |
2622 | - if (probe_for_cmd640_pci1()) | |
2623 | + /* Find out what kind of PCI probing is supported otherwise | |
2624 | + Justin Gibbs will sulk.. */ | |
2625 | + if (pci_conf1() && probe_for_cmd640_pci1()) | |
2626 | bus_type = "PCI (type1)"; | |
2627 | - else if (probe_for_cmd640_pci2()) | |
2628 | + else if (pci_conf2() && probe_for_cmd640_pci2()) | |
2629 | bus_type = "PCI (type2)"; | |
2630 | else | |
2631 | return 0; | |
2632 | diff -Nur linux.org/drivers/ide/cmd64x.c linux/drivers/ide/cmd64x.c | |
2633 | --- linux.org/drivers/ide/cmd64x.c Fri Jul 28 01:40:57 2000 | |
2634 | +++ linux/drivers/ide/cmd64x.c Thu Jul 18 14:24:33 2002 | |
2635 | @@ -8,9 +8,10 @@ | |
2636 | * Due to massive hardware bugs, UltraDMA is only supported | |
2637 | * on the 646U2 and not on the 646U. | |
2638 | * | |
2639 | - * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be) | |
2640 | - * Copyright (C) 1998 David S. Miller (davem@redhat.com) | |
2641 | - * Copyright (C) 1999-2000 Andre Hedrick <andre@linux-ide.org> | |
2642 | + * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be) | |
2643 | + * Copyright (C) 1998 David S. Miller (davem@redhat.com) | |
2644 | + * | |
2645 | + * Copyright (C) 1999-2002 Andre Hedrick <andre@linux-ide.org> | |
2646 | */ | |
2647 | ||
2648 | #include <linux/config.h> | |
2649 | @@ -32,7 +33,7 @@ | |
2650 | #define CMD_DEBUG 0 | |
2651 | ||
2652 | #if CMD_DEBUG | |
2653 | -#define cmdprintk(x...) printk(##x) | |
2654 | +#define cmdprintk(x...) printk(x) | |
2655 | #else | |
2656 | #define cmdprintk(x...) | |
2657 | #endif | |
2658 | @@ -85,81 +86,97 @@ | |
2659 | #include <linux/stat.h> | |
2660 | #include <linux/proc_fs.h> | |
2661 | ||
2662 | +static char * print_cmd64x_get_info(char *, struct pci_dev *, int); | |
2663 | +static char * print_sii_get_info(char *, struct pci_dev *, int); | |
2664 | static int cmd64x_get_info(char *, char **, off_t, int); | |
2665 | extern int (*cmd64x_display_info)(char *, char **, off_t, int); /* ide-proc.c */ | |
2666 | -extern char *ide_media_verbose(ide_drive_t *); | |
2667 | -static struct pci_dev *bmide_dev; | |
2668 | ||
2669 | -static int cmd64x_get_info (char *buffer, char **addr, off_t offset, int count) | |
2670 | +byte cmd64x_proc = 0; | |
2671 | + | |
2672 | +#define CMD_MAX_DEVS 5 | |
2673 | + | |
2674 | +static struct pci_dev *cmd_devs[CMD_MAX_DEVS]; | |
2675 | +static int n_cmd_devs; | |
2676 | + | |
2677 | +#undef DEBUG_CMD_REGS | |
2678 | + | |
2679 | +static char * print_cmd64x_get_info (char *buf, struct pci_dev *dev, int index) | |
2680 | { | |
2681 | - char *p = buffer; | |
2682 | + char *p = buf; | |
2683 | + | |
2684 | u8 reg53 = 0, reg54 = 0, reg55 = 0, reg56 = 0; /* primary */ | |
2685 | u8 reg57 = 0, reg58 = 0, reg5b; /* secondary */ | |
2686 | u8 reg72 = 0, reg73 = 0; /* primary */ | |
2687 | u8 reg7a = 0, reg7b = 0; /* secondary */ | |
2688 | u8 reg50 = 0, reg71 = 0; /* extra */ | |
2689 | +#ifdef DEBUG_CMD_REGS | |
2690 | u8 hi_byte = 0, lo_byte = 0; | |
2691 | +#endif /* DEBUG_CMD_REGS */ | |
2692 | ||
2693 | - switch(bmide_dev->device) { | |
2694 | - case PCI_DEVICE_ID_CMD_649: | |
2695 | - p += sprintf(p, "\n CMD649 Chipset.\n"); | |
2696 | - break; | |
2697 | - case PCI_DEVICE_ID_CMD_648: | |
2698 | - p += sprintf(p, "\n CMD648 Chipset.\n"); | |
2699 | - break; | |
2700 | - case PCI_DEVICE_ID_CMD_646: | |
2701 | - p += sprintf(p, "\n CMD646 Chipset.\n"); | |
2702 | - break; | |
2703 | - case PCI_DEVICE_ID_CMD_643: | |
2704 | - p += sprintf(p, "\n CMD643 Chipset.\n"); | |
2705 | - break; | |
2706 | - default: | |
2707 | - p += sprintf(p, "\n CMD64? Chipse.\n"); | |
2708 | - break; | |
2709 | - } | |
2710 | - (void) pci_read_config_byte(bmide_dev, CFR, ®50); | |
2711 | - (void) pci_read_config_byte(bmide_dev, ARTTIM0, ®53); | |
2712 | - (void) pci_read_config_byte(bmide_dev, DRWTIM0, ®54); | |
2713 | - (void) pci_read_config_byte(bmide_dev, ARTTIM1, ®55); | |
2714 | - (void) pci_read_config_byte(bmide_dev, DRWTIM1, ®56); | |
2715 | - (void) pci_read_config_byte(bmide_dev, ARTTIM2, ®57); | |
2716 | - (void) pci_read_config_byte(bmide_dev, DRWTIM2, ®58); | |
2717 | - (void) pci_read_config_byte(bmide_dev, DRWTIM3, ®5b); | |
2718 | - (void) pci_read_config_byte(bmide_dev, MRDMODE, ®71); | |
2719 | - (void) pci_read_config_byte(bmide_dev, BMIDESR0, ®72); | |
2720 | - (void) pci_read_config_byte(bmide_dev, UDIDETCR0, ®73); | |
2721 | - (void) pci_read_config_byte(bmide_dev, BMIDESR1, ®7a); | |
2722 | - (void) pci_read_config_byte(bmide_dev, UDIDETCR1, ®7b); | |
2723 | - | |
2724 | - p += sprintf(p, "--------------- Primary Channel ---------------- Secondary Channel -------------\n"); | |
2725 | - p += sprintf(p, " %sabled %sabled\n", | |
2726 | - (reg72&0x80)?"dis":" en",(reg7a&0x80)?"dis":" en"); | |
2727 | - p += sprintf(p, "--------------- drive0 --------- drive1 -------- drive0 ---------- drive1 ------\n"); | |
2728 | - p += sprintf(p, "DMA enabled: %s %s %s %s\n", | |
2729 | - (reg72&0x20)?"yes":"no ",(reg72&0x40)?"yes":"no ",(reg7a&0x20)?"yes":"no ",(reg7a&0x40)?"yes":"no "); | |
2730 | - p += sprintf(p, "DMA Mode: %s(%s) %s(%s) %s(%s) %s(%s)\n", | |
2731 | + p += sprintf(p, "\nController: %d\n", index); | |
2732 | + p += sprintf(p, "CMD%x Chipset.\n", dev->device); | |
2733 | + (void) pci_read_config_byte(dev, CFR, ®50); | |
2734 | + (void) pci_read_config_byte(dev, ARTTIM0, ®53); | |
2735 | + (void) pci_read_config_byte(dev, DRWTIM0, ®54); | |
2736 | + (void) pci_read_config_byte(dev, ARTTIM1, ®55); | |
2737 | + (void) pci_read_config_byte(dev, DRWTIM1, ®56); | |
2738 | + (void) pci_read_config_byte(dev, ARTTIM2, ®57); | |
2739 | + (void) pci_read_config_byte(dev, DRWTIM2, ®58); | |
2740 | + (void) pci_read_config_byte(dev, DRWTIM3, ®5b); | |
2741 | + (void) pci_read_config_byte(dev, MRDMODE, ®71); | |
2742 | + (void) pci_read_config_byte(dev, BMIDESR0, ®72); | |
2743 | + (void) pci_read_config_byte(dev, UDIDETCR0, ®73); | |
2744 | + (void) pci_read_config_byte(dev, BMIDESR1, ®7a); | |
2745 | + (void) pci_read_config_byte(dev, UDIDETCR1, ®7b); | |
2746 | + | |
2747 | + p += sprintf(p, "--------------- Primary Channel " | |
2748 | + "---------------- Secondary Channel " | |
2749 | + "-------------\n"); | |
2750 | + p += sprintf(p, " %sabled " | |
2751 | + " %sabled\n", | |
2752 | + (reg72&0x80)?"dis":" en", | |
2753 | + (reg7a&0x80)?"dis":" en"); | |
2754 | + p += sprintf(p, "--------------- drive0 " | |
2755 | + "--------- drive1 -------- drive0 " | |
2756 | + "---------- drive1 ------\n"); | |
2757 | + p += sprintf(p, "DMA enabled: %s %s" | |
2758 | + " %s %s\n", | |
2759 | + (reg72&0x20)?"yes":"no ", (reg72&0x40)?"yes":"no ", | |
2760 | + (reg7a&0x20)?"yes":"no ", (reg7a&0x40)?"yes":"no "); | |
2761 | + | |
2762 | + p += sprintf(p, "DMA Mode: %s(%s) %s(%s)", | |
2763 | (reg72&0x20)?((reg73&0x01)?"UDMA":" DMA"):" PIO", | |
2764 | - (reg72&0x20)?( ((reg73&0x30)==0x30)?(((reg73&0x35)==0x35)?"3":"0"): | |
2765 | - ((reg73&0x20)==0x20)?(((reg73&0x25)==0x25)?"3":"1"): | |
2766 | - ((reg73&0x10)==0x10)?(((reg73&0x15)==0x15)?"4":"2"): | |
2767 | - ((reg73&0x00)==0x00)?(((reg73&0x05)==0x05)?"5":"2"):"X"):"?", | |
2768 | + (reg72&0x20)?( | |
2769 | + ((reg73&0x30)==0x30)?(((reg73&0x35)==0x35)?"3":"0"): | |
2770 | + ((reg73&0x20)==0x20)?(((reg73&0x25)==0x25)?"3":"1"): | |
2771 | + ((reg73&0x10)==0x10)?(((reg73&0x15)==0x15)?"4":"2"): | |
2772 | + ((reg73&0x00)==0x00)?(((reg73&0x05)==0x05)?"5":"2"): | |
2773 | + "X"):"?", | |
2774 | (reg72&0x40)?((reg73&0x02)?"UDMA":" DMA"):" PIO", | |
2775 | - (reg72&0x40)?( ((reg73&0xC0)==0xC0)?(((reg73&0xC5)==0xC5)?"3":"0"): | |
2776 | - ((reg73&0x80)==0x80)?(((reg73&0x85)==0x85)?"3":"1"): | |
2777 | - ((reg73&0x40)==0x40)?(((reg73&0x4A)==0x4A)?"4":"2"): | |
2778 | - ((reg73&0x00)==0x00)?(((reg73&0x0A)==0x0A)?"5":"2"):"X"):"?", | |
2779 | + (reg72&0x40)?( | |
2780 | + ((reg73&0xC0)==0xC0)?(((reg73&0xC5)==0xC5)?"3":"0"): | |
2781 | + ((reg73&0x80)==0x80)?(((reg73&0x85)==0x85)?"3":"1"): | |
2782 | + ((reg73&0x40)==0x40)?(((reg73&0x4A)==0x4A)?"4":"2"): | |
2783 | + ((reg73&0x00)==0x00)?(((reg73&0x0A)==0x0A)?"5":"2"): | |
2784 | + "X"):"?"); | |
2785 | + p += sprintf(p, " %s(%s) %s(%s)\n", | |
2786 | (reg7a&0x20)?((reg7b&0x01)?"UDMA":" DMA"):" PIO", | |
2787 | - (reg7a&0x20)?( ((reg7b&0x30)==0x30)?(((reg7b&0x35)==0x35)?"3":"0"): | |
2788 | - ((reg7b&0x20)==0x20)?(((reg7b&0x25)==0x25)?"3":"1"): | |
2789 | - ((reg7b&0x10)==0x10)?(((reg7b&0x15)==0x15)?"4":"2"): | |
2790 | - ((reg7b&0x00)==0x00)?(((reg7b&0x05)==0x05)?"5":"2"):"X"):"?", | |
2791 | + (reg7a&0x20)?( | |
2792 | + ((reg7b&0x30)==0x30)?(((reg7b&0x35)==0x35)?"3":"0"): | |
2793 | + ((reg7b&0x20)==0x20)?(((reg7b&0x25)==0x25)?"3":"1"): | |
2794 | + ((reg7b&0x10)==0x10)?(((reg7b&0x15)==0x15)?"4":"2"): | |
2795 | + ((reg7b&0x00)==0x00)?(((reg7b&0x05)==0x05)?"5":"2"): | |
2796 | + "X"):"?", | |
2797 | (reg7a&0x40)?((reg7b&0x02)?"UDMA":" DMA"):" PIO", | |
2798 | - (reg7a&0x40)?( ((reg7b&0xC0)==0xC0)?(((reg7b&0xC5)==0xC5)?"3":"0"): | |
2799 | - ((reg7b&0x80)==0x80)?(((reg7b&0x85)==0x85)?"3":"1"): | |
2800 | - ((reg7b&0x40)==0x40)?(((reg7b&0x4A)==0x4A)?"4":"2"): | |
2801 | - ((reg7b&0x00)==0x00)?(((reg7b&0x0A)==0x0A)?"5":"2"):"X"):"?" ); | |
2802 | - p += sprintf(p, "PIO Mode: %s %s %s %s\n", | |
2803 | - "?", "?", "?", "?"); | |
2804 | + (reg7a&0x40)?( | |
2805 | + ((reg7b&0xC0)==0xC0)?(((reg7b&0xC5)==0xC5)?"3":"0"): | |
2806 | + ((reg7b&0x80)==0x80)?(((reg7b&0x85)==0x85)?"3":"1"): | |
2807 | + ((reg7b&0x40)==0x40)?(((reg7b&0x4A)==0x4A)?"4":"2"): | |
2808 | + ((reg7b&0x00)==0x00)?(((reg7b&0x0A)==0x0A)?"5":"2"): | |
2809 | + "X"):"?" ); | |
2810 | + p += sprintf(p, "PIO Mode: %s %s" | |
2811 | + " %s %s\n", | |
2812 | + "?", "?", "?", "?"); | |
2813 | p += sprintf(p, " %s %s\n", | |
2814 | (reg50 & CFR_INTR_CH0) ? "interrupting" : "polling ", | |
2815 | (reg57 & ARTTIM23_INTR_CH1) ? "interrupting" : "polling"); | |
2816 | @@ -170,35 +187,58 @@ | |
2817 | (reg71 & MRDMODE_BLK_CH0) ? "blocked" : "enabled", | |
2818 | (reg71 & MRDMODE_BLK_CH1) ? "blocked" : "enabled"); | |
2819 | ||
2820 | +#ifdef DEBUG_CMD_REGS | |
2821 | SPLIT_BYTE(reg50, hi_byte, lo_byte); | |
2822 | - p += sprintf(p, "CFR = 0x%02x, HI = 0x%02x, LOW = 0x%02x\n", reg50, hi_byte, lo_byte); | |
2823 | + p += sprintf(p, "CFR = 0x%02x, HI = 0x%02x, " | |
2824 | + "LOW = 0x%02x\n", reg50, hi_byte, lo_byte); | |
2825 | SPLIT_BYTE(reg57, hi_byte, lo_byte); | |
2826 | - p += sprintf(p, "ARTTIM23 = 0x%02x, HI = 0x%02x, LOW = 0x%02x\n", reg57, hi_byte, lo_byte); | |
2827 | + p += sprintf(p, "ARTTIM23 = 0x%02x, HI = 0x%02x, " | |
2828 | + "LOW = 0x%02x\n", reg57, hi_byte, lo_byte); | |
2829 | SPLIT_BYTE(reg71, hi_byte, lo_byte); | |
2830 | - p += sprintf(p, "MRDMODE = 0x%02x, HI = 0x%02x, LOW = 0x%02x\n", reg71, hi_byte, lo_byte); | |
2831 | + p += sprintf(p, "MRDMODE = 0x%02x, HI = 0x%02x, " | |
2832 | + "LOW = 0x%02x\n", reg71, hi_byte, lo_byte); | |
2833 | +#endif /* DEBUG_CMD_REGS */ | |
2834 | ||
2835 | - return p-buffer; /* => must be less than 4k! */ | |
2836 | + return (char *)p; | |
2837 | } | |
2838 | ||
2839 | -#if 0 | |
2840 | -static char * cmd64x_chipset_data (char *buf, struct pci_dev *dev) | |
2841 | +static char * print_sii_get_info (char *buf, struct pci_dev *dev, int index) | |
2842 | { | |
2843 | char *p = buf; | |
2844 | - p += sprintf(p, "thingy stuff\n"); | |
2845 | + | |
2846 | + p += sprintf(p, "\nController: %d\n", index); | |
2847 | + p += sprintf(p, "SII%x Chipset.\n", dev->device); | |
2848 | + | |
2849 | + p += sprintf(p, "--------------- Primary Channel " | |
2850 | + "---------------- Secondary Channel " | |
2851 | + "-------------\n"); | |
2852 | + p += sprintf(p, "--------------- drive0 --------- drive1 " | |
2853 | + "-------- drive0 ---------- drive1 ------\n"); | |
2854 | + p += sprintf(p, "PIO Mode: %s %s" | |
2855 | + " %s %s\n", | |
2856 | + "?", "?", "?", "?"); | |
2857 | return (char *)p; | |
2858 | } | |
2859 | -static int __init cmd64x_get_info (char *buffer, char **addr, off_t offset, int count) | |
2860 | + | |
2861 | +static int cmd64x_get_info (char *buffer, char **addr, off_t offset, int count) | |
2862 | { | |
2863 | char *p = buffer; | |
2864 | - p = cmd64x_chipset_data(buffer, bmide_dev); | |
2865 | - return p-buffer; /* hoping it is less than 4K... */ | |
2866 | + int i; | |
2867 | + | |
2868 | + p += sprintf(p, "\n"); | |
2869 | + for (i = 0; i < n_cmd_devs; i++) { | |
2870 | + struct pci_dev *dev = cmd_devs[i]; | |
2871 | + | |
2872 | + if (dev->device <= PCI_DEVICE_ID_CMD_649) | |
2873 | + p = print_cmd64x_get_info(p, dev, i); | |
2874 | + else | |
2875 | + p = print_sii_get_info(p, dev, i); | |
2876 | + } | |
2877 | + return p-buffer; /* => must be less than 4k! */ | |
2878 | } | |
2879 | -#endif | |
2880 | ||
2881 | #endif /* defined(DISPLAY_CMD64X_TIMINGS) && defined(CONFIG_PROC_FS) */ | |
2882 | ||
2883 | -byte cmd64x_proc = 0; | |
2884 | - | |
2885 | /* | |
2886 | * Registers and masks for easy access by drive index: | |
2887 | */ | |
2888 | @@ -214,6 +254,7 @@ | |
2889 | static void program_drive_counts (ide_drive_t *drive, int setup_count, int active_count, int recovery_count) | |
2890 | { | |
2891 | unsigned long flags; | |
2892 | + struct pci_dev *dev = HWIF(drive)->pci_dev; | |
2893 | ide_drive_t *drives = HWIF(drive)->drives; | |
2894 | byte temp_b; | |
2895 | static const byte setup_counts[] = {0x40, 0x40, 0x40, 0x80, 0, 0xc0}; | |
2896 | @@ -252,25 +293,29 @@ | |
2897 | active_count &= 0xf; /* Remember, max value is 16 */ | |
2898 | recovery_count = (int) recovery_counts[recovery_count]; | |
2899 | ||
2900 | - cmdprintk("Final values = %d,%d,%d\n", setup_count, active_count, recovery_count); | |
2901 | + cmdprintk("Final values = %d,%d,%d\n", | |
2902 | + setup_count, active_count, recovery_count); | |
2903 | ||
2904 | /* | |
2905 | * Now that everything is ready, program the new timings | |
2906 | */ | |
2907 | - __save_flags (flags); | |
2908 | - __cli(); | |
2909 | + local_irq_save(flags); | |
2910 | /* | |
2911 | * Program the address_setup clocks into ARTTIM reg, | |
2912 | * and then the active/recovery counts into the DRWTIM reg | |
2913 | */ | |
2914 | - (void) pci_read_config_byte(HWIF(drive)->pci_dev, arttim_regs[channel][slave], &temp_b); | |
2915 | - (void) pci_write_config_byte(HWIF(drive)->pci_dev, arttim_regs[channel][slave], | |
2916 | + (void) pci_read_config_byte(dev, arttim_regs[channel][slave], &temp_b); | |
2917 | + (void) pci_write_config_byte(dev, arttim_regs[channel][slave], | |
2918 | ((byte) setup_count) | (temp_b & 0x3f)); | |
2919 | - (void) pci_write_config_byte(HWIF(drive)->pci_dev, drwtim_regs[channel][slave], | |
2920 | + (void) pci_write_config_byte(dev, drwtim_regs[channel][slave], | |
2921 | (byte) ((active_count << 4) | recovery_count)); | |
2922 | - cmdprintk ("Write %x to %x\n", ((byte) setup_count) | (temp_b & 0x3f), arttim_regs[channel][slave]); | |
2923 | - cmdprintk ("Write %x to %x\n", (byte) ((active_count << 4) | recovery_count), drwtim_regs[channel][slave]); | |
2924 | - __restore_flags(flags); | |
2925 | + cmdprintk ("Write %x to %x\n", | |
2926 | + ((byte) setup_count) | (temp_b & 0x3f), | |
2927 | + arttim_regs[channel][slave]); | |
2928 | + cmdprintk ("Write %x to %x\n", | |
2929 | + (byte) ((active_count << 4) | recovery_count), | |
2930 | + drwtim_regs[channel][slave]); | |
2931 | + local_irq_restore(flags); | |
2932 | } | |
2933 | ||
2934 | /* | |
2935 | @@ -294,7 +339,8 @@ | |
2936 | case 9: /* set prefetch on */ | |
2937 | mode_wanted &= 1; | |
2938 | /*set_prefetch_mode(index, mode_wanted);*/ | |
2939 | - cmdprintk("%s: %sabled cmd640 prefetch\n", drive->name, mode_wanted ? "en" : "dis"); | |
2940 | + cmdprintk("%s: %sabled cmd640 prefetch\n", | |
2941 | + drive->name, mode_wanted ? "en" : "dis"); | |
2942 | return; | |
2943 | } | |
2944 | ||
2945 | @@ -303,8 +349,8 @@ | |
2946 | cycle_time = d.cycle_time; | |
2947 | ||
2948 | /* | |
2949 | - * I copied all this complicated stuff from cmd640.c and made a few minor changes. | |
2950 | - * For now I am just going to pray that it is correct. | |
2951 | + * I copied all this complicated stuff from cmd640.c and made a few | |
2952 | + * minor changes. For now I am just going to pray that it is correct. | |
2953 | */ | |
2954 | if (pio_mode > 5) | |
2955 | pio_mode = 5; | |
2956 | @@ -334,21 +380,137 @@ | |
2957 | * (using WIN_SETFEATURE) before continuing. | |
2958 | * | |
2959 | * But we do not, because: | |
2960 | - * 1) this is the wrong place to do it (proper is do_special() in ide.c) | |
2961 | + * 1) this is the wrong place to do it | |
2962 | + * (proper is do_special() in ide.c) | |
2963 | * 2) in practice this is rarely, if ever, necessary | |
2964 | */ | |
2965 | program_drive_counts (drive, setup_count, active_count, recovery_count); | |
2966 | ||
2967 | - cmdprintk("%s: selected cmd646 PIO mode%d : %d (%dns)%s, clocks=%d/%d/%d\n", | |
2968 | + cmdprintk("%s: selected cmd646 PIO mode%d : %d (%dns)%s, " | |
2969 | + "clocks=%d/%d/%d\n", | |
2970 | drive->name, pio_mode, mode_wanted, cycle_time, | |
2971 | d.overridden ? " (overriding vendor mode)" : "", | |
2972 | setup_count, active_count, recovery_count); | |
2973 | } | |
2974 | ||
2975 | -static void config_chipset_for_pio (ide_drive_t *drive, byte set_speed) | |
2976 | +static byte cmd64x_ratemask (ide_drive_t *drive) | |
2977 | { | |
2978 | - byte speed= 0x00; | |
2979 | - byte set_pio= ide_get_best_pio_mode(drive, 4, 5, NULL); | |
2980 | + struct pci_dev *dev = HWIF(drive)->pci_dev; | |
2981 | + byte mode = 0x00; | |
2982 | + | |
2983 | + switch(dev->device) { | |
2984 | + case PCI_DEVICE_ID_CMD_680: { mode |= 0x04; break; } | |
2985 | + case PCI_DEVICE_ID_CMD_649: { mode |= 0x03; break; } | |
2986 | + case PCI_DEVICE_ID_CMD_648: { mode |= 0x02; break; } | |
2987 | + case PCI_DEVICE_ID_CMD_643: { mode |= 0x01; break; } | |
2988 | + | |
2989 | + case PCI_DEVICE_ID_CMD_646: | |
2990 | + { | |
2991 | + unsigned int class_rev = 0; | |
2992 | + pci_read_config_dword(dev, | |
2993 | + PCI_CLASS_REVISION, &class_rev); | |
2994 | + class_rev &= 0xff; | |
2995 | + /* | |
2996 | + * UltraDMA only supported on PCI646U and PCI646U2, which | |
2997 | + * correspond to revisions 0x03, 0x05 and 0x07 respectively. | |
2998 | + * Actually, although the CMD tech support people won't | |
2999 | + * tell me the details, the 0x03 revision cannot support | |
3000 | + * UDMA correctly without hardware modifications, and even | |
3001 | + * then it only works with Quantum disks due to some | |
3002 | + * hold time assumptions in the 646U part which are fixed | |
3003 | + * in the 646U2. | |
3004 | + * | |
3005 | + * So we only do UltraDMA on revision 0x05 and 0x07 chipsets. | |
3006 | + */ | |
3007 | + switch(class_rev) { | |
3008 | + case 0x07: | |
3009 | + case 0x05: { mode |= 0x01; break; } | |
3010 | + case 0x03: | |
3011 | + case 0x01: | |
3012 | + default: { mode |= 0x00; break; } | |
3013 | + } | |
3014 | + } | |
3015 | + } | |
3016 | + if (!eighty_ninty_three(drive)) { | |
3017 | + mode &= ~0xFE; | |
3018 | + mode |= 0x01; | |
3019 | + } | |
3020 | + return (mode &= ~0xF8); | |
3021 | +} | |
3022 | + | |
3023 | +static byte cmd64x_ratefilter (ide_drive_t *drive, byte speed) | |
3024 | +{ | |
3025 | +#ifdef CONFIG_BLK_DEV_IDEDMA | |
3026 | + byte mode = cmd64x_ratemask(drive); | |
3027 | + | |
3028 | + switch(mode) { | |
3029 | + case 0x04: while (speed > XFER_UDMA_6) speed--; break; | |
3030 | + case 0x03: while (speed > XFER_UDMA_5) speed--; break; | |
3031 | + case 0x02: while (speed > XFER_UDMA_4) speed--; break; | |
3032 | + case 0x01: while (speed > XFER_UDMA_2) speed--; break; | |
3033 | + case 0x00: | |
3034 | + default: while (speed > XFER_MW_DMA_2) speed--; break; | |
3035 | + break; | |
3036 | + } | |
3037 | +#else | |
3038 | + while (speed > XFER_PIO_4) speed--; | |
3039 | +#endif /* CONFIG_BLK_DEV_IDEDMA */ | |
3040 | +// printk("%s: mode == %02x speed == %02x\n", drive->name, mode, speed); | |
3041 | + return speed; | |
3042 | +} | |
3043 | + | |
3044 | +static byte cmd680_taskfile_timing (ide_hwif_t *hwif) | |
3045 | +{ | |
3046 | + struct pci_dev *dev = hwif->pci_dev; | |
3047 | + byte addr_mask = (hwif->channel) ? 0xB2 : 0xA2; | |
3048 | + unsigned short timing; | |
3049 | + | |
3050 | + pci_read_config_word(dev, addr_mask, &timing); | |
3051 | + | |
3052 | + switch (timing) { | |
3053 | + case 0x10c1: return 4; | |
3054 | + case 0x10c3: return 3; | |
3055 | + case 0x1281: return 2; | |
3056 | + case 0x2283: return 1; | |
3057 | + case 0x328a: | |
3058 | + default: return 0; | |
3059 | + } | |
3060 | +} | |
3061 | + | |
3062 | +static void cmd680_tuneproc (ide_drive_t *drive, byte mode_wanted) | |
3063 | +{ | |
3064 | + ide_hwif_t *hwif = HWIF(drive); | |
3065 | + struct pci_dev *dev = hwif->pci_dev; | |
3066 | + byte drive_pci; | |
3067 | + unsigned short speedt; | |
3068 | + | |
3069 | + switch (drive->dn) { | |
3070 | + case 0: drive_pci = 0xA4; break; | |
3071 | + case 1: drive_pci = 0xA6; break; | |
3072 | + case 2: drive_pci = 0xB4; break; | |
3073 | + case 3: drive_pci = 0xB6; break; | |
3074 | + default: return; | |
3075 | + } | |
3076 | + | |
3077 | + pci_read_config_word(dev, drive_pci, &speedt); | |
3078 | + | |
3079 | + /* cheat for now and use the docs */ | |
3080 | +// switch(cmd680_taskfile_timing(hwif)) { | |
3081 | + switch(mode_wanted) { | |
3082 | + case 4: speedt = 0x10c1; break; | |
3083 | + case 3: speedt = 0x10C3; break; | |
3084 | + case 2: speedt = 0x1104; break; | |
3085 | + case 1: speedt = 0x2283; break; | |
3086 | + case 0: | |
3087 | + default: speedt = 0x328A; break; | |
3088 | + } | |
3089 | + pci_write_config_word(dev, drive_pci, speedt); | |
3090 | +} | |
3091 | + | |
3092 | +static void config_cmd64x_chipset_for_pio (ide_drive_t *drive, byte set_speed) | |
3093 | +{ | |
3094 | + byte speed = 0x00; | |
3095 | + byte set_pio = ide_get_best_pio_mode(drive, 4, 5, NULL); | |
3096 | ||
3097 | cmd64x_tuneproc(drive, set_pio); | |
3098 | speed = XFER_PIO_0 + set_pio; | |
3099 | @@ -356,20 +518,60 @@ | |
3100 | (void) ide_config_drive_speed(drive, speed); | |
3101 | } | |
3102 | ||
3103 | -static int cmd64x_tune_chipset (ide_drive_t *drive, byte speed) | |
3104 | +static void config_cmd680_chipset_for_pio (ide_drive_t *drive, byte set_speed) | |
3105 | +{ | |
3106 | + ide_hwif_t *hwif = HWIF(drive); | |
3107 | + struct pci_dev *dev = hwif->pci_dev; | |
3108 | + u8 unit = (drive->select.b.unit & 0x01); | |
3109 | + u8 addr_mask = (hwif->channel) ? 0x84 : 0x80; | |
3110 | + u8 speed = 0x00; | |
3111 | + u8 mode_pci = 0x00; | |
3112 | + u8 channel_timings = cmd680_taskfile_timing(hwif); | |
3113 | + u8 set_pio = ide_get_best_pio_mode(drive, 4, 5, NULL); | |
3114 | + | |
3115 | + pci_read_config_byte(dev, addr_mask, &mode_pci); | |
3116 | + mode_pci &= ~((unit) ? 0x30 : 0x03); | |
3117 | + | |
3118 | + /* WARNING PIO timing mess is going to happen b/w devices, argh */ | |
3119 | + if ((channel_timings != set_pio) && (set_pio > channel_timings)) | |
3120 | + set_pio = channel_timings; | |
3121 | + | |
3122 | + cmd680_tuneproc(drive, set_pio); | |
3123 | + speed = XFER_PIO_0 + set_pio; | |
3124 | + if (set_speed) | |
3125 | + (void) ide_config_drive_speed(drive, speed); | |
3126 | +} | |
3127 | + | |
3128 | +static void config_chipset_for_pio (ide_drive_t *drive, byte set_speed) | |
3129 | +{ | |
3130 | + switch(HWIF(drive)->pci_dev->device) { | |
3131 | + case PCI_DEVICE_ID_CMD_680: | |
3132 | + config_cmd680_chipset_for_pio(drive, set_speed); | |
3133 | + return; | |
3134 | + default: | |
3135 | + break; | |
3136 | + } | |
3137 | + config_cmd64x_chipset_for_pio(drive, set_speed); | |
3138 | +} | |
3139 | + | |
3140 | +static int cmd64x_tune_chipset (ide_drive_t *drive, byte xferspeed) | |
3141 | { | |
3142 | #ifdef CONFIG_BLK_DEV_IDEDMA | |
3143 | ide_hwif_t *hwif = HWIF(drive); | |
3144 | struct pci_dev *dev = hwif->pci_dev; | |
3145 | - int err = 0; | |
3146 | ||
3147 | - byte unit = (drive->select.b.unit & 0x01); | |
3148 | + u8 unit = (drive->select.b.unit & 0x01); | |
3149 | u8 pciU = (hwif->channel) ? UDIDETCR1 : UDIDETCR0; | |
3150 | u8 pciD = (hwif->channel) ? BMIDESR1 : BMIDESR0; | |
3151 | u8 regU = 0; | |
3152 | u8 regD = 0; | |
3153 | +#endif /* CONFIG_BLK_DEV_IDEDMA */ | |
3154 | ||
3155 | - if ((drive->media != ide_disk) && (speed < XFER_SW_DMA_0)) return 1; | |
3156 | + u8 speed = cmd64x_ratefilter(drive, xferspeed); | |
3157 | + | |
3158 | +#ifdef CONFIG_BLK_DEV_IDEDMA | |
3159 | + if ((drive->media != ide_disk) && (speed < XFER_SW_DMA_0)) | |
3160 | + return 1; | |
3161 | ||
3162 | (void) pci_read_config_byte(dev, pciD, ®D); | |
3163 | (void) pci_read_config_byte(dev, pciU, ®U); | |
3164 | @@ -377,10 +579,12 @@ | |
3165 | regU &= ~(unit ? 0xCA : 0x35); | |
3166 | (void) pci_write_config_byte(dev, pciD, regD); | |
3167 | (void) pci_write_config_byte(dev, pciU, regU); | |
3168 | - | |
3169 | (void) pci_read_config_byte(dev, pciD, ®D); | |
3170 | (void) pci_read_config_byte(dev, pciU, ®U); | |
3171 | +#endif /* CONFIG_BLK_DEV_IDEDMA */ | |
3172 | + | |
3173 | switch(speed) { | |
3174 | +#ifdef CONFIG_BLK_DEV_IDEDMA | |
3175 | case XFER_UDMA_5: regU |= (unit ? 0x0A : 0x05); break; | |
3176 | case XFER_UDMA_4: regU |= (unit ? 0x4A : 0x15); break; | |
3177 | case XFER_UDMA_3: regU |= (unit ? 0x8A : 0x25); break; | |
3178 | @@ -393,10 +597,6 @@ | |
3179 | case XFER_SW_DMA_2: regD |= (unit ? 0x40 : 0x10); break; | |
3180 | case XFER_SW_DMA_1: regD |= (unit ? 0x80 : 0x20); break; | |
3181 | case XFER_SW_DMA_0: regD |= (unit ? 0xC0 : 0x30); break; | |
3182 | -#else | |
3183 | - int err = 0; | |
3184 | - | |
3185 | - switch(speed) { | |
3186 | #endif /* CONFIG_BLK_DEV_IDEDMA */ | |
3187 | case XFER_PIO_4: cmd64x_tuneproc(drive, 4); break; | |
3188 | case XFER_PIO_3: cmd64x_tuneproc(drive, 3); break; | |
3189 | @@ -410,84 +610,180 @@ | |
3190 | ||
3191 | #ifdef CONFIG_BLK_DEV_IDEDMA | |
3192 | (void) pci_write_config_byte(dev, pciU, regU); | |
3193 | + regD |= (unit ? 0x40 : 0x20); | |
3194 | + (void) pci_write_config_byte(dev, pciD, regD); | |
3195 | #endif /* CONFIG_BLK_DEV_IDEDMA */ | |
3196 | ||
3197 | - err = ide_config_drive_speed(drive, speed); | |
3198 | + return (ide_config_drive_speed(drive, speed)); | |
3199 | +} | |
3200 | ||
3201 | - drive->current_speed = speed; | |
3202 | +static int cmd680_tune_chipset (ide_drive_t *drive, byte xferspeed) | |
3203 | +{ | |
3204 | + ide_hwif_t *hwif = HWIF(drive); | |
3205 | + struct pci_dev *dev = hwif->pci_dev; | |
3206 | + u8 addr_mask = (hwif->channel) ? 0x84 : 0x80; | |
3207 | + u8 unit = (drive->select.b.unit & 0x01); | |
3208 | + u8 speed = cmd64x_ratefilter(drive, xferspeed); | |
3209 | + u8 dma_pci = 0; | |
3210 | + u8 udma_pci = 0; | |
3211 | + u8 mode_pci = 0; | |
3212 | + u8 scsc = 0; | |
3213 | + u16 ultra = 0; | |
3214 | + u16 multi = 0; | |
3215 | + | |
3216 | + pci_read_config_byte(dev, addr_mask, &mode_pci); | |
3217 | + pci_read_config_byte(dev, 0x8A, &scsc); | |
3218 | + | |
3219 | + switch (drive->dn) { | |
3220 | + case 0: dma_pci = 0xA8; udma_pci = 0xAC; break; | |
3221 | + case 1: dma_pci = 0xAA; udma_pci = 0xAE; break; | |
3222 | + case 2: dma_pci = 0xB8; udma_pci = 0xBC; break; | |
3223 | + case 3: dma_pci = 0xBA; udma_pci = 0xBE; break; | |
3224 | + default: return 1; | |
3225 | + } | |
3226 | ||
3227 | + pci_read_config_byte(dev, addr_mask, &mode_pci); | |
3228 | + mode_pci &= ~((unit) ? 0x30 : 0x03); | |
3229 | + pci_read_config_word(dev, dma_pci, &multi); | |
3230 | + pci_read_config_word(dev, udma_pci, &ultra); | |
3231 | + | |
3232 | + if ((speed == XFER_UDMA_6) && (scsc & 0x30) == 0x00) { | |
3233 | + pci_write_config_byte(dev, 0x8A, scsc|0x01); | |
3234 | + pci_read_config_byte(dev, 0x8A, &scsc); | |
3235 | +#if 0 | |
3236 | + /* if 133 clock fails, switch to 2xbus clock */ | |
3237 | + if (!(scsc & 0x01)) | |
3238 | + pci_write_config_byte(dev, 0x8A, scsc|0x10); | |
3239 | +#endif | |
3240 | + } | |
3241 | + | |
3242 | + switch(speed) { | |
3243 | #ifdef CONFIG_BLK_DEV_IDEDMA | |
3244 | - regD |= (unit ? 0x40 : 0x20); | |
3245 | - (void) pci_write_config_byte(dev, pciD, regD); | |
3246 | + case XFER_UDMA_6: | |
3247 | + if ((scsc & 0x30) == 0x00) | |
3248 | + goto speed_break; | |
3249 | + multi = 0x10C1; | |
3250 | + ultra &= ~0x3F; | |
3251 | + ultra |= 0x01; | |
3252 | + break; | |
3253 | +speed_break : | |
3254 | + speed = XFER_UDMA_5; | |
3255 | + case XFER_UDMA_5: | |
3256 | + multi = 0x10C1; | |
3257 | + ultra &= ~0x3F; | |
3258 | + ultra |= (((scsc & 0x30) == 0x00) ? 0x01 : 0x02); | |
3259 | + break; | |
3260 | + case XFER_UDMA_4: | |
3261 | + multi = 0x10C1; | |
3262 | + ultra &= ~0x3F; | |
3263 | + ultra |= (((scsc & 0x30) == 0x00) ? 0x02 : 0x03); | |
3264 | + break; | |
3265 | + case XFER_UDMA_3: | |
3266 | + multi = 0x10C1; | |
3267 | + ultra &= ~0x3F; | |
3268 | + ultra |= (((scsc & 0x30) == 0x00) ? 0x04 : 0x05); | |
3269 | + break; | |
3270 | + case XFER_UDMA_2: | |
3271 | + multi = 0x10C1; | |
3272 | + ultra &= ~0x3F; | |
3273 | + ultra |= (((scsc & 0x30) == 0x00) ? 0x05 : 0x07); | |
3274 | + break; | |
3275 | + case XFER_UDMA_1: | |
3276 | + multi = 0x10C1; | |
3277 | + ultra &= ~0x3F; | |
3278 | + ultra |= (((scsc & 0x30) == 0x00) ? 0x07 : 0x0B); | |
3279 | + break; | |
3280 | + case XFER_UDMA_0: | |
3281 | + multi = 0x10C1; | |
3282 | + ultra &= ~0x3F; | |
3283 | + ultra |= (((scsc & 0x30) == 0x00) ? 0x0C : 0x0F); | |
3284 | + break; | |
3285 | + case XFER_MW_DMA_2: | |
3286 | + multi = 0x10C1; | |
3287 | + break; | |
3288 | + case XFER_MW_DMA_1: | |
3289 | + multi = 0x10C2; | |
3290 | + break; | |
3291 | + case XFER_MW_DMA_0: | |
3292 | + multi = 0x2208; | |
3293 | + break; | |
3294 | #endif /* CONFIG_BLK_DEV_IDEDMA */ | |
3295 | + case XFER_PIO_4: cmd680_tuneproc(drive, 4); break; | |
3296 | + case XFER_PIO_3: cmd680_tuneproc(drive, 3); break; | |
3297 | + case XFER_PIO_2: cmd680_tuneproc(drive, 2); break; | |
3298 | + case XFER_PIO_1: cmd680_tuneproc(drive, 1); break; | |
3299 | + case XFER_PIO_0: cmd680_tuneproc(drive, 0); break; | |
3300 | + default: | |
3301 | + return 1; | |
3302 | + } | |
3303 | + | |
3304 | + if (speed >= XFER_MW_DMA_0) | |
3305 | + config_cmd680_chipset_for_pio(drive, 0); | |
3306 | + | |
3307 | + if (speed >= XFER_UDMA_0) | |
3308 | + mode_pci |= ((unit) ? 0x30 : 0x03); | |
3309 | + else if (speed >= XFER_MW_DMA_0) | |
3310 | + mode_pci |= ((unit) ? 0x20 : 0x02); | |
3311 | + else | |
3312 | + mode_pci |= ((unit) ? 0x10 : 0x01); | |
3313 | + | |
3314 | + pci_write_config_byte(dev, addr_mask, mode_pci); | |
3315 | + pci_write_config_word(dev, dma_pci, multi); | |
3316 | + pci_write_config_word(dev, udma_pci, ultra); | |
3317 | ||
3318 | - return err; | |
3319 | + return (ide_config_drive_speed(drive, speed)); | |
3320 | } | |
3321 | ||
3322 | #ifdef CONFIG_BLK_DEV_IDEDMA | |
3323 | -static int config_chipset_for_dma (ide_drive_t *drive, unsigned int rev, byte ultra_66) | |
3324 | +static int config_chipset_for_dma (ide_drive_t *drive) | |
3325 | { | |
3326 | struct hd_driveid *id = drive->id; | |
3327 | ide_hwif_t *hwif = HWIF(drive); | |
3328 | - struct pci_dev *dev = hwif->pci_dev; | |
3329 | - | |
3330 | + byte mode = cmd64x_ratemask(drive); | |
3331 | byte speed = 0x00; | |
3332 | byte set_pio = 0x00; | |
3333 | - byte udma_33 = ((rev >= 0x05) || (ultra_66)) ? 1 : 0; | |
3334 | - byte udma_66 = eighty_ninty_three(drive); | |
3335 | - byte udma_100 = 0; | |
3336 | int rval; | |
3337 | ||
3338 | - switch(dev->device) { | |
3339 | - case PCI_DEVICE_ID_CMD_649: udma_100 = 1; break; | |
3340 | - case PCI_DEVICE_ID_CMD_648: | |
3341 | - case PCI_DEVICE_ID_CMD_646: | |
3342 | - case PCI_DEVICE_ID_CMD_643: | |
3343 | - default: | |
3344 | - break; | |
3345 | - } | |
3346 | - | |
3347 | if (drive->media != ide_disk) { | |
3348 | - cmdprintk("CMD64X: drive->media != ide_disk at double check, inital check failed!!\n"); | |
3349 | + cmdprintk("CMD64X: drive->media != ide_disk at double check," | |
3350 | + " inital check failed!!\n"); | |
3351 | return ((int) ide_dma_off); | |
3352 | } | |
3353 | ||
3354 | - /* UltraDMA only supported on PCI646U and PCI646U2, | |
3355 | - * which correspond to revisions 0x03, 0x05 and 0x07 respectively. | |
3356 | - * Actually, although the CMD tech support people won't | |
3357 | - * tell me the details, the 0x03 revision cannot support | |
3358 | - * UDMA correctly without hardware modifications, and even | |
3359 | - * then it only works with Quantum disks due to some | |
3360 | - * hold time assumptions in the 646U part which are fixed | |
3361 | - * in the 646U2. | |
3362 | - * So we only do UltraDMA on revision 0x05 and 0x07 chipsets. | |
3363 | - */ | |
3364 | - if ((id->dma_ultra & 0x0020) && (udma_100) && (udma_66) && (udma_33)) { | |
3365 | - speed = XFER_UDMA_5; | |
3366 | - } else if ((id->dma_ultra & 0x0010) && (udma_66) && (udma_33)) { | |
3367 | - speed = XFER_UDMA_4; | |
3368 | - } else if ((id->dma_ultra & 0x0008) && (udma_66) && (udma_33)) { | |
3369 | - speed = XFER_UDMA_3; | |
3370 | - } else if ((id->dma_ultra & 0x0004) && (udma_33)) { | |
3371 | - speed = XFER_UDMA_2; | |
3372 | - } else if ((id->dma_ultra & 0x0002) && (udma_33)) { | |
3373 | - speed = XFER_UDMA_1; | |
3374 | - } else if ((id->dma_ultra & 0x0001) && (udma_33)) { | |
3375 | - speed = XFER_UDMA_0; | |
3376 | - } else if (id->dma_mword & 0x0004) { | |
3377 | - speed = XFER_MW_DMA_2; | |
3378 | - } else if (id->dma_mword & 0x0002) { | |
3379 | - speed = XFER_MW_DMA_1; | |
3380 | - } else if (id->dma_mword & 0x0001) { | |
3381 | - speed = XFER_MW_DMA_0; | |
3382 | - } else if (id->dma_1word & 0x0004) { | |
3383 | - speed = XFER_SW_DMA_2; | |
3384 | - } else if (id->dma_1word & 0x0002) { | |
3385 | - speed = XFER_SW_DMA_1; | |
3386 | - } else if (id->dma_1word & 0x0001) { | |
3387 | - speed = XFER_SW_DMA_0; | |
3388 | - } else { | |
3389 | - set_pio = 1; | |
3390 | + switch(mode) { | |
3391 | + case 0x04: | |
3392 | + if (id->dma_ultra & 0x0040) | |
3393 | + { speed = XFER_UDMA_6; break; } | |
3394 | + case 0x03: | |
3395 | + if (id->dma_ultra & 0x0020) | |
3396 | + { speed = XFER_UDMA_5; break; } | |
3397 | + case 0x02: | |
3398 | + if (id->dma_ultra & 0x0010) | |
3399 | + { speed = XFER_UDMA_4; break; } | |
3400 | + if (id->dma_ultra & 0x0008) | |
3401 | + { speed = XFER_UDMA_3; break; } | |
3402 | + case 0x01: | |
3403 | + if (id->dma_ultra & 0x0004) | |
3404 | + { speed = XFER_UDMA_2; break; } | |
3405 | + if (id->dma_ultra & 0x0002) | |
3406 | + { speed = XFER_UDMA_1; break; } | |
3407 | + if (id->dma_ultra & 0x0001) | |
3408 | + { speed = XFER_UDMA_0; break; } | |
3409 | + case 0x00: | |
3410 | + if (id->dma_mword & 0x0004) | |
3411 | + { speed = XFER_MW_DMA_2; break; } | |
3412 | + if (id->dma_mword & 0x0002) | |
3413 | + { speed = XFER_MW_DMA_1; break; } | |
3414 | + if (id->dma_mword & 0x0001) | |
3415 | + { speed = XFER_MW_DMA_0; break; } | |
3416 | + if (id->dma_1word & 0x0004) | |
3417 | + { speed = XFER_SW_DMA_2; break; } | |
3418 | + if (id->dma_1word & 0x0002) | |
3419 | + { speed = XFER_SW_DMA_1; break; } | |
3420 | + if (id->dma_1word & 0x0001) | |
3421 | + { speed = XFER_SW_DMA_0; break; } | |
3422 | + default: | |
3423 | + { set_pio = 1; break; } | |
3424 | } | |
3425 | ||
3426 | if (!drive->init_speed) | |
3427 | @@ -498,10 +794,11 @@ | |
3428 | if (set_pio) | |
3429 | return ((int) ide_dma_off_quietly); | |
3430 | ||
3431 | - if (cmd64x_tune_chipset(drive, speed)) | |
3432 | + if (hwif->speedproc(drive, speed)) | |
3433 | return ((int) ide_dma_off); | |
3434 | ||
3435 | - rval = (int)( ((id->dma_ultra >> 11) & 7) ? ide_dma_on : | |
3436 | + rval = (int)( ((id->dma_ultra >> 14) & 3) ? ide_dma_on : | |
3437 | + ((id->dma_ultra >> 11) & 7) ? ide_dma_on : | |
3438 | ((id->dma_ultra >> 8) & 7) ? ide_dma_on : | |
3439 | ((id->dma_mword >> 8) & 7) ? ide_dma_on : | |
3440 | ((id->dma_1word >> 8) & 7) ? ide_dma_on : | |
3441 | @@ -514,33 +811,8 @@ | |
3442 | { | |
3443 | struct hd_driveid *id = drive->id; | |
3444 | ide_hwif_t *hwif = HWIF(drive); | |
3445 | - struct pci_dev *dev = hwif->pci_dev; | |
3446 | - unsigned int class_rev = 0; | |
3447 | - byte can_ultra_33 = 0; | |
3448 | - byte can_ultra_66 = 0; | |
3449 | - byte can_ultra_100 = 0; | |
3450 | ide_dma_action_t dma_func = ide_dma_on; | |
3451 | ||
3452 | - pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); | |
3453 | - class_rev &= 0xff; | |
3454 | - | |
3455 | - switch(dev->device) { | |
3456 | - case PCI_DEVICE_ID_CMD_649: | |
3457 | - can_ultra_100 = 1; | |
3458 | - case PCI_DEVICE_ID_CMD_648: | |
3459 | - can_ultra_66 = 1; | |
3460 | - case PCI_DEVICE_ID_CMD_643: | |
3461 | - can_ultra_33 = 1; | |
3462 | - break; | |
3463 | - case PCI_DEVICE_ID_CMD_646: | |
3464 | - can_ultra_33 = (class_rev >= 0x05) ? 1 : 0; | |
3465 | - can_ultra_66 = 0; | |
3466 | - can_ultra_100 = 0; | |
3467 | - break; | |
3468 | - default: | |
3469 | - return hwif->dmaproc(ide_dma_off, drive); | |
3470 | - } | |
3471 | - | |
3472 | if ((id != NULL) && ((id->capability & 1) != 0) && | |
3473 | hwif->autodma && (drive->media == ide_disk)) { | |
3474 | /* Consult the list of known "bad" drives */ | |
3475 | @@ -549,10 +821,10 @@ | |
3476 | goto fast_ata_pio; | |
3477 | } | |
3478 | dma_func = ide_dma_off_quietly; | |
3479 | - if ((id->field_valid & 4) && (can_ultra_33)) { | |
3480 | - if (id->dma_ultra & 0x002F) { | |
3481 | + if ((id->field_valid & 4) && cmd64x_ratemask(drive)) { | |
3482 | + if (id->dma_ultra & 0x007F) { | |
3483 | /* Force if Capable UltraDMA */ | |
3484 | - dma_func = config_chipset_for_dma(drive, class_rev, can_ultra_66); | |
3485 | + dma_func = config_chipset_for_dma(drive); | |
3486 | if ((id->field_valid & 2) && | |
3487 | (dma_func != ide_dma_on)) | |
3488 | goto try_dma_modes; | |
3489 | @@ -562,7 +834,7 @@ | |
3490 | if ((id->dma_mword & 0x0007) || | |
3491 | (id->dma_1word & 0x0007)) { | |
3492 | /* Force if Capable regular DMA modes */ | |
3493 | - dma_func = config_chipset_for_dma(drive, class_rev, 0); | |
3494 | + dma_func = config_chipset_for_dma(drive); | |
3495 | if (dma_func != ide_dma_on) | |
3496 | goto no_dma_set; | |
3497 | } | |
3498 | @@ -571,7 +843,7 @@ | |
3499 | goto no_dma_set; | |
3500 | } | |
3501 | /* Consult the list of known "good" drives */ | |
3502 | - dma_func = config_chipset_for_dma(drive, class_rev, 0); | |
3503 | + dma_func = config_chipset_for_dma(drive); | |
3504 | if (dma_func != ide_dma_on) | |
3505 | goto no_dma_set; | |
3506 | } else { | |
3507 | @@ -586,47 +858,76 @@ | |
3508 | return HWIF(drive)->dmaproc(dma_func, drive); | |
3509 | } | |
3510 | ||
3511 | +static int cmd680_dmaproc (ide_dma_action_t func, ide_drive_t *drive) | |
3512 | +{ | |
3513 | + switch (func) { | |
3514 | + case ide_dma_check: | |
3515 | + return cmd64x_config_drive_for_dma(drive); | |
3516 | + default: | |
3517 | + break; | |
3518 | + } | |
3519 | + /* Other cases are done by generic IDE-DMA code. */ | |
3520 | + return ide_dmaproc(func, drive); | |
3521 | +} | |
3522 | + | |
3523 | +static int cmd64x_alt_dma_status (struct pci_dev *dev) | |
3524 | +{ | |
3525 | + switch(dev->device) { | |
3526 | + case PCI_DEVICE_ID_CMD_648: | |
3527 | + case PCI_DEVICE_ID_CMD_649: | |
3528 | + return 1; | |
3529 | + default: | |
3530 | + break; | |
3531 | + } | |
3532 | + return 0; | |
3533 | +} | |
3534 | + | |
3535 | static int cmd64x_dmaproc (ide_dma_action_t func, ide_drive_t *drive) | |
3536 | { | |
3537 | byte dma_stat = 0; | |
3538 | byte dma_alt_stat = 0; | |
3539 | - byte mask = (HWIF(drive)->channel) ? MRDMODE_INTR_CH1 : MRDMODE_INTR_CH0; | |
3540 | - unsigned long dma_base = HWIF(drive)->dma_base; | |
3541 | - struct pci_dev *dev = HWIF(drive)->pci_dev; | |
3542 | - byte jack_slap = ((dev->device == PCI_DEVICE_ID_CMD_648) || (dev->device == PCI_DEVICE_ID_CMD_649)) ? 1 : 0; | |
3543 | + ide_hwif_t *hwif = HWIF(drive); | |
3544 | + byte mask = (hwif->channel) ? MRDMODE_INTR_CH1 : MRDMODE_INTR_CH0; | |
3545 | + unsigned long dma_base = hwif->dma_base; | |
3546 | + struct pci_dev *dev = hwif->pci_dev; | |
3547 | + byte alt_dma_stat = cmd64x_alt_dma_status(dev); | |
3548 | ||
3549 | switch (func) { | |
3550 | case ide_dma_check: | |
3551 | return cmd64x_config_drive_for_dma(drive); | |
3552 | case ide_dma_end: /* returns 1 on error, 0 otherwise */ | |
3553 | drive->waiting_for_dma = 0; | |
3554 | - outb(inb(dma_base)&~1, dma_base); /* stop DMA */ | |
3555 | - dma_stat = inb(dma_base+2); /* get DMA status */ | |
3556 | - outb(dma_stat|6, dma_base+2); /* clear the INTR & ERROR bits */ | |
3557 | - if (jack_slap) { | |
3558 | + /* stop DMA */ | |
3559 | + OUT_BYTE(IN_BYTE(dma_base)&~1, dma_base); | |
3560 | + /* get DMA status */ | |
3561 | + dma_stat = IN_BYTE(dma_base+2); | |
3562 | + /* clear the INTR & ERROR bits */ | |
3563 | + OUT_BYTE(dma_stat|6, dma_base+2); | |
3564 | + if (alt_dma_stat) { | |
3565 | byte dma_intr = 0; | |
3566 | - byte dma_mask = (HWIF(drive)->channel) ? ARTTIM23_INTR_CH1 : CFR_INTR_CH0; | |
3567 | - byte dma_reg = (HWIF(drive)->channel) ? ARTTIM2 : CFR; | |
3568 | + byte dma_mask = (hwif->channel) ? ARTTIM23_INTR_CH1 : CFR_INTR_CH0; | |
3569 | + byte dma_reg = (hwif->channel) ? ARTTIM2 : CFR; | |
3570 | (void) pci_read_config_byte(dev, dma_reg, &dma_intr); | |
3571 | - /* | |
3572 | - * DAMN BMIDE is not connected to PCI space! | |
3573 | - * Have to manually jack-slap that bitch! | |
3574 | - * To allow the PCI side to read incoming interrupts. | |
3575 | - */ | |
3576 | - (void) pci_write_config_byte(dev, dma_reg, dma_intr|dma_mask); /* clear the INTR bit */ | |
3577 | + /* clear the INTR bit */ | |
3578 | + (void) pci_write_config_byte(dev, dma_reg, dma_intr|dma_mask); | |
3579 | } | |
3580 | - ide_destroy_dmatable(drive); /* purge DMA mappings */ | |
3581 | - return (dma_stat & 7) != 4; /* verify good DMA status */ | |
3582 | + /* purge DMA mappings */ | |
3583 | + ide_destroy_dmatable(drive); | |
3584 | + /* verify good DMA status */ | |
3585 | + return (dma_stat & 7) != 4; | |
3586 | case ide_dma_test_irq: /* returns 1 if dma irq issued, 0 otherwise */ | |
3587 | - dma_stat = inb(dma_base+2); | |
3588 | + dma_stat = IN_BYTE(dma_base+2); | |
3589 | (void) pci_read_config_byte(dev, MRDMODE, &dma_alt_stat); | |
3590 | #ifdef DEBUG | |
3591 | - printk("%s: dma_stat: 0x%02x dma_alt_stat: 0x%02x mask: 0x%02x\n", drive->name, dma_stat, dma_alt_stat, mask); | |
3592 | + printk("%s: dma_stat: 0x%02x dma_alt_stat: " | |
3593 | + "0x%02x mask: 0x%02x\n", drive->name, | |
3594 | + dma_stat, dma_alt_stat, mask); | |
3595 | #endif | |
3596 | if (!(dma_alt_stat & mask)) { | |
3597 | return 0; | |
3598 | } | |
3599 | - return (dma_stat & 4) == 4; /* return 1 if INTR asserted */ | |
3600 | + /* return 1 if INTR asserted */ | |
3601 | + return (dma_stat & 4) == 4; | |
3602 | default: | |
3603 | break; | |
3604 | } | |
3605 | @@ -649,11 +950,16 @@ | |
3606 | return cmd64x_config_drive_for_dma(drive); | |
3607 | case ide_dma_end: | |
3608 | drive->waiting_for_dma = 0; | |
3609 | - dma_stat = inb(dma_base+2); /* get DMA status */ | |
3610 | - outb(inb(dma_base)&~1, dma_base); /* stop DMA */ | |
3611 | - outb(dma_stat|6, dma_base+2); /* clear the INTR & ERROR bits */ | |
3612 | - ide_destroy_dmatable(drive); /* and free any DMA resources */ | |
3613 | - return (dma_stat & 7) != 4; /* verify good DMA status */ | |
3614 | + /* get DMA status */ | |
3615 | + dma_stat = IN_BYTE(dma_base+2); | |
3616 | + /* stop DMA */ | |
3617 | + OUT_BYTE(IN_BYTE(dma_base)&~1, dma_base); | |
3618 | + /* clear the INTR & ERROR bits */ | |
3619 | + OUT_BYTE(dma_stat|6, dma_base+2); | |
3620 | + /* and free any DMA resources */ | |
3621 | + ide_destroy_dmatable(drive); | |
3622 | + /* verify good DMA status */ | |
3623 | + return (dma_stat & 7) != 4; | |
3624 | default: | |
3625 | break; | |
3626 | } | |
3627 | @@ -663,7 +969,87 @@ | |
3628 | } | |
3629 | #endif /* CONFIG_BLK_DEV_IDEDMA */ | |
3630 | ||
3631 | -unsigned int __init pci_init_cmd64x (struct pci_dev *dev, const char *name) | |
3632 | +static int cmd680_busproc (ide_drive_t * drive, int state) | |
3633 | +{ | |
3634 | +#if 0 | |
3635 | + ide_hwif_t *hwif = HWIF(drive); | |
3636 | + u8 addr_mask = (hwif->channel) ? 0xB0 : 0xA0; | |
3637 | + u32 stat_config = 0; | |
3638 | + | |
3639 | + pci_read_config_dword(hwif->pci_dev, addr_mask, &stat_config); | |
3640 | + | |
3641 | + if (!hwif) | |
3642 | + return -EINVAL; | |
3643 | + | |
3644 | + switch (state) { | |
3645 | + case BUSSTATE_ON: | |
3646 | + hwif->drives[0].failures = 0; | |
3647 | + hwif->drives[1].failures = 0; | |
3648 | + break; | |
3649 | + case BUSSTATE_OFF: | |
3650 | + hwif->drives[0].failures = hwif->drives[0].max_failures + 1; | |
3651 | + hwif->drives[1].failures = hwif->drives[1].max_failures + 1; | |
3652 | + break; | |
3653 | + case BUSSTATE_TRISTATE: | |
3654 | + hwif->drives[0].failures = hwif->drives[0].max_failures + 1; | |
3655 | + hwif->drives[1].failures = hwif->drives[1].max_failures + 1; | |
3656 | + break; | |
3657 | + default: | |
3658 | + return 0; | |
3659 | + } | |
3660 | + hwif->bus_state = state; | |
3661 | +#endif | |
3662 | + return 0; | |
3663 | +} | |
3664 | + | |
3665 | +void cmd680_reset (ide_drive_t *drive) | |
3666 | +{ | |
3667 | +#if 0 | |
3668 | + ide_hwif_t *hwif = HWIF(drive); | |
3669 | + u8 addr_mask = (hwif->channel) ? 0xB0 : 0xA0; | |
3670 | + byte reset = 0; | |
3671 | + | |
3672 | + pci_read_config_byte(hwif->pci_dev, addr_mask, &reset); | |
3673 | + pci_write_config_byte(hwif->pci_dev, addr_mask, reset|0x03); | |
3674 | +#endif | |
3675 | +} | |
3676 | + | |
3677 | +unsigned int cmd680_pci_init (struct pci_dev *dev, const char *name) | |
3678 | +{ | |
3679 | + u8 tmpbyte = 0; | |
3680 | + pci_write_config_byte(dev, 0x80, 0x00); | |
3681 | + pci_write_config_byte(dev, 0x84, 0x00); | |
3682 | + pci_read_config_byte(dev, 0x8A, &tmpbyte); | |
3683 | + pci_write_config_byte(dev, 0x8A, tmpbyte|0x01); | |
3684 | +#if 0 | |
3685 | + /* if 133 clock fails, switch to 2xbus clock */ | |
3686 | + if (!(tmpbyte & 0x01)) { | |
3687 | + pci_read_config_byte(dev, 0x8A, &tmpbyte); | |
3688 | + pci_write_config_byte(dev, 0x8A, tmpbyte|0x10); | |
3689 | + } | |
3690 | +#endif | |
3691 | + pci_write_config_word(dev, 0xA2, 0x328A); | |
3692 | + pci_write_config_dword(dev, 0xA4, 0x328A); | |
3693 | + pci_write_config_dword(dev, 0xA8, 0x4392); | |
3694 | + pci_write_config_dword(dev, 0xAC, 0x4009); | |
3695 | + pci_write_config_word(dev, 0xB2, 0x328A); | |
3696 | + pci_write_config_dword(dev, 0xB4, 0x328A); | |
3697 | + pci_write_config_dword(dev, 0xB8, 0x4392); | |
3698 | + pci_write_config_dword(dev, 0xBC, 0x4009); | |
3699 | + | |
3700 | + cmd_devs[n_cmd_devs++] = dev; | |
3701 | + | |
3702 | +#if defined(DISPLAY_CMD64X_TIMINGS) && defined(CONFIG_PROC_FS) | |
3703 | + if (!cmd64x_proc) { | |
3704 | + cmd64x_proc = 1; | |
3705 | + cmd64x_display_info = &cmd64x_get_info; | |
3706 | + } | |
3707 | +#endif /* DISPLAY_CMD64X_TIMINGS && CONFIG_PROC_FS */ | |
3708 | + | |
3709 | + return 0; | |
3710 | +} | |
3711 | + | |
3712 | +unsigned int cmd64x_pci_init (struct pci_dev *dev, const char *name) | |
3713 | { | |
3714 | unsigned char mrdmode; | |
3715 | unsigned int class_rev; | |
3716 | @@ -741,10 +1127,11 @@ | |
3717 | (void) pci_write_config_byte(dev, UDIDETCR0, 0xf0); | |
3718 | #endif /* CONFIG_PPC */ | |
3719 | ||
3720 | + cmd_devs[n_cmd_devs++] = dev; | |
3721 | + | |
3722 | #if defined(DISPLAY_CMD64X_TIMINGS) && defined(CONFIG_PROC_FS) | |
3723 | if (!cmd64x_proc) { | |
3724 | cmd64x_proc = 1; | |
3725 | - bmide_dev = dev; | |
3726 | cmd64x_display_info = &cmd64x_get_info; | |
3727 | } | |
3728 | #endif /* DISPLAY_CMD64X_TIMINGS && CONFIG_PROC_FS */ | |
3729 | @@ -752,7 +1139,27 @@ | |
3730 | return 0; | |
3731 | } | |
3732 | ||
3733 | -unsigned int __init ata66_cmd64x (ide_hwif_t *hwif) | |
3734 | +unsigned int __init pci_init_cmd64x (struct pci_dev *dev, const char *name) | |
3735 | +{ | |
3736 | + switch(dev->device) { | |
3737 | + case PCI_DEVICE_ID_CMD_680: | |
3738 | + return cmd680_pci_init (dev, name); | |
3739 | + default: | |
3740 | + break; | |
3741 | + } | |
3742 | + return cmd64x_pci_init (dev, name); | |
3743 | +} | |
3744 | + | |
3745 | +unsigned int cmd680_ata66 (ide_hwif_t *hwif) | |
3746 | +{ | |
3747 | + byte ata66 = 0; | |
3748 | + byte addr_mask = (hwif->channel) ? 0xB0 : 0xA0; | |
3749 | + | |
3750 | + pci_read_config_byte(hwif->pci_dev, addr_mask, &ata66); | |
3751 | + return (ata66 & 0x01) ? 1 : 0; | |
3752 | +} | |
3753 | + | |
3754 | +unsigned int cmd64x_ata66 (ide_hwif_t *hwif) | |
3755 | { | |
3756 | byte ata66 = 0; | |
3757 | byte mask = (hwif->channel) ? 0x02 : 0x01; | |
3758 | @@ -761,6 +1168,17 @@ | |
3759 | return (ata66 & mask) ? 1 : 0; | |
3760 | } | |
3761 | ||
3762 | +unsigned int __init ata66_cmd64x (ide_hwif_t *hwif) | |
3763 | +{ | |
3764 | + switch(hwif->pci_dev->device) { | |
3765 | + case PCI_DEVICE_ID_CMD_680: | |
3766 | + return cmd680_ata66(hwif); | |
3767 | + default: | |
3768 | + break; | |
3769 | + } | |
3770 | + return cmd64x_ata66(hwif); | |
3771 | +} | |
3772 | + | |
3773 | void __init ide_init_cmd64x (ide_hwif_t *hwif) | |
3774 | { | |
3775 | struct pci_dev *dev = hwif->pci_dev; | |
3776 | @@ -769,31 +1187,50 @@ | |
3777 | pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); | |
3778 | class_rev &= 0xff; | |
3779 | ||
3780 | - hwif->tuneproc = &cmd64x_tuneproc; | |
3781 | - hwif->speedproc = &cmd64x_tune_chipset; | |
3782 | hwif->drives[0].autotune = 1; | |
3783 | hwif->drives[1].autotune = 1; | |
3784 | ||
3785 | - if (!hwif->dma_base) | |
3786 | - return; | |
3787 | - | |
3788 | -#ifdef CONFIG_BLK_DEV_IDEDMA | |
3789 | switch(dev->device) { | |
3790 | + case PCI_DEVICE_ID_CMD_680: | |
3791 | + hwif->busproc = &cmd680_busproc; | |
3792 | +#ifdef CONFIG_BLK_DEV_IDEDMA | |
3793 | + if (hwif->dma_base) | |
3794 | + hwif->dmaproc = &cmd680_dmaproc; | |
3795 | +#endif /* CONFIG_BLK_DEV_IDEDMA */ | |
3796 | + hwif->resetproc = &cmd680_reset; | |
3797 | + hwif->speedproc = &cmd680_tune_chipset; | |
3798 | + hwif->tuneproc = &cmd680_tuneproc; | |
3799 | + break; | |
3800 | case PCI_DEVICE_ID_CMD_649: | |
3801 | case PCI_DEVICE_ID_CMD_648: | |
3802 | case PCI_DEVICE_ID_CMD_643: | |
3803 | - hwif->dmaproc = &cmd64x_dmaproc; | |
3804 | +#ifdef CONFIG_BLK_DEV_IDEDMA | |
3805 | + if (hwif->dma_base) | |
3806 | + hwif->dmaproc = &cmd64x_dmaproc; | |
3807 | +#endif /* CONFIG_BLK_DEV_IDEDMA */ | |
3808 | + hwif->tuneproc = &cmd64x_tuneproc; | |
3809 | + hwif->speedproc = &cmd64x_tune_chipset; | |
3810 | break; | |
3811 | case PCI_DEVICE_ID_CMD_646: | |
3812 | hwif->chipset = ide_cmd646; | |
3813 | - if (class_rev == 0x01) { | |
3814 | - hwif->dmaproc = &cmd646_1_dmaproc; | |
3815 | - } else { | |
3816 | - hwif->dmaproc = &cmd64x_dmaproc; | |
3817 | +#ifdef CONFIG_BLK_DEV_IDEDMA | |
3818 | + if (hwif->dma_base) { | |
3819 | + if (class_rev == 0x01) | |
3820 | + hwif->dmaproc = &cmd646_1_dmaproc; | |
3821 | + else | |
3822 | + hwif->dmaproc = &cmd64x_dmaproc; | |
3823 | } | |
3824 | +#endif /* CONFIG_BLK_DEV_IDEDMA */ | |
3825 | + hwif->tuneproc = &cmd64x_tuneproc; | |
3826 | + hwif->speedproc = &cmd64x_tune_chipset; | |
3827 | break; | |
3828 | default: | |
3829 | break; | |
3830 | } | |
3831 | -#endif /* CONFIG_BLK_DEV_IDEDMA */ | |
3832 | + | |
3833 | +#if defined(CONFIG_BLK_DEV_IDEDMA) && defined(CONFIG_IDEDMA_AUTO) | |
3834 | + if (hwif->dma_base) | |
3835 | + if (!noautodma) | |
3836 | + hwif->autodma = 1; | |
3837 | +#endif /* CONFIG_BLK_DEV_IDEDMA && CONFIG_IDEDMA_AUTO*/ | |
3838 | } | |
3839 | diff -Nur linux.org/drivers/ide/cs5530.c linux/drivers/ide/cs5530.c | |
3840 | --- linux.org/drivers/ide/cs5530.c Wed Jan 3 01:58:45 2001 | |
3841 | +++ linux/drivers/ide/cs5530.c Thu Jul 18 14:24:33 2002 | |
3842 | @@ -37,7 +37,6 @@ | |
3843 | ||
3844 | static int cs5530_get_info(char *, char **, off_t, int); | |
3845 | extern int (*cs5530_display_info)(char *, char **, off_t, int); /* ide-proc.c */ | |
3846 | -extern char *ide_media_verbose(ide_drive_t *); | |
3847 | static struct pci_dev *bmide_dev; | |
3848 | ||
3849 | static int cs5530_get_info (char *buffer, char **addr, off_t offset, int count) | |
3850 | @@ -54,13 +53,19 @@ | |
3851 | c0 = inb_p((unsigned short)bibma + 0x02); | |
3852 | c1 = inb_p((unsigned short)bibma + 0x0a); | |
3853 | ||
3854 | - p += sprintf(p, "\n Cyrix 5530 Chipset.\n"); | |
3855 | - p += sprintf(p, "--------------- Primary Channel ---------------- Secondary Channel -------------\n"); | |
3856 | - p += sprintf(p, " %sabled %sabled\n", | |
3857 | + p += sprintf(p, "\n " | |
3858 | + "Cyrix 5530 Chipset.\n"); | |
3859 | + p += sprintf(p, "--------------- Primary Channel " | |
3860 | + "---------------- Secondary Channel " | |
3861 | + "-------------\n"); | |
3862 | + p += sprintf(p, " %sabled " | |
3863 | + " %sabled\n", | |
3864 | (c0&0x80) ? "dis" : " en", | |
3865 | (c1&0x80) ? "dis" : " en"); | |
3866 | - p += sprintf(p, "--------------- drive0 --------- drive1 -------- drive0 ---------- drive1 ------\n"); | |
3867 | - p += sprintf(p, "DMA enabled: %s %s %s %s\n", | |
3868 | + p += sprintf(p, "--------------- drive0 --------- drive1 " | |
3869 | + "-------- drive0 ---------- drive1 ------\n"); | |
3870 | + p += sprintf(p, "DMA enabled: %s %s " | |
3871 | + " %s %s\n", | |
3872 | (c0&0x20) ? "yes" : "no ", (c0&0x40) ? "yes" : "no ", | |
3873 | (c1&0x20) ? "yes" : "no ", (c1&0x40) ? "yes" : "no " ); | |
3874 | ||
3875 | @@ -74,19 +79,14 @@ | |
3876 | ||
3877 | byte cs5530_proc = 0; | |
3878 | ||
3879 | -extern char *ide_xfer_verbose (byte xfer_rate); | |
3880 | - | |
3881 | /* | |
3882 | * Set a new transfer mode at the drive | |
3883 | */ | |
3884 | int cs5530_set_xfer_mode (ide_drive_t *drive, byte mode) | |
3885 | { | |
3886 | - int error = 0; | |
3887 | - | |
3888 | - printk("%s: cs5530_set_xfer_mode(%s)\n", drive->name, ide_xfer_verbose(mode)); | |
3889 | - error = ide_config_drive_speed(drive, mode); | |
3890 | - | |
3891 | - return error; | |
3892 | + printk("%s: cs5530_set_xfer_mode(%s)\n", | |
3893 | + drive->name, ide_xfer_verbose(mode)); | |
3894 | + return (ide_config_drive_speed(drive, mode)); | |
3895 | } | |
3896 | ||
3897 | /* | |
3898 | @@ -115,12 +115,13 @@ | |
3899 | { | |
3900 | ide_hwif_t *hwif = HWIF(drive); | |
3901 | unsigned int format, basereg = CS5530_BASEREG(hwif); | |
3902 | - static byte modes[5] = {XFER_PIO_0, XFER_PIO_1, XFER_PIO_2, XFER_PIO_3, XFER_PIO_4}; | |
3903 | + static byte modes[5] = { XFER_PIO_0, XFER_PIO_1, XFER_PIO_2, XFER_PIO_3, XFER_PIO_4}; | |
3904 | ||
3905 | pio = ide_get_best_pio_mode(drive, pio, 4, NULL); | |
3906 | if (!cs5530_set_xfer_mode(drive, modes[pio])) { | |
3907 | format = (inl(basereg+4) >> 31) & 1; | |
3908 | - outl(cs5530_pio_timings[format][pio], basereg+(drive->select.b.unit<<3)); | |
3909 | + outl(cs5530_pio_timings[format][pio], | |
3910 | + basereg+(drive->select.b.unit<<3)); | |
3911 | } | |
3912 | } | |
3913 | ||
3914 | @@ -138,12 +139,13 @@ | |
3915 | struct hd_driveid *id = drive->id; | |
3916 | unsigned int basereg, reg, timings; | |
3917 | ||
3918 | - | |
3919 | /* | |
3920 | * Default to DMA-off in case we run into trouble here. | |
3921 | */ | |
3922 | - (void)hwif->dmaproc(ide_dma_off_quietly, drive); /* turn off DMA while we fiddle */ | |
3923 | - outb(inb(hwif->dma_base+2)&~(unit?0x40:0x20), hwif->dma_base+2); /* clear DMA_capable bit */ | |
3924 | + (void)hwif->dmaproc(ide_dma_off_quietly, drive); | |
3925 | + /* turn off DMA while we fiddle */ | |
3926 | + (void)hwif->dmaproc(ide_dma_host_off, drive); | |
3927 | + /* clear DMA_capable bit */ | |
3928 | ||
3929 | /* | |
3930 | * The CS5530 specifies that two drives sharing a cable cannot | |
3931 | @@ -156,10 +158,13 @@ | |
3932 | */ | |
3933 | if (mate->present) { | |
3934 | struct hd_driveid *mateid = mate->id; | |
3935 | - if (mateid && (mateid->capability & 1) && !hwif->dmaproc(ide_dma_bad_drive, mate)) { | |
3936 | - if ((mateid->field_valid & 4) && (mateid->dma_ultra & 7)) | |
3937 | + if (mateid && (mateid->capability & 1) && | |
3938 | + !hwif->dmaproc(ide_dma_bad_drive, mate)) { | |
3939 | + if ((mateid->field_valid & 4) && | |
3940 | + (mateid->dma_ultra & 7)) | |
3941 | udma_ok = 1; | |
3942 | - else if ((mateid->field_valid & 2) && (mateid->dma_mword & 7)) | |
3943 | + else if ((mateid->field_valid & 2) && | |
3944 | + (mateid->dma_mword & 7)) | |
3945 | udma_ok = 0; | |
3946 | else | |
3947 | udma_ok = 1; | |
3948 | @@ -170,7 +175,8 @@ | |
3949 | * Now see what the current drive is capable of, | |
3950 | * selecting UDMA only if the mate said it was ok. | |
3951 | */ | |
3952 | - if (id && (id->capability & 1) && hwif->autodma && !hwif->dmaproc(ide_dma_bad_drive, drive)) { | |
3953 | + if (id && (id->capability & 1) && hwif->autodma && | |
3954 | + !hwif->dmaproc(ide_dma_bad_drive, drive)) { | |
3955 | if (udma_ok && (id->field_valid & 4) && (id->dma_ultra & 7)) { | |
3956 | if (id->dma_ultra & 4) | |
3957 | mode = XFER_UDMA_2; | |
3958 | @@ -206,11 +212,12 @@ | |
3959 | case XFER_MW_DMA_1: timings = 0x00012121; break; | |
3960 | case XFER_MW_DMA_2: timings = 0x00002020; break; | |
3961 | default: | |
3962 | - printk("%s: cs5530_config_dma: huh? mode=%02x\n", drive->name, mode); | |
3963 | + printk("%s: cs5530_config_dma: huh? mode=%02x\n", | |
3964 | + drive->name, mode); | |
3965 | return 1; /* failure */ | |
3966 | } | |
3967 | basereg = CS5530_BASEREG(hwif); | |
3968 | - reg = inl(basereg+4); /* get drive0 config register */ | |
3969 | + reg = inl(basereg+4); /* get drive0 config register */ | |
3970 | timings |= reg & 0x80000000; /* preserve PIO format bit */ | |
3971 | if (unit == 0) { /* are we configuring drive0? */ | |
3972 | outl(timings, basereg+4); /* write drive0 config register */ | |
3973 | @@ -222,7 +229,8 @@ | |
3974 | outl(reg, basereg+4); /* write drive0 config register */ | |
3975 | outl(timings, basereg+12); /* write drive1 config register */ | |
3976 | } | |
3977 | - outb(inb(hwif->dma_base+2)|(unit?0x40:0x20), hwif->dma_base+2); /* set DMA_capable bit */ | |
3978 | + (void)hwif->dmaproc(ide_dma_host_on, drive); | |
3979 | + /* set DMA_capable bit */ | |
3980 | ||
3981 | /* | |
3982 | * Finally, turn DMA on in software, and exit. | |
3983 | @@ -286,8 +294,8 @@ | |
3984 | return 0; | |
3985 | } | |
3986 | ||
3987 | - save_flags(flags); | |
3988 | - cli(); /* all CPUs (there should only be one CPU with this chipset) */ | |
3989 | + spin_lock_irqsave(&io_request_lock, flags); | |
3990 | + /* all CPUs (there should only be one CPU with this chipset) */ | |
3991 | ||
3992 | /* | |
3993 | * Enable BusMaster and MemoryWriteAndInvalidate for the cs5530: | |
3994 | @@ -333,7 +341,7 @@ | |
3995 | pci_write_config_byte(master_0, 0x42, 0x00); | |
3996 | pci_write_config_byte(master_0, 0x43, 0xc1); | |
3997 | ||
3998 | - restore_flags(flags); | |
3999 | + spin_unlock_irqrestore(&io_request_lock, flags); | |
4000 | ||
4001 | return 0; | |
4002 | } | |
4003 | @@ -344,31 +352,35 @@ | |
4004 | */ | |
4005 | void __init ide_init_cs5530 (ide_hwif_t *hwif) | |
4006 | { | |
4007 | + unsigned int basereg, d0_timings; | |
4008 | + hwif->autodma = 0; | |
4009 | + | |
4010 | if (hwif->mate) | |
4011 | hwif->serialized = hwif->mate->serialized = 1; | |
4012 | - if (!hwif->dma_base) { | |
4013 | - hwif->autodma = 0; | |
4014 | - } else { | |
4015 | - unsigned int basereg, d0_timings; | |
4016 | + | |
4017 | + hwif->tuneproc = &cs5530_tuneproc; | |
4018 | + basereg = CS5530_BASEREG(hwif); | |
4019 | + d0_timings = inl(basereg+0); | |
4020 | + if (CS5530_BAD_PIO(d0_timings)) { | |
4021 | + /* PIO timings not initialized? */ | |
4022 | + outl(cs5530_pio_timings[(d0_timings>>31)&1][0], basereg+0); | |
4023 | + if (!hwif->drives[0].autotune) | |
4024 | + hwif->drives[0].autotune = 1; | |
4025 | + /* needs autotuning later */ | |
4026 | + } | |
4027 | + if (CS5530_BAD_PIO(inl(basereg+8))) { | |
4028 | + /* PIO timings not initialized? */ | |
4029 | + outl(cs5530_pio_timings[(d0_timings>>31)&1][0], basereg+8); | |
4030 | + if (!hwif->drives[1].autotune) | |
4031 | + hwif->drives[1].autotune = 1; | |
4032 | + /* needs autotuning later */ | |
4033 | + } | |
4034 | ||
4035 | #ifdef CONFIG_BLK_DEV_IDEDMA | |
4036 | - hwif->dmaproc = &cs5530_dmaproc; | |
4037 | -#else | |
4038 | - hwif->autodma = 0; | |
4039 | + hwif->dmaproc = &cs5530_dmaproc; | |
4040 | +#ifdef CONFIG_IDEDMA_AUTO | |
4041 | + if (!noautodma) | |
4042 | + hwif->autodma = 1; | |
4043 | +#endif /* CONFIG_IDEDMA_AUTO */ | |
4044 | #endif /* CONFIG_BLK_DEV_IDEDMA */ | |
4045 | - | |
4046 | - hwif->tuneproc = &cs5530_tuneproc; | |
4047 | - basereg = CS5530_BASEREG(hwif); | |
4048 | - d0_timings = inl(basereg+0); | |
4049 | - if (CS5530_BAD_PIO(d0_timings)) { /* PIO timings not initialized? */ | |
4050 | - outl(cs5530_pio_timings[(d0_timings>>31)&1][0], basereg+0); | |
4051 | - if (!hwif->drives[0].autotune) | |
4052 | - hwif->drives[0].autotune = 1; /* needs autotuning later */ | |
4053 | - } | |
4054 | - if (CS5530_BAD_PIO(inl(basereg+8))) { /* PIO timings not initialized? */ | |
4055 | - outl(cs5530_pio_timings[(d0_timings>>31)&1][0], basereg+8); | |
4056 | - if (!hwif->drives[1].autotune) | |
4057 | - hwif->drives[1].autotune = 1; /* needs autotuning later */ | |
4058 | - } | |
4059 | - } | |
4060 | } | |
4061 | diff -Nur linux.org/drivers/ide/cy82c693.c linux/drivers/ide/cy82c693.c | |
4062 | --- linux.org/drivers/ide/cy82c693.c Sun May 20 02:43:06 2001 | |
4063 | +++ linux/drivers/ide/cy82c693.c Thu Jul 18 14:24:33 2002 | |
4064 | @@ -105,10 +105,10 @@ | |
4065 | ||
4066 | /* the struct for the PIO mode timings */ | |
4067 | typedef struct pio_clocks_s { | |
4068 | - byte address_time; /* Address setup (clocks) */ | |
4069 | - byte time_16r; /* clocks for 16bit IOR (0xF0=Active/data, 0x0F=Recovery) */ | |
4070 | - byte time_16w; /* clocks for 16bit IOW (0xF0=Active/data, 0x0F=Recovery) */ | |
4071 | - byte time_8; /* clocks for 8bit (0xF0=Active/data, 0x0F=Recovery) */ | |
4072 | + byte address_time; /* Address setup (clocks) */ | |
4073 | + byte time_16r; /* clocks for 16bit IOR (0xF0=Active/data, 0x0F=Recovery) */ | |
4074 | + byte time_16w; /* clocks for 16bit IOW (0xF0=Active/data, 0x0F=Recovery) */ | |
4075 | + byte time_8; /* clocks for 8bit (0xF0=Active/data, 0x0F=Recovery) */ | |
4076 | } pio_clocks_t; | |
4077 | ||
4078 | /* | |
4079 | @@ -183,24 +183,26 @@ | |
4080 | */ | |
4081 | static void cy82c693_dma_enable (ide_drive_t *drive, int mode, int single) | |
4082 | { | |
4083 | - byte index; | |
4084 | + byte index; | |
4085 | byte data; | |
4086 | ||
4087 | - if (mode>2) /* make sure we set a valid mode */ | |
4088 | + if (mode>2) /* make sure we set a valid mode */ | |
4089 | mode = 2; | |
4090 | ||
4091 | if (mode > drive->id->tDMA) /* to be absolutly sure we have a valid mode */ | |
4092 | mode = drive->id->tDMA; | |
4093 | ||
4094 | - index = (HWIF(drive)->channel==0) ? CY82_INDEX_CHANNEL0 : CY82_INDEX_CHANNEL1; | |
4095 | + index = (HWIF(drive)->channel==0) ? CY82_INDEX_CHANNEL0 : CY82_INDEX_CHANNEL1; | |
4096 | ||
4097 | #if CY82C693_DEBUG_LOGS | |
4098 | - /* for debug let's show the previous values */ | |
4099 | + /* for debug let's show the previous values */ | |
4100 | ||
4101 | OUT_BYTE(index, CY82_INDEX_PORT); | |
4102 | data = IN_BYTE(CY82_DATA_PORT); | |
4103 | ||
4104 | - printk (KERN_INFO "%s (ch=%d, dev=%d): DMA mode is %d (single=%d)\n", drive->name, HWIF(drive)->channel, drive->select.b.unit, (data&0x3), ((data>>2)&1)); | |
4105 | + printk (KERN_INFO "%s (ch=%d, dev=%d): DMA mode is %d (single=%d)\n", | |
4106 | + drive->name, HWIF(drive)->channel, drive->select.b.unit, | |
4107 | + (data&0x3), ((data>>2)&1)); | |
4108 | #endif /* CY82C693_DEBUG_LOGS */ | |
4109 | ||
4110 | data = (byte)mode|(byte)(single<<2); | |
4111 | @@ -209,7 +211,9 @@ | |
4112 | OUT_BYTE(data, CY82_DATA_PORT); | |
4113 | ||
4114 | #if CY82C693_DEBUG_INFO | |
4115 | - printk (KERN_INFO "%s (ch=%d, dev=%d): set DMA mode to %d (single=%d)\n", drive->name, HWIF(drive)->channel, drive->select.b.unit, mode, single); | |
4116 | + printk(KERN_INFO "%s (ch=%d, dev=%d): set DMA mode to %d (single=%d)\n", | |
4117 | + drive->name, HWIF(drive)->channel, drive->select.b.unit, | |
4118 | + mode, single); | |
4119 | #endif /* CY82C693_DEBUG_INFO */ | |
4120 | ||
4121 | /* | |
4122 | @@ -227,7 +231,8 @@ | |
4123 | OUT_BYTE(data, CY82_DATA_PORT); | |
4124 | ||
4125 | #if CY82C693_DEBUG_INFO | |
4126 | - printk (KERN_INFO "%s: Set IDE Bus Master TimeOut Register to 0x%X\n", drive->name, data); | |
4127 | + printk (KERN_INFO "%s: Set IDE Bus Master TimeOut Register to 0x%X\n", | |
4128 | + drive->name, data); | |
4129 | #endif /* CY82C693_DEBUG_INFO */ | |
4130 | } | |
4131 | ||
4132 | @@ -318,7 +323,10 @@ | |
4133 | pci_read_config_byte(dev, CY82_IDE_SLAVE_8BIT, &pclk.time_8); | |
4134 | } | |
4135 | ||
4136 | - printk (KERN_INFO "%s (ch=%d, dev=%d): PIO timing is (addr=0x%X, ior=0x%X, iow=0x%X, 8bit=0x%X)\n", drive->name, hwif->channel, drive->select.b.unit, addrCtrl, pclk.time_16r, pclk.time_16w, pclk.time_8); | |
4137 | + printk(KERN_INFO "%s (ch=%d, dev=%d): PIO timing is " | |
4138 | + "(addr=0x%X, ior=0x%X, iow=0x%X, 8bit=0x%X)\n", | |
4139 | + drive->name, hwif->channel, drive->select.b.unit, | |
4140 | + addrCtrl, pclk.time_16r, pclk.time_16w, pclk.time_8); | |
4141 | #endif /* CY82C693_DEBUG_LOGS */ | |
4142 | ||
4143 | /* first let's calc the pio modes */ | |
4144 | @@ -371,7 +379,10 @@ | |
4145 | } | |
4146 | ||
4147 | #if CY82C693_DEBUG_INFO | |
4148 | - printk (KERN_INFO "%s (ch=%d, dev=%d): set PIO timing to (addr=0x%X, ior=0x%X, iow=0x%X, 8bit=0x%X)\n", drive->name, hwif->channel, drive->select.b.unit, addrCtrl, pclk.time_16r, pclk.time_16w, pclk.time_8); | |
4149 | + printk(KERN_INFO "%s (ch=%d, dev=%d): set PIO timing to " | |
4150 | + "(addr=0x%X, ior=0x%X, iow=0x%X, 8bit=0x%X)\n", | |
4151 | + drive->name, hwif->channel, drive->select.b.unit, | |
4152 | + addrCtrl, pclk.time_16r, pclk.time_16w, pclk.time_8); | |
4153 | #endif /* CY82C693_DEBUG_INFO */ | |
4154 | } | |
4155 | ||
4156 | @@ -391,7 +402,7 @@ | |
4157 | #endif /* CY82C693_SETDMA_CLOCK */ | |
4158 | ||
4159 | /* write info about this verion of the driver */ | |
4160 | - printk (KERN_INFO CY82_VERSION "\n"); | |
4161 | + printk(KERN_INFO CY82_VERSION "\n"); | |
4162 | ||
4163 | #ifdef CY82C693_SETDMA_CLOCK | |
4164 | /* okay let's set the DMA clock speed */ | |
4165 | @@ -400,7 +411,8 @@ | |
4166 | data = IN_BYTE(CY82_DATA_PORT); | |
4167 | ||
4168 | #if CY82C693_DEBUG_INFO | |
4169 | - printk (KERN_INFO "%s: Peripheral Configuration Register: 0x%X\n", name, data); | |
4170 | + printk(KERN_INFO "%s: Peripheral Configuration Register: 0x%X\n", | |
4171 | + name, data); | |
4172 | #endif /* CY82C693_DEBUG_INFO */ | |
4173 | ||
4174 | /* | |
4175 | @@ -421,7 +433,8 @@ | |
4176 | OUT_BYTE(data, CY82_DATA_PORT); | |
4177 | ||
4178 | #if CY82C693_DEBUG_INFO | |
4179 | - printk (KERN_INFO "%s: New Peripheral Configuration Register: 0x%X\n", name, data); | |
4180 | + printk (KERN_INFO "%s: New Peripheral Configuration Register: 0x%X\n", | |
4181 | + name, data); | |
4182 | #endif /* CY82C693_DEBUG_INFO */ | |
4183 | ||
4184 | #endif /* CY82C693_SETDMA_CLOCK */ | |
4185 | @@ -439,11 +452,27 @@ | |
4186 | hwif->drives[1].autotune = 1; | |
4187 | hwif->autodma = 0; | |
4188 | ||
4189 | + if (!hwif->dma_base) | |
4190 | + return; | |
4191 | #ifdef CONFIG_BLK_DEV_IDEDMA | |
4192 | - if (hwif->dma_base) { | |
4193 | - hwif->dmaproc = &cy82c693_dmaproc; | |
4194 | - if (!noautodma) | |
4195 | - hwif->autodma = 1; | |
4196 | - } | |
4197 | + hwif->dmaproc = &cy82c693_dmaproc; | |
4198 | +#ifdef CONFIG_IDEDMA_AUTO | |
4199 | + if (!noautodma) | |
4200 | + hwif->autodma = 1; | |
4201 | +#endif /* CONFIG_IDEDMA_AUTO */ | |
4202 | #endif /* CONFIG_BLK_DEV_IDEDMA */ | |
4203 | } | |
4204 | + | |
4205 | +extern void ide_setup_pci_device (struct pci_dev *dev, ide_pci_device_t *d); | |
4206 | + | |
4207 | +void __init fixup_device_cy82c693 (struct pci_dev *dev, ide_pci_device_t *d) | |
4208 | +{ | |
4209 | + if ((!(PCI_FUNC(dev->devfn) & 1) || | |
4210 | + (!((dev->class >> 8) == PCI_CLASS_STORAGE_IDE)))) | |
4211 | + return; /* CY82C693 is more than only a IDE controller */ | |
4212 | + | |
4213 | + printk("%s: IDE controller on PCI bus %02x dev %02x\n", | |
4214 | + d->name, dev->bus->number, dev->devfn); | |
4215 | + ide_setup_pci_device(dev, d); | |
4216 | +} | |
4217 | + | |
4218 | diff -Nur linux.org/drivers/ide/dtc2278.c linux/drivers/ide/dtc2278.c | |
4219 | --- linux.org/drivers/ide/dtc2278.c Fri Apr 14 07:54:26 2000 | |
4220 | +++ linux/drivers/ide/dtc2278.c Thu Jul 18 14:24:33 2002 | |
4221 | @@ -57,14 +57,14 @@ | |
4222 | int i; | |
4223 | ||
4224 | for(i = 0; i < 3; ++i) { | |
4225 | - inb(0x3f6); | |
4226 | + IN_BYTE(0x3f6); | |
4227 | outb_p(b,0xb0); | |
4228 | - inb(0x3f6); | |
4229 | + IN_BYTE(0x3f6); | |
4230 | outb_p(c,0xb4); | |
4231 | - inb(0x3f6); | |
4232 | - if(inb(0xb4) == c) { | |
4233 | + IN_BYTE(0x3f6); | |
4234 | + if(IN_BYTE(0xb4) == c) { | |
4235 | outb_p(7,0xb0); | |
4236 | - inb(0x3f6); | |
4237 | + IN_BYTE(0x3f6); | |
4238 | return; /* success */ | |
4239 | } | |
4240 | } | |
4241 | @@ -77,14 +77,13 @@ | |
4242 | pio = ide_get_best_pio_mode(drive, pio, 4, NULL); | |
4243 | ||
4244 | if (pio >= 3) { | |
4245 | - save_flags(flags); /* all CPUs */ | |
4246 | - cli(); /* all CPUs */ | |
4247 | + spin_lock_irqsave(&io_request_lock, flags); | |
4248 | /* | |
4249 | * This enables PIO mode4 (3?) on the first interface | |
4250 | */ | |
4251 | sub22(1,0xc3); | |
4252 | sub22(0,0xa0); | |
4253 | - restore_flags(flags); /* all CPUs */ | |
4254 | + spin_unlock_irqrestore(&io_request_lock, flags); | |
4255 | } else { | |
4256 | /* we don't know how to set it back again.. */ | |
4257 | } | |
4258 | @@ -100,15 +99,14 @@ | |
4259 | { | |
4260 | unsigned long flags; | |
4261 | ||
4262 | - __save_flags(flags); /* local CPU only */ | |
4263 | - __cli(); /* local CPU only */ | |
4264 | + local_irq_save(flags); | |
4265 | /* | |
4266 | * This enables the second interface | |
4267 | */ | |
4268 | outb_p(4,0xb0); | |
4269 | - inb(0x3f6); | |
4270 | + IN_BYTE(0x3f6); | |
4271 | outb_p(0x20,0xb4); | |
4272 | - inb(0x3f6); | |
4273 | + IN_BYTE(0x3f6); | |
4274 | #ifdef ALWAYS_SET_DTC2278_PIO_MODE | |
4275 | /* | |
4276 | * This enables PIO mode4 (3?) on the first interface | |
4277 | @@ -117,7 +115,7 @@ | |
4278 | sub22(1,0xc3); | |
4279 | sub22(0,0xa0); | |
4280 | #endif | |
4281 | - __restore_flags(flags); /* local CPU only */ | |
4282 | + local_irq_restore(flags); | |
4283 | ||
4284 | ide_hwifs[0].serialized = 1; | |
4285 | ide_hwifs[1].serialized = 1; | |
4286 | diff -Nur linux.org/drivers/ide/falconide.c linux/drivers/ide/falconide.c | |
4287 | --- linux.org/drivers/ide/falconide.c Thu Oct 25 22:53:47 2001 | |
4288 | +++ linux/drivers/ide/falconide.c Thu Jul 18 14:23:00 2002 | |
4289 | @@ -7,7 +7,7 @@ | |
4290 | * License. See the file COPYING in the main directory of this archive for | |
4291 | * more details. | |
4292 | */ | |
4293 | -#include <linux/config.h> | |
4294 | + | |
4295 | #include <linux/types.h> | |
4296 | #include <linux/mm.h> | |
4297 | #include <linux/interrupt.h> | |
4298 | diff -Nur linux.org/drivers/ide/gayle.c linux/drivers/ide/gayle.c | |
4299 | --- linux.org/drivers/ide/gayle.c Tue Nov 28 02:57:34 2000 | |
4300 | +++ linux/drivers/ide/gayle.c Thu Jul 18 14:23:00 2002 | |
4301 | @@ -16,6 +16,7 @@ | |
4302 | #include <linux/hdreg.h> | |
4303 | #include <linux/ide.h> | |
4304 | #include <linux/init.h> | |
4305 | +#include <linux/zorro.h> | |
4306 | ||
4307 | #include <asm/setup.h> | |
4308 | #include <asm/amigahw.h> | |
4309 | @@ -88,7 +89,7 @@ | |
4310 | { | |
4311 | unsigned char ch; | |
4312 | ||
4313 | - ch = inb(hwif->io_ports[IDE_IRQ_OFFSET]); | |
4314 | + ch = z_readb(hwif->io_ports[IDE_IRQ_OFFSET]); | |
4315 | if (!(ch & GAYLE_IRQ_IDE)) | |
4316 | return 0; | |
4317 | return 1; | |
4318 | @@ -98,11 +99,11 @@ | |
4319 | { | |
4320 | unsigned char ch; | |
4321 | ||
4322 | - ch = inb(hwif->io_ports[IDE_IRQ_OFFSET]); | |
4323 | + ch = z_readb(hwif->io_ports[IDE_IRQ_OFFSET]); | |
4324 | if (!(ch & GAYLE_IRQ_IDE)) | |
4325 | return 0; | |
4326 | - (void)inb(hwif->io_ports[IDE_STATUS_OFFSET]); | |
4327 | - outb(0x7c, hwif->io_ports[IDE_IRQ_OFFSET]); | |
4328 | + (void)z_readb(hwif->io_ports[IDE_STATUS_OFFSET]); | |
4329 | + z_writeb(0x7c, hwif->io_ports[IDE_IRQ_OFFSET]); | |
4330 | return 1; | |
4331 | } | |
4332 | ||
4333 | diff -Nur linux.org/drivers/ide/hd.c linux/drivers/ide/hd.c | |
4334 | --- linux.org/drivers/ide/hd.c Mon Oct 15 22:27:42 2001 | |
4335 | +++ linux/drivers/ide/hd.c Thu Jul 18 14:24:33 2002 | |
4336 | @@ -135,13 +135,12 @@ | |
4337 | unsigned long t, flags; | |
4338 | int i; | |
4339 | ||
4340 | - save_flags(flags); | |
4341 | - cli(); | |
4342 | + spin_lock_irqsave(&io_request_lock, flags); | |
4343 | t = jiffies * 11932; | |
4344 | outb_p(0, 0x43); | |
4345 | i = inb_p(0x40); | |
4346 | - i |= inb(0x40) << 8; | |
4347 | - restore_flags(flags); | |
4348 | + i |= IN_BYTE(0x40) << 8; | |
4349 | + spin_unlock_irqrestore(&io_request_lock, flags); | |
4350 | return(t - i); | |
4351 | } | |
4352 | #endif | |
4353 | @@ -185,7 +184,7 @@ | |
4354 | if ((stat & ERR_STAT) == 0) { | |
4355 | hd_error = 0; | |
4356 | } else { | |
4357 | - hd_error = inb(HD_ERROR); | |
4358 | + hd_error = IN_BYTE(HD_ERROR); | |
4359 | printk("hd%c: %s: error=0x%02x { ", devc, msg, hd_error & 0xff); | |
4360 | if (hd_error & BBD_ERR) printk("BadSector "); | |
4361 | if (hd_error & ECC_ERR) printk("UncorrectableError "); | |
4362 | @@ -195,8 +194,9 @@ | |
4363 | if (hd_error & MARK_ERR) printk("AddrMarkNotFound "); | |
4364 | printk("}"); | |
4365 | if (hd_error & (BBD_ERR|ECC_ERR|ID_ERR|MARK_ERR)) { | |
4366 | - printk(", CHS=%d/%d/%d", (inb(HD_HCYL)<<8) + inb(HD_LCYL), | |
4367 | - inb(HD_CURRENT) & 0xf, inb(HD_SECTOR)); | |
4368 | + printk(", CHS=%d/%d/%d", | |
4369 | + (IN_BYTE(HD_HCYL)<<8) + IN_BYTE(HD_LCYL), | |
4370 | + IN_BYTE(HD_CURRENT) & 0xf, IN_BYTE(HD_SECTOR)); | |
4371 | if (!QUEUE_EMPTY) | |
4372 | printk(", sector=%ld", CURRENT->sector); | |
4373 | } | |
4374 | @@ -207,7 +207,7 @@ | |
4375 | if ((stat & ERR_STAT) == 0) { | |
4376 | hd_error = 0; | |
4377 | } else { | |
4378 | - hd_error = inb(HD_ERROR); | |
4379 | + hd_error = IN_BYTE(HD_ERROR); | |
4380 | printk("hd%c: %s: error=0x%02x.\n", devc, msg, hd_error & 0xff); | |
4381 | } | |
4382 | #endif /* verbose errors */ | |
4383 | @@ -318,7 +318,7 @@ | |
4384 | for(i = 0; i < 1000; i++) barrier(); | |
4385 | if (drive_busy()) | |
4386 | printk("hd: controller still busy\n"); | |
4387 | - else if ((hd_error = inb(HD_ERROR)) != 1) | |
4388 | + else if ((hd_error = IN_BYTE(HD_ERROR)) != 1) | |
4389 | printk("hd: controller reset failed: %02x\n",hd_error); | |
4390 | } | |
4391 | ||
4392 | @@ -346,6 +346,13 @@ | |
4393 | hd_request(); | |
4394 | } | |
4395 | ||
4396 | +void do_reset_hd(void) | |
4397 | +{ | |
4398 | + DEVICE_INTR = NULL; | |
4399 | + reset = 1; | |
4400 | + reset_hd(); | |
4401 | +} | |
4402 | + | |
4403 | /* | |
4404 | * Ok, don't know what to do with the unexpected interrupts: on some machines | |
4405 | * doing a reset and a retry seems to result in an eternal loop. Right now I | |
4406 | @@ -876,14 +883,13 @@ | |
4407 | target = DEVICE_NR(dev); | |
4408 | gdev = &GENDISK_STRUCT; | |
4409 | ||
4410 | - save_flags(flags); | |
4411 | - cli(); | |
4412 | + spin_lock_irqsave(&io_request_lock, flags); | |
4413 | if (DEVICE_BUSY || USAGE > maxusage) { | |
4414 | - restore_flags(flags); | |
4415 | + spin_unlock_irqrestore(&io_request_lock, flags); | |
4416 | return -EBUSY; | |
4417 | } | |
4418 | DEVICE_BUSY = 1; | |
4419 | - restore_flags(flags); | |
4420 | + spin_unlock_irqrestore(&io_request_lock, flags); | |
4421 | ||
4422 | max_p = gdev->max_p; | |
4423 | start = target << gdev->minor_shift; | |
4424 | diff -Nur linux.org/drivers/ide/hpt34x.c linux/drivers/ide/hpt34x.c | |
4425 | --- linux.org/drivers/ide/hpt34x.c Sun May 20 02:43:06 2001 | |
4426 | +++ linux/drivers/ide/hpt34x.c Thu Jul 18 14:24:33 2002 | |
4427 | @@ -50,41 +50,57 @@ | |
4428 | ||
4429 | #undef DISPLAY_HPT34X_TIMINGS | |
4430 | ||
4431 | +#define HPT34X_MAX_DEVS 8 | |
4432 | +static struct pci_dev *hpt34x_devs[HPT34X_MAX_DEVS]; | |
4433 | +static int n_hpt34x_devs; | |
4434 | + | |
4435 | #if defined(DISPLAY_HPT34X_TIMINGS) && defined(CONFIG_PROC_FS) | |
4436 | #include <linux/stat.h> | |
4437 | #include <linux/proc_fs.h> | |
4438 | ||
4439 | static int hpt34x_get_info(char *, char **, off_t, int); | |
4440 | extern int (*hpt34x_display_info)(char *, char **, off_t, int); /* ide-proc.c */ | |
4441 | -extern char *ide_media_verbose(ide_drive_t *); | |
4442 | -static struct pci_dev *bmide_dev; | |
4443 | ||
4444 | static int hpt34x_get_info (char *buffer, char **addr, off_t offset, int count) | |
4445 | { | |
4446 | char *p = buffer; | |
4447 | - u32 bibma = pci_resource_start(bmide_dev, 4); | |
4448 | - u8 c0 = 0, c1 = 0; | |
4449 | + int i; | |
4450 | ||
4451 | - /* | |
4452 | - * at that point bibma+0x2 et bibma+0xa are byte registers | |
4453 | - * to investigate: | |
4454 | - */ | |
4455 | - c0 = inb_p((unsigned short)bibma + 0x02); | |
4456 | - c1 = inb_p((unsigned short)bibma + 0x0a); | |
4457 | - | |
4458 | - p += sprintf(p, "\n HPT34X Chipset.\n"); | |
4459 | - p += sprintf(p, "--------------- Primary Channel ---------------- Secondary Channel -------------\n"); | |
4460 | - p += sprintf(p, " %sabled %sabled\n", | |
4461 | - (c0&0x80) ? "dis" : " en", | |
4462 | - (c1&0x80) ? "dis" : " en"); | |
4463 | - p += sprintf(p, "--------------- drive0 --------- drive1 -------- drive0 ---------- drive1 ------\n"); | |
4464 | - p += sprintf(p, "DMA enabled: %s %s %s %s\n", | |
4465 | - (c0&0x20) ? "yes" : "no ", (c0&0x40) ? "yes" : "no ", | |
4466 | - (c1&0x20) ? "yes" : "no ", (c1&0x40) ? "yes" : "no " ); | |
4467 | - | |
4468 | - p += sprintf(p, "UDMA\n"); | |
4469 | - p += sprintf(p, "DMA\n"); | |
4470 | - p += sprintf(p, "PIO\n"); | |
4471 | + p += sprintf(p, "\n " | |
4472 | + "HPT34X Chipset.\n"); | |
4473 | + for (i = 0; i < n_hpt34x_devs; i++) { | |
4474 | + struct pci_dev *dev = hpt34x_devs[i]; | |
4475 | + u32 bibma = pci_resource_start(dev, 4); | |
4476 | + u8 c0 = 0, c1 = 0; | |
4477 | + | |
4478 | + /* | |
4479 | + * at that point bibma+0x2 et bibma+0xa are byte registers | |
4480 | + * to investigate: | |
4481 | + */ | |
4482 | + c0 = inb_p((unsigned short)bibma + 0x02); | |
4483 | + c1 = inb_p((unsigned short)bibma + 0x0a); | |
4484 | + p += sprintf(p, "\nController: %d\n", i); | |
4485 | + p += sprintf(p, "--------------- Primary Channel " | |
4486 | + "---------------- Secondary Channel " | |
4487 | + "-------------\n"); | |
4488 | + p += sprintf(p, " %sabled " | |
4489 | + " %sabled\n", | |
4490 | + (c0&0x80) ? "dis" : " en", | |
4491 | + (c1&0x80) ? "dis" : " en"); | |
4492 | + p += sprintf(p, "--------------- drive0 --------- drive1 " | |
4493 | + "-------- drive0 ---------- drive1 ------\n"); | |
4494 | + p += sprintf(p, "DMA enabled: %s %s" | |
4495 | + " %s %s\n", | |
4496 | + (c0&0x20) ? "yes" : "no ", | |
4497 | + (c0&0x40) ? "yes" : "no ", | |
4498 | + (c1&0x20) ? "yes" : "no ", | |
4499 | + (c1&0x40) ? "yes" : "no " ); | |
4500 | + | |
4501 | + p += sprintf(p, "UDMA\n"); | |
4502 | + p += sprintf(p, "DMA\n"); | |
4503 | + p += sprintf(p, "PIO\n"); | |
4504 | + } | |
4505 | + p += sprintf(p, "\n"); | |
4506 | ||
4507 | return p-buffer; /* => must be less than 4k! */ | |
4508 | } | |
4509 | @@ -92,27 +108,65 @@ | |
4510 | ||
4511 | byte hpt34x_proc = 0; | |
4512 | ||
4513 | -extern char *ide_xfer_verbose (byte xfer_rate); | |
4514 | +static byte hpt34x_ratemask (ide_drive_t *drive) | |
4515 | +{ | |
4516 | + byte mode = 0x00; | |
4517 | + | |
4518 | + mode |= 0x01; | |
4519 | + | |
4520 | + if (!eighty_ninty_three(drive)) { | |
4521 | + mode &= ~0xFE; | |
4522 | + mode |= 0x01; | |
4523 | + } | |
4524 | + return (mode &= ~0xF8); | |
4525 | +} | |
4526 | + | |
4527 | +static byte hpt34x_ratefilter (ide_drive_t *drive, byte speed) | |
4528 | +{ | |
4529 | +#ifdef CONFIG_BLK_DEV_IDEDMA | |
4530 | +# ifdef CONFIG_HPT34X_AUTODMA | |
4531 | +byte mode = hpt34x_ratemask(drive); | |
4532 | + | |
4533 | + switch(mode) { | |
4534 | + case 0x04: // while (speed > XFER_UDMA_6) speed--; break; | |
4535 | + case 0x03: // while (speed > XFER_UDMA_5) speed--; break; | |
4536 | + case 0x02: // while (speed > XFER_UDMA_4) speed--; break; | |
4537 | + case 0x01: while (speed > XFER_UDMA_2) speed--; break; | |
4538 | + case 0x00: | |
4539 | + default: while (speed > XFER_MW_DMA_2) speed--; break; | |
4540 | + break; | |
4541 | + } | |
4542 | +# else /* !CONFIG_HPT34X_AUTODMA */ | |
4543 | + while (speed > XFER_PIO_4) speed--; | |
4544 | +# endif /* CONFIG_HPT34X_AUTODMA */ | |
4545 | +#else | |
4546 | + while (speed > XFER_PIO_4) speed--; | |
4547 | +#endif /* CONFIG_BLK_DEV_IDEDMA */ | |
4548 | +// printk("%s: mode == %02x speed == %02x\n", drive->name, mode, speed); | |
4549 | + return speed; | |
4550 | +} | |
4551 | ||
4552 | static void hpt34x_clear_chipset (ide_drive_t *drive) | |
4553 | { | |
4554 | + struct pci_dev *dev = HWIF(drive)->pci_dev; | |
4555 | unsigned int reg1 = 0, tmp1 = 0; | |
4556 | unsigned int reg2 = 0, tmp2 = 0; | |
4557 | ||
4558 | - pci_read_config_dword(HWIF(drive)->pci_dev, 0x44, ®1); | |
4559 | - pci_read_config_dword(HWIF(drive)->pci_dev, 0x48, ®2); | |
4560 | + pci_read_config_dword(dev, 0x44, ®1); | |
4561 | + pci_read_config_dword(dev, 0x48, ®2); | |
4562 | tmp1 = ((0x00 << (3*drive->dn)) | (reg1 & ~(7 << (3*drive->dn)))); | |
4563 | tmp2 = (reg2 & ~(0x11 << drive->dn)); | |
4564 | - pci_write_config_dword(HWIF(drive)->pci_dev, 0x44, tmp1); | |
4565 | - pci_write_config_dword(HWIF(drive)->pci_dev, 0x48, tmp2); | |
4566 | + pci_write_config_dword(dev, 0x44, tmp1); | |
4567 | + pci_write_config_dword(dev, 0x48, tmp2); | |
4568 | } | |
4569 | ||
4570 | -static int hpt34x_tune_chipset (ide_drive_t *drive, byte speed) | |
4571 | +static int hpt34x_tune_chipset (ide_drive_t *drive, byte xferspeed) | |
4572 | { | |
4573 | - int err; | |
4574 | - byte hi_speed, lo_speed; | |
4575 | + struct pci_dev *dev = HWIF(drive)->pci_dev; | |
4576 | + byte speed = hpt34x_ratefilter(drive, xferspeed); | |
4577 | unsigned int reg1 = 0, tmp1 = 0; | |
4578 | unsigned int reg2 = 0, tmp2 = 0; | |
4579 | + byte hi_speed, lo_speed; | |
4580 | ||
4581 | SPLIT_BYTE(speed, hi_speed, lo_speed); | |
4582 | ||
4583 | @@ -123,76 +177,35 @@ | |
4584 | lo_speed >>= 5; | |
4585 | } | |
4586 | ||
4587 | - pci_read_config_dword(HWIF(drive)->pci_dev, 0x44, ®1); | |
4588 | - pci_read_config_dword(HWIF(drive)->pci_dev, 0x48, ®2); | |
4589 | + pci_read_config_dword(dev, 0x44, ®1); | |
4590 | + pci_read_config_dword(dev, 0x48, ®2); | |
4591 | tmp1 = ((lo_speed << (3*drive->dn)) | (reg1 & ~(7 << (3*drive->dn)))); | |
4592 | tmp2 = ((hi_speed << drive->dn) | reg2); | |
4593 | - err = ide_config_drive_speed(drive, speed); | |
4594 | - pci_write_config_dword(HWIF(drive)->pci_dev, 0x44, tmp1); | |
4595 | - pci_write_config_dword(HWIF(drive)->pci_dev, 0x48, tmp2); | |
4596 | - | |
4597 | - if (!drive->init_speed) | |
4598 | - drive->init_speed = speed; | |
4599 | + pci_write_config_dword(dev, 0x44, tmp1); | |
4600 | + pci_write_config_dword(dev, 0x48, tmp2); | |
4601 | ||
4602 | #if HPT343_DEBUG_DRIVE_INFO | |
4603 | printk("%s: %s drive%d (0x%04x 0x%04x) (0x%04x 0x%04x)" \ | |
4604 | - " (0x%02x 0x%02x) 0x%04x\n", | |
4605 | + " (0x%02x 0x%02x)\n", | |
4606 | drive->name, ide_xfer_verbose(speed), | |
4607 | drive->dn, reg1, tmp1, reg2, tmp2, | |
4608 | - hi_speed, lo_speed, err); | |
4609 | + hi_speed, lo_speed); | |
4610 | #endif /* HPT343_DEBUG_DRIVE_INFO */ | |
4611 | ||
4612 | - drive->current_speed = speed; | |
4613 | - return(err); | |
4614 | -} | |
4615 | - | |
4616 | -static void config_chipset_for_pio (ide_drive_t *drive) | |
4617 | -{ | |
4618 | - unsigned short eide_pio_timing[6] = {960, 480, 240, 180, 120, 90}; | |
4619 | - unsigned short xfer_pio = drive->id->eide_pio_modes; | |
4620 | - | |
4621 | - byte timing, speed, pio; | |
4622 | - | |
4623 | - pio = ide_get_best_pio_mode(drive, 255, 5, NULL); | |
4624 | - | |
4625 | - if (xfer_pio> 4) | |
4626 | - xfer_pio = 0; | |
4627 | - | |
4628 | - if (drive->id->eide_pio_iordy > 0) { | |
4629 | - for (xfer_pio = 5; | |
4630 | - xfer_pio>0 && | |
4631 | - drive->id->eide_pio_iordy>eide_pio_timing[xfer_pio]; | |
4632 | - xfer_pio--); | |
4633 | - } else { | |
4634 | - xfer_pio = (drive->id->eide_pio_modes & 4) ? 0x05 : | |
4635 | - (drive->id->eide_pio_modes & 2) ? 0x04 : | |
4636 | - (drive->id->eide_pio_modes & 1) ? 0x03 : xfer_pio; | |
4637 | - } | |
4638 | - | |
4639 | - timing = (xfer_pio >= pio) ? xfer_pio : pio; | |
4640 | - | |
4641 | - switch(timing) { | |
4642 | - case 4: speed = XFER_PIO_4;break; | |
4643 | - case 3: speed = XFER_PIO_3;break; | |
4644 | - case 2: speed = XFER_PIO_2;break; | |
4645 | - case 1: speed = XFER_PIO_1;break; | |
4646 | - default: | |
4647 | - speed = (!drive->id->tPIO) ? XFER_PIO_0 : XFER_PIO_SLOW; | |
4648 | - break; | |
4649 | - } | |
4650 | - (void) hpt34x_tune_chipset(drive, speed); | |
4651 | + return(ide_config_drive_speed(drive, speed)); | |
4652 | } | |
4653 | ||
4654 | static void hpt34x_tune_drive (ide_drive_t *drive, byte pio) | |
4655 | { | |
4656 | byte speed; | |
4657 | + pio = ide_get_best_pio_mode(drive, pio, 5, NULL); | |
4658 | ||
4659 | switch(pio) { | |
4660 | - case 4: speed = XFER_PIO_4;break; | |
4661 | - case 3: speed = XFER_PIO_3;break; | |
4662 | - case 2: speed = XFER_PIO_2;break; | |
4663 | - case 1: speed = XFER_PIO_1;break; | |
4664 | - default: speed = XFER_PIO_0;break; | |
4665 | + case 4: speed = XFER_PIO_4; break; | |
4666 | + case 3: speed = XFER_PIO_3; break; | |
4667 | + case 2: speed = XFER_PIO_2; break; | |
4668 | + case 1: speed = XFER_PIO_1; break; | |
4669 | + default: speed = XFER_PIO_0; break; | |
4670 | } | |
4671 | hpt34x_clear_chipset(drive); | |
4672 | (void) hpt34x_tune_chipset(drive, speed); | |
4673 | @@ -205,42 +218,41 @@ | |
4674 | * after the drive is reported by the OS. Initally for designed for | |
4675 | * HPT343 UDMA chipset by HighPoint|Triones Technologies, Inc. | |
4676 | */ | |
4677 | -static int config_chipset_for_dma (ide_drive_t *drive, byte ultra) | |
4678 | +static int config_chipset_for_dma (ide_drive_t *drive) | |
4679 | { | |
4680 | struct hd_driveid *id = drive->id; | |
4681 | + byte mode = hpt34x_ratemask(drive); | |
4682 | byte speed = 0x00; | |
4683 | ||
4684 | if (drive->media != ide_disk) | |
4685 | return ((int) ide_dma_off_quietly); | |
4686 | ||
4687 | - hpt34x_clear_chipset(drive); | |
4688 | - | |
4689 | - if ((id->dma_ultra & 0x0010) && ultra) { | |
4690 | - speed = XFER_UDMA_2; | |
4691 | - } else if ((id->dma_ultra & 0x0008) && ultra) { | |
4692 | - speed = XFER_UDMA_2; | |
4693 | - } else if ((id->dma_ultra & 0x0004) && ultra) { | |
4694 | - speed = XFER_UDMA_2; | |
4695 | - } else if ((id->dma_ultra & 0x0002) && ultra) { | |
4696 | - speed = XFER_UDMA_1; | |
4697 | - } else if ((id->dma_ultra & 0x0001) && ultra) { | |
4698 | - speed = XFER_UDMA_0; | |
4699 | - } else if (id->dma_mword & 0x0004) { | |
4700 | - speed = XFER_MW_DMA_2; | |
4701 | - } else if (id->dma_mword & 0x0002) { | |
4702 | - speed = XFER_MW_DMA_1; | |
4703 | - } else if (id->dma_mword & 0x0001) { | |
4704 | - speed = XFER_MW_DMA_0; | |
4705 | - } else if (id->dma_1word & 0x0004) { | |
4706 | - speed = XFER_SW_DMA_2; | |
4707 | - } else if (id->dma_1word & 0x0002) { | |
4708 | - speed = XFER_SW_DMA_1; | |
4709 | - } else if (id->dma_1word & 0x0001) { | |
4710 | - speed = XFER_SW_DMA_0; | |
4711 | - } else { | |
4712 | - return ((int) ide_dma_off_quietly); | |
4713 | + switch(mode) { | |
4714 | + case 0x01: | |
4715 | + if (id->dma_ultra & 0x0004) | |
4716 | + { speed = XFER_UDMA_2; break; } | |
4717 | + if (id->dma_ultra & 0x0002) | |
4718 | + { speed = XFER_UDMA_1; break; } | |
4719 | + if (id->dma_ultra & 0x0001) | |
4720 | + { speed = XFER_UDMA_0; break; } | |
4721 | + case 0x00: | |
4722 | + if (id->dma_mword & 0x0004) | |
4723 | + { speed = XFER_MW_DMA_2; break; } | |
4724 | + if (id->dma_mword & 0x0002) | |
4725 | + { speed = XFER_MW_DMA_1; break; } | |
4726 | + if (id->dma_mword & 0x0001) | |
4727 | + { speed = XFER_MW_DMA_0; break; } | |
4728 | + if (id->dma_1word & 0x0004) | |
4729 | + { speed = XFER_SW_DMA_2; break; } | |
4730 | + if (id->dma_1word & 0x0002) | |
4731 | + { speed = XFER_SW_DMA_1; break; } | |
4732 | + if (id->dma_1word & 0x0001) | |
4733 | + { speed = XFER_SW_DMA_0; break; } | |
4734 | + default: | |
4735 | + return ((int) ide_dma_off_quietly); | |
4736 | } | |
4737 | ||
4738 | + hpt34x_clear_chipset(drive); | |
4739 | (void) hpt34x_tune_chipset(drive, speed); | |
4740 | ||
4741 | return ((int) ((id->dma_ultra >> 11) & 3) ? ide_dma_off : | |
4742 | @@ -255,6 +267,8 @@ | |
4743 | struct hd_driveid *id = drive->id; | |
4744 | ide_dma_action_t dma_func = ide_dma_on; | |
4745 | ||
4746 | + drive->init_speed = 0; | |
4747 | + | |
4748 | if (id && (id->capability & 1) && HWIF(drive)->autodma) { | |
4749 | /* Consult the list of known "bad" drives */ | |
4750 | if (ide_dmaproc(ide_dma_bad_drive, drive)) { | |
4751 | @@ -265,7 +279,7 @@ | |
4752 | if (id->field_valid & 4) { | |
4753 | if (id->dma_ultra & 0x0007) { | |
4754 | /* Force if Capable UltraDMA */ | |
4755 | - dma_func = config_chipset_for_dma(drive, 1); | |
4756 | + dma_func = config_chipset_for_dma(drive); | |
4757 | if ((id->field_valid & 2) && | |
4758 | (dma_func != ide_dma_on)) | |
4759 | goto try_dma_modes; | |
4760 | @@ -275,7 +289,7 @@ | |
4761 | if ((id->dma_mword & 0x0007) || | |
4762 | (id->dma_1word & 0x0007)) { | |
4763 | /* Force if Capable regular DMA modes */ | |
4764 | - dma_func = config_chipset_for_dma(drive, 0); | |
4765 | + dma_func = config_chipset_for_dma(drive); | |
4766 | if (dma_func != ide_dma_on) | |
4767 | goto no_dma_set; | |
4768 | } | |
4769 | @@ -284,7 +298,7 @@ | |
4770 | goto no_dma_set; | |
4771 | } | |
4772 | /* Consult the list of known "good" drives */ | |
4773 | - dma_func = config_chipset_for_dma(drive, 0); | |
4774 | + dma_func = config_chipset_for_dma(drive); | |
4775 | if (dma_func != ide_dma_on) | |
4776 | goto no_dma_set; | |
4777 | } else { | |
4778 | @@ -294,7 +308,7 @@ | |
4779 | fast_ata_pio: | |
4780 | dma_func = ide_dma_off_quietly; | |
4781 | no_dma_set: | |
4782 | - config_chipset_for_pio(drive); | |
4783 | + hpt34x_tune_drive(drive, 255); | |
4784 | } | |
4785 | ||
4786 | #ifndef CONFIG_HPT34X_AUTODMA | |
4787 | @@ -316,6 +330,7 @@ | |
4788 | int hpt34x_dmaproc (ide_dma_action_t func, ide_drive_t *drive) | |
4789 | { | |
4790 | ide_hwif_t *hwif = HWIF(drive); | |
4791 | +// ide_task_t *args = HWGROUP(drive)->rq->special; | |
4792 | unsigned long dma_base = hwif->dma_base; | |
4793 | unsigned int count, reading = 0; | |
4794 | byte dma_stat; | |
4795 | @@ -327,24 +342,52 @@ | |
4796 | reading = 1 << 3; | |
4797 | case ide_dma_write: | |
4798 | if (!(count = ide_build_dmatable(drive, func))) | |
4799 | - return 1; /* try PIO instead of DMA */ | |
4800 | - outl(hwif->dmatable_dma, dma_base + 4); /* PRD table */ | |
4801 | + return 1; | |
4802 | + /* try PIO instead of DMA */ | |
4803 | + outl(hwif->dmatable_dma, dma_base + 4); | |
4804 | + /* PRD table */ | |
4805 | reading |= 0x01; | |
4806 | - outb(reading, dma_base); /* specify r/w */ | |
4807 | - outb(inb(dma_base+2)|6, dma_base+2); /* clear INTR & ERROR flags */ | |
4808 | + OUT_BYTE(reading, dma_base); | |
4809 | + /* specify r/w */ | |
4810 | + OUT_BYTE(IN_BYTE(dma_base+2)|6, dma_base+2); | |
4811 | + /* clear INTR & ERROR flags */ | |
4812 | drive->waiting_for_dma = 1; | |
4813 | if (drive->media != ide_disk) | |
4814 | return 0; | |
4815 | - ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL); /* issue cmd to drive */ | |
4816 | - OUT_BYTE((reading == 9) ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG); | |
4817 | - return 0; | |
4818 | + if (HWGROUP(drive)->handler != NULL) /* paranoia check */ | |
4819 | + BUG(); | |
4820 | + ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL); | |
4821 | + /* issue cmd to drive */ | |
4822 | + /* | |
4823 | + * FIX ME to use only ACB ide_task_t args Struct | |
4824 | + */ | |
4825 | +#if 0 | |
4826 | + { | |
4827 | + ide_task_t *args = HWGROUP(drive)->rq->special; | |
4828 | + OUT_BYTE(args->tfRegister[IDE_COMMAND_OFFSET], IDE_COMMAND_REG); | |
4829 | + { | |
4830 | +#else | |
4831 | + if (HWGROUP(drive)->rq->cmd == IDE_DRIVE_TASKFILE) { | |
4832 | + ide_task_t *args = HWGROUP(drive)->rq->special; | |
4833 | + OUT_BYTE(args->tfRegister[IDE_COMMAND_OFFSET], IDE_COMMAND_REG); | |
4834 | + } else if (drive->addressing == 1) | |
4835 | + OUT_BYTE((reading == 9) ? WIN_READDMA_EXT : WIN_WRITEDMA_EXT, IDE_COMMAND_REG); | |
4836 | + else | |
4837 | + OUT_BYTE((reading == 9) ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG); | |
4838 | +#endif | |
4839 | + return HWIF(drive)->dmaproc(ide_dma_begin, drive); | |
4840 | case ide_dma_end: /* returns 1 on error, 0 otherwise */ | |
4841 | drive->waiting_for_dma = 0; | |
4842 | - outb(inb(dma_base)&~1, dma_base); /* stop DMA */ | |
4843 | - dma_stat = inb(dma_base+2); /* get DMA status */ | |
4844 | - outb(dma_stat|6, dma_base+2); /* clear the INTR & ERROR bits */ | |
4845 | - ide_destroy_dmatable(drive); /* purge DMA mappings */ | |
4846 | - return (dma_stat & 7) != 4; /* verify good DMA status */ | |
4847 | + /* stop DMA */ | |
4848 | + OUT_BYTE(IN_BYTE(dma_base)&~1, dma_base); | |
4849 | + /* get DMA status */ | |
4850 | + dma_stat = IN_BYTE(dma_base+2); | |
4851 | + /* clear the INTR & ERROR bits */ | |
4852 | + OUT_BYTE(dma_stat|6, dma_base+2); | |
4853 | + /* purge DMA mappings */ | |
4854 | + ide_destroy_dmatable(drive); | |
4855 | + /* verify good DMA status */ | |
4856 | + return (dma_stat & 7) != 4; | |
4857 | default: | |
4858 | break; | |
4859 | } | |
4860 | @@ -361,11 +404,11 @@ | |
4861 | { | |
4862 | int i = 0; | |
4863 | unsigned long hpt34xIoBase = pci_resource_start(dev, 4); | |
4864 | + unsigned long hpt_addr[4] = { 0x20, 0x34, 0x28, 0x3c }; | |
4865 | unsigned short cmd; | |
4866 | unsigned long flags; | |
4867 | ||
4868 | - __save_flags(flags); /* local CPU only */ | |
4869 | - __cli(); /* local CPU only */ | |
4870 | + local_irq_save(flags); | |
4871 | ||
4872 | pci_write_config_byte(dev, HPT34X_PCI_INIT_REG, 0x00); | |
4873 | pci_read_config_word(dev, PCI_COMMAND, &cmd); | |
4874 | @@ -373,35 +416,34 @@ | |
4875 | if (cmd & PCI_COMMAND_MEMORY) { | |
4876 | if (pci_resource_start(dev, PCI_ROM_RESOURCE)) { | |
4877 | pci_write_config_byte(dev, PCI_ROM_ADDRESS, dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE); | |
4878 | - printk(KERN_INFO "HPT345: ROM enabled at 0x%08lx\n", dev->resource[PCI_ROM_RESOURCE].start); | |
4879 | + printk(KERN_INFO "HPT345: ROM enabled at 0x%08lx\n", | |
4880 | + dev->resource[PCI_ROM_RESOURCE].start); | |
4881 | } | |
4882 | pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0xF0); | |
4883 | } else { | |
4884 | pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x20); | |
4885 | } | |
4886 | ||
4887 | - pci_write_config_word(dev, PCI_COMMAND, cmd & ~PCI_COMMAND_IO); | |
4888 | - dev->resource[0].start = (hpt34xIoBase + 0x20); | |
4889 | - dev->resource[1].start = (hpt34xIoBase + 0x34); | |
4890 | - dev->resource[2].start = (hpt34xIoBase + 0x28); | |
4891 | - dev->resource[3].start = (hpt34xIoBase + 0x3c); | |
4892 | - for(i=0; i<4; i++) | |
4893 | - dev->resource[i].flags |= PCI_BASE_ADDRESS_SPACE_IO; | |
4894 | /* | |
4895 | * Since 20-23 can be assigned and are R/W, we correct them. | |
4896 | */ | |
4897 | - pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, dev->resource[0].start); | |
4898 | - pci_write_config_dword(dev, PCI_BASE_ADDRESS_1, dev->resource[1].start); | |
4899 | - pci_write_config_dword(dev, PCI_BASE_ADDRESS_2, dev->resource[2].start); | |
4900 | - pci_write_config_dword(dev, PCI_BASE_ADDRESS_3, dev->resource[3].start); | |
4901 | + pci_write_config_word(dev, PCI_COMMAND, cmd & ~PCI_COMMAND_IO); | |
4902 | + for(i=0; i<4; i++) { | |
4903 | + dev->resource[i].start = (hpt34xIoBase + hpt_addr[i]); | |
4904 | + dev->resource[i].flags |= PCI_BASE_ADDRESS_SPACE_IO; | |
4905 | + pci_write_config_dword(dev, | |
4906 | + (PCI_BASE_ADDRESS_0 + (i * 4)), | |
4907 | + dev->resource[i].start); | |
4908 | + } | |
4909 | pci_write_config_word(dev, PCI_COMMAND, cmd); | |
4910 | ||
4911 | - __restore_flags(flags); /* local CPU only */ | |
4912 | + local_irq_restore(flags); | |
4913 | + | |
4914 | + hpt34x_devs[n_hpt34x_devs++] = dev; | |
4915 | ||
4916 | #if defined(DISPLAY_HPT34X_TIMINGS) && defined(CONFIG_PROC_FS) | |
4917 | if (!hpt34x_proc) { | |
4918 | hpt34x_proc = 1; | |
4919 | - bmide_dev = dev; | |
4920 | hpt34x_display_info = &hpt34x_get_info; | |
4921 | } | |
4922 | #endif /* DISPLAY_HPT34X_TIMINGS && CONFIG_PROC_FS */ | |
4923 | @@ -411,27 +453,39 @@ | |
4924 | ||
4925 | void __init ide_init_hpt34x (ide_hwif_t *hwif) | |
4926 | { | |
4927 | + unsigned short pcicmd = 0; | |
4928 | hwif->tuneproc = &hpt34x_tune_drive; | |
4929 | hwif->speedproc = &hpt34x_tune_chipset; | |
4930 | - | |
4931 | -#ifdef CONFIG_BLK_DEV_IDEDMA | |
4932 | - if (hwif->dma_base) { | |
4933 | - unsigned short pcicmd = 0; | |
4934 | - | |
4935 | - pci_read_config_word(hwif->pci_dev, PCI_COMMAND, &pcicmd); | |
4936 | - if (!noautodma) | |
4937 | - hwif->autodma = (pcicmd & PCI_COMMAND_MEMORY) ? 1 : 0; | |
4938 | - else | |
4939 | - hwif->autodma = 0; | |
4940 | - | |
4941 | - hwif->dmaproc = &hpt34x_dmaproc; | |
4942 | - } else { | |
4943 | - hwif->drives[0].autotune = 1; | |
4944 | - hwif->drives[1].autotune = 1; | |
4945 | - } | |
4946 | -#else /* !CONFIG_BLK_DEV_IDEDMA */ | |
4947 | hwif->drives[0].autotune = 1; | |
4948 | hwif->drives[1].autotune = 1; | |
4949 | hwif->autodma = 0; | |
4950 | + | |
4951 | + pci_read_config_word(hwif->pci_dev, PCI_COMMAND, &pcicmd); | |
4952 | + | |
4953 | + if (!hwif->dma_base) | |
4954 | + return; | |
4955 | + | |
4956 | +#ifdef CONFIG_BLK_DEV_IDEDMA | |
4957 | + hwif->dmaproc = &hpt34x_dmaproc; | |
4958 | +#ifdef CONFIG_IDEDMA_AUTO | |
4959 | + if (!noautodma) | |
4960 | + hwif->autodma = (pcicmd & PCI_COMMAND_MEMORY) ? 1 : 0; | |
4961 | +#endif /* CONFIG_IDEDMA_AUTO */ | |
4962 | #endif /* CONFIG_BLK_DEV_IDEDMA */ | |
4963 | } | |
4964 | + | |
4965 | +extern void ide_setup_pci_device (struct pci_dev *dev, ide_pci_device_t *d); | |
4966 | + | |
4967 | +void __init fixup_device_hpt343 (struct pci_dev *dev, ide_pci_device_t *d) | |
4968 | +{ | |
4969 | + char *chipset_names[] = {"HPT343", "HPT345"}; | |
4970 | + unsigned short pcicmd = 0; | |
4971 | + | |
4972 | + pci_read_config_word(dev, PCI_COMMAND, &pcicmd); | |
4973 | + | |
4974 | + strcpy(d->name, chipset_names[(pcicmd & PCI_COMMAND_MEMORY) ? 1 : 0]); | |
4975 | + d->bootable = (pcicmd & PCI_COMMAND_MEMORY) ? OFF_BOARD : NEVER_BOARD; | |
4976 | + printk("%s: IDE controller on PCI bus %02x dev %02x\n", | |
4977 | + d->name, dev->bus->number, dev->devfn); | |
4978 | + ide_setup_pci_device(dev, d); | |
4979 | +} | |
4980 | diff -Nur linux.org/drivers/ide/hpt366.c linux/drivers/ide/hpt366.c | |
4981 | --- linux.org/drivers/ide/hpt366.c Wed Aug 15 05:01:07 2001 | |
4982 | +++ linux/drivers/ide/hpt366.c Thu Jul 18 14:24:33 2002 | |
4983 | @@ -1,8 +1,8 @@ | |
4984 | /* | |
4985 | - * linux/drivers/ide/hpt366.c Version 0.18 June. 9, 2000 | |
4986 | + * linux/drivers/ide/hpt366.c Version 0.33 April 17, 2002 | |
4987 | * | |
4988 | - * Copyright (C) 1999-2000 Andre Hedrick <andre@linux-ide.org> | |
4989 | - * May be copied or modified under the terms of the GNU General Public License | |
4990 | + * Copyright (C) 1999-2002 Andre Hedrick <andre@linux-ide.org> | |
4991 | + * Portions Copyright (C) 2001 Sun Microsystems, Inc. | |
4992 | * | |
4993 | * Thanks to HighPoint Technologies for their assistance, and hardware. | |
4994 | * Special Thanks to Jon Burchmore in SanDiego for the deep pockets, his | |
4995 | @@ -11,8 +11,37 @@ | |
4996 | * | |
4997 | * Note that final HPT370 support was done by force extraction of GPL. | |
4998 | * | |
4999 | + * - add function for getting/setting power status of drive | |
5000 | + * - the HPT370's state machine can get confused. reset it before each dma | |
5001 | + * xfer to prevent that from happening. | |
5002 | + * - reset state engine whenever we get an error. | |
5003 | + * - check for busmaster state at end of dma. | |
5004 | + * - use new highpoint timings. | |
5005 | + * - detect bus speed using highpoint register. | |
5006 | + * - use pll if we don't have a clock table. added a 66MHz table that's | |
5007 | + * just 2x the 33MHz table. | |
5008 | + * - removed turnaround. NOTE: we never want to switch between pll and | |
5009 | + * pci clocks as the chip can glitch in those cases. the highpoint | |
5010 | + * approved workaround slows everything down too much to be useful. in | |
5011 | + * addition, we would have to serialize access to each chip. | |
5012 | + * Adrian Sun <a.sun@sun.com> | |
5013 | + * | |
5014 | + * add drive timings for 66MHz PCI bus, | |
5015 | + * fix ATA Cable signal detection, fix incorrect /proc info | |
5016 | + * add /proc display for per-drive PIO/DMA/UDMA mode and | |
5017 | + * per-channel ATA-33/66 Cable detect. | |
5018 | + * Duncan Laurie <void@sun.com> | |
5019 | + * | |
5020 | + * fixup /proc output for multiple controllers | |
5021 | + * Tim Hockin <thockin@sun.com> | |
5022 | + * | |
5023 | + * On hpt366: | |
5024 | + * Reset the hpt366 on error, reset on dma | |
5025 | + * Fix disabling Fast Interrupt hpt366. | |
5026 | + * Mike Waychison <crlf@sun.com> | |
5027 | */ | |
5028 | ||
5029 | + | |
5030 | #include <linux/config.h> | |
5031 | #include <linux/types.h> | |
5032 | #include <linux/kernel.h> | |
5033 | @@ -28,6 +57,7 @@ | |
5034 | #include <linux/init.h> | |
5035 | #include <linux/ide.h> | |
5036 | ||
5037 | +#include <asm/uaccess.h> | |
5038 | #include <asm/io.h> | |
5039 | #include <asm/irq.h> | |
5040 | ||
5041 | @@ -35,13 +65,16 @@ | |
5042 | ||
5043 | #define DISPLAY_HPT366_TIMINGS | |
5044 | ||
5045 | +/* various tuning parameters */ | |
5046 | +#define HPT_RESET_STATE_ENGINE | |
5047 | +#undef HPT_DELAY_INTERRUPT | |
5048 | +#undef HPT_SERIALIZE_IO | |
5049 | + | |
5050 | #if defined(DISPLAY_HPT366_TIMINGS) && defined(CONFIG_PROC_FS) | |
5051 | #include <linux/stat.h> | |
5052 | #include <linux/proc_fs.h> | |
5053 | #endif /* defined(DISPLAY_HPT366_TIMINGS) && defined(CONFIG_PROC_FS) */ | |
5054 | ||
5055 | -extern char *ide_dmafunc_verbose(ide_dma_action_t dmafunc); | |
5056 | - | |
5057 | const char *quirk_drives[] = { | |
5058 | "QUANTUM FIREBALLlct08 08", | |
5059 | "QUANTUM FIREBALLP KA6.4", | |
5060 | @@ -106,160 +139,554 @@ | |
5061 | ||
5062 | struct chipset_bus_clock_list_entry { | |
5063 | byte xfer_speed; | |
5064 | - unsigned int chipset_settings_write; | |
5065 | - unsigned int chipset_settings_read; | |
5066 | + unsigned int chipset_settings; | |
5067 | }; | |
5068 | ||
5069 | -struct chipset_bus_clock_list_entry forty_base [] = { | |
5070 | +/* key for bus clock timings | |
5071 | + * bit | |
5072 | + * 0:3 data_high_time. inactive time of DIOW_/DIOR_ for PIO and MW | |
5073 | + * DMA. cycles = value + 1 | |
5074 | + * 4:8 data_low_time. active time of DIOW_/DIOR_ for PIO and MW | |
5075 | + * DMA. cycles = value + 1 | |
5076 | + * 9:12 cmd_high_time. inactive time of DIOW_/DIOR_ during task file | |
5077 | + * register access. | |
5078 | + * 13:17 cmd_low_time. active time of DIOW_/DIOR_ during task file | |
5079 | + * register access. | |
5080 | + * 18:21 udma_cycle_time. clock freq and clock cycles for UDMA xfer. | |
5081 | + * during task file register access. | |
5082 | + * 22:24 pre_high_time. time to initialize 1st cycle for PIO and MW DMA | |
5083 | + * xfer. | |
5084 | + * 25:27 cmd_pre_high_time. time to initialize 1st PIO cycle for task | |
5085 | + * register access. | |
5086 | + * 28 UDMA enable | |
5087 | + * 29 DMA enable | |
5088 | + * 30 PIO_MST enable. if set, the chip is in bus master mode during | |
5089 | + * PIO. | |
5090 | + * 31 FIFO enable. | |
5091 | + */ | |
5092 | +struct chipset_bus_clock_list_entry forty_base_hpt366[] = { | |
5093 | + { XFER_UDMA_4, 0x900fd943 }, | |
5094 | + { XFER_UDMA_3, 0x900ad943 }, | |
5095 | + { XFER_UDMA_2, 0x900bd943 }, | |
5096 | + { XFER_UDMA_1, 0x9008d943 }, | |
5097 | + { XFER_UDMA_0, 0x9008d943 }, | |
5098 | + | |
5099 | + { XFER_MW_DMA_2, 0xa008d943 }, | |
5100 | + { XFER_MW_DMA_1, 0xa010d955 }, | |
5101 | + { XFER_MW_DMA_0, 0xa010d9fc }, | |
5102 | + | |
5103 | + { XFER_PIO_4, 0xc008d963 }, | |
5104 | + { XFER_PIO_3, 0xc010d974 }, | |
5105 | + { XFER_PIO_2, 0xc010d997 }, | |
5106 | + { XFER_PIO_1, 0xc010d9c7 }, | |
5107 | + { XFER_PIO_0, 0xc018d9d9 }, | |
5108 | + { 0, 0x0120d9d9 } | |
5109 | +}; | |
5110 | ||
5111 | - { XFER_UDMA_4, 0x900fd943, 0x900fd943 }, | |
5112 | - { XFER_UDMA_3, 0x900ad943, 0x900ad943 }, | |
5113 | - { XFER_UDMA_2, 0x900bd943, 0x900bd943 }, | |
5114 | - { XFER_UDMA_1, 0x9008d943, 0x9008d943 }, | |
5115 | - { XFER_UDMA_0, 0x9008d943, 0x9008d943 }, | |
5116 | - | |
5117 | - { XFER_MW_DMA_2, 0xa008d943, 0xa008d943 }, | |
5118 | - { XFER_MW_DMA_1, 0xa010d955, 0xa010d955 }, | |
5119 | - { XFER_MW_DMA_0, 0xa010d9fc, 0xa010d9fc }, | |
5120 | - | |
5121 | - { XFER_PIO_4, 0xc008d963, 0xc008d963 }, | |
5122 | - { XFER_PIO_3, 0xc010d974, 0xc010d974 }, | |
5123 | - { XFER_PIO_2, 0xc010d997, 0xc010d997 }, | |
5124 | - { XFER_PIO_1, 0xc010d9c7, 0xc010d9c7 }, | |
5125 | - { XFER_PIO_0, 0xc018d9d9, 0xc018d9d9 }, | |
5126 | - { 0, 0x0120d9d9, 0x0120d9d9 } | |
5127 | -}; | |
5128 | - | |
5129 | -struct chipset_bus_clock_list_entry thirty_three_base [] = { | |
5130 | - | |
5131 | - { XFER_UDMA_4, 0x90c9a731, 0x90c9a731 }, | |
5132 | - { XFER_UDMA_3, 0x90cfa731, 0x90cfa731 }, | |
5133 | - { XFER_UDMA_2, 0x90caa731, 0x90caa731 }, | |
5134 | - { XFER_UDMA_1, 0x90cba731, 0x90cba731 }, | |
5135 | - { XFER_UDMA_0, 0x90c8a731, 0x90c8a731 }, | |
5136 | - | |
5137 | - { XFER_MW_DMA_2, 0xa0c8a731, 0xa0c8a731 }, | |
5138 | - { XFER_MW_DMA_1, 0xa0c8a732, 0xa0c8a732 }, /* 0xa0c8a733 */ | |
5139 | - { XFER_MW_DMA_0, 0xa0c8a797, 0xa0c8a797 }, | |
5140 | - | |
5141 | - { XFER_PIO_4, 0xc0c8a731, 0xc0c8a731 }, | |
5142 | - { XFER_PIO_3, 0xc0c8a742, 0xc0c8a742 }, | |
5143 | - { XFER_PIO_2, 0xc0d0a753, 0xc0d0a753 }, | |
5144 | - { XFER_PIO_1, 0xc0d0a7a3, 0xc0d0a7a3 }, /* 0xc0d0a793 */ | |
5145 | - { XFER_PIO_0, 0xc0d0a7aa, 0xc0d0a7aa }, /* 0xc0d0a7a7 */ | |
5146 | - { 0, 0x0120a7a7, 0x0120a7a7 } | |
5147 | -}; | |
5148 | - | |
5149 | -struct chipset_bus_clock_list_entry twenty_five_base [] = { | |
5150 | - | |
5151 | - { XFER_UDMA_4, 0x90c98521, 0x90c98521 }, | |
5152 | - { XFER_UDMA_3, 0x90cf8521, 0x90cf8521 }, | |
5153 | - { XFER_UDMA_2, 0x90cf8521, 0x90cf8521 }, | |
5154 | - { XFER_UDMA_1, 0x90cb8521, 0x90cb8521 }, | |
5155 | - { XFER_UDMA_0, 0x90cb8521, 0x90cb8521 }, | |
5156 | - | |
5157 | - { XFER_MW_DMA_2, 0xa0ca8521, 0xa0ca8521 }, | |
5158 | - { XFER_MW_DMA_1, 0xa0ca8532, 0xa0ca8532 }, | |
5159 | - { XFER_MW_DMA_0, 0xa0ca8575, 0xa0ca8575 }, | |
5160 | - | |
5161 | - { XFER_PIO_4, 0xc0ca8521, 0xc0ca8521 }, | |
5162 | - { XFER_PIO_3, 0xc0ca8532, 0xc0ca8532 }, | |
5163 | - { XFER_PIO_2, 0xc0ca8542, 0xc0ca8542 }, | |
5164 | - { XFER_PIO_1, 0xc0d08572, 0xc0d08572 }, | |
5165 | - { XFER_PIO_0, 0xc0d08585, 0xc0d08585 }, | |
5166 | - { 0, 0x01208585, 0x01208585 } | |
5167 | +struct chipset_bus_clock_list_entry thirty_three_base_hpt366[] = { | |
5168 | + { XFER_UDMA_4, 0x90c9a731 }, | |
5169 | + { XFER_UDMA_3, 0x90cfa731 }, | |
5170 | + { XFER_UDMA_2, 0x90caa731 }, | |
5171 | + { XFER_UDMA_1, 0x90cba731 }, | |
5172 | + { XFER_UDMA_0, 0x90c8a731 }, | |
5173 | + | |
5174 | + { XFER_MW_DMA_2, 0xa0c8a731 }, | |
5175 | + { XFER_MW_DMA_1, 0xa0c8a732 }, /* 0xa0c8a733 */ | |
5176 | + { XFER_MW_DMA_0, 0xa0c8a797 }, | |
5177 | + | |
5178 | + { XFER_PIO_4, 0xc0c8a731 }, | |
5179 | + { XFER_PIO_3, 0xc0c8a742 }, | |
5180 | + { XFER_PIO_2, 0xc0d0a753 }, | |
5181 | + { XFER_PIO_1, 0xc0d0a7a3 }, /* 0xc0d0a793 */ | |
5182 | + { XFER_PIO_0, 0xc0d0a7aa }, /* 0xc0d0a7a7 */ | |
5183 | + { 0, 0x0120a7a7 } | |
5184 | }; | |
5185 | ||
5186 | +struct chipset_bus_clock_list_entry twenty_five_base_hpt366[] = { | |
5187 | + | |
5188 | + { XFER_UDMA_4, 0x90c98521 }, | |
5189 | + { XFER_UDMA_3, 0x90cf8521 }, | |
5190 | + { XFER_UDMA_2, 0x90cf8521 }, | |
5191 | + { XFER_UDMA_1, 0x90cb8521 }, | |
5192 | + { XFER_UDMA_0, 0x90cb8521 }, | |
5193 | + | |
5194 | + { XFER_MW_DMA_2, 0xa0ca8521 }, | |
5195 | + { XFER_MW_DMA_1, 0xa0ca8532 }, | |
5196 | + { XFER_MW_DMA_0, 0xa0ca8575 }, | |
5197 | + | |
5198 | + { XFER_PIO_4, 0xc0ca8521 }, | |
5199 | + { XFER_PIO_3, 0xc0ca8532 }, | |
5200 | + { XFER_PIO_2, 0xc0ca8542 }, | |
5201 | + { XFER_PIO_1, 0xc0d08572 }, | |
5202 | + { XFER_PIO_0, 0xc0d08585 }, | |
5203 | + { 0, 0x01208585 } | |
5204 | +}; | |
5205 | + | |
5206 | +/* from highpoint documentation. these are old values */ | |
5207 | struct chipset_bus_clock_list_entry thirty_three_base_hpt370[] = { | |
5208 | - { XFER_UDMA_5, 0x1A85F442, 0x16454e31 }, | |
5209 | - { XFER_UDMA_4, 0x16454e31, 0x16454e31 }, | |
5210 | - { XFER_UDMA_3, 0x166d4e31, 0x166d4e31 }, | |
5211 | - { XFER_UDMA_2, 0x16494e31, 0x16494e31 }, | |
5212 | - { XFER_UDMA_1, 0x164d4e31, 0x164d4e31 }, | |
5213 | - { XFER_UDMA_0, 0x16514e31, 0x16514e31 }, | |
5214 | - | |
5215 | - { XFER_MW_DMA_2, 0x26514e21, 0x26514e21 }, | |
5216 | - { XFER_MW_DMA_1, 0x26514e33, 0x26514e33 }, | |
5217 | - { XFER_MW_DMA_0, 0x26514e97, 0x26514e97 }, | |
5218 | - | |
5219 | - { XFER_PIO_4, 0x06514e21, 0x06514e21 }, | |
5220 | - { XFER_PIO_3, 0x06514e22, 0x06514e22 }, | |
5221 | - { XFER_PIO_2, 0x06514e33, 0x06514e33 }, | |
5222 | - { XFER_PIO_1, 0x06914e43, 0x06914e43 }, | |
5223 | - { XFER_PIO_0, 0x06914e57, 0x06914e57 }, | |
5224 | - { 0, 0x06514e57, 0x06514e57 } | |
5225 | +/* { XFER_UDMA_5, 0x1A85F442, 0x16454e31 }, */ | |
5226 | + { XFER_UDMA_5, 0x16454e31 }, | |
5227 | + { XFER_UDMA_4, 0x16454e31 }, | |
5228 | + { XFER_UDMA_3, 0x166d4e31 }, | |
5229 | + { XFER_UDMA_2, 0x16494e31 }, | |
5230 | + { XFER_UDMA_1, 0x164d4e31 }, | |
5231 | + { XFER_UDMA_0, 0x16514e31 }, | |
5232 | + | |
5233 | + { XFER_MW_DMA_2, 0x26514e21 }, | |
5234 | + { XFER_MW_DMA_1, 0x26514e33 }, | |
5235 | + { XFER_MW_DMA_0, 0x26514e97 }, | |
5236 | + | |
5237 | + { XFER_PIO_4, 0x06514e21 }, | |
5238 | + { XFER_PIO_3, 0x06514e22 }, | |
5239 | + { XFER_PIO_2, 0x06514e33 }, | |
5240 | + { XFER_PIO_1, 0x06914e43 }, | |
5241 | + { XFER_PIO_0, 0x06914e57 }, | |
5242 | + { 0, 0x06514e57 } | |
5243 | +}; | |
5244 | + | |
5245 | +struct chipset_bus_clock_list_entry sixty_six_base_hpt370[] = { | |
5246 | + { XFER_UDMA_5, 0x14846231 }, | |
5247 | + { XFER_UDMA_4, 0x14886231 }, | |
5248 | + { XFER_UDMA_3, 0x148c6231 }, | |
5249 | + { XFER_UDMA_2, 0x148c6231 }, | |
5250 | + { XFER_UDMA_1, 0x14906231 }, | |
5251 | + { XFER_UDMA_0, 0x14986231 }, | |
5252 | + | |
5253 | + { XFER_MW_DMA_2, 0x26514e21 }, | |
5254 | + { XFER_MW_DMA_1, 0x26514e33 }, | |
5255 | + { XFER_MW_DMA_0, 0x26514e97 }, | |
5256 | + | |
5257 | + { XFER_PIO_4, 0x06514e21 }, | |
5258 | + { XFER_PIO_3, 0x06514e22 }, | |
5259 | + { XFER_PIO_2, 0x06514e33 }, | |
5260 | + { XFER_PIO_1, 0x06914e43 }, | |
5261 | + { XFER_PIO_0, 0x06914e57 }, | |
5262 | + { 0, 0x06514e57 } | |
5263 | +}; | |
5264 | + | |
5265 | +/* these are the current (4 sep 2001) timings from highpoint */ | |
5266 | +struct chipset_bus_clock_list_entry thirty_three_base_hpt370a[] = { | |
5267 | + { XFER_UDMA_5, 0x12446231 }, | |
5268 | + { XFER_UDMA_4, 0x12446231 }, | |
5269 | + { XFER_UDMA_3, 0x126c6231 }, | |
5270 | + { XFER_UDMA_2, 0x12486231 }, | |
5271 | + { XFER_UDMA_1, 0x124c6233 }, | |
5272 | + { XFER_UDMA_0, 0x12506297 }, | |
5273 | + | |
5274 | + { XFER_MW_DMA_2, 0x22406c31 }, | |
5275 | + { XFER_MW_DMA_1, 0x22406c33 }, | |
5276 | + { XFER_MW_DMA_0, 0x22406c97 }, | |
5277 | + | |
5278 | + { XFER_PIO_4, 0x06414e31 }, | |
5279 | + { XFER_PIO_3, 0x06414e42 }, | |
5280 | + { XFER_PIO_2, 0x06414e53 }, | |
5281 | + { XFER_PIO_1, 0x06814e93 }, | |
5282 | + { XFER_PIO_0, 0x06814ea7 }, | |
5283 | + { 0, 0x06814ea7 } | |
5284 | +}; | |
5285 | + | |
5286 | +/* 2x 33MHz timings */ | |
5287 | +struct chipset_bus_clock_list_entry sixty_six_base_hpt370a[] = { | |
5288 | + { XFER_UDMA_5, 0x1488e673 }, | |
5289 | + { XFER_UDMA_4, 0x1488e673 }, | |
5290 | + { XFER_UDMA_3, 0x1498e673 }, | |
5291 | + { XFER_UDMA_2, 0x1490e673 }, | |
5292 | + { XFER_UDMA_1, 0x1498e677 }, | |
5293 | + { XFER_UDMA_0, 0x14a0e73f }, | |
5294 | + | |
5295 | + { XFER_MW_DMA_2, 0x2480fa73 }, | |
5296 | + { XFER_MW_DMA_1, 0x2480fa77 }, | |
5297 | + { XFER_MW_DMA_0, 0x2480fb3f }, | |
5298 | + | |
5299 | + { XFER_PIO_4, 0x0c82be73 }, | |
5300 | + { XFER_PIO_3, 0x0c82be95 }, | |
5301 | + { XFER_PIO_2, 0x0c82beb7 }, | |
5302 | + { XFER_PIO_1, 0x0d02bf37 }, | |
5303 | + { XFER_PIO_0, 0x0d02bf5f }, | |
5304 | + { 0, 0x0d02bf5f } | |
5305 | +}; | |
5306 | + | |
5307 | +struct chipset_bus_clock_list_entry fifty_base_hpt370a[] = { | |
5308 | + { XFER_UDMA_5, 0x12848242 }, | |
5309 | + { XFER_UDMA_4, 0x12ac8242 }, | |
5310 | + { XFER_UDMA_3, 0x128c8242 }, | |
5311 | + { XFER_UDMA_2, 0x120c8242 }, | |
5312 | + { XFER_UDMA_1, 0x12148254 }, | |
5313 | + { XFER_UDMA_0, 0x121882ea }, | |
5314 | + | |
5315 | + { XFER_MW_DMA_2, 0x22808242 }, | |
5316 | + { XFER_MW_DMA_1, 0x22808254 }, | |
5317 | + { XFER_MW_DMA_0, 0x228082ea }, | |
5318 | + | |
5319 | + { XFER_PIO_4, 0x0a81f442 }, | |
5320 | + { XFER_PIO_3, 0x0a81f443 }, | |
5321 | + { XFER_PIO_2, 0x0a81f454 }, | |
5322 | + { XFER_PIO_1, 0x0ac1f465 }, | |
5323 | + { XFER_PIO_0, 0x0ac1f48a }, | |
5324 | + { 0, 0x0ac1f48a } | |
5325 | }; | |
5326 | ||
5327 | +struct chipset_bus_clock_list_entry thirty_three_base_hpt372[] = { | |
5328 | + { XFER_UDMA_6, 0x1c81dc62 }, | |
5329 | + { XFER_UDMA_5, 0x1c6ddc62 }, | |
5330 | + { XFER_UDMA_4, 0x1c8ddc62 }, | |
5331 | + { XFER_UDMA_3, 0x1c8edc62 }, /* checkme */ | |
5332 | + { XFER_UDMA_2, 0x1c91dc62 }, | |
5333 | + { XFER_UDMA_1, 0x1c9adc62 }, /* checkme */ | |
5334 | + { XFER_UDMA_0, 0x1c82dc62 }, /* checkme */ | |
5335 | + | |
5336 | + { XFER_MW_DMA_2, 0x2c829262 }, | |
5337 | + { XFER_MW_DMA_1, 0x2c829266 }, /* checkme */ | |
5338 | + { XFER_MW_DMA_0, 0x2c82922e }, /* checkme */ | |
5339 | + | |
5340 | + { XFER_PIO_4, 0x0c829c62 }, | |
5341 | + { XFER_PIO_3, 0x0c829c84 }, | |
5342 | + { XFER_PIO_2, 0x0c829ca6 }, | |
5343 | + { XFER_PIO_1, 0x0d029d26 }, | |
5344 | + { XFER_PIO_0, 0x0d029d5e }, | |
5345 | + { 0, 0x0d029d5e } | |
5346 | +}; | |
5347 | + | |
5348 | +struct chipset_bus_clock_list_entry fifty_base_hpt372[] = { | |
5349 | + { XFER_UDMA_5, 0x12848242 }, | |
5350 | + { XFER_UDMA_4, 0x12ac8242 }, | |
5351 | + { XFER_UDMA_3, 0x128c8242 }, | |
5352 | + { XFER_UDMA_2, 0x120c8242 }, | |
5353 | + { XFER_UDMA_1, 0x12148254 }, | |
5354 | + { XFER_UDMA_0, 0x121882ea }, | |
5355 | + | |
5356 | + { XFER_MW_DMA_2, 0x22808242 }, | |
5357 | + { XFER_MW_DMA_1, 0x22808254 }, | |
5358 | + { XFER_MW_DMA_0, 0x228082ea }, | |
5359 | + | |
5360 | + { XFER_PIO_4, 0x0a81f442 }, | |
5361 | + { XFER_PIO_3, 0x0a81f443 }, | |
5362 | + { XFER_PIO_2, 0x0a81f454 }, | |
5363 | + { XFER_PIO_1, 0x0ac1f465 }, | |
5364 | + { XFER_PIO_0, 0x0ac1f48a }, | |
5365 | + { 0, 0x0a81f443 } | |
5366 | +}; | |
5367 | + | |
5368 | +struct chipset_bus_clock_list_entry sixty_six_base_hpt372[] = { | |
5369 | + { XFER_UDMA_6, 0x1c869c62 }, | |
5370 | + { XFER_UDMA_5, 0x1cae9c62 }, | |
5371 | + { XFER_UDMA_4, 0x1c8a9c62 }, | |
5372 | + { XFER_UDMA_3, 0x1c8e9c62 }, | |
5373 | + { XFER_UDMA_2, 0x1c929c62 }, | |
5374 | + { XFER_UDMA_1, 0x1c9a9c62 }, | |
5375 | + { XFER_UDMA_0, 0x1c829c62 }, | |
5376 | + | |
5377 | + { XFER_MW_DMA_2, 0x2c829c62 }, | |
5378 | + { XFER_MW_DMA_1, 0x2c829c66 }, | |
5379 | + { XFER_MW_DMA_0, 0x2c829d2e }, | |
5380 | + | |
5381 | + { XFER_PIO_4, 0x0c829c62 }, | |
5382 | + { XFER_PIO_3, 0x0c829c84 }, | |
5383 | + { XFER_PIO_2, 0x0c829ca6 }, | |
5384 | + { XFER_PIO_1, 0x0d029d26 }, | |
5385 | + { XFER_PIO_0, 0x0d029d5e }, | |
5386 | + { 0, 0x0d029d26 } | |
5387 | +}; | |
5388 | + | |
5389 | +struct chipset_bus_clock_list_entry thirty_three_base_hpt374[] = { | |
5390 | + { XFER_UDMA_6, 0x12808242 }, | |
5391 | + { XFER_UDMA_5, 0x12848242 }, | |
5392 | + { XFER_UDMA_4, 0x12ac8242 }, | |
5393 | + { XFER_UDMA_3, 0x128c8242 }, | |
5394 | + { XFER_UDMA_2, 0x120c8242 }, | |
5395 | + { XFER_UDMA_1, 0x12148254 }, | |
5396 | + { XFER_UDMA_0, 0x121882ea }, | |
5397 | + | |
5398 | + { XFER_MW_DMA_2, 0x22808242 }, | |
5399 | + { XFER_MW_DMA_1, 0x22808254 }, | |
5400 | + { XFER_MW_DMA_0, 0x228082ea }, | |
5401 | + | |
5402 | + { XFER_PIO_4, 0x0a81f442 }, | |
5403 | + { XFER_PIO_3, 0x0a81f443 }, | |
5404 | + { XFER_PIO_2, 0x0a81f454 }, | |
5405 | + { XFER_PIO_1, 0x0ac1f465 }, | |
5406 | + { XFER_PIO_0, 0x0ac1f48a }, | |
5407 | + { 0, 0x06814e93 } | |
5408 | +}; | |
5409 | + | |
5410 | +#if 0 | |
5411 | +struct chipset_bus_clock_list_entry fifty_base_hpt374[] = { | |
5412 | + { XFER_UDMA_6, }, | |
5413 | + { XFER_UDMA_5, }, | |
5414 | + { XFER_UDMA_4, }, | |
5415 | + { XFER_UDMA_3, }, | |
5416 | + { XFER_UDMA_2, }, | |
5417 | + { XFER_UDMA_1, }, | |
5418 | + { XFER_UDMA_0, }, | |
5419 | + { XFER_MW_DMA_2, }, | |
5420 | + { XFER_MW_DMA_1, }, | |
5421 | + { XFER_MW_DMA_0, }, | |
5422 | + { XFER_PIO_4, }, | |
5423 | + { XFER_PIO_3, }, | |
5424 | + { XFER_PIO_2, }, | |
5425 | + { XFER_PIO_1, }, | |
5426 | + { XFER_PIO_0, }, | |
5427 | + { 0, } | |
5428 | +}; | |
5429 | +#endif | |
5430 | +#if 0 | |
5431 | +struct chipset_bus_clock_list_entry sixty_six_base_hpt374[] = { | |
5432 | + { XFER_UDMA_6, 0x12406231 }, /* checkme */ | |
5433 | + { XFER_UDMA_5, 0x12446231 }, | |
5434 | + 0x14846231 | |
5435 | + { XFER_UDMA_4, 0x16814ea7 }, | |
5436 | + 0x14886231 | |
5437 | + { XFER_UDMA_3, 0x16814ea7 }, | |
5438 | + 0x148c6231 | |
5439 | + { XFER_UDMA_2, 0x16814ea7 }, | |
5440 | + 0x148c6231 | |
5441 | + { XFER_UDMA_1, 0x16814ea7 }, | |
5442 | + 0x14906231 | |
5443 | + { XFER_UDMA_0, 0x16814ea7 }, | |
5444 | + 0x14986231 | |
5445 | + { XFER_MW_DMA_2, 0x16814ea7 }, | |
5446 | + 0x26514e21 | |
5447 | + { XFER_MW_DMA_1, 0x16814ea7 }, | |
5448 | + 0x26514e97 | |
5449 | + { XFER_MW_DMA_0, 0x16814ea7 }, | |
5450 | + 0x26514e97 | |
5451 | + { XFER_PIO_4, 0x06814ea7 }, | |
5452 | + 0x06514e21 | |
5453 | + { XFER_PIO_3, 0x06814ea7 }, | |
5454 | + 0x06514e22 | |
5455 | + { XFER_PIO_2, 0x06814ea7 }, | |
5456 | + 0x06514e33 | |
5457 | + { XFER_PIO_1, 0x06814ea7 }, | |
5458 | + 0x06914e43 | |
5459 | + { XFER_PIO_0, 0x06814ea7 }, | |
5460 | + 0x06914e57 | |
5461 | + { 0, 0x06814ea7 } | |
5462 | +}; | |
5463 | +#endif | |
5464 | + | |
5465 | #define HPT366_DEBUG_DRIVE_INFO 0 | |
5466 | +#define HPT374_ALLOW_ATA133_6 0 | |
5467 | +#define HPT371_ALLOW_ATA133_6 0 | |
5468 | +#define HPT302_ALLOW_ATA133_6 0 | |
5469 | +#define HPT372_ALLOW_ATA133_6 1 | |
5470 | #define HPT370_ALLOW_ATA100_5 1 | |
5471 | #define HPT366_ALLOW_ATA66_4 1 | |
5472 | #define HPT366_ALLOW_ATA66_3 1 | |
5473 | +#define HPT366_MAX_DEVS 8 | |
5474 | + | |
5475 | +#define F_LOW_PCI_33 0x23 | |
5476 | +#define F_LOW_PCI_40 0x29 | |
5477 | +#define F_LOW_PCI_50 0x2d | |
5478 | +#define F_LOW_PCI_66 0x42 | |
5479 | + | |
5480 | +static struct pci_dev *hpt_devs[HPT366_MAX_DEVS]; | |
5481 | +static int n_hpt_devs; | |
5482 | + | |
5483 | +static unsigned int hpt_revision(struct pci_dev *dev); | |
5484 | +static unsigned int hpt_minimum_revision(struct pci_dev *dev, int revision); | |
5485 | + | |
5486 | +byte hpt366_proc = 0; | |
5487 | +byte hpt363_shared_irq; | |
5488 | +byte hpt363_shared_pin; | |
5489 | ||
5490 | #if defined(DISPLAY_HPT366_TIMINGS) && defined(CONFIG_PROC_FS) | |
5491 | static int hpt366_get_info(char *, char **, off_t, int); | |
5492 | extern int (*hpt366_display_info)(char *, char **, off_t, int); /* ide-proc.c */ | |
5493 | -extern char *ide_media_verbose(ide_drive_t *); | |
5494 | -static struct pci_dev *bmide_dev; | |
5495 | -static struct pci_dev *bmide2_dev; | |
5496 | ||
5497 | static int hpt366_get_info (char *buffer, char **addr, off_t offset, int count) | |
5498 | { | |
5499 | - char *p = buffer; | |
5500 | - u32 bibma = bmide_dev->resource[4].start; | |
5501 | - u32 bibma2 = bmide2_dev->resource[4].start; | |
5502 | - char *chipset_names[] = {"HPT366", "HPT366", "HPT368", "HPT370", "HPT370A"}; | |
5503 | - u8 c0 = 0, c1 = 0; | |
5504 | - u32 class_rev; | |
5505 | - | |
5506 | - pci_read_config_dword(bmide_dev, PCI_CLASS_REVISION, &class_rev); | |
5507 | - class_rev &= 0xff; | |
5508 | - | |
5509 | - /* | |
5510 | - * at that point bibma+0x2 et bibma+0xa are byte registers | |
5511 | - * to investigate: | |
5512 | - */ | |
5513 | - c0 = inb_p((unsigned short)bibma + 0x02); | |
5514 | - if (bmide2_dev) | |
5515 | - c1 = inb_p((unsigned short)bibma2 + 0x02); | |
5516 | - | |
5517 | - p += sprintf(p, "\n %s Chipset.\n", chipset_names[class_rev]); | |
5518 | - p += sprintf(p, "--------------- Primary Channel ---------------- Secondary Channel -------------\n"); | |
5519 | - p += sprintf(p, " %sabled %sabled\n", | |
5520 | - (c0&0x80) ? "dis" : " en", | |
5521 | - (c1&0x80) ? "dis" : " en"); | |
5522 | - p += sprintf(p, "--------------- drive0 --------- drive1 -------- drive0 ---------- drive1 ------\n"); | |
5523 | - p += sprintf(p, "DMA enabled: %s %s %s %s\n", | |
5524 | - (c0&0x20) ? "yes" : "no ", (c0&0x40) ? "yes" : "no ", | |
5525 | - (c1&0x20) ? "yes" : "no ", (c1&0x40) ? "yes" : "no " ); | |
5526 | - | |
5527 | - p += sprintf(p, "UDMA\n"); | |
5528 | - p += sprintf(p, "DMA\n"); | |
5529 | - p += sprintf(p, "PIO\n"); | |
5530 | + char *p = buffer; | |
5531 | + char *chipset_nums[] = {"366", "366", "368", | |
5532 | + "370", "370A", "372", | |
5533 | + "302", "371", "374" }; | |
5534 | + int i; | |
5535 | + | |
5536 | + p += sprintf(p, "\n " | |
5537 | + "HighPoint HPT366/368/370/372/374\n"); | |
5538 | + for (i = 0; i < n_hpt_devs; i++) { | |
5539 | + struct pci_dev *dev = hpt_devs[i]; | |
5540 | + unsigned long iobase = dev->resource[4].start; | |
5541 | + u32 class_rev = hpt_revision(dev); | |
5542 | + u8 c0, c1; | |
5543 | + | |
5544 | + p += sprintf(p, "\nController: %d\n", i); | |
5545 | + p += sprintf(p, "Chipset: HPT%s\n", chipset_nums[class_rev]); | |
5546 | + p += sprintf(p, "--------------- Primary Channel " | |
5547 | + "--------------- Secondary Channel " | |
5548 | + "--------------\n"); | |
5549 | + | |
5550 | + /* get the bus master status registers */ | |
5551 | + c0 = inb_p(iobase + 0x2); | |
5552 | + c1 = inb_p(iobase + 0xa); | |
5553 | + p += sprintf(p, "Enabled: %s" | |
5554 | + " %s\n", | |
5555 | + (c0 & 0x80) ? "no" : "yes", | |
5556 | + (c1 & 0x80) ? "no" : "yes"); | |
5557 | + | |
5558 | + if (hpt_minimum_revision(dev, 3)) { | |
5559 | + u8 cbl; | |
5560 | + cbl = inb_p(iobase + 0x7b); | |
5561 | + outb_p(cbl | 1, iobase + 0x7b); | |
5562 | + outb_p(cbl & ~1, iobase + 0x7b); | |
5563 | + cbl = inb_p(iobase + 0x7a); | |
5564 | + p += sprintf(p, "Cable: ATA-%d" | |
5565 | + " ATA-%d\n", | |
5566 | + (cbl & 0x02) ? 33 : 66, | |
5567 | + (cbl & 0x01) ? 33 : 66); | |
5568 | + p += sprintf(p, "\n"); | |
5569 | + } | |
5570 | ||
5571 | + p += sprintf(p, "--------------- drive0 --------- drive1 " | |
5572 | + "------- drive0 ---------- drive1 -------\n"); | |
5573 | + p += sprintf(p, "DMA capable: %s %s" | |
5574 | + " %s %s\n", | |
5575 | + (c0 & 0x20) ? "yes" : "no ", | |
5576 | + (c0 & 0x40) ? "yes" : "no ", | |
5577 | + (c1 & 0x20) ? "yes" : "no ", | |
5578 | + (c1 & 0x40) ? "yes" : "no "); | |
5579 | + | |
5580 | + { | |
5581 | + u8 c2, c3; | |
5582 | + /* older revs don't have these registers mapped | |
5583 | + * into io space */ | |
5584 | + pci_read_config_byte(dev, 0x43, &c0); | |
5585 | + pci_read_config_byte(dev, 0x47, &c1); | |
5586 | + pci_read_config_byte(dev, 0x4b, &c2); | |
5587 | + pci_read_config_byte(dev, 0x4f, &c3); | |
5588 | + | |
5589 | + p += sprintf(p, "Mode: %s %s" | |
5590 | + " %s %s\n", | |
5591 | + (c0 & 0x10) ? "UDMA" : (c0 & 0x20) ? "DMA " : | |
5592 | + (c0 & 0x80) ? "PIO " : "off ", | |
5593 | + (c1 & 0x10) ? "UDMA" : (c1 & 0x20) ? "DMA " : | |
5594 | + (c1 & 0x80) ? "PIO " : "off ", | |
5595 | + (c2 & 0x10) ? "UDMA" : (c2 & 0x20) ? "DMA " : | |
5596 | + (c2 & 0x80) ? "PIO " : "off ", | |
5597 | + (c3 & 0x10) ? "UDMA" : (c3 & 0x20) ? "DMA " : | |
5598 | + (c3 & 0x80) ? "PIO " : "off "); | |
5599 | + } | |
5600 | + } | |
5601 | + p += sprintf(p, "\n"); | |
5602 | + | |
5603 | return p-buffer;/* => must be less than 4k! */ | |
5604 | } | |
5605 | #endif /* defined(DISPLAY_HPT366_TIMINGS) && defined(CONFIG_PROC_FS) */ | |
5606 | ||
5607 | -byte hpt366_proc = 0; | |
5608 | - | |
5609 | -extern char *ide_xfer_verbose (byte xfer_rate); | |
5610 | -byte hpt363_shared_irq; | |
5611 | -byte hpt363_shared_pin; | |
5612 | - | |
5613 | -static unsigned int pci_rev_check_hpt3xx (struct pci_dev *dev) | |
5614 | +static unsigned int hpt_revision (struct pci_dev *dev) | |
5615 | { | |
5616 | unsigned int class_rev; | |
5617 | pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); | |
5618 | class_rev &= 0xff; | |
5619 | - return ((int) (class_rev > 0x02) ? 1 : 0); | |
5620 | + | |
5621 | + switch(dev->device) { | |
5622 | + case PCI_DEVICE_ID_TTI_HPT374: | |
5623 | + class_rev = PCI_DEVICE_ID_TTI_HPT374; break; | |
5624 | + case PCI_DEVICE_ID_TTI_HPT371: | |
5625 | + class_rev = PCI_DEVICE_ID_TTI_HPT371; break; | |
5626 | + case PCI_DEVICE_ID_TTI_HPT302: | |
5627 | + class_rev = PCI_DEVICE_ID_TTI_HPT302; break; | |
5628 | + case PCI_DEVICE_ID_TTI_HPT372: | |
5629 | + class_rev = PCI_DEVICE_ID_TTI_HPT372; break; | |
5630 | + default: | |
5631 | + break; | |
5632 | + } | |
5633 | + return class_rev; | |
5634 | } | |
5635 | ||
5636 | -static unsigned int pci_rev2_check_hpt3xx (struct pci_dev *dev) | |
5637 | +static unsigned int hpt_minimum_revision (struct pci_dev *dev, int revision) | |
5638 | { | |
5639 | - unsigned int class_rev; | |
5640 | - pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); | |
5641 | - class_rev &= 0xff; | |
5642 | - return ((int) (class_rev > 0x01) ? 1 : 0); | |
5643 | + unsigned int class_rev = hpt_revision(dev); | |
5644 | + revision--; | |
5645 | + return ((int) (class_rev > revision) ? 1 : 0); | |
5646 | +} | |
5647 | + | |
5648 | +static int check_in_drive_lists(ide_drive_t *drive, const char **list); | |
5649 | + | |
5650 | +static byte hpt3xx_ratemask (ide_drive_t *drive) | |
5651 | +{ | |
5652 | + struct pci_dev *dev = HWIF(drive)->pci_dev; | |
5653 | + byte mode = 0x00; | |
5654 | + | |
5655 | + if (hpt_minimum_revision(dev, 8)) { /* HPT374 */ | |
5656 | + mode |= (HPT374_ALLOW_ATA133_6) ? 0x04 : 0x03; | |
5657 | + } else if (hpt_minimum_revision(dev, 7)) { /* HPT371 */ | |
5658 | + mode |= (HPT371_ALLOW_ATA133_6) ? 0x04 : 0x03; | |
5659 | + } else if (hpt_minimum_revision(dev, 6)) { /* HPT302 */ | |
5660 | + mode |= (HPT302_ALLOW_ATA133_6) ? 0x04 : 0x03; | |
5661 | + } else if (hpt_minimum_revision(dev, 5)) { /* HPT372 */ | |
5662 | + mode |= (HPT372_ALLOW_ATA133_6) ? 0x04 : 0x03; | |
5663 | + } else if (hpt_minimum_revision(dev, 4)) { /* HPT370A */ | |
5664 | + mode |= (HPT370_ALLOW_ATA100_5) ? 0x03 : 0x02; | |
5665 | + } else if (hpt_minimum_revision(dev, 3)) { /* HPT370 */ | |
5666 | + mode |= (HPT370_ALLOW_ATA100_5) ? 0x03 : 0x02; | |
5667 | + if (check_in_drive_lists(drive, bad_ata33)) | |
5668 | + return (mode &= ~0xFF); | |
5669 | + } else { /* HPT366 and HPT368 */ | |
5670 | + mode |= 0x02; | |
5671 | + if (check_in_drive_lists(drive, bad_ata33)) | |
5672 | + return (mode &= ~0xFF); | |
5673 | + } | |
5674 | + | |
5675 | + if (!eighty_ninty_three(drive)) { | |
5676 | + mode &= ~0xFE; | |
5677 | + mode |= 0x01; | |
5678 | + } | |
5679 | + return (mode &= ~0xF8); | |
5680 | +} | |
5681 | + | |
5682 | +static byte hpt3xx_ratefilter (ide_drive_t *drive, byte speed) | |
5683 | +{ | |
5684 | +#ifdef CONFIG_BLK_DEV_IDEDMA | |
5685 | + struct pci_dev *dev = HWIF(drive)->pci_dev; | |
5686 | + byte mode = hpt3xx_ratemask(drive); | |
5687 | + | |
5688 | + if (drive->media != ide_disk) | |
5689 | + while (speed > XFER_PIO_4) speed--; | |
5690 | + | |
5691 | + switch(mode) { | |
5692 | + case 0x04: | |
5693 | + while (speed > XFER_UDMA_6) speed--; | |
5694 | + break; | |
5695 | + case 0x03: | |
5696 | + while (speed > XFER_UDMA_5) speed--; | |
5697 | + if (hpt_minimum_revision(dev, 5)) | |
5698 | + break; | |
5699 | + if (check_in_drive_lists(drive, bad_ata100_5)) | |
5700 | + while (speed > XFER_UDMA_4) speed--; | |
5701 | + break; | |
5702 | + case 0x02: | |
5703 | + while (speed > XFER_UDMA_4) speed--; | |
5704 | + /* | |
5705 | + * CHECK ME, Does this need to be set to 5 ?? | |
5706 | + */ | |
5707 | + if (hpt_minimum_revision(dev, 3)) | |
5708 | + break; | |
5709 | + if ((check_in_drive_lists(drive, bad_ata66_4)) || | |
5710 | + (!(HPT366_ALLOW_ATA66_4))) | |
5711 | + while (speed > XFER_UDMA_3) speed--; | |
5712 | + if ((check_in_drive_lists(drive, bad_ata66_3)) || | |
5713 | + (!(HPT366_ALLOW_ATA66_3))) | |
5714 | + while (speed > XFER_UDMA_2) speed--; | |
5715 | + break; | |
5716 | + case 0x01: | |
5717 | + while (speed > XFER_UDMA_2) speed--; | |
5718 | + /* | |
5719 | + * CHECK ME, Does this need to be set to 5 ?? | |
5720 | + */ | |
5721 | + if (hpt_minimum_revision(dev, 3)) | |
5722 | + break; | |
5723 | + if (check_in_drive_lists(drive, bad_ata33)) | |
5724 | + while (speed > XFER_MW_DMA_2) speed--; | |
5725 | + break; | |
5726 | + case 0x00: | |
5727 | + default: while (speed > XFER_MW_DMA_2) speed--; break; | |
5728 | + break; | |
5729 | + } | |
5730 | +#else | |
5731 | + while (speed > XFER_PIO_4) speed--; | |
5732 | +#endif /* CONFIG_BLK_DEV_IDEDMA */ | |
5733 | +// printk("%s: mode == %02x speed == %02x\n", drive->name, mode, speed); | |
5734 | + return speed; | |
5735 | } | |
5736 | ||
5737 | static int check_in_drive_lists (ide_drive_t *drive, const char **list) | |
5738 | @@ -282,51 +709,44 @@ | |
5739 | return 0; | |
5740 | } | |
5741 | ||
5742 | -static unsigned int pci_bus_clock_list (byte speed, int direction, struct chipset_bus_clock_list_entry * chipset_table) | |
5743 | +static unsigned int pci_bus_clock_list (byte speed, struct chipset_bus_clock_list_entry * chipset_table) | |
5744 | { | |
5745 | for ( ; chipset_table->xfer_speed ; chipset_table++) | |
5746 | if (chipset_table->xfer_speed == speed) { | |
5747 | - return (direction) ? chipset_table->chipset_settings_write : chipset_table->chipset_settings_read; | |
5748 | + return chipset_table->chipset_settings; | |
5749 | } | |
5750 | - return (direction) ? chipset_table->chipset_settings_write : chipset_table->chipset_settings_read; | |
5751 | + return chipset_table->chipset_settings; | |
5752 | } | |
5753 | ||
5754 | -static void hpt366_tune_chipset (ide_drive_t *drive, byte speed, int direction) | |
5755 | +static void hpt366_tune_chipset (ide_drive_t *drive, byte xferspeed) | |
5756 | { | |
5757 | + struct pci_dev *dev = HWIF(drive)->pci_dev; | |
5758 | + byte speed = hpt3xx_ratefilter(drive, xferspeed); | |
5759 | byte regtime = (drive->select.b.unit & 0x01) ? 0x44 : 0x40; | |
5760 | byte regfast = (HWIF(drive)->channel) ? 0x55 : 0x51; | |
5761 | - /* | |
5762 | - * since the channel is always 0 it does not matter. | |
5763 | - */ | |
5764 | - | |
5765 | + byte drive_fast = 0; | |
5766 | unsigned int reg1 = 0; | |
5767 | unsigned int reg2 = 0; | |
5768 | - byte drive_fast = 0; | |
5769 | ||
5770 | /* | |
5771 | * Disable the "fast interrupt" prediction. | |
5772 | */ | |
5773 | - pci_read_config_byte(HWIF(drive)->pci_dev, regfast, &drive_fast); | |
5774 | + pci_read_config_byte(dev, regfast, &drive_fast); | |
5775 | +#if 0 | |
5776 | if (drive_fast & 0x02) | |
5777 | - pci_write_config_byte(HWIF(drive)->pci_dev, regfast, drive_fast & ~0x20); | |
5778 | + pci_write_config_byte(dev, regfast, drive_fast & ~0x20); | |
5779 | +#else | |
5780 | + if (drive_fast & 0x80) | |
5781 | + pci_write_config_byte(dev, regfast, drive_fast & ~0x80); | |
5782 | +#endif | |
5783 | ||
5784 | - pci_read_config_dword(HWIF(drive)->pci_dev, regtime, ®1); | |
5785 | - /* detect bus speed by looking at control reg timing: */ | |
5786 | - switch((reg1 >> 8) & 7) { | |
5787 | - case 5: | |
5788 | - reg2 = pci_bus_clock_list(speed, direction, forty_base); | |
5789 | - break; | |
5790 | - case 9: | |
5791 | - reg2 = pci_bus_clock_list(speed, direction, twenty_five_base); | |
5792 | - break; | |
5793 | - default: | |
5794 | - case 7: | |
5795 | - reg2 = pci_bus_clock_list(speed, direction, thirty_three_base); | |
5796 | - break; | |
5797 | - } | |
5798 | + reg2 = pci_bus_clock_list(speed, | |
5799 | + (struct chipset_bus_clock_list_entry *) dev->driver_data); | |
5800 | /* | |
5801 | - * Disable on-chip PIO FIFO/buffer (to avoid problems handling I/O errors later) | |
5802 | + * Disable on-chip PIO FIFO/buffer | |
5803 | + * (to avoid problems handling I/O errors later) | |
5804 | */ | |
5805 | + pci_read_config_dword(dev, regtime, ®1); | |
5806 | if (speed >= XFER_MW_DMA_0) { | |
5807 | reg2 = (reg2 & ~0xc0000000) | (reg1 & 0xc0000000); | |
5808 | } else { | |
5809 | @@ -334,109 +754,127 @@ | |
5810 | } | |
5811 | reg2 &= ~0x80000000; | |
5812 | ||
5813 | - pci_write_config_dword(HWIF(drive)->pci_dev, regtime, reg2); | |
5814 | + pci_write_config_dword(dev, regtime, reg2); | |
5815 | } | |
5816 | ||
5817 | -static void hpt370_tune_chipset (ide_drive_t *drive, byte speed, int direction) | |
5818 | +static void hpt368_tune_chipset (ide_drive_t *drive, byte speed) | |
5819 | { | |
5820 | + hpt366_tune_chipset(drive, speed); | |
5821 | +} | |
5822 | + | |
5823 | +static void hpt370_tune_chipset (ide_drive_t *drive, byte xferspeed) | |
5824 | +{ | |
5825 | + byte speed = hpt3xx_ratefilter(drive, xferspeed); | |
5826 | byte regfast = (HWIF(drive)->channel) ? 0x55 : 0x51; | |
5827 | - byte reg5bh = (speed != XFER_UDMA_5) ? 0x22 : (direction) ? 0x20 : 0x22; | |
5828 | - unsigned int list_conf = pci_bus_clock_list(speed, direction, thirty_three_base_hpt370); | |
5829 | + unsigned int list_conf = 0; | |
5830 | unsigned int drive_conf = 0; | |
5831 | unsigned int conf_mask = (speed >= XFER_MW_DMA_0) ? 0xc0000000 : 0x30070000; | |
5832 | - byte drive_pci = 0; | |
5833 | - byte drive_fast = 0; | |
5834 | + byte drive_pci = 0x40 + (drive->dn * 4); | |
5835 | + byte new_fast, drive_fast = 0; | |
5836 | + struct pci_dev *dev = HWIF(drive)->pci_dev; | |
5837 | ||
5838 | - switch (drive->dn) { | |
5839 | - case 0: drive_pci = 0x40; break; | |
5840 | - case 1: drive_pci = 0x44; break; | |
5841 | - case 2: drive_pci = 0x48; break; | |
5842 | - case 3: drive_pci = 0x4c; break; | |
5843 | - default: return; | |
5844 | - } | |
5845 | /* | |
5846 | * Disable the "fast interrupt" prediction. | |
5847 | + * don't holdoff on interrupts. (== 0x01 despite what the docs say) | |
5848 | */ | |
5849 | - pci_read_config_byte(HWIF(drive)->pci_dev, regfast, &drive_fast); | |
5850 | - if (drive_fast & 0x80) | |
5851 | - pci_write_config_byte(HWIF(drive)->pci_dev, regfast, drive_fast & ~0x80); | |
5852 | + pci_read_config_byte(dev, regfast, &drive_fast); | |
5853 | + new_fast = drive_fast; | |
5854 | + if (new_fast & 0x02) | |
5855 | + new_fast &= ~0x02; | |
5856 | + | |
5857 | +#ifdef HPT_DELAY_INTERRUPT | |
5858 | + if (new_fast & 0x01) | |
5859 | + new_fast &= ~0x01; | |
5860 | +#else | |
5861 | + if ((new_fast & 0x01) == 0) | |
5862 | + new_fast |= 0x01; | |
5863 | +#endif | |
5864 | + if (new_fast != drive_fast) | |
5865 | + pci_write_config_byte(dev, regfast, new_fast); | |
5866 | ||
5867 | - pci_read_config_dword(HWIF(drive)->pci_dev, drive_pci, &drive_conf); | |
5868 | - pci_write_config_byte(HWIF(drive)->pci_dev, 0x5b, reg5bh); | |
5869 | + list_conf = pci_bus_clock_list(speed, | |
5870 | + (struct chipset_bus_clock_list_entry *) | |
5871 | + dev->driver_data); | |
5872 | ||
5873 | + pci_read_config_dword(dev, drive_pci, &drive_conf); | |
5874 | list_conf = (list_conf & ~conf_mask) | (drive_conf & conf_mask); | |
5875 | - /* | |
5876 | - * Disable on-chip PIO FIFO/buffer (to avoid problems handling I/O errors later) | |
5877 | - */ | |
5878 | - list_conf &= ~0x80000000; | |
5879 | + | |
5880 | + if (speed < XFER_MW_DMA_0) { | |
5881 | + list_conf &= ~0x80000000; /* Disable on-chip PIO FIFO/buffer */ | |
5882 | + } | |
5883 | ||
5884 | - pci_write_config_dword(HWIF(drive)->pci_dev, drive_pci, list_conf); | |
5885 | + pci_write_config_dword(dev, drive_pci, list_conf); | |
5886 | } | |
5887 | ||
5888 | -static int hpt3xx_tune_chipset (ide_drive_t *drive, byte speed) | |
5889 | +static void hpt372_tune_chipset (ide_drive_t *drive, byte xferspeed) | |
5890 | { | |
5891 | - if ((drive->media != ide_disk) && (speed < XFER_SW_DMA_0)) | |
5892 | - return -1; | |
5893 | + byte speed = hpt3xx_ratefilter(drive, xferspeed); | |
5894 | + byte regfast = (HWIF(drive)->channel) ? 0x55 : 0x51; | |
5895 | + unsigned int list_conf = 0; | |
5896 | + unsigned int drive_conf = 0; | |
5897 | + unsigned int conf_mask = (speed >= XFER_MW_DMA_0) ? 0xc0000000 : 0x30070000; | |
5898 | + byte drive_pci = 0x40 + (drive->dn * 4); | |
5899 | + byte drive_fast = 0; | |
5900 | + struct pci_dev *dev = HWIF(drive)->pci_dev; | |
5901 | ||
5902 | - if (!drive->init_speed) | |
5903 | - drive->init_speed = speed; | |
5904 | + /* | |
5905 | + * Disable the "fast interrupt" prediction. | |
5906 | + * don't holdoff on interrupts. (== 0x01 despite what the docs say) | |
5907 | + */ | |
5908 | + pci_read_config_byte(dev, regfast, &drive_fast); | |
5909 | + drive_fast &= ~0x07; | |
5910 | + pci_write_config_byte(dev, regfast, drive_fast); | |
5911 | + | |
5912 | + list_conf = pci_bus_clock_list(speed, | |
5913 | + (struct chipset_bus_clock_list_entry *) | |
5914 | + dev->driver_data); | |
5915 | + pci_read_config_dword(dev, drive_pci, &drive_conf); | |
5916 | + list_conf = (list_conf & ~conf_mask) | (drive_conf & conf_mask); | |
5917 | + if (speed < XFER_MW_DMA_0) | |
5918 | + list_conf &= ~0x80000000; /* Disable on-chip PIO FIFO/buffer */ | |
5919 | + pci_write_config_dword(dev, drive_pci, list_conf); | |
5920 | +} | |
5921 | ||
5922 | - if (pci_rev_check_hpt3xx(HWIF(drive)->pci_dev)) { | |
5923 | - hpt370_tune_chipset(drive, speed, 0); | |
5924 | - } else { | |
5925 | - hpt366_tune_chipset(drive, speed, 0); | |
5926 | - } | |
5927 | - drive->current_speed = speed; | |
5928 | - return ((int) ide_config_drive_speed(drive, speed)); | |
5929 | +static void hpt374_tune_chipset (ide_drive_t *drive, byte speed) | |
5930 | +{ | |
5931 | + hpt372_tune_chipset(drive, speed); | |
5932 | } | |
5933 | ||
5934 | -static void config_chipset_for_pio (ide_drive_t *drive) | |
5935 | +static int hpt3xx_tune_chipset (ide_drive_t *drive, byte speed) | |
5936 | { | |
5937 | - unsigned short eide_pio_timing[6] = {960, 480, 240, 180, 120, 90}; | |
5938 | - unsigned short xfer_pio = drive->id->eide_pio_modes; | |
5939 | - byte timing, speed, pio; | |
5940 | - | |
5941 | - pio = ide_get_best_pio_mode(drive, 255, 5, NULL); | |
5942 | - | |
5943 | - if (xfer_pio> 4) | |
5944 | - xfer_pio = 0; | |
5945 | - | |
5946 | - if (drive->id->eide_pio_iordy > 0) { | |
5947 | - for (xfer_pio = 5; | |
5948 | - xfer_pio>0 && | |
5949 | - drive->id->eide_pio_iordy>eide_pio_timing[xfer_pio]; | |
5950 | - xfer_pio--); | |
5951 | - } else { | |
5952 | - xfer_pio = (drive->id->eide_pio_modes & 4) ? 0x05 : | |
5953 | - (drive->id->eide_pio_modes & 2) ? 0x04 : | |
5954 | - (drive->id->eide_pio_modes & 1) ? 0x03 : | |
5955 | - (drive->id->tPIO & 2) ? 0x02 : | |
5956 | - (drive->id->tPIO & 1) ? 0x01 : xfer_pio; | |
5957 | - } | |
5958 | + struct pci_dev *dev = HWIF(drive)->pci_dev; | |
5959 | ||
5960 | - timing = (xfer_pio >= pio) ? xfer_pio : pio; | |
5961 | - | |
5962 | - switch(timing) { | |
5963 | - case 4: speed = XFER_PIO_4;break; | |
5964 | - case 3: speed = XFER_PIO_3;break; | |
5965 | - case 2: speed = XFER_PIO_2;break; | |
5966 | - case 1: speed = XFER_PIO_1;break; | |
5967 | - default: | |
5968 | - speed = (!drive->id->tPIO) ? XFER_PIO_0 : XFER_PIO_SLOW; | |
5969 | - break; | |
5970 | - } | |
5971 | - (void) hpt3xx_tune_chipset(drive, speed); | |
5972 | + if (hpt_minimum_revision(dev, 8)) | |
5973 | + hpt374_tune_chipset(drive, speed); | |
5974 | +#if 0 | |
5975 | + else if (hpt_minimum_revision(dev, 7)) | |
5976 | + hpt371_tune_chipset(drive, speed); | |
5977 | + else if (hpt_minimum_revision(dev, 6)) | |
5978 | + hpt302_tune_chipset(drive, speed); | |
5979 | +#endif | |
5980 | + else if (hpt_minimum_revision(dev, 5)) | |
5981 | + hpt372_tune_chipset(drive, speed); | |
5982 | + else if (hpt_minimum_revision(dev, 3)) | |
5983 | + hpt370_tune_chipset(drive, speed); | |
5984 | + else if (hpt_minimum_revision(dev, 2)) | |
5985 | + hpt368_tune_chipset(drive, speed); | |
5986 | + else | |
5987 | + hpt366_tune_chipset(drive, speed); | |
5988 | + | |
5989 | + return ((int) ide_config_drive_speed(drive, speed)); | |
5990 | } | |
5991 | ||
5992 | static void hpt3xx_tune_drive (ide_drive_t *drive, byte pio) | |
5993 | { | |
5994 | byte speed; | |
5995 | + | |
5996 | + pio = ide_get_best_pio_mode(drive, pio, 5, NULL); | |
5997 | switch(pio) { | |
5998 | - case 4: speed = XFER_PIO_4;break; | |
5999 | - case 3: speed = XFER_PIO_3;break; | |
6000 | - case 2: speed = XFER_PIO_2;break; | |
6001 | - case 1: speed = XFER_PIO_1;break; | |
6002 | - default: speed = XFER_PIO_0;break; | |
6003 | + case 4: speed = XFER_PIO_4; break; | |
6004 | + case 3: speed = XFER_PIO_3; break; | |
6005 | + case 2: speed = XFER_PIO_2; break; | |
6006 | + case 1: speed = XFER_PIO_1; break; | |
6007 | + default: speed = XFER_PIO_0; break; | |
6008 | } | |
6009 | (void) hpt3xx_tune_chipset(drive, speed); | |
6010 | } | |
6011 | @@ -456,54 +894,49 @@ | |
6012 | static int config_chipset_for_dma (ide_drive_t *drive) | |
6013 | { | |
6014 | struct hd_driveid *id = drive->id; | |
6015 | + byte mode = hpt3xx_ratemask(drive); | |
6016 | byte speed = 0x00; | |
6017 | - byte ultra66 = eighty_ninty_three(drive); | |
6018 | - int rval; | |
6019 | ||
6020 | - if ((drive->media != ide_disk) && (speed < XFER_SW_DMA_0)) | |
6021 | - return ((int) ide_dma_off_quietly); | |
6022 | + if (drive->media != ide_disk) | |
6023 | + mode |= 0x08; | |
6024 | ||
6025 | - if ((id->dma_ultra & 0x0020) && | |
6026 | - (!check_in_drive_lists(drive, bad_ata100_5)) && | |
6027 | - (HPT370_ALLOW_ATA100_5) && | |
6028 | - (pci_rev_check_hpt3xx(HWIF(drive)->pci_dev)) && | |
6029 | - (ultra66)) { | |
6030 | - speed = XFER_UDMA_5; | |
6031 | - } else if ((id->dma_ultra & 0x0010) && | |
6032 | - (!check_in_drive_lists(drive, bad_ata66_4)) && | |
6033 | - (HPT366_ALLOW_ATA66_4) && | |
6034 | - (ultra66)) { | |
6035 | - speed = XFER_UDMA_4; | |
6036 | - } else if ((id->dma_ultra & 0x0008) && | |
6037 | - (!check_in_drive_lists(drive, bad_ata66_3)) && | |
6038 | - (HPT366_ALLOW_ATA66_3) && | |
6039 | - (ultra66)) { | |
6040 | - speed = XFER_UDMA_3; | |
6041 | - } else if (id->dma_ultra && (!check_in_drive_lists(drive, bad_ata33))) { | |
6042 | - if (id->dma_ultra & 0x0004) { | |
6043 | - speed = XFER_UDMA_2; | |
6044 | - } else if (id->dma_ultra & 0x0002) { | |
6045 | - speed = XFER_UDMA_1; | |
6046 | - } else if (id->dma_ultra & 0x0001) { | |
6047 | - speed = XFER_UDMA_0; | |
6048 | - } | |
6049 | - } else if (id->dma_mword & 0x0004) { | |
6050 | - speed = XFER_MW_DMA_2; | |
6051 | - } else if (id->dma_mword & 0x0002) { | |
6052 | - speed = XFER_MW_DMA_1; | |
6053 | - } else if (id->dma_mword & 0x0001) { | |
6054 | - speed = XFER_MW_DMA_0; | |
6055 | - } else { | |
6056 | - return ((int) ide_dma_off_quietly); | |
6057 | + switch(mode) { | |
6058 | + case 0x04: | |
6059 | + if (id->dma_ultra & 0x0040) | |
6060 | + { speed = XFER_UDMA_6; break; } | |
6061 | + case 0x03: | |
6062 | + if (id->dma_ultra & 0x0020) | |
6063 | + { speed = XFER_UDMA_5; break; } | |
6064 | + case 0x02: | |
6065 | + if (id->dma_ultra & 0x0010) | |
6066 | + { speed = XFER_UDMA_4; break; } | |
6067 | + if (id->dma_ultra & 0x0008) | |
6068 | + { speed = XFER_UDMA_3; break; } | |
6069 | + case 0x01: | |
6070 | + if (id->dma_ultra & 0x0004) | |
6071 | + { speed = XFER_UDMA_2; break; } | |
6072 | + if (id->dma_ultra & 0x0002) | |
6073 | + { speed = XFER_UDMA_1; break; } | |
6074 | + if (id->dma_ultra & 0x0001) | |
6075 | + { speed = XFER_UDMA_0; break; } | |
6076 | + case 0x00: | |
6077 | + if (id->dma_mword & 0x0004) | |
6078 | + { speed = XFER_MW_DMA_2; break; } | |
6079 | + if (id->dma_mword & 0x0002) | |
6080 | + { speed = XFER_MW_DMA_1; break; } | |
6081 | + if (id->dma_mword & 0x0001) | |
6082 | + { speed = XFER_MW_DMA_0; break; } | |
6083 | + default: | |
6084 | + return ((int) ide_dma_off_quietly); | |
6085 | } | |
6086 | ||
6087 | (void) hpt3xx_tune_chipset(drive, speed); | |
6088 | ||
6089 | - rval = (int)( ((id->dma_ultra >> 11) & 7) ? ide_dma_on : | |
6090 | + return ((int) ((id->dma_ultra >> 14) & 3) ? ide_dma_on : | |
6091 | + ((id->dma_ultra >> 11) & 7) ? ide_dma_on : | |
6092 | ((id->dma_ultra >> 8) & 7) ? ide_dma_on : | |
6093 | ((id->dma_mword >> 8) & 7) ? ide_dma_on : | |
6094 | ide_dma_off_quietly); | |
6095 | - return rval; | |
6096 | } | |
6097 | ||
6098 | int hpt3xx_quirkproc (ide_drive_t *drive) | |
6099 | @@ -513,21 +946,22 @@ | |
6100 | ||
6101 | void hpt3xx_intrproc (ide_drive_t *drive) | |
6102 | { | |
6103 | - if (drive->quirk_list) { | |
6104 | - /* drives in the quirk_list may not like intr setups/cleanups */ | |
6105 | - } else { | |
6106 | - OUT_BYTE((drive)->ctl|2, HWIF(drive)->io_ports[IDE_CONTROL_OFFSET]); | |
6107 | - } | |
6108 | + if (drive->quirk_list) | |
6109 | + return; | |
6110 | + /* drives in the quirk_list may not like intr setups/cleanups */ | |
6111 | + OUT_BYTE((drive)->ctl|2, HWIF(drive)->io_ports[IDE_CONTROL_OFFSET]); | |
6112 | } | |
6113 | ||
6114 | void hpt3xx_maskproc (ide_drive_t *drive, int mask) | |
6115 | { | |
6116 | + struct pci_dev *dev = HWIF(drive)->pci_dev; | |
6117 | + | |
6118 | if (drive->quirk_list) { | |
6119 | - if (pci_rev_check_hpt3xx(HWIF(drive)->pci_dev)) { | |
6120 | + if (hpt_minimum_revision(dev,3)) { | |
6121 | byte reg5a = 0; | |
6122 | - pci_read_config_byte(HWIF(drive)->pci_dev, 0x5a, ®5a); | |
6123 | + pci_read_config_byte(dev, 0x5a, ®5a); | |
6124 | if (((reg5a & 0x10) >> 4) != mask) | |
6125 | - pci_write_config_byte(HWIF(drive)->pci_dev, 0x5a, mask ? (reg5a | 0x10) : (reg5a & ~0x10)); | |
6126 | + pci_write_config_byte(dev, 0x5a, mask ? (reg5a | 0x10) : (reg5a & ~0x10)); | |
6127 | } else { | |
6128 | if (mask) { | |
6129 | disable_irq(HWIF(drive)->irq); | |
6130 | @@ -541,18 +975,13 @@ | |
6131 | } | |
6132 | } | |
6133 | ||
6134 | -void hpt370_rw_proc (ide_drive_t *drive, ide_dma_action_t func) | |
6135 | -{ | |
6136 | - if ((func != ide_dma_write) || (func != ide_dma_read)) | |
6137 | - return; | |
6138 | - hpt370_tune_chipset(drive, drive->current_speed, (func == ide_dma_write)); | |
6139 | -} | |
6140 | - | |
6141 | static int config_drive_xfer_rate (ide_drive_t *drive) | |
6142 | { | |
6143 | struct hd_driveid *id = drive->id; | |
6144 | ide_dma_action_t dma_func = ide_dma_on; | |
6145 | ||
6146 | + drive->init_speed = 0; | |
6147 | + | |
6148 | if (id && (id->capability & 1) && HWIF(drive)->autodma) { | |
6149 | /* Consult the list of known "bad" drives */ | |
6150 | if (ide_dmaproc(ide_dma_bad_drive, drive)) { | |
6151 | @@ -561,7 +990,7 @@ | |
6152 | } | |
6153 | dma_func = ide_dma_off_quietly; | |
6154 | if (id->field_valid & 4) { | |
6155 | - if (id->dma_ultra & 0x002F) { | |
6156 | + if (id->dma_ultra & 0x007F) { | |
6157 | /* Force if Capable UltraDMA */ | |
6158 | dma_func = config_chipset_for_dma(drive); | |
6159 | if ((id->field_valid & 2) && | |
6160 | @@ -592,7 +1021,7 @@ | |
6161 | dma_func = ide_dma_off_quietly; | |
6162 | no_dma_set: | |
6163 | ||
6164 | - config_chipset_for_pio(drive); | |
6165 | + hpt3xx_tune_drive(drive, 5); | |
6166 | } | |
6167 | return HWIF(drive)->dmaproc(dma_func, drive); | |
6168 | } | |
6169 | @@ -605,45 +1034,418 @@ | |
6170 | */ | |
6171 | int hpt366_dmaproc (ide_dma_action_t func, ide_drive_t *drive) | |
6172 | { | |
6173 | + struct pci_dev *dev = HWIF(drive)->pci_dev; | |
6174 | + unsigned long dma_base = HWIF(drive)->dma_base; | |
6175 | byte reg50h = 0, reg52h = 0, reg5ah = 0, dma_stat = 0; | |
6176 | - unsigned long dma_base = HWIF(drive)->dma_base; | |
6177 | ||
6178 | switch (func) { | |
6179 | case ide_dma_check: | |
6180 | return config_drive_xfer_rate(drive); | |
6181 | - case ide_dma_test_irq: /* returns 1 if dma irq issued, 0 otherwise */ | |
6182 | - dma_stat = inb(dma_base+2); | |
6183 | - return (dma_stat & 4) == 4; /* return 1 if INTR asserted */ | |
6184 | + case ide_dma_test_irq: | |
6185 | + /* returns 1 if dma irq issued, 0 otherwise */ | |
6186 | + dma_stat = IN_BYTE(dma_base+2); | |
6187 | + /* return 1 if INTR asserted */ | |
6188 | + return (dma_stat & 4) == 4; | |
6189 | case ide_dma_lostirq: | |
6190 | - pci_read_config_byte(HWIF(drive)->pci_dev, 0x50, ®50h); | |
6191 | - pci_read_config_byte(HWIF(drive)->pci_dev, 0x52, ®52h); | |
6192 | - pci_read_config_byte(HWIF(drive)->pci_dev, 0x5a, ®5ah); | |
6193 | - printk("%s: (%s) reg50h=0x%02x, reg52h=0x%02x, reg5ah=0x%02x\n", | |
6194 | + pci_read_config_byte(dev, 0x50, ®50h); | |
6195 | + pci_read_config_byte(dev, 0x52, ®52h); | |
6196 | + pci_read_config_byte(dev, 0x5a, ®5ah); | |
6197 | + printk("%s: (%s) reg50h=0x%02x, reg52h=0x%02x," | |
6198 | + " reg5ah=0x%02x\n", | |
6199 | drive->name, | |
6200 | ide_dmafunc_verbose(func), | |
6201 | reg50h, reg52h, reg5ah); | |
6202 | if (reg5ah & 0x10) | |
6203 | - pci_write_config_byte(HWIF(drive)->pci_dev, 0x5a, reg5ah & ~0x10); | |
6204 | + pci_write_config_byte(dev, 0x5a, reg5ah & ~0x10); | |
6205 | +#if 0 | |
6206 | + /* how about we flush and reset, mmmkay? */ | |
6207 | + pci_write_config_byte(dev, 0x51, 0x1F); | |
6208 | + /* fall through to a reset */ | |
6209 | + case ide_dma_begin: | |
6210 | + case ide_dma_end: | |
6211 | + /* reset the chips state over and over.. */ | |
6212 | + pci_write_config_byte(dev, 0x51, 0x13); | |
6213 | +#endif | |
6214 | break; | |
6215 | case ide_dma_timeout: | |
6216 | default: | |
6217 | break; | |
6218 | } | |
6219 | - return ide_dmaproc(func, drive); /* use standard DMA stuff */ | |
6220 | + /* use standard DMA stuff */ | |
6221 | + return ide_dmaproc(func, drive); | |
6222 | } | |
6223 | ||
6224 | int hpt370_dmaproc (ide_dma_action_t func, ide_drive_t *drive) | |
6225 | { | |
6226 | + struct pci_dev *dev = HWIF(drive)->pci_dev; | |
6227 | + ide_hwif_t *hwif = HWIF(drive); | |
6228 | + unsigned long dma_base = hwif->dma_base; | |
6229 | + byte regstate = hwif->channel ? 0x54 : 0x50; | |
6230 | + byte reginfo = hwif->channel ? 0x56 : 0x52; | |
6231 | + byte dma_stat; | |
6232 | + | |
6233 | + switch (func) { | |
6234 | + case ide_dma_check: | |
6235 | + return config_drive_xfer_rate(drive); | |
6236 | + case ide_dma_test_irq: | |
6237 | + /* returns 1 if dma irq issued, 0 otherwise */ | |
6238 | + dma_stat = IN_BYTE(dma_base+2); | |
6239 | + /* return 1 if INTR asserted */ | |
6240 | + return (dma_stat & 4) == 4; | |
6241 | + | |
6242 | + case ide_dma_end: | |
6243 | + dma_stat = IN_BYTE(dma_base + 2); | |
6244 | + if (dma_stat & 0x01) { | |
6245 | + /* wait a little */ | |
6246 | + udelay(20); | |
6247 | + dma_stat = IN_BYTE(dma_base + 2); | |
6248 | + } | |
6249 | + if ((dma_stat & 0x01) == 0) | |
6250 | + break; | |
6251 | + | |
6252 | + func = ide_dma_timeout; | |
6253 | + /* fallthrough */ | |
6254 | + | |
6255 | + case ide_dma_timeout: | |
6256 | + case ide_dma_lostirq: | |
6257 | + pci_read_config_byte(dev, reginfo, &dma_stat); | |
6258 | + printk("%s: %d bytes in FIFO\n", drive->name, | |
6259 | + dma_stat); | |
6260 | + pci_write_config_byte(dev, regstate, 0x37); | |
6261 | + udelay(10); | |
6262 | + dma_stat = IN_BYTE(dma_base); | |
6263 | + /* stop dma */ | |
6264 | + OUT_BYTE(dma_stat & ~0x1, dma_base); | |
6265 | + dma_stat = IN_BYTE(dma_base + 2); | |
6266 | + /* clear errors */ | |
6267 | + OUT_BYTE(dma_stat | 0x6, dma_base+2); | |
6268 | + /* fallthrough */ | |
6269 | + | |
6270 | +#ifdef HPT_RESET_STATE_ENGINE | |
6271 | + case ide_dma_begin: | |
6272 | +#endif | |
6273 | + pci_write_config_byte(dev, regstate, 0x37); | |
6274 | + udelay(10); | |
6275 | + break; | |
6276 | + | |
6277 | + default: | |
6278 | + break; | |
6279 | + } | |
6280 | + /* use standard DMA stuff */ | |
6281 | + return ide_dmaproc(func, drive); | |
6282 | +} | |
6283 | + | |
6284 | +int hpt374_dmaproc (ide_dma_action_t func, ide_drive_t *drive) | |
6285 | +{ | |
6286 | + struct pci_dev *dev = HWIF(drive)->pci_dev; | |
6287 | + ide_hwif_t *hwif = HWIF(drive); | |
6288 | + unsigned long dma_base = hwif->dma_base; | |
6289 | + byte mscreg = hwif->channel ? 0x54 : 0x50; | |
6290 | +// byte reginfo = hwif->channel ? 0x56 : 0x52; | |
6291 | + byte dma_stat; | |
6292 | + | |
6293 | switch (func) { | |
6294 | case ide_dma_check: | |
6295 | return config_drive_xfer_rate(drive); | |
6296 | + case ide_dma_test_irq: | |
6297 | + /* returns 1 if dma irq issued, 0 otherwise */ | |
6298 | + dma_stat = IN_BYTE(dma_base+2); | |
6299 | +#if 0 /* do not set unless you know what you are doing */ | |
6300 | + if (dma_stat & 4) { | |
6301 | + byte stat = GET_STAT(); | |
6302 | + OUT_BYTE(dma_base+2, dma_stat & 0xE4); | |
6303 | + } | |
6304 | +#endif | |
6305 | + /* return 1 if INTR asserted */ | |
6306 | + return (dma_stat & 4) == 4; | |
6307 | + case ide_dma_end: | |
6308 | + { | |
6309 | + byte bwsr_mask = hwif->channel ? 0x02 : 0x01; | |
6310 | + byte bwsr_stat, msc_stat; | |
6311 | + pci_read_config_byte(dev, 0x6a, &bwsr_stat); | |
6312 | + pci_read_config_byte(dev, mscreg, &msc_stat); | |
6313 | + if ((bwsr_stat & bwsr_mask) == bwsr_mask) | |
6314 | + pci_write_config_byte(dev, mscreg, msc_stat|0x30); | |
6315 | + } | |
6316 | default: | |
6317 | break; | |
6318 | } | |
6319 | - return ide_dmaproc(func, drive); /* use standard DMA stuff */ | |
6320 | + /* use standard DMA stuff */ | |
6321 | + return ide_dmaproc(func, drive); | |
6322 | } | |
6323 | #endif /* CONFIG_BLK_DEV_IDEDMA */ | |
6324 | ||
6325 | +/* | |
6326 | + * Since SUN Cobalt is attempting to do this operation, I should disclose | |
6327 | + * this has been a long time ago Thu Jul 27 16:40:57 2000 was the patch date | |
6328 | + * HOTSWAP ATA Infrastructure. | |
6329 | + */ | |
6330 | +void hpt3xx_reset (ide_drive_t *drive) | |
6331 | +{ | |
6332 | +#if 0 | |
6333 | + unsigned long high_16 = pci_resource_start(HWIF(drive)->pci_dev, 4); | |
6334 | + byte reset = (HWIF(drive)->channel) ? 0x80 : 0x40; | |
6335 | + byte reg59h = 0; | |
6336 | + | |
6337 | + pci_read_config_byte(HWIF(drive)->pci_dev, 0x59, ®59h); | |
6338 | + pci_write_config_byte(HWIF(drive)->pci_dev, 0x59, reg59h|reset); | |
6339 | + pci_write_config_byte(HWIF(drive)->pci_dev, 0x59, reg59h); | |
6340 | +#endif | |
6341 | +} | |
6342 | + | |
6343 | +static int hpt3xx_tristate (ide_drive_t * drive, int state) | |
6344 | +{ | |
6345 | + ide_hwif_t *hwif = HWIF(drive); | |
6346 | + struct pci_dev *dev = hwif->pci_dev; | |
6347 | + byte reset = (hwif->channel) ? 0x80 : 0x40; | |
6348 | + byte state_reg = (hwif->channel) ? 0x57 : 0x53; | |
6349 | + byte reg59h = 0; | |
6350 | + byte regXXh = 0; | |
6351 | + | |
6352 | + if (!hwif) | |
6353 | + return -EINVAL; | |
6354 | + | |
6355 | +// hwif->bus_state = state; | |
6356 | + | |
6357 | + pci_read_config_byte(dev, 0x59, ®59h); | |
6358 | + pci_read_config_byte(dev, state_reg, ®XXh); | |
6359 | + | |
6360 | + if (state) { | |
6361 | + (void) ide_do_reset(drive); | |
6362 | + pci_write_config_byte(dev, state_reg, regXXh|0x80); | |
6363 | + pci_write_config_byte(dev, 0x59, reg59h|reset); | |
6364 | + } else { | |
6365 | + pci_write_config_byte(dev, 0x59, reg59h & ~(reset)); | |
6366 | + pci_write_config_byte(dev, state_reg, regXXh & ~(0x80)); | |
6367 | + (void) ide_do_reset(drive); | |
6368 | + } | |
6369 | + return 0; | |
6370 | +} | |
6371 | + | |
6372 | +/* | |
6373 | + * set/get power state for a drive. | |
6374 | + * turning the power off does the following things: | |
6375 | + * 1) soft-reset the drive | |
6376 | + * 2) tri-states the ide bus | |
6377 | + * | |
6378 | + * when we turn things back on, we need to re-initialize things. | |
6379 | + */ | |
6380 | +#define TRISTATE_BIT 0x8000 | |
6381 | +static int hpt370_busproc(ide_drive_t * drive, int state) | |
6382 | +{ | |
6383 | + ide_hwif_t *hwif = HWIF(drive); | |
6384 | + struct pci_dev *dev = hwif->pci_dev; | |
6385 | + byte tristate, resetmask, bus_reg; | |
6386 | + u16 tri_reg; | |
6387 | + | |
6388 | + if (!hwif) | |
6389 | + return -EINVAL; | |
6390 | + | |
6391 | + hwif->bus_state = state; | |
6392 | + | |
6393 | + if (hwif->channel) { | |
6394 | + /* secondary channel */ | |
6395 | + tristate = 0x56; | |
6396 | + resetmask = 0x80; | |
6397 | + } else { | |
6398 | + /* primary channel */ | |
6399 | + tristate = 0x52; | |
6400 | + resetmask = 0x40; | |
6401 | + } | |
6402 | + | |
6403 | + /* grab status */ | |
6404 | + pci_read_config_word(dev, tristate, &tri_reg); | |
6405 | + pci_read_config_byte(dev, 0x59, &bus_reg); | |
6406 | + | |
6407 | + /* set the state. we don't set it if we don't need to do so. | |
6408 | + * make sure that the drive knows that it has failed if it's off */ | |
6409 | + switch (state) { | |
6410 | + case BUSSTATE_ON: | |
6411 | + hwif->drives[0].failures = 0; | |
6412 | + hwif->drives[1].failures = 0; | |
6413 | + if ((bus_reg & resetmask) == 0) | |
6414 | + return 0; | |
6415 | + tri_reg &= ~TRISTATE_BIT; | |
6416 | + bus_reg &= ~resetmask; | |
6417 | + break; | |
6418 | + case BUSSTATE_OFF: | |
6419 | + hwif->drives[0].failures = hwif->drives[0].max_failures + 1; | |
6420 | + hwif->drives[1].failures = hwif->drives[1].max_failures + 1; | |
6421 | + if ((tri_reg & TRISTATE_BIT) == 0 && (bus_reg & resetmask)) | |
6422 | + return 0; | |
6423 | + tri_reg &= ~TRISTATE_BIT; | |
6424 | + bus_reg |= resetmask; | |
6425 | + break; | |
6426 | + case BUSSTATE_TRISTATE: | |
6427 | + hwif->drives[0].failures = hwif->drives[0].max_failures + 1; | |
6428 | + hwif->drives[1].failures = hwif->drives[1].max_failures + 1; | |
6429 | + if ((tri_reg & TRISTATE_BIT) && (bus_reg & resetmask)) | |
6430 | + return 0; | |
6431 | + tri_reg |= TRISTATE_BIT; | |
6432 | + bus_reg |= resetmask; | |
6433 | + break; | |
6434 | + } | |
6435 | + pci_write_config_byte(dev, 0x59, bus_reg); | |
6436 | + pci_write_config_word(dev, tristate, tri_reg); | |
6437 | + | |
6438 | + return 0; | |
6439 | +} | |
6440 | + | |
6441 | +static void __init init_hpt37x(struct pci_dev *dev) | |
6442 | +{ | |
6443 | + int adjust, i; | |
6444 | + u16 freq; | |
6445 | + u32 pll; | |
6446 | + byte reg5bh; | |
6447 | + | |
6448 | +#if 1 | |
6449 | + byte reg5ah = 0; | |
6450 | + pci_read_config_byte(dev, 0x5a, ®5ah); | |
6451 | + /* interrupt force enable */ | |
6452 | + pci_write_config_byte(dev, 0x5a, (reg5ah & ~0x10)); | |
6453 | +#endif | |
6454 | + | |
6455 | + /* | |
6456 | + * default to pci clock. make sure MA15/16 are set to output | |
6457 | + * to prevent drives having problems with 40-pin cables. | |
6458 | + */ | |
6459 | + pci_write_config_byte(dev, 0x5b, 0x23); | |
6460 | + | |
6461 | + /* | |
6462 | + * set up the PLL. we need to adjust it so that it's stable. | |
6463 | + * freq = Tpll * 192 / Tpci | |
6464 | + */ | |
6465 | + pci_read_config_word(dev, 0x78, &freq); | |
6466 | + freq &= 0x1FF; | |
6467 | + if (freq < 0x9c) { | |
6468 | + pll = F_LOW_PCI_33; | |
6469 | + if (hpt_minimum_revision(dev,8)) | |
6470 | + dev->driver_data = (void *) thirty_three_base_hpt374; | |
6471 | + else if (hpt_minimum_revision(dev,5)) | |
6472 | + dev->driver_data = (void *) thirty_three_base_hpt372; | |
6473 | + else if (hpt_minimum_revision(dev,4)) | |
6474 | + dev->driver_data = (void *) thirty_three_base_hpt370a; | |
6475 | + else | |
6476 | + dev->driver_data = (void *) thirty_three_base_hpt370; | |
6477 | + printk("HPT37X: using 33MHz PCI clock\n"); | |
6478 | + } else if (freq < 0xb0) { | |
6479 | + pll = F_LOW_PCI_40; | |
6480 | + } else if (freq < 0xc8) { | |
6481 | + pll = F_LOW_PCI_50; | |
6482 | + if (hpt_minimum_revision(dev,8)) | |
6483 | + BUG(); | |
6484 | + else if (hpt_minimum_revision(dev,5)) | |
6485 | + dev->driver_data = (void *) fifty_base_hpt372; | |
6486 | + else if (hpt_minimum_revision(dev,4)) | |
6487 | + dev->driver_data = (void *) fifty_base_hpt370a; | |
6488 | + else | |
6489 | + dev->driver_data = (void *) fifty_base_hpt370a; | |
6490 | + printk("HPT37X: using 50MHz PCI clock\n"); | |
6491 | + } else { | |
6492 | + pll = F_LOW_PCI_66; | |
6493 | + if (hpt_minimum_revision(dev,8)) | |
6494 | + BUG(); | |
6495 | + else if (hpt_minimum_revision(dev,5)) | |
6496 | + dev->driver_data = (void *) sixty_six_base_hpt372; | |
6497 | + else if (hpt_minimum_revision(dev,4)) | |
6498 | + dev->driver_data = (void *) sixty_six_base_hpt370a; | |
6499 | + else | |
6500 | + dev->driver_data = (void *) sixty_six_base_hpt370; | |
6501 | + printk("HPT37X: using 66MHz PCI clock\n"); | |
6502 | + } | |
6503 | + | |
6504 | + /* | |
6505 | + * only try the pll if we don't have a table for the clock | |
6506 | + * speed that we're running at. NOTE: the internal PLL will | |
6507 | + * result in slow reads when using a 33MHz PCI clock. we also | |
6508 | + * don't like to use the PLL because it will cause glitches | |
6509 | + * on PRST/SRST when the HPT state engine gets reset. | |
6510 | + */ | |
6511 | + if (dev->driver_data) | |
6512 | + goto init_hpt37X_done; | |
6513 | + | |
6514 | + /* | |
6515 | + * adjust PLL based upon PCI clock, enable it, and wait for | |
6516 | + * stabilization. | |
6517 | + */ | |
6518 | + adjust = 0; | |
6519 | + freq = (pll < F_LOW_PCI_50) ? 2 : 4; | |
6520 | + while (adjust++ < 6) { | |
6521 | + pci_write_config_dword(dev, 0x5c, (freq + pll) << 16 | | |
6522 | + pll | 0x100); | |
6523 | + | |
6524 | + /* wait for clock stabilization */ | |
6525 | + for (i = 0; i < 0x50000; i++) { | |
6526 | + pci_read_config_byte(dev, 0x5b, ®5bh); | |
6527 | + if (reg5bh & 0x80) { | |
6528 | + /* spin looking for the clock to destabilize */ | |
6529 | + for (i = 0; i < 0x1000; ++i) { | |
6530 | + pci_read_config_byte(dev, 0x5b, | |
6531 | + ®5bh); | |
6532 | + if ((reg5bh & 0x80) == 0) | |
6533 | + goto pll_recal; | |
6534 | + } | |
6535 | + pci_read_config_dword(dev, 0x5c, &pll); | |
6536 | + pci_write_config_dword(dev, 0x5c, | |
6537 | + pll & ~0x100); | |
6538 | + pci_write_config_byte(dev, 0x5b, 0x21); | |
6539 | + if (hpt_minimum_revision(dev,8)) | |
6540 | + BUG(); | |
6541 | + else if (hpt_minimum_revision(dev,5)) | |
6542 | + dev->driver_data = (void *) fifty_base_hpt372; | |
6543 | + else if (hpt_minimum_revision(dev,4)) | |
6544 | + dev->driver_data = (void *) fifty_base_hpt370a; | |
6545 | + else | |
6546 | + dev->driver_data = (void *) fifty_base_hpt370a; | |
6547 | + printk("HPT37X: using 50MHz internal PLL\n"); | |
6548 | + goto init_hpt37X_done; | |
6549 | + } | |
6550 | + } | |
6551 | +pll_recal: | |
6552 | + if (adjust & 1) | |
6553 | + pll -= (adjust >> 1); | |
6554 | + else | |
6555 | + pll += (adjust >> 1); | |
6556 | + } | |
6557 | + | |
6558 | +init_hpt37X_done: | |
6559 | + /* reset state engine */ | |
6560 | + pci_write_config_byte(dev, 0x50, 0x37); | |
6561 | + pci_write_config_byte(dev, 0x54, 0x37); | |
6562 | + udelay(100); | |
6563 | +} | |
6564 | + | |
6565 | +static void __init init_hpt366 (struct pci_dev *dev) | |
6566 | +{ | |
6567 | + unsigned int reg1 = 0; | |
6568 | + byte drive_fast = 0; | |
6569 | + | |
6570 | + /* | |
6571 | + * Disable the "fast interrupt" prediction. | |
6572 | + */ | |
6573 | + pci_read_config_byte(dev, 0x51, &drive_fast); | |
6574 | + if (drive_fast & 0x80) | |
6575 | + pci_write_config_byte(dev, 0x51, drive_fast & ~0x80); | |
6576 | + pci_read_config_dword(dev, 0x40, ®1); | |
6577 | + | |
6578 | + /* detect bus speed by looking at control reg timing: */ | |
6579 | + switch((reg1 >> 8) & 7) { | |
6580 | + case 5: | |
6581 | + dev->driver_data = (void *) forty_base_hpt366; | |
6582 | + break; | |
6583 | + case 9: | |
6584 | + dev->driver_data = (void *) twenty_five_base_hpt366; | |
6585 | + break; | |
6586 | + case 7: | |
6587 | + default: | |
6588 | + dev->driver_data = (void *) thirty_three_base_hpt366; | |
6589 | + break; | |
6590 | + } | |
6591 | + | |
6592 | + if (!dev->driver_data) | |
6593 | + BUG(); | |
6594 | +} | |
6595 | + | |
6596 | unsigned int __init pci_init_hpt366 (struct pci_dev *dev, const char *name) | |
6597 | { | |
6598 | byte test = 0; | |
6599 | @@ -652,14 +1454,8 @@ | |
6600 | pci_write_config_byte(dev, PCI_ROM_ADDRESS, dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE); | |
6601 | ||
6602 | pci_read_config_byte(dev, PCI_CACHE_LINE_SIZE, &test); | |
6603 | - | |
6604 | -#if 0 | |
6605 | - if (test != 0x08) | |
6606 | - pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 0x08); | |
6607 | -#else | |
6608 | if (test != (L1_CACHE_BYTES / 4)) | |
6609 | pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, (L1_CACHE_BYTES / 4)); | |
6610 | -#endif | |
6611 | ||
6612 | pci_read_config_byte(dev, PCI_LATENCY_TIMER, &test); | |
6613 | if (test != 0x78) | |
6614 | @@ -673,17 +1469,19 @@ | |
6615 | if (test != 0x08) | |
6616 | pci_write_config_byte(dev, PCI_MAX_LAT, 0x08); | |
6617 | ||
6618 | + if (hpt_minimum_revision(dev, 3)) { | |
6619 | + init_hpt37x(dev); | |
6620 | + hpt_devs[n_hpt_devs++] = dev; | |
6621 | + } else { | |
6622 | + init_hpt366(dev); | |
6623 | + hpt_devs[n_hpt_devs++] = dev; | |
6624 | + } | |
6625 | + | |
6626 | #if defined(DISPLAY_HPT366_TIMINGS) && defined(CONFIG_PROC_FS) | |
6627 | if (!hpt366_proc) { | |
6628 | hpt366_proc = 1; | |
6629 | - bmide_dev = dev; | |
6630 | - if (pci_rev_check_hpt3xx(dev)) | |
6631 | - bmide2_dev = dev; | |
6632 | hpt366_display_info = &hpt366_get_info; | |
6633 | } | |
6634 | - if ((hpt366_proc) && ((dev->devfn - bmide_dev->devfn) == 1)) { | |
6635 | - bmide2_dev = dev; | |
6636 | - } | |
6637 | #endif /* DISPLAY_HPT366_TIMINGS && CONFIG_PROC_FS */ | |
6638 | ||
6639 | return dev->irq; | |
6640 | @@ -692,66 +1490,84 @@ | |
6641 | unsigned int __init ata66_hpt366 (ide_hwif_t *hwif) | |
6642 | { | |
6643 | byte ata66 = 0; | |
6644 | + byte regmask = (hwif->channel) ? 0x01 : 0x02; | |
6645 | ||
6646 | pci_read_config_byte(hwif->pci_dev, 0x5a, &ata66); | |
6647 | #ifdef DEBUG | |
6648 | printk("HPT366: reg5ah=0x%02x ATA-%s Cable Port%d\n", | |
6649 | - ata66, (ata66 & 0x02) ? "33" : "66", | |
6650 | + ata66, (ata66 & regmask) ? "33" : "66", | |
6651 | PCI_FUNC(hwif->pci_dev->devfn)); | |
6652 | #endif /* DEBUG */ | |
6653 | - return ((ata66 & 0x02) ? 0 : 1); | |
6654 | + return ((ata66 & regmask) ? 0 : 1); | |
6655 | } | |
6656 | ||
6657 | void __init ide_init_hpt366 (ide_hwif_t *hwif) | |
6658 | { | |
6659 | - hwif->tuneproc = &hpt3xx_tune_drive; | |
6660 | - hwif->speedproc = &hpt3xx_tune_chipset; | |
6661 | - hwif->quirkproc = &hpt3xx_quirkproc; | |
6662 | - hwif->intrproc = &hpt3xx_intrproc; | |
6663 | - hwif->maskproc = &hpt3xx_maskproc; | |
6664 | - | |
6665 | - if (pci_rev2_check_hpt3xx(hwif->pci_dev)) { | |
6666 | - /* do nothing now but will split device types */ | |
6667 | - } | |
6668 | + struct pci_dev *dev = hwif->pci_dev; | |
6669 | + hwif->tuneproc = &hpt3xx_tune_drive; | |
6670 | + hwif->speedproc = &hpt3xx_tune_chipset; | |
6671 | + hwif->quirkproc = &hpt3xx_quirkproc; | |
6672 | + hwif->intrproc = &hpt3xx_intrproc; | |
6673 | + hwif->maskproc = &hpt3xx_maskproc; | |
6674 | + | |
6675 | +#ifdef HPT_SERIALIZE_IO | |
6676 | + /* serialize access to this device */ | |
6677 | + if (hwif->mate) | |
6678 | + hwif->serialized = hwif->mate->serialized = 1; | |
6679 | +#endif | |
6680 | ||
6681 | -#ifdef CONFIG_BLK_DEV_IDEDMA | |
6682 | - if (hwif->dma_base) { | |
6683 | - if (pci_rev_check_hpt3xx(hwif->pci_dev)) { | |
6684 | - byte reg5ah = 0; | |
6685 | - pci_read_config_byte(hwif->pci_dev, 0x5a, ®5ah); | |
6686 | - if (reg5ah & 0x10) /* interrupt force enable */ | |
6687 | - pci_write_config_byte(hwif->pci_dev, 0x5a, reg5ah & ~0x10); | |
6688 | - hwif->dmaproc = &hpt370_dmaproc; | |
6689 | - hwif->rwproc = &hpt370_rw_proc; | |
6690 | - } else { | |
6691 | - hwif->dmaproc = &hpt366_dmaproc; | |
6692 | - } | |
6693 | - if (!noautodma) | |
6694 | - hwif->autodma = 1; | |
6695 | - else | |
6696 | - hwif->autodma = 0; | |
6697 | - } else { | |
6698 | - hwif->autodma = 0; | |
6699 | + if (hpt_minimum_revision(dev,3)) { | |
6700 | + byte reg5ah = 0; | |
6701 | + pci_write_config_byte(dev, 0x5a, reg5ah & ~0x10); | |
6702 | + /* | |
6703 | + * set up ioctl for power status. | |
6704 | + * note: power affects both | |
6705 | + * drives on each channel | |
6706 | + */ | |
6707 | + hwif->resetproc = &hpt3xx_reset; | |
6708 | + hwif->busproc = &hpt370_busproc; | |
6709 | hwif->drives[0].autotune = 1; | |
6710 | hwif->drives[1].autotune = 1; | |
6711 | + } else if (hpt_minimum_revision(dev,2)) { | |
6712 | + hwif->resetproc = &hpt3xx_reset; | |
6713 | + hwif->busproc = &hpt3xx_tristate; | |
6714 | + } else { | |
6715 | + hwif->resetproc = &hpt3xx_reset; | |
6716 | + hwif->busproc = &hpt3xx_tristate; | |
6717 | } | |
6718 | -#else /* !CONFIG_BLK_DEV_IDEDMA */ | |
6719 | - hwif->drives[0].autotune = 1; | |
6720 | - hwif->drives[1].autotune = 1; | |
6721 | - hwif->autodma = 0; | |
6722 | + | |
6723 | + if (!hwif->dma_base) | |
6724 | + return; | |
6725 | + | |
6726 | +#ifdef CONFIG_BLK_DEV_IDEDMA | |
6727 | + if (hpt_minimum_revision(dev,8)) | |
6728 | + hwif->dmaproc = &hpt374_dmaproc; | |
6729 | + else if (hpt_minimum_revision(dev,5)) | |
6730 | + hwif->dmaproc = &hpt374_dmaproc; | |
6731 | + else if (hpt_minimum_revision(dev,3)) | |
6732 | + hwif->dmaproc = &hpt370_dmaproc; | |
6733 | + else if (hpt_minimum_revision(dev,2)) | |
6734 | + hwif->dmaproc = &hpt366_dmaproc; | |
6735 | + else | |
6736 | + hwif->dmaproc = &hpt366_dmaproc; | |
6737 | + | |
6738 | + | |
6739 | +#ifdef CONFIG_IDEDMA_AUTO | |
6740 | + if (!noautodma) | |
6741 | + hwif->autodma = 1; | |
6742 | +#endif /* CONFIG_IDEDMA_AUTO */ | |
6743 | #endif /* CONFIG_BLK_DEV_IDEDMA */ | |
6744 | } | |
6745 | ||
6746 | void __init ide_dmacapable_hpt366 (ide_hwif_t *hwif, unsigned long dmabase) | |
6747 | { | |
6748 | byte masterdma = 0, slavedma = 0; | |
6749 | - byte dma_new = 0, dma_old = inb(dmabase+2); | |
6750 | + byte dma_new = 0, dma_old = IN_BYTE(dmabase+2); | |
6751 | byte primary = hwif->channel ? 0x4b : 0x43; | |
6752 | byte secondary = hwif->channel ? 0x4f : 0x47; | |
6753 | unsigned long flags; | |
6754 | ||
6755 | - __save_flags(flags); /* local CPU only */ | |
6756 | - __cli(); /* local CPU only */ | |
6757 | + local_irq_save(flags); | |
6758 | ||
6759 | dma_new = dma_old; | |
6760 | pci_read_config_byte(hwif->pci_dev, primary, &masterdma); | |
6761 | @@ -759,9 +1575,121 @@ | |
6762 | ||
6763 | if (masterdma & 0x30) dma_new |= 0x20; | |
6764 | if (slavedma & 0x30) dma_new |= 0x40; | |
6765 | - if (dma_new != dma_old) outb(dma_new, dmabase+2); | |
6766 | + if (dma_new != dma_old) OUT_BYTE(dma_new, dmabase+2); | |
6767 | ||
6768 | - __restore_flags(flags); /* local CPU only */ | |
6769 | + local_irq_restore(flags); | |
6770 | ||
6771 | ide_setup_dma(hwif, dmabase, 8); | |
6772 | } | |
6773 | + | |
6774 | +extern void ide_setup_pci_device (struct pci_dev *dev, ide_pci_device_t *d); | |
6775 | + | |
6776 | +void __init fixup_device_hpt374 (struct pci_dev *dev, ide_pci_device_t *d) | |
6777 | +{ | |
6778 | + struct pci_dev *dev2 = NULL, *findev; | |
6779 | + ide_pci_device_t *d2; | |
6780 | + | |
6781 | + if (PCI_FUNC(dev->devfn) & 1) | |
6782 | + return; | |
6783 | + | |
6784 | + pci_for_each_dev(findev) { | |
6785 | + if ((findev->vendor == dev->vendor) && | |
6786 | + (findev->device == dev->device) && | |
6787 | + ((findev->devfn - dev->devfn) == 1) && | |
6788 | + (PCI_FUNC(findev->devfn) & 1)) { | |
6789 | + dev2 = findev; | |
6790 | + break; | |
6791 | + } | |
6792 | + } | |
6793 | + | |
6794 | + printk("%s: IDE controller on PCI bus %02x dev %02x\n", | |
6795 | + d->name, dev->bus->number, dev->devfn); | |
6796 | + ide_setup_pci_device(dev, d); | |
6797 | + if (!dev2) { | |
6798 | + return; | |
6799 | + } else { | |
6800 | + byte irq = 0, irq2 = 0; | |
6801 | + pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq); | |
6802 | + pci_read_config_byte(dev2, PCI_INTERRUPT_LINE, &irq2); | |
6803 | + if (irq != irq2) { | |
6804 | + pci_write_config_byte(dev2, PCI_INTERRUPT_LINE, irq); | |
6805 | + dev2->irq = dev->irq; | |
6806 | + printk("%s: pci-config space interrupt fixed.\n", | |
6807 | + d->name); | |
6808 | + } | |
6809 | + } | |
6810 | + d2 = d; | |
6811 | + printk("%s: IDE controller on PCI bus %02x dev %02x\n", | |
6812 | + d2->name, dev2->bus->number, dev2->devfn); | |
6813 | + ide_setup_pci_device(dev2, d2); | |
6814 | + | |
6815 | +} | |
6816 | + | |
6817 | +void __init fixup_device_hpt366 (struct pci_dev *dev, ide_pci_device_t *d) | |
6818 | +{ | |
6819 | + struct pci_dev *dev2 = NULL, *findev; | |
6820 | + ide_pci_device_t *d2; | |
6821 | + unsigned char pin1 = 0, pin2 = 0; | |
6822 | + unsigned int class_rev; | |
6823 | + char *chipset_names[] = {"HPT366", "HPT366", "HPT368", | |
6824 | + "HPT370", "HPT370A", "HPT372"}; | |
6825 | + | |
6826 | + if (PCI_FUNC(dev->devfn) & 1) | |
6827 | + return; | |
6828 | + | |
6829 | + pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); | |
6830 | + class_rev &= 0xff; | |
6831 | + | |
6832 | + strcpy(d->name, chipset_names[class_rev]); | |
6833 | + | |
6834 | + switch(class_rev) { | |
6835 | + case 5: | |
6836 | + case 4: | |
6837 | + case 3: printk("%s: IDE controller on PCI bus %02x dev %02x\n", | |
6838 | + d->name, dev->bus->number, dev->devfn); | |
6839 | + ide_setup_pci_device(dev, d); | |
6840 | + return; | |
6841 | + default: break; | |
6842 | + } | |
6843 | + | |
6844 | + pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin1); | |
6845 | + pci_for_each_dev(findev) { | |
6846 | + if ((findev->vendor == dev->vendor) && | |
6847 | + (findev->device == dev->device) && | |
6848 | + ((findev->devfn - dev->devfn) == 1) && | |
6849 | + (PCI_FUNC(findev->devfn) & 1)) { | |
6850 | + dev2 = findev; | |
6851 | + pci_read_config_byte(dev2, PCI_INTERRUPT_PIN, &pin2); | |
6852 | + hpt363_shared_pin = (pin1 != pin2) ? 1 : 0; | |
6853 | + hpt363_shared_irq = (dev->irq == dev2->irq) ? 1 : 0; | |
6854 | + if (hpt363_shared_pin && hpt363_shared_irq) { | |
6855 | + d->bootable = ON_BOARD; | |
6856 | + printk("%s: onboard version of chipset, " | |
6857 | + "pin1=%d pin2=%d\n", d->name, | |
6858 | + pin1, pin2); | |
6859 | +#if 0 | |
6860 | + /* | |
6861 | + * This is the third undocumented detection | |
6862 | + * method and is generally required for the | |
6863 | + * ABIT-BP6 boards. | |
6864 | + */ | |
6865 | + pci_write_config_byte(dev2, PCI_INTERRUPT_PIN, dev->irq); | |
6866 | + printk("PCI: %s: Fixing interrupt %d pin %d " | |
6867 | + "to ZERO \n", d->name, dev2->irq, pin2); | |
6868 | + pci_write_config_byte(dev2, PCI_INTERRUPT_LINE, 0); | |
6869 | +#endif | |
6870 | + } | |
6871 | + break; | |
6872 | + } | |
6873 | + } | |
6874 | + printk("%s: IDE controller on PCI bus %02x dev %02x\n", | |
6875 | + d->name, dev->bus->number, dev->devfn); | |
6876 | + ide_setup_pci_device(dev, d); | |
6877 | + if (!dev2) | |
6878 | + return; | |
6879 | + d2 = d; | |
6880 | + printk("%s: IDE controller on PCI bus %02x dev %02x\n", | |
6881 | + d2->name, dev2->bus->number, dev2->devfn); | |
6882 | + ide_setup_pci_device(dev2, d2); | |
6883 | +} | |
6884 | + | |
6885 | diff -Nur linux.org/drivers/ide/hptraid.c linux/drivers/ide/hptraid.c | |
6886 | --- linux.org/drivers/ide/hptraid.c Mon Oct 15 22:27:42 2001 | |
6887 | +++ linux/drivers/ide/hptraid.c Thu Jul 18 14:23:00 2002 | |
6888 | @@ -123,13 +123,8 @@ | |
6889 | return 0; | |
6890 | } | |
6891 | ||
6892 | - case BLKROSET: | |
6893 | - case BLKROGET: | |
6894 | - case BLKSSZGET: | |
6895 | - return blk_ioctl(inode->i_rdev, cmd, arg); | |
6896 | - | |
6897 | default: | |
6898 | - return -EINVAL; | |
6899 | + return blk_ioctl(inode->i_rdev, cmd, arg); | |
6900 | }; | |
6901 | ||
6902 | return 0; | |
6903 | @@ -366,7 +361,11 @@ | |
6904 | probedisk(IDE2_MAJOR, 64, device); | |
6905 | probedisk(IDE3_MAJOR, 0, device); | |
6906 | probedisk(IDE3_MAJOR, 64, device); | |
6907 | - | |
6908 | + probedisk(IDE4_MAJOR, 0, device); | |
6909 | + probedisk(IDE4_MAJOR, 64, device); | |
6910 | + probedisk(IDE5_MAJOR, 0, device); | |
6911 | + probedisk(IDE5_MAJOR, 64, device); | |
6912 | + | |
6913 | fill_cutoff(device); | |
6914 | ||
6915 | /* Initialize the gendisk structure */ | |
6916 | diff -Nur linux.org/drivers/ide/ht6560b.c linux/drivers/ide/ht6560b.c | |
6917 | --- linux.org/drivers/ide/ht6560b.c Fri Apr 14 07:54:26 2000 | |
6918 | +++ linux/drivers/ide/ht6560b.c Thu Jul 18 14:24:33 2002 | |
6919 | @@ -134,8 +134,7 @@ | |
6920 | static byte current_timing = 0; | |
6921 | byte select, timing; | |
6922 | ||
6923 | - __save_flags (flags); /* local CPU only */ | |
6924 | - __cli(); /* local CPU only */ | |
6925 | + local_irq_save(flags); | |
6926 | ||
6927 | select = HT_CONFIG(drive); | |
6928 | timing = HT_TIMING(drive); | |
6929 | @@ -145,21 +144,22 @@ | |
6930 | current_timing = timing; | |
6931 | if (drive->media != ide_disk || !drive->present) | |
6932 | select |= HT_PREFETCH_MODE; | |
6933 | - (void) inb(HT_CONFIG_PORT); | |
6934 | - (void) inb(HT_CONFIG_PORT); | |
6935 | - (void) inb(HT_CONFIG_PORT); | |
6936 | - (void) inb(HT_CONFIG_PORT); | |
6937 | - outb(select, HT_CONFIG_PORT); | |
6938 | + (void) IN_BYTE(HT_CONFIG_PORT); | |
6939 | + (void) IN_BYTE(HT_CONFIG_PORT); | |
6940 | + (void) IN_BYTE(HT_CONFIG_PORT); | |
6941 | + (void) IN_BYTE(HT_CONFIG_PORT); | |
6942 | + OUT_BYTE(select, HT_CONFIG_PORT); | |
6943 | /* | |
6944 | * Set timing for this drive: | |
6945 | */ | |
6946 | - outb(timing, IDE_SELECT_REG); | |
6947 | - (void) inb(IDE_STATUS_REG); | |
6948 | + OUT_BYTE(timing, IDE_SELECT_REG); | |
6949 | + (void) IN_BYTE(IDE_STATUS_REG); | |
6950 | #ifdef DEBUG | |
6951 | - printk("ht6560b: %s: select=%#x timing=%#x\n", drive->name, select, timing); | |
6952 | + printk("ht6560b: %s: select=%#x timing=%#x\n", | |
6953 | + drive->name, select, timing); | |
6954 | #endif | |
6955 | } | |
6956 | - __restore_flags (flags); /* local CPU only */ | |
6957 | + local_irq_restore(flags); | |
6958 | } | |
6959 | ||
6960 | /* | |
6961 | @@ -171,27 +171,27 @@ | |
6962 | int i; | |
6963 | ||
6964 | /* Autodetect ht6560b */ | |
6965 | - if ((orig_value=inb(HT_CONFIG_PORT)) == 0xff) | |
6966 | + if ((orig_value = IN_BYTE(HT_CONFIG_PORT)) == 0xff) | |
6967 | return 0; | |
6968 | ||
6969 | for (i=3;i>0;i--) { | |
6970 | - outb(0x00, HT_CONFIG_PORT); | |
6971 | - if (!( (~inb(HT_CONFIG_PORT)) & 0x3f )) { | |
6972 | - outb(orig_value, HT_CONFIG_PORT); | |
6973 | + OUT_BYTE(0x00, HT_CONFIG_PORT); | |
6974 | + if (!( (~IN_BYTE(HT_CONFIG_PORT)) & 0x3f )) { | |
6975 | + OUT_BYTE(orig_value, HT_CONFIG_PORT); | |
6976 | return 0; | |
6977 | } | |
6978 | } | |
6979 | - outb(0x00, HT_CONFIG_PORT); | |
6980 | - if ((~inb(HT_CONFIG_PORT))& 0x3f) { | |
6981 | - outb(orig_value, HT_CONFIG_PORT); | |
6982 | + OUT_BYTE(0x00, HT_CONFIG_PORT); | |
6983 | + if ((~IN_BYTE(HT_CONFIG_PORT))& 0x3f) { | |
6984 | + OUT_BYTE(orig_value, HT_CONFIG_PORT); | |
6985 | return 0; | |
6986 | } | |
6987 | /* | |
6988 | * Ht6560b autodetected | |
6989 | */ | |
6990 | - outb(HT_CONFIG_DEFAULT, HT_CONFIG_PORT); | |
6991 | - outb(HT_TIMING_DEFAULT, 0x1f6); /* IDE_SELECT_REG */ | |
6992 | - (void) inb(0x1f7); /* IDE_STATUS_REG */ | |
6993 | + OUT_BYTE(HT_CONFIG_DEFAULT, HT_CONFIG_PORT); | |
6994 | + OUT_BYTE(HT_TIMING_DEFAULT, 0x1f6); /* IDE_SELECT_REG */ | |
6995 | + (void) IN_BYTE(0x1f7); /* IDE_STATUS_REG */ | |
6996 | ||
6997 | printk("\nht6560b " HT6560B_VERSION | |
6998 | ": chipset detected and initialized" | |
6999 | @@ -257,8 +257,7 @@ | |
7000 | unsigned long flags; | |
7001 | int t = HT_PREFETCH_MODE << 8; | |
7002 | ||
7003 | - save_flags (flags); /* all CPUs */ | |
7004 | - cli(); /* all CPUs */ | |
7005 | + spin_lock_irqsave(&io_request_lock, flags); | |
7006 | ||
7007 | /* | |
7008 | * Prefetch mode and unmask irq seems to conflict | |
7009 | @@ -272,7 +271,7 @@ | |
7010 | drive->no_unmask = 0; | |
7011 | } | |
7012 | ||
7013 | - restore_flags (flags); /* all CPUs */ | |
7014 | + spin_unlock_irqrestore(&io_request_lock, flags); | |
7015 | ||
7016 | #ifdef DEBUG | |
7017 | printk("ht6560b: drive %s prefetch mode %sabled\n", drive->name, (state ? "en" : "dis")); | |
7018 | @@ -293,13 +292,12 @@ | |
7019 | ||
7020 | timing = ht_pio2timings(drive, pio); | |
7021 | ||
7022 | - save_flags (flags); /* all CPUs */ | |
7023 | - cli(); /* all CPUs */ | |
7024 | + spin_lock_irqsave(&io_request_lock, flags); | |
7025 | ||
7026 | drive->drive_data &= 0xff00; | |
7027 | drive->drive_data |= timing; | |
7028 | ||
7029 | - restore_flags (flags); /* all CPUs */ | |
7030 | + spin_unlock_irqrestore(&io_request_lock, flags); | |
7031 | ||
7032 | #ifdef DEBUG | |
7033 | printk("ht6560b: drive %s tuned to pio mode %#x timing=%#x\n", drive->name, pio, timing); | |
7034 | diff -Nur linux.org/drivers/ide/icside.c linux/drivers/ide/icside.c | |
7035 | --- linux.org/drivers/ide/icside.c Thu Oct 25 22:53:47 2001 | |
7036 | +++ linux/drivers/ide/icside.c Thu Jul 18 14:24:33 2002 | |
7037 | @@ -26,8 +26,6 @@ | |
7038 | #include <asm/ecard.h> | |
7039 | #include <asm/io.h> | |
7040 | ||
7041 | -extern char *ide_xfer_verbose (byte xfer_rate); | |
7042 | - | |
7043 | /* | |
7044 | * Maximum number of interfaces per card | |
7045 | */ | |
7046 | @@ -94,7 +92,7 @@ | |
7047 | static void icside_irqenable_arcin_v5 (struct expansion_card *ec, int irqnr) | |
7048 | { | |
7049 | unsigned int memc_port = (unsigned int)ec->irq_data; | |
7050 | - outb (0, memc_port + ICS_ARCIN_V5_INTROFFSET); | |
7051 | + OUT_BYTE(0, memc_port + ICS_ARCIN_V5_INTROFFSET); | |
7052 | } | |
7053 | ||
7054 | /* Prototype: icside_irqdisable_arcin_v5 (struct expansion_card *ec, int irqnr) | |
7055 | @@ -103,7 +101,7 @@ | |
7056 | static void icside_irqdisable_arcin_v5 (struct expansion_card *ec, int irqnr) | |
7057 | { | |
7058 | unsigned int memc_port = (unsigned int)ec->irq_data; | |
7059 | - inb (memc_port + ICS_ARCIN_V5_INTROFFSET); | |
7060 | + IN_BYTE(memc_port + ICS_ARCIN_V5_INTROFFSET); | |
7061 | } | |
7062 | ||
7063 | static const expansioncard_ops_t icside_ops_arcin_v5 = { | |
7064 | @@ -124,8 +122,8 @@ | |
7065 | { | |
7066 | unsigned int ide_base_port = (unsigned int)ec->irq_data; | |
7067 | ||
7068 | - outb (0, ide_base_port + ICS_ARCIN_V6_INTROFFSET_1); | |
7069 | - outb (0, ide_base_port + ICS_ARCIN_V6_INTROFFSET_2); | |
7070 | + OUT_BYTE(0, ide_base_port + ICS_ARCIN_V6_INTROFFSET_1); | |
7071 | + OUT_BYTE(0, ide_base_port + ICS_ARCIN_V6_INTROFFSET_2); | |
7072 | } | |
7073 | ||
7074 | /* Prototype: icside_irqdisable_arcin_v6 (struct expansion_card *ec, int irqnr) | |
7075 | @@ -135,8 +133,8 @@ | |
7076 | { | |
7077 | unsigned int ide_base_port = (unsigned int)ec->irq_data; | |
7078 | ||
7079 | - inb (ide_base_port + ICS_ARCIN_V6_INTROFFSET_1); | |
7080 | - inb (ide_base_port + ICS_ARCIN_V6_INTROFFSET_2); | |
7081 | + IN_BYTE(ide_base_port + ICS_ARCIN_V6_INTROFFSET_1); | |
7082 | + IN_BYTE(ide_base_port + ICS_ARCIN_V6_INTROFFSET_2); | |
7083 | } | |
7084 | ||
7085 | /* Prototype: icside_irqprobe(struct expansion_card *ec) | |
7086 | @@ -146,8 +144,8 @@ | |
7087 | { | |
7088 | unsigned int ide_base_port = (unsigned int)ec->irq_data; | |
7089 | ||
7090 | - return inb(ide_base_port + ICS_ARCIN_V6_INTRSTAT_1) & 1 || | |
7091 | - inb(ide_base_port + ICS_ARCIN_V6_INTRSTAT_2) & 1; | |
7092 | + return IN_BYTE(ide_base_port + ICS_ARCIN_V6_INTRSTAT_1) & 1 || | |
7093 | + IN_BYTE(ide_base_port + ICS_ARCIN_V6_INTRSTAT_2) & 1; | |
7094 | } | |
7095 | ||
7096 | static const expansioncard_ops_t icside_ops_arcin_v6 = { | |
7097 | @@ -173,10 +171,10 @@ | |
7098 | ||
7099 | addr = ecard_address (ec, ECARD_IOC, ECARD_FAST) + ICS_IDENT_OFFSET; | |
7100 | ||
7101 | - id = inb (addr) & 1; | |
7102 | - id |= (inb (addr + 1) & 1) << 1; | |
7103 | - id |= (inb (addr + 2) & 1) << 2; | |
7104 | - id |= (inb (addr + 3) & 1) << 3; | |
7105 | + id = IN_BYTE(addr) & 1; | |
7106 | + id |= (IN_BYTE(addr + 1) & 1) << 1; | |
7107 | + id |= (IN_BYTE(addr + 2) & 1) << 2; | |
7108 | + id |= (IN_BYTE(addr + 3) & 1) << 3; | |
7109 | ||
7110 | switch (id) { | |
7111 | case 0: /* A3IN */ | |
7112 | @@ -334,14 +332,14 @@ | |
7113 | rq = HWGROUP(drive)->rq; | |
7114 | for (i = rq->nr_sectors; i > 0;) { | |
7115 | i -= rq->current_nr_sectors; | |
7116 | - ide_end_request(1, HWGROUP(drive)); | |
7117 | + DRIVER(drive)->end_request(drive, 1); | |
7118 | } | |
7119 | return ide_stopped; | |
7120 | } | |
7121 | printk("%s: dma_intr: bad DMA status (dma_stat=%x)\n", | |
7122 | drive->name, dma_stat); | |
7123 | } | |
7124 | - return ide_error(drive, "dma_intr", stat); | |
7125 | + return DRIVER(drive)->error(drive, "dma_intr", stat); | |
7126 | } | |
7127 | ||
7128 | /* | |
7129 | @@ -493,6 +491,7 @@ | |
7130 | icside_dmaproc(ide_dma_action_t func, ide_drive_t *drive) | |
7131 | { | |
7132 | ide_hwif_t *hwif = HWIF(drive); | |
7133 | +// ide_task_t *args = HWGROUP(drive)->rq->special; | |
7134 | int count, reading = 0; | |
7135 | ||
7136 | switch (func) { | |
7137 | @@ -519,7 +518,7 @@ | |
7138 | /* Route the DMA signals to | |
7139 | * to the correct interface. | |
7140 | */ | |
7141 | - outb(hwif->select_data, hwif->config_data); | |
7142 | + OUT_BYTE(hwif->select_data, hwif->config_data); | |
7143 | ||
7144 | /* Select the correct timing | |
7145 | * for this drive | |
7146 | @@ -534,10 +533,27 @@ | |
7147 | if (drive->media != ide_disk) | |
7148 | return 0; | |
7149 | ||
7150 | + if (HWGROUP(drive)->handler != NULL) /* paranoia check */ | |
7151 | + BUG(); | |
7152 | ide_set_handler(drive, &icside_dmaintr, WAIT_CMD, NULL); | |
7153 | - OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, | |
7154 | - IDE_COMMAND_REG); | |
7155 | - | |
7156 | + /* | |
7157 | + * FIX ME to use only ACB ide_task_t args Struct | |
7158 | + */ | |
7159 | +#if 0 | |
7160 | + { | |
7161 | + ide_task_t *args = HWGROUP(drive)->rq->special; | |
7162 | + OUT_BYTE(args->tfRegister[IDE_COMMAND_OFFSET], IDE_COMMAND_REG); | |
7163 | + } | |
7164 | +#else | |
7165 | + if (HWGROUP(drive)->rq->cmd == IDE_DRIVE_TASKFILE) { | |
7166 | + ide_task_t *args = HWGROUP(drive)->rq->special; | |
7167 | + OUT_BYTE(args->tfRegister[IDE_COMMAND_OFFSET], IDE_COMMAND_REG); | |
7168 | + } else if (drive->addressing == 1) | |
7169 | + OUT_BYTE(reading ? WIN_READDMA_EXT : WIN_WRITEDMA_EXT, IDE_COMMAND_REG); | |
7170 | + else | |
7171 | + OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG); | |
7172 | +#endif | |
7173 | + return HWIF(drive)->dmaproc(ide_dma_begin, drive); | |
7174 | case ide_dma_begin: | |
7175 | enable_dma(hwif->hw.dma); | |
7176 | return 0; | |
7177 | @@ -549,7 +565,7 @@ | |
7178 | return get_dma_residue(hwif->hw.dma) != 0; | |
7179 | ||
7180 | case ide_dma_test_irq: | |
7181 | - return inb((unsigned long)hwif->hw.priv) & 1; | |
7182 | + return IN_BYTE((unsigned long)hwif->hw.priv) & 1; | |
7183 | ||
7184 | case ide_dma_bad_drive: | |
7185 | case ide_dma_good_drive: | |
7186 | @@ -660,7 +676,7 @@ | |
7187 | /* | |
7188 | * Be on the safe side - disable interrupts | |
7189 | */ | |
7190 | - inb(slot_port + ICS_ARCIN_V5_INTROFFSET); | |
7191 | + IN_BYTE(slot_port + ICS_ARCIN_V5_INTROFFSET); | |
7192 | ||
7193 | hwif = icside_setup(slot_port, &icside_cardinfo_v5, ec->irq); | |
7194 | ||
7195 | @@ -681,7 +697,7 @@ | |
7196 | else | |
7197 | sel = 1 << 5; | |
7198 | ||
7199 | - outb(sel, slot_port); | |
7200 | + OUT_BYTE(sel, slot_port); | |
7201 | ||
7202 | ec->irq_data = (void *)port; | |
7203 | ec->ops = (expansioncard_ops_t *)&icside_ops_arcin_v6; | |
7204 | @@ -689,8 +705,8 @@ | |
7205 | /* | |
7206 | * Be on the safe side - disable interrupts | |
7207 | */ | |
7208 | - inb(port + ICS_ARCIN_V6_INTROFFSET_1); | |
7209 | - inb(port + ICS_ARCIN_V6_INTROFFSET_2); | |
7210 | + IN_BYTE(port + ICS_ARCIN_V6_INTROFFSET_1); | |
7211 | + IN_BYTE(port + ICS_ARCIN_V6_INTROFFSET_2); | |
7212 | ||
7213 | hwif = icside_setup(port, &icside_cardinfo_v6_1, ec->irq); | |
7214 | mate = icside_setup(port, &icside_cardinfo_v6_2, ec->irq); | |
7215 | diff -Nur linux.org/drivers/ide/ide-cd.c linux/drivers/ide/ide-cd.c | |
7216 | --- linux.org/drivers/ide/ide-cd.c Mon Feb 25 20:37:57 2002 | |
7217 | +++ linux/drivers/ide/ide-cd.c Thu Jul 18 14:24:33 2002 | |
7218 | @@ -540,7 +540,113 @@ | |
7219 | } | |
7220 | ||
7221 | ||
7222 | -static void cdrom_end_request (int uptodate, ide_drive_t *drive) | |
7223 | +/* | |
7224 | + * This is our end_request replacement function. | |
7225 | + */ | |
7226 | +static int ide_cdrom_end_request (ide_drive_t *drive, int uptodate) | |
7227 | +{ | |
7228 | + struct request *rq; | |
7229 | + unsigned long flags; | |
7230 | + int ret = 1; | |
7231 | + | |
7232 | + spin_lock_irqsave(&io_request_lock, flags); | |
7233 | + rq = HWGROUP(drive)->rq; | |
7234 | + | |
7235 | + /* | |
7236 | + * decide whether to reenable DMA -- 3 is a random magic for now, | |
7237 | + * if we DMA timeout more than 3 times, just stay in PIO | |
7238 | + */ | |
7239 | + if (drive->state == DMA_PIO_RETRY && drive->retry_pio <= 3) { | |
7240 | + drive->state = 0; | |
7241 | + HWGROUP(drive)->hwif->dmaproc(ide_dma_on, drive); | |
7242 | + } | |
7243 | + | |
7244 | + if (!end_that_request_first(rq, uptodate, drive->name)) { | |
7245 | + add_blkdev_randomness(MAJOR(rq->rq_dev)); | |
7246 | + blkdev_dequeue_request(rq); | |
7247 | + HWGROUP(drive)->rq = NULL; | |
7248 | + end_that_request_last(rq); | |
7249 | + ret = 0; | |
7250 | + } | |
7251 | + spin_unlock_irqrestore(&io_request_lock, flags); | |
7252 | + return ret; | |
7253 | +} | |
7254 | + | |
7255 | +/* | |
7256 | + * Error reporting, in human readable form (luxurious, but a memory hog). | |
7257 | + */ | |
7258 | +byte ide_cdrom_dump_status (ide_drive_t *drive, const char *msg, byte stat) | |
7259 | +{ | |
7260 | + unsigned long flags; | |
7261 | + byte err = 0; | |
7262 | + | |
7263 | + local_irq_set(flags); | |
7264 | + printk("%s: %s: status=0x%02x", drive->name, msg, stat); | |
7265 | +#if FANCY_STATUS_DUMPS | |
7266 | + printk(" { "); | |
7267 | + if (stat & BUSY_STAT) | |
7268 | + printk("Busy "); | |
7269 | + else { | |
7270 | + if (stat & READY_STAT) printk("DriveReady "); | |
7271 | + if (stat & WRERR_STAT) printk("DeviceFault "); | |
7272 | + if (stat & SEEK_STAT) printk("SeekComplete "); | |
7273 | + if (stat & DRQ_STAT) printk("DataRequest "); | |
7274 | + if (stat & ECC_STAT) printk("CorrectedError "); | |
7275 | + if (stat & INDEX_STAT) printk("Index "); | |
7276 | + if (stat & ERR_STAT) printk("Error "); | |
7277 | + } | |
7278 | + printk("}"); | |
7279 | +#endif /* FANCY_STATUS_DUMPS */ | |
7280 | + printk("\n"); | |
7281 | + if ((stat & (BUSY_STAT|ERR_STAT)) == ERR_STAT) { | |
7282 | + err = GET_ERR(); | |
7283 | + printk("%s: %s: error=0x%02x", drive->name, msg, err); | |
7284 | +#if FANCY_STATUS_DUMPS | |
7285 | +#endif /* FANCY_STATUS_DUMPS */ | |
7286 | + printk("\n"); | |
7287 | + } | |
7288 | + local_irq_restore(flags); | |
7289 | + return err; | |
7290 | +} | |
7291 | + | |
7292 | +/* | |
7293 | + * ide_error() takes action based on the error returned by the drive. | |
7294 | + */ | |
7295 | +ide_startstop_t ide_cdrom_error (ide_drive_t *drive, const char *msg, byte stat) | |
7296 | +{ | |
7297 | + struct request *rq; | |
7298 | + byte err; | |
7299 | + | |
7300 | + err = ide_cdrom_dump_status(drive, msg, stat); | |
7301 | + if (drive == NULL || (rq = HWGROUP(drive)->rq) == NULL) | |
7302 | + return ide_stopped; | |
7303 | + /* retry only "normal" I/O: */ | |
7304 | + if (rq->cmd == IDE_DRIVE_CMD || rq->cmd == IDE_DRIVE_TASK) { | |
7305 | + rq->errors = 1; | |
7306 | + ide_end_drive_cmd(drive, stat, err); | |
7307 | + return ide_stopped; | |
7308 | + } | |
7309 | + | |
7310 | + if (stat & BUSY_STAT || ((stat & WRERR_STAT) && !drive->nowerr)) { | |
7311 | + /* other bits are useless when BUSY */ | |
7312 | + rq->errors |= ERROR_RESET; | |
7313 | + } | |
7314 | + if (GET_STAT() & (BUSY_STAT|DRQ_STAT)) | |
7315 | + /* force an abort */ | |
7316 | + OUT_BYTE(WIN_IDLEIMMEDIATE,IDE_COMMAND_REG); | |
7317 | + if (rq->errors >= ERROR_MAX) { | |
7318 | + DRIVER(drive)->end_request(drive, 0); | |
7319 | + } else { | |
7320 | + if ((rq->errors & ERROR_RESET) == ERROR_RESET) { | |
7321 | + ++rq->errors; | |
7322 | + return ide_do_reset(drive); | |
7323 | + } | |
7324 | + ++rq->errors; | |
7325 | + } | |
7326 | + return ide_stopped; | |
7327 | +} | |
7328 | + | |
7329 | +static void cdrom_end_request (ide_drive_t *drive, int uptodate) | |
7330 | { | |
7331 | struct request *rq = HWGROUP(drive)->rq; | |
7332 | ||
7333 | @@ -554,7 +660,7 @@ | |
7334 | if (!rq->current_nr_sectors) | |
7335 | uptodate = 1; | |
7336 | ||
7337 | - ide_end_request (uptodate, HWGROUP(drive)); | |
7338 | + ide_cdrom_end_request(drive, uptodate); | |
7339 | } | |
7340 | ||
7341 | ||
7342 | @@ -591,8 +697,8 @@ | |
7343 | ||
7344 | pc = (struct packet_command *) rq->buffer; | |
7345 | pc->stat = 1; | |
7346 | - cdrom_end_request (1, drive); | |
7347 | - *startstop = ide_error (drive, "request sense failure", stat); | |
7348 | + cdrom_end_request(drive, 1); | |
7349 | + *startstop = DRIVER(drive)->error(drive, "request sense failure", stat); | |
7350 | return 1; | |
7351 | ||
7352 | } else if (rq->cmd == PACKET_COMMAND) { | |
7353 | @@ -628,7 +734,7 @@ | |
7354 | } | |
7355 | ||
7356 | pc->stat = 1; | |
7357 | - cdrom_end_request (1, drive); | |
7358 | + cdrom_end_request(drive, 1); | |
7359 | ||
7360 | if ((stat & ERR_STAT) != 0) | |
7361 | cdrom_queue_request_sense(drive, wait, pc->sense, pc); | |
7362 | @@ -641,7 +747,7 @@ | |
7363 | ||
7364 | /* Fail the request. */ | |
7365 | printk ("%s: tray open\n", drive->name); | |
7366 | - cdrom_end_request (0, drive); | |
7367 | + cdrom_end_request(drive, 0); | |
7368 | } else if (sense_key == UNIT_ATTENTION) { | |
7369 | /* Media change. */ | |
7370 | cdrom_saw_media_change (drive); | |
7371 | @@ -650,21 +756,21 @@ | |
7372 | But be sure to give up if we've retried | |
7373 | too many times. */ | |
7374 | if (++rq->errors > ERROR_MAX) | |
7375 | - cdrom_end_request (0, drive); | |
7376 | + cdrom_end_request(drive, 0); | |
7377 | } else if (sense_key == ILLEGAL_REQUEST || | |
7378 | sense_key == DATA_PROTECT) { | |
7379 | /* No point in retrying after an illegal | |
7380 | request or data protect error.*/ | |
7381 | ide_dump_status (drive, "command error", stat); | |
7382 | - cdrom_end_request (0, drive); | |
7383 | + cdrom_end_request(drive, 0); | |
7384 | } else if ((err & ~ABRT_ERR) != 0) { | |
7385 | /* Go to the default handler | |
7386 | for other errors. */ | |
7387 | - *startstop = ide_error (drive, "cdrom_decode_status", stat); | |
7388 | + *startstop = DRIVER(drive)->error(drive, "cdrom_decode_status", stat); | |
7389 | return 1; | |
7390 | } else if ((++rq->errors > ERROR_MAX)) { | |
7391 | /* We've racked up too many retries. Abort. */ | |
7392 | - cdrom_end_request (0, drive); | |
7393 | + cdrom_end_request(drive, 0); | |
7394 | } | |
7395 | ||
7396 | /* If we got a CHECK_CONDITION status, | |
7397 | @@ -732,24 +838,26 @@ | |
7398 | } | |
7399 | ||
7400 | /* Set up the controller registers. */ | |
7401 | - OUT_BYTE (info->dma, IDE_FEATURE_REG); | |
7402 | - OUT_BYTE (0, IDE_NSECTOR_REG); | |
7403 | - OUT_BYTE (0, IDE_SECTOR_REG); | |
7404 | + OUT_BYTE(info->dma, IDE_FEATURE_REG); | |
7405 | + OUT_BYTE(0, IDE_NSECTOR_REG); | |
7406 | + OUT_BYTE(0, IDE_SECTOR_REG); | |
7407 | ||
7408 | - OUT_BYTE (xferlen & 0xff, IDE_LCYL_REG); | |
7409 | - OUT_BYTE (xferlen >> 8 , IDE_HCYL_REG); | |
7410 | + OUT_BYTE(xferlen & 0xff, IDE_LCYL_REG); | |
7411 | + OUT_BYTE(xferlen >> 8 , IDE_HCYL_REG); | |
7412 | if (IDE_CONTROL_REG) | |
7413 | - OUT_BYTE (drive->ctl, IDE_CONTROL_REG); | |
7414 | + OUT_BYTE(drive->ctl, IDE_CONTROL_REG); | |
7415 | ||
7416 | if (info->dma) | |
7417 | (void) (HWIF(drive)->dmaproc(ide_dma_begin, drive)); | |
7418 | ||
7419 | if (CDROM_CONFIG_FLAGS (drive)->drq_interrupt) { | |
7420 | + if (HWGROUP(drive)->handler != NULL) /* paranoia check */ | |
7421 | + BUG(); | |
7422 | ide_set_handler (drive, handler, WAIT_CMD, cdrom_timer_expiry); | |
7423 | - OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG); /* packet command */ | |
7424 | + OUT_BYTE(WIN_PACKETCMD, IDE_COMMAND_REG); /* packet command */ | |
7425 | return ide_started; | |
7426 | } else { | |
7427 | - OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG); /* packet command */ | |
7428 | + OUT_BYTE(WIN_PACKETCMD, IDE_COMMAND_REG); /* packet command */ | |
7429 | return (*handler) (drive); | |
7430 | } | |
7431 | } | |
7432 | @@ -786,6 +894,9 @@ | |
7433 | return startstop; | |
7434 | } | |
7435 | ||
7436 | + if (HWGROUP(drive)->handler != NULL) /* paranoia check */ | |
7437 | + BUG(); | |
7438 | + | |
7439 | /* Arm the interrupt handler. */ | |
7440 | ide_set_handler (drive, handler, timeout, cdrom_timer_expiry); | |
7441 | ||
7442 | @@ -879,7 +990,7 @@ | |
7443 | drive->name, ireason); | |
7444 | } | |
7445 | ||
7446 | - cdrom_end_request (0, drive); | |
7447 | + cdrom_end_request(drive, 0); | |
7448 | return -1; | |
7449 | } | |
7450 | ||
7451 | @@ -910,16 +1021,16 @@ | |
7452 | if (!dma_error) { | |
7453 | for (i = rq->nr_sectors; i > 0;) { | |
7454 | i -= rq->current_nr_sectors; | |
7455 | - ide_end_request(1, HWGROUP(drive)); | |
7456 | + ide_cdrom_end_request(drive, 1); | |
7457 | } | |
7458 | return ide_stopped; | |
7459 | } else | |
7460 | - return ide_error (drive, "dma error", stat); | |
7461 | + return DRIVER(drive)->error(drive, "dma error", stat); | |
7462 | } | |
7463 | ||
7464 | /* Read the interrupt reason and the transfer length. */ | |
7465 | - ireason = IN_BYTE (IDE_NSECTOR_REG); | |
7466 | - len = IN_BYTE (IDE_LCYL_REG) + 256 * IN_BYTE (IDE_HCYL_REG); | |
7467 | + ireason = IN_BYTE(IDE_NSECTOR_REG); | |
7468 | + len = IN_BYTE(IDE_LCYL_REG) + 256 * IN_BYTE(IDE_HCYL_REG); | |
7469 | ||
7470 | /* If DRQ is clear, the command has completed. */ | |
7471 | if ((stat & DRQ_STAT) == 0) { | |
7472 | @@ -928,9 +1039,9 @@ | |
7473 | if (rq->current_nr_sectors > 0) { | |
7474 | printk ("%s: cdrom_read_intr: data underrun (%ld blocks)\n", | |
7475 | drive->name, rq->current_nr_sectors); | |
7476 | - cdrom_end_request (0, drive); | |
7477 | + cdrom_end_request(drive, 0); | |
7478 | } else | |
7479 | - cdrom_end_request (1, drive); | |
7480 | + cdrom_end_request(drive, 1); | |
7481 | return ide_stopped; | |
7482 | } | |
7483 | ||
7484 | @@ -950,7 +1061,7 @@ | |
7485 | printk (" Trying to limit transfer sizes\n"); | |
7486 | CDROM_CONFIG_FLAGS (drive)->limit_nframes = 1; | |
7487 | } | |
7488 | - cdrom_end_request (0, drive); | |
7489 | + cdrom_end_request(drive, 0); | |
7490 | return ide_stopped; | |
7491 | } | |
7492 | ||
7493 | @@ -979,7 +1090,7 @@ | |
7494 | /* If we've filled the present buffer but there's another | |
7495 | chained buffer after it, move on. */ | |
7496 | if (rq->current_nr_sectors == 0 && rq->nr_sectors) | |
7497 | - cdrom_end_request (1, drive); | |
7498 | + cdrom_end_request(drive, 1); | |
7499 | ||
7500 | /* If the buffers are full, cache the rest of the data in our | |
7501 | internal buffer. */ | |
7502 | @@ -1007,8 +1118,10 @@ | |
7503 | } | |
7504 | } | |
7505 | ||
7506 | - /* Done moving data! | |
7507 | - Wait for another interrupt. */ | |
7508 | + if (HWGROUP(drive)->handler != NULL) /* paranoia check */ | |
7509 | + BUG(); | |
7510 | + | |
7511 | + /* Done moving data! Wait for another interrupt. */ | |
7512 | ide_set_handler(drive, &cdrom_read_intr, WAIT_CMD, NULL); | |
7513 | return ide_started; | |
7514 | } | |
7515 | @@ -1031,7 +1144,7 @@ | |
7516 | rq->sector >= info->sector_buffered && | |
7517 | rq->sector < info->sector_buffered + info->nsectors_buffered) { | |
7518 | if (rq->current_nr_sectors == 0) | |
7519 | - cdrom_end_request (1, drive); | |
7520 | + cdrom_end_request(drive, 1); | |
7521 | ||
7522 | memcpy (rq->buffer, | |
7523 | info->buffer + | |
7524 | @@ -1046,13 +1159,13 @@ | |
7525 | /* If we've satisfied the current request, | |
7526 | terminate it successfully. */ | |
7527 | if (rq->nr_sectors == 0) { | |
7528 | - cdrom_end_request (1, drive); | |
7529 | + cdrom_end_request(drive, 1); | |
7530 | return -1; | |
7531 | } | |
7532 | ||
7533 | /* Move on to the next buffer if needed. */ | |
7534 | if (rq->current_nr_sectors == 0) | |
7535 | - cdrom_end_request (1, drive); | |
7536 | + cdrom_end_request(drive, 1); | |
7537 | ||
7538 | /* If this condition does not hold, then the kluge i use to | |
7539 | represent the number of sectors to skip at the start of a transfer | |
7540 | @@ -1062,7 +1175,7 @@ | |
7541 | (rq->sector % SECTORS_PER_FRAME) != 0) { | |
7542 | printk ("%s: cdrom_read_from_buffer: buffer botch (%ld)\n", | |
7543 | drive->name, rq->sector); | |
7544 | - cdrom_end_request (0, drive); | |
7545 | + cdrom_end_request(drive, 0); | |
7546 | return -1; | |
7547 | } | |
7548 | ||
7549 | @@ -1101,7 +1214,7 @@ | |
7550 | (rq->sector % CD_FRAMESIZE != 0)) { | |
7551 | printk ("%s: cdrom_start_read_continuation: buffer botch (%lu)\n", | |
7552 | drive->name, rq->current_nr_sectors); | |
7553 | - cdrom_end_request (0, drive); | |
7554 | + cdrom_end_request(drive, 0); | |
7555 | return ide_stopped; | |
7556 | } | |
7557 | sector -= nskip; | |
7558 | @@ -1147,7 +1260,7 @@ | |
7559 | return startstop; | |
7560 | CDROM_CONFIG_FLAGS(drive)->seeking = 1; | |
7561 | ||
7562 | - if (retry && jiffies - info->start_seek > IDECD_SEEK_TIMER) { | |
7563 | + if (retry && time_after(jiffies, info->start_seek + IDECD_SEEK_TIMER)) { | |
7564 | if (--retry == 0) { | |
7565 | /* | |
7566 | * this condition is far too common, to bother | |
7567 | @@ -1337,7 +1450,7 @@ | |
7568 | } | |
7569 | ||
7570 | if (pc->buflen == 0) | |
7571 | - cdrom_end_request (1, drive); | |
7572 | + cdrom_end_request(drive, 1); | |
7573 | else { | |
7574 | /* Comment this out, because this always happens | |
7575 | right after a reset occurs, and it is annoying to | |
7576 | @@ -1347,7 +1460,7 @@ | |
7577 | drive->name, pc->buflen); | |
7578 | */ | |
7579 | pc->stat = 1; | |
7580 | - cdrom_end_request (1, drive); | |
7581 | + cdrom_end_request(drive, 1); | |
7582 | } | |
7583 | return ide_stopped; | |
7584 | } | |
7585 | @@ -1398,6 +1511,9 @@ | |
7586 | pc->stat = 1; | |
7587 | } | |
7588 | ||
7589 | + if (HWGROUP(drive)->handler != NULL) /* paranoia check */ | |
7590 | + BUG(); | |
7591 | + | |
7592 | /* Now we wait for another interrupt. */ | |
7593 | ide_set_handler (drive, &cdrom_pc_intr, WAIT_CMD, cdrom_timer_expiry); | |
7594 | return ide_started; | |
7595 | @@ -1522,7 +1638,7 @@ | |
7596 | drive->name, ireason); | |
7597 | } | |
7598 | ||
7599 | - cdrom_end_request(0, drive); | |
7600 | + cdrom_end_request(drive, 0); | |
7601 | return 1; | |
7602 | } | |
7603 | ||
7604 | @@ -1554,12 +1670,12 @@ | |
7605 | */ | |
7606 | if (dma) { | |
7607 | if (dma_error) | |
7608 | - return ide_error(drive, "dma error", stat); | |
7609 | + return DRIVER(drive)->error(drive, "dma error", stat); | |
7610 | ||
7611 | rq = HWGROUP(drive)->rq; | |
7612 | for (i = rq->nr_sectors; i > 0;) { | |
7613 | i -= rq->current_nr_sectors; | |
7614 | - ide_end_request(1, HWGROUP(drive)); | |
7615 | + ide_cdrom_end_request(drive, 1); | |
7616 | } | |
7617 | return ide_stopped; | |
7618 | } | |
7619 | @@ -1579,7 +1695,7 @@ | |
7620 | drive->name, rq->current_nr_sectors); | |
7621 | uptodate = 0; | |
7622 | } | |
7623 | - cdrom_end_request(uptodate, drive); | |
7624 | + cdrom_end_request(drive, uptodate); | |
7625 | return ide_stopped; | |
7626 | } | |
7627 | ||
7628 | @@ -1620,9 +1736,12 @@ | |
7629 | * current buffer complete, move on | |
7630 | */ | |
7631 | if (rq->current_nr_sectors == 0 && rq->nr_sectors) | |
7632 | - cdrom_end_request (1, drive); | |
7633 | + cdrom_end_request(drive, 1); | |
7634 | } | |
7635 | ||
7636 | + if (HWGROUP(drive)->handler != NULL) /* paranoia check */ | |
7637 | + BUG(); | |
7638 | + | |
7639 | /* re-arm handler */ | |
7640 | ide_set_handler(drive, &cdrom_write_intr, 5 * WAIT_CMD, NULL); | |
7641 | return ide_started; | |
7642 | @@ -1662,7 +1781,7 @@ | |
7643 | * writes *must* be 2kB frame aligned | |
7644 | */ | |
7645 | if ((rq->nr_sectors & 3) || (rq->sector & 3)) { | |
7646 | - cdrom_end_request(0, drive); | |
7647 | + cdrom_end_request(drive, 0); | |
7648 | return ide_stopped; | |
7649 | } | |
7650 | ||
7651 | @@ -1698,11 +1817,10 @@ | |
7652 | case WRITE: | |
7653 | case READ: { | |
7654 | if (CDROM_CONFIG_FLAGS(drive)->seeking) { | |
7655 | - unsigned long elpased = jiffies - info->start_seek; | |
7656 | int stat = GET_STAT(); | |
7657 | ||
7658 | if ((stat & SEEK_STAT) != SEEK_STAT) { | |
7659 | - if (elpased < IDECD_SEEK_TIMEOUT) { | |
7660 | + if (time_before(jiffies, info->start_seek + IDECD_SEEK_TIMEOUT)) { | |
7661 | ide_stall_queue(drive, IDECD_SEEK_TIMER); | |
7662 | return ide_stopped; | |
7663 | } | |
7664 | @@ -1728,13 +1846,13 @@ | |
7665 | } | |
7666 | ||
7667 | case RESET_DRIVE_COMMAND: { | |
7668 | - cdrom_end_request(1, drive); | |
7669 | + cdrom_end_request(drive, 1); | |
7670 | return ide_do_reset(drive); | |
7671 | } | |
7672 | ||
7673 | default: { | |
7674 | printk("ide-cd: bad cmd %d\n", rq->cmd); | |
7675 | - cdrom_end_request(0, drive); | |
7676 | + cdrom_end_request(drive, 0); | |
7677 | return ide_stopped; | |
7678 | } | |
7679 | } | |
7680 | @@ -2536,8 +2654,8 @@ | |
7681 | devinfo->dev = MKDEV (HWIF(drive)->major, minor); | |
7682 | devinfo->ops = &ide_cdrom_dops; | |
7683 | devinfo->mask = 0; | |
7684 | - *(int *)&devinfo->speed = CDROM_STATE_FLAGS (drive)->current_speed; | |
7685 | - *(int *)&devinfo->capacity = nslots; | |
7686 | + devinfo->speed = CDROM_STATE_FLAGS (drive)->current_speed; | |
7687 | + devinfo->capacity = nslots; | |
7688 | devinfo->handle = (void *) drive; | |
7689 | strcpy(devinfo->name, drive->name); | |
7690 | ||
7691 | @@ -2644,7 +2762,9 @@ | |
7692 | * but they do support reading TOC & audio datas | |
7693 | */ | |
7694 | if (strcmp (drive->id->model, "MATSHITADVD-ROM SR-8187") == 0 || | |
7695 | - strcmp (drive->id->model, "MATSHITADVD-ROM SR-8186") == 0) | |
7696 | + strcmp (drive->id->model, "MATSHITADVD-ROM SR-8186") == 0 || | |
7697 | + strcmp (drive->id->model, "MATSHITADVD-ROM SR-8176") == 0 || | |
7698 | + strcmp (drive->id->model, "MATSHITADVD-ROM SR-8174") == 0) | |
7699 | CDROM_CONFIG_FLAGS (drive)->audio_play = 1; | |
7700 | ||
7701 | #if ! STANDARD_ATAPI | |
7702 | @@ -2961,22 +3081,29 @@ | |
7703 | return 0; | |
7704 | } | |
7705 | ||
7706 | -static | |
7707 | -int ide_cdrom_reinit (ide_drive_t *drive) | |
7708 | -{ | |
7709 | - return 0; | |
7710 | -} | |
7711 | +int ide_cdrom_init(void); | |
7712 | +int ide_cdrom_reinit (ide_drive_t *drive); | |
7713 | ||
7714 | static ide_driver_t ide_cdrom_driver = { | |
7715 | name: "ide-cdrom", | |
7716 | version: IDECD_VERSION, | |
7717 | media: ide_cdrom, | |
7718 | busy: 0, | |
7719 | +#ifdef CONFIG_IDEDMA_ONLYDISK | |
7720 | + supports_dma: 0, | |
7721 | +#else | |
7722 | supports_dma: 1, | |
7723 | +#endif | |
7724 | supports_dsc_overlap: 1, | |
7725 | cleanup: ide_cdrom_cleanup, | |
7726 | + standby: NULL, | |
7727 | + suspend: NULL, | |
7728 | + resume: NULL, | |
7729 | + flushcache: NULL, | |
7730 | do_request: ide_do_rw_cdrom, | |
7731 | - end_request: NULL, | |
7732 | + end_request: ide_cdrom_end_request, | |
7733 | + sense: ide_cdrom_dump_status, | |
7734 | + error: ide_cdrom_error, | |
7735 | ioctl: ide_cdrom_ioctl, | |
7736 | open: ide_cdrom_open, | |
7737 | release: ide_cdrom_release, | |
7738 | @@ -2986,10 +3113,12 @@ | |
7739 | capacity: ide_cdrom_capacity, | |
7740 | special: NULL, | |
7741 | proc: NULL, | |
7742 | - driver_reinit: ide_cdrom_reinit, | |
7743 | + init: ide_cdrom_init, | |
7744 | + reinit: ide_cdrom_reinit, | |
7745 | + ata_prebuilder: NULL, | |
7746 | + atapi_prebuilder: NULL, | |
7747 | }; | |
7748 | ||
7749 | -int ide_cdrom_init(void); | |
7750 | static ide_module_t ide_cdrom_module = { | |
7751 | IDE_DRIVER_MODULE, | |
7752 | ide_cdrom_init, | |
7753 | @@ -3003,6 +3132,39 @@ | |
7754 | MODULE_PARM(ignore, "s"); | |
7755 | MODULE_DESCRIPTION("ATAPI CD-ROM Driver"); | |
7756 | ||
7757 | +int ide_cdrom_reinit (ide_drive_t *drive) | |
7758 | +{ | |
7759 | + struct cdrom_info *info; | |
7760 | + int failed = 0; | |
7761 | + | |
7762 | + MOD_INC_USE_COUNT; | |
7763 | + info = (struct cdrom_info *) kmalloc (sizeof (struct cdrom_info), GFP_KERNEL); | |
7764 | + if (info == NULL) { | |
7765 | + printk ("%s: Can't allocate a cdrom structure\n", drive->name); | |
7766 | + return 1; | |
7767 | + } | |
7768 | + if (ide_register_subdriver (drive, &ide_cdrom_driver, IDE_SUBDRIVER_VERSION)) { | |
7769 | + printk ("%s: Failed to register the driver with ide.c\n", drive->name); | |
7770 | + kfree (info); | |
7771 | + return 1; | |
7772 | + } | |
7773 | + memset (info, 0, sizeof (struct cdrom_info)); | |
7774 | + drive->driver_data = info; | |
7775 | + DRIVER(drive)->busy++; | |
7776 | + if (ide_cdrom_setup (drive)) { | |
7777 | + DRIVER(drive)->busy--; | |
7778 | + if (ide_cdrom_cleanup (drive)) | |
7779 | + printk ("%s: ide_cdrom_cleanup failed in ide_cdrom_init\n", drive->name); | |
7780 | + return 1; | |
7781 | + } | |
7782 | + DRIVER(drive)->busy--; | |
7783 | + failed--; | |
7784 | + | |
7785 | + ide_register_module(&ide_cdrom_module); | |
7786 | + MOD_DEC_USE_COUNT; | |
7787 | + return 0; | |
7788 | +} | |
7789 | + | |
7790 | static void __exit ide_cdrom_exit(void) | |
7791 | { | |
7792 | ide_drive_t *drive; | |
7793 | diff -Nur linux.org/drivers/ide/ide-cd.h linux/drivers/ide/ide-cd.h | |
7794 | --- linux.org/drivers/ide/ide-cd.h Thu Nov 22 20:46:58 2001 | |
7795 | +++ linux/drivers/ide/ide-cd.h Thu Jul 18 14:23:00 2002 | |
7796 | @@ -38,7 +38,9 @@ | |
7797 | /************************************************************************/ | |
7798 | ||
7799 | #define SECTOR_BITS 9 | |
7800 | +#ifndef SECTOR_SIZE | |
7801 | #define SECTOR_SIZE (1 << SECTOR_BITS) | |
7802 | +#endif | |
7803 | #define SECTORS_PER_FRAME (CD_FRAMESIZE >> SECTOR_BITS) | |
7804 | #define SECTOR_BUFFER_SIZE (CD_FRAMESIZE * 32) | |
7805 | #define SECTORS_BUFFER (SECTOR_BUFFER_SIZE >> SECTOR_BITS) | |
7806 | diff -Nur linux.org/drivers/ide/ide-cs.c linux/drivers/ide/ide-cs.c | |
7807 | --- linux.org/drivers/ide/ide-cs.c Sun Sep 30 21:26:05 2001 | |
7808 | +++ linux/drivers/ide/ide-cs.c Thu Jul 18 14:24:33 2002 | |
7809 | @@ -42,6 +42,7 @@ | |
7810 | #include <linux/ioport.h> | |
7811 | #include <linux/hdreg.h> | |
7812 | #include <linux/major.h> | |
7813 | +#include <linux/ide.h> | |
7814 | ||
7815 | #include <asm/io.h> | |
7816 | #include <asm/system.h> | |
7817 | @@ -226,6 +227,15 @@ | |
7818 | #define CFG_CHECK(fn, args...) \ | |
7819 | if (CardServices(fn, args) != 0) goto next_entry | |
7820 | ||
7821 | +int idecs_register (int arg1, int arg2, int irq) | |
7822 | +{ | |
7823 | + hw_regs_t hw; | |
7824 | + ide_init_hwif_ports(&hw, (ide_ioreg_t) arg1, (ide_ioreg_t) arg2, NULL); | |
7825 | + hw.irq = irq; | |
7826 | + hw.chipset = ide_pci; /* this enables IRQ sharing w/ PCI irqs */ | |
7827 | + return ide_register_hw(&hw, NULL); | |
7828 | +} | |
7829 | + | |
7830 | void ide_config(dev_link_t *link) | |
7831 | { | |
7832 | client_handle_t handle = link->handle; | |
7833 | @@ -329,10 +339,14 @@ | |
7834 | ||
7835 | /* retry registration in case device is still spinning up */ | |
7836 | for (i = 0; i < 10; i++) { | |
7837 | - hd = ide_register(io_base, ctl_base, link->irq.AssignedIRQ); | |
7838 | + if (ctl_base) | |
7839 | + OUT_BYTE(0x02, ctl_base); /* Set nIEN = disable device interrupts */ | |
7840 | + hd = idecs_register(io_base, ctl_base, link->irq.AssignedIRQ); | |
7841 | if (hd >= 0) break; | |
7842 | if (link->io.NumPorts1 == 0x20) { | |
7843 | - hd = ide_register(io_base+0x10, ctl_base+0x10, | |
7844 | + if (ctl_base) | |
7845 | + OUT_BYTE(0x02, ctl_base+0x10); | |
7846 | + hd = idecs_register(io_base+0x10, ctl_base+0x10, | |
7847 | link->irq.AssignedIRQ); | |
7848 | if (hd >= 0) { | |
7849 | io_base += 0x10; ctl_base += 0x10; | |
7850 | diff -Nur linux.org/drivers/ide/ide-disk.c linux/drivers/ide/ide-disk.c | |
7851 | --- linux.org/drivers/ide/ide-disk.c Fri Dec 21 18:41:54 2001 | |
7852 | +++ linux/drivers/ide/ide-disk.c Thu Jul 18 14:24:33 2002 | |
7853 | @@ -1,5 +1,9 @@ | |
7854 | /* | |
7855 | - * linux/drivers/ide/ide-disk.c Version 1.10 June 9, 2000 | |
7856 | + * linux/drivers/ide/ide-disk.c Version 1.16 April 7, 2002 | |
7857 | + * | |
7858 | + * Copyright (C) 1998-2002 Linux ATA Developemt | |
7859 | + * Andre Hedrick <andre@linux-ide.org> | |
7860 | + * | |
7861 | * | |
7862 | * Copyright (C) 1994-1998 Linus Torvalds & authors (see below) | |
7863 | */ | |
7864 | @@ -27,9 +31,16 @@ | |
7865 | * Version 1.09 added increment of rq->sector in ide_multwrite | |
7866 | * added UDMA 3/4 reporting | |
7867 | * Version 1.10 request queue changes, Ultra DMA 100 | |
7868 | + * Version 1.11 added 48-bit lba | |
7869 | + * Version 1.12 adding taskfile io access method | |
7870 | + * Version 1.13 added standby and flush-cache for notifier | |
7871 | + * Version 1.14 added acoustic-wcache | |
7872 | + * Version 1.15 convert all calls to ide_raw_taskfile | |
7873 | + * since args will return register content. | |
7874 | + * Version 1.16 added suspend-resume-checkpower | |
7875 | */ | |
7876 | ||
7877 | -#define IDEDISK_VERSION "1.10" | |
7878 | +#define IDEDISK_VERSION "1.16" | |
7879 | ||
7880 | #undef REALLY_SLOW_IO /* most systems can safely undef this */ | |
7881 | ||
7882 | @@ -59,32 +70,16 @@ | |
7883 | #define IS_PDC4030_DRIVE (0) /* auto-NULLs out pdc4030 code */ | |
7884 | #endif | |
7885 | ||
7886 | -static void idedisk_bswap_data (void *buffer, int wcount) | |
7887 | -{ | |
7888 | - u16 *p = buffer; | |
7889 | +static int driver_blocked; | |
7890 | ||
7891 | - while (wcount--) { | |
7892 | - *p = *p << 8 | *p >> 8; p++; | |
7893 | - *p = *p << 8 | *p >> 8; p++; | |
7894 | - } | |
7895 | -} | |
7896 | - | |
7897 | -static inline void idedisk_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount) | |
7898 | +static inline u32 idedisk_read_24 (ide_drive_t *drive) | |
7899 | { | |
7900 | - ide_input_data(drive, buffer, wcount); | |
7901 | - if (drive->bswap) | |
7902 | - idedisk_bswap_data(buffer, wcount); | |
7903 | + return (IN_BYTE(IDE_HCYL_REG)<<16) | | |
7904 | + (IN_BYTE(IDE_LCYL_REG)<<8) | | |
7905 | + IN_BYTE(IDE_SECTOR_REG); | |
7906 | } | |
7907 | ||
7908 | -static inline void idedisk_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount) | |
7909 | -{ | |
7910 | - if (drive->bswap) { | |
7911 | - idedisk_bswap_data(buffer, wcount); | |
7912 | - ide_output_data(drive, buffer, wcount); | |
7913 | - idedisk_bswap_data(buffer, wcount); | |
7914 | - } else | |
7915 | - ide_output_data(drive, buffer, wcount); | |
7916 | -} | |
7917 | +static int idedisk_end_request(ide_drive_t *drive, int uptodate); | |
7918 | ||
7919 | /* | |
7920 | * lba_capacity_is_ok() performs a sanity check on the claimed "lba_capacity" | |
7921 | @@ -99,6 +94,11 @@ | |
7922 | { | |
7923 | unsigned long lba_sects, chs_sects, head, tail; | |
7924 | ||
7925 | + if ((id->command_set_2 & 0x0400) && (id->cfs_enable_2 & 0x0400)) { | |
7926 | + printk("48-bit Drive: %llu \n", id->lba_capacity_2); | |
7927 | + return 1; | |
7928 | + } | |
7929 | + | |
7930 | /* | |
7931 | * The ATA spec tells large drives to return | |
7932 | * C/H/S = 16383/16/63 independent of their size. | |
7933 | @@ -131,6 +131,8 @@ | |
7934 | return 0; /* lba_capacity value may be bad */ | |
7935 | } | |
7936 | ||
7937 | +#ifndef CONFIG_IDE_TASKFILE_IO | |
7938 | + | |
7939 | /* | |
7940 | * read_intr() is the handler for disk read/multread interrupts | |
7941 | */ | |
7942 | @@ -144,9 +146,11 @@ | |
7943 | /* new way for dealing with premature shared PCI interrupts */ | |
7944 | if (!OK_STAT(stat=GET_STAT(),DATA_READY,BAD_R_STAT)) { | |
7945 | if (stat & (ERR_STAT|DRQ_STAT)) { | |
7946 | - return ide_error(drive, "read_intr", stat); | |
7947 | + return DRIVER(drive)->error(drive, "read_intr", stat); | |
7948 | } | |
7949 | /* no data yet, so wait for another interrupt */ | |
7950 | + if (HWGROUP(drive)->handler != NULL) | |
7951 | + BUG(); | |
7952 | ide_set_handler(drive, &read_intr, WAIT_CMD, NULL); | |
7953 | return ide_started; | |
7954 | } | |
7955 | @@ -160,7 +164,7 @@ | |
7956 | msect -= nsect; | |
7957 | } else | |
7958 | nsect = 1; | |
7959 | - idedisk_input_data(drive, rq->buffer, nsect * SECTOR_WORDS); | |
7960 | + taskfile_input_data(drive, rq->buffer, nsect * SECTOR_WORDS); | |
7961 | #ifdef DEBUG | |
7962 | printk("%s: read: sectors(%ld-%ld), buffer=0x%08lx, remaining=%ld\n", | |
7963 | drive->name, rq->sector, rq->sector+nsect-1, | |
7964 | @@ -171,11 +175,18 @@ | |
7965 | rq->errors = 0; | |
7966 | i = (rq->nr_sectors -= nsect); | |
7967 | if (((long)(rq->current_nr_sectors -= nsect)) <= 0) | |
7968 | - ide_end_request(1, HWGROUP(drive)); | |
7969 | + idedisk_end_request(drive, 1); | |
7970 | + /* | |
7971 | + * Another BH Page walker and DATA INTERGRITY Questioned on ERROR. | |
7972 | + * If passed back up on multimode read, BAD DATA could be ACKED | |
7973 | + * to FILE SYSTEMS above ... | |
7974 | + */ | |
7975 | if (i > 0) { | |
7976 | if (msect) | |
7977 | goto read_next; | |
7978 | - ide_set_handler (drive, &read_intr, WAIT_CMD, NULL); | |
7979 | + if (HWGROUP(drive)->handler != NULL) /* paranoia check */ | |
7980 | + BUG(); | |
7981 | + ide_set_handler(drive, &read_intr, WAIT_CMD, NULL); | |
7982 | return ide_started; | |
7983 | } | |
7984 | return ide_stopped; | |
7985 | @@ -206,17 +217,19 @@ | |
7986 | i = --rq->nr_sectors; | |
7987 | --rq->current_nr_sectors; | |
7988 | if (((long)rq->current_nr_sectors) <= 0) | |
7989 | - ide_end_request(1, hwgroup); | |
7990 | + idedisk_end_request(drive, 1); | |
7991 | if (i > 0) { | |
7992 | - idedisk_output_data (drive, rq->buffer, SECTOR_WORDS); | |
7993 | - ide_set_handler (drive, &write_intr, WAIT_CMD, NULL); | |
7994 | + taskfile_output_data(drive, rq->buffer, SECTOR_WORDS); | |
7995 | + if (HWGROUP(drive)->handler != NULL) | |
7996 | + BUG(); | |
7997 | + ide_set_handler(drive, &write_intr, WAIT_CMD, NULL); | |
7998 | return ide_started; | |
7999 | } | |
8000 | return ide_stopped; | |
8001 | } | |
8002 | return ide_stopped; /* the original code did this here (?) */ | |
8003 | } | |
8004 | - return ide_error(drive, "write_intr", stat); | |
8005 | + return DRIVER(drive)->error(drive, "write_intr", stat); | |
8006 | } | |
8007 | ||
8008 | /* | |
8009 | @@ -229,6 +242,11 @@ | |
8010 | * and IRQ context. The IRQ can happen any time after we've output the | |
8011 | * full "mcount" number of sectors, so we must make sure we update the | |
8012 | * state _before_ we output the final part of the data! | |
8013 | + * | |
8014 | + * The update and return to BH is a BLOCK Layer Fakey to get more data | |
8015 | + * to satisfy the hardware atomic segment. If the hardware atomic segment | |
8016 | + * is shorter or smaller than the BH segment then we should be OKAY. | |
8017 | + * This is only valid if we can rewind the rq->current_nr_sectors counter. | |
8018 | */ | |
8019 | int ide_multwrite (ide_drive_t *drive, unsigned int mcount) | |
8020 | { | |
8021 | @@ -267,7 +285,7 @@ | |
8022 | * Ok, we're all setup for the interrupt | |
8023 | * re-entering us on the last transfer. | |
8024 | */ | |
8025 | - idedisk_output_data(drive, buffer, nsect<<7); | |
8026 | + taskfile_output_data(drive, buffer, nsect<<7); | |
8027 | } while (mcount); | |
8028 | ||
8029 | return 0; | |
8030 | @@ -292,7 +310,9 @@ | |
8031 | if (rq->nr_sectors) { | |
8032 | if (ide_multwrite(drive, drive->mult_count)) | |
8033 | return ide_stopped; | |
8034 | - ide_set_handler (drive, &multwrite_intr, WAIT_CMD, NULL); | |
8035 | + if (HWGROUP(drive)->handler != NULL) | |
8036 | + BUG(); | |
8037 | + ide_set_handler(drive, &multwrite_intr, WAIT_CMD, NULL); | |
8038 | return ide_started; | |
8039 | } | |
8040 | } else { | |
8041 | @@ -304,62 +324,186 @@ | |
8042 | rq = hwgroup->rq; | |
8043 | for (i = rq->nr_sectors; i > 0;){ | |
8044 | i -= rq->current_nr_sectors; | |
8045 | - ide_end_request(1, hwgroup); | |
8046 | + idedisk_end_request(drive, 1); | |
8047 | } | |
8048 | return ide_stopped; | |
8049 | } | |
8050 | } | |
8051 | return ide_stopped; /* the original code did this here (?) */ | |
8052 | } | |
8053 | - return ide_error(drive, "multwrite_intr", stat); | |
8054 | + return DRIVER(drive)->error(drive, "multwrite_intr", stat); | |
8055 | } | |
8056 | +#endif /* CONFIG_IDE_TASKFILE_IO */ | |
8057 | + | |
8058 | +#ifdef CONFIG_IDE_TASKFILE_IO | |
8059 | + | |
8060 | +static ide_startstop_t chs_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block); | |
8061 | +static ide_startstop_t lba_28_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block); | |
8062 | +static ide_startstop_t lba_48_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long long block); | |
8063 | ||
8064 | /* | |
8065 | - * set_multmode_intr() is invoked on completion of a WIN_SETMULT cmd. | |
8066 | + * do_rw_disk() issues READ and WRITE commands to a disk, | |
8067 | + * using LBA if supported, or CHS otherwise, to address sectors. | |
8068 | + * It also takes care of issuing special DRIVE_CMDs. | |
8069 | */ | |
8070 | -static ide_startstop_t set_multmode_intr (ide_drive_t *drive) | |
8071 | +static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block) | |
8072 | { | |
8073 | - byte stat; | |
8074 | + if (rq->cmd == READ) | |
8075 | + goto good_command; | |
8076 | + if (rq->cmd == WRITE) | |
8077 | + goto good_command; | |
8078 | ||
8079 | - if (OK_STAT(stat=GET_STAT(),READY_STAT,BAD_STAT)) { | |
8080 | - drive->mult_count = drive->mult_req; | |
8081 | - } else { | |
8082 | - drive->mult_req = drive->mult_count = 0; | |
8083 | - drive->special.b.recalibrate = 1; | |
8084 | - (void) ide_dump_status(drive, "set_multmode", stat); | |
8085 | - } | |
8086 | + printk(KERN_ERR "%s: bad command: %d\n", drive->name, rq->cmd); | |
8087 | + idedisk_end_request(drive, 0); | |
8088 | return ide_stopped; | |
8089 | + | |
8090 | +good_command: | |
8091 | + | |
8092 | +#ifdef CONFIG_BLK_DEV_PDC4030 | |
8093 | + if (IS_PDC4030_DRIVE) { | |
8094 | + extern ide_startstop_t promise_rw_disk(ide_drive_t *, struct request *, unsigned long); | |
8095 | + return promise_rw_disk(drive, rq, block); | |
8096 | + } | |
8097 | +#endif /* CONFIG_BLK_DEV_PDC4030 */ | |
8098 | + | |
8099 | + if ((drive->id->cfs_enable_2 & 0x0400) && | |
8100 | + (drive->addressing == 1)) /* 48-bit LBA */ | |
8101 | + return lba_48_rw_disk(drive, rq, (unsigned long long) block); | |
8102 | + if (drive->select.b.lba) /* 28-bit LBA */ | |
8103 | + return lba_28_rw_disk(drive, rq, (unsigned long) block); | |
8104 | + | |
8105 | + /* 28-bit CHS : DIE DIE DIE piece of legacy crap!!! */ | |
8106 | + return chs_rw_disk(drive, rq, (unsigned long) block); | |
8107 | } | |
8108 | ||
8109 | -/* | |
8110 | - * set_geometry_intr() is invoked on completion of a WIN_SPECIFY cmd. | |
8111 | - */ | |
8112 | -static ide_startstop_t set_geometry_intr (ide_drive_t *drive) | |
8113 | +static task_ioreg_t get_command (ide_drive_t *drive, int cmd) | |
8114 | { | |
8115 | - byte stat; | |
8116 | + int lba48bit = (drive->id->cfs_enable_2 & 0x0400) ? 1 : 0; | |
8117 | ||
8118 | - if (OK_STAT(stat=GET_STAT(),READY_STAT,BAD_STAT)) | |
8119 | - return ide_stopped; | |
8120 | +#if 1 | |
8121 | + lba48bit = (drive->addressing == 1) ? 1 : 0; | |
8122 | +#endif | |
8123 | ||
8124 | - if (stat & (ERR_STAT|DRQ_STAT)) | |
8125 | - return ide_error(drive, "set_geometry_intr", stat); | |
8126 | + if ((cmd == READ) && (drive->using_dma)) | |
8127 | + return (lba48bit) ? WIN_READDMA_EXT : WIN_READDMA; | |
8128 | + else if ((cmd == READ) && (drive->mult_count)) | |
8129 | + return (lba48bit) ? WIN_MULTREAD_EXT : WIN_MULTREAD; | |
8130 | + else if (cmd == READ) | |
8131 | + return (lba48bit) ? WIN_READ_EXT : WIN_READ; | |
8132 | + else if ((cmd == WRITE) && (drive->using_dma)) | |
8133 | + return (lba48bit) ? WIN_WRITEDMA_EXT : WIN_WRITEDMA; | |
8134 | + else if ((cmd == WRITE) && (drive->mult_count)) | |
8135 | + return (lba48bit) ? WIN_MULTWRITE_EXT : WIN_MULTWRITE; | |
8136 | + else if (cmd == WRITE) | |
8137 | + return (lba48bit) ? WIN_WRITE_EXT : WIN_WRITE; | |
8138 | + else | |
8139 | + return WIN_NOP; | |
8140 | +} | |
8141 | ||
8142 | - ide_set_handler(drive, &set_geometry_intr, WAIT_CMD, NULL); | |
8143 | - return ide_started; | |
8144 | +static ide_startstop_t chs_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block) | |
8145 | +{ | |
8146 | + ide_task_t args; | |
8147 | + int sectors; | |
8148 | + task_ioreg_t command = get_command(drive, rq->cmd); | |
8149 | + unsigned int track = (block / drive->sect); | |
8150 | + unsigned int sect = (block % drive->sect) + 1; | |
8151 | + unsigned int head = (track % drive->head); | |
8152 | + unsigned int cyl = (track / drive->head); | |
8153 | + | |
8154 | +#ifdef DEBUG | |
8155 | + printk("%s: %sing: ", drive->name, (rq->cmd==READ) ? "read" : "writ"); | |
8156 | + printk("CHS=%d/%d/%d, ", cyl, head, sect); | |
8157 | + printk("sectors=%ld, ", rq->nr_sectors); | |
8158 | + printk("buffer=0x%08lx\n", (unsigned long) rq->buffer); | |
8159 | +#endif | |
8160 | + | |
8161 | + memset(&args, 0, sizeof(ide_task_t)); | |
8162 | + | |
8163 | + sectors = (rq->nr_sectors == 256) ? 0x00 : rq->nr_sectors; | |
8164 | + args.tfRegister[IDE_NSECTOR_OFFSET] = sectors; | |
8165 | + args.tfRegister[IDE_SECTOR_OFFSET] = sect; | |
8166 | + args.tfRegister[IDE_LCYL_OFFSET] = cyl; | |
8167 | + args.tfRegister[IDE_HCYL_OFFSET] = (cyl>>8); | |
8168 | + args.tfRegister[IDE_SELECT_OFFSET] = head; | |
8169 | + args.tfRegister[IDE_SELECT_OFFSET] |= drive->select.all; | |
8170 | + args.tfRegister[IDE_COMMAND_OFFSET] = command; | |
8171 | + args.command_type = ide_cmd_type_parser(&args); | |
8172 | + args.rq = (struct request *) rq; | |
8173 | + rq->special = (ide_task_t *)&args; | |
8174 | + return do_rw_taskfile(drive, &args); | |
8175 | +} | |
8176 | + | |
8177 | +static ide_startstop_t lba_28_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block) | |
8178 | +{ | |
8179 | + ide_task_t args; | |
8180 | + int sectors; | |
8181 | + task_ioreg_t command = get_command(drive, rq->cmd); | |
8182 | + | |
8183 | +#ifdef DEBUG | |
8184 | + printk("%s: %sing: ", drive->name, (rq->cmd==READ) ? "read" : "writ"); | |
8185 | + printk("LBAsect=%lld, ", block); | |
8186 | + printk("sectors=%ld, ", rq->nr_sectors); | |
8187 | + printk("buffer=0x%08lx\n", (unsigned long) rq->buffer); | |
8188 | +#endif | |
8189 | + | |
8190 | + memset(&args, 0, sizeof(ide_task_t)); | |
8191 | + | |
8192 | + sectors = (rq->nr_sectors == 256) ? 0x00 : rq->nr_sectors; | |
8193 | + args.tfRegister[IDE_NSECTOR_OFFSET] = sectors; | |
8194 | + args.tfRegister[IDE_SECTOR_OFFSET] = block; | |
8195 | + args.tfRegister[IDE_LCYL_OFFSET] = (block>>=8); | |
8196 | + args.tfRegister[IDE_HCYL_OFFSET] = (block>>=8); | |
8197 | + args.tfRegister[IDE_SELECT_OFFSET] = ((block>>8)&0x0f); | |
8198 | + args.tfRegister[IDE_SELECT_OFFSET] |= drive->select.all; | |
8199 | + args.tfRegister[IDE_COMMAND_OFFSET] = command; | |
8200 | + args.command_type = ide_cmd_type_parser(&args); | |
8201 | + args.rq = (struct request *) rq; | |
8202 | + rq->special = (ide_task_t *)&args; | |
8203 | + return do_rw_taskfile(drive, &args); | |
8204 | } | |
8205 | ||
8206 | /* | |
8207 | - * recal_intr() is invoked on completion of a WIN_RESTORE (recalibrate) cmd. | |
8208 | + * 268435455 == 137439 MB or 28bit limit | |
8209 | + * 320173056 == 163929 MB or 48bit addressing | |
8210 | + * 1073741822 == 549756 MB or 48bit addressing fake drive | |
8211 | */ | |
8212 | -static ide_startstop_t recal_intr (ide_drive_t *drive) | |
8213 | + | |
8214 | +static ide_startstop_t lba_48_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long long block) | |
8215 | { | |
8216 | - byte stat = GET_STAT(); | |
8217 | + ide_task_t args; | |
8218 | + int sectors; | |
8219 | + task_ioreg_t command = get_command(drive, rq->cmd); | |
8220 | ||
8221 | - if (!OK_STAT(stat,READY_STAT,BAD_STAT)) | |
8222 | - return ide_error(drive, "recal_intr", stat); | |
8223 | - return ide_stopped; | |
8224 | +#ifdef DEBUG | |
8225 | + printk("%s: %sing: ", drive->name, (rq->cmd==READ) ? "read" : "writ"); | |
8226 | + printk("LBAsect=%lld, ", block); | |
8227 | + printk("sectors=%ld, ", rq->nr_sectors); | |
8228 | + printk("buffer=0x%08lx\n", (unsigned long) rq->buffer); | |
8229 | +#endif | |
8230 | + | |
8231 | + memset(&args, 0, sizeof(ide_task_t)); | |
8232 | + | |
8233 | + sectors = (rq->nr_sectors == 65536) ? 0 : rq->nr_sectors; | |
8234 | + args.tfRegister[IDE_NSECTOR_OFFSET] = sectors; | |
8235 | + args.tfRegister[IDE_SECTOR_OFFSET] = block; /* low lba */ | |
8236 | + args.tfRegister[IDE_LCYL_OFFSET] = (block>>=8); /* mid lba */ | |
8237 | + args.tfRegister[IDE_HCYL_OFFSET] = (block>>=8); /* hi lba */ | |
8238 | + args.tfRegister[IDE_SELECT_OFFSET] = drive->select.all; | |
8239 | + args.tfRegister[IDE_COMMAND_OFFSET] = command; | |
8240 | + args.hobRegister[IDE_NSECTOR_OFFSET_HOB]= sectors >> 8; | |
8241 | + args.hobRegister[IDE_SECTOR_OFFSET_HOB] = (block>>=8); /* low lba */ | |
8242 | + args.hobRegister[IDE_LCYL_OFFSET_HOB] = (block>>=8); /* mid lba */ | |
8243 | + args.hobRegister[IDE_HCYL_OFFSET_HOB] = (block>>=8); /* hi lba */ | |
8244 | + args.hobRegister[IDE_SELECT_OFFSET_HOB] = drive->select.all; | |
8245 | + args.hobRegister[IDE_CONTROL_OFFSET_HOB]= (drive->ctl|0x80); | |
8246 | + args.command_type = ide_cmd_type_parser(&args); | |
8247 | + args.rq = (struct request *) rq; | |
8248 | + rq->special = (ide_task_t *)&args; | |
8249 | + return do_rw_taskfile(drive, &args); | |
8250 | } | |
8251 | ||
8252 | +#else /* !CONFIG_IDE_TASKFILE_IO */ | |
8253 | + | |
8254 | /* | |
8255 | * do_rw_disk() issues READ and WRITE commands to a disk, | |
8256 | * using LBA if supported, or CHS otherwise, to address sectors. | |
8257 | @@ -367,24 +511,75 @@ | |
8258 | */ | |
8259 | static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block) | |
8260 | { | |
8261 | + if (driver_blocked) | |
8262 | + panic("Request while ide driver is blocked?"); | |
8263 | if (IDE_CONTROL_REG) | |
8264 | OUT_BYTE(drive->ctl,IDE_CONTROL_REG); | |
8265 | - OUT_BYTE(0x00, IDE_FEATURE_REG); | |
8266 | - OUT_BYTE(rq->nr_sectors,IDE_NSECTOR_REG); | |
8267 | + | |
8268 | #ifdef CONFIG_BLK_DEV_PDC4030 | |
8269 | if (drive->select.b.lba || IS_PDC4030_DRIVE) { | |
8270 | #else /* !CONFIG_BLK_DEV_PDC4030 */ | |
8271 | if (drive->select.b.lba) { | |
8272 | #endif /* CONFIG_BLK_DEV_PDC4030 */ | |
8273 | + | |
8274 | + if ((drive->id->cfs_enable_2 & 0x0400) && | |
8275 | + (drive->addressing == 1)) { | |
8276 | + task_ioreg_t tasklets[10]; | |
8277 | + | |
8278 | + tasklets[0] = 0; | |
8279 | + tasklets[1] = 0; | |
8280 | + tasklets[2] = rq->nr_sectors; | |
8281 | + tasklets[3] = (rq->nr_sectors>>8); | |
8282 | + if (rq->nr_sectors == 65536) { | |
8283 | + tasklets[2] = 0x00; | |
8284 | + tasklets[3] = 0x00; | |
8285 | + } | |
8286 | + tasklets[4] = (task_ioreg_t) block; | |
8287 | + tasklets[5] = (task_ioreg_t) (block>>8); | |
8288 | + tasklets[6] = (task_ioreg_t) (block>>16); | |
8289 | + tasklets[7] = (task_ioreg_t) (block>>24); | |
8290 | + tasklets[8] = (task_ioreg_t) 0; | |
8291 | + tasklets[9] = (task_ioreg_t) 0; | |
8292 | +// tasklets[8] = (task_ioreg_t) (block>>32); | |
8293 | +// tasklets[9] = (task_ioreg_t) (block>>40); | |
8294 | #ifdef DEBUG | |
8295 | - printk("%s: %sing: LBAsect=%ld, sectors=%ld, buffer=0x%08lx\n", | |
8296 | - drive->name, (rq->cmd==READ)?"read":"writ", | |
8297 | - block, rq->nr_sectors, (unsigned long) rq->buffer); | |
8298 | -#endif | |
8299 | - OUT_BYTE(block,IDE_SECTOR_REG); | |
8300 | - OUT_BYTE(block>>=8,IDE_LCYL_REG); | |
8301 | - OUT_BYTE(block>>=8,IDE_HCYL_REG); | |
8302 | - OUT_BYTE(((block>>8)&0x0f)|drive->select.all,IDE_SELECT_REG); | |
8303 | + printk("%s: %sing: LBAsect=%lu, sectors=%ld, buffer=0x%08lx, LBAsect=0x%012lx\n", | |
8304 | + drive->name, | |
8305 | + (rq->cmd==READ)?"read":"writ", | |
8306 | + block, | |
8307 | + rq->nr_sectors, | |
8308 | + (unsigned long) rq->buffer, | |
8309 | + block); | |
8310 | + printk("%s: 0x%02x%02x 0x%02x%02x%02x%02x%02x%02x\n", | |
8311 | + drive->name, tasklets[3], tasklets[2], | |
8312 | + tasklets[9], tasklets[8], tasklets[7], | |
8313 | + tasklets[6], tasklets[5], tasklets[4]); | |
8314 | +#endif | |
8315 | + OUT_BYTE(tasklets[1], IDE_FEATURE_REG); | |
8316 | + OUT_BYTE(tasklets[3], IDE_NSECTOR_REG); | |
8317 | + OUT_BYTE(tasklets[7], IDE_SECTOR_REG); | |
8318 | + OUT_BYTE(tasklets[8], IDE_LCYL_REG); | |
8319 | + OUT_BYTE(tasklets[9], IDE_HCYL_REG); | |
8320 | + | |
8321 | + OUT_BYTE(tasklets[0], IDE_FEATURE_REG); | |
8322 | + OUT_BYTE(tasklets[2], IDE_NSECTOR_REG); | |
8323 | + OUT_BYTE(tasklets[4], IDE_SECTOR_REG); | |
8324 | + OUT_BYTE(tasklets[5], IDE_LCYL_REG); | |
8325 | + OUT_BYTE(tasklets[6], IDE_HCYL_REG); | |
8326 | + OUT_BYTE(0x00|drive->select.all,IDE_SELECT_REG); | |
8327 | + } else { | |
8328 | +#ifdef DEBUG | |
8329 | + printk("%s: %sing: LBAsect=%ld, sectors=%ld, buffer=0x%08lx\n", | |
8330 | + drive->name, (rq->cmd==READ)?"read":"writ", | |
8331 | + block, rq->nr_sectors, (unsigned long) rq->buffer); | |
8332 | +#endif | |
8333 | + OUT_BYTE(0x00, IDE_FEATURE_REG); | |
8334 | + OUT_BYTE((rq->nr_sectors==256)?0x00:rq->nr_sectors,IDE_NSECTOR_REG); | |
8335 | + OUT_BYTE(block,IDE_SECTOR_REG); | |
8336 | + OUT_BYTE(block>>=8,IDE_LCYL_REG); | |
8337 | + OUT_BYTE(block>>=8,IDE_HCYL_REG); | |
8338 | + OUT_BYTE(((block>>8)&0x0f)|drive->select.all,IDE_SELECT_REG); | |
8339 | + } | |
8340 | } else { | |
8341 | unsigned int sect,head,cyl,track; | |
8342 | track = block / drive->sect; | |
8343 | @@ -392,6 +587,9 @@ | |
8344 | OUT_BYTE(sect,IDE_SECTOR_REG); | |
8345 | head = track % drive->head; | |
8346 | cyl = track / drive->head; | |
8347 | + | |
8348 | + OUT_BYTE(0x00, IDE_FEATURE_REG); | |
8349 | + OUT_BYTE((rq->nr_sectors==256)?0x00:rq->nr_sectors,IDE_NSECTOR_REG); | |
8350 | OUT_BYTE(cyl,IDE_LCYL_REG); | |
8351 | OUT_BYTE(cyl>>8,IDE_HCYL_REG); | |
8352 | OUT_BYTE(head|drive->select.all,IDE_SELECT_REG); | |
8353 | @@ -412,8 +610,15 @@ | |
8354 | if (drive->using_dma && !(HWIF(drive)->dmaproc(ide_dma_read, drive))) | |
8355 | return ide_started; | |
8356 | #endif /* CONFIG_BLK_DEV_IDEDMA */ | |
8357 | + if (HWGROUP(drive)->handler != NULL) | |
8358 | + BUG(); | |
8359 | ide_set_handler(drive, &read_intr, WAIT_CMD, NULL); | |
8360 | - OUT_BYTE(drive->mult_count ? WIN_MULTREAD : WIN_READ, IDE_COMMAND_REG); | |
8361 | + if ((drive->id->cfs_enable_2 & 0x0400) && | |
8362 | + (drive->addressing == 1)) { | |
8363 | + OUT_BYTE(drive->mult_count ? WIN_MULTREAD_EXT : WIN_READ_EXT, IDE_COMMAND_REG); | |
8364 | + } else { | |
8365 | + OUT_BYTE(drive->mult_count ? WIN_MULTREAD : WIN_READ, IDE_COMMAND_REG); | |
8366 | + } | |
8367 | return ide_started; | |
8368 | } | |
8369 | if (rq->cmd == WRITE) { | |
8370 | @@ -422,27 +627,36 @@ | |
8371 | if (drive->using_dma && !(HWIF(drive)->dmaproc(ide_dma_write, drive))) | |
8372 | return ide_started; | |
8373 | #endif /* CONFIG_BLK_DEV_IDEDMA */ | |
8374 | - OUT_BYTE(drive->mult_count ? WIN_MULTWRITE : WIN_WRITE, IDE_COMMAND_REG); | |
8375 | + if ((drive->id->cfs_enable_2 & 0x0400) && | |
8376 | + (drive->addressing == 1)) { | |
8377 | + OUT_BYTE(drive->mult_count ? WIN_MULTWRITE_EXT : WIN_WRITE_EXT, IDE_COMMAND_REG); | |
8378 | + } else { | |
8379 | + OUT_BYTE(drive->mult_count ? WIN_MULTWRITE : WIN_WRITE, IDE_COMMAND_REG); | |
8380 | + } | |
8381 | if (ide_wait_stat(&startstop, drive, DATA_READY, drive->bad_wstat, WAIT_DRQ)) { | |
8382 | printk(KERN_ERR "%s: no DRQ after issuing %s\n", drive->name, | |
8383 | drive->mult_count ? "MULTWRITE" : "WRITE"); | |
8384 | return startstop; | |
8385 | } | |
8386 | if (!drive->unmask) | |
8387 | - __cli(); /* local CPU only */ | |
8388 | + local_irq_disable(); | |
8389 | if (drive->mult_count) { | |
8390 | ide_hwgroup_t *hwgroup = HWGROUP(drive); | |
8391 | - /* | |
8392 | - * Ugh.. this part looks ugly because we MUST set up | |
8393 | - * the interrupt handler before outputting the first block | |
8394 | - * of data to be written. If we hit an error (corrupted buffer list) | |
8395 | - * in ide_multwrite(), then we need to remove the handler/timer | |
8396 | - * before returning. Fortunately, this NEVER happens (right?). | |
8397 | - * | |
8398 | - * Except when you get an error it seems... | |
8399 | - */ | |
8400 | + /* | |
8401 | + * Ugh.. this part looks ugly because we MUST set up | |
8402 | + * the interrupt handler before outputting the first block | |
8403 | + * of data to be written. If we hit an error (corrupted buffer list) | |
8404 | + * in ide_multwrite(), then we need to remove the handler/timer | |
8405 | + * before returning. Fortunately, this NEVER happens (right?). | |
8406 | + * | |
8407 | + * Except when you get an error it seems... | |
8408 | + * | |
8409 | + * MAJOR DATA INTEGRITY BUG !!! only if we error | |
8410 | + */ | |
8411 | hwgroup->wrq = *rq; /* scratchpad */ | |
8412 | - ide_set_handler (drive, &multwrite_intr, WAIT_CMD, NULL); | |
8413 | + if (HWGROUP(drive)->handler != NULL) | |
8414 | + BUG(); | |
8415 | + ide_set_handler(drive, &multwrite_intr, WAIT_CMD, NULL); | |
8416 | if (ide_multwrite(drive, drive->mult_count)) { | |
8417 | unsigned long flags; | |
8418 | spin_lock_irqsave(&io_request_lock, flags); | |
8419 | @@ -452,39 +666,57 @@ | |
8420 | return ide_stopped; | |
8421 | } | |
8422 | } else { | |
8423 | - ide_set_handler (drive, &write_intr, WAIT_CMD, NULL); | |
8424 | - idedisk_output_data(drive, rq->buffer, SECTOR_WORDS); | |
8425 | + if (HWGROUP(drive)->handler != NULL) | |
8426 | + BUG(); | |
8427 | + ide_set_handler(drive, &write_intr, WAIT_CMD, NULL); | |
8428 | + taskfile_output_data(drive, rq->buffer, SECTOR_WORDS); | |
8429 | } | |
8430 | return ide_started; | |
8431 | } | |
8432 | printk(KERN_ERR "%s: bad command: %d\n", drive->name, rq->cmd); | |
8433 | - ide_end_request(0, HWGROUP(drive)); | |
8434 | + idedisk_end_request(drive, 0); | |
8435 | return ide_stopped; | |
8436 | } | |
8437 | ||
8438 | +#endif /* CONFIG_IDE_TASKFILE_IO */ | |
8439 | + | |
8440 | static int idedisk_open (struct inode *inode, struct file *filp, ide_drive_t *drive) | |
8441 | { | |
8442 | MOD_INC_USE_COUNT; | |
8443 | if (drive->removable && drive->usage == 1) { | |
8444 | + ide_task_t args; | |
8445 | + memset(&args, 0, sizeof(ide_task_t)); | |
8446 | + args.tfRegister[IDE_COMMAND_OFFSET] = WIN_DOORLOCK; | |
8447 | + args.command_type = ide_cmd_type_parser(&args); | |
8448 | check_disk_change(inode->i_rdev); | |
8449 | /* | |
8450 | * Ignore the return code from door_lock, | |
8451 | * since the open() has already succeeded, | |
8452 | * and the door_lock is irrelevant at this point. | |
8453 | */ | |
8454 | - if (drive->doorlocking && ide_wait_cmd(drive, WIN_DOORLOCK, 0, 0, 0, NULL)) | |
8455 | + if (drive->doorlocking && ide_raw_taskfile(drive, &args, NULL)) | |
8456 | drive->doorlocking = 0; | |
8457 | } | |
8458 | return 0; | |
8459 | } | |
8460 | ||
8461 | +static int do_idedisk_flushcache(ide_drive_t *drive); | |
8462 | + | |
8463 | static void idedisk_release (struct inode *inode, struct file *filp, ide_drive_t *drive) | |
8464 | { | |
8465 | if (drive->removable && !drive->usage) { | |
8466 | + ide_task_t args; | |
8467 | + memset(&args, 0, sizeof(ide_task_t)); | |
8468 | + args.tfRegister[IDE_COMMAND_OFFSET] = WIN_DOORUNLOCK; | |
8469 | + args.command_type = ide_cmd_type_parser(&args); | |
8470 | invalidate_bdev(inode->i_bdev, 0); | |
8471 | - if (drive->doorlocking && ide_wait_cmd(drive, WIN_DOORUNLOCK, 0, 0, 0, NULL)) | |
8472 | + if (drive->doorlocking && ide_raw_taskfile(drive, &args, NULL)) | |
8473 | drive->doorlocking = 0; | |
8474 | } | |
8475 | + if ((drive->id->cfs_enable_2 & 0x3000) && drive->wcache) | |
8476 | + if (do_idedisk_flushcache(drive)) | |
8477 | + printk (KERN_INFO "%s: Write Cache FAILED Flushing!\n", | |
8478 | + drive->name); | |
8479 | MOD_DEC_USE_COUNT; | |
8480 | } | |
8481 | ||
8482 | @@ -500,28 +732,423 @@ | |
8483 | current_capacity(drive)); | |
8484 | } | |
8485 | ||
8486 | +static int idedisk_end_request (ide_drive_t *drive, int uptodate) | |
8487 | +{ | |
8488 | + struct request *rq; | |
8489 | + unsigned long flags; | |
8490 | + int ret = 1; | |
8491 | + | |
8492 | + spin_lock_irqsave(&io_request_lock, flags); | |
8493 | + rq = HWGROUP(drive)->rq; | |
8494 | + | |
8495 | + /* | |
8496 | + * decide whether to reenable DMA -- 3 is a random magic for now, | |
8497 | + * if we DMA timeout more than 3 times, just stay in PIO | |
8498 | + */ | |
8499 | + if (drive->state == DMA_PIO_RETRY && drive->retry_pio <= 3) { | |
8500 | + drive->state = 0; | |
8501 | + HWGROUP(drive)->hwif->dmaproc(ide_dma_on, drive); | |
8502 | + } | |
8503 | + | |
8504 | + if (!end_that_request_first(rq, uptodate, drive->name)) { | |
8505 | + add_blkdev_randomness(MAJOR(rq->rq_dev)); | |
8506 | + blkdev_dequeue_request(rq); | |
8507 | + HWGROUP(drive)->rq = NULL; | |
8508 | + end_that_request_last(rq); | |
8509 | + ret = 0; | |
8510 | + } | |
8511 | + spin_unlock_irqrestore(&io_request_lock, flags); | |
8512 | + return ret; | |
8513 | +} | |
8514 | + | |
8515 | +static byte idedisk_dump_status (ide_drive_t *drive, const char *msg, byte stat) | |
8516 | +{ | |
8517 | + unsigned long flags; | |
8518 | + byte err = 0; | |
8519 | + | |
8520 | + local_irq_set(flags); | |
8521 | + printk("%s: %s: status=0x%02x", drive->name, msg, stat); | |
8522 | +#if FANCY_STATUS_DUMPS | |
8523 | + printk(" { "); | |
8524 | + if (stat & BUSY_STAT) | |
8525 | + printk("Busy "); | |
8526 | + else { | |
8527 | + if (stat & READY_STAT) printk("DriveReady "); | |
8528 | + if (stat & WRERR_STAT) printk("DeviceFault "); | |
8529 | + if (stat & SEEK_STAT) printk("SeekComplete "); | |
8530 | + if (stat & DRQ_STAT) printk("DataRequest "); | |
8531 | + if (stat & ECC_STAT) printk("CorrectedError "); | |
8532 | + if (stat & INDEX_STAT) printk("Index "); | |
8533 | + if (stat & ERR_STAT) printk("Error "); | |
8534 | + } | |
8535 | + printk("}"); | |
8536 | +#endif /* FANCY_STATUS_DUMPS */ | |
8537 | + printk("\n"); | |
8538 | + if ((stat & (BUSY_STAT|ERR_STAT)) == ERR_STAT) { | |
8539 | + err = GET_ERR(); | |
8540 | + printk("%s: %s: error=0x%02x", drive->name, msg, err); | |
8541 | +#if FANCY_STATUS_DUMPS | |
8542 | + printk(" { "); | |
8543 | + if (err & ABRT_ERR) printk("DriveStatusError "); | |
8544 | + if (err & ICRC_ERR) printk("%s", (err & ABRT_ERR) ? "BadCRC " : "BadSector "); | |
8545 | + if (err & ECC_ERR) printk("UncorrectableError "); | |
8546 | + if (err & ID_ERR) printk("SectorIdNotFound "); | |
8547 | + if (err & TRK0_ERR) printk("TrackZeroNotFound "); | |
8548 | + if (err & MARK_ERR) printk("AddrMarkNotFound "); | |
8549 | + printk("}"); | |
8550 | + if ((err & (BBD_ERR | ABRT_ERR)) == BBD_ERR || (err & (ECC_ERR|ID_ERR|MARK_ERR))) { | |
8551 | + if ((drive->id->command_set_2 & 0x0400) && | |
8552 | + (drive->id->cfs_enable_2 & 0x0400) && | |
8553 | + (drive->addressing == 1)) { | |
8554 | + __u64 sectors = 0; | |
8555 | + u32 low = 0, high = 0; | |
8556 | + low = idedisk_read_24(drive); | |
8557 | + OUT_BYTE(drive->ctl|0x80, IDE_CONTROL_REG); | |
8558 | + high = idedisk_read_24(drive); | |
8559 | + sectors = ((__u64)high << 24) | low; | |
8560 | + printk(", LBAsect=%llu, high=%d, low=%d", | |
8561 | + (unsigned long long) sectors, | |
8562 | + high, low); | |
8563 | + } else { | |
8564 | + byte cur = IN_BYTE(IDE_SELECT_REG); | |
8565 | + if (cur & 0x40) { /* using LBA? */ | |
8566 | + printk(", LBAsect=%ld", (unsigned long) | |
8567 | + ((cur&0xf)<<24) | |
8568 | + |(IN_BYTE(IDE_HCYL_REG)<<16) | |
8569 | + |(IN_BYTE(IDE_LCYL_REG)<<8) | |
8570 | + | IN_BYTE(IDE_SECTOR_REG)); | |
8571 | + } else { | |
8572 | + printk(", CHS=%d/%d/%d", | |
8573 | + (IN_BYTE(IDE_HCYL_REG)<<8) + | |
8574 | + IN_BYTE(IDE_LCYL_REG), | |
8575 | + cur & 0xf, | |
8576 | + IN_BYTE(IDE_SECTOR_REG)); | |
8577 | + } | |
8578 | + } | |
8579 | + if (HWGROUP(drive) && HWGROUP(drive)->rq) | |
8580 | + printk(", sector=%ld", HWGROUP(drive)->rq->sector); | |
8581 | + } | |
8582 | + } | |
8583 | +#endif /* FANCY_STATUS_DUMPS */ | |
8584 | + printk("\n"); | |
8585 | + local_irq_restore(flags); | |
8586 | + return err; | |
8587 | +} | |
8588 | + | |
8589 | +ide_startstop_t idedisk_error (ide_drive_t *drive, const char *msg, byte stat) | |
8590 | +{ | |
8591 | + struct request *rq; | |
8592 | + byte err; | |
8593 | + int i = (drive->mult_count ? drive->mult_count : 1) * SECTOR_WORDS; | |
8594 | + | |
8595 | + err = idedisk_dump_status(drive, msg, stat); | |
8596 | + | |
8597 | + if (drive == NULL || (rq = HWGROUP(drive)->rq) == NULL) | |
8598 | + return ide_stopped; | |
8599 | + /* retry only "normal" I/O: */ | |
8600 | + switch (rq->cmd) { | |
8601 | + case IDE_DRIVE_CMD: | |
8602 | + case IDE_DRIVE_TASK: | |
8603 | + case IDE_DRIVE_TASKFILE: | |
8604 | + rq->errors = 1; | |
8605 | + ide_end_drive_cmd(drive, stat, err); | |
8606 | + return ide_stopped; | |
8607 | +#if 0 | |
8608 | + case IDE_DRIVE_TASKFILE: | |
8609 | + rq->errors = 1; | |
8610 | + ide_end_taskfile(drive, stat, err); | |
8611 | + return ide_stopped; | |
8612 | +#endif | |
8613 | + default: | |
8614 | + break; | |
8615 | + } | |
8616 | + | |
8617 | + if (stat & BUSY_STAT || ((stat & WRERR_STAT) && !drive->nowerr)) { | |
8618 | + /* other bits are useless when BUSY */ | |
8619 | + rq->errors |= ERROR_RESET; | |
8620 | + } else if (stat & ERR_STAT) { | |
8621 | + /* err has different meaning on cdrom and tape */ | |
8622 | + if (err == ABRT_ERR) { | |
8623 | + if (drive->select.b.lba && | |
8624 | + /* some newer drives don't support WIN_SPECIFY */ | |
8625 | + IN_BYTE(IDE_COMMAND_REG) == WIN_SPECIFY) | |
8626 | + return ide_stopped; | |
8627 | + } else if ((err & (ABRT_ERR | ICRC_ERR)) == (ABRT_ERR | ICRC_ERR)) { | |
8628 | + /* UDMA crc error, just retry the operation */ | |
8629 | + drive->crc_count++; | |
8630 | + } else if (err & (BBD_ERR | ECC_ERR)) | |
8631 | + /* retries won't help these */ | |
8632 | + rq->errors = ERROR_MAX; | |
8633 | + else if (err & TRK0_ERR) | |
8634 | + /* help it find track zero */ | |
8635 | + rq->errors |= ERROR_RECAL; | |
8636 | + } | |
8637 | + if ((stat & DRQ_STAT) && rq->cmd != WRITE) { | |
8638 | + /* | |
8639 | + * try_to_flush_leftover_data() is invoked in response to | |
8640 | + * a drive unexpectedly having its DRQ_STAT bit set. As | |
8641 | + * an alternative to resetting the drive, this routine | |
8642 | + * tries to clear the condition by read a sector's worth | |
8643 | + * of data from the drive. Of course, this may not help | |
8644 | + * if the drive is *waiting* for data from *us*. | |
8645 | + */ | |
8646 | + while (i > 0) { | |
8647 | + u32 buffer[16]; | |
8648 | + unsigned int wcount = (i > 16) ? 16 : i; | |
8649 | + i -= wcount; | |
8650 | + ata_input_data(drive, buffer, wcount); | |
8651 | + } | |
8652 | + } | |
8653 | + if (GET_STAT() & (BUSY_STAT|DRQ_STAT)) | |
8654 | + /* force an abort */ | |
8655 | + OUT_BYTE(WIN_IDLEIMMEDIATE,IDE_COMMAND_REG); | |
8656 | + if (rq->errors >= ERROR_MAX) | |
8657 | + DRIVER(drive)->end_request(drive, 0); | |
8658 | + else { | |
8659 | + if ((rq->errors & ERROR_RESET) == ERROR_RESET) { | |
8660 | + ++rq->errors; | |
8661 | + return ide_do_reset(drive); | |
8662 | + } | |
8663 | + if ((rq->errors & ERROR_RECAL) == ERROR_RECAL) | |
8664 | + drive->special.b.recalibrate = 1; | |
8665 | + ++rq->errors; | |
8666 | + } | |
8667 | + return ide_stopped; | |
8668 | +} | |
8669 | + | |
8670 | +/* | |
8671 | + * Queries for true maximum capacity of the drive. | |
8672 | + * Returns maximum LBA address (> 0) of the drive, 0 if failed. | |
8673 | + */ | |
8674 | +static unsigned long idedisk_read_native_max_address(ide_drive_t *drive) | |
8675 | +{ | |
8676 | + ide_task_t args; | |
8677 | + unsigned long addr = 0; | |
8678 | + | |
8679 | +#if 0 | |
8680 | + if (!(drive->id->command_set_1 & 0x0400) && | |
8681 | + !(drive->id->cfs_enable_2 & 0x0100)) | |
8682 | + return addr; | |
8683 | +#endif | |
8684 | + | |
8685 | + /* Create IDE/ATA command request structure */ | |
8686 | + memset(&args, 0, sizeof(ide_task_t)); | |
8687 | + args.tfRegister[IDE_SELECT_OFFSET] = 0x40; | |
8688 | + args.tfRegister[IDE_COMMAND_OFFSET] = WIN_READ_NATIVE_MAX; | |
8689 | + args.command_type = ide_cmd_type_parser(&args); | |
8690 | + /* submit command request */ | |
8691 | + ide_raw_taskfile(drive, &args, NULL); | |
8692 | + | |
8693 | + /* if OK, compute maximum address value */ | |
8694 | + if ((args.tfRegister[IDE_STATUS_OFFSET] & 0x01) == 0) { | |
8695 | + addr = ((args.tfRegister[IDE_SELECT_OFFSET] & 0x0f) << 24) | |
8696 | + | ((args.tfRegister[ IDE_HCYL_OFFSET] ) << 16) | |
8697 | + | ((args.tfRegister[ IDE_LCYL_OFFSET] ) << 8) | |
8698 | + | ((args.tfRegister[IDE_SECTOR_OFFSET] )); | |
8699 | + } | |
8700 | + addr++; /* since the return value is (maxlba - 1), we add 1 */ | |
8701 | + return addr; | |
8702 | +} | |
8703 | + | |
8704 | +static unsigned long long idedisk_read_native_max_address_ext(ide_drive_t *drive) | |
8705 | +{ | |
8706 | + ide_task_t args; | |
8707 | + unsigned long long addr = 0; | |
8708 | + | |
8709 | + /* Create IDE/ATA command request structure */ | |
8710 | + memset(&args, 0, sizeof(ide_task_t)); | |
8711 | + | |
8712 | + args.tfRegister[IDE_SELECT_OFFSET] = 0x40; | |
8713 | + args.tfRegister[IDE_COMMAND_OFFSET] = WIN_READ_NATIVE_MAX_EXT; | |
8714 | + args.command_type = ide_cmd_type_parser(&args); | |
8715 | + /* submit command request */ | |
8716 | + ide_raw_taskfile(drive, &args, NULL); | |
8717 | + | |
8718 | + /* if OK, compute maximum address value */ | |
8719 | + if ((args.tfRegister[IDE_STATUS_OFFSET] & 0x01) == 0) { | |
8720 | + u32 high = ((args.hobRegister[IDE_HCYL_OFFSET_HOB])<<16) | | |
8721 | + ((args.hobRegister[IDE_LCYL_OFFSET_HOB])<<8) | | |
8722 | + (args.hobRegister[IDE_SECTOR_OFFSET_HOB]); | |
8723 | + u32 low = ((args.tfRegister[IDE_HCYL_OFFSET])<<16) | | |
8724 | + ((args.tfRegister[IDE_LCYL_OFFSET])<<8) | | |
8725 | + (args.tfRegister[IDE_SECTOR_OFFSET]); | |
8726 | + addr = ((__u64)high << 24) | low; | |
8727 | + } | |
8728 | + addr++; /* since the return value is (maxlba - 1), we add 1 */ | |
8729 | + return addr; | |
8730 | +} | |
8731 | + | |
8732 | +#ifdef CONFIG_IDEDISK_STROKE | |
8733 | +/* | |
8734 | + * Sets maximum virtual LBA address of the drive. | |
8735 | + * Returns new maximum virtual LBA address (> 0) or 0 on failure. | |
8736 | + */ | |
8737 | +static unsigned long idedisk_set_max_address(ide_drive_t *drive, unsigned long addr_req) | |
8738 | +{ | |
8739 | + ide_task_t args; | |
8740 | + unsigned long addr_set = 0; | |
8741 | + | |
8742 | + addr_req--; | |
8743 | + /* Create IDE/ATA command request structure */ | |
8744 | + memset(&args, 0, sizeof(ide_task_t)); | |
8745 | + args.tfRegister[IDE_SECTOR_OFFSET] = ((addr_req >> 0) & 0xff); | |
8746 | + args.tfRegister[IDE_LCYL_OFFSET] = ((addr_req >> 8) & 0xff); | |
8747 | + args.tfRegister[IDE_HCYL_OFFSET] = ((addr_req >> 16) & 0xff); | |
8748 | + args.tfRegister[IDE_SELECT_OFFSET] = ((addr_req >> 24) & 0x0f) | 0x40; | |
8749 | + args.tfRegister[IDE_COMMAND_OFFSET] = WIN_SET_MAX; | |
8750 | + args.command_type = ide_cmd_type_parser(&args); | |
8751 | + /* submit command request */ | |
8752 | + ide_raw_taskfile(drive, &args, NULL); | |
8753 | + /* if OK, read new maximum address value */ | |
8754 | + if ((args.tfRegister[IDE_STATUS_OFFSET] & 0x01) == 0) { | |
8755 | + addr_set = ((args.tfRegister[IDE_SELECT_OFFSET] & 0x0f) << 24) | |
8756 | + | ((args.tfRegister[ IDE_HCYL_OFFSET] ) << 16) | |
8757 | + | ((args.tfRegister[ IDE_LCYL_OFFSET] ) << 8) | |
8758 | + | ((args.tfRegister[IDE_SECTOR_OFFSET] )); | |
8759 | + } | |
8760 | + addr_set++; | |
8761 | + return addr_set; | |
8762 | +} | |
8763 | + | |
8764 | +static unsigned long long idedisk_set_max_address_ext(ide_drive_t *drive, unsigned long long addr_req) | |
8765 | +{ | |
8766 | + ide_task_t args; | |
8767 | + unsigned long long addr_set = 0; | |
8768 | + | |
8769 | + addr_req--; | |
8770 | + /* Create IDE/ATA command request structure */ | |
8771 | + memset(&args, 0, sizeof(ide_task_t)); | |
8772 | + args.tfRegister[IDE_SECTOR_OFFSET] = ((addr_req >> 0) & 0xff); | |
8773 | + args.tfRegister[IDE_LCYL_OFFSET] = ((addr_req >>= 8) & 0xff); | |
8774 | + args.tfRegister[IDE_HCYL_OFFSET] = ((addr_req >>= 8) & 0xff); | |
8775 | + args.tfRegister[IDE_SELECT_OFFSET] = 0x40; | |
8776 | + args.tfRegister[IDE_COMMAND_OFFSET] = WIN_SET_MAX_EXT; | |
8777 | + args.hobRegister[IDE_SECTOR_OFFSET_HOB] = ((addr_req >>= 8) & 0xff); | |
8778 | + args.hobRegister[IDE_LCYL_OFFSET_HOB] = ((addr_req >>= 8) & 0xff); | |
8779 | + args.hobRegister[IDE_HCYL_OFFSET_HOB] = ((addr_req >>= 8) & 0xff); | |
8780 | + args.hobRegister[IDE_SELECT_OFFSET_HOB] = 0x40; | |
8781 | + args.hobRegister[IDE_CONTROL_OFFSET_HOB]= (drive->ctl|0x80); | |
8782 | + args.command_type = ide_cmd_type_parser(&args); | |
8783 | + /* submit command request */ | |
8784 | + ide_raw_taskfile(drive, &args, NULL); | |
8785 | + /* if OK, compute maximum address value */ | |
8786 | + if ((args.tfRegister[IDE_STATUS_OFFSET] & 0x01) == 0) { | |
8787 | + u32 high = ((args.hobRegister[IDE_HCYL_OFFSET_HOB])<<16) | | |
8788 | + ((args.hobRegister[IDE_LCYL_OFFSET_HOB])<<8) | | |
8789 | + (args.hobRegister[IDE_SECTOR_OFFSET_HOB]); | |
8790 | + u32 low = ((args.tfRegister[IDE_HCYL_OFFSET])<<16) | | |
8791 | + ((args.tfRegister[IDE_LCYL_OFFSET])<<8) | | |
8792 | + (args.tfRegister[IDE_SECTOR_OFFSET]); | |
8793 | + addr_set = ((__u64)high << 24) | low; | |
8794 | + } | |
8795 | + return addr_set; | |
8796 | +} | |
8797 | + | |
8798 | +#endif /* CONFIG_IDEDISK_STROKE */ | |
8799 | + | |
8800 | +/* | |
8801 | + * Tests if the drive supports Host Protected Area feature. | |
8802 | + * Returns true if supported, false otherwise. | |
8803 | + */ | |
8804 | +static inline int idedisk_supports_host_protected_area(ide_drive_t *drive) | |
8805 | +{ | |
8806 | + int flag = (drive->id->cfs_enable_1 & 0x0400) ? 1 : 0; | |
8807 | + if (flag) | |
8808 | + printk("%s: host protected area => %d\n", drive->name, flag); | |
8809 | + return flag; | |
8810 | +} | |
8811 | + | |
8812 | /* | |
8813 | * Compute drive->capacity, the full capacity of the drive | |
8814 | * Called with drive->id != NULL. | |
8815 | + * | |
8816 | + * To compute capacity, this uses either of | |
8817 | + * | |
8818 | + * 1. CHS value set by user (whatever user sets will be trusted) | |
8819 | + * 2. LBA value from target drive (require new ATA feature) | |
8820 | + * 3. LBA value from system BIOS (new one is OK, old one may break) | |
8821 | + * 4. CHS value from system BIOS (traditional style) | |
8822 | + * | |
8823 | + * in above order (i.e., if value of higher priority is available, | |
8824 | + * reset will be ignored). | |
8825 | */ | |
8826 | static void init_idedisk_capacity (ide_drive_t *drive) | |
8827 | { | |
8828 | struct hd_driveid *id = drive->id; | |
8829 | unsigned long capacity = drive->cyl * drive->head * drive->sect; | |
8830 | + unsigned long set_max = idedisk_read_native_max_address(drive); | |
8831 | + unsigned long long capacity_2 = capacity; | |
8832 | + unsigned long long set_max_ext; | |
8833 | ||
8834 | + drive->capacity48 = 0; | |
8835 | drive->select.b.lba = 0; | |
8836 | ||
8837 | + (void) idedisk_supports_host_protected_area(drive); | |
8838 | + | |
8839 | + if (id->cfs_enable_2 & 0x0400) { | |
8840 | + capacity_2 = id->lba_capacity_2; | |
8841 | + drive->head = drive->bios_head = 255; | |
8842 | + drive->sect = drive->bios_sect = 63; | |
8843 | + drive->cyl = (unsigned int) capacity_2 / (drive->head * drive->sect); | |
8844 | + drive->select.b.lba = 1; | |
8845 | + set_max_ext = idedisk_read_native_max_address_ext(drive); | |
8846 | + if (set_max_ext > capacity_2) { | |
8847 | +#ifdef CONFIG_IDEDISK_STROKE | |
8848 | + set_max_ext = idedisk_read_native_max_address_ext(drive); | |
8849 | + set_max_ext = idedisk_set_max_address_ext(drive, set_max_ext); | |
8850 | + if (set_max_ext) { | |
8851 | + drive->capacity48 = capacity_2 = set_max_ext; | |
8852 | + drive->cyl = (unsigned int) set_max_ext / (drive->head * drive->sect); | |
8853 | + drive->select.b.lba = 1; | |
8854 | + drive->id->lba_capacity_2 = capacity_2; | |
8855 | + } | |
8856 | +#else /* !CONFIG_IDEDISK_STROKE */ | |
8857 | + printk("%s: setmax_ext LBA %llu, native %llu\n", | |
8858 | + drive->name, set_max_ext, capacity_2); | |
8859 | +#endif /* CONFIG_IDEDISK_STROKE */ | |
8860 | + } | |
8861 | + drive->cyl = (unsigned int) capacity_2 / (drive->head * drive->sect); | |
8862 | + drive->bios_cyl = drive->cyl; | |
8863 | + drive->capacity48 = capacity_2; | |
8864 | + drive->capacity = (unsigned long) capacity_2; | |
8865 | + return; | |
8866 | /* Determine capacity, and use LBA if the drive properly supports it */ | |
8867 | - if ((id->capability & 2) && lba_capacity_is_ok(id)) { | |
8868 | + } else if ((id->capability & 2) && lba_capacity_is_ok(id)) { | |
8869 | capacity = id->lba_capacity; | |
8870 | drive->cyl = capacity / (drive->head * drive->sect); | |
8871 | drive->select.b.lba = 1; | |
8872 | } | |
8873 | + | |
8874 | + if (set_max > capacity) { | |
8875 | +#ifdef CONFIG_IDEDISK_STROKE | |
8876 | + set_max = idedisk_read_native_max_address(drive); | |
8877 | + set_max = idedisk_set_max_address(drive, set_max); | |
8878 | + if (set_max) { | |
8879 | + drive->capacity = capacity = set_max; | |
8880 | + drive->cyl = set_max / (drive->head * drive->sect); | |
8881 | + drive->select.b.lba = 1; | |
8882 | + drive->id->lba_capacity = capacity; | |
8883 | + } | |
8884 | +#else /* !CONFIG_IDEDISK_STROKE */ | |
8885 | + printk("%s: setmax LBA %lu, native %lu\n", | |
8886 | + drive->name, set_max, capacity); | |
8887 | +#endif /* CONFIG_IDEDISK_STROKE */ | |
8888 | + } | |
8889 | + | |
8890 | drive->capacity = capacity; | |
8891 | + | |
8892 | + if ((id->command_set_2 & 0x0400) && (id->cfs_enable_2 & 0x0400)) { | |
8893 | + drive->capacity48 = id->lba_capacity_2; | |
8894 | + drive->head = 255; | |
8895 | + drive->sect = 63; | |
8896 | + drive->cyl = (unsigned long)(drive->capacity48) / (drive->head * drive->sect); | |
8897 | + } | |
8898 | } | |
8899 | ||
8900 | -static unsigned long idedisk_capacity (ide_drive_t *drive) | |
8901 | +static unsigned long idedisk_capacity (ide_drive_t *drive) | |
8902 | { | |
8903 | + if (drive->id->cfs_enable_2 & 0x0400) | |
8904 | + return (drive->capacity48 - drive->sect0); | |
8905 | return (drive->capacity - drive->sect0); | |
8906 | } | |
8907 | ||
8908 | @@ -530,23 +1157,41 @@ | |
8909 | special_t *s = &drive->special; | |
8910 | ||
8911 | if (s->b.set_geometry) { | |
8912 | - s->b.set_geometry = 0; | |
8913 | - OUT_BYTE(drive->sect,IDE_SECTOR_REG); | |
8914 | - OUT_BYTE(drive->cyl,IDE_LCYL_REG); | |
8915 | - OUT_BYTE(drive->cyl>>8,IDE_HCYL_REG); | |
8916 | - OUT_BYTE(((drive->head-1)|drive->select.all)&0xBF,IDE_SELECT_REG); | |
8917 | - if (!IS_PDC4030_DRIVE) | |
8918 | - ide_cmd(drive, WIN_SPECIFY, drive->sect, &set_geometry_intr); | |
8919 | + s->b.set_geometry = 0; | |
8920 | + if (!IS_PDC4030_DRIVE) { | |
8921 | + ide_task_t args; | |
8922 | + memset(&args, 0, sizeof(ide_task_t)); | |
8923 | + args.tfRegister[IDE_NSECTOR_OFFSET] = drive->sect; | |
8924 | + args.tfRegister[IDE_SECTOR_OFFSET] = drive->sect; | |
8925 | + args.tfRegister[IDE_LCYL_OFFSET] = drive->cyl; | |
8926 | + args.tfRegister[IDE_HCYL_OFFSET] = drive->cyl>>8; | |
8927 | + args.tfRegister[IDE_SELECT_OFFSET] = ((drive->head-1)|drive->select.all)&0xBF; | |
8928 | + args.tfRegister[IDE_COMMAND_OFFSET] = WIN_SPECIFY; | |
8929 | + args.command_type = ide_cmd_type_parser(&args); | |
8930 | + do_rw_taskfile(drive, &args); | |
8931 | + } | |
8932 | } else if (s->b.recalibrate) { | |
8933 | s->b.recalibrate = 0; | |
8934 | - if (!IS_PDC4030_DRIVE) | |
8935 | - ide_cmd(drive, WIN_RESTORE, drive->sect, &recal_intr); | |
8936 | + if (!IS_PDC4030_DRIVE) { | |
8937 | + ide_task_t args; | |
8938 | + memset(&args, 0, sizeof(ide_task_t)); | |
8939 | + args.tfRegister[IDE_NSECTOR_OFFSET] = drive->sect; | |
8940 | + args.tfRegister[IDE_COMMAND_OFFSET] = WIN_RESTORE; | |
8941 | + args.command_type = ide_cmd_type_parser(&args); | |
8942 | + do_rw_taskfile(drive, &args); | |
8943 | + } | |
8944 | } else if (s->b.set_multmode) { | |
8945 | s->b.set_multmode = 0; | |
8946 | if (drive->id && drive->mult_req > drive->id->max_multsect) | |
8947 | drive->mult_req = drive->id->max_multsect; | |
8948 | - if (!IS_PDC4030_DRIVE) | |
8949 | - ide_cmd(drive, WIN_SETMULT, drive->mult_req, &set_multmode_intr); | |
8950 | + if (!IS_PDC4030_DRIVE) { | |
8951 | + ide_task_t args; | |
8952 | + memset(&args, 0, sizeof(ide_task_t)); | |
8953 | + args.tfRegister[IDE_NSECTOR_OFFSET] = drive->mult_req; | |
8954 | + args.tfRegister[IDE_COMMAND_OFFSET] = WIN_SETMULT; | |
8955 | + args.command_type = ide_cmd_type_parser(&args); | |
8956 | + do_rw_taskfile(drive, &args); | |
8957 | + } | |
8958 | } else if (s->all) { | |
8959 | int special = s->all; | |
8960 | s->all = 0; | |
8961 | @@ -558,9 +1203,11 @@ | |
8962 | ||
8963 | static void idedisk_pre_reset (ide_drive_t *drive) | |
8964 | { | |
8965 | + int legacy = (drive->id->cfs_enable_2 & 0x0400) ? 0 : 1; | |
8966 | + | |
8967 | drive->special.all = 0; | |
8968 | - drive->special.b.set_geometry = 1; | |
8969 | - drive->special.b.recalibrate = 1; | |
8970 | + drive->special.b.set_geometry = legacy; | |
8971 | + drive->special.b.recalibrate = legacy; | |
8972 | if (OK_TO_RESET_CONTROLLER) | |
8973 | drive->mult_count = 0; | |
8974 | if (!drive->keep_settings && !drive->using_dma) | |
8975 | @@ -573,19 +1220,44 @@ | |
8976 | ||
8977 | static int smart_enable(ide_drive_t *drive) | |
8978 | { | |
8979 | - return ide_wait_cmd(drive, WIN_SMART, 0, SMART_ENABLE, 0, NULL); | |
8980 | + ide_task_t args; | |
8981 | + | |
8982 | + memset(&args, 0, sizeof(ide_task_t)); | |
8983 | + args.tfRegister[IDE_FEATURE_OFFSET] = SMART_ENABLE; | |
8984 | + args.tfRegister[IDE_LCYL_OFFSET] = SMART_LCYL_PASS; | |
8985 | + args.tfRegister[IDE_HCYL_OFFSET] = SMART_HCYL_PASS; | |
8986 | + args.tfRegister[IDE_COMMAND_OFFSET] = WIN_SMART; | |
8987 | + args.command_type = ide_cmd_type_parser(&args); | |
8988 | + return ide_raw_taskfile(drive, &args, NULL); | |
8989 | } | |
8990 | ||
8991 | static int get_smart_values(ide_drive_t *drive, byte *buf) | |
8992 | { | |
8993 | + ide_task_t args; | |
8994 | + | |
8995 | + memset(&args, 0, sizeof(ide_task_t)); | |
8996 | + args.tfRegister[IDE_FEATURE_OFFSET] = SMART_READ_VALUES; | |
8997 | + args.tfRegister[IDE_NSECTOR_OFFSET] = 0x01; | |
8998 | + args.tfRegister[IDE_LCYL_OFFSET] = SMART_LCYL_PASS; | |
8999 | + args.tfRegister[IDE_HCYL_OFFSET] = SMART_HCYL_PASS; | |
9000 | + args.tfRegister[IDE_COMMAND_OFFSET] = WIN_SMART; | |
9001 | + args.command_type = ide_cmd_type_parser(&args); | |
9002 | (void) smart_enable(drive); | |
9003 | - return ide_wait_cmd(drive, WIN_SMART, 0, SMART_READ_VALUES, 1, buf); | |
9004 | + return ide_raw_taskfile(drive, &args, buf); | |
9005 | } | |
9006 | ||
9007 | static int get_smart_thresholds(ide_drive_t *drive, byte *buf) | |
9008 | { | |
9009 | + ide_task_t args; | |
9010 | + memset(&args, 0, sizeof(ide_task_t)); | |
9011 | + args.tfRegister[IDE_FEATURE_OFFSET] = SMART_READ_THRESHOLDS; | |
9012 | + args.tfRegister[IDE_NSECTOR_OFFSET] = 0x01; | |
9013 | + args.tfRegister[IDE_LCYL_OFFSET] = SMART_LCYL_PASS; | |
9014 | + args.tfRegister[IDE_HCYL_OFFSET] = SMART_HCYL_PASS; | |
9015 | + args.tfRegister[IDE_COMMAND_OFFSET] = WIN_SMART; | |
9016 | + args.command_type = ide_cmd_type_parser(&args); | |
9017 | (void) smart_enable(drive); | |
9018 | - return ide_wait_cmd(drive, WIN_SMART, 0, SMART_READ_THRESHOLDS, 1, buf); | |
9019 | + return ide_raw_taskfile(drive, &args, buf); | |
9020 | } | |
9021 | ||
9022 | static int proc_idedisk_read_cache | |
9023 | @@ -609,7 +1281,7 @@ | |
9024 | int len = 0, i = 0; | |
9025 | ||
9026 | if (!get_smart_thresholds(drive, page)) { | |
9027 | - unsigned short *val = ((unsigned short *)page) + 2; | |
9028 | + unsigned short *val = (unsigned short *) page; | |
9029 | char *out = ((char *)val) + (SECTOR_WORDS * 4); | |
9030 | page = out; | |
9031 | do { | |
9032 | @@ -628,7 +1300,7 @@ | |
9033 | int len = 0, i = 0; | |
9034 | ||
9035 | if (!get_smart_values(drive, page)) { | |
9036 | - unsigned short *val = ((unsigned short *)page) + 2; | |
9037 | + unsigned short *val = (unsigned short *) page; | |
9038 | char *out = ((char *)val) + (SECTOR_WORDS * 4); | |
9039 | page = out; | |
9040 | do { | |
9041 | @@ -654,6 +1326,10 @@ | |
9042 | ||
9043 | #endif /* CONFIG_PROC_FS */ | |
9044 | ||
9045 | +/* | |
9046 | + * This is tightly woven into the driver->do_special can not touch. | |
9047 | + * DON'T do it again until a total personality rewrite is committed. | |
9048 | + */ | |
9049 | static int set_multcount(ide_drive_t *drive, int arg) | |
9050 | { | |
9051 | struct request rq; | |
9052 | @@ -661,6 +1337,7 @@ | |
9053 | if (drive->special.b.set_multmode) | |
9054 | return -EBUSY; | |
9055 | ide_init_drive_cmd (&rq); | |
9056 | + rq.cmd = IDE_DRIVE_CMD; | |
9057 | drive->mult_req = arg; | |
9058 | drive->special.b.set_multmode = 1; | |
9059 | (void) ide_do_drive_cmd (drive, &rq, ide_wait); | |
9060 | @@ -677,6 +1354,136 @@ | |
9061 | return 0; | |
9062 | } | |
9063 | ||
9064 | +static int write_cache (ide_drive_t *drive, int arg) | |
9065 | +{ | |
9066 | + ide_task_t args; | |
9067 | + | |
9068 | + if (!(drive->id->cfs_enable_2 & 0x3000)) | |
9069 | + return 1; | |
9070 | + | |
9071 | + memset(&args, 0, sizeof(ide_task_t)); | |
9072 | + args.tfRegister[IDE_FEATURE_OFFSET] = (arg) ? | |
9073 | + SETFEATURES_EN_WCACHE : SETFEATURES_DIS_WCACHE; | |
9074 | + args.tfRegister[IDE_COMMAND_OFFSET] = WIN_SETFEATURES; | |
9075 | + args.command_type = ide_cmd_type_parser(&args); | |
9076 | + (void) ide_raw_taskfile(drive, &args, NULL); | |
9077 | + | |
9078 | + drive->wcache = arg; | |
9079 | + return 0; | |
9080 | +} | |
9081 | + | |
9082 | +static int call_idedisk_standby (ide_drive_t *drive, int arg) | |
9083 | +{ | |
9084 | + ide_task_t args; | |
9085 | + byte standby = (arg) ? WIN_STANDBYNOW2 : WIN_STANDBYNOW1; | |
9086 | + memset(&args, 0, sizeof(ide_task_t)); | |
9087 | + args.tfRegister[IDE_COMMAND_OFFSET] = standby; | |
9088 | + args.command_type = ide_cmd_type_parser(&args); | |
9089 | + return ide_raw_taskfile(drive, &args, NULL); | |
9090 | +} | |
9091 | + | |
9092 | +static int do_idedisk_standby (ide_drive_t *drive) | |
9093 | +{ | |
9094 | + return call_idedisk_standby(drive, 0); | |
9095 | +} | |
9096 | + | |
9097 | +static int call_idedisk_suspend (ide_drive_t *drive, int arg) | |
9098 | +{ | |
9099 | + ide_task_t args; | |
9100 | + byte suspend = (arg) ? WIN_SLEEPNOW2 : WIN_SLEEPNOW1; | |
9101 | + memset(&args, 0, sizeof(ide_task_t)); | |
9102 | + args.tfRegister[IDE_COMMAND_OFFSET] = suspend; | |
9103 | + args.command_type = ide_cmd_type_parser(&args); | |
9104 | + return ide_raw_taskfile(drive, &args, NULL); | |
9105 | +} | |
9106 | + | |
9107 | +static int do_idedisk_suspend (ide_drive_t *drive) | |
9108 | +{ | |
9109 | + if (drive->suspend_reset) | |
9110 | + return 1; | |
9111 | + | |
9112 | + return call_idedisk_suspend(drive, 0); | |
9113 | +} | |
9114 | + | |
9115 | +#if 0 | |
9116 | +static int call_idedisk_checkpower (ide_drive_t *drive, int arg) | |
9117 | +{ | |
9118 | + ide_task_t args; | |
9119 | + byte ckpw = (arg) ? WIN_CHECKPOWERMODE2 : WIN_CHECKPOWERMODE1; | |
9120 | + memset(&args, 0, sizeof(ide_task_t)); | |
9121 | + args.tfRegister[IDE_COMMAND_OFFSET] = ckpw; | |
9122 | + args.command_type = ide_cmd_type_parser(&args); | |
9123 | + ide_raw_taskfile(drive, &args, NULL); | |
9124 | +#if 0 | |
9125 | +if (errno != EIO || args[0] != 0 || args[1] != 0) | |
9126 | + state = "unknown"; | |
9127 | +else | |
9128 | + state = "sleeping"; | |
9129 | +} else { | |
9130 | + state = (args[2] == 255) ? "active/idle" : "standby"; | |
9131 | +#endif | |
9132 | + return 0; | |
9133 | +} | |
9134 | + | |
9135 | +static int do_idedisk_checkpower (ide_drive_t *drive) | |
9136 | +{ | |
9137 | + return call_idedisk_checkpower(drive, 0); | |
9138 | +} | |
9139 | +#endif | |
9140 | + | |
9141 | +static int do_idedisk_resume (ide_drive_t *drive) | |
9142 | +{ | |
9143 | + if (!drive->suspend_reset) | |
9144 | + return 1; | |
9145 | + return 0; | |
9146 | +} | |
9147 | + | |
9148 | +static int do_idedisk_flushcache (ide_drive_t *drive) | |
9149 | +{ | |
9150 | + ide_task_t args; | |
9151 | + | |
9152 | + memset(&args, 0, sizeof(ide_task_t)); | |
9153 | + if (drive->id->cfs_enable_2 & 0x2400) | |
9154 | + args.tfRegister[IDE_COMMAND_OFFSET] = WIN_FLUSH_CACHE_EXT; | |
9155 | + else | |
9156 | + args.tfRegister[IDE_COMMAND_OFFSET] = WIN_FLUSH_CACHE; | |
9157 | + args.command_type = ide_cmd_type_parser(&args); | |
9158 | + return ide_raw_taskfile(drive, &args, NULL); | |
9159 | +} | |
9160 | + | |
9161 | +static int set_acoustic (ide_drive_t *drive, int arg) | |
9162 | +{ | |
9163 | + ide_task_t args; | |
9164 | + | |
9165 | + memset(&args, 0, sizeof(ide_task_t)); | |
9166 | + args.tfRegister[IDE_FEATURE_OFFSET] = (arg) ? SETFEATURES_EN_AAM : | |
9167 | + SETFEATURES_DIS_AAM; | |
9168 | + args.tfRegister[IDE_NSECTOR_OFFSET] = arg; | |
9169 | + args.tfRegister[IDE_COMMAND_OFFSET] = WIN_SETFEATURES; | |
9170 | + args.command_type = ide_cmd_type_parser(&args); | |
9171 | + ide_raw_taskfile(drive, &args, NULL); | |
9172 | + drive->acoustic = arg; | |
9173 | + return 0; | |
9174 | +} | |
9175 | + | |
9176 | +static int probe_lba_addressing (ide_drive_t *drive, int arg) | |
9177 | +{ | |
9178 | + drive->addressing = 0; | |
9179 | + | |
9180 | + if (HWIF(drive)->addressing) | |
9181 | + return 0; | |
9182 | + | |
9183 | + if (!(drive->id->cfs_enable_2 & 0x0400)) | |
9184 | + return -EIO; | |
9185 | + drive->addressing = arg; | |
9186 | + return 0; | |
9187 | +} | |
9188 | + | |
9189 | +static int set_lba_addressing (ide_drive_t *drive, int arg) | |
9190 | +{ | |
9191 | + return (probe_lba_addressing(drive, arg)); | |
9192 | +} | |
9193 | + | |
9194 | static void idedisk_add_settings(ide_drive_t *drive) | |
9195 | { | |
9196 | struct hd_driveid *id = drive->id; | |
9197 | @@ -686,15 +1493,18 @@ | |
9198 | ide_add_setting(drive, "bios_cyl", SETTING_RW, -1, -1, TYPE_INT, 0, 65535, 1, 1, &drive->bios_cyl, NULL); | |
9199 | ide_add_setting(drive, "bios_head", SETTING_RW, -1, -1, TYPE_BYTE, 0, 255, 1, 1, &drive->bios_head, NULL); | |
9200 | ide_add_setting(drive, "bios_sect", SETTING_RW, -1, -1, TYPE_BYTE, 0, 63, 1, 1, &drive->bios_sect, NULL); | |
9201 | + ide_add_setting(drive, "address", SETTING_RW, HDIO_GET_ADDRESS, HDIO_SET_ADDRESS, TYPE_INTA, 0, 2, 1, 1, &drive->addressing, set_lba_addressing); | |
9202 | ide_add_setting(drive, "bswap", SETTING_READ, -1, -1, TYPE_BYTE, 0, 1, 1, 1, &drive->bswap, NULL); | |
9203 | - ide_add_setting(drive, "multcount", id ? SETTING_RW : SETTING_READ, HDIO_GET_MULTCOUNT, HDIO_SET_MULTCOUNT, TYPE_BYTE, 0, id ? id->max_multsect : 0, 1, 2, &drive->mult_count, set_multcount); | |
9204 | + ide_add_setting(drive, "multcount", id ? SETTING_RW : SETTING_READ, HDIO_GET_MULTCOUNT, HDIO_SET_MULTCOUNT, TYPE_BYTE, 0, id ? id->max_multsect : 0, 1, 1, &drive->mult_count, set_multcount); | |
9205 | ide_add_setting(drive, "nowerr", SETTING_RW, HDIO_GET_NOWERR, HDIO_SET_NOWERR, TYPE_BYTE, 0, 1, 1, 1, &drive->nowerr, set_nowerr); | |
9206 | - ide_add_setting(drive, "breada_readahead", SETTING_RW, BLKRAGET, BLKRASET, TYPE_INT, 0, 255, 1, 2, &read_ahead[major], NULL); | |
9207 | + ide_add_setting(drive, "breada_readahead", SETTING_RW, BLKRAGET, BLKRASET, TYPE_INT, 0, 255, 1, 1, &read_ahead[major], NULL); | |
9208 | ide_add_setting(drive, "file_readahead", SETTING_RW, BLKFRAGET, BLKFRASET, TYPE_INTA, 0, 4096, PAGE_SIZE, 1024, &max_readahead[major][minor], NULL); | |
9209 | - ide_add_setting(drive, "max_kb_per_request", SETTING_RW, BLKSECTGET, BLKSECTSET, TYPE_INTA, 1, 255, 1, 2, &max_sectors[major][minor], NULL); | |
9210 | + ide_add_setting(drive, "max_kb_per_request", SETTING_RW, BLKSECTGET, BLKSECTSET, TYPE_INTA, 1, 255, 1, 1, &max_sectors[major][minor], NULL); | |
9211 | ide_add_setting(drive, "lun", SETTING_RW, -1, -1, TYPE_INT, 0, 7, 1, 1, &drive->lun, NULL); | |
9212 | - ide_add_setting(drive, "failures", SETTING_RW, -1, -1, TYPE_INT, 0, 65535, 1, 1, &drive->failures, NULL); | |
9213 | - ide_add_setting(drive, "max_failures", SETTING_RW, -1, -1, TYPE_INT, 0, 65535, 1, 1, &drive->max_failures, NULL); | |
9214 | + ide_add_setting(drive, "wcache", SETTING_RW, HDIO_GET_WCACHE, HDIO_SET_WCACHE, TYPE_BYTE, 0, 1, 1, 1, &drive->wcache, write_cache); | |
9215 | + ide_add_setting(drive, "acoustic", SETTING_RW, HDIO_GET_ACOUSTIC, HDIO_SET_ACOUSTIC, TYPE_BYTE, 0, 254, 1, 1, &drive->acoustic, set_acoustic); | |
9216 | + ide_add_setting(drive, "failures", SETTING_RW, -1, -1, TYPE_INT, 0, 65535, 1, 1, &drive->failures, NULL); | |
9217 | + ide_add_setting(drive, "max_failures", SETTING_RW, -1, -1, TYPE_INT, 0, 65535, 1, 1, &drive->max_failures, NULL); | |
9218 | } | |
9219 | ||
9220 | static void idedisk_setup (ide_drive_t *drive) | |
9221 | @@ -731,6 +1541,14 @@ | |
9222 | break; | |
9223 | } | |
9224 | ||
9225 | +#if 1 | |
9226 | + (void) probe_lba_addressing(drive, 1); | |
9227 | +#else | |
9228 | + /* if using 48-bit addressing bump the request size up */ | |
9229 | + if (probe_lba_addressing(drive, 1)) | |
9230 | + blk_queue_max_sectors(&drive->queue, 2048); | |
9231 | +#endif | |
9232 | + | |
9233 | /* Extract geometry if we did not already have one for the drive */ | |
9234 | if (!drive->cyl || !drive->head || !drive->sect) { | |
9235 | drive->cyl = drive->bios_cyl = id->cyls; | |
9236 | @@ -764,7 +1582,6 @@ | |
9237 | if ((capacity >= (drive->bios_cyl * drive->bios_sect * drive->bios_head)) && | |
9238 | (!drive->forced_geom) && drive->bios_sect && drive->bios_head) | |
9239 | drive->bios_cyl = (capacity / drive->bios_sect) / drive->bios_head; | |
9240 | - | |
9241 | printk (KERN_INFO "%s: %ld sectors", drive->name, capacity); | |
9242 | ||
9243 | /* Give size in megabytes (MB), not mebibytes (MiB). */ | |
9244 | @@ -796,21 +1613,25 @@ | |
9245 | drive->mult_req = id->max_multsect; | |
9246 | if (drive->mult_req || ((id->multsect_valid & 1) && id->multsect)) | |
9247 | drive->special.b.set_multmode = 1; | |
9248 | -#endif | |
9249 | +#endif /* CONFIG_IDEDISK_MULTI_MODE */ | |
9250 | } | |
9251 | drive->no_io_32bit = id->dword_io ? 1 : 0; | |
9252 | -} | |
9253 | - | |
9254 | -static int idedisk_reinit (ide_drive_t *drive) | |
9255 | -{ | |
9256 | - return 0; | |
9257 | + if (drive->id->cfs_enable_2 & 0x3000) | |
9258 | + write_cache(drive, (id->cfs_enable_2 & 0x3000)); | |
9259 | } | |
9260 | ||
9261 | static int idedisk_cleanup (ide_drive_t *drive) | |
9262 | { | |
9263 | + if ((drive->id->cfs_enable_2 & 0x3000) && drive->wcache) | |
9264 | + if (do_idedisk_flushcache(drive)) | |
9265 | + printk (KERN_INFO "%s: Write Cache FAILED Flushing!\n", | |
9266 | + drive->name); | |
9267 | return ide_unregister_subdriver(drive); | |
9268 | } | |
9269 | ||
9270 | +int idedisk_init (void); | |
9271 | +int idedisk_reinit(ide_drive_t *drive); | |
9272 | + | |
9273 | /* | |
9274 | * IDE subdriver functions, registered with ide.c | |
9275 | */ | |
9276 | @@ -822,8 +1643,14 @@ | |
9277 | supports_dma: 1, | |
9278 | supports_dsc_overlap: 0, | |
9279 | cleanup: idedisk_cleanup, | |
9280 | + standby: do_idedisk_standby, | |
9281 | + suspend: do_idedisk_suspend, | |
9282 | + resume: do_idedisk_resume, | |
9283 | + flushcache: do_idedisk_flushcache, | |
9284 | do_request: do_rw_disk, | |
9285 | - end_request: NULL, | |
9286 | + end_request: idedisk_end_request, | |
9287 | + sense: idedisk_dump_status, | |
9288 | + error: idedisk_error, | |
9289 | ioctl: NULL, | |
9290 | open: idedisk_open, | |
9291 | release: idedisk_release, | |
9292 | @@ -833,10 +1660,12 @@ | |
9293 | capacity: idedisk_capacity, | |
9294 | special: idedisk_special, | |
9295 | proc: idedisk_proc, | |
9296 | - driver_reinit: idedisk_reinit, | |
9297 | + init: idedisk_init, | |
9298 | + reinit: idedisk_reinit, | |
9299 | + ata_prebuilder: NULL, | |
9300 | + atapi_prebuilder: NULL, | |
9301 | }; | |
9302 | ||
9303 | -int idedisk_init (void); | |
9304 | static ide_module_t idedisk_module = { | |
9305 | IDE_DRIVER_MODULE, | |
9306 | idedisk_init, | |
9307 | @@ -846,6 +1675,33 @@ | |
9308 | ||
9309 | MODULE_DESCRIPTION("ATA DISK Driver"); | |
9310 | ||
9311 | +int idedisk_reinit (ide_drive_t *drive) | |
9312 | +{ | |
9313 | + int failed = 0; | |
9314 | + | |
9315 | + MOD_INC_USE_COUNT; | |
9316 | + | |
9317 | + if (ide_register_subdriver (drive, &idedisk_driver, IDE_SUBDRIVER_VERSION)) { | |
9318 | + printk (KERN_ERR "ide-disk: %s: Failed to register the driver with ide.c\n", drive->name); | |
9319 | + return 1; | |
9320 | + } | |
9321 | + DRIVER(drive)->busy++; | |
9322 | + idedisk_setup(drive); | |
9323 | + if ((!drive->head || drive->head > 16) && !drive->select.b.lba) { | |
9324 | + printk(KERN_ERR "%s: INVALID GEOMETRY: %d PHYSICAL HEADS?\n", | |
9325 | + drive->name, drive->head); | |
9326 | + (void) idedisk_cleanup(drive); | |
9327 | + DRIVER(drive)->busy--; | |
9328 | + return 1; | |
9329 | + } | |
9330 | + DRIVER(drive)->busy--; | |
9331 | + failed--; | |
9332 | + | |
9333 | + ide_register_module(&idedisk_module); | |
9334 | + MOD_DEC_USE_COUNT; | |
9335 | + return 0; | |
9336 | +} | |
9337 | + | |
9338 | static void __exit idedisk_exit (void) | |
9339 | { | |
9340 | ide_drive_t *drive; | |
9341 | @@ -877,12 +1733,15 @@ | |
9342 | printk (KERN_ERR "ide-disk: %s: Failed to register the driver with ide.c\n", drive->name); | |
9343 | continue; | |
9344 | } | |
9345 | + DRIVER(drive)->busy++; | |
9346 | idedisk_setup(drive); | |
9347 | if ((!drive->head || drive->head > 16) && !drive->select.b.lba) { | |
9348 | printk(KERN_ERR "%s: INVALID GEOMETRY: %d PHYSICAL HEADS?\n", drive->name, drive->head); | |
9349 | (void) idedisk_cleanup(drive); | |
9350 | + DRIVER(drive)->busy--; | |
9351 | continue; | |
9352 | } | |
9353 | + DRIVER(drive)->busy--; | |
9354 | failed--; | |
9355 | } | |
9356 | ide_register_module(&idedisk_module); | |
9357 | @@ -890,6 +1749,78 @@ | |
9358 | return 0; | |
9359 | } | |
9360 | ||
9361 | +ide_startstop_t panic_box(ide_drive_t *drive) | |
9362 | +{ | |
9363 | +#if 0 | |
9364 | + panic("%s: Attempted to corrupt something: ide operation " | |
9365 | +#else | |
9366 | + printk(KERN_ERR "%s: Attempted to corrupt something: ide operation " | |
9367 | +#endif | |
9368 | + "was pending accross suspend/resume.\n", drive->name); | |
9369 | + return ide_stopped; | |
9370 | +} | |
9371 | + | |
9372 | +int ide_disks_busy(void) | |
9373 | +{ | |
9374 | + int i; | |
9375 | + for (i=0; i<MAX_HWIFS; i++) { | |
9376 | + struct hwgroup_s *hwgroup = ide_hwifs[i].hwgroup; | |
9377 | + if (!hwgroup) continue; | |
9378 | + if ((hwgroup->handler) && (hwgroup->handler != panic_box)) | |
9379 | + return 1; | |
9380 | + } | |
9381 | + return 0; | |
9382 | +} | |
9383 | + | |
9384 | +void ide_disk_suspend(void) | |
9385 | +{ | |
9386 | + int i; | |
9387 | + while (ide_disks_busy()) { | |
9388 | + printk("*"); | |
9389 | + schedule(); | |
9390 | + } | |
9391 | + for (i=0; i<MAX_HWIFS; i++) { | |
9392 | + struct hwgroup_s *hwgroup = ide_hwifs[i].hwgroup; | |
9393 | + | |
9394 | + if (!hwgroup) continue; | |
9395 | + hwgroup->handler_save = hwgroup->handler; | |
9396 | + hwgroup->handler = panic_box; | |
9397 | + } | |
9398 | + driver_blocked = 1; | |
9399 | + if (ide_disks_busy()) | |
9400 | + panic("How did you get that request through?!"); | |
9401 | +} | |
9402 | + | |
9403 | +/* unsuspend and resume should be equal in the ideal world */ | |
9404 | + | |
9405 | +void ide_disk_unsuspend(void) | |
9406 | +{ | |
9407 | + int i; | |
9408 | + for (i=0; i<MAX_HWIFS; i++) { | |
9409 | + struct hwgroup_s *hwgroup = ide_hwifs[i].hwgroup; | |
9410 | + | |
9411 | + if (!hwgroup) continue; | |
9412 | + hwgroup->handler = NULL; /* hwgroup->handler_save; */ | |
9413 | + hwgroup->handler_save = NULL; | |
9414 | + } | |
9415 | + driver_blocked = 0; | |
9416 | +} | |
9417 | + | |
9418 | +void ide_disk_resume(void) | |
9419 | +{ | |
9420 | + int i; | |
9421 | + for (i=0; i<MAX_HWIFS; i++) { | |
9422 | + struct hwgroup_s *hwgroup = ide_hwifs[i].hwgroup; | |
9423 | + | |
9424 | + if (!hwgroup) continue; | |
9425 | + if (hwgroup->handler != panic_box) | |
9426 | + panic("Handler was not set to panic?"); | |
9427 | + hwgroup->handler_save = NULL; | |
9428 | + hwgroup->handler = NULL; | |
9429 | + } | |
9430 | + driver_blocked = 0; | |
9431 | +} | |
9432 | + | |
9433 | module_init(idedisk_init); | |
9434 | module_exit(idedisk_exit); | |
9435 | MODULE_LICENSE("GPL"); | |
9436 | diff -Nur linux.org/drivers/ide/ide-dma.c linux/drivers/ide/ide-dma.c | |
9437 | --- linux.org/drivers/ide/ide-dma.c Sun Sep 9 19:43:02 2001 | |
9438 | +++ linux/drivers/ide/ide-dma.c Thu Jul 18 14:24:33 2002 | |
9439 | @@ -101,8 +101,6 @@ | |
9440 | #define DEFAULT_BMCRBA 0xcc00 /* VIA's default value */ | |
9441 | #define DEFAULT_BMALIBA 0xd400 /* ALI's default value */ | |
9442 | ||
9443 | -extern char *ide_dmafunc_verbose(ide_dma_action_t dmafunc); | |
9444 | - | |
9445 | #ifdef CONFIG_IDEDMA_NEW_DRIVE_LISTINGS | |
9446 | ||
9447 | struct drive_list_entry { | |
9448 | @@ -237,14 +235,14 @@ | |
9449 | rq = HWGROUP(drive)->rq; | |
9450 | for (i = rq->nr_sectors; i > 0;) { | |
9451 | i -= rq->current_nr_sectors; | |
9452 | - ide_end_request(1, HWGROUP(drive)); | |
9453 | + DRIVER(drive)->end_request(drive, 1); | |
9454 | } | |
9455 | return ide_stopped; | |
9456 | } | |
9457 | printk("%s: dma_intr: bad DMA status (dma_stat=%x)\n", | |
9458 | drive->name, dma_stat); | |
9459 | } | |
9460 | - return ide_error(drive, "dma_intr", stat); | |
9461 | + return DRIVER(drive)->error(drive, "dma_intr", stat); | |
9462 | } | |
9463 | ||
9464 | static int ide_build_sglist (ide_hwif_t *hwif, struct request *rq) | |
9465 | @@ -282,6 +280,48 @@ | |
9466 | return pci_map_sg(hwif->pci_dev, sg, nents, hwif->sg_dma_direction); | |
9467 | } | |
9468 | ||
9469 | +static int ide_raw_build_sglist (ide_hwif_t *hwif, struct request *rq) | |
9470 | +{ | |
9471 | + struct scatterlist *sg = hwif->sg_table; | |
9472 | + int nents = 0; | |
9473 | + ide_task_t *args = rq->special; | |
9474 | + unsigned char *virt_addr = rq->buffer; | |
9475 | + int sector_count = rq->nr_sectors; | |
9476 | + | |
9477 | + if (args->command_type == IDE_DRIVE_TASK_RAW_WRITE) | |
9478 | + hwif->sg_dma_direction = PCI_DMA_TODEVICE; | |
9479 | + else | |
9480 | + hwif->sg_dma_direction = PCI_DMA_FROMDEVICE; | |
9481 | +#if 1 | |
9482 | + if (sector_count > 128) { | |
9483 | + memset(&sg[nents], 0, sizeof(*sg)); | |
9484 | + sg[nents].address = virt_addr; | |
9485 | + sg[nents].length = 128 * SECTOR_SIZE; | |
9486 | + nents++; | |
9487 | + virt_addr = virt_addr + (128 * SECTOR_SIZE); | |
9488 | + sector_count -= 128; | |
9489 | + } | |
9490 | + memset(&sg[nents], 0, sizeof(*sg)); | |
9491 | + sg[nents].address = virt_addr; | |
9492 | + sg[nents].length = sector_count * SECTOR_SIZE; | |
9493 | + nents++; | |
9494 | +#else | |
9495 | + while (sector_count > 128) { | |
9496 | + memset(&sg[nents], 0, sizeof(*sg)); | |
9497 | + sg[nents].address = virt_addr; | |
9498 | + sg[nents].length = 128 * SECTOR_SIZE; | |
9499 | + nents++; | |
9500 | + virt_addr = virt_addr + (128 * SECTOR_SIZE); | |
9501 | + sector_count -= 128; | |
9502 | + }; | |
9503 | + memset(&sg[nents], 0, sizeof(*sg)); | |
9504 | + sg[nents].address = virt_addr; | |
9505 | + sg[nents].length = sector_count * SECTOR_SIZE; | |
9506 | + nents++; | |
9507 | +#endif | |
9508 | + return pci_map_sg(hwif->pci_dev, sg, nents, hwif->sg_dma_direction); | |
9509 | +} | |
9510 | + | |
9511 | /* | |
9512 | * ide_build_dmatable() prepares a dma request. | |
9513 | * Returns 0 if all went okay, returns 1 otherwise. | |
9514 | @@ -299,7 +339,10 @@ | |
9515 | int i; | |
9516 | struct scatterlist *sg; | |
9517 | ||
9518 | - HWIF(drive)->sg_nents = i = ide_build_sglist(HWIF(drive), HWGROUP(drive)->rq); | |
9519 | + if (HWGROUP(drive)->rq->cmd == IDE_DRIVE_TASKFILE) | |
9520 | + HWIF(drive)->sg_nents = i = ide_raw_build_sglist(HWIF(drive), HWGROUP(drive)->rq); | |
9521 | + else | |
9522 | + HWIF(drive)->sg_nents = i = ide_build_sglist(HWIF(drive), HWGROUP(drive)->rq); | |
9523 | ||
9524 | if (!i) | |
9525 | return 0; | |
9526 | @@ -429,7 +472,14 @@ | |
9527 | struct hd_driveid *id = drive->id; | |
9528 | ||
9529 | if ((id->field_valid & 4) && (eighty_ninty_three(drive)) && | |
9530 | - (id->dma_ultra & (id->dma_ultra >> 11) & 7)) { | |
9531 | + (id->dma_ultra & (id->dma_ultra >> 14) & 3)) { | |
9532 | + if ((id->dma_ultra >> 15) & 1) { | |
9533 | + printk(", UDMA(mode 7)"); /* UDMA BIOS-enabled! */ | |
9534 | + } else { | |
9535 | + printk(", UDMA(133)"); /* UDMA BIOS-enabled! */ | |
9536 | + } | |
9537 | + } else if ((id->field_valid & 4) && (eighty_ninty_three(drive)) && | |
9538 | + (id->dma_ultra & (id->dma_ultra >> 11) & 7)) { | |
9539 | if ((id->dma_ultra >> 13) & 1) { | |
9540 | printk(", UDMA(100)"); /* UDMA BIOS-enabled! */ | |
9541 | } else if ((id->dma_ultra >> 12) & 1) { | |
9542 | @@ -464,6 +514,10 @@ | |
9543 | if (ide_dmaproc(ide_dma_bad_drive, drive)) | |
9544 | return hwif->dmaproc(ide_dma_off, drive); | |
9545 | ||
9546 | + /* Enable DMA on any drive that has UltraDMA (mode 6/7/?) enabled */ | |
9547 | + if ((id->field_valid & 4) && (eighty_ninty_three(drive))) | |
9548 | + if ((id->dma_ultra & (id->dma_ultra >> 14) & 2)) | |
9549 | + return hwif->dmaproc(ide_dma_on, drive); | |
9550 | /* Enable DMA on any drive that has UltraDMA (mode 3/4/5) enabled */ | |
9551 | if ((id->field_valid & 4) && (eighty_ninty_three(drive))) | |
9552 | if ((id->dma_ultra & (id->dma_ultra >> 11) & 7)) | |
9553 | @@ -483,54 +537,70 @@ | |
9554 | return hwif->dmaproc(ide_dma_off_quietly, drive); | |
9555 | } | |
9556 | ||
9557 | -#ifndef CONFIG_BLK_DEV_IDEDMA_TIMEOUT | |
9558 | +#ifndef __IDEDMA_TIMEOUT | |
9559 | /* | |
9560 | * 1 dmaing, 2 error, 4 intr | |
9561 | */ | |
9562 | static int dma_timer_expiry (ide_drive_t *drive) | |
9563 | { | |
9564 | - byte dma_stat = inb(HWIF(drive)->dma_base+2); | |
9565 | + byte dma_stat = IN_BYTE(HWIF(drive)->dma_base+2); | |
9566 | ||
9567 | #ifdef DEBUG | |
9568 | printk("%s: dma_timer_expiry: dma status == 0x%02x\n", drive->name, dma_stat); | |
9569 | #endif /* DEBUG */ | |
9570 | ||
9571 | -#if 1 | |
9572 | +#if 0 | |
9573 | HWGROUP(drive)->expiry = NULL; /* one free ride for now */ | |
9574 | #endif | |
9575 | ||
9576 | if (dma_stat & 2) { /* ERROR */ | |
9577 | byte stat = GET_STAT(); | |
9578 | - return ide_error(drive, "dma_timer_expiry", stat); | |
9579 | + return DRIVER(drive)->error(drive, "dma_timer_expiry", stat); | |
9580 | } | |
9581 | if (dma_stat & 1) /* DMAing */ | |
9582 | return WAIT_CMD; | |
9583 | return 0; | |
9584 | } | |
9585 | -#else /* CONFIG_BLK_DEV_IDEDMA_TIMEOUT */ | |
9586 | -static ide_startstop_t ide_dma_timeout_revovery (ide_drive_t *drive) | |
9587 | +#else /* __IDEDMA_TIMEOUT */ | |
9588 | +static int ide_dma_timeout_recovery (ide_drive_t *drive) | |
9589 | { | |
9590 | - ide_hwgroup_t *hwgroup = HWGROUP(drive); | |
9591 | - ide_hwif_t *hwif = HWIF(drive); | |
9592 | + struct request *rq = HWGROUP(drive)->rq; | |
9593 | int enable_dma = drive->using_dma; | |
9594 | + int speed = drive->current_speed; | |
9595 | unsigned long flags; | |
9596 | - ide_startstop_t startstop; | |
9597 | ||
9598 | spin_lock_irqsave(&io_request_lock, flags); | |
9599 | - hwgroup->handler = NULL; | |
9600 | - del_timer(&hwgroup->timer); | |
9601 | + HWGROUP(drive)->handler = NULL; | |
9602 | + del_timer(&HWGROUP(drive)->timer); | |
9603 | + HWGROUP(drive)->expiry = NULL; | |
9604 | + HWGROUP(drive)->rq = NULL; | |
9605 | spin_unlock_irqrestore(&io_request_lock, flags); | |
9606 | ||
9607 | + (void) HWIF(drive)->dmaproc(ide_dma_off, drive); | |
9608 | drive->waiting_for_dma = 0; | |
9609 | ||
9610 | - startstop = ide_do_reset(drive); | |
9611 | + (void) ide_do_reset(drive); | |
9612 | + | |
9613 | + if (!(drive_is_ready(drive))) { | |
9614 | + /* FIXME: Replace hard-coded 100, error handling? */ | |
9615 | + int i; | |
9616 | + for (i=0; i<100; i++) { | |
9617 | + if (drive_is_ready(drive)) | |
9618 | + break; | |
9619 | + } | |
9620 | + } | |
9621 | + | |
9622 | + if ((HWIF(drive)->speedproc) != NULL) { | |
9623 | + HWIF(drive)->speedproc(drive, speed); | |
9624 | + drive->current_speed = speed; | |
9625 | + } | |
9626 | ||
9627 | if ((enable_dma) && !(drive->using_dma)) | |
9628 | - (void) hwif->dmaproc(ide_dma_on, drive); | |
9629 | + (void) HWIF(drive)->dmaproc(ide_dma_on, drive); | |
9630 | ||
9631 | - return startstop; | |
9632 | + return restart_request(drive, rq); | |
9633 | } | |
9634 | -#endif /* CONFIG_BLK_DEV_IDEDMA_TIMEOUT */ | |
9635 | +#endif /* __IDEDMA_TIMEOUT */ | |
9636 | ||
9637 | /* | |
9638 | * ide_dmaproc() initiates/aborts DMA read/write operations on a drive. | |
9639 | @@ -550,8 +620,8 @@ | |
9640 | */ | |
9641 | int ide_dmaproc (ide_dma_action_t func, ide_drive_t *drive) | |
9642 | { | |
9643 | -// ide_hwgroup_t *hwgroup = HWGROUP(drive); | |
9644 | ide_hwif_t *hwif = HWIF(drive); | |
9645 | +// ide_task_t *args = HWGROUP(drive)->rq->special; | |
9646 | unsigned long dma_base = hwif->dma_base; | |
9647 | byte unit = (drive->select.b.unit & 0x01); | |
9648 | unsigned int count, reading = 0; | |
9649 | @@ -561,11 +631,17 @@ | |
9650 | case ide_dma_off: | |
9651 | printk("%s: DMA disabled\n", drive->name); | |
9652 | case ide_dma_off_quietly: | |
9653 | - outb(inb(dma_base+2) & ~(1<<(5+unit)), dma_base+2); | |
9654 | + case ide_dma_host_off: | |
9655 | + OUT_BYTE(IN_BYTE(dma_base+2) & ~(1<<(5+unit)), dma_base+2); | |
9656 | + if (func == ide_dma_host_off) | |
9657 | + return 0; | |
9658 | case ide_dma_on: | |
9659 | drive->using_dma = (func == ide_dma_on); | |
9660 | + if (!drive->using_dma) | |
9661 | + return 0; | |
9662 | + case ide_dma_host_on: | |
9663 | if (drive->using_dma) | |
9664 | - outb(inb(dma_base+2)|(1<<(5+unit)), dma_base+2); | |
9665 | + OUT_BYTE(IN_BYTE(dma_base+2)|(1<<(5+unit)), dma_base+2); | |
9666 | return 0; | |
9667 | case ide_dma_check: | |
9668 | return config_drive_for_dma (drive); | |
9669 | @@ -574,88 +650,127 @@ | |
9670 | case ide_dma_write: | |
9671 | SELECT_READ_WRITE(hwif,drive,func); | |
9672 | if (!(count = ide_build_dmatable(drive, func))) | |
9673 | - return 1; /* try PIO instead of DMA */ | |
9674 | - outl(hwif->dmatable_dma, dma_base + 4); /* PRD table */ | |
9675 | - outb(reading, dma_base); /* specify r/w */ | |
9676 | - outb(inb(dma_base+2)|6, dma_base+2); /* clear INTR & ERROR flags */ | |
9677 | + /* try PIO instead of DMA */ | |
9678 | + return 1; | |
9679 | + /* PRD table */ | |
9680 | + outl(hwif->dmatable_dma, dma_base + 4); | |
9681 | + /* specify r/w */ | |
9682 | + OUT_BYTE(reading, dma_base); | |
9683 | + /* clear INTR & ERROR flags */ | |
9684 | + OUT_BYTE(IN_BYTE(dma_base+2)|6, dma_base+2); | |
9685 | drive->waiting_for_dma = 1; | |
9686 | if (drive->media != ide_disk) | |
9687 | return 0; | |
9688 | -#ifdef CONFIG_BLK_DEV_IDEDMA_TIMEOUT | |
9689 | - ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL); /* issue cmd to drive */ | |
9690 | -#else /* !CONFIG_BLK_DEV_IDEDMA_TIMEOUT */ | |
9691 | - ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, dma_timer_expiry); /* issue cmd to drive */ | |
9692 | -#endif /* CONFIG_BLK_DEV_IDEDMA_TIMEOUT */ | |
9693 | - OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG); | |
9694 | + /* paranoia check */ | |
9695 | + if (HWGROUP(drive)->handler != NULL) | |
9696 | + BUG(); | |
9697 | +#ifndef __IDEDMA_TIMEOUT | |
9698 | + ide_set_handler(drive, &ide_dma_intr, 2*WAIT_CMD, dma_timer_expiry); | |
9699 | +#else /* __IDEDMA_TIMEOUT */ | |
9700 | + ide_set_handler(drive, &ide_dma_intr, 2*WAIT_CMD, NULL); | |
9701 | +#endif /* __IDEDMA_TIMEOUT */ | |
9702 | + /* issue cmd to drive */ | |
9703 | + /* | |
9704 | + * FIX ME to use only ACB ide_task_t args Struct | |
9705 | + */ | |
9706 | +#if 0 | |
9707 | + { | |
9708 | + ide_task_t *args = HWGROUP(drive)->rq->special; | |
9709 | + OUT_BYTE(args->tfRegister[IDE_COMMAND_OFFSET], IDE_COMMAND_REG); | |
9710 | + } | |
9711 | +#else | |
9712 | + if (HWGROUP(drive)->rq->cmd == IDE_DRIVE_TASKFILE) { | |
9713 | + ide_task_t *args = HWGROUP(drive)->rq->special; | |
9714 | + OUT_BYTE(args->tfRegister[IDE_COMMAND_OFFSET], IDE_COMMAND_REG); | |
9715 | + } else if (drive->addressing == 1) | |
9716 | + OUT_BYTE(reading ? WIN_READDMA_EXT : WIN_WRITEDMA_EXT, IDE_COMMAND_REG); | |
9717 | + else | |
9718 | + OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG); | |
9719 | +#endif | |
9720 | + return HWIF(drive)->dmaproc(ide_dma_begin, drive); | |
9721 | case ide_dma_begin: | |
9722 | /* Note that this is done *after* the cmd has | |
9723 | * been issued to the drive, as per the BM-IDE spec. | |
9724 | * The Promise Ultra33 doesn't work correctly when | |
9725 | * we do this part before issuing the drive cmd. | |
9726 | */ | |
9727 | - outb(inb(dma_base)|1, dma_base); /* start DMA */ | |
9728 | + /* start DMA */ | |
9729 | + OUT_BYTE(IN_BYTE(dma_base)|1, dma_base); | |
9730 | return 0; | |
9731 | case ide_dma_end: /* returns 1 on error, 0 otherwise */ | |
9732 | drive->waiting_for_dma = 0; | |
9733 | - outb(inb(dma_base)&~1, dma_base); /* stop DMA */ | |
9734 | - dma_stat = inb(dma_base+2); /* get DMA status */ | |
9735 | - outb(dma_stat|6, dma_base+2); /* clear the INTR & ERROR bits */ | |
9736 | - ide_destroy_dmatable(drive); /* purge DMA mappings */ | |
9737 | - return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0; /* verify good DMA status */ | |
9738 | + /* stop DMA */ | |
9739 | + OUT_BYTE(IN_BYTE(dma_base)&~1, dma_base); | |
9740 | + /* get DMA status */ | |
9741 | + dma_stat = IN_BYTE(dma_base+2); | |
9742 | + /* clear the INTR & ERROR bits */ | |
9743 | + OUT_BYTE(dma_stat|6, dma_base+2); | |
9744 | + /* purge DMA mappings */ | |
9745 | + ide_destroy_dmatable(drive); | |
9746 | + /* verify good DMA status */ | |
9747 | + return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0; | |
9748 | case ide_dma_test_irq: /* returns 1 if dma irq issued, 0 otherwise */ | |
9749 | - dma_stat = inb(dma_base+2); | |
9750 | -#if 0 /* do not set unless you know what you are doing */ | |
9751 | + dma_stat = IN_BYTE(dma_base+2); | |
9752 | +#if 0 /* do not set unless you know what you are doing */ | |
9753 | if (dma_stat & 4) { | |
9754 | byte stat = GET_STAT(); | |
9755 | - outb(dma_base+2, dma_stat & 0xE4); | |
9756 | + OUT_BYTE(dma_base+2, dma_stat & 0xE4); | |
9757 | } | |
9758 | #endif | |
9759 | - return (dma_stat & 4) == 4; /* return 1 if INTR asserted */ | |
9760 | + /* return 1 if INTR asserted */ | |
9761 | + return (dma_stat & 4) == 4; | |
9762 | case ide_dma_bad_drive: | |
9763 | case ide_dma_good_drive: | |
9764 | return check_drive_lists(drive, (func == ide_dma_good_drive)); | |
9765 | case ide_dma_verbose: | |
9766 | return report_drive_dmaing(drive); | |
9767 | case ide_dma_timeout: | |
9768 | - // FIXME: Many IDE chipsets do not permit command file register access | |
9769 | - // FIXME: while the bus-master function is still active. | |
9770 | - // FIXME: To prevent deadlock with those chipsets, we must be extremely | |
9771 | - // FIXME: careful here (and in ide_intr() as well) to NOT access any | |
9772 | - // FIXME: registers from the 0x1Fx/0x17x sets before terminating the | |
9773 | - // FIXME: bus-master operation via the bus-master control reg. | |
9774 | - // FIXME: Otherwise, chipset deadlock will occur, and some systems will | |
9775 | - // FIXME: lock up completely!! | |
9776 | -#ifdef CONFIG_BLK_DEV_IDEDMA_TIMEOUT | |
9777 | + // FIXME: Many IDE chipsets do not permit command file register access | |
9778 | + // FIXME: while the bus-master function is still active. | |
9779 | + // FIXME: To prevent deadlock with those chipsets, we must be extremely | |
9780 | + // FIXME: careful here (and in ide_intr() as well) to NOT access any | |
9781 | + // FIXME: registers from the 0x1Fx/0x17x sets before terminating the | |
9782 | + // FIXME: bus-master operation via the bus-master control reg. | |
9783 | + // FIXME: Otherwise, chipset deadlock will occur, and some systems will | |
9784 | + // FIXME: lock up completely!! | |
9785 | +#ifdef __IDEDMA_TIMEOUT | |
9786 | /* | |
9787 | * Have to issue an abort and requeue the request | |
9788 | * DMA engine got turned off by a goofy ASIC, and | |
9789 | * we have to clean up the mess, and here is as good | |
9790 | * as any. Do it globally for all chipsets. | |
9791 | */ | |
9792 | - outb(0x00, dma_base); /* stop DMA */ | |
9793 | - dma_stat = inb(dma_base+2); /* get DMA status */ | |
9794 | - outb(dma_stat|6, dma_base+2); /* clear the INTR & ERROR bits */ | |
9795 | +#if 0 | |
9796 | + dma_stat = HWIF(drive)->dmaproc(ide_dma_end, drive); | |
9797 | +#else | |
9798 | + drive->waiting_for_dma = 0; | |
9799 | + /* stop DMA */ | |
9800 | + OUT_BYTE(IN_BYTE(dma_base)&~1, dma_base); | |
9801 | +// OUT_BYTE(0x00, dma_base); | |
9802 | + /* get DMA status */ | |
9803 | + dma_stat = IN_BYTE(dma_base+2); | |
9804 | + /* clear the INTR & ERROR bits */ | |
9805 | + OUT_BYTE(dma_stat|6, dma_base+2); | |
9806 | + /* purge DMA mappings */ | |
9807 | + ide_destroy_dmatable(drive); | |
9808 | +#endif | |
9809 | printk("%s: %s: Lets do it again!" \ | |
9810 | "stat = 0x%02x, dma_stat = 0x%02x\n", | |
9811 | drive->name, ide_dmafunc_verbose(func), | |
9812 | GET_STAT(), dma_stat); | |
9813 | ||
9814 | if (dma_stat & 0xF0) | |
9815 | - return ide_dma_timeout_revovery(drive); | |
9816 | - | |
9817 | - printk("%s: %s: (restart_request) Lets do it again!" \ | |
9818 | - "stat = 0x%02x, dma_stat = 0x%02x\n", | |
9819 | - drive->name, ide_dmafunc_verbose(func), | |
9820 | - GET_STAT(), dma_stat); | |
9821 | - | |
9822 | - return restart_request(drive); // BUG: return types do not match!! | |
9823 | -#endif /* CONFIG_BLK_DEV_IDEDMA_TIMEOUT */ | |
9824 | + return ide_dma_timeout_recovery(drive); | |
9825 | +#endif /* __IDEDMA_TIMEOUT */ | |
9826 | case ide_dma_retune: | |
9827 | case ide_dma_lostirq: | |
9828 | - printk("ide_dmaproc: chipset supported %s func only: %d\n", ide_dmafunc_verbose(func), func); | |
9829 | + printk("ide_dmaproc: chipset supported %s " | |
9830 | + "func only: %d\n", | |
9831 | + ide_dmafunc_verbose(func), func); | |
9832 | return 1; | |
9833 | default: | |
9834 | - printk("ide_dmaproc: unsupported %s func: %d\n", ide_dmafunc_verbose(func), func); | |
9835 | + printk("ide_dmaproc: unsupported %s func: %d\n", | |
9836 | + ide_dmafunc_verbose(func), func); | |
9837 | return 1; | |
9838 | } | |
9839 | } | |
9840 | @@ -683,7 +798,7 @@ | |
9841 | } | |
9842 | ||
9843 | /* | |
9844 | - * This can be called for a dynamically installed interface. Don't __init it | |
9845 | + * This can be called for a dynamically installed interface. Don't __init it | |
9846 | */ | |
9847 | ||
9848 | void ide_setup_dma (ide_hwif_t *hwif, unsigned long dma_base, unsigned int num_ports) | |
9849 | @@ -712,7 +827,7 @@ | |
9850 | hwif->dmaproc = &ide_dmaproc; | |
9851 | ||
9852 | if (hwif->chipset != ide_trm290) { | |
9853 | - byte dma_stat = inb(dma_base+2); | |
9854 | + byte dma_stat = IN_BYTE(dma_base+2); | |
9855 | printk(", BIOS settings: %s:%s, %s:%s", | |
9856 | hwif->drives[0].name, (dma_stat & 0x20) ? "DMA" : "pio", | |
9857 | hwif->drives[1].name, (dma_stat & 0x40) ? "DMA" : "pio"); | |
9858 | @@ -777,8 +892,9 @@ | |
9859 | case PCI_DEVICE_ID_AL_M5219: | |
9860 | case PCI_DEVICE_ID_AMD_VIPER_7409: | |
9861 | case PCI_DEVICE_ID_CMD_643: | |
9862 | - outb(inb(dma_base+2) & 0x60, dma_base+2); | |
9863 | - if (inb(dma_base+2) & 0x80) { | |
9864 | + case PCI_DEVICE_ID_SERVERWORKS_CSB5IDE: | |
9865 | + OUT_BYTE(IN_BYTE(dma_base+2) & 0x60, dma_base+2); | |
9866 | + if (IN_BYTE(dma_base+2) & 0x80) { | |
9867 | printk("%s: simplex device: DMA forced\n", name); | |
9868 | } | |
9869 | break; | |
9870 | @@ -790,7 +906,7 @@ | |
9871 | * So we should enable DMA only on one of the | |
9872 | * two interfaces. | |
9873 | */ | |
9874 | - if ((inb(dma_base+2) & 0x80)) { /* simplex device? */ | |
9875 | + if ((IN_BYTE(dma_base+2) & 0x80)) { /* simplex device? */ | |
9876 | if ((!hwif->drives[0].present && !hwif->drives[1].present) || | |
9877 | (hwif->mate && hwif->mate->dma_base)) { | |
9878 | printk("%s: simplex device: DMA disabled\n", name); | |
9879 | diff -Nur linux.org/drivers/ide/ide-features.c linux/drivers/ide/ide-features.c | |
9880 | --- linux.org/drivers/ide/ide-features.c Fri Feb 9 20:40:02 2001 | |
9881 | +++ linux/drivers/ide/ide-features.c Thu Jan 1 01:00:00 1970 | |
9882 | @@ -1,391 +0,0 @@ | |
9883 | -/* | |
9884 | - * linux/drivers/block/ide-features.c Version 0.04 June 9, 2000 | |
9885 | - * | |
9886 | - * Copyright (C) 1999-2000 Linus Torvalds & authors (see below) | |
9887 | - * | |
9888 | - * Copyright (C) 1999-2000 Andre Hedrick <andre@linux-ide.org> | |
9889 | - * | |
9890 | - * Extracts if ide.c to address the evolving transfer rate code for | |
9891 | - * the SETFEATURES_XFER callouts. Various parts of any given function | |
9892 | - * are credited to previous ATA-IDE maintainers. | |
9893 | - * | |
9894 | - * Auto-CRC downgrade for Ultra DMA(ing) | |
9895 | - * | |
9896 | - * May be copied or modified under the terms of the GNU General Public License | |
9897 | - */ | |
9898 | - | |
9899 | -#include <linux/config.h> | |
9900 | -#define __NO_VERSION__ | |
9901 | -#include <linux/module.h> | |
9902 | -#include <linux/types.h> | |
9903 | -#include <linux/string.h> | |
9904 | -#include <linux/kernel.h> | |
9905 | -#include <linux/timer.h> | |
9906 | -#include <linux/mm.h> | |
9907 | -#include <linux/interrupt.h> | |
9908 | -#include <linux/major.h> | |
9909 | -#include <linux/errno.h> | |
9910 | -#include <linux/genhd.h> | |
9911 | -#include <linux/blkpg.h> | |
9912 | -#include <linux/slab.h> | |
9913 | -#include <linux/pci.h> | |
9914 | -#include <linux/delay.h> | |
9915 | -#include <linux/hdreg.h> | |
9916 | -#include <linux/ide.h> | |
9917 | - | |
9918 | -#include <asm/byteorder.h> | |
9919 | -#include <asm/irq.h> | |
9920 | -#include <asm/uaccess.h> | |
9921 | -#include <asm/io.h> | |
9922 | -#include <asm/bitops.h> | |
9923 | - | |
9924 | -/* | |
9925 | - * A Verbose noise maker for debugging on the attempted transfer rates. | |
9926 | - */ | |
9927 | -char *ide_xfer_verbose (byte xfer_rate) | |
9928 | -{ | |
9929 | - switch(xfer_rate) { | |
9930 | - case XFER_UDMA_7: return("UDMA 7"); | |
9931 | - case XFER_UDMA_6: return("UDMA 6"); | |
9932 | - case XFER_UDMA_5: return("UDMA 5"); | |
9933 | - case XFER_UDMA_4: return("UDMA 4"); | |
9934 | - case XFER_UDMA_3: return("UDMA 3"); | |
9935 | - case XFER_UDMA_2: return("UDMA 2"); | |
9936 | - case XFER_UDMA_1: return("UDMA 1"); | |
9937 | - case XFER_UDMA_0: return("UDMA 0"); | |
9938 | - case XFER_MW_DMA_2: return("MW DMA 2"); | |
9939 | - case XFER_MW_DMA_1: return("MW DMA 1"); | |
9940 | - case XFER_MW_DMA_0: return("MW DMA 0"); | |
9941 | - case XFER_SW_DMA_2: return("SW DMA 2"); | |
9942 | - case XFER_SW_DMA_1: return("SW DMA 1"); | |
9943 | - case XFER_SW_DMA_0: return("SW DMA 0"); | |
9944 | - case XFER_PIO_4: return("PIO 4"); | |
9945 | - case XFER_PIO_3: return("PIO 3"); | |
9946 | - case XFER_PIO_2: return("PIO 2"); | |
9947 | - case XFER_PIO_1: return("PIO 1"); | |
9948 | - case XFER_PIO_0: return("PIO 0"); | |
9949 | - case XFER_PIO_SLOW: return("PIO SLOW"); | |
9950 | - default: return("XFER ERROR"); | |
9951 | - } | |
9952 | -} | |
9953 | - | |
9954 | -/* | |
9955 | - * | |
9956 | - */ | |
9957 | -char *ide_media_verbose (ide_drive_t *drive) | |
9958 | -{ | |
9959 | - switch (drive->media) { | |
9960 | - case ide_scsi: return("scsi "); | |
9961 | - case ide_disk: return("disk "); | |
9962 | - case ide_optical: return("optical"); | |
9963 | - case ide_cdrom: return("cdrom "); | |
9964 | - case ide_tape: return("tape "); | |
9965 | - case ide_floppy: return("floppy "); | |
9966 | - default: return("???????"); | |
9967 | - } | |
9968 | -} | |
9969 | - | |
9970 | -/* | |
9971 | - * A Verbose noise maker for debugging on the attempted dmaing calls. | |
9972 | - */ | |
9973 | -char *ide_dmafunc_verbose (ide_dma_action_t dmafunc) | |
9974 | -{ | |
9975 | - switch (dmafunc) { | |
9976 | - case ide_dma_read: return("ide_dma_read"); | |
9977 | - case ide_dma_write: return("ide_dma_write"); | |
9978 | - case ide_dma_begin: return("ide_dma_begin"); | |
9979 | - case ide_dma_end: return("ide_dma_end:"); | |
9980 | - case ide_dma_check: return("ide_dma_check"); | |
9981 | - case ide_dma_on: return("ide_dma_on"); | |
9982 | - case ide_dma_off: return("ide_dma_off"); | |
9983 | - case ide_dma_off_quietly: return("ide_dma_off_quietly"); | |
9984 | - case ide_dma_test_irq: return("ide_dma_test_irq"); | |
9985 | - case ide_dma_bad_drive: return("ide_dma_bad_drive"); | |
9986 | - case ide_dma_good_drive: return("ide_dma_good_drive"); | |
9987 | - case ide_dma_verbose: return("ide_dma_verbose"); | |
9988 | - case ide_dma_retune: return("ide_dma_retune"); | |
9989 | - case ide_dma_lostirq: return("ide_dma_lostirq"); | |
9990 | - case ide_dma_timeout: return("ide_dma_timeout"); | |
9991 | - default: return("unknown"); | |
9992 | - } | |
9993 | -} | |
9994 | - | |
9995 | -/* | |
9996 | - * | |
9997 | - */ | |
9998 | -byte ide_auto_reduce_xfer (ide_drive_t *drive) | |
9999 | -{ | |
10000 | - if (!drive->crc_count) | |
10001 | - return drive->current_speed; | |
10002 | - drive->crc_count = 0; | |
10003 | - | |
10004 | - switch(drive->current_speed) { | |
10005 | - case XFER_UDMA_7: return XFER_UDMA_6; | |
10006 | - case XFER_UDMA_6: return XFER_UDMA_5; | |
10007 | - case XFER_UDMA_5: return XFER_UDMA_4; | |
10008 | - case XFER_UDMA_4: return XFER_UDMA_3; | |
10009 | - case XFER_UDMA_3: return XFER_UDMA_2; | |
10010 | - case XFER_UDMA_2: return XFER_UDMA_1; | |
10011 | - case XFER_UDMA_1: return XFER_UDMA_0; | |
10012 | - case XFER_UDMA_0: | |
10013 | - if (drive->id->dma_mword & 0x0004) return XFER_MW_DMA_2; | |
10014 | - else if (drive->id->dma_mword & 0x0002) return XFER_MW_DMA_1; | |
10015 | - else if (drive->id->dma_mword & 0x0001) return XFER_MW_DMA_0; | |
10016 | - else return XFER_PIO_4; | |
10017 | - case XFER_MW_DMA_2: return XFER_MW_DMA_1; | |
10018 | - case XFER_MW_DMA_1: return XFER_MW_DMA_0; | |
10019 | - case XFER_MW_DMA_0: | |
10020 | - if (drive->id->dma_1word & 0x0004) return XFER_SW_DMA_2; | |
10021 | - else if (drive->id->dma_1word & 0x0002) return XFER_SW_DMA_1; | |
10022 | - else if (drive->id->dma_1word & 0x0001) return XFER_SW_DMA_0; | |
10023 | - else return XFER_PIO_4; | |
10024 | - case XFER_SW_DMA_2: return XFER_SW_DMA_1; | |
10025 | - case XFER_SW_DMA_1: return XFER_SW_DMA_0; | |
10026 | - case XFER_SW_DMA_0: | |
10027 | - { | |
10028 | - return XFER_PIO_4; | |
10029 | - } | |
10030 | - case XFER_PIO_4: return XFER_PIO_3; | |
10031 | - case XFER_PIO_3: return XFER_PIO_2; | |
10032 | - case XFER_PIO_2: return XFER_PIO_1; | |
10033 | - case XFER_PIO_1: return XFER_PIO_0; | |
10034 | - case XFER_PIO_0: | |
10035 | - default: return XFER_PIO_SLOW; | |
10036 | - } | |
10037 | -} | |
10038 | - | |
10039 | -/* | |
10040 | - * Update the | |
10041 | - */ | |
10042 | -int ide_driveid_update (ide_drive_t *drive) | |
10043 | -{ | |
10044 | - /* | |
10045 | - * Re-read drive->id for possible DMA mode | |
10046 | - * change (copied from ide-probe.c) | |
10047 | - */ | |
10048 | - struct hd_driveid *id; | |
10049 | - unsigned long timeout, flags; | |
10050 | - | |
10051 | - SELECT_MASK(HWIF(drive), drive, 1); | |
10052 | - if (IDE_CONTROL_REG) | |
10053 | - OUT_BYTE(drive->ctl,IDE_CONTROL_REG); | |
10054 | - ide_delay_50ms(); | |
10055 | - OUT_BYTE(WIN_IDENTIFY, IDE_COMMAND_REG); | |
10056 | - timeout = jiffies + WAIT_WORSTCASE; | |
10057 | - do { | |
10058 | - if (0 < (signed long)(jiffies - timeout)) { | |
10059 | - SELECT_MASK(HWIF(drive), drive, 0); | |
10060 | - return 0; /* drive timed-out */ | |
10061 | - } | |
10062 | - ide_delay_50ms(); /* give drive a breather */ | |
10063 | - } while (IN_BYTE(IDE_ALTSTATUS_REG) & BUSY_STAT); | |
10064 | - ide_delay_50ms(); /* wait for IRQ and DRQ_STAT */ | |
10065 | - if (!OK_STAT(GET_STAT(),DRQ_STAT,BAD_R_STAT)) { | |
10066 | - SELECT_MASK(HWIF(drive), drive, 0); | |
10067 | - printk("%s: CHECK for good STATUS\n", drive->name); | |
10068 | - return 0; | |
10069 | - } | |
10070 | - __save_flags(flags); /* local CPU only */ | |
10071 | - __cli(); /* local CPU only; some systems need this */ | |
10072 | - SELECT_MASK(HWIF(drive), drive, 0); | |
10073 | - id = kmalloc(SECTOR_WORDS*4, GFP_ATOMIC); | |
10074 | - if (!id) { | |
10075 | - __restore_flags(flags); /* local CPU only */ | |
10076 | - return 0; | |
10077 | - } | |
10078 | - ide_input_data(drive, id, SECTOR_WORDS); | |
10079 | - (void) GET_STAT(); /* clear drive IRQ */ | |
10080 | - ide__sti(); /* local CPU only */ | |
10081 | - __restore_flags(flags); /* local CPU only */ | |
10082 | - ide_fix_driveid(id); | |
10083 | - if (id) { | |
10084 | - drive->id->dma_ultra = id->dma_ultra; | |
10085 | - drive->id->dma_mword = id->dma_mword; | |
10086 | - drive->id->dma_1word = id->dma_1word; | |
10087 | - /* anything more ? */ | |
10088 | - kfree(id); | |
10089 | - } | |
10090 | - | |
10091 | - return 1; | |
10092 | -} | |
10093 | - | |
10094 | -/* | |
10095 | - * Verify that we are doing an approved SETFEATURES_XFER with respect | |
10096 | - * to the hardware being able to support request. Since some hardware | |
10097 | - * can improperly report capabilties, we check to see if the host adapter | |
10098 | - * in combination with the device (usually a disk) properly detect | |
10099 | - * and acknowledge each end of the ribbon. | |
10100 | - */ | |
10101 | -int ide_ata66_check (ide_drive_t *drive, byte cmd, byte nsect, byte feature) | |
10102 | -{ | |
10103 | - if ((cmd == WIN_SETFEATURES) && | |
10104 | - (nsect > XFER_UDMA_2) && | |
10105 | - (feature == SETFEATURES_XFER)) { | |
10106 | - if (!HWIF(drive)->udma_four) { | |
10107 | - printk("%s: Speed warnings UDMA 3/4/5 is not functional.\n", HWIF(drive)->name); | |
10108 | - return 1; | |
10109 | - } | |
10110 | -#ifndef CONFIG_IDEDMA_IVB | |
10111 | - if ((drive->id->hw_config & 0x6000) == 0) { | |
10112 | -#else /* !CONFIG_IDEDMA_IVB */ | |
10113 | - if (((drive->id->hw_config & 0x2000) == 0) || | |
10114 | - ((drive->id->hw_config & 0x4000) == 0)) { | |
10115 | -#endif /* CONFIG_IDEDMA_IVB */ | |
10116 | - printk("%s: Speed warnings UDMA 3/4/5 is not functional.\n", drive->name); | |
10117 | - return 1; | |
10118 | - } | |
10119 | - } | |
10120 | - return 0; | |
10121 | -} | |
10122 | - | |
10123 | -/* | |
10124 | - * Backside of HDIO_DRIVE_CMD call of SETFEATURES_XFER. | |
10125 | - * 1 : Safe to update drive->id DMA registers. | |
10126 | - * 0 : OOPs not allowed. | |
10127 | - */ | |
10128 | -int set_transfer (ide_drive_t *drive, byte cmd, byte nsect, byte feature) | |
10129 | -{ | |
10130 | - if ((cmd == WIN_SETFEATURES) && | |
10131 | - (nsect >= XFER_SW_DMA_0) && | |
10132 | - (feature == SETFEATURES_XFER) && | |
10133 | - (drive->id->dma_ultra || | |
10134 | - drive->id->dma_mword || | |
10135 | - drive->id->dma_1word)) | |
10136 | - return 1; | |
10137 | - | |
10138 | - return 0; | |
10139 | -} | |
10140 | - | |
10141 | -/* | |
10142 | - * All hosts that use the 80c ribbon mus use! | |
10143 | - */ | |
10144 | -byte eighty_ninty_three (ide_drive_t *drive) | |
10145 | -{ | |
10146 | - return ((byte) ((HWIF(drive)->udma_four) && | |
10147 | -#ifndef CONFIG_IDEDMA_IVB | |
10148 | - (drive->id->hw_config & 0x4000) && | |
10149 | -#endif /* CONFIG_IDEDMA_IVB */ | |
10150 | - (drive->id->hw_config & 0x6000)) ? 1 : 0); | |
10151 | -} | |
10152 | - | |
10153 | -/* | |
10154 | - * Similar to ide_wait_stat(), except it never calls ide_error internally. | |
10155 | - * This is a kludge to handle the new ide_config_drive_speed() function, | |
10156 | - * and should not otherwise be used anywhere. Eventually, the tuneproc's | |
10157 | - * should be updated to return ide_startstop_t, in which case we can get | |
10158 | - * rid of this abomination again. :) -ml | |
10159 | - * | |
10160 | - * It is gone.......... | |
10161 | - * | |
10162 | - * const char *msg == consider adding for verbose errors. | |
10163 | - */ | |
10164 | -int ide_config_drive_speed (ide_drive_t *drive, byte speed) | |
10165 | -{ | |
10166 | - ide_hwif_t *hwif = HWIF(drive); | |
10167 | - int i, error = 1; | |
10168 | - byte stat; | |
10169 | - | |
10170 | -#if defined(CONFIG_BLK_DEV_IDEDMA) && !defined(CONFIG_DMA_NONPCI) | |
10171 | - byte unit = (drive->select.b.unit & 0x01); | |
10172 | - outb(inb(hwif->dma_base+2) & ~(1<<(5+unit)), hwif->dma_base+2); | |
10173 | -#endif /* (CONFIG_BLK_DEV_IDEDMA) && !(CONFIG_DMA_NONPCI) */ | |
10174 | - | |
10175 | - /* | |
10176 | - * Don't use ide_wait_cmd here - it will | |
10177 | - * attempt to set_geometry and recalibrate, | |
10178 | - * but for some reason these don't work at | |
10179 | - * this point (lost interrupt). | |
10180 | - */ | |
10181 | - /* | |
10182 | - * Select the drive, and issue the SETFEATURES command | |
10183 | - */ | |
10184 | - disable_irq(hwif->irq); /* disable_irq_nosync ?? */ | |
10185 | - udelay(1); | |
10186 | - SELECT_DRIVE(HWIF(drive), drive); | |
10187 | - SELECT_MASK(HWIF(drive), drive, 0); | |
10188 | - udelay(1); | |
10189 | - if (IDE_CONTROL_REG) | |
10190 | - OUT_BYTE(drive->ctl | 2, IDE_CONTROL_REG); | |
10191 | - OUT_BYTE(speed, IDE_NSECTOR_REG); | |
10192 | - OUT_BYTE(SETFEATURES_XFER, IDE_FEATURE_REG); | |
10193 | - OUT_BYTE(WIN_SETFEATURES, IDE_COMMAND_REG); | |
10194 | - if ((IDE_CONTROL_REG) && (drive->quirk_list == 2)) | |
10195 | - OUT_BYTE(drive->ctl, IDE_CONTROL_REG); | |
10196 | - udelay(1); | |
10197 | - /* | |
10198 | - * Wait for drive to become non-BUSY | |
10199 | - */ | |
10200 | - if ((stat = GET_STAT()) & BUSY_STAT) { | |
10201 | - unsigned long flags, timeout; | |
10202 | - __save_flags(flags); /* local CPU only */ | |
10203 | - ide__sti(); /* local CPU only -- for jiffies */ | |
10204 | - timeout = jiffies + WAIT_CMD; | |
10205 | - while ((stat = GET_STAT()) & BUSY_STAT) { | |
10206 | - if (0 < (signed long)(jiffies - timeout)) | |
10207 | - break; | |
10208 | - } | |
10209 | - __restore_flags(flags); /* local CPU only */ | |
10210 | - } | |
10211 | - | |
10212 | - /* | |
10213 | - * Allow status to settle, then read it again. | |
10214 | - * A few rare drives vastly violate the 400ns spec here, | |
10215 | - * so we'll wait up to 10usec for a "good" status | |
10216 | - * rather than expensively fail things immediately. | |
10217 | - * This fix courtesy of Matthew Faupel & Niccolo Rigacci. | |
10218 | - */ | |
10219 | - for (i = 0; i < 10; i++) { | |
10220 | - udelay(1); | |
10221 | - if (OK_STAT((stat = GET_STAT()), DRIVE_READY, BUSY_STAT|DRQ_STAT|ERR_STAT)) { | |
10222 | - error = 0; | |
10223 | - break; | |
10224 | - } | |
10225 | - } | |
10226 | - | |
10227 | - SELECT_MASK(HWIF(drive), drive, 0); | |
10228 | - | |
10229 | - enable_irq(hwif->irq); | |
10230 | - | |
10231 | - if (error) { | |
10232 | - (void) ide_dump_status(drive, "set_drive_speed_status", stat); | |
10233 | - return error; | |
10234 | - } | |
10235 | - | |
10236 | - drive->id->dma_ultra &= ~0xFF00; | |
10237 | - drive->id->dma_mword &= ~0x0F00; | |
10238 | - drive->id->dma_1word &= ~0x0F00; | |
10239 | - | |
10240 | -#if defined(CONFIG_BLK_DEV_IDEDMA) && !defined(CONFIG_DMA_NONPCI) | |
10241 | - if (speed > XFER_PIO_4) { | |
10242 | - outb(inb(hwif->dma_base+2)|(1<<(5+unit)), hwif->dma_base+2); | |
10243 | - } else { | |
10244 | - outb(inb(hwif->dma_base+2) & ~(1<<(5+unit)), hwif->dma_base+2); | |
10245 | - } | |
10246 | -#endif /* (CONFIG_BLK_DEV_IDEDMA) && !(CONFIG_DMA_NONPCI) */ | |
10247 | - | |
10248 | - switch(speed) { | |
10249 | - case XFER_UDMA_7: drive->id->dma_ultra |= 0x8080; break; | |
10250 | - case XFER_UDMA_6: drive->id->dma_ultra |= 0x4040; break; | |
10251 | - case XFER_UDMA_5: drive->id->dma_ultra |= 0x2020; break; | |
10252 | - case XFER_UDMA_4: drive->id->dma_ultra |= 0x1010; break; | |
10253 | - case XFER_UDMA_3: drive->id->dma_ultra |= 0x0808; break; | |
10254 | - case XFER_UDMA_2: drive->id->dma_ultra |= 0x0404; break; | |
10255 | - case XFER_UDMA_1: drive->id->dma_ultra |= 0x0202; break; | |
10256 | - case XFER_UDMA_0: drive->id->dma_ultra |= 0x0101; break; | |
10257 | - case XFER_MW_DMA_2: drive->id->dma_mword |= 0x0404; break; | |
10258 | - case XFER_MW_DMA_1: drive->id->dma_mword |= 0x0202; break; | |
10259 | - case XFER_MW_DMA_0: drive->id->dma_mword |= 0x0101; break; | |
10260 | - case XFER_SW_DMA_2: drive->id->dma_1word |= 0x0404; break; | |
10261 | - case XFER_SW_DMA_1: drive->id->dma_1word |= 0x0202; break; | |
10262 | - case XFER_SW_DMA_0: drive->id->dma_1word |= 0x0101; break; | |
10263 | - default: break; | |
10264 | - } | |
10265 | - return error; | |
10266 | -} | |
10267 | - | |
10268 | -EXPORT_SYMBOL(ide_auto_reduce_xfer); | |
10269 | -EXPORT_SYMBOL(ide_driveid_update); | |
10270 | -EXPORT_SYMBOL(ide_ata66_check); | |
10271 | -EXPORT_SYMBOL(set_transfer); | |
10272 | -EXPORT_SYMBOL(eighty_ninty_three); | |
10273 | -EXPORT_SYMBOL(ide_config_drive_speed); | |
10274 | diff -Nur linux.org/drivers/ide/ide-floppy.c linux/drivers/ide/ide-floppy.c | |
10275 | --- linux.org/drivers/ide/ide-floppy.c Fri Dec 21 18:41:54 2001 | |
10276 | +++ linux/drivers/ide/ide-floppy.c Thu Jul 18 14:24:33 2002 | |
10277 | @@ -1,8 +1,8 @@ | |
10278 | /* | |
10279 | - * linux/drivers/ide/ide-floppy.c Version 0.97.sv Jan 14 2001 | |
10280 | + * linux/drivers/ide/ide-floppy.c Version 0.99 Feb 24 2002 | |
10281 | * | |
10282 | * Copyright (C) 1996 - 1999 Gadi Oxman <gadio@netvision.net.il> | |
10283 | - * Copyright (C) 2000 - 2001 Paul Bristow <paul@paulbristow.net> | |
10284 | + * Copyright (C) 2000 - 2002 Paul Bristow <paul@paulbristow.net> | |
10285 | */ | |
10286 | ||
10287 | /* | |
10288 | @@ -13,7 +13,7 @@ | |
10289 | * | |
10290 | * This driver supports the following IDE floppy drives: | |
10291 | * | |
10292 | - * LS-120 SuperDisk | |
10293 | + * LS-120/240 SuperDisk | |
10294 | * Iomega Zip 100/250 | |
10295 | * Iomega PC Card Clik!/PocketZip | |
10296 | * | |
10297 | @@ -68,12 +68,19 @@ | |
10298 | * Ver 0.94 Oct 27 00 Tidied up to remove strstr(Clik) everywhere | |
10299 | * Ver 0.95 Nov 7 00 Brought across to kernel 2.4 | |
10300 | * Ver 0.96 Jan 7 01 Actually in line with release version of 2.4.0 | |
10301 | - * including set_bit patch from Rusty Russel | |
10302 | + * including set_bit patch from Rusty Russell | |
10303 | * Ver 0.97 Jul 22 01 Merge 0.91-0.96 onto 0.9.sv for ac series | |
10304 | * Ver 0.97.sv Aug 3 01 Backported from 2.4.7-ac3 | |
10305 | + * Ver 0.98 Oct 26 01 Split idefloppy_transfer_pc into two pieces to | |
10306 | + * fix a lost interrupt problem. It appears the busy | |
10307 | + * bit was being deasserted by my IOMEGA ATAPI ZIP 100 | |
10308 | + * drive before the drive was actually ready. | |
10309 | + * Ver 0.98a Oct 29 01 Expose delay value so we can play. | |
10310 | + * Ver 0.99 Feb 24 02 Remove duplicate code, modify clik! detection code | |
10311 | + * to support new PocketZip drives | |
10312 | */ | |
10313 | ||
10314 | -#define IDEFLOPPY_VERSION "0.97.sv" | |
10315 | +#define IDEFLOPPY_VERSION "0.99.newide" | |
10316 | ||
10317 | #include <linux/config.h> | |
10318 | #include <linux/module.h> | |
10319 | @@ -276,6 +283,7 @@ | |
10320 | * Last error information | |
10321 | */ | |
10322 | byte sense_key, asc, ascq; | |
10323 | + byte ticks; /* delay this long before sending packet command */ | |
10324 | int progress_indication; | |
10325 | ||
10326 | /* | |
10327 | @@ -289,6 +297,8 @@ | |
10328 | unsigned long flags; /* Status/Action flags */ | |
10329 | } idefloppy_floppy_t; | |
10330 | ||
10331 | +#define IDEFLOPPY_TICKS_DELAY 3 /* default delay for ZIP 100 */ | |
10332 | + | |
10333 | /* | |
10334 | * Floppy flag bits values. | |
10335 | */ | |
10336 | @@ -297,7 +307,7 @@ | |
10337 | #define IDEFLOPPY_USE_READ12 2 /* Use READ12/WRITE12 or READ10/WRITE10 */ | |
10338 | #define IDEFLOPPY_FORMAT_IN_PROGRESS 3 /* Format in progress */ | |
10339 | #define IDEFLOPPY_CLIK_DRIVE 4 /* Avoid commands not supported in Clik drive */ | |
10340 | - | |
10341 | +#define IDEFLOPPY_ZIP_DRIVE 5 /* Requires BH algorithm for packets */ | |
10342 | ||
10343 | /* | |
10344 | * ATAPI floppy drive packet commands | |
10345 | @@ -658,28 +668,57 @@ | |
10346 | static void idefloppy_discard_data (ide_drive_t *drive, unsigned int bcount) | |
10347 | { | |
10348 | while (bcount--) | |
10349 | - IN_BYTE (IDE_DATA_REG); | |
10350 | + IN_BYTE(IDE_DATA_REG); | |
10351 | } | |
10352 | ||
10353 | #if IDEFLOPPY_DEBUG_BUGS | |
10354 | static void idefloppy_write_zeros (ide_drive_t *drive, unsigned int bcount) | |
10355 | { | |
10356 | while (bcount--) | |
10357 | - OUT_BYTE (0, IDE_DATA_REG); | |
10358 | + OUT_BYTE(0, IDE_DATA_REG); | |
10359 | } | |
10360 | #endif /* IDEFLOPPY_DEBUG_BUGS */ | |
10361 | ||
10362 | + | |
10363 | +static int idefloppy_end_request (ide_drive_t *drive, int uptodate) | |
10364 | +{ | |
10365 | + struct request *rq; | |
10366 | + unsigned long flags; | |
10367 | + int ret = 1; | |
10368 | + | |
10369 | + spin_lock_irqsave(&io_request_lock, flags); | |
10370 | + rq = HWGROUP(drive)->rq; | |
10371 | + | |
10372 | + /* | |
10373 | + * decide whether to reenable DMA -- 3 is a random magic for now, | |
10374 | + * if we DMA timeout more than 3 times, just stay in PIO | |
10375 | + */ | |
10376 | + if (drive->state == DMA_PIO_RETRY && drive->retry_pio <= 3) { | |
10377 | + drive->state = 0; | |
10378 | + HWGROUP(drive)->hwif->dmaproc(ide_dma_on, drive); | |
10379 | + } | |
10380 | + | |
10381 | + if (!end_that_request_first(rq, uptodate, drive->name)) { | |
10382 | + add_blkdev_randomness(MAJOR(rq->rq_dev)); | |
10383 | + blkdev_dequeue_request(rq); | |
10384 | + HWGROUP(drive)->rq = NULL; | |
10385 | + end_that_request_last(rq); | |
10386 | + ret = 0; | |
10387 | + } | |
10388 | + spin_unlock_irqrestore(&io_request_lock, flags); | |
10389 | + return ret; | |
10390 | +} | |
10391 | + | |
10392 | /* | |
10393 | - * idefloppy_end_request is used to finish servicing a request. | |
10394 | + * idefloppy_do_end_request is used to finish servicing a request. | |
10395 | * | |
10396 | * For read/write requests, we will call ide_end_request to pass to the | |
10397 | * next buffer. | |
10398 | */ | |
10399 | -static void idefloppy_end_request (byte uptodate, ide_hwgroup_t *hwgroup) | |
10400 | +static int idefloppy_do_end_request (ide_drive_t *drive, int uptodate) | |
10401 | { | |
10402 | - ide_drive_t *drive = hwgroup->drive; | |
10403 | idefloppy_floppy_t *floppy = drive->driver_data; | |
10404 | - struct request *rq = hwgroup->rq; | |
10405 | + struct request *rq = HWGROUP(drive)->rq; | |
10406 | int error; | |
10407 | ||
10408 | #if IDEFLOPPY_DEBUG_LOG | |
10409 | @@ -695,13 +734,16 @@ | |
10410 | floppy->failed_pc = NULL; | |
10411 | /* Why does this happen? */ | |
10412 | if (!rq) | |
10413 | - return; | |
10414 | + return 0; | |
10415 | if (!IDEFLOPPY_RQ_CMD (rq->cmd)) { | |
10416 | - ide_end_request (uptodate, hwgroup); | |
10417 | - return; | |
10418 | + /* our real local end request function */ | |
10419 | + idefloppy_end_request(drive, uptodate); | |
10420 | + return 0; | |
10421 | } | |
10422 | rq->errors = error; | |
10423 | + /* fixme: need to move this local also */ | |
10424 | ide_end_drive_cmd (drive, 0, 0); | |
10425 | + return 0; | |
10426 | } | |
10427 | ||
10428 | static void idefloppy_input_buffers (ide_drive_t *drive, idefloppy_pc_t *pc, unsigned int bcount) | |
10429 | @@ -714,7 +756,7 @@ | |
10430 | if (pc->b_count == bh->b_size) { | |
10431 | rq->sector += rq->current_nr_sectors; | |
10432 | rq->nr_sectors -= rq->current_nr_sectors; | |
10433 | - idefloppy_end_request (1, HWGROUP(drive)); | |
10434 | + idefloppy_do_end_request(drive, 1); | |
10435 | if ((bh = rq->bh) != NULL) | |
10436 | pc->b_count = 0; | |
10437 | } | |
10438 | @@ -739,7 +781,7 @@ | |
10439 | if (!pc->b_count) { | |
10440 | rq->sector += rq->current_nr_sectors; | |
10441 | rq->nr_sectors -= rq->current_nr_sectors; | |
10442 | - idefloppy_end_request (1, HWGROUP(drive)); | |
10443 | + idefloppy_do_end_request(drive, 1); | |
10444 | if ((bh = rq->bh) != NULL) { | |
10445 | pc->b_data = bh->b_data; | |
10446 | pc->b_count = bh->b_size; | |
10447 | @@ -763,7 +805,7 @@ | |
10448 | struct buffer_head *bh = rq->bh; | |
10449 | ||
10450 | while ((bh = rq->bh) != NULL) | |
10451 | - idefloppy_end_request (1, HWGROUP(drive)); | |
10452 | + idefloppy_do_end_request(drive, 1); | |
10453 | } | |
10454 | #endif /* CONFIG_BLK_DEV_IDEDMA */ | |
10455 | ||
10456 | @@ -826,10 +868,10 @@ | |
10457 | #endif /* IDEFLOPPY_DEBUG_LOG */ | |
10458 | if (!floppy->pc->error) { | |
10459 | idefloppy_analyze_error (drive,(idefloppy_request_sense_result_t *) floppy->pc->buffer); | |
10460 | - idefloppy_end_request (1,HWGROUP (drive)); | |
10461 | + idefloppy_do_end_request(drive, 1); | |
10462 | } else { | |
10463 | printk (KERN_ERR "Error in REQUEST SENSE itself - Aborting request!\n"); | |
10464 | - idefloppy_end_request (0,HWGROUP (drive)); | |
10465 | + idefloppy_do_end_request(drive, 0); | |
10466 | } | |
10467 | } | |
10468 | ||
10469 | @@ -844,7 +886,7 @@ | |
10470 | printk (KERN_INFO "ide-floppy: Reached idefloppy_pc_callback\n"); | |
10471 | #endif /* IDEFLOPPY_DEBUG_LOG */ | |
10472 | ||
10473 | - idefloppy_end_request (floppy->pc->error ? 0:1, HWGROUP(drive)); | |
10474 | + idefloppy_do_end_request(drive, floppy->pc->error ? 0 : 1); | |
10475 | } | |
10476 | ||
10477 | /* | |
10478 | @@ -929,7 +971,7 @@ | |
10479 | #endif /* IDEFLOPPY_DEBUG_LOG */ | |
10480 | clear_bit (PC_DMA_IN_PROGRESS, &pc->flags); | |
10481 | ||
10482 | - ide__sti(); /* local CPU only */ | |
10483 | + local_irq_enable(); | |
10484 | ||
10485 | if (status.b.check || test_bit (PC_DMA_ERROR, &pc->flags)) { /* Error detected */ | |
10486 | #if IDEFLOPPY_DEBUG_LOG | |
10487 | @@ -975,7 +1017,9 @@ | |
10488 | if (temp > pc->buffer_size) { | |
10489 | printk (KERN_ERR "ide-floppy: The floppy wants to send us more data than expected - discarding data\n"); | |
10490 | idefloppy_discard_data (drive,bcount.all); | |
10491 | - ide_set_handler (drive,&idefloppy_pc_intr,IDEFLOPPY_WAIT_CMD, NULL); | |
10492 | + if (HWGROUP(drive)->handler != NULL) | |
10493 | + BUG(); | |
10494 | + ide_set_handler(drive, &idefloppy_pc_intr, IDEFLOPPY_WAIT_CMD, NULL); | |
10495 | return ide_started; | |
10496 | } | |
10497 | #if IDEFLOPPY_DEBUG_LOG | |
10498 | @@ -997,10 +1041,17 @@ | |
10499 | pc->actually_transferred+=bcount.all; /* Update the current position */ | |
10500 | pc->current_position+=bcount.all; | |
10501 | ||
10502 | - ide_set_handler (drive,&idefloppy_pc_intr,IDEFLOPPY_WAIT_CMD, NULL); /* And set the interrupt handler again */ | |
10503 | + if (HWGROUP(drive)->handler != NULL) | |
10504 | + BUG(); | |
10505 | + ide_set_handler(drive, &idefloppy_pc_intr, IDEFLOPPY_WAIT_CMD, NULL); /* And set the interrupt handler again */ | |
10506 | return ide_started; | |
10507 | } | |
10508 | ||
10509 | +/* | |
10510 | + * This is the original routine that did the packet transfer. | |
10511 | + * It fails at high speeds on the Iomega ZIP drive, so there's a slower version | |
10512 | + * for that drive below. The algorithm is chosen based on drive type | |
10513 | + */ | |
10514 | static ide_startstop_t idefloppy_transfer_pc (ide_drive_t *drive) | |
10515 | { | |
10516 | ide_startstop_t startstop; | |
10517 | @@ -1008,19 +1059,77 @@ | |
10518 | idefloppy_ireason_reg_t ireason; | |
10519 | ||
10520 | if (ide_wait_stat (&startstop,drive,DRQ_STAT,BUSY_STAT,WAIT_READY)) { | |
10521 | - printk (KERN_ERR "ide-floppy: Strange, packet command initiated yet DRQ isn't asserted\n"); | |
10522 | + printk(KERN_ERR "ide-floppy: Strange, packet command " | |
10523 | + "initiated yet DRQ isn't asserted\n"); | |
10524 | return startstop; | |
10525 | } | |
10526 | - ireason.all=IN_BYTE (IDE_IREASON_REG); | |
10527 | + ireason.all = IN_BYTE(IDE_IREASON_REG); | |
10528 | if (!ireason.b.cod || ireason.b.io) { | |
10529 | - printk (KERN_ERR "ide-floppy: (IO,CoD) != (0,1) while issuing a packet command\n"); | |
10530 | + printk(KERN_ERR "ide-floppy: (IO,CoD) != (0,1) while " | |
10531 | + "issuing a packet command\n"); | |
10532 | return ide_do_reset (drive); | |
10533 | } | |
10534 | - ide_set_handler (drive, &idefloppy_pc_intr, IDEFLOPPY_WAIT_CMD, NULL); /* Set the interrupt routine */ | |
10535 | + if (HWGROUP(drive)->handler != NULL) | |
10536 | + BUG(); | |
10537 | + ide_set_handler(drive, &idefloppy_pc_intr, IDEFLOPPY_WAIT_CMD, NULL); /* Set the interrupt routine */ | |
10538 | atapi_output_bytes (drive, floppy->pc->c, 12); /* Send the actual packet */ | |
10539 | return ide_started; | |
10540 | } | |
10541 | ||
10542 | + | |
10543 | +/* | |
10544 | + * What we have here is a classic case of a top half / bottom half | |
10545 | + * interrupt service routine. In interrupt mode, the device sends | |
10546 | + * an interrupt to signal it's ready to receive a packet. However, | |
10547 | + * we need to delay about 2-3 ticks before issuing the packet or we | |
10548 | + * gets in trouble. | |
10549 | + * | |
10550 | + * So, follow carefully. transfer_pc1 is called as an interrupt (or | |
10551 | + * directly). In either case, when the device says it's ready for a | |
10552 | + * packet, we schedule the packet transfer to occur about 2-3 ticks | |
10553 | + * later in transfer_pc2. | |
10554 | + */ | |
10555 | +static int idefloppy_transfer_pc2 (ide_drive_t *drive) | |
10556 | +{ | |
10557 | + idefloppy_floppy_t *floppy = drive->driver_data; | |
10558 | + | |
10559 | + atapi_output_bytes(drive, floppy->pc->c, 12); /* Send the actual packet */ | |
10560 | + return IDEFLOPPY_WAIT_CMD; /* Timeout for the packet command */ | |
10561 | +} | |
10562 | + | |
10563 | +static ide_startstop_t idefloppy_transfer_pc1 (ide_drive_t *drive) | |
10564 | +{ | |
10565 | + idefloppy_floppy_t *floppy = drive->driver_data; | |
10566 | + ide_startstop_t startstop; | |
10567 | + idefloppy_ireason_reg_t ireason; | |
10568 | + | |
10569 | + if (ide_wait_stat (&startstop,drive,DRQ_STAT,BUSY_STAT,WAIT_READY)) { | |
10570 | + printk(KERN_ERR "ide-floppy: Strange, packet command " | |
10571 | + "initiated yet DRQ isn't asserted\n"); | |
10572 | + return startstop; | |
10573 | + } | |
10574 | + ireason.all = IN_BYTE(IDE_IREASON_REG); | |
10575 | + if (!ireason.b.cod || ireason.b.io) { | |
10576 | + printk(KERN_ERR "ide-floppy: (IO,CoD) != (0,1) " | |
10577 | + "while issuing a packet command\n"); | |
10578 | + return ide_do_reset (drive); | |
10579 | + } | |
10580 | + /* | |
10581 | + * The following delay solves a problem with ATAPI Zip 100 drives where the | |
10582 | + * Busy flag was apparently being deasserted before the unit was ready to | |
10583 | + * receive data. This was happening on a 1200 MHz Athlon system. 10/26/01 | |
10584 | + * 25msec is too short, 40 and 50msec work well. idefloppy_pc_intr will | |
10585 | + * not be actually used until after the packet is moved in about 50 msec. | |
10586 | + */ | |
10587 | + if (HWGROUP(drive)->handler != NULL) | |
10588 | + BUG(); | |
10589 | + ide_set_handler(drive, | |
10590 | + &idefloppy_pc_intr, /* service routine for packet command */ | |
10591 | + floppy->ticks, /* wait this long before "failing" */ | |
10592 | + &idefloppy_transfer_pc2); /* fail == transfer_pc2 */ | |
10593 | + return ide_started; | |
10594 | +} | |
10595 | + | |
10596 | /* | |
10597 | * Issue a packet command | |
10598 | */ | |
10599 | @@ -1029,6 +1138,7 @@ | |
10600 | idefloppy_floppy_t *floppy = drive->driver_data; | |
10601 | idefloppy_bcount_reg_t bcount; | |
10602 | int dma_ok = 0; | |
10603 | + ide_handler_t *pkt_xfer_routine; | |
10604 | ||
10605 | #if IDEFLOPPY_DEBUG_BUGS | |
10606 | if (floppy->pc->c[0] == IDEFLOPPY_REQUEST_SENSE_CMD && pc->c[0] == IDEFLOPPY_REQUEST_SENSE_CMD) { | |
10607 | @@ -1048,10 +1158,15 @@ | |
10608 | if (!test_bit (PC_ABORT, &pc->flags)) { | |
10609 | if (!test_bit (PC_SUPPRESS_ERROR, &pc->flags)) { | |
10610 | ; | |
10611 | - printk( KERN_ERR "ide-floppy: %s: I/O error, pc = %2x, key = %2x, asc = %2x, ascq = %2x\n", | |
10612 | - drive->name, pc->c[0], floppy->sense_key, floppy->asc, floppy->ascq); | |
10613 | + printk(KERN_ERR "ide-floppy: %s: I/O error, " | |
10614 | + "pc = %2x, key = %2x, " | |
10615 | + "asc = %2x, ascq = %2x\n", | |
10616 | + drive->name, pc->c[0], | |
10617 | + floppy->sense_key, | |
10618 | + floppy->asc, floppy->ascq); | |
10619 | } | |
10620 | - pc->error = IDEFLOPPY_ERROR_GENERAL; /* Giving up */ | |
10621 | + /* Giving up */ | |
10622 | + pc->error = IDEFLOPPY_ERROR_GENERAL; | |
10623 | } | |
10624 | floppy->failed_pc=NULL; | |
10625 | pc->callback(drive); | |
10626 | @@ -1062,7 +1177,7 @@ | |
10627 | #endif /* IDEFLOPPY_DEBUG_LOG */ | |
10628 | ||
10629 | pc->retries++; | |
10630 | - pc->actually_transferred=0; /* We haven't transferred any data yet */ | |
10631 | + pc->actually_transferred=0; /* We haven't transferred any data yet */ | |
10632 | pc->current_position=pc->buffer; | |
10633 | bcount.all = IDE_MIN(pc->request_transfer, 63 * 1024); | |
10634 | ||
10635 | @@ -1075,26 +1190,35 @@ | |
10636 | #endif /* CONFIG_BLK_DEV_IDEDMA */ | |
10637 | ||
10638 | if (IDE_CONTROL_REG) | |
10639 | - OUT_BYTE (drive->ctl,IDE_CONTROL_REG); | |
10640 | - OUT_BYTE (dma_ok ? 1:0,IDE_FEATURE_REG); /* Use PIO/DMA */ | |
10641 | - OUT_BYTE (bcount.b.high,IDE_BCOUNTH_REG); | |
10642 | - OUT_BYTE (bcount.b.low,IDE_BCOUNTL_REG); | |
10643 | - OUT_BYTE (drive->select.all,IDE_SELECT_REG); | |
10644 | + OUT_BYTE(drive->ctl,IDE_CONTROL_REG); | |
10645 | + OUT_BYTE(dma_ok ? 1:0,IDE_FEATURE_REG); /* Use PIO/DMA */ | |
10646 | + OUT_BYTE(bcount.b.high,IDE_BCOUNTH_REG); | |
10647 | + OUT_BYTE(bcount.b.low,IDE_BCOUNTL_REG); | |
10648 | + OUT_BYTE(drive->select.all,IDE_SELECT_REG); | |
10649 | ||
10650 | #ifdef CONFIG_BLK_DEV_IDEDMA | |
10651 | - if (dma_ok) { /* Begin DMA, if necessary */ | |
10652 | + if (dma_ok) { /* Begin DMA, if necessary */ | |
10653 | set_bit (PC_DMA_IN_PROGRESS, &pc->flags); | |
10654 | (void) (HWIF(drive)->dmaproc(ide_dma_begin, drive)); | |
10655 | } | |
10656 | #endif /* CONFIG_BLK_DEV_IDEDMA */ | |
10657 | ||
10658 | + /* Can we transfer the packet when we get the interrupt or wait? */ | |
10659 | + if (test_bit (IDEFLOPPY_ZIP_DRIVE, &floppy->flags)) { | |
10660 | + pkt_xfer_routine = &idefloppy_transfer_pc1; /* wait */ | |
10661 | + } else { | |
10662 | + pkt_xfer_routine = &idefloppy_transfer_pc; /* immediate */ | |
10663 | + } | |
10664 | + | |
10665 | if (test_bit (IDEFLOPPY_DRQ_INTERRUPT, &floppy->flags)) { | |
10666 | - ide_set_handler (drive, &idefloppy_transfer_pc, IDEFLOPPY_WAIT_CMD, NULL); | |
10667 | - OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG); /* Issue the packet command */ | |
10668 | + if (HWGROUP(drive)->handler != NULL) | |
10669 | + BUG(); | |
10670 | + ide_set_handler(drive, pkt_xfer_routine, IDEFLOPPY_WAIT_CMD, NULL); | |
10671 | + OUT_BYTE(WIN_PACKETCMD, IDE_COMMAND_REG); /* Issue the packet command */ | |
10672 | return ide_started; | |
10673 | } else { | |
10674 | - OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG); | |
10675 | - return idefloppy_transfer_pc (drive); | |
10676 | + OUT_BYTE(WIN_PACKETCMD, IDE_COMMAND_REG); | |
10677 | + return (*pkt_xfer_routine) (drive); | |
10678 | } | |
10679 | } | |
10680 | ||
10681 | @@ -1104,7 +1228,7 @@ | |
10682 | printk (KERN_INFO "ide-floppy: Reached idefloppy_rw_callback\n"); | |
10683 | #endif /* IDEFLOPPY_DEBUG_LOG */ | |
10684 | ||
10685 | - idefloppy_end_request(1, HWGROUP(drive)); | |
10686 | + idefloppy_do_end_request(drive, 1); | |
10687 | return; | |
10688 | } | |
10689 | ||
10690 | @@ -1227,25 +1351,33 @@ | |
10691 | idefloppy_pc_t *pc; | |
10692 | ||
10693 | #if IDEFLOPPY_DEBUG_LOG | |
10694 | - printk (KERN_INFO "rq_status: %d, rq_dev: %u, cmd: %d, errors: %d\n",rq->rq_status,(unsigned int) rq->rq_dev,rq->cmd,rq->errors); | |
10695 | - printk (KERN_INFO "sector: %ld, nr_sectors: %ld, current_nr_sectors: %ld\n",rq->sector,rq->nr_sectors,rq->current_nr_sectors); | |
10696 | + printk(KERN_INFO "rq_status: %d, rq_dev: %u, cmd: %d, errors: %d\n", | |
10697 | + rq->rq_status, (unsigned int) rq->rq_dev, rq->cmd, rq->errors); | |
10698 | + printk(KERN_INFO "sector: %ld, nr_sectors: %ld, " | |
10699 | + "current_nr_sectors: %ld\n", rq->sector, | |
10700 | + rq->nr_sectors, rq->current_nr_sectors); | |
10701 | #endif /* IDEFLOPPY_DEBUG_LOG */ | |
10702 | ||
10703 | if (rq->errors >= ERROR_MAX) { | |
10704 | if (floppy->failed_pc != NULL) | |
10705 | - printk (KERN_ERR "ide-floppy: %s: I/O error, pc = %2x, key = %2x, asc = %2x, ascq = %2x\n", | |
10706 | - drive->name, floppy->failed_pc->c[0], floppy->sense_key, floppy->asc, floppy->ascq); | |
10707 | + printk(KERN_ERR "ide-floppy: %s: I/O error, pc = %2x," | |
10708 | + " key = %2x, asc = %2x, ascq = %2x\n", | |
10709 | + drive->name, floppy->failed_pc->c[0], | |
10710 | + floppy->sense_key, floppy->asc, floppy->ascq); | |
10711 | else | |
10712 | - printk (KERN_ERR "ide-floppy: %s: I/O error\n", drive->name); | |
10713 | - idefloppy_end_request (0, HWGROUP(drive)); | |
10714 | + printk(KERN_ERR "ide-floppy: %s: I/O error\n", | |
10715 | + drive->name); | |
10716 | + idefloppy_do_end_request(drive, 0); | |
10717 | return ide_stopped; | |
10718 | } | |
10719 | switch (rq->cmd) { | |
10720 | case READ: | |
10721 | case WRITE: | |
10722 | - if (rq->sector % floppy->bs_factor || rq->nr_sectors % floppy->bs_factor) { | |
10723 | - printk ("%s: unsupported r/w request size\n", drive->name); | |
10724 | - idefloppy_end_request (0, HWGROUP(drive)); | |
10725 | + if (rq->sector % floppy->bs_factor || | |
10726 | + rq->nr_sectors % floppy->bs_factor) { | |
10727 | + printk("%s: unsupported r/w request size\n", | |
10728 | + drive->name); | |
10729 | + idefloppy_do_end_request(drive, 0); | |
10730 | return ide_stopped; | |
10731 | } | |
10732 | pc = idefloppy_next_pc_storage (drive); | |
10733 | @@ -1255,8 +1387,9 @@ | |
10734 | pc = (idefloppy_pc_t *) rq->buffer; | |
10735 | break; | |
10736 | default: | |
10737 | - printk (KERN_ERR "ide-floppy: unsupported command %x in request queue\n", rq->cmd); | |
10738 | - idefloppy_end_request (0,HWGROUP (drive)); | |
10739 | + printk(KERN_ERR "ide-floppy: unsupported command %x" | |
10740 | + " in request queue\n", rq->cmd); | |
10741 | + idefloppy_do_end_request(drive, 0); | |
10742 | return ide_stopped; | |
10743 | } | |
10744 | pc->rq = rq; | |
10745 | @@ -1304,8 +1437,10 @@ | |
10746 | page->rpm = ntohs (page->rpm); | |
10747 | capacity = page->cyls * page->heads * page->sectors * page->sector_size; | |
10748 | if (memcmp (page, &floppy->flexible_disk_page, sizeof (idefloppy_flexible_disk_page_t))) | |
10749 | - printk (KERN_INFO "%s: %dkB, %d/%d/%d CHS, %d kBps, %d sector size, %d rpm\n", | |
10750 | - drive->name, capacity / 1024, page->cyls, page->heads, page->sectors, | |
10751 | + printk(KERN_INFO "%s: %dkB, %d/%d/%d CHS, %d kBps, " | |
10752 | + "%d sector size, %d rpm\n", | |
10753 | + drive->name, capacity / 1024, page->cyls, | |
10754 | + page->heads, page->sectors, | |
10755 | page->transfer_rate / 8, page->sector_size, page->rpm); | |
10756 | ||
10757 | floppy->flexible_disk_page = *page; | |
10758 | @@ -1314,8 +1449,8 @@ | |
10759 | drive->bios_sect = page->sectors; | |
10760 | lba_capacity = floppy->blocks * floppy->block_size; | |
10761 | if (capacity < lba_capacity) { | |
10762 | - printk (KERN_NOTICE "%s: The disk reports a capacity of %d bytes, " | |
10763 | - "but the drive only handles %d\n", | |
10764 | + printk(KERN_NOTICE "%s: The disk reports a capacity of %d " | |
10765 | + "bytes, but the drive only handles %d\n", | |
10766 | drive->name, lba_capacity, capacity); | |
10767 | floppy->blocks = floppy->block_size ? capacity / floppy->block_size : 0; | |
10768 | } | |
10769 | @@ -1410,8 +1545,7 @@ | |
10770 | } | |
10771 | ||
10772 | /* Clik! disk does not support get_flexible_disk_page */ | |
10773 | - if (!test_bit(IDEFLOPPY_CLIK_DRIVE, &floppy->flags)) | |
10774 | - { | |
10775 | + if (!test_bit(IDEFLOPPY_CLIK_DRIVE, &floppy->flags)) { | |
10776 | (void) idefloppy_get_flexible_disk_page (drive); | |
10777 | } | |
10778 | ||
10779 | @@ -1586,10 +1720,9 @@ | |
10780 | idefloppy_status_reg_t status; | |
10781 | unsigned long flags; | |
10782 | ||
10783 | - __save_flags(flags); | |
10784 | - __cli(); | |
10785 | + local_irq_save(flags); | |
10786 | status.all=GET_STAT(); | |
10787 | - __restore_flags(flags); | |
10788 | + local_irq_restore(flags); | |
10789 | ||
10790 | progress_indication= !status.b.dsc ? 0:0x10000; | |
10791 | } | |
10792 | @@ -1914,13 +2047,18 @@ | |
10793 | { | |
10794 | int major = HWIF(drive)->major; | |
10795 | int minor = drive->select.b.unit << PARTN_BITS; | |
10796 | + idefloppy_floppy_t *floppy = drive->driver_data; | |
10797 | ||
10798 | +/* | |
10799 | + * drive setting name read/write ioctl ioctl data type min max mul_factor div_factor data pointer set function | |
10800 | + */ | |
10801 | ide_add_setting(drive, "bios_cyl", SETTING_RW, -1, -1, TYPE_INT, 0, 1023, 1, 1, &drive->bios_cyl, NULL); | |
10802 | ide_add_setting(drive, "bios_head", SETTING_RW, -1, -1, TYPE_BYTE, 0, 255, 1, 1, &drive->bios_head, NULL); | |
10803 | ide_add_setting(drive, "bios_sect", SETTING_RW, -1, -1, TYPE_BYTE, 0, 63, 1, 1, &drive->bios_sect, NULL); | |
10804 | ide_add_setting(drive, "breada_readahead", SETTING_RW, BLKRAGET, BLKRASET, TYPE_INT, 0, 255, 1, 2, &read_ahead[major], NULL); | |
10805 | ide_add_setting(drive, "file_readahead", SETTING_RW, BLKFRAGET, BLKFRASET, TYPE_INTA, 0, INT_MAX, 1, 1024, &max_readahead[major][minor], NULL); | |
10806 | ide_add_setting(drive, "max_kb_per_request", SETTING_RW, BLKSECTGET, BLKSECTSET, TYPE_INTA, 1, 255, 1, 2, &max_sectors[major][minor], NULL); | |
10807 | + ide_add_setting(drive, "ticks", SETTING_RW, -1, -1, TYPE_BYTE, 0, 255, 1, 1, &floppy->ticks, NULL); | |
10808 | ||
10809 | } | |
10810 | ||
10811 | @@ -1954,27 +2092,19 @@ | |
10812 | ||
10813 | if (strcmp(drive->id->model, "IOMEGA ZIP 100 ATAPI") == 0) | |
10814 | { | |
10815 | + set_bit(IDEFLOPPY_ZIP_DRIVE, &floppy->flags); | |
10816 | + /* This value will be visible in the /proc/ide/hdx/settings */ | |
10817 | + floppy->ticks = IDEFLOPPY_TICKS_DELAY; | |
10818 | for (i = 0; i < 1 << PARTN_BITS; i++) | |
10819 | max_sectors[major][minor + i] = 64; | |
10820 | } | |
10821 | - /* | |
10822 | - * Guess what? The IOMEGA Clik! drive also needs the | |
10823 | - * above fix. It makes nasty clicking noises without | |
10824 | - * it, so please don't remove this. | |
10825 | - */ | |
10826 | - if (strcmp(drive->id->model, "IOMEGA Clik! 40 CZ ATAPI") == 0) | |
10827 | - { | |
10828 | - for (i = 0; i < 1 << PARTN_BITS; i++) | |
10829 | - max_sectors[major][minor + i] = 64; | |
10830 | - set_bit(IDEFLOPPY_CLIK_DRIVE, &floppy->flags); | |
10831 | - } | |
10832 | ||
10833 | /* | |
10834 | * Guess what? The IOMEGA Clik! drive also needs the | |
10835 | * above fix. It makes nasty clicking noises without | |
10836 | * it, so please don't remove this. | |
10837 | */ | |
10838 | - if (strcmp(drive->id->model, "IOMEGA Clik! 40 CZ ATAPI") == 0) | |
10839 | + if (strncmp(drive->id->model, "IOMEGA Clik!", 11) == 0) | |
10840 | { | |
10841 | for (i = 0; i < 1 << PARTN_BITS; i++) | |
10842 | max_sectors[major][minor + i] = 64; | |
10843 | @@ -2019,10 +2149,8 @@ | |
10844 | ||
10845 | #endif /* CONFIG_PROC_FS */ | |
10846 | ||
10847 | -static int idefloppy_reinit (ide_drive_t *drive) | |
10848 | -{ | |
10849 | - return 0; | |
10850 | -} | |
10851 | +int idefloppy_init (void); | |
10852 | +int idefloppy_reinit(ide_drive_t *drive); | |
10853 | ||
10854 | /* | |
10855 | * IDE subdriver functions, registered with ide.c | |
10856 | @@ -2032,11 +2160,21 @@ | |
10857 | version: IDEFLOPPY_VERSION, | |
10858 | media: ide_floppy, | |
10859 | busy: 0, | |
10860 | +#ifdef CONFIG_IDEDMA_ONLYDISK | |
10861 | + supports_dma: 0, | |
10862 | +#else | |
10863 | supports_dma: 1, | |
10864 | +#endif | |
10865 | supports_dsc_overlap: 0, | |
10866 | cleanup: idefloppy_cleanup, | |
10867 | + standby: NULL, | |
10868 | + suspend: NULL, | |
10869 | + resume: NULL, | |
10870 | + flushcache: NULL, | |
10871 | do_request: idefloppy_do_request, | |
10872 | - end_request: idefloppy_end_request, | |
10873 | + end_request: idefloppy_do_end_request, | |
10874 | + sense: NULL, | |
10875 | + error: NULL, | |
10876 | ioctl: idefloppy_ioctl, | |
10877 | open: idefloppy_open, | |
10878 | release: idefloppy_release, | |
10879 | @@ -2046,10 +2184,12 @@ | |
10880 | capacity: idefloppy_capacity, | |
10881 | special: NULL, | |
10882 | proc: idefloppy_proc, | |
10883 | - driver_reinit: idefloppy_reinit, | |
10884 | + init: idefloppy_init, | |
10885 | + reinit: idefloppy_reinit, | |
10886 | + ata_prebuilder: NULL, | |
10887 | + atapi_prebuilder: NULL, | |
10888 | }; | |
10889 | ||
10890 | -int idefloppy_init (void); | |
10891 | static ide_module_t idefloppy_module = { | |
10892 | IDE_DRIVER_MODULE, | |
10893 | idefloppy_init, | |
10894 | @@ -2057,6 +2197,40 @@ | |
10895 | NULL | |
10896 | }; | |
10897 | ||
10898 | +int idefloppy_reinit (ide_drive_t *drive) | |
10899 | +{ | |
10900 | + idefloppy_floppy_t *floppy; | |
10901 | + int failed = 0; | |
10902 | + | |
10903 | + MOD_INC_USE_COUNT; | |
10904 | + while ((drive = ide_scan_devices (ide_floppy, idefloppy_driver.name, NULL, failed++)) != NULL) { | |
10905 | + if (!idefloppy_identify_device (drive, drive->id)) { | |
10906 | + printk (KERN_ERR "ide-floppy: %s: not supported by this version of ide-floppy\n", drive->name); | |
10907 | + continue; | |
10908 | + } | |
10909 | + if (drive->scsi) { | |
10910 | + printk("ide-floppy: passing drive %s to ide-scsi emulation.\n", drive->name); | |
10911 | + continue; | |
10912 | + } | |
10913 | + if ((floppy = (idefloppy_floppy_t *) kmalloc (sizeof (idefloppy_floppy_t), GFP_KERNEL)) == NULL) { | |
10914 | + printk (KERN_ERR "ide-floppy: %s: Can't allocate a floppy structure\n", drive->name); | |
10915 | + continue; | |
10916 | + } | |
10917 | + if (ide_register_subdriver (drive, &idefloppy_driver, IDE_SUBDRIVER_VERSION)) { | |
10918 | + printk (KERN_ERR "ide-floppy: %s: Failed to register the driver with ide.c\n", drive->name); | |
10919 | + kfree (floppy); | |
10920 | + continue; | |
10921 | + } | |
10922 | + DRIVER(drive)->busy++; | |
10923 | + idefloppy_setup (drive, floppy); | |
10924 | + DRIVER(drive)->busy--; | |
10925 | + failed--; | |
10926 | + } | |
10927 | + ide_register_module(&idefloppy_module); | |
10928 | + MOD_DEC_USE_COUNT; | |
10929 | + return 0; | |
10930 | +} | |
10931 | + | |
10932 | MODULE_DESCRIPTION("ATAPI FLOPPY Driver"); | |
10933 | ||
10934 | static void __exit idefloppy_exit (void) | |
10935 | @@ -2108,7 +2282,9 @@ | |
10936 | kfree (floppy); | |
10937 | continue; | |
10938 | } | |
10939 | + DRIVER(drive)->busy++; | |
10940 | idefloppy_setup (drive, floppy); | |
10941 | + DRIVER(drive)->busy--; | |
10942 | failed--; | |
10943 | } | |
10944 | ide_register_module(&idefloppy_module); | |
10945 | diff -Nur linux.org/drivers/ide/ide-geometry.c linux/drivers/ide/ide-geometry.c | |
10946 | --- linux.org/drivers/ide/ide-geometry.c Fri Nov 9 23:23:34 2001 | |
10947 | +++ linux/drivers/ide/ide-geometry.c Thu Jul 18 14:23:00 2002 | |
10948 | @@ -6,6 +6,8 @@ | |
10949 | #include <linux/mc146818rtc.h> | |
10950 | #include <asm/io.h> | |
10951 | ||
10952 | +#ifdef CONFIG_BLK_DEV_IDE | |
10953 | + | |
10954 | /* | |
10955 | * We query CMOS about hard disks : it could be that we have a SCSI/ESDI/etc | |
10956 | * controller that is BIOS compatible with ST-506, and thus showing up in our | |
10957 | @@ -40,7 +42,11 @@ | |
10958 | * Consequently, also the former "drive->present = 1" below was a mistake. | |
10959 | * | |
10960 | * Eventually the entire routine below should be removed. | |
10961 | + * | |
10962 | + * 17-OCT-2000 rjohnson@analogic.com Added spin-locks for reading CMOS | |
10963 | + * chip. | |
10964 | */ | |
10965 | + | |
10966 | void probe_cmos_for_drives (ide_hwif_t *hwif) | |
10967 | { | |
10968 | #ifdef __i386__ | |
10969 | @@ -80,9 +86,10 @@ | |
10970 | } | |
10971 | #endif | |
10972 | } | |
10973 | +#endif /* CONFIG_BLK_DEV_IDE */ | |
10974 | ||
10975 | ||
10976 | -#ifdef CONFIG_BLK_DEV_IDE | |
10977 | +#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) | |
10978 | ||
10979 | extern ide_drive_t * get_info_ptr(kdev_t); | |
10980 | extern unsigned long current_capacity (ide_drive_t *); | |
10981 | @@ -214,4 +221,4 @@ | |
10982 | drive->bios_cyl, drive->bios_head, drive->bios_sect); | |
10983 | return ret; | |
10984 | } | |
10985 | -#endif /* CONFIG_BLK_DEV_IDE */ | |
10986 | +#endif /* defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) */ | |
10987 | diff -Nur linux.org/drivers/ide/ide-pci.c linux/drivers/ide/ide-pci.c | |
10988 | --- linux.org/drivers/ide/ide-pci.c Thu Oct 25 22:53:47 2001 | |
10989 | +++ linux/drivers/ide/ide-pci.c Thu Jul 18 14:24:33 2002 | |
10990 | @@ -12,6 +12,13 @@ | |
10991 | * configuration of all PCI IDE interfaces present in a system. | |
10992 | */ | |
10993 | ||
10994 | +/* | |
10995 | + * Chipsets that are on the IDE_IGNORE list because of problems of not being | |
10996 | + * set at compile time. | |
10997 | + * | |
10998 | + * CONFIG_BLK_DEV_PDC202XX | |
10999 | + */ | |
11000 | + | |
11001 | #include <linux/config.h> | |
11002 | #include <linux/types.h> | |
11003 | #include <linux/kernel.h> | |
11004 | @@ -38,15 +45,24 @@ | |
11005 | #define DEVID_PIIX4U3 ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_9}) | |
11006 | #define DEVID_PIIX4U4 ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_8}) | |
11007 | #define DEVID_PIIX4U5 ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_10}) | |
11008 | +#define DEVID_PIIX4U6 ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_11}) | |
11009 | +#define DEVID_PIIX4U7 ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801E_11}) | |
11010 | +#define DEVID_PIIX4U8 ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_11}) | |
11011 | #define DEVID_VIA_IDE ((ide_pci_devid_t){PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C561}) | |
11012 | #define DEVID_MR_IDE ((ide_pci_devid_t){PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C576_1}) | |
11013 | #define DEVID_VP_IDE ((ide_pci_devid_t){PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1}) | |
11014 | #define DEVID_PDC20246 ((ide_pci_devid_t){PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20246}) | |
11015 | #define DEVID_PDC20262 ((ide_pci_devid_t){PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20262}) | |
11016 | +#define DEVID_PDC20263 ((ide_pci_devid_t){PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20263}) | |
11017 | #define DEVID_PDC20265 ((ide_pci_devid_t){PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20265}) | |
11018 | #define DEVID_PDC20267 ((ide_pci_devid_t){PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20267}) | |
11019 | #define DEVID_PDC20268 ((ide_pci_devid_t){PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20268}) | |
11020 | -#define DEVID_PDC20268R ((ide_pci_devid_t){PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20268R}) | |
11021 | +#define DEVID_PDC20270 ((ide_pci_devid_t){PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20270}) | |
11022 | +#define DEVID_PDC20269 ((ide_pci_devid_t){PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20269}) | |
11023 | +#define DEVID_PDC20271 ((ide_pci_devid_t){PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20271}) | |
11024 | +#define DEVID_PDC20275 ((ide_pci_devid_t){PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20275}) | |
11025 | +#define DEVID_PDC20276 ((ide_pci_devid_t){PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20276}) | |
11026 | +#define DEVID_PDC20277 ((ide_pci_devid_t){PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20277}) | |
11027 | #define DEVID_RZ1000 ((ide_pci_devid_t){PCI_VENDOR_ID_PCTECH, PCI_DEVICE_ID_PCTECH_RZ1000}) | |
11028 | #define DEVID_RZ1001 ((ide_pci_devid_t){PCI_VENDOR_ID_PCTECH, PCI_DEVICE_ID_PCTECH_RZ1001}) | |
11029 | #define DEVID_SAMURAI ((ide_pci_devid_t){PCI_VENDOR_ID_PCTECH, PCI_DEVICE_ID_PCTECH_SAMURAI_IDE}) | |
11030 | @@ -55,6 +71,7 @@ | |
11031 | #define DEVID_CMD646 ((ide_pci_devid_t){PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_CMD_646}) | |
11032 | #define DEVID_CMD648 ((ide_pci_devid_t){PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_CMD_648}) | |
11033 | #define DEVID_CMD649 ((ide_pci_devid_t){PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_CMD_649}) | |
11034 | +#define DEVID_CMD680 ((ide_pci_devid_t){PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_CMD_680}) | |
11035 | #define DEVID_SIS5513 ((ide_pci_devid_t){PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5513}) | |
11036 | #define DEVID_OPTI621 ((ide_pci_devid_t){PCI_VENDOR_ID_OPTI, PCI_DEVICE_ID_OPTI_82C621}) | |
11037 | #define DEVID_OPTI621V ((ide_pci_devid_t){PCI_VENDOR_ID_OPTI, PCI_DEVICE_ID_OPTI_82C558}) | |
11038 | @@ -66,12 +83,18 @@ | |
11039 | #define DEVID_AEC6210 ((ide_pci_devid_t){PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP850UF}) | |
11040 | #define DEVID_AEC6260 ((ide_pci_devid_t){PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP860}) | |
11041 | #define DEVID_AEC6260R ((ide_pci_devid_t){PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP860R}) | |
11042 | +#define DEVID_AEC6280 ((ide_pci_devid_t){PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP865}) | |
11043 | +#define DEVID_AEC6880 ((ide_pci_devid_t){PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP865R}) | |
11044 | #define DEVID_W82C105 ((ide_pci_devid_t){PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105}) | |
11045 | #define DEVID_UM8673F ((ide_pci_devid_t){PCI_VENDOR_ID_UMC, PCI_DEVICE_ID_UMC_UM8673F}) | |
11046 | #define DEVID_UM8886A ((ide_pci_devid_t){PCI_VENDOR_ID_UMC, PCI_DEVICE_ID_UMC_UM8886A}) | |
11047 | #define DEVID_UM8886BF ((ide_pci_devid_t){PCI_VENDOR_ID_UMC, PCI_DEVICE_ID_UMC_UM8886BF}) | |
11048 | #define DEVID_HPT34X ((ide_pci_devid_t){PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT343}) | |
11049 | #define DEVID_HPT366 ((ide_pci_devid_t){PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT366}) | |
11050 | +#define DEVID_HPT372 ((ide_pci_devid_t){PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT372}) | |
11051 | +#define DEVID_HPT302 ((ide_pci_devid_t){PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT302}) | |
11052 | +#define DEVID_HPT371 ((ide_pci_devid_t){PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT371}) | |
11053 | +#define DEVID_HPT374 ((ide_pci_devid_t){PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT374}) | |
11054 | #define DEVID_ALI15X3 ((ide_pci_devid_t){PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M5229}) | |
11055 | #define DEVID_CY82C693 ((ide_pci_devid_t){PCI_VENDOR_ID_CONTAQ, PCI_DEVICE_ID_CONTAQ_82C693}) | |
11056 | #define DEVID_HINT ((ide_pci_devid_t){0x3388, 0x8013}) | |
11057 | @@ -79,59 +102,71 @@ | |
11058 | #define DEVID_AMD7401 ((ide_pci_devid_t){PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_COBRA_7401}) | |
11059 | #define DEVID_AMD7409 ((ide_pci_devid_t){PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7409}) | |
11060 | #define DEVID_AMD7411 ((ide_pci_devid_t){PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7411}) | |
11061 | +#define DEVID_AMD7441 ((ide_pci_devid_t){PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7441}) | |
11062 | #define DEVID_PDCADMA ((ide_pci_devid_t){PCI_VENDOR_ID_PDC, PCI_DEVICE_ID_PDC_1841}) | |
11063 | #define DEVID_SLC90E66 ((ide_pci_devid_t){PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_1}) | |
11064 | #define DEVID_OSB4 ((ide_pci_devid_t){PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_OSB4IDE}) | |
11065 | #define DEVID_CSB5 ((ide_pci_devid_t){PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5IDE}) | |
11066 | +#define DEVID_CSB6 ((ide_pci_devid_t){PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6IDE}) | |
11067 | #define DEVID_ITE8172G ((ide_pci_devid_t){PCI_VENDOR_ID_ITE, PCI_DEVICE_ID_ITE_IT8172G}) | |
11068 | ||
11069 | #define IDE_IGNORE ((void *)-1) | |
11070 | +#define IDE_NO_DRIVER ((void *)-2) | |
11071 | ||
11072 | #ifdef CONFIG_BLK_DEV_AEC62XX | |
11073 | +extern void fixup_device_aec6x80(struct pci_dev *, ide_pci_device_t *); | |
11074 | extern unsigned int pci_init_aec62xx(struct pci_dev *, const char *); | |
11075 | extern unsigned int ata66_aec62xx(ide_hwif_t *); | |
11076 | extern void ide_init_aec62xx(ide_hwif_t *); | |
11077 | extern void ide_dmacapable_aec62xx(ide_hwif_t *, unsigned long); | |
11078 | +#define FIXUP_AEC62XX &fixup_device_aec6x80 | |
11079 | #define PCI_AEC62XX &pci_init_aec62xx | |
11080 | #define ATA66_AEC62XX &ata66_aec62xx | |
11081 | #define INIT_AEC62XX &ide_init_aec62xx | |
11082 | #define DMA_AEC62XX &ide_dmacapable_aec62xx | |
11083 | #else | |
11084 | +#define FIXUP_AEC62XX NULL | |
11085 | #define PCI_AEC62XX NULL | |
11086 | #define ATA66_AEC62XX NULL | |
11087 | -#define INIT_AEC62XX NULL | |
11088 | +#define INIT_AEC62XX IDE_NO_DRIVER | |
11089 | #define DMA_AEC62XX NULL | |
11090 | #endif | |
11091 | ||
11092 | #ifdef CONFIG_BLK_DEV_ALI15X3 | |
11093 | +extern void fixup_device_ali15x3(struct pci_dev *, ide_pci_device_t *); | |
11094 | extern unsigned int pci_init_ali15x3(struct pci_dev *, const char *); | |
11095 | extern unsigned int ata66_ali15x3(ide_hwif_t *); | |
11096 | extern void ide_init_ali15x3(ide_hwif_t *); | |
11097 | extern void ide_dmacapable_ali15x3(ide_hwif_t *, unsigned long); | |
11098 | +#define FIXUP_ALI15X3 &fixup_device_ali15x3 | |
11099 | #define PCI_ALI15X3 &pci_init_ali15x3 | |
11100 | #define ATA66_ALI15X3 &ata66_ali15x3 | |
11101 | #define INIT_ALI15X3 &ide_init_ali15x3 | |
11102 | #define DMA_ALI15X3 &ide_dmacapable_ali15x3 | |
11103 | #else | |
11104 | +#define FIXUP_ALI15X3 NULL | |
11105 | #define PCI_ALI15X3 NULL | |
11106 | #define ATA66_ALI15X3 NULL | |
11107 | -#define INIT_ALI15X3 NULL | |
11108 | +#define INIT_ALI15X3 IDE_NO_DRIVER | |
11109 | #define DMA_ALI15X3 NULL | |
11110 | #endif | |
11111 | ||
11112 | #ifdef CONFIG_BLK_DEV_AMD74XX | |
11113 | +extern void fixup_device_amd74xx(struct pci_dev *, ide_pci_device_t *); | |
11114 | extern unsigned int pci_init_amd74xx(struct pci_dev *, const char *); | |
11115 | extern unsigned int ata66_amd74xx(ide_hwif_t *); | |
11116 | extern void ide_init_amd74xx(ide_hwif_t *); | |
11117 | extern void ide_dmacapable_amd74xx(ide_hwif_t *, unsigned long); | |
11118 | +#define FIXUP_AMD74XX &fixup_device_amd74xx | |
11119 | #define PCI_AMD74XX &pci_init_amd74xx | |
11120 | #define ATA66_AMD74XX &ata66_amd74xx | |
11121 | #define INIT_AMD74XX &ide_init_amd74xx | |
11122 | #define DMA_AMD74XX &ide_dmacapable_amd74xx | |
11123 | #else | |
11124 | +#define FIXUP_AMD74XX NULL | |
11125 | #define PCI_AMD74XX NULL | |
11126 | #define ATA66_AMD74XX NULL | |
11127 | -#define INIT_AMD74XX NULL | |
11128 | +#define INIT_AMD74XX IDE_NO_DRIVER | |
11129 | #define DMA_AMD74XX NULL | |
11130 | #endif | |
11131 | ||
11132 | @@ -149,18 +184,21 @@ | |
11133 | #ifdef __sparc_v9__ | |
11134 | #define INIT_CMD64X IDE_IGNORE | |
11135 | #else | |
11136 | -#define INIT_CMD64X NULL | |
11137 | +#define INIT_CMD64X IDE_NO_DRIVER | |
11138 | #endif | |
11139 | #endif | |
11140 | ||
11141 | #ifdef CONFIG_BLK_DEV_CY82C693 | |
11142 | +extern void fixup_device_cy82c693(struct pci_dev *, ide_pci_device_t *); | |
11143 | extern unsigned int pci_init_cy82c693(struct pci_dev *, const char *); | |
11144 | extern void ide_init_cy82c693(ide_hwif_t *); | |
11145 | +#define FIXUP_CY82C693 &fixup_device_cy82c693 | |
11146 | #define PCI_CY82C693 &pci_init_cy82c693 | |
11147 | #define INIT_CY82C693 &ide_init_cy82c693 | |
11148 | #else | |
11149 | +#define FIXUP_CY82C693 NULL | |
11150 | #define PCI_CY82C693 NULL | |
11151 | -#define INIT_CY82C693 NULL | |
11152 | +#define INIT_CY82C693 IDE_NO_DRIVER | |
11153 | #endif | |
11154 | ||
11155 | #ifdef CONFIG_BLK_DEV_CS5530 | |
11156 | @@ -170,36 +208,41 @@ | |
11157 | #define INIT_CS5530 &ide_init_cs5530 | |
11158 | #else | |
11159 | #define PCI_CS5530 NULL | |
11160 | -#define INIT_CS5530 NULL | |
11161 | +#define INIT_CS5530 IDE_NO_DRIVER | |
11162 | #endif | |
11163 | ||
11164 | #ifdef CONFIG_BLK_DEV_HPT34X | |
11165 | +extern void fixup_device_hpt343(struct pci_dev *, ide_pci_device_t *); | |
11166 | extern unsigned int pci_init_hpt34x(struct pci_dev *, const char *); | |
11167 | extern void ide_init_hpt34x(ide_hwif_t *); | |
11168 | +#define FIXUP_HPT34X &fixup_device_hpt343 | |
11169 | #define PCI_HPT34X &pci_init_hpt34x | |
11170 | #define INIT_HPT34X &ide_init_hpt34x | |
11171 | #else | |
11172 | +#define FIXUP_HPT34X NULL | |
11173 | #define PCI_HPT34X NULL | |
11174 | #define INIT_HPT34X IDE_IGNORE | |
11175 | #endif | |
11176 | ||
11177 | #ifdef CONFIG_BLK_DEV_HPT366 | |
11178 | -extern byte hpt363_shared_irq; | |
11179 | -extern byte hpt363_shared_pin; | |
11180 | +extern void fixup_device_hpt366(struct pci_dev *, ide_pci_device_t *); | |
11181 | +extern void fixup_device_hpt374(struct pci_dev *, ide_pci_device_t *); | |
11182 | extern unsigned int pci_init_hpt366(struct pci_dev *, const char *); | |
11183 | extern unsigned int ata66_hpt366(ide_hwif_t *); | |
11184 | extern void ide_init_hpt366(ide_hwif_t *); | |
11185 | extern void ide_dmacapable_hpt366(ide_hwif_t *, unsigned long); | |
11186 | +#define FIXUP_HPT366 &fixup_device_hpt366 | |
11187 | +#define FIXUP_HPT374 &fixup_device_hpt374 | |
11188 | #define PCI_HPT366 &pci_init_hpt366 | |
11189 | #define ATA66_HPT366 &ata66_hpt366 | |
11190 | #define INIT_HPT366 &ide_init_hpt366 | |
11191 | #define DMA_HPT366 &ide_dmacapable_hpt366 | |
11192 | #else | |
11193 | -static byte hpt363_shared_irq; | |
11194 | -static byte hpt363_shared_pin; | |
11195 | +#define FIXUP_HPT366 NULL | |
11196 | +#define FIXUP_HPT374 NULL | |
11197 | #define PCI_HPT366 NULL | |
11198 | #define ATA66_HPT366 NULL | |
11199 | -#define INIT_HPT366 NULL | |
11200 | +#define INIT_HPT366 IDE_NO_DRIVER | |
11201 | #define DMA_HPT366 NULL | |
11202 | #endif | |
11203 | ||
11204 | @@ -211,10 +254,13 @@ | |
11205 | #endif | |
11206 | ||
11207 | #ifdef CONFIG_BLK_DEV_OPTI621 | |
11208 | +extern void fixup_device_opti621(struct pci_dev *, ide_pci_device_t *); | |
11209 | extern void ide_init_opti621(ide_hwif_t *); | |
11210 | +#define FIXUP_OPTI621 &fixup_device_opti621 | |
11211 | #define INIT_OPTI621 &ide_init_opti621 | |
11212 | #else | |
11213 | -#define INIT_OPTI621 NULL | |
11214 | +#define FIXUP_OPTI621 NULL | |
11215 | +#define INIT_OPTI621 IDE_NO_DRIVER | |
11216 | #endif | |
11217 | ||
11218 | #ifdef CONFIG_BLK_DEV_PDC_ADMA | |
11219 | @@ -234,41 +280,54 @@ | |
11220 | #endif | |
11221 | ||
11222 | #ifdef CONFIG_BLK_DEV_PDC202XX | |
11223 | +extern void fixup_device_pdc20265(struct pci_dev *, ide_pci_device_t *); | |
11224 | +extern void fixup_device_pdc20270(struct pci_dev *, ide_pci_device_t *); | |
11225 | extern unsigned int pci_init_pdc202xx(struct pci_dev *, const char *); | |
11226 | extern unsigned int ata66_pdc202xx(ide_hwif_t *); | |
11227 | extern void ide_init_pdc202xx(ide_hwif_t *); | |
11228 | +#define FIXUP_PDC20265 &fixup_device_pdc20265 | |
11229 | +#define FIXUP_PDC20270 &fixup_device_pdc20270 | |
11230 | #define PCI_PDC202XX &pci_init_pdc202xx | |
11231 | #define ATA66_PDC202XX &ata66_pdc202xx | |
11232 | #define INIT_PDC202XX &ide_init_pdc202xx | |
11233 | #else | |
11234 | -#define PCI_PDC202XX NULL | |
11235 | -#define ATA66_PDC202XX NULL | |
11236 | -#define INIT_PDC202XX NULL | |
11237 | +#define FIXUP_PDC20265 IDE_IGNORE | |
11238 | +#define FIXUP_PDC20270 IDE_IGNORE | |
11239 | +#define PCI_PDC202XX IDE_IGNORE | |
11240 | +#define ATA66_PDC202XX IDE_IGNORE | |
11241 | +#define INIT_PDC202XX IDE_IGNORE | |
11242 | #endif | |
11243 | ||
11244 | #ifdef CONFIG_BLK_DEV_PIIX | |
11245 | +extern void fixup_device_piix(struct pci_dev *, ide_pci_device_t *); | |
11246 | extern unsigned int pci_init_piix(struct pci_dev *, const char *); | |
11247 | extern unsigned int ata66_piix(ide_hwif_t *); | |
11248 | extern void ide_init_piix(ide_hwif_t *); | |
11249 | +#define FIXUP_PIIX &fixup_device_piix | |
11250 | #define PCI_PIIX &pci_init_piix | |
11251 | #define ATA66_PIIX &ata66_piix | |
11252 | #define INIT_PIIX &ide_init_piix | |
11253 | #else | |
11254 | +#define FIXUP_PIIX NULL | |
11255 | #define PCI_PIIX NULL | |
11256 | #define ATA66_PIIX NULL | |
11257 | -#define INIT_PIIX NULL | |
11258 | +#define INIT_PIIX IDE_NO_DRIVER | |
11259 | #endif | |
11260 | ||
11261 | #ifdef CONFIG_BLK_DEV_IT8172 | |
11262 | +extern void fixup_device_it8172(struct pci_dev *, ide_pci_device_t *); | |
11263 | extern unsigned int pci_init_it8172(struct pci_dev *, const char *); | |
11264 | extern unsigned int ata66_it8172(ide_hwif_t *); | |
11265 | extern void ide_init_it8172(ide_hwif_t *); | |
11266 | +#define FIXUP_IT8172 &fixup_device_it8172 | |
11267 | #define PCI_IT8172 &pci_init_it8172 | |
11268 | +#define ATA66_IT8172 &ata66_it8172 | |
11269 | #define INIT_IT8172 &ide_init_it8172 | |
11270 | #else | |
11271 | +#define FIXUP_IT8172 NULL | |
11272 | #define PCI_IT8172 NULL | |
11273 | #define ATA66_IT8172 NULL | |
11274 | -#define INIT_IT8172 NULL | |
11275 | +#define INIT_IT8172 IDE_NO_DRIVER | |
11276 | #endif | |
11277 | ||
11278 | #ifdef CONFIG_BLK_DEV_RZ1000 | |
11279 | @@ -281,29 +340,38 @@ | |
11280 | #define INIT_SAMURAI NULL | |
11281 | ||
11282 | #ifdef CONFIG_BLK_DEV_SVWKS | |
11283 | +extern void fixup_device_csb6(struct pci_dev *, ide_pci_device_t *); | |
11284 | extern unsigned int pci_init_svwks(struct pci_dev *, const char *); | |
11285 | extern unsigned int ata66_svwks(ide_hwif_t *); | |
11286 | extern void ide_init_svwks(ide_hwif_t *); | |
11287 | +extern void ide_dmacapable_svwks(ide_hwif_t *, unsigned long); | |
11288 | +#define FIXUP_CSB6 &fixup_device_csb6 | |
11289 | #define PCI_SVWKS &pci_init_svwks | |
11290 | #define ATA66_SVWKS &ata66_svwks | |
11291 | #define INIT_SVWKS &ide_init_svwks | |
11292 | +#define DMA_SVWKS &ide_dmacapable_svwks | |
11293 | #else | |
11294 | +#define FIXUP_CSB6 NULL | |
11295 | #define PCI_SVWKS NULL | |
11296 | #define ATA66_SVWKS NULL | |
11297 | -#define INIT_SVWKS NULL | |
11298 | +#define INIT_SVWKS IDE_NO_DRIVER | |
11299 | +#define DMA_SVWKS NULL | |
11300 | #endif | |
11301 | ||
11302 | #ifdef CONFIG_BLK_DEV_SIS5513 | |
11303 | +extern void fixup_device_sis5513(struct pci_dev *, ide_pci_device_t *); | |
11304 | extern unsigned int pci_init_sis5513(struct pci_dev *, const char *); | |
11305 | extern unsigned int ata66_sis5513(ide_hwif_t *); | |
11306 | extern void ide_init_sis5513(ide_hwif_t *); | |
11307 | +#define FIXUP_SIS5513 &fixup_device_sis5513 | |
11308 | #define PCI_SIS5513 &pci_init_sis5513 | |
11309 | #define ATA66_SIS5513 &ata66_sis5513 | |
11310 | #define INIT_SIS5513 &ide_init_sis5513 | |
11311 | #else | |
11312 | +#define FIXUP_SIS5513 NULL | |
11313 | #define PCI_SIS5513 NULL | |
11314 | #define ATA66_SIS5513 NULL | |
11315 | -#define INIT_SIS5513 NULL | |
11316 | +#define INIT_SIS5513 IDE_NO_DRIVER | |
11317 | #endif | |
11318 | ||
11319 | #ifdef CONFIG_BLK_DEV_SLC90E66 | |
11320 | @@ -316,7 +384,7 @@ | |
11321 | #else | |
11322 | #define PCI_SLC90E66 NULL | |
11323 | #define ATA66_SLC90E66 NULL | |
11324 | -#define INIT_SLC90E66 NULL | |
11325 | +#define INIT_SLC90E66 IDE_NO_DRIVER | |
11326 | #endif | |
11327 | ||
11328 | #ifdef CONFIG_BLK_DEV_SL82C105 | |
11329 | @@ -351,98 +419,102 @@ | |
11330 | #else | |
11331 | #define PCI_VIA82CXXX NULL | |
11332 | #define ATA66_VIA82CXXX NULL | |
11333 | -#define INIT_VIA82CXXX NULL | |
11334 | +#define INIT_VIA82CXXX IDE_NO_DRIVER | |
11335 | #define DMA_VIA82CXXX NULL | |
11336 | #endif | |
11337 | ||
11338 | -typedef struct ide_pci_enablebit_s { | |
11339 | - byte reg; /* byte pci reg holding the enable-bit */ | |
11340 | - byte mask; /* mask to isolate the enable-bit */ | |
11341 | - byte val; /* value of masked reg when "enabled" */ | |
11342 | -} ide_pci_enablebit_t; | |
11343 | - | |
11344 | -typedef struct ide_pci_device_s { | |
11345 | - ide_pci_devid_t devid; | |
11346 | - char *name; | |
11347 | - unsigned int (*init_chipset)(struct pci_dev *dev, const char *name); | |
11348 | - unsigned int (*ata66_check)(ide_hwif_t *hwif); | |
11349 | - void (*init_hwif)(ide_hwif_t *hwif); | |
11350 | - void (*dma_init)(ide_hwif_t *hwif, unsigned long dmabase); | |
11351 | - ide_pci_enablebit_t enablebits[2]; | |
11352 | - byte bootable; | |
11353 | - unsigned int extra; | |
11354 | -} ide_pci_device_t; | |
11355 | - | |
11356 | static ide_pci_device_t ide_pci_chipsets[] __initdata = { | |
11357 | - {DEVID_PIIXa, "PIIX", NULL, NULL, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, | |
11358 | - {DEVID_PIIXb, "PIIX", NULL, NULL, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, | |
11359 | - {DEVID_MPIIX, "MPIIX", NULL, NULL, INIT_PIIX, NULL, {{0x6D,0x80,0x80}, {0x6F,0x80,0x80}}, ON_BOARD, 0 }, | |
11360 | - {DEVID_PIIX3, "PIIX3", PCI_PIIX, NULL, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, | |
11361 | - {DEVID_PIIX4, "PIIX4", PCI_PIIX, NULL, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, | |
11362 | - {DEVID_PIIX4E, "PIIX4", PCI_PIIX, NULL, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, | |
11363 | - {DEVID_PIIX4E2, "PIIX4", PCI_PIIX, NULL, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, | |
11364 | - {DEVID_PIIX4U, "PIIX4", PCI_PIIX, ATA66_PIIX, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, | |
11365 | - {DEVID_PIIX4U2, "PIIX4", PCI_PIIX, ATA66_PIIX, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, | |
11366 | - {DEVID_PIIX4NX, "PIIX4", PCI_PIIX, NULL, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, | |
11367 | - {DEVID_PIIX4U3, "PIIX4", PCI_PIIX, ATA66_PIIX, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, | |
11368 | - {DEVID_PIIX4U4, "PIIX4", PCI_PIIX, ATA66_PIIX, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, | |
11369 | - {DEVID_PIIX4U5, "PIIX4", PCI_PIIX, ATA66_PIIX, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, | |
11370 | - {DEVID_VIA_IDE, "VIA_IDE", NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, | |
11371 | - {DEVID_MR_IDE, "VP_IDE", PCI_VIA82CXXX, ATA66_VIA82CXXX,INIT_VIA82CXXX, DMA_VIA82CXXX, {{0x40,0x02,0x02}, {0x40,0x01,0x01}}, ON_BOARD, 0 }, | |
11372 | - {DEVID_VP_IDE, "VP_IDE", PCI_VIA82CXXX, ATA66_VIA82CXXX,INIT_VIA82CXXX, DMA_VIA82CXXX, {{0x40,0x02,0x02}, {0x40,0x01,0x01}}, ON_BOARD, 0 }, | |
11373 | + {DEVID_PIIXa, "PIIX", FIXUP_PIIX, PCI_PIIX, NULL, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, | |
11374 | + {DEVID_PIIXb, "PIIX", FIXUP_PIIX, PCI_PIIX, NULL, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, | |
11375 | + {DEVID_MPIIX, "MPIIX", FIXUP_PIIX, NULL, NULL, INIT_PIIX, NULL, {{0x6D,0x80,0x80}, {0x6F,0x80,0x80}}, ON_BOARD, 0 }, | |
11376 | + {DEVID_PIIX3, "PIIX3", FIXUP_PIIX, PCI_PIIX, NULL, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, | |
11377 | + {DEVID_PIIX4, "PIIX4", FIXUP_PIIX, PCI_PIIX, NULL, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, | |
11378 | + {DEVID_PIIX4E, "PIIX4", FIXUP_PIIX, PCI_PIIX, NULL, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, | |
11379 | + {DEVID_PIIX4E2, "PIIX4", FIXUP_PIIX, PCI_PIIX, NULL, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, | |
11380 | + {DEVID_PIIX4U, "PIIX4", FIXUP_PIIX, PCI_PIIX, ATA66_PIIX, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, | |
11381 | + {DEVID_PIIX4U2, "PIIX4", FIXUP_PIIX, PCI_PIIX, ATA66_PIIX, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, | |
11382 | + {DEVID_PIIX4NX, "PIIX4", FIXUP_PIIX, PCI_PIIX, NULL, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, | |
11383 | + {DEVID_PIIX4U3, "PIIX4", FIXUP_PIIX, PCI_PIIX, ATA66_PIIX, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, | |
11384 | + {DEVID_PIIX4U4, "PIIX4", FIXUP_PIIX, PCI_PIIX, ATA66_PIIX, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, | |
11385 | + {DEVID_PIIX4U5, "PIIX4", FIXUP_PIIX, PCI_PIIX, ATA66_PIIX, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, | |
11386 | + {DEVID_PIIX4U6, "PIIX4", FIXUP_PIIX, PCI_PIIX, ATA66_PIIX, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, | |
11387 | + {DEVID_PIIX4U7, "PIIX4", FIXUP_PIIX, PCI_PIIX, ATA66_PIIX, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, | |
11388 | + {DEVID_PIIX4U8, "PIIX4", FIXUP_PIIX, PCI_PIIX, ATA66_PIIX, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, | |
11389 | + {DEVID_VIA_IDE, "VIA_IDE", NULL, NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, | |
11390 | + {DEVID_MR_IDE, "VP_IDE", NULL, PCI_VIA82CXXX, ATA66_VIA82CXXX,INIT_VIA82CXXX, DMA_VIA82CXXX, {{0x40,0x02,0x02}, {0x40,0x01,0x01}}, ON_BOARD, 0 }, | |
11391 | + {DEVID_VP_IDE, "VP_IDE", NULL, PCI_VIA82CXXX, ATA66_VIA82CXXX,INIT_VIA82CXXX, DMA_VIA82CXXX, {{0x40,0x02,0x02}, {0x40,0x01,0x01}}, ON_BOARD, 0 }, | |
11392 | #ifdef CONFIG_PDC202XX_FORCE | |
11393 | - {DEVID_PDC20246,"PDC20246", PCI_PDC202XX, NULL, INIT_PDC202XX, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 16 }, | |
11394 | - {DEVID_PDC20262,"PDC20262", PCI_PDC202XX, ATA66_PDC202XX, INIT_PDC202XX, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 48 }, | |
11395 | - {DEVID_PDC20265,"PDC20265", PCI_PDC202XX, ATA66_PDC202XX, INIT_PDC202XX, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 48 }, | |
11396 | - {DEVID_PDC20267,"PDC20267", PCI_PDC202XX, ATA66_PDC202XX, INIT_PDC202XX, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 48 }, | |
11397 | + {DEVID_PDC20246,"PDC20246", NULL, PCI_PDC202XX, NULL, INIT_PDC202XX, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 16 }, | |
11398 | + {DEVID_PDC20262,"PDC20262", NULL, PCI_PDC202XX, ATA66_PDC202XX, INIT_PDC202XX, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 48 }, | |
11399 | + {DEVID_PDC20263,"PDC20263", NULL, PCI_PDC202XX, ATA66_PDC202XX, INIT_PDC202XX, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 48 }, | |
11400 | + {DEVID_PDC20265,"PDC20265", FIXUP_PDC20265, PCI_PDC202XX, ATA66_PDC202XX, INIT_PDC202XX, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 48 }, | |
11401 | + {DEVID_PDC20267,"PDC20267", NULL, PCI_PDC202XX, ATA66_PDC202XX, INIT_PDC202XX, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 48 }, | |
11402 | #else /* !CONFIG_PDC202XX_FORCE */ | |
11403 | - {DEVID_PDC20246,"PDC20246", PCI_PDC202XX, NULL, INIT_PDC202XX, NULL, {{0x50,0x02,0x02}, {0x50,0x04,0x04}}, OFF_BOARD, 16 }, | |
11404 | - {DEVID_PDC20262,"PDC20262", PCI_PDC202XX, ATA66_PDC202XX, INIT_PDC202XX, NULL, {{0x50,0x02,0x02}, {0x50,0x04,0x04}}, OFF_BOARD, 48 }, | |
11405 | - {DEVID_PDC20265,"PDC20265", PCI_PDC202XX, ATA66_PDC202XX, INIT_PDC202XX, NULL, {{0x50,0x02,0x02}, {0x50,0x04,0x04}}, OFF_BOARD, 48 }, | |
11406 | - {DEVID_PDC20267,"PDC20267", PCI_PDC202XX, ATA66_PDC202XX, INIT_PDC202XX, NULL, {{0x50,0x02,0x02}, {0x50,0x04,0x04}}, OFF_BOARD, 48 }, | |
11407 | -#endif | |
11408 | - {DEVID_PDC20268,"PDC20268", PCI_PDC202XX, ATA66_PDC202XX, INIT_PDC202XX, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 16 }, | |
11409 | - /* Promise used a different PCI ident for the raid card apparently to try and | |
11410 | - prevent Linux detecting it and using our own raid code. We want to detect | |
11411 | - it for the ataraid drivers, so we have to list both here.. */ | |
11412 | - {DEVID_PDC20268R,"PDC20268", PCI_PDC202XX, ATA66_PDC202XX, INIT_PDC202XX, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 16 }, | |
11413 | - {DEVID_RZ1000, "RZ1000", NULL, NULL, INIT_RZ1000, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, | |
11414 | - {DEVID_RZ1001, "RZ1001", NULL, NULL, INIT_RZ1000, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, | |
11415 | - {DEVID_SAMURAI, "SAMURAI", NULL, NULL, INIT_SAMURAI, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, | |
11416 | - {DEVID_CMD640, "CMD640", NULL, NULL, IDE_IGNORE, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, | |
11417 | - {DEVID_NS87410, "NS87410", NULL, NULL, NULL, NULL, {{0x43,0x08,0x08}, {0x47,0x08,0x08}}, ON_BOARD, 0 }, | |
11418 | - {DEVID_SIS5513, "SIS5513", PCI_SIS5513, ATA66_SIS5513, INIT_SIS5513, NULL, {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}}, ON_BOARD, 0 }, | |
11419 | - {DEVID_CMD643, "CMD643", PCI_CMD64X, NULL, INIT_CMD64X, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, | |
11420 | - {DEVID_CMD646, "CMD646", PCI_CMD64X, NULL, INIT_CMD64X, NULL, {{0x00,0x00,0x00}, {0x51,0x80,0x80}}, ON_BOARD, 0 }, | |
11421 | - {DEVID_CMD648, "CMD648", PCI_CMD64X, ATA66_CMD64X, INIT_CMD64X, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, | |
11422 | - {DEVID_CMD649, "CMD649", PCI_CMD64X, ATA66_CMD64X, INIT_CMD64X, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, | |
11423 | - {DEVID_HT6565, "HT6565", NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, | |
11424 | - {DEVID_OPTI621, "OPTI621", NULL, NULL, INIT_OPTI621, NULL, {{0x45,0x80,0x00}, {0x40,0x08,0x00}}, ON_BOARD, 0 }, | |
11425 | - {DEVID_OPTI621X,"OPTI621X", NULL, NULL, INIT_OPTI621, NULL, {{0x45,0x80,0x00}, {0x40,0x08,0x00}}, ON_BOARD, 0 }, | |
11426 | - {DEVID_TRM290, "TRM290", NULL, NULL, INIT_TRM290, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, | |
11427 | - {DEVID_NS87415, "NS87415", NULL, NULL, INIT_NS87415, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, | |
11428 | - {DEVID_AEC6210, "AEC6210", PCI_AEC62XX, NULL, INIT_AEC62XX, DMA_AEC62XX, {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}}, OFF_BOARD, 0 }, | |
11429 | - {DEVID_AEC6260, "AEC6260", PCI_AEC62XX, ATA66_AEC62XX, INIT_AEC62XX, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, NEVER_BOARD, 0 }, | |
11430 | - {DEVID_AEC6260R,"AEC6260R", PCI_AEC62XX, ATA66_AEC62XX, INIT_AEC62XX, NULL, {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}}, OFF_BOARD, 0 }, | |
11431 | - {DEVID_W82C105, "W82C105", PCI_W82C105, NULL, INIT_W82C105, DMA_W82C105, {{0x40,0x01,0x01}, {0x40,0x10,0x10}}, ON_BOARD, 0 }, | |
11432 | - {DEVID_UM8673F, "UM8673F", NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, | |
11433 | - {DEVID_UM8886A, "UM8886A", NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, | |
11434 | - {DEVID_UM8886BF,"UM8886BF", NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, | |
11435 | - {DEVID_HPT34X, "HPT34X", PCI_HPT34X, NULL, INIT_HPT34X, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, NEVER_BOARD, 16 }, | |
11436 | - {DEVID_HPT366, "HPT366", PCI_HPT366, ATA66_HPT366, INIT_HPT366, DMA_HPT366, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 240 }, | |
11437 | - {DEVID_ALI15X3, "ALI15X3", PCI_ALI15X3, ATA66_ALI15X3, INIT_ALI15X3, DMA_ALI15X3, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, | |
11438 | - {DEVID_CY82C693,"CY82C693", PCI_CY82C693, NULL, INIT_CY82C693, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, | |
11439 | - {DEVID_HINT, "HINT_IDE", NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, | |
11440 | - {DEVID_CS5530, "CS5530", PCI_CS5530, NULL, INIT_CS5530, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, | |
11441 | - {DEVID_AMD7401, "AMD7401", NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, | |
11442 | - {DEVID_AMD7409, "AMD7409", PCI_AMD74XX, ATA66_AMD74XX, INIT_AMD74XX, DMA_AMD74XX, {{0x40,0x01,0x01}, {0x40,0x02,0x02}}, ON_BOARD, 0 }, | |
11443 | - {DEVID_AMD7411, "AMD7411", PCI_AMD74XX, ATA66_AMD74XX, INIT_AMD74XX, DMA_AMD74XX, {{0x40,0x01,0x01}, {0x40,0x02,0x02}}, ON_BOARD, 0 }, | |
11444 | - {DEVID_PDCADMA, "PDCADMA", PCI_PDCADMA, ATA66_PDCADMA, INIT_PDCADMA, DMA_PDCADMA, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 0 }, | |
11445 | - {DEVID_SLC90E66,"SLC90E66", PCI_SLC90E66, ATA66_SLC90E66, INIT_SLC90E66, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, | |
11446 | - {DEVID_OSB4, "ServerWorks OSB4", PCI_SVWKS, ATA66_SVWKS, INIT_SVWKS, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, | |
11447 | - {DEVID_CSB5, "ServerWorks CSB5", PCI_SVWKS, ATA66_SVWKS, INIT_SVWKS, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, | |
11448 | - {DEVID_ITE8172G,"IT8172G", PCI_IT8172, NULL, INIT_IT8172, NULL, {{0x00,0x00,0x00}, {0x40,0x00,0x01}}, ON_BOARD, 0 }, | |
11449 | - {IDE_PCI_DEVID_NULL, "PCI_IDE", NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }}; | |
11450 | + {DEVID_PDC20246,"PDC20246", NULL, PCI_PDC202XX, NULL, INIT_PDC202XX, NULL, {{0x50,0x02,0x02}, {0x50,0x04,0x04}}, OFF_BOARD, 16 }, | |
11451 | + {DEVID_PDC20262,"PDC20262", NULL, PCI_PDC202XX, ATA66_PDC202XX, INIT_PDC202XX, NULL, {{0x50,0x02,0x02}, {0x50,0x04,0x04}}, OFF_BOARD, 48 }, | |
11452 | + {DEVID_PDC20263,"PDC20263", NULL, PCI_PDC202XX, ATA66_PDC202XX, INIT_PDC202XX, NULL, {{0x50,0x02,0x02}, {0x50,0x04,0x04}}, OFF_BOARD, 48 }, | |
11453 | + {DEVID_PDC20265,"PDC20265", FIXUP_PDC20265, PCI_PDC202XX, ATA66_PDC202XX, INIT_PDC202XX, NULL, {{0x50,0x02,0x02}, {0x50,0x04,0x04}}, OFF_BOARD, 48 }, | |
11454 | + {DEVID_PDC20267,"PDC20267", NULL, PCI_PDC202XX, ATA66_PDC202XX, INIT_PDC202XX, NULL, {{0x50,0x02,0x02}, {0x50,0x04,0x04}}, OFF_BOARD, 48 }, | |
11455 | +#endif | |
11456 | + {DEVID_PDC20268,"PDC20268", NULL, PCI_PDC202XX, ATA66_PDC202XX, INIT_PDC202XX, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 0 }, | |
11457 | + /* | |
11458 | + * Promise used a different PCI ident for the raid card apparently | |
11459 | + * to try and prevent Linux detecting it and using our own raid code. | |
11460 | + * We want to detect it for the ataraid drivers, so we have to list | |
11461 | + * both here.. | |
11462 | + */ | |
11463 | + {DEVID_PDC20270,"PDC20270", FIXUP_PDC20270, PCI_PDC202XX, ATA66_PDC202XX, INIT_PDC202XX, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 0 }, | |
11464 | + {DEVID_PDC20269,"PDC20269", NULL, PCI_PDC202XX, ATA66_PDC202XX, INIT_PDC202XX, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 0 }, | |
11465 | + {DEVID_PDC20271,"PDC20271", NULL, PCI_PDC202XX, ATA66_PDC202XX, INIT_PDC202XX, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 0 }, | |
11466 | + {DEVID_PDC20275,"PDC20275", NULL, PCI_PDC202XX, ATA66_PDC202XX, INIT_PDC202XX, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 0 }, | |
11467 | + {DEVID_PDC20276,"PDC20276", NULL, PCI_PDC202XX, ATA66_PDC202XX, INIT_PDC202XX, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 0 }, | |
11468 | + {DEVID_PDC20277,"PDC20277", NULL, PCI_PDC202XX, ATA66_PDC202XX, INIT_PDC202XX, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 0 }, | |
11469 | + {DEVID_RZ1000, "RZ1000", NULL, NULL, NULL, INIT_RZ1000, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, | |
11470 | + {DEVID_RZ1001, "RZ1001", NULL, NULL, NULL, INIT_RZ1000, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, | |
11471 | + {DEVID_SAMURAI, "SAMURAI", NULL, NULL, NULL, INIT_SAMURAI, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, | |
11472 | + {DEVID_CMD640, "CMD640", NULL, NULL, NULL, IDE_IGNORE, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, | |
11473 | + {DEVID_NS87410, "NS87410", NULL, NULL, NULL, NULL, NULL, {{0x43,0x08,0x08}, {0x47,0x08,0x08}}, ON_BOARD, 0 }, | |
11474 | + {DEVID_SIS5513, "SIS5513", FIXUP_SIS5513, PCI_SIS5513, ATA66_SIS5513, INIT_SIS5513, NULL, {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}}, ON_BOARD, 0 }, | |
11475 | + {DEVID_CMD643, "CMD643", NULL, PCI_CMD64X, NULL, INIT_CMD64X, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, | |
11476 | + {DEVID_CMD646, "CMD646", NULL, PCI_CMD64X, NULL, INIT_CMD64X, NULL, {{0x00,0x00,0x00}, {0x51,0x80,0x80}}, ON_BOARD, 0 }, | |
11477 | + {DEVID_CMD648, "CMD648", NULL, PCI_CMD64X, ATA66_CMD64X, INIT_CMD64X, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, | |
11478 | + {DEVID_CMD649, "CMD649", NULL, PCI_CMD64X, ATA66_CMD64X, INIT_CMD64X, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, | |
11479 | + {DEVID_CMD680, "CMD680", NULL, PCI_CMD64X, ATA66_CMD64X, INIT_CMD64X, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, | |
11480 | + {DEVID_HT6565, "HT6565", NULL, NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, | |
11481 | + {DEVID_OPTI621, "OPTI621", FIXUP_OPTI621, NULL, NULL, INIT_OPTI621, NULL, {{0x45,0x80,0x00}, {0x40,0x08,0x00}}, ON_BOARD, 0 }, | |
11482 | + {DEVID_OPTI621X,"OPTI621X", FIXUP_OPTI621, NULL, NULL, INIT_OPTI621, NULL, {{0x45,0x80,0x00}, {0x40,0x08,0x00}}, ON_BOARD, 0 }, | |
11483 | + {DEVID_TRM290, "TRM290", NULL, NULL, NULL, INIT_TRM290, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, | |
11484 | + {DEVID_NS87415, "NS87415", NULL, NULL, NULL, INIT_NS87415, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, | |
11485 | + {DEVID_AEC6210, "AEC6210", NULL, PCI_AEC62XX, NULL, INIT_AEC62XX, DMA_AEC62XX, {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}}, OFF_BOARD, 0 }, | |
11486 | + {DEVID_AEC6260, "AEC6260", NULL, PCI_AEC62XX, ATA66_AEC62XX, INIT_AEC62XX, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, NEVER_BOARD, 0 }, | |
11487 | + {DEVID_AEC6260R,"AEC6260R", NULL, PCI_AEC62XX, ATA66_AEC62XX, INIT_AEC62XX, NULL, {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}}, OFF_BOARD, 0 }, | |
11488 | + {DEVID_AEC6280, "AEC6X80", FIXUP_AEC62XX, PCI_AEC62XX, ATA66_AEC62XX, INIT_AEC62XX, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, NEVER_BOARD, 0 }, | |
11489 | + {DEVID_AEC6880, "AEC6X80R", FIXUP_AEC62XX, PCI_AEC62XX, ATA66_AEC62XX, INIT_AEC62XX, NULL, {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}}, OFF_BOARD, 0 }, | |
11490 | + {DEVID_W82C105, "W82C105", NULL, PCI_W82C105, NULL, INIT_W82C105, DMA_W82C105, {{0x40,0x01,0x01}, {0x40,0x10,0x10}}, ON_BOARD, 0 }, | |
11491 | + {DEVID_UM8673F, "UM8673F", NULL, NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, | |
11492 | + {DEVID_UM8886A, "UM8886A", NULL, NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, | |
11493 | + {DEVID_UM8886BF,"UM8886BF", NULL, NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, | |
11494 | + {DEVID_HPT34X, "HPT34X", FIXUP_HPT34X, PCI_HPT34X, NULL, INIT_HPT34X, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, NEVER_BOARD, 16 }, | |
11495 | + {DEVID_HPT366, "HPT366", FIXUP_HPT366, PCI_HPT366, ATA66_HPT366, INIT_HPT366, DMA_HPT366, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 240 }, | |
11496 | + {DEVID_HPT372, "HPT372A", NULL, PCI_HPT366, ATA66_HPT366, INIT_HPT366, DMA_HPT366, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 0 }, | |
11497 | + {DEVID_HPT302, "HPT302", NULL, PCI_HPT366, ATA66_HPT366, INIT_HPT366, DMA_HPT366, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 0 }, | |
11498 | + {DEVID_HPT371, "HPT371", NULL, PCI_HPT366, ATA66_HPT366, INIT_HPT366, DMA_HPT366, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 0 }, | |
11499 | + {DEVID_HPT374, "HPT374", FIXUP_HPT374, PCI_HPT366, ATA66_HPT366, INIT_HPT366, DMA_HPT366, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 0 }, | |
11500 | + {DEVID_ALI15X3, "ALI15X3", FIXUP_ALI15X3, PCI_ALI15X3, ATA66_ALI15X3, INIT_ALI15X3, DMA_ALI15X3, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, | |
11501 | + {DEVID_CY82C693,"CY82C693", FIXUP_CY82C693, PCI_CY82C693, NULL, INIT_CY82C693, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, | |
11502 | + {DEVID_HINT, "HINT_IDE", NULL, NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, | |
11503 | + {DEVID_CS5530, "CS5530", NULL, PCI_CS5530, NULL, INIT_CS5530, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, | |
11504 | + {DEVID_AMD7401, "AMD7401", FIXUP_AMD74XX, NULL, NULL, NULL, DMA_AMD74XX, {{0x40,0x01,0x01}, {0x40,0x02,0x02}}, ON_BOARD, 0 }, | |
11505 | + {DEVID_AMD7409, "AMD7409", FIXUP_AMD74XX, PCI_AMD74XX, ATA66_AMD74XX, INIT_AMD74XX, DMA_AMD74XX, {{0x40,0x01,0x01}, {0x40,0x02,0x02}}, ON_BOARD, 0 }, | |
11506 | + {DEVID_AMD7411, "AMD7411", FIXUP_AMD74XX, PCI_AMD74XX, ATA66_AMD74XX, INIT_AMD74XX, DMA_AMD74XX, {{0x40,0x01,0x01}, {0x40,0x02,0x02}}, ON_BOARD, 0 }, | |
11507 | + {DEVID_AMD7441, "AMD7441", FIXUP_AMD74XX, PCI_AMD74XX, ATA66_AMD74XX, INIT_AMD74XX, DMA_AMD74XX, {{0x40,0x01,0x01}, {0x40,0x02,0x02}}, ON_BOARD, 0 }, | |
11508 | + {DEVID_PDCADMA, "PDCADMA", NULL, PCI_PDCADMA, ATA66_PDCADMA, INIT_PDCADMA, DMA_PDCADMA, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 0 }, | |
11509 | + {DEVID_SLC90E66,"SLC90E66", NULL, PCI_SLC90E66, ATA66_SLC90E66, INIT_SLC90E66, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, | |
11510 | + {DEVID_OSB4, "SvrWks OSB4", NULL, PCI_SVWKS, ATA66_SVWKS, INIT_SVWKS, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, | |
11511 | + {DEVID_CSB5, "SvrWks CSB5", NULL, PCI_SVWKS, ATA66_SVWKS, INIT_SVWKS, DMA_SVWKS, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, | |
11512 | + {DEVID_CSB6, "SvrWks CSB6", FIXUP_CSB6, PCI_SVWKS, ATA66_SVWKS, INIT_SVWKS, DMA_SVWKS, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, | |
11513 | + {DEVID_ITE8172G,"IT8172G", FIXUP_IT8172, PCI_IT8172, NULL, INIT_IT8172, NULL, {{0x00,0x00,0x00}, {0x40,0x00,0x01}}, ON_BOARD, 0 }, | |
11514 | + {IDE_PCI_DEVID_NULL, "PCI_IDE", NULL, NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }}; | |
11515 | ||
11516 | /* | |
11517 | * This allows offboard ide-pci cards the enable a BIOS, verify interrupt | |
11518 | @@ -453,14 +525,33 @@ | |
11519 | { | |
11520 | switch(dev->device) { | |
11521 | case PCI_DEVICE_ID_TTI_HPT366: | |
11522 | + case PCI_DEVICE_ID_TTI_HPT372: | |
11523 | + case PCI_DEVICE_ID_TTI_HPT302: | |
11524 | + case PCI_DEVICE_ID_TTI_HPT371: | |
11525 | + case PCI_DEVICE_ID_TTI_HPT374: | |
11526 | case PCI_DEVICE_ID_PROMISE_20246: | |
11527 | case PCI_DEVICE_ID_PROMISE_20262: | |
11528 | + case PCI_DEVICE_ID_PROMISE_20263: | |
11529 | case PCI_DEVICE_ID_PROMISE_20265: | |
11530 | case PCI_DEVICE_ID_PROMISE_20267: | |
11531 | case PCI_DEVICE_ID_PROMISE_20268: | |
11532 | - case PCI_DEVICE_ID_ARTOP_ATP850UF: | |
11533 | - case PCI_DEVICE_ID_ARTOP_ATP860: | |
11534 | - case PCI_DEVICE_ID_ARTOP_ATP860R: | |
11535 | + case PCI_DEVICE_ID_PROMISE_20270: | |
11536 | + case PCI_DEVICE_ID_PROMISE_20269: | |
11537 | + case PCI_DEVICE_ID_PROMISE_20271: | |
11538 | + case PCI_DEVICE_ID_PROMISE_20275: | |
11539 | + case PCI_DEVICE_ID_PROMISE_20276: | |
11540 | + case PCI_DEVICE_ID_PROMISE_20277: | |
11541 | + /* | |
11542 | + * case PCI_DEVICE_ID_ARTOP_ATP850UF: | |
11543 | + * same device ID value as PCI_DEVICE_ID_TTI_HPT372 | |
11544 | + * case PCI_DEVICE_ID_ARTOP_ATP860: | |
11545 | + * same device ID value as PCI_DEVICE_ID_TTI_HPT302 | |
11546 | + * case PCI_DEVICE_ID_ARTOP_ATP860R: | |
11547 | + * same device ID value as PCI_DEVICE_ID_TTI_HPT371 | |
11548 | + * case PCI_DEVICE_ID_ARTOP_ATP865: | |
11549 | + * same device ID value as PCI_DEVICE_ID_TTI_HPT374 | |
11550 | + */ | |
11551 | + case PCI_DEVICE_ID_ARTOP_ATP865R: | |
11552 | return dev->irq; | |
11553 | default: | |
11554 | break; | |
11555 | @@ -498,7 +589,8 @@ | |
11556 | if (hwif->io_ports[IDE_DATA_OFFSET] == io_base) { | |
11557 | if (hwif->chipset == ide_unknown) | |
11558 | return hwif; /* match */ | |
11559 | - printk("%s: port 0x%04lx already claimed by %s\n", name, io_base, hwif->name); | |
11560 | + printk("%s: port 0x%04lx already claimed by %s\n", | |
11561 | + name, io_base, hwif->name); | |
11562 | return NULL; /* already claimed */ | |
11563 | } | |
11564 | } | |
11565 | @@ -541,9 +633,11 @@ | |
11566 | /* | |
11567 | * Place both IDE interfaces into PCI "native" mode: | |
11568 | */ | |
11569 | - if (pci_read_config_byte(dev, PCI_CLASS_PROG, &progif) || (progif & 5) != 5) { | |
11570 | + if (pci_read_config_byte(dev, PCI_CLASS_PROG, &progif) || | |
11571 | + (progif & 5) != 5) { | |
11572 | if ((progif & 0xa) != 0xa) { | |
11573 | - printk("%s: device not capable of full native PCI mode\n", name); | |
11574 | + printk("%s: device not capable of full " | |
11575 | + "native PCI mode\n", name); | |
11576 | return 1; | |
11577 | } | |
11578 | printk("%s: placing both ports into native PCI mode\n", name); | |
11579 | @@ -578,7 +672,7 @@ | |
11580 | * we "know" about, this information is in the ide_pci_device_t struct; | |
11581 | * for all other chipsets, we just assume both interfaces are enabled. | |
11582 | */ | |
11583 | -static void __init ide_setup_pci_device (struct pci_dev *dev, ide_pci_device_t *d) | |
11584 | +void __init ide_setup_pci_device (struct pci_dev *dev, ide_pci_device_t *d) | |
11585 | { | |
11586 | unsigned int port, at_least_one_hwif_enabled = 0, autodma = 0, pciirq = 0; | |
11587 | unsigned short pcicmd = 0, tried_config = 0; | |
11588 | @@ -592,7 +686,17 @@ | |
11589 | autodma = 1; | |
11590 | #endif | |
11591 | ||
11592 | - pci_enable_device(dev); | |
11593 | + if (d->init_hwif == IDE_NO_DRIVER) { | |
11594 | + printk(KERN_WARNING "%s: detected chipset, " | |
11595 | + "but driver not compiled in!\n", d->name); | |
11596 | + d->init_hwif = NULL; | |
11597 | + } | |
11598 | + | |
11599 | + if (pci_enable_device(dev)) { | |
11600 | + printk(KERN_WARNING "%s: (ide_setup_pci_device:) " | |
11601 | + "Could not enable device.\n", d->name); | |
11602 | + return; | |
11603 | + } | |
11604 | ||
11605 | check_if_enabled: | |
11606 | if (pci_read_config_word(dev, PCI_COMMAND, &pcicmd)) { | |
11607 | @@ -621,14 +725,6 @@ | |
11608 | ||
11609 | pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); | |
11610 | class_rev &= 0xff; | |
11611 | - | |
11612 | - if (IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT34X)) { | |
11613 | - /* see comments in hpt34x.c on why..... */ | |
11614 | - char *chipset_names[] = {"HPT343", "HPT345"}; | |
11615 | - strcpy(d->name, chipset_names[(pcicmd & PCI_COMMAND_MEMORY) ? 1 : 0]); | |
11616 | - d->bootable = (pcicmd & PCI_COMMAND_MEMORY) ? OFF_BOARD : NEVER_BOARD; | |
11617 | - } | |
11618 | - | |
11619 | printk("%s: chipset revision %d\n", d->name, class_rev); | |
11620 | ||
11621 | /* | |
11622 | @@ -642,13 +738,12 @@ | |
11623 | people have some strange ideas about proprietary so we have | |
11624 | to act otherwise on those. The supertrak however we need | |
11625 | to skip */ | |
11626 | - if (IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20265)) | |
11627 | + if (IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20265) || IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20276)) | |
11628 | { | |
11629 | - printk(KERN_INFO "ide: Found promise 20265 in RAID mode.\n"); | |
11630 | if(dev->bus->self && dev->bus->self->vendor == PCI_VENDOR_ID_INTEL && | |
11631 | - dev->bus->self->device == PCI_DEVICE_ID_INTEL_I960) | |
11632 | + (dev->bus->self->device == PCI_DEVICE_ID_INTEL_I960 || dev->bus->self->device == PCI_DEVICE_ID_INTEL_I960RM)) | |
11633 | { | |
11634 | - printk(KERN_INFO "ide: Skipping Promise PDC20265 attached to I2O RAID controller.\n"); | |
11635 | + printk(KERN_INFO "ide: Skipping Promise IDE controller attached to I2O RAID controller.\n"); | |
11636 | return; | |
11637 | } | |
11638 | } | |
11639 | @@ -656,7 +751,8 @@ | |
11640 | Suspect a fastrak and fall through */ | |
11641 | } | |
11642 | if ((dev->class & ~(0xfa)) != ((PCI_CLASS_STORAGE_IDE << 8) | 5)) { | |
11643 | - printk("%s: not 100%% native mode: will probe irqs later\n", d->name); | |
11644 | + printk("%s: not 100%% native mode: " | |
11645 | + "will probe irqs later\n", d->name); | |
11646 | /* | |
11647 | * This allows offboard ide-pci cards the enable a BIOS, | |
11648 | * verify interrupt settings of split-mirror pci-config | |
11649 | @@ -689,34 +785,52 @@ | |
11650 | ide_pci_enablebit_t *e = &(d->enablebits[port]); | |
11651 | ||
11652 | /* | |
11653 | - * If this is a Promise FakeRaid controller, the 2nd controller will be marked as | |
11654 | - * disabled while it is actually there and enabled by the bios for raid purposes. | |
11655 | + * If this is a Promise FakeRaid controller, | |
11656 | + * the 2nd controller will be marked as | |
11657 | + * disabled while it is actually there and enabled | |
11658 | + * by the bios for raid purposes. | |
11659 | * Skip the normal "is it enabled" test for those. | |
11660 | */ | |
11661 | - if ((IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20265)) && (secondpdc++==1) && (port==1) ) | |
11662 | + if ((IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20265)) && | |
11663 | + (secondpdc++==1) && (port==1)) | |
11664 | goto controller_ok; | |
11665 | - if ((IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20262)) && (secondpdc++==1) && (port==1) ) | |
11666 | + if ((IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20262)) && | |
11667 | + (secondpdc++==1) && (port==1)) | |
11668 | goto controller_ok; | |
11669 | ||
11670 | - if (e->reg && (pci_read_config_byte(dev, e->reg, &tmp) || (tmp & e->mask) != e->val)) | |
11671 | + if (e->reg && (pci_read_config_byte(dev, e->reg, &tmp) || | |
11672 | + (tmp & e->mask) != e->val)) | |
11673 | continue; /* port not enabled */ | |
11674 | controller_ok: | |
11675 | - if (IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT366) && (port) && (class_rev < 0x03)) | |
11676 | + if (IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT366) && | |
11677 | + (port) && (class_rev < 0x03)) | |
11678 | + return; | |
11679 | + if (IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT302) && (port)) | |
11680 | + return; | |
11681 | + if (IDE_PCI_DEVID_EQ(d->devid, DEVID_CSB6) && | |
11682 | + (port) && (!(PCI_FUNC(dev->devfn) & 1))) | |
11683 | return; | |
11684 | - if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE || (dev->class & (port ? 4 : 1)) != 0) { | |
11685 | + if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE || | |
11686 | + (dev->class & (port ? 4 : 1)) != 0) { | |
11687 | ctl = dev->resource[(2*port)+1].start; | |
11688 | base = dev->resource[2*port].start; | |
11689 | if (!(ctl & PCI_BASE_ADDRESS_IO_MASK) || | |
11690 | !(base & PCI_BASE_ADDRESS_IO_MASK)) { | |
11691 | - printk("%s: IO baseregs (BIOS) are reported as MEM, report to <andre@linux-ide.org>.\n", d->name); | |
11692 | + printk("%s: IO baseregs (BIOS) are reported " | |
11693 | + "as MEM, report to " | |
11694 | + "<andre@linux-ide.org>.\n", d->name); | |
11695 | #if 0 | |
11696 | - /* FIXME! This really should check that it really gets the IO/MEM part right! */ | |
11697 | + /* | |
11698 | + * FIXME! This really should check that | |
11699 | + * it really gets the IO/MEM part right! | |
11700 | + */ | |
11701 | continue; | |
11702 | #endif | |
11703 | } | |
11704 | } | |
11705 | if ((ctl && !base) || (base && !ctl)) { | |
11706 | - printk("%s: inconsistent baseregs (BIOS) for port %d, skipping\n", d->name, port); | |
11707 | + printk("%s: inconsistent baseregs (BIOS) " | |
11708 | + "for port %d, skipping\n", d->name, port); | |
11709 | continue; | |
11710 | } | |
11711 | if (!ctl) | |
11712 | @@ -752,9 +866,11 @@ | |
11713 | } | |
11714 | if (IDE_PCI_DEVID_EQ(d->devid, DEVID_MPIIX)) | |
11715 | goto bypass_piix_dma; | |
11716 | - | |
11717 | + if (IDE_PCI_DEVID_EQ(d->devid, DEVID_PDCADMA)) | |
11718 | + goto bypass_legacy_dma; | |
11719 | if (hwif->udma_four) { | |
11720 | - printk("%s: ATA-66/100 forced bit set (WARNING)!!\n", d->name); | |
11721 | + printk("%s: ATA-66/100 forced bit set (WARNING)!!\n", | |
11722 | + d->name); | |
11723 | } else { | |
11724 | hwif->udma_four = (d->ata66_check) ? d->ata66_check(hwif) : 0; | |
11725 | } | |
11726 | @@ -769,22 +885,36 @@ | |
11727 | autodma = 0; | |
11728 | if (autodma) | |
11729 | hwif->autodma = 1; | |
11730 | + | |
11731 | if (IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20246) || | |
11732 | IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20262) || | |
11733 | + IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20263) || | |
11734 | IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20265) || | |
11735 | IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20267) || | |
11736 | IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20268) || | |
11737 | - IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20268R) || | |
11738 | + IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20270) || | |
11739 | + IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20269) || | |
11740 | + IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20271) || | |
11741 | + IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20275) || | |
11742 | + IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20276) || | |
11743 | + IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20277) || | |
11744 | IDE_PCI_DEVID_EQ(d->devid, DEVID_AEC6210) || | |
11745 | IDE_PCI_DEVID_EQ(d->devid, DEVID_AEC6260) || | |
11746 | IDE_PCI_DEVID_EQ(d->devid, DEVID_AEC6260R) || | |
11747 | + IDE_PCI_DEVID_EQ(d->devid, DEVID_AEC6280) || | |
11748 | + IDE_PCI_DEVID_EQ(d->devid, DEVID_AEC6880) || | |
11749 | IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT34X) || | |
11750 | IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT366) || | |
11751 | + IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT372) || | |
11752 | + IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT302) || | |
11753 | + IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT371) || | |
11754 | + IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT374) || | |
11755 | IDE_PCI_DEVID_EQ(d->devid, DEVID_CS5530) || | |
11756 | IDE_PCI_DEVID_EQ(d->devid, DEVID_CY82C693) || | |
11757 | IDE_PCI_DEVID_EQ(d->devid, DEVID_CMD646) || | |
11758 | IDE_PCI_DEVID_EQ(d->devid, DEVID_CMD648) || | |
11759 | IDE_PCI_DEVID_EQ(d->devid, DEVID_CMD649) || | |
11760 | + IDE_PCI_DEVID_EQ(d->devid, DEVID_CMD680) || | |
11761 | IDE_PCI_DEVID_EQ(d->devid, DEVID_OSB4) || | |
11762 | ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE && (dev->class & 0x80))) { | |
11763 | unsigned long dma_base = ide_get_or_set_dma_base(hwif, (!mate && d->extra) ? d->extra : 0, d->name); | |
11764 | @@ -811,6 +941,7 @@ | |
11765 | } | |
11766 | } | |
11767 | #endif /* CONFIG_BLK_DEV_IDEDMA */ | |
11768 | +bypass_legacy_dma: | |
11769 | bypass_piix_dma: | |
11770 | bypass_umc_dma: | |
11771 | if (d->init_hwif) /* Call chipset-specific routine for each enabled hwif */ | |
11772 | @@ -822,62 +953,6 @@ | |
11773 | printk("%s: neither IDE port enabled (BIOS)\n", d->name); | |
11774 | } | |
11775 | ||
11776 | -static void __init hpt366_device_order_fixup (struct pci_dev *dev, ide_pci_device_t *d) | |
11777 | -{ | |
11778 | - struct pci_dev *dev2 = NULL, *findev; | |
11779 | - ide_pci_device_t *d2; | |
11780 | - unsigned char pin1 = 0, pin2 = 0; | |
11781 | - unsigned int class_rev; | |
11782 | - char *chipset_names[] = {"HPT366", "HPT366", "HPT368", "HPT370", "HPT370A"}; | |
11783 | - | |
11784 | - if (PCI_FUNC(dev->devfn) & 1) | |
11785 | - return; | |
11786 | - | |
11787 | - pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); | |
11788 | - class_rev &= 0xff; | |
11789 | - | |
11790 | - strcpy(d->name, chipset_names[class_rev]); | |
11791 | - | |
11792 | - switch(class_rev) { | |
11793 | - case 4: | |
11794 | - case 3: printk("%s: IDE controller on PCI bus %02x dev %02x\n", d->name, dev->bus->number, dev->devfn); | |
11795 | - ide_setup_pci_device(dev, d); | |
11796 | - return; | |
11797 | - default: break; | |
11798 | - } | |
11799 | - | |
11800 | - pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin1); | |
11801 | - pci_for_each_dev(findev) { | |
11802 | - if ((findev->vendor == dev->vendor) && | |
11803 | - (findev->device == dev->device) && | |
11804 | - ((findev->devfn - dev->devfn) == 1) && | |
11805 | - (PCI_FUNC(findev->devfn) & 1)) { | |
11806 | - dev2 = findev; | |
11807 | - pci_read_config_byte(dev2, PCI_INTERRUPT_PIN, &pin2); | |
11808 | - hpt363_shared_pin = (pin1 != pin2) ? 1 : 0; | |
11809 | - hpt363_shared_irq = (dev->irq == dev2->irq) ? 1 : 0; | |
11810 | - if (hpt363_shared_pin && hpt363_shared_irq) { | |
11811 | - d->bootable = ON_BOARD; | |
11812 | - printk("%s: onboard version of chipset, pin1=%d pin2=%d\n", d->name, pin1, pin2); | |
11813 | -#if 0 | |
11814 | - /* I forgot why I did this once, but it fixed something. */ | |
11815 | - pci_write_config_byte(dev2, PCI_INTERRUPT_PIN, dev->irq); | |
11816 | - printk("PCI: %s: Fixing interrupt %d pin %d to ZERO \n", d->name, dev2->irq, pin2); | |
11817 | - pci_write_config_byte(dev2, PCI_INTERRUPT_LINE, 0); | |
11818 | -#endif | |
11819 | - } | |
11820 | - break; | |
11821 | - } | |
11822 | - } | |
11823 | - printk("%s: IDE controller on PCI bus %02x dev %02x\n", d->name, dev->bus->number, dev->devfn); | |
11824 | - ide_setup_pci_device(dev, d); | |
11825 | - if (!dev2) | |
11826 | - return; | |
11827 | - d2 = d; | |
11828 | - printk("%s: IDE controller on PCI bus %02x dev %02x\n", d2->name, dev2->bus->number, dev2->devfn); | |
11829 | - ide_setup_pci_device(dev2, d2); | |
11830 | -} | |
11831 | - | |
11832 | /* | |
11833 | * ide_scan_pcibus() gets invoked at boot time from ide.c. | |
11834 | * It finds all PCI IDE controllers and calls ide_setup_pci_device for them. | |
11835 | @@ -889,25 +964,32 @@ | |
11836 | ||
11837 | devid.vid = dev->vendor; | |
11838 | devid.did = dev->device; | |
11839 | - for (d = ide_pci_chipsets; d->devid.vid && !IDE_PCI_DEVID_EQ(d->devid, devid); ++d); | |
11840 | + for (d = ide_pci_chipsets; | |
11841 | + d->devid.vid && !IDE_PCI_DEVID_EQ(d->devid, devid); ++d); | |
11842 | + | |
11843 | if (d->init_hwif == IDE_IGNORE) | |
11844 | - printk("%s: ignored by ide_scan_pci_device() (uses own driver)\n", d->name); | |
11845 | - else if (IDE_PCI_DEVID_EQ(d->devid, DEVID_OPTI621V) && !(PCI_FUNC(dev->devfn) & 1)) | |
11846 | + printk("%s: ignored by ide_scan_pci_device() " | |
11847 | + "(uses own driver)\n", d->name); | |
11848 | + else if (d->fixup_device) | |
11849 | + d->fixup_device(dev, d); | |
11850 | +#if 0 | |
11851 | + else if (((dev->class >> 8) != PCI_CLASS_STORAGE_IDE) && | |
11852 | + (!(PCI_FUNC(dev->devfn) & 1))) | |
11853 | return; | |
11854 | - else if (IDE_PCI_DEVID_EQ(d->devid, DEVID_CY82C693) && (!(PCI_FUNC(dev->devfn) & 1) || !((dev->class >> 8) == PCI_CLASS_STORAGE_IDE))) | |
11855 | - return; /* CY82C693 is more than only a IDE controller */ | |
11856 | - else if (IDE_PCI_DEVID_EQ(d->devid, DEVID_ITE8172G) && (!(PCI_FUNC(dev->devfn) & 1) || !((dev->class >> 8) == PCI_CLASS_STORAGE_IDE))) | |
11857 | - return; /* IT8172G is also more than only an IDE controller */ | |
11858 | - else if (IDE_PCI_DEVID_EQ(d->devid, DEVID_UM8886A) && !(PCI_FUNC(dev->devfn) & 1)) | |
11859 | +#endif | |
11860 | + else if (IDE_PCI_DEVID_EQ(d->devid, DEVID_UM8886A) && | |
11861 | + (!(PCI_FUNC(dev->devfn) & 1))) | |
11862 | return; /* UM8886A/BF pair */ | |
11863 | - else if (IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT366)) | |
11864 | - hpt366_device_order_fixup(dev, d); | |
11865 | - else if (!IDE_PCI_DEVID_EQ(d->devid, IDE_PCI_DEVID_NULL) || (dev->class >> 8) == PCI_CLASS_STORAGE_IDE) { | |
11866 | + else if (!IDE_PCI_DEVID_EQ(d->devid, IDE_PCI_DEVID_NULL) || | |
11867 | + (dev->class >> 8) == PCI_CLASS_STORAGE_IDE) { | |
11868 | if (IDE_PCI_DEVID_EQ(d->devid, IDE_PCI_DEVID_NULL)) | |
11869 | - printk("%s: unknown IDE controller on PCI bus %02x device %02x, VID=%04x, DID=%04x\n", | |
11870 | - d->name, dev->bus->number, dev->devfn, devid.vid, devid.did); | |
11871 | + printk("%s: unknown IDE controller on PCI bus " | |
11872 | + "%02x device %02x, VID=%04x, DID=%04x\n", | |
11873 | + d->name, dev->bus->number, dev->devfn, | |
11874 | + devid.vid, devid.did); | |
11875 | else | |
11876 | - printk("%s: IDE controller on PCI bus %02x dev %02x\n", d->name, dev->bus->number, dev->devfn); | |
11877 | + printk("%s: IDE controller on PCI bus %02x dev %02x\n", | |
11878 | + d->name, dev->bus->number, dev->devfn); | |
11879 | ide_setup_pci_device(dev, d); | |
11880 | } | |
11881 | } | |
11882 | diff -Nur linux.org/drivers/ide/ide-pmac.c linux/drivers/ide/ide-pmac.c | |
11883 | --- linux.org/drivers/ide/ide-pmac.c Mon Feb 25 20:37:57 2002 | |
11884 | +++ linux/drivers/ide/ide-pmac.c Thu Jul 18 14:24:33 2002 | |
11885 | @@ -26,11 +26,14 @@ | |
11886 | #include <linux/ide.h> | |
11887 | #include <linux/notifier.h> | |
11888 | #include <linux/reboot.h> | |
11889 | +#include <linux/pci.h> | |
11890 | + | |
11891 | #include <asm/prom.h> | |
11892 | #include <asm/io.h> | |
11893 | #include <asm/dbdma.h> | |
11894 | #include <asm/ide.h> | |
11895 | #include <asm/mediabay.h> | |
11896 | +#include <asm/pci-bridge.h> | |
11897 | #include <asm/machdep.h> | |
11898 | #include <asm/pmac_feature.h> | |
11899 | #include <asm/sections.h> | |
11900 | @@ -41,7 +44,6 @@ | |
11901 | #endif | |
11902 | #include "ide_modes.h" | |
11903 | ||
11904 | -extern char *ide_dmafunc_verbose(ide_dma_action_t dmafunc); | |
11905 | extern void ide_do_request(ide_hwgroup_t *hwgroup, int masked_irq); | |
11906 | ||
11907 | #define IDE_PMAC_DEBUG | |
11908 | @@ -55,11 +57,18 @@ | |
11909 | int aapl_bus_id; | |
11910 | struct device_node* node; | |
11911 | u32 timings[2]; | |
11912 | - struct resource* reg_resource; | |
11913 | #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC | |
11914 | + /* Those fields are duplicating what is in hwif. We currently | |
11915 | + * can't use the hwif ones because of some assumptions that are | |
11916 | + * beeing done by the generic code about the kind of dma controller | |
11917 | + * and format of the dma table. This will have to be fixed though. | |
11918 | + */ | |
11919 | volatile struct dbdma_regs* dma_regs; | |
11920 | - struct dbdma_cmd* dma_table; | |
11921 | - struct resource* dma_resource; | |
11922 | + struct dbdma_cmd* dma_table_cpu; | |
11923 | + dma_addr_t dma_table_dma; | |
11924 | + struct scatterlist* sg_table; | |
11925 | + int sg_nents; | |
11926 | + int sg_dma_direction; | |
11927 | #endif | |
11928 | ||
11929 | } pmac_ide[MAX_HWIFS] __pmacdata; | |
11930 | @@ -308,7 +317,7 @@ | |
11931 | ide_hwifs[ix].tuneproc = pmac_ide_tuneproc; | |
11932 | ide_hwifs[ix].selectproc = pmac_ide_selectproc; | |
11933 | ide_hwifs[ix].speedproc = &pmac_ide_tune_chipset; | |
11934 | - if (pmac_ide[ix].dma_regs && pmac_ide[ix].dma_table) { | |
11935 | + if (pmac_ide[ix].dma_regs && pmac_ide[ix].dma_table_cpu) { | |
11936 | ide_hwifs[ix].dmaproc = &pmac_ide_dmaproc; | |
11937 | #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC_AUTO | |
11938 | if (!noautodma) | |
11939 | @@ -352,41 +361,6 @@ | |
11940 | } | |
11941 | ||
11942 | ||
11943 | -/* Note: We don't use the generic routine here because for some | |
11944 | - * yet unexplained reasons, it cause some media-bay CD-ROMs to | |
11945 | - * lockup the bus. Strangely, this new version of the code is | |
11946 | - * almost identical to the generic one and works, I've not yet | |
11947 | - * managed to figure out what bit is causing the lockup in the | |
11948 | - * generic code, possibly a timing issue... | |
11949 | - * | |
11950 | - * --BenH | |
11951 | - */ | |
11952 | -static int __pmac | |
11953 | -wait_for_ready(ide_drive_t *drive) | |
11954 | -{ | |
11955 | - /* Timeout bumped for some powerbooks */ | |
11956 | - int timeout = 2000; | |
11957 | - byte stat; | |
11958 | - | |
11959 | - while(--timeout) { | |
11960 | - stat = GET_STAT(); | |
11961 | - if(!(stat & BUSY_STAT)) { | |
11962 | - if (drive->ready_stat == 0) | |
11963 | - break; | |
11964 | - else if((stat & drive->ready_stat) || (stat & ERR_STAT)) | |
11965 | - break; | |
11966 | - } | |
11967 | - mdelay(1); | |
11968 | - } | |
11969 | - if((stat & ERR_STAT) || timeout <= 0) { | |
11970 | - if (stat & ERR_STAT) { | |
11971 | - printk(KERN_ERR "ide_pmac: wait_for_ready, error status: %x\n", stat); | |
11972 | - } | |
11973 | - return 1; | |
11974 | - } | |
11975 | - return 0; | |
11976 | -} | |
11977 | - | |
11978 | static int __pmac | |
11979 | pmac_ide_do_setfeature(ide_drive_t *drive, byte command) | |
11980 | { | |
11981 | @@ -400,7 +374,7 @@ | |
11982 | SELECT_MASK(HWIF(drive), drive, 0); | |
11983 | udelay(1); | |
11984 | (void)GET_STAT(); /* Get rid of pending error state */ | |
11985 | - if(wait_for_ready(drive)) { | |
11986 | + if(wait_for_ready(drive, 2000)) { /* Timeout bumped for some powerbooks */ | |
11987 | printk(KERN_ERR "pmac_ide_do_setfeature disk not ready before SET_FEATURE!\n"); | |
11988 | goto out; | |
11989 | } | |
11990 | @@ -410,10 +384,9 @@ | |
11991 | OUT_BYTE(SETFEATURES_XFER, IDE_FEATURE_REG); | |
11992 | OUT_BYTE(WIN_SETFEATURES, IDE_COMMAND_REG); | |
11993 | udelay(1); | |
11994 | - __save_flags(flags); /* local CPU only */ | |
11995 | - ide__sti(); /* local CPU only -- for jiffies */ | |
11996 | - result = wait_for_ready(drive); | |
11997 | - __restore_flags(flags); /* local CPU only */ | |
11998 | + local_irq_set(flags); | |
11999 | + result = wait_for_ready(drive, 2000); /* Timeout bumped for some powerbooks */ | |
12000 | + local_irq_restore(flags); | |
12001 | OUT_BYTE(drive->ctl, IDE_CONTROL_REG); | |
12002 | if (result) | |
12003 | printk(KERN_ERR "pmac_ide_do_setfeature disk not ready after SET_FEATURE !\n"); | |
12004 | @@ -823,6 +796,8 @@ | |
12005 | struct pmac_ide_hwif* pmhw; | |
12006 | int *bidp; | |
12007 | int in_bay = 0; | |
12008 | + u8 pbus, pid; | |
12009 | + struct pci_dev *pdev = NULL; | |
12010 | ||
12011 | /* | |
12012 | * If this node is not under a mac-io or dbdma node, | |
12013 | @@ -841,6 +816,15 @@ | |
12014 | continue; | |
12015 | } | |
12016 | ||
12017 | + /* We need to find the pci_dev of the mac-io holding the | |
12018 | + * IDE interface | |
12019 | + */ | |
12020 | + if (pci_device_from_OF_node(tp, &pbus, &pid) == 0) | |
12021 | + pdev = pci_find_slot(pbus, pid); | |
12022 | + if (pdev == NULL) | |
12023 | + printk(KERN_WARNING "ide: no PCI host for device %s, DMA disabled\n", | |
12024 | + np->full_name); | |
12025 | + | |
12026 | /* | |
12027 | * If this slot is taken (e.g. by ide-pci.c) try the next one. | |
12028 | */ | |
12029 | @@ -860,8 +844,7 @@ | |
12030 | if (np->n_addrs > 1 && np->addrs[1].size > 0x100) | |
12031 | np->addrs[1].size = 0x100; | |
12032 | ||
12033 | - pmhw->reg_resource = request_OF_resource(np, 0, " (mac-io IDE IO)"); | |
12034 | - if (!pmhw->reg_resource) { | |
12035 | + if (request_OF_resource(np, 0, " (mac-io IDE IO)") == NULL) { | |
12036 | printk(KERN_ERR "ide-pmac(%s): can't request IO resource !\n", np->name); | |
12037 | continue; | |
12038 | } | |
12039 | @@ -935,6 +918,7 @@ | |
12040 | hwif->chipset = ide_pmac; | |
12041 | hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET] || in_bay; | |
12042 | hwif->udma_four = (pmhw->kind == controller_kl_ata4_80); | |
12043 | + hwif->pci_dev = pdev; | |
12044 | #ifdef CONFIG_PMAC_PBOOK | |
12045 | if (in_bay && check_media_bay_by_base(base, MB_CD) == 0) | |
12046 | hwif->noprobe = 0; | |
12047 | @@ -964,13 +948,14 @@ | |
12048 | static void __init | |
12049 | pmac_ide_setup_dma(struct device_node *np, int ix) | |
12050 | { | |
12051 | - pmac_ide[ix].dma_resource = request_OF_resource(np, 1, " (mac-io IDE DMA)"); | |
12052 | - if (!pmac_ide[ix].dma_resource) { | |
12053 | + struct pmac_ide_hwif *pmif = &pmac_ide[ix]; | |
12054 | + | |
12055 | + if (request_OF_resource(np, 1, " (mac-io IDE DMA)") == NULL) { | |
12056 | printk(KERN_ERR "ide-pmac(%s): can't request DMA resource !\n", np->name); | |
12057 | return; | |
12058 | } | |
12059 | ||
12060 | - pmac_ide[ix].dma_regs = | |
12061 | + pmif->dma_regs = | |
12062 | (volatile struct dbdma_regs*)ioremap(np->addrs[1].address, 0x200); | |
12063 | ||
12064 | /* | |
12065 | @@ -978,14 +963,24 @@ | |
12066 | * The +2 is +1 for the stop command and +1 to allow for | |
12067 | * aligning the start address to a multiple of 16 bytes. | |
12068 | */ | |
12069 | - pmac_ide[ix].dma_table = (struct dbdma_cmd*) | |
12070 | - kmalloc((MAX_DCMDS + 2) * sizeof(struct dbdma_cmd), GFP_KERNEL); | |
12071 | - if (pmac_ide[ix].dma_table == 0) { | |
12072 | + pmif->dma_table_cpu = (struct dbdma_cmd*)pci_alloc_consistent( | |
12073 | + ide_hwifs[ix].pci_dev, | |
12074 | + (MAX_DCMDS + 2) * sizeof(struct dbdma_cmd), | |
12075 | + &pmif->dma_table_dma); | |
12076 | + if (pmif->dma_table_cpu == NULL) { | |
12077 | printk(KERN_ERR "%s: unable to allocate DMA command list\n", | |
12078 | ide_hwifs[ix].name); | |
12079 | return; | |
12080 | } | |
12081 | ||
12082 | + pmif->sg_table = kmalloc(sizeof(struct scatterlist) * MAX_DCMDS, | |
12083 | + GFP_KERNEL); | |
12084 | + if (pmif->sg_table == NULL) { | |
12085 | + pci_free_consistent( ide_hwifs[ix].pci_dev, | |
12086 | + (MAX_DCMDS + 2) * sizeof(struct dbdma_cmd), | |
12087 | + pmif->dma_table_cpu, pmif->dma_table_dma); | |
12088 | + return; | |
12089 | + } | |
12090 | ide_hwifs[ix].dmaproc = &pmac_ide_dmaproc; | |
12091 | #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC_AUTO | |
12092 | if (!noautodma) | |
12093 | @@ -993,65 +988,116 @@ | |
12094 | #endif | |
12095 | } | |
12096 | ||
12097 | +static int | |
12098 | +pmac_ide_build_sglist (int ix, struct request *rq) | |
12099 | +{ | |
12100 | + ide_hwif_t *hwif = &ide_hwifs[ix]; | |
12101 | + struct pmac_ide_hwif *pmif = &pmac_ide[ix]; | |
12102 | + struct buffer_head *bh; | |
12103 | + struct scatterlist *sg = pmif->sg_table; | |
12104 | + int nents = 0; | |
12105 | + | |
12106 | + if (hwif->sg_dma_active) | |
12107 | + BUG(); | |
12108 | + | |
12109 | + if (rq->cmd == READ) | |
12110 | + pmif->sg_dma_direction = PCI_DMA_FROMDEVICE; | |
12111 | + else | |
12112 | + pmif->sg_dma_direction = PCI_DMA_TODEVICE; | |
12113 | + bh = rq->bh; | |
12114 | + do { | |
12115 | + unsigned char *virt_addr = bh->b_data; | |
12116 | + unsigned int size = bh->b_size; | |
12117 | + | |
12118 | + if (nents >= MAX_DCMDS) | |
12119 | + return 0; | |
12120 | + | |
12121 | + while ((bh = bh->b_reqnext) != NULL) { | |
12122 | + if ((virt_addr + size) != (unsigned char *) bh->b_data) | |
12123 | + break; | |
12124 | + size += bh->b_size; | |
12125 | + } | |
12126 | + memset(&sg[nents], 0, sizeof(*sg)); | |
12127 | + sg[nents].address = virt_addr; | |
12128 | + sg[nents].length = size; | |
12129 | + nents++; | |
12130 | + } while (bh != NULL); | |
12131 | + | |
12132 | + return pci_map_sg(hwif->pci_dev, sg, nents, pmif->sg_dma_direction); | |
12133 | +} | |
12134 | + | |
12135 | +static int | |
12136 | +pmac_ide_raw_build_sglist (int ix, struct request *rq) | |
12137 | +{ | |
12138 | + ide_hwif_t *hwif = &ide_hwifs[ix]; | |
12139 | + struct pmac_ide_hwif *pmif = &pmac_ide[ix]; | |
12140 | + struct scatterlist *sg = hwif->sg_table; | |
12141 | + int nents = 0; | |
12142 | + ide_task_t *args = rq->special; | |
12143 | + unsigned char *virt_addr = rq->buffer; | |
12144 | + int sector_count = rq->nr_sectors; | |
12145 | + | |
12146 | + if (args->command_type == IDE_DRIVE_TASK_RAW_WRITE) | |
12147 | + pmif->sg_dma_direction = PCI_DMA_TODEVICE; | |
12148 | + else | |
12149 | + pmif->sg_dma_direction = PCI_DMA_FROMDEVICE; | |
12150 | + | |
12151 | + if (sector_count > 128) { | |
12152 | + memset(&sg[nents], 0, sizeof(*sg)); | |
12153 | + sg[nents].address = virt_addr; | |
12154 | + sg[nents].length = 128 * SECTOR_SIZE; | |
12155 | + nents++; | |
12156 | + virt_addr = virt_addr + (128 * SECTOR_SIZE); | |
12157 | + sector_count -= 128; | |
12158 | + } | |
12159 | + memset(&sg[nents], 0, sizeof(*sg)); | |
12160 | + sg[nents].address = virt_addr; | |
12161 | + sg[nents].length = sector_count * SECTOR_SIZE; | |
12162 | + nents++; | |
12163 | + | |
12164 | + return pci_map_sg(hwif->pci_dev, sg, nents, pmif->sg_dma_direction); | |
12165 | +} | |
12166 | + | |
12167 | /* | |
12168 | * pmac_ide_build_dmatable builds the DBDMA command list | |
12169 | * for a transfer and sets the DBDMA channel to point to it. | |
12170 | */ | |
12171 | -static int __pmac | |
12172 | +static int | |
12173 | pmac_ide_build_dmatable(ide_drive_t *drive, int ix, int wr) | |
12174 | { | |
12175 | - struct dbdma_cmd *table, *tstart; | |
12176 | - int count = 0; | |
12177 | + struct dbdma_cmd *table; | |
12178 | + int i, count = 0; | |
12179 | struct request *rq = HWGROUP(drive)->rq; | |
12180 | - struct buffer_head *bh = rq->bh; | |
12181 | - unsigned int size, addr; | |
12182 | volatile struct dbdma_regs *dma = pmac_ide[ix].dma_regs; | |
12183 | + struct scatterlist *sg; | |
12184 | ||
12185 | - table = tstart = (struct dbdma_cmd *) DBDMA_ALIGN(pmac_ide[ix].dma_table); | |
12186 | + /* DMA table is already aligned */ | |
12187 | + table = (struct dbdma_cmd *) pmac_ide[ix].dma_table_cpu; | |
12188 | ||
12189 | -#ifdef IDE_PMAC_DEBUG | |
12190 | - if (in_le32(&dma->status) & (RUN|ACTIVE)) | |
12191 | - printk("ide-pmac: channel status not stopped ! (%x)\n", | |
12192 | - in_le32(&dma->status)); | |
12193 | -#endif | |
12194 | - /* Make sure channel is stopped and all error conditions are clear */ | |
12195 | + /* Make sure DMA controller is stopped (necessary ?) */ | |
12196 | out_le32(&dma->control, (RUN|PAUSE|FLUSH|WAKE|DEAD) << 16); | |
12197 | while (in_le32(&dma->status) & RUN) | |
12198 | udelay(1); | |
12199 | ||
12200 | - do { | |
12201 | - /* | |
12202 | - * Determine addr and size of next buffer area. We assume that | |
12203 | - * individual virtual buffers are always composed linearly in | |
12204 | - * physical memory. For example, we assume that any 8kB buffer | |
12205 | - * is always composed of two adjacent physical 4kB pages rather | |
12206 | - * than two possibly non-adjacent physical 4kB pages. | |
12207 | - */ | |
12208 | - if (bh == NULL) { /* paging requests have (rq->bh == NULL) */ | |
12209 | - addr = virt_to_bus(rq->buffer); | |
12210 | - size = rq->nr_sectors << 9; | |
12211 | - } else { | |
12212 | - /* group sequential buffers into one large buffer */ | |
12213 | - addr = virt_to_bus(bh->b_data); | |
12214 | - size = bh->b_size; | |
12215 | - while ((bh = bh->b_reqnext) != NULL) { | |
12216 | - if ((addr + size) != virt_to_bus(bh->b_data)) | |
12217 | - break; | |
12218 | - size += bh->b_size; | |
12219 | - } | |
12220 | - } | |
12221 | + /* Build sglist */ | |
12222 | + if (HWGROUP(drive)->rq->cmd == IDE_DRIVE_TASKFILE) | |
12223 | + pmac_ide[ix].sg_nents = i = pmac_ide_raw_build_sglist(ix, rq); | |
12224 | + else | |
12225 | + pmac_ide[ix].sg_nents = i = pmac_ide_build_sglist(ix, rq); | |
12226 | + if (!i) | |
12227 | + return 0; | |
12228 | ||
12229 | - /* | |
12230 | - * Fill in the next DBDMA command block. | |
12231 | - * Note that one DBDMA command can transfer | |
12232 | - * at most 65535 bytes. | |
12233 | - */ | |
12234 | -#ifdef IDE_PMAC_DEBUG | |
12235 | - if (size & 0x01) | |
12236 | - printk("ide-pmac: odd size transfer ! (%d)\n", size); | |
12237 | -#endif | |
12238 | - while (size) { | |
12239 | - unsigned int tc = (size < 0xfe00)? size: 0xfe00; | |
12240 | + /* Build DBDMA commands list */ | |
12241 | + sg = pmac_ide[ix].sg_table; | |
12242 | + while (i) { | |
12243 | + u32 cur_addr; | |
12244 | + u32 cur_len; | |
12245 | + | |
12246 | + cur_addr = sg_dma_address(sg); | |
12247 | + cur_len = sg_dma_len(sg); | |
12248 | + | |
12249 | + while (cur_len) { | |
12250 | + unsigned int tc = (cur_len < 0xfe00)? cur_len: 0xfe00; | |
12251 | ||
12252 | if (++count >= MAX_DCMDS) { | |
12253 | printk(KERN_WARNING "%s: DMA table too small\n", | |
12254 | @@ -1060,15 +1106,17 @@ | |
12255 | } | |
12256 | st_le16(&table->command, wr? OUTPUT_MORE: INPUT_MORE); | |
12257 | st_le16(&table->req_count, tc); | |
12258 | - st_le32(&table->phy_addr, addr); | |
12259 | + st_le32(&table->phy_addr, cur_addr); | |
12260 | table->cmd_dep = 0; | |
12261 | table->xfer_status = 0; | |
12262 | table->res_count = 0; | |
12263 | - addr += tc; | |
12264 | - size -= tc; | |
12265 | + cur_addr += tc; | |
12266 | + cur_len -= tc; | |
12267 | ++table; | |
12268 | } | |
12269 | - } while (bh != NULL); | |
12270 | + sg++; | |
12271 | + i--; | |
12272 | + } | |
12273 | ||
12274 | /* convert the last command to an input/output last command */ | |
12275 | if (count) | |
12276 | @@ -1080,10 +1128,23 @@ | |
12277 | memset(table, 0, sizeof(struct dbdma_cmd)); | |
12278 | out_le16(&table->command, DBDMA_STOP); | |
12279 | ||
12280 | - out_le32(&dma->cmdptr, virt_to_bus(tstart)); | |
12281 | + out_le32(&dma->cmdptr, pmac_ide[ix].dma_table_dma); | |
12282 | return 1; | |
12283 | } | |
12284 | ||
12285 | +/* Teardown mappings after DMA has completed. */ | |
12286 | +static void | |
12287 | +pmac_ide_destroy_dmatable (ide_drive_t *drive, int ix) | |
12288 | +{ | |
12289 | + struct pci_dev *dev = HWIF(drive)->pci_dev; | |
12290 | + struct scatterlist *sg = pmac_ide[ix].sg_table; | |
12291 | + int nents = pmac_ide[ix].sg_nents; | |
12292 | + | |
12293 | + if (nents) { | |
12294 | + pci_unmap_sg(dev, sg, nents, pmac_ide[ix].sg_dma_direction); | |
12295 | + pmac_ide[ix].sg_nents = 0; | |
12296 | + } | |
12297 | +} | |
12298 | ||
12299 | static __inline__ unsigned char | |
12300 | dma_bits_to_command(unsigned char bits) | |
12301 | @@ -1233,10 +1294,12 @@ | |
12302 | static int __pmac | |
12303 | pmac_ide_dmaproc(ide_dma_action_t func, ide_drive_t *drive) | |
12304 | { | |
12305 | +// ide_task_t *args = HWGROUP(drive)->rq->special; | |
12306 | int ix, dstat; | |
12307 | volatile struct dbdma_regs *dma; | |
12308 | byte unit = (drive->select.b.unit & 0x01); | |
12309 | byte ata4; | |
12310 | + int reading = 0; | |
12311 | ||
12312 | /* Can we stuff a pointer to our intf structure in config_data | |
12313 | * or select_data in hwif ? | |
12314 | @@ -1259,22 +1322,38 @@ | |
12315 | pmac_ide_check_dma(drive); | |
12316 | break; | |
12317 | case ide_dma_read: | |
12318 | + reading = 1; | |
12319 | case ide_dma_write: | |
12320 | - if (!pmac_ide_build_dmatable(drive, ix, func==ide_dma_write)) | |
12321 | + SELECT_READ_WRITE(HWIF(drive),drive,func); | |
12322 | + if (!pmac_ide_build_dmatable(drive, ix, !reading)) | |
12323 | return 1; | |
12324 | /* Apple adds 60ns to wrDataSetup on reads */ | |
12325 | if (ata4 && (pmac_ide[ix].timings[unit] & TR_66_UDMA_EN)) { | |
12326 | out_le32((unsigned *)(IDE_DATA_REG + IDE_TIMING_CONFIG + _IO_BASE), | |
12327 | pmac_ide[ix].timings[unit] + | |
12328 | - ((func == ide_dma_read) ? 0x00800000UL : 0)); | |
12329 | + (reading ? 0x00800000UL : 0)); | |
12330 | (void)in_le32((unsigned *)(IDE_DATA_REG + IDE_TIMING_CONFIG + _IO_BASE)); | |
12331 | } | |
12332 | drive->waiting_for_dma = 1; | |
12333 | if (drive->media != ide_disk) | |
12334 | return 0; | |
12335 | + if (HWGROUP(drive)->handler != NULL) /* paranoia check */ | |
12336 | + BUG(); | |
12337 | ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL); | |
12338 | - OUT_BYTE(func==ide_dma_write? WIN_WRITEDMA: WIN_READDMA, | |
12339 | - IDE_COMMAND_REG); | |
12340 | +#if 0 | |
12341 | + { | |
12342 | + ide_task_t *args = HWGROUP(drive)->rq->special; | |
12343 | + OUT_BYTE(args->tfRegister[IDE_COMMAND_OFFSET], IDE_COMMAND_REG); | |
12344 | + } | |
12345 | +#else | |
12346 | + if (HWGROUP(drive)->rq->cmd == IDE_DRIVE_TASKFILE) { | |
12347 | + ide_task_t *args = HWGROUP(drive)->rq->special; | |
12348 | + OUT_BYTE(args->tfRegister[IDE_COMMAND_OFFSET], IDE_COMMAND_REG); | |
12349 | + } else if (drive->addressing == 1) | |
12350 | + OUT_BYTE(reading ? WIN_READDMA_EXT : WIN_WRITEDMA_EXT, IDE_COMMAND_REG); | |
12351 | + else | |
12352 | + OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG); | |
12353 | +#endif | |
12354 | case ide_dma_begin: | |
12355 | out_le32(&dma->control, (RUN << 16) | RUN); | |
12356 | /* Make sure it gets to the controller right now */ | |
12357 | @@ -1284,6 +1363,7 @@ | |
12358 | drive->waiting_for_dma = 0; | |
12359 | dstat = in_le32(&dma->status); | |
12360 | out_le32(&dma->control, ((RUN|WAKE|DEAD) << 16)); | |
12361 | + pmac_ide_destroy_dmatable(drive, ix); | |
12362 | /* verify good dma status */ | |
12363 | return (dstat & (RUN|DEAD|ACTIVE)) != RUN; | |
12364 | case ide_dma_test_irq: /* returns 1 if dma irq issued, 0 otherwise */ | |
12365 | @@ -1358,19 +1438,19 @@ | |
12366 | switch (drive->media) { | |
12367 | case ide_disk: | |
12368 | /* Spin down the drive */ | |
12369 | - outb(drive->select.all, base+0x60); | |
12370 | - (void)inb(base+0x60); | |
12371 | + OUT_BYTE(drive->select.all, base+0x60); | |
12372 | + (void) IN_BYTE(base+0x60); | |
12373 | udelay(100); | |
12374 | - outb(0x0, base+0x30); | |
12375 | - outb(0x0, base+0x20); | |
12376 | - outb(0x0, base+0x40); | |
12377 | - outb(0x0, base+0x50); | |
12378 | - outb(0xe0, base+0x70); | |
12379 | - outb(0x2, base+0x160); | |
12380 | + OUT_BYTE(0x0, base+0x30); | |
12381 | + OUT_BYTE(0x0, base+0x20); | |
12382 | + OUT_BYTE(0x0, base+0x40); | |
12383 | + OUT_BYTE(0x0, base+0x50); | |
12384 | + OUT_BYTE(0xe0, base+0x70); | |
12385 | + OUT_BYTE(0x2, base+0x160); | |
12386 | for (j = 0; j < 10; j++) { | |
12387 | int status; | |
12388 | mdelay(100); | |
12389 | - status = inb(base+0x70); | |
12390 | + status = IN_BYTE(base+0x70); | |
12391 | if (!(status & BUSY_STAT) && (status & DRQ_STAT)) | |
12392 | break; | |
12393 | } | |
12394 | @@ -1483,10 +1563,10 @@ | |
12395 | for (j = 0; j < 200; j++) { | |
12396 | int status; | |
12397 | mdelay(100); | |
12398 | - outb(drive->select.all, base + 0x60); | |
12399 | - if (inb(base + 0x60) != drive->select.all) | |
12400 | + OUT_BYTE(drive->select.all, base + 0x60); | |
12401 | + if (IN_BYTE(base + 0x60) != drive->select.all) | |
12402 | continue; | |
12403 | - status = inb(base + 0x70); | |
12404 | + status = IN_BYTE(base + 0x70); | |
12405 | if (!(status & BUSY_STAT)) | |
12406 | break; | |
12407 | } | |
12408 | diff -Nur linux.org/drivers/ide/ide-probe.c linux/drivers/ide/ide-probe.c | |
12409 | --- linux.org/drivers/ide/ide-probe.c Mon Nov 26 14:29:17 2001 | |
12410 | +++ linux/drivers/ide/ide-probe.c Thu Jul 18 14:24:33 2002 | |
12411 | @@ -54,16 +54,33 @@ | |
12412 | ||
12413 | static inline void do_identify (ide_drive_t *drive, byte cmd) | |
12414 | { | |
12415 | + ide_hwif_t *hwif = HWIF(drive); | |
12416 | int bswap = 1; | |
12417 | struct hd_driveid *id; | |
12418 | ||
12419 | id = drive->id = kmalloc (SECTOR_WORDS*4, GFP_ATOMIC); /* called with interrupts disabled! */ | |
12420 | - ide_input_data(drive, id, SECTOR_WORDS); /* read 512 bytes of id info */ | |
12421 | - ide__sti(); /* local CPU only */ | |
12422 | + if (!id) { | |
12423 | + printk(KERN_WARNING "(ide-probe::do_identify) Out of memory.\n"); | |
12424 | + goto err_kmalloc; | |
12425 | + } | |
12426 | + /* read 512 bytes of id info */ | |
12427 | +#if 1 | |
12428 | + ata_input_data(drive, id, SECTOR_WORDS); | |
12429 | +#else | |
12430 | + { | |
12431 | + unsigned long *ptr = (unsigned long *)id ; | |
12432 | + unsigned long lcount = 256/2 ; | |
12433 | + // printk("IDE_DATA_REG = %#lx",IDE_DATA_REG); | |
12434 | + while( lcount-- ) | |
12435 | + *ptr++ = inl(IDE_DATA_REG); | |
12436 | + } | |
12437 | +#endif | |
12438 | + local_irq_enable(); | |
12439 | ide_fix_driveid(id); | |
12440 | ||
12441 | if (id->word156 == 0x4d42) { | |
12442 | - printk("%s: drive->id->word156 == 0x%04x \n", drive->name, drive->id->word156); | |
12443 | + printk("%s: drive->id->word156 == 0x%04x \n", | |
12444 | + drive->name, drive->id->word156); | |
12445 | } | |
12446 | ||
12447 | if (!drive->forced_lun) | |
12448 | @@ -76,8 +93,7 @@ | |
12449 | if ((id->model[0] == 'P' && id->model[1] == 'M') | |
12450 | || (id->model[0] == 'S' && id->model[1] == 'K')) { | |
12451 | printk("%s: EATA SCSI HBA %.10s\n", drive->name, id->model); | |
12452 | - drive->present = 0; | |
12453 | - return; | |
12454 | + goto err_misc; | |
12455 | } | |
12456 | #endif /* CONFIG_SCSI_EATA_DMA || CONFIG_SCSI_EATA_PIO */ | |
12457 | ||
12458 | @@ -96,7 +112,7 @@ | |
12459 | ide_fixstring (id->serial_no, sizeof(id->serial_no), bswap); | |
12460 | ||
12461 | if (strstr(id->model, "E X A B Y T E N E S T")) | |
12462 | - return; | |
12463 | + goto err_misc; | |
12464 | ||
12465 | id->model[sizeof(id->model)-1] = '\0'; /* we depend on this a lot! */ | |
12466 | printk("%s: %s, ", drive->name, id->model); | |
12467 | @@ -109,16 +125,17 @@ | |
12468 | byte type = (id->config >> 8) & 0x1f; | |
12469 | printk("ATAPI "); | |
12470 | #ifdef CONFIG_BLK_DEV_PDC4030 | |
12471 | - if (HWIF(drive)->channel == 1 && HWIF(drive)->chipset == ide_pdc4030) { | |
12472 | + if (hwif->channel == 1 && hwif->chipset == ide_pdc4030) { | |
12473 | printk(" -- not supported on 2nd Promise port\n"); | |
12474 | - drive->present = 0; | |
12475 | - return; | |
12476 | + goto err_misc; | |
12477 | } | |
12478 | #endif /* CONFIG_BLK_DEV_PDC4030 */ | |
12479 | switch (type) { | |
12480 | case ide_floppy: | |
12481 | if (!strstr(id->model, "CD-ROM")) { | |
12482 | - if (!strstr(id->model, "oppy") && !strstr(id->model, "poyp") && !strstr(id->model, "ZIP")) | |
12483 | + if (!strstr(id->model, "oppy") && | |
12484 | + !strstr(id->model, "poyp") && | |
12485 | + !strstr(id->model, "ZIP")) | |
12486 | printk("cdrom or floppy?, assuming "); | |
12487 | if (drive->media != ide_cdrom) { | |
12488 | printk ("FLOPPY"); | |
12489 | @@ -130,7 +147,8 @@ | |
12490 | drive->removable = 1; | |
12491 | #ifdef CONFIG_PPC | |
12492 | /* kludge for Apple PowerBook internal zip */ | |
12493 | - if (!strstr(id->model, "CD-ROM") && strstr(id->model, "ZIP")) { | |
12494 | + if (!strstr(id->model, "CD-ROM") && | |
12495 | + strstr(id->model, "ZIP")) { | |
12496 | printk ("FLOPPY"); | |
12497 | type = ide_floppy; | |
12498 | break; | |
12499 | @@ -161,10 +179,11 @@ | |
12500 | drive->removable = 1; | |
12501 | /* | |
12502 | * Prevent long system lockup probing later for non-existant | |
12503 | - * slave drive if the hwif is actually a flash memory card of some variety: | |
12504 | + * slave drive if the hwif is actually a flash memory card of | |
12505 | + * some variety: | |
12506 | */ | |
12507 | if (drive_is_flashcard(drive)) { | |
12508 | - ide_drive_t *mate = &HWIF(drive)->drives[1^drive->select.b.unit]; | |
12509 | + ide_drive_t *mate = &hwif->drives[1^drive->select.b.unit]; | |
12510 | if (!mate->ata_flash) { | |
12511 | mate->present = 0; | |
12512 | mate->noprobe = 1; | |
12513 | @@ -172,7 +191,13 @@ | |
12514 | } | |
12515 | drive->media = ide_disk; | |
12516 | printk("ATA DISK drive\n"); | |
12517 | - QUIRK_LIST(HWIF(drive),drive); | |
12518 | + QUIRK_LIST(hwif, drive); | |
12519 | + return; | |
12520 | + | |
12521 | +err_misc: | |
12522 | + kfree(id); | |
12523 | +err_kmalloc: | |
12524 | + drive->present = 0; | |
12525 | return; | |
12526 | } | |
12527 | ||
12528 | @@ -188,6 +213,7 @@ | |
12529 | */ | |
12530 | static int actual_try_to_identify (ide_drive_t *drive, byte cmd) | |
12531 | { | |
12532 | +// ide_hwif_t *hwif = HWIF(drive); | |
12533 | int rc; | |
12534 | ide_ioreg_t hd_status; | |
12535 | unsigned long timeout; | |
12536 | @@ -226,7 +252,7 @@ | |
12537 | timeout = ((cmd == WIN_IDENTIFY) ? WAIT_WORSTCASE : WAIT_PIDENTIFY) / 2; | |
12538 | timeout += jiffies; | |
12539 | do { | |
12540 | - if (0 < (signed long)(jiffies - timeout)) { | |
12541 | + if (time_after(jiffies, timeout)) { | |
12542 | return 1; /* drive timed-out */ | |
12543 | } | |
12544 | ide_delay_50ms(); /* give drive a breather */ | |
12545 | @@ -235,12 +261,12 @@ | |
12546 | ide_delay_50ms(); /* wait for IRQ and DRQ_STAT */ | |
12547 | if (OK_STAT(GET_STAT(),DRQ_STAT,BAD_R_STAT)) { | |
12548 | unsigned long flags; | |
12549 | - __save_flags(flags); /* local CPU only */ | |
12550 | - __cli(); /* local CPU only; some systems need this */ | |
12551 | + local_irq_save(flags); | |
12552 | + /* local CPU only; some systems need this */ | |
12553 | do_identify(drive, cmd); /* drive returned ID */ | |
12554 | rc = 0; /* drive responded with ID */ | |
12555 | (void) GET_STAT(); /* clear drive IRQ */ | |
12556 | - __restore_flags(flags); /* local CPU only */ | |
12557 | + local_irq_restore(flags); | |
12558 | } else | |
12559 | rc = 2; /* drive refused ID */ | |
12560 | return rc; | |
12561 | @@ -248,11 +274,12 @@ | |
12562 | ||
12563 | static int try_to_identify (ide_drive_t *drive, byte cmd) | |
12564 | { | |
12565 | + ide_hwif_t *hwif = HWIF(drive); | |
12566 | int retval; | |
12567 | int autoprobe = 0; | |
12568 | unsigned long cookie = 0; | |
12569 | ||
12570 | - if (IDE_CONTROL_REG && !HWIF(drive)->irq) { | |
12571 | + if (IDE_CONTROL_REG && !hwif->irq) { | |
12572 | autoprobe = 1; | |
12573 | cookie = probe_irq_on(); | |
12574 | OUT_BYTE(drive->ctl,IDE_CONTROL_REG); /* enable device irq */ | |
12575 | @@ -266,14 +293,14 @@ | |
12576 | (void) GET_STAT(); /* clear drive IRQ */ | |
12577 | udelay(5); | |
12578 | irq = probe_irq_off(cookie); | |
12579 | - if (!HWIF(drive)->irq) { | |
12580 | + if (!hwif->irq) { | |
12581 | if (irq > 0) { | |
12582 | - HWIF(drive)->irq = irq; | |
12583 | + hwif->irq = irq; | |
12584 | } else { /* Mmmm.. multiple IRQs.. don't know which was ours */ | |
12585 | printk("%s: IRQ probe failed (0x%lx)\n", drive->name, cookie); | |
12586 | #ifdef CONFIG_BLK_DEV_CMD640 | |
12587 | #ifdef CMD640_DUMP_REGS | |
12588 | - if (HWIF(drive)->chipset == ide_cmd640) { | |
12589 | + if (hwif->chipset == ide_cmd640) { | |
12590 | printk("%s: Hmmm.. probably a driver problem.\n", drive->name); | |
12591 | CMD640_DUMP_REGS; | |
12592 | } | |
12593 | @@ -326,9 +353,8 @@ | |
12594 | return 3; /* no i/f present: mmm.. this should be a 4 -ml */ | |
12595 | } | |
12596 | ||
12597 | - if (OK_STAT(GET_STAT(),READY_STAT,BUSY_STAT) | |
12598 | - || drive->present || cmd == WIN_PIDENTIFY) | |
12599 | - { | |
12600 | + if (OK_STAT(GET_STAT(),READY_STAT,BUSY_STAT) || | |
12601 | + drive->present || cmd == WIN_PIDENTIFY) { | |
12602 | if ((rc = try_to_identify(drive,cmd))) /* send cmd and wait */ | |
12603 | rc = try_to_identify(drive,cmd); /* failed: try again */ | |
12604 | if (rc == 1 && cmd == WIN_PIDENTIFY && drive->autotune != 2) { | |
12605 | @@ -362,15 +388,16 @@ | |
12606 | */ | |
12607 | static void enable_nest (ide_drive_t *drive) | |
12608 | { | |
12609 | + ide_hwif_t *hwif = HWIF(drive); | |
12610 | unsigned long timeout; | |
12611 | ||
12612 | - printk("%s: enabling %s -- ", HWIF(drive)->name, drive->id->model); | |
12613 | - SELECT_DRIVE(HWIF(drive), drive); | |
12614 | + printk("%s: enabling %s -- ", hwif->name, drive->id->model); | |
12615 | + SELECT_DRIVE(hwif, drive); | |
12616 | ide_delay_50ms(); | |
12617 | OUT_BYTE(EXABYTE_ENABLE_NEST, IDE_COMMAND_REG); | |
12618 | timeout = jiffies + WAIT_WORSTCASE; | |
12619 | do { | |
12620 | - if (jiffies > timeout) { | |
12621 | + if (time_after(jiffies, timeout)) { | |
12622 | printk("failed (timeout)\n"); | |
12623 | return; | |
12624 | } | |
12625 | @@ -381,9 +408,9 @@ | |
12626 | printk("failed (status = 0x%02x)\n", GET_STAT()); | |
12627 | else | |
12628 | printk("success\n"); | |
12629 | - if (do_probe(drive, WIN_IDENTIFY) >= 2) { /* if !(success||timed-out) */ | |
12630 | + | |
12631 | + if (do_probe(drive, WIN_IDENTIFY) >= 2) /* if !(success||timed-out) */ | |
12632 | (void) do_probe(drive, WIN_PIDENTIFY); /* look for ATAPI device */ | |
12633 | - } | |
12634 | } | |
12635 | ||
12636 | /* | |
12637 | @@ -521,8 +548,7 @@ | |
12638 | return; | |
12639 | } | |
12640 | ||
12641 | - __save_flags(flags); /* local CPU only */ | |
12642 | - __sti(); /* local CPU only; needed for jiffies and irq probing */ | |
12643 | + local_irq_set(flags); | |
12644 | /* | |
12645 | * Second drive should only exist if first drive was found, | |
12646 | * but a lot of cdrom drives are configured as single slaves. | |
12647 | @@ -532,7 +558,8 @@ | |
12648 | (void) probe_for_drive (drive); | |
12649 | if (drive->present && !hwif->present) { | |
12650 | hwif->present = 1; | |
12651 | - if (hwif->chipset != ide_4drives || !hwif->mate->present) { | |
12652 | + if (hwif->chipset != ide_4drives || | |
12653 | + !hwif->mate->present) { | |
12654 | hwif_register(hwif); | |
12655 | } | |
12656 | } | |
12657 | @@ -548,16 +575,16 @@ | |
12658 | do { | |
12659 | ide_delay_50ms(); | |
12660 | stat = IN_BYTE(hwif->io_ports[IDE_STATUS_OFFSET]); | |
12661 | - } while ((stat & BUSY_STAT) && 0 < (signed long)(timeout - jiffies)); | |
12662 | + } while ((stat & BUSY_STAT) && time_after(timeout, jiffies)); | |
12663 | ||
12664 | } | |
12665 | - __restore_flags(flags); /* local CPU only */ | |
12666 | + local_irq_restore(flags); | |
12667 | for (unit = 0; unit < MAX_DRIVES; ++unit) { | |
12668 | ide_drive_t *drive = &hwif->drives[unit]; | |
12669 | if (drive->present) { | |
12670 | - ide_tuneproc_t *tuneproc = HWIF(drive)->tuneproc; | |
12671 | - if (tuneproc != NULL && drive->autotune == 1) | |
12672 | - tuneproc(drive, 255); /* auto-tune PIO mode */ | |
12673 | + if (hwif->tuneproc != NULL && drive->autotune == 1) | |
12674 | + /* auto-tune PIO mode */ | |
12675 | + hwif->tuneproc(drive, 255); | |
12676 | } | |
12677 | } | |
12678 | } | |
12679 | @@ -581,7 +608,8 @@ | |
12680 | if (m && m->hwgroup && m->hwgroup != new->hwgroup) { | |
12681 | if (!new->hwgroup) | |
12682 | return; | |
12683 | - printk("%s: potential irq problem with %s and %s\n", hwif->name, new->name, m->name); | |
12684 | + printk("%s: potential irq problem with %s and %s\n", | |
12685 | + hwif->name, new->name, m->name); | |
12686 | } | |
12687 | if (!m || m->irq != hwif->irq) /* don't undo a prior perfect match */ | |
12688 | *match = new; | |
12689 | @@ -597,8 +625,15 @@ | |
12690 | ||
12691 | q->queuedata = HWGROUP(drive); | |
12692 | blk_init_queue(q, do_ide_request); | |
12693 | + | |
12694 | + if (drive->media == ide_disk) { | |
12695 | +#ifdef CONFIG_BLK_DEV_ELEVATOR_NOOP | |
12696 | + elevator_init(&q->elevator, ELEVATOR_NOOP); | |
12697 | +#endif | |
12698 | + } | |
12699 | } | |
12700 | ||
12701 | +#undef __IRQ_HELL_SPIN | |
12702 | /* | |
12703 | * This routine sets up the irq for an ide interface, and creates a new | |
12704 | * hwgroup for the irq/hwif if none was previously assigned. | |
12705 | @@ -624,8 +659,11 @@ | |
12706 | ||
12707 | new_hwgroup = kmalloc(sizeof(ide_hwgroup_t),GFP_KERNEL); | |
12708 | ||
12709 | - save_flags(flags); /* all CPUs */ | |
12710 | - cli(); /* all CPUs */ | |
12711 | +#ifndef __IRQ_HELL_SPIN | |
12712 | + save_and_cli(flags); | |
12713 | +#else | |
12714 | + spin_lock_irqsave(&io_request_lock, flags); | |
12715 | +#endif | |
12716 | ||
12717 | hwif->hwgroup = NULL; | |
12718 | #if MAX_HWIFS > 1 | |
12719 | @@ -662,7 +700,11 @@ | |
12720 | } else { | |
12721 | hwgroup = new_hwgroup; | |
12722 | if (!hwgroup) { | |
12723 | - restore_flags(flags); /* all CPUs */ | |
12724 | +#ifndef __IRQ_HELL_SPIN | |
12725 | + restore_flags(flags); | |
12726 | +#else | |
12727 | + spin_unlock_irqrestore(&io_request_lock, flags); | |
12728 | +#endif | |
12729 | return 1; | |
12730 | } | |
12731 | memset(hwgroup, 0, sizeof(ide_hwgroup_t)); | |
12732 | @@ -685,10 +727,18 @@ | |
12733 | #else /* !CONFIG_IDEPCI_SHARE_IRQ */ | |
12734 | int sa = IDE_CHIPSET_IS_PCI(hwif->chipset) ? SA_INTERRUPT|SA_SHIRQ : SA_INTERRUPT; | |
12735 | #endif /* CONFIG_IDEPCI_SHARE_IRQ */ | |
12736 | + | |
12737 | + if (hwif->io_ports[IDE_CONTROL_OFFSET]) | |
12738 | + OUT_BYTE(0x08, hwif->io_ports[IDE_CONTROL_OFFSET]); /* clear nIEN */ | |
12739 | + | |
12740 | if (ide_request_irq(hwif->irq, &ide_intr, sa, hwif->name, hwgroup)) { | |
12741 | if (!match) | |
12742 | kfree(hwgroup); | |
12743 | - restore_flags(flags); /* all CPUs */ | |
12744 | +#ifndef __IRQ_HELL_SPIN | |
12745 | + restore_flags(flags); | |
12746 | +#else | |
12747 | + spin_unlock_irqrestore(&io_request_lock, flags); | |
12748 | +#endif | |
12749 | return 1; | |
12750 | } | |
12751 | } | |
12752 | @@ -716,7 +766,12 @@ | |
12753 | printk("%s : Adding missed hwif to hwgroup!!\n", hwif->name); | |
12754 | #endif | |
12755 | } | |
12756 | - restore_flags(flags); /* all CPUs; safe now that hwif->hwgroup is set up */ | |
12757 | +#ifndef __IRQ_HELL_SPIN | |
12758 | + restore_flags(flags); | |
12759 | +#else | |
12760 | + spin_unlock_irqrestore(&io_request_lock, flags); | |
12761 | +#endif | |
12762 | + /* all CPUs; safe now that hwif->hwgroup is set up */ | |
12763 | ||
12764 | #if !defined(__mc68000__) && !defined(CONFIG_APUS) && !defined(__sparc__) | |
12765 | printk("%s at 0x%03x-0x%03x,0x%03x on irq %d", hwif->name, | |
12766 | @@ -752,18 +807,35 @@ | |
12767 | int *bs, *max_sect, *max_ra; | |
12768 | extern devfs_handle_t ide_devfs_handle; | |
12769 | ||
12770 | +#if 1 | |
12771 | + units = MAX_DRIVES; | |
12772 | +#else | |
12773 | /* figure out maximum drive number on the interface */ | |
12774 | for (units = MAX_DRIVES; units > 0; --units) { | |
12775 | if (hwif->drives[units-1].present) | |
12776 | break; | |
12777 | } | |
12778 | +#endif | |
12779 | + | |
12780 | minors = units * (1<<PARTN_BITS); | |
12781 | gd = kmalloc (sizeof(struct gendisk), GFP_KERNEL); | |
12782 | + if (!gd) | |
12783 | + goto err_kmalloc_gd; | |
12784 | gd->sizes = kmalloc (minors * sizeof(int), GFP_KERNEL); | |
12785 | + if (!gd->sizes) | |
12786 | + goto err_kmalloc_gd_sizes; | |
12787 | gd->part = kmalloc (minors * sizeof(struct hd_struct), GFP_KERNEL); | |
12788 | + if (!gd->part) | |
12789 | + goto err_kmalloc_gd_part; | |
12790 | bs = kmalloc (minors*sizeof(int), GFP_KERNEL); | |
12791 | + if (!bs) | |
12792 | + goto err_kmalloc_bs; | |
12793 | max_sect = kmalloc (minors*sizeof(int), GFP_KERNEL); | |
12794 | + if (!max_sect) | |
12795 | + goto err_kmalloc_max_sect; | |
12796 | max_ra = kmalloc (minors*sizeof(int), GFP_KERNEL); | |
12797 | + if (!max_ra) | |
12798 | + goto err_kmalloc_max_ra; | |
12799 | ||
12800 | memset(gd->part, 0, minors * sizeof(struct hd_struct)); | |
12801 | ||
12802 | @@ -773,12 +845,10 @@ | |
12803 | max_readahead[hwif->major] = max_ra; | |
12804 | for (unit = 0; unit < minors; ++unit) { | |
12805 | *bs++ = BLOCK_SIZE; | |
12806 | -#ifdef CONFIG_BLK_DEV_PDC4030 | |
12807 | - *max_sect++ = ((hwif->chipset == ide_pdc4030) ? 127 : 255); | |
12808 | -#else | |
12809 | - /* IDE can do up to 128K per request. */ | |
12810 | - *max_sect++ = 255; | |
12811 | -#endif | |
12812 | + /* | |
12813 | + * IDE can do up to 128K per request == 256 | |
12814 | + */ | |
12815 | + *max_sect++ = ((hwif->chipset == ide_pdc4030) ? 127 : 128); | |
12816 | *max_ra++ = vm_max_readahead; | |
12817 | } | |
12818 | ||
12819 | @@ -804,6 +874,17 @@ | |
12820 | add_gendisk(gd); | |
12821 | ||
12822 | for (unit = 0; unit < units; ++unit) { | |
12823 | +#if 1 | |
12824 | + char name[64]; | |
12825 | + ide_add_generic_settings(hwif->drives + unit); | |
12826 | + hwif->drives[unit].dn = ((hwif->channel ? 2 : 0) + unit); | |
12827 | + sprintf (name, "host%d/bus%d/target%d/lun%d", | |
12828 | + (hwif->channel && hwif->mate) ? | |
12829 | + hwif->mate->index : hwif->index, | |
12830 | + hwif->channel, unit, hwif->drives[unit].lun); | |
12831 | + if (hwif->drives[unit].present) | |
12832 | + hwif->drives[unit].de = devfs_mk_dir(ide_devfs_handle, name, NULL); | |
12833 | +#else | |
12834 | if (hwif->drives[unit].present) { | |
12835 | char name[64]; | |
12836 | ||
12837 | @@ -815,7 +896,23 @@ | |
12838 | hwif->drives[unit].de = | |
12839 | devfs_mk_dir (ide_devfs_handle, name, NULL); | |
12840 | } | |
12841 | +#endif | |
12842 | } | |
12843 | + return; | |
12844 | + | |
12845 | +err_kmalloc_max_ra: | |
12846 | + kfree(max_sect); | |
12847 | +err_kmalloc_max_sect: | |
12848 | + kfree(bs); | |
12849 | +err_kmalloc_bs: | |
12850 | + kfree(gd->part); | |
12851 | +err_kmalloc_gd_part: | |
12852 | + kfree(gd->sizes); | |
12853 | +err_kmalloc_gd_sizes: | |
12854 | + kfree(gd); | |
12855 | +err_kmalloc_gd: | |
12856 | + printk(KERN_WARNING "(ide::init_gendisk) Out of memory\n"); | |
12857 | + return; | |
12858 | } | |
12859 | ||
12860 | static int hwif_init (ide_hwif_t *hwif) | |
12861 | @@ -831,7 +928,8 @@ | |
12862 | } | |
12863 | #ifdef CONFIG_BLK_DEV_HD | |
12864 | if (hwif->irq == HD_IRQ && hwif->io_ports[IDE_DATA_OFFSET] != HD_DATA) { | |
12865 | - printk("%s: CANNOT SHARE IRQ WITH OLD HARDDISK DRIVER (hd.c)\n", hwif->name); | |
12866 | + printk("%s: CANNOT SHARE IRQ WITH OLD " | |
12867 | + "HARDDISK DRIVER (hd.c)\n", hwif->name); | |
12868 | return (hwif->present = 0); | |
12869 | } | |
12870 | #endif /* CONFIG_BLK_DEV_HD */ | |
12871 | @@ -839,7 +937,8 @@ | |
12872 | hwif->present = 0; /* we set it back to 1 if all is ok below */ | |
12873 | ||
12874 | if (devfs_register_blkdev (hwif->major, hwif->name, ide_fops)) { | |
12875 | - printk("%s: UNABLE TO GET MAJOR NUMBER %d\n", hwif->name, hwif->major); | |
12876 | + printk("%s: UNABLE TO GET MAJOR NUMBER %d\n", | |
12877 | + hwif->name, hwif->major); | |
12878 | return (hwif->present = 0); | |
12879 | } | |
12880 | ||
12881 | @@ -850,7 +949,8 @@ | |
12882 | * this port and try that. | |
12883 | */ | |
12884 | if (!(hwif->irq = ide_default_irq(hwif->io_ports[IDE_DATA_OFFSET]))) { | |
12885 | - printk("%s: Disabled unable to get IRQ %d.\n", hwif->name, i); | |
12886 | + printk("%s: Disabled unable to get IRQ %d.\n", | |
12887 | + hwif->name, i); | |
12888 | (void) unregister_blkdev (hwif->major, hwif->name); | |
12889 | return (hwif->present = 0); | |
12890 | } | |
12891 | @@ -880,6 +980,19 @@ | |
12892 | return hwif->present; | |
12893 | } | |
12894 | ||
12895 | +void export_ide_init_queue (ide_drive_t *drive) | |
12896 | +{ | |
12897 | + ide_init_queue(drive); | |
12898 | +} | |
12899 | + | |
12900 | +byte export_probe_for_drive (ide_drive_t *drive) | |
12901 | +{ | |
12902 | + return probe_for_drive(drive); | |
12903 | +} | |
12904 | + | |
12905 | +EXPORT_SYMBOL(export_ide_init_queue); | |
12906 | +EXPORT_SYMBOL(export_probe_for_drive); | |
12907 | + | |
12908 | int ideprobe_init (void); | |
12909 | static ide_module_t ideprobe_module = { | |
12910 | IDE_PROBE_MODULE, | |
12911 | @@ -913,6 +1026,8 @@ | |
12912 | } | |
12913 | ||
12914 | #ifdef MODULE | |
12915 | +extern int (*ide_xlate_1024_hook)(kdev_t, int, int, const char *); | |
12916 | + | |
12917 | int init_module (void) | |
12918 | { | |
12919 | unsigned int index; | |
12920 | @@ -921,12 +1036,14 @@ | |
12921 | ide_unregister(index); | |
12922 | ideprobe_init(); | |
12923 | create_proc_ide_interfaces(); | |
12924 | + ide_xlate_1024_hook = ide_xlate_1024; | |
12925 | return 0; | |
12926 | } | |
12927 | ||
12928 | void cleanup_module (void) | |
12929 | { | |
12930 | ide_probe = NULL; | |
12931 | + ide_xlate_1024_hook = 0; | |
12932 | } | |
12933 | MODULE_LICENSE("GPL"); | |
12934 | #endif /* MODULE */ | |
12935 | diff -Nur linux.org/drivers/ide/ide-proc.c linux/drivers/ide/ide-proc.c | |
12936 | --- linux.org/drivers/ide/ide-proc.c Fri Sep 7 18:28:38 2001 | |
12937 | +++ linux/drivers/ide/ide-proc.c Thu Jul 18 14:24:33 2002 | |
12938 | @@ -65,6 +65,7 @@ | |
12939 | #include <linux/mm.h> | |
12940 | #include <linux/pci.h> | |
12941 | #include <linux/ctype.h> | |
12942 | +#include <linux/hdreg.h> | |
12943 | #include <linux/ide.h> | |
12944 | ||
12945 | #include <asm/io.h> | |
12946 | @@ -159,6 +160,8 @@ | |
12947 | ||
12948 | static struct proc_dir_entry * proc_ide_root = NULL; | |
12949 | ||
12950 | +#undef __PROC_HELL | |
12951 | + | |
12952 | static int proc_ide_write_config | |
12953 | (struct file *file, const char *buffer, unsigned long count, void *data) | |
12954 | { | |
12955 | @@ -180,7 +183,11 @@ | |
12956 | * Do one full pass to verify all parameters, | |
12957 | * then do another to actually write the regs. | |
12958 | */ | |
12959 | +#ifndef __PROC_HELL | |
12960 | save_flags(flags); /* all CPUs */ | |
12961 | +#else | |
12962 | + spin_lock_irqsave(&io_request_lock, flags); | |
12963 | +#endif | |
12964 | do { | |
12965 | const char *p; | |
12966 | if (for_real) { | |
12967 | @@ -189,15 +196,32 @@ | |
12968 | ide_hwgroup_t *mategroup = NULL; | |
12969 | if (hwif->mate && hwif->mate->hwgroup) | |
12970 | mategroup = (ide_hwgroup_t *)(hwif->mate->hwgroup); | |
12971 | +#ifndef __PROC_HELL | |
12972 | cli(); /* all CPUs; ensure all writes are done together */ | |
12973 | - while (mygroup->busy || (mategroup && mategroup->busy)) { | |
12974 | +#else | |
12975 | + spin_lock_irqsave(&io_request_lock, flags); | |
12976 | +#endif | |
12977 | + while (mygroup->busy || | |
12978 | + (mategroup && mategroup->busy)) { | |
12979 | +#ifndef __PROC_HELL | |
12980 | sti(); /* all CPUs */ | |
12981 | - if (0 < (signed long)(jiffies - timeout)) { | |
12982 | +#else | |
12983 | + spin_unlock_irqrestore(&io_request_lock, flags); | |
12984 | +#endif | |
12985 | + if (time_after(jiffies, timeout)) { | |
12986 | printk("/proc/ide/%s/config: channel(s) busy, cannot write\n", hwif->name); | |
12987 | +#ifndef __PROC_HELL | |
12988 | restore_flags(flags); /* all CPUs */ | |
12989 | +#else | |
12990 | + spin_unlock_irqrestore(&io_request_lock, flags); | |
12991 | +#endif | |
12992 | return -EBUSY; | |
12993 | } | |
12994 | +#ifndef __PROC_HELL | |
12995 | cli(); /* all CPUs */ | |
12996 | +#else | |
12997 | + spin_lock_irqsave(&io_request_lock, flags); | |
12998 | +#endif | |
12999 | } | |
13000 | } | |
13001 | p = buffer; | |
13002 | @@ -280,7 +304,11 @@ | |
13003 | break; | |
13004 | } | |
13005 | if (rc) { | |
13006 | +#ifndef __PROC_HELL | |
13007 | restore_flags(flags); /* all CPUs */ | |
13008 | +#else | |
13009 | + spin_unlock_irqrestore(&io_request_lock, flags); | |
13010 | +#endif | |
13011 | printk("proc_ide_write_config: error writing %s at bus %02x dev %02x reg 0x%x value 0x%x\n", | |
13012 | msg, dev->bus->number, dev->devfn, reg, val); | |
13013 | printk("proc_ide_write_config: error %d\n", rc); | |
13014 | @@ -310,9 +338,9 @@ | |
13015 | * | |
13016 | */ | |
13017 | switch (digits) { | |
13018 | - case 2: outb(val, reg); | |
13019 | + case 2: OUT_BYTE(val, reg); | |
13020 | break; | |
13021 | - case 4: outw(val, reg); | |
13022 | + case 4: OUT_WORD(val, reg); | |
13023 | break; | |
13024 | case 8: outl(val, reg); | |
13025 | break; | |
13026 | @@ -322,10 +350,18 @@ | |
13027 | } | |
13028 | } | |
13029 | } while (!for_real++); | |
13030 | +#ifndef __PROC_HELL | |
13031 | restore_flags(flags); /* all CPUs */ | |
13032 | +#else | |
13033 | + spin_unlock_irqrestore(&io_request_lock, flags); | |
13034 | +#endif | |
13035 | return count; | |
13036 | parse_error: | |
13037 | +#ifndef __PROC_HELL | |
13038 | restore_flags(flags); /* all CPUs */ | |
13039 | +#else | |
13040 | + spin_unlock_irqrestore(&io_request_lock, flags); | |
13041 | +#endif | |
13042 | printk("parse error\n"); | |
13043 | return xx_xx_parse_error(start, startn, msg); | |
13044 | } | |
13045 | @@ -445,19 +481,14 @@ | |
13046 | PROC_IDE_READ_RETURN(page,start,off,count,eof,len); | |
13047 | } | |
13048 | ||
13049 | -static int proc_ide_get_identify(ide_drive_t *drive, byte *buf) | |
13050 | -{ | |
13051 | - return ide_wait_cmd(drive, (drive->media == ide_disk) ? WIN_IDENTIFY : WIN_PIDENTIFY, 0, 0, 1, buf); | |
13052 | -} | |
13053 | - | |
13054 | static int proc_ide_read_identify | |
13055 | (char *page, char **start, off_t off, int count, int *eof, void *data) | |
13056 | { | |
13057 | ide_drive_t *drive = (ide_drive_t *)data; | |
13058 | int len = 0, i = 0; | |
13059 | ||
13060 | - if (drive && !proc_ide_get_identify(drive, page)) { | |
13061 | - unsigned short *val = ((unsigned short *)page) + 2; | |
13062 | + if (drive && !taskfile_lib_get_identify(drive, page)) { | |
13063 | + unsigned short *val = (unsigned short *) page; | |
13064 | char *out = ((char *)val) + (SECTOR_WORDS * 4); | |
13065 | page = out; | |
13066 | do { | |
13067 | @@ -588,7 +619,8 @@ | |
13068 | if (!driver) | |
13069 | len = sprintf(page, "(none)\n"); | |
13070 | else | |
13071 | - len = sprintf(page,"%li\n", ((ide_driver_t *)drive->driver)->capacity(drive)); | |
13072 | + len = sprintf(page,"%llu\n", | |
13073 | + (unsigned long long) ((ide_driver_t *)drive->driver)->capacity(drive)); | |
13074 | PROC_IDE_READ_RETURN(page,start,off,count,eof,len); | |
13075 | } | |
13076 | ||
13077 | @@ -732,16 +764,38 @@ | |
13078 | } | |
13079 | } | |
13080 | ||
13081 | -void destroy_proc_ide_drives(ide_hwif_t *hwif) | |
13082 | +void recreate_proc_ide_device(ide_hwif_t *hwif, ide_drive_t *drive) | |
13083 | { | |
13084 | - int d; | |
13085 | + struct proc_dir_entry *ent; | |
13086 | + struct proc_dir_entry *parent = hwif->proc; | |
13087 | + char name[64]; | |
13088 | +// ide_driver_t *driver = drive->driver; | |
13089 | ||
13090 | - for (d = 0; d < MAX_DRIVES; d++) { | |
13091 | - ide_drive_t *drive = &hwif->drives[d]; | |
13092 | - ide_driver_t *driver = drive->driver; | |
13093 | + if (drive->present && !drive->proc) { | |
13094 | + drive->proc = proc_mkdir(drive->name, parent); | |
13095 | + if (drive->proc) | |
13096 | + ide_add_proc_entries(drive->proc, generic_drive_entries, drive); | |
13097 | ||
13098 | - if (!drive->proc) | |
13099 | - continue; | |
13100 | +/* | |
13101 | + * assume that we have these already, however, should test FIXME! | |
13102 | + * if (driver) { | |
13103 | + * ide_add_proc_entries(drive->proc, generic_subdriver_entries, drive); | |
13104 | + * ide_add_proc_entries(drive->proc, driver->proc, drive); | |
13105 | + * } | |
13106 | + * | |
13107 | + */ | |
13108 | + sprintf(name,"ide%d/%s", (drive->name[2]-'a')/2, drive->name); | |
13109 | + ent = proc_symlink(drive->name, proc_ide_root, name); | |
13110 | + if (!ent) | |
13111 | + return; | |
13112 | + } | |
13113 | +} | |
13114 | + | |
13115 | +void destroy_proc_ide_device(ide_hwif_t *hwif, ide_drive_t *drive) | |
13116 | +{ | |
13117 | + ide_driver_t *driver = drive->driver; | |
13118 | + | |
13119 | + if (drive->proc) { | |
13120 | if (driver) | |
13121 | ide_remove_proc_entries(drive->proc, driver->proc); | |
13122 | ide_remove_proc_entries(drive->proc, generic_drive_entries); | |
13123 | @@ -751,6 +805,19 @@ | |
13124 | } | |
13125 | } | |
13126 | ||
13127 | +void destroy_proc_ide_drives(ide_hwif_t *hwif) | |
13128 | +{ | |
13129 | + int d; | |
13130 | + | |
13131 | + for (d = 0; d < MAX_DRIVES; d++) { | |
13132 | + ide_drive_t *drive = &hwif->drives[d]; | |
13133 | +// ide_driver_t *driver = drive->driver; | |
13134 | + | |
13135 | + if (drive->proc) | |
13136 | + destroy_proc_ide_device(hwif, drive); | |
13137 | + } | |
13138 | +} | |
13139 | + | |
13140 | static ide_proc_entry_t hwif_entries[] = { | |
13141 | { "channel", S_IFREG|S_IRUGO, proc_ide_read_channel, NULL }, | |
13142 | { "config", S_IFREG|S_IRUGO|S_IWUSR,proc_ide_read_config, proc_ide_write_config }, | |
13143 | diff -Nur linux.org/drivers/ide/ide-swarm.c linux/drivers/ide/ide-swarm.c | |
13144 | --- linux.org/drivers/ide/ide-swarm.c Thu Jan 1 01:00:00 1970 | |
13145 | +++ linux/drivers/ide/ide-swarm.c Thu Jul 18 14:23:01 2002 | |
13146 | @@ -0,0 +1,73 @@ | |
13147 | +/* | |
13148 | + * Copyright (C) 2001 Broadcom Corporation | |
13149 | + * | |
13150 | + * This program is free software; you can redistribute it and/or | |
13151 | + * modify it under the terms of the GNU General Public License | |
13152 | + * as published by the Free Software Foundation; either version 2 | |
13153 | + * of the License, or (at your option) any later version. | |
13154 | + * | |
13155 | + * This program is distributed in the hope that it will be useful, | |
13156 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13157 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13158 | + * GNU General Public License for more details. | |
13159 | + * | |
13160 | + * You should have received a copy of the GNU General Public License | |
13161 | + * along with this program; if not, write to the Free Software | |
13162 | + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
13163 | + */ | |
13164 | + | |
13165 | +/* Derived loosely from ide-pmac.c, so: | |
13166 | + * | |
13167 | + * Copyright (C) 1998 Paul Mackerras. | |
13168 | + * Copyright (C) 1995-1998 Mark Lord | |
13169 | + */ | |
13170 | +#include <linux/config.h> | |
13171 | +#include <linux/types.h> | |
13172 | +#include <linux/kernel.h> | |
13173 | +#include <linux/sched.h> | |
13174 | +#include <linux/init.h> | |
13175 | +#include <linux/delay.h> | |
13176 | +#include <linux/ide.h> | |
13177 | +#include <asm/irq.h> | |
13178 | +#include <asm/io.h> | |
13179 | +#include <asm/sibyte/sb1250_int.h> | |
13180 | +#include <asm/sibyte/swarm_ide.h> | |
13181 | + | |
13182 | +void __init swarm_ide_probe(void) | |
13183 | +{ | |
13184 | + int i; | |
13185 | + ide_hwif_t *hwif; | |
13186 | + /* | |
13187 | + * Find the first untaken slot in hwifs | |
13188 | + */ | |
13189 | + for (i = 0; i < MAX_HWIFS; i++) { | |
13190 | + if (!ide_hwifs[i].io_ports[IDE_DATA_OFFSET]) { | |
13191 | + break; | |
13192 | + } | |
13193 | + } | |
13194 | + if (i == MAX_HWIFS) { | |
13195 | + printk("No space for SWARM onboard IDE driver in ide_hwifs[]. Not enabled.\n"); | |
13196 | + return; | |
13197 | + } | |
13198 | + | |
13199 | + /* Set up our stuff */ | |
13200 | + hwif = &ide_hwifs[i]; | |
13201 | + hwif->hw.io_ports[IDE_DATA_OFFSET] = SWARM_IDE_REG(0x1f0); | |
13202 | + hwif->hw.io_ports[IDE_ERROR_OFFSET] = SWARM_IDE_REG(0x1f1); | |
13203 | + hwif->hw.io_ports[IDE_NSECTOR_OFFSET] = SWARM_IDE_REG(0x1f2); | |
13204 | + hwif->hw.io_ports[IDE_SECTOR_OFFSET] = SWARM_IDE_REG(0x1f3); | |
13205 | + hwif->hw.io_ports[IDE_LCYL_OFFSET] = SWARM_IDE_REG(0x1f4); | |
13206 | + hwif->hw.io_ports[IDE_HCYL_OFFSET] = SWARM_IDE_REG(0x1f5); | |
13207 | + hwif->hw.io_ports[IDE_SELECT_OFFSET] = SWARM_IDE_REG(0x1f6); | |
13208 | + hwif->hw.io_ports[IDE_STATUS_OFFSET] = SWARM_IDE_REG(0x1f7); | |
13209 | + hwif->hw.io_ports[IDE_CONTROL_OFFSET] = SWARM_IDE_REG(0x3f6); | |
13210 | + hwif->hw.io_ports[IDE_IRQ_OFFSET] = SWARM_IDE_REG(0x3f7); | |
13211 | +// hwif->hw->ack_intr = swarm_ide_ack_intr; | |
13212 | + hwif->hw.irq = SWARM_IDE_INT; | |
13213 | + hwif->ideproc = swarm_ideproc; | |
13214 | + | |
13215 | + memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->io_ports)); | |
13216 | + hwif->irq = hwif->hw.irq; | |
13217 | + printk("SWARM onboard IDE configured as device %i\n", i); | |
13218 | +} | |
13219 | + | |
13220 | diff -Nur linux.org/drivers/ide/ide-tape.c linux/drivers/ide/ide-tape.c | |
13221 | --- linux.org/drivers/ide/ide-tape.c Fri Dec 21 18:41:54 2001 | |
13222 | +++ linux/drivers/ide/ide-tape.c Thu Jul 18 14:24:33 2002 | |
13223 | @@ -1835,10 +1835,9 @@ | |
13224 | * idetape_end_request is used to finish servicing a request, and to | |
13225 | * insert a pending pipeline request into the main device queue. | |
13226 | */ | |
13227 | -static void idetape_end_request (byte uptodate, ide_hwgroup_t *hwgroup) | |
13228 | +static int idetape_end_request (ide_drive_t *drive, int uptodate) | |
13229 | { | |
13230 | - ide_drive_t *drive = hwgroup->drive; | |
13231 | - struct request *rq = hwgroup->rq; | |
13232 | + struct request *rq = HWGROUP(drive)->rq; | |
13233 | idetape_tape_t *tape = drive->driver_data; | |
13234 | unsigned long flags; | |
13235 | int error; | |
13236 | @@ -1932,6 +1931,7 @@ | |
13237 | if (tape->active_data_request == NULL) | |
13238 | clear_bit(IDETAPE_PIPELINE_ACTIVE, &tape->flags); | |
13239 | spin_unlock_irqrestore(&tape->spinlock, flags); | |
13240 | + return 0; | |
13241 | } | |
13242 | ||
13243 | static ide_startstop_t idetape_request_sense_callback (ide_drive_t *drive) | |
13244 | @@ -1944,10 +1944,10 @@ | |
13245 | #endif /* IDETAPE_DEBUG_LOG */ | |
13246 | if (!tape->pc->error) { | |
13247 | idetape_analyze_error (drive, (idetape_request_sense_result_t *) tape->pc->buffer); | |
13248 | - idetape_end_request (1, HWGROUP (drive)); | |
13249 | + idetape_end_request(drive, 1); | |
13250 | } else { | |
13251 | printk (KERN_ERR "ide-tape: Error in REQUEST SENSE itself - Aborting request!\n"); | |
13252 | - idetape_end_request (0, HWGROUP (drive)); | |
13253 | + idetape_end_request(drive, 0); | |
13254 | } | |
13255 | return ide_stopped; | |
13256 | } | |
13257 | @@ -2050,10 +2050,11 @@ | |
13258 | ||
13259 | #if IDETAPE_DEBUG_LOG | |
13260 | if (tape->debug_level >= 4) | |
13261 | - printk (KERN_INFO "ide-tape: Reached idetape_pc_intr interrupt handler\n"); | |
13262 | + printk(KERN_INFO "ide-tape: Reached idetape_pc_intr " | |
13263 | + "interrupt handler\n"); | |
13264 | #endif /* IDETAPE_DEBUG_LOG */ | |
13265 | ||
13266 | - status.all = GET_STAT(); /* Clear the interrupt */ | |
13267 | + status.all = GET_STAT(); /* Clear the interrupt */ | |
13268 | ||
13269 | #ifdef CONFIG_BLK_DEV_IDEDMA | |
13270 | if (test_bit (PC_DMA_IN_PROGRESS, &pc->flags)) { | |
13271 | @@ -2090,11 +2091,14 @@ | |
13272 | #endif /* IDETAPE_DEBUG_LOG */ | |
13273 | clear_bit (PC_DMA_IN_PROGRESS, &pc->flags); | |
13274 | ||
13275 | - ide__sti(); /* local CPU only */ | |
13276 | + local_irq_enable(); | |
13277 | ||
13278 | #if SIMULATE_ERRORS | |
13279 | - if ((pc->c[0] == IDETAPE_WRITE_CMD || pc->c[0] == IDETAPE_READ_CMD) && (++error_sim_count % 100) == 0) { | |
13280 | - printk(KERN_INFO "ide-tape: %s: simulating error\n", tape->name); | |
13281 | + if ((pc->c[0] == IDETAPE_WRITE_CMD || | |
13282 | + pc->c[0] == IDETAPE_READ_CMD) && | |
13283 | + (++error_sim_count % 100) == 0) { | |
13284 | + printk(KERN_INFO "ide-tape: %s: simulating error\n", | |
13285 | + tape->name); | |
13286 | status.b.check = 1; | |
13287 | } | |
13288 | #endif | |
13289 | @@ -2103,10 +2107,10 @@ | |
13290 | if (status.b.check || test_bit (PC_DMA_ERROR, &pc->flags)) { /* Error detected */ | |
13291 | #if IDETAPE_DEBUG_LOG | |
13292 | if (tape->debug_level >= 1) | |
13293 | - printk (KERN_INFO "ide-tape: %s: I/O error, ",tape->name); | |
13294 | + printk(KERN_INFO "ide-tape: %s: I/O error, ",tape->name); | |
13295 | #endif /* IDETAPE_DEBUG_LOG */ | |
13296 | if (pc->c[0] == IDETAPE_REQUEST_SENSE_CMD) { | |
13297 | - printk (KERN_ERR "ide-tape: I/O error in request sense command\n"); | |
13298 | + printk(KERN_ERR "ide-tape: I/O error in request sense command\n"); | |
13299 | return ide_do_reset (drive); | |
13300 | } | |
13301 | #if IDETAPE_DEBUG_LOG | |
13302 | @@ -2116,31 +2120,34 @@ | |
13303 | return idetape_retry_pc (drive); /* Retry operation */ | |
13304 | } | |
13305 | pc->error = 0; | |
13306 | - if (!tape->onstream && test_bit (PC_WAIT_FOR_DSC, &pc->flags) && !status.b.dsc) { /* Media access command */ | |
13307 | + if (!tape->onstream && | |
13308 | + test_bit (PC_WAIT_FOR_DSC, &pc->flags) && !status.b.dsc) { | |
13309 | + /* Media access command */ | |
13310 | tape->dsc_polling_start = jiffies; | |
13311 | tape->dsc_polling_frequency = IDETAPE_DSC_MA_FAST; | |
13312 | tape->dsc_timeout = jiffies + IDETAPE_DSC_MA_TIMEOUT; | |
13313 | - idetape_postpone_request (drive); /* Allow ide.c to handle other requests */ | |
13314 | + idetape_postpone_request(drive); /* Allow ide.c to handle other requests */ | |
13315 | return ide_stopped; | |
13316 | } | |
13317 | if (tape->failed_pc == pc) | |
13318 | tape->failed_pc = NULL; | |
13319 | - return pc->callback(drive); /* Command finished - Call the callback function */ | |
13320 | + return pc->callback(drive); /* Command finished - Call the callback function */ | |
13321 | } | |
13322 | #ifdef CONFIG_BLK_DEV_IDEDMA | |
13323 | if (test_and_clear_bit (PC_DMA_IN_PROGRESS, &pc->flags)) { | |
13324 | - printk (KERN_ERR "ide-tape: The tape wants to issue more interrupts in DMA mode\n"); | |
13325 | - printk (KERN_ERR "ide-tape: DMA disabled, reverting to PIO\n"); | |
13326 | + printk(KERN_ERR "ide-tape: The tape wants to issue more " | |
13327 | + "interrupts in DMA mode\n"); | |
13328 | + printk(KERN_ERR "ide-tape: DMA disabled, reverting to PIO\n"); | |
13329 | (void) HWIF(drive)->dmaproc(ide_dma_off, drive); | |
13330 | return ide_do_reset (drive); | |
13331 | } | |
13332 | #endif /* CONFIG_BLK_DEV_IDEDMA */ | |
13333 | - bcount.b.high = IN_BYTE (IDE_BCOUNTH_REG); /* Get the number of bytes to transfer */ | |
13334 | - bcount.b.low = IN_BYTE (IDE_BCOUNTL_REG); /* on this interrupt */ | |
13335 | - ireason.all = IN_BYTE (IDE_IREASON_REG); | |
13336 | + bcount.b.high = IN_BYTE(IDE_BCOUNTH_REG); /* Get the number of bytes to transfer */ | |
13337 | + bcount.b.low = IN_BYTE(IDE_BCOUNTL_REG); /* on this interrupt */ | |
13338 | + ireason.all = IN_BYTE(IDE_IREASON_REG); | |
13339 | ||
13340 | if (ireason.b.cod) { | |
13341 | - printk (KERN_ERR "ide-tape: CoD != 0 in idetape_pc_intr\n"); | |
13342 | + printk(KERN_ERR "ide-tape: CoD != 0 in idetape_pc_intr\n"); | |
13343 | return ide_do_reset (drive); | |
13344 | } | |
13345 | if (ireason.b.io == test_bit (PC_WRITING, &pc->flags)) { /* Hopefully, we will never get here */ | |
13346 | @@ -2154,6 +2161,8 @@ | |
13347 | if (temp > pc->buffer_size) { | |
13348 | printk (KERN_ERR "ide-tape: The tape wants to send us more data than expected - discarding data\n"); | |
13349 | idetape_discard_data (drive, bcount.all); | |
13350 | + if (HWGROUP(drive)->handler != NULL) /* paranoia check */ | |
13351 | + BUG(); | |
13352 | ide_set_handler (drive, &idetape_pc_intr, IDETAPE_WAIT_CMD, NULL); | |
13353 | return ide_started; | |
13354 | } | |
13355 | @@ -2180,6 +2189,8 @@ | |
13356 | if (tape->debug_level >= 2) | |
13357 | printk(KERN_INFO "ide-tape: [cmd %x] transferred %d bytes on that interrupt\n", pc->c[0], bcount.all); | |
13358 | #endif | |
13359 | + if (HWGROUP(drive)->handler != NULL) /* paranoia check */ | |
13360 | + BUG(); | |
13361 | ide_set_handler (drive, &idetape_pc_intr, IDETAPE_WAIT_CMD, NULL); /* And set the interrupt handler again */ | |
13362 | return ide_started; | |
13363 | } | |
13364 | @@ -2234,28 +2245,33 @@ | |
13365 | int retries = 100; | |
13366 | ide_startstop_t startstop; | |
13367 | ||
13368 | - if (ide_wait_stat (&startstop,drive,DRQ_STAT,BUSY_STAT,WAIT_READY)) { | |
13369 | - printk (KERN_ERR "ide-tape: Strange, packet command initiated yet DRQ isn't asserted\n"); | |
13370 | + if (ide_wait_stat(&startstop,drive,DRQ_STAT,BUSY_STAT,WAIT_READY)) { | |
13371 | + printk(KERN_ERR "ide-tape: Strange, packet command initiated yet DRQ isn't asserted\n"); | |
13372 | return startstop; | |
13373 | } | |
13374 | - ireason.all = IN_BYTE (IDE_IREASON_REG); | |
13375 | + ireason.all = IN_BYTE(IDE_IREASON_REG); | |
13376 | while (retries-- && (!ireason.b.cod || ireason.b.io)) { | |
13377 | - printk(KERN_ERR "ide-tape: (IO,CoD != (0,1) while issuing a packet command, retrying\n"); | |
13378 | + printk(KERN_ERR "ide-tape: (IO,CoD != (0,1) while issuing " | |
13379 | + "a packet command, retrying\n"); | |
13380 | udelay(100); | |
13381 | ireason.all = IN_BYTE(IDE_IREASON_REG); | |
13382 | if (retries == 0) { | |
13383 | - printk(KERN_ERR "ide-tape: (IO,CoD != (0,1) while issuing a packet command, ignoring\n"); | |
13384 | + printk(KERN_ERR "ide-tape: (IO,CoD != (0,1) while " | |
13385 | + "issuing a packet command, ignoring\n"); | |
13386 | ireason.b.cod = 1; | |
13387 | ireason.b.io = 0; | |
13388 | } | |
13389 | } | |
13390 | if (!ireason.b.cod || ireason.b.io) { | |
13391 | - printk (KERN_ERR "ide-tape: (IO,CoD) != (0,1) while issuing a packet command\n"); | |
13392 | + printk(KERN_ERR "ide-tape: (IO,CoD) != (0,1) while issuing " | |
13393 | + "a packet command\n"); | |
13394 | return ide_do_reset (drive); | |
13395 | } | |
13396 | tape->cmd_start_time = jiffies; | |
13397 | + if (HWGROUP(drive)->handler != NULL) /* paranoia check */ | |
13398 | + BUG(); | |
13399 | ide_set_handler(drive, &idetape_pc_intr, IDETAPE_WAIT_CMD, NULL); /* Set the interrupt routine */ | |
13400 | - atapi_output_bytes (drive,pc->c,12); /* Send the actual packet */ | |
13401 | + atapi_output_bytes(drive,pc->c,12); /* Send the actual packet */ | |
13402 | return ide_started; | |
13403 | } | |
13404 | ||
13405 | @@ -2266,16 +2282,19 @@ | |
13406 | int dma_ok = 0; | |
13407 | ||
13408 | #if IDETAPE_DEBUG_BUGS | |
13409 | - if (tape->pc->c[0] == IDETAPE_REQUEST_SENSE_CMD && pc->c[0] == IDETAPE_REQUEST_SENSE_CMD) { | |
13410 | - printk (KERN_ERR "ide-tape: possible ide-tape.c bug - Two request sense in serial were issued\n"); | |
13411 | + if (tape->pc->c[0] == IDETAPE_REQUEST_SENSE_CMD && | |
13412 | + pc->c[0] == IDETAPE_REQUEST_SENSE_CMD) { | |
13413 | + printk(KERN_ERR "ide-tape: possible ide-tape.c bug - " | |
13414 | + "Two request sense in serial were issued\n"); | |
13415 | } | |
13416 | #endif /* IDETAPE_DEBUG_BUGS */ | |
13417 | ||
13418 | if (tape->failed_pc == NULL && pc->c[0] != IDETAPE_REQUEST_SENSE_CMD) | |
13419 | tape->failed_pc = pc; | |
13420 | - tape->pc = pc; /* Set the current packet command */ | |
13421 | + tape->pc = pc; /* Set the current packet command */ | |
13422 | ||
13423 | - if (pc->retries > IDETAPE_MAX_PC_RETRIES || test_bit (PC_ABORT, &pc->flags)) { | |
13424 | + if (pc->retries > IDETAPE_MAX_PC_RETRIES || | |
13425 | + test_bit(PC_ABORT, &pc->flags)) { | |
13426 | /* | |
13427 | * We will "abort" retrying a packet command in case | |
13428 | * a legitimate error code was received (crossing a | |
13429 | @@ -2283,14 +2302,19 @@ | |
13430 | * example). | |
13431 | */ | |
13432 | if (!test_bit (PC_ABORT, &pc->flags)) { | |
13433 | - if (!(pc->c[0] == IDETAPE_TEST_UNIT_READY_CMD && tape->sense_key == 2 && | |
13434 | - tape->asc == 4 && (tape->ascq == 1 || tape->ascq == 8))) { | |
13435 | - printk (KERN_ERR "ide-tape: %s: I/O error, pc = %2x, key = %2x, asc = %2x, ascq = %2x\n", | |
13436 | - tape->name, pc->c[0], tape->sense_key, tape->asc, tape->ascq); | |
13437 | + if (!(pc->c[0] == IDETAPE_TEST_UNIT_READY_CMD && | |
13438 | + tape->sense_key == 2 && tape->asc == 4 && | |
13439 | + (tape->ascq == 1 || tape->ascq == 8))) { | |
13440 | + printk(KERN_ERR "ide-tape: %s: I/O error, " | |
13441 | + "pc = %2x, key = %2x, " | |
13442 | + "asc = %2x, ascq = %2x\n", | |
13443 | + tape->name, pc->c[0], | |
13444 | + tape->sense_key, tape->asc, | |
13445 | + tape->ascq); | |
13446 | if (tape->onstream && pc->c[0] == IDETAPE_READ_CMD && tape->sense_key == 3 && tape->asc == 0x11) /* AJN-1: 11 should be 0x11 */ | |
13447 | printk(KERN_ERR "ide-tape: %s: enabling read error recovery\n", tape->name); | |
13448 | } | |
13449 | - pc->error = IDETAPE_ERROR_GENERAL; /* Giving up */ | |
13450 | + pc->error = IDETAPE_ERROR_GENERAL; /* Giving up */ | |
13451 | } | |
13452 | tape->failed_pc = NULL; | |
13453 | return pc->callback(drive); | |
13454 | @@ -2301,13 +2325,14 @@ | |
13455 | #endif /* IDETAPE_DEBUG_LOG */ | |
13456 | ||
13457 | pc->retries++; | |
13458 | - pc->actually_transferred = 0; /* We haven't transferred any data yet */ | |
13459 | + pc->actually_transferred = 0; /* We haven't transferred any data yet */ | |
13460 | pc->current_position=pc->buffer; | |
13461 | - bcount.all=pc->request_transfer; /* Request to transfer the entire buffer at once */ | |
13462 | + bcount.all=pc->request_transfer; /* Request to transfer the entire buffer at once */ | |
13463 | ||
13464 | #ifdef CONFIG_BLK_DEV_IDEDMA | |
13465 | - if (test_and_clear_bit (PC_DMA_ERROR, &pc->flags)) { | |
13466 | - printk (KERN_WARNING "ide-tape: DMA disabled, reverting to PIO\n"); | |
13467 | + if (test_and_clear_bit(PC_DMA_ERROR, &pc->flags)) { | |
13468 | + printk(KERN_WARNING "ide-tape: DMA disabled, " | |
13469 | + "reverting to PIO\n"); | |
13470 | (void) HWIF(drive)->dmaproc(ide_dma_off, drive); | |
13471 | } | |
13472 | if (test_bit (PC_DMA_RECOMMENDED, &pc->flags) && drive->using_dma) | |
13473 | @@ -2315,18 +2340,20 @@ | |
13474 | #endif /* CONFIG_BLK_DEV_IDEDMA */ | |
13475 | ||
13476 | if (IDE_CONTROL_REG) | |
13477 | - OUT_BYTE (drive->ctl, IDE_CONTROL_REG); | |
13478 | - OUT_BYTE (dma_ok ? 1 : 0, IDE_FEATURE_REG); /* Use PIO/DMA */ | |
13479 | - OUT_BYTE (bcount.b.high, IDE_BCOUNTH_REG); | |
13480 | - OUT_BYTE (bcount.b.low, IDE_BCOUNTL_REG); | |
13481 | - OUT_BYTE (drive->select.all, IDE_SELECT_REG); | |
13482 | + OUT_BYTE(drive->ctl, IDE_CONTROL_REG); | |
13483 | + OUT_BYTE(dma_ok ? 1 : 0, IDE_FEATURE_REG); /* Use PIO/DMA */ | |
13484 | + OUT_BYTE(bcount.b.high, IDE_BCOUNTH_REG); | |
13485 | + OUT_BYTE(bcount.b.low, IDE_BCOUNTL_REG); | |
13486 | + OUT_BYTE(drive->select.all, IDE_SELECT_REG); | |
13487 | #ifdef CONFIG_BLK_DEV_IDEDMA | |
13488 | - if (dma_ok) { /* Begin DMA, if necessary */ | |
13489 | + if (dma_ok) { /* Begin DMA, if necessary */ | |
13490 | set_bit (PC_DMA_IN_PROGRESS, &pc->flags); | |
13491 | (void) (HWIF(drive)->dmaproc(ide_dma_begin, drive)); | |
13492 | } | |
13493 | #endif /* CONFIG_BLK_DEV_IDEDMA */ | |
13494 | if (test_bit(IDETAPE_DRQ_INTERRUPT, &tape->flags)) { | |
13495 | + if (HWGROUP(drive)->handler != NULL) /* paranoia check */ | |
13496 | + BUG(); | |
13497 | ide_set_handler(drive, &idetape_transfer_pc, IDETAPE_WAIT_CMD, NULL); | |
13498 | OUT_BYTE(WIN_PACKETCMD, IDE_COMMAND_REG); | |
13499 | return ide_started; | |
13500 | @@ -2348,7 +2375,7 @@ | |
13501 | printk (KERN_INFO "ide-tape: Reached idetape_pc_callback\n"); | |
13502 | #endif /* IDETAPE_DEBUG_LOG */ | |
13503 | ||
13504 | - idetape_end_request (tape->pc->error ? 0 : 1, HWGROUP(drive)); | |
13505 | + idetape_end_request(drive, tape->pc->error ? 0 : 1); | |
13506 | return ide_stopped; | |
13507 | } | |
13508 | ||
13509 | @@ -2360,10 +2387,10 @@ | |
13510 | idetape_init_pc (pc); | |
13511 | pc->c[0] = IDETAPE_MODE_SENSE_CMD; | |
13512 | if (page_code != IDETAPE_BLOCK_DESCRIPTOR) | |
13513 | - pc->c[1] = 8; /* DBD = 1 - Don't return block descriptors */ | |
13514 | + pc->c[1] = 8; /* DBD = 1 - Don't return block descriptors */ | |
13515 | pc->c[2] = page_code; | |
13516 | - pc->c[3] = 255; /* Don't limit the returned information */ | |
13517 | - pc->c[4] = 255; /* (We will just discard data in that case) */ | |
13518 | + pc->c[3] = 255; /* Don't limit the returned information */ | |
13519 | + pc->c[4] = 255; /* (We will just discard data in that case) */ | |
13520 | if (page_code == IDETAPE_BLOCK_DESCRIPTOR) | |
13521 | pc->request_transfer = 12; | |
13522 | else if (page_code == IDETAPE_CAPABILITIES_PAGE) | |
13523 | @@ -2391,13 +2418,15 @@ | |
13524 | } | |
13525 | tape->tape_still_time = (jiffies - tape->tape_still_time_begin) * 1000 / HZ; | |
13526 | #if USE_IOTRACE | |
13527 | - IO_trace(IO_IDETAPE_FIFO, tape->pipeline_head, tape->buffer_head, tape->tape_head, tape->minor); | |
13528 | + IO_trace(IO_IDETAPE_FIFO, tape->pipeline_head, tape->buffer_head, | |
13529 | + tape->tape_head, tape->minor); | |
13530 | #endif | |
13531 | #if IDETAPE_DEBUG_LOG | |
13532 | if (tape->debug_level >= 1) | |
13533 | - printk(KERN_INFO "ide-tape: buffer fill callback, %d/%d\n", tape->cur_frames, tape->max_frames); | |
13534 | + printk(KERN_INFO "ide-tape: buffer fill callback, %d/%d\n", | |
13535 | + tape->cur_frames, tape->max_frames); | |
13536 | #endif | |
13537 | - idetape_end_request (tape->pc->error ? 0 : 1, HWGROUP(drive)); | |
13538 | + idetape_end_request(drive, tape->pc->error ? 0 : 1); | |
13539 | return ide_stopped; | |
13540 | } | |
13541 | ||
13542 | @@ -2418,26 +2447,26 @@ | |
13543 | idetape_tape_t *tape = drive->driver_data; | |
13544 | int full = 125, empty = 75; | |
13545 | ||
13546 | - if (jiffies > tape->controlled_pipeline_head_time + 120 * HZ) { | |
13547 | + if (time_after(jiffies, tape->controlled_pipeline_head_time + 120 * HZ)) { | |
13548 | tape->controlled_previous_pipeline_head = tape->controlled_last_pipeline_head; | |
13549 | tape->controlled_previous_head_time = tape->controlled_pipeline_head_time; | |
13550 | tape->controlled_last_pipeline_head = tape->pipeline_head; | |
13551 | tape->controlled_pipeline_head_time = jiffies; | |
13552 | } | |
13553 | - if (jiffies > tape->controlled_pipeline_head_time + 60 * HZ) | |
13554 | + if (time_after(jiffies, tape->controlled_pipeline_head_time + 60 * HZ)) | |
13555 | tape->controlled_pipeline_head_speed = (tape->pipeline_head - tape->controlled_last_pipeline_head) * 32 * HZ / (jiffies - tape->controlled_pipeline_head_time); | |
13556 | - else if (jiffies > tape->controlled_previous_head_time) | |
13557 | + else if (time_after(jiffies, tape->controlled_previous_head_time)) | |
13558 | tape->controlled_pipeline_head_speed = (tape->pipeline_head - tape->controlled_previous_pipeline_head) * 32 * HZ / (jiffies - tape->controlled_previous_head_time); | |
13559 | ||
13560 | if (tape->nr_pending_stages < tape->max_stages /*- 1 */) { /* -1 for read mode error recovery */ | |
13561 | - if (jiffies > tape->uncontrolled_previous_head_time + 10 * HZ) { | |
13562 | + if (time_after(jiffies, tape->uncontrolled_previous_head_time + 10 * HZ)) { | |
13563 | tape->uncontrolled_pipeline_head_time = jiffies; | |
13564 | tape->uncontrolled_pipeline_head_speed = (tape->pipeline_head - tape->uncontrolled_previous_pipeline_head) * 32 * HZ / (jiffies - tape->uncontrolled_previous_head_time); | |
13565 | } | |
13566 | } else { | |
13567 | tape->uncontrolled_previous_head_time = jiffies; | |
13568 | tape->uncontrolled_previous_pipeline_head = tape->pipeline_head; | |
13569 | - if (jiffies > tape->uncontrolled_pipeline_head_time + 30 * HZ) { | |
13570 | + if (time_after(jiffies, tape->uncontrolled_pipeline_head_time + 30 * HZ)) { | |
13571 | tape->uncontrolled_pipeline_head_time = jiffies; | |
13572 | } | |
13573 | } | |
13574 | @@ -2471,9 +2500,9 @@ | |
13575 | printk(KERN_INFO "ide-tape: bug: onstream, media_access_finished\n"); | |
13576 | status.all = GET_STAT(); | |
13577 | if (status.b.dsc) { | |
13578 | - if (status.b.check) { /* Error detected */ | |
13579 | + if (status.b.check) { /* Error detected */ | |
13580 | printk (KERN_ERR "ide-tape: %s: I/O error, ",tape->name); | |
13581 | - return idetape_retry_pc (drive); /* Retry operation */ | |
13582 | + return idetape_retry_pc (drive); /* Retry operation */ | |
13583 | } | |
13584 | pc->error = 0; | |
13585 | if (tape->failed_pc == pc) | |
13586 | @@ -2500,7 +2529,7 @@ | |
13587 | tape->insert_time = jiffies; | |
13588 | tape->insert_size = 0; | |
13589 | } | |
13590 | - if (jiffies > tape->insert_time) | |
13591 | + if (time_after(jiffies, tape->insert_time)) | |
13592 | tape->insert_speed = tape->insert_size / 1024 * HZ / (jiffies - tape->insert_time); | |
13593 | if (jiffies - tape->avg_time >= HZ) { | |
13594 | tape->avg_speed = tape->avg_size * HZ / (jiffies - tape->avg_time) / 1024; | |
13595 | @@ -2517,9 +2546,9 @@ | |
13596 | rq->current_nr_sectors -= blocks; | |
13597 | ||
13598 | if (!tape->pc->error) | |
13599 | - idetape_end_request (1, HWGROUP (drive)); | |
13600 | + idetape_end_request(drive, 1); | |
13601 | else | |
13602 | - idetape_end_request (tape->pc->error, HWGROUP (drive)); | |
13603 | + idetape_end_request(drive, tape->pc->error); | |
13604 | return ide_stopped; | |
13605 | } | |
13606 | ||
13607 | @@ -2607,6 +2636,38 @@ | |
13608 | } | |
13609 | ||
13610 | /* | |
13611 | + * This is our end_request replacement function. | |
13612 | + */ | |
13613 | +static int idetape_do_end_request (ide_drive_t *drive, int uptodate) | |
13614 | +{ | |
13615 | + struct request *rq; | |
13616 | + unsigned long flags; | |
13617 | + int ret = 1; | |
13618 | + | |
13619 | + spin_lock_irqsave(&io_request_lock, flags); | |
13620 | + rq = HWGROUP(drive)->rq; | |
13621 | + | |
13622 | + /* | |
13623 | + * decide whether to reenable DMA -- 3 is a random magic for now, | |
13624 | + * if we DMA timeout more than 3 times, just stay in PIO | |
13625 | + */ | |
13626 | + if (drive->state == DMA_PIO_RETRY && drive->retry_pio <= 3) { | |
13627 | + drive->state = 0; | |
13628 | + HWGROUP(drive)->hwif->dmaproc(ide_dma_on, drive); | |
13629 | + } | |
13630 | + | |
13631 | + if (!end_that_request_first(rq, uptodate, drive->name)) { | |
13632 | + add_blkdev_randomness(MAJOR(rq->rq_dev)); | |
13633 | + blkdev_dequeue_request(rq); | |
13634 | + HWGROUP(drive)->rq = NULL; | |
13635 | + end_that_request_last(rq); | |
13636 | + ret = 0; | |
13637 | + } | |
13638 | + spin_unlock_irqrestore(&io_request_lock, flags); | |
13639 | + return ret; | |
13640 | +} | |
13641 | + | |
13642 | +/* | |
13643 | * idetape_do_request is our request handling function. | |
13644 | */ | |
13645 | static ide_startstop_t idetape_do_request (ide_drive_t *drive, struct request *rq, unsigned long block) | |
13646 | @@ -2618,31 +2679,38 @@ | |
13647 | ||
13648 | #if IDETAPE_DEBUG_LOG | |
13649 | if (tape->debug_level >= 5) | |
13650 | - printk (KERN_INFO "ide-tape: rq_status: %d, rq_dev: %u, cmd: %d, errors: %d\n",rq->rq_status,(unsigned int) rq->rq_dev,rq->cmd,rq->errors); | |
13651 | + printk (KERN_INFO "ide-tape: rq_status: %d, " | |
13652 | + "rq_dev: %u, cmd: %d, errors: %d\n", rq->rq_status, | |
13653 | + (unsigned int) rq->rq_dev, rq->cmd, rq->errors); | |
13654 | if (tape->debug_level >= 2) | |
13655 | - printk (KERN_INFO "ide-tape: sector: %ld, nr_sectors: %ld, current_nr_sectors: %ld\n",rq->sector,rq->nr_sectors,rq->current_nr_sectors); | |
13656 | + printk (KERN_INFO "ide-tape: sector: %ld, " | |
13657 | + "nr_sectors: %ld, current_nr_sectors: %ld\n", | |
13658 | + rq->sector, rq->nr_sectors, rq->current_nr_sectors); | |
13659 | #endif /* IDETAPE_DEBUG_LOG */ | |
13660 | ||
13661 | if (!IDETAPE_RQ_CMD (rq->cmd)) { | |
13662 | /* | |
13663 | * We do not support buffer cache originated requests. | |
13664 | */ | |
13665 | - printk (KERN_NOTICE "ide-tape: %s: Unsupported command in request queue (%d)\n", drive->name, rq->cmd); | |
13666 | - ide_end_request (0, HWGROUP (drive)); /* Let the common code handle it */ | |
13667 | + printk (KERN_NOTICE "ide-tape: %s: Unsupported command in " | |
13668 | + "request queue (%d)\n", drive->name, rq->cmd); | |
13669 | + idetape_do_end_request(drive, 0); | |
13670 | return ide_stopped; | |
13671 | } | |
13672 | ||
13673 | /* | |
13674 | * Retry a failed packet command | |
13675 | */ | |
13676 | - if (tape->failed_pc != NULL && tape->pc->c[0] == IDETAPE_REQUEST_SENSE_CMD) { | |
13677 | + if (tape->failed_pc != NULL && | |
13678 | + tape->pc->c[0] == IDETAPE_REQUEST_SENSE_CMD) { | |
13679 | return idetape_issue_packet_command (drive, tape->failed_pc); | |
13680 | } | |
13681 | #if IDETAPE_DEBUG_BUGS | |
13682 | if (postponed_rq != NULL) | |
13683 | if (rq != postponed_rq) { | |
13684 | - printk (KERN_ERR "ide-tape: ide-tape.c bug - Two DSC requests were queued\n"); | |
13685 | - idetape_end_request (0, HWGROUP (drive)); | |
13686 | + printk (KERN_ERR "ide-tape: ide-tape.c bug - " | |
13687 | + "Two DSC requests were queued\n"); | |
13688 | + idetape_end_request(drive, 0); | |
13689 | return ide_stopped; | |
13690 | } | |
13691 | #endif /* IDETAPE_DEBUG_BUGS */ | |
13692 | @@ -2674,17 +2742,18 @@ | |
13693 | */ | |
13694 | if (tape->tape_still_time > 100 && tape->tape_still_time < 200) | |
13695 | tape->measure_insert_time = 1; | |
13696 | - if (tape->req_buffer_fill && (rq->cmd == IDETAPE_WRITE_RQ || rq->cmd == IDETAPE_READ_RQ)) { | |
13697 | + if (tape->req_buffer_fill && | |
13698 | + (rq->cmd == IDETAPE_WRITE_RQ || rq->cmd == IDETAPE_READ_RQ)) { | |
13699 | tape->req_buffer_fill = 0; | |
13700 | tape->writes_since_buffer_fill = 0; | |
13701 | tape->reads_since_buffer_fill = 0; | |
13702 | tape->last_buffer_fill = jiffies; | |
13703 | idetape_queue_onstream_buffer_fill(drive); | |
13704 | - if (jiffies > tape->insert_time) | |
13705 | + if (time_after(jiffies, tape->insert_time)) | |
13706 | tape->insert_speed = tape->insert_size / 1024 * HZ / (jiffies - tape->insert_time); | |
13707 | return ide_stopped; | |
13708 | } | |
13709 | - if (jiffies > tape->insert_time) | |
13710 | + if (time_after(jiffies, tape->insert_time)) | |
13711 | tape->insert_speed = tape->insert_size / 1024 * HZ / (jiffies - tape->insert_time); | |
13712 | calculate_speeds(drive); | |
13713 | if (tape->onstream && tape->max_frames && | |
13714 | @@ -2699,7 +2768,8 @@ | |
13715 | tape->insert_speed > tape->max_insert_speed ) ) && rq->nr_sectors) ) ) { | |
13716 | #if IDETAPE_DEBUG_LOG | |
13717 | if (tape->debug_level >= 4) | |
13718 | - printk(KERN_INFO "ide-tape: postponing request, cmd %d, cur %d, max %d\n", | |
13719 | + printk(KERN_INFO "ide-tape: postponing request, " | |
13720 | + "cmd %d, cur %d, max %d\n", | |
13721 | rq->cmd, tape->cur_frames, tape->max_frames); | |
13722 | #endif | |
13723 | if (tape->postpone_cnt++ < 500) { | |
13724 | @@ -2708,7 +2778,8 @@ | |
13725 | } | |
13726 | #if ONSTREAM_DEBUG | |
13727 | else if (tape->debug_level >= 4) | |
13728 | - printk(KERN_INFO "ide-tape: %s: postpone_cnt %d\n", tape->name, tape->postpone_cnt); | |
13729 | + printk(KERN_INFO "ide-tape: %s: postpone_cnt %d\n", | |
13730 | + tape->name, tape->postpone_cnt); | |
13731 | #endif | |
13732 | } | |
13733 | if (!test_and_clear_bit (IDETAPE_IGNORE_DSC, &tape->flags) && !status.b.dsc) { | |
13734 | @@ -2740,7 +2811,7 @@ | |
13735 | if (tape->onstream) { | |
13736 | if (tape->cur_frames - tape->reads_since_buffer_fill <= 0) | |
13737 | tape->req_buffer_fill = 1; | |
13738 | - if (jiffies > tape->last_buffer_fill + 5 * HZ / 100) | |
13739 | + if (time_after(jiffies, tape->last_buffer_fill + 5 * HZ / 100)) | |
13740 | tape->req_buffer_fill = 1; | |
13741 | } | |
13742 | pc = idetape_next_pc_storage (drive); | |
13743 | @@ -2756,7 +2827,7 @@ | |
13744 | if (tape->onstream) { | |
13745 | if (tape->cur_frames + tape->writes_since_buffer_fill >= tape->max_frames) | |
13746 | tape->req_buffer_fill = 1; | |
13747 | - if (jiffies > tape->last_buffer_fill + 5 * HZ / 100) | |
13748 | + if (time_after(jiffies, tape->last_buffer_fill + 5 * HZ / 100)) | |
13749 | tape->req_buffer_fill = 1; | |
13750 | calculate_speeds(drive); | |
13751 | } | |
13752 | @@ -2770,7 +2841,7 @@ | |
13753 | break; | |
13754 | case IDETAPE_ABORTED_WRITE_RQ: | |
13755 | rq->cmd = IDETAPE_WRITE_RQ; | |
13756 | - idetape_end_request (IDETAPE_ERROR_EOD, HWGROUP(drive)); | |
13757 | + idetape_end_request(drive, IDETAPE_ERROR_EOD); | |
13758 | return ide_stopped; | |
13759 | case IDETAPE_ABORTED_READ_RQ: | |
13760 | #if IDETAPE_DEBUG_LOG | |
13761 | @@ -2778,7 +2849,7 @@ | |
13762 | printk(KERN_INFO "ide-tape: %s: detected aborted read rq\n", tape->name); | |
13763 | #endif | |
13764 | rq->cmd = IDETAPE_READ_RQ; | |
13765 | - idetape_end_request (IDETAPE_ERROR_EOD, HWGROUP(drive)); | |
13766 | + idetape_end_request(drive, IDETAPE_ERROR_EOD); | |
13767 | return ide_stopped; | |
13768 | case IDETAPE_PC_RQ1: | |
13769 | pc = (idetape_pc_t *) rq->buffer; | |
13770 | @@ -2789,7 +2860,7 @@ | |
13771 | return ide_stopped; | |
13772 | default: | |
13773 | printk (KERN_ERR "ide-tape: bug in IDETAPE_RQ_CMD macro\n"); | |
13774 | - idetape_end_request (0, HWGROUP (drive)); | |
13775 | + idetape_end_request(drive, 0); | |
13776 | return ide_stopped; | |
13777 | } | |
13778 | return idetape_issue_packet_command (drive, pc); | |
13779 | @@ -3096,10 +3167,10 @@ | |
13780 | idetape_tape_t *tape = drive->driver_data; | |
13781 | idetape_read_position_result_t *result; | |
13782 | ||
13783 | -//#if IDETAPE_DEBUG_LOG | |
13784 | -// if (tape->debug_level >= 4) | |
13785 | +#if IDETAPE_DEBUG_LOG | |
13786 | + if (tape->debug_level >= 4) | |
13787 | printk (KERN_INFO "ide-tape: Reached idetape_read_position_callback\n"); | |
13788 | -//#endif /* IDETAPE_DEBUG_LOG */ | |
13789 | +#endif /* IDETAPE_DEBUG_LOG */ | |
13790 | ||
13791 | if (!tape->pc->error) { | |
13792 | result = (idetape_read_position_result_t *) tape->pc->buffer; | |
13793 | @@ -3112,7 +3183,7 @@ | |
13794 | if (result->bpu) { | |
13795 | printk (KERN_INFO "ide-tape: Block location is unknown to the tape\n"); | |
13796 | clear_bit (IDETAPE_ADDRESS_VALID, &tape->flags); | |
13797 | - idetape_end_request (0, HWGROUP (drive)); | |
13798 | + idetape_end_request(drive, 0); | |
13799 | } else { | |
13800 | #if IDETAPE_DEBUG_LOG | |
13801 | if (tape->debug_level >= 2) | |
13802 | @@ -3123,10 +3194,10 @@ | |
13803 | tape->last_frame_position = ntohl (result->last_block); | |
13804 | tape->blocks_in_buffer = result->blocks_in_buffer[2]; | |
13805 | set_bit (IDETAPE_ADDRESS_VALID, &tape->flags); | |
13806 | - idetape_end_request (1, HWGROUP (drive)); | |
13807 | + idetape_end_request(drive, 1); | |
13808 | } | |
13809 | } else { | |
13810 | - idetape_end_request (0, HWGROUP (drive)); | |
13811 | + idetape_end_request(drive, 0); | |
13812 | } | |
13813 | return ide_stopped; | |
13814 | } | |
13815 | @@ -3214,7 +3285,7 @@ | |
13816 | * Wait for the tape to become ready | |
13817 | */ | |
13818 | timeout += jiffies; | |
13819 | - while (jiffies < timeout) { | |
13820 | + while (time_before(jiffies, timeout)) { | |
13821 | idetape_create_test_unit_ready_cmd(&pc); | |
13822 | if (!__idetape_queue_pc_tail(drive, &pc)) | |
13823 | return 0; | |
13824 | @@ -3273,10 +3344,10 @@ | |
13825 | idetape_pc_t pc; | |
13826 | int position; | |
13827 | ||
13828 | -//#if IDETAPE_DEBUG_LOG | |
13829 | -// if (tape->debug_level >= 4) | |
13830 | +#if IDETAPE_DEBUG_LOG | |
13831 | + if (tape->debug_level >= 4) | |
13832 | printk (KERN_INFO "ide-tape: Reached idetape_read_position\n"); | |
13833 | -//#endif /* IDETAPE_DEBUG_LOG */ | |
13834 | +#endif /* IDETAPE_DEBUG_LOG */ | |
13835 | ||
13836 | #ifdef NO_LONGER_REQUIRED | |
13837 | idetape_flush_tape_buffers(drive); | |
13838 | @@ -6085,14 +6156,14 @@ | |
13839 | int minor = tape->minor; | |
13840 | unsigned long flags; | |
13841 | ||
13842 | - save_flags (flags); /* all CPUs (overkill?) */ | |
13843 | - cli(); /* all CPUs (overkill?) */ | |
13844 | - if (test_bit (IDETAPE_BUSY, &tape->flags) || tape->first_stage != NULL || tape->merge_stage_size || drive->usage) { | |
13845 | - restore_flags(flags); /* all CPUs (overkill?) */ | |
13846 | + spin_lock_irqsave(&io_request_lock, flags); | |
13847 | + if (test_bit (IDETAPE_BUSY, &tape->flags) || drive->usage || | |
13848 | + tape->first_stage != NULL || tape->merge_stage_size) { | |
13849 | + spin_unlock_irqrestore(&io_request_lock, flags); | |
13850 | return 1; | |
13851 | } | |
13852 | idetape_chrdevs[minor].drive = NULL; | |
13853 | - restore_flags (flags); /* all CPUs (overkill?) */ | |
13854 | + spin_unlock_irqrestore(&io_request_lock, flags); | |
13855 | DRIVER(drive)->busy = 0; | |
13856 | (void) ide_unregister_subdriver (drive); | |
13857 | drive->driver_data = NULL; | |
13858 | @@ -6132,10 +6203,8 @@ | |
13859 | ||
13860 | #endif | |
13861 | ||
13862 | -static int idetape_reinit (ide_drive_t *drive) | |
13863 | -{ | |
13864 | - return 0; | |
13865 | -} | |
13866 | +int idetape_init (void); | |
13867 | +int idetape_reinit(ide_drive_t *drive); | |
13868 | ||
13869 | /* | |
13870 | * IDE subdriver functions, registered with ide.c | |
13871 | @@ -6145,11 +6214,21 @@ | |
13872 | version: IDETAPE_VERSION, | |
13873 | media: ide_tape, | |
13874 | busy: 1, | |
13875 | +#ifdef CONFIG_IDEDMA_ONLYDISK | |
13876 | + supports_dma: 0, | |
13877 | +#else | |
13878 | supports_dma: 1, | |
13879 | +#endif | |
13880 | supports_dsc_overlap: 1, | |
13881 | cleanup: idetape_cleanup, | |
13882 | + standby: NULL, | |
13883 | + suspend: NULL, | |
13884 | + resume: NULL, | |
13885 | + flushcache: NULL, | |
13886 | do_request: idetape_do_request, | |
13887 | end_request: idetape_end_request, | |
13888 | + sense: NULL, | |
13889 | + error: NULL, | |
13890 | ioctl: idetape_blkdev_ioctl, | |
13891 | open: idetape_blkdev_open, | |
13892 | release: idetape_blkdev_release, | |
13893 | @@ -6157,11 +6236,14 @@ | |
13894 | revalidate: NULL, | |
13895 | pre_reset: idetape_pre_reset, | |
13896 | capacity: NULL, | |
13897 | + special: NULL, | |
13898 | proc: idetape_proc, | |
13899 | - driver_reinit: idetape_reinit, | |
13900 | + init: idetape_init, | |
13901 | + reinit: idetape_reinit, | |
13902 | + ata_prebuilder: NULL, | |
13903 | + atapi_prebuilder: NULL, | |
13904 | }; | |
13905 | ||
13906 | -int idetape_init (void); | |
13907 | static ide_module_t idetape_module = { | |
13908 | IDE_DRIVER_MODULE, | |
13909 | idetape_init, | |
13910 | @@ -6181,6 +6263,92 @@ | |
13911 | release: idetape_chrdev_release, | |
13912 | }; | |
13913 | ||
13914 | +int idetape_reinit (ide_drive_t *drive) | |
13915 | +{ | |
13916 | +#if 0 | |
13917 | + idetape_tape_t *tape; | |
13918 | + int minor, failed = 0, supported = 0; | |
13919 | +/* DRIVER(drive)->busy++; */ | |
13920 | + MOD_INC_USE_COUNT; | |
13921 | +#if ONSTREAM_DEBUG | |
13922 | + printk(KERN_INFO "ide-tape: MOD_INC_USE_COUNT in idetape_init\n"); | |
13923 | +#endif | |
13924 | + if (!idetape_chrdev_present) | |
13925 | + for (minor = 0; minor < MAX_HWIFS * MAX_DRIVES; minor++ ) | |
13926 | + idetape_chrdevs[minor].drive = NULL; | |
13927 | + | |
13928 | + if ((drive = ide_scan_devices (ide_tape, idetape_driver.name, NULL, failed++)) == NULL) { | |
13929 | + ide_register_module (&idetape_module); | |
13930 | + MOD_DEC_USE_COUNT; | |
13931 | +#if ONSTREAM_DEBUG | |
13932 | + printk(KERN_INFO "ide-tape: MOD_DEC_USE_COUNT in idetape_init\n"); | |
13933 | +#endif | |
13934 | + return 0; | |
13935 | + } | |
13936 | + if (!idetape_chrdev_present && | |
13937 | + devfs_register_chrdev (IDETAPE_MAJOR, "ht", &idetape_fops)) { | |
13938 | + printk (KERN_ERR "ide-tape: Failed to register character device interface\n"); | |
13939 | + MOD_DEC_USE_COUNT; | |
13940 | +#if ONSTREAM_DEBUG | |
13941 | + printk(KERN_INFO "ide-tape: MOD_DEC_USE_COUNT in idetape_init\n"); | |
13942 | +#endif | |
13943 | + return -EBUSY; | |
13944 | + } | |
13945 | + do { | |
13946 | + if (!idetape_identify_device (drive, drive->id)) { | |
13947 | + printk (KERN_ERR "ide-tape: %s: not supported by this version of ide-tape\n", drive->name); | |
13948 | + continue; | |
13949 | + } | |
13950 | + if (drive->scsi) { | |
13951 | + if (strstr(drive->id->model, "OnStream DI-30")) { | |
13952 | + printk("ide-tape: ide-scsi emulation is not supported for %s.\n", drive->id->model); | |
13953 | + } else { | |
13954 | + printk("ide-tape: passing drive %s to ide-scsi emulation.\n", drive->name); | |
13955 | + continue; | |
13956 | + } | |
13957 | + } | |
13958 | + tape = (idetape_tape_t *) kmalloc (sizeof (idetape_tape_t), GFP_KERNEL); | |
13959 | + if (tape == NULL) { | |
13960 | + printk (KERN_ERR "ide-tape: %s: Can't allocate a tape structure\n", drive->name); | |
13961 | + continue; | |
13962 | + } | |
13963 | + if (ide_register_subdriver (drive, &idetape_driver, IDE_SUBDRIVER_VERSION)) { | |
13964 | + printk (KERN_ERR "ide-tape: %s: Failed to register the driver with ide.c\n", drive->name); | |
13965 | + kfree (tape); | |
13966 | + continue; | |
13967 | + } | |
13968 | + for (minor = 0; idetape_chrdevs[minor].drive != NULL; minor++); | |
13969 | + idetape_setup (drive, tape, minor); | |
13970 | + idetape_chrdevs[minor].drive = drive; | |
13971 | + tape->de_r = | |
13972 | + devfs_register (drive->de, "mt", DEVFS_FL_DEFAULT, | |
13973 | + HWIF(drive)->major, minor, | |
13974 | + S_IFCHR | S_IRUGO | S_IWUGO, | |
13975 | + &idetape_fops, NULL); | |
13976 | + tape->de_n = | |
13977 | + devfs_register (drive->de, "mtn", DEVFS_FL_DEFAULT, | |
13978 | + HWIF(drive)->major, minor + 128, | |
13979 | + S_IFCHR | S_IRUGO | S_IWUGO, | |
13980 | + &idetape_fops, NULL); | |
13981 | + devfs_register_tape (tape->de_r); | |
13982 | + supported++; failed--; | |
13983 | + } while ((drive = ide_scan_devices (ide_tape, idetape_driver.name, NULL, failed++)) != NULL); | |
13984 | + if (!idetape_chrdev_present && !supported) { | |
13985 | + devfs_unregister_chrdev (IDETAPE_MAJOR, "ht"); | |
13986 | + } else | |
13987 | + idetape_chrdev_present = 1; | |
13988 | + ide_register_module (&idetape_module); | |
13989 | + MOD_DEC_USE_COUNT; | |
13990 | +#if ONSTREAM_DEBUG | |
13991 | + printk(KERN_INFO "ide-tape: MOD_DEC_USE_COUNT in idetape_init\n"); | |
13992 | +#endif | |
13993 | + | |
13994 | + return 0; | |
13995 | +#else | |
13996 | + return 1; | |
13997 | +#endif | |
13998 | +} | |
13999 | + | |
14000 | MODULE_DESCRIPTION("ATAPI Streaming TAPE Driver"); | |
14001 | MODULE_LICENSE("GPL"); | |
14002 | ||
14003 | @@ -6205,7 +6373,7 @@ | |
14004 | ide_drive_t *drive; | |
14005 | idetape_tape_t *tape; | |
14006 | int minor, failed = 0, supported = 0; | |
14007 | - | |
14008 | +/* DRIVER(drive)->busy++; */ | |
14009 | MOD_INC_USE_COUNT; | |
14010 | #if ONSTREAM_DEBUG | |
14011 | printk(KERN_INFO "ide-tape: MOD_INC_USE_COUNT in idetape_init\n"); | |
14012 | diff -Nur linux.org/drivers/ide/ide-taskfile.c linux/drivers/ide/ide-taskfile.c | |
14013 | --- linux.org/drivers/ide/ide-taskfile.c Thu Jan 1 01:00:00 1970 | |
14014 | +++ linux/drivers/ide/ide-taskfile.c Thu Jul 18 14:24:33 2002 | |
14015 | @@ -0,0 +1,2826 @@ | |
14016 | +/* | |
14017 | + * linux/drivers/ide/ide-taskfile.c Version 0.33 April 11, 2002 | |
14018 | + * | |
14019 | + * Copyright (C) 2000-2002 Michael Cornwell <cornwell@acm.org> | |
14020 | + * Copyright (C) 2000-2002 Andre Hedrick <andre@linux-ide.org> | |
14021 | + * Copyright (C) 2001-2002 Klaus Smolin | |
14022 | + * IBM Storage Technology Division | |
14023 | + * | |
14024 | + * The big the bad and the ugly. | |
14025 | + * | |
14026 | + * Problems to be fixed because of BH interface or the lack therefore. | |
14027 | + * | |
14028 | + * Fill me in stupid !!! | |
14029 | + * | |
14030 | + * HOST: | |
14031 | + * General refers to the Controller and Driver "pair". | |
14032 | + * DATA HANDLER: | |
14033 | + * Under the context of Linux it generally refers to an interrupt handler. | |
14034 | + * However, it correctly describes the 'HOST' | |
14035 | + * DATA BLOCK: | |
14036 | + * The amount of data needed to be transfered as predefined in the | |
14037 | + * setup of the device. | |
14038 | + * STORAGE ATOMIC: | |
14039 | + * The 'DATA BLOCK' associated to the 'DATA HANDLER', and can be as | |
14040 | + * small as a single sector or as large as the entire command block | |
14041 | + * request. | |
14042 | + */ | |
14043 | + | |
14044 | +#include <linux/config.h> | |
14045 | +#define __NO_VERSION__ | |
14046 | +#include <linux/module.h> | |
14047 | +#include <linux/types.h> | |
14048 | +#include <linux/string.h> | |
14049 | +#include <linux/kernel.h> | |
14050 | +#include <linux/timer.h> | |
14051 | +#include <linux/mm.h> | |
14052 | +#include <linux/interrupt.h> | |
14053 | +#include <linux/major.h> | |
14054 | +#include <linux/errno.h> | |
14055 | +#include <linux/genhd.h> | |
14056 | +#include <linux/blkpg.h> | |
14057 | +#include <linux/slab.h> | |
14058 | +#include <linux/pci.h> | |
14059 | +#include <linux/delay.h> | |
14060 | +#include <linux/hdreg.h> | |
14061 | +#include <linux/ide.h> | |
14062 | + | |
14063 | +#include <asm/byteorder.h> | |
14064 | +#include <asm/irq.h> | |
14065 | +#include <asm/uaccess.h> | |
14066 | +#include <asm/io.h> | |
14067 | +#include <asm/bitops.h> | |
14068 | + | |
14069 | +#define DEBUG_TASKFILE 0 /* unset when fixed */ | |
14070 | + | |
14071 | +#if DEBUG_TASKFILE | |
14072 | +#define DTF(x...) printk(x) | |
14073 | +#else | |
14074 | +#define DTF(x...) | |
14075 | +#endif | |
14076 | + | |
14077 | +/* | |
14078 | + * | |
14079 | + */ | |
14080 | +#define task_rq_offset(rq) \ | |
14081 | + (((rq)->nr_sectors - (rq)->current_nr_sectors) * SECTOR_SIZE) | |
14082 | + | |
14083 | +/* | |
14084 | + * for now, taskfile requests are special :/ | |
14085 | + * | |
14086 | + * However, upon the creation of the atapi version of packet_command | |
14087 | + * data-phase ISR plus it own diagnostics and extensions for direct access | |
14088 | + * (ioctl,read,write,rip,stream -- atapi), the kmap/kunmap for PIO will | |
14089 | + * come localized. | |
14090 | + */ | |
14091 | +inline char *task_map_rq (struct request *rq, unsigned long *flags) | |
14092 | +{ | |
14093 | + if (rq->bh) | |
14094 | + return ide_map_buffer(rq, flags); | |
14095 | + return rq->buffer + task_rq_offset(rq); | |
14096 | +} | |
14097 | + | |
14098 | +inline void task_unmap_rq (struct request *rq, char *buf, unsigned long *flags) | |
14099 | +{ | |
14100 | + if (rq->bh) | |
14101 | + ide_unmap_buffer(buf, flags); | |
14102 | +} | |
14103 | + | |
14104 | +inline u32 task_read_24 (ide_drive_t *drive) | |
14105 | +{ | |
14106 | + return (IN_BYTE(IDE_HCYL_REG)<<16) | | |
14107 | + (IN_BYTE(IDE_LCYL_REG)<<8) | | |
14108 | + IN_BYTE(IDE_SECTOR_REG); | |
14109 | +} | |
14110 | + | |
14111 | +static void ata_bswap_data (void *buffer, int wcount) | |
14112 | +{ | |
14113 | + u16 *p = buffer; | |
14114 | + | |
14115 | + while (wcount--) { | |
14116 | + *p = *p << 8 | *p >> 8; p++; | |
14117 | + *p = *p << 8 | *p >> 8; p++; | |
14118 | + } | |
14119 | +} | |
14120 | + | |
14121 | +#if SUPPORT_VLB_SYNC | |
14122 | +/* | |
14123 | + * Some localbus EIDE interfaces require a special access sequence | |
14124 | + * when using 32-bit I/O instructions to transfer data. We call this | |
14125 | + * the "vlb_sync" sequence, which consists of three successive reads | |
14126 | + * of the sector count register location, with interrupts disabled | |
14127 | + * to ensure that the reads all happen together. | |
14128 | + */ | |
14129 | +static inline void task_vlb_sync (ide_ioreg_t port) | |
14130 | +{ | |
14131 | + (void) IN_BYTE (port); | |
14132 | + (void) IN_BYTE (port); | |
14133 | + (void) IN_BYTE (port); | |
14134 | +} | |
14135 | +#endif /* SUPPORT_VLB_SYNC */ | |
14136 | + | |
14137 | +/* | |
14138 | + * This is used for most PIO data transfers *from* the IDE interface | |
14139 | + */ | |
14140 | +void ata_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount) | |
14141 | +{ | |
14142 | + byte io_32bit; | |
14143 | + | |
14144 | + /* | |
14145 | + * first check if this controller has defined a special function | |
14146 | + * for handling polled ide transfers | |
14147 | + */ | |
14148 | + | |
14149 | + if (HWIF(drive)->ideproc) { | |
14150 | + HWIF(drive)->ideproc(ideproc_ide_input_data, drive, buffer, wcount); | |
14151 | + return; | |
14152 | + } | |
14153 | + | |
14154 | + io_32bit = drive->io_32bit; | |
14155 | + | |
14156 | + if (io_32bit) { | |
14157 | +#if SUPPORT_VLB_SYNC | |
14158 | + if (io_32bit & 2) { | |
14159 | + unsigned long flags; | |
14160 | + local_irq_save(flags); | |
14161 | + task_vlb_sync(IDE_NSECTOR_REG); | |
14162 | + insl(IDE_DATA_REG, buffer, wcount); | |
14163 | + local_irq_restore(flags); | |
14164 | + } else | |
14165 | +#endif /* SUPPORT_VLB_SYNC */ | |
14166 | + insl(IDE_DATA_REG, buffer, wcount); | |
14167 | + } else { | |
14168 | +#if SUPPORT_SLOW_DATA_PORTS | |
14169 | + if (drive->slow) { | |
14170 | + unsigned short *ptr = (unsigned short *) buffer; | |
14171 | + while (wcount--) { | |
14172 | + *ptr++ = inw_p(IDE_DATA_REG); | |
14173 | + *ptr++ = inw_p(IDE_DATA_REG); | |
14174 | + } | |
14175 | + } else | |
14176 | +#endif /* SUPPORT_SLOW_DATA_PORTS */ | |
14177 | + insw(IDE_DATA_REG, buffer, wcount<<1); | |
14178 | + } | |
14179 | +} | |
14180 | + | |
14181 | +/* | |
14182 | + * This is used for most PIO data transfers *to* the IDE interface | |
14183 | + */ | |
14184 | +void ata_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount) | |
14185 | +{ | |
14186 | + byte io_32bit; | |
14187 | + | |
14188 | + if (HWIF(drive)->ideproc) { | |
14189 | + HWIF(drive)->ideproc(ideproc_ide_output_data, drive, buffer, wcount); | |
14190 | + return; | |
14191 | + } | |
14192 | + | |
14193 | + io_32bit = drive->io_32bit; | |
14194 | + | |
14195 | + if (io_32bit) { | |
14196 | +#if SUPPORT_VLB_SYNC | |
14197 | + if (io_32bit & 2) { | |
14198 | + unsigned long flags; | |
14199 | + local_irq_save(flags); | |
14200 | + task_vlb_sync(IDE_NSECTOR_REG); | |
14201 | + outsl(IDE_DATA_REG, buffer, wcount); | |
14202 | + local_irq_restore(flags); | |
14203 | + } else | |
14204 | +#endif /* SUPPORT_VLB_SYNC */ | |
14205 | + outsl(IDE_DATA_REG, buffer, wcount); | |
14206 | + } else { | |
14207 | +#if SUPPORT_SLOW_DATA_PORTS | |
14208 | + if (drive->slow) { | |
14209 | + unsigned short *ptr = (unsigned short *) buffer; | |
14210 | + while (wcount--) { | |
14211 | + outw_p(*ptr++, IDE_DATA_REG); | |
14212 | + outw_p(*ptr++, IDE_DATA_REG); | |
14213 | + } | |
14214 | + } else | |
14215 | +#endif /* SUPPORT_SLOW_DATA_PORTS */ | |
14216 | + outsw(IDE_DATA_REG, buffer, wcount<<1); | |
14217 | + } | |
14218 | +} | |
14219 | + | |
14220 | +/* | |
14221 | + * The following routines are mainly used by the ATAPI drivers. | |
14222 | + * | |
14223 | + * These routines will round up any request for an odd number of bytes, | |
14224 | + * so if an odd bytecount is specified, be sure that there's at least one | |
14225 | + * extra byte allocated for the buffer. | |
14226 | + */ | |
14227 | +void atapi_input_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount) | |
14228 | +{ | |
14229 | + if (HWIF(drive)->ideproc) { | |
14230 | + HWIF(drive)->ideproc(ideproc_atapi_input_bytes, drive, buffer, bytecount); | |
14231 | + return; | |
14232 | + } | |
14233 | + | |
14234 | + ++bytecount; | |
14235 | +#if defined(CONFIG_ATARI) || defined(CONFIG_Q40) | |
14236 | + if (MACH_IS_ATARI || MACH_IS_Q40) { | |
14237 | + /* Atari has a byte-swapped IDE interface */ | |
14238 | + insw_swapw(IDE_DATA_REG, buffer, bytecount / 2); | |
14239 | + return; | |
14240 | + } | |
14241 | +#endif /* CONFIG_ATARI */ | |
14242 | + ata_input_data (drive, buffer, bytecount / 4); | |
14243 | + if ((bytecount & 0x03) >= 2) | |
14244 | + insw (IDE_DATA_REG, ((byte *)buffer) + (bytecount & ~0x03), 1); | |
14245 | +} | |
14246 | + | |
14247 | +void atapi_output_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount) | |
14248 | +{ | |
14249 | + if (HWIF(drive)->ideproc) { | |
14250 | + HWIF(drive)->ideproc(ideproc_atapi_output_bytes, drive, buffer, bytecount); | |
14251 | + return; | |
14252 | + } | |
14253 | + | |
14254 | + ++bytecount; | |
14255 | +#if defined(CONFIG_ATARI) || defined(CONFIG_Q40) | |
14256 | + if (MACH_IS_ATARI || MACH_IS_Q40) { | |
14257 | + /* Atari has a byte-swapped IDE interface */ | |
14258 | + outsw_swapw(IDE_DATA_REG, buffer, bytecount / 2); | |
14259 | + return; | |
14260 | + } | |
14261 | +#endif /* CONFIG_ATARI */ | |
14262 | + ata_output_data (drive, buffer, bytecount / 4); | |
14263 | + if ((bytecount & 0x03) >= 2) | |
14264 | + outsw (IDE_DATA_REG, ((byte *)buffer) + (bytecount & ~0x03), 1); | |
14265 | +} | |
14266 | + | |
14267 | +void taskfile_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount) | |
14268 | +{ | |
14269 | + ata_input_data(drive, buffer, wcount); | |
14270 | + if (drive->bswap) | |
14271 | + ata_bswap_data(buffer, wcount); | |
14272 | +} | |
14273 | + | |
14274 | +void taskfile_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount) | |
14275 | +{ | |
14276 | + if (drive->bswap) { | |
14277 | + ata_bswap_data(buffer, wcount); | |
14278 | + ata_output_data(drive, buffer, wcount); | |
14279 | + ata_bswap_data(buffer, wcount); | |
14280 | + } else { | |
14281 | + ata_output_data(drive, buffer, wcount); | |
14282 | + } | |
14283 | +} | |
14284 | + | |
14285 | +/* | |
14286 | + * Needed for PCI irq sharing | |
14287 | + */ | |
14288 | +int drive_is_ready (ide_drive_t *drive) | |
14289 | +{ | |
14290 | + byte stat = 0; | |
14291 | + if (drive->waiting_for_dma) | |
14292 | + return HWIF(drive)->dmaproc(ide_dma_test_irq, drive); | |
14293 | +#if 0 | |
14294 | + /* need to guarantee 400ns since last command was issued */ | |
14295 | + udelay(1); | |
14296 | +#endif | |
14297 | + | |
14298 | +#ifdef CONFIG_IDEPCI_SHARE_IRQ | |
14299 | + /* | |
14300 | + * We do a passive status test under shared PCI interrupts on | |
14301 | + * cards that truly share the ATA side interrupt, but may also share | |
14302 | + * an interrupt with another pci card/device. We make no assumptions | |
14303 | + * about possible isa-pnp and pci-pnp issues yet. | |
14304 | + */ | |
14305 | + if (IDE_CONTROL_REG) | |
14306 | + stat = GET_ALTSTAT(); | |
14307 | + else | |
14308 | +#endif /* CONFIG_IDEPCI_SHARE_IRQ */ | |
14309 | + stat = GET_STAT(); /* Note: this may clear a pending IRQ!! */ | |
14310 | + | |
14311 | + if (stat & BUSY_STAT) | |
14312 | + return 0; /* drive busy: definitely not interrupting */ | |
14313 | + return 1; /* drive ready: *might* be interrupting */ | |
14314 | +} | |
14315 | + | |
14316 | +/* | |
14317 | + * Global for All, and taken from ide-pmac.c | |
14318 | + */ | |
14319 | +int wait_for_ready (ide_drive_t *drive, int timeout) | |
14320 | +{ | |
14321 | + byte stat = 0; | |
14322 | + | |
14323 | + while(--timeout) { | |
14324 | + stat = GET_STAT(); | |
14325 | + if(!(stat & BUSY_STAT)) { | |
14326 | + if (drive->ready_stat == 0) | |
14327 | + break; | |
14328 | + else if((stat & drive->ready_stat) || (stat & ERR_STAT)) | |
14329 | + break; | |
14330 | + } | |
14331 | + mdelay(1); | |
14332 | + } | |
14333 | + if((stat & ERR_STAT) || timeout <= 0) { | |
14334 | + if (stat & ERR_STAT) { | |
14335 | + printk(KERN_ERR "%s: wait_for_ready, error status: %x\n", drive->name, stat); | |
14336 | + } | |
14337 | + return 1; | |
14338 | + } | |
14339 | + return 0; | |
14340 | +} | |
14341 | + | |
14342 | +/* | |
14343 | + * This routine busy-waits for the drive status to be not "busy". | |
14344 | + * It then checks the status for all of the "good" bits and none | |
14345 | + * of the "bad" bits, and if all is okay it returns 0. All other | |
14346 | + * cases return 1 after invoking ide_error() -- caller should just return. | |
14347 | + * | |
14348 | + * This routine should get fixed to not hog the cpu during extra long waits.. | |
14349 | + * That could be done by busy-waiting for the first jiffy or two, and then | |
14350 | + * setting a timer to wake up at half second intervals thereafter, | |
14351 | + * until timeout is achieved, before timing out. | |
14352 | + */ | |
14353 | +int ide_wait_stat (ide_startstop_t *startstop, ide_drive_t *drive, byte good, byte bad, unsigned long timeout) | |
14354 | +{ | |
14355 | + byte stat; | |
14356 | + int i; | |
14357 | + unsigned long flags; | |
14358 | + | |
14359 | + /* bail early if we've exceeded max_failures */ | |
14360 | + if (drive->max_failures && (drive->failures > drive->max_failures)) { | |
14361 | + *startstop = ide_stopped; | |
14362 | + return 1; | |
14363 | + } | |
14364 | + | |
14365 | + udelay(1); /* spec allows drive 400ns to assert "BUSY" */ | |
14366 | + if ((stat = GET_STAT()) & BUSY_STAT) { | |
14367 | + local_irq_set(flags); | |
14368 | + timeout += jiffies; | |
14369 | + while ((stat = GET_STAT()) & BUSY_STAT) { | |
14370 | + if (time_after(jiffies, timeout)) { | |
14371 | + local_irq_restore(flags); | |
14372 | + *startstop = DRIVER(drive)->error(drive, "status timeout", stat); | |
14373 | + return 1; | |
14374 | + } | |
14375 | + } | |
14376 | + local_irq_restore(flags); | |
14377 | + } | |
14378 | + /* | |
14379 | + * Allow status to settle, then read it again. | |
14380 | + * A few rare drives vastly violate the 400ns spec here, | |
14381 | + * so we'll wait up to 10usec for a "good" status | |
14382 | + * rather than expensively fail things immediately. | |
14383 | + * This fix courtesy of Matthew Faupel & Niccolo Rigacci. | |
14384 | + */ | |
14385 | + for (i = 0; i < 10; i++) { | |
14386 | + udelay(1); | |
14387 | + if (OK_STAT((stat = GET_STAT()), good, bad)) | |
14388 | + return 0; | |
14389 | + } | |
14390 | + *startstop = DRIVER(drive)->error(drive, "status error", stat); | |
14391 | + return 1; | |
14392 | +} | |
14393 | + | |
14394 | +void debug_taskfile (ide_drive_t *drive, ide_task_t *args) | |
14395 | +{ | |
14396 | +#ifdef CONFIG_IDE_TASK_IOCTL_DEBUG | |
14397 | + printk(KERN_INFO "%s: ", drive->name); | |
14398 | +// printk("TF.0=x%02x ", args->tfRegister[IDE_DATA_OFFSET]); | |
14399 | + printk("TF.1=x%02x ", args->tfRegister[IDE_FEATURE_OFFSET]); | |
14400 | + printk("TF.2=x%02x ", args->tfRegister[IDE_NSECTOR_OFFSET]); | |
14401 | + printk("TF.3=x%02x ", args->tfRegister[IDE_SECTOR_OFFSET]); | |
14402 | + printk("TF.4=x%02x ", args->tfRegister[IDE_LCYL_OFFSET]); | |
14403 | + printk("TF.5=x%02x ", args->tfRegister[IDE_HCYL_OFFSET]); | |
14404 | + printk("TF.6=x%02x ", args->tfRegister[IDE_SELECT_OFFSET]); | |
14405 | + printk("TF.7=x%02x\n", args->tfRegister[IDE_COMMAND_OFFSET]); | |
14406 | + printk(KERN_INFO "%s: ", drive->name); | |
14407 | +// printk("HTF.0=x%02x ", args->hobRegister[IDE_DATA_OFFSET_HOB]); | |
14408 | + printk("HTF.1=x%02x ", args->hobRegister[IDE_FEATURE_OFFSET_HOB]); | |
14409 | + printk("HTF.2=x%02x ", args->hobRegister[IDE_NSECTOR_OFFSET_HOB]); | |
14410 | + printk("HTF.3=x%02x ", args->hobRegister[IDE_SECTOR_OFFSET_HOB]); | |
14411 | + printk("HTF.4=x%02x ", args->hobRegister[IDE_LCYL_OFFSET_HOB]); | |
14412 | + printk("HTF.5=x%02x ", args->hobRegister[IDE_HCYL_OFFSET_HOB]); | |
14413 | + printk("HTF.6=x%02x ", args->hobRegister[IDE_SELECT_OFFSET_HOB]); | |
14414 | + printk("HTF.7=x%02x\n", args->hobRegister[IDE_CONTROL_OFFSET_HOB]); | |
14415 | +#endif /* CONFIG_IDE_TASK_IOCTL_DEBUG */ | |
14416 | +} | |
14417 | + | |
14418 | +ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task) | |
14419 | +{ | |
14420 | + task_struct_t *taskfile = (task_struct_t *) task->tfRegister; | |
14421 | + hob_struct_t *hobfile = (hob_struct_t *) task->hobRegister; | |
14422 | + struct hd_driveid *id = drive->id; | |
14423 | + byte HIHI = (drive->addressing == 1) ? 0xE0 : 0xEF; | |
14424 | + | |
14425 | +#ifdef CONFIG_IDE_TASK_IOCTL_DEBUG | |
14426 | + void debug_taskfile(drive, task); | |
14427 | +#endif /* CONFIG_IDE_TASK_IOCTL_DEBUG */ | |
14428 | + | |
14429 | + /* ALL Command Block Executions SHALL clear nIEN, unless otherwise */ | |
14430 | + if (IDE_CONTROL_REG) | |
14431 | + OUT_BYTE(drive->ctl, IDE_CONTROL_REG); /* clear nIEN */ | |
14432 | + SELECT_MASK(HWIF(drive), drive, 0); | |
14433 | + | |
14434 | + if ((id->command_set_2 & 0x0400) && | |
14435 | + (id->cfs_enable_2 & 0x0400) && | |
14436 | + (drive->addressing == 1)) { | |
14437 | + OUT_BYTE(hobfile->feature, IDE_FEATURE_REG); | |
14438 | + OUT_BYTE(hobfile->sector_count, IDE_NSECTOR_REG); | |
14439 | + OUT_BYTE(hobfile->sector_number, IDE_SECTOR_REG); | |
14440 | + OUT_BYTE(hobfile->low_cylinder, IDE_LCYL_REG); | |
14441 | + OUT_BYTE(hobfile->high_cylinder, IDE_HCYL_REG); | |
14442 | + } | |
14443 | + | |
14444 | + OUT_BYTE(taskfile->feature, IDE_FEATURE_REG); | |
14445 | + OUT_BYTE(taskfile->sector_count, IDE_NSECTOR_REG); | |
14446 | + /* refers to number of sectors to transfer */ | |
14447 | + OUT_BYTE(taskfile->sector_number, IDE_SECTOR_REG); | |
14448 | + /* refers to sector offset or start sector */ | |
14449 | + OUT_BYTE(taskfile->low_cylinder, IDE_LCYL_REG); | |
14450 | + OUT_BYTE(taskfile->high_cylinder, IDE_HCYL_REG); | |
14451 | + | |
14452 | + OUT_BYTE((taskfile->device_head & HIHI) | drive->select.all, IDE_SELECT_REG); | |
14453 | + if (task->handler != NULL) { | |
14454 | + ide_set_handler (drive, task->handler, WAIT_CMD, NULL); | |
14455 | + OUT_BYTE(taskfile->command, IDE_COMMAND_REG); | |
14456 | + if (task->prehandler != NULL) | |
14457 | + return task->prehandler(drive, task->rq); | |
14458 | + return ide_started; | |
14459 | + } | |
14460 | +#if 0 | |
14461 | + switch(task->data_phase) { | |
14462 | +#ifdef CONFIG_BLK_DEV_IDEDMA | |
14463 | + case TASKFILE_OUT_DMAQ: | |
14464 | + case TASKFILE_OUT_DMA: | |
14465 | + HWIF(drive)->dmaproc(ide_dma_write, drive); | |
14466 | + break; | |
14467 | + case TASKFILE_IN_DMAQ: | |
14468 | + case TASKFILE_IN_DMA: | |
14469 | + HWIF(drive)->dmaproc(ide_dma_read, drive); | |
14470 | + break; | |
14471 | +#endif /* CONFIG_BLK_DEV_IDEDMA */ | |
14472 | + default: | |
14473 | + if (task->handler == NULL) | |
14474 | + return ide_stopped; | |
14475 | + ide_set_handler (drive, task->handler, WAIT_WORSTCASE, NULL); | |
14476 | + /* Issue the command */ | |
14477 | + OUT_BYTE(taskfile->command, IDE_COMMAND_REG); | |
14478 | + if (task->prehandler != NULL) | |
14479 | + return task->prehandler(drive, HWGROUP(drive)->rq); | |
14480 | + } | |
14481 | +#else | |
14482 | + // if ((rq->cmd == WRITE) && (drive->using_dma)) | |
14483 | + /* for dma commands we down set the handler */ | |
14484 | + if (drive->using_dma && !(HWIF(drive)->dmaproc(((taskfile->command == WIN_WRITEDMA) || (taskfile->command == WIN_WRITEDMA_EXT)) ? ide_dma_write : ide_dma_read, drive))); | |
14485 | +#endif | |
14486 | + return ide_started; | |
14487 | +} | |
14488 | + | |
14489 | +#if 0 | |
14490 | +/* | |
14491 | + * Error reporting, in human readable form (luxurious, but a memory hog). | |
14492 | + */ | |
14493 | +byte taskfile_dump_status (ide_drive_t *drive, const char *msg, byte stat) | |
14494 | +{ | |
14495 | + unsigned long flags; | |
14496 | + byte err = 0; | |
14497 | + | |
14498 | + local_irq_set(flags); | |
14499 | + printk("%s: %s: status=0x%02x", drive->name, msg, stat); | |
14500 | +#if FANCY_STATUS_DUMPS | |
14501 | + printk(" { "); | |
14502 | + if (stat & BUSY_STAT) | |
14503 | + printk("Busy "); | |
14504 | + else { | |
14505 | + if (stat & READY_STAT) printk("DriveReady "); | |
14506 | + if (stat & WRERR_STAT) printk("DeviceFault "); | |
14507 | + if (stat & SEEK_STAT) printk("SeekComplete "); | |
14508 | + if (stat & DRQ_STAT) printk("DataRequest "); | |
14509 | + if (stat & ECC_STAT) printk("CorrectedError "); | |
14510 | + if (stat & INDEX_STAT) printk("Index "); | |
14511 | + if (stat & ERR_STAT) printk("Error "); | |
14512 | + } | |
14513 | + printk("}"); | |
14514 | +#endif /* FANCY_STATUS_DUMPS */ | |
14515 | + printk("\n"); | |
14516 | + if ((stat & (BUSY_STAT|ERR_STAT)) == ERR_STAT) { | |
14517 | + err = GET_ERR(); | |
14518 | + printk("%s: %s: error=0x%02x", drive->name, msg, err); | |
14519 | +#if FANCY_STATUS_DUMPS | |
14520 | + if (drive->media == ide_disk) { | |
14521 | + printk(" { "); | |
14522 | + if (err & ABRT_ERR) printk("DriveStatusError "); | |
14523 | + if (err & ICRC_ERR) printk("%s", (err & ABRT_ERR) ? "BadCRC " : "BadSector "); | |
14524 | + if (err & ECC_ERR) printk("UncorrectableError "); | |
14525 | + if (err & ID_ERR) printk("SectorIdNotFound "); | |
14526 | + if (err & TRK0_ERR) printk("TrackZeroNotFound "); | |
14527 | + if (err & MARK_ERR) printk("AddrMarkNotFound "); | |
14528 | + printk("}"); | |
14529 | + if ((err & (BBD_ERR | ABRT_ERR)) == BBD_ERR || (err & (ECC_ERR|ID_ERR|MARK_ERR))) { | |
14530 | + if ((drive->id->command_set_2 & 0x0400) && | |
14531 | + (drive->id->cfs_enable_2 & 0x0400) && | |
14532 | + (drive->addressing == 1)) { | |
14533 | + __u64 sectors = 0; | |
14534 | + u32 low = 0, high = 0; | |
14535 | + low = task_read_24(drive); | |
14536 | + OUT_BYTE(0x80, IDE_CONTROL_REG); | |
14537 | + high = task_read_24(drive); | |
14538 | + sectors = ((__u64)high << 24) | low; | |
14539 | + printk(", LBAsect=%lld", sectors); | |
14540 | + } else { | |
14541 | + byte cur = IN_BYTE(IDE_SELECT_REG); | |
14542 | + if (cur & 0x40) { /* using LBA? */ | |
14543 | + printk(", LBAsect=%ld", (unsigned long) | |
14544 | + ((cur&0xf)<<24) | |
14545 | + |(IN_BYTE(IDE_HCYL_REG)<<16) | |
14546 | + |(IN_BYTE(IDE_LCYL_REG)<<8) | |
14547 | + | IN_BYTE(IDE_SECTOR_REG)); | |
14548 | + } else { | |
14549 | + printk(", CHS=%d/%d/%d", | |
14550 | + (IN_BYTE(IDE_HCYL_REG)<<8) + | |
14551 | + IN_BYTE(IDE_LCYL_REG), | |
14552 | + cur & 0xf, | |
14553 | + IN_BYTE(IDE_SECTOR_REG)); | |
14554 | + } | |
14555 | + } | |
14556 | + if (HWGROUP(drive)->rq) | |
14557 | + printk(", sector=%lu", (__u64) HWGROUP(drive)->rq->sector); | |
14558 | + } | |
14559 | + } | |
14560 | +#endif /* FANCY_STATUS_DUMPS */ | |
14561 | + printk("\n"); | |
14562 | + } | |
14563 | + local_irq_restore(flags); | |
14564 | + return err; | |
14565 | +} | |
14566 | +#endif | |
14567 | + | |
14568 | +/* | |
14569 | + * Clean up after success/failure of an explicit taskfile operation. | |
14570 | + */ | |
14571 | +void ide_end_taskfile (ide_drive_t *drive, byte stat, byte err) | |
14572 | +{ | |
14573 | + unsigned long flags; | |
14574 | + struct request *rq; | |
14575 | + ide_task_t *args; | |
14576 | + task_ioreg_t command; | |
14577 | + | |
14578 | + spin_lock_irqsave(&io_request_lock, flags); | |
14579 | + rq = HWGROUP(drive)->rq; | |
14580 | + spin_unlock_irqrestore(&io_request_lock, flags); | |
14581 | + args = (ide_task_t *) rq->special; | |
14582 | + | |
14583 | + command = args->tfRegister[IDE_COMMAND_OFFSET]; | |
14584 | + | |
14585 | + if (rq->errors == 0) | |
14586 | + rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT); | |
14587 | + | |
14588 | + if (args->tf_in_flags.b.data) { | |
14589 | + unsigned short data = IN_WORD(IDE_DATA_REG); | |
14590 | + args->tfRegister[IDE_DATA_OFFSET] = (data) & 0xFF; | |
14591 | + args->hobRegister[IDE_DATA_OFFSET_HOB] = (data >> 8) & 0xFF; | |
14592 | + } | |
14593 | + args->tfRegister[IDE_ERROR_OFFSET] = err; | |
14594 | + args->tfRegister[IDE_NSECTOR_OFFSET] = IN_BYTE(IDE_NSECTOR_REG); | |
14595 | + args->tfRegister[IDE_SECTOR_OFFSET] = IN_BYTE(IDE_SECTOR_REG); | |
14596 | + args->tfRegister[IDE_LCYL_OFFSET] = IN_BYTE(IDE_LCYL_REG); | |
14597 | + args->tfRegister[IDE_HCYL_OFFSET] = IN_BYTE(IDE_HCYL_REG); | |
14598 | + args->tfRegister[IDE_SELECT_OFFSET] = IN_BYTE(IDE_SELECT_REG); | |
14599 | + args->tfRegister[IDE_STATUS_OFFSET] = stat; | |
14600 | + if ((drive->id->command_set_2 & 0x0400) && | |
14601 | + (drive->id->cfs_enable_2 & 0x0400) && | |
14602 | + (drive->addressing == 1)) { | |
14603 | + OUT_BYTE(drive->ctl|0x80, IDE_CONTROL_REG_HOB); | |
14604 | + args->hobRegister[IDE_FEATURE_OFFSET_HOB] = IN_BYTE(IDE_FEATURE_REG); | |
14605 | + args->hobRegister[IDE_NSECTOR_OFFSET_HOB] = IN_BYTE(IDE_NSECTOR_REG); | |
14606 | + args->hobRegister[IDE_SECTOR_OFFSET_HOB] = IN_BYTE(IDE_SECTOR_REG); | |
14607 | + args->hobRegister[IDE_LCYL_OFFSET_HOB] = IN_BYTE(IDE_LCYL_REG); | |
14608 | + args->hobRegister[IDE_HCYL_OFFSET_HOB] = IN_BYTE(IDE_HCYL_REG); | |
14609 | + } | |
14610 | + | |
14611 | +#if 0 | |
14612 | +/* taskfile_settings_update(drive, args, command); */ | |
14613 | + | |
14614 | + if (args->posthandler != NULL) | |
14615 | + args->posthandler(drive, args); | |
14616 | +#endif | |
14617 | + | |
14618 | + spin_lock_irqsave(&io_request_lock, flags); | |
14619 | + blkdev_dequeue_request(rq); | |
14620 | + HWGROUP(drive)->rq = NULL; | |
14621 | + end_that_request_last(rq); | |
14622 | + spin_unlock_irqrestore(&io_request_lock, flags); | |
14623 | +} | |
14624 | + | |
14625 | +#if 0 | |
14626 | +/* | |
14627 | + * try_to_flush_leftover_data() is invoked in response to a drive | |
14628 | + * unexpectedly having its DRQ_STAT bit set. As an alternative to | |
14629 | + * resetting the drive, this routine tries to clear the condition | |
14630 | + * by read a sector's worth of data from the drive. Of course, | |
14631 | + * this may not help if the drive is *waiting* for data from *us*. | |
14632 | + */ | |
14633 | +void task_try_to_flush_leftover_data (ide_drive_t *drive) | |
14634 | +{ | |
14635 | + int i = (drive->mult_count ? drive->mult_count : 1) * SECTOR_WORDS; | |
14636 | + | |
14637 | + if (drive->media != ide_disk) | |
14638 | + return; | |
14639 | + while (i > 0) { | |
14640 | + u32 buffer[16]; | |
14641 | + unsigned int wcount = (i > 16) ? 16 : i; | |
14642 | + i -= wcount; | |
14643 | + taskfile_input_data (drive, buffer, wcount); | |
14644 | + } | |
14645 | +} | |
14646 | + | |
14647 | +/* | |
14648 | + * taskfile_error() takes action based on the error returned by the drive. | |
14649 | + */ | |
14650 | +ide_startstop_t taskfile_error (ide_drive_t *drive, const char *msg, byte stat) | |
14651 | +{ | |
14652 | + struct request *rq; | |
14653 | + byte err; | |
14654 | + | |
14655 | + err = taskfile_dump_status(drive, msg, stat); | |
14656 | + if (drive == NULL || (rq = HWGROUP(drive)->rq) == NULL) | |
14657 | + return ide_stopped; | |
14658 | + /* retry only "normal" I/O: */ | |
14659 | + if (rq->cmd == IDE_DRIVE_TASKFILE) { | |
14660 | + rq->errors = 1; | |
14661 | + ide_end_taskfile(drive, stat, err); | |
14662 | + return ide_stopped; | |
14663 | + } | |
14664 | + if (stat & BUSY_STAT || ((stat & WRERR_STAT) && !drive->nowerr)) { /* other bits are useless when BUSY */ | |
14665 | + rq->errors |= ERROR_RESET; | |
14666 | + } else { | |
14667 | + if (drive->media == ide_disk && (stat & ERR_STAT)) { | |
14668 | + /* err has different meaning on cdrom and tape */ | |
14669 | + if (err == ABRT_ERR) { | |
14670 | + if (drive->select.b.lba && IN_BYTE(IDE_COMMAND_REG) == WIN_SPECIFY) | |
14671 | + return ide_stopped; /* some newer drives don't support WIN_SPECIFY */ | |
14672 | + } else if ((err & (ABRT_ERR | ICRC_ERR)) == (ABRT_ERR | ICRC_ERR)) { | |
14673 | + drive->crc_count++; /* UDMA crc error -- just retry the operation */ | |
14674 | + } else if (err & (BBD_ERR | ECC_ERR)) /* retries won't help these */ | |
14675 | + rq->errors = ERROR_MAX; | |
14676 | + else if (err & TRK0_ERR) /* help it find track zero */ | |
14677 | + rq->errors |= ERROR_RECAL; | |
14678 | + } | |
14679 | + if ((stat & DRQ_STAT) && rq->cmd != WRITE) | |
14680 | + task_try_to_flush_leftover_data(drive); | |
14681 | + } | |
14682 | + if (GET_STAT() & (BUSY_STAT|DRQ_STAT)) | |
14683 | + OUT_BYTE(WIN_IDLEIMMEDIATE,IDE_COMMAND_REG); /* force an abort */ | |
14684 | + | |
14685 | + if (rq->errors >= ERROR_MAX) { | |
14686 | + DRIVER(drive)->end_request(drive, 0); | |
14687 | + } else { | |
14688 | + if ((rq->errors & ERROR_RESET) == ERROR_RESET) { | |
14689 | + ++rq->errors; | |
14690 | + return ide_do_reset(drive); | |
14691 | + } | |
14692 | + if ((rq->errors & ERROR_RECAL) == ERROR_RECAL) | |
14693 | + drive->special.b.recalibrate = 1; | |
14694 | + ++rq->errors; | |
14695 | + } | |
14696 | + return ide_stopped; | |
14697 | +} | |
14698 | +#endif | |
14699 | + | |
14700 | +/* | |
14701 | + * Handler for special commands without a data phase from ide-disk | |
14702 | + */ | |
14703 | + | |
14704 | +/* | |
14705 | + * set_multmode_intr() is invoked on completion of a WIN_SETMULT cmd. | |
14706 | + */ | |
14707 | +ide_startstop_t set_multmode_intr (ide_drive_t *drive) | |
14708 | +{ | |
14709 | + byte stat; | |
14710 | + | |
14711 | + if (OK_STAT(stat=GET_STAT(),READY_STAT,BAD_STAT)) { | |
14712 | + drive->mult_count = drive->mult_req; | |
14713 | + } else { | |
14714 | + drive->mult_req = drive->mult_count = 0; | |
14715 | + drive->special.b.recalibrate = 1; | |
14716 | + (void) ide_dump_status(drive, "set_multmode", stat); | |
14717 | + } | |
14718 | + return ide_stopped; | |
14719 | +} | |
14720 | + | |
14721 | +/* | |
14722 | + * set_geometry_intr() is invoked on completion of a WIN_SPECIFY cmd. | |
14723 | + */ | |
14724 | +ide_startstop_t set_geometry_intr (ide_drive_t *drive) | |
14725 | +{ | |
14726 | + byte stat; | |
14727 | + | |
14728 | + if (OK_STAT(stat=GET_STAT(),READY_STAT,BAD_STAT)) | |
14729 | + return ide_stopped; | |
14730 | + | |
14731 | + if (stat & (ERR_STAT|DRQ_STAT)) | |
14732 | + return DRIVER(drive)->error(drive, "set_geometry_intr", stat); | |
14733 | + | |
14734 | + if (HWGROUP(drive)->handler != NULL) /* paranoia check */ | |
14735 | + BUG(); | |
14736 | + ide_set_handler(drive, &set_geometry_intr, WAIT_CMD, NULL); | |
14737 | + return ide_started; | |
14738 | +} | |
14739 | + | |
14740 | +/* | |
14741 | + * recal_intr() is invoked on completion of a WIN_RESTORE (recalibrate) cmd. | |
14742 | + */ | |
14743 | +ide_startstop_t recal_intr (ide_drive_t *drive) | |
14744 | +{ | |
14745 | + byte stat = GET_STAT(); | |
14746 | + | |
14747 | + if (!OK_STAT(stat,READY_STAT,BAD_STAT)) | |
14748 | + return DRIVER(drive)->error(drive, "recal_intr", stat); | |
14749 | + return ide_stopped; | |
14750 | +} | |
14751 | + | |
14752 | +/* | |
14753 | + * Handler for commands without a data phase | |
14754 | + */ | |
14755 | +ide_startstop_t task_no_data_intr (ide_drive_t *drive) | |
14756 | +{ | |
14757 | + ide_task_t *args = HWGROUP(drive)->rq->special; | |
14758 | + byte stat = GET_STAT(); | |
14759 | + | |
14760 | + local_irq_enable(); | |
14761 | + if (!OK_STAT(stat, READY_STAT, BAD_STAT)) { | |
14762 | + DTF("%s: command opcode 0x%02x\n", drive->name, | |
14763 | + args->tfRegister[IDE_COMMAND_OFFSET]); | |
14764 | + return DRIVER(drive)->error(drive, "task_no_data_intr", stat); | |
14765 | + /* calls ide_end_drive_cmd */ | |
14766 | + } | |
14767 | + if (args) | |
14768 | + ide_end_drive_cmd (drive, stat, GET_ERR()); | |
14769 | + | |
14770 | + return ide_stopped; | |
14771 | +} | |
14772 | + | |
14773 | +/* | |
14774 | + * Handler for command with PIO data-in phase, READ | |
14775 | + */ | |
14776 | +/* | |
14777 | + * FIXME before 2.4 enable ... | |
14778 | + * DATA integrity issue upon error. <andre@linux-ide.org> | |
14779 | + */ | |
14780 | +ide_startstop_t task_in_intr (ide_drive_t *drive) | |
14781 | +{ | |
14782 | + byte stat = GET_STAT(); | |
14783 | + struct request *rq = HWGROUP(drive)->rq; | |
14784 | + char *pBuf = NULL; | |
14785 | + unsigned long flags; | |
14786 | + | |
14787 | + if (!OK_STAT(stat,DATA_READY,BAD_R_STAT)) { | |
14788 | + if (stat & (ERR_STAT|DRQ_STAT)) { | |
14789 | +#if 0 | |
14790 | + DTF("%s: attempting to recover last " \ | |
14791 | + "sector counter status=0x%02x\n", | |
14792 | + drive->name, stat); | |
14793 | + /* | |
14794 | + * Expect a BUG BOMB if we attempt to rewind the | |
14795 | + * offset in the BH aka PAGE in the current BLOCK | |
14796 | + * segment. This is different than the HOST segment. | |
14797 | + */ | |
14798 | +#endif | |
14799 | + if (!rq->bh) | |
14800 | + rq->current_nr_sectors++; | |
14801 | + return DRIVER(drive)->error(drive, "task_in_intr", stat); | |
14802 | + } | |
14803 | + if (!(stat & BUSY_STAT)) { | |
14804 | + DTF("task_in_intr to Soon wait for next interrupt\n"); | |
14805 | + if (HWGROUP(drive)->handler == NULL) | |
14806 | + ide_set_handler(drive, &task_in_intr, WAIT_CMD, NULL); | |
14807 | + return ide_started; | |
14808 | + } | |
14809 | + } | |
14810 | +#if 0 | |
14811 | + | |
14812 | + /* | |
14813 | + * Holding point for a brain dump of a thought :-/ | |
14814 | + */ | |
14815 | + | |
14816 | + if (!OK_STAT(stat,DRIVE_READY,drive->bad_wstat)) { | |
14817 | + DTF("%s: READ attempting to recover last " \ | |
14818 | + "sector counter status=0x%02x\n", | |
14819 | + drive->name, stat); | |
14820 | + rq->current_nr_sectors++; | |
14821 | + return DRIVER(drive)->error(drive, "task_in_intr", stat); | |
14822 | + } | |
14823 | + if (!rq->current_nr_sectors) | |
14824 | + if (!DRIVER(drive)->end_request(drive, 1)) | |
14825 | + return ide_stopped; | |
14826 | + | |
14827 | + if (--rq->current_nr_sectors <= 0) | |
14828 | + if (!DRIVER(drive)->end_request(drive, 1)) | |
14829 | + return ide_stopped; | |
14830 | +#endif | |
14831 | + | |
14832 | + pBuf = task_map_rq(rq, &flags); | |
14833 | + DTF("Read: %p, rq->current_nr_sectors: %d, stat: %02x\n", | |
14834 | + pBuf, (int) rq->current_nr_sectors, stat); | |
14835 | + taskfile_input_data(drive, pBuf, SECTOR_WORDS); | |
14836 | + task_unmap_rq(rq, pBuf, &flags); | |
14837 | + /* | |
14838 | + * FIXME :: We really can not legally get a new page/bh | |
14839 | + * regardless, if this is the end of our segment. | |
14840 | + * BH walking or segment can only be updated after we have a good | |
14841 | + * GET_STAT(); return. | |
14842 | + */ | |
14843 | + if (--rq->current_nr_sectors <= 0) | |
14844 | + if (!DRIVER(drive)->end_request(drive, 1)) | |
14845 | + return ide_stopped; | |
14846 | + /* | |
14847 | + * ERM, it is techincally legal to leave/exit here but it makes | |
14848 | + * a mess of the code ... | |
14849 | + */ | |
14850 | + if (HWGROUP(drive)->handler == NULL) | |
14851 | + ide_set_handler(drive, &task_in_intr, WAIT_CMD, NULL); | |
14852 | + return ide_started; | |
14853 | +} | |
14854 | + | |
14855 | +#undef ALTSTAT_SCREW_UP | |
14856 | + | |
14857 | +#ifdef ALTSTAT_SCREW_UP | |
14858 | +/* | |
14859 | + * (ks/hs): Poll Alternate Status Register to ensure | |
14860 | + * that drive is not busy. | |
14861 | + */ | |
14862 | +byte altstat_multi_busy (ide_drive_t *drive, byte stat, const char *msg) | |
14863 | +{ | |
14864 | + int i; | |
14865 | + | |
14866 | + DTF("multi%s: ASR = %x\n", msg, stat); | |
14867 | + if (stat & BUSY_STAT) { | |
14868 | + /* (ks/hs): FIXME: Replace hard-coded 100, error handling? */ | |
14869 | + for (i=0; i<100; i++) { | |
14870 | + stat = GET_ALTSTAT(); | |
14871 | + if ((stat & BUSY_STAT) == 0) | |
14872 | + break; | |
14873 | + } | |
14874 | + } | |
14875 | + /* | |
14876 | + * (ks/hs): Read Status AFTER Alternate Status Register | |
14877 | + */ | |
14878 | + return(GET_STAT()); | |
14879 | +} | |
14880 | + | |
14881 | +/* | |
14882 | + * (ks/hs): Poll Alternate status register to wait for drive | |
14883 | + * to become ready for next transfer | |
14884 | + */ | |
14885 | +byte altstat_multi_poll (ide_drive_t *drive, byte stat, const char *msg) | |
14886 | +{ | |
14887 | + | |
14888 | + /* (ks/hs): FIXME: Error handling, time-out? */ | |
14889 | + while (stat & BUSY_STAT) | |
14890 | + stat = GET_ALTSTAT(); | |
14891 | + DTF("multi%s: nsect=1, ASR = %x\n", msg, stat); | |
14892 | + return(GET_STAT()); /* (ks/hs): Clear pending IRQ */ | |
14893 | +} | |
14894 | +#endif /* ALTSTAT_SCREW_UP */ | |
14895 | + | |
14896 | +/* | |
14897 | + * Handler for command with Read Multiple | |
14898 | + */ | |
14899 | +ide_startstop_t task_mulin_intr (ide_drive_t *drive) | |
14900 | +{ | |
14901 | +#ifdef ALTSTAT_SCREW_UP | |
14902 | + byte stat = altstat_multi_busy(drive, GET_ALTSTAT(), "read"); | |
14903 | +#else | |
14904 | + byte stat = GET_STAT(); | |
14905 | +#endif /* ALTSTAT_SCREW_UP */ | |
14906 | + struct request *rq = HWGROUP(drive)->rq; | |
14907 | + char *pBuf = NULL; | |
14908 | + unsigned int msect = drive->mult_count; | |
14909 | + unsigned int nsect; | |
14910 | + unsigned long flags; | |
14911 | + | |
14912 | + if (!OK_STAT(stat,DATA_READY,BAD_R_STAT)) { | |
14913 | + if (stat & (ERR_STAT|DRQ_STAT)) { | |
14914 | + if (!rq->bh) { | |
14915 | + rq->current_nr_sectors += drive->mult_count; | |
14916 | + /* | |
14917 | + * NOTE: could rewind beyond beginning :-/ | |
14918 | + */ | |
14919 | + } else { | |
14920 | + printk("%s: MULTI-READ assume all data " \ | |
14921 | + "transfered is bad status=0x%02x\n", | |
14922 | + drive->name, stat); | |
14923 | + } | |
14924 | + return DRIVER(drive)->error(drive, "task_mulin_intr", stat); | |
14925 | + } | |
14926 | + /* no data yet, so wait for another interrupt */ | |
14927 | + if (HWGROUP(drive)->handler == NULL) | |
14928 | + ide_set_handler(drive, &task_mulin_intr, WAIT_CMD, NULL); | |
14929 | + return ide_started; | |
14930 | + } | |
14931 | + | |
14932 | +#ifdef ALTSTAT_SCREW_UP | |
14933 | + /* | |
14934 | + * Screw the request we do not support bad data-phase setups! | |
14935 | + * Either read and learn the ATA standard or crash yourself! | |
14936 | + */ | |
14937 | + if (!msect) { | |
14938 | + /* | |
14939 | + * (ks/hs): Drive supports multi-sector transfer, | |
14940 | + * drive->mult_count was not set | |
14941 | + */ | |
14942 | + nsect = 1; | |
14943 | + while (rq->current_nr_sectors) { | |
14944 | + pBuf = task_map_rq(rq, &flags); | |
14945 | + DTF("Multiread: %p, nsect: %d, " \ | |
14946 | + "rq->current_nr_sectors: %ld\n", | |
14947 | + pBuf, nsect, rq->current_nr_sectors); | |
14948 | +// rq->current_nr_sectors -= nsect; | |
14949 | + taskfile_input_data(drive, pBuf, nsect * SECTOR_WORDS); | |
14950 | + task_unmap_rq(rq, pBuf, &flags); | |
14951 | + rq->errors = 0; | |
14952 | + rq->current_nr_sectors -= nsect; | |
14953 | + stat = altstat_multi_poll(drive, GET_ALTSTAT(), "read"); | |
14954 | + } | |
14955 | + DRIVER(drive)->end_request(drive, 1); | |
14956 | + return ide_stopped; | |
14957 | + } | |
14958 | +#endif /* ALTSTAT_SCREW_UP */ | |
14959 | + | |
14960 | + do { | |
14961 | + nsect = rq->current_nr_sectors; | |
14962 | + if (nsect > msect) | |
14963 | + nsect = msect; | |
14964 | + pBuf = task_map_rq(rq, &flags); | |
14965 | + DTF("Multiread: %p, nsect: %d, msect: %d, " \ | |
14966 | + " rq->current_nr_sectors: %d\n", | |
14967 | + pBuf, nsect, msect, rq->current_nr_sectors); | |
14968 | +// rq->current_nr_sectors -= nsect; | |
14969 | +// msect -= nsect; | |
14970 | + taskfile_input_data(drive, pBuf, nsect * SECTOR_WORDS); | |
14971 | + task_unmap_rq(rq, pBuf, &flags); | |
14972 | + rq->errors = 0; | |
14973 | + rq->current_nr_sectors -= nsect; | |
14974 | + msect -= nsect; | |
14975 | + /* | |
14976 | + * FIXME :: We really can not legally get a new page/bh | |
14977 | + * regardless, if this is the end of our segment. | |
14978 | + * BH walking or segment can only be updated after we have a | |
14979 | + * good GET_STAT(); return. | |
14980 | + */ | |
14981 | + if (!rq->current_nr_sectors) { | |
14982 | + if (!DRIVER(drive)->end_request(drive, 1)) | |
14983 | + return ide_stopped; | |
14984 | + } | |
14985 | + } while (msect); | |
14986 | + if (HWGROUP(drive)->handler == NULL) | |
14987 | + ide_set_handler(drive, &task_mulin_intr, WAIT_CMD, NULL); | |
14988 | + return ide_started; | |
14989 | +} | |
14990 | + | |
14991 | +/* | |
14992 | + * VERIFY ME before 2.4 ... unexpected race is possible based on details | |
14993 | + * RMK with 74LS245/373/374 TTL buffer logic because of passthrough. | |
14994 | + */ | |
14995 | +ide_startstop_t pre_task_out_intr (ide_drive_t *drive, struct request *rq) | |
14996 | +{ | |
14997 | + char *pBuf = NULL; | |
14998 | + unsigned long flags; | |
14999 | + ide_startstop_t startstop; | |
15000 | + | |
15001 | + if (ide_wait_stat(&startstop, drive, DATA_READY, | |
15002 | + drive->bad_wstat, WAIT_DRQ)) { | |
15003 | + printk(KERN_ERR "%s: no DRQ after issuing %s\n", | |
15004 | + drive->name, | |
15005 | + drive->addressing ? "WRITE_EXT" : "WRITE"); | |
15006 | + return startstop; | |
15007 | + } | |
15008 | + /* For Write_sectors we need to stuff the first sector */ | |
15009 | + pBuf = task_map_rq(rq, &flags); | |
15010 | +// rq->current_nr_sectors--; | |
15011 | + taskfile_output_data(drive, pBuf, SECTOR_WORDS); | |
15012 | + rq->current_nr_sectors--; | |
15013 | + /* | |
15014 | + * WARNING :: Interrupt could happen instantly :-/ | |
15015 | + */ | |
15016 | + task_unmap_rq(rq, pBuf, &flags); | |
15017 | + return ide_started; | |
15018 | +} | |
15019 | + | |
15020 | +/* | |
15021 | + * Handler for command with PIO data-out phase WRITE | |
15022 | + * | |
15023 | + * WOOHOO this is a CORRECT STATE DIAGRAM NOW, <andre@linux-ide.org> | |
15024 | + */ | |
15025 | +ide_startstop_t task_out_intr (ide_drive_t *drive) | |
15026 | +{ | |
15027 | + byte stat = GET_STAT(); | |
15028 | + struct request *rq = HWGROUP(drive)->rq; | |
15029 | + char *pBuf = NULL; | |
15030 | + unsigned long flags; | |
15031 | + | |
15032 | + if (!OK_STAT(stat,DRIVE_READY,drive->bad_wstat)) { | |
15033 | + DTF("%s: WRITE attempting to recover last " \ | |
15034 | + "sector counter status=0x%02x\n", | |
15035 | + drive->name, stat); | |
15036 | + rq->current_nr_sectors++; | |
15037 | + return DRIVER(drive)->error(drive, "task_out_intr", stat); | |
15038 | + } | |
15039 | + /* | |
15040 | + * Safe to update request for partial completions. | |
15041 | + * We have a good STATUS CHECK!!! | |
15042 | + */ | |
15043 | + if (!rq->current_nr_sectors) | |
15044 | + if (!DRIVER(drive)->end_request(drive, 1)) | |
15045 | + return ide_stopped; | |
15046 | + if ((rq->current_nr_sectors==1) ^ (stat & DRQ_STAT)) { | |
15047 | + rq = HWGROUP(drive)->rq; | |
15048 | + pBuf = task_map_rq(rq, &flags); | |
15049 | + DTF("write: %p, rq->current_nr_sectors: %d\n", | |
15050 | + pBuf, (int) rq->current_nr_sectors); | |
15051 | +// rq->current_nr_sectors--; | |
15052 | + taskfile_output_data(drive, pBuf, SECTOR_WORDS); | |
15053 | + task_unmap_rq(rq, pBuf, &flags); | |
15054 | + rq->errors = 0; | |
15055 | + rq->current_nr_sectors--; | |
15056 | + } | |
15057 | + if (HWGROUP(drive)->handler == NULL) | |
15058 | + ide_set_handler(drive, &task_out_intr, WAIT_CMD, NULL); | |
15059 | + return ide_started; | |
15060 | +} | |
15061 | + | |
15062 | +ide_startstop_t pre_task_mulout_intr (ide_drive_t *drive, struct request *rq) | |
15063 | +{ | |
15064 | + ide_task_t *args = rq->special; | |
15065 | + ide_startstop_t startstop; | |
15066 | + | |
15067 | +#if 0 | |
15068 | + /* | |
15069 | + * assign private copy for multi-write | |
15070 | + */ | |
15071 | + memcpy(&HWGROUP(drive)->wrq, rq, sizeof(struct request)); | |
15072 | +#endif | |
15073 | + | |
15074 | + if (ide_wait_stat(&startstop, drive, DATA_READY, | |
15075 | + drive->bad_wstat, WAIT_DRQ)) { | |
15076 | + printk(KERN_ERR "%s: no DRQ after issuing %s\n", | |
15077 | + drive->name, | |
15078 | + drive->addressing ? "MULTWRITE_EXT" : "MULTWRITE"); | |
15079 | + return startstop; | |
15080 | + } | |
15081 | +#if 0 | |
15082 | + if (wait_for_ready(drive, 100)) | |
15083 | + IDE_DEBUG(__LINE__); //BUG(); | |
15084 | +#else | |
15085 | + if (!(drive_is_ready(drive))) { | |
15086 | + int i; | |
15087 | + for (i=0; i<100; i++) { | |
15088 | + if (drive_is_ready(drive)) | |
15089 | + break; | |
15090 | + } | |
15091 | + } | |
15092 | +#endif | |
15093 | + /* | |
15094 | + * WARNING :: if the drive as not acked good status we may not | |
15095 | + * move the DATA-TRANSFER T-Bar as BSY != 0. <andre@linux-ide.org> | |
15096 | + */ | |
15097 | + return args->handler(drive); | |
15098 | +} | |
15099 | + | |
15100 | +/* | |
15101 | + * FIXME before enabling in 2.4 ... DATA integrity issue upon error. | |
15102 | + */ | |
15103 | +/* | |
15104 | + * Handler for command write multiple | |
15105 | + * Called directly from execute_drive_cmd for the first bunch of sectors, | |
15106 | + * afterwards only by the ISR | |
15107 | + */ | |
15108 | +ide_startstop_t task_mulout_intr (ide_drive_t *drive) | |
15109 | +{ | |
15110 | +#ifdef ALTSTAT_SCREW_UP | |
15111 | + byte stat = altstat_multi_busy(drive, GET_ALTSTAT(), "write"); | |
15112 | +#else | |
15113 | + byte stat = GET_STAT(); | |
15114 | +#endif /* ALTSTAT_SCREW_UP */ | |
15115 | + | |
15116 | + struct request *rq = HWGROUP(drive)->rq; | |
15117 | + char *pBuf = NULL; | |
15118 | + ide_startstop_t startstop = ide_stopped; | |
15119 | + unsigned int msect = drive->mult_count; | |
15120 | + unsigned int nsect; | |
15121 | + unsigned long flags; | |
15122 | + | |
15123 | + /* | |
15124 | + * (ks/hs): Handle last IRQ on multi-sector transfer, | |
15125 | + * occurs after all data was sent in this chunk | |
15126 | + */ | |
15127 | + if (rq->current_nr_sectors == 0) { | |
15128 | + if (stat & (ERR_STAT|DRQ_STAT)) { | |
15129 | + if (!rq->bh) { | |
15130 | + rq->current_nr_sectors += drive->mult_count; | |
15131 | + /* | |
15132 | + * NOTE: could rewind beyond beginning :-/ | |
15133 | + */ | |
15134 | + } else { | |
15135 | + printk("%s: MULTI-WRITE assume all data " \ | |
15136 | + "transfered is bad status=0x%02x\n", | |
15137 | + drive->name, stat); | |
15138 | + } | |
15139 | + return DRIVER(drive)->error(drive, "task_mulout_intr", stat); | |
15140 | + } | |
15141 | + if (!rq->bh) | |
15142 | + DRIVER(drive)->end_request(drive, 1); | |
15143 | + return startstop; | |
15144 | + } | |
15145 | + /* | |
15146 | + * DON'T be lazy code the above and below togather !!! | |
15147 | + */ | |
15148 | + if (!OK_STAT(stat,DATA_READY,BAD_R_STAT)) { | |
15149 | + if (stat & (ERR_STAT|DRQ_STAT)) { | |
15150 | + if (!rq->bh) { | |
15151 | + rq->current_nr_sectors += drive->mult_count; | |
15152 | + /* | |
15153 | + * NOTE: could rewind beyond beginning :-/ | |
15154 | + */ | |
15155 | + } else { | |
15156 | + printk("%s: MULTI-WRITE assume all data " \ | |
15157 | + "transfered is bad status=0x%02x\n", | |
15158 | + drive->name, stat); | |
15159 | + } | |
15160 | + return DRIVER(drive)->error(drive, "task_mulout_intr", stat); | |
15161 | + } | |
15162 | + /* no data yet, so wait for another interrupt */ | |
15163 | + if (HWGROUP(drive)->handler == NULL) | |
15164 | + ide_set_handler(drive, &task_mulout_intr, WAIT_CMD, NULL); | |
15165 | + return ide_started; | |
15166 | + } | |
15167 | + | |
15168 | + if (HWGROUP(drive)->handler != NULL) { | |
15169 | + unsigned long lflags; | |
15170 | + spin_lock_irqsave(&io_request_lock, lflags); | |
15171 | + HWGROUP(drive)->handler = NULL; | |
15172 | + del_timer(&HWGROUP(drive)->timer); | |
15173 | + spin_unlock_irqrestore(&io_request_lock, lflags); | |
15174 | + } | |
15175 | + | |
15176 | +#ifdef ALTSTAT_SCREW_UP | |
15177 | + /* | |
15178 | + * Screw the request we do not support bad data-phase setups! | |
15179 | + * Either read and learn the ATA standard or crash yourself! | |
15180 | + */ | |
15181 | + if (!msect) { | |
15182 | + nsect = 1; | |
15183 | + while (rq->current_nr_sectors) { | |
15184 | + pBuf = task_map_rq(rq, &flags); | |
15185 | + DTF("Multiwrite: %p, nsect: %d, " \ | |
15186 | + "rq->current_nr_sectors: %d\n", | |
15187 | + pBuf, nsect, rq->current_nr_sectors); | |
15188 | +// rq->current_nr_sectors -= nsect; | |
15189 | + taskfile_output_data(drive, pBuf, nsect * SECTOR_WORDS); | |
15190 | + task_unmap_rq(pBuf, &flags); | |
15191 | + rq->errors = 0; | |
15192 | + rq->current_nr_sectors -= nsect; | |
15193 | + stat = altstat_multi_poll(drive, GET_ALTSTAT(), "write"); | |
15194 | + } | |
15195 | + DRIVER(drive)->end_request(drive, 1); | |
15196 | + return ide_stopped; | |
15197 | + } | |
15198 | +#endif /* ALTSTAT_SCREW_UP */ | |
15199 | + | |
15200 | + do { | |
15201 | + nsect = rq->current_nr_sectors; | |
15202 | + if (nsect > msect) | |
15203 | + nsect = msect; | |
15204 | + pBuf = task_map_rq(rq, &flags); | |
15205 | + DTF("Multiwrite: %p, nsect: %d, msect: %d, " \ | |
15206 | + "rq->current_nr_sectors: %ld\n", | |
15207 | + pBuf, nsect, msect, rq->current_nr_sectors); | |
15208 | + msect -= nsect; | |
15209 | +// rq->current_nr_sectors -= nsect; | |
15210 | + taskfile_output_data(drive, pBuf, nsect * SECTOR_WORDS); | |
15211 | + task_unmap_rq(rq, pBuf, &flags); | |
15212 | + rq->current_nr_sectors -= nsect; | |
15213 | + /* | |
15214 | + * FIXME :: We really can not legally get a new page/bh | |
15215 | + * regardless, if this is the end of our segment. | |
15216 | + * BH walking or segment can only be updated after we | |
15217 | + * have a good GET_STAT(); return. | |
15218 | + */ | |
15219 | + if (!rq->current_nr_sectors) { | |
15220 | + if (!DRIVER(drive)->end_request(drive, 1)) | |
15221 | + if (!rq->bh) | |
15222 | + return ide_stopped; | |
15223 | + } | |
15224 | + } while (msect); | |
15225 | + rq->errors = 0; | |
15226 | + if (HWGROUP(drive)->handler == NULL) | |
15227 | + ide_set_handler(drive, &task_mulout_intr, WAIT_CMD, NULL); | |
15228 | + return ide_started; | |
15229 | +} | |
15230 | + | |
15231 | +/* Called by internal to feature out type of command being called */ | |
15232 | +ide_pre_handler_t * ide_pre_handler_parser (struct hd_drive_task_hdr *taskfile, struct hd_drive_hob_hdr *hobfile) | |
15233 | +{ | |
15234 | + switch(taskfile->command) { | |
15235 | + /* IDE_DRIVE_TASK_RAW_WRITE */ | |
15236 | + case CFA_WRITE_MULTI_WO_ERASE: | |
15237 | + // case WIN_WRITE_LONG: | |
15238 | + // case WIN_WRITE_LONG_ONCE: | |
15239 | + case WIN_MULTWRITE: | |
15240 | + case WIN_MULTWRITE_EXT: | |
15241 | + return &pre_task_mulout_intr; | |
15242 | + | |
15243 | + /* IDE_DRIVE_TASK_OUT */ | |
15244 | + case WIN_WRITE: | |
15245 | + // case WIN_WRITE_ONCE: | |
15246 | + case WIN_WRITE_EXT: | |
15247 | + case WIN_WRITE_VERIFY: | |
15248 | + case WIN_WRITE_BUFFER: | |
15249 | + case CFA_WRITE_SECT_WO_ERASE: | |
15250 | + case WIN_DOWNLOAD_MICROCODE: | |
15251 | + return &pre_task_out_intr; | |
15252 | + /* IDE_DRIVE_TASK_OUT */ | |
15253 | + case WIN_SMART: | |
15254 | + if (taskfile->feature == SMART_WRITE_LOG_SECTOR) | |
15255 | + return &pre_task_out_intr; | |
15256 | + case WIN_WRITEDMA: | |
15257 | + // case WIN_WRITEDMA_ONCE: | |
15258 | + case WIN_WRITEDMA_QUEUED: | |
15259 | + case WIN_WRITEDMA_EXT: | |
15260 | + case WIN_WRITEDMA_QUEUED_EXT: | |
15261 | + /* IDE_DRIVE_TASK_OUT */ | |
15262 | + default: | |
15263 | + break; | |
15264 | + } | |
15265 | + return(NULL); | |
15266 | +} | |
15267 | + | |
15268 | +/* Called by internal to feature out type of command being called */ | |
15269 | +ide_handler_t * ide_handler_parser (struct hd_drive_task_hdr *taskfile, struct hd_drive_hob_hdr *hobfile) | |
15270 | +{ | |
15271 | + switch(taskfile->command) { | |
15272 | + case WIN_IDENTIFY: | |
15273 | + case WIN_PIDENTIFY: | |
15274 | + case CFA_TRANSLATE_SECTOR: | |
15275 | + case WIN_READ_BUFFER: | |
15276 | + case WIN_READ: | |
15277 | + // case WIN_READ_ONCE: | |
15278 | + case WIN_READ_EXT: | |
15279 | + return &task_in_intr; | |
15280 | + case WIN_SECURITY_DISABLE: | |
15281 | + case WIN_SECURITY_ERASE_UNIT: | |
15282 | + case WIN_SECURITY_SET_PASS: | |
15283 | + case WIN_SECURITY_UNLOCK: | |
15284 | + case WIN_DOWNLOAD_MICROCODE: | |
15285 | + case CFA_WRITE_SECT_WO_ERASE: | |
15286 | + case WIN_WRITE_BUFFER: | |
15287 | + case WIN_WRITE_VERIFY: | |
15288 | + case WIN_WRITE: | |
15289 | + // case WIN_WRITE_ONCE: | |
15290 | + case WIN_WRITE_EXT: | |
15291 | + return &task_out_intr; | |
15292 | + // case WIN_READ_LONG: | |
15293 | + // case WIN_READ_LONG_ONCE: | |
15294 | + case WIN_MULTREAD: | |
15295 | + case WIN_MULTREAD_EXT: | |
15296 | + return &task_mulin_intr; | |
15297 | + // case WIN_WRITE_LONG: | |
15298 | + // case WIN_WRITE_LONG_ONCE: | |
15299 | + case CFA_WRITE_MULTI_WO_ERASE: | |
15300 | + case WIN_MULTWRITE: | |
15301 | + case WIN_MULTWRITE_EXT: | |
15302 | + return &task_mulout_intr; | |
15303 | + case WIN_SMART: | |
15304 | + switch(taskfile->feature) { | |
15305 | + case SMART_READ_VALUES: | |
15306 | + case SMART_READ_THRESHOLDS: | |
15307 | + case SMART_READ_LOG_SECTOR: | |
15308 | + return &task_in_intr; | |
15309 | + case SMART_WRITE_LOG_SECTOR: | |
15310 | + return &task_out_intr; | |
15311 | + default: | |
15312 | + return &task_no_data_intr; | |
15313 | + } | |
15314 | + case CFA_REQ_EXT_ERROR_CODE: | |
15315 | + case CFA_ERASE_SECTORS: | |
15316 | + case WIN_VERIFY: | |
15317 | + // case WIN_VERIFY_ONCE: | |
15318 | + case WIN_VERIFY_EXT: | |
15319 | + case WIN_SEEK: | |
15320 | + return &task_no_data_intr; | |
15321 | + case WIN_SPECIFY: | |
15322 | + return &set_geometry_intr; | |
15323 | + case WIN_RECAL: | |
15324 | + // case WIN_RESTORE: | |
15325 | + return &recal_intr; | |
15326 | + case WIN_NOP: | |
15327 | + case WIN_DIAGNOSE: | |
15328 | + case WIN_FLUSH_CACHE: | |
15329 | + case WIN_FLUSH_CACHE_EXT: | |
15330 | + case WIN_STANDBYNOW1: | |
15331 | + case WIN_STANDBYNOW2: | |
15332 | + case WIN_SLEEPNOW1: | |
15333 | + case WIN_SLEEPNOW2: | |
15334 | + case WIN_SETIDLE1: | |
15335 | + case WIN_CHECKPOWERMODE1: | |
15336 | + case WIN_CHECKPOWERMODE2: | |
15337 | + case WIN_GETMEDIASTATUS: | |
15338 | + case WIN_MEDIAEJECT: | |
15339 | + return &task_no_data_intr; | |
15340 | + case WIN_SETMULT: | |
15341 | + return &set_multmode_intr; | |
15342 | + case WIN_READ_NATIVE_MAX: | |
15343 | + case WIN_SET_MAX: | |
15344 | + case WIN_READ_NATIVE_MAX_EXT: | |
15345 | + case WIN_SET_MAX_EXT: | |
15346 | + case WIN_SECURITY_ERASE_PREPARE: | |
15347 | + case WIN_SECURITY_FREEZE_LOCK: | |
15348 | + case WIN_DOORLOCK: | |
15349 | + case WIN_DOORUNLOCK: | |
15350 | + case WIN_SETFEATURES: | |
15351 | + return &task_no_data_intr; | |
15352 | + case DISABLE_SEAGATE: | |
15353 | + case EXABYTE_ENABLE_NEST: | |
15354 | + return &task_no_data_intr; | |
15355 | +#ifdef CONFIG_BLK_DEV_IDEDMA | |
15356 | + case WIN_READDMA: | |
15357 | + // case WIN_READDMA_ONCE: | |
15358 | + case WIN_IDENTIFY_DMA: | |
15359 | + case WIN_READDMA_QUEUED: | |
15360 | + case WIN_READDMA_EXT: | |
15361 | + case WIN_READDMA_QUEUED_EXT: | |
15362 | + case WIN_WRITEDMA: | |
15363 | + // case WIN_WRITEDMA_ONCE: | |
15364 | + case WIN_WRITEDMA_QUEUED: | |
15365 | + case WIN_WRITEDMA_EXT: | |
15366 | + case WIN_WRITEDMA_QUEUED_EXT: | |
15367 | +#endif | |
15368 | + case WIN_FORMAT: | |
15369 | + case WIN_INIT: | |
15370 | + case WIN_DEVICE_RESET: | |
15371 | + case WIN_QUEUED_SERVICE: | |
15372 | + case WIN_PACKETCMD: | |
15373 | + default: | |
15374 | + return(NULL); | |
15375 | + } | |
15376 | +} | |
15377 | + | |
15378 | +ide_post_handler_t * ide_post_handler_parser (struct hd_drive_task_hdr *taskfile, struct hd_drive_hob_hdr *hobfile) | |
15379 | +{ | |
15380 | + switch(taskfile->command) { | |
15381 | + case WIN_SPECIFY: /* set_geometry_intr */ | |
15382 | + case WIN_RESTORE: /* recal_intr */ | |
15383 | + case WIN_SETMULT: /* set_multmode_intr */ | |
15384 | + default: | |
15385 | + return(NULL); | |
15386 | + } | |
15387 | +} | |
15388 | + | |
15389 | +/* Called by ioctl to feature out type of command being called */ | |
15390 | +int ide_cmd_type_parser (ide_task_t *args) | |
15391 | +{ | |
15392 | + struct hd_drive_task_hdr *taskfile = (struct hd_drive_task_hdr *) args->tfRegister; | |
15393 | + struct hd_drive_hob_hdr *hobfile = (struct hd_drive_hob_hdr *) args->hobRegister; | |
15394 | + | |
15395 | + args->prehandler = ide_pre_handler_parser(taskfile, hobfile); | |
15396 | + args->handler = ide_handler_parser(taskfile, hobfile); | |
15397 | + args->posthandler = ide_post_handler_parser(taskfile, hobfile); | |
15398 | + | |
15399 | + switch(args->tfRegister[IDE_COMMAND_OFFSET]) { | |
15400 | + case WIN_IDENTIFY: | |
15401 | + case WIN_PIDENTIFY: | |
15402 | + return IDE_DRIVE_TASK_IN; | |
15403 | + case CFA_TRANSLATE_SECTOR: | |
15404 | + case WIN_READ: | |
15405 | + // case WIN_READ_ONCE: | |
15406 | + case WIN_READ_EXT: | |
15407 | + case WIN_READ_BUFFER: | |
15408 | + return IDE_DRIVE_TASK_IN; | |
15409 | + case WIN_WRITE: | |
15410 | + // case WIN_WRITE_ONCE: | |
15411 | + case WIN_WRITE_EXT: | |
15412 | + case WIN_WRITE_VERIFY: | |
15413 | + case WIN_WRITE_BUFFER: | |
15414 | + case CFA_WRITE_SECT_WO_ERASE: | |
15415 | + case WIN_DOWNLOAD_MICROCODE: | |
15416 | + return IDE_DRIVE_TASK_RAW_WRITE; | |
15417 | + // case WIN_READ_LONG: | |
15418 | + // case WIN_READ_LONG_ONCE: | |
15419 | + case WIN_MULTREAD: | |
15420 | + case WIN_MULTREAD_EXT: | |
15421 | + return IDE_DRIVE_TASK_IN; | |
15422 | + // case WIN_WRITE_LONG: | |
15423 | + // case WIN_WRITE_LONG_ONCE: | |
15424 | + case CFA_WRITE_MULTI_WO_ERASE: | |
15425 | + case WIN_MULTWRITE: | |
15426 | + case WIN_MULTWRITE_EXT: | |
15427 | + return IDE_DRIVE_TASK_RAW_WRITE; | |
15428 | + case WIN_SECURITY_DISABLE: | |
15429 | + case WIN_SECURITY_ERASE_UNIT: | |
15430 | + case WIN_SECURITY_SET_PASS: | |
15431 | + case WIN_SECURITY_UNLOCK: | |
15432 | + return IDE_DRIVE_TASK_OUT; | |
15433 | + case WIN_SMART: | |
15434 | + args->tfRegister[IDE_LCYL_OFFSET] = SMART_LCYL_PASS; | |
15435 | + args->tfRegister[IDE_HCYL_OFFSET] = SMART_HCYL_PASS; | |
15436 | + switch(args->tfRegister[IDE_FEATURE_OFFSET]) { | |
15437 | + case SMART_READ_VALUES: | |
15438 | + case SMART_READ_THRESHOLDS: | |
15439 | + case SMART_READ_LOG_SECTOR: | |
15440 | + return IDE_DRIVE_TASK_IN; | |
15441 | + case SMART_WRITE_LOG_SECTOR: | |
15442 | + return IDE_DRIVE_TASK_OUT; | |
15443 | + default: | |
15444 | + return IDE_DRIVE_TASK_NO_DATA; | |
15445 | + } | |
15446 | +#ifdef CONFIG_BLK_DEV_IDEDMA | |
15447 | + case WIN_READDMA: | |
15448 | + // case WIN_READDMA_ONCE: | |
15449 | + case WIN_IDENTIFY_DMA: | |
15450 | + case WIN_READDMA_QUEUED: | |
15451 | + case WIN_READDMA_EXT: | |
15452 | + case WIN_READDMA_QUEUED_EXT: | |
15453 | + return IDE_DRIVE_TASK_IN; | |
15454 | + case WIN_WRITEDMA: | |
15455 | + // case WIN_WRITEDMA_ONCE: | |
15456 | + case WIN_WRITEDMA_QUEUED: | |
15457 | + case WIN_WRITEDMA_EXT: | |
15458 | + case WIN_WRITEDMA_QUEUED_EXT: | |
15459 | + return IDE_DRIVE_TASK_RAW_WRITE; | |
15460 | +#endif | |
15461 | + case WIN_SETFEATURES: | |
15462 | + switch(args->tfRegister[IDE_FEATURE_OFFSET]) { | |
15463 | + case SETFEATURES_EN_8BIT: | |
15464 | + case SETFEATURES_EN_WCACHE: | |
15465 | + return IDE_DRIVE_TASK_NO_DATA; | |
15466 | + case SETFEATURES_XFER: | |
15467 | + return IDE_DRIVE_TASK_SET_XFER; | |
15468 | + case SETFEATURES_DIS_DEFECT: | |
15469 | + case SETFEATURES_EN_APM: | |
15470 | + case SETFEATURES_DIS_MSN: | |
15471 | + case SETFEATURES_DIS_RETRY: | |
15472 | + case SETFEATURES_EN_AAM: | |
15473 | + case SETFEATURES_RW_LONG: | |
15474 | + case SETFEATURES_SET_CACHE: | |
15475 | + case SETFEATURES_DIS_RLA: | |
15476 | + case SETFEATURES_EN_RI: | |
15477 | + case SETFEATURES_EN_SI: | |
15478 | + case SETFEATURES_DIS_RPOD: | |
15479 | + case SETFEATURES_DIS_WCACHE: | |
15480 | + case SETFEATURES_EN_DEFECT: | |
15481 | + case SETFEATURES_DIS_APM: | |
15482 | + case SETFEATURES_EN_ECC: | |
15483 | + case SETFEATURES_EN_MSN: | |
15484 | + case SETFEATURES_EN_RETRY: | |
15485 | + case SETFEATURES_EN_RLA: | |
15486 | + case SETFEATURES_PREFETCH: | |
15487 | + case SETFEATURES_4B_RW_LONG: | |
15488 | + case SETFEATURES_DIS_AAM: | |
15489 | + case SETFEATURES_EN_RPOD: | |
15490 | + case SETFEATURES_DIS_RI: | |
15491 | + case SETFEATURES_DIS_SI: | |
15492 | + default: | |
15493 | + return IDE_DRIVE_TASK_NO_DATA; | |
15494 | + } | |
15495 | + case WIN_NOP: | |
15496 | + case CFA_REQ_EXT_ERROR_CODE: | |
15497 | + case CFA_ERASE_SECTORS: | |
15498 | + case WIN_VERIFY: | |
15499 | + // case WIN_VERIFY_ONCE: | |
15500 | + case WIN_VERIFY_EXT: | |
15501 | + case WIN_SEEK: | |
15502 | + case WIN_SPECIFY: | |
15503 | + case WIN_RESTORE: | |
15504 | + case WIN_DIAGNOSE: | |
15505 | + case WIN_FLUSH_CACHE: | |
15506 | + case WIN_FLUSH_CACHE_EXT: | |
15507 | + case WIN_STANDBYNOW1: | |
15508 | + case WIN_STANDBYNOW2: | |
15509 | + case WIN_SLEEPNOW1: | |
15510 | + case WIN_SLEEPNOW2: | |
15511 | + case WIN_SETIDLE1: | |
15512 | + case DISABLE_SEAGATE: | |
15513 | + case WIN_CHECKPOWERMODE1: | |
15514 | + case WIN_CHECKPOWERMODE2: | |
15515 | + case WIN_GETMEDIASTATUS: | |
15516 | + case WIN_MEDIAEJECT: | |
15517 | + case WIN_SETMULT: | |
15518 | + case WIN_READ_NATIVE_MAX: | |
15519 | + case WIN_SET_MAX: | |
15520 | + case WIN_READ_NATIVE_MAX_EXT: | |
15521 | + case WIN_SET_MAX_EXT: | |
15522 | + case WIN_SECURITY_ERASE_PREPARE: | |
15523 | + case WIN_SECURITY_FREEZE_LOCK: | |
15524 | + case EXABYTE_ENABLE_NEST: | |
15525 | + case WIN_DOORLOCK: | |
15526 | + case WIN_DOORUNLOCK: | |
15527 | + return IDE_DRIVE_TASK_NO_DATA; | |
15528 | + case WIN_FORMAT: | |
15529 | + case WIN_INIT: | |
15530 | + case WIN_DEVICE_RESET: | |
15531 | + case WIN_QUEUED_SERVICE: | |
15532 | + case WIN_PACKETCMD: | |
15533 | + default: | |
15534 | + return IDE_DRIVE_TASK_INVALID; | |
15535 | + } | |
15536 | +} | |
15537 | + | |
15538 | +/* | |
15539 | + * NOTICE: This is additions from IBM to provide a discrete interface, | |
15540 | + * for selective taskregister access operations. Nice JOB Klaus!!! | |
15541 | + * Glad to be able to work and co-develop this with you and IBM. | |
15542 | + */ | |
15543 | +ide_startstop_t flagged_taskfile (ide_drive_t *drive, ide_task_t *task) | |
15544 | +{ | |
15545 | + task_struct_t *taskfile = (task_struct_t *) task->tfRegister; | |
15546 | + hob_struct_t *hobfile = (hob_struct_t *) task->hobRegister; | |
15547 | + struct hd_driveid *id = drive->id; | |
15548 | +#if DEBUG_TASKFILE | |
15549 | + byte status; | |
15550 | +#endif | |
15551 | + | |
15552 | + | |
15553 | +#ifdef CONFIG_IDE_TASK_IOCTL_DEBUG | |
15554 | + void debug_taskfile(drive, task); | |
15555 | +#endif /* CONFIG_IDE_TASK_IOCTL_DEBUG */ | |
15556 | + | |
15557 | + /* | |
15558 | + * (ks) Check taskfile in/out flags. | |
15559 | + * If set, then execute as it is defined. | |
15560 | + * If not set, then define default settings. | |
15561 | + * The default values are: | |
15562 | + * write and read all taskfile registers (except data) | |
15563 | + * write and read the hob registers (sector,nsector,lcyl,hcyl) | |
15564 | + */ | |
15565 | + if (task->tf_out_flags.all == 0) { | |
15566 | + task->tf_out_flags.all = IDE_TASKFILE_STD_OUT_FLAGS; | |
15567 | + if ((id->command_set_2 & 0x0400) && | |
15568 | + (id->cfs_enable_2 & 0x0400) && | |
15569 | + (drive->addressing == 1)) { | |
15570 | + task->tf_out_flags.all |= (IDE_HOB_STD_OUT_FLAGS << 8); | |
15571 | + } | |
15572 | + } | |
15573 | + | |
15574 | + if (task->tf_in_flags.all == 0) { | |
15575 | + task->tf_in_flags.all = IDE_TASKFILE_STD_IN_FLAGS; | |
15576 | + if ((id->command_set_2 & 0x0400) && | |
15577 | + (id->cfs_enable_2 & 0x0400) && | |
15578 | + (drive->addressing == 1)) { | |
15579 | + task->tf_in_flags.all |= (IDE_HOB_STD_IN_FLAGS << 8); | |
15580 | + } | |
15581 | + } | |
15582 | + | |
15583 | + /* ALL Command Block Executions SHALL clear nIEN, unless otherwise */ | |
15584 | + if (IDE_CONTROL_REG) | |
15585 | + OUT_BYTE(drive->ctl, IDE_CONTROL_REG); /* clear nIEN */ | |
15586 | + SELECT_MASK(HWIF(drive), drive, 0); | |
15587 | + | |
15588 | +#if DEBUG_TASKFILE | |
15589 | + status = GET_STAT(); | |
15590 | + if (status & 0x80) { | |
15591 | + printk("flagged_taskfile -> Bad status. Status = %02x. wait 100 usec ...\n", status); | |
15592 | + udelay(100); | |
15593 | + status = GET_STAT(); | |
15594 | + printk("flagged_taskfile -> Status = %02x\n", status); | |
15595 | + } | |
15596 | +#endif | |
15597 | + | |
15598 | + if (task->tf_out_flags.b.data) { | |
15599 | + unsigned short data = taskfile->data + (hobfile->data << 8); | |
15600 | + OUT_WORD(data, IDE_DATA_REG); | |
15601 | + } | |
15602 | + | |
15603 | + /* (ks) send hob registers first */ | |
15604 | + if (task->tf_out_flags.b.nsector_hob) | |
15605 | + OUT_BYTE(hobfile->sector_count, IDE_NSECTOR_REG); | |
15606 | + if (task->tf_out_flags.b.sector_hob) | |
15607 | + OUT_BYTE(hobfile->sector_number, IDE_SECTOR_REG); | |
15608 | + if (task->tf_out_flags.b.lcyl_hob) | |
15609 | + OUT_BYTE(hobfile->low_cylinder, IDE_LCYL_REG); | |
15610 | + if (task->tf_out_flags.b.hcyl_hob) | |
15611 | + OUT_BYTE(hobfile->high_cylinder, IDE_HCYL_REG); | |
15612 | + | |
15613 | + /* (ks) Send now the standard registers */ | |
15614 | + if (task->tf_out_flags.b.error_feature) | |
15615 | + OUT_BYTE(taskfile->feature, IDE_FEATURE_REG); | |
15616 | + /* refers to number of sectors to transfer */ | |
15617 | + if (task->tf_out_flags.b.nsector) | |
15618 | + OUT_BYTE(taskfile->sector_count, IDE_NSECTOR_REG); | |
15619 | + /* refers to sector offset or start sector */ | |
15620 | + if (task->tf_out_flags.b.sector) | |
15621 | + OUT_BYTE(taskfile->sector_number, IDE_SECTOR_REG); | |
15622 | + if (task->tf_out_flags.b.lcyl) | |
15623 | + OUT_BYTE(taskfile->low_cylinder, IDE_LCYL_REG); | |
15624 | + if (task->tf_out_flags.b.hcyl) | |
15625 | + OUT_BYTE(taskfile->high_cylinder, IDE_HCYL_REG); | |
15626 | + | |
15627 | + /* | |
15628 | + * (ks) In the flagged taskfile approch, we will used all specified | |
15629 | + * registers and the register value will not be changed. Except the | |
15630 | + * select bit (master/slave) in the drive_head register. We must make | |
15631 | + * sure that the desired drive is selected. | |
15632 | + */ | |
15633 | + OUT_BYTE(taskfile->device_head | drive->select.all, IDE_SELECT_REG); | |
15634 | + switch(task->data_phase) { | |
15635 | + | |
15636 | + case TASKFILE_OUT_DMAQ: | |
15637 | + case TASKFILE_OUT_DMA: | |
15638 | + HWIF(drive)->dmaproc(ide_dma_write, drive); | |
15639 | + break; | |
15640 | + | |
15641 | + case TASKFILE_IN_DMAQ: | |
15642 | + case TASKFILE_IN_DMA: | |
15643 | + HWIF(drive)->dmaproc(ide_dma_read, drive); | |
15644 | + break; | |
15645 | + | |
15646 | + default: | |
15647 | + if (task->handler == NULL) | |
15648 | + return ide_stopped; | |
15649 | + | |
15650 | + ide_set_handler (drive, task->handler, WAIT_WORSTCASE, NULL); | |
15651 | + /* Issue the command */ | |
15652 | + OUT_BYTE(taskfile->command, IDE_COMMAND_REG); | |
15653 | + if (task->prehandler != NULL) | |
15654 | + return task->prehandler(drive, HWGROUP(drive)->rq); | |
15655 | + } | |
15656 | + | |
15657 | + return ide_started; | |
15658 | +} | |
15659 | + | |
15660 | +ide_startstop_t flagged_task_no_data_intr (ide_drive_t *drive) | |
15661 | +{ | |
15662 | + byte stat = GET_STAT(); | |
15663 | + | |
15664 | + local_irq_enable(); | |
15665 | + | |
15666 | + if (!OK_STAT(stat, READY_STAT, BAD_STAT)) { | |
15667 | + if (stat & ERR_STAT) { | |
15668 | + return DRIVER(drive)->error(drive, "flagged_task_no_data_intr", stat); | |
15669 | + } | |
15670 | + /* | |
15671 | + * (ks) Unexpected ATA data phase detected. | |
15672 | + * This should not happen. But, it can ! | |
15673 | + * I am not sure, which function is best to clean up | |
15674 | + * this situation. I choose: ide_error(...) | |
15675 | + */ | |
15676 | + return DRIVER(drive)->error(drive, "flagged_task_no_data_intr (unexpected phase)", stat); | |
15677 | + } | |
15678 | + | |
15679 | + ide_end_drive_cmd (drive, stat, GET_ERR()); | |
15680 | + | |
15681 | + return ide_stopped; | |
15682 | +} | |
15683 | + | |
15684 | +/* | |
15685 | + * Handler for command with PIO data-in phase | |
15686 | + */ | |
15687 | +ide_startstop_t flagged_task_in_intr (ide_drive_t *drive) | |
15688 | +{ | |
15689 | + byte stat = GET_STAT(); | |
15690 | + struct request *rq = HWGROUP(drive)->rq; | |
15691 | + char *pBuf = NULL; | |
15692 | + int retries = 5; | |
15693 | + | |
15694 | + if (rq->current_nr_sectors == 0) | |
15695 | + return DRIVER(drive)->error(drive, "flagged_task_in_intr (no data requested)", stat); | |
15696 | + | |
15697 | + if (!OK_STAT(stat, DATA_READY, BAD_R_STAT)) { | |
15698 | + if (stat & ERR_STAT) { | |
15699 | + return DRIVER(drive)->error(drive, "flagged_task_in_intr", stat); | |
15700 | + } | |
15701 | + /* | |
15702 | + * (ks) Unexpected ATA data phase detected. | |
15703 | + * This should not happen. But, it can ! | |
15704 | + * I am not sure, which function is best to clean up | |
15705 | + * this situation. I choose: ide_error(...) | |
15706 | + */ | |
15707 | + return DRIVER(drive)->error(drive, "flagged_task_in_intr (unexpected data phase)", stat); | |
15708 | + } | |
15709 | + | |
15710 | + pBuf = rq->buffer + ((rq->nr_sectors - rq->current_nr_sectors) * SECTOR_SIZE); | |
15711 | + DTF("Read - rq->current_nr_sectors: %d, status: %02x\n", (int) rq->current_nr_sectors, stat); | |
15712 | + | |
15713 | + taskfile_input_data(drive, pBuf, SECTOR_WORDS); | |
15714 | + | |
15715 | + if (--rq->current_nr_sectors != 0) { | |
15716 | + /* | |
15717 | + * (ks) We don't know which command was executed. | |
15718 | + * So, we wait the 'WORSTCASE' value. | |
15719 | + */ | |
15720 | + ide_set_handler(drive, &flagged_task_in_intr, WAIT_WORSTCASE, NULL); | |
15721 | + return ide_started; | |
15722 | + } | |
15723 | + /* | |
15724 | + * (ks) Last sector was transfered, wait until drive is ready. | |
15725 | + * This can take up to 10 usec. We willl wait max 50 us. | |
15726 | + */ | |
15727 | + while (((stat = GET_STAT()) & BUSY_STAT) && retries--) | |
15728 | + udelay(10); | |
15729 | + ide_end_drive_cmd (drive, stat, GET_ERR()); | |
15730 | + | |
15731 | + return ide_stopped; | |
15732 | +} | |
15733 | + | |
15734 | +ide_startstop_t flagged_task_mulin_intr (ide_drive_t *drive) | |
15735 | +{ | |
15736 | + byte stat = GET_STAT(); | |
15737 | + struct request *rq = HWGROUP(drive)->rq; | |
15738 | + char *pBuf = NULL; | |
15739 | + int retries = 5; | |
15740 | + unsigned int msect, nsect; | |
15741 | + | |
15742 | + if (rq->current_nr_sectors == 0) | |
15743 | + return DRIVER(drive)->error(drive, "flagged_task_mulin_intr (no data requested)", stat); | |
15744 | + | |
15745 | + msect = drive->mult_count; | |
15746 | + if (msect == 0) | |
15747 | + return DRIVER(drive)->error(drive, "flagged_task_mulin_intr (multimode not set)", stat); | |
15748 | + | |
15749 | + if (!OK_STAT(stat, DATA_READY, BAD_R_STAT)) { | |
15750 | + if (stat & ERR_STAT) { | |
15751 | + return DRIVER(drive)->error(drive, "flagged_task_mulin_intr", stat); | |
15752 | + } | |
15753 | + /* | |
15754 | + * (ks) Unexpected ATA data phase detected. | |
15755 | + * This should not happen. But, it can ! | |
15756 | + * I am not sure, which function is best to clean up | |
15757 | + * this situation. I choose: ide_error(...) | |
15758 | + */ | |
15759 | + return DRIVER(drive)->error(drive, "flagged_task_mulin_intr (unexpected data phase)", stat); | |
15760 | + } | |
15761 | + | |
15762 | + nsect = (rq->current_nr_sectors > msect) ? msect : rq->current_nr_sectors; | |
15763 | + pBuf = rq->buffer + ((rq->nr_sectors - rq->current_nr_sectors) * SECTOR_SIZE); | |
15764 | + | |
15765 | + DTF("Multiread: %p, nsect: %d , rq->current_nr_sectors: %ld\n", | |
15766 | + pBuf, nsect, rq->current_nr_sectors); | |
15767 | + | |
15768 | + taskfile_input_data(drive, pBuf, nsect * SECTOR_WORDS); | |
15769 | + | |
15770 | + rq->current_nr_sectors -= nsect; | |
15771 | + if (rq->current_nr_sectors != 0) { | |
15772 | + /* | |
15773 | + * (ks) We don't know which command was executed. | |
15774 | + * So, we wait the 'WORSTCASE' value. | |
15775 | + */ | |
15776 | + ide_set_handler(drive, &flagged_task_mulin_intr, WAIT_WORSTCASE, NULL); | |
15777 | + return ide_started; | |
15778 | + } | |
15779 | + | |
15780 | + /* | |
15781 | + * (ks) Last sector was transfered, wait until drive is ready. | |
15782 | + * This can take up to 10 usec. We willl wait max 50 us. | |
15783 | + */ | |
15784 | + while (((stat = GET_STAT()) & BUSY_STAT) && retries--) | |
15785 | + udelay(10); | |
15786 | + ide_end_drive_cmd (drive, stat, GET_ERR()); | |
15787 | + | |
15788 | + return ide_stopped; | |
15789 | +} | |
15790 | + | |
15791 | +/* | |
15792 | + * Pre handler for command with PIO data-out phase | |
15793 | + */ | |
15794 | +ide_startstop_t flagged_pre_task_out_intr (ide_drive_t *drive, struct request *rq) | |
15795 | +{ | |
15796 | + byte stat = GET_STAT(); | |
15797 | + ide_startstop_t startstop; | |
15798 | + | |
15799 | + if (!rq->current_nr_sectors) { | |
15800 | + return DRIVER(drive)->error(drive, "flagged_pre_task_out_intr (write data not specified)", stat); | |
15801 | + } | |
15802 | + | |
15803 | + if (ide_wait_stat(&startstop, drive, DATA_READY, | |
15804 | + BAD_W_STAT, WAIT_DRQ)) { | |
15805 | + printk(KERN_ERR "%s: No DRQ bit after issuing write command.\n", drive->name); | |
15806 | + return startstop; | |
15807 | + } | |
15808 | + | |
15809 | + taskfile_output_data(drive, rq->buffer, SECTOR_WORDS); | |
15810 | + --rq->current_nr_sectors; | |
15811 | + | |
15812 | + return ide_started; | |
15813 | +} | |
15814 | + | |
15815 | +ide_startstop_t flagged_task_out_intr (ide_drive_t *drive) | |
15816 | +{ | |
15817 | + byte stat = GET_STAT(); | |
15818 | + struct request *rq = HWGROUP(drive)->rq; | |
15819 | + char *pBuf = NULL; | |
15820 | + | |
15821 | + if (!OK_STAT(stat, DRIVE_READY, BAD_W_STAT)) | |
15822 | + return DRIVER(drive)->error(drive, "flagged_task_out_intr", stat); | |
15823 | + | |
15824 | + if (!rq->current_nr_sectors) { | |
15825 | + ide_end_drive_cmd (drive, stat, GET_ERR()); | |
15826 | + return ide_stopped; | |
15827 | + } | |
15828 | + | |
15829 | + if (!OK_STAT(stat, DATA_READY, BAD_W_STAT)) { | |
15830 | + /* | |
15831 | + * (ks) Unexpected ATA data phase detected. | |
15832 | + * This should not happen. But, it can ! | |
15833 | + * I am not sure, which function is best to clean up | |
15834 | + * this situation. I choose: ide_error(...) | |
15835 | + */ | |
15836 | + return DRIVER(drive)->error(drive, "flagged_task_out_intr (unexpected data phase)", stat); | |
15837 | + } | |
15838 | + | |
15839 | + pBuf = rq->buffer + ((rq->nr_sectors - rq->current_nr_sectors) * SECTOR_SIZE); | |
15840 | + DTF("Write - rq->current_nr_sectors: %d, status: %02x\n", | |
15841 | + (int) rq->current_nr_sectors, stat); | |
15842 | + | |
15843 | + taskfile_output_data(drive, pBuf, SECTOR_WORDS); | |
15844 | + --rq->current_nr_sectors; | |
15845 | + | |
15846 | + /* | |
15847 | + * (ks) We don't know which command was executed. | |
15848 | + * So, we wait the 'WORSTCASE' value. | |
15849 | + */ | |
15850 | + ide_set_handler(drive, &flagged_task_out_intr, WAIT_WORSTCASE, NULL); | |
15851 | + | |
15852 | + return ide_started; | |
15853 | +} | |
15854 | + | |
15855 | +ide_startstop_t flagged_pre_task_mulout_intr (ide_drive_t *drive, struct request *rq) | |
15856 | +{ | |
15857 | + byte stat = GET_STAT(); | |
15858 | + char *pBuf = NULL; | |
15859 | + ide_startstop_t startstop; | |
15860 | + unsigned int msect, nsect; | |
15861 | + | |
15862 | + if (!rq->current_nr_sectors) | |
15863 | + return DRIVER(drive)->error(drive, "flagged_pre_task_mulout_intr (write data not specified)", stat); | |
15864 | + | |
15865 | + msect = drive->mult_count; | |
15866 | + if (msect == 0) | |
15867 | + return DRIVER(drive)->error(drive, "flagged_pre_task_mulout_intr (multimode not set)", stat); | |
15868 | + | |
15869 | + if (ide_wait_stat(&startstop, drive, DATA_READY, | |
15870 | + BAD_W_STAT, WAIT_DRQ)) { | |
15871 | + printk(KERN_ERR "%s: No DRQ bit after issuing write command.\n", drive->name); | |
15872 | + return startstop; | |
15873 | + } | |
15874 | + | |
15875 | + nsect = (rq->current_nr_sectors > msect) ? msect : rq->current_nr_sectors; | |
15876 | + pBuf = rq->buffer + ((rq->nr_sectors - rq->current_nr_sectors) * SECTOR_SIZE); | |
15877 | + DTF("Multiwrite: %p, nsect: %d , rq->current_nr_sectors: %ld\n", | |
15878 | + pBuf, nsect, rq->current_nr_sectors); | |
15879 | + | |
15880 | + taskfile_output_data(drive, pBuf, nsect * SECTOR_WORDS); | |
15881 | + | |
15882 | + rq->current_nr_sectors -= nsect; | |
15883 | + | |
15884 | + return ide_started; | |
15885 | +} | |
15886 | + | |
15887 | +ide_startstop_t flagged_task_mulout_intr (ide_drive_t *drive) | |
15888 | +{ | |
15889 | + byte stat = GET_STAT(); | |
15890 | + struct request *rq = HWGROUP(drive)->rq; | |
15891 | + char *pBuf = NULL; | |
15892 | + unsigned int msect, nsect; | |
15893 | + | |
15894 | + msect = drive->mult_count; | |
15895 | + if (msect == 0) | |
15896 | + return DRIVER(drive)->error(drive, "flagged_task_mulout_intr (multimode not set)", stat); | |
15897 | + | |
15898 | + if (!OK_STAT(stat, DRIVE_READY, BAD_W_STAT)) | |
15899 | + return DRIVER(drive)->error(drive, "flagged_task_mulout_intr", stat); | |
15900 | + | |
15901 | + if (!rq->current_nr_sectors) { | |
15902 | + ide_end_drive_cmd (drive, stat, GET_ERR()); | |
15903 | + return ide_stopped; | |
15904 | + } | |
15905 | + | |
15906 | + if (!OK_STAT(stat, DATA_READY, BAD_W_STAT)) { | |
15907 | + /* | |
15908 | + * (ks) Unexpected ATA data phase detected. | |
15909 | + * This should not happen. But, it can ! | |
15910 | + * I am not sure, which function is best to clean up | |
15911 | + * this situation. I choose: ide_error(...) | |
15912 | + */ | |
15913 | + return DRIVER(drive)->error(drive, "flagged_task_mulout_intr (unexpected data phase)", stat); | |
15914 | + } | |
15915 | + | |
15916 | + nsect = (rq->current_nr_sectors > msect) ? msect : rq->current_nr_sectors; | |
15917 | + pBuf = rq->buffer + ((rq->nr_sectors - rq->current_nr_sectors) * SECTOR_SIZE); | |
15918 | + DTF("Multiwrite: %p, nsect: %d , rq->current_nr_sectors: %ld\n", | |
15919 | + pBuf, nsect, rq->current_nr_sectors); | |
15920 | + | |
15921 | + taskfile_output_data(drive, pBuf, nsect * SECTOR_WORDS); | |
15922 | + rq->current_nr_sectors -= nsect; | |
15923 | + | |
15924 | + /* | |
15925 | + * (ks) We don't know which command was executed. | |
15926 | + * So, we wait the 'WORSTCASE' value. | |
15927 | + */ | |
15928 | + ide_set_handler(drive, &flagged_task_mulout_intr, WAIT_WORSTCASE, NULL); | |
15929 | + | |
15930 | + return ide_started; | |
15931 | +} | |
15932 | + | |
15933 | +/* | |
15934 | + * This function is intended to be used prior to invoking ide_do_drive_cmd(). | |
15935 | + */ | |
15936 | +void ide_init_drive_taskfile (struct request *rq) | |
15937 | +{ | |
15938 | + memset(rq, 0, sizeof(*rq)); | |
15939 | + rq->cmd = IDE_DRIVE_TASK_NO_DATA; | |
15940 | +} | |
15941 | + | |
15942 | +int ide_diag_taskfile (ide_drive_t *drive, ide_task_t *args, unsigned long data_size, byte *buf) | |
15943 | +{ | |
15944 | + struct request rq; | |
15945 | + | |
15946 | + ide_init_drive_taskfile(&rq); | |
15947 | + rq.cmd = IDE_DRIVE_TASKFILE; | |
15948 | + rq.buffer = buf; | |
15949 | + | |
15950 | + /* | |
15951 | + * (ks) We transfer currently only whole sectors. | |
15952 | + * This is suffient for now. But, it would be great, | |
15953 | + * if we would find a solution to transfer any size. | |
15954 | + * To support special commands like READ LONG. | |
15955 | + */ | |
15956 | + if (args->command_type != IDE_DRIVE_TASK_NO_DATA) { | |
15957 | + if (data_size == 0) | |
15958 | + rq.current_nr_sectors = rq.nr_sectors = (args->hobRegister[IDE_NSECTOR_OFFSET_HOB] << 8) | args->tfRegister[IDE_NSECTOR_OFFSET]; | |
15959 | + /* rq.hard_cur_sectors */ | |
15960 | + else | |
15961 | + rq.current_nr_sectors = rq.nr_sectors = data_size / SECTOR_SIZE; | |
15962 | + /* rq.hard_cur_sectors */ | |
15963 | + } | |
15964 | + | |
15965 | + if (args->tf_out_flags.all == 0) { | |
15966 | + /* | |
15967 | + * clean up kernel settings for driver sanity, regardless. | |
15968 | + * except for discrete diag services. | |
15969 | + */ | |
15970 | + args->posthandler = ide_post_handler_parser( | |
15971 | + (struct hd_drive_task_hdr *) args->tfRegister, | |
15972 | + (struct hd_drive_hob_hdr *) args->hobRegister); | |
15973 | + | |
15974 | + } | |
15975 | + rq.special = args; | |
15976 | + return ide_do_drive_cmd(drive, &rq, ide_wait); | |
15977 | +} | |
15978 | + | |
15979 | +int ide_raw_taskfile (ide_drive_t *drive, ide_task_t *args, byte *buf) | |
15980 | +{ | |
15981 | + return ide_diag_taskfile(drive, args, 0, buf); | |
15982 | +} | |
15983 | + | |
15984 | +#ifdef CONFIG_IDE_TASK_IOCTL_DEBUG | |
15985 | +char * ide_ioctl_verbose (unsigned int cmd) | |
15986 | +{ | |
15987 | + return("unknown"); | |
15988 | +} | |
15989 | + | |
15990 | +char * ide_task_cmd_verbose (byte task) | |
15991 | +{ | |
15992 | + return("unknown"); | |
15993 | +} | |
15994 | +#endif /* CONFIG_IDE_TASK_IOCTL_DEBUG */ | |
15995 | + | |
15996 | +#define MAX_DMA (256*SECTOR_WORDS) | |
15997 | + | |
15998 | +int ide_taskfile_ioctl (ide_drive_t *drive, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) | |
15999 | +{ | |
16000 | + ide_task_request_t *req_task; | |
16001 | + ide_task_t args; | |
16002 | + byte *outbuf = NULL; | |
16003 | + byte *inbuf = NULL; | |
16004 | + task_ioreg_t *argsptr = args.tfRegister; | |
16005 | + task_ioreg_t *hobsptr = args.hobRegister; | |
16006 | + int err = 0; | |
16007 | + int tasksize = sizeof(struct ide_task_request_s); | |
16008 | + int taskin = 0; | |
16009 | + int taskout = 0; | |
16010 | + byte io_32bit = drive->io_32bit; | |
16011 | + | |
16012 | +// printk("IDE Taskfile ...\n"); | |
16013 | + | |
16014 | + req_task = kmalloc(tasksize, GFP_KERNEL); | |
16015 | + if (req_task == NULL) return -ENOMEM; | |
16016 | + memset(req_task, 0, tasksize); | |
16017 | + if (copy_from_user(req_task, (void *) arg, tasksize)) { | |
16018 | + kfree(req_task); | |
16019 | + return -EFAULT; | |
16020 | + } | |
16021 | + | |
16022 | + taskout = (int) req_task->out_size; | |
16023 | + taskin = (int) req_task->in_size; | |
16024 | + | |
16025 | + if (taskout) { | |
16026 | + int outtotal = tasksize; | |
16027 | + outbuf = kmalloc(taskout, GFP_KERNEL); | |
16028 | + if (outbuf == NULL) { | |
16029 | + err = -ENOMEM; | |
16030 | + goto abort; | |
16031 | + } | |
16032 | + memset(outbuf, 0, taskout); | |
16033 | + if (copy_from_user(outbuf, (void *)arg + outtotal, taskout)) { | |
16034 | + err = -EFAULT; | |
16035 | + goto abort; | |
16036 | + } | |
16037 | + } | |
16038 | + | |
16039 | + if (taskin) { | |
16040 | + int intotal = tasksize + taskout; | |
16041 | + inbuf = kmalloc(taskin, GFP_KERNEL); | |
16042 | + if (inbuf == NULL) { | |
16043 | + err = -ENOMEM; | |
16044 | + goto abort; | |
16045 | + } | |
16046 | + memset(inbuf, 0, taskin); | |
16047 | + if (copy_from_user(inbuf, (void *)arg + intotal , taskin)) { | |
16048 | + err = -EFAULT; | |
16049 | + goto abort; | |
16050 | + } | |
16051 | + } | |
16052 | + | |
16053 | + memset (&args, 0, sizeof (ide_task_t) ); | |
16054 | + memcpy(argsptr, req_task->io_ports, HDIO_DRIVE_TASK_HDR_SIZE); | |
16055 | + memcpy(hobsptr, req_task->hob_ports, HDIO_DRIVE_HOB_HDR_SIZE); | |
16056 | + | |
16057 | + args.tf_in_flags = req_task->in_flags; | |
16058 | + args.tf_out_flags = req_task->out_flags; | |
16059 | + args.data_phase = req_task->data_phase; | |
16060 | + args.command_type = req_task->req_cmd; | |
16061 | + | |
16062 | +#ifdef CONFIG_IDE_TASK_IOCTL_DEBUG | |
16063 | + DTF("%s: ide_ioctl_cmd %s: ide_task_cmd %s\n", | |
16064 | + drive->name, | |
16065 | + ide_ioctl_verbose(cmd), | |
16066 | + ide_task_cmd_verbose(args.tfRegister[IDE_COMMAND_OFFSET])); | |
16067 | +#endif /* CONFIG_IDE_TASK_IOCTL_DEBUG */ | |
16068 | + | |
16069 | + drive->io_32bit = 0; | |
16070 | + switch(req_task->data_phase) { | |
16071 | + case TASKFILE_OUT_DMAQ: | |
16072 | + case TASKFILE_OUT_DMA: | |
16073 | + err = ide_diag_taskfile(drive, &args, taskout, outbuf); | |
16074 | + break; | |
16075 | + case TASKFILE_IN_DMAQ: | |
16076 | + case TASKFILE_IN_DMA: | |
16077 | + err = ide_diag_taskfile(drive, &args, taskin, inbuf); | |
16078 | + break; | |
16079 | + case TASKFILE_IN_OUT: | |
16080 | +#if 0 | |
16081 | + args.prehandler = &pre_task_out_intr; | |
16082 | + args.handler = &task_out_intr; | |
16083 | + args.posthandler = NULL; | |
16084 | + err = ide_diag_taskfile(drive, &args, taskout, outbuf); | |
16085 | + args.prehandler = NULL; | |
16086 | + args.handler = &task_in_intr; | |
16087 | + args.posthandler = NULL; | |
16088 | + err = ide_diag_taskfile(drive, &args, taskin, inbuf); | |
16089 | + break; | |
16090 | +#else | |
16091 | + err = -EFAULT; | |
16092 | + goto abort; | |
16093 | +#endif | |
16094 | + case TASKFILE_MULTI_OUT: | |
16095 | + if (!drive->mult_count) { | |
16096 | + /* (hs): give up if multcount is not set */ | |
16097 | + printk("%s: %s Multimode Write " \ | |
16098 | + "multcount is not set\n", | |
16099 | + drive->name, __FUNCTION__); | |
16100 | + err = -EPERM; | |
16101 | + goto abort; | |
16102 | + } | |
16103 | + if (args.tf_out_flags.all != 0) { | |
16104 | + args.prehandler = &flagged_pre_task_mulout_intr; | |
16105 | + args.handler = &flagged_task_mulout_intr; | |
16106 | + } else { | |
16107 | + args.prehandler = &pre_task_mulout_intr; | |
16108 | + args.handler = &task_mulout_intr; | |
16109 | + } | |
16110 | + err = ide_diag_taskfile(drive, &args, taskout, outbuf); | |
16111 | + break; | |
16112 | + case TASKFILE_OUT: | |
16113 | + if (args.tf_out_flags.all != 0) { | |
16114 | + args.prehandler = &flagged_pre_task_out_intr; | |
16115 | + args.handler = &flagged_task_out_intr; | |
16116 | + } else { | |
16117 | + args.prehandler = &pre_task_out_intr; | |
16118 | + args.handler = &task_out_intr; | |
16119 | + } | |
16120 | + err = ide_diag_taskfile(drive, &args, taskout, outbuf); | |
16121 | + break; | |
16122 | + case TASKFILE_MULTI_IN: | |
16123 | + if (!drive->mult_count) { | |
16124 | + /* (hs): give up if multcount is not set */ | |
16125 | + printk("%s: %s Multimode Read failure " \ | |
16126 | + "multcount is not set\n", | |
16127 | + drive->name, __FUNCTION__); | |
16128 | + err = -EPERM; | |
16129 | + goto abort; | |
16130 | + } | |
16131 | + if (args.tf_out_flags.all != 0) { | |
16132 | + args.handler = &flagged_task_mulin_intr; | |
16133 | + } else { | |
16134 | + args.handler = &task_mulin_intr; | |
16135 | + } | |
16136 | + err = ide_diag_taskfile(drive, &args, taskin, inbuf); | |
16137 | + break; | |
16138 | + case TASKFILE_IN: | |
16139 | + if (args.tf_out_flags.all != 0) { | |
16140 | + args.handler = &flagged_task_in_intr; | |
16141 | + } else { | |
16142 | + args.handler = &task_in_intr; | |
16143 | + } | |
16144 | + err = ide_diag_taskfile(drive, &args, taskin, inbuf); | |
16145 | + break; | |
16146 | + case TASKFILE_NO_DATA: | |
16147 | + if (args.tf_out_flags.all != 0) { | |
16148 | + args.handler = &flagged_task_no_data_intr; | |
16149 | + } else { | |
16150 | + args.handler = &task_no_data_intr; | |
16151 | + } | |
16152 | + err = ide_diag_taskfile(drive, &args, 0, NULL); | |
16153 | + break; | |
16154 | + default: | |
16155 | + err = -EFAULT; | |
16156 | + goto abort; | |
16157 | + } | |
16158 | + | |
16159 | + memcpy(req_task->io_ports, &(args.tfRegister), HDIO_DRIVE_TASK_HDR_SIZE); | |
16160 | + memcpy(req_task->hob_ports, &(args.hobRegister), HDIO_DRIVE_HOB_HDR_SIZE); | |
16161 | + req_task->in_flags = args.tf_in_flags; | |
16162 | + req_task->out_flags = args.tf_out_flags; | |
16163 | + | |
16164 | + if (copy_to_user((void *)arg, req_task, tasksize)) { | |
16165 | + err = -EFAULT; | |
16166 | + goto abort; | |
16167 | + } | |
16168 | + if (taskout) { | |
16169 | + int outtotal = tasksize; | |
16170 | + if (copy_to_user((void *)arg+outtotal, outbuf, taskout)) { | |
16171 | + err = -EFAULT; | |
16172 | + goto abort; | |
16173 | + } | |
16174 | + } | |
16175 | + if (taskin) { | |
16176 | + int intotal = tasksize + taskout; | |
16177 | + if (copy_to_user((void *)arg+intotal, inbuf, taskin)) { | |
16178 | + err = -EFAULT; | |
16179 | + goto abort; | |
16180 | + } | |
16181 | + } | |
16182 | +abort: | |
16183 | + kfree(req_task); | |
16184 | + if (outbuf != NULL) | |
16185 | + kfree(outbuf); | |
16186 | + if (inbuf != NULL) | |
16187 | + kfree(inbuf); | |
16188 | + | |
16189 | +// printk("IDE Taskfile ioctl ended. rc = %i\n", err); | |
16190 | + | |
16191 | + drive->io_32bit = io_32bit; | |
16192 | + | |
16193 | + return err; | |
16194 | +} | |
16195 | + | |
16196 | +int ide_ata66_check (ide_drive_t *drive, ide_task_t *args); | |
16197 | +int set_transfer(ide_drive_t *drive, ide_task_t *args); | |
16198 | + | |
16199 | +/* | |
16200 | + * FIXME : this needs to map into at taskfile. <andre@linux-ide.org> | |
16201 | + */ | |
16202 | +int ide_cmd_ioctl (ide_drive_t *drive, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) | |
16203 | +{ | |
16204 | +#if 1 | |
16205 | + int err = 0; | |
16206 | + byte args[4], *argbuf = args; | |
16207 | + byte xfer_rate = 0; | |
16208 | + int argsize = 4; | |
16209 | + ide_task_t tfargs; | |
16210 | + | |
16211 | + if (NULL == (void *) arg) { | |
16212 | + struct request rq; | |
16213 | + ide_init_drive_cmd(&rq); | |
16214 | + return ide_do_drive_cmd(drive, &rq, ide_wait); | |
16215 | + } | |
16216 | + | |
16217 | + if (copy_from_user(args, (void *)arg, 4)) | |
16218 | + return -EFAULT; | |
16219 | + | |
16220 | + memset(&tfargs, 0, sizeof(ide_task_t)); | |
16221 | + tfargs.tfRegister[IDE_FEATURE_OFFSET] = args[2]; | |
16222 | + tfargs.tfRegister[IDE_NSECTOR_OFFSET] = args[3]; | |
16223 | + tfargs.tfRegister[IDE_SECTOR_OFFSET] = args[1]; | |
16224 | + tfargs.tfRegister[IDE_LCYL_OFFSET] = 0x00; | |
16225 | + tfargs.tfRegister[IDE_HCYL_OFFSET] = 0x00; | |
16226 | + tfargs.tfRegister[IDE_SELECT_OFFSET] = 0x00; | |
16227 | + tfargs.tfRegister[IDE_COMMAND_OFFSET] = args[0]; | |
16228 | + | |
16229 | + if (args[3]) { | |
16230 | + argsize = 4 + (SECTOR_WORDS * 4 * args[3]); | |
16231 | + argbuf = kmalloc(argsize, GFP_KERNEL); | |
16232 | + if (argbuf == NULL) | |
16233 | + return -ENOMEM; | |
16234 | + memcpy(argbuf, args, 4); | |
16235 | + } | |
16236 | + if (set_transfer(drive, &tfargs)) { | |
16237 | + xfer_rate = args[1]; | |
16238 | + if (ide_ata66_check(drive, &tfargs)) | |
16239 | + goto abort; | |
16240 | + } | |
16241 | + | |
16242 | + err = ide_wait_cmd(drive, args[0], args[1], args[2], args[3], argbuf); | |
16243 | + | |
16244 | + if (!err && xfer_rate) { | |
16245 | + /* active-retuning-calls future */ | |
16246 | + if ((HWIF(drive)->speedproc) != NULL) | |
16247 | + HWIF(drive)->speedproc(drive, xfer_rate); | |
16248 | + ide_driveid_update(drive); | |
16249 | + } | |
16250 | +abort: | |
16251 | + if (copy_to_user((void *)arg, argbuf, argsize)) | |
16252 | + err = -EFAULT; | |
16253 | + if (argsize > 4) | |
16254 | + kfree(argbuf); | |
16255 | + return err; | |
16256 | + | |
16257 | +#else | |
16258 | + | |
16259 | + int err = 0; | |
16260 | + byte args[4], *argbuf = args; | |
16261 | + byte xfer_rate = 0; | |
16262 | + int argsize = 0; | |
16263 | + ide_task_t tfargs; | |
16264 | + | |
16265 | + if (NULL == (void *) arg) { | |
16266 | + struct request rq; | |
16267 | + ide_init_drive_cmd(&rq); | |
16268 | + return ide_do_drive_cmd(drive, &rq, ide_wait); | |
16269 | + } | |
16270 | + | |
16271 | + if (copy_from_user(args, (void *)arg, 4)) | |
16272 | + return -EFAULT; | |
16273 | + | |
16274 | + memset(&tfargs, 0, sizeof(ide_task_t)); | |
16275 | + tfargs.tfRegister[IDE_FEATURE_OFFSET] = args[2]; | |
16276 | + tfargs.tfRegister[IDE_NSECTOR_OFFSET] = args[3]; | |
16277 | + tfargs.tfRegister[IDE_SECTOR_OFFSET] = args[1]; | |
16278 | + tfargs.tfRegister[IDE_LCYL_OFFSET] = 0x00; | |
16279 | + tfargs.tfRegister[IDE_HCYL_OFFSET] = 0x00; | |
16280 | + tfargs.tfRegister[IDE_SELECT_OFFSET] = 0x00; | |
16281 | + tfargs.tfRegister[IDE_COMMAND_OFFSET] = args[0]; | |
16282 | + | |
16283 | + if (args[3]) { | |
16284 | + argsize = (SECTOR_WORDS * 4 * args[3]); | |
16285 | + argbuf = kmalloc(argsize, GFP_KERNEL); | |
16286 | + if (argbuf == NULL) | |
16287 | + return -ENOMEM; | |
16288 | + } | |
16289 | + | |
16290 | + if (set_transfer(drive, &tfargs)) { | |
16291 | + xfer_rate = args[1]; | |
16292 | + if (ide_ata66_check(drive, &tfargs)) | |
16293 | + goto abort; | |
16294 | + } | |
16295 | + | |
16296 | + tfargs.command_type = ide_cmd_type_parser(&tfargs); | |
16297 | + err = ide_raw_taskfile(drive, &tfargs, argbuf); | |
16298 | + | |
16299 | + if (!err && xfer_rate) { | |
16300 | + /* active-retuning-calls future */ | |
16301 | + if ((HWIF(drive)->speedproc) != NULL) | |
16302 | + HWIF(drive)->speedproc(drive, xfer_rate); | |
16303 | + ide_driveid_update(drive); | |
16304 | + } | |
16305 | +abort: | |
16306 | + | |
16307 | + args[0] = tfargs.tfRegister[IDE_COMMAND_OFFSET]; | |
16308 | + args[1] = tfargs.tfRegister[IDE_FEATURE_OFFSET]; | |
16309 | + args[2] = tfargs.tfRegister[IDE_NSECTOR_OFFSET]; | |
16310 | + args[3] = 0; | |
16311 | + | |
16312 | + if (copy_to_user((void *)arg, argbuf, 4)) | |
16313 | + err = -EFAULT; | |
16314 | + if (argbuf != NULL) { | |
16315 | + if (copy_to_user((void *)arg, argbuf + 4, argsize)) | |
16316 | + err = -EFAULT; | |
16317 | + kfree(argbuf); | |
16318 | + } | |
16319 | + return err; | |
16320 | + | |
16321 | +#endif | |
16322 | + | |
16323 | +} | |
16324 | + | |
16325 | +/* | |
16326 | + * FIXME : this needs to map into at taskfile. <andre@linux-ide.org> | |
16327 | + */ | |
16328 | +int ide_task_ioctl (ide_drive_t *drive, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) | |
16329 | +{ | |
16330 | + int err = 0; | |
16331 | + byte args[7], *argbuf = args; | |
16332 | + int argsize = 7; | |
16333 | + | |
16334 | + if (copy_from_user(args, (void *)arg, 7)) | |
16335 | + return -EFAULT; | |
16336 | + err = ide_wait_cmd_task(drive, argbuf); | |
16337 | + if (copy_to_user((void *)arg, argbuf, argsize)) | |
16338 | + err = -EFAULT; | |
16339 | + return err; | |
16340 | +} | |
16341 | + | |
16342 | +EXPORT_SYMBOL(drive_is_ready); | |
16343 | +EXPORT_SYMBOL(wait_for_ready); | |
16344 | + | |
16345 | +EXPORT_SYMBOL(task_read_24); | |
16346 | +EXPORT_SYMBOL(ata_input_data); | |
16347 | +EXPORT_SYMBOL(ata_output_data); | |
16348 | +EXPORT_SYMBOL(atapi_input_bytes); | |
16349 | +EXPORT_SYMBOL(atapi_output_bytes); | |
16350 | +EXPORT_SYMBOL(taskfile_input_data); | |
16351 | +EXPORT_SYMBOL(taskfile_output_data); | |
16352 | + | |
16353 | +EXPORT_SYMBOL(ide_wait_stat); | |
16354 | +EXPORT_SYMBOL(do_rw_taskfile); | |
16355 | +EXPORT_SYMBOL(flagged_taskfile); | |
16356 | +EXPORT_SYMBOL(ide_end_taskfile); | |
16357 | + | |
16358 | +EXPORT_SYMBOL(set_multmode_intr); | |
16359 | +EXPORT_SYMBOL(set_geometry_intr); | |
16360 | +EXPORT_SYMBOL(recal_intr); | |
16361 | + | |
16362 | +EXPORT_SYMBOL(task_no_data_intr); | |
16363 | +EXPORT_SYMBOL(task_in_intr); | |
16364 | +EXPORT_SYMBOL(task_mulin_intr); | |
16365 | +EXPORT_SYMBOL(pre_task_out_intr); | |
16366 | +EXPORT_SYMBOL(task_out_intr); | |
16367 | +EXPORT_SYMBOL(pre_task_mulout_intr); | |
16368 | +EXPORT_SYMBOL(task_mulout_intr); | |
16369 | + | |
16370 | +EXPORT_SYMBOL(ide_init_drive_taskfile); | |
16371 | +EXPORT_SYMBOL(ide_raw_taskfile); | |
16372 | +EXPORT_SYMBOL(ide_pre_handler_parser); | |
16373 | +EXPORT_SYMBOL(ide_handler_parser); | |
16374 | +EXPORT_SYMBOL(ide_post_handler_parser); | |
16375 | +EXPORT_SYMBOL(ide_cmd_type_parser); | |
16376 | +EXPORT_SYMBOL(ide_taskfile_ioctl); | |
16377 | +EXPORT_SYMBOL(ide_cmd_ioctl); | |
16378 | +EXPORT_SYMBOL(ide_task_ioctl); | |
16379 | + | |
16380 | +/* | |
16381 | + * Beginning of Taskfile OPCODE Library and feature sets. | |
16382 | + */ | |
16383 | + | |
16384 | +/* | |
16385 | + * All hosts that use the 80c ribbon must use! | |
16386 | + * The name is derived from upper byte of word 93 and the 80c ribbon. | |
16387 | + */ | |
16388 | +byte eighty_ninty_three (ide_drive_t *drive) | |
16389 | +{ | |
16390 | +#if 0 | |
16391 | + if (!HWIF(drive)->udma_four) | |
16392 | + return 0; | |
16393 | + | |
16394 | + if (drive->id->major_rev_num) { | |
16395 | + int hssbd = 0; | |
16396 | + int i; | |
16397 | + /* | |
16398 | + * Determime highest Supported SPEC | |
16399 | + */ | |
16400 | + for (i=1; i<=15; i++) | |
16401 | + if (drive->id->major_rev_num & (1<<i)) | |
16402 | + hssbd++; | |
16403 | + | |
16404 | + switch (hssbd) { | |
16405 | + case 7: | |
16406 | + | |
16407 | + case 6: | |
16408 | + case 5: | |
16409 | + /* ATA-4 and older do not support above Ultra 33 */ | |
16410 | + default: | |
16411 | + return 0; | |
16412 | + } | |
16413 | + } | |
16414 | + | |
16415 | + return ((byte) ( | |
16416 | +#ifndef CONFIG_IDEDMA_IVB | |
16417 | + (drive->id->hw_config & 0x4000) && | |
16418 | +#endif /* CONFIG_IDEDMA_IVB */ | |
16419 | + (drive->id->hw_config & 0x6000)) ? 1 : 0); | |
16420 | + | |
16421 | +#else | |
16422 | + | |
16423 | + return ((byte) ((HWIF(drive)->udma_four) && | |
16424 | +#ifndef CONFIG_IDEDMA_IVB | |
16425 | + (drive->id->hw_config & 0x4000) && | |
16426 | +#endif /* CONFIG_IDEDMA_IVB */ | |
16427 | + (drive->id->hw_config & 0x6000)) ? 1 : 0); | |
16428 | +#endif | |
16429 | +} | |
16430 | + | |
16431 | +int ide_ata66_check (ide_drive_t *drive, ide_task_t *args) | |
16432 | +{ | |
16433 | + if (!HWIF(drive)->udma_four) { | |
16434 | + printk("%s: Speed warnings UDMA 3/4/5 is not functional.\n", | |
16435 | + HWIF(drive)->name); | |
16436 | + return 1; | |
16437 | + } | |
16438 | + if ((args->tfRegister[IDE_COMMAND_OFFSET] == WIN_SETFEATURES) && | |
16439 | + (args->tfRegister[IDE_SECTOR_OFFSET] > XFER_UDMA_2) && | |
16440 | + (args->tfRegister[IDE_FEATURE_OFFSET] == SETFEATURES_XFER)) { | |
16441 | +#ifndef CONFIG_IDEDMA_IVB | |
16442 | + if ((drive->id->hw_config & 0x6000) == 0) { | |
16443 | +#else /* !CONFIG_IDEDMA_IVB */ | |
16444 | + if (((drive->id->hw_config & 0x2000) == 0) || | |
16445 | + ((drive->id->hw_config & 0x4000) == 0)) { | |
16446 | +#endif /* CONFIG_IDEDMA_IVB */ | |
16447 | + printk("%s: Speed warnings UDMA 3/4/5 is not functional.\n", drive->name); | |
16448 | + return 1; | |
16449 | + } | |
16450 | + } | |
16451 | + return 0; | |
16452 | +} | |
16453 | + | |
16454 | +/* | |
16455 | + * Backside of HDIO_DRIVE_CMD call of SETFEATURES_XFER. | |
16456 | + * 1 : Safe to update drive->id DMA registers. | |
16457 | + * 0 : OOPs not allowed. | |
16458 | + */ | |
16459 | +int set_transfer (ide_drive_t *drive, ide_task_t *args) | |
16460 | +{ | |
16461 | + if ((args->tfRegister[IDE_COMMAND_OFFSET] == WIN_SETFEATURES) && | |
16462 | + (args->tfRegister[IDE_SECTOR_OFFSET] >= XFER_SW_DMA_0) && | |
16463 | + (args->tfRegister[IDE_FEATURE_OFFSET] == SETFEATURES_XFER) && | |
16464 | + (drive->id->dma_ultra || | |
16465 | + drive->id->dma_mword || | |
16466 | + drive->id->dma_1word)) | |
16467 | + return 1; | |
16468 | + | |
16469 | + return 0; | |
16470 | +} | |
16471 | + | |
16472 | +byte ide_auto_reduce_xfer (ide_drive_t *drive) | |
16473 | +{ | |
16474 | + if (!drive->crc_count) | |
16475 | + return drive->current_speed; | |
16476 | + drive->crc_count = 0; | |
16477 | + | |
16478 | + switch(drive->current_speed) { | |
16479 | + case XFER_UDMA_7: return XFER_UDMA_6; | |
16480 | + case XFER_UDMA_6: return XFER_UDMA_5; | |
16481 | + case XFER_UDMA_5: return XFER_UDMA_4; | |
16482 | + case XFER_UDMA_4: return XFER_UDMA_3; | |
16483 | + case XFER_UDMA_3: return XFER_UDMA_2; | |
16484 | + case XFER_UDMA_2: return XFER_UDMA_1; | |
16485 | + case XFER_UDMA_1: return XFER_UDMA_0; | |
16486 | + /* | |
16487 | + * OOPS we do not goto non Ultra DMA modes | |
16488 | + * without iCRC's available we force | |
16489 | + * the system to PIO and make the user | |
16490 | + * invoke the ATA-1 ATA-2 DMA modes. | |
16491 | + */ | |
16492 | + case XFER_UDMA_0: | |
16493 | + default: return XFER_PIO_4; | |
16494 | + } | |
16495 | +} | |
16496 | + | |
16497 | +int taskfile_lib_get_identify (ide_drive_t *drive, byte *buf) | |
16498 | +{ | |
16499 | + ide_task_t args; | |
16500 | + memset(&args, 0, sizeof(ide_task_t)); | |
16501 | + args.tfRegister[IDE_NSECTOR_OFFSET] = 0x01; | |
16502 | + if (drive->media == ide_disk) | |
16503 | + args.tfRegister[IDE_COMMAND_OFFSET] = WIN_IDENTIFY; | |
16504 | + else | |
16505 | + args.tfRegister[IDE_COMMAND_OFFSET] = WIN_PIDENTIFY; | |
16506 | + args.command_type = ide_cmd_type_parser(&args); | |
16507 | + return ide_raw_taskfile(drive, &args, buf); | |
16508 | +} | |
16509 | + | |
16510 | +/* | |
16511 | + * Update the | |
16512 | + */ | |
16513 | +int ide_driveid_update (ide_drive_t *drive) | |
16514 | +{ | |
16515 | +#if 0 | |
16516 | + struct hd_driveid *id; | |
16517 | + | |
16518 | + id = kmalloc(SECTOR_WORDS*4, GFP_ATOMIC); | |
16519 | + if (!id) | |
16520 | + return 0; | |
16521 | + | |
16522 | + taskfile_lib_get_identify(drive, (char *)&id); | |
16523 | + | |
16524 | + ide_fix_driveid(id); | |
16525 | + if (id) { | |
16526 | + drive->id->dma_ultra = id->dma_ultra; | |
16527 | + drive->id->dma_mword = id->dma_mword; | |
16528 | + drive->id->dma_1word = id->dma_1word; | |
16529 | + /* anything more ? */ | |
16530 | + kfree(id); | |
16531 | + } | |
16532 | + return 1; | |
16533 | +#else | |
16534 | + /* | |
16535 | + * Re-read drive->id for possible DMA mode | |
16536 | + * change (copied from ide-probe.c) | |
16537 | + */ | |
16538 | + struct hd_driveid *id; | |
16539 | + unsigned long timeout, flags; | |
16540 | + | |
16541 | + SELECT_MASK(HWIF(drive), drive, 1); | |
16542 | + if (IDE_CONTROL_REG) | |
16543 | + OUT_BYTE(drive->ctl,IDE_CONTROL_REG); | |
16544 | + ide_delay_50ms(); | |
16545 | + OUT_BYTE(WIN_IDENTIFY, IDE_COMMAND_REG); | |
16546 | + timeout = jiffies + WAIT_WORSTCASE; | |
16547 | + do { | |
16548 | + if (time_after(jiffies, timeout)) { | |
16549 | + SELECT_MASK(HWIF(drive), drive, 0); | |
16550 | + return 0; /* drive timed-out */ | |
16551 | + } | |
16552 | + ide_delay_50ms(); /* give drive a breather */ | |
16553 | + } while (IN_BYTE(IDE_ALTSTATUS_REG) & BUSY_STAT); | |
16554 | + ide_delay_50ms(); /* wait for IRQ and DRQ_STAT */ | |
16555 | + if (!OK_STAT(GET_STAT(),DRQ_STAT,BAD_R_STAT)) { | |
16556 | + SELECT_MASK(HWIF(drive), drive, 0); | |
16557 | + printk("%s: CHECK for good STATUS\n", drive->name); | |
16558 | + return 0; | |
16559 | + } | |
16560 | + local_irq_save(flags); | |
16561 | + SELECT_MASK(HWIF(drive), drive, 0); | |
16562 | + id = kmalloc(SECTOR_WORDS*4, GFP_ATOMIC); | |
16563 | + if (!id) { | |
16564 | + local_irq_restore(flags); | |
16565 | + return 0; | |
16566 | + } | |
16567 | + ata_input_data(drive, id, SECTOR_WORDS); | |
16568 | + (void) GET_STAT(); /* clear drive IRQ */ | |
16569 | + local_irq_enable(); | |
16570 | + local_irq_restore(flags); | |
16571 | + ide_fix_driveid(id); | |
16572 | + if (id) { | |
16573 | + drive->id->dma_ultra = id->dma_ultra; | |
16574 | + drive->id->dma_mword = id->dma_mword; | |
16575 | + drive->id->dma_1word = id->dma_1word; | |
16576 | + /* anything more ? */ | |
16577 | + kfree(id); | |
16578 | + } | |
16579 | + | |
16580 | + return 1; | |
16581 | +#endif | |
16582 | +} | |
16583 | + | |
16584 | + | |
16585 | +/* | |
16586 | + * Similar to ide_wait_stat(), except it never calls ide_error internally. | |
16587 | + * This is a kludge to handle the new ide_config_drive_speed() function, | |
16588 | + * and should not otherwise be used anywhere. Eventually, the tuneproc's | |
16589 | + * should be updated to return ide_startstop_t, in which case we can get | |
16590 | + * rid of this abomination again. :) -ml | |
16591 | + * | |
16592 | + * It is gone.......... | |
16593 | + * | |
16594 | + * const char *msg == consider adding for verbose errors. | |
16595 | + */ | |
16596 | +int ide_config_drive_speed (ide_drive_t *drive, byte speed) | |
16597 | +{ | |
16598 | + ide_hwif_t *hwif = HWIF(drive); | |
16599 | + int i, error = 1; | |
16600 | + byte stat; | |
16601 | + | |
16602 | +#if defined(CONFIG_BLK_DEV_IDEDMA) && !defined(CONFIG_DMA_NONPCI) | |
16603 | + hwif->dmaproc(ide_dma_host_off, drive); | |
16604 | +#endif /* (CONFIG_BLK_DEV_IDEDMA) && !(CONFIG_DMA_NONPCI) */ | |
16605 | + | |
16606 | + /* | |
16607 | + * Don't use ide_wait_cmd here - it will | |
16608 | + * attempt to set_geometry and recalibrate, | |
16609 | + * but for some reason these don't work at | |
16610 | + * this point (lost interrupt). | |
16611 | + */ | |
16612 | + /* | |
16613 | + * Select the drive, and issue the SETFEATURES command | |
16614 | + */ | |
16615 | + disable_irq(hwif->irq); /* disable_irq_nosync ?? */ | |
16616 | + udelay(1); | |
16617 | + SELECT_DRIVE(HWIF(drive), drive); | |
16618 | + SELECT_MASK(HWIF(drive), drive, 0); | |
16619 | + udelay(1); | |
16620 | + if (IDE_CONTROL_REG) | |
16621 | + OUT_BYTE(drive->ctl | 2, IDE_CONTROL_REG); | |
16622 | + OUT_BYTE(speed, IDE_NSECTOR_REG); | |
16623 | + OUT_BYTE(SETFEATURES_XFER, IDE_FEATURE_REG); | |
16624 | + OUT_BYTE(WIN_SETFEATURES, IDE_COMMAND_REG); | |
16625 | + if ((IDE_CONTROL_REG) && (drive->quirk_list == 2)) | |
16626 | + OUT_BYTE(drive->ctl, IDE_CONTROL_REG); | |
16627 | + udelay(1); | |
16628 | + /* | |
16629 | + * Wait for drive to become non-BUSY | |
16630 | + */ | |
16631 | + if ((stat = GET_STAT()) & BUSY_STAT) { | |
16632 | + unsigned long flags, timeout; | |
16633 | + local_irq_set(flags); | |
16634 | + timeout = jiffies + WAIT_CMD; | |
16635 | + while ((stat = GET_STAT()) & BUSY_STAT) { | |
16636 | + if (time_after(jiffies, timeout)) | |
16637 | + break; | |
16638 | + } | |
16639 | + local_irq_restore(flags); | |
16640 | + } | |
16641 | + | |
16642 | + /* | |
16643 | + * Allow status to settle, then read it again. | |
16644 | + * A few rare drives vastly violate the 400ns spec here, | |
16645 | + * so we'll wait up to 10usec for a "good" status | |
16646 | + * rather than expensively fail things immediately. | |
16647 | + * This fix courtesy of Matthew Faupel & Niccolo Rigacci. | |
16648 | + */ | |
16649 | + for (i = 0; i < 10; i++) { | |
16650 | + udelay(1); | |
16651 | + if (OK_STAT((stat = GET_STAT()), DRIVE_READY, BUSY_STAT|DRQ_STAT|ERR_STAT)) { | |
16652 | + error = 0; | |
16653 | + break; | |
16654 | + } | |
16655 | + } | |
16656 | + | |
16657 | + SELECT_MASK(HWIF(drive), drive, 0); | |
16658 | + | |
16659 | + enable_irq(hwif->irq); | |
16660 | + | |
16661 | + if (error) { | |
16662 | + (void) ide_dump_status(drive, "set_drive_speed_status", stat); | |
16663 | + return error; | |
16664 | + } | |
16665 | + | |
16666 | + drive->id->dma_ultra &= ~0xFF00; | |
16667 | + drive->id->dma_mword &= ~0x0F00; | |
16668 | + drive->id->dma_1word &= ~0x0F00; | |
16669 | + | |
16670 | +#if defined(CONFIG_BLK_DEV_IDEDMA) && !defined(CONFIG_DMA_NONPCI) | |
16671 | + if (speed >= XFER_SW_DMA_0) | |
16672 | + hwif->dmaproc(ide_dma_host_on, drive); | |
16673 | +#endif /* (CONFIG_BLK_DEV_IDEDMA) && !(CONFIG_DMA_NONPCI) */ | |
16674 | + | |
16675 | + switch(speed) { | |
16676 | + case XFER_UDMA_7: drive->id->dma_ultra |= 0x8080; break; | |
16677 | + case XFER_UDMA_6: drive->id->dma_ultra |= 0x4040; break; | |
16678 | + case XFER_UDMA_5: drive->id->dma_ultra |= 0x2020; break; | |
16679 | + case XFER_UDMA_4: drive->id->dma_ultra |= 0x1010; break; | |
16680 | + case XFER_UDMA_3: drive->id->dma_ultra |= 0x0808; break; | |
16681 | + case XFER_UDMA_2: drive->id->dma_ultra |= 0x0404; break; | |
16682 | + case XFER_UDMA_1: drive->id->dma_ultra |= 0x0202; break; | |
16683 | + case XFER_UDMA_0: drive->id->dma_ultra |= 0x0101; break; | |
16684 | + case XFER_MW_DMA_2: drive->id->dma_mword |= 0x0404; break; | |
16685 | + case XFER_MW_DMA_1: drive->id->dma_mword |= 0x0202; break; | |
16686 | + case XFER_MW_DMA_0: drive->id->dma_mword |= 0x0101; break; | |
16687 | + case XFER_SW_DMA_2: drive->id->dma_1word |= 0x0404; break; | |
16688 | + case XFER_SW_DMA_1: drive->id->dma_1word |= 0x0202; break; | |
16689 | + case XFER_SW_DMA_0: drive->id->dma_1word |= 0x0101; break; | |
16690 | + default: break; | |
16691 | + } | |
16692 | + if (!drive->init_speed) | |
16693 | + drive->init_speed = speed; | |
16694 | + drive->current_speed = speed; | |
16695 | + return error; | |
16696 | +} | |
16697 | + | |
16698 | +EXPORT_SYMBOL(eighty_ninty_three); | |
16699 | +EXPORT_SYMBOL(ide_auto_reduce_xfer); | |
16700 | +EXPORT_SYMBOL(set_transfer); | |
16701 | +EXPORT_SYMBOL(taskfile_lib_get_identify); | |
16702 | +EXPORT_SYMBOL(ide_driveid_update); | |
16703 | +EXPORT_SYMBOL(ide_config_drive_speed); | |
16704 | + | |
16705 | +#ifdef CONFIG_PKT_TASK_IOCTL | |
16706 | + | |
16707 | +#if 0 | |
16708 | +{ | |
16709 | + | |
16710 | +{ /* start cdrom */ | |
16711 | + | |
16712 | + struct cdrom_info *info = drive->driver_data; | |
16713 | + | |
16714 | + if (info->dma) { | |
16715 | + if (info->cmd == READ) { | |
16716 | + info->dma = !HWIF(drive)->dmaproc(ide_dma_read, drive); | |
16717 | + } else if (info->cmd == WRITE) { | |
16718 | + info->dma = !HWIF(drive)->dmaproc(ide_dma_write, drive); | |
16719 | + } else { | |
16720 | + printk("ide-cd: DMA set, but not allowed\n"); | |
16721 | + } | |
16722 | + } | |
16723 | + | |
16724 | + /* Set up the controller registers. */ | |
16725 | + OUT_BYTE (info->dma, IDE_FEATURE_REG); | |
16726 | + OUT_BYTE (0, IDE_NSECTOR_REG); | |
16727 | + OUT_BYTE (0, IDE_SECTOR_REG); | |
16728 | + | |
16729 | + OUT_BYTE (xferlen & 0xff, IDE_LCYL_REG); | |
16730 | + OUT_BYTE (xferlen >> 8 , IDE_HCYL_REG); | |
16731 | + if (IDE_CONTROL_REG) | |
16732 | + OUT_BYTE (drive->ctl, IDE_CONTROL_REG); | |
16733 | + | |
16734 | + if (info->dma) | |
16735 | + (void) (HWIF(drive)->dmaproc(ide_dma_begin, drive)); | |
16736 | + | |
16737 | + if (CDROM_CONFIG_FLAGS (drive)->drq_interrupt) { | |
16738 | + ide_set_handler (drive, handler, WAIT_CMD, cdrom_timer_expiry); | |
16739 | + OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG); /* packet command */ | |
16740 | + return ide_started; | |
16741 | + } else { | |
16742 | + OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG); /* packet command */ | |
16743 | + return (*handler) (drive); | |
16744 | + } | |
16745 | + | |
16746 | +} /* end cdrom */ | |
16747 | + | |
16748 | +{ /* start floppy */ | |
16749 | + | |
16750 | + idefloppy_floppy_t *floppy = drive->driver_data; | |
16751 | + idefloppy_bcount_reg_t bcount; | |
16752 | + int dma_ok = 0; | |
16753 | + | |
16754 | + floppy->pc=pc; /* Set the current packet command */ | |
16755 | + | |
16756 | + pc->retries++; | |
16757 | + pc->actually_transferred=0; /* We haven't transferred any data yet */ | |
16758 | + pc->current_position=pc->buffer; | |
16759 | + bcount.all = IDE_MIN(pc->request_transfer, 63 * 1024); | |
16760 | + | |
16761 | +#ifdef CONFIG_BLK_DEV_IDEDMA | |
16762 | + if (test_and_clear_bit (PC_DMA_ERROR, &pc->flags)) { | |
16763 | + (void) HWIF(drive)->dmaproc(ide_dma_off, drive); | |
16764 | + } | |
16765 | + if (test_bit (PC_DMA_RECOMMENDED, &pc->flags) && drive->using_dma) | |
16766 | + dma_ok=!HWIF(drive)->dmaproc(test_bit (PC_WRITING, &pc->flags) ? ide_dma_write : ide_dma_read, drive); | |
16767 | +#endif /* CONFIG_BLK_DEV_IDEDMA */ | |
16768 | + | |
16769 | + if (IDE_CONTROL_REG) | |
16770 | + OUT_BYTE (drive->ctl,IDE_CONTROL_REG); | |
16771 | + OUT_BYTE (dma_ok ? 1:0,IDE_FEATURE_REG); /* Use PIO/DMA */ | |
16772 | + OUT_BYTE (bcount.b.high,IDE_BCOUNTH_REG); | |
16773 | + OUT_BYTE (bcount.b.low,IDE_BCOUNTL_REG); | |
16774 | + OUT_BYTE (drive->select.all,IDE_SELECT_REG); | |
16775 | + | |
16776 | +#ifdef CONFIG_BLK_DEV_IDEDMA | |
16777 | + if (dma_ok) { /* Begin DMA, if necessary */ | |
16778 | + set_bit (PC_DMA_IN_PROGRESS, &pc->flags); | |
16779 | + (void) (HWIF(drive)->dmaproc(ide_dma_begin, drive)); | |
16780 | + } | |
16781 | +#endif /* CONFIG_BLK_DEV_IDEDMA */ | |
16782 | + | |
16783 | +} /* end floppy */ | |
16784 | + | |
16785 | +{ /* start tape */ | |
16786 | + | |
16787 | + idetape_tape_t *tape = drive->driver_data; | |
16788 | + | |
16789 | +#ifdef CONFIG_BLK_DEV_IDEDMA | |
16790 | + if (test_and_clear_bit (PC_DMA_ERROR, &pc->flags)) { | |
16791 | + printk (KERN_WARNING "ide-tape: DMA disabled, reverting to PIO\n"); | |
16792 | + (void) HWIF(drive)->dmaproc(ide_dma_off, drive); | |
16793 | + } | |
16794 | + if (test_bit (PC_DMA_RECOMMENDED, &pc->flags) && drive->using_dma) | |
16795 | + dma_ok=!HWIF(drive)->dmaproc(test_bit (PC_WRITING, &pc->flags) ? ide_dma_write : ide_dma_read, drive); | |
16796 | +#endif /* CONFIG_BLK_DEV_IDEDMA */ | |
16797 | + | |
16798 | + if (IDE_CONTROL_REG) | |
16799 | + OUT_BYTE (drive->ctl,IDE_CONTROL_REG); | |
16800 | + OUT_BYTE (dma_ok ? 1:0,IDE_FEATURE_REG); /* Use PIO/DMA */ | |
16801 | + OUT_BYTE (bcount.b.high,IDE_BCOUNTH_REG); | |
16802 | + OUT_BYTE (bcount.b.low,IDE_BCOUNTL_REG); | |
16803 | + OUT_BYTE (drive->select.all,IDE_SELECT_REG); | |
16804 | +#ifdef CONFIG_BLK_DEV_IDEDMA | |
16805 | + if (dma_ok) { /* Begin DMA, if necessary */ | |
16806 | + set_bit (PC_DMA_IN_PROGRESS, &pc->flags); | |
16807 | + (void) (HWIF(drive)->dmaproc(ide_dma_begin, drive)); | |
16808 | + } | |
16809 | +#endif /* CONFIG_BLK_DEV_IDEDMA */ | |
16810 | + if (test_bit(IDETAPE_DRQ_INTERRUPT, &tape->flags)) { | |
16811 | + ide_set_handler(drive, &idetape_transfer_pc, IDETAPE_WAIT_CMD, NULL); | |
16812 | + OUT_BYTE(WIN_PACKETCMD, IDE_COMMAND_REG); | |
16813 | + return ide_started; | |
16814 | + } else { | |
16815 | + OUT_BYTE(WIN_PACKETCMD, IDE_COMMAND_REG); | |
16816 | + return idetape_transfer_pc(drive); | |
16817 | + } | |
16818 | + | |
16819 | +} /* end tape */ | |
16820 | + | |
16821 | +} | |
16822 | +#endif | |
16823 | + | |
16824 | +int pkt_taskfile_ioctl (ide_drive_t *drive, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) | |
16825 | +{ | |
16826 | +#if 0 | |
16827 | + switch(req_task->data_phase) { | |
16828 | + case TASKFILE_P_OUT_DMAQ: | |
16829 | + case TASKFILE_P_IN_DMAQ: | |
16830 | + case TASKFILE_P_OUT_DMA: | |
16831 | + case TASKFILE_P_IN_DMA: | |
16832 | + case TASKFILE_P_OUT: | |
16833 | + case TASKFILE_P_IN: | |
16834 | + } | |
16835 | +#endif | |
16836 | + return -ENOMSG; | |
16837 | +} | |
16838 | + | |
16839 | +EXPORT_SYMBOL(pkt_taskfile_ioctl); | |
16840 | + | |
16841 | +#endif /* CONFIG_PKT_TASK_IOCTL */ | |
16842 | diff -Nur linux.org/drivers/ide/ide-timing.h linux/drivers/ide/ide-timing.h | |
16843 | --- linux.org/drivers/ide/ide-timing.h Sat Feb 3 20:27:43 2001 | |
16844 | +++ linux/drivers/ide/ide-timing.h Thu Jul 18 14:23:01 2002 | |
16845 | @@ -2,11 +2,9 @@ | |
16846 | #define _IDE_TIMING_H | |
16847 | ||
16848 | /* | |
16849 | - * $Id$ | |
16850 | + * $Id$ | |
16851 | * | |
16852 | - * Copyright (c) 1999-2000 Vojtech Pavlik | |
16853 | - * | |
16854 | - * Sponsored by SuSE | |
16855 | + * Copyright (c) 1999-2001 Vojtech Pavlik | |
16856 | */ | |
16857 | ||
16858 | /* | |
16859 | @@ -25,16 +23,14 @@ | |
16860 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
16861 | * | |
16862 | * Should you need to contact me, the author, you can do so either by | |
16863 | - * e-mail - mail your message to <vojtech@suse.cz>, or by paper mail: | |
16864 | - * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic | |
16865 | + * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail: | |
16866 | + * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic | |
16867 | */ | |
16868 | ||
16869 | #include <linux/hdreg.h> | |
16870 | ||
16871 | -#ifndef XFER_PIO_5 | |
16872 | #define XFER_PIO_5 0x0d | |
16873 | #define XFER_UDMA_SLOW 0x4f | |
16874 | -#endif | |
16875 | ||
16876 | struct ide_timing { | |
16877 | short mode; | |
16878 | @@ -49,13 +45,15 @@ | |
16879 | }; | |
16880 | ||
16881 | /* | |
16882 | - * PIO 0-5, MWDMA 0-2 and UDMA 0-5 timings (in nanoseconds). | |
16883 | + * PIO 0-5, MWDMA 0-2 and UDMA 0-6 timings (in nanoseconds). | |
16884 | * These were taken from ATA/ATAPI-6 standard, rev 0a, except | |
16885 | - * for PIO 5, which is a nonstandard extension. | |
16886 | + * for PIO 5, which is a nonstandard extension and UDMA6, which | |
16887 | + * is currently supported only by Maxtor drives. | |
16888 | */ | |
16889 | ||
16890 | static struct ide_timing ide_timing[] = { | |
16891 | ||
16892 | + { XFER_UDMA_6, 0, 0, 0, 0, 0, 0, 0, 15 }, | |
16893 | { XFER_UDMA_5, 0, 0, 0, 0, 0, 0, 0, 20 }, | |
16894 | { XFER_UDMA_4, 0, 0, 0, 0, 0, 0, 0, 30 }, | |
16895 | { XFER_UDMA_3, 0, 0, 0, 0, 0, 0, 0, 45 }, | |
16896 | @@ -105,6 +103,7 @@ | |
16897 | #define EZ(v,unit) ((v)?ENOUGH(v,unit):0) | |
16898 | ||
16899 | #define XFER_MODE 0xf0 | |
16900 | +#define XFER_UDMA_133 0x48 | |
16901 | #define XFER_UDMA_100 0x44 | |
16902 | #define XFER_UDMA_66 0x42 | |
16903 | #define XFER_UDMA 0x40 | |
16904 | @@ -123,6 +122,9 @@ | |
16905 | ||
16906 | if ((map & XFER_UDMA) && (id->field_valid & 4)) { /* Want UDMA and UDMA bitmap valid */ | |
16907 | ||
16908 | + if ((map & XFER_UDMA_133) == XFER_UDMA_133) | |
16909 | + if ((best = (id->dma_ultra & 0x0040) ? XFER_UDMA_6 : 0)) return best; | |
16910 | + | |
16911 | if ((map & XFER_UDMA_100) == XFER_UDMA_100) | |
16912 | if ((best = (id->dma_ultra & 0x0020) ? XFER_UDMA_5 : 0)) return best; | |
16913 | ||
16914 | @@ -174,14 +176,14 @@ | |
16915 | ||
16916 | static void ide_timing_quantize(struct ide_timing *t, struct ide_timing *q, int T, int UT) | |
16917 | { | |
16918 | - q->setup = EZ(t->setup, T); | |
16919 | - q->act8b = EZ(t->act8b, T); | |
16920 | - q->rec8b = EZ(t->rec8b, T); | |
16921 | - q->cyc8b = EZ(t->cyc8b, T); | |
16922 | - q->active = EZ(t->active, T); | |
16923 | - q->recover = EZ(t->recover, T); | |
16924 | - q->cycle = EZ(t->cycle, T); | |
16925 | - q->udma = EZ(t->udma, UT); | |
16926 | + q->setup = EZ(t->setup * 1000, T); | |
16927 | + q->act8b = EZ(t->act8b * 1000, T); | |
16928 | + q->rec8b = EZ(t->rec8b * 1000, T); | |
16929 | + q->cyc8b = EZ(t->cyc8b * 1000, T); | |
16930 | + q->active = EZ(t->active * 1000, T); | |
16931 | + q->recover = EZ(t->recover * 1000, T); | |
16932 | + q->cycle = EZ(t->cycle * 1000, T); | |
16933 | + q->udma = EZ(t->udma * 1000, UT); | |
16934 | } | |
16935 | ||
16936 | static void ide_timing_merge(struct ide_timing *a, struct ide_timing *b, struct ide_timing *m, unsigned int what) | |
16937 | diff -Nur linux.org/drivers/ide/ide.c linux/drivers/ide/ide.c | |
16938 | --- linux.org/drivers/ide/ide.c Mon Feb 25 20:37:57 2002 | |
16939 | +++ linux/drivers/ide/ide.c Thu Jul 18 14:24:33 2002 | |
16940 | @@ -149,6 +149,7 @@ | |
16941 | #include <linux/ide.h> | |
16942 | #include <linux/devfs_fs_kernel.h> | |
16943 | #include <linux/completion.h> | |
16944 | +#include <linux/reboot.h> | |
16945 | ||
16946 | #include <asm/byteorder.h> | |
16947 | #include <asm/irq.h> | |
16948 | @@ -206,13 +207,12 @@ | |
16949 | unsigned long t, flags; | |
16950 | int i; | |
16951 | ||
16952 | - __save_flags(flags); /* local CPU only */ | |
16953 | - __cli(); /* local CPU only */ | |
16954 | + local_irq_save(flags); | |
16955 | t = jiffies * 11932; | |
16956 | outb_p(0, 0x43); | |
16957 | i = inb_p(0x40); | |
16958 | - i |= inb(0x40) << 8; | |
16959 | - __restore_flags(flags); /* local CPU only */ | |
16960 | + i |= IN_BYTE(0x40) << 8; | |
16961 | + local_irq_restore(flags); | |
16962 | return (t - i); | |
16963 | } | |
16964 | #endif /* DISK_RECOVERY_TIME */ | |
16965 | @@ -362,197 +362,17 @@ | |
16966 | return system_bus_speed; | |
16967 | } | |
16968 | ||
16969 | -#if SUPPORT_VLB_SYNC | |
16970 | -/* | |
16971 | - * Some localbus EIDE interfaces require a special access sequence | |
16972 | - * when using 32-bit I/O instructions to transfer data. We call this | |
16973 | - * the "vlb_sync" sequence, which consists of three successive reads | |
16974 | - * of the sector count register location, with interrupts disabled | |
16975 | - * to ensure that the reads all happen together. | |
16976 | - */ | |
16977 | -static inline void do_vlb_sync (ide_ioreg_t port) { | |
16978 | - (void) inb (port); | |
16979 | - (void) inb (port); | |
16980 | - (void) inb (port); | |
16981 | -} | |
16982 | -#endif /* SUPPORT_VLB_SYNC */ | |
16983 | - | |
16984 | -/* | |
16985 | - * This is used for most PIO data transfers *from* the IDE interface | |
16986 | - */ | |
16987 | -void ide_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount) | |
16988 | -{ | |
16989 | - byte io_32bit; | |
16990 | - | |
16991 | - /* first check if this controller has defined a special function | |
16992 | - * for handling polled ide transfers | |
16993 | - */ | |
16994 | - | |
16995 | - if(HWIF(drive)->ideproc) { | |
16996 | - HWIF(drive)->ideproc(ideproc_ide_input_data, | |
16997 | - drive, buffer, wcount); | |
16998 | - return; | |
16999 | - } | |
17000 | - | |
17001 | - io_32bit = drive->io_32bit; | |
17002 | - | |
17003 | - if (io_32bit) { | |
17004 | -#if SUPPORT_VLB_SYNC | |
17005 | - if (io_32bit & 2) { | |
17006 | - unsigned long flags; | |
17007 | - __save_flags(flags); /* local CPU only */ | |
17008 | - __cli(); /* local CPU only */ | |
17009 | - do_vlb_sync(IDE_NSECTOR_REG); | |
17010 | - insl(IDE_DATA_REG, buffer, wcount); | |
17011 | - __restore_flags(flags); /* local CPU only */ | |
17012 | - } else | |
17013 | -#endif /* SUPPORT_VLB_SYNC */ | |
17014 | - insl(IDE_DATA_REG, buffer, wcount); | |
17015 | - } else { | |
17016 | -#if SUPPORT_SLOW_DATA_PORTS | |
17017 | - if (drive->slow) { | |
17018 | - unsigned short *ptr = (unsigned short *) buffer; | |
17019 | - while (wcount--) { | |
17020 | - *ptr++ = inw_p(IDE_DATA_REG); | |
17021 | - *ptr++ = inw_p(IDE_DATA_REG); | |
17022 | - } | |
17023 | - } else | |
17024 | -#endif /* SUPPORT_SLOW_DATA_PORTS */ | |
17025 | - insw(IDE_DATA_REG, buffer, wcount<<1); | |
17026 | - } | |
17027 | -} | |
17028 | - | |
17029 | -/* | |
17030 | - * This is used for most PIO data transfers *to* the IDE interface | |
17031 | - */ | |
17032 | -void ide_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount) | |
17033 | -{ | |
17034 | - byte io_32bit; | |
17035 | - | |
17036 | - if(HWIF(drive)->ideproc) { | |
17037 | - HWIF(drive)->ideproc(ideproc_ide_output_data, | |
17038 | - drive, buffer, wcount); | |
17039 | - return; | |
17040 | - } | |
17041 | - | |
17042 | - io_32bit = drive->io_32bit; | |
17043 | - | |
17044 | - if (io_32bit) { | |
17045 | -#if SUPPORT_VLB_SYNC | |
17046 | - if (io_32bit & 2) { | |
17047 | - unsigned long flags; | |
17048 | - __save_flags(flags); /* local CPU only */ | |
17049 | - __cli(); /* local CPU only */ | |
17050 | - do_vlb_sync(IDE_NSECTOR_REG); | |
17051 | - outsl(IDE_DATA_REG, buffer, wcount); | |
17052 | - __restore_flags(flags); /* local CPU only */ | |
17053 | - } else | |
17054 | -#endif /* SUPPORT_VLB_SYNC */ | |
17055 | - outsl(IDE_DATA_REG, buffer, wcount); | |
17056 | - } else { | |
17057 | -#if SUPPORT_SLOW_DATA_PORTS | |
17058 | - if (drive->slow) { | |
17059 | - unsigned short *ptr = (unsigned short *) buffer; | |
17060 | - while (wcount--) { | |
17061 | - outw_p(*ptr++, IDE_DATA_REG); | |
17062 | - outw_p(*ptr++, IDE_DATA_REG); | |
17063 | - } | |
17064 | - } else | |
17065 | -#endif /* SUPPORT_SLOW_DATA_PORTS */ | |
17066 | - outsw(IDE_DATA_REG, buffer, wcount<<1); | |
17067 | - } | |
17068 | -} | |
17069 | - | |
17070 | -/* | |
17071 | - * The following routines are mainly used by the ATAPI drivers. | |
17072 | - * | |
17073 | - * These routines will round up any request for an odd number of bytes, | |
17074 | - * so if an odd bytecount is specified, be sure that there's at least one | |
17075 | - * extra byte allocated for the buffer. | |
17076 | - */ | |
17077 | -void atapi_input_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount) | |
17078 | -{ | |
17079 | - if(HWIF(drive)->ideproc) { | |
17080 | - HWIF(drive)->ideproc(ideproc_atapi_input_bytes, | |
17081 | - drive, buffer, bytecount); | |
17082 | - return; | |
17083 | - } | |
17084 | - | |
17085 | - ++bytecount; | |
17086 | -#if defined(CONFIG_ATARI) || defined(CONFIG_Q40) | |
17087 | - if (MACH_IS_ATARI || MACH_IS_Q40) { | |
17088 | - /* Atari has a byte-swapped IDE interface */ | |
17089 | - insw_swapw(IDE_DATA_REG, buffer, bytecount / 2); | |
17090 | - return; | |
17091 | - } | |
17092 | -#endif /* CONFIG_ATARI */ | |
17093 | - ide_input_data (drive, buffer, bytecount / 4); | |
17094 | - if ((bytecount & 0x03) >= 2) | |
17095 | - insw (IDE_DATA_REG, ((byte *)buffer) + (bytecount & ~0x03), 1); | |
17096 | -} | |
17097 | - | |
17098 | -void atapi_output_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount) | |
17099 | -{ | |
17100 | - if(HWIF(drive)->ideproc) { | |
17101 | - HWIF(drive)->ideproc(ideproc_atapi_output_bytes, | |
17102 | - drive, buffer, bytecount); | |
17103 | - return; | |
17104 | - } | |
17105 | - | |
17106 | - ++bytecount; | |
17107 | -#if defined(CONFIG_ATARI) || defined(CONFIG_Q40) | |
17108 | - if (MACH_IS_ATARI || MACH_IS_Q40) { | |
17109 | - /* Atari has a byte-swapped IDE interface */ | |
17110 | - outsw_swapw(IDE_DATA_REG, buffer, bytecount / 2); | |
17111 | - return; | |
17112 | - } | |
17113 | -#endif /* CONFIG_ATARI */ | |
17114 | - ide_output_data (drive, buffer, bytecount / 4); | |
17115 | - if ((bytecount & 0x03) >= 2) | |
17116 | - outsw (IDE_DATA_REG, ((byte *)buffer) + (bytecount & ~0x03), 1); | |
17117 | -} | |
17118 | - | |
17119 | -/* | |
17120 | - * Needed for PCI irq sharing | |
17121 | - */ | |
17122 | -static inline int drive_is_ready (ide_drive_t *drive) | |
17123 | -{ | |
17124 | - byte stat = 0; | |
17125 | - if (drive->waiting_for_dma) | |
17126 | - return HWIF(drive)->dmaproc(ide_dma_test_irq, drive); | |
17127 | -#if 0 | |
17128 | - udelay(1); /* need to guarantee 400ns since last command was issued */ | |
17129 | -#endif | |
17130 | - | |
17131 | -#ifdef CONFIG_IDEPCI_SHARE_IRQ | |
17132 | - /* | |
17133 | - * We do a passive status test under shared PCI interrupts on | |
17134 | - * cards that truly share the ATA side interrupt, but may also share | |
17135 | - * an interrupt with another pci card/device. We make no assumptions | |
17136 | - * about possible isa-pnp and pci-pnp issues yet. | |
17137 | - */ | |
17138 | - if (IDE_CONTROL_REG) | |
17139 | - stat = GET_ALTSTAT(); | |
17140 | - else | |
17141 | -#endif /* CONFIG_IDEPCI_SHARE_IRQ */ | |
17142 | - stat = GET_STAT(); /* Note: this may clear a pending IRQ!! */ | |
17143 | - | |
17144 | - if (stat & BUSY_STAT) | |
17145 | - return 0; /* drive busy: definitely not interrupting */ | |
17146 | - return 1; /* drive ready: *might* be interrupting */ | |
17147 | -} | |
17148 | - | |
17149 | /* | |
17150 | * This is our end_request replacement function. | |
17151 | */ | |
17152 | -void ide_end_request (byte uptodate, ide_hwgroup_t *hwgroup) | |
17153 | +int ide_end_request (ide_drive_t *drive, int uptodate) | |
17154 | { | |
17155 | struct request *rq; | |
17156 | unsigned long flags; | |
17157 | - ide_drive_t *drive = hwgroup->drive; | |
17158 | + int ret = 1; | |
17159 | ||
17160 | spin_lock_irqsave(&io_request_lock, flags); | |
17161 | - rq = hwgroup->rq; | |
17162 | + rq = HWGROUP(drive)->rq; | |
17163 | ||
17164 | /* | |
17165 | * decide whether to reenable DMA -- 3 is a random magic for now, | |
17166 | @@ -560,16 +380,18 @@ | |
17167 | */ | |
17168 | if (drive->state == DMA_PIO_RETRY && drive->retry_pio <= 3) { | |
17169 | drive->state = 0; | |
17170 | - hwgroup->hwif->dmaproc(ide_dma_on, drive); | |
17171 | + HWGROUP(drive)->hwif->dmaproc(ide_dma_on, drive); | |
17172 | } | |
17173 | ||
17174 | - if (!end_that_request_first(rq, uptodate, hwgroup->drive->name)) { | |
17175 | + if (!end_that_request_first(rq, uptodate, drive->name)) { | |
17176 | add_blkdev_randomness(MAJOR(rq->rq_dev)); | |
17177 | blkdev_dequeue_request(rq); | |
17178 | - hwgroup->rq = NULL; | |
17179 | + HWGROUP(drive)->rq = NULL; | |
17180 | end_that_request_last(rq); | |
17181 | + ret = 0; | |
17182 | } | |
17183 | spin_unlock_irqrestore(&io_request_lock, flags); | |
17184 | + return ret; | |
17185 | } | |
17186 | ||
17187 | /* | |
17188 | @@ -654,7 +476,9 @@ | |
17189 | if (OK_STAT(stat=GET_STAT(), 0, BUSY_STAT)) { | |
17190 | printk("%s: ATAPI reset complete\n", drive->name); | |
17191 | } else { | |
17192 | - if (0 < (signed long)(hwgroup->poll_timeout - jiffies)) { | |
17193 | + if (time_before(jiffies, hwgroup->poll_timeout)) { | |
17194 | + if (HWGROUP(drive)->handler != NULL) /* paranoia check */ | |
17195 | + BUG(); | |
17196 | ide_set_handler (drive, &atapi_reset_pollfunc, HZ/20, NULL); | |
17197 | return ide_started; /* continue polling */ | |
17198 | } | |
17199 | @@ -679,7 +503,9 @@ | |
17200 | byte tmp; | |
17201 | ||
17202 | if (!OK_STAT(tmp=GET_STAT(), 0, BUSY_STAT)) { | |
17203 | - if (0 < (signed long)(hwgroup->poll_timeout - jiffies)) { | |
17204 | + if (time_before(jiffies, hwgroup->poll_timeout)) { | |
17205 | + if (HWGROUP(drive)->handler != NULL) /* paranoia check */ | |
17206 | + BUG(); | |
17207 | ide_set_handler (drive, &reset_pollfunc, HZ/20, NULL); | |
17208 | return ide_started; /* continue polling */ | |
17209 | } | |
17210 | @@ -772,8 +598,7 @@ | |
17211 | ide_hwif_t *hwif = HWIF(drive); | |
17212 | ide_hwgroup_t *hwgroup = HWGROUP(drive); | |
17213 | ||
17214 | - __save_flags(flags); /* local CPU only */ | |
17215 | - __cli(); /* local CPU only */ | |
17216 | + local_irq_save(flags); | |
17217 | ||
17218 | /* For an ATAPI device, first try an ATAPI SRST. */ | |
17219 | if (drive->media != ide_disk && !do_not_try_atapi) { | |
17220 | @@ -782,8 +607,10 @@ | |
17221 | udelay (20); | |
17222 | OUT_BYTE (WIN_SRST, IDE_COMMAND_REG); | |
17223 | hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE; | |
17224 | + if (HWGROUP(drive)->handler != NULL) /* paranoia check */ | |
17225 | + BUG(); | |
17226 | ide_set_handler (drive, &atapi_reset_pollfunc, HZ/20, NULL); | |
17227 | - __restore_flags (flags); /* local CPU only */ | |
17228 | + local_irq_restore(flags); | |
17229 | return ide_started; | |
17230 | } | |
17231 | ||
17232 | @@ -796,7 +623,7 @@ | |
17233 | ||
17234 | #if OK_TO_RESET_CONTROLLER | |
17235 | if (!IDE_CONTROL_REG) { | |
17236 | - __restore_flags(flags); | |
17237 | + local_irq_restore(flags); | |
17238 | return ide_stopped; | |
17239 | } | |
17240 | /* | |
17241 | @@ -809,9 +636,15 @@ | |
17242 | */ | |
17243 | OUT_BYTE(drive->ctl|6,IDE_CONTROL_REG); /* set SRST and nIEN */ | |
17244 | udelay(10); /* more than enough time */ | |
17245 | - OUT_BYTE(drive->ctl|2,IDE_CONTROL_REG); /* clear SRST, leave nIEN */ | |
17246 | + if (drive->quirk_list == 2) { | |
17247 | + OUT_BYTE(drive->ctl,IDE_CONTROL_REG); /* clear SRST and nIEN */ | |
17248 | + } else { | |
17249 | + OUT_BYTE(drive->ctl|2,IDE_CONTROL_REG); /* clear SRST, leave nIEN */ | |
17250 | + } | |
17251 | udelay(10); /* more than enough time */ | |
17252 | hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE; | |
17253 | + if (HWGROUP(drive)->handler != NULL) /* paranoia check */ | |
17254 | + BUG(); | |
17255 | ide_set_handler (drive, &reset_pollfunc, HZ/20, NULL); | |
17256 | ||
17257 | /* | |
17258 | @@ -824,7 +657,7 @@ | |
17259 | ||
17260 | #endif /* OK_TO_RESET_CONTROLLER */ | |
17261 | ||
17262 | - __restore_flags (flags); /* local CPU only */ | |
17263 | + local_irq_restore(flags); | |
17264 | return ide_started; | |
17265 | } | |
17266 | ||
17267 | @@ -836,6 +669,13 @@ | |
17268 | return do_reset1 (drive, 0); | |
17269 | } | |
17270 | ||
17271 | +static inline u32 read_24 (ide_drive_t *drive) | |
17272 | +{ | |
17273 | + return (IN_BYTE(IDE_HCYL_REG)<<16) | | |
17274 | + (IN_BYTE(IDE_LCYL_REG)<<8) | | |
17275 | + IN_BYTE(IDE_SECTOR_REG); | |
17276 | +} | |
17277 | + | |
17278 | /* | |
17279 | * Clean up after success/failure of an explicit drive cmd | |
17280 | */ | |
17281 | @@ -848,26 +688,72 @@ | |
17282 | rq = HWGROUP(drive)->rq; | |
17283 | spin_unlock_irqrestore(&io_request_lock, flags); | |
17284 | ||
17285 | - if (rq->cmd == IDE_DRIVE_CMD) { | |
17286 | - byte *args = (byte *) rq->buffer; | |
17287 | - rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT); | |
17288 | - if (args) { | |
17289 | - args[0] = stat; | |
17290 | - args[1] = err; | |
17291 | - args[2] = IN_BYTE(IDE_NSECTOR_REG); | |
17292 | - } | |
17293 | - } else if (rq->cmd == IDE_DRIVE_TASK) { | |
17294 | - byte *args = (byte *) rq->buffer; | |
17295 | - rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT); | |
17296 | - if (args) { | |
17297 | - args[0] = stat; | |
17298 | - args[1] = err; | |
17299 | - args[2] = IN_BYTE(IDE_NSECTOR_REG); | |
17300 | - args[3] = IN_BYTE(IDE_SECTOR_REG); | |
17301 | - args[4] = IN_BYTE(IDE_LCYL_REG); | |
17302 | - args[5] = IN_BYTE(IDE_HCYL_REG); | |
17303 | - args[6] = IN_BYTE(IDE_SELECT_REG); | |
17304 | + switch(rq->cmd) { | |
17305 | + case IDE_DRIVE_CMD: | |
17306 | + { | |
17307 | + byte *args = (byte *) rq->buffer; | |
17308 | + if (rq->errors == 0) | |
17309 | + rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT); | |
17310 | + | |
17311 | + if (args) { | |
17312 | + args[0] = stat; | |
17313 | + args[1] = err; | |
17314 | + args[2] = IN_BYTE(IDE_NSECTOR_REG); | |
17315 | + } | |
17316 | + break; | |
17317 | } | |
17318 | + case IDE_DRIVE_TASK: | |
17319 | + { | |
17320 | + byte *args = (byte *) rq->buffer; | |
17321 | + if (rq->errors == 0) | |
17322 | + rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT); | |
17323 | + | |
17324 | + if (args) { | |
17325 | + args[0] = stat; | |
17326 | + args[1] = err; | |
17327 | + args[2] = IN_BYTE(IDE_NSECTOR_REG); | |
17328 | + args[3] = IN_BYTE(IDE_SECTOR_REG); | |
17329 | + args[4] = IN_BYTE(IDE_LCYL_REG); | |
17330 | + args[5] = IN_BYTE(IDE_HCYL_REG); | |
17331 | + args[6] = IN_BYTE(IDE_SELECT_REG); | |
17332 | + } | |
17333 | + break; | |
17334 | + } | |
17335 | + case IDE_DRIVE_TASKFILE: | |
17336 | + { | |
17337 | + ide_task_t *args = (ide_task_t *) rq->special; | |
17338 | + if (rq->errors == 0) | |
17339 | + rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT); | |
17340 | + | |
17341 | + if (args) { | |
17342 | + if (args->tf_in_flags.b.data) { | |
17343 | + unsigned short data = IN_WORD(IDE_DATA_REG); | |
17344 | + args->tfRegister[IDE_DATA_OFFSET] = (data) & 0xFF; | |
17345 | + args->hobRegister[IDE_DATA_OFFSET_HOB] = (data >> 8) & 0xFF; | |
17346 | + } | |
17347 | + args->tfRegister[IDE_ERROR_OFFSET] = err; | |
17348 | + args->tfRegister[IDE_NSECTOR_OFFSET] = IN_BYTE(IDE_NSECTOR_REG); | |
17349 | + args->tfRegister[IDE_SECTOR_OFFSET] = IN_BYTE(IDE_SECTOR_REG); | |
17350 | + args->tfRegister[IDE_LCYL_OFFSET] = IN_BYTE(IDE_LCYL_REG); | |
17351 | + args->tfRegister[IDE_HCYL_OFFSET] = IN_BYTE(IDE_HCYL_REG); | |
17352 | + args->tfRegister[IDE_SELECT_OFFSET] = IN_BYTE(IDE_SELECT_REG); | |
17353 | + args->tfRegister[IDE_STATUS_OFFSET] = stat; | |
17354 | + | |
17355 | + if ((drive->id->command_set_2 & 0x0400) && | |
17356 | + (drive->id->cfs_enable_2 & 0x0400) && | |
17357 | + (drive->addressing == 1)) { | |
17358 | + OUT_BYTE(drive->ctl|0x80, IDE_CONTROL_REG_HOB); | |
17359 | + args->hobRegister[IDE_FEATURE_OFFSET_HOB] = IN_BYTE(IDE_FEATURE_REG); | |
17360 | + args->hobRegister[IDE_NSECTOR_OFFSET_HOB] = IN_BYTE(IDE_NSECTOR_REG); | |
17361 | + args->hobRegister[IDE_SECTOR_OFFSET_HOB] = IN_BYTE(IDE_SECTOR_REG); | |
17362 | + args->hobRegister[IDE_LCYL_OFFSET_HOB] = IN_BYTE(IDE_LCYL_REG); | |
17363 | + args->hobRegister[IDE_HCYL_OFFSET_HOB] = IN_BYTE(IDE_HCYL_REG); | |
17364 | + } | |
17365 | + } | |
17366 | + break; | |
17367 | + } | |
17368 | + default: | |
17369 | + break; | |
17370 | } | |
17371 | spin_lock_irqsave(&io_request_lock, flags); | |
17372 | blkdev_dequeue_request(rq); | |
17373 | @@ -884,8 +770,7 @@ | |
17374 | unsigned long flags; | |
17375 | byte err = 0; | |
17376 | ||
17377 | - __save_flags (flags); /* local CPU only */ | |
17378 | - ide__sti(); /* local CPU only */ | |
17379 | + local_irq_set(flags); | |
17380 | printk("%s: %s: status=0x%02x", drive->name, msg, stat); | |
17381 | #if FANCY_STATUS_DUMPS | |
17382 | printk(" { "); | |
17383 | @@ -917,19 +802,34 @@ | |
17384 | if (err & MARK_ERR) printk("AddrMarkNotFound "); | |
17385 | printk("}"); | |
17386 | if ((err & (BBD_ERR | ABRT_ERR)) == BBD_ERR || (err & (ECC_ERR|ID_ERR|MARK_ERR))) { | |
17387 | - byte cur = IN_BYTE(IDE_SELECT_REG); | |
17388 | - if (cur & 0x40) { /* using LBA? */ | |
17389 | - printk(", LBAsect=%ld", (unsigned long) | |
17390 | - ((cur&0xf)<<24) | |
17391 | - |(IN_BYTE(IDE_HCYL_REG)<<16) | |
17392 | - |(IN_BYTE(IDE_LCYL_REG)<<8) | |
17393 | - | IN_BYTE(IDE_SECTOR_REG)); | |
17394 | + if ((drive->id->command_set_2 & 0x0400) && | |
17395 | + (drive->id->cfs_enable_2 & 0x0400) && | |
17396 | + (drive->addressing == 1)) { | |
17397 | + __u64 sectors = 0; | |
17398 | + u32 low = 0, high = 0; | |
17399 | + low = read_24(drive); | |
17400 | + OUT_BYTE(drive->ctl|0x80, IDE_CONTROL_REG); | |
17401 | + high = read_24(drive); | |
17402 | + | |
17403 | + sectors = ((__u64)high << 24) | low; | |
17404 | + printk(", LBAsect=%llu, high=%d, low=%d", | |
17405 | + (unsigned long long) sectors, | |
17406 | + high, low); | |
17407 | } else { | |
17408 | - printk(", CHS=%d/%d/%d", | |
17409 | - (IN_BYTE(IDE_HCYL_REG)<<8) + | |
17410 | - IN_BYTE(IDE_LCYL_REG), | |
17411 | - cur & 0xf, | |
17412 | - IN_BYTE(IDE_SECTOR_REG)); | |
17413 | + byte cur = IN_BYTE(IDE_SELECT_REG); | |
17414 | + if (cur & 0x40) { /* using LBA? */ | |
17415 | + printk(", LBAsect=%ld", (unsigned long) | |
17416 | + ((cur&0xf)<<24) | |
17417 | + |(IN_BYTE(IDE_HCYL_REG)<<16) | |
17418 | + |(IN_BYTE(IDE_LCYL_REG)<<8) | |
17419 | + | IN_BYTE(IDE_SECTOR_REG)); | |
17420 | + } else { | |
17421 | + printk(", CHS=%d/%d/%d", | |
17422 | + (IN_BYTE(IDE_HCYL_REG)<<8) + | |
17423 | + IN_BYTE(IDE_LCYL_REG), | |
17424 | + cur & 0xf, | |
17425 | + IN_BYTE(IDE_SECTOR_REG)); | |
17426 | + } | |
17427 | } | |
17428 | if (HWGROUP(drive) && HWGROUP(drive)->rq) | |
17429 | printk(", sector=%ld", HWGROUP(drive)->rq->sector); | |
17430 | @@ -938,7 +838,7 @@ | |
17431 | #endif /* FANCY_STATUS_DUMPS */ | |
17432 | printk("\n"); | |
17433 | } | |
17434 | - __restore_flags (flags); /* local CPU only */ | |
17435 | + local_irq_restore(flags); | |
17436 | return err; | |
17437 | } | |
17438 | ||
17439 | @@ -959,11 +859,15 @@ | |
17440 | u32 buffer[16]; | |
17441 | unsigned int wcount = (i > 16) ? 16 : i; | |
17442 | i -= wcount; | |
17443 | - ide_input_data (drive, buffer, wcount); | |
17444 | + ata_input_data (drive, buffer, wcount); | |
17445 | } | |
17446 | } | |
17447 | ||
17448 | /* | |
17449 | + * FIXME Add an ATAPI error | |
17450 | + */ | |
17451 | + | |
17452 | +/* | |
17453 | * ide_error() takes action based on the error returned by the drive. | |
17454 | */ | |
17455 | ide_startstop_t ide_error (ide_drive_t *drive, const char *msg, byte stat) | |
17456 | @@ -980,9 +884,18 @@ | |
17457 | ide_end_drive_cmd(drive, stat, err); | |
17458 | return ide_stopped; | |
17459 | } | |
17460 | + if (rq->cmd == IDE_DRIVE_TASKFILE) { | |
17461 | + rq->errors = 1; | |
17462 | + ide_end_drive_cmd(drive, stat, err); | |
17463 | +// ide_end_taskfile(drive, stat, err); | |
17464 | + return ide_stopped; | |
17465 | + } | |
17466 | + | |
17467 | if (stat & BUSY_STAT || ((stat & WRERR_STAT) && !drive->nowerr)) { /* other bits are useless when BUSY */ | |
17468 | rq->errors |= ERROR_RESET; | |
17469 | } else { | |
17470 | + | |
17471 | +/* ide_disk */ | |
17472 | if (drive->media == ide_disk && (stat & ERR_STAT)) { | |
17473 | /* err has different meaning on cdrom and tape */ | |
17474 | if (err == ABRT_ERR) { | |
17475 | @@ -995,17 +908,19 @@ | |
17476 | else if (err & TRK0_ERR) /* help it find track zero */ | |
17477 | rq->errors |= ERROR_RECAL; | |
17478 | } | |
17479 | +/* !ide_disk */ | |
17480 | if ((stat & DRQ_STAT) && rq->cmd != WRITE) | |
17481 | try_to_flush_leftover_data(drive); | |
17482 | +/* !ide_disk */ | |
17483 | } | |
17484 | if (GET_STAT() & (BUSY_STAT|DRQ_STAT)) | |
17485 | OUT_BYTE(WIN_IDLEIMMEDIATE,IDE_COMMAND_REG); /* force an abort */ | |
17486 | ||
17487 | if (rq->errors >= ERROR_MAX) { | |
17488 | if (drive->driver != NULL) | |
17489 | - DRIVER(drive)->end_request(0, HWGROUP(drive)); | |
17490 | + DRIVER(drive)->end_request(drive, 0); | |
17491 | else | |
17492 | - ide_end_request(0, HWGROUP(drive)); | |
17493 | + ide_end_request(drive, 0); | |
17494 | } else { | |
17495 | if ((rq->errors & ERROR_RESET) == ERROR_RESET) { | |
17496 | ++rq->errors; | |
17497 | @@ -1024,6 +939,8 @@ | |
17498 | */ | |
17499 | void ide_cmd (ide_drive_t *drive, byte cmd, byte nsect, ide_handler_t *handler) | |
17500 | { | |
17501 | + if (HWGROUP(drive)->handler != NULL) /* paranoia check */ | |
17502 | + BUG(); | |
17503 | ide_set_handler (drive, handler, WAIT_CMD, NULL); | |
17504 | if (IDE_CONTROL_REG) | |
17505 | OUT_BYTE(drive->ctl,IDE_CONTROL_REG); /* clear nIEN */ | |
17506 | @@ -1042,18 +959,18 @@ | |
17507 | byte stat = GET_STAT(); | |
17508 | int retries = 10; | |
17509 | ||
17510 | - ide__sti(); /* local CPU only */ | |
17511 | + local_irq_enable(); | |
17512 | if ((stat & DRQ_STAT) && args && args[3]) { | |
17513 | byte io_32bit = drive->io_32bit; | |
17514 | drive->io_32bit = 0; | |
17515 | - ide_input_data(drive, &args[4], args[3] * SECTOR_WORDS); | |
17516 | + ata_input_data(drive, &args[4], args[3] * SECTOR_WORDS); | |
17517 | drive->io_32bit = io_32bit; | |
17518 | while (((stat = GET_STAT()) & BUSY_STAT) && retries--) | |
17519 | udelay(100); | |
17520 | } | |
17521 | ||
17522 | if (!OK_STAT(stat, READY_STAT, BAD_STAT)) | |
17523 | - return ide_error(drive, "drive_cmd", stat); /* calls ide_end_drive_cmd */ | |
17524 | + return DRIVER(drive)->error(drive, "drive_cmd", stat); /* calls ide_end_drive_cmd */ | |
17525 | ide_end_drive_cmd (drive, stat, GET_ERR()); | |
17526 | return ide_stopped; | |
17527 | } | |
17528 | @@ -1070,10 +987,9 @@ | |
17529 | printk("%s: do_special: 0x%02x\n", drive->name, s->all); | |
17530 | #endif | |
17531 | if (s->b.set_tune) { | |
17532 | - ide_tuneproc_t *tuneproc = HWIF(drive)->tuneproc; | |
17533 | s->b.set_tune = 0; | |
17534 | - if (tuneproc != NULL) | |
17535 | - tuneproc(drive, drive->tune_req); | |
17536 | + if (HWIF(drive)->tuneproc != NULL) | |
17537 | + HWIF(drive)->tuneproc(drive, drive->tune_req); | |
17538 | } else if (drive->driver != NULL) { | |
17539 | return DRIVER(drive)->special(drive); | |
17540 | } else if (s->all) { | |
17541 | @@ -1084,132 +1000,120 @@ | |
17542 | } | |
17543 | ||
17544 | /* | |
17545 | - * This routine busy-waits for the drive status to be not "busy". | |
17546 | - * It then checks the status for all of the "good" bits and none | |
17547 | - * of the "bad" bits, and if all is okay it returns 0. All other | |
17548 | - * cases return 1 after invoking ide_error() -- caller should just return. | |
17549 | - * | |
17550 | - * This routine should get fixed to not hog the cpu during extra long waits.. | |
17551 | - * That could be done by busy-waiting for the first jiffy or two, and then | |
17552 | - * setting a timer to wake up at half second intervals thereafter, | |
17553 | - * until timeout is achieved, before timing out. | |
17554 | - */ | |
17555 | -int ide_wait_stat (ide_startstop_t *startstop, ide_drive_t *drive, byte good, byte bad, unsigned long timeout) { | |
17556 | - byte stat; | |
17557 | - int i; | |
17558 | - unsigned long flags; | |
17559 | - | |
17560 | - /* bail early if we've exceeded max_failures */ | |
17561 | - if (drive->max_failures && (drive->failures > drive->max_failures)) { | |
17562 | - *startstop = ide_stopped; | |
17563 | - return 1; | |
17564 | - } | |
17565 | - | |
17566 | - udelay(1); /* spec allows drive 400ns to assert "BUSY" */ | |
17567 | - if ((stat = GET_STAT()) & BUSY_STAT) { | |
17568 | - __save_flags(flags); /* local CPU only */ | |
17569 | - ide__sti(); /* local CPU only */ | |
17570 | - timeout += jiffies; | |
17571 | - while ((stat = GET_STAT()) & BUSY_STAT) { | |
17572 | - if (0 < (signed long)(jiffies - timeout)) { | |
17573 | - __restore_flags(flags); /* local CPU only */ | |
17574 | - *startstop = ide_error(drive, "status timeout", stat); | |
17575 | - return 1; | |
17576 | - } | |
17577 | - } | |
17578 | - __restore_flags(flags); /* local CPU only */ | |
17579 | - } | |
17580 | - /* | |
17581 | - * Allow status to settle, then read it again. | |
17582 | - * A few rare drives vastly violate the 400ns spec here, | |
17583 | - * so we'll wait up to 10usec for a "good" status | |
17584 | - * rather than expensively fail things immediately. | |
17585 | - * This fix courtesy of Matthew Faupel & Niccolo Rigacci. | |
17586 | - */ | |
17587 | - for (i = 0; i < 10; i++) { | |
17588 | - udelay(1); | |
17589 | - if (OK_STAT((stat = GET_STAT()), good, bad)) | |
17590 | - return 0; | |
17591 | - } | |
17592 | - *startstop = ide_error(drive, "status error", stat); | |
17593 | - return 1; | |
17594 | -} | |
17595 | - | |
17596 | -/* | |
17597 | * execute_drive_cmd() issues a special drive command, | |
17598 | * usually initiated by ioctl() from the external hdparm program. | |
17599 | */ | |
17600 | static ide_startstop_t execute_drive_cmd (ide_drive_t *drive, struct request *rq) | |
17601 | { | |
17602 | - byte *args = rq->buffer; | |
17603 | - if (args && rq->cmd == IDE_DRIVE_TASK) { | |
17604 | - byte sel; | |
17605 | + switch(rq->cmd) { | |
17606 | + case IDE_DRIVE_TASKFILE: | |
17607 | + { | |
17608 | + ide_task_t *args = rq->special; | |
17609 | + | |
17610 | + if (!(args)) break; | |
17611 | + | |
17612 | + if (args->tf_out_flags.all != 0) | |
17613 | + return flagged_taskfile(drive, args); | |
17614 | + return do_rw_taskfile(drive, args); | |
17615 | + } | |
17616 | + case IDE_DRIVE_TASK: | |
17617 | + { | |
17618 | + byte *args = rq->buffer; | |
17619 | + byte sel; | |
17620 | + | |
17621 | + if (!(args)) break; | |
17622 | #ifdef DEBUG | |
17623 | - printk("%s: DRIVE_TASK_CMD data=x%02x cmd=0x%02x fr=0x%02x ns=0x%02x sc=0x%02x lcyl=0x%02x hcyl=0x%02x sel=0x%02x\n", | |
17624 | - drive->name, | |
17625 | - args[0], args[1], args[2], args[3], | |
17626 | - args[4], args[5], args[6], args[7]); | |
17627 | + printk("%s: DRIVE_TASK_CMD ", drive->name); | |
17628 | + printk("cmd=0x%02x ", args[0]); | |
17629 | + printk("fr=0x%02x ", args[1]); | |
17630 | + printk("ns=0x%02x ", args[2]); | |
17631 | + printk("sc=0x%02x ", args[3]); | |
17632 | + printk("lcyl=0x%02x ", args[4]); | |
17633 | + printk("hcyl=0x%02x ", args[5]); | |
17634 | + printk("sel=0x%02x\n", args[6]); | |
17635 | #endif | |
17636 | - OUT_BYTE(args[1], IDE_FEATURE_REG); | |
17637 | - OUT_BYTE(args[3], IDE_SECTOR_REG); | |
17638 | - OUT_BYTE(args[4], IDE_LCYL_REG); | |
17639 | - OUT_BYTE(args[5], IDE_HCYL_REG); | |
17640 | - sel = (args[6] & ~0x10); | |
17641 | - if (drive->select.b.unit) | |
17642 | - sel |= 0x10; | |
17643 | - OUT_BYTE(sel, IDE_SELECT_REG); | |
17644 | - ide_cmd(drive, args[0], args[2], &drive_cmd_intr); | |
17645 | - return ide_started; | |
17646 | - } else if (args) { | |
17647 | + OUT_BYTE(args[1], IDE_FEATURE_REG); | |
17648 | + OUT_BYTE(args[3], IDE_SECTOR_REG); | |
17649 | + OUT_BYTE(args[4], IDE_LCYL_REG); | |
17650 | + OUT_BYTE(args[5], IDE_HCYL_REG); | |
17651 | + sel = (args[6] & ~0x10); | |
17652 | + if (drive->select.b.unit) | |
17653 | + sel |= 0x10; | |
17654 | + OUT_BYTE(sel, IDE_SELECT_REG); | |
17655 | + ide_cmd(drive, args[0], args[2], &drive_cmd_intr); | |
17656 | + return ide_started; | |
17657 | + } | |
17658 | + case IDE_DRIVE_CMD: | |
17659 | + { | |
17660 | + byte *args = rq->buffer; | |
17661 | + | |
17662 | + if (!(args)) break; | |
17663 | #ifdef DEBUG | |
17664 | - printk("%s: DRIVE_CMD cmd=0x%02x sc=0x%02x fr=0x%02x xx=0x%02x\n", | |
17665 | - drive->name, args[0], args[1], args[2], args[3]); | |
17666 | + printk("%s: DRIVE_CMD ", drive->name); | |
17667 | + printk("cmd=0x%02x ", args[0]); | |
17668 | + printk("sc=0x%02x ", args[1]); | |
17669 | + printk("fr=0x%02x ", args[2]); | |
17670 | + printk("xx=0x%02x\n", args[3]); | |
17671 | #endif | |
17672 | - if (args[0] == WIN_SMART) { | |
17673 | - OUT_BYTE(0x4f, IDE_LCYL_REG); | |
17674 | - OUT_BYTE(0xc2, IDE_HCYL_REG); | |
17675 | - OUT_BYTE(args[2],IDE_FEATURE_REG); | |
17676 | - OUT_BYTE(args[1],IDE_SECTOR_REG); | |
17677 | - ide_cmd(drive, args[0], args[3], &drive_cmd_intr); | |
17678 | - return ide_started; | |
17679 | - } | |
17680 | - OUT_BYTE(args[2],IDE_FEATURE_REG); | |
17681 | - ide_cmd(drive, args[0], args[1], &drive_cmd_intr); | |
17682 | - return ide_started; | |
17683 | - } else { | |
17684 | - /* | |
17685 | - * NULL is actually a valid way of waiting for | |
17686 | - * all current requests to be flushed from the queue. | |
17687 | - */ | |
17688 | + if (args[0] == WIN_SMART) { | |
17689 | + OUT_BYTE(0x4f, IDE_LCYL_REG); | |
17690 | + OUT_BYTE(0xc2, IDE_HCYL_REG); | |
17691 | + OUT_BYTE(args[2],IDE_FEATURE_REG); | |
17692 | + OUT_BYTE(args[1],IDE_SECTOR_REG); | |
17693 | + ide_cmd(drive, args[0], args[3], &drive_cmd_intr); | |
17694 | + return ide_started; | |
17695 | + } | |
17696 | + OUT_BYTE(args[2],IDE_FEATURE_REG); | |
17697 | + ide_cmd(drive, args[0], args[1], &drive_cmd_intr); | |
17698 | + return ide_started; | |
17699 | + } | |
17700 | + default: | |
17701 | + break; | |
17702 | + } | |
17703 | + /* | |
17704 | + * NULL is actually a valid way of waiting for | |
17705 | + * all current requests to be flushed from the queue. | |
17706 | + */ | |
17707 | #ifdef DEBUG | |
17708 | - printk("%s: DRIVE_CMD (null)\n", drive->name); | |
17709 | + printk("%s: DRIVE_CMD (null)\n", drive->name); | |
17710 | #endif | |
17711 | - ide_end_drive_cmd(drive, GET_STAT(), GET_ERR()); | |
17712 | - return ide_stopped; | |
17713 | - } | |
17714 | + ide_end_drive_cmd(drive, GET_STAT(), GET_ERR()); | |
17715 | + return ide_stopped; | |
17716 | } | |
17717 | ||
17718 | /* | |
17719 | * start_request() initiates handling of a new I/O request | |
17720 | + * needed to reverse the perverted changes anonymously made back | |
17721 | + * 2.3.99-pre6 | |
17722 | */ | |
17723 | -static ide_startstop_t start_request (ide_drive_t *drive) | |
17724 | +static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq) | |
17725 | { | |
17726 | ide_startstop_t startstop; | |
17727 | unsigned long block, blockend; | |
17728 | - struct request *rq = blkdev_entry_next_request(&drive->queue.queue_head); | |
17729 | unsigned int minor = MINOR(rq->rq_dev), unit = minor >> PARTN_BITS; | |
17730 | ide_hwif_t *hwif = HWIF(drive); | |
17731 | ||
17732 | #ifdef DEBUG | |
17733 | - printk("%s: start_request: current=0x%08lx\n", hwif->name, (unsigned long) rq); | |
17734 | + printk("%s: start_request: current=0x%08lx\n", | |
17735 | + hwif->name, (unsigned long) rq); | |
17736 | #endif | |
17737 | + | |
17738 | /* bail early if we've exceeded max_failures */ | |
17739 | if (drive->max_failures && (drive->failures > drive->max_failures)) { | |
17740 | goto kill_rq; | |
17741 | } | |
17742 | ||
17743 | + /* | |
17744 | + * bail early if we've sent a device to sleep, however how to wake | |
17745 | + * this needs to be a masked flag. FIXME for proper operations. | |
17746 | + */ | |
17747 | + if (drive->suspend_reset) { | |
17748 | + goto kill_rq; | |
17749 | + } | |
17750 | + | |
17751 | if (unit >= MAX_DRIVES) { | |
17752 | - printk("%s: bad device number: %s\n", hwif->name, kdevname(rq->rq_dev)); | |
17753 | + printk("%s: bad device number: %s\n", | |
17754 | + hwif->name, kdevname(rq->rq_dev)); | |
17755 | goto kill_rq; | |
17756 | } | |
17757 | #ifdef DEBUG | |
17758 | @@ -1245,8 +1149,14 @@ | |
17759 | return startstop; | |
17760 | } | |
17761 | if (!drive->special.all) { | |
17762 | - if (rq->cmd == IDE_DRIVE_CMD || rq->cmd == IDE_DRIVE_TASK) { | |
17763 | - return execute_drive_cmd(drive, rq); | |
17764 | + switch(rq->cmd) { | |
17765 | + case IDE_DRIVE_CMD: | |
17766 | + case IDE_DRIVE_TASK: | |
17767 | + return execute_drive_cmd(drive, rq); | |
17768 | + case IDE_DRIVE_TASKFILE: | |
17769 | + return execute_drive_cmd(drive, rq); | |
17770 | + default: | |
17771 | + break; | |
17772 | } | |
17773 | if (drive->driver != NULL) { | |
17774 | return (DRIVER(drive)->do_request(drive, rq, block)); | |
17775 | @@ -1257,23 +1167,16 @@ | |
17776 | return do_special(drive); | |
17777 | kill_rq: | |
17778 | if (drive->driver != NULL) | |
17779 | - DRIVER(drive)->end_request(0, HWGROUP(drive)); | |
17780 | + DRIVER(drive)->end_request(drive, 0); | |
17781 | else | |
17782 | - ide_end_request(0, HWGROUP(drive)); | |
17783 | + ide_end_request(drive, 0); | |
17784 | return ide_stopped; | |
17785 | } | |
17786 | ||
17787 | -ide_startstop_t restart_request (ide_drive_t *drive) | |
17788 | +int restart_request (ide_drive_t *drive, struct request *rq) | |
17789 | { | |
17790 | - ide_hwgroup_t *hwgroup = HWGROUP(drive); | |
17791 | - unsigned long flags; | |
17792 | - | |
17793 | - spin_lock_irqsave(&io_request_lock, flags); | |
17794 | - hwgroup->handler = NULL; | |
17795 | - del_timer(&hwgroup->timer); | |
17796 | - spin_unlock_irqrestore(&io_request_lock, flags); | |
17797 | - | |
17798 | - return start_request(drive); | |
17799 | + (void) start_request(drive, rq); | |
17800 | + return 0; | |
17801 | } | |
17802 | ||
17803 | /* | |
17804 | @@ -1300,7 +1203,7 @@ | |
17805 | best = NULL; | |
17806 | drive = hwgroup->drive; | |
17807 | do { | |
17808 | - if (!list_empty(&drive->queue.queue_head) && (!drive->sleep || 0 <= (signed long)(jiffies - drive->sleep))) { | |
17809 | + if (!list_empty(&drive->queue.queue_head) && (!drive->sleep || time_after_eq(jiffies, drive->sleep))) { | |
17810 | if (!best | |
17811 | || (drive->sleep && (!best->sleep || 0 < (signed long)(best->sleep - drive->sleep))) | |
17812 | || (!best->sleep && 0 < (signed long)(WAKEUP(best) - WAKEUP(drive)))) | |
17813 | @@ -1313,10 +1216,10 @@ | |
17814 | if (best && best->nice1 && !best->sleep && best != hwgroup->drive && best->service_time > WAIT_MIN_SLEEP) { | |
17815 | long t = (signed long)(WAKEUP(best) - jiffies); | |
17816 | if (t >= WAIT_MIN_SLEEP) { | |
17817 | - /* | |
17818 | - * We *may* have some time to spare, but first let's see if | |
17819 | - * someone can potentially benefit from our nice mood today.. | |
17820 | - */ | |
17821 | + /* | |
17822 | + * We *may* have some time to spare, but first let's see if | |
17823 | + * someone can potentially benefit from our nice mood today.. | |
17824 | + */ | |
17825 | drive = best->next; | |
17826 | do { | |
17827 | if (!drive->sleep | |
17828 | @@ -1370,15 +1273,17 @@ | |
17829 | /* --BenH: made non-static as ide-pmac.c uses it to kick the hwgroup back | |
17830 | * into life on wakeup from machine sleep. | |
17831 | */ | |
17832 | -void ide_do_request(ide_hwgroup_t *hwgroup, int masked_irq) | |
17833 | +void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq) | |
17834 | { | |
17835 | ide_drive_t *drive; | |
17836 | ide_hwif_t *hwif; | |
17837 | + struct request *rq; | |
17838 | ide_startstop_t startstop; | |
17839 | ||
17840 | ide_get_lock(&ide_lock, ide_intr, hwgroup); /* for atari only: POSSIBLY BROKEN HERE(?) */ | |
17841 | ||
17842 | - __cli(); /* necessary paranoia: ensure IRQs are masked on local CPU */ | |
17843 | + local_irq_disable(); | |
17844 | + /* necessary paranoia: ensure IRQs are masked on local CPU */ | |
17845 | ||
17846 | while (!hwgroup->busy) { | |
17847 | hwgroup->busy = 1; | |
17848 | @@ -1392,13 +1297,13 @@ | |
17849 | sleep = drive->sleep; | |
17850 | } while ((drive = drive->next) != hwgroup->drive); | |
17851 | if (sleep) { | |
17852 | - /* | |
17853 | - * Take a short snooze, and then wake up this hwgroup again. | |
17854 | - * This gives other hwgroups on the same a chance to | |
17855 | - * play fairly with us, just in case there are big differences | |
17856 | - * in relative throughputs.. don't want to hog the cpu too much. | |
17857 | - */ | |
17858 | - if (0 < (signed long)(jiffies + WAIT_MIN_SLEEP - sleep)) | |
17859 | + /* | |
17860 | + * Take a short snooze, and then wake up this hwgroup again. | |
17861 | + * This gives other hwgroups on the same a chance to | |
17862 | + * play fairly with us, just in case there are big differences | |
17863 | + * in relative throughputs.. don't want to hog the cpu too much. | |
17864 | + */ | |
17865 | + if (time_before(sleep, jiffies + WAIT_MIN_SLEEP)) | |
17866 | sleep = jiffies + WAIT_MIN_SLEEP; | |
17867 | #if 1 | |
17868 | if (timer_pending(&hwgroup->timer)) | |
17869 | @@ -1426,7 +1331,8 @@ | |
17870 | ||
17871 | if ( drive->queue.plugged ) /* paranoia */ | |
17872 | printk("%s: Huh? nuking plugged queue\n", drive->name); | |
17873 | - hwgroup->rq = blkdev_entry_next_request(&drive->queue.queue_head); | |
17874 | + | |
17875 | + rq = hwgroup->rq = blkdev_entry_next_request(&drive->queue.queue_head); | |
17876 | /* | |
17877 | * Some systems have trouble with IDE IRQs arriving while | |
17878 | * the driver is still setting things up. So, here we disable | |
17879 | @@ -1438,8 +1344,9 @@ | |
17880 | if (masked_irq && hwif->irq != masked_irq) | |
17881 | disable_irq_nosync(hwif->irq); | |
17882 | spin_unlock(&io_request_lock); | |
17883 | - ide__sti(); /* allow other IRQs while we start this request */ | |
17884 | - startstop = start_request(drive); | |
17885 | + local_irq_enable(); | |
17886 | + /* allow other IRQs while we start this request */ | |
17887 | + startstop = start_request(drive, rq); | |
17888 | spin_lock_irq(&io_request_lock); | |
17889 | if (masked_irq && hwif->irq != masked_irq) | |
17890 | enable_irq(hwif->irq); | |
17891 | @@ -1466,6 +1373,7 @@ | |
17892 | ide_do_request(q->queuedata, 0); | |
17893 | } | |
17894 | ||
17895 | +#ifndef __IDEDMA_TIMEOUT | |
17896 | /* | |
17897 | * un-busy the hwgroup etc, and clear any pending DMA status. we want to | |
17898 | * retry the current request in pio mode instead of risking tossing it | |
17899 | @@ -1506,8 +1414,17 @@ | |
17900 | rq->errors = 0; | |
17901 | rq->sector = rq->bh->b_rsector; | |
17902 | rq->current_nr_sectors = rq->bh->b_size >> 9; | |
17903 | + rq->hard_cur_sectors = rq->current_nr_sectors; | |
17904 | rq->buffer = rq->bh->b_data; | |
17905 | + | |
17906 | + /* | |
17907 | + * FIXME or DELETE ME | |
17908 | + * | |
17909 | + * so what do we do if the device is left in an invalid state | |
17910 | + * and will not accept commands. SOFT RESET is the only chance. | |
17911 | + */ | |
17912 | } | |
17913 | +#endif | |
17914 | ||
17915 | /* | |
17916 | * ide_timer_expiry() is our timeout function for all drive operations. | |
17917 | @@ -1543,7 +1460,7 @@ | |
17918 | hwgroup->handler = NULL; | |
17919 | } else { | |
17920 | ide_hwif_t *hwif; | |
17921 | - ide_startstop_t startstop; | |
17922 | + ide_startstop_t startstop = ide_stopped; | |
17923 | if (!hwgroup->busy) { | |
17924 | hwgroup->busy = 1; /* paranoia */ | |
17925 | printk("%s: ide_timer_expiry: hwgroup->busy was 0 ??\n", drive->name); | |
17926 | @@ -1571,7 +1488,8 @@ | |
17927 | #else | |
17928 | disable_irq(hwif->irq); /* disable_irq_nosync ?? */ | |
17929 | #endif /* DISABLE_IRQ_NOSYNC */ | |
17930 | - __cli(); /* local CPU only, as if we were handling an interrupt */ | |
17931 | + local_irq_disable(); | |
17932 | + /* local CPU only, as if we were handling an interrupt */ | |
17933 | if (hwgroup->poll_timeout != 0) { | |
17934 | startstop = handler(drive); | |
17935 | } else if (drive_is_ready(drive)) { | |
17936 | @@ -1582,10 +1500,16 @@ | |
17937 | startstop = handler(drive); | |
17938 | } else { | |
17939 | if (drive->waiting_for_dma) { | |
17940 | +#ifndef __IDEDMA_TIMEOUT | |
17941 | startstop = ide_stopped; | |
17942 | ide_dma_timeout_retry(drive); | |
17943 | +#else /* __IDEDMA_TIMEOUT */ | |
17944 | + (void) hwgroup->hwif->dmaproc(ide_dma_end, drive); | |
17945 | + printk("%s: timeout waiting for DMA\n", drive->name); | |
17946 | + (void) hwgroup->hwif->dmaproc(ide_dma_timeout, drive); | |
17947 | +#endif /* __IDEDMA_TIMEOUT */ | |
17948 | } else | |
17949 | - startstop = ide_error(drive, "irq timeout", GET_STAT()); | |
17950 | + startstop = DRIVER(drive)->error(drive, "irq timeout", GET_STAT()); | |
17951 | } | |
17952 | set_recovery_timer(hwif); | |
17953 | drive->service_time = jiffies - drive->service_start; | |
17954 | @@ -1619,7 +1543,7 @@ | |
17955 | * drive is ready to accept one, in which case we know the drive is not | |
17956 | * trying to interrupt us. And ide_set_handler() is always invoked before | |
17957 | * completing the issuance of any new drive command, so we will not be | |
17958 | - * accidently invoked as a result of any valid command completion interrupt. | |
17959 | + * accidentally invoked as a result of any valid command completion interrupt. | |
17960 | * | |
17961 | */ | |
17962 | static void unexpected_intr (int irq, ide_hwgroup_t *hwgroup) | |
17963 | @@ -1637,7 +1561,7 @@ | |
17964 | /* Try to not flood the console with msgs */ | |
17965 | static unsigned long last_msgtime, count; | |
17966 | ++count; | |
17967 | - if (0 < (signed long)(jiffies - (last_msgtime + HZ))) { | |
17968 | + if (time_after(jiffies, last_msgtime + HZ)) { | |
17969 | last_msgtime = jiffies; | |
17970 | printk("%s%s: unexpected interrupt, status=0x%02x, count=%ld\n", | |
17971 | hwif->name, (hwif->next == hwgroup->hwif) ? "" : "(?)", stat, count); | |
17972 | @@ -1692,7 +1616,8 @@ | |
17973 | #ifdef CONFIG_BLK_DEV_IDEPCI | |
17974 | } else { | |
17975 | /* | |
17976 | - * Whack the status register, just in case we have a leftover pending IRQ. | |
17977 | + * Whack the status register, just in case | |
17978 | + * we have a leftover pending IRQ. | |
17979 | */ | |
17980 | (void) IN_BYTE(hwif->io_ports[IDE_STATUS_OFFSET]); | |
17981 | #endif /* CONFIG_BLK_DEV_IDEPCI */ | |
17982 | @@ -1703,16 +1628,18 @@ | |
17983 | drive = hwgroup->drive; | |
17984 | if (!drive) { | |
17985 | /* | |
17986 | - * This should NEVER happen, and there isn't much we could do about it here. | |
17987 | + * This should NEVER happen, and there isn't much | |
17988 | + * we could do about it here. | |
17989 | */ | |
17990 | spin_unlock_irqrestore(&io_request_lock, flags); | |
17991 | return; | |
17992 | } | |
17993 | if (!drive_is_ready(drive)) { | |
17994 | /* | |
17995 | - * This happens regularly when we share a PCI IRQ with another device. | |
17996 | - * Unfortunately, it can also happen with some buggy drives that trigger | |
17997 | - * the IRQ before their status register is up to date. Hopefully we have | |
17998 | + * This happens regularly when we share a PCI IRQ with | |
17999 | + * another device. Unfortunately, it can also happen | |
18000 | + * with some buggy drives that trigger the IRQ before | |
18001 | + * their status register is up to date. Hopefully we have | |
18002 | * enough advance overhead that the latter isn't a problem. | |
18003 | */ | |
18004 | spin_unlock_irqrestore(&io_request_lock, flags); | |
18005 | @@ -1727,7 +1654,7 @@ | |
18006 | spin_unlock(&io_request_lock); | |
18007 | ||
18008 | if (drive->unmask) | |
18009 | - ide__sti(); /* local CPU only */ | |
18010 | + local_irq_enable(); | |
18011 | startstop = handler(drive); /* service this interrupt, may set handler for next interrupt */ | |
18012 | spin_lock_irq(&io_request_lock); | |
18013 | ||
18014 | @@ -1867,7 +1794,7 @@ | |
18015 | ide_drive_t *drive; | |
18016 | ide_hwgroup_t *hwgroup; | |
18017 | unsigned int p, major, minor; | |
18018 | - long flags; | |
18019 | + unsigned long flags; | |
18020 | ||
18021 | if ((drive = get_info_ptr(i_rdev)) == NULL) | |
18022 | return -ENODEV; | |
18023 | @@ -1967,6 +1894,10 @@ | |
18024 | (void) request_module("ide-tape"); | |
18025 | if (drive->media == ide_floppy) | |
18026 | (void) request_module("ide-floppy"); | |
18027 | +#if defined(CONFIG_BLK_DEV_IDESCSI) && defined(CONFIG_SCSI) | |
18028 | + if (drive->media == ide_scsi) | |
18029 | + (void) request_module("ide-scsi"); | |
18030 | +#endif /* defined(CONFIG_BLK_DEV_IDESCSI) && defined(CONFIG_SCSI) */ | |
18031 | } | |
18032 | #endif /* CONFIG_KMOD */ | |
18033 | while (drive->busy) | |
18034 | @@ -2067,8 +1998,7 @@ | |
18035 | ||
18036 | if (index >= MAX_HWIFS) | |
18037 | return; | |
18038 | - save_flags(flags); /* all CPUs */ | |
18039 | - cli(); /* all CPUs */ | |
18040 | + spin_lock_irqsave(&io_request_lock, flags); | |
18041 | hwif = &ide_hwifs[index]; | |
18042 | if (!hwif->present) | |
18043 | goto abort; | |
18044 | @@ -2086,7 +2016,7 @@ | |
18045 | /* | |
18046 | * All clear? Then blow away the buffer cache | |
18047 | */ | |
18048 | - sti(); | |
18049 | + spin_unlock_irqrestore(&io_request_lock, flags); | |
18050 | for (unit = 0; unit < MAX_DRIVES; ++unit) { | |
18051 | drive = &hwif->drives[unit]; | |
18052 | if (!drive->present) | |
18053 | @@ -2102,7 +2032,7 @@ | |
18054 | destroy_proc_ide_drives(hwif); | |
18055 | #endif | |
18056 | } | |
18057 | - cli(); | |
18058 | + spin_lock_irqsave(&io_request_lock, flags); | |
18059 | hwgroup = hwif->hwgroup; | |
18060 | ||
18061 | /* | |
18062 | @@ -2115,7 +2045,7 @@ | |
18063 | g = g->next; | |
18064 | } while (g != hwgroup->hwif); | |
18065 | if (irq_count == 1) | |
18066 | - free_irq(hwif->irq, hwgroup); | |
18067 | + ide_free_irq(hwif->irq, hwgroup); | |
18068 | ||
18069 | /* | |
18070 | * Note that we only release the standard ports, | |
18071 | @@ -2222,7 +2152,7 @@ | |
18072 | hwif->straight8 = old_hwif.straight8; | |
18073 | hwif->hwif_data = old_hwif.hwif_data; | |
18074 | abort: | |
18075 | - restore_flags(flags); /* all CPUs */ | |
18076 | + spin_unlock_irqrestore(&io_request_lock, flags); | |
18077 | } | |
18078 | ||
18079 | /* | |
18080 | @@ -2295,6 +2225,7 @@ | |
18081 | memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->hw.io_ports)); | |
18082 | hwif->irq = hw->irq; | |
18083 | hwif->noprobe = 0; | |
18084 | + hwif->chipset = hw->chipset; | |
18085 | ||
18086 | if (!initializing) { | |
18087 | ide_probe_module(); | |
18088 | @@ -2433,14 +2364,13 @@ | |
18089 | while (hwgroup->busy) { | |
18090 | unsigned long lflags; | |
18091 | spin_unlock_irq(&io_request_lock); | |
18092 | - __save_flags(lflags); /* local CPU only */ | |
18093 | - __sti(); /* local CPU only; needed for jiffies */ | |
18094 | - if (0 < (signed long)(jiffies - timeout)) { | |
18095 | - __restore_flags(lflags); /* local CPU only */ | |
18096 | + local_irq_set(lflags); | |
18097 | + if (time_after(jiffies, timeout)) { | |
18098 | + local_irq_restore(lflags); | |
18099 | printk("%s: channel busy\n", drive->name); | |
18100 | return -EBUSY; | |
18101 | } | |
18102 | - __restore_flags(lflags); /* local CPU only */ | |
18103 | + local_irq_restore(lflags); | |
18104 | spin_lock_irq(&io_request_lock); | |
18105 | } | |
18106 | return 0; | |
18107 | @@ -2535,8 +2465,8 @@ | |
18108 | ide_add_setting(drive, "unmaskirq", drive->no_unmask ? SETTING_READ : SETTING_RW, HDIO_GET_UNMASKINTR, HDIO_SET_UNMASKINTR, TYPE_BYTE, 0, 1, 1, 1, &drive->unmask, NULL); | |
18109 | ide_add_setting(drive, "using_dma", SETTING_RW, HDIO_GET_DMA, HDIO_SET_DMA, TYPE_BYTE, 0, 1, 1, 1, &drive->using_dma, set_using_dma); | |
18110 | ide_add_setting(drive, "ide_scsi", SETTING_RW, -1, -1, TYPE_BYTE, 0, 1, 1, 1, &drive->scsi, NULL); | |
18111 | - ide_add_setting(drive, "init_speed", SETTING_RW, -1, -1, TYPE_BYTE, 0, 69, 1, 1, &drive->init_speed, NULL); | |
18112 | - ide_add_setting(drive, "current_speed", SETTING_RW, -1, -1, TYPE_BYTE, 0, 69, 1, 1, &drive->current_speed, NULL); | |
18113 | + ide_add_setting(drive, "init_speed", SETTING_RW, -1, -1, TYPE_BYTE, 0, 70, 1, 1, &drive->init_speed, NULL); | |
18114 | + ide_add_setting(drive, "current_speed", SETTING_RW, -1, -1, TYPE_BYTE, 0, 70, 1, 1, &drive->current_speed, NULL); | |
18115 | ide_add_setting(drive, "number", SETTING_RW, -1, -1, TYPE_BYTE, 0, 3, 1, 1, &drive->dn, NULL); | |
18116 | } | |
18117 | ||
18118 | @@ -2590,6 +2520,61 @@ | |
18119 | return((int) ((!system_bus_speed) ? ide_system_bus_speed() : system_bus_speed )); | |
18120 | } | |
18121 | ||
18122 | +int ide_reinit_drive (ide_drive_t *drive) | |
18123 | +{ | |
18124 | + switch (drive->media) { | |
18125 | +#ifdef CONFIG_BLK_DEV_IDECD | |
18126 | + case ide_cdrom: | |
18127 | + { | |
18128 | + extern int ide_cdrom_reinit(ide_drive_t *drive); | |
18129 | + if (ide_cdrom_reinit(drive)) | |
18130 | + return 1; | |
18131 | + break; | |
18132 | + } | |
18133 | +#endif /* CONFIG_BLK_DEV_IDECD */ | |
18134 | +#ifdef CONFIG_BLK_DEV_IDEDISK | |
18135 | + case ide_disk: | |
18136 | + { | |
18137 | + extern int idedisk_reinit(ide_drive_t *drive); | |
18138 | + if (idedisk_reinit(drive)) | |
18139 | + return 1; | |
18140 | + break; | |
18141 | + } | |
18142 | +#endif /* CONFIG_BLK_DEV_IDEDISK */ | |
18143 | +#ifdef CONFIG_BLK_DEV_IDEFLOPPY | |
18144 | + case ide_floppy: | |
18145 | + { | |
18146 | + extern int idefloppy_reinit(ide_drive_t *drive); | |
18147 | + if (idefloppy_reinit(drive)) | |
18148 | + return 1; | |
18149 | + break; | |
18150 | + } | |
18151 | +#endif /* CONFIG_BLK_DEV_IDEFLOPPY */ | |
18152 | +#ifdef CONFIG_BLK_DEV_IDETAPE | |
18153 | + case ide_tape: | |
18154 | + { | |
18155 | + extern int idetape_reinit(ide_drive_t *drive); | |
18156 | + if (idetape_reinit(drive)) | |
18157 | + return 1; | |
18158 | + break; | |
18159 | + } | |
18160 | +#endif /* CONFIG_BLK_DEV_IDETAPE */ | |
18161 | +#ifdef CONFIG_BLK_DEV_IDESCSI | |
18162 | +/* | |
18163 | + * { | |
18164 | + * extern int idescsi_reinit(ide_drive_t *drive); | |
18165 | + * if (idescsi_reinit(drive)) | |
18166 | + * return 1; | |
18167 | + * break; | |
18168 | + * } | |
18169 | + */ | |
18170 | +#endif /* CONFIG_BLK_DEV_IDESCSI */ | |
18171 | + default: | |
18172 | + return 1; | |
18173 | + } | |
18174 | + return 0; | |
18175 | +} | |
18176 | + | |
18177 | static int ide_ioctl (struct inode *inode, struct file *file, | |
18178 | unsigned int cmd, unsigned long arg) | |
18179 | { | |
18180 | @@ -2681,57 +2666,35 @@ | |
18181 | drive->nice1 << IDE_NICE_1 | | |
18182 | drive->nice2 << IDE_NICE_2, | |
18183 | (long *) arg); | |
18184 | + | |
18185 | +#ifdef CONFIG_IDE_TASK_IOCTL | |
18186 | + case HDIO_DRIVE_TASKFILE: | |
18187 | + if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO)) | |
18188 | + return -EACCES; | |
18189 | + switch(drive->media) { | |
18190 | + case ide_disk: | |
18191 | + return ide_taskfile_ioctl(drive, inode, file, cmd, arg); | |
18192 | +#ifdef CONFIG_PKT_TASK_IOCTL | |
18193 | + case ide_cdrom: | |
18194 | + case ide_tape: | |
18195 | + case ide_floppy: | |
18196 | + return pkt_taskfile_ioctl(drive, inode, file, cmd, arg); | |
18197 | +#endif /* CONFIG_PKT_TASK_IOCTL */ | |
18198 | + default: | |
18199 | + return -ENOMSG; | |
18200 | + } | |
18201 | +#endif /* CONFIG_IDE_TASK_IOCTL */ | |
18202 | + | |
18203 | case HDIO_DRIVE_CMD: | |
18204 | - { | |
18205 | - byte args[4], *argbuf = args; | |
18206 | - byte xfer_rate = 0; | |
18207 | - int argsize = 4; | |
18208 | - if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO)) return -EACCES; | |
18209 | - if (NULL == (void *) arg) | |
18210 | - return ide_do_drive_cmd(drive, &rq, ide_wait); | |
18211 | - if (copy_from_user(args, (void *)arg, 4)) | |
18212 | - return -EFAULT; | |
18213 | - if (args[3]) { | |
18214 | - argsize = 4 + (SECTOR_WORDS * 4 * args[3]); | |
18215 | - argbuf = kmalloc(argsize, GFP_KERNEL); | |
18216 | - if (argbuf == NULL) | |
18217 | - return -ENOMEM; | |
18218 | - memcpy(argbuf, args, 4); | |
18219 | - } | |
18220 | - | |
18221 | - if (set_transfer(drive, args[0], args[1], args[2])) { | |
18222 | - xfer_rate = args[1]; | |
18223 | - if (ide_ata66_check(drive, args[0], args[1], args[2])) | |
18224 | - goto abort; | |
18225 | - } | |
18226 | - | |
18227 | - err = ide_wait_cmd(drive, args[0], args[1], args[2], args[3], argbuf); | |
18228 | - | |
18229 | - if (!err && xfer_rate) { | |
18230 | - /* active-retuning-calls future */ | |
18231 | - if ((HWIF(drive)->speedproc) != NULL) | |
18232 | - HWIF(drive)->speedproc(drive, xfer_rate); | |
18233 | - ide_driveid_update(drive); | |
18234 | - } | |
18235 | - abort: | |
18236 | - if (copy_to_user((void *)arg, argbuf, argsize)) | |
18237 | - err = -EFAULT; | |
18238 | - if (argsize > 4) | |
18239 | - kfree(argbuf); | |
18240 | - return err; | |
18241 | - } | |
18242 | + if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO)) | |
18243 | + return -EACCES; | |
18244 | + return ide_cmd_ioctl(drive, inode, file, cmd, arg); | |
18245 | + | |
18246 | case HDIO_DRIVE_TASK: | |
18247 | - { | |
18248 | - byte args[7], *argbuf = args; | |
18249 | - int argsize = 7; | |
18250 | - if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO)) return -EACCES; | |
18251 | - if (copy_from_user(args, (void *)arg, 7)) | |
18252 | - return -EFAULT; | |
18253 | - err = ide_wait_cmd_task(drive, argbuf); | |
18254 | - if (copy_to_user((void *)arg, argbuf, argsize)) | |
18255 | - err = -EFAULT; | |
18256 | - return err; | |
18257 | - } | |
18258 | + if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO)) | |
18259 | + return -EACCES; | |
18260 | + return ide_task_ioctl(drive, inode, file, cmd, arg); | |
18261 | + | |
18262 | case HDIO_SCAN_HWIF: | |
18263 | { | |
18264 | int args[3]; | |
18265 | @@ -2761,7 +2724,21 @@ | |
18266 | drive->nice1 = (arg >> IDE_NICE_1) & 1; | |
18267 | return 0; | |
18268 | case HDIO_DRIVE_RESET: | |
18269 | + { | |
18270 | + unsigned long flags; | |
18271 | if (!capable(CAP_SYS_ADMIN)) return -EACCES; | |
18272 | +#if 1 | |
18273 | + spin_lock_irqsave(&io_request_lock, flags); | |
18274 | + if ( HWGROUP(drive)->handler != NULL) { | |
18275 | + printk("%s: ide_set_handler: handler not null; %p\n", drive->name, HWGROUP(drive)->handler); | |
18276 | + (void) HWGROUP(drive)->handler(drive); | |
18277 | +// HWGROUP(drive)->handler = NULL; | |
18278 | + HWGROUP(drive)->expiry = NULL; | |
18279 | + del_timer(&HWGROUP(drive)->timer); | |
18280 | + } | |
18281 | + spin_unlock_irqrestore(&io_request_lock, flags); | |
18282 | + | |
18283 | +#endif | |
18284 | (void) ide_do_reset(drive); | |
18285 | if (drive->suspend_reset) { | |
18286 | /* | |
18287 | @@ -2776,7 +2753,7 @@ | |
18288 | return ide_revalidate_disk(inode->i_rdev); | |
18289 | } | |
18290 | return 0; | |
18291 | - | |
18292 | + } | |
18293 | case BLKROSET: | |
18294 | case BLKROGET: | |
18295 | case BLKFLSBUF: | |
18296 | @@ -2799,7 +2776,7 @@ | |
18297 | if (!capable(CAP_SYS_ADMIN)) | |
18298 | return -EACCES; | |
18299 | if (HWIF(drive)->busproc) | |
18300 | - HWIF(drive)->busproc(HWIF(drive), arg); | |
18301 | + HWIF(drive)->busproc(drive, (int)arg); | |
18302 | return 0; | |
18303 | ||
18304 | default: | |
18305 | @@ -3316,13 +3293,6 @@ | |
18306 | { | |
18307 | #ifdef CONFIG_BLK_DEV_IDEPCI | |
18308 | ide_scan_pcibus(ide_scan_direction); | |
18309 | -#else | |
18310 | -#ifdef CONFIG_BLK_DEV_RZ1000 | |
18311 | - { | |
18312 | - extern void ide_probe_for_rz100x(void); | |
18313 | - ide_probe_for_rz100x(); | |
18314 | - } | |
18315 | -#endif /* CONFIG_BLK_DEV_RZ1000 */ | |
18316 | #endif /* CONFIG_BLK_DEV_IDEPCI */ | |
18317 | } | |
18318 | #endif /* CONFIG_PCI */ | |
18319 | @@ -3351,6 +3321,12 @@ | |
18320 | pmac_ide_probe(); | |
18321 | } | |
18322 | #endif /* CONFIG_BLK_DEV_IDE_PMAC */ | |
18323 | +#ifdef CONFIG_BLK_DEV_IDE_SWARM | |
18324 | + { | |
18325 | + extern void swarm_ide_probe(void); | |
18326 | + swarm_ide_probe(); | |
18327 | + } | |
18328 | +#endif /* CONFIG_BLK_DEV_IDE_SWARM */ | |
18329 | #ifdef CONFIG_BLK_DEV_IDE_ICSIDE | |
18330 | { | |
18331 | extern void icside_init(void); | |
18332 | @@ -3460,17 +3436,47 @@ | |
18333 | return ide_unregister_subdriver(drive); | |
18334 | } | |
18335 | ||
18336 | -static ide_startstop_t default_do_request(ide_drive_t *drive, struct request *rq, unsigned long block) | |
18337 | +static int default_standby (ide_drive_t *drive) | |
18338 | { | |
18339 | - ide_end_request(0, HWGROUP(drive)); | |
18340 | + return 0; | |
18341 | +} | |
18342 | + | |
18343 | +static int default_suspend (ide_drive_t *drive) | |
18344 | +{ | |
18345 | + return 0; | |
18346 | +} | |
18347 | + | |
18348 | +static int default_resume (ide_drive_t *drive) | |
18349 | +{ | |
18350 | + return 0; | |
18351 | +} | |
18352 | + | |
18353 | +static int default_flushcache (ide_drive_t *drive) | |
18354 | +{ | |
18355 | + return 0; | |
18356 | +} | |
18357 | + | |
18358 | +static ide_startstop_t default_do_request (ide_drive_t *drive, struct request *rq, unsigned long block) | |
18359 | +{ | |
18360 | + ide_end_request(drive, 0); | |
18361 | return ide_stopped; | |
18362 | } | |
18363 | - | |
18364 | -static void default_end_request (byte uptodate, ide_hwgroup_t *hwgroup) | |
18365 | + | |
18366 | +static int default_end_request (ide_drive_t *drive, int uptodate) | |
18367 | +{ | |
18368 | + return ide_end_request(drive, uptodate); | |
18369 | +} | |
18370 | + | |
18371 | +static byte default_sense (ide_drive_t *drive, const char *msg, byte stat) | |
18372 | +{ | |
18373 | + return ide_dump_status(drive, msg, stat); | |
18374 | +} | |
18375 | + | |
18376 | +static ide_startstop_t default_error (ide_drive_t *drive, const char *msg, byte stat) | |
18377 | { | |
18378 | - ide_end_request(uptodate, hwgroup); | |
18379 | + return ide_error(drive, msg, stat); | |
18380 | } | |
18381 | - | |
18382 | + | |
18383 | static int default_ioctl (ide_drive_t *drive, struct inode *inode, struct file *file, | |
18384 | unsigned int cmd, unsigned long arg) | |
18385 | { | |
18386 | @@ -3510,7 +3516,12 @@ | |
18387 | return ide_stopped; | |
18388 | } | |
18389 | ||
18390 | -static int default_driver_reinit (ide_drive_t *drive) | |
18391 | +static int default_init (void) | |
18392 | +{ | |
18393 | + return 0; | |
18394 | +} | |
18395 | + | |
18396 | +static int default_reinit (ide_drive_t *drive) | |
18397 | { | |
18398 | printk(KERN_ERR "%s: does not support hotswap of device class !\n", drive->name); | |
18399 | ||
18400 | @@ -3522,8 +3533,14 @@ | |
18401 | ide_driver_t *d = drive->driver; | |
18402 | ||
18403 | if (d->cleanup == NULL) d->cleanup = default_cleanup; | |
18404 | + if (d->standby == NULL) d->standby = default_standby; | |
18405 | + if (d->suspend == NULL) d->suspend = default_suspend; | |
18406 | + if (d->resume == NULL) d->resume = default_resume; | |
18407 | + if (d->flushcache == NULL) d->flushcache = default_flushcache; | |
18408 | if (d->do_request == NULL) d->do_request = default_do_request; | |
18409 | if (d->end_request == NULL) d->end_request = default_end_request; | |
18410 | + if (d->sense == NULL) d->sense = default_sense; | |
18411 | + if (d->error == NULL) d->error = default_error; | |
18412 | if (d->ioctl == NULL) d->ioctl = default_ioctl; | |
18413 | if (d->open == NULL) d->open = default_open; | |
18414 | if (d->release == NULL) d->release = default_release; | |
18415 | @@ -3531,7 +3548,8 @@ | |
18416 | if (d->pre_reset == NULL) d->pre_reset = default_pre_reset; | |
18417 | if (d->capacity == NULL) d->capacity = default_capacity; | |
18418 | if (d->special == NULL) d->special = default_special; | |
18419 | - if (d->driver_reinit == NULL) d->driver_reinit = default_driver_reinit; | |
18420 | + if (d->init == NULL) d->init = default_init; | |
18421 | + if (d->reinit == NULL) d->reinit = default_reinit; | |
18422 | } | |
18423 | ||
18424 | ide_drive_t *ide_scan_devices (byte media, const char *name, ide_driver_t *driver, int n) | |
18425 | @@ -3558,15 +3576,15 @@ | |
18426 | { | |
18427 | unsigned long flags; | |
18428 | ||
18429 | - save_flags(flags); /* all CPUs */ | |
18430 | - cli(); /* all CPUs */ | |
18431 | - if (version != IDE_SUBDRIVER_VERSION || !drive->present || drive->driver != NULL || drive->busy || drive->usage) { | |
18432 | - restore_flags(flags); /* all CPUs */ | |
18433 | + spin_lock_irqsave(&io_request_lock, flags); | |
18434 | + if (version != IDE_SUBDRIVER_VERSION || !drive->present || | |
18435 | + drive->driver != NULL || drive->busy || drive->usage) { | |
18436 | + spin_unlock_irqrestore(&io_request_lock, flags); | |
18437 | return 1; | |
18438 | } | |
18439 | drive->driver = driver; | |
18440 | setup_driver_defaults(drive); | |
18441 | - restore_flags(flags); /* all CPUs */ | |
18442 | + spin_unlock_irqrestore(&io_request_lock, flags); | |
18443 | if (drive->autotune != 2) { | |
18444 | if (driver->supports_dma && HWIF(drive)->dmaproc != NULL) { | |
18445 | /* | |
18446 | @@ -3594,10 +3612,10 @@ | |
18447 | { | |
18448 | unsigned long flags; | |
18449 | ||
18450 | - save_flags(flags); /* all CPUs */ | |
18451 | - cli(); /* all CPUs */ | |
18452 | - if (drive->usage || drive->busy || drive->driver == NULL || DRIVER(drive)->busy) { | |
18453 | - restore_flags(flags); /* all CPUs */ | |
18454 | + spin_lock_irqsave(&io_request_lock, flags); | |
18455 | + if (drive->usage || drive->busy || | |
18456 | + drive->driver == NULL || DRIVER(drive)->busy) { | |
18457 | + spin_unlock_irqrestore(&io_request_lock, flags); | |
18458 | return 1; | |
18459 | } | |
18460 | #if defined(CONFIG_BLK_DEV_ISAPNP) && defined(CONFIG_ISAPNP) && defined(MODULE) | |
18461 | @@ -3609,7 +3627,7 @@ | |
18462 | #endif | |
18463 | auto_remove_settings(drive); | |
18464 | drive->driver = NULL; | |
18465 | - restore_flags(flags); /* all CPUs */ | |
18466 | + spin_unlock_irqrestore(&io_request_lock, flags); | |
18467 | return 0; | |
18468 | } | |
18469 | ||
18470 | @@ -3672,15 +3690,10 @@ | |
18471 | EXPORT_SYMBOL(ide_register_subdriver); | |
18472 | EXPORT_SYMBOL(ide_unregister_subdriver); | |
18473 | EXPORT_SYMBOL(ide_replace_subdriver); | |
18474 | -EXPORT_SYMBOL(ide_input_data); | |
18475 | -EXPORT_SYMBOL(ide_output_data); | |
18476 | -EXPORT_SYMBOL(atapi_input_bytes); | |
18477 | -EXPORT_SYMBOL(atapi_output_bytes); | |
18478 | EXPORT_SYMBOL(ide_set_handler); | |
18479 | EXPORT_SYMBOL(ide_dump_status); | |
18480 | EXPORT_SYMBOL(ide_error); | |
18481 | EXPORT_SYMBOL(ide_fixstring); | |
18482 | -EXPORT_SYMBOL(ide_wait_stat); | |
18483 | EXPORT_SYMBOL(ide_do_reset); | |
18484 | EXPORT_SYMBOL(restart_request); | |
18485 | EXPORT_SYMBOL(ide_init_drive_cmd); | |
18486 | @@ -3698,6 +3711,8 @@ | |
18487 | EXPORT_SYMBOL(ide_remove_proc_entries); | |
18488 | EXPORT_SYMBOL(proc_ide_read_geometry); | |
18489 | EXPORT_SYMBOL(create_proc_ide_interfaces); | |
18490 | +EXPORT_SYMBOL(recreate_proc_ide_device); | |
18491 | +EXPORT_SYMBOL(destroy_proc_ide_device); | |
18492 | #endif | |
18493 | EXPORT_SYMBOL(ide_add_setting); | |
18494 | EXPORT_SYMBOL(ide_remove_setting); | |
18495 | @@ -3712,6 +3727,54 @@ | |
18496 | ||
18497 | EXPORT_SYMBOL(system_bus_clock); | |
18498 | ||
18499 | +EXPORT_SYMBOL(ide_reinit_drive); | |
18500 | + | |
18501 | +static int ide_notify_reboot (struct notifier_block *this, unsigned long event, void *x) | |
18502 | +{ | |
18503 | + ide_hwif_t *hwif; | |
18504 | + ide_drive_t *drive; | |
18505 | + int i, unit; | |
18506 | + | |
18507 | + switch (event) { | |
18508 | + case SYS_HALT: | |
18509 | + case SYS_POWER_OFF: | |
18510 | + case SYS_RESTART: | |
18511 | + break; | |
18512 | + default: | |
18513 | + return NOTIFY_DONE; | |
18514 | + } | |
18515 | + | |
18516 | + printk("flushing ide devices: "); | |
18517 | + | |
18518 | + for (i = 0; i < MAX_HWIFS; i++) { | |
18519 | + hwif = &ide_hwifs[i]; | |
18520 | + if (!hwif->present) | |
18521 | + continue; | |
18522 | + for (unit = 0; unit < MAX_DRIVES; ++unit) { | |
18523 | + drive = &hwif->drives[unit]; | |
18524 | + if (!drive->present) | |
18525 | + continue; | |
18526 | + | |
18527 | + /* set the drive to standby */ | |
18528 | + printk("%s ", drive->name); | |
18529 | + if (event != SYS_RESTART) | |
18530 | + if (drive->driver != NULL && DRIVER(drive)->standby(drive)) | |
18531 | + continue; | |
18532 | + | |
18533 | + if (drive->driver != NULL && DRIVER(drive)->cleanup(drive)) | |
18534 | + continue; | |
18535 | + } | |
18536 | + } | |
18537 | + printk("\n"); | |
18538 | + return NOTIFY_DONE; | |
18539 | +} | |
18540 | + | |
18541 | +static struct notifier_block ide_notifier = { | |
18542 | + ide_notify_reboot, | |
18543 | + NULL, | |
18544 | + 5 | |
18545 | +}; | |
18546 | + | |
18547 | /* | |
18548 | * This is gets invoked once during initialization, to set *everything* up | |
18549 | */ | |
18550 | @@ -3739,6 +3802,7 @@ | |
18551 | ide_geninit(hwif); | |
18552 | } | |
18553 | ||
18554 | + register_reboot_notifier(&ide_notifier); | |
18555 | return 0; | |
18556 | } | |
18557 | ||
18558 | @@ -3771,6 +3835,7 @@ | |
18559 | { | |
18560 | int index; | |
18561 | ||
18562 | + unregister_reboot_notifier(&ide_notifier); | |
18563 | for (index = 0; index < MAX_HWIFS; ++index) { | |
18564 | ide_unregister(index); | |
18565 | #if defined(CONFIG_BLK_DEV_IDEDMA) && !defined(CONFIG_DMA_NONPCI) | |
18566 | diff -Nur linux.org/drivers/ide/it8172.c linux/drivers/ide/it8172.c | |
18567 | --- linux.org/drivers/ide/it8172.c Fri Sep 7 18:28:38 2001 | |
18568 | +++ linux/drivers/ide/it8172.c Thu Jul 18 14:24:33 2002 | |
18569 | @@ -46,100 +46,134 @@ | |
18570 | /* | |
18571 | * Prototypes | |
18572 | */ | |
18573 | +static byte it8172_ratemask (ide_drive_t *drive); | |
18574 | +static byte it8172_ratefilter (ide_drive_t *drive, byte speed); | |
18575 | static void it8172_tune_drive (ide_drive_t *drive, byte pio); | |
18576 | -#if defined(CONFIG_BLK_DEV_IDEDMA) && defined(CONFIG_IT8172_TUNING) | |
18577 | static byte it8172_dma_2_pio (byte xfer_rate); | |
18578 | -static int it8172_tune_chipset (ide_drive_t *drive, byte speed); | |
18579 | -static int it8172_config_drive_for_dma (ide_drive_t *drive); | |
18580 | +static int it8172_tune_chipset (ide_drive_t *drive, byte xferspeed); | |
18581 | +#ifdef CONFIG_BLK_DEV_IDEDMA | |
18582 | +static int it8172_config_chipset_for_dma (ide_drive_t *drive); | |
18583 | static int it8172_dmaproc(ide_dma_action_t func, ide_drive_t *drive); | |
18584 | #endif | |
18585 | unsigned int __init pci_init_it8172 (struct pci_dev *dev, const char *name); | |
18586 | void __init ide_init_it8172 (ide_hwif_t *hwif); | |
18587 | ||
18588 | +static byte it8172_ratemask (ide_drive_t *drive) | |
18589 | +{ | |
18590 | + byte mode = 0x00; | |
18591 | +#if 1 | |
18592 | + mode |= 0x01; | |
18593 | +#endif | |
18594 | + return (mode &= ~0xF8); | |
18595 | +} | |
18596 | + | |
18597 | +static byte it8172_ratefilter (ide_drive_t *drive, byte speed) | |
18598 | +{ | |
18599 | +#ifdef CONFIG_BLK_DEV_IDEDMA | |
18600 | + byte mode = it8172_ratemask(drive); | |
18601 | + | |
18602 | + switch(mode) { | |
18603 | + case 0x04: // while (speed > XFER_UDMA_6) speed--; break; | |
18604 | + case 0x03: // while (speed > XFER_UDMA_5) speed--; break; | |
18605 | + case 0x02: while (speed > XFER_UDMA_4) speed--; break; | |
18606 | + case 0x01: while (speed > XFER_UDMA_2) speed--; break; | |
18607 | + case 0x00: | |
18608 | + default: while (speed > XFER_MW_DMA_2) speed--; break; | |
18609 | + break; | |
18610 | + } | |
18611 | +#else | |
18612 | + while (speed > XFER_PIO_4) speed--; | |
18613 | +#endif /* CONFIG_BLK_DEV_IDEDMA */ | |
18614 | +// printk("%s: mode == %02x speed == %02x\n", drive->name, mode, speed); | |
18615 | + return speed; | |
18616 | +} | |
18617 | ||
18618 | static void it8172_tune_drive (ide_drive_t *drive, byte pio) | |
18619 | { | |
18620 | - unsigned long flags; | |
18621 | - u16 master_data; | |
18622 | - u32 slave_data; | |
18623 | - int is_slave = (&HWIF(drive)->drives[1] == drive); | |
18624 | - int master_port = 0x40; | |
18625 | - int slave_port = 0x44; | |
18626 | - | |
18627 | - pio = ide_get_best_pio_mode(drive, pio, 5, NULL); | |
18628 | - pci_read_config_word(HWIF(drive)->pci_dev, master_port, &master_data); | |
18629 | - pci_read_config_dword(HWIF(drive)->pci_dev, slave_port, &slave_data); | |
18630 | + ide_hwif_t *hwif = HWIF(drive); | |
18631 | + struct pci_dev *dev = hwif->pci_dev; | |
18632 | + int is_slave = (hwif->drives[1] == drive); | |
18633 | + unsigned long flags; | |
18634 | + u16 drive_enables; | |
18635 | + u32 drive_timing; | |
18636 | + | |
18637 | + pio = ide_get_best_pio_mode(drive, pio, 4, NULL); | |
18638 | + spin_lock_irqsave(&io_request_lock, flags); | |
18639 | + pci_read_config_word(dev, 0x40, &drive_enables); | |
18640 | + pci_read_config_dword(dev, 0x44, &drive_timing); | |
18641 | + | |
18642 | + /* | |
18643 | + * FIX! The DIOR/DIOW pulse width and recovery times in port 0x44 | |
18644 | + * are being left at the default values of 8 PCI clocks (242 nsec | |
18645 | + * for a 33 MHz clock). These can be safely shortened at higher | |
18646 | + * PIO modes. The DIOR/DIOW pulse width and recovery times only | |
18647 | + * apply to PIO modes, not to the DMA modes. | |
18648 | + */ | |
18649 | + | |
18650 | + /* | |
18651 | + * Enable port 0x44. The IT8172G spec is confused; it calls | |
18652 | + * this register the "Slave IDE Timing Register", but in fact, | |
18653 | + * it controls timing for both master and slave drives. | |
18654 | + */ | |
18655 | + drive_enables |= 0x4000; | |
18656 | + | |
18657 | + if (is_slave) { | |
18658 | + drive_enables &= 0xc006; | |
18659 | + if (pio > 1) | |
18660 | + /* enable prefetch and IORDY sample-point */ | |
18661 | + drive_enables |= 0x0060; | |
18662 | + } else { | |
18663 | + drive_enables &= 0xc060; | |
18664 | + if (pio > 1) | |
18665 | + /* enable prefetch and IORDY sample-point */ | |
18666 | + drive_enables |= 0x0006; | |
18667 | + } | |
18668 | ||
18669 | - /* | |
18670 | - * FIX! The DIOR/DIOW pulse width and recovery times in port 0x44 | |
18671 | - * are being left at the default values of 8 PCI clocks (242 nsec | |
18672 | - * for a 33 MHz clock). These can be safely shortened at higher | |
18673 | - * PIO modes. | |
18674 | - */ | |
18675 | - | |
18676 | - if (is_slave) { | |
18677 | - master_data |= 0x4000; | |
18678 | - if (pio > 1) | |
18679 | - /* enable PPE and IE */ | |
18680 | - master_data |= 0x0060; | |
18681 | - } else { | |
18682 | - master_data &= 0xc060; | |
18683 | - if (pio > 1) | |
18684 | - /* enable PPE and IE */ | |
18685 | - master_data |= 0x0006; | |
18686 | - } | |
18687 | - | |
18688 | - save_flags(flags); | |
18689 | - cli(); | |
18690 | - pci_write_config_word(HWIF(drive)->pci_dev, master_port, master_data); | |
18691 | - restore_flags(flags); | |
18692 | + pci_write_config_word(dev, 0x40, drive_enables); | |
18693 | + spin_unlock_irqrestore(&io_request_lock, flags) | |
18694 | } | |
18695 | ||
18696 | -#if defined(CONFIG_BLK_DEV_IDEDMA) && defined(CONFIG_IT8172_TUNING) | |
18697 | -/* | |
18698 | - * | |
18699 | - */ | |
18700 | static byte it8172_dma_2_pio (byte xfer_rate) | |
18701 | { | |
18702 | - switch(xfer_rate) { | |
18703 | - case XFER_UDMA_5: | |
18704 | - case XFER_UDMA_4: | |
18705 | - case XFER_UDMA_3: | |
18706 | - case XFER_UDMA_2: | |
18707 | - case XFER_UDMA_1: | |
18708 | - case XFER_UDMA_0: | |
18709 | - case XFER_MW_DMA_2: | |
18710 | - case XFER_PIO_4: | |
18711 | - return 4; | |
18712 | - case XFER_MW_DMA_1: | |
18713 | - case XFER_PIO_3: | |
18714 | - return 3; | |
18715 | - case XFER_SW_DMA_2: | |
18716 | - case XFER_PIO_2: | |
18717 | - return 2; | |
18718 | - case XFER_MW_DMA_0: | |
18719 | - case XFER_SW_DMA_1: | |
18720 | - case XFER_SW_DMA_0: | |
18721 | - case XFER_PIO_1: | |
18722 | - case XFER_PIO_0: | |
18723 | - case XFER_PIO_SLOW: | |
18724 | - default: | |
18725 | - return 0; | |
18726 | - } | |
18727 | -} | |
18728 | - | |
18729 | -static int it8172_tune_chipset (ide_drive_t *drive, byte speed) | |
18730 | -{ | |
18731 | - ide_hwif_t *hwif = HWIF(drive); | |
18732 | - struct pci_dev *dev = hwif->pci_dev; | |
18733 | - int a_speed = 3 << (drive->dn * 4); | |
18734 | - int u_flag = 1 << drive->dn; | |
18735 | - int u_speed = 0; | |
18736 | - int err = 0; | |
18737 | - byte reg48, reg4a; | |
18738 | + switch(xfer_rate) { | |
18739 | + case XFER_UDMA_5: | |
18740 | + case XFER_UDMA_4: | |
18741 | + case XFER_UDMA_3: | |
18742 | + case XFER_UDMA_2: | |
18743 | + case XFER_UDMA_1: | |
18744 | + case XFER_UDMA_0: | |
18745 | + case XFER_MW_DMA_2: | |
18746 | + case XFER_PIO_4: | |
18747 | + return 4; | |
18748 | + case XFER_MW_DMA_1: | |
18749 | + case XFER_PIO_3: | |
18750 | + return 3; | |
18751 | + case XFER_SW_DMA_2: | |
18752 | + case XFER_PIO_2: | |
18753 | + return 2; | |
18754 | + case XFER_MW_DMA_0: | |
18755 | + case XFER_SW_DMA_1: | |
18756 | + case XFER_SW_DMA_0: | |
18757 | + case XFER_PIO_1: | |
18758 | + case XFER_PIO_0: | |
18759 | + case XFER_PIO_SLOW: | |
18760 | + default: | |
18761 | + return 0; | |
18762 | + } | |
18763 | +} | |
18764 | ||
18765 | - pci_read_config_byte(dev, 0x48, ®48); | |
18766 | - pci_read_config_byte(dev, 0x4a, ®4a); | |
18767 | +static int it8172_tune_chipset (ide_drive_t *drive, byte xferspeed) | |
18768 | +{ | |
18769 | + ide_hwif_t *hwif = HWIF(drive); | |
18770 | + struct pci_dev *dev = hwif->pci_dev; | |
18771 | + byte speed = it8172_ratefilter(drive, xferspeed); | |
18772 | + int a_speed = 3 << (drive->dn * 4); | |
18773 | + int u_flag = 1 << drive->dn; | |
18774 | + int u_speed = 0; | |
18775 | + byte reg48, reg4a; | |
18776 | + | |
18777 | + pci_read_config_byte(dev, 0x48, ®48); | |
18778 | + pci_read_config_byte(dev, 0x4a, ®4a); | |
18779 | ||
18780 | /* | |
18781 | * Setting the DMA cycle time to 2 or 3 PCI clocks (60 and 91 nsec | |
18782 | @@ -151,127 +185,205 @@ | |
18783 | * performance. | |
18784 | */ | |
18785 | ||
18786 | - switch(speed) { | |
18787 | - case XFER_UDMA_4: | |
18788 | - case XFER_UDMA_2: //u_speed = 2 << (drive->dn * 4); break; | |
18789 | - case XFER_UDMA_5: | |
18790 | - case XFER_UDMA_3: | |
18791 | - case XFER_UDMA_1: //u_speed = 1 << (drive->dn * 4); break; | |
18792 | - case XFER_UDMA_0: u_speed = 0 << (drive->dn * 4); break; | |
18793 | - case XFER_MW_DMA_2: | |
18794 | - case XFER_MW_DMA_1: | |
18795 | - case XFER_SW_DMA_2: break; | |
18796 | - default: return -1; | |
18797 | - } | |
18798 | - | |
18799 | - if (speed >= XFER_UDMA_0) { | |
18800 | - pci_write_config_byte(dev, 0x48, reg48 | u_flag); | |
18801 | - reg4a &= ~a_speed; | |
18802 | - pci_write_config_byte(dev, 0x4a, reg4a | u_speed); | |
18803 | - } else { | |
18804 | - pci_write_config_byte(dev, 0x48, reg48 & ~u_flag); | |
18805 | - pci_write_config_byte(dev, 0x4a, reg4a & ~a_speed); | |
18806 | - } | |
18807 | - | |
18808 | - it8172_tune_drive(drive, it8172_dma_2_pio(speed)); | |
18809 | - | |
18810 | - if (!drive->init_speed) | |
18811 | - drive->init_speed = speed; | |
18812 | - err = ide_config_drive_speed(drive, speed); | |
18813 | - drive->current_speed = speed; | |
18814 | - return err; | |
18815 | -} | |
18816 | - | |
18817 | -static int it8172_config_drive_for_dma (ide_drive_t *drive) | |
18818 | -{ | |
18819 | - struct hd_driveid *id = drive->id; | |
18820 | - byte speed; | |
18821 | - | |
18822 | - if (id->dma_ultra & 0x0010) { | |
18823 | - speed = XFER_UDMA_2; | |
18824 | - } else if (id->dma_ultra & 0x0008) { | |
18825 | - speed = XFER_UDMA_1; | |
18826 | - } else if (id->dma_ultra & 0x0004) { | |
18827 | - speed = XFER_UDMA_2; | |
18828 | - } else if (id->dma_ultra & 0x0002) { | |
18829 | - speed = XFER_UDMA_1; | |
18830 | - } else if (id->dma_ultra & 0x0001) { | |
18831 | - speed = XFER_UDMA_0; | |
18832 | - } else if (id->dma_mword & 0x0004) { | |
18833 | - speed = XFER_MW_DMA_2; | |
18834 | - } else if (id->dma_mword & 0x0002) { | |
18835 | - speed = XFER_MW_DMA_1; | |
18836 | - } else if (id->dma_1word & 0x0004) { | |
18837 | - speed = XFER_SW_DMA_2; | |
18838 | - } else { | |
18839 | - speed = XFER_PIO_0 + ide_get_best_pio_mode(drive, 255, 5, NULL); | |
18840 | - } | |
18841 | - | |
18842 | - (void) it8172_tune_chipset(drive, speed); | |
18843 | - | |
18844 | - return ((int)((id->dma_ultra >> 11) & 7) ? ide_dma_on : | |
18845 | - ((id->dma_ultra >> 8) & 7) ? ide_dma_on : | |
18846 | - ((id->dma_mword >> 8) & 7) ? ide_dma_on : | |
18847 | - ((id->dma_1word >> 8) & 7) ? ide_dma_on : | |
18848 | - ide_dma_off_quietly); | |
18849 | + switch(speed) { | |
18850 | +#ifdef CONFIG_BLK_DEV_IDEDMA | |
18851 | + case XFER_UDMA_4: | |
18852 | + case XFER_UDMA_2: //u_speed = 2 << (drive->dn * 4); break; | |
18853 | + case XFER_UDMA_5: | |
18854 | + case XFER_UDMA_3: | |
18855 | + case XFER_UDMA_1: //u_speed = 1 << (drive->dn * 4); break; | |
18856 | + case XFER_UDMA_0: u_speed = 0 << (drive->dn * 4); break; | |
18857 | + case XFER_MW_DMA_2: | |
18858 | + case XFER_MW_DMA_1: | |
18859 | + case XFER_MW_DMA_0: | |
18860 | + case XFER_SW_DMA_2: break; | |
18861 | +#endif /* CONFIG_BLK_DEV_IDEDMA */ | |
18862 | + case XFER_PIO_4: | |
18863 | + case XFER_PIO_3: | |
18864 | + case XFER_PIO_2: | |
18865 | + case XFER_PIO_0: break; | |
18866 | + default: return -1; | |
18867 | + } | |
18868 | + | |
18869 | + if (speed >= XFER_UDMA_0) { | |
18870 | + pci_write_config_byte(dev, 0x48, reg48 | u_flag); | |
18871 | + reg4a &= ~a_speed; | |
18872 | + pci_write_config_byte(dev, 0x4a, reg4a | u_speed); | |
18873 | + } else { | |
18874 | + pci_write_config_byte(dev, 0x48, reg48 & ~u_flag); | |
18875 | + pci_write_config_byte(dev, 0x4a, reg4a & ~a_speed); | |
18876 | + } | |
18877 | + | |
18878 | + it8172_tune_drive(drive, it8172_dma_2_pio(speed)); | |
18879 | + return (ide_config_drive_speed(drive, speed)); | |
18880 | } | |
18881 | ||
18882 | -static int it8172_dmaproc(ide_dma_action_t func, ide_drive_t *drive) | |
18883 | +#ifdef CONFIG_BLK_DEV_IDEDMA | |
18884 | +static int it8172_config_chipset_for_dma (ide_drive_t *drive) | |
18885 | { | |
18886 | - switch (func) { | |
18887 | - case ide_dma_check: | |
18888 | - return ide_dmaproc((ide_dma_action_t)it8172_config_drive_for_dma(drive), | |
18889 | - drive); | |
18890 | - default : | |
18891 | - break; | |
18892 | - } | |
18893 | - /* Other cases are done by generic IDE-DMA code. */ | |
18894 | - return ide_dmaproc(func, drive); | |
18895 | + struct hd_driveid *id = drive->id; | |
18896 | + byte mode = it8172_ratemask(drive); | |
18897 | + byte speed, tspeed, dma = 1; | |
18898 | + | |
18899 | + switch(mode) { | |
18900 | + case 0x01: | |
18901 | + if (id->dma_ultra & 0x0040) | |
18902 | + { speed = XFER_UDMA_2; break; } | |
18903 | + if (id->dma_ultra & 0x0020) | |
18904 | + { speed = XFER_UDMA_2; break; } | |
18905 | + if (id->dma_ultra & 0x0010) | |
18906 | + { speed = XFER_UDMA_2; break; } | |
18907 | + if (id->dma_ultra & 0x0008) | |
18908 | + { speed = XFER_UDMA_2; break; } | |
18909 | + if (id->dma_ultra & 0x0004) | |
18910 | + { speed = XFER_UDMA_2; break; } | |
18911 | + if (id->dma_ultra & 0x0002) | |
18912 | + { speed = XFER_UDMA_1; break; } | |
18913 | + if (id->dma_ultra & 0x0001) | |
18914 | + { speed = XFER_UDMA_0; break; } | |
18915 | + case 0x00: | |
18916 | + if (id->dma_mword & 0x0004) | |
18917 | + { speed = XFER_MW_DMA_2; break; } | |
18918 | + if (id->dma_mword & 0x0002) | |
18919 | + { speed = XFER_MW_DMA_1; break; } | |
18920 | + if (id->dma_1word & 0x0004) | |
18921 | + { speed = XFER_SW_DMA_2; break; } | |
18922 | + default: | |
18923 | + tspeed = ide_get_best_pio_mode(drive, 255, 4, NULL); | |
18924 | + speed = it8172_dma_2_pio(XFER_PIO_0 + tspeed); | |
18925 | + dma = 0; | |
18926 | + break; | |
18927 | + } | |
18928 | + | |
18929 | + (void) it8172_tune_chipset(drive, speed); | |
18930 | + | |
18931 | +// return ((int)(dma) ? ide_dma_on : ide_dma_off_quietly); | |
18932 | + return ((int)((id->dma_ultra >> 11) & 7) ? ide_dma_on : | |
18933 | + ((id->dma_ultra >> 8) & 7) ? ide_dma_on : | |
18934 | + ((id->dma_mword >> 8) & 7) ? ide_dma_on : | |
18935 | + ((id->dma_1word >> 8) & 7) ? ide_dma_on : | |
18936 | + ide_dma_off_quietly); | |
18937 | } | |
18938 | ||
18939 | -#endif /* defined(CONFIG_BLK_DEV_IDEDMA) && (CONFIG_IT8172_TUNING) */ | |
18940 | +static int config_drive_xfer_rate (ide_drive_t *drive) | |
18941 | +{ | |
18942 | + struct hd_driveid *id = drive->id; | |
18943 | + ide_dma_action_t dma_func = ide_dma_on; | |
18944 | + | |
18945 | + drive->init_speed = 0; | |
18946 | + | |
18947 | + if (id && (id->capability & 1) && HWIF(drive)->autodma) { | |
18948 | + /* Consult the list of known "bad" drives */ | |
18949 | + if (ide_dmaproc(ide_dma_bad_drive, drive)) { | |
18950 | + dma_func = ide_dma_off; | |
18951 | + goto fast_ata_pio; | |
18952 | + } | |
18953 | + dma_func = ide_dma_off_quietly; | |
18954 | + if (id->field_valid & 4) { | |
18955 | + if (id->dma_ultra & 0x007F) { | |
18956 | + /* Force if Capable UltraDMA */ | |
18957 | + dma_func = it8172_config_chipset_for_dma(drive); | |
18958 | + if ((id->field_valid & 2) && | |
18959 | + (dma_func != ide_dma_on)) | |
18960 | + goto try_dma_modes; | |
18961 | + } | |
18962 | + } else if (id->field_valid & 2) { | |
18963 | +try_dma_modes: | |
18964 | + if ((id->dma_mword & 0x0007) || | |
18965 | + (id->dma_1word & 0x007)) { | |
18966 | + /* Force if Capable regular DMA modes */ | |
18967 | + dma_func = it8172_config_chipset_for_dma(drive); | |
18968 | + if (dma_func != ide_dma_on) | |
18969 | + goto no_dma_set; | |
18970 | + } | |
18971 | + } else if (ide_dmaproc(ide_dma_good_drive, drive)) { | |
18972 | + if (id->eide_dma_time > 150) { | |
18973 | + goto no_dma_set; | |
18974 | + } | |
18975 | + /* Consult the list of known "good" drives */ | |
18976 | + dma_func = it8172_config_chipset_for_dma(drive); | |
18977 | + if (dma_func != ide_dma_on) | |
18978 | + goto no_dma_set; | |
18979 | + } else { | |
18980 | + goto fast_ata_pio; | |
18981 | + } | |
18982 | + } else if ((id->capability & 8) || (id->field_valid & 2)) { | |
18983 | +fast_ata_pio: | |
18984 | + dma_func = ide_dma_off_quietly; | |
18985 | +no_dma_set: | |
18986 | + it8172_tune_drive(drive, 5); | |
18987 | + } | |
18988 | + return HWIF(drive)->dmaproc(dma_func, drive); | |
18989 | +} | |
18990 | + | |
18991 | +static int it8172_dmaproc(ide_dma_action_t func, ide_drive_t *drive) | |
18992 | +{ | |
18993 | + switch (func) { | |
18994 | + case ide_dma_check: | |
18995 | + return config_drive_xfer_rate(drive); | |
18996 | + default : | |
18997 | + break; | |
18998 | + } | |
18999 | + /* Other cases are done by generic IDE-DMA code. */ | |
19000 | + return ide_dmaproc(func, drive); | |
19001 | +} | |
19002 | +#endif /* CONFIG_BLK_DEV_IDEDMA */ | |
19003 | ||
19004 | ||
19005 | unsigned int __init pci_init_it8172 (struct pci_dev *dev, const char *name) | |
19006 | { | |
19007 | - unsigned char progif; | |
19008 | + unsigned char progif; | |
19009 | ||
19010 | - /* | |
19011 | - * Place both IDE interfaces into PCI "native" mode | |
19012 | - */ | |
19013 | - (void)pci_read_config_byte(dev, PCI_CLASS_PROG, &progif); | |
19014 | - (void)pci_write_config_byte(dev, PCI_CLASS_PROG, progif | 0x05); | |
19015 | + /* | |
19016 | + * Place both IDE interfaces into PCI "native" mode | |
19017 | + */ | |
19018 | + pci_read_config_byte(dev, PCI_CLASS_PROG, &progif); | |
19019 | + pci_write_config_byte(dev, PCI_CLASS_PROG, progif | 0x05); | |
19020 | ||
19021 | - return IT8172_IDE_IRQ; | |
19022 | + return IT8172_IDE_IRQ; | |
19023 | } | |
19024 | ||
19025 | ||
19026 | void __init ide_init_it8172 (ide_hwif_t *hwif) | |
19027 | { | |
19028 | - struct pci_dev* dev = hwif->pci_dev; | |
19029 | - unsigned long cmdBase, ctrlBase; | |
19030 | + struct pci_dev* dev = hwif->pci_dev; | |
19031 | + unsigned long cmdBase, ctrlBase; | |
19032 | ||
19033 | - hwif->tuneproc = &it8172_tune_drive; | |
19034 | - hwif->drives[0].autotune = 1; | |
19035 | - hwif->drives[1].autotune = 1; | |
19036 | - | |
19037 | - if (!hwif->dma_base) | |
19038 | - return; | |
19039 | - | |
19040 | -#ifndef CONFIG_BLK_DEV_IDEDMA | |
19041 | - hwif->autodma = 0; | |
19042 | -#else /* CONFIG_BLK_DEV_IDEDMA */ | |
19043 | -#ifdef CONFIG_IT8172_TUNING | |
19044 | - hwif->autodma = 1; | |
19045 | - hwif->dmaproc = &it8172_dmaproc; | |
19046 | - hwif->speedproc = &it8172_tune_chipset; | |
19047 | -#endif /* CONFIG_IT8172_TUNING */ | |
19048 | -#endif /* !CONFIG_BLK_DEV_IDEDMA */ | |
19049 | + hwif->autodma = 0; | |
19050 | + hwif->tuneproc = &it8172_tune_drive; | |
19051 | + hwif->speedproc = &it8172_tune_chipset; | |
19052 | + hwif->drives[0].autotune = 1; | |
19053 | + hwif->drives[1].autotune = 1; | |
19054 | ||
19055 | - cmdBase = dev->resource[0].start; | |
19056 | - ctrlBase = dev->resource[1].start; | |
19057 | + cmdBase = dev->resource[0].start; | |
19058 | + ctrlBase = dev->resource[1].start; | |
19059 | ||
19060 | - ide_init_hwif_ports(&hwif->hw, cmdBase, ctrlBase | 2, NULL); | |
19061 | - memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->io_ports)); | |
19062 | - hwif->noprobe = 0; | |
19063 | + ide_init_hwif_ports(&hwif->hw, cmdBase, ctrlBase | 2, NULL); | |
19064 | + memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->io_ports)); | |
19065 | + hwif->noprobe = 0; | |
19066 | + | |
19067 | + if (!hwif->dma_base) | |
19068 | + return; | |
19069 | + | |
19070 | +#ifdef CONFIG_BLK_DEV_IDEDMA | |
19071 | + hwif->dmaproc = &it8172_dmaproc; | |
19072 | +# ifdef CONFIG_IDEDMA_AUTO | |
19073 | + if (!noautodma) | |
19074 | + hwif->autodma = 1; | |
19075 | +# endif /* CONFIG_IDEDMA_AUTO */ | |
19076 | +#endif /* !CONFIG_BLK_DEV_IDEDMA */ | |
19077 | +} | |
19078 | + | |
19079 | +extern void ide_setup_pci_device (struct pci_dev *dev, ide_pci_device_t *d); | |
19080 | + | |
19081 | +void __init fixup_device_it8172 (struct pci_dev *dev, ide_pci_device_t *d) | |
19082 | +{ | |
19083 | + if ((!(PCI_FUNC(dev->devfn) & 1) || | |
19084 | + (!((dev->class >> 8) == PCI_CLASS_STORAGE_IDE)))) | |
19085 | + return; /* IT8172 is more than only a IDE controller */ | |
19086 | + | |
19087 | + printk("%s: IDE controller on PCI bus %02x dev %02x\n", | |
19088 | + d->name, dev->bus->number, dev->devfn); | |
19089 | + ide_setup_pci_device(dev, d); | |
19090 | } | |
19091 | + | |
19092 | diff -Nur linux.org/drivers/ide/ns87415.c linux/drivers/ide/ns87415.c | |
19093 | --- linux.org/drivers/ide/ns87415.c Tue Jun 20 16:52:36 2000 | |
19094 | +++ linux/drivers/ide/ns87415.c Thu Jul 18 14:24:33 2002 | |
19095 | @@ -24,6 +24,10 @@ | |
19096 | ||
19097 | #include <asm/io.h> | |
19098 | ||
19099 | +#if defined(__hppa__) && defined(CONFIG_SUPERIO) | |
19100 | +#include <asm/superio.h> | |
19101 | +#endif | |
19102 | + | |
19103 | static unsigned int ns87415_count = 0, ns87415_control[MAX_HWIFS] = { 0 }; | |
19104 | ||
19105 | /* | |
19106 | @@ -38,8 +42,7 @@ | |
19107 | struct pci_dev *dev = hwif->pci_dev; | |
19108 | unsigned long flags; | |
19109 | ||
19110 | - __save_flags(flags); /* local CPU only */ | |
19111 | - __cli(); /* local CPU only */ | |
19112 | + local_irq_save(flags); | |
19113 | new = *old; | |
19114 | ||
19115 | /* Adjust IRQ enable bit */ | |
19116 | @@ -73,7 +76,7 @@ | |
19117 | udelay(10); | |
19118 | } | |
19119 | ||
19120 | - __restore_flags(flags); /* local CPU only */ | |
19121 | + local_irq_restore(flags); | |
19122 | } | |
19123 | ||
19124 | static void ns87415_selectproc (ide_drive_t *drive) | |
19125 | @@ -90,17 +93,24 @@ | |
19126 | switch (func) { | |
19127 | case ide_dma_end: /* returns 1 on error, 0 otherwise */ | |
19128 | drive->waiting_for_dma = 0; | |
19129 | - dma_stat = inb(hwif->dma_base+2); | |
19130 | - outb(inb(hwif->dma_base)&~1, hwif->dma_base); /* stop DMA */ | |
19131 | - outb(inb(hwif->dma_base)|6, hwif->dma_base); /* from ERRATA: clear the INTR & ERROR bits */ | |
19132 | - ide_destroy_dmatable(drive); /* and free any DMA resources */ | |
19133 | - return (dma_stat & 7) != 4; /* verify good DMA status */ | |
19134 | + dma_stat = IN_BYTE(hwif->dma_base+2); | |
19135 | + /* stop DMA */ | |
19136 | + OUT_BYTE(IN_BYTE(hwif->dma_base)&~1, hwif->dma_base); | |
19137 | + /* from ERRATA: clear the INTR & ERROR bits */ | |
19138 | + OUT_BYTE(IN_BYTE(hwif->dma_base)|6, hwif->dma_base); | |
19139 | + /* and free any DMA resources */ | |
19140 | + ide_destroy_dmatable(drive); | |
19141 | + /* verify good DMA status */ | |
19142 | + return (dma_stat & 7) != 4; | |
19143 | case ide_dma_write: | |
19144 | case ide_dma_read: | |
19145 | - ns87415_prepare_drive(drive, 1); /* select DMA xfer */ | |
19146 | - if (!ide_dmaproc(func, drive)) /* use standard DMA stuff */ | |
19147 | + /* select DMA xfer */ | |
19148 | + ns87415_prepare_drive(drive, 1); | |
19149 | + /* use standard DMA stuff */ | |
19150 | + if (!ide_dmaproc(func, drive)) | |
19151 | return 0; | |
19152 | - ns87415_prepare_drive(drive, 0); /* DMA failed: select PIO xfer */ | |
19153 | + /* DMA failed: select PIO xfer */ | |
19154 | + ns87415_prepare_drive(drive, 0); | |
19155 | return 1; | |
19156 | case ide_dma_check: | |
19157 | if (drive->media != ide_disk) | |
19158 | @@ -122,6 +132,9 @@ | |
19159 | byte stat; | |
19160 | #endif | |
19161 | ||
19162 | + hwif->autodma = 0; | |
19163 | + hwif->selectproc = &ns87415_selectproc; | |
19164 | + | |
19165 | /* Set a good latency timer and cache line size value. */ | |
19166 | (void) pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64); | |
19167 | #ifdef __sparc_v9__ | |
19168 | @@ -164,30 +177,36 @@ | |
19169 | * to SELECT_DRIVE() properly during first probe_hwif(). | |
19170 | */ | |
19171 | timeout = 10000; | |
19172 | - outb(12, hwif->io_ports[IDE_CONTROL_OFFSET]); | |
19173 | + OUT_BYTE(12, hwif->io_ports[IDE_CONTROL_OFFSET]); | |
19174 | udelay(10); | |
19175 | - outb(8, hwif->io_ports[IDE_CONTROL_OFFSET]); | |
19176 | + OUT_BYTE(8, hwif->io_ports[IDE_CONTROL_OFFSET]); | |
19177 | do { | |
19178 | udelay(50); | |
19179 | - stat = inb(hwif->io_ports[IDE_STATUS_OFFSET]); | |
19180 | + stat = IN_BYTE(hwif->io_ports[IDE_STATUS_OFFSET]); | |
19181 | if (stat == 0xff) | |
19182 | break; | |
19183 | } while ((stat & BUSY_STAT) && --timeout); | |
19184 | #endif | |
19185 | } | |
19186 | ||
19187 | - if (hwif->dma_base) | |
19188 | - outb(0x60, hwif->dma_base + 2); | |
19189 | - | |
19190 | if (!using_inta) | |
19191 | +#if defined(__hppa__) && defined(CONFIG_SUPERIO) | |
19192 | + hwif->irq = superio_get_ide_irq(); /* legacy mode */ | |
19193 | +#else | |
19194 | hwif->irq = hwif->channel ? 15 : 14; /* legacy mode */ | |
19195 | +#endif | |
19196 | else if (!hwif->irq && hwif->mate && hwif->mate->irq) | |
19197 | hwif->irq = hwif->mate->irq; /* share IRQ with mate */ | |
19198 | ||
19199 | + if (!hwif->dma_base) | |
19200 | + return; | |
19201 | + | |
19202 | #ifdef CONFIG_BLK_DEV_IDEDMA | |
19203 | - if (hwif->dma_base) | |
19204 | - hwif->dmaproc = &ns87415_dmaproc; | |
19205 | + OUT_BYTE(0x60, hwif->dma_base + 2); | |
19206 | + hwif->dmaproc = &ns87415_dmaproc; | |
19207 | +#ifdef CONFIG_IDEDMA_AUTO | |
19208 | + if (!noautodma) | |
19209 | + hwif->autodma = 1; | |
19210 | +#endif /* CONFIG_IDEDMA_AUTO */ | |
19211 | #endif /* CONFIG_BLK_DEV_IDEDMA */ | |
19212 | - | |
19213 | - hwif->selectproc = &ns87415_selectproc; | |
19214 | } | |
19215 | diff -Nur linux.org/drivers/ide/opti621.c linux/drivers/ide/opti621.c | |
19216 | --- linux.org/drivers/ide/opti621.c Wed May 2 01:05:00 2001 | |
19217 | +++ linux/drivers/ide/opti621.c Thu Jul 18 14:24:34 2002 | |
19218 | @@ -97,6 +97,7 @@ | |
19219 | #include <linux/mm.h> | |
19220 | #include <linux/ioport.h> | |
19221 | #include <linux/blkdev.h> | |
19222 | +#include <linux/pci.h> | |
19223 | #include <linux/hdreg.h> | |
19224 | #include <linux/ide.h> | |
19225 | ||
19226 | @@ -183,11 +184,11 @@ | |
19227 | * This is from setupvic.exe program. | |
19228 | */ | |
19229 | { | |
19230 | - inw(reg_base+1); | |
19231 | - inw(reg_base+1); | |
19232 | - outb(3, reg_base+2); | |
19233 | - outb(value, reg_base+reg); | |
19234 | - outb(0x83, reg_base+2); | |
19235 | + IN_WORD(reg_base+1); | |
19236 | + IN_WORD(reg_base+1); | |
19237 | + OUT_BYTE(3, reg_base+2); | |
19238 | + OUT_BYTE(value, reg_base+reg); | |
19239 | + OUT_BYTE(0x83, reg_base+2); | |
19240 | } | |
19241 | ||
19242 | static byte read_reg(int reg) | |
19243 | @@ -198,11 +199,11 @@ | |
19244 | */ | |
19245 | { | |
19246 | byte ret; | |
19247 | - inw(reg_base+1); | |
19248 | - inw(reg_base+1); | |
19249 | - outb(3, reg_base+2); | |
19250 | - ret=inb(reg_base+reg); | |
19251 | - outb(0x83, reg_base+2); | |
19252 | + IN_WORD(reg_base+1); | |
19253 | + IN_WORD(reg_base+1); | |
19254 | + OUT_BYTE(3, reg_base+2); | |
19255 | + ret=IN_BYTE(reg_base+reg); | |
19256 | + OUT_BYTE(0x83, reg_base+2); | |
19257 | return ret; | |
19258 | } | |
19259 | ||
19260 | @@ -276,13 +277,12 @@ | |
19261 | hwif->name, ax, second.data_time, second.recovery_time, drdy); | |
19262 | #endif | |
19263 | ||
19264 | - save_flags(flags); /* all CPUs */ | |
19265 | - cli(); /* all CPUs */ | |
19266 | + spin_lock_irqsave(&io_request_lock, flags); | |
19267 | ||
19268 | reg_base = hwif->io_ports[IDE_DATA_OFFSET]; | |
19269 | - outb(0xc0, reg_base+CNTRL_REG); /* allow Register-B */ | |
19270 | - outb(0xff, reg_base+5); /* hmm, setupvic.exe does this ;-) */ | |
19271 | - inb(reg_base+CNTRL_REG); /* if reads 0xff, adapter not exist? */ | |
19272 | + OUT_BYTE(0xc0, reg_base+CNTRL_REG); /* allow Register-B */ | |
19273 | + OUT_BYTE(0xff, reg_base+5); /* hmm, setupvic.exe does this ;-) */ | |
19274 | + IN_BYTE(reg_base+CNTRL_REG); /* if reads 0xff, adapter not exist? */ | |
19275 | read_reg(CNTRL_REG); /* if reads 0xc0, no interface exist? */ | |
19276 | read_reg(STRAP_REG); /* read version, probably 0 */ | |
19277 | ||
19278 | @@ -302,7 +302,7 @@ | |
19279 | write_reg(misc, MISC_REG); /* set address setup, DRDY timings, */ | |
19280 | /* and read prefetch for both drives */ | |
19281 | ||
19282 | - restore_flags(flags); /* all CPUs */ | |
19283 | + spin_unlock_irqrestore(&io_request_lock, flags); | |
19284 | } | |
19285 | ||
19286 | /* | |
19287 | @@ -310,7 +310,30 @@ | |
19288 | */ | |
19289 | void __init ide_init_opti621 (ide_hwif_t *hwif) | |
19290 | { | |
19291 | + hwif->autodma = 0; | |
19292 | hwif->drives[0].drive_data = PIO_DONT_KNOW; | |
19293 | hwif->drives[1].drive_data = PIO_DONT_KNOW; | |
19294 | hwif->tuneproc = &opti621_tune_drive; | |
19295 | + | |
19296 | + /* safety call for Anton A */ | |
19297 | + hwif->dma_base = 0; | |
19298 | +} | |
19299 | + | |
19300 | +extern void ide_setup_pci_device (struct pci_dev *dev, ide_pci_device_t *d); | |
19301 | + | |
19302 | +void __init fixup_device_opti621 (struct pci_dev *dev, ide_pci_device_t *d) | |
19303 | +{ | |
19304 | +#if 0 | |
19305 | + if (IDE_PCI_DEVID_EQ(d->devid, DEVID_OPTI621V) && | |
19306 | + !(PCI_FUNC(dev->devfn) & 1)) | |
19307 | +#else | |
19308 | + if ((dev->device == PCI_DEVICE_ID_OPTI_82C558) && | |
19309 | + (!(PCI_FUNC(dev->devfn) & 1))) | |
19310 | +#endif | |
19311 | + return; /* OPTI621 is more than only a IDE controller */ | |
19312 | + | |
19313 | + printk("%s: IDE controller on PCI bus %02x dev %02x\n", | |
19314 | + d->name, dev->bus->number, dev->devfn); | |
19315 | + ide_setup_pci_device(dev, d); | |
19316 | } | |
19317 | + | |
19318 | diff -Nur linux.org/drivers/ide/pdc202xx.c linux/drivers/ide/pdc202xx.c | |
19319 | --- linux.org/drivers/ide/pdc202xx.c Wed Nov 14 20:44:03 2001 | |
19320 | +++ linux/drivers/ide/pdc202xx.c Thu Jul 18 14:24:34 2002 | |
19321 | @@ -1,8 +1,7 @@ | |
19322 | /* | |
19323 | - * linux/drivers/ide/pdc202xx.c Version 0.30 Mar. 18, 2000 | |
19324 | + * linux/drivers/ide/pdc202xx.c Version 0.35 Mar. 30, 2002 | |
19325 | * | |
19326 | - * Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org> | |
19327 | - * May be copied or modified under the terms of the GNU General Public License | |
19328 | + * Copyright (C) 1998-2002 Andre Hedrick <andre@linux-ide.org> | |
19329 | * | |
19330 | * Promise Ultra33 cards with BIOS v1.20 through 1.28 will need this | |
19331 | * compiled into the kernel if you have more than one card installed. | |
19332 | @@ -63,8 +62,25 @@ | |
19333 | ||
19334 | static int pdc202xx_get_info(char *, char **, off_t, int); | |
19335 | extern int (*pdc202xx_display_info)(char *, char **, off_t, int); /* ide-proc.c */ | |
19336 | -extern char *ide_media_verbose(ide_drive_t *); | |
19337 | -static struct pci_dev *bmide_dev; | |
19338 | + | |
19339 | +byte pdc202xx_proc = 0; | |
19340 | + | |
19341 | +#define PDC202_MAX_DEVS 5 | |
19342 | + | |
19343 | +static struct pci_dev *pdc202_devs[PDC202_MAX_DEVS]; | |
19344 | +static int n_pdc202_devs; | |
19345 | + | |
19346 | +const char *pdc_quirk_drives[] = { | |
19347 | + "QUANTUM FIREBALLlct08 08", | |
19348 | + "QUANTUM FIREBALLP KA6.4", | |
19349 | + "QUANTUM FIREBALLP KA9.1", | |
19350 | + "QUANTUM FIREBALLP LM20.4", | |
19351 | + "QUANTUM FIREBALLP KX13.6", | |
19352 | + "QUANTUM FIREBALLP KX20.5", | |
19353 | + "QUANTUM FIREBALLP KX27.3", | |
19354 | + "QUANTUM FIREBALLP LM20.5", | |
19355 | + NULL | |
19356 | +}; | |
19357 | ||
19358 | char *pdc202xx_pio_verbose (u32 drive_pci) | |
19359 | { | |
19360 | @@ -108,7 +124,7 @@ | |
19361 | u32 bibma = pci_resource_start(dev, 4); | |
19362 | u32 reg60h = 0, reg64h = 0, reg68h = 0, reg6ch = 0; | |
19363 | u16 reg50h = 0, pmask = (1<<10), smask = (1<<11); | |
19364 | - u8 hi = 0, lo = 0, invalid_data_set = 0; | |
19365 | + u8 hi = 0, lo = 0; | |
19366 | ||
19367 | /* | |
19368 | * at that point bibma+0x2 et bibma+0xa are byte registers | |
19369 | @@ -131,33 +147,31 @@ | |
19370 | pci_read_config_dword(dev, 0x68, ®68h); | |
19371 | pci_read_config_dword(dev, 0x6c, ®6ch); | |
19372 | ||
19373 | + p += sprintf(p, "\n "); | |
19374 | switch(dev->device) { | |
19375 | - case PCI_DEVICE_ID_PROMISE_20268: | |
19376 | - case PCI_DEVICE_ID_PROMISE_20268R: | |
19377 | - p += sprintf(p, "\n PDC20268 TX2 Chipset.\n"); | |
19378 | - invalid_data_set = 1; | |
19379 | - break; | |
19380 | case PCI_DEVICE_ID_PROMISE_20267: | |
19381 | - p += sprintf(p, "\n PDC20267 Chipset.\n"); | |
19382 | - break; | |
19383 | + p += sprintf(p, "Ultra100"); break; | |
19384 | case PCI_DEVICE_ID_PROMISE_20265: | |
19385 | - p += sprintf(p, "\n PDC20265 Chipset.\n"); | |
19386 | - break; | |
19387 | + p += sprintf(p, "Ultra100 on M/B"); break; | |
19388 | + case PCI_DEVICE_ID_PROMISE_20263: | |
19389 | + p += sprintf(p, "FastTrak 66"); break; | |
19390 | case PCI_DEVICE_ID_PROMISE_20262: | |
19391 | - p += sprintf(p, "\n PDC20262 Chipset.\n"); | |
19392 | - break; | |
19393 | + p += sprintf(p, "Ultra66"); break; | |
19394 | case PCI_DEVICE_ID_PROMISE_20246: | |
19395 | - p += sprintf(p, "\n PDC20246 Chipset.\n"); | |
19396 | + p += sprintf(p, "Ultra33"); | |
19397 | reg50h |= 0x0c00; | |
19398 | break; | |
19399 | default: | |
19400 | - p += sprintf(p, "\n PDC202XX Chipset.\n"); | |
19401 | - break; | |
19402 | + p += sprintf(p, "Ultra Series"); break; | |
19403 | } | |
19404 | + p += sprintf(p, " Chipset.\n"); | |
19405 | ||
19406 | - p += sprintf(p, "------------------------------- General Status ---------------------------------\n"); | |
19407 | - p += sprintf(p, "Burst Mode : %sabled\n", (sc1f & 0x01) ? "en" : "dis"); | |
19408 | - p += sprintf(p, "Host Mode : %s\n", (sc1f & 0x08) ? "Tri-Stated" : "Normal"); | |
19409 | + p += sprintf(p, "------------------------------- General Status " | |
19410 | + "---------------------------------\n"); | |
19411 | + p += sprintf(p, "Burst Mode : %sabled\n", | |
19412 | + (sc1f & 0x01) ? "en" : "dis"); | |
19413 | + p += sprintf(p, "Host Mode : %s\n", | |
19414 | + (sc1f & 0x08) ? "Tri-Stated" : "Normal"); | |
19415 | p += sprintf(p, "Bus Clocking : %s\n", | |
19416 | ((sc1f & 0xC0) == 0xC0) ? "100 External" : | |
19417 | ((sc1f & 0x80) == 0x80) ? "66 External" : | |
19418 | @@ -170,7 +184,9 @@ | |
19419 | SPLIT_BYTE(sc1e, hi, lo); | |
19420 | p += sprintf(p, "Status Polling Period : %d\n", hi); | |
19421 | p += sprintf(p, "Interrupt Check Status Polling Delay : %d\n", lo); | |
19422 | - p += sprintf(p, "--------------- Primary Channel ---------------- Secondary Channel -------------\n"); | |
19423 | + p += sprintf(p, "--------------- Primary Channel " | |
19424 | + "---------------- Secondary Channel " | |
19425 | + "-------------\n"); | |
19426 | p += sprintf(p, " %s %s\n", | |
19427 | (c0&0x80)?"disabled":"enabled ", | |
19428 | (c1&0x80)?"disabled":"enabled "); | |
19429 | @@ -180,63 +196,101 @@ | |
19430 | p += sprintf(p, " Mode %s Mode %s\n", | |
19431 | (sc1a & 0x01) ? "MASTER" : "PCI ", | |
19432 | (sc1b & 0x01) ? "MASTER" : "PCI "); | |
19433 | - if (!(invalid_data_set)) | |
19434 | - p += sprintf(p, " %s %s\n", | |
19435 | - (sc1d & 0x08) ? "Error " : | |
19436 | - ((sc1d & 0x05) == 0x05) ? "Not My INTR " : | |
19437 | - (sc1d & 0x04) ? "Interrupting" : | |
19438 | - (sc1d & 0x02) ? "FIFO Full " : | |
19439 | - (sc1d & 0x01) ? "FIFO Empty " : "????????????", | |
19440 | - (sc1d & 0x80) ? "Error " : | |
19441 | - ((sc1d & 0x50) == 0x50) ? "Not My INTR " : | |
19442 | - (sc1d & 0x40) ? "Interrupting" : | |
19443 | - (sc1d & 0x20) ? "FIFO Full " : | |
19444 | - (sc1d & 0x10) ? "FIFO Empty " : "????????????"); | |
19445 | - p += sprintf(p, "--------------- drive0 --------- drive1 -------- drive0 ---------- drive1 ------\n"); | |
19446 | - p += sprintf(p, "DMA enabled: %s %s %s %s\n", | |
19447 | - (c0&0x20)?"yes":"no ",(c0&0x40)?"yes":"no ",(c1&0x20)?"yes":"no ",(c1&0x40)?"yes":"no "); | |
19448 | - if (!(invalid_data_set)) | |
19449 | - p += sprintf(p, "DMA Mode: %s %s %s %s\n", | |
19450 | - pdc202xx_ultra_verbose(reg60h, (reg50h & pmask)), | |
19451 | - pdc202xx_ultra_verbose(reg64h, (reg50h & pmask)), | |
19452 | - pdc202xx_ultra_verbose(reg68h, (reg50h & smask)), | |
19453 | - pdc202xx_ultra_verbose(reg6ch, (reg50h & smask))); | |
19454 | - if (!(invalid_data_set)) | |
19455 | - p += sprintf(p, "PIO Mode: %s %s %s %s\n", | |
19456 | - pdc202xx_pio_verbose(reg60h), | |
19457 | - pdc202xx_pio_verbose(reg64h), | |
19458 | - pdc202xx_pio_verbose(reg68h), | |
19459 | - pdc202xx_pio_verbose(reg6ch)); | |
19460 | + p += sprintf(p, " %s %s\n", | |
19461 | + (sc1d & 0x08) ? "Error " : | |
19462 | + ((sc1d & 0x05) == 0x05) ? "Not My INTR " : | |
19463 | + (sc1d & 0x04) ? "Interrupting" : | |
19464 | + (sc1d & 0x02) ? "FIFO Full " : | |
19465 | + (sc1d & 0x01) ? "FIFO Empty " : "????????????", | |
19466 | + (sc1d & 0x80) ? "Error " : | |
19467 | + ((sc1d & 0x50) == 0x50) ? "Not My INTR " : | |
19468 | + (sc1d & 0x40) ? "Interrupting" : | |
19469 | + (sc1d & 0x20) ? "FIFO Full " : | |
19470 | + (sc1d & 0x10) ? "FIFO Empty " : "????????????"); | |
19471 | + p += sprintf(p, "--------------- drive0 --------- drive1 " | |
19472 | + "-------- drive0 ---------- drive1 ------\n"); | |
19473 | + p += sprintf(p, "DMA enabled: %s %s " | |
19474 | + " %s %s\n", | |
19475 | + (c0&0x20)?"yes":"no ", (c0&0x40)?"yes":"no ", | |
19476 | + (c1&0x20)?"yes":"no ", (c1&0x40)?"yes":"no "); | |
19477 | + p += sprintf(p, "DMA Mode: %s %s " | |
19478 | + " %s %s\n", | |
19479 | + pdc202xx_ultra_verbose(reg60h, (reg50h & pmask)), | |
19480 | + pdc202xx_ultra_verbose(reg64h, (reg50h & pmask)), | |
19481 | + pdc202xx_ultra_verbose(reg68h, (reg50h & smask)), | |
19482 | + pdc202xx_ultra_verbose(reg6ch, (reg50h & smask))); | |
19483 | + p += sprintf(p, "PIO Mode: %s %s " | |
19484 | + " %s %s\n", | |
19485 | + pdc202xx_pio_verbose(reg60h), | |
19486 | + pdc202xx_pio_verbose(reg64h), | |
19487 | + pdc202xx_pio_verbose(reg68h), | |
19488 | + pdc202xx_pio_verbose(reg6ch)); | |
19489 | #if 0 | |
19490 | p += sprintf(p, "--------------- Can ATAPI DMA ---------------\n"); | |
19491 | #endif | |
19492 | - if (invalid_data_set) | |
19493 | - p += sprintf(p, "--------------- Cannot Decode HOST ---------------\n"); | |
19494 | + return (char *)p; | |
19495 | +} | |
19496 | + | |
19497 | +static char * pdc202xx_info_new (char *buf, struct pci_dev *dev) | |
19498 | +{ | |
19499 | + char *p = buf; | |
19500 | +// u32 bibma = pci_resource_start(dev, 4); | |
19501 | + | |
19502 | +// u32 reg60h = 0, reg64h = 0, reg68h = 0, reg6ch = 0; | |
19503 | +// u16 reg50h = 0, word88 = 0; | |
19504 | +// int udmasel[4]={0,0,0,0}, piosel[4]={0,0,0,0}, i=0, hd=0; | |
19505 | + | |
19506 | + p += sprintf(p, "\n "); | |
19507 | + switch(dev->device) { | |
19508 | + case PCI_DEVICE_ID_PROMISE_20277: | |
19509 | + p += sprintf(p, "SBFastTrak 133 Lite"); break; | |
19510 | + case PCI_DEVICE_ID_PROMISE_20276: | |
19511 | + p += sprintf(p, "MBFastTrak 133 Lite"); break; | |
19512 | + case PCI_DEVICE_ID_PROMISE_20275: | |
19513 | + p += sprintf(p, "MBUltra133"); break; | |
19514 | + case PCI_DEVICE_ID_PROMISE_20271: | |
19515 | + p += sprintf(p, "FastTrak TX2000"); break; | |
19516 | + case PCI_DEVICE_ID_PROMISE_20270: | |
19517 | + p += sprintf(p, "FastTrak LP/TX2/TX4"); break; | |
19518 | + case PCI_DEVICE_ID_PROMISE_20269: | |
19519 | + p += sprintf(p, "Ultra133 TX2"); break; | |
19520 | + case PCI_DEVICE_ID_PROMISE_20268: | |
19521 | + p += sprintf(p, "Ultra100 TX2"); break; | |
19522 | + default: | |
19523 | + p += sprintf(p, "Ultra series"); break; | |
19524 | + break; | |
19525 | + } | |
19526 | + p += sprintf(p, " Chipset.\n"); | |
19527 | return (char *)p; | |
19528 | } | |
19529 | ||
19530 | static int pdc202xx_get_info (char *buffer, char **addr, off_t offset, int count) | |
19531 | { | |
19532 | char *p = buffer; | |
19533 | - p = pdc202xx_info(buffer, bmide_dev); | |
19534 | + int i; | |
19535 | + | |
19536 | + for (i = 0; i < n_pdc202_devs; i++) { | |
19537 | + struct pci_dev *dev = pdc202_devs[i]; | |
19538 | + | |
19539 | + switch(dev->device) { | |
19540 | + case PCI_DEVICE_ID_PROMISE_20277: | |
19541 | + case PCI_DEVICE_ID_PROMISE_20276: | |
19542 | + case PCI_DEVICE_ID_PROMISE_20275: | |
19543 | + case PCI_DEVICE_ID_PROMISE_20271: | |
19544 | + case PCI_DEVICE_ID_PROMISE_20269: | |
19545 | + case PCI_DEVICE_ID_PROMISE_20268: | |
19546 | + case PCI_DEVICE_ID_PROMISE_20270: | |
19547 | + p = pdc202xx_info_new(buffer, dev); | |
19548 | + break; | |
19549 | + default: | |
19550 | + p = pdc202xx_info(buffer, dev); | |
19551 | + break; | |
19552 | + } | |
19553 | + } | |
19554 | return p-buffer; /* => must be less than 4k! */ | |
19555 | } | |
19556 | #endif /* defined(DISPLAY_PDC202XX_TIMINGS) && defined(CONFIG_PROC_FS) */ | |
19557 | ||
19558 | -byte pdc202xx_proc = 0; | |
19559 | - | |
19560 | -const char *pdc_quirk_drives[] = { | |
19561 | - "QUANTUM FIREBALLlct08 08", | |
19562 | - "QUANTUM FIREBALLP KA6.4", | |
19563 | - "QUANTUM FIREBALLP LM20.4", | |
19564 | - "QUANTUM FIREBALLP KX20.5", | |
19565 | - "QUANTUM FIREBALLP KX27.3", | |
19566 | - "QUANTUM FIREBALLP LM20.5", | |
19567 | - NULL | |
19568 | -}; | |
19569 | - | |
19570 | -extern char *ide_xfer_verbose (byte xfer_rate); | |
19571 | - | |
19572 | /* A Register */ | |
19573 | #define SYNC_ERRDY_EN 0xC0 | |
19574 | ||
19575 | @@ -347,6 +401,69 @@ | |
19576 | ||
19577 | #endif /* PDC202XX_DECODE_REGISTER_INFO */ | |
19578 | ||
19579 | +#if 0 | |
19580 | +static byte pdc202xx_ratemask (ide_drive_t *drive) | |
19581 | +{ | |
19582 | + struct pci_dev *dev = HWIF(drive)->pci_dev; | |
19583 | + byte mode = 0x00; | |
19584 | + | |
19585 | + switch(dev->device) { | |
19586 | + case PCI_DEVICE_ID_PROMISE_20277: | |
19587 | + case PCI_DEVICE_ID_PROMISE_20276: | |
19588 | + case PCI_DEVICE_ID_PROMISE_20275: | |
19589 | + case PCI_DEVICE_ID_PROMISE_20271: | |
19590 | + case PCI_DEVICE_ID_PROMISE_20269: | |
19591 | + { mode |= 0x04; break; } | |
19592 | + case PCI_DEVICE_ID_PROMISE_20270: | |
19593 | + case PCI_DEVICE_ID_PROMISE_20268: | |
19594 | + { mode |= 0x03; break; } | |
19595 | + case PCI_DEVICE_ID_PROMISE_20267: | |
19596 | + case PCI_DEVICE_ID_PROMISE_20265: | |
19597 | + { mode |= 0x03; break; } | |
19598 | + case PCI_DEVICE_ID_PROMISE_20263: | |
19599 | + case PCI_DEVICE_ID_PROMISE_20262: | |
19600 | + { mode |= 0x02; break; } | |
19601 | + case PCI_DEVICE_ID_PROMISE_20246: | |
19602 | + { mode |= 0x01; break; } | |
19603 | + default: | |
19604 | + return (mode &= ~0xF8); | |
19605 | + } | |
19606 | + | |
19607 | + if (!eighty_ninty_three(drive)) { | |
19608 | + mode &= ~0xFE; | |
19609 | + mode |= 0x01; | |
19610 | + } | |
19611 | + return (mode &= ~0xF8); | |
19612 | +} | |
19613 | + | |
19614 | +static byte pdc202xx_ratefilter (ide_drive_t *drive, byte speed) | |
19615 | +{ | |
19616 | +#ifdef CONFIG_BLK_DEV_IDEDMA | |
19617 | + byte mode = pdc202xx_ratemask(drive); | |
19618 | + | |
19619 | + switch(mode) { | |
19620 | + case 0x04: while (speed > XFER_UDMA_6) speed--; break; | |
19621 | + case 0x03: while (speed > XFER_UDMA_5) speed--; break; | |
19622 | + case 0x02: while (speed > XFER_UDMA_4) speed--; break; | |
19623 | + case 0x01: while (speed > XFER_UDMA_2) speed--; break; | |
19624 | + case 0x00: | |
19625 | + default: while (speed > XFER_MW_DMA_2) speed--; break; | |
19626 | + break; | |
19627 | + } | |
19628 | +#else | |
19629 | + while (speed > XFER_PIO_4) speed--; | |
19630 | +#endif /* CONFIG_BLK_DEV_IDEDMA */ | |
19631 | +// printk("%s: mode == %02x speed == %02x\n", drive->name, mode, speed); | |
19632 | + return speed; | |
19633 | +} | |
19634 | + | |
19635 | +#else | |
19636 | +static byte pdc202xx_ratefilter (ide_drive_t *drive, byte speed) | |
19637 | +{ | |
19638 | + return speed; | |
19639 | +} | |
19640 | +#endif | |
19641 | + | |
19642 | static int check_in_drive_lists (ide_drive_t *drive, const char **list) | |
19643 | { | |
19644 | struct hd_driveid *id = drive->id; | |
19645 | @@ -367,13 +484,13 @@ | |
19646 | return 0; | |
19647 | } | |
19648 | ||
19649 | -static int pdc202xx_tune_chipset (ide_drive_t *drive, byte speed) | |
19650 | +static int pdc202xx_tune_chipset (ide_drive_t *drive, byte xferspeed) | |
19651 | { | |
19652 | ide_hwif_t *hwif = HWIF(drive); | |
19653 | struct pci_dev *dev = hwif->pci_dev; | |
19654 | + byte speed = pdc202xx_ratefilter(drive, xferspeed); | |
19655 | ||
19656 | unsigned int drive_conf; | |
19657 | - int err; | |
19658 | byte drive_pci, AP, BP, CP, DP; | |
19659 | byte TA = 0, TB = 0, TC = 0; | |
19660 | ||
19661 | @@ -385,10 +502,8 @@ | |
19662 | default: return -1; | |
19663 | } | |
19664 | ||
19665 | - if ((drive->media != ide_disk) && (speed < XFER_SW_DMA_0)) return -1; | |
19666 | - | |
19667 | - if (dev->device == PCI_DEVICE_ID_PROMISE_20268) | |
19668 | - goto skip_register_hell; | |
19669 | + if ((drive->media != ide_disk) && (speed < XFER_SW_DMA_0)) | |
19670 | + return -1; | |
19671 | ||
19672 | pci_read_config_dword(dev, drive_pci, &drive_conf); | |
19673 | pci_read_config_byte(dev, (drive_pci), &AP); | |
19674 | @@ -396,34 +511,32 @@ | |
19675 | pci_read_config_byte(dev, (drive_pci)|0x02, &CP); | |
19676 | pci_read_config_byte(dev, (drive_pci)|0x03, &DP); | |
19677 | ||
19678 | -#ifdef CONFIG_BLK_DEV_IDEDMA | |
19679 | - if (speed >= XFER_SW_DMA_0) { | |
19680 | - if ((BP & 0xF0) && (CP & 0x0F)) { | |
19681 | - /* clear DMA modes of upper 842 bits of B Register */ | |
19682 | - /* clear PIO forced mode upper 1 bit of B Register */ | |
19683 | - pci_write_config_byte(dev, (drive_pci)|0x01, BP & ~0xF0); | |
19684 | - pci_read_config_byte(dev, (drive_pci)|0x01, &BP); | |
19685 | - | |
19686 | - /* clear DMA modes of lower 8421 bits of C Register */ | |
19687 | - pci_write_config_byte(dev, (drive_pci)|0x02, CP & ~0x0F); | |
19688 | - pci_read_config_byte(dev, (drive_pci)|0x02, &CP); | |
19689 | - } | |
19690 | - } else { | |
19691 | -#else | |
19692 | - { | |
19693 | -#endif /* CONFIG_BLK_DEV_IDEDMA */ | |
19694 | + if (speed < XFER_SW_DMA_0) { | |
19695 | if ((AP & 0x0F) || (BP & 0x07)) { | |
19696 | /* clear PIO modes of lower 8421 bits of A Register */ | |
19697 | - pci_write_config_byte(dev, (drive_pci), AP & ~0x0F); | |
19698 | + pci_write_config_byte(dev, (drive_pci), AP &~0x0F); | |
19699 | pci_read_config_byte(dev, (drive_pci), &AP); | |
19700 | ||
19701 | /* clear PIO modes of lower 421 bits of B Register */ | |
19702 | - pci_write_config_byte(dev, (drive_pci)|0x01, BP & ~0x07); | |
19703 | + pci_write_config_byte(dev, (drive_pci)|0x01, BP &~0x07); | |
19704 | pci_read_config_byte(dev, (drive_pci)|0x01, &BP); | |
19705 | ||
19706 | pci_read_config_byte(dev, (drive_pci), &AP); | |
19707 | pci_read_config_byte(dev, (drive_pci)|0x01, &BP); | |
19708 | } | |
19709 | +#ifdef CONFIG_BLK_DEV_IDEDMA | |
19710 | + } else { | |
19711 | + if ((BP & 0xF0) && (CP & 0x0F)) { | |
19712 | + /* clear DMA modes of upper 842 bits of B Register */ | |
19713 | + /* clear PIO forced mode upper 1 bit of B Register */ | |
19714 | + pci_write_config_byte(dev, (drive_pci)|0x01, BP &~0xF0); | |
19715 | + pci_read_config_byte(dev, (drive_pci)|0x01, &BP); | |
19716 | + | |
19717 | + /* clear DMA modes of lower 8421 bits of C Register */ | |
19718 | + pci_write_config_byte(dev, (drive_pci)|0x02, CP &~0x0F); | |
19719 | + pci_read_config_byte(dev, (drive_pci)|0x02, &CP); | |
19720 | + } | |
19721 | +#endif /* CONFIG_BLK_DEV_IDEDMA */ | |
19722 | } | |
19723 | ||
19724 | pci_read_config_byte(dev, (drive_pci), &AP); | |
19725 | @@ -432,18 +545,19 @@ | |
19726 | ||
19727 | switch(speed) { | |
19728 | #ifdef CONFIG_BLK_DEV_IDEDMA | |
19729 | + /* case XFER_UDMA_6: */ | |
19730 | case XFER_UDMA_5: | |
19731 | - case XFER_UDMA_4: TB = 0x20; TC = 0x01; break; /* speed 8 == UDMA mode 4 */ | |
19732 | - case XFER_UDMA_3: TB = 0x40; TC = 0x02; break; /* speed 7 == UDMA mode 3 */ | |
19733 | - case XFER_UDMA_2: TB = 0x20; TC = 0x01; break; /* speed 6 == UDMA mode 2 */ | |
19734 | - case XFER_UDMA_1: TB = 0x40; TC = 0x02; break; /* speed 5 == UDMA mode 1 */ | |
19735 | - case XFER_UDMA_0: TB = 0x60; TC = 0x03; break; /* speed 4 == UDMA mode 0 */ | |
19736 | - case XFER_MW_DMA_2: TB = 0x60; TC = 0x03; break; /* speed 4 == MDMA mode 2 */ | |
19737 | - case XFER_MW_DMA_1: TB = 0x60; TC = 0x04; break; /* speed 3 == MDMA mode 1 */ | |
19738 | - case XFER_MW_DMA_0: TB = 0x60; TC = 0x05; break; /* speed 2 == MDMA mode 0 */ | |
19739 | - case XFER_SW_DMA_2: TB = 0x60; TC = 0x05; break; /* speed 0 == SDMA mode 2 */ | |
19740 | - case XFER_SW_DMA_1: TB = 0x80; TC = 0x06; break; /* speed 1 == SDMA mode 1 */ | |
19741 | - case XFER_SW_DMA_0: TB = 0xC0; TC = 0x0B; break; /* speed 0 == SDMA mode 0 */ | |
19742 | + case XFER_UDMA_4: TB = 0x20; TC = 0x01; break; | |
19743 | + case XFER_UDMA_3: TB = 0x40; TC = 0x02; break; | |
19744 | + case XFER_UDMA_2: TB = 0x20; TC = 0x01; break; | |
19745 | + case XFER_UDMA_1: TB = 0x40; TC = 0x02; break; | |
19746 | + case XFER_UDMA_0: TB = 0x60; TC = 0x03; break; | |
19747 | + case XFER_MW_DMA_2: TB = 0x60; TC = 0x03; break; | |
19748 | + case XFER_MW_DMA_1: TB = 0x60; TC = 0x04; break; | |
19749 | + case XFER_MW_DMA_0: TB = 0x60; TC = 0x05; break; | |
19750 | + case XFER_SW_DMA_2: TB = 0x60; TC = 0x05; break; | |
19751 | + case XFER_SW_DMA_1: TB = 0x80; TC = 0x06; break; | |
19752 | + case XFER_SW_DMA_0: TB = 0xC0; TC = 0x0B; break; | |
19753 | #endif /* CONFIG_BLK_DEV_IDEDMA */ | |
19754 | case XFER_PIO_4: TA = 0x01; TB = 0x04; break; | |
19755 | case XFER_PIO_3: TA = 0x02; TB = 0x06; break; | |
19756 | @@ -453,16 +567,14 @@ | |
19757 | default: TA = 0x09; TB = 0x13; break; | |
19758 | } | |
19759 | ||
19760 | + if (speed < XFER_SW_DMA_0) { | |
19761 | + pci_write_config_byte(dev, (drive_pci), AP|TA); | |
19762 | + pci_write_config_byte(dev, (drive_pci)|0x01, BP|TB); | |
19763 | #ifdef CONFIG_BLK_DEV_IDEDMA | |
19764 | - if (speed >= XFER_SW_DMA_0) { | |
19765 | + } else { | |
19766 | pci_write_config_byte(dev, (drive_pci)|0x01, BP|TB); | |
19767 | pci_write_config_byte(dev, (drive_pci)|0x02, CP|TC); | |
19768 | - } else { | |
19769 | -#else | |
19770 | - { | |
19771 | #endif /* CONFIG_BLK_DEV_IDEDMA */ | |
19772 | - pci_write_config_byte(dev, (drive_pci), AP|TA); | |
19773 | - pci_write_config_byte(dev, (drive_pci)|0x01, BP|TB); | |
19774 | } | |
19775 | ||
19776 | #if PDC202XX_DECODE_REGISTER_INFO | |
19777 | @@ -476,14 +588,6 @@ | |
19778 | decode_registers(REG_C, CP); | |
19779 | decode_registers(REG_D, DP); | |
19780 | #endif /* PDC202XX_DECODE_REGISTER_INFO */ | |
19781 | - | |
19782 | -skip_register_hell: | |
19783 | - | |
19784 | - if (!drive->init_speed) | |
19785 | - drive->init_speed = speed; | |
19786 | - err = ide_config_drive_speed(drive, speed); | |
19787 | - drive->current_speed = speed; | |
19788 | - | |
19789 | #if PDC202XX_DEBUG_DRIVE_INFO | |
19790 | printk("%s: %s drive%d 0x%08x ", | |
19791 | drive->name, ide_xfer_verbose(speed), | |
19792 | @@ -491,7 +595,156 @@ | |
19793 | pci_read_config_dword(dev, drive_pci, &drive_conf); | |
19794 | printk("0x%08x\n", drive_conf); | |
19795 | #endif /* PDC202XX_DEBUG_DRIVE_INFO */ | |
19796 | - return err; | |
19797 | + | |
19798 | + return (ide_config_drive_speed(drive, speed)); | |
19799 | +} | |
19800 | + | |
19801 | +static int pdc202xx_new_tune_chipset (ide_drive_t *drive, byte xferspeed) | |
19802 | +{ | |
19803 | + ide_hwif_t *hwif = HWIF(drive); | |
19804 | +#ifdef CONFIG_BLK_DEV_IDEDMA | |
19805 | + unsigned long indexreg = (hwif->dma_base + 1); | |
19806 | + unsigned long datareg = (hwif->dma_base + 3); | |
19807 | +#else | |
19808 | + struct pci_dev *dev = hwif->pci_dev; | |
19809 | + unsigned long high_16 = pci_resource_start(dev, 4); | |
19810 | + unsigned long indexreg = high_16 + (hwif->channel ? 0x09 : 0x01); | |
19811 | + unsigned long datareg = (indexreg + 2); | |
19812 | +#endif /* CONFIG_BLK_DEV_IDEDMA */ | |
19813 | + byte thold = 0x10; | |
19814 | + byte adj = (drive->dn%2) ? 0x08 : 0x00; | |
19815 | + byte speed = pdc202xx_ratefilter(drive, xferspeed); | |
19816 | + | |
19817 | +#ifdef CONFIG_BLK_DEV_IDEDMA | |
19818 | + if (speed == XFER_UDMA_2) { | |
19819 | + OUT_BYTE((thold + adj), indexreg); | |
19820 | + OUT_BYTE((IN_BYTE(datareg) & 0x7f), datareg); | |
19821 | + } | |
19822 | +#endif /* CONFIG_BLK_DEV_IDEDMA */ | |
19823 | + | |
19824 | + switch (speed) { | |
19825 | +#ifdef CONFIG_BLK_DEV_IDEDMA | |
19826 | + case XFER_UDMA_7: | |
19827 | + speed = XFER_UDMA_6; | |
19828 | + case XFER_UDMA_6: | |
19829 | + OUT_BYTE((0x10 + adj), indexreg); | |
19830 | + OUT_BYTE(0x1a, datareg); | |
19831 | + OUT_BYTE((0x11 + adj), indexreg); | |
19832 | + OUT_BYTE(0x01, datareg); | |
19833 | + OUT_BYTE((0x12 + adj), indexreg); | |
19834 | + OUT_BYTE(0xcb, datareg); | |
19835 | + break; | |
19836 | + case XFER_UDMA_5: | |
19837 | + OUT_BYTE((0x10 + adj), indexreg); | |
19838 | + OUT_BYTE(0x1a, datareg); | |
19839 | + OUT_BYTE((0x11 + adj), indexreg); | |
19840 | + OUT_BYTE(0x02, datareg); | |
19841 | + OUT_BYTE((0x12 + adj), indexreg); | |
19842 | + OUT_BYTE(0xcb, datareg); | |
19843 | + break; | |
19844 | + case XFER_UDMA_4: | |
19845 | + OUT_BYTE((0x10 + adj), indexreg); | |
19846 | + OUT_BYTE(0x1a, datareg); | |
19847 | + OUT_BYTE((0x11 + adj), indexreg); | |
19848 | + OUT_BYTE(0x03, datareg); | |
19849 | + OUT_BYTE((0x12 + adj), indexreg); | |
19850 | + OUT_BYTE(0xcd, datareg); | |
19851 | + break; | |
19852 | + case XFER_UDMA_3: | |
19853 | + OUT_BYTE((0x10 + adj), indexreg); | |
19854 | + OUT_BYTE(0x1a, datareg); | |
19855 | + OUT_BYTE((0x11 + adj), indexreg); | |
19856 | + OUT_BYTE(0x05, datareg); | |
19857 | + OUT_BYTE((0x12 + adj), indexreg); | |
19858 | + OUT_BYTE(0xcd, datareg); | |
19859 | + break; | |
19860 | + case XFER_UDMA_2: | |
19861 | + OUT_BYTE((0x10 + adj), indexreg); | |
19862 | + OUT_BYTE(0x2a, datareg); | |
19863 | + OUT_BYTE((0x11 + adj), indexreg); | |
19864 | + OUT_BYTE(0x07, datareg); | |
19865 | + OUT_BYTE((0x12 + adj), indexreg); | |
19866 | + OUT_BYTE(0xcd, datareg); | |
19867 | + break; | |
19868 | + case XFER_UDMA_1: | |
19869 | + OUT_BYTE((0x10 + adj), indexreg); | |
19870 | + OUT_BYTE(0x3a, datareg); | |
19871 | + OUT_BYTE((0x11 + adj), indexreg); | |
19872 | + OUT_BYTE(0x0a, datareg); | |
19873 | + OUT_BYTE((0x12 + adj), indexreg); | |
19874 | + OUT_BYTE(0xd0, datareg); | |
19875 | + break; | |
19876 | + case XFER_UDMA_0: | |
19877 | + OUT_BYTE((0x10 + adj), indexreg); | |
19878 | + OUT_BYTE(0x4a, datareg); | |
19879 | + OUT_BYTE((0x11 + adj), indexreg); | |
19880 | + OUT_BYTE(0x0f, datareg); | |
19881 | + OUT_BYTE((0x12 + adj), indexreg); | |
19882 | + OUT_BYTE(0xd5, datareg); | |
19883 | + break; | |
19884 | + case XFER_MW_DMA_2: | |
19885 | + OUT_BYTE((0x0e + adj), indexreg); | |
19886 | + OUT_BYTE(0x69, datareg); | |
19887 | + OUT_BYTE((0x0f + adj), indexreg); | |
19888 | + OUT_BYTE(0x25, datareg); | |
19889 | + break; | |
19890 | + case XFER_MW_DMA_1: | |
19891 | + OUT_BYTE((0x0e + adj), indexreg); | |
19892 | + OUT_BYTE(0x6b, datareg); | |
19893 | + OUT_BYTE((0x0f+ adj), indexreg); | |
19894 | + OUT_BYTE(0x27, datareg); | |
19895 | + break; | |
19896 | + case XFER_MW_DMA_0: | |
19897 | + OUT_BYTE((0x0e + adj), indexreg); | |
19898 | + OUT_BYTE(0xdf, datareg); | |
19899 | + OUT_BYTE((0x0f + adj), indexreg); | |
19900 | + OUT_BYTE(0x5f, datareg); | |
19901 | + break; | |
19902 | +#endif /* CONFIG_BLK_DEV_IDEDMA */ | |
19903 | + case XFER_PIO_4: | |
19904 | + OUT_BYTE((0x0c + adj), indexreg); | |
19905 | + OUT_BYTE(0x23, datareg); | |
19906 | + OUT_BYTE((0x0d + adj), indexreg); | |
19907 | + OUT_BYTE(0x09, datareg); | |
19908 | + OUT_BYTE((0x13 + adj), indexreg); | |
19909 | + OUT_BYTE(0x25, datareg); | |
19910 | + break; | |
19911 | + case XFER_PIO_3: | |
19912 | + OUT_BYTE((0x0c + adj), indexreg); | |
19913 | + OUT_BYTE(0x27, datareg); | |
19914 | + OUT_BYTE((0x0d + adj), indexreg); | |
19915 | + OUT_BYTE(0x0d, datareg); | |
19916 | + OUT_BYTE((0x13 + adj), indexreg); | |
19917 | + OUT_BYTE(0x35, datareg); | |
19918 | + break; | |
19919 | + case XFER_PIO_2: | |
19920 | + OUT_BYTE((0x0c + adj), indexreg); | |
19921 | + OUT_BYTE(0x23, datareg); | |
19922 | + OUT_BYTE((0x0d + adj), indexreg); | |
19923 | + OUT_BYTE(0x26, datareg); | |
19924 | + OUT_BYTE((0x13 + adj), indexreg); | |
19925 | + OUT_BYTE(0x64, datareg); | |
19926 | + break; | |
19927 | + case XFER_PIO_1: | |
19928 | + OUT_BYTE((0x0c + adj), indexreg); | |
19929 | + OUT_BYTE(0x46, datareg); | |
19930 | + OUT_BYTE((0x0d + adj), indexreg); | |
19931 | + OUT_BYTE(0x29, datareg); | |
19932 | + OUT_BYTE((0x13 + adj), indexreg); | |
19933 | + OUT_BYTE(0xa4, datareg); | |
19934 | + break; | |
19935 | + case XFER_PIO_0: | |
19936 | + OUT_BYTE((0x0c + adj), indexreg); | |
19937 | + OUT_BYTE(0xfb, datareg); | |
19938 | + OUT_BYTE((0x0d + adj), indexreg); | |
19939 | + OUT_BYTE(0x2b, datareg); | |
19940 | + OUT_BYTE((0x13 + adj), indexreg); | |
19941 | + OUT_BYTE(0xac, datareg); | |
19942 | + break; | |
19943 | + default: | |
19944 | + } | |
19945 | + | |
19946 | + return (ide_config_drive_speed(drive, speed)); | |
19947 | } | |
19948 | ||
19949 | /* 0 1 2 3 4 5 6 7 8 | |
19950 | @@ -517,25 +770,81 @@ | |
19951 | } | |
19952 | ||
19953 | #ifdef CONFIG_BLK_DEV_IDEDMA | |
19954 | -static int config_chipset_for_dma (ide_drive_t *drive, byte ultra) | |
19955 | +static int config_chipset_for_dma (ide_drive_t *drive) | |
19956 | { | |
19957 | struct hd_driveid *id = drive->id; | |
19958 | +// byte mode = pdc202xx_ratemask(drive); | |
19959 | ide_hwif_t *hwif = HWIF(drive); | |
19960 | struct pci_dev *dev = hwif->pci_dev; | |
19961 | unsigned long high_16 = pci_resource_start(dev, 4); | |
19962 | unsigned long dma_base = hwif->dma_base; | |
19963 | - byte unit = (drive->select.b.unit & 0x01); | |
19964 | - | |
19965 | + unsigned long indexreg = dma_base + 1; | |
19966 | + unsigned long datareg = dma_base + 3; | |
19967 | + byte iordy = 0x13; | |
19968 | + byte adj = (drive->dn%2) ? 0x08 : 0x00; | |
19969 | + byte cable = 0; | |
19970 | + byte jumpbit = 0; | |
19971 | unsigned int drive_conf; | |
19972 | - byte drive_pci; | |
19973 | + byte drive_pci = 0; | |
19974 | byte test1, test2, speed = -1; | |
19975 | byte AP; | |
19976 | unsigned short EP; | |
19977 | - byte CLKSPD = IN_BYTE(high_16 + 0x11); | |
19978 | - byte udma_33 = ultra ? (inb(high_16 + 0x001f) & 1) : 0; | |
19979 | - byte udma_66 = ((eighty_ninty_three(drive)) && udma_33) ? 1 : 0; | |
19980 | - byte udma_100 = (((dev->device == PCI_DEVICE_ID_PROMISE_20265) || (dev->device == PCI_DEVICE_ID_PROMISE_20267) || (dev->device == PCI_DEVICE_ID_PROMISE_20268)) && udma_66) ? 1 : 0; | |
19981 | + byte CLKSPD = 0; | |
19982 | + byte udma_33 = 1; | |
19983 | + byte udma_66 = (eighty_ninty_three(drive)) ? 1 : 0; | |
19984 | + byte udma_100 = 0; | |
19985 | + byte udma_133 = 0; | |
19986 | + byte mask = hwif->channel ? 0x08 : 0x02; | |
19987 | + unsigned short c_mask = hwif->channel ? (1<<11) : (1<<10); | |
19988 | + | |
19989 | + byte ultra_66 = ((id->dma_ultra & 0x0010) || | |
19990 | + (id->dma_ultra & 0x0008)) ? 1 : 0; | |
19991 | + | |
19992 | + switch(dev->device) { | |
19993 | + case PCI_DEVICE_ID_PROMISE_20277: | |
19994 | + case PCI_DEVICE_ID_PROMISE_20276: | |
19995 | + case PCI_DEVICE_ID_PROMISE_20275: | |
19996 | + case PCI_DEVICE_ID_PROMISE_20271: | |
19997 | + case PCI_DEVICE_ID_PROMISE_20269: | |
19998 | + udma_133 = (udma_66) ? 1 : 0; | |
19999 | + udma_100 = (udma_66) ? 1 : 0; | |
20000 | + OUT_BYTE(0x0b, (hwif->dma_base + 1)); | |
20001 | + cable = ((IN_BYTE((hwif->dma_base + 3)) & 0x04)); | |
20002 | + jumpbit = 1; | |
20003 | + break; | |
20004 | + case PCI_DEVICE_ID_PROMISE_20270: | |
20005 | + udma_100 = 1; | |
20006 | + udma_66 = 1; | |
20007 | + OUT_BYTE(0x0b, (hwif->dma_base + 1)); | |
20008 | + cable = ((IN_BYTE((hwif->dma_base + 3)) & 0x04)); | |
20009 | + jumpbit = 1; | |
20010 | + break; | |
20011 | + case PCI_DEVICE_ID_PROMISE_20268: | |
20012 | + udma_100 = (udma_66) ? 1 : 0; | |
20013 | + OUT_BYTE(0x0b, (hwif->dma_base + 1)); | |
20014 | + cable = ((IN_BYTE((hwif->dma_base + 3)) & 0x04)); | |
20015 | + jumpbit = 1; | |
20016 | + break; | |
20017 | + case PCI_DEVICE_ID_PROMISE_20267: | |
20018 | + case PCI_DEVICE_ID_PROMISE_20265: | |
20019 | + udma_100 = (udma_66) ? 1 : 0; | |
20020 | + pci_read_config_word(dev, 0x50, &EP); | |
20021 | + cable = (EP & c_mask); | |
20022 | + jumpbit = 0; | |
20023 | + break; | |
20024 | + case PCI_DEVICE_ID_PROMISE_20263: | |
20025 | + case PCI_DEVICE_ID_PROMISE_20262: | |
20026 | + pci_read_config_word(dev, 0x50, &EP); | |
20027 | + cable = (EP & c_mask); | |
20028 | + jumpbit = 0; | |
20029 | + break; | |
20030 | + default: | |
20031 | + udma_100 = 0; udma_133 = 0; cable = 1; jumpbit = 0; | |
20032 | + break; | |
20033 | + } | |
20034 | ||
20035 | + if (!jumpbit) | |
20036 | + CLKSPD = IN_BYTE(high_16 + 0x11); | |
20037 | /* | |
20038 | * Set the control register to use the 66Mhz system | |
20039 | * clock for UDMA 3/4 mode operation. If one drive on | |
20040 | @@ -549,47 +858,51 @@ | |
20041 | * parameters. | |
20042 | */ | |
20043 | ||
20044 | - byte mask = hwif->channel ? 0x08 : 0x02; | |
20045 | - unsigned short c_mask = hwif->channel ? (1<<11) : (1<<10); | |
20046 | - byte ultra_66 = ((id->dma_ultra & 0x0010) || | |
20047 | - (id->dma_ultra & 0x0008)) ? 1 : 0; | |
20048 | - byte ultra_100 = ((id->dma_ultra & 0x0020) || | |
20049 | - (id->dma_ultra & 0x0010) || | |
20050 | - (id->dma_ultra & 0x0008)) ? 1 : 0; | |
20051 | - | |
20052 | - if (dev->device == PCI_DEVICE_ID_PROMISE_20268) | |
20053 | - goto jump_pci_mucking; | |
20054 | - | |
20055 | - pci_read_config_word(dev, 0x50, &EP); | |
20056 | - | |
20057 | - if (((ultra_66) || (ultra_100)) && (EP & c_mask)) { | |
20058 | -#ifdef DEBUG | |
20059 | - printk("ULTRA66: %s channel of Ultra 66 requires an 80-pin cable for Ultra66 operation.\n", hwif->channel ? "Secondary" : "Primary"); | |
20060 | + if ((ultra_66) && (cable)) { | |
20061 | +//#ifdef DEBUG | |
20062 | +#if 1 | |
20063 | + printk("ULTRA 66/100/133: %s channel of Ultra 66/100/133 " | |
20064 | + "requires an 80-pin cable for Ultra66 operation.\n", | |
20065 | + hwif->channel ? "Secondary" : "Primary"); | |
20066 | printk(" Switching to Ultra33 mode.\n"); | |
20067 | #endif /* DEBUG */ | |
20068 | /* Primary : zero out second bit */ | |
20069 | /* Secondary : zero out fourth bit */ | |
20070 | - OUT_BYTE(CLKSPD & ~mask, (high_16 + 0x11)); | |
20071 | + if (!jumpbit) | |
20072 | + OUT_BYTE(CLKSPD & ~mask, (high_16 + 0x11)); | |
20073 | + printk("Warning: %s channel requires an 80-pin cable for operation.\n", hwif->channel ? "Secondary":"Primary"); | |
20074 | + printk("%s reduced to Ultra33 mode.\n", drive->name); | |
20075 | + udma_66 = 0; | |
20076 | } else { | |
20077 | - if ((ultra_66) || (ultra_100)) { | |
20078 | + if (ultra_66) { | |
20079 | /* | |
20080 | * check to make sure drive on same channel | |
20081 | * is u66 capable | |
20082 | */ | |
20083 | if (hwif->drives[!(drive->dn%2)].id) { | |
20084 | - if ((hwif->drives[!(drive->dn%2)].id->dma_ultra & 0x0020) || | |
20085 | - (hwif->drives[!(drive->dn%2)].id->dma_ultra & 0x0010) || | |
20086 | - (hwif->drives[!(drive->dn%2)].id->dma_ultra & 0x0008)) { | |
20087 | - OUT_BYTE(CLKSPD | mask, (high_16 + 0x11)); | |
20088 | + if (hwif->drives[!(drive->dn%2)].id->dma_ultra & 0x0078) { | |
20089 | + if (!jumpbit) | |
20090 | + OUT_BYTE(CLKSPD | mask, (high_16 + 0x11)); | |
20091 | } else { | |
20092 | - OUT_BYTE(CLKSPD & ~mask, (high_16 + 0x11)); | |
20093 | + if (!jumpbit) | |
20094 | + OUT_BYTE(CLKSPD & ~mask, (high_16 + 0x11)); | |
20095 | } | |
20096 | } else { /* udma4 drive by itself */ | |
20097 | - OUT_BYTE(CLKSPD | mask, (high_16 + 0x11)); | |
20098 | + if (!jumpbit) | |
20099 | + OUT_BYTE(CLKSPD | mask, (high_16 + 0x11)); | |
20100 | } | |
20101 | } | |
20102 | } | |
20103 | ||
20104 | + if (jumpbit) { | |
20105 | + if (drive->media != ide_disk) return ide_dma_off_quietly; | |
20106 | + if (id->capability & 4) { /* IORDY_EN & PREFETCH_EN */ | |
20107 | + OUT_BYTE((iordy + adj), indexreg); | |
20108 | + OUT_BYTE((IN_BYTE(datareg)|0x03), datareg); | |
20109 | + } | |
20110 | + goto jumpbit_is_set; | |
20111 | + } | |
20112 | + | |
20113 | switch(drive->dn) { | |
20114 | case 0: drive_pci = 0x60; | |
20115 | pci_read_config_dword(dev, drive_pci, &drive_conf); | |
20116 | @@ -631,7 +944,10 @@ | |
20117 | ||
20118 | chipset_is_set: | |
20119 | ||
20120 | - if (drive->media != ide_disk) return ide_dma_off_quietly; | |
20121 | + if (drive->media != ide_disk) { | |
20122 | + hwif->tuneproc(drive, 5); | |
20123 | + return ide_dma_off_quietly; | |
20124 | + } | |
20125 | ||
20126 | pci_read_config_byte(dev, (drive_pci), &AP); | |
20127 | if (id->capability & 4) /* IORDY_EN */ | |
20128 | @@ -640,31 +956,33 @@ | |
20129 | if (drive->media == ide_disk) /* PREFETCH_EN */ | |
20130 | pci_write_config_byte(dev, (drive_pci), AP|PREFETCH_EN); | |
20131 | ||
20132 | -jump_pci_mucking: | |
20133 | +jumpbit_is_set: | |
20134 | ||
20135 | - if ((id->dma_ultra & 0x0020) && (udma_100)) speed = XFER_UDMA_5; | |
20136 | - else if ((id->dma_ultra & 0x0010) && (udma_66)) speed = XFER_UDMA_4; | |
20137 | - else if ((id->dma_ultra & 0x0008) && (udma_66)) speed = XFER_UDMA_3; | |
20138 | - else if ((id->dma_ultra & 0x0004) && (udma_33)) speed = XFER_UDMA_2; | |
20139 | - else if ((id->dma_ultra & 0x0002) && (udma_33)) speed = XFER_UDMA_1; | |
20140 | - else if ((id->dma_ultra & 0x0001) && (udma_33)) speed = XFER_UDMA_0; | |
20141 | + if ((id->dma_ultra & 0x0040)&&(udma_133)) speed = XFER_UDMA_6; | |
20142 | + else if ((id->dma_ultra & 0x0020)&&(udma_100)) speed = XFER_UDMA_5; | |
20143 | + else if ((id->dma_ultra & 0x0010)&&(udma_66)) speed = XFER_UDMA_4; | |
20144 | + else if ((id->dma_ultra & 0x0008)&&(udma_66)) speed = XFER_UDMA_3; | |
20145 | + else if ((id->dma_ultra & 0x0004)&&(udma_33)) speed = XFER_UDMA_2; | |
20146 | + else if ((id->dma_ultra & 0x0002)&&(udma_33)) speed = XFER_UDMA_1; | |
20147 | + else if ((id->dma_ultra & 0x0001)&&(udma_33)) speed = XFER_UDMA_0; | |
20148 | else if (id->dma_mword & 0x0004) speed = XFER_MW_DMA_2; | |
20149 | else if (id->dma_mword & 0x0002) speed = XFER_MW_DMA_1; | |
20150 | else if (id->dma_mword & 0x0001) speed = XFER_MW_DMA_0; | |
20151 | - else if (id->dma_1word & 0x0004) speed = XFER_SW_DMA_2; | |
20152 | - else if (id->dma_1word & 0x0002) speed = XFER_SW_DMA_1; | |
20153 | - else if (id->dma_1word & 0x0001) speed = XFER_SW_DMA_0; | |
20154 | + else if ((id->dma_1word & 0x0004)&&(!jumpbit)) speed = XFER_SW_DMA_2; | |
20155 | + else if ((id->dma_1word & 0x0002)&&(!jumpbit)) speed = XFER_SW_DMA_1; | |
20156 | + else if ((id->dma_1word & 0x0001)&&(!jumpbit)) speed = XFER_SW_DMA_0; | |
20157 | else { | |
20158 | /* restore original pci-config space */ | |
20159 | - if (dev->device != PCI_DEVICE_ID_PROMISE_20268) | |
20160 | + if (!jumpbit) | |
20161 | pci_write_config_dword(dev, drive_pci, drive_conf); | |
20162 | + hwif->tuneproc(drive, 5); | |
20163 | return ide_dma_off_quietly; | |
20164 | } | |
20165 | ||
20166 | - outb(inb(dma_base+2) & ~(1<<(5+unit)), dma_base+2); | |
20167 | - (void) pdc202xx_tune_chipset(drive, speed); | |
20168 | + (void) hwif->speedproc(drive, speed); | |
20169 | ||
20170 | - return ((int) ((id->dma_ultra >> 11) & 7) ? ide_dma_on : | |
20171 | + return ((int) ((id->dma_ultra >> 14) & 3) ? ide_dma_on : | |
20172 | + ((id->dma_ultra >> 11) & 7) ? ide_dma_on : | |
20173 | ((id->dma_ultra >> 8) & 7) ? ide_dma_on : | |
20174 | ((id->dma_mword >> 8) & 7) ? ide_dma_on : | |
20175 | ((id->dma_1word >> 8) & 7) ? ide_dma_on : | |
20176 | @@ -673,9 +991,11 @@ | |
20177 | ||
20178 | static int config_drive_xfer_rate (ide_drive_t *drive) | |
20179 | { | |
20180 | - struct hd_driveid *id = drive->id; | |
20181 | - ide_hwif_t *hwif = HWIF(drive); | |
20182 | - ide_dma_action_t dma_func = ide_dma_off_quietly; | |
20183 | + struct hd_driveid *id = drive->id; | |
20184 | + ide_hwif_t *hwif = HWIF(drive); | |
20185 | + ide_dma_action_t dma_func = ide_dma_off_quietly; | |
20186 | + | |
20187 | + drive->init_speed = 0; | |
20188 | ||
20189 | if (id && (id->capability & 1) && hwif->autodma) { | |
20190 | /* Consult the list of known "bad" drives */ | |
20191 | @@ -685,9 +1005,9 @@ | |
20192 | } | |
20193 | dma_func = ide_dma_off_quietly; | |
20194 | if (id->field_valid & 4) { | |
20195 | - if (id->dma_ultra & 0x002F) { | |
20196 | + if (id->dma_ultra & 0x007F) { | |
20197 | /* Force if Capable UltraDMA */ | |
20198 | - dma_func = config_chipset_for_dma(drive, 1); | |
20199 | + dma_func = config_chipset_for_dma(drive); | |
20200 | if ((id->field_valid & 2) && | |
20201 | (dma_func != ide_dma_on)) | |
20202 | goto try_dma_modes; | |
20203 | @@ -697,7 +1017,7 @@ | |
20204 | if ((id->dma_mword & 0x0007) || | |
20205 | (id->dma_1word & 0x0007)) { | |
20206 | /* Force if Capable regular DMA modes */ | |
20207 | - dma_func = config_chipset_for_dma(drive, 0); | |
20208 | + dma_func = config_chipset_for_dma(drive); | |
20209 | if (dma_func != ide_dma_on) | |
20210 | goto no_dma_set; | |
20211 | } | |
20212 | @@ -706,7 +1026,7 @@ | |
20213 | goto no_dma_set; | |
20214 | } | |
20215 | /* Consult the list of known "good" drives */ | |
20216 | - dma_func = config_chipset_for_dma(drive, 0); | |
20217 | + dma_func = config_chipset_for_dma(drive); | |
20218 | if (dma_func != ide_dma_on) | |
20219 | goto no_dma_set; | |
20220 | } else { | |
20221 | @@ -716,10 +1036,10 @@ | |
20222 | fast_ata_pio: | |
20223 | dma_func = ide_dma_off_quietly; | |
20224 | no_dma_set: | |
20225 | - (void) config_chipset_for_pio(drive, 5); | |
20226 | + hwif->tuneproc(drive, 5); | |
20227 | } | |
20228 | ||
20229 | - return HWIF(drive)->dmaproc(dma_func, drive); | |
20230 | + return hwif->dmaproc(dma_func, drive); | |
20231 | } | |
20232 | ||
20233 | int pdc202xx_quirkproc (ide_drive_t *drive) | |
20234 | @@ -732,17 +1052,68 @@ | |
20235 | */ | |
20236 | int pdc202xx_dmaproc (ide_dma_action_t func, ide_drive_t *drive) | |
20237 | { | |
20238 | - byte dma_stat = 0, sc1d = 0; | |
20239 | - unsigned long high_16 = pci_resource_start(HWIF(drive)->pci_dev, 4); | |
20240 | - unsigned long dma_base = HWIF(drive)->dma_base; | |
20241 | + byte dma_stat = 0; | |
20242 | + byte sc1d = 0; | |
20243 | + byte newchip = 0; | |
20244 | + byte clock = 0; | |
20245 | + byte hardware48fix = 0; | |
20246 | + ide_hwif_t *hwif = HWIF(drive); | |
20247 | + struct pci_dev *dev = hwif->pci_dev; | |
20248 | + unsigned long high_16 = pci_resource_start(dev, 4); | |
20249 | + unsigned long atapi_reg = high_16 + (hwif->channel ? 0x24 : 0x20); | |
20250 | + unsigned long dma_base = hwif->dma_base; | |
20251 | + | |
20252 | + switch (dev->device) { | |
20253 | + case PCI_DEVICE_ID_PROMISE_20277: | |
20254 | + case PCI_DEVICE_ID_PROMISE_20276: | |
20255 | + case PCI_DEVICE_ID_PROMISE_20275: | |
20256 | + case PCI_DEVICE_ID_PROMISE_20271: | |
20257 | + case PCI_DEVICE_ID_PROMISE_20270: | |
20258 | + case PCI_DEVICE_ID_PROMISE_20269: | |
20259 | + case PCI_DEVICE_ID_PROMISE_20268: | |
20260 | + newchip = 1; | |
20261 | + break; | |
20262 | + case PCI_DEVICE_ID_PROMISE_20267: | |
20263 | + case PCI_DEVICE_ID_PROMISE_20265: | |
20264 | + hardware48fix = 1; | |
20265 | + clock = IN_BYTE(high_16 + 0x11); | |
20266 | + default: | |
20267 | + break; | |
20268 | + } | |
20269 | ||
20270 | switch (func) { | |
20271 | case ide_dma_check: | |
20272 | return config_drive_xfer_rate(drive); | |
20273 | + case ide_dma_begin: | |
20274 | + /* Note that this is done *after* the cmd has | |
20275 | + * been issued to the drive, as per the BM-IDE spec. | |
20276 | + * The Promise Ultra33 doesn't work correctly when | |
20277 | + * we do this part before issuing the drive cmd. | |
20278 | + */ | |
20279 | + if ((drive->addressing == 1) && (hardware48fix)) { | |
20280 | + struct request *rq = HWGROUP(drive)->rq; | |
20281 | + unsigned long word_count = 0; | |
20282 | + | |
20283 | + OUT_BYTE(clock|(hwif->channel ? 0x08 : 0x02), high_16 + 0x11); | |
20284 | + word_count = (rq->nr_sectors << 8); | |
20285 | + word_count = (rq->cmd == READ) ? word_count | 0x05000000 : word_count | 0x06000000; | |
20286 | + outl(word_count, atapi_reg); | |
20287 | + } | |
20288 | + break; | |
20289 | + case ide_dma_end: | |
20290 | + if ((drive->addressing == 1) && (hardware48fix)) { | |
20291 | + outl(0, atapi_reg); /* zero out extra */ | |
20292 | + clock = IN_BYTE(high_16 + 0x11); | |
20293 | + OUT_BYTE(clock & ~(hwif->channel ? 0x08:0x02), high_16 + 0x11); | |
20294 | + } | |
20295 | + break; | |
20296 | case ide_dma_test_irq: /* returns 1 if dma irq issued, 0 otherwise */ | |
20297 | - dma_stat = inb(dma_base+2); | |
20298 | - sc1d = inb(high_16 + 0x001d); | |
20299 | - if (HWIF(drive)->channel) { | |
20300 | + dma_stat = IN_BYTE(dma_base+2); | |
20301 | + if (newchip) | |
20302 | + return (dma_stat & 4) == 4; | |
20303 | + | |
20304 | + sc1d = IN_BYTE(high_16 + 0x001d); | |
20305 | + if (hwif->channel) { | |
20306 | if ((sc1d & 0x50) == 0x50) goto somebody_else; | |
20307 | else if ((sc1d & 0x40) == 0x40) | |
20308 | return (dma_stat & 4) == 4; | |
20309 | @@ -755,8 +1126,8 @@ | |
20310 | return (dma_stat & 4) == 4; /* return 1 if INTR asserted */ | |
20311 | case ide_dma_lostirq: | |
20312 | case ide_dma_timeout: | |
20313 | - if (HWIF(drive)->resetproc != NULL) | |
20314 | - HWIF(drive)->resetproc(drive); | |
20315 | + if (hwif->resetproc != NULL) | |
20316 | + hwif->resetproc(drive); | |
20317 | default: | |
20318 | break; | |
20319 | } | |
20320 | @@ -764,10 +1135,19 @@ | |
20321 | } | |
20322 | #endif /* CONFIG_BLK_DEV_IDEDMA */ | |
20323 | ||
20324 | -void pdc202xx_reset (ide_drive_t *drive) | |
20325 | +void pdc202xx_new_reset (ide_drive_t *drive) | |
20326 | +{ | |
20327 | + /* | |
20328 | + * Deleted this because it is redundant from the caller. | |
20329 | + */ | |
20330 | + printk("PDC202XX: %s channel reset.\n", | |
20331 | + HWIF(drive)->channel ? "Secondary" : "Primary"); | |
20332 | +} | |
20333 | + | |
20334 | +void pdc202xx_reset_pci (struct pci_dev *dev) | |
20335 | { | |
20336 | - unsigned long high_16 = pci_resource_start(HWIF(drive)->pci_dev, 4); | |
20337 | - byte udma_speed_flag = inb(high_16 + 0x001f); | |
20338 | + unsigned long high_16 = pci_resource_start(dev, 4); | |
20339 | + byte udma_speed_flag = IN_BYTE(high_16 + 0x001f); | |
20340 | ||
20341 | OUT_BYTE(udma_speed_flag | 0x10, high_16 + 0x001f); | |
20342 | mdelay(100); | |
20343 | @@ -775,50 +1155,102 @@ | |
20344 | mdelay(2000); /* 2 seconds ?! */ | |
20345 | } | |
20346 | ||
20347 | -unsigned int __init pci_init_pdc202xx (struct pci_dev *dev, const char *name) | |
20348 | +void pdc202xx_reset_host (ide_hwif_t *hwif) | |
20349 | +{ | |
20350 | + pdc202xx_reset_pci(hwif->pci_dev); | |
20351 | + printk("PDC202XX: %s channel reset.\n", | |
20352 | + hwif->channel ? "Secondary" : "Primary"); | |
20353 | +} | |
20354 | + | |
20355 | +void pdc202xx_reset (ide_drive_t *drive) | |
20356 | +{ | |
20357 | + pdc202xx_reset_host(HWIF(drive)); | |
20358 | +} | |
20359 | + | |
20360 | +/* | |
20361 | + * Since SUN Cobalt is attempting to do this operation, I should disclose | |
20362 | + * this has been a long time ago Thu Jul 27 16:40:57 2000 was the patch date | |
20363 | + * HOTSWAP ATA Infrastructure. | |
20364 | + */ | |
20365 | +static int pdc202xx_tristate (ide_drive_t * drive, int state) | |
20366 | { | |
20367 | - unsigned long high_16 = pci_resource_start(dev, 4); | |
20368 | - byte udma_speed_flag = inb(high_16 + 0x001f); | |
20369 | - byte primary_mode = inb(high_16 + 0x001a); | |
20370 | - byte secondary_mode = inb(high_16 + 0x001b); | |
20371 | - | |
20372 | - if ((dev->device == PCI_DEVICE_ID_PROMISE_20262) || | |
20373 | - (dev->device == PCI_DEVICE_ID_PROMISE_20265) || | |
20374 | - (dev->device == PCI_DEVICE_ID_PROMISE_20267)) { | |
20375 | - /* | |
20376 | - * software reset - this is required because the bios | |
20377 | - * will set UDMA timing on if the hdd supports it. The | |
20378 | - * user may want to turn udma off. A bug in the pdc20262 | |
20379 | - * is that it cannot handle a downgrade in timing from UDMA | |
20380 | - * to DMA. Disk accesses after issuing a set feature command | |
20381 | - * will result in errors. A software reset leaves the timing | |
20382 | - * registers intact, but resets the drives. | |
20383 | - */ | |
20384 | - | |
20385 | - OUT_BYTE(udma_speed_flag | 0x10, high_16 + 0x001f); | |
20386 | - mdelay(100); | |
20387 | - OUT_BYTE(udma_speed_flag & ~0x10, high_16 + 0x001f); | |
20388 | - mdelay(2000); /* 2 seconds ?! */ | |
20389 | +#if 0 | |
20390 | + ide_hwif_t *hwif = HWIF(drive); | |
20391 | + unsigned long high_16 = pci_resource_start(hwif->pci_dev, 4); | |
20392 | + byte sc1f = IN_BYTE(high_16 + 0x001f); | |
20393 | + | |
20394 | + if (!hwif) | |
20395 | + return -EINVAL; | |
20396 | + | |
20397 | +// hwif->bus_state = state; | |
20398 | + | |
20399 | + if (state) { | |
20400 | + OUT_BYTE(sc1f | 0x08, high_16 + 0x001f); | |
20401 | + } else { | |
20402 | + OUT_BYTE(sc1f & ~0x08, high_16 + 0x001f); | |
20403 | } | |
20404 | +#endif | |
20405 | + return 0; | |
20406 | +} | |
20407 | + | |
20408 | +unsigned int __init pci_init_pdc202xx (struct pci_dev *dev, const char *name) | |
20409 | +{ | |
20410 | + unsigned long high_16 = pci_resource_start(dev, 4); | |
20411 | + byte udma_speed_flag = IN_BYTE(high_16 + 0x001f); | |
20412 | + byte primary_mode = IN_BYTE(high_16 + 0x001a); | |
20413 | + byte secondary_mode = IN_BYTE(high_16 + 0x001b); | |
20414 | + byte newchip = 0; | |
20415 | ||
20416 | if (dev->resource[PCI_ROM_RESOURCE].start) { | |
20417 | - pci_write_config_dword(dev, PCI_ROM_ADDRESS, dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE); | |
20418 | - printk("%s: ROM enabled at 0x%08lx\n", name, dev->resource[PCI_ROM_RESOURCE].start); | |
20419 | + pci_write_config_dword(dev, PCI_ROM_ADDRESS, | |
20420 | + dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE); | |
20421 | + printk("%s: ROM enabled at 0x%08lx\n", | |
20422 | + name, dev->resource[PCI_ROM_RESOURCE].start); | |
20423 | } | |
20424 | ||
20425 | - if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE) { | |
20426 | - byte irq = 0, irq2 = 0; | |
20427 | - pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq); | |
20428 | - pci_read_config_byte(dev, (PCI_INTERRUPT_LINE)|0x80, &irq2); /* 0xbc */ | |
20429 | - if ((irq != irq2) && | |
20430 | - (dev->device != PCI_DEVICE_ID_PROMISE_20265) && | |
20431 | - (dev->device != PCI_DEVICE_ID_PROMISE_20267) && | |
20432 | - (dev->device != PCI_DEVICE_ID_PROMISE_20268)) { | |
20433 | - pci_write_config_byte(dev, (PCI_INTERRUPT_LINE)|0x80, irq); /* 0xbc */ | |
20434 | - printk("%s: pci-config space interrupt mirror fixed.\n", name); | |
20435 | - } | |
20436 | + switch (dev->device) { | |
20437 | + case PCI_DEVICE_ID_PROMISE_20277: | |
20438 | + case PCI_DEVICE_ID_PROMISE_20276: | |
20439 | + case PCI_DEVICE_ID_PROMISE_20275: | |
20440 | + case PCI_DEVICE_ID_PROMISE_20271: | |
20441 | + case PCI_DEVICE_ID_PROMISE_20269: | |
20442 | + case PCI_DEVICE_ID_PROMISE_20270: | |
20443 | + case PCI_DEVICE_ID_PROMISE_20268: | |
20444 | + newchip = 1; | |
20445 | + break; | |
20446 | + case PCI_DEVICE_ID_PROMISE_20267: | |
20447 | + case PCI_DEVICE_ID_PROMISE_20265: | |
20448 | + pdc202xx_reset_pci(dev); | |
20449 | + break; | |
20450 | + case PCI_DEVICE_ID_PROMISE_20263: | |
20451 | + case PCI_DEVICE_ID_PROMISE_20262: | |
20452 | + /* | |
20453 | + * software reset - this is required because the bios | |
20454 | + * will set UDMA timing on if the hdd supports it. The | |
20455 | + * user may want to turn udma off. A bug in the pdc20262 | |
20456 | + * is that it cannot handle a downgrade in timing from | |
20457 | + * UDMA to DMA. Disk accesses after issuing a set | |
20458 | + * feature command will result in errors. A software | |
20459 | + * reset leaves the timing registers intact, | |
20460 | + * but resets the drives. | |
20461 | + */ | |
20462 | + pdc202xx_reset_pci(dev); | |
20463 | + default: | |
20464 | + if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE) { | |
20465 | + byte irq = 0, irq2 = 0; | |
20466 | + pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq); | |
20467 | + pci_read_config_byte(dev, (PCI_INTERRUPT_LINE)|0x80, &irq2); /* 0xbc */ | |
20468 | + if (irq != irq2) { | |
20469 | + pci_write_config_byte(dev, (PCI_INTERRUPT_LINE)|0x80, irq); /* 0xbc */ | |
20470 | + printk("%s: pci-config space interrupt mirror fixed.\n", name); | |
20471 | + } | |
20472 | + } | |
20473 | + break; | |
20474 | } | |
20475 | ||
20476 | + if (newchip) | |
20477 | + goto fttk_tx_series; | |
20478 | + | |
20479 | printk("%s: (U)DMA Burst Bit %sABLED " \ | |
20480 | "Primary %s Mode " \ | |
20481 | "Secondary %s Mode.\n", | |
20482 | @@ -830,8 +1262,8 @@ | |
20483 | #ifdef CONFIG_PDC202XX_BURST | |
20484 | if (!(udma_speed_flag & 1)) { | |
20485 | printk("%s: FORCING BURST BIT 0x%02x -> 0x%02x ", name, udma_speed_flag, (udma_speed_flag|1)); | |
20486 | - outb(udma_speed_flag|1, high_16 + 0x001f); | |
20487 | - printk("%sCTIVE\n", (inb(high_16 + 0x001f) & 1) ? "A" : "INA"); | |
20488 | + OUT_BYTE(udma_speed_flag|1, high_16 + 0x001f); | |
20489 | + printk("%sCTIVE\n", (IN_BYTE(high_16 + 0x001f) & 1) ? "A" : "INA"); | |
20490 | } | |
20491 | #endif /* CONFIG_PDC202XX_BURST */ | |
20492 | ||
20493 | @@ -839,25 +1271,29 @@ | |
20494 | if (!(primary_mode & 1)) { | |
20495 | printk("%s: FORCING PRIMARY MODE BIT 0x%02x -> 0x%02x ", | |
20496 | name, primary_mode, (primary_mode|1)); | |
20497 | - outb(primary_mode|1, high_16 + 0x001a); | |
20498 | - printk("%s\n", (inb(high_16 + 0x001a) & 1) ? "MASTER" : "PCI"); | |
20499 | + OUT_BYTE(primary_mode|1, high_16 + 0x001a); | |
20500 | + printk("%s\n", (IN_BYTE(high_16 + 0x001a) & 1) ? "MASTER" : "PCI"); | |
20501 | } | |
20502 | ||
20503 | if (!(secondary_mode & 1)) { | |
20504 | printk("%s: FORCING SECONDARY MODE BIT 0x%02x -> 0x%02x ", | |
20505 | name, secondary_mode, (secondary_mode|1)); | |
20506 | - outb(secondary_mode|1, high_16 + 0x001b); | |
20507 | - printk("%s\n", (inb(high_16 + 0x001b) & 1) ? "MASTER" : "PCI"); | |
20508 | + OUT_BYTE(secondary_mode|1, high_16 + 0x001b); | |
20509 | + printk("%s\n", (IN_BYTE(high_16 + 0x001b) & 1) ? "MASTER" : "PCI"); | |
20510 | } | |
20511 | #endif /* CONFIG_PDC202XX_MASTER */ | |
20512 | ||
20513 | +fttk_tx_series: | |
20514 | + | |
20515 | + pdc202_devs[n_pdc202_devs++] = dev; | |
20516 | + | |
20517 | #if defined(DISPLAY_PDC202XX_TIMINGS) && defined(CONFIG_PROC_FS) | |
20518 | if (!pdc202xx_proc) { | |
20519 | pdc202xx_proc = 1; | |
20520 | - bmide_dev = dev; | |
20521 | pdc202xx_display_info = &pdc202xx_get_info; | |
20522 | } | |
20523 | #endif /* DISPLAY_PDC202XX_TIMINGS && CONFIG_PROC_FS */ | |
20524 | + | |
20525 | return dev->irq; | |
20526 | } | |
20527 | ||
20528 | @@ -866,21 +1302,32 @@ | |
20529 | unsigned short mask = (hwif->channel) ? (1<<11) : (1<<10); | |
20530 | unsigned short CIS; | |
20531 | ||
20532 | - pci_read_config_word(hwif->pci_dev, 0x50, &CIS); | |
20533 | - return ((CIS & mask) ? 0 : 1); | |
20534 | + switch(hwif->pci_dev->device) { | |
20535 | + case PCI_DEVICE_ID_PROMISE_20277: | |
20536 | + case PCI_DEVICE_ID_PROMISE_20276: | |
20537 | + case PCI_DEVICE_ID_PROMISE_20275: | |
20538 | + case PCI_DEVICE_ID_PROMISE_20271: | |
20539 | + case PCI_DEVICE_ID_PROMISE_20269: | |
20540 | + case PCI_DEVICE_ID_PROMISE_20268: | |
20541 | + case PCI_DEVICE_ID_PROMISE_20270: | |
20542 | + OUT_BYTE(0x0b, (hwif->dma_base + 1)); | |
20543 | + return (!(IN_BYTE((hwif->dma_base + 3)) & 0x04)); | |
20544 | + case PCI_DEVICE_ID_PROMISE_20267: | |
20545 | + hwif->addressing = (hwif->channel) ? 0 : 1; | |
20546 | + default: | |
20547 | + pci_read_config_word(hwif->pci_dev, 0x50, &CIS); | |
20548 | + return (!(CIS & mask)); | |
20549 | + } | |
20550 | } | |
20551 | ||
20552 | void __init ide_init_pdc202xx (ide_hwif_t *hwif) | |
20553 | { | |
20554 | - hwif->tuneproc = &pdc202xx_tune_drive; | |
20555 | - hwif->speedproc = &pdc202xx_tune_chipset; | |
20556 | - hwif->quirkproc = &pdc202xx_quirkproc; | |
20557 | - | |
20558 | - if ((hwif->pci_dev->device == PCI_DEVICE_ID_PROMISE_20262) || | |
20559 | - (hwif->pci_dev->device == PCI_DEVICE_ID_PROMISE_20265) || | |
20560 | - (hwif->pci_dev->device == PCI_DEVICE_ID_PROMISE_20267)) { | |
20561 | - hwif->resetproc = &pdc202xx_reset; | |
20562 | - } | |
20563 | + hwif->tuneproc = &pdc202xx_tune_drive; | |
20564 | + hwif->quirkproc = &pdc202xx_quirkproc; | |
20565 | + | |
20566 | + hwif->drives[0].autotune = 1; | |
20567 | + hwif->drives[1].autotune = 1; | |
20568 | + hwif->autodma = 0; | |
20569 | ||
20570 | #undef CONFIG_PDC202XX_32_UNMASK | |
20571 | #ifdef CONFIG_PDC202XX_32_UNMASK | |
20572 | @@ -890,19 +1337,85 @@ | |
20573 | hwif->drives[1].unmask = 1; | |
20574 | #endif /* CONFIG_PDC202XX_32_UNMASK */ | |
20575 | ||
20576 | -#ifdef CONFIG_BLK_DEV_IDEDMA | |
20577 | - if (hwif->dma_base) { | |
20578 | - hwif->dmaproc = &pdc202xx_dmaproc; | |
20579 | - if (!noautodma) | |
20580 | - hwif->autodma = 1; | |
20581 | - } else { | |
20582 | - hwif->drives[0].autotune = 1; | |
20583 | - hwif->drives[1].autotune = 1; | |
20584 | - hwif->autodma = 0; | |
20585 | + switch(hwif->pci_dev->device) { | |
20586 | + case PCI_DEVICE_ID_PROMISE_20277: | |
20587 | + case PCI_DEVICE_ID_PROMISE_20276: | |
20588 | + case PCI_DEVICE_ID_PROMISE_20275: | |
20589 | + case PCI_DEVICE_ID_PROMISE_20271: | |
20590 | + case PCI_DEVICE_ID_PROMISE_20269: | |
20591 | + case PCI_DEVICE_ID_PROMISE_20268: | |
20592 | + case PCI_DEVICE_ID_PROMISE_20270: | |
20593 | + hwif->speedproc = &pdc202xx_new_tune_chipset; | |
20594 | + hwif->resetproc = &pdc202xx_new_reset; | |
20595 | + break; | |
20596 | + case PCI_DEVICE_ID_PROMISE_20267: | |
20597 | + case PCI_DEVICE_ID_PROMISE_20265: | |
20598 | + case PCI_DEVICE_ID_PROMISE_20263: | |
20599 | + case PCI_DEVICE_ID_PROMISE_20262: | |
20600 | + hwif->busproc = &pdc202xx_tristate; | |
20601 | + hwif->resetproc = &pdc202xx_reset; | |
20602 | + case PCI_DEVICE_ID_PROMISE_20246: | |
20603 | + hwif->speedproc = &pdc202xx_tune_chipset; | |
20604 | + default: | |
20605 | + break; | |
20606 | } | |
20607 | -#else /* !CONFIG_BLK_DEV_IDEDMA */ | |
20608 | - hwif->drives[0].autotune = 1; | |
20609 | - hwif->drives[1].autotune = 1; | |
20610 | - hwif->autodma = 0; | |
20611 | + | |
20612 | + if (!hwif->dma_base) | |
20613 | + return; | |
20614 | + | |
20615 | +#ifdef CONFIG_BLK_DEV_IDEDMA | |
20616 | + hwif->dmaproc = &pdc202xx_dmaproc; | |
20617 | +# ifdef CONFIG_IDEDMA_AUTO | |
20618 | + if (!noautodma) | |
20619 | + hwif->autodma = 1; | |
20620 | +# endif /* CONFIG_IDEDMA_AUTO */ | |
20621 | #endif /* CONFIG_BLK_DEV_IDEDMA */ | |
20622 | } | |
20623 | + | |
20624 | +extern void ide_setup_pci_device (struct pci_dev *dev, ide_pci_device_t *d); | |
20625 | + | |
20626 | +void __init fixup_device_pdc20265 (struct pci_dev *dev, ide_pci_device_t *d) | |
20627 | +{ | |
20628 | + printk("%s: IDE controller on PCI bus %02x dev %02x\n", | |
20629 | + d->name, dev->bus->number, dev->devfn); | |
20630 | + ide_setup_pci_device(dev, d); | |
20631 | +} | |
20632 | + | |
20633 | +void __init fixup_device_pdc20270 (struct pci_dev *dev, ide_pci_device_t *d) | |
20634 | +{ | |
20635 | + struct pci_dev *dev2 = NULL, *findev; | |
20636 | + ide_pci_device_t *d2; | |
20637 | + | |
20638 | + if ((dev->bus->self && | |
20639 | + dev->bus->self->vendor == PCI_VENDOR_ID_DEC) && | |
20640 | + (dev->bus->self->device == PCI_DEVICE_ID_DEC_21150)) { | |
20641 | + if (PCI_SLOT(dev->devfn) & 2) { | |
20642 | + return; | |
20643 | + } | |
20644 | + d->extra = 0; | |
20645 | + pci_for_each_dev(findev) { | |
20646 | + if ((findev->vendor == dev->vendor) && | |
20647 | + (findev->device == dev->device) && | |
20648 | + (PCI_SLOT(findev->devfn) & 2)) { | |
20649 | + byte irq = 0, irq2 = 0; | |
20650 | + dev2 = findev; | |
20651 | + pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq); | |
20652 | + pci_read_config_byte(dev2, PCI_INTERRUPT_LINE, &irq2); | |
20653 | + if (irq != irq2) { | |
20654 | + dev2->irq = dev->irq; | |
20655 | + pci_write_config_byte(dev2, PCI_INTERRUPT_LINE, irq); | |
20656 | + } | |
20657 | + } | |
20658 | + } | |
20659 | + } | |
20660 | + | |
20661 | + printk("%s: IDE controller on PCI bus %02x dev %02x\n", | |
20662 | + d->name, dev->bus->number, dev->devfn); | |
20663 | + ide_setup_pci_device(dev, d); | |
20664 | + if (!dev2) | |
20665 | + return; | |
20666 | + d2 = d; | |
20667 | + printk("%s: IDE controller on PCI bus %02x dev %02x\n", | |
20668 | + d2->name, dev2->bus->number, dev2->devfn); | |
20669 | + ide_setup_pci_device(dev2, d2); | |
20670 | +} | |
20671 | diff -Nur linux.org/drivers/ide/pdc4030.c linux/drivers/ide/pdc4030.c | |
20672 | --- linux.org/drivers/ide/pdc4030.c Wed Jul 18 03:53:55 2001 | |
20673 | +++ linux/drivers/ide/pdc4030.c Thu Jul 18 14:24:34 2002 | |
20674 | @@ -168,7 +168,8 @@ | |
20675 | if (hwif->chipset == ide_pdc4030) /* we've already been found ! */ | |
20676 | return 1; | |
20677 | ||
20678 | - if (IN_BYTE(IDE_NSECTOR_REG) == 0xFF || IN_BYTE(IDE_SECTOR_REG) == 0xFF) { | |
20679 | + if (IN_BYTE(IDE_NSECTOR_REG) == 0xFF || | |
20680 | + IN_BYTE(IDE_SECTOR_REG) == 0xFF) { | |
20681 | return 0; | |
20682 | } | |
20683 | if (IDE_CONTROL_REG) | |
20684 | @@ -181,7 +182,7 @@ | |
20685 | "%s: Failed Promise read config!\n",hwif->name); | |
20686 | return 0; | |
20687 | } | |
20688 | - ide_input_data(drive,&ident,SECTOR_WORDS); | |
20689 | + ata_input_data(drive, &ident, SECTOR_WORDS); | |
20690 | if (ident.id[1] != 'P' || ident.id[0] != 'T') { | |
20691 | return 0; | |
20692 | } | |
20693 | @@ -234,7 +235,7 @@ | |
20694 | ||
20695 | #ifdef DEBUG | |
20696 | printk(KERN_DEBUG "Shifting i/f %d values to i/f %d\n",i-1,i); | |
20697 | -#endif | |
20698 | +#endif /* DEBUG */ | |
20699 | ide_init_hwif_ports(&h->hw, (h-1)->io_ports[IDE_DATA_OFFSET], 0, NULL); | |
20700 | memcpy(h->io_ports, h->hw.io_ports, sizeof(h->io_ports)); | |
20701 | h->noprobe = (h-1)->noprobe; | |
20702 | @@ -298,8 +299,6 @@ | |
20703 | } | |
20704 | } | |
20705 | ||
20706 | - | |
20707 | - | |
20708 | /* | |
20709 | * promise_read_intr() is the handler for disk read/multread interrupts | |
20710 | */ | |
20711 | @@ -309,10 +308,13 @@ | |
20712 | int total_remaining; | |
20713 | unsigned int sectors_left, sectors_avail, nsect; | |
20714 | struct request *rq; | |
20715 | +#ifdef CONFIG_IDE_TASKFILE_IO | |
20716 | + unsigned long flags; | |
20717 | + char *to; | |
20718 | +#endif /* CONFIG_IDE_TASKFILE_IO */ | |
20719 | ||
20720 | - if (!OK_STAT(stat=GET_STAT(),DATA_READY,BAD_R_STAT)) { | |
20721 | - return ide_error(drive, "promise_read_intr", stat); | |
20722 | - } | |
20723 | + if (!OK_STAT(stat=GET_STAT(),DATA_READY,BAD_R_STAT)) | |
20724 | + return DRIVER(drive)->error(drive, "promise_read_intr", stat); | |
20725 | ||
20726 | read_again: | |
20727 | do { | |
20728 | @@ -330,20 +332,36 @@ | |
20729 | if (nsect > sectors_avail) | |
20730 | nsect = sectors_avail; | |
20731 | sectors_avail -= nsect; | |
20732 | - ide_input_data(drive, rq->buffer, nsect * SECTOR_WORDS); | |
20733 | +#ifdef CONFIG_IDE_TASKFILE_IO | |
20734 | + to = ide_map_buffer(rq, &flags); | |
20735 | + ata_input_data(drive, to, nsect * SECTOR_WORDS); | |
20736 | +#else /* !CONFIG_IDE_TASKFILE_IO */ | |
20737 | + ata_input_data(drive, rq->buffer, nsect * SECTOR_WORDS); | |
20738 | +#endif /* CONFIG_IDE_TASKFILE_IO */ | |
20739 | + | |
20740 | #ifdef DEBUG_READ | |
20741 | printk(KERN_DEBUG "%s: promise_read: sectors(%ld-%ld), " | |
20742 | "buf=0x%08lx, rem=%ld\n", drive->name, rq->sector, | |
20743 | - rq->sector+nsect-1, (unsigned long) rq->buffer, | |
20744 | + rq->sector+nsect-1, | |
20745 | +#ifdef CONFIG_IDE_TASKFILE_IO | |
20746 | + (unsigned long) to, | |
20747 | +#else /* !CONFIG_IDE_TASKFILE_IO */ | |
20748 | + (unsigned long) rq->buffer, | |
20749 | +#endif /* CONFIG_IDE_TASKFILE_IO */ | |
20750 | rq->nr_sectors-nsect); | |
20751 | -#endif | |
20752 | - rq->sector += nsect; | |
20753 | +#endif /* DEBUG_READ */ | |
20754 | + | |
20755 | +#ifdef CONFIG_IDE_TASKFILE_IO | |
20756 | + ide_unmap_buffer(to, &flags); | |
20757 | +#else /* !CONFIG_IDE_TASKFILE_IO */ | |
20758 | rq->buffer += nsect<<9; | |
20759 | +#endif /* CONFIG_IDE_TASKFILE_IO */ | |
20760 | + rq->sector += nsect; | |
20761 | rq->errors = 0; | |
20762 | rq->nr_sectors -= nsect; | |
20763 | total_remaining = rq->nr_sectors; | |
20764 | if ((rq->current_nr_sectors -= nsect) <= 0) { | |
20765 | - ide_end_request(1, HWGROUP(drive)); | |
20766 | + DRIVER(drive)->end_request(drive, 1); | |
20767 | } | |
20768 | /* | |
20769 | * Now the data has been read in, do the following: | |
20770 | @@ -363,16 +381,18 @@ | |
20771 | if (stat & DRQ_STAT) | |
20772 | goto read_again; | |
20773 | if (stat & BUSY_STAT) { | |
20774 | + if (HWGROUP(drive)->handler != NULL) /* paranoia check */ | |
20775 | + BUG(); | |
20776 | ide_set_handler (drive, &promise_read_intr, WAIT_CMD, NULL); | |
20777 | #ifdef DEBUG_READ | |
20778 | printk(KERN_DEBUG "%s: promise_read: waiting for" | |
20779 | "interrupt\n", drive->name); | |
20780 | -#endif | |
20781 | +#endif /* DEBUG_READ */ | |
20782 | return ide_started; | |
20783 | } | |
20784 | printk(KERN_ERR "%s: Eeek! promise_read_intr: sectors left " | |
20785 | "!DRQ !BUSY\n", drive->name); | |
20786 | - return ide_error(drive, "promise read intr", stat); | |
20787 | + return DRIVER(drive)->error(drive, "promise read intr", stat); | |
20788 | } | |
20789 | return ide_stopped; | |
20790 | } | |
20791 | @@ -393,27 +413,95 @@ | |
20792 | ||
20793 | if (GET_STAT() & BUSY_STAT) { | |
20794 | if (time_before(jiffies, hwgroup->poll_timeout)) { | |
20795 | + if (HWGROUP(drive)->handler != NULL) /* paranoia check */ | |
20796 | + BUG(); | |
20797 | ide_set_handler(drive, &promise_complete_pollfunc, HZ/100, NULL); | |
20798 | return ide_started; /* continue polling... */ | |
20799 | } | |
20800 | hwgroup->poll_timeout = 0; | |
20801 | printk(KERN_ERR "%s: completion timeout - still busy!\n", | |
20802 | drive->name); | |
20803 | - return ide_error(drive, "busy timeout", GET_STAT()); | |
20804 | + return DRIVER(drive)->error(drive, "busy timeout", GET_STAT()); | |
20805 | } | |
20806 | ||
20807 | hwgroup->poll_timeout = 0; | |
20808 | #ifdef DEBUG_WRITE | |
20809 | printk(KERN_DEBUG "%s: Write complete - end_request\n", drive->name); | |
20810 | -#endif | |
20811 | +#endif /* DEBUG_WRITE */ | |
20812 | for (i = rq->nr_sectors; i > 0; ) { | |
20813 | i -= rq->current_nr_sectors; | |
20814 | - ide_end_request(1, hwgroup); | |
20815 | + DRIVER(drive)->end_request(drive, 1); | |
20816 | } | |
20817 | return ide_stopped; | |
20818 | } | |
20819 | ||
20820 | /* | |
20821 | + * promise_multwrite() transfers a block of up to mcount sectors of data | |
20822 | + * to a drive as part of a disk multiple-sector write operation. | |
20823 | + * | |
20824 | + * Returns 0 on success. | |
20825 | + * | |
20826 | + * Note that we may be called from two contexts - the do_rw_disk context | |
20827 | + * and IRQ context. The IRQ can happen any time after we've output the | |
20828 | + * full "mcount" number of sectors, so we must make sure we update the | |
20829 | + * state _before_ we output the final part of the data! | |
20830 | + */ | |
20831 | +int promise_multwrite (ide_drive_t *drive, unsigned int mcount) | |
20832 | +{ | |
20833 | + ide_hwgroup_t *hwgroup = HWGROUP(drive); | |
20834 | + struct request *rq = &hwgroup->wrq; | |
20835 | + | |
20836 | + do { | |
20837 | + char *buffer; | |
20838 | + int nsect = rq->current_nr_sectors; | |
20839 | +#ifdef CONFIG_IDE_TASKFILE_IO | |
20840 | + unsigned long flags; | |
20841 | +#endif /* CONFIG_IDE_TASKFILE_IO */ | |
20842 | + | |
20843 | + if (nsect > mcount) | |
20844 | + nsect = mcount; | |
20845 | + mcount -= nsect; | |
20846 | +#ifdef CONFIG_IDE_TASKFILE_IO | |
20847 | + buffer = ide_map_buffer(rq, &flags); | |
20848 | + rq->sector += nsect; | |
20849 | +#else /* !CONFIG_IDE_TASKFILE_IO */ | |
20850 | + buffer = rq->buffer; | |
20851 | + | |
20852 | + rq->sector += nsect; | |
20853 | + rq->buffer += nsect << 9; | |
20854 | +#endif /* CONFIG_IDE_TASKFILE_IO */ | |
20855 | + rq->nr_sectors -= nsect; | |
20856 | + rq->current_nr_sectors -= nsect; | |
20857 | + | |
20858 | + /* Do we move to the next bh after this? */ | |
20859 | + if (!rq->current_nr_sectors) { | |
20860 | + struct buffer_head *bh = rq->bh->b_reqnext; | |
20861 | + | |
20862 | + /* end early early we ran out of requests */ | |
20863 | + if (!bh) { | |
20864 | + mcount = 0; | |
20865 | + } else { | |
20866 | + rq->bh = bh; | |
20867 | + rq->current_nr_sectors = bh->b_size >> 9; | |
20868 | + rq->hard_cur_sectors = rq->current_nr_sectors; | |
20869 | + rq->buffer = bh->b_data; | |
20870 | + } | |
20871 | + } | |
20872 | + | |
20873 | + /* | |
20874 | + * Ok, we're all setup for the interrupt | |
20875 | + * re-entering us on the last transfer. | |
20876 | + */ | |
20877 | + taskfile_output_data(drive, buffer, nsect<<7); | |
20878 | +#ifdef CONFIG_IDE_TASKFILE_IO | |
20879 | + ide_unmap_buffer(buffer, &flags); | |
20880 | +#endif /* CONFIG_IDE_TASKFILE_IO */ | |
20881 | + } while (mcount); | |
20882 | + | |
20883 | + return 0; | |
20884 | +} | |
20885 | + | |
20886 | +/* | |
20887 | * promise_write_pollfunc() is the handler for disk write completion polling. | |
20888 | */ | |
20889 | static ide_startstop_t promise_write_pollfunc (ide_drive_t *drive) | |
20890 | @@ -422,24 +510,28 @@ | |
20891 | ||
20892 | if (IN_BYTE(IDE_NSECTOR_REG) != 0) { | |
20893 | if (time_before(jiffies, hwgroup->poll_timeout)) { | |
20894 | + if (HWGROUP(drive)->handler != NULL) /* paranoia check */ | |
20895 | + BUG(); | |
20896 | ide_set_handler (drive, &promise_write_pollfunc, HZ/100, NULL); | |
20897 | return ide_started; /* continue polling... */ | |
20898 | } | |
20899 | hwgroup->poll_timeout = 0; | |
20900 | printk(KERN_ERR "%s: write timed-out!\n",drive->name); | |
20901 | - return ide_error (drive, "write timeout", GET_STAT()); | |
20902 | + return DRIVER(drive)->error(drive, "write timeout", GET_STAT()); | |
20903 | } | |
20904 | ||
20905 | /* | |
20906 | * Now write out last 4 sectors and poll for not BUSY | |
20907 | */ | |
20908 | - ide_multwrite(drive, 4); | |
20909 | + promise_multwrite(drive, 4); | |
20910 | hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE; | |
20911 | + if (HWGROUP(drive)->handler != NULL) /* paranoia check */ | |
20912 | + BUG(); | |
20913 | ide_set_handler(drive, &promise_complete_pollfunc, HZ/100, NULL); | |
20914 | #ifdef DEBUG_WRITE | |
20915 | printk(KERN_DEBUG "%s: Done last 4 sectors - status = %02x\n", | |
20916 | drive->name, GET_STAT()); | |
20917 | -#endif | |
20918 | +#endif /* DEBUG_WRITE */ | |
20919 | return ide_started; | |
20920 | } | |
20921 | ||
20922 | @@ -459,16 +551,18 @@ | |
20923 | printk(KERN_DEBUG "%s: promise_write: sectors(%ld-%ld), " | |
20924 | "buffer=%p\n", drive->name, rq->sector, | |
20925 | rq->sector + rq->nr_sectors - 1, rq->buffer); | |
20926 | -#endif | |
20927 | +#endif /* DEBUG_WRITE */ | |
20928 | ||
20929 | /* | |
20930 | * If there are more than 4 sectors to transfer, do n-4 then go into | |
20931 | * the polling strategy as defined above. | |
20932 | */ | |
20933 | if (rq->nr_sectors > 4) { | |
20934 | - if (ide_multwrite(drive, rq->nr_sectors - 4)) | |
20935 | + if (promise_multwrite(drive, rq->nr_sectors - 4)) | |
20936 | return ide_stopped; | |
20937 | hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE; | |
20938 | + if (HWGROUP(drive)->handler != NULL) /* paranoia check */ | |
20939 | + BUG(); | |
20940 | ide_set_handler (drive, &promise_write_pollfunc, HZ/100, NULL); | |
20941 | return ide_started; | |
20942 | } else { | |
20943 | @@ -476,14 +570,16 @@ | |
20944 | * There are 4 or fewer sectors to transfer, do them all in one go | |
20945 | * and wait for NOT BUSY. | |
20946 | */ | |
20947 | - if (ide_multwrite(drive, rq->nr_sectors)) | |
20948 | + if (promise_multwrite(drive, rq->nr_sectors)) | |
20949 | return ide_stopped; | |
20950 | hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE; | |
20951 | + if (HWGROUP(drive)->handler != NULL) /* paranoia check */ | |
20952 | + BUG(); | |
20953 | ide_set_handler(drive, &promise_complete_pollfunc, HZ/100, NULL); | |
20954 | #ifdef DEBUG_WRITE | |
20955 | printk(KERN_DEBUG "%s: promise_write: <= 4 sectors, " | |
20956 | "status = %02x\n", drive->name, GET_STAT()); | |
20957 | -#endif | |
20958 | +#endif /* DEBUG_WRITE */ | |
20959 | return ide_started; | |
20960 | } | |
20961 | } | |
20962 | @@ -493,13 +589,40 @@ | |
20963 | * already set up. It issues a READ or WRITE command to the Promise | |
20964 | * controller, assuming LBA has been used to set up the block number. | |
20965 | */ | |
20966 | +#ifndef CONFIG_IDE_TASKFILE_IO | |
20967 | ide_startstop_t do_pdc4030_io (ide_drive_t *drive, struct request *rq) | |
20968 | { | |
20969 | +#else /* CONFIG_IDE_TASKFILE_IO */ | |
20970 | +ide_startstop_t do_pdc4030_io (ide_drive_t *drive, ide_task_t *task) | |
20971 | +{ | |
20972 | + struct request *rq = HWGROUP(drive)->rq; | |
20973 | + task_struct_t *taskfile = (task_struct_t *) task->tfRegister; | |
20974 | +#endif /* CONFIG_IDE_TASKFILE_IO */ | |
20975 | + ide_startstop_t startstop; | |
20976 | unsigned long timeout; | |
20977 | byte stat; | |
20978 | ||
20979 | - if (rq->cmd == READ) { | |
20980 | +#ifdef CONFIG_IDE_TASKFILE_IO | |
20981 | + if (IDE_CONTROL_REG) | |
20982 | + OUT_BYTE(drive->ctl, IDE_CONTROL_REG); /* clear nIEN */ | |
20983 | + SELECT_MASK(HWIF(drive), drive, 0); | |
20984 | + | |
20985 | + OUT_BYTE(taskfile->feature, IDE_FEATURE_REG); | |
20986 | + OUT_BYTE(taskfile->sector_count, IDE_NSECTOR_REG); | |
20987 | + /* refers to number of sectors to transfer */ | |
20988 | + OUT_BYTE(taskfile->sector_number, IDE_SECTOR_REG); | |
20989 | + /* refers to sector offset or start sector */ | |
20990 | + OUT_BYTE(taskfile->low_cylinder, IDE_LCYL_REG); | |
20991 | + OUT_BYTE(taskfile->high_cylinder, IDE_HCYL_REG); | |
20992 | + OUT_BYTE(taskfile->device_head, IDE_SELECT_REG); | |
20993 | + OUT_BYTE(taskfile->command, IDE_COMMAND_REG); | |
20994 | +#endif /* CONFIG_IDE_TASKFILE_IO */ | |
20995 | + | |
20996 | + switch(rq->cmd) { | |
20997 | + case READ: | |
20998 | +#ifndef CONFIG_IDE_TASKFILE_IO | |
20999 | OUT_BYTE(PROMISE_READ, IDE_COMMAND_REG); | |
21000 | +#endif /* CONFIG_IDE_TASKFILE_IO */ | |
21001 | /* | |
21002 | * The card's behaviour is odd at this point. If the data is | |
21003 | * available, DRQ will be true, and no interrupt will be | |
21004 | @@ -520,34 +643,66 @@ | |
21005 | if (IN_BYTE(IDE_SELECT_REG) & 0x01) { | |
21006 | #ifdef DEBUG_READ | |
21007 | printk(KERN_DEBUG "%s: read: waiting for " | |
21008 | - "interrupt\n", drive->name); | |
21009 | -#endif | |
21010 | + "interrupt\n", drive->name); | |
21011 | +#endif /* DEBUG_READ */ | |
21012 | ide_set_handler(drive, &promise_read_intr, WAIT_CMD, NULL); | |
21013 | return ide_started; | |
21014 | } | |
21015 | udelay(1); | |
21016 | } while (time_before(jiffies, timeout)); | |
21017 | ||
21018 | - printk(KERN_ERR "%s: reading: No DRQ and not waiting - Odd!\n", | |
21019 | - drive->name); | |
21020 | + printk(KERN_ERR "%s: reading: No DRQ and not " | |
21021 | + "waiting - Odd!\n", drive->name); | |
21022 | return ide_stopped; | |
21023 | - } else if (rq->cmd == WRITE) { | |
21024 | - ide_startstop_t startstop; | |
21025 | + case WRITE: | |
21026 | +#ifndef CONFIG_IDE_TASKFILE_IO | |
21027 | OUT_BYTE(PROMISE_WRITE, IDE_COMMAND_REG); | |
21028 | - if (ide_wait_stat(&startstop, drive, DATA_READY, drive->bad_wstat, WAIT_DRQ)) { | |
21029 | +#endif /* CONFIG_IDE_TASKFILE_IO */ | |
21030 | + if (ide_wait_stat(&startstop, drive, DATA_READY, | |
21031 | + drive->bad_wstat, WAIT_DRQ)) { | |
21032 | printk(KERN_ERR "%s: no DRQ after issuing " | |
21033 | - "PROMISE_WRITE\n", drive->name); | |
21034 | + "PROMISE_WRITE\n", drive->name); | |
21035 | return startstop; | |
21036 | } | |
21037 | if (!drive->unmask) | |
21038 | - __cli(); /* local CPU only */ | |
21039 | + local_irq_disable(); | |
21040 | HWGROUP(drive)->wrq = *rq; /* scratchpad */ | |
21041 | return promise_write(drive); | |
21042 | - | |
21043 | - } else { | |
21044 | + default: | |
21045 | printk("KERN_WARNING %s: bad command: %d\n", | |
21046 | - drive->name, rq->cmd); | |
21047 | - ide_end_request(0, HWGROUP(drive)); | |
21048 | + drive->name, rq->cmd); | |
21049 | + DRIVER(drive)->end_request(drive, 0); | |
21050 | return ide_stopped; | |
21051 | } | |
21052 | } | |
21053 | + | |
21054 | +#ifdef CONFIG_IDE_TASKFILE_IO | |
21055 | + | |
21056 | +ide_startstop_t promise_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block) | |
21057 | +{ | |
21058 | + struct hd_drive_task_hdr taskfile; | |
21059 | + ide_task_t args; | |
21060 | + | |
21061 | + memset(&taskfile, 0, sizeof(struct hd_drive_task_hdr)); | |
21062 | + | |
21063 | + taskfile.sector_count = rq->nr_sectors; | |
21064 | + taskfile.sector_number = block; | |
21065 | + taskfile.low_cylinder = (block>>=8); | |
21066 | + taskfile.high_cylinder = (block>>=8); | |
21067 | + taskfile.device_head = ((block>>8)&0x0f)|drive->select.all; | |
21068 | + taskfile.command = (rq->cmd==READ)?PROMISE_READ:PROMISE_WRITE; | |
21069 | + | |
21070 | + memcpy(args.tfRegister, &taskfile, sizeof(struct hd_drive_task_hdr)); | |
21071 | + memcpy(args.hobRegister, NULL, sizeof(struct hd_drive_hob_hdr)); | |
21072 | + args.command_type = ide_cmd_type_parser(&args); | |
21073 | + args.prehandler = NULL; | |
21074 | + args.handler = NULL; | |
21075 | + args.posthandler = NULL; | |
21076 | + args.rq = (struct request *) rq; | |
21077 | + rq->special = NULL; | |
21078 | + rq->special = (ide_task_t *)&args; | |
21079 | + | |
21080 | + return do_pdc4030_io(drive, &args); | |
21081 | +} | |
21082 | +#endif /* CONFIG_IDE_TASKFILE_IO */ | |
21083 | + | |
21084 | diff -Nur linux.org/drivers/ide/pdcadma.c linux/drivers/ide/pdcadma.c | |
21085 | --- linux.org/drivers/ide/pdcadma.c Thu Jan 1 01:00:00 1970 | |
21086 | +++ linux/drivers/ide/pdcadma.c Thu Jul 18 14:24:34 2002 | |
21087 | @@ -0,0 +1,106 @@ | |
21088 | +/* | |
21089 | + * linux/drivers/ide/pdcadma.c Version 0.01 June 21, 2001 | |
21090 | + * | |
21091 | + * Copyright (C) 1999-2000 Andre Hedrick <andre@linux-ide.org> | |
21092 | + * May be copied or modified under the terms of the GNU General Public License | |
21093 | + * | |
21094 | + */ | |
21095 | + | |
21096 | +#include <linux/config.h> | |
21097 | +#include <linux/types.h> | |
21098 | +#include <linux/kernel.h> | |
21099 | +#include <linux/delay.h> | |
21100 | +#include <linux/timer.h> | |
21101 | +#include <linux/mm.h> | |
21102 | +#include <linux/ioport.h> | |
21103 | +#include <linux/blkdev.h> | |
21104 | +#include <linux/hdreg.h> | |
21105 | + | |
21106 | +#include <linux/interrupt.h> | |
21107 | +#include <linux/init.h> | |
21108 | +#include <linux/pci.h> | |
21109 | +#include <linux/ide.h> | |
21110 | + | |
21111 | +#include <asm/io.h> | |
21112 | +#include <asm/irq.h> | |
21113 | + | |
21114 | +#include "ide_modes.h" | |
21115 | + | |
21116 | +#undef DISPLAY_PDCADMA_TIMINGS | |
21117 | + | |
21118 | +#if defined(DISPLAY_PDCADMA_TIMINGS) && defined(CONFIG_PROC_FS) | |
21119 | +#include <linux/stat.h> | |
21120 | +#include <linux/proc_fs.h> | |
21121 | + | |
21122 | +static int pdcadma_get_info(char *, char **, off_t, int); | |
21123 | +extern int (*pdcadma_display_info)(char *, char **, off_t, int); /* ide-proc.c */ | |
21124 | +static struct pci_dev *bmide_dev; | |
21125 | + | |
21126 | +static int pdcadma_get_info (char *buffer, char **addr, off_t offset, int count) | |
21127 | +{ | |
21128 | + char *p = buffer; | |
21129 | + u32 bibma = pci_resource_start(bmide_dev, 4); | |
21130 | + | |
21131 | + p += sprintf(p, "\n PDC ADMA %04X Chipset.\n", bmide_dev->device); | |
21132 | + p += sprintf(p, "UDMA\n"); | |
21133 | + p += sprintf(p, "PIO\n"); | |
21134 | + | |
21135 | + return p-buffer; /* => must be less than 4k! */ | |
21136 | +} | |
21137 | +#endif /* defined(DISPLAY_PDCADMA_TIMINGS) && defined(CONFIG_PROC_FS) */ | |
21138 | + | |
21139 | +byte pdcadma_proc = 0; | |
21140 | + | |
21141 | +#ifdef CONFIG_BLK_DEV_IDEDMA | |
21142 | +/* | |
21143 | + * pdcadma_dmaproc() initiates/aborts (U)DMA read/write operations on a drive. | |
21144 | + */ | |
21145 | + | |
21146 | +int pdcadma_dmaproc (ide_dma_action_t func, ide_drive_t *drive) | |
21147 | +{ | |
21148 | + switch (func) { | |
21149 | + case ide_dma_check: | |
21150 | + func = ide_dma_off_quietly; | |
21151 | + default: | |
21152 | + break; | |
21153 | + } | |
21154 | + return ide_dmaproc(func, drive); /* use standard DMA stuff */ | |
21155 | +} | |
21156 | +#endif /* CONFIG_BLK_DEV_IDEDMA */ | |
21157 | + | |
21158 | +unsigned int __init pci_init_pdcadma (struct pci_dev *dev, const char *name) | |
21159 | +{ | |
21160 | +#if defined(DISPLAY_PDCADMA_TIMINGS) && defined(CONFIG_PROC_FS) | |
21161 | + if (!pdcadma_proc) { | |
21162 | + pdcadma_proc = 1; | |
21163 | + bmide_dev = dev; | |
21164 | + pdcadma_display_info = &pdcadma_get_info; | |
21165 | + } | |
21166 | +#endif /* DISPLAY_PDCADMA_TIMINGS && CONFIG_PROC_FS */ | |
21167 | + return 0; | |
21168 | +} | |
21169 | + | |
21170 | +unsigned int __init ata66_pdcadma (ide_hwif_t *hwif) | |
21171 | +{ | |
21172 | + return 1; | |
21173 | +} | |
21174 | + | |
21175 | +void __init ide_init_pdcadma (ide_hwif_t *hwif) | |
21176 | +{ | |
21177 | + hwif->autodma = 0; | |
21178 | + hwif->dma_base = 0; | |
21179 | + | |
21180 | +// hwif->tuneproc = &pdcadma_tune_drive; | |
21181 | +// hwif->speedproc = &pdcadma_tune_chipset; | |
21182 | + | |
21183 | +// if (hwif->dma_base) { | |
21184 | +// hwif->dmaproc = &pdcadma_dmaproc; | |
21185 | +// hwif->autodma = 1; | |
21186 | +// } | |
21187 | +} | |
21188 | + | |
21189 | +void __init ide_dmacapable_pdcadma (ide_hwif_t *hwif, unsigned long dmabase) | |
21190 | +{ | |
21191 | +// ide_setup_dma(hwif, dmabase, 8); | |
21192 | +} | |
21193 | + | |
21194 | diff -Nur linux.org/drivers/ide/piix.c linux/drivers/ide/piix.c | |
21195 | --- linux.org/drivers/ide/piix.c Thu Oct 25 22:53:47 2001 | |
21196 | +++ linux/drivers/ide/piix.c Thu Jul 18 14:24:34 2002 | |
21197 | @@ -77,7 +77,6 @@ | |
21198 | ||
21199 | static int piix_get_info(char *, char **, off_t, int); | |
21200 | extern int (*piix_display_info)(char *, char **, off_t, int); /* ide-proc.c */ | |
21201 | -extern char *ide_media_verbose(ide_drive_t *); | |
21202 | static struct pci_dev *bmide_dev; | |
21203 | ||
21204 | static int piix_get_info (char *buffer, char **addr, off_t offset, int count) | |
21205 | @@ -88,32 +87,36 @@ | |
21206 | u8 c0 = 0, c1 = 0; | |
21207 | u8 reg44 = 0, reg48 = 0, reg4a = 0, reg4b = 0, reg54 = 0, reg55 = 0; | |
21208 | ||
21209 | + p += sprintf(p, "\n "); | |
21210 | switch(bmide_dev->device) { | |
21211 | case PCI_DEVICE_ID_INTEL_82801BA_8: | |
21212 | case PCI_DEVICE_ID_INTEL_82801BA_9: | |
21213 | - case PCI_DEVICE_ID_INTEL_82801CA_10: | |
21214 | - p += sprintf(p, "\n Intel PIIX4 Ultra 100 Chipset.\n"); | |
21215 | + case PCI_DEVICE_ID_INTEL_82801CA_10: | |
21216 | + case PCI_DEVICE_ID_INTEL_82801CA_11: | |
21217 | + case PCI_DEVICE_ID_INTEL_82801DB_11: | |
21218 | + case PCI_DEVICE_ID_INTEL_82801E_11: | |
21219 | + p += sprintf(p, "Intel PIIX4 Ultra 100 Chipset.\n"); | |
21220 | break; | |
21221 | case PCI_DEVICE_ID_INTEL_82372FB_1: | |
21222 | case PCI_DEVICE_ID_INTEL_82801AA_1: | |
21223 | - p += sprintf(p, "\n Intel PIIX4 Ultra 66 Chipset.\n"); | |
21224 | + p += sprintf(p, "Intel PIIX4 Ultra 66 Chipset.\n"); | |
21225 | break; | |
21226 | case PCI_DEVICE_ID_INTEL_82451NX: | |
21227 | case PCI_DEVICE_ID_INTEL_82801AB_1: | |
21228 | case PCI_DEVICE_ID_INTEL_82443MX_1: | |
21229 | case PCI_DEVICE_ID_INTEL_82371AB: | |
21230 | - p += sprintf(p, "\n Intel PIIX4 Ultra 33 Chipset.\n"); | |
21231 | + p += sprintf(p, "Intel PIIX4 Ultra 33 Chipset.\n"); | |
21232 | break; | |
21233 | case PCI_DEVICE_ID_INTEL_82371SB_1: | |
21234 | - p += sprintf(p, "\n Intel PIIX3 Chipset.\n"); | |
21235 | + p += sprintf(p, "Intel PIIX3 Chipset.\n"); | |
21236 | break; | |
21237 | case PCI_DEVICE_ID_INTEL_82371MX: | |
21238 | - p += sprintf(p, "\n Intel MPIIX Chipset.\n"); | |
21239 | + p += sprintf(p, "Intel MPIIX Chipset.\n"); | |
21240 | return p-buffer; /* => must be less than 4k! */ | |
21241 | case PCI_DEVICE_ID_INTEL_82371FB_1: | |
21242 | case PCI_DEVICE_ID_INTEL_82371FB_0: | |
21243 | default: | |
21244 | - p += sprintf(p, "\n Intel PIIX Chipset.\n"); | |
21245 | + p += sprintf(p, "Intel PIIX Chipset.\n"); | |
21246 | break; | |
21247 | } | |
21248 | ||
21249 | @@ -136,22 +139,29 @@ | |
21250 | c0 = inb_p((unsigned short)bibma + 0x02); | |
21251 | c1 = inb_p((unsigned short)bibma + 0x0a); | |
21252 | ||
21253 | - p += sprintf(p, "--------------- Primary Channel ---------------- Secondary Channel -------------\n"); | |
21254 | - p += sprintf(p, " %sabled %sabled\n", | |
21255 | + p += sprintf(p, "--------------- Primary Channel " | |
21256 | + "---------------- Secondary Channel " | |
21257 | + "-------------\n"); | |
21258 | + p += sprintf(p, " %sabled " | |
21259 | + " %sabled\n", | |
21260 | (c0&0x80) ? "dis" : " en", | |
21261 | (c1&0x80) ? "dis" : " en"); | |
21262 | - p += sprintf(p, "--------------- drive0 --------- drive1 -------- drive0 ---------- drive1 ------\n"); | |
21263 | - p += sprintf(p, "DMA enabled: %s %s %s %s\n", | |
21264 | + p += sprintf(p, "--------------- drive0 --------- drive1 " | |
21265 | + "-------- drive0 ---------- drive1 ------\n"); | |
21266 | + p += sprintf(p, "DMA enabled: %s %s " | |
21267 | + " %s %s\n", | |
21268 | (c0&0x20) ? "yes" : "no ", | |
21269 | (c0&0x40) ? "yes" : "no ", | |
21270 | (c1&0x20) ? "yes" : "no ", | |
21271 | (c1&0x40) ? "yes" : "no " ); | |
21272 | - p += sprintf(p, "UDMA enabled: %s %s %s %s\n", | |
21273 | + p += sprintf(p, "UDMA enabled: %s %s " | |
21274 | + " %s %s\n", | |
21275 | (reg48&0x01) ? "yes" : "no ", | |
21276 | (reg48&0x02) ? "yes" : "no ", | |
21277 | (reg48&0x04) ? "yes" : "no ", | |
21278 | (reg48&0x08) ? "yes" : "no " ); | |
21279 | - p += sprintf(p, "UDMA enabled: %s %s %s %s\n", | |
21280 | + p += sprintf(p, "UDMA enabled: %s %s " | |
21281 | + " %s %s\n", | |
21282 | ((reg54&0x11) && (reg55&0x10) && (reg4a&0x01)) ? "5" : | |
21283 | ((reg54&0x11) && (reg4a&0x02)) ? "4" : | |
21284 | ((reg54&0x11) && (reg4a&0x01)) ? "3" : | |
21285 | @@ -195,12 +205,65 @@ | |
21286 | ||
21287 | byte piix_proc = 0; | |
21288 | ||
21289 | -extern char *ide_xfer_verbose (byte xfer_rate); | |
21290 | ||
21291 | -#if defined(CONFIG_BLK_DEV_IDEDMA) && defined(CONFIG_PIIX_TUNING) | |
21292 | -/* | |
21293 | - * | |
21294 | - */ | |
21295 | +static byte piix_ratemask (ide_drive_t *drive) | |
21296 | +{ | |
21297 | + struct pci_dev *dev = HWIF(drive)->pci_dev; | |
21298 | + byte mode = 0x00; | |
21299 | + | |
21300 | + switch(dev->device) { | |
21301 | + case PCI_DEVICE_ID_INTEL_82801BA_8: | |
21302 | + case PCI_DEVICE_ID_INTEL_82801BA_9: | |
21303 | + case PCI_DEVICE_ID_INTEL_82801CA_10: | |
21304 | + case PCI_DEVICE_ID_INTEL_82801CA_11: | |
21305 | + case PCI_DEVICE_ID_INTEL_82801E_11: | |
21306 | + case PCI_DEVICE_ID_INTEL_82801DB_11: | |
21307 | + mode |= 0x03; | |
21308 | + break; | |
21309 | + case PCI_DEVICE_ID_INTEL_82801AA_1: | |
21310 | + case PCI_DEVICE_ID_INTEL_82372FB_1: | |
21311 | + mode |= 0x02; | |
21312 | + break; | |
21313 | + case PCI_DEVICE_ID_INTEL_82371AB: | |
21314 | + case PCI_DEVICE_ID_INTEL_82443MX_1: | |
21315 | + case PCI_DEVICE_ID_INTEL_82451NX: | |
21316 | + case PCI_DEVICE_ID_INTEL_82801AB_1: | |
21317 | + mode |= 0x01; | |
21318 | + case PCI_DEVICE_ID_INTEL_82371SB_1: | |
21319 | + case PCI_DEVICE_ID_INTEL_82371FB_1: | |
21320 | + case PCI_DEVICE_ID_INTEL_82371FB_0: | |
21321 | + case PCI_DEVICE_ID_INTEL_82371MX: | |
21322 | + default: | |
21323 | + return (mode &= ~0xF8); | |
21324 | + } | |
21325 | + if (!eighty_ninty_three(drive)) { | |
21326 | + mode &= ~0xFE; | |
21327 | + mode |= 0x01; | |
21328 | + } | |
21329 | + return (mode &= ~0xF8); | |
21330 | +} | |
21331 | + | |
21332 | +static byte piix_ratefilter (ide_drive_t *drive, byte speed) | |
21333 | +{ | |
21334 | +#ifdef CONFIG_BLK_DEV_IDEDMA | |
21335 | + byte mode = piix_ratemask(drive); | |
21336 | + | |
21337 | + switch(mode) { | |
21338 | + case 0x04: while (speed > XFER_UDMA_6) speed--; break; | |
21339 | + case 0x03: while (speed > XFER_UDMA_5) speed--; break; | |
21340 | + case 0x02: while (speed > XFER_UDMA_4) speed--; break; | |
21341 | + case 0x01: while (speed > XFER_UDMA_2) speed--; break; | |
21342 | + case 0x00: | |
21343 | + default: while (speed > XFER_MW_DMA_2) speed--; break; | |
21344 | + break; | |
21345 | + } | |
21346 | +#else | |
21347 | + while (speed > XFER_PIO_4) speed--; | |
21348 | +#endif /* CONFIG_BLK_DEV_IDEDMA */ | |
21349 | +// printk("%s: mode == %02x speed == %02x\n", drive->name, mode, speed); | |
21350 | + return speed; | |
21351 | +} | |
21352 | + | |
21353 | static byte piix_dma_2_pio (byte xfer_rate) { | |
21354 | switch(xfer_rate) { | |
21355 | case XFER_UDMA_5: | |
21356 | @@ -228,7 +291,6 @@ | |
21357 | return 0; | |
21358 | } | |
21359 | } | |
21360 | -#endif /* defined(CONFIG_BLK_DEV_IDEDMA) && (CONFIG_PIIX_TUNING) */ | |
21361 | ||
21362 | /* | |
21363 | * Based on settings done by AMI BIOS | |
21364 | @@ -236,12 +298,14 @@ | |
21365 | */ | |
21366 | static void piix_tune_drive (ide_drive_t *drive, byte pio) | |
21367 | { | |
21368 | + ide_hwif_t *hwif = HWIF(drive); | |
21369 | + struct pci_dev *dev = hwif->pci_dev; | |
21370 | + int is_slave = (&hwif->drives[1] == drive); | |
21371 | + int master_port = hwif->channel ? 0x42 : 0x40; | |
21372 | + int slave_port = 0x44; | |
21373 | unsigned long flags; | |
21374 | u16 master_data; | |
21375 | byte slave_data; | |
21376 | - int is_slave = (&HWIF(drive)->drives[1] == drive); | |
21377 | - int master_port = HWIF(drive)->index ? 0x42 : 0x40; | |
21378 | - int slave_port = 0x44; | |
21379 | /* ISP RTC */ | |
21380 | byte timings[][2] = { { 0, 0 }, | |
21381 | { 0, 0 }, | |
21382 | @@ -250,44 +314,40 @@ | |
21383 | { 2, 3 }, }; | |
21384 | ||
21385 | pio = ide_get_best_pio_mode(drive, pio, 5, NULL); | |
21386 | - pci_read_config_word(HWIF(drive)->pci_dev, master_port, &master_data); | |
21387 | + spin_lock_irqsave(&io_request_lock, flags); | |
21388 | + pci_read_config_word(dev, master_port, &master_data); | |
21389 | if (is_slave) { | |
21390 | master_data = master_data | 0x4000; | |
21391 | if (pio > 1) | |
21392 | /* enable PPE, IE and TIME */ | |
21393 | master_data = master_data | 0x0070; | |
21394 | - pci_read_config_byte(HWIF(drive)->pci_dev, slave_port, &slave_data); | |
21395 | - slave_data = slave_data & (HWIF(drive)->index ? 0x0f : 0xf0); | |
21396 | - slave_data = slave_data | ((timings[pio][0] << 2) | (timings[pio][1] | |
21397 | - << (HWIF(drive)->index ? 4 : 0))); | |
21398 | + pci_read_config_byte(dev, slave_port, &slave_data); | |
21399 | + slave_data = slave_data & (hwif->channel ? 0x0f : 0xf0); | |
21400 | + slave_data = slave_data | (((timings[pio][0] << 2) | timings[pio][1]) << (hwif->channel ? 4 : 0)); | |
21401 | } else { | |
21402 | master_data = master_data & 0xccf8; | |
21403 | if (pio > 1) | |
21404 | /* enable PPE, IE and TIME */ | |
21405 | master_data = master_data | 0x0007; | |
21406 | - master_data = master_data | (timings[pio][0] << 12) | | |
21407 | - (timings[pio][1] << 8); | |
21408 | + master_data = master_data | (timings[pio][0] << 12) | (timings[pio][1] << 8); | |
21409 | } | |
21410 | - save_flags(flags); | |
21411 | - cli(); | |
21412 | - pci_write_config_word(HWIF(drive)->pci_dev, master_port, master_data); | |
21413 | + pci_write_config_word(dev, master_port, master_data); | |
21414 | if (is_slave) | |
21415 | - pci_write_config_byte(HWIF(drive)->pci_dev, slave_port, slave_data); | |
21416 | - restore_flags(flags); | |
21417 | + pci_write_config_byte(dev, slave_port, slave_data); | |
21418 | + spin_unlock_irqrestore(&io_request_lock, flags); | |
21419 | } | |
21420 | ||
21421 | -#if defined(CONFIG_BLK_DEV_IDEDMA) && defined(CONFIG_PIIX_TUNING) | |
21422 | -static int piix_tune_chipset (ide_drive_t *drive, byte speed) | |
21423 | +static int piix_tune_chipset (ide_drive_t *drive, byte xferspeed) | |
21424 | { | |
21425 | ide_hwif_t *hwif = HWIF(drive); | |
21426 | struct pci_dev *dev = hwif->pci_dev; | |
21427 | byte maslave = hwif->channel ? 0x42 : 0x40; | |
21428 | + byte speed = piix_ratefilter(drive, xferspeed); | |
21429 | int a_speed = 3 << (drive->dn * 4); | |
21430 | int u_flag = 1 << drive->dn; | |
21431 | int v_flag = 0x01 << drive->dn; | |
21432 | int w_flag = 0x10 << drive->dn; | |
21433 | int u_speed = 0; | |
21434 | - int err = 0; | |
21435 | int sitre; | |
21436 | short reg4042, reg44, reg48, reg4a, reg54; | |
21437 | byte reg55; | |
21438 | @@ -301,6 +361,7 @@ | |
21439 | pci_read_config_byte(dev, 0x55, ®55); | |
21440 | ||
21441 | switch(speed) { | |
21442 | +#ifdef CONFIG_BLK_DEV_IDEDMA | |
21443 | case XFER_UDMA_4: | |
21444 | case XFER_UDMA_2: u_speed = 2 << (drive->dn * 4); break; | |
21445 | case XFER_UDMA_5: | |
21446 | @@ -310,6 +371,11 @@ | |
21447 | case XFER_MW_DMA_2: | |
21448 | case XFER_MW_DMA_1: | |
21449 | case XFER_SW_DMA_2: break; | |
21450 | +#endif /* CONFIG_BLK_DEV_IDEDMA */ | |
21451 | + case XFER_PIO_4: | |
21452 | + case XFER_PIO_3: | |
21453 | + case XFER_PIO_2: | |
21454 | + case XFER_PIO_0: break; | |
21455 | default: return -1; | |
21456 | } | |
21457 | ||
21458 | @@ -332,8 +398,7 @@ | |
21459 | } else { | |
21460 | pci_write_config_word(dev, 0x54, reg54 & ~v_flag); | |
21461 | } | |
21462 | - } | |
21463 | - if (speed < XFER_UDMA_0) { | |
21464 | + } else { | |
21465 | if (reg48 & u_flag) | |
21466 | pci_write_config_word(dev, 0x48, reg48 & ~u_flag); | |
21467 | if (reg4a & a_speed) | |
21468 | @@ -345,61 +410,51 @@ | |
21469 | } | |
21470 | ||
21471 | piix_tune_drive(drive, piix_dma_2_pio(speed)); | |
21472 | - | |
21473 | -#if PIIX_DEBUG_DRIVE_INFO | |
21474 | - printk("%s: %s drive%d\n", drive->name, ide_xfer_verbose(speed), drive->dn); | |
21475 | -#endif /* PIIX_DEBUG_DRIVE_INFO */ | |
21476 | - if (!drive->init_speed) | |
21477 | - drive->init_speed = speed; | |
21478 | - err = ide_config_drive_speed(drive, speed); | |
21479 | - drive->current_speed = speed; | |
21480 | - return err; | |
21481 | + return (ide_config_drive_speed(drive, speed)); | |
21482 | } | |
21483 | ||
21484 | +#ifdef CONFIG_BLK_DEV_IDEDMA | |
21485 | static int piix_config_drive_for_dma (ide_drive_t *drive) | |
21486 | { | |
21487 | struct hd_driveid *id = drive->id; | |
21488 | - ide_hwif_t *hwif = HWIF(drive); | |
21489 | - struct pci_dev *dev = hwif->pci_dev; | |
21490 | - byte speed; | |
21491 | + byte mode = piix_ratemask(drive); | |
21492 | + byte speed, tspeed, dma = 1; | |
21493 | ||
21494 | - byte udma_66 = eighty_ninty_three(drive); | |
21495 | - int ultra100 = ((dev->device == PCI_DEVICE_ID_INTEL_82801BA_8) || | |
21496 | - (dev->device == PCI_DEVICE_ID_INTEL_82801BA_9) || | |
21497 | - (dev->device == PCI_DEVICE_ID_INTEL_82801CA_10)) ? 1 : 0; | |
21498 | - int ultra66 = ((ultra100) || | |
21499 | - (dev->device == PCI_DEVICE_ID_INTEL_82801AA_1) || | |
21500 | - (dev->device == PCI_DEVICE_ID_INTEL_82372FB_1)) ? 1 : 0; | |
21501 | - int ultra = ((ultra66) || | |
21502 | - (dev->device == PCI_DEVICE_ID_INTEL_82371AB) || | |
21503 | - (dev->device == PCI_DEVICE_ID_INTEL_82443MX_1) || | |
21504 | - (dev->device == PCI_DEVICE_ID_INTEL_82451NX) || | |
21505 | - (dev->device == PCI_DEVICE_ID_INTEL_82801AB_1)) ? 1 : 0; | |
21506 | - | |
21507 | - if ((id->dma_ultra & 0x0020) && (udma_66) && (ultra100)) { | |
21508 | - speed = XFER_UDMA_5; | |
21509 | - } else if ((id->dma_ultra & 0x0010) && (ultra)) { | |
21510 | - speed = ((udma_66) && (ultra66)) ? XFER_UDMA_4 : XFER_UDMA_2; | |
21511 | - } else if ((id->dma_ultra & 0x0008) && (ultra)) { | |
21512 | - speed = ((udma_66) && (ultra66)) ? XFER_UDMA_3 : XFER_UDMA_1; | |
21513 | - } else if ((id->dma_ultra & 0x0004) && (ultra)) { | |
21514 | - speed = XFER_UDMA_2; | |
21515 | - } else if ((id->dma_ultra & 0x0002) && (ultra)) { | |
21516 | - speed = XFER_UDMA_1; | |
21517 | - } else if ((id->dma_ultra & 0x0001) && (ultra)) { | |
21518 | - speed = XFER_UDMA_0; | |
21519 | - } else if (id->dma_mword & 0x0004) { | |
21520 | - speed = XFER_MW_DMA_2; | |
21521 | - } else if (id->dma_mword & 0x0002) { | |
21522 | - speed = XFER_MW_DMA_1; | |
21523 | - } else if (id->dma_1word & 0x0004) { | |
21524 | - speed = XFER_SW_DMA_2; | |
21525 | - } else { | |
21526 | - speed = XFER_PIO_0 + ide_get_best_pio_mode(drive, 255, 5, NULL); | |
21527 | + switch(mode) { | |
21528 | + case 0x03: | |
21529 | + if (id->dma_ultra & 0x0040) | |
21530 | + { speed = XFER_UDMA_5; break; } | |
21531 | + if (id->dma_ultra & 0x0020) | |
21532 | + { speed = XFER_UDMA_5; break; } | |
21533 | + case 0x02: | |
21534 | + if (id->dma_ultra & 0x0010) | |
21535 | + { speed = XFER_UDMA_4; break; } | |
21536 | + if (id->dma_ultra & 0x0008) | |
21537 | + { speed = XFER_UDMA_3; break; } | |
21538 | + case 0x01: | |
21539 | + if (id->dma_ultra & 0x0004) | |
21540 | + { speed = XFER_UDMA_2; break; } | |
21541 | + if (id->dma_ultra & 0x0002) | |
21542 | + { speed = XFER_UDMA_1; break; } | |
21543 | + if (id->dma_ultra & 0x0001) | |
21544 | + { speed = XFER_UDMA_0; break; } | |
21545 | + case 0x00: | |
21546 | + if (id->dma_mword & 0x0004) | |
21547 | + { speed = XFER_MW_DMA_2; break; } | |
21548 | + if (id->dma_mword & 0x0002) | |
21549 | + { speed = XFER_MW_DMA_1; break; } | |
21550 | + if (id->dma_1word & 0x0004) | |
21551 | + { speed = XFER_SW_DMA_2; break; } | |
21552 | + default: | |
21553 | + tspeed = ide_get_best_pio_mode(drive, 255, 5, NULL); | |
21554 | + speed = piix_dma_2_pio(XFER_PIO_0 + tspeed); | |
21555 | + dma = 0; | |
21556 | + break; | |
21557 | } | |
21558 | ||
21559 | (void) piix_tune_chipset(drive, speed); | |
21560 | ||
21561 | +// return ((int) (dma) ? ide_dma_on : ide_dma_off_quietly); | |
21562 | return ((int) ((id->dma_ultra >> 11) & 7) ? ide_dma_on : | |
21563 | ((id->dma_ultra >> 8) & 7) ? ide_dma_on : | |
21564 | ((id->dma_mword >> 8) & 7) ? ide_dma_on : | |
21565 | @@ -407,16 +462,13 @@ | |
21566 | ide_dma_off_quietly); | |
21567 | } | |
21568 | ||
21569 | -static void config_chipset_for_pio (ide_drive_t *drive) | |
21570 | -{ | |
21571 | - piix_tune_drive(drive, ide_get_best_pio_mode(drive, 255, 5, NULL)); | |
21572 | -} | |
21573 | - | |
21574 | static int config_drive_xfer_rate (ide_drive_t *drive) | |
21575 | { | |
21576 | struct hd_driveid *id = drive->id; | |
21577 | ide_dma_action_t dma_func = ide_dma_on; | |
21578 | ||
21579 | + drive->init_speed = 0; | |
21580 | + | |
21581 | if (id && (id->capability & 1) && HWIF(drive)->autodma) { | |
21582 | /* Consult the list of known "bad" drives */ | |
21583 | if (ide_dmaproc(ide_dma_bad_drive, drive)) { | |
21584 | @@ -425,7 +477,7 @@ | |
21585 | } | |
21586 | dma_func = ide_dma_off_quietly; | |
21587 | if (id->field_valid & 4) { | |
21588 | - if (id->dma_ultra & 0x002F) { | |
21589 | + if (id->dma_ultra & 0x007F) { | |
21590 | /* Force if Capable UltraDMA */ | |
21591 | dma_func = piix_config_drive_for_dma(drive); | |
21592 | if ((id->field_valid & 2) && | |
21593 | @@ -456,7 +508,7 @@ | |
21594 | fast_ata_pio: | |
21595 | dma_func = ide_dma_off_quietly; | |
21596 | no_dma_set: | |
21597 | - config_chipset_for_pio(drive); | |
21598 | + piix_tune_drive(drive, 255); | |
21599 | } | |
21600 | return HWIF(drive)->dmaproc(dma_func, drive); | |
21601 | } | |
21602 | @@ -472,10 +524,28 @@ | |
21603 | /* Other cases are done by generic IDE-DMA code. */ | |
21604 | return ide_dmaproc(func, drive); | |
21605 | } | |
21606 | -#endif /* defined(CONFIG_BLK_DEV_IDEDMA) && (CONFIG_PIIX_TUNING) */ | |
21607 | +#endif /* CONFIG_BLK_DEV_IDEDMA */ | |
21608 | ||
21609 | unsigned int __init pci_init_piix (struct pci_dev *dev, const char *name) | |
21610 | { | |
21611 | + switch(dev->device) { | |
21612 | + case PCI_DEVICE_ID_INTEL_82801AA_1: | |
21613 | + case PCI_DEVICE_ID_INTEL_82801AB_1: | |
21614 | + case PCI_DEVICE_ID_INTEL_82801BA_8: | |
21615 | + case PCI_DEVICE_ID_INTEL_82801BA_9: | |
21616 | + case PCI_DEVICE_ID_INTEL_82801CA_10: | |
21617 | + case PCI_DEVICE_ID_INTEL_82801CA_11: | |
21618 | + case PCI_DEVICE_ID_INTEL_82801E_11: | |
21619 | + case PCI_DEVICE_ID_INTEL_82801DB_11: | |
21620 | + { | |
21621 | + unsigned int extra = 0; | |
21622 | + pci_read_config_dword(dev, 0x54, &extra); | |
21623 | + pci_write_config_dword(dev, 0x54, extra|0x400); | |
21624 | + } | |
21625 | + default: | |
21626 | + break; | |
21627 | + } | |
21628 | + | |
21629 | #if defined(DISPLAY_PIIX_TIMINGS) && defined(CONFIG_PROC_FS) | |
21630 | if (!piix_proc) { | |
21631 | piix_proc = 1; | |
21632 | @@ -516,21 +586,32 @@ | |
21633 | return; | |
21634 | } | |
21635 | ||
21636 | + hwif->autodma = 0; | |
21637 | hwif->tuneproc = &piix_tune_drive; | |
21638 | + hwif->speedproc = &piix_tune_chipset; | |
21639 | hwif->drives[0].autotune = 1; | |
21640 | hwif->drives[1].autotune = 1; | |
21641 | ||
21642 | if (!hwif->dma_base) | |
21643 | return; | |
21644 | ||
21645 | -#ifndef CONFIG_BLK_DEV_IDEDMA | |
21646 | - hwif->autodma = 0; | |
21647 | -#else /* CONFIG_BLK_DEV_IDEDMA */ | |
21648 | -#ifdef CONFIG_PIIX_TUNING | |
21649 | +#ifdef CONFIG_BLK_DEV_IDEDMA | |
21650 | + hwif->dmaproc = &piix_dmaproc; | |
21651 | +#ifdef CONFIG_IDEDMA_AUTO | |
21652 | if (!noautodma) | |
21653 | hwif->autodma = 1; | |
21654 | - hwif->dmaproc = &piix_dmaproc; | |
21655 | - hwif->speedproc = &piix_tune_chipset; | |
21656 | -#endif /* CONFIG_PIIX_TUNING */ | |
21657 | +#endif /* CONFIG_IDEDMA_AUTO */ | |
21658 | #endif /* !CONFIG_BLK_DEV_IDEDMA */ | |
21659 | } | |
21660 | + | |
21661 | +extern void ide_setup_pci_device (struct pci_dev *dev, ide_pci_device_t *d); | |
21662 | + | |
21663 | +void __init fixup_device_piix (struct pci_dev *dev, ide_pci_device_t *d) | |
21664 | +{ | |
21665 | + if (dev->resource[0].start != 0x01F1) | |
21666 | + ide_register_xp_fix(dev); | |
21667 | + | |
21668 | + printk("%s: IDE controller on PCI bus %02x dev %02x\n", | |
21669 | + d->name, dev->bus->number, dev->devfn); | |
21670 | + ide_setup_pci_device(dev, d); | |
21671 | +} | |
21672 | diff -Nur linux.org/drivers/ide/qd65xx.c linux/drivers/ide/qd65xx.c | |
21673 | --- linux.org/drivers/ide/qd65xx.c Fri Sep 7 18:28:38 2001 | |
21674 | +++ linux/drivers/ide/qd65xx.c Thu Jul 18 14:24:34 2002 | |
21675 | @@ -1,14 +1,15 @@ | |
21676 | /* | |
21677 | - * linux/drivers/ide/qd65xx.c Version 0.06 Aug 3, 2000 | |
21678 | + * linux/drivers/ide/qd65xx.c Version 0.07 Sep 30, 2001 | |
21679 | * | |
21680 | - * Copyright (C) 1996-2000 Linus Torvalds & author (see below) | |
21681 | + * Copyright (C) 1996-2001 Linus Torvalds & author (see below) | |
21682 | */ | |
21683 | ||
21684 | /* | |
21685 | * Version 0.03 Cleaned auto-tune, added probe | |
21686 | * Version 0.04 Added second channel tuning | |
21687 | * Version 0.05 Enhanced tuning ; added qd6500 support | |
21688 | - * Version 0.06 added dos driver's list | |
21689 | + * Version 0.06 Added dos driver's list | |
21690 | + * Version 0.07 Second channel bug fix | |
21691 | * | |
21692 | * QDI QD6500/QD6580 EIDE controller fast support | |
21693 | * | |
21694 | @@ -67,6 +68,7 @@ | |
21695 | * qd6500: 1100 | |
21696 | * qd6580: either 1010 or 0101 | |
21697 | * | |
21698 | + * | |
21699 | * base+0x02: Timer2 (qd6580 only) | |
21700 | * | |
21701 | * | |
21702 | @@ -92,10 +94,9 @@ | |
21703 | { | |
21704 | unsigned long flags; | |
21705 | ||
21706 | - save_flags(flags); /* all CPUs */ | |
21707 | - cli(); /* all CPUs */ | |
21708 | - outb(content,reg); | |
21709 | - restore_flags(flags); /* all CPUs */ | |
21710 | + spin_lock_irqsave(&io_request_lock, flags); | |
21711 | + OUT_BYTE(content,reg); | |
21712 | + spin_unlock_irqrestore(&io_request_lock, flags); | |
21713 | } | |
21714 | ||
21715 | byte __init qd_read_reg (byte reg) | |
21716 | @@ -103,10 +104,9 @@ | |
21717 | unsigned long flags; | |
21718 | byte read; | |
21719 | ||
21720 | - save_flags(flags); /* all CPUs */ | |
21721 | - cli(); /* all CPUs */ | |
21722 | - read = inb(reg); | |
21723 | - restore_flags(flags); /* all CPUs */ | |
21724 | + spin_lock_irqsave(&io_request_lock, flags); | |
21725 | + read = IN_BYTE(reg); | |
21726 | + spin_unlock_irqrestore(&io_request_lock, flags); | |
21727 | return read; | |
21728 | } | |
21729 | ||
21730 | @@ -137,12 +137,12 @@ | |
21731 | { | |
21732 | byte active_cycle,recovery_cycle; | |
21733 | ||
21734 | - if (system_bus_clock()<=33) { | |
21735 | - active_cycle = 9 - IDE_IN(active_time * system_bus_clock() / 1000 + 1, 2, 9); | |
21736 | - recovery_cycle = 15 - IDE_IN(recovery_time * system_bus_clock() / 1000 + 1, 0, 15); | |
21737 | + if (ide_system_bus_speed()<=33) { | |
21738 | + active_cycle = 9 - IDE_IN(active_time * ide_system_bus_speed() / 1000 + 1, 2, 9); | |
21739 | + recovery_cycle = 15 - IDE_IN(recovery_time * ide_system_bus_speed() / 1000 + 1, 0, 15); | |
21740 | } else { | |
21741 | - active_cycle = 8 - IDE_IN(active_time * system_bus_clock() / 1000 + 1, 1, 8); | |
21742 | - recovery_cycle = 18 - IDE_IN(recovery_time * system_bus_clock() / 1000 + 1, 3, 18); | |
21743 | + active_cycle = 8 - IDE_IN(active_time * ide_system_bus_speed() / 1000 + 1, 1, 8); | |
21744 | + recovery_cycle = 18 - IDE_IN(recovery_time * ide_system_bus_speed() / 1000 + 1, 3, 18); | |
21745 | } | |
21746 | ||
21747 | return((recovery_cycle<<4) | 0x08 | active_cycle); | |
21748 | @@ -156,8 +156,8 @@ | |
21749 | ||
21750 | static byte qd6580_compute_timing (int active_time, int recovery_time) | |
21751 | { | |
21752 | - byte active_cycle = 17-IDE_IN(active_time * system_bus_clock() / 1000 + 1, 2, 17); | |
21753 | - byte recovery_cycle = 15-IDE_IN(recovery_time * system_bus_clock() / 1000 + 1, 2, 15); | |
21754 | + byte active_cycle = 17-IDE_IN(active_time * ide_system_bus_speed() / 1000 + 1, 2, 17); | |
21755 | + byte recovery_cycle = 15-IDE_IN(recovery_time * ide_system_bus_speed() / 1000 + 1, 2, 15); | |
21756 | ||
21757 | return((recovery_cycle<<4) | active_cycle); | |
21758 | } | |
21759 | @@ -311,13 +311,12 @@ | |
21760 | byte readreg; | |
21761 | unsigned long flags; | |
21762 | ||
21763 | - save_flags(flags); /* all CPUs */ | |
21764 | - cli(); /* all CPUs */ | |
21765 | + spin_lock_irqsave(&io_request_lock, flags); | |
21766 | savereg = inb_p(port); | |
21767 | outb_p(QD_TESTVAL,port); /* safe value */ | |
21768 | readreg = inb_p(port); | |
21769 | - outb(savereg,port); | |
21770 | - restore_flags(flags); /* all CPUs */ | |
21771 | + OUT_BYTE(savereg,port); | |
21772 | + spin_unlock_irqrestore(&io_request_lock, flags); | |
21773 | ||
21774 | if (savereg == QD_TESTVAL) { | |
21775 | printk(KERN_ERR "Outch ! the probe for qd65xx isn't reliable !\n"); | |
21776 | @@ -427,7 +426,8 @@ | |
21777 | ide_hwifs[i].tuneproc = &qd6580_tune_drive; | |
21778 | ||
21779 | for (j=0;j<2;j++) { | |
21780 | - ide_hwifs[i].drives[j].drive_data = QD6580_DEF_DATA; | |
21781 | + ide_hwifs[i].drives[j].drive_data = | |
21782 | + i?QD6580_DEF_DATA2:QD6580_DEF_DATA; | |
21783 | ide_hwifs[i].drives[j].io_32bit = 1; | |
21784 | } | |
21785 | } | |
21786 | diff -Nur linux.org/drivers/ide/qd65xx.h linux/drivers/ide/qd65xx.h | |
21787 | --- linux.org/drivers/ide/qd65xx.h Fri Sep 7 18:28:38 2001 | |
21788 | +++ linux/drivers/ide/qd65xx.h Thu Jul 18 14:23:01 2002 | |
21789 | @@ -29,7 +29,7 @@ | |
21790 | ||
21791 | #define QD_CONTR_SEC_DISABLED 0x01 | |
21792 | ||
21793 | -#define QD_ID3 (config & QD_CONFIG_ID3) | |
21794 | +#define QD_ID3 ((config & QD_CONFIG_ID3)!=0) | |
21795 | ||
21796 | #define QD_CONFIG(hwif) ((hwif)->config_data & 0x00ff) | |
21797 | #define QD_CONTROL(hwif) (((hwif)->config_data & 0xff00) >> 8) | |
21798 | @@ -39,6 +39,7 @@ | |
21799 | ||
21800 | #define QD6500_DEF_DATA ((QD_TIM1_PORT<<8) | (QD_ID3 ? 0x0c : 0x08)) | |
21801 | #define QD6580_DEF_DATA ((QD_TIM1_PORT<<8) | (QD_ID3 ? 0x0a : 0x00)) | |
21802 | +#define QD6580_DEF_DATA2 ((QD_TIM2_PORT<<8) | (QD_ID3 ? 0x0a : 0x00)) | |
21803 | #define QD_DEF_CONTR (0x40 | ((control & 0x02) ? 0x9f : 0x1f)) | |
21804 | ||
21805 | #define QD_TESTVAL 0x19 /* safe value */ | |
21806 | diff -Nur linux.org/drivers/ide/rz1000.c linux/drivers/ide/rz1000.c | |
21807 | --- linux.org/drivers/ide/rz1000.c Wed May 2 01:05:00 2001 | |
21808 | +++ linux/drivers/ide/rz1000.c Thu Jul 18 14:24:34 2002 | |
21809 | @@ -40,15 +40,16 @@ | |
21810 | struct pci_dev *dev = hwif->pci_dev; | |
21811 | ||
21812 | hwif->chipset = ide_rz1000; | |
21813 | - if (!pci_read_config_word (dev, 0x40, ®) | |
21814 | - && !pci_write_config_word(dev, 0x40, reg & 0xdfff)) | |
21815 | - { | |
21816 | - printk("%s: disabled chipset read-ahead (buggy RZ1000/RZ1001)\n", hwif->name); | |
21817 | + if (!pci_read_config_word (dev, 0x40, ®) && | |
21818 | + !pci_write_config_word(dev, 0x40, reg & 0xdfff)) { | |
21819 | + printk("%s: disabled chipset read-ahead " | |
21820 | + "(buggy RZ1000/RZ1001)\n", hwif->name); | |
21821 | } else { | |
21822 | hwif->serialized = 1; | |
21823 | hwif->drives[0].no_unmask = 1; | |
21824 | hwif->drives[1].no_unmask = 1; | |
21825 | - printk("%s: serialized, disabled unmasking (buggy RZ1000/RZ1001)\n", hwif->name); | |
21826 | + printk("%s: serialized, disabled unmasking " | |
21827 | + "(buggy RZ1000/RZ1001)\n", hwif->name); | |
21828 | } | |
21829 | } | |
21830 | ||
21831 | @@ -58,27 +59,29 @@ | |
21832 | { | |
21833 | unsigned short reg, h; | |
21834 | ||
21835 | - if (!pci_read_config_word (dev, PCI_COMMAND, ®) && !(reg & PCI_COMMAND_IO)) { | |
21836 | + if (!pci_read_config_word (dev, PCI_COMMAND, ®) && | |
21837 | + !(reg & PCI_COMMAND_IO)) { | |
21838 | printk("%s: buggy IDE controller disabled (BIOS)\n", name); | |
21839 | return; | |
21840 | } | |
21841 | - if (!pci_read_config_word (dev, 0x40, ®) | |
21842 | - && !pci_write_config_word(dev, 0x40, reg & 0xdfff)) | |
21843 | - { | |
21844 | + if (!pci_read_config_word (dev, 0x40, ®) && | |
21845 | + !pci_write_config_word(dev, 0x40, reg & 0xdfff)) { | |
21846 | printk("IDE: disabled chipset read-ahead (buggy %s)\n", name); | |
21847 | } else { | |
21848 | for (h = 0; h < MAX_HWIFS; ++h) { | |
21849 | ide_hwif_t *hwif = &ide_hwifs[h]; | |
21850 | - if ((hwif->io_ports[IDE_DATA_OFFSET] == 0x1f0 || hwif->io_ports[IDE_DATA_OFFSET] == 0x170) | |
21851 | - && (hwif->chipset == ide_unknown || hwif->chipset == ide_generic)) | |
21852 | - { | |
21853 | + if ((hwif->io_ports[IDE_DATA_OFFSET] == 0x1f0 || | |
21854 | + hwif->io_ports[IDE_DATA_OFFSET] == 0x170) && | |
21855 | + (hwif->chipset == ide_unknown || | |
21856 | + hwif->chipset == ide_generic)) { | |
21857 | hwif->chipset = ide_rz1000; | |
21858 | hwif->serialized = 1; | |
21859 | hwif->drives[0].no_unmask = 1; | |
21860 | hwif->drives[1].no_unmask = 1; | |
21861 | if (hwif->io_ports[IDE_DATA_OFFSET] == 0x170) | |
21862 | hwif->channel = 1; | |
21863 | - printk("%s: serialized, disabled unmasking (buggy %s)\n", hwif->name, name); | |
21864 | + printk("%s: serialized, disabled unmasking " | |
21865 | + "(buggy %s)\n", hwif->name, name); | |
21866 | } | |
21867 | } | |
21868 | } | |
21869 | diff -Nur linux.org/drivers/ide/serverworks.c linux/drivers/ide/serverworks.c | |
21870 | --- linux.org/drivers/ide/serverworks.c Sun Sep 9 19:43:02 2001 | |
21871 | +++ linux/drivers/ide/serverworks.c Thu Jul 18 14:24:34 2002 | |
21872 | @@ -1,71 +1,25 @@ | |
21873 | /* | |
21874 | - * linux/drivers/ide/serverworks.c Version 0.2 17 Oct 2000 | |
21875 | + * linux/drivers/ide/serverworks.c Version 0.6 05 April 2002 | |
21876 | * | |
21877 | - * Copyright (C) 2000 Cobalt Networks, Inc. <asun@cobalt.com> | |
21878 | - * May be copied or modified under the terms of the GNU General Public License | |
21879 | + * Copyright (C) 1998-2000 Michel Aubry | |
21880 | + * Copyright (C) 1998-2000 Andrzej Krzysztofowicz | |
21881 | + * Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org> | |
21882 | + * Portions copyright (c) 2001 Sun Microsystems | |
21883 | * | |
21884 | - * interface borrowed from alim15x3.c: | |
21885 | - * Copyright (C) 1998-2000 Michel Aubry, Maintainer | |
21886 | - * Copyright (C) 1998-2000 Andrzej Krzysztofowicz, Maintainer | |
21887 | * | |
21888 | - * Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org> | |
21889 | + * RCC/ServerWorks IDE driver for Linux | |
21890 | * | |
21891 | - * IDE support for the ServerWorks OSB4 IDE chipset | |
21892 | + * OSB4: `Open South Bridge' IDE Interface (fn 1) | |
21893 | + * supports UDMA mode 2 (33 MB/s) | |
21894 | * | |
21895 | - * here's the default lspci: | |
21896 | + * CSB5: `Champion South Bridge' IDE Interface (fn 1) | |
21897 | + * all revisions support UDMA mode 4 (66 MB/s) | |
21898 | + * revision A2.0 and up support UDMA mode 5 (100 MB/s) | |
21899 | * | |
21900 | - * 00:0f.1 IDE interface: ServerWorks: Unknown device 0211 (prog-if 8a [Master SecP PriP]) | |
21901 | - * Control: I/O+ Mem- BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR+ FastB2B- | |
21902 | - * Status: Cap- 66Mhz- UDF- FastB2B- ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- | |
21903 | - * Latency: 255 | |
21904 | - * Region 4: I/O ports at c200 | |
21905 | - * 00: 66 11 11 02 05 01 00 02 00 8a 01 01 00 ff 80 00 | |
21906 | - * 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | |
21907 | - * 20: 01 c2 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | |
21908 | - * 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | |
21909 | - * 40: 99 99 99 99 ff ff ff ff 0c 0c 00 00 00 00 00 00 | |
21910 | - * 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | |
21911 | - * 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | |
21912 | - * 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | |
21913 | - * 80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | |
21914 | - * 90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | |
21915 | - * a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | |
21916 | - * b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | |
21917 | - * c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | |
21918 | - * d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | |
21919 | - * e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | |
21920 | - * f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | |
21921 | - * | |
21922 | - * 00:0f.1 IDE interface: ServerWorks: Unknown device 0212 (rev 92) (prog-if 8a [Master SecP PriP]) | |
21923 | - * Subsystem: ServerWorks: Unknown device 0212 | |
21924 | - * Control: I/O+ Mem- BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- | |
21925 | - * Status: Cap- 66Mhz- UDF- FastB2B- ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- | |
21926 | - * Latency: 64, cache line size 08 | |
21927 | - * Region 0: I/O ports at 01f0 | |
21928 | - * Region 1: I/O ports at 03f4 | |
21929 | - * Region 2: I/O ports at 0170 | |
21930 | - * Region 3: I/O ports at 0374 | |
21931 | - * Region 4: I/O ports at 08b0 | |
21932 | - * Region 5: I/O ports at 1000 | |
21933 | - * | |
21934 | - * 00:0f.1 IDE interface: ServerWorks: Unknown device 0212 (rev 92) | |
21935 | - * 00: 66 11 12 02 05 00 00 02 92 8a 01 01 08 40 80 00 | |
21936 | - * 10: f1 01 00 00 f5 03 00 00 71 01 00 00 75 03 00 00 | |
21937 | - * 20: b1 08 00 00 01 10 00 00 00 00 00 00 66 11 12 02 | |
21938 | - * 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | |
21939 | - * 40: 4f 4f 4f 4f 20 ff ff ff f0 50 44 44 00 00 00 00 | |
21940 | - * 50: 00 00 00 00 07 00 44 02 0f 04 03 00 00 00 00 00 | |
21941 | - * 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | |
21942 | - * 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | |
21943 | - * 80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | |
21944 | - * 90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | |
21945 | - * a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | |
21946 | - * b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | |
21947 | - * c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | |
21948 | - * d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | |
21949 | - * e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | |
21950 | - * f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | |
21951 | + * *** The CSB5 does not provide ANY register *** | |
21952 | + * *** to detect 80-conductor cable presence. *** | |
21953 | * | |
21954 | + * CSB6: `Champion South Bridge' IDE Interface (optional: third channel) | |
21955 | * | |
21956 | */ | |
21957 | ||
21958 | @@ -83,73 +37,98 @@ | |
21959 | ||
21960 | #include "ide_modes.h" | |
21961 | ||
21962 | -#define SVWKS_DEBUG_DRIVE_INFO 0 | |
21963 | - | |
21964 | -#define DISPLAY_SVWKS_TIMINGS | |
21965 | +#define DISPLAY_SVWKS_TIMINGS 1 | |
21966 | +#undef SVWKS_DEBUG_DRIVE_INFO | |
21967 | ||
21968 | #if defined(DISPLAY_SVWKS_TIMINGS) && defined(CONFIG_PROC_FS) | |
21969 | #include <linux/stat.h> | |
21970 | #include <linux/proc_fs.h> | |
21971 | ||
21972 | -static struct pci_dev *bmide_dev; | |
21973 | +#define SVWKS_MAX_DEVS 2 | |
21974 | +static struct pci_dev *svwks_devs[SVWKS_MAX_DEVS]; | |
21975 | +static int n_svwks_devs; | |
21976 | + | |
21977 | +static byte svwks_revision = 0; | |
21978 | ||
21979 | static int svwks_get_info(char *, char **, off_t, int); | |
21980 | extern int (*svwks_display_info)(char *, char **, off_t, int); /* ide-proc.c */ | |
21981 | -extern char *ide_media_verbose(ide_drive_t *); | |
21982 | ||
21983 | static int svwks_get_info (char *buffer, char **addr, off_t offset, int count) | |
21984 | { | |
21985 | char *p = buffer; | |
21986 | - u32 bibma = pci_resource_start(bmide_dev, 4); | |
21987 | - u32 reg40, reg44; | |
21988 | - u16 reg48, reg56; | |
21989 | - u8 c0 = 0, c1 = 0, reg54; | |
21990 | - | |
21991 | - pci_read_config_dword(bmide_dev, 0x40, ®40); | |
21992 | - pci_read_config_dword(bmide_dev, 0x44, ®44); | |
21993 | - pci_read_config_word(bmide_dev, 0x48, ®48); | |
21994 | - pci_read_config_byte(bmide_dev, 0x54, ®54); | |
21995 | - pci_read_config_word(bmide_dev, 0x56, ®56); | |
21996 | - | |
21997 | - /* | |
21998 | - * at that point bibma+0x2 et bibma+0xa are byte registers | |
21999 | - * to investigate: | |
22000 | - */ | |
22001 | - c0 = inb_p((unsigned short)bibma + 0x02); | |
22002 | - c1 = inb_p((unsigned short)bibma + 0x0a); | |
22003 | + int i; | |
22004 | ||
22005 | - switch(bmide_dev->device) { | |
22006 | - case PCI_DEVICE_ID_SERVERWORKS_CSB5IDE: | |
22007 | - p += sprintf(p, "\n ServerWorks CSB5 Chipset.\n"); | |
22008 | - break; | |
22009 | - case PCI_DEVICE_ID_SERVERWORKS_OSB4: | |
22010 | - p += sprintf(p, "\n ServerWorks OSB4 Chipset.\n"); | |
22011 | - break; | |
22012 | - default: | |
22013 | - p += sprintf(p, "\n ServerWorks 0x%04x Chipset.\n", bmide_dev->device); | |
22014 | - break; | |
22015 | - } | |
22016 | + p += sprintf(p, "\n " | |
22017 | + "ServerWorks OSB4/CSB5/CSB6\n"); | |
22018 | ||
22019 | - p += sprintf(p, "------------------------------- General Status ---------------------------------\n"); | |
22020 | -#if 0 | |
22021 | - p += sprintf(p, " : %s\n", "str"); | |
22022 | -#endif | |
22023 | - p += sprintf(p, "--------------- Primary Channel ---------------- Secondary Channel -------------\n"); | |
22024 | - p += sprintf(p, " %sabled %sabled\n", | |
22025 | - (c0&0x80) ? "dis" : " en", | |
22026 | - (c1&0x80) ? "dis" : " en"); | |
22027 | - p += sprintf(p, "--------------- drive0 --------- drive1 -------- drive0 ---------- drive1 ------\n"); | |
22028 | - p += sprintf(p, "DMA enabled: %s %s %s %s\n", | |
22029 | + for (i = 0; i < n_svwks_devs; i++) { | |
22030 | + struct pci_dev *dev = svwks_devs[i]; | |
22031 | + u32 bibma = pci_resource_start(dev, 4); | |
22032 | + u32 reg40, reg44; | |
22033 | + u16 reg48, reg56; | |
22034 | + u8 reg54, c0=0, c1=0; | |
22035 | + | |
22036 | + pci_read_config_dword(dev, 0x40, ®40); | |
22037 | + pci_read_config_dword(dev, 0x44, ®44); | |
22038 | + pci_read_config_word(dev, 0x48, ®48); | |
22039 | + pci_read_config_byte(dev, 0x54, ®54); | |
22040 | + pci_read_config_word(dev, 0x56, ®56); | |
22041 | + | |
22042 | + /* | |
22043 | + * at that point bibma+0x2 et bibma+0xa are byte registers | |
22044 | + * to investigate: | |
22045 | + */ | |
22046 | + c0 = inb_p((unsigned short)bibma + 0x02); | |
22047 | + c1 = inb_p((unsigned short)bibma + 0x0a); | |
22048 | + | |
22049 | + switch(dev->device) { | |
22050 | + case PCI_DEVICE_ID_SERVERWORKS_CSB6IDE: | |
22051 | + p += sprintf(p, "\n " | |
22052 | + "ServerWorks CSB6 Chipset (rev %02x)\n", | |
22053 | + svwks_revision); | |
22054 | + break; | |
22055 | + case PCI_DEVICE_ID_SERVERWORKS_CSB5IDE: | |
22056 | + p += sprintf(p, "\n " | |
22057 | + "ServerWorks CSB5 Chipset (rev %02x)\n", | |
22058 | + svwks_revision); | |
22059 | + break; | |
22060 | + case PCI_DEVICE_ID_SERVERWORKS_OSB4IDE: | |
22061 | + p += sprintf(p, "\n " | |
22062 | + "ServerWorks OSB4 Chipset (rev %02x)\n", | |
22063 | + svwks_revision); | |
22064 | + break; | |
22065 | + default: | |
22066 | + p += sprintf(p, "\n " | |
22067 | + "ServerWorks %04x Chipset (rev %02x)\n", | |
22068 | + dev->device, svwks_revision); | |
22069 | + break; | |
22070 | + } | |
22071 | + | |
22072 | + p += sprintf(p, "------------------------------- " | |
22073 | + "General Status " | |
22074 | + "---------------------------------\n"); | |
22075 | + p += sprintf(p, "--------------- Primary Channel " | |
22076 | + "---------------- Secondary Channel " | |
22077 | + "-------------\n"); | |
22078 | + p += sprintf(p, " %sabled %sabled\n", | |
22079 | + (c0&0x80) ? "dis" : " en", | |
22080 | + (c1&0x80) ? "dis" : " en"); | |
22081 | + p += sprintf(p, "--------------- drive0 --------- drive1 " | |
22082 | + "-------- drive0 ---------- drive1 ------\n"); | |
22083 | + p += sprintf(p, "DMA enabled: %s %s" | |
22084 | + " %s %s\n", | |
22085 | (c0&0x20) ? "yes" : "no ", | |
22086 | (c0&0x40) ? "yes" : "no ", | |
22087 | (c1&0x20) ? "yes" : "no ", | |
22088 | (c1&0x40) ? "yes" : "no " ); | |
22089 | - p += sprintf(p, "UDMA enabled: %s %s %s %s\n", | |
22090 | + p += sprintf(p, "UDMA enabled: %s %s" | |
22091 | + " %s %s\n", | |
22092 | (reg54 & 0x01) ? "yes" : "no ", | |
22093 | (reg54 & 0x02) ? "yes" : "no ", | |
22094 | (reg54 & 0x04) ? "yes" : "no ", | |
22095 | (reg54 & 0x08) ? "yes" : "no " ); | |
22096 | - p += sprintf(p, "UDMA enabled: %s %s %s %s\n", | |
22097 | + p += sprintf(p, "UDMA enabled: %s %s" | |
22098 | + " %s %s\n", | |
22099 | ((reg56&0x0005)==0x0005)?"5": | |
22100 | ((reg56&0x0004)==0x0004)?"4": | |
22101 | ((reg56&0x0003)==0x0003)?"3": | |
22102 | @@ -174,7 +153,8 @@ | |
22103 | ((reg56&0x2000)==0x2000)?"2": | |
22104 | ((reg56&0x1000)==0x1000)?"1": | |
22105 | ((reg56&0xF000))?"?":"0"); | |
22106 | - p += sprintf(p, "DMA enabled: %s %s %s %s\n", | |
22107 | + p += sprintf(p, "DMA enabled: %s %s" | |
22108 | + " %s %s\n", | |
22109 | ((reg44&0x00002000)==0x00002000)?"2": | |
22110 | ((reg44&0x00002100)==0x00002100)?"1": | |
22111 | ((reg44&0x00007700)==0x00007700)?"0": | |
22112 | @@ -191,12 +171,9 @@ | |
22113 | ((reg44&0x00210000)==0x00210000)?"1": | |
22114 | ((reg44&0x00770000)==0x00770000)?"0": | |
22115 | ((reg44&0x00FF0000)==0x00FF0000)?"X":"?"); | |
22116 | -#if 0 | |
22117 | - if (bmide_dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5IDE) | |
22118 | - p += sprintf(p, "PIO enabled: %s %s %s %s\n", | |
22119 | - if (bmide_dev->device == PCI_DEVICE_ID_SERVERWORKS_OSB4) | |
22120 | -#endif | |
22121 | - p += sprintf(p, "PIO enabled: %s %s %s %s\n", | |
22122 | + | |
22123 | + p += sprintf(p, "PIO enabled: %s %s" | |
22124 | + " %s %s\n", | |
22125 | ((reg40&0x00002000)==0x00002000)?"4": | |
22126 | ((reg40&0x00002200)==0x00002200)?"3": | |
22127 | ((reg40&0x00003400)==0x00003400)?"2": | |
22128 | @@ -217,19 +194,83 @@ | |
22129 | ((reg40&0x00340000)==0x00340000)?"2": | |
22130 | ((reg40&0x00470000)==0x00470000)?"1": | |
22131 | ((reg40&0x005D0000)==0x005D0000)?"0":"?"); | |
22132 | + | |
22133 | + } | |
22134 | + p += sprintf(p, "\n"); | |
22135 | + | |
22136 | return p-buffer; /* => must be less than 4k! */ | |
22137 | } | |
22138 | #endif /* defined(DISPLAY_SVWKS_TIMINGS) && defined(CONFIG_PROC_FS) */ | |
22139 | ||
22140 | -static byte svwks_revision = 0; | |
22141 | +#define SVWKS_CSB5_REVISION_NEW 0x92 /* min PCI_REVISION_ID for UDMA5 (A2.0) */ | |
22142 | ||
22143 | -byte svwks_proc = 0; | |
22144 | +#define SVWKS_CSB6_REVISION 0xa0 /* min PCI_REVISION_ID for UDMA4 (A1.0) */ | |
22145 | ||
22146 | -extern char *ide_xfer_verbose (byte xfer_rate); | |
22147 | +byte svwks_proc = 0; | |
22148 | ||
22149 | static struct pci_dev *isa_dev; | |
22150 | ||
22151 | -static int svwks_tune_chipset (ide_drive_t *drive, byte speed) | |
22152 | +static byte svwks_ratemask (ide_drive_t *drive) | |
22153 | +{ | |
22154 | + struct pci_dev *dev = HWIF(drive)->pci_dev; | |
22155 | + byte mode = 0; | |
22156 | + | |
22157 | + if (dev->device == PCI_DEVICE_ID_SERVERWORKS_OSB4IDE) { | |
22158 | + u32 reg = 0; | |
22159 | + mode &= ~0x01; | |
22160 | + if (isa_dev) | |
22161 | + pci_read_config_dword(isa_dev, 0x64, ®); | |
22162 | + if ((reg & 0x00004000) == 0x00004000) | |
22163 | + mode |= 0x01; | |
22164 | + } else if (svwks_revision < SVWKS_CSB5_REVISION_NEW) { | |
22165 | + mode |= 0x01; | |
22166 | + } else if (svwks_revision >= SVWKS_CSB5_REVISION_NEW) { | |
22167 | + u8 btr =0; | |
22168 | + pci_read_config_byte(dev, 0x5A, &btr); | |
22169 | + mode |= btr; | |
22170 | + if (!eighty_ninty_three(drive)) | |
22171 | + mode &= ~0x02; | |
22172 | + } | |
22173 | + if ((dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE) && | |
22174 | + (!(PCI_FUNC(dev->devfn) & 1))) | |
22175 | + mode = 0x02; | |
22176 | + mode &= ~0xFC; | |
22177 | + return (mode); | |
22178 | +} | |
22179 | + | |
22180 | +static byte svwks_ratefilter (ide_drive_t *drive, byte speed) | |
22181 | +{ | |
22182 | +#ifdef CONFIG_BLK_DEV_IDEDMA | |
22183 | + byte mode = svwks_ratemask(drive); | |
22184 | + | |
22185 | + switch(mode) { | |
22186 | + case 0x04: while (speed > XFER_UDMA_6) speed--; break; | |
22187 | + case 0x03: while (speed > XFER_UDMA_5) speed--; break; | |
22188 | + case 0x02: while (speed > XFER_UDMA_4) speed--; break; | |
22189 | + case 0x01: while (speed > XFER_UDMA_2) speed--; break; | |
22190 | + case 0x00: | |
22191 | + default: while (speed > XFER_MW_DMA_2) speed--; break; | |
22192 | + break; | |
22193 | + } | |
22194 | +#else | |
22195 | + while (speed > XFER_PIO_4) speed--; | |
22196 | +#endif /* CONFIG_BLK_DEV_IDEDMA */ | |
22197 | +// printk("%s: mode == %02x speed == %02x\n", drive->name, mode, speed); | |
22198 | + return speed; | |
22199 | +} | |
22200 | + | |
22201 | +static byte svwks_csb_check (struct pci_dev *dev) | |
22202 | +{ | |
22203 | + switch (dev->device) { | |
22204 | + case PCI_DEVICE_ID_SERVERWORKS_CSB5IDE: | |
22205 | + case PCI_DEVICE_ID_SERVERWORKS_CSB6IDE: | |
22206 | + return 1; | |
22207 | + default: | |
22208 | + break; | |
22209 | + } | |
22210 | + return 0; | |
22211 | +} | |
22212 | +static int svwks_tune_chipset (ide_drive_t *drive, byte xferspeed) | |
22213 | { | |
22214 | byte udma_modes[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 }; | |
22215 | byte dma_modes[] = { 0x77, 0x21, 0x20 }; | |
22216 | @@ -238,12 +279,7 @@ | |
22217 | ide_hwif_t *hwif = HWIF(drive); | |
22218 | struct pci_dev *dev = hwif->pci_dev; | |
22219 | byte unit = (drive->select.b.unit & 0x01); | |
22220 | - byte csb5 = (dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5IDE) ? 1 : 0; | |
22221 | - | |
22222 | -#ifdef CONFIG_BLK_DEV_IDEDMA | |
22223 | - unsigned long dma_base = hwif->dma_base; | |
22224 | -#endif /* CONFIG_BLK_DEV_IDEDMA */ | |
22225 | - int err; | |
22226 | + byte csb5 = svwks_csb_check(dev); | |
22227 | ||
22228 | byte drive_pci = 0x00; | |
22229 | byte drive_pci2 = 0x00; | |
22230 | @@ -256,6 +292,7 @@ | |
22231 | unsigned short csb5_pio = 0x00; | |
22232 | ||
22233 | byte pio = ide_get_best_pio_mode(drive, 255, 5, NULL); | |
22234 | + byte speed = svwks_ratefilter(drive, xferspeed); | |
22235 | ||
22236 | switch (drive->dn) { | |
22237 | case 0: drive_pci = 0x41; drive_pci2 = 0x45; break; | |
22238 | @@ -272,11 +309,6 @@ | |
22239 | pci_read_config_word(dev, 0x4A, &csb5_pio); | |
22240 | pci_read_config_byte(dev, 0x54, &ultra_enable); | |
22241 | ||
22242 | -#ifdef DEBUG | |
22243 | - printk("%s: UDMA 0x%02x DMAPIO 0x%02x PIO 0x%02x ", | |
22244 | - drive->name, ultra_timing, dma_timing, pio_timing); | |
22245 | -#endif | |
22246 | - | |
22247 | pio_timing &= ~0xFF; | |
22248 | dma_timing &= ~0xFF; | |
22249 | ultra_timing &= ~(0x0F << (4*unit)); | |
22250 | @@ -292,6 +324,7 @@ | |
22251 | pio_timing |= pio_modes[speed - XFER_PIO_0]; | |
22252 | csb5_pio |= ((speed - XFER_PIO_0) << (4*drive->dn)); | |
22253 | break; | |
22254 | + | |
22255 | #ifdef CONFIG_BLK_DEV_IDEDMA | |
22256 | case XFER_MW_DMA_2: | |
22257 | case XFER_MW_DMA_1: | |
22258 | @@ -307,9 +340,9 @@ | |
22259 | case XFER_UDMA_2: | |
22260 | case XFER_UDMA_1: | |
22261 | case XFER_UDMA_0: | |
22262 | - pio_timing |= pio_modes[pio]; | |
22263 | - csb5_pio |= (pio << (4*drive->dn)); | |
22264 | - dma_timing |= dma_modes[2]; | |
22265 | + pio_timing |= pio_modes[pio]; | |
22266 | + csb5_pio |= (pio << (4*drive->dn)); | |
22267 | + dma_timing |= dma_modes[2]; | |
22268 | ultra_timing |= ((udma_modes[speed - XFER_UDMA_0]) << (4*unit)); | |
22269 | ultra_enable |= (0x01 << drive->dn); | |
22270 | #endif | |
22271 | @@ -317,18 +350,6 @@ | |
22272 | break; | |
22273 | } | |
22274 | ||
22275 | -#ifdef DEBUG | |
22276 | - printk("%s: UDMA 0x%02x DMAPIO 0x%02x PIO 0x%02x ", | |
22277 | - drive->name, ultra_timing, dma_timing, pio_timing); | |
22278 | -#endif | |
22279 | - | |
22280 | -#if OSB4_DEBUG_DRIVE_INFO | |
22281 | - printk("%s: %s drive%d\n", drive->name, ide_xfer_verbose(speed), drive->dn); | |
22282 | -#endif /* OSB4_DEBUG_DRIVE_INFO */ | |
22283 | - | |
22284 | - if (!drive->init_speed) | |
22285 | - drive->init_speed = speed; | |
22286 | - | |
22287 | pci_write_config_byte(dev, drive_pci, pio_timing); | |
22288 | if (csb5) | |
22289 | pci_write_config_word(dev, 0x4A, csb5_pio); | |
22290 | @@ -337,42 +358,33 @@ | |
22291 | pci_write_config_byte(dev, drive_pci2, dma_timing); | |
22292 | pci_write_config_byte(dev, drive_pci3, ultra_timing); | |
22293 | pci_write_config_byte(dev, 0x54, ultra_enable); | |
22294 | - | |
22295 | - if (speed > XFER_PIO_4) { | |
22296 | - outb(inb(dma_base+2)|(1<<(5+unit)), dma_base+2); | |
22297 | - } else { | |
22298 | - outb(inb(dma_base+2) & ~(1<<(5+unit)), dma_base+2); | |
22299 | - } | |
22300 | #endif /* CONFIG_BLK_DEV_IDEDMA */ | |
22301 | ||
22302 | - err = ide_config_drive_speed(drive, speed); | |
22303 | - drive->current_speed = speed; | |
22304 | - return err; | |
22305 | + return (ide_config_drive_speed(drive, speed)); | |
22306 | } | |
22307 | ||
22308 | static void config_chipset_for_pio (ide_drive_t *drive) | |
22309 | { | |
22310 | unsigned short eide_pio_timing[6] = {960, 480, 240, 180, 120, 90}; | |
22311 | unsigned short xfer_pio = drive->id->eide_pio_modes; | |
22312 | - byte timing, speed, pio; | |
22313 | + byte timing, speed, pio; | |
22314 | ||
22315 | pio = ide_get_best_pio_mode(drive, 255, 5, NULL); | |
22316 | ||
22317 | if (xfer_pio> 4) | |
22318 | xfer_pio = 0; | |
22319 | ||
22320 | - if (drive->id->eide_pio_iordy > 0) { | |
22321 | + if (drive->id->eide_pio_iordy > 0) | |
22322 | for (xfer_pio = 5; | |
22323 | xfer_pio>0 && | |
22324 | drive->id->eide_pio_iordy>eide_pio_timing[xfer_pio]; | |
22325 | xfer_pio--); | |
22326 | - } else { | |
22327 | + else | |
22328 | xfer_pio = (drive->id->eide_pio_modes & 4) ? 0x05 : | |
22329 | (drive->id->eide_pio_modes & 2) ? 0x04 : | |
22330 | (drive->id->eide_pio_modes & 1) ? 0x03 : | |
22331 | (drive->id->tPIO & 2) ? 0x02 : | |
22332 | (drive->id->tPIO & 1) ? 0x01 : xfer_pio; | |
22333 | - } | |
22334 | ||
22335 | timing = (xfer_pio >= pio) ? xfer_pio : pio; | |
22336 | ||
22337 | @@ -406,38 +418,54 @@ | |
22338 | static int config_chipset_for_dma (ide_drive_t *drive) | |
22339 | { | |
22340 | struct hd_driveid *id = drive->id; | |
22341 | - struct pci_dev *dev = HWIF(drive)->pci_dev; | |
22342 | - byte udma_66 = eighty_ninty_three(drive); | |
22343 | - byte speed; | |
22344 | - | |
22345 | - int ultra66 = (dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5IDE) ? 1 : 0; | |
22346 | - /* need specs to figure out if osb4 is capable of ata/66/100 */ | |
22347 | - int ultra100 = (dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5IDE) ? 1 : 0; | |
22348 | - | |
22349 | - if ((id->dma_ultra & 0x0020) && (udma_66) && (ultra100)) { | |
22350 | - speed = XFER_UDMA_5; | |
22351 | - } else if (id->dma_ultra & 0x0010) { | |
22352 | - speed = ((udma_66) && (ultra66)) ? XFER_UDMA_4 : XFER_UDMA_2; | |
22353 | - } else if (id->dma_ultra & 0x0008) { | |
22354 | - speed = ((udma_66) && (ultra66)) ? XFER_UDMA_3 : XFER_UDMA_1; | |
22355 | - } else if (id->dma_ultra & 0x0004) { | |
22356 | - speed = XFER_UDMA_2; | |
22357 | - } else if (id->dma_ultra & 0x0002) { | |
22358 | - speed = XFER_UDMA_1; | |
22359 | - } else if (id->dma_ultra & 0x0001) { | |
22360 | - speed = XFER_UDMA_0; | |
22361 | - } else if (id->dma_mword & 0x0004) { | |
22362 | - speed = XFER_MW_DMA_2; | |
22363 | - } else if (id->dma_mword & 0x0002) { | |
22364 | - speed = XFER_MW_DMA_1; | |
22365 | - } else if (id->dma_1word & 0x0004) { | |
22366 | - speed = XFER_SW_DMA_2; | |
22367 | - } else { | |
22368 | - speed = XFER_PIO_0 + ide_get_best_pio_mode(drive, 255, 5, NULL); | |
22369 | + byte mode = svwks_ratemask(drive); | |
22370 | + byte speed, dma = 1; | |
22371 | + | |
22372 | + if (HWIF(drive)->pci_dev->device == PCI_DEVICE_ID_SERVERWORKS_OSB4IDE) | |
22373 | + mode = 0; | |
22374 | + | |
22375 | + switch(mode) { | |
22376 | + case 0x04: | |
22377 | + if (id->dma_ultra & 0x0040) | |
22378 | + { speed = XFER_UDMA_6; break; } | |
22379 | + case 0x03: | |
22380 | + if (id->dma_ultra & 0x0020) | |
22381 | + { speed = XFER_UDMA_5; break; } | |
22382 | + case 0x02: | |
22383 | + if (id->dma_ultra & 0x0010) | |
22384 | + { speed = XFER_UDMA_4; break; } | |
22385 | + if (id->dma_ultra & 0x0008) | |
22386 | + { speed = XFER_UDMA_3; break; } | |
22387 | + case 0x01: | |
22388 | + if (id->dma_ultra & 0x0004) | |
22389 | + { speed = XFER_UDMA_2; break; } | |
22390 | + if (id->dma_ultra & 0x0002) | |
22391 | + { speed = XFER_UDMA_1; break; } | |
22392 | + if (id->dma_ultra & 0x0001) | |
22393 | + { speed = XFER_UDMA_0; break; } | |
22394 | + if (id->dma_mword & 0x0004) | |
22395 | + { speed = XFER_MW_DMA_2; break; } | |
22396 | + if (id->dma_mword & 0x0002) | |
22397 | + { speed = XFER_MW_DMA_1; break; } | |
22398 | + if (id->dma_mword & 0x0001) | |
22399 | + { speed = XFER_MW_DMA_0; break; } | |
22400 | +#if 0 | |
22401 | + if (id->dma_1word & 0x0004) | |
22402 | + { speed = XFER_SW_DMA_2; break; } | |
22403 | + if (id->dma_1word & 0x0002) | |
22404 | + { speed = XFER_SW_DMA_1; break; } | |
22405 | + if (id->dma_1word & 0x0001) | |
22406 | + { speed = XFER_SW_DMA_0; break; } | |
22407 | +#endif | |
22408 | + default: | |
22409 | + speed = XFER_PIO_0 + ide_get_best_pio_mode(drive, 255, 5, NULL); | |
22410 | + dma = 0; | |
22411 | + break; | |
22412 | } | |
22413 | ||
22414 | (void) svwks_tune_chipset(drive, speed); | |
22415 | ||
22416 | +// return ((int) (dma) ? ide_dma_on : ide_dma_off_quietly); | |
22417 | return ((int) ((id->dma_ultra >> 11) & 7) ? ide_dma_on : | |
22418 | ((id->dma_ultra >> 8) & 7) ? ide_dma_on : | |
22419 | ((id->dma_mword >> 8) & 7) ? ide_dma_on : | |
22420 | @@ -450,6 +478,8 @@ | |
22421 | struct hd_driveid *id = drive->id; | |
22422 | ide_dma_action_t dma_func = ide_dma_on; | |
22423 | ||
22424 | + drive->init_speed = 0; | |
22425 | + | |
22426 | if (id && (id->capability & 1) && HWIF(drive)->autodma) { | |
22427 | /* Consult the list of known "bad" drives */ | |
22428 | if (ide_dmaproc(ide_dma_bad_drive, drive)) { | |
22429 | @@ -458,7 +488,7 @@ | |
22430 | } | |
22431 | dma_func = ide_dma_off_quietly; | |
22432 | if (id->field_valid & 4) { | |
22433 | - if (id->dma_ultra & 0x002F) { | |
22434 | + if (id->dma_ultra & 0x003F) { | |
22435 | /* Force if Capable UltraDMA */ | |
22436 | dma_func = config_chipset_for_dma(drive); | |
22437 | if ((id->field_valid & 2) && | |
22438 | @@ -490,6 +520,7 @@ | |
22439 | dma_func = ide_dma_off_quietly; | |
22440 | no_dma_set: | |
22441 | config_chipset_for_pio(drive); | |
22442 | + // HWIF(drive)->tuneproc(drive, 5); | |
22443 | } | |
22444 | return HWIF(drive)->dmaproc(dma_func, drive); | |
22445 | } | |
22446 | @@ -499,7 +530,41 @@ | |
22447 | switch (func) { | |
22448 | case ide_dma_check: | |
22449 | return config_drive_xfer_rate(drive); | |
22450 | - default : | |
22451 | + case ide_dma_end: | |
22452 | + { | |
22453 | + ide_hwif_t *hwif = HWIF(drive); | |
22454 | + unsigned long dma_base = hwif->dma_base; | |
22455 | + | |
22456 | + if(IN_BYTE(dma_base+0x02)&1) | |
22457 | + { | |
22458 | +#if 0 | |
22459 | + int i; | |
22460 | + printk(KERN_ERR "Curious - OSB4 thinks the DMA is still running.\n"); | |
22461 | + for(i=0;i<10;i++) | |
22462 | + { | |
22463 | + if(!(IN_BYTE(dma_base+0x02)&1)) | |
22464 | + { | |
22465 | + printk(KERN_ERR "OSB4 now finished.\n"); | |
22466 | + break; | |
22467 | + } | |
22468 | + udelay(5); | |
22469 | + } | |
22470 | +#endif | |
22471 | + printk(KERN_CRIT "Serverworks OSB4 in impossible state.\n"); | |
22472 | + printk(KERN_CRIT "Disable UDMA or if you are using Seagate then try switching disk types\n"); | |
22473 | + printk(KERN_CRIT "on this controller. Please report this event to osb4-bug@ide.cabal.tm\n"); | |
22474 | +#if 0 | |
22475 | + /* Panic might sys_sync -> death by corrupt disk */ | |
22476 | + panic("OSB4: continuing might cause disk corruption.\n"); | |
22477 | +#else | |
22478 | + printk(KERN_CRIT "OSB4: continuing might cause disk corruption.\n"); | |
22479 | + while(1) | |
22480 | + cpu_relax(); | |
22481 | +#endif | |
22482 | + } | |
22483 | + /* and drop through */ | |
22484 | + } | |
22485 | + default: | |
22486 | break; | |
22487 | } | |
22488 | /* Other cases are done by generic IDE-DMA code. */ | |
22489 | @@ -509,68 +574,154 @@ | |
22490 | ||
22491 | unsigned int __init pci_init_svwks (struct pci_dev *dev, const char *name) | |
22492 | { | |
22493 | - unsigned int reg64; | |
22494 | + unsigned int reg; | |
22495 | + byte btr; | |
22496 | ||
22497 | + /* save revision id to determine DMA capability */ | |
22498 | pci_read_config_byte(dev, PCI_REVISION_ID, &svwks_revision); | |
22499 | ||
22500 | + /* force Master Latency Timer value to 64 PCICLKs */ | |
22501 | + pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x40); | |
22502 | + | |
22503 | + /* OSB4 : South Bridge and IDE */ | |
22504 | if (dev->device == PCI_DEVICE_ID_SERVERWORKS_OSB4IDE) { | |
22505 | - isa_dev = pci_find_device(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_OSB4, NULL); | |
22506 | + isa_dev = pci_find_device(PCI_VENDOR_ID_SERVERWORKS, | |
22507 | + PCI_DEVICE_ID_SERVERWORKS_OSB4, NULL); | |
22508 | + if (isa_dev) { | |
22509 | + pci_read_config_dword(isa_dev, 0x64, ®); | |
22510 | + reg &= ~0x00002000; /* disable 600ns interrupt mask */ | |
22511 | + reg |= 0x00004000; /* enable UDMA/33 support */ | |
22512 | + pci_write_config_dword(isa_dev, 0x64, reg); | |
22513 | + } | |
22514 | + } | |
22515 | ||
22516 | - pci_read_config_dword(isa_dev, 0x64, ®64); | |
22517 | -#ifdef DEBUG | |
22518 | - printk("%s: reg64 == 0x%08x\n", name, reg64); | |
22519 | + /* setup CSB5/CSB6 : South Bridge and IDE option RAID */ | |
22520 | + else if ((dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5IDE) || | |
22521 | + (dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE)) { | |
22522 | + /* Third Channel Test */ | |
22523 | + if (!(PCI_FUNC(dev->devfn) & 1)) { | |
22524 | +#if 1 | |
22525 | + struct pci_dev * findev = NULL; | |
22526 | + unsigned int reg4c = 0; | |
22527 | + findev = pci_find_device(PCI_VENDOR_ID_SERVERWORKS, | |
22528 | + PCI_DEVICE_ID_SERVERWORKS_CSB5, NULL); | |
22529 | + if (findev) { | |
22530 | + pci_read_config_dword(findev, 0x4C, ®4c); | |
22531 | + reg4c &= ~0x000007FF; | |
22532 | + reg4c |= 0x00000040; | |
22533 | + reg4c |= 0x00000020; | |
22534 | + pci_write_config_dword(findev, 0x4C, reg4c); | |
22535 | + } | |
22536 | #endif | |
22537 | - | |
22538 | -// reg64 &= ~0x0000A000; | |
22539 | -//#ifdef CONFIG_SMP | |
22540 | -// reg64 |= 0x00008000; | |
22541 | -//#endif | |
22542 | - /* Assume the APIC was set up properly by the BIOS for now . If it | |
22543 | - wasnt we need to do a fix up _way_ earlier. Bits 15,10,3 control | |
22544 | - APIC enable, routing and decode */ | |
22545 | - | |
22546 | - reg64 &= ~0x00002000; | |
22547 | - pci_write_config_dword(isa_dev, 0x64, reg64); | |
22548 | + outb_p(0x06, 0x0c00); | |
22549 | + dev->irq = inb_p(0x0c01); | |
22550 | +#if 1 | |
22551 | + /* WE need to figure out how to get the correct one */ | |
22552 | + printk("%s: interrupt %d\n", name, dev->irq); | |
22553 | + if (dev->irq != 0x0B) | |
22554 | + dev->irq = 0x0B; | |
22555 | +#endif | |
22556 | + } else { | |
22557 | + /* | |
22558 | + * This is a device pin issue on CSB6. | |
22559 | + * Since there will be a future raid mode, | |
22560 | + * early versions of the chipset require the | |
22561 | + * interrupt pin to be set, and it is a compatablity | |
22562 | + * mode issue. | |
22563 | + */ | |
22564 | + dev->irq = 0; | |
22565 | + } | |
22566 | + pci_write_config_dword(dev, 0x40, 0x99999999); | |
22567 | + pci_write_config_dword(dev, 0x44, 0xFFFFFFFF); | |
22568 | + /* setup the UDMA Control register | |
22569 | + * | |
22570 | + * 1. clear bit 6 to enable DMA | |
22571 | + * 2. enable DMA modes with bits 0-1 | |
22572 | + * 00 : legacy | |
22573 | + * 01 : udma2 | |
22574 | + * 10 : udma2/udma4 | |
22575 | + * 11 : udma2/udma4/udma5 | |
22576 | + */ | |
22577 | + pci_read_config_byte(dev, 0x5A, &btr); | |
22578 | + btr &= ~0x40; | |
22579 | + if (!(PCI_FUNC(dev->devfn) & 1)) | |
22580 | + btr |= 0x2; | |
22581 | + else | |
22582 | + btr |= (svwks_revision >= SVWKS_CSB5_REVISION_NEW) ? 0x3 : 0x2; | |
22583 | + pci_write_config_byte(dev, 0x5A, btr); | |
22584 | } | |
22585 | - pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x40); | |
22586 | + | |
22587 | + svwks_devs[n_svwks_devs++] = dev; | |
22588 | ||
22589 | #if defined(DISPLAY_SVWKS_TIMINGS) && defined(CONFIG_PROC_FS) | |
22590 | if (!svwks_proc) { | |
22591 | svwks_proc = 1; | |
22592 | - bmide_dev = dev; | |
22593 | svwks_display_info = &svwks_get_info; | |
22594 | } | |
22595 | #endif /* DISPLAY_SVWKS_TIMINGS && CONFIG_PROC_FS */ | |
22596 | - return 0; | |
22597 | + | |
22598 | + return (dev->irq) ? dev->irq : 0; | |
22599 | } | |
22600 | ||
22601 | -/* On Dell PowerEdge servers with a CSB5, the top two bits of the subsystem | |
22602 | - * device ID indicate presence of an 80-pin cable. | |
22603 | +static unsigned int __init ata66_svwks_svwks (ide_hwif_t *hwif) | |
22604 | +{ | |
22605 | +// struct pci_dev *dev = hwif->pci_dev; | |
22606 | +// return 0; | |
22607 | + return 1; | |
22608 | +} | |
22609 | + | |
22610 | +/* On Dell PowerEdge servers with a CSB5/CSB6, the top two bits | |
22611 | + * of the subsystem device ID indicate presence of an 80-pin cable. | |
22612 | * Bit 15 clear = secondary IDE channel does not have 80-pin cable. | |
22613 | * Bit 15 set = secondary IDE channel has 80-pin cable. | |
22614 | * Bit 14 clear = primary IDE channel does not have 80-pin cable. | |
22615 | * Bit 14 set = primary IDE channel has 80-pin cable. | |
22616 | */ | |
22617 | - | |
22618 | static unsigned int __init ata66_svwks_dell (ide_hwif_t *hwif) | |
22619 | { | |
22620 | - struct pci_dev *dev = hwif->pci_dev; | |
22621 | - if (dev->subsystem_vendor == PCI_VENDOR_ID_DELL && | |
22622 | - dev->vendor == PCI_VENDOR_ID_SERVERWORKS && | |
22623 | - dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5IDE) | |
22624 | + struct pci_dev *dev = hwif->pci_dev; | |
22625 | + if (dev->subsystem_vendor == PCI_VENDOR_ID_DELL && | |
22626 | + dev->vendor == PCI_VENDOR_ID_SERVERWORKS && | |
22627 | + (dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5IDE || | |
22628 | + dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE)) | |
22629 | return ((1 << (hwif->channel + 14)) & | |
22630 | dev->subsystem_device) ? 1 : 0; | |
22631 | - | |
22632 | return 0; | |
22633 | +} | |
22634 | ||
22635 | +/* Sun Cobalt Alpine hardware avoids the 80-pin cable | |
22636 | + * detect issue by attaching the drives directly to the board. | |
22637 | + * This check follows the Dell precedent (how scary is that?!) | |
22638 | + * | |
22639 | + * WARNING: this only works on Alpine hardware! | |
22640 | + */ | |
22641 | +static unsigned int __init ata66_svwks_cobalt (ide_hwif_t *hwif) | |
22642 | +{ | |
22643 | + struct pci_dev *dev = hwif->pci_dev; | |
22644 | + if (dev->subsystem_vendor == PCI_VENDOR_ID_SUN && | |
22645 | + dev->vendor == PCI_VENDOR_ID_SERVERWORKS && | |
22646 | + dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5IDE) | |
22647 | + return ((1 << (hwif->channel + 14)) & | |
22648 | + dev->subsystem_device) ? 1 : 0; | |
22649 | + return 0; | |
22650 | } | |
22651 | ||
22652 | unsigned int __init ata66_svwks (ide_hwif_t *hwif) | |
22653 | { | |
22654 | - struct pci_dev *dev = hwif->pci_dev; | |
22655 | + struct pci_dev *dev = hwif->pci_dev; | |
22656 | + | |
22657 | + /* Server Works */ | |
22658 | + if (dev->subsystem_vendor == PCI_VENDOR_ID_SERVERWORKS) | |
22659 | + return ata66_svwks_svwks (hwif); | |
22660 | + | |
22661 | + /* Dell PowerEdge */ | |
22662 | if (dev->subsystem_vendor == PCI_VENDOR_ID_DELL) | |
22663 | return ata66_svwks_dell (hwif); | |
22664 | - | |
22665 | + | |
22666 | + /* Cobalt Alpine */ | |
22667 | + if (dev->subsystem_vendor == PCI_VENDOR_ID_SUN) | |
22668 | + return ata66_svwks_cobalt (hwif); | |
22669 | + | |
22670 | return 0; | |
22671 | } | |
22672 | ||
22673 | @@ -581,22 +732,58 @@ | |
22674 | ||
22675 | hwif->tuneproc = &svwks_tune_drive; | |
22676 | hwif->speedproc = &svwks_tune_chipset; | |
22677 | - | |
22678 | -#ifndef CONFIG_BLK_DEV_IDEDMA | |
22679 | hwif->drives[0].autotune = 1; | |
22680 | hwif->drives[1].autotune = 1; | |
22681 | hwif->autodma = 0; | |
22682 | - return; | |
22683 | -#else /* CONFIG_BLK_DEV_IDEDMA */ | |
22684 | ||
22685 | - if (hwif->dma_base) { | |
22686 | - if (!noautodma) | |
22687 | - hwif->autodma = 1; | |
22688 | - hwif->dmaproc = &svwks_dmaproc; | |
22689 | - } else { | |
22690 | - hwif->autodma = 0; | |
22691 | - hwif->drives[0].autotune = 1; | |
22692 | - hwif->drives[1].autotune = 1; | |
22693 | - } | |
22694 | + if (!hwif->dma_base) | |
22695 | + return; | |
22696 | + | |
22697 | +#ifdef CONFIG_BLK_DEV_IDEDMA | |
22698 | + hwif->dmaproc = &svwks_dmaproc; | |
22699 | +# ifdef CONFIG_IDEDMA_AUTO | |
22700 | + if (!noautodma) | |
22701 | + hwif->autodma = 1; | |
22702 | +# endif /* CONFIG_IDEDMA_AUTO */ | |
22703 | #endif /* !CONFIG_BLK_DEV_IDEDMA */ | |
22704 | } | |
22705 | + | |
22706 | +/* | |
22707 | + * We allow the BM-DMA driver to only work on enabled interfaces. | |
22708 | + */ | |
22709 | +void __init ide_dmacapable_svwks (ide_hwif_t *hwif, unsigned long dmabase) | |
22710 | +{ | |
22711 | + struct pci_dev *dev = hwif->pci_dev; | |
22712 | + if ((dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE) && | |
22713 | + (!(PCI_FUNC(dev->devfn) & 1)) && (hwif->channel)) | |
22714 | + return; | |
22715 | +#if 0 | |
22716 | + if (svwks_revision == (SVWKS_CSB5_REVISION_NEW + 1)) { | |
22717 | + if (hwif->mate && hwif->mate->dma_base) { | |
22718 | + dmabase = hwif->mate->dma_base - (hwif->channel ? 0 : 8); | |
22719 | + } else { | |
22720 | + dmabase = pci_resource_start(dev, 4); | |
22721 | + if (!dmabase) { | |
22722 | + printk("%s: dma_base is invalid (0x%04lx)\n", | |
22723 | + hwif->name, dmabase); | |
22724 | + dmabase = 0; | |
22725 | + } | |
22726 | + } | |
22727 | + } | |
22728 | +#endif | |
22729 | + ide_setup_dma(hwif, dmabase, 8); | |
22730 | +} | |
22731 | + | |
22732 | +extern void ide_setup_pci_device (struct pci_dev *dev, ide_pci_device_t *d); | |
22733 | + | |
22734 | +void __init fixup_device_csb6 (struct pci_dev *dev, ide_pci_device_t *d) | |
22735 | +{ | |
22736 | + if (!(PCI_FUNC(dev->devfn) & 1)) { | |
22737 | + d->bootable = NEVER_BOARD; | |
22738 | + } | |
22739 | + | |
22740 | + printk("%s: IDE controller on PCI bus %02x dev %02x\n", | |
22741 | + d->name, dev->bus->number, dev->devfn); | |
22742 | + ide_setup_pci_device(dev, d); | |
22743 | +} | |
22744 | + | |
22745 | diff -Nur linux.org/drivers/ide/sis5513.c linux/drivers/ide/sis5513.c | |
22746 | --- linux.org/drivers/ide/sis5513.c Fri Sep 7 18:28:38 2001 | |
22747 | +++ linux/drivers/ide/sis5513.c Thu Jul 18 14:24:34 2002 | |
22748 | @@ -1,11 +1,35 @@ | |
22749 | /* | |
22750 | - * linux/drivers/ide/sis5513.c Version 0.11 June 9, 2000 | |
22751 | + * linux/drivers/ide/sis5513.c Version 0.13 March 6, 2002 | |
22752 | * | |
22753 | * Copyright (C) 1999-2000 Andre Hedrick <andre@linux-ide.org> | |
22754 | + * Copyright (C) 2002 Lionel Bouton <Lionel.Bouton@inet6.fr>, Maintainer | |
22755 | * May be copied or modified under the terms of the GNU General Public License | |
22756 | * | |
22757 | - * Thanks to SIS Taiwan for direct support and hardware. | |
22758 | - * Tested and designed on the SiS620/5513 chipset. | |
22759 | + * | |
22760 | + * Thanks : | |
22761 | + * | |
22762 | + * SiS Taiwan : for direct support and hardware. | |
22763 | + * Daniela Engert : for initial ATA100 advices and numerous others. | |
22764 | + * John Fremlin, Manfred Spraul : | |
22765 | + * for checking code correctness, providing patches. | |
22766 | + * | |
22767 | + * | |
22768 | + * Original tests and design on the SiS620/5513 chipset. | |
22769 | + * ATA100 tests and design on the SiS735/5513 chipset. | |
22770 | + * ATA16/33 design from specs | |
22771 | + */ | |
22772 | + | |
22773 | +/* | |
22774 | + * TODO: | |
22775 | + * - Get ridden of SisHostChipInfo[] completness dependancy. | |
22776 | + * - Get ATA-133 datasheets, implement ATA-133 init code. | |
22777 | + * - Study drivers/ide/ide-timing.h. | |
22778 | + * - Are there pre-ATA_16 SiS5513 chips ? -> tune init code for them | |
22779 | + * or remove ATA_00 define | |
22780 | + * - More checks in the config registers (force values instead of | |
22781 | + * relying on the BIOS setting them correctly). | |
22782 | + * - Further optimisations ? | |
22783 | + * . for example ATA66+ regs 0x48 & 0x4A | |
22784 | */ | |
22785 | ||
22786 | #include <linux/config.h> | |
22787 | @@ -28,88 +52,165 @@ | |
22788 | ||
22789 | #include "ide_modes.h" | |
22790 | ||
22791 | +/* When DEBUG is defined it outputs initial PCI config register | |
22792 | + values and changes made to them by the driver */ | |
22793 | +// #define DEBUG | |
22794 | +/* When BROKEN_LEVEL is defined it limits the DMA mode | |
22795 | + at boot time to its value */ | |
22796 | +// #define BROKEN_LEVEL XFER_SW_DMA_0 | |
22797 | #define DISPLAY_SIS_TIMINGS | |
22798 | -#define SIS5513_DEBUG_DRIVE_INFO 0 | |
22799 | ||
22800 | -static struct pci_dev *host_dev = NULL; | |
22801 | +/* Miscellaneaous flags */ | |
22802 | +#define SIS5513_LATENCY 0x01 | |
22803 | + | |
22804 | +/* registers layout and init values are chipset family dependant */ | |
22805 | +/* 1/ define families */ | |
22806 | +#define ATA_00 0x00 | |
22807 | +#define ATA_16 0x01 | |
22808 | +#define ATA_33 0x02 | |
22809 | +#define ATA_66 0x03 | |
22810 | +#define ATA_100a 0x04 // SiS730 is ATA100 with ATA66 layout | |
22811 | +#define ATA_100 0x05 | |
22812 | +#define ATA_133 0x06 | |
22813 | +/* 2/ variable holding the controller chipset family value */ | |
22814 | +static unsigned char chipset_family; | |
22815 | + | |
22816 | + | |
22817 | +/* | |
22818 | + * Debug code: following IDE config registers' changes | |
22819 | + */ | |
22820 | +#ifdef DEBUG | |
22821 | +/* Copy of IDE Config registers 0x00 -> 0x57 | |
22822 | + Fewer might be used depending on the actual chipset */ | |
22823 | +static unsigned char ide_regs_copy[0x58]; | |
22824 | + | |
22825 | +static byte sis5513_max_config_register(void) { | |
22826 | + switch(chipset_family) { | |
22827 | + case ATA_00: | |
22828 | + case ATA_16: return 0x4f; | |
22829 | + case ATA_33: return 0x52; | |
22830 | + case ATA_66: | |
22831 | + case ATA_100a: | |
22832 | + case ATA_100: | |
22833 | + case ATA_133: | |
22834 | + default: return 0x57; | |
22835 | + } | |
22836 | +} | |
22837 | + | |
22838 | +/* Read config registers, print differences from previous read */ | |
22839 | +static void sis5513_load_verify_registers(struct pci_dev* dev, char* info) { | |
22840 | + int i; | |
22841 | + byte reg_val; | |
22842 | + byte changed=0; | |
22843 | + byte max = sis5513_max_config_register(); | |
22844 | + | |
22845 | + printk("SIS5513: %s, changed registers:\n", info); | |
22846 | + for(i=0; i<=max; i++) { | |
22847 | + pci_read_config_byte(dev, i, ®_val); | |
22848 | + if (reg_val != ide_regs_copy[i]) { | |
22849 | + printk("%0#x: %0#x -> %0#x\n", | |
22850 | + i, ide_regs_copy[i], reg_val); | |
22851 | + ide_regs_copy[i]=reg_val; | |
22852 | + changed=1; | |
22853 | + } | |
22854 | + } | |
22855 | + | |
22856 | + if (!changed) { | |
22857 | + printk("none\n"); | |
22858 | + } | |
22859 | +} | |
22860 | + | |
22861 | +/* Load config registers, no printing */ | |
22862 | +static void sis5513_load_registers(struct pci_dev* dev) { | |
22863 | + int i; | |
22864 | + byte max = sis5513_max_config_register(); | |
22865 | + | |
22866 | + for(i=0; i<=max; i++) { | |
22867 | + pci_read_config_byte(dev, i, &(ide_regs_copy[i])); | |
22868 | + } | |
22869 | +} | |
22870 | + | |
22871 | +/* Print a register */ | |
22872 | +static void sis5513_print_register(int reg) { | |
22873 | + printk(" %0#x:%0#x", reg, ide_regs_copy[reg]); | |
22874 | +} | |
22875 | + | |
22876 | +/* Print valuable registers */ | |
22877 | +static void sis5513_print_registers(struct pci_dev* dev, char* marker) { | |
22878 | + int i; | |
22879 | + byte max = sis5513_max_config_register(); | |
22880 | + | |
22881 | + sis5513_load_registers(dev); | |
22882 | + printk("SIS5513 %s\n", marker); | |
22883 | + printk("SIS5513 dump:"); | |
22884 | + for(i=0x00; i<0x40; i++) { | |
22885 | + if ((i % 0x10)==0) printk("\n "); | |
22886 | + sis5513_print_register(i); | |
22887 | + } | |
22888 | + for(; i<49; i++) { | |
22889 | + sis5513_print_register(i); | |
22890 | + } | |
22891 | + printk("\n "); | |
22892 | + | |
22893 | + for(; i<=max; i++) { | |
22894 | + sis5513_print_register(i); | |
22895 | + } | |
22896 | + printk("\n"); | |
22897 | +} | |
22898 | +#endif | |
22899 | ||
22900 | -#define SIS5513_FLAG_ATA_00 0x00000000 | |
22901 | -#define SIS5513_FLAG_ATA_16 0x00000001 | |
22902 | -#define SIS5513_FLAG_ATA_33 0x00000002 | |
22903 | -#define SIS5513_FLAG_ATA_66 0x00000004 | |
22904 | -#define SIS5513_FLAG_LATENCY 0x00000010 | |
22905 | ||
22906 | +/* | |
22907 | + * Devices supported | |
22908 | + */ | |
22909 | static const struct { | |
22910 | const char *name; | |
22911 | unsigned short host_id; | |
22912 | - unsigned int flags; | |
22913 | + unsigned char chipset_family; | |
22914 | + unsigned char flags; | |
22915 | } SiSHostChipInfo[] = { | |
22916 | - { "SiS530", PCI_DEVICE_ID_SI_530, SIS5513_FLAG_ATA_66, }, | |
22917 | - { "SiS540", PCI_DEVICE_ID_SI_540, SIS5513_FLAG_ATA_66, }, | |
22918 | - { "SiS620", PCI_DEVICE_ID_SI_620, SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, }, | |
22919 | - { "SiS630", PCI_DEVICE_ID_SI_630, SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, }, | |
22920 | - { "SiS635", PCI_DEVICE_ID_SI_635, SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, }, | |
22921 | - { "SiS640", PCI_DEVICE_ID_SI_640, SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, }, | |
22922 | - { "SiS645", PCI_DEVICE_ID_SI_645, SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, }, | |
22923 | - { "SiS650", PCI_DEVICE_ID_SI_650, SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, }, | |
22924 | - { "SiS730", PCI_DEVICE_ID_SI_730, SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, }, | |
22925 | - { "SiS735", PCI_DEVICE_ID_SI_735, SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, }, | |
22926 | - { "SiS740", PCI_DEVICE_ID_SI_740, SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, }, | |
22927 | - { "SiS745", PCI_DEVICE_ID_SI_745, SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, }, | |
22928 | - { "SiS750", PCI_DEVICE_ID_SI_750, SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, }, | |
22929 | - { "SiS5591", PCI_DEVICE_ID_SI_5591, SIS5513_FLAG_ATA_33, }, | |
22930 | - { "SiS5597", PCI_DEVICE_ID_SI_5597, SIS5513_FLAG_ATA_33, }, | |
22931 | - { "SiS5600", PCI_DEVICE_ID_SI_5600, SIS5513_FLAG_ATA_33, }, | |
22932 | - { "SiS5511", PCI_DEVICE_ID_SI_5511, SIS5513_FLAG_ATA_16, }, | |
22933 | -}; | |
22934 | - | |
22935 | -#if 0 | |
22936 | - | |
22937 | -static struct _pio_mode_mapping { | |
22938 | - byte data_active; | |
22939 | - byte recovery; | |
22940 | - byte pio_mode; | |
22941 | -} pio_mode_mapping[] = { | |
22942 | - { 8, 12, 0 }, | |
22943 | - { 6, 7, 1 }, | |
22944 | - { 4, 4, 2 }, | |
22945 | - { 3, 3, 3 }, | |
22946 | - { 3, 1, 4 } | |
22947 | + { "SiS750", PCI_DEVICE_ID_SI_750, ATA_100, SIS5513_LATENCY }, | |
22948 | + { "SiS745", PCI_DEVICE_ID_SI_745, ATA_100, SIS5513_LATENCY }, | |
22949 | + { "SiS740", PCI_DEVICE_ID_SI_740, ATA_100, SIS5513_LATENCY }, | |
22950 | + { "SiS735", PCI_DEVICE_ID_SI_735, ATA_100, SIS5513_LATENCY }, | |
22951 | + { "SiS730", PCI_DEVICE_ID_SI_730, ATA_100a, SIS5513_LATENCY }, | |
22952 | + { "SiS650", PCI_DEVICE_ID_SI_650, ATA_100, SIS5513_LATENCY }, | |
22953 | + { "SiS645", PCI_DEVICE_ID_SI_645, ATA_100, SIS5513_LATENCY }, | |
22954 | + { "SiS635", PCI_DEVICE_ID_SI_635, ATA_100, SIS5513_LATENCY }, | |
22955 | + { "SiS640", PCI_DEVICE_ID_SI_640, ATA_66, SIS5513_LATENCY }, | |
22956 | + { "SiS630", PCI_DEVICE_ID_SI_630, ATA_66, SIS5513_LATENCY }, | |
22957 | + { "SiS620", PCI_DEVICE_ID_SI_620, ATA_66, SIS5513_LATENCY }, | |
22958 | + { "SiS540", PCI_DEVICE_ID_SI_540, ATA_66, 0}, | |
22959 | + { "SiS530", PCI_DEVICE_ID_SI_530, ATA_66, 0}, | |
22960 | + { "SiS5600", PCI_DEVICE_ID_SI_5600, ATA_33, 0}, | |
22961 | + { "SiS5598", PCI_DEVICE_ID_SI_5598, ATA_33, 0}, | |
22962 | + { "SiS5597", PCI_DEVICE_ID_SI_5597, ATA_33, 0}, | |
22963 | + { "SiS5591", PCI_DEVICE_ID_SI_5591, ATA_33, 0}, | |
22964 | + { "SiS5513", PCI_DEVICE_ID_SI_5513, ATA_16, 0}, | |
22965 | + { "SiS5511", PCI_DEVICE_ID_SI_5511, ATA_16, 0}, | |
22966 | }; | |
22967 | ||
22968 | -static struct _dma_mode_mapping { | |
22969 | - byte data_active; | |
22970 | - byte recovery; | |
22971 | - byte dma_mode; | |
22972 | -} dma_mode_mapping[] = { | |
22973 | - { 8, 8, 0 }, | |
22974 | - { 3, 2, 1 }, | |
22975 | - { 3, 1, 2 } | |
22976 | +/* Cycle time bits and values vary accross chip dma capabilities | |
22977 | + These three arrays hold the register layout and the values to set. | |
22978 | + Indexed by chipset_family and (dma_mode - XFER_UDMA_0) */ | |
22979 | +static byte cycle_time_offset[] = {0,0,5,4,4,0,0}; | |
22980 | +static byte cycle_time_range[] = {0,0,2,3,3,4,4}; | |
22981 | +static byte cycle_time_value[][XFER_UDMA_5 - XFER_UDMA_0 + 1] = { | |
22982 | + {0,0,0,0,0,0}, /* no udma */ | |
22983 | + {0,0,0,0,0,0}, /* no udma */ | |
22984 | + {3,2,1,0,0,0}, | |
22985 | + {7,5,3,2,1,0}, | |
22986 | + {7,5,3,2,1,0}, | |
22987 | + {11,7,5,4,2,1}, | |
22988 | + {0,0,0,0,0,0} /* not yet known, ask SiS */ | |
22989 | }; | |
22990 | ||
22991 | -static struct _udma_mode_mapping { | |
22992 | - byte cycle_time; | |
22993 | - char * udma_mode; | |
22994 | -} udma_mode_mapping[] = { | |
22995 | - { 8, "Mode 0" }, | |
22996 | - { 6, "Mode 1" }, | |
22997 | - { 4, "Mode 2" }, | |
22998 | - { 3, "Mode 3" }, | |
22999 | - { 2, "Mode 4" }, | |
23000 | - { 0, "Mode 5" } | |
23001 | -}; | |
23002 | +static struct pci_dev *host_dev = NULL; | |
23003 | ||
23004 | -static __inline__ char * find_udma_mode (byte cycle_time) | |
23005 | -{ | |
23006 | - int n; | |
23007 | - | |
23008 | - for (n = 0; n <= 4; n++) | |
23009 | - if (udma_mode_mapping[n].cycle_time <= cycle_time) | |
23010 | - return udma_mode_mapping[n].udma_mode; | |
23011 | - return udma_mode_mapping[4].udma_mode; | |
23012 | -} | |
23013 | -#endif | |
23014 | ||
23015 | +/* | |
23016 | + * Printing configuration | |
23017 | + */ | |
23018 | #if defined(DISPLAY_SIS_TIMINGS) && defined(CONFIG_PROC_FS) | |
23019 | #include <linux/stat.h> | |
23020 | #include <linux/proc_fs.h> | |
23021 | @@ -118,12 +219,12 @@ | |
23022 | extern int (*sis_display_info)(char *, char **, off_t, int); /* ide-proc.c */ | |
23023 | static struct pci_dev *bmide_dev; | |
23024 | ||
23025 | -static char *cable_type[] = { | |
23026 | +static char* cable_type[] = { | |
23027 | "80 pins", | |
23028 | "40 pins" | |
23029 | }; | |
23030 | ||
23031 | -static char *recovery_time [] ={ | |
23032 | +static char* recovery_time[] ={ | |
23033 | "12 PCICLK", "1 PCICLK", | |
23034 | "2 PCICLK", "3 PCICLK", | |
23035 | "4 PCICLK", "5 PCICLCK", | |
23036 | @@ -134,101 +235,228 @@ | |
23037 | "15 PCICLK", "15 PCICLK" | |
23038 | }; | |
23039 | ||
23040 | -static char * cycle_time [] = { | |
23041 | - "2 CLK", "2 CLK", | |
23042 | - "3 CLK", "4 CLK", | |
23043 | - "5 CLK", "6 CLK", | |
23044 | - "7 CLK", "8 CLK" | |
23045 | -}; | |
23046 | - | |
23047 | -static char * active_time [] = { | |
23048 | +static char* active_time[] = { | |
23049 | "8 PCICLK", "1 PCICLCK", | |
23050 | - "2 PCICLK", "2 PCICLK", | |
23051 | + "2 PCICLK", "3 PCICLK", | |
23052 | "4 PCICLK", "5 PCICLK", | |
23053 | "6 PCICLK", "12 PCICLK" | |
23054 | }; | |
23055 | ||
23056 | +static char* cycle_time[] = { | |
23057 | + "Reserved", "2 CLK", | |
23058 | + "3 CLK", "4 CLK", | |
23059 | + "5 CLK", "6 CLK", | |
23060 | + "7 CLK", "8 CLK", | |
23061 | + "9 CLK", "10 CLK", | |
23062 | + "11 CLK", "12 CLK", | |
23063 | + "Reserved", "Reserved", | |
23064 | + "Reserved", "Reserved" | |
23065 | +}; | |
23066 | + | |
23067 | +/* Generic add master or slave info function */ | |
23068 | +static char* get_drives_info (char *buffer, byte pos) | |
23069 | +{ | |
23070 | + byte reg00, reg01, reg10, reg11; /* timing registers */ | |
23071 | + char* p = buffer; | |
23072 | + | |
23073 | +/* Postwrite/Prefetch */ | |
23074 | + pci_read_config_byte(bmide_dev, 0x4b, ®00); | |
23075 | + p += sprintf(p, "Drive %d: Postwrite %s \t \t Postwrite %s\n", | |
23076 | + pos, (reg00 & (0x10 << pos)) ? "Enabled" : "Disabled", | |
23077 | + (reg00 & (0x40 << pos)) ? "Enabled" : "Disabled"); | |
23078 | + p += sprintf(p, " Prefetch %s \t \t Prefetch %s\n", | |
23079 | + (reg00 & (0x01 << pos)) ? "Enabled" : "Disabled", | |
23080 | + (reg00 & (0x04 << pos)) ? "Enabled" : "Disabled"); | |
23081 | + | |
23082 | + pci_read_config_byte(bmide_dev, 0x40+2*pos, ®00); | |
23083 | + pci_read_config_byte(bmide_dev, 0x41+2*pos, ®01); | |
23084 | + pci_read_config_byte(bmide_dev, 0x44+2*pos, ®10); | |
23085 | + pci_read_config_byte(bmide_dev, 0x45+2*pos, ®11); | |
23086 | + | |
23087 | +/* UDMA */ | |
23088 | + if (chipset_family >= ATA_33) { | |
23089 | + p += sprintf(p, " UDMA %s \t \t \t UDMA %s\n", | |
23090 | + (reg01 & 0x80) ? "Enabled" : "Disabled", | |
23091 | + (reg11 & 0x80) ? "Enabled" : "Disabled"); | |
23092 | + | |
23093 | + p += sprintf(p, " UDMA Cycle Time "); | |
23094 | + switch(chipset_family) { | |
23095 | + case ATA_33: p += sprintf(p, cycle_time[(reg01 & 0x60) >> 5]); break; | |
23096 | + case ATA_66: | |
23097 | + case ATA_100a: p += sprintf(p, cycle_time[(reg01 & 0x70) >> 4]); break; | |
23098 | + case ATA_100: p += sprintf(p, cycle_time[reg01 & 0x0F]); break; | |
23099 | + case ATA_133: | |
23100 | + default: p += sprintf(p, "133+ ?"); break; | |
23101 | + } | |
23102 | + p += sprintf(p, " \t UDMA Cycle Time "); | |
23103 | + switch(chipset_family) { | |
23104 | + case ATA_33: p += sprintf(p, cycle_time[(reg11 & 0x60) >> 5]); break; | |
23105 | + case ATA_66: | |
23106 | + case ATA_100a: p += sprintf(p, cycle_time[(reg11 & 0x70) >> 4]); break; | |
23107 | + case ATA_100: p += sprintf(p, cycle_time[reg11 & 0x0F]); break; | |
23108 | + case ATA_133: | |
23109 | + default: p += sprintf(p, "133+ ?"); break; | |
23110 | + } | |
23111 | + p += sprintf(p, "\n"); | |
23112 | + } | |
23113 | + | |
23114 | +/* Data Active */ | |
23115 | + p += sprintf(p, " Data Active Time "); | |
23116 | + switch(chipset_family) { | |
23117 | + case ATA_00: | |
23118 | + case ATA_16: /* confirmed */ | |
23119 | + case ATA_33: | |
23120 | + case ATA_66: | |
23121 | + case ATA_100a: p += sprintf(p, active_time[reg01 & 0x07]); break; | |
23122 | + case ATA_100: p += sprintf(p, active_time[(reg00 & 0x70) >> 4]); break; | |
23123 | + case ATA_133: | |
23124 | + default: p += sprintf(p, "133+ ?"); break; | |
23125 | + } | |
23126 | + p += sprintf(p, " \t Data Active Time "); | |
23127 | + switch(chipset_family) { | |
23128 | + case ATA_00: | |
23129 | + case ATA_16: | |
23130 | + case ATA_33: | |
23131 | + case ATA_66: | |
23132 | + case ATA_100a: p += sprintf(p, active_time[reg11 & 0x07]); break; | |
23133 | + case ATA_100: p += sprintf(p, active_time[(reg10 & 0x70) >> 4]); break; | |
23134 | + case ATA_133: | |
23135 | + default: p += sprintf(p, "133+ ?"); break; | |
23136 | + } | |
23137 | + p += sprintf(p, "\n"); | |
23138 | + | |
23139 | +/* Data Recovery */ | |
23140 | + /* warning: may need (reg&0x07) for pre ATA66 chips */ | |
23141 | + p += sprintf(p, " Data Recovery Time %s \t Data Recovery Time %s\n", | |
23142 | + recovery_time[reg00 & 0x0f], recovery_time[reg10 & 0x0f]); | |
23143 | + | |
23144 | + return p; | |
23145 | +} | |
23146 | + | |
23147 | +static char* get_masters_info(char* buffer) | |
23148 | +{ | |
23149 | + return get_drives_info(buffer, 0); | |
23150 | +} | |
23151 | + | |
23152 | +static char* get_slaves_info(char* buffer) | |
23153 | +{ | |
23154 | + return get_drives_info(buffer, 1); | |
23155 | +} | |
23156 | + | |
23157 | +/* Main get_info, called on /proc/ide/sis reads */ | |
23158 | static int sis_get_info (char *buffer, char **addr, off_t offset, int count) | |
23159 | { | |
23160 | - int rc; | |
23161 | char *p = buffer; | |
23162 | - byte reg,reg1; | |
23163 | + byte reg; | |
23164 | u16 reg2, reg3; | |
23165 | ||
23166 | - p += sprintf(p, "--------------- Primary Channel ---------------- Secondary Channel -------------\n"); | |
23167 | - rc = pci_read_config_byte(bmide_dev, 0x4a, ®); | |
23168 | - p += sprintf(p, "Channel Status: %s \t \t \t \t %s \n", | |
23169 | - (reg & 0x02) ? "On" : "Off", | |
23170 | - (reg & 0x04) ? "On" : "Off"); | |
23171 | - | |
23172 | - rc = pci_read_config_byte(bmide_dev, 0x09, ®); | |
23173 | + p += sprintf(p, "\nSiS 5513 "); | |
23174 | + switch(chipset_family) { | |
23175 | + case ATA_00: p += sprintf(p, "Unknown???"); break; | |
23176 | + case ATA_16: p += sprintf(p, "DMA 16"); break; | |
23177 | + case ATA_33: p += sprintf(p, "Ultra 33"); break; | |
23178 | + case ATA_66: p += sprintf(p, "Ultra 66"); break; | |
23179 | + case ATA_100a: | |
23180 | + case ATA_100: p += sprintf(p, "Ultra 100"); break; | |
23181 | + case ATA_133: | |
23182 | + default: p+= sprintf(p, "Ultra 133+"); break; | |
23183 | + } | |
23184 | + p += sprintf(p, " chipset\n"); | |
23185 | + p += sprintf(p, "--------------- Primary Channel " | |
23186 | + "---------------- Secondary Channel " | |
23187 | + "-------------\n"); | |
23188 | + | |
23189 | +/* Status */ | |
23190 | + pci_read_config_byte(bmide_dev, 0x4a, ®); | |
23191 | + p += sprintf(p, "Channel Status: "); | |
23192 | + if (chipset_family < ATA_66) { | |
23193 | + p += sprintf(p, "%s \t \t \t \t %s\n", | |
23194 | + (reg & 0x04) ? "On" : "Off", | |
23195 | + (reg & 0x02) ? "On" : "Off"); | |
23196 | + } else { | |
23197 | + p += sprintf(p, "%s \t \t \t \t %s \n", | |
23198 | + (reg & 0x02) ? "On" : "Off", | |
23199 | + (reg & 0x04) ? "On" : "Off"); | |
23200 | + } | |
23201 | + | |
23202 | +/* Operation Mode */ | |
23203 | + pci_read_config_byte(bmide_dev, 0x09, ®); | |
23204 | p += sprintf(p, "Operation Mode: %s \t \t \t %s \n", | |
23205 | (reg & 0x01) ? "Native" : "Compatible", | |
23206 | (reg & 0x04) ? "Native" : "Compatible"); | |
23207 | - | |
23208 | - rc = pci_read_config_byte(bmide_dev, 0x48, ®); | |
23209 | - p += sprintf(p, "Cable Type: %s \t \t \t %s\n", | |
23210 | - (reg & 0x10) ? cable_type[1] : cable_type[0], | |
23211 | - (reg & 0x20) ? cable_type[1] : cable_type[0]); | |
23212 | - | |
23213 | - rc = pci_read_config_word(bmide_dev, 0x4c, ®2); | |
23214 | - rc = pci_read_config_word(bmide_dev, 0x4e, ®3); | |
23215 | + | |
23216 | +/* 80-pin cable ? */ | |
23217 | + if (chipset_family > ATA_33) { | |
23218 | + pci_read_config_byte(bmide_dev, 0x48, ®); | |
23219 | + p += sprintf(p, "Cable Type: %s \t \t \t %s\n", | |
23220 | + (reg & 0x10) ? cable_type[1] : cable_type[0], | |
23221 | + (reg & 0x20) ? cable_type[1] : cable_type[0]); | |
23222 | + } | |
23223 | + | |
23224 | +/* Prefetch Count */ | |
23225 | + pci_read_config_word(bmide_dev, 0x4c, ®2); | |
23226 | + pci_read_config_word(bmide_dev, 0x4e, ®3); | |
23227 | p += sprintf(p, "Prefetch Count: %d \t \t \t \t %d\n", | |
23228 | reg2, reg3); | |
23229 | ||
23230 | - rc = pci_read_config_byte(bmide_dev, 0x4b, ®); | |
23231 | - p += sprintf(p, "Drive 0: Postwrite %s \t \t Postwrite %s\n", | |
23232 | - (reg & 0x10) ? "Enabled" : "Disabled", | |
23233 | - (reg & 0x40) ? "Enabled" : "Disabled"); | |
23234 | - p += sprintf(p, " Prefetch %s \t \t Prefetch %s\n", | |
23235 | - (reg & 0x01) ? "Enabled" : "Disabled", | |
23236 | - (reg & 0x04) ? "Enabled" : "Disabled"); | |
23237 | - | |
23238 | - rc = pci_read_config_byte(bmide_dev, 0x41, ®); | |
23239 | - rc = pci_read_config_byte(bmide_dev, 0x45, ®1); | |
23240 | - p += sprintf(p, " UDMA %s \t \t \t UDMA %s\n", | |
23241 | - (reg & 0x80) ? "Enabled" : "Disabled", | |
23242 | - (reg1 & 0x80) ? "Enabled" : "Disabled"); | |
23243 | - p += sprintf(p, " UDMA Cycle Time %s \t UDMA Cycle Time %s\n", | |
23244 | - cycle_time[(reg & 0x70) >> 4], cycle_time[(reg1 & 0x70) >> 4]); | |
23245 | - p += sprintf(p, " Data Active Time %s \t Data Active Time %s\n", | |
23246 | - active_time[(reg & 0x07)], active_time[(reg1 &0x07)] ); | |
23247 | + p = get_masters_info(p); | |
23248 | + p = get_slaves_info(p); | |
23249 | ||
23250 | - rc = pci_read_config_byte(bmide_dev, 0x40, ®); | |
23251 | - rc = pci_read_config_byte(bmide_dev, 0x44, ®1); | |
23252 | - p += sprintf(p, " Data Recovery Time %s \t Data Recovery Time %s\n", | |
23253 | - recovery_time[(reg & 0x0f)], recovery_time[(reg1 & 0x0f)]); | |
23254 | + return p-buffer; | |
23255 | +} | |
23256 | +#endif /* defined(DISPLAY_SIS_TIMINGS) && defined(CONFIG_PROC_FS) */ | |
23257 | ||
23258 | ||
23259 | - rc = pci_read_config_byte(bmide_dev, 0x4b, ®); | |
23260 | - p += sprintf(p, "Drive 1: Postwrite %s \t \t Postwrite %s\n", | |
23261 | - (reg & 0x20) ? "Enabled" : "Disabled", | |
23262 | - (reg & 0x80) ? "Enabled" : "Disabled"); | |
23263 | - p += sprintf(p, " Prefetch %s \t \t Prefetch %s\n", | |
23264 | - (reg & 0x02) ? "Enabled" : "Disabled", | |
23265 | - (reg & 0x08) ? "Enabled" : "Disabled"); | |
23266 | +byte sis_proc = 0; | |
23267 | ||
23268 | - rc = pci_read_config_byte(bmide_dev, 0x43, ®); | |
23269 | - rc = pci_read_config_byte(bmide_dev, 0x47, ®1); | |
23270 | - p += sprintf(p, " UDMA %s \t \t \t UDMA %s\n", | |
23271 | - (reg & 0x80) ? "Enabled" : "Disabled", | |
23272 | - (reg1 & 0x80) ? "Enabled" : "Disabled"); | |
23273 | - p += sprintf(p, " UDMA Cycle Time %s \t UDMA Cycle Time %s\n", | |
23274 | - cycle_time[(reg & 0x70) >> 4], cycle_time[(reg1 & 0x70) >> 4]); | |
23275 | - p += sprintf(p, " Data Active Time %s \t Data Active Time %s\n", | |
23276 | - active_time[(reg & 0x07)], active_time[(reg1 &0x07)] ); | |
23277 | +static byte sis5513_ratemask (ide_drive_t *drive) | |
23278 | +{ | |
23279 | +// struct pci_dev *dev = HWIF(drive)->pci_dev; | |
23280 | + byte mode = 0x00; | |
23281 | ||
23282 | - rc = pci_read_config_byte(bmide_dev, 0x42, ®); | |
23283 | - rc = pci_read_config_byte(bmide_dev, 0x46, ®1); | |
23284 | - p += sprintf(p, " Data Recovery Time %s \t Data Recovery Time %s\n", | |
23285 | - recovery_time[(reg & 0x0f)], recovery_time[(reg1 & 0x0f)]); | |
23286 | - return p-buffer; | |
23287 | + switch(chipset_family) { | |
23288 | + case ATA_133: // { mode |= 0x04; break; } | |
23289 | + case ATA_100: | |
23290 | + case ATA_100a: { mode |= 0x03; break; } | |
23291 | + case ATA_66: { mode |= 0x02; break; } | |
23292 | + case ATA_33: { mode |= 0x01; break; } | |
23293 | + case ATA_16: | |
23294 | + case ATA_00: | |
23295 | + default: | |
23296 | + return (mode &= ~0xF8); | |
23297 | + } | |
23298 | + if (!eighty_ninty_three(drive)) { | |
23299 | + mode &= ~0xFE; | |
23300 | + mode |= 0x01; | |
23301 | + } | |
23302 | + return (mode &= ~0xF8); | |
23303 | } | |
23304 | -#endif /* defined(DISPLAY_SIS_TIMINGS) && defined(CONFIG_PROC_FS) */ | |
23305 | ||
23306 | -byte sis_proc = 0; | |
23307 | -extern char *ide_xfer_verbose (byte xfer_rate); | |
23308 | +static byte sis5513_ratefilter (ide_drive_t *drive, byte speed) | |
23309 | +{ | |
23310 | +#ifdef CONFIG_BLK_DEV_IDEDMA | |
23311 | + byte mode = sis5513_ratemask(drive); | |
23312 | + | |
23313 | + switch(mode) { | |
23314 | + case 0x04: while (speed > XFER_UDMA_6) speed--; break; | |
23315 | + case 0x03: while (speed > XFER_UDMA_5) speed--; break; | |
23316 | + case 0x02: while (speed > XFER_UDMA_4) speed--; break; | |
23317 | + case 0x01: while (speed > XFER_UDMA_2) speed--; break; | |
23318 | + case 0x00: | |
23319 | + default: while (speed > XFER_MW_DMA_2) speed--; break; | |
23320 | + break; | |
23321 | + } | |
23322 | +#else | |
23323 | + while (speed > XFER_PIO_4) speed--; | |
23324 | +#endif /* CONFIG_BLK_DEV_IDEDMA */ | |
23325 | +// printk("%s: mode == %02x speed == %02x\n", drive->name, mode, speed); | |
23326 | + return speed; | |
23327 | +} | |
23328 | ||
23329 | +/* | |
23330 | + * Configuration functions | |
23331 | + */ | |
23332 | +/* Enables per-drive prefetch and postwrite */ | |
23333 | static void config_drive_art_rwp (ide_drive_t *drive) | |
23334 | { | |
23335 | ide_hwif_t *hwif = HWIF(drive); | |
23336 | @@ -237,14 +465,24 @@ | |
23337 | byte reg4bh = 0; | |
23338 | byte rw_prefetch = (0x11 << drive->dn); | |
23339 | ||
23340 | - pci_read_config_byte(dev, 0x4b, ®4bh); | |
23341 | +#ifdef DEBUG | |
23342 | + printk("SIS5513: config_drive_art_rwp, drive %d\n", drive->dn); | |
23343 | + sis5513_load_verify_registers(dev, "config_drive_art_rwp start"); | |
23344 | +#endif | |
23345 | + | |
23346 | if (drive->media != ide_disk) | |
23347 | return; | |
23348 | - | |
23349 | + pci_read_config_byte(dev, 0x4b, ®4bh); | |
23350 | + | |
23351 | if ((reg4bh & rw_prefetch) != rw_prefetch) | |
23352 | pci_write_config_byte(dev, 0x4b, reg4bh|rw_prefetch); | |
23353 | +#ifdef DEBUG | |
23354 | + sis5513_load_verify_registers(dev, "config_drive_art_rwp end"); | |
23355 | +#endif | |
23356 | } | |
23357 | ||
23358 | + | |
23359 | +/* Set per-drive active and recovery time */ | |
23360 | static void config_art_rwp_pio (ide_drive_t *drive, byte pio) | |
23361 | { | |
23362 | ide_hwif_t *hwif = HWIF(drive); | |
23363 | @@ -255,6 +493,10 @@ | |
23364 | unsigned short eide_pio_timing[6] = {600, 390, 240, 180, 120, 90}; | |
23365 | unsigned short xfer_pio = drive->id->eide_pio_modes; | |
23366 | ||
23367 | +#ifdef DEBUG | |
23368 | + sis5513_load_verify_registers(dev, "config_drive_art_rwp_pio start"); | |
23369 | +#endif | |
23370 | + | |
23371 | config_drive_art_rwp(drive); | |
23372 | pio = ide_get_best_pio_mode(drive, 255, pio, NULL); | |
23373 | ||
23374 | @@ -263,8 +505,8 @@ | |
23375 | ||
23376 | if (drive->id->eide_pio_iordy > 0) { | |
23377 | for (xfer_pio = 5; | |
23378 | - xfer_pio>0 && | |
23379 | - drive->id->eide_pio_iordy>eide_pio_timing[xfer_pio]; | |
23380 | + (xfer_pio > 0) && | |
23381 | + (drive->id->eide_pio_iordy > eide_pio_timing[xfer_pio]); | |
23382 | xfer_pio--); | |
23383 | } else { | |
23384 | xfer_pio = (drive->id->eide_pio_modes & 4) ? 0x05 : | |
23385 | @@ -274,14 +516,10 @@ | |
23386 | ||
23387 | timing = (xfer_pio >= pio) ? xfer_pio : pio; | |
23388 | ||
23389 | -/* | |
23390 | - * Mode 0 Mode 1 Mode 2 Mode 3 Mode 4 | |
23391 | - * Active time 8T (240ns) 6T (180ns) 4T (120ns) 3T (90ns) 3T (90ns) | |
23392 | - * 0x41 2:0 bits 000 110 100 011 011 | |
23393 | - * Recovery time 12T (360ns) 7T (210ns) 4T (120ns) 3T (90ns) 1T (30ns) | |
23394 | - * 0x40 3:0 bits 0000 0111 0100 0011 0001 | |
23395 | - * Cycle time 20T (600ns) 13T (390ns) 8T (240ns) 6T (180ns) 4T (120ns) | |
23396 | - */ | |
23397 | +#ifdef DEBUG | |
23398 | + printk("SIS5513: config_drive_art_rwp_pio, drive %d, pio %d, timing %d\n", | |
23399 | + drive->dn, pio, timing); | |
23400 | +#endif | |
23401 | ||
23402 | switch(drive->dn) { | |
23403 | case 0: drive_pci = 0x40; break; | |
23404 | @@ -291,31 +529,43 @@ | |
23405 | default: return; | |
23406 | } | |
23407 | ||
23408 | - pci_read_config_byte(dev, drive_pci, &test1); | |
23409 | - pci_read_config_byte(dev, drive_pci|0x01, &test2); | |
23410 | - | |
23411 | - /* | |
23412 | - * Do a blanket clear of active and recovery timings. | |
23413 | - */ | |
23414 | - | |
23415 | - test1 &= ~0x07; | |
23416 | - test2 &= ~0x0F; | |
23417 | - | |
23418 | - switch(timing) { | |
23419 | - case 4: test1 |= 0x01; test2 |= 0x03; break; | |
23420 | - case 3: test1 |= 0x03; test2 |= 0x03; break; | |
23421 | - case 2: test1 |= 0x04; test2 |= 0x04; break; | |
23422 | - case 1: test1 |= 0x07; test2 |= 0x06; break; | |
23423 | - default: break; | |
23424 | + /* register layout changed with newer ATA100 chips */ | |
23425 | + if (chipset_family < ATA_100) { | |
23426 | + pci_read_config_byte(dev, drive_pci, &test1); | |
23427 | + pci_read_config_byte(dev, drive_pci+1, &test2); | |
23428 | + | |
23429 | + /* Clear active and recovery timings */ | |
23430 | + test1 &= ~0x0F; | |
23431 | + test2 &= ~0x07; | |
23432 | + | |
23433 | + switch(timing) { | |
23434 | + case 4: test1 |= 0x01; test2 |= 0x03; break; | |
23435 | + case 3: test1 |= 0x03; test2 |= 0x03; break; | |
23436 | + case 2: test1 |= 0x04; test2 |= 0x04; break; | |
23437 | + case 1: test1 |= 0x07; test2 |= 0x06; break; | |
23438 | + default: break; | |
23439 | + } | |
23440 | + pci_write_config_byte(dev, drive_pci, test1); | |
23441 | + pci_write_config_byte(dev, drive_pci+1, test2); | |
23442 | + } else { | |
23443 | + switch(timing) { /* active recovery | |
23444 | + v v */ | |
23445 | + case 4: test1 = 0x30|0x01; break; | |
23446 | + case 3: test1 = 0x30|0x03; break; | |
23447 | + case 2: test1 = 0x40|0x04; break; | |
23448 | + case 1: test1 = 0x60|0x07; break; | |
23449 | + default: break; | |
23450 | + } | |
23451 | + pci_write_config_byte(dev, drive_pci, test1); | |
23452 | } | |
23453 | ||
23454 | - pci_write_config_byte(dev, drive_pci, test1); | |
23455 | - pci_write_config_byte(dev, drive_pci|0x01, test2); | |
23456 | +#ifdef DEBUG | |
23457 | + sis5513_load_verify_registers(dev, "config_drive_art_rwp_pio start"); | |
23458 | +#endif | |
23459 | } | |
23460 | ||
23461 | static int config_chipset_for_pio (ide_drive_t *drive, byte pio) | |
23462 | { | |
23463 | - int err; | |
23464 | byte speed; | |
23465 | ||
23466 | switch(pio) { | |
23467 | @@ -327,92 +577,86 @@ | |
23468 | } | |
23469 | ||
23470 | config_art_rwp_pio(drive, pio); | |
23471 | - drive->current_speed = speed; | |
23472 | - err = ide_config_drive_speed(drive, speed); | |
23473 | - return err; | |
23474 | + return (ide_config_drive_speed(drive, speed)); | |
23475 | } | |
23476 | ||
23477 | -static int sis5513_tune_chipset (ide_drive_t *drive, byte speed) | |
23478 | +static int sis5513_tune_chipset (ide_drive_t *drive, byte xferspeed) | |
23479 | { | |
23480 | ide_hwif_t *hwif = HWIF(drive); | |
23481 | struct pci_dev *dev = hwif->pci_dev; | |
23482 | + byte speed = sis5513_ratefilter(drive, xferspeed); | |
23483 | + byte drive_pci, reg; | |
23484 | ||
23485 | - byte drive_pci, test1, test2; | |
23486 | - byte unmask, four_two, mask = 0; | |
23487 | - | |
23488 | - if (host_dev) { | |
23489 | - switch(host_dev->device) { | |
23490 | - case PCI_DEVICE_ID_SI_530: | |
23491 | - case PCI_DEVICE_ID_SI_540: | |
23492 | - case PCI_DEVICE_ID_SI_620: | |
23493 | - case PCI_DEVICE_ID_SI_630: | |
23494 | - case PCI_DEVICE_ID_SI_635: | |
23495 | - case PCI_DEVICE_ID_SI_640: | |
23496 | - case PCI_DEVICE_ID_SI_645: | |
23497 | - case PCI_DEVICE_ID_SI_650: | |
23498 | - case PCI_DEVICE_ID_SI_730: | |
23499 | - case PCI_DEVICE_ID_SI_735: | |
23500 | - case PCI_DEVICE_ID_SI_740: | |
23501 | - case PCI_DEVICE_ID_SI_745: | |
23502 | - case PCI_DEVICE_ID_SI_750: | |
23503 | - unmask = 0xF0; | |
23504 | - four_two = 0x01; | |
23505 | - break; | |
23506 | - default: | |
23507 | - unmask = 0xE0; | |
23508 | - four_two = 0x00; | |
23509 | - break; | |
23510 | - } | |
23511 | - } else { | |
23512 | - unmask = 0xE0; | |
23513 | - four_two = 0x00; | |
23514 | - } | |
23515 | - | |
23516 | +#ifdef DEBUG | |
23517 | + sis5513_load_verify_registers(dev, "sis5513_tune_chipset start"); | |
23518 | + printk("SIS5513: sis5513_tune_chipset, drive %d, speed %d\n", | |
23519 | + drive->dn, speed); | |
23520 | +#endif | |
23521 | +#if 1 | |
23522 | switch(drive->dn) { | |
23523 | - case 0: drive_pci = 0x40;break; | |
23524 | - case 1: drive_pci = 0x42;break; | |
23525 | - case 2: drive_pci = 0x44;break; | |
23526 | - case 3: drive_pci = 0x46;break; | |
23527 | + case 0: drive_pci = 0x40; break; | |
23528 | + case 1: drive_pci = 0x42; break; | |
23529 | + case 2: drive_pci = 0x44; break; | |
23530 | + case 3: drive_pci = 0x46; break; | |
23531 | default: return ide_dma_off; | |
23532 | } | |
23533 | +#else | |
23534 | +// drive_pci = (0x40 + ((drive->dn) *2)); | |
23535 | +// drive_pci = 0x40; | |
23536 | +// drive_pci |= ((drive->dn) << 1); | |
23537 | +#endif | |
23538 | ||
23539 | - pci_read_config_byte(dev, drive_pci, &test1); | |
23540 | - pci_read_config_byte(dev, drive_pci|0x01, &test2); | |
23541 | +#ifdef BROKEN_LEVEL | |
23542 | +#ifdef DEBUG | |
23543 | + printk("SIS5513: BROKEN_LEVEL activated, speed=%d -> speed=%d\n", speed, BROKEN_LEVEL); | |
23544 | +#endif | |
23545 | + if (speed > BROKEN_LEVEL) speed = BROKEN_LEVEL; | |
23546 | +#endif | |
23547 | ||
23548 | - if ((speed <= XFER_MW_DMA_2) && (test2 & 0x80)) { | |
23549 | - pci_write_config_byte(dev, drive_pci|0x01, test2 & ~0x80); | |
23550 | - pci_read_config_byte(dev, drive_pci|0x01, &test2); | |
23551 | - } else { | |
23552 | - pci_write_config_byte(dev, drive_pci|0x01, test2 & ~unmask); | |
23553 | + pci_read_config_byte(dev, drive_pci+1, ®); | |
23554 | + /* Disable UDMA bit for non UDMA modes on UDMA chips */ | |
23555 | + if ((speed < XFER_UDMA_0) && (chipset_family > ATA_16)) { | |
23556 | + reg &= 0x7F; | |
23557 | + pci_write_config_byte(dev, drive_pci+1, reg); | |
23558 | } | |
23559 | ||
23560 | + /* Config chip for mode */ | |
23561 | switch(speed) { | |
23562 | #ifdef CONFIG_BLK_DEV_IDEDMA | |
23563 | - case XFER_UDMA_5: mask = 0x80; break; | |
23564 | - case XFER_UDMA_4: mask = 0x90; break; | |
23565 | - case XFER_UDMA_3: mask = 0xA0; break; | |
23566 | - case XFER_UDMA_2: mask = (four_two) ? 0xB0 : 0xA0; break; | |
23567 | - case XFER_UDMA_1: mask = (four_two) ? 0xD0 : 0xC0; break; | |
23568 | - case XFER_UDMA_0: mask = unmask; break; | |
23569 | + case XFER_UDMA_5: | |
23570 | + case XFER_UDMA_4: | |
23571 | + case XFER_UDMA_3: | |
23572 | + case XFER_UDMA_2: | |
23573 | + case XFER_UDMA_1: | |
23574 | + case XFER_UDMA_0: | |
23575 | + /* Force the UDMA bit on if we want to use UDMA */ | |
23576 | + reg |= 0x80; | |
23577 | + /* clean reg cycle time bits */ | |
23578 | + reg &= ~((0xFF >> (8 - cycle_time_range[chipset_family])) | |
23579 | + << cycle_time_offset[chipset_family]); | |
23580 | + /* set reg cycle time bits */ | |
23581 | + reg |= cycle_time_value[chipset_family-ATA_00][speed-XFER_UDMA_0] | |
23582 | + << cycle_time_offset[chipset_family]; | |
23583 | + pci_write_config_byte(dev, drive_pci+1, reg); | |
23584 | + break; | |
23585 | case XFER_MW_DMA_2: | |
23586 | case XFER_MW_DMA_1: | |
23587 | case XFER_MW_DMA_0: | |
23588 | case XFER_SW_DMA_2: | |
23589 | case XFER_SW_DMA_1: | |
23590 | - case XFER_SW_DMA_0: break; | |
23591 | + case XFER_SW_DMA_0: | |
23592 | + break; | |
23593 | #endif /* CONFIG_BLK_DEV_IDEDMA */ | |
23594 | case XFER_PIO_4: return((int) config_chipset_for_pio(drive, 4)); | |
23595 | case XFER_PIO_3: return((int) config_chipset_for_pio(drive, 3)); | |
23596 | case XFER_PIO_2: return((int) config_chipset_for_pio(drive, 2)); | |
23597 | case XFER_PIO_1: return((int) config_chipset_for_pio(drive, 1)); | |
23598 | case XFER_PIO_0: | |
23599 | - default: return((int) config_chipset_for_pio(drive, 0)); | |
23600 | + default: return((int) config_chipset_for_pio(drive, 0)); | |
23601 | } | |
23602 | - | |
23603 | - if (speed > XFER_MW_DMA_2) | |
23604 | - pci_write_config_byte(dev, drive_pci|0x01, test2|mask); | |
23605 | - | |
23606 | - drive->current_speed = speed; | |
23607 | +#ifdef DEBUG | |
23608 | + sis5513_load_verify_registers(dev, "sis5513_tune_chipset end"); | |
23609 | +#endif | |
23610 | return ((int) ide_config_drive_speed(drive, speed)); | |
23611 | } | |
23612 | ||
23613 | @@ -425,77 +669,56 @@ | |
23614 | /* | |
23615 | * ((id->hw_config & 0x4000|0x2000) && (HWIF(drive)->udma_four)) | |
23616 | */ | |
23617 | -static int config_chipset_for_dma (ide_drive_t *drive, byte ultra) | |
23618 | +static int config_chipset_for_dma (ide_drive_t *drive) | |
23619 | { | |
23620 | struct hd_driveid *id = drive->id; | |
23621 | - ide_hwif_t *hwif = HWIF(drive); | |
23622 | - | |
23623 | - byte four_two = 0, speed = 0; | |
23624 | - int err; | |
23625 | + byte mode = sis5513_ratemask(drive); | |
23626 | + byte speed = 0; | |
23627 | ||
23628 | - byte unit = (drive->select.b.unit & 0x01); | |
23629 | - byte udma_66 = eighty_ninty_three(drive); | |
23630 | - byte ultra_100 = 0; | |
23631 | +#ifdef DEBUG | |
23632 | + printk("SIS5513: config_chipset_for_dma, drive %d ultra %d\n", | |
23633 | + drive->dn, mode); | |
23634 | +#endif | |
23635 | ||
23636 | - if (host_dev) { | |
23637 | - switch(host_dev->device) { | |
23638 | - case PCI_DEVICE_ID_SI_635: | |
23639 | - case PCI_DEVICE_ID_SI_640: | |
23640 | - case PCI_DEVICE_ID_SI_645: | |
23641 | - case PCI_DEVICE_ID_SI_650: | |
23642 | - case PCI_DEVICE_ID_SI_730: | |
23643 | - case PCI_DEVICE_ID_SI_735: | |
23644 | - case PCI_DEVICE_ID_SI_740: | |
23645 | - case PCI_DEVICE_ID_SI_745: | |
23646 | - case PCI_DEVICE_ID_SI_750: | |
23647 | - ultra_100 = 1; | |
23648 | - case PCI_DEVICE_ID_SI_530: | |
23649 | - case PCI_DEVICE_ID_SI_540: | |
23650 | - case PCI_DEVICE_ID_SI_620: | |
23651 | - case PCI_DEVICE_ID_SI_630: | |
23652 | - four_two = 0x01; | |
23653 | - break; | |
23654 | - default: | |
23655 | - four_two = 0x00; break; | |
23656 | - } | |
23657 | + switch(mode) { | |
23658 | + case 0x04: | |
23659 | + if (id->dma_ultra & 0x0040) | |
23660 | + { speed = XFER_UDMA_6; break; } | |
23661 | + case 0x03: | |
23662 | + if (id->dma_ultra & 0x0020) | |
23663 | + { speed = XFER_UDMA_5; break; } | |
23664 | + case 0x02: | |
23665 | + if (id->dma_ultra & 0x0010) | |
23666 | + { speed = XFER_UDMA_4; break; } | |
23667 | + if (id->dma_ultra & 0x0008) | |
23668 | + { speed = XFER_UDMA_3; break; } | |
23669 | + case 0x01: | |
23670 | + if (id->dma_ultra & 0x0004) | |
23671 | + { speed = XFER_UDMA_2; break; } | |
23672 | + if (id->dma_ultra & 0x0002) | |
23673 | + { speed = XFER_UDMA_1; break; } | |
23674 | + if (id->dma_ultra & 0x0001) | |
23675 | + { speed = XFER_UDMA_0; break; } | |
23676 | + case 0x00: | |
23677 | + if (id->dma_mword & 0x0004) | |
23678 | + { speed = XFER_MW_DMA_2; break; } | |
23679 | + if (id->dma_mword & 0x0002) | |
23680 | + { speed = XFER_MW_DMA_1; break; } | |
23681 | + if (id->dma_mword & 0x0001) | |
23682 | + { speed = XFER_MW_DMA_0; break; } | |
23683 | + if (id->dma_1word & 0x0004) | |
23684 | + { speed = XFER_SW_DMA_2; break; } | |
23685 | + if (id->dma_1word & 0x0002) | |
23686 | + { speed = XFER_SW_DMA_1; break; } | |
23687 | + if (id->dma_1word & 0x0001) | |
23688 | + { speed = XFER_SW_DMA_0; break; } | |
23689 | + default: | |
23690 | + return ((int) ide_dma_off_quietly); | |
23691 | } | |
23692 | - | |
23693 | - if ((id->dma_ultra & 0x0020) && (ultra) && (udma_66) && (four_two) && (ultra_100)) | |
23694 | - speed = XFER_UDMA_5; | |
23695 | - else if ((id->dma_ultra & 0x0010) && (ultra) && (udma_66) && (four_two)) | |
23696 | - speed = XFER_UDMA_4; | |
23697 | - else if ((id->dma_ultra & 0x0008) && (ultra) && (udma_66) && (four_two)) | |
23698 | - speed = XFER_UDMA_3; | |
23699 | - else if ((id->dma_ultra & 0x0004) && (ultra)) | |
23700 | - speed = XFER_UDMA_2; | |
23701 | - else if ((id->dma_ultra & 0x0002) && (ultra)) | |
23702 | - speed = XFER_UDMA_1; | |
23703 | - else if ((id->dma_ultra & 0x0001) && (ultra)) | |
23704 | - speed = XFER_UDMA_0; | |
23705 | - else if (id->dma_mword & 0x0004) | |
23706 | - speed = XFER_MW_DMA_2; | |
23707 | - else if (id->dma_mword & 0x0002) | |
23708 | - speed = XFER_MW_DMA_1; | |
23709 | - else if (id->dma_mword & 0x0001) | |
23710 | - speed = XFER_MW_DMA_0; | |
23711 | - else if (id->dma_1word & 0x0004) | |
23712 | - speed = XFER_SW_DMA_2; | |
23713 | - else if (id->dma_1word & 0x0002) | |
23714 | - speed = XFER_SW_DMA_1; | |
23715 | - else if (id->dma_1word & 0x0001) | |
23716 | - speed = XFER_SW_DMA_0; | |
23717 | - else | |
23718 | - return ((int) ide_dma_off_quietly); | |
23719 | - | |
23720 | - outb(inb(hwif->dma_base+2)|(1<<(5+unit)), hwif->dma_base+2); | |
23721 | - | |
23722 | - err = sis5513_tune_chipset(drive, speed); | |
23723 | - | |
23724 | -#if SIS5513_DEBUG_DRIVE_INFO | |
23725 | - printk("%s: %s drive%d\n", drive->name, ide_xfer_verbose(speed), drive->dn); | |
23726 | -#endif /* SIS5513_DEBUG_DRIVE_INFO */ | |
23727 | - | |
23728 | - return ((int) ((id->dma_ultra >> 11) & 7) ? ide_dma_on : | |
23729 | + sis5513_tune_chipset(drive, speed); | |
23730 | +// return ((int) ide_dma_on); | |
23731 | + return ((int) ((id->dma_ultra >> 14) & 3) ? ide_dma_on : | |
23732 | + ((id->dma_ultra >> 11) & 7) ? ide_dma_on : | |
23733 | ((id->dma_ultra >> 8) & 7) ? ide_dma_on : | |
23734 | ((id->dma_mword >> 8) & 7) ? ide_dma_on : | |
23735 | ((id->dma_1word >> 8) & 7) ? ide_dma_on : | |
23736 | @@ -507,6 +730,8 @@ | |
23737 | struct hd_driveid *id = drive->id; | |
23738 | ide_dma_action_t dma_func = ide_dma_off_quietly; | |
23739 | ||
23740 | + drive->init_speed = 0; | |
23741 | + | |
23742 | if (id && (id->capability & 1) && HWIF(drive)->autodma) { | |
23743 | /* Consult the list of known "bad" drives */ | |
23744 | if (ide_dmaproc(ide_dma_bad_drive, drive)) { | |
23745 | @@ -517,7 +742,7 @@ | |
23746 | if (id->field_valid & 4) { | |
23747 | if (id->dma_ultra & 0x003F) { | |
23748 | /* Force if Capable UltraDMA */ | |
23749 | - dma_func = config_chipset_for_dma(drive, 1); | |
23750 | + dma_func = config_chipset_for_dma(drive); | |
23751 | if ((id->field_valid & 2) && | |
23752 | (dma_func != ide_dma_on)) | |
23753 | goto try_dma_modes; | |
23754 | @@ -527,14 +752,14 @@ | |
23755 | if ((id->dma_mword & 0x0007) || | |
23756 | (id->dma_1word & 0x0007)) { | |
23757 | /* Force if Capable regular DMA modes */ | |
23758 | - dma_func = config_chipset_for_dma(drive, 0); | |
23759 | + dma_func = config_chipset_for_dma(drive); | |
23760 | if (dma_func != ide_dma_on) | |
23761 | goto no_dma_set; | |
23762 | } | |
23763 | } else if ((ide_dmaproc(ide_dma_good_drive, drive)) && | |
23764 | (id->eide_dma_time > 150)) { | |
23765 | /* Consult the list of known "good" drives */ | |
23766 | - dma_func = config_chipset_for_dma(drive, 0); | |
23767 | + dma_func = config_chipset_for_dma(drive); | |
23768 | if (dma_func != ide_dma_on) | |
23769 | goto no_dma_set; | |
23770 | } else { | |
23771 | @@ -544,15 +769,13 @@ | |
23772 | fast_ata_pio: | |
23773 | dma_func = ide_dma_off_quietly; | |
23774 | no_dma_set: | |
23775 | - (void) config_chipset_for_pio(drive, 5); | |
23776 | + sis5513_tune_drive(drive, 5); | |
23777 | } | |
23778 | ||
23779 | return HWIF(drive)->dmaproc(dma_func, drive); | |
23780 | } | |
23781 | ||
23782 | -/* | |
23783 | - * sis5513_dmaproc() initiates/aborts (U)DMA read/write operations on a drive. | |
23784 | - */ | |
23785 | +/* initiates/aborts (U)DMA read/write operations on a drive. */ | |
23786 | int sis5513_dmaproc (ide_dma_action_t func, ide_drive_t *drive) | |
23787 | { | |
23788 | switch (func) { | |
23789 | @@ -567,15 +790,14 @@ | |
23790 | } | |
23791 | #endif /* CONFIG_BLK_DEV_IDEDMA */ | |
23792 | ||
23793 | +/* Chip detection and general config */ | |
23794 | unsigned int __init pci_init_sis5513 (struct pci_dev *dev, const char *name) | |
23795 | { | |
23796 | struct pci_dev *host; | |
23797 | int i = 0; | |
23798 | - byte latency = 0; | |
23799 | - | |
23800 | - pci_read_config_byte(dev, PCI_LATENCY_TIMER, &latency); | |
23801 | ||
23802 | - for (i = 0; i < ARRAY_SIZE (SiSHostChipInfo) && !host_dev; i++) { | |
23803 | + /* Find the chip */ | |
23804 | + for (i = 0; i < ARRAY_SIZE(SiSHostChipInfo) && !host_dev; i++) { | |
23805 | host = pci_find_device (PCI_VENDOR_ID_SI, | |
23806 | SiSHostChipInfo[i].host_id, | |
23807 | NULL); | |
23808 | @@ -583,30 +805,71 @@ | |
23809 | continue; | |
23810 | ||
23811 | host_dev = host; | |
23812 | + chipset_family = SiSHostChipInfo[i].chipset_family; | |
23813 | printk(SiSHostChipInfo[i].name); | |
23814 | printk("\n"); | |
23815 | - if (SiSHostChipInfo[i].flags & SIS5513_FLAG_LATENCY) { | |
23816 | - if (latency != 0x10) | |
23817 | - pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x10); | |
23818 | + | |
23819 | +#ifdef DEBUG | |
23820 | + sis5513_print_registers(dev, "pci_init_sis5513 start"); | |
23821 | +#endif | |
23822 | + | |
23823 | + if (SiSHostChipInfo[i].flags & SIS5513_LATENCY) { | |
23824 | + byte latency = (chipset_family == ATA_100)? 0x80 : 0x10; /* Lacking specs */ | |
23825 | + pci_write_config_byte(dev, PCI_LATENCY_TIMER, latency); | |
23826 | } | |
23827 | } | |
23828 | ||
23829 | + /* Make general config ops here | |
23830 | + 1/ tell IDE channels to operate in Compabitility mode only | |
23831 | + 2/ tell old chips to allow per drive IDE timings */ | |
23832 | if (host_dev) { | |
23833 | - byte reg52h = 0; | |
23834 | - | |
23835 | - pci_read_config_byte(dev, 0x52, ®52h); | |
23836 | - if (!(reg52h & 0x04)) { | |
23837 | - /* set IDE controller to operate in Compabitility mode only */ | |
23838 | - pci_write_config_byte(dev, 0x52, reg52h|0x04); | |
23839 | + byte reg; | |
23840 | + switch(chipset_family) { | |
23841 | + case ATA_133: | |
23842 | + case ATA_100: | |
23843 | + /* Set compatibility bit */ | |
23844 | + pci_read_config_byte(dev, 0x49, ®); | |
23845 | + if (!(reg & 0x01)) { | |
23846 | + pci_write_config_byte(dev, 0x49, reg|0x01); | |
23847 | + } | |
23848 | + break; | |
23849 | + case ATA_100a: | |
23850 | + case ATA_66: | |
23851 | + /* On ATA_66 chips the bit was elsewhere */ | |
23852 | + pci_read_config_byte(dev, 0x52, ®); | |
23853 | + if (!(reg & 0x04)) { | |
23854 | + pci_write_config_byte(dev, 0x52, reg|0x04); | |
23855 | + } | |
23856 | + break; | |
23857 | + case ATA_33: | |
23858 | + /* On ATA_33 we didn't have a single bit to set */ | |
23859 | + pci_read_config_byte(dev, 0x09, ®); | |
23860 | + if ((reg & 0x0f) != 0x00) { | |
23861 | + pci_write_config_byte(dev, 0x09, reg&0xf0); | |
23862 | + } | |
23863 | + case ATA_16: | |
23864 | + /* force per drive recovery and active timings | |
23865 | + needed on ATA_33 and below chips */ | |
23866 | + pci_read_config_byte(dev, 0x52, ®); | |
23867 | + if (!(reg & 0x08)) { | |
23868 | + pci_write_config_byte(dev, 0x52, reg|0x08); | |
23869 | + } | |
23870 | + break; | |
23871 | + case ATA_00: | |
23872 | + default: break; | |
23873 | } | |
23874 | + | |
23875 | #if defined(DISPLAY_SIS_TIMINGS) && defined(CONFIG_PROC_FS) | |
23876 | if (!sis_proc) { | |
23877 | sis_proc = 1; | |
23878 | bmide_dev = dev; | |
23879 | sis_display_info = &sis_get_info; | |
23880 | } | |
23881 | -#endif /* defined(DISPLAY_SIS_TIMINGS) && defined(CONFIG_PROC_FS) */ | |
23882 | +#endif | |
23883 | } | |
23884 | +#ifdef DEBUG | |
23885 | + sis5513_load_verify_registers(dev, "pci_init_sis5513 end"); | |
23886 | +#endif | |
23887 | return 0; | |
23888 | } | |
23889 | ||
23890 | @@ -616,27 +879,10 @@ | |
23891 | byte mask = hwif->channel ? 0x20 : 0x10; | |
23892 | pci_read_config_byte(hwif->pci_dev, 0x48, ®48h); | |
23893 | ||
23894 | - if (host_dev) { | |
23895 | - switch(host_dev->device) { | |
23896 | - case PCI_DEVICE_ID_SI_530: | |
23897 | - case PCI_DEVICE_ID_SI_540: | |
23898 | - case PCI_DEVICE_ID_SI_620: | |
23899 | - case PCI_DEVICE_ID_SI_630: | |
23900 | - case PCI_DEVICE_ID_SI_635: | |
23901 | - case PCI_DEVICE_ID_SI_640: | |
23902 | - case PCI_DEVICE_ID_SI_645: | |
23903 | - case PCI_DEVICE_ID_SI_650: | |
23904 | - case PCI_DEVICE_ID_SI_730: | |
23905 | - case PCI_DEVICE_ID_SI_735: | |
23906 | - case PCI_DEVICE_ID_SI_740: | |
23907 | - case PCI_DEVICE_ID_SI_745: | |
23908 | - case PCI_DEVICE_ID_SI_750: | |
23909 | - ata66 = (reg48h & mask) ? 0 : 1; | |
23910 | - default: | |
23911 | - break; | |
23912 | - } | |
23913 | + if (chipset_family >= ATA_66) { | |
23914 | + ata66 = (reg48h & mask) ? 0 : 1; | |
23915 | } | |
23916 | - return (ata66); | |
23917 | + return ata66; | |
23918 | } | |
23919 | ||
23920 | void __init ide_init_sis5513 (ide_hwif_t *hwif) | |
23921 | @@ -646,38 +892,36 @@ | |
23922 | ||
23923 | hwif->tuneproc = &sis5513_tune_drive; | |
23924 | hwif->speedproc = &sis5513_tune_chipset; | |
23925 | + hwif->drives[0].autotune = 1; | |
23926 | + hwif->drives[1].autotune = 1; | |
23927 | + hwif->autodma = 0; | |
23928 | ||
23929 | if (!(hwif->dma_base)) | |
23930 | return; | |
23931 | ||
23932 | - if (host_dev) { | |
23933 | - switch(host_dev->device) { | |
23934 | #ifdef CONFIG_BLK_DEV_IDEDMA | |
23935 | - case PCI_DEVICE_ID_SI_530: | |
23936 | - case PCI_DEVICE_ID_SI_540: | |
23937 | - case PCI_DEVICE_ID_SI_620: | |
23938 | - case PCI_DEVICE_ID_SI_630: | |
23939 | - case PCI_DEVICE_ID_SI_635: | |
23940 | - case PCI_DEVICE_ID_SI_640: | |
23941 | - case PCI_DEVICE_ID_SI_645: | |
23942 | - case PCI_DEVICE_ID_SI_650: | |
23943 | - case PCI_DEVICE_ID_SI_730: | |
23944 | - case PCI_DEVICE_ID_SI_735: | |
23945 | - case PCI_DEVICE_ID_SI_740: | |
23946 | - case PCI_DEVICE_ID_SI_745: | |
23947 | - case PCI_DEVICE_ID_SI_750: | |
23948 | - case PCI_DEVICE_ID_SI_5600: | |
23949 | - case PCI_DEVICE_ID_SI_5597: | |
23950 | - case PCI_DEVICE_ID_SI_5591: | |
23951 | - if (!noautodma) | |
23952 | - hwif->autodma = 1; | |
23953 | - hwif->dmaproc = &sis5513_dmaproc; | |
23954 | - break; | |
23955 | + if (host_dev) { | |
23956 | + if (chipset_family > ATA_16) | |
23957 | + hwif->dmaproc = &sis5513_dmaproc; | |
23958 | + else | |
23959 | + hwif->autodma = 0; | |
23960 | + } | |
23961 | +# ifdef CONFIG_IDEDMA_AUTO | |
23962 | + if (!noautodma) | |
23963 | + hwif->autodma = 1; | |
23964 | +# endif /* CONFIG_IDEDMA_AUTO */ | |
23965 | #endif /* CONFIG_BLK_DEV_IDEDMA */ | |
23966 | - default: | |
23967 | - hwif->autodma = 0; | |
23968 | - break; | |
23969 | - } | |
23970 | - } | |
23971 | return; | |
23972 | } | |
23973 | + | |
23974 | +extern void ide_setup_pci_device (struct pci_dev *dev, ide_pci_device_t *d); | |
23975 | + | |
23976 | +void __init fixup_device_sis5513 (struct pci_dev *dev, ide_pci_device_t *d) | |
23977 | +{ | |
23978 | + if (dev->resource[0].start != 0x01F1) | |
23979 | + ide_register_xp_fix(dev); | |
23980 | + | |
23981 | + printk("%s: IDE controller on PCI bus %02x dev %02x\n", | |
23982 | + d->name, dev->bus->number, dev->devfn); | |
23983 | + ide_setup_pci_device(dev, d); | |
23984 | +} | |
23985 | diff -Nur linux.org/drivers/ide/sl82c105.c linux/drivers/ide/sl82c105.c | |
23986 | --- linux.org/drivers/ide/sl82c105.c Fri Sep 7 19:45:30 2001 | |
23987 | +++ linux/drivers/ide/sl82c105.c Thu Jul 18 14:24:34 2002 | |
23988 | @@ -26,8 +26,6 @@ | |
23989 | ||
23990 | #include "ide_modes.h" | |
23991 | ||
23992 | -extern char *ide_xfer_verbose (byte xfer_rate); | |
23993 | - | |
23994 | /* | |
23995 | * Convert a PIO mode and cycle time to the required on/off | |
23996 | * times for the interface. This has protection against run-away | |
23997 | @@ -243,7 +241,7 @@ | |
23998 | unsigned int rev; | |
23999 | byte dma_state; | |
24000 | ||
24001 | - dma_state = inb(dma_base + 2); | |
24002 | + dma_state = IN_BYTE(dma_base + 2); | |
24003 | rev = sl82c105_bridge_revision(hwif->pci_dev); | |
24004 | if (rev <= 5) { | |
24005 | hwif->autodma = 0; | |
24006 | @@ -256,7 +254,7 @@ | |
24007 | dma_state |= 0x60; | |
24008 | hwif->autodma = 1; | |
24009 | } | |
24010 | - outb(dma_state, dma_base + 2); | |
24011 | + OUT_BYTE(dma_state, dma_base + 2); | |
24012 | ||
24013 | hwif->dmaproc = NULL; | |
24014 | ide_setup_dma(hwif, dma_base, 8); | |
24015 | diff -Nur linux.org/drivers/ide/slc90e66.c linux/drivers/ide/slc90e66.c | |
24016 | --- linux.org/drivers/ide/slc90e66.c Mon Jul 16 01:22:23 2001 | |
24017 | +++ linux/drivers/ide/slc90e66.c Thu Jul 18 14:24:34 2002 | |
24018 | @@ -60,7 +60,6 @@ | |
24019 | ||
24020 | static int slc90e66_get_info(char *, char **, off_t, int); | |
24021 | extern int (*slc90e66_display_info)(char *, char **, off_t, int); /* ide-proc.c */ | |
24022 | -extern char *ide_media_verbose(ide_drive_t *); | |
24023 | static struct pci_dev *bmide_dev; | |
24024 | ||
24025 | static int slc90e66_get_info (char *buffer, char **addr, off_t offset, int count) | |
24026 | @@ -86,26 +85,38 @@ | |
24027 | * at that point bibma+0x2 et bibma+0xa are byte registers | |
24028 | * to investigate: | |
24029 | */ | |
24030 | +#ifdef __mips__ /* only for mips? */ | |
24031 | + c0 = inb_p(bibma + 0x02); | |
24032 | + c1 = inb_p(bibma + 0x0a); | |
24033 | +#else | |
24034 | c0 = inb_p((unsigned short)bibma + 0x02); | |
24035 | c1 = inb_p((unsigned short)bibma + 0x0a); | |
24036 | +#endif | |
24037 | ||
24038 | p += sprintf(p, " SLC90E66 Chipset.\n"); | |
24039 | - p += sprintf(p, "--------------- Primary Channel ---------------- Secondary Channel -------------\n"); | |
24040 | - p += sprintf(p, " %sabled %sabled\n", | |
24041 | + p += sprintf(p, "--------------- Primary Channel " | |
24042 | + "---------------- Secondary Channel " | |
24043 | + "-------------\n"); | |
24044 | + p += sprintf(p, " %sabled " | |
24045 | + " %sabled\n", | |
24046 | (c0&0x80) ? "dis" : " en", | |
24047 | (c1&0x80) ? "dis" : " en"); | |
24048 | - p += sprintf(p, "--------------- drive0 --------- drive1 -------- drive0 ---------- drive1 ------\n"); | |
24049 | - p += sprintf(p, "DMA enabled: %s %s %s %s\n", | |
24050 | + p += sprintf(p, "--------------- drive0 --------- drive1 " | |
24051 | + "-------- drive0 ---------- drive1 ------\n"); | |
24052 | + p += sprintf(p, "DMA enabled: %s %s " | |
24053 | + " %s %s\n", | |
24054 | (c0&0x20) ? "yes" : "no ", | |
24055 | (c0&0x40) ? "yes" : "no ", | |
24056 | (c1&0x20) ? "yes" : "no ", | |
24057 | (c1&0x40) ? "yes" : "no " ); | |
24058 | - p += sprintf(p, "UDMA enabled: %s %s %s %s\n", | |
24059 | + p += sprintf(p, "UDMA enabled: %s %s " | |
24060 | + " %s %s\n", | |
24061 | (reg48&0x01) ? "yes" : "no ", | |
24062 | (reg48&0x02) ? "yes" : "no ", | |
24063 | (reg48&0x04) ? "yes" : "no ", | |
24064 | (reg48&0x08) ? "yes" : "no " ); | |
24065 | - p += sprintf(p, "UDMA enabled: %s %s %s %s\n", | |
24066 | + p += sprintf(p, "UDMA enabled: %s %s " | |
24067 | + " %s %s\n", | |
24068 | ((reg4a&0x04)==0x04) ? "4" : | |
24069 | ((reg4a&0x03)==0x03) ? "3" : | |
24070 | (reg4a&0x02) ? "2" : | |
24071 | @@ -145,12 +156,40 @@ | |
24072 | ||
24073 | byte slc90e66_proc = 0; | |
24074 | ||
24075 | -extern char *ide_xfer_verbose (byte xfer_rate); | |
24076 | +static byte slc90e66_ratemask (ide_drive_t *drive) | |
24077 | +{ | |
24078 | + byte mode = 0x00; | |
24079 | + | |
24080 | + mode |= 0x02; | |
24081 | + | |
24082 | + if (!eighty_ninty_three(drive)) { | |
24083 | + mode &= ~0xFE; | |
24084 | + mode |= 0x01; | |
24085 | + } | |
24086 | + return (mode &= ~0xF8); | |
24087 | +} | |
24088 | ||
24089 | +static byte slc90e66_ratefilter (ide_drive_t *drive, byte speed) | |
24090 | +{ | |
24091 | #ifdef CONFIG_BLK_DEV_IDEDMA | |
24092 | -/* | |
24093 | - * | |
24094 | - */ | |
24095 | + byte mode = slc90e66_ratemask(drive); | |
24096 | + | |
24097 | + switch(mode) { | |
24098 | + case 0x04: // while (speed > XFER_UDMA_6) speed--; break; | |
24099 | + case 0x03: // while (speed > XFER_UDMA_5) speed--; break; | |
24100 | + case 0x02: while (speed > XFER_UDMA_4) speed--; break; | |
24101 | + case 0x01: while (speed > XFER_UDMA_2) speed--; break; | |
24102 | + case 0x00: | |
24103 | + default: while (speed > XFER_MW_DMA_2) speed--; break; | |
24104 | + break; | |
24105 | + } | |
24106 | +#else | |
24107 | + while (speed > XFER_PIO_4) speed--; | |
24108 | +#endif /* CONFIG_BLK_DEV_IDEDMA */ | |
24109 | +// printk("%s: mode == %02x speed == %02x\n", drive->name, mode, speed); | |
24110 | + return speed; | |
24111 | +} | |
24112 | + | |
24113 | static byte slc90e66_dma_2_pio (byte xfer_rate) { | |
24114 | switch(xfer_rate) { | |
24115 | case XFER_UDMA_4: | |
24116 | @@ -177,7 +216,6 @@ | |
24117 | return 0; | |
24118 | } | |
24119 | } | |
24120 | -#endif /* CONFIG_BLK_DEV_IDEDMA */ | |
24121 | ||
24122 | /* | |
24123 | * Based on settings done by AMI BIOS | |
24124 | @@ -185,12 +223,14 @@ | |
24125 | */ | |
24126 | static void slc90e66_tune_drive (ide_drive_t *drive, byte pio) | |
24127 | { | |
24128 | + ide_hwif_t *hwif = HWIF(drive); | |
24129 | + struct pci_dev *dev = hwif->pci_dev; | |
24130 | + int is_slave = (&hwif->drives[1] == drive); | |
24131 | + int master_port = hwif->channel ? 0x42 : 0x40; | |
24132 | + int slave_port = 0x44; | |
24133 | unsigned long flags; | |
24134 | u16 master_data; | |
24135 | byte slave_data; | |
24136 | - int is_slave = (&HWIF(drive)->drives[1] == drive); | |
24137 | - int master_port = HWIF(drive)->index ? 0x42 : 0x40; | |
24138 | - int slave_port = 0x44; | |
24139 | /* ISP RTC */ | |
24140 | byte timings[][2] = { { 0, 0 }, | |
24141 | { 0, 0 }, | |
24142 | @@ -199,42 +239,38 @@ | |
24143 | { 2, 3 }, }; | |
24144 | ||
24145 | pio = ide_get_best_pio_mode(drive, pio, 5, NULL); | |
24146 | - pci_read_config_word(HWIF(drive)->pci_dev, master_port, &master_data); | |
24147 | + spin_lock_irqsave(&io_request_lock, flags); | |
24148 | + pci_read_config_word(dev, master_port, &master_data); | |
24149 | if (is_slave) { | |
24150 | master_data = master_data | 0x4000; | |
24151 | if (pio > 1) | |
24152 | /* enable PPE, IE and TIME */ | |
24153 | master_data = master_data | 0x0070; | |
24154 | - pci_read_config_byte(HWIF(drive)->pci_dev, slave_port, &slave_data); | |
24155 | - slave_data = slave_data & (HWIF(drive)->index ? 0x0f : 0xf0); | |
24156 | - slave_data = slave_data | ((timings[pio][0] << 2) | (timings[pio][1] | |
24157 | - << (HWIF(drive)->index ? 4 : 0))); | |
24158 | + pci_read_config_byte(dev, slave_port, &slave_data); | |
24159 | + slave_data = slave_data & (hwif->channel ? 0x0f : 0xf0); | |
24160 | + slave_data = slave_data | (((timings[pio][0] << 2) | timings[pio][1]) << (hwif->channel ? 4 : 0)); | |
24161 | } else { | |
24162 | master_data = master_data & 0xccf8; | |
24163 | if (pio > 1) | |
24164 | /* enable PPE, IE and TIME */ | |
24165 | master_data = master_data | 0x0007; | |
24166 | - master_data = master_data | (timings[pio][0] << 12) | | |
24167 | - (timings[pio][1] << 8); | |
24168 | + master_data = master_data | (timings[pio][0] << 12) | (timings[pio][1] << 8); | |
24169 | } | |
24170 | - save_flags(flags); | |
24171 | - cli(); | |
24172 | - pci_write_config_word(HWIF(drive)->pci_dev, master_port, master_data); | |
24173 | + pci_write_config_word(dev, master_port, master_data); | |
24174 | if (is_slave) | |
24175 | - pci_write_config_byte(HWIF(drive)->pci_dev, slave_port, slave_data); | |
24176 | - restore_flags(flags); | |
24177 | + pci_write_config_byte(dev, slave_port, slave_data); | |
24178 | + spin_unlock_irqrestore(&io_request_lock, flags); | |
24179 | } | |
24180 | ||
24181 | -#ifdef CONFIG_BLK_DEV_IDEDMA | |
24182 | -static int slc90e66_tune_chipset (ide_drive_t *drive, byte speed) | |
24183 | +static int slc90e66_tune_chipset (ide_drive_t *drive, byte xferspeed) | |
24184 | { | |
24185 | ide_hwif_t *hwif = HWIF(drive); | |
24186 | struct pci_dev *dev = hwif->pci_dev; | |
24187 | byte maslave = hwif->channel ? 0x42 : 0x40; | |
24188 | + byte speed = slc90e66_ratefilter(drive, xferspeed); | |
24189 | int a_speed = 7 << (drive->dn * 4); | |
24190 | int u_flag = 1 << drive->dn; | |
24191 | int u_speed = 0; | |
24192 | - int err = 0; | |
24193 | int sitre; | |
24194 | short reg4042, reg44, reg48, reg4a; | |
24195 | ||
24196 | @@ -245,6 +281,7 @@ | |
24197 | pci_read_config_word(dev, 0x4a, ®4a); | |
24198 | ||
24199 | switch(speed) { | |
24200 | +#ifdef CONFIG_BLK_DEV_IDEDMA | |
24201 | case XFER_UDMA_4: u_speed = 4 << (drive->dn * 4); break; | |
24202 | case XFER_UDMA_3: u_speed = 3 << (drive->dn * 4); break; | |
24203 | case XFER_UDMA_2: u_speed = 2 << (drive->dn * 4); break; | |
24204 | @@ -253,6 +290,11 @@ | |
24205 | case XFER_MW_DMA_2: | |
24206 | case XFER_MW_DMA_1: | |
24207 | case XFER_SW_DMA_2: break; | |
24208 | +#endif /* CONFIG_BLK_DEV_IDEDMA */ | |
24209 | + case XFER_PIO_4: | |
24210 | + case XFER_PIO_3: | |
24211 | + case XFER_PIO_2: | |
24212 | + case XFER_PIO_0: break; | |
24213 | default: return -1; | |
24214 | } | |
24215 | ||
24216 | @@ -264,8 +306,7 @@ | |
24217 | pci_read_config_word(dev, 0x4a, ®4a); | |
24218 | pci_write_config_word(dev, 0x4a, reg4a|u_speed); | |
24219 | } | |
24220 | - } | |
24221 | - if (speed < XFER_UDMA_0) { | |
24222 | + } else { | |
24223 | if (reg48 & u_flag) | |
24224 | pci_write_config_word(dev, 0x48, reg48 & ~u_flag); | |
24225 | if (reg4a & a_speed) | |
24226 | @@ -273,46 +314,45 @@ | |
24227 | } | |
24228 | ||
24229 | slc90e66_tune_drive(drive, slc90e66_dma_2_pio(speed)); | |
24230 | - | |
24231 | -#if SLC90E66_DEBUG_DRIVE_INFO | |
24232 | - printk("%s: %s drive%d\n", drive->name, ide_xfer_verbose(speed), drive->dn); | |
24233 | -#endif /* SLC90E66_DEBUG_DRIVE_INFO */ | |
24234 | - if (!drive->init_speed) | |
24235 | - drive->init_speed = speed; | |
24236 | - err = ide_config_drive_speed(drive, speed); | |
24237 | - drive->current_speed = speed; | |
24238 | - return err; | |
24239 | + return (ide_config_drive_speed(drive, speed)); | |
24240 | } | |
24241 | ||
24242 | +#ifdef CONFIG_BLK_DEV_IDEDMA | |
24243 | static int slc90e66_config_drive_for_dma (ide_drive_t *drive) | |
24244 | { | |
24245 | struct hd_driveid *id = drive->id; | |
24246 | - int ultra = 1; | |
24247 | - byte speed = 0; | |
24248 | - byte udma_66 = eighty_ninty_three(drive); | |
24249 | - | |
24250 | - if ((id->dma_ultra & 0x0010) && (ultra)) { | |
24251 | - speed = (udma_66) ? XFER_UDMA_4 : XFER_UDMA_2; | |
24252 | - } else if ((id->dma_ultra & 0x0008) && (ultra)) { | |
24253 | - speed = (udma_66) ? XFER_UDMA_3 : XFER_UDMA_1; | |
24254 | - } else if ((id->dma_ultra & 0x0004) && (ultra)) { | |
24255 | - speed = XFER_UDMA_2; | |
24256 | - } else if ((id->dma_ultra & 0x0002) && (ultra)) { | |
24257 | - speed = XFER_UDMA_1; | |
24258 | - } else if ((id->dma_ultra & 0x0001) && (ultra)) { | |
24259 | - speed = XFER_UDMA_0; | |
24260 | - } else if (id->dma_mword & 0x0004) { | |
24261 | - speed = XFER_MW_DMA_2; | |
24262 | - } else if (id->dma_mword & 0x0002) { | |
24263 | - speed = XFER_MW_DMA_1; | |
24264 | - } else if (id->dma_1word & 0x0004) { | |
24265 | - speed = XFER_SW_DMA_2; | |
24266 | - } else { | |
24267 | - speed = XFER_PIO_0 + ide_get_best_pio_mode(drive, 255, 5, NULL); | |
24268 | + byte mode = slc90e66_ratemask(drive); | |
24269 | + byte speed, tspeed, dma = 1; | |
24270 | + | |
24271 | + switch(mode) { | |
24272 | + case 0x02: | |
24273 | + if (id->dma_ultra & 0x0010) | |
24274 | + { speed = XFER_UDMA_4; break; } | |
24275 | + if (id->dma_ultra & 0x0008) | |
24276 | + { speed = XFER_UDMA_3; break; } | |
24277 | + case 0x01: | |
24278 | + if (id->dma_ultra & 0x0004) | |
24279 | + { speed = XFER_UDMA_2; break; } | |
24280 | + if (id->dma_ultra & 0x0002) | |
24281 | + { speed = XFER_UDMA_1; break; } | |
24282 | + if (id->dma_ultra & 0x0001) | |
24283 | + { speed = XFER_UDMA_0; break; } | |
24284 | + case 0x00: | |
24285 | + if (id->dma_mword & 0x0004) | |
24286 | + { speed = XFER_MW_DMA_2; break; } | |
24287 | + if (id->dma_mword & 0x0002) | |
24288 | + { speed = XFER_MW_DMA_1; break; } | |
24289 | + if (id->dma_1word & 0x0004) | |
24290 | + { speed = XFER_SW_DMA_2; break; } | |
24291 | + default: | |
24292 | + tspeed = ide_get_best_pio_mode(drive, 255, 5, NULL); | |
24293 | + speed = slc90e66_dma_2_pio(XFER_PIO_0 + tspeed); | |
24294 | + dma = 0; | |
24295 | + break; | |
24296 | } | |
24297 | ||
24298 | (void) slc90e66_tune_chipset(drive, speed); | |
24299 | - | |
24300 | +// return ((int) (dma) ? ide_dma_on : ide_dma_off_quietly); | |
24301 | return ((int) ((id->dma_ultra >> 11) & 7) ? ide_dma_on : | |
24302 | ((id->dma_ultra >> 8) & 7) ? ide_dma_on : | |
24303 | ((id->dma_mword >> 8) & 7) ? ide_dma_on : | |
24304 | @@ -320,11 +360,62 @@ | |
24305 | ide_dma_off_quietly); | |
24306 | } | |
24307 | ||
24308 | +static int config_drive_xfer_rate (ide_drive_t *drive) | |
24309 | +{ | |
24310 | + struct hd_driveid *id = drive->id; | |
24311 | + ide_dma_action_t dma_func = ide_dma_on; | |
24312 | + | |
24313 | + drive->init_speed = 0; | |
24314 | + | |
24315 | + if (id && (id->capability & 1) && HWIF(drive)->autodma) { | |
24316 | + /* Consult the list of known "bad" drives */ | |
24317 | + if (ide_dmaproc(ide_dma_bad_drive, drive)) { | |
24318 | + dma_func = ide_dma_off; | |
24319 | + goto fast_ata_pio; | |
24320 | + } | |
24321 | + dma_func = ide_dma_off_quietly; | |
24322 | + if (id->field_valid & 4) { | |
24323 | + if (id->dma_ultra & 0x007F) { | |
24324 | + /* Force if Capable UltraDMA */ | |
24325 | + dma_func = slc90e66_config_drive_for_dma(drive); | |
24326 | + if ((id->field_valid & 2) && | |
24327 | + (dma_func != ide_dma_on)) | |
24328 | + goto try_dma_modes; | |
24329 | + } | |
24330 | + } else if (id->field_valid & 2) { | |
24331 | +try_dma_modes: | |
24332 | + if ((id->dma_mword & 0x0007) || | |
24333 | + (id->dma_1word & 0x007)) { | |
24334 | + /* Force if Capable regular DMA modes */ | |
24335 | + dma_func = slc90e66_config_drive_for_dma(drive); | |
24336 | + if (dma_func != ide_dma_on) | |
24337 | + goto no_dma_set; | |
24338 | + } | |
24339 | + } else if (ide_dmaproc(ide_dma_good_drive, drive)) { | |
24340 | + if (id->eide_dma_time > 150) { | |
24341 | + goto no_dma_set; | |
24342 | + } | |
24343 | + /* Consult the list of known "good" drives */ | |
24344 | + dma_func = slc90e66_config_drive_for_dma(drive); | |
24345 | + if (dma_func != ide_dma_on) | |
24346 | + goto no_dma_set; | |
24347 | + } else { | |
24348 | + goto fast_ata_pio; | |
24349 | + } | |
24350 | + } else if ((id->capability & 8) || (id->field_valid & 2)) { | |
24351 | +fast_ata_pio: | |
24352 | + dma_func = ide_dma_off_quietly; | |
24353 | +no_dma_set: | |
24354 | + slc90e66_tune_drive(drive, 5); | |
24355 | + } | |
24356 | + return HWIF(drive)->dmaproc(dma_func, drive); | |
24357 | +} | |
24358 | + | |
24359 | static int slc90e66_dmaproc(ide_dma_action_t func, ide_drive_t *drive) | |
24360 | { | |
24361 | switch (func) { | |
24362 | case ide_dma_check: | |
24363 | - return ide_dmaproc((ide_dma_action_t) slc90e66_config_drive_for_dma(drive), drive); | |
24364 | + return config_drive_xfer_rate(drive); | |
24365 | default : | |
24366 | break; | |
24367 | } | |
24368 | @@ -347,16 +438,11 @@ | |
24369 | ||
24370 | unsigned int __init ata66_slc90e66 (ide_hwif_t *hwif) | |
24371 | { | |
24372 | -#if 1 | |
24373 | byte reg47 = 0, ata66 = 0; | |
24374 | byte mask = hwif->channel ? 0x01 : 0x02; /* bit0:Primary */ | |
24375 | ||
24376 | pci_read_config_byte(hwif->pci_dev, 0x47, ®47); | |
24377 | - | |
24378 | ata66 = (reg47 & mask) ? 0 : 1; /* bit[0(1)]: 0:80, 1:40 */ | |
24379 | -#else | |
24380 | - byte ata66 = 0; | |
24381 | -#endif | |
24382 | return ata66; | |
24383 | } | |
24384 | ||
24385 | @@ -365,6 +451,8 @@ | |
24386 | if (!hwif->irq) | |
24387 | hwif->irq = hwif->channel ? 15 : 14; | |
24388 | ||
24389 | + hwif->autodma = 0; | |
24390 | + hwif->speedproc = &slc90e66_tune_chipset; | |
24391 | hwif->tuneproc = &slc90e66_tune_drive; | |
24392 | hwif->drives[0].autotune = 1; | |
24393 | hwif->drives[1].autotune = 1; | |
24394 | @@ -372,11 +460,11 @@ | |
24395 | if (!hwif->dma_base) | |
24396 | return; | |
24397 | ||
24398 | - hwif->autodma = 0; | |
24399 | #ifdef CONFIG_BLK_DEV_IDEDMA | |
24400 | + hwif->dmaproc = &slc90e66_dmaproc; | |
24401 | +#ifdef CONFIG_IDEDMA_AUTO | |
24402 | if (!noautodma) | |
24403 | hwif->autodma = 1; | |
24404 | - hwif->dmaproc = &slc90e66_dmaproc; | |
24405 | - hwif->speedproc = &slc90e66_tune_chipset; | |
24406 | +#endif /* CONFIG_IDEDMA_AUTO */ | |
24407 | #endif /* !CONFIG_BLK_DEV_IDEDMA */ | |
24408 | } | |
24409 | diff -Nur linux.org/drivers/ide/trm290.c linux/drivers/ide/trm290.c | |
24410 | --- linux.org/drivers/ide/trm290.c Tue Jun 20 16:52:36 2000 | |
24411 | +++ linux/drivers/ide/trm290.c Thu Jul 18 14:24:34 2002 | |
24412 | @@ -148,23 +148,23 @@ | |
24413 | /* select PIO or DMA */ | |
24414 | reg = use_dma ? (0x21 | 0x82) : (0x21 & ~0x82); | |
24415 | ||
24416 | - __save_flags(flags); /* local CPU only */ | |
24417 | - __cli(); /* local CPU only */ | |
24418 | + local_irq_save(flags); | |
24419 | ||
24420 | if (reg != hwif->select_data) { | |
24421 | hwif->select_data = reg; | |
24422 | - outb(0x51|(hwif->channel<<3), hwif->config_data+1); /* set PIO/DMA */ | |
24423 | - outw(reg & 0xff, hwif->config_data); | |
24424 | + /* set PIO/DMA */ | |
24425 | + OUT_BYTE(0x51|(hwif->channel<<3), hwif->config_data+1); | |
24426 | + OUT_WORD(reg & 0xff, hwif->config_data); | |
24427 | } | |
24428 | ||
24429 | /* enable IRQ if not probing */ | |
24430 | if (drive->present) { | |
24431 | - reg = inw(hwif->config_data+3) & 0x13; | |
24432 | + reg = IN_WORD(hwif->config_data+3) & 0x13; | |
24433 | reg &= ~(1 << hwif->channel); | |
24434 | - outw(reg, hwif->config_data+3); | |
24435 | + OUT_WORD(reg, hwif->config_data+3); | |
24436 | } | |
24437 | ||
24438 | - __restore_flags(flags); /* local CPU only */ | |
24439 | + local_irq_restore(flags); | |
24440 | } | |
24441 | ||
24442 | static void trm290_selectproc (ide_drive_t *drive) | |
24443 | @@ -176,6 +176,7 @@ | |
24444 | static int trm290_dmaproc (ide_dma_action_t func, ide_drive_t *drive) | |
24445 | { | |
24446 | ide_hwif_t *hwif = HWIF(drive); | |
24447 | +// ide_task_t *args = HWGROUP(drive)->rq->special; | |
24448 | unsigned int count, reading = 2, writing = 0; | |
24449 | ||
24450 | switch (func) { | |
24451 | @@ -187,24 +188,46 @@ | |
24452 | #endif | |
24453 | case ide_dma_read: | |
24454 | if (!(count = ide_build_dmatable(drive, func))) | |
24455 | - break; /* try PIO instead of DMA */ | |
24456 | - trm290_prepare_drive(drive, 1); /* select DMA xfer */ | |
24457 | + /* try PIO instead of DMA */ | |
24458 | + break; | |
24459 | + /* select DMA xfer */ | |
24460 | + trm290_prepare_drive(drive, 1); | |
24461 | outl(hwif->dmatable_dma|reading|writing, hwif->dma_base); | |
24462 | drive->waiting_for_dma = 1; | |
24463 | - outw((count * 2) - 1, hwif->dma_base+2); /* start DMA */ | |
24464 | + /* start DMA */ | |
24465 | + OUT_WORD((count * 2) - 1, hwif->dma_base+2); | |
24466 | if (drive->media != ide_disk) | |
24467 | return 0; | |
24468 | + if (HWGROUP(drive)->handler != NULL) /* paranoia check */ | |
24469 | + BUG(); | |
24470 | ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL); | |
24471 | - OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG); | |
24472 | - return 0; | |
24473 | +/* | |
24474 | + * FIX ME to use only ACB ide_task_t args Struct | |
24475 | + */ | |
24476 | +#if 0 | |
24477 | + { | |
24478 | + ide_task_t *args = HWGROUP(drive)->rq->special; | |
24479 | + OUT_BYTE(args->tfRegister[IDE_COMMAND_OFFSET], IDE_COMMAND_REG); | |
24480 | + } | |
24481 | +#else | |
24482 | + if (HWGROUP(drive)->rq->cmd == IDE_DRIVE_TASKFILE) { | |
24483 | + ide_task_t *args = HWGROUP(drive)->rq->special; | |
24484 | + OUT_BYTE(args->tfRegister[IDE_COMMAND_OFFSET], IDE_COMMAND_REG); | |
24485 | + } else if (drive->addressing == 1) | |
24486 | + OUT_BYTE(reading ? WIN_READDMA_EXT : WIN_WRITEDMA_EXT, IDE_COMMAND_REG); | |
24487 | + else | |
24488 | + OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG); | |
24489 | +#endif | |
24490 | + return HWIF(drive)->dmaproc(ide_dma_begin, drive); | |
24491 | case ide_dma_begin: | |
24492 | return 0; | |
24493 | case ide_dma_end: | |
24494 | drive->waiting_for_dma = 0; | |
24495 | - ide_destroy_dmatable(drive); /* purge DMA mappings */ | |
24496 | - return (inw(hwif->dma_base+2) != 0x00ff); | |
24497 | + /* purge DMA mappings */ | |
24498 | + ide_destroy_dmatable(drive); | |
24499 | + return (IN_WORD(hwif->dma_base+2) != 0x00ff); | |
24500 | case ide_dma_test_irq: | |
24501 | - return (inw(hwif->dma_base+2) == 0x00ff); | |
24502 | + return (IN_WORD(hwif->dma_base+2) == 0x00ff); | |
24503 | default: | |
24504 | return ide_dmaproc(func, drive); | |
24505 | } | |
24506 | @@ -225,25 +248,28 @@ | |
24507 | ||
24508 | hwif->chipset = ide_trm290; | |
24509 | cfgbase = pci_resource_start(dev, 4); | |
24510 | - if ((dev->class & 5) && cfgbase) | |
24511 | - { | |
24512 | + if ((dev->class & 5) && cfgbase) { | |
24513 | hwif->config_data = cfgbase; | |
24514 | - printk("TRM290: chip config base at 0x%04lx\n", hwif->config_data); | |
24515 | + printk("TRM290: chip config base at 0x%04lx\n", | |
24516 | + hwif->config_data); | |
24517 | } else { | |
24518 | hwif->config_data = 0x3df0; | |
24519 | - printk("TRM290: using default config base at 0x%04lx\n", hwif->config_data); | |
24520 | + printk("TRM290: using default config base at 0x%04lx\n", | |
24521 | + hwif->config_data); | |
24522 | } | |
24523 | ||
24524 | - __save_flags(flags); /* local CPU only */ | |
24525 | - __cli(); /* local CPU only */ | |
24526 | + local_irq_save(flags); | |
24527 | /* put config reg into first byte of hwif->select_data */ | |
24528 | - outb(0x51|(hwif->channel<<3), hwif->config_data+1); | |
24529 | - hwif->select_data = 0x21; /* select PIO as default */ | |
24530 | - outb(hwif->select_data, hwif->config_data); | |
24531 | - reg = inb(hwif->config_data+3); /* get IRQ info */ | |
24532 | - reg = (reg & 0x10) | 0x03; /* mask IRQs for both ports */ | |
24533 | - outb(reg, hwif->config_data+3); | |
24534 | - __restore_flags(flags); /* local CPU only */ | |
24535 | + OUT_BYTE(0x51|(hwif->channel<<3), hwif->config_data+1); | |
24536 | + /* select PIO as default */ | |
24537 | + hwif->select_data = 0x21; | |
24538 | + OUT_BYTE(hwif->select_data, hwif->config_data); | |
24539 | + /* get IRQ info */ | |
24540 | + reg = IN_BYTE(hwif->config_data+3); | |
24541 | + /* mask IRQs for both ports */ | |
24542 | + reg = (reg & 0x10) | 0x03; | |
24543 | + OUT_BYTE(reg, hwif->config_data+3); | |
24544 | + local_irq_restore(flags); | |
24545 | ||
24546 | if ((reg & 0x10)) | |
24547 | hwif->irq = hwif->channel ? 15 : 14; /* legacy mode */ | |
24548 | @@ -256,20 +282,20 @@ | |
24549 | #endif /* CONFIG_BLK_DEV_IDEDMA */ | |
24550 | ||
24551 | hwif->selectproc = &trm290_selectproc; | |
24552 | - hwif->autodma = 0; /* play it safe for now */ | |
24553 | + hwif->autodma = 0; /* play it safe for now */ | |
24554 | #if 1 | |
24555 | { | |
24556 | - /* | |
24557 | - * My trm290-based card doesn't seem to work with all possible values | |
24558 | - * for the control basereg, so this kludge ensures that we use only | |
24559 | - * values that are known to work. Ugh. -ml | |
24560 | - */ | |
24561 | + /* | |
24562 | + * My trm290-based card doesn't seem to work with all possible values | |
24563 | + * for the control basereg, so this kludge ensures that we use only | |
24564 | + * values that are known to work. Ugh. -ml | |
24565 | + */ | |
24566 | unsigned short old, compat = hwif->channel ? 0x374 : 0x3f4; | |
24567 | static unsigned short next_offset = 0; | |
24568 | ||
24569 | - outb(0x54|(hwif->channel<<3), hwif->config_data+1); | |
24570 | - old = inw(hwif->config_data) & ~1; | |
24571 | - if (old != compat && inb(old+2) == 0xff) { | |
24572 | + OUT_BYTE(0x54|(hwif->channel<<3), hwif->config_data+1); | |
24573 | + old = IN_WORD(hwif->config_data) & ~1; | |
24574 | + if (old != compat && IN_BYTE(old+2) == 0xff) { | |
24575 | compat += (next_offset += 0x400); /* leave lower 10 bits untouched */ | |
24576 | #if 1 | |
24577 | if (ide_check_region(compat + 2, 1)) | |
24578 | @@ -281,8 +307,8 @@ | |
24579 | */ | |
24580 | #endif | |
24581 | hwif->io_ports[IDE_CONTROL_OFFSET] = compat + 2; | |
24582 | - outw(compat|1, hwif->config_data); | |
24583 | - printk("%s: control basereg workaround: old=0x%04x, new=0x%04x\n", hwif->name, old, inw(hwif->config_data) & ~1); | |
24584 | + OUT_WORD(compat|1, hwif->config_data); | |
24585 | + printk("%s: control basereg workaround: old=0x%04x, new=0x%04x\n", hwif->name, old, IN_WORD(hwif->config_data) & ~1); | |
24586 | } | |
24587 | } | |
24588 | #endif | |
24589 | diff -Nur linux.org/drivers/ide/umc8672.c linux/drivers/ide/umc8672.c | |
24590 | --- linux.org/drivers/ide/umc8672.c Fri Apr 14 07:54:26 2000 | |
24591 | +++ linux/drivers/ide/umc8672.c Thu Jul 18 14:24:34 2002 | |
24592 | @@ -73,36 +73,34 @@ | |
24593 | ||
24594 | static void out_umc (char port,char wert) | |
24595 | { | |
24596 | - outb_p (port,0x108); | |
24597 | - outb_p (wert,0x109); | |
24598 | + outb_p(port,0x108); | |
24599 | + outb_p(wert,0x109); | |
24600 | } | |
24601 | ||
24602 | static inline byte in_umc (char port) | |
24603 | { | |
24604 | - outb_p (port,0x108); | |
24605 | - return inb_p (0x109); | |
24606 | + outb_p(port,0x108); | |
24607 | + return inb_p(0x109); | |
24608 | } | |
24609 | ||
24610 | static void umc_set_speeds (byte speeds[]) | |
24611 | { | |
24612 | int i, tmp; | |
24613 | ||
24614 | - outb_p (0x5A,0x108); /* enable umc */ | |
24615 | + outb_p(0x5A,0x108); /* enable umc */ | |
24616 | ||
24617 | out_umc (0xd7,(speedtab[0][speeds[2]] | (speedtab[0][speeds[3]]<<4))); | |
24618 | out_umc (0xd6,(speedtab[0][speeds[0]] | (speedtab[0][speeds[1]]<<4))); | |
24619 | tmp = 0; | |
24620 | - for (i = 3; i >= 0; i--) | |
24621 | - { | |
24622 | + for (i = 3; i >= 0; i--) { | |
24623 | tmp = (tmp << 2) | speedtab[1][speeds[i]]; | |
24624 | } | |
24625 | out_umc (0xdc,tmp); | |
24626 | - for (i = 0;i < 4; i++) | |
24627 | - { | |
24628 | + for (i = 0;i < 4; i++) { | |
24629 | out_umc (0xd0+i,speedtab[2][speeds[i]]); | |
24630 | out_umc (0xd8+i,speedtab[2][speeds[i]]); | |
24631 | } | |
24632 | - outb_p (0xa5,0x108); /* disable umc */ | |
24633 | + outb_p(0xa5,0x108); /* disable umc */ | |
24634 | ||
24635 | printk ("umc8672: drive speeds [0 to 11]: %d %d %d %d\n", | |
24636 | speeds[0], speeds[1], speeds[2], speeds[3]); | |
24637 | @@ -114,40 +112,38 @@ | |
24638 | ide_hwgroup_t *hwgroup = ide_hwifs[HWIF(drive)->index^1].hwgroup; | |
24639 | ||
24640 | pio = ide_get_best_pio_mode(drive, pio, 4, NULL); | |
24641 | - printk("%s: setting umc8672 to PIO mode%d (speed %d)\n", drive->name, pio, pio_to_umc[pio]); | |
24642 | - save_flags(flags); /* all CPUs */ | |
24643 | - cli(); /* all CPUs */ | |
24644 | + printk("%s: setting umc8672 to PIO mode%d (speed %d)\n", | |
24645 | + drive->name, pio, pio_to_umc[pio]); | |
24646 | + spin_lock_irqsave(&io_request_lock, flags); | |
24647 | if (hwgroup && hwgroup->handler != NULL) { | |
24648 | printk("umc8672: other interface is busy: exiting tune_umc()\n"); | |
24649 | } else { | |
24650 | current_speeds[drive->name[2] - 'a'] = pio_to_umc[pio]; | |
24651 | umc_set_speeds (current_speeds); | |
24652 | } | |
24653 | - restore_flags(flags); /* all CPUs */ | |
24654 | + spin_unlock_irqrestore(&io_request_lock, flags); | |
24655 | } | |
24656 | ||
24657 | void __init init_umc8672 (void) /* called from ide.c */ | |
24658 | { | |
24659 | unsigned long flags; | |
24660 | ||
24661 | - __save_flags(flags); /* local CPU only */ | |
24662 | - __cli(); /* local CPU only */ | |
24663 | + local_irq_save(flags); | |
24664 | if (check_region(0x108, 2)) { | |
24665 | - __restore_flags(flags); | |
24666 | + local_irq_restore(flags); | |
24667 | printk("\numc8672: PORTS 0x108-0x109 ALREADY IN USE\n"); | |
24668 | return; | |
24669 | } | |
24670 | - outb_p (0x5A,0x108); /* enable umc */ | |
24671 | - if (in_umc (0xd5) != 0xa0) | |
24672 | - { | |
24673 | - __restore_flags(flags); /* local CPU only */ | |
24674 | + outb_p(0x5A,0x108); /* enable umc */ | |
24675 | + if (in_umc (0xd5) != 0xa0) { | |
24676 | + local_irq_restore(flags); | |
24677 | printk ("umc8672: not found\n"); | |
24678 | return; | |
24679 | } | |
24680 | - outb_p (0xa5,0x108); /* disable umc */ | |
24681 | + outb_p(0xa5,0x108); /* disable umc */ | |
24682 | ||
24683 | umc_set_speeds (current_speeds); | |
24684 | - __restore_flags(flags); /* local CPU only */ | |
24685 | + local_irq_restore(flags); | |
24686 | ||
24687 | request_region(0x108, 2, "umc8672"); | |
24688 | ide_hwifs[0].chipset = ide_umc8672; | |
24689 | diff -Nur linux.org/drivers/ide/via82cxxx.c linux/drivers/ide/via82cxxx.c | |
24690 | --- linux.org/drivers/ide/via82cxxx.c Tue Sep 11 17:40:36 2001 | |
24691 | +++ linux/drivers/ide/via82cxxx.c Thu Jul 18 14:24:34 2002 | |
24692 | @@ -1,5 +1,5 @@ | |
24693 | /* | |
24694 | - * $Id$ | |
24695 | + * $Id$ | |
24696 | * | |
24697 | * Copyright (c) 2000-2001 Vojtech Pavlik | |
24698 | * | |
24699 | @@ -7,23 +7,21 @@ | |
24700 | * Michel Aubry | |
24701 | * Jeff Garzik | |
24702 | * Andre Hedrick | |
24703 | - * | |
24704 | - * Sponsored by SuSE | |
24705 | */ | |
24706 | ||
24707 | /* | |
24708 | * VIA IDE driver for Linux. Supports | |
24709 | * | |
24710 | * vt82c576, vt82c586, vt82c586a, vt82c586b, vt82c596a, vt82c596b, | |
24711 | - * vt82c686, vt82c686a, vt82c686b, vt8231, vt8233 | |
24712 | + * vt82c686, vt82c686a, vt82c686b, vt8231, vt8233, vt8233c, vt8233a | |
24713 | * | |
24714 | * southbridges, which can be found in | |
24715 | * | |
24716 | * VIA Apollo Master, VP, VP2, VP2/97, VP3, VPX, VPX/97, MVP3, MVP4, P6, Pro, | |
24717 | * ProII, ProPlus, Pro133, Pro133+, Pro133A, Pro133A Dual, Pro133T, Pro133Z, | |
24718 | * PLE133, PLE133T, Pro266, Pro266T, ProP4X266, PM601, PM133, PN133, PL133T, | |
24719 | - * PX266, PM266, KX133, KT133, KT133A, KLE133, KT266, KX266, KM133, KM133A, | |
24720 | - * KL133, KN133, KM266 | |
24721 | + * PX266, PM266, KX133, KT133, KT133A, KT133E, KLE133, KT266, KX266, KM133, | |
24722 | + * KM133A, KL133, KN133, KM266 | |
24723 | * PC-Chips VXPro, VXPro+, VXTwo, TXPro-III, TXPro-AGP, AGPPro, ViaGra, BXToo, | |
24724 | * BXTel, BXpert | |
24725 | * AMD 640, 640 AGP, 750 IronGate, 760, 760MP | |
24726 | @@ -32,9 +30,9 @@ | |
24727 | * | |
24728 | * chipsets. Supports | |
24729 | * | |
24730 | - * PIO 0-5, MWDMA 0-2, SWDMA 0-2 and UDMA 0-5 | |
24731 | + * PIO 0-5, MWDMA 0-2, SWDMA 0-2 and UDMA 0-6 | |
24732 | * | |
24733 | - * (this includes UDMA33, 66 and 100) modes. UDMA66 and higher modes are | |
24734 | + * (this includes UDMA33, 66, 100 and 133) modes. UDMA66 and higher modes are | |
24735 | * autoenabled only in case the BIOS has detected a 80 wire cable. To ignore | |
24736 | * the BIOS data and assume the cable is present, use 'ide0=ata66' or | |
24737 | * 'ide1=ata66' on the kernel command line. | |
24738 | @@ -56,8 +54,8 @@ | |
24739 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
24740 | * | |
24741 | * Should you need to contact me, the author, you can do so either by | |
24742 | - * e-mail - mail your message to <vojtech@suse.cz>, or by paper mail: | |
24743 | - * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic | |
24744 | + * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail: | |
24745 | + * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic | |
24746 | */ | |
24747 | ||
24748 | #include <linux/config.h> | |
24749 | @@ -87,10 +85,12 @@ | |
24750 | #define VIA_UDMA_33 0x001 | |
24751 | #define VIA_UDMA_66 0x002 | |
24752 | #define VIA_UDMA_100 0x003 | |
24753 | +#define VIA_UDMA_133 0x004 | |
24754 | #define VIA_BAD_PREQ 0x010 /* Crashes if PREQ# till DDACK# set */ | |
24755 | #define VIA_BAD_CLK66 0x020 /* 66 MHz clock doesn't work correctly */ | |
24756 | #define VIA_SET_FIFO 0x040 /* Needs to have FIFO split set */ | |
24757 | #define VIA_NO_UNMASK 0x080 /* Doesn't work with IRQ unmasking on */ | |
24758 | +#define VIA_BAD_ID 0x100 /* Has wrong vendor ID (0x1107) */ | |
24759 | ||
24760 | /* | |
24761 | * VIA SouthBridge chips. | |
24762 | @@ -104,10 +104,11 @@ | |
24763 | unsigned short flags; | |
24764 | } via_isa_bridges[] = { | |
24765 | #ifdef FUTURE_BRIDGES | |
24766 | - { "vt8237", PCI_DEVICE_ID_VIA_8237, 0x00, 0x2f, VIA_UDMA_100 }, | |
24767 | - { "vt8235", PCI_DEVICE_ID_VIA_8235, 0x00, 0x2f, VIA_UDMA_100 }, | |
24768 | - { "vt8233c", PCI_DEVICE_ID_VIA_8233C, 0x00, 0x2f, VIA_UDMA_100 }, | |
24769 | + { "vt8237", PCI_DEVICE_ID_VIA_8237, 0x00, 0x2f, VIA_UDMA_133 }, | |
24770 | + { "vt8235", PCI_DEVICE_ID_VIA_8235, 0x00, 0x2f, VIA_UDMA_133 }, | |
24771 | #endif | |
24772 | + { "vt8233a", PCI_DEVICE_ID_VIA_8233A, 0x00, 0x2f, VIA_UDMA_133 }, | |
24773 | + { "vt8233c", PCI_DEVICE_ID_VIA_8233C_0, 0x00, 0x2f, VIA_UDMA_100 }, | |
24774 | { "vt8233", PCI_DEVICE_ID_VIA_8233_0, 0x00, 0x2f, VIA_UDMA_100 }, | |
24775 | { "vt8231", PCI_DEVICE_ID_VIA_8231, 0x00, 0x2f, VIA_UDMA_100 }, | |
24776 | { "vt82c686b", PCI_DEVICE_ID_VIA_82C686, 0x40, 0x4f, VIA_UDMA_100 }, | |
24777 | @@ -121,6 +122,7 @@ | |
24778 | { "vt82c586a", PCI_DEVICE_ID_VIA_82C586_0, 0x20, 0x2f, VIA_UDMA_33 | VIA_SET_FIFO }, | |
24779 | { "vt82c586", PCI_DEVICE_ID_VIA_82C586_0, 0x00, 0x0f, VIA_UDMA_NONE | VIA_SET_FIFO }, | |
24780 | { "vt82c576", PCI_DEVICE_ID_VIA_82C576, 0x00, 0x2f, VIA_UDMA_NONE | VIA_SET_FIFO | VIA_NO_UNMASK }, | |
24781 | + { "vt82c576", PCI_DEVICE_ID_VIA_82C576, 0x00, 0x2f, VIA_UDMA_NONE | VIA_SET_FIFO | VIA_NO_UNMASK | VIA_BAD_ID }, | |
24782 | { NULL } | |
24783 | }; | |
24784 | ||
24785 | @@ -128,7 +130,7 @@ | |
24786 | static unsigned char via_enabled; | |
24787 | static unsigned int via_80w; | |
24788 | static unsigned int via_clock; | |
24789 | -static char *via_dma[] = { "MWDMA16", "UDMA33", "UDMA66", "UDMA100" }; | |
24790 | +static char *via_dma[] = { "MWDMA16", "UDMA33", "UDMA66", "UDMA100", "UDMA133" }; | |
24791 | ||
24792 | /* | |
24793 | * VIA /proc entry. | |
24794 | @@ -151,7 +153,7 @@ | |
24795 | ||
24796 | static int via_get_info(char *buffer, char **addr, off_t offset, int count) | |
24797 | { | |
24798 | - short speed[4], cycle[4], setup[4], active[4], recover[4], den[4], | |
24799 | + int speed[4], cycle[4], setup[4], active[4], recover[4], den[4], | |
24800 | uen[4], udma[4], umul[4], active8b[4], recover8b[4]; | |
24801 | struct pci_dev *dev = bmide_dev; | |
24802 | unsigned int v, u, i; | |
24803 | @@ -161,7 +163,7 @@ | |
24804 | ||
24805 | via_print("----------VIA BusMastering IDE Configuration----------------"); | |
24806 | ||
24807 | - via_print("Driver Version: 3.29"); | |
24808 | + via_print("Driver Version: 3.34"); | |
24809 | via_print("South Bridge: VIA %s", via_config->name); | |
24810 | ||
24811 | pci_read_config_byte(isa_dev, PCI_REVISION_ID, &t); | |
24812 | @@ -170,7 +172,7 @@ | |
24813 | via_print("Highest DMA rate: %s", via_dma[via_config->flags & VIA_UDMA]); | |
24814 | ||
24815 | via_print("BM-DMA base: %#x", via_base); | |
24816 | - via_print("PCI clock: %dMHz", via_clock); | |
24817 | + via_print("PCI clock: %d.%dMHz", via_clock / 1000, via_clock / 100 % 10); | |
24818 | ||
24819 | pci_read_config_byte(dev, VIA_MISC_1, &t); | |
24820 | via_print("Master Read Cycle IRDY: %dws", (t & 64) >> 6); | |
24821 | @@ -191,7 +193,7 @@ | |
24822 | pci_read_config_byte(dev, VIA_IDE_ENABLE, &t); | |
24823 | via_print("Enabled: %10s%20s", (t & 0x02) ? "yes" : "no", (t & 0x01) ? "yes" : "no"); | |
24824 | ||
24825 | - c = inb(via_base + 0x02) | (inb(via_base + 0x0a) << 8); | |
24826 | + c = IN_BYTE(via_base + 0x02) | (IN_BYTE(via_base + 0x0a) << 8); | |
24827 | via_print("Simplex only: %10s%20s", (c & 0x80) ? "yes" : "no", (c & 0x8000) ? "yes" : "no"); | |
24828 | ||
24829 | via_print("Cable Type: %10s%20s", (via_80w & 1) ? "80w" : "40w", (via_80w & 2) ? "80w" : "40w"); | |
24830 | @@ -218,40 +220,45 @@ | |
24831 | uen[i] = ((u >> ((3 - i) << 3)) & 0x20); | |
24832 | den[i] = (c & ((i & 1) ? 0x40 : 0x20) << ((i & 2) << 2)); | |
24833 | ||
24834 | - speed[i] = 20 * via_clock / (active[i] + recover[i]); | |
24835 | - cycle[i] = 1000 / via_clock * (active[i] + recover[i]); | |
24836 | + speed[i] = 2 * via_clock / (active[i] + recover[i]); | |
24837 | + cycle[i] = 1000000 * (active[i] + recover[i]) / via_clock; | |
24838 | ||
24839 | if (!uen[i] || !den[i]) | |
24840 | continue; | |
24841 | ||
24842 | switch (via_config->flags & VIA_UDMA) { | |
24843 | - | |
24844 | - case VIA_UDMA_100: | |
24845 | - speed[i] = 60 * via_clock / udma[i]; | |
24846 | - cycle[i] = 333 / via_clock * udma[i]; | |
24847 | + | |
24848 | + case VIA_UDMA_33: | |
24849 | + speed[i] = 2 * via_clock / udma[i]; | |
24850 | + cycle[i] = 1000000 * udma[i] / via_clock; | |
24851 | break; | |
24852 | ||
24853 | case VIA_UDMA_66: | |
24854 | - speed[i] = 40 * via_clock / (udma[i] * umul[i]); | |
24855 | - cycle[i] = 500 / via_clock * (udma[i] * umul[i]); | |
24856 | + speed[i] = 4 * via_clock / (udma[i] * umul[i]); | |
24857 | + cycle[i] = 500000 * (udma[i] * umul[i]) / via_clock; | |
24858 | break; | |
24859 | ||
24860 | - case VIA_UDMA_33: | |
24861 | - speed[i] = 20 * via_clock / udma[i]; | |
24862 | - cycle[i] = 1000 / via_clock * udma[i]; | |
24863 | + case VIA_UDMA_100: | |
24864 | + speed[i] = 6 * via_clock / udma[i]; | |
24865 | + cycle[i] = 333333 * udma[i] / via_clock; | |
24866 | + break; | |
24867 | + | |
24868 | + case VIA_UDMA_133: | |
24869 | + speed[i] = 8 * via_clock / udma[i]; | |
24870 | + cycle[i] = 250000 * udma[i] / via_clock; | |
24871 | break; | |
24872 | } | |
24873 | } | |
24874 | ||
24875 | via_print_drive("Transfer Mode: ", "%10s", den[i] ? (uen[i] ? "UDMA" : "DMA") : "PIO"); | |
24876 | ||
24877 | - via_print_drive("Address Setup: ", "%8dns", (1000 / via_clock) * setup[i]); | |
24878 | - via_print_drive("Cmd Active: ", "%8dns", (1000 / via_clock) * active8b[i]); | |
24879 | - via_print_drive("Cmd Recovery: ", "%8dns", (1000 / via_clock) * recover8b[i]); | |
24880 | - via_print_drive("Data Active: ", "%8dns", (1000 / via_clock) * active[i]); | |
24881 | - via_print_drive("Data Recovery: ", "%8dns", (1000 / via_clock) * recover[i]); | |
24882 | + via_print_drive("Address Setup: ", "%8dns", 1000000 * setup[i] / via_clock); | |
24883 | + via_print_drive("Cmd Active: ", "%8dns", 1000000 * active8b[i] / via_clock); | |
24884 | + via_print_drive("Cmd Recovery: ", "%8dns", 1000000 * recover8b[i] / via_clock); | |
24885 | + via_print_drive("Data Active: ", "%8dns", 1000000 * active[i] / via_clock); | |
24886 | + via_print_drive("Data Recovery: ", "%8dns", 1000000 * recover[i] / via_clock); | |
24887 | via_print_drive("Cycle Time: ", "%8dns", cycle[i]); | |
24888 | - via_print_drive("Transfer Rate: ", "%4d.%dMB/s", speed[i] / 10, speed[i] % 10); | |
24889 | + via_print_drive("Transfer Rate: ", "%4d.%dMB/s", speed[i] / 1000, speed[i] / 100 % 10); | |
24890 | ||
24891 | return p - buffer; /* hoping it is less than 4K... */ | |
24892 | } | |
24893 | @@ -280,6 +287,7 @@ | |
24894 | case VIA_UDMA_33: t = timing->udma ? (0xe0 | (FIT(timing->udma, 2, 5) - 2)) : 0x03; break; | |
24895 | case VIA_UDMA_66: t = timing->udma ? (0xe8 | (FIT(timing->udma, 2, 9) - 2)) : 0x0f; break; | |
24896 | case VIA_UDMA_100: t = timing->udma ? (0xe0 | (FIT(timing->udma, 2, 9) - 2)) : 0x07; break; | |
24897 | + case VIA_UDMA_133: t = timing->udma ? (0xe0 | (FIT(timing->udma, 2, 9) - 2)) : 0x07; break; | |
24898 | default: return; | |
24899 | } | |
24900 | ||
24901 | @@ -296,20 +304,21 @@ | |
24902 | { | |
24903 | ide_drive_t *peer = HWIF(drive)->drives + (~drive->dn & 1); | |
24904 | struct ide_timing t, p; | |
24905 | - int T, UT; | |
24906 | + unsigned int T, UT; | |
24907 | ||
24908 | if (speed != XFER_PIO_SLOW && speed != drive->current_speed) | |
24909 | if (ide_config_drive_speed(drive, speed)) | |
24910 | printk(KERN_WARNING "ide%d: Drive %d didn't accept speed setting. Oh, well.\n", | |
24911 | drive->dn >> 1, drive->dn & 1); | |
24912 | ||
24913 | - T = 1000 / via_clock; | |
24914 | + T = 1000000000 / via_clock; | |
24915 | ||
24916 | switch (via_config->flags & VIA_UDMA) { | |
24917 | case VIA_UDMA_33: UT = T; break; | |
24918 | case VIA_UDMA_66: UT = T/2; break; | |
24919 | case VIA_UDMA_100: UT = T/3; break; | |
24920 | - default: UT = T; break; | |
24921 | + case VIA_UDMA_133: UT = T/4; break; | |
24922 | + default: UT = T; | |
24923 | } | |
24924 | ||
24925 | ide_timing_compute(drive, speed, &t, T, UT); | |
24926 | @@ -365,7 +374,8 @@ | |
24927 | XFER_PIO | XFER_EPIO | XFER_SWDMA | XFER_MWDMA | | |
24928 | (via_config->flags & VIA_UDMA ? XFER_UDMA : 0) | | |
24929 | (w80 && (via_config->flags & VIA_UDMA) >= VIA_UDMA_66 ? XFER_UDMA_66 : 0) | | |
24930 | - (w80 && (via_config->flags & VIA_UDMA) >= VIA_UDMA_100 ? XFER_UDMA_100 : 0)); | |
24931 | + (w80 && (via_config->flags & VIA_UDMA) >= VIA_UDMA_100 ? XFER_UDMA_100 : 0) | | |
24932 | + (w80 && (via_config->flags & VIA_UDMA) >= VIA_UDMA_133 ? XFER_UDMA_133 : 0)); | |
24933 | ||
24934 | via_set_drive(drive, speed); | |
24935 | ||
24936 | @@ -395,14 +405,16 @@ | |
24937 | */ | |
24938 | ||
24939 | for (via_config = via_isa_bridges; via_config->id; via_config++) | |
24940 | - if ((isa = pci_find_device(PCI_VENDOR_ID_VIA, via_config->id, NULL))) { | |
24941 | + if ((isa = pci_find_device(PCI_VENDOR_ID_VIA + | |
24942 | + !!(via_config->flags & VIA_BAD_ID), via_config->id, NULL))) { | |
24943 | + | |
24944 | pci_read_config_byte(isa, PCI_REVISION_ID, &t); | |
24945 | if (t >= via_config->rev_min && t <= via_config->rev_max) | |
24946 | break; | |
24947 | } | |
24948 | ||
24949 | if (!via_config->id) { | |
24950 | - printk(KERN_WARNING "VP_IDE: Unknown VIA SouthBridge, contact Vojtech Pavlik <vojtech@suse.cz>\n"); | |
24951 | + printk(KERN_WARNING "VP_IDE: Unknown VIA SouthBridge, contact Vojtech Pavlik <vojtech@ucw.cz>\n"); | |
24952 | return -ENODEV; | |
24953 | } | |
24954 | ||
24955 | @@ -412,22 +424,28 @@ | |
24956 | ||
24957 | switch (via_config->flags & VIA_UDMA) { | |
24958 | ||
24959 | - case VIA_UDMA_100: | |
24960 | - | |
24961 | - pci_read_config_dword(dev, VIA_UDMA_TIMING, &u); | |
24962 | - for (i = 24; i >= 0; i -= 8) | |
24963 | - if (((u >> i) & 0x10) || (((u >> i) & 0x20) && (((u >> i) & 7) < 3))) | |
24964 | - via_80w |= (1 << (1 - (i >> 4))); /* BIOS 80-wire bit or UDMA w/ < 50ns/cycle */ | |
24965 | - break; | |
24966 | - | |
24967 | case VIA_UDMA_66: | |
24968 | - | |
24969 | pci_read_config_dword(dev, VIA_UDMA_TIMING, &u); /* Enable Clk66 */ | |
24970 | pci_write_config_dword(dev, VIA_UDMA_TIMING, u | 0x80008); | |
24971 | for (i = 24; i >= 0; i -= 8) | |
24972 | if (((u >> (i & 16)) & 8) && ((u >> i) & 0x20) && (((u >> i) & 7) < 2)) | |
24973 | via_80w |= (1 << (1 - (i >> 4))); /* 2x PCI clock and UDMA w/ < 3T/cycle */ | |
24974 | break; | |
24975 | + | |
24976 | + case VIA_UDMA_100: | |
24977 | + pci_read_config_dword(dev, VIA_UDMA_TIMING, &u); | |
24978 | + for (i = 24; i >= 0; i -= 8) | |
24979 | + if (((u >> i) & 0x10) || (((u >> i) & 0x20) && (((u >> i) & 7) < 4))) | |
24980 | + via_80w |= (1 << (1 - (i >> 4))); /* BIOS 80-wire bit or UDMA w/ < 60ns/cycle */ | |
24981 | + break; | |
24982 | + | |
24983 | + case VIA_UDMA_133: | |
24984 | + pci_read_config_dword(dev, VIA_UDMA_TIMING, &u); | |
24985 | + for (i = 24; i >= 0; i -= 8) | |
24986 | + if (((u >> i) & 0x10) || (((u >> i) & 0x20) && (((u >> i) & 7) < 8))) | |
24987 | + via_80w |= (1 << (1 - (i >> 4))); /* BIOS 80-wire bit or UDMA w/ < 60ns/cycle */ | |
24988 | + break; | |
24989 | + | |
24990 | } | |
24991 | ||
24992 | if (via_config->flags & VIA_BAD_CLK66) { /* Disable Clk66 */ | |
24993 | @@ -466,11 +484,18 @@ | |
24994 | * Determine system bus clock. | |
24995 | */ | |
24996 | ||
24997 | - via_clock = system_bus_clock(); | |
24998 | - if (via_clock < 20 || via_clock > 50) { | |
24999 | + via_clock = system_bus_clock() * 1000; | |
25000 | + | |
25001 | + switch (via_clock) { | |
25002 | + case 33000: via_clock = 33333; break; | |
25003 | + case 37000: via_clock = 37500; break; | |
25004 | + case 41000: via_clock = 41666; break; | |
25005 | + } | |
25006 | + | |
25007 | + if (via_clock < 20000 || via_clock > 50000) { | |
25008 | printk(KERN_WARNING "VP_IDE: User given PCI clock speed impossible (%d), using 33 MHz instead.\n", via_clock); | |
25009 | - printk(KERN_WARNING "VP_IDE: Use ide0=ata66 if you want to force UDMA66/UDMA100.\n"); | |
25010 | - via_clock = 33; | |
25011 | + printk(KERN_WARNING "VP_IDE: Use ide0=ata66 if you want to assume 80-wire cable.\n"); | |
25012 | + via_clock = 33333; | |
25013 | } | |
25014 | ||
25015 | /* | |
25016 | --- linux.org/include/linux/ide.h Thu Nov 22 20:48:07 2001 | |
25017 | +++ linux/include/linux/ide.h Thu Jul 18 14:24:44 2002 | |
25018 | @@ -14,7 +14,16 @@ | |
25019 | #include <linux/blkdev.h> | |
25020 | #include <linux/proc_fs.h> | |
25021 | #include <linux/devfs_fs_kernel.h> | |
25022 | +#include <asm/byteorder.h> | |
25023 | +#include <asm/system.h> | |
25024 | #include <asm/hdreg.h> | |
25025 | +#include <asm/io.h> | |
25026 | + | |
25027 | +#ifdef CONFIG_BLK_DEV_IDEDMA_TIMEOUT | |
25028 | +# define __IDEDMA_TIMEOUT | |
25029 | +#else /* CONFIG_BLK_DEV_IDEDMA_TIMEOUT */ | |
25030 | +# undef __IDEDMA_TIMEOUT | |
25031 | +#endif /* CONFIG_BLK_DEV_IDEDMA_TIMEOUT */ | |
25032 | ||
25033 | /* | |
25034 | * This is the multiple IDE interface driver, as evolved from hd.c. | |
25035 | @@ -65,13 +74,14 @@ | |
25036 | /* | |
25037 | * IDE_DRIVE_CMD is used to implement many features of the hdparm utility | |
25038 | */ | |
25039 | -#define IDE_DRIVE_CMD 99 /* (magic) undef to reduce kernel size*/ | |
25040 | +#define IDE_DRIVE_CMD 99 /* (magic) undef to reduce kernel size*/ | |
25041 | + | |
25042 | +#define IDE_DRIVE_TASK 98 | |
25043 | ||
25044 | /* | |
25045 | - * IDE_DRIVE_TASK is used to implement many features needed for raw tasks | |
25046 | + * IDE_DRIVE_TASKFILE is used to implement many features needed for raw tasks | |
25047 | */ | |
25048 | -#define IDE_DRIVE_TASK 98 | |
25049 | -#define IDE_DRIVE_CMD_AEB 98 | |
25050 | +#define IDE_DRIVE_TASKFILE 97 | |
25051 | ||
25052 | /* | |
25053 | * "No user-serviceable parts" beyond this point :) | |
25054 | @@ -120,6 +130,17 @@ | |
25055 | #define IDE_FEATURE_OFFSET IDE_ERROR_OFFSET | |
25056 | #define IDE_COMMAND_OFFSET IDE_STATUS_OFFSET | |
25057 | ||
25058 | +#define IDE_DATA_OFFSET_HOB (0) | |
25059 | +#define IDE_ERROR_OFFSET_HOB (1) | |
25060 | +#define IDE_NSECTOR_OFFSET_HOB (2) | |
25061 | +#define IDE_SECTOR_OFFSET_HOB (3) | |
25062 | +#define IDE_LCYL_OFFSET_HOB (4) | |
25063 | +#define IDE_HCYL_OFFSET_HOB (5) | |
25064 | +#define IDE_SELECT_OFFSET_HOB (6) | |
25065 | +#define IDE_CONTROL_OFFSET_HOB (7) | |
25066 | + | |
25067 | +#define IDE_FEATURE_OFFSET_HOB IDE_ERROR_OFFSET_HOB | |
25068 | + | |
25069 | #define IDE_DATA_REG (HWIF(drive)->io_ports[IDE_DATA_OFFSET]) | |
25070 | #define IDE_ERROR_REG (HWIF(drive)->io_ports[IDE_ERROR_OFFSET]) | |
25071 | #define IDE_NSECTOR_REG (HWIF(drive)->io_ports[IDE_NSECTOR_OFFSET]) | |
25072 | @@ -131,6 +152,16 @@ | |
25073 | #define IDE_CONTROL_REG (HWIF(drive)->io_ports[IDE_CONTROL_OFFSET]) | |
25074 | #define IDE_IRQ_REG (HWIF(drive)->io_ports[IDE_IRQ_OFFSET]) | |
25075 | ||
25076 | +#define IDE_DATA_REG_HOB (HWIF(drive)->io_ports[IDE_DATA_OFFSET]) | |
25077 | +#define IDE_ERROR_REG_HOB (HWIF(drive)->io_ports[IDE_ERROR_OFFSET]) | |
25078 | +#define IDE_NSECTOR_REG_HOB (HWIF(drive)->io_ports[IDE_NSECTOR_OFFSET]) | |
25079 | +#define IDE_SECTOR_REG_HOB (HWIF(drive)->io_ports[IDE_SECTOR_OFFSET]) | |
25080 | +#define IDE_LCYL_REG_HOB (HWIF(drive)->io_ports[IDE_LCYL_OFFSET]) | |
25081 | +#define IDE_HCYL_REG_HOB (HWIF(drive)->io_ports[IDE_HCYL_OFFSET]) | |
25082 | +#define IDE_SELECT_REG_HOB (HWIF(drive)->io_ports[IDE_SELECT_OFFSET]) | |
25083 | +#define IDE_STATUS_REG_HOB (HWIF(drive)->io_ports[IDE_STATUS_OFFSET]) | |
25084 | +#define IDE_CONTROL_REG_HOB (HWIF(drive)->io_ports[IDE_CONTROL_OFFSET]) | |
25085 | + | |
25086 | #define IDE_FEATURE_REG IDE_ERROR_REG | |
25087 | #define IDE_COMMAND_REG IDE_STATUS_REG | |
25088 | #define IDE_ALTSTATUS_REG IDE_CONTROL_REG | |
25089 | @@ -156,11 +187,21 @@ | |
25090 | #define PARTN_BITS 6 /* number of minor dev bits for partitions */ | |
25091 | #define PARTN_MASK ((1<<PARTN_BITS)-1) /* a useful bit mask */ | |
25092 | #define MAX_DRIVES 2 /* per interface; 2 assumed by lots of code */ | |
25093 | -#define SECTOR_WORDS (512 / 4) /* number of 32bit words per sector */ | |
25094 | +#define CASCADE_DRIVES 8 /* per interface; 8|2 assumed by lots of code */ | |
25095 | +#define SECTOR_SIZE 512 | |
25096 | +#define SECTOR_WORDS (SECTOR_SIZE / 4) /* number of 32bit words per sector */ | |
25097 | #define IDE_LARGE_SEEK(b1,b2,t) (((b1) > (b2) + (t)) || ((b2) > (b1) + (t))) | |
25098 | #define IDE_MIN(a,b) ((a)<(b) ? (a):(b)) | |
25099 | #define IDE_MAX(a,b) ((a)>(b) ? (a):(b)) | |
25100 | ||
25101 | +#ifndef SPLIT_WORD | |
25102 | +# define SPLIT_WORD(W,HB,LB) ((HB)=(W>>8), (LB)=(W-((W>>8)<<8))) | |
25103 | +#endif | |
25104 | +#ifndef MAKE_WORD | |
25105 | +# define MAKE_WORD(W,HB,LB) ((W)=((HB<<8)+LB)) | |
25106 | +#endif | |
25107 | + | |
25108 | + | |
25109 | /* | |
25110 | * Timeouts for various operations: | |
25111 | */ | |
25112 | @@ -170,8 +211,7 @@ | |
25113 | #else | |
25114 | #define WAIT_READY (3*HZ/100) /* 30msec - should be instantaneous */ | |
25115 | #endif /* CONFIG_APM || CONFIG_APM_MODULE */ | |
25116 | -#define WAIT_PIDENTIFY (10*HZ) /* 10sec - should be less than 3ms (?) | |
25117 | - if all ATAPI CD is closed at boot */ | |
25118 | +#define WAIT_PIDENTIFY (10*HZ) /* 10sec - should be less than 3ms (?), if all ATAPI CD is closed at boot */ | |
25119 | #define WAIT_WORSTCASE (30*HZ) /* 30sec - worst case when spinning up */ | |
25120 | #define WAIT_CMD (10*HZ) /* 10sec - maximum wait for an IRQ to happen */ | |
25121 | #define WAIT_MIN_SLEEP (2*HZ/100) /* 20msec - minimum sleep time */ | |
25122 | @@ -209,6 +249,11 @@ | |
25123 | (drive)->quirk_list = hwif->quirkproc(drive); \ | |
25124 | } | |
25125 | ||
25126 | +#define HOST(hwif,chipset) \ | |
25127 | +{ \ | |
25128 | + return ((hwif)->chipset == chipset) ? 1 : 0; \ | |
25129 | +} | |
25130 | + | |
25131 | #define IDE_DEBUG(lineno) \ | |
25132 | printk("%s,%s,line=%d\n", __FILE__, __FUNCTION__, (lineno)) | |
25133 | ||
25134 | @@ -223,6 +268,18 @@ | |
25135 | #endif | |
25136 | ||
25137 | /* | |
25138 | + * hwif_chipset_t is used to keep track of the specific hardware | |
25139 | + * chipset used by each IDE interface, if known. | |
25140 | + */ | |
25141 | +typedef enum { ide_unknown, ide_generic, ide_pci, | |
25142 | + ide_cmd640, ide_dtc2278, ide_ali14xx, | |
25143 | + ide_qd65xx, ide_umc8672, ide_ht6560b, | |
25144 | + ide_pdc4030, ide_rz1000, ide_trm290, | |
25145 | + ide_cmd646, ide_cy82c693, ide_4drives, | |
25146 | + ide_pmac, ide_etrax100 | |
25147 | +} hwif_chipset_t; | |
25148 | + | |
25149 | +/* | |
25150 | * Structure to hold all information about the location of this port | |
25151 | */ | |
25152 | typedef struct hw_regs_s { | |
25153 | @@ -231,6 +288,7 @@ | |
25154 | int dma; /* our dma entry */ | |
25155 | ide_ack_intr_t *ack_intr; /* acknowledge interrupt */ | |
25156 | void *priv; /* interface specific data */ | |
25157 | + hwif_chipset_t chipset; | |
25158 | } hw_regs_t; | |
25159 | ||
25160 | /* | |
25161 | @@ -257,19 +315,23 @@ | |
25162 | */ | |
25163 | ||
25164 | #ifndef HAVE_ARCH_OUT_BYTE | |
25165 | -#ifdef REALLY_FAST_IO | |
25166 | -#define OUT_BYTE(b,p) outb((b),(p)) | |
25167 | -#else | |
25168 | -#define OUT_BYTE(b,p) outb_p((b),(p)) | |
25169 | -#endif | |
25170 | +# ifdef REALLY_FAST_IO | |
25171 | +# define OUT_BYTE(b,p) outb((b),(p)) | |
25172 | +# define OUT_WORD(w,p) outw((w),(p)) | |
25173 | +# else | |
25174 | +# define OUT_BYTE(b,p) outb_p((b),(p)) | |
25175 | +# define OUT_WORD(w,p) outw_p((w),(p)) | |
25176 | +# endif | |
25177 | #endif | |
25178 | ||
25179 | #ifndef HAVE_ARCH_IN_BYTE | |
25180 | -#ifdef REALLY_FAST_IO | |
25181 | -#define IN_BYTE(p) (byte)inb_p(p) | |
25182 | -#else | |
25183 | -#define IN_BYTE(p) (byte)inb(p) | |
25184 | -#endif | |
25185 | +# ifdef REALLY_FAST_IO | |
25186 | +# define IN_BYTE(p) (byte)inb(p) | |
25187 | +# define IN_WORD(p) (short)inw(p) | |
25188 | +# else | |
25189 | +# define IN_BYTE(p) (byte)inb_p(p) | |
25190 | +# define IN_WORD(p) (short)inw_p(p) | |
25191 | +# endif | |
25192 | #endif | |
25193 | ||
25194 | /* | |
25195 | @@ -286,14 +348,74 @@ | |
25196 | typedef union { | |
25197 | unsigned all : 8; /* all of the bits together */ | |
25198 | struct { | |
25199 | +#if defined(__LITTLE_ENDIAN_BITFIELD) | |
25200 | unsigned set_geometry : 1; /* respecify drive geometry */ | |
25201 | unsigned recalibrate : 1; /* seek to cyl 0 */ | |
25202 | unsigned set_multmode : 1; /* set multmode count */ | |
25203 | unsigned set_tune : 1; /* tune interface for drive */ | |
25204 | - unsigned reserved : 4; /* unused */ | |
25205 | + unsigned serviced : 1; /* service command */ | |
25206 | + unsigned reserved : 3; /* unused */ | |
25207 | +#elif defined(__BIG_ENDIAN_BITFIELD) | |
25208 | + unsigned reserved : 3; /* unused */ | |
25209 | + unsigned serviced : 1; /* service command */ | |
25210 | + unsigned set_tune : 1; /* tune interface for drive */ | |
25211 | + unsigned set_multmode : 1; /* set multmode count */ | |
25212 | + unsigned recalibrate : 1; /* seek to cyl 0 */ | |
25213 | + unsigned set_geometry : 1; /* respecify drive geometry */ | |
25214 | +#else | |
25215 | +#error "Please fix <asm/byteorder.h>" | |
25216 | +#endif | |
25217 | } b; | |
25218 | } special_t; | |
25219 | ||
25220 | +typedef union { | |
25221 | + unsigned all : 8; /* all of the bits together */ | |
25222 | + struct { | |
25223 | +#if defined(__LITTLE_ENDIAN_BITFIELD) | |
25224 | + unsigned head : 4; /* always zeros here */ | |
25225 | + unsigned unit : 1; /* drive select number: 0/1 */ | |
25226 | + unsigned bit5 : 1; /* always 1 */ | |
25227 | + unsigned lba : 1; /* using LBA instead of CHS */ | |
25228 | + unsigned bit7 : 1; /* always 1 */ | |
25229 | +#elif defined(__BIG_ENDIAN_BITFIELD) | |
25230 | + unsigned bit7 : 1; /* always 1 */ | |
25231 | + unsigned lba : 1; /* using LBA instead of CHS */ | |
25232 | + unsigned bit5 : 1; /* always 1 */ | |
25233 | + unsigned unit : 1; /* drive select number: 0/1 */ | |
25234 | + unsigned head : 4; /* always zeros here */ | |
25235 | +#else | |
25236 | +#error "Please fix <asm/byteorder.h>" | |
25237 | +#endif | |
25238 | + } b; | |
25239 | +} select_t; | |
25240 | + | |
25241 | +typedef union { | |
25242 | + unsigned all : 8; /* all of the bits together */ | |
25243 | + struct { | |
25244 | +#if defined(__LITTLE_ENDIAN_BITFIELD) | |
25245 | + unsigned bit0 : 1; | |
25246 | + unsigned nIEN : 1; /* device INTRQ to host */ | |
25247 | + unsigned SRST : 1; /* host soft reset bit */ | |
25248 | + unsigned bit3 : 1; /* ATA-2 thingy */ | |
25249 | + unsigned reserved456 : 3; | |
25250 | + unsigned HOB : 1; /* 48-bit address ordering */ | |
25251 | +#elif defined(__BIG_ENDIAN_BITFIELD) | |
25252 | + unsigned HOB : 1; /* 48-bit address ordering */ | |
25253 | + unsigned reserved456 : 3; | |
25254 | + unsigned bit3 : 1; /* ATA-2 thingy */ | |
25255 | + unsigned SRST : 1; /* host soft reset bit */ | |
25256 | + unsigned nIEN : 1; /* device INTRQ to host */ | |
25257 | + unsigned bit0 : 1; | |
25258 | +#else | |
25259 | +#error "Please fix <asm/byteorder.h>" | |
25260 | +#endif | |
25261 | + } b; | |
25262 | +} control_t; | |
25263 | + | |
25264 | + | |
25265 | +struct ide_driver_s; | |
25266 | +struct ide_settings_s; | |
25267 | + | |
25268 | typedef struct ide_drive_s { | |
25269 | request_queue_t queue; /* request queue */ | |
25270 | struct ide_drive_s *next; /* circular list of hwgroup drives */ | |
25271 | @@ -328,6 +450,12 @@ | |
25272 | unsigned autotune : 2; /* 1=autotune, 2=noautotune, 0=default */ | |
25273 | unsigned remap_0_to_1 : 2; /* 0=remap if ezdrive, 1=remap, 2=noremap */ | |
25274 | unsigned ata_flash : 1; /* 1=present, 0=default */ | |
25275 | + unsigned addressing; /* : 3; | |
25276 | + * 0=28-bit | |
25277 | + * 1=48-bit | |
25278 | + * 2=48-bit doing 28-bit | |
25279 | + * 3=64-bit | |
25280 | + */ | |
25281 | byte scsi; /* 0=default, 1=skip current ide-subdriver for ide-scsi emulation */ | |
25282 | byte media; /* disk, cdrom, tape, floppy, ... */ | |
25283 | select_t select; /* basic drive/head select reg value */ | |
25284 | @@ -340,7 +468,7 @@ | |
25285 | byte bad_wstat; /* used for ignoring WRERR_STAT */ | |
25286 | byte nowerr; /* used for ignoring WRERR_STAT */ | |
25287 | byte sect0; /* offset of first sector for DM6:DDO */ | |
25288 | - byte usage; /* current "open()" count for drive */ | |
25289 | + unsigned int usage; /* current "open()" count for drive */ | |
25290 | byte head; /* "real" number of heads */ | |
25291 | byte sect; /* "real" sectors per track */ | |
25292 | byte bios_head; /* BIOS/fdisk/LILO number of heads */ | |
25293 | @@ -348,17 +476,18 @@ | |
25294 | unsigned int bios_cyl; /* BIOS/fdisk/LILO number of cyls */ | |
25295 | unsigned int cyl; /* "real" number of cyls */ | |
25296 | unsigned long capacity; /* total number of sectors */ | |
25297 | + unsigned long long capacity48; /* total number of sectors */ | |
25298 | unsigned int drive_data; /* for use by tuneproc/selectproc as needed */ | |
25299 | - void *hwif; /* actually (ide_hwif_t *) */ | |
25300 | + struct hwif_s *hwif; /* actually (ide_hwif_t *) */ | |
25301 | wait_queue_head_t wqueue; /* used to wait for drive in open() */ | |
25302 | struct hd_driveid *id; /* drive model identification info */ | |
25303 | struct hd_struct *part; /* drive partition table */ | |
25304 | char name[4]; /* drive name, such as "hda" */ | |
25305 | - void *driver; /* (ide_driver_t *) */ | |
25306 | + struct ide_driver_s *driver; /* (ide_driver_t *) */ | |
25307 | void *driver_data; /* extra driver data */ | |
25308 | devfs_handle_t de; /* directory for device */ | |
25309 | struct proc_dir_entry *proc; /* /proc/ide/ directory entry */ | |
25310 | - void *settings; /* /proc/ide/ drive settings */ | |
25311 | + struct ide_settings_s *settings; /* /proc/ide/ drive settings */ | |
25312 | char driver_req[10]; /* requests specific driver */ | |
25313 | int last_lun; /* last logical unit */ | |
25314 | int forced_lun; /* if hdxlun was given at boot */ | |
25315 | @@ -369,6 +498,8 @@ | |
25316 | byte init_speed; /* transfer rate set at boot */ | |
25317 | byte current_speed; /* current transfer rate set */ | |
25318 | byte dn; /* now wide spread use */ | |
25319 | + byte wcache; /* status of write cache */ | |
25320 | + byte acoustic; /* acoustic management */ | |
25321 | unsigned int failures; /* current failure count */ | |
25322 | unsigned int max_failures; /* maximum allowed failure count */ | |
25323 | } ide_drive_t; | |
25324 | @@ -387,6 +518,7 @@ | |
25325 | typedef enum { ide_dma_read, ide_dma_write, ide_dma_begin, | |
25326 | ide_dma_end, ide_dma_check, ide_dma_on, | |
25327 | ide_dma_off, ide_dma_off_quietly, ide_dma_test_irq, | |
25328 | + ide_dma_host_on, ide_dma_host_off, | |
25329 | ide_dma_bad_drive, ide_dma_good_drive, | |
25330 | ide_dma_verbose, ide_dma_retune, | |
25331 | ide_dma_lostirq, ide_dma_timeout | |
25332 | @@ -412,6 +544,81 @@ | |
25333 | typedef void (ide_ideproc_t)(ide_ide_action_t, ide_drive_t *, void *, unsigned int); | |
25334 | ||
25335 | /* | |
25336 | + * mapping stuff, prepare for highmem... | |
25337 | + * | |
25338 | + * temporarily mapping a (possible) highmem bio for PIO transfer | |
25339 | + */ | |
25340 | +#define ide_rq_offset(rq) \ | |
25341 | + (((rq)->hard_cur_sectors - (rq)->current_nr_sectors) << 9) | |
25342 | + | |
25343 | +extern inline void *ide_map_buffer(struct request *rq, unsigned long *flags) | |
25344 | +{ | |
25345 | + return rq->buffer + ide_rq_offset(rq); | |
25346 | +} | |
25347 | + | |
25348 | +extern inline void ide_unmap_buffer(char *buffer, unsigned long *flags) | |
25349 | +{ | |
25350 | + do { } while (0); | |
25351 | +} | |
25352 | + | |
25353 | +/* | |
25354 | + * A Verbose noise maker for debugging on the attempted transfer rates. | |
25355 | + */ | |
25356 | +extern inline char *ide_xfer_verbose (byte xfer_rate) | |
25357 | +{ | |
25358 | + switch(xfer_rate) { | |
25359 | + case XFER_UDMA_7: return("UDMA 7"); | |
25360 | + case XFER_UDMA_6: return("UDMA 6"); | |
25361 | + case XFER_UDMA_5: return("UDMA 5"); | |
25362 | + case XFER_UDMA_4: return("UDMA 4"); | |
25363 | + case XFER_UDMA_3: return("UDMA 3"); | |
25364 | + case XFER_UDMA_2: return("UDMA 2"); | |
25365 | + case XFER_UDMA_1: return("UDMA 1"); | |
25366 | + case XFER_UDMA_0: return("UDMA 0"); | |
25367 | + case XFER_MW_DMA_2: return("MW DMA 2"); | |
25368 | + case XFER_MW_DMA_1: return("MW DMA 1"); | |
25369 | + case XFER_MW_DMA_0: return("MW DMA 0"); | |
25370 | + case XFER_SW_DMA_2: return("SW DMA 2"); | |
25371 | + case XFER_SW_DMA_1: return("SW DMA 1"); | |
25372 | + case XFER_SW_DMA_0: return("SW DMA 0"); | |
25373 | + case XFER_PIO_4: return("PIO 4"); | |
25374 | + case XFER_PIO_3: return("PIO 3"); | |
25375 | + case XFER_PIO_2: return("PIO 2"); | |
25376 | + case XFER_PIO_1: return("PIO 1"); | |
25377 | + case XFER_PIO_0: return("PIO 0"); | |
25378 | + case XFER_PIO_SLOW: return("PIO SLOW"); | |
25379 | + default: return("XFER ERROR"); | |
25380 | + } | |
25381 | +} | |
25382 | + | |
25383 | +/* | |
25384 | + * A Verbose noise maker for debugging on the attempted dmaing calls. | |
25385 | + */ | |
25386 | +extern inline char *ide_dmafunc_verbose (ide_dma_action_t dmafunc) | |
25387 | +{ | |
25388 | + switch (dmafunc) { | |
25389 | + case ide_dma_read: return("ide_dma_read"); | |
25390 | + case ide_dma_write: return("ide_dma_write"); | |
25391 | + case ide_dma_begin: return("ide_dma_begin"); | |
25392 | + case ide_dma_end: return("ide_dma_end:"); | |
25393 | + case ide_dma_check: return("ide_dma_check"); | |
25394 | + case ide_dma_on: return("ide_dma_on"); | |
25395 | + case ide_dma_off: return("ide_dma_off"); | |
25396 | + case ide_dma_off_quietly: return("ide_dma_off_quietly"); | |
25397 | + case ide_dma_test_irq: return("ide_dma_test_irq"); | |
25398 | + case ide_dma_host_on: return("ide_dma_host_on"); | |
25399 | + case ide_dma_host_off: return("ide_dma_host_off"); | |
25400 | + case ide_dma_bad_drive: return("ide_dma_bad_drive"); | |
25401 | + case ide_dma_good_drive: return("ide_dma_good_drive"); | |
25402 | + case ide_dma_verbose: return("ide_dma_verbose"); | |
25403 | + case ide_dma_retune: return("ide_dma_retune"); | |
25404 | + case ide_dma_lostirq: return("ide_dma_lostirq"); | |
25405 | + case ide_dma_timeout: return("ide_dma_timeout"); | |
25406 | + default: return("unknown"); | |
25407 | + } | |
25408 | +} | |
25409 | + | |
25410 | +/* | |
25411 | * An ide_tuneproc_t() is used to set the speed of an IDE interface | |
25412 | * to a particular PIO mode. The "byte" parameter is used | |
25413 | * to select the PIO mode by number (0,1,2,3,4,5), and a value of 255 | |
25414 | @@ -438,19 +645,7 @@ | |
25415 | /* | |
25416 | * ide soft-power support | |
25417 | */ | |
25418 | -typedef int (ide_busproc_t) (struct hwif_s *, int); | |
25419 | - | |
25420 | -/* | |
25421 | - * hwif_chipset_t is used to keep track of the specific hardware | |
25422 | - * chipset used by each IDE interface, if known. | |
25423 | - */ | |
25424 | -typedef enum { ide_unknown, ide_generic, ide_pci, | |
25425 | - ide_cmd640, ide_dtc2278, ide_ali14xx, | |
25426 | - ide_qd65xx, ide_umc8672, ide_ht6560b, | |
25427 | - ide_pdc4030, ide_rz1000, ide_trm290, | |
25428 | - ide_cmd646, ide_cy82c693, ide_4drives, | |
25429 | - ide_pmac, ide_etrax100 | |
25430 | -} hwif_chipset_t; | |
25431 | +typedef int (ide_busproc_t) (ide_drive_t *, int); | |
25432 | ||
25433 | #define IDE_CHIPSET_PCI_MASK \ | |
25434 | ((1<<ide_pci)|(1<<ide_cmd646)|(1<<ide_ali14xx)) | |
25435 | @@ -468,21 +663,29 @@ | |
25436 | ||
25437 | typedef struct hwif_s { | |
25438 | struct hwif_s *next; /* for linked-list in ide_hwgroup_t */ | |
25439 | - void *hwgroup; /* actually (ide_hwgroup_t *) */ | |
25440 | + struct hwgroup_s *hwgroup; /* actually (ide_hwgroup_t *) */ | |
25441 | ide_ioreg_t io_ports[IDE_NR_PORTS]; /* task file registers */ | |
25442 | +/* | |
25443 | + * FIXME!! need a generic register set :-/ PPC guys ideas?? | |
25444 | + * | |
25445 | + * ide_mmioreg_t mm_ports[IDE_NR_PORTS]; "task file registers" | |
25446 | + * | |
25447 | + */ | |
25448 | hw_regs_t hw; /* Hardware info */ | |
25449 | ide_drive_t drives[MAX_DRIVES]; /* drive info */ | |
25450 | struct gendisk *gd; /* gendisk structure */ | |
25451 | - ide_tuneproc_t *tuneproc; /* routine to tune PIO mode for drives */ | |
25452 | - ide_speedproc_t *speedproc; /* routine to retune DMA modes for drives */ | |
25453 | - ide_selectproc_t *selectproc; /* tweaks hardware to select drive */ | |
25454 | - ide_resetproc_t *resetproc; /* routine to reset controller after a disk reset */ | |
25455 | - ide_intrproc_t *intrproc; /* special interrupt handling for shared pci interrupts */ | |
25456 | - ide_maskproc_t *maskproc; /* special host masking for drive selection */ | |
25457 | - ide_quirkproc_t *quirkproc; /* check host's drive quirk list */ | |
25458 | - ide_rw_proc_t *rwproc; /* adjust timing based upon rq->cmd direction */ | |
25459 | - ide_ideproc_t *ideproc; /* CPU-polled transfer routine */ | |
25460 | - ide_dmaproc_t *dmaproc; /* dma read/write/abort routine */ | |
25461 | + int addressing; /* hosts addressing */ | |
25462 | + void (*tuneproc)(ide_drive_t *, byte); /* routine to tune PIO mode for drives */ | |
25463 | + int (*speedproc)(ide_drive_t *, byte); /* routine to retune DMA modes for drives */ | |
25464 | + void (*selectproc)(ide_drive_t *); /* tweaks hardware to select drive */ | |
25465 | + void (*resetproc)(ide_drive_t *); /* routine to reset controller after a disk reset */ | |
25466 | + void (*intrproc)(ide_drive_t *); /* special interrupt handling for shared pci interrupts */ | |
25467 | + void (*maskproc)(ide_drive_t *, int); /* special host masking for drive selection */ | |
25468 | + int (*quirkproc)(ide_drive_t *); /* check host's drive quirk list */ | |
25469 | + void (*rwproc)(ide_drive_t *, ide_dma_action_t); /* adjust timing based upon rq->cmd direction */ | |
25470 | + void (*ideproc)(ide_ide_action_t, ide_drive_t *, void *, unsigned int); /* CPU-polled transfer routine */ | |
25471 | + int (*dmaproc)(ide_dma_action_t, ide_drive_t *); /* dma read/write/abort routine */ | |
25472 | + int (*busproc)(ide_drive_t *, int); /* driver soft-power interface */ | |
25473 | unsigned int *dmatable_cpu; /* dma physical region descriptor table (cpu view) */ | |
25474 | dma_addr_t dmatable_dma; /* dma physical region descriptor table (dma view) */ | |
25475 | struct scatterlist *sg_table; /* Scatter-gather list used to build the above */ | |
25476 | @@ -507,6 +710,7 @@ | |
25477 | unsigned reset : 1; /* reset after probe */ | |
25478 | unsigned autodma : 1; /* automatically try to enable DMA at boot */ | |
25479 | unsigned udma_four : 1; /* 1=ATA-66 capable, 0=default */ | |
25480 | + unsigned highmem : 1; /* can do full 32-bit dma */ | |
25481 | byte channel; /* for dual-port chips: 0=primary, 1=secondary */ | |
25482 | #ifdef CONFIG_BLK_DEV_IDEPCI | |
25483 | struct pci_dev *pci_dev; /* for pci chipsets */ | |
25484 | @@ -517,11 +721,9 @@ | |
25485 | #endif | |
25486 | byte straight8; /* Alan's straight 8 check */ | |
25487 | void *hwif_data; /* extra hwif data */ | |
25488 | - ide_busproc_t *busproc; /* driver soft-power interface */ | |
25489 | byte bus_state; /* power state of the IDE bus */ | |
25490 | } ide_hwif_t; | |
25491 | ||
25492 | - | |
25493 | /* | |
25494 | * Status returned from various ide_ functions | |
25495 | */ | |
25496 | @@ -533,7 +735,9 @@ | |
25497 | /* | |
25498 | * internal ide interrupt handler type | |
25499 | */ | |
25500 | +typedef ide_startstop_t (ide_pre_handler_t)(ide_drive_t *, struct request *); | |
25501 | typedef ide_startstop_t (ide_handler_t)(ide_drive_t *); | |
25502 | +typedef ide_startstop_t (ide_post_handler_t)(ide_drive_t *); | |
25503 | ||
25504 | /* | |
25505 | * when ide_timer_expiry fires, invoke a handler of this type | |
25506 | @@ -543,6 +747,7 @@ | |
25507 | ||
25508 | typedef struct hwgroup_s { | |
25509 | ide_handler_t *handler;/* irq handler, if active */ | |
25510 | + ide_handler_t *handler_save;/* irq handler, if active */ | |
25511 | volatile int busy; /* BOOL: protects all fields below */ | |
25512 | int sleeping; /* BOOL: wake us up on timer expiry */ | |
25513 | ide_drive_t *drive; /* current drive */ | |
25514 | @@ -552,8 +757,11 @@ | |
25515 | struct request wrq; /* local copy of current write rq */ | |
25516 | unsigned long poll_timeout; /* timeout value during long polls */ | |
25517 | ide_expiry_t *expiry; /* queried upon timeouts */ | |
25518 | + int pio_clock; /* ide_system_bus_speed */ | |
25519 | } ide_hwgroup_t; | |
25520 | ||
25521 | +/* structure attached to the request for IDE_TASK_CMDS */ | |
25522 | + | |
25523 | /* | |
25524 | * configurable drive settings | |
25525 | */ | |
25526 | @@ -604,6 +812,8 @@ | |
25527 | #ifdef CONFIG_PROC_FS | |
25528 | void proc_ide_create(void); | |
25529 | void proc_ide_destroy(void); | |
25530 | +void recreate_proc_ide_device(ide_hwif_t *, ide_drive_t *); | |
25531 | +void destroy_proc_ide_device(ide_hwif_t *, ide_drive_t *); | |
25532 | void destroy_proc_ide_drives(ide_hwif_t *); | |
25533 | void create_proc_ide_interfaces(void); | |
25534 | void ide_add_proc_entries(struct proc_dir_entry *dir, ide_proc_entry_t *p, void *data); | |
25535 | @@ -635,20 +845,6 @@ | |
25536 | */ | |
25537 | #define IDE_SUBDRIVER_VERSION 1 | |
25538 | ||
25539 | -typedef int (ide_cleanup_proc)(ide_drive_t *); | |
25540 | -typedef ide_startstop_t (ide_do_request_proc)(ide_drive_t *, struct request *, unsigned long); | |
25541 | -typedef void (ide_end_request_proc)(byte, ide_hwgroup_t *); | |
25542 | -typedef int (ide_ioctl_proc)(ide_drive_t *, struct inode *, struct file *, unsigned int, unsigned long); | |
25543 | -typedef int (ide_open_proc)(struct inode *, struct file *, ide_drive_t *); | |
25544 | -typedef void (ide_release_proc)(struct inode *, struct file *, ide_drive_t *); | |
25545 | -typedef int (ide_check_media_change_proc)(ide_drive_t *); | |
25546 | -typedef void (ide_revalidate_proc)(ide_drive_t *); | |
25547 | -typedef void (ide_pre_reset_proc)(ide_drive_t *); | |
25548 | -typedef unsigned long (ide_capacity_proc)(ide_drive_t *); | |
25549 | -typedef ide_startstop_t (ide_special_proc)(ide_drive_t *); | |
25550 | -typedef void (ide_setting_proc)(ide_drive_t *); | |
25551 | -typedef int (ide_driver_reinit_proc)(ide_drive_t *); | |
25552 | - | |
25553 | typedef struct ide_driver_s { | |
25554 | const char *name; | |
25555 | const char *version; | |
25556 | @@ -656,22 +852,31 @@ | |
25557 | unsigned busy : 1; | |
25558 | unsigned supports_dma : 1; | |
25559 | unsigned supports_dsc_overlap : 1; | |
25560 | - ide_cleanup_proc *cleanup; | |
25561 | - ide_do_request_proc *do_request; | |
25562 | - ide_end_request_proc *end_request; | |
25563 | - ide_ioctl_proc *ioctl; | |
25564 | - ide_open_proc *open; | |
25565 | - ide_release_proc *release; | |
25566 | - ide_check_media_change_proc *media_change; | |
25567 | - ide_revalidate_proc *revalidate; | |
25568 | - ide_pre_reset_proc *pre_reset; | |
25569 | - ide_capacity_proc *capacity; | |
25570 | - ide_special_proc *special; | |
25571 | - ide_proc_entry_t *proc; | |
25572 | - ide_driver_reinit_proc *driver_reinit; | |
25573 | + int (*cleanup)(ide_drive_t *); | |
25574 | + int (*standby)(ide_drive_t *); | |
25575 | + int (*suspend)(ide_drive_t *); | |
25576 | + int (*resume)(ide_drive_t *); | |
25577 | + int (*flushcache)(ide_drive_t *); | |
25578 | + ide_startstop_t (*do_request)(ide_drive_t *, struct request *, unsigned long); | |
25579 | + int (*end_request)(ide_drive_t *, int); | |
25580 | + byte (*sense)(ide_drive_t *, const char *, byte); | |
25581 | + ide_startstop_t (*error)(ide_drive_t *, const char *, byte); | |
25582 | + int (*ioctl)(ide_drive_t *, struct inode *, struct file *, unsigned int, unsigned long); | |
25583 | + int (*open)(struct inode *, struct file *, ide_drive_t *); | |
25584 | + void (*release)(struct inode *, struct file *, ide_drive_t *); | |
25585 | + int (*media_change)(ide_drive_t *); | |
25586 | + void (*revalidate)(ide_drive_t *); | |
25587 | + void (*pre_reset)(ide_drive_t *); | |
25588 | + unsigned long (*capacity)(ide_drive_t *); | |
25589 | + ide_startstop_t (*special)(ide_drive_t *); | |
25590 | + ide_proc_entry_t *proc; | |
25591 | + int (*init)(void); | |
25592 | + int (*reinit)(ide_drive_t *); | |
25593 | + void (*ata_prebuilder)(ide_drive_t *); | |
25594 | + void (*atapi_prebuilder)(ide_drive_t *); | |
25595 | } ide_driver_t; | |
25596 | ||
25597 | -#define DRIVER(drive) ((ide_driver_t *)((drive)->driver)) | |
25598 | +#define DRIVER(drive) ((drive)->driver) | |
25599 | ||
25600 | /* | |
25601 | * IDE modules. | |
25602 | @@ -711,21 +916,7 @@ | |
25603 | #define LOCAL_END_REQUEST /* Don't generate end_request in blk.h */ | |
25604 | #include <linux/blk.h> | |
25605 | ||
25606 | -void ide_end_request(byte uptodate, ide_hwgroup_t *hwgroup); | |
25607 | - | |
25608 | -/* | |
25609 | - * This is used for (nearly) all data transfers from/to the IDE interface | |
25610 | - * FIXME for 2.5, to a pointer pass verses memcpy........ | |
25611 | - */ | |
25612 | -void ide_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount); | |
25613 | -void ide_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount); | |
25614 | - | |
25615 | -/* | |
25616 | - * This is used for (nearly) all ATAPI data transfers from/to the IDE interface | |
25617 | - * FIXME for 2.5, to a pointer pass verses memcpy........ | |
25618 | - */ | |
25619 | -void atapi_input_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount); | |
25620 | -void atapi_output_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount); | |
25621 | +int ide_end_request (ide_drive_t *drive, int uptodate); | |
25622 | ||
25623 | /* | |
25624 | * This is used on exit from the driver, to designate the next irq handler | |
25625 | @@ -748,7 +939,7 @@ | |
25626 | * Issue a simple drive command | |
25627 | * The drive must be selected beforehand. | |
25628 | */ | |
25629 | -void ide_cmd(ide_drive_t *drive, byte cmd, byte nsect, ide_handler_t *handler); | |
25630 | +void ide_cmd (ide_drive_t *drive, byte cmd, byte nsect, ide_handler_t *handler); | |
25631 | ||
25632 | /* | |
25633 | * ide_fixstring() cleans up and (optionally) byte-swaps a text string, | |
25634 | @@ -768,8 +959,6 @@ | |
25635 | */ | |
25636 | int ide_wait_stat (ide_startstop_t *startstop, ide_drive_t *drive, byte good, byte bad, unsigned long timeout); | |
25637 | ||
25638 | -int ide_wait_noerr (ide_drive_t *drive, byte good, byte bad, unsigned long timeout); | |
25639 | - | |
25640 | /* | |
25641 | * This routine is called from the partition-table code in genhd.c | |
25642 | * to "convert" a drive to a logical geometry with fewer than 1024 cyls. | |
25643 | @@ -796,7 +985,7 @@ | |
25644 | * Re-Start an operation for an IDE interface. | |
25645 | * The caller should return immediately after invoking this. | |
25646 | */ | |
25647 | -ide_startstop_t restart_request (ide_drive_t *); | |
25648 | +int restart_request (ide_drive_t *, struct request *); | |
25649 | ||
25650 | /* | |
25651 | * This function is intended to be used prior to invoking ide_do_drive_cmd(). | |
25652 | @@ -843,24 +1032,100 @@ | |
25653 | /* | |
25654 | * Clean up after success/failure of an explicit drive cmd. | |
25655 | * stat/err are used only when (HWGROUP(drive)->rq->cmd == IDE_DRIVE_CMD). | |
25656 | + * stat/err are used only when (HWGROUP(drive)->rq->cmd == IDE_DRIVE_TASK_MASK). | |
25657 | */ | |
25658 | void ide_end_drive_cmd (ide_drive_t *drive, byte stat, byte err); | |
25659 | ||
25660 | /* | |
25661 | - * Issue ATA command and wait for completion. | |
25662 | + * Issue ATA command and wait for completion. use for implementing commands in kernel | |
25663 | */ | |
25664 | int ide_wait_cmd (ide_drive_t *drive, int cmd, int nsect, int feature, int sectors, byte *buf); | |
25665 | + | |
25666 | int ide_wait_cmd_task (ide_drive_t *drive, byte *buf); | |
25667 | + | |
25668 | +typedef struct ide_task_s { | |
25669 | + task_ioreg_t tfRegister[8]; | |
25670 | + task_ioreg_t hobRegister[8]; | |
25671 | + ide_reg_valid_t tf_out_flags; | |
25672 | + ide_reg_valid_t tf_in_flags; | |
25673 | + int data_phase; | |
25674 | + int command_type; | |
25675 | + ide_pre_handler_t *prehandler; | |
25676 | + ide_handler_t *handler; | |
25677 | + ide_post_handler_t *posthandler; | |
25678 | + struct request *rq; /* copy of request */ | |
25679 | + void *special; /* valid_t generally */ | |
25680 | +} ide_task_t; | |
25681 | + | |
25682 | +typedef struct pkt_task_s { | |
25683 | + task_ioreg_t tfRegister[8]; | |
25684 | + int data_phase; | |
25685 | + int command_type; | |
25686 | + ide_handler_t *handler; | |
25687 | + struct request *rq; /* copy of request */ | |
25688 | + void *special; | |
25689 | +} pkt_task_t; | |
25690 | + | |
25691 | +void ata_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount); | |
25692 | +void ata_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount); | |
25693 | +void atapi_input_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount); | |
25694 | +void atapi_output_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount); | |
25695 | +void taskfile_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount); | |
25696 | +void taskfile_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount); | |
25697 | + | |
25698 | +int drive_is_ready (ide_drive_t *drive); | |
25699 | +int wait_for_ready (ide_drive_t *drive, int timeout); | |
25700 | + | |
25701 | +/* | |
25702 | + * taskfile io for disks for now...and builds request from ide_ioctl | |
25703 | + */ | |
25704 | +ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task); | |
25705 | + | |
25706 | +void ide_end_taskfile (ide_drive_t *drive, byte stat, byte err); | |
25707 | + | |
25708 | +/* | |
25709 | + * Special Flagged Register Validation Caller | |
25710 | + */ | |
25711 | +ide_startstop_t flagged_taskfile (ide_drive_t *drive, ide_task_t *task); | |
25712 | + | |
25713 | +ide_startstop_t set_multmode_intr (ide_drive_t *drive); | |
25714 | +ide_startstop_t set_geometry_intr (ide_drive_t *drive); | |
25715 | +ide_startstop_t recal_intr (ide_drive_t *drive); | |
25716 | +ide_startstop_t task_no_data_intr (ide_drive_t *drive); | |
25717 | +ide_startstop_t task_in_intr (ide_drive_t *drive); | |
25718 | +ide_startstop_t task_mulin_intr (ide_drive_t *drive); | |
25719 | +ide_startstop_t pre_task_out_intr (ide_drive_t *drive, struct request *rq); | |
25720 | +ide_startstop_t task_out_intr (ide_drive_t *drive); | |
25721 | +ide_startstop_t pre_task_mulout_intr (ide_drive_t *drive, struct request *rq); | |
25722 | +ide_startstop_t task_mulout_intr (ide_drive_t *drive); | |
25723 | +void ide_init_drive_taskfile (struct request *rq); | |
25724 | + | |
25725 | +int ide_raw_taskfile (ide_drive_t *drive, ide_task_t *cmd, byte *buf); | |
25726 | + | |
25727 | +ide_pre_handler_t * ide_pre_handler_parser (struct hd_drive_task_hdr *taskfile, struct hd_drive_hob_hdr *hobfile); | |
25728 | +ide_handler_t * ide_handler_parser (struct hd_drive_task_hdr *taskfile, struct hd_drive_hob_hdr *hobfile); | |
25729 | +ide_post_handler_t * ide_post_handler_parser (struct hd_drive_task_hdr *taskfile, struct hd_drive_hob_hdr *hobfile); | |
25730 | +/* Expects args is a full set of TF registers and parses the command type */ | |
25731 | +int ide_cmd_type_parser (ide_task_t *args); | |
25732 | + | |
25733 | +int ide_taskfile_ioctl (ide_drive_t *drive, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); | |
25734 | +int ide_cmd_ioctl (ide_drive_t *drive, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); | |
25735 | +int ide_task_ioctl (ide_drive_t *drive, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); | |
25736 | + | |
25737 | +#ifdef CONFIG_PKT_TASK_IOCTL | |
25738 | +int pkt_taskfile_ioctl (ide_drive_t *drive, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); | |
25739 | +#endif /* CONFIG_PKT_TASK_IOCTL */ | |
25740 | ||
25741 | void ide_delay_50ms (void); | |
25742 | int system_bus_clock(void); | |
25743 | ||
25744 | byte ide_auto_reduce_xfer (ide_drive_t *drive); | |
25745 | int ide_driveid_update (ide_drive_t *drive); | |
25746 | -int ide_ata66_check (ide_drive_t *drive, byte cmd, byte nsect, byte feature); | |
25747 | +int ide_ata66_check (ide_drive_t *drive, ide_task_t *args); | |
25748 | int ide_config_drive_speed (ide_drive_t *drive, byte speed); | |
25749 | byte eighty_ninty_three (ide_drive_t *drive); | |
25750 | -int set_transfer (ide_drive_t *drive, byte cmd, byte nsect, byte feature); | |
25751 | +int set_transfer (ide_drive_t *drive, ide_task_t *args); | |
25752 | +int taskfile_lib_get_identify (ide_drive_t *drive, byte *buf); | |
25753 | ||
25754 | /* | |
25755 | * ide_system_bus_speed() returns what we think is the system VESA/PCI | |
25756 | @@ -871,12 +1136,6 @@ | |
25757 | int ide_system_bus_speed (void); | |
25758 | ||
25759 | /* | |
25760 | - * ide_multwrite() transfers a block of up to mcount sectors of data | |
25761 | - * to a drive as part of a disk multwrite operation. | |
25762 | - */ | |
25763 | -int ide_multwrite (ide_drive_t *drive, unsigned int mcount); | |
25764 | - | |
25765 | -/* | |
25766 | * ide_stall_queue() can be used by a drive to give excess bandwidth back | |
25767 | * to the hwgroup by sleeping for timeout jiffies. | |
25768 | */ | |
25769 | @@ -905,23 +1164,30 @@ | |
25770 | extern ide_proc_entry_t generic_subdriver_entries[]; | |
25771 | #endif | |
25772 | ||
25773 | +int ide_reinit_drive (ide_drive_t *drive); | |
25774 | + | |
25775 | #ifdef _IDE_C | |
25776 | #ifdef CONFIG_BLK_DEV_IDE | |
25777 | int ideprobe_init (void); | |
25778 | #endif /* CONFIG_BLK_DEV_IDE */ | |
25779 | #ifdef CONFIG_BLK_DEV_IDEDISK | |
25780 | +int idedisk_reinit (ide_drive_t *drive); | |
25781 | int idedisk_init (void); | |
25782 | #endif /* CONFIG_BLK_DEV_IDEDISK */ | |
25783 | #ifdef CONFIG_BLK_DEV_IDECD | |
25784 | +int ide_cdrom_reinit (ide_drive_t *drive); | |
25785 | int ide_cdrom_init (void); | |
25786 | #endif /* CONFIG_BLK_DEV_IDECD */ | |
25787 | #ifdef CONFIG_BLK_DEV_IDETAPE | |
25788 | +int idetape_reinit (ide_drive_t *drive); | |
25789 | int idetape_init (void); | |
25790 | #endif /* CONFIG_BLK_DEV_IDETAPE */ | |
25791 | #ifdef CONFIG_BLK_DEV_IDEFLOPPY | |
25792 | +int idefloppy_reinit (ide_drive_t *drive); | |
25793 | int idefloppy_init (void); | |
25794 | #endif /* CONFIG_BLK_DEV_IDEFLOPPY */ | |
25795 | #ifdef CONFIG_BLK_DEV_IDESCSI | |
25796 | +int idescsi_reinit (ide_drive_t *drive); | |
25797 | int idescsi_init (void); | |
25798 | #endif /* CONFIG_BLK_DEV_IDESCSI */ | |
25799 | #endif /* _IDE_C */ | |
25800 | @@ -942,6 +1208,56 @@ | |
25801 | # define OFF_BOARD NEVER_BOARD | |
25802 | #endif /* CONFIG_BLK_DEV_OFFBOARD */ | |
25803 | ||
25804 | + | |
25805 | +typedef struct ide_pci_enablebit_s { | |
25806 | + byte reg; /* byte pci reg holding the enable-bit */ | |
25807 | + byte mask; /* mask to isolate the enable-bit */ | |
25808 | + byte val; /* value of masked reg when "enabled" */ | |
25809 | +} ide_pci_enablebit_t; | |
25810 | + | |
25811 | +typedef struct ide_pci_device_s { | |
25812 | + ide_pci_devid_t devid; | |
25813 | + char *name; | |
25814 | + void (*fixup_device)(struct pci_dev *, struct ide_pci_device_s *); | |
25815 | + unsigned int (*init_chipset)(struct pci_dev *, const char *); | |
25816 | + unsigned int (*ata66_check)(ide_hwif_t *); | |
25817 | + void (*init_hwif)(ide_hwif_t *); | |
25818 | + void (*dma_init)(ide_hwif_t *, unsigned long); | |
25819 | + ide_pci_enablebit_t enablebits[2]; | |
25820 | + byte bootable; | |
25821 | + unsigned int extra; | |
25822 | +} ide_pci_device_t; | |
25823 | + | |
25824 | +#ifdef LINUX_PCI_H | |
25825 | +extern inline void ide_register_xp_fix(struct pci_dev *dev) | |
25826 | +{ | |
25827 | + int i; | |
25828 | + unsigned short cmd; | |
25829 | + unsigned long flags; | |
25830 | + unsigned long base_address[4] = { 0x1f0, 0x3f4, 0x170, 0x374 }; | |
25831 | + | |
25832 | + local_irq_save(flags); | |
25833 | + pci_read_config_word(dev, PCI_COMMAND, &cmd); | |
25834 | + pci_write_config_word(dev, PCI_COMMAND, cmd & ~PCI_COMMAND_IO); | |
25835 | + for (i=0; i<4; i++) { | |
25836 | + dev->resource[i].start = 0; | |
25837 | + dev->resource[i].end = 0; | |
25838 | + dev->resource[i].flags = 0; | |
25839 | + } | |
25840 | + for (i=0; i<4; i++) { | |
25841 | + dev->resource[i].start = base_address[i]; | |
25842 | + dev->resource[i].flags |= PCI_BASE_ADDRESS_SPACE_IO; | |
25843 | + pci_write_config_dword(dev, | |
25844 | + (PCI_BASE_ADDRESS_0 + (i * 4)), | |
25845 | + dev->resource[i].start); | |
25846 | + } | |
25847 | + pci_write_config_word(dev, PCI_COMMAND, cmd); | |
25848 | + local_irq_restore(flags); | |
25849 | +} | |
25850 | + | |
25851 | +void ide_setup_pci_device(struct pci_dev *dev, ide_pci_device_t *d) __init; | |
25852 | +#endif /* LINUX_PCI_H */ | |
25853 | + | |
25854 | unsigned long ide_find_free_region (unsigned short size) __init; | |
25855 | void ide_scan_pcibus (int scan_direction) __init; | |
25856 | #endif | |
25857 | @@ -957,8 +1273,11 @@ | |
25858 | int ide_release_dma (ide_hwif_t *hwif); | |
25859 | void ide_setup_dma (ide_hwif_t *hwif, unsigned long dmabase, unsigned int num_ports) __init; | |
25860 | unsigned long ide_get_or_set_dma_base (ide_hwif_t *hwif, int extra, const char *name) __init; | |
25861 | -#endif | |
25862 | +#endif /* CONFIG_BLK_DEV_IDEPCI */ | |
25863 | ||
25864 | void hwif_unregister (ide_hwif_t *hwif); | |
25865 | ||
25866 | +void export_ide_init_queue (ide_drive_t *drive); | |
25867 | +byte export_probe_for_drive (ide_drive_t *drive); | |
25868 | + | |
25869 | #endif /* _IDE_H */ | |
25870 | --- linux.org/include/linux/hdreg.h Thu Nov 22 20:46:18 2001 | |
25871 | +++ linux-2.4.19-rc1-ac7/include/linux/hdreg.h Thu Jul 18 14:24:44 2002 | |
25872 | @@ -6,106 +6,315 @@ | |
25873 | * Various sources. | |
25874 | */ | |
25875 | ||
25876 | -#define HD_IRQ 14 /* the standard disk interrupt */ | |
25877 | +#define HD_IRQ 14 /* the standard disk interrupt */ | |
25878 | ||
25879 | /* ide.c has its own port definitions in "ide.h" */ | |
25880 | ||
25881 | /* Hd controller regs. Ref: IBM AT Bios-listing */ | |
25882 | -#define HD_DATA 0x1f0 /* _CTL when writing */ | |
25883 | -#define HD_ERROR 0x1f1 /* see err-bits */ | |
25884 | -#define HD_NSECTOR 0x1f2 /* nr of sectors to read/write */ | |
25885 | -#define HD_SECTOR 0x1f3 /* starting sector */ | |
25886 | -#define HD_LCYL 0x1f4 /* starting cylinder */ | |
25887 | -#define HD_HCYL 0x1f5 /* high byte of starting cyl */ | |
25888 | -#define HD_CURRENT 0x1f6 /* 101dhhhh , d=drive, hhhh=head */ | |
25889 | -#define HD_STATUS 0x1f7 /* see status-bits */ | |
25890 | -#define HD_FEATURE HD_ERROR /* same io address, read=error, write=feature */ | |
25891 | -#define HD_PRECOMP HD_FEATURE /* obsolete use of this port - predates IDE */ | |
25892 | -#define HD_COMMAND HD_STATUS /* same io address, read=status, write=cmd */ | |
25893 | +#define HD_DATA 0x1f0 /* _CTL when writing */ | |
25894 | +#define HD_ERROR 0x1f1 /* see err-bits */ | |
25895 | +#define HD_NSECTOR 0x1f2 /* nr of sectors to read/write */ | |
25896 | +#define HD_SECTOR 0x1f3 /* starting sector */ | |
25897 | +#define HD_LCYL 0x1f4 /* starting cylinder */ | |
25898 | +#define HD_HCYL 0x1f5 /* high byte of starting cyl */ | |
25899 | +#define HD_CURRENT 0x1f6 /* 101dhhhh , d=drive, hhhh=head */ | |
25900 | +#define HD_STATUS 0x1f7 /* see status-bits */ | |
25901 | +#define HD_FEATURE HD_ERROR /* same io address, read=error, write=feature */ | |
25902 | +#define HD_PRECOMP HD_FEATURE /* obsolete use of this port - predates IDE */ | |
25903 | +#define HD_COMMAND HD_STATUS /* same io address, read=status, write=cmd */ | |
25904 | ||
25905 | -#define HD_CMD 0x3f6 /* used for resets */ | |
25906 | -#define HD_ALTSTATUS 0x3f6 /* same as HD_STATUS but doesn't clear irq */ | |
25907 | +#define HD_CMD 0x3f6 /* used for resets */ | |
25908 | +#define HD_ALTSTATUS 0x3f6 /* same as HD_STATUS but doesn't clear irq */ | |
25909 | ||
25910 | /* remainder is shared between hd.c, ide.c, ide-cd.c, and the hdparm utility */ | |
25911 | ||
25912 | /* Bits of HD_STATUS */ | |
25913 | -#define ERR_STAT 0x01 | |
25914 | -#define INDEX_STAT 0x02 | |
25915 | -#define ECC_STAT 0x04 /* Corrected error */ | |
25916 | -#define DRQ_STAT 0x08 | |
25917 | -#define SEEK_STAT 0x10 | |
25918 | -#define WRERR_STAT 0x20 | |
25919 | -#define READY_STAT 0x40 | |
25920 | -#define BUSY_STAT 0x80 | |
25921 | - | |
25922 | -/* Values for HD_COMMAND */ | |
25923 | -#define WIN_RESTORE 0x10 | |
25924 | -#define WIN_READ 0x20 | |
25925 | -#define WIN_WRITE 0x30 | |
25926 | -#define WIN_WRITE_VERIFY 0x3C | |
25927 | -#define WIN_VERIFY 0x40 | |
25928 | -#define WIN_FORMAT 0x50 | |
25929 | -#define WIN_INIT 0x60 | |
25930 | -#define WIN_SEEK 0x70 | |
25931 | -#define WIN_DIAGNOSE 0x90 | |
25932 | -#define WIN_SPECIFY 0x91 /* set drive geometry translation */ | |
25933 | -#define WIN_IDLEIMMEDIATE 0xE1 /* force drive to become "ready" */ | |
25934 | -#define WIN_SETIDLE1 0xE3 | |
25935 | -#define WIN_SETIDLE2 0x97 | |
25936 | - | |
25937 | -#define WIN_STANDBYNOW1 0xE0 | |
25938 | -#define WIN_STANDBYNOW2 0x94 | |
25939 | -#define WIN_SLEEPNOW1 0xE6 | |
25940 | -#define WIN_SLEEPNOW2 0x99 | |
25941 | -#define WIN_CHECKPOWERMODE1 0xE5 | |
25942 | -#define WIN_CHECKPOWERMODE2 0x98 | |
25943 | - | |
25944 | -#define WIN_DOORLOCK 0xDE /* lock door on removable drives */ | |
25945 | -#define WIN_DOORUNLOCK 0xDF /* unlock door on removable drives */ | |
25946 | - | |
25947 | -#define WIN_MULTREAD 0xC4 /* read sectors using multiple mode */ | |
25948 | -#define WIN_MULTWRITE 0xC5 /* write sectors using multiple mode */ | |
25949 | -#define WIN_SETMULT 0xC6 /* enable/disable multiple mode */ | |
25950 | -#define WIN_IDENTIFY 0xEC /* ask drive to identify itself */ | |
25951 | -#define WIN_IDENTIFY_DMA 0xEE /* same as WIN_IDENTIFY, but DMA */ | |
25952 | -#define WIN_SETFEATURES 0xEF /* set special drive features */ | |
25953 | -#define WIN_READDMA 0xC8 /* read sectors using DMA transfers */ | |
25954 | -#define WIN_WRITEDMA 0xCA /* write sectors using DMA transfers */ | |
25955 | - | |
25956 | -#define WIN_QUEUED_SERVICE 0xA2 /* */ | |
25957 | -#define WIN_READDMA_QUEUED 0xC7 /* read sectors using Queued DMA transfers */ | |
25958 | -#define WIN_WRITEDMA_QUEUED 0xCC /* write sectors using Queued DMA transfers */ | |
25959 | - | |
25960 | -#define WIN_READ_BUFFER 0xE4 /* force read only 1 sector */ | |
25961 | -#define WIN_WRITE_BUFFER 0xE8 /* force write only 1 sector */ | |
25962 | - | |
25963 | -#define WIN_SMART 0xB0 /* self-monitoring and reporting */ | |
25964 | - | |
25965 | -/* Additional drive command codes used by ATAPI devices. */ | |
25966 | -#define WIN_PIDENTIFY 0xA1 /* identify ATAPI device */ | |
25967 | -#define WIN_SRST 0x08 /* ATAPI soft reset command */ | |
25968 | -#define WIN_PACKETCMD 0xA0 /* Send a packet command. */ | |
25969 | +#define ERR_STAT 0x01 | |
25970 | +#define INDEX_STAT 0x02 | |
25971 | +#define ECC_STAT 0x04 /* Corrected error */ | |
25972 | +#define DRQ_STAT 0x08 | |
25973 | +#define SEEK_STAT 0x10 | |
25974 | +#define WRERR_STAT 0x20 | |
25975 | +#define READY_STAT 0x40 | |
25976 | +#define BUSY_STAT 0x80 | |
25977 | ||
25978 | -#define DISABLE_SEAGATE 0xFB | |
25979 | -#define EXABYTE_ENABLE_NEST 0xF0 | |
25980 | +/* Bits for HD_ERROR */ | |
25981 | +#define MARK_ERR 0x01 /* Bad address mark */ | |
25982 | +#define TRK0_ERR 0x02 /* couldn't find track 0 */ | |
25983 | +#define ABRT_ERR 0x04 /* Command aborted */ | |
25984 | +#define MCR_ERR 0x08 /* media change request */ | |
25985 | +#define ID_ERR 0x10 /* ID field not found */ | |
25986 | +#define MC_ERR 0x20 /* media changed */ | |
25987 | +#define ECC_ERR 0x40 /* Uncorrectable ECC error */ | |
25988 | +#define BBD_ERR 0x80 /* pre-EIDE meaning: block marked bad */ | |
25989 | +#define ICRC_ERR 0x80 /* new meaning: CRC error during transfer */ | |
25990 | ||
25991 | -/* WIN_SMART sub-commands */ | |
25992 | +/* | |
25993 | + * Command Header sizes for IOCTL commands | |
25994 | + * HDIO_DRIVE_CMD, HDIO_DRIVE_TASK, and HDIO_DRIVE_TASKFILE | |
25995 | + */ | |
25996 | ||
25997 | -#define SMART_READ_VALUES 0xd0 | |
25998 | -#define SMART_READ_THRESHOLDS 0xd1 | |
25999 | -#define SMART_AUTOSAVE 0xd2 | |
26000 | -#define SMART_SAVE 0xd3 | |
26001 | -#define SMART_IMMEDIATE_OFFLINE 0xd4 | |
26002 | -#define SMART_READ_LOG_SECTOR 0xd5 | |
26003 | -#define SMART_WRITE_LOG_SECTOR 0xd6 | |
26004 | -#define SMART_WRITE_THRESHOLDS 0xd7 | |
26005 | -#define SMART_ENABLE 0xd8 | |
26006 | -#define SMART_DISABLE 0xd9 | |
26007 | -#define SMART_STATUS 0xda | |
26008 | -#define SMART_AUTO_OFFLINE 0xdb | |
26009 | +#if 0 | |
26010 | +#include <asm/hdreg.h> | |
26011 | +typedef ide_ioreg_t task_ioreg_t; | |
26012 | +#else | |
26013 | +typedef unsigned char task_ioreg_t; | |
26014 | +#endif | |
26015 | + | |
26016 | +#define HDIO_DRIVE_CMD_HDR_SIZE 4*sizeof(task_ioreg_t) | |
26017 | +#define HDIO_DRIVE_TASK_HDR_SIZE 8*sizeof(task_ioreg_t) | |
26018 | +#define HDIO_DRIVE_HOB_HDR_SIZE 8*sizeof(task_ioreg_t) | |
26019 | + | |
26020 | +#define IDE_DRIVE_TASK_INVALID -1 | |
26021 | +#define IDE_DRIVE_TASK_NO_DATA 0 | |
26022 | +#define IDE_DRIVE_TASK_SET_XFER 1 | |
26023 | + | |
26024 | +#define IDE_DRIVE_TASK_IN 2 | |
26025 | + | |
26026 | +#define IDE_DRIVE_TASK_OUT 3 | |
26027 | +#define IDE_DRIVE_TASK_RAW_WRITE 4 | |
26028 | + | |
26029 | +struct hd_drive_cmd_hdr { | |
26030 | + task_ioreg_t command; | |
26031 | + task_ioreg_t sector_number; | |
26032 | + task_ioreg_t feature; | |
26033 | + task_ioreg_t sector_count; | |
26034 | +}; | |
26035 | ||
26036 | -/* WIN_SETFEATURES sub-commands */ | |
26037 | +typedef struct hd_drive_task_hdr { | |
26038 | + task_ioreg_t data; | |
26039 | + task_ioreg_t feature; | |
26040 | + task_ioreg_t sector_count; | |
26041 | + task_ioreg_t sector_number; | |
26042 | + task_ioreg_t low_cylinder; | |
26043 | + task_ioreg_t high_cylinder; | |
26044 | + task_ioreg_t device_head; | |
26045 | + task_ioreg_t command; | |
26046 | +} task_struct_t; | |
26047 | + | |
26048 | +typedef struct hd_drive_hob_hdr { | |
26049 | + task_ioreg_t data; | |
26050 | + task_ioreg_t feature; | |
26051 | + task_ioreg_t sector_count; | |
26052 | + task_ioreg_t sector_number; | |
26053 | + task_ioreg_t low_cylinder; | |
26054 | + task_ioreg_t high_cylinder; | |
26055 | + task_ioreg_t device_head; | |
26056 | + task_ioreg_t control; | |
26057 | +} hob_struct_t; | |
26058 | + | |
26059 | +typedef union ide_reg_valid_s { | |
26060 | + unsigned all : 16; | |
26061 | + struct { | |
26062 | + unsigned data : 1; | |
26063 | + unsigned error_feature : 1; | |
26064 | + unsigned sector : 1; | |
26065 | + unsigned nsector : 1; | |
26066 | + unsigned lcyl : 1; | |
26067 | + unsigned hcyl : 1; | |
26068 | + unsigned select : 1; | |
26069 | + unsigned status_command : 1; | |
26070 | + | |
26071 | + unsigned data_hob : 1; | |
26072 | + unsigned error_feature_hob : 1; | |
26073 | + unsigned sector_hob : 1; | |
26074 | + unsigned nsector_hob : 1; | |
26075 | + unsigned lcyl_hob : 1; | |
26076 | + unsigned hcyl_hob : 1; | |
26077 | + unsigned select_hob : 1; | |
26078 | + unsigned control_hob : 1; | |
26079 | + } b; | |
26080 | +} ide_reg_valid_t; | |
26081 | + | |
26082 | +/* | |
26083 | + * Define standard taskfile in/out register | |
26084 | + */ | |
26085 | +#define IDE_TASKFILE_STD_OUT_FLAGS 0xFE | |
26086 | +#define IDE_TASKFILE_STD_IN_FLAGS 0xFE | |
26087 | +#define IDE_HOB_STD_OUT_FLAGS 0x3C /* sector, nsector lcyl and hcyl */ | |
26088 | +#define IDE_HOB_STD_IN_FLAGS 0x3C | |
26089 | + | |
26090 | +typedef struct ide_task_request_s { | |
26091 | + task_ioreg_t io_ports[8]; | |
26092 | + task_ioreg_t hob_ports[8]; | |
26093 | + ide_reg_valid_t out_flags; | |
26094 | + ide_reg_valid_t in_flags; | |
26095 | + int data_phase; | |
26096 | + int req_cmd; | |
26097 | + unsigned long out_size; | |
26098 | + unsigned long in_size; | |
26099 | +} ide_task_request_t; | |
26100 | + | |
26101 | +typedef struct ide_ioctl_request_s { | |
26102 | + ide_task_request_t *task_request; | |
26103 | + unsigned char *out_buffer; | |
26104 | + unsigned char *in_buffer; | |
26105 | +} ide_ioctl_request_t; | |
26106 | + | |
26107 | +#define TASKFILE_INVALID 0x7fff | |
26108 | +#define TASKFILE_48 0x8000 | |
26109 | + | |
26110 | +#define TASKFILE_NO_DATA 0x0000 | |
26111 | + | |
26112 | +#define TASKFILE_IN 0x0001 | |
26113 | +#define TASKFILE_MULTI_IN 0x0002 | |
26114 | + | |
26115 | +#define TASKFILE_OUT 0x0004 | |
26116 | +#define TASKFILE_MULTI_OUT 0x0008 | |
26117 | +#define TASKFILE_IN_OUT 0x0010 | |
26118 | + | |
26119 | +#define TASKFILE_IN_DMA 0x0020 | |
26120 | +#define TASKFILE_OUT_DMA 0x0040 | |
26121 | +#define TASKFILE_IN_DMAQ 0x0080 | |
26122 | +#define TASKFILE_OUT_DMAQ 0x0100 | |
26123 | + | |
26124 | +#define TASKFILE_P_IN 0x0200 | |
26125 | +#define TASKFILE_P_OUT 0x0400 | |
26126 | +#define TASKFILE_P_IN_DMA 0x0800 | |
26127 | +#define TASKFILE_P_OUT_DMA 0x1000 | |
26128 | +#define TASKFILE_P_IN_DMAQ 0x2000 | |
26129 | +#define TASKFILE_P_OUT_DMAQ 0x4000 | |
26130 | + | |
26131 | +/* ATA/ATAPI Commands pre T13 Spec */ | |
26132 | +#define WIN_NOP 0x00 | |
26133 | +/* | |
26134 | + * 0x01->0x02 Reserved | |
26135 | + */ | |
26136 | +#define CFA_REQ_EXT_ERROR_CODE 0x03 /* CFA Request Extended Error Code */ | |
26137 | +/* | |
26138 | + * 0x04->0x07 Reserved | |
26139 | + */ | |
26140 | +#define WIN_SRST 0x08 /* ATAPI soft reset command */ | |
26141 | +#define WIN_DEVICE_RESET 0x08 | |
26142 | +/* | |
26143 | + * 0x09->0x0F Reserved | |
26144 | + */ | |
26145 | +#define WIN_RECAL 0x10 | |
26146 | +/* | |
26147 | + * 0x10->0x1F Reserved | |
26148 | + */ | |
26149 | +#define WIN_RESTORE WIN_RECAL | |
26150 | +#define WIN_READ 0x20 /* 28-Bit */ | |
26151 | +#define WIN_READ_ONCE 0x21 /* 28-Bit without retries */ | |
26152 | +#define WIN_READ_LONG 0x22 /* 28-Bit */ | |
26153 | +#define WIN_READ_LONG_ONCE 0x23 /* 28-Bit without retries */ | |
26154 | +#define WIN_READ_EXT 0x24 /* 48-Bit */ | |
26155 | +#define WIN_READDMA_EXT 0x25 /* 48-Bit */ | |
26156 | +#define WIN_READDMA_QUEUED_EXT 0x26 /* 48-Bit */ | |
26157 | +#define WIN_READ_NATIVE_MAX_EXT 0x27 /* 48-Bit */ | |
26158 | +#define WIN_MULTREAD_EXT 0x29 /* 48-Bit */ | |
26159 | +/* | |
26160 | + * 0x2A->0x2F Reserved | |
26161 | + */ | |
26162 | +#define WIN_WRITE 0x30 /* 28-Bit */ | |
26163 | +#define WIN_WRITE_ONCE 0x31 /* 28-Bit without retries */ | |
26164 | +#define WIN_WRITE_LONG 0x32 /* 28-Bit */ | |
26165 | +#define WIN_WRITE_LONG_ONCE 0x33 /* 28-Bit without retries */ | |
26166 | +#define WIN_WRITE_EXT 0x34 /* 48-Bit */ | |
26167 | +#define WIN_WRITEDMA_EXT 0x35 /* 48-Bit */ | |
26168 | +#define WIN_WRITEDMA_QUEUED_EXT 0x36 /* 48-Bit */ | |
26169 | +#define WIN_SET_MAX_EXT 0x37 /* 48-Bit */ | |
26170 | +#define CFA_WRITE_SECT_WO_ERASE 0x38 /* CFA Write Sectors without erase */ | |
26171 | +#define WIN_MULTWRITE_EXT 0x39 /* 48-Bit */ | |
26172 | +/* | |
26173 | + * 0x3A->0x3B Reserved | |
26174 | + */ | |
26175 | +#define WIN_WRITE_VERIFY 0x3C /* 28-Bit */ | |
26176 | +/* | |
26177 | + * 0x3D->0x3F Reserved | |
26178 | + */ | |
26179 | +#define WIN_VERIFY 0x40 /* 28-Bit - Read Verify Sectors */ | |
26180 | +#define WIN_VERIFY_ONCE 0x41 /* 28-Bit - without retries */ | |
26181 | +#define WIN_VERIFY_EXT 0x42 /* 48-Bit */ | |
26182 | +/* | |
26183 | + * 0x43->0x4F Reserved | |
26184 | + */ | |
26185 | +#define WIN_FORMAT 0x50 | |
26186 | +/* | |
26187 | + * 0x51->0x5F Reserved | |
26188 | + */ | |
26189 | +#define WIN_INIT 0x60 | |
26190 | +/* | |
26191 | + * 0x61->0x5F Reserved | |
26192 | + */ | |
26193 | +#define WIN_SEEK 0x70 /* 0x70-0x7F Reserved */ | |
26194 | +#define CFA_TRANSLATE_SECTOR 0x87 /* CFA Translate Sector */ | |
26195 | +#define WIN_DIAGNOSE 0x90 | |
26196 | +#define WIN_SPECIFY 0x91 /* set drive geometry translation */ | |
26197 | +#define WIN_DOWNLOAD_MICROCODE 0x92 | |
26198 | +#define WIN_STANDBYNOW2 0x94 | |
26199 | +#define WIN_SETIDLE2 0x97 | |
26200 | +#define WIN_CHECKPOWERMODE2 0x98 | |
26201 | +#define WIN_SLEEPNOW2 0x99 | |
26202 | +/* | |
26203 | + * 0x9A VENDOR | |
26204 | + */ | |
26205 | +#define WIN_PACKETCMD 0xA0 /* Send a packet command. */ | |
26206 | +#define WIN_PIDENTIFY 0xA1 /* identify ATAPI device */ | |
26207 | +#define WIN_QUEUED_SERVICE 0xA2 | |
26208 | +#define WIN_SMART 0xB0 /* self-monitoring and reporting */ | |
26209 | +#define CFA_ERASE_SECTORS 0xC0 | |
26210 | +#define WIN_MULTREAD 0xC4 /* read sectors using multiple mode*/ | |
26211 | +#define WIN_MULTWRITE 0xC5 /* write sectors using multiple mode */ | |
26212 | +#define WIN_SETMULT 0xC6 /* enable/disable multiple mode */ | |
26213 | +#define WIN_READDMA_QUEUED 0xC7 /* read sectors using Queued DMA transfers */ | |
26214 | +#define WIN_READDMA 0xC8 /* read sectors using DMA transfers */ | |
26215 | +#define WIN_READDMA_ONCE 0xC9 /* 28-Bit - without retries */ | |
26216 | +#define WIN_WRITEDMA 0xCA /* write sectors using DMA transfers */ | |
26217 | +#define WIN_WRITEDMA_ONCE 0xCB /* 28-Bit - without retries */ | |
26218 | +#define WIN_WRITEDMA_QUEUED 0xCC /* write sectors using Queued DMA transfers */ | |
26219 | +#define CFA_WRITE_MULTI_WO_ERASE 0xCD /* CFA Write multiple without erase */ | |
26220 | +#define WIN_GETMEDIASTATUS 0xDA | |
26221 | +#define WIN_DOORLOCK 0xDE /* lock door on removable drives */ | |
26222 | +#define WIN_DOORUNLOCK 0xDF /* unlock door on removable drives */ | |
26223 | +#define WIN_STANDBYNOW1 0xE0 | |
26224 | +#define WIN_IDLEIMMEDIATE 0xE1 /* force drive to become "ready" */ | |
26225 | +#define WIN_STANDBY 0xE2 /* Set device in Standby Mode */ | |
26226 | +#define WIN_SETIDLE1 0xE3 | |
26227 | +#define WIN_READ_BUFFER 0xE4 /* force read only 1 sector */ | |
26228 | +#define WIN_CHECKPOWERMODE1 0xE5 | |
26229 | +#define WIN_SLEEPNOW1 0xE6 | |
26230 | +#define WIN_FLUSH_CACHE 0xE7 | |
26231 | +#define WIN_WRITE_BUFFER 0xE8 /* force write only 1 sector */ | |
26232 | +#define WIN_WRITE_SAME 0xE9 /* read ata-2 to use */ | |
26233 | +#define WIN_FLUSH_CACHE_EXT 0xEA /* 48-Bit */ | |
26234 | +#define WIN_IDENTIFY 0xEC /* ask drive to identify itself */ | |
26235 | +#define WIN_MEDIAEJECT 0xED | |
26236 | +#define WIN_IDENTIFY_DMA 0xEE /* same as WIN_IDENTIFY, but DMA */ | |
26237 | +#define WIN_SETFEATURES 0xEF /* set special drive features */ | |
26238 | +#define EXABYTE_ENABLE_NEST 0xF0 | |
26239 | +#define WIN_SECURITY_SET_PASS 0xF1 | |
26240 | +#define WIN_SECURITY_UNLOCK 0xF2 | |
26241 | +#define WIN_SECURITY_ERASE_PREPARE 0xF3 | |
26242 | +#define WIN_SECURITY_ERASE_UNIT 0xF4 | |
26243 | +#define WIN_SECURITY_FREEZE_LOCK 0xF5 | |
26244 | +#define WIN_SECURITY_DISABLE 0xF6 | |
26245 | +#define WIN_READ_NATIVE_MAX 0xF8 /* return the native maximum address */ | |
26246 | +#define WIN_SET_MAX 0xF9 | |
26247 | +#define DISABLE_SEAGATE 0xFB | |
26248 | ||
26249 | +/* WIN_SMART sub-commands */ | |
26250 | + | |
26251 | +#define SMART_READ_VALUES 0xD0 | |
26252 | +#define SMART_READ_THRESHOLDS 0xD1 | |
26253 | +#define SMART_AUTOSAVE 0xD2 | |
26254 | +#define SMART_SAVE 0xD3 | |
26255 | +#define SMART_IMMEDIATE_OFFLINE 0xD4 | |
26256 | +#define SMART_READ_LOG_SECTOR 0xD5 | |
26257 | +#define SMART_WRITE_LOG_SECTOR 0xD6 | |
26258 | +#define SMART_WRITE_THRESHOLDS 0xD7 | |
26259 | +#define SMART_ENABLE 0xD8 | |
26260 | +#define SMART_DISABLE 0xD9 | |
26261 | +#define SMART_STATUS 0xDA | |
26262 | +#define SMART_AUTO_OFFLINE 0xDB | |
26263 | + | |
26264 | +/* Password used in TF4 & TF5 executing SMART commands */ | |
26265 | + | |
26266 | +#define SMART_LCYL_PASS 0x4F | |
26267 | +#define SMART_HCYL_PASS 0xC2 | |
26268 | + | |
26269 | +/* WIN_SETFEATURES sub-commands */ | |
26270 | +#define SETFEATURES_EN_8BIT 0x01 /* Enable 8-Bit Transfers */ | |
26271 | #define SETFEATURES_EN_WCACHE 0x02 /* Enable write cache */ | |
26272 | #define SETFEATURES_XFER 0x03 /* Set transfer mode */ | |
26273 | # define XFER_UDMA_7 0x47 /* 0100|0111 */ | |
26274 | @@ -131,39 +340,38 @@ | |
26275 | #define SETFEATURES_DIS_DEFECT 0x04 /* Disable Defect Management */ | |
26276 | #define SETFEATURES_EN_APM 0x05 /* Enable advanced power management */ | |
26277 | #define SETFEATURES_DIS_MSN 0x31 /* Disable Media Status Notification */ | |
26278 | +#define SETFEATURES_DIS_RETRY 0x33 /* Disable Retry */ | |
26279 | +#define SETFEATURES_EN_AAM 0x42 /* Enable Automatic Acoustic Management */ | |
26280 | +#define SETFEATURES_RW_LONG 0x44 /* Set Lenght of VS bytes */ | |
26281 | +#define SETFEATURES_SET_CACHE 0x54 /* Set Cache segments to SC Reg. Val */ | |
26282 | #define SETFEATURES_DIS_RLA 0x55 /* Disable read look-ahead feature */ | |
26283 | #define SETFEATURES_EN_RI 0x5D /* Enable release interrupt */ | |
26284 | #define SETFEATURES_EN_SI 0x5E /* Enable SERVICE interrupt */ | |
26285 | #define SETFEATURES_DIS_RPOD 0x66 /* Disable reverting to power on defaults */ | |
26286 | +#define SETFEATURES_DIS_ECC 0x77 /* Disable ECC byte count */ | |
26287 | +#define SETFEATURES_DIS_8BIT 0x81 /* Disable 8-Bit Transfers */ | |
26288 | #define SETFEATURES_DIS_WCACHE 0x82 /* Disable write cache */ | |
26289 | #define SETFEATURES_EN_DEFECT 0x84 /* Enable Defect Management */ | |
26290 | #define SETFEATURES_DIS_APM 0x85 /* Disable advanced power management */ | |
26291 | +#define SETFEATURES_EN_ECC 0x88 /* Enable ECC byte count */ | |
26292 | #define SETFEATURES_EN_MSN 0x95 /* Enable Media Status Notification */ | |
26293 | +#define SETFEATURES_EN_RETRY 0x99 /* Enable Retry */ | |
26294 | #define SETFEATURES_EN_RLA 0xAA /* Enable read look-ahead feature */ | |
26295 | #define SETFEATURES_PREFETCH 0xAB /* Sets drive prefetch value */ | |
26296 | +#define SETFEATURES_4B_RW_LONG 0xBB /* Set Lenght of 4 bytes */ | |
26297 | +#define SETFEATURES_DIS_AAM 0xC2 /* Disable Automatic Acoustic Management */ | |
26298 | #define SETFEATURES_EN_RPOD 0xCC /* Enable reverting to power on defaults */ | |
26299 | #define SETFEATURES_DIS_RI 0xDD /* Disable release interrupt */ | |
26300 | #define SETFEATURES_DIS_SI 0xDE /* Disable SERVICE interrupt */ | |
26301 | ||
26302 | /* WIN_SECURITY sub-commands */ | |
26303 | ||
26304 | -#define SECURITY_SET_PASSWORD 0xBA /* 0xF1 */ | |
26305 | -#define SECURITY_UNLOCK 0xBB /* 0xF2 */ | |
26306 | -#define SECURITY_ERASE_PREPARE 0xBC /* 0xF3 */ | |
26307 | -#define SECURITY_ERASE_UNIT 0xBD /* 0xF4 */ | |
26308 | -#define SECURITY_FREEZE_LOCK 0xBE /* 0xF5 */ | |
26309 | -#define SECURITY_DISABLE_PASSWORD 0xBF /* 0xF6 */ | |
26310 | - | |
26311 | -/* Bits for HD_ERROR */ | |
26312 | -#define MARK_ERR 0x01 /* Bad address mark */ | |
26313 | -#define TRK0_ERR 0x02 /* couldn't find track 0 */ | |
26314 | -#define ABRT_ERR 0x04 /* Command aborted */ | |
26315 | -#define MCR_ERR 0x08 /* media change request */ | |
26316 | -#define ID_ERR 0x10 /* ID field not found */ | |
26317 | -#define MC_ERR 0x20 /* media changed */ | |
26318 | -#define ECC_ERR 0x40 /* Uncorrectable ECC error */ | |
26319 | -#define BBD_ERR 0x80 /* pre-EIDE meaning: block marked bad */ | |
26320 | -#define ICRC_ERR 0x80 /* new meaning: CRC error during transfer */ | |
26321 | +#define SECURITY_SET_PASSWORD 0xBA | |
26322 | +#define SECURITY_UNLOCK 0xBB | |
26323 | +#define SECURITY_ERASE_PREPARE 0xBC | |
26324 | +#define SECURITY_ERASE_UNIT 0xBD | |
26325 | +#define SECURITY_FREEZE_LOCK 0xBE | |
26326 | +#define SECURITY_DISABLE_PASSWORD 0xBF | |
26327 | ||
26328 | struct hd_geometry { | |
26329 | unsigned char heads; | |
26330 | @@ -172,6 +380,14 @@ | |
26331 | unsigned long start; | |
26332 | }; | |
26333 | ||
26334 | +/* BIG GEOMETRY */ | |
26335 | +struct hd_big_geometry { | |
26336 | + unsigned char heads; | |
26337 | + unsigned char sectors; | |
26338 | + unsigned int cylinders; | |
26339 | + unsigned long start; | |
26340 | +}; | |
26341 | + | |
26342 | /* hd/ide ctl's that pass (arg) ptrs to user space are numbered 0x030n/0x031n */ | |
26343 | #define HDIO_GETGEO 0x0301 /* get device geometry */ | |
26344 | #define HDIO_GET_UNMASKINTR 0x0302 /* get current unmask setting */ | |
26345 | @@ -186,9 +402,10 @@ | |
26346 | #define HDIO_GET_IDENTITY 0x030d /* get IDE identification info */ | |
26347 | #define HDIO_GET_WCACHE 0x030e /* get write cache mode on|off */ | |
26348 | #define HDIO_GET_ACOUSTIC 0x030f /* get acoustic value */ | |
26349 | +#define HDIO_GET_ADDRESS 0x0310 /* */ | |
26350 | ||
26351 | #define HDIO_GET_BUSSTATE 0x031a /* get the bus state of the hwif */ | |
26352 | -#define HDIO_TRISTATE_HWIF 0x031b /* OBSOLETE - use SET_BUSSTATE */ | |
26353 | +#define HDIO_TRISTATE_HWIF 0x031b /* execute a channel tristate */ | |
26354 | #define HDIO_DRIVE_RESET 0x031c /* execute a device reset */ | |
26355 | #define HDIO_DRIVE_TASKFILE 0x031d /* execute raw taskfile */ | |
26356 | #define HDIO_DRIVE_TASK 0x031e /* execute task and special drive command */ | |
26357 | @@ -211,6 +428,7 @@ | |
26358 | #define HDIO_SET_ACOUSTIC 0x032c /* change acoustic behavior */ | |
26359 | #define HDIO_SET_BUSSTATE 0x032d /* set the bus state of the hwif */ | |
26360 | #define HDIO_SET_QDMA 0x032e /* change use-qdma flag */ | |
26361 | +#define HDIO_SET_ADDRESS 0x032f /* change lba addressing modes */ | |
26362 | ||
26363 | /* bus states */ | |
26364 | enum { | |
26365 | @@ -219,34 +437,30 @@ | |
26366 | BUSSTATE_TRISTATE | |
26367 | }; | |
26368 | ||
26369 | -/* BIG GEOMETRY */ | |
26370 | -struct hd_big_geometry { | |
26371 | - unsigned char heads; | |
26372 | - unsigned char sectors; | |
26373 | - unsigned int cylinders; | |
26374 | - unsigned long start; | |
26375 | -}; | |
26376 | - | |
26377 | /* hd/ide ctl's that pass (arg) ptrs to user space are numbered 0x033n/0x033n */ | |
26378 | #define HDIO_GETGEO_BIG 0x0330 /* */ | |
26379 | #define HDIO_GETGEO_BIG_RAW 0x0331 /* */ | |
26380 | ||
26381 | #define __NEW_HD_DRIVE_ID | |
26382 | -/* structure returned by HDIO_GET_IDENTITY, as per ANSI ATA2 rev.2f spec */ | |
26383 | +/* structure returned by HDIO_GET_IDENTITY, | |
26384 | + * as per ANSI NCITS ATA6 rev.1b spec | |
26385 | + */ | |
26386 | struct hd_driveid { | |
26387 | unsigned short config; /* lots of obsolete bit flags */ | |
26388 | - unsigned short cyls; /* "physical" cyls */ | |
26389 | + unsigned short cyls; /* Obsolete, "physical" cyls */ | |
26390 | unsigned short reserved2; /* reserved (word 2) */ | |
26391 | - unsigned short heads; /* "physical" heads */ | |
26392 | + unsigned short heads; /* Obsolete, "physical" heads */ | |
26393 | unsigned short track_bytes; /* unformatted bytes per track */ | |
26394 | unsigned short sector_bytes; /* unformatted bytes per sector */ | |
26395 | - unsigned short sectors; /* "physical" sectors per track */ | |
26396 | + unsigned short sectors; /* Obsolete, "physical" sectors per track */ | |
26397 | unsigned short vendor0; /* vendor unique */ | |
26398 | unsigned short vendor1; /* vendor unique */ | |
26399 | - unsigned short vendor2; /* vendor unique */ | |
26400 | + unsigned short vendor2; /* Retired vendor unique */ | |
26401 | unsigned char serial_no[20]; /* 0 = not_specified */ | |
26402 | - unsigned short buf_type; | |
26403 | - unsigned short buf_size; /* 512 byte increments; 0 = not_specified */ | |
26404 | + unsigned short buf_type; /* Retired */ | |
26405 | + unsigned short buf_size; /* Retired, 512 byte increments | |
26406 | + * 0 = not_specified | |
26407 | + */ | |
26408 | unsigned short ecc_bytes; /* for r/w long cmds; 0 = not_specified */ | |
26409 | unsigned char fw_rev[8]; /* 0 = not_specified */ | |
26410 | unsigned char model[40]; /* 0 = not_specified */ | |
26411 | @@ -254,72 +468,228 @@ | |
26412 | unsigned char vendor3; /* vendor unique */ | |
26413 | unsigned short dword_io; /* 0=not_implemented; 1=implemented */ | |
26414 | unsigned char vendor4; /* vendor unique */ | |
26415 | - unsigned char capability; /* bits 0:DMA 1:LBA 2:IORDYsw 3:IORDYsup*/ | |
26416 | + unsigned char capability; /* (upper byte of word 49) | |
26417 | + * 3: IORDYsup | |
26418 | + * 2: IORDYsw | |
26419 | + * 1: LBA | |
26420 | + * 0: DMA | |
26421 | + */ | |
26422 | unsigned short reserved50; /* reserved (word 50) */ | |
26423 | - unsigned char vendor5; /* vendor unique */ | |
26424 | - unsigned char tPIO; /* 0=slow, 1=medium, 2=fast */ | |
26425 | - unsigned char vendor6; /* vendor unique */ | |
26426 | - unsigned char tDMA; /* 0=slow, 1=medium, 2=fast */ | |
26427 | - unsigned short field_valid; /* bits 0:cur_ok 1:eide_ok */ | |
26428 | - unsigned short cur_cyls; /* logical cylinders */ | |
26429 | - unsigned short cur_heads; /* logical heads */ | |
26430 | - unsigned short cur_sectors; /* logical sectors per track */ | |
26431 | - unsigned short cur_capacity0; /* logical total sectors on drive */ | |
26432 | - unsigned short cur_capacity1; /* (2 words, misaligned int) */ | |
26433 | + unsigned char vendor5; /* Obsolete, vendor unique */ | |
26434 | + unsigned char tPIO; /* Obsolete, 0=slow, 1=medium, 2=fast */ | |
26435 | + unsigned char vendor6; /* Obsolete, vendor unique */ | |
26436 | + unsigned char tDMA; /* Obsolete, 0=slow, 1=medium, 2=fast */ | |
26437 | + unsigned short field_valid; /* (word 53) | |
26438 | + * 2: ultra_ok word 88 | |
26439 | + * 1: eide_ok words 64-70 | |
26440 | + * 0: cur_ok words 54-58 | |
26441 | + */ | |
26442 | + unsigned short cur_cyls; /* Obsolete, logical cylinders */ | |
26443 | + unsigned short cur_heads; /* Obsolete, l heads */ | |
26444 | + unsigned short cur_sectors; /* Obsolete, l sectors per track */ | |
26445 | + unsigned short cur_capacity0; /* Obsolete, l total sectors on drive */ | |
26446 | + unsigned short cur_capacity1; /* Obsolete, (2 words, misaligned int) */ | |
26447 | unsigned char multsect; /* current multiple sector count */ | |
26448 | unsigned char multsect_valid; /* when (bit0==1) multsect is ok */ | |
26449 | - unsigned int lba_capacity; /* total number of sectors */ | |
26450 | - unsigned short dma_1word; /* single-word dma info */ | |
26451 | + unsigned int lba_capacity; /* Obsolete, total number of sectors */ | |
26452 | + unsigned short dma_1word; /* Obsolete, single-word dma info */ | |
26453 | unsigned short dma_mword; /* multiple-word dma info */ | |
26454 | unsigned short eide_pio_modes; /* bits 0:mode3 1:mode4 */ | |
26455 | unsigned short eide_dma_min; /* min mword dma cycle time (ns) */ | |
26456 | unsigned short eide_dma_time; /* recommended mword dma cycle time (ns) */ | |
26457 | unsigned short eide_pio; /* min cycle time (ns), no IORDY */ | |
26458 | unsigned short eide_pio_iordy; /* min cycle time (ns), with IORDY */ | |
26459 | - unsigned short words69_70[2]; /* reserved words 69-70 */ | |
26460 | + unsigned short words69_70[2]; /* reserved words 69-70 | |
26461 | + * future command overlap and queuing | |
26462 | + */ | |
26463 | /* HDIO_GET_IDENTITY currently returns only words 0 through 70 */ | |
26464 | - unsigned short words71_74[4]; /* reserved words 71-74 */ | |
26465 | - unsigned short queue_depth; /* */ | |
26466 | + unsigned short words71_74[4]; /* reserved words 71-74 | |
26467 | + * for IDENTIFY PACKET DEVICE command | |
26468 | + */ | |
26469 | + unsigned short queue_depth; /* (word 75) | |
26470 | + * 15:5 reserved | |
26471 | + * 4:0 Maximum queue depth -1 | |
26472 | + */ | |
26473 | unsigned short words76_79[4]; /* reserved words 76-79 */ | |
26474 | - unsigned short major_rev_num; /* */ | |
26475 | - unsigned short minor_rev_num; /* */ | |
26476 | - unsigned short command_set_1; /* bits 0:Smart 1:Security 2:Removable 3:PM */ | |
26477 | - unsigned short command_set_2; /* bits 14:Smart Enabled 13:0 zero */ | |
26478 | - unsigned short cfsse; /* command set-feature supported extensions */ | |
26479 | - unsigned short cfs_enable_1; /* command set-feature enabled */ | |
26480 | - unsigned short cfs_enable_2; /* command set-feature enabled */ | |
26481 | - unsigned short csf_default; /* command set-feature default */ | |
26482 | - unsigned short dma_ultra; /* */ | |
26483 | - unsigned short word89; /* reserved (word 89) */ | |
26484 | - unsigned short word90; /* reserved (word 90) */ | |
26485 | + unsigned short major_rev_num; /* (word 80) */ | |
26486 | + unsigned short minor_rev_num; /* (word 81) */ | |
26487 | + unsigned short command_set_1; /* (word 82) supported | |
26488 | + * 15: Obsolete | |
26489 | + * 14: NOP command | |
26490 | + * 13: READ_BUFFER | |
26491 | + * 12: WRITE_BUFFER | |
26492 | + * 11: Obsolete | |
26493 | + * 10: Host Protected Area | |
26494 | + * 9: DEVICE Reset | |
26495 | + * 8: SERVICE Interrupt | |
26496 | + * 7: Release Interrupt | |
26497 | + * 6: look-ahead | |
26498 | + * 5: write cache | |
26499 | + * 4: PACKET Command | |
26500 | + * 3: Power Management Feature Set | |
26501 | + * 2: Removable Feature Set | |
26502 | + * 1: Security Feature Set | |
26503 | + * 0: SMART Feature Set | |
26504 | + */ | |
26505 | + unsigned short command_set_2; /* (word 83) | |
26506 | + * 15: Shall be ZERO | |
26507 | + * 14: Shall be ONE | |
26508 | + * 13: FLUSH CACHE EXT | |
26509 | + * 12: FLUSH CACHE | |
26510 | + * 11: Device Configuration Overlay | |
26511 | + * 10: 48-bit Address Feature Set | |
26512 | + * 9: Automatic Acoustic Management | |
26513 | + * 8: SET MAX security | |
26514 | + * 7: reserved 1407DT PARTIES | |
26515 | + * 6: SetF sub-command Power-Up | |
26516 | + * 5: Power-Up in Standby Feature Set | |
26517 | + * 4: Removable Media Notification | |
26518 | + * 3: APM Feature Set | |
26519 | + * 2: CFA Feature Set | |
26520 | + * 1: READ/WRITE DMA QUEUED | |
26521 | + * 0: Download MicroCode | |
26522 | + */ | |
26523 | + unsigned short cfsse; /* (word 84) | |
26524 | + * cmd set-feature supported extensions | |
26525 | + * 15: Shall be ZERO | |
26526 | + * 14: Shall be ONE | |
26527 | + * 13:6 reserved | |
26528 | + * 5: General Purpose Logging | |
26529 | + * 4: Streaming Feature Set | |
26530 | + * 3: Media Card Pass Through | |
26531 | + * 2: Media Serial Number Valid | |
26532 | + * 1: SMART selt-test supported | |
26533 | + * 0: SMART error logging | |
26534 | + */ | |
26535 | + unsigned short cfs_enable_1; /* (word 85) | |
26536 | + * command set-feature enabled | |
26537 | + * 15: Obsolete | |
26538 | + * 14: NOP command | |
26539 | + * 13: READ_BUFFER | |
26540 | + * 12: WRITE_BUFFER | |
26541 | + * 11: Obsolete | |
26542 | + * 10: Host Protected Area | |
26543 | + * 9: DEVICE Reset | |
26544 | + * 8: SERVICE Interrupt | |
26545 | + * 7: Release Interrupt | |
26546 | + * 6: look-ahead | |
26547 | + * 5: write cache | |
26548 | + * 4: PACKET Command | |
26549 | + * 3: Power Management Feature Set | |
26550 | + * 2: Removable Feature Set | |
26551 | + * 1: Security Feature Set | |
26552 | + * 0: SMART Feature Set | |
26553 | + */ | |
26554 | + unsigned short cfs_enable_2; /* (word 86) | |
26555 | + * command set-feature enabled | |
26556 | + * 15: Shall be ZERO | |
26557 | + * 14: Shall be ONE | |
26558 | + * 13: FLUSH CACHE EXT | |
26559 | + * 12: FLUSH CACHE | |
26560 | + * 11: Device Configuration Overlay | |
26561 | + * 10: 48-bit Address Feature Set | |
26562 | + * 9: Automatic Acoustic Management | |
26563 | + * 8: SET MAX security | |
26564 | + * 7: reserved 1407DT PARTIES | |
26565 | + * 6: SetF sub-command Power-Up | |
26566 | + * 5: Power-Up in Standby Feature Set | |
26567 | + * 4: Removable Media Notification | |
26568 | + * 3: APM Feature Set | |
26569 | + * 2: CFA Feature Set | |
26570 | + * 1: READ/WRITE DMA QUEUED | |
26571 | + * 0: Download MicroCode | |
26572 | + */ | |
26573 | + unsigned short csf_default; /* (word 87) | |
26574 | + * command set-feature default | |
26575 | + * 15: Shall be ZERO | |
26576 | + * 14: Shall be ONE | |
26577 | + * 13:6 reserved | |
26578 | + * 5: General Purpose Logging enabled | |
26579 | + * 4: Valid CONFIGURE STREAM executed | |
26580 | + * 3: Media Card Pass Through enabled | |
26581 | + * 2: Media Serial Number Valid | |
26582 | + * 1: SMART selt-test supported | |
26583 | + * 0: SMART error logging | |
26584 | + */ | |
26585 | + unsigned short dma_ultra; /* (word 88) */ | |
26586 | + unsigned short trseuc; /* time required for security erase */ | |
26587 | + unsigned short trsEuc; /* time required for enhanced erase */ | |
26588 | unsigned short CurAPMvalues; /* current APM values */ | |
26589 | - unsigned short word92; /* reserved (word 92) */ | |
26590 | - unsigned short hw_config; /* hardware config */ | |
26591 | - unsigned short words94_125[32];/* reserved words 94-125 */ | |
26592 | - unsigned short last_lun; /* reserved (word 126) */ | |
26593 | - unsigned short word127; /* reserved (word 127) */ | |
26594 | - unsigned short dlf; /* device lock function | |
26595 | + unsigned short mprc; /* master password revision code */ | |
26596 | + unsigned short hw_config; /* hardware config (word 93) | |
26597 | + * 15: Shall be ZERO | |
26598 | + * 14: Shall be ONE | |
26599 | + * 13: | |
26600 | + * 12: | |
26601 | + * 11: | |
26602 | + * 10: | |
26603 | + * 9: | |
26604 | + * 8: | |
26605 | + * 7: | |
26606 | + * 6: | |
26607 | + * 5: | |
26608 | + * 4: | |
26609 | + * 3: | |
26610 | + * 2: | |
26611 | + * 1: | |
26612 | + * 0: Shall be ONE | |
26613 | + */ | |
26614 | + unsigned short acoustic; /* (word 94) | |
26615 | + * 15:8 Vendor's recommended value | |
26616 | + * 7:0 current value | |
26617 | + */ | |
26618 | + unsigned short msrqs; /* min stream request size */ | |
26619 | + unsigned short sxfert; /* stream transfer time */ | |
26620 | + unsigned short sal; /* stream access latency */ | |
26621 | + unsigned int spg; /* stream performance granularity */ | |
26622 | + unsigned long long lba_capacity_2;/* 48-bit total number of sectors */ | |
26623 | + unsigned short words104_125[22];/* reserved words 104-125 */ | |
26624 | + unsigned short last_lun; /* (word 126) */ | |
26625 | + unsigned short word127; /* (word 127) Feature Set | |
26626 | + * Removable Media Notification | |
26627 | + * 15:2 reserved | |
26628 | + * 1:0 00 = not supported | |
26629 | + * 01 = supported | |
26630 | + * 10 = reserved | |
26631 | + * 11 = reserved | |
26632 | + */ | |
26633 | + unsigned short dlf; /* (word 128) | |
26634 | + * device lock function | |
26635 | * 15:9 reserved | |
26636 | - * 8 security level 1:max 0:high | |
26637 | - * 7:6 reserved | |
26638 | - * 5 enhanced erase | |
26639 | - * 4 expire | |
26640 | - * 3 frozen | |
26641 | - * 2 locked | |
26642 | - * 1 en/disabled | |
26643 | - * 0 capability | |
26644 | + * 8 security level 1:max 0:high | |
26645 | + * 7:6 reserved | |
26646 | + * 5 enhanced erase | |
26647 | + * 4 expire | |
26648 | + * 3 frozen | |
26649 | + * 2 locked | |
26650 | + * 1 en/disabled | |
26651 | + * 0 capability | |
26652 | */ | |
26653 | - unsigned short csfo; /* current set features options | |
26654 | + unsigned short csfo; /* (word 129) | |
26655 | + * current set features options | |
26656 | * 15:4 reserved | |
26657 | - * 3 auto reassign | |
26658 | - * 2 reverting | |
26659 | - * 1 read-look-ahead | |
26660 | - * 0 write cache | |
26661 | + * 3: auto reassign | |
26662 | + * 2: reverting | |
26663 | + * 1: read-look-ahead | |
26664 | + * 0: write cache | |
26665 | */ | |
26666 | unsigned short words130_155[26];/* reserved vendor words 130-155 */ | |
26667 | - unsigned short word156; | |
26668 | + unsigned short word156; /* reserved vendor word 156 */ | |
26669 | unsigned short words157_159[3];/* reserved vendor words 157-159 */ | |
26670 | - unsigned short words160_255[95];/* reserved words 160-255 */ | |
26671 | + unsigned short cfa_power; /* (word 160) CFA Power Mode | |
26672 | + * 15 word 160 supported | |
26673 | + * 14 reserved | |
26674 | + * 13 | |
26675 | + * 12 | |
26676 | + * 11:0 | |
26677 | + */ | |
26678 | + unsigned short words161_175[14];/* Reserved for CFA */ | |
26679 | + unsigned short words176_205[31];/* Current Media Serial Number */ | |
26680 | + unsigned short words206_254[48];/* reserved words 206-254 */ | |
26681 | + unsigned short integrity_word; /* (word 255) | |
26682 | + * 15:8 Checksum | |
26683 | + * 7:0 Signature | |
26684 | + */ | |
26685 | }; | |
26686 | ||
26687 | /* | |
26688 | --- linux.org/include/asm-i386/ide.h Thu Nov 22 20:46:58 2001 | |
26689 | +++ linux-2.4.19-rc1-ac7/include/asm-i386/ide.h Thu Jul 18 14:24:43 2002 | |
26690 | @@ -23,8 +23,6 @@ | |
26691 | # endif | |
26692 | #endif | |
26693 | ||
26694 | -#define ide__sti() __sti() | |
26695 | - | |
26696 | static __inline__ int ide_default_irq(ide_ioreg_t base) | |
26697 | { | |
26698 | switch (base) { | |
26699 | @@ -86,17 +84,6 @@ | |
26700 | #endif /* CONFIG_BLK_DEV_IDEPCI */ | |
26701 | } | |
26702 | ||
26703 | -typedef union { | |
26704 | - unsigned all : 8; /* all of the bits together */ | |
26705 | - struct { | |
26706 | - unsigned head : 4; /* always zeros here */ | |
26707 | - unsigned unit : 1; /* drive select number, 0 or 1 */ | |
26708 | - unsigned bit5 : 1; /* always 1 */ | |
26709 | - unsigned lba : 1; /* using LBA instead of CHS */ | |
26710 | - unsigned bit7 : 1; /* always 1 */ | |
26711 | - } b; | |
26712 | - } select_t; | |
26713 | - | |
26714 | #define ide_request_irq(irq,hand,flg,dev,id) request_irq((irq),(hand),(flg),(dev),(id)) | |
26715 | #define ide_free_irq(irq,dev_id) free_irq((irq), (dev_id)) | |
26716 | #define ide_check_region(from,extent) check_region((from), (extent)) | |
26717 | --- linux.org/include/linux/blkdev.h Mon Nov 26 14:29:17 2001 | |
26718 | +++ linux-2.4.19-rc1-ac7/include/linux/blkdev.h Thu Jul 18 14:24:44 2002 | |
26719 | @@ -6,6 +6,7 @@ | |
26720 | #include <linux/genhd.h> | |
26721 | #include <linux/tqueue.h> | |
26722 | #include <linux/list.h> | |
26723 | +/* #include <linux/blkcdb.h> */ | |
26724 | ||
26725 | struct request_queue; | |
26726 | typedef struct request_queue request_queue_t; | |
26727 | @@ -30,13 +31,16 @@ | |
26728 | kdev_t rq_dev; | |
26729 | int cmd; /* READ or WRITE */ | |
26730 | int errors; | |
26731 | + unsigned long start_time; | |
26732 | unsigned long sector; | |
26733 | unsigned long nr_sectors; | |
26734 | unsigned long hard_sector, hard_nr_sectors; | |
26735 | unsigned int nr_segments; | |
26736 | unsigned int nr_hw_segments; | |
26737 | unsigned long current_nr_sectors; | |
26738 | + unsigned long hard_cur_sectors; | |
26739 | void * special; | |
26740 | +/* void * cdb; */ | |
26741 | char * buffer; | |
26742 | struct completion * waiting; | |
26743 | struct buffer_head * bh; | |
58834b10 | 26744 | @@ -119,7 +123,7 @@ |
964949d0 | 26745 | spinlock_t queue_lock; |
26746 | ||
26747 | /* | |
26748 | - * Tasks wait here for free request | |
26749 | + * Tasks wait here for free read and write requests | |
26750 | */ | |
58834b10 | 26751 | wait_queue_head_t wait_for_request; |
964949d0 | 26752 | }; |
964949d0 | 26753 | @@ -175,6 +179,8 @@ |
26754 | ||
26755 | extern int * max_segments[MAX_BLKDEV]; | |
26756 | ||
26757 | +extern char * blkdev_varyio[MAX_BLKDEV]; | |
26758 | + | |
26759 | #define MAX_SEGMENTS 128 | |
26760 | #define MAX_SECTORS 255 | |
26761 | ||
26762 | @@ -228,4 +234,12 @@ | |
26763 | return retval; | |
26764 | } | |
26765 | ||
26766 | +static inline int get_blkdev_varyio(int major, int minor) | |
26767 | +{ | |
26768 | + int retval = 0; | |
26769 | + if (blkdev_varyio[major]) { | |
26770 | + retval = blkdev_varyio[major][minor]; | |
26771 | + } | |
26772 | + return retval; | |
26773 | +} | |
26774 | #endif | |
26775 | --- linux.org/include/linux/pci_ids.h Mon Feb 25 20:38:13 2002 | |
26776 | +++ linux-2.4.19-rc1-ac7/include/linux/pci_ids.h Thu Jul 18 14:24:44 2002 | |
26777 | @@ -133,6 +133,7 @@ | |
26778 | #define PCI_DEVICE_ID_COMPAQ_1280 0x3033 | |
26779 | #define PCI_DEVICE_ID_COMPAQ_TRIFLEX 0x4000 | |
26780 | #define PCI_DEVICE_ID_COMPAQ_6010 0x6010 | |
26781 | +#define PCI_DEVICE_ID_COMPAQ_TACHYON 0xa0fc | |
26782 | #define PCI_DEVICE_ID_COMPAQ_SMART2P 0xae10 | |
26783 | #define PCI_DEVICE_ID_COMPAQ_NETEL100 0xae32 | |
26784 | #define PCI_DEVICE_ID_COMPAQ_NETEL10 0xae34 | |
26785 | @@ -346,6 +347,8 @@ | |
26786 | #define PCI_DEVICE_ID_IBM_MPIC 0x0046 | |
26787 | #define PCI_DEVICE_ID_IBM_3780IDSP 0x007d | |
26788 | #define PCI_DEVICE_ID_IBM_CHUKAR 0x0096 | |
26789 | +#define PCI_DEVICE_ID_IBM_CPC710_PCI64 0x00fc | |
26790 | +#define PCI_DEVICE_ID_IBM_CPC710_PCI32 0x0105 | |
26791 | #define PCI_DEVICE_ID_IBM_405GP 0x0156 | |
26792 | #define PCI_DEVICE_ID_IBM_SERVERAIDI960 0x01bd | |
26793 | #define PCI_DEVICE_ID_IBM_MPIC_2 0xffff | |
26794 | @@ -443,6 +446,7 @@ | |
26795 | #define PCI_DEVICE_ID_NEC_PCX2 0x0046 | |
26796 | #define PCI_DEVICE_ID_NEC_NILE4 0x005a | |
26797 | #define PCI_DEVICE_ID_NEC_VRC5476 0x009b | |
26798 | +#define PCI_DEVICE_ID_NEC_VRC5477_AC97 0x00a6 | |
26799 | ||
26800 | #define PCI_VENDOR_ID_FD 0x1036 | |
26801 | #define PCI_DEVICE_ID_FD_36C70 0x0000 | |
26802 | @@ -505,6 +509,9 @@ | |
26803 | #define PCI_DEVICE_ID_HP_DIVA1 0x1049 | |
26804 | #define PCI_DEVICE_ID_HP_DIVA2 0x104A | |
26805 | #define PCI_DEVICE_ID_HP_SP2_0 0x104B | |
26806 | +#define PCI_DEVICE_ID_HP_ZX1_SBA 0x1229 | |
26807 | +#define PCI_DEVICE_ID_HP_ZX1_IOC 0x122a | |
26808 | +#define PCI_DEVICE_ID_HP_ZX1_LBA 0x122e | |
26809 | ||
26810 | #define PCI_VENDOR_ID_PCTECH 0x1042 | |
26811 | #define PCI_DEVICE_ID_PCTECH_RZ1000 0x1000 | |
26812 | @@ -535,10 +542,6 @@ | |
26813 | #define PCI_DEVICE_ID_ELSA_MICROLINK 0x1000 | |
26814 | #define PCI_DEVICE_ID_ELSA_QS3000 0x3000 | |
26815 | ||
26816 | -#define PCI_VENDOR_ID_ELSA 0x1048 | |
26817 | -#define PCI_DEVICE_ID_ELSA_MICROLINK 0x1000 | |
26818 | -#define PCI_DEVICE_ID_ELSA_QS3000 0x3000 | |
26819 | - | |
26820 | #define PCI_VENDOR_ID_SGS 0x104a | |
26821 | #define PCI_DEVICE_ID_SGS_2000 0x0008 | |
26822 | #define PCI_DEVICE_ID_SGS_1764 0x0009 | |
26823 | @@ -595,6 +598,7 @@ | |
26824 | #define PCI_DEVICE_ID_MOTOROLA_MPC106 0x0002 | |
26825 | #define PCI_DEVICE_ID_MOTOROLA_RAVEN 0x4801 | |
26826 | #define PCI_DEVICE_ID_MOTOROLA_FALCON 0x4802 | |
26827 | +#define PCI_DEVICE_ID_MOTOROLA_HAWK 0x4803 | |
26828 | #define PCI_DEVICE_ID_MOTOROLA_CPX8216 0x4806 | |
26829 | ||
26830 | #define PCI_VENDOR_ID_PROMISE 0x105a | |
26831 | @@ -602,10 +606,14 @@ | |
26832 | #define PCI_DEVICE_ID_PROMISE_20267 0x4d30 | |
26833 | #define PCI_DEVICE_ID_PROMISE_20246 0x4d33 | |
26834 | #define PCI_DEVICE_ID_PROMISE_20262 0x4d38 | |
26835 | +#define PCI_DEVICE_ID_PROMISE_20263 0x0D38 | |
26836 | #define PCI_DEVICE_ID_PROMISE_20268 0x4d68 | |
26837 | -#define PCI_DEVICE_ID_PROMISE_20268R 0x6268 | |
26838 | +#define PCI_DEVICE_ID_PROMISE_20270 0x6268 | |
26839 | #define PCI_DEVICE_ID_PROMISE_20269 0x4d69 | |
26840 | +#define PCI_DEVICE_ID_PROMISE_20271 0x6269 | |
26841 | #define PCI_DEVICE_ID_PROMISE_20275 0x1275 | |
26842 | +#define PCI_DEVICE_ID_PROMISE_20276 0x5275 | |
26843 | +#define PCI_DEVICE_ID_PROMISE_20277 0x7275 | |
26844 | #define PCI_DEVICE_ID_PROMISE_5300 0x5300 | |
26845 | ||
26846 | #define PCI_VENDOR_ID_N9 0x105d | |
26847 | @@ -807,6 +815,7 @@ | |
26848 | #define PCI_DEVICE_ID_AL_M1621 0x1621 | |
26849 | #define PCI_DEVICE_ID_AL_M1631 0x1631 | |
26850 | #define PCI_DEVICE_ID_AL_M1641 0x1641 | |
26851 | +#define PCI_DEVICE_ID_AL_M1644 0x1644 | |
26852 | #define PCI_DEVICE_ID_AL_M1647 0x1647 | |
26853 | #define PCI_DEVICE_ID_AL_M1651 0x1651 | |
26854 | #define PCI_DEVICE_ID_AL_M1543 0x1543 | |
26855 | @@ -923,6 +932,10 @@ | |
26856 | #define PCI_VENDOR_ID_TTI 0x1103 | |
26857 | #define PCI_DEVICE_ID_TTI_HPT343 0x0003 | |
26858 | #define PCI_DEVICE_ID_TTI_HPT366 0x0004 | |
26859 | +#define PCI_DEVICE_ID_TTI_HPT372 0x0005 | |
26860 | +#define PCI_DEVICE_ID_TTI_HPT302 0x0006 | |
26861 | +#define PCI_DEVICE_ID_TTI_HPT371 0x0007 | |
26862 | +#define PCI_DEVICE_ID_TTI_HPT374 0x0008 | |
26863 | ||
26864 | #define PCI_VENDOR_ID_VIA 0x1106 | |
26865 | #define PCI_DEVICE_ID_VIA_8363_0 0x0305 | |
26866 | @@ -959,11 +972,12 @@ | |
26867 | #define PCI_DEVICE_ID_VIA_8233_7 0x3065 | |
26868 | #define PCI_DEVICE_ID_VIA_82C686_6 0x3068 | |
26869 | #define PCI_DEVICE_ID_VIA_8233_0 0x3074 | |
26870 | +#define PCI_DEVICE_ID_VIA_8633_0 0x3091 | |
26871 | +#define PCI_DEVICE_ID_VIA_8367_0 0x3099 | |
26872 | #define PCI_DEVICE_ID_VIA_8622 0x3102 | |
26873 | #define PCI_DEVICE_ID_VIA_8233C_0 0x3109 | |
26874 | #define PCI_DEVICE_ID_VIA_8361 0x3112 | |
26875 | -#define PCI_DEVICE_ID_VIA_8633_0 0x3091 | |
26876 | -#define PCI_DEVICE_ID_VIA_8367_0 0x3099 | |
26877 | +#define PCI_DEVICE_ID_VIA_8233A 0x3147 | |
26878 | #define PCI_DEVICE_ID_VIA_86C100A 0x6100 | |
26879 | #define PCI_DEVICE_ID_VIA_8231 0x8231 | |
26880 | #define PCI_DEVICE_ID_VIA_8231_4 0x8235 | |
26881 | @@ -973,7 +987,7 @@ | |
26882 | #define PCI_DEVICE_ID_VIA_82C597_1 0x8597 | |
26883 | #define PCI_DEVICE_ID_VIA_82C598_1 0x8598 | |
26884 | #define PCI_DEVICE_ID_VIA_8601_1 0x8601 | |
26885 | -#define PCI_DEVICE_ID_VIA_8505_1 0X8605 | |
26886 | +#define PCI_DEVICE_ID_VIA_8505_1 0x8605 | |
26887 | #define PCI_DEVICE_ID_VIA_8633_1 0xB091 | |
26888 | #define PCI_DEVICE_ID_VIA_8367_1 0xB099 | |
26889 | ||
26890 | @@ -1094,12 +1108,18 @@ | |
26891 | #define PCI_DEVICE_ID_SERVERWORKS_LE 0x0009 | |
26892 | #define PCI_DEVICE_ID_SERVERWORKS_CIOB30 0x0010 | |
26893 | #define PCI_DEVICE_ID_SERVERWORKS_CMIC_HE 0x0011 | |
26894 | +#define PCI_DEVICE_ID_SERVERWORKS_GCNB_LE 0x0017 | |
26895 | #define PCI_DEVICE_ID_SERVERWORKS_OSB4 0x0200 | |
26896 | #define PCI_DEVICE_ID_SERVERWORKS_CSB5 0x0201 | |
26897 | +#define PCI_DEVICE_ID_SERVERWORKS_CSB6 0x0203 | |
26898 | #define PCI_DEVICE_ID_SERVERWORKS_OSB4IDE 0x0211 | |
26899 | #define PCI_DEVICE_ID_SERVERWORKS_CSB5IDE 0x0212 | |
26900 | +#define PCI_DEVICE_ID_SERVERWORKS_CSB6IDE 0x0213 | |
26901 | #define PCI_DEVICE_ID_SERVERWORKS_OSB4USB 0x0220 | |
26902 | #define PCI_DEVICE_ID_SERVERWORKS_CSB5USB PCI_DEVICE_ID_SERVERWORKS_OSB4USB | |
26903 | +#define PCI_DEVICE_ID_SERVERWORKS_CSB6USB 0x0221 | |
26904 | +#define PCI_DEVICE_ID_SERVERWORKS_GCLE 0x0225 | |
26905 | +#define PCI_DEVICE_ID_SERVERWORKS_GCLE2 0x0227 | |
26906 | #define PCI_DEVICE_ID_SERVERWORKS_CSB5ISA 0x0230 | |
26907 | ||
26908 | #define PCI_VENDOR_ID_SBE 0x1176 | |
26909 | @@ -1112,6 +1132,11 @@ | |
26910 | #define PCI_DEVICE_ID_TOSHIBA_TOPIC95 0x060a | |
26911 | #define PCI_DEVICE_ID_TOSHIBA_TOPIC97 0x060f | |
26912 | ||
26913 | +#define PCI_VENDOR_ID_TOSHIBA_2 0x102f | |
26914 | +#define PCI_DEVICE_ID_TOSHIBA_TX3927 0x000a | |
26915 | +#define PCI_DEVICE_ID_TOSHIBA_TC35815CF 0x0030 | |
26916 | +#define PCI_DEVICE_ID_TOSHIBA_TX4927 0x0180 | |
26917 | + | |
26918 | #define PCI_VENDOR_ID_RICOH 0x1180 | |
26919 | #define PCI_DEVICE_ID_RICOH_RL5C465 0x0465 | |
26920 | #define PCI_DEVICE_ID_RICOH_RL5C466 0x0466 | |
26921 | @@ -1287,13 +1312,9 @@ | |
26922 | #define PCI_VENDOR_ID_ITE 0x1283 | |
26923 | #define PCI_DEVICE_ID_ITE_IT8172G 0x8172 | |
26924 | #define PCI_DEVICE_ID_ITE_IT8172G_AUDIO 0x0801 | |
26925 | - | |
26926 | -#define PCI_VENDOR_ID_ITE 0x1283 | |
26927 | -#define PCI_DEVICE_ID_ITE_IT8172G 0x8172 | |
26928 | - | |
26929 | -#define PCI_VENDOR_ID_ITE 0x1283 | |
26930 | #define PCI_DEVICE_ID_ITE_8872 0x8872 | |
26931 | ||
26932 | +#define PCI_DEVICE_ID_ITE_IT8330G_0 0xe886 | |
26933 | ||
26934 | /* formerly Platform Tech */ | |
26935 | #define PCI_VENDOR_ID_ESS_OLD 0x1285 | |
26936 | @@ -1458,6 +1479,8 @@ | |
26937 | #define PCI_DEVICE_ID_LAVA_DSERIAL 0x0100 /* 2x 16550 */ | |
26938 | #define PCI_DEVICE_ID_LAVA_QUATRO_A 0x0101 /* 2x 16550, half of 4 port */ | |
26939 | #define PCI_DEVICE_ID_LAVA_QUATRO_B 0x0102 /* 2x 16550, half of 4 port */ | |
26940 | +#define PCI_DEVICE_ID_LAVA_OCTO_A 0x0180 /* 4x 16550A, half of 8 port */ | |
26941 | +#define PCI_DEVICE_ID_LAVA_OCTO_B 0x0181 /* 4x 16550A, half of 8 port */ | |
26942 | #define PCI_DEVICE_ID_LAVA_PORT_PLUS 0x0200 /* 2x 16650 */ | |
26943 | #define PCI_DEVICE_ID_LAVA_QUAD_A 0x0201 /* 2x 16650, half of 4 port */ | |
26944 | #define PCI_DEVICE_ID_LAVA_QUAD_B 0x0202 /* 2x 16650, half of 4 port */ | |
26945 | @@ -1474,9 +1497,9 @@ | |
26946 | #define PCI_VENDOR_ID_OXSEMI 0x1415 | |
26947 | #define PCI_DEVICE_ID_OXSEMI_12PCI840 0x8403 | |
26948 | #define PCI_DEVICE_ID_OXSEMI_16PCI954 0x9501 | |
26949 | -#define PCI_DEVICE_ID_OXSEMI_16PCI952 0x950A | |
26950 | #define PCI_DEVICE_ID_OXSEMI_16PCI95N 0x9511 | |
26951 | #define PCI_DEVICE_ID_OXSEMI_16PCI954PP 0x9513 | |
26952 | +#define PCI_DEVICE_ID_OXSEMI_16PCI952 0x9521 | |
26953 | ||
26954 | #define PCI_VENDOR_ID_AIRONET 0x14b9 | |
26955 | #define PCI_DEVICE_ID_AIRONET_4800_1 0x0001 | |
26956 | @@ -1506,7 +1529,11 @@ | |
26957 | #define PCI_VENDOR_ID_BROADCOM 0x14e4 | |
26958 | #define PCI_DEVICE_ID_TIGON3_5700 0x1644 | |
26959 | #define PCI_DEVICE_ID_TIGON3_5701 0x1645 | |
26960 | +#define PCI_DEVICE_ID_TIGON3_5702 0x1646 | |
26961 | #define PCI_DEVICE_ID_TIGON3_5703 0x1647 | |
26962 | +#define PCI_DEVICE_ID_TIGON3_5702FE 0x164d | |
26963 | +#define PCI_DEVICE_ID_TIGON3_5702X 0x16a6 | |
26964 | +#define PCI_DEVICE_ID_TIGON3_5703X 0x16a7 | |
26965 | ||
26966 | #define PCI_VENDOR_ID_SYBA 0x1592 | |
26967 | #define PCI_DEVICE_ID_SYBA_2P_EPP 0x0782 | |
26968 | @@ -1521,6 +1548,10 @@ | |
26969 | #define PCI_VENDOR_ID_PDC 0x15e9 | |
26970 | #define PCI_DEVICE_ID_PDC_1841 0x1841 | |
26971 | ||
26972 | +#define PCI_VENDOR_ID_ALTIMA 0x173b | |
26973 | +#define PCI_DEVICE_ID_ALTIMA_AC1000 0x03e8 | |
26974 | +#define PCI_DEVICE_ID_ALTIMA_AC9100 0x03ea | |
26975 | + | |
26976 | #define PCI_VENDOR_ID_SYMPHONY 0x1c1c | |
26977 | #define PCI_DEVICE_ID_SYMPHONY_101 0x0001 | |
26978 | ||
26979 | @@ -1571,13 +1602,15 @@ | |
26980 | #define PCI_DEVICE_ID_S3_ViRGE_MXPMV 0x8c03 | |
26981 | #define PCI_DEVICE_ID_S3_SONICVIBES 0xca00 | |
26982 | ||
26983 | +#define PCI_VENDOR_ID_DUNORD 0x5544 | |
26984 | +#define PCI_DEVICE_ID_DUNORD_I3000 0x0001 | |
26985 | +#define PCI_VENDOR_ID_GENROCO 0x5555 | |
26986 | +#define PCI_DEVICE_ID_GENROCO_HFP832 0x0003 | |
26987 | + | |
26988 | #define PCI_VENDOR_ID_DCI 0x6666 | |
26989 | #define PCI_DEVICE_ID_DCI_PCCOM4 0x0001 | |
26990 | #define PCI_DEVICE_ID_DCI_PCCOM8 0x0002 | |
26991 | ||
26992 | -#define PCI_VENDOR_ID_GENROCO 0x5555 | |
26993 | -#define PCI_DEVICE_ID_GENROCO_HFP832 0x0003 | |
26994 | - | |
26995 | #define PCI_VENDOR_ID_INTEL 0x8086 | |
26996 | #define PCI_DEVICE_ID_INTEL_21145 0x0039 | |
26997 | #define PCI_DEVICE_ID_INTEL_82375 0x0482 | |
26998 | @@ -1586,6 +1619,7 @@ | |
26999 | #define PCI_DEVICE_ID_INTEL_82430 0x0486 | |
27000 | #define PCI_DEVICE_ID_INTEL_82434 0x04a3 | |
27001 | #define PCI_DEVICE_ID_INTEL_I960 0x0960 | |
27002 | +#define PCI_DEVICE_ID_INTEL_I960RM 0x0962 | |
27003 | #define PCI_DEVICE_ID_INTEL_82562ET 0x1031 | |
27004 | #define PCI_DEVICE_ID_INTEL_82559ER 0x1209 | |
27005 | #define PCI_DEVICE_ID_INTEL_82092AA_0 0x1221 | |
27006 | @@ -1631,16 +1665,6 @@ | |
27007 | #define PCI_DEVICE_ID_INTEL_82801BA_2 0x2443 | |
27008 | #define PCI_DEVICE_ID_INTEL_82801BA_3 0x2444 | |
27009 | #define PCI_DEVICE_ID_INTEL_82801BA_4 0x2445 | |
27010 | -#define PCI_DEVICE_ID_INTEL_82801CA_0 0x2480 | |
27011 | -#define PCI_DEVICE_ID_INTEL_82801CA_2 0x2482 | |
27012 | -#define PCI_DEVICE_ID_INTEL_82801CA_3 0x2483 | |
27013 | -#define PCI_DEVICE_ID_INTEL_82801CA_4 0x2484 | |
27014 | -#define PCI_DEVICE_ID_INTEL_82801CA_5 0x2485 | |
27015 | -#define PCI_DEVICE_ID_INTEL_82801CA_6 0x2486 | |
27016 | -#define PCI_DEVICE_ID_INTEL_82801CA_7 0x2487 | |
27017 | -#define PCI_DEVICE_ID_INTEL_82801CA_10 0x248a | |
27018 | -#define PCI_DEVICE_ID_INTEL_82801CA_11 0x248b | |
27019 | -#define PCI_DEVICE_ID_INTEL_82801CA_12 0x248c | |
27020 | #define PCI_DEVICE_ID_INTEL_82801BA_5 0x2446 | |
27021 | #define PCI_DEVICE_ID_INTEL_82801BA_6 0x2448 | |
27022 | #define PCI_DEVICE_ID_INTEL_82801BA_7 0x2449 | |
27023 | @@ -1648,6 +1672,13 @@ | |
27024 | #define PCI_DEVICE_ID_INTEL_82801BA_9 0x244b | |
27025 | #define PCI_DEVICE_ID_INTEL_82801BA_10 0x244c | |
27026 | #define PCI_DEVICE_ID_INTEL_82801BA_11 0x244e | |
27027 | +#define PCI_DEVICE_ID_INTEL_82801E_0 0x2450 | |
27028 | +#define PCI_DEVICE_ID_INTEL_82801E_2 0x2452 | |
27029 | +#define PCI_DEVICE_ID_INTEL_82801E_3 0x2453 | |
27030 | +#define PCI_DEVICE_ID_INTEL_82801E_9 0x2459 | |
27031 | +#define PCI_DEVICE_ID_INTEL_82801E_11 0x245B | |
27032 | +#define PCI_DEVICE_ID_INTEL_82801E_14 0x245D | |
27033 | +#define PCI_DEVICE_ID_INTEL_82801E_15 0x245E | |
27034 | #define PCI_DEVICE_ID_INTEL_82801CA_0 0x2480 | |
27035 | #define PCI_DEVICE_ID_INTEL_82801CA_2 0x2482 | |
27036 | #define PCI_DEVICE_ID_INTEL_82801CA_3 0x2483 | |
27037 | @@ -1658,6 +1689,15 @@ | |
27038 | #define PCI_DEVICE_ID_INTEL_82801CA_10 0x248a | |
27039 | #define PCI_DEVICE_ID_INTEL_82801CA_11 0x248b | |
27040 | #define PCI_DEVICE_ID_INTEL_82801CA_12 0x248c | |
27041 | +#define PCI_DEVICE_ID_INTEL_82801DB_0 0x24c0 | |
27042 | +#define PCI_DEVICE_ID_INTEL_82801DB_2 0x24c2 | |
27043 | +#define PCI_DEVICE_ID_INTEL_82801DB_3 0x24c3 | |
27044 | +#define PCI_DEVICE_ID_INTEL_82801DB_4 0x24c4 | |
27045 | +#define PCI_DEVICE_ID_INTEL_82801DB_5 0x24c5 | |
27046 | +#define PCI_DEVICE_ID_INTEL_82801DB_6 0x24c6 | |
27047 | +#define PCI_DEVICE_ID_INTEL_82801DB_7 0x24c7 | |
27048 | +#define PCI_DEVICE_ID_INTEL_82801DB_11 0x24cb | |
27049 | +#define PCI_DEVICE_ID_INTEL_82801DB_13 0x24cd | |
27050 | #define PCI_DEVICE_ID_INTEL_80310 0x530d | |
27051 | #define PCI_DEVICE_ID_INTEL_82810_MC1 0x7120 | |
27052 | #define PCI_DEVICE_ID_INTEL_82810_IG1 0x7121 | |
ca42f4c5 | 27053 | --- linux.org/include/asm-i386/system.h Thu Nov 22 20:46:18 2001 |
27054 | +++ linux-2.4.19-rc1-ac7/include/asm-i386/system.h Thu Jul 18 14:24:43 2002 | |
27055 | @@ -317,8 +314,18 @@ | |
27056 | /* used in the idle loop; sti takes one instruction cycle to complete */ | |
27057 | #define safe_halt() __asm__ __volatile__("sti; hlt": : :"memory") | |
27058 | ||
27059 | +#define __save_and_cli(x) do { __save_flags(x); __cli(); } while(0); | |
27060 | +#define __save_and_sti(x) do { __save_flags(x); __sti(); } while(0); | |
27061 | + | |
27062 | /* For spinlocks etc */ | |
27063 | +#if 0 | |
27064 | #define local_irq_save(x) __asm__ __volatile__("pushfl ; popl %0 ; cli":"=g" (x): /* no input */ :"memory") | |
27065 | +#define local_irq_set(x) __asm__ __volatile__("pushfl ; popl %0 ; sti":"=g" (x): /* no input */ :"memory") | |
27066 | +#else | |
27067 | +#define local_irq_save(x) __save_and_cli(x) | |
27068 | +#define local_irq_set(x) __save_and_sti(x) | |
27069 | +#endif | |
27070 | + | |
27071 | #define local_irq_restore(x) __restore_flags(x) | |
27072 | #define local_irq_disable() __cli() | |
27073 | #define local_irq_enable() __sti() | |
27074 | @@ -333,6 +340,8 @@ | |
27075 | #define sti() __global_sti() | |
27076 | #define save_flags(x) ((x)=__global_save_flags()) | |
27077 | #define restore_flags(x) __global_restore_flags(x) | |
27078 | +#define save_and_cli(x) do { save_flags(x); cli(); } while(0); | |
27079 | +#define save_and_sti(x) do { save_flags(x); sti(); } while(0); | |
27080 | ||
27081 | #else | |
27082 | ||
27083 | @@ -340,6 +349,8 @@ | |
27084 | #define sti() __sti() | |
27085 | #define save_flags(x) __save_flags(x) | |
27086 | #define restore_flags(x) __restore_flags(x) | |
27087 | +#define save_and_cli(x) __save_and_cli(x) | |
27088 | +#define save_and_sti(x) __save_and_sti(x) | |
27089 | ||
27090 | #endif | |
27091 | ||
604fbef6 | 27092 | --- linux.org/fs/partitions/msdos.c Mon Feb 25 20:38:09 2002 |
27093 | +++ linux-2.4.19-rc1-ac7/fs/partitions/msdos.c Thu Jul 18 14:23:38 2002 | |
27094 | @@ -29,7 +29,13 @@ | |
27095 | ||
27096 | #ifdef CONFIG_BLK_DEV_IDE | |
27097 | #include <linux/ide.h> /* IDE xlate */ | |
27098 | -#endif /* CONFIG_BLK_DEV_IDE */ | |
27099 | +#elif defined(CONFIG_BLK_DEV_IDE_MODULE) | |
27100 | +#include <linux/module.h> | |
27101 | + | |
27102 | +int (*ide_xlate_1024_hook)(kdev_t, int, int, const char *); | |
27103 | +EXPORT_SYMBOL(ide_xlate_1024_hook); | |
27104 | +#define ide_xlate_1024 ide_xlate_1024_hook | |
27105 | +#endif | |
27106 | ||
27107 | #include <asm/system.h> | |
27108 | ||
569dabae | 27109 | --- linux/fs/partitions/Makefile.org Fri Jul 27 01:30:04 2001 |
27110 | +++ linux/fs/partitions/Makefile Mon Jul 22 10:31:42 2002 | |
27111 | @@ -9,7 +9,7 @@ | |
27112 | ||
27113 | O_TARGET := partitions.o | |
27114 | ||
27115 | -export-objs := check.o ibm.o | |
27116 | +export-objs := check.o ibm.o msdos.o | |
27117 | ||
27118 | obj-y := check.o | |
27119 | ||
8687e79e | 27120 | --- linux/drivers/scsi/ide-scsi.c.org Fri Dec 21 18:41:55 2001 |
27121 | +++ linux/drivers/scsi/ide-scsi.c Mon Jul 22 12:31:35 2002 | |
27122 | @@ -333,7 +333,7 @@ | |
27123 | if ((status & DRQ_STAT) == 0) { /* No more interrupts */ | |
27124 | if (test_bit(IDESCSI_LOG_CMD, &scsi->log)) | |
27125 | printk (KERN_INFO "Packet command completed, %d bytes transferred\n", pc->actually_transferred); | |
27126 | - ide__sti(); | |
27127 | + local_irq_enable(); | |
27128 | if (status & ERR_STAT) | |
27129 | rq->errors++; | |
27130 | idescsi_end_request (1, HWGROUP(drive)); | |
6c0a457b | 27131 | --- linux/kernel/ksyms.c.org Mon Jul 22 10:20:54 2002 |
27132 | +++ linux/kernel/ksyms.c Mon Jul 22 13:17:03 2002 | |
27133 | @@ -471,6 +471,7 @@ | |
27134 | EXPORT_SYMBOL(xtime); | |
27135 | EXPORT_SYMBOL(do_gettimeofday); | |
27136 | EXPORT_SYMBOL(do_settimeofday); | |
27137 | +EXPORT_SYMBOL(sys_sched_yield); | |
27138 | ||
27139 | #if !defined(__ia64__) | |
27140 | EXPORT_SYMBOL(loops_per_jiffy); | |
8d8b41df | 27141 | --- linux/include/linux/sched.h Mon Jul 22 12:32:07 2002 |
27142 | +++ linux-2.4.19-rc1-ac7/include/linux/sched.h Thu Jul 18 14:24:44 2002 | |
27143 | @@ -466,6 +466,8 @@ | |
27144 | */ | |
27145 | #define _STK_LIM (8*1024*1024) | |
27146 | ||
27147 | +asmlinkage long sys_sched_yield(void); | |
27148 | +#define yield() sys_sched_yield() | |
27149 | ||
27150 | /* | |
27151 | * The default (Linux) execution domain. | |
dedd3741 | 27152 | diff -Nur linux.org/arch/ppc/kernel/setup.c linux/arch/ppc/kernel/setup.c |
27153 | --- linux.org/arch/ppc/kernel/setup.c Wed Jul 24 12:24:05 2002 | |
27154 | +++ linux/arch/ppc/kernel/setup.c Wed Jul 24 11:33:17 2002 | |
27155 | @@ -690,13 +690,18 @@ | |
27156 | id->cfs_enable_2 = __le16_to_cpu(id->cfs_enable_2); | |
27157 | id->csf_default = __le16_to_cpu(id->csf_default); | |
27158 | id->dma_ultra = __le16_to_cpu(id->dma_ultra); | |
27159 | - id->word89 = __le16_to_cpu(id->word89); | |
27160 | - id->word90 = __le16_to_cpu(id->word90); | |
27161 | + id->trseuc = __le16_to_cpu(id->trseuc); | |
27162 | + id->trsEuc = __le16_to_cpu(id->trsEuc); | |
27163 | id->CurAPMvalues = __le16_to_cpu(id->CurAPMvalues); | |
27164 | - id->word92 = __le16_to_cpu(id->word92); | |
27165 | - id->hw_config = __le16_to_cpu(id->hw_config); | |
27166 | - for (i = 0; i < 32; i++) | |
27167 | - id->words94_125[i] = __le16_to_cpu(id->words94_125[i]); | |
27168 | + id->mprc = __le16_to_cpu(id->mprc); | |
27169 | + id->hw_config = __le16_to_cpu(id->hw_config); /* 93 */ | |
27170 | + id->acoustic = __le16_to_cpu(id->acoustic); | |
27171 | + id->msrqs = __le16_to_cpu(id->msrqs); | |
27172 | + id->sxfert = __le16_to_cpu(id->sxfert); | |
27173 | + id->sal = __le16_to_cpu(id->sal); | |
27174 | + id->spg = __le32_to_cpu(id->spg); | |
27175 | + for (i = 0; i < 22; i++) | |
27176 | + id->words104_125[i] = __le16_to_cpu(id->words104_125[i]); | |
27177 | id->last_lun = __le16_to_cpu(id->last_lun); | |
27178 | id->word127 = __le16_to_cpu(id->word127); | |
27179 | id->dlf = __le16_to_cpu(id->dlf); | |
27180 | @@ -706,6 +711,12 @@ | |
27181 | id->word156 = __le16_to_cpu(id->word156); | |
27182 | for (i = 0; i < 3; i++) | |
27183 | id->words157_159[i] = __le16_to_cpu(id->words157_159[i]); | |
27184 | - for (i = 0; i < 96; i++) | |
27185 | - id->words160_255[i] = __le16_to_cpu(id->words160_255[i]); | |
27186 | + id->cfa_power = __le16_to_cpu(id->cfa_power); | |
27187 | + for (i = 0; i < 14; i++) | |
27188 | + id->words161_175[i] = __le16_to_cpu(id->words161_175[i]); | |
27189 | + for (i = 0; i < 38; i++) | |
27190 | + id->words176_205[i] = __le16_to_cpu(id->words176_205[i]); | |
27191 | + for (i = 0; i < 48; i++) | |
27192 | + id->words206_254[i] = __le16_to_cpu(id->words206_254[i]); | |
27193 | + id->integrity_word = __le16_to_cpu(id->integrity_word); | |
27194 | } | |
27195 | diff -Nur linux.org/include/asm-ppc/hw_irq.h linux/include/asm-ppc/hw_irq.h | |
27196 | --- linux.org/include/asm-ppc/hw_irq.h Tue May 22 00:02:06 2001 | |
27197 | +++ linux/include/asm-ppc/hw_irq.h Wed Jul 24 12:00:53 2002 | |
27198 | @@ -20,6 +20,7 @@ | |
27199 | ||
27200 | #define __save_flags(flags) __save_flags_ptr((unsigned long *)&flags) | |
27201 | #define __save_and_cli(flags) ({__save_flags(flags);__cli();}) | |
27202 | +#define __save_and_sti(flags) ({__save_flags(flags);__sti();}) | |
27203 | ||
27204 | extern void do_lost_interrupts(unsigned long); | |
27205 | ||
27206 | diff -Nur linux.org/include/asm-ppc/ide.h linux/include/asm-ppc/ide.h | |
27207 | --- linux.org/include/asm-ppc/ide.h Mon Oct 8 20:40:13 2001 | |
27208 | +++ linux/include/asm-ppc/ide.h Wed Jul 24 12:02:43 2002 | |
27209 | @@ -118,17 +118,6 @@ | |
27210 | ppc_ide_md.ide_release_region(from, extent); | |
27211 | } | |
27212 | ||
27213 | -typedef union { | |
27214 | - unsigned all : 8; /* all of the bits together */ | |
27215 | - struct { | |
27216 | - unsigned bit7 : 1; /* always 1 */ | |
27217 | - unsigned lba : 1; /* using LBA instead of CHS */ | |
27218 | - unsigned bit5 : 1; /* always 1 */ | |
27219 | - unsigned unit : 1; /* drive select number, 0/1 */ | |
27220 | - unsigned head : 4; /* always zeros here */ | |
27221 | - } b; | |
27222 | -} select_t; | |
27223 | - | |
27224 | #if !defined(ide_request_irq) | |
27225 | #define ide_request_irq(irq,hand,flg,dev,id) request_irq((irq),(hand),(flg),(dev),(id)) | |
27226 | #endif | |
27227 | diff -Nur linux.org/include/asm-ppc/system.h linux/include/asm-ppc/system.h | |
27228 | --- linux.org/include/asm-ppc/system.h Tue Aug 28 15:58:33 2001 | |
27229 | +++ linux/include/asm-ppc/system.h Wed Jul 24 12:01:36 2002 | |
27230 | @@ -1,5 +1,5 @@ | |
27231 | /* | |
27232 | - * BK Id: SCCS/s.system.h 1.14 08/20/01 14:34:41 paulus | |
27233 | + * BK Id: SCCS/s.system.h 1.20 03/19/02 15:04:39 benh | |
27234 | */ | |
27235 | /* | |
27236 | * Copyright (C) 1999 Cort Dougan <cort@cs.nmt.edu> | |
27237 | @@ -58,9 +58,13 @@ | |
27238 | #ifdef CONFIG_6xx | |
27239 | extern long _get_L2CR(void); | |
27240 | extern void _set_L2CR(unsigned long); | |
27241 | +extern long _get_L3CR(void); | |
27242 | +extern void _set_L3CR(unsigned long); | |
27243 | #else | |
27244 | -#define _get_L2CR() 0 | |
27245 | +#define _get_L2CR() 0L | |
27246 | #define _set_L2CR(val) do { } while(0) | |
27247 | +#define _get_L3CR() 0L | |
27248 | +#define _set_L3CR(val) do { } while(0) | |
27249 | #endif | |
27250 | extern void via_cuda_init(void); | |
27251 | extern void pmac_nvram_init(void); | |
27252 | @@ -101,6 +105,7 @@ | |
27253 | #define save_flags(flags) __save_flags(flags) | |
27254 | #define restore_flags(flags) __restore_flags(flags) | |
27255 | #define save_and_cli(flags) __save_and_cli(flags) | |
27256 | +#define save_and_sti(flags) __save_and_sti(flags) | |
27257 | ||
27258 | #else /* CONFIG_SMP */ | |
27259 | ||
27260 | @@ -113,17 +118,17 @@ | |
27261 | #define save_flags(x) ((x)=__global_save_flags()) | |
27262 | #define restore_flags(x) __global_restore_flags(x) | |
27263 | ||
27264 | +#define save_and_cli(x) do { save_flags(x); cli(); } while(0); | |
27265 | +#define save_and_sti(x) do { save_flags(x); sti(); } while(0); | |
27266 | + | |
27267 | #endif /* !CONFIG_SMP */ | |
27268 | ||
27269 | #define local_irq_disable() __cli() | |
27270 | #define local_irq_enable() __sti() | |
27271 | #define local_irq_save(flags) __save_and_cli(flags) | |
27272 | +#define local_irq_set(flags) __save_and_sti(flags) | |
27273 | #define local_irq_restore(flags) __restore_flags(flags) | |
27274 | ||
27275 | -#endif /* __KERNEL__ */ | |
27276 | - | |
27277 | -#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr)))) | |
27278 | - | |
27279 | static __inline__ unsigned long | |
27280 | xchg_u32(volatile void *p, unsigned long val) | |
27281 | { | |
27282 | @@ -222,4 +227,5 @@ | |
27283 | (unsigned long)_n_, sizeof(*(ptr))); \ | |
27284 | }) | |
27285 | ||
27286 | +#endif /* __KERNEL__ */ | |
27287 | #endif /* __PPC_SYSTEM_H */ |