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;
}
Beispiel #2
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;
}
Beispiel #3
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);
}
Beispiel #4
0
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;
}
Beispiel #7
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;
}
Beispiel #8
0
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);
}
Beispiel #9
0
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;
}
Beispiel #10
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;
}