aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-09-09 13:32:03 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-09-09 13:32:03 -0400
commitb5f0998cae3d7ea56d3d8377e46328fe972b9546 (patch)
tree497531102958a4c364521cfd9f3b0110aa6d8db0
parent64c353864e3f7ccba0ade1bd6f562f9a3bc7e68d (diff)
parentdb9ae8fec7b19f0ac6c60d998cac968d801a998d (diff)
Merge tag 'firewire-updates' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394
Pull firewire updates from Stefan Richter: - Fix a regression since 3.2 inclusive: The subsystem workqueue deadlocked between transaction completion handling and bus reset handling if the worker pool could not be increased in time. - janitorial updates * tag 'firewire-updates' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394: firewire: ohci: Fix deadlock at bus reset firewire: ohci: Change module_pci_driver to module_init/module_exit firewire: ohci: beautify some macro definitions firewire: ohci: change confusing name of a struct member firewire: core: typecast from gfp_t to bool more safely firewire: WQ_NON_REENTRANT is meaningless and going away
-rw-r--r--drivers/firewire/core-cdev.c2
-rw-r--r--drivers/firewire/core-transaction.c3
-rw-r--r--drivers/firewire/ohci.c50
3 files changed, 36 insertions, 19 deletions
diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c
index ac1b43a04285..d7d5c8af92b9 100644
--- a/drivers/firewire/core-cdev.c
+++ b/drivers/firewire/core-cdev.c
@@ -486,7 +486,7 @@ static int ioctl_get_info(struct client *client, union ioctl_arg *arg)
486static int add_client_resource(struct client *client, 486static int add_client_resource(struct client *client,
487 struct client_resource *resource, gfp_t gfp_mask) 487 struct client_resource *resource, gfp_t gfp_mask)
488{ 488{
489 bool preload = gfp_mask & __GFP_WAIT; 489 bool preload = !!(gfp_mask & __GFP_WAIT);
490 unsigned long flags; 490 unsigned long flags;
491 int ret; 491 int ret;
492 492
diff --git a/drivers/firewire/core-transaction.c b/drivers/firewire/core-transaction.c
index 28a94c7ec6e5..e5af0e3a26ec 100644
--- a/drivers/firewire/core-transaction.c
+++ b/drivers/firewire/core-transaction.c
@@ -1262,8 +1262,7 @@ static int __init fw_core_init(void)
1262{ 1262{
1263 int ret; 1263 int ret;
1264 1264
1265 fw_workqueue = alloc_workqueue("firewire", 1265 fw_workqueue = alloc_workqueue("firewire", WQ_MEM_RECLAIM, 0);
1266 WQ_NON_REENTRANT | WQ_MEM_RECLAIM, 0);
1267 if (!fw_workqueue) 1266 if (!fw_workqueue)
1268 return -ENOMEM; 1267 return -ENOMEM;
1269 1268
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c
index afb701ec90ca..6aa8a86cb83b 100644
--- a/drivers/firewire/ohci.c
+++ b/drivers/firewire/ohci.c
@@ -235,13 +235,15 @@ struct fw_ohci {
235 dma_addr_t next_config_rom_bus; 235 dma_addr_t next_config_rom_bus;
236 __be32 next_header; 236 __be32 next_header;
237 237
238 __le32 *self_id_cpu; 238 __le32 *self_id;
239 dma_addr_t self_id_bus; 239 dma_addr_t self_id_bus;
240 struct work_struct bus_reset_work; 240 struct work_struct bus_reset_work;
241 241
242 u32 self_id_buffer[512]; 242 u32 self_id_buffer[512];
243}; 243};
244 244
245static struct workqueue_struct *selfid_workqueue;
246
245static inline struct fw_ohci *fw_ohci(struct fw_card *card) 247static inline struct fw_ohci *fw_ohci(struct fw_card *card)
246{ 248{
247 return container_of(card, struct fw_ohci, card); 249 return container_of(card, struct fw_ohci, card);
@@ -271,6 +273,7 @@ static inline struct fw_ohci *fw_ohci(struct fw_card *card)
271 273
272static char ohci_driver_name[] = KBUILD_MODNAME; 274static char ohci_driver_name[] = KBUILD_MODNAME;
273 275
276#define PCI_VENDOR_ID_PINNACLE_SYSTEMS 0x11bd
274#define PCI_DEVICE_ID_AGERE_FW643 0x5901 277#define PCI_DEVICE_ID_AGERE_FW643 0x5901
275#define PCI_DEVICE_ID_CREATIVE_SB1394 0x4001 278#define PCI_DEVICE_ID_CREATIVE_SB1394 0x4001
276#define PCI_DEVICE_ID_JMICRON_JMB38X_FW 0x2380 279#define PCI_DEVICE_ID_JMICRON_JMB38X_FW 0x2380
@@ -278,17 +281,16 @@ static char ohci_driver_name[] = KBUILD_MODNAME;
278#define PCI_DEVICE_ID_TI_TSB12LV26 0x8020 281#define PCI_DEVICE_ID_TI_TSB12LV26 0x8020
279#define PCI_DEVICE_ID_TI_TSB82AA2 0x8025 282#define PCI_DEVICE_ID_TI_TSB82AA2 0x8025
280#define PCI_DEVICE_ID_VIA_VT630X 0x3044 283#define PCI_DEVICE_ID_VIA_VT630X 0x3044
281#define PCI_VENDOR_ID_PINNACLE_SYSTEMS 0x11bd
282#define PCI_REV_ID_VIA_VT6306 0x46 284#define PCI_REV_ID_VIA_VT6306 0x46
283 285
284#define QUIRK_CYCLE_TIMER 1 286#define QUIRK_CYCLE_TIMER 0x1
285#define QUIRK_RESET_PACKET 2 287#define QUIRK_RESET_PACKET 0x2
286#define QUIRK_BE_HEADERS 4 288#define QUIRK_BE_HEADERS 0x4
287#define QUIRK_NO_1394A 8 289#define QUIRK_NO_1394A 0x8
288#define QUIRK_NO_MSI 16 290#define QUIRK_NO_MSI 0x10
289#define QUIRK_TI_SLLZ059 32 291#define QUIRK_TI_SLLZ059 0x20
290#define QUIRK_IR_WAKE 64 292#define QUIRK_IR_WAKE 0x40
291#define QUIRK_PHY_LCTRL_TIMEOUT 128 293#define QUIRK_PHY_LCTRL_TIMEOUT 0x80
292 294
293/* In case of multiple matches in ohci_quirks[], only the first one is used. */ 295/* In case of multiple matches in ohci_quirks[], only the first one is used. */
294static const struct { 296static const struct {
@@ -1929,12 +1931,12 @@ static void bus_reset_work(struct work_struct *work)
1929 return; 1931 return;
1930 } 1932 }
1931 1933
1932 generation = (cond_le32_to_cpu(ohci->self_id_cpu[0]) >> 16) & 0xff; 1934 generation = (cond_le32_to_cpu(ohci->self_id[0]) >> 16) & 0xff;
1933 rmb(); 1935 rmb();
1934 1936
1935 for (i = 1, j = 0; j < self_id_count; i += 2, j++) { 1937 for (i = 1, j = 0; j < self_id_count; i += 2, j++) {
1936 u32 id = cond_le32_to_cpu(ohci->self_id_cpu[i]); 1938 u32 id = cond_le32_to_cpu(ohci->self_id[i]);
1937 u32 id2 = cond_le32_to_cpu(ohci->self_id_cpu[i + 1]); 1939 u32 id2 = cond_le32_to_cpu(ohci->self_id[i + 1]);
1938 1940
1939 if (id != ~id2) { 1941 if (id != ~id2) {
1940 /* 1942 /*
@@ -2087,7 +2089,7 @@ static irqreturn_t irq_handler(int irq, void *data)
2087 log_irqs(ohci, event); 2089 log_irqs(ohci, event);
2088 2090
2089 if (event & OHCI1394_selfIDComplete) 2091 if (event & OHCI1394_selfIDComplete)
2090 queue_work(fw_workqueue, &ohci->bus_reset_work); 2092 queue_work(selfid_workqueue, &ohci->bus_reset_work);
2091 2093
2092 if (event & OHCI1394_RQPkt) 2094 if (event & OHCI1394_RQPkt)
2093 tasklet_schedule(&ohci->ar_request_ctx.tasklet); 2095 tasklet_schedule(&ohci->ar_request_ctx.tasklet);
@@ -3692,7 +3694,7 @@ static int pci_probe(struct pci_dev *dev,
3692 goto fail_contexts; 3694 goto fail_contexts;
3693 } 3695 }
3694 3696
3695 ohci->self_id_cpu = ohci->misc_buffer + PAGE_SIZE/2; 3697 ohci->self_id = ohci->misc_buffer + PAGE_SIZE/2;
3696 ohci->self_id_bus = ohci->misc_buffer_bus + PAGE_SIZE/2; 3698 ohci->self_id_bus = ohci->misc_buffer_bus + PAGE_SIZE/2;
3697 3699
3698 bus_options = reg_read(ohci, OHCI1394_BusOptions); 3700 bus_options = reg_read(ohci, OHCI1394_BusOptions);
@@ -3870,7 +3872,23 @@ static struct pci_driver fw_ohci_pci_driver = {
3870#endif 3872#endif
3871}; 3873};
3872 3874
3873module_pci_driver(fw_ohci_pci_driver); 3875static int __init fw_ohci_init(void)
3876{
3877 selfid_workqueue = alloc_workqueue(KBUILD_MODNAME, WQ_MEM_RECLAIM, 0);
3878 if (!selfid_workqueue)
3879 return -ENOMEM;
3880
3881 return pci_register_driver(&fw_ohci_pci_driver);
3882}
3883
3884static void __exit fw_ohci_cleanup(void)
3885{
3886 pci_unregister_driver(&fw_ohci_pci_driver);
3887 destroy_workqueue(selfid_workqueue);
3888}
3889
3890module_init(fw_ohci_init);
3891module_exit(fw_ohci_cleanup);
3874 3892
3875MODULE_AUTHOR("Kristian Hoegsberg <krh@bitplanet.net>"); 3893MODULE_AUTHOR("Kristian Hoegsberg <krh@bitplanet.net>");
3876MODULE_DESCRIPTION("Driver for PCI OHCI IEEE1394 controllers"); 3894MODULE_DESCRIPTION("Driver for PCI OHCI IEEE1394 controllers");