📄 interface.c
字号:
#endif if (!S_ISBLK(statstruct->st_mode)) { fprintf(stderr, "%s is not a block device\n",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 %s\n", 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 %d\n",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 = %p\n", *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 = %p\n", 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 TOCs\n" "0 : 1 track with 1 index\n" "1 : 1 track with 2 indices\n" "2 : 1 track with 99 indices\n" "3 : 2 tracks with 1 index each\n" "4 : 2 tracks with 2 indices each\n" "5 : 2 tracks with 99 indices each\n" "6 : 5 tracks with 1 index each\n" "7 : 5 tracks with 2 indices each\n" "8 : 5 tracks with 99 indices each\n" "9 : 99 tracks with 1 index each\n" "10: 99 tracks with 2 indices each\n" "11: 99 tracks with 99 indices each\n" ); 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 sectors\n", 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 2048\n", 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 */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -