| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /**************************************************************** |
|---|
| 2 | 3 | |
|---|
| 3 | 4 | Siano Mobile Silicon, Inc. |
|---|
| 4 | 5 | MDTV receiver kernel modules. |
|---|
| 5 | 6 | Copyright (C) 2005-2009, Uri Shkolnik, Anatoly Greenblat |
|---|
| 6 | 7 | |
|---|
| 7 | | -This program is free software: you can redistribute it and/or modify |
|---|
| 8 | | -it under the terms of the GNU General Public License as published by |
|---|
| 9 | | -the Free Software Foundation, either version 2 of the License, or |
|---|
| 10 | | -(at your option) any later version. |
|---|
| 11 | | - |
|---|
| 12 | | - This program is distributed in the hope that it will be useful, |
|---|
| 13 | | -but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 14 | | -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 15 | | -GNU General Public License for more details. |
|---|
| 16 | | - |
|---|
| 17 | | -You should have received a copy of the GNU General Public License |
|---|
| 18 | | -along with this program. If not, see <http://www.gnu.org/licenses/>. |
|---|
| 19 | 8 | |
|---|
| 20 | 9 | ****************************************************************/ |
|---|
| 21 | 10 | |
|---|
| .. | .. |
|---|
| 75 | 64 | struct smsusb_urb_t *surb); |
|---|
| 76 | 65 | |
|---|
| 77 | 66 | /* |
|---|
| 78 | | - * Completing URB's callback handler - bottom half (proccess context) |
|---|
| 67 | + * Completing URB's callback handler - bottom half (process context) |
|---|
| 79 | 68 | * submits the URB prepared on smsusb_onresponse() |
|---|
| 80 | 69 | */ |
|---|
| 81 | 70 | static void do_submit_urb(struct work_struct *work) |
|---|
| .. | .. |
|---|
| 190 | 179 | |
|---|
| 191 | 180 | for (i = 0; i < MAX_URBS; i++) { |
|---|
| 192 | 181 | usb_kill_urb(&dev->surbs[i].urb); |
|---|
| 182 | + if (dev->surbs[i].wq.func) |
|---|
| 183 | + cancel_work_sync(&dev->surbs[i].wq); |
|---|
| 193 | 184 | |
|---|
| 194 | 185 | if (dev->surbs[i].cb) { |
|---|
| 195 | 186 | smscore_putbuffer(dev->coredev, dev->surbs[i].cb); |
|---|
| .. | .. |
|---|
| 225 | 216 | return -ENOENT; |
|---|
| 226 | 217 | } |
|---|
| 227 | 218 | |
|---|
| 228 | | - phdr = kmalloc(size, GFP_KERNEL); |
|---|
| 219 | + phdr = kmemdup(buffer, size, GFP_KERNEL); |
|---|
| 229 | 220 | if (!phdr) |
|---|
| 230 | 221 | return -ENOMEM; |
|---|
| 231 | | - memcpy(phdr, buffer, size); |
|---|
| 232 | 222 | |
|---|
| 233 | 223 | pr_debug("sending %s(%d) size: %d\n", |
|---|
| 234 | 224 | smscore_translate_msg(phdr->msg_type), phdr->msg_type, |
|---|
| .. | .. |
|---|
| 442 | 432 | break; |
|---|
| 443 | 433 | case SMS_UNKNOWN_TYPE: |
|---|
| 444 | 434 | pr_err("Unspecified sms device type!\n"); |
|---|
| 445 | | - /* fall-thru */ |
|---|
| 435 | + fallthrough; |
|---|
| 446 | 436 | default: |
|---|
| 447 | 437 | dev->buffer_size = USB2_BUFFER_SIZE; |
|---|
| 448 | 438 | dev->response_alignment = align; |
|---|
| .. | .. |
|---|
| 465 | 455 | rc = smscore_register_device(¶ms, &dev->coredev, 0, mdev); |
|---|
| 466 | 456 | if (rc < 0) { |
|---|
| 467 | 457 | pr_err("smscore_register_device(...) failed, rc %d\n", rc); |
|---|
| 468 | | - smsusb_term_device(intf); |
|---|
| 469 | | -#ifdef CONFIG_MEDIA_CONTROLLER_DVB |
|---|
| 470 | | - media_device_unregister(mdev); |
|---|
| 471 | | -#endif |
|---|
| 472 | | - kfree(mdev); |
|---|
| 473 | | - return rc; |
|---|
| 458 | + goto err_unregister_device; |
|---|
| 474 | 459 | } |
|---|
| 475 | 460 | |
|---|
| 476 | 461 | smscore_set_board_id(dev->coredev, board_id); |
|---|
| .. | .. |
|---|
| 487 | 472 | rc = smsusb_start_streaming(dev); |
|---|
| 488 | 473 | if (rc < 0) { |
|---|
| 489 | 474 | pr_err("smsusb_start_streaming(...) failed\n"); |
|---|
| 490 | | - smsusb_term_device(intf); |
|---|
| 491 | | - return rc; |
|---|
| 475 | + goto err_unregister_device; |
|---|
| 492 | 476 | } |
|---|
| 493 | 477 | |
|---|
| 494 | 478 | dev->state = SMSUSB_ACTIVE; |
|---|
| .. | .. |
|---|
| 496 | 480 | rc = smscore_start_device(dev->coredev); |
|---|
| 497 | 481 | if (rc < 0) { |
|---|
| 498 | 482 | pr_err("smscore_start_device(...) failed\n"); |
|---|
| 499 | | - smsusb_term_device(intf); |
|---|
| 500 | | - return rc; |
|---|
| 483 | + goto err_unregister_device; |
|---|
| 501 | 484 | } |
|---|
| 502 | 485 | |
|---|
| 503 | 486 | pr_debug("device 0x%p created\n", dev); |
|---|
| 504 | 487 | |
|---|
| 505 | 488 | return rc; |
|---|
| 489 | + |
|---|
| 490 | +err_unregister_device: |
|---|
| 491 | + smsusb_term_device(intf); |
|---|
| 492 | +#ifdef CONFIG_MEDIA_CONTROLLER_DVB |
|---|
| 493 | + media_device_unregister(mdev); |
|---|
| 494 | +#endif |
|---|
| 495 | + kfree(mdev); |
|---|
| 496 | + return rc; |
|---|
| 506 | 497 | } |
|---|
| 507 | 498 | |
|---|
| 508 | 499 | static int smsusb_probe(struct usb_interface *intf, |
|---|