22 Jul, 2011

1 commit

  • Some broken devices indicates that media has changed on every
    GET_EVENT_STATUS_NOTIFICATION. This translates into MEDIA_CHANGE
    uevent on every open() which lets udev run into a loop.

    Verify GET_EVENT result against TUR and if it generates spurious
    events for several times in a row, ignore the GET_EVENT events, and
    trust only the TUR status.

    This is the log of a USB stick with a (broken) fake CDROM drive:

    scsi 5:0:0:0: Direct-Access SanDisk U3 Cruzer Micro 8.02 PQ: 0 ANSI: 0 CCS
    sd 5:0:0:0: Attached scsi generic sg3 type 0
    scsi 5:0:0:1: CD-ROM SanDisk U3 Cruzer Micro 8.02 PQ: 0 ANSI: 0
    sd 5:0:0:0: [sdb] Attached SCSI removable disk
    sr2: scsi3-mmc drive: 48x/48x tray
    sr 5:0:0:1: Attached scsi CD-ROM sr2
    sr 5:0:0:1: Attached scsi generic sg4 type 5
    sr2: GET_EVENT and TUR disagree continuously, suppress GET_EVENT events
    sd 5:0:0:0: [sdb] 31777279 512-byte logical blocks: (16.2 GB/15.1 GiB)
    sd 5:0:0:0: [sdb] No Caching mode page present
    sd 5:0:0:0: [sdb] Assuming drive cache: write through
    sd 5:0:0:0: [sdb] No Caching mode page present
    sd 5:0:0:0: [sdb] Assuming drive cache: write through
    sdb: sdb1

    -tj: Updated to consider only spurious GET_EVENT events among
    different types of disagreement and allow using TUR for kernel
    event polling after GET_EVENT is ignored.

    Reported-By: Markus Rathgeb maggu2810@googlemail.com
    Signed-off-by: Kay Sievers
    Signed-off-by: Tejun Heo
    Cc: stable@kernel.org # >= v2.6.38, fixes udev busy looping w/ certain devices
    Signed-off-by: James Bottomley

    Kay Sievers
     

17 Dec, 2010

2 commits

  • Replace sr_media_change() with sr_check_events(). It normally only
    uses GET_EVENT_STATUS_NOTIFICATION to check both media change and
    eject request. If @clearing includes DISK_EVENT_MEDIA_CHANGE, it
    issues TUR and compares whether media presence has changed. The SCSI
    specific media change uevent is kept for compatibility.

    sr_media_change() was doing both media change check and revalidation.
    The revalidation part is split into sr_block_revalidate_disk().

    Signed-off-by: Tejun Heo
    Cc: Kay Sievers
    Signed-off-by: Jens Axboe

    Tejun Heo
     
  • The usage of TUR has been confusing involving several different
    commits updating different parts over time. Currently, the only
    differences between scsi_test_unit_ready() and sr_test_unit_ready()
    are,

    * scsi_test_unit_ready() also sets sdev->changed on NOT_READY.

    * scsi_test_unit_ready() returns 0 if TUR ended with UNIT_ATTENTION or
    NOT_READY.

    Due to the above two differences, sr is using its own
    sr_test_unit_ready(), but sd - the sole user of the above extra
    handling - doesn't even need them.

    Where scsi_test_unit_ready() is used in sd_media_changed(), the code
    is looking for device ready w/ media present state which is true iff
    TUR succeeds w/o sense data or UA, and when the device is not ready
    for whatever reason sd_media_changed() explicitly marks media as
    missing so there's no reason to set sdev->changed automatically from
    scsi_test_unit_ready() on NOT_READY.

    Drop both special handlings from scsi_test_unit_ready(), which makes
    it equivalant to sr_test_unit_ready(), and replace
    sr_test_unit_ready() with scsi_test_unit_ready(). Also, drop the
    unnecessary explicit NOT_READY check from sd_media_changed().
    Checking return value is enough for testing device readiness.

    Signed-off-by: Tejun Heo
    Signed-off-by: Jens Axboe

    Tejun Heo
     

08 Feb, 2008

1 commit

  • Commit 210ba1d1724f5c4ed87a2ab1a21ca861a915f734 updated sr.c to use
    the scsi_test_unit_ready() function. Unfortunately, this has the
    wrong characteristic of eating NOT_READY returns which sr.c relies on
    for tray status.

    Fix by rolling an internal sr_test_unit_ready() that doesn't do this.

    Tested-by: Daniel Drake
    Signed-off-by: James Bottomley

    James Bottomley
     

12 Jan, 2008

2 commits

  • Based on an original patch from: David Martin

    When trying to get the drive status via ioctl CDROM_DRIVE_STATUS, with
    no disk it gives CDS_TRAY_OPEN even if the tray is closed.

    ioctl works as expected with ide-cd driver.

    Gentoo bug report: http://bugs.gentoo.org/show_bug.cgi?id=196879

    Cc: Maarten Bressers
    Signed-off-by: James Bottomley

    James Bottomley
     
  • This will send for a card reader slot (remove/add media):
    UEVENT[1187091572.155884] change /devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/host7/target7:0:0/7:0:0:0 (scsi)
    UEVENT[1187091572.162314] remove /block/sdb/sdb1 (block)
    UEVENT[1187091572.172464] add /block/sdb/sdb1 (block)
    UEVENT[1187091572.175408] change /devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/host7/target7:0:0/7:0:0:0 (scsi)

    and for a DVD drive (add/eject media):
    UEVENT[1187091590.189159] change /devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0 (scsi)
    UEVENT[1187091590.957124] add /module/isofs (module)
    UEVENT[1187091604.468207] change /devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0 (scsi)

    Userspace gets events, even for unpartitioned media. This unifies
    the event handling for asynchronoous events (AN) and events caused by
    perodical polling the device from userspace.

    Signed-off-by: Kay Sievers

    [jejb: modified for new event API]

    Signed-off-by: James Bottomley

    Kay Sievers
     

23 Mar, 2006

1 commit

  • Since early 2.4.x all cdrom drivers implement the block_device methods
    themselves, so they can handle additional ioctls directly instead of going
    through the cdrom layer.

    Signed-off-by: Christoph Hellwig
    Acked-by: Jens Axboe
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Christoph Hellwig
     

29 Aug, 2005

1 commit

  • Here's the problem. Try to do this on 2.6.12:
    - Kill udev and HAL
    - Insert a CD-ROM into a SCSI or USB CD-ROM drive
    - Run dd if=/dev/scd0
    - cat /sys/block/sr0/size
    - Eject the CD, insert a different one
    - Run dd if=/dev/scd0
    This is likely to do "access beyond the end of device", if you let it
    - cat /sys/block/sr0/size
    This shows the size of a previous CD, even though dd was supposed
    to revalidate the device.
    - Run dd if=/dev/scd0
    The second run of dd works correctly!

    The bug was introduced in 2.5.31, when Al fixes the recursive opens
    in partitioning. Before, the code worked like this:
    - Block layer called cdrom_open directly
    - cdrom_open called sr_open
    - sr_open called check_disk_change
    - check_disk_change called sr_media_change
    - sr_media_change did cd->needs_disk_change=1
    - before returning sr_open tested cd->needs_disk_change
    and called get_sector_size.

    In 2.6.12, the check_disk_change is called from cdrom_open only. Thus:
    - Block layer calls sr_bd_open
    - sr_bd_open calls cdrom_open
    - cdrom_open calls sr_open
    - sr_open tests cd->needs_disk_change, which wasn't set yet; returns
    - cdrom_open calls check_disk_change
    - check_disk_change calls sr_media_change
    - sr_media_change does cd->needs_disk_change=1, but nobody cares

    Acked by: Alexander Viro
    Signed-off-by: James Bottomley

    Pete Zaitcev
     

17 Apr, 2005

1 commit

  • Initial git repository build. I'm not bothering with the full history,
    even though we have it. We can create a separate "historical" git
    archive of that later if we want to, and in the meantime it's about
    3.2GB when imported into git - space that would just make the early
    git days unnecessarily complicated, when we don't have a lot of good
    infrastructure for it.

    Let it rip!

    Linus Torvalds