Resubmit: Try 3:Implement IOCTL_SCSI_GET_INQUIRY_DATA
Vitaliy Margolen
wine-patch at kievinfo.com
Tue Aug 2 10:07:44 CDT 2005
Move #ifdef to protect some variables as well.
Check for HAVE_SG_IO_HDR_T_INTERFACE_ID instead of defined Linux
Implement IOCTL_SCSI_GET_INQUIRY_DATA. It is somewhat limited right now -
doesn't enumerate all devices on a given bus.
Vitaliy Margolen
changelog:
Implement IOCTL_SCSI_GET_INQUIRY_DATA
-------------- next part --------------
Index: dlls/ntdll/cdrom.c
===================================================================
RCS file: /home/wine/wine/dlls/ntdll/cdrom.c,v
retrieving revision 1.63
diff -u -p -r1.63 cdrom.c
--- dlls/ntdll/cdrom.c 20 Jul 2005 10:28:27 -0000 1.63
+++ dlls/ntdll/cdrom.c 28 Jul 2005 13:48:28 -0000
@@ -288,6 +288,7 @@ X(IOCTL_DVD_SEND_KEY)
X(IOCTL_DVD_START_SESSION)
X(IOCTL_SCSI_GET_ADDRESS)
X(IOCTL_SCSI_GET_CAPABILITIES)
+X(IOCTL_SCSI_GET_INQUIRY_DATA)
X(IOCTL_SCSI_PASS_THROUGH)
X(IOCTL_SCSI_PASS_THROUGH_DIRECT)
X(IOCTL_STORAGE_CHECK_VERIFY)
@@ -310,6 +311,8 @@ static const char *iocodex(DWORD code)
return buffer;
}
+#define INQ_REPLY_LEN 36
+#define INQ_CMD_LEN 6
WINE_DEFAULT_DEBUG_CHANNEL(cdrom);
#define FRAME_OF_ADDR(a) (((int)(a)[1] * CD_SECS + (a)[2]) * CD_FRAMES + (a)[3])
@@ -1920,6 +1927,66 @@ static NTSTATUS DVD_ReadStructure(int de
return STATUS_SUCCESS;
}
+
+/******************************************************************
+ * GetInquiryData
+ * Implements the IOCTL_GET_INQUIRY_DATA ioctl.
+ * Returns Inquiry data for all devices on the specified scsi bus
+ * Returns STATUS_BUFFER_TOO_SMALL if the output buffer is to small,
+ * STATUS_INVALID_DEVICE_REQUEST if the given handle isn't to a SCSI device,
+ * or STATUS_NOT_SUPPORTED if the OS driver is too old
+ */
+static NTSTATUS GetInquiryData(int fd, PSCSI_ADAPTER_BUS_INFO BufferOut, DWORD OutBufferSize)
+{
+ PSCSI_INQUIRY_DATA pInquiryData = NULL;
+ UCHAR sense_buffer[32];
+ int iochk, version;
+#ifdef HAVE_SG_IO_HDR_T_INTERFACE_ID
+ sg_io_hdr_t iocmd;
+ UCHAR inquiry[INQ_CMD_LEN] = {INQUIRY, 0, 0, 0, INQ_REPLY_LEN, 0};
+
+ /* Check we have a SCSI device and a supported driver */
+ if(ioctl(fd, SG_GET_VERSION_NUM, &version) != 0)
+ {
+ ERR("IOCTL_SCSI_GET_INQUIRY_DATA sg driver is not loaded\n");
+ return STATUS_INVALID_DEVICE_REQUEST;
+ }
+ if(version < 30000 )
+ return STATUS_NOT_SUPPORTED;
+
+ /* FIXME: Enumerate devices on the bus */
+ BufferOut->NumberOfBuses = 1;
+ BufferOut->BusData[0].NumberOfLogicalUnits = 1;
+ BufferOut->BusData[0].InquiryDataOffset = sizeof(SCSI_ADAPTER_BUS_INFO);
+
+ pInquiryData = (PSCSI_INQUIRY_DATA)(BufferOut + 1);
+
+ RtlZeroMemory(&iocmd, sizeof(iocmd));
+ iocmd.interface_id = 'S';
+ iocmd.cmd_len = sizeof(inquiry);
+ iocmd.mx_sb_len = sizeof(sense_buffer);
+ iocmd.dxfer_direction = SG_DXFER_FROM_DEV;
+ iocmd.dxfer_len = INQ_REPLY_LEN;
+ iocmd.dxferp = pInquiryData->InquiryData;
+ iocmd.cmdp = inquiry;
+ iocmd.sbp = sense_buffer;
+ iocmd.timeout = 1000;
+
+ iochk = ioctl(fd, SG_IO, &iocmd);
+ if(iochk != 0)
+ ERR("ioctl SG_IO returned %d, error (%s)\n", iochk, strerror(errno));
+
+ CDROM_GetInterfaceInfo(fd, &BufferOut->BusData[0].InitiatorBusId, &pInquiryData->PathId, &pInquiryData->TargetId, &pInquiryData->Lun);
+ pInquiryData->DeviceClaimed = TRUE;
+ pInquiryData->InquiryDataLength = INQ_REPLY_LEN;
+ pInquiryData->NextInquiryDataOffset = 0;
+ return STATUS_SUCCESS;
+#else
+ FIXME("not implemented for nonlinux\n");
+ return STATUS_NOT_SUPPORTED;
+#endif
+}
+
/******************************************************************
* CDROM_DeviceIoControl
*
@@ -2183,6 +2250,11 @@ NTSTATUS CDROM_DeviceIoControl(HANDLE hD
else if (nOutBufferSize < sz) status = STATUS_BUFFER_TOO_SMALL;
TRACE("doing DVD_READ_STRUCTURE\n");
status = DVD_ReadStructure(fd, (PDVD_READ_STRUCTURE)lpInBuffer, (PDVD_LAYER_DESCRIPTOR)lpOutBuffer);
+ break;
+
+ case IOCTL_SCSI_GET_INQUIRY_DATA:
+ sz = INQ_REPLY_LEN;
+ status = GetInquiryData(fd, (PSCSI_ADAPTER_BUS_INFO)lpOutBuffer, nOutBufferSize);
break;
default:
More information about the wine-patches
mailing list