summaryrefslogtreecommitdiff
path: root/drivers/ide/ide-probe.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-09-15 21:01:16 +0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-09-15 21:01:16 +0400
commit0cb583fd2862f19ea88b02eb307d11c09e51e2f8 (patch)
tree740769ab145ed72af4d00ea8e4d55ebcef337fce /drivers/ide/ide-probe.c
parent723e9db7a46e328527cc3da2b478b831184fe828 (diff)
parenta2d10568fd3965fffeb29a3a6f29966dd3801727 (diff)
downloadlinux-0cb583fd2862f19ea88b02eb307d11c09e51e2f8.tar.xz
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/ide-next-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/ide-next-2.6: ide: fixup for fujitsu disk ide: convert to ->proc_fops at91_ide: remove headers specific for at91sam9263 IDE: palm_bk3710: convert clock usage after clkdev conversion ide: fix races in handling of user-space SET XFER commands ide: allow ide_dev_read_id() to be called from the IRQ context ide: ide-taskfile.c fix style problems drivers/ide/ide-cd.c: Use DIV_ROUND_CLOSEST ide-tape: fix handling of postponed rqs ide-tape: convert to ide_debug_log macro ide-tape: fix debug call ide: Fix annoying warning in ide_pio_bytes(). IDE: Save a call to PageHighMem()
Diffstat (limited to 'drivers/ide/ide-probe.c')
-rw-r--r--drivers/ide/ide-probe.c31
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)
* @drive: drive to identify
* @cmd: command to use
* @id: buffer for IDENTIFY data
+ * @irq_ctx: flag set when called from the IRQ context
*
* Sends an ATA(PI) IDENTIFY request to a drive and waits for a response.
*
@@ -246,7 +247,7 @@ static void do_identify(ide_drive_t *drive, u8 cmd, u16 *id)
* 2 device aborted the command (refused to identify itself)
*/
-int ide_dev_read_id(ide_drive_t *drive, u8 cmd, u16 *id)
+int ide_dev_read_id(ide_drive_t *drive, u8 cmd, u16 *id, int irq_ctx)
{
ide_hwif_t *hwif = drive->hwif;
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)
tp_ops->write_devctl(hwif, ATA_NIEN | ATA_DEVCTL_OBS);
/* take a deep breath */
- msleep(50);
+ if (irq_ctx)
+ mdelay(50);
+ else
+ msleep(50);
if (io_ports->ctl_addr &&
(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)
timeout = ((cmd == ATA_CMD_ID_ATA) ? WAIT_WORSTCASE : WAIT_PIDENTIFY) / 2;
- if (ide_busy_sleep(drive, timeout, use_altstatus))
- return 1;
-
/* wait for IRQ and ATA_DRQ */
- msleep(50);
- s = tp_ops->read_status(hwif);
+ if (irq_ctx) {
+ rc = __ide_wait_stat(drive, ATA_DRQ, BAD_R_STAT, timeout, &s);
+ if (rc)
+ return 1;
+ } else {
+ rc = ide_busy_sleep(drive, timeout, use_altstatus);
+ if (rc)
+ return 1;
+
+ msleep(50);
+ s = tp_ops->read_status(hwif);
+ }
if (OK_STAT(s, ATA_DRQ, BAD_R_STAT)) {
/* drive returned ID */
@@ -406,10 +417,10 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
if (OK_STAT(stat, ATA_DRDY, ATA_BUSY) ||
present || cmd == ATA_CMD_ID_ATAPI) {
- rc = ide_dev_read_id(drive, cmd, id);
+ rc = ide_dev_read_id(drive, cmd, id, 0);
if (rc)
/* failed: try again */
- rc = ide_dev_read_id(drive, cmd, id);
+ rc = ide_dev_read_id(drive, cmd, id, 0);
stat = tp_ops->read_status(hwif);
@@ -424,7 +435,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
msleep(50);
tp_ops->exec_command(hwif, ATA_CMD_DEV_RESET);
(void)ide_busy_sleep(drive, WAIT_WORSTCASE, 0);
- rc = ide_dev_read_id(drive, cmd, id);
+ rc = ide_dev_read_id(drive, cmd, id, 0);
}
/* ensure drive IRQ is clear */