* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: scsi-linux.c,v 1.1.2.18.4.1.2.5 2003/07/05 16:59:01 ant Exp $
+ * $Id: scsi-linux.c,v 1.30 2006/07/06 11:57:28 martinea Exp $
*
* Interface to execute SCSI commands on Linux
*
#include <scsi-defs.h>
+extern OpenFiles_T *pDev;
-void SCSI_OS_Version()
+void SCSI_OS_Version(void)
{
#ifndef lint
- static char rcsid[] = "$Id: scsi-linux.c,v 1.1.2.18.4.1.2.5 2003/07/05 16:59:01 ant Exp $";
+ 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)
{
- extern OpenFiles_T *pDev;
int ret = 0;
if (pDev[DeviceFD].devopen == 1)
#ifdef LINUX_SG
int SCSI_OpenDevice(int ip)
{
- extern OpenFiles_T *pDev;
int DeviceFD;
int i;
int timeout;
- int sg_info = 0; /* Used to get some infos about the sg interface */
- int ret = 0; /* To store return results from ioctl etc */
struct stat pstat;
char *buffer = NULL ; /* Will contain the device name after checking */
int openmode = O_RDONLY;
if (S_ISLNK(pstat.st_mode) == 1)
{
DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_OpenDevice : is a link, checking destination\n");
- if ((buffer = (char *)malloc(512)) == NULL)
+ if ((buffer = (char *)malloc(513)) == NULL)
{
DebugPrint(DEBUG_ERROR, SECTION_SCSI,"SCSI_OpenDevice : malloc failed\n");
return(0);
}
- memset(buffer, 0, 512);
+ memset(buffer, 0, 513);
if (( i = readlink(pDev[ip].dev, buffer, 512)) == -1)
{
if (errno == ENAMETOOLONG )
}
DebugPrint(DEBUG_INFO, SECTION_SCSI,"Try to open %s\n", buffer);
- if ((DeviceFD = open(buffer, openmode)) > 0)
+ 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);
}
pDev[ip].SCSI = 1;
}
- pDev[ip].dev = stralloc(buffer);
+ pDev[ip].dev = buffer;
if (pDev[ip].SCSI == 1)
{
- if ((ret = ioctl(DeviceFD, SG_GET_VERSION_NUM, &sg_info)) == 0)
- {
- DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_OpenDevice : SG_VERSION %d\n",sg_info);
- } else {
- DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_OpenDevice : SG_VERSION ioctl returned %d\n", ret);
- }
-
- if ((ret = ioctl(DeviceFD, SG_GET_RESERVED_SIZE, &sg_info)) == 0)
- {
- DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_OpenDevice : SG_RESERVED_SIZE %d\n",sg_info);
- } else {
- DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_OpenDevice : SG_RESERVED_SIZE ioctl returned %d\n", ret);
- }
-
DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_OpenDevice : use SG interface\n");
if ((timeout = ioctl(pDev[ip].fd, SG_GET_TIMEOUT)) > 0)
{
}
}
pDev[ip].inquiry = (SCSIInquiry_T *)malloc(INQUIRY_SIZE);
- if (SCSI_Inquiry(ip, pDev[ip].inquiry, INQUIRY_SIZE) == 0)
+ 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)
{
return(1);
} else {
close(DeviceFD);
- free(pDev[ip].inquiry);
+ amfree(pDev[ip].inquiry);
DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### STOP SCSI_OpenDevice (0)\n");
return(0);
}
pDev[ip].SCSI = 0;
pDev[ip].devopen = 0;
close(DeviceFD);
- free(pDev[ip].inquiry);
+ amfree(pDev[ip].inquiry);
pDev[ip].inquiry = NULL;
DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### STOP SCSI_OpenDevice (1)\n");
return(1);
} else {
openmode = O_RDONLY;
}
- if ((DeviceFD = open(pDev[ip].dev, openmode)) > 0)
+ if ((DeviceFD = open(pDev[ip].dev, openmode)) >= 0)
{
pDev[ip].devopen = 1;
pDev[ip].fd = DeviceFD;
return(0);
}
-#define SCSI_OFF sizeof(struct sg_header)
+#define SCSI_OFF SIZEOF(struct sg_header)
int SCSI_ExecuteCommand(int DeviceFD,
Direction_T Direction,
CDB_T CDB,
- int CDB_Length,
+ size_t CDB_Length,
void *DataBuffer,
- int DataBufferLength,
- char *pRequestSense,
- int RequestSenseLength)
+ size_t DataBufferLength,
+ RequestSense_T *pRequestSense,
+ size_t RequestSenseLength)
{
- extern OpenFiles_T *pDev;
struct sg_header *psg_header;
char *buffer;
- int osize = 0;
- int status;
+ 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)
{
}
if (pDev[DeviceFD].devopen == 0)
+ if (SCSI_OpenDevice(DeviceFD) == 0)
+ return(-1);
+
+ if (SCSI_OFF + CDB_Length + DataBufferLength > 4096)
{
- SCSI_OpenDevice(DeviceFD);
+ SCSI_CloseDevice(DeviceFD);
+ return(-1);
}
-
-/* if (SCSI_OFF + CDB_Length + DataBufferLength > 4096) */
-/* { */
-/* SCSI_CloseDevice(DeviceFD); */
-/* DebugPrint(DEBUG_ERROR, SECTION_SCSI,"##### SCSI_ExecuteCommand error, SCSI_OFF + CDB_Length + DataBufferLength > 4096\n"); */
-/* 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->twelve_byte = 0;
}
psg_header->result = 0;
- psg_header->reply_len = SCSI_OFF + DataBufferLength;
+ psg_header->reply_len = (int)(SCSI_OFF + DataBufferLength);
switch (Direction)
{
DecodeSCSI(CDB, "SCSI_ExecuteCommand : ");
status = write(pDev[DeviceFD].fd, buffer, SCSI_OFF + CDB_Length + osize);
- if ( status < 0 || status != SCSI_OFF + CDB_Length + osize ||
- psg_header->result )
+ 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);
return(SCSI_ERROR);
}
memset(pRequestSense, 0, RequestSenseLength);
memcpy(pRequestSense, psg_header->sense_buffer, 16);
- if ( status < 0 || status != SCSI_OFF + DataBufferLength ||
- psg_header->result )
+ if ( (status < 0) ||
+ (status != (ssize_t)(SCSI_OFF + DataBufferLength)) ||
+ (psg_header->result != 0))
{
dbprintf(("SCSI_ExecuteCommand error read \n"));
- dbprintf(("Status %d (%d) %2X\n", status, SCSI_OFF + DataBufferLength, psg_header->result ));
+ dbprintf(("Status " SSIZE_T_FMT " (" SSIZE_T_FMT ") %2X\n", status, SCSI_OFF + DataBufferLength,psg_header->result ));
SCSI_CloseDevice(DeviceFD);
+ amfree(buffer);
return(SCSI_ERROR);
}
memcpy(DataBuffer, buffer + SCSI_OFF, DataBufferLength);
}
- free(buffer);
SCSI_CloseDevice(DeviceFD);
+ amfree(buffer);
return(SCSI_OK);
}
int SCSI_OpenDevice(int ip)
{
- extern OpenFiles_T *pDev;
int DeviceFD;
int i;
if (pDev[ip].inqdone == 0)
{
pDev[ip].inqdone = 1;
- if ((DeviceFD = open(pDev[ip].dev, O_RDWR)) > 0)
+ if ((DeviceFD = open(pDev[ip].dev, O_RDWR)) >= 0)
{
pDev[ip].avail = 1;
pDev[ip].fd = DeviceFD;
pDev[ip].SCSI = 0;
pDev[ip].inquiry = (SCSIInquiry_T *)malloc(INQUIRY_SIZE);
dbprintf(("SCSI_OpenDevice : use ioctl interface\n"));
- if (SCSI_Inquiry(ip, pDev[ip].inquiry, INQUIRY_SIZE) == 0)
+ 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)
{
PrintInquiry(pDev[ip].inquiry);
return(1);
} else {
- free(pDev[ip].inquiry);
+ amfree(pDev[ip].inquiry);
close(DeviceFD);
return(0);
}
} else {
close(DeviceFD);
- free(pDev[ip].inquiry);
+ amfree(pDev[ip].inquiry);
pDev[ip].inquiry = NULL;
return(1);
}
}
return(1);
} else {
- if ((DeviceFD = open(pDev[ip].dev, O_RDWR)) > 0)
+ if ((DeviceFD = open(pDev[ip].dev, O_RDWR)) >= 0)
{
pDev[ip].fd = DeviceFD;
pDev[ip].devopen = 1;
int CDB_Length,
void *DataBuffer,
int DataBufferLength,
- char *pRequestSense,
+ RequestSense_T *pRequestSense,
int RequestSenseLength)
{
- extern OpenFiles_T *pDev;
unsigned char *Command;
int Zero = 0, Result;
if (pDev[DeviceFD].devopen == 0)
{
- SCSI_OpenDevice(DeviceFD);
+ if (SCSI_OpenDevice(DeviceFD) == 0)
+ return(-1);
}
memset(pRequestSense, 0, RequestSenseLength);
memcpy(pRequestSense, &Command[8], RequestSenseLength);
else if (Direction == Input)
memcpy(DataBuffer, &Command[8], DataBufferLength);
- free(Command);
+ amfree(Command);
SCSI_CloseDevice(DeviceFD);
switch(Result)
*/
int Tape_Ioctl( int DeviceFD, int command)
{
- extern OpenFiles_T *pDev;
struct mtop mtop;
int ret = 0;
if (pDev[DeviceFD].devopen == 0)
{
- SCSI_OpenDevice(DeviceFD);
+ if (SCSI_OpenDevice(DeviceFD) == 0)
+ return(-1);
}
switch (command)
if (ioctl(pDev[DeviceFD].fd , MTIOCTOP, &mtop) != 0)
{
- dbprintf(("Tape_Ioctl error ioctl %d\n",errno));
+ dbprintf(("Tape_Ioctl error ioctl %s\n",strerror(errno)));
SCSI_CloseDevice(DeviceFD);
return(-1);
}
int Tape_Status( int DeviceFD)
{
- extern OpenFiles_T *pDev;
struct mtget mtget;
int ret = 0;
+ memset(&mtget, 0, SIZEOF(mtget));
if (pDev[DeviceFD].devopen == 0)
{
- SCSI_OpenDevice(DeviceFD);
+ if (SCSI_OpenDevice(DeviceFD) == 0)
+ return(-1);
}
if (ioctl(pDev[DeviceFD].fd , MTIOCGET, &mtget) != 0)
{
- DebugPrint(DEBUG_ERROR, SECTION_TAPE,"Tape_Status error ioctl %d\n",errno);
+ DebugPrint(DEBUG_ERROR, SECTION_TAPE,"Tape_Status error ioctl %s\n",
+ strerror(errno));
SCSI_CloseDevice(DeviceFD);
return(-1);
}
{
DIR *dir;
struct dirent *dirent;
- extern OpenFiles_T *pDev;
- extern int errno;
int count = 0;
- dir = opendir("/dev/");
+ if ((dir = opendir("/dev/")) == NULL)
+ {
+ dbprintf(("/dev/ error: %s", strerror(errno)));
+ return 0;
+ }
while ((dirent = readdir(dir)) != NULL)
{
{
pDev[count].dev = malloc(10);
pDev[count].inqdone = 0;
- sprintf(pDev[count].dev,"/dev/%s", dirent->d_name);
+ snprintf(pDev[count].dev, SIZEOF(pDev[count].dev),
+ "/dev/%s", dirent->d_name);
if (OpenDevice(count,pDev[count].dev, "Scan", NULL ))
{
SCSI_CloseDevice(count);
count++;
printf("Count %d\n",count);
} else {
- free(pDev[count].dev);
+ amfree(pDev[count].dev);
pDev[count].dev=NULL;
}
}