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

📄 scsitransp.c

📁 创建一个符合iso-9660标准的iso文件系统
💻 C
字号:
/* @(#)scsitransp.c	1.53 00/07/01 Copyright 1988,1995,2000 J. Schilling */#ifndef lintstatic	char sccsid[] =	"@(#)scsitransp.c	1.53 00/07/01 Copyright 1988,1995,2000 J. Schilling";#endif/* *	SCSI user level command transport routines (generic part). * *	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) 1988,1995,2000 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 <mconfig.h>#ifdef	HAVE_SYS_PARAM_H#include <sys/param.h>	/* XXX nonportable to use u_char */#endif#include <stdio.h>#include <standard.h>#include <stdxlib.h>#include <unixstd.h>#include <errno.h>#include <timedefs.h>#include <sys/ioctl.h>#include <fctldefs.h>#include <schily.h>#include <scg/scgcmd.h>#include <scg/scsireg.h>#include <scg/scsitransp.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_version[]		= "0.1";	/* The global libscg version	*/LOCAL	char	_scg_auth_schily[]	= "schily";	/* The author for this module	*/#define	DEFTIMEOUT	20	/* Default timeout for SCSI command transport */EXPORT	char	*scg_version	__PR((SCSI *scgp, int what));EXPORT	char	*scg__version	__PR((SCSI *scgp, int what));EXPORT	int	scsi_open	__PR((SCSI *scgp, char *device, int busno, int tgt, int tlun));EXPORT	int	scsi_close	__PR((SCSI *scgp));LOCAL	long	scsi_maxdma	__PR((SCSI *scgp, long amt));EXPORT	BOOL	scsi_havebus	__PR((SCSI *scgp, int));EXPORT	int	scsi_fileno	__PR((SCSI *scgp, int, int, int));EXPORT	int	scsi_initiator_id __PR((SCSI *scgp));EXPORT	int	scsi_isatapi	__PR((SCSI *scgp));EXPORT	int	scsireset	__PR((SCSI *scgp));EXPORT	void	*scsi_getbuf	__PR((SCSI *scgp, long));EXPORT	void	scsi_freebuf	__PR((SCSI *scgp));EXPORT	long	scsi_bufsize	__PR((SCSI *scgp, long));EXPORT	void	scsi_setnonstderrs __PR((SCSI *scgp, const char **));EXPORT	BOOL	scsi_yes	__PR((char *));#ifdef	nononoLOCAL	void	scsi_sighandler	__PR((int));#endifEXPORT	int	scsicmd		__PR((SCSI *scgp));EXPORT	int	scsigetresid	__PR((SCSI *scgp));LOCAL	void	scsitimes	__PR((SCSI *scgp));LOCAL	BOOL	scsierr		__PR((SCSI *scgp));LOCAL	int	scsicheckerr	__PR((SCSI *scgp));EXPORT	void	scsiprinterr	__PR((SCSI *scgp));EXPORT	void	scsiprintcdb	__PR((SCSI *scgp));EXPORT	void	scsiprintwdata	__PR((SCSI *scgp));EXPORT	void	scsiprintrdata	__PR((SCSI *scgp));EXPORT	void	scsiprintresult	__PR((SCSI *scgp));EXPORT	void	scsiprintstatus	__PR((SCSI *scgp));EXPORT	void	scsiprbytes	__PR((char *, unsigned char *, int));EXPORT	void	scsiprsense	__PR((unsigned char *, int));EXPORT	int	scsi_sense_key	__PR((SCSI *scgp));EXPORT	int	scsi_sense_code	__PR((SCSI *scgp));EXPORT	int	scsi_sense_qual	__PR((SCSI *scgp));EXPORT	void	scsiprintdev	__PR((struct scsi_inquiry *));/* * Emulate the functionality of /dev/scg? with the local * SCSI user land implementation. */#include "scsihack.c"/* * Return version information for the SCSI transport code. * This has been introduced to make it easier to trace down problems * in applications. * * If scgp is NULL, return general library version information. * If scgp is != NULL, return version information for the low level transport. */EXPORT char *scg_version(scgp, what)	SCSI	*scgp;	int	what;{	if (scgp == (SCSI *)0) {		switch (what) {		case SCG_VERSION:			return (_scg_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);		default:			return ((char *)0);		}	}	return (scg__version(scgp, what));}EXPORT longscsi_bufsize(scgp, amt)	SCSI	*scgp;	long	amt;{	long	maxdma;	maxdma = scsi_maxdma(scgp, amt);	if (amt <= 0 || amt > maxdma)		amt = maxdma;	scgp->maxdma = maxdma;	scgp->maxbuf = amt;	return (amt);}EXPORT voidscsi_setnonstderrs(scgp, vec)	SCSI	*scgp;	const char **vec;{	scgp->nonstderrs = vec;}EXPORTBOOL scsi_yes(msg)	char	*msg;{	char okbuf[10];	printf("%s", msg);	flush();	if (getline(okbuf, sizeof(okbuf)) == EOF)		exit(EX_BAD);	if(streql(okbuf, "y") || streql(okbuf, "yes") ||	   streql(okbuf, "Y") || streql(okbuf, "YES"))		return(TRUE);	else		return(FALSE);}#ifdef	nononoLOCAL voidscsi_sighandler(sig)	int	sig;{	printf("\n");	if (scsi_running) {		printf("Running command: %s\n", scsi_command);		printf("Resetting SCSI - Bus.\n");		if (scsireset(scgp) < 0)			errmsg("Cannot reset SCSI - Bus.\n");	}	if (scsi_yes("EXIT ? "))		exit(sig);}#endifEXPORTint scsicmd(scgp)	SCSI	*scgp;{		 int		f;		 int		ret;	register struct	scg_cmd	*scmd = scgp->scmd;	f = scsi_fileno(scgp, scgp->scsibus, scgp->target, scgp->lun);	scmd->kdebug = scgp->kdebug;	if (scmd->timeout == 0 || scmd->timeout < scgp->deftimeout)		scmd->timeout = scgp->deftimeout;	if (scgp->disre_disable)		scmd->flags &= ~SCG_DISRE_ENA;	if (scgp->noparity)		scmd->flags |= SCG_NOPARITY;	scmd->u_sense.cmd_sense[0] = 0;		/* Paranioa */	if (scgp->verbose) {		printf("\nExecuting '%s' command on Bus %d Target %d, Lun %d timeout %ds\n",			scgp->cmdname, scgp->scsibus, scgp->target, scmd->cdb.g0_cdb.lun,			scmd->timeout);		scsiprintcdb(scgp);		if (scgp->verbose > 1)			scsiprintwdata(scgp);		flush();	}	if (scgp->running) {		if (scgp->curcmdname) {			error("Currently running '%s' command.\n",							scgp->curcmdname);		}		raisecond("SCSI ALREADY RUNNING !!", 0L);	}	gettimeofday(scgp->cmdstart, (struct timezone *)0);	scgp->curcmdname = scgp->cmdname;	scgp->running = TRUE;	ret = scsi_send(scgp, f, scmd);	scgp->running = FALSE;	scsitimes(scgp);	if (ret < 0) {		/*		 * Old /dev/scg versions will not allow to access targets > 7.		 * Include a workaround to make this non fatal.		 */		if (scgp->target < 8 || geterrno() != EINVAL)			comerr("Cannot send SCSI cmd via ioctl\n");		if (scmd->ux_errno == 0)			scmd->ux_errno = geterrno();		if (scmd->error == SCG_NO_ERROR)			scmd->error = SCG_FATAL;		if (scgp->debug) {			errmsg("ret < 0 errno: %d ux_errno: %d error: %d\n",					geterrno(), scmd->ux_errno, scmd->error);		}	}	ret = scsicheckerr(scgp);	if (scgp->verbose || (ret && scgp->silent <= 0)) {		scsiprintresult(scgp);	}	return (ret);}EXPORTint scsigetresid(scgp)	SCSI	*scgp;{	return (scgp->scmd->resid);}LOCALvoid scsitimes(scgp)	SCSI	*scgp;{	struct timeval	*stp = scgp->cmdstop;	gettimeofday(stp, (struct timezone *)0);	stp->tv_sec -= scgp->cmdstart->tv_sec;	stp->tv_usec -= scgp->cmdstart->tv_usec;	while (stp->tv_usec < 0) {		stp->tv_sec -= 1;		stp->tv_usec += 1000000;	}}LOCAL BOOLscsierr(scgp)	SCSI	*scgp;{	register struct scg_cmd *cp = scgp->scmd;	if(cp->error != SCG_NO_ERROR ||				cp->ux_errno != 0 ||				*(u_char *)&cp->scb != 0 ||				cp->u_sense.cmd_sense[0] != 0)	/* Paranioa */		return (TRUE);	return (FALSE);}LOCAL intscsicheckerr(scgp)	SCSI	*scgp;{	register int ret;	ret = 0;	if(scsierr(scgp)) {		if (!scgp->silent || scgp->verbose)			scsiprinterr(scgp);		ret = -1;	}	if ((!scgp->silent || scgp->verbose) && scgp->scmd->resid) {		printf("resid: %d\n", scgp->scmd->resid);		flush();	}	return (ret);}EXPORT voidscsiprinterr(scgp)	SCSI	*scgp;{	register struct scg_cmd *cp = scgp->scmd;	register char	*err;		char	errbuf[64];	switch (cp->error) {	case SCG_NO_ERROR :	err = "no error"; break;	case SCG_RETRYABLE:	err = "retryable error"; break;	case SCG_FATAL    :	err = "fatal error"; break;				/*				 * We need to cast timeval->* to long because				 * of the broken sys/time.h in Linux.				 */	case SCG_TIMEOUT  :	sprintf(errbuf,					"cmd timeout after %ld.%03ld (%d) s",					(long)scgp->cmdstop->tv_sec,					(long)scgp->cmdstop->tv_usec/1000,								cp->timeout);				err = errbuf;				break;	default:		sprintf(errbuf, "error: %d", cp->error);				err = errbuf;	}	errmsgno(cp->ux_errno, "%s: scsi sendcmd: %s\n", scgp->cmdname, err);	scsiprintcdb(scgp);	if (cp->error <= SCG_RETRYABLE)		scsiprintstatus(scgp);	if (cp->scb.chk) {		scsiprsense((u_char *)&cp->sense, cp->sense_count);		scsierrmsg(scgp, &cp->sense, &cp->scb, -1, scgp->nonstderrs);	}	flush();}EXPORT voidscsiprintcdb(scgp)	SCSI	*scgp;{	scsiprbytes("CDB: ", scgp->scmd->cdb.cmd_cdb, scgp->scmd->cdb_len);}EXPORT voidscsiprintwdata(scgp)	SCSI	*scgp;{	register struct	scg_cmd	*scmd = scgp->scmd;	if (scmd->size > 0 && (scmd->flags & SCG_RECV_DATA) == 0) {		printf("Sending %d (0x%X) bytes of data.\n",			scmd->size, scmd->size);		scsiprbytes("Write Data: ",			(Uchar *)scmd->addr,			scmd->size > 100 ? 100 : scmd->size);	}}EXPORT voidscsiprintrdata(scgp)	SCSI	*scgp;{	register struct	scg_cmd	*scmd = scgp->scmd;	if (scmd->size > 0 && (scmd->flags & SCG_RECV_DATA) != 0) {		printf("Got %d (0x%X), expecting %d (0x%X) bytes of data.\n",			scmd->size-scmd->resid, scmd->size-scmd->resid,			scmd->size, scmd->size);		scsiprbytes("Received Data: ",			(Uchar *)scmd->addr,			(scmd->size-scmd->resid) > 100 ?			100 : (scmd->size-scmd->resid));	}}EXPORT voidscsiprintresult(scgp)	SCSI	*scgp;{	printf("cmd finished after %ld.%03lds timeout %ds\n",		(long)scgp->cmdstop->tv_sec,		(long)scgp->cmdstop->tv_usec/1000,		scgp->scmd->timeout);	if (scgp->verbose > 1)		scsiprintrdata(scgp);	flush();}EXPORTvoid scsiprintstatus(scgp)	SCSI	*scgp;{	register struct scg_cmd *cp = scgp->scmd;	error("status: 0x%x ", *(u_char *)&cp->scb);#ifdef	SCSI_EXTENDED_STATUS	if (cp->scb.ext_st1)		error("0x%x ", ((u_char *)&cp->scb)[1]);	if (cp->scb.ext_st2)		error("0x%x ", ((u_char *)&cp->scb)[2]);#endif	error("(");	switch (*(u_char *)&cp->scb & 036) {	case 0  : error("GOOD STATUS"); break;	case 02 : error("CHECK CONDITION"); break;	case 04 : error("CONDITION MET/GOOD"); break;	case 010: error("BUSY"); break;	case 020: error("INTERMEDIATE GOOD STATUS"); break;	case 024: error("INTERMEDIATE CONDITION MET/GOOD"); break;	case 030: error("RESERVATION CONFLICT"); break;	default : error("Reserved"); break;	}#ifdef	SCSI_EXTENDED_STATUS	if (cp->scb.ext_st1 && cp->scb.ha_er)		error(" host adapter detected error");#endif	error(")\n");}EXPORT voidscsiprbytes(s, cp, n)		char	*s;	register u_char	*cp;	register int	n;{	printf(s);	while (--n >= 0)		printf(" %02X", *cp++);	printf("\n");}EXPORT voidscsiprsense(cp, n)	u_char	*cp;	int	n;{	scsiprbytes("Sense Bytes:", cp, n);}EXPORT intscsi_sense_key(scgp)	SCSI	*scgp;{	register struct scg_cmd *cp = scgp->scmd;	int	key = -1;	if(!scsierr(scgp))		return (0);	if (cp->sense.code >= 0x70)		key = ((struct scsi_ext_sense*)&(cp->sense))->key;	return(key);}EXPORT intscsi_sense_code(scgp)	SCSI	*scgp;{	register struct scg_cmd *cp = scgp->scmd;	int	code = -1;	if(!scsierr(scgp))		return (0);	if (cp->sense.code >= 0x70)		code = ((struct scsi_ext_sense*)&(cp->sense))->sense_code;	else		code = cp->sense.code;	return(code);}EXPORT intscsi_sense_qual(scgp)	SCSI	*scgp;{	register struct scg_cmd *cp = scgp->scmd;	if(!scsierr(scgp))		return (0);	if (cp->sense.code >= 0x70)		return (((struct scsi_ext_sense*)&(cp->sense))->qual_code);	else		return (0);}EXPORTvoid scsiprintdev(ip)	struct	scsi_inquiry *ip;{	if (ip->removable)		printf("Removable ");	if (ip->data_format >= 2) {		switch (ip->qualifier) {		case INQ_DEV_PRESENT:		break;		case INQ_DEV_NOTPR:			printf("not present ");	break;		case INQ_DEV_RES:			printf("reserved ");	break;		case INQ_DEV_NOTSUP:			if (ip->type == INQ_NODEV) {				printf("unsupported\n"); return;			}			printf("unsupported ");	break;		default:			printf("vendor specific %d ", ip->qualifier);		}	}	switch (ip->type) {	case INQ_DASD:		printf("Disk");			break;	case INQ_SEQD:		printf("Tape");			break;	case INQ_PRTD:		printf("Printer");		break;	case INQ_PROCD:		printf("Processor");		break;	case INQ_WORM:		printf("WORM");			break;	case INQ_ROMD:		printf("CD-ROM");		break;	case INQ_SCAN:		printf("Scanner");		break;	case INQ_OMEM:		printf("Optical Storage");	break;	case INQ_JUKE:		printf("Juke Box");		break;	case INQ_COMM:		printf("Communication");	break;	case INQ_IT8_1:		printf("IT8 1");		break;	case INQ_IT8_2:		printf("IT8 2");		break;	case INQ_STARR:		printf("Storage array");	break;	case INQ_ENCL:		printf("Enclosure services");	break;	case INQ_NODEV:		if (ip->data_format >= 2) {			printf("unknown/no device");			break;		} else if (ip->qualifier == INQ_DEV_NOTSUP) {			printf("unit not present");			break;		}	default:		printf("unknown device type 0x%x", ip->type);	}	printf("\n");}

⌨️ 快捷键说明

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