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

HID: put usb_interface instead of usb_device into hid->dev to fix udevinfo breakage

The commit 4916b3a57fc94664677d439b911b8aaf86c7ec23 introduced a
hid regression between 2.6.19 and 2.6.20-rc1. The device put in
input_dev->cdev is now of type usb_device instead of usb_interface.

Before:
> # readlink -f /sys/class/input/input6/event4/device
> /sys/devices/pci0000:00/0000:00:10.0/usb2/2-1/2-1:1.1
After:
> # readlink -f /sys/class/input/input3/event3/device
> /sys/devices/pci0000:00/0000:00:10.0/usb1/1-1

This causes breakage:
> # udevinfo -q all -n /dev/input/event3
> P: /class/input/input3/event3
> N: input/event3
> S: input/by-path/pci-1-1--event-
> E: ID_SERIAL=noserial
> E: ID_PATH=pci-1-1-

No ID_MODEL, ID_VENDOR, ID_REVISION, ID_TYPE etc etc.

Fix this by assigning the intf->dev into hid->dev, and fixing
all the users.

Signed-off-by: Anssi Hannula <anssi.hannula@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>

authored by

Anssi Hannula and committed by
Jiri Kosina
be820975 f7ebf99e

+22 -18
+15 -15
drivers/usb/input/hid-core.c
··· 106 106 107 107 if (test_bit(HID_CLEAR_HALT, &usbhid->iofl)) { 108 108 dev_dbg(&usbhid->intf->dev, "clear halt\n"); 109 - rc = usb_clear_halt(to_usb_device(hid->dev), usbhid->urbin->pipe); 109 + rc = usb_clear_halt(hid_to_usb_dev(hid), usbhid->urbin->pipe); 110 110 clear_bit(HID_CLEAR_HALT, &usbhid->iofl); 111 111 hid_start_in(hid); 112 112 } 113 113 114 114 else if (test_bit(HID_RESET_PENDING, &usbhid->iofl)) { 115 115 dev_dbg(&usbhid->intf->dev, "resetting device\n"); 116 - rc = rc_lock = usb_lock_device_for_reset(to_usb_device(hid->dev), usbhid->intf); 116 + rc = rc_lock = usb_lock_device_for_reset(hid_to_usb_dev(hid), usbhid->intf); 117 117 if (rc_lock >= 0) { 118 - rc = usb_reset_composite_device(to_usb_device(hid->dev), usbhid->intf); 118 + rc = usb_reset_composite_device(hid_to_usb_dev(hid), usbhid->intf); 119 119 if (rc_lock) 120 - usb_unlock_device(to_usb_device(hid->dev)); 120 + usb_unlock_device(hid_to_usb_dev(hid)); 121 121 } 122 122 clear_bit(HID_RESET_PENDING, &usbhid->iofl); 123 123 } ··· 129 129 break; 130 130 default: 131 131 err("can't reset device, %s-%s/input%d, status %d", 132 - to_usb_device(hid->dev)->bus->bus_name, 133 - to_usb_device(hid->dev)->devpath, 132 + hid_to_usb_dev(hid)->bus->bus_name, 133 + hid_to_usb_dev(hid)->devpath, 134 134 usbhid->ifnum, rc); 135 135 /* FALLTHROUGH */ 136 136 case -EHOSTUNREACH: ··· 217 217 clear_bit(HID_IN_RUNNING, &usbhid->iofl); 218 218 if (status != -EPERM) { 219 219 err("can't resubmit intr, %s-%s/input%d, status %d", 220 - to_usb_device(hid->dev)->bus->bus_name, 221 - to_usb_device(hid->dev)->devpath, 220 + hid_to_usb_dev(hid)->bus->bus_name, 221 + hid_to_usb_dev(hid)->devpath, 222 222 usbhid->ifnum, status); 223 223 hid_io_error(hid); 224 224 } ··· 251 251 252 252 hid_output_report(report, usbhid->outbuf); 253 253 usbhid->urbout->transfer_buffer_length = ((report->size - 1) >> 3) + 1 + (report->id > 0); 254 - usbhid->urbout->dev = to_usb_device(hid->dev); 254 + usbhid->urbout->dev = hid_to_usb_dev(hid); 255 255 256 256 dbg("submitting out urb"); 257 257 ··· 276 276 len = ((report->size - 1) >> 3) + 1 + (report->id > 0); 277 277 if (dir == USB_DIR_OUT) { 278 278 hid_output_report(report, usbhid->ctrlbuf); 279 - usbhid->urbctrl->pipe = usb_sndctrlpipe(to_usb_device(hid->dev), 0); 279 + usbhid->urbctrl->pipe = usb_sndctrlpipe(hid_to_usb_dev(hid), 0); 280 280 usbhid->urbctrl->transfer_buffer_length = len; 281 281 } else { 282 282 int maxpacket, padlen; 283 283 284 - usbhid->urbctrl->pipe = usb_rcvctrlpipe(to_usb_device(hid->dev), 0); 285 - maxpacket = usb_maxpacket(to_usb_device(hid->dev), usbhid->urbctrl->pipe, 0); 284 + usbhid->urbctrl->pipe = usb_rcvctrlpipe(hid_to_usb_dev(hid), 0); 285 + maxpacket = usb_maxpacket(hid_to_usb_dev(hid), usbhid->urbctrl->pipe, 0); 286 286 if (maxpacket > 0) { 287 287 padlen = (len + maxpacket - 1) / maxpacket; 288 288 padlen *= maxpacket; ··· 292 292 padlen = 0; 293 293 usbhid->urbctrl->transfer_buffer_length = padlen; 294 294 } 295 - usbhid->urbctrl->dev = to_usb_device(hid->dev); 295 + usbhid->urbctrl->dev = hid_to_usb_dev(hid); 296 296 297 297 usbhid->cr->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE | dir; 298 298 usbhid->cr->bRequest = (dir == USB_DIR_OUT) ? HID_REQ_SET_REPORT : HID_REQ_GET_REPORT; ··· 1187 1187 1188 1188 hid->version = le16_to_cpu(hdesc->bcdHID); 1189 1189 hid->country = hdesc->bCountryCode; 1190 - hid->dev = &dev->dev; 1190 + hid->dev = &intf->dev; 1191 1191 usbhid->intf = intf; 1192 1192 usbhid->ifnum = interface->desc.bInterfaceNumber; 1193 1193 ··· 1282 1282 usb_free_urb(usbhid->urbctrl); 1283 1283 usb_free_urb(usbhid->urbout); 1284 1284 1285 - hid_free_buffers(to_usb_device(hid->dev), hid); 1285 + hid_free_buffers(hid_to_usb_dev(hid), hid); 1286 1286 hid_free_device(hid); 1287 1287 } 1288 1288
+3 -2
drivers/usb/input/hid-ff.c
··· 33 33 #include <linux/usb.h> 34 34 35 35 #include <linux/hid.h> 36 + #include "usbhid.h" 36 37 37 38 /* 38 39 * This table contains pointers to initializers. To add support for new ··· 71 70 int hid_ff_init(struct hid_device* hid) 72 71 { 73 72 struct hid_ff_initializer *init; 74 - int vendor = le16_to_cpu(to_usb_device(hid->dev)->descriptor.idVendor); 75 - int product = le16_to_cpu(to_usb_device(hid->dev)->descriptor.idProduct); 73 + int vendor = le16_to_cpu(hid_to_usb_dev(hid)->descriptor.idVendor); 74 + int product = le16_to_cpu(hid_to_usb_dev(hid)->descriptor.idProduct); 76 75 77 76 for (init = inits; init->idVendor; init++) 78 77 if (init->idVendor == vendor && init->idProduct == product)
+1 -1
drivers/usb/input/hiddev.c
··· 384 384 struct hiddev_list *list = file->private_data; 385 385 struct hiddev *hiddev = list->hiddev; 386 386 struct hid_device *hid = hiddev->hid; 387 - struct usb_device *dev = to_usb_device(hid->dev); 387 + struct usb_device *dev = hid_to_usb_dev(hid); 388 388 struct hiddev_collection_info cinfo; 389 389 struct hiddev_report_info rinfo; 390 390 struct hiddev_field_info finfo;
+3
drivers/usb/input/usbhid.h
··· 80 80 81 81 }; 82 82 83 + #define hid_to_usb_dev(hid_dev) \ 84 + container_of(hid_dev->dev->parent, struct usb_device, dev) 85 + 83 86 #endif 84 87