Skip to content

Commit

Permalink
Input: bcm5974 - only setup button urb for TYPE1 devices
Browse files Browse the repository at this point in the history
The early generations with this trackpad used the separate mouse
interface to produce button events. With the introduction of the
button pads, this information was moved to the trackpad interface,
leaving the mouse interface unused. The driver is still setting up
both interfaces, which has not caused any problems - until now.

It turns out that without the CONFIG_USB_EHCI_TT_NEWSCHED option, the
driver may return an ENOSPC upon bt_urb submission, resulting in a
failure to open the device. This happens everytime on the MacBookPro
Retina (and likely on other mid-2012 models), but earlier MacBook
models seem to work fine.

This patch skips the bt_urb setup for TYPE2 devices, which arguably
should have been done in the first place.

Tested-by: Benjamin Tissoires <benjamin.tissoires@enac.fr>
Acked-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
  • Loading branch information
Henrik Rydberg committed Sep 19, 2012
1 parent 77723e3 commit 43f482b
Showing 1 changed file with 26 additions and 17 deletions.
43 changes: 26 additions & 17 deletions drivers/input/mouse/bcm5974.c
Original file line number Diff line number Diff line change
Expand Up @@ -742,9 +742,11 @@ static int bcm5974_start_traffic(struct bcm5974 *dev)
goto err_out;
}

error = usb_submit_urb(dev->bt_urb, GFP_KERNEL);
if (error)
goto err_reset_mode;
if (dev->bt_urb) {
error = usb_submit_urb(dev->bt_urb, GFP_KERNEL);
if (error)
goto err_reset_mode;
}

error = usb_submit_urb(dev->tp_urb, GFP_KERNEL);
if (error)
Expand Down Expand Up @@ -868,30 +870,35 @@ static int bcm5974_probe(struct usb_interface *iface,
mutex_init(&dev->pm_mutex);

/* setup urbs */
dev->bt_urb = usb_alloc_urb(0, GFP_KERNEL);
if (!dev->bt_urb)
goto err_free_devs;
if (cfg->tp_type == TYPE1) {
dev->bt_urb = usb_alloc_urb(0, GFP_KERNEL);
if (!dev->bt_urb)
goto err_free_devs;
}

dev->tp_urb = usb_alloc_urb(0, GFP_KERNEL);
if (!dev->tp_urb)
goto err_free_bt_urb;

dev->bt_data = usb_alloc_coherent(dev->udev,
if (dev->bt_urb) {
dev->bt_data = usb_alloc_coherent(dev->udev,
dev->cfg.bt_datalen, GFP_KERNEL,
&dev->bt_urb->transfer_dma);
if (!dev->bt_data)
goto err_free_urb;
if (!dev->bt_data)
goto err_free_urb;
}

dev->tp_data = usb_alloc_coherent(dev->udev,
dev->cfg.tp_datalen, GFP_KERNEL,
&dev->tp_urb->transfer_dma);
if (!dev->tp_data)
goto err_free_bt_buffer;

usb_fill_int_urb(dev->bt_urb, udev,
usb_rcvintpipe(udev, cfg->bt_ep),
dev->bt_data, dev->cfg.bt_datalen,
bcm5974_irq_button, dev, 1);
if (dev->bt_urb)
usb_fill_int_urb(dev->bt_urb, udev,
usb_rcvintpipe(udev, cfg->bt_ep),
dev->bt_data, dev->cfg.bt_datalen,
bcm5974_irq_button, dev, 1);

usb_fill_int_urb(dev->tp_urb, udev,
usb_rcvintpipe(udev, cfg->tp_ep),
Expand Down Expand Up @@ -929,8 +936,9 @@ static int bcm5974_probe(struct usb_interface *iface,
usb_free_coherent(dev->udev, dev->cfg.tp_datalen,
dev->tp_data, dev->tp_urb->transfer_dma);
err_free_bt_buffer:
usb_free_coherent(dev->udev, dev->cfg.bt_datalen,
dev->bt_data, dev->bt_urb->transfer_dma);
if (dev->bt_urb)
usb_free_coherent(dev->udev, dev->cfg.bt_datalen,
dev->bt_data, dev->bt_urb->transfer_dma);
err_free_urb:
usb_free_urb(dev->tp_urb);
err_free_bt_urb:
Expand All @@ -951,8 +959,9 @@ static void bcm5974_disconnect(struct usb_interface *iface)
input_unregister_device(dev->input);
usb_free_coherent(dev->udev, dev->cfg.tp_datalen,
dev->tp_data, dev->tp_urb->transfer_dma);
usb_free_coherent(dev->udev, dev->cfg.bt_datalen,
dev->bt_data, dev->bt_urb->transfer_dma);
if (dev->bt_urb)
usb_free_coherent(dev->udev, dev->cfg.bt_datalen,
dev->bt_data, dev->bt_urb->transfer_dma);
usb_free_urb(dev->tp_urb);
usb_free_urb(dev->bt_urb);
kfree(dev);
Expand Down

0 comments on commit 43f482b

Please sign in to comment.