⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 drv_jvc.c

📁 刻录光盘的程序
💻 C
📖 第 1 页 / 共 3 页
字号:
/** @(#)drv_jvc.c	1.46 99/10/17 Copyright 1997 J. Schilling */#ifndef lintstatic	char sccsid[] =	"@(#)drv_jvc.c	1.46 99/10/17 Copyright 1997 J. Schilling";#endif/* *	CDR device implementation for *	JVC/TEAC * *	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	XXDEBUG*//*#define	XXBUFFER*/#include <mconfig.h>#include <stdio.h>#include <standard.h>#include <fctldefs.h>#include <errno.h>#include <strdefs.h>#include <unixstd.h>#ifdef	XXDEBUG#include <stdxlib.h>#endif#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 "cdrecord.h"/* just a hack */long	lba_addr;BOOL	last_done;/* * macros for building MSF values from LBA */#define LBA_MIN(x)	((x)/(60*75))#define LBA_SEC(x)	(((x)%(60*75))/75)#define LBA_FRM(x)	((x)%75)#define MSF_CONV(a)	((((a)%100)/10)*16 + ((a)%10))extern	int	lverbose;#if defined(_BIT_FIELDS_LTOH)	/* Intel byteorder */struct teac_mode_page_21 {		/* teac dummy selection */		MP_P_CODE;		/* parsave & pagecode */	u_char	p_len;			/* 0x01 = 1 Byte */	Ucbit	dummy		: 2;	Ucbit	res		: 6;};#elsestruct teac_mode_page_21 {		/* teac dummy selection */		MP_P_CODE;		/* parsave & pagecode */	u_char	p_len;			/* 0x01 = 1 Byte */	Ucbit	res		: 6;	Ucbit	dummy		: 2;};#endifstruct teac_mode_page_31 {		/* teac speed selection */		MP_P_CODE;		/* parsave & pagecode */	u_char	p_len;			/* 0x02 = 2 Byte */	u_char	speed;	u_char	res;};struct cdd_52x_mode_data {	struct scsi_mode_header	header;	union cdd_pagex	{		struct teac_mode_page_21	teac_page21;		struct teac_mode_page_31	teac_page31;	} pagex;};#if defined(_BIT_FIELDS_LTOH)	/* Intel byteorder */struct pgm_subcode {		/* subcode for progam area */	u_char	subcode;	Ucbit	addr		: 4;	Ucbit	control		: 4;	u_char	track;	u_char	index;};#elsestruct pgm_subcode {		/* subcode for progam area */	u_char	subcode;	Ucbit	control		: 4;	Ucbit	addr		: 4;	u_char	track;	u_char	index;};#endif#define	set_pgm_subcode(sp, t, c, a, tr, idx)		(\			(sp)->subcode = (t),		 \			(sp)->control = (c),		 \			(sp)->addr = (a),		 \			(sp)->track = MSF_CONV(tr),	 \			(sp)->index = (idx))#define	SC_P		1	/* Subcode defines pre-gap (Pause)	*/#define	SC_TR		0	/* Subcode defines track data		*/#if defined(_BIT_FIELDS_LTOH)	/* Intel byteorder */typedef struct lin_subcode {	/* subcode for lead in area */	Ucbit	addr		: 4;	Ucbit	control		: 4;	u_char	track;	u_char	msf[3];} lsc_t;#elsetypedef struct lin_subcode {	/* subcode for lead in area */	Ucbit	control		: 4;	Ucbit	addr		: 4;	u_char	track;	u_char	msf[3];} lsc_t;#endif#define	set_toc_subcode(sp, c, a, tr, bno)				(\			((lsc_t *)sp)->control = (c),			 \			((lsc_t *)sp)->addr = (a),			 \			((lsc_t *)sp)->track = MSF_CONV(tr),		 \			((lsc_t *)sp)->msf[0] = MSF_CONV(LBA_MIN(bno)),	 \			((lsc_t *)sp)->msf[1] = MSF_CONV(LBA_SEC(bno)),	 \			((lsc_t *)sp)->msf[2] = MSF_CONV(LBA_FRM(bno)),	 \			&((lsc_t *)sp)->msf[3])#define	set_lin_subcode(sp, c, a, pt, min, sec, frm)			(\			((lsc_t *)sp)->control = (c),			 \			((lsc_t *)sp)->addr = (a),			 \			((lsc_t *)sp)->track = (pt),			 \			((lsc_t *)sp)->msf[0] = (min),			 \			((lsc_t *)sp)->msf[1] = (sec),			 \			((lsc_t *)sp)->msf[2] = (frm),			 \			&((lsc_t *)sp)->msf[3])#if defined(_BIT_FIELDS_LTOH)	/* Intel byteorder */struct upc_subcode {		/* subcode for upc/bar code */	u_char	res;	Ucbit	addr		: 4;	Ucbit	control		: 4;	u_char	upc[13];};#elsestruct upc_subcode {		/* subcode for upc/bar code */	u_char	res;	Ucbit	control		: 4;	Ucbit	addr		: 4;	u_char	upc[13];};#endif#if defined(_BIT_FIELDS_LTOH)	/* Intel byteorder */struct isrc_subcode {		/* subcode for ISRC code */	u_char	res;	Ucbit	addr		: 4;	Ucbit	control		: 4;	u_char	isrc[12];	u_char	res14;};#elsestruct isrc_subcode {		/* subcode for ISRC code */	u_char	res;	Ucbit	control		: 4;	Ucbit	addr		: 4;	u_char	isrc[12];	u_char	res14;};#endifLOCAL	int	teac_attach		__PR((SCSI *scgp, cdr_t *dp));LOCAL	int	teac_getdisktype	__PR((SCSI *scgp, cdr_t *dp, dstat_t *dsp));LOCAL	int	speed_select_teac	__PR((SCSI *scgp, int *speedp, int dummy));LOCAL	int	select_secsize_teac	__PR((SCSI *scgp, track_t *trackp));LOCAL	int	next_wr_addr_jvc	__PR((SCSI *scgp, int track, track_t *, long *ap));LOCAL	int	write_teac_xg1		__PR((SCSI *scgp, caddr_t, long, long, int, BOOL));LOCAL	int	cdr_write_teac		__PR((SCSI *scgp, caddr_t bp, long sectaddr, long size, int blocks, BOOL islast));LOCAL	int	open_track_jvc		__PR((SCSI *scgp, cdr_t *dp, int track, track_t *trackp));LOCAL	int	teac_fixation		__PR((SCSI *scgp, int onp, int dummy, int toctype, int tracks, track_t *trackp));LOCAL	int	close_track_teac	__PR((SCSI *scgp, int track, track_t *trackp));LOCAL	int	teac_open_session	__PR((SCSI *scgp, int tracks, track_t *trackp, int toctype, int multi));LOCAL	int	teac_calibrate		__PR((SCSI *scgp, int toctype, int multi));LOCAL	int	opt_power_judge		__PR((SCSI *scgp, int judge));LOCAL	int	clear_subcode		__PR((SCSI *scgp));LOCAL	int	set_limits		__PR((SCSI *scgp, long lba, long length));LOCAL	int	set_subcode		__PR((SCSI *scgp, u_char *subcode_data, int length));LOCAL	int	read_disk_info_teac	__PR((SCSI *scgp, u_char *data, int length, int type));LOCAL	int	teac_freeze		__PR((SCSI *scgp, int bp_flag));LOCAL	int	teac_wr_pma		__PR((SCSI *scgp));LOCAL	int	teac_rd_pma		__PR((SCSI *scgp));LOCAL	int	next_wr_addr_teac	__PR((SCSI *scgp, long start_lba, long last_lba));LOCAL	int	blank_jvc		__PR((SCSI *scgp, long addr, int blanktype));LOCAL	int	buf_cap_teac		__PR((SCSI *scgp, long *sp, long *fp));LOCAL	long	read_peak_buffer_cap_teac __PR((SCSI *scgp));LOCAL	int	buffer_inquiry_teac	__PR((SCSI *scgp, int fmt));#ifdef	XXBUFFERLOCAL	void	check_buffer_teac	__PR((SCSI *scgp));#endif#ifdef	XXDEBUGLOCAL	void	xxtest_teac		__PR((SCSI *scgp));#endifcdr_t	cdr_teac_cdr50 = {	0,	CDR_TAO|CDR_DAO|CDR_SWABAUDIO|CDR_NO_LOLIMIT,	"teac_cdr50",	"driver for Teac CD-R50S, Teac CD-R55S, JVC XR-W2010, Pinnacle RCD-5020",	0,	drive_identify,	teac_attach,	teac_getdisktype,	scsi_load,	scsi_unload,	buf_cap_teac,	(int(*)__PR((SCSI *)))cmd_dummy,	/* recovery_needed	*/	(int(*)__PR((SCSI *, int)))cmd_dummy,	/* recover		*/	speed_select_teac,	select_secsize,	next_wr_addr_jvc,	(int(*)__PR((SCSI *, Ulong)))cmd_ill,	/* reserve_track	*/	cdr_write_teac,	no_sendcue,	open_track_jvc,	close_track_teac,	teac_open_session,	cmd_dummy,	read_session_offset_philips,	teac_fixation,/*	blank_dummy,*/	blank_jvc,};LOCAL intteac_getdisktype(scgp, dp, dsp)	SCSI	*scgp;	cdr_t	*dp;	dstat_t	*dsp;{	struct scsi_mode_data md;	int	count = sizeof(struct scsi_mode_header) +			sizeof(struct scsi_mode_blockdesc);	int	len;	int	page = 0;	long	l;	fillbytes((caddr_t)&md, sizeof(md), '\0');	(void)test_unit_ready(scgp);	if (mode_sense(scgp, (u_char *)&md, count, page, 0) < 0) {	/* Page n current */		return (-1);	} else {		len = ((struct scsi_mode_header *)&md)->sense_data_len + 1;	}	if (((struct scsi_mode_header *)&md)->blockdesc_len < 8)		return (-1);	l = a_to_u_3_byte(md.blockdesc.nlblock);	dsp->ds_maxblocks = l;	return (0);}LOCAL intspeed_select_teac(scgp, speedp, dummy)	SCSI	*scgp;	int	*speedp;	int	dummy;{	struct cdd_52x_mode_data md;	int	count;	int	status;	int	speed = 1;	if (speedp)		speed = *speedp;	fillbytes((caddr_t)&md, sizeof(md), '\0');	count  = sizeof(struct scsi_mode_header) +		sizeof(struct teac_mode_page_21);	md.pagex.teac_page21.p_code = 0x21;	md.pagex.teac_page21.p_len =  0x01;	md.pagex.teac_page21.dummy = dummy?3:0;	status = mode_select(scgp, (u_char *)&md, count, 0, scgp->inq->data_format >= 2);	if (status < 0)		return (status);	if (speedp == 0)		return (0);	fillbytes((caddr_t)&md, sizeof(md), '\0');	count  = sizeof(struct scsi_mode_header) +		sizeof(struct teac_mode_page_31);	speed >>= 1;	md.pagex.teac_page31.p_code = 0x31;	md.pagex.teac_page31.p_len =  0x02;	md.pagex.teac_page31.speed = speed;	return (mode_select(scgp, (u_char *)&md, count, 0, scgp->inq->data_format >= 2));}LOCAL intselect_secsize_teac(scgp, trackp)	SCSI	*scgp;	track_t	*trackp;{	struct scsi_mode_data md;	int	count = sizeof(struct scsi_mode_header) +			sizeof(struct scsi_mode_blockdesc);	int	len;	int	page = 0;	fillbytes((caddr_t)&md, sizeof(md), '\0');	(void)test_unit_ready(scgp);	if (mode_sense(scgp, (u_char *)&md, count, page, 0) < 0) {	/* Page n current */		return (-1);	} else {		len = ((struct scsi_mode_header *)&md)->sense_data_len + 1;	}	if (((struct scsi_mode_header *)&md)->blockdesc_len < 8)		return (-1);	md.header.sense_data_len = 0;	md.header.blockdesc_len = 8;	md.blockdesc.density = 1;	if (trackp->secsize == 2352)		md.blockdesc.density = 4;	i_to_3_byte(md.blockdesc.lblen, trackp->secsize);		return (mode_select(scgp, (u_char *)&md, count, 0, scgp->inq->data_format >= 2));}LOCAL intnext_wr_addr_jvc(scgp, track, trackp, ap)	SCSI	*scgp;	int	track;	track_t	*trackp;	long	*ap;{	if (track > 0) {		*ap = lba_addr;	} else {		long	nwa;		if (read_B0(scgp, TRUE, &nwa, NULL) < 0)			return (-1);		*ap = nwa + 150;	}	return (0);}LOCAL intwrite_teac_xg1(scgp, bp, sectaddr, size, blocks, extwr)	SCSI	*scgp;	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	extwr;		/* is an extended write */{	register struct	scg_cmd	*scmd = scgp->scmd;	fillbytes((caddr_t)scmd, sizeof(*scmd), '\0');	scmd->addr = bp;	scmd->size = size;	scmd->flags = SCG_DISRE_ENA|SCG_CMD_RETRY;/*	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 = SC_EWRITE;	scmd->cdb.g1_cdb.lun = scgp->lun;	g1_cdbaddr(&scmd->cdb.g1_cdb, sectaddr);	g1_cdblen(&scmd->cdb.g1_cdb, blocks);	scmd->cdb.g1_cdb.vu_97 = extwr;	scgp->cmdname = "write_teac_g1";	if (scsicmd(scgp) < 0)		return (-1);	return (size - scsigetresid(scgp));}LOCAL intcdr_write_teac(scgp, bp, sectaddr, size, blocks, islast)	SCSI	*scgp;	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 */{	int	ret;	if (islast)		last_done = TRUE;	ret = write_teac_xg1(scgp, bp, sectaddr, size, blocks, !islast);	if (ret < 0)		return (ret);	lba_addr = sectaddr + blocks;#ifdef	XXBUFFER	check_buffer_teac(scgp);#endif	return (ret);}LOCAL intopen_track_jvc(scgp, dp, track, trackp)	SCSI	*scgp;	cdr_t	*dp;	int	track;	track_t	*trackp;{	int	status;	long	blocks;	long	pregapsize;	struct	pgm_subcode	sc;	last_done = FALSE;	if (select_secsize_teac(scgp, trackp) < 0)		return (-1);	status = clear_subcode(scgp);/*next_wr_addr_teac(scgp);*/	if (status < 0)		return (status);if (trackp->pregapsize != 0) {	if (lverbose > 1) {		printf("set_limits(%ld, %ld)-> %ld\n",		lba_addr, trackp->pregapsize, lba_addr + trackp->pregapsize);	}	status = set_limits(scgp, lba_addr, trackp->pregapsize);	if (status < 0)		return (status);

⌨️ 快捷键说明

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