Skip site navigation (1)Skip section navigation (2)
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>

next in thread | raw e-mail | index | archive | help

>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:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199608310100.SAA10793>