⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bsd.c

📁 usb user mode lib
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * (Free|Open|Net)BSD USB support * * Derived from Linux version by Richard Tobin. * * $Id: bsd.c,v 1.28 2003/12/30 01:12:38 jerdfelt Exp $ * $Name:  $ * * This library is covered by the LGPL, read LICENSE for details. *//* * Note: I don't have a clue what I'm doing.  I just looked at the * man pages and source to try and find things that did the same as * the Linux version. -- Richard * * johnjen@reynoldsnet.org - minor fixes with debug mode output. Consistent brace * use as well as indenting. More error messages put in to test for failure * modes with /dev/ permissions (when it happens). Note: I, like Richard, have * no clue what I'm doing. Patches to increase/fix functionality happily * accepted! *//* dirkx@webweaving.org - minor changes to make things actually work * 	for both read and write. */#include <stdlib.h>#include <unistd.h>#include <string.h>#include <stdio.h>#include <fcntl.h>#include <errno.h>#include <assert.h>#include <sys/time.h>#include <sys/ioctl.h>#include <dev/usb/usb.h>#include "usbi.h"#ifdef HAVE_CONFIG_H#include "config.h"#endif#ifdef HAVE_OLD_DEV_USB_USB_H/* * It appears some of the BSD's (OpenBSD atleast) have switched over to a * new naming convention, so we setup some macro's for backward * compability with older versions --jerdfelt *//* struct usb_ctl_request */#define ucr_addr		addr#define ucr_request		request#define ucr_data		data#define ucr_flags		flags#define ucr_actlen		actlen/* struct usb_alt_interface */#define uai_config_index	config_index#define uai_interface_index	interface_index#define uai_alt_no		alt_no/* struct usb_config_desc */#define ucd_config_index	config_index#define ucd_desc		desc/* struct usb_interface_desc */#define uid_config_index	config_index#define uid_interface_index	interface_index#define uid_alt_index		alt_index#define uid_desc		desc/* struct usb_endpoint_desc */#define ued_config_index	config_index#define ued_interface_index	interface_index#define ued_alt_index		alt_index#define ued_endpoint_index	endpoint_index#define ued_desc		desc/* struct usb_full_desc */#define ufd_config_index	config_index#define ufd_size		size#define ufd_data		data/* struct usb_string_desc */#define usd_string_index	string_index#define usd_language_id		language_id#define usd_desc		desc/* struct usb_ctl_report_desc */#define ucrd_size		size#define ucrd_data		data/* struct usb_device_info */#define udi_bus			bus#define udi_addr		addr#define udi_cookie		cookie#define udi_product		product#define udi_vendor		vendor#define udi_release		release#define udi_productNo		productNo#define udi_vendorNo		vendorNo#define udi_releaseNo		releaseNo#define udi_class		class#define udi_subclass		subclass#define udi_protocol		protocol#define udi_config		config#define udi_lowspeed		lowspeed#define udi_power		power#define udi_nports		nports#define udi_devnames		devnames#define udi_ports		ports/* struct usb_ctl_report */#define ucr_report		report#define ucr_data		data/* struct usb_device_stats */#define uds_requests		requests#endifstatic int ensure_ep_open(usb_dev_handle *dev, int ep, int mode);#define MAX_CONTROLLERS 10/* This records the file descriptors for the endpoints.  It doesn't seem   to work to re-open them for each read (as well as being inefficient). */struct bsd_usb_dev_handle_info {    int ep_fd[USB_MAX_ENDPOINTS];};int usb_os_open(usb_dev_handle *dev){  int i;  struct bsd_usb_dev_handle_info *info;  char ctlpath[PATH_MAX + 1];  info = malloc(sizeof(struct bsd_usb_dev_handle_info));  if (!info)    USB_ERROR(-ENOMEM);  dev->impl_info = info;#if __FreeBSD__  snprintf(ctlpath, PATH_MAX, "%s", dev->device->filename);#else  snprintf(ctlpath, PATH_MAX, "%s.00", dev->device->filename);#endif  dev->fd = open(ctlpath, O_RDWR);  if (dev->fd < 0) {    dev->fd = open(ctlpath, O_RDONLY);    if (dev->fd < 0) {      free(info);      USB_ERROR_STR(-errno, "failed to open %s: %s",                    ctlpath, strerror(errno));    }  }  /* Mark the endpoints as not yet open */  for (i = 0; i < USB_MAX_ENDPOINTS; i++)    info->ep_fd[i] = -1;  return 0;}int usb_os_close(usb_dev_handle *dev){  struct bsd_usb_dev_handle_info *info = dev->impl_info;  int i;  /* Close any open endpoints */  for (i = 0; i < USB_MAX_ENDPOINTS; i++)    if (info->ep_fd[i] >= 0) {      if (usb_debug >= 2)        fprintf(stderr, "usb_os_close: closing endpoint %d\n", info->ep_fd[i]);      close(info->ep_fd[i]);    }  free(info);  if (dev->fd <= 0)    return 0;  if (close(dev->fd) == -1)    /* Failing trying to close a file really isn't an error, so return 0 */    USB_ERROR_STR(0, "tried to close device fd %d: %s", dev->fd,                  strerror(errno));  return 0;}int usb_set_configuration(usb_dev_handle *dev, int configuration){  int ret;  ret = ioctl(dev->fd, USB_SET_CONFIG, &configuration);  if (ret < 0)    USB_ERROR_STR(-errno, "could not set config %d: %s", configuration,                  strerror(errno));  dev->config = configuration;  return 0;}int usb_claim_interface(usb_dev_handle *dev, int interface){  /* BSD doesn't have the corresponding ioctl.  It seems to     be sufficient to open the relevant endpoints as needed. */  dev->interface = interface;  return 0;}int usb_release_interface(usb_dev_handle *dev, int interface){  /* See above */  return 0;}int usb_set_altinterface(usb_dev_handle *dev, int alternate){  int ret;  struct usb_alt_interface intf;  if (dev->interface < 0)    USB_ERROR(-EINVAL);  intf.uai_interface_index = dev->interface;  intf.uai_alt_no = alternate;  ret = ioctl(dev->fd, USB_SET_ALTINTERFACE, &intf);  if (ret < 0)    USB_ERROR_STR(-errno, "could not set alt intf %d/%d: %s",                  dev->interface, alternate, strerror(errno));  dev->altsetting = alternate;  return 0;}static int ensure_ep_open(usb_dev_handle *dev, int ep, int mode){  struct bsd_usb_dev_handle_info *info = dev->impl_info;  int fd;  char buf[20];  /* Get the address for this endpoint; we could check   * the mode against the direction; but we've done that   * already in the usb_bulk_read/write.   */  ep = UE_GET_ADDR(ep);  if (info->ep_fd[ep] < 0) {#if __FreeBSD__    snprintf(buf, sizeof(buf) - 1, "%s.%d", dev->device->filename, ep);#else    snprintf(buf, sizeof(buf) - 1, "%s.%02d", dev->device->filename, ep);#endif    /* Try to open it O_RDWR first for those devices which have in and out     * endpoints with the same address (eg 0x02 and 0x82)     */    fd = open(buf, O_RDWR);    if (fd < 0 && errno == ENXIO)      fd = open(buf, mode);    if (fd < 0)      USB_ERROR_STR(-errno, "can't open %s for bulk read: %s",                    buf, strerror(errno));    info->ep_fd[ep] = fd;  }  return info->ep_fd[ep];}int usb_bulk_write(usb_dev_handle *dev, int ep, char *bytes, int size,                   int timeout){  int fd, ret, sent = 0;  /* Ensure the endpoint address is correct */  ep &= ~USB_ENDPOINT_IN;  fd = ensure_ep_open(dev, ep, O_WRONLY);  if (fd < 0) {    if (usb_debug >= 2) {#if __FreeBSD__      fprintf (stderr, "usb_bulk_write: got negative open file descriptor for endpoint %d\n", UE_GET_ADDR(ep));#else      fprintf (stderr, "usb_bulk_write: got negative open file descriptor for endpoint %02d\n", UE_GET_ADDR(ep));#endif    }    return fd;  }  ret = ioctl(fd, USB_SET_TIMEOUT, &timeout);  if (ret < 0)    USB_ERROR_STR(-errno, "error setting timeout: %s",                  strerror(errno));  do {    ret = write(fd, bytes+sent, size-sent);    if (ret < 0)#if __FreeBSD__      USB_ERROR_STR(-errno, "error writing to bulk endpoint %s.%d: %s",                    dev->device->filename, UE_GET_ADDR(ep), strerror(errno));#else      USB_ERROR_STR(-errno, "error writing to bulk endpoint %s.%02d: %s",                  dev->device->filename, UE_GET_ADDR(ep), strerror(errno));#endif    sent += ret;  } while (ret > 0 && sent < size);  return sent;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -