[xiph-cvs] cvs commit: paranoia-III/paranoia cdda_paranoia.h paranoia.c

Monty xiphmont at xiph.org
Fri Mar 23 17:15:48 PST 2001



xiphmont    01/03/23 17:15:47

  Modified:    .        cdparanoia.1 main.c version.h
               interface cdda_interface.h scan_devices.c scsi_interface.c
               paranoia cdda_paranoia.h paranoia.c
  Log:
  First round of maintainence commits toward 9.8
  
  Monty

Revision  Changes    Path
1.7       +8 -2      paranoia-III/cdparanoia.1

Index: cdparanoia.1
===================================================================
RCS file: /usr/local/cvsroot/paranoia-III/cdparanoia.1,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- cdparanoia.1	1999/12/14 08:18:43	1.6
+++ cdparanoia.1	2001/03/24 01:15:45	1.7
@@ -2,7 +2,7 @@
 .SH NAME
 cdparanoia (Paranoia release III) \- an audio CD reading utility which includes extra data verification features
 .SH DATE
-version III release alpha 9.7 (13 Dec 1999)
+version III release alpha 9.8 (02 Mar 2001)
 .SH SYNOPSIS
 .B cdparanoia
 .RB [ options ]
@@ -165,9 +165,15 @@
 is active.
 
 .TP
+.B \-z --never-skip[=max_retries]
+Do not accept any skips; retry forever if needed.  An optional maximum
+number of retries can be specified; for comparison, default without -z is
+currently 20.
+
+.TP
 .B \-Y --disable-extra-paranoia
 Disables intra-read data verification; only overlap checking at read
-boundaries is performed. Not recommended.
+boundaries is performed. It can wedge if errors occur in the attempted overlap area. Not recommended.
 
 .TP
 .B \-X --abort-on-skip

1.19      +15 -9     paranoia-III/main.c

Index: main.c
===================================================================
RCS file: /usr/local/cvsroot/paranoia-III/main.c,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -r1.18 -r1.19
--- main.c	2000/04/19 22:41:04	1.18
+++ main.c	2001/03/24 01:15:45	1.19
@@ -248,9 +248,7 @@
 "  -R --output-raw-big-endian      : output raw 16 bit big-endian PCM\n"
 "  -w --output-wav                 : output as WAV file (default)\n"
 "  -f --output-aiff                : output as AIFF file\n"
-"  -a --output-aifc                : output as AIFF-C file\n"
-"  -i --output-info <file>         : output human readable ripping info to\n"
-"                                    file\n\n"
+"  -a --output-aifc                : output as AIFF-C file\n\n"
 
 "  -c --force-cdrom-little-endian  : force treating drive as little endian\n"
 "  -C --force-cdrom-big-endian     : force treating drive as big endian\n"
@@ -269,8 +267,10 @@
 "                                    addressed as LBA 0.  Necessary for some\n"
 "                                    Toshiba drives to get track boundaries\n"
 "                                    correct\n"
-"  -z --never-skip                 : never accept any less than perfect\n"
+"  -z --never-skip[=n]             : never accept any less than perfect\n"
 "                                    data reconstruction (don't allow 'V's)\n"
+"                                    but if [n] is given, skip after [n]\n"
+"                                    retries without progress.\n"
 "  -Z --disable-paranoia           : disable all paranoia checking\n"
 "  -Y --disable-extra-paranoia     : only do cdda2wav-style overlap checking\n"
 "  -X --abort-on-skip              : abort on imperfect reads/skips\n\n"
@@ -583,7 +583,7 @@
     memset(dispcache,' ',graph);
 }
 
-const char *optstring = "escCn:o:d:g:S:prRwafvqVQhZzYXWBi:Tt:";
+const char *optstring = "escCn:o:d:g:S:prRwafvqVQhZz::YXWBi:Tt:";
 
 struct option options [] = {
         {"stderr-progress",no_argument,NULL,'e'},
@@ -614,7 +614,7 @@
         {"abort-on-skip",no_argument,NULL,'X'},
         {"disable-fragmentation",no_argument,NULL,'F'},
         {"output-info",required_argument,NULL,'i'},
-	{"never-skip",no_argument,NULL,'z'},
+	{"never-skip",optional_argument,NULL,'z'},
 
         {NULL,0,NULL,0}
 };
@@ -651,6 +651,7 @@
   char *force_cdrom_device=NULL;
   char *force_generic_device=NULL;
   int force_cdrom_speed=-1;
+  int max_retries=20;
   char *span=NULL;
   int output_type=1; /* 0=raw, 1=wav, 2=aifc */
   int output_endian=0; /* -1=host, 0=little, 1=big */
@@ -750,7 +751,12 @@
       paranoia_mode=PARANOIA_MODE_DISABLE; 
       break;
     case 'z':
-      paranoia_mode|=PARANOIA_MODE_NEVERSKIP; 
+      if (optarg) {
+        max_retries = atoi (optarg);
+        paranoia_mode&=~PARANOIA_MODE_NEVERSKIP;
+      } else {
+        paranoia_mode|=PARANOIA_MODE_NEVERSKIP;
+      }
       break;
     case 'Y':
       paranoia_mode|=PARANOIA_MODE_OVERLAP; /* cdda2wav style overlap 
@@ -818,7 +824,7 @@
             verbose=1;
             report("\n/dev/cdrom exists but isn't accessible.  By default,\n"
                    "cdparanoia stops searching for an accessible drive here.\n"
-		   "Consider using -s to force a more complete autosense\n"
+		   "Consider using -sv to force a more complete autosense\n"
                    "of the machine.\n\nMore information about /dev/cdrom:");
 
             d=cdda_identify("/dev/cdrom",CDDA_MESSAGE_PRINTIT,NULL);
@@ -1150,7 +1156,7 @@
         skipped_flag=0;
         while(cursor<=batch_last){
           /* read a sector */
-	  int16_t *readbuf=paranoia_read(p,callback);
+	  int16_t *readbuf=paranoia_read_limited(p,callback,max_retries);
           char *err=cdda_errors(d);
           char *mes=cdda_messages(d);
 

1.19      +4 -4      paranoia-III/version.h

Index: version.h
===================================================================
RCS file: /usr/local/cvsroot/paranoia-III/version.h,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -r1.18 -r1.19
--- version.h	1999/12/14 04:27:57	1.18
+++ version.h	2001/03/24 01:15:45	1.19
@@ -1,13 +1,13 @@
 /******************************************************************
  * CopyPolicy: GNU Public License 2 applies
  * 
- * cdda_paranoia generation III release 9.7
- * Copyright (C) 1999 Monty monty at xiph.org, xiphmont at mit.edu
+ * cdda_paranoia generation III release 9.8
+ * Copyright (C) 2001 Monty monty at xiph.org, xiphmont at mit.edu
  *
  ******************************************************************/
 
 
-#define VERSION "cdparanoia III release 9.7 (December 13, 1999)\n"\
-                "(C) 1999 Monty <monty at xiph.org> and Xiphophorus\n\n"\
+#define VERSION "cdparanoia III release 9.8 (March 23, 2001)\n"\
+                "(C) 2001 Monty <monty at xiph.org> and Xiphophorus\n\n"\
                 "Report bugs to paranoia at xiph.org\n"\
                 "http://www.xiph.org/paranoia/\n"

1.9       +1 -1      paranoia-III/interface/cdda_interface.h

Index: cdda_interface.h
===================================================================
RCS file: /usr/local/cvsroot/paranoia-III/interface/cdda_interface.h,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- cdda_interface.h	2000/03/26 07:33:22	1.8
+++ cdda_interface.h	2001/03/24 01:15:46	1.9
@@ -1,6 +1,6 @@
 /******************************************************************
  * CopyPolicy: GNU Public License 2 applies
- * Copyright (C) 1998 Monty xiphmont at mit.edu
+ * Copyright (C) 2001 Xiph.org
  * and Heiko Eissfeldt heiko at escape.colossus.de
  *
  * Toplevel interface header; applications include this

1.16      +59 -31    paranoia-III/interface/scan_devices.c

Index: scan_devices.c
===================================================================
RCS file: /usr/local/cvsroot/paranoia-III/interface/scan_devices.c,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- scan_devices.c	1999/12/14 07:30:23	1.15
+++ scan_devices.c	2001/03/24 01:15:46	1.16
@@ -283,11 +283,8 @@
   int lun;
 } scsiid;
 
-#ifndef SCSI_IOCTL_GET_BUS_NUMBER
-#define SCSI_IOCTL_GET_BUS_NUMBER 0x5386
-#endif
-
 /* Even *this* isn't as simple as it bloody well should be :-P */
+/* SG has an easy interface, but SCSI overall does not */
 static int get_scsi_id(int fd, scsiid *id){
   struct sg_id argid;
   int busarg;
@@ -307,10 +304,9 @@
 }
 
 /* slightly wasteful, but a clean abstraction */
-static char *scsi_match(const char *device,char **prefixes,int perma,
-			int permb,char *prompt,int messagedest,
-			char **messages){
-  int dev=open(device,perma);
+static char *scsi_match(const char *device,char **prefixes,
+			char *prompt,int messagedest,char **messages){
+  int dev=open(device,O_RDONLY|O_NONBLOCK);
   scsiid a,b;
 
   int i,j;
@@ -348,7 +344,7 @@
           break;
         }
         
-	matchf=open(buffer,permb);
+	matchf=open(buffer,O_RDONLY|O_NONBLOCK);
         if(matchf!=-1){
           if(get_scsi_id(matchf,&b)==0){
             if(a.bus==b.bus && a.id==b.id && a.lun==b.lun){
@@ -382,6 +378,36 @@
   strcat(a," ");
 }
 
+/* At this point, we're going to punt compatability before SG2, and
+   allow only SG2 and SG3 */
+static int verify_SG_version(cdrom_drive *d,int messagedest,
+			     char **messages){
+  /* are we using the new SG driver by Doug Gilbert? If not, punt */
+  int version,major,minor;
+  char buffer[256];
+  idmessage(messagedest,messages,
+	    "\nFound an accessible SCSI CDROM drive."
+	    "\nLooking at revision of the SG interface in use...","");
+
+  if(ioctl(d->cdda_fd,SG_GET_VERSION_NUM,&version)){
+    /* Up, guess not. */
+    idmessage(messagedest,messages,
+	      "\tOOPS!  Old 2.0/early 2.1/early 2.2.x (non-ac patch) style "
+	      "SG.\n\tCdparanoia no longer supports the old interface.\n","");
+    return(0);
+  }
+  major=version/10000;
+  version-=major*10000;
+  minor=version/100;
+  version-=minor*100;
+  
+  sprintf(buffer,"\tSG interface version %d.%d.%d; OK.",
+	  major,minor,version);
+
+  idmessage(messagedest,messages,buffer,"");
+  return(major);
+}
+
 cdrom_drive *cdda_identify_scsi(const char *generic_device, 
                                 const char *ioctl_device, int messagedest,
                                 char **messages){
@@ -391,6 +417,7 @@
   struct stat g_st;
   int i_fd=-1;
   int g_fd=-1;
+  int version;
   int type;
   char *p;
 
@@ -456,13 +483,13 @@
 
   if(!generic_device || !ioctl_device){
     if(generic_device){
-      ioctl_device=scsi_match(generic_device,scsi_cdrom_prefixes,O_RDWR,
-			      O_RDONLY|O_NONBLOCK,
-			      "\t\tNo cdrom device found to match generic device %s",
-			      messagedest,messages);
+      ioctl_device=
+	scsi_match(generic_device,scsi_cdrom_prefixes,
+		   "\t\tNo cdrom device found to match generic device %s",
+		   messagedest,messages);
     }else{
       generic_device=
-	scsi_match(ioctl_device,scsi_generic_prefixes,O_RDONLY|O_NONBLOCK,O_RDWR,
+	scsi_match(ioctl_device,scsi_generic_prefixes,
                    "\t\tNo generic SCSI device found to match CDROM device %s",
                    messagedest,messages);
       if(!generic_device)	
@@ -483,7 +510,7 @@
   }
 
   if(ioctl_device)i_fd=open(ioctl_device,O_RDONLY|O_NONBLOCK);
-  g_fd=open(generic_device,O_RDWR|O_EXCL);
+  g_fd=open(generic_device,O_RDWR);
   
   if(ioctl_device && i_fd==-1)
     idperror(messagedest,messages,"\t\tCould not open SCSI cdrom device "
@@ -529,28 +556,29 @@
     goto cdda_identify_scsi_fail;
   }
   
-  d=calloc(1,sizeof(cdrom_drive));
-
-  /* build signal set to block for during generic scsi; we really *don't*
-     want to die between the SCSI write and reading the result. */
-
-  sigemptyset (&(d->sigset));
-  sigaddset (&(d->sigset), SIGINT);
-  sigaddset (&(d->sigset), SIGTERM);
-  sigaddset (&(d->sigset), SIGPIPE);
-  sigaddset (&(d->sigset), SIGPROF);
 
-  /* malloc our big buffer for scsi commands */
-  d->sg=malloc(MAX_BIG_BUFF_SIZE);
-  d->sg_buffer=d->sg+SG_OFF;
+  d=calloc(1,sizeof(cdrom_drive));
 
   d->drive_type=type;
   d->cdda_fd=g_fd;
   d->ioctl_fd=i_fd;
-  d->interface=GENERIC_SCSI;
   d->bigendianp=-1; /* We don't know yet... */
   d->nsectors=-1;
 
+  version=verify_SG_version(d,messagedest,messages);
+  switch(version){
+  case -1:case 0:case 1:
+    d->interface=GENERIC_SCSI;
+    goto cdda_identify_scsi_fail;
+  case 2:case 3:
+    d->interface=GENERIC_SCSI;
+    break;
+  }
+
+  /* malloc our big buffer for scsi commands */
+  d->sg=malloc(MAX_BIG_BUFF_SIZE);
+  d->sg_buffer=d->sg+SG_OFF;
+
   {
     /* get the lun */
     scsiid lun;
@@ -562,7 +590,7 @@
 
   p = scsi_inquiry(d);
 
-  /* It would seem some TOSHIBA CDROM gets things wrong */
+  /* It would seem some TOSHIBA CDROMs gets things wrong */
  
   if (!strncmp (p + 8, "TOSHIBA", 7) &&
       !strncmp (p + 16, "CD-ROM", 6) &&
@@ -589,7 +617,7 @@
   strscat(d->drive_model,p+16,16);
   strscat(d->drive_model,p+32,4);
 
-  idmessage(messagedest,messages,"\t\tCDROM sensed: %s",d->drive_model);
+  idmessage(messagedest,messages,"\nCDROM model sensed sensed: %s",d->drive_model);
   
   return(d);
   

1.21      +137 -241  paranoia-III/interface/scsi_interface.c

Index: scsi_interface.c
===================================================================
RCS file: /usr/local/cvsroot/paranoia-III/interface/scsi_interface.c,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -r1.20 -r1.21
--- scsi_interface.c	2000/04/19 22:41:04	1.20
+++ scsi_interface.c	2001/03/24 01:15:46	1.21
@@ -19,37 +19,19 @@
 
 #include "drive_exceptions.h"
 
-#ifndef SG_GET_RESERVED_SIZE
-#define SG_GET_RESERVED_SIZE 0x2272
-#endif 
-
-#ifndef SG_GET_SG_TABLESIZE
-#define SG_GET_SG_TABLESIZE 0x227F
-#endif 
-
-#ifndef SG_SET_COMMAND_Q
-#define SG_SET_COMMAND_Q 0x2271 
-#endif
-
-static int look_for_dougg(cdrom_drive *d){
-  /* are we using the new SG driver by Doug Gilbert? If so, our memory
-     strategy will be different. */
-  int reserved,table;
-  cdmessage(d,"\nLooking at revision of the SG interface in use...\n");
+static void tweak_SG_buffer(cdrom_drive *d){
+  int table,reserved;
+  char buffer[256];
 
+  /* maximum transfer size? */
   if(ioctl(d->cdda_fd,SG_GET_RESERVED_SIZE,&reserved)){
     /* Up, guess not. */
-    cdmessage(d,"\tOld 2.0/early 2.1/early 2.2.x (non-ac patch) style SG.\n");
-    return(0);
+    cdmessage(d,"\tCould not get scatter/gather buffer size.\n");
+    return;
   }
-  cdmessage(d,"\tNew style SG with scatter/gather memory management\n");
-
-  /* maximum transfer size? */
 
   if(ioctl(d->cdda_fd,SG_GET_SG_TABLESIZE,&table))table=1;
-
   {
-    char buffer[256];
     int cur;
 
     sprintf(buffer,"\tDMA scatter/gather table entries: %d\n\t"
@@ -66,80 +48,30 @@
     d->nsectors=cur/CD_FRAMESIZE_RAW;
     d->bigbuff=cur;
 
-    sprintf(buffer,"\tSetting default read size to %d sectors (%d bytes).\n",
+    sprintf(buffer,"\tSetting default read size to %d sectors (%d bytes).\n\n",
             d->nsectors,d->nsectors*CD_FRAMESIZE_RAW);
     cdmessage(d,buffer);
   } 
 
-  /* Disable command queue; we don;t need it, no reason to have it on */
+  /* Disable command queue; we don't need it, no reason to have it on */
   reserved=0;
   if(ioctl(d->cdda_fd,SG_SET_COMMAND_Q,&reserved)){
     cdmessage(d,"\tCouldn't disable command queue!  Continuing anyway...\n");
   }
 
-  return(1);
 }
 
-static void find_bloody_big_buff_size(cdrom_drive *d){
-
-  /* find the biggest read command that succeeds.  This should be
-     safe; the kernel will reject requests that are too big. */
-
-  long begin=cdda_disc_firstsector(d);
-  long cur=MAX_BIG_BUFF_SIZE/CD_FRAMESIZE_RAW;
-  cdmessage(d,"\nAttempting to autosense SG_BIG_BUFF size...\n");
-
-  d->enable_cdda(d,1);
-  if(begin==-1){
-    cur=1; /* 4096 is hardwired into linux/drivers/scsi/sg.c */
-  }else{
-
-    /* bisection is not fastest here; requests that are too big are 
-       rejected quickly */
-    /* Also, we bloody well try more than one sector juuuust in case
-       we hit an unaddressable one. */
-
-    while(cur>1){
-      long i;
-      int flag=0;
-      d->nsectors=cur;
-      
-      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);
-	  long sector=(firstsector+lastsector)>>1;
-	  
-	  errno=0;
-	  d->read_audio(d,NULL,sector,cur);
-	  if(errno!=ENOMEM)flag=1;
-	  break;
-
-	}
-      }
-      if(flag)break;
-      cur--;
-    }
-  }
-  d->enable_cdda(d,0);
-  {
-    char buffer[256];
-    sprintf(buffer,"\tSetting read block size at %ld sectors (%ld bytes).\n",
-	    cur,cur*CD_FRAMESIZE_RAW);
-    cdmessage(d,buffer);
-  }
-  d->nsectors=cur;
-  d->bigbuff=cur*CD_FRAMESIZE_RAW;
-
-}
-
 static void reset_scsi(cdrom_drive *d){
-
-  /* really ought to close the fd and reopen */
-
+  int arg;
   d->enable_cdda(d,0);
-  d->enable_cdda(d,1);
 
+  cdmessage(d,"sending SG SCSI reset... ");
+  if(ioctl(d->cdda_fd,SG_SCSI_RESET,&arg))
+    cdmessage(d,"FAILED: EBUSY\n");
+  else
+    cdmessage(d,"OK\n");
+  
+  d->enable_cdda(d,1);
 }
 
 static void clear_garbage(cdrom_drive *d){
@@ -178,6 +110,7 @@
                            unsigned int cmd_len, 
                            unsigned int in_size, 
                            unsigned int out_size,
+
                            unsigned char bytefill,
                            int bytecheck){
   int status = 0;
@@ -826,6 +759,66 @@
   return(0);
 }
 
+/* straight from the MMC3 spec */
+static inline void LBA_to_MSF(long lba,
+			      unsigned char *M, 
+			      unsigned char *S, 
+			      unsigned char *F){
+  if(lba>=-150){
+    *M=(lba+150)/(60*75);
+    lba-=(*M)*60*75;
+    *S=(lba+150)/75;
+    lba-=(*S)*75;
+    *F=(lba+150);
+  }else{
+    *M=(lba+450150)/(60*75);
+    lba-=(*M)*60*75;
+    *S=(lba+450150)/75;
+    lba-=(*S)*75;
+    *F=(lba+450150);
+  }
+}
+
+
+static int i_read_msf (cdrom_drive *d, void *p, long begin, long sectors){
+  int ret;
+  memcpy(d->sg_buffer,(char []){0xb9, 0, 0, 0, 0, 0, 0, 0, 0, 0x10, 0, 0},12);
+
+  LBA_to_MSF(begin,d->sg_buffer+3,d->sg_buffer+4,d->sg_buffer+5);
+  LBA_to_MSF(begin+sectors,d->sg_buffer+6,d->sg_buffer+7,d->sg_buffer+8);
+
+  if((ret=handle_scsi_cmd(d,12,0,sectors * CD_FRAMESIZE_RAW,'\177',1)))
+    return(ret);
+  if(p)memcpy(p,d->sg_buffer,sectors*CD_FRAMESIZE_RAW);
+  return(0);
+}
+
+static int i_read_msf2 (cdrom_drive *d, void *p, long begin, long sectors){
+  int ret;
+  memcpy(d->sg_buffer,(char []){0xb9, 0, 0, 0, 0, 0, 0, 0, 0, 0xf8, 0, 0},12);
+
+  LBA_to_MSF(begin,d->sg_buffer+3,d->sg_buffer+4,d->sg_buffer+5);
+  LBA_to_MSF(begin+sectors,d->sg_buffer+6,d->sg_buffer+7,d->sg_buffer+8);
+
+  if((ret=handle_scsi_cmd(d,12,0,sectors * CD_FRAMESIZE_RAW,'\177',1)))
+    return(ret);
+  if(p)memcpy(p,d->sg_buffer,sectors*CD_FRAMESIZE_RAW);
+  return(0);
+}
+
+static int i_read_msf3 (cdrom_drive *d, void *p, long begin, long sectors){
+  int ret;
+  memcpy(d->sg_buffer,(char []){0xb9, 4, 0, 0, 0, 0, 0, 0, 0, 0xf8, 0, 0},12);
+
+  LBA_to_MSF(begin,d->sg_buffer+3,d->sg_buffer+4,d->sg_buffer+5);
+  LBA_to_MSF(begin+sectors,d->sg_buffer+6,d->sg_buffer+7,d->sg_buffer+8);
+
+  if((ret=handle_scsi_cmd(d,12,0,sectors * CD_FRAMESIZE_RAW,'\177',1)))
+    return(ret);
+  if(p)memcpy(p,d->sg_buffer,sectors*CD_FRAMESIZE_RAW);
+  return(0);
+}
+
 static long scsi_read_map (cdrom_drive *d, void *p, long begin, long sectors,
                           int (*map)(cdrom_drive *, void *, long, long)){
   int retry_count,err;
@@ -872,27 +865,22 @@
         usleep(100);
         continue;
       case ENOMEM:
-	if(d->bigbuff==0){
-	  /* just testing for SG_BIG_BUFF */
-	  return(-7);
-	}else{
-	  /* D'oh.  Possible kernel error. Keep limping */
-	  usleep(100);
-	  if(sectors==1){
-	    /* Nope, can't continue */
-	    cderror(d,"300: Kernel memory error\n");
-	    return(-300);  
-	  }
-	  if(d->report_all){
-	    char b[256];
-	    sprintf(b,"scsi_read: kernel couldn't alloc %ld bytes.  "
-		    "backing off...\n",sectors*CD_FRAMESIZE_RAW);
+	/* D'oh.  Possible kernel error. Keep limping */
+	usleep(100);
+	if(sectors==1){
+	  /* Nope, can't continue */
+	  cderror(d,"300: Kernel memory error\n");
+	  return(-300);  
+	}
+	if(d->report_all){
+	  char b[256];
+	  sprintf(b,"scsi_read: kernel couldn't alloc %ld bytes.  "
+		  "backing off...\n",sectors*CD_FRAMESIZE_RAW);
             
-	    cdmessage(d,b);
-	  }
-	  sectors--;
-	  continue;
+	  cdmessage(d,b);
         }
+	sectors--;
+	continue;
       default:
         if(sectors==1){
           if(errno==EIO)
@@ -1003,6 +991,22 @@
   return(scsi_read_map(d,p,begin,sectors,i_read_mmc3));
 }
 
+long scsi_read_msf (cdrom_drive *d, void *p, long begin, 
+			       long sectors){
+  return(scsi_read_map(d,p,begin,sectors,i_read_msf));
+}
+
+long scsi_read_msf2 (cdrom_drive *d, void *p, long begin, 
+			       long sectors){
+  return(scsi_read_map(d,p,begin,sectors,i_read_msf2));
+}
+
+long scsi_read_msf3 (cdrom_drive *d, void *p, long begin, 
+			       long sectors){
+  return(scsi_read_map(d,p,begin,sectors,i_read_msf3));
+}
+
+
 /* Some drives, given an audio read command, return only 2048 bytes
    of data as opposed to 2352 bytes.  Look for bytess at the end of the
    single sector verification read */
@@ -1122,19 +1126,36 @@
         rs="be 04,f8";
         densitypossible=0;
         break;
+
       case 5:
+	d->read_audio=scsi_read_msf;
+	rs="b9 00,10";
+	densitypossible=0;
+	break;
+      case 6:
+	d->read_audio=scsi_read_msf2;
+	rs="b9 00,f8";
+	densitypossible=0;
+	break;
+      case 7:
+	d->read_audio=scsi_read_msf3;
+	rs="b9 04,f8";
+	densitypossible=0;
+	break;
+
+      case 8:
         d->read_audio=scsi_read_D4_10;
         rs="d4(10)0x";
         break;
-      case 6:
+      case 9:
         d->read_audio=scsi_read_D4_12;
         rs="d4(12)0x";
         break;
-      case 7:
+      case 10:
         d->read_audio=scsi_read_D5;
         rs="d5 0x,00";
         break;
-      case 8:
+      case 11:
         d->read_audio=scsi_read_D8;
         rs="d8 0x,00";
         j=-2;
@@ -1194,8 +1215,6 @@
                   if((lengthflag=count_2352_bytes(d))==2352){
                     if(verify_nonzero(d)){
                       cdmessage(d,"\t\tCommand set FOUND!\n");
-		      cdmessage(d,"\t\t(please email a copy of this "
-				"output to paranoia at xiph.org)\n");
                       
                       free(buff);
                       d->enable_cdda(d,0);
@@ -1288,133 +1307,17 @@
   return;
 }
 
-static int guess_atapi(cdrom_drive *d,int reportp){
-  /* Use an Inquiry request to guess drive type. */
-  
-  /* the fields in byte 3 of the response serve different purposes in
-     ATAPI an SCSI and we can probably distinguish the two, but not
-     always */
-
-  /* Check our known weird drives.... */
-  {
-    int i=0;
-    while(atapi_list[i].model){
-      if(!strncmp(atapi_list[i].model,d->drive_model,strlen(atapi_list[i].model)))
-	if(atapi_list[i].atapi!=-1){
-	  if(reportp)
-	    cdmessage(d,"\tThis drive appears on the 'known exceptions' list:\n");
-	  if(atapi_list[i].atapi){
-	    if(reportp)
-	      cdmessage(d,"\tDrive is ATAPI (using SCSI host adaptor emulation)\n");
-	  }else{
-	    if(reportp)cdmessage(d,"\tDrive is SCSI\n");
-	  }
-	  return(atapi_list[i].atapi);
-	}
-      i++;
-    }
-  }
-
-  /* No exception listing.  What does byte 3 say? */
-
-  /* Low 4 bits are data format; 0 is SCSI-I or early ATAPI,
-                                 1 is modern ATAPI or SCSI-1 CCS
-				 2 is SCSI-II (or future ATAPI?)
-				 3 is reserved (SCSI-III?) */
-
-  /* high 4 bits are ATAPI version in ATAPI and AENC/TrmIOP/Reserved in SCSI */
-
-  /* How I see it:
-     (&0x3f) 0x00 SCSI-I
-     (&0x3f) 0x01 SCSI-1 CCS 
-     (&0x3f) 0x02 SCSI-II
-     0x20 early ATAPI
-     0x21 modern ATAPI
-     0x31 Mt FUJI ATAPI
-     0x03 SCSI-III?  dunno... */
-
-  /* News flash: a good number of ATAPI drives out there seem not to
-     bother setting the 0x20 bit, and come out looking like SCSI-1-CCS. */
-
-  if(reportp){
-    char buffer[256];
-    sprintf(buffer,"\tInquiry bytes: 0x%02x 0x%02x 0x%02x 0x%02x\n",
-	    (int)d->inqbytes[0],
-	    (int)d->inqbytes[1],
-	    (int)d->inqbytes[2],
-	    (int)d->inqbytes[3]);
-    cdmessage(d,buffer);
-  }
-
-  switch(d->inqbytes[3]){
-  case 0x20:
-    /* early ATAPI */
-    if(reportp){
-      cderror(d,"\tDrive appears to be early (pre-draft) ATAPI\n");
-      cderror(d,"\tThis drive will probably break cdparanoia; please send\n");
-      cderror(d,"\temail to paranoia at xiph.org\n");
-    }
-    return(1);
-  case 0x01:
-    /* ATAPI reporting as SCSI-1-CCS most likely */
-    if(reportp)
-      cdmessage(d,"\tDrive is reporting itself as SCSI-1-CCS, but is\n"
-		  "\tprobably just a buggy/broken ATAPI drive.  Assuming\n"
-		  "\tATAPI.\n");
-    return(1);
-  case 0x21:
-    /* modern ATAPI */
-    if(reportp)
-      cdmessage(d,"\tDrive appears to be standard ATAPI\n");
-    return(1);
-  case 0x30:
-    /* Old Mt Fuji? */
-    if(reportp)
-      cdmessage(d,"\tDrive appears to be an early Mt. Fuji ATAPI CD/DVD\n");
-    return(1);
-  case 0x31:
-    /* Mt Fuji */
-    if(reportp)
-      cdmessage(d,"\tDrive appears to be Mt. Fuji ATAPI C/DVD\n");
-    return(1);
-  default:
-    if(reportp)
-      switch(d->inqbytes[3]&0x0f){
-      case 0x0:
-	cdmessage(d,"\tDrive appears to be SCSI-1\n");
-	break;
-      case 0x1:
-	cdmessage(d,"\tDrive appears to be SCSI-1-CCS\n");
-	break;
-      case 0x2:
-	cdmessage(d,"\tDrive appears to be SCSI-2\n");
-	break;
-      case 0x3:
-	cdmessage(d,"\tUnknown type, perhaps SCSI-3?\n");
-	break;
-      default:
-	cdmessage(d,"\tUnknown drive type; assuming SCSI\n");
-	break;
-      }
-  }
-  return(0);
-}
-
 static int check_atapi(cdrom_drive *d){
   int atapiret=-1;
   int fd = d->cdda_fd; /* this is the correct fd (not ioctl_fd), as the 
                           generic device is the device we need to check */
                           
-  cdmessage(d,"\nChecking for SCSI emulation and transport revision...\n");
+  cdmessage(d,"\nChecking for SCSI emulation...\n");
 
-  /* This isn't as strightforward as it should be */
-
-  /* first, we try the SG_EMULATED_HOST ioctl; this only exists in new
-     kernels though */
-
-  if (ioctl(fd,SG_EMULATED_HOST,&atapiret))
-    cdmessage(d,"\tNo SG_EMULATED_HOST ioctl(); Checking inquiry command...\n");
-  else {
+  if (ioctl(fd,SG_EMULATED_HOST,&atapiret)){
+    cderror(d,"\tSG_EMULATED_HOST ioctl() failed!\n");
+    return(-1);
+  } else {
     if(atapiret==1){
       cdmessage(d,"\tDrive is ATAPI (using SCSI host adaptor emulation)\n");
       /* Disable kernel SCSI command translation layer for access through sg */
@@ -1426,15 +1329,8 @@
       d->is_atapi=0;
     }
 
-    if(guess_atapi(d,0)!=d->is_atapi){
-      cderror(d,"\tNOTE: Our ATAPI/SCSI guessing algorithm will detect the\n");
-      cderror(d,"\tdrive type incorrectly on older kernels; please e-mail the\n");
-      cderror(d,"\toutput of 'cdparanoia -vQ' to paranoia at xiph.org\n");
-    }
     return(d->is_atapi);
   }
-  
-  return(d->is_atapi=guess_atapi(d,1));
 }  
 
 static int check_mmc(cdrom_drive *d){
@@ -1494,6 +1390,7 @@
   return (d->sg_buffer);
 }
 
+
 int scsi_init_drive(cdrom_drive *d){
   int ret;
 
@@ -1509,7 +1406,7 @@
       
   if(d->is_mmc){
 
-    d->read_audio = scsi_read_mmc3;
+    d->read_audio = scsi_read_mmc2;
     d->bigendianp=0;
 
     check_exceptions(d,mmc_list);
@@ -1519,7 +1416,7 @@
     if(d->is_atapi){
       /* Not MMC maybe still uses 0xbe */
 
-      d->read_audio = scsi_read_mmc3;
+      d->read_audio = scsi_read_mmc2;
       d->bigendianp=0;
 
       check_exceptions(d,atapi_list);
@@ -1554,17 +1451,16 @@
   if(d->tracks<1)
     return(d->tracks);
 
+  tweak_SG_buffer(d);
   d->opened=1;
 
   if((ret=verify_read_command(d)))return(ret);
   check_fua_bit(d);
 
-  if(!look_for_dougg(d))
-    if(d->nsectors<1)find_bloody_big_buff_size(d);
-
   d->error_retry=1;
   d->sg=realloc(d->sg,d->nsectors*CD_FRAMESIZE_RAW + SG_OFF + 128);
   d->sg_buffer=d->sg+SG_OFF;
   d->report_all=1;
   return(0);
 }
+

1.9       +1 -0      paranoia-III/paranoia/cdda_paranoia.h

Index: cdda_paranoia.h
===================================================================
RCS file: /usr/local/cvsroot/paranoia-III/paranoia/cdda_paranoia.h,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- cdda_paranoia.h	2000/04/19 22:41:04	1.8
+++ cdda_paranoia.h	2001/03/24 01:15:47	1.9
@@ -41,6 +41,7 @@
 extern void paranoia_modeset(cdrom_paranoia *p,int mode);
 extern long paranoia_seek(cdrom_paranoia *p,long seek,int mode);
 extern int16_t *paranoia_read(cdrom_paranoia *p,void(*callback)(long,int));
+extern int16_t *paranoia_read_limited(cdrom_paranoia *p,void(*callback)(long,int),int maxretries);
 extern void paranoia_free(cdrom_paranoia *p);
 extern void paranoia_overlapset(cdrom_paranoia *p,long overlap);
 

1.19      +9 -1      paranoia-III/paranoia/paranoia.c

Index: paranoia.c
===================================================================
RCS file: /usr/local/cvsroot/paranoia-III/paranoia/paranoia.c,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -r1.18 -r1.19
--- paranoia.c	2000/04/19 22:41:04	1.18
+++ paranoia.c	2001/03/24 01:15:47	1.19
@@ -1189,7 +1189,15 @@
    persist only until the next call to paranoia_read() for this p */
 
 int16_t *paranoia_read(cdrom_paranoia *p, void(*callback)(long,int)){
+  return paranoia_read_limited(p,callback,20);
+}
 
+  /* I added max_retry functionality this way in order to avoid
+     breaking any old apps using the nerw libs.  cdparanoia 9.8 will
+     need the updated libs, but nothing else will require it. */
+int16_t *paranoia_read_limited(cdrom_paranoia *p, void(*callback)(long,int),
+			       int max_retries){
+
   long beginword=p->cursor*(CD_FRAMEWORDS);
   long endword=beginword+CD_FRAMEWORDS;
   long retry_count=0,lastend=-2;
@@ -1283,7 +1291,7 @@
 
       if(retry_count%5==0){
         if(p->dynoverlap==MAX_SECTOR_OVERLAP*CD_FRAMEWORDS ||
-	   retry_count==20){
+	   retry_count==max_retries){
           if(!(p->enable&PARANOIA_MODE_NEVERSKIP))verify_skip_case(p,callback);
           retry_count=0;
         }else{

--- >8 ----
List archives:  http://www.xiph.org/archives/
Ogg project homepage: http://www.xiph.org/ogg/
To unsubscribe from this list, send a message to 'cvs-request at xiph.org'
containing only the word 'unsubscribe' in the body.  No subject is needed.
Unsubscribe messages sent to the list will be ignored/filtered.



More information about the commits mailing list