twe(4): Sync with FreeBSD.
authorSascha Wildner <saw@online.de>
Wed, 5 Dec 2012 22:28:33 +0000 (23:28 +0100)
committerSascha Wildner <saw@online.de>
Wed, 5 Dec 2012 22:29:07 +0000 (23:29 +0100)
Main change is making it MPSAFE. There's also some cleanup and misc
fixes.

I tested it with an Escalade 8506-8.

share/man/man4/twe.4
sys/dev/raid/twe/Makefile
sys/dev/raid/twe/twe.c
sys/dev/raid/twe/twe_compat.h
sys/dev/raid/twe/twe_freebsd.c
sys/dev/raid/twe/twe_tables.h
sys/dev/raid/twe/tweio.h
sys/dev/raid/twe/twereg.h
sys/dev/raid/twe/twevar.h

index e37163e..1495fa1 100644 (file)
@@ -22,7 +22,7 @@
 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.\" $FreeBSD: src/share/man/man4/twe.4,v 1.17 2006/05/20 09:39:28 brueffer Exp $
+.\" $FreeBSD: src/share/man/man4/twe.4,v 1.18 2012/11/17 01:50:48 svnexp Exp $
 .\"
 .Dd December 31, 2010
 .Dt TWE 4
index 0c3041a..73bec50 100644 (file)
@@ -1,4 +1,4 @@
-# $FreeBSD: src/sys/modules/twe/Makefile,v 1.7 2005/08/10 04:01:21 obrien Exp $
+# $FreeBSD: src/sys/modules/twe/Makefile,v 1.8 2012/11/17 01:53:01 svnexp Exp $
 
 KMOD=  twe
 SRCS=  bus_if.h device_if.h pci_if.h twe.c twe_freebsd.c
index 9683684..4add740 100644 (file)
@@ -26,7 +26,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *     $FreeBSD: src/sys/dev/twe/twe.c,v 1.30 2009/12/25 17:34:43 mav Exp $
+ *     $FreeBSD: src/sys/dev/twe/twe.c,v 1.34 2012/11/17 01:52:19 svnexp Exp $
  */
 
 /*
@@ -68,7 +68,7 @@ static int    twe_del_unit(struct twe_softc *sc, int unit);
 /*
  * Command I/O to controller.
  */
-static void    twe_done(struct twe_softc *sc);
+static void    twe_done(struct twe_softc *sc, int startio);
 static void    twe_complete(struct twe_softc *sc);
 static int     twe_wait_status(struct twe_softc *sc, u_int32_t status, int timeout);
 static int     twe_drain_response_queue(struct twe_softc *sc);
@@ -151,8 +151,11 @@ twe_setup(struct twe_softc *sc)
        /*
         * Put command onto the freelist.
         */
+       TWE_IO_LOCK(sc);
        twe_release_request(tr);
+       TWE_IO_UNLOCK(sc);
     }
+    TWE_IO_LOCK(sc);
 
     /*
      * Check status register for errors, clear them.
@@ -164,6 +167,7 @@ twe_setup(struct twe_softc *sc)
      * Wait for the controller to come ready.
      */
     if (twe_wait_status(sc, TWE_STATUS_MICROCONTROLLER_READY, 60)) {
+       TWE_IO_UNLOCK(sc);
        twe_printf(sc, "microcontroller not ready\n");
        return(ENXIO);
     }
@@ -185,6 +189,7 @@ twe_setup(struct twe_softc *sc)
        if (!twe_soft_reset(sc))
            break;                      /* reset process complete */
     }
+    TWE_IO_UNLOCK(sc);
     /* did we give up? */
     if (i >= TWE_MAX_RESET_TRIES) {
        twe_printf(sc, "can't initialise controller, giving up\n");
@@ -203,14 +208,17 @@ twe_add_unit(struct twe_softc *sc, int unit)
     TWE_Param                  *drives = NULL, *param = NULL;
     TWE_Array_Descriptor       *ud;
 
+    TWE_CONFIG_ASSERT_LOCKED(sc);
     if (unit < 0 || unit > TWE_MAX_UNITS)
        return (EINVAL);
 
     /*
      * The controller is in a safe state, so try to find drives attached to it.
      */
+    TWE_IO_LOCK(sc);
     if ((drives = twe_get_param(sc, TWE_PARAM_UNITSUMMARY, TWE_PARAM_UNITSUMMARY_Status,
                                TWE_MAX_UNITS, NULL)) == NULL) {
+       TWE_IO_UNLOCK(sc);
        twe_printf(sc, "can't detect attached units\n");
        return (EIO);
     }
@@ -218,6 +226,7 @@ twe_add_unit(struct twe_softc *sc, int unit)
     dr = &sc->twe_drive[unit];
     /* check that the drive is online */
     if (!(drives->data[unit] & TWE_PARAM_UNITSTATUS_Online)) {
+       TWE_IO_UNLOCK(sc);
        error = ENXIO;
        goto out;
     }
@@ -225,21 +234,25 @@ twe_add_unit(struct twe_softc *sc, int unit)
     table = TWE_PARAM_UNITINFO + unit;
 
     if (twe_get_param_4(sc, table, TWE_PARAM_UNITINFO_Capacity, &dr->td_size)) {
+       TWE_IO_UNLOCK(sc);
        twe_printf(sc, "error fetching capacity for unit %d\n", unit);
        error = EIO;
        goto out;
     }
     if (twe_get_param_1(sc, table, TWE_PARAM_UNITINFO_Status, &dr->td_state)) {
+       TWE_IO_UNLOCK(sc);
        twe_printf(sc, "error fetching state for unit %d\n", unit);
        error = EIO;
        goto out;
     }
     if (twe_get_param_2(sc, table, TWE_PARAM_UNITINFO_DescriptorSize, &dsize)) {
+       TWE_IO_UNLOCK(sc);
        twe_printf(sc, "error fetching descriptor size for unit %d\n", unit);
        error = EIO;
        goto out;
     }
     if ((param = twe_get_param(sc, table, TWE_PARAM_UNITINFO_Descriptor, dsize - 3, NULL)) == NULL) {
+       TWE_IO_UNLOCK(sc);
        twe_printf(sc, "error fetching descriptor for unit %d\n", unit);
        error = EIO;
        goto out;
@@ -257,6 +270,7 @@ twe_add_unit(struct twe_softc *sc, int unit)
     }
     dr->td_cylinders = dr->td_size / (dr->td_heads * dr->td_sectors);
     dr->td_twe_unit = unit;
+    TWE_IO_UNLOCK(sc);
 
     error = twe_attach_drive(sc, dr);
 
@@ -273,6 +287,7 @@ twe_del_unit(struct twe_softc *sc, int unit)
 {
     int error;
 
+    TWE_CONFIG_ASSERT_LOCKED(sc);
     if (unit < 0 || unit >= TWE_MAX_UNITS)
        return (ENXIO);
 
@@ -294,12 +309,15 @@ twe_init(struct twe_softc *sc)
     /*
      * Scan for drives
      */
+    TWE_CONFIG_LOCK(sc);
     for (i = 0; i < TWE_MAX_UNITS; i++)
        twe_add_unit(sc, i);
+    TWE_CONFIG_UNLOCK(sc);
 
     /*
      * Initialise connection with controller.
      */
+    TWE_IO_LOCK(sc);
     twe_init_connection(sc, TWE_INIT_MESSAGE_CREDITS);
 
 #ifdef TWE_SHUTDOWN_NOTIFICATION
@@ -318,6 +336,7 @@ twe_init(struct twe_softc *sc)
      * Finally enable interrupts.
      */
     twe_enable_interrupts(sc);
+    TWE_IO_UNLOCK(sc);
 }
 
 /********************************************************************************
@@ -329,6 +348,7 @@ twe_deinit(struct twe_softc *sc)
     /*
      * Mark the controller as shutting down, and disable any further interrupts.
      */
+    twe_lockassert(&sc->twe_io_lock);
     sc->twe_state |= TWE_STATE_SHUTDOWN;
     twe_disable_interrupts(sc);
 
@@ -367,7 +387,7 @@ twe_intr(struct twe_softc *sc)
     if (status_reg & TWE_STATUS_COMMAND_INTERRUPT)
        twe_command_intr(sc);
     if (status_reg & TWE_STATUS_RESPONSE_INTERRUPT)
-       twe_done(sc);
+       twe_done(sc, 1);
 }
 
 /********************************************************************************
@@ -379,12 +399,13 @@ twe_startio(struct twe_softc *sc)
 {
     struct twe_request *tr;
     TWE_Command                *cmd;
-    twe_bio            *bio;
+    struct bio         *bio;
     struct buf         *bp;
     int                        error;
 
     debug_called(4);
 
+    twe_lockassert(&sc->twe_io_lock);
     if (sc->twe_state & (TWE_STATE_CTLR_BUSY | TWE_STATE_FRZN))
        return;
 
@@ -442,7 +463,7 @@ twe_startio(struct twe_softc *sc)
                break;
            tr->tr_status = TWE_CMD_ERROR;
            if (tr->tr_private != NULL) {
-               bio = (twe_bio *)tr->tr_private;
+               bio = (struct bio *)(tr->tr_private);
                bp = bio->bio_buf;
                bp->b_error = error;
                bp->b_flags |= B_ERROR;
@@ -507,14 +528,31 @@ twe_ioctl(struct twe_softc *sc, u_long ioctlcmd, void *addr)
     struct twe_request         *tr;
     u_int8_t                   srid;
     int                                error;
+    size_t                     tr_length;
 
     error = 0;
     switch(ioctlcmd) {
        /* handle a command from userspace */
     case TWEIO_COMMAND:
+       /*
+        * if there's a data buffer, allocate and copy it in.
+        * Must be in multipled of 512 bytes.
+        */
+       tr_length = roundup2(tu->tu_size, 512);
+       if (tr_length > 0) {
+           data = kmalloc(tr_length, M_DEVBUF, M_WAITOK);
+           error = copyin(tu->tu_data, data, tu->tu_size);
+           if (error) {
+               kfree(data, M_DEVBUF);
+               break;
+           }
+       } else
+           data = NULL;
+
        /* get a request */
+       TWE_IO_LOCK(sc);
        while (twe_get_request(sc, &tr))
-           tsleep(sc, 0, "twioctl", hz);
+           lksleep(sc, &sc->twe_io_lock, 0, "twioctl", hz);
 
        /*
         * Save the command's request ID, copy the user-supplied command in,
@@ -529,16 +567,14 @@ twe_ioctl(struct twe_softc *sc, u_long ioctlcmd, void *addr)
         * if there's a data buffer, allocate and copy it in.
         * Must be in multipled of 512 bytes.
         */
-       tr->tr_length = (tu->tu_size + 511) & ~511;
-       if (tr->tr_length > 0) {
-           tr->tr_data = kmalloc(tr->tr_length, M_DEVBUF, M_WAITOK);
-           if ((error = copyin(tu->tu_data, tr->tr_data, tu->tu_size)) != 0)
-               goto cmd_done;
+       tr->tr_length = tr_length;
+       tr->tr_data = data;
+       if (tr->tr_length > 0)
            tr->tr_flags |= TWE_CMD_DATAIN | TWE_CMD_DATAOUT;
-       }
 
        /* run the command */
        error = twe_wait_request(tr);
+       TWE_IO_UNLOCK(sc);
        if (error)
            goto cmd_done;
 
@@ -553,8 +589,9 @@ twe_ioctl(struct twe_softc *sc, u_long ioctlcmd, void *addr)
        /* free resources */
        if (tr->tr_data != NULL)
            kfree(tr->tr_data, M_DEVBUF);
-       if (tr != NULL)
-           twe_release_request(tr);
+       TWE_IO_LOCK(sc);
+       twe_release_request(tr);
+       TWE_IO_UNLOCK(sc);
 
        break;
 
@@ -567,7 +604,9 @@ twe_ioctl(struct twe_softc *sc, u_long ioctlcmd, void *addr)
        case TWEQ_READY:
        case TWEQ_BUSY:
        case TWEQ_COMPLETE:
+           TWE_IO_LOCK(sc);
            bcopy(&sc->twe_qstat[ts->ts_item], &ts->ts_qstat, sizeof(struct twe_qstat));
+           TWE_IO_UNLOCK(sc);
            break;
 #endif
        default:
@@ -578,22 +617,28 @@ twe_ioctl(struct twe_softc *sc, u_long ioctlcmd, void *addr)
 
        /* poll for an AEN */
     case TWEIO_AEN_POLL:
+       TWE_IO_LOCK(sc);
        *aen_code = twe_dequeue_aen(sc);
+       TWE_IO_UNLOCK(sc);
        break;
 
        /* wait for another AEN to show up */
     case TWEIO_AEN_WAIT:
-       crit_enter();
+       TWE_IO_LOCK(sc);
        while ((*aen_code = twe_dequeue_aen(sc)) == TWE_AEN_QUEUE_EMPTY) {
-           error = tsleep(&sc->twe_aen_queue, PCATCH, "tweaen", 0);
+           error = lksleep(&sc->twe_aen_queue, &sc->twe_io_lock, PCATCH,
+               "tweaen", 0);
            if (error == EINTR)
                break;
        }
-       crit_exit();
+       TWE_IO_UNLOCK(sc);
        break;
 
     case TWEIO_GET_PARAM:
-       if ((param = twe_get_param(sc, tp->tp_table_id, tp->tp_param_id, tp->tp_size, NULL)) == NULL) {
+       TWE_IO_LOCK(sc);
+       param = twe_get_param(sc, tp->tp_table_id, tp->tp_param_id, tp->tp_size, NULL);
+       TWE_IO_UNLOCK(sc);
+       if (param == NULL) {
            twe_printf(sc, "TWEIO_GET_PARAM failed for 0x%x/0x%x/%d\n", 
                       tp->tp_table_id, tp->tp_param_id, tp->tp_size);
            error = EINVAL;
@@ -612,21 +657,30 @@ twe_ioctl(struct twe_softc *sc, u_long ioctlcmd, void *addr)
     case TWEIO_SET_PARAM:
        data = kmalloc(tp->tp_size, M_DEVBUF, M_WAITOK);
        error = copyin(tp->tp_data, data, tp->tp_size);
-       if (error == 0)
+       if (error == 0) {
+           TWE_IO_LOCK(sc);
            error = twe_set_param(sc, tp->tp_table_id, tp->tp_param_id, tp->tp_size, data);
+           TWE_IO_UNLOCK(sc);
+       }
        kfree(data, M_DEVBUF);
        break;
 
     case TWEIO_RESET:
+       TWE_IO_LOCK(sc);
        twe_reset(sc);
+       TWE_IO_UNLOCK(sc);
        break;
 
     case TWEIO_ADD_UNIT:
+       TWE_CONFIG_LOCK(sc);
        error = twe_add_unit(sc, td->td_unit);
+       TWE_CONFIG_UNLOCK(sc);
        break;
 
     case TWEIO_DEL_UNIT:
+       TWE_CONFIG_LOCK(sc);
        error = twe_del_unit(sc, td->td_unit);
+       TWE_CONFIG_UNLOCK(sc);
        break;
 
        /* XXX implement ATA PASSTHROUGH */
@@ -724,6 +778,7 @@ twe_get_param(struct twe_softc *sc, int table_id, int param_id, size_t param_siz
 
     debug_called(4);
 
+    twe_lockassert(&sc->twe_io_lock);
     tr = NULL;
     param = NULL;
 
@@ -816,6 +871,7 @@ twe_set_param(struct twe_softc *sc, int table_id, int param_id, int param_size,
 
     debug_called(4);
 
+    twe_lockassert(&sc->twe_io_lock);
     tr = NULL;
     param = NULL;
     error = ENOMEM;
@@ -872,6 +928,8 @@ twe_init_connection(struct twe_softc *sc, int mode)
     
     debug_called(4);
 
+    twe_lockassert(&sc->twe_io_lock);
+
     /* get a command */
     if (twe_get_request(sc, &tr))
        return(0);
@@ -903,14 +961,13 @@ twe_wait_request(struct twe_request *tr)
 {
     debug_called(4);
 
+    twe_lockassert(&tr->tr_sc->twe_io_lock);
     tr->tr_flags |= TWE_CMD_SLEEPER;
     tr->tr_status = TWE_CMD_BUSY;
     twe_enqueue_ready(tr);
     twe_startio(tr->tr_sc);
-    crit_enter();
     while (tr->tr_status == TWE_CMD_BUSY)
-       tsleep(tr, 0, "twewait", 0);
-    crit_exit();
+       lksleep(tr, &tr->tr_sc->twe_io_lock, 0, "twewait", 0);
     
     return(tr->tr_status != TWE_CMD_COMPLETE);
 }
@@ -945,7 +1002,7 @@ twe_immediate_request(struct twe_request *tr, int usetmp)
     /* Wait up to 5 seconds for the command to complete */
     while ((count++ < 5000) && (tr->tr_status == TWE_CMD_BUSY)){
        DELAY(1000);
-       twe_done(sc);
+       twe_done(sc, 1);
     }
     if (usetmp && (tr->tr_data != NULL))
        bcopy(sc->twe_immediate, tr->tr_data, tr->tr_length);
@@ -961,7 +1018,7 @@ twe_completeio(struct twe_request *tr)
 {
     TWE_Command                *cmd = TWE_FIND_COMMAND(tr);
     struct twe_softc   *sc = tr->tr_sc;
-    struct bio         *bio = (twe_bio *)tr->tr_private;
+    struct bio         *bio = tr->tr_private;
     struct buf         *bp = bio->bio_buf;
 
     debug_called(4);
@@ -995,7 +1052,7 @@ twe_reset(struct twe_softc *sc)
     /*
      * Sleep for a short period to allow AENs to be signalled.
      */
-    tsleep(sc, 0, "twereset", hz);
+    lksleep(sc, &sc->twe_io_lock, 0, "twereset", hz);
 
     /*
      * Disable interrupts from the controller, and mask any accidental entry
@@ -1003,7 +1060,6 @@ twe_reset(struct twe_softc *sc)
      */
     twe_printf(sc, "controller reset in progress...\n");
     twe_disable_interrupts(sc);
-    crit_enter();
 
     /*
      * Try to soft-reset the controller.
@@ -1035,11 +1091,9 @@ twe_reset(struct twe_softc *sc)
      * Kick the controller to start things going again, then re-enable interrupts.
      */
     twe_startio(sc);
-    twe_enable_interrupts(sc);
     twe_printf(sc, "controller reset done, %d commands restarted\n", i);
 
 out:
-    crit_exit();
     twe_enable_interrupts(sc);
 }
 
@@ -1059,11 +1113,13 @@ twe_start(struct twe_request *tr)
 {
     struct twe_softc   *sc = tr->tr_sc;
     TWE_Command                *cmd;
-    int                        i, done;
+    int                        i;
     u_int32_t          status_reg;
 
     debug_called(4);
 
+    twe_lockassert(&sc->twe_io_lock);
+
     /* mark the command as currently being processed */
     tr->tr_status = TWE_CMD_BUSY;
     cmd = TWE_FIND_COMMAND(tr);
@@ -1074,8 +1130,7 @@ twe_start(struct twe_request *tr)
      * XXX it might be more efficient to return EBUSY immediately
      *     and let the command be rescheduled.
      */
-    for (i = 100000, done = 0; (i > 0) && !done; i--) {
-       crit_enter();
+    for (i = 100000; (i > 0); i--) {
        
        /* check to see if we can post a command */
        status_reg = TWE_STATUS(sc);
@@ -1085,7 +1140,7 @@ twe_start(struct twe_request *tr)
            twe_enqueue_busy(tr);
 
            TWE_COMMAND_QUEUE(sc, TWE_FIND_COMMANDPHYS(tr));
-           done = 1;
+
            /* move command to work queue */
 #ifdef TWE_DEBUG
            if (tr->tr_complete != NULL) {
@@ -1096,14 +1151,11 @@ twe_start(struct twe_request *tr)
                debug(3, "queued request %d for polling caller", cmd->generic.request_id);
            }
 #endif
-       }
-       crit_exit();    /* drop critical section to allow completion interrupts */
+           return(0);
+       } else if (!(status_reg & TWE_STATUS_RESPONSE_QUEUE_EMPTY) && i > 1)
+           twe_done(sc, 0);
     }
 
-    /* command is enqueued */
-    if (done)
-       return(0);
-
     /* 
      * We couldn't get the controller to take the command; try submitting it again later.
      * This should only happen if something is wrong with the controller, or if we have
@@ -1119,7 +1171,7 @@ twe_start(struct twe_request *tr)
  * Can be called at any interrupt level, with or without interrupts enabled.
  */
 static void
-twe_done(struct twe_softc *sc)
+twe_done(struct twe_softc *sc, int startio)
 {
     TWE_Response_Queue rq;
     TWE_Command                *cmd;
@@ -1131,7 +1183,6 @@ twe_done(struct twe_softc *sc)
 
     /* loop collecting completed commands */
     found = 0;
-    crit_enter();
     for (;;) {
        status_reg = TWE_STATUS(sc);
        twe_check_bits(sc, status_reg);         /* XXX should this fail? */
@@ -1154,10 +1205,9 @@ twe_done(struct twe_softc *sc)
            break;                                      /* no response ready */
        }
     }
-    crit_exit();
 
     /* if we've completed any commands, try posting some more */
-    if (found)
+    if (found && startio)
        twe_startio(sc);
 
     /* handle completion and timeouts */
@@ -1258,6 +1308,7 @@ twe_soft_reset(struct twe_softc *sc)
 
     debug_called(2);
 
+    twe_lockassert(&sc->twe_io_lock);
     TWE_SOFT_RESET(sc);
 
     if (twe_wait_status(sc, TWE_STATUS_ATTENTION_INTERRUPT, 30)) {
@@ -1395,6 +1446,7 @@ twe_drain_aen_queue(struct twe_softc *sc)
 {
     u_int16_t  aen;
 
+    twe_lockassert(&sc->twe_io_lock);
     for (;;) {
        if (twe_get_param_2(sc, TWE_PARAM_AEN, TWE_PARAM_AEN_UnitCode, &aen))
            return(1);
@@ -1420,10 +1472,10 @@ twe_enqueue_aen(struct twe_softc *sc, u_int16_t aen)
 
     debug_called(4);
 
+    twe_lockassert(&sc->twe_io_lock);
     if ((msg = twe_format_aen(sc, aen)) != NULL)
        twe_printf(sc, "AEN: <%s>\n", msg);
 
-    crit_enter();
     /* enqueue the AEN */
     next = ((sc->twe_aen_head + 1) % TWE_Q_LENGTH);
     nextnext = ((sc->twe_aen_head + 2) % TWE_Q_LENGTH);
@@ -1446,7 +1498,6 @@ twe_enqueue_aen(struct twe_softc *sc, u_int16_t aen)
        sc->twe_wait_aen = -1;
        wakeup(&sc->twe_wait_aen);
     }
-    crit_exit();
 }
 
 /********************************************************************************
@@ -1461,6 +1512,7 @@ twe_dequeue_aen(struct twe_softc *sc)
     
     debug_called(4);
 
+    twe_lockassert(&sc->twe_io_lock);
     if (sc->twe_aen_tail == sc->twe_aen_head) {
        result = TWE_AEN_QUEUE_EMPTY;
     } else {
@@ -1481,12 +1533,10 @@ twe_find_aen(struct twe_softc *sc, u_int16_t aen)
     int                i, missing;
 
     missing = 1;
-    crit_enter();
     for (i = sc->twe_aen_tail; (i != sc->twe_aen_head) && missing; i = (i + 1) % TWE_Q_LENGTH) {
        if (sc->twe_aen_queue[i] == aen)
            missing = 0;
     }
-    crit_exit();
     return(missing);
 }
 
@@ -1510,15 +1560,13 @@ twe_wait_aen(struct twe_softc *sc, int aen, int timeout)
     expiry = time_second + timeout;
     found = 0;
 
-    crit_enter();
     sc->twe_wait_aen = aen;
     do {
        twe_fetch_aen(sc);
-       tsleep(&sc->twe_wait_aen, PZERO, "twewaen", hz);
+       lksleep(&sc->twe_wait_aen, &sc->twe_io_lock, 0, "twewaen", hz);
        if (sc->twe_wait_aen == -1)
            found = 1;
     } while ((time_second <= expiry) && !found);
-    crit_exit();
     return(!found);
 }
 #endif
@@ -1540,6 +1588,8 @@ twe_get_request(struct twe_softc *sc, struct twe_request **tr)
     TWE_Command                *cmd;
     debug_called(4);
 
+    twe_lockassert(&sc->twe_io_lock);
+
     /* try to reuse an old buffer */
     *tr = twe_dequeue_free(sc);
 
@@ -1566,6 +1616,7 @@ twe_release_request(struct twe_request *tr)
 {
     debug_called(4);
 
+    twe_lockassert(&tr->tr_sc->twe_io_lock);
     if (tr->tr_private != NULL)
        twe_panic(tr->tr_sc, "tr_private != NULL");
     twe_enqueue_free(tr);
@@ -1590,6 +1641,8 @@ twe_describe_controller(struct twe_softc *sc)
 
     debug_called(2);
 
+    TWE_IO_LOCK(sc);
+
     /* get the port count */
     twe_get_param_1(sc, TWE_PARAM_CONTROLLER, TWE_PARAM_CONTROLLER_PortCount, &ports);
 
@@ -1640,6 +1693,7 @@ twe_describe_controller(struct twe_softc *sc)
        if (p[0])
            kfree(p[0], M_DEVBUF);
     }
+    TWE_IO_UNLOCK(sc);
 }
 
 /********************************************************************************
@@ -1721,7 +1775,6 @@ twe_check_bits(struct twe_softc *sc, u_int32_t status_reg)
 static char *
 twe_format_aen(struct twe_softc *sc, u_int16_t aen)
 {
-    static char        buf[80];
     device_t   child;
     char       *code, *msg;
 
@@ -1738,25 +1791,28 @@ twe_format_aen(struct twe_softc *sc, u_int16_t aen)
 
     case 'c':
        if ((child = sc->twe_drive[TWE_AEN_UNIT(aen)].td_disk) != NULL) {
-           ksprintf(buf, "twed%d: %s", device_get_unit(child), msg);
+           ksnprintf(sc->twe_aen_buf, sizeof(sc->twe_aen_buf), "twed%d: %s",
+               device_get_unit(child), msg);
        } else {
-           ksprintf(buf, "twe%d: %s for unknown unit %d", device_get_unit(sc->twe_dev),
-                   msg, TWE_AEN_UNIT(aen));
+           ksnprintf(sc->twe_aen_buf, sizeof(sc->twe_aen_buf),
+               "twe%d: %s for unknown unit %d", device_get_unit(sc->twe_dev),
+               msg, TWE_AEN_UNIT(aen));
        }
-       return(buf);
+       return(sc->twe_aen_buf);
 
     case 'p':
-       ksprintf(buf, "twe%d: port %d: %s", device_get_unit(sc->twe_dev), TWE_AEN_UNIT(aen),
-               msg);
-       return(buf);
+       ksnprintf(sc->twe_aen_buf, sizeof(sc->twe_aen_buf),
+           "twe%d: port %d: %s", device_get_unit(sc->twe_dev),
+           TWE_AEN_UNIT(aen), msg);
+       return(sc->twe_aen_buf);
 
        
     case 'x':
     default:
        break;
     }
-    ksprintf(buf, "unknown AEN 0x%x", aen);
-    return(buf);
+    ksnprintf(sc->twe_aen_buf, sizeof(sc->twe_aen_buf), "unknown AEN 0x%x", aen);
+    return(sc->twe_aen_buf);
 }
 
 /********************************************************************************
index 6ed0a20..16f931c 100644 (file)
@@ -26,7 +26,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/dev/twe/twe_compat.h,v 1.14 2005/05/29 04:42:26 nyan Exp $
+ * $FreeBSD: src/sys/dev/twe/twe_compat.h,v 1.17 2012/11/17 01:52:19 svnexp Exp $
  */
 /*
  * Portability and compatibility interfaces.
@@ -36,6 +36,7 @@
 #include <sys/systm.h>
 #include <sys/malloc.h>
 #include <sys/kernel.h>
+#include <sys/lock.h>
 #include <sys/sysctl.h>
 #include <sys/buf2.h>
 #include <sys/bus.h>
@@ -44,7 +45,6 @@
 #include <sys/stat.h>
 #include <sys/rman.h>
 #include <sys/devicestat.h>
-#include <sys/thread2.h>
 
 #include <bus/pci/pcireg.h>
 #include <bus/pci/pcivar.h>
 /* 
  * Wrappers for bus-space actions
  */
-#define TWE_CONTROL(sc, val)           bus_space_write_4((sc)->twe_btag, (sc)->twe_bhandle, 0x0, (u_int32_t)val)
-#define TWE_STATUS(sc)                 (u_int32_t)bus_space_read_4((sc)->twe_btag, (sc)->twe_bhandle, 0x4)
-#define TWE_COMMAND_QUEUE(sc, val)     bus_space_write_4((sc)->twe_btag, (sc)->twe_bhandle, 0x8, (u_int32_t)val)
-#define TWE_RESPONSE_QUEUE(sc)         bus_space_read_4((sc)->twe_btag, (sc)->twe_bhandle, 0xc)
+#define TWE_CONTROL(sc, val)           bus_write_4((sc)->twe_io, 0x0, (u_int32_t)val)
+#define TWE_STATUS(sc)                 (u_int32_t)bus_read_4((sc)->twe_io, 0x4)
+#define TWE_COMMAND_QUEUE(sc, val)     bus_write_4((sc)->twe_io, 0x8, (u_int32_t)val)
+#define TWE_RESPONSE_QUEUE(sc)         bus_read_4((sc)->twe_io, 0xc)
 
 /*
  * FreeBSD-specific softc elements
@@ -70,8 +70,6 @@
     device_t                   twe_dev;                /* bus device */                \
     cdev_t                     twe_dev_t;              /* control device */            \
     struct resource            *twe_io;                /* register interface window */ \
-    bus_space_handle_t         twe_bhandle;            /* bus space handle */          \
-    bus_space_tag_t            twe_btag;               /* bus space tag */             \
     bus_dma_tag_t              twe_parent_dmat;        /* parent DMA tag */            \
     bus_dma_tag_t              twe_buffer_dmat;        /* data buffer DMA tag */       \
     bus_dma_tag_t              twe_cmd_dmat;           /* command buffer DMA tag */    \
@@ -83,7 +81,9 @@
     void                       *twe_immediate;         /* immediate commands */        \
     bus_dmamap_t               twe_immediate_map;                                      \
     struct sysctl_ctx_list     sysctl_ctx;                                             \
-    struct sysctl_oid          *sysctl_tree;
+    struct sysctl_oid          *sysctl_tree;                                           \
+    struct lock                        twe_io_lock;                                            \
+    struct lock                        twe_config_lock;
 
 /*
  * FreeBSD-specific request elements
 #define twe_printf(sc, fmt, args...)   device_printf(sc->twe_dev, fmt , ##args)
 #define twed_printf(twed, fmt, args...)        device_printf(twed->twed_dev, fmt , ##args)
 
-typedef struct bio                     twe_bio;
-typedef struct bio_queue_head          twe_bioq;
+#define        TWE_IO_LOCK(sc)                 lockmgr(&(sc)->twe_io_lock, LK_EXCLUSIVE)
+#define        TWE_IO_UNLOCK(sc)               lockmgr(&(sc)->twe_io_lock, LK_RELEASE)
+#define        TWE_CONFIG_LOCK(sc)             lockmgr(&(sc)->twe_config_lock, LK_EXCLUSIVE)
+#define        TWE_CONFIG_UNLOCK(sc)           lockmgr(&(sc)->twe_config_lock, LK_RELEASE)
+#define        TWE_CONFIG_ASSERT_LOCKED(sc)    KKASSERT(lockowned(&(sc)->twe_config_lock))
+
+/*
+ * XXX
+ *
+ * Mimics FreeBSD's mtx_assert() behavior.
+ * We might want a global lockassert() function in the future.
+ */
+static __inline void
+twe_lockassert(struct lock *lockp)
+{
+       if (panicstr == NULL && !dumping)
+               KKASSERT(lockstatus(lockp, curthread) != 0);
+}
index bea43f4..acf4bde 100644 (file)
@@ -26,7 +26,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/dev/twe/twe_freebsd.c,v 1.48 2009/12/25 17:34:43 mav Exp $
+ * $FreeBSD: src/sys/dev/twe/twe_freebsd.c,v 1.54 2012/11/17 01:52:19 svnexp Exp $
  */
 
 /*
@@ -39,6 +39,7 @@
 #include <dev/raid/twe/twevar.h>
 #include <dev/raid/twe/twe_tables.h>
 #include <sys/dtype.h>
+#include <sys/mplock2.h>
 
 #include <vm/vm.h>
 
@@ -68,7 +69,7 @@ static        d_close_t               twe_close;
 static d_ioctl_t               twe_ioctl_wrapper;
 
 static struct dev_ops twe_ops = {
-       { "twe", 0, 0 },
+       { "twe", 0, D_MPSAFE },
        .d_open =       twe_open,
        .d_close =      twe_close,
        .d_ioctl =      twe_ioctl_wrapper,
@@ -83,7 +84,13 @@ twe_open(struct dev_open_args *ap)
     cdev_t                     dev = ap->a_head.a_dev;
     struct twe_softc           *sc = (struct twe_softc *)dev->si_drv1;
 
+    TWE_IO_LOCK(sc);
+    if (sc->twe_state & TWE_STATE_DETACHING) {
+       TWE_IO_UNLOCK(sc);
+       return (ENXIO);
+    }
     sc->twe_state |= TWE_STATE_OPEN;
+    TWE_IO_UNLOCK(sc);
     return(0);
 }
 
@@ -96,7 +103,9 @@ twe_close(struct dev_close_args *ap)
     cdev_t                     dev = ap->a_head.a_dev;
     struct twe_softc           *sc = (struct twe_softc *)dev->si_drv1;
 
+    TWE_IO_LOCK(sc);
     sc->twe_state &= ~TWE_STATE_OPEN;
+    TWE_IO_UNLOCK(sc);
     return (0);
 }
 
@@ -139,8 +148,6 @@ static device_method_t twe_methods[] = {
     DEVMETHOD(device_suspend,  twe_suspend),
     DEVMETHOD(device_resume,   twe_resume),
 
-    DEVMETHOD(bus_print_child, bus_generic_print_child),
-    DEVMETHOD(bus_driver_added,        bus_generic_driver_added),
     { 0, 0 }
 };
 
@@ -178,7 +185,6 @@ twe_attach(device_t dev)
 {
     struct twe_softc   *sc;
     int                        rid, error;
-    u_int32_t          command;
 
     debug_called(4);
 
@@ -187,6 +193,8 @@ twe_attach(device_t dev)
      */
     sc = device_get_softc(dev);
     sc->twe_dev = dev;
+    lockinit(&sc->twe_io_lock, "twe I/O", 0, LK_CANRECURSE);
+    lockinit(&sc->twe_config_lock, "twe config", 0, LK_CANRECURSE);
 
     sysctl_ctx_init(&sc->sysctl_ctx);
     sc->sysctl_tree = SYSCTL_ADD_NODE(&sc->sysctl_ctx,
@@ -201,18 +209,9 @@ twe_attach(device_t dev)
        "TWE driver version");
 
     /*
-     * Make sure we are going to be able to talk to this board.
-     */
-    command = pci_read_config(dev, PCIR_COMMAND, 2);
-    if ((command & PCIM_CMD_PORTEN) == 0) {
-       twe_printf(sc, "register window not available\n");
-       return(ENXIO);
-    }
-    /*
      * Force the busmaster enable bit on, in case the BIOS forgot.
      */
-    command |= PCIM_CMD_BUSMASTEREN;
-    pci_write_config(dev, PCIR_COMMAND, command, 2);
+    pci_enable_busmaster(dev);
 
     /*
      * Allocate the PCI register window.
@@ -224,8 +223,6 @@ twe_attach(device_t dev)
        twe_free(sc);
        return(ENXIO);
     }
-    sc->twe_btag = rman_get_bustag(sc->twe_io);
-    sc->twe_bhandle = rman_get_bushandle(sc->twe_io);
 
     /*
      * Allocate the parent bus DMA tag appropriate for PCI.
@@ -254,7 +251,7 @@ twe_attach(device_t dev)
        twe_free(sc);
        return(ENXIO);
     }
-    if (bus_setup_intr(sc->twe_dev, sc->twe_irq, 0,
+    if (bus_setup_intr(sc->twe_dev, sc->twe_irq, INTR_MPSAFE,
                        twe_pci_intr, sc, &sc->twe_intr, NULL)) {
        twe_printf(sc, "can't set up interrupt\n");
        twe_free(sc);
@@ -427,6 +424,8 @@ twe_free(struct twe_softc *sc)
     dev_ops_remove_minor(&twe_ops, device_get_unit(sc->twe_dev));
 
     sysctl_ctx_free(&sc->sysctl_ctx);
+    lockuninit(&sc->twe_config_lock);
+    lockuninit(&sc->twe_io_lock);
 }
 
 /********************************************************************************
@@ -436,27 +435,30 @@ static int
 twe_detach(device_t dev)
 {
     struct twe_softc   *sc = device_get_softc(dev);
-    int                        error;
 
     debug_called(4);
 
-    error = EBUSY;
-    crit_enter();
-    if (sc->twe_state & TWE_STATE_OPEN)
-       goto out;
+    TWE_IO_LOCK(sc);
+    if (sc->twe_state & TWE_STATE_OPEN) {
+       TWE_IO_UNLOCK(sc);
+       return (EBUSY);
+    }
+    sc->twe_state |= TWE_STATE_DETACHING;
+    TWE_IO_UNLOCK(sc);
 
     /* 
      * Shut the controller down.
      */
-    if (twe_shutdown(dev))
-       goto out;
+    if (twe_shutdown(dev)) {
+       TWE_IO_LOCK(sc);
+       sc->twe_state &= ~TWE_STATE_DETACHING;
+       TWE_IO_UNLOCK(sc);
+       return (EBUSY);
+    }
 
     twe_free(sc);
 
-    error = 0;
- out:
-    crit_exit();
-    return(error);
+    return(0);
 }
 
 /********************************************************************************
@@ -473,26 +475,28 @@ twe_shutdown(device_t dev)
 
     debug_called(4);
 
-    crit_enter();
-
     /* 
      * Delete all our child devices.
      */
+    TWE_CONFIG_LOCK(sc);
     for (i = 0; i < TWE_MAX_UNITS; i++) {
        if (sc->twe_drive[i].td_disk != 0) {
-           if ((error = twe_detach_drive(sc, i)) != 0)
-               goto out;
+           if ((error = twe_detach_drive(sc, i)) != 0) {
+               TWE_CONFIG_UNLOCK(sc);
+               return (error);
+           }
        }
     }
+    TWE_CONFIG_UNLOCK(sc);
 
     /*
      * Bring the controller down.
      */
+    TWE_IO_LOCK(sc);
     twe_deinit(sc);
+    TWE_IO_UNLOCK(sc);
 
-out:
-    crit_exit();
-    return(error);
+    return(0);
 }
 
 /********************************************************************************
@@ -505,8 +509,9 @@ twe_suspend(device_t dev)
 
     debug_called(4);
 
-    crit_enter();
+    TWE_IO_LOCK(sc);
     sc->twe_state |= TWE_STATE_SUSPEND;
+    TWE_IO_UNLOCK(sc);
     
     twe_disable_interrupts(sc);
     crit_exit();
@@ -524,8 +529,10 @@ twe_resume(device_t dev)
 
     debug_called(4);
 
+    TWE_IO_LOCK(sc);
     sc->twe_state &= ~TWE_STATE_SUSPEND;
     twe_enable_interrupts(sc);
+    TWE_IO_UNLOCK(sc);
 
     return(0);
 }
@@ -537,7 +544,11 @@ twe_resume(device_t dev)
 static void
 twe_pci_intr(void *arg)
 {
-    twe_intr((struct twe_softc *)arg);
+    struct twe_softc *sc = arg;
+
+    TWE_IO_LOCK(sc);
+    twe_intr(sc);
+    TWE_IO_UNLOCK(sc);
 }
 
 /********************************************************************************
@@ -566,8 +577,10 @@ twe_attach_drive(struct twe_softc *sc, struct twe_drive *dr)
     char       buf[80];
     int                error;
 
+    get_mplock();
     dr->td_disk =  device_add_child(sc->twe_dev, NULL, -1);
     if (dr->td_disk == NULL) {
+       rel_mplock();
        twe_printf(sc, "Cannot add unit\n");
        return (EIO);
     }
@@ -583,7 +596,9 @@ twe_attach_drive(struct twe_softc *sc, struct twe_drive *dr)
            twe_describe_code(twe_table_unitstate, dr->td_state & TWE_PARAM_UNITSTATUS_MASK));
     device_set_desc_copy(dr->td_disk, buf);
 
-    if ((error = bus_generic_attach(sc->twe_dev)) != 0) {
+    error = device_probe_and_attach(dr->td_disk);
+    rel_mplock();
+    if (error != 0) {
        twe_printf(sc, "Cannot attach unit to controller. error = %d\n", error);
        return (EIO);
     }
@@ -600,7 +615,11 @@ twe_detach_drive(struct twe_softc *sc, int unit)
 {
     int error = 0;
 
-    if ((error = device_delete_child(sc->twe_dev, sc->twe_drive[unit].td_disk)) != 0) {
+    TWE_CONFIG_ASSERT_LOCKED(sc);
+    get_mplock();
+    error = device_delete_child(sc->twe_dev, sc->twe_drive[unit].td_disk);
+    rel_mplock();
+    if (error != 0) {
        twe_printf(sc, "failed to delete unit %d\n", unit);
        return(error);
     }
@@ -666,7 +685,7 @@ static      d_strategy_t    twed_strategy;
 static d_dump_t        twed_dump;
 
 static struct dev_ops twed_ops = {
-       { "twed", 0, D_DISK },
+       { "twed", 0, D_DISK | D_MPSAFE},
        .d_open =       twed_open,
        .d_close =      twed_close,
        .d_read =       physread,
@@ -749,10 +768,12 @@ twed_strategy(struct dev_strategy_args *ap)
     devstat_start_transaction(&sc->twed_stats);
 
     /* queue the bio on the controller */
+    TWE_IO_LOCK(sc->twed_controller);
     twe_enqueue_bio(sc->twed_controller, bio);
 
     /* poke the controller to start I/O */
     twe_startio(sc->twed_controller);
+    TWE_IO_UNLOCK(sc->twed_controller);
     return(0);
 }
 
@@ -794,7 +815,7 @@ twed_intr(struct bio *bio)
     debug_called(4);
 
     /* if no error, transfer completed */
-    if ((bp->b_flags & B_ERROR) == 0)
+    if (!(bp->b_flags & B_ERROR))
        bp->b_resid = 0;
     devstat_end_transaction_buf(&sc->twed_stats, bp);
     biodone(bio);
@@ -899,13 +920,13 @@ twed_detach(device_t dev)
 /********************************************************************************
  * Allocate a command buffer
  */
-MALLOC_DEFINE(TWE_MALLOC_CLASS, "twe_commands", "twe commands");
+static MALLOC_DEFINE(TWE_MALLOC_CLASS, "twe_commands", "twe commands");
 
 struct twe_request *
 twe_allocate_request(struct twe_softc *sc, int tag)
 {
     struct twe_request *tr;
-       int aligned_size;
+    int aligned_size;
 
     /*
      * TWE requires requests to be 512-byte aligned.  Depend on malloc()
@@ -914,8 +935,8 @@ twe_allocate_request(struct twe_softc *sc, int tag)
      * allocator only guarentees same-size alignment for power-of-2 requests.
      */
     aligned_size = (sizeof(struct twe_request) + TWE_ALIGNMASK) &
-           ~TWE_ALIGNMASK;
-    tr = kmalloc(aligned_size, TWE_MALLOC_CLASS, M_INTWAIT|M_ZERO);
+       ~TWE_ALIGNMASK;
+    tr = kmalloc(aligned_size, TWE_MALLOC_CLASS, M_INTWAIT | M_ZERO);
     tr->tr_sc = sc;
     tr->tr_tag = tag;
     if (bus_dmamap_create(sc->twe_buffer_dmat, 0, &tr->tr_dmamap)) {
@@ -1077,6 +1098,7 @@ twe_map_request(struct twe_request *tr)
 
     debug_called(4);
 
+    twe_lockassert(&sc->twe_io_lock);
     if (sc->twe_state & (TWE_STATE_CTLR_BUSY | TWE_STATE_FRZN)) {
        twe_requeue_ready(tr);
        return (EBUSY);
@@ -1196,10 +1218,8 @@ twe_report(void)
     struct twe_softc   *sc;
     int                        i;
 
-    crit_enter();
     for (i = 0; (sc = devclass_get_softc(twe_devclass, i)) != NULL; i++)
        twe_print_controller(sc);
     kprintf("twed: total bio count in %u  out %u\n", twed_bio_in, twed_bio_out);
-    crit_exit();
 }
 #endif
index c8871a2..40ef35e 100644 (file)
@@ -26,7 +26,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *     $FreeBSD: src/sys/dev/twe/twe_tables.h,v 1.4 2003/12/02 07:57:20 ps Exp $
+ *     $FreeBSD: src/sys/dev/twe/twe_tables.h,v 1.5 2012/11/17 01:52:19 svnexp Exp $
  */
 
 /*
index aa69c72..7e75b02 100644 (file)
@@ -26,7 +26,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *     $FreeBSD: src/sys/dev/twe/tweio.h,v 1.5 2005/02/17 19:05:42 vkashyap Exp $
+ *     $FreeBSD: src/sys/dev/twe/tweio.h,v 1.6 2012/11/17 01:52:19 svnexp Exp $
  */
 
 #include <sys/ioccom.h>
index 93ca338..58828f6 100644 (file)
@@ -26,7 +26,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *      $FreeBSD: src/sys/dev/twe/twereg.h,v 1.11 2004/05/12 04:10:37 vkashyap Exp $
+ *      $FreeBSD: src/sys/dev/twe/twereg.h,v 1.12 2012/11/17 01:52:19 svnexp Exp $
  */
 
 /* 
index 25ab133..6f77dac 100644 (file)
@@ -24,7 +24,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *     $FreeBSD: src/sys/dev/twe/twevar.h,v 1.15 2009/12/25 17:34:43 mav Exp $
+ *     $FreeBSD: src/sys/dev/twe/twevar.h,v 1.19 2012/11/17 01:52:19 svnexp Exp $
  */
 
 #define TWE_DRIVER_VERSION_STRING      "1.50.01.002"
@@ -128,7 +128,7 @@ struct twe_softc
 {
     /* controller queues and arrays */
     TAILQ_HEAD(, twe_request)  twe_free;                       /* command structures available for reuse */
-    twe_bioq                   twe_bioq;                       /* outstanding I/O operations */
+    struct bio_queue_head      twe_bioq;                       /* outstanding I/O operations */
     TAILQ_HEAD(, twe_request)  twe_ready;                      /* requests ready for the controller */
     TAILQ_HEAD(, twe_request)  twe_busy;                       /* requests busy in the controller */
     TAILQ_HEAD(, twe_request)  twe_complete;                   /* active commands (busy or waiting for completion) */
@@ -139,6 +139,7 @@ struct twe_softc
     u_int16_t          twe_aen_queue[TWE_Q_LENGTH];    /* AENs queued for userland tool(s) */
     int                        twe_aen_head, twe_aen_tail;     /* ringbuffer pointers for AEN queue */
     int                        twe_wait_aen;                   /* wait-for-aen notification */
+    char               twe_aen_buf[80];                /* AEN format buffer */
 
     /* controller status */
     int                        twe_state;
@@ -148,6 +149,7 @@ struct twe_softc
 #define TWE_STATE_SUSPEND      (1<<3)  /* controller is suspended */
 #define TWE_STATE_FRZN         (1<<4)  /* got EINPROGRESS */
 #define TWE_STATE_CTLR_BUSY    (1<<5)  /* controller cmd queue full */
+#define        TWE_STATE_DETACHING     (1<<6)  /* controller is being shut down */
     int                        twe_host_id;
     struct twe_qstat   twe_qstat[TWEQ_COUNT];  /* queue statistics */
 
@@ -178,7 +180,7 @@ extern int  twe_detach_drive(struct twe_softc *sc,
                                         int unit);             /* detach drive */
 extern void    twe_clear_pci_parity_error(struct twe_softc *sc);
 extern void    twe_clear_pci_abort(struct twe_softc *sc);
-extern void    twed_intr(twe_bio *bp);                         /* return bio from core */
+extern void    twed_intr(struct bio *bp);                              /* return bio from core */
 extern struct twe_request *twe_allocate_request(struct twe_softc *sc, int tag);        /* allocate request structure */
 extern void    twe_free_request(struct twe_request *tr);       /* free request structure */
 extern int     twe_map_request(struct twe_request *tr);        /* make request visible to controller, do s/g */
@@ -223,39 +225,31 @@ twe_initq_ ## name (struct twe_softc *sc)                         \
 static __inline void                                                   \
 twe_enqueue_ ## name (struct twe_request *tr)                          \
 {                                                                      \
-    crit_enter();                                                      \
     TAILQ_INSERT_TAIL(&tr->tr_sc->twe_ ## name, tr, tr_link);          \
     TWEQ_ADD(tr->tr_sc, index);                                                \
-    crit_exit();                                                       \
 }                                                                      \
 static __inline void                                                   \
 twe_requeue_ ## name (struct twe_request *tr)                          \
 {                                                                      \
-    crit_enter();                                                      \
     TAILQ_INSERT_HEAD(&tr->tr_sc->twe_ ## name, tr, tr_link);          \
     TWEQ_ADD(tr->tr_sc, index);                                                \
-    crit_exit();                                                       \
 }                                                                      \
 static __inline struct twe_request *                                   \
 twe_dequeue_ ## name (struct twe_softc *sc)                            \
 {                                                                      \
     struct twe_request *tr;                                            \
                                                                        \
-    crit_enter();                                                      \
     if ((tr = TAILQ_FIRST(&sc->twe_ ## name)) != NULL) {               \
        TAILQ_REMOVE(&sc->twe_ ## name, tr, tr_link);                   \
        TWEQ_REMOVE(sc, index);                                         \
     }                                                                  \
-    crit_exit();                                                       \
     return(tr);                                                                \
 }                                                                      \
 static __inline void                                                   \
 twe_remove_ ## name (struct twe_request *tr)                           \
 {                                                                      \
-    crit_enter();                                                      \
     TAILQ_REMOVE(&tr->tr_sc->twe_ ## name, tr, tr_link);               \
     TWEQ_REMOVE(tr->tr_sc, index);                                     \
-    crit_exit();                                                       \
 }
 
 TWEQ_REQUEST_QUEUE(free, TWEQ_FREE)
@@ -276,11 +270,9 @@ twe_initq_bio(struct twe_softc *sc)
 static __inline void
 twe_enqueue_bio(struct twe_softc *sc, struct bio *bio)
 {
-    crit_enter();
     bioqdisksort(&sc->twe_bioq, bio);
     /* bioq_insert_tail(&sc->twe_bioq, bio); */
     TWEQ_ADD(sc, TWEQ_BIO);
-    crit_exit();
 }
 
 static __inline
@@ -289,11 +281,9 @@ twe_dequeue_bio(struct twe_softc *sc)
 {
     struct bio *bio;
 
-    crit_enter();
     if ((bio = bioq_first(&sc->twe_bioq)) != NULL) {
        bioq_remove(&sc->twe_bioq, bio);
        TWEQ_REMOVE(sc, TWEQ_BIO);
     }
-    crit_exit();
     return(bio);
 }