* [RFT] usb: class: cdc-wdm: switch to kfifo for buffering
@ 2026-04-30 12:18 Oliver Neukum
2026-05-04 15:54 ` kernel test robot
2026-05-04 20:37 ` kernel test robot
0 siblings, 2 replies; 3+ messages in thread
From: Oliver Neukum @ 2026-04-30 12:18 UTC (permalink / raw)
To: hanguidong02, linux-usb; +Cc: Oliver Neukum
The kfifo code is more efficient and takes care
of memory ordering without locking.
Signed-off-by: Oliver Neukum <oneukum@suse.com>
---
drivers/usb/class/cdc-wdm.c | 60 ++++++++++++++++++-------------------
1 file changed, 30 insertions(+), 30 deletions(-)
diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c
index 7556c0dac908..9185295f5376 100644
--- a/drivers/usb/class/cdc-wdm.c
+++ b/drivers/usb/class/cdc-wdm.c
@@ -27,6 +27,7 @@
#include <linux/wwan.h>
#include <asm/byteorder.h>
#include <linux/unaligned.h>
+#include <linux/kfifo.h>
#include <linux/usb/cdc-wdm.h>
#define DRIVER_AUTHOR "Oliver Neukum"
@@ -77,7 +78,8 @@ struct wdm_device {
u8 *inbuf; /* buffer for response */
u8 *outbuf; /* buffer for command */
u8 *sbuf; /* buffer for status */
- u8 *ubuf; /* buffer for copy to user space */
+
+ struct kfifo ubuf; /* payload */
struct urb *command;
struct urb *response;
@@ -92,7 +94,6 @@ struct wdm_device {
u16 wMaxCommand;
u16 wMaxPacketSize;
__le16 inum;
- int length;
int read;
int count;
dma_addr_t shandle;
@@ -170,6 +171,7 @@ static void wdm_in_callback(struct urb *urb)
struct wdm_device *desc = urb->context;
int status = urb->status;
int length = urb->actual_length;
+ int processed;
spin_lock_irqsave(&desc->iuspin, flags);
clear_bit(WDM_RESPONDING, &desc->flags);
@@ -218,17 +220,13 @@ static void wdm_in_callback(struct urb *urb)
goto skip_zlp;
}
- if (length + desc->length > desc->wMaxCommand) {
- /* The buffer would overflow */
- set_bit(WDM_OVERFLOW, &desc->flags);
- } else {
- /* we may already be in overflow */
- if (!test_bit(WDM_OVERFLOW, &desc->flags)) {
- memmove(desc->ubuf + desc->length, desc->inbuf, length);
- smp_wmb(); /* against wdm_read() */
- WRITE_ONCE(desc->length, desc->length + length);
- }
+ processed = kfifo_in(&desc->ubuf, desc->inbuf, length);
+ if (processed < length) {
+ set_bit(WDM_OVERFLOW, &desc->flags);
+ /* WDM_OVERFLOW must not be set after WDM_READ */
+ smp_wmb(); /* against wdm_read() */
}
+
skip_error:
if (desc->rerr) {
@@ -372,8 +370,8 @@ static void cleanup(struct wdm_device *desc)
kfree(desc->inbuf);
kfree(desc->orq);
kfree(desc->irq);
- kfree(desc->ubuf);
free_urbs(desc);
+ kfifo_free(&desc->ubuf);
kfree(desc);
}
@@ -524,7 +522,7 @@ static int service_outstanding_interrupt(struct wdm_device *desc)
static ssize_t wdm_read
(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
{
- int rv, cntr;
+ int rv, cntr, done;
int i = 0;
struct wdm_device *desc = file->private_data;
@@ -533,8 +531,7 @@ static ssize_t wdm_read
if (rv < 0)
return -ERESTARTSYS;
- cntr = READ_ONCE(desc->length);
- smp_rmb(); /* against wdm_in_callback() */
+ cntr = kfifo_len(&desc->ubuf);
if (cntr == 0) {
desc->read = 0;
retry:
@@ -568,6 +565,13 @@ static ssize_t wdm_read
rv = -EIO;
goto err;
}
+ smp_rmb(); /* against wdm_in_callback() */
+ if (test_bit(WDM_OVERFLOW, &desc->flags)) {
+ clear_bit(WDM_OVERFLOW, &desc->flags);
+ rv = -ENOBUFS;
+ goto err;
+ }
+
usb_mark_last_busy(interface_to_usbdev(desc->intf));
if (rv < 0) {
rv = -ERESTARTSYS;
@@ -591,31 +595,27 @@ static ssize_t wdm_read
goto retry;
}
- cntr = desc->length;
+ cntr = kfifo_len(&desc->ubuf);
spin_unlock_irq(&desc->iuspin);
}
if (cntr > count)
cntr = count;
- rv = copy_to_user(buffer, desc->ubuf, cntr);
- if (rv > 0) {
+ rv = kfifo_to_user(&desc->ubuf, buffer, cntr, &done);
+ if (rv < 0) {
rv = -EFAULT;
goto err;
}
spin_lock_irq(&desc->iuspin);
- for (i = 0; i < desc->length - cntr; i++)
- desc->ubuf[i] = desc->ubuf[i + cntr];
-
- desc->length -= cntr;
/* in case we had outstanding data */
- if (!desc->length) {
+ if (kfifo_is_empty(&desc->ubuf)) {
clear_bit(WDM_READ, &desc->flags);
service_outstanding_interrupt(desc);
}
spin_unlock_irq(&desc->iuspin);
- rv = cntr;
+ rv = done;
err:
mutex_unlock(&desc->rlock);
@@ -1013,7 +1013,7 @@ static void service_interrupt_work(struct work_struct *work)
spin_lock_irq(&desc->iuspin);
service_outstanding_interrupt(desc);
- if (!desc->resp_count && (desc->length || desc->rerr)) {
+ if (!desc->resp_count && (!kfifo_is_empty(&desc->ubuf) || desc->rerr)) {
set_bit(WDM_READ, &desc->flags);
wake_up(&desc->wait);
}
@@ -1071,10 +1071,6 @@ static int wdm_create(struct usb_interface *intf, struct usb_endpoint_descriptor
if (!desc->command)
goto err;
- desc->ubuf = kmalloc(desc->wMaxCommand, GFP_KERNEL);
- if (!desc->ubuf)
- goto err;
-
desc->sbuf = kmalloc(desc->wMaxPacketSize, GFP_KERNEL);
if (!desc->sbuf)
goto err;
@@ -1083,6 +1079,10 @@ static int wdm_create(struct usb_interface *intf, struct usb_endpoint_descriptor
if (!desc->inbuf)
goto err;
+ rv = kfifo_alloc(&desc->ubuf, roundup_pow_of_two(desc->wMaxCommand), GFP_KERNEL);
+ if (rv < 0)
+ goto err;
+
usb_fill_int_urb(
desc->validity,
interface_to_usbdev(intf),
--
2.54.0
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [RFT] usb: class: cdc-wdm: switch to kfifo for buffering
2026-04-30 12:18 [RFT] usb: class: cdc-wdm: switch to kfifo for buffering Oliver Neukum
@ 2026-05-04 15:54 ` kernel test robot
2026-05-04 20:37 ` kernel test robot
1 sibling, 0 replies; 3+ messages in thread
From: kernel test robot @ 2026-05-04 15:54 UTC (permalink / raw)
To: Oliver Neukum, hanguidong02, linux-usb; +Cc: llvm, oe-kbuild-all, Oliver Neukum
Hi Oliver,
kernel test robot noticed the following build warnings:
[auto build test WARNING on usb/usb-testing]
[also build test WARNING on usb/usb-next usb/usb-linus westeri-thunderbolt/next linus/master v7.1-rc2 next-20260430]
[cannot apply to peter-chen-usb/for-usb-next]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Oliver-Neukum/usb-class-cdc-wdm-switch-to-kfifo-for-buffering/20260504-164851
base: https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git usb-testing
patch link: https://lore.kernel.org/r/20260430121859.1018894-1-oneukum%40suse.com
patch subject: [RFT] usb: class: cdc-wdm: switch to kfifo for buffering
config: arm-randconfig-004-20260504 (https://download.01.org/0day-ci/archive/20260504/202605042331.sI8rgflD-lkp@intel.com/config)
compiler: clang version 23.0.0git (https://github.com/llvm/llvm-project 5bac06718f502014fade905512f1d26d578a18f3)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260504/202605042331.sI8rgflD-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202605042331.sI8rgflD-lkp@intel.com/
All warnings (new ones prefixed by >>):
>> drivers/usb/class/cdc-wdm.c:526:6: warning: variable 'i' set but not used [-Wunused-but-set-variable]
526 | int i = 0;
| ^
1 warning generated.
vim +/i +526 drivers/usb/class/cdc-wdm.c
8dd5cd5395b9007 Bjørn Mork 2013-12-20 521
afba937e540c902 Oliver Neukum 2008-05-13 522 static ssize_t wdm_read
afba937e540c902 Oliver Neukum 2008-05-13 523 (struct file *file, char __user *buffer, size_t count, loff_t *ppos)
afba937e540c902 Oliver Neukum 2008-05-13 524 {
055e352971719f8 Oliver Neukum 2026-04-30 525 int rv, cntr, done;
afba937e540c902 Oliver Neukum 2008-05-13 @526 int i = 0;
afba937e540c902 Oliver Neukum 2008-05-13 527 struct wdm_device *desc = file->private_data;
afba937e540c902 Oliver Neukum 2008-05-13 528
afba937e540c902 Oliver Neukum 2008-05-13 529
e8537bd2c4f325a Bjørn Mork 2012-01-16 530 rv = mutex_lock_interruptible(&desc->rlock); /*concurrent reads */
afba937e540c902 Oliver Neukum 2008-05-13 531 if (rv < 0)
afba937e540c902 Oliver Neukum 2008-05-13 532 return -ERESTARTSYS;
afba937e540c902 Oliver Neukum 2008-05-13 533
055e352971719f8 Oliver Neukum 2026-04-30 534 cntr = kfifo_len(&desc->ubuf);
711c68b3c0f7a92 Ben Hutchings 2012-02-12 535 if (cntr == 0) {
afba937e540c902 Oliver Neukum 2008-05-13 536 desc->read = 0;
afba937e540c902 Oliver Neukum 2008-05-13 537 retry:
7f1dc313d01f5f0 Oliver Neukum 2009-09-09 538 if (test_bit(WDM_DISCONNECTING, &desc->flags)) {
7f1dc313d01f5f0 Oliver Neukum 2009-09-09 539 rv = -ENODEV;
7f1dc313d01f5f0 Oliver Neukum 2009-09-09 540 goto err;
7f1dc313d01f5f0 Oliver Neukum 2009-09-09 541 }
c0f5ecee4e74166 Oliver Neukum 2013-03-12 542 if (test_bit(WDM_OVERFLOW, &desc->flags)) {
c0f5ecee4e74166 Oliver Neukum 2013-03-12 543 clear_bit(WDM_OVERFLOW, &desc->flags);
c0f5ecee4e74166 Oliver Neukum 2013-03-12 544 rv = -ENOBUFS;
c0f5ecee4e74166 Oliver Neukum 2013-03-12 545 goto err;
c0f5ecee4e74166 Oliver Neukum 2013-03-12 546 }
afba937e540c902 Oliver Neukum 2008-05-13 547 i++;
7f1dc313d01f5f0 Oliver Neukum 2009-09-09 548 if (file->f_flags & O_NONBLOCK) {
7f1dc313d01f5f0 Oliver Neukum 2009-09-09 549 if (!test_bit(WDM_READ, &desc->flags)) {
53b7f7b53d83727 Gustavo A. R. Silva 2017-02-14 550 rv = -EAGAIN;
7f1dc313d01f5f0 Oliver Neukum 2009-09-09 551 goto err;
7f1dc313d01f5f0 Oliver Neukum 2009-09-09 552 }
7f1dc313d01f5f0 Oliver Neukum 2009-09-09 553 rv = 0;
7f1dc313d01f5f0 Oliver Neukum 2009-09-09 554 } else {
afba937e540c902 Oliver Neukum 2008-05-13 555 rv = wait_event_interruptible(desc->wait,
afba937e540c902 Oliver Neukum 2008-05-13 556 test_bit(WDM_READ, &desc->flags));
7f1dc313d01f5f0 Oliver Neukum 2009-09-09 557 }
afba937e540c902 Oliver Neukum 2008-05-13 558
7f1dc313d01f5f0 Oliver Neukum 2009-09-09 559 /* may have happened while we slept */
17d80d562fd78a0 Oliver Neukum 2008-06-24 560 if (test_bit(WDM_DISCONNECTING, &desc->flags)) {
17d80d562fd78a0 Oliver Neukum 2008-06-24 561 rv = -ENODEV;
17d80d562fd78a0 Oliver Neukum 2008-06-24 562 goto err;
17d80d562fd78a0 Oliver Neukum 2008-06-24 563 }
88044202756925a Bjørn Mork 2012-02-10 564 if (test_bit(WDM_RESETTING, &desc->flags)) {
88044202756925a Bjørn Mork 2012-02-10 565 rv = -EIO;
88044202756925a Bjørn Mork 2012-02-10 566 goto err;
88044202756925a Bjørn Mork 2012-02-10 567 }
055e352971719f8 Oliver Neukum 2026-04-30 568 smp_rmb(); /* against wdm_in_callback() */
055e352971719f8 Oliver Neukum 2026-04-30 569 if (test_bit(WDM_OVERFLOW, &desc->flags)) {
055e352971719f8 Oliver Neukum 2026-04-30 570 clear_bit(WDM_OVERFLOW, &desc->flags);
055e352971719f8 Oliver Neukum 2026-04-30 571 rv = -ENOBUFS;
055e352971719f8 Oliver Neukum 2026-04-30 572 goto err;
055e352971719f8 Oliver Neukum 2026-04-30 573 }
055e352971719f8 Oliver Neukum 2026-04-30 574
17d80d562fd78a0 Oliver Neukum 2008-06-24 575 usb_mark_last_busy(interface_to_usbdev(desc->intf));
afba937e540c902 Oliver Neukum 2008-05-13 576 if (rv < 0) {
afba937e540c902 Oliver Neukum 2008-05-13 577 rv = -ERESTARTSYS;
afba937e540c902 Oliver Neukum 2008-05-13 578 goto err;
afba937e540c902 Oliver Neukum 2008-05-13 579 }
afba937e540c902 Oliver Neukum 2008-05-13 580
afba937e540c902 Oliver Neukum 2008-05-13 581 spin_lock_irq(&desc->iuspin);
afba937e540c902 Oliver Neukum 2008-05-13 582
afba937e540c902 Oliver Neukum 2008-05-13 583 if (desc->rerr) { /* read completed, error happened */
85e8a0b9a3565c8 Oliver Neukum 2015-03-23 584 rv = usb_translate_errors(desc->rerr);
afba937e540c902 Oliver Neukum 2008-05-13 585 desc->rerr = 0;
afba937e540c902 Oliver Neukum 2008-05-13 586 spin_unlock_irq(&desc->iuspin);
afba937e540c902 Oliver Neukum 2008-05-13 587 goto err;
afba937e540c902 Oliver Neukum 2008-05-13 588 }
afba937e540c902 Oliver Neukum 2008-05-13 589 /*
afba937e540c902 Oliver Neukum 2008-05-13 590 * recheck whether we've lost the race
afba937e540c902 Oliver Neukum 2008-05-13 591 * against the completion handler
afba937e540c902 Oliver Neukum 2008-05-13 592 */
afba937e540c902 Oliver Neukum 2008-05-13 593 if (!test_bit(WDM_READ, &desc->flags)) { /* lost race */
afba937e540c902 Oliver Neukum 2008-05-13 594 spin_unlock_irq(&desc->iuspin);
afba937e540c902 Oliver Neukum 2008-05-13 595 goto retry;
afba937e540c902 Oliver Neukum 2008-05-13 596 }
c0f5ecee4e74166 Oliver Neukum 2013-03-12 597
055e352971719f8 Oliver Neukum 2026-04-30 598 cntr = kfifo_len(&desc->ubuf);
afba937e540c902 Oliver Neukum 2008-05-13 599 spin_unlock_irq(&desc->iuspin);
afba937e540c902 Oliver Neukum 2008-05-13 600 }
afba937e540c902 Oliver Neukum 2008-05-13 601
711c68b3c0f7a92 Ben Hutchings 2012-02-12 602 if (cntr > count)
711c68b3c0f7a92 Ben Hutchings 2012-02-12 603 cntr = count;
055e352971719f8 Oliver Neukum 2026-04-30 604 rv = kfifo_to_user(&desc->ubuf, buffer, cntr, &done);
055e352971719f8 Oliver Neukum 2026-04-30 605 if (rv < 0) {
afba937e540c902 Oliver Neukum 2008-05-13 606 rv = -EFAULT;
afba937e540c902 Oliver Neukum 2008-05-13 607 goto err;
afba937e540c902 Oliver Neukum 2008-05-13 608 }
afba937e540c902 Oliver Neukum 2008-05-13 609
711c68b3c0f7a92 Ben Hutchings 2012-02-12 610 spin_lock_irq(&desc->iuspin);
711c68b3c0f7a92 Ben Hutchings 2012-02-12 611
87d65e54b6d5ff6 Oliver Neukum 2008-06-19 612 /* in case we had outstanding data */
055e352971719f8 Oliver Neukum 2026-04-30 613 if (kfifo_is_empty(&desc->ubuf)) {
c1da59dad0ebd3f Robert Foss 2016-08-09 614 clear_bit(WDM_READ, &desc->flags);
c1da59dad0ebd3f Robert Foss 2016-08-09 615 service_outstanding_interrupt(desc);
c1da59dad0ebd3f Robert Foss 2016-08-09 616 }
73e06865ead1bec Greg Suarez 2013-10-29 617 spin_unlock_irq(&desc->iuspin);
055e352971719f8 Oliver Neukum 2026-04-30 618 rv = done;
afba937e540c902 Oliver Neukum 2008-05-13 619
afba937e540c902 Oliver Neukum 2008-05-13 620 err:
e8537bd2c4f325a Bjørn Mork 2012-01-16 621 mutex_unlock(&desc->rlock);
afba937e540c902 Oliver Neukum 2008-05-13 622 return rv;
afba937e540c902 Oliver Neukum 2008-05-13 623 }
afba937e540c902 Oliver Neukum 2008-05-13 624
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [RFT] usb: class: cdc-wdm: switch to kfifo for buffering
2026-04-30 12:18 [RFT] usb: class: cdc-wdm: switch to kfifo for buffering Oliver Neukum
2026-05-04 15:54 ` kernel test robot
@ 2026-05-04 20:37 ` kernel test robot
1 sibling, 0 replies; 3+ messages in thread
From: kernel test robot @ 2026-05-04 20:37 UTC (permalink / raw)
To: Oliver Neukum, hanguidong02, linux-usb; +Cc: llvm, oe-kbuild-all, Oliver Neukum
Hi Oliver,
kernel test robot noticed the following build warnings:
[auto build test WARNING on usb/usb-testing]
[also build test WARNING on usb/usb-next usb/usb-linus westeri-thunderbolt/next next-20260430]
[cannot apply to peter-chen-usb/for-usb-next linus/master v6.16-rc1]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Oliver-Neukum/usb-class-cdc-wdm-switch-to-kfifo-for-buffering/20260504-164851
base: https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git usb-testing
patch link: https://lore.kernel.org/r/20260430121859.1018894-1-oneukum%40suse.com
patch subject: [RFT] usb: class: cdc-wdm: switch to kfifo for buffering
config: x86_64-kexec (https://download.01.org/0day-ci/archive/20260504/202605042206.Ybpa1c91-lkp@intel.com/config)
compiler: clang version 20.1.8 (https://github.com/llvm/llvm-project 87f0227cb60147a26a1eeb4fb06e3b505e9c7261)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260504/202605042206.Ybpa1c91-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202605042206.Ybpa1c91-lkp@intel.com/
All warnings (new ones prefixed by >>):
>> drivers/usb/class/cdc-wdm.c:526:6: warning: variable 'i' set but not used [-Wunused-but-set-variable]
526 | int i = 0;
| ^
1 warning generated.
vim +/i +526 drivers/usb/class/cdc-wdm.c
8dd5cd5395b900 Bjørn Mork 2013-12-20 521
afba937e540c90 Oliver Neukum 2008-05-13 522 static ssize_t wdm_read
afba937e540c90 Oliver Neukum 2008-05-13 523 (struct file *file, char __user *buffer, size_t count, loff_t *ppos)
afba937e540c90 Oliver Neukum 2008-05-13 524 {
055e352971719f Oliver Neukum 2026-04-30 525 int rv, cntr, done;
afba937e540c90 Oliver Neukum 2008-05-13 @526 int i = 0;
afba937e540c90 Oliver Neukum 2008-05-13 527 struct wdm_device *desc = file->private_data;
afba937e540c90 Oliver Neukum 2008-05-13 528
afba937e540c90 Oliver Neukum 2008-05-13 529
e8537bd2c4f325 Bjørn Mork 2012-01-16 530 rv = mutex_lock_interruptible(&desc->rlock); /*concurrent reads */
afba937e540c90 Oliver Neukum 2008-05-13 531 if (rv < 0)
afba937e540c90 Oliver Neukum 2008-05-13 532 return -ERESTARTSYS;
afba937e540c90 Oliver Neukum 2008-05-13 533
055e352971719f Oliver Neukum 2026-04-30 534 cntr = kfifo_len(&desc->ubuf);
711c68b3c0f7a9 Ben Hutchings 2012-02-12 535 if (cntr == 0) {
afba937e540c90 Oliver Neukum 2008-05-13 536 desc->read = 0;
afba937e540c90 Oliver Neukum 2008-05-13 537 retry:
7f1dc313d01f5f Oliver Neukum 2009-09-09 538 if (test_bit(WDM_DISCONNECTING, &desc->flags)) {
7f1dc313d01f5f Oliver Neukum 2009-09-09 539 rv = -ENODEV;
7f1dc313d01f5f Oliver Neukum 2009-09-09 540 goto err;
7f1dc313d01f5f Oliver Neukum 2009-09-09 541 }
c0f5ecee4e7416 Oliver Neukum 2013-03-12 542 if (test_bit(WDM_OVERFLOW, &desc->flags)) {
c0f5ecee4e7416 Oliver Neukum 2013-03-12 543 clear_bit(WDM_OVERFLOW, &desc->flags);
c0f5ecee4e7416 Oliver Neukum 2013-03-12 544 rv = -ENOBUFS;
c0f5ecee4e7416 Oliver Neukum 2013-03-12 545 goto err;
c0f5ecee4e7416 Oliver Neukum 2013-03-12 546 }
afba937e540c90 Oliver Neukum 2008-05-13 547 i++;
7f1dc313d01f5f Oliver Neukum 2009-09-09 548 if (file->f_flags & O_NONBLOCK) {
7f1dc313d01f5f Oliver Neukum 2009-09-09 549 if (!test_bit(WDM_READ, &desc->flags)) {
53b7f7b53d8372 Gustavo A. R. Silva 2017-02-14 550 rv = -EAGAIN;
7f1dc313d01f5f Oliver Neukum 2009-09-09 551 goto err;
7f1dc313d01f5f Oliver Neukum 2009-09-09 552 }
7f1dc313d01f5f Oliver Neukum 2009-09-09 553 rv = 0;
7f1dc313d01f5f Oliver Neukum 2009-09-09 554 } else {
afba937e540c90 Oliver Neukum 2008-05-13 555 rv = wait_event_interruptible(desc->wait,
afba937e540c90 Oliver Neukum 2008-05-13 556 test_bit(WDM_READ, &desc->flags));
7f1dc313d01f5f Oliver Neukum 2009-09-09 557 }
afba937e540c90 Oliver Neukum 2008-05-13 558
7f1dc313d01f5f Oliver Neukum 2009-09-09 559 /* may have happened while we slept */
17d80d562fd78a Oliver Neukum 2008-06-24 560 if (test_bit(WDM_DISCONNECTING, &desc->flags)) {
17d80d562fd78a Oliver Neukum 2008-06-24 561 rv = -ENODEV;
17d80d562fd78a Oliver Neukum 2008-06-24 562 goto err;
17d80d562fd78a Oliver Neukum 2008-06-24 563 }
88044202756925 Bjørn Mork 2012-02-10 564 if (test_bit(WDM_RESETTING, &desc->flags)) {
88044202756925 Bjørn Mork 2012-02-10 565 rv = -EIO;
88044202756925 Bjørn Mork 2012-02-10 566 goto err;
88044202756925 Bjørn Mork 2012-02-10 567 }
055e352971719f Oliver Neukum 2026-04-30 568 smp_rmb(); /* against wdm_in_callback() */
055e352971719f Oliver Neukum 2026-04-30 569 if (test_bit(WDM_OVERFLOW, &desc->flags)) {
055e352971719f Oliver Neukum 2026-04-30 570 clear_bit(WDM_OVERFLOW, &desc->flags);
055e352971719f Oliver Neukum 2026-04-30 571 rv = -ENOBUFS;
055e352971719f Oliver Neukum 2026-04-30 572 goto err;
055e352971719f Oliver Neukum 2026-04-30 573 }
055e352971719f Oliver Neukum 2026-04-30 574
17d80d562fd78a Oliver Neukum 2008-06-24 575 usb_mark_last_busy(interface_to_usbdev(desc->intf));
afba937e540c90 Oliver Neukum 2008-05-13 576 if (rv < 0) {
afba937e540c90 Oliver Neukum 2008-05-13 577 rv = -ERESTARTSYS;
afba937e540c90 Oliver Neukum 2008-05-13 578 goto err;
afba937e540c90 Oliver Neukum 2008-05-13 579 }
afba937e540c90 Oliver Neukum 2008-05-13 580
afba937e540c90 Oliver Neukum 2008-05-13 581 spin_lock_irq(&desc->iuspin);
afba937e540c90 Oliver Neukum 2008-05-13 582
afba937e540c90 Oliver Neukum 2008-05-13 583 if (desc->rerr) { /* read completed, error happened */
85e8a0b9a3565c Oliver Neukum 2015-03-23 584 rv = usb_translate_errors(desc->rerr);
afba937e540c90 Oliver Neukum 2008-05-13 585 desc->rerr = 0;
afba937e540c90 Oliver Neukum 2008-05-13 586 spin_unlock_irq(&desc->iuspin);
afba937e540c90 Oliver Neukum 2008-05-13 587 goto err;
afba937e540c90 Oliver Neukum 2008-05-13 588 }
afba937e540c90 Oliver Neukum 2008-05-13 589 /*
afba937e540c90 Oliver Neukum 2008-05-13 590 * recheck whether we've lost the race
afba937e540c90 Oliver Neukum 2008-05-13 591 * against the completion handler
afba937e540c90 Oliver Neukum 2008-05-13 592 */
afba937e540c90 Oliver Neukum 2008-05-13 593 if (!test_bit(WDM_READ, &desc->flags)) { /* lost race */
afba937e540c90 Oliver Neukum 2008-05-13 594 spin_unlock_irq(&desc->iuspin);
afba937e540c90 Oliver Neukum 2008-05-13 595 goto retry;
afba937e540c90 Oliver Neukum 2008-05-13 596 }
c0f5ecee4e7416 Oliver Neukum 2013-03-12 597
055e352971719f Oliver Neukum 2026-04-30 598 cntr = kfifo_len(&desc->ubuf);
afba937e540c90 Oliver Neukum 2008-05-13 599 spin_unlock_irq(&desc->iuspin);
afba937e540c90 Oliver Neukum 2008-05-13 600 }
afba937e540c90 Oliver Neukum 2008-05-13 601
711c68b3c0f7a9 Ben Hutchings 2012-02-12 602 if (cntr > count)
711c68b3c0f7a9 Ben Hutchings 2012-02-12 603 cntr = count;
055e352971719f Oliver Neukum 2026-04-30 604 rv = kfifo_to_user(&desc->ubuf, buffer, cntr, &done);
055e352971719f Oliver Neukum 2026-04-30 605 if (rv < 0) {
afba937e540c90 Oliver Neukum 2008-05-13 606 rv = -EFAULT;
afba937e540c90 Oliver Neukum 2008-05-13 607 goto err;
afba937e540c90 Oliver Neukum 2008-05-13 608 }
afba937e540c90 Oliver Neukum 2008-05-13 609
711c68b3c0f7a9 Ben Hutchings 2012-02-12 610 spin_lock_irq(&desc->iuspin);
711c68b3c0f7a9 Ben Hutchings 2012-02-12 611
87d65e54b6d5ff Oliver Neukum 2008-06-19 612 /* in case we had outstanding data */
055e352971719f Oliver Neukum 2026-04-30 613 if (kfifo_is_empty(&desc->ubuf)) {
c1da59dad0ebd3 Robert Foss 2016-08-09 614 clear_bit(WDM_READ, &desc->flags);
c1da59dad0ebd3 Robert Foss 2016-08-09 615 service_outstanding_interrupt(desc);
c1da59dad0ebd3 Robert Foss 2016-08-09 616 }
73e06865ead1be Greg Suarez 2013-10-29 617 spin_unlock_irq(&desc->iuspin);
055e352971719f Oliver Neukum 2026-04-30 618 rv = done;
afba937e540c90 Oliver Neukum 2008-05-13 619
afba937e540c90 Oliver Neukum 2008-05-13 620 err:
e8537bd2c4f325 Bjørn Mork 2012-01-16 621 mutex_unlock(&desc->rlock);
afba937e540c90 Oliver Neukum 2008-05-13 622 return rv;
afba937e540c90 Oliver Neukum 2008-05-13 623 }
afba937e540c90 Oliver Neukum 2008-05-13 624
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-05-04 20:38 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-30 12:18 [RFT] usb: class: cdc-wdm: switch to kfifo for buffering Oliver Neukum
2026-05-04 15:54 ` kernel test robot
2026-05-04 20:37 ` kernel test robot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox