![]() |
Detect CD tray status
Superfluous project of the day:
I'm looking for a way to detect a CD drive tray status. Background: I have a vintage system with a nice CD writer but the drive does not support the eject -T command. I can only use eject or eject -t. On all of my other systems I have a handy desktop shortcut with the eject -T command. :) I can't use that shortcut with this drive --- I need two shortcuts. :( I prefer to detect the tray status with the stock Slackware tools. I've seen some possible solutions but they require lshw or hwinfo. The /usr/include/linux/cdrom.h has a CDROM_DRIVE_STATUS option, but I'm not a C coder. All I seek is something like this: Code:
if [ $TRAY_IS_OPEN ];Code:
if [ "`/usr/sbin/lshw -quiet 2>/dev/null | awk '/\*-cd/,/con/' | sed -e 's/^[ \t]*//' | grep configuration | cut -d ' ' -f3`" = "status=open" ]; thenThanks. |
Here's a simple C program:
Code:
#include <sys/ioctl.h>./trayopen /dev/sr0 && echo tray is open || echo tray is closed |
Pat, that is very kind of you. Thank you! :)
I'm not a C coder but I can read uncomplicated C code and write a basic printf command. Because I tend to forget things as I age, here is version 0.2 with some reminders for me how to use. I added two includes to fix the compile warnings (I had to search the web to learn how to do that :)). Code:
#include <stdio.h> |
Quote:
Long shot, but it's worth a try. |
LOL. Out of curiosity I just looked at the code that does the toggle in eject, and it basically does this:
:doh: Anyway, try this patch. It replaces the eject_for_mac.patch file in the slackbuild. (Needs to be applied with -p1 not -p4). Works on my box, but no idea how it will behave on other people's machines |
Quote:
Quote:
Quote:
|
My report:
I tested on 4 systems here. On two modern systems, eject -T works with the stock Slackware eject and the newly patched eject. On a PI system with a Creative Labs (MATSHITA CR-585 ZU17) 24x CD-ROM, the stock eject -T works to open and close the drive, but the new patched version does not. With the new patch eject -T opens the tray but will not close. Further, the C code Pat provided does not correctly reflect the tray status on this machine. That is, the trayopen command reports the tray is closed when the tray is open. On a PII system, the original problem system that started this thread, the stock Slackware eject -T does not close the tray. The newly patched version works both to open and close. That system has a HP CD-Writer+ 9300 1.0c 10x/4x/32x CD Recorder. So with the stock eject the PI system works correctly with eject -T but not with the PII system. The newly patched eject works with the PII system but not the PI. Seems some combination of the new patch and the "mac" patch are needed. :) |
Pat's code above doesn't check for errors from the ioctl so if you get a 1 you don't know whether it's because the call failed or the drive is closed. If you run strace eject -T /dev/sr0 you'll see the results of the ioctls at the end of the output. You can also use strace on pats trayopen command.
What kernels are your older boxes using? The patch I provided includes the change that the mac patch was making previously, so I don't think that matters. Perhaps the answer is to include the time based operation as a fallback if CDROM_DRIVE_STATUS doesn't work. Maybe that would sort out your P1 machine. If you could show me the last bit of the strace on the one that doesn't work I'll see what I can do. |
Ok, I took a guess that the MATSHITA drive was returning CDS_NO_INFO for the CDROM_DRIVE_STATUS query.
Here's an updated patch if you want to try it. |
Quote:
Quote:
That said, attached are the last few lines from 8 straces. ====================================================== PI, stock Slackware (eject -T works to open and close) ====================================================== Tray is closed, attempt to open: ================================ stat64("/dev/sr0", {st_mode=S_IFBLK|0660, st_rdev=makedev(11, 0), ...}) = 0 open("/dev/sr0", O_RDONLY|O_NONBLOCK) = 3 gettimeofday({1361231138, 960547}, NULL) = 0 ioctl(3, CDROMEJECT, 0) = 0 gettimeofday({1361231140, 894047}, NULL) = 0 exit_group(0) = ? Tray is open, attempt to close: =============================== stat64("/dev/sr0", {st_mode=S_IFBLK|0660, st_rdev=makedev(11, 0), ...}) = 0 open("/dev/sr0", O_RDONLY|O_NONBLOCK) = 3 gettimeofday({1361231159, 60890}, NULL) = 0 ioctl(3, CDROMEJECT, 0) = 0 gettimeofday({1361231159, 194454}, NULL) = 0 ioctl(3, CDROMCLOSETRAY, 0) = 0 exit_group(0) = ? ===================================================== PI, newly patched (eject -T opens but fails to close) ===================================================== Tray is closed, attempt to open: ================================ stat64("/dev/sr0", {st_mode=S_IFBLK|0660, st_rdev=makedev(11, 0), ...}) = 0 open("/dev/sr0", O_RDONLY|O_NONBLOCK) = 3 ioctl(3, CDROM_DRIVE_STATUS, 0x804b82c) = 1 ioctl(3, CDROMEJECT, 0) = 0 exit_group(0) = ? Tray is open, attempt to close FAILS: ===================================== stat64("/dev/sr0", {st_mode=S_IFBLK|0660, st_rdev=makedev(11, 0), ...}) = 0 open("/dev/sr0", O_RDONLY|O_NONBLOCK) = 3 ioctl(3, CDROM_DRIVE_STATUS, 0x804b82c) = 1 ioctl(3, CDROMEJECT, 0) = 0 exit_group(0) = ? ======================================================== PII, stock Slackware (eject -T opens but fails to close) ======================================================== Tray is closed, attempt to open: ================================ stat64("/dev/sr0", {st_mode=S_IFBLK|0660, st_rdev=makedev(11, 0), ...}) = 0 open("/dev/sr0", O_RDONLY|O_NONBLOCK) = 3 gettimeofday({1361231700, 129791}, NULL) = 0 ioctl(3, CDROMEJECT, 0) = 0 gettimeofday({1361231702, 429991}, NULL) = 0 exit_group(0) = ? Tray is open, attempt to close FAILS: ===================================== stat64("/dev/sr0", {st_mode=S_IFBLK|0660, st_rdev=makedev(11, 0), ...}) = 0 open("/dev/sr0", O_RDONLY|O_NONBLOCK) = 3 gettimeofday({1361231750, 488658}, NULL) = 0 ioctl(3, CDROMEJECT, 0) = 0 gettimeofday({1361231751, 180760}, NULL) = 0 exit_group(0) = ? ===================================================== PII, newly patched (eject -T works to open and close) ===================================================== Tray is closed, attempt to open: ================================ stat64("/dev/sr0", {st_mode=S_IFBLK|0660, st_rdev=makedev(11, 0), ...}) = 0 open("/dev/sr0", O_RDONLY|O_NONBLOCK) = 3 ioctl(3, CDROM_DRIVE_STATUS, 0x804b82c) = 1 ioctl(3, CDROMEJECT, 0) = 0 exit_group(0) = ? Tray is open, attempt to close: =============================== stat64("/dev/sr0", {st_mode=S_IFBLK|0660, st_rdev=makedev(11, 0), ...}) = 0 open("/dev/sr0", O_RDONLY|O_NONBLOCK) = 3 ioctl(3, CDROM_DRIVE_STATUS, 0x804b82c) = 2 ioctl(3, CDROMCLOSETRAY, 0x804b82c) = 0 exit_group(0) = ? |
Quote:
I'll test right away. |
Same results. The PI works with the stock eject -T but with the new second patch only opens. The PII opens with the stock eject but will not close. With the new second patch the tray opens and closes.
==================================================== PI, second patch (eject -T opens but fails to close) ==================================================== Tray is closed, attempt to open: ================================ stat64("/dev/sr0", {st_mode=S_IFBLK|0660, st_rdev=makedev(11, 0), ...}) = 0 open("/dev/sr0", O_RDONLY|O_NONBLOCK) = 3 ioctl(3, CDROM_DRIVE_STATUS, 0) = 1 ioctl(3, CDROMEJECT, 0) = 0 exit_group(0) = ? Tray is open, attempt to close FAILS: ===================================== stat64("/dev/sr0", {st_mode=S_IFBLK|0660, st_rdev=makedev(11, 0), ...}) = 0 open("/dev/sr0", O_RDONLY|O_NONBLOCK) = 3 ioctl(3, CDROM_DRIVE_STATUS, 0) = 1 ioctl(3, CDROMEJECT, 0) = 0 exit_group(0) = ? |
Code:
=====================================================Your MATSHITSA drive is returning CDS_NO_DISC to CDROM_DRIVE_STATUS whether the drive is open or closed. Damn! Off-hand, I don't see any way around that. :( |
The problem with your PII and the stock eject seems to be that its responding too slowly to the first CDROMEJECT of an already open drive to meet the conditions
in the TRAY_WAS_ALREADY_OPEN_USECS check and thus never trying to close it. You could try increasing that time limit, but the danger is that if you set it too high it may trigger a close instead of an open for some drives when you're trying to open them. I've attached a v3 of the patch, Basically it'll check for CDS_TRAY_OPEN first, and then fall back to the old mechanism for everything else. Anyway, here it is for what it is worth. I don't think I'd suggest it for inclusion in stock slackware though. It might sort your specific problems out, but IMO it's only half a solution and version 2 or even the version 1 of my patch are more correct (but unfortunately won't work with your aptly named MATSHITA drive which doesn't provide accurate status. |
Quote:
Quote:
|
| All times are GMT -5. The time now is 09:36 PM. |