aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/ide/ide-floppy.c68
1 files changed, 42 insertions, 26 deletions
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
index 84c333e44349..06db5edf9cee 100644
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -36,6 +36,7 @@
36#include <linux/hdreg.h> 36#include <linux/hdreg.h>
37#include <linux/bitops.h> 37#include <linux/bitops.h>
38#include <linux/mutex.h> 38#include <linux/mutex.h>
39#include <linux/scatterlist.h>
39 40
40#include <scsi/scsi_ioctl.h> 41#include <scsi/scsi_ioctl.h>
41 42
@@ -226,29 +227,36 @@ static void ide_floppy_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
226 unsigned int bcount, int direction) 227 unsigned int bcount, int direction)
227{ 228{
228 ide_hwif_t *hwif = drive->hwif; 229 ide_hwif_t *hwif = drive->hwif;
229 struct request *rq = pc->rq; 230 const struct ide_tp_ops *tp_ops = hwif->tp_ops;
230 struct req_iterator iter; 231 xfer_func_t *xf = direction ? tp_ops->output_data : tp_ops->input_data;
231 struct bio_vec *bvec; 232 struct scatterlist *sg = pc->sg;
232 unsigned long flags; 233 char *buf;
233 int count, done = 0; 234 int count, done = 0;
234 char *data;
235
236 rq_for_each_segment(bvec, rq, iter) {
237 if (!bcount)
238 break;
239
240 count = min(bvec->bv_len, bcount);
241
242 data = bvec_kmap_irq(bvec, &flags);
243 if (direction)
244 hwif->tp_ops->output_data(drive, NULL, data, count);
245 else
246 hwif->tp_ops->input_data(drive, NULL, data, count);
247 bvec_kunmap_irq(data, &flags);
248 235
236 while (bcount) {
237 count = min(sg->length - pc->b_count, bcount);
238 if (PageHighMem(sg_page(sg))) {
239 unsigned long flags;
240
241 local_irq_save(flags);
242 buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
243 xf(drive, NULL, buf + pc->b_count, count);
244 kunmap_atomic(buf - sg->offset, KM_IRQ0);
245 local_irq_restore(flags);
246 } else {
247 buf = sg_virt(sg);
248 xf(drive, NULL, buf + pc->b_count, count);
249 }
249 bcount -= count; 250 bcount -= count;
250 pc->b_count += count; 251 pc->b_count += count;
251 done += count; 252 done += count;
253
254 if (pc->b_count == sg->length) {
255 if (!--pc->sg_cnt)
256 break;
257 pc->sg = sg = sg_next(sg);
258 pc->b_count = 0;
259 }
252 } 260 }
253 261
254 idefloppy_end_request(drive, 1, done >> 9); 262 idefloppy_end_request(drive, 1, done >> 9);
@@ -571,7 +579,7 @@ static void idefloppy_create_rw_cmd(idefloppy_floppy_t *floppy,
571 memcpy(rq->cmd, pc->c, 12); 579 memcpy(rq->cmd, pc->c, 12);
572 580
573 pc->rq = rq; 581 pc->rq = rq;
574 pc->b_count = cmd == READ ? 0 : rq->bio->bi_size; 582 pc->b_count = 0;
575 if (rq->cmd_flags & REQ_RW) 583 if (rq->cmd_flags & REQ_RW)
576 pc->flags |= PC_FLAG_WRITING; 584 pc->flags |= PC_FLAG_WRITING;
577 pc->buf = NULL; 585 pc->buf = NULL;
@@ -585,7 +593,7 @@ static void idefloppy_blockpc_cmd(idefloppy_floppy_t *floppy,
585 idefloppy_init_pc(pc); 593 idefloppy_init_pc(pc);
586 memcpy(pc->c, rq->cmd, sizeof(pc->c)); 594 memcpy(pc->c, rq->cmd, sizeof(pc->c));
587 pc->rq = rq; 595 pc->rq = rq;
588 pc->b_count = rq->data_len; 596 pc->b_count = 0;
589 if (rq->data_len && rq_data_dir(rq) == WRITE) 597 if (rq->data_len && rq_data_dir(rq) == WRITE)
590 pc->flags |= PC_FLAG_WRITING; 598 pc->flags |= PC_FLAG_WRITING;
591 pc->buf = rq->data; 599 pc->buf = rq->data;
@@ -602,15 +610,17 @@ static ide_startstop_t idefloppy_do_request(ide_drive_t *drive,
602 struct request *rq, sector_t block_s) 610 struct request *rq, sector_t block_s)
603{ 611{
604 idefloppy_floppy_t *floppy = drive->driver_data; 612 idefloppy_floppy_t *floppy = drive->driver_data;
613 ide_hwif_t *hwif = drive->hwif;
605 struct ide_atapi_pc *pc; 614 struct ide_atapi_pc *pc;
606 unsigned long block = (unsigned long)block_s; 615 unsigned long block = (unsigned long)block_s;
607 616
608 debug_log("dev: %s, cmd_type: %x, errors: %d\n", 617 debug_log("%s: dev: %s, cmd: 0x%x, cmd_type: %x, errors: %d\n",
609 rq->rq_disk ? rq->rq_disk->disk_name : "?", 618 __func__, rq->rq_disk ? rq->rq_disk->disk_name : "?",
610 rq->cmd_type, rq->errors); 619 rq->cmd[0], rq->cmd_type, rq->errors);
611 debug_log("sector: %ld, nr_sectors: %ld, " 620
612 "current_nr_sectors: %d\n", (long)rq->sector, 621 debug_log("%s: sector: %ld, nr_sectors: %ld, current_nr_sectors: %d\n",
613 rq->nr_sectors, rq->current_nr_sectors); 622 __func__, (long)rq->sector, rq->nr_sectors,
623 rq->current_nr_sectors);
614 624
615 if (rq->errors >= ERROR_MAX) { 625 if (rq->errors >= ERROR_MAX) {
616 if (floppy->failed_pc) 626 if (floppy->failed_pc)
@@ -643,6 +653,12 @@ static ide_startstop_t idefloppy_do_request(ide_drive_t *drive,
643 return ide_stopped; 653 return ide_stopped;
644 } 654 }
645 655
656 ide_init_sg_cmd(drive, rq);
657 ide_map_sg(drive, rq);
658
659 pc->sg = hwif->sg_table;
660 pc->sg_cnt = hwif->sg_nents;
661
646 pc->rq = rq; 662 pc->rq = rq;
647 663
648 return idefloppy_issue_pc(drive, pc); 664 return idefloppy_issue_pc(drive, pc);