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

📄 scsi-linux-sg.c

📁 另一种方法编辑刻录程序的代码!要的与偶联系呀
💻 C
📖 第 1 页 / 共 2 页
字号:
/* @(#)scsi-linux-sg.c	1.26 98/10/06 Copyright 1997 J. Schilling */#ifndef lintstatic	char __sccsid[] =	"@(#)scsi-linux-sg.c	1.26 98/10/06 Copyright 1997 J. Schilling";#endif/* *	Interface for Linux generic SCSI implementation (sg). * *	This is the interface for the broken Linux SCSI generic driver. *	This is a hack, that tries to emulate the functionality *	of the scg driver. * *	Design flaws of the sg driver: *	-	cannot see if SCSI command could not be send *	-	cannot get SCSI status byte *	-	cannot get real dma count of tranfer *	-	cannot get number of bytes valid in auto sense data *	-	to few data in auto sense (CCS/SCSI-2/SCSI-3 needs >= 18) * *	This code contains support for the sg driver version 2 * *	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. */#if HAVE_CONFIG_H#include <config.h>#endif#include <scsi/scsi.h>#include <scsi/sg.h>#ifdef HAVE_LINUX_PG_H#       define   USE_PG#endif#ifndef	SCSI_IOCTL_GET_BUS_NUMBER#define SCSI_IOCTL_GET_BUS_NUMBER 0x5386#endif/* * XXX There must be a better way than duplicating things from system include * XXX files. This is stolen from /usr/src/linux/drivers/scsi/scsi.h */#ifndef	DID_OK#define DID_OK          0x00 /* NO error                                */#define DID_NO_CONNECT  0x01 /* Couldn't connect before timeout period  */#define DID_BUS_BUSY    0x02 /* BUS stayed busy through time out period */#define DID_TIME_OUT    0x03 /* TIMED OUT for other reason              */#define DID_BAD_TARGET  0x04 /* BAD target.                             */#define DID_ABORT       0x05 /* Told to abort for some other reason     */#define DID_PARITY      0x06 /* Parity error                            */#define DID_ERROR       0x07 /* Internal error                          */#define DID_RESET       0x08 /* Reset by somebody.                      */#define DID_BAD_INTR    0x09 /* Got an interrupt we weren't expecting.  */ #endif#define	MAX_SCG		8	/* Max # of SCSI controllers */#define	MAX_TGT		8#define	MAX_LUN		8LOCAL	int	scgfile = -1;	/* Used for SG_GET_BUFSIZE ioctl()	*/LOCAL	short	scgfiles[MAX_SCG][MAX_TGT][MAX_LUN];LOCAL	short	buscookies[MAX_SCG];#ifdef	SG_BIG_BUFF#define	MAX_DMA_LINUX	SG_BIG_BUFF	/* Defined in include/scsi/sg.h	*/#else#define	MAX_DMA_LINUX	(4*1024)	/* Old Linux versions		*/#endif#ifndef	SG_MAX_SENSE#	define	SG_MAX_SENSE	16	/* Too small for CCS / SCSI-2	*/#endif					/* But cannot be changed	*/LOCAL	int	pack_id = 5;		/* Should be a random number	*/LOCAL	char	*SCSIbuf = (char *)-1;#if	!defined(__i386) && !defined(i386) && !defined(mc68000)#define	MISALIGN#endif/*#define	MISALIGN*//*#undef	SG_GET_BUFSIZE*/#if	defined(USE_PG) && !defined(USE_PG_ONLY)#include "scsi-linux-pg.c"#endif#ifdef	MISALIGNLOCAL	int	scsi_getint	__PR((int *ip));#endifLOCAL	int	scsi_send	__PR((int f, struct scg_cmd *sp));LOCAL	BOOL	sg_setup	__PR((int f, int busno, int tgt, int tlun));LOCAL	void	sg_initdev	__PR((int f));LOCAL	int	sg_mapbus	__PR((int ino));LOCAL	BOOL	sg_mapdev	__PR((int f, int *busp, int *tgtp, int *lunp,							int *chanp, int *inop));LOCAL	void	sg_settimeout	__PR((int f, int timeout));EXPORTint scsi_open(device, busno, tgt, tlun)	char	*device;	int	busno;	int	tgt;	int	tlun;{	register int	f;	register int	i;	register int	b;	register int	t;	register int	l;	register int	nopen = 0;	char		devname[64];	for (b=0; b < MAX_SCG; b++) {		buscookies[b] = (short)-1;		for (t=0; t < MAX_TGT; t++) {			for (l=0; l < MAX_LUN ; l++)				scgfiles[b][t][l] = (short)-1;		}	}	if (*device != '\0' || (busno == -2 && tgt == -2))		goto openbydev;	if (busno >= 0 && tgt >= 0 && tlun >= 0) {		if (busno >= MAX_SCG || tgt >= MAX_TGT || tlun >= MAX_LUN)			return (-1);	}	for (i=0; i < 32; i++) {		sprintf(devname, "/dev/sg%d", i);		f = open(devname, 2);		if (f < 0) {			if (errno != ENOENT && errno != ENXIO && errno != ENODEV)				comerr("Cannot open '%s'.\n", devname);		} else {			if (sg_setup(f, busno, tgt, tlun))				return (++nopen);			if (busno < 0 && tgt < 0 && tlun < 0)				nopen++;		}	}	if (nopen == 0) for (i=0; i <= 25; i++) {		sprintf(devname, "/dev/sg%c", i+'a');		f = open(devname, 2);		if (f < 0) {			if (errno != ENOENT && errno != ENXIO && errno != ENODEV)				comerr("Cannot open '%s'.\n", devname);		} else {			if (sg_setup(f, busno, tgt, tlun))				return (++nopen);			if (busno < 0 && tgt < 0 && tlun < 0)				nopen++;		}	}openbydev:	if (*device != '\0') {		f = open(device, 2);		if (f < 0 && errno == ENOENT)			goto openpg;		if (!sg_mapdev(f, &busno, &tgt, &tlun, 0, 0)) {			close(f);			goto openpg;		}		if (scsibus < 0)			scsibus = busno;		if (target < 0)			target = tgt;		if (lun < 0)			lun = tlun;		if (sg_setup(f, busno, tgt, tlun))			return (++nopen);	}openpg:#ifdef	USE_PG	nopen += pg_open(device, busno, tgt, tlun);#endif	return (nopen);}LOCAL BOOLsg_setup(f, busno, tgt, tlun)	int	f;	int	busno;	int	tgt;	int	tlun;{	int	n;	int	Chan;	int	Ino;	int	Bus;	int	Target;	int	Lun;	BOOL	onetarget = FALSE;	if (scsibus >= 0 && target >= 0 && lun >= 0)		onetarget = TRUE;	sg_mapdev(f, &Bus, &Target, &Lun, &Chan, &Ino);	/*	 * For old kernels try to make the best guess.	 */	Ino |= Chan << 8;	n = sg_mapbus(Ino);	if (Bus == -1) {		Bus = n;		if (debug)			printf("SCSI Bus: %d (mapped from %d)\n", Bus, Ino);	}	if (scgfiles[Bus][Target][Lun] == (short)-1)		scgfiles[Bus][Target][Lun] = (short)f;	if (onetarget) {		if (Bus == busno && Target == tgt && Lun == tlun) {			sg_initdev(f);			scgfile = f;	/* remember file for ioctl's */			return (TRUE);		} else {			scgfiles[Bus][Target][Lun] = (short)-1;			close(f);		}	} else {		sg_initdev(f);		if (scgfile < 0)			scgfile = f;	/* remember file for ioctl's */	}	return (FALSE);}LOCAL voidsg_initdev(f)	int	f;{	struct sg_rep {		struct sg_header	hd;		unsigned char		rbuf[100];	} sg_rep;	int	n;	/* Eat any unwanted garbage from prior use of this device */	n = fcntl(f, F_GETFL);	/* Be very proper about this */	fcntl(f, F_SETFL, n|O_NONBLOCK);	fillbytes((caddr_t)&sg_rep, sizeof(struct sg_header), '\0');	sg_rep.hd.reply_len = sizeof(struct sg_header);	while (read(f, &sg_rep, sizeof(sg_rep)) >= 0 || errno != EAGAIN)		;	fcntl(f, F_SETFL, n);	sg_settimeout(f, deftimeout);}LOCAL intsg_mapbus(ino)	int	ino;{	register int	i;	for (i=0; i < MAX_SCG; i++) {		if (buscookies[i] == (short)-1) {			buscookies[i] = ino;			return (i);		}		if (buscookies[i] == ino)			return (i);	}	return (0);}LOCAL BOOLsg_mapdev(f, busp, tgtp, lunp, chanp, inop)	int	f;	int	*busp;	int	*tgtp;	int	*lunp;	int	*chanp;	int	*inop;{	struct	sg_id {		long	l1; /* target | lun << 8 | channel << 16 | low_ino << 24 */		long	l2; /* Unique id */	} sg_id;	int	Chan;	int	Ino;	int	Bus;	int	Target;	int	Lun;	if (ioctl(f, SCSI_IOCTL_GET_IDLUN, &sg_id))		return (FALSE);	if (debug)		printf("l1: 0x%lX l2: 0x%lX\n", sg_id.l1, sg_id.l2);	if (ioctl(f, SCSI_IOCTL_GET_BUS_NUMBER, &Bus) < 0) {		Bus = -1;	}	Target	= sg_id.l1 & 0xFF;	Lun	= (sg_id.l1 >> 8) & 0xFF;	Chan	= (sg_id.l1 >> 16) & 0xFF;	Ino	= (sg_id.l1 >> 24) & 0xFF;	if (debug) {		printf("Bus: %d Target: %d Lun: %d Chan: %d Ino: %d\n",				Bus, Target, Lun, Chan, Ino);	}	*busp = Bus;	*tgtp = Target;	*lunp = Lun;	if (chanp)		*chanp = Chan;	if (inop)		*inop = Ino;	return (TRUE);}LOCAL longscsi_maxdma(){	long maxdma = MAX_DMA_LINUX;#ifdef	SG_GET_BUFSIZE	/*	 * We assume that all /dev/sg instances use the same	 * maximum buffer size.	 */	if ((maxdma = ioctl(scgfile, SG_GET_BUFSIZE, 0)) < 0) {		if (scgfile >= 0) {			maxdma = MAX_DMA_LINUX;		}	}#endif#ifdef	USE_PG	if (scsibus == pgbus)		return (pg_maxdma());	if ((scsibus < 0) && (pg_maxdma() < maxdma))		return (pg_maxdma());#endif	return (maxdma);}EXPORT void *scsi_getbuf(amt)	long	amt;{	char	*ret;	if (scg_maxdma == 0)		scg_maxdma = scsi_maxdma();

⌨️ 快捷键说明

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