Deleted Added
full compact
ubser.c (187970) ubser.c (188413)
1/*-
2 * Copyright (c) 2004 Bernd Walter <ticso@freebsd.org>
3 *
4 * $URL: https://devel.bwct.de/svn/projects/ubser/ubser.c $
5 * $Date: 2004-02-29 01:53:10 +0100 (Sun, 29 Feb 2004) $
6 * $Author: ticso $
7 * $Rev: 1127 $
8 */

--- 56 unchanged lines hidden (view full) ---

65 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
66 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
67 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
68 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
69 * POSSIBILITY OF SUCH DAMAGE.
70 */
71
72#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2004 Bernd Walter <ticso@freebsd.org>
3 *
4 * $URL: https://devel.bwct.de/svn/projects/ubser/ubser.c $
5 * $Date: 2004-02-29 01:53:10 +0100 (Sun, 29 Feb 2004) $
6 * $Author: ticso $
7 * $Rev: 1127 $
8 */

--- 56 unchanged lines hidden (view full) ---

65 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
66 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
67 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
68 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
69 * POSSIBILITY OF SUCH DAMAGE.
70 */
71
72#include <sys/cdefs.h>
73__FBSDID("$FreeBSD: head/sys/dev/usb2/serial/ubser2.c 187970 2009-02-01 00:51:25Z thompsa $");
73__FBSDID("$FreeBSD: head/sys/dev/usb2/serial/ubser2.c 188413 2009-02-09 22:05:25Z thompsa $");
74
75/*
76 * BWCT serial adapter driver
77 */
78
79#include <dev/usb2/include/usb2_standard.h>
80#include <dev/usb2/include/usb2_mfunc.h>
81#include <dev/usb2/include/usb2_error.h>

--- 26 unchanged lines hidden (view full) ---

108SYSCTL_NODE(_hw_usb2, OID_AUTO, ubser, CTLFLAG_RW, 0, "USB ubser");
109SYSCTL_INT(_hw_usb2_ubser, OID_AUTO, debug, CTLFLAG_RW,
110 &ubser_debug, 0, "ubser debug level");
111#endif
112
113enum {
114 UBSER_BULK_DT_WR,
115 UBSER_BULK_DT_RD,
74
75/*
76 * BWCT serial adapter driver
77 */
78
79#include <dev/usb2/include/usb2_standard.h>
80#include <dev/usb2/include/usb2_mfunc.h>
81#include <dev/usb2/include/usb2_error.h>

--- 26 unchanged lines hidden (view full) ---

108SYSCTL_NODE(_hw_usb2, OID_AUTO, ubser, CTLFLAG_RW, 0, "USB ubser");
109SYSCTL_INT(_hw_usb2_ubser, OID_AUTO, debug, CTLFLAG_RW,
110 &ubser_debug, 0, "ubser debug level");
111#endif
112
113enum {
114 UBSER_BULK_DT_WR,
115 UBSER_BULK_DT_RD,
116 UBSER_BULK_CS_WR,
117 UBSER_BULK_CS_RD,
118 UBSER_N_TRANSFER = 4,
116 UBSER_N_TRANSFER,
119};
120
121struct ubser_softc {
122 struct usb2_com_super_softc sc_super_ucom;
123 struct usb2_com_softc sc_ucom[UBSER_UNIT_MAX];
124
125 struct usb2_xfer *sc_xfer[UBSER_N_TRANSFER];
126 struct usb2_device *sc_udev;
127
128 uint16_t sc_tx_size;
129
130 uint8_t sc_numser;
117};
118
119struct ubser_softc {
120 struct usb2_com_super_softc sc_super_ucom;
121 struct usb2_com_softc sc_ucom[UBSER_UNIT_MAX];
122
123 struct usb2_xfer *sc_xfer[UBSER_N_TRANSFER];
124 struct usb2_device *sc_udev;
125
126 uint16_t sc_tx_size;
127
128 uint8_t sc_numser;
131 uint8_t sc_flags;
132#define UBSER_FLAG_READ_STALL 0x01
133#define UBSER_FLAG_WRITE_STALL 0x02
134
135 uint8_t sc_iface_no;
136 uint8_t sc_iface_index;
137 uint8_t sc_curr_tx_unit;
138 uint8_t sc_name[16];
139};
140
141/* prototypes */
142
143static device_probe_t ubser_probe;
144static device_attach_t ubser_attach;
145static device_detach_t ubser_detach;
146
129 uint8_t sc_iface_no;
130 uint8_t sc_iface_index;
131 uint8_t sc_curr_tx_unit;
132 uint8_t sc_name[16];
133};
134
135/* prototypes */
136
137static device_probe_t ubser_probe;
138static device_attach_t ubser_attach;
139static device_detach_t ubser_detach;
140
147static usb2_callback_t ubser_write_clear_stall_callback;
148static usb2_callback_t ubser_write_callback;
141static usb2_callback_t ubser_write_callback;
149static usb2_callback_t ubser_read_clear_stall_callback;
150static usb2_callback_t ubser_read_callback;
151
152static int ubser_pre_param(struct usb2_com_softc *, struct termios *);
153static void ubser_cfg_set_break(struct usb2_com_softc *, uint8_t);
154static void ubser_cfg_get_status(struct usb2_com_softc *, uint8_t *,
155 uint8_t *);
156static void ubser_start_read(struct usb2_com_softc *);
157static void ubser_stop_read(struct usb2_com_softc *);

--- 14 unchanged lines hidden (view full) ---

172 [UBSER_BULK_DT_RD] = {
173 .type = UE_BULK,
174 .endpoint = UE_ADDR_ANY,
175 .direction = UE_DIR_IN,
176 .mh.bufsize = 0, /* use wMaxPacketSize */
177 .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
178 .mh.callback = &ubser_read_callback,
179 },
142static usb2_callback_t ubser_read_callback;
143
144static int ubser_pre_param(struct usb2_com_softc *, struct termios *);
145static void ubser_cfg_set_break(struct usb2_com_softc *, uint8_t);
146static void ubser_cfg_get_status(struct usb2_com_softc *, uint8_t *,
147 uint8_t *);
148static void ubser_start_read(struct usb2_com_softc *);
149static void ubser_stop_read(struct usb2_com_softc *);

--- 14 unchanged lines hidden (view full) ---

164 [UBSER_BULK_DT_RD] = {
165 .type = UE_BULK,
166 .endpoint = UE_ADDR_ANY,
167 .direction = UE_DIR_IN,
168 .mh.bufsize = 0, /* use wMaxPacketSize */
169 .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
170 .mh.callback = &ubser_read_callback,
171 },
180
181 [UBSER_BULK_CS_WR] = {
182 .type = UE_CONTROL,
183 .endpoint = 0x00, /* Control pipe */
184 .direction = UE_DIR_ANY,
185 .mh.bufsize = sizeof(struct usb2_device_request),
186 .mh.flags = {},
187 .mh.callback = &ubser_write_clear_stall_callback,
188 .mh.timeout = 1000, /* 1 second */
189 .mh.interval = 50, /* 50ms */
190 },
191
192 [UBSER_BULK_CS_RD] = {
193 .type = UE_CONTROL,
194 .endpoint = 0x00, /* Control pipe */
195 .direction = UE_DIR_ANY,
196 .mh.bufsize = sizeof(struct usb2_device_request),
197 .mh.flags = {},
198 .mh.callback = &ubser_read_clear_stall_callback,
199 .mh.timeout = 1000, /* 1 second */
200 .mh.interval = 50, /* 50ms */
201 },
202};
203
204static const struct usb2_com_callback ubser_callback = {
205 .usb2_com_cfg_set_break = &ubser_cfg_set_break,
206 .usb2_com_cfg_get_status = &ubser_cfg_get_status,
207 .usb2_com_pre_param = &ubser_pre_param,
208 .usb2_com_start_read = &ubser_start_read,
209 .usb2_com_stop_read = &ubser_stop_read,

--- 96 unchanged lines hidden (view full) ---

306
307 error = usb2_com_attach(&sc->sc_super_ucom, sc->sc_ucom,
308 sc->sc_numser, sc, &ubser_callback, &Giant);
309 if (error) {
310 goto detach;
311 }
312 mtx_lock(&Giant);
313
172};
173
174static const struct usb2_com_callback ubser_callback = {
175 .usb2_com_cfg_set_break = &ubser_cfg_set_break,
176 .usb2_com_cfg_get_status = &ubser_cfg_get_status,
177 .usb2_com_pre_param = &ubser_pre_param,
178 .usb2_com_start_read = &ubser_start_read,
179 .usb2_com_stop_read = &ubser_stop_read,

--- 96 unchanged lines hidden (view full) ---

276
277 error = usb2_com_attach(&sc->sc_super_ucom, sc->sc_ucom,
278 sc->sc_numser, sc, &ubser_callback, &Giant);
279 if (error) {
280 goto detach;
281 }
282 mtx_lock(&Giant);
283
314 sc->sc_flags |= (UBSER_FLAG_READ_STALL |
315 UBSER_FLAG_WRITE_STALL);
284 usb2_transfer_set_stall(sc->sc_xfer[UBSER_BULK_DT_WR]);
285 usb2_transfer_set_stall(sc->sc_xfer[UBSER_BULK_DT_RD]);
316
317 usb2_transfer_start(sc->sc_xfer[UBSER_BULK_DT_RD]);
318
319 mtx_unlock(&Giant);
320
321 return (0); /* success */
322
323detach:
324 ubser_detach(dev);
325 return (ENXIO); /* failure */
326}
327
328static int
329ubser_detach(device_t dev)
330{
331 struct ubser_softc *sc = device_get_softc(dev);
286
287 usb2_transfer_start(sc->sc_xfer[UBSER_BULK_DT_RD]);
288
289 mtx_unlock(&Giant);
290
291 return (0); /* success */
292
293detach:
294 ubser_detach(dev);
295 return (ENXIO); /* failure */
296}
297
298static int
299ubser_detach(device_t dev)
300{
301 struct ubser_softc *sc = device_get_softc(dev);
332 uint8_t n;
333
334 DPRINTF("\n");
335
336 usb2_com_detach(&sc->sc_super_ucom, sc->sc_ucom, sc->sc_numser);
337
302
303 DPRINTF("\n");
304
305 usb2_com_detach(&sc->sc_super_ucom, sc->sc_ucom, sc->sc_numser);
306
338 /*
339 * need to stop all transfers atomically, hence when clear stall
340 * completes, it might start other transfers !
341 */
342 mtx_lock(&Giant);
343 for (n = 0; n < UBSER_N_TRANSFER; n++) {
344 usb2_transfer_stop(sc->sc_xfer[n]);
345 }
346 mtx_unlock(&Giant);
347
348 usb2_transfer_unsetup(sc->sc_xfer, UBSER_N_TRANSFER);
349
350 return (0);
351}
352
353static int
354ubser_pre_param(struct usb2_com_softc *ucom, struct termios *t)
355{

--- 48 unchanged lines hidden (view full) ---

404{
405 sc->sc_curr_tx_unit++;
406 if (sc->sc_curr_tx_unit >= sc->sc_numser) {
407 sc->sc_curr_tx_unit = 0;
408 }
409}
410
411static void
307 usb2_transfer_unsetup(sc->sc_xfer, UBSER_N_TRANSFER);
308
309 return (0);
310}
311
312static int
313ubser_pre_param(struct usb2_com_softc *ucom, struct termios *t)
314{

--- 48 unchanged lines hidden (view full) ---

363{
364 sc->sc_curr_tx_unit++;
365 if (sc->sc_curr_tx_unit >= sc->sc_numser) {
366 sc->sc_curr_tx_unit = 0;
367 }
368}
369
370static void
412ubser_write_clear_stall_callback(struct usb2_xfer *xfer)
413{
414 struct ubser_softc *sc = xfer->priv_sc;
415 struct usb2_xfer *xfer_other = sc->sc_xfer[UBSER_BULK_DT_WR];
416
417 if (usb2_clear_stall_callback(xfer, xfer_other)) {
418 DPRINTF("stall cleared\n");
419 sc->sc_flags &= ~UBSER_FLAG_WRITE_STALL;
420 usb2_transfer_start(xfer_other);
421 }
422}
423
424static void
425ubser_write_callback(struct usb2_xfer *xfer)
426{
427 struct ubser_softc *sc = xfer->priv_sc;
428 uint8_t buf[1];
429 uint8_t first_unit = sc->sc_curr_tx_unit;
430 uint32_t actlen;
431
432 switch (USB_GET_STATE(xfer)) {
433 case USB_ST_SETUP:
434 case USB_ST_TRANSFERRED:
371ubser_write_callback(struct usb2_xfer *xfer)
372{
373 struct ubser_softc *sc = xfer->priv_sc;
374 uint8_t buf[1];
375 uint8_t first_unit = sc->sc_curr_tx_unit;
376 uint32_t actlen;
377
378 switch (USB_GET_STATE(xfer)) {
379 case USB_ST_SETUP:
380 case USB_ST_TRANSFERRED:
435 if (sc->sc_flags & UBSER_FLAG_WRITE_STALL) {
436 usb2_transfer_start(sc->sc_xfer[UBSER_BULK_CS_WR]);
437 return;
438 }
381tr_setup:
439 do {
440 if (usb2_com_get_data(sc->sc_ucom + sc->sc_curr_tx_unit,
441 xfer->frbuffers, 1, sc->sc_tx_size - 1,
442 &actlen)) {
443
444 buf[0] = sc->sc_curr_tx_unit;
445
446 usb2_copy_in(xfer->frbuffers, 0, buf, 1);

--- 8 unchanged lines hidden (view full) ---

455 ubser_inc_tx_unit(sc);
456
457 } while (sc->sc_curr_tx_unit != first_unit);
458
459 return;
460
461 default: /* Error */
462 if (xfer->error != USB_ERR_CANCELLED) {
382 do {
383 if (usb2_com_get_data(sc->sc_ucom + sc->sc_curr_tx_unit,
384 xfer->frbuffers, 1, sc->sc_tx_size - 1,
385 &actlen)) {
386
387 buf[0] = sc->sc_curr_tx_unit;
388
389 usb2_copy_in(xfer->frbuffers, 0, buf, 1);

--- 8 unchanged lines hidden (view full) ---

398 ubser_inc_tx_unit(sc);
399
400 } while (sc->sc_curr_tx_unit != first_unit);
401
402 return;
403
404 default: /* Error */
405 if (xfer->error != USB_ERR_CANCELLED) {
463 sc->sc_flags |= UBSER_FLAG_WRITE_STALL;
464 usb2_transfer_start(sc->sc_xfer[UBSER_BULK_CS_WR]);
406 /* try to clear stall first */
407 xfer->flags.stall_pipe = 1;
408 goto tr_setup;
465 }
466 return;
467
468 }
469}
470
471static void
409 }
410 return;
411
412 }
413}
414
415static void
472ubser_read_clear_stall_callback(struct usb2_xfer *xfer)
473{
474 struct ubser_softc *sc = xfer->priv_sc;
475 struct usb2_xfer *xfer_other = sc->sc_xfer[UBSER_BULK_DT_RD];
476
477 if (usb2_clear_stall_callback(xfer, xfer_other)) {
478 DPRINTF("stall cleared\n");
479 sc->sc_flags &= ~UBSER_FLAG_READ_STALL;
480 usb2_transfer_start(xfer_other);
481 }
482}
483
484static void
485ubser_read_callback(struct usb2_xfer *xfer)
486{
487 struct ubser_softc *sc = xfer->priv_sc;
488 uint8_t buf[1];
489
490 switch (USB_GET_STATE(xfer)) {
491 case USB_ST_TRANSFERRED:
492 if (xfer->actlen < 1) {

--- 6 unchanged lines hidden (view full) ---

499 DPRINTF("invalid serial number!\n");
500 goto tr_setup;
501 }
502 usb2_com_put_data(sc->sc_ucom + buf[0],
503 xfer->frbuffers, 1, xfer->actlen - 1);
504
505 case USB_ST_SETUP:
506tr_setup:
416ubser_read_callback(struct usb2_xfer *xfer)
417{
418 struct ubser_softc *sc = xfer->priv_sc;
419 uint8_t buf[1];
420
421 switch (USB_GET_STATE(xfer)) {
422 case USB_ST_TRANSFERRED:
423 if (xfer->actlen < 1) {

--- 6 unchanged lines hidden (view full) ---

430 DPRINTF("invalid serial number!\n");
431 goto tr_setup;
432 }
433 usb2_com_put_data(sc->sc_ucom + buf[0],
434 xfer->frbuffers, 1, xfer->actlen - 1);
435
436 case USB_ST_SETUP:
437tr_setup:
507 if (sc->sc_flags & UBSER_FLAG_READ_STALL) {
508 usb2_transfer_start(sc->sc_xfer[UBSER_BULK_CS_RD]);
509 } else {
510 xfer->frlengths[0] = xfer->max_data_length;
511 usb2_start_hardware(xfer);
512 }
438 xfer->frlengths[0] = xfer->max_data_length;
439 usb2_start_hardware(xfer);
513 return;
514
515 default: /* Error */
516 if (xfer->error != USB_ERR_CANCELLED) {
440 return;
441
442 default: /* Error */
443 if (xfer->error != USB_ERR_CANCELLED) {
517 sc->sc_flags |= UBSER_FLAG_READ_STALL;
518 usb2_transfer_start(sc->sc_xfer[UBSER_BULK_CS_RD]);
444 /* try to clear stall first */
445 xfer->flags.stall_pipe = 1;
446 goto tr_setup;
519 }
520 return;
521
522 }
523}
524
525static void
526ubser_cfg_set_break(struct usb2_com_softc *ucom, uint8_t onoff)

--- 8 unchanged lines hidden (view full) ---

535 req.bmRequestType = UT_READ_VENDOR_INTERFACE;
536 req.bRequest = VENDOR_SET_BREAK;
537 req.wValue[0] = x;
538 req.wValue[1] = 0;
539 req.wIndex[0] = sc->sc_iface_no;
540 req.wIndex[1] = 0;
541 USETW(req.wLength, 0);
542
447 }
448 return;
449
450 }
451}
452
453static void
454ubser_cfg_set_break(struct usb2_com_softc *ucom, uint8_t onoff)

--- 8 unchanged lines hidden (view full) ---

463 req.bmRequestType = UT_READ_VENDOR_INTERFACE;
464 req.bRequest = VENDOR_SET_BREAK;
465 req.wValue[0] = x;
466 req.wValue[1] = 0;
467 req.wIndex[0] = sc->sc_iface_no;
468 req.wIndex[1] = 0;
469 USETW(req.wLength, 0);
470
543 err = usb2_do_request_flags
544 (sc->sc_udev, &Giant, &req, NULL, 0, NULL, 1000);
545
471 err = usb2_com_cfg_do_request(sc->sc_udev, ucom,
472 &req, NULL, 0, 1000);
546 if (err) {
547 DPRINTFN(0, "send break failed, error=%s\n",
548 usb2_errstr(err));
549 }
550 }
551}
552
553static void

--- 12 unchanged lines hidden (view full) ---

566 usb2_transfer_start(sc->sc_xfer[UBSER_BULK_DT_RD]);
567}
568
569static void
570ubser_stop_read(struct usb2_com_softc *ucom)
571{
572 struct ubser_softc *sc = ucom->sc_parent;
573
473 if (err) {
474 DPRINTFN(0, "send break failed, error=%s\n",
475 usb2_errstr(err));
476 }
477 }
478}
479
480static void

--- 12 unchanged lines hidden (view full) ---

493 usb2_transfer_start(sc->sc_xfer[UBSER_BULK_DT_RD]);
494}
495
496static void
497ubser_stop_read(struct usb2_com_softc *ucom)
498{
499 struct ubser_softc *sc = ucom->sc_parent;
500
574 usb2_transfer_stop(sc->sc_xfer[UBSER_BULK_CS_RD]);
575 usb2_transfer_stop(sc->sc_xfer[UBSER_BULK_DT_RD]);
576}
577
578static void
579ubser_start_write(struct usb2_com_softc *ucom)
580{
581 struct ubser_softc *sc = ucom->sc_parent;
582
583 usb2_transfer_start(sc->sc_xfer[UBSER_BULK_DT_WR]);
584}
585
586static void
587ubser_stop_write(struct usb2_com_softc *ucom)
588{
589 struct ubser_softc *sc = ucom->sc_parent;
590
501 usb2_transfer_stop(sc->sc_xfer[UBSER_BULK_DT_RD]);
502}
503
504static void
505ubser_start_write(struct usb2_com_softc *ucom)
506{
507 struct ubser_softc *sc = ucom->sc_parent;
508
509 usb2_transfer_start(sc->sc_xfer[UBSER_BULK_DT_WR]);
510}
511
512static void
513ubser_stop_write(struct usb2_com_softc *ucom)
514{
515 struct ubser_softc *sc = ucom->sc_parent;
516
591 usb2_transfer_stop(sc->sc_xfer[UBSER_BULK_CS_WR]);
592 usb2_transfer_stop(sc->sc_xfer[UBSER_BULK_DT_WR]);
593}
517 usb2_transfer_stop(sc->sc_xfer[UBSER_BULK_DT_WR]);
518}