source: mainline/uspace/srv/hw/netif/dp8390/dp8390.c@ 8f5e2527

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 8f5e2527 was 8f5e2527, checked in by Martin Decky <martin@…>, 14 years ago

remove unnecessary clutter

  • Property mode set to 100644
File size: 34.9 KB
Line 
1/** @addtogroup dp8390
2 * @{
3 */
4
5/** @file
6 * DP8390 network interface core implementation.
7 */
8
9#include <assert.h>
10#include <byteorder.h>
11#include <errno.h>
12
13#include <netif_local.h>
14#include <net/packet.h>
15#include <packet_client.h>
16
17#include "dp8390_drv.h"
18#include "dp8390_port.h"
19
20#include "local.h"
21#include "dp8390.h"
22
23/** Queues the outgoing packet.
24 * @param[in] dep The network interface structure.
25 * @param[in] packet The outgoing packet.
26 * @return EOK on success.
27 * @return EINVAL
28 */
29int queue_packet(dpeth_t * dep, packet_t *packet);
30
31/** Reads a memory block byte by byte.
32 * @param[in] port The source address.
33 * @param[out] buf The destination buffer.
34 * @param[in] size The memory block size in bytes.
35 */
36static void outsb(port_t port, void * buf, size_t size);
37
38/** Reads a memory block word by word.
39 * @param[in] port The source address.
40 * @param[out] buf The destination buffer.
41 * @param[in] size The memory block size in bytes.
42 */
43static void outsw(port_t port, void * buf, size_t size);
44
45/* Some clones of the dp8390 and the PC emulator 'Bochs' require the CR_STA
46 * on writes to the CR register. Additional CR_STAs do not appear to hurt
47 * genuine dp8390s
48 */
49#define CR_EXTRA CR_STA
50
51_PROTOTYPE(static void dp_init, (dpeth_t *dep) );
52_PROTOTYPE(static void dp_reinit, (dpeth_t *dep) );
53_PROTOTYPE(static void dp_reset, (dpeth_t *dep) );
54_PROTOTYPE(static void dp_recv, (dpeth_t *dep) );
55_PROTOTYPE(static void dp_send, (dpeth_t *dep) );
56_PROTOTYPE(static void dp_pio8_getblock, (dpeth_t *dep, int page,
57 size_t offset, size_t size, void *dst) );
58_PROTOTYPE(static void dp_pio16_getblock, (dpeth_t *dep, int page,
59 size_t offset, size_t size, void *dst) );
60_PROTOTYPE(static int dp_pkt2user, (dpeth_t *dep, int page,
61 int length) );
62_PROTOTYPE(static void dp_pio8_user2nic, (dpeth_t *dep,
63 iovec_dat_t *iovp, vir_bytes offset,
64 int nic_addr, vir_bytes count) );
65_PROTOTYPE(static void dp_pio16_user2nic, (dpeth_t *dep,
66 iovec_dat_t *iovp, vir_bytes offset,
67 int nic_addr, vir_bytes count) );
68_PROTOTYPE(static void dp_pio8_nic2user, (dpeth_t *dep, int nic_addr,
69 iovec_dat_t *iovp, vir_bytes offset, vir_bytes count) );
70_PROTOTYPE(static void dp_pio16_nic2user, (dpeth_t *dep, int nic_addr,
71 iovec_dat_t *iovp, vir_bytes offset, vir_bytes count) );
72_PROTOTYPE(static void dp_next_iovec, (iovec_dat_t *iovp) );
73_PROTOTYPE(static void conf_hw, (dpeth_t *dep) );
74_PROTOTYPE(static void reply, (dpeth_t *dep, int err, int may_block) );
75_PROTOTYPE(static void get_userdata, (int user_proc,
76 vir_bytes user_addr, vir_bytes count, void *loc_addr) );
77_PROTOTYPE(static void insb, (port_t port, void *buf, size_t size) );
78_PROTOTYPE(static void insw, (port_t port, void *buf, size_t size) );
79
80int do_probe(dpeth_t * dep){
81 /* This is the default, try to (re)locate the device. */
82 conf_hw(dep);
83 if (dep->de_mode == DEM_DISABLED)
84 {
85 /* Probe failed, or the device is configured off. */
86 return EXDEV;//ENXIO;
87 }
88 if (dep->de_mode == DEM_ENABLED)
89 dp_init(dep);
90 return EOK;
91}
92
93/*===========================================================================*
94 * dp8390_dump *
95 *===========================================================================*/
96void dp8390_dump(dpeth_t * dep)
97{
98// dpeth_t *dep;
99 int /*i,*/ isr;
100
101// printf("\n");
102// for (i= 0, dep = &de_table[0]; i<DE_PORT_NR; i++, dep++)
103// {
104#if XXX
105 if (dep->de_mode == DEM_DISABLED)
106 printf("dp8390 port %d is disabled\n", i);
107 else if (dep->de_mode == DEM_SINK)
108 printf("dp8390 port %d is in sink mode\n", i);
109#endif
110
111 if (dep->de_mode != DEM_ENABLED)
112// continue;
113 return;
114
115// printf("dp8390 statistics of port %d:\n", i);
116
117 printf("recvErr :%8ld\t", dep->de_stat.ets_recvErr);
118 printf("sendErr :%8ld\t", dep->de_stat.ets_sendErr);
119 printf("OVW :%8ld\n", dep->de_stat.ets_OVW);
120
121 printf("CRCerr :%8ld\t", dep->de_stat.ets_CRCerr);
122 printf("frameAll :%8ld\t", dep->de_stat.ets_frameAll);
123 printf("missedP :%8ld\n", dep->de_stat.ets_missedP);
124
125 printf("packetR :%8ld\t", dep->de_stat.ets_packetR);
126 printf("packetT :%8ld\t", dep->de_stat.ets_packetT);
127 printf("transDef :%8ld\n", dep->de_stat.ets_transDef);
128
129 printf("collision :%8ld\t", dep->de_stat.ets_collision);
130 printf("transAb :%8ld\t", dep->de_stat.ets_transAb);
131 printf("carrSense :%8ld\n", dep->de_stat.ets_carrSense);
132
133 printf("fifoUnder :%8ld\t", dep->de_stat.ets_fifoUnder);
134 printf("fifoOver :%8ld\t", dep->de_stat.ets_fifoOver);
135 printf("CDheartbeat:%8ld\n", dep->de_stat.ets_CDheartbeat);
136
137 printf("OWC :%8ld\t", dep->de_stat.ets_OWC);
138
139 isr= inb_reg0(dep, DP_ISR);
140 printf("dp_isr = 0x%x + 0x%x, de_flags = 0x%x\n", isr,
141 inb_reg0(dep, DP_ISR), dep->de_flags);
142// }
143}
144
145/*===========================================================================*
146 * do_init *
147 *===========================================================================*/
148int do_init(dpeth_t * dep, int mode){
149 if (dep->de_mode == DEM_DISABLED)
150 {
151 // might call do_probe()
152 return EXDEV;
153 }
154
155 if (dep->de_mode == DEM_SINK)
156 {
157// strncpy((char *) dep->de_address.ea_addr, "ZDP", 6);
158// dep->de_address.ea_addr[5] = port;
159// dp_confaddr(dep);
160// reply_mess.m_type = DL_CONF_REPLY;
161// reply_mess.m3_i1 = mp->DL_PORT;
162// reply_mess.m3_i2 = DE_PORT_NR;
163// *(ether_addr_t *) reply_mess.m3_ca1 = dep->de_address;
164// mess_reply(mp, &reply_mess);
165// return;
166 return EOK;
167 }
168 assert(dep->de_mode == DEM_ENABLED);
169 assert(dep->de_flags &DEF_ENABLED);
170
171 dep->de_flags &= ~(DEF_PROMISC | DEF_MULTI | DEF_BROAD);
172
173 if (mode &DL_PROMISC_REQ)
174 dep->de_flags |= DEF_PROMISC | DEF_MULTI | DEF_BROAD;
175 if (mode &DL_MULTI_REQ)
176 dep->de_flags |= DEF_MULTI;
177 if (mode &DL_BROAD_REQ)
178 dep->de_flags |= DEF_BROAD;
179
180// dep->de_client = mp->m_source;
181 dp_reinit(dep);
182
183// reply_mess.m_type = DL_CONF_REPLY;
184// reply_mess.m3_i1 = mp->DL_PORT;
185// reply_mess.m3_i2 = DE_PORT_NR;
186// *(ether_addr_t *) reply_mess.m3_ca1 = dep->de_address;
187
188// mess_reply(mp, &reply_mess);
189 return EOK;
190}
191
192/*===========================================================================*
193 * do_stop *
194 *===========================================================================*/
195void do_stop(dpeth_t * dep){
196 if((dep->de_mode != DEM_SINK) && (dep->de_mode == DEM_ENABLED) && (dep->de_flags &DEF_ENABLED)){
197 outb_reg0(dep, DP_CR, CR_STP | CR_DM_ABORT);
198 (dep->de_stopf)(dep);
199
200 dep->de_flags = DEF_EMPTY;
201 }
202}
203
204int queue_packet(dpeth_t * dep, packet_t *packet){
205 packet_t *tmp;
206
207 if(dep->packet_count >= MAX_PACKETS){
208 netif_pq_release(packet_get_id(packet));
209 return ELIMIT;
210 }
211
212 tmp = dep->packet_queue;
213 while(pq_next(tmp)){
214 tmp = pq_next(tmp);
215 }
216 if(pq_add(&tmp, packet, 0, 0) != EOK){
217 return EINVAL;
218 }
219 if(! dep->packet_count){
220 dep->packet_queue = packet;
221 }
222 ++ dep->packet_count;
223 return EBUSY;
224}
225
226/*===========================================================================*
227 * based on do_vwrite *
228 *===========================================================================*/
229int do_pwrite(dpeth_t * dep, packet_t *packet, int from_int)
230{
231// int port, count, size;
232 int size;
233 int sendq_head;
234/* dpeth_t *dep;
235
236 port = mp->DL_PORT;
237 count = mp->DL_COUNT;
238 if (port < 0 || port >= DE_PORT_NR)
239 panic("", "dp8390: illegal port", port);
240 dep= &de_table[port];
241 dep->de_client= mp->DL_PROC;
242*/
243 if (dep->de_mode == DEM_SINK)
244 {
245 assert(!from_int);
246// dep->de_flags |= DEF_PACK_SEND;
247 reply(dep, OK, FALSE);
248// return;
249 return EOK;
250 }
251 assert(dep->de_mode == DEM_ENABLED);
252 assert(dep->de_flags &DEF_ENABLED);
253 if(dep->packet_queue && (! from_int)){
254// if (dep->de_flags &DEF_SEND_AVAIL){
255// panic("", "dp8390: send already in progress", NO_NUM);
256 return queue_packet(dep, packet);
257 }
258
259 sendq_head= dep->de_sendq_head;
260// if (dep->de_sendq[sendq_head].sq_filled)
261// {
262// if (from_int)
263// panic("", "dp8390: should not be sending\n", NO_NUM);
264// dep->de_sendmsg= *mp;
265// dep->de_flags |= DEF_SEND_AVAIL;
266// reply(dep, OK, FALSE);
267// return;
268// return queue_packet(dep, packet);
269// }
270// assert(!(dep->de_flags &DEF_PACK_SEND));
271
272/* if (vectored)
273 {
274 get_userdata(mp->DL_PROC, (vir_bytes) mp->DL_ADDR,
275 (count > IOVEC_NR ? IOVEC_NR : count) *
276 sizeof(iovec_t), dep->de_write_iovec.iod_iovec);
277 dep->de_write_iovec.iod_iovec_s = count;
278 dep->de_write_iovec.iod_proc_nr = mp->DL_PROC;
279 dep->de_write_iovec.iod_iovec_addr = (vir_bytes) mp->DL_ADDR;
280
281 dep->de_tmp_iovec = dep->de_write_iovec;
282 size = calc_iovec_size(&dep->de_tmp_iovec);
283 }
284 else
285 {
286 dep->de_write_iovec.iod_iovec[0].iov_addr =
287 (vir_bytes) mp->DL_ADDR;
288 dep->de_write_iovec.iod_iovec[0].iov_size =
289 mp->DL_COUNT;
290 dep->de_write_iovec.iod_iovec_s = 1;
291 dep->de_write_iovec.iod_proc_nr = mp->DL_PROC;
292 dep->de_write_iovec.iod_iovec_addr = 0;
293 size= mp->DL_COUNT;
294 }
295*/
296 size = packet_get_data_length(packet);
297 dep->de_write_iovec.iod_iovec[0].iov_addr = (vir_bytes) packet_get_data(packet);
298 dep->de_write_iovec.iod_iovec[0].iov_size = size;
299 dep->de_write_iovec.iod_iovec_s = 1;
300 dep->de_write_iovec.iod_iovec_addr = (uintptr_t) NULL;
301
302 if (size < ETH_MIN_PACK_SIZE || size > ETH_MAX_PACK_SIZE_TAGGED)
303 {
304 panic("", "dp8390: invalid packet size", size);
305 return EINVAL;
306 }
307 (dep->de_user2nicf)(dep, &dep->de_write_iovec, 0,
308 dep->de_sendq[sendq_head].sq_sendpage * DP_PAGESIZE,
309 size);
310 dep->de_sendq[sendq_head].sq_filled= TRUE;
311 if (dep->de_sendq_tail == sendq_head)
312 {
313 outb_reg0(dep, DP_TPSR, dep->de_sendq[sendq_head].sq_sendpage);
314 outb_reg0(dep, DP_TBCR1, size >> 8);
315 outb_reg0(dep, DP_TBCR0, size &0xff);
316 outb_reg0(dep, DP_CR, CR_TXP | CR_EXTRA);/* there it goes.. */
317 }
318 else
319 dep->de_sendq[sendq_head].sq_size= size;
320
321 if (++sendq_head == dep->de_sendq_nr)
322 sendq_head= 0;
323 assert(sendq_head < SENDQ_NR);
324 dep->de_sendq_head= sendq_head;
325
326// dep->de_flags |= DEF_PACK_SEND;
327
328 /* If the interrupt handler called, don't send a reply. The reply
329 * will be sent after all interrupts are handled.
330 */
331 if (from_int)
332 return EOK;
333 reply(dep, OK, FALSE);
334
335 assert(dep->de_mode == DEM_ENABLED);
336 assert(dep->de_flags &DEF_ENABLED);
337 return EOK;
338}
339
340/*===========================================================================*
341 * dp_init *
342 *===========================================================================*/
343void dp_init(dep)
344dpeth_t *dep;
345{
346 int dp_rcr_reg;
347 int i;//, r;
348
349 /* General initialization */
350 dep->de_flags = DEF_EMPTY;
351 (*dep->de_initf)(dep);
352
353// dp_confaddr(dep);
354
355 if (debug)
356 {
357 printf("%s: Ethernet address ", dep->de_name);
358 for (i= 0; i < 6; i++)
359 printf("%x%c", dep->de_address.ea_addr[i],
360 i < 5 ? ':' : '\n');
361 }
362
363 /* Initialization of the dp8390 following the mandatory procedure
364 * in reference manual ("DP8390D/NS32490D NIC Network Interface
365 * Controller", National Semiconductor, July 1995, Page 29).
366 */
367 /* Step 1: */
368 outb_reg0(dep, DP_CR, CR_PS_P0 | CR_STP | CR_DM_ABORT);
369 /* Step 2: */
370 if (dep->de_16bit)
371 outb_reg0(dep, DP_DCR, DCR_WORDWIDE | DCR_8BYTES | DCR_BMS);
372 else
373 outb_reg0(dep, DP_DCR, DCR_BYTEWIDE | DCR_8BYTES | DCR_BMS);
374 /* Step 3: */
375 outb_reg0(dep, DP_RBCR0, 0);
376 outb_reg0(dep, DP_RBCR1, 0);
377 /* Step 4: */
378 dp_rcr_reg = 0;
379 if (dep->de_flags &DEF_PROMISC)
380 dp_rcr_reg |= RCR_AB | RCR_PRO | RCR_AM;
381 if (dep->de_flags &DEF_BROAD)
382 dp_rcr_reg |= RCR_AB;
383 if (dep->de_flags &DEF_MULTI)
384 dp_rcr_reg |= RCR_AM;
385 outb_reg0(dep, DP_RCR, dp_rcr_reg);
386 /* Step 5: */
387 outb_reg0(dep, DP_TCR, TCR_INTERNAL);
388 /* Step 6: */
389 outb_reg0(dep, DP_BNRY, dep->de_startpage);
390 outb_reg0(dep, DP_PSTART, dep->de_startpage);
391 outb_reg0(dep, DP_PSTOP, dep->de_stoppage);
392 /* Step 7: */
393 outb_reg0(dep, DP_ISR, 0xFF);
394 /* Step 8: */
395 outb_reg0(dep, DP_IMR, IMR_PRXE | IMR_PTXE | IMR_RXEE | IMR_TXEE |
396 IMR_OVWE | IMR_CNTE);
397 /* Step 9: */
398 outb_reg0(dep, DP_CR, CR_PS_P1 | CR_DM_ABORT | CR_STP);
399
400 outb_reg1(dep, DP_PAR0, dep->de_address.ea_addr[0]);
401 outb_reg1(dep, DP_PAR1, dep->de_address.ea_addr[1]);
402 outb_reg1(dep, DP_PAR2, dep->de_address.ea_addr[2]);
403 outb_reg1(dep, DP_PAR3, dep->de_address.ea_addr[3]);
404 outb_reg1(dep, DP_PAR4, dep->de_address.ea_addr[4]);
405 outb_reg1(dep, DP_PAR5, dep->de_address.ea_addr[5]);
406
407 outb_reg1(dep, DP_MAR0, 0xff);
408 outb_reg1(dep, DP_MAR1, 0xff);
409 outb_reg1(dep, DP_MAR2, 0xff);
410 outb_reg1(dep, DP_MAR3, 0xff);
411 outb_reg1(dep, DP_MAR4, 0xff);
412 outb_reg1(dep, DP_MAR5, 0xff);
413 outb_reg1(dep, DP_MAR6, 0xff);
414 outb_reg1(dep, DP_MAR7, 0xff);
415
416 outb_reg1(dep, DP_CURR, dep->de_startpage + 1);
417 /* Step 10: */
418 outb_reg0(dep, DP_CR, CR_DM_ABORT | CR_STA);
419 /* Step 11: */
420 outb_reg0(dep, DP_TCR, TCR_NORMAL);
421
422 inb_reg0(dep, DP_CNTR0); /* reset counters by reading */
423 inb_reg0(dep, DP_CNTR1);
424 inb_reg0(dep, DP_CNTR2);
425
426 /* Finish the initialization. */
427 dep->de_flags |= DEF_ENABLED;
428 for (i= 0; i<dep->de_sendq_nr; i++)
429 dep->de_sendq[i].sq_filled= 0;
430 dep->de_sendq_head= 0;
431 dep->de_sendq_tail= 0;
432 if (dep->de_16bit)
433 {
434 dep->de_user2nicf= dp_pio16_user2nic;
435// dep->de_user2nicf_s= dp_pio16_user2nic_s;
436 dep->de_nic2userf= dp_pio16_nic2user;
437// dep->de_nic2userf_s= dp_pio16_nic2user_s;
438 dep->de_getblockf= dp_pio16_getblock;
439 }
440 else
441 {
442 dep->de_user2nicf= dp_pio8_user2nic;
443// dep->de_user2nicf_s= dp_pio8_user2nic_s;
444 dep->de_nic2userf= dp_pio8_nic2user;
445// dep->de_nic2userf_s= dp_pio8_nic2user_s;
446 dep->de_getblockf= dp_pio8_getblock;
447 }
448
449 /* Set the interrupt handler and policy. Do not automatically
450 * reenable interrupts. Return the IRQ line number on interrupts.
451 */
452/* dep->de_hook = dep->de_irq;
453 r= sys_irqsetpolicy(dep->de_irq, 0, &dep->de_hook);
454 if (r != OK)
455 panic("DP8390", "sys_irqsetpolicy failed", r);
456
457 r= sys_irqenable(&dep->de_hook);
458 if (r != OK)
459 {
460 panic("DP8390", "unable enable interrupts", r);
461 }
462*/
463}
464
465/*===========================================================================*
466 * dp_reinit *
467 *===========================================================================*/
468static void dp_reinit(dep)
469dpeth_t *dep;
470{
471 int dp_rcr_reg;
472
473 outb_reg0(dep, DP_CR, CR_PS_P0 | CR_EXTRA);
474
475 dp_rcr_reg = 0;
476 if (dep->de_flags &DEF_PROMISC)
477 dp_rcr_reg |= RCR_AB | RCR_PRO | RCR_AM;
478 if (dep->de_flags &DEF_BROAD)
479 dp_rcr_reg |= RCR_AB;
480 if (dep->de_flags &DEF_MULTI)
481 dp_rcr_reg |= RCR_AM;
482 outb_reg0(dep, DP_RCR, dp_rcr_reg);
483}
484
485/*===========================================================================*
486 * dp_reset *
487 *===========================================================================*/
488static void dp_reset(dep)
489dpeth_t *dep;
490{
491 int i;
492
493 /* Stop chip */
494 outb_reg0(dep, DP_CR, CR_STP | CR_DM_ABORT);
495 outb_reg0(dep, DP_RBCR0, 0);
496 outb_reg0(dep, DP_RBCR1, 0);
497 for (i= 0; i < 0x1000 && ((inb_reg0(dep, DP_ISR) &ISR_RST) == 0); i++)
498 ; /* Do nothing */
499 outb_reg0(dep, DP_TCR, TCR_1EXTERNAL|TCR_OFST);
500 outb_reg0(dep, DP_CR, CR_STA|CR_DM_ABORT);
501 outb_reg0(dep, DP_TCR, TCR_NORMAL);
502
503 /* Acknowledge the ISR_RDC (remote dma) interrupt. */
504 for (i= 0; i < 0x1000 && ((inb_reg0(dep, DP_ISR) &ISR_RDC) == 0); i++)
505 ; /* Do nothing */
506 outb_reg0(dep, DP_ISR, inb_reg0(dep, DP_ISR) &~ISR_RDC);
507
508 /* Reset the transmit ring. If we were transmitting a packet, we
509 * pretend that the packet is processed. Higher layers will
510 * retransmit if the packet wasn't actually sent.
511 */
512 dep->de_sendq_head= dep->de_sendq_tail= 0;
513 for (i= 0; i<dep->de_sendq_nr; i++)
514 dep->de_sendq[i].sq_filled= 0;
515 dp_send(dep);
516 dep->de_flags &= ~DEF_STOPPED;
517}
518
519/*===========================================================================*
520 * dp_check_ints *
521 *===========================================================================*/
522void dp_check_ints(dep, isr)
523dpeth_t *dep;
524int isr;
525{
526 int /*isr,*/ tsr;
527 int size, sendq_tail;
528
529 if (!(dep->de_flags &DEF_ENABLED))
530 panic("", "dp8390: got premature interrupt", NO_NUM);
531
532 for(;;)
533 {
534// isr = inb_reg0(dep, DP_ISR);
535 if (!isr)
536 break;
537 outb_reg0(dep, DP_ISR, isr);
538 if (isr &(ISR_PTX|ISR_TXE))
539 {
540 if (isr &ISR_TXE)
541 {
542#if DEBUG
543 {printf("%s: got send Error\n", dep->de_name);}
544#endif
545 dep->de_stat.ets_sendErr++;
546 }
547 else
548 {
549 tsr = inb_reg0(dep, DP_TSR);
550
551 if (tsr &TSR_PTX) dep->de_stat.ets_packetT++;
552#if 0 /* Reserved in later manuals, should be ignored */
553 if (!(tsr &TSR_DFR))
554 {
555 /* In most (all?) implementations of
556 * the dp8390, this bit is set
557 * when the packet is not deferred
558 */
559 dep->de_stat.ets_transDef++;
560 }
561#endif
562 if (tsr &TSR_COL) dep->de_stat.ets_collision++;
563 if (tsr &TSR_ABT) dep->de_stat.ets_transAb++;
564 if (tsr &TSR_CRS) dep->de_stat.ets_carrSense++;
565 if (tsr &TSR_FU
566 && ++dep->de_stat.ets_fifoUnder <= 10)
567 {
568 printf("%s: fifo underrun\n",
569 dep->de_name);
570 }
571 if (tsr &TSR_CDH
572 && ++dep->de_stat.ets_CDheartbeat <= 10)
573 {
574 printf("%s: CD heart beat failure\n",
575 dep->de_name);
576 }
577 if (tsr &TSR_OWC) dep->de_stat.ets_OWC++;
578 }
579 sendq_tail= dep->de_sendq_tail;
580
581 if (!(dep->de_sendq[sendq_tail].sq_filled))
582 {
583 /* Software bug? */
584 assert(!debug);
585
586 /* Or hardware bug? */
587 printf(
588 "%s: transmit interrupt, but not sending\n",
589 dep->de_name);
590 continue;
591 }
592 dep->de_sendq[sendq_tail].sq_filled= 0;
593 if (++sendq_tail == dep->de_sendq_nr)
594 sendq_tail= 0;
595 dep->de_sendq_tail= sendq_tail;
596 if (dep->de_sendq[sendq_tail].sq_filled)
597 {
598 size= dep->de_sendq[sendq_tail].sq_size;
599 outb_reg0(dep, DP_TPSR,
600 dep->de_sendq[sendq_tail].sq_sendpage);
601 outb_reg0(dep, DP_TBCR1, size >> 8);
602 outb_reg0(dep, DP_TBCR0, size &0xff);
603 outb_reg0(dep, DP_CR, CR_TXP | CR_EXTRA);
604 }
605// if (dep->de_flags &DEF_SEND_AVAIL)
606 dp_send(dep);
607 }
608
609 if (isr &ISR_PRX)
610 {
611 /* Only call dp_recv if there is a read request */
612// if (dep->de_flags) &DEF_READING)
613 dp_recv(dep);
614 }
615
616 if (isr &ISR_RXE) dep->de_stat.ets_recvErr++;
617 if (isr &ISR_CNT)
618 {
619 dep->de_stat.ets_CRCerr += inb_reg0(dep, DP_CNTR0);
620 dep->de_stat.ets_frameAll += inb_reg0(dep, DP_CNTR1);
621 dep->de_stat.ets_missedP += inb_reg0(dep, DP_CNTR2);
622 }
623 if (isr &ISR_OVW)
624 {
625 dep->de_stat.ets_OVW++;
626#if 0
627 {printW(); printf(
628 "%s: got overwrite warning\n", dep->de_name);}
629#endif
630/* if (dep->de_flags &DEF_READING)
631 {
632 printf(
633"dp_check_ints: strange: overwrite warning and pending read request\n");
634 dp_recv(dep);
635 }
636*/ }
637 if (isr &ISR_RDC)
638 {
639 /* Nothing to do */
640 }
641 if (isr &ISR_RST)
642 {
643 /* this means we got an interrupt but the ethernet
644 * chip is shutdown. We set the flag DEF_STOPPED,
645 * and continue processing arrived packets. When the
646 * receive buffer is empty, we reset the dp8390.
647 */
648#if 0
649 {printW(); printf(
650 "%s: NIC stopped\n", dep->de_name);}
651#endif
652 dep->de_flags |= DEF_STOPPED;
653 break;
654 }
655 isr = inb_reg0(dep, DP_ISR);
656 }
657// if ((dep->de_flags &(DEF_READING|DEF_STOPPED)) ==
658// (DEF_READING|DEF_STOPPED))
659 if ((dep->de_flags &DEF_STOPPED) == DEF_STOPPED)
660 {
661 /* The chip is stopped, and all arrived packets are
662 * delivered.
663 */
664 dp_reset(dep);
665 }
666}
667
668/*===========================================================================*
669 * dp_recv *
670 *===========================================================================*/
671static void dp_recv(dep)
672dpeth_t *dep;
673{
674 dp_rcvhdr_t header;
675 //unsigned pageno, curr, next;
676 int pageno, curr, next;
677 vir_bytes length;
678 int packet_processed, r;
679 u16_t eth_type;
680
681 packet_processed = FALSE;
682 pageno = inb_reg0(dep, DP_BNRY) + 1;
683 if (pageno == dep->de_stoppage) pageno = dep->de_startpage;
684
685 do
686 {
687 outb_reg0(dep, DP_CR, CR_PS_P1 | CR_EXTRA);
688 curr = inb_reg1(dep, DP_CURR);
689 outb_reg0(dep, DP_CR, CR_PS_P0 | CR_EXTRA);
690
691 if (curr == pageno) break;
692
693 (dep->de_getblockf)(dep, pageno, (size_t)0, sizeof(header),
694 &header);
695 (dep->de_getblockf)(dep, pageno, sizeof(header) +
696 2*sizeof(ether_addr_t), sizeof(eth_type), &eth_type);
697
698 length = (header.dr_rbcl | (header.dr_rbch << 8)) -
699 sizeof(dp_rcvhdr_t);
700 next = header.dr_next;
701 if (length < ETH_MIN_PACK_SIZE ||
702 length > ETH_MAX_PACK_SIZE_TAGGED)
703 {
704 printf("%s: packet with strange length arrived: %d\n",
705 dep->de_name, (int) length);
706 next= curr;
707 }
708 else if (next < dep->de_startpage || next >= dep->de_stoppage)
709 {
710 printf("%s: strange next page\n", dep->de_name);
711 next= curr;
712 }
713/* else if (eth_type == eth_ign_proto)
714 {
715*/ /* Hack: ignore packets of a given protocol, useful
716 * if you share a net with 80 computers sending
717 * Amoeba FLIP broadcasts. (Protocol 0x8146.)
718 */
719/* static int first= 1;
720 if (first)
721 {
722 first= 0;
723 printf("%s: dropping proto 0x%04x packets\n",
724 dep->de_name,
725 ntohs(eth_ign_proto));
726 }
727 dep->de_stat.ets_packetR++;
728 }
729*/ else if (header.dr_status &RSR_FO)
730 {
731 /* This is very serious, so we issue a warning and
732 * reset the buffers */
733 printf("%s: fifo overrun, resetting receive buffer\n",
734 dep->de_name);
735 dep->de_stat.ets_fifoOver++;
736 next = curr;
737 }
738 else if ((header.dr_status &RSR_PRX) &&
739 (dep->de_flags &DEF_ENABLED))
740 {
741// if (dep->de_safecopy_read)
742// r = dp_pkt2user_s(dep, pageno, length);
743// else
744 r = dp_pkt2user(dep, pageno, length);
745 if (r != OK)
746 return;
747
748 packet_processed = TRUE;
749 dep->de_stat.ets_packetR++;
750 }
751 if (next == dep->de_startpage)
752 outb_reg0(dep, DP_BNRY, dep->de_stoppage - 1);
753 else
754 outb_reg0(dep, DP_BNRY, next - 1);
755
756 pageno = next;
757 }
758 while (!packet_processed);
759}
760
761/*===========================================================================*
762 * dp_send *
763 *===========================================================================*/
764static void dp_send(dep)
765dpeth_t *dep;
766{
767 packet_t *packet;
768
769// if (!(dep->de_flags &DEF_SEND_AVAIL))
770// return;
771
772 if(dep->packet_queue){
773 packet = dep->packet_queue;
774 dep->packet_queue = pq_detach(packet);
775 do_pwrite(dep, packet, TRUE);
776 netif_pq_release(packet_get_id(packet));
777 -- dep->packet_count;
778 }
779// if(! dep->packet_queue){
780// dep->de_flags &= ~DEF_SEND_AVAIL;
781// }
782/* switch(dep->de_sendmsg.m_type)
783 {
784 case DL_WRITE: do_vwrite(&dep->de_sendmsg, TRUE, FALSE); break;
785 case DL_WRITEV: do_vwrite(&dep->de_sendmsg, TRUE, TRUE); break;
786 case DL_WRITEV_S: do_vwrite_s(&dep->de_sendmsg, TRUE); break;
787 default:
788 panic("", "dp8390: wrong type", dep->de_sendmsg.m_type);
789 break;
790 }
791*/
792}
793
794/*===========================================================================*
795 * dp_pio8_getblock *
796 *===========================================================================*/
797static void dp_pio8_getblock(dep, page, offset, size, dst)
798dpeth_t *dep;
799int page;
800size_t offset;
801size_t size;
802void *dst;
803{
804 offset = page * DP_PAGESIZE + offset;
805 outb_reg0(dep, DP_RBCR0, size &0xFF);
806 outb_reg0(dep, DP_RBCR1, size >> 8);
807 outb_reg0(dep, DP_RSAR0, offset &0xFF);
808 outb_reg0(dep, DP_RSAR1, offset >> 8);
809 outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
810
811 insb(dep->de_data_port, dst, size);
812}
813
814/*===========================================================================*
815 * dp_pio16_getblock *
816 *===========================================================================*/
817static void dp_pio16_getblock(dep, page, offset, size, dst)
818dpeth_t *dep;
819int page;
820size_t offset;
821size_t size;
822void *dst;
823{
824 offset = page * DP_PAGESIZE + offset;
825 outb_reg0(dep, DP_RBCR0, size &0xFF);
826 outb_reg0(dep, DP_RBCR1, size >> 8);
827 outb_reg0(dep, DP_RSAR0, offset &0xFF);
828 outb_reg0(dep, DP_RSAR1, offset >> 8);
829 outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
830
831 assert (!(size &1));
832 insw(dep->de_data_port, dst, size);
833}
834
835/*===========================================================================*
836 * dp_pkt2user *
837 *===========================================================================*/
838static int dp_pkt2user(dep, page, length)
839dpeth_t *dep;
840int page, length;
841{
842 int last, count;
843 packet_t *packet;
844
845// if (!(dep->de_flags &DEF_READING))
846// return EGENERIC;
847
848 packet = netif_packet_get_1(length);
849 if(! packet){
850 return ENOMEM;
851 }
852 dep->de_read_iovec.iod_iovec[0].iov_addr = (vir_bytes) packet_suffix(packet, length);
853 dep->de_read_iovec.iod_iovec[0].iov_size = length;
854 dep->de_read_iovec.iod_iovec_s = 1;
855 dep->de_read_iovec.iod_iovec_addr = (uintptr_t) NULL;
856
857 last = page + (length - 1) / DP_PAGESIZE;
858 if (last >= dep->de_stoppage)
859 {
860 count = (dep->de_stoppage - page) * DP_PAGESIZE -
861 sizeof(dp_rcvhdr_t);
862
863 /* Save read_iovec since we need it twice. */
864 dep->de_tmp_iovec = dep->de_read_iovec;
865 (dep->de_nic2userf)(dep, page * DP_PAGESIZE +
866 sizeof(dp_rcvhdr_t), &dep->de_tmp_iovec, 0, count);
867 (dep->de_nic2userf)(dep, dep->de_startpage * DP_PAGESIZE,
868 &dep->de_read_iovec, count, length - count);
869 }
870 else
871 {
872 (dep->de_nic2userf)(dep, page * DP_PAGESIZE +
873 sizeof(dp_rcvhdr_t), &dep->de_read_iovec, 0, length);
874 }
875
876 dep->de_read_s = length;
877 dep->de_flags |= DEF_PACK_RECV;
878// dep->de_flags &= ~DEF_READING;
879
880 if(dep->received_count >= MAX_PACKETS){
881 netif_pq_release(packet_get_id(packet));
882 return ELIMIT;
883 }else{
884 if(pq_add(&dep->received_queue, packet, 0, 0) == EOK){
885 ++ dep->received_count;
886 }else{
887 netif_pq_release(packet_get_id(packet));
888 }
889 }
890 return OK;
891}
892
893/*===========================================================================*
894 * dp_pio8_user2nic *
895 *===========================================================================*/
896static void dp_pio8_user2nic(dep, iovp, offset, nic_addr, count)
897dpeth_t *dep;
898iovec_dat_t *iovp;
899vir_bytes offset;
900int nic_addr;
901vir_bytes count;
902{
903// phys_bytes phys_user;
904 int i;
905 vir_bytes bytes;
906
907 outb_reg0(dep, DP_ISR, ISR_RDC);
908
909 outb_reg0(dep, DP_RBCR0, count &0xFF);
910 outb_reg0(dep, DP_RBCR1, count >> 8);
911 outb_reg0(dep, DP_RSAR0, nic_addr &0xFF);
912 outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
913 outb_reg0(dep, DP_CR, CR_DM_RW | CR_PS_P0 | CR_STA);
914
915 i= 0;
916 while (count > 0)
917 {
918 if (i >= IOVEC_NR)
919 {
920 dp_next_iovec(iovp);
921 i= 0;
922 continue;
923 }
924 assert(i < iovp->iod_iovec_s);
925 if (offset >= iovp->iod_iovec[i].iov_size)
926 {
927 offset -= iovp->iod_iovec[i].iov_size;
928 i++;
929 continue;
930 }
931 bytes = iovp->iod_iovec[i].iov_size - offset;
932 if (bytes > count)
933 bytes = count;
934
935 do_vir_outsb(dep->de_data_port, iovp->iod_proc_nr,
936 iovp->iod_iovec[i].iov_addr + offset, bytes);
937 count -= bytes;
938 offset += bytes;
939 }
940 assert(count == 0);
941
942 for (i= 0; i<100; i++)
943 {
944 if (inb_reg0(dep, DP_ISR) &ISR_RDC)
945 break;
946 }
947 if (i == 100)
948 {
949 panic("", "dp8390: remote dma failed to complete", NO_NUM);
950 }
951}
952
953/*===========================================================================*
954 * dp_pio16_user2nic *
955 *===========================================================================*/
956static void dp_pio16_user2nic(dep, iovp, offset, nic_addr, count)
957dpeth_t *dep;
958iovec_dat_t *iovp;
959vir_bytes offset;
960int nic_addr;
961vir_bytes count;
962{
963 vir_bytes vir_user;
964 vir_bytes ecount;
965 int i, r, user_proc;
966 vir_bytes bytes;
967 //u8_t two_bytes[2];
968 u16_t two_bytes;
969 int odd_byte;
970
971 ecount= (count+1) &~1;
972 odd_byte= 0;
973
974 outb_reg0(dep, DP_ISR, ISR_RDC);
975 outb_reg0(dep, DP_RBCR0, ecount &0xFF);
976 outb_reg0(dep, DP_RBCR1, ecount >> 8);
977 outb_reg0(dep, DP_RSAR0, nic_addr &0xFF);
978 outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
979 outb_reg0(dep, DP_CR, CR_DM_RW | CR_PS_P0 | CR_STA);
980
981 i= 0;
982 while (count > 0)
983 {
984 if (i >= IOVEC_NR)
985 {
986 dp_next_iovec(iovp);
987 i= 0;
988 continue;
989 }
990 assert(i < iovp->iod_iovec_s);
991 if (offset >= iovp->iod_iovec[i].iov_size)
992 {
993 offset -= iovp->iod_iovec[i].iov_size;
994 i++;
995 continue;
996 }
997 bytes = iovp->iod_iovec[i].iov_size - offset;
998 if (bytes > count)
999 bytes = count;
1000
1001 user_proc= iovp->iod_proc_nr;
1002 vir_user= iovp->iod_iovec[i].iov_addr + offset;
1003 if (odd_byte)
1004 {
1005 r= sys_vircopy(user_proc, D, vir_user,
1006 // SELF, D, (vir_bytes)&two_bytes[1], 1);
1007 SELF, D, (vir_bytes)&(((u8_t *)&two_bytes)[1]), 1);
1008 if (r != OK)
1009 {
1010 panic("DP8390",
1011 "dp_pio16_user2nic: sys_vircopy failed",
1012 r);
1013 }
1014 //outw(dep->de_data_port, *(u16_t *)two_bytes);
1015 outw(dep->de_data_port, two_bytes);
1016 count--;
1017 offset++;
1018 bytes--;
1019 vir_user++;
1020 odd_byte= 0;
1021 if (!bytes)
1022 continue;
1023 }
1024 ecount= bytes &~1;
1025 if (ecount != 0)
1026 {
1027 do_vir_outsw(dep->de_data_port, user_proc, vir_user,
1028 ecount);
1029 count -= ecount;
1030 offset += ecount;
1031 bytes -= ecount;
1032 vir_user += ecount;
1033 }
1034 if (bytes)
1035 {
1036 assert(bytes == 1);
1037 r= sys_vircopy(user_proc, D, vir_user,
1038 // SELF, D, (vir_bytes)&two_bytes[0], 1);
1039 SELF, D, (vir_bytes)&(((u8_t *)&two_bytes)[0]), 1);
1040 if (r != OK)
1041 {
1042 panic("DP8390",
1043 "dp_pio16_user2nic: sys_vircopy failed",
1044 r);
1045 }
1046 count--;
1047 offset++;
1048 bytes--;
1049 vir_user++;
1050 odd_byte= 1;
1051 }
1052 }
1053 assert(count == 0);
1054
1055 if (odd_byte)
1056 //outw(dep->de_data_port, *(u16_t *)two_bytes);
1057 outw(dep->de_data_port, two_bytes);
1058
1059 for (i= 0; i<100; i++)
1060 {
1061 if (inb_reg0(dep, DP_ISR) &ISR_RDC)
1062 break;
1063 }
1064 if (i == 100)
1065 {
1066 panic("", "dp8390: remote dma failed to complete", NO_NUM);
1067 }
1068}
1069
1070/*===========================================================================*
1071 * dp_pio8_nic2user *
1072 *===========================================================================*/
1073static void dp_pio8_nic2user(dep, nic_addr, iovp, offset, count)
1074dpeth_t *dep;
1075int nic_addr;
1076iovec_dat_t *iovp;
1077vir_bytes offset;
1078vir_bytes count;
1079{
1080// phys_bytes phys_user;
1081 int i;
1082 vir_bytes bytes;
1083
1084 outb_reg0(dep, DP_RBCR0, count &0xFF);
1085 outb_reg0(dep, DP_RBCR1, count >> 8);
1086 outb_reg0(dep, DP_RSAR0, nic_addr &0xFF);
1087 outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
1088 outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
1089
1090 i= 0;
1091 while (count > 0)
1092 {
1093 if (i >= IOVEC_NR)
1094 {
1095 dp_next_iovec(iovp);
1096 i= 0;
1097 continue;
1098 }
1099 assert(i < iovp->iod_iovec_s);
1100 if (offset >= iovp->iod_iovec[i].iov_size)
1101 {
1102 offset -= iovp->iod_iovec[i].iov_size;
1103 i++;
1104 continue;
1105 }
1106 bytes = iovp->iod_iovec[i].iov_size - offset;
1107 if (bytes > count)
1108 bytes = count;
1109
1110 do_vir_insb(dep->de_data_port, iovp->iod_proc_nr,
1111 iovp->iod_iovec[i].iov_addr + offset, bytes);
1112 count -= bytes;
1113 offset += bytes;
1114 }
1115 assert(count == 0);
1116}
1117
1118/*===========================================================================*
1119 * dp_pio16_nic2user *
1120 *===========================================================================*/
1121static void dp_pio16_nic2user(dep, nic_addr, iovp, offset, count)
1122dpeth_t *dep;
1123int nic_addr;
1124iovec_dat_t *iovp;
1125vir_bytes offset;
1126vir_bytes count;
1127{
1128 vir_bytes vir_user;
1129 vir_bytes ecount;
1130 int i, r, user_proc;
1131 vir_bytes bytes;
1132 //u8_t two_bytes[2];
1133 u16_t two_bytes;
1134 int odd_byte;
1135
1136 ecount= (count+1) &~1;
1137 odd_byte= 0;
1138
1139 outb_reg0(dep, DP_RBCR0, ecount &0xFF);
1140 outb_reg0(dep, DP_RBCR1, ecount >> 8);
1141 outb_reg0(dep, DP_RSAR0, nic_addr &0xFF);
1142 outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
1143 outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
1144
1145 i= 0;
1146 while (count > 0)
1147 {
1148 if (i >= IOVEC_NR)
1149 {
1150 dp_next_iovec(iovp);
1151 i= 0;
1152 continue;
1153 }
1154 assert(i < iovp->iod_iovec_s);
1155 if (offset >= iovp->iod_iovec[i].iov_size)
1156 {
1157 offset -= iovp->iod_iovec[i].iov_size;
1158 i++;
1159 continue;
1160 }
1161 bytes = iovp->iod_iovec[i].iov_size - offset;
1162 if (bytes > count)
1163 bytes = count;
1164
1165 user_proc= iovp->iod_proc_nr;
1166 vir_user= iovp->iod_iovec[i].iov_addr + offset;
1167 if (odd_byte)
1168 {
1169 //r= sys_vircopy(SELF, D, (vir_bytes)&two_bytes[1],
1170 r= sys_vircopy(SELF, D, (vir_bytes)&(((u8_t *)&two_bytes)[1]),
1171 user_proc, D, vir_user, 1);
1172 if (r != OK)
1173 {
1174 panic("DP8390",
1175 "dp_pio16_nic2user: sys_vircopy failed",
1176 r);
1177 }
1178 count--;
1179 offset++;
1180 bytes--;
1181 vir_user++;
1182 odd_byte= 0;
1183 if (!bytes)
1184 continue;
1185 }
1186 ecount= bytes &~1;
1187 if (ecount != 0)
1188 {
1189 do_vir_insw(dep->de_data_port, user_proc, vir_user,
1190 ecount);
1191 count -= ecount;
1192 offset += ecount;
1193 bytes -= ecount;
1194 vir_user += ecount;
1195 }
1196 if (bytes)
1197 {
1198 assert(bytes == 1);
1199 //*(u16_t *)two_bytes= inw(dep->de_data_port);
1200 two_bytes= inw(dep->de_data_port);
1201 //r= sys_vircopy(SELF, D, (vir_bytes)&two_bytes[0],
1202 r= sys_vircopy(SELF, D, (vir_bytes)&(((u8_t *)&two_bytes)[0]),
1203 user_proc, D, vir_user, 1);
1204 if (r != OK)
1205 {
1206 panic("DP8390",
1207 "dp_pio16_nic2user: sys_vircopy failed",
1208 r);
1209 }
1210 count--;
1211 offset++;
1212 bytes--;
1213 vir_user++;
1214 odd_byte= 1;
1215 }
1216 }
1217 assert(count == 0);
1218}
1219
1220/*===========================================================================*
1221 * dp_next_iovec *
1222 *===========================================================================*/
1223static void dp_next_iovec(iovp)
1224iovec_dat_t *iovp;
1225{
1226 assert(iovp->iod_iovec_s > IOVEC_NR);
1227
1228 iovp->iod_iovec_s -= IOVEC_NR;
1229
1230 iovp->iod_iovec_addr += IOVEC_NR * sizeof(iovec_t);
1231
1232 get_userdata(iovp->iod_proc_nr, iovp->iod_iovec_addr,
1233 (iovp->iod_iovec_s > IOVEC_NR ? IOVEC_NR : iovp->iod_iovec_s) *
1234 sizeof(iovec_t), iovp->iod_iovec);
1235}
1236
1237/*===========================================================================*
1238 * conf_hw *
1239 *===========================================================================*/
1240static void conf_hw(dep)
1241dpeth_t *dep;
1242{
1243// static eth_stat_t empty_stat = {0, 0, 0, 0, 0, 0 /* ,... */};
1244
1245// int ifnr;
1246// dp_conf_t *dcp;
1247
1248// dep->de_mode= DEM_DISABLED; /* Superfluous */
1249// ifnr= dep-de_table;
1250
1251// dcp= &dp_conf[ifnr];
1252// update_conf(dep, dcp);
1253// if (dep->de_mode != DEM_ENABLED)
1254// return;
1255 if (!ne_probe(dep)) {
1256 printf("%s: No ethernet card found at %#lx\n",
1257 dep->de_name, dep->de_base_port);
1258 dep->de_mode= DEM_DISABLED;
1259 return;
1260 }
1261
1262/* XXX */ if (dep->de_linmem == 0) dep->de_linmem= 0xFFFF0000;
1263
1264 dep->de_mode = DEM_ENABLED;
1265
1266 dep->de_flags = DEF_EMPTY;
1267// dep->de_stat = empty_stat;
1268}
1269
1270/*===========================================================================*
1271 * reply *
1272 *===========================================================================*/
1273static void reply(dep, err, may_block)
1274dpeth_t *dep;
1275int err;
1276int may_block;
1277{
1278/* message reply;
1279 int status;
1280 int r;
1281
1282 status = 0;
1283 if (dep->de_flags &DEF_PACK_SEND)
1284 status |= DL_PACK_SEND;
1285 if (dep->de_flags &DEF_PACK_RECV)
1286 status |= DL_PACK_RECV;
1287
1288 reply.m_type = DL_TASK_REPLY;
1289 reply.DL_PORT = dep - de_table;
1290 reply.DL_PROC = dep->de_client;
1291 reply.DL_STAT = status | ((u32_t) err << 16);
1292 reply.DL_COUNT = dep->de_read_s;
1293 reply.DL_CLCK = 0; *//* Don't know */
1294/* r= send(dep->de_client, &reply);
1295
1296 if (r == ELOCKED && may_block)
1297 {
1298#if 0
1299 printf("send locked\n");
1300#endif
1301 return;
1302 }
1303
1304 if (r < 0)
1305 panic("", "dp8390: send failed:", r);
1306
1307*/ dep->de_read_s = 0;
1308// dep->de_flags &= ~(DEF_PACK_SEND | DEF_PACK_RECV);
1309}
1310
1311/*===========================================================================*
1312 * get_userdata *
1313 *===========================================================================*/
1314static void get_userdata(user_proc, user_addr, count, loc_addr)
1315int user_proc;
1316vir_bytes user_addr;
1317vir_bytes count;
1318void *loc_addr;
1319{
1320 int r;
1321
1322 r= sys_vircopy(user_proc, D, user_addr,
1323 SELF, D, (vir_bytes)loc_addr, count);
1324 if (r != OK)
1325 panic("DP8390", "get_userdata: sys_vircopy failed", r);
1326}
1327
1328static void insb(port_t port, void *buf, size_t size)
1329{
1330 size_t i;
1331
1332 for(i = 0; i < size; ++ i){
1333 *((uint8_t *) buf + i) = inb(port);
1334 }
1335}
1336
1337static void insw(port_t port, void *buf, size_t size)
1338{
1339 size_t i;
1340
1341 for(i = 0; i * 2 < size; ++ i){
1342 *((uint16_t *) buf + i) = inw(port);
1343 }
1344}
1345
1346static void outsb(port_t port, void *buf, size_t size)
1347{
1348 size_t i;
1349
1350 for(i = 0; i < size; ++ i){
1351 outb(port, *((uint8_t *) buf + i));
1352 }
1353}
1354
1355static void outsw(port_t port, void *buf, size_t size)
1356{
1357 size_t i;
1358
1359 for(i = 0; i * 2 < size; ++ i){
1360 outw(port, *((uint16_t *) buf + i));
1361 }
1362}
1363
1364/** @}
1365 */
Note: See TracBrowser for help on using the repository browser.