Date: Fri, 30 Aug 1996 18:00:33 -0700 (PDT) From: arver@sn.no, Arve.Ronning@alcatel.no To: gnats-admin@freebsd.org Subject: i386/1556: ATAPI CDROM probes ok, but will not 'mount_cd9660' Message-ID: <199608310100.SAA10793@freefall.freebsd.org> Resent-Message-ID: <199608310350.UAA17655@freefall.freebsd.org>
index | next in thread | raw e-mail
>Number: 1556
>Category: i386
>Synopsis: ATAPI CDROM probes ok, but will not 'mount_cd9660'
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: freebsd-bugs
>State: open
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Fri Aug 30 20:50:01 PDT 1996
>Last-Modified:
>Originator: Arve Ronning
>Organization:
>Release: 2.1.5-RELEASE [GENERIC] & 2.2-960801-SNAP
>Environment:
>Description:
Hitachi CDR-7730 (4x ATAPI CDROM drive) probes ok during boot, but
'mount_cd9660 /dev/wcd0c /mnt' responds
'mount_cd9660: /dev/wcd0c: Device not configured' because the drive
rejects the ATAPI_TEST_UNIT_READY command during open which returns ENXIO.
This is caused by a violation of ATA by atapi_wait_cmd() which does not
wait for the ARS_BSY status bit low when polling for ARS_DRQ high. (See
/sys/i386/isa/atapi.?).
If my (short term:) memory serves me right, I believe others have
reported this behaviour for at least one other ATAPI CDROM drive model.
(Can't remember who/which one).
>How-To-Repeat:
You will need a Hitachi CDR-7730 ATAPI CDROM drive and 2.1.5R or
960801-SNAP or -current. If this works like it does on my P100/Triton,
the probe will be ok (although it reports 'medium type unknown' even
with a 9660 disk in the drive) and the mount_cd9660 will fail.
>Fix:
Proposed patch for 2.1.5R :
(atapi.c Version 1.5, Thu Sep 21 23:08:11 MSD 1995)
*** atapi.c.ori Sat Sep 30 01:11:15 1995
--- atapi.c Wed Aug 28 21:23:01 1996
***************
*** 536,550 ****
int atapi_wait_cmd (struct atapi *ata, struct atapicmd *ac)
{
/* Wait for DRQ from 50 usec to 3 msec for slow devices */
! int cnt = ata->intrcmd ? 10000 : ata->slow ? 3000 : 50;
for (; cnt>0; cnt-=10) {
ac->result.status = inb (ata->port + AR_STATUS);
! if (ac->result.status & ARS_DRQ)
break;
DELAY (10);
}
! if (! (ac->result.status & ARS_DRQ)) {
printf ("atapi%d.%d: no cmd drq\n", ata->ctrlr, ac->unit);
ac->result.code = RES_NODRQ;
ac->result.error = inb (ata->port + AR_ERROR);
--- 536,554 ----
int atapi_wait_cmd (struct atapi *ata, struct atapicmd *ac)
{
/* Wait for DRQ from 50 usec to 3 msec for slow devices */
! /* Add another 2 msec for slooow devices (eg CDR-7730) */
! int cnt = ata->intrcmd ? 10000 : ata->slow ? 3000+2000 : 50;
for (; cnt>0; cnt-=10) {
ac->result.status = inb (ata->port + AR_STATUS);
! /*
! * According to ATA, ARS_DRQ is only valid when ARS_BSY is low
! */
! if ((ac->result.status & (ARS_BSY | ARS_DRQ)) == ARS_DRQ)
break;
DELAY (10);
}
! if ((ac->result.status & (ARS_BSY | ARS_DRQ)) != ARS_DRQ) {
printf ("atapi%d.%d: no cmd drq\n", ata->ctrlr, ac->unit);
ac->result.code = RES_NODRQ;
ac->result.error = inb (ata->port + AR_ERROR);
Proposed patch for 2.2-960801-SNAP / 2.2-current
( atapi.c Version 1.9, Mon Oct 9 22:34:47 MSK 1995 )
*** atapi.c.2.2 Sat Aug 24 19:06:00 1996
--- atapi.c Sat Aug 31 02:53:40 1996
***************
*** 577,591 ****
int atapi_wait_cmd (struct atapi *ata, struct atapicmd *ac)
{
/* Wait for DRQ from 50 usec to 3 msec for slow devices */
! int cnt = ata->intrcmd ? 10000 : ata->slow ? 3000 : 50;
int ireason = 0, phase = 0;
/* Wait for command phase. */
for (; cnt>0; cnt-=10) {
- ireason = inb (ata->port + AR_IREASON);
ac->result.status = inb (ata->port + AR_STATUS);
phase = (ireason & (ARI_CMD | ARI_IN)) |
! (ac->result.status & ARS_DRQ);
if (phase == PHASE_CMDOUT)
break;
DELAY (10);
--- 577,596 ----
int atapi_wait_cmd (struct atapi *ata, struct atapicmd *ac)
{
/* Wait for DRQ from 50 usec to 3 msec for slow devices */
! /* Allow another 2 msec for sloow devices (eg CDR-7730) */
! int cnt = ata->intrcmd ? 10000 : ata->slow ? 3000+2000 : 50;
int ireason = 0, phase = 0;
/* Wait for command phase. */
for (; cnt>0; cnt-=10) {
ac->result.status = inb (ata->port + AR_STATUS);
+ ireason = inb (ata->port + AR_IREASON);
+ /*
+ * According to ATA, AR_IREASON and ARS_DRQ are
+ * valid only when ARS_BSY is low.
+ */
phase = (ireason & (ARI_CMD | ARI_IN)) |
! (ac->result.status & (ARS_BSY | ARS_DRQ));
if (phase == PHASE_CMDOUT)
break;
DELAY (10);
>Audit-Trail:
>Unformatted:
home |
help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199608310100.SAA10793>
