--- mythtv/libs/libmyth/mythcdrom-linux.cpp.orig	2007-10-04 22:48:51.000000000 -0400
+++ mythtv/libs/libmyth/mythcdrom-linux.cpp	2007-10-27 15:38:17.000000000 -0400
@@ -31,6 +31,7 @@ public:
     virtual bool isSameDevice(const QString &path);
     virtual MediaError lock(void);
     virtual MediaError unlock(void);
+    virtual int driveStatus(void);
 };
 
 MythCDROM *GetMythCDROMLinux(QObject* par, const char* devicePath,
@@ -39,6 +40,105 @@ MythCDROM *GetMythCDROMLinux(QObject* pa
     return new MythCDROMLinux(par, devicePath, SuperMount, AllowEject);
 }
 
+struct event_header {
+        unsigned char data_len[2];
+#ifdef WORDS_BIGENDIAN
+        unsigned char nea                : 1;
+        unsigned char reserved1          : 4;
+        unsigned char notification_class : 3;
+#else
+        unsigned char notification_class : 3;
+        unsigned char reserved1          : 4;
+        unsigned char nea                : 1;
+#endif
+        unsigned char supp_event_class;
+};
+ 
+struct media_event_desc {
+#ifdef WORDS_BIGENDIAN
+        unsigned char reserved1          : 4;
+        unsigned char media_event_code   : 4;
+        unsigned char reserved2          : 6;
+        unsigned char media_present      : 1;
+        unsigned char door_open          : 1;
+#else
+        unsigned char media_event_code   : 4;
+        unsigned char reserved1          : 4;
+        unsigned char door_open          : 1;
+        unsigned char media_present      : 1;
+        unsigned char reserved2          : 6;
+#endif
+        unsigned char start_slot;
+        unsigned char end_slot;
+};
+
+
+// Routine to determine drive status
+// If the CDROM is managed by the SCSI driver, then CDROM_DRIVE_STATUS
+// as reported by ioctl will always return CDS_TRAY_OPEN if the tray is 
+// closed with no media.  To determine the actual drive status we need
+// to ask the drive directly by sending a packet to the drive.
+// Note that in recent kernels, whether you have a IDE/ATA/SATA or SCSI
+// CDROM, the drive is managed by the SCSI driver and therefore needs
+// this work around.  This code is based on the routine cdrom_get_media_event
+// in cdrom.c of the linux kernel
+
+int MythCDROMLinux::driveStatus()
+{
+    int drive_status, stat;
+    struct cdrom_generic_command cgc;
+    unsigned char buffer[8];
+    struct event_header *eh = (struct event_header *)buffer;
+    struct media_event_desc *med = (struct media_event_desc *)&buffer[sizeof(struct event_header)];
+    QString device_path = getDevicePath();    
+  
+    drive_status = ioctl(m_DeviceHandle, CDROM_DRIVE_STATUS, CDSL_CURRENT);
+    
+    if ((drive_status != CDS_TRAY_OPEN) || (!device_path.contains("/dev/scd")))
+      return drive_status;
+
+    // VERBOSE(VB_MEDIA, "MythCDROMLinux::driveStatus detected SCSI managed CDROM");
+   
+    // If the CDROM is managed by the SCSI driver and is reporting tray open
+    // Lets double check with the drive itself.
+    
+    memset(&cgc, 0, sizeof(struct cdrom_generic_command));
+    memset(&buffer, 0, 8);
+    
+    cgc.cmd[0] = GPCMD_GET_EVENT_STATUS_NOTIFICATION;
+    cgc.cmd[1] = 1;
+    cgc.cmd[4] = 1 << 4;
+    cgc.cmd[8] = sizeof(buffer);
+    cgc.quiet  = 1;
+    cgc.buffer = buffer;
+    cgc.buflen = sizeof(buffer);
+    cgc.data_direction = CGC_DATA_READ;
+    
+    stat = ioctl(m_DeviceHandle, CDROM_SEND_PACKET, &cgc);
+    
+    if ((stat < 0) || eh->nea || (eh->notification_class != 0x4))
+    {
+      VERBOSE(VB_MEDIA, "MythCDROMLinux::driveStatus - failed to send CDROM packet");
+      return drive_status;
+    }
+           
+    if (med->media_present)
+    {
+//      VERBOSE(VB_MEDIA, "MythCDROMLinux::driveStatus disc ok");
+      return CDS_DISC_OK;
+    }
+    else if (med->door_open)
+    {
+//      VERBOSE(VB_MEDIA, "MythCDROMLinux::driveStatus tray open");
+      return CDS_TRAY_OPEN;
+    }
+    else 
+    {
+//      VERBOSE(VB_MEDIA, "MythCDROMLinux::driveStatus no disc");
+      return CDS_NO_DISC;
+    }
+}
+
 MediaError MythCDROMLinux::eject(bool open_close)
 {
     if (!isDeviceOpen())
@@ -54,7 +154,7 @@ MediaError MythCDROMLinux::eject(bool op
 
         // This allows us to catch any drives that the OS has problems
         // detecting the status of (some always report OPEN when empty)
-        if (ioctl(m_DeviceHandle, CDROM_DRIVE_STATUS) == CDS_TRAY_OPEN)
+        if (driveStatus() == CDS_TRAY_OPEN)
             return MEDIAERR_FAILED;
         else
             return MEDIAERR_OK;
@@ -94,7 +194,7 @@ MediaError MythCDROMLinux::testMedia()
     }
 
     // Since the device was is/was open we can get it's status...
-    int Stat = ioctl(m_DeviceHandle, CDROM_DRIVE_STATUS, CDSL_CURRENT);
+    int Stat = driveStatus();
     
     // Be nice and close the device if we opened it, otherwise it might be locked when the user doesn't want it to be.
     if (OpenedHere)
@@ -128,7 +228,7 @@ MediaStatus MythCDROMLinux::checkMedia()
     if (isDeviceOpen()) 
     {
         //VERBOSE(VB_MEDIA, "MythCDROMLinux::checkMedia - Device is open...");
-        int ret = ioctl(m_DeviceHandle, CDROM_DRIVE_STATUS, CDSL_CURRENT);
+        int ret = driveStatus();
         switch (ret) 
         {
             case CDS_DISC_OK:
