From 334a17f09a71daa88e7f7651d94f64711e2d0319 Mon Sep 17 00:00:00 2001 From: Nicolas Souchu Date: Sat, 23 Jun 2001 06:51:52 +0000 Subject: [PATCH] Translate various ppbus sequences into microsequences to limit overhead of abstraction layers. Submitted by: jcm@FreeBSD-uk.eu.org --- sys/dev/ppbus/immio.c | 140 ++++++++++++++++++++++-------------------- sys/dev/ppbus/vpoio.c | 97 ++++++++++++++++------------- 2 files changed, 128 insertions(+), 109 deletions(-) diff --git a/sys/dev/ppbus/immio.c b/sys/dev/ppbus/immio.c index fca5374f24ad..dcdc34b68a43 100644 --- a/sys/dev/ppbus/immio.c +++ b/sys/dev/ppbus/immio.c @@ -41,12 +41,8 @@ #include #include - #endif /* _KERNEL */ -#ifdef _KERNEL -#endif /* _KERNEL */ - #include "opt_vpo.h" #include @@ -67,9 +63,27 @@ * Microcode to execute very fast I/O sequences at the lowest bus level. */ +#define WAIT_RET MS_PARAM(7, 2, MS_TYP_PTR) +#define WAIT_TMO MS_PARAM(1, 0, MS_TYP_INT) + +#define DECLARE_WAIT_MICROSEQUENCE \ +struct ppb_microseq wait_microseq[] = { \ + MS_CASS(0x0c), \ + MS_SET(MS_UNKNOWN), \ + /* loop */ \ + MS_BRSET(nBUSY, 4 /* ready */), \ + MS_DBRA(-2 /* loop */), \ + MS_CASS(0x04), \ + MS_RET(1), /* timed out */ \ + /* ready */ \ + MS_CASS(0x04), \ + MS_RFETCH(MS_REG_STR, 0xb8, MS_UNKNOWN ), \ + MS_RET(0) /* no error */ \ +} + #define SELECT_TARGET MS_PARAM(6, 1, MS_TYP_CHA) -#define DECLARE_SELECT_MICROSEQUENCE \ +#define DECLARE_SELECT_MICROSEQUENCE \ struct ppb_microseq select_microseq[] = { \ MS_CASS(0xc), \ /* first, check there is nothing holding onto the bus */ \ @@ -134,7 +148,7 @@ struct ppb_microseq cpp_microseq[] = { \ #define NEGOCIATED_MODE MS_PARAM(2, 1, MS_TYP_CHA) #define DECLARE_NEGOCIATE_MICROSEQ \ -static struct ppb_microseq negociate_microseq[] = { \ +struct ppb_microseq negociate_microseq[] = { \ MS_CASS(0x4), \ MS_DELAY(5), \ MS_DASS(MS_UNKNOWN /* mode */), \ @@ -155,6 +169,35 @@ static struct ppb_microseq negociate_microseq[] = { \ MS_RET(0) \ } +#define INB_NIBBLE_L MS_PARAM(3, 2, MS_TYP_PTR) +#define INB_NIBBLE_H MS_PARAM(6, 2, MS_TYP_PTR) +#define INB_NIBBLE_F MS_PARAM(9, 0, MS_TYP_FUN) +#define INB_NIBBLE_P MS_PARAM(9, 1, MS_TYP_PTR) + +/* + * This is the sub-microseqence for MS_GET in NIBBLE mode + * Retrieve the two nibbles and call the C function to generate the character + * and store it in the buffer (see nibble_inbyte_hook()) + */ + +#define DECLARE_NIBBLE_INBYTE_SUBMICROSEQ \ +struct ppb_microseq nibble_inbyte_submicroseq[] = { \ + MS_CASS(0x4), \ +/* loop: */ \ + MS_CASS(0x6), \ + MS_DELAY(1), \ + MS_RFETCH(MS_REG_STR, MS_FETCH_ALL, MS_UNKNOWN /* low nibble */),\ + MS_CASS(0x5), \ + MS_DELAY(1), \ + MS_RFETCH(MS_REG_STR, MS_FETCH_ALL, MS_UNKNOWN /* high nibble */),\ + MS_CASS(0x4), \ + MS_DELAY(1), \ + /* do a C call to format the received nibbles */ \ + MS_C_CALL(MS_UNKNOWN /* C hook */, MS_UNKNOWN /* param */), \ + MS_DBRA(-7 /* loop */), \ + MS_RET(0) \ +} + static struct ppb_microseq reset_microseq[] = { MS_CASS(0x04), MS_DASS(0x40), @@ -183,47 +226,6 @@ nibble_inbyte_hook (void *p, char *ptr) return (0); } -/* - * Macro used to initialize each vpoio_data structure during - * low level attachment - * - * XXX should be converted to ppb_MS_init_msq() - */ -#define INIT_NIBBLE_INBYTE_SUBMICROSEQ(vpo) { \ - (vpo)->vpo_nibble_inbyte_msq[6].arg[2].p = \ - (void *)&(vpo)->vpo_nibble.h; \ - (vpo)->vpo_nibble_inbyte_msq[3].arg[2].p = \ - (void *)&(vpo)->vpo_nibble.l; \ - (vpo)->vpo_nibble_inbyte_msq[9].arg[0].f = \ - nibble_inbyte_hook; \ - (vpo)->vpo_nibble_inbyte_msq[9].arg[1].p = \ - (void *)&(vpo)->vpo_nibble; \ -} - -/* - * This is the sub-microseqence for MS_GET in NIBBLE mode - * Retrieve the two nibbles and call the C function to generate the character - * and store it in the buffer (see nibble_inbyte_hook()) - */ -static struct ppb_microseq nibble_inbyte_submicroseq[] = { - MS_CASS(0x4), - -/* loop: */ - MS_CASS(0x6), - MS_DELAY(1), - MS_RFETCH(MS_REG_STR, MS_FETCH_ALL, MS_UNKNOWN /* low nibble */), - MS_CASS(0x5), - MS_DELAY(1), - MS_RFETCH(MS_REG_STR, MS_FETCH_ALL, MS_UNKNOWN /* high nibble */), - MS_CASS(0x4), - MS_DELAY(1), - - /* do a C call to format the received nibbles */ - MS_C_CALL(MS_UNKNOWN /* C hook */, MS_UNKNOWN /* param */), - MS_DBRA(-7 /* loop */), - MS_RET(0) -}; - /* * This is the sub-microseqence for MS_GET in PS2 mode */ @@ -483,21 +485,14 @@ imm_select(struct vpoio_data *vpo, int initiator, int target) * * H_SELIN must be low. * - * XXX should be ported to microseq */ static char imm_wait(struct vpoio_data *vpo, int tmo) { + DECLARE_WAIT_MICROSEQUENCE; + device_t ppbus = device_get_parent(vpo->vpo_dev); - register int k; - register char r; - - ppb_wctr(ppbus, 0xc); - - /* XXX should be ported to microseq */ - k = 0; - while (!((r = ppb_rstr(ppbus)) & 0x80) && (k++ < tmo)) - DELAY(1); + int ret, err; /* * Return some status information. @@ -506,11 +501,17 @@ imm_wait(struct vpoio_data *vpo, int tmo) * 0xa8 = ZIP+ wants command * 0xb8 = end of transfer, ZIP+ is sending status */ - ppb_wctr(ppbus, 0x4); - if (k < tmo) - return (r & 0xb8); - return (0); /* command timed out */ + ppb_MS_init_msq(wait_microseq, 2, + WAIT_RET, (void *)&ret, + WAIT_TMO, tmo); + + ppb_MS_microseq(ppbus, vpo->vpo_dev, wait_microseq, &err); + + if (err) + return (0); /* command timed out */ + + return(ret); } static int @@ -574,7 +575,9 @@ imm_probe(device_t dev, struct vpoio_data *vpo) int imm_attach(struct vpoio_data *vpo) { + DECLARE_NIBBLE_INBYTE_SUBMICROSEQ; device_t ppbus = device_get_parent(vpo->vpo_dev); + int error = 0; /* * Initialize microsequence code @@ -589,12 +592,17 @@ imm_attach(struct vpoio_data *vpo) (void *)vpo->vpo_nibble_inbyte_msq, sizeof(nibble_inbyte_submicroseq)); - INIT_NIBBLE_INBYTE_SUBMICROSEQ(vpo); + ppb_MS_init_msq(vpo->vpo_nibble_inbyte_msq, 4, + INB_NIBBLE_H, (void *)&(vpo)->vpo_nibble.h, + INB_NIBBLE_L, (void *)&(vpo)->vpo_nibble.l, + INB_NIBBLE_F, nibble_inbyte_hook, + INB_NIBBLE_P, (void *)&(vpo)->vpo_nibble); /* * Initialize mode dependent in/out microsequences */ - ppb_request_bus(ppbus, vpo->vpo_dev, PPB_WAIT); + if ((error = ppb_request_bus(ppbus, vpo->vpo_dev, PPB_WAIT))) + goto error; /* ppbus automatically restore the last mode entered during detection */ switch (vpo->vpo_mode_found) { @@ -618,8 +626,8 @@ imm_attach(struct vpoio_data *vpo) } ppb_release_bus(ppbus, vpo->vpo_dev); - - return (0); + error: + return (error); } /* @@ -671,7 +679,7 @@ imm_do_scsi(struct vpoio_data *vpo, int host, int target, char *command, * XXX * Should we allow this call to be interruptible? * The only way to report the interruption is to return - * EIO do upper SCSI code :^( + * EIO to upper SCSI code :^( */ if ((error = imm_connect(vpo, PPB_WAIT|PPB_INTR, ¬_connected, 1))) return (error); diff --git a/sys/dev/ppbus/vpoio.c b/sys/dev/ppbus/vpoio.c index c8fd27374214..7ce6f0802c6e 100644 --- a/sys/dev/ppbus/vpoio.c +++ b/sys/dev/ppbus/vpoio.c @@ -35,6 +35,7 @@ #include #include +#include #endif @@ -97,6 +98,21 @@ * Microcode to execute very fast I/O sequences at the lowest bus level. */ +#define WAIT_RET MS_PARAM(4, 2, MS_TYP_PTR) +#define WAIT_TMO MS_PARAM(0, 0, MS_TYP_INT) + +#define DECLARE_WAIT_MICROSEQUENCE \ +struct ppb_microseq wait_microseq[] = { \ + MS_SET(MS_UNKNOWN), \ + /* loop */ \ + MS_BRSET(nBUSY, 2 /* ready */), \ + MS_DBRA(-2 /* loop */), \ + MS_RET(1), /* timed out */ \ + /* ready */ \ + MS_RFETCH(MS_REG_STR, 0xf0, MS_UNKNOWN), \ + MS_RET(0) /* no error */ \ +} + /* call this macro to initialize connect/disconnect microsequences */ #define INIT_TRIG_MICROSEQ { \ int i; \ @@ -156,44 +172,31 @@ nibble_inbyte_hook (void *p, char *ptr) return (0); } -/* - * Macro used to initialize each vpoio_data structure during - * low level attachment - * - * XXX should be converted to ppb_MS_init_msq() - */ -#define INIT_NIBBLE_INBYTE_SUBMICROSEQ(vpo) { \ - (vpo)->vpo_nibble_inbyte_msq[2].arg[2].p = \ - (void *)&(vpo)->vpo_nibble.h; \ - (vpo)->vpo_nibble_inbyte_msq[4].arg[2].p = \ - (void *)&(vpo)->vpo_nibble.l; \ - (vpo)->vpo_nibble_inbyte_msq[5].arg[0].f = \ - nibble_inbyte_hook; \ - (vpo)->vpo_nibble_inbyte_msq[5].arg[1].p = \ - (void *)&(vpo)->vpo_nibble; \ -} +#define INB_NIBBLE_H MS_PARAM(2, 2, MS_TYP_PTR) +#define INB_NIBBLE_L MS_PARAM(4, 2, MS_TYP_PTR) +#define INB_NIBBLE_F MS_PARAM(5, 0, MS_TYP_FUN) +#define INB_NIBBLE_P MS_PARAM(5, 1, MS_TYP_PTR) /* * This is the sub-microseqence for MS_GET in NIBBLE mode * Retrieve the two nibbles and call the C function to generate the character * and store it in the buffer (see nibble_inbyte_hook()) */ -static struct ppb_microseq nibble_inbyte_submicroseq[] = { -/* loop: */ - MS_CASS( H_AUTO | H_SELIN | H_INIT | H_STROBE), - MS_DELAY(VP0_PULSE), - MS_RFETCH(MS_REG_STR, MS_FETCH_ALL, MS_UNKNOWN /* high nibble */), - MS_CASS(H_nAUTO | H_SELIN | H_INIT | H_STROBE), - MS_RFETCH(MS_REG_STR, MS_FETCH_ALL, MS_UNKNOWN /* low nibble */), - - /* do a C call to format the received nibbles */ - MS_C_CALL(MS_UNKNOWN /* C hook */, MS_UNKNOWN /* param */), - MS_DBRA(-7 /* loop */), - - MS_CASS(H_AUTO | H_nSELIN | H_INIT | H_STROBE), - MS_RET(0) -}; +#define DECLARE_NIBBLE_INBYTE_SUBMICROSEQ \ +struct ppb_microseq nibble_inbyte_submicroseq[] = { \ +/* loop: */ \ + MS_CASS( H_AUTO | H_SELIN | H_INIT | H_STROBE), \ + MS_DELAY(VP0_PULSE), \ + MS_RFETCH(MS_REG_STR, MS_FETCH_ALL, MS_UNKNOWN /* high nibble */),\ + MS_CASS(H_nAUTO | H_SELIN | H_INIT | H_STROBE), \ + MS_RFETCH(MS_REG_STR, MS_FETCH_ALL, MS_UNKNOWN /* low nibble */),\ + /* do a C call to format the received nibbles */ \ + MS_C_CALL(MS_UNKNOWN /* C hook */, MS_UNKNOWN /* param */),\ + MS_DBRA(-7 /* loop */), \ + MS_CASS(H_AUTO | H_nSELIN | H_INIT | H_STROBE), \ + MS_RET(0) \ +} /* * This is the sub-microseqence for MS_GET in PS2 mode @@ -364,8 +367,8 @@ vpoio_detect(struct vpoio_data *vpo) if ((error = ppb_request_bus(ppbus, vpo->vpo_dev, PPB_DONTWAIT))) return (error); - ppb_MS_microseq(ppbus, vpo->vpo_dev, disconnect_microseq, &ret); /* Force disconnection */ + ppb_MS_microseq(ppbus, vpo->vpo_dev, disconnect_microseq, &ret); /* Try to enter EPP mode, then connect to the drive in EPP mode */ if (ppb_set_mode(ppbus, PPB_EPP) != -1) { @@ -517,9 +520,10 @@ vpoio_select(struct vpoio_data *vpo, int initiator, int target) static char vpoio_wait(struct vpoio_data *vpo, int tmo) { + DECLARE_WAIT_MICROSEQUENCE; + device_t ppbus = device_get_parent(vpo->vpo_dev); - register int k; - register char r; + int ret, err; #if 0 /* broken */ if (ppb_poll_device(ppbus, 150, nBUSY, nBUSY, PPB_INTR)) @@ -528,11 +532,6 @@ vpoio_wait(struct vpoio_data *vpo, int tmo) return (ppb_rstr(ppbus) & 0xf0); #endif - /* XXX should be ported to microseq */ - k = 0; - while (!((r = ppb_rstr(ppbus)) & nBUSY) && (k++ < tmo)) - ; - /* * Return some status information. * Semantics : 0xc0 = ZIP wants more data @@ -540,10 +539,17 @@ vpoio_wait(struct vpoio_data *vpo, int tmo) * 0xe0 = ZIP wants command * 0xf0 = end of transfer, ZIP is sending status */ - if (k < tmo) - return (r & 0xf0); - return (0); /* command timed out */ + ppb_MS_init_msq(wait_microseq, 2, + WAIT_RET, (void *)&ret, + WAIT_TMO, tmo); + + ppb_MS_microseq(ppbus, vpo->vpo_dev, wait_microseq, &err); + + if (err) + return (0); /* command timed out */ + + return(ret); } /* @@ -582,6 +588,7 @@ vpoio_probe(device_t dev, struct vpoio_data *vpo) int vpoio_attach(struct vpoio_data *vpo) { + DECLARE_NIBBLE_INBYTE_SUBMICROSEQ; device_t ppbus = device_get_parent(vpo->vpo_dev); int error = 0; @@ -595,7 +602,11 @@ vpoio_attach(struct vpoio_data *vpo) (void *)vpo->vpo_nibble_inbyte_msq, sizeof(nibble_inbyte_submicroseq)); - INIT_NIBBLE_INBYTE_SUBMICROSEQ(vpo); + ppb_MS_init_msq(vpo->vpo_nibble_inbyte_msq, 4, + INB_NIBBLE_H, (void *)&(vpo)->vpo_nibble.h, + INB_NIBBLE_L, (void *)&(vpo)->vpo_nibble.l, + INB_NIBBLE_F, nibble_inbyte_hook, + INB_NIBBLE_P, (void *)&(vpo)->vpo_nibble); /* * Initialize mode dependent in/out microsequences