aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firewire/fw-device-cdev.c
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@redhat.com>2007-03-07 12:12:41 -0500
committerStefan Richter <stefanr@s5r6.in-berlin.de>2007-03-09 16:03:08 -0500
commit97bd9efa5a4d8a70b3bafe0d1e3e1a814fdac5bc (patch)
tree7f405323e9b6ccd690b7673cc4495d35e5926a06 /drivers/firewire/fw-device-cdev.c
parent1da0c93b31bb8f374a22f4e20dab02fd79f6c7e6 (diff)
firewire: Add a bus reset event type for fw-device-cdev.
Signed-off-by: Kristian Høgsberg <krh@redhat.com> Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
Diffstat (limited to 'drivers/firewire/fw-device-cdev.c')
-rw-r--r--drivers/firewire/fw-device-cdev.c56
1 files changed, 56 insertions, 0 deletions
diff --git a/drivers/firewire/fw-device-cdev.c b/drivers/firewire/fw-device-cdev.c
index 33fe5768a078..9f3c96c7af29 100644
--- a/drivers/firewire/fw-device-cdev.c
+++ b/drivers/firewire/fw-device-cdev.c
@@ -50,6 +50,11 @@ struct event {
50 struct list_head link; 50 struct list_head link;
51}; 51};
52 52
53struct bus_reset {
54 struct event event;
55 struct fw_cdev_event_bus_reset reset;
56};
57
53struct response { 58struct response {
54 struct event event; 59 struct event event;
55 struct fw_transaction transaction; 60 struct fw_transaction transaction;
@@ -75,6 +80,8 @@ struct client {
75 struct fw_iso_context *iso_context; 80 struct fw_iso_context *iso_context;
76 struct fw_iso_buffer buffer; 81 struct fw_iso_buffer buffer;
77 unsigned long vm_start; 82 unsigned long vm_start;
83
84 struct list_head link;
78}; 85};
79 86
80static inline void __user * 87static inline void __user *
@@ -93,6 +100,7 @@ static int fw_device_op_open(struct inode *inode, struct file *file)
93{ 100{
94 struct fw_device *device; 101 struct fw_device *device;
95 struct client *client; 102 struct client *client;
103 unsigned long flags;
96 104
97 device = container_of(inode->i_cdev, struct fw_device, cdev); 105 device = container_of(inode->i_cdev, struct fw_device, cdev);
98 106
@@ -110,6 +118,10 @@ static int fw_device_op_open(struct inode *inode, struct file *file)
110 118
111 file->private_data = client; 119 file->private_data = client;
112 120
121 spin_lock_irqsave(&device->card->lock, flags);
122 list_add_tail(&client->link, &device->client_list);
123 spin_unlock_irqrestore(&device->card->lock, flags);
124
113 return 0; 125 return 0;
114} 126}
115 127
@@ -177,6 +189,45 @@ fw_device_op_read(struct file *file,
177 return dequeue_event(client, buffer, count); 189 return dequeue_event(client, buffer, count);
178} 190}
179 191
192static void
193queue_bus_reset_event(struct client *client)
194{
195 struct bus_reset *bus_reset;
196 struct fw_device *device = client->device;
197 struct fw_card *card = device->card;
198
199 bus_reset = kzalloc(sizeof *bus_reset, GFP_ATOMIC);
200 if (bus_reset == NULL) {
201 fw_notify("Out of memory when allocating bus reset event\n");
202 return;
203 }
204
205 bus_reset->reset.type = FW_CDEV_EVENT_BUS_RESET;
206 bus_reset->reset.node_id = device->node_id;
207 bus_reset->reset.local_node_id = card->local_node->node_id;
208 bus_reset->reset.bm_node_id = 0; /* FIXME: We don't track the BM. */
209 bus_reset->reset.irm_node_id = card->irm_node->node_id;
210 bus_reset->reset.root_node_id = card->root_node->node_id;
211 bus_reset->reset.generation = card->generation;
212
213 queue_event(client, &bus_reset->event,
214 &bus_reset->reset, sizeof bus_reset->reset, NULL, 0);
215}
216
217void fw_device_cdev_update(struct fw_device *device)
218{
219 struct fw_card *card = device->card;
220 struct client *c;
221 unsigned long flags;
222
223 spin_lock_irqsave(&card->lock, flags);
224
225 list_for_each_entry(c, &device->client_list, link)
226 queue_bus_reset_event(c);
227
228 spin_unlock_irqrestore(&card->lock, flags);
229}
230
180static int ioctl_config_rom(struct client *client, void __user *arg) 231static int ioctl_config_rom(struct client *client, void __user *arg)
181{ 232{
182 struct fw_cdev_get_config_rom rom; 233 struct fw_cdev_get_config_rom rom;
@@ -633,6 +684,7 @@ static int fw_device_op_release(struct inode *inode, struct file *file)
633 struct client *client = file->private_data; 684 struct client *client = file->private_data;
634 struct address_handler *h, *next; 685 struct address_handler *h, *next;
635 struct request *r, *next_r; 686 struct request *r, *next_r;
687 unsigned long flags;
636 688
637 if (client->buffer.pages) 689 if (client->buffer.pages)
638 fw_iso_buffer_destroy(&client->buffer, client->device->card); 690 fw_iso_buffer_destroy(&client->buffer, client->device->card);
@@ -657,6 +709,10 @@ static int fw_device_op_release(struct inode *inode, struct file *file)
657 while (!list_empty(&client->event_list)) 709 while (!list_empty(&client->event_list))
658 dequeue_event(client, NULL, 0); 710 dequeue_event(client, NULL, 0);
659 711
712 spin_lock_irqsave(&client->device->card->lock, flags);
713 list_del(&client->link);
714 spin_unlock_irqrestore(&client->device->card->lock, flags);
715
660 fw_device_put(client->device); 716 fw_device_put(client->device);
661 kfree(client); 717 kfree(client);
662 718