aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/ide/ide-cd.c146
-rw-r--r--drivers/ide/ide-taskfile.c5
-rw-r--r--include/linux/ide.h4
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 */
580static 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
600static void ide_cd_request_sense_fixup(ide_drive_t *drive, struct request *rq) 548static 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
641static 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)
703static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) 662static 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:
960static ide_startstop_t cdrom_start_rw(ide_drive_t *drive, struct request *rq) 897static 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);
1082out_end: 1022out_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
191static void ide_pio_bytes(ide_drive_t *drive, struct ide_cmd *cmd, 191void 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}
246EXPORT_SYMBOL_GPL(ide_pio_bytes);
246 247
247static void ide_pio_datablock(ide_drive_t *drive, struct ide_cmd *cmd, 248static 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
1227ide_startstop_t do_rw_taskfile(ide_drive_t *, struct ide_cmd *); 1229ide_startstop_t do_rw_taskfile(ide_drive_t *, struct ide_cmd *);
1228 1230
1231void ide_pio_bytes(ide_drive_t *, struct ide_cmd *, unsigned int, unsigned int);
1232
1229void ide_finish_cmd(ide_drive_t *, struct ide_cmd *, u8); 1233void ide_finish_cmd(ide_drive_t *, struct ide_cmd *, u8);
1230 1234
1231int ide_raw_taskfile(ide_drive_t *, struct ide_cmd *, u8 *, u16); 1235int ide_raw_taskfile(ide_drive_t *, struct ide_cmd *, u8 *, u16);