Make all transfer types use a generic endpoint.transfer() function

that uses libusb's asynchronous interface.
This commit is contained in:
Sebastian Zagrodzki
2017-02-10 22:06:57 +01:00
parent c9c2757fe6
commit 87abb704d7
3 changed files with 13 additions and 43 deletions

View File

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

View File

@@ -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)

View File

@@ -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 {