📄 scsi_cdr.c
字号:
scgp->cmdname = "blank unit"; return (scsicmd(scgp));}/* * XXX First try to handle ATAPI: * XXX ATAPI cannot handle SCSI 6 byte commands. * XXX We try to simulate 6 byte mode sense/select. */LOCAL BOOL is_atapi;EXPORT BOOLallow_atapi(scgp, new) SCSI *scgp; BOOL new;{ BOOL old = is_atapi; Uchar mode[256]; if (new == old) return (old); scgp->silent++; if (new && mode_sense_g1(scgp, mode, 8, 0x3F, 0) < 0) { /* All pages current */ new = FALSE; } scgp->silent--; is_atapi = new; return (old);}EXPORT intmode_select(scgp, dp, cnt, smp, pf) SCSI *scgp; Uchar *dp; int cnt; int smp; int pf;{ if (is_atapi) return (mode_select_sg0(scgp, dp, cnt, smp, pf)); return (mode_select_g0(scgp, dp, cnt, smp, pf));}EXPORT intmode_sense(scgp, dp, cnt, page, pcf) SCSI *scgp; Uchar *dp; int cnt; int page; int pcf;{ if (is_atapi) return (mode_sense_sg0(scgp, dp, cnt, page, pcf)); return (mode_sense_g0(scgp, dp, cnt, page, pcf));}/* * Simulate mode select g0 with mode select g1. */EXPORT intmode_select_sg0(scgp, dp, cnt, smp, pf) SCSI *scgp; Uchar *dp; int cnt; int smp; int pf;{ Uchar xmode[256+4]; int amt = cnt; if (amt < 1 || amt > 255) { /* XXX clear SCSI error codes ??? */ return (-1); } if (amt < 4) { /* Data length. medium type & VU */ amt += 1; } else { amt += 4; movebytes(&dp[4], &xmode[8], cnt-4); } xmode[0] = 0; xmode[1] = 0; xmode[2] = dp[1]; xmode[3] = dp[2]; xmode[4] = 0; xmode[5] = 0; i_to_2_byte(&xmode[6], (unsigned int)dp[3]); if (scgp->verbose) scsiprbytes("Mode Parameters (un-converted)", dp, cnt); return (mode_select_g1(scgp, xmode, amt, smp, pf));}/* * Simulate mode sense g0 with mode sense g1. */EXPORT intmode_sense_sg0(scgp, dp, cnt, page, pcf) SCSI *scgp; Uchar *dp; int cnt; int page; int pcf;{ Uchar xmode[256+4]; int amt = cnt; int len; if (amt < 1 || amt > 255) { /* XXX clear SCSI error codes ??? */ return (-1); } fillbytes((caddr_t)xmode, sizeof(xmode), '\0'); if (amt < 4) { /* Data length. medium type & VU */ amt += 1; } else { amt += 4; } if (mode_sense_g1(scgp, xmode, amt, page, pcf) < 0) return (-1); amt = cnt - scsigetresid(scgp);/* * For tests: Solaris 8 & LG CD-ROM always returns resid == amt *//* amt = cnt;*/ if (amt > 4) movebytes(&xmode[8], &dp[4], amt-4); len = a_to_u_2_byte(xmode); if (len == 0) { dp[0] = 0; } else if (len < 6) { if (len > 2) len = 2; dp[0] = len; } else { dp[0] = len - 3; } dp[1] = xmode[2]; dp[2] = xmode[3]; len = a_to_u_2_byte(&xmode[6]); dp[3] = len; if (scgp->verbose) scsiprbytes("Mode Sense Data (converted)", dp, amt); return (0);}EXPORT intmode_select_g0(scgp, dp, cnt, smp, pf) SCSI *scgp; Uchar *dp; int cnt; int smp; int pf;{ register struct scg_cmd *scmd = scgp->scmd; fillbytes((caddr_t)scmd, sizeof(*scmd), '\0'); scmd->addr = (caddr_t)dp; scmd->size = cnt; 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 = SC_MODE_SELECT; scmd->cdb.g0_cdb.lun = scgp->lun; scmd->cdb.g0_cdb.high_addr = smp ? 1 : 0 | pf ? 0x10 : 0; scmd->cdb.g0_cdb.count = cnt; if (scgp->verbose) { printf("%s ", smp?"Save":"Set "); scsiprbytes("Mode Parameters", dp, cnt); } scgp->cmdname = "mode select g0"; return (scsicmd(scgp));}EXPORT intmode_select_g1(scgp, dp, cnt, smp, pf) SCSI *scgp; Uchar *dp; int cnt; int smp; int pf;{ register struct scg_cmd *scmd = scgp->scmd; fillbytes((caddr_t)scmd, sizeof(*scmd), '\0'); scmd->addr = (caddr_t)dp; scmd->size = cnt; 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 = 0x55; scmd->cdb.g1_cdb.lun = scgp->lun; scmd->cdb.g0_cdb.high_addr = smp ? 1 : 0 | pf ? 0x10 : 0; g1_cdblen(&scmd->cdb.g1_cdb, cnt); if (scgp->verbose) { printf("%s ", smp?"Save":"Set "); scsiprbytes("Mode Parameters", dp, cnt); } scgp->cmdname = "mode select g1"; return (scsicmd(scgp));}EXPORT intmode_sense_g0(scgp, dp, cnt, page, pcf) SCSI *scgp; Uchar *dp; int cnt; int page; int pcf;{ register struct scg_cmd *scmd = scgp->scmd; fillbytes((caddr_t)scmd, sizeof(*scmd), '\0'); scmd->addr = (caddr_t)dp; scmd->size = 0xFF; scmd->size = cnt; 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_MODE_SENSE; scmd->cdb.g0_cdb.lun = scgp->lun;#ifdef nonono scmd->cdb.g0_cdb.high_addr = 1<<4; /* DBD Disable Block desc. */#endif scmd->cdb.g0_cdb.mid_addr = (page&0x3F) | ((pcf<<6)&0xC0); scmd->cdb.g0_cdb.count = page ? 0xFF : 24; scmd->cdb.g0_cdb.count = cnt; scgp->cmdname = "mode sense g0"; if (scsicmd(scgp) < 0) return (-1); if (scgp->verbose) scsiprbytes("Mode Sense Data", dp, cnt - scsigetresid(scgp)); return (0);}EXPORT intmode_sense_g1(scgp, dp, cnt, page, pcf) SCSI *scgp; Uchar *dp; int cnt; int page; int pcf;{ register struct scg_cmd *scmd = scgp->scmd; fillbytes((caddr_t)scmd, sizeof(*scmd), '\0'); scmd->addr = (caddr_t)dp; scmd->size = cnt; 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 = 0x5A; scmd->cdb.g1_cdb.lun = scgp->lun;#ifdef nonono scmd->cdb.g0_cdb.high_addr = 1<<4; /* DBD Disable Block desc. */#endif scmd->cdb.g1_cdb.addr[0] = (page&0x3F) | ((pcf<<6)&0xC0); g1_cdblen(&scmd->cdb.g1_cdb, cnt); scgp->cmdname = "mode sense g1"; if (scsicmd(scgp) < 0) return (-1); if (scgp->verbose) scsiprbytes("Mode Sense Data", dp, cnt - scsigetresid(scgp)); return (0);}struct tocheader { Uchar len[2]; Uchar first; Uchar last;};struct trackdesc { Uchar res0;#if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ Ucbit control : 4; Ucbit adr : 4;#else /* Motorola byteorder */ Ucbit adr : 4; Ucbit control : 4;#endif Uchar track; Uchar res3; Uchar addr[4];};struct diskinfo { struct tocheader hd; struct trackdesc desc[1];};struct siheader { Uchar len[2]; Uchar finished; Uchar unfinished;};struct sidesc { Uchar sess_number; Uchar res1; Uchar track; Uchar res3; Uchar addr[4];};struct sinfo { struct siheader hd; struct sidesc desc[1];};struct trackheader { Uchar mode; Uchar res[3]; Uchar addr[4];};#define TRM_ZERO 0#define TRM_USER_ECC 1 /* 2048 bytes user data + 288 Bytes ECC/EDC */#define TRM_USER 2 /* All user data (2336 bytes) */struct ftrackdesc { Uchar sess_number;#if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */ Ucbit control : 4; Ucbit adr : 4;#else /* Motorola byteorder */ Ucbit adr : 4; Ucbit control : 4;#endif Uchar track; Uchar point; Uchar amin; Uchar asec; Uchar aframe; Uchar res7; Uchar pmin; Uchar psec; Uchar pframe;};struct fdiskinfo { struct tocheader hd; struct ftrackdesc desc[1];};EXPORT intread_tochdr(scgp, dp, fp, lp) SCSI *scgp; cdr_t *dp; int *fp; int *lp;{ struct tocheader *tp; char xb[256]; int len; tp = (struct tocheader *)xb; fillbytes((caddr_t)xb, sizeof(xb), '\0'); if (read_toc(scgp, xb, 0, sizeof(struct tocheader), 0, FMT_TOC) < 0) { if (scgp->silent == 0) errmsgno(EX_BAD, "Cannot read TOC header\n"); return (-1); } len = a_to_u_2_byte(tp->len) + sizeof(struct tocheader)-2; if (len >= 4) { if (fp) *fp = tp->first; if (lp) *lp = tp->last; return (0); } return (-1);} EXPORT intread_cdtext(scgp) SCSI *scgp;{ struct tocheader *tp; char xb[256]; int len; char xxb[10000]; tp = (struct tocheader *)xb; fillbytes((caddr_t)xb, sizeof(xb), '\0'); if (read_toc(scgp, xb, 0, sizeof(struct tocheader), 0, FMT_CDTEXT) < 0) { if (scgp->silent == 0 || scgp->verbose > 0) errmsgno(EX_BAD, "Cannot read CD-Text header\n"); return (-1); } len = a_to_u_2_byte(tp->len) + sizeof(struct tocheader)-2; printf("CD-Text len: %d\n", len); if (read_toc(scgp, xxb, 0, len, 0, FMT_CDTEXT) < 0) { if (scgp->silent == 0) errmsgno(EX_BAD, "Cannot read CD-Text\n"); return (-1); } { FILE *f = fileopen("cdtext.dat", "wct"); filewrite(f, xxb, len); } return (0);} EXPORT intread_trackinfo(scgp, track, offp, msfp, adrp, controlp, modep) SCSI *scgp; int track; long *offp; struct msf *msfp; int *adrp; int *controlp; int *modep;{ struct diskinfo *dp; char xb[256]; int len; dp = (struct diskinfo *)xb; fillbytes((caddr_t)xb, sizeof(xb), '\0'); if (read_toc(scgp, xb, track, sizeof(struct diskinfo), 0, FMT_TOC) < 0) { if (scgp->silent <= 0) errmsgno(EX_BAD, "Cannot read TOC\n"); return (-1); } len = a_to_u_2_byte(dp->hd.len) + sizeof(struct tocheader)-2; if (len < (int)sizeof(struct diskinfo)) return (-1); if (offp) *offp = a_to_4_byte(dp->desc[0].addr); if (adrp) *adrp = dp->desc[0].adr; if (controlp) *controlp = dp->desc[0].control; if (msfp) { scgp->silent++; if (read_toc(scgp, xb, track, sizeof(struct diskinfo), 1, FMT_TOC) >= 0) { msfp->msf_min = dp->desc[0].addr[1]; msfp->msf_sec = dp->desc[0].addr[2]; msfp->msf_frame = dp->desc[0].addr[3]; } else if (read_toc(scgp, xb, track, sizeof(struct diskinfo), 0, FMT_TOC) >= 0) { /* * Some drives (e.g. the Philips CDD-522) don't support * to read the TOC in MSF mode. */ long off = a_to_4_byte(dp->desc[0].addr); lba_to_msf(off, msfp); } else { msfp->msf_min = 0; msfp->msf_sec = 0; msfp->msf_frame = 0; } scgp->silent--; } if (modep == NULL) return (0); if (track == 0xAA) { *modep = -1; return (0); } fillbytes((caddr_t)xb, sizeof(xb), '\0'); scgp->silent++; if (read_header(scgp, xb, *offp, 8, 0) >= 0) { *modep = xb[0]; } else if (read_track_info_philips(scgp, xb, track, 14) >= 0) { *modep = xb[0xb] & 0xF; } else { *modep = -1; } scgp->silent--; return (0);}EXPORT intread_B0(scgp, isbcd, b0p, lop) SCSI *scgp; BOOL isbcd; long *b0p; long *lop;{ struct fdiskinfo *dp; struct ftrackdesc *tp; char xb[8192]; char *pe; int len; long l; dp = (struct fdiskinfo *)xb; fillbytes((caddr_t)xb, sizeof(xb), '\0'); if (read_toc_philips(scgp, xb, 1, sizeof(struct tocheader), 0, FMT_FULLTOC) < 0) { return (-1); } len = a_to_u_2_byte(dp->hd.len) + sizeof(struct tocheader)-2; if (len < (int)sizeof(struct fdiskinfo)) return (-1); if (read_toc_philips(scgp, xb, 1, len, 0, FMT_FULLTOC) < 0) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -