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