diff options
Diffstat (limited to 'drivers/ide/ide-probe.c')
-rw-r--r-- | drivers/ide/ide-probe.c | 31 |
1 files changed, 21 insertions, 10 deletions
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 1bb106f6221a..8de442cbee94 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c | |||
@@ -238,6 +238,7 @@ static void do_identify(ide_drive_t *drive, u8 cmd, u16 *id) | |||
238 | * @drive: drive to identify | 238 | * @drive: drive to identify |
239 | * @cmd: command to use | 239 | * @cmd: command to use |
240 | * @id: buffer for IDENTIFY data | 240 | * @id: buffer for IDENTIFY data |
241 | * @irq_ctx: flag set when called from the IRQ context | ||
241 | * | 242 | * |
242 | * Sends an ATA(PI) IDENTIFY request to a drive and waits for a response. | 243 | * Sends an ATA(PI) IDENTIFY request to a drive and waits for a response. |
243 | * | 244 | * |
@@ -246,7 +247,7 @@ static void do_identify(ide_drive_t *drive, u8 cmd, u16 *id) | |||
246 | * 2 device aborted the command (refused to identify itself) | 247 | * 2 device aborted the command (refused to identify itself) |
247 | */ | 248 | */ |
248 | 249 | ||
249 | int ide_dev_read_id(ide_drive_t *drive, u8 cmd, u16 *id) | 250 | int ide_dev_read_id(ide_drive_t *drive, u8 cmd, u16 *id, int irq_ctx) |
250 | { | 251 | { |
251 | ide_hwif_t *hwif = drive->hwif; | 252 | ide_hwif_t *hwif = drive->hwif; |
252 | struct ide_io_ports *io_ports = &hwif->io_ports; | 253 | struct ide_io_ports *io_ports = &hwif->io_ports; |
@@ -263,7 +264,10 @@ int ide_dev_read_id(ide_drive_t *drive, u8 cmd, u16 *id) | |||
263 | tp_ops->write_devctl(hwif, ATA_NIEN | ATA_DEVCTL_OBS); | 264 | tp_ops->write_devctl(hwif, ATA_NIEN | ATA_DEVCTL_OBS); |
264 | 265 | ||
265 | /* take a deep breath */ | 266 | /* take a deep breath */ |
266 | msleep(50); | 267 | if (irq_ctx) |
268 | mdelay(50); | ||
269 | else | ||
270 | msleep(50); | ||
267 | 271 | ||
268 | if (io_ports->ctl_addr && | 272 | if (io_ports->ctl_addr && |
269 | (hwif->host_flags & IDE_HFLAG_BROKEN_ALTSTATUS) == 0) { | 273 | (hwif->host_flags & IDE_HFLAG_BROKEN_ALTSTATUS) == 0) { |
@@ -295,12 +299,19 @@ int ide_dev_read_id(ide_drive_t *drive, u8 cmd, u16 *id) | |||
295 | 299 | ||
296 | timeout = ((cmd == ATA_CMD_ID_ATA) ? WAIT_WORSTCASE : WAIT_PIDENTIFY) / 2; | 300 | timeout = ((cmd == ATA_CMD_ID_ATA) ? WAIT_WORSTCASE : WAIT_PIDENTIFY) / 2; |
297 | 301 | ||
298 | if (ide_busy_sleep(drive, timeout, use_altstatus)) | ||
299 | return 1; | ||
300 | |||
301 | /* wait for IRQ and ATA_DRQ */ | 302 | /* wait for IRQ and ATA_DRQ */ |
302 | msleep(50); | 303 | if (irq_ctx) { |
303 | s = tp_ops->read_status(hwif); | 304 | rc = __ide_wait_stat(drive, ATA_DRQ, BAD_R_STAT, timeout, &s); |
305 | if (rc) | ||
306 | return 1; | ||
307 | } else { | ||
308 | rc = ide_busy_sleep(drive, timeout, use_altstatus); | ||
309 | if (rc) | ||
310 | return 1; | ||
311 | |||
312 | msleep(50); | ||
313 | s = tp_ops->read_status(hwif); | ||
314 | } | ||
304 | 315 | ||
305 | if (OK_STAT(s, ATA_DRQ, BAD_R_STAT)) { | 316 | if (OK_STAT(s, ATA_DRQ, BAD_R_STAT)) { |
306 | /* drive returned ID */ | 317 | /* drive returned ID */ |
@@ -406,10 +417,10 @@ static int do_probe (ide_drive_t *drive, u8 cmd) | |||
406 | 417 | ||
407 | if (OK_STAT(stat, ATA_DRDY, ATA_BUSY) || | 418 | if (OK_STAT(stat, ATA_DRDY, ATA_BUSY) || |
408 | present || cmd == ATA_CMD_ID_ATAPI) { | 419 | present || cmd == ATA_CMD_ID_ATAPI) { |
409 | rc = ide_dev_read_id(drive, cmd, id); | 420 | rc = ide_dev_read_id(drive, cmd, id, 0); |
410 | if (rc) | 421 | if (rc) |
411 | /* failed: try again */ | 422 | /* failed: try again */ |
412 | rc = ide_dev_read_id(drive, cmd, id); | 423 | rc = ide_dev_read_id(drive, cmd, id, 0); |
413 | 424 | ||
414 | stat = tp_ops->read_status(hwif); | 425 | stat = tp_ops->read_status(hwif); |
415 | 426 | ||
@@ -424,7 +435,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd) | |||
424 | msleep(50); | 435 | msleep(50); |
425 | tp_ops->exec_command(hwif, ATA_CMD_DEV_RESET); | 436 | tp_ops->exec_command(hwif, ATA_CMD_DEV_RESET); |
426 | (void)ide_busy_sleep(drive, WAIT_WORSTCASE, 0); | 437 | (void)ide_busy_sleep(drive, WAIT_WORSTCASE, 0); |
427 | rc = ide_dev_read_id(drive, cmd, id); | 438 | rc = ide_dev_read_id(drive, cmd, id, 0); |
428 | } | 439 | } |
429 | 440 | ||
430 | /* ensure drive IRQ is clear */ | 441 | /* ensure drive IRQ is clear */ |