Blame view
drivers/ide/ide-iops.c
13.5 KB
1da177e4c Linux-2.6.12-rc2 |
1 |
/* |
1da177e4c Linux-2.6.12-rc2 |
2 |
* Copyright (C) 2000-2002 Andre Hedrick <andre@linux-ide.org> |
ccd32e221 ide: Switch to a ... |
3 |
* Copyright (C) 2003 Red Hat |
1da177e4c Linux-2.6.12-rc2 |
4 5 |
* */ |
1da177e4c Linux-2.6.12-rc2 |
6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#include <linux/module.h> #include <linux/types.h> #include <linux/string.h> #include <linux/kernel.h> #include <linux/timer.h> #include <linux/mm.h> #include <linux/interrupt.h> #include <linux/major.h> #include <linux/errno.h> #include <linux/genhd.h> #include <linux/blkpg.h> #include <linux/slab.h> #include <linux/pci.h> #include <linux/delay.h> |
1da177e4c Linux-2.6.12-rc2 |
20 21 |
#include <linux/ide.h> #include <linux/bitops.h> |
1e86240f3 [PATCH] IDE: Touc... |
22 |
#include <linux/nmi.h> |
1da177e4c Linux-2.6.12-rc2 |
23 24 25 26 27 |
#include <asm/byteorder.h> #include <asm/irq.h> #include <asm/uaccess.h> #include <asm/io.h> |
ed4af48fd ide: move IRQ unm... |
28 |
void SELECT_MASK(ide_drive_t *drive, int mask) |
1da177e4c Linux-2.6.12-rc2 |
29 |
{ |
ac95beedf ide: add struct i... |
30 31 32 33 |
const struct ide_port_ops *port_ops = drive->hwif->port_ops; if (port_ops && port_ops->maskproc) port_ops->maskproc(drive, mask); |
1da177e4c Linux-2.6.12-rc2 |
34 |
} |
92eb43800 ide: use ->tf_rea... |
35 36 |
u8 ide_read_error(ide_drive_t *drive) { |
3153c26b5 ide: refactor tf_... |
37 |
struct ide_taskfile tf; |
92eb43800 ide: use ->tf_rea... |
38 |
|
3153c26b5 ide: refactor tf_... |
39 |
drive->hwif->tp_ops->tf_read(drive, &tf, IDE_VALID_ERROR); |
92eb43800 ide: use ->tf_rea... |
40 |
|
3153c26b5 ide: refactor tf_... |
41 |
return tf.error; |
92eb43800 ide: use ->tf_rea... |
42 43 |
} EXPORT_SYMBOL_GPL(ide_read_error); |
4dde4492d ide: make drive->... |
44 |
void ide_fix_driveid(u16 *id) |
1da177e4c Linux-2.6.12-rc2 |
45 46 47 48 |
{ #ifndef __LITTLE_ENDIAN # ifdef __BIG_ENDIAN int i; |
5b90e9909 ide: cleanup ide_... |
49 |
|
48fb2688a ide: remove drive... |
50 |
for (i = 0; i < 256; i++) |
5b90e9909 ide: cleanup ide_... |
51 |
id[i] = __le16_to_cpu(id[i]); |
1da177e4c Linux-2.6.12-rc2 |
52 53 54 55 56 |
# else # error "Please fix <asm/byteorder.h>" # endif #endif } |
01745112d ide: move ide_fix... |
57 58 59 60 |
/* * ide_fixstring() cleans up and (optionally) byte-swaps a text string, * removing leading/trailing blanks and compressing internal blanks. * It is primarily used to tidy up the model name/number fields as |
aaaade3f0 ide: WIN_* -> ATA... |
61 |
* returned by the ATA_CMD_ID_ATA[PI] commands. |
01745112d ide: move ide_fix... |
62 |
*/ |
122f06f8b ide: checkpatch.p... |
63 |
void ide_fixstring(u8 *s, const int bytecount, const int byteswap) |
1da177e4c Linux-2.6.12-rc2 |
64 |
{ |
1a7809e34 ide: re-code ide_... |
65 |
u8 *p, *end = &s[bytecount & ~1]; /* bytecount must be even */ |
1da177e4c Linux-2.6.12-rc2 |
66 67 68 |
if (byteswap) { /* convert from big-endian to host byte order */ |
1a7809e34 ide: re-code ide_... |
69 70 |
for (p = s ; p != end ; p += 2) be16_to_cpus((u16 *) p); |
1da177e4c Linux-2.6.12-rc2 |
71 |
} |
1a7809e34 ide: re-code ide_... |
72 |
|
1da177e4c Linux-2.6.12-rc2 |
73 |
/* strip leading blanks */ |
1a7809e34 ide: re-code ide_... |
74 |
p = s; |
1da177e4c Linux-2.6.12-rc2 |
75 76 77 78 79 80 81 82 83 84 85 |
while (s != end && *s == ' ') ++s; /* compress internal blanks and strip trailing blanks */ while (s != end && *s) { if (*s++ != ' ' || (s != end && *s && *s != ' ')) *p++ = *(s-1); } /* wipe out trailing garbage */ while (p != end) *p++ = '\0'; } |
1da177e4c Linux-2.6.12-rc2 |
86 |
EXPORT_SYMBOL(ide_fixstring); |
1da177e4c Linux-2.6.12-rc2 |
87 |
/* |
1da177e4c Linux-2.6.12-rc2 |
88 89 90 |
* This routine busy-waits for the drive status to be not "busy". * It then checks the status for all of the "good" bits and none * of the "bad" bits, and if all is okay it returns 0. All other |
74af21cf4 ide: add __ide_wa... |
91 |
* cases return error -- caller may then invoke ide_error(). |
1da177e4c Linux-2.6.12-rc2 |
92 93 94 95 96 97 |
* * This routine should get fixed to not hog the cpu during extra long waits.. * That could be done by busy-waiting for the first jiffy or two, and then * setting a timer to wake up at half second intervals thereafter, * until timeout is achieved, before timing out. */ |
fa56d4cb4 ide: allow ide_de... |
98 99 |
int __ide_wait_stat(ide_drive_t *drive, u8 good, u8 bad, unsigned long timeout, u8 *rstat) |
1da177e4c Linux-2.6.12-rc2 |
100 |
{ |
b73c7ee25 ide: add ->read_s... |
101 |
ide_hwif_t *hwif = drive->hwif; |
374e042c3 ide: add struct i... |
102 |
const struct ide_tp_ops *tp_ops = hwif->tp_ops; |
1da177e4c Linux-2.6.12-rc2 |
103 |
unsigned long flags; |
74af21cf4 ide: add __ide_wa... |
104 105 |
int i; u8 stat; |
1da177e4c Linux-2.6.12-rc2 |
106 107 |
udelay(1); /* spec allows drive 400ns to assert "BUSY" */ |
374e042c3 ide: add struct i... |
108 |
stat = tp_ops->read_status(hwif); |
c47137a99 ide: add ide_read... |
109 |
|
3a7d24841 ide: use ATA_* de... |
110 |
if (stat & ATA_BUSY) { |
9b896033a ide: fix accident... |
111 |
local_save_flags(flags); |
54cc1428c ide: remove local... |
112 |
local_irq_enable_in_hardirq(); |
1da177e4c Linux-2.6.12-rc2 |
113 |
timeout += jiffies; |
3a7d24841 ide: use ATA_* de... |
114 |
while ((stat = tp_ops->read_status(hwif)) & ATA_BUSY) { |
1da177e4c Linux-2.6.12-rc2 |
115 116 117 118 119 120 |
if (time_after(jiffies, timeout)) { /* * One last read after the timeout in case * heavy interrupt load made us not make any * progress during the timeout.. */ |
374e042c3 ide: add struct i... |
121 |
stat = tp_ops->read_status(hwif); |
3a7d24841 ide: use ATA_* de... |
122 |
if ((stat & ATA_BUSY) == 0) |
1da177e4c Linux-2.6.12-rc2 |
123 124 125 |
break; local_irq_restore(flags); |
74af21cf4 ide: add __ide_wa... |
126 127 |
*rstat = stat; return -EBUSY; |
1da177e4c Linux-2.6.12-rc2 |
128 129 130 131 132 133 134 135 136 137 138 139 140 |
} } local_irq_restore(flags); } /* * Allow status to settle, then read it again. * A few rare drives vastly violate the 400ns spec here, * so we'll wait up to 10usec for a "good" status * rather than expensively fail things immediately. * This fix courtesy of Matthew Faupel & Niccolo Rigacci. */ for (i = 0; i < 10; i++) { udelay(1); |
374e042c3 ide: add struct i... |
141 |
stat = tp_ops->read_status(hwif); |
c47137a99 ide: add ide_read... |
142 143 |
if (OK_STAT(stat, good, bad)) { |
74af21cf4 ide: add __ide_wa... |
144 |
*rstat = stat; |
1da177e4c Linux-2.6.12-rc2 |
145 |
return 0; |
74af21cf4 ide: add __ide_wa... |
146 |
} |
1da177e4c Linux-2.6.12-rc2 |
147 |
} |
74af21cf4 ide: add __ide_wa... |
148 149 150 151 152 153 154 155 156 |
*rstat = stat; return -EFAULT; } /* * In case of error returns error value after doing "*startstop = ide_error()". * The caller should return the updated value of "startstop" in this case, * "startstop" is unchanged when the function returns 0. */ |
122f06f8b ide: checkpatch.p... |
157 158 |
int ide_wait_stat(ide_startstop_t *startstop, ide_drive_t *drive, u8 good, u8 bad, unsigned long timeout) |
74af21cf4 ide: add __ide_wa... |
159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 |
{ int err; u8 stat; /* bail early if we've exceeded max_failures */ if (drive->max_failures && (drive->failures > drive->max_failures)) { *startstop = ide_stopped; return 1; } err = __ide_wait_stat(drive, good, bad, timeout, &stat); if (err) { char *s = (err == -EBUSY) ? "status timeout" : "status error"; *startstop = ide_error(drive, s, stat); } return err; |
1da177e4c Linux-2.6.12-rc2 |
177 |
} |
1da177e4c Linux-2.6.12-rc2 |
178 |
EXPORT_SYMBOL(ide_wait_stat); |
a5b7e70d7 ide: add cable de... |
179 180 181 |
/** * ide_in_drive_list - look for drive in black/white list * @id: drive identifier |
4dde4492d ide: make drive->... |
182 |
* @table: list to inspect |
a5b7e70d7 ide: add cable de... |
183 184 185 186 |
* * Look for a drive in the blacklist and the whitelist tables * Returns 1 if the drive is found in the table. */ |
4dde4492d ide: make drive->... |
187 |
int ide_in_drive_list(u16 *id, const struct drive_list_entry *table) |
a5b7e70d7 ide: add cable de... |
188 |
{ |
4dde4492d ide: make drive->... |
189 190 191 192 |
for ( ; table->id_model; table++) if ((!strcmp(table->id_model, (char *)&id[ATA_ID_PROD])) && (!table->id_firmware || strstr((char *)&id[ATA_ID_FW_REV], table->id_firmware))) |
a5b7e70d7 ide: add cable de... |
193 194 195 |
return 1; return 0; } |
b0244a004 ide-disk: workaro... |
196 |
EXPORT_SYMBOL_GPL(ide_in_drive_list); |
a5b7e70d7 ide: add cable de... |
197 198 |
/* * Early UDMA66 devices don't set bit14 to 1, only bit13 is valid. |
8588a2b73 ide: add SH-S202J... |
199 |
* Some optical devices with the buggy firmwares have the same problem. |
a5b7e70d7 ide: add cable de... |
200 201 202 |
*/ static const struct drive_list_entry ivb_list[] = { { "QUANTUM FIREBALLlct10 05" , "A03.0900" }, |
ba9413bd2 ide: add QUANTUM ... |
203 |
{ "QUANTUM FIREBALLlct20 30" , "APL.0900" }, |
8588a2b73 ide: add SH-S202J... |
204 |
{ "TSSTcorp CDDVDW SH-S202J" , "SB00" }, |
e97564f36 ide: More TSST dr... |
205 206 207 |
{ "TSSTcorp CDDVDW SH-S202J" , "SB01" }, { "TSSTcorp CDDVDW SH-S202N" , "SB00" }, { "TSSTcorp CDDVDW SH-S202N" , "SB01" }, |
3ced5c49b ide: add TSSTcorp... |
208 209 |
{ "TSSTcorp CDDVDW SH-S202H" , "SB00" }, { "TSSTcorp CDDVDW SH-S202H" , "SB01" }, |
c7b997b37 ide: add SAMSUNG ... |
210 |
{ "SAMSUNG SP0822N" , "WA100-10" }, |
a5b7e70d7 ide: add cable de... |
211 212 |
{ NULL , NULL } }; |
1da177e4c Linux-2.6.12-rc2 |
213 214 215 216 |
/* * All hosts that use the 80c ribbon must use! * The name is derived from upper byte of word 93 and the 80c ribbon. */ |
122f06f8b ide: checkpatch.p... |
217 |
u8 eighty_ninty_three(ide_drive_t *drive) |
1da177e4c Linux-2.6.12-rc2 |
218 |
{ |
7f8f48af0 ide: cable detect... |
219 |
ide_hwif_t *hwif = drive->hwif; |
4dde4492d ide: make drive->... |
220 |
u16 *id = drive->id; |
a5b7e70d7 ide: add cable de... |
221 |
int ivb = ide_in_drive_list(id, ivb_list); |
7f8f48af0 ide: cable detect... |
222 |
|
76937fa76 ide: add SATA cab... |
223 |
if (hwif->cbl == ATA_CBL_SATA || hwif->cbl == ATA_CBL_PATA40_SHORT) |
49521f97c ide: add short ca... |
224 |
return 1; |
a5b7e70d7 ide: add cable de... |
225 226 227 228 |
if (ivb) printk(KERN_DEBUG "%s: skipping word 93 validity check ", drive->name); |
367d7e78d ide: ide_dev_is_s... |
229 |
if (ata_id_is_sata(id) && !ivb) |
b98f8803c ide: fix cable de... |
230 |
return 1; |
a5b7e70d7 ide: add cable de... |
231 |
if (hwif->cbl != ATA_CBL_PATA80 && !ivb) |
7f8f48af0 ide: cable detect... |
232 |
goto no_80w; |
1a1276e7b [PATCH] Old IDE, ... |
233 |
|
f68d9320c ide: revert "ide:... |
234 235 |
/* * FIXME: |
f367bed00 Revert "ide: chan... |
236 |
* - change master/slave IDENTIFY order |
a5b7e70d7 ide: add cable de... |
237 |
* - force bit13 (80c cable present) check also for !ivb devices |
f68d9320c ide: revert "ide:... |
238 239 |
* (unless the slave device is pre-ATA3) */ |
8369d5fa6 ide: fix 40-wire ... |
240 |
if (id[ATA_ID_HW_CONFIG] & 0x4000) |
7f8f48af0 ide: cable detect... |
241 |
return 1; |
8369d5fa6 ide: fix 40-wire ... |
242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 |
if (ivb) { const char *model = (char *)&id[ATA_ID_PROD]; if (strstr(model, "TSSTcorp CDDVDW SH-S202")) { /* * These ATAPI devices always report 80c cable * so we have to depend on the host in this case. */ if (hwif->cbl == ATA_CBL_PATA80) return 1; } else { /* Depend on the device side cable detection. */ if (id[ATA_ID_HW_CONFIG] & 0x2000) return 1; } } |
7f8f48af0 ide: cable detect... |
258 |
no_80w: |
97100fc81 ide: add device f... |
259 |
if (drive->dev_flags & IDE_DFLAG_UDMA33_WARNED) |
7f8f48af0 ide: cable detect... |
260 261 262 263 264 |
return 0; printk(KERN_WARNING "%s: %s side 80-wire cable detection failed, " "limiting max speed to UDMA33 ", |
49521f97c ide: add short ca... |
265 266 |
drive->name, hwif->cbl == ATA_CBL_PATA80 ? "drive" : "host"); |
7f8f48af0 ide: cable detect... |
267 |
|
97100fc81 ide: add device f... |
268 |
drive->dev_flags |= IDE_DFLAG_UDMA33_WARNED; |
7f8f48af0 ide: cable detect... |
269 270 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
271 |
} |
8bc1e5aa0 ide: respect quir... |
272 273 274 275 276 277 278 279 280 |
static const char *nien_quirk_list[] = { "QUANTUM FIREBALLlct08 08", "QUANTUM FIREBALLP KA6.4", "QUANTUM FIREBALLP KA9.1", "QUANTUM FIREBALLP KX13.6", "QUANTUM FIREBALLP KX20.5", "QUANTUM FIREBALLP KX27.3", "QUANTUM FIREBALLP LM20.4", "QUANTUM FIREBALLP LM20.5", |
a2d10568f ide: fixup for fu... |
281 |
"FUJITSU MHZ2160BH G2", |
8bc1e5aa0 ide: respect quir... |
282 283 284 285 286 287 288 289 290 |
NULL }; void ide_check_nien_quirk_list(ide_drive_t *drive) { const char **list, *m = (char *)&drive->id[ATA_ID_PROD]; for (list = nien_quirk_list; *list != NULL; list++) if (strstr(m, *list) != NULL) { |
734affdca ide: add IDE_DFLA... |
291 |
drive->dev_flags |= IDE_DFLAG_NIEN_QUIRK; |
8bc1e5aa0 ide: respect quir... |
292 293 |
return; } |
8bc1e5aa0 ide: respect quir... |
294 |
} |
8a4551340 ide: remove dead ... |
295 |
int ide_driveid_update(ide_drive_t *drive) |
1da177e4c Linux-2.6.12-rc2 |
296 |
{ |
4dde4492d ide: make drive->... |
297 |
u16 *id; |
2ebe1d9ef ide: use try_to_i... |
298 |
int rc; |
2f40c9b0b ide: fix kmalloc(... |
299 300 301 302 |
id = kmalloc(SECTOR_SIZE, GFP_ATOMIC); if (id == NULL) return 0; |
1da177e4c Linux-2.6.12-rc2 |
303 |
|
1da177e4c Linux-2.6.12-rc2 |
304 |
SELECT_MASK(drive, 1); |
fa56d4cb4 ide: allow ide_de... |
305 |
rc = ide_dev_read_id(drive, ATA_CMD_ID_ATA, id, 1); |
2ebe1d9ef ide: use try_to_i... |
306 |
SELECT_MASK(drive, 0); |
2f40c9b0b ide: fix kmalloc(... |
307 |
|
2ebe1d9ef ide: use try_to_i... |
308 |
if (rc) |
2f40c9b0b ide: fix kmalloc(... |
309 |
goto out_err; |
f323b80dc ide: sanitize SEL... |
310 |
|
4dde4492d ide: make drive->... |
311 312 313 |
drive->id[ATA_ID_UDMA_MODES] = id[ATA_ID_UDMA_MODES]; drive->id[ATA_ID_MWDMA_MODES] = id[ATA_ID_MWDMA_MODES]; drive->id[ATA_ID_SWDMA_MODES] = id[ATA_ID_SWDMA_MODES]; |
74638c848 ide: add support ... |
314 |
drive->id[ATA_ID_CFA_MODES] = id[ATA_ID_CFA_MODES]; |
4dde4492d ide: make drive->... |
315 316 317 |
/* anything more ? */ kfree(id); |
1da177e4c Linux-2.6.12-rc2 |
318 |
return 1; |
2f40c9b0b ide: fix kmalloc(... |
319 |
out_err: |
2f40c9b0b ide: fix kmalloc(... |
320 321 322 323 324 |
if (rc == 2) printk(KERN_ERR "%s: %s: bad status ", drive->name, __func__); kfree(id); return 0; |
1da177e4c Linux-2.6.12-rc2 |
325 |
} |
74af21cf4 ide: add __ide_wa... |
326 |
int ide_config_drive_speed(ide_drive_t *drive, u8 speed) |
1da177e4c Linux-2.6.12-rc2 |
327 |
{ |
74af21cf4 ide: add __ide_wa... |
328 |
ide_hwif_t *hwif = drive->hwif; |
374e042c3 ide: add struct i... |
329 |
const struct ide_tp_ops *tp_ops = hwif->tp_ops; |
c9ff9e7b6 ide: refactor tf_... |
330 |
struct ide_taskfile tf; |
4dde4492d ide: make drive->... |
331 |
u16 *id = drive->id, i; |
89613e667 ide: don't set PI... |
332 |
int error = 0; |
1da177e4c Linux-2.6.12-rc2 |
333 |
u8 stat; |
1da177e4c Linux-2.6.12-rc2 |
334 |
#ifdef CONFIG_BLK_DEV_IDEDMA |
5e37bdc08 ide: add struct i... |
335 336 |
if (hwif->dma_ops) /* check if host supports DMA */ hwif->dma_ops->dma_host_set(drive, 0); |
1da177e4c Linux-2.6.12-rc2 |
337 |
#endif |
89613e667 ide: don't set PI... |
338 |
/* Skip setting PIO flow-control modes on pre-EIDE drives */ |
48fb2688a ide: remove drive... |
339 |
if ((speed & 0xf8) == XFER_PIO_0 && ata_id_has_iordy(drive->id) == 0) |
89613e667 ide: don't set PI... |
340 |
goto skip; |
1da177e4c Linux-2.6.12-rc2 |
341 342 343 344 345 346 |
/* * Don't use ide_wait_cmd here - it will * attempt to set_geometry and recalibrate, * but for some reason these don't work at * this point (lost interrupt). */ |
ee1b1cc97 ide: fix comments... |
347 |
|
1da177e4c Linux-2.6.12-rc2 |
348 |
udelay(1); |
fdd88f0af ide: inline SELEC... |
349 |
tp_ops->dev_select(drive); |
e5403bff8 ide: mask interru... |
350 |
SELECT_MASK(drive, 1); |
1da177e4c Linux-2.6.12-rc2 |
351 |
udelay(1); |
ecf3a31d2 ide: turn set_irq... |
352 |
tp_ops->write_devctl(hwif, ATA_NIEN | ATA_DEVCTL_OBS); |
59be2c80f ide: use ->tf_loa... |
353 |
|
c9ff9e7b6 ide: refactor tf_... |
354 355 356 |
memset(&tf, 0, sizeof(tf)); tf.feature = SETFEATURES_XFER; tf.nsect = speed; |
59be2c80f ide: use ->tf_loa... |
357 |
|
c9ff9e7b6 ide: refactor tf_... |
358 |
tp_ops->tf_load(drive, &tf, IDE_VALID_FEATURE | IDE_VALID_NSECT); |
59be2c80f ide: use ->tf_loa... |
359 |
|
aaaade3f0 ide: WIN_* -> ATA... |
360 |
tp_ops->exec_command(hwif, ATA_CMD_SET_FEATURES); |
59be2c80f ide: use ->tf_loa... |
361 |
|
734affdca ide: add IDE_DFLA... |
362 |
if (drive->dev_flags & IDE_DFLAG_NIEN_QUIRK) |
ecf3a31d2 ide: turn set_irq... |
363 |
tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS); |
1da177e4c Linux-2.6.12-rc2 |
364 |
|
74af21cf4 ide: add __ide_wa... |
365 |
error = __ide_wait_stat(drive, drive->ready_stat, |
3a7d24841 ide: use ATA_* de... |
366 |
ATA_BUSY | ATA_DRQ | ATA_ERR, |
74af21cf4 ide: add __ide_wa... |
367 |
WAIT_CMD, &stat); |
1da177e4c Linux-2.6.12-rc2 |
368 369 |
SELECT_MASK(drive, 0); |
1da177e4c Linux-2.6.12-rc2 |
370 371 372 373 |
if (error) { (void) ide_dump_status(drive, "set_drive_speed_status", stat); return error; } |
c4199930b ide-iops: only cl... |
374 375 376 377 |
if (speed >= XFER_SW_DMA_0) { id[ATA_ID_UDMA_MODES] &= ~0xFF00; id[ATA_ID_MWDMA_MODES] &= ~0x0700; id[ATA_ID_SWDMA_MODES] &= ~0x0700; |
74638c848 ide: add support ... |
378 379 380 381 |
if (ata_id_is_cfa(id)) id[ATA_ID_CFA_MODES] &= ~0x0E00; } else if (ata_id_is_cfa(id)) id[ATA_ID_CFA_MODES] &= ~0x01C0; |
1da177e4c Linux-2.6.12-rc2 |
382 |
|
89613e667 ide: don't set PI... |
383 |
skip: |
1da177e4c Linux-2.6.12-rc2 |
384 |
#ifdef CONFIG_BLK_DEV_IDEDMA |
97100fc81 ide: add device f... |
385 |
if (speed >= XFER_SW_DMA_0 && (drive->dev_flags & IDE_DFLAG_USING_DMA)) |
5e37bdc08 ide: add struct i... |
386 387 |
hwif->dma_ops->dma_host_set(drive, 1); else if (hwif->dma_ops) /* check if host supports DMA */ |
4a546e046 ide: remove ->ide... |
388 |
ide_dma_off_quietly(drive); |
1da177e4c Linux-2.6.12-rc2 |
389 |
#endif |
4dde4492d ide: make drive->... |
390 391 392 |
if (speed >= XFER_UDMA_0) { i = 1 << (speed - XFER_UDMA_0); id[ATA_ID_UDMA_MODES] |= (i << 8 | i); |
74638c848 ide: add support ... |
393 394 395 |
} else if (ata_id_is_cfa(id) && speed >= XFER_MW_DMA_3) { i = speed - XFER_MW_DMA_2; id[ATA_ID_CFA_MODES] |= i << 9; |
4dde4492d ide: make drive->... |
396 397 398 399 400 401 |
} else if (speed >= XFER_MW_DMA_0) { i = 1 << (speed - XFER_MW_DMA_0); id[ATA_ID_MWDMA_MODES] |= (i << 8 | i); } else if (speed >= XFER_SW_DMA_0) { i = 1 << (speed - XFER_SW_DMA_0); id[ATA_ID_SWDMA_MODES] |= (i << 8 | i); |
74638c848 ide: add support ... |
402 403 404 |
} else if (ata_id_is_cfa(id) && speed >= XFER_PIO_5) { i = speed - XFER_PIO_4; id[ATA_ID_CFA_MODES] |= i << 6; |
1da177e4c Linux-2.6.12-rc2 |
405 |
} |
4dde4492d ide: make drive->... |
406 |
|
1da177e4c Linux-2.6.12-rc2 |
407 408 409 410 411 |
if (!drive->init_speed) drive->init_speed = speed; drive->current_speed = speed; return error; } |
1da177e4c Linux-2.6.12-rc2 |
412 413 414 415 416 417 418 419 420 |
/* * This should get invoked any time we exit the driver to * wait for an interrupt response from a drive. handler() points * at the appropriate code to handle the next interrupt, and a * timer is started to prevent us from waiting forever in case * something goes wrong (see the ide_timer_expiry() handler later on). * * See also ide_execute_command */ |
327fa1c29 ide: move error h... |
421 |
void __ide_set_handler(ide_drive_t *drive, ide_handler_t *handler, |
60c0cd02b ide: set hwif->ex... |
422 |
unsigned int timeout) |
1da177e4c Linux-2.6.12-rc2 |
423 |
{ |
b65fac32c ide: merge ide_hw... |
424 425 426 427 |
ide_hwif_t *hwif = drive->hwif; BUG_ON(hwif->handler); hwif->handler = handler; |
b65fac32c ide: merge ide_hw... |
428 429 430 |
hwif->timer.expires = jiffies + timeout; hwif->req_gen_timer = hwif->req_gen; add_timer(&hwif->timer); |
1da177e4c Linux-2.6.12-rc2 |
431 |
} |
60c0cd02b ide: set hwif->ex... |
432 433 |
void ide_set_handler(ide_drive_t *drive, ide_handler_t *handler, unsigned int timeout) |
1da177e4c Linux-2.6.12-rc2 |
434 |
{ |
b65fac32c ide: merge ide_hw... |
435 |
ide_hwif_t *hwif = drive->hwif; |
1da177e4c Linux-2.6.12-rc2 |
436 |
unsigned long flags; |
2a2ca6a96 ide: replace the ... |
437 |
|
b65fac32c ide: merge ide_hw... |
438 |
spin_lock_irqsave(&hwif->lock, flags); |
60c0cd02b ide: set hwif->ex... |
439 |
__ide_set_handler(drive, handler, timeout); |
b65fac32c ide: merge ide_hw... |
440 |
spin_unlock_irqrestore(&hwif->lock, flags); |
1da177e4c Linux-2.6.12-rc2 |
441 |
} |
1da177e4c Linux-2.6.12-rc2 |
442 |
EXPORT_SYMBOL(ide_set_handler); |
122f06f8b ide: checkpatch.p... |
443 |
|
1da177e4c Linux-2.6.12-rc2 |
444 445 446 |
/** * ide_execute_command - execute an IDE command * @drive: IDE drive to issue the command against |
35b5d0be3 ide: remove ide_e... |
447 |
* @cmd: command |
1da177e4c Linux-2.6.12-rc2 |
448 449 |
* @handler: handler for next phase * @timeout: timeout for command |
1da177e4c Linux-2.6.12-rc2 |
450 451 |
* * Helper function to issue an IDE command. This handles the |
122f06f8b ide: checkpatch.p... |
452 |
* atomicity requirements, command timing and ensures that the |
1da177e4c Linux-2.6.12-rc2 |
453 454 455 |
* handler and IRQ setup do not race. All IDE command kick off * should go via this function or do equivalent locking. */ |
cd2a2d969 ide: remove task_... |
456 |
|
35b5d0be3 ide: remove ide_e... |
457 458 |
void ide_execute_command(ide_drive_t *drive, struct ide_cmd *cmd, ide_handler_t *handler, unsigned timeout) |
1da177e4c Linux-2.6.12-rc2 |
459 |
{ |
2a2ca6a96 ide: replace the ... |
460 |
ide_hwif_t *hwif = drive->hwif; |
1da177e4c Linux-2.6.12-rc2 |
461 |
unsigned long flags; |
629f944bb ide: use __ide_se... |
462 |
|
b65fac32c ide: merge ide_hw... |
463 |
spin_lock_irqsave(&hwif->lock, flags); |
35b5d0be3 ide: remove ide_e... |
464 465 466 467 468 |
if ((cmd->protocol != ATAPI_PROT_DMA && cmd->protocol != ATAPI_PROT_PIO) || (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT)) __ide_set_handler(drive, handler, timeout); hwif->tp_ops->exec_command(hwif, cmd->tf.command); |
629f944bb ide: use __ide_se... |
469 470 471 472 473 474 |
/* * Drive takes 400nS to respond, we must avoid the IRQ being * serviced before that. * * FIXME: we could skip this delay with care on non shared devices */ |
1da177e4c Linux-2.6.12-rc2 |
475 |
ndelay(400); |
b65fac32c ide: merge ide_hw... |
476 |
spin_unlock_irqrestore(&hwif->lock, flags); |
1da177e4c Linux-2.6.12-rc2 |
477 |
} |
1da177e4c Linux-2.6.12-rc2 |
478 |
|
1da177e4c Linux-2.6.12-rc2 |
479 480 |
/* * ide_wait_not_busy() waits for the currently selected device on the hwif |
9d501529b ide: make probe_h... |
481 |
* to report a non-busy status, see comments in ide_probe_port(). |
1da177e4c Linux-2.6.12-rc2 |
482 483 484 485 |
*/ int ide_wait_not_busy(ide_hwif_t *hwif, unsigned long timeout) { u8 stat = 0; |
122f06f8b ide: checkpatch.p... |
486 |
while (timeout--) { |
1da177e4c Linux-2.6.12-rc2 |
487 488 489 490 491 |
/* * Turn this into a schedule() sleep once I'm sure * about locking issues (2.5 work ?). */ mdelay(1); |
374e042c3 ide: add struct i... |
492 |
stat = hwif->tp_ops->read_status(hwif); |
3a7d24841 ide: use ATA_* de... |
493 |
if ((stat & ATA_BUSY) == 0) |
1da177e4c Linux-2.6.12-rc2 |
494 495 496 497 498 499 500 501 |
return 0; /* * Assume a value of 0xff means nothing is connected to * the interface and it doesn't implement the pull-down * resistor on D7. */ if (stat == 0xff) return -ENODEV; |
6842f8c8d [PATCH] solve fal... |
502 |
touch_softlockup_watchdog(); |
1e86240f3 [PATCH] IDE: Touc... |
503 |
touch_nmi_watchdog(); |
1da177e4c Linux-2.6.12-rc2 |
504 505 506 |
} return -EBUSY; } |