diff --git a/usb/config.go b/usb/config.go index 53c5a97..d60a703 100644 --- a/usb/config.go +++ b/usb/config.go @@ -38,14 +38,17 @@ func (e EndpointInfo) Number() int { return int(e.Address) & ENDPOINT_NUM_MASK } +func (e EndpointInfo) TransferType() TransferType { + return TransferType(e.Attributes) & TRANSFER_TYPE_MASK +} + func (e EndpointInfo) Direction() EndpointDirection { return EndpointDirection(e.Address) & ENDPOINT_DIR_MASK } func (e EndpointInfo) String() string { return fmt.Sprintf("Endpoint %d %-3s %s - %s %s [%d %d]", - e.Number(), e.Direction(), - TransferType(e.Attributes)&TRANSFER_TYPE_MASK, + e.Number(), e.Direction(), e.TransferType(), IsoSyncType(e.Attributes)&ISO_SYNC_TYPE_MASK, IsoUsageType(e.Attributes)&ISO_USAGE_TYPE_MASK, e.MaxPacketSize, e.MaxIsoPacket, @@ -135,7 +138,7 @@ func newConfig(dev *C.libusb_device, cfg *C.struct_libusb_config_descriptor) Con RefreshRate: uint8(end.bRefresh), SynchAddress: uint8(end.bSynchAddress), } - if TransferType(ei.Attributes)&TRANSFER_TYPE_MASK == TRANSFER_TYPE_ISOCHRONOUS { + if ei.TransferType() == TRANSFER_TYPE_ISOCHRONOUS { // bits 0-10 identify the packet size, bits 11-12 are the number of additional transactions per microframe. // Don't use libusb_get_max_iso_packet_size, as it has a bug where it returns the same value // regardless of alternative setting used, where different alternative settings might define different diff --git a/usb/device.go b/usb/device.go index 309fd4c..e065a46 100644 --- a/usb/device.go +++ b/usb/device.go @@ -151,16 +151,6 @@ func (d *Device) OpenEndpoint(conf, iface, setup, epoint uint8) (Endpoint, error } end.InterfaceSetup = s end.EndpointInfo = e - switch tt := TransferType(e.Attributes) & TRANSFER_TYPE_MASK; tt { - case TRANSFER_TYPE_BULK: - end.xfer = bulk_xfer - case TRANSFER_TYPE_INTERRUPT: - end.xfer = interrupt_xfer - case TRANSFER_TYPE_ISOCHRONOUS: - end.xfer = isochronous_xfer - default: - return nil, fmt.Errorf("usb: %s transfer is unsupported", tt) - } goto found } return nil, fmt.Errorf("usb: unknown endpoint %02x", epoint) diff --git a/usb/endpoint.go b/usb/endpoint.go index a6d30e2..68fbcdf 100644 --- a/usb/endpoint.go +++ b/usb/endpoint.go @@ -21,7 +21,6 @@ import "C" import ( "fmt" "log" - "reflect" "time" "unsafe" ) @@ -37,7 +36,6 @@ type endpoint struct { *Device InterfaceSetup EndpointInfo - xfer func(*endpoint, []byte, time.Duration) (int, error) } func (e *endpoint) Read(buf []byte) (int, error) { @@ -45,7 +43,7 @@ func (e *endpoint) Read(buf []byte) (int, error) { return 0, fmt.Errorf("usb: read: not an IN endpoint") } - return e.xfer(e, buf, e.ReadTimeout) + return e.transfer(buf, e.ReadTimeout) } func (e *endpoint) Write(buf []byte) (int, error) { @@ -53,58 +51,37 @@ func (e *endpoint) Write(buf []byte) (int, error) { return 0, fmt.Errorf("usb: write: not an OUT endpoint") } - return e.xfer(e, buf, e.WriteTimeout) + return e.transfer(buf, e.WriteTimeout) } func (e *endpoint) Interface() InterfaceSetup { return e.InterfaceSetup } func (e *endpoint) Info() EndpointInfo { return e.EndpointInfo } -// TODO(kevlar): (*Endpoint).Close - -func bulk_xfer(e *endpoint, buf []byte, timeout time.Duration) (int, error) { +func (e *endpoint) transfer(buf []byte, timeout time.Duration) (int, error) { if len(buf) == 0 { return 0, nil } - t, err := e.newUSBTransfer(TRANSFER_TYPE_BULK, buf) + tt := e.TransferType() + t, err := e.newUSBTransfer(tt, buf) if err != nil { return 0, err } defer t.free() if err := t.submit(timeout); err != nil { - log.Printf("bulk: xfer failed to submit: %s", err) + log.Printf("bulk: %s failed to submit: %s", tt, err) return 0, err } n, err := t.wait(buf) if err != nil { - log.Printf("bulk: xfer failed: %s", err) + log.Printf("bulk: %s failed: %s", tt, err) return 0, err } return n, err } -func interrupt_xfer(e *endpoint, buf []byte, timeout time.Duration) (int, error) { - if len(buf) == 0 { - return 0, nil - } - - data := (*reflect.SliceHeader)(unsafe.Pointer(&buf)).Data - - var cnt C.int - if errno := C.libusb_interrupt_transfer( - e.handle, - C.uchar(e.Address), - (*C.uchar)(unsafe.Pointer(data)), - C.int(len(buf)), - &cnt, - C.uint(timeout/time.Millisecond)); errno < 0 { - return 0, usbError(errno) - } - return int(cnt), nil -} - func (e *endpoint) newUSBTransfer(tt TransferType, buf []byte) (*usbTransfer, error) { var isoPackets int if tt == TRANSFER_TYPE_ISOCHRONOUS {