This source file includes following definitions.
- upl_match
- upl_attach
- upl_detach
- upl_activate
- upl_newbuf
- upl_rx_list_init
- upl_tx_list_init
- upl_rxeof
- upl_txeof
- upl_send
- upl_start
- upl_init
- upl_openpipes
- upl_intr
- upl_ioctl
- upl_watchdog
- upl_stop
- upl_output
- upl_input
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44 #include "bpfilter.h"
45
46 #include <sys/param.h>
47 #include <sys/systm.h>
48 #include <sys/timeout.h>
49 #include <sys/sockio.h>
50 #include <sys/mbuf.h>
51 #include <sys/malloc.h>
52 #include <sys/kernel.h>
53 #include <sys/socket.h>
54
55 #include <sys/device.h>
56
57 #include <net/if.h>
58 #include <net/if_types.h>
59 #include <net/if_dl.h>
60 #include <net/netisr.h>
61
62 #if NBPFILTER > 0
63 #include <net/bpf.h>
64 #endif
65
66 #ifdef INET
67 #include <netinet/in.h>
68 #include <netinet/in_var.h>
69 #include <netinet/in_systm.h>
70 #include <netinet/ip.h>
71 #include <netinet/if_ether.h>
72 #else
73 #error upl without INET?
74 #endif
75
76 #include <dev/usb/usb.h>
77 #include <dev/usb/usbdi.h>
78 #include <dev/usb/usbdi_util.h>
79 #include <dev/usb/usbdevs.h>
80
81
82
83
84
85
86
87
88
89
90 #define UPL_RXDATA 0x40
91 #define UPL_TXOK 0x80
92
93 #define UPL_INTR_PKTLEN 1
94
95 #define UPL_CONFIG_NO 1
96 #define UPL_IFACE_IDX 0
97
98
99
100 #define UPL_INTR_INTERVAL 20
101
102 #define UPL_BUFSZ 1024
103
104 #define UPL_RX_FRAMES 1
105 #define UPL_TX_FRAMES 1
106
107 #define UPL_RX_LIST_CNT 1
108 #define UPL_TX_LIST_CNT 1
109
110 #define UPL_ENDPT_RX 0x0
111 #define UPL_ENDPT_TX 0x1
112 #define UPL_ENDPT_INTR 0x2
113 #define UPL_ENDPT_MAX 0x3
114
115 struct upl_type {
116 u_int16_t upl_vid;
117 u_int16_t upl_did;
118 };
119
120 struct upl_softc;
121
122 struct upl_chain {
123 struct upl_softc *upl_sc;
124 usbd_xfer_handle upl_xfer;
125 char *upl_buf;
126 struct mbuf *upl_mbuf;
127 int upl_idx;
128 };
129
130 struct upl_cdata {
131 struct upl_chain upl_tx_chain[UPL_TX_LIST_CNT];
132 struct upl_chain upl_rx_chain[UPL_RX_LIST_CNT];
133 int upl_tx_prod;
134 int upl_tx_cons;
135 int upl_tx_cnt;
136 int upl_rx_prod;
137 };
138
139 struct upl_softc {
140 struct device sc_dev;
141
142 struct ifnet sc_if;
143 struct timeout sc_stat_ch;
144
145 usbd_device_handle sc_udev;
146 usbd_interface_handle sc_iface;
147 u_int16_t sc_vendor;
148 u_int16_t sc_product;
149 int sc_ed[UPL_ENDPT_MAX];
150 usbd_pipe_handle sc_ep[UPL_ENDPT_MAX];
151 struct upl_cdata sc_cdata;
152
153 uByte sc_ibuf;
154
155 char sc_dying;
156 char sc_attached;
157 u_int sc_rx_errs;
158 struct timeval sc_rx_notice;
159 u_int sc_intr_errs;
160 };
161
162 #ifdef UPL_DEBUG
163 #define DPRINTF(x) do { if (upldebug) printf x; } while (0)
164 #define DPRINTFN(n,x) do { if (upldebug >= (n)) printf x; } while (0)
165 int upldebug = 0;
166 #else
167 #define DPRINTF(x)
168 #define DPRINTFN(n,x)
169 #endif
170
171
172
173
174 struct upl_type sc_devs[] = {
175 { USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2301 },
176 { USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2302 },
177 { 0, 0 }
178 };
179
180 int upl_match(struct device *, void *, void *);
181 void upl_attach(struct device *, struct device *, void *);
182 int upl_detach(struct device *, int);
183 int upl_activate(struct device *, enum devact);
184
185 struct cfdriver upl_cd = {
186 NULL, "upl", DV_IFNET
187 };
188
189 const struct cfattach upl_ca = {
190 sizeof(struct upl_softc),
191 upl_match,
192 upl_attach,
193 upl_detach,
194 upl_activate,
195 };
196
197 int upl_openpipes(struct upl_softc *);
198 int upl_tx_list_init(struct upl_softc *);
199 int upl_rx_list_init(struct upl_softc *);
200 int upl_newbuf(struct upl_softc *, struct upl_chain *, struct mbuf *);
201 int upl_send(struct upl_softc *, struct mbuf *, int);
202 void upl_intr(usbd_xfer_handle, usbd_private_handle, usbd_status);
203 void upl_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
204 void upl_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
205 void upl_start(struct ifnet *);
206 int upl_ioctl(struct ifnet *, u_long, caddr_t);
207 void upl_init(void *);
208 void upl_stop(struct upl_softc *);
209 void upl_watchdog(struct ifnet *);
210
211 int upl_output(struct ifnet *, struct mbuf *, struct sockaddr *,
212 struct rtentry *);
213 void upl_input(struct ifnet *, struct mbuf *);
214
215
216
217
218 int
219 upl_match(struct device *parent, void *match, void *aux)
220 {
221 struct usb_attach_arg *uaa = aux;
222 struct upl_type *t;
223
224 if (uaa->iface != NULL)
225 return (UMATCH_NONE);
226
227 for (t = sc_devs; t->upl_vid != 0; t++)
228 if (uaa->vendor == t->upl_vid && uaa->product == t->upl_did)
229 return (UMATCH_VENDOR_PRODUCT);
230
231 return (UMATCH_NONE);
232 }
233
234 void
235 upl_attach(struct device *parent, struct device *self, void *aux)
236 {
237 struct upl_softc *sc = (struct upl_softc *)self;
238 struct usb_attach_arg *uaa = aux;
239 char *devinfop;
240 int s;
241 usbd_device_handle dev = uaa->device;
242 usbd_interface_handle iface;
243 usbd_status err;
244 struct ifnet *ifp;
245 usb_interface_descriptor_t *id;
246 usb_endpoint_descriptor_t *ed;
247 int i;
248
249 DPRINTFN(5,(" : upl_attach: sc=%p, dev=%p", sc, dev));
250
251 devinfop = usbd_devinfo_alloc(dev, 0);
252 printf("\n%s: %s\n", sc->sc_dev.dv_xname, devinfop);
253 usbd_devinfo_free(devinfop);
254
255 err = usbd_set_config_no(dev, UPL_CONFIG_NO, 1);
256 if (err) {
257 printf("%s: setting config no failed\n",
258 sc->sc_dev.dv_xname);
259 return;
260 }
261
262 sc->sc_udev = dev;
263 sc->sc_product = uaa->product;
264 sc->sc_vendor = uaa->vendor;
265
266 err = usbd_device2interface_handle(dev, UPL_IFACE_IDX, &iface);
267 if (err) {
268 printf("%s: getting interface handle failed\n",
269 sc->sc_dev.dv_xname);
270 return;
271 }
272
273 sc->sc_iface = iface;
274 id = usbd_get_interface_descriptor(iface);
275
276
277 for (i = 0; i < id->bNumEndpoints; i++) {
278 ed = usbd_interface2endpoint_descriptor(iface, i);
279 if (ed == NULL) {
280 printf("%s: couldn't get ep %d\n",
281 sc->sc_dev.dv_xname, i);
282 return;
283 }
284 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
285 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
286 sc->sc_ed[UPL_ENDPT_RX] = ed->bEndpointAddress;
287 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
288 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
289 sc->sc_ed[UPL_ENDPT_TX] = ed->bEndpointAddress;
290 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
291 UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
292 sc->sc_ed[UPL_ENDPT_INTR] = ed->bEndpointAddress;
293 }
294 }
295
296 if (sc->sc_ed[UPL_ENDPT_RX] == 0 || sc->sc_ed[UPL_ENDPT_TX] == 0 ||
297 sc->sc_ed[UPL_ENDPT_INTR] == 0) {
298 printf("%s: missing endpoint\n", sc->sc_dev.dv_xname);
299 return;
300 }
301
302 s = splnet();
303
304
305 ifp = &sc->sc_if;
306 ifp->if_softc = sc;
307 ifp->if_mtu = UPL_BUFSZ;
308 ifp->if_flags = IFF_POINTOPOINT | IFF_NOARP | IFF_SIMPLEX;
309 ifp->if_ioctl = upl_ioctl;
310 ifp->if_start = upl_start;
311 ifp->if_watchdog = upl_watchdog;
312 strlcpy(ifp->if_xname, sc->sc_dev.dv_xname, IFNAMSIZ);
313
314 ifp->if_type = IFT_OTHER;
315 ifp->if_addrlen = 0;
316 ifp->if_hdrlen = 0;
317 ifp->if_output = upl_output;
318 ifp->if_baudrate = 12000000;
319 IFQ_SET_READY(&ifp->if_snd);
320
321
322 if_attach(ifp);
323 if_alloc_sadl(ifp);
324
325 sc->sc_attached = 1;
326 splx(s);
327
328 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
329 &sc->sc_dev);
330 }
331
332 int
333 upl_detach(struct device *self, int flags)
334 {
335 struct upl_softc *sc = (struct upl_softc *)self;
336 struct ifnet *ifp = &sc->sc_if;
337 int s;
338
339 DPRINTFN(2,("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__));
340
341 s = splusb();
342
343 if (!sc->sc_attached) {
344
345 splx(s);
346 return (0);
347 }
348
349 if (ifp->if_flags & IFF_RUNNING)
350 upl_stop(sc);
351
352 if_detach(ifp);
353
354 #ifdef DIAGNOSTIC
355 if (sc->sc_ep[UPL_ENDPT_TX] != NULL ||
356 sc->sc_ep[UPL_ENDPT_RX] != NULL ||
357 sc->sc_ep[UPL_ENDPT_INTR] != NULL)
358 printf("%s: detach has active endpoints\n",
359 sc->sc_dev.dv_xname);
360 #endif
361
362 sc->sc_attached = 0;
363 splx(s);
364
365 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
366 &sc->sc_dev);
367
368 return (0);
369 }
370
371 int
372 upl_activate(struct device *self, enum devact act)
373 {
374 struct upl_softc *sc = (struct upl_softc *)self;
375
376 DPRINTFN(2,("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__));
377
378 switch (act) {
379 case DVACT_ACTIVATE:
380 break;
381
382 case DVACT_DEACTIVATE:
383 sc->sc_dying = 1;
384 break;
385 }
386 return (0);
387 }
388
389
390
391
392 int
393 upl_newbuf(struct upl_softc *sc, struct upl_chain *c, struct mbuf *m)
394 {
395 struct mbuf *m_new = NULL;
396
397 DPRINTFN(8,("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__));
398
399 if (m == NULL) {
400 MGETHDR(m_new, M_DONTWAIT, MT_DATA);
401 if (m_new == NULL) {
402 printf("%s: no memory for rx list "
403 "-- packet dropped!\n", sc->sc_dev.dv_xname);
404 return (ENOBUFS);
405 }
406
407 MCLGET(m_new, M_DONTWAIT);
408 if (!(m_new->m_flags & M_EXT)) {
409 printf("%s: no memory for rx list "
410 "-- packet dropped!\n", sc->sc_dev.dv_xname);
411 m_freem(m_new);
412 return (ENOBUFS);
413 }
414 m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
415 } else {
416 m_new = m;
417 m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
418 m_new->m_data = m_new->m_ext.ext_buf;
419 }
420
421 c->upl_mbuf = m_new;
422
423 return (0);
424 }
425
426 int
427 upl_rx_list_init(struct upl_softc *sc)
428 {
429 struct upl_cdata *cd;
430 struct upl_chain *c;
431 int i;
432
433 DPRINTFN(5,("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__));
434
435 cd = &sc->sc_cdata;
436 for (i = 0; i < UPL_RX_LIST_CNT; i++) {
437 c = &cd->upl_rx_chain[i];
438 c->upl_sc = sc;
439 c->upl_idx = i;
440 if (upl_newbuf(sc, c, NULL) == ENOBUFS)
441 return (ENOBUFS);
442 if (c->upl_xfer == NULL) {
443 c->upl_xfer = usbd_alloc_xfer(sc->sc_udev);
444 if (c->upl_xfer == NULL)
445 return (ENOBUFS);
446 c->upl_buf = usbd_alloc_buffer(c->upl_xfer, UPL_BUFSZ);
447 if (c->upl_buf == NULL) {
448 usbd_free_xfer(c->upl_xfer);
449 return (ENOBUFS);
450 }
451 }
452 }
453
454 return (0);
455 }
456
457 int
458 upl_tx_list_init(struct upl_softc *sc)
459 {
460 struct upl_cdata *cd;
461 struct upl_chain *c;
462 int i;
463
464 DPRINTFN(5,("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__));
465
466 cd = &sc->sc_cdata;
467 for (i = 0; i < UPL_TX_LIST_CNT; i++) {
468 c = &cd->upl_tx_chain[i];
469 c->upl_sc = sc;
470 c->upl_idx = i;
471 c->upl_mbuf = NULL;
472 if (c->upl_xfer == NULL) {
473 c->upl_xfer = usbd_alloc_xfer(sc->sc_udev);
474 if (c->upl_xfer == NULL)
475 return (ENOBUFS);
476 c->upl_buf = usbd_alloc_buffer(c->upl_xfer, UPL_BUFSZ);
477 if (c->upl_buf == NULL) {
478 usbd_free_xfer(c->upl_xfer);
479 return (ENOBUFS);
480 }
481 }
482 }
483
484 return (0);
485 }
486
487
488
489
490
491 void
492 upl_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
493 {
494 struct upl_chain *c = priv;
495 struct upl_softc *sc = c->upl_sc;
496 struct ifnet *ifp = &sc->sc_if;
497 struct mbuf *m;
498 int total_len = 0;
499 int s;
500
501 if (sc->sc_dying)
502 return;
503
504 if (!(ifp->if_flags & IFF_RUNNING))
505 return;
506
507 if (status != USBD_NORMAL_COMPLETION) {
508 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
509 return;
510 sc->sc_rx_errs++;
511 if (usbd_ratecheck(&sc->sc_rx_notice)) {
512 printf("%s: %u usb errors on rx: %s\n",
513 sc->sc_dev.dv_xname, sc->sc_rx_errs,
514 usbd_errstr(status));
515 sc->sc_rx_errs = 0;
516 }
517 if (status == USBD_STALLED)
518 usbd_clear_endpoint_stall_async(sc->sc_ep[UPL_ENDPT_RX]);
519 goto done;
520 }
521
522 usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL);
523
524 DPRINTFN(9,("%s: %s: enter status=%d length=%d\n",
525 sc->sc_dev.dv_xname, __func__, status, total_len));
526
527 m = c->upl_mbuf;
528 memcpy(mtod(c->upl_mbuf, char *), c->upl_buf, total_len);
529
530 ifp->if_ipackets++;
531 m->m_pkthdr.len = m->m_len = total_len;
532
533 m->m_pkthdr.rcvif = ifp;
534
535 s = splnet();
536
537
538 if (upl_newbuf(sc, c, NULL) == ENOBUFS) {
539 ifp->if_ierrors++;
540 goto done1;
541 }
542
543 #if NBPFILTER > 0
544
545
546
547
548
549
550 if (ifp->if_bpf) {
551 bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_IN);
552 }
553 #endif
554
555 DPRINTFN(10,("%s: %s: deliver %d\n", sc->sc_dev.dv_xname,
556 __func__, m->m_len));
557
558 ether_input_mbuf(ifp, m);
559
560 done1:
561 splx(s);
562
563 done:
564 #if 1
565
566 usbd_setup_xfer(c->upl_xfer, sc->sc_ep[UPL_ENDPT_RX],
567 c, c->upl_buf, UPL_BUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY,
568 USBD_NO_TIMEOUT, upl_rxeof);
569 usbd_transfer(c->upl_xfer);
570
571 DPRINTFN(10,("%s: %s: start rx\n", sc->sc_dev.dv_xname,
572 __func__));
573 #endif
574 }
575
576
577
578
579
580 void
581 upl_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
582 {
583 struct upl_chain *c = priv;
584 struct upl_softc *sc = c->upl_sc;
585 struct ifnet *ifp = &sc->sc_if;
586 int s;
587
588 if (sc->sc_dying)
589 return;
590
591 s = splnet();
592
593 DPRINTFN(10,("%s: %s: enter status=%d\n", sc->sc_dev.dv_xname,
594 __func__, status));
595
596 ifp->if_timer = 0;
597 ifp->if_flags &= ~IFF_OACTIVE;
598
599 if (status != USBD_NORMAL_COMPLETION) {
600 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
601 splx(s);
602 return;
603 }
604 ifp->if_oerrors++;
605 printf("%s: usb error on tx: %s\n", sc->sc_dev.dv_xname,
606 usbd_errstr(status));
607 if (status == USBD_STALLED)
608 usbd_clear_endpoint_stall_async(sc->sc_ep[UPL_ENDPT_TX]);
609 splx(s);
610 return;
611 }
612
613 ifp->if_opackets++;
614
615 m_freem(c->upl_mbuf);
616 c->upl_mbuf = NULL;
617
618 if (IFQ_IS_EMPTY(&ifp->if_snd) == 0)
619 upl_start(ifp);
620
621 splx(s);
622 }
623
624 int
625 upl_send(struct upl_softc *sc, struct mbuf *m, int idx)
626 {
627 int total_len;
628 struct upl_chain *c;
629 usbd_status err;
630
631 c = &sc->sc_cdata.upl_tx_chain[idx];
632
633
634
635
636
637 m_copydata(m, 0, m->m_pkthdr.len, c->upl_buf);
638 c->upl_mbuf = m;
639
640 total_len = m->m_pkthdr.len;
641
642 DPRINTFN(10,("%s: %s: total_len=%d\n",
643 sc->sc_dev.dv_xname, __func__, total_len));
644
645 usbd_setup_xfer(c->upl_xfer, sc->sc_ep[UPL_ENDPT_TX],
646 c, c->upl_buf, total_len, USBD_NO_COPY, USBD_DEFAULT_TIMEOUT,
647 upl_txeof);
648
649
650 err = usbd_transfer(c->upl_xfer);
651 if (err != USBD_IN_PROGRESS) {
652 printf("%s: upl_send error=%s\n", sc->sc_dev.dv_xname,
653 usbd_errstr(err));
654 upl_stop(sc);
655 return (EIO);
656 }
657
658 sc->sc_cdata.upl_tx_cnt++;
659
660 return (0);
661 }
662
663 void
664 upl_start(struct ifnet *ifp)
665 {
666 struct upl_softc *sc = ifp->if_softc;
667 struct mbuf *m_head = NULL;
668
669 if (sc->sc_dying)
670 return;
671
672 DPRINTFN(10,("%s: %s: enter\n", sc->sc_dev.dv_xname,__func__));
673
674 if (ifp->if_flags & IFF_OACTIVE)
675 return;
676
677 IFQ_POLL(&ifp->if_snd, m_head);
678 if (m_head == NULL)
679 return;
680
681 if (upl_send(sc, m_head, 0)) {
682 ifp->if_flags |= IFF_OACTIVE;
683 return;
684 }
685
686 IFQ_DEQUEUE(&ifp->if_snd, m_head);
687
688 #if NBPFILTER > 0
689
690
691
692
693 if (ifp->if_bpf)
694 bpf_mtap(ifp->if_bpf, m_head, BPF_DIRECTION_OUT);
695 #endif
696
697 ifp->if_flags |= IFF_OACTIVE;
698
699
700
701
702 ifp->if_timer = 5;
703 }
704
705 void
706 upl_init(void *xsc)
707 {
708 struct upl_softc *sc = xsc;
709 struct ifnet *ifp = &sc->sc_if;
710 int s;
711
712 if (sc->sc_dying)
713 return;
714
715 DPRINTFN(10,("%s: %s: enter\n", sc->sc_dev.dv_xname,__func__));
716
717 if (ifp->if_flags & IFF_RUNNING)
718 return;
719
720 s = splnet();
721
722
723 if (upl_tx_list_init(sc) == ENOBUFS) {
724 printf("%s: tx list init failed\n", sc->sc_dev.dv_xname);
725 splx(s);
726 return;
727 }
728
729
730 if (upl_rx_list_init(sc) == ENOBUFS) {
731 printf("%s: rx list init failed\n", sc->sc_dev.dv_xname);
732 splx(s);
733 return;
734 }
735
736 if (sc->sc_ep[UPL_ENDPT_RX] == NULL) {
737 if (upl_openpipes(sc)) {
738 splx(s);
739 return;
740 }
741 }
742
743 ifp->if_flags |= IFF_RUNNING;
744 ifp->if_flags &= ~IFF_OACTIVE;
745
746 splx(s);
747 }
748
749 int
750 upl_openpipes(struct upl_softc *sc)
751 {
752 struct upl_chain *c;
753 usbd_status err;
754 int i;
755
756
757 err = usbd_open_pipe(sc->sc_iface, sc->sc_ed[UPL_ENDPT_RX],
758 USBD_EXCLUSIVE_USE, &sc->sc_ep[UPL_ENDPT_RX]);
759 if (err) {
760 printf("%s: open rx pipe failed: %s\n",
761 sc->sc_dev.dv_xname, usbd_errstr(err));
762 return (EIO);
763 }
764 err = usbd_open_pipe(sc->sc_iface, sc->sc_ed[UPL_ENDPT_TX],
765 USBD_EXCLUSIVE_USE, &sc->sc_ep[UPL_ENDPT_TX]);
766 if (err) {
767 printf("%s: open tx pipe failed: %s\n",
768 sc->sc_dev.dv_xname, usbd_errstr(err));
769 return (EIO);
770 }
771 err = usbd_open_pipe_intr(sc->sc_iface, sc->sc_ed[UPL_ENDPT_INTR],
772 USBD_EXCLUSIVE_USE, &sc->sc_ep[UPL_ENDPT_INTR], sc,
773 &sc->sc_ibuf, UPL_INTR_PKTLEN, upl_intr,
774 UPL_INTR_INTERVAL);
775 if (err) {
776 printf("%s: open intr pipe failed: %s\n",
777 sc->sc_dev.dv_xname, usbd_errstr(err));
778 return (EIO);
779 }
780
781
782 #if 1
783
784 for (i = 0; i < UPL_RX_LIST_CNT; i++) {
785 c = &sc->sc_cdata.upl_rx_chain[i];
786 usbd_setup_xfer(c->upl_xfer, sc->sc_ep[UPL_ENDPT_RX],
787 c, c->upl_buf, UPL_BUFSZ,
788 USBD_SHORT_XFER_OK | USBD_NO_COPY, USBD_NO_TIMEOUT,
789 upl_rxeof);
790 usbd_transfer(c->upl_xfer);
791 }
792 #endif
793
794 return (0);
795 }
796
797 void
798 upl_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
799 {
800 struct upl_softc *sc = priv;
801 struct ifnet *ifp = &sc->sc_if;
802 uByte stat;
803
804 DPRINTFN(15,("%s: %s: enter\n", sc->sc_dev.dv_xname,__func__));
805
806 if (sc->sc_dying)
807 return;
808
809 if (!(ifp->if_flags & IFF_RUNNING))
810 return;
811
812 if (status != USBD_NORMAL_COMPLETION) {
813 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
814 return;
815 }
816 sc->sc_intr_errs++;
817 if (usbd_ratecheck(&sc->sc_rx_notice)) {
818 printf("%s: %u usb errors on intr: %s\n",
819 sc->sc_dev.dv_xname, sc->sc_rx_errs,
820 usbd_errstr(status));
821 sc->sc_intr_errs = 0;
822 }
823 if (status == USBD_STALLED)
824 usbd_clear_endpoint_stall_async(sc->sc_ep[UPL_ENDPT_RX]);
825 return;
826 }
827
828 stat = sc->sc_ibuf;
829
830 if (stat == 0)
831 return;
832
833 DPRINTFN(10,("%s: %s: stat=0x%02x\n", sc->sc_dev.dv_xname,
834 __func__, stat));
835
836 }
837
838 int
839 upl_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
840 {
841 struct upl_softc *sc = ifp->if_softc;
842 struct ifaddr *ifa = (struct ifaddr *)data;
843 struct ifreq *ifr = (struct ifreq *)data;
844 int s, error = 0;
845
846 if (sc->sc_dying)
847 return (EIO);
848
849 DPRINTFN(5,("%s: %s: cmd=0x%08lx\n",
850 sc->sc_dev.dv_xname, __func__, command));
851
852 s = splnet();
853
854 switch(command) {
855 case SIOCSIFADDR:
856 ifp->if_flags |= IFF_UP;
857 upl_init(sc);
858
859 switch (ifa->ifa_addr->sa_family) {
860 #ifdef INET
861 case AF_INET:
862 break;
863 #endif
864 }
865 break;
866
867 case SIOCSIFMTU:
868 if (ifr->ifr_mtu > UPL_BUFSZ)
869 error = EINVAL;
870 else
871 ifp->if_mtu = ifr->ifr_mtu;
872 break;
873
874 case SIOCSIFFLAGS:
875 if (ifp->if_flags & IFF_UP) {
876 if (!(ifp->if_flags & IFF_RUNNING))
877 upl_init(sc);
878 } else {
879 if (ifp->if_flags & IFF_RUNNING)
880 upl_stop(sc);
881 }
882 error = 0;
883 break;
884 default:
885 error = EINVAL;
886 break;
887 }
888
889 splx(s);
890
891 return (error);
892 }
893
894 void
895 upl_watchdog(struct ifnet *ifp)
896 {
897 struct upl_softc *sc = ifp->if_softc;
898
899 DPRINTFN(5,("%s: %s: enter\n", sc->sc_dev.dv_xname,__func__));
900
901 if (sc->sc_dying)
902 return;
903
904 ifp->if_oerrors++;
905 printf("%s: watchdog timeout\n", sc->sc_dev.dv_xname);
906
907 upl_stop(sc);
908 upl_init(sc);
909
910 if (IFQ_IS_EMPTY(&ifp->if_snd) == 0)
911 upl_start(ifp);
912 }
913
914
915
916
917
918 void
919 upl_stop(struct upl_softc *sc)
920 {
921 usbd_status err;
922 struct ifnet *ifp;
923 int i;
924
925 DPRINTFN(10,("%s: %s: enter\n", sc->sc_dev.dv_xname,__func__));
926
927 ifp = &sc->sc_if;
928 ifp->if_timer = 0;
929 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
930
931
932 if (sc->sc_ep[UPL_ENDPT_RX] != NULL) {
933 err = usbd_abort_pipe(sc->sc_ep[UPL_ENDPT_RX]);
934 if (err) {
935 printf("%s: abort rx pipe failed: %s\n",
936 sc->sc_dev.dv_xname, usbd_errstr(err));
937 }
938 err = usbd_close_pipe(sc->sc_ep[UPL_ENDPT_RX]);
939 if (err) {
940 printf("%s: close rx pipe failed: %s\n",
941 sc->sc_dev.dv_xname, usbd_errstr(err));
942 }
943 sc->sc_ep[UPL_ENDPT_RX] = NULL;
944 }
945
946 if (sc->sc_ep[UPL_ENDPT_TX] != NULL) {
947 err = usbd_abort_pipe(sc->sc_ep[UPL_ENDPT_TX]);
948 if (err) {
949 printf("%s: abort tx pipe failed: %s\n",
950 sc->sc_dev.dv_xname, usbd_errstr(err));
951 }
952 err = usbd_close_pipe(sc->sc_ep[UPL_ENDPT_TX]);
953 if (err) {
954 printf("%s: close tx pipe failed: %s\n",
955 sc->sc_dev.dv_xname, usbd_errstr(err));
956 }
957 sc->sc_ep[UPL_ENDPT_TX] = NULL;
958 }
959
960 if (sc->sc_ep[UPL_ENDPT_INTR] != NULL) {
961 err = usbd_abort_pipe(sc->sc_ep[UPL_ENDPT_INTR]);
962 if (err) {
963 printf("%s: abort intr pipe failed: %s\n",
964 sc->sc_dev.dv_xname, usbd_errstr(err));
965 }
966 err = usbd_close_pipe(sc->sc_ep[UPL_ENDPT_INTR]);
967 if (err) {
968 printf("%s: close intr pipe failed: %s\n",
969 sc->sc_dev.dv_xname, usbd_errstr(err));
970 }
971 sc->sc_ep[UPL_ENDPT_INTR] = NULL;
972 }
973
974
975 for (i = 0; i < UPL_RX_LIST_CNT; i++) {
976 if (sc->sc_cdata.upl_rx_chain[i].upl_mbuf != NULL) {
977 m_freem(sc->sc_cdata.upl_rx_chain[i].upl_mbuf);
978 sc->sc_cdata.upl_rx_chain[i].upl_mbuf = NULL;
979 }
980 if (sc->sc_cdata.upl_rx_chain[i].upl_xfer != NULL) {
981 usbd_free_xfer(sc->sc_cdata.upl_rx_chain[i].upl_xfer);
982 sc->sc_cdata.upl_rx_chain[i].upl_xfer = NULL;
983 }
984 }
985
986
987 for (i = 0; i < UPL_TX_LIST_CNT; i++) {
988 if (sc->sc_cdata.upl_tx_chain[i].upl_mbuf != NULL) {
989 m_freem(sc->sc_cdata.upl_tx_chain[i].upl_mbuf);
990 sc->sc_cdata.upl_tx_chain[i].upl_mbuf = NULL;
991 }
992 if (sc->sc_cdata.upl_tx_chain[i].upl_xfer != NULL) {
993 usbd_free_xfer(sc->sc_cdata.upl_tx_chain[i].upl_xfer);
994 sc->sc_cdata.upl_tx_chain[i].upl_xfer = NULL;
995 }
996 }
997 }
998
999 int
1000 upl_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
1001 struct rtentry *rt0)
1002 {
1003 int s, len, error;
1004
1005 DPRINTFN(10,("%s: %s: enter\n",
1006 ((struct upl_softc *)ifp->if_softc)->sc_dev.dv_xname,
1007 __func__));
1008
1009 len = m->m_pkthdr.len;
1010 s = splnet();
1011
1012
1013
1014
1015 IFQ_ENQUEUE(&ifp->if_snd, m, NULL, error);
1016 if (error) {
1017
1018 splx(s);
1019 return (error);
1020 }
1021 ifp->if_obytes += len;
1022 if ((ifp->if_flags & IFF_OACTIVE) == 0)
1023 (*ifp->if_start)(ifp);
1024 splx(s);
1025
1026 return (0);
1027 }
1028
1029 void
1030 upl_input(struct ifnet *ifp, struct mbuf *m)
1031 {
1032 struct ifqueue *inq;
1033 int s;
1034
1035
1036
1037 schednetisr(NETISR_IP);
1038 inq = &ipintrq;
1039
1040 s = splnet();
1041 if (IF_QFULL(inq)) {
1042 IF_DROP(inq);
1043 splx(s);
1044 #if 0
1045 if (sc->sc_flags & SC_DEBUG)
1046 printf("%s: input queue full\n", ifp->if_xname);
1047 #endif
1048 ifp->if_iqdrops++;
1049 return;
1050 }
1051 IF_ENQUEUE(inq, m);
1052 splx(s);
1053 ifp->if_ipackets++;
1054 ifp->if_ibytes += m->m_len;
1055 }