remove __P() from this directory
[dragonfly.git] / sys / dev / atm / hfa / fore_buffer.c
CommitLineData
984263bc
MD
1/*
2 *
3 * ===================================
4 * HARP | Host ATM Research Platform
5 * ===================================
6 *
7 *
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.
12 *
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.
20 *
21 * Copyright 1994-1998 Network Computing Services, Inc.
22 *
23 * Copies of this Software may be made, however, the above copyright
24 * notice must be reproduced on all copies.
25 *
26 * @(#) $FreeBSD: src/sys/dev/hfa/fore_buffer.c,v 1.5 2000/01/15 21:01:04 mks Exp $
38e94a25 27 * @(#) $DragonFly: src/sys/dev/atm/hfa/fore_buffer.c,v 1.4 2003/08/27 10:35:16 rob Exp $
984263bc
MD
28 */
29
30/*
31 * FORE Systems 200-Series Adapter Support
32 * ---------------------------------------
33 *
34 * Buffer Supply queue management
35 *
36 */
37
1f2de5d4 38#include "fore_include.h"
984263bc 39
984263bc
MD
40/*
41 * Local functions
42 */
38e94a25
RG
43static void fore_buf_drain (Fore_unit *);
44static void fore_buf_supply_1s (Fore_unit *);
45static void fore_buf_supply_1l (Fore_unit *);
984263bc
MD
46
47
48/*
49 * Allocate Buffer Supply Queues Data Structures
50 *
51 * Here we are allocating memory for both Strategy 1 Small and Large
52 * structures contiguously.
53 *
54 * Arguments:
55 * fup pointer to device unit structure
56 *
57 * Returns:
58 * 0 allocations successful
59 * else allocation failed
60 */
61int
62fore_buf_allocate(fup)
63 Fore_unit *fup;
64{
65 caddr_t memp;
66
67 /*
68 * Allocate non-cacheable memory for buffer supply status words
69 */
70 memp = atm_dev_alloc(
71 sizeof(Q_status) * (BUF1_SM_QUELEN + BUF1_LG_QUELEN),
72 QSTAT_ALIGN, ATM_DEV_NONCACHE);
73 if (memp == NULL) {
74 return (1);
75 }
76 fup->fu_buf1s_stat = (Q_status *) memp;
77 fup->fu_buf1l_stat = ((Q_status *) memp) + BUF1_SM_QUELEN;
78
79 memp = DMA_GET_ADDR(fup->fu_buf1s_stat,
80 sizeof(Q_status) * (BUF1_SM_QUELEN + BUF1_LG_QUELEN),
81 QSTAT_ALIGN, ATM_DEV_NONCACHE);
82 if (memp == NULL) {
83 return (1);
84 }
85 fup->fu_buf1s_statd = (Q_status *) memp;
86 fup->fu_buf1l_statd = ((Q_status *) memp) + BUF1_SM_QUELEN;
87
88 /*
89 * Allocate memory for buffer supply descriptors
90 */
91 memp = atm_dev_alloc(sizeof(Buf_descr) *
92 ((BUF1_SM_QUELEN * BUF1_SM_ENTSIZE) +
93 (BUF1_LG_QUELEN * BUF1_LG_ENTSIZE)),
94 BUF_DESCR_ALIGN, 0);
95 if (memp == NULL) {
96 return (1);
97 }
98 fup->fu_buf1s_desc = (Buf_descr *) memp;
99 fup->fu_buf1l_desc = ((Buf_descr *) memp) +
100 (BUF1_SM_QUELEN * BUF1_SM_ENTSIZE);
101
102 memp = DMA_GET_ADDR(fup->fu_buf1s_desc, sizeof(Buf_descr) *
103 ((BUF1_SM_QUELEN * BUF1_SM_ENTSIZE) +
104 (BUF1_LG_QUELEN * BUF1_LG_ENTSIZE)),
105 BUF_DESCR_ALIGN, 0);
106 if (memp == NULL) {
107 return (1);
108 }
109 fup->fu_buf1s_descd = (Buf_descr *) memp;
110 fup->fu_buf1l_descd = ((Buf_descr *) memp) +
111 (BUF1_SM_QUELEN * BUF1_SM_ENTSIZE);
112
113 return (0);
114}
115
116
117/*
118 * Buffer Supply Queues Initialization
119 *
120 * Allocate and initialize the host-resident buffer supply queue structures
121 * and then initialize the CP-resident queue structures.
122 *
123 * Called at interrupt level.
124 *
125 * Arguments:
126 * fup pointer to device unit structure
127 *
128 * Returns:
129 * none
130 */
131void
132fore_buf_initialize(fup)
133 Fore_unit *fup;
134{
135 Aali *aap = fup->fu_aali;
136 Buf_queue *cqp;
137 H_buf_queue *hbp;
138 Buf_descr *bdp;
139 Buf_descr *bdp_dma;
140 Q_status *qsp;
141 Q_status *qsp_dma;
142 int i;
143
144 /*
145 * Initialize Strategy 1 Small Queues
146 */
147
148 /*
149 * Point to CP-resident buffer supply queue
150 */
151 cqp = (Buf_queue *)(fup->fu_ram + CP_READ(aap->aali_buf1s_q));
152
153 /*
154 * Point to host-resident buffer supply queue structures
155 */
156 hbp = fup->fu_buf1s_q;
157 qsp = fup->fu_buf1s_stat;
158 qsp_dma = fup->fu_buf1s_statd;
159 bdp = fup->fu_buf1s_desc;
160 bdp_dma = fup->fu_buf1s_descd;
161
162 /*
163 * Loop thru all queue entries and do whatever needs doing
164 */
165 for (i = 0; i < BUF1_SM_QUELEN; i++) {
166
167 /*
168 * Set queue status word to free
169 */
170 *qsp = QSTAT_FREE;
171
172 /*
173 * Set up host queue entry and link into ring
174 */
175 hbp->hbq_cpelem = cqp;
176 hbp->hbq_status = qsp;
177 hbp->hbq_descr = bdp;
178 hbp->hbq_descr_dma = bdp_dma;
179 if (i == (BUF1_SM_QUELEN - 1))
180 hbp->hbq_next = fup->fu_buf1s_q;
181 else
182 hbp->hbq_next = hbp + 1;
183
184 /*
185 * Now let the CP into the game
186 */
187 cqp->cq_status = (CP_dma) CP_WRITE(qsp_dma);
188
189 /*
190 * Bump all queue pointers
191 */
192 hbp++;
193 qsp++;
194 qsp_dma++;
195 bdp += BUF1_SM_ENTSIZE;
196 bdp_dma += BUF1_SM_ENTSIZE;
197 cqp++;
198 }
199
200 /*
201 * Initialize queue pointers
202 */
203 fup->fu_buf1s_head = fup->fu_buf1s_tail = fup->fu_buf1s_q;
204
205
206 /*
207 * Initialize Strategy 1 Large Queues
208 */
209
210 /*
211 * Point to CP-resident buffer supply queue
212 */
213 cqp = (Buf_queue *)(fup->fu_ram + CP_READ(aap->aali_buf1l_q));
214
215 /*
216 * Point to host-resident buffer supply queue structures
217 */
218 hbp = fup->fu_buf1l_q;
219 qsp = fup->fu_buf1l_stat;
220 qsp_dma = fup->fu_buf1l_statd;
221 bdp = fup->fu_buf1l_desc;
222 bdp_dma = fup->fu_buf1l_descd;
223
224 /*
225 * Loop thru all queue entries and do whatever needs doing
226 */
227 for (i = 0; i < BUF1_LG_QUELEN; i++) {
228
229 /*
230 * Set queue status word to free
231 */
232 *qsp = QSTAT_FREE;
233
234 /*
235 * Set up host queue entry and link into ring
236 */
237 hbp->hbq_cpelem = cqp;
238 hbp->hbq_status = qsp;
239 hbp->hbq_descr = bdp;
240 hbp->hbq_descr_dma = bdp_dma;
241 if (i == (BUF1_LG_QUELEN - 1))
242 hbp->hbq_next = fup->fu_buf1l_q;
243 else
244 hbp->hbq_next = hbp + 1;
245
246 /*
247 * Now let the CP into the game
248 */
249 cqp->cq_status = (CP_dma) CP_WRITE(qsp_dma);
250
251 /*
252 * Bump all queue pointers
253 */
254 hbp++;
255 qsp++;
256 qsp_dma++;
257 bdp += BUF1_LG_ENTSIZE;
258 bdp_dma += BUF1_LG_ENTSIZE;
259 cqp++;
260 }
261
262 /*
263 * Initialize queue pointers
264 */
265 fup->fu_buf1l_head = fup->fu_buf1l_tail = fup->fu_buf1l_q;
266
267 return;
268}
269
270
271/*
272 * Supply Buffers to CP
273 *
274 * This function will resupply the CP with buffers to be used to
275 * store incoming data.
276 *
277 * May be called in interrupt state.
278 * Must be called with interrupts locked out.
279 *
280 * Arguments:
281 * fup pointer to device unit structure
282 *
283 * Returns:
284 * none
285 */
286void
287fore_buf_supply(fup)
288 Fore_unit *fup;
289{
290
291 /*
292 * First, clean out the supply queues
293 */
294 fore_buf_drain(fup);
295
296 /*
297 * Then, supply the buffers for each queue
298 */
299 fore_buf_supply_1s(fup);
300 fore_buf_supply_1l(fup);
301
302 return;
303}
304
305
306/*
307 * Supply Strategy 1 Small Buffers to CP
308 *
309 * May be called in interrupt state.
310 * Must be called with interrupts locked out.
311 *
312 * Arguments:
313 * fup pointer to device unit structure
314 *
315 * Returns:
316 * none
317 */
318static void
319fore_buf_supply_1s(fup)
320 Fore_unit *fup;
321{
322 H_buf_queue *hbp;
323 Buf_queue *cqp;
324 Buf_descr *bdp;
325 Buf_handle *bhp;
326 KBuffer *m;
327 int nvcc, nbuf, i;
328
329 /*
330 * Figure out how many buffers we should be giving to the CP.
331 * We're basing this calculation on the current number of open
332 * VCCs thru this device, with certain minimum and maximum values
333 * enforced. This will then allow us to figure out how many more
334 * buffers we need to supply to the CP. This will be rounded up
335 * to fill a supply queue entry.
336 */
337 nvcc = MAX(fup->fu_open_vcc, BUF_MIN_VCC);
338 nbuf = nvcc * 4;
339 nbuf = MIN(nbuf, BUF1_SM_CPPOOL);
340 nbuf -= fup->fu_buf1s_cnt;
341 nbuf = roundup(nbuf, BUF1_SM_ENTSIZE);
342
343 /*
344 * OK, now supply the buffers to the CP
345 */
346 while (nbuf > 0) {
347
348 /*
349 * Acquire a supply queue entry
350 */
351 hbp = fup->fu_buf1s_tail;
352 if (!((*hbp->hbq_status) & QSTAT_FREE))
353 break;
354 bdp = hbp->hbq_descr;
355
356 /*
357 * Get a buffer for each descriptor in the queue entry
358 */
359 for (i = 0; i < BUF1_SM_ENTSIZE; i++, bdp++) {
360 caddr_t cp;
361
362 /*
363 * Get a small buffer
364 */
365 KB_ALLOCPKT(m, BUF1_SM_SIZE, KB_F_NOWAIT, KB_T_DATA);
366 if (m == 0) {
367 break;
368 }
369 KB_HEADSET(m, BUF1_SM_DOFF);
370
371 /*
372 * Point to buffer handle structure
373 */
374 bhp = (Buf_handle *)((caddr_t)m + BUF1_SM_HOFF);
375 bhp->bh_type = BHT_S1_SMALL;
376
377 /*
378 * Setup buffer descriptor
379 */
380 bdp->bsd_handle = bhp;
381 KB_DATASTART(m, cp, caddr_t);
382 bhp->bh_dma = bdp->bsd_buffer = (H_dma) DMA_GET_ADDR(
383 cp, BUF1_SM_SIZE, BUF_DATA_ALIGN, 0);
384 if (bdp->bsd_buffer == NULL) {
385 /*
386 * Unable to assign dma address - free up
387 * this descriptor's buffer
388 */
389 fup->fu_stats->st_drv.drv_bf_segdma++;
390 KB_FREEALL(m);
391 break;
392 }
393
394 /*
395 * All set, so queue buffer (handle)
396 */
397 ENQUEUE(bhp, Buf_handle, bh_qelem, fup->fu_buf1s_bq);
398 }
399
400 /*
401 * If we we're not able to fill all the descriptors for
402 * an entry, free up what's been partially built
403 */
404 if (i != BUF1_SM_ENTSIZE) {
405 caddr_t cp;
406
407 /*
408 * Clean up each used descriptor
409 */
410 for (bdp = hbp->hbq_descr; i; i--, bdp++) {
411
412 bhp = bdp->bsd_handle;
413
414 DEQUEUE(bhp, Buf_handle, bh_qelem,
415 fup->fu_buf1s_bq);
416
417 m = (KBuffer *)
418 ((caddr_t)bhp - BUF1_SM_HOFF);
419 KB_DATASTART(m, cp, caddr_t);
420 DMA_FREE_ADDR(cp, bhp->bh_dma, BUF1_SM_SIZE, 0);
421 KB_FREEALL(m);
422 }
423 break;
424 }
425
426 /*
427 * Finally, we've got an entry ready for the CP.
428 * So claim the host queue entry and setup the CP-resident
429 * queue entry. The CP will (potentially) grab the supplied
430 * buffers when the descriptor pointer is set.
431 */
432 fup->fu_buf1s_tail = hbp->hbq_next;
433 (*hbp->hbq_status) = QSTAT_PENDING;
434 cqp = hbp->hbq_cpelem;
435 cqp->cq_descr = (CP_dma) CP_WRITE((u_long)hbp->hbq_descr_dma);
436
437 /*
438 * Update counters, etc for supplied buffers
439 */
440 fup->fu_buf1s_cnt += BUF1_SM_ENTSIZE;
441 nbuf -= BUF1_SM_ENTSIZE;
442 }
443
444 return;
445}
446
447
448/*
449 * Supply Strategy 1 Large Buffers to CP
450 *
451 * May be called in interrupt state.
452 * Must be called with interrupts locked out.
453 *
454 * Arguments:
455 * fup pointer to device unit structure
456 *
457 * Returns:
458 * none
459 */
460static void
461fore_buf_supply_1l(fup)
462 Fore_unit *fup;
463{
464 H_buf_queue *hbp;
465 Buf_queue *cqp;
466 Buf_descr *bdp;
467 Buf_handle *bhp;
468 KBuffer *m;
469 int nvcc, nbuf, i;
470
471 /*
472 * Figure out how many buffers we should be giving to the CP.
473 * We're basing this calculation on the current number of open
474 * VCCs thru this device, with certain minimum and maximum values
475 * enforced. This will then allow us to figure out how many more
476 * buffers we need to supply to the CP. This will be rounded up
477 * to fill a supply queue entry.
478 */
479 nvcc = MAX(fup->fu_open_vcc, BUF_MIN_VCC);
480 nbuf = nvcc * 4 * RECV_MAX_SEGS;
481 nbuf = MIN(nbuf, BUF1_LG_CPPOOL);
482 nbuf -= fup->fu_buf1l_cnt;
483 nbuf = roundup(nbuf, BUF1_LG_ENTSIZE);
484
485 /*
486 * OK, now supply the buffers to the CP
487 */
488 while (nbuf > 0) {
489
490 /*
491 * Acquire a supply queue entry
492 */
493 hbp = fup->fu_buf1l_tail;
494 if (!((*hbp->hbq_status) & QSTAT_FREE))
495 break;
496 bdp = hbp->hbq_descr;
497
498 /*
499 * Get a buffer for each descriptor in the queue entry
500 */
501 for (i = 0; i < BUF1_LG_ENTSIZE; i++, bdp++) {
502 caddr_t cp;
503
504 /*
505 * Get a cluster buffer
506 */
507 KB_ALLOCEXT(m, BUF1_LG_SIZE, KB_F_NOWAIT, KB_T_DATA);
508 if (m == 0) {
509 break;
510 }
511 KB_HEADSET(m, BUF1_LG_DOFF);
512
513 /*
514 * Point to buffer handle structure
515 */
516 bhp = (Buf_handle *)((caddr_t)m + BUF1_LG_HOFF);
517 bhp->bh_type = BHT_S1_LARGE;
518
519 /*
520 * Setup buffer descriptor
521 */
522 bdp->bsd_handle = bhp;
523 KB_DATASTART(m, cp, caddr_t);
524 bhp->bh_dma = bdp->bsd_buffer = (H_dma) DMA_GET_ADDR(
525 cp, BUF1_LG_SIZE, BUF_DATA_ALIGN, 0);
526 if (bdp->bsd_buffer == NULL) {
527 /*
528 * Unable to assign dma address - free up
529 * this descriptor's buffer
530 */
531 fup->fu_stats->st_drv.drv_bf_segdma++;
532 KB_FREEALL(m);
533 break;
534 }
535
536 /*
537 * All set, so queue buffer (handle)
538 */
539 ENQUEUE(bhp, Buf_handle, bh_qelem, fup->fu_buf1l_bq);
540 }
541
542 /*
543 * If we we're not able to fill all the descriptors for
544 * an entry, free up what's been partially built
545 */
546 if (i != BUF1_LG_ENTSIZE) {
547 caddr_t cp;
548
549 /*
550 * Clean up each used descriptor
551 */
552 for (bdp = hbp->hbq_descr; i; i--, bdp++) {
553 bhp = bdp->bsd_handle;
554
555 DEQUEUE(bhp, Buf_handle, bh_qelem,
556 fup->fu_buf1l_bq);
557
558 m = (KBuffer *)
559 ((caddr_t)bhp - BUF1_LG_HOFF);
560 KB_DATASTART(m, cp, caddr_t);
561 DMA_FREE_ADDR(cp, bhp->bh_dma, BUF1_LG_SIZE, 0);
562 KB_FREEALL(m);
563 }
564 break;
565 }
566
567 /*
568 * Finally, we've got an entry ready for the CP.
569 * So claim the host queue entry and setup the CP-resident
570 * queue entry. The CP will (potentially) grab the supplied
571 * buffers when the descriptor pointer is set.
572 */
573 fup->fu_buf1l_tail = hbp->hbq_next;
574 (*hbp->hbq_status) = QSTAT_PENDING;
575 cqp = hbp->hbq_cpelem;
576 cqp->cq_descr = (CP_dma) CP_WRITE((u_long)hbp->hbq_descr_dma);
577
578 /*
579 * Update counters, etc for supplied buffers
580 */
581 fup->fu_buf1l_cnt += BUF1_LG_ENTSIZE;
582 nbuf -= BUF1_LG_ENTSIZE;
583 }
584
585 return;
586}
587
588
589/*
590 * Drain Buffer Supply Queues
591 *
592 * This function will free all completed entries at the head of each
593 * buffer supply queue. Since we consider the CP to "own" the buffers
594 * once we put them on a supply queue and since a completed supply queue
595 * entry is only telling us that the CP has accepted the buffers that we
596 * gave to it, there's not much to do here.
597 *
598 * May be called in interrupt state.
599 * Must be called with interrupts locked out.
600 *
601 * Arguments:
602 * fup pointer to device unit structure
603 *
604 * Returns:
605 * none
606 */
607static void
608fore_buf_drain(fup)
609 Fore_unit *fup;
610{
611 H_buf_queue *hbp;
612
613 /*
614 * Drain Strategy 1 Small Queue
615 */
616
617 /*
618 * Process each completed entry
619 */
620 while (*fup->fu_buf1s_head->hbq_status & QSTAT_COMPLETED) {
621
622 hbp = fup->fu_buf1s_head;
623
624 if (*hbp->hbq_status & QSTAT_ERROR) {
625 /*
626 * XXX - what does this mean???
627 */
628 log(LOG_ERR, "fore_buf_drain: buf1s queue error\n");
629 }
630
631 /*
632 * Mark this entry free for use and bump head pointer
633 * to the next entry in the queue
634 */
635 *hbp->hbq_status = QSTAT_FREE;
636 fup->fu_buf1s_head = hbp->hbq_next;
637 }
638
639
640 /*
641 * Drain Strategy 1 Large Queue
642 */
643
644 /*
645 * Process each completed entry
646 */
647 while (*fup->fu_buf1l_head->hbq_status & QSTAT_COMPLETED) {
648
649 hbp = fup->fu_buf1l_head;
650
651 if (*hbp->hbq_status & QSTAT_ERROR) {
652 /*
653 * XXX - what does this mean???
654 */
655 log(LOG_ERR, "fore_buf_drain: buf1l queue error\n");
656 }
657
658 /*
659 * Mark this entry free for use and bump head pointer
660 * to the next entry in the queue
661 */
662 *hbp->hbq_status = QSTAT_FREE;
663 fup->fu_buf1l_head = hbp->hbq_next;
664 }
665
666 return;
667}
668
669
670/*
671 * Free Buffer Supply Queue Data Structures
672 *
673 * Arguments:
674 * fup pointer to device unit structure
675 *
676 * Returns:
677 * none
678 */
679void
680fore_buf_free(fup)
681 Fore_unit *fup;
682{
683 Buf_handle *bhp;
684 KBuffer *m;
685
686 /*
687 * Free any previously supplied and not returned buffers
688 */
689 if (fup->fu_flags & CUF_INITED) {
690
691 /*
692 * Run through Strategy 1 Small queue
693 */
694 while ((bhp = Q_HEAD(fup->fu_buf1s_bq, Buf_handle)) != NULL) {
695 caddr_t cp;
696
697 /*
698 * Back off to buffer
699 */
700 m = (KBuffer *)((caddr_t)bhp - BUF1_SM_HOFF);
701
702 /*
703 * Dequeue handle and free buffer
704 */
705 DEQUEUE(bhp, Buf_handle, bh_qelem, fup->fu_buf1s_bq);
706
707 KB_DATASTART(m, cp, caddr_t);
708 DMA_FREE_ADDR(cp, bhp->bh_dma, BUF1_SM_SIZE, 0);
709
710 KB_FREEALL(m);
711 }
712
713 /*
714 * Run through Strategy 1 Large queue
715 */
716 while ((bhp = Q_HEAD(fup->fu_buf1l_bq, Buf_handle)) != NULL) {
717 caddr_t cp;
718
719 /*
720 * Back off to buffer
721 */
722 m = (KBuffer *)((caddr_t)bhp - BUF1_LG_HOFF);
723
724 /*
725 * Dequeue handle and free buffer
726 */
727 DEQUEUE(bhp, Buf_handle, bh_qelem, fup->fu_buf1l_bq);
728
729 KB_DATASTART(m, cp, caddr_t);
730 DMA_FREE_ADDR(cp, bhp->bh_dma, BUF1_LG_SIZE, 0);
731
732 KB_FREEALL(m);
733 }
734 }
735
736 /*
737 * Free the status words
738 */
739 if (fup->fu_buf1s_stat) {
740 if (fup->fu_buf1s_statd) {
741 DMA_FREE_ADDR(fup->fu_buf1s_stat, fup->fu_buf1s_statd,
742 sizeof(Q_status) *
743 (BUF1_SM_QUELEN + BUF1_LG_QUELEN),
744 ATM_DEV_NONCACHE);
745 }
746 atm_dev_free((volatile void *)fup->fu_buf1s_stat);
747 fup->fu_buf1s_stat = NULL;
748 fup->fu_buf1s_statd = NULL;
749 fup->fu_buf1l_stat = NULL;
750 fup->fu_buf1l_statd = NULL;
751 }
752
753 /*
754 * Free the transmit descriptors
755 */
756 if (fup->fu_buf1s_desc) {
757 if (fup->fu_buf1s_descd) {
758 DMA_FREE_ADDR(fup->fu_buf1s_desc, fup->fu_buf1s_descd,
759 sizeof(Buf_descr) *
760 ((BUF1_SM_QUELEN * BUF1_SM_ENTSIZE) +
761 (BUF1_LG_QUELEN * BUF1_LG_ENTSIZE)),
762 0);
763 }
764 atm_dev_free(fup->fu_buf1s_desc);
765 fup->fu_buf1s_desc = NULL;
766 fup->fu_buf1s_descd = NULL;
767 fup->fu_buf1l_desc = NULL;
768 fup->fu_buf1l_descd = NULL;
769 }
770
771 return;
772}
773