aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide/ide-cd.c
diff options
context:
space:
mode:
authorBorislav Petkov <petkovbb@googlemail.com>2008-04-26 11:36:37 -0400
committerBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2008-04-26 11:36:37 -0400
commit968c49641338f4fb71d35352d49b1d25a68c5e93 (patch)
treefbff834006b20bfac4af6dbc70b951a31bc2f3af /drivers/ide/ide-cd.c
parent9841654949f0a3f1289b6b95b2ab56cd99fb5360 (diff)
ide-cd: remove the internal 64k buffer
This removes the internal ide-cd buffer and falls back to read-ahead block layer capabilities. Thorough testing (cd burning, dvd read, raw read) gives with the bufferless mode marginally better performance in addition to simplified code. bufferless: dd: reading `/dev/hdc': Input/output error 6238+0 records in 6238+0 records out 204406784 bytes (204 MB) copied, 259.891 s, 787 kB/s real 4m21.598s user 0m0.014s sys 0m0.744s with the old buffer (2.6.25-rc1): dd: reading `/dev/hdc': Input/output error 6238+0 records in 6238+0 records out 204406784 bytes (204 MB) copied, 262.893 s, 778 kB/s real 4m22.938s user 0m0.009s sys 0m0.771s Signed-off-by: Borislav Petkov <petkovbb@gmail.com> Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Diffstat (limited to 'drivers/ide/ide-cd.c')
-rw-r--r--drivers/ide/ide-cd.c123
1 files changed, 4 insertions, 119 deletions
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index fe5aefbf8339..5163f6069f8a 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -89,7 +89,6 @@ static void cdrom_saw_media_change (ide_drive_t *drive)
89 89
90 cd->cd_flags |= IDE_CD_FLAG_MEDIA_CHANGED; 90 cd->cd_flags |= IDE_CD_FLAG_MEDIA_CHANGED;
91 cd->cd_flags &= ~IDE_CD_FLAG_TOC_VALID; 91 cd->cd_flags &= ~IDE_CD_FLAG_TOC_VALID;
92 cd->nsectors_buffered = 0;
93} 92}
94 93
95static int cdrom_log_sense(ide_drive_t *drive, struct request *rq, 94static int cdrom_log_sense(ide_drive_t *drive, struct request *rq,
@@ -626,47 +625,6 @@ static void ide_cd_drain_data(ide_drive_t *drive, int nsects)
626} 625}
627 626
628/* 627/*
629 * Buffer up to SECTORS_TO_TRANSFER sectors from the drive in our sector
630 * buffer. Once the first sector is added, any subsequent sectors are
631 * assumed to be continuous (until the buffer is cleared). For the first
632 * sector added, SECTOR is its sector number. (SECTOR is then ignored until
633 * the buffer is cleared.)
634 */
635static void cdrom_buffer_sectors (ide_drive_t *drive, unsigned long sector,
636 int sectors_to_transfer)
637{
638 struct cdrom_info *info = drive->driver_data;
639
640 /* Number of sectors to read into the buffer. */
641 int sectors_to_buffer = min_t(int, sectors_to_transfer,
642 (SECTOR_BUFFER_SIZE >> SECTOR_BITS) -
643 info->nsectors_buffered);
644
645 char *dest;
646
647 /* If we couldn't get a buffer, don't try to buffer anything... */
648 if (info->buffer == NULL)
649 sectors_to_buffer = 0;
650
651 /* If this is the first sector in the buffer, remember its number. */
652 if (info->nsectors_buffered == 0)
653 info->sector_buffered = sector;
654
655 /* Read the data into the buffer. */
656 dest = info->buffer + info->nsectors_buffered * SECTOR_SIZE;
657 while (sectors_to_buffer > 0) {
658 HWIF(drive)->atapi_input_bytes(drive, dest, SECTOR_SIZE);
659 --sectors_to_buffer;
660 --sectors_to_transfer;
661 ++info->nsectors_buffered;
662 dest += SECTOR_SIZE;
663 }
664
665 /* Throw away any remaining data. */
666 ide_cd_drain_data(drive, sectors_to_transfer);
667}
668
669/*
670 * Check the contents of the interrupt reason register from the cdrom 628 * Check the contents of the interrupt reason register from the cdrom
671 * and attempt to recover if there are problems. Returns 0 if everything's 629 * and attempt to recover if there are problems. Returns 0 if everything's
672 * ok; nonzero if the request has been terminated. 630 * ok; nonzero if the request has been terminated.
@@ -734,65 +692,6 @@ static int ide_cd_check_transfer_size(ide_drive_t *drive, int len)
734 return 1; 692 return 1;
735} 693}
736 694
737/*
738 * Try to satisfy some of the current read request from our cached data.
739 * Returns nonzero if the request has been completed, zero otherwise.
740 */
741static int cdrom_read_from_buffer (ide_drive_t *drive)
742{
743 struct cdrom_info *info = drive->driver_data;
744 struct request *rq = HWGROUP(drive)->rq;
745 unsigned short sectors_per_frame;
746
747 sectors_per_frame = queue_hardsect_size(drive->queue) >> SECTOR_BITS;
748
749 /* Can't do anything if there's no buffer. */
750 if (info->buffer == NULL) return 0;
751
752 /* Loop while this request needs data and the next block is present
753 in our cache. */
754 while (rq->nr_sectors > 0 &&
755 rq->sector >= info->sector_buffered &&
756 rq->sector < info->sector_buffered + info->nsectors_buffered) {
757 if (rq->current_nr_sectors == 0)
758 cdrom_end_request(drive, 1);
759
760 memcpy (rq->buffer,
761 info->buffer +
762 (rq->sector - info->sector_buffered) * SECTOR_SIZE,
763 SECTOR_SIZE);
764 rq->buffer += SECTOR_SIZE;
765 --rq->current_nr_sectors;
766 --rq->nr_sectors;
767 ++rq->sector;
768 }
769
770 /* If we've satisfied the current request,
771 terminate it successfully. */
772 if (rq->nr_sectors == 0) {
773 cdrom_end_request(drive, 1);
774 return -1;
775 }
776
777 /* Move on to the next buffer if needed. */
778 if (rq->current_nr_sectors == 0)
779 cdrom_end_request(drive, 1);
780
781 /* If this condition does not hold, then the kluge i use to
782 represent the number of sectors to skip at the start of a transfer
783 will fail. I think that this will never happen, but let's be
784 paranoid and check. */
785 if (rq->current_nr_sectors < bio_cur_sectors(rq->bio) &&
786 (rq->sector & (sectors_per_frame - 1))) {
787 printk(KERN_ERR "%s: cdrom_read_from_buffer: buffer botch (%ld)\n",
788 drive->name, (long)rq->sector);
789 cdrom_end_request(drive, 0);
790 return -1;
791 }
792
793 return 0;
794}
795
796static ide_startstop_t cdrom_newpc_intr(ide_drive_t *); 695static ide_startstop_t cdrom_newpc_intr(ide_drive_t *);
797 696
798/* 697/*
@@ -1134,11 +1033,9 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
1134 if (!ptr) { 1033 if (!ptr) {
1135 if (blk_fs_request(rq) && !write) 1034 if (blk_fs_request(rq) && !write)
1136 /* 1035 /*
1137 * If the buffers are full, cache the rest 1036 * If the buffers are full, pipe the rest into
1138 * of the data in our internal buffer. 1037 * oblivion. */
1139 */ 1038 ide_cd_drain_data(drive, thislen >> 9);
1140 cdrom_buffer_sectors(drive, rq->sector,
1141 thislen >> 9);
1142 else { 1039 else {
1143 printk(KERN_ERR "%s: confused, missing data\n", 1040 printk(KERN_ERR "%s: confused, missing data\n",
1144 drive->name); 1041 drive->name);
@@ -1243,10 +1140,6 @@ static ide_startstop_t cdrom_start_rw(ide_drive_t *drive, struct request *rq)
1243 * weirdness which might be present in the request packet. 1140 * weirdness which might be present in the request packet.
1244 */ 1141 */
1245 restore_request(rq); 1142 restore_request(rq);
1246
1247 /* Satisfy whatever we can of this request from our cache. */
1248 if (cdrom_read_from_buffer(drive))
1249 return ide_stopped;
1250 } 1143 }
1251 1144
1252 /* 1145 /*
@@ -1262,9 +1155,6 @@ static ide_startstop_t cdrom_start_rw(ide_drive_t *drive, struct request *rq)
1262 } else 1155 } else
1263 cd->dma = drive->using_dma; 1156 cd->dma = drive->using_dma;
1264 1157
1265 /* Clear the local sector buffer. */
1266 cd->nsectors_buffered = 0;
1267
1268 if (write) 1158 if (write)
1269 cd->devinfo.media_written = 1; 1159 cd->devinfo.media_written = 1;
1270 1160
@@ -2030,7 +1920,6 @@ static void ide_cd_release(struct kref *kref)
2030 ide_drive_t *drive = info->drive; 1920 ide_drive_t *drive = info->drive;
2031 struct gendisk *g = info->disk; 1921 struct gendisk *g = info->disk;
2032 1922
2033 kfree(info->buffer);
2034 kfree(info->toc); 1923 kfree(info->toc);
2035 if (devinfo->handle == drive) 1924 if (devinfo->handle == drive)
2036 unregister_cdrom(devinfo); 1925 unregister_cdrom(devinfo);
@@ -2090,11 +1979,7 @@ static int idecd_open(struct inode * inode, struct file * file)
2090 if (!(info = ide_cd_get(disk))) 1979 if (!(info = ide_cd_get(disk)))
2091 return -ENXIO; 1980 return -ENXIO;
2092 1981
2093 if (!info->buffer) 1982 rc = cdrom_open(&info->devinfo, inode, file);
2094 info->buffer = kmalloc(SECTOR_BUFFER_SIZE, GFP_KERNEL|__GFP_REPEAT);
2095
2096 if (info->buffer)
2097 rc = cdrom_open(&info->devinfo, inode, file);
2098 1983
2099 if (rc < 0) 1984 if (rc < 0)
2100 ide_cd_put(info); 1985 ide_cd_put(info);