WARN("Could not get device name for h%02dc%02dt%02dd%02d\n",h,c,t,d);
return-1;
}
TRACE("Opening device %s mode O_RDWR\n",devstr);
fd=open(devstr,O_RDWR);
if(fd==-1){
char*errstring=strerror(errno);
ERR("Failed to open device %s: %s\n",devstr,errstring);
}
returnfd;
}
#ifdef linux
/* SCSI_Fix_CMD_LEN
* Checks to make sure the CMD_LEN is correct
*/
void
SCSI_Fix_CMD_LEN(intfd,intcmd,intlen)
{
/* This is what the linux kernel thinks.... */
staticconstunsignedcharscsi_command_size[8]=
{
6,10,10,12,
12,12,10,10
};
intindex=(cmd>>5)&7;
if(len!=scsi_command_size[index])
{
TRACE("CDBLen for command %d claims to be %d, expected %d\n",
cmd,len,scsi_command_size[index]);
ioctl(fd,SG_NEXT_CMD_LEN,&len);
}
}
int
SCSI_LinuxSetTimeout(intfd,inttimeout)
{
intretval;
TRACE("Setting timeout to %d jiffies\n",timeout);
retval=ioctl(fd,SG_SET_TIMEOUT,&timeout);
if(retval)
{
WARN("Could not set timeout ! (%s)\n",strerror(errno));
}
returnretval;
}
/* This function takes care of the write/read to the linux sg device.
* It returns TRUE or FALSE and uses set_last_error() to convert
* UNIX errno to Windows GetLastError(). The reason for that is that
* several programs will check that error and we might as well set
* it here. We also return the value of the read call in
* lpcbBytesReturned.
*/
BOOL/* NOTE: This function SHOULD BLOCK */
SCSI_LinuxDeviceIo(intfd,
structsg_header*lpInBuffer,DWORDcbInBuffer,
structsg_header*lpOutBuffer,DWORDcbOutBuffer,
LPDWORDlpcbBytesReturned)
{
DWORDdwBytes;
DWORDsave_error;
TRACE("Writing to Linux sg device\n");
dwBytes=write(fd,lpInBuffer,cbInBuffer);
if(dwBytes!=cbInBuffer)
{
set_last_error();
save_error=GetLastError();
WARN("Not enough bytes written to scsi device. bytes=%d .. %d\n",cbInBuffer,dwBytes);
/* FIXME: set_last_error() never sets error to ERROR_NOT_ENOUGH_MEMORY... */
if(save_error==ERROR_NOT_ENOUGH_MEMORY)
MESSAGE("Your Linux kernel was not able to handle the amount of data sent to the scsi device. Try recompiling with a larger SG_BIG_BUFF value (kernel 2.0.x sg.h)\n");