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

📄 scsi-aix.c

📁 开源备份软件源码 AMANDA, the Advanced Maryland Automatic Network Disk Archiver, is a backup system that a
💻 C
字号:
/* * Amanda, The Advanced Maryland Automatic Network Disk Archiver * Copyright (c) 1991-2000 University of Maryland at College Park * All Rights Reserved. * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of U.M. not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission.  U.M. makes no representations about the * suitability of this software for any purpose.  It is provided "as is" * without express or implied warranty. * * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M. * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Authors: the Amanda Development Team.  Its members are listed in a * file named AUTHORS, in the root directory of this distribution. *//* * $Id: scsi-aix.c,v 1.23 2006/05/25 01:47:07 johnfranks Exp $ * * Interface to execute SCSI commands on an AIX System * * Copyright (c) Thomas Hepper th@ant.han.de */#include <amanda.h>#include <scsi-defs.h>#ifdef HAVE_SYS_TYPES_H#include <sys/types.h>#endif#ifdef HAVE_STAT_H#include <sys/stat.h>#endif#ifdef HAVE_FCNTL_H#include <fcntl.h>#endif#ifdef HAVE_UNISTD_H#include <unistd.h>#endif#ifdef HAVE_STDIO_H#include <stdio.h>#endif#ifdef HAVE_ERRNO_H#include <errno.h>#endif#include <sys/scarray.h>#include <sys/tape.h>#include <scsi-defs.h>#include <gscdds.h>void SCSI_OS_Version(void){#ifndef lint   static char rcsid[] = "$Id: scsi-aix.c,v 1.23 2006/05/25 01:47:07 johnfranks Exp $";   DebugPrint(DEBUG_INFO, SECTION_INFO, "scsi-os-layer: %s\n",rcsid);#endif}int SCSI_OpenDevice(int ip){  int DeviceFD;  int i;  extern OpenFiles_T *pDev;    if (pDev[ip].inqdone == 0)    {      pDev[ip].inqdone = 1;      /*       * Check if it is an gsc (generic SCSI device)       */      if (strncmp("/dev/gsc", pDev[ip].dev, 8) == 0)        {	  pDev[ip].flags = AIX_USE_GSC;          DeviceFD = open(pDev[ip].dev, 0);        } else {          DeviceFD = openx(pDev[ip].dev, O_RDWR, 0, SC_DIAGNOSTIC);        }      if (DeviceFD >= 0)	{	  pDev[ip].avail = 1;          pDev[ip].fd = DeviceFD;          pDev[ip].SCSI = 0;          pDev[ip].devopen = 1;          pDev[ip].inquiry = (SCSIInquiry_T *)malloc(INQUIRY_SIZE);          if (SCSI_Inquiry(ip, pDev[ip].inquiry, INQUIRY_SIZE) == 0)	    {             if (pDev[ip].inquiry->type == TYPE_TAPE || pDev[ip].inquiry->type == TYPE_CHANGER)               {                 for (i=0;i < 16;i++)                   pDev[ip].ident[i] = pDev[ip].inquiry->prod_ident[i];                 for (i=15; i >= 0 && !isalnum(pDev[ip].ident[i]) ; i--)                   {                     pDev[ip].ident[i] = '\0';                   }                 pDev[ip].SCSI = 1;		  if (pDev[ip].inquiry->type == TYPE_TAPE)		  {		          pDev[ip].type = stralloc("tape");		  }		  if (pDev[ip].inquiry->type == TYPE_CHANGER)		  {		          pDev[ip].type = stralloc("changer");		  }                 PrintInquiry(pDev[ip].inquiry);                 return(1);                } else {                 close(DeviceFD);                 free(pDev[ip].inquiry);                 return(0);               }           }           free(pDev[ip].inquiry);           pDev[ip].inquiry = NULL;           return(1);       } else {	 dbprintf(_("SCSI_OpenDevice %s failed\n"), pDev[ip].dev);         return(0);       }    } else {      if ((DeviceFD = openx(pDev[ip].dev, O_RDWR, 0, SC_DIAGNOSTIC)) >= 0)        {          pDev[ip].fd = DeviceFD;          pDev[ip].devopen = 1;          return(1);        }    }  return(0);}int SCSI_CloseDevice(int DeviceFD){  int ret;  extern OpenFiles_T *pDev;  ret = close(pDev[DeviceFD].fd);  pDev[DeviceFD].devopen = 0;  return(ret);}int SCSI_ExecuteCommand(int DeviceFD,                        Direction_T Direction,                        CDB_T CDB,                        size_t CDB_Length,                        void *DataBuffer,                        size_t DataBufferLength,                        RequestSense_T *RequestSenseBuf,                        size_t RequestSenseLength){  extern OpenFiles_T *pDev;  extern FILE * debug_file;  CDB_T CDBSENSE;  CDB_T SINQ;  ExtendedRequestSense_T ExtendedRequestSense;  struct sc_iocmd ds;  scmd_t scmd;  char sbyte;  int Result;  int isbusy = 0;  int target = 3;  /* Basic sanity checks */  assert(CDB_Length <= UCHAR_MAX);  assert(RequestSenseLength <= UCHAR_MAX);  /* Clear buffer for cases where sense is not returned */  memset(RequestSenseBuf, 0, RequestSenseLength);  if (pDev[DeviceFD].avail == 0)    {      return(SCSI_ERROR);    }  if (pDev[DeviceFD].flags == AIX_USE_GSC)    {      scmd.cdb = CDB;      scmd.cdblen = CDB_Length;      scmd.data_buf = DataBuffer;      scmd.datalen = DataBufferLength;      scmd.sense_buf = (unsigned char *)RequestSenseBuf;      scmd.senselen = RequestSenseLength;      scmd.statusp = &sbyte;      scmd.timeval = 60;      switch (Direction)         {        case Input:          scmd.rw = 0;          break;        case Output:          scmd.rw = 1;          break;        }      if (ioctl(pDev[DeviceFD].fd, GSC_CMD, (caddr_t) &scmd) < 0) {        return(SCSI_ERROR);      }      return(SCSI_OK);    } else {      bzero(&ds, SIZEOF(struct sc_iocmd));      bzero(RequestSenseBuf, RequestSenseLength);      bzero(&ExtendedRequestSense, SIZEOF(ExtendedRequestSense_T));            ds.flags = SC_ASYNC;       /* Timeout */      ds.timeout_value = 60;      bcopy(CDB, ds.scsi_cdb, CDB_Length);      ds.command_length = CDB_Length;      /*        *  Data buffer for results        * If the size of the buffer is 0       * then keep this fields untouched                  */      if (DataBufferLength > 0)        {          ds.buffer = DataBuffer;          ds.data_length = DataBufferLength;        }            /* Sense Buffer is not available on AIX ?*/      /*        ds.req_sense_length = 255;        ds.request_sense_ptr = (unsigned char *)RequestSense;      */      switch (Direction)         {        case Input:          ds.flags = ds.flags | B_READ;          break;        case Output:          ds.flags = ds.flags | B_WRITE;          break;        }      DecodeSCSI(CDB, "SCSI_ExecuteCommand : ");            if (pDev[DeviceFD].devopen == 0)        if (SCSI_OpenDevice(DeviceFD) == 0)          return(SCSI_ERROR);      Result = ioctl(pDev[DeviceFD].fd, STIOCMD, &ds);      SCSI_CloseDevice(DeviceFD);            if ( Result < 0)        {          switch (ds.scsi_bus_status)            {            case SC_GOOD_STATUS:              SINQ[0] = SC_COM_REQUEST_SENSE;              SINQ[1] = 0;               SINQ[2] = 0;              SINQ[3] = 0;              SINQ[4] = 0x1D;              SINQ[5] = 0x80;              bcopy(SINQ, ds.scsi_cdb, 6);              ds.command_length = 6;              ds.buffer = (unsigned char *)RequestSenseBuf;              ds.data_length = RequestSenseLength;                            if (pDev[DeviceFD].devopen == 0)                if (SCSI_OpenDevice(DeviceFD) == 0)                  return(SCSI_ERROR);              Result = ioctl(pDev[DeviceFD].fd, STIOCMD, &ds);              SCSI_CloseDevice(DeviceFD);              return(SCSI_OK);            case SC_BUSY_STATUS:              return(SCSI_BUSY);            case SC_CHECK_CONDITION:              SINQ[0] = SC_COM_REQUEST_SENSE;              SINQ[1] = 0;               SINQ[2] = 0;              SINQ[3] = 0;              SINQ[4] = 0x1D;              SINQ[5] = 0x80;              bcopy(SINQ, ds.scsi_cdb, 6);              ds.command_length = 6;              ds.buffer = (unsigned char *)RequestSenseBuf;              ds.data_length = (unsigned char)RequestSenseLength;              if (pDev[DeviceFD].devopen == 0)                if (SCSI_OpenDevice(DeviceFD) == 0)                  return(SCSI_ERROR);              Result = ioctl(pDev[DeviceFD].fd, STIOCMD, &ds);              SCSI_CloseDevice(DeviceFD);              return(SCSI_CHECK);            default:              /*               * Makes no sense yet, may result in an endless loop               *               RequestSense(DeviceFD, &ExtendedRequestSense, 0);               DecodeExtSense(&ExtendedRequestSense, "SCSI_ExecuteCommand:", debug_file);               bcopy(&ExtendedRequestSense, RequestSenseBuf, RequestSenseLength);              */              dbprintf(_("ioctl on %d return %d\n"), pDev[DeviceFD].fd, Result);              dbprintf(_("ret: %d errno: %d (%s)\n"), Result, errno, "");              dbprintf(_("data_length:     %d\n"), ds.data_length);              dbprintf(_("buffer:          0x%X\n"), ds.buffer);              dbprintf(_("timeout_value:   %d\n"), ds.timeout_value);              dbprintf(_("status_validity: %d\n"), ds.status_validity);              dbprintf(_("scsi_bus_status: 0x%X\n"), ds.scsi_bus_status);              dbprintf(_("adapter_status:  0x%X\n"), ds.adapter_status);              dbprintf(_("adap_q_status:   0x%X\n"), ds.adap_q_status);              dbprintf(_("q_tag_msg:       0x%X\n"), ds.q_tag_msg);              dbprintf(_("flags:           0X%X\n"), ds.flags);              return(SCSI_ERROR);            }        }      return(SCSI_OK);    }}int SCSI_Scan(void){  int fd;  struct sc_inquiry si;  u_char buf[255];  int target;  int lun;  int isbusy;  char type;  char bus[] = "/dev/scsi0";    if ((fd = open(bus, O_RDWR)) == -1)    return(1);  for (target = 0; target < 7; target++)     {      for (lun = 0; lun < 7; lun++)        {          g_printf(_("Target:Lun %d:%d\n"), target,lun);          if (ioctl(fd, SCIOSTART, IDLUN(target, lun)) == -1) {            if (errno == EINVAL) {              g_printf(_("is in use\n"));              isbusy = 1;            } else {              return(1);            }          } else {            isbusy = 0;          }                    bzero(&si, SIZEOF(si));          si.scsi_id = target;          si.lun_id = lun;          si.inquiry_len = 255;          si.inquiry_ptr = (char *)&buf;          if (ioctl(fd, SCIOINQU, &si) == -1)            {              g_printf("SCIOINQU: %s\n", strerror(errno));            } else {              dump_hex(&buf, 255, DEBUG_INFO, SECTION_SCSI);              type = buf[0] & 0x1lf;              buf[8+28] = 0;              g_printf(_("%-28s|Device Type %d\n"),buf[8], type);            }          if (!isbusy && ioctl(fd, SCIOSTOP, IDLUN(target, lun)) == -1)            return(1);        }    }}int Tape_Ioctl(int DeviceFD, int command){  extern OpenFiles_T *pDev;  int ret = -1;  return(ret);}int Tape_Status( int DeviceFD){/*  Not yet*/  return(-1);}int ScanBus(int print){/*  Not yet*/  SCSI_Scan();  return(-1);}/* * Local variables: * indent-tabs-mode: nil * c-file-style: gnu * End: */

⌨️ 快捷键说明

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