Charles Davis : ntdll: Implement IOCTL_SCSI_PASS_THROUGH(_DIRECT) on Mac OS .
Alexandre Julliard
julliard at winehq.org
Wed May 5 11:08:35 CDT 2010
Module: wine
Branch: master
Commit: 1e0cee6d3c343ad21e3a4d69cfa9d1d164943745
URL: http://source.winehq.org/git/wine.git/?a=commit;h=1e0cee6d3c343ad21e3a4d69cfa9d1d164943745
Author: Charles Davis <cdavis at mymail.mines.edu>
Date: Tue May 4 23:57:02 2010 -0600
ntdll: Implement IOCTL_SCSI_PASS_THROUGH(_DIRECT) on Mac OS.
---
dlls/ntdll/cdrom.c | 145 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 145 insertions(+), 0 deletions(-)
diff --git a/dlls/ntdll/cdrom.c b/dlls/ntdll/cdrom.c
index 069ac01..ab68459 100644
--- a/dlls/ntdll/cdrom.c
+++ b/dlls/ntdll/cdrom.c
@@ -83,8 +83,28 @@
# include <IOKit/storage/IOMedia.h>
# include <IOKit/storage/IOCDMediaBSDClient.h>
# include <IOKit/storage/IODVDMediaBSDClient.h>
+# include <IOKit/scsi/SCSITask.h>
# include <IOKit/scsi/SCSICmds_REQUEST_SENSE_Defs.h>
# define SENSEBUFLEN kSenseDefaultSize
+
+typedef struct
+{
+ uint32_t attribute;
+ uint32_t timeout;
+ uint32_t response;
+ uint32_t status;
+ uint8_t direction;
+ uint8_t cdbSize;
+ uint8_t reserved0144[2];
+ uint8_t cdb[16];
+ void* buffer;
+ uint64_t bufferSize;
+ void* sense;
+ uint64_t senseLen;
+} dk_scsi_command_t;
+
+#define DKIOCSCSICOMMAND _IOWR('d', 253, dk_scsi_command_t)
+
#endif
#define NONAMELESSUNION
@@ -1649,6 +1669,9 @@ static NTSTATUS CDROM_ScsiPassThroughDirect(int fd, PSCSI_PASS_THROUGH_DIRECT pP
#elif defined HAVE_SCSIREQ_T_CMD
scsireq_t cmd;
int io;
+#elif defined __APPLE__
+ dk_scsi_command_t cmd;
+ int io;
#endif
if (pPacket->Length < sizeof(SCSI_PASS_THROUGH_DIRECT))
@@ -1752,6 +1775,64 @@ static NTSTATUS CDROM_ScsiPassThroughDirect(int fd, PSCSI_PASS_THROUGH_DIRECT pP
pPacket->ScsiStatus = cmd.status;
ret = CDROM_GetStatusCode(io);
+
+#elif defined(__APPLE__)
+
+ memset(&cmd, 0, sizeof(cmd));
+ memcpy(cmd.cdb, pPacket->Cdb, pPacket->CdbLength);
+
+ cmd.cdbSize = pPacket->CdbLength;
+ cmd.buffer = pPacket->DataBuffer;
+ cmd.bufferSize = pPacket->DataTransferLength;
+ cmd.sense = (char*)pPacket + pPacket->SenseInfoOffset;
+ cmd.senseLen = pPacket->SenseInfoLength;
+ cmd.timeout = pPacket->TimeOutValue*1000; /* in milliseconds */
+
+ switch (pPacket->DataIn)
+ {
+ case SCSI_IOCTL_DATA_OUT:
+ cmd.direction = kSCSIDataTransfer_FromInitiatorToTarget;
+ break;
+ case SCSI_IOCTL_DATA_IN:
+ cmd.direction = kSCSIDataTransfer_FromTargetToInitiator;
+ break;
+ case SCSI_IOCTL_DATA_UNSPECIFIED:
+ cmd.direction = kSCSIDataTransfer_NoDataTransfer;
+ break;
+ default:
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ io = ioctl(fd, DKIOCSCSICOMMAND, &cmd);
+
+ if (cmd.response == kSCSIServiceResponse_SERVICE_DELIVERY_OR_TARGET_FAILURE)
+ {
+ /* Command failed */
+ switch (cmd.status)
+ {
+ case kSCSITaskStatus_TaskTimeoutOccurred: return STATUS_TIMEOUT;
+ break;
+ case kSCSITaskStatus_ProtocolTimeoutOccurred: return STATUS_IO_TIMEOUT;
+ break;
+ case kSCSITaskStatus_DeviceNotResponding: return STATUS_DEVICE_BUSY;
+ break;
+ case kSCSITaskStatus_DeviceNotPresent:
+ return STATUS_NO_SUCH_DEVICE;
+ break;
+ case kSCSITaskStatus_DeliveryFailure:
+ return STATUS_DEVICE_PROTOCOL_ERROR;
+ break;
+ case kSCSITaskStatus_No_Status:
+ default:
+ return STATUS_UNSUCCESSFUL;
+ break;
+ }
+ }
+
+ if (cmd.status != kSCSITaskStatus_No_Status)
+ pPacket->ScsiStatus = cmd.status;
+
+ ret = CDROM_GetStatusCode(io);
#endif
return ret;
}
@@ -1770,6 +1851,9 @@ static NTSTATUS CDROM_ScsiPassThrough(int fd, PSCSI_PASS_THROUGH pPacket)
#elif defined HAVE_SCSIREQ_T_CMD
scsireq_t cmd;
int io;
+#elif defined __APPLE__
+ dk_scsi_command_t cmd;
+ int io;
#endif
if (pPacket->Length < sizeof(SCSI_PASS_THROUGH))
@@ -1883,6 +1967,67 @@ static NTSTATUS CDROM_ScsiPassThrough(int fd, PSCSI_PASS_THROUGH pPacket)
pPacket->ScsiStatus = cmd.status;
ret = CDROM_GetStatusCode(io);
+
+#elif defined(__APPLE__)
+
+ memset(&cmd, 0, sizeof(cmd));
+ memcpy(cmd.cdb, pPacket->Cdb, pPacket->CdbLength);
+
+ cmd.cdbSize = pPacket->CdbLength;
+ cmd.buffer = (char*)pPacket + pPacket->DataBufferOffset;
+ cmd.bufferSize = pPacket->DataTransferLength;
+ cmd.sense = (char*)pPacket + pPacket->SenseInfoOffset;
+ cmd.senseLen = pPacket->SenseInfoLength;
+ cmd.timeout = pPacket->TimeOutValue*1000; /* in milliseconds */
+
+ switch (pPacket->DataIn)
+ {
+ case SCSI_IOCTL_DATA_OUT:
+ cmd.direction = kSCSIDataTransfer_FromInitiatorToTarget;
+ break;
+ case SCSI_IOCTL_DATA_IN:
+ cmd.direction = kSCSIDataTransfer_FromTargetToInitiator;
+ break;
+ case SCSI_IOCTL_DATA_UNSPECIFIED:
+ cmd.direction = kSCSIDataTransfer_NoDataTransfer;
+ break;
+ default:
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ io = ioctl(fd, DKIOCSCSICOMMAND, &cmd);
+
+ if (cmd.response == kSCSIServiceResponse_SERVICE_DELIVERY_OR_TARGET_FAILURE)
+ {
+ /* Command failed */
+ switch (cmd.status)
+ {
+ case kSCSITaskStatus_TaskTimeoutOccurred:
+ return STATUS_TIMEOUT;
+ break;
+ case kSCSITaskStatus_ProtocolTimeoutOccurred:
+ return STATUS_IO_TIMEOUT;
+ break;
+ case kSCSITaskStatus_DeviceNotResponding:
+ return STATUS_DEVICE_BUSY;
+ break;
+ case kSCSITaskStatus_DeviceNotPresent:
+ return STATUS_NO_SUCH_DEVICE;
+ break;
+ case kSCSITaskStatus_DeliveryFailure:
+ return STATUS_DEVICE_PROTOCOL_ERROR;
+ break;
+ case kSCSITaskStatus_No_Status:
+ default:
+ return STATUS_UNSUCCESSFUL;
+ break;
+ }
+ }
+
+ if (cmd.status != kSCSITaskStatus_No_Status)
+ pPacket->ScsiStatus = cmd.status;
+
+ ret = CDROM_GetStatusCode(io);
#endif
return ret;
}
More information about the wine-cvs
mailing list