aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Dalecki <dalecki@evision-ventures.com>2002-04-22 00:13:03 -0700
committerLinus Torvalds <torvalds@home.transmeta.com>2002-04-22 00:13:03 -0700
commit45fbecb1147007167ea78399f165ceae775d86e7 (patch)
tree549ea5d36ce306f8ae939394866f6bbec46e0dd2
parent13f62bdbdbfc5b19b9083f6af8c83a3ad2ed70d1 (diff)
downloadhistory-45fbecb1147007167ea78399f165ceae775d86e7.tar.gz
[PATCH] 2.5.8 IDE 40v2.5.9
- Make the ide-cd driver usable again in DMA mode by adapting it to the TCQ related request handling changes and fixing some other minor stuff related to this. This patch is ugly like hell I know. Cleanup will follow separately. It was hard enough to make this going agian at all.
-rw-r--r--drivers/ide/ide-cd.c51
-rw-r--r--drivers/ide/ide-dma.c5
-rw-r--r--drivers/ide/ide-probe.c4
3 files changed, 51 insertions, 9 deletions
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index 2aebf927a1f13..29e0be7635c09 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -535,9 +535,9 @@ static void cdrom_queue_request_sense(ide_drive_t *drive,
/* stuff the sense request in front of our current request */
rq = &info->request_sense_request;
+ ide_init_drive_cmd(rq);
rq->cmd[0] = GPCMD_REQUEST_SENSE;
rq->cmd[4] = pc->buflen;
- ide_init_drive_cmd(rq);
rq->flags = REQ_SENSE;
/* FIXME --mdcki */
@@ -558,8 +558,10 @@ static void cdrom_end_request(ide_drive_t *drive, int uptodate)
if ((rq->flags & REQ_CMD) && !rq->current_nr_sectors)
uptodate = 1;
+#if 0
/* FIXME --mdcki */
HWGROUP(drive)->rq->special = NULL;
+#endif
ide_end_request(drive, uptodate);
}
@@ -1215,13 +1217,22 @@ static void restore_request (struct request *rq)
/*
* Start a read request from the CD-ROM.
*/
-static ide_startstop_t cdrom_start_read (ide_drive_t *drive, unsigned int block)
+static ide_startstop_t cdrom_start_read(struct ata_device *drive, struct ata_request *ar, unsigned int block)
{
struct cdrom_info *info = drive->driver_data;
- struct request *rq = HWGROUP(drive)->rq;
+ struct request *rq = ar->ar_rq;
+
+ if (ar->ar_flags & ATA_AR_QUEUED) {
+// spin_lock_irqsave(DRIVE_LOCK(drive), flags);
+ blkdev_dequeue_request(rq);
+// spin_unlock_irqrestore(DRIVE_LOCK(drive), flags);
+ }
+
restore_request(rq);
+ rq->special = ar;
+
/* Satisfy whatever we can of this request from our cached sector. */
if (cdrom_read_from_buffer(drive))
return ide_stopped;
@@ -1404,10 +1415,10 @@ int cdrom_queue_packet_command(ide_drive_t *drive, unsigned char *cmd,
struct request rq;
int retries = 10;
- memcpy(rq.cmd, cmd, CDROM_PACKET_SIZE);
/* Start of retry loop. */
do {
ide_init_drive_cmd(&rq);
+ memcpy(rq.cmd, cmd, CDROM_PACKET_SIZE);
rq.flags = REQ_PC;
@@ -1630,12 +1641,14 @@ static ide_startstop_t cdrom_start_write(ide_drive_t *drive, struct request *rq)
* cdrom driver request routine.
*/
static ide_startstop_t
-ide_do_rw_cdrom(ide_drive_t *drive, struct request *rq, unsigned long block)
+ide_cdrom_do_request(struct ata_device *drive, struct request *rq, sector_t block)
{
ide_startstop_t action;
struct cdrom_info *info = drive->driver_data;
if (rq->flags & REQ_CMD) {
+
+
if (CDROM_CONFIG_FLAGS(drive)->seeking) {
unsigned long elpased = jiffies - info->start_seek;
int stat = GET_STAT();
@@ -1652,8 +1665,30 @@ ide_do_rw_cdrom(ide_drive_t *drive, struct request *rq, unsigned long block)
if (IDE_LARGE_SEEK(info->last_block, block, IDECD_SEEK_THRESHOLD) && drive->dsc_overlap)
action = cdrom_start_seek (drive, block);
else {
+ unsigned long flags;
+ struct ata_request *ar;
+
+ /*
+ * get a new command (push ar further down to avoid grabbing lock here
+ */
+ spin_lock_irqsave(DRIVE_LOCK(drive), flags);
+
+ ar = ata_ar_get(drive);
+
+ /*
+ * we've reached maximum queue depth, bail
+ */
+ if (!ar) {
+ spin_unlock_irqrestore(DRIVE_LOCK(drive), flags);
+
+ return ide_started;
+ }
+
+ ar->ar_rq = rq;
+ spin_unlock_irqrestore(DRIVE_LOCK(drive), flags);
+
if (rq_data_dir(rq) == READ)
- action = cdrom_start_read(drive, block);
+ action = cdrom_start_read(drive, ar, block);
else
action = cdrom_start_write(drive, rq);
}
@@ -2297,7 +2332,7 @@ int ide_cdrom_reset (struct cdrom_device_info *cdi)
struct request req;
int ret;
- ide_init_drive_cmd (&req);
+ ide_init_drive_cmd(&req);
req.flags = REQ_SPECIAL;
ret = ide_do_drive_cmd(drive, &req, ide_wait);
@@ -2927,7 +2962,7 @@ static struct ata_operations ide_cdrom_driver = {
owner: THIS_MODULE,
cleanup: ide_cdrom_cleanup,
standby: NULL,
- do_request: ide_do_rw_cdrom,
+ do_request: ide_cdrom_do_request,
end_request: NULL,
ioctl: ide_cdrom_ioctl,
open: ide_cdrom_open,
diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c
index e828e6c6ce156..8f25d626f2740 100644
--- a/drivers/ide/ide-dma.c
+++ b/drivers/ide/ide-dma.c
@@ -549,8 +549,11 @@ int ide_start_dma(struct ata_channel *hwif, ide_drive_t *drive, ide_dma_action_t
/* This can happen with drivers abusing the special request field.
*/
- if (!ar)
+ if (!ar) {
+ printk(KERN_ERR "DMA without ATA request\n");
+
return 1;
+ }
if (rq_data_dir(ar->ar_rq) == READ)
reading = 1 << 3;
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index 3bfe703e69efd..b7dbb283cfc81 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -168,6 +168,9 @@ static inline void do_identify (ide_drive_t *drive, byte cmd)
}
printk (" drive\n");
drive->type = type;
+
+ goto init_queue;
+
return;
}
@@ -198,6 +201,7 @@ static inline void do_identify (ide_drive_t *drive, byte cmd)
if (drive->channel->quirkproc)
drive->quirk_list = drive->channel->quirkproc(drive);
+init_queue:
/*
* it's an ata drive, build command list
*/