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); |
