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

📄 scsi-solaris.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-solaris.c,v 1.26 2006/05/25 01:47:10 johnfranks Exp $ * * Interface to execute SCSI commands on an Sun Workstation * * Copyright (c) Thomas Hepper th@ant.han.de */#include "amanda.h"#include <sys/scsi/impl/uscsi.h>#include <scsi-defs.h>#include <sys/mtio.h>void SCSI_OS_Version(void){#ifndef lint   static char rcsid[] = "$Id: scsi-solaris.c,v 1.26 2006/05/25 01:47:10 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;      if ((DeviceFD = open(pDev[ip].dev, O_RDWR| O_NONBLOCK)) >= 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, (unsigned char)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((int)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 = open(pDev[ip].dev, O_RDWR| O_NDELAY)) >= 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 *RequestSense,                        size_t RequestSenseLength){  extern OpenFiles_T *pDev;  extern FILE * debug_file;  int ret = 0;  int retries = 1;  struct uscsi_cmd Command;  static int depth = 0;  /* Basic sanity checks */  assert(CDB_Length <= UCHAR_MAX);  assert(RequestSenseLength <= UCHAR_MAX);  /* Clear buffer for cases where sense is not returned */  memset(RequestSense, 0, RequestSenseLength);  if (pDev[DeviceFD].avail == 0)    {      return(SCSI_ERROR);    }    if (depth++ > 2)  {     --depth;     SCSI_CloseDevice(DeviceFD);     return SCSI_ERROR;  }  memset(&Command, 0, SIZEOF(struct uscsi_cmd));  memset(RequestSense, 0, RequestSenseLength);  switch (Direction)    {    case Input:      if (DataBufferLength > 0)        memset(DataBuffer, 0, DataBufferLength);      /* Command.uscsi_flags =  USCSI_READ | USCSI_RQENABLE;    */      Command.uscsi_flags = USCSI_DIAGNOSE | USCSI_ISOLATE        | USCSI_READ | USCSI_RQENABLE;      break;    case Output:      /* Command.uscsi_flags =  USCSI_WRITE | USCSI_RQENABLE;   */      Command.uscsi_flags = USCSI_DIAGNOSE | USCSI_ISOLATE        | USCSI_WRITE | USCSI_RQENABLE;      break;    }  /* Set timeout to 5 minutes. */  Command.uscsi_timeout = 300;  Command.uscsi_cdb = (caddr_t) CDB;  Command.uscsi_cdblen = (u_char)CDB_Length;  if (DataBufferLength > 0)    {        Command.uscsi_bufaddr = DataBuffer;      Command.uscsi_buflen = DataBufferLength;    } else {/* * If there is no data buffer force the direction to write, read with * a null buffer will fail (errno 22) */      Command.uscsi_flags = USCSI_DIAGNOSE | USCSI_ISOLATE        | USCSI_WRITE | USCSI_RQENABLE;   }  Command.uscsi_rqbuf = (caddr_t)RequestSense;  Command.uscsi_rqlen = (u_char)RequestSenseLength;  DecodeSCSI(CDB, "SCSI_ExecuteCommand : ");  while (retries > 0)  {    if (pDev[DeviceFD].devopen == 0)      if (SCSI_OpenDevice(DeviceFD) == 0)        {	  sleep(1);	  continue;        }    if ((ret = ioctl(pDev[DeviceFD].fd, USCSICMD, &Command)) >= 0)    {      ret = Command.uscsi_status;      break;    }    dbprintf(_("ioctl on %d failed, errno %s, ret %d\n"),	      pDev[DeviceFD].fd, strerror(errno), ret);#if 0    RequestSense(DeviceFD, &pExtendedRequestSense, 0);#endif    DecodeSense(RequestSense, "SCSI_ExecuteCommand:", debug_file);    retries--;  }  --depth;  SCSI_CloseDevice(DeviceFD);  DebugPrint(DEBUG_INFO, SECTION_SCSI,_("ioctl ret (%d)\n"),ret);  return(SCSI_OK);}/* * Send the command to the device with the * ioctl interface */int Tape_Ioctl( int DeviceFD, int command){  extern OpenFiles_T *pDev;  struct mtop mtop;  int ret = 0;  if (pDev[DeviceFD].devopen == 0)      if (SCSI_OpenDevice(DeviceFD) == 0)          return(-1);  switch (command)    {    case IOCTL_EJECT:      mtop.mt_op = MTOFFL;      mtop.mt_count = 1;      break;     default:      break;    }  if (ioctl(pDev[DeviceFD].fd , MTIOCTOP, &mtop) != 0)    {      dbprintf(_("Tape_Ioctl error ioctl %s\n"), strerror(errno));      SCSI_CloseDevice(DeviceFD);      return(-1);    }  SCSI_CloseDevice(DeviceFD);  return(ret);  }int Tape_Status( int DeviceFD){  extern OpenFiles_T *pDev;  struct mtget mtget;  int ret = -1;  memset(&mtget, 0, SIZEOF(mtget));  if (pDev[DeviceFD].devopen == 0)      if (SCSI_OpenDevice(DeviceFD) == 0)          return(-1);    if (ioctl(pDev[DeviceFD].fd , MTIOCGET, &mtget) != 0)    {      dbprintf(_("Tape_Status error ioctl %s\n"), strerror(errno));      SCSI_CloseDevice(DeviceFD);      return(-1);    }  /*   * I have no idea what is the meaning of the bits in mt_erreg   * I assume that nothing set is tape loaded   * 0x2 is no tape online   */  DebugPrint(DEBUG_INFO, SECTION_TAPE, _("ioctl result for mt_dsreg (%d)\n"), mtget.mt_dsreg);  DebugPrint(DEBUG_INFO, SECTION_TAPE, _("ioctl result for mt_erreg (%d)\n"), mtget.mt_erreg);  if (mtget.mt_erreg == 0)    {      ret = ret | TAPE_ONLINE;    }  if (mtget.mt_erreg & 0x2)    {      ret = ret | TAPE_NOT_LOADED;    }  SCSI_CloseDevice(DeviceFD);  return(ret); }int ScanBus(int print){	(void)print;	/* Quiet unused parameter warning */	return(-1);}/* * Local variables: * indent-tabs-mode: nil * c-file-style: gnu * End: */

⌨️ 快捷键说明

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