mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-05-24 10:39:52 +00:00
Merge branch 'for-5.15/core' into for-linus
- Regression fix for an issue in HID core that got uncovered by recent USB core cleanup leading to issues when transfer_buffer_length is not in line with wLength - Memory leak fix in USB HID core - Improvement of stylus battery reporting
This commit is contained in:
commit
dab6e4f452
2 changed files with 18 additions and 13 deletions
|
@ -419,8 +419,6 @@ static int hidinput_get_battery_property(struct power_supply *psy,
|
||||||
|
|
||||||
if (dev->battery_status == HID_BATTERY_UNKNOWN)
|
if (dev->battery_status == HID_BATTERY_UNKNOWN)
|
||||||
val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
|
val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
|
||||||
else if (dev->battery_capacity == 100)
|
|
||||||
val->intval = POWER_SUPPLY_STATUS_FULL;
|
|
||||||
else
|
else
|
||||||
val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
|
val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -377,27 +377,23 @@ static int hid_submit_ctrl(struct hid_device *hid)
|
||||||
len = hid_report_len(report);
|
len = hid_report_len(report);
|
||||||
if (dir == USB_DIR_OUT) {
|
if (dir == USB_DIR_OUT) {
|
||||||
usbhid->urbctrl->pipe = usb_sndctrlpipe(hid_to_usb_dev(hid), 0);
|
usbhid->urbctrl->pipe = usb_sndctrlpipe(hid_to_usb_dev(hid), 0);
|
||||||
usbhid->urbctrl->transfer_buffer_length = len;
|
|
||||||
if (raw_report) {
|
if (raw_report) {
|
||||||
memcpy(usbhid->ctrlbuf, raw_report, len);
|
memcpy(usbhid->ctrlbuf, raw_report, len);
|
||||||
kfree(raw_report);
|
kfree(raw_report);
|
||||||
usbhid->ctrl[usbhid->ctrltail].raw_report = NULL;
|
usbhid->ctrl[usbhid->ctrltail].raw_report = NULL;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int maxpacket, padlen;
|
int maxpacket;
|
||||||
|
|
||||||
usbhid->urbctrl->pipe = usb_rcvctrlpipe(hid_to_usb_dev(hid), 0);
|
usbhid->urbctrl->pipe = usb_rcvctrlpipe(hid_to_usb_dev(hid), 0);
|
||||||
maxpacket = usb_maxpacket(hid_to_usb_dev(hid),
|
maxpacket = usb_maxpacket(hid_to_usb_dev(hid),
|
||||||
usbhid->urbctrl->pipe, 0);
|
usbhid->urbctrl->pipe, 0);
|
||||||
if (maxpacket > 0) {
|
len += (len == 0); /* Don't allow 0-length reports */
|
||||||
padlen = DIV_ROUND_UP(len, maxpacket);
|
len = round_up(len, maxpacket);
|
||||||
padlen *= maxpacket;
|
if (len > usbhid->bufsize)
|
||||||
if (padlen > usbhid->bufsize)
|
len = usbhid->bufsize;
|
||||||
padlen = usbhid->bufsize;
|
|
||||||
} else
|
|
||||||
padlen = 0;
|
|
||||||
usbhid->urbctrl->transfer_buffer_length = padlen;
|
|
||||||
}
|
}
|
||||||
|
usbhid->urbctrl->transfer_buffer_length = len;
|
||||||
usbhid->urbctrl->dev = hid_to_usb_dev(hid);
|
usbhid->urbctrl->dev = hid_to_usb_dev(hid);
|
||||||
|
|
||||||
usbhid->cr->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE | dir;
|
usbhid->cr->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE | dir;
|
||||||
|
@ -505,7 +501,7 @@ static void hid_ctrl(struct urb *urb)
|
||||||
|
|
||||||
if (unplug) {
|
if (unplug) {
|
||||||
usbhid->ctrltail = usbhid->ctrlhead;
|
usbhid->ctrltail = usbhid->ctrlhead;
|
||||||
} else {
|
} else if (usbhid->ctrlhead != usbhid->ctrltail) {
|
||||||
usbhid->ctrltail = (usbhid->ctrltail + 1) & (HID_CONTROL_FIFO_SIZE - 1);
|
usbhid->ctrltail = (usbhid->ctrltail + 1) & (HID_CONTROL_FIFO_SIZE - 1);
|
||||||
|
|
||||||
if (usbhid->ctrlhead != usbhid->ctrltail &&
|
if (usbhid->ctrlhead != usbhid->ctrltail &&
|
||||||
|
@ -1223,9 +1219,20 @@ static void usbhid_stop(struct hid_device *hid)
|
||||||
mutex_lock(&usbhid->mutex);
|
mutex_lock(&usbhid->mutex);
|
||||||
|
|
||||||
clear_bit(HID_STARTED, &usbhid->iofl);
|
clear_bit(HID_STARTED, &usbhid->iofl);
|
||||||
|
|
||||||
spin_lock_irq(&usbhid->lock); /* Sync with error and led handlers */
|
spin_lock_irq(&usbhid->lock); /* Sync with error and led handlers */
|
||||||
set_bit(HID_DISCONNECTED, &usbhid->iofl);
|
set_bit(HID_DISCONNECTED, &usbhid->iofl);
|
||||||
|
while (usbhid->ctrltail != usbhid->ctrlhead) {
|
||||||
|
if (usbhid->ctrl[usbhid->ctrltail].dir == USB_DIR_OUT) {
|
||||||
|
kfree(usbhid->ctrl[usbhid->ctrltail].raw_report);
|
||||||
|
usbhid->ctrl[usbhid->ctrltail].raw_report = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
usbhid->ctrltail = (usbhid->ctrltail + 1) &
|
||||||
|
(HID_CONTROL_FIFO_SIZE - 1);
|
||||||
|
}
|
||||||
spin_unlock_irq(&usbhid->lock);
|
spin_unlock_irq(&usbhid->lock);
|
||||||
|
|
||||||
usb_kill_urb(usbhid->urbin);
|
usb_kill_urb(usbhid->urbin);
|
||||||
usb_kill_urb(usbhid->urbout);
|
usb_kill_urb(usbhid->urbout);
|
||||||
usb_kill_urb(usbhid->urbctrl);
|
usb_kill_urb(usbhid->urbctrl);
|
||||||
|
|
Loading…
Add table
Reference in a new issue