firewire: don't use extern on public symbols
[linux-2.6] / drivers / firewire / fw-device-cdev.c
1 /*                                              -*- c-basic-offset: 8 -*-
2  *
3  * fw-device-cdev.c - Char device for device raw access
4  *
5  * Copyright (C) 2005-2006  Kristian Hoegsberg <krh@bitplanet.net>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software Foundation,
19  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20  */
21
22 #include <linux/module.h>
23 #include <linux/kernel.h>
24 #include <linux/wait.h>
25 #include <linux/errno.h>
26 #include <linux/device.h>
27 #include <linux/vmalloc.h>
28 #include <linux/poll.h>
29 #include <linux/delay.h>
30 #include <linux/mm.h>
31 #include <linux/idr.h>
32 #include <linux/compat.h>
33 #include <asm/uaccess.h>
34 #include "fw-transaction.h"
35 #include "fw-topology.h"
36 #include "fw-device.h"
37 #include "fw-device-cdev.h"
38
39 /* dequeue_event() just kfree()'s the event, so the event has to be
40  * the first field in the struct. */
41
42 struct client;
43 struct client_resource {
44         struct list_head link;
45         void (*release)(struct client *client, struct client_resource *r);
46         u32 handle;
47 };
48
49 struct event {
50         struct { void *data; size_t size; } v[2];
51         struct list_head link;
52 };
53
54 struct bus_reset {
55         struct event event;
56         struct fw_cdev_event_bus_reset reset;
57 };
58
59 struct response {
60         struct event event;
61         struct fw_transaction transaction;
62         struct client *client;
63         struct client_resource resource;
64         struct fw_cdev_event_response response;
65 };
66
67 struct iso_interrupt {
68         struct event event;
69         struct fw_cdev_event_iso_interrupt interrupt;
70 };
71
72 struct client {
73         u32 version;
74         struct fw_device *device;
75         spinlock_t lock;
76         u32 resource_handle;
77         struct list_head resource_list;
78         struct list_head event_list;
79         wait_queue_head_t wait;
80         u64 bus_reset_closure;
81
82         struct fw_iso_context *iso_context;
83         struct fw_iso_buffer buffer;
84         unsigned long vm_start;
85
86         struct list_head link;
87 };
88
89 static inline void __user *
90 u64_to_uptr(__u64 value)
91 {
92         return (void __user *)(unsigned long)value;
93 }
94
95 static inline __u64
96 uptr_to_u64(void __user *ptr)
97 {
98         return (__u64)(unsigned long)ptr;
99 }
100
101 static int fw_device_op_open(struct inode *inode, struct file *file)
102 {
103         struct fw_device *device;
104         struct client *client;
105         unsigned long flags;
106
107         device = fw_device_from_devt(inode->i_rdev);
108         if (device == NULL)
109                 return -ENODEV;
110
111         client = kzalloc(sizeof *client, GFP_KERNEL);
112         if (client == NULL)
113                 return -ENOMEM;
114
115         client->device = fw_device_get(device);
116         INIT_LIST_HEAD(&client->event_list);
117         INIT_LIST_HEAD(&client->resource_list);
118         spin_lock_init(&client->lock);
119         init_waitqueue_head(&client->wait);
120
121         file->private_data = client;
122
123         spin_lock_irqsave(&device->card->lock, flags);
124         list_add_tail(&client->link, &device->client_list);
125         spin_unlock_irqrestore(&device->card->lock, flags);
126
127         return 0;
128 }
129
130 static void queue_event(struct client *client, struct event *event,
131                         void *data0, size_t size0, void *data1, size_t size1)
132 {
133         unsigned long flags;
134
135         event->v[0].data = data0;
136         event->v[0].size = size0;
137         event->v[1].data = data1;
138         event->v[1].size = size1;
139
140         spin_lock_irqsave(&client->lock, flags);
141
142         list_add_tail(&event->link, &client->event_list);
143         wake_up_interruptible(&client->wait);
144
145         spin_unlock_irqrestore(&client->lock, flags);
146 }
147
148 static int
149 dequeue_event(struct client *client, char __user *buffer, size_t count)
150 {
151         unsigned long flags;
152         struct event *event;
153         size_t size, total;
154         int i, retval;
155
156         retval = wait_event_interruptible(client->wait,
157                                           !list_empty(&client->event_list) ||
158                                           fw_device_is_shutdown(client->device));
159         if (retval < 0)
160                 return retval;
161
162         if (list_empty(&client->event_list) &&
163                        fw_device_is_shutdown(client->device))
164                 return -ENODEV;
165
166         spin_lock_irqsave(&client->lock, flags);
167         event = container_of(client->event_list.next, struct event, link);
168         list_del(&event->link);
169         spin_unlock_irqrestore(&client->lock, flags);
170
171         total = 0;
172         for (i = 0; i < ARRAY_SIZE(event->v) && total < count; i++) {
173                 size = min(event->v[i].size, count - total);
174                 if (copy_to_user(buffer + total, event->v[i].data, size)) {
175                         retval = -EFAULT;
176                         goto out;
177                 }
178                 total += size;
179         }
180         retval = total;
181
182  out:
183         kfree(event);
184
185         return retval;
186 }
187
188 static ssize_t
189 fw_device_op_read(struct file *file,
190                   char __user *buffer, size_t count, loff_t *offset)
191 {
192         struct client *client = file->private_data;
193
194         return dequeue_event(client, buffer, count);
195 }
196
197 static void
198 fill_bus_reset_event(struct fw_cdev_event_bus_reset *event,
199                      struct client *client)
200 {
201         struct fw_card *card = client->device->card;
202
203         event->closure       = client->bus_reset_closure;
204         event->type          = FW_CDEV_EVENT_BUS_RESET;
205         event->node_id       = client->device->node_id;
206         event->local_node_id = card->local_node->node_id;
207         event->bm_node_id    = 0; /* FIXME: We don't track the BM. */
208         event->irm_node_id   = card->irm_node->node_id;
209         event->root_node_id  = card->root_node->node_id;
210         event->generation    = card->generation;
211 }
212
213 static void
214 for_each_client(struct fw_device *device,
215                 void (*callback)(struct client *client))
216 {
217         struct fw_card *card = device->card;
218         struct client *c;
219         unsigned long flags;
220
221         spin_lock_irqsave(&card->lock, flags);
222
223         list_for_each_entry(c, &device->client_list, link)
224                 callback(c);
225
226         spin_unlock_irqrestore(&card->lock, flags);
227 }
228
229 static void
230 queue_bus_reset_event(struct client *client)
231 {
232         struct bus_reset *bus_reset;
233
234         bus_reset = kzalloc(sizeof *bus_reset, GFP_ATOMIC);
235         if (bus_reset == NULL) {
236                 fw_notify("Out of memory when allocating bus reset event\n");
237                 return;
238         }
239
240         fill_bus_reset_event(&bus_reset->reset, client);
241
242         queue_event(client, &bus_reset->event,
243                     &bus_reset->reset, sizeof bus_reset->reset, NULL, 0);
244 }
245
246 void fw_device_cdev_update(struct fw_device *device)
247 {
248         for_each_client(device, queue_bus_reset_event);
249 }
250
251 static void wake_up_client(struct client *client)
252 {
253         wake_up_interruptible(&client->wait);
254 }
255
256 void fw_device_cdev_remove(struct fw_device *device)
257 {
258         for_each_client(device, wake_up_client);
259 }
260
261 static int ioctl_get_info(struct client *client, void __user *arg)
262 {
263         struct fw_cdev_get_info get_info;
264         struct fw_cdev_event_bus_reset bus_reset;
265
266         if (copy_from_user(&get_info, arg, sizeof get_info))
267                 return -EFAULT;
268
269         client->version = get_info.version;
270         get_info.version = FW_CDEV_VERSION;
271
272         if (get_info.rom != 0) {
273                 void __user *uptr = u64_to_uptr(get_info.rom);
274                 size_t want = get_info.rom_length;
275                 size_t have = client->device->config_rom_length * 4;
276
277                 if (copy_to_user(uptr, client->device->config_rom,
278                                  min(want, have)))
279                         return -EFAULT;
280         }
281         get_info.rom_length = client->device->config_rom_length * 4;
282
283         client->bus_reset_closure = get_info.bus_reset_closure;
284         if (get_info.bus_reset != 0) {
285                 void __user *uptr = u64_to_uptr(get_info.bus_reset);
286
287                 fill_bus_reset_event(&bus_reset, client);
288                 if (copy_to_user(uptr, &bus_reset, sizeof bus_reset))
289                         return -EFAULT;
290         }
291
292         get_info.card = client->device->card->index;
293
294         if (copy_to_user(arg, &get_info, sizeof get_info))
295                 return -EFAULT;
296
297         return 0;
298 }
299
300 static void
301 add_client_resource(struct client *client, struct client_resource *resource)
302 {
303         unsigned long flags;
304
305         spin_lock_irqsave(&client->lock, flags);
306         list_add_tail(&resource->link, &client->resource_list);
307         resource->handle = client->resource_handle++;
308         spin_unlock_irqrestore(&client->lock, flags);
309 }
310
311 static int
312 release_client_resource(struct client *client, u32 handle,
313                         struct client_resource **resource)
314 {
315         struct client_resource *r;
316         unsigned long flags;
317
318         spin_lock_irqsave(&client->lock, flags);
319         list_for_each_entry(r, &client->resource_list, link) {
320                 if (r->handle == handle) {
321                         list_del(&r->link);
322                         break;
323                 }
324         }
325         spin_unlock_irqrestore(&client->lock, flags);
326
327         if (&r->link == &client->resource_list)
328                 return -EINVAL;
329
330         if (resource)
331                 *resource = r;
332         else
333                 r->release(client, r);
334
335         return 0;
336 }
337
338 static void
339 release_transaction(struct client *client, struct client_resource *resource)
340 {
341         struct response *response =
342                 container_of(resource, struct response, resource);
343
344         fw_cancel_transaction(client->device->card, &response->transaction);
345 }
346
347 static void
348 complete_transaction(struct fw_card *card, int rcode,
349                      void *payload, size_t length, void *data)
350 {
351         struct response *response = data;
352         struct client *client = response->client;
353         unsigned long flags;
354
355         if (length < response->response.length)
356                 response->response.length = length;
357         if (rcode == RCODE_COMPLETE)
358                 memcpy(response->response.data, payload,
359                        response->response.length);
360
361         spin_lock_irqsave(&client->lock, flags);
362         list_del(&response->resource.link);
363         spin_unlock_irqrestore(&client->lock, flags);
364
365         response->response.type   = FW_CDEV_EVENT_RESPONSE;
366         response->response.rcode  = rcode;
367         queue_event(client, &response->event,
368                     &response->response, sizeof response->response,
369                     response->response.data, response->response.length);
370 }
371
372 static ssize_t ioctl_send_request(struct client *client, void __user *arg)
373 {
374         struct fw_device *device = client->device;
375         struct fw_cdev_send_request request;
376         struct response *response;
377
378         if (copy_from_user(&request, arg, sizeof request))
379                 return -EFAULT;
380
381         /* What is the biggest size we'll accept, really? */
382         if (request.length > 4096)
383                 return -EINVAL;
384
385         response = kmalloc(sizeof *response + request.length, GFP_KERNEL);
386         if (response == NULL)
387                 return -ENOMEM;
388
389         response->client = client;
390         response->response.length = request.length;
391         response->response.closure = request.closure;
392
393         if (request.data &&
394             copy_from_user(response->response.data,
395                            u64_to_uptr(request.data), request.length)) {
396                 kfree(response);
397                 return -EFAULT;
398         }
399
400         response->resource.release = release_transaction;
401         add_client_resource(client, &response->resource);
402
403         fw_send_request(device->card, &response->transaction,
404                         request.tcode & 0x1f,
405                         device->node->node_id,
406                         request.generation,
407                         device->node->max_speed,
408                         request.offset,
409                         response->response.data, request.length,
410                         complete_transaction, response);
411
412         if (request.data)
413                 return sizeof request + request.length;
414         else
415                 return sizeof request;
416 }
417
418 struct address_handler {
419         struct fw_address_handler handler;
420         __u64 closure;
421         struct client *client;
422         struct client_resource resource;
423 };
424
425 struct request {
426         struct fw_request *request;
427         void *data;
428         size_t length;
429         struct client_resource resource;
430 };
431
432 struct request_event {
433         struct event event;
434         struct fw_cdev_event_request request;
435 };
436
437 static void
438 release_request(struct client *client, struct client_resource *resource)
439 {
440         struct request *request =
441                 container_of(resource, struct request, resource);
442
443         fw_send_response(client->device->card, request->request,
444                          RCODE_CONFLICT_ERROR);
445         kfree(request);
446 }
447
448 static void
449 handle_request(struct fw_card *card, struct fw_request *r,
450                int tcode, int destination, int source,
451                int generation, int speed,
452                unsigned long long offset,
453                void *payload, size_t length, void *callback_data)
454 {
455         struct address_handler *handler = callback_data;
456         struct request *request;
457         struct request_event *e;
458         struct client *client = handler->client;
459
460         request = kmalloc(sizeof *request, GFP_ATOMIC);
461         e = kmalloc(sizeof *e, GFP_ATOMIC);
462         if (request == NULL || e == NULL) {
463                 kfree(request);
464                 kfree(e);
465                 fw_send_response(card, r, RCODE_CONFLICT_ERROR);
466                 return;
467         }
468
469         request->request = r;
470         request->data    = payload;
471         request->length  = length;
472
473         request->resource.release = release_request;
474         add_client_resource(client, &request->resource);
475
476         e->request.type    = FW_CDEV_EVENT_REQUEST;
477         e->request.tcode   = tcode;
478         e->request.offset  = offset;
479         e->request.length  = length;
480         e->request.handle  = request->resource.handle;
481         e->request.closure = handler->closure;
482
483         queue_event(client, &e->event,
484                     &e->request, sizeof e->request, payload, length);
485 }
486
487 static void
488 release_address_handler(struct client *client,
489                         struct client_resource *resource)
490 {
491         struct address_handler *handler =
492                 container_of(resource, struct address_handler, resource);
493
494         fw_core_remove_address_handler(&handler->handler);
495         kfree(handler);
496 }
497
498 static int ioctl_allocate(struct client *client, void __user *arg)
499 {
500         struct fw_cdev_allocate request;
501         struct address_handler *handler;
502         struct fw_address_region region;
503
504         if (copy_from_user(&request, arg, sizeof request))
505                 return -EFAULT;
506
507         handler = kmalloc(sizeof *handler, GFP_KERNEL);
508         if (handler == NULL)
509                 return -ENOMEM;
510
511         region.start = request.offset;
512         region.end = request.offset + request.length;
513         handler->handler.length = request.length;
514         handler->handler.address_callback = handle_request;
515         handler->handler.callback_data = handler;
516         handler->closure = request.closure;
517         handler->client = client;
518
519         if (fw_core_add_address_handler(&handler->handler, &region) < 0) {
520                 kfree(handler);
521                 return -EBUSY;
522         }
523
524         handler->resource.release = release_address_handler;
525         add_client_resource(client, &handler->resource);
526         request.handle = handler->resource.handle;
527
528         if (copy_to_user(arg, &request, sizeof request))
529                 return -EFAULT;
530
531         return 0;
532 }
533
534 static int ioctl_deallocate(struct client *client, void __user *arg)
535 {
536         struct fw_cdev_deallocate request;
537
538         if (copy_from_user(&request, arg, sizeof request))
539                 return -EFAULT;
540
541         return release_client_resource(client, request.handle, NULL);
542 }
543
544 static int ioctl_send_response(struct client *client, void __user *arg)
545 {
546         struct fw_cdev_send_response request;
547         struct client_resource *resource;
548         struct request *r;
549
550         if (copy_from_user(&request, arg, sizeof request))
551                 return -EFAULT;
552         if (release_client_resource(client, request.handle, &resource) < 0)
553                 return -EINVAL;
554         r = container_of(resource, struct request, resource);
555         if (request.length < r->length)
556                 r->length = request.length;
557         if (copy_from_user(r->data, u64_to_uptr(request.data), r->length))
558                 return -EFAULT;
559
560         fw_send_response(client->device->card, r->request, request.rcode);
561         kfree(r);
562
563         return 0;
564 }
565
566 static int ioctl_initiate_bus_reset(struct client *client, void __user *arg)
567 {
568         struct fw_cdev_initiate_bus_reset request;
569         int short_reset;
570
571         if (copy_from_user(&request, arg, sizeof request))
572                 return -EFAULT;
573
574         short_reset = (request.type == FW_CDEV_SHORT_RESET);
575
576         return fw_core_initiate_bus_reset(client->device->card, short_reset);
577 }
578
579 struct descriptor {
580         struct fw_descriptor d;
581         struct client_resource resource;
582         u32 data[0];
583 };
584
585 static void release_descriptor(struct client *client,
586                                struct client_resource *resource)
587 {
588         struct descriptor *descriptor =
589                 container_of(resource, struct descriptor, resource);
590
591         fw_core_remove_descriptor(&descriptor->d);
592         kfree(descriptor);
593 }
594
595 static int ioctl_add_descriptor(struct client *client, void __user *arg)
596 {
597         struct fw_cdev_add_descriptor request;
598         struct descriptor *descriptor;
599         int retval;
600
601         if (copy_from_user(&request, arg, sizeof request))
602                 return -EFAULT;
603
604         if (request.length > 256)
605                 return -EINVAL;
606
607         descriptor =
608                 kmalloc(sizeof *descriptor + request.length * 4, GFP_KERNEL);
609         if (descriptor == NULL)
610                 return -ENOMEM;
611
612         if (copy_from_user(descriptor->data,
613                            u64_to_uptr(request.data), request.length * 4)) {
614                 kfree(descriptor);
615                 return -EFAULT;
616         }
617
618         descriptor->d.length = request.length;
619         descriptor->d.immediate = request.immediate;
620         descriptor->d.key = request.key;
621         descriptor->d.data = descriptor->data;
622
623         retval = fw_core_add_descriptor(&descriptor->d);
624         if (retval < 0) {
625                 kfree(descriptor);
626                 return retval;
627         }
628
629         descriptor->resource.release = release_descriptor;
630         add_client_resource(client, &descriptor->resource);
631         request.handle = descriptor->resource.handle;
632
633         if (copy_to_user(arg, &request, sizeof request))
634                 return -EFAULT;
635
636         return 0;
637 }
638
639 static int ioctl_remove_descriptor(struct client *client, void __user *arg)
640 {
641         struct fw_cdev_remove_descriptor request;
642
643         if (copy_from_user(&request, arg, sizeof request))
644                 return -EFAULT;
645
646         return release_client_resource(client, request.handle, NULL);
647 }
648
649 static void
650 iso_callback(struct fw_iso_context *context, u32 cycle,
651              size_t header_length, void *header, void *data)
652 {
653         struct client *client = data;
654         struct iso_interrupt *interrupt;
655
656         interrupt = kzalloc(sizeof *interrupt + header_length, GFP_ATOMIC);
657         if (interrupt == NULL)
658                 return;
659
660         interrupt->interrupt.type      = FW_CDEV_EVENT_ISO_INTERRUPT;
661         interrupt->interrupt.closure   = 0;
662         interrupt->interrupt.cycle     = cycle;
663         interrupt->interrupt.header_length = header_length;
664         memcpy(interrupt->interrupt.header, header, header_length);
665         queue_event(client, &interrupt->event,
666                     &interrupt->interrupt,
667                     sizeof interrupt->interrupt + header_length, NULL, 0);
668 }
669
670 static int ioctl_create_iso_context(struct client *client, void __user *arg)
671 {
672         struct fw_cdev_create_iso_context request;
673
674         if (copy_from_user(&request, arg, sizeof request))
675                 return -EFAULT;
676
677         if (request.channel > 63)
678                 return -EINVAL;
679
680         switch (request.type) {
681         case FW_ISO_CONTEXT_RECEIVE:
682                 if (request.header_size < 4 || (request.header_size & 3))
683                         return -EINVAL;
684
685                 break;
686
687         case FW_ISO_CONTEXT_TRANSMIT:
688                 if (request.speed > SCODE_3200)
689                         return -EINVAL;
690
691                 break;
692
693         default:
694                 return -EINVAL;
695         }
696
697         client->iso_context = fw_iso_context_create(client->device->card,
698                                                     request.type,
699                                                     request.channel,
700                                                     request.speed,
701                                                     request.header_size,
702                                                     iso_callback, client);
703         if (IS_ERR(client->iso_context))
704                 return PTR_ERR(client->iso_context);
705
706         return 0;
707 }
708
709 static int ioctl_queue_iso(struct client *client, void __user *arg)
710 {
711         struct fw_cdev_queue_iso request;
712         struct fw_cdev_iso_packet __user *p, *end, *next;
713         struct fw_iso_context *ctx = client->iso_context;
714         unsigned long payload, buffer_end, header_length;
715         int count;
716         struct {
717                 struct fw_iso_packet packet;
718                 u8 header[256];
719         } u;
720
721         if (ctx == NULL)
722                 return -EINVAL;
723         if (copy_from_user(&request, arg, sizeof request))
724                 return -EFAULT;
725
726         /* If the user passes a non-NULL data pointer, has mmap()'ed
727          * the iso buffer, and the pointer points inside the buffer,
728          * we setup the payload pointers accordingly.  Otherwise we
729          * set them both to 0, which will still let packets with
730          * payload_length == 0 through.  In other words, if no packets
731          * use the indirect payload, the iso buffer need not be mapped
732          * and the request.data pointer is ignored.*/
733
734         payload = (unsigned long)request.data - client->vm_start;
735         buffer_end = client->buffer.page_count << PAGE_SHIFT;
736         if (request.data == 0 || client->buffer.pages == NULL ||
737             payload >= buffer_end) {
738                 payload = 0;
739                 buffer_end = 0;
740         }
741
742         if (!access_ok(VERIFY_READ, request.packets, request.size))
743                 return -EFAULT;
744
745         p = (struct fw_cdev_iso_packet __user *)u64_to_uptr(request.packets);
746         end = (void __user *)p + request.size;
747         count = 0;
748         while (p < end) {
749                 if (__copy_from_user(&u.packet, p, sizeof *p))
750                         return -EFAULT;
751
752                 if (ctx->type == FW_ISO_CONTEXT_TRANSMIT) {
753                         header_length = u.packet.header_length;
754                 } else {
755                         /* We require that header_length is a multiple of
756                          * the fixed header size, ctx->header_size */
757                         if (ctx->header_size == 0) {
758                                 if (u.packet.header_length > 0)
759                                         return -EINVAL;
760                         } else if (u.packet.header_length % ctx->header_size != 0) {
761                                 return -EINVAL;
762                         }
763                         header_length = 0;
764                 }
765
766                 next = (struct fw_cdev_iso_packet __user *)
767                         &p->header[header_length / 4];
768                 if (next > end)
769                         return -EINVAL;
770                 if (__copy_from_user
771                     (u.packet.header, p->header, header_length))
772                         return -EFAULT;
773                 if (u.packet.skip && ctx->type == FW_ISO_CONTEXT_TRANSMIT &&
774                     u.packet.header_length + u.packet.payload_length > 0)
775                         return -EINVAL;
776                 if (payload + u.packet.payload_length > buffer_end)
777                         return -EINVAL;
778
779                 if (fw_iso_context_queue(ctx, &u.packet,
780                                          &client->buffer, payload))
781                         break;
782
783                 p = next;
784                 payload += u.packet.payload_length;
785                 count++;
786         }
787
788         request.size    -= uptr_to_u64(p) - request.packets;
789         request.packets  = uptr_to_u64(p);
790         request.data     = client->vm_start + payload;
791
792         if (copy_to_user(arg, &request, sizeof request))
793                 return -EFAULT;
794
795         return count;
796 }
797
798 static int ioctl_start_iso(struct client *client, void __user *arg)
799 {
800         struct fw_cdev_start_iso request;
801
802         if (copy_from_user(&request, arg, sizeof request))
803                 return -EFAULT;
804
805         if (client->iso_context->type == FW_ISO_CONTEXT_RECEIVE) {
806                 if (request.tags == 0 || request.tags > 15)
807                         return -EINVAL;
808
809                 if (request.sync > 15)
810                         return -EINVAL;
811         }
812
813         return fw_iso_context_start(client->iso_context,
814                                     request.cycle, request.sync, request.tags);
815 }
816
817 static int ioctl_stop_iso(struct client *client, void __user *arg)
818 {
819         return fw_iso_context_stop(client->iso_context);
820 }
821
822 static int
823 dispatch_ioctl(struct client *client, unsigned int cmd, void __user *arg)
824 {
825         switch (cmd) {
826         case FW_CDEV_IOC_GET_INFO:
827                 return ioctl_get_info(client, arg);
828         case FW_CDEV_IOC_SEND_REQUEST:
829                 return ioctl_send_request(client, arg);
830         case FW_CDEV_IOC_ALLOCATE:
831                 return ioctl_allocate(client, arg);
832         case FW_CDEV_IOC_DEALLOCATE:
833                 return ioctl_deallocate(client, arg);
834         case FW_CDEV_IOC_SEND_RESPONSE:
835                 return ioctl_send_response(client, arg);
836         case FW_CDEV_IOC_INITIATE_BUS_RESET:
837                 return ioctl_initiate_bus_reset(client, arg);
838         case FW_CDEV_IOC_ADD_DESCRIPTOR:
839                 return ioctl_add_descriptor(client, arg);
840         case FW_CDEV_IOC_REMOVE_DESCRIPTOR:
841                 return ioctl_remove_descriptor(client, arg);
842         case FW_CDEV_IOC_CREATE_ISO_CONTEXT:
843                 return ioctl_create_iso_context(client, arg);
844         case FW_CDEV_IOC_QUEUE_ISO:
845                 return ioctl_queue_iso(client, arg);
846         case FW_CDEV_IOC_START_ISO:
847                 return ioctl_start_iso(client, arg);
848         case FW_CDEV_IOC_STOP_ISO:
849                 return ioctl_stop_iso(client, arg);
850         default:
851                 return -EINVAL;
852         }
853 }
854
855 static long
856 fw_device_op_ioctl(struct file *file,
857                    unsigned int cmd, unsigned long arg)
858 {
859         struct client *client = file->private_data;
860
861         return dispatch_ioctl(client, cmd, (void __user *) arg);
862 }
863
864 #ifdef CONFIG_COMPAT
865 static long
866 fw_device_op_compat_ioctl(struct file *file,
867                           unsigned int cmd, unsigned long arg)
868 {
869         struct client *client = file->private_data;
870
871         return dispatch_ioctl(client, cmd, compat_ptr(arg));
872 }
873 #endif
874
875 static int fw_device_op_mmap(struct file *file, struct vm_area_struct *vma)
876 {
877         struct client *client = file->private_data;
878         enum dma_data_direction direction;
879         unsigned long size;
880         int page_count, retval;
881
882         /* FIXME: We could support multiple buffers, but we don't. */
883         if (client->buffer.pages != NULL)
884                 return -EBUSY;
885
886         if (!(vma->vm_flags & VM_SHARED))
887                 return -EINVAL;
888
889         if (vma->vm_start & ~PAGE_MASK)
890                 return -EINVAL;
891
892         client->vm_start = vma->vm_start;
893         size = vma->vm_end - vma->vm_start;
894         page_count = size >> PAGE_SHIFT;
895         if (size & ~PAGE_MASK)
896                 return -EINVAL;
897
898         if (vma->vm_flags & VM_WRITE)
899                 direction = DMA_TO_DEVICE;
900         else
901                 direction = DMA_FROM_DEVICE;
902
903         retval = fw_iso_buffer_init(&client->buffer, client->device->card,
904                                     page_count, direction);
905         if (retval < 0)
906                 return retval;
907
908         retval = fw_iso_buffer_map(&client->buffer, vma);
909         if (retval < 0)
910                 fw_iso_buffer_destroy(&client->buffer, client->device->card);
911
912         return retval;
913 }
914
915 static int fw_device_op_release(struct inode *inode, struct file *file)
916 {
917         struct client *client = file->private_data;
918         struct event *e, *next_e;
919         struct client_resource *r, *next_r;
920         unsigned long flags;
921
922         if (client->buffer.pages)
923                 fw_iso_buffer_destroy(&client->buffer, client->device->card);
924
925         if (client->iso_context)
926                 fw_iso_context_destroy(client->iso_context);
927
928         list_for_each_entry_safe(r, next_r, &client->resource_list, link)
929                 r->release(client, r);
930
931         /* FIXME: We should wait for the async tasklets to stop
932          * running before freeing the memory. */
933
934         list_for_each_entry_safe(e, next_e, &client->event_list, link)
935                 kfree(e);
936
937         spin_lock_irqsave(&client->device->card->lock, flags);
938         list_del(&client->link);
939         spin_unlock_irqrestore(&client->device->card->lock, flags);
940
941         fw_device_put(client->device);
942         kfree(client);
943
944         return 0;
945 }
946
947 static unsigned int fw_device_op_poll(struct file *file, poll_table * pt)
948 {
949         struct client *client = file->private_data;
950         unsigned int mask = 0;
951
952         poll_wait(file, &client->wait, pt);
953
954         if (fw_device_is_shutdown(client->device))
955                 mask |= POLLHUP | POLLERR;
956         if (!list_empty(&client->event_list))
957                 mask |= POLLIN | POLLRDNORM;
958
959         return mask;
960 }
961
962 const struct file_operations fw_device_ops = {
963         .owner          = THIS_MODULE,
964         .open           = fw_device_op_open,
965         .read           = fw_device_op_read,
966         .unlocked_ioctl = fw_device_op_ioctl,
967         .poll           = fw_device_op_poll,
968         .release        = fw_device_op_release,
969         .mmap           = fw_device_op_mmap,
970
971 #ifdef CONFIG_COMPAT
972         .compat_ioctl   = fw_device_op_compat_ioctl,
973 #endif
974 };