static int gpio_proc_show(struct seq_file *m, void *v) { static const char port_name[]="123456789ABCDEFGH"; int c; for (c = 0; c < MAX_PORT; c++) { if (ddrs[c] == NULL) continue; seq_printf(m, "P%c: %s\n", port_name[c], port_status(c)); } return 0; }
static int gpio_proc_read(char *buf, char **start, off_t offset, int len, int *unused_i, void *unused_v) { int c,outlen; static const char port_name[]="123456789ABCDEFGH"; outlen = 0; for (c = 0; c < MAX_PORT; c++) { if (ddrs[c] == NULL) continue ; len = sprintf(buf,"P%c: %s\n",port_name[c],port_status(c)); buf += len; outlen += len; } return outlen; }
int main(int argc, char **argv) { int busnum, devnum, numports; enum {DO_POWER, DO_STATUS, DO_BIND} action; char fname1[40], fname2[40]; int rc; int portnum; struct usb_device_descriptor dev_descr; struct usb_hub_descriptor hub_descr; struct usbdevfs_ctrltransfer ctrl; struct usbdevfs_ioctl usb_ioctl; int bus_endian; if (argc < 3) usage(); if (sscanf(argv[1], "%d:%d", &busnum, &devnum) != 2 || busnum <= 0 || busnum > 255 || devnum <= 0 || devnum > 255) usage(); if (strcmp(argv[2], "power") == 0) { action = DO_POWER; if ((argc - 3) % 2 != 0) usage(); } else if (strcmp(argv[2], "status") == 0) { action = DO_STATUS; if (argc != 3) usage(); } else if (strcmp(argv[2], "bind") == 0) { action = DO_BIND; if (argc != 3) usage(); } else { usage(); } sprintf(fname1, "/dev/bus/usb/%03d/%03d", busnum, devnum); sprintf(fname2, "/proc/bus/usb/%03d/%03d", busnum, devnum); bus_endian = 1; fd = open(fname1, O_RDWR); if (fd < 0) { int err1 = errno; bus_endian = 0; fd = open(fname2, O_RDWR); if (fd < 0) { fprintf(stderr, "Unable to open device file %s: %s\n", fname1, strerror(err1)); fprintf(stderr, "Unable to open device file %s: %s\n", fname2, strerror(errno)); return 1; } } rc = read(fd, &dev_descr, USB_DT_DEVICE_SIZE); if (rc != USB_DT_DEVICE_SIZE) { perror("Error reading device descriptor"); return 1; } if (dev_descr.bDeviceClass != USB_CLASS_HUB) { fprintf(stderr, "Device %d:%d is not a hub\n", busnum, devnum); return 1; } if (bus_endian) { dev_descr.bcdUSB = __le16_to_cpu(dev_descr.bcdUSB); } usb_level = dev_descr.bcdUSB >> 8; ctrl.bRequestType = USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_DEVICE; ctrl.bRequest = USB_REQ_GET_DESCRIPTOR; ctrl.wValue = USB_DT_HUB << 8; ctrl.wIndex = 0; ctrl.wLength = USB_DT_HUB_SIZE; ctrl.timeout = USB_HUB_TIMEOUT; ctrl.data = &hub_descr; rc = ioctl(fd, USBDEVFS_CONTROL, &ctrl); if (rc == -1) { perror("Error in ioctl (read hub descriptor)"); return 1; } numports = hub_descr.bNbrPorts; if (action == DO_STATUS) { for (portnum = 1; portnum <= numports; ++portnum) port_status(portnum); return 0; } if (action == DO_BIND) { usb_ioctl.ifno = 0; usb_ioctl.ioctl_code = USBDEVFS_CONNECT; usb_ioctl.data = NULL; rc = ioctl(fd, USBDEVFS_IOCTL, &usb_ioctl); if (rc == -1) { perror("Error in ioctl (USBDEVFS_CONNECT)"); return 1; } printf("Bind-driver request sent to the kernel\n"); return 0; } if (action == DO_POWER) { int i; int power_on = 1; usb_ioctl.ifno = 0; usb_ioctl.ioctl_code = USBDEVFS_DISCONNECT; usb_ioctl.data = NULL; rc = ioctl(fd, USBDEVFS_IOCTL, &usb_ioctl); if (rc == -1 && errno != ENODATA) { perror("Error in ioctl (USBDEVFS_DISCONNECT)"); return 1; } for (i = 3; i < argc; i += 2) { portnum = atoi(argv[i]); if (portnum < 1 || portnum > numports) { fprintf(stderr, "Invalid port number: %d\n", portnum); continue; } if (strcmp(argv[i+1], "on") == 0) toggle_power(ctrl, portnum, 1); else if (strcmp(argv[i+1], "off") == 0) toggle_power(ctrl, portnum, 0); else if (strcmp(argv[i+1], "loop") == 0) while(1) { toggle_power(ctrl, portnum, power_on); power_on = ! power_on; sleep(1); } else { fprintf(stderr, "Invalid port power level: %s\n)", argv[i+1]); continue; } port_status(portnum); } } return 0; }