Reimplement IOCTL_SCSI_PASS_THROUGH_DIRECT and
IOCTL_SCSI_PASS_THROUGH on top of the linux scsi driver.
This commit is contained in:
parent
8272074b85
commit
eacd06264e
|
@ -4,6 +4,7 @@
|
||||||
* Copyright 1994 Martin Ayotte
|
* Copyright 1994 Martin Ayotte
|
||||||
* Copyright 1999, 2001, 2003 Eric Pouech
|
* Copyright 1999, 2001, 2003 Eric Pouech
|
||||||
* Copyright 2000 Andreas Mohr
|
* Copyright 2000 Andreas Mohr
|
||||||
|
* Copyright 2005 Ivan Leo Puoti
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
@ -1397,62 +1398,61 @@ static NTSTATUS CDROM_RawRead(int fd, const RAW_READ_INFO* raw, void* buffer, DW
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************
|
/******************************************************************
|
||||||
* CDROM_ScsiPassThroughDirect
|
* CDROM_ScsiPassThroughDirect
|
||||||
*
|
* Implements IOCTL_SCSI_PASS_THROUGH_DIRECT
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static NTSTATUS CDROM_ScsiPassThroughDirect(int fd, PSCSI_PASS_THROUGH_DIRECT pPacket)
|
static NTSTATUS CDROM_ScsiPassThroughDirect(int fd, PSCSI_PASS_THROUGH_DIRECT pPacket)
|
||||||
{
|
{
|
||||||
int ret = STATUS_NOT_SUPPORTED;
|
int ret = STATUS_NOT_SUPPORTED;
|
||||||
#if defined(linux) && defined(CDROM_SEND_PACKET)
|
|
||||||
struct linux_cdrom_generic_command cmd;
|
#if defined(linux)
|
||||||
struct request_sense sense;
|
sg_io_hdr_t cmd;
|
||||||
int io;
|
int io;
|
||||||
|
|
||||||
if (pPacket->Length < sizeof(SCSI_PASS_THROUGH_DIRECT))
|
if (pPacket->Length < sizeof(SCSI_PASS_THROUGH_DIRECT))
|
||||||
return STATUS_BUFFER_TOO_SMALL;
|
return STATUS_BUFFER_TOO_SMALL;
|
||||||
|
|
||||||
if (pPacket->CdbLength > 12)
|
if (pPacket->CdbLength > 16)
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
if (pPacket->SenseInfoLength > sizeof(sense))
|
if (pPacket->SenseInfoLength > sizeof(struct request_sense))
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
memset(&cmd, 0, sizeof(cmd));
|
if (pPacket->DataTransferLength > 0 && !pPacket->DataBuffer)
|
||||||
memset(&sense, 0, sizeof(sense));
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
memcpy(&(cmd.cmd), &(pPacket->Cdb), pPacket->CdbLength);
|
RtlZeroMemory(&cmd, sizeof(cmd));
|
||||||
|
|
||||||
cmd.buffer = pPacket->DataBuffer;
|
cmd.interface_id = 'S';
|
||||||
cmd.buflen = pPacket->DataTransferLength;
|
cmd.cmd_len = pPacket->CdbLength;
|
||||||
cmd.sense = &sense;
|
cmd.mx_sb_len = pPacket->SenseInfoLength;
|
||||||
cmd.quiet = 0;
|
cmd.dxfer_len = pPacket->DataTransferLength;
|
||||||
cmd.timeout = pPacket->TimeOutValue*HZ;
|
cmd.dxferp = pPacket->DataBuffer;
|
||||||
|
cmd.cmdp = pPacket->Cdb;
|
||||||
|
cmd.sbp = (char*)pPacket + pPacket->SenseInfoOffset;
|
||||||
|
cmd.timeout = pPacket->TimeOutValue*1000;
|
||||||
|
|
||||||
switch (pPacket->DataIn)
|
switch (pPacket->DataIn)
|
||||||
{
|
{
|
||||||
case SCSI_IOCTL_DATA_OUT:
|
|
||||||
cmd.data_direction = CGC_DATA_WRITE;
|
|
||||||
break;
|
|
||||||
case SCSI_IOCTL_DATA_IN:
|
case SCSI_IOCTL_DATA_IN:
|
||||||
cmd.data_direction = CGC_DATA_READ;
|
cmd.dxfer_direction = SG_DXFER_TO_DEV;
|
||||||
break;
|
break;
|
||||||
|
case SCSI_IOCTL_DATA_OUT:
|
||||||
|
cmd.dxfer_direction = SG_DXFER_FROM_DEV;
|
||||||
|
break;
|
||||||
case SCSI_IOCTL_DATA_UNSPECIFIED:
|
case SCSI_IOCTL_DATA_UNSPECIFIED:
|
||||||
cmd.data_direction = CGC_DATA_NONE;
|
cmd.dxfer_direction = SG_DXFER_NONE;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
io = ioctl(fd, CDROM_SEND_PACKET, &cmd);
|
io = ioctl(fd, SG_IO, &cmd);
|
||||||
|
|
||||||
if (pPacket->SenseInfoLength != 0)
|
pPacket->ScsiStatus = cmd.status;
|
||||||
{
|
pPacket->DataTransferLength = cmd.resid;
|
||||||
memcpy((char*)pPacket + pPacket->SenseInfoOffset,
|
pPacket->SenseInfoLength = cmd.sb_len_wr;
|
||||||
&sense, pPacket->SenseInfoLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
pPacket->ScsiStatus = cmd.stat;
|
|
||||||
|
|
||||||
ret = CDROM_GetStatusCode(io);
|
ret = CDROM_GetStatusCode(io);
|
||||||
|
|
||||||
|
@ -1521,69 +1521,62 @@ static NTSTATUS CDROM_ScsiPassThroughDirect(int fd, PSCSI_PASS_THROUGH_DIRECT pP
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************
|
/******************************************************************
|
||||||
* CDROM_ScsiPassThrough
|
* CDROM_ScsiPassThrough
|
||||||
*
|
* Implements IOCTL_SCSI_PASS_THROUGH
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static NTSTATUS CDROM_ScsiPassThrough(int fd, PSCSI_PASS_THROUGH pPacket)
|
static NTSTATUS CDROM_ScsiPassThrough(int fd, PSCSI_PASS_THROUGH pPacket)
|
||||||
{
|
{
|
||||||
int ret = STATUS_NOT_SUPPORTED;
|
int ret = STATUS_NOT_SUPPORTED;
|
||||||
#if defined(linux) && defined(CDROM_SEND_PACKET)
|
#if defined(linux)
|
||||||
struct linux_cdrom_generic_command cmd;
|
sg_io_hdr_t cmd;
|
||||||
struct request_sense sense;
|
|
||||||
int io;
|
int io;
|
||||||
|
|
||||||
if (pPacket->Length < sizeof(SCSI_PASS_THROUGH))
|
if (pPacket->Length < sizeof(SCSI_PASS_THROUGH))
|
||||||
return STATUS_BUFFER_TOO_SMALL;
|
return STATUS_BUFFER_TOO_SMALL;
|
||||||
|
|
||||||
if (pPacket->CdbLength > 12)
|
if (pPacket->CdbLength > 16)
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
if (pPacket->SenseInfoLength > sizeof(sense))
|
if (pPacket->SenseInfoLength > sizeof(struct request_sense))
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
memset(&cmd, 0, sizeof(cmd));
|
if (pPacket->DataTransferLength > 0 && pPacket->DataBufferOffset < sizeof(SCSI_PASS_THROUGH))
|
||||||
memset(&sense, 0, sizeof(sense));
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
memcpy(&(cmd.cmd), &(pPacket->Cdb), pPacket->CdbLength);
|
RtlZeroMemory(&cmd, sizeof(cmd));
|
||||||
|
|
||||||
if ( pPacket->DataBufferOffset > 0x1000 )
|
cmd.interface_id = 'S';
|
||||||
{
|
cmd.dxfer_len = pPacket->DataTransferLength;
|
||||||
cmd.buffer = (void*)pPacket->DataBufferOffset;
|
cmd.dxferp = (char*)pPacket + pPacket->DataBufferOffset;
|
||||||
}
|
cmd.cmd_len = pPacket->CdbLength;
|
||||||
else
|
cmd.cmdp = pPacket->Cdb;
|
||||||
{
|
cmd.mx_sb_len = pPacket->SenseInfoLength;
|
||||||
cmd.buffer = (char*)pPacket + pPacket->DataBufferOffset;
|
cmd.timeout = pPacket->TimeOutValue*1000;
|
||||||
}
|
|
||||||
cmd.buflen = pPacket->DataTransferLength;
|
if(cmd.mx_sb_len > 0)
|
||||||
cmd.sense = &sense;
|
cmd.sbp = (char*)pPacket + pPacket->SenseInfoOffset;
|
||||||
cmd.quiet = 0;
|
|
||||||
cmd.timeout = pPacket->TimeOutValue*HZ;
|
|
||||||
|
|
||||||
switch (pPacket->DataIn)
|
switch (pPacket->DataIn)
|
||||||
{
|
{
|
||||||
case SCSI_IOCTL_DATA_OUT:
|
|
||||||
cmd.data_direction = CGC_DATA_WRITE;
|
|
||||||
break;
|
|
||||||
case SCSI_IOCTL_DATA_IN:
|
case SCSI_IOCTL_DATA_IN:
|
||||||
cmd.data_direction = CGC_DATA_READ;
|
cmd.dxfer_direction = SG_DXFER_TO_DEV;
|
||||||
break;
|
break;
|
||||||
|
case SCSI_IOCTL_DATA_OUT:
|
||||||
|
cmd.dxfer_direction = SG_DXFER_FROM_DEV;
|
||||||
|
break;
|
||||||
case SCSI_IOCTL_DATA_UNSPECIFIED:
|
case SCSI_IOCTL_DATA_UNSPECIFIED:
|
||||||
cmd.data_direction = CGC_DATA_NONE;
|
cmd.dxfer_direction = SG_DXFER_NONE;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
io = ioctl(fd, CDROM_SEND_PACKET, &cmd);
|
io = ioctl(fd, SG_IO, &cmd);
|
||||||
|
|
||||||
if (pPacket->SenseInfoLength != 0)
|
pPacket->ScsiStatus = cmd.status;
|
||||||
{
|
pPacket->DataTransferLength = cmd.resid;
|
||||||
memcpy((char*)pPacket + pPacket->SenseInfoOffset,
|
pPacket->SenseInfoLength = cmd.sb_len_wr;
|
||||||
&sense, pPacket->SenseInfoLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
pPacket->ScsiStatus = cmd.stat;
|
|
||||||
|
|
||||||
ret = CDROM_GetStatusCode(io);
|
ret = CDROM_GetStatusCode(io);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue