diff -r -u -X dontdiff linux-2.6.9-vanilla/drivers/scsi/libata-core.c linux-2.6.9/drivers/scsi/libata-core.c --- linux-2.6.9-vanilla/drivers/scsi/libata-core.c 2004-10-18 16:53:06.000000000 -0500 +++ linux-2.6.9/drivers/scsi/libata-core.c 2004-11-24 11:01:40.000000000 -0600 @@ -2099,7 +2099,7 @@ } drv_stat = ata_wait_idle(ap); - if (!ata_ok(drv_stat)) { + if (drv_stat & (ATA_ERR | ATA_DF)) { ap->pio_task_state = PIO_ST_ERR; return; } @@ -2254,23 +2254,17 @@ * chk-status again. If still busy, fall back to * PIO_ST_POLL state. */ - status = ata_busy_wait(ap, ATA_BUSY, 5); - if (status & ATA_BUSY) { + status = ata_altstatus(ap) ; + if (!(status & ATA_DRQ)) { msleep(2); - status = ata_busy_wait(ap, ATA_BUSY, 10); - if (status & ATA_BUSY) { + status = ata_altstatus(ap) ; + if (!(status & ATA_DRQ)) { ap->pio_task_state = PIO_ST_POLL; ap->pio_task_timeout = jiffies + ATA_TMOUT_PIO; return; } } - /* handle BSY=0, DRQ=0 as error */ - if ((status & ATA_DRQ) == 0) { - ap->pio_task_state = PIO_ST_ERR; - return; - } - qc = ata_qc_from_tag(ap, ap->active_tag); assert(qc != NULL); @@ -2321,17 +2315,15 @@ case PIO_ST_TMOUT: case PIO_ST_ERR: ata_pio_error(ap); - break; + return ; } - if ((ap->pio_task_state != PIO_ST_IDLE) && - (ap->pio_task_state != PIO_ST_TMOUT) && - (ap->pio_task_state != PIO_ST_ERR)) { + if (ap->pio_task_state != PIO_ST_IDLE) { if (timeout) queue_delayed_work(ata_wq, &ap->pio_task, timeout); else - queue_work(ata_wq, &ap->pio_task); + queue_delayed_work(ata_wq, &ap->pio_task, 2); } } @@ -2624,7 +2616,7 @@ ata_qc_set_polling(qc); ata_tf_to_host_nolock(ap, &qc->tf); ap->pio_task_state = PIO_ST; - queue_work(ata_wq, &ap->pio_task); + queue_delayed_work(ata_wq, &ap->pio_task, 2); break; case ATA_PROT_ATAPI: