ultra5/cmd646 hang
Soren Schmidt
sos at spider.deepcore.dk
Fri Nov 21 14:06:38 PST 2003
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
More information about the freebsd-sparc64
mailing list