static int acc_function_set_alt(struct usb_function *f, unsigned intf, unsigned alt) { struct acc_dev *dev = func_to_dev(f); struct usb_composite_dev *cdev = f->config->cdev; int ret; DBG(cdev, "acc_function_set_alt intf: %d alt: %d\n", intf, alt); ret = usb_ep_enable(dev->ep_in, ep_choose(cdev->gadget, &acc_highspeed_in_desc, &acc_fullspeed_in_desc)); if (ret) return ret; ret = usb_ep_enable(dev->ep_out, ep_choose(cdev->gadget, &acc_highspeed_out_desc, &acc_fullspeed_out_desc)); if (ret) { usb_ep_disable(dev->ep_in); return ret; } dev->online = 1; /* readers may be blocked waiting for us to go online */ wake_up(&dev->read_wq); #ifdef CONFIG_ANDROID_PANTECH_USB_MANAGER usb_interface_enum_cb(ACCESSORY_TYPE_FLAG); #endif return 0; }
static int acc_function_set_alt(struct usb_function *f, unsigned intf, unsigned alt) { struct acc_dev *dev = func_to_dev(f); struct usb_composite_dev *cdev = f->config->cdev; int ret; DBG(cdev, "acc_function_set_alt intf: %d alt: %d\n", intf, alt); ret = usb_ep_enable(dev->ep_in, ep_choose(cdev->gadget, &acc_highspeed_in_desc, &acc_fullspeed_in_desc)); if (ret) return ret; ret = usb_ep_enable(dev->ep_out, ep_choose(cdev->gadget, &acc_highspeed_out_desc, &acc_fullspeed_out_desc)); if (ret) { usb_ep_disable(dev->ep_in); return ret; } if (!dev->function.hidden) dev->online = 1; /* readers may be blocked waiting for us to go online */ wake_up(&dev->read_wq); return 0; }
static void acc_function_unbind(struct usb_configuration *c, struct usb_function *f) { struct acc_dev *dev = func_to_dev(f); struct usb_request *req; int i; while ((req = req_get(dev, &dev->tx_idle))) acc_request_free(req, dev->ep_in); for (i = 0; i < RX_REQ_MAX; i++) acc_request_free(dev->rx_req[i], dev->ep_out); }
static void acc_function_disable(struct usb_function *f) { struct acc_dev *dev = func_to_dev(f); struct usb_composite_dev *cdev = dev->cdev; DBG(cdev, "acc_function_disable\n"); acc_set_disconnected(dev); usb_ep_disable(dev->ep_in); usb_ep_disable(dev->ep_out); /* readers may be blocked waiting for us to go online */ wake_up(&dev->read_wq); VDBG(cdev, "%s disabled\n", dev->function.name); }
static void acc_function_disable(struct usb_function *f) { struct acc_dev *dev = func_to_dev(f); struct usb_composite_dev *cdev = dev->cdev; DBG(cdev, "acc_function_disable\n"); acc_set_disconnected(dev); usb_ep_disable(dev->ep_in); usb_ep_disable(dev->ep_out); wake_up(&dev->read_wq); VDBG(cdev, "%s disabled\n", dev->function.name); }
static int acc_function_set_alt(struct usb_function *f, unsigned intf, unsigned alt) { struct acc_dev *dev = func_to_dev(f); struct usb_composite_dev *cdev = f->config->cdev; int ret; DBG(cdev, "acc_function_set_alt intf: %d alt: %d\n", intf, alt); ret = config_ep_by_speed(cdev->gadget, f, dev->ep_in); if (ret) { dev->ep_in->desc = NULL; ERROR(cdev, "config_ep_by_speed failes for ep %s, result %d\n", dev->ep_in->name, ret); return ret; } ret = usb_ep_enable(dev->ep_in); if (ret) { ERROR(cdev, "failed to enable ep %s, result %d\n", dev->ep_in->name, ret); return ret; } ret = config_ep_by_speed(cdev->gadget, f, dev->ep_out); if (ret) { dev->ep_out->desc = NULL; ERROR(cdev, "config_ep_by_speed failes for ep %s, result %d\n", dev->ep_out->name, ret); usb_ep_disable(dev->ep_in); return ret; } ret = usb_ep_enable(dev->ep_out); if (ret) { ERROR(cdev, "failed to enable ep %s, result %d\n", dev->ep_out->name, ret); usb_ep_disable(dev->ep_in); return ret; } dev->online = 1; /* readers may be blocked waiting for us to go online */ wake_up(&dev->read_wq); return 0; }
static void acc_function_unbind(struct usb_configuration *c, struct usb_function *f) { struct acc_dev *dev = func_to_dev(f); struct usb_request *req; int i; spin_lock_irq(&dev->lock); while ((req = req_get(dev, &dev->tx_idle))) acc_request_free(req, dev->ep_in); for (i = 0; i < RX_REQ_MAX; i++) acc_request_free(dev->rx_req[i], dev->ep_out); dev->online = 0; spin_unlock_irq(&dev->lock); misc_deregister(&acc_device); kfree(_acc_dev); _acc_dev = NULL; }
static void acc_function_release(struct usb_configuration *c, struct usb_function *f) { struct acc_dev *dev = func_to_dev(f); struct usb_request *req; int i; if (dev->ep_in) dev->ep_in->driver_data = NULL; if (dev->ep_out) dev->ep_out->driver_data = NULL; /* spin_lock_irq(&dev->lock); */ while ((req = req_get(dev, &dev->tx_idle))) acc_request_free(req, dev->ep_in); for (i = 0; i < RX_REQ_MAX; i++) acc_request_free(dev->rx_req[i], dev->ep_out); dev->online = 0; /* spin_unlock_irq(&dev->lock); */ usb_interface_id_remove(c, 1); }
static int acc_function_bind(struct usb_configuration *c, struct usb_function *f) { struct usb_composite_dev *cdev = c->cdev; struct acc_dev *dev = func_to_dev(f); int id; int ret; DBG(cdev, "acc_function_bind dev: %p\n", dev); dev->start_requested = 0; /* allocate interface ID(s) */ id = usb_interface_id(c, f); if (id < 0) return id; acc_interface_desc.bInterfaceNumber = id; /* allocate endpoints */ ret = create_bulk_endpoints(dev, &acc_fullspeed_in_desc, &acc_fullspeed_out_desc); if (ret) return ret; /* support high speed hardware */ if (gadget_is_dualspeed(c->cdev->gadget)) { acc_highspeed_in_desc.bEndpointAddress = acc_fullspeed_in_desc.bEndpointAddress; acc_highspeed_out_desc.bEndpointAddress = acc_fullspeed_out_desc.bEndpointAddress; } DBG(cdev, "%s speed %s: IN/%s, OUT/%s\n", gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full", f->name, dev->ep_in->name, dev->ep_out->name); return 0; }
static int acc_function_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl) { struct acc_dev *dev = func_to_dev(f); struct usb_composite_dev *cdev = dev->cdev; int value = -EOPNOTSUPP; u8 b_requestType = ctrl->bRequestType; u8 b_request = ctrl->bRequest; u16 w_index = le16_to_cpu(ctrl->wIndex); u16 w_value = le16_to_cpu(ctrl->wValue); u16 w_length = le16_to_cpu(ctrl->wLength); /* printk(KERN_INFO "acc_function_setup " "%02x.%02x v%04x i%04x l%u\n", b_requestType, b_request, w_value, w_index, w_length); */ if (dev->function.hidden) { if (b_requestType == (USB_DIR_OUT | USB_TYPE_VENDOR)) { if (b_request == ACCESSORY_START) { schedule_delayed_work( &dev->work, msecs_to_jiffies(10)); value = 0; } else if (b_request == ACCESSORY_SEND_STRING) { dev->string_index = w_index; cdev->gadget->ep0->driver_data = dev; cdev->req->complete = acc_complete_set_string; value = w_length; } } else if (b_requestType == (USB_DIR_IN | USB_TYPE_VENDOR)) { if (b_request == ACCESSORY_GET_PROTOCOL) { *((u16 *)cdev->req->buf) = PROTOCOL_VERSION; value = sizeof(u16); /* clear any strings left over from a previous session */ memset(dev->manufacturer, 0, sizeof(dev->manufacturer)); memset(dev->model, 0, sizeof(dev->model)); memset(dev->description, 0, sizeof(dev->description)); memset(dev->version, 0, sizeof(dev->version)); memset(dev->uri, 0, sizeof(dev->uri)); memset(dev->serial, 0, sizeof(dev->serial)); } } } if (value >= 0) { cdev->req->zero = 0; cdev->req->length = value; value = usb_ep_queue(cdev->gadget->ep0, cdev->req, GFP_ATOMIC); if (value < 0) ERROR(cdev, "%s setup response queue error\n", __func__); } if (value == -EOPNOTSUPP) VDBG(cdev, "(%s) unknown class-specific control req " "%02x.%02x v%04x i%04x l%u\n", f->name, ctrl->bRequestType, ctrl->bRequest, w_value, w_index, w_length); return value; }