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

📄 scsi-linux-sg.c

📁 另一种方法编辑刻录程序的代码!要的与偶联系呀
💻 C
📖 第 1 页 / 共 2 页
字号:
	if (amt <= 0 || amt > scg_maxdma)		return ((void *)0);	if (debug)		printf("scsi_getbuf: %ld bytes\n", amt);	/*	 * For performance reason, we allocate pagesize()	 * bytes before the SCSI buffer to avoid	 * copying the whole buffer contents when	 * setting up the /dev/sg data structures.	 */	ret = valloc((size_t)(amt+getpagesize()));	if (ret == NULL)		return (ret);	ret += getpagesize();	SCSIbuf = ret;	return ((void *)ret);}EXPORTBOOL scsi_havebus(busno)	int	busno;{	register int	t;	register int	l;	if (busno < 0 || busno >= MAX_SCG)		return (FALSE);	for (t=0; t < MAX_TGT; t++) {		for (l=0; l < MAX_LUN ; l++)			if (scgfiles[busno][t][l] >= 0)				return (TRUE);	}	return (FALSE);}EXPORTint scsi_fileno(busno, tgt, tlun)	int	busno;	int	tgt;	int	tlun;{	if (busno < 0 || busno >= MAX_SCG ||	    tgt < 0 || tgt >= MAX_TGT ||	    tlun < 0 || tlun >= MAX_LUN)		return (-1);	return ((int)scgfiles[busno][tgt][tlun]);}EXPORTint scsi_isatapi(){#ifdef	USE_PG	if (scsibus == pgbus)		return (pg_isatapi());#endif#ifdef	SG_EMULATED_HOST	{	int	emulated = FALSE;	int	f = scsi_fileno(scsibus, target, lun);	if (ioctl(f, SG_EMULATED_HOST, &emulated) >= 0)		return (emulated != 0);	}#endif	return (-1);}EXPORTint scsireset(){#ifdef	USE_PG	if (scsibus == pgbus)		return (pg_reset());#endif	/*	 * Do we have a SCSI reset in the Linux sg driver?	 */	return (-1);}LOCAL voidsg_settimeout(f, tmo)	int	f;	int	tmo;{	tmo *= HZ;	if (tmo)		tmo += HZ/2;	if (ioctl(f, SG_SET_TIMEOUT, &tmo) < 0)		comerr("Cannot set SG_SET_TIMEOUT.\n");}/* * Get misaligned int. * Needed for all recent processors (sparc/ppc/alpha) * because the /dev/sg design forces us to do misaligned * reads of integers. */#ifdef	MISALIGNLOCAL intscsi_getint(ip)	int	*ip;{		 int	ret;	register char	*cp = (char *)ip;	register char	*tp = (char *)&ret;	register int	i;	for (i = sizeof(int); --i >= 0; )		*tp++ = *cp++;		return (ret);}#define	GETINT(a)	scsi_getint(&(a))#else#define	GETINT(a)	(a)#endifLOCAL intscsi_send(int f, struct scg_cmd *sp){	struct sg_rq	*sgp;	struct sg_rq	*sgp2;	int	i;	int	pack_len;	int	reply_len;	int	amt = sp->cdb_len;	struct sg_rq {		struct sg_header	hd;		unsigned char		buf[MAX_DMA_LINUX+SCG_MAX_CMD];	} sg_rq;#ifdef	SG_GET_BUFSIZE		/* We may use a 'sg' version 2 driver	*/	char	driver_byte;	char	host_byte;	char	msg_byte;	char	status_byte;#endif	if (f < 0) {		sp->error = SCG_FATAL;		return (0);	}#ifdef	USE_PG	if (scsibus == pgbus)		return (pg_send(f, sp));#endif	if (sp->timeout != deftimeout)		sg_settimeout(f, sp->timeout);	sgp2 = sgp = &sg_rq;	if (sp->addr == SCSIbuf) {		sgp = (struct sg_rq *)			(SCSIbuf - (sizeof(struct sg_header) + amt));		sgp2 = (struct sg_rq *)			(SCSIbuf - (sizeof(struct sg_header)));	} else {		if (debug) {			printf("DMA addr: 0x%8.8lX size: %d - using copy buffer\n",				(long)sp->addr, sp->size);		}		if (sp->size > (int)(sizeof(sg_rq.buf) - SCG_MAX_CMD)) {			errno = ENOMEM;			return (-1);		}	}	/*	 * This is done to avoid misaligned access of sgp->some_int	 */	pack_len = sizeof(struct sg_header) + amt;	reply_len = sizeof(struct sg_header);	if (sp->flags & SCG_RECV_DATA) {		reply_len += sp->size;	} else {		pack_len += sp->size;	}#ifdef	MISALIGN	/*	 * sgp->some_int may be misaligned if (sp->addr == SCSIbuf)	 * This is no problem on Intel porocessors, however	 * all other processors don't like it.	 * sizeof(struct sg_header) + amt is usually not a multiple of	 * sizeof(int). For this reason, we fill in the values into sg_rq	 * which is always corectly aligned and then copy it to the real	 * location if this location differs from sg_rq.	 * Never read/write directly to sgp->some_int !!!!!	 */	fillbytes((caddr_t)&sg_rq, sizeof(struct sg_header), '\0');	sg_rq.hd.pack_len = pack_len;	sg_rq.hd.reply_len = reply_len;	sg_rq.hd.pack_id = pack_id++;/*	sg_rq.hd.result = 0;	not needed because of fillbytes() */	if ((caddr_t)&sg_rq != (caddr_t)sgp)		movebytes((caddr_t)&sg_rq, (caddr_t)sgp, sizeof(struct sg_header));#else	fillbytes((caddr_t)sgp, sizeof(struct sg_header), '\0');	sgp->hd.pack_len = pack_len;	sgp->hd.reply_len = reply_len;	sgp->hd.pack_id = pack_id++;/*	sgp->hd.result = 0;	not needed because of fillbytes() */#endif	if (amt == 12)		sgp->hd.twelve_byte = 1;	for (i = 0; i < amt; i++ ) {		sgp->buf[i] = sp->cdb.cmd_cdb[i];;	}	if (!(sp->flags & SCG_RECV_DATA)) {		if ((void *)sp->addr != (void *)&sgp->buf[amt])			movebytes(sp->addr, &sgp->buf[amt], sp->size);		amt += sp->size;	}#ifdef	SG_GET_BUFSIZE	sgp->hd.want_new  = 1;			/* Order new behaviour	*/	sgp->hd.cdb_len	  = sp->cdb_len;	/* Set CDB length	*/	if (sp->sense_len > SG_MAX_SENSE)		sgp->hd.sense_len = SG_MAX_SENSE;	else		sgp->hd.sense_len = sp->sense_len;#endif	i = sizeof(struct sg_header) + amt;	if ((amt = write(f, sgp, i)) < 0) {			/* write */		sg_settimeout(f, deftimeout);		return (-1);	} else if (amt != i) {		errmsg("scsi_send(%s) wrote %d bytes (expected %d).\n",						scsi_command, amt, i);	}	if (sp->addr == SCSIbuf) {		movebytes(sgp, sgp2, sizeof(struct sg_header));		sgp = sgp2;	}	sgp->hd.sense_buffer[0] = 0;	if ((amt = read(f, sgp, reply_len)) < 0) {		/* read */		sg_settimeout(f, deftimeout);		return (-1);	}	if (sp->flags & SCG_RECV_DATA && ((void *)sgp->buf != (void *)sp->addr)) {		movebytes(sgp->buf, sp->addr, sp->size);	}	sp->ux_errno = GETINT(sgp->hd.result);		/* Unaligned read */	sp->error = SCG_NO_ERROR;#ifdef	SG_GET_BUFSIZE	if (sgp->hd.grant_new) {		sp->sense_count = sgp->hd.sense_len;		pack_len    = GETINT(sgp->hd.sg_cmd_status);	/* Unaligned read */		driver_byte = (pack_len  >> 24) & 0xFF;		host_byte   = (pack_len  >> 16) & 0xFF;		msg_byte    = (pack_len  >> 8) & 0xFF;		status_byte =  pack_len  & 0xFF;		switch (host_byte) {		case DID_OK:				if (sgp->hd.sense_buffer[0] != 0) {					/*					 * The Linux SCSI system up to 2.1.xx					 * trashes the status byte in the					 * kernel. Until this gets fixed, we					 * need this hack.					 */					sp->error = SCG_RETRYABLE;					status_byte = 2;					sgp->hd.sense_len = SG_MAX_SENSE;				}				break;		case DID_NO_CONNECT:	/* Arbitration won, retry NO_CONNECT? */		case DID_BAD_TARGET:				sp->error = SCG_FATAL;				break;			case DID_TIME_OUT:				sp->error = SCG_TIMEOUT;				break;		default:				sp->error = SCG_RETRYABLE;				break;		}		if ((host_byte != DID_OK || status_byte != 0) && sp->ux_errno == 0)			sp->ux_errno = EIO;		sp->u_scb.cmd_scb[0] = status_byte;		if (status_byte & 2) {			sp->sense_count = sgp->hd.sense_len;			movebytes(sgp->hd.sense_buffer, sp->u_sense.cmd_sense, sp->sense_count);		}	} else#endif	{		if (GETINT(sgp->hd.result) == EBUSY) {	/* Unaligned read */			struct timeval to;			to.tv_sec = sp->timeout;			to.tv_usec = 500000;			scsitimes();			if (cmdstop.tv_sec < to.tv_sec ||			    (cmdstop.tv_sec == to.tv_sec &&				cmdstop.tv_usec < to.tv_usec)) {				sp->ux_errno = 0;				sp->error = SCG_TIMEOUT;	/* a timeout */			} else {				sp->error = SCG_RETRYABLE;	/* may be BUS_BUSY */			}		}		if (sp->flags & SCG_RECV_DATA)			sp->resid = (sp->size + sizeof(struct sg_header)) - amt;		else			sp->resid = 0;	/* sg version1 cannot return DMA resid count */		if (sgp->hd.sense_buffer[0] != 0) {			sp->error = SCG_RETRYABLE;			sp->scb.chk = 1;			sp->sense_count = SG_MAX_SENSE;			movebytes(sgp->hd.sense_buffer, sp->u_sense.cmd_sense, sp->sense_count);			if (sp->ux_errno == 0)				sp->ux_errno = EIO;		}	}	if (verbose > 0 && debug) {#ifdef	SG_GET_BUFSIZE		printf("status: %X pack_len: %d, reply_len: %d pack_id: %d result: %d wn: %d gn: %d cdb_len: %d sense_len: %d sense[0]: %02X\n",				GETINT(sgp->hd.sg_cmd_status),				GETINT(sgp->hd.pack_len),				GETINT(sgp->hd.reply_len),				GETINT(sgp->hd.pack_id),				GETINT(sgp->hd.result),				sgp->hd.want_new,				sgp->hd.grant_new,				sgp->hd.cdb_len,				sgp->hd.sense_len,					sgp->hd.sense_buffer[0]);#else		printf("pack_len: %d, reply_len: %d pack_id: %d result: %d sense[0]: %02X\n",				GETINT(sgp->hd.pack_len),				GETINT(sgp->hd.reply_len),				GETINT(sgp->hd.pack_id),				GETINT(sgp->hd.result),				sgp->hd.sense_buffer[0]);#endif#ifdef	DEBUG		printf("sense: ");		for (i=0; i < 16; i++)			printf("%02X ", sgp->hd.sense_buffer[i]);		printf("\n");#endif	}	if (sp->timeout != deftimeout)		sg_settimeout(f, deftimeout);	return 0;}

⌨️ 快捷键说明

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