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
--- 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__)