This source file includes following definitions.
- rln_enable
- rln_reset
- rln_wakeup
- rln_tx_request
- rln_tx_end
- rln_rx_request
- rln_rx_pdata
- rln_rx_data
- rln_rx_end
- rln_clear_nak
- rln_msg_tx_start
- rln_msg_tx_data
- rln_msg_tx_end
- rln_newseq
- rln_msg_txrx
- rln_mbox_create
- rln_mbox_wait
- rln_mbox_lock
- rln_mbox_unlock
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 #include <sys/param.h>
16 #include <sys/systm.h>
17 #include <sys/mbuf.h>
18 #include <sys/socket.h>
19 #include <sys/ioctl.h>
20 #include <sys/syslog.h>
21 #include <sys/device.h>
22 #include <sys/queue.h>
23 #include <sys/proc.h>
24 #include <sys/kernel.h>
25
26 #include <net/if.h>
27
28 #ifdef INET
29 #include <netinet/in.h>
30 #include <netinet/if_ether.h>
31 #endif
32
33 #include <machine/bus.h>
34 #include <machine/intr.h>
35
36 #include <dev/ic/rln.h>
37 #include <dev/ic/rlnvar.h>
38 #include <dev/ic/rlnreg.h>
39 #include <dev/ic/rlncmd.h>
40
41 static int rln_tx_request(struct rln_softc *, u_int16_t);
42 static int rln_tx_end(struct rln_softc *);
43
44
45
46
47
48 int
49 rln_enable(sc, enable)
50 struct rln_softc * sc;
51 int enable;
52 {
53 int s;
54 int was_enabled;
55
56 s = splhigh();
57 was_enabled = (sc->sc_intsel & RLN_INTSEL_ENABLE) ? 1 : 0;
58 if (enable != was_enabled) {
59 if (enable)
60 sc->sc_intsel |= RLN_INTSEL_ENABLE;
61 else
62 sc->sc_intsel &=~RLN_INTSEL_ENABLE;
63 _rln_register_write_1(sc, RLN_REG_INTSEL, sc->sc_intsel);
64 }
65 splx(s);
66 return (was_enabled);
67 }
68
69
70
71
72
73
74
75
76
77 int
78 rln_reset(sc)
79 struct rln_softc * sc;
80 {
81 int s;
82 int i;
83 int status;
84 u_int8_t op = 0x00;
85
86 s = splhigh();
87 dprintf(" R[");
88 if (sc->sc_cardtype & (RLN_CTYPE_UISA | RLN_CTYPE_ONE_PIECE))
89 op = 0x04;
90 if (rln_status_read(sc) & RLN_STATUS_WAKEUP) {
91 rln_control_write(sc, op);
92 rln_control_write(sc, op | RLN_CONTROL_RESET);
93 dprintf(" 7ms");
94 DELAY(7000);
95 rln_control_write(sc, op);
96 dprintf(" 7ms");
97 DELAY(7000);
98 }
99 rln_control_write(sc, op);
100 rln_control_write(sc, op);
101 rln_control_write(sc, op | RLN_CONTROL_BIT3);
102 dprintf(" 67ms");
103 DELAY(67000);
104 rln_status_write(sc, 0x00);
105 if (sc->sc_cardtype & (RLN_CTYPE_UISA | RLN_CTYPE_ONE_PIECE))
106 rln_control_write(sc, 0x38);
107
108 else
109 rln_control_write(sc, 0x2c);
110
111 dprintf(" 67ms");
112 DELAY(67000);
113 rln_data_write_2(sc, 0xaa55);
114 rln_status_write(sc, 0x5a);
115 splx(s);
116 for (i = 0; i < 200 * 10; i++) {
117 if ((status = rln_status_read(sc)) == 0x5a)
118 break;
119 DELAY(1000);
120 }
121 dprintf(" (%dms)", i);
122 s = splhigh();
123 if (status != 0x5a) {
124 splx(s);
125
126 if (sc->sc_width != 0)
127 printf("%s: reset timeout\n", sc->sc_dev.dv_xname);
128 dprintf("]=-1");
129 return (-1);
130 }
131 if (sc->sc_width == 8) {
132 if (sc->sc_cardtype & (RLN_CTYPE_UISA | RLN_CTYPE_ONE_PIECE))
133 rln_control_write(sc, RLN_CONTROL_BIT3);
134 else
135 rln_control_write(sc, RLN_CONTROL_BIT3 |
136 RLN_CONTROL_BIT2);
137 rln_data_write_1(sc, 0x20);
138 } else if (sc->sc_width == 16) {
139 rln_data_write_2(sc, 0x0000);
140 } else {
141 if (rln_data_read_2(sc) == 0x55aa) {
142 rln_data_write_2(sc, 0x0000);
143 sc->sc_width = 16;
144 } else {
145 if (sc->sc_cardtype & (RLN_CTYPE_UISA |
146 RLN_CTYPE_ONE_PIECE))
147 rln_control_write(sc, RLN_CONTROL_BIT3);
148 else
149 rln_control_write(sc, RLN_CONTROL_BIT3 |
150 RLN_CONTROL_BIT2);
151 rln_data_write_1(sc, 0x20);
152 sc->sc_width = 8;
153 }
154
155
156 }
157 rln_status_write(sc, 0x00);
158 sc->sc_intsel = 0;
159 rln_intsel_write(sc, sc->sc_irq);
160 splx(s);
161 dprintf("]");
162 return (0);
163 }
164
165
166
167
168
169
170
171 u_int8_t
172 rln_wakeup(sc, wnew)
173 struct rln_softc * sc;
174 u_int8_t wnew;
175 {
176 u_int8_t wold, s;
177 int i;
178
179
180 wold = (sc->sc_status & RLN_STATUS_WAKEUP) |
181 (sc->sc_control & RLN_CONTROL_RESET);
182
183 if (wnew == RLN_WAKEUP_SET) {
184
185 dprintf(" Ws[");
186 rln_status_set(sc, RLN_STATUS_WAKEUP);
187 if (0
188 ) {
189 dprintf (" 167ms");
190 DELAY(167000);
191 } else {
192 dprintf (" .1ms");
193 DELAY(100);
194 }
195 s = rln_status_read(sc);
196 rln_control_set(sc, RLN_CONTROL_RESET);
197 if ((s & RLN_STATUS_WAKEUP) != 0)
198 for (i = 0; i < 9; i++) {
199 dprintf(" 2ms");
200 DELAY(2000);
201 rln_status_set(sc, RLN_STATUS_WAKEUP);
202 }
203 dprintf("]");
204 } else {
205
206 dprintf(" Wc[");
207 if ((wnew & RLN_STATUS_WAKEUP) == 0)
208 rln_status_clear(sc, RLN_STATUS_WAKEUP);
209 if ((wnew & RLN_CONTROL_RESET) == 0)
210 rln_control_clear(sc, RLN_CONTROL_RESET);
211 dprintf("]");
212 }
213 return (wold);
214 }
215
216
217
218
219
220
221
222
223 static int
224 rln_tx_request(sc, len)
225 struct rln_softc * sc;
226 u_int16_t len;
227 {
228
229 int s;
230 int i;
231 u_int8_t status;
232
233
234
235
236 dprintf(" Tr[");
237 if (sc->sc_width == 16) {
238 rln_status_tx_write(sc, RLN_STATUS_TX_HILEN_AVAIL);
239 rln_data_write_2(sc, len);
240 rln_status_tx_int(sc);
241
242 s = spl0();
243 for (i = 0; i < 600; i++) {
244 status = rln_status_tx_read(sc);
245 if (status == RLN_STATUS_TX_HILEN_ACCEPT ||
246 status == RLN_STATUS_TX_ERROR)
247 break;
248 DELAY(1000);
249 }
250 splx(s);
251 dprintf(" %dms", i);
252 if (status == RLN_STATUS_TX_HILEN_ACCEPT)
253 goto success;
254 if (status == RLN_STATUS_TX_ERROR)
255 goto error;
256 } else if (sc->sc_width == 8) {
257 rln_status_tx_write(sc, RLN_STATUS_TX_LOLEN_AVAIL);
258 rln_data_write_1(sc, len & 0xff);
259 rln_status_tx_int(sc);
260 s = spl0();
261 for (i = 0; i < 6800; i++) {
262 status = rln_status_tx_read(sc);
263 if (status == RLN_STATUS_TX_LOLEN_ACCEPT)
264 break;
265 DELAY(1000);
266 }
267 splx(s);
268 dprintf(" %dms", i);
269 if (status == RLN_STATUS_TX_LOLEN_ACCEPT) {
270 rln_data_write_1(sc, (len >> 8) & 0xff);
271 rln_status_tx_write(sc, RLN_STATUS_TX_HILEN_AVAIL);
272 s = spl0();
273 for (i = 0; i < 600; i++) {
274 status = rln_status_tx_read(sc);
275 if (status == RLN_STATUS_TX_HILEN_ACCEPT ||
276 status == RLN_STATUS_TX_ERROR)
277 break;
278 DELAY(1000);
279 }
280 splx(s);
281 dprintf(" %dms", i);
282 if (status == RLN_STATUS_TX_HILEN_ACCEPT)
283 goto success;
284 if (status == RLN_STATUS_TX_ERROR)
285 goto error;
286 }
287 }
288 #ifdef DIAGNOSTIC
289 else
290 panic("rln: bus width");
291 #endif
292
293 printf("%s: tx_request timed out, status 0x%02x",
294 sc->sc_dev.dv_xname, status);
295 dprintf("]=(1)");
296 return (1);
297
298 error:
299
300 dprintf("]=2");
301 #ifdef DIAGNOSTIC
302 printf("%s: tx protocol fault (nak)\n", sc->sc_dev.dv_xname);
303 #endif
304 return (2);
305
306 success:
307
308 dprintf("]=0");
309 return (0);
310 }
311
312
313
314
315
316
317
318 static int
319 rln_tx_end(sc)
320 struct rln_softc * sc;
321 {
322
323 int i;
324 int s;
325 u_int8_t status;
326
327 dprintf(" Te[");
328 s = spl0();
329 for (i = 0; i < 600; i++) {
330 status = rln_status_tx_read(sc);
331 if (status == RLN_STATUS_TX_XFR_COMPLETE)
332 break;
333 DELAY(1000);
334 }
335 splx(s);
336 if (status == RLN_STATUS_TX_XFR_COMPLETE) {
337 rln_status_tx_write(sc, RLN_STATUS_TX_IDLE);
338 dprintf("]=0");
339 return (0);
340 } else {
341 printf("%s: tx cmd failed (%02x)\n", sc->sc_dev.dv_xname,
342 status);
343 rln_need_reset(sc);
344 dprintf("]=-1");
345 return (-1);
346 }
347 }
348
349
350
351
352
353
354
355 int
356 rln_rx_request(sc, timeo)
357 struct rln_softc * sc;
358 int timeo;
359 {
360
361 int s;
362 int len = 0;
363 int i;
364 u_int8_t status;
365 u_int8_t hi, lo;
366
367 dprintf(" Rr[");
368 status = rln_status_rx_read(sc);
369
370
371 s = spl0();
372 for (i = 0; i < timeo; i++) {
373 if (status == RLN_STATUS_RX_LOLEN_AVAIL ||
374 status == RLN_STATUS_RX_HILEN_AVAIL ||
375 status == RLN_STATUS_RX_ERROR)
376 break;
377 DELAY(1000);
378 status = rln_status_rx_read(sc);
379 }
380 splx(s);
381 dprintf(" (%dms)",i);
382
383 if (sc->sc_width == 16) {
384 if (status != RLN_STATUS_RX_HILEN_AVAIL)
385 goto badstatus_quiet;
386
387 len = rln_data_read_2(sc);
388 } else if (sc->sc_width == 8) {
389 if (status != RLN_STATUS_RX_LOLEN_AVAIL)
390 goto badstatus_quiet;
391
392 lo = rln_data_read_1(sc);
393 rln_status_rx_write(sc, RLN_STATUS_RX_LOLEN_ACCEPT);
394 rln_status_rx_int(sc);
395 s = spl0();
396 for (i = 0; i < 600; i++) {
397 status = rln_status_rx_read(sc);
398 if (status == RLN_STATUS_RX_HILEN_AVAIL)
399 break;
400 DELAY(1000);
401 }
402 splx(s);
403 if (status != RLN_STATUS_RX_HILEN_AVAIL)
404 goto badstatus;
405
406 hi = rln_data_read_1(sc);
407 len = lo | (hi << 8);
408 }
409 #ifdef DIAGNOSTIC
410 else
411 panic("rln: bus width %d", sc->sc_width);
412 #endif
413
414 dprintf(" len=%d]", len);
415 return (len);
416
417 badstatus:
418 printf("%s: rx_request timed out, status %02x\n",
419 sc->sc_dev.dv_xname, status);
420 badstatus_quiet:
421 if (status == RLN_STATUS_RX_ERROR)
422 printf("%s: rx protocol error (nak)\n", sc->sc_dev.dv_xname);
423 dprintf("]");
424 return (-1);
425 }
426
427
428 void
429 rln_rx_pdata(sc, buf, len, pd)
430 struct rln_softc * sc;
431 void * buf;
432 int len;
433 struct rln_pdata * pd;
434 {
435 char * data = (char *)buf;
436
437 if (pd->p_nremain) {
438 *data++ = pd->p_data;
439 if (--len == 0)
440 return;
441 }
442
443 pd->p_nremain = 0;
444
445 if (sc->sc_width == 16) {
446
447 rln_data_read_multi_2(sc, data, len / 2);
448 #ifdef RLNDEBUG_REG
449 dprintf(" D>");
450 dprinthex(data, len);
451 #endif
452 if (len & 1) {
453
454 union {
455 u_int16_t w;
456 u_int8_t b[2];
457 } u;
458
459 u.w = rln_data_read_2(sc);
460 data[len - 1] = u.b[0];
461 pd->p_data = u.b[1];
462 pd->p_nremain = 1;
463 #ifdef RLNDEBUG_REG
464 dprintf(" D>{%02x%02x}", u.b[0], u.b[1]);
465 #endif
466 }
467 } else if (sc->sc_width == 8) {
468 rln_data_read_multi_1(sc, data, len);
469 #ifdef RLNDEBUG_REG
470 dprintf(" D>");
471 dprinthex(data, len);
472 #endif
473 if (len & 1) {
474
475 pd->p_data = rln_data_read_1(sc);
476 pd->p_nremain = 1;
477 #ifdef RLNDEBUG_REG
478 dprintf(" D>{%02x}", pd->p_data);
479 #endif
480 }
481 }
482
483 }
484
485 int
486 rln_rx_data(sc, buf, len)
487 struct rln_softc * sc;
488 void * buf;
489 int len;
490 {
491
492 struct rln_pdata pd = { 0, 0 };
493 int s;
494 int i;
495 u_int8_t status;
496
497 dprintf(" Rd[");
498 rln_status_rx_write(sc, RLN_STATUS_RX_HILEN_ACCEPT);
499 rln_status_rx_int(sc);
500 s = spl0();
501 for (i = 0; i < 600; i++) {
502 status = rln_status_rx_read(sc);
503 if (status == RLN_STATUS_RX_XFR)
504 break;
505 DELAY(1000);
506 }
507 splx(s);
508 if (status != RLN_STATUS_RX_XFR) {
509 dprintf("]=-1");
510 return (-1);
511 }
512
513 rln_rx_pdata(sc, buf, len, &pd);
514 #ifdef DIAGNOSTIC
515
516 if (pd.p_nremain || len & 1)
517 panic("rln_rx_data: leftover");
518 #endif
519
520 dprintf("]=0");
521 return (0);
522 }
523
524 void
525 rln_rx_end(sc)
526 struct rln_softc * sc;
527 {
528
529
530 dprintf(" Re[");
531 rln_status_rx_write(sc, RLN_STATUS_RX_XFR_COMPLETE);
532 rln_status_rx_int(sc);
533
534 dprintf("]");
535 }
536
537
538 void
539 rln_clear_nak(sc)
540 struct rln_softc * sc;
541 {
542
543
544 rln_status_tx_write(sc, RLN_STATUS_CLRNAK);
545 rln_status_tx_int(sc);
546 }
547
548
549
550
551
552
553
554 int
555 rln_msg_tx_start(sc, buf, pktlen, state)
556 struct rln_softc * sc;
557 void * buf;
558 int pktlen;
559 struct rln_msg_tx_state * state;
560 {
561 struct rln_mm_cmd * cmd = (struct rln_mm_cmd *)buf;
562 int ret;
563
564 state->ien = rln_enable(sc, 0);
565 state->pd.p_nremain = 0;
566
567 if (!(cmd->cmd_letter == 'A' && cmd->cmd_fn == 6))
568 state->w = rln_wakeup(sc, RLN_WAKEUP_SET);
569 else
570 state->w = RLN_WAKEUP_NOCHANGE;
571
572 ret = rln_tx_request(sc, pktlen);
573 if (ret == 2) {
574 rln_clear_nak(sc);
575 if (sc->sc_cardtype & RLN_CTYPE_OEM)
576 rln_need_reset(sc);
577 ret = 2;
578 }
579 else if (ret == 1) {
580
581 rln_status_tx_write(sc, RLN_STATUS_TX_XFR);
582 ret = -1;
583 }
584 return (ret);
585 }
586
587 void
588 rln_msg_tx_data(sc, buf, len, state)
589 struct rln_softc * sc;
590 void * buf;
591 u_int16_t len;
592 struct rln_msg_tx_state * state;
593 {
594 char * data = (char *)buf;
595
596 if (sc->sc_width == 16 && state->pd.p_nremain) {
597
598 union {
599 u_int8_t b[2];
600 u_int16_t w;
601 } u;
602
603 u.b[0] = state->pd.p_data;
604 if (len) {
605 u.b[1] = *data++;
606 len--;
607 } else
608 u.b[1] = '\0';
609 #ifdef RLNDEBUG_REG
610 dprintf(" D<%02x%02x", u.b[0], u.b[1]);
611 #endif
612 rln_data_write_2(sc, u.w);
613 state->pd.p_nremain = 0;
614 }
615
616 if (len) {
617 if (sc->sc_width == 16) {
618 if (len >= 2)
619 rln_data_write_multi_2(sc, buf, len / 2);
620 if (len & 1) {
621 state->pd.p_nremain = 1;
622 state->pd.p_data = data[len - 1];
623 }
624 } else if (sc->sc_width == 8)
625 rln_data_write_multi_1(sc, buf, len);
626 #ifdef DIAGNOSTIC
627 else
628 panic("rln_msg_tx_data width %d", sc->sc_width);
629 #endif
630 #ifdef RLNDEBUG_REG
631 dprintf(" D<");
632 dprinthex(data, len);
633 #endif
634 }
635 }
636
637
638 int
639 rln_msg_tx_end(sc, state)
640 struct rln_softc * sc;
641 struct rln_msg_tx_state * state;
642 {
643 int ret;
644
645
646 if (state->pd.p_nremain)
647 rln_msg_tx_data(sc, NULL, 0, state);
648
649 #ifdef DIAGNOSTIC
650 if (state->pd.p_nremain)
651 panic("rln_msg_tx_end remain %d", state->pd.p_nremain);
652 #endif
653 ret = rln_tx_end(sc);
654 if (sc->sc_arpcom.ac_if.if_flags & IFF_OACTIVE)
655 state->w = RLN_WAKEUP_NOCHANGE;
656 rln_wakeup(sc, state->w);
657 rln_enable(sc, state->ien);
658 return (ret);
659 }
660
661
662 u_int8_t
663 rln_newseq(sc)
664 struct rln_softc * sc;
665 {
666 int s;
667 u_int8_t seq;
668
669 s = splhigh();
670 seq = sc->sc_pktseq++;
671 if (sc->sc_pktseq > RLN_MAXSEQ)
672 sc->sc_pktseq = 0;
673 splx(s);
674 return (seq);
675 }
676
677
678
679
680
681
682
683
684
685
686 int
687 rln_msg_txrx(sc, tx, txlen, rx, rxlen)
688 struct rln_softc * sc;
689 void * tx;
690 int txlen;
691 void * rx;
692 int rxlen;
693 {
694 struct rln_mm_cmd * txc = (struct rln_mm_cmd *)tx;
695 struct rln_mm_cmd * rxc = (struct rln_mm_cmd *)rx;
696 struct rln_msg_tx_state state;
697 int ien;
698 int ret;
699
700 #ifdef DIAGNOSTIC
701 if (rx != NULL && rxlen < sizeof *rxc)
702 panic("rln_msg_txrx");
703 #endif
704
705 txc->cmd_seq = rln_newseq(sc);
706
707 #ifdef RLNDUMP
708 printf("%s: send %c%d seq %d data ", sc->sc_dev.dv_xname,
709 txc->cmd_letter, txc->cmd_fn, txc->cmd_seq);
710 RLNDUMPHEX(txc, sizeof *txc);
711 printf(":");
712 RLNDUMPHEX((char *)tx + sizeof *txc, txlen - sizeof *txc);
713 printf("\n");
714 #endif
715
716 if (rx != NULL)
717 if (rln_mbox_create(sc, txc->cmd_seq, rx, rxlen) < 0)
718
719 return (-1);
720
721
722 if ((ret = rln_msg_tx_start(sc, tx, txlen, &state))) {
723 if (rx != NULL)
724 rln_mbox_wait(sc, txc->cmd_seq, -1);
725 return (ret);
726 }
727
728
729 rln_msg_tx_data(sc, tx, (txlen + 1) & ~1, &state);
730
731
732 if ((ret = rln_msg_tx_end(sc, &state))) {
733
734 if (rx != NULL)
735 rln_mbox_wait(sc, txc->cmd_seq, -1);
736 return (ret);
737 }
738
739
740 if (rx == NULL)
741 return (0);
742
743
744 ien = rln_enable(sc, 1);
745
746
747 if (rln_mbox_wait(sc, txc->cmd_seq, 4000) <= 0) {
748 printf("%s: lost message %c%d seq %d\n", sc->sc_dev.dv_xname,
749 txc->cmd_letter, txc->cmd_fn, txc->cmd_seq);
750 rln_enable(sc, ien);
751 return (-1);
752 }
753 rln_enable(sc, ien);
754
755 #ifdef RLNDUMP
756 printf("%s: recv %c%d seq %d data ", sc->sc_dev.dv_xname,
757 rxc->cmd_letter, rxc->cmd_fn, rxc->cmd_seq);
758 RLNDUMPHEX(rxc, sizeof *rxc);
759 printf(":");
760 RLNDUMPHEX(((char *)rx) + sizeof *rxc, rxlen - sizeof *rxc);
761 printf("\n");
762 #endif
763
764
765 if (rxc->cmd_error & 0x80) {
766 printf("%s: command error 0x%02x command %c%d\n",
767 sc->sc_dev.dv_xname,
768 rxc->cmd_error & ~0x80,
769 rxc->cmd_letter, rxc->cmd_fn);
770 return (-1);
771 }
772
773 return (0);
774 }
775
776
777
778
779
780
781
782
783
784
785
786 int
787 rln_mbox_create(sc, seq, buf, len)
788 struct rln_softc * sc;
789 u_int8_t seq;
790 void * buf;
791 size_t len;
792 {
793 int s;
794 struct rln_mbox * mb = &sc->sc_mbox[seq];
795
796 dprintf(" <create %d", seq);
797
798 #ifdef DIAGNOSTIC
799 if (seq > RLN_NMBOX)
800 panic("mbox create");
801 #endif
802
803 s = splhigh();
804 if (mb->mb_state != RLNMBOX_VOID) {
805 #ifdef DIAGNOSTIC
806 printf("mbox collision");
807 #endif
808 splx(s);
809 return (-1);
810 }
811 mb->mb_buf = buf;
812 mb->mb_len = len;
813 mb->mb_actlen = 0;
814 mb->mb_state = RLNMBOX_EMPTY;
815 dprintf(" empty>");
816 splx(s);
817 return (0);
818 }
819
820
821
822 int
823 rln_mbox_wait(sc, seq, timeo)
824 struct rln_softc * sc;
825 u_int8_t seq;
826 int timeo;
827 {
828 int i;
829 int s;
830 int ret;
831 volatile struct rln_mbox * mb = &sc->sc_mbox[seq];
832
833 dprintf(" <wait %d", seq);
834
835 #ifdef DIAGNOSTIC
836 if (seq > RLN_NMBOX)
837 panic("mbox wait");
838 #endif
839
840 #if defined(RLN_TSLEEP)
841 if (!cold) {
842 tsleep((void *)mb, PRIBIO, "rlnmbox", hz * timeo / 1000);
843 if (mb->mb_state == RLNMBOX_FILLING) {
844
845 s = spl0();
846 while (mb->mb_state == RLNMBOX_FILLING)
847 ;
848 splx(s);
849 }
850 } else {
851
852 #endif
853 s = spl0();
854 i = 0;
855 while (mb->mb_state == RLNMBOX_EMPTY && i < timeo) {
856 DELAY(1000);
857 i++;
858 }
859 if (i)
860 dprintf(" %dms", i);
861 while (mb->mb_state == RLNMBOX_FILLING)
862 ;
863 splx(s);
864 #if defined(RLN_TSLEEP)
865 }
866 #endif
867
868 s = splhigh();
869
870 #ifdef DIAGNOSTIC
871 if (mb->mb_state != RLNMBOX_EMPTY && mb->mb_state != RLNMBOX_FILLED)
872 panic("mbox wait %d", mb->mb_state);
873 #endif
874 ret = mb->mb_actlen;
875 mb->mb_state = RLNMBOX_VOID;
876 dprintf(" void>=%d", ret);
877 splx(s);
878 return (ret);
879 }
880
881
882 int
883 rln_mbox_lock(sc, seq, bufp, lenp)
884 struct rln_softc * sc;
885 u_int8_t seq;
886 void ** bufp;
887 size_t * lenp;
888 {
889 int s;
890 struct rln_mbox * mb = &sc->sc_mbox[seq];
891
892 dprintf(" <lock %d", seq);
893
894 s = splhigh();
895 #ifdef DIAGNOSTIC
896 if (seq > RLN_NMBOX)
897 panic("mbox lock");
898 #endif
899 if (mb->mb_state != RLNMBOX_EMPTY) {
900 splx(s);
901 dprintf(" ?>");
902 return (-1);
903 }
904
905 mb->mb_state = RLNMBOX_FILLING;
906 dprintf(" filling>");
907 *bufp = mb->mb_buf;
908 *lenp = mb->mb_len;
909
910 splx(s);
911 return (0);
912 }
913
914
915 void
916 rln_mbox_unlock(sc, seq, actlen)
917 struct rln_softc * sc;
918 u_int8_t seq;
919 size_t actlen;
920 {
921 int s;
922 struct rln_mbox * mb = &sc->sc_mbox[seq];
923
924 dprintf(" <unlock %d", seq);
925
926 s = splhigh();
927 #ifdef DIAGNOSTIC
928 if (seq > RLN_NMBOX)
929 panic("mbox unlock seq");
930 if (mb->mb_state != RLNMBOX_FILLING)
931 panic("mbox unlock");
932 #endif
933 mb->mb_state = RLNMBOX_FILLED;
934 dprintf(" filled>");
935 mb->mb_actlen = actlen;
936 #if defined(RLN_TSLEEP)
937 wakeup(mb);
938 #endif
939 splx(s);
940 }
941