From 10c0b3437c4dc0d14ac254bbe71e54ea5f238d97 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Fri, 1 May 2009 20:29:53 +0200 Subject: ide-tape: fix potential fs requests bug ide-tape had a potential bug for fs requests when preparing the command packet: it was writing the transfer length as a number of fixed blocks. However, the block layer implies 512 byte blocks and ide-tape can have other block sizes so account for that too. ide-floppy does this calculation properly with the block size factor (floppy->bs_factor). Signed-off-by: Borislav Petkov --- drivers/ide/ide-tape.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/ide/ide-tape.c') diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index e166045..fc79cf4 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -586,7 +586,7 @@ static void ide_tape_create_rw_cmd(idetape_tape_t *tape, struct ide_atapi_pc *pc, struct request *rq, u8 opcode) { - unsigned int length = blk_rq_sectors(rq); + unsigned int length = blk_rq_sectors(rq) / (tape->blk_size >> 9); ide_init_pc(pc); put_unaligned(cpu_to_be32(length), (unsigned int *) &pc->c[1]); -- cgit v1.1 From dfb7e621fa12c0579e88560ab176c5768f9e0bfb Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Fri, 1 May 2009 20:35:21 +0200 Subject: ide-atapi: switch to blk_rq_bytes() on do_request() path After the recent struct request cleanups, blk_rq_bytes() is guaranteed to be valid and is the current total length of the rq's bio. Use that instead of pc->req_xfer in the do_request() path after the command has been queued The remaining usage of pc->req_xfer now is only until we map the rq to a bio. While at it: - remove local caching of rq completion length in ide_tape_issue_pc() Signed-off-by: Borislav Petkov --- drivers/ide/ide-tape.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers/ide/ide-tape.c') diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index fc79cf4..aaeef12 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -292,6 +292,7 @@ static void idetape_analyze_error(ide_drive_t *drive, u8 *sense) { idetape_tape_t *tape = drive->driver_data; struct ide_atapi_pc *pc = drive->failed_pc; + struct request *rq = drive->hwif->rq; tape->sense_key = sense[2] & 0xF; tape->asc = sense[12]; @@ -302,7 +303,7 @@ static void idetape_analyze_error(ide_drive_t *drive, u8 *sense) /* Correct pc->xferred by asking the tape. */ if (pc->flags & PC_FLAG_DMA_ERROR) - pc->xferred = pc->req_xfer - + pc->xferred = blk_rq_bytes(rq) - tape->blk_size * get_unaligned_be32(&sense[3]); @@ -484,6 +485,7 @@ static ide_startstop_t ide_tape_issue_pc(ide_drive_t *drive, struct ide_atapi_pc *pc) { idetape_tape_t *tape = drive->driver_data; + struct request *rq = drive->hwif->rq; if (drive->failed_pc == NULL && pc->c[0] != REQUEST_SENSE) drive->failed_pc = pc; @@ -493,7 +495,6 @@ static ide_startstop_t ide_tape_issue_pc(ide_drive_t *drive, if (pc->retries > IDETAPE_MAX_PC_RETRIES || (pc->flags & PC_FLAG_ABORT)) { - unsigned int done = blk_rq_bytes(drive->hwif->rq); /* * We will "abort" retrying a packet command in case legitimate @@ -517,7 +518,7 @@ static ide_startstop_t ide_tape_issue_pc(ide_drive_t *drive, drive->failed_pc = NULL; drive->pc_callback(drive, 0); - ide_complete_rq(drive, -EIO, done); + ide_complete_rq(drive, -EIO, blk_rq_bytes(rq)); return ide_stopped; } debug_log(DBG_SENSE, "Retry #%d, cmd = %02X\n", pc->retries, pc->c[0]); @@ -592,9 +593,8 @@ static void ide_tape_create_rw_cmd(idetape_tape_t *tape, put_unaligned(cpu_to_be32(length), (unsigned int *) &pc->c[1]); pc->c[1] = 1; pc->buf = NULL; - pc->buf_size = length * tape->blk_size; - pc->req_xfer = pc->buf_size; - if (pc->req_xfer == tape->buffer_size) + pc->buf_size = blk_rq_bytes(rq); + if (pc->buf_size == tape->buffer_size) pc->flags |= PC_FLAG_DMA_OK; if (opcode == READ_6) @@ -718,7 +718,7 @@ out: cmd.rq = rq; - ide_init_sg_cmd(&cmd, pc->req_xfer); + ide_init_sg_cmd(&cmd, blk_rq_bytes(rq)); ide_map_sg(drive, &cmd); return ide_tape_issue_pc(drive, &cmd, pc); -- cgit v1.1 From 077e6dba20e74a455a0452379d2a965c7e1b01ad Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Fri, 1 May 2009 21:21:02 +0200 Subject: ide-atapi: switch to rq->resid_len Now that we have rq->resid_len, use it to account partial completion amount during the lifetime of an rq, decrementing it on each successful transfer. As a result, get rid of now unused pc->xferred. While at it, remove noisy debug call in ide_prep_sense. Signed-off-by: Borislav Petkov --- drivers/ide/ide-tape.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'drivers/ide/ide-tape.c') diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index aaeef12..c933709 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -301,11 +301,9 @@ static void idetape_analyze_error(ide_drive_t *drive, u8 *sense) debug_log(DBG_ERR, "pc = %x, sense key = %x, asc = %x, ascq = %x\n", pc->c[0], tape->sense_key, tape->asc, tape->ascq); - /* Correct pc->xferred by asking the tape. */ + /* correct remaining bytes to transfer */ if (pc->flags & PC_FLAG_DMA_ERROR) - pc->xferred = blk_rq_bytes(rq) - - tape->blk_size * - get_unaligned_be32(&sense[3]); + rq->resid_len = tape->blk_size * get_unaligned_be32(&sense[3]); /* * If error was the result of a zero-length read or write command, @@ -339,7 +337,7 @@ static void idetape_analyze_error(ide_drive_t *drive, u8 *sense) pc->flags |= PC_FLAG_ABORT; } if (!(pc->flags & PC_FLAG_ABORT) && - pc->xferred) + (blk_rq_bytes(rq) - rq->resid_len)) pc->retries = IDETAPE_MAX_PC_RETRIES + 1; } } @@ -369,7 +367,8 @@ static int ide_tape_callback(ide_drive_t *drive, int dsc) printk(KERN_ERR "ide-tape: Error in REQUEST SENSE " "itself - Aborting request!\n"); } else if (pc->c[0] == READ_6 || pc->c[0] == WRITE_6) { - int blocks = pc->xferred / tape->blk_size; + unsigned int blocks = + (blk_rq_bytes(rq) - rq->resid_len) / tape->blk_size; tape->avg_size += blocks * tape->blk_size; @@ -381,7 +380,6 @@ static int ide_tape_callback(ide_drive_t *drive, int dsc) } tape->first_frame += blocks; - rq->resid_len = blk_rq_bytes(rq) - blocks * tape->blk_size; if (pc->error) { uptodate = 0; -- cgit v1.1 From 5a0e43b5e2ee9a295f864c38f0e853b1a4fc3892 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Fri, 1 May 2009 23:27:11 +0200 Subject: ide-atapi: add a len-parameter to ide_queue_pc_tail This is in preparation for removing ide_atapi_pc. There should be no functional change resulting from this patch. Signed-off-by: Borislav Petkov --- drivers/ide/ide-tape.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'drivers/ide/ide-tape.c') diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index c933709..f09a263 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -770,7 +770,7 @@ static int idetape_flush_tape_buffers(ide_drive_t *drive) int rc; idetape_create_write_filemark_cmd(drive, &pc, 0); - rc = ide_queue_pc_tail(drive, tape->disk, &pc); + rc = ide_queue_pc_tail(drive, tape->disk, &pc, pc.req_xfer); if (rc) return rc; idetape_wait_ready(drive, 60 * 5 * HZ); @@ -793,7 +793,7 @@ static int idetape_read_position(ide_drive_t *drive) debug_log(DBG_PROCS, "Enter %s\n", __func__); idetape_create_read_position_cmd(&pc); - if (ide_queue_pc_tail(drive, tape->disk, &pc)) + if (ide_queue_pc_tail(drive, tape->disk, &pc, pc.req_xfer)) return -1; position = tape->first_frame; return position; @@ -846,12 +846,12 @@ static int idetape_position_tape(ide_drive_t *drive, unsigned int block, __ide_tape_discard_merge_buffer(drive); idetape_wait_ready(drive, 60 * 5 * HZ); idetape_create_locate_cmd(drive, &pc, block, partition, skip); - retval = ide_queue_pc_tail(drive, disk, &pc); + retval = ide_queue_pc_tail(drive, disk, &pc, pc.req_xfer); if (retval) return (retval); idetape_create_read_position_cmd(&pc); - return ide_queue_pc_tail(drive, disk, &pc); + return ide_queue_pc_tail(drive, disk, &pc, pc.req_xfer); } static void ide_tape_discard_merge_buffer(ide_drive_t *drive, @@ -1047,12 +1047,12 @@ static int idetape_rewind_tape(ide_drive_t *drive) debug_log(DBG_SENSE, "Enter %s\n", __func__); idetape_create_rewind_cmd(drive, &pc); - retval = ide_queue_pc_tail(drive, disk, &pc); + retval = ide_queue_pc_tail(drive, disk, &pc, pc.req_xfer); if (retval) return retval; idetape_create_read_position_cmd(&pc); - retval = ide_queue_pc_tail(drive, disk, &pc); + retval = ide_queue_pc_tail(drive, disk, &pc, pc.req_xfer); if (retval) return retval; return 0; @@ -1120,7 +1120,7 @@ static int idetape_space_over_filemarks(ide_drive_t *drive, short mt_op, case MTBSF: idetape_create_space_cmd(&pc, mt_count - count, IDETAPE_SPACE_OVER_FILEMARK); - return ide_queue_pc_tail(drive, disk, &pc); + return ide_queue_pc_tail(drive, disk, &pc, pc.req_xfer); case MTFSFM: case MTBSFM: if (!sprev) @@ -1259,7 +1259,7 @@ static int idetape_write_filemark(ide_drive_t *drive) /* Write a filemark */ idetape_create_write_filemark_cmd(drive, &pc, 1); - if (ide_queue_pc_tail(drive, tape->disk, &pc)) { + if (ide_queue_pc_tail(drive, tape->disk, &pc, pc.req_xfer)) { printk(KERN_ERR "ide-tape: Couldn't write a filemark\n"); return -EIO; } @@ -1344,11 +1344,11 @@ static int idetape_mtioctop(ide_drive_t *drive, short mt_op, int mt_count) IDETAPE_LU_RETENSION_MASK | IDETAPE_LU_LOAD_MASK); case MTEOM: idetape_create_space_cmd(&pc, 0, IDETAPE_SPACE_TO_EOD); - return ide_queue_pc_tail(drive, disk, &pc); + return ide_queue_pc_tail(drive, disk, &pc, pc.req_xfer); case MTERASE: (void)idetape_rewind_tape(drive); idetape_create_erase_cmd(&pc); - return ide_queue_pc_tail(drive, disk, &pc); + return ide_queue_pc_tail(drive, disk, &pc, pc.req_xfer); case MTSETBLK: if (mt_count) { if (mt_count < tape->blk_size || @@ -1457,7 +1457,7 @@ static void ide_tape_get_bsize_from_bdesc(ide_drive_t *drive) struct ide_atapi_pc pc; idetape_create_mode_sense_cmd(&pc, IDETAPE_BLOCK_DESCRIPTOR); - if (ide_queue_pc_tail(drive, tape->disk, &pc)) { + if (ide_queue_pc_tail(drive, tape->disk, &pc, pc.req_xfer)) { printk(KERN_ERR "ide-tape: Can't get block descriptor\n"); if (tape->blk_size == 0) { printk(KERN_WARNING "ide-tape: Cannot deal with zero " @@ -1613,7 +1613,7 @@ static void idetape_get_inquiry_results(ide_drive_t *drive) pc.buf = &pc_buf[0]; pc.buf_size = sizeof(pc_buf); - if (ide_queue_pc_tail(drive, tape->disk, &pc)) { + if (ide_queue_pc_tail(drive, tape->disk, &pc, pc.req_xfer)) { printk(KERN_ERR "ide-tape: %s: can't get INQUIRY results\n", tape->name); return; @@ -1642,7 +1642,7 @@ static void idetape_get_mode_sense_results(ide_drive_t *drive) u8 speed, max_speed; idetape_create_mode_sense_cmd(&pc, IDETAPE_CAPABILITIES_PAGE); - if (ide_queue_pc_tail(drive, tape->disk, &pc)) { + if (ide_queue_pc_tail(drive, tape->disk, &pc, pc.req_xfer)) { printk(KERN_ERR "ide-tape: Can't get tape parameters - assuming" " some default values\n"); tape->blk_size = 512; -- cgit v1.1 From b13345f39dadbabdabaf8819cf6df26913da9e8d Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Sat, 2 May 2009 10:26:12 +0200 Subject: ide-atapi: add a buffer-arg to ide_queue_pc_tail This is in preparation of removing ide_atapi_pc. Expose the buffer as an argument to ide_queue_pc_tail with later replacing it with local buffer or even kmalloc'ed one if needed due to stack usage constraints. Also, add the possibility of passing a NULL-ptr buffer for cmds which don't transfer data besides the cdb. While at it, switch to local buffer in idetape_get_mode_sense_results(). There should be no functional change resulting from this patch. Signed-off-by: Borislav Petkov --- drivers/ide/ide-tape.c | 37 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 19 deletions(-) (limited to 'drivers/ide/ide-tape.c') diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index f09a263..1f7f504 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -770,7 +770,7 @@ static int idetape_flush_tape_buffers(ide_drive_t *drive) int rc; idetape_create_write_filemark_cmd(drive, &pc, 0); - rc = ide_queue_pc_tail(drive, tape->disk, &pc, pc.req_xfer); + rc = ide_queue_pc_tail(drive, tape->disk, &pc, NULL, 0); if (rc) return rc; idetape_wait_ready(drive, 60 * 5 * HZ); @@ -793,7 +793,7 @@ static int idetape_read_position(ide_drive_t *drive) debug_log(DBG_PROCS, "Enter %s\n", __func__); idetape_create_read_position_cmd(&pc); - if (ide_queue_pc_tail(drive, tape->disk, &pc, pc.req_xfer)) + if (ide_queue_pc_tail(drive, tape->disk, &pc, pc.buf, pc.req_xfer)) return -1; position = tape->first_frame; return position; @@ -846,12 +846,12 @@ static int idetape_position_tape(ide_drive_t *drive, unsigned int block, __ide_tape_discard_merge_buffer(drive); idetape_wait_ready(drive, 60 * 5 * HZ); idetape_create_locate_cmd(drive, &pc, block, partition, skip); - retval = ide_queue_pc_tail(drive, disk, &pc, pc.req_xfer); + retval = ide_queue_pc_tail(drive, disk, &pc, NULL, 0); if (retval) return (retval); idetape_create_read_position_cmd(&pc); - return ide_queue_pc_tail(drive, disk, &pc, pc.req_xfer); + return ide_queue_pc_tail(drive, disk, &pc, pc.buf, pc.req_xfer); } static void ide_tape_discard_merge_buffer(ide_drive_t *drive, @@ -1047,12 +1047,12 @@ static int idetape_rewind_tape(ide_drive_t *drive) debug_log(DBG_SENSE, "Enter %s\n", __func__); idetape_create_rewind_cmd(drive, &pc); - retval = ide_queue_pc_tail(drive, disk, &pc, pc.req_xfer); + retval = ide_queue_pc_tail(drive, disk, &pc, NULL, 0); if (retval) return retval; idetape_create_read_position_cmd(&pc); - retval = ide_queue_pc_tail(drive, disk, &pc, pc.req_xfer); + retval = ide_queue_pc_tail(drive, disk, &pc, pc.buf, pc.req_xfer); if (retval) return retval; return 0; @@ -1120,7 +1120,7 @@ static int idetape_space_over_filemarks(ide_drive_t *drive, short mt_op, case MTBSF: idetape_create_space_cmd(&pc, mt_count - count, IDETAPE_SPACE_OVER_FILEMARK); - return ide_queue_pc_tail(drive, disk, &pc, pc.req_xfer); + return ide_queue_pc_tail(drive, disk, &pc, NULL, 0); case MTFSFM: case MTBSFM: if (!sprev) @@ -1259,7 +1259,7 @@ static int idetape_write_filemark(ide_drive_t *drive) /* Write a filemark */ idetape_create_write_filemark_cmd(drive, &pc, 1); - if (ide_queue_pc_tail(drive, tape->disk, &pc, pc.req_xfer)) { + if (ide_queue_pc_tail(drive, tape->disk, &pc, NULL, 0)) { printk(KERN_ERR "ide-tape: Couldn't write a filemark\n"); return -EIO; } @@ -1344,11 +1344,11 @@ static int idetape_mtioctop(ide_drive_t *drive, short mt_op, int mt_count) IDETAPE_LU_RETENSION_MASK | IDETAPE_LU_LOAD_MASK); case MTEOM: idetape_create_space_cmd(&pc, 0, IDETAPE_SPACE_TO_EOD); - return ide_queue_pc_tail(drive, disk, &pc, pc.req_xfer); + return ide_queue_pc_tail(drive, disk, &pc, NULL, 0); case MTERASE: (void)idetape_rewind_tape(drive); idetape_create_erase_cmd(&pc); - return ide_queue_pc_tail(drive, disk, &pc, pc.req_xfer); + return ide_queue_pc_tail(drive, disk, &pc, NULL, 0); case MTSETBLK: if (mt_count) { if (mt_count < tape->blk_size || @@ -1457,7 +1457,7 @@ static void ide_tape_get_bsize_from_bdesc(ide_drive_t *drive) struct ide_atapi_pc pc; idetape_create_mode_sense_cmd(&pc, IDETAPE_BLOCK_DESCRIPTOR); - if (ide_queue_pc_tail(drive, tape->disk, &pc, pc.req_xfer)) { + if (ide_queue_pc_tail(drive, tape->disk, &pc, pc.buf, pc.req_xfer)) { printk(KERN_ERR "ide-tape: Can't get block descriptor\n"); if (tape->blk_size == 0) { printk(KERN_WARNING "ide-tape: Cannot deal with zero " @@ -1610,17 +1610,16 @@ static void idetape_get_inquiry_results(ide_drive_t *drive) char fw_rev[4], vendor_id[8], product_id[16]; idetape_create_inquiry_cmd(&pc); - pc.buf = &pc_buf[0]; pc.buf_size = sizeof(pc_buf); - if (ide_queue_pc_tail(drive, tape->disk, &pc, pc.req_xfer)) { + if (ide_queue_pc_tail(drive, tape->disk, &pc, pc_buf, pc.req_xfer)) { printk(KERN_ERR "ide-tape: %s: can't get INQUIRY results\n", tape->name); return; } - memcpy(vendor_id, &pc.buf[8], 8); - memcpy(product_id, &pc.buf[16], 16); - memcpy(fw_rev, &pc.buf[32], 4); + memcpy(vendor_id, &pc_buf[8], 8); + memcpy(product_id, &pc_buf[16], 16); + memcpy(fw_rev, &pc_buf[32], 4); ide_fixstring(vendor_id, 8, 0); ide_fixstring(product_id, 16, 0); @@ -1638,11 +1637,11 @@ static void idetape_get_mode_sense_results(ide_drive_t *drive) { idetape_tape_t *tape = drive->driver_data; struct ide_atapi_pc pc; - u8 *caps; + u8 buf[24], *caps; u8 speed, max_speed; idetape_create_mode_sense_cmd(&pc, IDETAPE_CAPABILITIES_PAGE); - if (ide_queue_pc_tail(drive, tape->disk, &pc, pc.req_xfer)) { + if (ide_queue_pc_tail(drive, tape->disk, &pc, buf, pc.req_xfer)) { printk(KERN_ERR "ide-tape: Can't get tape parameters - assuming" " some default values\n"); tape->blk_size = 512; @@ -1651,7 +1650,7 @@ static void idetape_get_mode_sense_results(ide_drive_t *drive) put_unaligned(6*52, (u16 *)&tape->caps[16]); return; } - caps = pc.buf + 4 + pc.buf[3]; + caps = buf + 4 + buf[3]; /* convert to host order and save for later use */ speed = be16_to_cpup((__be16 *)&caps[14]); -- cgit v1.1 From ae3a8387be529e632eac69b342524c25b892fc63 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Sat, 2 May 2009 10:58:17 +0200 Subject: ide-atapi: use local sense buffer Access the sense buffer through the bio in ->pc_callback method thus alleviating the need for the pc->buf pointer. There should be no functional change resulting from this patch. Signed-off-by: Borislav Petkov --- drivers/ide/ide-tape.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/ide/ide-tape.c') diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 1f7f504..ef5f342 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -288,11 +288,12 @@ static struct ide_tape_obj *ide_tape_chrdev_get(unsigned int i) * called on each failed packet command retry to analyze the request sense. We * currently do not utilize this information. */ -static void idetape_analyze_error(ide_drive_t *drive, u8 *sense) +static void idetape_analyze_error(ide_drive_t *drive) { idetape_tape_t *tape = drive->driver_data; struct ide_atapi_pc *pc = drive->failed_pc; struct request *rq = drive->hwif->rq; + u8 *sense = bio_data(rq->bio); tape->sense_key = sense[2] & 0xF; tape->asc = sense[12]; @@ -362,7 +363,7 @@ static int ide_tape_callback(ide_drive_t *drive, int dsc) if (pc->c[0] == REQUEST_SENSE) { if (uptodate) - idetape_analyze_error(drive, pc->buf); + idetape_analyze_error(drive); else printk(KERN_ERR "ide-tape: Error in REQUEST SENSE " "itself - Aborting request!\n"); -- cgit v1.1 From 837272b4f9393df40d16cc2ac731221027048ba6 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Mon, 4 May 2009 09:48:57 +0200 Subject: ide-tape/ide_tape_get_bsize_from_bdesc: use local buffer There should be no functional change resulting from this patch. Signed-off-by: Borislav Petkov --- drivers/ide/ide-tape.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers/ide/ide-tape.c') diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index ef5f342..1a8c940 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -1456,9 +1456,10 @@ static void ide_tape_get_bsize_from_bdesc(ide_drive_t *drive) { idetape_tape_t *tape = drive->driver_data; struct ide_atapi_pc pc; + u8 buf[12]; idetape_create_mode_sense_cmd(&pc, IDETAPE_BLOCK_DESCRIPTOR); - if (ide_queue_pc_tail(drive, tape->disk, &pc, pc.buf, pc.req_xfer)) { + if (ide_queue_pc_tail(drive, tape->disk, &pc, buf, pc.req_xfer)) { printk(KERN_ERR "ide-tape: Can't get block descriptor\n"); if (tape->blk_size == 0) { printk(KERN_WARNING "ide-tape: Cannot deal with zero " @@ -1467,10 +1468,10 @@ static void ide_tape_get_bsize_from_bdesc(ide_drive_t *drive) } return; } - tape->blk_size = (pc.buf[4 + 5] << 16) + - (pc.buf[4 + 6] << 8) + - pc.buf[4 + 7]; - tape->drv_write_prot = (pc.buf[2] & 0x80) >> 7; + tape->blk_size = (buf[4 + 5] << 16) + + (buf[4 + 6] << 8) + + buf[4 + 7]; + tape->drv_write_prot = (buf[2] & 0x80) >> 7; } static int idetape_chrdev_open(struct inode *inode, struct file *filp) -- cgit v1.1 From 55ce3a129ea2e8faba4a11bb5dbc305590d1c20c Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Mon, 4 May 2009 09:38:15 +0200 Subject: ide-tape: fix READ POSITION cmd handling ide-tape used to issue READ POSITION in several places and the evaluation of the returned READ POSITION data was done in the ->pc_callback. Convert it to use local buffer and move that evaluation chunk in the idetape_read_position(). Additionally, fold idetape_create_read_position_cmd() into it, too, thus concentrating READ POSITION handling in one method only and making all places call that. Finally, mv {idetape,ide_tape}_read_position. There should be no functional change resulting from this patch. Signed-off-by: Borislav Petkov --- drivers/ide/ide-tape.c | 102 ++++++++++++++++++++++++------------------------- 1 file changed, 49 insertions(+), 53 deletions(-) (limited to 'drivers/ide/ide-tape.c') diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 1a8c940..ead2734 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -386,30 +386,7 @@ static int ide_tape_callback(ide_drive_t *drive, int dsc) uptodate = 0; err = pc->error; } - } else if (pc->c[0] == READ_POSITION && uptodate) { - u8 *readpos = pc->buf; - - debug_log(DBG_SENSE, "BOP - %s\n", - (readpos[0] & 0x80) ? "Yes" : "No"); - debug_log(DBG_SENSE, "EOP - %s\n", - (readpos[0] & 0x40) ? "Yes" : "No"); - - if (readpos[0] & 0x4) { - printk(KERN_INFO "ide-tape: Block location is unknown" - "to the tape\n"); - clear_bit(IDE_AFLAG_ADDRESS_VALID, &drive->atapi_flags); - uptodate = 0; - err = IDE_DRV_ERROR_GENERAL; - } else { - debug_log(DBG_SENSE, "Block Location - %u\n", - be32_to_cpup((__be32 *)&readpos[4])); - - tape->partition = readpos[1]; - tape->first_frame = be32_to_cpup((__be32 *)&readpos[4]); - set_bit(IDE_AFLAG_ADDRESS_VALID, &drive->atapi_flags); - } } - rq->errors = err; return uptodate; @@ -778,26 +755,44 @@ static int idetape_flush_tape_buffers(ide_drive_t *drive) return 0; } -static void idetape_create_read_position_cmd(struct ide_atapi_pc *pc) -{ - ide_init_pc(pc); - pc->c[0] = READ_POSITION; - pc->req_xfer = 20; -} - -static int idetape_read_position(ide_drive_t *drive) +static int ide_tape_read_position(ide_drive_t *drive) { idetape_tape_t *tape = drive->driver_data; struct ide_atapi_pc pc; - int position; + u8 buf[20]; debug_log(DBG_PROCS, "Enter %s\n", __func__); - idetape_create_read_position_cmd(&pc); - if (ide_queue_pc_tail(drive, tape->disk, &pc, pc.buf, pc.req_xfer)) + /* prep cmd */ + ide_init_pc(&pc); + pc.c[0] = READ_POSITION; + pc.req_xfer = 20; + + if (ide_queue_pc_tail(drive, tape->disk, &pc, buf, pc.req_xfer)) return -1; - position = tape->first_frame; - return position; + + if (!pc.error) { + debug_log(DBG_SENSE, "BOP - %s\n", + (buf[0] & 0x80) ? "Yes" : "No"); + debug_log(DBG_SENSE, "EOP - %s\n", + (buf[0] & 0x40) ? "Yes" : "No"); + + if (buf[0] & 0x4) { + printk(KERN_INFO "ide-tape: Block location is unknown" + "to the tape\n"); + clear_bit(IDE_AFLAG_ADDRESS_VALID, &drive->atapi_flags); + return -1; + } else { + debug_log(DBG_SENSE, "Block Location - %u\n", + be32_to_cpup((__be32 *)&buf[4])); + + tape->partition = buf[1]; + tape->first_frame = be32_to_cpup((__be32 *)&buf[4]); + set_bit(IDE_AFLAG_ADDRESS_VALID, &drive->atapi_flags); + } + } + + return tape->first_frame; } static void idetape_create_locate_cmd(ide_drive_t *drive, @@ -840,19 +835,21 @@ static int idetape_position_tape(ide_drive_t *drive, unsigned int block, { idetape_tape_t *tape = drive->driver_data; struct gendisk *disk = tape->disk; - int retval; + int ret; struct ide_atapi_pc pc; if (tape->chrdev_dir == IDETAPE_DIR_READ) __ide_tape_discard_merge_buffer(drive); idetape_wait_ready(drive, 60 * 5 * HZ); idetape_create_locate_cmd(drive, &pc, block, partition, skip); - retval = ide_queue_pc_tail(drive, disk, &pc, NULL, 0); - if (retval) - return (retval); + ret = ide_queue_pc_tail(drive, disk, &pc, NULL, 0); + if (ret) + return ret; - idetape_create_read_position_cmd(&pc); - return ide_queue_pc_tail(drive, disk, &pc, pc.buf, pc.req_xfer); + ret = ide_tape_read_position(drive); + if (ret < 0) + return ret; + return 0; } static void ide_tape_discard_merge_buffer(ide_drive_t *drive, @@ -863,7 +860,7 @@ static void ide_tape_discard_merge_buffer(ide_drive_t *drive, __ide_tape_discard_merge_buffer(drive); if (restore_position) { - position = idetape_read_position(drive); + position = ide_tape_read_position(drive); seek = position > 0 ? position : 0; if (idetape_position_tape(drive, seek, 0, 0)) { printk(KERN_INFO "ide-tape: %s: position_tape failed in" @@ -1042,20 +1039,19 @@ static int idetape_rewind_tape(ide_drive_t *drive) { struct ide_tape_obj *tape = drive->driver_data; struct gendisk *disk = tape->disk; - int retval; struct ide_atapi_pc pc; + int ret; debug_log(DBG_SENSE, "Enter %s\n", __func__); idetape_create_rewind_cmd(drive, &pc); - retval = ide_queue_pc_tail(drive, disk, &pc, NULL, 0); - if (retval) - return retval; + ret = ide_queue_pc_tail(drive, disk, &pc, NULL, 0); + if (ret) + return ret; - idetape_create_read_position_cmd(&pc); - retval = ide_queue_pc_tail(drive, disk, &pc, pc.buf, pc.req_xfer); - if (retval) - return retval; + ret = ide_tape_read_position(drive); + if (ret < 0) + return ret; return 0; } @@ -1413,7 +1409,7 @@ static int idetape_chrdev_ioctl(struct inode *inode, struct file *file, if (cmd == MTIOCGET || cmd == MTIOCPOS) { block_offset = tape->valid / (tape->blk_size * tape->user_bs_factor); - position = idetape_read_position(drive); + position = ide_tape_read_position(drive); if (position < 0) return -EIO; } @@ -1516,7 +1512,7 @@ static int idetape_chrdev_open(struct inode *inode, struct file *filp) goto out_put_tape; } - idetape_read_position(drive); + ide_tape_read_position(drive); if (!test_bit(IDE_AFLAG_ADDRESS_VALID, &drive->atapi_flags)) (void)idetape_rewind_tape(drive); -- cgit v1.1 From 19f52a784f7ecb5b51cd73cc4514614b600b995a Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Mon, 4 May 2009 09:53:03 +0200 Subject: ide-atapi: remove pc->buf Now after all users of pc->buf have been converted, remove the 64B buffer embedded in each packet command. There should be no functional change resulting from this patch. Signed-off-by: Borislav Petkov --- drivers/ide/ide-tape.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'drivers/ide/ide-tape.c') diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index ead2734..9ca2665 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -568,9 +568,8 @@ static void ide_tape_create_rw_cmd(idetape_tape_t *tape, ide_init_pc(pc); put_unaligned(cpu_to_be32(length), (unsigned int *) &pc->c[1]); pc->c[1] = 1; - pc->buf = NULL; - pc->buf_size = blk_rq_bytes(rq); - if (pc->buf_size == tape->buffer_size) + + if (blk_rq_bytes(rq) == tape->buffer_size) pc->flags |= PC_FLAG_DMA_OK; if (opcode == READ_6) @@ -1608,8 +1607,6 @@ static void idetape_get_inquiry_results(ide_drive_t *drive) char fw_rev[4], vendor_id[8], product_id[16]; idetape_create_inquiry_cmd(&pc); - pc.buf_size = sizeof(pc_buf); - if (ide_queue_pc_tail(drive, tape->disk, &pc, pc_buf, pc.req_xfer)) { printk(KERN_ERR "ide-tape: %s: can't get INQUIRY results\n", tape->name); -- cgit v1.1