kernel: vm kernel call can't suspend
[minix.git] / drivers / dpeth / netbuff.c
blobe190048d3af6872437dea9b2de5d951766655f21
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 */
10 #include <minix/drivers.h>
11 #include <net/gen/ether.h>
12 #include <net/gen/eth_io.h>
13 #include "dp.h"
15 #if (HAVE_BUFFERS == 1)
17 static m_hdr_t *allocptr = NULL;
18 static char tx_rx_buff[8192];
21 ** Name: void *alloc_buff(dpeth_t *dep, int size)
22 ** Function: Allocates a buffer from the common pool.
24 void *alloc_buff(dpeth_t *dep, int size)
26 m_hdr_t *ptr, *wrk = allocptr;
27 int units = ((size + sizeof(m_hdr_t) - 1) / sizeof(m_hdr_t)) + 1;
29 lock();
30 for (ptr = wrk->next;; wrk = ptr, ptr = ptr->next) {
31 if (ptr->size >= units) {
32 /* Memory is available, carve requested size from pool */
33 if (ptr->size == units) {
34 wrk->next = ptr->next;
35 } else {
36 /* Get memory from top address */
37 ptr->size -= units;
38 ptr += ptr->size;
39 ptr->size = units;
41 allocptr = wrk;
42 unlock();
43 return ptr + 1;
45 if (ptr == allocptr) break;
47 unlock();
48 return NULL; /* No memory available */
52 ** Name: void free_buff(dpeth_t *dep, void *blk)
53 ** Function: Returns a buffer to the common pool.
55 void free_buff(dpeth_t *dep, void *blk)
57 m_hdr_t *wrk, *ptr = (m_hdr_t *) blk - 1;
59 lock(); /* Scan linked list for the correct place */
60 for (wrk = allocptr; !(ptr > wrk && ptr < wrk->next); wrk = wrk->next)
61 if (wrk >= wrk->next && (ptr > wrk || ptr < wrk->next)) break;
63 /* Check if adjacent block is free and join blocks */
64 if (ptr + ptr->size == wrk->next) {
65 ptr->size += wrk->next->size;
66 ptr->next = wrk->next->next;
67 } else
68 ptr->next = wrk->next;
69 if (wrk + wrk->size == ptr) {
70 wrk->size += ptr->size;
71 wrk->next = ptr->next;
72 } else
73 wrk->next = ptr;
74 allocptr = wrk; /* Point allocptr to block just released */
75 unlock();
76 return;
80 ** Name: void init_buff(dpeth_t *dep, buff_t **tx_buff)
81 ** Function: Initalizes driver data structures.
83 void init_buff(dpeth_t *dep, buff_t **tx_buff)
86 /* Initializes buffer pool */
87 if (allocptr == NULL) {
88 m_hdr_t *rx = (m_hdr_t *) tx_rx_buff;
89 rx->next = allocptr = rx;
90 rx->size = 0;
91 rx += 1;
92 rx->next = NULL;
93 rx->size = (sizeof(tx_rx_buff) / sizeof(m_hdr_t)) - 1;
94 free_buff(dep, rx + 1);
95 dep->de_recvq_tail = dep->de_recvq_head = NULL;
96 if (tx_buff != NULL) {
97 *tx_buff = alloc_buff(dep, ETH_MAX_PACK_SIZE + sizeof(buff_t));
98 (*tx_buff)->size = 0;
101 return; /* Done */
105 ** Name: void mem2user(dpeth_t *dep, buff_t *rxbuff);
106 ** Function: Copies a packet from local buffer to user area.
108 void mem2user(dpeth_t *dep, buff_t *rxbuff)
110 int bytes, ix = 0;
111 iovec_dat_s_t *iovp = &dep->de_read_iovec;
112 int r, pktsize = rxbuff->size;
113 char *buffer = rxbuff->buffer;
115 do { /* Reads chuncks of packet into user buffers */
117 bytes = iovp->iod_iovec[ix].iov_size; /* Size of buffer */
118 if (bytes > pktsize) bytes = pktsize;
120 /* Reads from Rx buffer to user area */
121 r= sys_safecopyto(iovp->iod_proc_nr, iovp->iod_iovec[ix].iov_grant, 0,
122 (vir_bytes)buffer, bytes);
123 if (r != OK)
124 panic("mem2user: sys_safecopyto failed: %d", r);
125 buffer += bytes;
127 if (++ix >= IOVEC_NR) { /* Next buffer of IO vector */
128 dp_next_iovec(iovp);
129 ix = 0;
131 /* Till packet done */
132 } while ((pktsize -= bytes) > 0);
133 return;
137 ** Name: void user2mem(dpeth_t *dep, buff_t *txbuff)
138 ** Function: Copies a packet from user area to local buffer.
140 void user2mem(dpeth_t *dep, buff_t *txbuff)
142 int bytes, ix = 0;
143 iovec_dat_s_t *iovp = &dep->de_write_iovec;
144 int r, pktsize = txbuff->size;
145 char *buffer = txbuff->buffer;
147 do { /* Reads chuncks of packet from user buffers */
149 bytes = iovp->iod_iovec[ix].iov_size; /* Size of buffer */
150 if (bytes > pktsize) bytes = pktsize;
151 r= sys_safecopyfrom(iovp->iod_proc_nr, iovp->iod_iovec[ix].iov_grant,
152 0, (vir_bytes)buffer, bytes);
153 if (r != OK)
154 panic("user2mem: sys_safecopyfrom failed: %d", r);
155 buffer += bytes;
157 if (++ix >= IOVEC_NR) { /* Next buffer of IO vector */
158 dp_next_iovec(iovp);
159 ix = 0;
161 /* Till packet done */
162 } while ((pktsize -= bytes) > 0);
163 return;
166 #endif /* HAVE_BUFFERS */
168 /** netbuff.c **/