1、框架
opts:options缩写,存放与设备相关的选项字段,存放在此处
struct f_usb_function_device_opts {
struct list_head list;
struct usb_function_instance inst;
struct class *cls;
size_t bufsize;
dev_t dev;
}
struct usb_function_device {
struct config_group group
struct list_head list;
char name[32];
bool is_ready;
}
struct f_usb_function_device_port {
struct usb_ep *ep_in, *ep_out;
}
struct f_usb_function_device {
struct usb_function func;
struct f_usb_device_opts *opts;
struct f_usb_device_port port;
bool bound;
}
2、usb_function_instance实现
static void f_usb_function_device_instance_free(struct usb_function_instance *fi)
{
struct f_usb_function_device_opts *opts = container_of(fi, struct f_usb_function_device_opts, inst);
if (!list_empty(&opts->list)) {
printk("bug:sub device not empty\n");
return;
}
destroy_class(opts->cls);
unregister_chrdev_region(opts->dev, 255);
kfree(opts);
}
static struct usb_function_instance *f_usb_function_device_alloc_inst(void)
{
struct f_usb_function_device_opts *opts;
int ret;
opts = kzalloc(sizeof(*opts), GFP_KERNEL);
if (!opts)
return ERR_PTR(-ENOMEM);
INIT_LIST_HEAD(&opts->list);
opts->inst.free_func_inst = f_usb_function_device_instance_free;
opts->cls = class_create(THIS_MODULE, "usb_function");
if (IS_ERR(opts->cls)) {
void *r = opts->cls;
kfree(opts);
return r;
}
ret = alloc_chrdev_region(&opts->dev, 255, "usb_function");
if (ret)
goto out;
config_group_init_type_name(&opts->inst.group, "", &f_usb_function_root_type);
out:
destroy_class(opts->cls);
kfree(opts);
return ERR_PTR(ret);
}