diff options
Diffstat (limited to 'drivers/ide/ide-tape.c')
-rw-r--r-- | drivers/ide/ide-tape.c | 45 |
1 files changed, 20 insertions, 25 deletions
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 4da7fa9bca1e..d5e9bb286e30 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c | |||
@@ -879,15 +879,15 @@ static void ide_tape_discard_merge_buffer(ide_drive_t *drive, | |||
879 | * Generate a read/write request for the block device interface and wait for it | 879 | * Generate a read/write request for the block device interface and wait for it |
880 | * to be serviced. | 880 | * to be serviced. |
881 | */ | 881 | */ |
882 | static int idetape_queue_rw_tail(ide_drive_t *drive, int cmd, int blocks) | 882 | static int idetape_queue_rw_tail(ide_drive_t *drive, int cmd, int size) |
883 | { | 883 | { |
884 | idetape_tape_t *tape = drive->driver_data; | 884 | idetape_tape_t *tape = drive->driver_data; |
885 | size_t size = blocks * tape->blk_size; | ||
886 | struct request *rq; | 885 | struct request *rq; |
887 | int ret; | 886 | int ret; |
888 | 887 | ||
889 | debug_log(DBG_SENSE, "%s: cmd=%d\n", __func__, cmd); | 888 | debug_log(DBG_SENSE, "%s: cmd=%d\n", __func__, cmd); |
890 | BUG_ON(cmd != REQ_IDETAPE_READ && cmd != REQ_IDETAPE_WRITE); | 889 | BUG_ON(cmd != REQ_IDETAPE_READ && cmd != REQ_IDETAPE_WRITE); |
890 | BUG_ON(size < 0 || size % tape->blk_size); | ||
891 | 891 | ||
892 | rq = blk_get_request(drive->queue, READ, __GFP_WAIT); | 892 | rq = blk_get_request(drive->queue, READ, __GFP_WAIT); |
893 | rq->cmd_type = REQ_TYPE_SPECIAL; | 893 | rq->cmd_type = REQ_TYPE_SPECIAL; |
@@ -954,17 +954,16 @@ static void idetape_create_space_cmd(struct ide_atapi_pc *pc, int count, u8 cmd) | |||
954 | } | 954 | } |
955 | 955 | ||
956 | /* Queue up a character device originated write request. */ | 956 | /* Queue up a character device originated write request. */ |
957 | static int idetape_add_chrdev_write_request(ide_drive_t *drive, int blocks) | 957 | static int idetape_add_chrdev_write_request(ide_drive_t *drive, int size) |
958 | { | 958 | { |
959 | debug_log(DBG_CHRDEV, "Enter %s\n", __func__); | 959 | debug_log(DBG_CHRDEV, "Enter %s\n", __func__); |
960 | 960 | ||
961 | return idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, blocks); | 961 | return idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, size); |
962 | } | 962 | } |
963 | 963 | ||
964 | static void ide_tape_flush_merge_buffer(ide_drive_t *drive) | 964 | static void ide_tape_flush_merge_buffer(ide_drive_t *drive) |
965 | { | 965 | { |
966 | idetape_tape_t *tape = drive->driver_data; | 966 | idetape_tape_t *tape = drive->driver_data; |
967 | int blocks; | ||
968 | 967 | ||
969 | if (tape->chrdev_dir != IDETAPE_DIR_WRITE) { | 968 | if (tape->chrdev_dir != IDETAPE_DIR_WRITE) { |
970 | printk(KERN_ERR "ide-tape: bug: Trying to empty merge buffer" | 969 | printk(KERN_ERR "ide-tape: bug: Trying to empty merge buffer" |
@@ -972,15 +971,10 @@ static void ide_tape_flush_merge_buffer(ide_drive_t *drive) | |||
972 | return; | 971 | return; |
973 | } | 972 | } |
974 | if (tape->buf) { | 973 | if (tape->buf) { |
975 | blocks = tape->valid / tape->blk_size; | 974 | size_t aligned = roundup(tape->valid, tape->blk_size); |
976 | if (tape->valid % tape->blk_size) { | 975 | |
977 | blocks++; | 976 | memset(tape->cur, 0, aligned - tape->valid); |
978 | memset(tape->buf + tape->valid, 0, | 977 | idetape_add_chrdev_write_request(drive, aligned); |
979 | tape->blk_size - tape->valid % tape->blk_size); | ||
980 | } | ||
981 | (void) idetape_add_chrdev_write_request(drive, blocks); | ||
982 | } | ||
983 | if (tape->buf != NULL) { | ||
984 | kfree(tape->buf); | 978 | kfree(tape->buf); |
985 | tape->buf = NULL; | 979 | tape->buf = NULL; |
986 | } | 980 | } |
@@ -1038,9 +1032,9 @@ static int idetape_init_rw(ide_drive_t *drive, int dir) | |||
1038 | } | 1032 | } |
1039 | 1033 | ||
1040 | /* called from idetape_chrdev_read() to service a chrdev read request. */ | 1034 | /* called from idetape_chrdev_read() to service a chrdev read request. */ |
1041 | static int idetape_add_chrdev_read_request(ide_drive_t *drive, int blocks) | 1035 | static int idetape_add_chrdev_read_request(ide_drive_t *drive, int size) |
1042 | { | 1036 | { |
1043 | debug_log(DBG_PROCS, "Enter %s, %d blocks\n", __func__, blocks); | 1037 | debug_log(DBG_PROCS, "Enter %s, %d bytes\n", __func__, size); |
1044 | 1038 | ||
1045 | /* If we are at a filemark, return a read length of 0 */ | 1039 | /* If we are at a filemark, return a read length of 0 */ |
1046 | if (test_bit(IDE_AFLAG_FILEMARK, &drive->atapi_flags)) | 1040 | if (test_bit(IDE_AFLAG_FILEMARK, &drive->atapi_flags)) |
@@ -1048,7 +1042,7 @@ static int idetape_add_chrdev_read_request(ide_drive_t *drive, int blocks) | |||
1048 | 1042 | ||
1049 | idetape_init_rw(drive, IDETAPE_DIR_READ); | 1043 | idetape_init_rw(drive, IDETAPE_DIR_READ); |
1050 | 1044 | ||
1051 | return idetape_queue_rw_tail(drive, REQ_IDETAPE_READ, blocks); | 1045 | return idetape_queue_rw_tail(drive, REQ_IDETAPE_READ, size); |
1052 | } | 1046 | } |
1053 | 1047 | ||
1054 | static void idetape_pad_zeros(ide_drive_t *drive, int bcount) | 1048 | static void idetape_pad_zeros(ide_drive_t *drive, int bcount) |
@@ -1060,8 +1054,7 @@ static void idetape_pad_zeros(ide_drive_t *drive, int bcount) | |||
1060 | while (bcount) { | 1054 | while (bcount) { |
1061 | unsigned int count = min(tape->buffer_size, bcount); | 1055 | unsigned int count = min(tape->buffer_size, bcount); |
1062 | 1056 | ||
1063 | idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, | 1057 | idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, count); |
1064 | count / tape->blk_size); | ||
1065 | bcount -= count; | 1058 | bcount -= count; |
1066 | } | 1059 | } |
1067 | } | 1060 | } |
@@ -1193,7 +1186,6 @@ static ssize_t idetape_chrdev_read(struct file *file, char __user *buf, | |||
1193 | ide_drive_t *drive = tape->drive; | 1186 | ide_drive_t *drive = tape->drive; |
1194 | ssize_t bytes_read, temp, actually_read = 0, rc; | 1187 | ssize_t bytes_read, temp, actually_read = 0, rc; |
1195 | ssize_t ret = 0; | 1188 | ssize_t ret = 0; |
1196 | u16 ctl = *(u16 *)&tape->caps[12]; | ||
1197 | 1189 | ||
1198 | debug_log(DBG_CHRDEV, "Enter %s, count %Zd\n", __func__, count); | 1190 | debug_log(DBG_CHRDEV, "Enter %s, count %Zd\n", __func__, count); |
1199 | 1191 | ||
@@ -1218,7 +1210,8 @@ static ssize_t idetape_chrdev_read(struct file *file, char __user *buf, | |||
1218 | tape->valid -= actually_read; | 1210 | tape->valid -= actually_read; |
1219 | } | 1211 | } |
1220 | while (count >= tape->buffer_size) { | 1212 | while (count >= tape->buffer_size) { |
1221 | bytes_read = idetape_add_chrdev_read_request(drive, ctl); | 1213 | bytes_read = idetape_add_chrdev_read_request(drive, |
1214 | tape->buffer_size); | ||
1222 | if (bytes_read <= 0) | 1215 | if (bytes_read <= 0) |
1223 | goto finish; | 1216 | goto finish; |
1224 | if (copy_to_user(buf, tape->cur, bytes_read)) | 1217 | if (copy_to_user(buf, tape->cur, bytes_read)) |
@@ -1228,7 +1221,8 @@ static ssize_t idetape_chrdev_read(struct file *file, char __user *buf, | |||
1228 | actually_read += bytes_read; | 1221 | actually_read += bytes_read; |
1229 | } | 1222 | } |
1230 | if (count) { | 1223 | if (count) { |
1231 | bytes_read = idetape_add_chrdev_read_request(drive, ctl); | 1224 | bytes_read = idetape_add_chrdev_read_request(drive, |
1225 | tape->buffer_size); | ||
1232 | if (bytes_read <= 0) | 1226 | if (bytes_read <= 0) |
1233 | goto finish; | 1227 | goto finish; |
1234 | temp = min((unsigned long)count, (unsigned long)bytes_read); | 1228 | temp = min((unsigned long)count, (unsigned long)bytes_read); |
@@ -1256,7 +1250,6 @@ static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf, | |||
1256 | ide_drive_t *drive = tape->drive; | 1250 | ide_drive_t *drive = tape->drive; |
1257 | ssize_t actually_written = 0; | 1251 | ssize_t actually_written = 0; |
1258 | ssize_t ret = 0; | 1252 | ssize_t ret = 0; |
1259 | u16 ctl = *(u16 *)&tape->caps[12]; | ||
1260 | int rc; | 1253 | int rc; |
1261 | 1254 | ||
1262 | /* The drive is write protected. */ | 1255 | /* The drive is write protected. */ |
@@ -1284,7 +1277,8 @@ static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf, | |||
1284 | 1277 | ||
1285 | if (tape->valid == tape->buffer_size) { | 1278 | if (tape->valid == tape->buffer_size) { |
1286 | ssize_t retval; | 1279 | ssize_t retval; |
1287 | retval = idetape_add_chrdev_write_request(drive, ctl); | 1280 | retval = idetape_add_chrdev_write_request(drive, |
1281 | tape->buffer_size); | ||
1288 | if (retval <= 0) | 1282 | if (retval <= 0) |
1289 | return (retval); | 1283 | return (retval); |
1290 | } | 1284 | } |
@@ -1295,7 +1289,8 @@ static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf, | |||
1295 | ret = -EFAULT; | 1289 | ret = -EFAULT; |
1296 | buf += tape->buffer_size; | 1290 | buf += tape->buffer_size; |
1297 | count -= tape->buffer_size; | 1291 | count -= tape->buffer_size; |
1298 | retval = idetape_add_chrdev_write_request(drive, ctl); | 1292 | retval = idetape_add_chrdev_write_request(drive, |
1293 | tape->buffer_size); | ||
1299 | actually_written += tape->buffer_size; | 1294 | actually_written += tape->buffer_size; |
1300 | if (retval <= 0) | 1295 | if (retval <= 0) |
1301 | return (retval); | 1296 | return (retval); |