.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /****************************************************************************** |
---|
2 | 3 | * |
---|
3 | 4 | * Driver for Option High Speed Mobile Devices. |
---|
.. | .. |
---|
10 | 11 | * <ajb@spheresystems.co.uk> |
---|
11 | 12 | * Copyright (C) 2008 Greg Kroah-Hartman <gregkh@suse.de> |
---|
12 | 13 | * Copyright (C) 2008 Novell, Inc. |
---|
13 | | - * |
---|
14 | | - * This program is free software; you can redistribute it and/or modify |
---|
15 | | - * it under the terms of the GNU General Public License version 2 as |
---|
16 | | - * published by the Free Software Foundation. |
---|
17 | | - * |
---|
18 | | - * This program is distributed in the hope that it will be useful, |
---|
19 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
20 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
21 | | - * GNU General Public License for more details. |
---|
22 | | - * |
---|
23 | | - * You should have received a copy of the GNU General Public License |
---|
24 | | - * along with this program; if not, write to the Free Software |
---|
25 | | - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, |
---|
26 | | - * USA |
---|
27 | | - * |
---|
28 | 14 | * |
---|
29 | 15 | *****************************************************************************/ |
---|
30 | 16 | |
---|
.. | .. |
---|
200 | 186 | int intr_completed; |
---|
201 | 187 | struct usb_endpoint_descriptor *endp; |
---|
202 | 188 | struct urb *urb; |
---|
203 | | - struct hso_serial_state_notification serial_state_notification; |
---|
| 189 | + struct hso_serial_state_notification *serial_state_notification; |
---|
204 | 190 | u16 prev_UART_state_bitmap; |
---|
205 | 191 | struct uart_icount icount; |
---|
206 | 192 | }; |
---|
.. | .. |
---|
833 | 819 | }; |
---|
834 | 820 | |
---|
835 | 821 | /* called when a packet did not ack after watchdogtimeout */ |
---|
836 | | -static void hso_net_tx_timeout(struct net_device *net) |
---|
| 822 | +static void hso_net_tx_timeout(struct net_device *net, unsigned int txqueue) |
---|
837 | 823 | { |
---|
838 | 824 | struct hso_net *odev = netdev_priv(net); |
---|
839 | 825 | |
---|
.. | .. |
---|
844 | 830 | dev_warn(&net->dev, "Tx timed out.\n"); |
---|
845 | 831 | |
---|
846 | 832 | /* Tear the waiting frame off the list */ |
---|
847 | | - if (odev->mux_bulk_tx_urb && |
---|
848 | | - (odev->mux_bulk_tx_urb->status == -EINPROGRESS)) |
---|
| 833 | + if (odev->mux_bulk_tx_urb) |
---|
849 | 834 | usb_unlink_urb(odev->mux_bulk_tx_urb); |
---|
850 | 835 | |
---|
851 | 836 | /* Update statistics */ |
---|
.. | .. |
---|
1227 | 1212 | * This needs to be a tasklet otherwise we will |
---|
1228 | 1213 | * end up recursively calling this function. |
---|
1229 | 1214 | */ |
---|
1230 | | -static void hso_unthrottle_tasklet(struct hso_serial *serial) |
---|
| 1215 | +static void hso_unthrottle_tasklet(unsigned long data) |
---|
1231 | 1216 | { |
---|
| 1217 | + struct hso_serial *serial = (struct hso_serial *)data; |
---|
1232 | 1218 | unsigned long flags; |
---|
1233 | 1219 | |
---|
1234 | 1220 | spin_lock_irqsave(&serial->serial_lock, flags); |
---|
.. | .. |
---|
1278 | 1264 | /* Force default termio settings */ |
---|
1279 | 1265 | _hso_serial_set_termios(tty, NULL); |
---|
1280 | 1266 | tasklet_init(&serial->unthrottle_tasklet, |
---|
1281 | | - (void (*)(unsigned long))hso_unthrottle_tasklet, |
---|
| 1267 | + hso_unthrottle_tasklet, |
---|
1282 | 1268 | (unsigned long)serial); |
---|
1283 | 1269 | result = hso_start_serial_device(serial->parent, GFP_KERNEL); |
---|
1284 | 1270 | if (result) { |
---|
.. | .. |
---|
1446 | 1432 | usb_rcvintpipe(usb, |
---|
1447 | 1433 | tiocmget->endp-> |
---|
1448 | 1434 | bEndpointAddress & 0x7F), |
---|
1449 | | - &tiocmget->serial_state_notification, |
---|
| 1435 | + tiocmget->serial_state_notification, |
---|
1450 | 1436 | sizeof(struct hso_serial_state_notification), |
---|
1451 | 1437 | tiocmget_intr_callback, serial, |
---|
1452 | 1438 | tiocmget->endp->bInterval); |
---|
.. | .. |
---|
1493 | 1479 | /* wIndex should be the USB interface number of the port to which the |
---|
1494 | 1480 | * notification applies, which should always be the Modem port. |
---|
1495 | 1481 | */ |
---|
1496 | | - serial_state_notification = &tiocmget->serial_state_notification; |
---|
| 1482 | + serial_state_notification = tiocmget->serial_state_notification; |
---|
1497 | 1483 | if (serial_state_notification->bmRequestType != BM_REQUEST_TYPE || |
---|
1498 | 1484 | serial_state_notification->bNotification != B_NOTIFICATION || |
---|
1499 | 1485 | le16_to_cpu(serial_state_notification->wValue) != W_VALUE || |
---|
.. | .. |
---|
2476 | 2462 | &interface_to_usbdev(interface)->dev, |
---|
2477 | 2463 | RFKILL_TYPE_WWAN, |
---|
2478 | 2464 | &hso_rfkill_ops, hso_dev); |
---|
2479 | | - if (!hso_net->rfkill) { |
---|
2480 | | - dev_err(dev, "%s - Out of memory\n", __func__); |
---|
| 2465 | + if (!hso_net->rfkill) |
---|
2481 | 2466 | return; |
---|
2482 | | - } |
---|
| 2467 | + |
---|
2483 | 2468 | if (rfkill_register(hso_net->rfkill) < 0) { |
---|
2484 | 2469 | rfkill_destroy(hso_net->rfkill); |
---|
2485 | 2470 | hso_net->rfkill = NULL; |
---|
.. | .. |
---|
2552 | 2537 | if (!hso_net->mux_bulk_tx_buf) |
---|
2553 | 2538 | goto err_free_tx_urb; |
---|
2554 | 2539 | |
---|
2555 | | - add_net_device(hso_dev); |
---|
| 2540 | + result = add_net_device(hso_dev); |
---|
| 2541 | + if (result) { |
---|
| 2542 | + dev_err(&interface->dev, "Failed to add net device\n"); |
---|
| 2543 | + goto err_free_tx_buf; |
---|
| 2544 | + } |
---|
2556 | 2545 | |
---|
2557 | 2546 | /* registering our net device */ |
---|
2558 | 2547 | result = register_netdev(net); |
---|
2559 | 2548 | if (result) { |
---|
2560 | 2549 | dev_err(&interface->dev, "Failed to register device\n"); |
---|
2561 | | - goto err_free_tx_buf; |
---|
| 2550 | + goto err_rmv_ndev; |
---|
2562 | 2551 | } |
---|
2563 | 2552 | |
---|
2564 | 2553 | hso_log_port(hso_dev); |
---|
.. | .. |
---|
2567 | 2556 | |
---|
2568 | 2557 | return hso_dev; |
---|
2569 | 2558 | |
---|
2570 | | -err_free_tx_buf: |
---|
| 2559 | +err_rmv_ndev: |
---|
2571 | 2560 | remove_net_device(hso_dev); |
---|
| 2561 | +err_free_tx_buf: |
---|
2572 | 2562 | kfree(hso_net->mux_bulk_tx_buf); |
---|
2573 | 2563 | err_free_tx_urb: |
---|
2574 | 2564 | usb_free_urb(hso_net->mux_bulk_tx_urb); |
---|
.. | .. |
---|
2594 | 2584 | usb_free_urb(tiocmget->urb); |
---|
2595 | 2585 | tiocmget->urb = NULL; |
---|
2596 | 2586 | serial->tiocmget = NULL; |
---|
| 2587 | + kfree(tiocmget->serial_state_notification); |
---|
| 2588 | + tiocmget->serial_state_notification = NULL; |
---|
2597 | 2589 | kfree(tiocmget); |
---|
2598 | 2590 | } |
---|
2599 | 2591 | } |
---|
.. | .. |
---|
2644 | 2636 | num_urbs = 2; |
---|
2645 | 2637 | serial->tiocmget = kzalloc(sizeof(struct hso_tiocmget), |
---|
2646 | 2638 | GFP_KERNEL); |
---|
2647 | | - /* it isn't going to break our heart if serial->tiocmget |
---|
2648 | | - * allocation fails don't bother checking this. |
---|
2649 | | - */ |
---|
2650 | | - if (serial->tiocmget) { |
---|
2651 | | - tiocmget = serial->tiocmget; |
---|
2652 | | - tiocmget->endp = hso_get_ep(interface, |
---|
2653 | | - USB_ENDPOINT_XFER_INT, |
---|
2654 | | - USB_DIR_IN); |
---|
2655 | | - if (!tiocmget->endp) { |
---|
2656 | | - dev_err(&interface->dev, "Failed to find INT IN ep\n"); |
---|
2657 | | - goto exit; |
---|
2658 | | - } |
---|
2659 | | - |
---|
2660 | | - tiocmget->urb = usb_alloc_urb(0, GFP_KERNEL); |
---|
2661 | | - if (tiocmget->urb) { |
---|
2662 | | - mutex_init(&tiocmget->mutex); |
---|
2663 | | - init_waitqueue_head(&tiocmget->waitq); |
---|
2664 | | - } else |
---|
2665 | | - hso_free_tiomget(serial); |
---|
| 2639 | + if (!serial->tiocmget) |
---|
| 2640 | + goto exit; |
---|
| 2641 | + serial->tiocmget->serial_state_notification |
---|
| 2642 | + = kzalloc(sizeof(struct hso_serial_state_notification), |
---|
| 2643 | + GFP_KERNEL); |
---|
| 2644 | + if (!serial->tiocmget->serial_state_notification) |
---|
| 2645 | + goto exit; |
---|
| 2646 | + tiocmget = serial->tiocmget; |
---|
| 2647 | + tiocmget->endp = hso_get_ep(interface, |
---|
| 2648 | + USB_ENDPOINT_XFER_INT, |
---|
| 2649 | + USB_DIR_IN); |
---|
| 2650 | + if (!tiocmget->endp) { |
---|
| 2651 | + dev_err(&interface->dev, "Failed to find INT IN ep\n"); |
---|
| 2652 | + goto exit; |
---|
2666 | 2653 | } |
---|
2667 | | - } |
---|
2668 | | - else |
---|
| 2654 | + |
---|
| 2655 | + tiocmget->urb = usb_alloc_urb(0, GFP_KERNEL); |
---|
| 2656 | + if (!tiocmget->urb) |
---|
| 2657 | + goto exit; |
---|
| 2658 | + |
---|
| 2659 | + mutex_init(&tiocmget->mutex); |
---|
| 2660 | + init_waitqueue_head(&tiocmget->waitq); |
---|
| 2661 | + } else { |
---|
2669 | 2662 | num_urbs = 1; |
---|
| 2663 | + } |
---|
2670 | 2664 | |
---|
2671 | 2665 | if (hso_serial_common_create(serial, num_urbs, BULK_URB_RX_SIZE, |
---|
2672 | 2666 | BULK_URB_TX_SIZE)) |
---|
.. | .. |
---|
2682 | 2676 | if (! |
---|
2683 | 2677 | (serial->out_endp = |
---|
2684 | 2678 | hso_get_ep(interface, USB_ENDPOINT_XFER_BULK, USB_DIR_OUT))) { |
---|
2685 | | - dev_err(&interface->dev, "Failed to find BULK IN ep\n"); |
---|
| 2679 | + dev_err(&interface->dev, "Failed to find BULK OUT ep\n"); |
---|
2686 | 2680 | goto exit2; |
---|
2687 | 2681 | } |
---|
2688 | 2682 | |
---|