📄 linux.c
字号:
struct usb_device *fdev = NULL; DIR *dir; struct dirent *entry; char dirpath[PATH_MAX + 1]; snprintf(dirpath, PATH_MAX, "%s/%s", usb_path, bus->dirname); dir = opendir(dirpath); if (!dir) USB_ERROR_STR(-errno, "couldn't opendir(%s): %s", dirpath, strerror(errno)); while ((entry = readdir(dir)) != NULL) { unsigned char device_desc[DEVICE_DESC_LENGTH]; char filename[PATH_MAX + 1]; struct usb_device *dev; struct usb_connectinfo connectinfo; int i, fd, ret; /* Skip anything starting with a . */ if (entry->d_name[0] == '.') continue; dev = malloc(sizeof(*dev)); if (!dev) USB_ERROR(-ENOMEM); memset((void *)dev, 0, sizeof(*dev)); dev->bus = bus; strncpy(dev->filename, entry->d_name, sizeof(dev->filename) - 1); dev->filename[sizeof(dev->filename) - 1] = 0; snprintf(filename, sizeof(filename) - 1, "%s/%s", dirpath, entry->d_name); fd = open(filename, O_RDWR); if (fd < 0) { fd = open(filename, O_RDONLY); if (fd < 0) { if (usb_debug >= 2) fprintf(stderr, "usb_os_find_devices: Couldn't open %s\n", filename); free(dev); continue; } } /* Get the device number */ ret = ioctl(fd, IOCTL_USB_CONNECTINFO, &connectinfo); if (ret < 0) { if (usb_debug) fprintf(stderr, "usb_os_find_devices: couldn't get connect info\n"); } else dev->devnum = connectinfo.devnum; ret = read(fd, (void *)device_desc, DEVICE_DESC_LENGTH); if (ret < 0) { if (usb_debug) fprintf(stderr, "usb_os_find_devices: Couldn't read descriptor\n"); free(dev); goto err; } /* * Linux kernel converts the words in this descriptor to CPU endian, so * we use the undocumented W character for usb_parse_descriptor() that * doesn't convert endianess when parsing the descriptor */ usb_parse_descriptor(device_desc, "bbWbbbbWWWbbbb", &dev->descriptor); LIST_ADD(fdev, dev); if (usb_debug >= 2) fprintf(stderr, "usb_os_find_devices: Found %s on %s\n", dev->filename, bus->dirname); /* Now try to fetch the rest of the descriptors */ if (dev->descriptor.bNumConfigurations > USB_MAXCONFIG) /* Silent since we'll try again later */ goto err; if (dev->descriptor.bNumConfigurations < 1) /* Silent since we'll try again later */ goto err; dev->config = (struct usb_config_descriptor *)malloc(dev->descriptor.bNumConfigurations * sizeof(struct usb_config_descriptor)); if (!dev->config) /* Silent since we'll try again later */ goto err; memset(dev->config, 0, dev->descriptor.bNumConfigurations * sizeof(struct usb_config_descriptor)); for (i = 0; i < dev->descriptor.bNumConfigurations; i++) { unsigned char buffer[8], *bigbuffer; struct usb_config_descriptor config; /* Get the first 8 bytes so we can figure out what the total length is */ ret = read(fd, (void *)buffer, 8); if (ret < 8) { if (usb_debug >= 1) { if (ret < 0) fprintf(stderr, "Unable to get descriptor (%d)\n", ret); else fprintf(stderr, "Config descriptor too short (expected %d, got %d)\n", 8, ret); } goto err; } usb_parse_descriptor(buffer, "bbw", &config); bigbuffer = malloc(config.wTotalLength); if (!bigbuffer) { if (usb_debug >= 1) fprintf(stderr, "Unable to allocate memory for descriptors\n"); goto err; } /* Read the rest of the config descriptor */ memcpy(bigbuffer, buffer, 8); ret = read(fd, (void *)(bigbuffer + 8), config.wTotalLength - 8); if (ret < config.wTotalLength - 8) { if (usb_debug >= 1) { if (ret < 0) fprintf(stderr, "Unable to get descriptor (%d)\n", ret); else fprintf(stderr, "Config descriptor too short (expected %d, got %d)\n", config.wTotalLength, ret); } free(bigbuffer); goto err; } ret = usb_parse_configuration(&dev->config[i], bigbuffer); if (usb_debug >= 2) { if (ret > 0) fprintf(stderr, "Descriptor data still left\n"); else if (ret < 0) fprintf(stderr, "Unable to parse descriptors\n"); } free(bigbuffer); }err: close(fd); } closedir(dir); *devices = fdev; return 0;}int usb_os_determine_children(struct usb_bus *bus){ struct usb_device *dev, *devices[256]; struct usb_ioctl command; int ret, i, i1; /* Create a list of devices first */ memset(devices, 0, sizeof(devices)); for (dev = bus->devices; dev; dev = dev->next) if (dev->devnum) devices[dev->devnum] = dev; /* Now fetch the children for each device */ for (dev = bus->devices; dev; dev = dev->next) { struct usb_hub_portinfo portinfo; int fd; fd = device_open(dev); if (fd < 0) continue; /* Query the hub driver for the children of this device */ if (dev->config && dev->config->interface && dev->config->interface->altsetting) command.ifno = dev->config->interface->altsetting->bInterfaceNumber; else command.ifno = 0; command.ioctl_code = IOCTL_USB_HUB_PORTINFO; command.data = &portinfo; ret = ioctl(fd, IOCTL_USB_IOCTL, &command); if (ret < 0) { /* errno == ENOSYS means the device probably wasn't a hub */ if (errno != ENOSYS && usb_debug > 1) fprintf(stderr, "error obtaining child information: %s\n", strerror(errno)); close(fd); continue; } dev->num_children = 0; for (i = 0; i < portinfo.numports; i++) if (portinfo.port[i]) dev->num_children++; /* Free any old children first */ free(dev->children); dev->children = malloc(sizeof(struct usb_device *) * dev->num_children); if (!dev->children) { if (usb_debug > 1) fprintf(stderr, "error allocating %zu bytes memory for dev->children\n", sizeof(struct usb_device *) * dev->num_children); dev->num_children = 0; close(fd); continue; } for (i = 0, i1 = 0; i < portinfo.numports; i++) { if (!portinfo.port[i]) continue; dev->children[i1++] = devices[portinfo.port[i]]; devices[portinfo.port[i]] = NULL; } close(fd); } /* * There should be one device left in the devices list and that should be * the root device */ for (i = 0; i < sizeof(devices) / sizeof(devices[0]); i++) { if (devices[i]) bus->root_dev = devices[i]; } return 0;}static int check_usb_vfs(const char *dirname){ DIR *dir; struct dirent *entry; int found = 0; dir = opendir(dirname); if (!dir) return 0; while ((entry = readdir(dir)) != NULL) { /* Skip anything starting with a . */ if (entry->d_name[0] == '.') continue; /* We assume if we find any files that it must be the right place */ found = 1; break; } closedir(dir); return found;}void usb_os_init(void){ /* Find the path to the virtual filesystem */ if (getenv("USB_DEVFS_PATH")) { if (check_usb_vfs(getenv("USB_DEVFS_PATH"))) { strncpy(usb_path, getenv("USB_DEVFS_PATH"), sizeof(usb_path) - 1); usb_path[sizeof(usb_path) - 1] = 0; } else if (usb_debug) fprintf(stderr, "usb_os_init: couldn't find USB VFS in USB_DEVFS_PATH\n"); } if (!usb_path[0]) { if (check_usb_vfs("/dev/bus/usb")) { strncpy(usb_path, "/dev/bus/usb", sizeof(usb_path) - 1); usb_path[sizeof(usb_path) - 1] = 0; } else if (check_usb_vfs("/proc/bus/usb")) { strncpy(usb_path, "/proc/bus/usb", sizeof(usb_path) - 1); usb_path[sizeof(usb_path) - 1] = 0; } else usb_path[0] = 0; /* No path, no USB support */ } if (usb_debug) { if (usb_path[0]) fprintf(stderr, "usb_os_init: Found USB VFS at %s\n", usb_path); else fprintf(stderr, "usb_os_init: No USB VFS found, is it mounted?\n"); }}int usb_resetep(usb_dev_handle *dev, unsigned int ep){ int ret; ret = ioctl(dev->fd, IOCTL_USB_RESETEP, &ep); if (ret) USB_ERROR_STR(-errno, "could not reset ep %d: %s", ep, strerror(errno)); return 0;}int usb_clear_halt(usb_dev_handle *dev, unsigned int ep){ int ret; ret = ioctl(dev->fd, IOCTL_USB_CLEAR_HALT, &ep); if (ret) USB_ERROR_STR(-errno, "could not clear/halt ep %d: %s", ep, strerror(errno)); return 0;}int usb_reset(usb_dev_handle *dev){ int ret; ret = ioctl(dev->fd, IOCTL_USB_RESET, NULL); if (ret) USB_ERROR_STR(-errno, "could not reset: %s", strerror(errno)); return 0;}int usb_get_driver_np(usb_dev_handle *dev, int interface, char *name, unsigned int namelen){ struct usb_getdriver getdrv; int ret; getdrv.interface = interface; ret = ioctl(dev->fd, IOCTL_USB_GETDRIVER, &getdrv); if (ret) USB_ERROR_STR(-errno, "could not get bound driver: %s", strerror(errno)); strncpy(name, getdrv.driver, namelen - 1); name[namelen - 1] = 0; return 0;}int usb_detach_kernel_driver_np(usb_dev_handle *dev, int interface){ struct usb_ioctl command; int ret; command.ifno = interface; command.ioctl_code = IOCTL_USB_DISCONNECT; command.data = NULL; ret = ioctl(dev->fd, IOCTL_USB_IOCTL, &command); if (ret) USB_ERROR_STR(-errno, "could not detach kernel driver from interface %d: %s", interface, strerror(errno)); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -