Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 10 Oct 2001 20:47:34 +0100
From:      Ian Dowse <iedowse@maths.tcd.ie>
To:        freebsd-mobile@freebsd.org
Cc:        Shin Tai <tsefong@dcs.kcl.ac.uk>, sos@freebsd.org
Subject:   Re: Installing 4.4 on sony vaio c1ve from pcga-cd51 cdrom 
Message-ID:   <200110102047.aa14135@salmon.maths.tcd.ie>
In-Reply-To: Your message of "Mon, 08 Oct 2001 20:23:30 BST." <200110082023.aa44061@salmon.maths.tcd.ie> 

next in thread | previous in thread | raw e-mail | index | archive | help
In message <200110082023.aa44061@salmon.maths.tcd.ie>, Ian Dowse writes:
>Hmm - I just tried plugging a PCGA-CD51 cdrom drive into a C1XD
>vaio running 4.4ish sources, and it hung with an interrupt storm.
>I unplugged it, and got a page fault in the ATA code, and then I
>got a hard hang on reboot at the "starting local daemons:" line.
>
>I haven't used that cdrom drive in a while, but it definitely
>used to work! (I will debug further over the next few days).

Ok, I have looked into the ATA interrupt storm a bit further. The
laptop was hanging during ata_attach() while executing:

	if (scp->devices & ATA_ATAPI_SLAVE)
	    if (ata_getparam(scp, ATA_SLAVE, ATA_C_ATAPI_IDENTIFY))
		scp->devices &= ~ATA_ATAPI_SLAVE;

The request had been sent to the device, and ata_command() was
sitting in the await() call. The interrupt line was constantly
asserted, and ata_intr seemed to be unable to acknowledge it,
so it just kept re-interrupting.

When I tried clearing the interrupt manually via inb(0x187) calls
in ddb, it made no difference, but then I found that if I selected
the master device first with "call outb (0x186, 0xa0)", then "call
inb(0x187)" would clear the interrupt.

I'm not sure why this worked before, but it seems that with these
pccard cdrom drives you get unexpected results if you attempt
to talk to the non-existent slave device. The ata_pccard_probe()
routine seems to deal with this by arranging for the slave to
be ignored

	scp->flags |= (ATA_USE_16BIT | ATA_NO_SLAVE);

but this does not stop the ATAPI probe from happening. The drive
works fine when I apply the following patch. The important bit is
the "*mask" changes, but the patch also includes some extra spl
calls that may be necessary (I don't think ata_attach() has any
protetion from interrupts in the pccard case, and even if it does,
the protection won't necessarily cover a newly-set up interrupt).

Has anybody else tried a Sony PCGA-CD51 cdrom drive with a recent
-stable?

Ian

ata3 at port 0x180-0x187,0x386 iomem 0xd4000-0xd4fff irq 9 slot 0 on pccard0
acd0: CDROM <TOSHIBA CD-ROM XM-7002Bc> at ata3-master using BIOSPIO

Index: ata-all.c
===================================================================
RCS file: /home/iedowse/CVS/src/sys/dev/ata/ata-all.c,v
retrieving revision 1.50.2.20
diff -u -r1.50.2.20 ata-all.c
--- ata-all.c	2001/08/28 17:56:14	1.50.2.20
+++ ata-all.c	2001/10/10 18:48:15
@@ -885,7 +885,7 @@
 ata_attach(device_t dev)
 {
     struct ata_softc *scp = device_get_softc(dev);
-    int error, rid = 0;
+    int error, rid = 0, s;
 
     if (!scp || scp->flags & ATA_ATTACHED)
 	return ENXIO;
@@ -906,6 +906,7 @@
      * otherwise attach what the probe has found in scp->devices.
      */
     if (!ata_delayed_attach) {
+	s = splbio();
 	if (scp->devices & ATA_ATA_SLAVE)
 	    if (ata_getparam(scp, ATA_SLAVE, ATA_C_ATA_IDENTIFY))
 		scp->devices &= ~ATA_ATA_SLAVE;
@@ -930,6 +931,7 @@
 	if (scp->devices & ATA_ATAPI_SLAVE)
 	    atapi_attach(scp, ATA_SLAVE);
 #endif
+	splx(s);
     }
     scp->flags |= ATA_ATTACHED;
     return 0;
@@ -1285,7 +1287,7 @@
 
     /* wait for BUSY to go inactive */
     for (timeout = 0; timeout < 310000; timeout++) {
-	if (status0 & ATA_S_BUSY) {
+	if (*mask & 0x01 && status0 & ATA_S_BUSY) {
             outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | ATA_MASTER);
             DELAY(10);
             status0 = inb(scp->ioaddr + ATA_STATUS);
@@ -1300,7 +1302,7 @@
                     scp->devices |= ATA_ATAPI_MASTER;
             }
         }
-        if (status1 & ATA_S_BUSY) {
+        if (*mask & 0x02 && status1 & ATA_S_BUSY) {
             outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | ATA_SLAVE);
             DELAY(10);
             status1 = inb(scp->ioaddr + ATA_STATUS);

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-mobile" in the body of the message




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