scsitransp.c

来自「刻录光盘的程序」· C语言 代码 · 共 866 行 · 第 1/2 页

C
866
字号
	long	maxdma;	maxdma = scsi_maxdma(scgp);	if (amt <= 0 || amt > maxdma)		return (maxdma);	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 + =
减小字号Ctrl + -
显示快捷键?