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

📄 scsi_cdr.c

📁 另一种方法编辑刻录程序的代码!要的与偶联系呀
💻 C
📖 第 1 页 / 共 4 页
字号:
/* @(#)scsi_cdr.c	1.56 98/10/18 Copyright 1995 J. Schilling */#ifndef lintstatic	char sccsid[] =	"@(#)scsi_cdr.c	1.56 98/10/18 Copyright 1995 J. Schilling";#endif/* *	SCSI command functions for cdrecord * *	Copyright (c) 1995 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. *//* * NOTICE:	The Philips CDD 521 has several firmware bugs. *		One of them is not to respond to a SCSI selection *		within 200ms if the general load on the *		SCSI bus is high. To deal with this problem *		most of the SCSI commands are send with the *		SCG_CMD_RETRY flag enabled. */#include <mconfig.h>#include <stdio.h>#include <standard.h>#include <stdlib.h>#include <fcntl.h>#include <errno.h>#include <string.h>#include <utypes.h>#include <btorder.h>#include <scgio.h>#include <scsidefs.h>#include <scsireg.h>#include "cdrecord.h"#include "scsitransp.h"#define	strbeg(s1,s2)	(strstr((s2), (s1)) == (s2))struct	scg_cmd		scmd;struct	scsi_inquiry	inq;struct scsi_capacity cap = { 0, 2048 };/*struct scsi_capacity cap = { 0, 2352 };*/extern	int	scsibus;extern	int	target;extern	int	lun;extern	int	silent;extern	int	debug;extern	int	verbose;extern	int	lverbose;EXPORT	int	open_scsi	__PR((char *scsidev, int timeout,								int be_verbose));LOCAL	int	scsi_scandev	__PR((char *devp, int *xp1, int *xp2, int *xp3));EXPORT	void	scsi_settimeout	__PR((int timeout));EXPORT	BOOL	unit_ready	__PR((void));EXPORT	BOOL	wait_unit_ready	__PR((int secs));EXPORT	int	test_unit_ready	__PR((void));EXPORT	int	rezero_unit	__PR((void));EXPORT	int	request_sense	__PR((void));EXPORT	int	inquiry		__PR((caddr_t, int));EXPORT	int	read_capacity	__PR((void));EXPORT	int	scsi_load_unload __PR((int));EXPORT	int	load_unload_philips __PR((int));EXPORT	int	scsi_prevent_removal __PR((int));EXPORT	int	scsi_start_stop_unit __PR((int, int));EXPORT	int	scsi_set_speed	__PR((int readspeed, int writespeed));EXPORT	int	qic02		__PR((int));EXPORT	int	write_xg0	__PR((caddr_t, long, long, int));EXPORT	int	write_xg1	__PR((caddr_t, long, long, int));EXPORT	int	write_xg5	__PR((caddr_t, long, long, int));EXPORT	int	write_track	__PR((long, int));EXPORT	int	scsi_flush_cache __PR((void));EXPORT	int	read_toc	__PR((caddr_t, int, int, int, int));EXPORT	int	read_toc_philips __PR((caddr_t, int, int, int, int));EXPORT	int	read_header	__PR((caddr_t, long, int, int));EXPORT	int	read_disk_info	__PR((caddr_t, int));EXPORT	int	read_track_info	__PR((caddr_t, int, int));EXPORT	int	read_track_info_philips	__PR((caddr_t, int, int));EXPORT	int	close_track_philips __PR((int track, track_t *trackp));EXPORT	int	fixation	__PR((int, int, int, int tracks, track_t *trackp));EXPORT	int	scsi_close_tr_session __PR((int type, int track));EXPORT	int	scsi_blank	__PR((long addr, int blanktype));EXPORT	int	recover		__PR((int));EXPORT	int	first_writable_addr __PR((long *, int, int, int, int));EXPORT	int	reserve_track	__PR((unsigned long));EXPORT	BOOL	allow_atapi	__PR((BOOL new));EXPORT	int	mode_select	__PR((u_char *, int, int, int));EXPORT	int	mode_sense	__PR((u_char *dp, int cnt, int page, int pcf));EXPORT	int	mode_select_sg0	__PR((u_char *, int, int, int));EXPORT	int	mode_sense_sg0	__PR((u_char *dp, int cnt, int page, int pcf));EXPORT	int	mode_select_g0	__PR((u_char *, int, int, int));EXPORT	int	mode_select_g1	__PR((u_char *, int, int, int));EXPORT	int	mode_sense_g0	__PR((u_char *dp, int cnt, int page, int pcf));EXPORT	int	mode_sense_g1	__PR((u_char *dp, int cnt, int page, int pcf));EXPORT	int	speed_select_yamaha	__PR((int speed, int dummy));EXPORT	int	speed_select_philips	__PR((int speed, int dummy));EXPORT	int	write_track_info __PR((int));EXPORT	int	read_tochdr	__PR((cdr_t *, int *, int *));EXPORT	int	read_trackinfo	__PR((int, long *, struct msf *, int *, int *, int *));EXPORT	int	read_B0		__PR((BOOL isbcd, long *b0p, long *lop));EXPORT	int	read_session_offset __PR((long *));EXPORT	int	read_session_offset_philips __PR((long *));EXPORT	int	sense_secsize	__PR((int current));EXPORT	int	select_secsize	__PR((int));EXPORT	BOOL	is_cddrive	__PR((void));EXPORT	BOOL	is_unknown_dev	__PR((void));EXPORT	int	read_scsi	__PR((caddr_t, long, int));EXPORT	int	read_g0		__PR((caddr_t, long, int));EXPORT	int	read_g1		__PR((caddr_t, long, int));EXPORT	BOOL	getdev		__PR((BOOL));EXPORT	void	printdev	__PR((void));EXPORT	BOOL	do_inquiry	__PR((BOOL));EXPORT	BOOL	recovery_needed	__PR((void));EXPORT	int	scsi_load	__PR((void));EXPORT	int	scsi_unload	__PR((void));EXPORT	int	scsi_cdr_write	__PR((caddr_t bp, long sectaddr, long size, int blocks, BOOL islast));EXPORT	struct cd_mode_page_2A * mmc_cap __PR((u_char *modep));EXPORT	void	mmc_getval	__PR((struct cd_mode_page_2A *mp,					BOOL *cdrrp, BOOL *cdwrp,					BOOL *cdrrwp, BOOL *cdwrwp,					BOOL *dvdp));EXPORT	BOOL	is_mmc		__PR((BOOL *dvdp));EXPORT	BOOL	mmc_check	__PR((BOOL *cdrrp, BOOL *cdwrp,					BOOL *cdrrwp, BOOL *cdwrwp,					BOOL *dvdp));EXPORT	void	print_capabilities __PR((void));/* * Open a SCSI device. * * Possible syntax is: * * Preferred: *	dev=target,lun / dev=scsibus,target,lun * * Needed on some systems: *	dev=devicename:target,lun / dev=devicename:scsibus,target,lun * * On systems that don't support SCSI Bus scanning this syntax helps: *	dev=devicename:@ / dev=devicename:@,lun * or	dev=devicename (undocumented) * * NOTE: As the 'lun' is part of the SCSI command descriptor block, it * 	 must always be known. If the OS cannot map it, it must be *	 specified on command line. */EXPORT intopen_scsi(scsidev, timeout, be_verbose)	char	*scsidev;	int	timeout;	int	be_verbose;{	char	devname[256];	char	*devp = NULL;	int	x1, x2, x3;	int	n = 0;	extern	int	deftimeout;	if (timeout >= 0)		deftimeout = timeout;	devname[0] = '\0';	if (scsidev != NULL) {		if ((devp = strchr(scsidev, ':')) == NULL) {			if (strchr(scsidev, ',') == NULL) {				/* Notation form: 'devname' (undocumented)   */				/* Fetch bus/tgt/lun values from OS	     */				n = -1;				lun = -2;	/* Lun must be known	     */				strncpy(devname, scsidev, sizeof(devname)-1);				devname[sizeof(devname)-1] = '\0';			} else {				/* Basic notation form: 'bus,tgt,lun'	     */				devp = scsidev;			}		} else {			/* Notation form: 'devname:bus,tgt,lun'/'devname:@'  */			x1 = devp - scsidev;			if (x1 >= sizeof(devname))				x1 = sizeof(devname)-1;			strncpy(devname, scsidev, x1);			devname[x1] = '\0';			devp++;			/* Check for a notation in the form 'devname:@'	     */			if (devp[0] == '@') {				if (devp[1] == '\0') {					lun = -2;				} else if (devp[1] == ',') {					if (*astoi(&devp[2], &lun) != '\0')						return (-1);				}				n = -1;				devp = NULL;			}		}	}	if (devp != NULL) {		n = scsi_scandev(devp, &x1, &x2, &x3);		if (n < 0) {			errno = EINVAL;			return (-1);		}	}	if (n == 3) {		/* Got bus,target,lun			*/		scsibus = x1;		target = x2;		lun = x3;	} else if (n == 2) {	/* Got target,lun			*/		scsibus = 0;		target = x1;		lun = x2;	} else if (n == -1) {	/* Got device:@, fetch bus/lun from OS	*/		scsibus = target = -2;	} else if (devp != NULL) {		printf("WARNING: device not valid, trying to use default target...\n");		scsibus = 0;		target = 6;		lun = 0;	}	if (be_verbose && scsidev != NULL) {		printf("scsidev: '%s'\n", scsidev);		if (devname[0] != '\0')			printf("devname: '%s'\n", devname);		printf("scsibus: %d target: %d lun: %d\n",						scsibus, target, lun);	}	return (scsi_open(devname, scsibus, target, lun));}/* * Convert target,lun or scsibus,target,lun syntax. * Check for bad syntax and invalid values. * This is definitely better than using scanf() as it checks for syntax errors. */LOCAL intscsi_scandev(devp, xp1, xp2, xp3)	char	*devp;	int	*xp1;	int	*xp2;	int	*xp3;{	int	n = 0;	*xp1 = *xp2 = *xp3 = 0;	if (*devp != '\0') {		devp = astoi(devp, xp1);		if (*devp == ',') {			devp++;			n++;		} else {			return (-1);		}	}	if (*devp != '\0') {		devp = astoi(devp, xp2);		if (*devp == ',' || *devp == '\0') {			if (*devp != '\0')				devp++;			n++;		} else {			return (-1);		}	}	if (*devp != '\0') {		devp = astoi(devp, xp3);		if (*devp == '\0') {			n++;		} else {			return (-1);		}	}	if (*xp1 < 0 || *xp2 < 0 || *xp3 < 0)		return (-1);	return (n);}EXPORT voidscsi_settimeout(timeout)	int	timeout;{	extern	int	deftimeout;	deftimeout = timeout / 100;}EXPORT BOOLunit_ready(){	if (test_unit_ready() >= 0)		/* alles OK */		return (TRUE);	else if (scmd.error >= SCG_FATAL)	/* nicht selektierbar */		return (FALSE);	if (scmd.sense.code < 0x70) {		/* non extended Sense */		if (scmd.sense.code == 0x04)	/* NOT_READY */			return (FALSE);		return (TRUE);	}	if (((struct scsi_ext_sense *)&scmd.sense)->key == SC_UNIT_ATTENTION) {		if (test_unit_ready() >= 0)	/* alles OK */			return (TRUE);	}						/* FALSE wenn NOT_READY */	return (((struct scsi_ext_sense *)&scmd.sense)->key != SC_NOT_READY);}EXPORT BOOLwait_unit_ready(secs)	int	secs;{	int	i;	int	c;	int	k;	int	ret;	silent++;	ret = test_unit_ready();		/* eat up unit attention */	silent--;	if (ret >= 0)				/* success that's enough */		return (TRUE);	silent++;	for (i=0; i < secs && (ret = test_unit_ready()) < 0; i++) {		if (scmd.scb.busy != 0) {			sleep(1);			continue;		}		c = scsi_sense_code();		k = scsi_sense_key();		if (k == SC_NOT_READY && (c == 0x3A || c == 0x30)) {			scsiprinterr("test_unit_ready");			silent--;			return (FALSE);		}		sleep(1);	}	silent--;	if (ret < 0)		return (FALSE);	return (TRUE);}EXPORT inttest_unit_ready(){	fillbytes((caddr_t)&scmd, sizeof(scmd), '\0');	scmd.addr = (caddr_t)0;	scmd.size = 0;	scmd.flags = SCG_DISRE_ENA | (silent ? SCG_SILENT:0);	scmd.cdb_len = SC_G0_CDBLEN;	scmd.sense_len = CCS_SENSE_LEN;	scmd.target = target;	scmd.cdb.g0_cdb.cmd = SC_TEST_UNIT_READY;	scmd.cdb.g0_cdb.lun = lun;		return (scsicmd("test unit ready"));}EXPORT intrezero_unit(){	fillbytes((caddr_t)&scmd, sizeof(scmd), '\0');	scmd.addr = (caddr_t)0;	scmd.size = 0;	scmd.flags = SCG_DISRE_ENA;	scmd.cdb_len = SC_G0_CDBLEN;	scmd.sense_len = CCS_SENSE_LEN;	scmd.target = target;	scmd.cdb.g0_cdb.cmd = SC_REZERO_UNIT;	scmd.cdb.g0_cdb.lun = lun;		return (scsicmd("rezero unit"));}EXPORT intrequest_sense(){	char	sensebuf[CCS_SENSE_LEN];	fillbytes((caddr_t)&scmd, sizeof(scmd), '\0');	scmd.addr = sensebuf;	scmd.size = sizeof(sensebuf);;	scmd.flags = SCG_RECV_DATA|SCG_DISRE_ENA;	scmd.cdb_len = SC_G0_CDBLEN;	scmd.sense_len = CCS_SENSE_LEN;	scmd.target = target;	scmd.cdb.g0_cdb.cmd = SC_REQUEST_SENSE;	scmd.cdb.g0_cdb.lun = lun;	scmd.cdb.g0_cdb.count = CCS_SENSE_LEN;		if (scsicmd("request_sense") < 0)		return (-1);	scsiprsense((u_char *)sensebuf, CCS_SENSE_LEN - scmd.resid);	return (0);}EXPORT intinquiry(bp, cnt)	caddr_t	bp;	int	cnt;{	fillbytes(bp, cnt, '\0');	fillbytes((caddr_t)&scmd, sizeof(scmd), '\0');	scmd.addr = bp;	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 = target;	scmd.cdb.g0_cdb.cmd = SC_INQUIRY;	scmd.cdb.g0_cdb.lun = lun;	scmd.cdb.g0_cdb.count = cnt;		if (scsicmd("inquiry") < 0)		return (-1);	if (verbose)		scsiprbytes("Inquiry Data   :", (u_char *)bp, cnt - scmd.resid);	return (0);}EXPORT intread_capacity(){	fillbytes((caddr_t)&scmd, sizeof(scmd), '\0');	scmd.addr = (caddr_t)&cap;	scmd.size = sizeof(cap);	scmd.flags = SCG_RECV_DATA|SCG_DISRE_ENA;	scmd.cdb_len = SC_G1_CDBLEN;	scmd.sense_len = CCS_SENSE_LEN;	scmd.target = target;	scmd.cdb.g1_cdb.cmd = 0x25;	/* Read Capacity */	scmd.cdb.g1_cdb.lun = lun;	g1_cdblen(&scmd.cdb.g1_cdb, 0); /* Full Media */		if (scsicmd("read capacity") < 0) {		return (-1);	} else {		long	kb;		long	mb;		long	prmb;		double	dkb;		long	cbsize;		long	cbaddr;		cbsize = a_to_u_long(&cap.c_bsize);		cbaddr = a_to_u_long(&cap.c_baddr);		cap.c_bsize = cbsize;		cap.c_baddr = cbaddr;		if (silent)			return (0);		dkb =  (cap.c_baddr+1.0) * (cap.c_bsize/1024.0);		kb = dkb;		mb = dkb / 1024.0;		prmb = dkb / 1000.0 * 1.024;		printf("Capacity: %ld Blocks = %ld kBytes = %ld MBytes = %ld prMB\n",			cap.c_baddr+1, kb, mb, prmb);		printf("Sectorsize: %ld Bytes\n", cap.c_bsize);	}	return (0);}EXPORT intscsi_load_unload(load)	int	load;{	fillbytes((caddr_t)&scmd, sizeof(scmd), '\0');	scmd.flags = SCG_DISRE_ENA;	scmd.cdb_len = SC_G5_CDBLEN;	scmd.sense_len = CCS_SENSE_LEN;	scmd.target = target;	scmd.cdb.g5_cdb.cmd = 0xA6;	scmd.cdb.g5_cdb.lun = lun;	scmd.cdb.g5_cdb.addr[1] = load?3:2;	scmd.cdb.g5_cdb.count[2] = 0; /* slot # */		if (scsicmd("medium load/unload") < 0)		return (-1);	return (0);}EXPORT intload_unload_philips(load)	int	load;{	fillbytes((caddr_t)&scmd, sizeof(scmd), '\0');	scmd.flags = SCG_DISRE_ENA;	scmd.cdb_len = SC_G1_CDBLEN;	scmd.sense_len = CCS_SENSE_LEN;	scmd.target = target;	scmd.cdb.g1_cdb.cmd = 0xE7;	scmd.cdb.g1_cdb.lun = lun;	scmd.cdb.g1_cdb.count[1] = !load;		if (scsicmd("medium load/unload") < 0)		return (-1);	return (0);}EXPORT intscsi_prevent_removal(prevent)	int	prevent;{	fillbytes((caddr_t)&scmd, sizeof(scmd), '\0');	scmd.flags = SCG_DISRE_ENA;	scmd.cdb_len = SC_G0_CDBLEN;	scmd.sense_len = CCS_SENSE_LEN;	scmd.target = target;	scmd.cdb.g0_cdb.cmd = 0x1E;	scmd.cdb.g0_cdb.lun = lun;	scmd.cdb.g0_cdb.count = prevent & 1;		if (scsicmd("prevent/allow medium removal") < 0)		return (-1);	return (0);}EXPORT intscsi_start_stop_unit(flg, loej)	int	flg;	int	loej;{	fillbytes((caddr_t)&scmd, sizeof(scmd), '\0');	scmd.flags = SCG_DISRE_ENA;	scmd.cdb_len = SC_G0_CDBLEN;	scmd.sense_len = CCS_SENSE_LEN;	scmd.target = target;	scmd.cdb.g0_cdb.cmd = 0x1B;	/* Start Stop Unit */	scmd.cdb.g0_cdb.lun = lun;	scmd.cdb.g0_cdb.count = (flg ? 1:0) | (loej ? 2:0);		return (scsicmd("start/stop unit"));}EXPORT intscsi_set_speed(readspeed, writespeed)	int	readspeed;	int	writespeed;{	fillbytes((caddr_t)&scmd, sizeof(scmd), '\0');	scmd.flags = SCG_DISRE_ENA;	scmd.cdb_len = SC_G5_CDBLEN;	scmd.sense_len = CCS_SENSE_LEN;	scmd.target = target;	scmd.cdb.g5_cdb.cmd = 0xBB;	scmd.cdb.g5_cdb.lun = lun;	i_to_short(&scmd.cdb.g5_cdb.addr[0], readspeed);	i_to_short(&scmd.cdb.g5_cdb.addr[2], writespeed);	if (scsicmd("set cd speed") < 0)		return (-1);	return (0);}EXPORT intqic02(cmd)	int	cmd;{	fillbytes((caddr_t)&scmd, sizeof(scmd), '\0');	scmd.addr = (caddr_t)0;	scmd.size = 0;	scmd.flags = SCG_DISRE_ENA;	scmd.cdb_len = SC_G0_CDBLEN;	scmd.sense_len = DEF_SENSE_LEN;	scmd.target = target;	scmd.cdb.g0_cdb.cmd = 0x0D;	/* qic02 Sysgen SC4000 */	scmd.cdb.g0_cdb.lun = lun;	scmd.cdb.g0_cdb.mid_addr = cmd;		return (scsicmd("qic 02"));}EXPORT intwrite_xg0(bp, addr, size, cnt)	caddr_t	bp;		/* address of buffer */	long	addr;		/* disk address (sector) to put */	long	size;		/* number of bytes to transfer */	int	cnt;		/* sectorcount */{	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_G0_CDBLEN;	scmd.sense_len = CCS_SENSE_LEN;	scmd.target = target;	scmd.cdb.g0_cdb.cmd = SC_WRITE;	scmd.cdb.g0_cdb.lun = lun;	g0_cdbaddr(&scmd.cdb.g0_cdb, addr);	scmd.cdb.g0_cdb.count = cnt;		if (scsicmd("write_g0") < 0)		return (-1);	return (size - scmd.resid);}EXPORT intwrite_xg1(bp, addr, size, cnt)	caddr_t	bp;		/* address of buffer */	long	addr;		/* disk address (sector) to put */	long	size;		/* number of bytes to transfer */	int	cnt;		/* sectorcount */{	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 = target;	scmd.cdb.g1_cdb.cmd = SC_EWRITE;	scmd.cdb.g1_cdb.lun = lun;	g1_cdbaddr(&scmd.cdb.g1_cdb, addr);	g1_cdblen(&scmd.cdb.g1_cdb, cnt);

⌨️ 快捷键说明

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