summaryrefslogtreecommitdiff
path: root/xpp/astribank_usb.c
diff options
context:
space:
mode:
Diffstat (limited to 'xpp/astribank_usb.c')
-rw-r--r--xpp/astribank_usb.c415
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;