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} |