Remaining SATA (and other) issues
Søren Schmidt
sos at deepcore.dk
Thu Nov 8 01:43:33 PST 2007
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
down:
@@ -3265,12 +3265,26 @@
stat_reg = 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 gen purpose reg on the promises, this initialization is neededed.
-
- /* clear SATA status */
- ATA_OUTL(ctlr->r_res2, stat_reg, 0x000000ff);
+ {
+ const int PDC_FLASHCTL = 0x44;
+ const int PDC_HOTPLUG = 0x60;
+ int tmp;
+
+ /* enable BMR_BURST */
+ tmp = ATA_INL(ctlr->r_res2, PDC_FLASHCTL);
+ tmp |= 0x2000;
+ ATA_OUTL(ctlr->r_res2, PDC_FLASHCTL, tmp);
That part might be relevant, but the registers are only valid on newer promise chips (those I call PRSATA2).
+
+ /* clear plug/unplug flags */
+ tmp = ATA_INL(ctlr->r_res2, PDC_HOTPLUG);
+ tmp |= 0xff;
+ ATA_OUTL(ctlr->r_res2, PDC_HOTPLUG, tmp);
+
+ /* unmask plug/unplug ints */
+ tmp = ATA_INL(ctlr->r_res2, PDC_HOTPLUG);
+ tmp &= 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);
- /* clear SATA status */
+ /* clear SATA status and unmask interrupts */
ATA_OUTL(ctlr->r_res2, stat_reg, 0x000000ff);
+ /* enable "long burst lenght" on gen2 chips */
+ if ((ctlr->chip->cfg2 == PRSATA2) || (ctlr->chip->cfg2 == PRCMBO2))
+ ATA_OUTL(ctlr->r_res2, 0x44, ATA_INL(ctlr->r_res2, 0x44) | 0x2000);
+
ctlr->allocate = ata_promise_mio_allocate;
ctlr->reset = ata_promise_mio_reset;
ctlr->dmainit = ata_promise_mio_dmainit;
The DMA table part I'll look into next, that one seems important, its just not enough in itself.
However I still need to find a way to reproduce, still hunting that one....
-Søren
More information about the freebsd-current
mailing list