CDROM_GetInterfaceInfo for SCSI drives
Pavel Roskin
proski at gnu.org
Sat Sep 27 16:51:18 CDT 2003
Hello!
This patch implements CDROM_GetInterfaceInfo() for SCSI drives and makes
some other fixes in that function.
scsi/scsi_ioctl.h is checked in configure.ac and included if found.
CDROM_GetInterfaceInfo() doesn't promise to return port 0 or 1 anymore.
It's supposed to be host (controller) number, and there may be more than
one SCSI host. We reserve 0 for IDE, but the rest is for SCSI.
Device number for IDE CD-ROMs wasn't calculated properly. Secondary IDE
devices have minor number 64, not 63. The new code allows for devices 2
and 3 just in case they are supported.
The SCSI device ID is requested by calling SCSI_IOCTL_GET_IDLUN. Host
number is increased by 1 to reserve 0 for IDE.
Linux 2.6 supports SCSI_IOCTL_GET_IDLUN on IDE CD-ROMs. The code tries to
identify the device as IDE CD-ROM first.
If the device is not recognized as IDE or SCSI, 0 is returned, not 1 as
before.
ChangeLog:
configure.ac:
Check for scsi/scsi_ioctl.h
dlls/ntdll/cdrom.c:
Add support for SCSI CD-ROMs to CDROM_GetInterfaceInfo().
Fix device number for IDE CD-ROMs. Return 0 for unsupported
drives.
--
Regards,
Pavel Roskin
-------------- next part --------------
--- configure.ac
+++ configure.ac
@@ -1021,6 +1021,7 @@
regex.h \
sched.h \
scsi/sg.h \
+ scsi/scsi_ioctl.h \
socket.h \
stdint.h \
strings.h \
--- dlls/ntdll/cdrom.c
+++ dlls/ntdll/cdrom.c
@@ -43,6 +43,9 @@
#ifdef HAVE_SCSI_SG_H
# include <scsi/sg.h>
#endif
+#ifdef HAVE_SCSI_SCSI_IOCTL_H
+# include <scsi/scsi_ioctl.h>
+#endif
#ifdef HAVE_LINUX_MAJOR_H
# include <linux/major.h>
#endif
@@ -351,8 +354,8 @@ static void CDROM_ClearCacheEntry(int de
*
* Determines the ide interface (the number after the ide), and the
* number of the device on that interface for ide cdroms (*port == 0).
- * Determines the scsi information for scsi cdroms (*port == 1).
- * Returns false if the info could not be get
+ * Determines the scsi information for scsi cdroms (*port >= 1).
+ * Returns false if the info cannot not be obtained.
*
* NOTE: this function is used in CDROM_InitRegistry and CDROM_GetAddress
*/
@@ -361,17 +364,13 @@ static int CDROM_GetInterfaceInfo(int fd
#if defined(linux)
{
struct stat st;
-#ifdef SG_EMULATED_HOST
- if (ioctl(fd, SG_EMULATED_HOST) != -1) {
- FIXME("not implemented for true scsi drives\n");
- return 0;
- }
-#endif
if ( fstat(fd, &st) == -1 || ! S_ISBLK(st.st_mode)) {
FIXME("cdrom not a block device!!!\n");
return 0;
}
*port = 0;
+ *iface = 0;
+ *device = 0;
*lun = 0;
switch (major(st.st_rdev)) {
case IDE0_MAJOR: *iface = 0; break;
@@ -382,12 +381,30 @@ static int CDROM_GetInterfaceInfo(int fd
case IDE5_MAJOR: *iface = 5; break;
case IDE6_MAJOR: *iface = 6; break;
case IDE7_MAJOR: *iface = 7; break;
- case SCSI_CDROM_MAJOR: *iface = 11; break;
- default:
- FIXME("CD-ROM device with major ID %d not supported\n", major(st.st_rdev));
- break;
+ default: *port = 1; break;
+ }
+
+ if (*port == 0)
+ *device = (minor(st.st_rdev) >> 6);
+ else
+ {
+#ifdef SCSI_IOCTL_GET_IDLUN
+ UINT32 idlun[2];
+ if (ioctl(fd, SCSI_IOCTL_GET_IDLUN, &idlun) != -1)
+ {
+ *port = ((idlun[0] >> 24) & 0xff) + 1;
+ *iface = (idlun[0] >> 16) & 0xff;
+ *device = idlun[0] & 0xff;
+ *lun = (idlun[0] >> 8) & 0xff;
+ }
+ else
+#endif
+ {
+ FIXME("CD-ROM device (%d, %d) not supported\n",
+ major(st.st_rdev), minor(st.st_rdev));
+ return 0;
+ }
}
- *device = (minor(st.st_rdev) == 63 ? 1 : 0);
return 1;
}
#elif defined(__NetBSD__)
More information about the wine-patches
mailing list