aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/firewire/fw-card.c10
-rw-r--r--drivers/firewire/fw-device.c21
-rw-r--r--drivers/firewire/fw-device.h16
-rw-r--r--drivers/firewire/fw-sbp2.c4
-rw-r--r--drivers/firewire/fw-transaction.h2
5 files changed, 35 insertions, 18 deletions
diff --git a/drivers/firewire/fw-card.c b/drivers/firewire/fw-card.c
index e6395b298508..a03462750b95 100644
--- a/drivers/firewire/fw-card.c
+++ b/drivers/firewire/fw-card.c
@@ -18,6 +18,7 @@
18 18
19#include <linux/module.h> 19#include <linux/module.h>
20#include <linux/errno.h> 20#include <linux/errno.h>
21#include <linux/delay.h>
21#include <linux/device.h> 22#include <linux/device.h>
22#include <linux/mutex.h> 23#include <linux/mutex.h>
23#include <linux/crc-itu-t.h> 24#include <linux/crc-itu-t.h>
@@ -398,6 +399,7 @@ fw_card_initialize(struct fw_card *card, const struct fw_card_driver *driver,
398 static atomic_t index = ATOMIC_INIT(-1); 399 static atomic_t index = ATOMIC_INIT(-1);
399 400
400 kref_init(&card->kref); 401 kref_init(&card->kref);
402 atomic_set(&card->device_count, 0);
401 card->index = atomic_inc_return(&index); 403 card->index = atomic_inc_return(&index);
402 card->driver = driver; 404 card->driver = driver;
403 card->device = device; 405 card->device = device;
@@ -528,8 +530,14 @@ fw_core_remove_card(struct fw_card *card)
528 card->driver = &dummy_driver; 530 card->driver = &dummy_driver;
529 531
530 fw_destroy_nodes(card); 532 fw_destroy_nodes(card);
531 flush_scheduled_work(); 533 /*
534 * Wait for all device workqueue jobs to finish. Otherwise the
535 * firewire-core module could be unloaded before the jobs ran.
536 */
537 while (atomic_read(&card->device_count) > 0)
538 msleep(100);
532 539
540 cancel_delayed_work_sync(&card->work);
533 fw_flush_transactions(card); 541 fw_flush_transactions(card);
534 del_timer_sync(&card->flush_timer); 542 del_timer_sync(&card->flush_timer);
535 543
diff --git a/drivers/firewire/fw-device.c b/drivers/firewire/fw-device.c
index 2ab13e0f3469..870125a3638e 100644
--- a/drivers/firewire/fw-device.c
+++ b/drivers/firewire/fw-device.c
@@ -150,21 +150,10 @@ struct bus_type fw_bus_type = {
150}; 150};
151EXPORT_SYMBOL(fw_bus_type); 151EXPORT_SYMBOL(fw_bus_type);
152 152
153struct fw_device *fw_device_get(struct fw_device *device)
154{
155 get_device(&device->device);
156
157 return device;
158}
159
160void fw_device_put(struct fw_device *device)
161{
162 put_device(&device->device);
163}
164
165static void fw_device_release(struct device *dev) 153static void fw_device_release(struct device *dev)
166{ 154{
167 struct fw_device *device = fw_device(dev); 155 struct fw_device *device = fw_device(dev);
156 struct fw_card *card = device->card;
168 unsigned long flags; 157 unsigned long flags;
169 158
170 /* 159 /*
@@ -176,9 +165,9 @@ static void fw_device_release(struct device *dev)
176 spin_unlock_irqrestore(&device->card->lock, flags); 165 spin_unlock_irqrestore(&device->card->lock, flags);
177 166
178 fw_node_put(device->node); 167 fw_node_put(device->node);
179 fw_card_put(device->card);
180 kfree(device->config_rom); 168 kfree(device->config_rom);
181 kfree(device); 169 kfree(device);
170 atomic_dec(&card->device_count);
182} 171}
183 172
184int fw_device_enable_phys_dma(struct fw_device *device) 173int fw_device_enable_phys_dma(struct fw_device *device)
@@ -668,7 +657,8 @@ static void fw_device_init(struct work_struct *work)
668 */ 657 */
669 658
670 if (read_bus_info_block(device, device->generation) < 0) { 659 if (read_bus_info_block(device, device->generation) < 0) {
671 if (device->config_rom_retries < MAX_RETRIES) { 660 if (device->config_rom_retries < MAX_RETRIES &&
661 atomic_read(&device->state) == FW_DEVICE_INITIALIZING) {
672 device->config_rom_retries++; 662 device->config_rom_retries++;
673 schedule_delayed_work(&device->work, RETRY_DELAY); 663 schedule_delayed_work(&device->work, RETRY_DELAY);
674 } else { 664 } else {
@@ -805,7 +795,8 @@ void fw_node_event(struct fw_card *card, struct fw_node *node, int event)
805 */ 795 */
806 device_initialize(&device->device); 796 device_initialize(&device->device);
807 atomic_set(&device->state, FW_DEVICE_INITIALIZING); 797 atomic_set(&device->state, FW_DEVICE_INITIALIZING);
808 device->card = fw_card_get(card); 798 atomic_inc(&card->device_count);
799 device->card = card;
809 device->node = fw_node_get(node); 800 device->node = fw_node_get(node);
810 device->node_id = node->node_id; 801 device->node_id = node->node_id;
811 device->generation = card->generation; 802 device->generation = card->generation;
diff --git a/drivers/firewire/fw-device.h b/drivers/firewire/fw-device.h
index 43808c02793e..78ecd3991b7f 100644
--- a/drivers/firewire/fw-device.h
+++ b/drivers/firewire/fw-device.h
@@ -76,9 +76,21 @@ fw_device_is_shutdown(struct fw_device *device)
76 return atomic_read(&device->state) == FW_DEVICE_SHUTDOWN; 76 return atomic_read(&device->state) == FW_DEVICE_SHUTDOWN;
77} 77}
78 78
79struct fw_device *fw_device_get(struct fw_device *device); 79static inline struct fw_device *
80fw_device_get(struct fw_device *device)
81{
82 get_device(&device->device);
83
84 return device;
85}
86
87static inline void
88fw_device_put(struct fw_device *device)
89{
90 put_device(&device->device);
91}
92
80struct fw_device *fw_device_get_by_devt(dev_t devt); 93struct fw_device *fw_device_get_by_devt(dev_t devt);
81void fw_device_put(struct fw_device *device);
82int fw_device_enable_phys_dma(struct fw_device *device); 94int fw_device_enable_phys_dma(struct fw_device *device);
83 95
84void fw_device_cdev_update(struct fw_device *device); 96void fw_device_cdev_update(struct fw_device *device);
diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c
index a093ac329db7..03069a454c07 100644
--- a/drivers/firewire/fw-sbp2.c
+++ b/drivers/firewire/fw-sbp2.c
@@ -769,6 +769,7 @@ static void sbp2_release_target(struct kref *kref)
769 struct Scsi_Host *shost = 769 struct Scsi_Host *shost =
770 container_of((void *)tgt, struct Scsi_Host, hostdata[0]); 770 container_of((void *)tgt, struct Scsi_Host, hostdata[0]);
771 struct scsi_device *sdev; 771 struct scsi_device *sdev;
772 struct fw_device *device = fw_device(tgt->unit->device.parent);
772 773
773 /* prevent deadlocks */ 774 /* prevent deadlocks */
774 sbp2_unblock(tgt); 775 sbp2_unblock(tgt);
@@ -791,6 +792,7 @@ static void sbp2_release_target(struct kref *kref)
791 792
792 put_device(&tgt->unit->device); 793 put_device(&tgt->unit->device);
793 scsi_host_put(shost); 794 scsi_host_put(shost);
795 fw_device_put(device);
794} 796}
795 797
796static struct workqueue_struct *sbp2_wq; 798static struct workqueue_struct *sbp2_wq;
@@ -1088,6 +1090,8 @@ static int sbp2_probe(struct device *dev)
1088 if (scsi_add_host(shost, &unit->device) < 0) 1090 if (scsi_add_host(shost, &unit->device) < 0)
1089 goto fail_shost_put; 1091 goto fail_shost_put;
1090 1092
1093 fw_device_get(device);
1094
1091 /* Initialize to values that won't match anything in our table. */ 1095 /* Initialize to values that won't match anything in our table. */
1092 firmware_revision = 0xff000000; 1096 firmware_revision = 0xff000000;
1093 model = 0xff000000; 1097 model = 0xff000000;
diff --git a/drivers/firewire/fw-transaction.h b/drivers/firewire/fw-transaction.h
index fa7967b57408..09cb72870454 100644
--- a/drivers/firewire/fw-transaction.h
+++ b/drivers/firewire/fw-transaction.h
@@ -26,6 +26,7 @@
26#include <linux/fs.h> 26#include <linux/fs.h>
27#include <linux/dma-mapping.h> 27#include <linux/dma-mapping.h>
28#include <linux/firewire-constants.h> 28#include <linux/firewire-constants.h>
29#include <asm/atomic.h>
29 30
30#define TCODE_IS_READ_REQUEST(tcode) (((tcode) & ~1) == 4) 31#define TCODE_IS_READ_REQUEST(tcode) (((tcode) & ~1) == 4)
31#define TCODE_IS_BLOCK_PACKET(tcode) (((tcode) & 1) != 0) 32#define TCODE_IS_BLOCK_PACKET(tcode) (((tcode) & 1) != 0)
@@ -219,6 +220,7 @@ extern struct bus_type fw_bus_type;
219struct fw_card { 220struct fw_card {
220 const struct fw_card_driver *driver; 221 const struct fw_card_driver *driver;
221 struct device *device; 222 struct device *device;
223 atomic_t device_count;
222 struct kref kref; 224 struct kref kref;
223 225
224 int node_id; 226 int node_id;