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

📄 scsi.c

📁 通用SCSI设备备份/读写程序
💻 C
字号:
/* SCSI.C - Digital Unix-specific SCSI routines.**** TECSys Development, Inc., April 1998**** This module began life as a part of XMCD, an X-windows CD player** program for many platforms. No real functionality from the original XMCD** is present in this module, but in the interest of making certain that** proper credit is given where it may be due, the copyrights and inclusions** from the XMCD module OS_DEC.C are included below.**** The portions of coding in this module ascribable to TECSys Development** are hereby also released under the terms and conditions of version 2** of the GNU General Public License as described below....*//* *   libdi - scsipt SCSI Device Interface Library * *   Copyright (C) 1993-1997  Ti Kan *   E-mail: ti@amb.org * *   This library is free software; you can redistribute it and/or *   modify it under the terms of the GNU Library General Public *   License as published by the Free Software Foundation; either *   version 2 of the License, or (at your option) any later version. * *   This library 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 *   Library General Public License for more details. * *   You should have received a copy of the GNU Library General Public *   License along with this library; if not, write to the Free *   Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *//* *   Digital UNIX (OSF/1) and Ultrix support * *   Contributing author: Matt Thomas *   E-Mail: thomas@lkg.dec.com * *   This software fragment contains code that interfaces the *   application to the Digital UNIX and Ultrix operating systems. *   The term Digital, Ultrix and OSF/1 are used here for identification *   purposes only. */static int		bus = -1,			target = -1,			lun = -1;static int SCSI_OpenDevice(char *DeviceName){	int		fd;	struct stat	stbuf;	int		saverr;	/* Check for validity of device node */	if (stat(DeviceName, &stbuf) < 0) {		FatalError("cannot stat SCSI device '%s' - %m\n", DeviceName);	}	if (!S_ISCHR(stbuf.st_mode)) {		FatalError("device '%s': not appropriate device type - %m\n", DeviceName);	}	if ((fd = open(DeviceName, O_RDONLY | O_NDELAY, 0)) >= 0) {		struct devget	devget;		if (ioctl(fd, DEVIOCGET, &devget) >= 0) {#ifdef __osf__			lun = devget.slave_num % 8;			devget.slave_num /= 8;#else			lun = 0;#endif			target = devget.slave_num % 8;			devget.slave_num /= 8;			bus = devget.slave_num % 8;			(void) close(fd);			if ((fd = open(DEV_CAM, O_RDWR, 0)) >= 0 ||			    (fd = open(DEV_CAM, O_RDONLY, 0)) >= 0) {				return (fd);			}			fd = bus = target = lun = -1;			FatalError("error %d opening SCSI device '%s' - %m\n",					 errno, DEV_CAM);		}		else {			(void) close(fd);			fd = bus = target = lun = -1;			FatalError("error %d on DEVIOCGET ioctl for '%s' - %m\n",					 errno, DeviceName);		}	}	else {		saverr = errno;		fd = bus = target = lun = -1;		FatalError("cannot open SCSI device '%s', error %d - %m\n",				DeviceName, saverr);	}	fd = bus = target = lun = -1;	return -1;}static void SCSI_CloseDevice(char *DeviceName,			     int DeviceFD){	(void) close(DeviceFD);	bus = target = lun = -1;}static int SCSI_ExecuteCommand(int DeviceFD,			       Direction_T Direction,			       CDB_T *CDB,			       int CDB_Length,			       void *DataBuffer,			       int DataBufferLength,			       RequestSense_T *RequestSense){	UAGT_CAM_CCB	uagt;	CCB_SCSIIO	ccb;	if (DeviceFD < 0)		return -1;	(void) memset(&uagt, 0, sizeof(uagt));	(void) memset(&ccb, 0, sizeof(ccb));	/* Setup the user agent ccb */	uagt.uagt_ccb = (CCB_HEADER *) &ccb;	uagt.uagt_ccblen = sizeof(CCB_SCSIIO);	/* Setup the scsi ccb */	(void) memcpy((unsigned char  *) ccb.cam_cdb_io.cam_cdb_bytes,				CDB, CDB_Length);	ccb.cam_cdb_len = CDB_Length;	ccb.cam_ch.my_addr = (CCB_HEADER *) &ccb;	ccb.cam_ch.cam_ccb_len = sizeof(CCB_SCSIIO);	ccb.cam_ch.cam_func_code = XPT_SCSI_IO;	if (DataBuffer != NULL && DataBufferLength > 0) {		ccb.cam_ch.cam_flags |=			(Direction == Input) ? CAM_DIR_IN : CAM_DIR_OUT;		uagt.uagt_buffer = (u_char *) DataBuffer;		uagt.uagt_buflen = DataBufferLength;	}	else		ccb.cam_ch.cam_flags |= CAM_DIR_NONE;		ccb.cam_ch.cam_flags |= CAM_DIS_AUTOSENSE;	ccb.cam_data_ptr = uagt.uagt_buffer;	ccb.cam_dxfer_len = uagt.uagt_buflen;	ccb.cam_timeout = 300; /* Timeout set to 5 minutes */	ccb.cam_sense_ptr = (u_char *) RequestSense;	ccb.cam_sense_len = sizeof(RequestSense_T);	ccb.cam_ch.cam_path_id = bus;	ccb.cam_ch.cam_target_id = target;	ccb.cam_ch.cam_target_lun = lun;    	if (ioctl(DeviceFD, UAGT_CAM_IO, (caddr_t) &uagt) < 0) {		return -1;    	}	/* Check return status */	if ((ccb.cam_ch.cam_status & CAM_STATUS_MASK) != CAM_REQ_CMP) {		if (ccb.cam_ch.cam_status & CAM_SIM_QFRZN) {			(void) memset(&ccb, 0, sizeof(ccb));			(void) memset(&uagt, 0, sizeof(uagt));			/* Setup the user agent ccb */			uagt.uagt_ccb = (CCB_HEADER  *) &ccb;			uagt.uagt_ccblen = sizeof(CCB_RELSIM);			/* Setup the scsi ccb */			ccb.cam_ch.my_addr = (struct ccb_header *) &ccb;			ccb.cam_ch.cam_ccb_len = sizeof(CCB_RELSIM);			ccb.cam_ch.cam_func_code = XPT_REL_SIMQ;			ccb.cam_ch.cam_path_id = bus;			ccb.cam_ch.cam_target_id = target;			ccb.cam_ch.cam_target_lun = lun;			if (ioctl(DeviceFD, UAGT_CAM_IO, (caddr_t) &uagt) < 0)				return -1;		}		printf("mtx: %s:\n%s=0x%x %s=0x%x\n",				       "SCSI command fault",				       "Opcode",				       CDB[0],				       "Status",				       ccb.cam_scsi_status);		return -1;	}	return 0;}

⌨️ 快捷键说明

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