diff options
Diffstat (limited to 'drivers/ide/ide-tape.c')
-rw-r--r-- | drivers/ide/ide-tape.c | 822 |
1 files changed, 209 insertions, 613 deletions
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 3a53e0834cf7..4b447a8a49d4 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c | |||
@@ -131,13 +131,6 @@ enum { | |||
131 | IDETAPE_DIR_WRITE = (1 << 2), | 131 | IDETAPE_DIR_WRITE = (1 << 2), |
132 | }; | 132 | }; |
133 | 133 | ||
134 | struct idetape_bh { | ||
135 | u32 b_size; | ||
136 | atomic_t b_count; | ||
137 | struct idetape_bh *b_reqnext; | ||
138 | char *b_data; | ||
139 | }; | ||
140 | |||
141 | /* Tape door status */ | 134 | /* Tape door status */ |
142 | #define DOOR_UNLOCKED 0 | 135 | #define DOOR_UNLOCKED 0 |
143 | #define DOOR_LOCKED 1 | 136 | #define DOOR_LOCKED 1 |
@@ -219,18 +212,12 @@ typedef struct ide_tape_obj { | |||
219 | 212 | ||
220 | /* Data buffer size chosen based on the tape's recommendation */ | 213 | /* Data buffer size chosen based on the tape's recommendation */ |
221 | int buffer_size; | 214 | int buffer_size; |
222 | /* merge buffer */ | 215 | /* Staging buffer of buffer_size bytes */ |
223 | struct idetape_bh *merge_bh; | 216 | void *buf; |
224 | /* size of the merge buffer */ | 217 | /* The read/write cursor */ |
225 | int merge_bh_size; | 218 | void *cur; |
226 | /* pointer to current buffer head within the merge buffer */ | 219 | /* The number of valid bytes in buf */ |
227 | struct idetape_bh *bh; | 220 | size_t valid; |
228 | char *b_data; | ||
229 | int b_count; | ||
230 | |||
231 | int pages_per_buffer; | ||
232 | /* Wasted space in each stage */ | ||
233 | int excess_bh_size; | ||
234 | 221 | ||
235 | /* Measures average tape speed */ | 222 | /* Measures average tape speed */ |
236 | unsigned long avg_time; | 223 | unsigned long avg_time; |
@@ -253,18 +240,27 @@ static struct class *idetape_sysfs_class; | |||
253 | 240 | ||
254 | static void ide_tape_release(struct device *); | 241 | static void ide_tape_release(struct device *); |
255 | 242 | ||
256 | static struct ide_tape_obj *ide_tape_get(struct gendisk *disk) | 243 | static struct ide_tape_obj *idetape_devs[MAX_HWIFS * MAX_DRIVES]; |
244 | |||
245 | static struct ide_tape_obj *ide_tape_get(struct gendisk *disk, bool cdev, | ||
246 | unsigned int i) | ||
257 | { | 247 | { |
258 | struct ide_tape_obj *tape = NULL; | 248 | struct ide_tape_obj *tape = NULL; |
259 | 249 | ||
260 | mutex_lock(&idetape_ref_mutex); | 250 | mutex_lock(&idetape_ref_mutex); |
261 | tape = ide_drv_g(disk, ide_tape_obj); | 251 | |
252 | if (cdev) | ||
253 | tape = idetape_devs[i]; | ||
254 | else | ||
255 | tape = ide_drv_g(disk, ide_tape_obj); | ||
256 | |||
262 | if (tape) { | 257 | if (tape) { |
263 | if (ide_device_get(tape->drive)) | 258 | if (ide_device_get(tape->drive)) |
264 | tape = NULL; | 259 | tape = NULL; |
265 | else | 260 | else |
266 | get_device(&tape->dev); | 261 | get_device(&tape->dev); |
267 | } | 262 | } |
263 | |||
268 | mutex_unlock(&idetape_ref_mutex); | 264 | mutex_unlock(&idetape_ref_mutex); |
269 | return tape; | 265 | return tape; |
270 | } | 266 | } |
@@ -280,102 +276,6 @@ static void ide_tape_put(struct ide_tape_obj *tape) | |||
280 | } | 276 | } |
281 | 277 | ||
282 | /* | 278 | /* |
283 | * The variables below are used for the character device interface. Additional | ||
284 | * state variables are defined in our ide_drive_t structure. | ||
285 | */ | ||
286 | static struct ide_tape_obj *idetape_devs[MAX_HWIFS * MAX_DRIVES]; | ||
287 | |||
288 | static struct ide_tape_obj *ide_tape_chrdev_get(unsigned int i) | ||
289 | { | ||
290 | struct ide_tape_obj *tape = NULL; | ||
291 | |||
292 | mutex_lock(&idetape_ref_mutex); | ||
293 | tape = idetape_devs[i]; | ||
294 | if (tape) | ||
295 | get_device(&tape->dev); | ||
296 | mutex_unlock(&idetape_ref_mutex); | ||
297 | return tape; | ||
298 | } | ||
299 | |||
300 | static int idetape_input_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, | ||
301 | unsigned int bcount) | ||
302 | { | ||
303 | struct idetape_bh *bh = pc->bh; | ||
304 | int count; | ||
305 | |||
306 | while (bcount) { | ||
307 | if (bh == NULL) | ||
308 | break; | ||
309 | count = min( | ||
310 | (unsigned int)(bh->b_size - atomic_read(&bh->b_count)), | ||
311 | bcount); | ||
312 | drive->hwif->tp_ops->input_data(drive, NULL, bh->b_data + | ||
313 | atomic_read(&bh->b_count), count); | ||
314 | bcount -= count; | ||
315 | atomic_add(count, &bh->b_count); | ||
316 | if (atomic_read(&bh->b_count) == bh->b_size) { | ||
317 | bh = bh->b_reqnext; | ||
318 | if (bh) | ||
319 | atomic_set(&bh->b_count, 0); | ||
320 | } | ||
321 | } | ||
322 | |||
323 | pc->bh = bh; | ||
324 | |||
325 | return bcount; | ||
326 | } | ||
327 | |||
328 | static int idetape_output_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, | ||
329 | unsigned int bcount) | ||
330 | { | ||
331 | struct idetape_bh *bh = pc->bh; | ||
332 | int count; | ||
333 | |||
334 | while (bcount) { | ||
335 | if (bh == NULL) | ||
336 | break; | ||
337 | count = min((unsigned int)pc->b_count, (unsigned int)bcount); | ||
338 | drive->hwif->tp_ops->output_data(drive, NULL, pc->b_data, count); | ||
339 | bcount -= count; | ||
340 | pc->b_data += count; | ||
341 | pc->b_count -= count; | ||
342 | if (!pc->b_count) { | ||
343 | bh = bh->b_reqnext; | ||
344 | pc->bh = bh; | ||
345 | if (bh) { | ||
346 | pc->b_data = bh->b_data; | ||
347 | pc->b_count = atomic_read(&bh->b_count); | ||
348 | } | ||
349 | } | ||
350 | } | ||
351 | |||
352 | return bcount; | ||
353 | } | ||
354 | |||
355 | static void idetape_update_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc) | ||
356 | { | ||
357 | struct idetape_bh *bh = pc->bh; | ||
358 | int count; | ||
359 | unsigned int bcount = pc->xferred; | ||
360 | |||
361 | if (pc->flags & PC_FLAG_WRITING) | ||
362 | return; | ||
363 | while (bcount) { | ||
364 | if (bh == NULL) { | ||
365 | printk(KERN_ERR "ide-tape: bh == NULL in %s\n", | ||
366 | __func__); | ||
367 | return; | ||
368 | } | ||
369 | count = min((unsigned int)bh->b_size, (unsigned int)bcount); | ||
370 | atomic_set(&bh->b_count, count); | ||
371 | if (atomic_read(&bh->b_count) == bh->b_size) | ||
372 | bh = bh->b_reqnext; | ||
373 | bcount -= count; | ||
374 | } | ||
375 | pc->bh = bh; | ||
376 | } | ||
377 | |||
378 | /* | ||
379 | * called on each failed packet command retry to analyze the request sense. We | 279 | * called on each failed packet command retry to analyze the request sense. We |
380 | * currently do not utilize this information. | 280 | * currently do not utilize this information. |
381 | */ | 281 | */ |
@@ -392,12 +292,10 @@ static void idetape_analyze_error(ide_drive_t *drive, u8 *sense) | |||
392 | pc->c[0], tape->sense_key, tape->asc, tape->ascq); | 292 | pc->c[0], tape->sense_key, tape->asc, tape->ascq); |
393 | 293 | ||
394 | /* Correct pc->xferred by asking the tape. */ | 294 | /* Correct pc->xferred by asking the tape. */ |
395 | if (pc->flags & PC_FLAG_DMA_ERROR) { | 295 | if (pc->flags & PC_FLAG_DMA_ERROR) |
396 | pc->xferred = pc->req_xfer - | 296 | pc->xferred = pc->req_xfer - |
397 | tape->blk_size * | 297 | tape->blk_size * |
398 | get_unaligned_be32(&sense[3]); | 298 | get_unaligned_be32(&sense[3]); |
399 | idetape_update_buffers(drive, pc); | ||
400 | } | ||
401 | 299 | ||
402 | /* | 300 | /* |
403 | * If error was the result of a zero-length read or write command, | 301 | * If error was the result of a zero-length read or write command, |
@@ -436,29 +334,6 @@ static void idetape_analyze_error(ide_drive_t *drive, u8 *sense) | |||
436 | } | 334 | } |
437 | } | 335 | } |
438 | 336 | ||
439 | /* Free data buffers completely. */ | ||
440 | static void ide_tape_kfree_buffer(idetape_tape_t *tape) | ||
441 | { | ||
442 | struct idetape_bh *prev_bh, *bh = tape->merge_bh; | ||
443 | |||
444 | while (bh) { | ||
445 | u32 size = bh->b_size; | ||
446 | |||
447 | while (size) { | ||
448 | unsigned int order = fls(size >> PAGE_SHIFT)-1; | ||
449 | |||
450 | if (bh->b_data) | ||
451 | free_pages((unsigned long)bh->b_data, order); | ||
452 | |||
453 | size &= (order-1); | ||
454 | bh->b_data += (1 << order) * PAGE_SIZE; | ||
455 | } | ||
456 | prev_bh = bh; | ||
457 | bh = bh->b_reqnext; | ||
458 | kfree(prev_bh); | ||
459 | } | ||
460 | } | ||
461 | |||
462 | static void ide_tape_handle_dsc(ide_drive_t *); | 337 | static void ide_tape_handle_dsc(ide_drive_t *); |
463 | 338 | ||
464 | static int ide_tape_callback(ide_drive_t *drive, int dsc) | 339 | static int ide_tape_callback(ide_drive_t *drive, int dsc) |
@@ -496,7 +371,7 @@ static int ide_tape_callback(ide_drive_t *drive, int dsc) | |||
496 | } | 371 | } |
497 | 372 | ||
498 | tape->first_frame += blocks; | 373 | tape->first_frame += blocks; |
499 | rq->current_nr_sectors -= blocks; | 374 | rq->resid_len -= blocks * tape->blk_size; |
500 | 375 | ||
501 | if (pc->error) { | 376 | if (pc->error) { |
502 | uptodate = 0; | 377 | uptodate = 0; |
@@ -513,7 +388,8 @@ static int ide_tape_callback(ide_drive_t *drive, int dsc) | |||
513 | if (readpos[0] & 0x4) { | 388 | if (readpos[0] & 0x4) { |
514 | printk(KERN_INFO "ide-tape: Block location is unknown" | 389 | printk(KERN_INFO "ide-tape: Block location is unknown" |
515 | "to the tape\n"); | 390 | "to the tape\n"); |
516 | clear_bit(IDE_AFLAG_ADDRESS_VALID, &drive->atapi_flags); | 391 | clear_bit(ilog2(IDE_AFLAG_ADDRESS_VALID), |
392 | &drive->atapi_flags); | ||
517 | uptodate = 0; | 393 | uptodate = 0; |
518 | err = IDE_DRV_ERROR_GENERAL; | 394 | err = IDE_DRV_ERROR_GENERAL; |
519 | } else { | 395 | } else { |
@@ -522,7 +398,8 @@ static int ide_tape_callback(ide_drive_t *drive, int dsc) | |||
522 | 398 | ||
523 | tape->partition = readpos[1]; | 399 | tape->partition = readpos[1]; |
524 | tape->first_frame = be32_to_cpup((__be32 *)&readpos[4]); | 400 | tape->first_frame = be32_to_cpup((__be32 *)&readpos[4]); |
525 | set_bit(IDE_AFLAG_ADDRESS_VALID, &drive->atapi_flags); | 401 | set_bit(ilog2(IDE_AFLAG_ADDRESS_VALID), |
402 | &drive->atapi_flags); | ||
526 | } | 403 | } |
527 | } | 404 | } |
528 | 405 | ||
@@ -558,19 +435,6 @@ static void ide_tape_handle_dsc(ide_drive_t *drive) | |||
558 | idetape_postpone_request(drive); | 435 | idetape_postpone_request(drive); |
559 | } | 436 | } |
560 | 437 | ||
561 | static int ide_tape_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, | ||
562 | unsigned int bcount, int write) | ||
563 | { | ||
564 | unsigned int bleft; | ||
565 | |||
566 | if (write) | ||
567 | bleft = idetape_output_buffers(drive, pc, bcount); | ||
568 | else | ||
569 | bleft = idetape_input_buffers(drive, pc, bcount); | ||
570 | |||
571 | return bcount - bleft; | ||
572 | } | ||
573 | |||
574 | /* | 438 | /* |
575 | * Packet Command Interface | 439 | * Packet Command Interface |
576 | * | 440 | * |
@@ -622,6 +486,8 @@ static ide_startstop_t ide_tape_issue_pc(ide_drive_t *drive, | |||
622 | 486 | ||
623 | if (pc->retries > IDETAPE_MAX_PC_RETRIES || | 487 | if (pc->retries > IDETAPE_MAX_PC_RETRIES || |
624 | (pc->flags & PC_FLAG_ABORT)) { | 488 | (pc->flags & PC_FLAG_ABORT)) { |
489 | unsigned int done = blk_rq_bytes(drive->hwif->rq); | ||
490 | |||
625 | /* | 491 | /* |
626 | * We will "abort" retrying a packet command in case legitimate | 492 | * We will "abort" retrying a packet command in case legitimate |
627 | * error code was received (crossing a filemark, or end of the | 493 | * error code was received (crossing a filemark, or end of the |
@@ -641,8 +507,10 @@ static ide_startstop_t ide_tape_issue_pc(ide_drive_t *drive, | |||
641 | /* Giving up */ | 507 | /* Giving up */ |
642 | pc->error = IDE_DRV_ERROR_GENERAL; | 508 | pc->error = IDE_DRV_ERROR_GENERAL; |
643 | } | 509 | } |
510 | |||
644 | drive->failed_pc = NULL; | 511 | drive->failed_pc = NULL; |
645 | drive->pc_callback(drive, 0); | 512 | drive->pc_callback(drive, 0); |
513 | ide_complete_rq(drive, -EIO, done); | ||
646 | return ide_stopped; | 514 | return ide_stopped; |
647 | } | 515 | } |
648 | debug_log(DBG_SENSE, "Retry #%d, cmd = %02X\n", pc->retries, pc->c[0]); | 516 | debug_log(DBG_SENSE, "Retry #%d, cmd = %02X\n", pc->retries, pc->c[0]); |
@@ -695,7 +563,7 @@ static ide_startstop_t idetape_media_access_finished(ide_drive_t *drive) | |||
695 | printk(KERN_ERR "ide-tape: %s: I/O error, ", | 563 | printk(KERN_ERR "ide-tape: %s: I/O error, ", |
696 | tape->name); | 564 | tape->name); |
697 | /* Retry operation */ | 565 | /* Retry operation */ |
698 | ide_retry_pc(drive, tape->disk); | 566 | ide_retry_pc(drive); |
699 | return ide_stopped; | 567 | return ide_stopped; |
700 | } | 568 | } |
701 | pc->error = 0; | 569 | pc->error = 0; |
@@ -711,27 +579,22 @@ static void ide_tape_create_rw_cmd(idetape_tape_t *tape, | |||
711 | struct ide_atapi_pc *pc, struct request *rq, | 579 | struct ide_atapi_pc *pc, struct request *rq, |
712 | u8 opcode) | 580 | u8 opcode) |
713 | { | 581 | { |
714 | struct idetape_bh *bh = (struct idetape_bh *)rq->special; | 582 | unsigned int length = blk_rq_sectors(rq); |
715 | unsigned int length = rq->current_nr_sectors; | ||
716 | 583 | ||
717 | ide_init_pc(pc); | 584 | ide_init_pc(pc); |
718 | put_unaligned(cpu_to_be32(length), (unsigned int *) &pc->c[1]); | 585 | put_unaligned(cpu_to_be32(length), (unsigned int *) &pc->c[1]); |
719 | pc->c[1] = 1; | 586 | pc->c[1] = 1; |
720 | pc->bh = bh; | ||
721 | pc->buf = NULL; | 587 | pc->buf = NULL; |
722 | pc->buf_size = length * tape->blk_size; | 588 | pc->buf_size = length * tape->blk_size; |
723 | pc->req_xfer = pc->buf_size; | 589 | pc->req_xfer = pc->buf_size; |
724 | if (pc->req_xfer == tape->buffer_size) | 590 | if (pc->req_xfer == tape->buffer_size) |
725 | pc->flags |= PC_FLAG_DMA_OK; | 591 | pc->flags |= PC_FLAG_DMA_OK; |
726 | 592 | ||
727 | if (opcode == READ_6) { | 593 | if (opcode == READ_6) |
728 | pc->c[0] = READ_6; | 594 | pc->c[0] = READ_6; |
729 | atomic_set(&bh->b_count, 0); | 595 | else if (opcode == WRITE_6) { |
730 | } else if (opcode == WRITE_6) { | ||
731 | pc->c[0] = WRITE_6; | 596 | pc->c[0] = WRITE_6; |
732 | pc->flags |= PC_FLAG_WRITING; | 597 | pc->flags |= PC_FLAG_WRITING; |
733 | pc->b_data = bh->b_data; | ||
734 | pc->b_count = atomic_read(&bh->b_count); | ||
735 | } | 598 | } |
736 | 599 | ||
737 | memcpy(rq->cmd, pc->c, 12); | 600 | memcpy(rq->cmd, pc->c, 12); |
@@ -747,12 +610,10 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive, | |||
747 | struct ide_cmd cmd; | 610 | struct ide_cmd cmd; |
748 | u8 stat; | 611 | u8 stat; |
749 | 612 | ||
750 | debug_log(DBG_SENSE, "sector: %llu, nr_sectors: %lu," | 613 | debug_log(DBG_SENSE, "sector: %llu, nr_sectors: %u\n" |
751 | " current_nr_sectors: %u\n", | 614 | (unsigned long long)blk_rq_pos(rq), blk_rq_sectors(rq)); |
752 | (unsigned long long)rq->sector, rq->nr_sectors, | ||
753 | rq->current_nr_sectors); | ||
754 | 615 | ||
755 | if (!blk_special_request(rq)) { | 616 | if (!(blk_special_request(rq) || blk_sense_request(rq))) { |
756 | /* We do not support buffer cache originated requests. */ | 617 | /* We do not support buffer cache originated requests. */ |
757 | printk(KERN_NOTICE "ide-tape: %s: Unsupported request in " | 618 | printk(KERN_NOTICE "ide-tape: %s: Unsupported request in " |
758 | "request queue (%d)\n", drive->name, rq->cmd_type); | 619 | "request queue (%d)\n", drive->name, rq->cmd_type); |
@@ -788,15 +649,15 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive, | |||
788 | 649 | ||
789 | if ((drive->dev_flags & IDE_DFLAG_DSC_OVERLAP) == 0 && | 650 | if ((drive->dev_flags & IDE_DFLAG_DSC_OVERLAP) == 0 && |
790 | (rq->cmd[13] & REQ_IDETAPE_PC2) == 0) | 651 | (rq->cmd[13] & REQ_IDETAPE_PC2) == 0) |
791 | set_bit(IDE_AFLAG_IGNORE_DSC, &drive->atapi_flags); | 652 | drive->atapi_flags |= IDE_AFLAG_IGNORE_DSC; |
792 | 653 | ||
793 | if (drive->dev_flags & IDE_DFLAG_POST_RESET) { | 654 | if (drive->dev_flags & IDE_DFLAG_POST_RESET) { |
794 | set_bit(IDE_AFLAG_IGNORE_DSC, &drive->atapi_flags); | 655 | drive->atapi_flags |= IDE_AFLAG_IGNORE_DSC; |
795 | drive->dev_flags &= ~IDE_DFLAG_POST_RESET; | 656 | drive->dev_flags &= ~IDE_DFLAG_POST_RESET; |
796 | } | 657 | } |
797 | 658 | ||
798 | if (!test_and_clear_bit(IDE_AFLAG_IGNORE_DSC, &drive->atapi_flags) && | 659 | if (!(drive->atapi_flags & IDE_AFLAG_IGNORE_DSC) && |
799 | (stat & ATA_DSC) == 0) { | 660 | !(stat & ATA_DSC)) { |
800 | if (postponed_rq == NULL) { | 661 | if (postponed_rq == NULL) { |
801 | tape->dsc_polling_start = jiffies; | 662 | tape->dsc_polling_start = jiffies; |
802 | tape->dsc_poll_freq = tape->best_dsc_rw_freq; | 663 | tape->dsc_poll_freq = tape->best_dsc_rw_freq; |
@@ -816,7 +677,9 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive, | |||
816 | tape->dsc_poll_freq = IDETAPE_DSC_MA_SLOW; | 677 | tape->dsc_poll_freq = IDETAPE_DSC_MA_SLOW; |
817 | idetape_postpone_request(drive); | 678 | idetape_postpone_request(drive); |
818 | return ide_stopped; | 679 | return ide_stopped; |
819 | } | 680 | } else |
681 | drive->atapi_flags &= ~IDE_AFLAG_IGNORE_DSC; | ||
682 | |||
820 | if (rq->cmd[13] & REQ_IDETAPE_READ) { | 683 | if (rq->cmd[13] & REQ_IDETAPE_READ) { |
821 | pc = &tape->queued_pc; | 684 | pc = &tape->queued_pc; |
822 | ide_tape_create_rw_cmd(tape, pc, rq, READ_6); | 685 | ide_tape_create_rw_cmd(tape, pc, rq, READ_6); |
@@ -828,7 +691,7 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive, | |||
828 | goto out; | 691 | goto out; |
829 | } | 692 | } |
830 | if (rq->cmd[13] & REQ_IDETAPE_PC1) { | 693 | if (rq->cmd[13] & REQ_IDETAPE_PC1) { |
831 | pc = (struct ide_atapi_pc *) rq->buffer; | 694 | pc = (struct ide_atapi_pc *)rq->special; |
832 | rq->cmd[13] &= ~(REQ_IDETAPE_PC1); | 695 | rq->cmd[13] &= ~(REQ_IDETAPE_PC1); |
833 | rq->cmd[13] |= REQ_IDETAPE_PC2; | 696 | rq->cmd[13] |= REQ_IDETAPE_PC2; |
834 | goto out; | 697 | goto out; |
@@ -840,6 +703,9 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive, | |||
840 | BUG(); | 703 | BUG(); |
841 | 704 | ||
842 | out: | 705 | out: |
706 | /* prepare sense request for this command */ | ||
707 | ide_prep_sense(drive, rq); | ||
708 | |||
843 | memset(&cmd, 0, sizeof(cmd)); | 709 | memset(&cmd, 0, sizeof(cmd)); |
844 | 710 | ||
845 | if (rq_data_dir(rq)) | 711 | if (rq_data_dir(rq)) |
@@ -847,167 +713,10 @@ out: | |||
847 | 713 | ||
848 | cmd.rq = rq; | 714 | cmd.rq = rq; |
849 | 715 | ||
850 | return ide_tape_issue_pc(drive, &cmd, pc); | 716 | ide_init_sg_cmd(&cmd, pc->req_xfer); |
851 | } | 717 | ide_map_sg(drive, &cmd); |
852 | |||
853 | /* | ||
854 | * The function below uses __get_free_pages to allocate a data buffer of size | ||
855 | * tape->buffer_size (or a bit more). We attempt to combine sequential pages as | ||
856 | * much as possible. | ||
857 | * | ||
858 | * It returns a pointer to the newly allocated buffer, or NULL in case of | ||
859 | * failure. | ||
860 | */ | ||
861 | static struct idetape_bh *ide_tape_kmalloc_buffer(idetape_tape_t *tape, | ||
862 | int full, int clear) | ||
863 | { | ||
864 | struct idetape_bh *prev_bh, *bh, *merge_bh; | ||
865 | int pages = tape->pages_per_buffer; | ||
866 | unsigned int order, b_allocd; | ||
867 | char *b_data = NULL; | ||
868 | |||
869 | merge_bh = kmalloc(sizeof(struct idetape_bh), GFP_KERNEL); | ||
870 | bh = merge_bh; | ||
871 | if (bh == NULL) | ||
872 | goto abort; | ||
873 | |||
874 | order = fls(pages) - 1; | ||
875 | bh->b_data = (char *) __get_free_pages(GFP_KERNEL, order); | ||
876 | if (!bh->b_data) | ||
877 | goto abort; | ||
878 | b_allocd = (1 << order) * PAGE_SIZE; | ||
879 | pages &= (order-1); | ||
880 | |||
881 | if (clear) | ||
882 | memset(bh->b_data, 0, b_allocd); | ||
883 | bh->b_reqnext = NULL; | ||
884 | bh->b_size = b_allocd; | ||
885 | atomic_set(&bh->b_count, full ? bh->b_size : 0); | ||
886 | |||
887 | while (pages) { | ||
888 | order = fls(pages) - 1; | ||
889 | b_data = (char *) __get_free_pages(GFP_KERNEL, order); | ||
890 | if (!b_data) | ||
891 | goto abort; | ||
892 | b_allocd = (1 << order) * PAGE_SIZE; | ||
893 | |||
894 | if (clear) | ||
895 | memset(b_data, 0, b_allocd); | ||
896 | |||
897 | /* newly allocated page frames below buffer header or ...*/ | ||
898 | if (bh->b_data == b_data + b_allocd) { | ||
899 | bh->b_size += b_allocd; | ||
900 | bh->b_data -= b_allocd; | ||
901 | if (full) | ||
902 | atomic_add(b_allocd, &bh->b_count); | ||
903 | continue; | ||
904 | } | ||
905 | /* they are above the header */ | ||
906 | if (b_data == bh->b_data + bh->b_size) { | ||
907 | bh->b_size += b_allocd; | ||
908 | if (full) | ||
909 | atomic_add(b_allocd, &bh->b_count); | ||
910 | continue; | ||
911 | } | ||
912 | prev_bh = bh; | ||
913 | bh = kmalloc(sizeof(struct idetape_bh), GFP_KERNEL); | ||
914 | if (!bh) { | ||
915 | free_pages((unsigned long) b_data, order); | ||
916 | goto abort; | ||
917 | } | ||
918 | bh->b_reqnext = NULL; | ||
919 | bh->b_data = b_data; | ||
920 | bh->b_size = b_allocd; | ||
921 | atomic_set(&bh->b_count, full ? bh->b_size : 0); | ||
922 | prev_bh->b_reqnext = bh; | ||
923 | |||
924 | pages &= (order-1); | ||
925 | } | ||
926 | |||
927 | bh->b_size -= tape->excess_bh_size; | ||
928 | if (full) | ||
929 | atomic_sub(tape->excess_bh_size, &bh->b_count); | ||
930 | return merge_bh; | ||
931 | abort: | ||
932 | ide_tape_kfree_buffer(tape); | ||
933 | return NULL; | ||
934 | } | ||
935 | |||
936 | static int idetape_copy_stage_from_user(idetape_tape_t *tape, | ||
937 | const char __user *buf, int n) | ||
938 | { | ||
939 | struct idetape_bh *bh = tape->bh; | ||
940 | int count; | ||
941 | int ret = 0; | ||
942 | |||
943 | while (n) { | ||
944 | if (bh == NULL) { | ||
945 | printk(KERN_ERR "ide-tape: bh == NULL in %s\n", | ||
946 | __func__); | ||
947 | return 1; | ||
948 | } | ||
949 | count = min((unsigned int) | ||
950 | (bh->b_size - atomic_read(&bh->b_count)), | ||
951 | (unsigned int)n); | ||
952 | if (copy_from_user(bh->b_data + atomic_read(&bh->b_count), buf, | ||
953 | count)) | ||
954 | ret = 1; | ||
955 | n -= count; | ||
956 | atomic_add(count, &bh->b_count); | ||
957 | buf += count; | ||
958 | if (atomic_read(&bh->b_count) == bh->b_size) { | ||
959 | bh = bh->b_reqnext; | ||
960 | if (bh) | ||
961 | atomic_set(&bh->b_count, 0); | ||
962 | } | ||
963 | } | ||
964 | tape->bh = bh; | ||
965 | return ret; | ||
966 | } | ||
967 | 718 | ||
968 | static int idetape_copy_stage_to_user(idetape_tape_t *tape, char __user *buf, | 719 | return ide_tape_issue_pc(drive, &cmd, pc); |
969 | int n) | ||
970 | { | ||
971 | struct idetape_bh *bh = tape->bh; | ||
972 | int count; | ||
973 | int ret = 0; | ||
974 | |||
975 | while (n) { | ||
976 | if (bh == NULL) { | ||
977 | printk(KERN_ERR "ide-tape: bh == NULL in %s\n", | ||
978 | __func__); | ||
979 | return 1; | ||
980 | } | ||
981 | count = min(tape->b_count, n); | ||
982 | if (copy_to_user(buf, tape->b_data, count)) | ||
983 | ret = 1; | ||
984 | n -= count; | ||
985 | tape->b_data += count; | ||
986 | tape->b_count -= count; | ||
987 | buf += count; | ||
988 | if (!tape->b_count) { | ||
989 | bh = bh->b_reqnext; | ||
990 | tape->bh = bh; | ||
991 | if (bh) { | ||
992 | tape->b_data = bh->b_data; | ||
993 | tape->b_count = atomic_read(&bh->b_count); | ||
994 | } | ||
995 | } | ||
996 | } | ||
997 | return ret; | ||
998 | } | ||
999 | |||
1000 | static void idetape_init_merge_buffer(idetape_tape_t *tape) | ||
1001 | { | ||
1002 | struct idetape_bh *bh = tape->merge_bh; | ||
1003 | tape->bh = tape->merge_bh; | ||
1004 | |||
1005 | if (tape->chrdev_dir == IDETAPE_DIR_WRITE) | ||
1006 | atomic_set(&bh->b_count, 0); | ||
1007 | else { | ||
1008 | tape->b_data = bh->b_data; | ||
1009 | tape->b_count = atomic_read(&bh->b_count); | ||
1010 | } | ||
1011 | } | 720 | } |
1012 | 721 | ||
1013 | /* | 722 | /* |
@@ -1030,7 +739,7 @@ static int idetape_wait_ready(ide_drive_t *drive, unsigned long timeout) | |||
1030 | int load_attempted = 0; | 739 | int load_attempted = 0; |
1031 | 740 | ||
1032 | /* Wait for the tape to become ready */ | 741 | /* Wait for the tape to become ready */ |
1033 | set_bit(IDE_AFLAG_MEDIUM_PRESENT, &drive->atapi_flags); | 742 | set_bit(ilog2(IDE_AFLAG_MEDIUM_PRESENT), &drive->atapi_flags); |
1034 | timeout += jiffies; | 743 | timeout += jiffies; |
1035 | while (time_before(jiffies, timeout)) { | 744 | while (time_before(jiffies, timeout)) { |
1036 | if (ide_do_test_unit_ready(drive, disk) == 0) | 745 | if (ide_do_test_unit_ready(drive, disk) == 0) |
@@ -1106,11 +815,11 @@ static void __ide_tape_discard_merge_buffer(ide_drive_t *drive) | |||
1106 | if (tape->chrdev_dir != IDETAPE_DIR_READ) | 815 | if (tape->chrdev_dir != IDETAPE_DIR_READ) |
1107 | return; | 816 | return; |
1108 | 817 | ||
1109 | clear_bit(IDE_AFLAG_FILEMARK, &drive->atapi_flags); | 818 | clear_bit(ilog2(IDE_AFLAG_FILEMARK), &drive->atapi_flags); |
1110 | tape->merge_bh_size = 0; | 819 | tape->valid = 0; |
1111 | if (tape->merge_bh != NULL) { | 820 | if (tape->buf != NULL) { |
1112 | ide_tape_kfree_buffer(tape); | 821 | kfree(tape->buf); |
1113 | tape->merge_bh = NULL; | 822 | tape->buf = NULL; |
1114 | } | 823 | } |
1115 | 824 | ||
1116 | tape->chrdev_dir = IDETAPE_DIR_NONE; | 825 | tape->chrdev_dir = IDETAPE_DIR_NONE; |
@@ -1164,36 +873,44 @@ static void ide_tape_discard_merge_buffer(ide_drive_t *drive, | |||
1164 | * Generate a read/write request for the block device interface and wait for it | 873 | * Generate a read/write request for the block device interface and wait for it |
1165 | * to be serviced. | 874 | * to be serviced. |
1166 | */ | 875 | */ |
1167 | static int idetape_queue_rw_tail(ide_drive_t *drive, int cmd, int blocks, | 876 | static int idetape_queue_rw_tail(ide_drive_t *drive, int cmd, int size) |
1168 | struct idetape_bh *bh) | ||
1169 | { | 877 | { |
1170 | idetape_tape_t *tape = drive->driver_data; | 878 | idetape_tape_t *tape = drive->driver_data; |
1171 | struct request *rq; | 879 | struct request *rq; |
1172 | int ret, errors; | 880 | int ret; |
1173 | 881 | ||
1174 | debug_log(DBG_SENSE, "%s: cmd=%d\n", __func__, cmd); | 882 | debug_log(DBG_SENSE, "%s: cmd=%d\n", __func__, cmd); |
883 | BUG_ON(cmd != REQ_IDETAPE_READ && cmd != REQ_IDETAPE_WRITE); | ||
884 | BUG_ON(size < 0 || size % tape->blk_size); | ||
1175 | 885 | ||
1176 | rq = blk_get_request(drive->queue, READ, __GFP_WAIT); | 886 | rq = blk_get_request(drive->queue, READ, __GFP_WAIT); |
1177 | rq->cmd_type = REQ_TYPE_SPECIAL; | 887 | rq->cmd_type = REQ_TYPE_SPECIAL; |
1178 | rq->cmd[13] = cmd; | 888 | rq->cmd[13] = cmd; |
1179 | rq->rq_disk = tape->disk; | 889 | rq->rq_disk = tape->disk; |
1180 | rq->special = (void *)bh; | 890 | rq->__sector = tape->first_frame; |
1181 | rq->sector = tape->first_frame; | ||
1182 | rq->nr_sectors = blocks; | ||
1183 | rq->current_nr_sectors = blocks; | ||
1184 | blk_execute_rq(drive->queue, tape->disk, rq, 0); | ||
1185 | 891 | ||
1186 | errors = rq->errors; | 892 | if (size) { |
1187 | ret = tape->blk_size * (blocks - rq->current_nr_sectors); | 893 | ret = blk_rq_map_kern(drive->queue, rq, tape->buf, size, |
1188 | blk_put_request(rq); | 894 | __GFP_WAIT); |
895 | if (ret) | ||
896 | goto out_put; | ||
897 | } | ||
1189 | 898 | ||
1190 | if ((cmd & (REQ_IDETAPE_READ | REQ_IDETAPE_WRITE)) == 0) | 899 | blk_execute_rq(drive->queue, tape->disk, rq, 0); |
1191 | return 0; | ||
1192 | 900 | ||
1193 | if (tape->merge_bh) | 901 | /* calculate the number of transferred bytes and update buffer state */ |
1194 | idetape_init_merge_buffer(tape); | 902 | size -= rq->resid_len; |
1195 | if (errors == IDE_DRV_ERROR_GENERAL) | 903 | tape->cur = tape->buf; |
1196 | return -EIO; | 904 | if (cmd == REQ_IDETAPE_READ) |
905 | tape->valid = size; | ||
906 | else | ||
907 | tape->valid = 0; | ||
908 | |||
909 | ret = size; | ||
910 | if (rq->errors == IDE_DRV_ERROR_GENERAL) | ||
911 | ret = -EIO; | ||
912 | out_put: | ||
913 | blk_put_request(rq); | ||
1197 | return ret; | 914 | return ret; |
1198 | } | 915 | } |
1199 | 916 | ||
@@ -1230,153 +947,87 @@ static void idetape_create_space_cmd(struct ide_atapi_pc *pc, int count, u8 cmd) | |||
1230 | pc->flags |= PC_FLAG_WAIT_FOR_DSC; | 947 | pc->flags |= PC_FLAG_WAIT_FOR_DSC; |
1231 | } | 948 | } |
1232 | 949 | ||
1233 | /* Queue up a character device originated write request. */ | ||
1234 | static int idetape_add_chrdev_write_request(ide_drive_t *drive, int blocks) | ||
1235 | { | ||
1236 | idetape_tape_t *tape = drive->driver_data; | ||
1237 | |||
1238 | debug_log(DBG_CHRDEV, "Enter %s\n", __func__); | ||
1239 | |||
1240 | return idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, | ||
1241 | blocks, tape->merge_bh); | ||
1242 | } | ||
1243 | |||
1244 | static void ide_tape_flush_merge_buffer(ide_drive_t *drive) | 950 | static void ide_tape_flush_merge_buffer(ide_drive_t *drive) |
1245 | { | 951 | { |
1246 | idetape_tape_t *tape = drive->driver_data; | 952 | idetape_tape_t *tape = drive->driver_data; |
1247 | int blocks, min; | ||
1248 | struct idetape_bh *bh; | ||
1249 | 953 | ||
1250 | if (tape->chrdev_dir != IDETAPE_DIR_WRITE) { | 954 | if (tape->chrdev_dir != IDETAPE_DIR_WRITE) { |
1251 | printk(KERN_ERR "ide-tape: bug: Trying to empty merge buffer" | 955 | printk(KERN_ERR "ide-tape: bug: Trying to empty merge buffer" |
1252 | " but we are not writing.\n"); | 956 | " but we are not writing.\n"); |
1253 | return; | 957 | return; |
1254 | } | 958 | } |
1255 | if (tape->merge_bh_size > tape->buffer_size) { | 959 | if (tape->buf) { |
1256 | printk(KERN_ERR "ide-tape: bug: merge_buffer too big\n"); | 960 | size_t aligned = roundup(tape->valid, tape->blk_size); |
1257 | tape->merge_bh_size = tape->buffer_size; | 961 | |
1258 | } | 962 | memset(tape->cur, 0, aligned - tape->valid); |
1259 | if (tape->merge_bh_size) { | 963 | idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, aligned); |
1260 | blocks = tape->merge_bh_size / tape->blk_size; | 964 | kfree(tape->buf); |
1261 | if (tape->merge_bh_size % tape->blk_size) { | 965 | tape->buf = NULL; |
1262 | unsigned int i; | ||
1263 | |||
1264 | blocks++; | ||
1265 | i = tape->blk_size - tape->merge_bh_size % | ||
1266 | tape->blk_size; | ||
1267 | bh = tape->bh->b_reqnext; | ||
1268 | while (bh) { | ||
1269 | atomic_set(&bh->b_count, 0); | ||
1270 | bh = bh->b_reqnext; | ||
1271 | } | ||
1272 | bh = tape->bh; | ||
1273 | while (i) { | ||
1274 | if (bh == NULL) { | ||
1275 | printk(KERN_INFO "ide-tape: bug," | ||
1276 | " bh NULL\n"); | ||
1277 | break; | ||
1278 | } | ||
1279 | min = min(i, (unsigned int)(bh->b_size - | ||
1280 | atomic_read(&bh->b_count))); | ||
1281 | memset(bh->b_data + atomic_read(&bh->b_count), | ||
1282 | 0, min); | ||
1283 | atomic_add(min, &bh->b_count); | ||
1284 | i -= min; | ||
1285 | bh = bh->b_reqnext; | ||
1286 | } | ||
1287 | } | ||
1288 | (void) idetape_add_chrdev_write_request(drive, blocks); | ||
1289 | tape->merge_bh_size = 0; | ||
1290 | } | ||
1291 | if (tape->merge_bh != NULL) { | ||
1292 | ide_tape_kfree_buffer(tape); | ||
1293 | tape->merge_bh = NULL; | ||
1294 | } | 966 | } |
1295 | tape->chrdev_dir = IDETAPE_DIR_NONE; | 967 | tape->chrdev_dir = IDETAPE_DIR_NONE; |
1296 | } | 968 | } |
1297 | 969 | ||
1298 | static int idetape_init_read(ide_drive_t *drive) | 970 | static int idetape_init_rw(ide_drive_t *drive, int dir) |
1299 | { | 971 | { |
1300 | idetape_tape_t *tape = drive->driver_data; | 972 | idetape_tape_t *tape = drive->driver_data; |
1301 | int bytes_read; | 973 | int rc; |
1302 | |||
1303 | /* Initialize read operation */ | ||
1304 | if (tape->chrdev_dir != IDETAPE_DIR_READ) { | ||
1305 | if (tape->chrdev_dir == IDETAPE_DIR_WRITE) { | ||
1306 | ide_tape_flush_merge_buffer(drive); | ||
1307 | idetape_flush_tape_buffers(drive); | ||
1308 | } | ||
1309 | if (tape->merge_bh || tape->merge_bh_size) { | ||
1310 | printk(KERN_ERR "ide-tape: merge_bh_size should be" | ||
1311 | " 0 now\n"); | ||
1312 | tape->merge_bh_size = 0; | ||
1313 | } | ||
1314 | tape->merge_bh = ide_tape_kmalloc_buffer(tape, 0, 0); | ||
1315 | if (!tape->merge_bh) | ||
1316 | return -ENOMEM; | ||
1317 | tape->chrdev_dir = IDETAPE_DIR_READ; | ||
1318 | 974 | ||
1319 | /* | 975 | BUG_ON(dir != IDETAPE_DIR_READ && dir != IDETAPE_DIR_WRITE); |
1320 | * Issue a read 0 command to ensure that DSC handshake is | ||
1321 | * switched from completion mode to buffer available mode. | ||
1322 | * No point in issuing this if DSC overlap isn't supported, some | ||
1323 | * drives (Seagate STT3401A) will return an error. | ||
1324 | */ | ||
1325 | if (drive->dev_flags & IDE_DFLAG_DSC_OVERLAP) { | ||
1326 | bytes_read = idetape_queue_rw_tail(drive, | ||
1327 | REQ_IDETAPE_READ, 0, | ||
1328 | tape->merge_bh); | ||
1329 | if (bytes_read < 0) { | ||
1330 | ide_tape_kfree_buffer(tape); | ||
1331 | tape->merge_bh = NULL; | ||
1332 | tape->chrdev_dir = IDETAPE_DIR_NONE; | ||
1333 | return bytes_read; | ||
1334 | } | ||
1335 | } | ||
1336 | } | ||
1337 | 976 | ||
1338 | return 0; | 977 | if (tape->chrdev_dir == dir) |
1339 | } | 978 | return 0; |
1340 | 979 | ||
1341 | /* called from idetape_chrdev_read() to service a chrdev read request. */ | 980 | if (tape->chrdev_dir == IDETAPE_DIR_READ) |
1342 | static int idetape_add_chrdev_read_request(ide_drive_t *drive, int blocks) | 981 | ide_tape_discard_merge_buffer(drive, 1); |
1343 | { | 982 | else if (tape->chrdev_dir == IDETAPE_DIR_WRITE) { |
1344 | idetape_tape_t *tape = drive->driver_data; | 983 | ide_tape_flush_merge_buffer(drive); |
984 | idetape_flush_tape_buffers(drive); | ||
985 | } | ||
1345 | 986 | ||
1346 | debug_log(DBG_PROCS, "Enter %s, %d blocks\n", __func__, blocks); | 987 | if (tape->buf || tape->valid) { |
988 | printk(KERN_ERR "ide-tape: valid should be 0 now\n"); | ||
989 | tape->valid = 0; | ||
990 | } | ||
1347 | 991 | ||
1348 | /* If we are at a filemark, return a read length of 0 */ | 992 | tape->buf = kmalloc(tape->buffer_size, GFP_KERNEL); |
1349 | if (test_bit(IDE_AFLAG_FILEMARK, &drive->atapi_flags)) | 993 | if (!tape->buf) |
1350 | return 0; | 994 | return -ENOMEM; |
995 | tape->chrdev_dir = dir; | ||
996 | tape->cur = tape->buf; | ||
1351 | 997 | ||
1352 | idetape_init_read(drive); | 998 | /* |
999 | * Issue a 0 rw command to ensure that DSC handshake is | ||
1000 | * switched from completion mode to buffer available mode. No | ||
1001 | * point in issuing this if DSC overlap isn't supported, some | ||
1002 | * drives (Seagate STT3401A) will return an error. | ||
1003 | */ | ||
1004 | if (drive->dev_flags & IDE_DFLAG_DSC_OVERLAP) { | ||
1005 | int cmd = dir == IDETAPE_DIR_READ ? REQ_IDETAPE_READ | ||
1006 | : REQ_IDETAPE_WRITE; | ||
1007 | |||
1008 | rc = idetape_queue_rw_tail(drive, cmd, 0); | ||
1009 | if (rc < 0) { | ||
1010 | kfree(tape->buf); | ||
1011 | tape->buf = NULL; | ||
1012 | tape->chrdev_dir = IDETAPE_DIR_NONE; | ||
1013 | return rc; | ||
1014 | } | ||
1015 | } | ||
1353 | 1016 | ||
1354 | return idetape_queue_rw_tail(drive, REQ_IDETAPE_READ, blocks, | 1017 | return 0; |
1355 | tape->merge_bh); | ||
1356 | } | 1018 | } |
1357 | 1019 | ||
1358 | static void idetape_pad_zeros(ide_drive_t *drive, int bcount) | 1020 | static void idetape_pad_zeros(ide_drive_t *drive, int bcount) |
1359 | { | 1021 | { |
1360 | idetape_tape_t *tape = drive->driver_data; | 1022 | idetape_tape_t *tape = drive->driver_data; |
1361 | struct idetape_bh *bh; | 1023 | |
1362 | int blocks; | 1024 | memset(tape->buf, 0, tape->buffer_size); |
1363 | 1025 | ||
1364 | while (bcount) { | 1026 | while (bcount) { |
1365 | unsigned int count; | 1027 | unsigned int count = min(tape->buffer_size, bcount); |
1366 | 1028 | ||
1367 | bh = tape->merge_bh; | 1029 | idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, count); |
1368 | count = min(tape->buffer_size, bcount); | ||
1369 | bcount -= count; | 1030 | bcount -= count; |
1370 | blocks = count / tape->blk_size; | ||
1371 | while (count) { | ||
1372 | atomic_set(&bh->b_count, | ||
1373 | min(count, (unsigned int)bh->b_size)); | ||
1374 | memset(bh->b_data, 0, atomic_read(&bh->b_count)); | ||
1375 | count -= atomic_read(&bh->b_count); | ||
1376 | bh = bh->b_reqnext; | ||
1377 | } | ||
1378 | idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, blocks, | ||
1379 | tape->merge_bh); | ||
1380 | } | 1031 | } |
1381 | } | 1032 | } |
1382 | 1033 | ||
@@ -1456,8 +1107,9 @@ static int idetape_space_over_filemarks(ide_drive_t *drive, short mt_op, | |||
1456 | } | 1107 | } |
1457 | 1108 | ||
1458 | if (tape->chrdev_dir == IDETAPE_DIR_READ) { | 1109 | if (tape->chrdev_dir == IDETAPE_DIR_READ) { |
1459 | tape->merge_bh_size = 0; | 1110 | tape->valid = 0; |
1460 | if (test_and_clear_bit(IDE_AFLAG_FILEMARK, &drive->atapi_flags)) | 1111 | if (test_and_clear_bit(ilog2(IDE_AFLAG_FILEMARK), |
1112 | &drive->atapi_flags)) | ||
1461 | ++count; | 1113 | ++count; |
1462 | ide_tape_discard_merge_buffer(drive, 0); | 1114 | ide_tape_discard_merge_buffer(drive, 0); |
1463 | } | 1115 | } |
@@ -1505,61 +1157,56 @@ static ssize_t idetape_chrdev_read(struct file *file, char __user *buf, | |||
1505 | { | 1157 | { |
1506 | struct ide_tape_obj *tape = file->private_data; | 1158 | struct ide_tape_obj *tape = file->private_data; |
1507 | ide_drive_t *drive = tape->drive; | 1159 | ide_drive_t *drive = tape->drive; |
1508 | ssize_t bytes_read, temp, actually_read = 0, rc; | 1160 | size_t done = 0; |
1509 | ssize_t ret = 0; | 1161 | ssize_t ret = 0; |
1510 | u16 ctl = *(u16 *)&tape->caps[12]; | 1162 | int rc; |
1511 | 1163 | ||
1512 | debug_log(DBG_CHRDEV, "Enter %s, count %Zd\n", __func__, count); | 1164 | debug_log(DBG_CHRDEV, "Enter %s, count %Zd\n", __func__, count); |
1513 | 1165 | ||
1514 | if (tape->chrdev_dir != IDETAPE_DIR_READ) { | 1166 | if (tape->chrdev_dir != IDETAPE_DIR_READ) { |
1515 | if (test_bit(IDE_AFLAG_DETECT_BS, &drive->atapi_flags)) | 1167 | if (test_bit(ilog2(IDE_AFLAG_DETECT_BS), &drive->atapi_flags)) |
1516 | if (count > tape->blk_size && | 1168 | if (count > tape->blk_size && |
1517 | (count % tape->blk_size) == 0) | 1169 | (count % tape->blk_size) == 0) |
1518 | tape->user_bs_factor = count / tape->blk_size; | 1170 | tape->user_bs_factor = count / tape->blk_size; |
1519 | } | 1171 | } |
1520 | rc = idetape_init_read(drive); | 1172 | |
1173 | rc = idetape_init_rw(drive, IDETAPE_DIR_READ); | ||
1521 | if (rc < 0) | 1174 | if (rc < 0) |
1522 | return rc; | 1175 | return rc; |
1523 | if (count == 0) | 1176 | |
1524 | return (0); | 1177 | while (done < count) { |
1525 | if (tape->merge_bh_size) { | 1178 | size_t todo; |
1526 | actually_read = min((unsigned int)(tape->merge_bh_size), | 1179 | |
1527 | (unsigned int)count); | 1180 | /* refill if staging buffer is empty */ |
1528 | if (idetape_copy_stage_to_user(tape, buf, actually_read)) | 1181 | if (!tape->valid) { |
1529 | ret = -EFAULT; | 1182 | /* If we are at a filemark, nothing more to read */ |
1530 | buf += actually_read; | 1183 | if (test_bit(ilog2(IDE_AFLAG_FILEMARK), |
1531 | tape->merge_bh_size -= actually_read; | 1184 | &drive->atapi_flags)) |
1532 | count -= actually_read; | 1185 | break; |
1533 | } | 1186 | /* read */ |
1534 | while (count >= tape->buffer_size) { | 1187 | if (idetape_queue_rw_tail(drive, REQ_IDETAPE_READ, |
1535 | bytes_read = idetape_add_chrdev_read_request(drive, ctl); | 1188 | tape->buffer_size) <= 0) |
1536 | if (bytes_read <= 0) | 1189 | break; |
1537 | goto finish; | 1190 | } |
1538 | if (idetape_copy_stage_to_user(tape, buf, bytes_read)) | 1191 | |
1539 | ret = -EFAULT; | 1192 | /* copy out */ |
1540 | buf += bytes_read; | 1193 | todo = min_t(size_t, count - done, tape->valid); |
1541 | count -= bytes_read; | 1194 | if (copy_to_user(buf + done, tape->cur, todo)) |
1542 | actually_read += bytes_read; | ||
1543 | } | ||
1544 | if (count) { | ||
1545 | bytes_read = idetape_add_chrdev_read_request(drive, ctl); | ||
1546 | if (bytes_read <= 0) | ||
1547 | goto finish; | ||
1548 | temp = min((unsigned long)count, (unsigned long)bytes_read); | ||
1549 | if (idetape_copy_stage_to_user(tape, buf, temp)) | ||
1550 | ret = -EFAULT; | 1195 | ret = -EFAULT; |
1551 | actually_read += temp; | 1196 | |
1552 | tape->merge_bh_size = bytes_read-temp; | 1197 | tape->cur += todo; |
1198 | tape->valid -= todo; | ||
1199 | done += todo; | ||
1553 | } | 1200 | } |
1554 | finish: | 1201 | |
1555 | if (!actually_read && test_bit(IDE_AFLAG_FILEMARK, &drive->atapi_flags)) { | 1202 | if (!done && test_bit(ilog2(IDE_AFLAG_FILEMARK), &drive->atapi_flags)) { |
1556 | debug_log(DBG_SENSE, "%s: spacing over filemark\n", tape->name); | 1203 | debug_log(DBG_SENSE, "%s: spacing over filemark\n", tape->name); |
1557 | 1204 | ||
1558 | idetape_space_over_filemarks(drive, MTFSF, 1); | 1205 | idetape_space_over_filemarks(drive, MTFSF, 1); |
1559 | return 0; | 1206 | return 0; |
1560 | } | 1207 | } |
1561 | 1208 | ||
1562 | return ret ? ret : actually_read; | 1209 | return ret ? ret : done; |
1563 | } | 1210 | } |
1564 | 1211 | ||
1565 | static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf, | 1212 | static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf, |
@@ -1567,9 +1214,9 @@ static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf, | |||
1567 | { | 1214 | { |
1568 | struct ide_tape_obj *tape = file->private_data; | 1215 | struct ide_tape_obj *tape = file->private_data; |
1569 | ide_drive_t *drive = tape->drive; | 1216 | ide_drive_t *drive = tape->drive; |
1570 | ssize_t actually_written = 0; | 1217 | size_t done = 0; |
1571 | ssize_t ret = 0; | 1218 | ssize_t ret = 0; |
1572 | u16 ctl = *(u16 *)&tape->caps[12]; | 1219 | int rc; |
1573 | 1220 | ||
1574 | /* The drive is write protected. */ | 1221 | /* The drive is write protected. */ |
1575 | if (tape->write_prot) | 1222 | if (tape->write_prot) |
@@ -1578,80 +1225,31 @@ static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf, | |||
1578 | debug_log(DBG_CHRDEV, "Enter %s, count %Zd\n", __func__, count); | 1225 | debug_log(DBG_CHRDEV, "Enter %s, count %Zd\n", __func__, count); |
1579 | 1226 | ||
1580 | /* Initialize write operation */ | 1227 | /* Initialize write operation */ |
1581 | if (tape->chrdev_dir != IDETAPE_DIR_WRITE) { | 1228 | rc = idetape_init_rw(drive, IDETAPE_DIR_WRITE); |
1582 | if (tape->chrdev_dir == IDETAPE_DIR_READ) | 1229 | if (rc < 0) |
1583 | ide_tape_discard_merge_buffer(drive, 1); | 1230 | return rc; |
1584 | if (tape->merge_bh || tape->merge_bh_size) { | ||
1585 | printk(KERN_ERR "ide-tape: merge_bh_size " | ||
1586 | "should be 0 now\n"); | ||
1587 | tape->merge_bh_size = 0; | ||
1588 | } | ||
1589 | tape->merge_bh = ide_tape_kmalloc_buffer(tape, 0, 0); | ||
1590 | if (!tape->merge_bh) | ||
1591 | return -ENOMEM; | ||
1592 | tape->chrdev_dir = IDETAPE_DIR_WRITE; | ||
1593 | idetape_init_merge_buffer(tape); | ||
1594 | 1231 | ||
1595 | /* | 1232 | while (done < count) { |
1596 | * Issue a write 0 command to ensure that DSC handshake is | 1233 | size_t todo; |
1597 | * switched from completion mode to buffer available mode. No | 1234 | |
1598 | * point in issuing this if DSC overlap isn't supported, some | 1235 | /* flush if staging buffer is full */ |
1599 | * drives (Seagate STT3401A) will return an error. | 1236 | if (tape->valid == tape->buffer_size && |
1600 | */ | 1237 | idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, |
1601 | if (drive->dev_flags & IDE_DFLAG_DSC_OVERLAP) { | 1238 | tape->buffer_size) <= 0) |
1602 | ssize_t retval = idetape_queue_rw_tail(drive, | 1239 | return rc; |
1603 | REQ_IDETAPE_WRITE, 0, | 1240 | |
1604 | tape->merge_bh); | 1241 | /* copy in */ |
1605 | if (retval < 0) { | 1242 | todo = min_t(size_t, count - done, |
1606 | ide_tape_kfree_buffer(tape); | 1243 | tape->buffer_size - tape->valid); |
1607 | tape->merge_bh = NULL; | 1244 | if (copy_from_user(tape->cur, buf + done, todo)) |
1608 | tape->chrdev_dir = IDETAPE_DIR_NONE; | ||
1609 | return retval; | ||
1610 | } | ||
1611 | } | ||
1612 | } | ||
1613 | if (count == 0) | ||
1614 | return (0); | ||
1615 | if (tape->merge_bh_size) { | ||
1616 | if (tape->merge_bh_size >= tape->buffer_size) { | ||
1617 | printk(KERN_ERR "ide-tape: bug: merge buf too big\n"); | ||
1618 | tape->merge_bh_size = 0; | ||
1619 | } | ||
1620 | actually_written = min((unsigned int) | ||
1621 | (tape->buffer_size - tape->merge_bh_size), | ||
1622 | (unsigned int)count); | ||
1623 | if (idetape_copy_stage_from_user(tape, buf, actually_written)) | ||
1624 | ret = -EFAULT; | ||
1625 | buf += actually_written; | ||
1626 | tape->merge_bh_size += actually_written; | ||
1627 | count -= actually_written; | ||
1628 | |||
1629 | if (tape->merge_bh_size == tape->buffer_size) { | ||
1630 | ssize_t retval; | ||
1631 | tape->merge_bh_size = 0; | ||
1632 | retval = idetape_add_chrdev_write_request(drive, ctl); | ||
1633 | if (retval <= 0) | ||
1634 | return (retval); | ||
1635 | } | ||
1636 | } | ||
1637 | while (count >= tape->buffer_size) { | ||
1638 | ssize_t retval; | ||
1639 | if (idetape_copy_stage_from_user(tape, buf, tape->buffer_size)) | ||
1640 | ret = -EFAULT; | ||
1641 | buf += tape->buffer_size; | ||
1642 | count -= tape->buffer_size; | ||
1643 | retval = idetape_add_chrdev_write_request(drive, ctl); | ||
1644 | actually_written += tape->buffer_size; | ||
1645 | if (retval <= 0) | ||
1646 | return (retval); | ||
1647 | } | ||
1648 | if (count) { | ||
1649 | actually_written += count; | ||
1650 | if (idetape_copy_stage_from_user(tape, buf, count)) | ||
1651 | ret = -EFAULT; | 1245 | ret = -EFAULT; |
1652 | tape->merge_bh_size += count; | 1246 | |
1247 | tape->cur += todo; | ||
1248 | tape->valid += todo; | ||
1249 | done += todo; | ||
1653 | } | 1250 | } |
1654 | return ret ? ret : actually_written; | 1251 | |
1252 | return ret ? ret : done; | ||
1655 | } | 1253 | } |
1656 | 1254 | ||
1657 | static int idetape_write_filemark(ide_drive_t *drive) | 1255 | static int idetape_write_filemark(ide_drive_t *drive) |
@@ -1735,7 +1333,8 @@ static int idetape_mtioctop(ide_drive_t *drive, short mt_op, int mt_count) | |||
1735 | ide_tape_discard_merge_buffer(drive, 0); | 1333 | ide_tape_discard_merge_buffer(drive, 0); |
1736 | retval = ide_do_start_stop(drive, disk, !IDETAPE_LU_LOAD_MASK); | 1334 | retval = ide_do_start_stop(drive, disk, !IDETAPE_LU_LOAD_MASK); |
1737 | if (!retval) | 1335 | if (!retval) |
1738 | clear_bit(IDE_AFLAG_MEDIUM_PRESENT, &drive->atapi_flags); | 1336 | clear_bit(ilog2(IDE_AFLAG_MEDIUM_PRESENT), |
1337 | &drive->atapi_flags); | ||
1739 | return retval; | 1338 | return retval; |
1740 | case MTNOP: | 1339 | case MTNOP: |
1741 | ide_tape_discard_merge_buffer(drive, 0); | 1340 | ide_tape_discard_merge_buffer(drive, 0); |
@@ -1757,9 +1356,11 @@ static int idetape_mtioctop(ide_drive_t *drive, short mt_op, int mt_count) | |||
1757 | mt_count % tape->blk_size) | 1356 | mt_count % tape->blk_size) |
1758 | return -EIO; | 1357 | return -EIO; |
1759 | tape->user_bs_factor = mt_count / tape->blk_size; | 1358 | tape->user_bs_factor = mt_count / tape->blk_size; |
1760 | clear_bit(IDE_AFLAG_DETECT_BS, &drive->atapi_flags); | 1359 | clear_bit(ilog2(IDE_AFLAG_DETECT_BS), |
1360 | &drive->atapi_flags); | ||
1761 | } else | 1361 | } else |
1762 | set_bit(IDE_AFLAG_DETECT_BS, &drive->atapi_flags); | 1362 | set_bit(ilog2(IDE_AFLAG_DETECT_BS), |
1363 | &drive->atapi_flags); | ||
1763 | return 0; | 1364 | return 0; |
1764 | case MTSEEK: | 1365 | case MTSEEK: |
1765 | ide_tape_discard_merge_buffer(drive, 0); | 1366 | ide_tape_discard_merge_buffer(drive, 0); |
@@ -1812,7 +1413,7 @@ static int idetape_chrdev_ioctl(struct inode *inode, struct file *file, | |||
1812 | idetape_flush_tape_buffers(drive); | 1413 | idetape_flush_tape_buffers(drive); |
1813 | } | 1414 | } |
1814 | if (cmd == MTIOCGET || cmd == MTIOCPOS) { | 1415 | if (cmd == MTIOCGET || cmd == MTIOCPOS) { |
1815 | block_offset = tape->merge_bh_size / | 1416 | block_offset = tape->valid / |
1816 | (tape->blk_size * tape->user_bs_factor); | 1417 | (tape->blk_size * tape->user_bs_factor); |
1817 | position = idetape_read_position(drive); | 1418 | position = idetape_read_position(drive); |
1818 | if (position < 0) | 1419 | if (position < 0) |
@@ -1885,7 +1486,7 @@ static int idetape_chrdev_open(struct inode *inode, struct file *filp) | |||
1885 | return -ENXIO; | 1486 | return -ENXIO; |
1886 | 1487 | ||
1887 | lock_kernel(); | 1488 | lock_kernel(); |
1888 | tape = ide_tape_chrdev_get(i); | 1489 | tape = ide_tape_get(NULL, true, i); |
1889 | if (!tape) { | 1490 | if (!tape) { |
1890 | unlock_kernel(); | 1491 | unlock_kernel(); |
1891 | return -ENXIO; | 1492 | return -ENXIO; |
@@ -1904,20 +1505,20 @@ static int idetape_chrdev_open(struct inode *inode, struct file *filp) | |||
1904 | 1505 | ||
1905 | filp->private_data = tape; | 1506 | filp->private_data = tape; |
1906 | 1507 | ||
1907 | if (test_and_set_bit(IDE_AFLAG_BUSY, &drive->atapi_flags)) { | 1508 | if (test_and_set_bit(ilog2(IDE_AFLAG_BUSY), &drive->atapi_flags)) { |
1908 | retval = -EBUSY; | 1509 | retval = -EBUSY; |
1909 | goto out_put_tape; | 1510 | goto out_put_tape; |
1910 | } | 1511 | } |
1911 | 1512 | ||
1912 | retval = idetape_wait_ready(drive, 60 * HZ); | 1513 | retval = idetape_wait_ready(drive, 60 * HZ); |
1913 | if (retval) { | 1514 | if (retval) { |
1914 | clear_bit(IDE_AFLAG_BUSY, &drive->atapi_flags); | 1515 | clear_bit(ilog2(IDE_AFLAG_BUSY), &drive->atapi_flags); |
1915 | printk(KERN_ERR "ide-tape: %s: drive not ready\n", tape->name); | 1516 | printk(KERN_ERR "ide-tape: %s: drive not ready\n", tape->name); |
1916 | goto out_put_tape; | 1517 | goto out_put_tape; |
1917 | } | 1518 | } |
1918 | 1519 | ||
1919 | idetape_read_position(drive); | 1520 | idetape_read_position(drive); |
1920 | if (!test_bit(IDE_AFLAG_ADDRESS_VALID, &drive->atapi_flags)) | 1521 | if (!test_bit(ilog2(IDE_AFLAG_ADDRESS_VALID), &drive->atapi_flags)) |
1921 | (void)idetape_rewind_tape(drive); | 1522 | (void)idetape_rewind_tape(drive); |
1922 | 1523 | ||
1923 | /* Read block size and write protect status from drive. */ | 1524 | /* Read block size and write protect status from drive. */ |
@@ -1933,7 +1534,7 @@ static int idetape_chrdev_open(struct inode *inode, struct file *filp) | |||
1933 | if (tape->write_prot) { | 1534 | if (tape->write_prot) { |
1934 | if ((filp->f_flags & O_ACCMODE) == O_WRONLY || | 1535 | if ((filp->f_flags & O_ACCMODE) == O_WRONLY || |
1935 | (filp->f_flags & O_ACCMODE) == O_RDWR) { | 1536 | (filp->f_flags & O_ACCMODE) == O_RDWR) { |
1936 | clear_bit(IDE_AFLAG_BUSY, &drive->atapi_flags); | 1537 | clear_bit(ilog2(IDE_AFLAG_BUSY), &drive->atapi_flags); |
1937 | retval = -EROFS; | 1538 | retval = -EROFS; |
1938 | goto out_put_tape; | 1539 | goto out_put_tape; |
1939 | } | 1540 | } |
@@ -1960,12 +1561,12 @@ static void idetape_write_release(ide_drive_t *drive, unsigned int minor) | |||
1960 | idetape_tape_t *tape = drive->driver_data; | 1561 | idetape_tape_t *tape = drive->driver_data; |
1961 | 1562 | ||
1962 | ide_tape_flush_merge_buffer(drive); | 1563 | ide_tape_flush_merge_buffer(drive); |
1963 | tape->merge_bh = ide_tape_kmalloc_buffer(tape, 1, 0); | 1564 | tape->buf = kmalloc(tape->buffer_size, GFP_KERNEL); |
1964 | if (tape->merge_bh != NULL) { | 1565 | if (tape->buf != NULL) { |
1965 | idetape_pad_zeros(drive, tape->blk_size * | 1566 | idetape_pad_zeros(drive, tape->blk_size * |
1966 | (tape->user_bs_factor - 1)); | 1567 | (tape->user_bs_factor - 1)); |
1967 | ide_tape_kfree_buffer(tape); | 1568 | kfree(tape->buf); |
1968 | tape->merge_bh = NULL; | 1569 | tape->buf = NULL; |
1969 | } | 1570 | } |
1970 | idetape_write_filemark(drive); | 1571 | idetape_write_filemark(drive); |
1971 | idetape_flush_tape_buffers(drive); | 1572 | idetape_flush_tape_buffers(drive); |
@@ -1990,15 +1591,17 @@ static int idetape_chrdev_release(struct inode *inode, struct file *filp) | |||
1990 | ide_tape_discard_merge_buffer(drive, 1); | 1591 | ide_tape_discard_merge_buffer(drive, 1); |
1991 | } | 1592 | } |
1992 | 1593 | ||
1993 | if (minor < 128 && test_bit(IDE_AFLAG_MEDIUM_PRESENT, &drive->atapi_flags)) | 1594 | if (minor < 128 && test_bit(ilog2(IDE_AFLAG_MEDIUM_PRESENT), |
1595 | &drive->atapi_flags)) | ||
1994 | (void) idetape_rewind_tape(drive); | 1596 | (void) idetape_rewind_tape(drive); |
1597 | |||
1995 | if (tape->chrdev_dir == IDETAPE_DIR_NONE) { | 1598 | if (tape->chrdev_dir == IDETAPE_DIR_NONE) { |
1996 | if (tape->door_locked == DOOR_LOCKED) { | 1599 | if (tape->door_locked == DOOR_LOCKED) { |
1997 | if (!ide_set_media_lock(drive, tape->disk, 0)) | 1600 | if (!ide_set_media_lock(drive, tape->disk, 0)) |
1998 | tape->door_locked = DOOR_UNLOCKED; | 1601 | tape->door_locked = DOOR_UNLOCKED; |
1999 | } | 1602 | } |
2000 | } | 1603 | } |
2001 | clear_bit(IDE_AFLAG_BUSY, &drive->atapi_flags); | 1604 | clear_bit(ilog2(IDE_AFLAG_BUSY), &drive->atapi_flags); |
2002 | ide_tape_put(tape); | 1605 | ide_tape_put(tape); |
2003 | unlock_kernel(); | 1606 | unlock_kernel(); |
2004 | return 0; | 1607 | return 0; |
@@ -2159,8 +1762,6 @@ static void idetape_setup(ide_drive_t *drive, idetape_tape_t *tape, int minor) | |||
2159 | u16 *ctl = (u16 *)&tape->caps[12]; | 1762 | u16 *ctl = (u16 *)&tape->caps[12]; |
2160 | 1763 | ||
2161 | drive->pc_callback = ide_tape_callback; | 1764 | drive->pc_callback = ide_tape_callback; |
2162 | drive->pc_update_buffers = idetape_update_buffers; | ||
2163 | drive->pc_io_buffers = ide_tape_io_buffers; | ||
2164 | 1765 | ||
2165 | drive->dev_flags |= IDE_DFLAG_DSC_OVERLAP; | 1766 | drive->dev_flags |= IDE_DFLAG_DSC_OVERLAP; |
2166 | 1767 | ||
@@ -2191,11 +1792,6 @@ static void idetape_setup(ide_drive_t *drive, idetape_tape_t *tape, int minor) | |||
2191 | tape->buffer_size = *ctl * tape->blk_size; | 1792 | tape->buffer_size = *ctl * tape->blk_size; |
2192 | } | 1793 | } |
2193 | buffer_size = tape->buffer_size; | 1794 | buffer_size = tape->buffer_size; |
2194 | tape->pages_per_buffer = buffer_size / PAGE_SIZE; | ||
2195 | if (buffer_size % PAGE_SIZE) { | ||
2196 | tape->pages_per_buffer++; | ||
2197 | tape->excess_bh_size = PAGE_SIZE - buffer_size % PAGE_SIZE; | ||
2198 | } | ||
2199 | 1795 | ||
2200 | /* select the "best" DSC read/write polling freq */ | 1796 | /* select the "best" DSC read/write polling freq */ |
2201 | speed = max(*(u16 *)&tape->caps[14], *(u16 *)&tape->caps[8]); | 1797 | speed = max(*(u16 *)&tape->caps[14], *(u16 *)&tape->caps[8]); |
@@ -2238,7 +1834,7 @@ static void ide_tape_release(struct device *dev) | |||
2238 | ide_drive_t *drive = tape->drive; | 1834 | ide_drive_t *drive = tape->drive; |
2239 | struct gendisk *g = tape->disk; | 1835 | struct gendisk *g = tape->disk; |
2240 | 1836 | ||
2241 | BUG_ON(tape->merge_bh_size); | 1837 | BUG_ON(tape->valid); |
2242 | 1838 | ||
2243 | drive->dev_flags &= ~IDE_DFLAG_DSC_OVERLAP; | 1839 | drive->dev_flags &= ~IDE_DFLAG_DSC_OVERLAP; |
2244 | drive->driver_data = NULL; | 1840 | drive->driver_data = NULL; |
@@ -2311,7 +1907,7 @@ static const struct file_operations idetape_fops = { | |||
2311 | 1907 | ||
2312 | static int idetape_open(struct block_device *bdev, fmode_t mode) | 1908 | static int idetape_open(struct block_device *bdev, fmode_t mode) |
2313 | { | 1909 | { |
2314 | struct ide_tape_obj *tape = ide_tape_get(bdev->bd_disk); | 1910 | struct ide_tape_obj *tape = ide_tape_get(bdev->bd_disk, false, 0); |
2315 | 1911 | ||
2316 | if (!tape) | 1912 | if (!tape) |
2317 | return -ENXIO; | 1913 | return -ENXIO; |