interface.c
上传用户:xiejiait
上传日期:2007-01-06
资源大小:881k
文件大小:23k
- /* @(#)interface.c 1.3 00/01/25 Copyright 1998,1999 Heiko Eissfeldt */
- #ifndef lint
- static char sccsid[] =
- "@(#)interface.c 1.3 00/01/25 Copyright 1998,1999 Heiko Eissfeldt";
- #endif
- /***
- * CopyPolicy: GNU Public License 2 applies
- * Copyright (C) 1994-1997 Heiko Eissfeldt heiko@colossus.escape.de
- *
- * Interface module for cdrom drive access
- *
- * Two interfaces are possible.
- *
- * 1. using 'cooked' ioctls() (Linux only)
- * : available for atapi, sbpcd and cdu31a drives only.
- *
- * 2. using the generic scsi device (for details see SCSI Prog. HOWTO).
- * NOTE: a bug/misfeature in the kernel requires blocking signal
- * SIGINT during SCSI command handling. Once this flaw has
- * been removed, the sigprocmask SIG_BLOCK and SIG_UNBLOCK calls
- * should removed, thus saving context switches.
- *
- * For testing purposes I have added a third simulation interface.
- *
- * Version 0.8: used experiences of Jochen Karrer.
- * SparcLinux port fixes
- * AlphaLinux port fixes
- *
- */
- #if 0
- #define SIM_CD
- #endif
- #include "config.h"
- #include <stdio.h>
- #include <standard.h>
- #include <stdlib.h>
- #include <unixstd.h>
- #include <strdefs.h>
- #include <errno.h>
- #include <signal.h>
- #include <fcntl.h>
- #include <assert.h>
- #include <sys/ioctl.h>
- #include <sys/stat.h>
- #include <statdefs.h>
- #include "mycdrom.h"
- #include "lowlevel.h"
- /* some include file locations have changed with newer kernels */
- #if defined (__linux__)
- # if LINUX_VERSION_CODE > 0x10300 + 97
- # if LINUX_VERSION_CODE < 0x200ff
- # include <linux/sbpcd.h>
- # include <linux/ucdrom.h>
- # endif
- # if !defined(CDROM_SELECT_SPEED)
- # include <linux/ucdrom.h>
- # endif
- # endif
- #endif
- #include <scg/scsitransp.h>
- #include "mytype.h"
- #include "byteorder.h"
- #include "interface.h"
- #include "cdda2wav.h"
- #include "semshm.h"
- #include "setuid.h"
- #include "ringbuff.h"
- #include "toc.h"
- #include "global.h"
- #include "ioctl.h"
- #include "scsi_cmds.h"
- #include <utypes.h>
- #include <cdrecord.h>
- unsigned interface;
- int trackindex_disp = 0;
- TOC g_toc [MAXTRK]; /* 100 */
- unsigned char MCN[14]; /* including a zero string terminator */
- void (*EnableCdda) __PR((SCSI *, int Switch));
- unsigned (*ReadToc) __PR(( SCSI *scgp, TOC *ptoc ));
- void (*ReadTocText) __PR(( SCSI *scgp ));
- unsigned (*ReadLastAudio) __PR(( SCSI *scgp, unsigned tracks ));
- void (*ReadCdRom) __PR((SCSI *scgp, UINT4 *p, unsigned lSector, unsigned SectorBurstVal ));
- void (*ReadCdRomData) __PR((SCSI *scgp, unsigned char *p, unsigned lSector, unsigned SectorBurstVal ));
- subq_chnl *(*ReadSubQ) __PR(( SCSI *scgp, unsigned char sq_format, unsigned char track ));
- void (*SelectSpeed) __PR(( SCSI *scgp, unsigned speed ));
- int (*Play_at) __PR(( SCSI *scgp, unsigned int from_sector, unsigned int sectors));
- int (*StopPlay) __PR(( SCSI *scgp));
- void (*trash_cache) __PR((UINT4 *p, unsigned lSector, unsigned SectorBurstVal));
- typedef struct string_len {
- char *str;
- unsigned int sl;
- } mystring;
- static mystring drv_is_not_mmc[] = {
- {"SONY CD-ROM CDU625 1.0",28},
- {NULL,0} /* must be last entry */
- };
- static mystring drv_has_mmc_cdda[] = {
- {NULL,0} /* must be last entry */
- };
- static int Is_a_Toshiba3401;
- int Toshiba3401 __PR((void));
- int Toshiba3401 ( ) {
- return Is_a_Toshiba3401;
- }
- /* hook */
- static void Dummy __PR(( void ));
- static void Dummy ( )
- {
- }
- static SCSI *scgp;
- SCSI * get_scsi_p __PR((void));
- SCSI * get_scsi_p( )
- {
- return scgp;
- }
- #if !defined(SIM_CD)
- static void trash_cache_SCSI __PR((UINT4 *p, unsigned lSector, unsigned SectorBurstVal));
- static void trash_cache_SCSI(p, lSector, SectorBurstVal)
- UINT4 *p;
- unsigned lSector;
- unsigned SectorBurstVal;
- {
- /* trash the cache */
- ReadCdRom(get_scsi_p(), p, find_an_off_sector(lSector, SectorBurstVal), min(global.nsectors,6));
- }
- static void Check_interface_for_device __PR((struct stat *statstruct, char *pdev_name));
- static int OpenCdRom __PR((char *pdev_name));
- static void SetupSCSI __PR((void));
- static void SetupSCSI( )
- {
- unsigned char *p;
- if (interface != GENERIC_SCSI) {
- /* unfortunately we have the wrong interface and are
- * not able to change on the fly */
- fprintf(stderr, "The generic SCSI interface and devices are requiredn");
- exit(1);
- }
- /* do a test unit ready to 'init' the device. */
- TestForMedium(scgp);
- /* check for the correct type of unit. */
- p = Inquiry(scgp);
- #undef TYPE_ROM
- #define TYPE_ROM 5
- #undef TYPE_WORM
- #define TYPE_WORM 4
- if (p == NULL) {
- fprintf(stderr, "Inquiry command failed. Aborting...n");
- exit(1);
- }
- if ((*p != TYPE_ROM && *p != TYPE_WORM)) {
- fprintf(stderr, "this is neither a scsi cdrom nor a worm devicen");
- exit(1);
- }
- /* generic Sony type defaults */
- density = 0x0;
- accepts_fua_bit = -1;
- accepts_fua_bit = -1;
- EnableCdda = (void (*) __PR((SCSI *, int)))Dummy;
- ReadCdRom = ReadCdda12;
- ReadCdRomData = (void (*) __PR((SCSI *, unsigned char *, unsigned, unsigned ))) ReadStandard;
- ReadLastAudio = ReadFirstSessionTOCSony;
- SelectSpeed = SpeedSelectSCSISony;
- Play_at = Play_atSCSI;
- StopPlay = StopPlaySCSI;
- trash_cache = trash_cache_SCSI;
- ReadTocText = ReadTocTextSCSIMMC;
- /* check for brands and adjust special peculiaritites */
- /* If your drive is not treated correctly, you can adjust some things
- here:
- *in_leendian: should be to 1, if the CDROM drive or CD-Writer
- delivers the samples in the native byteorder of the audio cd
- (LSB first).
- HP CD-Writers need it set to 0.
- NOTE: If you get correct wav files when using sox with the '-x' option,
- the endianess is wrong. You can use the -C option to specify
- the value of (*in_lendian).
- */
- {
- int mmc_code;
- allow_atapi(scgp, 1);
- if (*p == TYPE_ROM) {
- mmc_code = heiko_mmc(scgp);
- } else {
- mmc_code = 0;
- }
- /* Exceptions for drives that report incorrect MMC capability */
- if (mmc_code != 0) {
- /* these drives are NOT capable of MMC commands */
- mystring *pp = drv_is_not_mmc;
- while (pp->str != NULL) {
- if (!strncmp(pp->str, (char *)p+8,pp->sl)) {
- mmc_code = 0;
- break;
- }
- pp++;
- }
- }
- {
- /* these drives flag themselves as non-MMC, but offer CDDA reading
- only with a MMC method. */
- mystring *pp = drv_has_mmc_cdda;
- while (pp->str != NULL) {
- if (!strncmp(pp->str, (char *)p+8,pp->sl)) {
- mmc_code = 1;
- break;
- }
- pp++;
- }
- }
- switch (mmc_code) {
- case 2: /* SCSI-3 cdrom drive with accurate audio stream */
- if ( (*in_lendian) == -1 )
- (*in_lendian) = 1;
- global.overlap = 0;
- ReadCdRom = ReadCddaMMC12;
- ReadLastAudio = ReadFirstSessionTOCMMC;
- global.speed = 0xffff;
- SelectSpeed = SpeedSelectSCSIMMC;
- ReadTocText = ReadTocTextSCSIMMC;
- break;
- case 1: /* SCSI-3 cdrom drive with no accurate audio stream */
- if ( (*in_lendian) == -1 )
- (*in_lendian) = 1;
- global.overlap = 1;
- ReadCdRom = ReadCddaMMC12;
- ReadLastAudio = ReadFirstSessionTOCMMC;
- global.speed = 0xffff;
- SelectSpeed = SpeedSelectSCSIMMC;
- break;
- case -1: /* "MMC drive does not support cdda reading, sorryn." */
- /* fall through */
- case 0: /* non SCSI-3 cdrom drive */
- ReadLastAudio = NULL;
- if (!memcmp(p+8,"TOSHIBA", 7) ||
- !memcmp(p+8,"IBM", 3) ||
- !memcmp(p+8,"DEC", 3)) {
- density = 0x82;
- EnableCdda = EnableCddaModeSelect;
- ReadCdRom = ReadStandard;
- SelectSpeed = SpeedSelectSCSIToshiba;
- if (!memcmp(p+16, "CD-ROM XM-3401",14)) {
- Is_a_Toshiba3401 = 1;
- }
- if ( (*in_lendian) == -1 )
- (*in_lendian) = 1;
- } else if (!memcmp(p+8,"IMS",3) ||
- !memcmp(p+8,"KODAK",5) ||
- !memcmp(p+8,"RICOH",5) ||
- !memcmp(p+8,"HP",2) ||
- !memcmp(p+8,"PHILIPS",7) ||
- !memcmp(p+8,"PLASMON",7) ||
- !memcmp(p+8,"GRUNDIG CDR100IPW",17) ||
- !memcmp(p+8,"MITSUMI CD-R ",13)) {
- EnableCdda = EnableCddaModeSelect;
- ReadCdRom = ReadStandard;
- SelectSpeed = SpeedSelectSCSIPhilipsCDD2600;
- /* treat all of these as bigendian */
- if ( (*in_lendian) == -1 )
- (*in_lendian) = 0;
- /* no overlap reading for cd-writers */
- global.overlap = 0;
- } else if (!memcmp(p+8,"NRC",3)) {
- SelectSpeed = NULL;
- } else if (!memcmp(p+8,"YAMAHA",6)) {
- EnableCdda = EnableCddaModeSelect;
- SelectSpeed = SpeedSelectSCSIYamaha;
- /* no overlap reading for cd-writers */
- global.overlap = 0;
- if ( (*in_lendian) == -1 )
- (*in_lendian) = 1;
- } else if (!memcmp(p+8,"PLEXTOR",7)) {
- if ( (*in_lendian) == -1 )
- (*in_lendian) = 1;
- global.overlap = 0;
- ReadLastAudio = ReadFirstSessionTOCSony;
- ReadTocText = ReadTocTextSCSIMMC;
- } else if (!memcmp(p+8,"SONY",4)) {
- if ( (*in_lendian) == -1 )
- (*in_lendian) = 1;
- if (!memcmp(p+16, "CD-ROM CDU55E",13)) {
- ReadCdRom = ReadCddaMMC12;
- }
- ReadLastAudio = ReadFirstSessionTOCSony;
- ReadTocText = ReadTocTextSCSIMMC;
- } else if (!memcmp(p+8,"NEC",3)) {
- ReadCdRom = ReadCdda10;
- ReadTocText = NULL;
- SelectSpeed = SpeedSelectSCSINEC;
- if ( (*in_lendian) == -1 )
- (*in_lendian) = 1;
- if (!memcmp(p+29,"5022.0r",3)) /* I assume all versions of the 502 require this? */
- global.overlap = 0; /* no overlap reading for NEC CD-ROM 502 */
- } else if (!memcmp(p+8,"MATSHITA",8)) {
- ReadCdRom = ReadCdda12Matsushita;
- if ( (*in_lendian) == -1 )
- (*in_lendian) = 1;
- }
- } /* switch (get_mmc) */
- }
- ReadToc = ReadTocSCSI;
- ReadSubQ = ReadSubQSCSI;
- /* look if caddy is loaded */
- if (interface == GENERIC_SCSI) while (!wait_unit_ready(scgp, 60)) {
- fprintf(stderr,"load cdrom please and press enter");
- getchar();
- }
- }
- /********************** General setup *******************************/
- /* As the name implies, interfaces and devices are checked. We also
- adjust nsectors, overlap, and interface for the first time here.
- Any unnecessary privileges (setuid, setgid) are also dropped here.
- */
- static void Check_interface_for_device( statstruct, pdev_name)
- struct stat *statstruct;
- char *pdev_name;
- {
- #if !defined (STAT_MACROS_BROKEN) || (STAT_MACROS_BROKEN != 1)
- if (!S_ISCHR(statstruct->st_mode) &&
- !S_ISBLK(statstruct->st_mode)) {
- fprintf(stderr, "%s is not a devicen",pdev_name);
- exit(1);
- }
- #endif
- #if defined (HAVE_ST_RDEV) && (HAVE_ST_RDEV == 1)
- switch ((int) (statstruct->st_rdev >> 8L)) {
- #if defined (__linux__)
- case SCSI_GENERIC_MAJOR: /* generic */
- #else
- default: /* ??? what is the proper value here */
- #endif
- #if !defined (STAT_MACROS_BROKEN) || (STAT_MACROS_BROKEN != 1)
- #if defined (__linux__)
- if (!S_ISCHR(statstruct->st_mode)) {
- fprintf(stderr, "%s is not a char devicen",pdev_name);
- exit(1);
- }
- if (interface != GENERIC_SCSI) {
- fprintf(stderr, "wrong interface (cooked_ioctl) for this device (%s)nset to generic_scsin", pdev_name);
- interface = GENERIC_SCSI;
- }
- #endif
- #endif
- break;
- #if defined (__linux__) || defined (__FreeBSD__)
- #if defined (__linux__)
- case SCSI_CDROM_MAJOR: /* scsi cd */
- default: /* for example ATAPI cds */
- #else
- #if defined (__FreeBSD__)
- case 117:
- if (!S_ISCHR(statstruct->st_mode)) {
- fprintf(stderr, "%s is not a char devicen",pdev_name);
- exit(1);
- }
- if (interface != COOKED_IOCTL) {
- fprintf(stderr, "cdrom device (%s) is not of type generic SCSI. "
- "Setting interface to cooked_ioctl.n", pdev_name);
- interface = COOKED_IOCTL;
- }
- break;
- case 19: /* first atapi cd */
- #endif
- #endif
- if (!S_ISBLK(statstruct->st_mode)) {
- fprintf(stderr, "%s is not a block devicen",pdev_name);
- exit(1);
- }
- if (interface != COOKED_IOCTL) {
- fprintf(stderr, "cdrom device (%s) is not of type generic SCSI. "
- "Setting interface to cooked_ioctl.n", pdev_name);
- interface = COOKED_IOCTL;
- }
- break;
- #endif
- }
- #endif
- if (global.overlap >= global.nsectors)
- global.overlap = global.nsectors-1;
- }
- /* open the cdrom device */
- static int OpenCdRom ( pdev_name )
- char *pdev_name;
- {
- int retval = 0;
- struct stat fstatstruct;
- /* The device (given by pdevname) can be:
- a. an SCSI device specified with a /dev/xxx name,
- b. an SCSI device specified with bus,target,lun numbers,
- c. a non-SCSI device such as ATAPI or proprietary CDROM devices.
- */
- #ifdef HAVE_IOCTL_INTERFACE
- struct stat statstruct;
- int have_named_device = 0;
- have_named_device = strchr(pdev_name, ':') == NULL
- && memcmp(pdev_name, "/dev/", 5) == 0;
- if (have_named_device) {
- if (stat(pdev_name, &statstruct)) {
- fprintf(stderr, "cannot stat device %sn", pdev_name);
- exit(1);
- } else {
- Check_interface_for_device( &statstruct, pdev_name );
- }
- }
- #endif
- if (interface == GENERIC_SCSI) {
- char errstr[80];
- needroot(0);
- needgroup(0);
- /* device name, debug, verboseopen */
- scgp = open_scsi(pdev_name, errstr, sizeof(errstr), 0, 0);
- if (scgp == NULL) {
- errmsg("%s%sCannot open SCSI driver.n", errstr, errstr[0]?". ":"");
- fprintf(stderr, "open(%s) in file %s, line %dn",pdev_name, __FILE__, __LINE__);
- dontneedgroup();
- dontneedroot();
- #if defined(sun) || defined(__sun)
- fprintf(stderr, "On SunOS/Solaris make sure you have Joerg Schillings scg SCSI driver installed.n");
- #endif
- #if defined (__linux__)
- fprintf(stderr, "Use the script scan_scsi.linux to find out more.n");
- #endif
- fprintf(stderr, "Probably you did not define your SCSI device.n");
- fprintf(stderr, "You can scan the SCSI bus(es) with 'cdrecord -scanbus'.n");
- fprintf(stderr, "Set the CDDA_DEVICE environment variable or use the -D option.n");
- fprintf(stderr, "You can also define the default device in the Makefile.n");
- exit(1);
- }
- scsi_settimeout(scgp, 100);
- if (scgp) {
- scgp->silent = global.scsi_silent;
- scgp->verbose = global.scsi_verbose;
- }
- dontneedgroup();
- dontneedroot();
- if (global.nsectors > (unsigned) scsi_bufsize(scgp, 100*1024*1024)/CD_FRAMESIZE_RAW)
- global.nsectors = scsi_bufsize(scgp, 100*1024*1024)/CD_FRAMESIZE_RAW;
- if (global.overlap >= global.nsectors)
- global.overlap = global.nsectors-1;
- init_scsibuf(scgp, global.nsectors*CD_FRAMESIZE_RAW);
- } else {
- needgroup(0);
- retval = open(pdev_name,O_RDONLY);
- dontneedgroup();
- if (retval < 0) {
- fprintf(stderr, "while opening %s :", pdev_name);
- perror("");
- exit(1);
- }
- /* Do final security checks here */
- if (fstat(retval, &fstatstruct)) {
- fprintf(stderr, "Could not fstat %s (fd %d): ", pdev_name, retval);
- perror("");
- exit(1);
- }
- Check_interface_for_device( &fstatstruct, pdev_name );
- #if defined HAVE_IOCTL_INTERFACE
- /* Watch for race conditions */
- if (have_named_device
- && (fstatstruct.st_dev != statstruct.st_dev ||
- fstatstruct.st_ino != statstruct.st_ino)) {
- fprintf(stderr,"Race condition attempted in OpenCdRom. Exiting now.n");
- exit(1);
- }
- #endif
- }
- return retval;
- }
- #endif /* SIM_CD */
- /******************* Simulation interface *****************/
- #if defined SIM_CD
- #include "toc.h"
- static unsigned long sim_pos=0;
- /* read 'SectorBurst' adjacent sectors of audio sectors
- * to Buffer '*p' beginning at sector 'lSector'
- */
- static void ReadCdRom_sim __PR(( SCSI *x, UINT4 *p, unsigned lSector, unsigned SectorBurstVal));
- static void ReadCdRom_sim (x, p, lSector, SectorBurstVal )
- SCSI *x;
- UINT4 *p;
- unsigned lSector;
- unsigned SectorBurstVal;
- {
- unsigned int loop=0;
- short *q = (short *) p;
- int joffset = 0;
- if (lSector > g_toc[cdtracks].dwStartSector || lSector + SectorBurstVal > g_toc[cdtracks].dwStartSector + 1) {
- fprintf(stderr, "Read request out of bounds: %u - %u (%d - %d allowed)n",
- lSector, lSector + SectorBurstVal, 0, g_toc[cdtracks].dwStartSector);
- }
- #if 0
- /* jitter with a probability of jprob */
- if (random() <= jprob) {
- /* jitter up to jmax samples */
- joffset = random();
- }
- #endif
- #ifdef DEBUG_SHM
- fprintf(stderr, ", last_b = %pn", *last_buffer);
- #endif
- for (loop = lSector*CD_FRAMESAMPLES + joffset;
- loop < (lSector+SectorBurstVal)*CD_FRAMESAMPLES + joffset;
- loop++) {
- *q++ = loop;
- *q++ = ~loop;
- }
- #ifdef DEBUG_SHM
- fprintf(stderr, "sim wrote from %p upto %p - 4 (%d), last_b = %pn",
- p, q, SectorBurstVal*CD_FRAMESAMPLES, *last_buffer);
- #endif
- sim_pos = (lSector+SectorBurstVal)*CD_FRAMESAMPLES + joffset;
- }
- static int Play_at_sim __PR(( SCSI *x, unsigned int from_sector, unsigned int sectors));
- static int Play_at_sim( x, from_sector, sectors)
- SCSI *x;
- unsigned int from_sector;
- unsigned int sectors;
- {
- sim_pos = from_sector*CD_FRAMESAMPLES;
- return 0;
- }
- static unsigned sim_indices;
- /* read the table of contents (toc) via the ioctl interface */
- static unsigned ReadToc_sim __PR(( SCSI *x, TOC *toc));
- static unsigned ReadToc_sim ( x, toc )
- SCSI *x;
- TOC *toc;
- {
- unsigned int scenario;
- int scen[12][3] = {
- {1,1,500},
- {1,2,500},
- {1,99,150*99},
- {2,1,500},
- {2,2,500},
- {2,99,150*99},
- {5,1,500},
- {5,2,500},
- {5,99,150*99},
- {99,1,1000},
- {99,2,1000},
- {99,99,150*99},
- };
- unsigned int i;
- unsigned trcks;
- #if 0
- fprintf(stderr, "select one of the following TOCsn"
- "0 : 1 track with 1 indexn"
- "1 : 1 track with 2 indicesn"
- "2 : 1 track with 99 indicesn"
- "3 : 2 tracks with 1 index eachn"
- "4 : 2 tracks with 2 indices eachn"
- "5 : 2 tracks with 99 indices eachn"
- "6 : 5 tracks with 1 index eachn"
- "7 : 5 tracks with 2 indices eachn"
- "8 : 5 tracks with 99 indices eachn"
- "9 : 99 tracks with 1 index eachn"
- "10: 99 tracks with 2 indices eachn"
- "11: 99 tracks with 99 indices eachn"
- );
- do {
- scanf("%u", &scenario);
- } while (scenario > sizeof(scen)/2/sizeof(int));
- #else
- scenario = 6;
- #endif
- /* build table of contents */
- trcks = scen[scenario][0] + 1;
- sim_indices = scen[scenario][1];
- for (i = 0; i < trcks; i++) {
- toc[i].bFlags = 0x1b;
- toc[i].bTrack = i + 1;
- toc[i].dwStartSector = i * scen[scenario][2];
- }
- toc[i].bTrack = 0xaa;
- return --trcks; /* without lead-out */
- }
- static subq_chnl *ReadSubQ_sim __PR(( SCSI *scgp, unsigned char sq_format, unsigned char track ));
- /* request sub-q-channel information. This function may cause confusion
- * for a drive, when called in the sampling process.
- */
- static subq_chnl *ReadSubQ_sim ( scgp, sq_format, track )
- SCSI *scgp;
- unsigned char sq_format;
- unsigned char track;
- {
- subq_chnl *SQp = (subq_chnl *) (SubQbuffer);
- subq_position *SQPp = (subq_position *) &SQp->data;
- unsigned long sim_pos1;
- unsigned long sim_pos2;
- if ( sq_format != GET_POSITIONDATA ) return NULL; /* not supported by sim */
- /* simulate CDROMSUBCHNL ioctl */
- /* copy to SubQbuffer */
- SQp->audio_status = 0;
- SQp->format = 0xff;
- SQp->control_adr = 0xff;
- sim_pos1 = sim_pos/CD_FRAMESAMPLES;
- sim_pos2 = sim_pos1 % 150;
- SQp->track = (sim_pos1 / 5000) + 1;
- SQp->index = ((sim_pos1 / 150) % sim_indices) + 1;
- sim_pos1 += 150;
- SQPp->abs_min = sim_pos1 / (75*60);
- SQPp->abs_sec = (sim_pos1 / 75) % 60;
- SQPp->abs_frame = sim_pos1 % 75;
- SQPp->trel_min = sim_pos2 / (75*60);
- SQPp->trel_sec = (sim_pos2 / 75) % 60;
- SQPp->trel_frame = sim_pos2 % 75;
- return (subq_chnl *)(SubQbuffer);
- }
- static void SelectSpeed_sim __PR(( SCSI *x, unsigned sp));
- static void SelectSpeed_sim(x, sp)
- SCSI *x;
- unsigned sp;
- {
- PRETEND_TO_USE(x);
- PRETEND_TO_USE(sp);
- }
- static void trash_cache_sim __PR((UINT4 *p, unsigned lSector, unsigned SectorBurstVal));
- static void trash_cache_sim(p, lSector, SectorBurstVal)
- UINT4 *p;
- unsigned lSector;
- unsigned SectorBurstVal;
- {
- PRETEND_TO_USE(p);
- PRETEND_TO_USE(lSector);
- PRETEND_TO_USE(SectorBurstVal);
- }
- static void SetupSimCd __PR((void));
- static void SetupSimCd()
- {
- EnableCdda = (void (*) __PR((SCSI *, int)))Dummy;
- ReadCdRom = ReadCdRom_sim;
- ReadCdRomData = (void (*) __PR((SCSI *, unsigned char *, unsigned, unsigned ))) ReadCdRom_sim;
- ReadToc = ReadToc_sim;
- ReadTocText = NULL;
- ReadSubQ = ReadSubQ_sim;
- ReadLastAudio = NULL;
- SelectSpeed = SelectSpeed_sim;
- Play_at = Play_at_sim;
- StopPlay = (int (*) __PR((SCSI *)))Dummy;
- trash_cache = trash_cache_sim;
-
- }
- #endif /* def SIM_CD */
- /* perform initialization depending on the interface used. */
- void SetupInterface( )
- {
- #if defined SIM_CD
- global.nsectors = 75;
- fprintf( stderr, "SIMULATION MODE !!!!!!!!!!!n");
- #else
- /* ensure interface is setup correctly */
- global.cooked_fd = OpenCdRom ( global.dev_name );
- #endif
- #ifdef _SC_PAGESIZE
- global.pagesize = sysconf(_SC_PAGESIZE);
- #else
- global.pagesize = getpagesize();
- #endif
- /* Value of 'nsectors' must be defined here */
- assert(global.nsectors > 0);
- assert(global.buffers > 0);
- global.shmsize = HEADER_SIZE + ENTRY_SIZE_PAGE_AL * global.buffers;
- #if defined (HAVE_FORK_AND_SHAREDMEM)
- #if defined(HAVE_SMMAP) || defined(HAVE_USGSHM) || defined(HAVE_DOSALLOCSHAREDMEM)
- fill_buffer = request_shm_sem(global.shmsize, (unsigned char **)&fill_buffer);
- if (fill_buffer == NULL) {
- #else /* have shared memory */
- if (1) {
- #endif
- fprintf( stderr, "no shared memory available!n");
- exit(2);
- }
- #else /* do not have fork() and shared memory */
- fill_buffer = malloc(global.shmsize);
- if (fill_buffer == NULL) {
- fprintf( stderr, "no buffer memory available!n");
- exit(2);
- }
- #endif
- if (global.verbose != 0)
- fprintf(stderr,
- "%u bytes buffer memory requested, %d buffers, %d sectorsn",
- global.shmsize, global.buffers, global.nsectors);
- /* initialize pointer into shared memory segment */
- last_buffer = fill_buffer + 1;
- total_segments_read = (unsigned long *) (last_buffer + 1);
- total_segments_written = total_segments_read + 1;
- child_waits = (int *) (total_segments_written + 1);
- parent_waits = child_waits + 1;
- in_lendian = parent_waits + 1;
- *in_lendian = -1;
- set_total_buffers(global.buffers, sem_id);
- /* request one sector for table of contents */
- bufferTOC = (unsigned char *) malloc( CD_FRAMESIZE ); /* assumes sufficient aligned addresses */
- /* SubQchannel buffer */
- SubQbuffer = (subq_chnl *) malloc( 48 ); /* assumes sufficient aligned addresses */
- cmd = (unsigned char *) malloc( 18 ); /* assumes sufficient aligned addresses */
- if ( !bufferTOC || !SubQbuffer || !cmd ) {
- fprintf( stderr, "Too low on memory. Giving up.n");
- exit(2);
- }
- #if defined SIM_CD
- SetupSimCd();
- #else
- /* if drive is of type scsi, get vendor name */
- if (interface == GENERIC_SCSI) {
- unsigned sector_size;
- SetupSCSI();
- sector_size = get_orig_sectorsize(scgp, &orgmode4, &orgmode10, &orgmode11);
- if (!SCSI_emulated_ATAPI_on(scgp)) {
- if ( sector_size != 2048 && set_sectorsize(scgp, 2048) ) {
- fprintf( stderr, "Could not change sector size from %d to 2048n", sector_size );
- }
- } else {
- sector_size = 2048;
- }
- /* get cache setting */
- /* set cache to zero */
- #if defined (HAVE_IOCTL_INTERFACE)
- } else {
- SetupCookedIoctl( global.dev_name );
- #endif
- }
- #endif /* if def SIM_CD */
- }