Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 08 Nov 2007 10:43:14 +0100
From:      =?ISO-8859-1?Q?S=F8ren_Schmidt?= <sos@deepcore.dk>
To:        Alexander Sabourenkov <screwdriver@lxnt.info>
Cc:        Nathan Butcher <n-butcher@fusiongol.com>, freebsd-current@freebsd.org
Subject:   Re: Remaining SATA (and other) issues
Message-ID:  <4732DA32.3090601@deepcore.dk>
In-Reply-To: <4732CEE3.3070003@lxnt.info>
References:  <47326FB8.50602@fusiongol.com> <4732CEE3.3070003@lxnt.info>

next in thread | previous in thread | raw e-mail | index | archive | help
Alexander Sabourenkov wrote:
> Please test this:
>
> http://lxnt.info/tx4/freebsd/chipinit.patch
> http://lxnt.info/tx4/freebsd/dma.patch
>
OK, some of that patch is wrong and break older chipsets, lets break it=20
down:

@@ -3265,12 +3265,26 @@
 	    stat_reg =3D 0x60;
 	    break;
 	}
-
-	/* prime fake interrupt register */
-	ATA_OUTL(ctlr->r_res2, fake_reg, 0xffffffff);

You cant remove this, ATA uses the 0x54 reg to store interrupts, its a ge=
n purpose reg on the promises, this initialization is neededed.

-
-	/* clear SATA status */
-	ATA_OUTL(ctlr->r_res2, stat_reg, 0x000000ff);
+	{
+	    const int PDC_FLASHCTL =3D 0x44;
+	    const int PDC_HOTPLUG  =3D 0x60;
+	    int tmp;
+	   =20
+	    /* enable BMR_BURST */
+	    tmp =3D ATA_INL(ctlr->r_res2, PDC_FLASHCTL);
+	    tmp |=3D 0x2000;
+	    ATA_OUTL(ctlr->r_res2, PDC_FLASHCTL, tmp);

That part might be relevant, but the registers are only valid on newer pr=
omise chips (those I call PRSATA2).

+	   =20
+	    /* clear plug/unplug flags */
+	    tmp =3D ATA_INL(ctlr->r_res2, PDC_HOTPLUG);
+	    tmp |=3D 0xff;
+	    ATA_OUTL(ctlr->r_res2, PDC_HOTPLUG, tmp);
+
+	    /* unmask plug/unplug ints */
+	    tmp =3D ATA_INL(ctlr->r_res2, PDC_HOTPLUG);
+	    tmp &=3D 0xff00ffff;
+	    ATA_OUTL(ctlr->r_res2, PDC_HOTPLUG, tmp);

This part is wrong for older promise chips, as the port# is different.
I also have a hard time seeing that this couldd change anything since the=
 registers are reset etc "my way" on each interrupt.
Besides you *do not* want to pass the other bits through, they shoudl be =
masked off and always written as 0's.

So my stance at this would be something like:

+++ ata-chipset.c	8 Nov 2007 10:43:00 -0000
@@ -3288,9 +3288,13 @@
 	/* prime fake interrupt register */
 	ATA_OUTL(ctlr->r_res2, fake_reg, 0xffffffff);
=20
-	/* clear SATA status */
+	/* clear SATA status and unmask interrupts */
 	ATA_OUTL(ctlr->r_res2, stat_reg, 0x000000ff);
=20
+	/* enable "long burst lenght" on gen2 chips */
+	if ((ctlr->chip->cfg2 =3D=3D PRSATA2) || (ctlr->chip->cfg2 =3D=3D PRCMB=
O2))
+	    ATA_OUTL(ctlr->r_res2, 0x44, ATA_INL(ctlr->r_res2, 0x44) | 0x2000);=

+
 	ctlr->allocate =3D ata_promise_mio_allocate;
 	ctlr->reset =3D ata_promise_mio_reset;
 	ctlr->dmainit =3D ata_promise_mio_dmainit;

The DMA table part I'll look into next, that one seems important, its jus=
t not enough in itself.

However I still need to find a way to reproduce, still hunting that one..=
=2E.

-S=F8ren





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