Blame view
drivers/ide/ide-iops.c
13.7 KB
457c89965
|
1 |
// SPDX-License-Identifier: GPL-2.0-only |
1da177e4c
|
2 |
/* |
1da177e4c
|
3 |
* Copyright (C) 2000-2002 Andre Hedrick <andre@linux-ide.org> |
ccd32e221
|
4 |
* Copyright (C) 2003 Red Hat |
1da177e4c
|
5 6 |
* */ |
1da177e4c
|
7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
#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
|
21 22 |
#include <linux/ide.h> #include <linux/bitops.h> |
1e86240f3
|
23 |
#include <linux/nmi.h> |
1da177e4c
|
24 25 26 |
#include <asm/byteorder.h> #include <asm/irq.h> |
7c0f6ba68
|
27 |
#include <linux/uaccess.h> |
1da177e4c
|
28 |
#include <asm/io.h> |
ed4af48fd
|
29 |
void SELECT_MASK(ide_drive_t *drive, int mask) |
1da177e4c
|
30 |
{ |
ac95beedf
|
31 32 33 34 |
const struct ide_port_ops *port_ops = drive->hwif->port_ops; if (port_ops && port_ops->maskproc) port_ops->maskproc(drive, mask); |
1da177e4c
|
35 |
} |
92eb43800
|
36 37 |
u8 ide_read_error(ide_drive_t *drive) { |
3153c26b5
|
38 |
struct ide_taskfile tf; |
92eb43800
|
39 |
|
3153c26b5
|
40 |
drive->hwif->tp_ops->tf_read(drive, &tf, IDE_VALID_ERROR); |
92eb43800
|
41 |
|
3153c26b5
|
42 |
return tf.error; |
92eb43800
|
43 44 |
} EXPORT_SYMBOL_GPL(ide_read_error); |
4dde4492d
|
45 |
void ide_fix_driveid(u16 *id) |
1da177e4c
|
46 47 48 49 |
{ #ifndef __LITTLE_ENDIAN # ifdef __BIG_ENDIAN int i; |
5b90e9909
|
50 |
|
48fb2688a
|
51 |
for (i = 0; i < 256; i++) |
5b90e9909
|
52 |
id[i] = __le16_to_cpu(id[i]); |
1da177e4c
|
53 54 55 56 57 |
# else # error "Please fix <asm/byteorder.h>" # endif #endif } |
01745112d
|
58 59 60 61 |
/* * 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
|
62 |
* returned by the ATA_CMD_ID_ATA[PI] commands. |
01745112d
|
63 |
*/ |
122f06f8b
|
64 |
void ide_fixstring(u8 *s, const int bytecount, const int byteswap) |
1da177e4c
|
65 |
{ |
1a7809e34
|
66 |
u8 *p, *end = &s[bytecount & ~1]; /* bytecount must be even */ |
1da177e4c
|
67 68 69 |
if (byteswap) { /* convert from big-endian to host byte order */ |
1a7809e34
|
70 71 |
for (p = s ; p != end ; p += 2) be16_to_cpus((u16 *) p); |
1da177e4c
|
72 |
} |
1a7809e34
|
73 |
|
1da177e4c
|
74 |
/* strip leading blanks */ |
1a7809e34
|
75 |
p = s; |
1da177e4c
|
76 77 78 79 80 81 82 83 84 85 86 |
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
|
87 |
EXPORT_SYMBOL(ide_fixstring); |
1da177e4c
|
88 |
/* |
1da177e4c
|
89 90 91 |
* 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
|
92 |
* cases return error -- caller may then invoke ide_error(). |
1da177e4c
|
93 94 95 96 97 98 |
* * 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
|
99 100 |
int __ide_wait_stat(ide_drive_t *drive, u8 good, u8 bad, unsigned long timeout, u8 *rstat) |
1da177e4c
|
101 |
{ |
b73c7ee25
|
102 |
ide_hwif_t *hwif = drive->hwif; |
374e042c3
|
103 |
const struct ide_tp_ops *tp_ops = hwif->tp_ops; |
1da177e4c
|
104 |
unsigned long flags; |
47b82e881
|
105 |
bool irqs_threaded = force_irqthreads; |
74af21cf4
|
106 107 |
int i; u8 stat; |
1da177e4c
|
108 109 |
udelay(1); /* spec allows drive 400ns to assert "BUSY" */ |
374e042c3
|
110 |
stat = tp_ops->read_status(hwif); |
c47137a99
|
111 |
|
3a7d24841
|
112 |
if (stat & ATA_BUSY) { |
47b82e881
|
113 114 115 116 |
if (!irqs_threaded) { local_save_flags(flags); local_irq_enable_in_hardirq(); } |
1da177e4c
|
117 |
timeout += jiffies; |
3a7d24841
|
118 |
while ((stat = tp_ops->read_status(hwif)) & ATA_BUSY) { |
1da177e4c
|
119 120 121 122 123 124 |
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
|
125 |
stat = tp_ops->read_status(hwif); |
3a7d24841
|
126 |
if ((stat & ATA_BUSY) == 0) |
1da177e4c
|
127 |
break; |
47b82e881
|
128 129 |
if (!irqs_threaded) local_irq_restore(flags); |
74af21cf4
|
130 131 |
*rstat = stat; return -EBUSY; |
1da177e4c
|
132 133 |
} } |
47b82e881
|
134 135 |
if (!irqs_threaded) local_irq_restore(flags); |
1da177e4c
|
136 137 138 139 140 141 142 143 144 145 |
} /* * 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
|
146 |
stat = tp_ops->read_status(hwif); |
c47137a99
|
147 148 |
if (OK_STAT(stat, good, bad)) { |
74af21cf4
|
149 |
*rstat = stat; |
1da177e4c
|
150 |
return 0; |
74af21cf4
|
151 |
} |
1da177e4c
|
152 |
} |
74af21cf4
|
153 154 155 156 157 158 159 160 161 |
*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
|
162 163 |
int ide_wait_stat(ide_startstop_t *startstop, ide_drive_t *drive, u8 good, u8 bad, unsigned long timeout) |
74af21cf4
|
164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 |
{ 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
|
182 |
} |
1da177e4c
|
183 |
EXPORT_SYMBOL(ide_wait_stat); |
a5b7e70d7
|
184 185 186 |
/** * ide_in_drive_list - look for drive in black/white list * @id: drive identifier |
4dde4492d
|
187 |
* @table: list to inspect |
a5b7e70d7
|
188 189 190 191 |
* * Look for a drive in the blacklist and the whitelist tables * Returns 1 if the drive is found in the table. */ |
4dde4492d
|
192 |
int ide_in_drive_list(u16 *id, const struct drive_list_entry *table) |
a5b7e70d7
|
193 |
{ |
4dde4492d
|
194 195 196 197 |
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
|
198 199 200 |
return 1; return 0; } |
b0244a004
|
201 |
EXPORT_SYMBOL_GPL(ide_in_drive_list); |
a5b7e70d7
|
202 203 |
/* * Early UDMA66 devices don't set bit14 to 1, only bit13 is valid. |
8588a2b73
|
204 |
* Some optical devices with the buggy firmwares have the same problem. |
a5b7e70d7
|
205 206 207 |
*/ static const struct drive_list_entry ivb_list[] = { { "QUANTUM FIREBALLlct10 05" , "A03.0900" }, |
ba9413bd2
|
208 |
{ "QUANTUM FIREBALLlct20 30" , "APL.0900" }, |
8588a2b73
|
209 |
{ "TSSTcorp CDDVDW SH-S202J" , "SB00" }, |
e97564f36
|
210 211 212 |
{ "TSSTcorp CDDVDW SH-S202J" , "SB01" }, { "TSSTcorp CDDVDW SH-S202N" , "SB00" }, { "TSSTcorp CDDVDW SH-S202N" , "SB01" }, |
3ced5c49b
|
213 214 |
{ "TSSTcorp CDDVDW SH-S202H" , "SB00" }, { "TSSTcorp CDDVDW SH-S202H" , "SB01" }, |
c7b997b37
|
215 |
{ "SAMSUNG SP0822N" , "WA100-10" }, |
a5b7e70d7
|
216 217 |
{ NULL , NULL } }; |
1da177e4c
|
218 219 220 221 |
/* * All hosts that use the 80c ribbon must use! * The name is derived from upper byte of word 93 and the 80c ribbon. */ |
122f06f8b
|
222 |
u8 eighty_ninty_three(ide_drive_t *drive) |
1da177e4c
|
223 |
{ |
7f8f48af0
|
224 |
ide_hwif_t *hwif = drive->hwif; |
4dde4492d
|
225 |
u16 *id = drive->id; |
a5b7e70d7
|
226 |
int ivb = ide_in_drive_list(id, ivb_list); |
7f8f48af0
|
227 |
|
76937fa76
|
228 |
if (hwif->cbl == ATA_CBL_SATA || hwif->cbl == ATA_CBL_PATA40_SHORT) |
49521f97c
|
229 |
return 1; |
a5b7e70d7
|
230 231 232 233 |
if (ivb) printk(KERN_DEBUG "%s: skipping word 93 validity check ", drive->name); |
367d7e78d
|
234 |
if (ata_id_is_sata(id) && !ivb) |
b98f8803c
|
235 |
return 1; |
a5b7e70d7
|
236 |
if (hwif->cbl != ATA_CBL_PATA80 && !ivb) |
7f8f48af0
|
237 |
goto no_80w; |
1a1276e7b
|
238 |
|
f68d9320c
|
239 240 |
/* * FIXME: |
f367bed00
|
241 |
* - change master/slave IDENTIFY order |
a5b7e70d7
|
242 |
* - force bit13 (80c cable present) check also for !ivb devices |
f68d9320c
|
243 244 |
* (unless the slave device is pre-ATA3) */ |
8369d5fa6
|
245 |
if (id[ATA_ID_HW_CONFIG] & 0x4000) |
7f8f48af0
|
246 |
return 1; |
8369d5fa6
|
247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 |
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
|
263 |
no_80w: |
97100fc81
|
264 |
if (drive->dev_flags & IDE_DFLAG_UDMA33_WARNED) |
7f8f48af0
|
265 266 267 268 269 |
return 0; printk(KERN_WARNING "%s: %s side 80-wire cable detection failed, " "limiting max speed to UDMA33 ", |
49521f97c
|
270 271 |
drive->name, hwif->cbl == ATA_CBL_PATA80 ? "drive" : "host"); |
7f8f48af0
|
272 |
|
97100fc81
|
273 |
drive->dev_flags |= IDE_DFLAG_UDMA33_WARNED; |
7f8f48af0
|
274 275 |
return 0; |
1da177e4c
|
276 |
} |
8bc1e5aa0
|
277 278 279 280 281 282 283 284 285 |
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
|
286 |
"FUJITSU MHZ2160BH G2", |
8bc1e5aa0
|
287 288 289 290 291 292 293 294 295 |
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
|
296 |
drive->dev_flags |= IDE_DFLAG_NIEN_QUIRK; |
8bc1e5aa0
|
297 298 |
return; } |
8bc1e5aa0
|
299 |
} |
8a4551340
|
300 |
int ide_driveid_update(ide_drive_t *drive) |
1da177e4c
|
301 |
{ |
4dde4492d
|
302 |
u16 *id; |
2ebe1d9ef
|
303 |
int rc; |
2f40c9b0b
|
304 305 306 307 |
id = kmalloc(SECTOR_SIZE, GFP_ATOMIC); if (id == NULL) return 0; |
1da177e4c
|
308 |
|
1da177e4c
|
309 |
SELECT_MASK(drive, 1); |
fa56d4cb4
|
310 |
rc = ide_dev_read_id(drive, ATA_CMD_ID_ATA, id, 1); |
2ebe1d9ef
|
311 |
SELECT_MASK(drive, 0); |
2f40c9b0b
|
312 |
|
2ebe1d9ef
|
313 |
if (rc) |
2f40c9b0b
|
314 |
goto out_err; |
f323b80dc
|
315 |
|
4dde4492d
|
316 317 318 |
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
|
319 |
drive->id[ATA_ID_CFA_MODES] = id[ATA_ID_CFA_MODES]; |
4dde4492d
|
320 321 322 |
/* anything more ? */ kfree(id); |
1da177e4c
|
323 |
return 1; |
2f40c9b0b
|
324 |
out_err: |
2f40c9b0b
|
325 326 327 328 329 |
if (rc == 2) printk(KERN_ERR "%s: %s: bad status ", drive->name, __func__); kfree(id); return 0; |
1da177e4c
|
330 |
} |
74af21cf4
|
331 |
int ide_config_drive_speed(ide_drive_t *drive, u8 speed) |
1da177e4c
|
332 |
{ |
74af21cf4
|
333 |
ide_hwif_t *hwif = drive->hwif; |
374e042c3
|
334 |
const struct ide_tp_ops *tp_ops = hwif->tp_ops; |
c9ff9e7b6
|
335 |
struct ide_taskfile tf; |
4dde4492d
|
336 |
u16 *id = drive->id, i; |
89613e667
|
337 |
int error = 0; |
1da177e4c
|
338 |
u8 stat; |
1da177e4c
|
339 |
#ifdef CONFIG_BLK_DEV_IDEDMA |
5e37bdc08
|
340 341 |
if (hwif->dma_ops) /* check if host supports DMA */ hwif->dma_ops->dma_host_set(drive, 0); |
1da177e4c
|
342 |
#endif |
89613e667
|
343 |
/* Skip setting PIO flow-control modes on pre-EIDE drives */ |
48fb2688a
|
344 |
if ((speed & 0xf8) == XFER_PIO_0 && ata_id_has_iordy(drive->id) == 0) |
89613e667
|
345 |
goto skip; |
1da177e4c
|
346 347 348 349 350 351 |
/* * 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
|
352 |
|
1da177e4c
|
353 |
udelay(1); |
fdd88f0af
|
354 |
tp_ops->dev_select(drive); |
e5403bff8
|
355 |
SELECT_MASK(drive, 1); |
1da177e4c
|
356 |
udelay(1); |
ecf3a31d2
|
357 |
tp_ops->write_devctl(hwif, ATA_NIEN | ATA_DEVCTL_OBS); |
59be2c80f
|
358 |
|
c9ff9e7b6
|
359 360 361 |
memset(&tf, 0, sizeof(tf)); tf.feature = SETFEATURES_XFER; tf.nsect = speed; |
59be2c80f
|
362 |
|
c9ff9e7b6
|
363 |
tp_ops->tf_load(drive, &tf, IDE_VALID_FEATURE | IDE_VALID_NSECT); |
59be2c80f
|
364 |
|
aaaade3f0
|
365 |
tp_ops->exec_command(hwif, ATA_CMD_SET_FEATURES); |
59be2c80f
|
366 |
|
734affdca
|
367 |
if (drive->dev_flags & IDE_DFLAG_NIEN_QUIRK) |
ecf3a31d2
|
368 |
tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS); |
1da177e4c
|
369 |
|
74af21cf4
|
370 |
error = __ide_wait_stat(drive, drive->ready_stat, |
3a7d24841
|
371 |
ATA_BUSY | ATA_DRQ | ATA_ERR, |
74af21cf4
|
372 |
WAIT_CMD, &stat); |
1da177e4c
|
373 374 |
SELECT_MASK(drive, 0); |
1da177e4c
|
375 376 377 378 |
if (error) { (void) ide_dump_status(drive, "set_drive_speed_status", stat); return error; } |
c4199930b
|
379 380 381 382 |
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
|
383 384 385 386 |
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
|
387 |
|
89613e667
|
388 |
skip: |
1da177e4c
|
389 |
#ifdef CONFIG_BLK_DEV_IDEDMA |
97100fc81
|
390 |
if (speed >= XFER_SW_DMA_0 && (drive->dev_flags & IDE_DFLAG_USING_DMA)) |
5e37bdc08
|
391 392 |
hwif->dma_ops->dma_host_set(drive, 1); else if (hwif->dma_ops) /* check if host supports DMA */ |
4a546e046
|
393 |
ide_dma_off_quietly(drive); |
1da177e4c
|
394 |
#endif |
4dde4492d
|
395 396 397 |
if (speed >= XFER_UDMA_0) { i = 1 << (speed - XFER_UDMA_0); id[ATA_ID_UDMA_MODES] |= (i << 8 | i); |
74638c848
|
398 399 400 |
} 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
|
401 402 403 404 405 406 |
} 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
|
407 408 409 |
} else if (ata_id_is_cfa(id) && speed >= XFER_PIO_5) { i = speed - XFER_PIO_4; id[ATA_ID_CFA_MODES] |= i << 6; |
1da177e4c
|
410 |
} |
4dde4492d
|
411 |
|
1da177e4c
|
412 413 414 415 416 |
if (!drive->init_speed) drive->init_speed = speed; drive->current_speed = speed; return error; } |
1da177e4c
|
417 418 419 420 421 422 423 424 425 |
/* * 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
|
426 |
void __ide_set_handler(ide_drive_t *drive, ide_handler_t *handler, |
60c0cd02b
|
427 |
unsigned int timeout) |
1da177e4c
|
428 |
{ |
b65fac32c
|
429 430 431 432 |
ide_hwif_t *hwif = drive->hwif; BUG_ON(hwif->handler); hwif->handler = handler; |
b65fac32c
|
433 434 435 |
hwif->timer.expires = jiffies + timeout; hwif->req_gen_timer = hwif->req_gen; add_timer(&hwif->timer); |
1da177e4c
|
436 |
} |
60c0cd02b
|
437 438 |
void ide_set_handler(ide_drive_t *drive, ide_handler_t *handler, unsigned int timeout) |
1da177e4c
|
439 |
{ |
b65fac32c
|
440 |
ide_hwif_t *hwif = drive->hwif; |
1da177e4c
|
441 |
unsigned long flags; |
2a2ca6a96
|
442 |
|
b65fac32c
|
443 |
spin_lock_irqsave(&hwif->lock, flags); |
60c0cd02b
|
444 |
__ide_set_handler(drive, handler, timeout); |
b65fac32c
|
445 |
spin_unlock_irqrestore(&hwif->lock, flags); |
1da177e4c
|
446 |
} |
1da177e4c
|
447 |
EXPORT_SYMBOL(ide_set_handler); |
122f06f8b
|
448 |
|
1da177e4c
|
449 450 451 |
/** * ide_execute_command - execute an IDE command * @drive: IDE drive to issue the command against |
35b5d0be3
|
452 |
* @cmd: command |
1da177e4c
|
453 454 |
* @handler: handler for next phase * @timeout: timeout for command |
1da177e4c
|
455 456 |
* * Helper function to issue an IDE command. This handles the |
122f06f8b
|
457 |
* atomicity requirements, command timing and ensures that the |
1da177e4c
|
458 459 460 |
* handler and IRQ setup do not race. All IDE command kick off * should go via this function or do equivalent locking. */ |
cd2a2d969
|
461 |
|
35b5d0be3
|
462 463 |
void ide_execute_command(ide_drive_t *drive, struct ide_cmd *cmd, ide_handler_t *handler, unsigned timeout) |
1da177e4c
|
464 |
{ |
2a2ca6a96
|
465 |
ide_hwif_t *hwif = drive->hwif; |
1da177e4c
|
466 |
unsigned long flags; |
629f944bb
|
467 |
|
b65fac32c
|
468 |
spin_lock_irqsave(&hwif->lock, flags); |
35b5d0be3
|
469 470 471 472 473 |
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
|
474 475 476 477 478 479 |
/* * 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
|
480 |
ndelay(400); |
b65fac32c
|
481 |
spin_unlock_irqrestore(&hwif->lock, flags); |
1da177e4c
|
482 |
} |
1da177e4c
|
483 |
|
1da177e4c
|
484 485 |
/* * ide_wait_not_busy() waits for the currently selected device on the hwif |
9d501529b
|
486 |
* to report a non-busy status, see comments in ide_probe_port(). |
1da177e4c
|
487 488 489 490 |
*/ int ide_wait_not_busy(ide_hwif_t *hwif, unsigned long timeout) { u8 stat = 0; |
122f06f8b
|
491 |
while (timeout--) { |
1da177e4c
|
492 493 494 495 496 |
/* * Turn this into a schedule() sleep once I'm sure * about locking issues (2.5 work ?). */ mdelay(1); |
374e042c3
|
497 |
stat = hwif->tp_ops->read_status(hwif); |
3a7d24841
|
498 |
if ((stat & ATA_BUSY) == 0) |
1da177e4c
|
499 500 501 502 503 504 505 506 |
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; |
1e86240f3
|
507 |
touch_nmi_watchdog(); |
1da177e4c
|
508 509 510 |
} return -EBUSY; } |