Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 4 May 2004 11:25:42 -0700 (PDT)
From:      Doug Ambrisko <ambrisko@ambrisko.com>
To:        current@freebsd.org
Subject:   Updated SATA support patches for Intel ICH & Promise cards
Message-ID:  <200405041825.i44IPgVa021573@ambrisko.com>

next in thread | raw e-mail | index | archive | help
These patches have been updated to -current as of the past weekend.
They increase the robustness of SATA disk errors (media errors and
drive going away such as drives that spin up and down).  Also has
code to support hot swap on both controllers.

This is only HW support and does not address other ata/FreeBSD issues.
That isn't quite right ... some ata changes have been made to avoid
panics in probes etc. to support the HW changes.

It would be nice to get this into FreeBSD in some form then I can
help with other issues.

I have -stable code to read and write the Intel RAID meta-data
but not Adaptec.  My latest -stable patches supports Intel/
Promise SATA hot-swap and the Intel RAID meta-data with ata-raid.

Doug A.

Index: sys/dev/ata/ata-all.c
===================================================================
RCS file: /cvs/src/sys/dev/ata/ata-all.c,v
retrieving revision 1.208
diff -u -p -r1.208 ata-all.c
--- sys/dev/ata/ata-all.c	13 Apr 2004 09:44:20 -0000	1.208
+++ sys/dev/ata/ata-all.c	4 May 2004 18:16:49 -0000
@@ -119,7 +119,6 @@ ata_probe(device_t dev)
     ch->device[SLAVE].channel = ch;
     ch->device[SLAVE].unit = ATA_SLAVE;
     ch->device[SLAVE].mode = ATA_PIO;
-    ch->dev = dev;
     ch->state = ATA_IDLE;
 
     /* initialise device(s) on this channel */
@@ -308,6 +307,19 @@ ata_reinit(struct ata_channel *ch)
     return 0;
 }
 
+static void
+ata_reinit_task(void *data, int dummy)
+{
+    ata_reinit(data);
+}
+
+void
+ata_queue_reinit(struct ata_channel *ch)
+{
+    TASK_INIT(&ch->task, 0, ata_reinit_task, ch);
+    taskqueue_enqueue(taskqueue_thread, &ch->task);
+}
+
 int
 ata_suspend(device_t dev)
 {
Index: sys/dev/ata/ata-all.h
===================================================================
RCS file: /cvs/src/sys/dev/ata/ata-all.h,v
retrieving revision 1.78
diff -u -p -r1.78 ata-all.h
--- sys/dev/ata/ata-all.h	13 Apr 2004 09:44:20 -0000	1.78
+++ sys/dev/ata/ata-all.h	4 May 2004 18:16:49 -0000
@@ -363,6 +363,10 @@ struct ata_channel {
     struct mtx			queue_mtx;	/* queue lock */
     TAILQ_HEAD(, ata_request)	ata_queue;	/* head of ATA queue */
     struct ata_request		*running;	/* currently running request */
+    int				sata_master_idx;
+    int				sata_slave_idx;
+    struct task			task;		/* task management */
+    struct callout_handle	timeout_handle;	/* poll channel */
 };
 
 /* disk bay/enclosure related */
@@ -398,6 +402,7 @@ int ata_limit_mode(struct ata_device *at
 
 /* ata-queue.c: */
 int ata_reinit(struct ata_channel *ch);
+void ata_queue_reinit(struct ata_channel *ch);
 void ata_start(struct ata_channel *ch);
 int ata_controlcmd(struct ata_device *atadev, u_int8_t command, u_int16_t feature, u_int64_t lba, u_int16_t count);
 int ata_atapicmd(struct ata_device *atadev, u_int8_t *ccb, caddr_t data, int count, int flags, int timeout);
Index: sys/dev/ata/ata-chipset.c
===================================================================
RCS file: /cvs/src/sys/dev/ata/ata-chipset.c,v
retrieving revision 1.70
diff -u -p -r1.70 ata-chipset.c
--- sys/dev/ata/ata-chipset.c	24 Apr 2004 15:54:20 -0000	1.70
+++ sys/dev/ata/ata-chipset.c	4 May 2004 18:16:49 -0000
@@ -81,6 +81,11 @@ static int ata_highpoint_check_80pin(str
 static int ata_intel_chipinit(device_t);
 static void ata_intel_old_setmode(struct ata_device *, int);
 static void ata_intel_new_setmode(struct ata_device *, int);
+static int ata_intel_sata_allocate(device_t, struct ata_channel *);
+static void ata_intel_map_sata_ports(device_t, struct ata_channel *);
+static void ata_intel_sata_intr(void *);
+static void ata_intel_sata_status(struct ata_channel *);
+static void ata_intel_sata_reset(struct ata_channel *);
 static int ata_national_chipinit(device_t);
 static void ata_national_setmode(struct ata_device *, int);
 static int ata_nvidia_chipinit(device_t);
@@ -827,11 +832,11 @@ ata_intel_ident(device_t dev)
      { ATA_I82801DB,   0, 0, 0x00, ATA_UDMA5, "Intel ICH4" },
      { ATA_I82801DB_1, 0, 0, 0x00, ATA_UDMA5, "Intel ICH4" },
      { ATA_I82801EB,   0, 0, 0x00, ATA_UDMA5, "Intel ICH5" },
-     { ATA_I82801EB_1, 0, 0, 0x00, ATA_SA150, "Intel ICH5" },
-     { ATA_I82801EB_2, 0, 0, 0x00, ATA_SA150, "Intel ICH5" },
-     { ATA_I6300ESB,   0, 0, 0x00, ATA_UDMA5, "Intel ICH5" },
-     { ATA_I6300ESB_1, 0, 0, 0x00, ATA_SA150, "Intel ICH5" },
-     { ATA_I6300ESB_2, 0, 0, 0x00, ATA_SA150, "Intel ICH5" },
+     { ATA_I82801EB_1, 0, 0, ISATA, ATA_SA150, "Intel ICH5" },
+     { ATA_I82801EB_2, 0, 0, ISATA, ATA_SA150, "Intel ICH5" },
+     { ATA_I6300ESB,   0, 0, 0x00, ATA_UDMA5, "Intel ICH6" },
+     { ATA_I6300ESB_1, 0, 0, ISATA, ATA_SA150, "Intel ICH6" },
+     { ATA_I6300ESB_2, 0, 0, ISATA, ATA_SA150, "Intel ICH6" },
      { 0, 0, 0, 0, 0, 0}};
     char buffer[64]; 
 
@@ -849,6 +854,35 @@ static int
 ata_intel_chipinit(device_t dev)
 {
     struct ata_pci_controller *ctlr = device_get_softc(dev);
+    int rid = ATA_IRQ_RID;
+
+    if (ctlr->chip->cfg2 & ISATA) {
+	ctlr->allocate = ata_intel_sata_allocate;
+
+	/* Clear SATA error registers */
+	pci_write_config(dev, 0xa0, 0x54, 4);
+	pci_write_config(dev, 0xa4, pci_read_config(dev, 0xa4, 4), 4);
+	pci_write_config(dev, 0xa0, 0x64, 4);
+	pci_write_config(dev, 0xa4, pci_read_config(dev, 0xa4, 4), 4);
+
+	if (!ata_legacy(dev)) {
+	    if (!(ctlr->r_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
+						       RF_SHAREABLE
+						       | RF_ACTIVE))) {
+	        device_printf(dev, "unable to map interrupt\n");
+		return ENXIO;
+	    }
+	    if ((bus_setup_intr(dev, ctlr->r_irq, ATA_INTR_FLAGS,
+				ata_intel_sata_intr, ctlr, &ctlr->handle))) {
+	      device_printf(dev, "unable to setup interrupt\n");
+	      return ENXIO;
+	    }
+	}
+
+	ctlr->setmode = ata_sata_setmode;
+
+	return 0;
+    }
 
     if (ata_setup_interrupt(dev))
 	return ENXIO;
@@ -944,6 +978,228 @@ ata_intel_new_setmode(struct ata_device 
     atadev->mode = mode;
 }
 
+static int
+ata_intel_sata_allocate(device_t dev, struct ata_channel *ch)
+{
+    struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
+    struct resource *io = NULL, *altio = NULL;
+    int i, rid;
+
+    rid = ATA_IOADDR_RID;
+    io = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
+			    0, ~0, ATA_IOSIZE, RF_ACTIVE);
+    if (!io)
+	return ENXIO;
+
+    rid = ATA_ALTADDR_RID;
+    altio = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
+			       0, ~0, ATA_ALTIOSIZE, RF_ACTIVE);
+    if (!altio) {
+	bus_release_resource(dev, SYS_RES_IOPORT, ATA_IOADDR_RID, io);
+	return ENXIO;
+    }
+
+    for (i = ATA_DATA; i <= ATA_STATUS; i ++) {
+	ch->r_io[i].res = io;
+	ch->r_io[i].offset = i;
+    }
+    ch->r_io[ATA_ALTSTAT].res = altio;
+    ch->r_io[ATA_ALTSTAT].offset = ata_legacy(device_get_parent(dev)) ? 0 : 2;
+    ch->r_io[ATA_IDX_ADDR].res = io;
+
+    if (ctlr->r_res1) {
+	for (i = ATA_BMCMD_PORT; i <= ATA_BMDTP_PORT; i++) {
+	    ch->r_io[i].res = ctlr->r_res1;
+	    ch->r_io[i].offset = (i - ATA_BMCMD_PORT)+(ch->unit * ATA_BMIOSIZE);
+	}
+
+	/* if simplex controller, only allow DMA on primary channel */
+	ATA_IDX_OUTB(ch, ATA_BMSTAT_PORT, ATA_IDX_INB(ch, ATA_BMSTAT_PORT) &
+		     (ATA_BMSTAT_DMA_MASTER | ATA_BMSTAT_DMA_SLAVE));
+	if (ch->unit > 0 &&
+	    (ATA_IDX_INB(ch, ATA_BMSTAT_PORT) & ATA_BMSTAT_DMA_SIMPLEX))
+	    device_printf(dev, "simplex device, DMA on primary only\n");
+	else 
+	    ctlr->dmainit(ch);
+    }
+
+    ch->reset = ata_intel_sata_reset;
+    ata_intel_map_sata_ports(dev, ch);
+
+    ata_generic_hw(ch);
+
+    return 0;
+}
+
+void
+ata_intel_map_sata_ports(device_t dev, struct ata_channel *ch)
+{
+    device_t parent = device_get_parent(dev);
+    int unit = ch->unit;
+    int sata_config;
+
+    sata_config = pci_read_config(parent, 0x90, 1);
+
+    switch (sata_config & 7) {
+    case 0: /* SATA P0 on pri master SATA P1 on sec master */
+	if (unit == 0) {
+	    ch->sata_master_idx = 1;
+	    device_printf(dev, "SATA P0 primary master\n");
+        }
+	if (unit == 1) {
+	    ch->sata_master_idx = 2;
+	    device_printf(dev, "SATA P1 secondary master\n");
+	}
+	break;
+    case 1: /* SATA P0 on sec master SATA P1 on pri master */
+	if (unit == 0) {
+	    ch->sata_master_idx = 2;
+	    device_printf(dev, "SATA P0 secondary master\n");
+	}
+	if (unit == 1) {
+	    ch->sata_master_idx = 0;
+	    device_printf(dev, "SATA P1 primary master\n");
+	}
+	break;
+    case 4: /* SATA P0 on pri master SATA P1 on pri slave  */
+	if (unit == 0) {
+	    ch->sata_master_idx = 1;
+	    ch->sata_slave_idx = 2;
+	    device_printf(dev, "SATA P0 primary master\n");
+	    device_printf(dev, "SATA P1 primary slave\n");
+        }
+	break;
+    case 5: /* SATA P0 on pri slave  SATA P1 on pri master */
+	if (unit == 0) {
+	    ch->sata_master_idx = 2;
+	    ch->sata_slave_idx = 1;
+	    device_printf(dev, "SATA P0 primary slave\n");
+	    device_printf(dev, "SATA P1 primary master\n");
+	}
+	break;
+    case 6: /* SATA P0 on sec master SATA P1 on sec slave  */
+	if (unit == 1) {
+	    ch->sata_master_idx = 1;
+	    ch->sata_slave_idx = 2;
+	    device_printf(dev, "SATA P0 secondary master\n");
+	    device_printf(dev, "SATA P1 secondary slave\n");
+	}
+	break;
+    case 7: /* SATA P0 on sec slave  SATA P1 on sec master */
+	if (unit == 1) {
+	    ch->sata_master_idx = 2;
+	    ch->sata_slave_idx = 1;
+	    device_printf(dev, "SATA P0 secondary slave\n");
+	    device_printf(dev, "SATA P1 secondary master\n");
+	}
+	break;
+    }
+}
+
+static void
+ata_intel_sata_status(struct ata_channel *ch)
+{
+    device_t parent;
+    struct ata_pci_controller *ctlr;
+    u_int32_t sstatus, serror, scontrol;
+    int index = 0, device, base;  
+    
+    if (!ch->dev)	/* Channel not ready */
+	return;
+    parent = device_get_parent(ch->dev);
+    ctlr = device_get_softc(parent);
+
+    ch->locking(ch, ATA_LF_LOCK);
+    untimeout((timeout_t *)ata_intel_sata_status, ch, ch->timeout_handle);
+
+    index = ch->sata_master_idx | ch->sata_slave_idx;;
+
+    for (device = 1; device <= 2; device++) {
+	if (index & device) {
+	    if (device == 1)
+		base = 0x50;
+	    else
+		base = 0x60;
+	
+	    pci_write_config(parent, 0xa0, base, 4);
+	    sstatus = pci_read_config(parent, 0xa4, 4);
+
+	    pci_write_config(parent, 0xa0, base + 4, 4);
+	    serror = pci_read_config(parent, 0xa4, 4);
+
+	    pci_write_config(parent, 0xa0, base + 8, 4);
+	    scontrol = pci_read_config(parent, 0xa4, 4);
+
+	    if (serror) {
+		if (sstatus == 0x05) { /* Drive left reset port */
+		    pci_write_config(parent, 0x92, 
+			pci_read_config(parent, 0x92, 2) & ~device, 2);
+		    pci_write_config(parent, 0x92, 
+			pci_read_config(parent, 0x92, 2) | device, 2);
+		}
+
+		/* Loop until SATA port is okay otherwise we can hang */
+		for (;;) {   
+		    pci_write_config(parent, 0xa0, base, 4);
+		    sstatus = pci_read_config(parent, 0xa4, 4);
+
+		    pci_write_config(parent, 0xa0, base + 4, 4);
+		    serror = pci_read_config(parent, 0xa4, 4);
+		    /* Acknowledge serror */
+		    pci_write_config(parent, 0xa4, serror, 4);
+
+		    pci_write_config(parent, 0xa0, base + 8, 4);
+		    scontrol = pci_read_config(parent, 0xa4, 4);
+		    device_printf(ch->dev, 
+			"Intel SATA P%d status %x error %x scontrol %x %d %x\n",
+			device - 1, sstatus, serror, scontrol, 
+			ch->unit, ch->devices);
+		    if (!serror && sstatus != 5)
+			break;
+
+		    DELAY(100000);
+		}
+		ata_queue_reinit(ch);
+	    }
+	}
+    }
+    ch->timeout_handle = timeout((timeout_t*)ata_intel_sata_status,
+        ch, 10 * hz);
+
+    ch->locking(ch, ATA_LF_UNLOCK);
+}
+
+static void 
+ata_intel_sata_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;
+	ata_intel_sata_status(ch);
+	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_intel_sata_reset(struct ata_channel *ch)
+{
+    ata_intel_sata_status(ch);
+}
+
 /*
  * National chipset support functions
  */
@@ -1182,6 +1438,8 @@ ata_promise_chipinit(device_t dev)
     struct ata_pci_controller *ctlr = device_get_softc(dev);
     int rid = ATA_IRQ_RID;
 
+    mtx_init(&ctlr->mtx, "ATA controller lock", MTX_DEF, 0);
+	
     if (!(ctlr->r_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
 					       RF_SHAREABLE | RF_ACTIVE))) {
 	device_printf(dev, "unable to map interrupt\n");
@@ -1238,7 +1496,7 @@ ata_promise_chipinit(device_t dev)
 			     ((ATA_INL(ctlr->r_res2, 0x48) & 0x02) > 0) + 2;
 	}
 	else if (ctlr->chip->cfg2 & PRSATA) {
-	    ATA_OUTL(ctlr->r_res2, 0x06c, 0x00ff0033);
+	    ATA_OUTL(ctlr->r_res2, 0x06c, 0x000000ff);
 	    ctlr->channels = ((ATA_INL(ctlr->r_res2, 0x48) & 0x02) > 0) + 3;
 	}
 	else
@@ -1302,6 +1560,7 @@ ata_promise_mio_allocate(device_t dev, s
     ch->r_io[ATA_IDX_ADDR].res = ctlr->r_res2;
     ch->flags |= ATA_USE_16BIT;
     ch->reset = ata_promise_mio_reset;
+    ch->reset(ch);
 
     ctlr->dmainit(ch);  
     ata_generic_hw(ch);
@@ -1317,13 +1576,50 @@ ata_promise_mio_intr(void *data)
 {
     struct ata_pci_controller *ctlr = data;
     struct ata_channel *ch;
-    u_int32_t vector = ATA_INL(ctlr->r_res2, 0x00040);
+    u_int32_t vector, plug_status;
+    int offset = (ctlr->chip->cfg2 & PRSX4X) ? 0x000c0000 : 0;
     int unit;
 
+    if (ctlr->chip->cfg2 & PRSATA) {
+	/* Check for all drive changes first */
+	plug_status = ATA_INL(ctlr->r_res2, 0x06c);
+	for (unit = 0; unit < ctlr->channels; unit++) {
+	    if (plug_status & (1 << unit)) {
+		/* drive gone */
+		ATA_OUTL(ctlr->r_res2, 0x06c, 1 << unit);
+		if ((ch = ctlr->interrupt[unit].argument)) {
+		    device_printf(ch->dev,
+				  "device on port %d gone\n", unit + 1);
+		    ata_queue_reinit(ch);
+		}
+	    }
+
+	    if (plug_status & (1 << (unit + 4))) {
+		/* drive connected */
+		ATA_OUTL(ctlr->r_res2, 0x06c, 1 << (unit + 4));
+		if ((ch = ctlr->interrupt[unit].argument)) {
+		    device_printf(ch->dev,
+				  "device on port %d connected\n", unit + 1);
+		    ata_queue_reinit(ch);
+		}
+	    }
+	}
+    }
+
+    vector = ATA_INL(ctlr->r_res2, 0x00040);
     for (unit = 0; unit < ctlr->channels; unit++) {
 	if (vector & (1 << (unit + 1))) {
 	    if ((ch = ctlr->interrupt[unit].argument))
+		if (ATA_INL(ctlr->r_res2, offset + ((ch->unit + 1) << 2))
+		    & 1 << (ch->unit + 16))
+		    ch->reset(ch);
 		ctlr->interrupt[unit].function(ch);
+		ATA_OUTL(ctlr->r_res2, offset + 0x0260 + (ch->unit << 7),
+			 (ATA_INL(ctlr->r_res2, 
+				  offset + 0x0260 + (ch->unit << 7)) &
+			  ~0x00003f9f) | (ch->unit + 1));
+
+		ATA_OUTL(ctlr->r_res2, offset + ((ch->unit + 1) << 2), 0x1);
 	}
     }
 }
@@ -1389,7 +1685,32 @@ ata_promise_mio_reset(struct ata_channel
     struct ata_pci_controller *ctlr = 
 	device_get_softc(device_get_parent(ch->dev));
     int offset = (ctlr->chip->cfg2 & PRSX4X) ? 0x000c0000 : 0;
+    u_int32_t control;
+
+    mtx_lock(&ctlr->mtx);
+    control = ATA_INL(ctlr->r_res2, 0x0048);
+    /* channel reset */
+    control &= ~(1 << (ch->unit + 12));
+    ATA_OUTL(ctlr->r_res2, 0x0048, control);
+    control |= 1 << (ch->unit + 12);
+    ATA_OUTL(ctlr->r_res2, 0x0048, control);
+    
+    DELAY(1000); /* DJA XXX */
+    mtx_unlock(&ctlr->mtx);
+
+    if (ctlr->chip->cfg2 & PRSATA) {
+        /* clear plug status that bounces during hard reset */
+	ATA_OUTL(ctlr->r_res2, 0x06c, (1 << ch->unit) | (1 << (ch->unit + 4)));
+    }
+
+    /* ATA module reset */
+    ATA_OUTL(ctlr->r_res2, offset + 0x0260 + (ch->unit << 7), 0x800);
+
+    /* Define which sequencer to interrupt on */
+    ATA_OUTL(ctlr->r_res2, offset + 0x0260 + (ch->unit << 7),
+	     0x80008000 | (ch->unit + 1));
 
+    /* Define which sequencer to interrupt on */
     ATA_OUTL(ctlr->r_res2, offset + 0x0260 + (ch->unit << 7),
 	     (ATA_INL(ctlr->r_res2, offset + 0x0260 + (ch->unit << 7)) &
 	      ~0x00003f9f) | (ch->unit + 1));
Index: sys/dev/ata/ata-lowlevel.c
===================================================================
RCS file: /cvs/src/sys/dev/ata/ata-lowlevel.c,v
retrieving revision 1.34
diff -u -p -r1.34 ata-lowlevel.c
--- sys/dev/ata/ata-lowlevel.c	27 Apr 2004 15:52:08 -0000	1.34
+++ sys/dev/ata/ata-lowlevel.c	4 May 2004 18:16:49 -0000
@@ -573,6 +573,10 @@ ata_generic_reset(struct ata_channel *ch
     if (!mask)
 	return;
 
+    /* reset host end of channel (if supported) */
+    if (ch->reset)
+	ch->reset(ch);
+
     /* reset (both) devices on this channel */
     ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_MASTER);
     DELAY(10);
Index: sys/dev/ata/ata-pci.c
===================================================================
RCS file: /cvs/src/sys/dev/ata/ata-pci.c,v
retrieving revision 1.82
diff -u -p -r1.82 ata-pci.c
--- sys/dev/ata/ata-pci.c	27 Apr 2004 12:54:59 -0000	1.82
+++ sys/dev/ata/ata-pci.c	4 May 2004 18:16:49 -0000
@@ -523,12 +523,15 @@ ata_pcisub_probe(device_t dev)
     }
     free(children, M_TEMP);
 
+    ch->dev = dev;
     if ((error = ctlr->allocate(dev, ch)))
 	return error;
 
     ch->device[MASTER].setmode = ctlr->setmode;
     ch->device[SLAVE].setmode = ctlr->setmode;
     ch->locking = ctlr->locking;
+    if (ch->reset)
+	ch->reset(ch);
     return ata_probe(dev);
 }
 
Index: sys/dev/ata/ata-pci.h
===================================================================
RCS file: /cvs/src/sys/dev/ata/ata-pci.h,v
retrieving revision 1.30
diff -u -p -r1.30 ata-pci.h
--- sys/dev/ata/ata-pci.h	21 Apr 2004 20:03:26 -0000	1.30
+++ sys/dev/ata/ata-pci.h	4 May 2004 18:16:49 -0000
@@ -61,6 +61,7 @@ struct ata_pci_controller {
     void		 *argument;
     } interrupt[8];	/* SOS max ch# for now XXX */
     void		 *driver;
+    struct mtx		mtx; 
 };
 
 /* defines for known chipset PCI id's */
@@ -251,6 +252,8 @@ struct ata_pci_controller {
 #define HPT374		3
 #define HPTOLD		0x01
 
+#define ISATA		1
+
 #define PROLD		0
 #define PRNEW		1
 #define PRTX		2
Index: sys/dev/ata/ata-queue.c
===================================================================
RCS file: /cvs/src/sys/dev/ata/ata-queue.c,v
retrieving revision 1.26
diff -u -p -r1.26 ata-queue.c
--- sys/dev/ata/ata-queue.c	13 Apr 2004 09:44:20 -0000	1.26
+++ sys/dev/ata/ata-queue.c	4 May 2004 18:16:49 -0000
@@ -454,6 +454,7 @@ ata_timeout(struct ata_request *request)
 	printf("\n");
     }
 
+    request->device->channel->hw.reset(request->device->channel);
     /* now simulate the missing interrupt */
     request->flags |= ATA_R_TIMEOUT;
     request->device->channel->hw.interrupt(request->device->channel);



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