This source file includes following definitions.
- ubsa_match
- ubsa_attach
- ubsa_detach
- ubsa_activate
- ubsa_request
- ubsa_dtr
- ubsa_rts
- ubsa_break
- ubsa_set
- ubsa_baudrate
- ubsa_parity
- ubsa_databits
- ubsa_stopbits
- ubsa_flow
- ubsa_param
- ubsa_open
- ubsa_close
- ubsa_intr
- ubsa_get_status
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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64 #include <sys/cdefs.h>
65
66 #include <sys/param.h>
67 #include <sys/systm.h>
68 #include <sys/kernel.h>
69 #include <sys/malloc.h>
70 #include <sys/device.h>
71 #include <sys/ioccom.h>
72 #include <sys/fcntl.h>
73 #include <sys/conf.h>
74 #include <sys/tty.h>
75 #include <sys/file.h>
76 #include <sys/selinfo.h>
77 #include <sys/proc.h>
78 #include <sys/vnode.h>
79 #include <sys/poll.h>
80 #include <sys/sysctl.h>
81
82 #include <dev/usb/usb.h>
83 #include <dev/usb/usbcdc.h>
84
85 #include <dev/usb/usbdi.h>
86 #include <dev/usb/usbdi_util.h>
87 #include <dev/usb/usbdevs.h>
88 #include <dev/usb/usb_quirks.h>
89
90 #include <dev/usb/ucomvar.h>
91
92 #ifdef USB_DEBUG
93 #define UBSA_DEBUG
94 #endif
95
96 #ifdef UBSA_DEBUG
97 int ubsadebug = 0;
98
99 #define DPRINTFN(n, x) do { if (ubsadebug > (n)) printf x; } while (0)
100 #else
101 #define DPRINTFN(n, x)
102 #endif
103 #define DPRINTF(x) DPRINTFN(0, x)
104
105 #define UBSA_MODVER 1
106
107 #define UBSA_CONFIG_INDEX 1
108 #define UBSA_IFACE_INDEX 0
109
110 #define UBSA_INTR_INTERVAL 100
111
112 #define UBSA_SET_BAUDRATE 0x00
113 #define UBSA_SET_STOP_BITS 0x01
114 #define UBSA_SET_DATA_BITS 0x02
115 #define UBSA_SET_PARITY 0x03
116 #define UBSA_SET_DTR 0x0A
117 #define UBSA_SET_RTS 0x0B
118 #define UBSA_SET_BREAK 0x0C
119 #define UBSA_SET_FLOW_CTRL 0x10
120
121 #define UBSA_PARITY_NONE 0x00
122 #define UBSA_PARITY_EVEN 0x01
123 #define UBSA_PARITY_ODD 0x02
124 #define UBSA_PARITY_MARK 0x03
125 #define UBSA_PARITY_SPACE 0x04
126
127 #define UBSA_FLOW_NONE 0x0000
128 #define UBSA_FLOW_OCTS 0x0001
129 #define UBSA_FLOW_ODSR 0x0002
130 #define UBSA_FLOW_IDSR 0x0004
131 #define UBSA_FLOW_IDTR 0x0008
132 #define UBSA_FLOW_IRTS 0x0010
133 #define UBSA_FLOW_ORTS 0x0020
134 #define UBSA_FLOW_UNKNOWN 0x0040
135 #define UBSA_FLOW_OXON 0x0080
136 #define UBSA_FLOW_IXON 0x0100
137
138
139 #define UBSA_LSR_TSRE 0x40
140 #define UBSA_LSR_TXRDY 0x20
141 #define UBSA_LSR_BI 0x10
142 #define UBSA_LSR_FE 0x08
143 #define UBSA_LSR_PE 0x04
144 #define UBSA_LSR_OE 0x02
145 #define UBSA_LSR_RXRDY 0x01
146 #define UBSA_LSR_RCV_MASK 0x1f
147
148
149
150 #define UBSA_MSR_DCD 0x80
151 #define UBSA_MSR_RI 0x40
152 #define UBSA_MSR_DSR 0x20
153 #define UBSA_MSR_CTS 0x10
154 #define UBSA_MSR_DDCD 0x08
155 #define UBSA_MSR_TERI 0x04
156 #define UBSA_MSR_DDSR 0x02
157 #define UBSA_MSR_DCTS 0x01
158
159 struct ubsa_softc {
160 struct device sc_dev;
161 usbd_device_handle sc_udev;
162 usbd_interface_handle sc_iface;
163
164 int sc_iface_number;
165
166 int sc_intr_number;
167 usbd_pipe_handle sc_intr_pipe;
168 u_char *sc_intr_buf;
169 int sc_isize;
170
171 u_char sc_dtr;
172 u_char sc_rts;
173
174 u_char sc_lsr;
175 u_char sc_msr;
176
177 struct device *sc_subdev;
178
179 u_char sc_dying;
180
181 };
182
183 void ubsa_intr(usbd_xfer_handle, usbd_private_handle, usbd_status);
184
185 void ubsa_get_status(void *, int, u_char *, u_char *);
186 void ubsa_set(void *, int, int, int);
187 int ubsa_param(void *, int, struct termios *);
188 int ubsa_open(void *, int);
189 void ubsa_close(void *, int);
190
191 void ubsa_break(struct ubsa_softc *sc, int onoff);
192 int ubsa_request(struct ubsa_softc *, u_int8_t, u_int16_t);
193 void ubsa_dtr(struct ubsa_softc *, int);
194 void ubsa_rts(struct ubsa_softc *, int);
195 void ubsa_baudrate(struct ubsa_softc *, speed_t);
196 void ubsa_parity(struct ubsa_softc *, tcflag_t);
197 void ubsa_databits(struct ubsa_softc *, tcflag_t);
198 void ubsa_stopbits(struct ubsa_softc *, tcflag_t);
199 void ubsa_flow(struct ubsa_softc *, tcflag_t, tcflag_t);
200
201 struct ucom_methods ubsa_methods = {
202 ubsa_get_status,
203 ubsa_set,
204 ubsa_param,
205 NULL,
206 ubsa_open,
207 ubsa_close,
208 NULL,
209 NULL
210 };
211
212 const struct usb_devno ubsa_devs[] = {
213
214 { USB_VENDOR_ANYDATA, USB_PRODUCT_ANYDATA_ADU_E100H },
215
216 { USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5U103 },
217
218 { USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5U120 },
219
220 { USB_VENDOR_ETEK, USB_PRODUCT_ETEK_1COM },
221
222 { USB_VENDOR_GOHUBS, USB_PRODUCT_GOHUBS_GOCOM232 },
223
224 { USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_E618 },
225
226 { USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_MERLINU740 },
227
228 { USB_VENDOR_OPTION, USB_PRODUCT_OPTION_VODAFONEMC3G },
229
230 { USB_VENDOR_OPTION, USB_PRODUCT_OPTION_GT3GFUSION },
231
232 { USB_VENDOR_OPTION, USB_PRODUCT_OPTION_GT3GQUAD },
233
234 { USB_VENDOR_OPTION, USB_PRODUCT_OPTION_GT3GQUADPLUS },
235
236 { USB_VENDOR_PERACOM, USB_PRODUCT_PERACOM_SERIAL1 },
237 };
238 #define ubsa_lookup(v, p) usb_lookup(ubsa_devs, v, p)
239
240 int ubsa_match(struct device *, void *, void *);
241 void ubsa_attach(struct device *, struct device *, void *);
242 int ubsa_detach(struct device *, int);
243 int ubsa_activate(struct device *, enum devact);
244
245 struct cfdriver ubsa_cd = {
246 NULL, "ubsa", DV_DULL
247 };
248
249 const struct cfattach ubsa_ca = {
250 sizeof(struct ubsa_softc),
251 ubsa_match,
252 ubsa_attach,
253 ubsa_detach,
254 ubsa_activate,
255 };
256
257 int
258 ubsa_match(struct device *parent, void *match, void *aux)
259 {
260 struct usb_attach_arg *uaa = aux;
261
262 if (uaa->iface != NULL)
263 return (UMATCH_NONE);
264
265 return (ubsa_lookup(uaa->vendor, uaa->product) != NULL ?
266 UMATCH_VENDOR_PRODUCT : UMATCH_NONE);
267 }
268
269 void
270 ubsa_attach(struct device *parent, struct device *self, void *aux)
271 {
272 struct ubsa_softc *sc = (struct ubsa_softc *)self;
273 struct usb_attach_arg *uaa = aux;
274 usbd_device_handle dev = uaa->device;
275 usb_config_descriptor_t *cdesc;
276 usb_interface_descriptor_t *id;
277 usb_endpoint_descriptor_t *ed;
278 char *devinfop;
279 const char *devname = sc->sc_dev.dv_xname;
280 usbd_status err;
281 struct ucom_attach_args uca;
282 int i;
283
284 devinfop = usbd_devinfo_alloc(dev, 0);
285 printf("\n%s: %s\n", devname, devinfop);
286 usbd_devinfo_free(devinfop);
287
288 sc->sc_udev = dev;
289
290
291
292
293
294 sc->sc_dtr = -1;
295 sc->sc_rts = -1;
296
297 DPRINTF(("ubsa attach: sc = %p\n", sc));
298
299
300 uca.bulkin = uca.bulkout = -1;
301 sc->sc_intr_number = -1;
302 sc->sc_intr_pipe = NULL;
303
304
305 err = usbd_set_config_index(dev, UBSA_CONFIG_INDEX, 1);
306 if (err) {
307 printf("%s: failed to set configuration: %s\n",
308 devname, usbd_errstr(err));
309 sc->sc_dying = 1;
310 goto error;
311 }
312
313
314 cdesc = usbd_get_config_descriptor(sc->sc_udev);
315
316 if (cdesc == NULL) {
317 printf("%s: failed to get configuration descriptor\n",
318 devname);
319 sc->sc_dying = 1;
320 goto error;
321 }
322
323
324 err = usbd_device2interface_handle(dev, UBSA_IFACE_INDEX,
325 &sc->sc_iface);
326 if (err) {
327 printf("%s: failed to get interface: %s\n",
328 devname, usbd_errstr(err));
329 sc->sc_dying = 1;
330 goto error;
331 }
332
333
334
335 id = usbd_get_interface_descriptor(sc->sc_iface);
336 sc->sc_iface_number = id->bInterfaceNumber;
337
338 for (i = 0; i < id->bNumEndpoints; i++) {
339 ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i);
340 if (ed == NULL) {
341 printf("%s: no endpoint descriptor for %d\n",
342 sc->sc_dev.dv_xname, i);
343 sc->sc_dying = 1;
344 goto error;
345 }
346
347 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
348 UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
349 sc->sc_intr_number = ed->bEndpointAddress;
350 sc->sc_isize = UGETW(ed->wMaxPacketSize);
351 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
352 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
353 uca.bulkin = ed->bEndpointAddress;
354 uca.ibufsize = UGETW(ed->wMaxPacketSize);
355 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
356 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
357 uca.bulkout = ed->bEndpointAddress;
358 uca.obufsize = UGETW(ed->wMaxPacketSize);
359 }
360 }
361
362 if (sc->sc_intr_number == -1) {
363 printf("%s: Could not find interrupt in\n", devname);
364 sc->sc_dying = 1;
365 goto error;
366 }
367
368 if (uca.bulkin == -1) {
369 printf("%s: Could not find data bulk in\n", devname);
370 sc->sc_dying = 1;
371 goto error;
372 }
373
374 if (uca.bulkout == -1) {
375 printf("%s: Could not find data bulk out\n", devname);
376 sc->sc_dying = 1;
377 goto error;
378 }
379
380 uca.portno = UCOM_UNK_PORTNO;
381
382 uca.ibufsizepad = uca.ibufsize;
383 uca.opkthdrlen = 0;
384 uca.device = dev;
385 uca.iface = sc->sc_iface;
386 uca.methods = &ubsa_methods;
387 uca.arg = sc;
388 uca.info = NULL;
389
390 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
391 &sc->sc_dev);
392
393 DPRINTF(("ubsa: in = 0x%x, out = 0x%x, intr = 0x%x\n",
394 uca.bulkin, uca.bulkout, sc->sc_intr_number));
395
396 sc->sc_subdev = config_found_sm(self, &uca, ucomprint, ucomsubmatch);
397
398 error:
399 return;
400 }
401
402 int
403 ubsa_detach(struct device *self, int flags)
404 {
405 struct ubsa_softc *sc = (struct ubsa_softc *)self;
406 int rv = 0;
407
408
409 DPRINTF(("ubsa_detach: sc = %p\n", sc));
410
411 if (sc->sc_intr_pipe != NULL) {
412 usbd_abort_pipe(sc->sc_intr_pipe);
413 usbd_close_pipe(sc->sc_intr_pipe);
414 free(sc->sc_intr_buf, M_USBDEV);
415 sc->sc_intr_pipe = NULL;
416 }
417
418 sc->sc_dying = 1;
419 if (sc->sc_subdev != NULL) {
420 rv = config_detach(sc->sc_subdev, flags);
421 sc->sc_subdev = NULL;
422 }
423
424 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
425 &sc->sc_dev);
426
427 return (rv);
428 }
429
430 int
431 ubsa_activate(struct device *self, enum devact act)
432 {
433 struct ubsa_softc *sc = (struct ubsa_softc *)self;
434 int rv = 0;
435
436 switch (act) {
437 case DVACT_ACTIVATE:
438 break;
439
440 case DVACT_DEACTIVATE:
441 if (sc->sc_subdev != NULL)
442 rv = config_deactivate(sc->sc_subdev);
443 sc->sc_dying = 1;
444 break;
445 }
446 return (rv);
447 }
448
449 int
450 ubsa_request(struct ubsa_softc *sc, u_int8_t request, u_int16_t value)
451 {
452 usb_device_request_t req;
453 usbd_status err;
454
455 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
456 req.bRequest = request;
457 USETW(req.wValue, value);
458 USETW(req.wIndex, sc->sc_iface_number);
459 USETW(req.wLength, 0);
460
461 err = usbd_do_request(sc->sc_udev, &req, 0);
462 if (err && err != USBD_STALLED)
463 printf("%s: ubsa_request: %s\n",
464 sc->sc_dev.dv_xname, usbd_errstr(err));
465 return (err);
466 }
467
468 void
469 ubsa_dtr(struct ubsa_softc *sc, int onoff)
470 {
471
472 DPRINTF(("ubsa_dtr: onoff = %d\n", onoff));
473
474 if (sc->sc_dtr == onoff)
475 return;
476 sc->sc_dtr = onoff;
477
478 ubsa_request(sc, UBSA_SET_DTR, onoff ? 1 : 0);
479 }
480
481 void
482 ubsa_rts(struct ubsa_softc *sc, int onoff)
483 {
484
485 DPRINTF(("ubsa_rts: onoff = %d\n", onoff));
486
487 if (sc->sc_rts == onoff)
488 return;
489 sc->sc_rts = onoff;
490
491 ubsa_request(sc, UBSA_SET_RTS, onoff ? 1 : 0);
492 }
493
494 void
495 ubsa_break(struct ubsa_softc *sc, int onoff)
496 {
497
498 DPRINTF(("ubsa_rts: onoff = %d\n", onoff));
499
500 ubsa_request(sc, UBSA_SET_BREAK, onoff ? 1 : 0);
501 }
502
503 void
504 ubsa_set(void *addr, int portno, int reg, int onoff)
505 {
506 struct ubsa_softc *sc;
507
508 sc = addr;
509 switch (reg) {
510 case UCOM_SET_DTR:
511 ubsa_dtr(sc, onoff);
512 break;
513 case UCOM_SET_RTS:
514 ubsa_rts(sc, onoff);
515 break;
516 case UCOM_SET_BREAK:
517 ubsa_break(sc, onoff);
518 break;
519 default:
520 break;
521 }
522 }
523
524 void
525 ubsa_baudrate(struct ubsa_softc *sc, speed_t speed)
526 {
527 u_int16_t value = 0;
528
529 DPRINTF(("ubsa_baudrate: speed = %d\n", speed));
530
531 switch(speed) {
532 case B0:
533 break;
534 case B300:
535 case B600:
536 case B1200:
537 case B2400:
538 case B4800:
539 case B9600:
540 case B19200:
541 case B38400:
542 case B57600:
543 case B115200:
544 case B230400:
545 value = B230400 / speed;
546 break;
547 default:
548 DPRINTF(("%s: ubsa_param: unsupported baudrate, "
549 "forcing default of 9600\n",
550 sc->sc_dev.dv_xname));
551 value = B230400 / B9600;
552 break;
553 };
554
555 if (speed == B0) {
556 ubsa_flow(sc, 0, 0);
557 ubsa_dtr(sc, 0);
558 ubsa_rts(sc, 0);
559 } else
560 ubsa_request(sc, UBSA_SET_BAUDRATE, value);
561 }
562
563 void
564 ubsa_parity(struct ubsa_softc *sc, tcflag_t cflag)
565 {
566 int value;
567
568 DPRINTF(("ubsa_parity: cflag = 0x%x\n", cflag));
569
570 if (cflag & PARENB)
571 value = (cflag & PARODD) ? UBSA_PARITY_ODD : UBSA_PARITY_EVEN;
572 else
573 value = UBSA_PARITY_NONE;
574
575 ubsa_request(sc, UBSA_SET_PARITY, value);
576 }
577
578 void
579 ubsa_databits(struct ubsa_softc *sc, tcflag_t cflag)
580 {
581 int value;
582
583 DPRINTF(("ubsa_databits: cflag = 0x%x\n", cflag));
584
585 switch (cflag & CSIZE) {
586 case CS5: value = 0; break;
587 case CS6: value = 1; break;
588 case CS7: value = 2; break;
589 case CS8: value = 3; break;
590 default:
591 DPRINTF(("%s: ubsa_param: unsupported databits requested, "
592 "forcing default of 8\n",
593 sc->sc_dev.dv_xname));
594 value = 3;
595 }
596
597 ubsa_request(sc, UBSA_SET_DATA_BITS, value);
598 }
599
600 void
601 ubsa_stopbits(struct ubsa_softc *sc, tcflag_t cflag)
602 {
603 int value;
604
605 DPRINTF(("ubsa_stopbits: cflag = 0x%x\n", cflag));
606
607 value = (cflag & CSTOPB) ? 1 : 0;
608
609 ubsa_request(sc, UBSA_SET_STOP_BITS, value);
610 }
611
612 void
613 ubsa_flow(struct ubsa_softc *sc, tcflag_t cflag, tcflag_t iflag)
614 {
615 int value;
616
617 DPRINTF(("ubsa_flow: cflag = 0x%x, iflag = 0x%x\n", cflag, iflag));
618
619 value = 0;
620 if (cflag & CRTSCTS)
621 value |= UBSA_FLOW_OCTS | UBSA_FLOW_IRTS;
622 if (iflag & (IXON|IXOFF))
623 value |= UBSA_FLOW_OXON | UBSA_FLOW_IXON;
624
625 ubsa_request(sc, UBSA_SET_FLOW_CTRL, value);
626 }
627
628 int
629 ubsa_param(void *addr, int portno, struct termios *ti)
630 {
631 struct ubsa_softc *sc = addr;
632
633 DPRINTF(("ubsa_param: sc = %p\n", sc));
634
635 ubsa_baudrate(sc, ti->c_ospeed);
636 ubsa_parity(sc, ti->c_cflag);
637 ubsa_databits(sc, ti->c_cflag);
638 ubsa_stopbits(sc, ti->c_cflag);
639 ubsa_flow(sc, ti->c_cflag, ti->c_iflag);
640
641 return (0);
642 }
643
644 int
645 ubsa_open(void *addr, int portno)
646 {
647 struct ubsa_softc *sc = addr;
648 int err;
649
650 if (sc->sc_dying)
651 return (ENXIO);
652
653 DPRINTF(("ubsa_open: sc = %p\n", sc));
654
655 if (sc->sc_intr_number != -1 && sc->sc_intr_pipe == NULL) {
656 sc->sc_intr_buf = malloc(sc->sc_isize, M_USBDEV, M_WAITOK);
657 err = usbd_open_pipe_intr(sc->sc_iface,
658 sc->sc_intr_number,
659 USBD_SHORT_XFER_OK,
660 &sc->sc_intr_pipe,
661 sc,
662 sc->sc_intr_buf,
663 sc->sc_isize,
664 ubsa_intr,
665 UBSA_INTR_INTERVAL);
666 if (err) {
667 printf("%s: cannot open interrupt pipe (addr %d)\n",
668 sc->sc_dev.dv_xname,
669 sc->sc_intr_number);
670 return (EIO);
671 }
672 }
673
674 return (0);
675 }
676
677 void
678 ubsa_close(void *addr, int portno)
679 {
680 struct ubsa_softc *sc = addr;
681 int err;
682
683 if (sc->sc_dying)
684 return;
685
686 DPRINTF(("ubsa_close: close\n"));
687
688 if (sc->sc_intr_pipe != NULL) {
689 err = usbd_abort_pipe(sc->sc_intr_pipe);
690 if (err)
691 printf("%s: abort interrupt pipe failed: %s\n",
692 sc->sc_dev.dv_xname,
693 usbd_errstr(err));
694 err = usbd_close_pipe(sc->sc_intr_pipe);
695 if (err)
696 printf("%s: close interrupt pipe failed: %s\n",
697 sc->sc_dev.dv_xname,
698 usbd_errstr(err));
699 free(sc->sc_intr_buf, M_USBDEV);
700 sc->sc_intr_pipe = NULL;
701 }
702 }
703
704 void
705 ubsa_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
706 {
707 struct ubsa_softc *sc = priv;
708 u_char *buf;
709
710 buf = sc->sc_intr_buf;
711 if (sc->sc_dying)
712 return;
713
714 if (status != USBD_NORMAL_COMPLETION) {
715 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
716 return;
717
718 DPRINTF(("%s: ubsa_intr: abnormal status: %s\n",
719 sc->sc_dev.dv_xname, usbd_errstr(status)));
720 usbd_clear_endpoint_stall_async(sc->sc_intr_pipe);
721 return;
722 }
723
724
725 sc->sc_lsr = buf[2];
726 sc->sc_msr = buf[3];
727
728 DPRINTF(("%s: ubsa lsr = 0x%02x, msr = 0x%02x\n",
729 sc->sc_dev.dv_xname, sc->sc_lsr, sc->sc_msr));
730
731 ucom_status_change((struct ucom_softc *)sc->sc_subdev);
732 }
733
734 void
735 ubsa_get_status(void *addr, int portno, u_char *lsr, u_char *msr)
736 {
737 struct ubsa_softc *sc = addr;
738
739 DPRINTF(("ubsa_get_status\n"));
740
741 if (lsr != NULL)
742 *lsr = sc->sc_lsr;
743 if (msr != NULL)
744 *msr = sc->sc_msr;
745 }