Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 09 Feb 2006 15:37:07 +0100
From:      =?ISO-8859-1?Q?S=F8ren_Schmidt?= <sos@deepcore.dk>
To:        Wilko Bulte <wb@freebie.xs4all.nl>
Cc:        stable@freebsd.org
Subject:   Re: Showstopper ATA bug in 6.1-PRE?
Message-ID:  <43EB5393.5090502@deepcore.dk>
In-Reply-To: <20060208221056.GA1299@freebie.xs4all.nl>
References:  <20060208194603.GA689@freebie.xs4all.nl> <43EA5C50.5020804@deepcore.dk> <20060208213704.GA703@freebie.xs4all.nl> <43EA6625.2070106@deepcore.dk> <20060208221056.GA1299@freebie.xs4all.nl>

next in thread | previous in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format.
--------------000801080306030609050702
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 8bit

Wilko Bulte wrote:
> On Wed, Feb 08, 2006 at 10:44:05PM +0100, Sren Schmidt wrote..
>> Wilko Bulte wrote:
>>> On Wed, Feb 08, 2006 at 10:02:08PM +0100, Sren Schmidt wrote..
>>>> Wilko Bulte wrote:
>>>>> Hi Soren,
>>>>>
>>>>> I just went to 6.1-PRE on my main machine, coming from 6.0-STABLE
>>>>> of roughly end of december.
>>>>>
>>>>> And I hit some stuff that really worries me:
>>>>>
>>>>> - the freshly built kernel keels over with (hand transcribed):
>>>>>
>>>>> ata3: reiniting channel SATA connect ... 
>>>>> SATA connected
>>>>> sata_connect_devices 0x1 <ATA_MASTER>
>>>>>
>>>>> ad6: req=0xC35ba0c8 SETFEATURES SETTRANSFERMODE semaphore timeout 
>>>>> !! DANGER Will RObinson !!
>>>>>
>>>>> (... is where I cannot read my own handwriting, it scrolled quite fast on
>>>>> the screen..)
>>>>>
>>>>> Boot device is a SATA RAID1 on a Promise 2300.
>>>> Hmm, that should not happen. Could you try to backstep just ATA to 
>>>> before the MFC, that is 24/1/06 and let me know if that helps please ?
>>> First impression is that the problem is gone.  None of the previously 
>>> reported errors are seen.  I am running a level 0 dump from disk to disk
>>> to see if the box remains stable.  Given that this is my primary machine
>>> I sure hope it will be :-)
>>>
>>>>> Another snag is that my ad10 disk on 6.0-STABLE suddenly became ad12 on
>>>>> 6.1-PRE
>>>> Hmm that is because there is only 2 ports on your promise which is now 
>>>> correctly identified, before it was errounsly found as 3 ports.
>>> Ah, OK.  I would suggest a note to the Release Note writers would be a good
>>> thing, devices changing location after an upgrade in the -stable branch
>>> is unnerving ;-)
>> Well, the good thing is that I can reproduce the error here, the bad 
>> thing is that it slipped through testing on -current...
>> Oh, well, I'll look into it ASAP...
> 
> Thank you Soren!

OK, had a few this afternoon, could you try this patch and let me know 
if it helps, at least it makes the problem go away on my testbed..

-Søren

--------------000801080306030609050702
Content-Type: text/plain;
 name="prom-p1"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="prom-p1"

Index: ata-chipset.c
===================================================================
RCS file: /nfs/export/ncvs/src/sys/dev/ata/ata-chipset.c,v
retrieving revision 1.156
diff -u -r1.156 ata-chipset.c
--- ata-chipset.c	6 Feb 2006 19:17:48 -0000	1.156
+++ ata-chipset.c	9 Feb 2006 13:20:06 -0000
@@ -2861,10 +2861,10 @@
      { ATA_PDC20377,  0, PRMIO, PRCMBO,  ATA_SA150, "PDC20377" },
      { ATA_PDC20378,  0, PRMIO, PRCMBO,  ATA_SA150, "PDC20378" },
      { ATA_PDC20379,  0, PRMIO, PRCMBO,  ATA_SA150, "PDC20379" },
-     { ATA_PDC20571,  0, PRMIO, PRSATA2, ATA_SA150, "PDC20571" },
+     { ATA_PDC20571,  0, PRMIO, PRCMBO2, ATA_SA150, "PDC20571" },
      { ATA_PDC20575,  0, PRMIO, PRCMBO2, ATA_SA150, "PDC20575" },
      { ATA_PDC20579,  0, PRMIO, PRCMBO2, ATA_SA150, "PDC20579" },
-     { ATA_PDC20771,  0, PRMIO, PRSATA2, ATA_SA300, "PDC20771" },
+     { ATA_PDC20771,  0, PRMIO, PRCMBO2, ATA_SA300, "PDC20771" },
      { ATA_PDC40775,  0, PRMIO, PRCMBO2, ATA_SA300, "PDC40775" },
      { ATA_PDC20617,  0, PRMIO, PRPATA,  ATA_UDMA6, "PDC20617" },
      { ATA_PDC20618,  0, PRMIO, PRPATA,  ATA_UDMA6, "PDC20618" },
@@ -2925,6 +2925,7 @@
 ata_promise_chipinit(device_t dev)
 {
     struct ata_pci_controller *ctlr = device_get_softc(dev);
+    int fake_reg, stat_reg;
 
     if (ata_setup_interrupt(dev))
 	return ENXIO;
@@ -2962,8 +2963,7 @@
 						    &ctlr->r_rid2, RF_ACTIVE)))
 	    goto failnfree;
 
-	switch (ctlr->chip->cfg2) {
-	case PRSX4X: {
+	if (ctlr->chip->cfg2 == PRSX4X) {
 	    struct ata_promise_sx4 *hpkt;
 	    u_int32_t dimm = ATA_INL(ctlr->r_res2, 0x000c0080);
 
@@ -2998,58 +2998,55 @@
 	    ctlr->setmode = ata_promise_setmode;
 	    ctlr->channels = 4;
 	    return 0;
-	    }
-	case PRPATA:
-	case PRCMBO:
-	case PRSATA:
-	    /* 
-	     * older "mio" type controllers need an interrupt intercept
-	     * function to compensate for the "reset on read" type interrupt
-	     * status register they have.
-	     */
-	    if (bus_teardown_intr(dev, ctlr->r_irq, ctlr->handle) ||
+	}
+
+	/* mio type controllers need an interrupt intercept */
+	if (bus_teardown_intr(dev, ctlr->r_irq, ctlr->handle) ||
 		bus_setup_intr(dev, ctlr->r_irq, ATA_INTR_FLAGS,
 			       ata_promise_mio_intr, ctlr, &ctlr->handle)) {
 		device_printf(dev, "unable to setup interrupt\n");
 		goto failnfree;
-	    }
-	    /* prime fake interrupt register */
-	    ATA_OUTL(ctlr->r_res2, 0x060, 0xffffffff);
-	    break;
 	}
 
-
-	ctlr->allocate = ata_promise_mio_allocate;
-	ctlr->reset = ata_promise_mio_reset;
-	ctlr->dmainit = ata_promise_mio_dmainit;
-	ctlr->setmode = ata_promise_mio_setmode;
-
 	switch (ctlr->chip->cfg2) {
 	case PRPATA:
 	    ctlr->channels = ((ATA_INL(ctlr->r_res2, 0x48) & 0x01) > 0) +
 			     ((ATA_INL(ctlr->r_res2, 0x48) & 0x02) > 0) + 2;
-	    return 0;
-
+	    goto sata150;
 	case PRCMBO:
-	    ATA_OUTL(ctlr->r_res2, 0x06c, 0x000000ff);
-	    ctlr->channels = ((ATA_INL(ctlr->r_res2, 0x48) & 0x02) > 0) + 3;
-	    return 0;
-
+	    ctlr->channels = 3;
+	    goto sata150;
 	case PRSATA:
-	    ATA_OUTL(ctlr->r_res2, 0x06c, 0x000000ff);
 	    ctlr->channels = 4;
-	    return 0;
+sata150:
+	    fake_reg = 0x60;
+	    stat_reg = 0x6c;
+	    break;
 
-	case PRCMBO2:
-	    ATA_OUTL(ctlr->r_res2, 0x060, 0x000000ff);
+	case PRCMBO2: 
 	    ctlr->channels = 3;
-	    return 0;
-
+	    goto sataii;
 	case PRSATA2:
-	    ATA_OUTL(ctlr->r_res2, 0x060, 0x000000ff);
+	default:
 	    ctlr->channels = 4;
-	    return 0;
+sataii:
+	    fake_reg = 0x54;
+	    stat_reg = 0x60;
+	    break;
 	}
+
+	/* prime fake interrupt register */
+	ATA_OUTL(ctlr->r_res2, fake_reg, 0xffffffff);
+
+	/* clear SATA status */
+	ATA_OUTL(ctlr->r_res2, stat_reg, 0x000000ff);
+
+	ctlr->allocate = ata_promise_mio_allocate;
+	ctlr->reset = ata_promise_mio_reset;
+	ctlr->dmainit = ata_promise_mio_dmainit;
+	ctlr->setmode = ata_promise_mio_setmode;
+
+	return 0;
     }
 
 failnfree:
@@ -3297,7 +3294,21 @@
 {
     struct ata_pci_controller *ctlr = data;
     struct ata_channel *ch;
-    int unit;
+    u_int32_t vector;
+    int unit, fake_reg;
+
+    switch (ctlr->chip->cfg2) {
+    case PRPATA:
+    case PRCMBO:
+    case PRSATA:
+	fake_reg = 0x60;
+	break;
+    case PRCMBO2: 
+    case PRSATA2:
+    default:
+	fake_reg = 0x54;
+	break;
+    }
 
     /*
      * since reading interrupt status register on early "mio" chips
@@ -3306,13 +3317,16 @@
      * store the bits in an unused register in the chip so we can read
      * it from there safely to get around this "feature".
      */
-    ATA_OUTL(ctlr->r_res2, 0x060, ATA_INL(ctlr->r_res2, 0x040));
+    vector = ATA_INL(ctlr->r_res2, 0x040);
+    ATA_OUTL(ctlr->r_res2, 0x040, vector);
+    ATA_OUTL(ctlr->r_res2, fake_reg, vector);
 
     for (unit = 0; unit < ctlr->channels; unit++) {
 	if ((ch = ctlr->interrupt[unit].argument))
 	    ctlr->interrupt[unit].function(ch);
     }
-    ATA_OUTL(ctlr->r_res2, 0x060, 0xffffffff);
+
+    ATA_OUTL(ctlr->r_res2, fake_reg, 0xffffffff);
 }
 
 static int
@@ -3321,37 +3335,30 @@
     struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
     struct ata_channel *ch = device_get_softc(dev);
     struct ata_connect_task *tp;
-    u_int32_t vector, status;
+    u_int32_t fake_reg, stat_reg, vector, status;
 
     switch (ctlr->chip->cfg2) {
     case PRPATA:
-    case PRSATA:
     case PRCMBO:
-	/* read and acknowledge interrupt */
-	vector = ATA_INL(ctlr->r_res2, 0x0060);
-
-	/* read and clear interface status */
-	status = ATA_INL(ctlr->r_res2, 0x006c);
-	ATA_OUTL(ctlr->r_res2, 0x006c, status & (0x00000011 << ch->unit));
+    case PRSATA:
+	fake_reg = 0x60;
+	stat_reg = 0x6c;
 	break;
-
+    case PRCMBO2: 
     case PRSATA2:
-    case PRCMBO2:
-critical_enter();
-	/* read and acknowledge interrupt */
-	vector = ATA_INL(ctlr->r_res2, 0x0040);
-	ATA_OUTL(ctlr->r_res2, 0x0040, (1 << (ch->unit + 1)));
-
-	/* read and clear interface status */
-	status = ATA_INL(ctlr->r_res2, 0x0060);
-	ATA_OUTL(ctlr->r_res2, 0x0060, status & (0x00000011 << ch->unit));
-critical_exit();
-	break;
-
     default:
-	return 0;
+	fake_reg = 0x54;
+	stat_reg = 0x60;
+	break;
     }
 
+    /* read and acknowledge interrupt */
+    vector = ATA_INL(ctlr->r_res2, fake_reg);
+
+    /* read and clear interface status */
+    status = ATA_INL(ctlr->r_res2, stat_reg);
+    ATA_OUTL(ctlr->r_res2, stat_reg, status & (0x00000011 << ch->unit));
+
     /* check for and handle disconnect events */
     if ((status & (0x00000001 << ch->unit)) &&
 	(tp = (struct ata_connect_task *)
Index: ata-pci.c
===================================================================
RCS file: /nfs/export/ncvs/src/sys/dev/ata/ata-pci.c,v
retrieving revision 1.114
diff -u -r1.114 ata-pci.c
--- ata-pci.c	25 Jan 2006 23:07:42 -0000	1.114
+++ ata-pci.c	9 Feb 2006 13:31:10 -0000
@@ -34,6 +34,7 @@
 #include <sys/module.h>
 #include <sys/ata.h>
 #include <sys/bus.h>
+#include <sys/conf.h>
 #include <sys/malloc.h>
 #include <sys/sema.h>
 #include <sys/taskqueue.h>
@@ -443,7 +444,7 @@
 {
     struct ata_channel *ch = device_get_softc(dev);
 
-    if (!ata_legacy(device_get_parent(dev)) &&
+    if ((dumping || !ata_legacy(device_get_parent(dev))) &&
 	ch->dma && ((ch->flags & ATA_ALWAYS_DMASTAT) ||
 		    (ch->dma->flags & ATA_DMA_ACTIVE))) {
 	int bmstat = ATA_IDX_INB(ch, ATA_BMSTAT_PORT) & ATA_BMSTAT_MASK;

--------------000801080306030609050702--



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