Rename sprintf -> ksprintf
[dfdiff.git] / sys / dev / atm / hfa / fore_command.c
blob610c41a325c860e790cbc7d80197007312c697ad
1 /*
3 * ===================================
4 * HARP | Host ATM Research Platform
5 * ===================================
8 * This Host ATM Research Platform ("HARP") file (the "Software") is
9 * made available by Network Computing Services, Inc. ("NetworkCS")
10 * "AS IS". NetworkCS does not provide maintenance, improvements or
11 * support of any kind.
13 * NETWORKCS MAKES NO WARRANTIES OR REPRESENTATIONS, EXPRESS OR IMPLIED,
14 * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
15 * AND FITNESS FOR A PARTICULAR PURPOSE, AS TO ANY ELEMENT OF THE
16 * SOFTWARE OR ANY SUPPORT PROVIDED IN CONNECTION WITH THIS SOFTWARE.
17 * In no event shall NetworkCS be responsible for any damages, including
18 * but not limited to consequential damages, arising from or relating to
19 * any use of the Software or related support.
21 * Copyright 1994-1998 Network Computing Services, Inc.
23 * Copies of this Software may be made, however, the above copyright
24 * notice must be reproduced on all copies.
26 * @(#) $FreeBSD: src/sys/dev/hfa/fore_command.c,v 1.6 1999/08/28 00:41:49 peter Exp $
27 * @(#) $DragonFly: src/sys/dev/atm/hfa/fore_command.c,v 1.5 2006/12/20 18:14:38 dillon Exp $
31 * FORE Systems 200-Series Adapter Support
32 * ---------------------------------------
34 * Command queue management
38 #include "fore_include.h"
41 * Local variables
43 static struct t_atm_cause fore_cause = {
44 T_ATM_ITU_CODING,
45 T_ATM_LOC_USER,
46 T_ATM_CAUSE_TEMPORARY_FAILURE,
47 {0, 0, 0, 0}
52 * Allocate Command Queue Data Structures
54 * Arguments:
55 * fup pointer to device unit structure
57 * Returns:
58 * 0 allocations successful
59 * else allocation failed
61 int
62 fore_cmd_allocate(fup)
63 Fore_unit *fup;
65 caddr_t memp;
68 * Allocate non-cacheable memory for command status words
70 memp = atm_dev_alloc(sizeof(Q_status) * CMD_QUELEN,
71 QSTAT_ALIGN, ATM_DEV_NONCACHE);
72 if (memp == NULL) {
73 return (1);
75 fup->fu_cmd_stat = (Q_status *) memp;
77 memp = DMA_GET_ADDR(fup->fu_cmd_stat, sizeof(Q_status) * CMD_QUELEN,
78 QSTAT_ALIGN, ATM_DEV_NONCACHE);
79 if (memp == NULL) {
80 return (1);
82 fup->fu_cmd_statd = (Q_status *) memp;
85 * Allocate memory for statistics buffer
87 memp = atm_dev_alloc(sizeof(Fore_stats), FORE_STATS_ALIGN, 0);
88 if (memp == NULL) {
89 return (1);
91 fup->fu_stats = (Fore_stats *) memp;
94 * Allocate memory for PROM buffer
96 memp = atm_dev_alloc(sizeof(Fore_prom), FORE_PROM_ALIGN, 0);
97 if (memp == NULL) {
98 return (1);
100 fup->fu_prom = (Fore_prom *) memp;
102 return (0);
107 * Command Queue Initialization
109 * Allocate and initialize the host-resident command queue structures
110 * and then initialize the CP-resident queue structures.
112 * Called at interrupt level.
114 * Arguments:
115 * fup pointer to device unit structure
117 * Returns:
118 * none
120 void
121 fore_cmd_initialize(fup)
122 Fore_unit *fup;
124 Aali *aap = fup->fu_aali;
125 Cmd_queue *cqp;
126 H_cmd_queue *hcp;
127 Q_status *qsp;
128 Q_status *qsp_dma;
129 int i;
132 * Point to CP-resident command queue
134 cqp = (Cmd_queue *)(fup->fu_ram + CP_READ(aap->aali_cmd_q));
137 * Point to host-resident command queue structures
139 hcp = fup->fu_cmd_q;
140 qsp = fup->fu_cmd_stat;
141 qsp_dma = fup->fu_cmd_statd;
144 * Loop thru all queue entries and do whatever needs doing
146 for (i = 0; i < CMD_QUELEN; i++) {
149 * Set queue status word to free
151 *qsp = QSTAT_FREE;
154 * Set up host queue entry and link into ring
156 hcp->hcq_cpelem = cqp;
157 hcp->hcq_status = qsp;
158 if (i == (CMD_QUELEN - 1))
159 hcp->hcq_next = fup->fu_cmd_q;
160 else
161 hcp->hcq_next = hcp + 1;
164 * Now let the CP into the game
166 cqp->cmdq_status = (CP_dma) CP_WRITE(qsp_dma);
169 * Bump all queue pointers
171 hcp++;
172 qsp++;
173 qsp_dma++;
174 cqp++;
178 * Initialize queue pointers
180 fup->fu_cmd_head = fup->fu_cmd_tail = fup->fu_cmd_q;
182 return;
187 * Drain Command Queue
189 * This function will process and free all completed entries at the head
190 * of the command queue.
192 * May be called in interrupt state.
193 * Must be called with interrupts locked out.
195 * Arguments:
196 * fup pointer to device unit structure
198 * Returns:
199 * none
201 void
202 fore_cmd_drain(fup)
203 Fore_unit *fup;
205 H_cmd_queue *hcp;
206 Fore_vcc *fvp;
209 * Process each completed entry
211 while (*fup->fu_cmd_head->hcq_status & QSTAT_COMPLETED) {
213 hcp = fup->fu_cmd_head;
216 * Process command completion
218 switch (hcp->hcq_code) {
220 case CMD_ACT_VCCIN:
221 case CMD_ACT_VCCOUT:
222 fvp = hcp->hcq_arg;
223 if (*hcp->hcq_status & QSTAT_ERROR) {
225 * VCC activation failed - just abort vcc
227 if (fvp)
228 atm_cm_abort(fvp->fv_connvc,
229 &fore_cause);
230 fup->fu_pif.pif_cmderrors++;
231 } else {
233 * Successful VCC activation
235 if (fvp) {
236 fvp->fv_state = CVS_ACTIVE;
237 fup->fu_open_vcc++;
240 break;
242 case CMD_DACT_VCCIN:
243 case CMD_DACT_VCCOUT:
244 fvp = hcp->hcq_arg;
245 if (*hcp->hcq_status & QSTAT_ERROR) {
247 * VCC dactivation failed - whine
249 log(LOG_ERR,
250 "fore_cmd_drain: DACT failed, vcc=(%d,%d)\n",
251 fvp->fv_connvc->cvc_vcc->vc_vpi,
252 fvp->fv_connvc->cvc_vcc->vc_vci);
253 fup->fu_pif.pif_cmderrors++;
254 } else {
256 * Successful VCC dactivation - so what?
259 break;
261 case CMD_GET_STATS:
262 if (*hcp->hcq_status & QSTAT_ERROR) {
264 * Couldn't get stats
266 fup->fu_pif.pif_cmderrors++;
267 fup->fu_stats_ret = EIO;
268 } else {
270 * Stats are now in unit buffer
272 fup->fu_stats_ret = 0;
274 DMA_FREE_ADDR(fup->fu_stats, fup->fu_statsd,
275 sizeof(Fore_cp_stats), 0);
276 fup->fu_flags &= ~FUF_STATCMD;
279 * Flush received stats data
281 #ifdef VAC
282 if (vac)
283 vac_pageflush((addr_t)fup->fu_stats);
284 #endif
286 #if BYTE_ORDER == LITTLE_ENDIAN
288 * Little endian machines receives the stats in
289 * wrong byte order. Instead of swapping in user
290 * land, swap here so that everything going out
291 * of the kernel is in correct host order.
294 u_long *bp = (u_long *)fup->fu_stats;
295 int loop;
297 for ( loop = 0; loop < sizeof(Fore_cp_stats)/
298 sizeof(long); loop++, bp++ )
299 *bp = ntohl(*bp);
301 #endif /* BYTE_ORDER == LITTLE_ENDIAN */
304 * Poke whoever is waiting on the stats
306 wakeup((caddr_t)&fup->fu_stats);
307 break;
309 case CMD_GET_PROM:
310 if (*hcp->hcq_status & QSTAT_ERROR) {
312 * Couldn't get PROM data
314 fup->fu_pif.pif_cmderrors++;
315 log(LOG_ERR,
316 "fore_cmd_drain: %s%d: GET_PROM failed\n",
317 fup->fu_pif.pif_name,
318 fup->fu_pif.pif_unit);
319 } else {
320 Fore_prom *fp = fup->fu_prom;
323 * Flush received PROM data
325 #ifdef VAC
326 if (vac)
327 vac_pageflush((addr_t)fp);
328 #endif
330 * Copy PROM info into config areas
332 KM_COPY(&fp->pr_mac[2],
333 &fup->fu_pif.pif_macaddr,
334 sizeof(struct mac_addr));
335 fup->fu_config.ac_macaddr =
336 fup->fu_pif.pif_macaddr;
337 ksnprintf(fup->fu_config.ac_hard_vers,
338 sizeof(fup->fu_config.ac_hard_vers),
339 "%ld.%ld.%ld",
340 (fp->pr_hwver >> 16) & 0xff,
341 (fp->pr_hwver >> 8) & 0xff,
342 fp->pr_hwver & 0xff);
343 fup->fu_config.ac_serial = fp->pr_serno;
346 DMA_FREE_ADDR(fup->fu_prom, fup->fu_promd,
347 sizeof(Fore_prom), 0);
348 break;
350 default:
351 log(LOG_ERR, "fore_cmd_drain: unknown command %ld\n",
352 hcp->hcq_code);
356 * Mark this entry free for use and bump head pointer
357 * to the next entry in the queue
359 *hcp->hcq_status = QSTAT_FREE;
360 fup->fu_cmd_head = hcp->hcq_next;
363 return;
368 * Free Command Queue Data Structures
370 * Arguments:
371 * fup pointer to device unit structure
373 * Returns:
374 * none
376 void
377 fore_cmd_free(fup)
378 Fore_unit *fup;
380 H_cmd_queue *hcp;
383 * Deal with any commands left on the queue
385 if (fup->fu_flags & CUF_INITED) {
386 while (*fup->fu_cmd_head->hcq_status != QSTAT_FREE) {
387 hcp = fup->fu_cmd_head;
389 switch (hcp->hcq_code) {
391 case CMD_GET_STATS:
393 * Just in case someone is sleeping on this
395 fup->fu_stats_ret = EIO;
396 wakeup((caddr_t)&fup->fu_stats);
397 break;
400 *hcp->hcq_status = QSTAT_FREE;
401 fup->fu_cmd_head = hcp->hcq_next;
406 * Free the statistics buffer
408 if (fup->fu_stats) {
409 atm_dev_free(fup->fu_stats);
410 fup->fu_stats = NULL;
414 * Free the PROM buffer
416 if (fup->fu_prom) {
417 atm_dev_free(fup->fu_prom);
418 fup->fu_prom = NULL;
422 * Free the status words
424 if (fup->fu_cmd_stat) {
425 if (fup->fu_cmd_statd) {
426 DMA_FREE_ADDR(fup->fu_cmd_stat, fup->fu_cmd_statd,
427 sizeof(Q_status) * CMD_QUELEN,
428 ATM_DEV_NONCACHE);
430 atm_dev_free((volatile void *)fup->fu_cmd_stat);
431 fup->fu_cmd_stat = NULL;
432 fup->fu_cmd_statd = NULL;
435 return;