diff options
| author | Hartmut Brandt <harti@FreeBSD.org> | 2003-08-20 11:05:28 +0000 |
|---|---|---|
| committer | Hartmut Brandt <harti@FreeBSD.org> | 2003-08-20 11:05:28 +0000 |
| commit | 48a4aa4d408593da47bd914c9876cd3ef7c07599 (patch) | |
| tree | 39b9b7e096e655ef7d00b3c3c470f87d930253df /sys/dev | |
| parent | d1a781decfa9780952cc2ba6fecf2d564c22e013 (diff) | |
Notes
Diffstat (limited to 'sys/dev')
| -rw-r--r-- | sys/dev/hfa/fore_aali.h | 2 | ||||
| -rw-r--r-- | sys/dev/hfa/fore_command.c | 12 | ||||
| -rw-r--r-- | sys/dev/hfa/fore_init.c | 53 | ||||
| -rw-r--r-- | sys/dev/hfa/fore_intr.c | 4 | ||||
| -rw-r--r-- | sys/dev/hfa/fore_var.h | 1 |
5 files changed, 68 insertions, 4 deletions
diff --git a/sys/dev/hfa/fore_aali.h b/sys/dev/hfa/fore_aali.h index c5bf8038f1a3..91387b6e1714 100644 --- a/sys/dev/hfa/fore_aali.h +++ b/sys/dev/hfa/fore_aali.h @@ -331,6 +331,8 @@ typedef volatile unsigned long Cmd_code; #define CMD_SET_OC3_REG 0x07 /* Set SUNI OC3 registers */ #define CMD_GET_OC3_REG 0x08 /* Get SUNI OC3 registers */ #define CMD_GET_PROM 0x09 /* Get PROM data */ +#define CMD_ZERO_STATS4 0x09 /* FT 4 Zero stats (unimpl) */ +#define CMD_GET_PROM4 0x0a /* FT 4 Get PROM data */ #define CMD_INTR_REQ 0x80 /* Request host interrupt */ #endif /* ATM_KERNEL */ diff --git a/sys/dev/hfa/fore_command.c b/sys/dev/hfa/fore_command.c index 5823a3623c5d..37890688b9e5 100644 --- a/sys/dev/hfa/fore_command.c +++ b/sys/dev/hfa/fore_command.c @@ -213,8 +213,9 @@ fore_cmd_drain(fup) /* * Process each completed entry + * ForeThought 4 may set QSTAT_ERROR without QSTAT_COMPLETED. */ - while (*fup->fu_cmd_head->hcq_status & QSTAT_COMPLETED) { + while (*fup->fu_cmd_head->hcq_status & (QSTAT_COMPLETED | QSTAT_ERROR)) { hcp = fup->fu_cmd_head; @@ -314,6 +315,14 @@ fore_cmd_drain(fup) #ifdef FORE_PCI case CMD_GET_PROM: + if (fup->fu_ft4) + goto unknown; + goto prom; + + case CMD_GET_PROM4: + if (!fup->fu_ft4) + goto unknown; + prom: if (*hcp->hcq_status & QSTAT_ERROR) { /* * Couldn't get PROM data @@ -356,6 +365,7 @@ fore_cmd_drain(fup) #endif /* FORE_PCI */ default: + unknown: log(LOG_ERR, "fore_cmd_drain: unknown command %ld\n", hcp->hcq_code); } diff --git a/sys/dev/hfa/fore_init.c b/sys/dev/hfa/fore_init.c index d0e6192ff479..e8584c2c1b89 100644 --- a/sys/dev/hfa/fore_init.c +++ b/sys/dev/hfa/fore_init.c @@ -72,6 +72,8 @@ fore_initialize(fup) Init_parms *inp; caddr_t errmsg; u_long vers; + u_int c, wait; +#define MAX_WAIT 100 /* * Must wait until firmware has been downloaded and is running @@ -126,6 +128,11 @@ fore_initialize(fup) sizeof(fup->fu_config.ac_firm_vers), "%ld.%ld.%ld", (vers >> 16) & 0xff, (vers >> 8) & 0xff, vers & 0xff); + if (((vers >> 16) & 0xff) == 4) + fup->fu_ft4 = 1; + else + fup->fu_ft4 = 0; + #ifdef notdef /* * Turn on CP debugging @@ -170,7 +177,41 @@ fore_initialize(fup) * the CP to interrupt to signal completion */ inp->init_status = CP_WRITE(QSTAT_PENDING); - inp->init_cmd = CP_WRITE(CMD_INIT | CMD_INTR_REQ); + + if (!fup->fu_ft4) { + inp->init_cmd = CP_WRITE(CMD_INIT | CMD_INTR_REQ); + return; + } + inp->init_cmd = CP_WRITE(CMD_INIT); + + /* + * With the ForeThought 4.X image it appears that we need to + * busy wait on the initializisation command to complete. + * Otherwise the command queue address (the first word + * of the queue structure) will be mangled. + */ + c = 0; + for (wait = 0; wait < MAX_WAIT; wait++) { + c = CP_READ(inp->init_status); + if (c & QSTAT_COMPLETED) + break; + DELAY(1000); + } + if (c & QSTAT_ERROR) { + log(LOG_ERR, "fore initialization failed: intf=%s%d, " + "hbeat=0x%lx\n", fup->fu_pif.pif_name, + fup->fu_pif.pif_unit, (u_long)CP_READ(aap->aali_heartbeat)); + fore_interface_free(fup); + return; + } + if (!(c & QSTAT_COMPLETED)) { + log(LOG_ERR, "fore initialization timed out: intf=%s%d, " + "hbeat=0x%lx\n", fup->fu_pif.pif_name, fup->fu_pif.pif_unit, + (u_long)CP_READ(aap->aali_heartbeat)); + fore_interface_free(fup); + return; + } + fore_initialize_complete(fup); return; failed: @@ -257,6 +298,9 @@ fore_initialize_complete(fup) * This will be called after CP initialization has completed. * There is (currently) no retry if this fails. * + * It took me some time to find out that FT3 and FT4 use different + * operation codes for GET_PROM. + * * Called at interrupt level. * * Arguments: @@ -282,7 +326,10 @@ fore_get_prom(fup) /* * Queue entry available, so set our view of things up */ - hcp->hcq_code = CMD_GET_PROM; + if (fup->fu_ft4) + hcp->hcq_code = CMD_GET_PROM4; + else + hcp->hcq_code = CMD_GET_PROM; hcp->hcq_arg = NULL; fup->fu_cmd_tail = hcp->hcq_next; @@ -300,7 +347,7 @@ fore_get_prom(fup) return; } cqp->cmdq_prom.prom_buffer = (CP_dma) CP_WRITE(fup->fu_promd); - cqp->cmdq_prom.prom_cmd = CP_WRITE(CMD_GET_PROM | CMD_INTR_REQ); + cqp->cmdq_prom.prom_cmd = CP_WRITE(hcp->hcq_code | CMD_INTR_REQ); } else { /* diff --git a/sys/dev/hfa/fore_intr.c b/sys/dev/hfa/fore_intr.c index aa7f05cce99a..2beec165a130 100644 --- a/sys/dev/hfa/fore_intr.c +++ b/sys/dev/hfa/fore_intr.c @@ -175,6 +175,10 @@ fore_intr(arg) */ if ((fup->fu_flags & CUF_INITED) == 0) { + if (fup->fu_ft4) + /* may not happen */ + goto done; + /* * We're just initializing device now, so see if * the initialization command has completed diff --git a/sys/dev/hfa/fore_var.h b/sys/dev/hfa/fore_var.h index 5a1533f3c2c6..62a52f3d87e6 100644 --- a/sys/dev/hfa/fore_var.h +++ b/sys/dev/hfa/fore_var.h @@ -234,6 +234,7 @@ struct fore_unit { Fore_prom *fu_promd; /* Device PROM buffer (DMA) */ #endif struct callout_handle fu_thandle; /* Timer handle */ + int fu_ft4; /* Running ForeThought 4 firmware */ }; typedef struct fore_unit Fore_unit; |
