diff options
-rw-r--r-- | drivers/ide/ide-cd.c | 146 | ||||
-rw-r--r-- | drivers/ide/ide-taskfile.c | 5 | ||||
-rw-r--r-- | include/linux/ide.h | 4 |
3 files changed, 50 insertions, 105 deletions
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 30113e69c8bb..5f15859c2c73 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c | |||
@@ -539,64 +539,12 @@ static ide_startstop_t ide_cd_prepare_rw_request(ide_drive_t *drive, | |||
539 | { | 539 | { |
540 | ide_debug_log(IDE_DBG_RQ, "rq->cmd_flags: 0x%x", rq->cmd_flags); | 540 | ide_debug_log(IDE_DBG_RQ, "rq->cmd_flags: 0x%x", rq->cmd_flags); |
541 | 541 | ||
542 | if (rq_data_dir(rq) == READ) { | ||
543 | unsigned short sectors_per_frame = | ||
544 | queue_hardsect_size(drive->queue) >> SECTOR_BITS; | ||
545 | int nskip = rq->sector & (sectors_per_frame - 1); | ||
546 | |||
547 | /* | ||
548 | * If the requested sector doesn't start on a frame boundary, | ||
549 | * we must adjust the start of the transfer so that it does, | ||
550 | * and remember to skip the first few sectors. | ||
551 | * | ||
552 | * If the rq->current_nr_sectors field is larger than the size | ||
553 | * of the buffer, it will mean that we're to skip a number of | ||
554 | * sectors equal to the amount by which rq->current_nr_sectors | ||
555 | * is larger than the buffer size. | ||
556 | */ | ||
557 | if (nskip > 0) { | ||
558 | /* sanity check... */ | ||
559 | if (rq->current_nr_sectors != | ||
560 | bio_cur_sectors(rq->bio)) { | ||
561 | printk(KERN_ERR PFX "%s: %s: buffer botch (%u)\n", | ||
562 | drive->name, __func__, | ||
563 | rq->current_nr_sectors); | ||
564 | return ide_stopped; | ||
565 | } | ||
566 | rq->current_nr_sectors += nskip; | ||
567 | } | ||
568 | } | ||
569 | |||
570 | /* set up the command */ | 542 | /* set up the command */ |
571 | rq->timeout = ATAPI_WAIT_PC; | 543 | rq->timeout = ATAPI_WAIT_PC; |
572 | 544 | ||
573 | return ide_started; | 545 | return ide_started; |
574 | } | 546 | } |
575 | 547 | ||
576 | /* | ||
577 | * Fix up a possibly partially-processed request so that we can start it over | ||
578 | * entirely, or even put it back on the request queue. | ||
579 | */ | ||
580 | static void ide_cd_restore_request(ide_drive_t *drive, struct request *rq) | ||
581 | { | ||
582 | |||
583 | ide_debug_log(IDE_DBG_FUNC, "enter"); | ||
584 | |||
585 | if (rq->buffer != bio_data(rq->bio)) { | ||
586 | sector_t n = | ||
587 | (rq->buffer - (char *)bio_data(rq->bio)) / SECTOR_SIZE; | ||
588 | |||
589 | rq->buffer = bio_data(rq->bio); | ||
590 | rq->nr_sectors += n; | ||
591 | rq->sector -= n; | ||
592 | } | ||
593 | rq->current_nr_sectors = bio_cur_sectors(rq->bio); | ||
594 | rq->hard_cur_sectors = rq->current_nr_sectors; | ||
595 | rq->hard_nr_sectors = rq->nr_sectors; | ||
596 | rq->hard_sector = rq->sector; | ||
597 | rq->q->prep_rq_fn(rq->q, rq); | ||
598 | } | ||
599 | |||
600 | static void ide_cd_request_sense_fixup(ide_drive_t *drive, struct request *rq) | 548 | static void ide_cd_request_sense_fixup(ide_drive_t *drive, struct request *rq) |
601 | { | 549 | { |
602 | ide_debug_log(IDE_DBG_FUNC, "rq->cmd[0]: 0x%x", rq->cmd[0]); | 550 | ide_debug_log(IDE_DBG_FUNC, "rq->cmd[0]: 0x%x", rq->cmd[0]); |
@@ -690,6 +638,17 @@ int ide_cd_queue_pc(ide_drive_t *drive, const unsigned char *cmd, | |||
690 | return (flags & REQ_FAILED) ? -EIO : 0; | 638 | return (flags & REQ_FAILED) ? -EIO : 0; |
691 | } | 639 | } |
692 | 640 | ||
641 | static void ide_cd_error_cmd(ide_drive_t *drive, struct ide_cmd *cmd) | ||
642 | { | ||
643 | unsigned int nr_bytes = cmd->nbytes - cmd->nleft; | ||
644 | |||
645 | if (cmd->tf_flags & IDE_TFLAG_WRITE) | ||
646 | nr_bytes -= cmd->last_xfer_len; | ||
647 | |||
648 | if (nr_bytes > 0) | ||
649 | ide_complete_rq(drive, 0, nr_bytes); | ||
650 | } | ||
651 | |||
693 | /* | 652 | /* |
694 | * Called from blk_end_request_callback() after the data of the request is | 653 | * Called from blk_end_request_callback() after the data of the request is |
695 | * completed and before the request itself is completed. By returning value '1', | 654 | * completed and before the request itself is completed. By returning value '1', |
@@ -703,6 +662,7 @@ static int cdrom_newpc_intr_dummy_cb(struct request *rq) | |||
703 | static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) | 662 | static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) |
704 | { | 663 | { |
705 | ide_hwif_t *hwif = drive->hwif; | 664 | ide_hwif_t *hwif = drive->hwif; |
665 | struct ide_cmd *cmd = &hwif->cmd; | ||
706 | struct request *rq = hwif->rq; | 666 | struct request *rq = hwif->rq; |
707 | xfer_func_t *xferfunc; | 667 | xfer_func_t *xferfunc; |
708 | ide_expiry_t *expiry = NULL; | 668 | ide_expiry_t *expiry = NULL; |
@@ -769,11 +729,10 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) | |||
769 | * Otherwise, complete the command normally. | 729 | * Otherwise, complete the command normally. |
770 | */ | 730 | */ |
771 | uptodate = 1; | 731 | uptodate = 1; |
772 | if (rq->current_nr_sectors > 0) { | 732 | if (cmd->nleft > 0) { |
773 | printk(KERN_ERR PFX "%s: %s: data underrun " | 733 | printk(KERN_ERR PFX "%s: %s: data underrun " |
774 | "(%d blocks)\n", | 734 | "(%u bytes)\n", drive->name, __func__, |
775 | drive->name, __func__, | 735 | cmd->nleft); |
776 | rq->current_nr_sectors); | ||
777 | if (!write) | 736 | if (!write) |
778 | rq->cmd_flags |= REQ_FAILED; | 737 | rq->cmd_flags |= REQ_FAILED; |
779 | uptodate = 0; | 738 | uptodate = 0; |
@@ -795,24 +754,10 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) | |||
795 | 754 | ||
796 | if (blk_fs_request(rq)) { | 755 | if (blk_fs_request(rq)) { |
797 | if (write == 0) { | 756 | if (write == 0) { |
798 | int nskip; | ||
799 | |||
800 | if (ide_cd_check_transfer_size(drive, len)) | 757 | if (ide_cd_check_transfer_size(drive, len)) |
801 | goto out_end; | 758 | goto out_end; |
802 | |||
803 | /* | ||
804 | * First, figure out if we need to bit-bucket | ||
805 | * any of the leading sectors. | ||
806 | */ | ||
807 | nskip = min_t(int, rq->current_nr_sectors | ||
808 | - bio_cur_sectors(rq->bio), | ||
809 | thislen >> 9); | ||
810 | if (nskip > 0) { | ||
811 | ide_pad_transfer(drive, write, nskip << 9); | ||
812 | rq->current_nr_sectors -= nskip; | ||
813 | thislen -= (nskip << 9); | ||
814 | } | ||
815 | } | 759 | } |
760 | cmd->last_xfer_len = 0; | ||
816 | } | 761 | } |
817 | 762 | ||
818 | if (ireason == 0) { | 763 | if (ireason == 0) { |
@@ -835,15 +780,15 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) | |||
835 | /* bio backed? */ | 780 | /* bio backed? */ |
836 | if (rq->bio) { | 781 | if (rq->bio) { |
837 | if (blk_fs_request(rq)) { | 782 | if (blk_fs_request(rq)) { |
838 | ptr = rq->buffer; | 783 | blen = min_t(int, thislen, cmd->nleft); |
839 | blen = rq->current_nr_sectors << 9; | ||
840 | } else { | 784 | } else { |
841 | ptr = bio_data(rq->bio); | 785 | ptr = bio_data(rq->bio); |
842 | blen = bio_iovec(rq->bio)->bv_len; | 786 | blen = bio_iovec(rq->bio)->bv_len; |
843 | } | 787 | } |
844 | } | 788 | } |
845 | 789 | ||
846 | if (!ptr) { | 790 | if ((blk_fs_request(rq) && cmd->nleft == 0) || |
791 | (blk_fs_request(rq) == 0 && ptr == NULL)) { | ||
847 | if (blk_fs_request(rq) && !write) | 792 | if (blk_fs_request(rq) && !write) |
848 | /* | 793 | /* |
849 | * If the buffers are full, pipe the rest into | 794 | * If the buffers are full, pipe the rest into |
@@ -863,26 +808,16 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) | |||
863 | if (blen > thislen) | 808 | if (blen > thislen) |
864 | blen = thislen; | 809 | blen = thislen; |
865 | 810 | ||
866 | xferfunc(drive, NULL, ptr, blen); | 811 | if (blk_fs_request(rq)) { |
812 | ide_pio_bytes(drive, cmd, write, blen); | ||
813 | cmd->last_xfer_len += blen; | ||
814 | } else | ||
815 | xferfunc(drive, NULL, ptr, blen); | ||
867 | 816 | ||
868 | thislen -= blen; | 817 | thislen -= blen; |
869 | len -= blen; | 818 | len -= blen; |
870 | 819 | ||
871 | if (blk_fs_request(rq)) { | 820 | if (blk_fs_request(rq) == 0) { |
872 | rq->buffer += blen; | ||
873 | rq->nr_sectors -= (blen >> 9); | ||
874 | rq->current_nr_sectors -= (blen >> 9); | ||
875 | rq->sector += (blen >> 9); | ||
876 | |||
877 | if (rq->current_nr_sectors == 0 && rq->nr_sectors) { | ||
878 | nsectors = rq->hard_cur_sectors; | ||
879 | |||
880 | if (nsectors == 0) | ||
881 | nsectors = 1; | ||
882 | |||
883 | ide_complete_rq(drive, 0, nsectors << 9); | ||
884 | } | ||
885 | } else { | ||
886 | rq->data_len -= blen; | 821 | rq->data_len -= blen; |
887 | 822 | ||
888 | /* | 823 | /* |
@@ -933,8 +868,10 @@ out_end: | |||
933 | ide_cd_complete_failed_rq(drive, rq); | 868 | ide_cd_complete_failed_rq(drive, rq); |
934 | 869 | ||
935 | if (blk_fs_request(rq)) { | 870 | if (blk_fs_request(rq)) { |
936 | if (rq->current_nr_sectors == 0) | 871 | if (cmd->nleft == 0) |
937 | uptodate = 1; | 872 | uptodate = 1; |
873 | if (uptodate == 0) | ||
874 | ide_cd_error_cmd(drive, cmd); | ||
938 | } else { | 875 | } else { |
939 | if (uptodate <= 0 && rq->errors == 0) | 876 | if (uptodate <= 0 && rq->errors == 0) |
940 | rq->errors = -EIO; | 877 | rq->errors = -EIO; |
@@ -944,7 +881,7 @@ out_end: | |||
944 | if (blk_pc_request(rq)) | 881 | if (blk_pc_request(rq)) |
945 | nsectors = (rq->data_len + 511) >> 9; | 882 | nsectors = (rq->data_len + 511) >> 9; |
946 | else | 883 | else |
947 | nsectors = rq->hard_cur_sectors; | 884 | nsectors = rq->hard_nr_sectors; |
948 | 885 | ||
949 | if (nsectors == 0) | 886 | if (nsectors == 0) |
950 | nsectors = 1; | 887 | nsectors = 1; |
@@ -960,9 +897,10 @@ out_end: | |||
960 | static ide_startstop_t cdrom_start_rw(ide_drive_t *drive, struct request *rq) | 897 | static ide_startstop_t cdrom_start_rw(ide_drive_t *drive, struct request *rq) |
961 | { | 898 | { |
962 | struct cdrom_info *cd = drive->driver_data; | 899 | struct cdrom_info *cd = drive->driver_data; |
900 | struct request_queue *q = drive->queue; | ||
963 | int write = rq_data_dir(rq) == WRITE; | 901 | int write = rq_data_dir(rq) == WRITE; |
964 | unsigned short sectors_per_frame = | 902 | unsigned short sectors_per_frame = |
965 | queue_hardsect_size(drive->queue) >> SECTOR_BITS; | 903 | queue_hardsect_size(q) >> SECTOR_BITS; |
966 | 904 | ||
967 | ide_debug_log(IDE_DBG_RQ, "rq->cmd[0]: 0x%x, write: 0x%x, " | 905 | ide_debug_log(IDE_DBG_RQ, "rq->cmd[0]: 0x%x, write: 0x%x, " |
968 | "secs_per_frame: %u", | 906 | "secs_per_frame: %u", |
@@ -977,17 +915,16 @@ static ide_startstop_t cdrom_start_rw(ide_drive_t *drive, struct request *rq) | |||
977 | * We may be retrying this request after an error. Fix up any | 915 | * We may be retrying this request after an error. Fix up any |
978 | * weirdness which might be present in the request packet. | 916 | * weirdness which might be present in the request packet. |
979 | */ | 917 | */ |
980 | ide_cd_restore_request(drive, rq); | 918 | q->prep_rq_fn(q, rq); |
981 | } | 919 | } |
982 | 920 | ||
983 | /* use DMA, if possible / writes *must* be hardware frame aligned */ | 921 | /* fs requests *must* be hardware frame aligned */ |
984 | if ((rq->nr_sectors & (sectors_per_frame - 1)) || | 922 | if ((rq->nr_sectors & (sectors_per_frame - 1)) || |
985 | (rq->sector & (sectors_per_frame - 1))) { | 923 | (rq->sector & (sectors_per_frame - 1))) |
986 | if (write) | 924 | return ide_stopped; |
987 | return ide_stopped; | 925 | |
988 | drive->dma = 0; | 926 | /* use DMA, if possible */ |
989 | } else | 927 | drive->dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA); |
990 | drive->dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA); | ||
991 | 928 | ||
992 | if (write) | 929 | if (write) |
993 | cd->devinfo.media_written = 1; | 930 | cd->devinfo.media_written = 1; |
@@ -1050,8 +987,6 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, | |||
1050 | if (blk_fs_request(rq)) { | 987 | if (blk_fs_request(rq)) { |
1051 | if (cdrom_start_rw(drive, rq) == ide_stopped || | 988 | if (cdrom_start_rw(drive, rq) == ide_stopped || |
1052 | ide_cd_prepare_rw_request(drive, rq) == ide_stopped) { | 989 | ide_cd_prepare_rw_request(drive, rq) == ide_stopped) { |
1053 | if (rq->current_nr_sectors == 0) | ||
1054 | uptodate = 1; | ||
1055 | goto out_end; | 990 | goto out_end; |
1056 | } | 991 | } |
1057 | } else if (blk_sense_request(rq) || blk_pc_request(rq) || | 992 | } else if (blk_sense_request(rq) || blk_pc_request(rq) || |
@@ -1078,6 +1013,11 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, | |||
1078 | 1013 | ||
1079 | cmd.rq = rq; | 1014 | cmd.rq = rq; |
1080 | 1015 | ||
1016 | if (blk_fs_request(rq)) { | ||
1017 | ide_init_sg_cmd(&cmd, rq->nr_sectors << 9); | ||
1018 | ide_map_sg(drive, &cmd); | ||
1019 | } | ||
1020 | |||
1081 | return ide_issue_pc(drive, &cmd); | 1021 | return ide_issue_pc(drive, &cmd); |
1082 | out_end: | 1022 | out_end: |
1083 | nsectors = rq->hard_nr_sectors; | 1023 | nsectors = rq->hard_nr_sectors; |
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c index 0e333ecf2ad6..a3b7a50562b2 100644 --- a/drivers/ide/ide-taskfile.c +++ b/drivers/ide/ide-taskfile.c | |||
@@ -188,8 +188,8 @@ static u8 wait_drive_not_busy(ide_drive_t *drive) | |||
188 | return stat; | 188 | return stat; |
189 | } | 189 | } |
190 | 190 | ||
191 | static void ide_pio_bytes(ide_drive_t *drive, struct ide_cmd *cmd, | 191 | void ide_pio_bytes(ide_drive_t *drive, struct ide_cmd *cmd, |
192 | unsigned int write, unsigned int len) | 192 | unsigned int write, unsigned int len) |
193 | { | 193 | { |
194 | ide_hwif_t *hwif = drive->hwif; | 194 | ide_hwif_t *hwif = drive->hwif; |
195 | struct scatterlist *sg = hwif->sg_table; | 195 | struct scatterlist *sg = hwif->sg_table; |
@@ -243,6 +243,7 @@ static void ide_pio_bytes(ide_drive_t *drive, struct ide_cmd *cmd, | |||
243 | len -= nr_bytes; | 243 | len -= nr_bytes; |
244 | } | 244 | } |
245 | } | 245 | } |
246 | EXPORT_SYMBOL_GPL(ide_pio_bytes); | ||
246 | 247 | ||
247 | static void ide_pio_datablock(ide_drive_t *drive, struct ide_cmd *cmd, | 248 | static void ide_pio_datablock(ide_drive_t *drive, struct ide_cmd *cmd, |
248 | unsigned int write) | 249 | unsigned int write) |
diff --git a/include/linux/ide.h b/include/linux/ide.h index d5d832271f44..c2841c0c36c8 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h | |||
@@ -352,6 +352,8 @@ struct ide_cmd { | |||
352 | 352 | ||
353 | unsigned int nbytes; | 353 | unsigned int nbytes; |
354 | unsigned int nleft; | 354 | unsigned int nleft; |
355 | unsigned int last_xfer_len; | ||
356 | |||
355 | struct scatterlist *cursg; | 357 | struct scatterlist *cursg; |
356 | unsigned int cursg_ofs; | 358 | unsigned int cursg_ofs; |
357 | 359 | ||
@@ -1226,6 +1228,8 @@ ide_startstop_t ide_issue_pc(ide_drive_t *, struct ide_cmd *); | |||
1226 | 1228 | ||
1227 | ide_startstop_t do_rw_taskfile(ide_drive_t *, struct ide_cmd *); | 1229 | ide_startstop_t do_rw_taskfile(ide_drive_t *, struct ide_cmd *); |
1228 | 1230 | ||
1231 | void ide_pio_bytes(ide_drive_t *, struct ide_cmd *, unsigned int, unsigned int); | ||
1232 | |||
1229 | void ide_finish_cmd(ide_drive_t *, struct ide_cmd *, u8); | 1233 | void ide_finish_cmd(ide_drive_t *, struct ide_cmd *, u8); |
1230 | 1234 | ||
1231 | int ide_raw_taskfile(ide_drive_t *, struct ide_cmd *, u8 *, u16); | 1235 | int ide_raw_taskfile(ide_drive_t *, struct ide_cmd *, u8 *, u16); |