From 0767ccf15b56ab462d11a6f47198aea1ce6a927e Mon Sep 17 00:00:00 2001 From: msmith Date: Sun, 3 Dec 2000 02:11:35 +0000 Subject: - add support for crashdumps (courtesy of ps and Y!) - standardise error reporting for commands - simplify the driver-to-controller bio transfer - add bio in/out accounting - correctly preserve the command ID in twe_ioctl (thanks to joel@3ware) --- sys/dev/twe/twe.c | 335 +++++++++++++++++++++++----------------------- sys/dev/twe/twe_freebsd.c | 103 +++++++++++++- sys/dev/twe/twevar.h | 20 +-- 3 files changed, 273 insertions(+), 185 deletions(-) (limited to 'sys/dev/twe') diff --git a/sys/dev/twe/twe.c b/sys/dev/twe/twe.c index 53075ab..6adb277 100644 --- a/sys/dev/twe/twe.c +++ b/sys/dev/twe/twe.c @@ -54,7 +54,6 @@ static int twe_set_param(struct twe_softc *sc, int table_id, int param_id, int p static int twe_init_connection(struct twe_softc *sc, int mode); static int twe_wait_request(struct twe_request *tr); static int twe_immediate_request(struct twe_request *tr); -static void twe_startio(struct twe_softc *sc); static void twe_completeio(struct twe_request *tr); static void twe_reset(struct twe_softc *sc); @@ -96,6 +95,7 @@ static void twe_release_request(struct twe_request *tr); * Debugging. */ static char *twe_format_aen(struct twe_softc *sc, u_int16_t aen); +static int twe_report_request(struct twe_request *tr); static int twe_request_qlen(struct twe_request *tr); static void twe_panic(struct twe_softc *sc, char *reason); @@ -320,20 +320,113 @@ twe_intr(struct twe_softc *sc) twe_done(sc); }; -/******************************************************************************* - * Receive a bio structure from a child device and queue it on a particular - * controller, then poke the controller to start as much work as it can. +/******************************************************************************** + * Pull as much work off the softc's work queue as possible and give it to the + * controller. */ -int -twe_submit_bio(struct twe_softc *sc, twe_bio *bp) +void +twe_startio(struct twe_softc *sc) { - + struct twe_request *tr; + TWE_Command *cmd; + twe_bio *bp; + int error; + debug_called(4); - twe_enqueue_bio(sc, bp); + /* spin until something prevents us from doing any work */ + for (;;) { - twe_startio(sc); - return(0); + /* try to get a command that's already ready to go */ + tr = twe_dequeue_ready(sc); + + /* build a command from an outstanding bio */ + if (tr == NULL) { + + /* see if there's work to be done */ + if ((bp = twe_dequeue_bio(sc)) == NULL) + break; + + /* get a command to handle the bio with */ + if (twe_get_request(sc, &tr)) { + twe_enqueue_bio(sc, bp); /* failed, put the bio back */ + break; + } + + /* connect the bio to the command */ + tr->tr_complete = twe_completeio; + tr->tr_private = bp; + tr->tr_data = TWE_BIO_DATA(bp); + tr->tr_length = TWE_BIO_LENGTH(bp); + cmd = &tr->tr_command; + if (TWE_BIO_IS_READ(bp)) { + tr->tr_flags |= TWE_CMD_DATAIN; + cmd->io.opcode = TWE_OP_READ; + } else { + tr->tr_flags |= TWE_CMD_DATAOUT; + cmd->io.opcode = TWE_OP_WRITE; + } + + /* build a suitable I/O command (assumes 512-byte rounded transfers) */ + cmd->io.size = 3; + cmd->io.unit = TWE_BIO_UNIT(bp); + cmd->io.block_count = (tr->tr_length + TWE_BLOCK_SIZE - 1) / TWE_BLOCK_SIZE; + cmd->io.lba = TWE_BIO_LBA(bp); + + /* map the command so the controller can work with it */ + twe_map_request(tr); + } + + /* did we find something to do? */ + if (tr == NULL) + break; + + /* try to give command to controller */ + error = twe_start(tr); + + if (error != 0) { + if (error == EBUSY) { + twe_requeue_ready(tr); /* try it again later */ + break; /* don't try anything more for now */ + } + /* we don't support any other return from twe_start */ + twe_panic(sc, "twe_start returned nonsense"); + } + } +} + +/******************************************************************************** + * Write blocks from memory to disk, for system crash dumps. + */ +int +twe_dump_blocks(struct twe_softc *sc, int unit, u_int32_t lba, void *data, int nblks) +{ + struct twe_request *tr; + TWE_Command *cmd; + int error; + + if (twe_get_request(sc, &tr)) + return(ENOMEM); + + tr->tr_data = data; + tr->tr_status = TWE_CMD_SETUP; + tr->tr_length = nblks * TWE_BLOCK_SIZE; + tr->tr_flags = TWE_CMD_DATAOUT; + + cmd = &tr->tr_command; + cmd->io.opcode = TWE_OP_WRITE; + cmd->io.size = 3; + cmd->io.unit = unit; + cmd->io.block_count = nblks; + cmd->io.lba = lba; + + twe_map_request(tr); + error = twe_immediate_request(tr); + if (error == 0) + if (twe_report_request(tr)) + error = EIO; + twe_release_request(tr); + return(error); } /******************************************************************************** @@ -349,6 +442,7 @@ twe_ioctl(struct twe_softc *sc, int cmd, void *addr) void *data; int *arg = (int *)addr; struct twe_request *tr; + u_int8_t srid; int s, error; error = 0; @@ -361,8 +455,13 @@ twe_ioctl(struct twe_softc *sc, int cmd, void *addr) goto cmd_done; } - /* copy the user-supplied command */ + /* + * Save the command's request ID, copy the user-supplied command in, + * restore the request ID. + */ + srid = tr->tr_command.generic.request_id; bcopy(&tu->tu_command, &tr->tr_command, sizeof(TWE_Command)); + tr->tr_command.generic.request_id = srid; /* if there's a data buffer, allocate and copy it in */ tr->tr_length = tu->tu_size; @@ -377,6 +476,7 @@ twe_ioctl(struct twe_softc *sc, int cmd, void *addr) } /* run the command */ + twe_map_request(tr); twe_wait_request(tr); /* copy the command out again */ @@ -590,21 +690,8 @@ twe_get_param(struct twe_softc *sc, int table_id, int param_id, size_t param_siz /* XXX could use twe_wait_request here if interrupts were enabled? */ error = twe_immediate_request(tr); if (error == 0) { - switch (cmd->generic.flags) { - case TWE_FLAGS_SUCCESS: - break; - case TWE_FLAGS_INFORMATIONAL: - case TWE_FLAGS_WARNING: - twe_printf(sc, "command completed - %s\n", - twe_describe_code(twe_table_status, cmd->generic.status)); - break; - - case TWE_FLAGS_FATAL: - default: - twe_printf(sc, "command failed - %s\n", - twe_describe_code(twe_table_status, cmd->generic.status)); + if (twe_report_request(tr)) goto err; - } } twe_release_request(tr); return(param); @@ -693,22 +780,8 @@ twe_set_param(struct twe_softc *sc, int table_id, int param_id, int param_size, /* XXX could use twe_wait_request here if interrupts were enabled? */ error = twe_immediate_request(tr); if (error == 0) { - switch (cmd->generic.flags) { - case TWE_FLAGS_SUCCESS: - break; - case TWE_FLAGS_INFORMATIONAL: - case TWE_FLAGS_WARNING: - twe_printf(sc, "command completed - %s\n", - twe_describe_code(twe_table_status, cmd->generic.status)); - break; - - case TWE_FLAGS_FATAL: - default: - twe_printf(sc, "command failed - %s\n", - twe_describe_code(twe_table_status, cmd->generic.status)); + if (twe_report_request(tr)) error = EIO; - break; - } } out: @@ -806,86 +879,11 @@ twe_immediate_request(struct twe_request *tr) } /******************************************************************************** - * Pull as much work off the softc's work queue as possible and give it to the - * controller. - */ -static void -twe_startio(struct twe_softc *sc) -{ - struct twe_request *tr; - TWE_Command *cmd; - twe_bio *bp; - int error; - - debug_called(4); - - /* spin until something prevents us from doing any work */ - for (;;) { - - /* try to get a command that's already ready to go */ - tr = twe_dequeue_ready(sc); - - /* build a command from an outstanding bio */ - if (tr == NULL) { - /* see if there's work to be done */ - if ((bp = twe_dequeue_bio(sc)) == NULL) - break; - /* get a command */ - if (twe_get_request(sc, &tr)) { - twe_enqueue_bio(sc, bp); - break; - } - - /* connect the bio to the command */ - tr->tr_complete = twe_completeio; - tr->tr_private = bp; - tr->tr_data = TWE_BIO_DATA(bp); - tr->tr_length = TWE_BIO_LENGTH(bp); - cmd = &tr->tr_command; - if (TWE_BIO_IS_READ(bp)) { - tr->tr_flags |= TWE_CMD_DATAIN; - cmd->io.opcode = TWE_OP_READ; - } else { - tr->tr_flags |= TWE_CMD_DATAOUT; - cmd->io.opcode = TWE_OP_WRITE; - } - - /* build a suitable I/O command (assumes 512-byte rounded transfers) */ - cmd->io.size = 3; - cmd->io.unit = TWE_BIO_UNIT(bp); - cmd->io.block_count = (tr->tr_length + TWE_BLOCK_SIZE - 1) / TWE_BLOCK_SIZE; - cmd->io.lba = TWE_BIO_LBA(bp); - - /* map the command so the controller can work with it */ - twe_map_request(tr); - } - - /* did we find something to do? */ - if (tr == NULL) - break; - - /* try to give command to controller */ - error = twe_start(tr); - - if (error != 0) { - if (error == EBUSY) { - twe_requeue_ready(tr); /* try it again later */ - break; /* don't try anything more for now */ - } - /* otherwise, fail the command */ - tr->tr_status = TWE_CMD_FAILED; - twe_completeio(tr); - } - } -} - -/******************************************************************************** * Handle completion of an I/O command. */ static void twe_completeio(struct twe_request *tr) { - TWE_Command *cmd = &tr->tr_command; struct twe_softc *sc = tr->tr_sc; twe_bio *bp = (twe_bio *)tr->tr_private; @@ -893,36 +891,15 @@ twe_completeio(struct twe_request *tr) if (tr->tr_status == TWE_CMD_COMPLETE) { - switch (cmd->generic.flags) { - case TWE_FLAGS_SUCCESS: - break; - case TWE_FLAGS_INFORMATIONAL: - case TWE_FLAGS_WARNING: - twe_printf(sc, "command completed - %s\n", - twe_describe_code(twe_table_status, cmd->generic.status)); - break; - - case TWE_FLAGS_FATAL: - default: - twe_printf(sc, "command failed - %s\n", - twe_describe_code(twe_table_status, cmd->generic.status)); + if (twe_report_request(tr)) TWE_BIO_SET_ERROR(bp, EIO); - /* - * XXX some status values suggest that the controller should be reset and all outstanding - * commands retried. This might be a good place for that. - */ - break; - } - } else if (tr->tr_status == TWE_CMD_FAILED) { /* could be more verbose here? */ - TWE_BIO_SET_ERROR(bp, EIO); - twe_printf(sc, "command failed submission - controller wedged\n"); - /* - * XXX reset controller and retry? - */ + } else { + twe_panic(sc, "twe_completeio on incomplete command"); } - twe_release_request(tr); + tr->tr_private = NULL; twed_intr(bp); + twe_release_request(tr); } /******************************************************************************** @@ -935,7 +912,7 @@ twe_reset(struct twe_softc *sc) struct twe_request *tr; int i, s; - twe_printf(sc, "Controller reset in progress...\n"); + twe_printf(sc, "controller reset in progress...\n"); /* * Disable interrupts from the controller, and mask any accidental entry @@ -1075,15 +1052,14 @@ twe_done(struct twe_softc *sc) found = 1; rq = TWE_RESPONSE_QUEUE(sc); tr = sc->twe_lookup[rq.u.response_id]; /* find command */ - if (tr != NULL) { /* paranoia */ - debug(3, "completed request id %d with status %d", - tr->tr_command.generic.request_id, tr->tr_command.generic.status); - /* move to completed queue */ - twe_remove_busy(tr); - twe_enqueue_complete(tr); - } else { - debug(2, "done event for nonbusy id %d\n", rq.u.response_id); - } + if (tr->tr_status != TWE_CMD_BUSY) + twe_printf(sc, "completion event for nonbusy command\n"); + tr->tr_status = TWE_CMD_COMPLETE; + debug(3, "completed request id %d with status %d", + tr->tr_command.generic.request_id, tr->tr_command.generic.status); + /* move to completed queue */ + twe_remove_busy(tr); + twe_enqueue_complete(tr); } else { break; /* no response ready */ } @@ -1119,9 +1095,6 @@ twe_complete(struct twe_softc *sc) /* unmap the command's data buffer */ twe_unmap_request(tr); - /* mark command as complete */ - tr->tr_status = TWE_CMD_COMPLETE; - /* dispatch to suit command originator */ if (tr->tr_complete != NULL) { /* completion callback */ debug(2, "call completion handler %p", tr->tr_complete); @@ -1483,6 +1456,7 @@ twe_get_request(struct twe_softc *sc, struct twe_request **tr) /* initialise some fields to their defaults */ if (*tr != NULL) { (*tr)->tr_data = NULL; + (*tr)->tr_private = NULL; (*tr)->tr_status = TWE_CMD_SETUP; /* command is in setup phase */ (*tr)->tr_flags = 0; (*tr)->tr_complete = NULL; @@ -1501,6 +1475,8 @@ twe_release_request(struct twe_request *tr) { debug_called(4); + if (tr->tr_private != NULL) + twe_panic(tr->tr_sc, "tr_private != NULL"); twe_enqueue_free(tr); } @@ -1653,18 +1629,47 @@ twe_format_aen(struct twe_softc *sc, u_int16_t aen) return(buf); } +/******************************************************************************** + * Print a diagnostic if the status of the command warrants it, and return + * either zero (command was ok) or nonzero (command failed). + */ static int -twe_request_qlen(struct twe_request *tr) +twe_report_request(struct twe_request *tr) { - int len = 0; + struct twe_softc *sc = tr->tr_sc; + TWE_Command *cmd = &tr->tr_command; + int result; - while (tr != NULL) { - tr = TAILQ_NEXT(tr, tr_link); - len++; + switch (cmd->generic.flags) { + case TWE_FLAGS_SUCCESS: + result = 0; + break; + case TWE_FLAGS_INFORMATIONAL: + case TWE_FLAGS_WARNING: + twe_printf(sc, "command completed - %s\n", + twe_describe_code(twe_table_status, cmd->generic.status)); + result = 0; + break; + + case TWE_FLAGS_FATAL: + default: + twe_printf(sc, "command failed - %s\n", + twe_describe_code(twe_table_status, cmd->generic.status)); + result = 1; + + /* + * The status code 0xff requests a controller reset + */ + if (cmd->generic.status == 0xff) + twe_reset(sc); + break; } - return(len); + return(result); } +/******************************************************************************** + * Print some controller state to aid in debugging error/panic conditions + */ void twe_print_controller(struct twe_softc *sc) { @@ -1672,10 +1677,12 @@ twe_print_controller(struct twe_softc *sc) status_reg = TWE_STATUS(sc); twe_printf(sc, "status %b\n", status_reg, TWE_STATUS_BITS_DESCRIPTION); - twe_printf(sc, "free %d\n", twe_request_qlen(TAILQ_FIRST(&sc->twe_free))); - twe_printf(sc, "ready %d\n", twe_request_qlen(TAILQ_FIRST(&sc->twe_ready))); - twe_printf(sc, "busy %d\n", twe_request_qlen(TAILQ_FIRST(&sc->twe_busy))); - twe_printf(sc, "complete %d\n", twe_request_qlen(TAILQ_FIRST(&sc->twe_complete))); + twe_printf(sc, " current max\n"); + twe_printf(sc, "free %04d %04d\n", sc->twe_qstat[TWEQ_FREE].q_length, sc->twe_qstat[TWEQ_FREE].q_max); + twe_printf(sc, "ready %04d %04d\n", sc->twe_qstat[TWEQ_READY].q_length, sc->twe_qstat[TWEQ_READY].q_max); + twe_printf(sc, "busy %04d %04d\n", sc->twe_qstat[TWEQ_BUSY].q_length, sc->twe_qstat[TWEQ_BUSY].q_max); + twe_printf(sc, "complete %04d %04d\n", sc->twe_qstat[TWEQ_COMPLETE].q_length, sc->twe_qstat[TWEQ_COMPLETE].q_max); + twe_printf(sc, "bioq %04d %04d\n", sc->twe_qstat[TWEQ_BIO].q_length, sc->twe_qstat[TWEQ_BIO].q_max); twe_printf(sc, "AEN queue head %d tail %d\n", sc->twe_aen_head, sc->twe_aen_tail); } diff --git a/sys/dev/twe/twe_freebsd.c b/sys/dev/twe/twe_freebsd.c index 9012f36..104e828 100644 --- a/sys/dev/twe/twe_freebsd.c +++ b/sys/dev/twe/twe_freebsd.c @@ -31,6 +31,13 @@ * FreeBSD-specific code. */ +#include +#include +#include +#include +#include +#include +#include #include #include #include @@ -41,6 +48,16 @@ static devclass_t twe_devclass; +#ifdef TWE_DEBUG +static u_int32_t twed_bio_in; +#define TWED_BIO_IN twed_bio_in++ +static u_int32_t twed_bio_out; +#define TWED_BIO_OUT twed_bio_out++ +#else +#define TWED_BIO_IN +#define TWED_BIO_OUT +#endif + /******************************************************************************** ******************************************************************************** Control device interface @@ -250,13 +267,13 @@ twe_attach(device_t dev) /* * Create DMA tag for mapping objects into controller-addressable space. */ - if (bus_dma_tag_create(sc->twe_parent_dmat, /* parent */ - 1, 0, /* alignment, boundary */ + if (bus_dma_tag_create(sc->twe_parent_dmat, /* parent */ + 1, 0, /* alignment, boundary */ BUS_SPACE_MAXADDR, /* lowaddr */ BUS_SPACE_MAXADDR, /* highaddr */ NULL, NULL, /* filter, filterarg */ - MAXBSIZE, TWE_MAX_SGL_LENGTH, /* maxsize, nsegments */ - BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */ + MAXBSIZE, TWE_MAX_SGL_LENGTH,/* maxsize, nsegments */ + BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */ 0, /* flags */ &sc->twe_buffer_dmat)) { twe_printf(sc, "can't allocate data buffer DMA tag\n"); @@ -551,6 +568,7 @@ DRIVER_MODULE(twed, twe, twed_driver, twed_devclass, 0, 0); static d_open_t twed_open; static d_close_t twed_close; static d_strategy_t twed_strategy; +static d_dump_t twed_dump; #define TWED_CDEV_MAJOR 147 @@ -565,7 +583,7 @@ static struct cdevsw twed_cdevsw = { twed_strategy, "twed", TWED_CDEV_MAJOR, - nodump, + twed_dump, nopsize, D_DISK, -1 @@ -639,9 +657,14 @@ twed_strategy(twe_bio *bp) debug_called(4); + TWED_BIO_IN; + /* bogus disk? */ if (sc == NULL) { TWE_BIO_SET_ERROR(bp, EINVAL); + printf("twe: bio for invalid disk!\n"); + TWE_BIO_DONE(bp); + TWED_BIO_OUT; return; } @@ -649,18 +672,82 @@ twed_strategy(twe_bio *bp) if (TWE_BIO_LENGTH(bp) == 0) { TWE_BIO_RESID(bp) = 0; TWE_BIO_DONE(bp); + TWED_BIO_OUT; return; } /* perform accounting */ TWE_BIO_STATS_START(bp); - /* pass the bio to the controller - it can work out who we are */ - twe_submit_bio(sc->twed_controller, bp); + /* queue the bio on the controller */ + twe_enqueue_bio(sc->twed_controller, bp); + + /* poke the controller to start I/O */ + twe_startio(sc->twed_controller); return; } /******************************************************************************** + * System crashdump support + */ +int +twed_dump(dev_t dev) +{ + struct twed_softc *twed_sc = (struct twed_softc *)dev->si_drv1; + struct twe_softc *twe_sc = (struct twe_softc *)twed_sc->twed_controller; + u_int count, blkno, secsize; + vm_offset_t addr = 0; + long blkcnt; + int dumppages = MAXDUMPPGS; + int error; + int i; + + if ((error = disk_dumpcheck(dev, &count, &blkno, &secsize))) + return(error); + + if (!twed_sc || !twe_sc) + return(ENXIO); + + blkcnt = howmany(PAGE_SIZE, secsize); + + while (count > 0) { + caddr_t va = NULL; + + if ((count / blkcnt) < dumppages) + dumppages = count / blkcnt; + + for (i = 0; i < dumppages; ++i) { + vm_offset_t a = addr + (i * PAGE_SIZE); + if (is_physical_memory(a)) + va = pmap_kenter_temporary(trunc_page(a), i); + else + va = pmap_kenter_temporary(trunc_page(0), i); + } + + if ((error = twe_dump_blocks(twe_sc, twed_sc->twed_drive->td_unit, blkno, va, + (PAGE_SIZE * dumppages) / TWE_BLOCK_SIZE)) != 0) + return(error); + + + if (addr % (1024 * 1024) == 0) { +#ifdef HW_WDOG + if (wdog_tickler) + (*wdog_tickler)(); +#endif + printf("%ld ", (long)(count * DEV_BSIZE) / (1024 * 1024)); + } + + blkno += blkcnt * dumppages; + count -= blkcnt * dumppages; + addr += PAGE_SIZE * dumppages; + + if (cncheckc() != -1) + return(EINTR); + } + return(0); +} + +/******************************************************************************** * Handle completion of an I/O request. */ void @@ -674,6 +761,7 @@ twed_intr(twe_bio *bp) TWE_BIO_STATS_END(bp); TWE_BIO_DONE(bp); + TWED_BIO_OUT; } /******************************************************************************** @@ -967,6 +1055,7 @@ twe_report(void) s = splbio(); for (i = 0; (sc = devclass_get_softc(twe_devclass, i)) != NULL; i++) twe_print_controller(sc); + printf("twed: total bio count in %u out %u\n", twed_bio_in, twed_bio_out); splx(s); } #endif diff --git a/sys/dev/twe/twevar.h b/sys/dev/twe/twevar.h index ea12062..639a4253 100644 --- a/sys/dev/twe/twevar.h +++ b/sys/dev/twe/twevar.h @@ -84,7 +84,6 @@ struct twe_request #define TWE_CMD_SETUP 0 /* being assembled */ #define TWE_CMD_BUSY 1 /* submitted to controller */ #define TWE_CMD_COMPLETE 2 /* completed by controller (maybe with error) */ -#define TWE_CMD_FAILED 3 /* failed submission to controller */ int tr_flags; #define TWE_CMD_DATAIN (1<<0) #define TWE_CMD_DATAOUT (1<<1) @@ -122,9 +121,7 @@ struct twe_softc #define TWE_STATE_OPEN (1<<2) /* control device is open */ #define TWE_STATE_SUSPEND (1<<3) /* controller is suspended */ int twe_host_id; -#ifdef TWE_PERFORMANCE_MONITOR struct twe_qstat twe_qstat[TWEQ_COUNT]; /* queue statistics */ -#endif TWE_PLATFORM_SOFTC /* platform-specific softc elements */ }; @@ -136,8 +133,9 @@ extern int twe_setup(struct twe_softc *sc); /* do early driver/controller setup extern void twe_init(struct twe_softc *sc); /* init controller */ extern void twe_deinit(struct twe_softc *sc); /* stop controller */ extern void twe_intr(struct twe_softc *sc); /* hardware interrupt signalled */ -extern int twe_submit_bio(struct twe_softc *sc, - twe_bio *bp); /* pass bio to core */ +extern void twe_startio(struct twe_softc *sc); +extern int twe_dump_blocks(struct twe_softc *sc, int unit, /* crashdump block write */ + u_int32_t lba, void *data, int nblks); extern int twe_ioctl(struct twe_softc *sc, int cmd, void *addr); /* handle user request */ extern void twe_describe_controller(struct twe_softc *sc); /* print controller info */ @@ -156,8 +154,7 @@ extern void twe_unmap_request(struct twe_request *tr); /* cleanup after transfer /******************************************************************************** * Queue primitives */ -#ifdef TWE_PERFORMANCE_MONITOR -# define TWEQ_ADD(sc, qname) \ +#define TWEQ_ADD(sc, qname) \ do { \ struct twe_qstat *qs = &(sc)->twe_qstat[qname]; \ \ @@ -166,17 +163,12 @@ extern void twe_unmap_request(struct twe_request *tr); /* cleanup after transfer qs->q_max = qs->q_length; \ } while(0) -# define TWEQ_REMOVE(sc, qname) (sc)->twe_qstat[qname].q_length-- -# define TWEQ_INIT(sc, qname) \ +#define TWEQ_REMOVE(sc, qname) (sc)->twe_qstat[qname].q_length-- +#define TWEQ_INIT(sc, qname) \ do { \ sc->twe_qstat[qname].q_length = 0; \ sc->twe_qstat[qname].q_max = 0; \ } while(0) -#else -# define TWEQ_ADD(sc, qname) -# define TWEQ_REMOVE(sc, qname) -# define TWEQ_INIT(sc, qname) -#endif #define TWEQ_REQUEST_QUEUE(name, index) \ -- cgit v1.1