Messages in this thread Patch in this message |  | | | Date | Thu, 16 Apr 2009 07:54:00 +0200 | | From | Borislav Petkov <> | | Subject | [PATCH 3/3] ide-atapi: convert ide-{floppy,tape} to using preallocated sense buffer |
| |
Since we're issuing REQ_TYPE_SENSE now we need to allow those types of rqs in the ->do_request callbacks. As a future improvement, sense_len assignment might be unified across all ATAPI devices. Borislav to check with specs and test.
As a result, get rid of ide_queue_pc_head() and the block layer structs.
CC: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> CC: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> CC: Tejun Heo <tj@kernel.org> Signed-off-by: Borislav Petkov <petkovbb@gmail.com> --- drivers/ide/ide-atapi.c | 59 ++++++++++++++-------------------------------- drivers/ide/ide-floppy.c | 19 ++++++++++++++- drivers/ide/ide-gd.c | 4 +++ drivers/ide/ide-tape.c | 23 +++++++++++++++++- include/linux/ide.h | 3 -- 5 files changed, 62 insertions(+), 46 deletions(-) diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index fa09789..43a2337 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c @@ -80,40 +80,6 @@ void ide_init_pc(struct ide_atapi_pc *pc) EXPORT_SYMBOL_GPL(ide_init_pc); /* - * Generate a new packet command request in front of the request queue, before - * the current request, so that it will be processed immediately, on the next - * pass through the driver. - */ -static void ide_queue_pc_head(ide_drive_t *drive, struct gendisk *disk, - struct ide_atapi_pc *pc, struct request *rq, - struct bio *bio, struct bio_vec *bvec, - unsigned short bvec_len) -{ - blk_rq_init(NULL, rq); - rq->cmd_type = REQ_TYPE_SPECIAL; - rq->cmd_flags |= REQ_PREEMPT; - rq->special = (char *)pc; - rq->rq_disk = disk; - - if (pc->req_xfer) { - int error; - - error = blk_rq_map_kern_prealloc(drive->queue, rq, bio, - bvec, bvec_len, - pc->buf, pc->req_xfer, true); - BUG_ON(error); - } - - memcpy(rq->cmd, pc->c, 12); - if (drive->media == ide_tape) - rq->cmd[13] = REQ_IDETAPE_PC1; - - drive->hwif->rq = NULL; - - elv_add_request(drive->queue, rq, ELEVATOR_INSERT_FRONT, 0); -} - -/* * Add a special packet command request to the tail of the request queue, * and wait for it to be serviced. */ @@ -237,22 +203,29 @@ void ide_queue_sense_rq(ide_drive_t *drive) EXPORT_SYMBOL_GPL(ide_queue_sense_rq); /* - * Called when an error was detected during the last packet command. - * We queue a request sense packet command in the head of the request list. + * Called when an error was detected during the last packet command. We queue a + * request sense packet command at the head of the request queue. */ void ide_retry_pc(ide_drive_t *drive, struct gendisk *disk) { - struct request *rq = &drive->request_sense_rq; - struct bio *bio = &drive->request_sense_bio; - struct bio_vec *bvec = drive->request_sense_bvec; struct ide_atapi_pc *pc = &drive->request_sense_pc; - unsigned short bvec_len = ARRAY_SIZE(drive->request_sense_bvec); (void)ide_read_error(drive); ide_create_request_sense_cmd(drive, pc); if (drive->media == ide_tape) set_bit(IDE_AFLAG_IGNORE_DSC, &drive->atapi_flags); - ide_queue_pc_head(drive, disk, pc, rq, bio, bvec, bvec_len); + + drive->sense_rq->special = (char *)pc; + drive->sense_rq->rq_disk = disk; + + /* FIXME: sense_len == sizeof(struct request_sense) */ + memcpy(drive->sense_rq->cmd, pc->c, 12); + drive->sense_rq->sense_len = pc->req_xfer; + + if (drive->media == ide_tape) + drive->sense_rq->cmd[13] = REQ_IDETAPE_PC1; + + ide_queue_sense_rq(drive); } EXPORT_SYMBOL_GPL(ide_retry_pc); @@ -425,6 +398,10 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) error = uptodate ? 0 : -EIO; } + /* prepare request sense if it got used with the last rq */ + if (blk_sense_request(rq)) + drive->sense_rq = NULL; + ide_complete_rq(drive, error, done); return ide_stopped; } diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index 9460033..7d2b219 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c @@ -263,7 +263,7 @@ static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive, } pc = &floppy->queued_pc; idefloppy_create_rw_cmd(drive, pc, rq, (unsigned long)block); - } else if (blk_special_request(rq)) { + } else if (blk_special_request(rq) || blk_sense_request(rq)) { pc = (struct ide_atapi_pc *)rq->special; } else if (blk_pc_request(rq)) { pc = &floppy->queued_pc; @@ -273,6 +273,23 @@ static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive, goto out_end; } + /* prepare request sense if it got used with the last rq */ + if (!drive->sense_rq) { + drive->sense_rq = ide_prep_sense(drive, floppy->disk); + if (!drive->sense_rq) { + printk(KERN_ERR "%s: error prepping sense request!\n", + drive->name); + return ide_stopped; + } + } + + /* + * save the current request in case we'll be queueing a sense rq + * afterwards due to its potential failure. + */ + if (!blk_sense_request(rq)) + drive->sense_rq->special = rq; + memset(&cmd, 0, sizeof(cmd)); if (rq_data_dir(rq)) diff --git a/drivers/ide/ide-gd.c b/drivers/ide/ide-gd.c index 1aebdf1..811c002 100644 --- a/drivers/ide/ide-gd.c +++ b/drivers/ide/ide-gd.c @@ -82,6 +82,10 @@ static void ide_disk_release(struct device *dev) struct gendisk *g = idkp->disk; drive->disk_ops = NULL; + + if (drive->sense_rq) + blk_put_request(drive->sense_rq); + drive->driver_data = NULL; g->private_data = NULL; put_disk(g); diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index d52f8b3..e26c9c7 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -758,7 +758,7 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive, (unsigned long long)rq->sector, rq->nr_sectors, rq->current_nr_sectors); - if (!blk_special_request(rq)) { + if (!(blk_special_request(rq) || blk_sense_request(rq))) { /* We do not support buffer cache originated requests. */ printk(KERN_NOTICE "ide-tape: %s: Unsupported request in " "request queue (%d)\n", drive->name, rq->cmd_type); @@ -850,6 +850,23 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive, BUG(); out: + /* prepare request sense if it got used with the last rq */ + if (!drive->sense_rq) { + drive->sense_rq = ide_prep_sense(drive, tape->disk); + if (!drive->sense_rq) { + printk(KERN_ERR "%s: error prepping sense request!\n", + drive->name); + return ide_stopped; + } + } + + /* + * save the current request in case we'll be queueing a sense rq + * afterwards due to its potential failure. + */ + if (!blk_sense_request(rq)) + drive->sense_rq->special = rq; + if (rq_data_dir(rq)) cmd.tf_flags |= IDE_TFLAG_WRITE; @@ -2249,6 +2266,10 @@ static void ide_tape_release(struct device *dev) BUG_ON(tape->merge_bh_size); drive->dev_flags &= ~IDE_DFLAG_DSC_OVERLAP; + + if (drive->sense_rq) + blk_put_request(drive->sense_rq); + drive->driver_data = NULL; device_destroy(idetape_sysfs_class, MKDEV(IDETAPE_MAJOR, tape->minor)); device_destroy(idetape_sysfs_class, diff --git a/include/linux/ide.h b/include/linux/ide.h index 095cda2..2238e61 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -605,9 +605,6 @@ struct ide_drive_s { /* for request sense */ struct ide_atapi_pc request_sense_pc; - struct request request_sense_rq; - struct bio request_sense_bio; - struct bio_vec request_sense_bvec[2]; /* current sense rq and buffer */ struct request *sense_rq; -- 1.6.2.2
-- Regards/Gruss, Boris.
|  |