.. | .. |
---|
71 | 71 | wait_queue_head_t write_queue; |
---|
72 | 72 | struct usb_request *req; |
---|
73 | 73 | |
---|
74 | | - int minor; |
---|
| 74 | + struct device dev; |
---|
75 | 75 | struct cdev cdev; |
---|
76 | 76 | struct usb_function func; |
---|
77 | 77 | |
---|
.. | .. |
---|
82 | 82 | static inline struct f_hidg *func_to_hidg(struct usb_function *f) |
---|
83 | 83 | { |
---|
84 | 84 | return container_of(f, struct f_hidg, func); |
---|
| 85 | +} |
---|
| 86 | + |
---|
| 87 | +static void hidg_release(struct device *dev) |
---|
| 88 | +{ |
---|
| 89 | + struct f_hidg *hidg = container_of(dev, struct f_hidg, dev); |
---|
| 90 | + |
---|
| 91 | + kfree(hidg->set_report_buf); |
---|
| 92 | + kfree(hidg); |
---|
85 | 93 | } |
---|
86 | 94 | |
---|
87 | 95 | /*-------------------------------------------------------------------------*/ |
---|
.. | .. |
---|
288 | 296 | if (!count) |
---|
289 | 297 | return 0; |
---|
290 | 298 | |
---|
291 | | - if (!access_ok(VERIFY_WRITE, buffer, count)) |
---|
292 | | - return -EFAULT; |
---|
293 | | - |
---|
294 | 299 | spin_lock_irqsave(&hidg->read_spinlock, flags); |
---|
295 | 300 | |
---|
296 | 301 | #define READ_COND_INTOUT (!list_empty(&hidg->completed_out_req)) |
---|
.. | .. |
---|
429 | 434 | unsigned long flags; |
---|
430 | 435 | ssize_t status = -ENOMEM; |
---|
431 | 436 | |
---|
432 | | - if (!access_ok(VERIFY_READ, buffer, count)) |
---|
433 | | - return -EFAULT; |
---|
434 | | - |
---|
435 | 437 | spin_lock_irqsave(&hidg->write_spinlock, flags); |
---|
436 | 438 | |
---|
437 | 439 | if (!hidg->req) { |
---|
.. | .. |
---|
487 | 489 | } |
---|
488 | 490 | |
---|
489 | 491 | req->status = 0; |
---|
490 | | - req->zero = ((count % hidg->in_ep->maxpacket) == 0); |
---|
| 492 | + req->zero = 0; |
---|
491 | 493 | req->length = count; |
---|
492 | 494 | req->complete = f_hidg_req_complete; |
---|
493 | 495 | req->context = hidg; |
---|
.. | .. |
---|
593 | 595 | break; |
---|
594 | 596 | default: |
---|
595 | 597 | ERROR(cdev, "Set report failed %d\n", req->status); |
---|
596 | | - /* FALLTHROUGH */ |
---|
| 598 | + fallthrough; |
---|
597 | 599 | case -ECONNABORTED: /* hardware forced ep reset */ |
---|
598 | 600 | case -ECONNRESET: /* request dequeued */ |
---|
599 | 601 | case -ESHUTDOWN: /* disconnect from host */ |
---|
.. | .. |
---|
910 | 912 | struct usb_ep *ep; |
---|
911 | 913 | struct f_hidg *hidg = func_to_hidg(f); |
---|
912 | 914 | struct usb_string *us; |
---|
913 | | - struct device *device; |
---|
914 | 915 | int status; |
---|
915 | | - dev_t dev; |
---|
916 | 916 | |
---|
917 | 917 | /* maybe allocate device-global string IDs, and patch descriptors */ |
---|
918 | 918 | us = usb_gstrings_attach(c->cdev, ct_func_strings, |
---|
.. | .. |
---|
1005 | 1005 | |
---|
1006 | 1006 | /* create char device */ |
---|
1007 | 1007 | cdev_init(&hidg->cdev, &f_hidg_fops); |
---|
1008 | | - dev = MKDEV(major, hidg->minor); |
---|
1009 | | - status = cdev_add(&hidg->cdev, dev, 1); |
---|
| 1008 | + status = cdev_device_add(&hidg->cdev, &hidg->dev); |
---|
1010 | 1009 | if (status) |
---|
1011 | 1010 | goto fail_free_descs; |
---|
1012 | 1011 | |
---|
1013 | | - device = device_create(hidg_class, NULL, dev, NULL, |
---|
1014 | | - "%s%d", "hidg", hidg->minor); |
---|
1015 | | - if (IS_ERR(device)) { |
---|
1016 | | - status = PTR_ERR(device); |
---|
1017 | | - goto del; |
---|
1018 | | - } |
---|
1019 | | - |
---|
1020 | 1012 | return 0; |
---|
1021 | | -del: |
---|
1022 | | - cdev_del(&hidg->cdev); |
---|
1023 | 1013 | fail_free_descs: |
---|
1024 | 1014 | usb_free_all_descriptors(f); |
---|
1025 | 1015 | fail: |
---|
.. | .. |
---|
1250 | 1240 | |
---|
1251 | 1241 | hidg = func_to_hidg(f); |
---|
1252 | 1242 | opts = container_of(f->fi, struct f_hid_opts, func_inst); |
---|
1253 | | - kfree(hidg->report_desc); |
---|
1254 | | - kfree(hidg->set_report_buf); |
---|
1255 | | - kfree(hidg); |
---|
| 1243 | + put_device(&hidg->dev); |
---|
1256 | 1244 | mutex_lock(&opts->lock); |
---|
1257 | 1245 | --opts->refcnt; |
---|
1258 | 1246 | mutex_unlock(&opts->lock); |
---|
.. | .. |
---|
1262 | 1250 | { |
---|
1263 | 1251 | struct f_hidg *hidg = func_to_hidg(f); |
---|
1264 | 1252 | |
---|
1265 | | - device_destroy(hidg_class, MKDEV(major, hidg->minor)); |
---|
1266 | | - cdev_del(&hidg->cdev); |
---|
| 1253 | + cdev_device_del(&hidg->cdev, &hidg->dev); |
---|
1267 | 1254 | |
---|
1268 | 1255 | usb_free_all_descriptors(f); |
---|
1269 | 1256 | } |
---|
.. | .. |
---|
1272 | 1259 | { |
---|
1273 | 1260 | struct f_hidg *hidg; |
---|
1274 | 1261 | struct f_hid_opts *opts; |
---|
| 1262 | + int ret; |
---|
1275 | 1263 | |
---|
1276 | 1264 | /* allocate and initialize one new instance */ |
---|
1277 | 1265 | hidg = kzalloc(sizeof(*hidg), GFP_KERNEL); |
---|
.. | .. |
---|
1283 | 1271 | mutex_lock(&opts->lock); |
---|
1284 | 1272 | ++opts->refcnt; |
---|
1285 | 1273 | |
---|
1286 | | - hidg->minor = opts->minor; |
---|
| 1274 | + device_initialize(&hidg->dev); |
---|
| 1275 | + hidg->dev.release = hidg_release; |
---|
| 1276 | + hidg->dev.class = hidg_class; |
---|
| 1277 | + hidg->dev.devt = MKDEV(major, opts->minor); |
---|
| 1278 | + ret = dev_set_name(&hidg->dev, "hidg%d", opts->minor); |
---|
| 1279 | + if (ret) { |
---|
| 1280 | + --opts->refcnt; |
---|
| 1281 | + mutex_unlock(&opts->lock); |
---|
| 1282 | + return ERR_PTR(ret); |
---|
| 1283 | + } |
---|
| 1284 | + |
---|
1287 | 1285 | hidg->bInterfaceSubClass = opts->subclass; |
---|
1288 | 1286 | hidg->bInterfaceProtocol = opts->protocol; |
---|
1289 | 1287 | hidg->report_length = opts->report_length; |
---|
1290 | 1288 | hidg->report_desc_length = opts->report_desc_length; |
---|
1291 | 1289 | if (opts->report_desc) { |
---|
1292 | | - hidg->report_desc = kmemdup(opts->report_desc, |
---|
1293 | | - opts->report_desc_length, |
---|
1294 | | - GFP_KERNEL); |
---|
| 1290 | + hidg->report_desc = devm_kmemdup(&hidg->dev, opts->report_desc, |
---|
| 1291 | + opts->report_desc_length, |
---|
| 1292 | + GFP_KERNEL); |
---|
1295 | 1293 | if (!hidg->report_desc) { |
---|
1296 | | - kfree(hidg); |
---|
| 1294 | + put_device(&hidg->dev); |
---|
| 1295 | + --opts->refcnt; |
---|
1297 | 1296 | mutex_unlock(&opts->lock); |
---|
1298 | 1297 | return ERR_PTR(-ENOMEM); |
---|
1299 | 1298 | } |
---|