summaryrefslogtreecommitdiffstats
path: root/sys/dev/ppbus
diff options
context:
space:
mode:
authornsouch <nsouch@FreeBSD.org>2001-06-23 06:51:52 +0000
committernsouch <nsouch@FreeBSD.org>2001-06-23 06:51:52 +0000
commitcb3f82adbb12b2e7175c1dd4bc4b67b10cdfcdb6 (patch)
tree161eacf06daeea252c5c4c06f3bde22b5708cbf5 /sys/dev/ppbus
parent49fc10f4a2791c4482d2ac1e61985b2067188a19 (diff)
downloadFreeBSD-src-cb3f82adbb12b2e7175c1dd4bc4b67b10cdfcdb6.zip
FreeBSD-src-cb3f82adbb12b2e7175c1dd4bc4b67b10cdfcdb6.tar.gz
Translate various ppbus sequences into microsequences to limit
overhead of abstraction layers. Submitted by: jcm@FreeBSD-uk.eu.org
Diffstat (limited to 'sys/dev/ppbus')
-rw-r--r--sys/dev/ppbus/immio.c140
-rw-r--r--sys/dev/ppbus/vpoio.c97
2 files changed, 128 insertions, 109 deletions
diff --git a/sys/dev/ppbus/immio.c b/sys/dev/ppbus/immio.c
index fca5374..dcdc34b 100644
--- a/sys/dev/ppbus/immio.c
+++ b/sys/dev/ppbus/immio.c
@@ -41,12 +41,8 @@
#include <sys/bus.h>
#include <sys/malloc.h>
-
#endif /* _KERNEL */
-#ifdef _KERNEL
-#endif /* _KERNEL */
-
#include "opt_vpo.h"
#include <dev/ppbus/ppbio.h>
@@ -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),
@@ -184,47 +227,6 @@ nibble_inbyte_hook (void *p, char *ptr)
}
/*
- * 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
*/
static struct ppb_microseq ps2_inbyte_submicroseq[] = {
@@ -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)
{
- device_t ppbus = device_get_parent(vpo->vpo_dev);
- register int k;
- register char r;
+ DECLARE_WAIT_MICROSEQUENCE;
- ppb_wctr(ppbus, 0xc);
-
- /* XXX should be ported to microseq */
- k = 0;
- while (!((r = ppb_rstr(ppbus)) & 0x80) && (k++ < tmo))
- DELAY(1);
+ device_t ppbus = device_get_parent(vpo->vpo_dev);
+ 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, &not_connected, 1)))
return (error);
diff --git a/sys/dev/ppbus/vpoio.c b/sys/dev/ppbus/vpoio.c
index c8fd273..7ce6f08 100644
--- a/sys/dev/ppbus/vpoio.c
+++ b/sys/dev/ppbus/vpoio.c
@@ -35,6 +35,7 @@
#include <sys/bus.h>
#include <sys/malloc.h>
+#include <machine/clock.h>
#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
OpenPOWER on IntegriCloud