Commit b5f0998c authored by Linus Torvalds's avatar Linus Torvalds

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
parents 64c35386 db9ae8fe
...@@ -486,7 +486,7 @@ static int ioctl_get_info(struct client *client, union ioctl_arg *arg) ...@@ -486,7 +486,7 @@ static int ioctl_get_info(struct client *client, union ioctl_arg *arg)
static int add_client_resource(struct client *client, static int add_client_resource(struct client *client,
struct client_resource *resource, gfp_t gfp_mask) struct client_resource *resource, gfp_t gfp_mask)
{ {
bool preload = gfp_mask & __GFP_WAIT; bool preload = !!(gfp_mask & __GFP_WAIT);
unsigned long flags; unsigned long flags;
int ret; int ret;
......
...@@ -1262,8 +1262,7 @@ static int __init fw_core_init(void) ...@@ -1262,8 +1262,7 @@ static int __init fw_core_init(void)
{ {
int ret; int ret;
fw_workqueue = alloc_workqueue("firewire", fw_workqueue = alloc_workqueue("firewire", WQ_MEM_RECLAIM, 0);
WQ_NON_REENTRANT | WQ_MEM_RECLAIM, 0);
if (!fw_workqueue) if (!fw_workqueue)
return -ENOMEM; return -ENOMEM;
......
...@@ -235,13 +235,15 @@ struct fw_ohci { ...@@ -235,13 +235,15 @@ struct fw_ohci {
dma_addr_t next_config_rom_bus; dma_addr_t next_config_rom_bus;
__be32 next_header; __be32 next_header;
__le32 *self_id_cpu; __le32 *self_id;
dma_addr_t self_id_bus; dma_addr_t self_id_bus;
struct work_struct bus_reset_work; struct work_struct bus_reset_work;
u32 self_id_buffer[512]; u32 self_id_buffer[512];
}; };
static struct workqueue_struct *selfid_workqueue;
static inline struct fw_ohci *fw_ohci(struct fw_card *card) static inline struct fw_ohci *fw_ohci(struct fw_card *card)
{ {
return container_of(card, struct fw_ohci, card); return container_of(card, struct fw_ohci, card);
...@@ -271,6 +273,7 @@ static inline struct fw_ohci *fw_ohci(struct fw_card *card) ...@@ -271,6 +273,7 @@ static inline struct fw_ohci *fw_ohci(struct fw_card *card)
static char ohci_driver_name[] = KBUILD_MODNAME; 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_AGERE_FW643 0x5901
#define PCI_DEVICE_ID_CREATIVE_SB1394 0x4001 #define PCI_DEVICE_ID_CREATIVE_SB1394 0x4001
#define PCI_DEVICE_ID_JMICRON_JMB38X_FW 0x2380 #define PCI_DEVICE_ID_JMICRON_JMB38X_FW 0x2380
...@@ -278,17 +281,16 @@ static char ohci_driver_name[] = KBUILD_MODNAME; ...@@ -278,17 +281,16 @@ static char ohci_driver_name[] = KBUILD_MODNAME;
#define PCI_DEVICE_ID_TI_TSB12LV26 0x8020 #define PCI_DEVICE_ID_TI_TSB12LV26 0x8020
#define PCI_DEVICE_ID_TI_TSB82AA2 0x8025 #define PCI_DEVICE_ID_TI_TSB82AA2 0x8025
#define PCI_DEVICE_ID_VIA_VT630X 0x3044 #define PCI_DEVICE_ID_VIA_VT630X 0x3044
#define PCI_VENDOR_ID_PINNACLE_SYSTEMS 0x11bd
#define PCI_REV_ID_VIA_VT6306 0x46 #define PCI_REV_ID_VIA_VT6306 0x46
#define QUIRK_CYCLE_TIMER 1 #define QUIRK_CYCLE_TIMER 0x1
#define QUIRK_RESET_PACKET 2 #define QUIRK_RESET_PACKET 0x2
#define QUIRK_BE_HEADERS 4 #define QUIRK_BE_HEADERS 0x4
#define QUIRK_NO_1394A 8 #define QUIRK_NO_1394A 0x8
#define QUIRK_NO_MSI 16 #define QUIRK_NO_MSI 0x10
#define QUIRK_TI_SLLZ059 32 #define QUIRK_TI_SLLZ059 0x20
#define QUIRK_IR_WAKE 64 #define QUIRK_IR_WAKE 0x40
#define QUIRK_PHY_LCTRL_TIMEOUT 128 #define QUIRK_PHY_LCTRL_TIMEOUT 0x80
/* In case of multiple matches in ohci_quirks[], only the first one is used. */ /* In case of multiple matches in ohci_quirks[], only the first one is used. */
static const struct { static const struct {
...@@ -1929,12 +1931,12 @@ static void bus_reset_work(struct work_struct *work) ...@@ -1929,12 +1931,12 @@ static void bus_reset_work(struct work_struct *work)
return; 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(); rmb();
for (i = 1, j = 0; j < self_id_count; i += 2, j++) { for (i = 1, j = 0; j < self_id_count; i += 2, j++) {
u32 id = cond_le32_to_cpu(ohci->self_id_cpu[i]); u32 id = cond_le32_to_cpu(ohci->self_id[i]);
u32 id2 = cond_le32_to_cpu(ohci->self_id_cpu[i + 1]); u32 id2 = cond_le32_to_cpu(ohci->self_id[i + 1]);
if (id != ~id2) { if (id != ~id2) {
/* /*
...@@ -2087,7 +2089,7 @@ static irqreturn_t irq_handler(int irq, void *data) ...@@ -2087,7 +2089,7 @@ static irqreturn_t irq_handler(int irq, void *data)
log_irqs(ohci, event); log_irqs(ohci, event);
if (event & OHCI1394_selfIDComplete) if (event & OHCI1394_selfIDComplete)
queue_work(fw_workqueue, &ohci->bus_reset_work); queue_work(selfid_workqueue, &ohci->bus_reset_work);
if (event & OHCI1394_RQPkt) if (event & OHCI1394_RQPkt)
tasklet_schedule(&ohci->ar_request_ctx.tasklet); tasklet_schedule(&ohci->ar_request_ctx.tasklet);
...@@ -3692,7 +3694,7 @@ static int pci_probe(struct pci_dev *dev, ...@@ -3692,7 +3694,7 @@ static int pci_probe(struct pci_dev *dev,
goto fail_contexts; 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; ohci->self_id_bus = ohci->misc_buffer_bus + PAGE_SIZE/2;
bus_options = reg_read(ohci, OHCI1394_BusOptions); bus_options = reg_read(ohci, OHCI1394_BusOptions);
...@@ -3870,7 +3872,23 @@ static struct pci_driver fw_ohci_pci_driver = { ...@@ -3870,7 +3872,23 @@ static struct pci_driver fw_ohci_pci_driver = {
#endif #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_AUTHOR("Kristian Hoegsberg <krh@bitplanet.net>");
MODULE_DESCRIPTION("Driver for PCI OHCI IEEE1394 controllers"); MODULE_DESCRIPTION("Driver for PCI OHCI IEEE1394 controllers");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment