dlls/ntdll/cdrom.c CDROM_ScsiPassThrough on NetBSD
Yorick Hardy
yh at metroweb.co.za
Mon May 19 14:25:16 CDT 2003
Implement CDROM_ScsiPassThrough and CDROM_ScsiPassThroughDirect
on NetBSD in dlls/ntdll/cdrom.c
The patch for CDROM_GetIdeInterface on NetBSD should be applied
first.
--
Yorick Hardy
--- dlls/ntdll/cdrom.c Mon May 19 20:54:02 2003
+++ dlls/ntdll/cdrom.c Mon May 19 21:03:49 2003
@@ -1359,11 +1359,15 @@
static DWORD CDROM_ScsiPassThroughDirect(int dev, PSCSI_PASS_THROUGH_DIRECT pPacket)
{
int ret = STATUS_NOT_SUPPORTED;
+ int io;
#if defined(linux) && defined(CDROM_SEND_PACKET)
struct linux_cdrom_generic_command cmd;
struct request_sense sense;
- int io;
+#elif defined(__NetBSD__)
+ scsireq_t cmd;
+#endif
+#if defined(linux) && defined(CDROM_SEND_PACKET)
if (pPacket->Length < sizeof(SCSI_PASS_THROUGH_DIRECT))
return STATUS_BUFFER_TOO_SMALL;
@@ -1410,6 +1414,64 @@
pPacket->ScsiStatus = cmd.stat;
ret = CDROM_GetStatusCode(io);
+
+#elif defined(__NetBSD__)
+ if (pPacket->Length < sizeof(SCSI_PASS_THROUGH_DIRECT))
+ return STATUS_BUFFER_TOO_SMALL;
+
+ if (pPacket->CdbLength > 12)
+ return STATUS_INVALID_PARAMETER;
+
+ if (pPacket->SenseInfoLength > SENSEBUFLEN)
+ return STATUS_INVALID_PARAMETER;
+
+ memset(&cmd, 0, sizeof(cmd));
+ memcpy(&(cmd.cmd), &(pPacket->Cdb), pPacket->CdbLength);
+
+ cmd.cmdlen = pPacket->CdbLength;
+ cmd.databuf = pPacket->DataBuffer;
+ cmd.datalen = pPacket->DataTransferLength;
+ cmd.senselen = pPacket->SenseInfoLength;
+ cmd.timeout = pPacket->TimeOutValue*1000; /* in milliseconds */
+
+ switch (pPacket->DataIn)
+ {
+ case SCSI_IOCTL_DATA_OUT:
+ cmd.flags |= SCCMD_WRITE;
+ break;
+ case SCSI_IOCTL_DATA_IN:
+ cmd.flags |= SCCMD_READ;
+ break;
+ case SCSI_IOCTL_DATA_UNSPECIFIED:
+ cmd.flags = 0;
+ break;
+ default:
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ io = ioctl(cdrom_cache[dev].fd, SCIOCCOMMAND, &cmd);
+
+ switch (cmd.retsts)
+ {
+ case SCCMD_OK: break;
+ case SCCMD_TIMEOUT: return STATUS_TIMEOUT;
+ break;
+ case SCCMD_BUSY: return STATUS_DEVICE_BUSY;
+ break;
+ case SCCMD_SENSE: break;
+ case SCCMD_UNKNOWN: return STATUS_UNSUCCESSFUL;
+ break;
+ }
+
+ if (pPacket->SenseInfoLength != 0)
+ {
+ memcpy((char*)pPacket + pPacket->SenseInfoOffset,
+ cmd.sense, pPacket->SenseInfoLength);
+ }
+
+ pPacket->ScsiStatus = cmd.status;
+
+ ret = CDROM_GetStatusCode(io);
#endif
return ret;
}
@@ -1422,11 +1484,15 @@
static DWORD CDROM_ScsiPassThrough(int dev, PSCSI_PASS_THROUGH pPacket)
{
int ret = STATUS_NOT_SUPPORTED;
+ int io;
#if defined(linux) && defined(CDROM_SEND_PACKET)
struct linux_cdrom_generic_command cmd;
struct request_sense sense;
- int io;
+#elif defined(__NetBSD__)
+ scsireq_t cmd;
+#endif
+#if defined(linux) && defined(CDROM_SEND_PACKET)
if (pPacket->Length < sizeof(SCSI_PASS_THROUGH))
return STATUS_BUFFER_TOO_SMALL;
@@ -1478,6 +1544,72 @@
}
pPacket->ScsiStatus = cmd.stat;
+
+ ret = CDROM_GetStatusCode(io);
+
+#elif defined(__NetBSD__)
+ if (pPacket->Length < sizeof(SCSI_PASS_THROUGH))
+ return STATUS_BUFFER_TOO_SMALL;
+
+ if (pPacket->CdbLength > 12)
+ return STATUS_INVALID_PARAMETER;
+
+ if (pPacket->SenseInfoLength > SENSEBUFLEN)
+ return STATUS_INVALID_PARAMETER;
+
+ memset(&cmd, 0, sizeof(cmd));
+ memcpy(&(cmd.cmd), &(pPacket->Cdb), pPacket->CdbLength);
+
+ if ( pPacket->DataBufferOffset > 0x1000 )
+ {
+ cmd.databuf = (void*)pPacket->DataBufferOffset;
+ }
+ else
+ {
+ cmd.databuf = (char*)pPacket + pPacket->DataBufferOffset;
+ }
+
+ cmd.cmdlen = pPacket->CdbLength;
+ cmd.datalen = pPacket->DataTransferLength;
+ cmd.senselen = pPacket->SenseInfoLength;
+ cmd.timeout = pPacket->TimeOutValue*1000; /* in milliseconds */
+
+ switch (pPacket->DataIn)
+ {
+ case SCSI_IOCTL_DATA_OUT:
+ cmd.flags |= SCCMD_WRITE;
+ break;
+ case SCSI_IOCTL_DATA_IN:
+ cmd.flags |= SCCMD_READ;
+ break;
+ case SCSI_IOCTL_DATA_UNSPECIFIED:
+ cmd.flags = 0;
+ break;
+ default:
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ io = ioctl(cdrom_cache[dev].fd, SCIOCCOMMAND, &cmd);
+
+ switch (cmd.retsts)
+ {
+ case SCCMD_OK: break;
+ case SCCMD_TIMEOUT: return STATUS_TIMEOUT;
+ break;
+ case SCCMD_BUSY: return STATUS_DEVICE_BUSY;
+ break;
+ case SCCMD_SENSE: break;
+ case SCCMD_UNKNOWN: return STATUS_UNSUCCESSFUL;
+ break;
+ }
+
+ if (pPacket->SenseInfoLength != 0)
+ {
+ memcpy((char*)pPacket + pPacket->SenseInfoOffset,
+ cmd.sense, pPacket->SenseInfoLength);
+ }
+
+ pPacket->ScsiStatus = cmd.status;
ret = CDROM_GetStatusCode(io);
#endif
More information about the wine-patches
mailing list