📄 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 + -