--- //depot/vendor/freebsd/src/sys/dev/mly/mly.c +++ //depot/user/jhb/cleanup/sys/dev/mly/mly.c @@ -88,7 +88,8 @@ static int mly_immediate_command(struct mly_command *mc); static int mly_start(struct mly_command *mc); static void mly_done(struct mly_softc *sc); -static void mly_complete(void *context, int pending); +static void mly_complete(struct mly_softc *sc); +static void mly_complete_handler(void *context, int pending); static int mly_alloc_command(struct mly_softc *sc, struct mly_command **mcp); static void mly_release_command(struct mly_command *mc); @@ -116,7 +117,7 @@ static void mly_print_command(struct mly_command *mc); static void mly_print_packet(struct mly_command *mc); static void mly_panic(struct mly_softc *sc, char *reason); -static int mly_timeout(struct mly_softc *sc); +static void mly_timeout(void *arg); #endif void mly_print_controller(int controller); @@ -151,7 +152,6 @@ static struct cdevsw mly_cdevsw = { .d_version = D_VERSION, - .d_flags = D_NEEDGIANT, .d_open = mly_user_open, .d_close = mly_user_close, .d_ioctl = mly_user_ioctl, @@ -216,8 +216,11 @@ debug_called(1); sc->mly_dev = dev; + mtx_init(&sc->mly_lock, "mly", NULL, MTX_DEF); + callout_init_mtx(&sc->mly_periodic, &sc->mly_lock, 0); #ifdef MLY_DEBUG + callout_init_mtx(&sc->mly_timeout, &sc->mly_lock, 0); if (device_get_unit(sc->mly_dev) == 0) mly_softc0 = sc; #endif @@ -238,7 +241,7 @@ /* * Initialise command-completion task. */ - TASK_INIT(&sc->mly_task_complete, 0, mly_complete, sc); + TASK_INIT(&sc->mly_task_complete, 0, mly_complete_handler, sc); /* disable interrupts before we start talking to the controller */ MLY_MASK_INTERRUPTS(sc); @@ -260,7 +263,10 @@ /* * Obtain controller feature information */ - if ((error = mly_get_controllerinfo(sc))) + MLY_LOCK(sc); + error = mly_get_controllerinfo(sc); + MLY_UNLOCK(sc); + if (error) goto out; /* @@ -274,13 +280,16 @@ * Get the current event counter for health purposes, populate the initial * health status buffer. */ - if ((error = mly_get_eventstatus(sc))) - goto out; + MLY_LOCK(sc); + error = mly_get_eventstatus(sc); /* * Enable memory-mailbox mode. */ - if ((error = mly_enable_mmbox(sc))) + if (error == 0) + error = mly_enable_mmbox(sc); + MLY_UNLOCK(sc); + if (error) goto out; /* @@ -297,6 +306,7 @@ /* * Mark all attached devices for rescan. */ + MLY_LOCK(sc); mly_scan_devices(sc); /* @@ -305,6 +315,7 @@ * the SCSI subsystem gets to us, courtesy of the "SCSI settling delay". */ mly_periodic((void *)sc); + MLY_UNLOCK(sc); /* * Create the control device. @@ -317,7 +328,7 @@ MLY_UNMASK_INTERRUPTS(sc); #ifdef MLY_DEBUG - timeout((timeout_t *)mly_timeout, sc, MLY_CMD_TIMEOUT * hz); + callout_reset(&sc->mly_timeout, MLY_CMD_TIMEOUT * hz, mly_timeout, sc); #endif out: @@ -353,8 +364,6 @@ mly_printf(sc, "can't allocate register window\n"); goto fail; } - sc->mly_btag = rman_get_bustag(sc->mly_regs_resource); - sc->mly_bhandle = rman_get_bushandle(sc->mly_regs_resource); /* * Allocate and connect our interrupt. @@ -365,7 +374,7 @@ mly_printf(sc, "can't allocate interrupt\n"); goto fail; } - if (bus_setup_intr(sc->mly_dev, sc->mly_irq, INTR_TYPE_CAM | INTR_ENTROPY, NULL, mly_intr, sc, &sc->mly_intr)) { + if (bus_setup_intr(sc->mly_dev, sc->mly_irq, INTR_TYPE_CAM | INTR_ENTROPY | INTR_MPSAFE, NULL, mly_intr, sc, &sc->mly_intr)) { mly_printf(sc, "can't set up interrupt\n"); goto fail; } @@ -405,7 +414,7 @@ BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */ 0, /* flags */ busdma_lock_mutex, /* lockfunc */ - &Giant, /* lockarg */ + &sc->mly_lock, /* lockarg */ &sc->mly_buffer_dmat)) { mly_printf(sc, "can't allocate buffer DMA tag\n"); goto fail; @@ -511,18 +520,25 @@ struct mly_softc *sc = device_get_softc(dev); debug_called(1); - - if (sc->mly_state & MLY_STATE_OPEN) + + MLY_LOCK(sc); + if (sc->mly_state & MLY_STATE_OPEN) { + MLY_UNLOCK(sc); return(EBUSY); + } /* kill the periodic event */ - untimeout(mly_periodic, sc, sc->mly_periodic); + callout_stop(&sc->mly_periodic); +#ifdef MLY_DEBUG + callout_stop(&sc->mly_timeout); +#endif /* flush controller */ mly_printf(sc, "flushing cache..."); printf("%s\n", mly_flush(sc) ? "failed" : "done"); MLY_MASK_INTERRUPTS(sc); + MLY_UNLOCK(sc); return(0); } @@ -538,7 +554,9 @@ debug_called(2); + MLY_LOCK(sc); mly_done(sc); + MLY_UNLOCK(sc); }; /******************************************************************************** @@ -676,6 +694,13 @@ /* Remove the management device */ destroy_dev(sc->mly_dev_t); + if (sc->mly_intr) + bus_teardown_intr(sc->mly_dev, sc->mly_irq, sc->mly_intr); + callout_drain(&sc->mly_periodic); +#ifdef MLY_DEBUG + callout_drain(&sc->mly_timeout); +#endif + /* detach from CAM */ mly_cam_detach(sc); @@ -711,8 +736,6 @@ bus_dma_tag_destroy(sc->mly_mmbox_dmat); /* disconnect the interrupt handler */ - if (sc->mly_intr) - bus_teardown_intr(sc->mly_dev, sc->mly_irq, sc->mly_intr); if (sc->mly_irq != NULL) bus_release_resource(sc->mly_dev, SYS_RES_IRQ, sc->mly_irq_rid, sc->mly_irq); @@ -723,6 +746,8 @@ /* release the register window mapping */ if (sc->mly_regs_resource != NULL) bus_release_resource(sc->mly_dev, SYS_RES_MEMORY, sc->mly_regs_rid, sc->mly_regs_resource); + + mtx_destroy(&sc->mly_lock); } /******************************************************************************** @@ -1086,6 +1111,7 @@ int error; debug_called(1); + MLY_ASSERT_LOCKED(sc); mc = NULL; if (mly_alloc_command(sc, &mc)) { @@ -1375,6 +1401,7 @@ int bus, target; debug_called(2); + MLY_ASSERT_LOCKED(sc); /* * Scan devices. @@ -1398,7 +1425,7 @@ mly_check_event(sc); /* reschedule ourselves */ - sc->mly_periodic = timeout(mly_periodic, sc, MLY_PERIODIC_INTERVAL * hz); + callout_schedule(&sc->mly_periodic, MLY_PERIODIC_INTERVAL * hz); } /******************************************************************************** @@ -1415,21 +1442,19 @@ mly_immediate_command(struct mly_command *mc) { struct mly_softc *sc = mc->mc_sc; - int error, s; + int error; debug_called(1); - /* spinning at splcam is ugly, but we're only used during controller init */ - s = splcam(); + MLY_ASSERT_LOCKED(sc); if ((error = mly_start(mc))) { - splx(s); return(error); } if (sc->mly_state & MLY_STATE_INTERRUPTS_ON) { /* sleep on the command */ while(!(mc->mc_flags & MLY_CMD_COMPLETE)) { - tsleep(mc, PRIBIO, "mlywait", 0); + mtx_sleep(mc, &sc->mly_lock, PRIBIO, "mlywait", 0); } } else { /* spin and collect status while we do */ @@ -1437,7 +1462,6 @@ mly_done(mc->mc_sc); } } - splx(s); return(0); } @@ -1453,9 +1477,9 @@ { struct mly_softc *sc = mc->mc_sc; union mly_command_packet *pkt; - int s; debug_called(2); + MLY_ASSERT_LOCKED(sc); /* * Set the command up for delivery to the controller. @@ -1467,8 +1491,6 @@ mc->mc_timestamp = time_second; #endif - s = splcam(); - /* * Do we have to use the hardware mailbox? */ @@ -1477,7 +1499,6 @@ * Check to see if the controller is ready for us. */ if (MLY_IDBR_TRUE(sc, MLY_HM_CMDSENT)) { - splx(s); return(EBUSY); } mc->mc_flags |= MLY_CMD_BUSY; @@ -1494,7 +1515,6 @@ /* check to see if the next index is free yet */ if (pkt->mmbox.flag != 0) { - splx(s); return(EBUSY); } mc->mc_flags |= MLY_CMD_BUSY; @@ -1502,13 +1522,11 @@ /* copy in new command */ bcopy(mc->mc_packet->mmbox.data, pkt->mmbox.data, sizeof(pkt->mmbox.data)); /* barrier to ensure completion of previous write before we write the flag */ - bus_space_barrier(sc->mly_btag, sc->mly_bhandle, 0, 0, - BUS_SPACE_BARRIER_WRITE); + bus_barrier(sc->mly_regs_resource, 0, 0, BUS_SPACE_BARRIER_WRITE); /* copy flag last */ pkt->mmbox.flag = mc->mc_packet->mmbox.flag; /* barrier to ensure completion of previous write before we notify the controller */ - bus_space_barrier(sc->mly_btag, sc->mly_bhandle, 0, 0, - BUS_SPACE_BARRIER_WRITE); + bus_barrier(sc->mly_regs_resource, 0, 0, BUS_SPACE_BARRIER_WRITE); /* signal controller, update index */ MLY_SET_REG(sc, sc->mly_idbr, MLY_AM_CMDSENT); @@ -1516,7 +1534,6 @@ } mly_enqueue_busy(mc); - splx(s); return(0); } @@ -1529,9 +1546,9 @@ struct mly_command *mc; union mly_status_packet *sp; u_int16_t slot; - int s, worked; + int worked; - s = splcam(); + MLY_ASSERT_LOCKED(sc); worked = 0; /* pick up hardware-mailbox commands */ @@ -1589,12 +1606,11 @@ MLY_SET_REG(sc, sc->mly_odbr, MLY_AM_STSREADY); } - splx(s); if (worked) { if (sc->mly_state & MLY_STATE_INTERRUPTS_ON) - taskqueue_enqueue(taskqueue_swi_giant, &sc->mly_task_complete); + taskqueue_enqueue(taskqueue_thread, &sc->mly_task_complete); else - mly_complete(sc, 0); + mly_complete(sc); } } @@ -1602,13 +1618,21 @@ * Process completed commands */ static void -mly_complete(void *context, int pending) +mly_complete_handler(void *context, int pending) { struct mly_softc *sc = (struct mly_softc *)context; + + MLY_LOCK(sc); + mly_complete(sc); + MLY_UNLOCK(sc); +} + +static void +mly_complete(struct mly_softc *sc) +{ struct mly_command *mc; void (* mc_complete)(struct mly_command *mc); - debug_called(2); /* @@ -1935,15 +1959,18 @@ if ((sc->mly_cam_sim[chn] = cam_sim_alloc(mly_cam_action, mly_cam_poll, "mly", sc, device_get_unit(sc->mly_dev), - &Giant, + &sc->mly_lock, sc->mly_controllerinfo->maximum_parallel_commands, 1, devq)) == NULL) { return(ENOMEM); } + MLY_LOCK(sc); if (xpt_bus_register(sc->mly_cam_sim[chn], sc->mly_dev, chn)) { + MLY_UNLOCK(sc); mly_printf(sc, "CAM XPT phsyical channel registration failed\n"); return(ENXIO); } + MLY_UNLOCK(sc); debug(1, "registered physical channel %d", chn); } } @@ -1955,15 +1982,18 @@ for (i = 0; i < sc->mly_controllerinfo->virtual_channels_present; i++, chn++) { if ((sc->mly_cam_sim[chn] = cam_sim_alloc(mly_cam_action, mly_cam_poll, "mly", sc, device_get_unit(sc->mly_dev), - &Giant, + &sc->mly_lock, sc->mly_controllerinfo->maximum_parallel_commands, 0, devq)) == NULL) { return(ENOMEM); } + MLY_LOCK(sc); if (xpt_bus_register(sc->mly_cam_sim[chn], sc->mly_dev, chn)) { + MLY_UNLOCK(sc); mly_printf(sc, "CAM XPT virtual channel registration failed\n"); return(ENXIO); } + MLY_UNLOCK(sc); debug(1, "registered virtual channel %d", chn); } @@ -1987,12 +2017,14 @@ debug_called(1); + MLY_LOCK(sc); for (i = 0; i < sc->mly_cam_channels; i++) { if (sc->mly_cam_sim[i] != NULL) { xpt_bus_deregister(cam_sim_path(sc->mly_cam_sim[i])); cam_sim_free(sc->mly_cam_sim[i], 0); } } + MLY_UNLOCK(sc); if (sc->mly_cam_devq != NULL) cam_simq_free(sc->mly_cam_devq); } @@ -2030,6 +2062,7 @@ struct mly_softc *sc = cam_sim_softc(sim); debug_called(2); + MLY_ASSERT_LOCKED(sc); switch (ccb->ccb_h.func_code) { @@ -2173,7 +2206,6 @@ struct mly_command_scsi_small *ss; int bus, target; int error; - int s; bus = cam_sim_bus(sim); target = csio->ccb_h.target_id; @@ -2220,11 +2252,9 @@ * Get a command, or push the ccb back to CAM and freeze the queue. */ if ((error = mly_alloc_command(sc, &mc))) { - s = splcam(); xpt_freeze_simq(sim, 1); csio->ccb_h.status |= CAM_REQUEUE_REQ; sc->mly_qfrzn_cnt++; - splx(s); return(error); } @@ -2270,11 +2300,9 @@ /* give the command to the controller */ if ((error = mly_start(mc))) { - s = splcam(); xpt_freeze_simq(sim, 1); csio->ccb_h.status |= CAM_REQUEUE_REQ; sc->mly_qfrzn_cnt++; - splx(s); return(error); } @@ -2306,7 +2334,6 @@ struct mly_btl *btl; u_int8_t cmd; int bus, target; - int s; debug_called(2); @@ -2359,12 +2386,10 @@ break; } - s = splcam(); if (sc->mly_qfrzn_cnt) { csio->ccb_h.status |= CAM_RELEASE_SIMQ; sc->mly_qfrzn_cnt--; } - splx(s); xpt_done((union ccb *)csio); mly_release_command(mc); @@ -2805,7 +2830,9 @@ { struct mly_softc *sc = dev->si_drv1; + MLY_LOCK(sc); sc->mly_state |= MLY_STATE_OPEN; + MLY_UNLOCK(sc); return(0); } @@ -2817,7 +2844,9 @@ { struct mly_softc *sc = dev->si_drv1; + MLY_LOCK(sc); sc->mly_state &= ~MLY_STATE_OPEN; + MLY_UNLOCK(sc); return (0); } @@ -2855,13 +2884,16 @@ mly_user_command(struct mly_softc *sc, struct mly_user_command *uc) { struct mly_command *mc; - int error, s; + int error; /* allocate a command */ + MLY_LOCK(sc); if (mly_alloc_command(sc, &mc)) { + MLY_UNLOCK(sc); error = ENOMEM; goto out; /* XXX Linux version will wait for a command */ } + MLY_UNLOCK(sc); /* handle data size/direction */ mc->mc_length = (uc->DataTransferLength >= 0) ? uc->DataTransferLength : -uc->DataTransferLength; @@ -2888,12 +2920,14 @@ mc->mc_complete = NULL; /* execute the command */ - if ((error = mly_start(mc)) != 0) + MLY_LOCK(sc); + if ((error = mly_start(mc)) != 0) { + MLY_UNLOCK(sc); goto out; - s = splcam(); + } while (!(mc->mc_flags & MLY_CMD_COMPLETE)) - tsleep(mc, PRIBIO, "mlyioctl", 0); - splx(s); + mtx_sleep(mc, &sc->mly_lock, PRIBIO, "mlyioctl", 0); + MLY_UNLOCK(sc); /* return the data to userspace */ if (uc->DataTransferLength > 0) @@ -2916,8 +2950,11 @@ out: if (mc->mc_data != NULL) free(mc->mc_data, M_DEVBUF); - if (mc != NULL) + if (mc != NULL) { + MLY_LOCK(sc); mly_release_command(mc); + MLY_UNLOCK(sc); + } return(error); } @@ -2931,32 +2968,36 @@ mly_user_health(struct mly_softc *sc, struct mly_user_health *uh) { struct mly_health_status mh; - int error, s; + int error; /* fetch the current health status from userspace */ if ((error = copyin(uh->HealthStatusBuffer, &mh, sizeof(mh))) != 0) return(error); /* spin waiting for a status update */ - s = splcam(); + MLY_LOCK(sc); error = EWOULDBLOCK; while ((error != 0) && (sc->mly_event_change == mh.change_counter)) - error = tsleep(&sc->mly_event_change, PRIBIO | PCATCH, "mlyhealth", 0); - splx(s); + error = mtx_sleep(&sc->mly_event_change, &sc->mly_lock, PRIBIO | PCATCH, + "mlyhealth", 0); + mh = sc->mly_mmbox->mmm_health.status; + MLY_UNLOCK(sc); - /* copy the controller's health status buffer out (there is a race here if it changes again) */ - error = copyout(&sc->mly_mmbox->mmm_health.status, uh->HealthStatusBuffer, - sizeof(uh->HealthStatusBuffer)); + /* copy the controller's health status buffer out */ + error = copyout(&mh, uh->HealthStatusBuffer, sizeof(mh)); return(error); } #ifdef MLY_DEBUG -static int -mly_timeout(struct mly_softc *sc) +static void +mly_timeout(void *arg) { + struct mly_softc *sc; struct mly_command *mc; int deadline; + sc = arg; + MLY_ASSERT_LOCKED(sc); deadline = time_second - MLY_CMD_TIMEOUT; TAILQ_FOREACH(mc, &sc->mly_busy, mc_link) { if ((mc->mc_timestamp < deadline)) { @@ -2966,8 +3007,6 @@ } } - timeout((timeout_t *)mly_timeout, sc, MLY_CMD_TIMEOUT * hz); - - return (0); + callout_reset(&sc->mly_timeout, MLY_CMD_TIMEOUT * hz, mly_timeout, sc); } #endif --- //depot/vendor/freebsd/src/sys/dev/mly/mlyvar.h +++ //depot/user/jhb/cleanup/sys/dev/mly/mlyvar.h @@ -59,10 +59,6 @@ # include -#ifndef INTR_ENTROPY -# define INTR_ENTROPY 0 -#endif - /******************************************************************************** ******************************************************************************** Driver Variable Definitions @@ -161,8 +157,6 @@ struct cdev *mly_dev_t; struct resource *mly_regs_resource; /* register interface window */ int mly_regs_rid; /* resource ID */ - bus_space_handle_t mly_bhandle; /* bus space handle */ - bus_space_tag_t mly_btag; /* bus space tag */ bus_dma_tag_t mly_parent_dmat; /* parent DMA tag */ bus_dma_tag_t mly_buffer_dmat; /* data buffer/command DMA tag */ struct resource *mly_irq; /* interrupt */ @@ -195,6 +189,7 @@ u_int32_t mly_mmbox_status_index; /* index we next expect status at */ /* controller features, limits and status */ + struct mtx mly_lock; int mly_state; #define MLY_STATE_OPEN (1<<1) #define MLY_STATE_INTERRUPTS_ON (1<<2) @@ -219,7 +214,7 @@ u_int32_t mly_event_change; /* event status change indicator */ u_int32_t mly_event_counter; /* next event for which we anticpiate status */ u_int32_t mly_event_waiting; /* next event the controller will post status for */ - struct callout_handle mly_periodic; /* periodic event handling */ + struct callout mly_periodic; /* periodic event handling */ /* CAM connection */ struct cam_devq *mly_cam_devq; /* CAM device queue */ @@ -230,29 +225,37 @@ /* command-completion task */ struct task mly_task_complete; /* deferred-completion task */ int mly_qfrzn_cnt; /* Track simq freezes */ + +#ifdef MLY_DEBUG + struct callout mly_timeout; +#endif }; +#define MLY_LOCK(sc) mtx_lock(&(sc)->mly_lock) +#define MLY_UNLOCK(sc) mtx_unlock(&(sc)->mly_lock) +#define MLY_ASSERT_LOCKED(sc) mtx_assert(&(sc)->mly_lock, MA_OWNED) + /* * Register access helpers. */ -#define MLY_SET_REG(sc, reg, val) bus_space_write_1(sc->mly_btag, sc->mly_bhandle, reg, val) -#define MLY_GET_REG(sc, reg) bus_space_read_1 (sc->mly_btag, sc->mly_bhandle, reg) -#define MLY_GET_REG2(sc, reg) bus_space_read_2 (sc->mly_btag, sc->mly_bhandle, reg) -#define MLY_GET_REG4(sc, reg) bus_space_read_4 (sc->mly_btag, sc->mly_bhandle, reg) +#define MLY_SET_REG(sc, reg, val) bus_write_1(sc->mly_regs_resource, reg, val) +#define MLY_GET_REG(sc, reg) bus_read_1 (sc->mly_regs_resource, reg) +#define MLY_GET_REG2(sc, reg) bus_read_2 (sc->mly_regs_resource, reg) +#define MLY_GET_REG4(sc, reg) bus_read_4 (sc->mly_regs_resource, reg) #define MLY_SET_MBOX(sc, mbox, ptr) \ do { \ - bus_space_write_4(sc->mly_btag, sc->mly_bhandle, mbox, *((u_int32_t *)ptr)); \ - bus_space_write_4(sc->mly_btag, sc->mly_bhandle, mbox + 4, *((u_int32_t *)ptr + 1)); \ - bus_space_write_4(sc->mly_btag, sc->mly_bhandle, mbox + 8, *((u_int32_t *)ptr + 2)); \ - bus_space_write_4(sc->mly_btag, sc->mly_bhandle, mbox + 12, *((u_int32_t *)ptr + 3)); \ + bus_write_4(sc->mly_regs_resource, mbox, *((u_int32_t *)ptr)); \ + bus_write_4(sc->mly_regs_resource, mbox + 4, *((u_int32_t *)ptr + 1)); \ + bus_write_4(sc->mly_regs_resource, mbox + 8, *((u_int32_t *)ptr + 2)); \ + bus_write_4(sc->mly_regs_resource, mbox + 12, *((u_int32_t *)ptr + 3)); \ } while(0); #define MLY_GET_MBOX(sc, mbox, ptr) \ do { \ - *((u_int32_t *)ptr) = bus_space_read_4(sc->mly_btag, sc->mly_bhandle, mbox); \ - *((u_int32_t *)ptr + 1) = bus_space_read_4(sc->mly_btag, sc->mly_bhandle, mbox + 4); \ - *((u_int32_t *)ptr + 2) = bus_space_read_4(sc->mly_btag, sc->mly_bhandle, mbox + 8); \ - *((u_int32_t *)ptr + 3) = bus_space_read_4(sc->mly_btag, sc->mly_bhandle, mbox + 12); \ + *((u_int32_t *)ptr) = bus_read_4(sc->mly_regs_resource, mbox); \ + *((u_int32_t *)ptr + 1) = bus_read_4(sc->mly_regs_resource, mbox + 4); \ + *((u_int32_t *)ptr + 2) = bus_read_4(sc->mly_regs_resource, mbox + 8); \ + *((u_int32_t *)ptr + 3) = bus_read_4(sc->mly_regs_resource, mbox + 12); \ } while(0); #define MLY_IDBR_TRUE(sc, mask) \ @@ -315,46 +318,34 @@ static __inline void \ mly_enqueue_ ## name (struct mly_command *mc) \ { \ - int s; \ \ - s = splcam(); \ TAILQ_INSERT_TAIL(&mc->mc_sc->mly_ ## name, mc, mc_link); \ MLYQ_ADD(mc->mc_sc, index); \ - splx(s); \ } \ static __inline void \ mly_requeue_ ## name (struct mly_command *mc) \ { \ - int s; \ \ - s = splcam(); \ TAILQ_INSERT_HEAD(&mc->mc_sc->mly_ ## name, mc, mc_link); \ MLYQ_ADD(mc->mc_sc, index); \ - splx(s); \ } \ static __inline struct mly_command * \ mly_dequeue_ ## name (struct mly_softc *sc) \ { \ struct mly_command *mc; \ - int s; \ \ - s = splcam(); \ if ((mc = TAILQ_FIRST(&sc->mly_ ## name)) != NULL) { \ TAILQ_REMOVE(&sc->mly_ ## name, mc, mc_link); \ MLYQ_REMOVE(sc, index); \ } \ - splx(s); \ return(mc); \ } \ static __inline void \ mly_remove_ ## name (struct mly_command *mc) \ { \ - int s; \ \ - s = splcam(); \ TAILQ_REMOVE(&mc->mc_sc->mly_ ## name, mc, mc_link); \ MLYQ_REMOVE(mc->mc_sc, index); \ - splx(s); \ } \ struct hack