return 0;
 
        events = sr_get_events(cd->device);
+       cd->get_event_changed |= events & DISK_EVENT_MEDIA_CHANGE;
+
+       /*
+        * If earlier GET_EVENT_STATUS_NOTIFICATION and TUR did not agree
+        * for several times in a row.  We rely on TUR only for this likely
+        * broken device, to prevent generating incorrect media changed
+        * events for every open().
+        */
+       if (cd->ignore_get_event) {
+               events &= ~DISK_EVENT_MEDIA_CHANGE;
+               goto do_tur;
+       }
+
        /*
         * GET_EVENT_STATUS_NOTIFICATION is enough unless MEDIA_CHANGE
         * is being cleared.  Note that there are devices which hang
         * if asked to execute TUR repeatedly.
         */
-       if (!(clearing & DISK_EVENT_MEDIA_CHANGE))
-               goto skip_tur;
+       if (cd->device->changed) {
+               events |= DISK_EVENT_MEDIA_CHANGE;
+               cd->device->changed = 0;
+               cd->tur_changed = true;
+       }
 
+       if (!(clearing & DISK_EVENT_MEDIA_CHANGE))
+               return events;
+do_tur:
        /* let's see whether the media is there with TUR */
        last_present = cd->media_present;
        ret = scsi_test_unit_ready(cd->device, SR_TIMEOUT, MAX_RETRIES, &sshdr);
                (scsi_sense_valid(&sshdr) && sshdr.asc != 0x3a);
 
        if (last_present != cd->media_present)
-               events |= DISK_EVENT_MEDIA_CHANGE;
-skip_tur:
+               cd->device->changed = 1;
+
        if (cd->device->changed) {
                events |= DISK_EVENT_MEDIA_CHANGE;
                cd->device->changed = 0;
+               cd->tur_changed = true;
+       }
+
+       if (cd->ignore_get_event)
+               return events;
+
+       /* check whether GET_EVENT is reporting spurious MEDIA_CHANGE */
+       if (!cd->tur_changed) {
+               if (cd->get_event_changed) {
+                       if (cd->tur_mismatch++ > 8) {
+                               sdev_printk(KERN_WARNING, cd->device,
+                                           "GET_EVENT and TUR disagree continuously, suppress GET_EVENT events\n");
+                               cd->ignore_get_event = true;
+                       }
+               } else {
+                       cd->tur_mismatch = 0;
+               }
        }
+       cd->tur_changed = false;
+       cd->get_event_changed = false;
 
        return events;
 }
 
        unsigned readcd_known:1;        /* drive supports READ_CD (0xbe) */
        unsigned readcd_cdda:1; /* reading audio data using READ_CD */
        unsigned media_present:1;       /* media is present */
+
+       /* GET_EVENT spurious event handling, blk layer guarantees exclusion */
+       int tur_mismatch;               /* nr of get_event TUR mismatches */
+       bool tur_changed:1;             /* changed according to TUR */
+       bool get_event_changed:1;       /* changed according to GET_EVENT */
+       bool ignore_get_event:1;        /* GET_EVENT is unreliable, use TUR */
+
        struct cdrom_device_info cdi;
        /* We hold gendisk and scsi_device references on probe and use
         * the refs on this kref to decide when to release them */