1*0ee61f55Smlelstv /* $NetBSD: ubsa_common.c,v 1.15 2021/06/13 09:29:38 mlelstv Exp $ */
2817e003aSichiro /*-
3817e003aSichiro * Copyright (c) 2002, Alexander Kabaev <kan.FreeBSD.org>.
4817e003aSichiro * All rights reserved.
5817e003aSichiro *
6817e003aSichiro * Redistribution and use in source and binary forms, with or without
7817e003aSichiro * modification, are permitted provided that the following conditions
8817e003aSichiro * are met:
9817e003aSichiro * 1. Redistributions of source code must retain the above copyright
10817e003aSichiro * notice, this list of conditions and the following disclaimer.
11817e003aSichiro * 2. Redistributions in binary form must reproduce the above copyright
12817e003aSichiro * notice, this list of conditions and the following disclaimer in the
13817e003aSichiro * documentation and/or other materials provided with the distribution.
14817e003aSichiro *
15817e003aSichiro * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16817e003aSichiro * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17817e003aSichiro * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18817e003aSichiro * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19817e003aSichiro * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20817e003aSichiro * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21817e003aSichiro * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22817e003aSichiro * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23817e003aSichiro * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24817e003aSichiro * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25817e003aSichiro * SUCH DAMAGE.
26817e003aSichiro */
27817e003aSichiro /*
28817e003aSichiro * Copyright (c) 2001 The NetBSD Foundation, Inc.
29817e003aSichiro * All rights reserved.
30817e003aSichiro *
31817e003aSichiro * This code is derived from software contributed to The NetBSD Foundation
32817e003aSichiro * by Ichiro FUKUHARA (ichiro@ichiro.org).
33817e003aSichiro *
34817e003aSichiro * Redistribution and use in source and binary forms, with or without
35817e003aSichiro * modification, are permitted provided that the following conditions
36817e003aSichiro * are met:
37817e003aSichiro * 1. Redistributions of source code must retain the above copyright
38817e003aSichiro * notice, this list of conditions and the following disclaimer.
39817e003aSichiro * 2. Redistributions in binary form must reproduce the above copyright
40817e003aSichiro * notice, this list of conditions and the following disclaimer in the
41817e003aSichiro * documentation and/or other materials provided with the distribution.
42817e003aSichiro *
43817e003aSichiro * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
44817e003aSichiro * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
45817e003aSichiro * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
46817e003aSichiro * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
47817e003aSichiro * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
48817e003aSichiro * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
49817e003aSichiro * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
50817e003aSichiro * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
51817e003aSichiro * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
52817e003aSichiro * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
53817e003aSichiro * POSSIBILITY OF SUCH DAMAGE.
54817e003aSichiro */
55817e003aSichiro
56817e003aSichiro #include <sys/cdefs.h>
57*0ee61f55Smlelstv __KERNEL_RCSID(0, "$NetBSD: ubsa_common.c,v 1.15 2021/06/13 09:29:38 mlelstv Exp $");
58817e003aSichiro
59817e003aSichiro #include <sys/param.h>
60817e003aSichiro #include <sys/systm.h>
61817e003aSichiro #include <sys/kernel.h>
624e8e6643Sskrll #include <sys/kmem.h>
63817e003aSichiro #include <sys/ioccom.h>
64817e003aSichiro #include <sys/fcntl.h>
65817e003aSichiro #include <sys/conf.h>
66817e003aSichiro #include <sys/tty.h>
67817e003aSichiro #include <sys/file.h>
68817e003aSichiro #include <sys/select.h>
69817e003aSichiro #include <sys/proc.h>
70817e003aSichiro #include <sys/device.h>
71817e003aSichiro #include <sys/poll.h>
72817e003aSichiro #include <sys/sysctl.h>
73817e003aSichiro #include <sys/bus.h>
74817e003aSichiro
75817e003aSichiro #include <dev/usb/usb.h>
76817e003aSichiro #include <dev/usb/usbdi.h>
77817e003aSichiro #include <dev/usb/usbdi_util.h>
78817e003aSichiro #include <dev/usb/usbdivar.h>
79817e003aSichiro
80817e003aSichiro #include <dev/usb/usbcdc.h>
81817e003aSichiro #include <dev/usb/usbdevs.h>
82817e003aSichiro #include <dev/usb/usb_quirks.h>
83817e003aSichiro #include <dev/usb/ucomvar.h>
84817e003aSichiro #include <dev/usb/ubsavar.h>
85817e003aSichiro
86817e003aSichiro #ifdef UBSA_DEBUG
87817e003aSichiro extern int ubsadebug;
88817e003aSichiro #define DPRINTFN(n, x) do { \
89817e003aSichiro if (ubsadebug > (n)) \
9049337c88Sdyoung printf x; \
91817e003aSichiro } while (0)
92817e003aSichiro #else
93817e003aSichiro #define DPRINTFN(n, x)
94817e003aSichiro #endif
95817e003aSichiro #define DPRINTF(x) DPRINTFN(0, x)
96817e003aSichiro
972e9fa9ffSichiro int
ubsa_request(struct ubsa_softc * sc,int portno,uint8_t request,uint16_t value)984e8e6643Sskrll ubsa_request(struct ubsa_softc *sc, int portno, uint8_t request, uint16_t value)
99817e003aSichiro {
100817e003aSichiro usb_device_request_t req;
101817e003aSichiro usbd_status err;
102817e003aSichiro
103817e003aSichiro if (sc->sc_quadumts)
104817e003aSichiro req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
105817e003aSichiro else
106817e003aSichiro req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
107817e003aSichiro
1085d8b710dSmsaitoh if (portno >= UBSA_MAXCONN) {
109817e003aSichiro printf("%s: ubsa_request: invalid port(%d)#\n",
11049337c88Sdyoung device_xname(sc->sc_dev), portno);
111817e003aSichiro return USBD_INVAL;
112817e003aSichiro }
113817e003aSichiro
114817e003aSichiro req.bRequest = request;
115817e003aSichiro USETW(req.wValue, value);
116817e003aSichiro USETW(req.wIndex, sc->sc_iface_number[portno]);
117817e003aSichiro USETW(req.wLength, 0);
118817e003aSichiro
119817e003aSichiro err = usbd_do_request(sc->sc_udev, &req, 0);
120817e003aSichiro if (err)
121817e003aSichiro printf("%s: ubsa_request: %s\n",
12249337c88Sdyoung device_xname(sc->sc_dev), usbd_errstr(err));
1234e8e6643Sskrll return err;
124817e003aSichiro }
125817e003aSichiro
1262e9fa9ffSichiro void
ubsa_dtr(struct ubsa_softc * sc,int portno,int onoff)127817e003aSichiro ubsa_dtr(struct ubsa_softc *sc, int portno, int onoff)
128817e003aSichiro {
129817e003aSichiro
130817e003aSichiro DPRINTF(("ubsa_dtr: onoff = %d\n", onoff));
131817e003aSichiro
132817e003aSichiro if (sc->sc_dtr == onoff)
133817e003aSichiro return;
134817e003aSichiro sc->sc_dtr = onoff;
135817e003aSichiro
136817e003aSichiro ubsa_request(sc, portno, UBSA_SET_DTR, onoff ? 1 : 0);
137817e003aSichiro }
138817e003aSichiro
1392e9fa9ffSichiro void
ubsa_rts(struct ubsa_softc * sc,int portno,int onoff)140817e003aSichiro ubsa_rts(struct ubsa_softc *sc, int portno, int onoff)
141817e003aSichiro {
142817e003aSichiro
143817e003aSichiro DPRINTF(("ubsa_rts: onoff = %d\n", onoff));
144817e003aSichiro
145817e003aSichiro if (sc->sc_rts == onoff)
146817e003aSichiro return;
147817e003aSichiro sc->sc_rts = onoff;
148817e003aSichiro
149817e003aSichiro ubsa_request(sc, portno, UBSA_SET_RTS, onoff ? 1 : 0);
150817e003aSichiro }
151817e003aSichiro
1522e9fa9ffSichiro void
ubsa_quadumts_dtr(struct ubsa_softc * sc,int portno,int onoff)153817e003aSichiro ubsa_quadumts_dtr(struct ubsa_softc *sc, int portno, int onoff)
154817e003aSichiro {
155817e003aSichiro
156817e003aSichiro DPRINTF(("ubsa_dtr: onoff = %d\n", onoff));
157817e003aSichiro
158817e003aSichiro if (sc->sc_dtr == onoff)
159817e003aSichiro return;
160817e003aSichiro sc->sc_dtr = onoff;
161817e003aSichiro
162817e003aSichiro ubsa_request(sc, portno, UBSA_QUADUMTS_SET_PIN,
163817e003aSichiro (sc->sc_rts ? 2 : 0)+(sc->sc_dtr ? 1 : 0));
164817e003aSichiro }
165817e003aSichiro
1662e9fa9ffSichiro void
ubsa_quadumts_rts(struct ubsa_softc * sc,int portno,int onoff)167817e003aSichiro ubsa_quadumts_rts(struct ubsa_softc *sc, int portno, int onoff)
168817e003aSichiro {
169817e003aSichiro
170817e003aSichiro DPRINTF(("ubsa_rts: onoff = %d\n", onoff));
171817e003aSichiro
172817e003aSichiro if (sc->sc_rts == onoff)
173817e003aSichiro return;
174817e003aSichiro sc->sc_rts = onoff;
175817e003aSichiro
176817e003aSichiro ubsa_request(sc, portno, UBSA_QUADUMTS_SET_PIN,
177817e003aSichiro (sc->sc_rts ? 2 : 0)+(sc->sc_dtr ? 1 : 0));
178817e003aSichiro }
179817e003aSichiro
1802e9fa9ffSichiro void
ubsa_break(struct ubsa_softc * sc,int portno,int onoff)181817e003aSichiro ubsa_break(struct ubsa_softc *sc, int portno, int onoff)
182817e003aSichiro {
183817e003aSichiro DPRINTF(("ubsa_rts: onoff = %d\n", onoff));
184817e003aSichiro
185cc0cad1eSmrg if (sc->sc_dying)
186cc0cad1eSmrg return;
187cc0cad1eSmrg
188817e003aSichiro ubsa_request(sc, portno, UBSA_SET_BREAK, onoff ? 1 : 0);
189817e003aSichiro }
190817e003aSichiro
1912e9fa9ffSichiro void
ubsa_set(void * addr,int portno,int reg,int onoff)192817e003aSichiro ubsa_set(void *addr, int portno, int reg, int onoff)
193817e003aSichiro {
194cc0cad1eSmrg struct ubsa_softc *sc = addr;
195817e003aSichiro
196cc0cad1eSmrg if (sc->sc_dying)
197cc0cad1eSmrg return;
198cc0cad1eSmrg
199817e003aSichiro switch (reg) {
200817e003aSichiro case UCOM_SET_DTR:
201817e003aSichiro if (sc->sc_quadumts)
202817e003aSichiro ubsa_quadumts_dtr(sc, portno, onoff);
203817e003aSichiro else
204817e003aSichiro ubsa_dtr(sc, portno, onoff);
205817e003aSichiro break;
206817e003aSichiro case UCOM_SET_RTS:
207817e003aSichiro if (sc->sc_quadumts)
208817e003aSichiro ubsa_quadumts_rts(sc, portno, onoff);
209817e003aSichiro else
210817e003aSichiro ubsa_rts(sc, portno, onoff);
211817e003aSichiro break;
212817e003aSichiro case UCOM_SET_BREAK:
213817e003aSichiro if (!sc->sc_quadumts)
214817e003aSichiro ubsa_break(sc, portno, onoff);
215817e003aSichiro break;
216817e003aSichiro default:
217817e003aSichiro break;
218817e003aSichiro }
219817e003aSichiro }
220817e003aSichiro
2212e9fa9ffSichiro void
ubsa_baudrate(struct ubsa_softc * sc,int portno,speed_t speed)222817e003aSichiro ubsa_baudrate(struct ubsa_softc *sc, int portno, speed_t speed)
223817e003aSichiro {
2244e8e6643Sskrll uint16_t value = 0;
225817e003aSichiro
226817e003aSichiro DPRINTF(("ubsa_baudrate: speed = %d\n", speed));
227817e003aSichiro
228817e003aSichiro switch(speed) {
229817e003aSichiro case B0:
230817e003aSichiro break;
231817e003aSichiro case B300:
232817e003aSichiro case B600:
233817e003aSichiro case B1200:
234817e003aSichiro case B2400:
235817e003aSichiro case B4800:
236817e003aSichiro case B9600:
237817e003aSichiro case B19200:
238817e003aSichiro case B38400:
239817e003aSichiro case B57600:
240817e003aSichiro case B115200:
241817e003aSichiro case B230400:
242817e003aSichiro value = B230400 / speed;
243817e003aSichiro break;
244817e003aSichiro default:
245817e003aSichiro printf("%s: ubsa_param: unsupported baudrate, "
246817e003aSichiro "forcing default of 9600\n",
24749337c88Sdyoung device_xname(sc->sc_dev));
248817e003aSichiro value = B230400 / B9600;
249817e003aSichiro break;
250817e003aSichiro };
251817e003aSichiro
252817e003aSichiro if (speed == B0) {
253817e003aSichiro ubsa_flow(sc, portno, 0, 0);
254817e003aSichiro ubsa_dtr(sc, portno, 0);
255817e003aSichiro ubsa_rts(sc, portno, 0);
256817e003aSichiro } else
257817e003aSichiro ubsa_request(sc, portno, UBSA_SET_BAUDRATE, value);
258817e003aSichiro }
259817e003aSichiro
2602e9fa9ffSichiro void
ubsa_parity(struct ubsa_softc * sc,int portno,tcflag_t cflag)261817e003aSichiro ubsa_parity(struct ubsa_softc *sc, int portno, tcflag_t cflag)
262817e003aSichiro {
263817e003aSichiro int value;
264817e003aSichiro
265d3dde16cSchristos DPRINTF(("ubsa_parity: cflag = %#x\n", cflag));
266817e003aSichiro
267817e003aSichiro if (cflag & PARENB)
268817e003aSichiro value = (cflag & PARODD) ? UBSA_PARITY_ODD : UBSA_PARITY_EVEN;
269817e003aSichiro else
270817e003aSichiro value = UBSA_PARITY_NONE;
271817e003aSichiro
272817e003aSichiro ubsa_request(sc, portno, UBSA_SET_PARITY, value);
273817e003aSichiro }
274817e003aSichiro
2752e9fa9ffSichiro void
ubsa_databits(struct ubsa_softc * sc,int portno,tcflag_t cflag)276817e003aSichiro ubsa_databits(struct ubsa_softc *sc, int portno, tcflag_t cflag)
277817e003aSichiro {
278817e003aSichiro int value;
279817e003aSichiro
280d3dde16cSchristos DPRINTF(("ubsa_databits: cflag = %#x\n", cflag));
281817e003aSichiro
282817e003aSichiro switch (cflag & CSIZE) {
283817e003aSichiro case CS5: value = 0; break;
284817e003aSichiro case CS6: value = 1; break;
285817e003aSichiro case CS7: value = 2; break;
286817e003aSichiro case CS8: value = 3; break;
287817e003aSichiro default:
288817e003aSichiro printf("%s: ubsa_param: unsupported databits requested, "
289817e003aSichiro "forcing default of 8\n",
29049337c88Sdyoung device_xname(sc->sc_dev));
291817e003aSichiro value = 3;
292817e003aSichiro }
293817e003aSichiro
294817e003aSichiro ubsa_request(sc, portno, UBSA_SET_DATA_BITS, value);
295817e003aSichiro }
296817e003aSichiro
2972e9fa9ffSichiro void
ubsa_stopbits(struct ubsa_softc * sc,int portno,tcflag_t cflag)298817e003aSichiro ubsa_stopbits(struct ubsa_softc *sc, int portno, tcflag_t cflag)
299817e003aSichiro {
300817e003aSichiro int value;
301817e003aSichiro
302d3dde16cSchristos DPRINTF(("ubsa_stopbits: cflag = %#x\n", cflag));
303817e003aSichiro
304817e003aSichiro value = (cflag & CSTOPB) ? 1 : 0;
305817e003aSichiro
306817e003aSichiro ubsa_request(sc, portno, UBSA_SET_STOP_BITS, value);
307817e003aSichiro }
308817e003aSichiro
3092e9fa9ffSichiro void
ubsa_flow(struct ubsa_softc * sc,int portno,tcflag_t cflag,tcflag_t iflag)310817e003aSichiro ubsa_flow(struct ubsa_softc *sc, int portno, tcflag_t cflag, tcflag_t iflag)
311817e003aSichiro {
312817e003aSichiro int value;
313817e003aSichiro
314d3dde16cSchristos DPRINTF(("ubsa_flow: cflag = %#x, iflag = %#x\n", cflag, iflag));
315817e003aSichiro
316817e003aSichiro value = 0;
317817e003aSichiro if (cflag & CRTSCTS)
318817e003aSichiro value |= UBSA_FLOW_OCTS | UBSA_FLOW_IRTS;
319*0ee61f55Smlelstv if (iflag & IXOFF)
320*0ee61f55Smlelstv value |= UBSA_FLOW_OXON;
321*0ee61f55Smlelstv if (iflag & IXON)
322*0ee61f55Smlelstv value |= UBSA_FLOW_IXON;
323817e003aSichiro
324817e003aSichiro ubsa_request(sc, portno, UBSA_SET_FLOW_CTRL, value);
325817e003aSichiro }
326817e003aSichiro
3272e9fa9ffSichiro int
ubsa_param(void * addr,int portno,struct termios * ti)328817e003aSichiro ubsa_param(void *addr, int portno, struct termios *ti)
329817e003aSichiro {
330817e003aSichiro struct ubsa_softc *sc = addr;
331817e003aSichiro
332cc0cad1eSmrg if (sc->sc_dying)
333cc0cad1eSmrg return EIO;
334cc0cad1eSmrg
335817e003aSichiro DPRINTF(("ubsa_param: sc = %p\n", sc));
336817e003aSichiro
337817e003aSichiro if (!sc->sc_quadumts) {
338817e003aSichiro ubsa_baudrate(sc, portno, ti->c_ospeed);
339817e003aSichiro ubsa_parity(sc, portno, ti->c_cflag);
340817e003aSichiro ubsa_databits(sc, portno, ti->c_cflag);
341817e003aSichiro ubsa_stopbits(sc, portno, ti->c_cflag);
342817e003aSichiro ubsa_flow(sc, portno, ti->c_cflag, ti->c_iflag);
343817e003aSichiro }
344817e003aSichiro
3454e8e6643Sskrll return 0;
346817e003aSichiro }
347817e003aSichiro
3482e9fa9ffSichiro int
ubsa_open(void * addr,int portno)349817e003aSichiro ubsa_open(void *addr, int portno)
350817e003aSichiro {
351817e003aSichiro struct ubsa_softc *sc = addr;
352817e003aSichiro int err;
353817e003aSichiro
354817e003aSichiro if (sc->sc_dying)
355cc0cad1eSmrg return EIO;
356817e003aSichiro
357817e003aSichiro if (sc->sc_intr_number != -1 && sc->sc_intr_pipe == NULL) {
3584e8e6643Sskrll sc->sc_intr_buf = kmem_alloc(sc->sc_isize, KM_SLEEP);
359817e003aSichiro /* XXX only iface# = 0 has intr line */
360817e003aSichiro /* XXX E220 specific? need to check */
361817e003aSichiro err = usbd_open_pipe_intr(sc->sc_iface[0],
362817e003aSichiro sc->sc_intr_number,
363817e003aSichiro USBD_SHORT_XFER_OK,
364817e003aSichiro &sc->sc_intr_pipe,
365817e003aSichiro sc,
366817e003aSichiro sc->sc_intr_buf,
367817e003aSichiro sc->sc_isize,
368817e003aSichiro ubsa_intr,
369817e003aSichiro UBSA_INTR_INTERVAL);
370817e003aSichiro if (err) {
371817e003aSichiro printf("%s: cannot open interrupt pipe (addr %d)\n",
37249337c88Sdyoung device_xname(sc->sc_dev),
373817e003aSichiro sc->sc_intr_number);
3744e8e6643Sskrll return EIO;
375817e003aSichiro }
376817e003aSichiro }
377817e003aSichiro
3784e8e6643Sskrll return 0;
379817e003aSichiro }
380817e003aSichiro
3812e9fa9ffSichiro void
ubsa_close_pipe(struct ubsa_softc * sc)382cc0cad1eSmrg ubsa_close_pipe(struct ubsa_softc *sc)
383cc0cad1eSmrg {
384cc0cad1eSmrg
385cc0cad1eSmrg if (sc->sc_intr_pipe != NULL) {
386cc0cad1eSmrg usbd_abort_pipe(sc->sc_intr_pipe);
387cc0cad1eSmrg usbd_close_pipe(sc->sc_intr_pipe);
388cc0cad1eSmrg sc->sc_intr_pipe = NULL;
389cc0cad1eSmrg }
390cc0cad1eSmrg if (sc->sc_intr_buf) {
391cc0cad1eSmrg kmem_free(sc->sc_intr_buf, sc->sc_isize);
392cc0cad1eSmrg sc->sc_intr_buf = NULL;
393cc0cad1eSmrg }
394cc0cad1eSmrg }
395cc0cad1eSmrg
396cc0cad1eSmrg void
ubsa_close(void * addr,int portno)397817e003aSichiro ubsa_close(void *addr, int portno)
398817e003aSichiro {
399817e003aSichiro struct ubsa_softc *sc = addr;
400cc0cad1eSmrg
401cc0cad1eSmrg DPRINTF(("ubsa_close: close\n"));
402817e003aSichiro
403817e003aSichiro if (sc->sc_dying)
404817e003aSichiro return;
405817e003aSichiro
406cc0cad1eSmrg ubsa_close_pipe(sc);
407817e003aSichiro }
408817e003aSichiro
4092e9fa9ffSichiro void
ubsa_intr(struct usbd_xfer * xfer,void * priv,usbd_status status)4104e8e6643Sskrll ubsa_intr(struct usbd_xfer *xfer, void *priv,
411817e003aSichiro usbd_status status)
412817e003aSichiro {
413817e003aSichiro struct ubsa_softc *sc = priv;
414817e003aSichiro u_char *buf;
415817e003aSichiro int i;
416817e003aSichiro
417817e003aSichiro buf = sc->sc_intr_buf;
418817e003aSichiro if (sc->sc_dying)
419817e003aSichiro return;
420817e003aSichiro
421817e003aSichiro if (status != USBD_NORMAL_COMPLETION) {
422817e003aSichiro if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
423817e003aSichiro return;
424817e003aSichiro
425817e003aSichiro DPRINTF(("%s: ubsa_intr: abnormal status: %s\n",
42649337c88Sdyoung device_xname(sc->sc_dev), usbd_errstr(status)));
427817e003aSichiro usbd_clear_endpoint_stall_async(sc->sc_intr_pipe);
428817e003aSichiro return;
429817e003aSichiro }
430817e003aSichiro
431817e003aSichiro /* incidentally, Belkin adapter status bits match UART 16550 bits */
432817e003aSichiro sc->sc_lsr = buf[2];
433817e003aSichiro sc->sc_msr = buf[3];
434817e003aSichiro
435aa3d6ec1Schristos DPRINTF(("%s: ubsa lsr = 0x%02x, msr = 0x%02x\n",
43649337c88Sdyoung device_xname(sc->sc_dev), sc->sc_lsr, sc->sc_msr));
437817e003aSichiro
438817e003aSichiro for (i = 0; i < sc->sc_numif; i++) {
4393624455eScube ucom_status_change(device_private(sc->sc_subdevs[i]));
440817e003aSichiro }
441817e003aSichiro }
442817e003aSichiro
4432e9fa9ffSichiro void
ubsa_get_status(void * addr,int portno,u_char * lsr,u_char * msr)444817e003aSichiro ubsa_get_status(void *addr, int portno, u_char *lsr, u_char *msr)
445817e003aSichiro {
446817e003aSichiro struct ubsa_softc *sc = addr;
447817e003aSichiro
448817e003aSichiro DPRINTF(("ubsa_get_status\n"));
449817e003aSichiro
450817e003aSichiro *lsr = sc->sc_lsr;
451817e003aSichiro *msr = sc->sc_msr;
452817e003aSichiro }
453817e003aSichiro
454