📄 scsi_cmds.c
字号:
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] = 2; /* format */ scmd->cdb.g1_cdb.res6 = 1; /* session */ g1_cdblen(&scmd->cdb.g1_cdb, 4 + (tracks + 3) * 11); 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 + 3; while (off < 4 + (tracks + 3) * 11 && bufferTOC[off] != 0xA2) { off += 11; } if (off < 4 + (tracks + 3) * 11) { off += 5; return (bufferTOC[off]*60 + bufferTOC[off+1])*75 + bufferTOC[off+2] - 150; } } return 0;}/* read the table of contents from the cd and fill the TOC array */unsigned ReadTocSCSI ( scgp, toc ) SCSI *scgp; TOC *toc;{ unsigned i; unsigned tracks; /* first read the first and last track number */ /* READTOC, MSF format flag, res, res, res, res, Start track, len msb, len lsb, flags */ 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.res6 = 1; /* start track */ g1_cdblen(&scmd->cdb.g1_cdb, 4); if (scgp->verbose) fprintf(stderr, "\nRead TOC size (standard)..."); /* do the scsi cmd (read table of contents) */ scgp->cmdname = "read toc size"; if (scsicmd(scgp) < 0) FatalError ("Read TOC size failed.\n"); tracks = ((bufferTOC [3] ) - bufferTOC [2] + 2) ; if (tracks > MAXTRK) return 0; if (tracks == 0) return 0; fillbytes((caddr_t)scmd, sizeof(*scmd), '\0'); scmd->addr = (caddr_t)bufferTOC; scmd->size = 4 + tracks * 8; 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.res = 1; /* MSF format */ scmd->cdb.g1_cdb.res6 = 1; /* start track */ g1_cdblen(&scmd->cdb.g1_cdb, 4 + tracks * 8); if (scgp->verbose) fprintf(stderr, "\nRead TOC tracks (standard MSF)..."); /* do the scsi cmd (read table of contents) */ scgp->cmdname = "read toc tracks "; if (scsicmd(scgp) < 0) { /* fallback to LBA format for cd burners like Philips CD-522 */ fillbytes((caddr_t)scmd, sizeof(*scmd), '\0'); scmd->addr = (caddr_t)bufferTOC; scmd->size = 4 + tracks * 8; 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.res = 0; /* LBA format */ scmd->cdb.g1_cdb.res6 = 1; /* start track */ g1_cdblen(&scmd->cdb.g1_cdb, 4 + tracks * 8); if (scgp->verbose) fprintf(stderr, "\nRead TOC tracks (standard LBA)..."); /* do the scsi cmd (read table of contents) */ scgp->cmdname = "read toc tracks "; if (scsicmd(scgp) < 0) { FatalError ("Read TOC tracks failed.\n"); } for (i = 0; i < tracks; i++) { memcpy (&toc[i], bufferTOC + 4 + 8*i, 8); toc[i].ISRC[0] = 0; toc[i].dwStartSector = be32_to_cpu(toc[i].dwStartSector); if ( toc [i].bTrack != i+1 ) toc [i].bTrack = i+1; } } else { /* copy to our structure and convert start sector */ for (i = 0; i < tracks; i++) { memcpy (&toc[i], bufferTOC + 4 + 8*i, 8); toc[i].ISRC[0] = 0; toc[i].dwStartSector = -150 + 75*60* bufferTOC[4 + 8*i + 5]+ 75* bufferTOC[4 + 8*i + 6]+ bufferTOC[4 + 8*i + 7]; if ( toc [i].bTrack != i+1 ) toc [i].bTrack = i+1; } } return --tracks; /* without lead-out */}/* ---------------- Read methods ------------------------------ *//* Read max. SectorBurst of cdda sectors to buffer via standard SCSI-2 Read(10) command */void ReadStandard (scgp, p, lSector, SectorBurstVal ) SCSI *scgp; UINT4 *p; unsigned lSector; unsigned SectorBurstVal;{ /* READ10, flags, block1 msb, block2, block3, block4 lsb, reserved, transfer len msb, transfer len lsb, block addressing mode */ register struct scg_cmd *scmd = scgp->scmd; fillbytes((caddr_t)scmd, sizeof(*scmd), '\0'); scmd->addr = (caddr_t)p; scmd->size = SectorBurstVal*CD_FRAMESIZE_RAW; 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 = 0x28; /* read 10 command */ scmd->cdb.g1_cdb.lun = scgp->lun; scmd->cdb.g1_cdb.res |= (accepts_fua_bit == 1 ? 1 << 2 : 0); g1_cdbaddr(&scmd->cdb.g1_cdb, lSector); g1_cdblen(&scmd->cdb.g1_cdb, SectorBurstVal); if (scgp->verbose) fprintf(stderr, "\nReadStandard10 CDDA..."); scgp->cmdname = "ReadStandard10"; if (scsicmd(scgp) < 0) FatalError ("Read CD-ROM10 failed\n");}/* Read max. SectorBurst of cdda sectors to buffer via vendor-specific ReadCdda(10) command */void ReadCdda10 (scgp, p, lSector, SectorBurstVal ) SCSI *scgp; UINT4 *p; unsigned lSector; unsigned SectorBurstVal;{ /* READ10, flags, block1 msb, block2, block3, block4 lsb, reserved, transfer len msb, transfer len lsb, block addressing mode */ register struct scg_cmd *scmd = scgp->scmd; fillbytes((caddr_t)scmd, sizeof(*scmd), '\0'); scmd->addr = (caddr_t)p; scmd->size = SectorBurstVal*CD_FRAMESIZE_RAW; 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 = 0xd4; /* Read audio command */ scmd->cdb.g1_cdb.lun = scgp->lun; scmd->cdb.g1_cdb.res |= (accepts_fua_bit == 1 ? 1 << 2 : 0); g1_cdbaddr(&scmd->cdb.g1_cdb, lSector); g1_cdblen(&scmd->cdb.g1_cdb, SectorBurstVal); if (scgp->verbose) fprintf(stderr, "\nReadNEC10 CDDA..."); scgp->cmdname = "Read10 NEC"; if (scsicmd(scgp) < 0) FatalError ("Read CD-ROM10 (NEC) failed\n");}/* Read max. SectorBurst of cdda sectors to buffer via vendor-specific ReadCdda(12) command */void ReadCdda12 (scgp, p, lSector, SectorBurstVal ) SCSI *scgp; UINT4 *p; unsigned lSector; unsigned SectorBurstVal;{ register struct scg_cmd *scmd = scgp->scmd; fillbytes((caddr_t)scmd, sizeof(*scmd), '\0'); scmd->addr = (caddr_t)p; scmd->size = SectorBurstVal*CD_FRAMESIZE_RAW; scmd->flags = SCG_RECV_DATA|SCG_DISRE_ENA; scmd->cdb_len = SC_G5_CDBLEN; scmd->sense_len = CCS_SENSE_LEN; scmd->target = scgp->target; scmd->cdb.g5_cdb.cmd = 0xd8; /* read audio command */ scmd->cdb.g5_cdb.lun = scgp->lun; scmd->cdb.g5_cdb.res |= (accepts_fua_bit == 1 ? 1 << 2 : 0); g5_cdbaddr(&scmd->cdb.g5_cdb, lSector); g5_cdblen(&scmd->cdb.g5_cdb, SectorBurstVal); if (scgp->verbose) fprintf(stderr, "\nReadSony12 CDDA..."); scgp->cmdname = "Read12"; if (scsicmd(scgp) < 0) FatalError ("Read CD-ROM12 failed\n");}/* Read max. SectorBurst of cdda sectors to buffer via vendor-specific ReadCdda(12) command *//*> It uses a 12 Byte CDB with 0xd4 as opcode, the start sector is coded as> normal and the number of sectors is coded in Byte 8 and 9 (begining with 0).*/void ReadCdda12Matsushita (scgp, p, lSector, SectorBurstVal ) SCSI *scgp; UINT4 *p; unsigned lSector; unsigned SectorBurstVal;{ register struct scg_cmd *scmd = scgp->scmd; fillbytes((caddr_t)scmd, sizeof(*scmd), '\0'); scmd->addr = (caddr_t)p; scmd->size = SectorBurstVal*CD_FRAMESIZE_RAW; scmd->flags = SCG_RECV_DATA|SCG_DISRE_ENA; scmd->cdb_len = SC_G5_CDBLEN; scmd->sense_len = CCS_SENSE_LEN; scmd->target = scgp->target; scmd->cdb.g5_cdb.cmd = 0xd4; /* read audio command */ scmd->cdb.g5_cdb.lun = scgp->lun; scmd->cdb.g5_cdb.res |= (accepts_fua_bit == 1 ? 1 << 2 : 0); g5_cdbaddr(&scmd->cdb.g5_cdb, lSector); g5_cdblen(&scmd->cdb.g5_cdb, SectorBurstVal); if (scgp->verbose) fprintf(stderr, "\nReadMatsushita12 CDDA..."); scgp->cmdname = "Read12Matsushita"; if (scsicmd(scgp) < 0) FatalError ("Read CD-ROM12 (Matsushita) failed\n");}/* Read max. SectorBurst of cdda sectors to buffer via MMC standard READ CD command */void ReadCddaMMC12 (scgp, p, lSector, SectorBurstVal ) SCSI *scgp; UINT4 *p; unsigned lSector; unsigned SectorBurstVal;{ register struct scg_cmd *scmd; int i; for (i = 5; i > 0; i--) { scmd = scgp->scmd; fillbytes((caddr_t)scmd, sizeof(*scmd), '\0'); scmd->addr = (caddr_t)p; scmd->size = SectorBurstVal*CD_FRAMESIZE_RAW; scmd->flags = SCG_RECV_DATA|SCG_DISRE_ENA; scmd->cdb_len = SC_G5_CDBLEN; scmd->sense_len = CCS_SENSE_LEN; scmd->target = scgp->target; scmd->cdb.g5_cdb.cmd = 0xbe; /* read cd command */ scmd->cdb.g5_cdb.lun = scgp->lun; scmd->cdb.g5_cdb.res = 1 << 1; /* expected sector type field CDDA */ g5_cdbaddr(&scmd->cdb.g5_cdb, lSector); g5x_cdblen(&scmd->cdb.g5_cdb, SectorBurstVal); scmd->cdb.g5_cdb.count[3] = 1 << 4; /* User data */ if (scgp->verbose) fprintf(stderr, "\nReadMMC12 CDDA..."); scgp->cmdname = "ReadCD MMC 12"; if (scsicmd(scgp) >= 0) break; } if (i == 0) FatalError("ReadCD MMC 12 failed");}/* Read the Sub-Q-Channel to SubQbuffer. This is the method for * drives that do not support subchannel parameters. */#ifdef PROTOTYPESstatic subq_chnl *ReadSubQFallback (SCSI *scgp, unsigned char sq_format, unsigned char track)#elsestatic subq_chnl *ReadSubQFallback ( scgp, sq_format, track ) SCSI *scgp; unsigned char sq_format; unsigned char track;#endif{ register struct scg_cmd *scmd = scgp->scmd; fillbytes((caddr_t)scmd, sizeof(*scmd), '\0'); scmd->addr = (caddr_t)SubQbuffer; scmd->size = 24; 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; /* Read SubQChannel */ /* use LBA */ scmd->cdb.g1_cdb.lun = scgp->lun; scmd->cdb.g1_cdb.addr[0] = 0x40; /* SubQ info */ scmd->cdb.g1_cdb.addr[1] = 0; /* parameter list: all */ scmd->cdb.g1_cdb.res6 = track; /* track number */ g1_cdblen(&scmd->cdb.g1_cdb, 24); if (scgp->verbose) fprintf(stderr, "\nRead Subchannel_dumb..."); scgp->cmdname = "Read Subchannel_dumb"; if (scsicmd(scgp) < 0) { fprintf( stderr, "Read SubQ failed\n"); } /* check, if the requested format is delivered */ { unsigned char *p = (unsigned char *) SubQbuffer; if ((((unsigned)p[2] << 8) | p[3]) /* LENGTH */ > ULONG_C(11) && (p[5] >> 4) /* ADR */ == sq_format) { return SubQbuffer; } } /* FIXME: we might actively search for the requested info ... */ return NULL;}/* Read the Sub-Q-Channel to SubQbuffer */#ifdef PROTOTYPESsubq_chnl *ReadSubQSCSI (SCSI *scgp, unsigned char sq_format, unsigned char track)#elsesubq_chnl *ReadSubQSCSI ( scgp, sq_format, track ) SCSI *scgp; unsigned char sq_format; unsigned char track;#endif{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -