📄 scsi_cmds.c
字号:
/* @(#)scsi_cmds.c 1.2 99/12/19 Copyright 1998,1999 Heiko Eissfeldt */#ifndef lintstatic char sccsid[] ="@(#)scsi_cmds.c 1.2 99/12/19 Copyright 1998,1999 Heiko Eissfeldt";#endif/* file for all SCSI commands * FUA (Force Unit Access) bit handling copied from Monty's cdparanoia. */#define TESTSUBQFALLBACK 0#include "config.h"#include <stdio.h>#include <standard.h>#include <stdlib.h>#include <strdefs.h>#include <btorder.h>#define g5x_cdblen(cdb, len) ((cdb)->count[0] = ((len) >> 16L)& 0xFF,\ (cdb)->count[1] = ((len) >> 8L) & 0xFF,\ (cdb)->count[2] = (len) & 0xFF)#include <scg/scgcmd.h>#include <scg/scsidefs.h>#include <scg/scsireg.h>#include <scg/scsitransp.h>#include "mytype.h"#include "cdda2wav.h"#include "interface.h"#include "byteorder.h"#include "global.h"#include "cdrecord.h"#include "scsi_cmds.h"unsigned char *bufferTOC;subq_chnl *SubQbuffer;unsigned char *cmd;int SCSI_emulated_ATAPI_on(scgp) SCSI *scgp;{/* return is_atapi;*/ if (scsi_isatapi(scgp) > 0) return (TRUE); (void) allow_atapi(scgp, TRUE); return (allow_atapi(scgp, TRUE));}int heiko_mmc(scgp) SCSI *scgp;{ unsigned char mode[0x100]; int was_atapi; struct cd_mode_page_2A *mp; int retval; fillbytes((caddr_t)mode, sizeof(mode), '\0'); was_atapi = allow_atapi(scgp, 1); scgp->silent++; mp = mmc_cap(scgp, mode); scgp->silent--; allow_atapi(scgp, was_atapi); if (mp == NULL) return (0); /* have a look at the capabilities */ if (mp->cd_da_supported == 0) { retval = -1; } else { retval = 1 + mp->cd_da_accurate; } return retval;}int accepts_fua_bit;unsigned char density = 0;unsigned char orgmode4 = 0;unsigned char orgmode10, orgmode11;/* get current sector size from SCSI cdrom drive */unsigned int get_orig_sectorsize(scgp, m4, m10, m11) SCSI *scgp; unsigned char *m4; unsigned char *m10; unsigned char *m11;{ /* first get current values for density, etc. */ static unsigned char *modesense = NULL; if (modesense == NULL) { modesense = (unsigned char *) malloc(12); if (modesense == NULL) { fprintf(stderr, "Cannot allocate memory for mode sense command in line %d\n", __LINE__); return 0; } } /* do the scsi cmd */ if (scgp->verbose) fprintf(stderr, "\nget density and sector size..."); if (mode_sense(scgp, modesense, 12, 0x01, 0) < 0) fprintf(stderr, "get_orig_sectorsize mode sense failed\n"); /* FIXME: some drives dont deliver block descriptors !!! */ if (modesense[3] == 0) return 0; if (m4 != NULL) /* density */ *m4 = modesense[4]; if (m10 != NULL) /* MSB sector size */ *m10 = modesense[10]; if (m11 != NULL) /* LSB sector size */ *m11 = modesense[11]; return (modesense[10] << 8) + modesense[11];}/* switch CDROM scsi drives to given sector size */int set_sectorsize (scgp, secsize) SCSI *scgp; unsigned int secsize;{ static unsigned char mode [4 + 8]; int retval; if (orgmode4 == 0xff) { get_orig_sectorsize(scgp, &orgmode4, &orgmode10, &orgmode11); } if (orgmode4 == 0x82 && secsize == 2048) orgmode4 = 0x81; /* prepare to read cds in the previous mode */ fillbytes((caddr_t)mode, sizeof(mode), '\0'); mode[ 3] = 8; /* Block Descriptor Length */ mode[ 4] = orgmode4; /* normal density */ mode[10] = secsize >> 8; /* block length "msb" */ mode[11] = secsize & 0xFF; /* block length lsb */ if (scgp->verbose) fprintf(stderr, "\nset density and sector size..."); /* do the scsi cmd */ if ((retval = mode_select(scgp, mode, 12, 0, scgp->inq->data_format >= 2)) < 0) fprintf (stderr, "setting sector size failed\n"); return retval;}/* switch Toshiba/DEC and HP drives from/to cdda density */void EnableCddaModeSelect (scgp, fAudioMode) SCSI *scgp; int fAudioMode;{ /* reserved, Medium type=0, Dev spec Parm = 0, block descriptor len 0 oder 8, Density (cd format) (0=YellowBook, XA Mode 2=81h, XA Mode1=83h and raw audio via SCSI=82h), # blks msb, #blks, #blks lsb, reserved, blocksize, blocklen msb, blocklen lsb, */ /* MODE_SELECT, page = SCSI-2 save page disabled, reserved, reserved, parm list len, flags */ static unsigned char mode [4 + 8] = { /* mode section */ 0, 0, 0, 8, /* Block Descriptor Length */ /* block descriptor */ 0, /* Density Code */ 0, 0, 0, /* # of Blocks */ 0, /* reserved */ 0, 0, 0};/* Blocklen */ if (orgmode4 == 0 && fAudioMode) { if (0 == get_orig_sectorsize(scgp, &orgmode4, &orgmode10, &orgmode11)) { /* cannot retrieve density, sectorsize */ orgmode10 = (CD_FRAMESIZE >> 8L); orgmode11 = (CD_FRAMESIZE & 0xFF); } } if (fAudioMode) { /* prepare to read audio cdda */ mode [4] = density; /* cdda density */ mode [10] = (CD_FRAMESIZE_RAW >> 8L); /* block length "msb" */ mode [11] = (CD_FRAMESIZE_RAW & 0xFF); /* block length "lsb" */ } else { /* prepare to read cds in the previous mode */ mode [4] = orgmode4; /* 0x00; \* normal density */ mode [10] = orgmode10; /* (CD_FRAMESIZE >> 8L); \* block length "msb" */ mode [11] = orgmode11; /* (CD_FRAMESIZE & 0xFF); \* block length lsb */ } if (scgp->verbose) fprintf(stderr, "\nset density/sector size (EnableCddaModeSelect)...\n"); /* do the scsi cmd */ if (mode_select(scgp, mode, 12, 0, scgp->inq->data_format >= 2) < 0) fprintf (stderr, "Audio mode switch failed\n");}/* read CD Text information from the table of contents */void ReadTocTextSCSIMMC ( scgp ) SCSI *scgp;{ short int datalength; unsigned char *p = bufferTOC;#if 1 /* READTOC, MSF, format, res, res, res, Start track/session, len msb, len lsb, control */ register struct scg_cmd *scmd = scgp->scmd; fillbytes((caddr_t)scmd, sizeof(*scmd), '\0'); scmd->addr = (caddr_t)bufferTOC; scmd->size = 4; scmd->flags = SCG_RECV_DATA|SCG_DISRE_ENA; scmd->cdb_len = SC_G1_CDBLEN; scmd->sense_len = CCS_SENSE_LEN; scmd->target = scgp->target; scmd->cdb.g1_cdb.cmd = 0x43; /* Read TOC command */ scmd->cdb.g1_cdb.lun = scgp->lun; scmd->cdb.g1_cdb.addr[0] = 5; /* format field */ scmd->cdb.g1_cdb.res6 = 1; /* track/session */ g1_cdblen(&scmd->cdb.g1_cdb, 4); scgp->silent++; if (scgp->verbose) fprintf(stderr, "\nRead TOC CD Text size ..."); scgp->cmdname = "read toc size (text)"; if (scsicmd(scgp) < 0) { scgp->silent--; if (global.quiet != 1) fprintf (stderr, "Read TOC CD Text failed (probably not supported).\n"); p[0] = p[1] = '\0'; return ; } scgp->silent--; datalength = (p[0] << 8) | (p[1]); if (datalength <= 2) return; fillbytes((caddr_t)scmd, sizeof(*scmd), '\0'); scmd->addr = (caddr_t)bufferTOC; scmd->size = 2+datalength; scmd->flags = SCG_RECV_DATA|SCG_DISRE_ENA; scmd->cdb_len = SC_G1_CDBLEN; scmd->sense_len = CCS_SENSE_LEN; scmd->target = scgp->target; scmd->cdb.g1_cdb.cmd = 0x43; /* Read TOC command */ scmd->cdb.g1_cdb.lun = scgp->lun; scmd->cdb.g1_cdb.addr[0] = 5; /* format field */ scmd->cdb.g1_cdb.res6 = 1; /* track/session */ g1_cdblen(&scmd->cdb.g1_cdb, 2+datalength); scgp->silent++; if (scgp->verbose) fprintf(stderr, "\nRead TOC CD Text data ..."); scgp->cmdname = "read toc data (text)"; if (scsicmd(scgp) < 0) { scgp->silent--; if (global.quiet != 1) fprintf (stderr, "Read TOC CD Text data failed (probably not supported).\n"); p[0] = p[1] = '\0'; return ; } scgp->silent--;#else { FILE *fp; int read_; fp = fopen("PearlJam.cdtext", "rb"); /*fp = fopen("celine.cdtext", "rb");*/ if (fp == NULL) { perror(""); return; } fillbytes(bufferTOC, CD_FRAMESIZE, '\0'); read_ = fread(bufferTOC, 1, CD_FRAMESIZE, fp );fprintf(stderr, "read %d bytes. sizeof(bufferTOC)=%u\n", read_, CD_FRAMESIZE); datalength = (bufferTOC[0] << 8) | (bufferTOC[1]); fclose(fp); }#endif}/* read the start of the lead-out from the first session TOC */unsigned ReadFirstSessionTOCSony ( scgp, tracks ) SCSI *scgp; unsigned tracks;{ /* READTOC, MSF, format, res, res, res, Start track/session, len msb, len lsb, control */ register struct scg_cmd *scmd = scgp->scmd; fillbytes((caddr_t)scmd, sizeof(*scmd), '\0'); scmd->addr = (caddr_t)bufferTOC; scmd->size = 4 + (tracks + 3) * 11; scmd->flags = SCG_RECV_DATA|SCG_DISRE_ENA; scmd->cdb_len = SC_G1_CDBLEN; scmd->sense_len = CCS_SENSE_LEN; scmd->target = scgp->target; scmd->cdb.g1_cdb.cmd = 0x43; /* Read TOC command */ scmd->cdb.g1_cdb.lun = scgp->lun; scmd->cdb.g1_cdb.res6 = 1; /* session */ g1_cdblen(&scmd->cdb.g1_cdb, 4 + (tracks + 3) * 11); scmd->cdb.g1_cdb.vu_97 = 1; /* format */ scgp->silent++; if (scgp->verbose) fprintf(stderr, "\nRead TOC first session ..."); scgp->cmdname = "read toc first session"; if (scsicmd(scgp) < 0) { scgp->silent--; if (global.quiet != 1) fprintf (stderr, "Read TOC first session failed (probably not supported).\n"); return 0; } scgp->silent--; if ((unsigned)((bufferTOC[0] << 8) | bufferTOC[1]) >= 4 + (tracks + 3) * 11 -2) { unsigned off; /* We want the entry with POINT = 0xA2, which has the start position of the first session lead out */ off = 4 + 2 * 11 + 3; if (bufferTOC[off-3] == 1 && bufferTOC[off] == 0xA2) { unsigned retval; off = 4 + 2 * 11 + 8; retval = bufferTOC[off] >> 4; retval *= 10; retval += bufferTOC[off] & 0xf; retval *= 60; off++; retval += 10 * (bufferTOC[off] >> 4) + (bufferTOC[off] & 0xf); retval *= 75; off++; retval += 10 * (bufferTOC[off] >> 4) + (bufferTOC[off] & 0xf); retval -= 150; return retval; } } return 0;}/* read the start of the lead-out from the first session TOC */unsigned ReadFirstSessionTOCMMC ( scgp, tracks ) SCSI *scgp; unsigned tracks;{ /* READTOC, MSF, format, res, res, res, Start track/session, len msb, len lsb, control */ register struct scg_cmd *scmd = scgp->scmd; fillbytes((caddr_t)scmd, sizeof(*scmd), '\0'); scmd->addr = (caddr_t)bufferTOC; scmd->size = 4 + (tracks + 3) * 11; scmd->flags = SCG_RECV_DATA|SCG_DISRE_ENA; scmd->cdb_len = SC_G1_CDBLEN; scmd->sense_len = CCS_SENSE_LEN;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -