diff options
Diffstat (limited to 'xpp/astribank_usb.c')
-rw-r--r-- | xpp/astribank_usb.c | 415 |
1 files changed, 67 insertions, 348 deletions
diff --git a/xpp/astribank_usb.c b/xpp/astribank_usb.c index dce3d47..13af7cd 100644 --- a/xpp/astribank_usb.c +++ b/xpp/astribank_usb.c @@ -30,39 +30,44 @@ #include <stdarg.h> #include <syslog.h> #include <arpa/inet.h> +#include <xusb.h> #include "astribank_usb.h" -#include "debug.h" +#include <debug.h> static const char rcsid[] = "$Id$"; #define DBG_MASK 0x01 #define TIMEOUT 500 -#define TYPE_ENTRY(t,ni,n,ne,out,in,...) \ - [t] = { \ - .type_code = (t), \ +#define TYPE_ENTRY(t,p,ni,n,ne,out,in,...) \ + { \ + .my_vendor_id = 0xe4e4, \ + .my_product_id = (p), \ + .name = #t, \ .num_interfaces = (ni), \ .my_interface_num = (n), \ .num_endpoints = (ne), \ .my_ep_in = (in), \ .my_ep_out = (out), \ - .name = #t, \ - .endpoints = { __VA_ARGS__ }, \ } -static const struct interface_type interface_types[] = { - TYPE_ENTRY(USB_11xx, 1, 0, 4, MP_EP_OUT, MP_EP_IN, - XPP_EP_OUT, - MP_EP_OUT, - XPP_EP_IN, - MP_EP_IN), - TYPE_ENTRY(USB_FIRMWARE_II, 2, 1, 2, MP_EP_OUT, MP_EP_IN, - MP_EP_OUT, - MP_EP_IN), - TYPE_ENTRY(USB_PIC, 2, 0, 2, XPP_EP_OUT, XPP_EP_IN, - XPP_EP_OUT, - XPP_EP_IN), - +#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) + +static const struct xusb_spec astribank_specs[] = { + /* OLD Firmwares */ + TYPE_ENTRY("USB-OLDFXS", 0x1131, 2, 1, 2, MP_EP_OUT, MP_EP_IN), + TYPE_ENTRY("FPGA-OLDFXS", 0x1132, 2, 1, 2, MP_EP_OUT, MP_EP_IN), + TYPE_ENTRY("USB-BRI", 0x1141, 2, 1, 2, MP_EP_OUT, MP_EP_IN), + TYPE_ENTRY("FPGA-BRI", 0x1142, 2, 1, 2, MP_EP_OUT, MP_EP_IN), + TYPE_ENTRY("USB-OLD", 0x1151, 2, 1, 2, MP_EP_OUT, MP_EP_IN), + TYPE_ENTRY("FPGA-OLD", 0x1152, 2, 1, 2, MP_EP_OUT, MP_EP_IN), + + TYPE_ENTRY("USB-MULTI", 0x1161, 2, 1, 2, MP_EP_OUT, MP_EP_IN), + TYPE_ENTRY("FPGA-MULTI", 0x1162, 2, 1, 2, MP_EP_OUT, MP_EP_IN), +}; + +static const struct xusb_spec astribank_pic_specs[] = { + TYPE_ENTRY("USB_PIC", 0x1161, 2, 0, 2, XPP_EP_OUT, XPP_EP_IN), }; #undef TYPE_ENTRY @@ -71,262 +76,41 @@ static const struct interface_type interface_types[] = { /* * USB handling */ - -/* return 1 if: - * - str has a number - * - It is larger than 0 - * - It equals num - */ -static int num_matches(int num, const char* str) { - int str_val = atoi(str); - if (str_val <= 0) - return 0; - return (str_val == num); -} - -struct usb_device *dev_of_path(const char *path) -{ - struct usb_bus *bus; - struct usb_device *dev; - char dirname[PATH_MAX]; - char filename[PATH_MAX]; - const char *p; - int bnum; - int dnum; - int ret; - - assert(path != NULL); - if(access(path, F_OK) < 0) { - perror(path); - return NULL; - } - /* Find last '/' */ - if((p = memrchr(path, '/', strlen(path))) == NULL) { - ERR("Missing a '/' in %s\n", path); - return NULL; - } - /* Get the device number */ - ret = sscanf(p + 1, "%d", &dnum); - if(ret != 1) { - ERR("Path tail is not a device number: '%s'\n", p); - return NULL; - } - /* Search for a '/' before that */ - p = memrchr(path, '/', p - path); - if(p == NULL) - p = path; /* Relative path */ - else - p++; /* skip '/' */ - /* Get the bus number */ - ret = sscanf(p, "%d", &bnum); - if(ret != 1) { - ERR("Path tail is not a bus number: '%s'\n", p); - return NULL; - } - sprintf(dirname, "%03d", bnum); - sprintf(filename, "%03d", dnum); - for (bus = usb_busses; bus; bus = bus->next) { - if (! num_matches(bnum, bus->dirname)) - //if(strcmp(bus->dirname, dirname) != 0) - continue; - for (dev = bus->devices; dev; dev = dev->next) { - //if(strcmp(dev->filename, filename) == 0) - if (num_matches(dnum, dev->filename)) - return dev; - } - } - ERR("no usb device match '%s'\n", path); - return NULL; -} - -int get_usb_string(struct astribank_device *astribank, uint8_t item, char *buf, unsigned int len) -{ - char tmp[BUFSIZ]; - int ret; - - assert(astribank->handle); - if (!item) - return 0; - ret = usb_get_string_simple(astribank->handle, item, tmp, BUFSIZ); - if (ret <= 0) - return ret; - return snprintf(buf, len, "%s", tmp); -} - -static int match_interface(const struct astribank_device *astribank, - const struct interface_type *itype) -{ - struct usb_interface *interface; - struct usb_interface_descriptor *iface_desc; - struct usb_config_descriptor *config_desc; - int i = itype - interface_types; - int inum; - int num_altsetting; - - DBG("Checking[%d]: interfaces=%d interface num=%d endpoints=%d: \"%s\"\n", - i, - itype->num_interfaces, - itype->my_interface_num, - itype->num_endpoints, - itype->name); - config_desc = astribank->dev->config; - if (!config_desc) { - ERR("No configuration descriptor: strange USB1 controller?\n"); - return 0; - } - if(config_desc->bNumInterfaces <= itype->my_interface_num) { - DBG("Too little interfaces: have %d need %d\n", - config_desc->bNumInterfaces, itype->my_interface_num + 1); - return 0; - } - if(astribank->my_interface_num != itype->my_interface_num) { - DBG("Wrong match -- not my interface num (wanted %d)\n", astribank->my_interface_num); - return 0; - } - inum = itype->my_interface_num; - interface = &config_desc->interface[inum]; - assert(interface != NULL); - iface_desc = interface->altsetting; - num_altsetting = interface->num_altsetting; - assert(num_altsetting != 0); - assert(iface_desc != NULL); - if(iface_desc->bInterfaceClass != 0xFF) { - DBG("Bad interface class 0x%X\n", iface_desc->bInterfaceClass); - return 0; - } - if(iface_desc->bInterfaceNumber != itype->my_interface_num) { - DBG("Bad interface number %d\n", iface_desc->bInterfaceNumber); - return 0; - } - if(iface_desc->bNumEndpoints != itype->num_endpoints) { - DBG("Different number of endpoints %d\n", iface_desc->bNumEndpoints); - return 0; - } - return 1; -} - -static int astribank_init(struct astribank_device *astribank) -{ - struct usb_device_descriptor *dev_desc; - struct usb_config_descriptor *config_desc; - struct usb_interface *interface; - struct usb_interface_descriptor *iface_desc; - struct usb_endpoint_descriptor *endpoint; - const struct interface_type *fwtype; - int i; - - assert(astribank); - astribank->handle = usb_open(astribank->dev); - if(!astribank->handle) { - ERR("Failed to open usb device '%s/%s': %s\n", - astribank->dev->bus->dirname, astribank->dev->filename, usb_strerror()); - return 0; - } - fwtype = astribank->fwtype; - if(usb_claim_interface(astribank->handle, fwtype->my_interface_num) != 0) { - ERR("usb_claim_interface: %s\n", usb_strerror()); - return 0; - } - dev_desc = &astribank->dev->descriptor; - config_desc = astribank->dev->config; - if (!config_desc) { - ERR("usb interface without a configuration\n"); - return 0; - } - DBG("Got config_desc. Looking for interface %d\n", fwtype->my_interface_num); - interface = &config_desc->interface[fwtype->my_interface_num]; - iface_desc = interface->altsetting; - endpoint = iface_desc->endpoint; - astribank->is_usb2 = (endpoint->wMaxPacketSize == 512); - for(i = 0; i < iface_desc->bNumEndpoints; i++, endpoint++) { - DBG("Validating endpoint @ %d (interface %d)\n", i, fwtype->my_interface_num); - if(endpoint->bEndpointAddress != fwtype->endpoints[i]) { - ERR("Wrong endpoint 0x%X != 0x%X (at index %d)\n", - endpoint->bEndpointAddress, - fwtype->endpoints[i], - i); - return 0; - } - if(endpoint->bEndpointAddress == MP_EP_OUT || endpoint->bEndpointAddress == MP_EP_IN) { - if(endpoint->wMaxPacketSize > PACKET_SIZE) { - ERR("Endpoint #%d wMaxPacketSize too large (%d)\n", i, endpoint->wMaxPacketSize); - return 0; - } - } - } - astribank->my_ep_in = fwtype->my_ep_in; - astribank->my_ep_out = fwtype->my_ep_out; - if(get_usb_string(astribank, dev_desc->iManufacturer, astribank->iManufacturer, BUFSIZ) < 0) - return 0; - if(get_usb_string(astribank, dev_desc->iProduct, astribank->iProduct, BUFSIZ) < 0) - return 0; - if(get_usb_string(astribank, dev_desc->iSerialNumber, astribank->iSerialNumber, BUFSIZ) < 0) - return 0; - if(get_usb_string(astribank, iface_desc->iInterface, astribank->iInterface, BUFSIZ) < 0) - return 0; - DBG("ID=%04X:%04X Manufacturer=[%s] Product=[%s] SerialNumber=[%s] Interface=[%s]\n", - dev_desc->idVendor, - dev_desc->idProduct, - astribank->iManufacturer, - astribank->iProduct, - astribank->iSerialNumber, - astribank->iInterface); - if(usb_clear_halt(astribank->handle, astribank->my_ep_out) != 0) { - ERR("Clearing output endpoint: %s\n", usb_strerror()); - return 0; - } - if(usb_clear_halt(astribank->handle, astribank->my_ep_in) != 0) { - ERR("Clearing input endpoint: %s\n", usb_strerror()); - return 0; - } - if((i = flush_read(astribank)) < 0) { - ERR("flush_read failed: %d\n", i); - return 0; - } - return 1; -} - struct astribank_device *astribank_open(const char devpath[], int iface_num) { - struct astribank_device *astribank; - int i; + struct astribank_device *astribank = NULL; + struct xusb *xusb; DBG("devpath='%s' iface_num=%d\n", devpath, iface_num); - if((astribank = malloc(sizeof(*astribank))) == NULL) { - ERR("Out of memory"); - return NULL; + if((astribank = malloc(sizeof(struct astribank_device))) == NULL) { + ERR("Out of memory\n"); + goto fail; } memset(astribank, 0, sizeof(*astribank)); - astribank->my_interface_num = iface_num; - usb_init(); - usb_find_busses(); - usb_find_devices(); - astribank->dev = dev_of_path(devpath); - if(!astribank->dev) { - ERR("Bailing out\n"); - goto fail; + if (iface_num) { + xusb = xusb_find_bypath(astribank_specs, ARRAY_SIZE(astribank_specs), devpath); + } else { + xusb = xusb_find_bypath(astribank_pic_specs, ARRAY_SIZE(astribank_pic_specs), devpath); } - DBG("Scan interface types (astribank has %d interfaces)\n", astribank->dev->config->bNumInterfaces); - for(i = 0; i < sizeof(interface_types)/sizeof(interface_types[0]); i++) { - if(match_interface(astribank, &interface_types[i])) { - DBG("Identified[%d]: interfaces=%d endpoints=%d: \"%s\"\n", - i, - interface_types[i].num_interfaces, - interface_types[i].num_endpoints, - interface_types[i].name); - astribank->fwtype = &interface_types[i]; - goto found; - } + if (!xusb) { + ERR("%s: No device found\n", __func__); + goto fail; } - ERR("Didn't find suitable device\n"); -fail: - free(astribank); - return NULL; -found: - if(!astribank_init(astribank)) + astribank->xusb = xusb; + astribank->is_usb2 = (xusb_packet_size(xusb) == 512); + astribank->my_interface_num = iface_num; + if (xusb_claim_interface(astribank->xusb) < 0) { + ERR("xusb_claim_interface failed\n"); goto fail; + } astribank->tx_sequenceno = 1; return astribank; +fail: + if (astribank) { + free(astribank); + astribank = NULL; + } + return NULL; } /* @@ -334,100 +118,36 @@ found: */ void show_astribank_info(const struct astribank_device *astribank) { - struct usb_device_descriptor *dev_desc; - struct usb_device *dev; + struct xusb *xusb; assert(astribank != NULL); - dev = astribank->dev; - dev_desc = &dev->descriptor; + xusb = astribank->xusb; + assert(xusb != NULL); if(verbose <= LOG_INFO) { - INFO("usb:%s/%s: ID=%04X:%04X [%s / %s / %s]\n", - dev->bus->dirname, - dev->filename, - dev_desc->idVendor, - dev_desc->idProduct, - astribank->iManufacturer, - astribank->iProduct, - astribank->iSerialNumber); + xusb_showinfo(xusb); } else { - printf("USB Bus/Device: [%s/%s]\n", dev->bus->dirname, dev->filename); - printf("USB Firmware Type: [%s]\n", astribank->fwtype->name); - printf("USB iManufacturer: [%s]\n", astribank->iManufacturer); - printf("USB iProduct: [%s]\n", astribank->iProduct); - printf("USB iSerialNumber: [%s]\n", astribank->iSerialNumber); + const struct xusb_spec *spec; + + spec = xusb_spec(xusb); + printf("USB Bus/Device: [%s]\n", xusb_devpath(xusb)); + printf("USB Firmware Type: [%s]\n", spec->name); + printf("USB iSerialNumber: [%s]\n", xusb_serial(xusb)); + printf("USB iManufacturer: [%s]\n", xusb_manufacturer(xusb)); + printf("USB iProduct: [%s]\n", xusb_product(xusb)); } } void astribank_close(struct astribank_device *astribank, int disconnected) { assert(astribank != NULL); - if(!astribank->handle) - return; /* Nothing to do */ - if(!disconnected) { - if(usb_release_interface(astribank->handle, astribank->fwtype->my_interface_num) != 0) { - ERR("Releasing interface: usb: %s\n", usb_strerror()); - } - } - if(usb_close(astribank->handle) != 0) { - ERR("Closing device: usb: %s\n", usb_strerror()); + if (astribank->xusb) { + xusb_close(astribank->xusb); + astribank->xusb = NULL; } astribank->tx_sequenceno = 0; - astribank->handle = NULL; -} - -int send_usb(struct astribank_device *astribank, char *buf, int len, int timeout) -{ - int ret; - - dump_packet(LOG_DEBUG, __FUNCTION__, buf, len); - if(astribank->my_ep_out & USB_ENDPOINT_IN) { - ERR("send_usb called with an input endpoint 0x%x\n", astribank->my_ep_out); - return -EINVAL; - } - ret = usb_bulk_write(astribank->handle, astribank->my_ep_out, buf, len, timeout); - if(ret < 0) { - /* - * If the device was gone, it may be the - * result of renumeration. Ignore it. - */ - if(ret != -ENODEV) { - ERR("bulk_write to endpoint 0x%x failed: (%d) %s\n", - astribank->my_ep_out, ret, usb_strerror()); - dump_packet(LOG_ERR, "send_usb[ERR]", buf, len); - exit(2); - } else { - DBG("bulk_write to endpoint 0x%x got ENODEV\n", astribank->my_ep_out); - astribank_close(astribank, 1); - } - return ret; - } else if(ret != len) { - ERR("bulk_write to endpoint 0x%x short write: (%d) %s\n", - astribank->my_ep_out, ret, usb_strerror()); - dump_packet(LOG_ERR, "send_usb[ERR]", buf, len); - return -EFAULT; - } - return ret; -} - -int recv_usb(struct astribank_device *astribank, char *buf, size_t len, int timeout) -{ - int ret; - - if(astribank->my_ep_in & USB_ENDPOINT_OUT) { - ERR("recv_usb called with an output endpoint 0x%x\n", astribank->my_ep_in); - return -EINVAL; - } - ret = usb_bulk_read(astribank->handle, astribank->my_ep_in, buf, len, timeout); - if(ret < 0) { - DBG("bulk_read from endpoint 0x%x failed: (%d) %s\n", - astribank->my_ep_in, ret, usb_strerror()); - memset(buf, 0, len); - return ret; - } - dump_packet(LOG_DEBUG, __FUNCTION__, buf, ret); - return ret; } +#if 0 int flush_read(struct astribank_device *astribank) { char tmpbuf[BUFSIZ]; @@ -441,10 +161,11 @@ int flush_read(struct astribank_device *astribank) return ret; } else if(ret > 0) { DBG("Got %d bytes:\n", ret); - dump_packet(LOG_DEBUG, __FUNCTION__, tmpbuf, ret); + dump_packet(LOG_DEBUG, DBG_MASK, __FUNCTION__, tmpbuf, ret); } return 0; } +#endif int release_isvalid(uint16_t release) @@ -541,12 +262,10 @@ int eeprom_fill(struct eeprom_table *eprm, int astribank_has_twinstar(struct astribank_device *astribank) { - struct usb_device_descriptor *dev_desc; uint16_t product_series; assert(astribank != NULL); - dev_desc = &astribank->dev->descriptor; - product_series = dev_desc->idProduct; + product_series = xusb_product_id(astribank->xusb); product_series &= 0xFFF0; if(product_series == 0x1160) /* New boards */ return 1; |