linux usb做复合设备,usb从设备驱动usb_composite_driver复合设备

Linux/arm 3.10.104

drivers/usb/gadget/composite.c

static const struct usb_gadget_driver composite_driver_template = {

.bind        = composite_bind,

.unbind        = composite_unbind,

.setup        = composite_setup,

.disconnect    = composite_disconnect,

.suspend    = composite_suspend,

.resume        = composite_resume,

.driver    = {

.owner        = THIS_MODULE,

},

};

drivers/usb/gadget/composite.c

/*

* 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 and function specific setup.

*/

int

composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)

{

struct usb_composite_dev    *cdev = get_gadget_data(gadget);

struct usb_request        *req = cdev->req;

int                value = -EOPNOTSUPP;

int                status = 0;

u16                w_index = le16_to_cpu(ctrl->wIndex);

u8                intf = w_index & 0xFF;

u16                w_value = le16_to_cpu(ctrl->wValue);

u16                w_length = le16_to_cpu(ctrl->wLength);

struct usb_function        *f = NULL;

u8                endp;

/* partial re-init of the response message; the function or the

* gadget might need to intercept e.g. a control-OUT completion

* when we delegate to it.

*/

req->zero = 0;

req->complete = composite_setup_complete;

req->length = 0;

gadget->ep0->driver_data = cdev;

switch (ctrl->bRequest) {

/* we handle all standard USB descriptors */

case USB_REQ_GET_DESCRIPTOR:

if (ctrl->bRequestType != USB_DIR_IN)

goto unknown;

switch (w_value >> 8) {

case USB_DT_DEVICE:

cdev->desc.bNumConfigurations =

count_configs(cdev, USB_DT_DEVICE);

cdev->desc.bMaxPacketSize0 =

cdev->gadget->ep0->maxpacket;

if (gadget_is_superspeed(gadget)) {

if (gadget->speed >= USB_SPEED_SUPER) {

cdev->desc.bcdUSB = cpu_to_le16(0x0300);

cdev->desc.bMaxPacketSize0 = 9;

} else {

cdev->desc.bcdUSB = cpu_to_le16(0x0210);

}

}

value = min(w_length, (u16) sizeof cdev->desc);

memcpy(req->buf, &cdev->desc, value);

break;

case USB_DT_DEVICE_QUALIFIER:

if (!gadget_is_dualspeed(gadget) ||

gadget->speed >= USB_SPEED_SUPER)

break;

device_qual(cdev);

value = min_t(int, w_length,

sizeof(struct usb_qualifier_descriptor));

break;

case USB_DT_OTHER_SPEED_CONFIG:

if (!gadget_is_dualspeed(gadget) ||

gadget->speed >= USB_SPEED_SUPER)

break;

/* FALLTHROUGH */

case USB_DT_CONFIG:

value = config_desc(cdev, w_value);

if (value >= 0)

value = min(w_length, (u16) value);

break;

case USB_DT_STRING:

value = get_string(cdev, req->buf,

w_index, w_value & 0xff);

if (value >= 0)

value = min(w_length, (u16) value);

break;

case USB_DT_BOS:

if (

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值