Inter-revision diff: patch 1

Comparing v3 (message) to v2 (message)

--- v3
+++ v2
@@ -1,244 +1,111 @@
-Move all MT-related things to a separate place. This saves some
-bytes for non-mt input devices, and prepares for new MT features.
+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.
 
 Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
 ---
- drivers/input/evdev.c    | 10 ++++++----
- drivers/input/input-mt.c | 47 +++++++++++++++++++++++++++--------------------
- drivers/input/input.c    |  9 ++++-----
- include/linux/input.h    |  9 ++-------
- include/linux/input/mt.h | 16 ++++++++++++++--
- 5 files changed, 53 insertions(+), 38 deletions(-)
+ drivers/input/mouse/bcm5974.c | 43 ++++++++++++++++++++++++++-----------------
+ 1 file changed, 26 insertions(+), 17 deletions(-)
 
-diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
-index 6c58bff..a0692c5 100644
---- a/drivers/input/evdev.c
-+++ b/drivers/input/evdev.c
-@@ -653,20 +653,22 @@ static int evdev_handle_mt_request(struct input_dev *dev,
- 				   unsigned int size,
- 				   int __user *ip)
- {
--	const struct input_mt_slot *mt = dev->mt;
-+	const struct input_mt *mt = dev->mt;
- 	unsigned int code;
- 	int max_slots;
- 	int i;
+diff --git a/drivers/input/mouse/bcm5974.c b/drivers/input/mouse/bcm5974.c
+index d528c23..39ac9ff 100644
+--- a/drivers/input/mouse/bcm5974.c
++++ b/drivers/input/mouse/bcm5974.c
+@@ -742,9 +742,11 @@ static int bcm5974_start_traffic(struct bcm5974 *dev)
+ 		goto err_out;
+ 	}
  
- 	if (get_user(code, &ip[0]))
- 		return -EFAULT;
--	if (!input_is_mt_value(code))
-+	if (!mt || !input_is_mt_value(code))
- 		return -EINVAL;
- 
- 	max_slots = (size - sizeof(__u32)) / sizeof(__s32);
--	for (i = 0; i < dev->mtsize && i < max_slots; i++)
--		if (put_user(input_mt_get_value(&mt[i], code), &ip[1 + i]))
-+	for (i = 0; i < mt->num_slots && i < max_slots; i++) {
-+		int value = input_mt_get_value(&mt->slots[i], code);
-+		if (put_user(value, &ip[1 + i]))
- 			return -EFAULT;
+-	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;
 +	}
  
- 	return 0;
- }
-diff --git a/drivers/input/input-mt.c b/drivers/input/input-mt.c
-index 70a16c7..c6df704 100644
---- a/drivers/input/input-mt.c
-+++ b/drivers/input/input-mt.c
-@@ -27,26 +27,28 @@
-  */
- int input_mt_init_slots(struct input_dev *dev, unsigned int num_slots)
- {
-+	struct input_mt *mt = dev->mt;
- 	int i;
+ 	error = usb_submit_urb(dev->tp_urb, GFP_KERNEL);
+ 	if (error)
+@@ -868,19 +870,23 @@ static int bcm5974_probe(struct usb_interface *iface,
+ 	mutex_init(&dev->pm_mutex);
  
- 	if (!num_slots)
- 		return 0;
--	if (dev->mt)
--		return dev->mtsize != num_slots ? -EINVAL : 0;
-+	if (mt)
-+		return mt->num_slots != num_slots ? -EINVAL : 0;
+ 	/* 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->mt = kcalloc(num_slots, sizeof(struct input_mt_slot), GFP_KERNEL);
--	if (!dev->mt)
-+	mt = kzalloc(sizeof(*mt) + num_slots * sizeof(*mt->slots), GFP_KERNEL);
-+	if (!mt)
- 		return -ENOMEM;
+ 	dev->tp_urb = usb_alloc_urb(0, GFP_KERNEL);
+ 	if (!dev->tp_urb)
+ 		goto err_free_bt_urb;
  
--	dev->mtsize = num_slots;
-+	mt->num_slots = num_slots;
- 	input_set_abs_params(dev, ABS_MT_SLOT, 0, num_slots - 1, 0, 0);
- 	input_set_abs_params(dev, ABS_MT_TRACKING_ID, 0, TRKID_MAX, 0, 0);
- 	input_set_events_per_packet(dev, 6 * num_slots);
+-	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;
++	}
  
- 	/* Mark slots as 'unused' */
- 	for (i = 0; i < num_slots; i++)
--		input_mt_set_value(&dev->mt[i], ABS_MT_TRACKING_ID, -1);
-+		input_mt_set_value(&mt->slots[i], ABS_MT_TRACKING_ID, -1);
+ 	dev->tp_data = usb_alloc_coherent(dev->udev,
+ 					  dev->cfg.tp_datalen, GFP_KERNEL,
+@@ -888,10 +894,11 @@ static int bcm5974_probe(struct usb_interface *iface,
+ 	if (!dev->tp_data)
+ 		goto err_free_bt_buffer;
  
-+	dev->mt = mt;
- 	return 0;
- }
- EXPORT_SYMBOL(input_mt_init_slots);
-@@ -62,9 +64,7 @@ void input_mt_destroy_slots(struct input_dev *dev)
- {
- 	kfree(dev->mt);
- 	dev->mt = NULL;
--	dev->mtsize = 0;
- 	dev->slot = 0;
--	dev->trkid = 0;
- }
- EXPORT_SYMBOL(input_mt_destroy_slots);
+-	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);
  
-@@ -83,18 +83,19 @@ EXPORT_SYMBOL(input_mt_destroy_slots);
- void input_mt_report_slot_state(struct input_dev *dev,
- 				unsigned int tool_type, bool active)
- {
--	struct input_mt_slot *mt;
-+	struct input_mt *mt = dev->mt;
-+	struct input_mt_slot *slot;
- 	int id;
- 
--	if (!dev->mt || !active) {
-+	if (!mt || !active) {
- 		input_event(dev, EV_ABS, ABS_MT_TRACKING_ID, -1);
- 		return;
- 	}
- 
--	mt = &dev->mt[dev->slot];
--	id = input_mt_get_value(mt, ABS_MT_TRACKING_ID);
--	if (id < 0 || input_mt_get_value(mt, ABS_MT_TOOL_TYPE) != tool_type)
--		id = input_mt_new_trkid(dev);
-+	slot = &mt->slots[dev->slot];
-+	id = input_mt_get_value(slot, ABS_MT_TRACKING_ID);
-+	if (id < 0 || input_mt_get_value(slot, ABS_MT_TOOL_TYPE) != tool_type)
-+		id = input_mt_new_trkid(mt);
- 
- 	input_event(dev, EV_ABS, ABS_MT_TRACKING_ID, id);
- 	input_event(dev, EV_ABS, ABS_MT_TOOL_TYPE, tool_type);
-@@ -135,13 +136,19 @@ EXPORT_SYMBOL(input_mt_report_finger_count);
-  */
- void input_mt_report_pointer_emulation(struct input_dev *dev, bool use_count)
- {
--	struct input_mt_slot *oldest = NULL;
--	int oldid = dev->trkid;
--	int count = 0;
--	int i;
-+	struct input_mt *mt = dev->mt;
-+	struct input_mt_slot *oldest;
-+	int oldid, count, i;
-+
-+	if (!mt)
-+		return;
-+
-+	oldest = 0;
-+	oldid = mt->trkid;
-+	count = 0;
- 
--	for (i = 0; i < dev->mtsize; ++i) {
--		struct input_mt_slot *ps = &dev->mt[i];
-+	for (i = 0; i < mt->num_slots; ++i) {
-+		struct input_mt_slot *ps = &mt->slots[i];
- 		int id = input_mt_get_value(ps, ABS_MT_TRACKING_ID);
- 
- 		if (id < 0)
-diff --git a/drivers/input/input.c b/drivers/input/input.c
-index 8921c61..6e90705 100644
---- a/drivers/input/input.c
-+++ b/drivers/input/input.c
-@@ -174,7 +174,7 @@ static int input_handle_abs_event(struct input_dev *dev,
- 		 * "Stage" the event; we'll flush it later, when we
- 		 * get actual touch data.
- 		 */
--		if (*pval >= 0 && *pval < dev->mtsize)
-+		if (dev->mt && *pval >= 0 && *pval < dev->mt->num_slots)
- 			dev->slot = *pval;
- 
- 		return INPUT_IGNORE_EVENT;
-@@ -185,8 +185,7 @@ static int input_handle_abs_event(struct input_dev *dev,
- 	if (!is_mt_event) {
- 		pold = &dev->absinfo[code].value;
- 	} else if (dev->mt) {
--		struct input_mt_slot *mtslot = &dev->mt[dev->slot];
--		pold = &mtslot->abs[code - ABS_MT_FIRST];
-+		pold = &dev->mt->slots[dev->slot].abs[code - ABS_MT_FIRST];
- 	} else {
- 		/*
- 		 * Bypass filtering for multi-touch events when
-@@ -1751,8 +1750,8 @@ static unsigned int input_estimate_events_per_packet(struct input_dev *dev)
- 	int i;
- 	unsigned int events;
- 
--	if (dev->mtsize) {
--		mt_slots = dev->mtsize;
-+	if (dev->mt) {
-+		mt_slots = dev->mt->num_slots;
- 	} else if (test_bit(ABS_MT_TRACKING_ID, dev->absbit)) {
- 		mt_slots = dev->absinfo[ABS_MT_TRACKING_ID].maximum -
- 			   dev->absinfo[ABS_MT_TRACKING_ID].minimum + 1,
-diff --git a/include/linux/input.h b/include/linux/input.h
-index 725dcd0..76d6788 100644
---- a/include/linux/input.h
-+++ b/include/linux/input.h
-@@ -1203,11 +1203,8 @@ struct ff_effect {
-  *	software autorepeat
-  * @timer: timer for software autorepeat
-  * @rep: current values for autorepeat parameters (delay, rate)
-- * @mt: pointer to array of struct input_mt_slot holding current values
-- *	of tracked contacts
-- * @mtsize: number of MT slots the device uses
-+ * @mt: pointer to multitouch state
-  * @slot: MT slot currently being transmitted
-- * @trkid: stores MT tracking ID for the current contact
-  * @absinfo: array of &struct input_absinfo elements holding information
-  *	about absolute axes (current value, min, max, flat, fuzz,
-  *	resolution)
-@@ -1287,10 +1284,8 @@ struct input_dev {
- 
- 	int rep[REP_CNT];
- 
--	struct input_mt_slot *mt;
--	int mtsize;
-+	struct input_mt *mt;
- 	int slot;
--	int trkid;
- 
- 	struct input_absinfo *absinfo;
- 
-diff --git a/include/linux/input/mt.h b/include/linux/input/mt.h
-index f867375..4ae275c 100644
---- a/include/linux/input/mt.h
-+++ b/include/linux/input/mt.h
-@@ -23,6 +23,18 @@ struct input_mt_slot {
- 	int abs[ABS_MT_LAST - ABS_MT_FIRST + 1];
- };
- 
-+/**
-+ * struct input_mt - state of tracked contacts
-+ * @trkid: stores MT tracking ID for the next contact
-+ * @num_slots: number of MT slots the device uses
-+ * @slots: array of slots holding current values of tracked contacts
-+ */
-+struct input_mt {
-+	int trkid;
-+	int num_slots;
-+	struct input_mt_slot slots[];
-+};
-+
- static inline void input_mt_set_value(struct input_mt_slot *slot,
- 				      unsigned code, int value)
- {
-@@ -38,9 +50,9 @@ static inline int input_mt_get_value(const struct input_mt_slot *slot,
- int input_mt_init_slots(struct input_dev *dev, unsigned int num_slots);
- void input_mt_destroy_slots(struct input_dev *dev);
- 
--static inline int input_mt_new_trkid(struct input_dev *dev)
-+static inline int input_mt_new_trkid(struct input_mt *mt)
- {
--	return dev->trkid++ & TRKID_MAX;
-+	return mt->trkid++ & TRKID_MAX;
- }
- 
- static inline void input_mt_slot(struct input_dev *dev, int slot)
+ 	usb_fill_int_urb(dev->tp_urb, udev,
+ 			 usb_rcvintpipe(udev, cfg->tp_ep),
+@@ -929,8 +936,9 @@ err_free_buffer:
+ 	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:
+@@ -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);
 -- 
 1.7.12
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help