aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide/ide-tape.c
diff options
context:
space:
mode:
authorBorislav Petkov <petkovbb@gmail.com>2009-05-04 03:38:15 -0400
committerBorislav Petkov <petkovbb@gmail.com>2009-05-15 00:44:35 -0400
commit55ce3a129ea2e8faba4a11bb5dbc305590d1c20c (patch)
tree78e0011fd9a404d959391073f5d56c57145a1006 /drivers/ide/ide-tape.c
parent837272b4f9393df40d16cc2ac731221027048ba6 (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.c102
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
781static void idetape_create_read_position_cmd(struct ide_atapi_pc *pc) 758static 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
788static 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
803static void idetape_create_locate_cmd(ide_drive_t *drive, 798static 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
858static void ide_tape_discard_merge_buffer(ide_drive_t *drive, 855static 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