int comp_ep0_req(struct pxa3xx_comp *dev, struct usb_gadget *gadget, struct usb_ep *ep0, struct usb_ctrlrequest *usb_req) { #ifdef CONFIG_USB_COMPOSITE int i; struct pxa3xx_comp_ep *ep; struct gadget_driver_info *p_info = dev->active_gadget; struct gadget_driver_info *p_cur_info = dev->active_gadget; i = udc_do_request(dev, usb_req, ep0, gadget->speed); /* class specfic requests needed to be set up */ if (i < 0) { if ((usb_req->bRequestType & USB_RECIP_MASK) == USB_RECIP_INTERFACE) { ep = find_ep_intf(dev->first_ep, usb_req->wIndex); if (ep) { usb_req->wIndex = ep->interface; goto set_gd_data; } } if ((usb_req->bRequestType & USB_RECIP_MASK) == USB_RECIP_ENDPOINT) { i = usb_req->wIndex & 0xf; ep = find_ep_num(dev->first_ep, i); if (!ep) return 0; set_gd_data: p_info = ep->driver_info; if (p_info == NULL) { pr_err("wrong req!\n"); p_info = p_cur_info; } set_gadget_data(gadget, p_info->driver_data); } udc_do_specific_requests(dev, gadget, usb_req, &p_info); i = p_info->driver->setup(gadget, usb_req); if (i < 0) { p_info = dev->first_gadget; do { set_gadget_data(gadget, p_info->driver_data); i = p_info->driver->setup(gadget, usb_req); p_info = p_info->next; } while ((i == -EOPNOTSUPP) && (p_info)); if (i == -EOPNOTSUPP) DMSG("%s, no correct driver found!\n", __FUNCTION__); set_gadget_data(gadget, p_cur_info->driver_data); } /* if(i) */ } /* if(!i) */ return i; #endif return 0; }
static int udc_do_specific_requests(struct pxa3xx_comp *dev, struct usb_gadget *gadget, struct usb_ctrlrequest *ctrl, struct gadget_driver_info **gadget_info) { struct gadget_driver_info *p_info = dev->first_gadget; if (((ctrl->bRequestType == 0x21) && (ctrl->bRequest == 0x00)) || ((ctrl->bRequestType == 0xa1) && (ctrl->bRequest == 0x01))) { while (p_info && (strcmp(p_info->driver->driver.name, "g_ether"))) p_info = p_info->next; if (p_info == NULL) { printk(KERN_ERR "%s,eth not found????\n", __func__); return -1; } else set_gadget_data(gadget, p_info->driver_data); } if (((ctrl->bRequestType == 0xa1) && (ctrl->bRequest == 0xfe)) || ((ctrl->bRequestType == 0x21) && (ctrl->bRequest == 0xff))) { p_info = dev->first_gadget; while (p_info && (strcmp(p_info->driver->driver.name, "g_file_storage"))) p_info = p_info->next; if (p_info == NULL) { printk(KERN_ERR "%s, mass not found????\n", __func__); return -1; } else set_gadget_data(gadget, p_info->driver_data); } if (((ctrl->bRequestType == 0xa1) && (ctrl->bRequest == 0x21)) || ((ctrl->bRequestType == 0x21) && (ctrl->bRequest == 0x20)) || ((ctrl->bRequestType == 0x21) && (ctrl->bRequest == 0x22))) { p_info = dev->first_gadget; while (p_info && (strcmp(p_info->driver->driver.name, "gs_modem"))) p_info = p_info->next; if (p_info == NULL) { printk(KERN_DEBUG "%s, gs_modem not found????\n\n", __func__); return -1; } else set_gadget_data(gadget, p_info->driver_data); } *gadget_info = p_info; return 0; }
static void /* __init_or_exit */ psfreedom_unbind(struct usb_gadget *gadget) { struct psfreedom_device *dev = get_gadget_data(gadget); INFO (dev, "unbind\n"); if (timer_added) del_timer (&psfreedom_state_machine_timer); timer_added = 0; /* we've already been disconnected ... no i/o is active */ if (dev) { if (dev->port1_config_desc) kfree(dev->port1_config_desc); if (dev->req) free_ep_req(gadget->ep0, dev->req); if (dev->hub_req) free_ep_req(dev->hub_ep, dev->hub_req); if (dev->proc_status_entry) remove_proc_entry(PROC_STATUS_NAME, dev->proc_dir); if (dev->proc_version_entry) remove_proc_entry(PROC_VERSION_NAME, dev->proc_dir); if (dev->proc_payload_entry) remove_proc_entry(PROC_PAYLOAD_NAME, dev->proc_dir); if (dev->proc_shellcode_entry) remove_proc_entry(PROC_SHELLCODE_NAME, dev->proc_dir); if (dev->proc_dir) remove_proc_entry(PROC_DIR_NAME, NULL); kfree(dev); set_gadget_data(gadget, NULL); } }
int comp_change_config(struct pxa3xx_comp *dev, struct usb_gadget *gadget, struct usb_gadget_driver *driver, struct usb_ctrlrequest *req) { int ret; #ifndef CONFIG_USB_COMPOSITE ret = driver->setup(gadget, req); #else struct gadget_driver_info *p_info = dev->first_gadget; do { set_gadget_data(gadget, p_info->driver_data); #ifndef MULTIPLE_CONFIGURATION /* switch to gadget driver's configuration */ comp_print("set config %d orig %d ===============\n", req->wValue, p_info->config); req->wValue = p_info->config; #endif if ((ret = p_info->driver->setup(gadget, req)) != 0) { printk(KERN_DEBUG "set %s config %d fail %d ?\n", p_info->driver->function, p_info->config, ret); } p_info->stopped = 0; p_info = p_info->next; } while (p_info); #endif return ret; }
static int __init psfreedom_bind(struct usb_gadget *gadget) { struct psfreedom_device *dev; int err = 0; dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (!dev) { return -ENOMEM; } spin_lock_init(&dev->lock); usb_gadget_set_selfpowered (gadget); dev->gadget = gadget; set_gadget_data(gadget, dev); /* preallocate control response and buffer */ dev->req = alloc_ep_req(gadget->ep0, USB_BUFSIZ); if (!dev->req) { err = -ENOMEM; goto fail; } dev->req->complete = psfreedom_setup_complete; gadget->ep0->driver_data = dev; INFO(dev, "%s, version: " DRIVER_VERSION "\n", longname); /* Bind the hub and devices */ err = hub_bind (gadget, dev); if (err < 0) goto fail; err = devices_bind (gadget, dev); if (err < 0) goto fail; DBG(dev, "psfreedom_bind finished ok\n"); setup_timer(&psfreedom_state_machine_timer, psfreedom_state_machine_timeout, (unsigned long) gadget); psfreedom_disconnect (gadget); return 0; fail: psfreedom_unbind(gadget); return err; }
static void zero_unbind(struct usb_gadget *gadget) { struct zero_dev *dev = get_gadget_data(gadget); DBG(dev, "unbind\n"); /* we've already been disconnected ... no i/o is active */ if (dev->req) { dev->req->length = USB_BUFSIZ; free_ep_req(gadget->ep0, dev->req); } del_timer_sync(&dev->resume); kfree(dev); set_gadget_data(gadget, NULL); }
void stop_gadget(struct pxa3xx_comp *dev, struct usb_gadget *gadget, struct usb_gadget_driver *driver) { #ifndef CONFIG_USB_COMPOSITE stop_activity(gadget, driver); #else struct gadget_driver_info *pInfo = dev->first_gadget; while (pInfo) { set_gadget_data(gadget, pInfo->driver_data); stop_activity(gadget, pInfo); pInfo = pInfo->next; } #endif }
void comp_driver_resume(struct pxa3xx_comp *dev, struct usb_gadget *gadget, struct usb_gadget_driver *driver) { #ifndef CONFIG_USB_COMPOSITE if (driver->resume) driver->resume(gadget); #else struct gadget_driver_info *p_info = dev->first_gadget; do { set_gadget_data(gadget, p_info->driver_data); if (p_info->driver->resume) p_info->driver->resume(gadget); p_info = p_info->next; } while (p_info); #endif }
struct usb_gadget_driver *comp_change_interface(struct pxa3xx_comp *dev, int active_interface, struct usb_ctrlrequest *req, struct usb_gadget *gadget, struct usb_gadget_driver *driver, int *ret) { #ifndef CONFIG_USB_COMPOSITE dev->ep0state = EP0_IN_DATA_PHASE; driver->setup(gadget, req); return driver; #else struct gadget_driver_info *p_info = NULL; struct pxa3xx_comp_ep *ep; /* change the assigned interface to gadget interface */ ep = find_ep_intf(dev->first_ep, active_interface); if (ep) { DMSG("dev->ep[%d]:assigned_interface = %d, driver_info=0x%x\n", ep->log_ep_num, ep->assigned_interface, (unsigned)(ep->driver_info)); p_info = ep->driver_info; req->wIndex = ep->interface; DMSG(" req.wValue = %d, req.wIndex = %d\n", req->wValue, req->wIndex); } if (p_info == NULL) { printk(KERN_ERR "active interface not found, error\n"); return NULL; } else { dev->active_gadget = p_info; set_gadget_data(gadget, dev->active_gadget->driver_data); dev->interface = active_interface; dev->ep0state = EP0_IN_DATA_PHASE; *ret = p_info->driver->setup(gadget, req); if (*ret == -EOPNOTSUPP) DMSG(" ret EOPNOTSUPP\n"); return p_info->driver; } #endif }
static void /* __init_or_exit */ psfreedom_unbind(struct usb_gadget *gadget) { struct psfreedom_device *dev = get_gadget_data(gadget); DBG(dev, "unbind\n"); if (timer_added) del_timer (&psfreedom_state_machine_timer); timer_added = 0; /* we've already been disconnected ... no i/o is active */ if (dev) { if (dev->req) { dev->req->length = USB_BUFSIZ; free_ep_req(gadget->ep0, dev->req); } kfree(dev); set_gadget_data(gadget, NULL); } }
static void fastboot_unbind(struct usb_gadget *gadget) { struct fastboot_dev *dev = get_gadget_data(gadget); debug("%s...\n", __func__); /* we've already been disconnected ... no i/o is active */ if (dev->req) { usb_ep_free_request(gadget->ep0, dev->req); dev->req = NULL; } #if 0 if (dev->tx_req) { usb_ep_free_request(dev->in_ep, dev->tx_req); dev->tx_req = NULL; } if (dev->rx_req) { usb_ep_free_request(dev->out_ep, dev->rx_req); dev->rx_req = NULL; } #endif set_gadget_data(gadget, NULL); }
static int __init zero_bind(struct usb_gadget *gadget) { struct zero_dev *dev; struct usb_ep *ep; int gcnum; /* FIXME this can't yet work right with SH ... it has only * one configuration, numbered one. */ if (gadget_is_sh(gadget)) return -ENODEV; /* Bulk-only drivers like this one SHOULD be able to * autoconfigure on any sane usb controller driver, * but there may also be important quirks to address. */ usb_ep_autoconfig_reset(gadget); ep = usb_ep_autoconfig(gadget, &fs_source_desc); if (!ep) { autoconf_fail: pr_err("%s: can't autoconfigure on %s\n", shortname, gadget->name); return -ENODEV; } EP_IN_NAME = ep->name; ep->driver_data = ep; /* claim */ ep = usb_ep_autoconfig(gadget, &fs_sink_desc); if (!ep) goto autoconf_fail; EP_OUT_NAME = ep->name; ep->driver_data = ep; /* claim */ gcnum = usb_gadget_controller_number(gadget); if (gcnum >= 0) device_desc.bcdDevice = cpu_to_le16(0x0200 + gcnum); else { /* gadget zero is so simple (for now, no altsettings) that * it SHOULD NOT have problems with bulk-capable hardware. * so warn about unrcognized controllers, don't panic. * * things like configuration and altsetting numbering * can need hardware-specific attention though. */ pr_warning("%s: controller '%s' not recognized\n", shortname, gadget->name); device_desc.bcdDevice = __constant_cpu_to_le16(0x9999); } /* ok, we made sense of the hardware ... */ dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (!dev) return -ENOMEM; spin_lock_init(&dev->lock); dev->gadget = gadget; set_gadget_data(gadget, dev); init_timer(&dev->resume); dev->resume.function = zero_autoresume; dev->resume.data = (unsigned long) dev; /* preallocate control response and buffer */ dev->req = usb_ep_alloc_request(gadget->ep0, GFP_KERNEL); if (!dev->req) goto enomem; dev->req->buf = kmalloc(USB_BUFSIZ, GFP_KERNEL); if (!dev->req->buf) goto enomem; dev->req->complete = zero_setup_complete; device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket; if (gadget_is_dualspeed(gadget)) { /* assume ep0 uses the same value for both speeds ... */ dev_qualifier.bMaxPacketSize0 = device_desc.bMaxPacketSize0; /* and that all endpoints are dual-speed */ hs_source_desc.bEndpointAddress = fs_source_desc.bEndpointAddress; hs_sink_desc.bEndpointAddress = fs_sink_desc.bEndpointAddress; } if (gadget_is_otg(gadget)) { otg_descriptor.bmAttributes |= USB_OTG_HNP, source_sink_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP; loopback_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP; } usb_gadget_set_selfpowered(gadget); if (autoresume) { source_sink_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP; loopback_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP; } gadget->ep0->driver_data = dev; INFO(dev, "%s, version: " DRIVER_VERSION "\n", longname); INFO(dev, "using %s, OUT %s IN %s\n", gadget->name, EP_OUT_NAME, EP_IN_NAME); snprintf(manufacturer, sizeof manufacturer, "%s %s with %s", init_utsname()->sysname, init_utsname()->release, gadget->name); return 0; enomem: zero_unbind(gadget); return -ENOMEM; }
static int psfreedom_bind(struct usb_gadget *gadget) { struct psfreedom_device *dev; int err = 0; dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (!dev) { return -ENOMEM; } spin_lock_init(&dev->lock); usb_gadget_set_selfpowered (gadget); dev->gadget = gadget; set_gadget_data(gadget, dev); INFO(dev, "%s, version: " PSFREEDOM_VERSION " - " DRIVER_VERSION "\n", longname); load_firmware (dev, supported_firmwares[0].version); /* preallocate control response and buffer */ dev->req = alloc_ep_req(gadget->ep0, max (sizeof (port3_config_desc), dev->port1_config_desc_size) + USB_BUFSIZ); if (!dev->req) { err = -ENOMEM; goto fail; } dev->req->complete = psfreedom_setup_complete; gadget->ep0->driver_data = dev; /* Bind the hub and devices */ err = hub_bind (gadget, dev); if (err < 0) goto fail; err = devices_bind (gadget, dev); if (err < 0) goto fail; DBG(dev, "psfreedom_bind finished ok\n"); setup_timer(&psfreedom_state_machine_timer, psfreedom_state_machine_timeout, (unsigned long) gadget); psfreedom_disconnect (gadget); /* Create the /proc filesystem */ dev->proc_dir = proc_mkdir (PROC_DIR_NAME, NULL); if (dev->proc_dir) { printk(KERN_INFO "/proc/%s/ created\n", PROC_DIR_NAME); create_proc_fs (dev, &dev->proc_status_entry, PROC_STATUS_NAME, proc_status_read, NULL); create_proc_fs (dev, &dev->proc_version_entry, PROC_VERSION_NAME, proc_version_read, NULL); create_proc_fs (dev, &dev->proc_payload_entry, PROC_PAYLOAD_NAME, proc_payload_read, proc_payload_write); create_proc_fs (dev, &dev->proc_shellcode_entry, PROC_SHELLCODE_NAME, proc_shellcode_read, proc_shellcode_write); create_proc_fs (dev, &dev->proc_supported_firmwares_entry, PROC_SUPPORTED_FIRMWARES_NAME, proc_supported_firmwares_read, NULL); create_proc_fs (dev, &dev->proc_fw_version_entry, PROC_FW_VERSION_NAME, proc_fw_version_read, proc_fw_version_write); create_proc_fs (dev, &dev->proc_stage2_entry, PROC_STAGE2_NAME, NULL, proc_stage2_write); /* that's it for now..*/ } /* By default don't use asbestos */ dev->stage2_payload = NULL; dev->stage2_payload_size = 0; return 0; fail: psfreedom_unbind(gadget); return err; }
static void #ifndef CONFIG_USB_COMPOSITE stop_activity(struct usb_gadget *gadget, struct usb_gadget_driver *driver) { #else stop_activity(struct usb_gadget *gadget, struct gadget_driver_info *p_info) { struct usb_gadget_driver *driver=NULL; #endif DMSG("Trace path 1\n"); driver = (struct usb_gadget_driver *)stop_udc(driver); /* report disconnect; the driver is already quiesced */ #ifndef CONFIG_USB_COMPOSITE if (driver) driver->disconnect(gadget); #else if (!p_info->stopped) p_info->driver->disconnect(gadget); p_info->stopped = 1; #endif /* re-init driver-visible data structures */ udc_reinit(); } #ifdef CONFIG_USB_COMPOSITE struct gadget_driver_info *get_driver_info(struct pxa3xx_comp *dev, struct usb_gadget_driver *driver) { struct gadget_driver_info *p_info = dev->first_gadget; while (p_info && (p_info->driver != driver)) p_info = p_info->next; return p_info; } #endif int comp_check_driver(struct pxa3xx_comp *dev, struct usb_gadget_driver *slf_drver, struct usb_gadget_driver *driver) { struct gadget_driver_info *p_info = get_driver_info(dev, driver); #ifdef CONFIG_USB_OTG if (dev->transceiver && dev->transceiver->default_a) { printk(KERN_ERR "Mini-A connected! " "This operation may cause unexpected error!!!\n"); } #endif #ifdef CONFIG_USB_COMPOSITE if (!driver || NULL == p_info) { printk(KERN_ERR "%s, can't find driver!\n", __FUNCTION__); return 0; } return 1; #else if (!driver || driver != slf_drver) { printk(KERN_ERR "%s, can't find driver!\n", __FUNCTION__); return 0; } return 1; #endif } int comp_is_dev_busy(struct pxa3xx_comp *dev, struct usb_gadget_driver *driver) { #ifndef CONFIG_USB_COMPOSITE if (driver) return 1; #else /* FIXME remove all modules before insert again */ if ((dev->rm_flag) && dev->first_gadget) { printk(KERN_ERR "left modules may not work! " "please remove all and insert again!!!\n"); return 1; } #ifdef CONFIG_USB_OTG if(dev->transceiver && dev->transceiver->default_a) { printk(KERN_ERR "Mini-A connected! " "please unplug it and insert module again!!!\n"); return 1; } #endif #endif return 0; } int stop_cur_gadget(struct pxa3xx_comp *dev, struct usb_gadget *gadget, struct usb_gadget_driver *driver) { #ifdef CONFIG_USB_COMPOSITE struct gadget_driver_info *p_info = get_driver_info(dev, driver); set_gadget_data(gadget, p_info->driver_data); stop_activity(gadget, p_info); return 0; #else stop_activity(gadget, driver); return 0; #endif } void comp_register_driver(struct pxa3xx_comp *dev, struct usb_gadget *gadget, struct usb_gadget_driver *driver) { #ifdef CONFIG_USB_COMPOSITE /* allocate gadget_driver_info and attach it to controller */ gadget_info_init(dev, gadget, driver); dev->active_gadget->driver_data = get_gadget_data(gadget); #ifdef MULTI_P3 gadget_get_device_desc(dev, gadget, driver); #endif /* MULTI_P3 */ #endif /* After driver is bound, send a fake get configuration command to * gadget driver to get the configuration information */ gadget_get_config_desc(dev, gadget, driver); #if defined(CONFIG_USB_COMPOSITE) && (defined(CONFIG_USB_PXA3XX_U2D) \ || defined(CONFIG_USB_PXA_U2O)) gadget_get_config_desc_hs(dev, gadget, driver); #endif }
static int fastboot_bind(struct usb_gadget *gadget) { struct fastboot_dev *dev = &l_fbdev; u8 cdc = 1, zlp = 1; struct usb_ep *in_ep, *out_ep; int gcnum; u8 tmp[7]; debug("%s controller :%s recognized\n", __func__, gadget->name); gcnum = usb_gadget_controller_number(gadget); if (gcnum >= 0) device_desc.bcdDevice = cpu_to_le16(0x0300 + gcnum); else { /* * can't assume CDC works. don't want to default to * anything less functional on CDC-capable hardware, * so we fail in this case. */ error("controller '%s' not recognized", gadget->name); return -ENODEV; } if (bcdDevice) device_desc.bcdDevice = cpu_to_le16(bcdDevice); if (iManufacturer) strlcpy(manufacturer, iManufacturer, sizeof manufacturer); if (iProduct) strlcpy(product_desc, iProduct, sizeof product_desc); iSerialNumber = get_product_sn(); device_desc.iSerialNumber = STRING_SERIALNUMBER, strlcpy(serial_number, iSerialNumber, sizeof serial_number); /* all we really need is bulk IN/OUT */ usb_ep_autoconfig_reset(gadget); in_ep = usb_ep_autoconfig(gadget, &fs_source_desc); if (!in_ep) { autoconf_fail: error("can't autoconfigure on %s\n", gadget->name); return -ENODEV; } in_ep->driver_data = in_ep; /* claim */ out_ep = usb_ep_autoconfig(gadget, &fs_sink_desc); if (!out_ep) goto autoconf_fail; out_ep->driver_data = out_ep; /* claim */ device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket; usb_gadget_set_selfpowered(gadget); if (gadget_is_dualspeed(gadget)) { /* assumes ep0 uses the same value for both speeds ... */ dev_qualifier.bMaxPacketSize0 = device_desc.bMaxPacketSize0; /* and that all endpoints are dual-speed */ hs_source_desc.bEndpointAddress = fs_source_desc.bEndpointAddress; hs_sink_desc.bEndpointAddress = fs_sink_desc.bEndpointAddress; } dev->network_started = 0; dev->in_ep = in_ep; dev->out_ep = out_ep; /* preallocate control message data and buffer */ dev->req = usb_ep_alloc_request(gadget->ep0, GFP_KERNEL); if (!dev->req) goto fail; dev->req->buf = control_req; dev->req->complete = fastboot_setup_complete; /* ... and maybe likewise for status transfer */ /* finish hookup to lower layer ... */ dev->gadget = gadget; set_gadget_data(gadget, dev); gadget->ep0->driver_data = dev; debug("bind controller with the driver\n"); /* * two kinds of host-initiated state changes: * - iff DATA transfer is active, carrier is "on" * - tx queueing enabled if open *and* carrier is "on" */ return 0; fail: error("%s failed", __func__); fastboot_unbind(gadget); return -ENOMEM; }