Gentoo Archives: gentoo-commits

From: "Markos Chandras (hwoarang)" <hwoarang@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] linux-patches r1579 - genpatches-2.6/trunk/2.6.29
Date: Tue, 23 Jun 2009 19:55:14
Message-Id: E1MJC5I-0003jF-3h@stork.gentoo.org
1 Author: hwoarang
2 Date: 2009-06-23 19:55:11 +0000 (Tue, 23 Jun 2009)
3 New Revision: 1579
4
5 Added:
6 genpatches-2.6/trunk/2.6.29/2900_bluetooth-fix-sysfs.patch
7 Modified:
8 genpatches-2.6/trunk/2.6.29/0000_README
9 Log:
10 Fix hard lock with bluetooth connections
11
12
13 Modified: genpatches-2.6/trunk/2.6.29/0000_README
14 ===================================================================
15 --- genpatches-2.6/trunk/2.6.29/0000_README 2009-06-22 19:27:41 UTC (rev 1578)
16 +++ genpatches-2.6/trunk/2.6.29/0000_README 2009-06-23 19:55:11 UTC (rev 1579)
17 @@ -83,6 +83,10 @@
18 From: http://bugs.gentoo.org/show_bug.cgi?id=251237
19 Desc: usblp: continuously poll for status
20
21 +Patch: 2900_bluetooth-fix-sysfs.patch
22 +From: http://bugs.gentoo.org/show_bug.cgi?id=274007
23 +Desc: Fix hard lock with bluetooth connections
24 +
25 Patch: 4100_dm-bbr.patch
26 From: EVMS 2.5.2
27 Desc: Bad block relocation support for LiveCD users
28
29 Added: genpatches-2.6/trunk/2.6.29/2900_bluetooth-fix-sysfs.patch
30 ===================================================================
31 --- genpatches-2.6/trunk/2.6.29/2900_bluetooth-fix-sysfs.patch (rev 0)
32 +++ genpatches-2.6/trunk/2.6.29/2900_bluetooth-fix-sysfs.patch 2009-06-23 19:55:11 UTC (rev 1579)
33 @@ -0,0 +1,454 @@
34 +From: Cornelia Huck <cornelia.huck@××××××.com>
35 +Date: Wed, 4 Mar 2009 11:44:00 +0000 (+0100)
36 +Subject: Driver core: Fix device_move() vs. dpm list ordering, v2
37 +X-Git-Tag: v2.6.30-rc1~671^2~7
38 +X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Fstable%2Flinux-2.6.30.y.git;a=commitdiff_plain;h=ffa6a7054d172a2f57248dff2de600ca795c5656;hp=60530afe1ee8a5532cb09d0ab5bc3f1a6495b780
39 +
40 +Driver core: Fix device_move() vs. dpm list ordering, v2
41 +
42 +dpm_list currently relies on the fact that child devices will
43 +be registered after their parents to get a correct suspend
44 +order. Using device_move() however destroys this assumption, as
45 +an already registered device may be moved under a newly registered
46 +one.
47 +
48 +This patch adds a new argument to device_move(), allowing callers
49 +to specify how dpm_list should be adapted.
50 +
51 +Signed-off-by: Cornelia Huck <cornelia.huck@××××××.com>
52 +Acked-by: Alan Stern <stern@×××××××××××××××.edu>
53 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
54 +---
55 +
56 +Index: linux-2.6.29.2/drivers/base/core.c
57 +===================================================================
58 +--- linux-2.6.29.2.orig/drivers/base/core.c
59 ++++ linux-2.6.29.2/drivers/base/core.c
60 +@@ -1545,8 +1545,10 @@ out:
61 + * device_move - moves a device to a new parent
62 + * @dev: the pointer to the struct device to be moved
63 + * @new_parent: the new parent of the device (can by NULL)
64 ++ * @dpm_order: how to reorder the dpm_list
65 + */
66 +-int device_move(struct device *dev, struct device *new_parent)
67 ++int device_move(struct device *dev, struct device *new_parent,
68 ++ enum dpm_order dpm_order)
69 + {
70 + int error;
71 + struct device *old_parent;
72 +@@ -1556,6 +1558,7 @@ int device_move(struct device *dev, stru
73 + if (!dev)
74 + return -EINVAL;
75 +
76 ++ device_pm_lock();
77 + new_parent = get_device(new_parent);
78 + new_parent_kobj = get_device_parent(dev, new_parent);
79 +
80 +@@ -1596,9 +1599,23 @@ int device_move(struct device *dev, stru
81 + put_device(new_parent);
82 + goto out;
83 + }
84 ++ switch (dpm_order) {
85 ++ case DPM_ORDER_NONE:
86 ++ break;
87 ++ case DPM_ORDER_DEV_AFTER_PARENT:
88 ++ device_pm_move_after(dev, new_parent);
89 ++ break;
90 ++ case DPM_ORDER_PARENT_BEFORE_DEV:
91 ++ device_pm_move_before(new_parent, dev);
92 ++ break;
93 ++ case DPM_ORDER_DEV_LAST:
94 ++ device_pm_move_last(dev);
95 ++ break;
96 ++ }
97 + out_put:
98 + put_device(old_parent);
99 + out:
100 ++ device_pm_unlock();
101 + put_device(dev);
102 + return error;
103 + }
104 +Index: linux-2.6.29.2/drivers/base/power/main.c
105 +===================================================================
106 +--- linux-2.6.29.2.orig/drivers/base/power/main.c
107 ++++ linux-2.6.29.2/drivers/base/power/main.c
108 +@@ -107,6 +107,50 @@ void device_pm_remove(struct device *dev
109 + }
110 +
111 + /**
112 ++ * device_pm_move_before - move device in dpm_list
113 ++ * @deva: Device to move in dpm_list
114 ++ * @devb: Device @deva should come before
115 ++ */
116 ++void device_pm_move_before(struct device *deva, struct device *devb)
117 ++{
118 ++ pr_debug("PM: Moving %s:%s before %s:%s\n",
119 ++ deva->bus ? deva->bus->name : "No Bus",
120 ++ kobject_name(&deva->kobj),
121 ++ devb->bus ? devb->bus->name : "No Bus",
122 ++ kobject_name(&devb->kobj));
123 ++ /* Delete deva from dpm_list and reinsert before devb. */
124 ++ list_move_tail(&deva->power.entry, &devb->power.entry);
125 ++}
126 ++
127 ++/**
128 ++ * device_pm_move_after - move device in dpm_list
129 ++ * @deva: Device to move in dpm_list
130 ++ * @devb: Device @deva should come after
131 ++ */
132 ++void device_pm_move_after(struct device *deva, struct device *devb)
133 ++{
134 ++ pr_debug("PM: Moving %s:%s after %s:%s\n",
135 ++ deva->bus ? deva->bus->name : "No Bus",
136 ++ kobject_name(&deva->kobj),
137 ++ devb->bus ? devb->bus->name : "No Bus",
138 ++ kobject_name(&devb->kobj));
139 ++ /* Delete deva from dpm_list and reinsert after devb. */
140 ++ list_move(&deva->power.entry, &devb->power.entry);
141 ++}
142 ++
143 ++/**
144 ++ * device_pm_move_last - move device to end of dpm_list
145 ++ * @dev: Device to move in dpm_list
146 ++ */
147 ++void device_pm_move_last(struct device *dev)
148 ++{
149 ++ pr_debug("PM: Moving %s:%s to end of list\n",
150 ++ dev->bus ? dev->bus->name : "No Bus",
151 ++ kobject_name(&dev->kobj));
152 ++ list_move_tail(&dev->power.entry, &dpm_list);
153 ++}
154 ++
155 ++/**
156 + * pm_op - execute the PM operation appropiate for given PM event
157 + * @dev: Device.
158 + * @ops: PM operations to choose from.
159 +Index: linux-2.6.29.2/drivers/base/power/power.h
160 +===================================================================
161 +--- linux-2.6.29.2.orig/drivers/base/power/power.h
162 ++++ linux-2.6.29.2/drivers/base/power/power.h
163 +@@ -18,11 +18,19 @@ static inline struct device *to_device(s
164 +
165 + extern void device_pm_add(struct device *);
166 + extern void device_pm_remove(struct device *);
167 ++extern void device_pm_move_before(struct device *, struct device *);
168 ++extern void device_pm_move_after(struct device *, struct device *);
169 ++extern void device_pm_move_last(struct device *);
170 +
171 + #else /* CONFIG_PM_SLEEP */
172 +
173 + static inline void device_pm_add(struct device *dev) {}
174 + static inline void device_pm_remove(struct device *dev) {}
175 ++static inline void device_pm_move_before(struct device *deva,
176 ++ struct device *devb) {}
177 ++static inline void device_pm_move_after(struct device *deva,
178 ++ struct device *devb) {}
179 ++static inline void device_pm_move_last(struct device *dev) {}
180 +
181 + #endif
182 +
183 +Index: linux-2.6.29.2/drivers/s390/cio/device.c
184 +===================================================================
185 +--- linux-2.6.29.2.orig/drivers/s390/cio/device.c
186 ++++ linux-2.6.29.2/drivers/s390/cio/device.c
187 +@@ -799,7 +799,7 @@ static void sch_attach_disconnected_devi
188 + return;
189 + other_sch = to_subchannel(cdev->dev.parent);
190 + /* Note: device_move() changes cdev->dev.parent */
191 +- ret = device_move(&cdev->dev, &sch->dev);
192 ++ ret = device_move(&cdev->dev, &sch->dev, DPM_ORDER_PARENT_BEFORE_DEV);
193 + if (ret) {
194 + CIO_MSG_EVENT(0, "Moving disconnected device 0.%x.%04x failed "
195 + "(ret=%d)!\n", cdev->private->dev_id.ssid,
196 +@@ -830,7 +830,7 @@ static void sch_attach_orphaned_device(s
197 + * Try to move the ccw device to its new subchannel.
198 + * Note: device_move() changes cdev->dev.parent
199 + */
200 +- ret = device_move(&cdev->dev, &sch->dev);
201 ++ ret = device_move(&cdev->dev, &sch->dev, DPM_ORDER_PARENT_BEFORE_DEV);
202 + if (ret) {
203 + CIO_MSG_EVENT(0, "Moving device 0.%x.%04x from orphanage "
204 + "failed (ret=%d)!\n",
205 +@@ -897,7 +897,8 @@ void ccw_device_move_to_orphanage(struct
206 + * ccw device can take its place on the subchannel.
207 + * Note: device_move() changes cdev->dev.parent
208 + */
209 +- ret = device_move(&cdev->dev, &css->pseudo_subchannel->dev);
210 ++ ret = device_move(&cdev->dev, &css->pseudo_subchannel->dev,
211 ++ DPM_ORDER_NONE);
212 + if (ret) {
213 + CIO_MSG_EVENT(0, "Moving device 0.%x.%04x to orphanage failed "
214 + "(ret=%d)!\n", cdev->private->dev_id.ssid,
215 +@@ -1129,7 +1130,7 @@ static void ccw_device_move_to_sch(struc
216 + * Try to move the ccw device to its new subchannel.
217 + * Note: device_move() changes cdev->dev.parent
218 + */
219 +- rc = device_move(&cdev->dev, &sch->dev);
220 ++ rc = device_move(&cdev->dev, &sch->dev, DPM_ORDER_PARENT_BEFORE_DEV);
221 + mutex_unlock(&sch->reg_mutex);
222 + if (rc) {
223 + CIO_MSG_EVENT(0, "Moving device 0.%x.%04x to subchannel "
224 +Index: linux-2.6.29.2/include/linux/device.h
225 +===================================================================
226 +--- linux-2.6.29.2.orig/include/linux/device.h
227 ++++ linux-2.6.29.2/include/linux/device.h
228 +@@ -483,7 +483,8 @@ extern int device_for_each_child(struct
229 + extern struct device *device_find_child(struct device *dev, void *data,
230 + int (*match)(struct device *dev, void *data));
231 + extern int device_rename(struct device *dev, char *new_name);
232 +-extern int device_move(struct device *dev, struct device *new_parent);
233 ++extern int device_move(struct device *dev, struct device *new_parent,
234 ++ enum dpm_order dpm_order);
235 +
236 + /*
237 + * Root device objects for grouping under /sys/devices
238 +Index: linux-2.6.29.2/include/linux/pm.h
239 +===================================================================
240 +--- linux-2.6.29.2.orig/include/linux/pm.h
241 ++++ linux-2.6.29.2/include/linux/pm.h
242 +@@ -400,6 +400,9 @@ extern void __suspend_report_result(cons
243 +
244 + #else /* !CONFIG_PM_SLEEP */
245 +
246 ++#define device_pm_lock() do {} while (0)
247 ++#define device_pm_unlock() do {} while (0)
248 ++
249 + static inline int device_suspend(pm_message_t state)
250 + {
251 + return 0;
252 +@@ -409,6 +412,14 @@ static inline int device_suspend(pm_mess
253 +
254 + #endif /* !CONFIG_PM_SLEEP */
255 +
256 ++/* How to reorder dpm_list after device_move() */
257 ++enum dpm_order {
258 ++ DPM_ORDER_NONE,
259 ++ DPM_ORDER_DEV_AFTER_PARENT,
260 ++ DPM_ORDER_PARENT_BEFORE_DEV,
261 ++ DPM_ORDER_DEV_LAST,
262 ++};
263 ++
264 + /*
265 + * Global Power Management flags
266 + * Used to keep APM and ACPI from both being active
267 +Index: linux-2.6.29.2/net/bluetooth/hci_sysfs.c
268 +===================================================================
269 +--- linux-2.6.29.2.orig/net/bluetooth/hci_sysfs.c
270 ++++ linux-2.6.29.2/net/bluetooth/hci_sysfs.c
271 +@@ -9,8 +9,7 @@
272 + struct class *bt_class = NULL;
273 + EXPORT_SYMBOL_GPL(bt_class);
274 +
275 +-static struct workqueue_struct *btaddconn;
276 +-static struct workqueue_struct *btdelconn;
277 ++static struct workqueue_struct *bt_workq;
278 +
279 + static inline char *link_typetostr(int type)
280 + {
281 +@@ -88,35 +87,17 @@ static struct device_type bt_link = {
282 +
283 + static void add_conn(struct work_struct *work)
284 + {
285 +- struct hci_conn *conn = container_of(work, struct hci_conn, work);
286 ++ struct hci_conn *conn = container_of(work, struct hci_conn, work_add);
287 ++ struct hci_dev *hdev = conn->hdev;
288 +
289 +- flush_workqueue(btdelconn);
290 ++ dev_set_name(&conn->dev, "%s:%d", hdev->name, conn->handle);
291 +
292 + if (device_add(&conn->dev) < 0) {
293 + BT_ERR("Failed to register connection device");
294 + return;
295 + }
296 +-}
297 +-
298 +-void hci_conn_add_sysfs(struct hci_conn *conn)
299 +-{
300 +- struct hci_dev *hdev = conn->hdev;
301 +-
302 +- BT_DBG("conn %p", conn);
303 +-
304 +- conn->dev.type = &bt_link;
305 +- conn->dev.class = bt_class;
306 +- conn->dev.parent = &hdev->dev;
307 +
308 +- dev_set_name(&conn->dev, "%s:%d", hdev->name, conn->handle);
309 +-
310 +- dev_set_drvdata(&conn->dev, conn);
311 +-
312 +- device_initialize(&conn->dev);
313 +-
314 +- INIT_WORK(&conn->work, add_conn);
315 +-
316 +- queue_work(btaddconn, &conn->work);
317 ++ hci_dev_hold(hdev);
318 + }
319 +
320 + /*
321 +@@ -131,34 +112,58 @@ static int __match_tty(struct device *de
322 +
323 + static void del_conn(struct work_struct *work)
324 + {
325 +- struct hci_conn *conn = container_of(work, struct hci_conn, work);
326 ++ struct hci_conn *conn = container_of(work, struct hci_conn, work_del);
327 + struct hci_dev *hdev = conn->hdev;
328 +
329 ++ if (!device_is_registered(&conn->dev))
330 ++ return;
331 ++
332 + while (1) {
333 + struct device *dev;
334 +
335 + dev = device_find_child(&conn->dev, NULL, __match_tty);
336 + if (!dev)
337 + break;
338 +- device_move(dev, NULL);
339 ++ device_move(dev, NULL, DPM_ORDER_DEV_LAST);
340 + put_device(dev);
341 + }
342 +
343 + device_del(&conn->dev);
344 + put_device(&conn->dev);
345 ++
346 + hci_dev_put(hdev);
347 + }
348 +
349 +-void hci_conn_del_sysfs(struct hci_conn *conn)
350 ++void hci_conn_init_sysfs(struct hci_conn *conn)
351 + {
352 ++ struct hci_dev *hdev = conn->hdev;
353 ++
354 + BT_DBG("conn %p", conn);
355 +
356 +- if (!device_is_registered(&conn->dev))
357 +- return;
358 ++ conn->dev.type = &bt_link;
359 ++ conn->dev.class = bt_class;
360 ++ conn->dev.parent = &hdev->dev;
361 +
362 +- INIT_WORK(&conn->work, del_conn);
363 ++ dev_set_drvdata(&conn->dev, conn);
364 ++
365 ++ device_initialize(&conn->dev);
366 +
367 +- queue_work(btdelconn, &conn->work);
368 ++ INIT_WORK(&conn->work_add, add_conn);
369 ++ INIT_WORK(&conn->work_del, del_conn);
370 ++}
371 ++
372 ++void hci_conn_add_sysfs(struct hci_conn *conn)
373 ++{
374 ++ BT_DBG("conn %p", conn);
375 ++
376 ++ queue_work(bt_workq, &conn->work_add);
377 ++}
378 ++
379 ++void hci_conn_del_sysfs(struct hci_conn *conn)
380 ++{
381 ++ BT_DBG("conn %p", conn);
382 ++
383 ++ queue_work(bt_workq, &conn->work_del);
384 + }
385 +
386 + static inline char *host_typetostr(int type)
387 +@@ -435,20 +440,13 @@ void hci_unregister_sysfs(struct hci_dev
388 +
389 + int __init bt_sysfs_init(void)
390 + {
391 +- btaddconn = create_singlethread_workqueue("btaddconn");
392 +- if (!btaddconn)
393 ++ bt_workq = create_singlethread_workqueue("bluetooth");
394 ++ if (!bt_workq)
395 + return -ENOMEM;
396 +
397 +- btdelconn = create_singlethread_workqueue("btdelconn");
398 +- if (!btdelconn) {
399 +- destroy_workqueue(btaddconn);
400 +- return -ENOMEM;
401 +- }
402 +-
403 + bt_class = class_create(THIS_MODULE, "bluetooth");
404 + if (IS_ERR(bt_class)) {
405 +- destroy_workqueue(btdelconn);
406 +- destroy_workqueue(btaddconn);
407 ++ destroy_workqueue(bt_workq);
408 + return PTR_ERR(bt_class);
409 + }
410 +
411 +@@ -457,8 +455,7 @@ int __init bt_sysfs_init(void)
412 +
413 + void bt_sysfs_cleanup(void)
414 + {
415 +- destroy_workqueue(btaddconn);
416 +- destroy_workqueue(btdelconn);
417 ++ destroy_workqueue(bt_workq);
418 +
419 + class_destroy(bt_class);
420 + }
421 +Index: linux-2.6.29.2/net/bluetooth/rfcomm/tty.c
422 +===================================================================
423 +--- linux-2.6.29.2.orig/net/bluetooth/rfcomm/tty.c
424 ++++ linux-2.6.29.2/net/bluetooth/rfcomm/tty.c
425 +@@ -731,7 +731,8 @@ static int rfcomm_tty_open(struct tty_st
426 + remove_wait_queue(&dev->wait, &wait);
427 +
428 + if (err == 0)
429 +- device_move(dev->tty_dev, rfcomm_get_device(dev));
430 ++ device_move(dev->tty_dev, rfcomm_get_device(dev),
431 ++ DPM_ORDER_DEV_AFTER_PARENT);
432 +
433 + rfcomm_tty_copy_pending(dev);
434 +
435 +@@ -751,7 +752,7 @@ static void rfcomm_tty_close(struct tty_
436 +
437 + if (atomic_dec_and_test(&dev->opened)) {
438 + if (dev->tty_dev->parent)
439 +- device_move(dev->tty_dev, NULL);
440 ++ device_move(dev->tty_dev, NULL, DPM_ORDER_DEV_LAST);
441 +
442 + /* Close DLC and dettach TTY */
443 + rfcomm_dlc_close(dev->dlc, 0);
444 +Index: linux-2.6.29.2/include/net/bluetooth/hci_core.h
445 +===================================================================
446 +--- linux-2.6.29.2.orig/include/net/bluetooth/hci_core.h
447 ++++ linux-2.6.29.2/include/net/bluetooth/hci_core.h
448 +@@ -179,7 +179,8 @@ struct hci_conn {
449 + struct timer_list disc_timer;
450 + struct timer_list idle_timer;
451 +
452 +- struct work_struct work;
453 ++ struct work_struct work_add;
454 ++ struct work_struct work_del;
455 +
456 + struct device dev;
457 +
458 +@@ -455,6 +456,7 @@ int hci_recv_fragment(struct hci_dev *hd
459 +
460 + int hci_register_sysfs(struct hci_dev *hdev);
461 + void hci_unregister_sysfs(struct hci_dev *hdev);
462 ++void hci_conn_init_sysfs(struct hci_conn *conn);
463 + void hci_conn_add_sysfs(struct hci_conn *conn);
464 + void hci_conn_del_sysfs(struct hci_conn *conn);
465 +
466 +Index: linux-2.6.29.2/net/bluetooth/hci_conn.c
467 +===================================================================
468 +--- linux-2.6.29.2.orig/net/bluetooth/hci_conn.c
469 ++++ linux-2.6.29.2/net/bluetooth/hci_conn.c
470 +@@ -240,6 +240,8 @@ struct hci_conn *hci_conn_add(struct hci
471 + if (hdev->notify)
472 + hdev->notify(hdev, HCI_NOTIFY_CONN_ADD);
473 +
474 ++ hci_conn_init_sysfs(conn);
475 ++
476 + tasklet_enable(&hdev->tx_task);
477 +
478 + return conn;
479 +@@ -280,6 +282,8 @@ int hci_conn_del(struct hci_conn *conn)
480 +
481 + skb_queue_purge(&conn->data_q);
482 +
483 ++ hci_dev_put(hdev);
484 ++
485 + return 0;
486 + }
487 +