From 45fbecb1147007167ea78399f165ceae775d86e7 Mon Sep 17 00:00:00 2001 From: Martin Dalecki Date: Mon, 22 Apr 2002 00:13:03 -0700 Subject: [PATCH] [PATCH] 2.5.8 IDE 40 - 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. --- drivers/ide/ide-cd.c | 51 ++++++++++++++++++++++++++++++++++------- drivers/ide/ide-dma.c | 5 +++- drivers/ide/ide-probe.c | 4 ++++ 3 files changed, 51 insertions(+), 9 deletions(-) diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 2aebf927a1f1..29e0be7635c0 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 e828e6c6ce15..8f25d626f274 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 3bfe703e69ef..b7dbb283cfc8 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 */ -- 2.39.5