diff options
author | Borislav Petkov <petkovbb@gmail.com> | 2009-05-04 03:38:15 -0400 |
---|---|---|
committer | Borislav Petkov <petkovbb@gmail.com> | 2009-05-15 00:44:35 -0400 |
commit | 55ce3a129ea2e8faba4a11bb5dbc305590d1c20c (patch) | |
tree | 78e0011fd9a404d959391073f5d56c57145a1006 /drivers/ide/ide-tape.c | |
parent | 837272b4f9393df40d16cc2ac731221027048ba6 (diff) |
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 <petkovbb@gmail.com>
Diffstat (limited to 'drivers/ide/ide-tape.c')
-rw-r--r-- | drivers/ide/ide-tape.c | 102 |
1 files changed, 49 insertions, 53 deletions
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 1a8c94055294..ead2734bc710 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) | |||
386 | uptodate = 0; | 386 | uptodate = 0; |
387 | err = pc->error; | 387 | err = pc->error; |
388 | } | 388 | } |
389 | } else if (pc->c[0] == READ_POSITION && uptodate) { | ||
390 | u8 *readpos = pc->buf; | ||
391 | |||
392 | debug_log(DBG_SENSE, "BOP - %s\n", | ||
393 | (readpos[0] & 0x80) ? "Yes" : "No"); | ||
394 | debug_log(DBG_SENSE, "EOP - %s\n", | ||
395 | (readpos[0] & 0x40) ? "Yes" : "No"); | ||
396 | |||
397 | if (readpos[0] & 0x4) { | ||
398 | printk(KERN_INFO "ide-tape: Block location is unknown" | ||
399 | "to the tape\n"); | ||
400 | clear_bit(IDE_AFLAG_ADDRESS_VALID, &drive->atapi_flags); | ||
401 | uptodate = 0; | ||
402 | err = IDE_DRV_ERROR_GENERAL; | ||
403 | } else { | ||
404 | debug_log(DBG_SENSE, "Block Location - %u\n", | ||
405 | be32_to_cpup((__be32 *)&readpos[4])); | ||
406 | |||
407 | tape->partition = readpos[1]; | ||
408 | tape->first_frame = be32_to_cpup((__be32 *)&readpos[4]); | ||
409 | set_bit(IDE_AFLAG_ADDRESS_VALID, &drive->atapi_flags); | ||
410 | } | ||
411 | } | 389 | } |
412 | |||
413 | rq->errors = err; | 390 | rq->errors = err; |
414 | 391 | ||
415 | return uptodate; | 392 | return uptodate; |
@@ -778,26 +755,44 @@ static int idetape_flush_tape_buffers(ide_drive_t *drive) | |||
778 | return 0; | 755 | return 0; |
779 | } | 756 | } |
780 | 757 | ||
781 | static void idetape_create_read_position_cmd(struct ide_atapi_pc *pc) | 758 | static int ide_tape_read_position(ide_drive_t *drive) |
782 | { | ||
783 | ide_init_pc(pc); | ||
784 | pc->c[0] = READ_POSITION; | ||
785 | pc->req_xfer = 20; | ||
786 | } | ||
787 | |||
788 | static int idetape_read_position(ide_drive_t *drive) | ||
789 | { | 759 | { |
790 | idetape_tape_t *tape = drive->driver_data; | 760 | idetape_tape_t *tape = drive->driver_data; |
791 | struct ide_atapi_pc pc; | 761 | struct ide_atapi_pc pc; |
792 | int position; | 762 | u8 buf[20]; |
793 | 763 | ||
794 | debug_log(DBG_PROCS, "Enter %s\n", __func__); | 764 | debug_log(DBG_PROCS, "Enter %s\n", __func__); |
795 | 765 | ||
796 | idetape_create_read_position_cmd(&pc); | 766 | /* prep cmd */ |
797 | if (ide_queue_pc_tail(drive, tape->disk, &pc, pc.buf, pc.req_xfer)) | 767 | ide_init_pc(&pc); |
768 | pc.c[0] = READ_POSITION; | ||
769 | pc.req_xfer = 20; | ||
770 | |||
771 | if (ide_queue_pc_tail(drive, tape->disk, &pc, buf, pc.req_xfer)) | ||
798 | return -1; | 772 | return -1; |
799 | position = tape->first_frame; | 773 | |
800 | return position; | 774 | if (!pc.error) { |
775 | debug_log(DBG_SENSE, "BOP - %s\n", | ||
776 | (buf[0] & 0x80) ? "Yes" : "No"); | ||
777 | debug_log(DBG_SENSE, "EOP - %s\n", | ||
778 | (buf[0] & 0x40) ? "Yes" : "No"); | ||
779 | |||
780 | if (buf[0] & 0x4) { | ||
781 | printk(KERN_INFO "ide-tape: Block location is unknown" | ||
782 | "to the tape\n"); | ||
783 | clear_bit(IDE_AFLAG_ADDRESS_VALID, &drive->atapi_flags); | ||
784 | return -1; | ||
785 | } else { | ||
786 | debug_log(DBG_SENSE, "Block Location - %u\n", | ||
787 | be32_to_cpup((__be32 *)&buf[4])); | ||
788 | |||
789 | tape->partition = buf[1]; | ||
790 | tape->first_frame = be32_to_cpup((__be32 *)&buf[4]); | ||
791 | set_bit(IDE_AFLAG_ADDRESS_VALID, &drive->atapi_flags); | ||
792 | } | ||
793 | } | ||
794 | |||
795 | return tape->first_frame; | ||
801 | } | 796 | } |
802 | 797 | ||
803 | static void idetape_create_locate_cmd(ide_drive_t *drive, | 798 | 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, | |||
840 | { | 835 | { |
841 | idetape_tape_t *tape = drive->driver_data; | 836 | idetape_tape_t *tape = drive->driver_data; |
842 | struct gendisk *disk = tape->disk; | 837 | struct gendisk *disk = tape->disk; |
843 | int retval; | 838 | int ret; |
844 | struct ide_atapi_pc pc; | 839 | struct ide_atapi_pc pc; |
845 | 840 | ||
846 | if (tape->chrdev_dir == IDETAPE_DIR_READ) | 841 | if (tape->chrdev_dir == IDETAPE_DIR_READ) |
847 | __ide_tape_discard_merge_buffer(drive); | 842 | __ide_tape_discard_merge_buffer(drive); |
848 | idetape_wait_ready(drive, 60 * 5 * HZ); | 843 | idetape_wait_ready(drive, 60 * 5 * HZ); |
849 | idetape_create_locate_cmd(drive, &pc, block, partition, skip); | 844 | idetape_create_locate_cmd(drive, &pc, block, partition, skip); |
850 | retval = ide_queue_pc_tail(drive, disk, &pc, NULL, 0); | 845 | ret = ide_queue_pc_tail(drive, disk, &pc, NULL, 0); |
851 | if (retval) | 846 | if (ret) |
852 | return (retval); | 847 | return ret; |
853 | 848 | ||
854 | idetape_create_read_position_cmd(&pc); | 849 | ret = ide_tape_read_position(drive); |
855 | return ide_queue_pc_tail(drive, disk, &pc, pc.buf, pc.req_xfer); | 850 | if (ret < 0) |
851 | return ret; | ||
852 | return 0; | ||
856 | } | 853 | } |
857 | 854 | ||
858 | static void ide_tape_discard_merge_buffer(ide_drive_t *drive, | 855 | 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, | |||
863 | 860 | ||
864 | __ide_tape_discard_merge_buffer(drive); | 861 | __ide_tape_discard_merge_buffer(drive); |
865 | if (restore_position) { | 862 | if (restore_position) { |
866 | position = idetape_read_position(drive); | 863 | position = ide_tape_read_position(drive); |
867 | seek = position > 0 ? position : 0; | 864 | seek = position > 0 ? position : 0; |
868 | if (idetape_position_tape(drive, seek, 0, 0)) { | 865 | if (idetape_position_tape(drive, seek, 0, 0)) { |
869 | printk(KERN_INFO "ide-tape: %s: position_tape failed in" | 866 | printk(KERN_INFO "ide-tape: %s: position_tape failed in" |
@@ -1042,20 +1039,19 @@ static int idetape_rewind_tape(ide_drive_t *drive) | |||
1042 | { | 1039 | { |
1043 | struct ide_tape_obj *tape = drive->driver_data; | 1040 | struct ide_tape_obj *tape = drive->driver_data; |
1044 | struct gendisk *disk = tape->disk; | 1041 | struct gendisk *disk = tape->disk; |
1045 | int retval; | ||
1046 | struct ide_atapi_pc pc; | 1042 | struct ide_atapi_pc pc; |
1043 | int ret; | ||
1047 | 1044 | ||
1048 | debug_log(DBG_SENSE, "Enter %s\n", __func__); | 1045 | debug_log(DBG_SENSE, "Enter %s\n", __func__); |
1049 | 1046 | ||
1050 | idetape_create_rewind_cmd(drive, &pc); | 1047 | idetape_create_rewind_cmd(drive, &pc); |
1051 | retval = ide_queue_pc_tail(drive, disk, &pc, NULL, 0); | 1048 | ret = ide_queue_pc_tail(drive, disk, &pc, NULL, 0); |
1052 | if (retval) | 1049 | if (ret) |
1053 | return retval; | 1050 | return ret; |
1054 | 1051 | ||
1055 | idetape_create_read_position_cmd(&pc); | 1052 | ret = ide_tape_read_position(drive); |
1056 | retval = ide_queue_pc_tail(drive, disk, &pc, pc.buf, pc.req_xfer); | 1053 | if (ret < 0) |
1057 | if (retval) | 1054 | return ret; |
1058 | return retval; | ||
1059 | return 0; | 1055 | return 0; |
1060 | } | 1056 | } |
1061 | 1057 | ||
@@ -1413,7 +1409,7 @@ static int idetape_chrdev_ioctl(struct inode *inode, struct file *file, | |||
1413 | if (cmd == MTIOCGET || cmd == MTIOCPOS) { | 1409 | if (cmd == MTIOCGET || cmd == MTIOCPOS) { |
1414 | block_offset = tape->valid / | 1410 | block_offset = tape->valid / |
1415 | (tape->blk_size * tape->user_bs_factor); | 1411 | (tape->blk_size * tape->user_bs_factor); |
1416 | position = idetape_read_position(drive); | 1412 | position = ide_tape_read_position(drive); |
1417 | if (position < 0) | 1413 | if (position < 0) |
1418 | return -EIO; | 1414 | return -EIO; |
1419 | } | 1415 | } |
@@ -1516,7 +1512,7 @@ static int idetape_chrdev_open(struct inode *inode, struct file *filp) | |||
1516 | goto out_put_tape; | 1512 | goto out_put_tape; |
1517 | } | 1513 | } |
1518 | 1514 | ||
1519 | idetape_read_position(drive); | 1515 | ide_tape_read_position(drive); |
1520 | if (!test_bit(IDE_AFLAG_ADDRESS_VALID, &drive->atapi_flags)) | 1516 | if (!test_bit(IDE_AFLAG_ADDRESS_VALID, &drive->atapi_flags)) |
1521 | (void)idetape_rewind_tape(drive); | 1517 | (void)idetape_rewind_tape(drive); |
1522 | 1518 | ||