📄 drv_mmc.c
字号:
print_atip((struct atipinfo *)mode);#endif#endif /* PRINT_ATIP */ return (drive_getdisktype(dp, dsp));}#ifdef PRINT_ATIP#define DOES(what,flag) printf(" Does %s%s\n", flag?"":"not ",what);#define IS(what,flag) printf(" Is %s%s\n", flag?"":"not ",what);#define VAL(what,val) printf(" %s: %d\n", what, val[0]*256 + val[1]);#define SVAL(what,val) printf(" %s: %s\n", what, val);voidprint_di(dip) struct disk_info *dip;{static char *ds_name[] = { "empty", "incomplete/appendable", "complete", "illegal" };static char *ss_name[] = { "empty", "incomplete/appendable", "illegal", "complete", }; IS("erasable", dip->erasable); printf("disk status: %s\n", ds_name[dip->disk_status]); printf("session status: %s\n", ss_name[dip->sess_status]); printf("first track: %d number of sessions: %d first track in last sess: %d last track in last sess: %d\n", dip->first_track, dip->numsess, dip->first_track_ls, dip->last_track_ls); IS("unrestricted", dip->uru); printf("Disk type: "); switch (dip->disk_type) { case SES_DA_ROM: printf("CD-DA or CD-ROM"); break; case SES_CDI: printf("CDI"); break; case SES_XA: printf("CD-ROM XA"); break; case SES_UNDEF: printf("undefined"); break; default: printf("reserved"); break; } printf("\n"); if (dip->did_v) printf("Disk id: 0x%lX\n", a_to_u_long(dip->disk_id)); printf("last start of lead in: %ld\n", msf_to_lba(dip->last_lead_in[1], dip->last_lead_in[2], dip->last_lead_in[3])); printf("last start of lead out: %ld\n", msf_to_lba(dip->last_lead_out[1], dip->last_lead_out[2], dip->last_lead_out[3])); if (dip->dbc_v) printf("Disk bar code: 0x%lX%lX\n", a_to_u_long(dip->disk_barcode), a_to_u_long(&dip->disk_barcode[4])); if (dip->num_opc_entries > 0) { printf("OPC table:\n"); }}LOCAL char clv_to_speed[8] = { 0, 2, 4, 6, 8, 0, 0, 0};voidprint_atip(atp) struct atipinfo *atp;{ if (verbose) scsiprbytes("ATIP info: ", (Uchar *)atp, sizeof (*atp)); printf("ATIP info from disk:\n"); printf(" Indicated writing power: %d\n", atp->desc.ind_wr_power); if (atp->desc.erasable || atp->desc.ref_speed) printf(" Reference speed: %d\n", clv_to_speed[atp->desc.ref_speed]); IS("unrestricted", atp->desc.uru); IS("erasable", atp->desc.erasable); if (atp->desc.sub_type) printf(" Disk sub type: %d\n", atp->desc.sub_type); printf(" ATIP start of lead in: %ld (%02d:%02d/%02d)\n", msf_to_lba(atp->desc.lead_in[1], atp->desc.lead_in[2], atp->desc.lead_in[3]), atp->desc.lead_in[1], atp->desc.lead_in[2], atp->desc.lead_in[3]); printf(" ATIP start of lead out: %ld (%02d:%02d/%02d)\n", msf_to_lba(atp->desc.lead_out[1], atp->desc.lead_out[2], atp->desc.lead_out[3]), atp->desc.lead_out[1], atp->desc.lead_out[2], atp->desc.lead_out[3]); if (atp->desc.a1_v) { if (atp->desc.clv_low != 0 || atp->desc.clv_high != 0) printf(" speed low: %d speed high: %d\n", clv_to_speed[atp->desc.clv_low], clv_to_speed[atp->desc.clv_high]); printf(" power mult factor: %d %d\n", atp->desc.power_mult, atp->desc.tgt_y_pow); if (atp->desc.erasable) printf(" recommended erase/write power: %d\n", atp->desc.rerase_pwr_ratio); } if (atp->desc.a2_v) { printf(" A2 values: %02X %02X %02X\n", atp->desc.a2[0], atp->desc.a2[1], atp->desc.a2[2]); } if (atp->desc.a3_v) { printf(" A3 values: %02X %02X %02X\n", atp->desc.a3[0], atp->desc.a3[1], atp->desc.a3[2]); }}#endif /* PRINT_ATIP */LOCAL intspeed_select_mmc(speed, dummy) int speed; int dummy;{ u_char mode[0x100]; int len; struct cd_mode_page_05 *mp; curspeed = speed; fillbytes((caddr_t)mode, sizeof(mode), '\0'); if (!get_mode_params(0x05, "CD write parameter", mode, (u_char *)0, (u_char *)0, (u_char *)0, &len)) return (-1); if (len == 0) return (-1); mp = (struct cd_mode_page_05 *) (mode + sizeof(struct scsi_mode_header) + ((struct scsi_mode_header *)mode)->blockdesc_len);#ifdef DEBUG scsiprbytes("CD write parameter:", (u_char *)mode, len);#endif mp->test_write = dummy != 0; /* * Set default values: * Write type = 01 (track at once) * Track mode = 04 (CD-ROM) * Data block type = 08 (CD-ROM) * Session format = 00 (CD-ROM) */ mp->write_type = WT_TAO; mp->track_mode = TM_DATA; mp->dbtype = DB_ROM_MODE1; mp->session_format = SES_DA_ROM;/* Matsushita has illegal def. value */#ifdef DEBUG scsiprbytes("CD write parameter:", (u_char *)mode, len);#endif if (!set_mode_params("CD write parameter", mode, len, 0, -1)) return (-1);/*XXX max speed aus page 0x2A lesen !! *//* if (scsi_set_speed(-1, speed*176) < 0)*/ /* * 44100 * 2 * 2 = 176400 bytes/s * * The right formula would be: * tmp = (((long)speed) * 1764) / 10; * * But the standard is rounding the wrong way. * Furtunately rounding down is guaranteed. */ if (scsi_set_speed(-1, speed*177) < 0) return (-1); return (0);}LOCAL intnext_wr_addr_mmc(track, trackp, ap) int track; track_t *trackp; long *ap;{ struct track_info track_info; long next_addr; int result = -1; /* * Reading info for current track may require doing the read_track_info * with either the track number (if the track is currently being written) * or with 0xFF (if the track hasn't been started yet and is invisible */ if (track > 0 && is_packet(trackp)) { silent ++; result = read_track_info((caddr_t)&track_info, track, sizeof(track_info)); silent --; } if (result < 0) { if (read_track_info((caddr_t)&track_info, 0xFF, sizeof(track_info)) < 0) return (-1); } if (verbose) scsiprbytes("track info:", (u_char *)&track_info, sizeof(track_info)-scsigetresid()); next_addr = a_to_u_long(track_info.next_writable_addr); if (ap) *ap = next_addr; return (0);}int st2mode[] = { 0, /* 0 */ TM_DATA, /* 1 ST_ROM_MODE1 */ TM_DATA, /* 2 ST_ROM_MODE2 */ 0, /* 3 */ 0, /* 4 ST_AUDIO_NOPRE */ TM_PREEM, /* 5 ST_AUDIO_PRE */ 0, /* 6 */ 0, /* 7 */};LOCAL intopen_track_mmc(dp, track, trackp) cdr_t *dp; int track; track_t *trackp;{ u_char mode[0x100]; int len; struct cd_mode_page_05 *mp; fillbytes((caddr_t)mode, sizeof(mode), '\0'); if (!get_mode_params(0x05, "CD write parameter", mode, (u_char *)0, (u_char *)0, (u_char *)0, &len)) return (-1); if (len == 0) return (-1); mp = (struct cd_mode_page_05 *) (mode + sizeof(struct scsi_mode_header) + ((struct scsi_mode_header *)mode)->blockdesc_len);/* mp->track_mode = ???;*/ mp->track_mode = st2mode[trackp->sectype & ST_MASK];/* mp->copy = ???;*/ mp->dbtype = trackp->dbtype;/*i_to_short(mp->audio_pause_len, 300);*//*i_to_short(mp->audio_pause_len, 150);*//*i_to_short(mp->audio_pause_len, 0);*/ if (is_packet(trackp)) { mp->write_type = WT_PACKET; mp->track_mode |= TM_INCREMENTAL; mp->fp = (trackp->pktsize > 0) ? 1 : 0; i_to_4_byte(mp->packet_size, trackp->pktsize); } else { mp->write_type = WT_TAO; mp->fp = 0; i_to_4_byte(mp->packet_size, 0); } #ifdef DEBUG scsiprbytes("CD write parameter:", (u_char *)mode, len);#endif if (!set_mode_params("CD write parameter", mode, len, 0, trackp->secsize)) return (-1); return (0);}LOCAL intclose_track_mmc(track, trackp) int track; track_t *trackp;{ int ret; if (scsi_flush_cache() < 0) { printf("Trouble flushing the cache\n"); return -1; } wait_unit_ready(300); /* XXX Wait for ATAPI */ if (is_packet(trackp) && !is_noclose(trackp)) { /* close the incomplete track */ ret = scsi_close_tr_session(1, 0xFF); wait_unit_ready(300); /* XXX Wait for ATAPI */ return (ret); } return (0);}int toc2sess[] = { SES_DA_ROM, /* CD-DA */ SES_DA_ROM, /* CD-ROM */ SES_XA, /* CD-ROM XA mode 1 */ SES_XA, /* CD-ROM XA MODE 2 */ SES_CDI, /* CDI */ SES_DA_ROM, /* Invalid - use default */ SES_DA_ROM, /* Invalid - use default */};LOCAL intopen_session_mmc(tracks, trackp, toctype, multi) int tracks; track_t *trackp; int toctype; int multi;{ u_char mode[0x100]; int len; struct cd_mode_page_05 *mp; fillbytes((caddr_t)mode, sizeof(mode), '\0'); if (!get_mode_params(0x05, "CD write parameter", mode, (u_char *)0, (u_char *)0, (u_char *)0, &len)) return (-1); if (len == 0) return (-1); mp = (struct cd_mode_page_05 *) (mode + sizeof(struct scsi_mode_header) + ((struct scsi_mode_header *)mode)->blockdesc_len); mp->write_type = WT_TAO; /* fix to allow DAO later */ mp->multi_session = (multi != 0) ? MS_MULTI : MS_NONE; mp->session_format = toc2sess[toctype & TOC_MASK];#ifdef DEBUG scsiprbytes("CD write parameter:", (u_char *)mode, len);#endif if (!set_mode_params("CD write parameter", mode, len, 0, -1)) return (-1); return (0);}LOCAL intwaitfix_mmc(secs) int secs;{ char dibuf[16]; int i; int key;#define W_SLEEP 2 silent++; for (i = 0; i < secs/W_SLEEP; i++) { if (read_disk_info(dibuf, sizeof(dibuf)) >= 0) { silent--; return (0); } key = scsi_sense_key(); if (key != SC_UNIT_ATTENTION && key != SC_NOT_READY) break; sleep(W_SLEEP); } silent--; return (-1);#undef W_SLEEP}LOCAL intfixate_mmc(onp, dummy, toctype, tracks, trackp) int onp; int dummy; int toctype; int tracks; track_t *trackp;{ int ret; int key; int code; struct timeval starttime; struct timeval stoptime; starttime.tv_sec = 0; starttime.tv_usec = 0; stoptime = starttime; gettimeofday(&starttime, (struct timezone *)0); if (dummy && lverbose) printf("WARNING: Some drives don't like fixation in dummy mode.\n"); silent++; ret = scsi_close_tr_session(2, 0); silent--; key = scsi_sense_key(); code = scsi_sense_code(); if (ret >= 0) { wait_unit_ready(420/curspeed); /* XXX Wait for ATAPI */ waitfix_mmc(420/curspeed); /* XXX Wait for ATAPI */ return (ret); } if ((dummy != 0 && (key != SC_ILLEGAL_REQUEST)) || /* * Try to suppress messages from drives that don't like fixation * in -dummy mode. */ ((dummy == 0) && ((key != SC_UNIT_ATTENTION) || (code != 0x2E) || (strncmp(inq.vendor_info, "MITSUMI", 7) != 0)))) { /* * UNIT ATTENTION/2E seems to be a magic for Mitsumi ATAPI drives * when returning early from fixating. * Try to supress the error message in this case to make * simple minded users less confused. */ scsiprinterr("close track/session"); scsiprintresult(); /* XXX restore key/code in future */ } wait_unit_ready(420); /* XXX Wait for ATAPI */ waitfix_mmc(420/curspeed); /* XXX Wait for ATAPI */ if (!dummy && (ret >= 0 || (key == SC_UNIT_ATTENTION && code == 0x2E))) { /* * Some ATAPI drives (e.g. Mitsumi) imply the * IMMED bit in the SCSI cdb. As there seems to be no * way to properly check for the real end of the * fixating process we wait for the expected time. */ gettimeofday(&stoptime, (struct timezone *)0); timevaldiff(&starttime, &stoptime); if (stoptime.tv_sec < (220 / curspeed)) { unsigned secs; if (lverbose) { printf("Actual fixating time: %ld seconds\n", (long)stoptime.tv_sec); } secs = (280 / curspeed) - stoptime.tv_sec; if (lverbose) { printf("ATAPI early return: sleeping %d seconds.\n", secs); } sleep(secs); } } return (ret);}char *blank_types[] = { "entire disk", "PMA, TOC, pregap", "incomplete track", "reserved track", "tail of track", "closing of last session", "last session", "reserved blanking type",};LOCAL intblank_mmc(addr, blanktype) long addr; int blanktype;{ BOOL cdrr = FALSE; /* Read CD-R */ BOOL cdwr = FALSE; /* Write CD-R */ BOOL cdrrw = FALSE; /* Read CD-RW */ BOOL cdwrw = FALSE; /* Write CD-RW */ mmc_check(&cdrr, &cdwr, &cdrrw, &cdwrw, NULL); if (!cdwrw) return (blank_dummy(addr, blanktype)); if (lverbose) printf("Blanking %s\n", blank_types[blanktype & 0x07]); return (scsi_blank(addr, blanktype));}LOCAL intscsi_sony_write(bp, sectaddr, size, blocks, islast) caddr_t bp; /* address of buffer */ long sectaddr; /* disk address (sector) to put */ long size; /* number of bytes to transfer */ int blocks; /* sector count */ BOOL islast; /* last write for track */{ return (write_xg5(bp, sectaddr, size, blocks));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -