udbp.c (194228) | udbp.c (194677) |
---|---|
1/*- 2 * Copyright (c) 1996-2000 Whistle Communications, Inc. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 15 unchanged lines hidden (view full) --- 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 * POSSIBILITY OF SUCH DAMAGE. 28 * 29 */ 30 31#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 1996-2000 Whistle Communications, Inc. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 15 unchanged lines hidden (view full) --- 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 * POSSIBILITY OF SUCH DAMAGE. 28 * 29 */ 30 31#include <sys/cdefs.h> |
32__FBSDID("$FreeBSD: head/sys/dev/usb/misc/udbp.c 194228 2009-06-15 01:02:43Z thompsa $"); | 32__FBSDID("$FreeBSD: head/sys/dev/usb/misc/udbp.c 194677 2009-06-23 02:19:59Z thompsa $"); |
33 34/* Driver for arbitrary double bulk pipe devices. 35 * The driver assumes that there will be the same driver on the other side. 36 * 37 * XXX Some more information on what the framing of the IP packets looks like. 38 * 39 * To take full advantage of bulk transmission, packets should be chosen 40 * between 1k and 5k in size (1k to make sure the sending side starts --- 11 unchanged lines hidden (view full) --- 52 * 53 * In case you were wondering, interrupt transfers happen exactly that way. 54 * It therefore doesn't make sense to use the interrupt pipe to signal 55 * 'data ready' and then schedule a bulk transfer to fetch it. That would 56 * incur a 2ms delay at least, without reducing bandwidth requirements. 57 * 58 */ 59 | 33 34/* Driver for arbitrary double bulk pipe devices. 35 * The driver assumes that there will be the same driver on the other side. 36 * 37 * XXX Some more information on what the framing of the IP packets looks like. 38 * 39 * To take full advantage of bulk transmission, packets should be chosen 40 * between 1k and 5k in size (1k to make sure the sending side starts --- 11 unchanged lines hidden (view full) --- 52 * 53 * In case you were wondering, interrupt transfers happen exactly that way. 54 * It therefore doesn't make sense to use the interrupt pipe to signal 55 * 'data ready' and then schedule a bulk transfer to fetch it. That would 56 * incur a 2ms delay at least, without reducing bandwidth requirements. 57 * 58 */ 59 |
60#include "usbdevs.h" | 60#include <sys/stdint.h> 61#include <sys/stddef.h> 62#include <sys/param.h> 63#include <sys/queue.h> 64#include <sys/types.h> 65#include <sys/systm.h> 66#include <sys/kernel.h> 67#include <sys/bus.h> 68#include <sys/linker_set.h> 69#include <sys/module.h> 70#include <sys/lock.h> 71#include <sys/mutex.h> 72#include <sys/condvar.h> 73#include <sys/sysctl.h> 74#include <sys/sx.h> 75#include <sys/unistd.h> 76#include <sys/callout.h> 77#include <sys/malloc.h> 78#include <sys/priv.h> 79 |
61#include <dev/usb/usb.h> | 80#include <dev/usb/usb.h> |
62#include <dev/usb/usb_mfunc.h> 63#include <dev/usb/usb_error.h> | 81#include <dev/usb/usbdi.h> 82#include <dev/usb/usbdi_util.h> 83#include "usbdevs.h" |
64 65#define USB_DEBUG_VAR udbp_debug | 84 85#define USB_DEBUG_VAR udbp_debug |
66 67#include <dev/usb/usb_core.h> | |
68#include <dev/usb/usb_debug.h> | 86#include <dev/usb/usb_debug.h> |
69#include <dev/usb/usb_parse.h> 70#include <dev/usb/usb_lookup.h> 71#include <dev/usb/usb_util.h> 72#include <dev/usb/usb_busdma.h> | |
73 74#include <sys/mbuf.h> 75 76#include <netgraph/ng_message.h> 77#include <netgraph/netgraph.h> 78#include <netgraph/ng_parse.h> 79#include <netgraph/bluetooth/include/ng_bluetooth.h> 80 --- 309 unchanged lines hidden (view full) --- 390 if (sc->sc_bulk_in_buffer) { 391 m_freem(sc->sc_bulk_in_buffer); 392 sc->sc_bulk_in_buffer = NULL; 393 } 394 return (0); /* success */ 395} 396 397static void | 87 88#include <sys/mbuf.h> 89 90#include <netgraph/ng_message.h> 91#include <netgraph/netgraph.h> 92#include <netgraph/ng_parse.h> 93#include <netgraph/bluetooth/include/ng_bluetooth.h> 94 --- 309 unchanged lines hidden (view full) --- 404 if (sc->sc_bulk_in_buffer) { 405 m_freem(sc->sc_bulk_in_buffer); 406 sc->sc_bulk_in_buffer = NULL; 407 } 408 return (0); /* success */ 409} 410 411static void |
398udbp_bulk_read_callback(struct usb_xfer *xfer) | 412udbp_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error) |
399{ | 413{ |
400 struct udbp_softc *sc = xfer->priv_sc; | 414 struct udbp_softc *sc = usbd_xfer_softc(xfer); 415 struct usb_page_cache *pc; |
401 struct mbuf *m; | 416 struct mbuf *m; |
417 int actlen; |
|
402 | 418 |
419 usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL); 420 |
|
403 switch (USB_GET_STATE(xfer)) { 404 case USB_ST_TRANSFERRED: 405 406 /* allocate new mbuf */ 407 408 MGETHDR(m, M_DONTWAIT, MT_DATA); 409 410 if (m == NULL) { 411 goto tr_setup; 412 } 413 MCLGET(m, M_DONTWAIT); 414 415 if (!(m->m_flags & M_EXT)) { 416 m_freem(m); 417 goto tr_setup; 418 } | 421 switch (USB_GET_STATE(xfer)) { 422 case USB_ST_TRANSFERRED: 423 424 /* allocate new mbuf */ 425 426 MGETHDR(m, M_DONTWAIT, MT_DATA); 427 428 if (m == NULL) { 429 goto tr_setup; 430 } 431 MCLGET(m, M_DONTWAIT); 432 433 if (!(m->m_flags & M_EXT)) { 434 m_freem(m); 435 goto tr_setup; 436 } |
419 m->m_pkthdr.len = m->m_len = xfer->actlen; | 437 m->m_pkthdr.len = m->m_len = actlen; |
420 | 438 |
421 usbd_copy_out(xfer->frbuffers, 0, m->m_data, xfer->actlen); | 439 pc = usbd_xfer_get_frame(xfer, 0); 440 usbd_copy_out(pc, 0, m->m_data, actlen); |
422 423 sc->sc_bulk_in_buffer = m; 424 | 441 442 sc->sc_bulk_in_buffer = m; 443 |
425 DPRINTF("received package %d " 426 "bytes\n", xfer->actlen); | 444 DPRINTF("received package %d bytes\n", actlen); |
427 428 case USB_ST_SETUP: 429tr_setup: 430 if (sc->sc_bulk_in_buffer) { 431 ng_send_fn(sc->sc_node, NULL, &udbp_bulk_read_complete, NULL, 0); 432 return; 433 } 434 if (sc->sc_flags & UDBP_FLAG_READ_STALL) { 435 usbd_transfer_start(sc->sc_xfer[UDBP_T_RD_CS]); 436 return; 437 } | 445 446 case USB_ST_SETUP: 447tr_setup: 448 if (sc->sc_bulk_in_buffer) { 449 ng_send_fn(sc->sc_node, NULL, &udbp_bulk_read_complete, NULL, 0); 450 return; 451 } 452 if (sc->sc_flags & UDBP_FLAG_READ_STALL) { 453 usbd_transfer_start(sc->sc_xfer[UDBP_T_RD_CS]); 454 return; 455 } |
438 xfer->frlengths[0] = xfer->max_data_length; | 456 usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer)); |
439 usbd_transfer_submit(xfer); 440 return; 441 442 default: /* Error */ | 457 usbd_transfer_submit(xfer); 458 return; 459 460 default: /* Error */ |
443 if (xfer->error != USB_ERR_CANCELLED) { | 461 if (error != USB_ERR_CANCELLED) { |
444 /* try to clear stall first */ 445 sc->sc_flags |= UDBP_FLAG_READ_STALL; 446 usbd_transfer_start(sc->sc_xfer[UDBP_T_RD_CS]); 447 } 448 return; 449 450 } 451} 452 453static void | 462 /* try to clear stall first */ 463 sc->sc_flags |= UDBP_FLAG_READ_STALL; 464 usbd_transfer_start(sc->sc_xfer[UDBP_T_RD_CS]); 465 } 466 return; 467 468 } 469} 470 471static void |
454udbp_bulk_read_clear_stall_callback(struct usb_xfer *xfer) | 472udbp_bulk_read_clear_stall_callback(struct usb_xfer *xfer, usb_error_t error) |
455{ | 473{ |
456 struct udbp_softc *sc = xfer->priv_sc; | 474 struct udbp_softc *sc = usbd_xfer_softc(xfer); |
457 struct usb_xfer *xfer_other = sc->sc_xfer[UDBP_T_RD]; 458 459 if (usbd_clear_stall_callback(xfer, xfer_other)) { 460 DPRINTF("stall cleared\n"); 461 sc->sc_flags &= ~UDBP_FLAG_READ_STALL; 462 usbd_transfer_start(xfer_other); 463 } 464} --- 34 unchanged lines hidden (view full) --- 499 /* start USB bulk-in transfer, if not already started */ 500 501 usbd_transfer_start(sc->sc_xfer[UDBP_T_RD]); 502 503 mtx_unlock(&sc->sc_mtx); 504} 505 506static void | 475 struct usb_xfer *xfer_other = sc->sc_xfer[UDBP_T_RD]; 476 477 if (usbd_clear_stall_callback(xfer, xfer_other)) { 478 DPRINTF("stall cleared\n"); 479 sc->sc_flags &= ~UDBP_FLAG_READ_STALL; 480 usbd_transfer_start(xfer_other); 481 } 482} --- 34 unchanged lines hidden (view full) --- 517 /* start USB bulk-in transfer, if not already started */ 518 519 usbd_transfer_start(sc->sc_xfer[UDBP_T_RD]); 520 521 mtx_unlock(&sc->sc_mtx); 522} 523 524static void |
507udbp_bulk_write_callback(struct usb_xfer *xfer) | 525udbp_bulk_write_callback(struct usb_xfer *xfer, usb_error_t error) |
508{ | 526{ |
509 struct udbp_softc *sc = xfer->priv_sc; | 527 struct udbp_softc *sc = usbd_xfer_softc(xfer); 528 struct usb_page_cache *pc; |
510 struct mbuf *m; 511 512 switch (USB_GET_STATE(xfer)) { 513 case USB_ST_TRANSFERRED: 514 515 sc->sc_packets_out++; 516 517 case USB_ST_SETUP: --- 12 unchanged lines hidden (view full) --- 530 } 531 } 532 if (m->m_pkthdr.len > MCLBYTES) { 533 DPRINTF("truncating large packet " 534 "from %d to %d bytes\n", m->m_pkthdr.len, 535 MCLBYTES); 536 m->m_pkthdr.len = MCLBYTES; 537 } | 529 struct mbuf *m; 530 531 switch (USB_GET_STATE(xfer)) { 532 case USB_ST_TRANSFERRED: 533 534 sc->sc_packets_out++; 535 536 case USB_ST_SETUP: --- 12 unchanged lines hidden (view full) --- 549 } 550 } 551 if (m->m_pkthdr.len > MCLBYTES) { 552 DPRINTF("truncating large packet " 553 "from %d to %d bytes\n", m->m_pkthdr.len, 554 MCLBYTES); 555 m->m_pkthdr.len = MCLBYTES; 556 } |
538 usbd_m_copy_in(xfer->frbuffers, 0, m, 0, m->m_pkthdr.len); | 557 pc = usbd_xfer_get_frame(xfer, 0); 558 usbd_m_copy_in(pc, 0, m, 0, m->m_pkthdr.len); |
539 | 559 |
540 xfer->frlengths[0] = m->m_pkthdr.len; | 560 usbd_xfer_set_frame_len(xfer, 0, m->m_pkthdr.len); |
541 | 561 |
562 DPRINTF("packet out: %d bytes\n", m->m_pkthdr.len); 563 |
|
542 m_freem(m); 543 | 564 m_freem(m); 565 |
544 DPRINTF("packet out: %d bytes\n", 545 xfer->frlengths[0]); 546 | |
547 usbd_transfer_submit(xfer); 548 return; 549 550 default: /* Error */ | 566 usbd_transfer_submit(xfer); 567 return; 568 569 default: /* Error */ |
551 if (xfer->error != USB_ERR_CANCELLED) { | 570 if (error != USB_ERR_CANCELLED) { |
552 /* try to clear stall first */ 553 sc->sc_flags |= UDBP_FLAG_WRITE_STALL; 554 usbd_transfer_start(sc->sc_xfer[UDBP_T_WR_CS]); 555 } 556 return; 557 558 } 559} 560 561static void | 571 /* try to clear stall first */ 572 sc->sc_flags |= UDBP_FLAG_WRITE_STALL; 573 usbd_transfer_start(sc->sc_xfer[UDBP_T_WR_CS]); 574 } 575 return; 576 577 } 578} 579 580static void |
562udbp_bulk_write_clear_stall_callback(struct usb_xfer *xfer) | 581udbp_bulk_write_clear_stall_callback(struct usb_xfer *xfer, usb_error_t error) |
563{ | 582{ |
564 struct udbp_softc *sc = xfer->priv_sc; | 583 struct udbp_softc *sc = usbd_xfer_softc(xfer); |
565 struct usb_xfer *xfer_other = sc->sc_xfer[UDBP_T_WR]; 566 567 if (usbd_clear_stall_callback(xfer, xfer_other)) { 568 DPRINTF("stall cleared\n"); 569 sc->sc_flags &= ~UDBP_FLAG_WRITE_STALL; 570 usbd_transfer_start(xfer_other); 571 } 572} --- 279 unchanged lines hidden --- | 584 struct usb_xfer *xfer_other = sc->sc_xfer[UDBP_T_WR]; 585 586 if (usbd_clear_stall_callback(xfer, xfer_other)) { 587 DPRINTF("stall cleared\n"); 588 sc->sc_flags &= ~UDBP_FLAG_WRITE_STALL; 589 usbd_transfer_start(xfer_other); 590 } 591} --- 279 unchanged lines hidden --- |