$OpenBSD: patch-bsd_c,v 1.12 2011/01/25 21:04:16 jakemsr Exp $ usb_os_find_busses(): don't access to the bus. just say there is one. usb_os_find_devices(): only ugen(4) are supported, so just probe /dev/ugen*. --- bsd.c.orig Fri Mar 3 18:52:46 2006 +++ bsd.c Mon Jan 24 23:46:26 2011 @@ -361,7 +361,7 @@ int usb_bulk_read(usb_dev_handle *dev, int ep, char *b int usb_interrupt_write(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout) { - int fd, ret, sent = 0; + int fd, ret; /* Ensure the endpoint address is correct */ ep &= ~USB_ENDPOINT_IN; @@ -383,8 +383,7 @@ int usb_interrupt_write(usb_dev_handle *dev, int ep, c USB_ERROR_STR(-errno, "error setting timeout: %s", strerror(errno)); - do { - ret = write(fd, bytes+sent, size-sent); + ret = write(fd, bytes, size); if (ret < 0) #ifdef __FreeBSD_kernel__ USB_ERROR_STR(-errno, "error writing to interrupt endpoint %s.%d: %s", @@ -394,16 +393,13 @@ int usb_interrupt_write(usb_dev_handle *dev, int ep, c dev->device->filename, UE_GET_ADDR(ep), strerror(errno)); #endif - sent += ret; - } while (ret > 0 && sent < size); - - return sent; + return ret; } int usb_interrupt_read(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout) { - int fd, ret, retrieved = 0, one = 1; + int fd, ret, one = 1; /* Ensure the endpoint address is correct */ ep |= USB_ENDPOINT_IN; @@ -428,8 +424,7 @@ int usb_interrupt_read(usb_dev_handle *dev, int ep, ch if (ret < 0) USB_ERROR_STR(-errno, "error setting short xfer: %s", strerror(errno)); - do { - ret = read(fd, bytes+retrieved, size-retrieved); + ret = read(fd, bytes, size); if (ret < 0) #ifdef __FreeBSD_kernel__ USB_ERROR_STR(-errno, "error reading from interrupt endpoint %s.%d: %s", @@ -438,10 +433,7 @@ int usb_interrupt_read(usb_dev_handle *dev, int ep, ch USB_ERROR_STR(-errno, "error reading from interrupt endpoint %s.%02d: %s", dev->device->filename, UE_GET_ADDR(ep), strerror(errno)); #endif - retrieved += ret; - } while (ret > 0 && retrieved < size); - - return retrieved; + return ret; } int usb_control_msg(usb_dev_handle *dev, int requesttype, int request, @@ -477,45 +469,28 @@ int usb_control_msg(usb_dev_handle *dev, int requestty USB_ERROR_STR(-errno, "error sending control message: %s", strerror(errno)); - return UGETW(req.ucr_request.wLength); + return req.ucr_actlen; } int usb_os_find_busses(struct usb_bus **busses) { struct usb_bus *fbus = NULL; - int controller; - int fd; - char buf[20]; + struct usb_bus *bus; - for (controller = 0; controller < MAX_CONTROLLERS; controller++) { - struct usb_bus *bus; + /* just one bus that always exists. this is faked, so we don't have + * to give access to the bus. + */ - snprintf(buf, sizeof(buf) - 1, "/dev/usb%d", controller); - fd = open(buf, O_RDWR); - if (fd < 0) { - if (usb_debug >= 2) - if (errno != ENXIO && errno != ENOENT) - fprintf(stderr, "usb_os_find_busses: can't open %s: %s\n", - buf, strerror(errno)); - continue; - } - close(fd); + bus = malloc(sizeof(*bus)); + if (!bus) + USB_ERROR(-ENOMEM); - bus = malloc(sizeof(*bus)); - if (!bus) - USB_ERROR(-ENOMEM); + memset((void *)bus, 0, sizeof(*bus)); - memset((void *)bus, 0, sizeof(*bus)); + snprintf(bus->dirname, sizeof(bus->dirname), "/dev/usb"); - strncpy(bus->dirname, buf, sizeof(bus->dirname) - 1); - bus->dirname[sizeof(bus->dirname) - 1] = 0; + LIST_ADD(fbus, bus); - LIST_ADD(fbus, bus); - - if (usb_debug >= 2) - fprintf(stderr, "usb_os_find_busses: Found %s\n", bus->dirname); - } - *busses = fbus; return 0; @@ -523,43 +498,27 @@ int usb_os_find_busses(struct usb_bus **busses) int usb_os_find_devices(struct usb_bus *bus, struct usb_device **devices) { + struct usb_device *dev; + unsigned char device_desc[DEVICE_DESC_LENGTH]; + char devnode[USB_MAX_DEVNAMELEN]; + char devname[USB_MAX_DEVNAMELEN]; struct usb_device *fdev = NULL; - int cfd, dfd; - int device; + int fd, i; - cfd = open(bus->dirname, O_RDONLY); - if (cfd < 0) - USB_ERROR_STR(-errno, "couldn't open(%s): %s", bus->dirname, - strerror(errno)); + /* USB_MAX_DEVICES is the max # of all devices per bus. this is + * only for ugen(4) devices, but on all buses. is 32 enough? + */ + for (i = 0; i < 32 /* USB_MAX_DEVICES */; i++) { + snprintf(devname, sizeof(devname), "/dev/ugen%d", i); - for (device = 1; device < USB_MAX_DEVICES; device++) { - struct usb_device_info di; - struct usb_device *dev; - unsigned char device_desc[DEVICE_DESC_LENGTH]; - char buf[20]; + /* device control node */ + snprintf(devnode, sizeof(devnode), "%s.00", devname); - di.udi_addr = device; - if (ioctl(cfd, USB_DEVICEINFO, &di) < 0) - continue; - - /* There's a device; is it one we should mess with? */ - - if (strncmp(di.udi_devnames[0], "ugen", 4) != 0) - /* best not to play with things we don't understand */ - continue; - -#ifdef __FreeBSD_kernel__ - snprintf(buf, sizeof(buf) - 1, "/dev/%s", di.udi_devnames[0]); -#else - snprintf(buf, sizeof(buf) - 1, "/dev/%s.00", di.udi_devnames[0]); -#endif - - /* Open its control endpoint */ - dfd = open(buf, O_RDONLY); - if (dfd < 0) { + fd = open(devnode, O_RDONLY); + if (fd < 0) { if (usb_debug >= 2) fprintf(stderr, "usb_os_find_devices: couldn't open device %s: %s\n", - buf, strerror(errno)); + devname, strerror(errno)); continue; } @@ -571,21 +530,13 @@ int usb_os_find_devices(struct usb_bus *bus, struct us dev->bus = bus; - /* we need to report the device name as /dev/ugenx NOT /dev/ugenx.00 - * This seemed easier than having 2 variables... - */ -#if (__NetBSD__ || __OpenBSD__) - snprintf(buf, sizeof(buf) - 1, "/dev/%s", di.udi_devnames[0]); -#endif + strlcpy(dev->filename, devname, sizeof(dev->filename)); - strncpy(dev->filename, buf, sizeof(dev->filename) - 1); - dev->filename[sizeof(dev->filename) - 1] = 0; - - if (ioctl(dfd, USB_GET_DEVICE_DESC, device_desc) < 0) + if (ioctl(fd, USB_GET_DEVICE_DESC, device_desc) < 0) USB_ERROR_STR(-errno, "couldn't get device descriptor for %s: %s", - buf, strerror(errno)); + devname, strerror(errno)); - close(dfd); + close(fd); usb_parse_descriptor(device_desc, "bbwbbbbwwwbbbb", &dev->descriptor); @@ -596,8 +547,6 @@ int usb_os_find_devices(struct usb_bus *bus, struct us dev->filename, bus->dirname); } - close(cfd); - *devices = fdev; return 0; @@ -623,9 +572,21 @@ int usb_resetep(usb_dev_handle *dev, unsigned int ep) int usb_clear_halt(usb_dev_handle *dev, unsigned int ep) { - /* Not yet done, because I haven't needed it. */ + int ret; + struct usb_ctl_request ctl_req; - USB_ERROR_STR(-ENOSYS, "usb_clear_halt called, unimplemented on BSD"); + ctl_req.ucr_addr = 0; // Not used for this type of request + ctl_req.ucr_request.bmRequestType = UT_WRITE_ENDPOINT; + ctl_req.ucr_request.bRequest = UR_CLEAR_FEATURE; + USETW(ctl_req.ucr_request.wValue, UF_ENDPOINT_HALT); + USETW(ctl_req.ucr_request.wIndex, ep); + USETW(ctl_req.ucr_request.wLength, 0); + ctl_req.ucr_flags = 0; + + if ((ret = ioctl(dev->fd, USB_DO_REQUEST, &ctl_req)) < 0) + USB_ERROR_STR(-errno, "clear_halt: failed for %d", ep); + + return ret; } int usb_reset(usb_dev_handle *dev)