diff options
Diffstat (limited to 'drivers/ide/ide-floppy.c')
-rw-r--r-- | drivers/ide/ide-floppy.c | 65 |
1 files changed, 19 insertions, 46 deletions
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index 78afc493e1fd..0b22933e258c 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c | |||
@@ -321,39 +321,8 @@ static int idefloppy_do_end_request(ide_drive_t *drive, int uptodate, int nsecs) | |||
321 | return 0; | 321 | return 0; |
322 | } | 322 | } |
323 | 323 | ||
324 | static void idefloppy_input_buffers (ide_drive_t *drive, idefloppy_pc_t *pc, unsigned int bcount) | 324 | static void ide_floppy_io_buffers(ide_drive_t *drive, idefloppy_pc_t *pc, |
325 | { | 325 | unsigned int bcount, int direction) |
326 | struct request *rq = pc->rq; | ||
327 | struct bio_vec *bvec; | ||
328 | struct req_iterator iter; | ||
329 | unsigned long flags; | ||
330 | char *data; | ||
331 | int count, done = 0; | ||
332 | |||
333 | rq_for_each_segment(bvec, rq, iter) { | ||
334 | if (!bcount) | ||
335 | break; | ||
336 | |||
337 | count = min(bvec->bv_len, bcount); | ||
338 | |||
339 | data = bvec_kmap_irq(bvec, &flags); | ||
340 | drive->hwif->atapi_input_bytes(drive, data, count); | ||
341 | bvec_kunmap_irq(data, &flags); | ||
342 | |||
343 | bcount -= count; | ||
344 | pc->b_count += count; | ||
345 | done += count; | ||
346 | } | ||
347 | |||
348 | idefloppy_do_end_request(drive, 1, done >> 9); | ||
349 | |||
350 | if (bcount) { | ||
351 | printk(KERN_ERR "%s: leftover data in idefloppy_input_buffers, bcount == %d\n", drive->name, bcount); | ||
352 | idefloppy_discard_data(drive, bcount); | ||
353 | } | ||
354 | } | ||
355 | |||
356 | static void idefloppy_output_buffers (ide_drive_t *drive, idefloppy_pc_t *pc, unsigned int bcount) | ||
357 | { | 326 | { |
358 | struct request *rq = pc->rq; | 327 | struct request *rq = pc->rq; |
359 | struct req_iterator iter; | 328 | struct req_iterator iter; |
@@ -369,7 +338,10 @@ static void idefloppy_output_buffers (ide_drive_t *drive, idefloppy_pc_t *pc, un | |||
369 | count = min(bvec->bv_len, bcount); | 338 | count = min(bvec->bv_len, bcount); |
370 | 339 | ||
371 | data = bvec_kmap_irq(bvec, &flags); | 340 | data = bvec_kmap_irq(bvec, &flags); |
372 | drive->hwif->atapi_output_bytes(drive, data, count); | 341 | if (direction) |
342 | drive->hwif->atapi_output_bytes(drive, data, count); | ||
343 | else | ||
344 | drive->hwif->atapi_input_bytes(drive, data, count); | ||
373 | bvec_kunmap_irq(data, &flags); | 345 | bvec_kunmap_irq(data, &flags); |
374 | 346 | ||
375 | bcount -= count; | 347 | bcount -= count; |
@@ -380,8 +352,13 @@ static void idefloppy_output_buffers (ide_drive_t *drive, idefloppy_pc_t *pc, un | |||
380 | idefloppy_do_end_request(drive, 1, done >> 9); | 352 | idefloppy_do_end_request(drive, 1, done >> 9); |
381 | 353 | ||
382 | if (bcount) { | 354 | if (bcount) { |
383 | printk(KERN_ERR "%s: leftover data in idefloppy_output_buffers, bcount == %d\n", drive->name, bcount); | 355 | printk(KERN_ERR "%s: leftover data in %s, bcount == %d\n", |
384 | idefloppy_write_zeros(drive, bcount); | 356 | drive->name, __func__, bcount); |
357 | if (direction) | ||
358 | idefloppy_write_zeros(drive, bcount); | ||
359 | else | ||
360 | idefloppy_discard_data(drive, bcount); | ||
361 | |||
385 | } | 362 | } |
386 | } | 363 | } |
387 | 364 | ||
@@ -516,8 +493,6 @@ static void idefloppy_retry_pc (ide_drive_t *drive) | |||
516 | idefloppy_queue_pc_head(drive, pc, rq); | 493 | idefloppy_queue_pc_head(drive, pc, rq); |
517 | } | 494 | } |
518 | 495 | ||
519 | typedef void (io_buf_t)(ide_drive_t *, idefloppy_pc_t *, unsigned int); | ||
520 | |||
521 | /* The usual interrupt handler called during a packet command. */ | 496 | /* The usual interrupt handler called during a packet command. */ |
522 | static ide_startstop_t idefloppy_pc_intr (ide_drive_t *drive) | 497 | static ide_startstop_t idefloppy_pc_intr (ide_drive_t *drive) |
523 | { | 498 | { |
@@ -526,7 +501,6 @@ static ide_startstop_t idefloppy_pc_intr (ide_drive_t *drive) | |||
526 | idefloppy_pc_t *pc = floppy->pc; | 501 | idefloppy_pc_t *pc = floppy->pc; |
527 | struct request *rq = pc->rq; | 502 | struct request *rq = pc->rq; |
528 | xfer_func_t *xferfunc; | 503 | xfer_func_t *xferfunc; |
529 | io_buf_t *iobuf_func; | ||
530 | unsigned int temp; | 504 | unsigned int temp; |
531 | int dma_error = 0; | 505 | int dma_error = 0; |
532 | u16 bcount; | 506 | u16 bcount; |
@@ -624,24 +598,23 @@ static ide_startstop_t idefloppy_pc_intr (ide_drive_t *drive) | |||
624 | " expected - allowing transfer\n"); | 598 | " expected - allowing transfer\n"); |
625 | } | 599 | } |
626 | } | 600 | } |
627 | if (test_bit(PC_WRITING, &pc->flags)) { | 601 | if (test_bit(PC_WRITING, &pc->flags)) |
628 | xferfunc = hwif->atapi_output_bytes; | 602 | xferfunc = hwif->atapi_output_bytes; |
629 | iobuf_func = &idefloppy_output_buffers; | 603 | else |
630 | } else { | ||
631 | xferfunc = hwif->atapi_input_bytes; | 604 | xferfunc = hwif->atapi_input_bytes; |
632 | iobuf_func = &idefloppy_input_buffers; | ||
633 | } | ||
634 | 605 | ||
635 | if (pc->buffer) | 606 | if (pc->buffer) |
636 | xferfunc(drive, pc->current_position, bcount); | 607 | xferfunc(drive, pc->current_position, bcount); |
637 | else | 608 | else |
638 | iobuf_func(drive, pc, bcount); | 609 | ide_floppy_io_buffers(drive, pc, bcount, |
610 | test_bit(PC_WRITING, &pc->flags)); | ||
639 | 611 | ||
640 | /* Update the current position */ | 612 | /* Update the current position */ |
641 | pc->actually_transferred += bcount; | 613 | pc->actually_transferred += bcount; |
642 | pc->current_position += bcount; | 614 | pc->current_position += bcount; |
643 | 615 | ||
644 | ide_set_handler(drive, &idefloppy_pc_intr, IDEFLOPPY_WAIT_CMD, NULL); /* And set the interrupt handler again */ | 616 | /* And set the interrupt handler again */ |
617 | ide_set_handler(drive, &idefloppy_pc_intr, IDEFLOPPY_WAIT_CMD, NULL); | ||
645 | return ide_started; | 618 | return ide_started; |
646 | } | 619 | } |
647 | 620 | ||