📄 scsi_cmds.c
字号:
int resp_size; register struct scg_cmd *scmd = scgp->scmd; switch (sq_format) { case GET_POSITIONDATA: resp_size = 16; track = 0; break; case GET_CATALOGNUMBER: resp_size = 24; track = 0; break; case GET_TRACK_ISRC: resp_size = 24; break; default: fprintf(stderr, "ReadSubQSCSI: unknown format %d\n", sq_format); return NULL; } fillbytes((caddr_t)scmd, sizeof(*scmd), '\0'); scmd->addr = (caddr_t)SubQbuffer; scmd->size = resp_size; 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 = 0x42; /* use LBA */ scmd->cdb.g1_cdb.lun = scgp->lun; scmd->cdb.g1_cdb.addr[0] = 0x40; /* SubQ info */ scmd->cdb.g1_cdb.addr[1] = sq_format; /* parameter list: all */ scmd->cdb.g1_cdb.res6 = track; /* track number */ g1_cdblen(&scmd->cdb.g1_cdb, resp_size); if (scgp->verbose) fprintf(stderr, "\nRead Subchannel..."); scgp->cmdname = "Read Subchannel"; if (scsicmd(scgp) < 0) { /* in case of error do a fallback for dumb firmwares */ return ReadSubQFallback(scgp, sq_format, track); } return SubQbuffer;}/********* non standardized speed selects ***********************/void SpeedSelectSCSIToshiba (scgp, speed) SCSI *scgp; unsigned speed;{ static unsigned char mode [4 + 3]; unsigned char *page = mode + 4; int retval; fillbytes((caddr_t)mode, sizeof(mode), '\0'); /* the first 4 mode bytes are zero. */ page[0] = 0x20; page[1] = 1; page[2] = speed; /* 0 for single speed, 1 for double speed (3401) */ if (scgp->verbose) fprintf(stderr, "\nspeed select Toshiba..."); scgp->silent++; /* do the scsi cmd */ if ((retval = mode_select(scgp, mode, 7, 0, scgp->inq->data_format >= 2)) < 0) fprintf (stderr, "speed select Toshiba failed\n"); scgp->silent--;}void SpeedSelectSCSINEC (scgp, speed) SCSI *scgp; unsigned speed;{ static unsigned char mode [4 + 8]; unsigned char *page = mode + 4; int retval; register struct scg_cmd *scmd = scgp->scmd; fillbytes((caddr_t)mode, sizeof(mode), '\0'); /* the first 4 mode bytes are zero. */ page [0] = 0x0f; /* page code */ page [1] = 6; /* parameter length */ /* bit 5 == 1 for single speed, otherwise double speed */ page [2] = speed == 1 ? 1 << 5 : 0; fillbytes((caddr_t)scmd, sizeof(*scmd), '\0'); scmd->addr = (caddr_t)mode; scmd->size = 12; scmd->flags = SCG_DISRE_ENA; scmd->cdb_len = SC_G1_CDBLEN; scmd->sense_len = CCS_SENSE_LEN; scmd->target = scgp->target; scmd->cdb.g1_cdb.cmd = 0xC5; scmd->cdb.g1_cdb.lun = scgp->lun; scmd->cdb.g1_cdb.addr[0] = 0 ? 1 : 0 | 1 ? 0x10 : 0; g1_cdblen(&scmd->cdb.g1_cdb, 12); if (scgp->verbose) fprintf(stderr, "\nspeed select NEC..."); /* do the scsi cmd */ scgp->cmdname = "speed select NEC"; if ((retval = scsicmd(scgp)) < 0) fprintf(stderr ,"speed select NEC failed\n");}void SpeedSelectSCSIPhilipsCDD2600 (scgp, speed) SCSI *scgp; unsigned speed;{ /* MODE_SELECT, page = SCSI-2 save page disabled, reserved, reserved, parm list len, flags */ static unsigned char mode [4 + 8]; unsigned char *page = mode + 4; int retval; fillbytes((caddr_t)mode, sizeof(mode), '\0'); /* the first 4 mode bytes are zero. */ page[0] = 0x23; page[1] = 6; page[2] = page [4] = speed; page[3] = 1; if (scgp->verbose) fprintf(stderr, "\nspeed select Philips..."); /* do the scsi cmd */ if ((retval = mode_select(scgp, mode, 12, 0, scgp->inq->data_format >= 2)) < 0) fprintf (stderr, "speed select PhilipsCDD2600 failed\n");}void SpeedSelectSCSISony (scgp, speed) SCSI *scgp; unsigned speed;{ static unsigned char mode [4 + 4]; unsigned char *page = mode + 4; int retval; fillbytes((caddr_t)mode, sizeof(mode), '\0'); /* the first 4 mode bytes are zero. */ page[0] = 0x31; page[1] = 2; page[2] = speed; if (scgp->verbose) fprintf(stderr, "\nspeed select Sony..."); /* do the scsi cmd */ scgp->silent++; if ((retval = mode_select(scgp, mode, 8, 0, scgp->inq->data_format >= 2)) < 0) fprintf (stderr, "speed select Sony failed\n"); scgp->silent--;}void SpeedSelectSCSIYamaha (scgp, speed) SCSI *scgp; unsigned speed;{ static unsigned char mode [4 + 4]; unsigned char *page = mode + 4; int retval; fillbytes((caddr_t)mode, sizeof(mode), '\0'); /* the first 4 mode bytes are zero. */ page[0] = 0x31; page[1] = 2; page[2] = speed; if (scgp->verbose) fprintf(stderr, "\nspeed select Yamaha..."); /* do the scsi cmd */ if ((retval = mode_select(scgp, mode, 8, 0, scgp->inq->data_format >= 2)) < 0) fprintf (stderr, "speed select Yamaha failed\n");}void SpeedSelectSCSIMMC (scgp, speed) SCSI *scgp; unsigned speed;{ int spd; register struct scg_cmd *scmd = scgp->scmd; if (speed == 0 || speed == 0xFFFF) { spd = 0xFFFF; } else { spd = (1764 * speed) / 10; } fillbytes((caddr_t)scmd, sizeof(*scmd), '\0'); scmd->flags = SCG_DISRE_ENA; scmd->cdb_len = SC_G5_CDBLEN; scmd->sense_len = CCS_SENSE_LEN; scmd->target = scgp->target; scmd->cdb.g5_cdb.cmd = 0xBB; scmd->cdb.g5_cdb.lun = scgp->lun; i_to_2_byte(&scmd->cdb.g5_cdb.addr[0], spd); i_to_2_byte(&scmd->cdb.g5_cdb.addr[2], spd); if (scgp->verbose) fprintf(stderr, "\nspeed select MMC..."); scgp->cmdname = "set cd speed"; if (scsicmd(scgp) < 0) fprintf (stderr, "speed select MMC failed\n");}/* request vendor brand and model */unsigned char *Inquiry ( scgp ) SCSI *scgp;{ static unsigned char *Inqbuffer = NULL; register struct scg_cmd *scmd = scgp->scmd; if (Inqbuffer == NULL) { Inqbuffer = (unsigned char *) malloc(42); if (Inqbuffer == NULL) { fprintf(stderr, "Cannot allocate memory for inquiry command in line %d\n", __LINE__); return NULL; } } fillbytes(Inqbuffer, 42, '\0'); fillbytes((caddr_t)scmd, sizeof(*scmd), '\0'); scmd->addr = (caddr_t)Inqbuffer; scmd->size = 42; scmd->flags = SCG_RECV_DATA|SCG_DISRE_ENA; scmd->cdb_len = SC_G0_CDBLEN; scmd->sense_len = CCS_SENSE_LEN; scmd->target = scgp->target; scmd->cdb.g0_cdb.cmd = SC_INQUIRY; scmd->cdb.g0_cdb.lun = scgp->lun; scmd->cdb.g0_cdb.count = 42; scgp->cmdname = "inquiry"; if (scsicmd(scgp) < 0) return (NULL); /* define structure with inquiry data */ memcpy(scgp->inq, Inqbuffer, sizeof(*scgp->inq)); if (scgp->verbose) scsiprbytes("Inquiry Data :", (u_char *)Inqbuffer, 22 - scmd->resid); return (Inqbuffer);}#define SC_CLASS_EXTENDED_SENSE 0x07#define TESTUNITREADY_CMD 0#define TESTUNITREADY_CMDLEN 6#define ADD_SENSECODE 12#define ADD_SC_QUALIFIER 13#define NO_MEDIA_SC 0x3a#define NO_MEDIA_SCQ 0x00int TestForMedium ( scgp ) SCSI *scgp;{ register struct scg_cmd *scmd = scgp->scmd; if (interface != GENERIC_SCSI) { return 1; } /* request READY status */ fillbytes((caddr_t)scmd, sizeof(*scmd), '\0'); scmd->addr = (caddr_t)0; scmd->size = 0; scmd->flags = SCG_DISRE_ENA | (1 ? SCG_SILENT:0); scmd->cdb_len = SC_G0_CDBLEN; scmd->sense_len = CCS_SENSE_LEN; scmd->target = scgp->target; scmd->cdb.g0_cdb.cmd = SC_TEST_UNIT_READY; scmd->cdb.g0_cdb.lun = scgp->lun; if (scgp->verbose) fprintf(stderr, "\ntest unit ready..."); scgp->silent++; scgp->cmdname = "test unit ready"; if (scsicmd(scgp) >= 0) { scgp->silent--; return 1; } scgp->silent--; if (scmd->sense.code >= SC_CLASS_EXTENDED_SENSE) { return scmd->u_sense.cmd_sense[ADD_SENSECODE] != NO_MEDIA_SC || scmd->u_sense.cmd_sense[ADD_SC_QUALIFIER] != NO_MEDIA_SCQ; } else { /* analyse status. */ /* 'check condition' is interpreted as not ready. */ return (scmd->u_scb.cmd_scb[0] & 0x1e) != 0x02; }}int StopPlaySCSI ( scgp ) SCSI *scgp;{ register struct scg_cmd *scmd = scgp->scmd; fillbytes((caddr_t)scmd, sizeof(*scmd), '\0'); scmd->addr = NULL; scmd->size = 0; scmd->flags = SCG_DISRE_ENA; scmd->cdb_len = SC_G0_CDBLEN; scmd->sense_len = CCS_SENSE_LEN; scmd->target = scgp->target; scmd->cdb.g0_cdb.cmd = 0x1b; scmd->cdb.g0_cdb.lun = scgp->lun; if (scgp->verbose) fprintf(stderr, "\nstop audio play"); /* do the scsi cmd */ scgp->cmdname = "stop audio play"; return scsicmd(scgp) >= 0 ? 0 : -1;}int Play_atSCSI ( scgp, from_sector, sectors) SCSI *scgp; unsigned int from_sector; unsigned int sectors;{ register struct scg_cmd *scmd = scgp->scmd; fillbytes((caddr_t)scmd, sizeof(*scmd), '\0'); scmd->addr = NULL; scmd->size = 0; scmd->flags = SCG_DISRE_ENA; scmd->cdb_len = SC_G1_CDBLEN; scmd->sense_len = CCS_SENSE_LEN; scmd->target = scgp->target; scmd->cdb.g1_cdb.cmd = 0x47; scmd->cdb.g1_cdb.lun = scgp->lun; scmd->cdb.g1_cdb.addr[1] = (from_sector + 150) / (60*75); scmd->cdb.g1_cdb.addr[2] = ((from_sector + 150) / 75) % 60; scmd->cdb.g1_cdb.addr[3] = (from_sector + 150) % 75; scmd->cdb.g1_cdb.res6 = (from_sector + 150 + sectors) / (60*75); scmd->cdb.g1_cdb.count[0] = ((from_sector + 150 + sectors) / 75) % 60; scmd->cdb.g1_cdb.count[1] = (from_sector + 150 + sectors) % 75; if (scgp->verbose) fprintf(stderr, "\nplay sectors..."); /* do the scsi cmd */ scgp->cmdname = "play sectors"; return scsicmd(scgp) >= 0 ? 0 : -1;}static caddr_t scsibuffer; /* page aligned scsi transfer buffer */void init_scsibuf __PR((SCSI *, unsigned));void init_scsibuf(scgp, amt) SCSI *scgp; unsigned amt;{ if (scsibuffer != NULL) { fprintf(stderr, "the SCSI transfer buffer has already been allocated!\n"); exit(3); } scsibuffer = scsi_getbuf(scgp, amt); if (scsibuffer == NULL) { fprintf(stderr, "could not get SCSI transfer buffer!\n"); exit(3); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -