Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 21 Nov 2003 23:04:55 +0100 (CET)
From:      Soren Schmidt <sos@spider.deepcore.dk>
To:        Thomas Moestl <t.moestl@tu-bs.de>
Cc:        Kris Kennaway <kris@obsecurity.org>
Subject:   Re: ultra5/cmd646 hang
Message-ID:  <200311212204.hALM4tiA098027@spider.deepcore.dk>
In-Reply-To: <20031121145928.GA5400@timesink.dyndns.org>

next in thread | previous in thread | raw e-mail | index | archive | help
It seems Thomas Moestl wrote:
> This was a red herring, sorry. I inadvertently had did another change
> when I was testing whether this is required.

Well, shit happens :)

OK, try the following patch, it should do the tricks:

Index: ata-chipset.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/ata/ata-chipset.c,v
retrieving revision 1.46
diff -u -r1.46 ata-chipset.c
--- ata-chipset.c	18 Nov 2003 15:27:28 -0000	1.46
+++ ata-chipset.c	21 Nov 2003 22:05:26 -0000
@@ -101,6 +101,7 @@
 static int ata_sii_mio_allocate(device_t, struct ata_channel *);
 static void ata_sii_intr(void *);
 static void ata_cmd_intr(void *);
+static void ata_cmd_old_intr(void *);
 static void ata_sii_setmode(struct ata_device *, int);
 static void ata_cmd_setmode(struct ata_device *, int);
 static int ata_sis_chipinit(device_t);
@@ -1639,7 +1642,7 @@
     else {
 	if ((bus_setup_intr(dev, ctlr->r_irq, ATA_INTR_FLAGS,
 			    ctlr->chip->cfg2 & SIIINTR ? 
-			    ata_cmd_intr : ata_generic_intr,
+			    ata_cmd_intr : ata_cmd_old_intr,
 			    ctlr, &ctlr->handle))) {
 	    device_printf(dev, "unable to setup interrupt\n");
 	    return ENXIO;
@@ -1743,6 +1748,30 @@
 }
 
 static void
+ata_cmd_old_intr(void *data)
+{
+    struct ata_pci_controller *ctlr = data;
+    struct ata_channel *ch;
+    int unit;
+
+    /* implement this as a toggle instead to balance load XXX */
+    for (unit = 0; unit < 2; unit++) {
+	if (!(ch = ctlr->interrupt[unit].argument))
+	    continue;
+	if (ch->dma && (ch->dma->flags & ATA_DMA_ACTIVE)) {
+	    int bmstat = ATA_IDX_INB(ch, ATA_BMSTAT_PORT) & ATA_BMSTAT_MASK;
+
+	    if ((bmstat & (ATA_BMSTAT_ACTIVE | ATA_BMSTAT_INTERRUPT)) !=
+		ATA_BMSTAT_INTERRUPT)
+		continue;
+	    ATA_IDX_OUTB(ch, ATA_BMSTAT_PORT, bmstat & ~ATA_BMSTAT_ERROR);
+	    DELAY(1);
+	}
+	ctlr->interrupt[unit].function(ch);
+    }
+}
+
+static void
 ata_sii_setmode(struct ata_device *atadev, int mode)
 {
     device_t parent = device_get_parent(atadev->channel->dev);
@@ -1823,7 +1852,7 @@
 		   (error) ? "FAILURE " : "",
 		   ata_mode2str(mode), ctlr->chip->text);
     if (!error) {
-	int treg = 0x54 + (devno < 3) ? (devno << 1) : 7;
+	int treg = 0x54 + ((devno < 3) ? (devno << 1) : 7);
 	int ureg = atadev->channel->unit ? 0x7b : 0x73;
 
 	if (mode >= ATA_UDMA0) {	
-Søren



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