.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* hfcsusb.c |
---|
2 | 3 | * mISDN driver for Colognechip HFC-S USB chip |
---|
3 | 4 | * |
---|
4 | 5 | * Copyright 2001 by Peter Sprenger (sprenger@moving-bytes.de) |
---|
5 | 6 | * Copyright 2008 by Martin Bachem (info@bachem-it.com) |
---|
6 | | - * |
---|
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, or (at your option) |
---|
10 | | - * 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, write to the Free Software |
---|
19 | | - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
---|
20 | | - * |
---|
21 | 7 | * |
---|
22 | 8 | * module params |
---|
23 | 9 | * debug=<n>, default=0, with n=0xHHHHGGGG |
---|
.. | .. |
---|
60 | 46 | static void hfcsusb_stop_endpoint(struct hfcsusb *hw, int channel); |
---|
61 | 47 | static int hfcsusb_setup_bch(struct bchannel *bch, int protocol); |
---|
62 | 48 | static void deactivate_bchannel(struct bchannel *bch); |
---|
63 | | -static void hfcsusb_ph_info(struct hfcsusb *hw); |
---|
| 49 | +static int hfcsusb_ph_info(struct hfcsusb *hw); |
---|
64 | 50 | |
---|
65 | 51 | /* start next background transfer for control channel */ |
---|
66 | 52 | static void |
---|
.. | .. |
---|
255 | 241 | * send full D/B channel status information |
---|
256 | 242 | * as MPH_INFORMATION_IND |
---|
257 | 243 | */ |
---|
258 | | -static void |
---|
| 244 | +static int |
---|
259 | 245 | hfcsusb_ph_info(struct hfcsusb *hw) |
---|
260 | 246 | { |
---|
261 | 247 | struct ph_info *phi; |
---|
262 | 248 | struct dchannel *dch = &hw->dch; |
---|
263 | 249 | int i; |
---|
264 | 250 | |
---|
265 | | - phi = kzalloc(sizeof(struct ph_info) + |
---|
266 | | - dch->dev.nrbchan * sizeof(struct ph_info_ch), GFP_ATOMIC); |
---|
| 251 | + phi = kzalloc(struct_size(phi, bch, dch->dev.nrbchan), GFP_ATOMIC); |
---|
| 252 | + if (!phi) |
---|
| 253 | + return -ENOMEM; |
---|
| 254 | + |
---|
267 | 255 | phi->dch.ch.protocol = hw->protocol; |
---|
268 | 256 | phi->dch.ch.Flags = dch->Flags; |
---|
269 | 257 | phi->dch.state = dch->state; |
---|
.. | .. |
---|
273 | 261 | phi->bch[i].Flags = hw->bch[i].Flags; |
---|
274 | 262 | } |
---|
275 | 263 | _queue_data(&dch->dev.D, MPH_INFORMATION_IND, MISDN_ID_ANY, |
---|
276 | | - sizeof(struct ph_info_dch) + dch->dev.nrbchan * |
---|
277 | | - sizeof(struct ph_info_ch), phi, GFP_ATOMIC); |
---|
| 264 | + struct_size(phi, bch, dch->dev.nrbchan), phi, GFP_ATOMIC); |
---|
278 | 265 | kfree(phi); |
---|
| 266 | + |
---|
| 267 | + return 0; |
---|
279 | 268 | } |
---|
280 | 269 | |
---|
281 | 270 | /* |
---|
.. | .. |
---|
337 | 326 | test_and_clear_bit(FLG_L2_ACTIVATED, &dch->Flags); |
---|
338 | 327 | |
---|
339 | 328 | if (hw->protocol == ISDN_P_NT_S0) { |
---|
| 329 | + struct sk_buff_head free_queue; |
---|
| 330 | + |
---|
| 331 | + __skb_queue_head_init(&free_queue); |
---|
340 | 332 | hfcsusb_ph_command(hw, HFC_L1_DEACTIVATE_NT); |
---|
341 | 333 | spin_lock_irqsave(&hw->lock, flags); |
---|
342 | | - skb_queue_purge(&dch->squeue); |
---|
| 334 | + skb_queue_splice_init(&dch->squeue, &free_queue); |
---|
343 | 335 | if (dch->tx_skb) { |
---|
344 | | - dev_kfree_skb(dch->tx_skb); |
---|
| 336 | + __skb_queue_tail(&free_queue, dch->tx_skb); |
---|
345 | 337 | dch->tx_skb = NULL; |
---|
346 | 338 | } |
---|
347 | 339 | dch->tx_idx = 0; |
---|
348 | 340 | if (dch->rx_skb) { |
---|
349 | | - dev_kfree_skb(dch->rx_skb); |
---|
| 341 | + __skb_queue_tail(&free_queue, dch->rx_skb); |
---|
350 | 342 | dch->rx_skb = NULL; |
---|
351 | 343 | } |
---|
352 | 344 | test_and_clear_bit(FLG_TX_BUSY, &dch->Flags); |
---|
353 | 345 | spin_unlock_irqrestore(&hw->lock, flags); |
---|
| 346 | + __skb_queue_purge(&free_queue); |
---|
354 | 347 | #ifdef FIXME |
---|
355 | 348 | if (test_and_clear_bit(FLG_L1_BUSY, &dch->Flags)) |
---|
356 | 349 | dchannel_sched_event(&hc->dch, D_CLEARBUSY); |
---|
.. | .. |
---|
360 | 353 | ret = l1_event(dch->l1, hh->prim); |
---|
361 | 354 | break; |
---|
362 | 355 | case MPH_INFORMATION_REQ: |
---|
363 | | - hfcsusb_ph_info(hw); |
---|
364 | | - ret = 0; |
---|
| 356 | + ret = hfcsusb_ph_info(hw); |
---|
365 | 357 | break; |
---|
366 | 358 | } |
---|
367 | 359 | |
---|
.. | .. |
---|
416 | 408 | hw->name, __func__, cmd); |
---|
417 | 409 | return -1; |
---|
418 | 410 | } |
---|
419 | | - hfcsusb_ph_info(hw); |
---|
420 | | - return 0; |
---|
| 411 | + return hfcsusb_ph_info(hw); |
---|
421 | 412 | } |
---|
422 | 413 | |
---|
423 | 414 | static int |
---|
.. | .. |
---|
708 | 699 | switch (protocol) { |
---|
709 | 700 | case (-1): /* used for init */ |
---|
710 | 701 | bch->state = -1; |
---|
711 | | - /* fall through */ |
---|
| 702 | + fallthrough; |
---|
712 | 703 | case (ISDN_P_NONE): |
---|
713 | 704 | if (bch->state == ISDN_P_NONE) |
---|
714 | 705 | return 0; /* already in idle state */ |
---|
.. | .. |
---|
759 | 750 | handle_led(hw, (bch->nr == 1) ? LED_B1_OFF : |
---|
760 | 751 | LED_B2_OFF); |
---|
761 | 752 | } |
---|
762 | | - hfcsusb_ph_info(hw); |
---|
763 | | - return 0; |
---|
| 753 | + return hfcsusb_ph_info(hw); |
---|
764 | 754 | } |
---|
765 | 755 | |
---|
766 | 756 | static void |
---|
.. | .. |
---|
853 | 843 | if (maxlen < 0) { |
---|
854 | 844 | if (rx_skb) |
---|
855 | 845 | skb_trim(rx_skb, 0); |
---|
856 | | - pr_warning("%s.B%d: No bufferspace for %d bytes\n", |
---|
857 | | - hw->name, fifo->bch->nr, len); |
---|
| 846 | + pr_warn("%s.B%d: No bufferspace for %d bytes\n", |
---|
| 847 | + hw->name, fifo->bch->nr, len); |
---|
858 | 848 | spin_unlock_irqrestore(&hw->lock, flags); |
---|
859 | 849 | return; |
---|
860 | 850 | } |
---|
.. | .. |
---|
1344 | 1334 | printk("\n"); |
---|
1345 | 1335 | } |
---|
1346 | 1336 | |
---|
1347 | | - dev_kfree_skb(tx_skb); |
---|
| 1337 | + dev_consume_skb_irq(tx_skb); |
---|
1348 | 1338 | tx_skb = NULL; |
---|
1349 | 1339 | if (fifo->dch && get_next_dframe(fifo->dch)) |
---|
1350 | 1340 | tx_skb = fifo->dch->tx_skb; |
---|