static void handle_control (int fd, struct usb_ctrlrequest *setup) { int status, tmp; __u8 buf [256]; __u16 value, index, length; value = __le16_to_cpu(setup->wValue); index = __le16_to_cpu(setup->wIndex); length = __le16_to_cpu(setup->wLength); if (verbose) fprintf (stderr, "SETUP %02x.%02x " "v%04x i%04x %d\n", setup->bRequestType, setup->bRequest, value, index, length); /* if ((setup->bRequestType & USB_TYPE_MASK) != USB_TYPE_STANDARD) goto special; */ switch (setup->bRequest) { /* usb 2.0 spec ch9 requests */ case USB_REQ_GET_DESCRIPTOR: if (setup->bRequestType != USB_DIR_IN) goto stall; switch (value >> 8) { case USB_DT_STRING: tmp = value & 0x0ff; if (verbose > 1) fprintf (stderr, "... get string %d lang %04x\n", tmp, index); if (tmp != 0 && index != strings.language) goto stall; status = usb_gadget_get_string (&strings, tmp, buf); if (status < 0) goto stall; tmp = status; if (length < tmp) tmp = length; status = write (fd, buf, tmp); if (status < 0) { if (errno == EIDRM) fprintf (stderr, "string timeout\n"); else perror ("write string data"); } else if (status != tmp) { fprintf (stderr, "short string write, %d\n", status); } break; default: goto stall; } return; case USB_REQ_SET_CONFIGURATION: if (setup->bRequestType != USB_DIR_OUT) goto stall; if (verbose) fprintf (stderr, "CONFIG #%d\n", value); /* Kernel is normally waiting for us to finish reconfiguring * the device. * * Some hardware can't, notably older PXA2xx hardware. (With * racey and restrictive config change automagic. PXA 255 is * OK, most PXA 250s aren't. If it has a UDC CFR register, * it can handle deferred response for SET_CONFIG.) To handle * such hardware, don't write code this way ... instead, keep * the endpoints always active and don't rely on seeing any * config change events, either this or SET_INTERFACE. */ switch (value) { case CONFIG_VALUE: start_io (); break; case 0: stop_io (); break; default: /* kernel bug -- "can't happen" */ fprintf (stderr, "? illegal config\n"); goto stall; } /* ... ack (a write would stall) */ status = read (fd, &status, 0); if (status) perror ("ack SET_CONFIGURATION"); return; case USB_REQ_GET_INTERFACE: if (setup->bRequestType != (USB_DIR_IN|USB_RECIP_INTERFACE) || index != 0 || length > 1) goto stall; /* only one altsetting in this driver */ buf [0] = 0; status = write (fd, buf, length); if (status < 0) { if (errno == EIDRM) fprintf (stderr, "GET_INTERFACE timeout\n"); else perror ("write GET_INTERFACE data"); } else if (status != length) { fprintf (stderr, "short GET_INTERFACE write, %d\n", status); } return; case USB_REQ_SET_INTERFACE: if (setup->bRequestType != USB_RECIP_INTERFACE || index != 0 || value != 0) goto stall; /* just reset toggle/halt for the interface's endpoints */ status = 0; if (ioctl (source_fd, GADGETFS_CLEAR_HALT) < 0) { status = errno; perror ("reset source fd"); } if (ioctl (sink_fd, GADGETFS_CLEAR_HALT) < 0) { status = errno; perror ("reset sink fd"); } /* FIXME eventually reset the status endpoint too */ if (status) goto stall; /* ... and ack (a write would stall) */ status = read (fd, &status, 0); if (status) perror ("ack SET_INTERFACE"); return; default: goto stall; } stall: if (verbose) fprintf (stderr, "... protocol stall %02x.%02x\n", setup->bRequestType, setup->bRequest); /* non-iso endpoints are stalled by issuing an i/o request * in the "wrong" direction. ep0 is special only because * the direction isn't fixed. */ if (setup->bRequestType & USB_DIR_IN) status = read (fd, &status, 0); else status = write (fd, &status, 0); if (status != -1) fprintf (stderr, "can't stall ep0 for %02x.%02x\n", setup->bRequestType, setup->bRequest); else if (errno != EL2HLT) perror ("ep0 stall"); }
/* * The setup() callback implements all the ep0 functionality that's * not handled lower down, in hardware or the hardware driver (like * device and endpoint feature flags, and their status). It's all * housekeeping for the gadget function we're implementing. Most of * the work is in config-specific setup. */ static int zero_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) { struct zero_dev *dev = get_gadget_data(gadget); struct usb_request *req = dev->req; int value = -EOPNOTSUPP; u16 w_index = le16_to_cpu(ctrl->wIndex); u16 w_value = le16_to_cpu(ctrl->wValue); u16 w_length = le16_to_cpu(ctrl->wLength); /* usually this stores reply data in the pre-allocated ep0 buffer, * but config change events will reconfigure hardware. */ req->zero = 0; switch (ctrl->bRequest) { case USB_REQ_GET_DESCRIPTOR: if (ctrl->bRequestType != USB_DIR_IN) goto unknown; switch (w_value >> 8) { case USB_DT_DEVICE: value = min(w_length, (u16) sizeof device_desc); memcpy(req->buf, &device_desc, value); break; case USB_DT_DEVICE_QUALIFIER: if (!gadget_is_dualspeed(gadget)) break; value = min(w_length, (u16) sizeof dev_qualifier); memcpy(req->buf, &dev_qualifier, value); break; case USB_DT_OTHER_SPEED_CONFIG: if (!gadget_is_dualspeed(gadget)) break; // FALLTHROUGH case USB_DT_CONFIG: value = config_buf(gadget, req->buf, w_value >> 8, w_value & 0xff); if (value >= 0) value = min(w_length, (u16) value); break; case USB_DT_STRING: /* wIndex == language code. * this driver only handles one language, you can * add string tables for other languages, using * any UTF-8 characters */ value = usb_gadget_get_string(&stringtab, w_value & 0xff, req->buf); if (value >= 0) value = min(w_length, (u16) value); break; } break; /* currently two configs, two speeds */ case USB_REQ_SET_CONFIGURATION: if (ctrl->bRequestType != 0) goto unknown; if (gadget->a_hnp_support) DBG(dev, "HNP available\n"); else if (gadget->a_alt_hnp_support) DBG(dev, "HNP needs a different root port\n"); else VDBG(dev, "HNP inactive\n"); spin_lock(&dev->lock); value = zero_set_config(dev, w_value); spin_unlock(&dev->lock); break; case USB_REQ_GET_CONFIGURATION: if (ctrl->bRequestType != USB_DIR_IN) goto unknown; *(u8 *)req->buf = dev->config; value = min(w_length, (u16) 1); break; /* until we add altsetting support, or other interfaces, * only 0/0 are possible. pxa2xx only supports 0/0 (poorly) * and already killed pending endpoint I/O. */ case USB_REQ_SET_INTERFACE: if (ctrl->bRequestType != USB_RECIP_INTERFACE) goto unknown; spin_lock(&dev->lock); if (dev->config && w_index == 0 && w_value == 0) { u8 config = dev->config; /* resets interface configuration, forgets about * previous transaction state (queued bufs, etc) * and re-inits endpoint state (toggle etc) * no response queued, just zero status == success. * if we had more than one interface we couldn't * use this "reset the config" shortcut. */ zero_reset_config(dev); zero_set_config(dev, config); value = 0; } spin_unlock(&dev->lock); break; case USB_REQ_GET_INTERFACE: if (ctrl->bRequestType != (USB_DIR_IN|USB_RECIP_INTERFACE)) goto unknown; if (!dev->config) break; if (w_index != 0) { value = -EDOM; break; } *(u8 *)req->buf = 0; value = min(w_length, (u16) 1); break; /* * These are the same vendor-specific requests supported by * Intel's USB 2.0 compliance test devices. We exceed that * device spec by allowing multiple-packet requests. */ case 0x5b: /* control WRITE test -- fill the buffer */ if (ctrl->bRequestType != (USB_DIR_OUT|USB_TYPE_VENDOR)) goto unknown; if (w_value || w_index) break; /* just read that many bytes into the buffer */ if (w_length > USB_BUFSIZ) break; value = w_length; break; case 0x5c: /* control READ test -- return the buffer */ if (ctrl->bRequestType != (USB_DIR_IN|USB_TYPE_VENDOR)) goto unknown; if (w_value || w_index) break; /* expect those bytes are still in the buffer; send back */ if (w_length > USB_BUFSIZ || w_length != req->length) break; value = w_length; break; default: unknown: VDBG(dev, "unknown control req%02x.%02x v%04x i%04x l%d\n", ctrl->bRequestType, ctrl->bRequest, w_value, w_index, w_length); } /* respond with data transfer before status phase? */ if (value >= 0) { req->length = value; req->zero = value < w_length; value = usb_ep_queue(gadget->ep0, req, GFP_ATOMIC); if (value < 0) { DBG(dev, "ep_queue --> %d\n", value); req->status = 0; zero_setup_complete(gadget->ep0, req); } } /* device either stalls (value < 0) or reports success */ return value; }
/* * The setup() callback implements all the ep0 functionality that's not * handled lower down. CDC has a number of less-common features: * * - two interfaces: control, and ethernet data * - Ethernet data interface has two altsettings: default, and active * - class-specific descriptors for the control interface * - class-specific control requests */ static int fastboot_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) { struct fastboot_dev *dev = get_gadget_data(gadget); struct usb_request *req = dev->req; int value = -EOPNOTSUPP; u16 wIndex = le16_to_cpu(ctrl->wIndex); u16 wValue = le16_to_cpu(ctrl->wValue); u16 wLength = le16_to_cpu(ctrl->wLength); /* * descriptors just go into the pre-allocated ep0 buffer, * while config change events may enable network traffic. */ debug("%s\n", __func__); req->complete = fastboot_setup_complete; switch (ctrl->bRequest) { case USB_REQ_GET_DESCRIPTOR: if (ctrl->bRequestType != USB_DIR_IN) break; switch (wValue >> 8) { case USB_DT_DEVICE: value = min(wLength, (u16) sizeof device_desc); memcpy(req->buf, &device_desc, value); break; case USB_DT_DEVICE_QUALIFIER: if (!gadget_is_dualspeed(gadget)) break; value = min(wLength, (u16) sizeof dev_qualifier); memcpy(req->buf, &dev_qualifier, value); break; case USB_DT_OTHER_SPEED_CONFIG: if (!gadget_is_dualspeed(gadget)) break; /* FALLTHROUGH */ case USB_DT_CONFIG: value = config_buf(gadget, req->buf, wValue >> 8, wValue & 0xff, gadget_is_otg(gadget)); if (value >= 0) value = min(wLength, (u16) value); break; case USB_DT_STRING: value = usb_gadget_get_string(&stringtab, wValue & 0xff, req->buf); if (value >= 0) value = min(wLength, (u16) value); break; } break; case USB_REQ_SET_CONFIGURATION: if (ctrl->bRequestType != 0) break; value = fastboot_set_config(dev, wValue, GFP_ATOMIC); l_fbdev.network_started = 1; break; case USB_REQ_GET_CONFIGURATION: if (ctrl->bRequestType != USB_DIR_IN) break; *(u8 *) req->buf = dev->config; value = min(wLength, (u16) 1); break; case USB_REQ_SET_INTERFACE: if (ctrl->bRequestType != USB_RECIP_INTERFACE || !dev->config || wIndex > 1) break; /* * FIXME this is wrong, as is the assumption that * all non-PXA hardware talks real CDC ... */ debug("set_interface ignored!\n"); done_set_intf: break; case USB_REQ_GET_INTERFACE: if (ctrl->bRequestType != (USB_DIR_IN | USB_RECIP_INTERFACE) || !dev->config || wIndex > 1) break; /* for CDC, iff carrier is on, data interface is active. */ if (wIndex != 1) *(u8 *) req->buf = 0; else { /* *(u8 *)req->buf = netif_carrier_ok (dev->net) ? 1 : 0; */ /* carrier always ok ... */ *(u8 *) req->buf = 1; } value = min(wLength, (u16) 1); break; default: debug("unknown control req%02x.%02x v%04x i%04x l%d\n", ctrl->bRequestType, ctrl->bRequest, wValue, wIndex, wLength); } /* respond with data transfer before status phase? */ if (value >= 0) { debug("respond with data transfer before status phase\n"); req->length = value; req->zero = value < wLength && (value % gadget->ep0->maxpacket) == 0; value = usb_ep_queue(gadget->ep0, req, GFP_ATOMIC); if (value < 0) { debug("ep_queue --> %d\n", value); req->status = 0; fastboot_setup_complete(gadget->ep0, req); } } /* host either stalls (value < 0) or reports success */ return value; }