Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

USB: usbtmc: Fix reading stale status byte

The ioctl USBTMC488_IOCTL_READ_STB either returns a cached status byte
(STB) sent by the device due to a service request (SRQ) condition or
the STB obtained from a query to the device with a READ_STATUS_BYTE
control message.

When the query is interrupted by an SRQ message on the interrupt pipe,
the ioctl still returns the requested STB while the STB of the
out-of-band SRQ message is cached for the next call of this
ioctl. However the cached SRQ STB represents a state that was previous
to the last returned STB. Furthermore the cached SRQ STB can be stale
and not reflect the current state of the device.

The fixed ioctl now always reads the STB from the device and if the
associated file descriptor has the srq_asserted bit set it ors in the
RQS bit to the returned STB and clears the srq_asserted bit conformant
to subclass USB488 devices.

Tested-by: Jian-Wei Wu <jian-wei_wu@keysight.com>
Reviewed-by: Guido Kiener <guido.kiener@rohde-schwarz.com>
Signed-off-by: Dave Penkler <dpenkler@gmail.com>
Link: https://lore.kernel.org/r/20201215155621.9592-2-dpenkler@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Dave Penkler and committed by
Greg Kroah-Hartman
3c1037e2 894f1f4f

+25 -21
+25 -21
drivers/usb/class/usbtmc.c
··· 475 475 return usbtmc_ioctl_abort_bulk_out_tag(data, data->bTag_last_write); 476 476 } 477 477 478 - static int usbtmc488_ioctl_read_stb(struct usbtmc_file_data *file_data, 479 - void __user *arg) 478 + static int usbtmc_get_stb(struct usbtmc_file_data *file_data, __u8 *stb) 480 479 { 481 480 struct usbtmc_device_data *data = file_data->data; 482 481 struct device *dev = &data->intf->dev; 483 - int srq_asserted = 0; 484 482 u8 *buffer; 485 483 u8 tag; 486 - __u8 stb; 487 484 int rv; 488 485 489 486 dev_dbg(dev, "Enter ioctl_read_stb iin_ep_present: %d\n", 490 487 data->iin_ep_present); 491 - 492 - spin_lock_irq(&data->dev_lock); 493 - srq_asserted = atomic_xchg(&file_data->srq_asserted, srq_asserted); 494 - if (srq_asserted) { 495 - /* a STB with SRQ is already received */ 496 - stb = file_data->srq_byte; 497 - spin_unlock_irq(&data->dev_lock); 498 - rv = put_user(stb, (__u8 __user *)arg); 499 - dev_dbg(dev, "stb:0x%02x with srq received %d\n", 500 - (unsigned int)stb, rv); 501 - return rv; 502 - } 503 - spin_unlock_irq(&data->dev_lock); 504 488 505 489 buffer = kmalloc(8, GFP_KERNEL); 506 490 if (!buffer) ··· 532 548 data->iin_bTag, tag); 533 549 } 534 550 535 - stb = data->bNotify2; 551 + *stb = data->bNotify2; 536 552 } else { 537 - stb = buffer[2]; 553 + *stb = buffer[2]; 538 554 } 539 555 540 - rv = put_user(stb, (__u8 __user *)arg); 541 - dev_dbg(dev, "stb:0x%02x received %d\n", (unsigned int)stb, rv); 556 + dev_dbg(dev, "stb:0x%02x received %d\n", (unsigned int)*stb, rv); 542 557 543 558 exit: 544 559 /* bump interrupt bTag */ ··· 548 565 549 566 kfree(buffer); 550 567 return rv; 568 + } 569 + 570 + static int usbtmc488_ioctl_read_stb(struct usbtmc_file_data *file_data, 571 + void __user *arg) 572 + { 573 + int srq_asserted = 0; 574 + __u8 stb; 575 + int rv; 576 + 577 + rv = usbtmc_get_stb(file_data, &stb); 578 + 579 + if (rv > 0) { 580 + srq_asserted = atomic_xchg(&file_data->srq_asserted, 581 + srq_asserted); 582 + if (srq_asserted) 583 + stb |= 0x40; /* Set RQS bit */ 584 + 585 + rv = put_user(stb, (__u8 __user *)arg); 586 + } 587 + return rv; 588 + 551 589 } 552 590 553 591 static int usbtmc488_ioctl_wait_srq(struct usbtmc_file_data *file_data,