drv_mmc.c

来自「刻录光盘的程序」· C语言 代码 · 共 1,299 行 · 第 1/3 页

C
1,299
字号
}#endif	/* PRINT_ATIP */LOCAL intgetdisktype_mmc(scgp, dp, dsp)	SCSI	*scgp;	cdr_t	*dp;	dstat_t	*dsp;{extern	char	*buf;	struct disk_info *dip;	u_char	mode[0x100];	char	ans[2];	msf_t	msf;	BOOL	did_atip = FALSE;	BOOL	did_dummy = FALSE;	msf.msf_min = msf.msf_sec = msf.msf_frame = 0;#ifdef	PRINT_ATIP	/*	 * It seems that there are drives that do not support to	 * read ATIP (e.g. HP 7100)	 * Also if a NON CD-R media is inserted, this will never work.	 * For this reason, make a failure non-fatal.	 */	scgp->silent++;	if (get_atip(scgp, (struct atipinfo *)mode) >= 0) {		msf.msf_min =		mode[8];		msf.msf_sec =		mode[9];		msf.msf_frame =		mode[10];		did_atip = TRUE;		if (lverbose) {			print_atip(scgp, (struct atipinfo *)mode);			pr_manufacturer(&msf,				((struct atipinfo *)mode)->desc.erasable,				((struct atipinfo *)mode)->desc.uru);		}	}	scgp->silent--;#endifagain:	dip = (struct disk_info *)buf;	if (get_diskinfo(scgp, dip) < 0)		return (-1);	/*	 * Check for non writable disk first.	 */	if (dip->disk_status == DS_COMPLETE && dsp->ds_cdrflags & RF_WRITE) {		if (!did_dummy) {			int	xspeed = 0xFFFF;			/*			 * Try to clear the dummy bit to reset the virtual			 * drive status. Not all drives support it even though			 * it is mentioned in the MMC standard.			 */			if (lverbose)				printf("Trying to clear drive status.\n");			speed_select_mmc(scgp, &xspeed, FALSE);			did_dummy = TRUE;			goto again;		}		errmsgno(EX_BAD, "Drive needs to reload the media to return to proper status.\n");		unload_media(scgp, dp, F_EJECT);		if ((dp->cdr_flags & CDR_TRAYLOAD) != 0) {			scgp->silent++;			load_media(scgp, dp, FALSE);			scgp->silent--;		}		scgp->silent++;		if (((dp->cdr_flags & CDR_TRAYLOAD) == 0) ||				!wait_unit_ready(scgp, 5)) {			scgp->silent--;			printf("Re-load disk and hit <CR>");			if (isgui)				printf("\n");			flush();			getline(ans, 1);		} else {			scgp->silent--;		}		load_media(scgp, dp, TRUE);	}	if (get_diskinfo(scgp, dip) < 0)		return (-1);	di_to_dstat(dip, dsp);	if (!did_atip && dsp->ds_first_leadin < 0)		lba_to_msf(dsp->ds_first_leadin, &msf);	if (lverbose && !did_atip) {		print_min_atip(dsp->ds_first_leadin, dsp->ds_last_leadout);		if (dsp->ds_first_leadin < 0)	                pr_manufacturer(&msf,				dip->erasable,				dip->uru);	}	dsp->ds_maxrblocks = disk_rcap(&msf, dsp->ds_maxblocks,				dip->erasable,				dip->uru);#ifdef	PRINT_ATIP#ifdef	DEBUG	if (get_atip(scgp, (struct atipinfo *)mode) < 0)		return (-1);	/*	 * Get pma gibt 膔ger mit CW-7502	 * Wenn Die Disk leer ist, dann stuerzt alles ab.	 * Firmware 4.02 kann nicht get_pma	 */	if (dip->disk_status != DS_EMPTY) {/*		get_pma();*/	}	printf("ATIP lead in:  %ld (%02d:%02d/%02d)\n",		msf_to_lba(mode[8], mode[9], mode[10]),		mode[8], mode[9], mode[10]);	printf("ATIP lead out: %ld (%02d:%02d/%02d)\n",		msf_to_lba(mode[12], mode[13], mode[14]),		mode[12], mode[13], mode[14]);	print_di(dip);	print_atip(scgp, (struct atipinfo *)mode);#endif#endif	/* PRINT_ATIP */	return (drive_getdisktype(scgp, 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_4_byte(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_4_byte(dip->disk_barcode),			a_to_u_4_byte(&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(scgp, atp)	SCSI		*scgp;	struct atipinfo *atp;{	if (scgp->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);/*	printf("  Disk application code: %d\n", atp->desc.res5_05);*/	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(scgp, speedp, dummy)	SCSI	*scgp;	int	*speedp;	int	dummy;{	u_char	mode[0x100];	int	len;	struct	cd_mode_page_05 *mp;	int	val;	if (speedp)		curspeed = *speedp;	fillbytes((caddr_t)mode, sizeof(mode), '\0');	if (!get_mode_params(scgp, 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(scgp, "CD write parameter", mode, len, 0, -1))		return (-1);	if (speedp == 0)		return (0);/*	if (scsi_set_speed(-1, curspeed*176) < 0)*/	/*	 * 44100 * 2 * 2 =  176400 bytes/s	 *	 * The right formula would be:	 * tmp = (((long)curspeed) * 1764) / 10;	 *	 * But the standard is rounding the wrong way.	 * Furtunately rounding down is guaranteed.	 */	if (scsi_set_speed(scgp, -1, curspeed*177) < 0)		return (-1);	if (scsi_get_speed(scgp, 0, &val) >= 0) {		curspeed = val / 176;		*speedp = curspeed;	}	return (0);}LOCAL intnext_wr_addr_mmc(scgp, track, trackp, ap)	SCSI	*scgp;	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)) {		scgp->silent++;		result = read_track_info(scgp, (caddr_t)&track_info, track,							sizeof(track_info));		scgp->silent--;	}	if (result < 0) {		if (read_track_info(scgp, (caddr_t)&track_info, 0xFF,						sizeof(track_info)) < 0)		return (-1);	}	if (scgp->verbose)		scsiprbytes("track info:", (u_char *)&track_info,				sizeof(track_info)-scsigetresid(scgp));	next_addr = a_to_4_byte(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(scgp, dp, track, trackp)	SCSI	*scgp;	cdr_t	*dp;	int	track;	track_t *trackp;{	u_char	mode[0x100];	int	len;	struct	cd_mode_page_05 *mp;	if (!is_tao(trackp)) {		if (trackp->pregapsize > 0 && (trackp->flags & TI_PREGAP) == 0) {			if (lverbose) {				printf("Writing pregap for track %d at %ld\n",					track,					trackp->trackstart-trackp->pregapsize);			}			pad_track(scgp, dp, track, trackp,				trackp->trackstart-trackp->pregapsize,				trackp->pregapsize*trackp->secsize,					FALSE, 0);		}		return (0);	}	fillbytes((caddr_t)mode, sizeof(mode), '\0');	if (!get_mode_params(scgp, 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);	}	if (trackp->isrc) {		mp->ISRC[0] = 0x80;	/* Set ISRC valid */		strncpy((char *)&mp->ISRC[1], trackp->isrc, 12);	} else {		fillbytes(&mp->ISRC[0], sizeof(mp->ISRC), '\0');	}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?