panic() cleanup.
[minix.git] / drivers / dpeth / netbuff.c
blob2e40db004c2f90d3d1fa772f7cd50c875ba121a4
1 /*
2 ** File: netbuff.c Jun. 10, 2000
3 **
4 ** Author: Giovanni Falzoni <gfalzoni@inwind.it>
5 **
6 ** This file contains specific implementation of buffering
7 ** for network packets.
8 **
9 ** $Id$
12 #include "drivers.h"
13 #include <net/gen/ether.h>
14 #include <net/gen/eth_io.h>
15 #include "dp.h"
17 #if (HAVE_BUFFERS == 1)
19 static m_hdr_t *allocptr = NULL;
20 static char tx_rx_buff[8192];
23 ** Name: void *alloc_buff(dpeth_t *dep, int size)
24 ** Function: Allocates a buffer from the common pool.
26 PUBLIC void *alloc_buff(dpeth_t *dep, int size)
28 m_hdr_t *ptr, *wrk = allocptr;
29 int units = ((size + sizeof(m_hdr_t) - 1) / sizeof(m_hdr_t)) + 1;
31 lock();
32 for (ptr = wrk->next;; wrk = ptr, ptr = ptr->next) {
33 if (ptr->size >= units) {
34 /* Memory is available, carve requested size from pool */
35 if (ptr->size == units) {
36 wrk->next = ptr->next;
37 } else {
38 /* Get memory from top address */
39 ptr->size -= units;
40 ptr += ptr->size;
41 ptr->size = units;
43 allocptr = wrk;
44 unlock();
45 return ptr + 1;
47 if (ptr == allocptr) break;
49 unlock();
50 return NULL; /* No memory available */
54 ** Name: void free_buff(dpeth_t *dep, void *blk)
55 ** Function: Returns a buffer to the common pool.
57 PUBLIC void free_buff(dpeth_t *dep, void *blk)
59 m_hdr_t *wrk, *ptr = (m_hdr_t *) blk - 1;
61 lock(); /* Scan linked list for the correct place */
62 for (wrk = allocptr; !(ptr > wrk && ptr < wrk->next); wrk = wrk->next)
63 if (wrk >= wrk->next && (ptr > wrk || ptr < wrk->next)) break;
65 /* Check if adjacent block is free and join blocks */
66 if (ptr + ptr->size == wrk->next) {
67 ptr->size += wrk->next->size;
68 ptr->next = wrk->next->next;
69 } else
70 ptr->next = wrk->next;
71 if (wrk + wrk->size == ptr) {
72 wrk->size += ptr->size;
73 wrk->next = ptr->next;
74 } else
75 wrk->next = ptr;
76 allocptr = wrk; /* Point allocptr to block just released */
77 unlock();
78 return;
82 ** Name: void init_buff(dpeth_t *dep, buff_t **tx_buff)
83 ** Function: Initalizes driver data structures.
85 PUBLIC void init_buff(dpeth_t *dep, buff_t **tx_buff)
88 /* Initializes buffer pool */
89 if (allocptr == NULL) {
90 m_hdr_t *rx = (m_hdr_t *) tx_rx_buff;
91 rx->next = allocptr = rx;
92 rx->size = 0;
93 rx += 1;
94 rx->next = NULL;
95 rx->size = (sizeof(tx_rx_buff) / sizeof(m_hdr_t)) - 1;
96 free_buff(dep, rx + 1);
97 dep->de_recvq_tail = dep->de_recvq_head = NULL;
98 if (tx_buff != NULL) {
99 *tx_buff = alloc_buff(dep, ETH_MAX_PACK_SIZE + sizeof(buff_t));
100 (*tx_buff)->size = 0;
103 return; /* Done */
107 ** Name: void mem2user(dpeth_t *dep, buff_t *rxbuff);
108 ** Function: Copies a packet from local buffer to user area.
110 PUBLIC void mem2user(dpeth_t *dep, buff_t *rxbuff)
112 int bytes, ix = 0;
113 iovec_dat_s_t *iovp = &dep->de_read_iovec;
114 int r, pktsize = rxbuff->size;
115 char *buffer = rxbuff->buffer;
117 do { /* Reads chuncks of packet into user buffers */
119 bytes = iovp->iod_iovec[ix].iov_size; /* Size of buffer */
120 if (bytes > pktsize) bytes = pktsize;
122 /* Reads from Rx buffer to user area */
123 r= sys_safecopyto(iovp->iod_proc_nr, iovp->iod_iovec[ix].iov_grant, 0,
124 (vir_bytes)buffer, bytes, D);
125 if (r != OK)
126 panic("mem2user: sys_safecopyto failed: %d", r);
127 buffer += bytes;
129 if (++ix >= IOVEC_NR) { /* Next buffer of IO vector */
130 dp_next_iovec(iovp);
131 ix = 0;
133 /* Till packet done */
134 } while ((pktsize -= bytes) > 0);
135 return;
139 ** Name: void user2mem(dpeth_t *dep, buff_t *txbuff)
140 ** Function: Copies a packet from user area to local buffer.
142 PUBLIC void user2mem(dpeth_t *dep, buff_t *txbuff)
144 int bytes, ix = 0;
145 iovec_dat_s_t *iovp = &dep->de_write_iovec;
146 int r, pktsize = txbuff->size;
147 char *buffer = txbuff->buffer;
149 do { /* Reads chuncks of packet from user buffers */
151 bytes = iovp->iod_iovec[ix].iov_size; /* Size of buffer */
152 if (bytes > pktsize) bytes = pktsize;
153 r= sys_safecopyfrom(iovp->iod_proc_nr, iovp->iod_iovec[ix].iov_grant,
154 0, (vir_bytes)buffer, bytes, D);
155 if (r != OK)
156 panic("user2mem: sys_safecopyfrom failed: %d", r);
157 buffer += bytes;
159 if (++ix >= IOVEC_NR) { /* Next buffer of IO vector */
160 dp_next_iovec(iovp);
161 ix = 0;
163 /* Till packet done */
164 } while ((pktsize -= bytes) > 0);
165 return;
168 #endif /* HAVE_BUFFERS */
170 /** netbuff.c **/