Subject: port-i386/17618: CDIOCRESET ioctl on Toshiba CDROM@ahc0 hangs machine if no media
To: None <gnats-bugs@gnats.netbsd.org>
From: None <rafal@netbsd.org>
List: netbsd-bugs
Date: 07/17/2002 10:00:57
>Number: 17618
>Category: port-i386
>Synopsis: CDIOCRESET ioctl on Toshiba CDROM@ahc0 hangs machine if no media
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: port-i386-maintainer
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Wed Jul 17 07:01:01 PDT 2002
>Closed-Date:
>Last-Modified:
>Originator:
>Release: NetBSD 1.6D
>Organization:
procrastinators anonymous
>Environment:
System: NetBSD cyclops 1.6D NetBSD 1.6D (CYCLOPS.mp) #16: Tue Jul 9 22:05:56 EDT 2002 rafal@cyclops:/extra/src-current/sys/arch/i386/compile/CYCLOPS.mp i386
Architecture: i386
Machine: i386
>Description:
The GNOME CD player applet would hang my machine hard if I removed
the CD from the drive or started it when there was no CD in the
drive.
I've gotten the problem down to a simple test program that (probably)
could be trimmed even further... The culprit is the CDIOCRESET ioctl,
which in turns does a Bus Device Reset at the SCSI level. This logs
a message about sending the BDR and then hangs the box (keyboard
still responds if running on a wscons console, but I'm unable to
suspend/kill the process nor switch to a different virtual console.
If in X, the keyboard/mouse *don't* respond and I'm still unable
to get to a different virtual console).
The controller is the following:
ahc0 at pci0 dev 16 function 0
ahc0: interrupting at apic 2 int 16 (irq 11)
ahc0: aic7890/91 Wide Channel A, SCSI Id=7, 16/255 SCBs
The CDROM is:
cd0 at scsibus0 target 5 lun 0: <TOSHIBA, CD-ROM XM-6401TA, 1015> SCSI2 5/cdrom removable
cd0: sync (50.0ns offset 16), 8-bit (20.000MB/s) transfers
There's also a CD-R/RW on the bus, and I haven't tried with that
device yet:
cd1 at scsibus0 target 4 lun 0: <PLEXTOR, CD-R PX-W124TS, 1.07> SCSI2 5/cdrom removable
cd1: sync (50.0ns offset 8), 8-bit (20.000MB/s) transfers
FWIW, the SCSI chain only has those two devices and a SCSI ZIP drive;
the system disks are all IDE, so the BDR shouldn't be interfering with
normal system disk I/O.
>How-To-Repeat:
Given:
/dev/cdrom points to a device for a CDROM hanging off an
`ahc' controller, as below:
rwxr-xr-x 1 root wheel 10 Jul 10 22:42 /dev/cdrom@ -> /dev/rcd0d
There is no media in that CDROM drive.
Now:
Run the following short program (best done on a wscons
text console so results are more evident), and it should
hang the PC (after printing the "Bus Device Reset" message
from the ahc driver).
I believe it should be sufficient to just to the CDIOCRESET
ioctl, without the CDIOCREADSUBCHANNEL first, but have not
verified this.
(Note also that this is a SMP kernel, and has had the signal
trampoline changes from the trunk pulled up... I'm not sure
if either is relevant -- I'll see if I can reproduce this
with a "stock" uniprocessor kernel or an SMP kernel without
any hand-applied changes and append the results here later)
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/cdio.h>
main()
{
int fd;
struct ioc_read_subchannel subchnl;
int errcode;
if ((fd = open("/dev/cdrom", O_RDONLY)) < 0) {
perror("Open /dev/cdrom");
exit(1);
}
memset(&subchnl, 0, sizeof(struct ioc_read_subchannel));
subchnl.address_format = CD_MSF_FORMAT;
subchnl.data_format = CD_CURRENT_POSITION;
subchnl.data_len = sizeof(struct cd_sub_channel_info);
subchnl.data = malloc(sizeof(struct cd_sub_channel_info));
if (ioctl(fd, CDIOCREADSUBCHANNEL, &subchnl) == -1) {
free(subchnl.data);
perror("read CD subchannel");
printf("about to reset cdrom\n");
fflush(stdout);
sleep(3);
if (ioctl(fd, CDIOCRESET, 0) == -1) {
perror("CD reset");
} else {
printf("cdrom reset OK\n");
fflush(stdout);
}
}
printf("CD data read ok!\n");
free(subchnl.data);
exit(0);
}
>Fix:
Unknown.
>Release-Note:
>Audit-Trail:
>Unformatted:
kernel build from i386 smp branch with sigtramp changes
from trunk applied. Haven't yet tested with UP kernel.
Sources from ~ Jul 9th (late evening US/Eastern)