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

📄 scsi-linux.c

📁 开源备份软件源码 AMANDA, the Advanced Maryland Automatic Network Disk Archiver, is a backup system that a
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * 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-linux.c,v 1.30 2006/07/06 11:57:28 martinea Exp $ * * Interface to execute SCSI commands on Linux * * Copyright (c) Thomas Hepper th@ant.han.de */#include "amanda.h"#ifdef HAVE_SCSI_SG_H#include <scsi/sg.h>#define LINUX_SG#endif#ifdef HAVE_SYS_MTIO_H#include <sys/mtio.h>#endif#include <scsi-defs.h>extern OpenFiles_T *pDev;void SCSI_OS_Version(void){#ifndef lint   static char rcsid[] = "$Id: scsi-linux.c,v 1.30 2006/07/06 11:57:28 martinea Exp $";   DebugPrint(DEBUG_ERROR, SECTION_INFO, "scsi-os-layer: %s\n",rcsid);#endif}int SCSI_CloseDevice(int DeviceFD){  int ret = 0;    if (pDev[DeviceFD].devopen == 1)    {      pDev[DeviceFD].devopen = 0;      ret = close(pDev[DeviceFD].fd);    }  return(ret);}/* Open a device to talk to an scsi device, either per ioctl, or * direct writing.... * Return: * 0 -> error * 1 -> OK * * TODO: * Define some readable defs for the falgs which can be set (like in the AIX dreiver) * */#ifdef LINUX_SGint SCSI_OpenDevice(int ip){  int DeviceFD;  int i;  int timeout;  struct stat pstat;  char *buffer = NULL ;           /* Will contain the device name after checking */  int openmode = O_RDONLY;  DebugPrint(DEBUG_INFO, SECTION_SCSI,_("##### START SCSI_OpenDevice\n"));  if (pDev[ip].inqdone == 0)    {      pDev[ip].inqdone = 1;      if (strncmp("/dev/sg", pDev[ip].dev, 7) != 0) /* Check if no sg device for an link .... */        {          DebugPrint(DEBUG_INFO, SECTION_SCSI,_("SCSI_OpenDevice : checking if %s is a sg device\n"), pDev[ip].dev);          if (lstat(pDev[ip].dev, &pstat) != -1)            {              if (S_ISLNK(pstat.st_mode) == 1)                {                  DebugPrint(DEBUG_INFO, SECTION_SCSI,_("SCSI_OpenDevice : is a link, checking destination\n"));                  if ((buffer = (char *)malloc(513)) == NULL)                    {                      DebugPrint(DEBUG_ERROR, SECTION_SCSI,_("SCSI_OpenDevice : malloc failed\n"));                      return(0);                    }                  memset(buffer, 0, 513);                  if (( i = readlink(pDev[ip].dev, buffer, 512)) == -1)                    {                      if (errno == ENAMETOOLONG )                        {                        } else {                          pDev[ip].SCSI = 0;                        }                    }                  if ( i >= 7)                    {                      if (strncmp("/dev/sg", buffer, 7) == 0)                        {                          DebugPrint(DEBUG_INFO, SECTION_SCSI,_("SCSI_OpenDevice : link points to %s\n"), buffer) ;                          pDev[ip].flags = 1;                        }                    }                } else {/* S_ISLNK(pstat.st_mode) == 1 */                  DebugPrint(DEBUG_INFO, SECTION_SCSI,_("No link %s\n"), pDev[ip].dev) ;                  buffer = stralloc(pDev[ip].dev);                }            } else {/* lstat(DeviceName, &pstat) != -1 */               DebugPrint(DEBUG_ERROR, SECTION_SCSI,_("can't stat device %s\n"), pDev[ip].dev);              return(0);            }        } else {          buffer = stralloc(pDev[ip].dev);          pDev[ip].flags = 1;        }            if (pDev[ip].flags == 1)        {          openmode = O_RDWR;        }            DebugPrint(DEBUG_INFO, SECTION_SCSI,_("Try to open %s\n"), buffer);      if ((DeviceFD = open(buffer, openmode)) >= 0)        {          pDev[ip].avail = 1;          pDev[ip].devopen = 1;          pDev[ip].fd = DeviceFD;        } else {          DebugPrint(DEBUG_INFO, SECTION_SCSI,_("##### STOP SCSI_OpenDevice open failed\n"));	  amfree(buffer);          return(0);        }            DebugPrint(DEBUG_INFO, SECTION_SCSI,_("done\n"));      if ( pDev[ip].flags == 1)        {          pDev[ip].SCSI = 1;        }            pDev[ip].dev = buffer;      if (pDev[ip].SCSI == 1)        {          DebugPrint(DEBUG_INFO, SECTION_SCSI,_("SCSI_OpenDevice : use SG interface\n"));          if ((timeout = ioctl(pDev[ip].fd, SG_GET_TIMEOUT)) > 0)             {              DebugPrint(DEBUG_INFO, SECTION_SCSI,_("SCSI_OpenDevice : current timeout %d\n"), timeout);              timeout = 60000;              if (ioctl(pDev[ip].fd, SG_SET_TIMEOUT, &timeout) == 0)                {                  DebugPrint(DEBUG_INFO, SECTION_SCSI,_("SCSI_OpenDevice : timeout set to %d\n"), timeout);                }            }          pDev[ip].inquiry = (SCSIInquiry_T *)malloc(INQUIRY_SIZE);          if (SCSI_Inquiry(ip, pDev[ip].inquiry, (u_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(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);                  DebugPrint(DEBUG_INFO, SECTION_SCSI,_("##### STOP SCSI_OpenDevice (1)\n"));                  return(1);                } else {                  close(DeviceFD);                  amfree(pDev[ip].inquiry);                  DebugPrint(DEBUG_INFO, SECTION_SCSI,_("##### STOP SCSI_OpenDevice (0)\n"));                  return(0);                }            } else {              pDev[ip].SCSI = 0;              pDev[ip].devopen = 0;              close(DeviceFD);              amfree(pDev[ip].inquiry);              pDev[ip].inquiry = NULL;              DebugPrint(DEBUG_INFO, SECTION_SCSI,_("##### STOP SCSI_OpenDevice (1)\n"));              return(1);            }        } else /* if (pDev[ip].SCSI == 1) */ {            DebugPrint(DEBUG_INFO, SECTION_SCSI,_("Device not capable for SCSI commands\n"));          pDev[ip].SCSI = 0;          pDev[ip].devopen = 0;          close(DeviceFD);          DebugPrint(DEBUG_INFO, SECTION_SCSI,_("##### STOP SCSI_OpenDevice (1)\n"));          return(1);        }    } else { /* if (pDev[ip].inqdone == 0) */      if (pDev[ip].flags == 1)        {          openmode = O_RDWR;        } else {          openmode = O_RDONLY;        }      if ((DeviceFD = open(pDev[ip].dev, openmode)) >= 0)        {          pDev[ip].devopen = 1;          pDev[ip].fd = DeviceFD;          if (pDev[ip].flags == 1)            {              if ((timeout = ioctl(pDev[ip].fd, SG_GET_TIMEOUT)) > 0)                 {                  DebugPrint(DEBUG_INFO, SECTION_SCSI,_("SCSI_OpenDevice : current timeout %d\n"), timeout);                  timeout = 60000;                  if (ioctl(pDev[ip].fd, SG_SET_TIMEOUT, &timeout) == 0)                    {                      DebugPrint(DEBUG_INFO, SECTION_SCSI,_("SCSI_OpenDevice : timeout set to %d\n"), timeout);                    }                }            }          DebugPrint(DEBUG_INFO, SECTION_SCSI,_("##### STOP SCSI_OpenDevice (1)\n"));          return(1);        } else {          DebugPrint(DEBUG_INFO, SECTION_SCSI,_("##### STOP SCSI_OpenDevice open failed\n"));          return(0);        }    }  DebugPrint(DEBUG_INFO, SECTION_SCSI,_("##### STOP SCSI_OpenDevice should not happen !!\n"));  return(0);}#define SCSI_OFF SIZEOF(struct sg_header)int SCSI_ExecuteCommand(int DeviceFD,                        Direction_T Direction,                        CDB_T CDB,                        size_t CDB_Length,                        void *DataBuffer,                        size_t DataBufferLength,                        RequestSense_T *pRequestSense,                        size_t RequestSenseLength){  struct sg_header *psg_header;  char *buffer;  size_t osize = 0;  ssize_t status;  /* Basic sanity checks */  assert(CDB_Length <= UCHAR_MAX);  assert(RequestSenseLength <= UCHAR_MAX);  /* Clear buffer for cases where sense is not returned */  memset(pRequestSense, 0, RequestSenseLength);  if (pDev[DeviceFD].avail == 0)    {      return(-1);    }  if (pDev[DeviceFD].devopen == 0)      if (SCSI_OpenDevice(DeviceFD) == 0)          return(-1);    if (SCSI_OFF + CDB_Length + DataBufferLength > 4096)     {      SCSI_CloseDevice(DeviceFD);      return(-1);    }  buffer = (char *)malloc(SCSI_OFF + CDB_Length + DataBufferLength);  if (buffer == NULL)    {      dbprintf(_("SCSI_ExecuteCommand memory allocation failure.\n"));      SCSI_CloseDevice(DeviceFD);      return(-1);    }  memset(buffer, 0, SCSI_OFF + CDB_Length + DataBufferLength);  memcpy(buffer + SCSI_OFF, CDB, CDB_Length);    psg_header = (struct sg_header *)buffer;  if (CDB_Length >= 12)    {      psg_header->twelve_byte = 1;    } else {      psg_header->twelve_byte = 0;    }  psg_header->result = 0;  psg_header->reply_len = (int)(SCSI_OFF + DataBufferLength);    switch (Direction)    {    case Input:      osize = 0;      break;    case Output:      osize = DataBufferLength;      break;    }    DecodeSCSI(CDB, "SCSI_ExecuteCommand : ");    status = write(pDev[DeviceFD].fd, buffer, SCSI_OFF + CDB_Length + osize);  if ( (status < (ssize_t)0) ||       (status != (ssize_t)(SCSI_OFF + CDB_Length + osize)) ||       (psg_header->result != 0))     {      dbprintf(_("SCSI_ExecuteCommand error send \n"));      SCSI_CloseDevice(DeviceFD);      amfree(buffer);

⌨️ 快捷键说明

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