drv_mmc.c

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

C
1,299
字号
/* @(#)drv_mmc.c	1.47 00/01/28 Copyright 1997 J. Schilling */#ifndef lintstatic	char sccsid[] =	"@(#)drv_mmc.c	1.47 00/01/28 Copyright 1997 J. Schilling";#endif/* *	CDR device implementation for *	SCSI-3/mmc conforming drives *	e.g. Yamaha CDR-400, Ricoh MP6200 * *	Copyright (c) 1997 J. Schilling *//* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; see the file COPYING.  If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. *//*#define	DEBUG*/#define	PRINT_ATIP#include <mconfig.h>#include <stdio.h>#include <standard.h>#include <fctldefs.h>#include <errno.h>#include <strdefs.h>#include <unixstd.h>#include <timedefs.h>#include <utypes.h>#include <btorder.h>#include <intcvt.h>#include <scg/scgcmd.h>#include <scg/scsidefs.h>#include <scg/scsireg.h>#include <scg/scsitransp.h>#include <scsimmc.h>#include "cdrecord.h"extern	BOOL	isgui;extern	int	debug;extern	int	lverbose;LOCAL	int	curspeed = 1;LOCAL	int	mmc_load		__PR((SCSI *scgp));LOCAL	int	mmc_unload		__PR((SCSI *scgp));LOCAL	cdr_t	*identify_mmc		__PR((SCSI *scgp, cdr_t *, struct scsi_inquiry *));LOCAL	int	attach_mmc		__PR((SCSI *scgp, cdr_t *));LOCAL	int	get_diskinfo		__PR((SCSI *scgp, struct disk_info *dip));LOCAL	void	di_to_dstat		__PR((struct disk_info *dip, dstat_t *dsp));#ifdef	PRINT_ATIPLOCAL	int	get_pma			__PR((SCSI *scgp));#endifLOCAL	int	getdisktype_mmc		__PR((SCSI *scgp, cdr_t *dp, dstat_t *dsp));LOCAL	int	speed_select_mmc	__PR((SCSI *scgp, int *speedp, int dummy));LOCAL	int	next_wr_addr_mmc	__PR((SCSI *scgp, int track, track_t *trackp, long *ap));LOCAL	int	open_track_mmc		__PR((SCSI *scgp, cdr_t *dp, int track, track_t *trackp));LOCAL	int	close_track_mmc		__PR((SCSI *scgp, int track, track_t *trackp));LOCAL	int	open_session_mmc	__PR((SCSI *scgp, int tracks, track_t *trackp, int toctype, int multi));LOCAL	int	waitfix_mmc		__PR((SCSI *scgp, int secs));LOCAL	int	fixate_mmc		__PR((SCSI *scgp, int onp, int dummy, int toctype, int tracks, track_t *trackp));LOCAL	int	blank_mmc		__PR((SCSI *scgp, long addr, int blanktype));LOCAL	int	scsi_sony_write		__PR((SCSI *scgp, caddr_t bp, long sectaddr, long size, int blocks, BOOL islast));LOCAL intmmc_load(scgp)	SCSI	*scgp;{	return (scsi_load_unload(scgp, 1));}LOCAL intmmc_unload(scgp)	SCSI	*scgp;{	return (scsi_load_unload(scgp, 0));}cdr_t	cdr_mmc = {	0,	CDR_TAO|CDR_DAO|CDR_PACKET|CDR_SWABAUDIO,	"mmc_cdr",	"generic SCSI-3/mmc CD-R driver",	0,	identify_mmc,	attach_mmc,	getdisktype_mmc,	scsi_load,/*	mmc_load,*/	scsi_unload,	read_buff_cap,	(int(*)__PR((SCSI *)))cmd_dummy,	/* recovery_needed	*/	(int(*)__PR((SCSI *, int)))cmd_dummy,	/* recover		*/	speed_select_mmc,	select_secsize,	next_wr_addr_mmc,	(int(*)__PR((SCSI *, Ulong)))cmd_ill,	/* reserve_track	*/	scsi_cdr_write,	send_cue,	open_track_mmc,	close_track_mmc,	open_session_mmc,	cmd_dummy,	read_session_offset,	fixate_mmc,	blank_mmc,};cdr_t	cdr_mmc_sony = {	0,	CDR_TAO|CDR_DAO|CDR_PACKET|CDR_SWABAUDIO,	"mmc_cdr_sony",	"generic SCSI-3/mmc CD-R driver (Sony 928 variant)",	0,	identify_mmc,	attach_mmc,	getdisktype_mmc,	scsi_load,/*	mmc_load,*/	scsi_unload,	read_buff_cap,	(int(*)__PR((SCSI *)))cmd_dummy,	/* recovery_needed	*/	(int(*)__PR((SCSI *, int)))cmd_dummy,	/* recover		*/	speed_select_mmc,	select_secsize,	next_wr_addr_mmc,	(int(*)__PR((SCSI *, Ulong)))cmd_ill,	/* reserve_track	*/	scsi_sony_write,	send_cue,	open_track_mmc,	close_track_mmc,	open_session_mmc,	cmd_dummy,	read_session_offset,	fixate_mmc,	blank_mmc,};/* * SCSI-3/mmc conformant CD drive */cdr_t	cdr_cd = {	0,	CDR_ISREADER|CDR_SWABAUDIO,	"mmc_cd",	"generic SCSI-3/mmc CD driver",	0,	identify_mmc,	attach_mmc,	drive_getdisktype,	scsi_load,	scsi_unload,	read_buff_cap,	(int(*)__PR((SCSI *)))cmd_dummy,	/* recovery_needed	*/	(int(*)__PR((SCSI *, int)))cmd_dummy,	/* recover		*/	speed_select_mmc,	select_secsize,	(int(*)__PR((SCSI *scgp, int, track_t *, long *)))cmd_ill,	/* next_wr_addr		*/	(int(*)__PR((SCSI *, Ulong)))cmd_ill,	/* reserve_track	*/	scsi_cdr_write,	no_sendcue,	open_track_mmc,	close_track_mmc,	(int(*)__PR((SCSI *scgp, int, track_t *, int, int)))cmd_dummy,	cmd_dummy,	read_session_offset,	(int(*)__PR((SCSI *scgp, int, int, int, int, track_t *)))cmd_dummy,	/* fixation */	blank_dummy,};/* * Old pre SCSI-3/mmc CD drive */cdr_t	cdr_oldcd = {	0,	CDR_ISREADER,	"scsi2_cd",	"generic SCSI-2 CD driver",	0,	identify_mmc,	drive_attach,	drive_getdisktype,	scsi_load,	scsi_unload,	buf_dummy,	(int(*)__PR((SCSI *)))cmd_dummy,	/* recovery_needed	*/	(int(*)__PR((SCSI *, int)))cmd_dummy,	/* recover		*/	speed_select_mmc,	select_secsize,	(int(*)__PR((SCSI *scg, int, track_t *, long *)))cmd_ill,	/* next_wr_addr		*/	(int(*)__PR((SCSI *, Ulong)))cmd_ill,	/* reserve_track	*/	scsi_cdr_write,	no_sendcue,	open_track_mmc,	close_track_mmc,	(int(*)__PR((SCSI *scgp, int, track_t *, int, int)))cmd_dummy,	cmd_dummy,	read_session_offset_philips,	(int(*)__PR((SCSI *scgp, int, int, int, int, track_t *)))cmd_dummy,	/* fixation */	blank_dummy,};LOCAL cdr_t *identify_mmc(scgp, dp, ip)	SCSI	*scgp;	cdr_t			*dp;	struct scsi_inquiry	*ip;{	BOOL	cdrr	 = FALSE;	/* Read CD-R	*/	BOOL	cdwr	 = FALSE;	/* Write CD-R	*/	BOOL	cdrrw	 = FALSE;	/* Read CD-RW	*/	BOOL	cdwrw	 = FALSE;	/* Write CD-RW	*/	Uchar	mode[0x100];	struct	cd_mode_page_2A *mp;	if (ip->type != INQ_WORM && ip->type != INQ_ROMD)		return ((cdr_t *)0);	allow_atapi(scgp, TRUE);/* Try to switch to 10 byte mode cmds */	scgp->silent++;	mp = mmc_cap(scgp, mode);	/* Get MMC capabilities */	scgp->silent--;	if (mp == NULL)		return (&cdr_oldcd);	/* Pre SCSI-3/mmc drive	 	*/	mmc_getval(mp, &cdrr, &cdwr, &cdrrw, &cdwrw, NULL);	/*	 * At this point we know that we have a SCSI-3/mmc compliant drive.	 * Unfortunately ATAPI drives violate the SCSI spec in returning	 * a response data format of '1' which from the SCSI spec would	 * tell us not to use the "PF" bit in mode select. As ATAPI drives	 * require the "PF" bit to be set, we 'correct' the inquiry data.	 *	 * XXX xxx_identify() should not have any side_effects ??	 */	if (ip->data_format < 2)		ip->data_format = 2;	if (strncmp(ip->vendor_info, "SONY", 4) == 0 &&	    strncmp(ip->prod_ident, "CD-R   CDU928E", 14) == 0) {		dp = &cdr_mmc_sony;	}	if (!cdwr)			/* SCSI-3/mmc CD drive		*/		dp = &cdr_cd;	return (dp);}LOCAL intattach_mmc(scgp, dp)	SCSI	*scgp;	cdr_t			*dp;{	struct	cd_mode_page_2A *mp;	allow_atapi(scgp, TRUE);/* Try to switch to 10 byte mode cmds */	scgp->silent++;	mp = mmc_cap(scgp, NULL);/* Get MMC capabilities in allocated mp */	scgp->silent--;	if (mp == NULL)		return (-1);	/* Pre SCSI-3/mmc drive	 	*/	dp->cdr_cdcap = mp;	/* Store MMC cap pointer	*/	if (mp->loading_type == LT_TRAY)		dp->cdr_flags |= CDR_TRAYLOAD;	else if (mp->loading_type == LT_CADDY)		dp->cdr_flags |= CDR_CADDYLOAD;	return (0);}#ifdef	PRINT_ATIPLOCAL	int	get_atip		__PR((SCSI *scgp, struct atipinfo *atp));	void	print_di		__PR((struct disk_info *dip));	void	print_atip		__PR((SCSI *scgp, struct atipinfo *atp));#endif	/* PRINT_ATIP */LOCAL intget_diskinfo(scgp, dip)	SCSI		*scgp;	struct disk_info *dip;{	int	len;	int	ret;	fillbytes((caddr_t)dip, sizeof(*dip), '\0');	if (read_disk_info(scgp, (caddr_t)dip, 2) < 0)		return (-1);	len = a_to_u_2_byte(dip->data_len);	len += 2;	ret = read_disk_info(scgp, (caddr_t)dip, len);#ifdef	DEBUG	scsiprbytes("Disk info:", (u_char *)dip,				len-scsigetresid(scgp));#endif	return (ret);}LOCAL voiddi_to_dstat(dip, dsp)	struct disk_info	*dip;	dstat_t	*dsp;{	dsp->ds_diskid = a_to_u_4_byte(dip->disk_id);	if (dip->did_v)		dsp->ds_flags |= DSF_DID_V;	dsp->ds_diskstat = dip->disk_status;	dsp->ds_sessstat = dip->sess_status;	dsp->ds_maxblocks = msf_to_lba(dip->last_lead_out[1],					dip->last_lead_out[2],					dip->last_lead_out[3]);	/*	 * Check for 0xFF:0xFF/0xFF which is an indicator for a complete disk	 */	if (dsp->ds_maxblocks == 716730)		dsp->ds_maxblocks = -1L;	if (dsp->ds_first_leadin == 0) {		dsp->ds_first_leadin = msf_to_lba(dip->last_lead_in[1],						dip->last_lead_in[2],						dip->last_lead_in[3]);		if (dsp->ds_first_leadin > 0)			dsp->ds_first_leadin = 0;	}	if (dsp->ds_last_leadout == 0 && dsp->ds_maxblocks >= 0)		dsp->ds_last_leadout = dsp->ds_maxblocks;}#ifdef	PRINT_ATIPLOCAL intget_atip(scgp, atp)	SCSI		*scgp;	struct atipinfo *atp;{	int	len;	int	ret;	fillbytes((caddr_t)atp, sizeof(*atp), '\0');	if (read_toc(scgp, (caddr_t)atp, 0, 2, 0, FMT_ATIP) < 0)		return (-1);	len = a_to_u_2_byte(atp->hd.len);	len += 2;	ret = read_toc(scgp, (caddr_t)atp, 0, len, 0, FMT_ATIP);#ifdef	DEBUG	scsiprbytes("ATIP info:", (u_char *)atp,				len-scsigetresid(scgp));#endif	/*	 * Yamaha sometimes returns zeroed ATIP info for disks without ATIP	 */	if (atp->desc.lead_in[1] == 0 &&			atp->desc.lead_in[2] == 0 &&			atp->desc.lead_in[3] == 0 &&			atp->desc.lead_out[1] == 0 &&			atp->desc.lead_out[2] == 0 &&			atp->desc.lead_out[3] == 0)		return (-1);	if (atp->desc.lead_in[1] >= 0x90 && debug) {		/*		 * Only makes sense with buggy Ricoh firmware.		 */		errmsgno(EX_BAD, "Converting ATIP from BCD\n");		atp->desc.lead_in[1] = from_bcd(atp->desc.lead_in[1]);		atp->desc.lead_in[2] = from_bcd(atp->desc.lead_in[2]);		atp->desc.lead_in[3] = from_bcd(atp->desc.lead_in[3]);		atp->desc.lead_out[1] = from_bcd(atp->desc.lead_out[1]);		atp->desc.lead_out[2] = from_bcd(atp->desc.lead_out[2]);		atp->desc.lead_out[3] = from_bcd(atp->desc.lead_out[3]);	}	return (ret);}LOCAL int/*get_pma(atp)*/get_pma(scgp)	SCSI	*scgp;/*	struct atipinfo *atp;*/{	int	len;	int	ret;char	atp[1024];	fillbytes((caddr_t)atp, sizeof(*atp), '\0');/*	if (read_toc(scgp, (caddr_t)atp, 0, 2, 1, FMT_PMA) < 0)*/	if (read_toc(scgp, (caddr_t)atp, 0, 2, 0, FMT_PMA) < 0)		return (-1);/*	len = a_to_u_2_byte(atp->hd.len);*/	len = a_to_u_2_byte(atp);	len += 2;/*	ret = read_toc(scgp, (caddr_t)atp, 0, len, 1, FMT_PMA);*/	ret = read_toc(scgp, (caddr_t)atp, 0, len, 0, FMT_PMA);#ifdef	DEBUG	scsiprbytes("PMA:", (u_char *)atp,				len-scsigetresid(scgp));#endif	ret = read_toc(scgp, (caddr_t)atp, 0, len, 1, FMT_PMA);#ifdef	DEBUG	scsiprbytes("PMA:", (u_char *)atp,				len-scsigetresid(scgp));#endif	return (ret);

⌨️ 快捷键说明

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