Deleted Added
full compact
uark.c (187970) uark.c (188413)
1/* $OpenBSD: uark.c,v 1.1 2006/08/14 08:30:22 jsg Exp $ */
2
3/*
4 * Copyright (c) 2006 Jonathan Gray <jsg@openbsd.org>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 *
1/* $OpenBSD: uark.c,v 1.1 2006/08/14 08:30:22 jsg Exp $ */
2
3/*
4 * Copyright (c) 2006 Jonathan Gray <jsg@openbsd.org>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 *
18 * $FreeBSD: head/sys/dev/usb2/serial/uark2.c 187970 2009-02-01 00:51:25Z thompsa $
18 * $FreeBSD: head/sys/dev/usb2/serial/uark2.c 188413 2009-02-09 22:05:25Z thompsa $
19 */
20
21/*
22 * NOTE: all function names beginning like "uark_cfg_" can only
23 * be called from within the config thread function !
24 */
25
26#include <dev/usb2/include/usb2_devid.h>
27#include <dev/usb2/include/usb2_standard.h>
28#include <dev/usb2/include/usb2_mfunc.h>
29#include <dev/usb2/include/usb2_error.h>
30#include <dev/usb2/include/usb2_cdc.h>
31
32#define USB_DEBUG_VAR usb2_debug
33
34#include <dev/usb2/core/usb2_core.h>
35#include <dev/usb2/core/usb2_debug.h>
36#include <dev/usb2/core/usb2_process.h>
37#include <dev/usb2/core/usb2_request.h>
38#include <dev/usb2/core/usb2_lookup.h>
39#include <dev/usb2/core/usb2_util.h>
40
41#include <dev/usb2/serial/usb2_serial.h>
42
43#define UARK_BUF_SIZE 1024 /* bytes */
44
45#define UARK_SET_DATA_BITS(x) ((x) - 5)
46
47#define UARK_PARITY_NONE 0x00
48#define UARK_PARITY_ODD 0x08
49#define UARK_PARITY_EVEN 0x18
50
51#define UARK_STOP_BITS_1 0x00
52#define UARK_STOP_BITS_2 0x04
53
54#define UARK_BAUD_REF 3000000
55
56#define UARK_WRITE 0x40
57#define UARK_READ 0xc0
58
59#define UARK_REQUEST 0xfe
60
61#define UARK_CONFIG_INDEX 0
62#define UARK_IFACE_INDEX 0
63
64enum {
65 UARK_BULK_DT_WR,
66 UARK_BULK_DT_RD,
19 */
20
21/*
22 * NOTE: all function names beginning like "uark_cfg_" can only
23 * be called from within the config thread function !
24 */
25
26#include <dev/usb2/include/usb2_devid.h>
27#include <dev/usb2/include/usb2_standard.h>
28#include <dev/usb2/include/usb2_mfunc.h>
29#include <dev/usb2/include/usb2_error.h>
30#include <dev/usb2/include/usb2_cdc.h>
31
32#define USB_DEBUG_VAR usb2_debug
33
34#include <dev/usb2/core/usb2_core.h>
35#include <dev/usb2/core/usb2_debug.h>
36#include <dev/usb2/core/usb2_process.h>
37#include <dev/usb2/core/usb2_request.h>
38#include <dev/usb2/core/usb2_lookup.h>
39#include <dev/usb2/core/usb2_util.h>
40
41#include <dev/usb2/serial/usb2_serial.h>
42
43#define UARK_BUF_SIZE 1024 /* bytes */
44
45#define UARK_SET_DATA_BITS(x) ((x) - 5)
46
47#define UARK_PARITY_NONE 0x00
48#define UARK_PARITY_ODD 0x08
49#define UARK_PARITY_EVEN 0x18
50
51#define UARK_STOP_BITS_1 0x00
52#define UARK_STOP_BITS_2 0x04
53
54#define UARK_BAUD_REF 3000000
55
56#define UARK_WRITE 0x40
57#define UARK_READ 0xc0
58
59#define UARK_REQUEST 0xfe
60
61#define UARK_CONFIG_INDEX 0
62#define UARK_IFACE_INDEX 0
63
64enum {
65 UARK_BULK_DT_WR,
66 UARK_BULK_DT_RD,
67 UARK_BULK_CS_WR,
68 UARK_BULK_CS_RD,
69 UARK_N_TRANSFER = 4,
67 UARK_N_TRANSFER,
70};
71
72struct uark_softc {
73 struct usb2_com_super_softc sc_super_ucom;
74 struct usb2_com_softc sc_ucom;
75
76 struct usb2_xfer *sc_xfer[UARK_N_TRANSFER];
77 struct usb2_device *sc_udev;
78
68};
69
70struct uark_softc {
71 struct usb2_com_super_softc sc_super_ucom;
72 struct usb2_com_softc sc_ucom;
73
74 struct usb2_xfer *sc_xfer[UARK_N_TRANSFER];
75 struct usb2_device *sc_udev;
76
79 uint8_t sc_flags;
80#define UARK_FLAG_BULK_READ_STALL 0x01
81#define UARK_FLAG_BULK_WRITE_STALL 0x02
82 uint8_t sc_msr;
83 uint8_t sc_lsr;
84};
85
86/* prototypes */
87
88static device_probe_t uark_probe;
89static device_attach_t uark_attach;
90static device_detach_t uark_detach;
91
92static usb2_callback_t uark_bulk_write_callback;
77 uint8_t sc_msr;
78 uint8_t sc_lsr;
79};
80
81/* prototypes */
82
83static device_probe_t uark_probe;
84static device_attach_t uark_attach;
85static device_detach_t uark_detach;
86
87static usb2_callback_t uark_bulk_write_callback;
93static usb2_callback_t uark_bulk_write_clear_stall_callback;
94static usb2_callback_t uark_bulk_read_callback;
88static usb2_callback_t uark_bulk_read_callback;
95static usb2_callback_t uark_bulk_read_clear_stall_callback;
96
97static void uark_start_read(struct usb2_com_softc *);
98static void uark_stop_read(struct usb2_com_softc *);
99static void uark_start_write(struct usb2_com_softc *);
100static void uark_stop_write(struct usb2_com_softc *);
101static int uark_pre_param(struct usb2_com_softc *, struct termios *);
102static void uark_cfg_param(struct usb2_com_softc *, struct termios *);
103static void uark_cfg_get_status(struct usb2_com_softc *, uint8_t *,
104 uint8_t *);
105static void uark_cfg_set_break(struct usb2_com_softc *, uint8_t);
106static void uark_cfg_write(struct uark_softc *, uint16_t, uint16_t);
107
108static const struct usb2_config
109 uark_xfer_config[UARK_N_TRANSFER] = {
110
111 [UARK_BULK_DT_WR] = {
112 .type = UE_BULK,
113 .endpoint = UE_ADDR_ANY,
114 .direction = UE_DIR_OUT,
115 .mh.bufsize = UARK_BUF_SIZE,
116 .mh.flags = {.pipe_bof = 1,.force_short_xfer = 1,},
117 .mh.callback = &uark_bulk_write_callback,
118 },
119
120 [UARK_BULK_DT_RD] = {
121 .type = UE_BULK,
122 .endpoint = UE_ADDR_ANY,
123 .direction = UE_DIR_IN,
124 .mh.bufsize = UARK_BUF_SIZE,
125 .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
126 .mh.callback = &uark_bulk_read_callback,
127 },
89
90static void uark_start_read(struct usb2_com_softc *);
91static void uark_stop_read(struct usb2_com_softc *);
92static void uark_start_write(struct usb2_com_softc *);
93static void uark_stop_write(struct usb2_com_softc *);
94static int uark_pre_param(struct usb2_com_softc *, struct termios *);
95static void uark_cfg_param(struct usb2_com_softc *, struct termios *);
96static void uark_cfg_get_status(struct usb2_com_softc *, uint8_t *,
97 uint8_t *);
98static void uark_cfg_set_break(struct usb2_com_softc *, uint8_t);
99static void uark_cfg_write(struct uark_softc *, uint16_t, uint16_t);
100
101static const struct usb2_config
102 uark_xfer_config[UARK_N_TRANSFER] = {
103
104 [UARK_BULK_DT_WR] = {
105 .type = UE_BULK,
106 .endpoint = UE_ADDR_ANY,
107 .direction = UE_DIR_OUT,
108 .mh.bufsize = UARK_BUF_SIZE,
109 .mh.flags = {.pipe_bof = 1,.force_short_xfer = 1,},
110 .mh.callback = &uark_bulk_write_callback,
111 },
112
113 [UARK_BULK_DT_RD] = {
114 .type = UE_BULK,
115 .endpoint = UE_ADDR_ANY,
116 .direction = UE_DIR_IN,
117 .mh.bufsize = UARK_BUF_SIZE,
118 .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
119 .mh.callback = &uark_bulk_read_callback,
120 },
128
129 [UARK_BULK_CS_WR] = {
130 .type = UE_CONTROL,
131 .endpoint = 0x00, /* Control pipe */
132 .direction = UE_DIR_ANY,
133 .mh.bufsize = sizeof(struct usb2_device_request),
134 .mh.flags = {},
135 .mh.callback = &uark_bulk_write_clear_stall_callback,
136 .mh.timeout = 1000, /* 1 second */
137 .mh.interval = 50, /* 50ms */
138 },
139
140 [UARK_BULK_CS_RD] = {
141 .type = UE_CONTROL,
142 .endpoint = 0x00, /* Control pipe */
143 .direction = UE_DIR_ANY,
144 .mh.bufsize = sizeof(struct usb2_device_request),
145 .mh.flags = {},
146 .mh.callback = &uark_bulk_read_clear_stall_callback,
147 .mh.timeout = 1000, /* 1 second */
148 .mh.interval = 50, /* 50ms */
149 },
150};
151
152static const struct usb2_com_callback uark_callback = {
153 .usb2_com_cfg_get_status = &uark_cfg_get_status,
154 .usb2_com_cfg_set_break = &uark_cfg_set_break,
155 .usb2_com_cfg_param = &uark_cfg_param,
156 .usb2_com_pre_param = &uark_pre_param,
157 .usb2_com_start_read = &uark_start_read,
158 .usb2_com_stop_read = &uark_stop_read,
159 .usb2_com_start_write = &uark_start_write,
160 .usb2_com_stop_write = &uark_stop_write,
161};
162
163static device_method_t uark_methods[] = {
164 /* Device methods */
165 DEVMETHOD(device_probe, uark_probe),
166 DEVMETHOD(device_attach, uark_attach),
167 DEVMETHOD(device_detach, uark_detach),
168 {0, 0}
169};
170
171static devclass_t uark_devclass;
172
173static driver_t uark_driver = {
174 .name = "uark",
175 .methods = uark_methods,
176 .size = sizeof(struct uark_softc),
177};
178
179DRIVER_MODULE(uark, ushub, uark_driver, uark_devclass, NULL, 0);
180MODULE_DEPEND(uark, usb2_serial, 1, 1, 1);
181MODULE_DEPEND(uark, usb2_core, 1, 1, 1);
182
183static const struct usb2_device_id uark_devs[] = {
184 {USB_VPI(USB_VENDOR_ARKMICRO, USB_PRODUCT_ARKMICRO_ARK3116, 0)},
185};
186
187static int
188uark_probe(device_t dev)
189{
190 struct usb2_attach_arg *uaa = device_get_ivars(dev);
191
192 if (uaa->usb2_mode != USB_MODE_HOST) {
193 return (ENXIO);
194 }
195 if (uaa->info.bConfigIndex != 0) {
196 return (ENXIO);
197 }
198 if (uaa->info.bIfaceIndex != UARK_IFACE_INDEX) {
199 return (ENXIO);
200 }
201 return (usb2_lookup_id_by_uaa(uark_devs, sizeof(uark_devs), uaa));
202}
203
204static int
205uark_attach(device_t dev)
206{
207 struct usb2_attach_arg *uaa = device_get_ivars(dev);
208 struct uark_softc *sc = device_get_softc(dev);
209 int32_t error;
210 uint8_t iface_index;
211
212 device_set_usb2_desc(dev);
213
214 sc->sc_udev = uaa->device;
215
216 iface_index = UARK_IFACE_INDEX;
217 error = usb2_transfer_setup
218 (uaa->device, &iface_index, sc->sc_xfer,
219 uark_xfer_config, UARK_N_TRANSFER, sc, &Giant);
220
221 if (error) {
222 device_printf(dev, "allocating control USB "
223 "transfers failed!\n");
224 goto detach;
225 }
226 /* clear stall at first run */
121};
122
123static const struct usb2_com_callback uark_callback = {
124 .usb2_com_cfg_get_status = &uark_cfg_get_status,
125 .usb2_com_cfg_set_break = &uark_cfg_set_break,
126 .usb2_com_cfg_param = &uark_cfg_param,
127 .usb2_com_pre_param = &uark_pre_param,
128 .usb2_com_start_read = &uark_start_read,
129 .usb2_com_stop_read = &uark_stop_read,
130 .usb2_com_start_write = &uark_start_write,
131 .usb2_com_stop_write = &uark_stop_write,
132};
133
134static device_method_t uark_methods[] = {
135 /* Device methods */
136 DEVMETHOD(device_probe, uark_probe),
137 DEVMETHOD(device_attach, uark_attach),
138 DEVMETHOD(device_detach, uark_detach),
139 {0, 0}
140};
141
142static devclass_t uark_devclass;
143
144static driver_t uark_driver = {
145 .name = "uark",
146 .methods = uark_methods,
147 .size = sizeof(struct uark_softc),
148};
149
150DRIVER_MODULE(uark, ushub, uark_driver, uark_devclass, NULL, 0);
151MODULE_DEPEND(uark, usb2_serial, 1, 1, 1);
152MODULE_DEPEND(uark, usb2_core, 1, 1, 1);
153
154static const struct usb2_device_id uark_devs[] = {
155 {USB_VPI(USB_VENDOR_ARKMICRO, USB_PRODUCT_ARKMICRO_ARK3116, 0)},
156};
157
158static int
159uark_probe(device_t dev)
160{
161 struct usb2_attach_arg *uaa = device_get_ivars(dev);
162
163 if (uaa->usb2_mode != USB_MODE_HOST) {
164 return (ENXIO);
165 }
166 if (uaa->info.bConfigIndex != 0) {
167 return (ENXIO);
168 }
169 if (uaa->info.bIfaceIndex != UARK_IFACE_INDEX) {
170 return (ENXIO);
171 }
172 return (usb2_lookup_id_by_uaa(uark_devs, sizeof(uark_devs), uaa));
173}
174
175static int
176uark_attach(device_t dev)
177{
178 struct usb2_attach_arg *uaa = device_get_ivars(dev);
179 struct uark_softc *sc = device_get_softc(dev);
180 int32_t error;
181 uint8_t iface_index;
182
183 device_set_usb2_desc(dev);
184
185 sc->sc_udev = uaa->device;
186
187 iface_index = UARK_IFACE_INDEX;
188 error = usb2_transfer_setup
189 (uaa->device, &iface_index, sc->sc_xfer,
190 uark_xfer_config, UARK_N_TRANSFER, sc, &Giant);
191
192 if (error) {
193 device_printf(dev, "allocating control USB "
194 "transfers failed!\n");
195 goto detach;
196 }
197 /* clear stall at first run */
227 sc->sc_flags |= (UARK_FLAG_BULK_WRITE_STALL |
228 UARK_FLAG_BULK_READ_STALL);
198 usb2_transfer_set_stall(sc->sc_xfer[UARK_BULK_DT_WR]);
199 usb2_transfer_set_stall(sc->sc_xfer[UARK_BULK_DT_RD]);
229
230 error = usb2_com_attach(&sc->sc_super_ucom, &sc->sc_ucom, 1, sc,
231 &uark_callback, &Giant);
232 if (error) {
233 DPRINTF("usb2_com_attach failed\n");
234 goto detach;
235 }
236 return (0); /* success */
237
238detach:
239 uark_detach(dev);
240 return (ENXIO); /* failure */
241}
242
243static int
244uark_detach(device_t dev)
245{
246 struct uark_softc *sc = device_get_softc(dev);
247
248 usb2_com_detach(&sc->sc_super_ucom, &sc->sc_ucom, 1);
249
250 usb2_transfer_unsetup(sc->sc_xfer, UARK_N_TRANSFER);
251
252 return (0);
253}
254
255static void
256uark_bulk_write_callback(struct usb2_xfer *xfer)
257{
258 struct uark_softc *sc = xfer->priv_sc;
259 uint32_t actlen;
260
261 switch (USB_GET_STATE(xfer)) {
262 case USB_ST_SETUP:
263 case USB_ST_TRANSFERRED:
200
201 error = usb2_com_attach(&sc->sc_super_ucom, &sc->sc_ucom, 1, sc,
202 &uark_callback, &Giant);
203 if (error) {
204 DPRINTF("usb2_com_attach failed\n");
205 goto detach;
206 }
207 return (0); /* success */
208
209detach:
210 uark_detach(dev);
211 return (ENXIO); /* failure */
212}
213
214static int
215uark_detach(device_t dev)
216{
217 struct uark_softc *sc = device_get_softc(dev);
218
219 usb2_com_detach(&sc->sc_super_ucom, &sc->sc_ucom, 1);
220
221 usb2_transfer_unsetup(sc->sc_xfer, UARK_N_TRANSFER);
222
223 return (0);
224}
225
226static void
227uark_bulk_write_callback(struct usb2_xfer *xfer)
228{
229 struct uark_softc *sc = xfer->priv_sc;
230 uint32_t actlen;
231
232 switch (USB_GET_STATE(xfer)) {
233 case USB_ST_SETUP:
234 case USB_ST_TRANSFERRED:
264 if (sc->sc_flags & UARK_FLAG_BULK_WRITE_STALL) {
265 usb2_transfer_start(sc->sc_xfer[UARK_BULK_CS_WR]);
266 return;
267 }
235tr_setup:
268 if (usb2_com_get_data(&sc->sc_ucom, xfer->frbuffers, 0,
269 UARK_BUF_SIZE, &actlen)) {
270 xfer->frlengths[0] = actlen;
271 usb2_start_hardware(xfer);
272 }
273 return;
274
275 default: /* Error */
276 if (xfer->error != USB_ERR_CANCELLED) {
236 if (usb2_com_get_data(&sc->sc_ucom, xfer->frbuffers, 0,
237 UARK_BUF_SIZE, &actlen)) {
238 xfer->frlengths[0] = actlen;
239 usb2_start_hardware(xfer);
240 }
241 return;
242
243 default: /* Error */
244 if (xfer->error != USB_ERR_CANCELLED) {
277 sc->sc_flags |= UARK_FLAG_BULK_WRITE_STALL;
278 usb2_transfer_start(sc->sc_xfer[UARK_BULK_CS_WR]);
245 /* try to clear stall first */
246 xfer->flags.stall_pipe = 1;
247 goto tr_setup;
279 }
280 return;
281
282 }
283}
284
285static void
248 }
249 return;
250
251 }
252}
253
254static void
286uark_bulk_write_clear_stall_callback(struct usb2_xfer *xfer)
287{
288 struct uark_softc *sc = xfer->priv_sc;
289 struct usb2_xfer *xfer_other = sc->sc_xfer[UARK_BULK_DT_WR];
290
291 if (usb2_clear_stall_callback(xfer, xfer_other)) {
292 DPRINTF("stall cleared\n");
293 sc->sc_flags &= ~UARK_FLAG_BULK_WRITE_STALL;
294 usb2_transfer_start(xfer_other);
295 }
296}
297
298static void
299uark_bulk_read_callback(struct usb2_xfer *xfer)
300{
301 struct uark_softc *sc = xfer->priv_sc;
302
303 switch (USB_GET_STATE(xfer)) {
304 case USB_ST_TRANSFERRED:
305 usb2_com_put_data(&sc->sc_ucom, xfer->frbuffers, 0,
306 xfer->actlen);
307
308 case USB_ST_SETUP:
255uark_bulk_read_callback(struct usb2_xfer *xfer)
256{
257 struct uark_softc *sc = xfer->priv_sc;
258
259 switch (USB_GET_STATE(xfer)) {
260 case USB_ST_TRANSFERRED:
261 usb2_com_put_data(&sc->sc_ucom, xfer->frbuffers, 0,
262 xfer->actlen);
263
264 case USB_ST_SETUP:
309 if (sc->sc_flags & UARK_FLAG_BULK_READ_STALL) {
310 usb2_transfer_start(sc->sc_xfer[UARK_BULK_CS_RD]);
311 } else {
312 xfer->frlengths[0] = xfer->max_data_length;
313 usb2_start_hardware(xfer);
314 }
265tr_setup:
266 xfer->frlengths[0] = xfer->max_data_length;
267 usb2_start_hardware(xfer);
315 return;
316
317 default: /* Error */
318 if (xfer->error != USB_ERR_CANCELLED) {
268 return;
269
270 default: /* Error */
271 if (xfer->error != USB_ERR_CANCELLED) {
319 sc->sc_flags |= UARK_FLAG_BULK_READ_STALL;
320 usb2_transfer_start(sc->sc_xfer[UARK_BULK_CS_RD]);
272 /* try to clear stall first */
273 xfer->flags.stall_pipe = 1;
274 goto tr_setup;
321 }
322 return;
275 }
276 return;
323
324 }
325}
326
327static void
277 }
278}
279
280static void
328uark_bulk_read_clear_stall_callback(struct usb2_xfer *xfer)
329{
330 struct uark_softc *sc = xfer->priv_sc;
331 struct usb2_xfer *xfer_other = sc->sc_xfer[UARK_BULK_DT_RD];
332
333 if (usb2_clear_stall_callback(xfer, xfer_other)) {
334 DPRINTF("stall cleared\n");
335 sc->sc_flags &= ~UARK_FLAG_BULK_READ_STALL;
336 usb2_transfer_start(xfer_other);
337 }
338}
339
340static void
341uark_start_read(struct usb2_com_softc *ucom)
342{
343 struct uark_softc *sc = ucom->sc_parent;
344
345 usb2_transfer_start(sc->sc_xfer[UARK_BULK_DT_RD]);
346}
347
348static void
349uark_stop_read(struct usb2_com_softc *ucom)
350{
351 struct uark_softc *sc = ucom->sc_parent;
352
281uark_start_read(struct usb2_com_softc *ucom)
282{
283 struct uark_softc *sc = ucom->sc_parent;
284
285 usb2_transfer_start(sc->sc_xfer[UARK_BULK_DT_RD]);
286}
287
288static void
289uark_stop_read(struct usb2_com_softc *ucom)
290{
291 struct uark_softc *sc = ucom->sc_parent;
292
353 usb2_transfer_stop(sc->sc_xfer[UARK_BULK_CS_RD]);
354 usb2_transfer_stop(sc->sc_xfer[UARK_BULK_DT_RD]);
355}
356
357static void
358uark_start_write(struct usb2_com_softc *ucom)
359{
360 struct uark_softc *sc = ucom->sc_parent;
361
362 usb2_transfer_start(sc->sc_xfer[UARK_BULK_DT_WR]);
363}
364
365static void
366uark_stop_write(struct usb2_com_softc *ucom)
367{
368 struct uark_softc *sc = ucom->sc_parent;
369
293 usb2_transfer_stop(sc->sc_xfer[UARK_BULK_DT_RD]);
294}
295
296static void
297uark_start_write(struct usb2_com_softc *ucom)
298{
299 struct uark_softc *sc = ucom->sc_parent;
300
301 usb2_transfer_start(sc->sc_xfer[UARK_BULK_DT_WR]);
302}
303
304static void
305uark_stop_write(struct usb2_com_softc *ucom)
306{
307 struct uark_softc *sc = ucom->sc_parent;
308
370 usb2_transfer_stop(sc->sc_xfer[UARK_BULK_CS_WR]);
371 usb2_transfer_stop(sc->sc_xfer[UARK_BULK_DT_WR]);
372}
373
374static int
375uark_pre_param(struct usb2_com_softc *ucom, struct termios *t)
376{
377 if ((t->c_ospeed < 300) || (t->c_ospeed > 115200))
378 return (EINVAL);
379 return (0);
380}
381
382static void
383uark_cfg_param(struct usb2_com_softc *ucom, struct termios *t)
384{
385 struct uark_softc *sc = ucom->sc_parent;
386 uint32_t speed = t->c_ospeed;
387 uint16_t data;
388
389 /*
390 * NOTE: When reverse computing the baud rate from the "data" all
391 * allowed baud rates are within 3% of the initial baud rate.
392 */
393 data = (UARK_BAUD_REF + (speed / 2)) / speed;
394
395 uark_cfg_write(sc, 3, 0x83);
396 uark_cfg_write(sc, 0, data & 0xFF);
397 uark_cfg_write(sc, 1, data >> 8);
398 uark_cfg_write(sc, 3, 0x03);
399
400 if (t->c_cflag & CSTOPB)
401 data = UARK_STOP_BITS_2;
402 else
403 data = UARK_STOP_BITS_1;
404
405 if (t->c_cflag & PARENB) {
406 if (t->c_cflag & PARODD)
407 data |= UARK_PARITY_ODD;
408 else
409 data |= UARK_PARITY_EVEN;
410 } else
411 data |= UARK_PARITY_NONE;
412
413 switch (t->c_cflag & CSIZE) {
414 case CS5:
415 data |= UARK_SET_DATA_BITS(5);
416 break;
417 case CS6:
418 data |= UARK_SET_DATA_BITS(6);
419 break;
420 case CS7:
421 data |= UARK_SET_DATA_BITS(7);
422 break;
423 default:
424 case CS8:
425 data |= UARK_SET_DATA_BITS(8);
426 break;
427 }
428 uark_cfg_write(sc, 3, 0x00);
429 uark_cfg_write(sc, 3, data);
430}
431
432static void
433uark_cfg_get_status(struct usb2_com_softc *ucom, uint8_t *lsr, uint8_t *msr)
434{
435 struct uark_softc *sc = ucom->sc_parent;
436
437 *lsr = sc->sc_lsr;
438 *msr = sc->sc_msr;
439}
440
441static void
442uark_cfg_set_break(struct usb2_com_softc *ucom, uint8_t onoff)
443{
444 struct uark_softc *sc = ucom->sc_parent;
445
446 DPRINTF("onoff=%d\n", onoff);
447
448 uark_cfg_write(sc, 4, onoff ? 0x01 : 0x00);
449}
450
451static void
452uark_cfg_write(struct uark_softc *sc, uint16_t index, uint16_t value)
453{
454 struct usb2_device_request req;
455 usb2_error_t err;
456
309 usb2_transfer_stop(sc->sc_xfer[UARK_BULK_DT_WR]);
310}
311
312static int
313uark_pre_param(struct usb2_com_softc *ucom, struct termios *t)
314{
315 if ((t->c_ospeed < 300) || (t->c_ospeed > 115200))
316 return (EINVAL);
317 return (0);
318}
319
320static void
321uark_cfg_param(struct usb2_com_softc *ucom, struct termios *t)
322{
323 struct uark_softc *sc = ucom->sc_parent;
324 uint32_t speed = t->c_ospeed;
325 uint16_t data;
326
327 /*
328 * NOTE: When reverse computing the baud rate from the "data" all
329 * allowed baud rates are within 3% of the initial baud rate.
330 */
331 data = (UARK_BAUD_REF + (speed / 2)) / speed;
332
333 uark_cfg_write(sc, 3, 0x83);
334 uark_cfg_write(sc, 0, data & 0xFF);
335 uark_cfg_write(sc, 1, data >> 8);
336 uark_cfg_write(sc, 3, 0x03);
337
338 if (t->c_cflag & CSTOPB)
339 data = UARK_STOP_BITS_2;
340 else
341 data = UARK_STOP_BITS_1;
342
343 if (t->c_cflag & PARENB) {
344 if (t->c_cflag & PARODD)
345 data |= UARK_PARITY_ODD;
346 else
347 data |= UARK_PARITY_EVEN;
348 } else
349 data |= UARK_PARITY_NONE;
350
351 switch (t->c_cflag & CSIZE) {
352 case CS5:
353 data |= UARK_SET_DATA_BITS(5);
354 break;
355 case CS6:
356 data |= UARK_SET_DATA_BITS(6);
357 break;
358 case CS7:
359 data |= UARK_SET_DATA_BITS(7);
360 break;
361 default:
362 case CS8:
363 data |= UARK_SET_DATA_BITS(8);
364 break;
365 }
366 uark_cfg_write(sc, 3, 0x00);
367 uark_cfg_write(sc, 3, data);
368}
369
370static void
371uark_cfg_get_status(struct usb2_com_softc *ucom, uint8_t *lsr, uint8_t *msr)
372{
373 struct uark_softc *sc = ucom->sc_parent;
374
375 *lsr = sc->sc_lsr;
376 *msr = sc->sc_msr;
377}
378
379static void
380uark_cfg_set_break(struct usb2_com_softc *ucom, uint8_t onoff)
381{
382 struct uark_softc *sc = ucom->sc_parent;
383
384 DPRINTF("onoff=%d\n", onoff);
385
386 uark_cfg_write(sc, 4, onoff ? 0x01 : 0x00);
387}
388
389static void
390uark_cfg_write(struct uark_softc *sc, uint16_t index, uint16_t value)
391{
392 struct usb2_device_request req;
393 usb2_error_t err;
394
457 if (usb2_com_cfg_is_gone(&sc->sc_ucom)) {
458 return;
459 }
460 req.bmRequestType = UARK_WRITE;
461 req.bRequest = UARK_REQUEST;
462 USETW(req.wValue, value);
463 USETW(req.wIndex, index);
464 USETW(req.wLength, 0);
465
395 req.bmRequestType = UARK_WRITE;
396 req.bRequest = UARK_REQUEST;
397 USETW(req.wValue, value);
398 USETW(req.wIndex, index);
399 USETW(req.wLength, 0);
400
466 err = usb2_do_request_flags
467 (sc->sc_udev, &Giant, &req, NULL, 0, NULL, 1000);
468
401 err = usb2_com_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
402 &req, NULL, 0, 1000);
469 if (err) {
470 DPRINTFN(0, "device request failed, err=%s "
471 "(ignored)\n", usb2_errstr(err));
472 }
473}
403 if (err) {
404 DPRINTFN(0, "device request failed, err=%s "
405 "(ignored)\n", usb2_errstr(err));
406 }
407}