apply patches
This commit is contained in:
commit
1a17599fcc
|
@ -32,10 +32,10 @@ export VERSION
|
|||
|
||||
ifeq ($(STATIC),TRUE)
|
||||
LIBS = interface/libcdda_interface.a paranoia/libcdda_paranoia.a \
|
||||
-static -lm -lrt
|
||||
-static -lm -lrt @LIBCAM@
|
||||
LIBDEP = interface/libcdda_interface.a paranoia/libcdda_paranoia.a
|
||||
else
|
||||
LIBS = -lcdda_interface -lcdda_paranoia -lm -lrt
|
||||
LIBS = -lcdda_interface -lcdda_paranoia -lm -lrt @LIBCAM@
|
||||
LIBDEP = interface/libcdda_interface.so paranoia/libcdda_paranoia.so
|
||||
endif
|
||||
|
||||
|
|
119
cdparanoia.1
119
cdparanoia.1
|
@ -1,16 +1,17 @@
|
|||
.TH CDPARANOIA 1 "11 Sep 2008"
|
||||
.SH NAME
|
||||
cdparanoia 10.2 (Paranoia release III) \- an audio CD reading utility which includes extra data verification features
|
||||
cdparanoia \- an audio CD reading utility which includes extra data verification features
|
||||
.SH SYNOPSIS
|
||||
.B cdparanoia
|
||||
.RB [ options ]
|
||||
.B span
|
||||
.RB [ outfile ]
|
||||
.RB | \-B
|
||||
.SH DESCRIPTION
|
||||
.B cdparanoia
|
||||
retrieves audio tracks from CDDA capable CDROM drives. The data can
|
||||
retrieves audio tracks from CDDA-capable CDROM drives. The data can
|
||||
be saved to a file or directed to standard output in WAV, AIFF, AIFF-C
|
||||
or raw format. Most ATAPI, SCSI and several proprietary CDROM drive
|
||||
or raw format. Most ATAPI and SCSI and several proprietary CDROM drive
|
||||
makes are supported;
|
||||
.B cdparanoia
|
||||
can determine if the target drive is CDDA capable.
|
||||
|
@ -24,12 +25,12 @@ and scratch reconstruction capability.
|
|||
.TP
|
||||
.B \-A --analyze-drive
|
||||
Run and log a complete analysis of drive caching, timing and reading behavior;
|
||||
verifies that cdparanoia is correctly modelling a sprcific drive's cache and
|
||||
verifies that cdparanoia is correctly modelling a specific drive's cache and
|
||||
read behavior. Implies -vQL.
|
||||
|
||||
.TP
|
||||
.B \-v --verbose
|
||||
Be absurdly verbose about the autosensing and reading process. Good
|
||||
Be absurdly verbose about the auto-sensing and reading process. Good
|
||||
for setup and debugging.
|
||||
|
||||
.TP
|
||||
|
@ -46,7 +47,7 @@ Save result summary to file, default filename cdparanoia.log.
|
|||
|
||||
.TP
|
||||
.B \-L --log-debug [file]
|
||||
Save detailed device autosense and debugging output to a file, default filename cdparanoia.log.
|
||||
Save detailed device auto-sense and debugging output to a file, default filename cdparanoia.log.
|
||||
|
||||
.TP
|
||||
.B \-V --version
|
||||
|
@ -54,12 +55,12 @@ Print the program version and quit.
|
|||
|
||||
.TP
|
||||
.B \-Q --query
|
||||
Perform CDROM drive autosense, query and print the CDROM table of
|
||||
Perform CDROM drive auto-sense, query and print the CDROM table of
|
||||
contents, then quit.
|
||||
|
||||
.TP
|
||||
.B \-s --search-for-drive
|
||||
Forces a complete search for a cdrom drive, even if the /dev/cdrom link exists.
|
||||
Forces a complete search for a CDROM drive, even if the /dev/cdrom link exists.
|
||||
|
||||
.TP
|
||||
.B \-h --help
|
||||
|
@ -69,7 +70,7 @@ usage and options.
|
|||
|
||||
.TP
|
||||
.B \-p --output-raw
|
||||
Output headerless data as raw 16 bit PCM data with interleaved samples in host byte order. To force little or big endian byte order, use
|
||||
Output headerless data as raw 16-bit PCM data with interleaved samples in host byte order. To force little or big endian byte order, use
|
||||
.B \-r
|
||||
or
|
||||
.B \-R
|
||||
|
@ -77,40 +78,46 @@ as described below.
|
|||
|
||||
.TP
|
||||
.B \-r --output-raw-little-endian
|
||||
Output headerless data as raw 16 bit PCM data with interleaved samples in LSB first byte order.
|
||||
Output headerless data as raw 16-bit PCM data with interleaved samples in LSB first byte order.
|
||||
|
||||
.TP
|
||||
.B \-R --output-raw-big-endian
|
||||
Output headerless data as raw 16 bit PCM data with interleaved samples in MSB first byte order.
|
||||
Output headerless data as raw 16-bit PCM data with interleaved samples in MSB first byte order.
|
||||
|
||||
.TP
|
||||
.B \-w --output-wav
|
||||
Output data in Micro$oft RIFF WAV format (note that WAV data is always
|
||||
LSB first byte order).
|
||||
LSB-first byte order).
|
||||
|
||||
.TP
|
||||
.B \-f --output-aiff
|
||||
Output data in Apple AIFF format (note that AIFC data is
|
||||
always in MSB first byte order).
|
||||
always in MSB-first byte order).
|
||||
|
||||
.TP
|
||||
.B \-a --output-aifc
|
||||
Output data in uncompressed Apple AIFF-C format (note that AIFF-C data is
|
||||
always in MSB first byte order).
|
||||
always in MSB-first byte order).
|
||||
|
||||
.TP
|
||||
.BI "\-B --batch "
|
||||
|
||||
Cdda2wav-style batch output flag; cdparanoia will split the output
|
||||
Cdda2wav-style batch output flag;
|
||||
.B cdparanoia
|
||||
will split the output
|
||||
into multiple files at track boundaries. Output file names are
|
||||
prepended with 'track#.'
|
||||
|
||||
.TP
|
||||
.B \-c --force-cdrom-little-endian
|
||||
Some CDROM drives misreport their endianness (or do not report it at
|
||||
all); it's possible that cdparanoia will guess wrong. Use
|
||||
all); it's possible that
|
||||
.B cdparanoia
|
||||
will guess wrong. Use
|
||||
.B \-c
|
||||
to force cdparanoia to treat the drive as a little endian device.
|
||||
to force
|
||||
.B cdparanoia
|
||||
to treat the drive as a little endian device.
|
||||
|
||||
.TP
|
||||
.B \-C --force-cdrom-big-endian
|
||||
|
@ -122,7 +129,7 @@ Force the interface backend to do atomic reads of
|
|||
.B n
|
||||
sectors per read. This number can be misleading; the kernel will often
|
||||
split read requests into multiple atomic reads (the automated Paranoia
|
||||
code is aware of this) or allow reads only wihin a restricted size
|
||||
code is aware of this) or allow reads only within a restricted size
|
||||
range.
|
||||
.B This option should generally not be used.
|
||||
|
||||
|
@ -131,13 +138,13 @@ range.
|
|||
Force the interface backend to read from
|
||||
.B device
|
||||
rather than the first readable CDROM drive it finds. This can be used
|
||||
to specify devices of any valid interface type (ATAPI, SCSI or
|
||||
to specify devices of any valid interface type (ATAPI, SCSI, or
|
||||
proprietary).
|
||||
|
||||
.TP
|
||||
.BI "\-k --force-cooked-device " device
|
||||
This option forces use of the old 'cooked ioctl' kernel
|
||||
interface with the specified cdrom device. The cooked ioctl interface
|
||||
interface with the specified CDROM device. The cooked ioctl interface
|
||||
is obsolete in Linux 2.6 if it is present at all.
|
||||
.B \-k
|
||||
cannot be used
|
||||
|
@ -149,22 +156,22 @@ or
|
|||
|
||||
.TP
|
||||
.BI "\-g --force-generic-device " device
|
||||
This option forces use of the old 'generic scsi' (sg) kernel
|
||||
interface with the specified generic scsi device.
|
||||
This option forces use of the old 'generic SCSI' (sg) kernel
|
||||
interface with the specified generic SCSI device.
|
||||
.B \-g
|
||||
cannot be used with
|
||||
.BR \-k .
|
||||
.B \-g
|
||||
may be used with
|
||||
.B \-d
|
||||
to explicitly set both the SCSI cdrom and
|
||||
generic (sg) devices seperately. This option is only useful on
|
||||
obsolete SCSI setups and when using the generic scsi (sg) driver.
|
||||
to explicitly set both the SCSI carom and
|
||||
generic (sg) devices separately. This option is only useful on
|
||||
obsolete SCSI setups and when using the generic SCSI (sg) driver.
|
||||
|
||||
.TP
|
||||
.BI "\-S --force-read-speed " number
|
||||
Use this option explicitly to set the read rate of the CD drive (where
|
||||
supported). This can reduce underruns on machines with slow disks, or
|
||||
supported). This can reduce underruns on machines that have slow disks, or
|
||||
which are low on memory.
|
||||
|
||||
.TP
|
||||
|
@ -184,16 +191,19 @@ every track seeming to start too late (losing a bit of the beginning
|
|||
and catching a bit of the next track).
|
||||
.B \-T
|
||||
accounts for this behavior. Note that this option will cause
|
||||
cdparanoia to attempt to read sectors before or past the known user
|
||||
.B cdparanoia
|
||||
to attempt to read sectors before or past the known user
|
||||
data area of the disc, resulting in read errors at disc edges on most
|
||||
drives and possibly even hard lockups on some buggy hardware.
|
||||
|
||||
.TP
|
||||
.BI "\-O --sample-offset " number
|
||||
Use this option to force the entire disc to shift sample position
|
||||
output by the given amount; This can be used to shift track boundaries
|
||||
output by the given amount; this can be used to shift track boundaries
|
||||
for the whole disc manually on sample granularity. Note that this will
|
||||
cause cdparanoia to attempt to read partial sectors before or past the
|
||||
cause
|
||||
.B cdparanoia
|
||||
to attempt to read partial sectors before or past the
|
||||
known user data area of the disc, probably causing read errors on most
|
||||
drives and possibly even hard lockups on some buggy hardware.
|
||||
|
||||
|
@ -202,8 +212,11 @@ drives and possibly even hard lockups on some buggy hardware.
|
|||
.B \-Z --disable-paranoia
|
||||
Disable
|
||||
.B all
|
||||
data verification and correction features. When using -Z, cdparanoia
|
||||
reads data exactly as would cdda2wav with an overlap setting of zero.
|
||||
data verification and correction features. When using -Z,
|
||||
.B cdparanoia
|
||||
reads data exactly as would
|
||||
.BR cdda2wav (1)
|
||||
with an overlap setting of zero.
|
||||
This option implies that
|
||||
.B \-Y
|
||||
is active.
|
||||
|
@ -211,7 +224,9 @@ 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
|
||||
number of retries can be specified; for comparison, default without
|
||||
.B -z
|
||||
is
|
||||
currently 20.
|
||||
|
||||
.TP
|
||||
|
@ -221,7 +236,7 @@ boundaries is performed. It can wedge if errors occur in the attempted overlap a
|
|||
|
||||
.TP
|
||||
.B \-X --abort-on-skip
|
||||
If the read skips due to imperfect data, a scratch, whatever, abort reading this track. If output is to a file, delete the partially completed file.
|
||||
If the read skips due to imperfect data, a scratch, or whatever, abort reading this track. If output is to a file, delete the partially completed file.
|
||||
|
||||
.SH OUTPUT SMILIES
|
||||
.TP
|
||||
|
@ -282,7 +297,9 @@ Unreported loss of streaming/other error in read
|
|||
.B
|
||||
!
|
||||
Errors found after stage 1 correction; the drive is making the
|
||||
same error through multiple re-reads, and cdparanoia is having trouble
|
||||
same error through multiple re-reads, and
|
||||
.B cdparanoia
|
||||
is having trouble
|
||||
detecting them.
|
||||
.TP
|
||||
.B
|
||||
|
@ -295,8 +312,9 @@ Uncorrected error/skip
|
|||
|
||||
.SH SPAN ARGUMENT
|
||||
|
||||
The span argument specifies which track, tracks or subsections of
|
||||
tracks to read. This argument is required.
|
||||
The span argument specifies which track, tracks, or subsections of
|
||||
tracks to read. This argument is required,
|
||||
unless batch-mode is used (in batch-mode, cdparanoia will rip all tracks if no span is given).
|
||||
.B NOTE:
|
||||
Unless the span is a simple number, it's generally a good idea to
|
||||
quote the span argument to protect it from the shell.
|
||||
|
@ -307,7 +325,7 @@ specification. The syntax of an offset/span takes the rough form:
|
|||
1[ww:xx:yy.zz]-2[aa:bb:cc.dd]
|
||||
.P
|
||||
Here, 1 and 2 are track numbers; the numbers in brackets provide a
|
||||
finer grained offset within a particular track. [aa:bb:cc.dd] is in
|
||||
finer-grained offset within a particular track. [aa:bb:cc.dd] is in
|
||||
hours/minutes/seconds/sectors format. Zero fields need not be
|
||||
specified: [::20], [:20], [20], [20.], etc, would be interpreted as
|
||||
twenty seconds, [10:] would be ten minutes, [.30] would be thirty
|
||||
|
@ -315,7 +333,7 @@ sectors (75 sectors per second).
|
|||
.P
|
||||
When only a single offset is supplied, it is interpreted as a starting
|
||||
offset and ripping will continue to the end of the track. If a single
|
||||
offset is preceeded or followed by a hyphen, the implicit missing
|
||||
offset is preceded or followed by a hyphen, the implicit missing
|
||||
offset is taken to be the start or end of the disc, respectively. Thus:
|
||||
|
||||
.TP
|
||||
|
@ -335,18 +353,18 @@ Specifies ripping from the beginning of the disc up to 2:[30.35]
|
|||
.B 2-4
|
||||
Specifies ripping from the beginning of track 2 to the end of track 4.
|
||||
.P
|
||||
Again, don't forget to protect square brackets and preceeding hyphens from
|
||||
Again, don't forget to protect square brackets from
|
||||
the shell.
|
||||
|
||||
.SH EXAMPLES
|
||||
|
||||
A few examples, protected from the shell:
|
||||
.TP
|
||||
Query only with exhaustive search for a drive and full reporting of autosense:
|
||||
Query only with exhaustive search for a drive and full reporting of auto-sense:
|
||||
.P
|
||||
cdparanoia -vsQ
|
||||
.TP
|
||||
Extract an entire disc, putting each track in a seperate file:
|
||||
Extract an entire disc, putting each track in a separate file:
|
||||
.P
|
||||
cdparanoia -B
|
||||
.TP
|
||||
|
@ -354,26 +372,30 @@ Extract from track 1, time 0:30.12 to 1:10.00:
|
|||
.P
|
||||
cdparanoia "1[:30.12]-1[1:10]"
|
||||
.TP
|
||||
Extract from the beginning of the disc up to track 3:
|
||||
Extract from the beginning of the disc up through track 3:
|
||||
.P
|
||||
cdparanoia -- "-3"
|
||||
cdparanoia -- -3
|
||||
.TP
|
||||
The "--" above is to distinguish "-3" from an option flag.
|
||||
.SH OUTPUT
|
||||
|
||||
The output file argument is optional; if it is not specified,
|
||||
cdparanoia will output samples to one of
|
||||
.B cdparanoia
|
||||
will output samples to one of
|
||||
.BR cdda.wav ", " cdda.aifc ", or " cdda.raw
|
||||
depending on whether
|
||||
.BR \-w ", " \-a ", " \-r " or " \-R " is used (" \-w
|
||||
.BR \-w ", " \-a ", " \-r " or, " \-R " is used (" \-w
|
||||
is the implicit default). The output file argument of
|
||||
.B \-
|
||||
specifies standard output; all data formats may be piped.
|
||||
|
||||
.SH ACKNOWLEDGEMENTS
|
||||
Cdparanoia sprang from and once drew heavily from the interface of
|
||||
.B cdparanoia
|
||||
sprang from and once drew heavily from the interface of
|
||||
Heiko Eissfeldt's (heiko@colossus.escape.de) 'cdda2wav'
|
||||
package. Cdparanoia would not have happened without it.
|
||||
package.
|
||||
.B cdparanoia
|
||||
would not have happened without it.
|
||||
.P
|
||||
Joerg Schilling has also contributed SCSI expertise through his
|
||||
generic SCSI transport library.
|
||||
|
@ -381,5 +403,6 @@ generic SCSI transport library.
|
|||
.SH AUTHOR
|
||||
Monty <monty@xiph.org>
|
||||
.P
|
||||
Cdparanoia's homepage may be found at:
|
||||
.B cdparanoia's
|
||||
homepage may be found at:
|
||||
http://www.xiph.org/paranoia/
|
||||
|
|
|
@ -151,7 +151,7 @@ CD
|
|||
.TP
|
||||
.B \-Z --disable-paranoia
|
||||
データ照合と訂正機能を
|
||||
.b 全て
|
||||
.B 全て
|
||||
無効にします。-Z オプションを用いると、cdparanoia は
|
||||
オーバーラップの設定が 0 である cdda2wav と全く同じようにデータの
|
||||
読み取りを行います。
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
AC_INIT(interface/interface.c)
|
||||
|
||||
cp $srcdir/configure.guess $srcdir/config.guess
|
||||
cp $srcdir/configure.sub $srcdir/config.sub
|
||||
|
||||
AC_CANONICAL_HOST
|
||||
|
||||
if test -z "$CC"; then
|
||||
|
@ -56,12 +53,14 @@ fi
|
|||
|
||||
AC_CHECK_HEADERS(linux/sbpcd.h, SBPCD_H="-DSBPCD_H='1' ")
|
||||
AC_CHECK_HEADERS(linux/ucdrom.h, UCDROM_H="-DUCDROM_H='1' ")
|
||||
AC_CHECK_HEADERS(cam/cam.h, LIBCAM="-lcam")
|
||||
|
||||
AC_PROG_MAKE_SET
|
||||
AC_C_CONST
|
||||
|
||||
AC_SUBST(SBPCD_H)
|
||||
AC_SUBST(UCDROM_H)
|
||||
AC_SUBST(LIBCAM)
|
||||
AC_SUBST(TYPESIZES)
|
||||
AC_SUBST(OPT)
|
||||
AC_SUBST(DEBUG)
|
||||
|
|
|
@ -15,7 +15,7 @@ LD=@CC@
|
|||
LDFLAGS=@LDFLAGS@ $(FLAGS)
|
||||
AR=@AR@
|
||||
RANLIB=@RANLIB@
|
||||
LIBS = -lm -lrt
|
||||
LIBS = -lm -lrt @LIBCAM@
|
||||
CPPFLAGS+=-D_REENTRANT
|
||||
|
||||
OFILES = scan_devices.o common_interface.o cooked_interface.o interface.o\
|
||||
|
|
|
@ -84,7 +84,7 @@ typedef struct cdrom_drive{
|
|||
int is_atapi;
|
||||
int is_mmc;
|
||||
|
||||
cdda_private_data_t *private;
|
||||
cdda_private_data_t *private_data;
|
||||
void *reserved;
|
||||
unsigned char inqbytes[4];
|
||||
|
||||
|
|
|
@ -13,15 +13,22 @@
|
|||
#include "utils.h"
|
||||
#include "smallft.h"
|
||||
|
||||
#if defined(__linux__)
|
||||
#include <linux/hdreg.h>
|
||||
#endif
|
||||
|
||||
/* Test for presence of a cdrom by pinging with the 'CDROMVOLREAD' ioctl() */
|
||||
/* Also test using CDROM_GET_CAPABILITY (if available) as some newer DVDROMs will
|
||||
reject CDROMVOLREAD ioctl for god-knows-what reason */
|
||||
int ioctl_ping_cdrom(int fd){
|
||||
#if defined(__linux__)
|
||||
struct cdrom_volctrl volctl;
|
||||
if (ioctl(fd, CDROMVOLREAD, &volctl) &&
|
||||
ioctl(fd, CDROM_GET_CAPABILITY, NULL)<0)
|
||||
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
|
||||
struct ioc_vol volctl;
|
||||
if (ioctl(fd, CDIOCGETVOL, &volctl))
|
||||
#endif
|
||||
return(1); /* failure */
|
||||
|
||||
return(0);
|
||||
|
@ -29,6 +36,7 @@ int ioctl_ping_cdrom(int fd){
|
|||
}
|
||||
|
||||
|
||||
#if defined(__linux__)
|
||||
/* Use the ioctl thingy above ping the cdrom; this will get model info */
|
||||
char *atapi_drive_info(int fd){
|
||||
/* Work around the fact that the struct grew without warning in
|
||||
|
@ -49,6 +57,7 @@ char *atapi_drive_info(int fd){
|
|||
free(id);
|
||||
return(ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
int data_bigendianp(cdrom_drive *d){
|
||||
float lsb_votes=0;
|
||||
|
@ -174,7 +183,9 @@ int data_bigendianp(cdrom_drive *d){
|
|||
knows the leadout/leadin size. */
|
||||
|
||||
int FixupTOC(cdrom_drive *d,int tracks){
|
||||
#if defined(__linux__)
|
||||
struct cdrom_multisession ms_str;
|
||||
#endif
|
||||
int j;
|
||||
|
||||
/* First off, make sure the 'starting sector' is >=0 */
|
||||
|
@ -211,6 +222,8 @@ int FixupTOC(cdrom_drive *d,int tracks){
|
|||
/* For a scsi device, the ioctl must go to the specialized SCSI
|
||||
CDROM device, not the generic device. */
|
||||
|
||||
/* XXX */
|
||||
#if defined(__linux__)
|
||||
if (d->ioctl_fd != -1) {
|
||||
int result;
|
||||
|
||||
|
@ -235,6 +248,7 @@ int FixupTOC(cdrom_drive *d,int tracks){
|
|||
return 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
/******************************************************************
|
||||
* CopyPolicy: GNU Lesser General Public License 2.1 applies
|
||||
* Copyright (C) Monty xiphmont@mit.edu
|
||||
* FreeBSD porting (c) 2003
|
||||
* Simon 'corecode' Schubert <corecode@corecode.ath.cx>
|
||||
*
|
||||
* CDROM code specific to the cooked ioctl interface
|
||||
*
|
||||
|
@ -13,17 +15,18 @@
|
|||
static int timed_ioctl(cdrom_drive *d, int fd, int command, void *arg){
|
||||
struct timespec tv1;
|
||||
struct timespec tv2;
|
||||
int ret1=clock_gettime(d->private->clock,&tv1);
|
||||
int ret1=clock_gettime(d->private_data->clock,&tv1);
|
||||
int ret2=ioctl(fd, command,arg);
|
||||
int ret3=clock_gettime(d->private->clock,&tv2);
|
||||
int ret3=clock_gettime(d->private_data->clock,&tv2);
|
||||
if(ret1<0 || ret3<0){
|
||||
d->private->last_milliseconds=-1;
|
||||
d->private_data->last_milliseconds=-1;
|
||||
}else{
|
||||
d->private->last_milliseconds = (tv2.tv_sec-tv1.tv_sec)*1000. + (tv2.tv_nsec-tv1.tv_nsec)/1000000.;
|
||||
d->private_data->last_milliseconds = (tv2.tv_sec-tv1.tv_sec)*1000. + (tv2.tv_nsec-tv1.tv_nsec)/1000000.;
|
||||
}
|
||||
return ret2;
|
||||
}
|
||||
|
||||
#if defined(__linux__)
|
||||
static int cooked_readtoc (cdrom_drive *d){
|
||||
int i;
|
||||
int tracks;
|
||||
|
@ -157,6 +160,140 @@ static long cooked_read (cdrom_drive *d, void *p, long begin, long sectors){
|
|||
return ret;
|
||||
}
|
||||
|
||||
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
|
||||
static int
|
||||
cooked_readtoc(cdrom_drive *d)
|
||||
{
|
||||
int i;
|
||||
struct ioc_toc_header hdr;
|
||||
struct ioc_read_toc_single_entry entry;
|
||||
|
||||
if (ioctl(d->ioctl_fd, CDIOREADTOCHEADER, &hdr) == -1) {
|
||||
int ret;
|
||||
|
||||
if (errno == EPERM) {
|
||||
ret = -102;
|
||||
cderror(d, "102: ");
|
||||
} else {
|
||||
ret = -4;
|
||||
cderror(d, "004: Unable to read table of contents header: ");
|
||||
}
|
||||
cderror(d, strerror(errno));
|
||||
cderror(d, "\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
entry.address_format = CD_LBA_FORMAT;
|
||||
for (i = hdr.starting_track; i <= hdr.ending_track; ++i) {
|
||||
entry.track = i;
|
||||
|
||||
if (ioctl(d->ioctl_fd, CDIOREADTOCENTRY, &entry) == -1) {
|
||||
cderror(d, "005: Unable to read table of contents entry\n");
|
||||
return -5;
|
||||
}
|
||||
|
||||
d->disc_toc[i - hdr.starting_track].bFlags = entry.entry.control;
|
||||
d->disc_toc[i - hdr.starting_track].bTrack = entry.entry.track;
|
||||
d->disc_toc[i - hdr.starting_track].dwStartSector = be32_to_cpu(entry.entry.addr.lba);
|
||||
}
|
||||
|
||||
entry.track = 0xaa; /* leadout */
|
||||
|
||||
if (ioctl(d->ioctl_fd, CDIOREADTOCENTRY, &entry) == -1) {
|
||||
cderror(d, "005: Unable to read table of contents entry\n");
|
||||
return -5;
|
||||
}
|
||||
|
||||
d->disc_toc[i - hdr.starting_track].bFlags = entry.entry.control;
|
||||
d->disc_toc[i - hdr.starting_track].bTrack = entry.entry.track;
|
||||
d->disc_toc[i - hdr.starting_track].dwStartSector = be32_to_cpu(entry.entry.addr.lba);
|
||||
|
||||
d->cd_extra = FixupTOC(d, hdr.ending_track - hdr.starting_track + 2); /* with TOC */
|
||||
|
||||
return hdr.ending_track - hdr.starting_track + 1;
|
||||
}
|
||||
|
||||
static int
|
||||
cooked_setspeed(cdrom_drive *d, int speed)
|
||||
{
|
||||
#ifdef CDRIOCREADSPEED
|
||||
speed *= 177;
|
||||
return ioctl(d->ioctl_fd, CDRIOCREADSPEED, &speed);
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static long
|
||||
cooked_read(cdrom_drive *d, void *p, long begin, long sectors)
|
||||
{
|
||||
int retry_count = 0;
|
||||
#ifndef CDIOCREADAUDIO
|
||||
int bsize = CD_FRAMESIZE_RAW;
|
||||
#else
|
||||
struct ioc_read_audio arg;
|
||||
|
||||
if (sectors > d->nsectors)
|
||||
sectors = d->nsectors;
|
||||
|
||||
arg.address_format = CD_LBA_FORMAT;
|
||||
arg.address.lba = begin;
|
||||
arg.buffer = p;
|
||||
#endif
|
||||
|
||||
#ifndef CDIOCREADAUDIO
|
||||
if (ioctl(d->ioctl_fd, CDRIOCSETBLOCKSIZE, &bsize) == -1)
|
||||
return -7;
|
||||
#endif
|
||||
for (;;) {
|
||||
#ifndef CDIOCREADAUDIO
|
||||
if (pread(d->ioctl_fd, p, sectors*bsize, begin*bsize) != sectors*bsize) {
|
||||
#else
|
||||
arg.nframes = sectors;
|
||||
if (ioctl(d->ioctl_fd, CDIOCREADAUDIO, &arg) == -1) {
|
||||
#endif
|
||||
if (!d->error_retry)
|
||||
return -7;
|
||||
|
||||
switch (errno) {
|
||||
case ENOMEM:
|
||||
if (sectors == 1) {
|
||||
cderror(d, "300: Kernel memory error\n");
|
||||
return -300;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
if (sectors == 1) {
|
||||
if (retry_count > MAX_RETRIES - 1) {
|
||||
char b[256];
|
||||
snprintf(b, sizeof(b),
|
||||
"010: Unable to access sector %ld; "
|
||||
"skipping...\n", begin);
|
||||
cderror(d, b);
|
||||
return -10;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (retry_count > 4 && sectors > 1)
|
||||
sectors = sectors * 3 / 4;
|
||||
|
||||
++retry_count;
|
||||
|
||||
if (retry_count > MAX_RETRIES) {
|
||||
cderror(d, "007: Unknown, unrecoverable error reading data\n");
|
||||
return -7;
|
||||
}
|
||||
} else
|
||||
break;
|
||||
}
|
||||
|
||||
return sectors;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* hook */
|
||||
static int Dummy (cdrom_drive *d,int Switch){
|
||||
return(0);
|
||||
|
@ -221,6 +358,7 @@ static void check_exceptions(cdrom_drive *d,exception *list){
|
|||
int cooked_init_drive (cdrom_drive *d){
|
||||
int ret;
|
||||
|
||||
#if defined(__linux__)
|
||||
switch(d->drive_type){
|
||||
case MATSUSHITA_CDROM_MAJOR: /* sbpcd 1 */
|
||||
case MATSUSHITA_CDROM2_MAJOR: /* sbpcd 2 */
|
||||
|
@ -271,6 +409,9 @@ int cooked_init_drive (cdrom_drive *d){
|
|||
default:
|
||||
d->nsectors=40;
|
||||
}
|
||||
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
|
||||
d->nsectors = 26; /* FreeBSD only support 64K I/O transfer size */
|
||||
#endif
|
||||
d->enable_cdda = Dummy;
|
||||
d->read_audio = cooked_read;
|
||||
d->read_toc = cooked_readtoc;
|
||||
|
|
|
@ -39,9 +39,17 @@ int cdda_close(cdrom_drive *d){
|
|||
if(d->drive_model)free(d->drive_model);
|
||||
if(d->cdda_fd!=-1)close(d->cdda_fd);
|
||||
if(d->ioctl_fd!=-1 && d->ioctl_fd!=d->cdda_fd)close(d->ioctl_fd);
|
||||
if(d->private){
|
||||
if(d->private->sg_hd)free(d->private->sg_hd);
|
||||
free(d->private);
|
||||
if(d->private_data){
|
||||
#if defined(__linux__)
|
||||
if(d->private_data->sg_hd)free(d->private_data->sg_hd);
|
||||
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
|
||||
if(d->private_data->dev)
|
||||
cam_close_device(d->private_data->dev);
|
||||
if(d->private_data->ccb)
|
||||
cam_freeccb(d->private_data->ccb);
|
||||
if(d->private_data->sg_buffer)free(d->private_data->sg_buffer);
|
||||
#endif
|
||||
free(d->private_data);
|
||||
}
|
||||
|
||||
free(d);
|
||||
|
@ -118,7 +126,7 @@ long cdda_read_timed(cdrom_drive *d, void *buffer, long beginsector, long sector
|
|||
if(d->bigendianp==-1) /* not determined yet */
|
||||
d->bigendianp=data_bigendianp(d);
|
||||
|
||||
if(d->bigendianp!=bigendianp()){
|
||||
if(buffer && d->bigendianp!=bigendianp()){
|
||||
int i;
|
||||
u_int16_t *p=(u_int16_t *)buffer;
|
||||
long els=sectors*CD_FRAMESIZE_RAW/2;
|
||||
|
@ -127,7 +135,7 @@ long cdda_read_timed(cdrom_drive *d, void *buffer, long beginsector, long sector
|
|||
}
|
||||
}
|
||||
}
|
||||
if(ms)*ms=d->private->last_milliseconds;
|
||||
if(ms)*ms=d->private_data->last_milliseconds;
|
||||
return(sectors);
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#if defined(__linux__)
|
||||
|
||||
#include <linux/major.h>
|
||||
#include <linux/version.h>
|
||||
|
||||
|
@ -54,7 +56,6 @@
|
|||
#include <linux/cdrom.h>
|
||||
#include <linux/major.h>
|
||||
|
||||
#include "cdda_interface.h"
|
||||
|
||||
#ifndef SG_EMULATED_HOST
|
||||
/* old kernel version; the check for the ioctl is still runtime, this
|
||||
|
@ -64,6 +65,19 @@
|
|||
#define SG_GET_TRANSFORM 0x2205
|
||||
#endif
|
||||
|
||||
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
|
||||
|
||||
#include <sys/cdio.h>
|
||||
#include <sys/cdrio.h>
|
||||
|
||||
#include <cam/scsi/scsi_message.h>
|
||||
#include <camlib.h>
|
||||
|
||||
#endif
|
||||
|
||||
#include "cdda_interface.h"
|
||||
|
||||
|
||||
#ifndef SG_IO
|
||||
/* old kernel version; the usage is all runtime-safe, this is just to
|
||||
build */
|
||||
|
@ -98,19 +112,30 @@ typedef struct sg_io_hdr
|
|||
#endif
|
||||
|
||||
struct cdda_private_data {
|
||||
#if defined(__linux__)
|
||||
struct sg_header *sg_hd;
|
||||
unsigned char *sg_buffer; /* points into sg_hd */
|
||||
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
|
||||
struct cam_device *dev;
|
||||
#endif
|
||||
unsigned char *sg_buffer; /* on Linux points into sg_hd */
|
||||
clockid_t clock;
|
||||
int last_milliseconds;
|
||||
#if defined (__FreeBSD__) || defined(__FreeBSD_kernel__)
|
||||
union ccb *ccb;
|
||||
#endif
|
||||
};
|
||||
|
||||
#define MAX_RETRIES 8
|
||||
#define MAX_BIG_BUFF_SIZE 65536
|
||||
#define MIN_BIG_BUFF_SIZE 4096
|
||||
#define SG_OFF sizeof(struct sg_header)
|
||||
|
||||
extern int cooked_init_drive (cdrom_drive *d);
|
||||
#if defined(__linux__)
|
||||
extern unsigned char *scsi_inquiry (cdrom_drive *d);
|
||||
#define SG_OFF sizeof(struct sg_header)
|
||||
#else
|
||||
#define SG_OFF (0)
|
||||
#endif
|
||||
extern int scsi_init_drive (cdrom_drive *d);
|
||||
#ifdef CDDA_TEST
|
||||
extern int test_init_drive (cdrom_drive *d);
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
|
||||
#define MAX_DEV_LEN 20 /* Safe because strings only come from below */
|
||||
/* must be absolute paths! */
|
||||
|
||||
#if defined(__linux__)
|
||||
static char *scsi_cdrom_prefixes[]={
|
||||
"/dev/scd",
|
||||
"/dev/sr",
|
||||
|
@ -52,6 +54,17 @@ static char *cdrom_devices[]={
|
|||
"/dev/cm206cd",
|
||||
"/dev/gscd",
|
||||
"/dev/optcd",NULL};
|
||||
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
|
||||
static char *cdrom_devices[] = {
|
||||
"/dev/cd?",
|
||||
"/dev/acd?",
|
||||
"/dev/wcd?",
|
||||
"/dev/mcd?",
|
||||
"/dev/cd?c",
|
||||
"/dev/acd?c",
|
||||
"/dev/wcd?c",
|
||||
"/dev/mcd?c", NULL};
|
||||
#endif
|
||||
|
||||
/* Functions here look for a cdrom drive; full init of a drive type
|
||||
happens in interface.c */
|
||||
|
@ -78,10 +91,12 @@ cdrom_drive *cdda_find_a_cdrom(int messagedest,char **messages){
|
|||
if((d=cdda_identify(buffer,messagedest,messages)))
|
||||
return(d);
|
||||
idmessage(messagedest,messages,"",NULL);
|
||||
#if defined(__linux__)
|
||||
buffer[pos-(cdrom_devices[i])]=j+97;
|
||||
if((d=cdda_identify(buffer,messagedest,messages)))
|
||||
return(d);
|
||||
idmessage(messagedest,messages,"",NULL);
|
||||
#endif
|
||||
}
|
||||
}else{
|
||||
/* Name. Go for it. */
|
||||
|
@ -145,6 +160,7 @@ char *test_resolve_symlink(const char *file,int messagedest,char **messages){
|
|||
|
||||
}
|
||||
|
||||
#if defined(__linux__)
|
||||
cdrom_drive *cdda_identify_cooked(const char *dev, int messagedest,
|
||||
char **messages){
|
||||
|
||||
|
@ -179,6 +195,12 @@ cdrom_drive *cdda_identify_cooked(const char *dev, int messagedest,
|
|||
case IDE1_MAJOR:
|
||||
case IDE2_MAJOR:
|
||||
case IDE3_MAJOR:
|
||||
case IDE4_MAJOR:
|
||||
case IDE5_MAJOR:
|
||||
case IDE6_MAJOR:
|
||||
case IDE7_MAJOR:
|
||||
case IDE8_MAJOR:
|
||||
case IDE9_MAJOR:
|
||||
/* Yay, ATAPI... */
|
||||
/* Ping for CDROM-ness */
|
||||
|
||||
|
@ -264,16 +286,71 @@ cdrom_drive *cdda_identify_cooked(const char *dev, int messagedest,
|
|||
d->interface=COOKED_IOCTL;
|
||||
d->bigendianp=-1; /* We don't know yet... */
|
||||
d->nsectors=-1;
|
||||
d->private=calloc(1,sizeof(*d->private));
|
||||
d->private_data=calloc(1,sizeof(*d->private_data));
|
||||
{
|
||||
/* goddamnit */
|
||||
struct timespec tv;
|
||||
d->private->clock=(clock_gettime(CLOCK_MONOTONIC,&tv)<0?CLOCK_REALTIME:CLOCK_MONOTONIC);
|
||||
d->private_data->clock=(clock_gettime(CLOCK_MONOTONIC,&tv)<0?CLOCK_REALTIME:CLOCK_MONOTONIC);
|
||||
}
|
||||
idmessage(messagedest,messages,"\t\tCDROM sensed: %s\n",description);
|
||||
return(d);
|
||||
}
|
||||
|
||||
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
|
||||
cdrom_drive *
|
||||
cdda_identify_cooked(const char *dev, int messagedest, char **messages)
|
||||
{
|
||||
cdrom_drive *d;
|
||||
struct stat st;
|
||||
|
||||
if (stat(dev, &st)) {
|
||||
idperror(messagedest, messages, "\t\tCould not stat %s", dev);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!S_ISCHR(st.st_mode)) {
|
||||
idmessage(messagedest, messages, "\t\t%s is no block device", dev);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((d = calloc(1, sizeof(*d))) == NULL) {
|
||||
idperror(messagedest, messages, "\t\tCould not allocate memory", NULL);
|
||||
return NULL;
|
||||
}
|
||||
d->ioctl_fd = -1;
|
||||
|
||||
if ((d->ioctl_fd = open(dev, O_RDONLY)) == -1) {
|
||||
idperror(messagedest, messages, "\t\tCould not open %s", dev);
|
||||
goto cdda_identify_cooked_fail;
|
||||
}
|
||||
|
||||
if (ioctl_ping_cdrom(d->ioctl_fd)) {
|
||||
idmessage(messagedest, messages, "\t\tDevice %s is not a CDROM", dev);
|
||||
goto cdda_identify_cooked_fail;
|
||||
}
|
||||
|
||||
d->cdda_device_name = copystring(dev);
|
||||
d->drive_model = copystring("Generic cooked ioctl CDROM");
|
||||
d->interface = COOKED_IOCTL;
|
||||
d->bigendianp = -1;
|
||||
d->nsectors = -1;
|
||||
|
||||
idmessage(messagedest, messages, "\t\tCDROM sensed: %s\n", d->drive_model);
|
||||
|
||||
return d;
|
||||
|
||||
cdda_identify_cooked_fail:
|
||||
if (d != NULL) {
|
||||
if (d->ioctl_fd != -1)
|
||||
close(d->ioctl_fd);
|
||||
free(d);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(__linux__)
|
||||
struct sg_id {
|
||||
long l1; /* target | lun << 8 | channel << 16 | low_ino << 24 */
|
||||
long l2; /* Unique id */
|
||||
|
@ -400,6 +477,7 @@ matchfail:
|
|||
if(dev!=-1)close(dev);
|
||||
return(NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
void strscat(char *a,char *b,int n){
|
||||
int i;
|
||||
|
@ -411,6 +489,7 @@ void strscat(char *a,char *b,int n){
|
|||
strcat(a," ");
|
||||
}
|
||||
|
||||
#if defined(__linux__)
|
||||
/* 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,
|
||||
|
@ -674,15 +753,15 @@ cdrom_drive *cdda_identify_scsi(const char *generic_device,
|
|||
d->bigendianp=-1; /* We don't know yet... */
|
||||
d->nsectors=-1;
|
||||
d->messagedest = messagedest;
|
||||
d->private=calloc(1,sizeof(*d->private));
|
||||
d->private_data=calloc(1,sizeof(*d->private_data));
|
||||
{
|
||||
/* goddamnit */
|
||||
struct timespec tv;
|
||||
d->private->clock=(clock_gettime(CLOCK_MONOTONIC,&tv)<0?CLOCK_REALTIME:CLOCK_MONOTONIC);
|
||||
d->private_data->clock=(clock_gettime(CLOCK_MONOTONIC,&tv)<0?CLOCK_REALTIME:CLOCK_MONOTONIC);
|
||||
}
|
||||
if(use_sgio){
|
||||
d->interface=SGIO_SCSI;
|
||||
d->private->sg_buffer=(unsigned char *)(d->private->sg_hd=malloc(MAX_BIG_BUFF_SIZE));
|
||||
d->private_data->sg_buffer=(unsigned char *)(d->private_data->sg_hd=malloc(MAX_BIG_BUFF_SIZE));
|
||||
g_fd=d->cdda_fd=dup(d->ioctl_fd);
|
||||
}else{
|
||||
version=verify_SG_version(d,messagedest,messages);
|
||||
|
@ -696,8 +775,8 @@ cdrom_drive *cdda_identify_scsi(const char *generic_device,
|
|||
}
|
||||
|
||||
/* malloc our big buffer for scsi commands */
|
||||
d->private->sg_hd=malloc(MAX_BIG_BUFF_SIZE);
|
||||
d->private->sg_buffer=((unsigned char *)d->private->sg_hd)+SG_OFF;
|
||||
d->private_data->sg_hd=malloc(MAX_BIG_BUFF_SIZE);
|
||||
d->private_data->sg_buffer=((unsigned char *)d->private_data->sg_hd)+SG_OFF;
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -772,14 +851,104 @@ cdda_identify_scsi_fail:
|
|||
if(i_fd!=-1)close(i_fd);
|
||||
if(g_fd!=-1)close(g_fd);
|
||||
if(d){
|
||||
if(d->private){
|
||||
if(d->private->sg_hd)free(d->private->sg_hd);
|
||||
free(d->private);
|
||||
if(d->private_data){
|
||||
if(d->private_data->sg_hd)free(d->private_data->sg_hd);
|
||||
free(d->private_data);
|
||||
}
|
||||
free(d);
|
||||
}
|
||||
return(NULL);
|
||||
}
|
||||
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
|
||||
|
||||
cdrom_drive *cdda_identify_scsi(const char *dummy,
|
||||
const char *device,
|
||||
int messagedest,
|
||||
char **messages)
|
||||
{
|
||||
char *devname;
|
||||
cdrom_drive *d = NULL;
|
||||
|
||||
if (device == NULL) {
|
||||
idperror(messagedest, messages, "\t\tNo device specified", NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((devname = test_resolve_symlink(device, messagedest, messages)) == NULL)
|
||||
return NULL;
|
||||
|
||||
if ((d = calloc(1, sizeof(*d))) == NULL) {
|
||||
idperror(messagedest, messages, "\t\tCould not allocate memory", NULL);
|
||||
free(devname);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((d->private_data = calloc(1, sizeof(*(d->private_data)))) == NULL) {
|
||||
idperror(messagedest, messages, "\t\tCould not allocate memory", NULL);
|
||||
free(d);
|
||||
free(devname);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((d->private_data->dev = cam_open_device(devname, O_RDWR)) == NULL) {
|
||||
idperror(messagedest, messages, "\t\tCould not open SCSI device: %s", cam_errbuf);
|
||||
goto cdda_identify_scsi_fail;
|
||||
}
|
||||
|
||||
if ((d->private_data->ccb = cam_getccb(d->private_data->dev)) == NULL) {
|
||||
idperror(messagedest, messages, "\t\tCould not allocate ccb", NULL);
|
||||
goto cdda_identify_scsi_fail;
|
||||
}
|
||||
|
||||
if (strncmp(d->private_data->dev->inq_data.vendor, "TOSHIBA", 7) == 0 &&
|
||||
strncmp(d->private_data->dev->inq_data.product, "CD_ROM", 6) == 0 &&
|
||||
SID_TYPE(&d->private_data->dev->inq_data) == T_DIRECT) {
|
||||
d->private_data->dev->inq_data.device = T_CDROM;
|
||||
d->private_data->dev->inq_data.dev_qual2 |= 0x80;
|
||||
}
|
||||
|
||||
if (SID_TYPE(&d->private_data->dev->inq_data) != T_CDROM &&
|
||||
SID_TYPE(&d->private_data->dev->inq_data) != T_WORM) {
|
||||
idmessage(messagedest, messages,
|
||||
"\t\tDevice is neither a CDROM nor a WORM device\n", NULL);
|
||||
goto cdda_identify_scsi_fail;
|
||||
}
|
||||
|
||||
d->cdda_device_name = copystring(devname);
|
||||
d->ioctl_fd = -1;
|
||||
d->bigendianp = -1;
|
||||
d->nsectors = -1;
|
||||
d->lun = d->private_data->dev->target_lun;
|
||||
d->interface = GENERIC_SCSI;
|
||||
|
||||
if ((d->private_data->sg_buffer = malloc(MAX_BIG_BUFF_SIZE)) == NULL) {
|
||||
idperror(messagedest, messages, "Could not allocate buffer memory", NULL);
|
||||
goto cdda_identify_scsi_fail;
|
||||
}
|
||||
|
||||
if ((d->drive_model = calloc(36,1)) == NULL) {
|
||||
}
|
||||
|
||||
strscat(d->drive_model, d->private_data->dev->inq_data.vendor, SID_VENDOR_SIZE);
|
||||
strscat(d->drive_model, d->private_data->dev->inq_data.product, SID_PRODUCT_SIZE);
|
||||
strscat(d->drive_model, d->private_data->dev->inq_data.revision, SID_REVISION_SIZE);
|
||||
|
||||
idmessage(messagedest, messages, "\nCDROM model sensed: %s", d->drive_model);
|
||||
|
||||
return d;
|
||||
|
||||
cdda_identify_scsi_fail:
|
||||
free(devname);
|
||||
if (d) {
|
||||
if (d->private_data->ccb)
|
||||
cam_freeccb(d->private_data->ccb);
|
||||
if (d->private_data->dev)
|
||||
cam_close_device(d->private_data->dev);
|
||||
free(d);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CDDA_TEST
|
||||
|
||||
|
@ -821,7 +990,7 @@ cdrom_drive *cdda_identify_test(const char *filename, int messagedest,
|
|||
d->interface=TEST_INTERFACE;
|
||||
d->bigendianp=-1; /* We don't know yet... */
|
||||
d->nsectors=-1;
|
||||
d->private=calloc(1,sizeof(*d->private));
|
||||
d->private_data=calloc(1,sizeof(*d->private_data));
|
||||
d->drive_model=copystring("File based test interface");
|
||||
idmessage(messagedest,messages,"\t\tCDROM sensed: %s\n",d->drive_model);
|
||||
|
||||
|
|
|
@ -12,16 +12,21 @@
|
|||
#include "common_interface.h"
|
||||
#include "utils.h"
|
||||
#include <time.h>
|
||||
|
||||
#ifndef SG_MAX_SENSE
|
||||
#define SG_MAX_SENSE 16
|
||||
#endif
|
||||
|
||||
static int timed_ioctl(cdrom_drive *d, int fd, int command, void *arg){
|
||||
struct timespec tv1;
|
||||
struct timespec tv2;
|
||||
int ret1=clock_gettime(d->private->clock,&tv1);
|
||||
int ret1=clock_gettime(d->private_data->clock,&tv1);
|
||||
int ret2=ioctl(fd, command,arg);
|
||||
int ret3=clock_gettime(d->private->clock,&tv2);
|
||||
int ret3=clock_gettime(d->private_data->clock,&tv2);
|
||||
if(ret1<0 || ret3<0){
|
||||
d->private->last_milliseconds=-1;
|
||||
d->private_data->last_milliseconds=-1;
|
||||
}else{
|
||||
d->private->last_milliseconds = (tv2.tv_sec-tv1.tv_sec)*1000. + (tv2.tv_nsec-tv1.tv_nsec)/1000000.;
|
||||
d->private_data->last_milliseconds = (tv2.tv_sec-tv1.tv_sec)*1000. + (tv2.tv_nsec-tv1.tv_nsec)/1000000.;
|
||||
}
|
||||
return ret2;
|
||||
}
|
||||
|
@ -36,6 +41,7 @@ static void tweak_SG_buffer(cdrom_drive *d) {
|
|||
int table, reserved, cur, err;
|
||||
char buffer[256];
|
||||
|
||||
#if defined(__linux__)
|
||||
/* SG_SET_RESERVED_SIZE doesn't actually allocate or reserve anything.
|
||||
* what it _does_ do is give you an error if you ask for a value
|
||||
* larger than q->max_sectors (the length of the device's bio request
|
||||
|
@ -59,6 +65,7 @@ static void tweak_SG_buffer(cdrom_drive *d) {
|
|||
"table entry size: %d bytes\n\t"
|
||||
"maximum theoretical transfer: %d sectors\n",
|
||||
table, reserved, table*(reserved/CD_FRAMESIZE_RAW));
|
||||
|
||||
cdmessage(d,buffer);
|
||||
|
||||
cur=reserved; /* only use one entry for now */
|
||||
|
@ -90,13 +97,23 @@ static void tweak_SG_buffer(cdrom_drive *d) {
|
|||
|
||||
if(cur==0) exit(1);
|
||||
|
||||
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
|
||||
d->nsectors = 26; /* FreeBSD only supports 64K I/O transfer size */
|
||||
d->bigbuff = d->nsectors * CD_FRAMESIZE_RAW;
|
||||
|
||||
sprintf(buffer,"\tSetting default read size to %d sectors (%d bytes).\n\n",
|
||||
d->nsectors,d->nsectors*CD_FRAMESIZE_RAW);
|
||||
#endif
|
||||
|
||||
cdmessage(d,buffer);
|
||||
}
|
||||
|
||||
|
||||
#if defined(__linux__)
|
||||
static void clear_garbage(cdrom_drive *d){
|
||||
fd_set fdset;
|
||||
struct timeval tv;
|
||||
struct sg_header *sg_hd=d->private->sg_hd;
|
||||
struct sg_header *sg_hd=d->private_data->sg_hd;
|
||||
int flag=0;
|
||||
|
||||
/* clear out any possibly preexisting garbage */
|
||||
|
@ -123,6 +140,7 @@ static void clear_garbage(cdrom_drive *d){
|
|||
flag=1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static int check_sbp_error(const unsigned char status,
|
||||
const unsigned char *sbp) {
|
||||
|
@ -142,7 +160,11 @@ static int check_sbp_error(const unsigned char status,
|
|||
case 1:
|
||||
break;
|
||||
case 2:
|
||||
#ifdef ENOMEDIUM
|
||||
errno = ENOMEDIUM;
|
||||
#else
|
||||
errno = EIO;
|
||||
#endif
|
||||
return(TR_NOTREADY);
|
||||
case 3:
|
||||
if ((ASC==0x0C) & (ASCQ==0x09)) {
|
||||
|
@ -172,6 +194,7 @@ static int check_sbp_error(const unsigned char status,
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
/* process a complete scsi command. */
|
||||
static int sg2_handle_scsi_cmd(cdrom_drive *d,
|
||||
unsigned char *cmd,
|
||||
|
@ -185,7 +208,7 @@ static int sg2_handle_scsi_cmd(cdrom_drive *d,
|
|||
struct timespec tv2;
|
||||
int tret1,tret2;
|
||||
int status = 0;
|
||||
struct sg_header *sg_hd=d->private->sg_hd;
|
||||
struct sg_header *sg_hd=d->private_data->sg_hd;
|
||||
long writebytes=SG_OFF+cmd_len+in_size;
|
||||
|
||||
/* generic scsi device services */
|
||||
|
@ -195,7 +218,7 @@ static int sg2_handle_scsi_cmd(cdrom_drive *d,
|
|||
|
||||
memset(sg_hd,0,sizeof(sg_hd));
|
||||
memset(sense_buffer,0,SG_MAX_SENSE);
|
||||
memcpy(d->private->sg_buffer,cmd,cmd_len+in_size);
|
||||
memcpy(d->private_data->sg_buffer,cmd,cmd_len+in_size);
|
||||
sg_hd->twelve_byte = cmd_len == 12;
|
||||
sg_hd->result = 0;
|
||||
sg_hd->reply_len = SG_OFF + out_size;
|
||||
|
@ -209,7 +232,7 @@ static int sg2_handle_scsi_cmd(cdrom_drive *d,
|
|||
tell if the command failed. Scared yet? */
|
||||
|
||||
if(bytecheck && out_size>in_size){
|
||||
memset(d->private->sg_buffer+cmd_len+in_size,bytefill,out_size-in_size);
|
||||
memset(d->private_data->sg_buffer+cmd_len+in_size,bytefill,out_size-in_size);
|
||||
/* the size does not remove cmd_len due to the way the kernel
|
||||
driver copies buffers */
|
||||
writebytes+=(out_size-in_size);
|
||||
|
@ -243,7 +266,7 @@ static int sg2_handle_scsi_cmd(cdrom_drive *d,
|
|||
}
|
||||
|
||||
sigprocmask (SIG_BLOCK, &(d->sigset), NULL );
|
||||
tret1=clock_gettime(d->private->clock,&tv1);
|
||||
tret1=clock_gettime(d->private_data->clock,&tv1);
|
||||
errno=0;
|
||||
status = write(d->cdda_fd, sg_hd, writebytes );
|
||||
|
||||
|
@ -289,7 +312,7 @@ static int sg2_handle_scsi_cmd(cdrom_drive *d,
|
|||
}
|
||||
}
|
||||
|
||||
tret2=clock_gettime(d->private->clock,&tv2);
|
||||
tret2=clock_gettime(d->private_data->clock,&tv2);
|
||||
errno=0;
|
||||
status = read(d->cdda_fd, sg_hd, SG_OFF + out_size);
|
||||
sigprocmask ( SIG_UNBLOCK, &(d->sigset), NULL );
|
||||
|
@ -313,7 +336,7 @@ static int sg2_handle_scsi_cmd(cdrom_drive *d,
|
|||
if(bytecheck && in_size+cmd_len<out_size){
|
||||
long i,flag=0;
|
||||
for(i=in_size;i<out_size;i++)
|
||||
if(d->private->sg_buffer[i]!=bytefill){
|
||||
if(d->private_data->sg_buffer[i]!=bytefill){
|
||||
flag=1;
|
||||
break;
|
||||
}
|
||||
|
@ -326,9 +349,9 @@ static int sg2_handle_scsi_cmd(cdrom_drive *d,
|
|||
|
||||
errno=0;
|
||||
if(tret1<0 || tret2<0){
|
||||
d->private->last_milliseconds=-1;
|
||||
d->private_data->last_milliseconds=-1;
|
||||
}else{
|
||||
d->private->last_milliseconds = (tv2.tv_sec-tv1.tv_sec)*1000 + (tv2.tv_nsec-tv1.tv_nsec)/1000000;
|
||||
d->private_data->last_milliseconds = (tv2.tv_sec-tv1.tv_sec)*1000 + (tv2.tv_nsec-tv1.tv_nsec)/1000000;
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
@ -347,7 +370,7 @@ static int sgio_handle_scsi_cmd(cdrom_drive *d,
|
|||
|
||||
memset(&hdr,0,sizeof(hdr));
|
||||
memset(sense,0,sizeof(sense));
|
||||
memcpy(d->private->sg_buffer,cmd+cmd_len,in_size);
|
||||
memcpy(d->private_data->sg_buffer,cmd+cmd_len,in_size);
|
||||
|
||||
hdr.cmdp = cmd;
|
||||
hdr.cmd_len = cmd_len;
|
||||
|
@ -355,7 +378,7 @@ static int sgio_handle_scsi_cmd(cdrom_drive *d,
|
|||
hdr.mx_sb_len = SG_MAX_SENSE;
|
||||
hdr.timeout = 50000;
|
||||
hdr.interface_id = 'S';
|
||||
hdr.dxferp = d->private->sg_buffer;
|
||||
hdr.dxferp = d->private_data->sg_buffer;
|
||||
hdr.flags = SG_FLAG_DIRECT_IO; /* direct IO if we can get it */
|
||||
|
||||
/* scary buffer fill hack */
|
||||
|
@ -400,7 +423,7 @@ static int sgio_handle_scsi_cmd(cdrom_drive *d,
|
|||
if(bytecheck && in_size<out_size){
|
||||
long i,flag=0;
|
||||
for(i=in_size;i<out_size;i++)
|
||||
if(d->private->sg_buffer[i]!=bytefill){
|
||||
if(d->private_data->sg_buffer[i]!=bytefill){
|
||||
flag=1;
|
||||
break;
|
||||
}
|
||||
|
@ -412,7 +435,7 @@ static int sgio_handle_scsi_cmd(cdrom_drive *d,
|
|||
}
|
||||
|
||||
/* Can't rely on .duration because we can't be certain kernel has HZ set to something useful */
|
||||
/* d->private->last_milliseconds = hdr.duration; */
|
||||
/* d->private_data->last_milliseconds = hdr.duration; */
|
||||
|
||||
errno = 0;
|
||||
return 0;
|
||||
|
@ -432,6 +455,91 @@ static int handle_scsi_cmd(cdrom_drive *d,
|
|||
return sg2_handle_scsi_cmd(d,cmd,cmd_len,in_size,out_size,bytefill,bytecheck,sense);
|
||||
|
||||
}
|
||||
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
|
||||
static int handle_scsi_cmd(cdrom_drive *d,
|
||||
unsigned char *cmd,
|
||||
unsigned int cmd_len,
|
||||
unsigned int write_len,
|
||||
unsigned int read_len,
|
||||
unsigned char bytefill,
|
||||
int bytecheck,
|
||||
unsigned char *sense){
|
||||
int result;
|
||||
|
||||
bzero(&d->private_data->ccb->csio, sizeof(d->private_data->ccb->csio));
|
||||
|
||||
memcpy(d->private_data->ccb->csio.cdb_io.cdb_bytes, cmd, cmd_len);
|
||||
memcpy(d->private_data->sg_buffer, cmd + cmd_len, write_len);
|
||||
|
||||
if (bytecheck && (read_len > write_len))
|
||||
memset(d->private_data->sg_buffer+write_len, bytefill, read_len - write_len);
|
||||
|
||||
cam_fill_csio(&d->private_data->ccb->csio,
|
||||
/* retries */ 0,
|
||||
/* cbfcnp */ NULL,
|
||||
/* flags */ CAM_DEV_QFRZDIS | (write_len ? CAM_DIR_OUT : CAM_DIR_IN),
|
||||
/* tag_action */ MSG_SIMPLE_Q_TAG,
|
||||
/* data_ptr */ d->private_data->sg_buffer,
|
||||
/* dxfer_len */ write_len ? write_len : read_len,
|
||||
/* sense_len */ SSD_FULL_SIZE,
|
||||
/* cdb_len */ cmd_len,
|
||||
/* timeout */ 60000); /* XXX */
|
||||
|
||||
|
||||
result = cam_send_ccb(d->private_data->dev, d->private_data->ccb);
|
||||
|
||||
if ((result < 0) ||
|
||||
(d->private_data->ccb->ccb_h.status & CAM_STATUS_MASK) == 0 /* hack? */)
|
||||
return TR_EREAD;
|
||||
|
||||
if ((d->private_data->ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP &&
|
||||
(d->private_data->ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_SCSI_STATUS_ERROR) {
|
||||
fprintf (stderr, "\t\terror returned from SCSI command:\n"
|
||||
"\t\tccb->ccb_h.status == %d\n", d->private_data->ccb->ccb_h.status);
|
||||
errno = EIO;
|
||||
return TR_UNKNOWN;
|
||||
}
|
||||
|
||||
if (d->private_data->ccb->csio.dxfer_len != (write_len ? write_len : read_len)) {
|
||||
errno = EIO;
|
||||
return TR_EREAD;
|
||||
}
|
||||
|
||||
int errorCode, senseKey, addSenseCode, addSenseCodeQual;
|
||||
scsi_extract_sense( &(d->private_data->ccb->csio.sense_data), &errorCode, &senseKey, &addSenseCode,
|
||||
&addSenseCodeQual );
|
||||
if (errorCode) {
|
||||
switch (senseKey) {
|
||||
case SSD_KEY_NO_SENSE:
|
||||
errno = EIO;
|
||||
return TR_UNKNOWN;
|
||||
case SSD_KEY_RECOVERED_ERROR:
|
||||
break;
|
||||
case SSD_KEY_NOT_READY:
|
||||
errno = EBUSY;
|
||||
return TR_BUSY;
|
||||
case SSD_KEY_MEDIUM_ERROR:
|
||||
errno = EIO;
|
||||
if (addSenseCode == 0x0c &&
|
||||
addSenseCodeQual == 0x09)
|
||||
return TR_STREAMING;
|
||||
else
|
||||
return TR_MEDIUM;
|
||||
case SSD_KEY_HARDWARE_ERROR:
|
||||
errno = EIO;
|
||||
return TR_FAULT;
|
||||
case SSD_KEY_ILLEGAL_REQUEST:
|
||||
errno = EINVAL;
|
||||
return TR_ILLEGAL;
|
||||
default:
|
||||
errno = EIO;
|
||||
return TR_UNKNOWN;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static int test_unit_ready(cdrom_drive *d){
|
||||
unsigned char sense[SG_MAX_SENSE];
|
||||
|
@ -445,14 +553,15 @@ static int test_unit_ready(cdrom_drive *d){
|
|||
|
||||
handle_scsi_cmd(d, cmd, 6, 0, 56, 0,0, sense);
|
||||
|
||||
key = d->private->sg_buffer[2] & 0xf;
|
||||
ASC = d->private->sg_buffer[12];
|
||||
ASCQ = d->private->sg_buffer[13];
|
||||
key = d->private_data->sg_buffer[2] & 0xf;
|
||||
ASC = d->private_data->sg_buffer[12];
|
||||
ASCQ = d->private_data->sg_buffer[13];
|
||||
|
||||
if(key == 2 && ASC == 4 && ASCQ == 1) return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if defined(__linux__)
|
||||
static void reset_scsi(cdrom_drive *d){
|
||||
int arg,tries=0;
|
||||
d->enable_cdda(d,0);
|
||||
|
@ -471,6 +580,29 @@ static void reset_scsi(cdrom_drive *d){
|
|||
|
||||
d->enable_cdda(d,1);
|
||||
}
|
||||
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
|
||||
static void reset_scsi(cdrom_drive *d) {
|
||||
d->enable_cdda(d,0);
|
||||
|
||||
d->private_data->ccb->ccb_h.func_code = XPT_RESET_DEV;
|
||||
d->private_data->ccb->ccb_h.timeout = 5000;
|
||||
|
||||
cdmessage(d, "sending SCSI reset... ");
|
||||
if (cam_send_ccb(d->private_data->dev, d->private_data->ccb)) {
|
||||
cdmessage(d, "error sending XPT_RESET_DEV CCB");
|
||||
} else {
|
||||
|
||||
if (((d->private_data->ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) ||
|
||||
((d->private_data->ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_BDR_SENT))
|
||||
cdmessage(d,"OK\n");
|
||||
else
|
||||
cdmessage(d,"FAILED\n");
|
||||
}
|
||||
|
||||
d->enable_cdda(d,1);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static int mode_sense_atapi(cdrom_drive *d,int size,int page){
|
||||
unsigned char sense[SG_MAX_SENSE];
|
||||
|
@ -492,7 +624,7 @@ static int mode_sense_atapi(cdrom_drive *d,int size,int page){
|
|||
if (handle_scsi_cmd (d, cmd, 10, 0, size+4,'\377',1,sense)) return(1);
|
||||
|
||||
{
|
||||
unsigned char *b=d->private->sg_buffer;
|
||||
unsigned char *b=d->private_data->sg_buffer;
|
||||
if(b[0])return(1); /* Handles only up to 256 bytes */
|
||||
if(b[6])return(1); /* Handles only up to 256 bytes */
|
||||
|
||||
|
@ -604,8 +736,8 @@ static int mode_select(cdrom_drive *d,int density,int secsize){
|
|||
static unsigned int get_orig_sectorsize(cdrom_drive *d){
|
||||
if(mode_sense(d,12,0x01))return(-1);
|
||||
|
||||
d->orgdens = d->private->sg_buffer[4];
|
||||
return(d->orgsize = ((int)(d->private->sg_buffer[10])<<8)+d->private->sg_buffer[11]);
|
||||
d->orgdens = d->private_data->sg_buffer[4];
|
||||
return(d->orgsize = ((int)(d->private_data->sg_buffer[10])<<8)+d->private_data->sg_buffer[11]);
|
||||
}
|
||||
|
||||
/* switch CDROM scsi drives to given sector size */
|
||||
|
@ -664,8 +796,8 @@ static int scsi_read_toc (cdrom_drive *d){
|
|||
return(-4);
|
||||
}
|
||||
|
||||
first=d->private->sg_buffer[2];
|
||||
last=d->private->sg_buffer[3];
|
||||
first=d->private_data->sg_buffer[2];
|
||||
last=d->private_data->sg_buffer[3];
|
||||
tracks=last-first+1;
|
||||
|
||||
if (last > MAXTRK || first > MAXTRK || last<0 || first<0) {
|
||||
|
@ -683,7 +815,7 @@ static int scsi_read_toc (cdrom_drive *d){
|
|||
return(-5);
|
||||
}
|
||||
{
|
||||
scsi_TOC *toc=(scsi_TOC *)(d->private->sg_buffer+4);
|
||||
scsi_TOC *toc=(scsi_TOC *)(d->private_data->sg_buffer+4);
|
||||
|
||||
d->disc_toc[i-first].bFlags=toc->bFlags;
|
||||
d->disc_toc[i-first].bTrack=i;
|
||||
|
@ -704,7 +836,7 @@ static int scsi_read_toc (cdrom_drive *d){
|
|||
return(-2);
|
||||
}
|
||||
{
|
||||
scsi_TOC *toc=(scsi_TOC *)(d->private->sg_buffer+4);
|
||||
scsi_TOC *toc=(scsi_TOC *)(d->private_data->sg_buffer+4);
|
||||
|
||||
d->disc_toc[i-first].bFlags=toc->bFlags;
|
||||
d->disc_toc[i-first].bTrack=0xAA;
|
||||
|
@ -738,7 +870,7 @@ static int scsi_read_toc2 (cdrom_drive *d){
|
|||
}
|
||||
|
||||
/* copy to our structure and convert start sector */
|
||||
tracks = d->private->sg_buffer[1];
|
||||
tracks = d->private_data->sg_buffer[1];
|
||||
if (tracks > MAXTRK) {
|
||||
cderror(d,"003: CDROM reporting illegal number of tracks\n");
|
||||
return(-3);
|
||||
|
@ -754,33 +886,33 @@ static int scsi_read_toc2 (cdrom_drive *d){
|
|||
return(-5);
|
||||
}
|
||||
|
||||
d->disc_toc[i].bFlags = d->private->sg_buffer[10];
|
||||
d->disc_toc[i].bFlags = d->private_data->sg_buffer[10];
|
||||
d->disc_toc[i].bTrack = i + 1;
|
||||
|
||||
d->disc_toc[i].dwStartSector= d->adjust_ssize *
|
||||
(((signed char)(d->private->sg_buffer[2])<<24) |
|
||||
(d->private->sg_buffer[3]<<16)|
|
||||
(d->private->sg_buffer[4]<<8)|
|
||||
(d->private->sg_buffer[5]));
|
||||
(((signed char)(d->private_data->sg_buffer[2])<<24) |
|
||||
(d->private_data->sg_buffer[3]<<16)|
|
||||
(d->private_data->sg_buffer[4]<<8)|
|
||||
(d->private_data->sg_buffer[5]));
|
||||
}
|
||||
|
||||
d->disc_toc[i].bFlags = 0;
|
||||
d->disc_toc[i].bTrack = i + 1;
|
||||
memcpy (&foo, d->private->sg_buffer+2, 4);
|
||||
memcpy (&bar, d->private->sg_buffer+6, 4);
|
||||
memcpy (&foo, d->private_data->sg_buffer+2, 4);
|
||||
memcpy (&bar, d->private_data->sg_buffer+6, 4);
|
||||
d->disc_toc[i].dwStartSector = d->adjust_ssize * (be32_to_cpu(foo) +
|
||||
be32_to_cpu(bar));
|
||||
|
||||
d->disc_toc[i].dwStartSector= d->adjust_ssize *
|
||||
((((signed char)(d->private->sg_buffer[2])<<24) |
|
||||
(d->private->sg_buffer[3]<<16)|
|
||||
(d->private->sg_buffer[4]<<8)|
|
||||
(d->private->sg_buffer[5]))+
|
||||
((((signed char)(d->private_data->sg_buffer[2])<<24) |
|
||||
(d->private_data->sg_buffer[3]<<16)|
|
||||
(d->private_data->sg_buffer[4]<<8)|
|
||||
(d->private_data->sg_buffer[5]))+
|
||||
|
||||
((((signed char)(d->private->sg_buffer[6])<<24) |
|
||||
(d->private->sg_buffer[7]<<16)|
|
||||
(d->private->sg_buffer[8]<<8)|
|
||||
(d->private->sg_buffer[9]))));
|
||||
((((signed char)(d->private_data->sg_buffer[6])<<24) |
|
||||
(d->private_data->sg_buffer[7]<<16)|
|
||||
(d->private_data->sg_buffer[8]<<8)|
|
||||
(d->private_data->sg_buffer[9]))));
|
||||
|
||||
|
||||
d->cd_extra = FixupTOC(d,tracks+1);
|
||||
|
@ -817,7 +949,7 @@ static int i_read_28 (cdrom_drive *d, void *p, long begin, long sectors, unsigne
|
|||
cmd[8] = sectors;
|
||||
if((ret=handle_scsi_cmd(d,cmd,10,0,sectors * CD_FRAMESIZE_RAW,'\177',1,sense)))
|
||||
return(ret);
|
||||
if(p)memcpy(p,d->private->sg_buffer,sectors*CD_FRAMESIZE_RAW);
|
||||
if(p)memcpy(p,d->private_data->sg_buffer,sectors*CD_FRAMESIZE_RAW);
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
@ -836,7 +968,7 @@ static int i_read_A8 (cdrom_drive *d, void *p, long begin, long sectors, unsigne
|
|||
cmd[9] = sectors;
|
||||
if((ret=handle_scsi_cmd(d,cmd,12,0,sectors * CD_FRAMESIZE_RAW,'\177',1,sense)))
|
||||
return(ret);
|
||||
if(p)memcpy(p,d->private->sg_buffer,sectors*CD_FRAMESIZE_RAW);
|
||||
if(p)memcpy(p,d->private_data->sg_buffer,sectors*CD_FRAMESIZE_RAW);
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
@ -854,7 +986,7 @@ static int i_read_D4_10 (cdrom_drive *d, void *p, long begin, long sectors, unsi
|
|||
cmd[8] = sectors;
|
||||
if((ret=handle_scsi_cmd(d,cmd,10,0,sectors * CD_FRAMESIZE_RAW,'\177',1,sense)))
|
||||
return(ret);
|
||||
if(p)memcpy(p,d->private->sg_buffer,sectors*CD_FRAMESIZE_RAW);
|
||||
if(p)memcpy(p,d->private_data->sg_buffer,sectors*CD_FRAMESIZE_RAW);
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
@ -872,7 +1004,7 @@ static int i_read_D4_12 (cdrom_drive *d, void *p, long begin, long sectors, unsi
|
|||
cmd[9] = sectors;
|
||||
if((ret=handle_scsi_cmd(d,cmd,12,0,sectors * CD_FRAMESIZE_RAW,'\177',1,sense)))
|
||||
return(ret);
|
||||
if(p)memcpy(p,d->private->sg_buffer,sectors*CD_FRAMESIZE_RAW);
|
||||
if(p)memcpy(p,d->private_data->sg_buffer,sectors*CD_FRAMESIZE_RAW);
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
@ -890,7 +1022,7 @@ static int i_read_D5 (cdrom_drive *d, void *p, long begin, long sectors, unsigne
|
|||
cmd[8] = sectors;
|
||||
if((ret=handle_scsi_cmd(d,cmd,10,0,sectors * CD_FRAMESIZE_RAW,'\177',1,sense)))
|
||||
return(ret);
|
||||
if(p)memcpy(p,d->private->sg_buffer,sectors*CD_FRAMESIZE_RAW);
|
||||
if(p)memcpy(p,d->private_data->sg_buffer,sectors*CD_FRAMESIZE_RAW);
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
@ -908,7 +1040,7 @@ static int i_read_D8 (cdrom_drive *d, void *p, long begin, long sectors, unsigne
|
|||
cmd[9] = sectors;
|
||||
if((ret=handle_scsi_cmd(d,cmd,12,0,sectors * CD_FRAMESIZE_RAW,'\177',1,sense)))
|
||||
return(ret);
|
||||
if(p)memcpy(p,d->private->sg_buffer,sectors*CD_FRAMESIZE_RAW);
|
||||
if(p)memcpy(p,d->private_data->sg_buffer,sectors*CD_FRAMESIZE_RAW);
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
@ -922,7 +1054,7 @@ static int i_read_mmc (cdrom_drive *d, void *p, long begin, long sectors, unsign
|
|||
cmd[8] = sectors;
|
||||
if((ret=handle_scsi_cmd(d,cmd,12,0,sectors * CD_FRAMESIZE_RAW,'\177',1,sense)))
|
||||
return(ret);
|
||||
if(p)memcpy(p,d->private->sg_buffer,sectors*CD_FRAMESIZE_RAW);
|
||||
if(p)memcpy(p,d->private_data->sg_buffer,sectors*CD_FRAMESIZE_RAW);
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
@ -936,7 +1068,7 @@ static int i_read_mmcB (cdrom_drive *d, void *p, long begin, long sectors, unsig
|
|||
cmd[8] = sectors;
|
||||
if((ret=handle_scsi_cmd(d,cmd,12,0,sectors * CD_FRAMESIZE_RAW,'\177',1,sense)))
|
||||
return(ret);
|
||||
if(p)memcpy(p,d->private->sg_buffer,sectors*CD_FRAMESIZE_RAW);
|
||||
if(p)memcpy(p,d->private_data->sg_buffer,sectors*CD_FRAMESIZE_RAW);
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
@ -950,7 +1082,7 @@ static int i_read_mmc2 (cdrom_drive *d, void *p, long begin, long sectors, unsig
|
|||
cmd[8] = sectors;
|
||||
if((ret=handle_scsi_cmd(d,cmd,12,0,sectors * CD_FRAMESIZE_RAW,'\177',1,sense)))
|
||||
return(ret);
|
||||
if(p)memcpy(p,d->private->sg_buffer,sectors*CD_FRAMESIZE_RAW);
|
||||
if(p)memcpy(p,d->private_data->sg_buffer,sectors*CD_FRAMESIZE_RAW);
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
@ -964,7 +1096,7 @@ static int i_read_mmc2B (cdrom_drive *d, void *p, long begin, long sectors, unsi
|
|||
cmd[8] = sectors;
|
||||
if((ret=handle_scsi_cmd(d,cmd,12,0,sectors * CD_FRAMESIZE_RAW,'\177',1,sense)))
|
||||
return(ret);
|
||||
if(p)memcpy(p,d->private->sg_buffer,sectors*CD_FRAMESIZE_RAW);
|
||||
if(p)memcpy(p,d->private_data->sg_buffer,sectors*CD_FRAMESIZE_RAW);
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
@ -978,7 +1110,7 @@ static int i_read_mmc3 (cdrom_drive *d, void *p, long begin, long sectors, unsig
|
|||
cmd[8] = sectors;
|
||||
if((ret=handle_scsi_cmd(d,cmd,12,0,sectors * CD_FRAMESIZE_RAW,'\177',1,sense)))
|
||||
return(ret);
|
||||
if(p)memcpy(p,d->private->sg_buffer,sectors*CD_FRAMESIZE_RAW);
|
||||
if(p)memcpy(p,d->private_data->sg_buffer,sectors*CD_FRAMESIZE_RAW);
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
@ -992,7 +1124,7 @@ static int i_read_mmc3B (cdrom_drive *d, void *p, long begin, long sectors, unsi
|
|||
cmd[8] = sectors;
|
||||
if((ret=handle_scsi_cmd(d,cmd,12,0,sectors * CD_FRAMESIZE_RAW,'\177',1,sense)))
|
||||
return(ret);
|
||||
if(p)memcpy(p,d->private->sg_buffer,sectors*CD_FRAMESIZE_RAW);
|
||||
if(p)memcpy(p,d->private_data->sg_buffer,sectors*CD_FRAMESIZE_RAW);
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
@ -1026,7 +1158,7 @@ static int i_read_msf (cdrom_drive *d, void *p, long begin, long sectors, unsign
|
|||
|
||||
if((ret=handle_scsi_cmd(d,cmd,12,0,sectors * CD_FRAMESIZE_RAW,'\177',1,sense)))
|
||||
return(ret);
|
||||
if(p)memcpy(p,d->private->sg_buffer,sectors*CD_FRAMESIZE_RAW);
|
||||
if(p)memcpy(p,d->private_data->sg_buffer,sectors*CD_FRAMESIZE_RAW);
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
@ -1039,7 +1171,7 @@ static int i_read_msf2 (cdrom_drive *d, void *p, long begin, long sectors, unsig
|
|||
|
||||
if((ret=handle_scsi_cmd(d,cmd,12,0,sectors * CD_FRAMESIZE_RAW,'\177',1,sense)))
|
||||
return(ret);
|
||||
if(p)memcpy(p,d->private->sg_buffer,sectors*CD_FRAMESIZE_RAW);
|
||||
if(p)memcpy(p,d->private_data->sg_buffer,sectors*CD_FRAMESIZE_RAW);
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
@ -1052,7 +1184,7 @@ static int i_read_msf3 (cdrom_drive *d, void *p, long begin, long sectors, unsig
|
|||
|
||||
if((ret=handle_scsi_cmd(d,cmd,12,0,sectors * CD_FRAMESIZE_RAW,'\177',1,sense)))
|
||||
return(ret);
|
||||
if(p)memcpy(p,d->private->sg_buffer,sectors*CD_FRAMESIZE_RAW);
|
||||
if(p)memcpy(p,d->private_data->sg_buffer,sectors*CD_FRAMESIZE_RAW);
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
@ -1079,10 +1211,20 @@ static long scsi_read_map (cdrom_drive *d, void *p, long begin, long sectors,
|
|||
sprintf(b,"scsi_read error: sector=%ld length=%ld retry=%d\n",
|
||||
begin,sectors,retry_count);
|
||||
cdmessage(d,b);
|
||||
#if defined(__linux__)
|
||||
sprintf(b," Sense key: %x ASC: %x ASCQ: %x\n",
|
||||
(int)(sense[2]&0xf),
|
||||
(int)(sense[12]),
|
||||
(int)(sense[13]));
|
||||
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
|
||||
int errorCode, senseKey, addSenseCode, addSenseCodeQual;
|
||||
scsi_extract_sense( &(d->private_data->ccb->csio.sense_data), &errorCode, &senseKey, &addSenseCode,
|
||||
&addSenseCodeQual );
|
||||
sprintf(b," Sense key: %x ASC: %x ASCQ: %x\n",
|
||||
senseKey,
|
||||
addSenseCode,
|
||||
addSenseCodeQual);
|
||||
#endif
|
||||
cdmessage(d,b);
|
||||
sprintf(b," Transport error: %s\n",strerror_tr[err]);
|
||||
cdmessage(d,b);
|
||||
|
@ -1091,10 +1233,19 @@ static long scsi_read_map (cdrom_drive *d, void *p, long begin, long sectors,
|
|||
|
||||
fprintf(stderr,"scsi_read error: sector=%ld length=%ld retry=%d\n",
|
||||
begin,sectors,retry_count);
|
||||
#if defined(__linux__)
|
||||
fprintf(stderr," Sense key: %x ASC: %x ASCQ: %x\n",
|
||||
(int)(sense[2]&0xf),
|
||||
(int)(sense[12]),
|
||||
(int)(sense[13]));
|
||||
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
|
||||
scsi_extract_sense( &(d->private_data->ccb->csio.sense_data), &errorCode, &senseKey, &addSenseCode,
|
||||
&addSenseCodeQual );
|
||||
fprintf(stderr," Sense key: %x ASC: %x ASCQ: %x\n",
|
||||
senseKey,
|
||||
addSenseCode,
|
||||
addSenseCodeQual);
|
||||
#endif
|
||||
fprintf(stderr," Transport error: %s\n",strerror_tr[err]);
|
||||
fprintf(stderr," System error: %s\n",strerror(errno));
|
||||
}
|
||||
|
@ -1120,10 +1271,11 @@ static long scsi_read_map (cdrom_drive *d, void *p, long begin, long sectors,
|
|||
}
|
||||
sectors--;
|
||||
continue;
|
||||
#ifdef ENOMEDIUM
|
||||
case ENOMEDIUM:
|
||||
cderror(d,"404: No medium present\n");
|
||||
return(-404);
|
||||
|
||||
#endif
|
||||
default:
|
||||
if(sectors==1){
|
||||
if(errno==EIO)
|
||||
|
@ -1275,7 +1427,7 @@ long scsi_read_msf3 (cdrom_drive *d, void *p, long begin,
|
|||
static int count_2352_bytes(cdrom_drive *d){
|
||||
long i;
|
||||
for(i=2351;i>=0;i--)
|
||||
if(d->private->sg_buffer[i]!=(unsigned char)'\177')
|
||||
if(d->private_data->sg_buffer[i]!=(unsigned char)'\177')
|
||||
return(((i+3)>>2)<<2);
|
||||
|
||||
return(0);
|
||||
|
@ -1284,7 +1436,7 @@ static int count_2352_bytes(cdrom_drive *d){
|
|||
static int verify_nonzero(cdrom_drive *d){
|
||||
long i,flag=0;
|
||||
for(i=0;i<2352;i++)
|
||||
if(d->private->sg_buffer[i]!=0){
|
||||
if(d->private_data->sg_buffer[i]!=0){
|
||||
flag=1;
|
||||
break;
|
||||
}
|
||||
|
@ -1587,6 +1739,7 @@ static void check_cache(cdrom_drive *d){
|
|||
}
|
||||
}
|
||||
|
||||
#if defined(__linux__)
|
||||
static int check_atapi(cdrom_drive *d){
|
||||
int atapiret=-1;
|
||||
int fd = d->cdda_fd; /* check the device we'll actually be using to read */
|
||||
|
@ -1618,6 +1771,47 @@ static int check_atapi(cdrom_drive *d){
|
|||
}
|
||||
}
|
||||
|
||||
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
|
||||
static int
|
||||
check_atapi(cdrom_drive *d)
|
||||
{
|
||||
bzero(&(&d->private_data->ccb->ccb_h)[1], sizeof(d->private_data->ccb->cpi) - sizeof(d->private_data->ccb->ccb_h));
|
||||
|
||||
d->private_data->ccb->ccb_h.func_code = XPT_PATH_INQ;
|
||||
|
||||
cdmessage(d, "\nChecking for ATAPICAM...\n");
|
||||
|
||||
if (cam_send_ccb(d->private_data->dev, d->private_data->ccb) < 0) {
|
||||
cderror(d, "\terror sending XPT_PATH_INQ CCB: ");
|
||||
cderror(d, cam_errbuf);
|
||||
cderror(d, "\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((d->private_data->ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
|
||||
cderror(d, "\tXPT_PATH_INQ CCB failed: ");
|
||||
cderror(d, cam_errbuf);
|
||||
cderror(d, "\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* if the bus device name is `ata', we're (obviously)
|
||||
* running ATAPICAM.
|
||||
*/
|
||||
|
||||
if (strncmp(d->private_data->ccb->cpi.dev_name, "ata", 3) == 0) {
|
||||
cdmessage(d, "\tDrive is ATAPI (using ATAPICAM)\n");
|
||||
d->is_atapi = 1;
|
||||
} else {
|
||||
cdmessage(d, "\tDrive is SCSI\n");
|
||||
d->is_atapi = 0;
|
||||
}
|
||||
|
||||
return d->is_atapi;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int check_mmc(cdrom_drive *d){
|
||||
unsigned char *b;
|
||||
cdmessage(d,"\nChecking for MMC style command set...\n");
|
||||
|
@ -1625,7 +1819,7 @@ static int check_mmc(cdrom_drive *d){
|
|||
d->is_mmc=0;
|
||||
if(mode_sense(d,22,0x2A)==0){
|
||||
|
||||
b=d->private->sg_buffer;
|
||||
b=d->private_data->sg_buffer;
|
||||
b+=b[3]+4;
|
||||
|
||||
if((b[0]&0x3F)==0x2A){
|
||||
|
@ -1664,6 +1858,7 @@ static void check_exceptions(cdrom_drive *d,exception *list){
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
/* request vendor brand and model */
|
||||
unsigned char *scsi_inquiry(cdrom_drive *d){
|
||||
unsigned char sense[SG_MAX_SENSE];
|
||||
|
@ -1673,8 +1868,9 @@ unsigned char *scsi_inquiry(cdrom_drive *d){
|
|||
cderror(d,"008: Unable to identify CDROM model\n");
|
||||
return(NULL);
|
||||
}
|
||||
return (d->private->sg_buffer);
|
||||
return (d->private_data->sg_buffer);
|
||||
}
|
||||
#endif
|
||||
|
||||
int scsi_init_drive(cdrom_drive *d){
|
||||
int ret;
|
||||
|
@ -1742,8 +1938,12 @@ int scsi_init_drive(cdrom_drive *d){
|
|||
check_cache(d);
|
||||
|
||||
d->error_retry=1;
|
||||
d->private->sg_hd=realloc(d->private->sg_hd,d->nsectors*CD_FRAMESIZE_RAW + SG_OFF + 128);
|
||||
d->private->sg_buffer=((unsigned char *)d->private->sg_hd)+SG_OFF;
|
||||
#if defined(__linux__)
|
||||
d->private_data->sg_hd=realloc(d->private_data->sg_hd,d->nsectors*CD_FRAMESIZE_RAW + SG_OFF + 128);
|
||||
d->private_data->sg_buffer=((unsigned char *)d->private_data->sg_hd)+SG_OFF;
|
||||
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
|
||||
d->private_data->sg_buffer==realloc(d->private_data->sg_buffer,d->nsectors * CD_FRAMESIZE_RAW + 128);
|
||||
#endif
|
||||
d->report_all=1;
|
||||
return(0);
|
||||
}
|
||||
|
|
|
@ -66,9 +66,9 @@ static long test_read(cdrom_drive *d, void *p, long begin, long sectors){
|
|||
if(!fd)fd=fdopen(d->cdda_fd,"r");
|
||||
|
||||
if(begin<lastread)
|
||||
d->private->last_milliseconds=20;
|
||||
d->private_data->last_milliseconds=20;
|
||||
else
|
||||
d->private->last_milliseconds=sectors;
|
||||
d->private_data->last_milliseconds=sectors;
|
||||
|
||||
#ifdef CDDA_TEST_UNDERRUN
|
||||
sectors-=1;
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
#if defined (__linux__) || defined (__GLIBC__)
|
||||
#include <endian.h>
|
||||
#elif defined(__FreeBSD__)
|
||||
#include <machine/endian.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
|
46
main.c
46
main.c
|
@ -51,7 +51,7 @@ static long parse_offset(cdrom_drive *d, char *offset, int begin){
|
|||
|
||||
if(offset==NULL)return(-1);
|
||||
|
||||
/* seperate track from time offset */
|
||||
/* separate track from time offset */
|
||||
temp=strchr(offset,']');
|
||||
if(temp){
|
||||
*temp='\0';
|
||||
|
@ -213,6 +213,8 @@ VERSION"\n"
|
|||
" -q --quiet : quiet operation\n"
|
||||
" -e --stderr-progress : force output of progress information to\n"
|
||||
" stderr (for wrapper scripts)\n"
|
||||
" -E --force-progress-bar : force output of progress bar even if\n"
|
||||
" stderr is not a terminal\n"
|
||||
" -l --log-summary [<file>] : save result summary to file, default\n"
|
||||
" filename cdparanoia.log\n"
|
||||
" -L --log-debug [<file>] : save detailed device autosense and\n"
|
||||
|
@ -221,14 +223,14 @@ VERSION"\n"
|
|||
" -V --version : print version info and quit\n"
|
||||
" -Q --query : autosense drive, query disc and quit\n"
|
||||
" -B --batch : 'batch' mode (saves each track to a\n"
|
||||
" seperate file.\n"
|
||||
" separate file.\n"
|
||||
" -s --search-for-drive : do an exhaustive search for drive\n"
|
||||
" -h --help : print help\n\n"
|
||||
|
||||
" -p --output-raw : output raw 16 bit PCM in host byte \n"
|
||||
" -p --output-raw : output raw 16-bit PCM in host byte \n"
|
||||
" order\n"
|
||||
" -r --output-raw-little-endian : output raw 16 bit little-endian PCM\n"
|
||||
" -R --output-raw-big-endian : output raw 16 bit big-endian PCM\n"
|
||||
" -r --output-raw-little-endian : output raw 16-bit little-endian PCM\n"
|
||||
" -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\n"
|
||||
|
@ -295,7 +297,7 @@ VERSION"\n"
|
|||
" 1[ww:xx:yy.zz]-2[aa:bb:cc.dd] \n\n"
|
||||
|
||||
"Here, 1 and 2 are track numbers; the numbers in brackets provide a\n"
|
||||
"finer grained offset within a particular track. [aa:bb:cc.dd] is in\n"
|
||||
"finer-grained offset within a particular track. [aa:bb:cc.dd] is in\n"
|
||||
"hours/minutes/seconds/sectors format. Zero fields need not be\n"
|
||||
"specified: [::20], [:20], [20], [20.], etc, would be interpreted as\n"
|
||||
"twenty seconds, [10:] would be ten minutes, [.30] would be thirty\n"
|
||||
|
@ -303,7 +305,7 @@ VERSION"\n"
|
|||
|
||||
"When only a single offset is supplied, it is interpreted as a starting\n"
|
||||
"offset and ripping will continue to the end of he track. If a single\n"
|
||||
"offset is preceeded or followed by a hyphen, the implicit missing\n"
|
||||
"offset is preceded or followed by a hyphen, the implicit missing\n"
|
||||
"offset is taken to be the start or end of the disc, respectively. Thus:\n\n"
|
||||
|
||||
" 1:[20.35] Specifies ripping from track 1, second 20, sector 35 to \n"
|
||||
|
@ -320,15 +322,18 @@ VERSION"\n"
|
|||
" 2-4 Specifies ripping from the beginning of track two to the\n"
|
||||
" end of track 4.\n\n"
|
||||
|
||||
"Don't forget to protect square brackets and preceeding hyphens from\n"
|
||||
"Don't forget to protect square brackets and preceding hyphens from\n"
|
||||
"the shell...\n\n"
|
||||
"A few examples, protected from the shell:\n"
|
||||
"Don't forget to protect square brackets from the shell...\n\n"
|
||||
|
||||
"A few examples, protected from the shell where appropriate:\n"
|
||||
" A) query only with exhaustive search for a drive and full reporting\n"
|
||||
" of autosense:\n"
|
||||
" cdparanoia -vsQ\n\n"
|
||||
" B) extract up to and including track 3, putting each track in a seperate\n"
|
||||
" B) extract up to and including track 3, putting each track in a separate\n"
|
||||
" file:\n"
|
||||
" cdparanoia -B -- \"-3\"\n\n"
|
||||
" cdparanoia -B -- -3\n\n"
|
||||
" C) extract from track 1, time 0:30.12 to 1:10.00:\n"
|
||||
" cdparanoia \"1[:30.12]-1[1:10]\"\n\n"
|
||||
|
||||
|
@ -338,6 +343,7 @@ VERSION"\n"
|
|||
long callbegin;
|
||||
long callend;
|
||||
long callscript=0;
|
||||
long force_progress_bar=0;
|
||||
|
||||
static char *callback_strings[16]={"wrote",
|
||||
"finished",
|
||||
|
@ -404,13 +410,13 @@ static void callback(long inpos, int function){
|
|||
}
|
||||
}
|
||||
|
||||
if(!quiet){
|
||||
if(force_progress_bar || !quiet){
|
||||
long test;
|
||||
osector=inpos;
|
||||
sector=inpos/CD_FRAMEWORDS;
|
||||
|
||||
if(printit==-1){
|
||||
if(isatty(STDERR_FILENO)){
|
||||
if(force_progress_bar || isatty(STDERR_FILENO)){
|
||||
printit=1;
|
||||
}else{
|
||||
printit=0;
|
||||
|
@ -604,10 +610,11 @@ static void callback(long inpos, int function){
|
|||
memset(dispcache,' ',graph);
|
||||
}
|
||||
|
||||
const char *optstring = "escCn:o:O:d:g:k:S:prRwafvqVQhZz::YXWBi:Tt:l::L::A";
|
||||
const char *optstring = "eEscCn:o:O:d:g:k:S:prRwafvqVQhZz::YXWBi:Tt:l::L::A";
|
||||
|
||||
struct option options [] = {
|
||||
{"stderr-progress",no_argument,NULL,'e'},
|
||||
{"force-progress-bar",no_argument,NULL,'E'},
|
||||
{"search-for-drive",no_argument,NULL,'s'},
|
||||
{"force-cdrom-little-endian",no_argument,NULL,'c'},
|
||||
{"force-cdrom-big-endian",no_argument,NULL,'C'},
|
||||
|
@ -726,7 +733,7 @@ int main(int argc,char *argv[]){
|
|||
break;
|
||||
case 'g':
|
||||
if(force_cooked_device){
|
||||
report("-g option incompatable with -k\n");
|
||||
report("-g option incompatible with -k\n");
|
||||
exit(1);
|
||||
}
|
||||
force_cooked_device=NULL;
|
||||
|
@ -735,7 +742,7 @@ int main(int argc,char *argv[]){
|
|||
break;
|
||||
case 'k':
|
||||
if(force_generic_device || force_cdrom_device){
|
||||
report("-k option incompatable with -d and -g\n");
|
||||
report("-k option incompatible with -d and -g\n");
|
||||
exit(1);
|
||||
}
|
||||
if(force_cooked_device)free(force_cooked_device);
|
||||
|
@ -783,6 +790,9 @@ int main(int argc,char *argv[]){
|
|||
callscript=1;
|
||||
fprintf(stderr,"Sending all callbacks to stderr for wrapper script\n");
|
||||
break;
|
||||
case 'E':
|
||||
force_progress_bar=1;
|
||||
break;
|
||||
case 'V':
|
||||
fprintf(stderr,VERSION);
|
||||
fprintf(stderr,"\n");
|
||||
|
@ -1362,7 +1372,11 @@ int main(int argc,char *argv[]){
|
|||
if(err)free(err);
|
||||
if(mes)free(mes);
|
||||
if(readbuf==NULL){
|
||||
if(errno==EBADF || errno==ENOMEDIUM){
|
||||
if(errno==EBADF
|
||||
#ifdef ENOMEDIUM
|
||||
|| errno==ENOMEDIUM
|
||||
#endif
|
||||
){
|
||||
report("\nparanoia_read: CDROM drive unavailable, bailing.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
|
|
@ -2439,6 +2439,7 @@ c_block *i_read_c_block(cdrom_paranoia *p,long beginword,long endword,
|
|||
secread))<secread){
|
||||
|
||||
if(thisread<0){
|
||||
#ifdef ENOMEDIUM
|
||||
if(errno==ENOMEDIUM){
|
||||
/* the one error we bail on immediately */
|
||||
if(new)free_c_block(new);
|
||||
|
@ -2446,6 +2447,7 @@ c_block *i_read_c_block(cdrom_paranoia *p,long beginword,long endword,
|
|||
if(flags)free(flags);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
thisread=0;
|
||||
}
|
||||
|
||||
|
@ -2687,7 +2689,9 @@ int16_t *paranoia_read_limited(cdrom_paranoia *p, void(*callback)(long,int),
|
|||
|
||||
/* Was the medium removed or the device closed out from
|
||||
under us? */
|
||||
#ifdef ENOMEDIUM
|
||||
if(errno==ENOMEDIUM) return NULL;
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue