Merge tag 'firewire-updates' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee139...
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 9 Sep 2013 17:32:03 +0000 (10:32 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 9 Sep 2013 17:32:03 +0000 (10:32 -0700)
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

drivers/firewire/core-cdev.c
drivers/firewire/core-transaction.c
drivers/firewire/ohci.c

index ac1b43a0428531273c4fdaefd56a0b83f1545ce2..d7d5c8af92b9754fa79aa632c69d9ffc1fb27420 100644 (file)
@@ -486,7 +486,7 @@ static int ioctl_get_info(struct client *client, union ioctl_arg *arg)
 static int add_client_resource(struct client *client,
                               struct client_resource *resource, gfp_t gfp_mask)
 {
-       bool preload = gfp_mask & __GFP_WAIT;
+       bool preload = !!(gfp_mask & __GFP_WAIT);
        unsigned long flags;
        int ret;
 
index 28a94c7ec6e5bad3af57ed258e0615266ab7b135..e5af0e3a26ec9345a9a775e77ab76b78db94ba25 100644 (file)
@@ -1262,8 +1262,7 @@ static int __init fw_core_init(void)
 {
        int ret;
 
-       fw_workqueue = alloc_workqueue("firewire",
-                                      WQ_NON_REENTRANT | WQ_MEM_RECLAIM, 0);
+       fw_workqueue = alloc_workqueue("firewire", WQ_MEM_RECLAIM, 0);
        if (!fw_workqueue)
                return -ENOMEM;
 
index afb701ec90cabd50ceb03b1298beba38e97717b4..6aa8a86cb83b33223aa7e2d26db2308aa440bdd8 100644 (file)
@@ -235,13 +235,15 @@ struct fw_ohci {
        dma_addr_t next_config_rom_bus;
        __be32     next_header;
 
-       __le32    *self_id_cpu;
+       __le32    *self_id;
        dma_addr_t self_id_bus;
        struct work_struct bus_reset_work;
 
        u32 self_id_buffer[512];
 };
 
+static struct workqueue_struct *selfid_workqueue;
+
 static inline struct fw_ohci *fw_ohci(struct fw_card *card)
 {
        return container_of(card, struct fw_ohci, card);
@@ -271,6 +273,7 @@ static inline struct fw_ohci *fw_ohci(struct fw_card *card)
 
 static char ohci_driver_name[] = KBUILD_MODNAME;
 
+#define PCI_VENDOR_ID_PINNACLE_SYSTEMS 0x11bd
 #define PCI_DEVICE_ID_AGERE_FW643      0x5901
 #define PCI_DEVICE_ID_CREATIVE_SB1394  0x4001
 #define PCI_DEVICE_ID_JMICRON_JMB38X_FW        0x2380
@@ -278,17 +281,16 @@ static char ohci_driver_name[] = KBUILD_MODNAME;
 #define PCI_DEVICE_ID_TI_TSB12LV26     0x8020
 #define PCI_DEVICE_ID_TI_TSB82AA2      0x8025
 #define PCI_DEVICE_ID_VIA_VT630X       0x3044
-#define PCI_VENDOR_ID_PINNACLE_SYSTEMS 0x11bd
 #define PCI_REV_ID_VIA_VT6306          0x46
 
-#define QUIRK_CYCLE_TIMER              1
-#define QUIRK_RESET_PACKET             2
-#define QUIRK_BE_HEADERS               4
-#define QUIRK_NO_1394A                 8
-#define QUIRK_NO_MSI                   16
-#define QUIRK_TI_SLLZ059               32
-#define QUIRK_IR_WAKE                  64
-#define QUIRK_PHY_LCTRL_TIMEOUT                128
+#define QUIRK_CYCLE_TIMER              0x1
+#define QUIRK_RESET_PACKET             0x2
+#define QUIRK_BE_HEADERS               0x4
+#define QUIRK_NO_1394A                 0x8
+#define QUIRK_NO_MSI                   0x10
+#define QUIRK_TI_SLLZ059               0x20
+#define QUIRK_IR_WAKE                  0x40
+#define QUIRK_PHY_LCTRL_TIMEOUT                0x80
 
 /* In case of multiple matches in ohci_quirks[], only the first one is used. */
 static const struct {
@@ -1929,12 +1931,12 @@ static void bus_reset_work(struct work_struct *work)
                return;
        }
 
-       generation = (cond_le32_to_cpu(ohci->self_id_cpu[0]) >> 16) & 0xff;
+       generation = (cond_le32_to_cpu(ohci->self_id[0]) >> 16) & 0xff;
        rmb();
 
        for (i = 1, j = 0; j < self_id_count; i += 2, j++) {
-               u32 id  = cond_le32_to_cpu(ohci->self_id_cpu[i]);
-               u32 id2 = cond_le32_to_cpu(ohci->self_id_cpu[i + 1]);
+               u32 id  = cond_le32_to_cpu(ohci->self_id[i]);
+               u32 id2 = cond_le32_to_cpu(ohci->self_id[i + 1]);
 
                if (id != ~id2) {
                        /*
@@ -2087,7 +2089,7 @@ static irqreturn_t irq_handler(int irq, void *data)
        log_irqs(ohci, event);
 
        if (event & OHCI1394_selfIDComplete)
-               queue_work(fw_workqueue, &ohci->bus_reset_work);
+               queue_work(selfid_workqueue, &ohci->bus_reset_work);
 
        if (event & OHCI1394_RQPkt)
                tasklet_schedule(&ohci->ar_request_ctx.tasklet);
@@ -3692,7 +3694,7 @@ static int pci_probe(struct pci_dev *dev,
                goto fail_contexts;
        }
 
-       ohci->self_id_cpu = ohci->misc_buffer     + PAGE_SIZE/2;
+       ohci->self_id     = ohci->misc_buffer     + PAGE_SIZE/2;
        ohci->self_id_bus = ohci->misc_buffer_bus + PAGE_SIZE/2;
 
        bus_options = reg_read(ohci, OHCI1394_BusOptions);
@@ -3870,7 +3872,23 @@ static struct pci_driver fw_ohci_pci_driver = {
 #endif
 };
 
-module_pci_driver(fw_ohci_pci_driver);
+static int __init fw_ohci_init(void)
+{
+       selfid_workqueue = alloc_workqueue(KBUILD_MODNAME, WQ_MEM_RECLAIM, 0);
+       if (!selfid_workqueue)
+               return -ENOMEM;
+
+       return pci_register_driver(&fw_ohci_pci_driver);
+}
+
+static void __exit fw_ohci_cleanup(void)
+{
+       pci_unregister_driver(&fw_ohci_pci_driver);
+       destroy_workqueue(selfid_workqueue);
+}
+
+module_init(fw_ohci_init);
+module_exit(fw_ohci_cleanup);
 
 MODULE_AUTHOR("Kristian Hoegsberg <krh@bitplanet.net>");
 MODULE_DESCRIPTION("Driver for PCI OHCI IEEE1394 controllers");