From 280fa259362169aee9bd9dcc4b05f20282529036 Mon Sep 17 00:00:00 2001 From: Alexander Moibenko <41128752+moibenko@users.noreply.github.com> Date: Fri, 2 Aug 2019 17:03:08 -0500 Subject: [PATCH] Delete scsi_linux.c --- scsi_linux.c | 502 --------------------------------------------------- 1 file changed, 502 deletions(-) delete mode 100644 scsi_linux.c diff --git a/scsi_linux.c b/scsi_linux.c deleted file mode 100644 index 21c1948..0000000 --- a/scsi_linux.c +++ /dev/null @@ -1,502 +0,0 @@ -/* Copyright 1997, 1998 Leonard Zubkoff - Changes in Feb 2000 Eric Green - Copyright 2007-2008 by Robert Nelson - -$Date: 2008-08-19 03:03:38 -0700 (Tue, 19 Aug 2008) $ -$Revision: 193 $ - - This program is free software; you may redistribute and/or modify it under - the terms of the GNU General Public License Version 2 as published by the - Free Software Foundation. - - 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 complete details. - -*/ - -/* this is the SCSI commands for Linux. Note that changed - * it from using SCSI_IOCTL_SEND_COMMAND to using the SCSI generic interface. - */ - -#ifndef HZ -#warning "HZ is not defined, mtx might not work correctly!" -#define HZ 100 /* Jiffys for SG_SET_TIMEOUT */ -#endif - -/* These are copied out of BRU 16.1, with all the boolean masks changed - * to our bitmasks. -*/ -#define S_NO_SENSE(s) ((s)->SenseKey == 0x0) -#define S_RECOVERED_ERROR(s) ((s)->SenseKey == 0x1) - -#define S_NOT_READY(s) ((s)->SenseKey == 0x2) -#define S_MEDIUM_ERROR(s) ((s)->SenseKey == 0x3) -#define S_HARDWARE_ERROR(s) ((s)->SenseKey == 0x4) -#define S_UNIT_ATTENTION(s) ((s)->SenseKey == 0x6) -#define S_BLANK_CHECK(s) ((s)->SenseKey == 0x8) -#define S_VOLUME_OVERFLOW(s) ((s)->SenseKey == 0xd) - -#define DEFAULT_TIMEOUT 3*60 /* 3 minutes here */ - -/* Sigh, the T-10 SSC spec says all of the following is needed to - * detect a short read while in variable block mode, and that even - * though we got a BLANK_CHECK or MEDIUM_ERROR, it's still a valid read. - */ - -#define HIT_FILEMARK(s) (S_NO_SENSE((s)) && (s)->Filemark && (s)->Valid) -#define SHORT_READ(s) (S_NO_SENSE((s)) && (s)->ILI && (s)->Valid && (s)->AdditionalSenseCode==0 && (s)->AdditionalSenseCodeQualifier==0) -#define HIT_EOD(s) (S_BLANK_CHECK((s)) && (s)->Valid) -#define HIT_EOP(s) (S_MEDIUM_ERROR((s)) && (s)->EOM && (s)->Valid) -#define HIT_EOM(s) ((s)->EOM && (s)->Valid) - -#define STILL_A_VALID_READ(s) (HIT_FILEMARK(s) || SHORT_READ(s) || HIT_EOD(s) || HIT_EOP(s) || HIT_EOM(s)) - -#define SG_SCSI_DEFAULT_TIMEOUT (HZ*60*5) /* 5 minutes? */ - -static int pack_id; -static int sg_timeout; -int sg_scsi_default_timeout = SG_SCSI_DEFAULT_TIMEOUT; - -void set_timeout(int timeout) -{ - sg_scsi_default_timeout = HZ*timeout; -} - -int get_timeout(void) -{ - return(sg_scsi_default_timeout/HZ); -} - -DEVICE_TYPE SCSI_OpenDevice(char *DeviceName) -{ - int timeout = sg_scsi_default_timeout; -#ifdef SG_IO - int k; /* version */ -#endif - int DeviceFD = open(DeviceName, O_RDWR); - - if (DeviceFD < 0) - FatalError("cannot open SCSI device '%s' - %m\n", DeviceName); - - -#ifdef SG_IO - /* It is prudent to check we have a sg device by trying an ioctl */ - if ((ioctl(DeviceFD, SG_GET_VERSION_NUM, &k) < 0) || (k < 30000)) - { - FatalError("%s is not an sg device, or old sg driver\n", DeviceName); - } -#endif - - if (ioctl(DeviceFD, SG_SET_TIMEOUT, &timeout)) - { - FatalError("failed to set sg timeout - %m\n"); - } - pack_id = 1; /* used for SG v3 interface if possible. */ - return (DEVICE_TYPE) DeviceFD; -} - -void SCSI_Set_Timeout(int secs) -{ - sg_timeout = secs * HZ; -} - -void SCSI_Default_Timeout(void) -{ - sg_timeout = sg_scsi_default_timeout; -} - -void SCSI_CloseDevice(char *DeviceName, DEVICE_TYPE DeviceFD) -{ - if (close(DeviceFD) < 0) - FatalError("cannot close SCSI device '%s' - %m\n", DeviceName); -} - - -/* Added by Eric Green to deal with burping - * Seagate autoloader (hopefully!). - */ -/* Get the SCSI ID and LUN... */ -scsi_id_t *SCSI_GetIDLun(DEVICE_TYPE fd) -{ - int status; - scsi_id_t *retval; - - struct my_scsi_idlun - { - int word1; - int word2; - } idlun; - - status = ioctl(fd, SCSI_IOCTL_GET_IDLUN, &idlun); - if (status) - { - return NULL; /* sorry! */ - } - - retval = (scsi_id_t *)xmalloc(sizeof(scsi_id_t)); - retval->id = idlun.word1 & 0xff; - retval->lun = idlun.word1 >> 8 & 0xff; - -#ifdef DEBUG - fprintf(stderr, "SCSI:ID=%d LUN=%d\n", retval->id, retval->lun); -#endif - - return retval; -} - - -/* Changed January 2001 by Eric Green to - * use the Linux version 2.4 SCSI Generic facility if available. - * Liberally cribbed code from Doug Gilbert's sg3 utils. - */ - -#ifdef SG_IO -#include "sg_err.h" /* error stuff. */ -#include "sg_err.c" /* some of Doug Gilbert's routines */ - -/* Use the new SG_IO structure */ -int SCSI_ExecuteCommand(DEVICE_TYPE DeviceFD, - Direction_T Direction, - CDB_T *CDB, - int CDB_Length, - void *DataBuffer, - int DataBufferLength, - RequestSense_T *RequestSense) -{ - unsigned int status; - sg_io_hdr_t io_hdr; - - memset(&io_hdr, 0, sizeof(sg_io_hdr_t)); - memset(RequestSense, 0, sizeof(RequestSense_T)); - - /* Fill in the common stuff... */ - io_hdr.interface_id = 'S'; - io_hdr.cmd_len = CDB_Length; - io_hdr.mx_sb_len = sizeof(RequestSense_T); - io_hdr.dxfer_len = DataBufferLength; - io_hdr.cmdp = (unsigned char *) CDB; - io_hdr.sbp = (unsigned char *) RequestSense; - io_hdr.dxferp = DataBuffer; - io_hdr.timeout = sg_timeout * 10; /* Convert from Jiffys to milliseconds */ - - if (Direction==Input) - { - /* fprintf(stderr,"direction=input\n"); */ - io_hdr.dxfer_direction=SG_DXFER_FROM_DEV; - } - else - { - /* fprintf(stderr,"direction=output\n"); */ - io_hdr.dxfer_direction=SG_DXFER_TO_DEV; - } - - /* Now do it: */ - if ((status = ioctl(DeviceFD, SG_IO , &io_hdr)) || io_hdr.masked_status) - { - /* fprintf(stderr, "smt_scsi_cmd: Rval=%d Status=%d, errno=%d [%s]\n",status, io_hdr.masked_status, - errno, - strerror(errno)); */ - - switch (sg_err_category3(&io_hdr)) - { - case SG_ERR_CAT_CLEAN: - case SG_ERR_CAT_RECOVERED: - break; - - case SG_ERR_CAT_MEDIA_CHANGED: - return 2; - - default: - return -1; - } - - /* fprintf(stderr,"host_status=%d driver_status=%d residual=%d writelen=%d\n",io_hdr.host_status,io_hdr.driver_status,io_hdr.resid,io_hdr.sb_len_wr ); */ - - return -errno; - } - - /* Now check the returned statuses: */ - /* fprintf(stderr,"host_status=%d driver_status=%d residual=%d writelen=%d\n",io_hdr.host_status,io_hdr.driver_status,io_hdr.resid,io_hdr.sb_len_wr ); */ - - SCSI_Default_Timeout(); /* reset back to default timeout, sigh. */ - return 0; -} - -#else - -/* Changed February 2000 by Eric Green to - * use the SCSI generic interface rather than SCSI_IOCTL_SEND_COMMAND - * so that we can get more than PAGE_SIZE data.... - * - * Note that the SCSI generic interface abuses READ and WRITE calls to serve - * the same purpose as IOCTL calls, i.e., for "writes", the contents of the - * buffer that you send as the argument to the write() call are actually - * altered to fill in result status and sense data (if needed). - * Also note that this brain-dead interface does not have any sort of - * provisions for expanding the sg_header struct in a backward-compatible - * manner. This sucks. But sucks less than SCSI_IOCTL_SEND_COMMAND, sigh. - */ - - -#ifndef OLD_EXECUTE_COMMAND_STUFF - -static void slow_memcopy(unsigned char *src, unsigned char *dest, int numbytes) -{ - while (numbytes--) - { - *dest++ = *src++; - } -} - - -int SCSI_ExecuteCommand(DEVICE_TYPE DeviceFD, - Direction_T Direction, - CDB_T *CDB, - int CDB_Length, - void *DataBuffer, - int DataBufferLength, - RequestSense_T *RequestSense) -{ - unsigned char *Command=NULL; /* the command data struct sent to them... */ - unsigned char *ResultBuf=NULL; /* the data we read in return... */ - - unsigned char *src; /* for copying stuff, sigh. */ - unsigned char *dest; /* for copy stuff, again, sigh. */ - - int write_length = sizeof(struct sg_header)+CDB_Length; - int i; /* a random index... */ - int result; /* the result of the write... */ - - struct sg_header *Header; /* we actually point this into Command... */ - struct sg_header *ResultHeader; /* we point this into ResultBuf... */ - - /* First, see if we need to set our SCSI timeout to something different */ - if (sg_timeout != sg_scsi_default_timeout) - { - /* if not default, set it: */ -#ifdef DEBUG_TIMEOUT - fprintf(stderr,"Setting timeout to %d\n", sg_timeout); - fflush(stderr); -#endif - if(ioctl(DeviceFD, SG_SET_TIMEOUT, &sg_timeout)) - { - FatalError("failed to set sg timeout - %m\n"); - } - } - - if (Direction == Output) - { - /* if we're writing, our length is longer... */ - write_length += DataBufferLength; - } - - /* allocate some memory... enough for the command plus the header + - * any other data that we may need here... - */ - - Command = (unsigned char *)xmalloc(write_length); - Header = (struct sg_header *) Command; /* make it point to start of buf */ - - dest = Command; /* now to copy the CDB... from start of buffer,*/ - dest += sizeof(struct sg_header); /* increment it past the header. */ - - slow_memcopy((char *)CDB, dest, CDB_Length); - - /* if we are writing additional data, tack it on here! */ - if (Direction == Output) - { - dest += CDB_Length; - slow_memcopy(DataBuffer, dest, DataBufferLength); /* copy to end of command */ - } - - /* Now to fill in the Header struct: */ - Header->reply_len=DataBufferLength+sizeof(struct sg_header); -#ifdef DEBUG - fprintf(stderr,"sg:reply_len(sent)=%d\n",Header->reply_len); -#endif - Header->twelve_byte = CDB_Length == 12; - Header->result = 0; - Header->pack_len = write_length; /* # of bytes written... */ - Header->pack_id = 0; /* not used */ - Header->other_flags = 0; /* not used. */ - Header->sense_buffer[0]=0; /* used? */ - - /* Now to do the write... */ - result = write(DeviceFD,Command,write_length); - - /* Now to check the result :-(. */ - /* Note that we don't have any request sense here. So we have no - * idea what's going on. - */ - if (result < 0 || result != write_length || Header->result || Header->sense_buffer[0]) - { -#ifdef DEBUG_SCSI - fprintf(stderr,"scsi:result=%d Header->result=%d Header->sense_buffer[0]=%d\n", - result,Header->result,Header->sense_buffer[0]); -#endif - /* we don't have any real sense data, sigh :-(. */ - if (Header->sense_buffer[0]) - { - /* well, I guess we DID have some! eep! copy the sense data! */ - slow_memcopy((char *)Header->sense_buffer,(char *)RequestSense, - sizeof(Header->sense_buffer)); - } - else - { - dest=(unsigned char *)RequestSense; - *dest=(unsigned char)Header->result; /* may chop, sigh... */ - } - - /* okay, now, we may or may not need to find a non-zero value to return. - * For tape drives, we may get a BLANK_CHECK or MEDIUM_ERROR and find - * that it's *STILL* a good read! Use the STILL_A_VALID_READ macro - * that calls all those macros I cribbed from Richard. - */ - - if (!STILL_A_VALID_READ(RequestSense)) - { - free(Command); /* zap memory leak, sigh */ - /* okay, find us a non-zero value to return :-(. */ - if (result) - { - return result; - } - else if (Header->result) - { - return Header->result; - } - else - { - return -1; /* sigh */ - } - } - else - { - result=-1; - } - } - else - { - result=0; /* we're okay! */ - } - - /* now to allocate the new block.... */ - ResultBuf=(unsigned char *)xmalloc(Header->reply_len); - /* now to clear ResultBuf... */ - slow_bzero(ResultBuf,Header->reply_len); - - ResultHeader=(struct sg_header *)ResultBuf; - - /* copy the original Header... */ - ResultHeader->result=0; - ResultHeader->pack_id=0; - ResultHeader->other_flags=0; - ResultHeader->reply_len=Header->reply_len; - ResultHeader->twelve_byte = CDB_Length == 12; - ResultHeader->pack_len = write_length; /* # of bytes written... */ - ResultHeader->sense_buffer[0]=0; /* whoops! Zero that! */ -#ifdef DEBUG - fprintf(stderr,"sg:Reading %d bytes from DeviceFD\n",Header->reply_len); - fflush(stderr); -#endif - result=read(DeviceFD,ResultBuf,Header->reply_len); -#ifdef DEBUG - fprintf(stderr,"sg:result=%d ResultHeader->result=%d\n", - result,ResultHeader->result); - fflush(stderr); -#endif - /* New: added check to see if the result block is still all zeros! */ - if (result < 0 || - result != Header->reply_len || - ResultHeader->result || - ResultHeader->sense_buffer[0]) - { -#ifdef DEBUG - fprintf(stderr, - "scsi: result=%d Header->reply_len=%d ResultHeader->result=%d ResultHeader->sense_buffer[0]=%d\n", - result, - Header->reply_len, - ResultHeader->result, - ResultHeader->sense_buffer[0]); -#endif - /* eep! copy the sense data! */ - slow_memcopy((char *)ResultHeader->sense_buffer,(char *)RequestSense, - sizeof(ResultHeader->sense_buffer)); - /* sense data copied, now find us a non-zero value to return :-(. */ - /* NOTE: Some commands return sense data even though they validly - * executed! We catch a few of those with the macro STILL_A_VALID_READ. - */ - - if (!STILL_A_VALID_READ(RequestSense)) - { - free(Command); - if (result) - { - free(ResultBuf); - return result; - } - else if (ResultHeader->result) - { - free(ResultBuf); - return ResultHeader->result; - } - else - { - free(ResultBuf); - return -1; /* sigh! */ - } - } - else - { - result=-1; /* if it was a valid read, still have -1 result. */ - } - } - else - { - result=0; - } - - /* See if we need to reset our SCSI timeout */ - if (sg_timeout != sg_scsi_default_timeout) - { - sg_timeout = sg_scsi_default_timeout; /* reset it back to default */ - -#ifdef DEBUG_TIMEOUT - fprintf(stderr,"Setting timeout to %d\n", sg_timeout); - fflush(stderr); -#endif - /* if not default, set it: */ - if (ioctl(DeviceFD, SG_SET_TIMEOUT, &sg_timeout)) - { - FatalError("failed to set sg timeout - %m\n"); - } - } - - /* now for the crowning moment: copying any result into the DataBuffer! */ - /* (but only if it were an input command and not an output command :-} */ - if (Direction == Input) - { -#ifdef DEBUG - fprintf(stderr,"Header->reply_len=%d,ResultHeader->reply_len=%d\n", - Header->reply_len,ResultHeader->reply_len); -#endif - src=ResultBuf+sizeof(struct sg_header); - dest=DataBuffer; - for (i = 0; i < ResultHeader->reply_len; i++) - { - if (i >= DataBufferLength) - break; /* eep! */ - *dest++ = *src++; - } - } - - /* and return! */ - free(Command); /* clean up memory leak... */ - free(ResultBuf); - return result; /* good stuff ! */ -} - -#endif -#endif /* #ifdef SG_IO */