Hi, Please find attached and updated version of the patch. It adds a field cdda_device_name to struct cdrom_drive to expose the path of the device node. Previously this was only present in the Linux version and it is now needed for KDE 3.5.1.
Thanks Aurelien -- .''`. Aurelien Jarno | GPG: 1024D/F1BCDB73 : :' : Debian developer | Electrical Engineer `. `' [EMAIL PROTECTED] | [EMAIL PROTECTED] `- people.debian.org/~aurel32 | www.aurel32.net
Author: FreeBSD + aurel32 Status: in BTS diff -u cdparanoia-3a9.8/Makefile.in cdparanoia-3a9.8/Makefile.in --- cdparanoia-3a9.8/Makefile.in +++ cdparanoia-3a9.8/Makefile.in @@ -32,10 +32,10 @@ ifeq ($(STATIC),TRUE) LIBS = interface/libcdda_interface.a paranoia/libcdda_paranoia.a \ - -static -lm + -static -lm @LIBCAM@ LIBDEP = interface/libcdda_interface.a paranoia/libcdda_paranoia.a else - LIBS = -lcdda_interface -lcdda_paranoia -lm + LIBS = -lcdda_interface -lcdda_paranoia -lm @LIBCAM@ LIBDEP = interface/libcdda_interface.so paranoia/libcdda_paranoia.so endif diff -u cdparanoia-3a9.8/configure cdparanoia-3a9.8/configure --- cdparanoia-3a9.8/configure +++ cdparanoia-3a9.8/configure @@ -1480,6 +1480,46 @@ fi done +for ac_hdr in cam/cam.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:1488: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 1493 "configure" +#include "confdefs.h" +#include <$ac_hdr> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1498: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <<EOF +#define $ac_tr_hdr 1 +EOF + LIBCAM="-lcam" +else + echo "$ac_t""no" 1>&6 +fi +done + echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 echo "configure:1486: checking whether ${MAKE-make} sets \${MAKE}" >&5 @@ -1748,6 +1788,7 @@ [EMAIL PROTECTED]@%$SET_MAKE%g [EMAIL PROTECTED]@%$SBPCD_H%g [EMAIL PROTECTED]@%$UCDROM_H%g [EMAIL PROTECTED]@%$LIBCAM%g [EMAIL PROTECTED]@%$TYPESIZES%g [EMAIL PROTECTED]@%$OPT%g [EMAIL PROTECTED]@%$DEBUG%g diff -u cdparanoia-3a9.8/interface/scan_devices.c cdparanoia-3a9.8/interface/scan_devices.c --- cdparanoia-3a9.8/interface/scan_devices.c +++ cdparanoia-3a9.8/interface/scan_devices.c @@ -1,6 +1,8 @@ /****************************************************************** * CopyPolicy: GNU Public License 2 applies * Copyright (C) 1998 Monty [EMAIL PROTECTED] + * FreeBSD porting (c) 2003 + * Simon 'corecode' Schubert <[EMAIL PROTECTED]> * * Autoscan for or verify presence of a cdrom device * @@ -21,6 +23,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", @@ -49,6 +53,17 @@ "/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 */ @@ -75,10 +90,12 @@ 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. */ @@ -117,8 +134,14 @@ } #endif +#if defined(__linux__) /* is order of checks important? */ d=cdda_identify_cooked(device,messagedest,messages); if(!d)d=cdda_identify_scsi(device,NULL,messagedest,messages); +#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) + d = cdda_identify_scsi(device, NULL, messagedest, messages); + if (d == NULL) + d = cdda_identify_cooked(device, messagedest, messages); +#endif #ifdef CDDA_TEST if(!d)d=cdda_identify_test(device,messagedest,messages); @@ -143,6 +166,7 @@ } +#if defined(__linux__) cdrom_drive *cdda_identify_cooked(const char *dev, int messagedest, char **messages){ @@ -275,6 +299,61 @@ 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 */ @@ -390,6 +469,7 @@ if(dev!=-1)close(dev); return(NULL); } +#endif void strscat(char *a,char *b,int n){ int i; @@ -401,6 +481,7 @@ 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, @@ -654,6 +735,89 @@ if(g_fd!=-1)close(g_fd); return(NULL); } +#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) + +cdrom_drive *cdda_identify_scsi(const char *device, + const char *dummy, + 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->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->ccb = cam_getccb(d->dev)) == NULL) { + idperror(messagedest, messages, "\t\tCould not allocate ccb", NULL); + goto cdda_identify_scsi_fail; + } + + if (strncmp(d->dev->inq_data.vendor, "TOSHIBA", 7) == 0 && + strncmp(d->dev->inq_data.product, "CD_ROM", 6) == 0 && + SID_TYPE(&d->dev->inq_data) == T_DIRECT) { + d->dev->inq_data.device = T_CDROM; + d->dev->inq_data.dev_qual2 |= 0x80; + } + + if (SID_TYPE(&d->dev->inq_data) != T_CDROM && + SID_TYPE(&d->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->dev->target_lun; + d->interface = GENERIC_SCSI; + + if ((d->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->dev->inq_data.vendor, SID_VENDOR_SIZE); + strscat(d->drive_model, d->dev->inq_data.product, SID_PRODUCT_SIZE); + strscat(d->drive_model, d->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->ccb) + cam_freeccb(d->ccb); + if (d->dev) + cam_close_device(d->dev); + free(d); + } + return NULL; +} +#endif #ifdef CDDA_TEST diff -u cdparanoia-3a9.8/interface/utils.h cdparanoia-3a9.8/interface/utils.h --- cdparanoia-3a9.8/interface/utils.h +++ cdparanoia-3a9.8/interface/utils.h @@ -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> diff -u cdparanoia-3a9.8/debian/changelog cdparanoia-3a9.8/debian/changelog --- cdparanoia-3a9.8/debian/changelog +++ cdparanoia-3a9.8/debian/changelog @@ -1,3 +1,17 @@ +cdparanoia (3a9.8-11+kbsd.1) unreleased; urgency=low + + * Use cdda_device_name of struct cdrom_drive to expose the path of the + device node. Previously this was only present in the Linux version and + is needed for KDE 3.5.1. + + -- Aurelien Jarno <[EMAIL PROTECTED]> Wed, 8 Feb 2006 14:43:21 +0100 + +cdparanoia (3a9.8-11+kbsd) unreleased; urgency=low + + * Added support for GNU/kFreeBSD + + -- Aurelien Jarno <[EMAIL PROTECTED]> Sat, 27 Aug 2005 17:35:25 +0200 + cdparanoia (3a9.8-11) unstable; urgency=low * Fix double heartbeat (Closes: #235415) diff -u cdparanoia-3a9.8/debian/control cdparanoia-3a9.8/debian/control --- cdparanoia-3a9.8/debian/control +++ cdparanoia-3a9.8/debian/control @@ -1,5 +1,5 @@ Source: cdparanoia -Build-Depends: debhelper (>> 3.0.0) +Build-Depends: debhelper (>> 3.0.0), libcam-dev [kfreebsd-i386] Section: sound Priority: optional Maintainer: Aaron Lehmann <[EMAIL PROTECTED]> --- cdparanoia-3a9.8.orig/configure.in +++ cdparanoia-3a9.8/configure.in @@ -62,12 +62,14 @@ 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) --- cdparanoia-3a9.8.orig/utils.h +++ cdparanoia-3a9.8/utils.h @@ -1,5 +1,9 @@ #include <stdlib.h> +#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> --- cdparanoia-3a9.8.orig/version.h +++ cdparanoia-3a9.8/version.h @@ -8,6 +8,8 @@ #define VERSION "cdparanoia III release 9.8 (March 23, 2001)\n"\ - "(C) 2001 Monty <[EMAIL PROTECTED]> and Xiphophorus\n\n"\ + "(C) 2001 Monty <[EMAIL PROTECTED]> and Xiphophorus\n"\ + "FreeBSD porting (c) 2003\n"\ + "\tSimon 'corecode' Schubert <[EMAIL PROTECTED]>\n\n"\ "Report bugs to [EMAIL PROTECTED]"\ "http://www.xiph.org/paranoia/\n" --- cdparanoia-3a9.8.orig/interface/Makefile.in +++ cdparanoia-3a9.8/interface/Makefile.in @@ -15,7 +15,7 @@ [EMAIL PROTECTED]@ $(FLAGS) [EMAIL PROTECTED]@ [EMAIL PROTECTED]@ -LIBS = -lm +LIBS = -lm @LIBCAM@ CPPFLAGS+=-D_REENTRANT OFILES = scan_devices.o common_interface.o cooked_interface.o interface.o\ @@ -46,7 +46,7 @@ $(RANLIB) libcdda_interface.a libcdda_interface.so: $(OFILES) - $(CC) -fpic -shared -o libcdda_interface.so.0.$(VERSION) -Wl,-soname -Wl,libcdda_interface.so.0 $(OFILES) + $(CC) -fpic -shared -o libcdda_interface.so.0.$(VERSION) -Wl,-soname -Wl,libcdda_interface.so.0 $(OFILES) $(LIBS) [ -e libcdda_interface.so.0 ] || ln -s libcdda_interface.so.0.$(VERSION) libcdda_interface.so.0 [ -e libcdda_interface.so ] || ln -s libcdda_interface.so.0.$(VERSION) libcdda_interface.so --- cdparanoia-3a9.8.orig/interface/cdda_interface.h +++ cdparanoia-3a9.8/interface/cdda_interface.h @@ -21,6 +21,11 @@ #include <sys/types.h> #include <signal.h> +#if defined (__FreeBSD__) || defined(__FreeBSD_kernel__) +#include <stdio.h> +#include <camlib.h> +#endif + #define MAXTRK 100 typedef struct TOC { /* structure of table of contents */ @@ -47,13 +52,19 @@ int opened; /* This struct may just represent a candidate for opening */ char *cdda_device_name; +#if defined(__linux__) char *ioctl_device_name; int cdda_fd; - int ioctl_fd; - char *drive_model; int drive_type; +#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) + struct cam_device *dev; + union ccb *ccb; +#endif + + int ioctl_fd; + char *drive_model; int interface; int bigendianp; int nsectors; @@ -83,9 +94,13 @@ int is_mmc; /* SCSI command buffer and offset pointers */ +#if defined(__linux__) unsigned char *sg; unsigned char *sg_buffer; unsigned char inqbytes[4]; +#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) + unsigned char *sg_buffer; +#endif /* Scsi parameters and state */ unsigned char density; --- cdparanoia-3a9.8.orig/interface/common_interface.c +++ cdparanoia-3a9.8/interface/common_interface.c @@ -13,12 +13,19 @@ #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() */ int ioctl_ping_cdrom(int fd){ +#if defined(__linux__) struct cdrom_volctrl volctl; if (ioctl(fd, CDROMVOLREAD, &volctl)) +#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) + struct ioc_vol volctl; + if (ioctl(fd, CDIOCGETVOL, &volctl)) +#endif return(1); /* failure */ return(0); @@ -26,6 +33,7 @@ } +#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 @@ -46,6 +54,7 @@ free(id); return(ret); } +#endif int data_bigendianp(cdrom_drive *d){ float lsb_votes=0; @@ -171,7 +180,9 @@ knows the leasoud/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 */ @@ -208,6 +219,8 @@ /* 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; @@ -231,6 +244,7 @@ return 1; } } +#endif return 0; } --- cdparanoia-3a9.8.orig/interface/cooked_interface.c +++ cdparanoia-3a9.8/interface/cooked_interface.c @@ -1,6 +1,8 @@ /****************************************************************** * CopyPolicy: GNU Public License 2 applies * Copyright (C) Monty [EMAIL PROTECTED] + * FreeBSD porting (c) 2003 + * Simon 'corecode' Schubert <[EMAIL PROTECTED]> * * CDROM code specific to the cooked ioctl interface * @@ -10,6 +12,7 @@ #include "common_interface.h" #include "utils.h" +#if defined(__linux__) static int cooked_readtoc (cdrom_drive *d){ int i; int tracks; @@ -129,6 +132,140 @@ return(sectors); } +#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); @@ -193,6 +330,7 @@ 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 */ @@ -243,6 +381,9 @@ 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->set_speed = cooked_setspeed; --- cdparanoia-3a9.8.orig/interface/interface.c +++ cdparanoia-3a9.8/interface/interface.c @@ -30,11 +30,24 @@ _clean_messages(d); if(d->cdda_device_name)free(d->cdda_device_name); +#if defined(__linux__) if(d->ioctl_device_name)free(d->ioctl_device_name); 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->sg)free(d->sg); +#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) + if (d->drive_model) + free(d->drive_model); + if (d->ccb) + cam_freeccb(d->ccb); + if (d->dev) + cam_close_device(d->dev); + if (d->sg_buffer) + free(d->sg_buffer); + if (d->ioctl_fd != -1) + close(d->ioctl_fd); +#endif free(d); } --- cdparanoia-3a9.8.orig/interface/low_interface.h +++ cdparanoia-3a9.8/interface/low_interface.h @@ -25,6 +25,8 @@ #include <sys/time.h> #include <sys/types.h> +#if defined(__linux__) + #include <linux/major.h> #include <linux/version.h> @@ -48,12 +50,27 @@ #include <linux/cdrom.h> #include <linux/major.h> +#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" #define MAX_RETRIES 8 #define MAX_BIG_BUFF_SIZE 65536 #define MIN_BIG_BUFF_SIZE 4096 + +#if defined(__linux__) #define SG_OFF sizeof(struct sg_header) +#else +#define SG_OFF (0) +#endif #ifndef SG_EMULATED_HOST /* old kernel version; the check for the ioctl is still runtime, this @@ -64,7 +81,9 @@ #endif extern int cooked_init_drive (cdrom_drive *d); +#if defined(__linux__) extern unsigned char *scsi_inquiry (cdrom_drive *d); +#endif extern int scsi_init_drive (cdrom_drive *d); #ifdef CDDA_TEST extern int test_init_drive (cdrom_drive *d); --- cdparanoia-3a9.8.orig/interface/scsi_interface.c +++ cdparanoia-3a9.8/interface/scsi_interface.c @@ -3,6 +3,8 @@ * Original interface.c Copyright (C) 1994-1997 * Eissfeldt [EMAIL PROTECTED] * Current blenderization Copyright (C) 1998-1999 Monty [EMAIL PROTECTED] + * FreeBSD porting (c) 2003 + * Simon 'corecode' Schubert <[EMAIL PROTECTED]> * * Generic SCSI interface specific code. * @@ -23,6 +25,7 @@ int table,reserved; char buffer[256]; +#if defined(__linux__) /* maximum transfer size? */ if(ioctl(d->cdda_fd,SG_GET_RESERVED_SIZE,&reserved)){ /* Up, guess not. */ @@ -59,8 +62,17 @@ cdmessage(d,"\tCouldn't disable command queue! Continuing anyway...\n"); } +#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); + cdmessage(d,buffer); +#endif } +#if defined(__linux__) static void reset_scsi(cdrom_drive *d){ int arg; d->enable_cdda(d,0); @@ -74,6 +86,30 @@ d->enable_cdda(d,1); } +#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) +static void reset_scsi(cdrom_drive *d) { + d->enable_cdda(d,0); + + d->ccb->ccb_h.func_code = XPT_RESET_DEV; + d->ccb->ccb_h.timeout = 5000; + + cdmessage(d, "sending SCSI reset... "); + if (cam_send_ccb(d->dev, d->ccb)) { + cdmessage(d, "error sending XPT_RESET_DEV CCB"); + } else { + + if (((d->ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) || + ((d->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 + +#if defined(__linux__) static void clear_garbage(cdrom_drive *d){ fd_set fdset; struct timeval tv; @@ -104,8 +140,10 @@ flag=1; } } +#endif /* process a complete scsi command. */ +#if defined(__linux__) static int handle_scsi_cmd(cdrom_drive *d, unsigned int cmd_len, unsigned int in_size, @@ -284,6 +322,84 @@ return(0); } +#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) +static int handle_scsi_cmd(cdrom_drive *d, + unsigned int cmd_len, + unsigned int out_size, + unsigned int in_size, + unsigned char bytefill, + int bytecheck) { + int result; + + bzero(&d->ccb->csio, sizeof(d->ccb->csio)); + + memcpy(d->ccb->csio.cdb_io.cdb_bytes, d->sg_buffer, cmd_len); + + if (bytecheck && out_size == 0) + memset(d->sg_buffer, bytefill, in_size); + + cam_fill_csio(&d->ccb->csio, + /* retries */ 0, + /* cbfcnp */ NULL, + /* flags */ CAM_DEV_QFRZDIS | (out_size ? CAM_DIR_OUT : CAM_DIR_IN), + /* tag_action */ MSG_SIMPLE_Q_TAG, + /* data_ptr */ out_size ? d->sg_buffer + cmd_len : d->sg_buffer, + /* dxfer_len */ out_size ? out_size : in_size, + /* sense_len */ SSD_FULL_SIZE, + /* cdb_len */ cmd_len, + /* timeout */ 60000); /* XXX */ + + if ((result = cam_send_ccb(d->dev, d->ccb)) < 0 || + (d->ccb->ccb_h.status & CAM_STATUS_MASK) == 0 /* hack? */) + return TR_EREAD; + + if ((d->ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP && + (d->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->ccb->ccb_h.status); + errno = EIO; + return TR_UNKNOWN; + } + + if (d->ccb->csio.dxfer_len != in_size) { + errno = EIO; + return TR_EREAD; + } + + if (d->ccb->csio.sense_data.error_code & SSD_ERRCODE) { + switch (d->ccb->csio.sense_data.flags & SSD_KEY) { + 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 (d->ccb->csio.sense_data.add_sense_code == 0x0c && + d->ccb->csio.sense_data.add_sense_code_qual == 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 + + /* Group 1 (10b) command */ static int mode_sense_atapi(cdrom_drive *d,int size,int page){ @@ -833,30 +949,33 @@ while(1) { if((err=map(d,(p?buffer:NULL),begin,sectors))){ if(d->report_all){ +#if defined(__linux__) struct sg_header *sg_hd=(struct sg_header *)d->sg; +#endif char b[256]; sprintf(b,"scsi_read error: sector=%ld length=%ld retry=%d\n", begin,sectors,retry_count); + fputs(b, stderr); cdmessage(d,b); sprintf(b," Sense key: %x ASC: %x ASCQ: %x\n", +#if defined(__linux__) (int)(sg_hd->sense_buffer[2]&0xf), (int)(sg_hd->sense_buffer[12]), (int)(sg_hd->sense_buffer[13])); +#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) + d->ccb->csio.sense_data.flags & SSD_KEY, + d->ccb->csio.sense_data.add_sense_code, + d->ccb->csio.sense_data.add_sense_code_qual); +#endif + fputs(b, stderr); cdmessage(d,b); sprintf(b," Transport error: %s\n",strerror_tr[err]); + fputs(b, stderr); cdmessage(d,b); sprintf(b," System error: %s\n",strerror(errno)); + fputs(b, stderr); cdmessage(d,b); - - fprintf(stderr,"scsi_read error: sector=%ld length=%ld retry=%d\n", - begin,sectors,retry_count); - fprintf(stderr," Sense key: %x ASC: %x ASCQ: %x\n", - (int)(sg_hd->sense_buffer[2]&0xf), - (int)(sg_hd->sense_buffer[12]), - (int)(sg_hd->sense_buffer[13])); - fprintf(stderr," Transport error: %s\n",strerror_tr[err]); - fprintf(stderr," System error: %s\n",strerror(errno)); } if(!d->error_retry)return(-7); @@ -1307,6 +1426,7 @@ return; } +#if defined(__linux__) 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 @@ -1333,6 +1453,47 @@ } } +#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) +static int +check_atapi(cdrom_drive *d) +{ + bzero(&(&d->ccb->ccb_h)[1], sizeof(d->ccb->cpi) - sizeof(d->ccb->ccb_h)); + + d->ccb->ccb_h.func_code = XPT_PATH_INQ; + + cdmessage(d, "\nChecking for ATAPICAM...\n"); + + if (cam_send_ccb(d->dev, d->ccb) < 0) { + cderror(d, "\terror sending XPT_PATH_INQ CCB: "); + cderror(d, cam_errbuf); + cderror(d, "\n"); + return -1; + } + + if ((d->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->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){ char *b; cdmessage(d,"\nChecking for MMC style command set...\n"); @@ -1379,6 +1540,7 @@ } } +#if defined(__linux__) /* request vendor brand and model */ unsigned char *scsi_inquiry(cdrom_drive *d){ memcpy(d->sg_buffer,(char[]){ 0x12,0,0,0,56,0},6); @@ -1389,6 +1551,7 @@ } return (d->sg_buffer); } +#endif int scsi_init_drive(cdrom_drive *d){ @@ -1458,8 +1621,12 @@ check_fua_bit(d); d->error_retry=1; +#if defined(__linux__) d->sg=realloc(d->sg,d->nsectors*CD_FRAMESIZE_RAW + SG_OFF + 128); d->sg_buffer=d->sg+SG_OFF; +#elif defined(__FreeBSD__) + d->sg_buffer = realloc(d->sg_buffer, d->nsectors * CD_FRAMESIZE_RAW); +#endif d->report_all=1; return(0); }