[xiph-commits] r15290 - in trunk/cdparanoia: . interface
xiphmont at svn.xiph.org
xiphmont at svn.xiph.org
Thu Sep 11 03:43:52 PDT 2008
Author: xiphmont
Date: 2008-09-11 03:43:52 -0700 (Thu, 11 Sep 2008)
New Revision: 15290
Modified:
trunk/cdparanoia/cachetest.c
trunk/cdparanoia/interface/cdda_interface.h
trunk/cdparanoia/interface/interface.c
trunk/cdparanoia/interface/low_interface.h
trunk/cdparanoia/interface/scsi_interface.c
Log:
Pending additional testing, the final cache tests are now integrated.
Eliminate the MMC commands that were added as an attempt to manage
cache through spec-mandated side effects; No surprise, but drives
don't seem to bother implementing spec correctly.
Modified: trunk/cdparanoia/cachetest.c
===================================================================
--- trunk/cdparanoia/cachetest.c 2008-09-11 06:01:07 UTC (rev 15289)
+++ trunk/cdparanoia/cachetest.c 2008-09-11 10:43:52 UTC (rev 15290)
@@ -35,7 +35,9 @@
#include "paranoia/cdda_paranoia.h"
#include "version.h"
-#define MIN_SEEK_MS 10
+/* not strictly just seeks, but also recapture and read resume when
+ reading/readahead is suspended and idling */
+#define MIN_SEEK_MS 6
#define reportC(...) {if(progress){fprintf(progress, __VA_ARGS__);} \
if(log){fprintf(log, __VA_ARGS__);}}
@@ -44,8 +46,7 @@
static int time_drive(cdrom_drive *d, FILE *progress, FILE *log, int lba, int len){
int i,j,x;
- int latency[len];
- int sectors[len];
+ int latency=0;
double sum=0;
double sumsq=0;
int sofar;
@@ -57,24 +58,22 @@
int toread = (i==0?1:len-sofar);
int ret;
/* first read should also trigger a short seek; one sector so seek duration dominates */
- if((ret=cdda_read(d,NULL,lba+sofar,toread))<=0){
+ if((ret=cdda_read_timed(d,NULL,lba+sofar,toread,&x))<=0){
/* media error! grr! retry elsewhere */
if(ret==-404)return -404;
return -1;
}
- x = cdda_milliseconds(d);
if(x>9999)x=9999;
if(x<0)x=0;
logC("%d:%d:%d ",lba+sofar,ret,x);
- latency[i]=x;
- sectors[i]=ret;
sofar+=ret;
if(i){
sum+=x;
sumsq+= x*x /(float)ret;
- }
+ }else
+ latency=x;
}
/* we count even the upper outliers because the drive is almost
@@ -86,8 +85,8 @@
double mean = sum/(float)(len-1);
double stddev = sqrt( (sumsq/(float)(len-1) - mean*mean));
- printC("%4dms seek, %.2fms/sec read [%.1fx]",latency[0],mean,1000./75./mean);
- logC("\n\tInitial seek latency (%d sectors): %dms",len,latency[0]);
+ printC("%4dms seek, %.2fms/sec read [%.1fx]",latency,mean,1000./75./mean);
+ logC("\n\tInitial seek latency (%d sectors): %dms",len,latency);
logC("\n\tAverage read latency: %.2fms/sector (raw speed: %.1fx)",mean,1000./75./mean);
logC("\n\tRead latency standard deviation: %.2fms/sector",stddev);
@@ -143,7 +142,7 @@
we're consistently hitting latency on the same sector during
initial collection, may need to move past it. */
- int i,j,ret;
+ int i,j,ret,x,x0;
int firstsector=-1;
int lastsector=-1;
int firsttest=-1;
@@ -261,7 +260,7 @@
}
}
- reportC("\n\nAnalyzing readahead cache access...\n");
+ reportC("\n\nAnalyzing cache behavior...\n");
/* search on cache size; cache hits are fast, seeks are not, so a
linear search through cache hits up to a miss are faster than a
@@ -295,13 +294,13 @@
reportC("\tFast search for approximate cache size... %d sectors ",current-1);
logC("\n");
- for(i=0;i<15 && !under;i++){
+ for(i=0;i<25 && !under;i++){
for(j=0;;j++){
int ret1,ret2;
- if(i>=5){
+ if(i>=15){
int sofar=0;
- if(i==5){
+ if(i==15){
printC("\r");
reportC("\tSlow verify for approximate cache size... %d sectors",current-1);
logC("\n");
@@ -318,17 +317,29 @@
logC("\t\t>>> ");
while(sofar<current){
- ret1 = cdda_read(d,NULL,offset+sofar,current-sofar);
- logC("slow_read=%d:%d:%d ",offset+sofar,ret1,cdda_milliseconds(d));
+ ret1 = cdda_read_timed(d,NULL,offset+sofar,current-sofar,&x);
+ logC("slow_read=%d:%d:%d ",offset+sofar,ret1,x);
if(ret1<=0)break;
sofar+=ret1;
}
}else{
- ret1 = cdda_read(d,NULL,offset+current-1,1);
- logC("\t\t>>> fast_read=%d:%d:%d ",offset+current-1,ret1,cdda_milliseconds(d));
+ ret1 = cdda_read_timed(d,NULL,offset+current-1,1,&x);
+ logC("\t\t>>> fast_read=%d:%d:%d ",offset+current-1,ret1,x);
+
+ /* Some drives are 'easily distracted' when readahead is
+ running ahead of the read cursor, causing accesses of
+ the earliest sectors in the cache to show bursty
+ latency. If there's no seek here after a borderline
+ long read of the earliest sector in the cache, then the
+ cache must not have been dumped yet. */
+
+ if(ret==1 && i && x<MIN_SEEK_MS){
+ under=1;
+ break;
+ }
}
- ret2 = cdda_read(d,NULL,offset,1);
- logC("seek_read=%d:%d:%d\n",offset,ret2,cdda_milliseconds(d));
+ ret2 = cdda_read_timed(d,NULL,offset,1,&x);
+ logC("seek_read=%d:%d:%d\n",offset,ret2,x);
if(ret1<=0 || ret2<=0){
offset+=current+100;
@@ -340,11 +351,11 @@
reportC("\n\tRead error while performing drive cache checks;"
"\n\t choosing new offset and trying again.\n");
}else{
- if(cdda_milliseconds(d)==-1){
+ if(x==-1){
reportC("\n\tTiming error while performing drive cache checks; aborting test.\n");
return(-1);
}else{
- if(cdda_milliseconds(d)<MIN_SEEK_MS){
+ if(x<MIN_SEEK_MS){
under=1;
}
break;
@@ -378,7 +389,6 @@
}
paranoia_free(p);
}
-
if(speed==-1){
logC("\tAttempting to reset read speed to full... ");
}else{
@@ -390,8 +400,6 @@
logC("drive said OK\n");
}
- goto fornow;
-
/* This is similar to the Fast search above, but just in case the
cache is being tracked as multiple areas that are treated
differently if non-contiguous.... */
@@ -412,10 +420,10 @@
}
- ret1 = cdda_read(d,NULL,offset+seekoff,1);
- logC("\t\t>>> %d:%d:%d ",offset+seekoff,ret1,cdda_milliseconds(d));
- ret2 = cdda_read(d,NULL,offset,1);
- logC("seek_read:%d:%d:%d\n",offset,ret2,cdda_milliseconds(d));
+ ret1 = cdda_read_timed(d,NULL,offset+seekoff,1,&x);
+ logC("\t\t>>> %d:%d:%d ",offset+seekoff,ret1,x);
+ ret2 = cdda_read_timed(d,NULL,offset,1,&x);
+ logC("seek_read:%d:%d:%d\n",offset,ret2,x);
if(ret1<=0 || ret2<=0){
offset+=cachesize+100;
@@ -427,11 +435,11 @@
reportC("\n\tRead error while performing drive cache checks;"
"\n\t choosing new offset and trying again.\n");
}else{
- if(cdda_milliseconds(d)==-1){
+ if(x==-1){
reportC("\n\tTiming error while performing drive cache checks; aborting test.\n");
return(-1);
}else{
- if(cdda_milliseconds(d)<MIN_SEEK_MS)under=1;
+ if(x<MIN_SEEK_MS)under=1;
break;
}
}
@@ -463,7 +471,7 @@
{
int lower=0;
int gran=64;
- int it=2;
+ int it=3;
int tests=0;
int under=1;
readahead=0;
@@ -473,7 +481,7 @@
if(tests>8 && gran<64){
gran<<=3;
tests=0;
- it=2;
+ it=3;
}
if(gran && !under){
gran>>=3;
@@ -493,9 +501,9 @@
logC("\n\t\t%d >>> ",i);
while(sofar<cachesize){
- ret = cdda_read(d,NULL,offset+sofar,cachesize-sofar);
+ ret = cdda_read_timed(d,NULL,offset+sofar,cachesize-sofar,&x);
if(ret<=0)goto error;
- logC("%d:%d:%d ",offset+sofar,ret,cdda_milliseconds(d));
+ logC("%d:%d:%d ",offset+sofar,ret,x);
/* some drives can lose sync and perform an internal resync,
which can also cause readahead to restart. If we see
@@ -509,7 +517,7 @@
/* what we'd predict is needed to let the readahead process work. */
{
- int usec=mspersector*(readahead)*(4+i)*500;
+ int usec=mspersector*(readahead)*(6+i)*200;
int max= 13000*2*readahead; /* corresponds to .5x */
if(usec>max)usec=max;
logC("sleep=%dus ",usec);
@@ -517,10 +525,10 @@
}
/* seek to offset+cachesize+readahead */
- ret = cdda_read(d,NULL,offset+cachesize+readahead-1,1);
+ ret = cdda_read_timed(d,NULL,offset+cachesize+readahead-1,1,&x);
if(ret<=0)break;
- logC("seek=%d:%d:%d",offset+cachesize+readahead-1,ret,cdda_milliseconds(d));
- if(cdda_milliseconds(d)<MIN_SEEK_MS){
+ logC("seek=%d:%d:%d",offset+cachesize+readahead-1,ret,x);
+ if(x<MIN_SEEK_MS){
under=1;
break;
}else if(i&1){
@@ -543,7 +551,7 @@
reportC("\tDrive readahead past read cursor: %d sector(s) \n",readahead);
}
- reportC("\tTesting cache tail cursor...");
+ reportC("\tTesting cache tail cursor...");
while(1){
rollbehind=cachesize;
@@ -553,15 +561,15 @@
logC("\n\t\t>>> ");
printC(".");
while(sofar<cachesize){
- ret = cdda_read(d,NULL,offset+sofar,cachesize-sofar);
+ ret = cdda_read_timed(d,NULL,offset+sofar,cachesize-sofar,&x);
if(ret<=0)goto error;
- logC("%d:%d:%d ",offset+sofar,ret,cdda_milliseconds(d));
+ logC("%d:%d:%d ",offset+sofar,ret,x);
sofar+=ret;
}
/* Pause what we'd predict is needed to let the readahead process work. */
{
- int usec=mspersector*readahead*5000;
+ int usec=mspersector*readahead*1500;
logC("\n\t\tsleeping %d microseconds",usec);
usleep(usec);
}
@@ -571,10 +579,10 @@
sofar=rollbehind;
while(sofar>0){
sofar--;
- ret = cdda_read(d,NULL,offset+sofar,1);
+ ret = cdda_read_timed(d,NULL,offset+sofar,1,&x);
if(ret<=0)break;
- logC("%d:%d:%d ",sofar,ret,cdda_milliseconds(d));
- if(cdda_milliseconds(d)>=MIN_SEEK_MS){
+ logC("%d:%d:%d ",sofar,ret,x);
+ if(x>=MIN_SEEK_MS){
rollbehind=sofar+1;
break;
}
@@ -616,7 +624,6 @@
}else{
reportC("\tCache tail rollbehind: %d sector(s) \n",rollbehind);
}
-
reportC("\tTesting granularity of cache tail");
while(1){
@@ -626,15 +633,15 @@
logC("\n\t\t>>> ");
printC(".");
while(sofar<cachesize+1){
- ret = cdda_read(d,NULL,offset+sofar,cachesize-sofar+1);
+ ret = cdda_read_timed(d,NULL,offset+sofar,cachesize-sofar+1,&x);
if(ret<=0)goto error2;
- logC("%d:%d:%d ",offset+sofar,ret,cdda_milliseconds(d));
+ logC("%d:%d:%d ",offset+sofar,ret,x);
sofar+=ret;
}
/* Pause what we'd predict is needed to let the readahead process work. */
{
- int usec=mspersector*readahead*5000;
+ int usec=mspersector*readahead*1500;
logC("\n\t\tsleeping %d microseconds",usec);
usleep(usec);
}
@@ -644,10 +651,10 @@
sofar=cachegran;
while(sofar){
sofar--;
- ret = cdda_read(d,NULL,offset+sofar,1);
+ ret = cdda_read_timed(d,NULL,offset+sofar,1,&x);
if(ret<=0)break;
- logC("%d:%d:%d ",offset+sofar,ret,cdda_milliseconds(d));
- if(cdda_milliseconds(d)>=MIN_SEEK_MS){
+ logC("%d:%d:%d ",offset+sofar,ret,x);
+ if(x>=MIN_SEEK_MS){
cachegran=sofar+1;
break;
}
@@ -704,83 +711,113 @@
or another and thus need to guard against slow bus transfer times
[eg, no DMA] swamping the actual read time from media. */
- /* sample cache access for ten realtime seconds. */
- //{
- //int cachems;
+ /* sample cache access for five realtime seconds. */
+ {
+ float cachems;
+ float readms;
+ int readsize = cachesize+readahead-rollbehind-4;
+ int retry;
- //reportC("\nVerifying that seeking before cache dumps readahead...");
- //reportC("\n\tSampling cache timing... ");
- //}
+ if(readsize>cachesize-1)readsize=cachesize-4;
- fornow:
- /* Check to see that cdda_clear_cache clears the specified cache area */
- if(cdda_clear_cache(d,firstsector+100,10)==-405){
- reportC("\tDrive/kernel does not allow cache management commands\n");
- }else{
- int fail=0;
- int success=0;
- int errors=0;
+ if(readsize<8){
+ reportC("\tCache size (minus rollbehind) too small to test cache speed.\n");
+ }else{
+ reportC("\tTesting cache transfer speed...");
+
+ /* cache timing isn't dependent on rotational speed, so get a good
+ read and then just hammer the cache; we will only need to do it once */
- reportC("\tTesting cache management commands...");
-
- for(i=0;i<10 && !fail;i++){
- int sofar=0,ret,retry=0;
- if(offset-1<firstsector)offset++;
-
- /* fill the readahead. */
- logC("\n\t\t>>> ");
- printC(".");
- while(sofar<cachesize){
- ret = cdda_read(d,NULL,offset+sofar,cachesize-sofar);
- if(ret<=0)goto error3;
- logC("%d:%d:%d ",offset+sofar,ret,cdda_milliseconds(d));
- sofar+=ret;
+ while(1){
+ int ret=time_drive(d, NULL, log, offset, readsize);
+ if(ret==-404) return -1;
+ if(ret>0)break;
+ retry++;
+ if(retry==10){
+ reportC("\n\tToo many read errors while performing drive cache checks;"
+ "\n\t aborting test.\n\n");
+ return(-1);
+ }
+ reportC("\n\tRead error while performing drive cache checks;"
+ "\n\t choosing new offset and trying again.\n");
}
- /* clear the readahead. */
- ret=cdda_clear_cache(d,offset,cachesize);
- logC("\n\t\tcdda_clear_cache(%d,%d)=%d ",offset,cachesize,ret);
- logC("\n\t\t<<< ");
-
- if(ret==0)success++;
-
- /* reread an area ahead of the rollback, checking for seek */
{
- int loc=offset+cachesize/2;//+cachesize - ((cachesize - rollbehind)*(i>>1)/5) - 1;
- ret = cdda_read(d,NULL,loc,1);
- if(ret<=0)goto error3;
- logC("%d:%d:%d ",loc,ret,cdda_milliseconds(d));
- if(cdda_milliseconds(d)<MIN_SEEK_MS) fail=1;
+ int elapsed=0;
+ int sectors=0;
+ int spinner=0;
+ while(elapsed<5000){
+ sectors += (readsize-1);
+ elapsed += time_drive(d, NULL, log, offset, readsize);
+ spinner = elapsed*5/1000%4;
+ printC("\b%c",(spinner==0?'o':(spinner==1?'O':(spinner==2?'o':'.'))));
+ }
+ printC("\r");
+ logC("\n");
+ cachems = elapsed/(float)sectors;
+ reportC("\t Cache read speed: %.2fms/sector [%dx]\n",
+ cachems,(int)(1000./75./cachems));
}
- continue;
- error3:
- errors++;
- if(errors<5){
- reportC("\n\tRead error while performing drive cache checks; trying again.\n");
+ if(cachems*3>mspersector){
+ reportC("\tCache access insufficiently faster than media access to\n"
+ "\t\tperform cache backseek tests\n\n");
}else{
- reportC("\n\tToo many read errors while performing drive cache checks;"
- "\n\t aborting test.\n\n");
- return(-1);
- }
- }
+
+ /* now do the read/backseek combo */
+ reportC("\tTesting that backseek flushes cache...");
+ {
+ int elapsed=0;
+ int sectors=0;
+ int spinner=0;
+ int retry=0;
+ while(elapsed<5000){
+ int ret;
+ while(1){
+ /* need to force seek/flush, but don't kill the drive */
+ int seekpos = offset+cachesize+20000;
+ if(seekpos>lastsector-150)seekpos=lastsector-150;
+ ret=cdda_read(d, NULL, seekpos, 1);
+ if(ret>0) ret=time_drive(d, NULL, log, offset+1, readsize);
+ if(ret>=0) ret=time_drive(d, NULL, log, offset, readsize);
- if(fail){
- warn=1;
- reportC("\nWARNING: Drive supports cache management commands, but does not"
- "\n implement commands correctly/according to spec. This"
- "\n will almost certainly break Paranoia.\n");
- }else{
- if(success){
- printC("\r");
- reportC("\tCache management commands clear cache as mandated by spec ");
- }else{
- printC("\r");
- reportC("\tDrive rejected cache management commands... odd, but not fatal");
+ if(ret<=0){
+ retry++;
+ if(retry==10){
+ reportC("\n\tToo many read errors while performing drive cache checks;"
+ "\n\t aborting test.\n\n");
+ return(-1);
+ }
+ reportC("\n\tRead error while performing drive cache checks; retrying...");
+ }else
+ break;
+ }
+
+ sectors += (readsize-1);
+ elapsed += ret;
+
+ spinner = elapsed*5/1000%4;
+ printC("\b%c",(spinner==0?'o':(spinner==1?'O':(spinner==2?'o':'.'))));
+ }
+
+ printC("\r");
+ logC("\n");
+ readms = elapsed/(float)sectors;
+ reportC("\t Access speed after backseek: %.2fms/sector [%dx]\n",
+ readms,(int)(1000./75./readms));
+ if(readms*2. < mspersector ||
+ cachems*2. > readms){
+ reportC("\tWARNING: Read timing after backseek faster than expected!\n"
+ "\t It's possible/likely that this drive is not\n"
+ "\t flushing the readahead cache on backward seeks!\n\n");
+ warn=1;
+ }else{
+ reportC("\tBackseek flushes the cache as expected\n");
+ }
+ }
}
}
}
- /* Does cdda_clear_cache result in noncontiguous cache areas? */
Modified: trunk/cdparanoia/interface/cdda_interface.h
===================================================================
--- trunk/cdparanoia/interface/cdda_interface.h 2008-09-11 06:01:07 UTC (rev 15289)
+++ trunk/cdparanoia/interface/cdda_interface.h 2008-09-11 10:43:52 UTC (rev 15290)
@@ -131,8 +131,8 @@
extern int cdda_open(cdrom_drive *d);
extern long cdda_read(cdrom_drive *d, void *buffer,
long beginsector, long sectors);
-extern int cdda_clear_cache(cdrom_drive *d, int lba, int sectors);
-extern int cdda_milliseconds(cdrom_drive *d);
+extern long cdda_read_timed(cdrom_drive *d, void *buffer,
+ long beginsector, long sectors, int *milliseconds);
extern long cdda_track_firstsector(cdrom_drive *d,int track);
extern long cdda_track_lastsector(cdrom_drive *d,int track);
Modified: trunk/cdparanoia/interface/interface.c
===================================================================
--- trunk/cdparanoia/interface/interface.c 2008-09-11 06:01:07 UTC (rev 15289)
+++ trunk/cdparanoia/interface/interface.c 2008-09-11 10:43:52 UTC (rev 15290)
@@ -107,7 +107,8 @@
return -405;
}
-long cdda_read(cdrom_drive *d, void *buffer, long beginsector, long sectors){
+long cdda_read_timed(cdrom_drive *d, void *buffer, long beginsector, long sectors, int *ms){
+ if(ms)*ms= -1;
if(d->opened){
if(sectors>0){
sectors=d->read_audio(d,buffer,beginsector,sectors);
@@ -126,6 +127,7 @@
}
}
}
+ if(ms)*ms=d->private->last_milliseconds;
return(sectors);
}
@@ -133,25 +135,10 @@
return(-400);
}
-/* Failure to clear the cache returns an error code but does not add a
- message to the message queue; this allows simpler code that assumes
- it can always issue a cache request, even if it's possible/likely
- it won't succeed */
-int cdda_clear_cache(cdrom_drive *d, int lba, int sectors){
- if(!d->opened)return -400;
- if(!d->private->cache_clear) return -405;
- return d->private->cache_clear(d,lba,sectors);
+long cdda_read(cdrom_drive *d, void *buffer, long beginsector, long sectors){
+ return cdda_read_timed(d,buffer,beginsector,sectors,NULL);
}
-/* Returns a (pessimistic) millisecond value for the duration of the
- last CDROM command; useful for looking for seek operations in the
- paranoia code. Does not return errors, only < 0 for no
- measurement.*/
-int cdda_milliseconds(cdrom_drive *d){
- if(!d->opened)return -1;
- return d->private->last_milliseconds;
-}
-
void cdda_verbose_set(cdrom_drive *d,int err_action, int mes_action){
d->messagedest=mes_action;
d->errordest=err_action;
Modified: trunk/cdparanoia/interface/low_interface.h
===================================================================
--- trunk/cdparanoia/interface/low_interface.h 2008-09-11 06:01:07 UTC (rev 15289)
+++ trunk/cdparanoia/interface/low_interface.h 2008-09-11 10:43:52 UTC (rev 15290)
@@ -102,8 +102,6 @@
unsigned char *sg_buffer; /* points into sg_hd */
clockid_t clock;
int last_milliseconds;
-
- int (*cache_clear) (struct cdrom_drive *d, int lba, int sectors);
};
#define MAX_RETRIES 8
Modified: trunk/cdparanoia/interface/scsi_interface.c
===================================================================
--- trunk/cdparanoia/interface/scsi_interface.c 2008-09-11 06:01:07 UTC (rev 15289)
+++ trunk/cdparanoia/interface/scsi_interface.c 2008-09-11 10:43:52 UTC (rev 15290)
@@ -73,14 +73,10 @@
* Updated: but we don't always get -ENOMEM. Sometimes USB drives
* still fail the wrong way. This needs some kernel-land investigation.
*/
- /* additional reason to use a low sector count by default: the
- paranoia code now includes code to watch timing during operations
- that should produce seeks, assuming that cachebusting works
- properly. If the machine in question is using PIO, larger atomic
- reads will require enough time to mask seeks. */
+ /* Bumping to 55 sector transfer max --Monty */
if (!getenv("CDDA_IGNORE_BUFSIZE_LIMIT")) {
- cur=(cur>1024*32?1024*32:cur);
+ cur=((cur+CD_FRAMESIZE_RAW-1)/CD_FRAMESIZE_RAW>55?55*CD_FRAMESIZE_RAW:cur);
}else{
cdmessage(d,"\tEnvironment variable CDDA_IGNORE_BUFSIZE_LIMIT set,\n"
"\t\tforcing maximum possible sector size. This can break\n"
@@ -804,29 +800,6 @@
return handle_scsi_cmd(d,cmd,12,0,0,0,0,sense);
}
-/* 'abuse' the set read ahead into manipulating the cache */
-static int mmc_cache_clear (cdrom_drive *d, int begin, int sectors){
- unsigned char cmd[12]={0xA7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
- unsigned char sense[SG_MAX_SENSE];
- int end=begin+sectors,ret;
- begin--;
-
- if(begin<0)return -1;
-
- cmd[2] = (begin >> 24) & 0xFF;
- cmd[3] = (begin >> 16) & 0xFF;
- cmd[4] = (begin >> 8) & 0xFF;
- cmd[5] = (begin) & 0xFF;
-
- cmd[6] = (end >> 24) & 0xFF;
- cmd[7] = (end >> 16) & 0xFF;
- cmd[8] = (end >> 8) & 0xFF;
- cmd[9] = (end) & 0xFF;
-
- ret = handle_scsi_cmd(d,cmd,12,0,0,0,0,sense);
- return ret;
-}
-
/* These do one 'extra' copy in the name of clean code */
static int i_read_28 (cdrom_drive *d, void *p, long begin, long sectors, unsigned char *sense){
@@ -1099,7 +1072,7 @@
while(1) {
- if(mmc_cache_clear (d, begin, sectors) || (err=map(d,(p?buffer:NULL),begin,sectors,sense))){
+ if((err=map(d,(p?buffer:NULL),begin,sectors,sense))){
if(d->report_all){
char b[256];
@@ -1577,41 +1550,13 @@
static void check_cache(cdrom_drive *d){
long i;
- if(d->read_audio==scsi_read_mmc ||
+ if(!(d->read_audio==scsi_read_mmc ||
d->read_audio==scsi_read_mmc2 ||
d->read_audio==scsi_read_mmc3 ||
d->read_audio==scsi_read_mmcB ||
d->read_audio==scsi_read_mmc2B ||
- d->read_audio==scsi_read_mmc3B){
+ d->read_audio==scsi_read_mmc3B)){
- cdmessage(d,"\nThis command set may allow read cache control.");
- cdmessage(d,"\nChecking drive for SET READ AHEAD command...\n");
-
- for(i=1;i<=d->tracks;i++){
- if(cdda_track_audiop(d,i)==1){
- long firstsector=cdda_track_firstsector(d,i);
- long lastsector=cdda_track_lastsector(d,i);
- int ret;
-
- if((ret=mmc_cache_clear(d,firstsector+1,lastsector-firstsector-1))==0){
- cdmessage(d,"\tDrive accepted SET READ AHEAD command.\n");
- d->private->cache_clear=mmc_cache_clear;
- return;
- }
- if(ret==-EPERM){
- cderror(d,"\nWARNING: Kernel block command filter is refusing to pass the\n"
- " SET_READ_AHEAD command. Please see:\n"
- " http://www.xiph.org/paranoia/trouble.html#blockfilter\n\n"
- " for more information on correcting or working around\n"
- " the problem.\n\n");
- break;
- }
- }
- }
- cdmessage(d,"\tSET READ AHEAD command failed; using fallback.\n");
-
- }else{
-
cdmessage(d,"This command set may use a Force Unit Access bit.");
cdmessage(d,"\nChecking drive for FUA bit support...\n");
More information about the commits
mailing list