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

📄 scsi-linux-sg.c

📁 创建一个符合iso-9660标准的iso文件系统
💻 C
📖 第 1 页 / 共 3 页
字号:
/* @(#)scsi-linux-sg.c	1.52 00/07/03 Copyright 1997 J. Schilling */#ifndef lintstatic	char __sccsid[] =	"@(#)scsi-linux-sg.c	1.52 00/07/03 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 by *		H. Ei遞eld & J. Schilling *	Although this enhanced version has been announced to Linus and Alan, *	there was no reaction at all. * *	About half a year later there occured a version in the official *	Linux that was also called version 2. The interface of this version *	looks like a playground - the enhancements from this version are *	more or less useless for a portable real-world program. * *	With Linux 2.4 the official version of the sg driver is called 3.x *	and seems to be usable again. The main problem now is the curious *	interface that is provided to raise the DMA limit from 32 kB to a *	more reasonable value. To do this in a reliable way, a lot of actions *	are required. * *	Warning: you may change this source, but if you do that *	you need to change the _scg_version and _scg_auth* string below. *	You may not return "schily" for an SCG_AUTHOR request anymore. *	Choose your name instead of "schily" and make clear that the version *	string is related to a modified source. * *	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. */#include <linux/version.h>#ifndef LINUX_VERSION_CODE	/* Very old kernel? */#	define LINUX_VERSION_CODE 0#endif#if LINUX_VERSION_CODE >= 0x01031a /* <linux/scsi.h> introduced in 1.3.26 */#if LINUX_VERSION_CODE >= 0x020000 /* <scsi/scsi.h> introduced somewhere. *//* Need to fine tune the ifdef so we get the transition point right. */#include <scsi/scsi.h>#else#include <linux/scsi.h>#endif#else#define __KERNEL__#include <linux/fs.h>#undef __KERNEL__#include "block/blk.h"#include "scsi/scsi.h"#endif#include "scsi/sg.h"/* *	Warning: you may change this source, but if you do that *	you need to change the _scg_version and _scg_auth* string below. *	You may not return "schily" for an SCG_AUTHOR request anymore. *	Choose your name instead of "schily" and make clear that the version *	string is related to a modified source. */LOCAL	char	_scg_trans_version[] = "scsi-linux-sg.c-1.52";	/* The version for this transport*/#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/* *  These indicate the error that occurred, and what is available. */#ifndef DRIVER_BUSY#define DRIVER_BUSY         0x01#define DRIVER_SOFT         0x02#define DRIVER_MEDIA        0x03#define DRIVER_ERROR        0x04 #define DRIVER_INVALID      0x05#define DRIVER_TIMEOUT      0x06#define DRIVER_HARD         0x07#define DRIVER_SENSE        0x08#endif/* * XXX Should add extra space in buscookies and scgfiles for a "PP bus" * XXX and for two "ATAPI busses". */#define	MAX_SCG		16	/* Max # of SCSI controllers */#define	MAX_TGT		16#define	MAX_LUN		8struct scg_local {	int	scgfile;		/* Used for SG_GET_BUFSIZE ioctl()*/	short	scgfiles[MAX_SCG][MAX_TGT][MAX_LUN];	short	buscookies[MAX_SCG];	int	pgbus;	int	pack_id;		/* Should be a random number	*/	int	drvers;	int	isold;	long	xbufsize;	char	*xbuf;	char	*SCSIbuf;};#define scglocal(p)	((struct scg_local *)((p)->local)) #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	*/#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((SCSI *scgp, int f, struct scg_cmd *sp));#ifdef	SG_IOLOCAL	int	scsi_rwsend	__PR((SCSI *scgp, int f, struct scg_cmd *sp));#endifLOCAL	BOOL	sg_setup	__PR((SCSI *scgp, int f, int busno, int tgt, int tlun));LOCAL	void	sg_initdev	__PR((SCSI *scgp, int f));LOCAL	int	sg_mapbus	__PR((SCSI *scgp, int busno, int ino));LOCAL	BOOL	sg_mapdev	__PR((SCSI *scgp, int f, int *busp, int *tgtp, int *lunp,							int *chanp, int *inop));LOCAL	void	sg_settimeout	__PR((int f, int timeout));/* * Return version information for the low level SCSI transport code. * This has been introduced to make it easier to trace down problems * in applications. */EXPORT char *scg__version(scgp, what)	SCSI	*scgp;	int	what;{	if (scgp != (SCSI *)0) {		switch (what) {		case SCG_VERSION:			return (_scg_trans_version);		/*		 * If you changed this source, you are not allowed to		 * return "schily" for the SCG_AUTHOR request.		 */		case SCG_AUTHOR:			return (_scg_auth_schily);		case SCG_SCCS_ID:			return (__sccsid);		}	}	return ((char *)0);}EXPORT intscsi_open(scgp, device, busno, tgt, tlun)	SCSI	*scgp;	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];	if (busno >= MAX_SCG || tgt >= MAX_TGT || tlun >= MAX_LUN) {		errno = EINVAL;		if (scgp->errstr)			js_snprintf(scgp->errstr, SCSI_ERRSTR_SIZE,				"Illegal value for busno, target or lun '%d,%d,%d'",				busno, tgt, tlun);		return (-1);	}	if (scgp->local == NULL) {		scgp->local = malloc(sizeof(struct scg_local));		if (scgp->local == NULL)			return (0);		scglocal(scgp)->scgfile = -1;		scglocal(scgp)->pgbus = -2;		scglocal(scgp)->SCSIbuf = (char *)-1;		scglocal(scgp)->pack_id = 5;		scglocal(scgp)->drvers = -1;		scglocal(scgp)->isold = -1;		scglocal(scgp)->xbufsize = 0L;		scglocal(scgp)->xbuf = NULL;		for (b=0; b < MAX_SCG; b++) {			scglocal(scgp)->buscookies[b] = (short)-1;			for (t=0; t < MAX_TGT; t++) {				for (l=0; l < MAX_LUN ; l++)					scglocal(scgp)->scgfiles[b][t][l] = (short)-1;			}		}	}	if ((device != NULL && *device != '\0') || (busno == -2 && tgt == -2))		goto openbydev;	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) {				if (scgp->errstr)					js_snprintf(scgp->errstr, SCSI_ERRSTR_SIZE,							"Cannot open '%s'", devname);				return (0);			}		} else {			if (sg_setup(scgp, 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) {				if (scgp->errstr)					js_snprintf(scgp->errstr, SCSI_ERRSTR_SIZE,						"Cannot open '%s'", devname);				return (0);			}		} else {			if (sg_setup(scgp, f, busno, tgt, tlun))				return (++nopen);			if (busno < 0 && tgt < 0 && tlun < 0)				nopen++;		}	}openbydev:	if (device != NULL && *device != '\0') {		f = open(device, 2);		if (f < 0 && errno == ENOENT)			goto openpg;		if (f < 0) {			if (scgp->errstr)				js_snprintf(scgp->errstr, SCSI_ERRSTR_SIZE,					"Cannot open '%s'",					device);			return (0);		}		if (!sg_mapdev(scgp, f, &busno, &tgt, &tlun, 0, 0)) {			close(f);			goto openpg;		}		if (scgp->scsibus < 0)			scgp->scsibus = busno;		if (scgp->target < 0)			scgp->target = tgt;		if (scgp->lun < 0)			scgp->lun = tlun;		if (sg_setup(scgp, f, busno, tgt, tlun))			return (++nopen);	}openpg:#ifdef	USE_PG	nopen += pg_open(scgp, device, busno, tgt, tlun);#endif	if (scgp->debug) for (b=0; b < MAX_SCG; b++) {		printf("Bus: %d cookie: %X\n", b, scglocal(scgp)->buscookies[b]);		for (t=0; t < MAX_TGT; t++) {			for (l=0; l < MAX_LUN ; l++)				if (scglocal(scgp)->scgfiles[b][t][l] != (short)-1)					printf("file (%d,%d,%d): %d\n",						b, t, l, scglocal(scgp)->scgfiles[b][t][l]);		}	}	return (nopen);}EXPORT intscsi_close(scgp)	SCSI	*scgp;{	register int	f;	register int	b;	register int	t;	register int	l;	if (scgp->local == NULL)		return (-1);	for (b=0; b < MAX_SCG; b++) {		if (b == scglocal(scgp)->pgbus)			continue;		scglocal(scgp)->buscookies[b] = (short)-1;		for (t=0; t < MAX_TGT; t++) {			for (l=0; l < MAX_LUN ; l++) {				f = scglocal(scgp)->scgfiles[b][t][l];				if (f >= 0)					close(f);				scglocal(scgp)->scgfiles[b][t][l] = (short)-1;			}		}	}	if (scglocal(scgp)->xbuf != NULL) {		free(scglocal(scgp)->xbuf);		scglocal(scgp)->xbufsize = 0L;		scglocal(scgp)->xbuf = NULL;	}#ifdef	USE_PG	pg_close(scgp);#endif	return (0);}LOCAL BOOLsg_setup(scgp, f, busno, tgt, tlun)	SCSI	*scgp;	int	f;	int	busno;	int	tgt;	int	tlun;{	int	n;	int	Chan;	int	Ino;	int	Bus;	int	Target;	int	Lun;	BOOL	onetarget = FALSE;#ifdef	SG_GET_VERSION_NUM	if (scglocal(scgp)->drvers < 0) {		scglocal(scgp)->drvers = 0;		if (ioctl(f, SG_GET_VERSION_NUM, &n) >= 0) {			scglocal(scgp)->drvers = n;			if (scgp->overbose)				printf("Linux sg driver version: %d.%d.%d\n",        				n/10000, (n%10000)/100, n%100);		}	}#endif	if (scgp->scsibus >= 0 && scgp->target >= 0 && scgp->lun >= 0)		onetarget = TRUE;	sg_mapdev(scgp, f, &Bus, &Target, &Lun, &Chan, &Ino);	/*	 * For old kernels try to make the best guess.	 */	Ino |= Chan << 8;	n = sg_mapbus(scgp, Bus, Ino);	if (Bus == -1) {		Bus = n;

⌨️ 快捷键说明

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