|
@@ -238,6 +238,7 @@ static void do_identify(ide_drive_t *drive, u8 cmd, u16 *id)
|
|
* @drive: drive to identify
|
|
* @drive: drive to identify
|
|
* @cmd: command to use
|
|
* @cmd: command to use
|
|
* @id: buffer for IDENTIFY data
|
|
* @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.
|
|
* 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)
|
|
* 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;
|
|
ide_hwif_t *hwif = drive->hwif;
|
|
struct ide_io_ports *io_ports = &hwif->io_ports;
|
|
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);
|
|
tp_ops->write_devctl(hwif, ATA_NIEN | ATA_DEVCTL_OBS);
|
|
|
|
|
|
/* take a deep breath */
|
|
/* take a deep breath */
|
|
- msleep(50);
|
|
|
|
|
|
+ if (irq_ctx)
|
|
|
|
+ mdelay(50);
|
|
|
|
+ else
|
|
|
|
+ msleep(50);
|
|
|
|
|
|
if (io_ports->ctl_addr &&
|
|
if (io_ports->ctl_addr &&
|
|
(hwif->host_flags & IDE_HFLAG_BROKEN_ALTSTATUS) == 0) {
|
|
(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;
|
|
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 */
|
|
/* 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)) {
|
|
if (OK_STAT(s, ATA_DRQ, BAD_R_STAT)) {
|
|
/* drive returned ID */
|
|
/* 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) ||
|
|
if (OK_STAT(stat, ATA_DRDY, ATA_BUSY) ||
|
|
present || cmd == ATA_CMD_ID_ATAPI) {
|
|
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)
|
|
if (rc)
|
|
/* failed: try again */
|
|
/* 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);
|
|
stat = tp_ops->read_status(hwif);
|
|
|
|
|
|
@@ -424,7 +435,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
|
|
msleep(50);
|
|
msleep(50);
|
|
tp_ops->exec_command(hwif, ATA_CMD_DEV_RESET);
|
|
tp_ops->exec_command(hwif, ATA_CMD_DEV_RESET);
|
|
(void)ide_busy_sleep(drive, WAIT_WORSTCASE, 0);
|
|
(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 */
|
|
/* ensure drive IRQ is clear */
|