aboutsummaryrefslogtreecommitdiff
path: root/drivers/ide
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ide')
-rw-r--r--drivers/ide/Kconfig6
-rw-r--r--drivers/ide/ide-cd.c9
-rw-r--r--drivers/ide/ide-io.c38
-rw-r--r--drivers/ide/ide-iops.c13
-rw-r--r--drivers/ide/ide.c39
-rw-r--r--drivers/ide/pci/pdc202xx_new.c3
6 files changed, 84 insertions, 24 deletions
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig
index 8f1fd017679..ca2e4f830c3 100644
--- a/drivers/ide/Kconfig
+++ b/drivers/ide/Kconfig
@@ -103,8 +103,10 @@ config BLK_DEV_IDE_SATA
---help---
There are two drivers for Serial ATA controllers.
- The main driver, "libata", exists inside the SCSI subsystem
- and supports most modern SATA controllers.
+ The main driver, "libata", uses the SCSI subsystem
+ and supports most modern SATA controllers. In order to use it
+ you may take a look at "Serial ATA (prod) and Parallel ATA
+ (experimental) drivers".
The IDE driver (which you are currently configuring) supports
a few first-generation SATA controllers.
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index 45a928c058c..638becda81c 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -735,6 +735,15 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
cdrom_saw_media_change (drive);
/*printk("%s: media changed\n",drive->name);*/
return 0;
+ } else if ((sense_key == ILLEGAL_REQUEST) &&
+ (rq->cmd[0] == GPCMD_START_STOP_UNIT)) {
+ /*
+ * Don't print error message for this condition--
+ * SFF8090i indicates that 5/24/00 is the correct
+ * response to a request to close the tray if the
+ * drive doesn't have that capability.
+ * cdrom_log_sense() knows this!
+ */
} else if (!(rq->cmd_flags & REQ_QUIET)) {
/* Otherwise, print an error. */
ide_dump_status(drive, "packet command error", stat);
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
index c193553f6fe..8670112f1d3 100644
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -519,21 +519,24 @@ static ide_startstop_t ide_ata_error(ide_drive_t *drive, struct request *rq, u8
if ((stat & DRQ_STAT) && rq_data_dir(rq) == READ && hwif->err_stops_fifo == 0)
try_to_flush_leftover_data(drive);
+ if (rq->errors >= ERROR_MAX || blk_noretry_request(rq)) {
+ ide_kill_rq(drive, rq);
+ return ide_stopped;
+ }
+
if (hwif->INB(IDE_STATUS_REG) & (BUSY_STAT|DRQ_STAT))
- /* force an abort */
- hwif->OUTB(WIN_IDLEIMMEDIATE, IDE_COMMAND_REG);
+ rq->errors |= ERROR_RESET;
- if (rq->errors >= ERROR_MAX || blk_noretry_request(rq))
- ide_kill_rq(drive, rq);
- else {
- if ((rq->errors & ERROR_RESET) == ERROR_RESET) {
- ++rq->errors;
- return ide_do_reset(drive);
- }
- if ((rq->errors & ERROR_RECAL) == ERROR_RECAL)
- drive->special.b.recalibrate = 1;
+ if ((rq->errors & ERROR_RESET) == ERROR_RESET) {
++rq->errors;
+ return ide_do_reset(drive);
}
+
+ if ((rq->errors & ERROR_RECAL) == ERROR_RECAL)
+ drive->special.b.recalibrate = 1;
+
+ ++rq->errors;
+
return ide_stopped;
}
@@ -1025,6 +1028,13 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq)
if (!drive->special.all) {
ide_driver_t *drv;
+ /*
+ * We reset the drive so we need to issue a SETFEATURES.
+ * Do it _after_ do_special() restored device parameters.
+ */
+ if (drive->current_speed == 0xff)
+ ide_config_drive_speed(drive, drive->desired_speed);
+
if (rq->cmd_type == REQ_TYPE_ATA_CMD ||
rq->cmd_type == REQ_TYPE_ATA_TASK ||
rq->cmd_type == REQ_TYPE_ATA_TASKFILE)
@@ -1216,6 +1226,7 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq)
#endif
/* so that ide_timer_expiry knows what to do */
hwgroup->sleeping = 1;
+ hwgroup->req_gen_timer = hwgroup->req_gen;
mod_timer(&hwgroup->timer, sleep);
/* we purposely leave hwgroup->busy==1
* while sleeping */
@@ -1401,7 +1412,8 @@ void ide_timer_expiry (unsigned long data)
spin_lock_irqsave(&ide_lock, flags);
- if ((handler = hwgroup->handler) == NULL) {
+ if (((handler = hwgroup->handler) == NULL) ||
+ (hwgroup->req_gen != hwgroup->req_gen_timer)) {
/*
* Either a marginal timeout occurred
* (got the interrupt just as timer expired),
@@ -1429,6 +1441,7 @@ void ide_timer_expiry (unsigned long data)
if ((wait = expiry(drive)) > 0) {
/* reset timer */
hwgroup->timer.expires = jiffies + wait;
+ hwgroup->req_gen_timer = hwgroup->req_gen;
add_timer(&hwgroup->timer);
spin_unlock_irqrestore(&ide_lock, flags);
return;
@@ -1643,6 +1656,7 @@ irqreturn_t ide_intr (int irq, void *dev_id)
printk(KERN_ERR "%s: ide_intr: hwgroup->busy was 0 ??\n", drive->name);
}
hwgroup->handler = NULL;
+ hwgroup->req_gen++;
del_timer(&hwgroup->timer);
spin_unlock(&ide_lock);
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c
index bd513f5a232..3caa176b315 100644
--- a/drivers/ide/ide-iops.c
+++ b/drivers/ide/ide-iops.c
@@ -583,8 +583,12 @@ u8 eighty_ninty_three (ide_drive_t *drive)
if(!(drive->id->hw_config & 0x4000))
return 0;
#endif /* CONFIG_IDEDMA_IVB */
- if (!(drive->id->hw_config & 0x2000))
- return 0;
+ /*
+ * FIXME:
+ * - change master/slave IDENTIFY order
+ * - force bit13 (80c cable present) check
+ * (unless the slave device is pre-ATA3)
+ */
return 1;
}
@@ -885,6 +889,7 @@ static void __ide_set_handler (ide_drive_t *drive, ide_handler_t *handler,
hwgroup->handler = handler;
hwgroup->expiry = expiry;
hwgroup->timer.expires = jiffies + timeout;
+ hwgroup->req_gen_timer = hwgroup->req_gen;
add_timer(&hwgroup->timer);
}
@@ -925,6 +930,7 @@ void ide_execute_command(ide_drive_t *drive, task_ioreg_t cmd, ide_handler_t *ha
hwgroup->handler = handler;
hwgroup->expiry = expiry;
hwgroup->timer.expires = jiffies + timeout;
+ hwgroup->req_gen_timer = hwgroup->req_gen;
add_timer(&hwgroup->timer);
hwif->OUTBSYNC(drive, cmd, IDE_COMMAND_REG);
/* Drive takes 400nS to respond, we must avoid the IRQ being
@@ -1090,6 +1096,9 @@ static void pre_reset(ide_drive_t *drive)
if (HWIF(drive)->pre_reset != NULL)
HWIF(drive)->pre_reset(drive);
+ if (drive->current_speed != 0xff)
+ drive->desired_speed = drive->current_speed;
+ drive->current_speed = 0xff;
}
/*
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c
index 695610f0e3e..ae5bf2be6f5 100644
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -1124,17 +1124,40 @@ static int set_io_32bit(ide_drive_t *drive, int arg)
static int set_using_dma (ide_drive_t *drive, int arg)
{
#ifdef CONFIG_BLK_DEV_IDEDMA
+ ide_hwif_t *hwif = drive->hwif;
+ int err = -EPERM;
+
if (!drive->id || !(drive->id->capability & 1))
- return -EPERM;
- if (HWIF(drive)->ide_dma_check == NULL)
- return -EPERM;
+ goto out;
+
+ if (hwif->ide_dma_check == NULL)
+ goto out;
+
+ err = -EBUSY;
+ if (ide_spin_wait_hwgroup(drive))
+ goto out;
+ /*
+ * set ->busy flag, unlock and let it ride
+ */
+ hwif->hwgroup->busy = 1;
+ spin_unlock_irq(&ide_lock);
+
+ err = 0;
+
if (arg) {
- if (ide_set_dma(drive))
- return -EIO;
- if (HWIF(drive)->ide_dma_on(drive)) return -EIO;
+ if (ide_set_dma(drive) || hwif->ide_dma_on(drive))
+ err = -EIO;
} else
ide_dma_off(drive);
- return 0;
+
+ /*
+ * lock, clear ->busy flag and unlock before leaving
+ */
+ spin_lock_irq(&ide_lock);
+ hwif->hwgroup->busy = 0;
+ spin_unlock_irq(&ide_lock);
+out:
+ return err;
#else
return -EPERM;
#endif
@@ -1939,6 +1962,8 @@ static char *media_string(ide_drive_t *drive)
return "tape";
case ide_floppy:
return "floppy";
+ case ide_optical:
+ return "optical";
default:
return "UNKNOWN";
}
diff --git a/drivers/ide/pci/pdc202xx_new.c b/drivers/ide/pci/pdc202xx_new.c
index 6ceb25bc5a7..ace98929cc3 100644
--- a/drivers/ide/pci/pdc202xx_new.c
+++ b/drivers/ide/pci/pdc202xx_new.c
@@ -255,7 +255,7 @@ static int config_chipset_for_dma(ide_drive_t *drive)
printk(KERN_WARNING "%s reduced to Ultra33 mode.\n", drive->name);
}
- if (drive->media != ide_disk)
+ if (drive->media != ide_disk && drive->media != ide_cdrom)
return 0;
if (id->capability & 4) {
@@ -545,6 +545,7 @@ static void __devinit init_hwif_pdc202new(ide_hwif_t *hwif)
hwif->drives[0].autotune = hwif->drives[1].autotune = 1;
+ hwif->atapi_dma = 1;
hwif->ultra_mask = 0x7f;
hwif->mwdma_mask = 0x07;