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>