firewire: mark some structs const
[firefly-linux-kernel-4.4.55.git] / 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/compat.h>
32 #include <asm/uaccess.h>
33 #include "fw-transaction.h"
34 #include "fw-topology.h"
35 #include "fw-device.h"
36 #include "fw-device-cdev.h"
37
38 /*
39  * todo
40  *
41  * - bus resets sends a new packet with new generation and node id
42  *
43  */
44
45 /* dequeue_event() just kfree()'s the event, so the event has to be
46  * the first field in the struct. */
47
48 struct event {
49         struct { void *data; size_t size; } v[2];
50         struct list_head link;
51 };
52
53 struct response {
54         struct event event;
55         struct fw_transaction transaction;
56         struct client *client;
57         struct fw_cdev_event_response response;
58 };
59
60 struct iso_interrupt {
61         struct event event;
62         struct fw_cdev_event_iso_interrupt interrupt;
63 };
64
65 struct client {
66         struct fw_device *device;
67         spinlock_t lock;
68         struct list_head handler_list;
69         struct list_head request_list;
70         u32 request_serial;
71         struct list_head event_list;
72         struct semaphore event_list_sem;
73         wait_queue_head_t wait;
74         unsigned long vm_start;
75         struct fw_iso_context *iso_context;
76 };
77
78 static inline void __user *
79 u64_to_uptr(__u64 value)
80 {
81         return (void __user *)(unsigned long)value;
82 }
83
84 static inline __u64
85 uptr_to_u64(void __user *ptr)
86 {
87         return (__u64)(unsigned long)ptr;
88 }
89
90 static int fw_device_op_open(struct inode *inode, struct file *file)
91 {
92         struct fw_device *device;
93         struct client *client;
94
95         device = container_of(inode->i_cdev, struct fw_device, cdev);
96
97         client = kzalloc(sizeof *client, GFP_KERNEL);
98         if (client == NULL)
99                 return -ENOMEM;
100
101         client->device = fw_device_get(device);
102         INIT_LIST_HEAD(&client->event_list);
103         sema_init(&client->event_list_sem, 0);
104         INIT_LIST_HEAD(&client->handler_list);
105         INIT_LIST_HEAD(&client->request_list);
106         spin_lock_init(&client->lock);
107         init_waitqueue_head(&client->wait);
108
109         file->private_data = client;
110
111         return 0;
112 }
113
114 static void queue_event(struct client *client, struct event *event,
115                         void *data0, size_t size0, void *data1, size_t size1)
116 {
117         unsigned long flags;
118
119         event->v[0].data = data0;
120         event->v[0].size = size0;
121         event->v[1].data = data1;
122         event->v[1].size = size1;
123
124         spin_lock_irqsave(&client->lock, flags);
125
126         list_add_tail(&event->link, &client->event_list);
127
128         up(&client->event_list_sem);
129         wake_up_interruptible(&client->wait);
130
131         spin_unlock_irqrestore(&client->lock, flags);
132 }
133
134 static int dequeue_event(struct client *client, char __user *buffer, size_t count)
135 {
136         unsigned long flags;
137         struct event *event;
138         size_t size, total;
139         int i, retval = -EFAULT;
140
141         if (down_interruptible(&client->event_list_sem) < 0)
142                 return -EINTR;
143
144         spin_lock_irqsave(&client->lock, flags);
145
146         event = container_of(client->event_list.next, struct event, link);
147         list_del(&event->link);
148
149         spin_unlock_irqrestore(&client->lock, flags);
150
151         if (buffer == NULL)
152                 goto out;
153
154         total = 0;
155         for (i = 0; i < ARRAY_SIZE(event->v) && total < count; i++) {
156                 size = min(event->v[i].size, count - total);
157                 if (copy_to_user(buffer + total, event->v[i].data, size))
158                         goto out;
159                 total += size;
160         }
161         retval = total;
162
163  out:
164         kfree(event);
165
166         return retval;
167 }
168
169 static ssize_t
170 fw_device_op_read(struct file *file,
171                   char __user *buffer, size_t count, loff_t *offset)
172 {
173         struct client *client = file->private_data;
174
175         return dequeue_event(client, buffer, count);
176 }
177
178 static int ioctl_config_rom(struct client *client, void __user *arg)
179 {
180         struct fw_cdev_get_config_rom rom;
181
182         rom.length = client->device->config_rom_length;
183         memcpy(rom.data, client->device->config_rom, rom.length * 4);
184         if (copy_to_user(arg, &rom,
185                          (char *)&rom.data[rom.length] - (char *)&rom))
186                 return -EFAULT;
187
188         return 0;
189 }
190
191 static void
192 complete_transaction(struct fw_card *card, int rcode,
193                      void *payload, size_t length, void *data)
194 {
195         struct response *response = data;
196         struct client *client = response->client;
197
198         if (length < response->response.length)
199                 response->response.length = length;
200         if (rcode == RCODE_COMPLETE)
201                 memcpy(response->response.data, payload,
202                        response->response.length);
203
204         response->response.type   = FW_CDEV_EVENT_RESPONSE;
205         response->response.rcode  = rcode;
206         queue_event(client, &response->event,
207                     &response->response, sizeof response->response,
208                     response->response.data, response->response.length);
209 }
210
211 static ssize_t ioctl_send_request(struct client *client, void __user *arg)
212 {
213         struct fw_device *device = client->device;
214         struct fw_cdev_send_request request;
215         struct response *response;
216
217         if (copy_from_user(&request, arg, sizeof request))
218                 return -EFAULT;
219
220         /* What is the biggest size we'll accept, really? */
221         if (request.length > 4096)
222                 return -EINVAL;
223
224         response = kmalloc(sizeof *response + request.length, GFP_KERNEL);
225         if (response == NULL)
226                 return -ENOMEM;
227
228         response->client = client;
229         response->response.length = request.length;
230         response->response.closure = request.closure;
231
232         if (request.data &&
233             copy_from_user(response->response.data,
234                            u64_to_uptr(request.data), request.length)) {
235                 kfree(response);
236                 return -EFAULT;
237         }
238
239         fw_send_request(device->card, &response->transaction,
240                         request.tcode,
241                         device->node->node_id | LOCAL_BUS,
242                         device->card->generation,
243                         device->node->max_speed,
244                         request.offset,
245                         response->response.data, request.length,
246                         complete_transaction, response);
247
248         if (request.data)
249                 return sizeof request + request.length;
250         else
251                 return sizeof request;
252 }
253
254 struct address_handler {
255         struct fw_address_handler handler;
256         __u64 closure;
257         struct client *client;
258         struct list_head link;
259 };
260
261 struct request {
262         struct fw_request *request;
263         void *data;
264         size_t length;
265         u32 serial;
266         struct list_head link;
267 };
268
269 struct request_event {
270         struct event event;
271         struct fw_cdev_event_request request;
272 };
273
274 static void
275 handle_request(struct fw_card *card, struct fw_request *r,
276                int tcode, int destination, int source,
277                int generation, int speed,
278                unsigned long long offset,
279                void *payload, size_t length, void *callback_data)
280 {
281         struct address_handler *handler = callback_data;
282         struct request *request;
283         struct request_event *e;
284         unsigned long flags;
285         struct client *client = handler->client;
286
287         request = kmalloc(sizeof *request, GFP_ATOMIC);
288         e = kmalloc(sizeof *e, GFP_ATOMIC);
289         if (request == NULL || e == NULL) {
290                 kfree(request);
291                 kfree(e);
292                 fw_send_response(card, r, RCODE_CONFLICT_ERROR);
293                 return;
294         }
295
296         request->request = r;
297         request->data    = payload;
298         request->length  = length;
299
300         spin_lock_irqsave(&client->lock, flags);
301         request->serial = client->request_serial++;
302         list_add_tail(&request->link, &client->request_list);
303         spin_unlock_irqrestore(&client->lock, flags);
304
305         e->request.type    = FW_CDEV_EVENT_REQUEST;
306         e->request.tcode   = tcode;
307         e->request.offset  = offset;
308         e->request.length  = length;
309         e->request.serial  = request->serial;
310         e->request.closure = handler->closure;
311
312         queue_event(client, &e->event,
313                     &e->request, sizeof e->request, payload, length);
314 }
315
316 static int ioctl_allocate(struct client *client, void __user *arg)
317 {
318         struct fw_cdev_allocate request;
319         struct address_handler *handler;
320         unsigned long flags;
321         struct fw_address_region region;
322
323         if (copy_from_user(&request, arg, sizeof request))
324                 return -EFAULT;
325
326         handler = kmalloc(sizeof *handler, GFP_KERNEL);
327         if (handler == NULL)
328                 return -ENOMEM;
329
330         region.start = request.offset;
331         region.end = request.offset + request.length;
332         handler->handler.length = request.length;
333         handler->handler.address_callback = handle_request;
334         handler->handler.callback_data = handler;
335         handler->closure = request.closure;
336         handler->client = client;
337
338         if (fw_core_add_address_handler(&handler->handler, &region) < 0) {
339                 kfree(handler);
340                 return -EBUSY;
341         }
342
343         spin_lock_irqsave(&client->lock, flags);
344         list_add_tail(&handler->link, &client->handler_list);
345         spin_unlock_irqrestore(&client->lock, flags);
346
347         return 0;
348 }
349
350 static int ioctl_send_response(struct client *client, void __user *arg)
351 {
352         struct fw_cdev_send_response request;
353         struct request *r;
354         unsigned long flags;
355
356         if (copy_from_user(&request, arg, sizeof request))
357                 return -EFAULT;
358
359         spin_lock_irqsave(&client->lock, flags);
360         list_for_each_entry(r, &client->request_list, link) {
361                 if (r->serial == request.serial) {
362                         list_del(&r->link);
363                         break;
364                 }
365         }
366         spin_unlock_irqrestore(&client->lock, flags);
367
368         if (&r->link == &client->request_list)
369                 return -EINVAL;
370
371         if (request.length < r->length)
372                 r->length = request.length;
373         if (copy_from_user(r->data, u64_to_uptr(request.data), r->length))
374                 return -EFAULT;
375
376         fw_send_response(client->device->card, r->request, request.rcode);
377
378         kfree(r);
379
380         return 0;
381 }
382
383 static void
384 iso_callback(struct fw_iso_context *context, int status, u32 cycle, void *data)
385 {
386         struct client *client = data;
387         struct iso_interrupt *interrupt;
388
389         interrupt = kzalloc(sizeof *interrupt, GFP_ATOMIC);
390         if (interrupt == NULL)
391                 return;
392
393         interrupt->interrupt.type      = FW_CDEV_EVENT_ISO_INTERRUPT;
394         interrupt->interrupt.closure   = 0;
395         interrupt->interrupt.cycle     = cycle;
396         queue_event(client, &interrupt->event,
397                     &interrupt->interrupt, sizeof interrupt->interrupt, NULL, 0);
398 }
399
400 static int ioctl_create_iso_context(struct client *client, void __user *arg)
401 {
402         struct fw_cdev_create_iso_context request;
403
404         if (copy_from_user(&request, arg, sizeof request))
405                 return -EFAULT;
406
407         client->iso_context = fw_iso_context_create(client->device->card,
408                                                     FW_ISO_CONTEXT_TRANSMIT,
409                                                     request.buffer_size,
410                                                     iso_callback, client);
411         if (IS_ERR(client->iso_context))
412                 return PTR_ERR(client->iso_context);
413
414         return 0;
415 }
416
417 static int ioctl_queue_iso(struct client *client, void __user *arg)
418 {
419         struct fw_cdev_queue_iso request;
420         struct fw_cdev_iso_packet __user *p, *end, *next;
421         void *payload, *payload_end;
422         unsigned long index;
423         int count;
424         struct {
425                 struct fw_iso_packet packet;
426                 u8 header[256];
427         } u;
428
429         if (client->iso_context == NULL)
430                 return -EINVAL;
431         if (copy_from_user(&request, arg, sizeof request))
432                 return -EFAULT;
433
434         /* If the user passes a non-NULL data pointer, has mmap()'ed
435          * the iso buffer, and the pointer points inside the buffer,
436          * we setup the payload pointers accordingly.  Otherwise we
437          * set them both to NULL, which will still let packets with
438          * payload_length == 0 through.  In other words, if no packets
439          * use the indirect payload, the iso buffer need not be mapped
440          * and the request.data pointer is ignored.*/
441
442         index = (unsigned long)request.data - client->vm_start;
443         if (request.data != 0 && client->vm_start != 0 &&
444             index <= client->iso_context->buffer_size) {
445                 payload = client->iso_context->buffer + index;
446                 payload_end = client->iso_context->buffer +
447                         client->iso_context->buffer_size;
448         } else {
449                 payload = NULL;
450                 payload_end = NULL;
451         }
452
453         if (!access_ok(VERIFY_READ, request.packets, request.size))
454                 return -EFAULT;
455
456         p = (struct fw_cdev_iso_packet __user *)u64_to_uptr(request.packets);
457         end = (void __user *)p + request.size;
458         count = 0;
459         while (p < end) {
460                 if (__copy_from_user(&u.packet, p, sizeof *p))
461                         return -EFAULT;
462                 next = (struct fw_cdev_iso_packet __user *)
463                         &p->header[u.packet.header_length / 4];
464                 if (next > end)
465                         return -EINVAL;
466                 if (__copy_from_user
467                     (u.packet.header, p->header, u.packet.header_length))
468                         return -EFAULT;
469                 if (u.packet.skip &&
470                     u.packet.header_length + u.packet.payload_length > 0)
471                         return -EINVAL;
472                 if (payload + u.packet.payload_length > payload_end)
473                         return -EINVAL;
474
475                 if (fw_iso_context_queue(client->iso_context,
476                                          &u.packet, payload))
477                         break;
478
479                 p = next;
480                 payload += u.packet.payload_length;
481                 count++;
482         }
483
484         request.size    -= uptr_to_u64(p) - request.packets;
485         request.packets  = uptr_to_u64(p);
486         request.data     =
487                 client->vm_start + (payload - client->iso_context->buffer);
488
489         if (copy_to_user(arg, &request, sizeof request))
490                 return -EFAULT;
491
492         return count;
493 }
494
495 static int ioctl_send_iso(struct client *client, void __user *arg)
496 {
497         struct fw_cdev_send_iso request;
498
499         if (copy_from_user(&request, arg, sizeof request))
500                 return -EFAULT;
501
502         return fw_iso_context_send(client->iso_context, request.channel,
503                                    request.speed, request.cycle);
504 }
505
506 static int
507 dispatch_ioctl(struct client *client, unsigned int cmd, void __user *arg)
508 {
509         switch (cmd) {
510         case FW_CDEV_IOC_GET_CONFIG_ROM:
511                 return ioctl_config_rom(client, arg);
512         case FW_CDEV_IOC_SEND_REQUEST:
513                 return ioctl_send_request(client, arg);
514         case FW_CDEV_IOC_ALLOCATE:
515                 return ioctl_allocate(client, arg);
516         case FW_CDEV_IOC_SEND_RESPONSE:
517                 return ioctl_send_response(client, arg);
518         case FW_CDEV_IOC_CREATE_ISO_CONTEXT:
519                 return ioctl_create_iso_context(client, arg);
520         case FW_CDEV_IOC_QUEUE_ISO:
521                 return ioctl_queue_iso(client, arg);
522         case FW_CDEV_IOC_SEND_ISO:
523                 return ioctl_send_iso(client, arg);
524         default:
525                 return -EINVAL;
526         }
527 }
528
529 static long
530 fw_device_op_ioctl(struct file *file,
531                    unsigned int cmd, unsigned long arg)
532 {
533         struct client *client = file->private_data;
534
535         return dispatch_ioctl(client, cmd, (void __user *) arg);
536 }
537
538 #ifdef CONFIG_COMPAT
539 static long
540 fw_device_op_compat_ioctl(struct file *file,
541                           unsigned int cmd, unsigned long arg)
542 {
543         struct client *client = file->private_data;
544
545         return dispatch_ioctl(client, cmd, compat_ptr(arg));
546 }
547 #endif
548
549 static int fw_device_op_mmap(struct file *file, struct vm_area_struct *vma)
550 {
551         struct client *client = file->private_data;
552
553         if (client->iso_context->buffer == NULL)
554                 return -EINVAL;
555
556         client->vm_start = vma->vm_start;
557
558         return remap_vmalloc_range(vma, client->iso_context->buffer, 0);
559 }
560
561 static int fw_device_op_release(struct inode *inode, struct file *file)
562 {
563         struct client *client = file->private_data;
564         struct address_handler *h, *next;
565         struct request *r, *next_r;
566
567         if (client->iso_context)
568                 fw_iso_context_destroy(client->iso_context);
569
570         list_for_each_entry_safe(h, next, &client->handler_list, link) {
571                 fw_core_remove_address_handler(&h->handler);
572                 kfree(h);
573         }
574
575         list_for_each_entry_safe(r, next_r, &client->request_list, link) {
576                 fw_send_response(client->device->card, r->request,
577                                  RCODE_CONFLICT_ERROR);
578                 kfree(r);
579         }
580
581         /* TODO: wait for all transactions to finish so
582          * complete_transaction doesn't try to queue up responses
583          * after we free client. */
584         while (!list_empty(&client->event_list))
585                 dequeue_event(client, NULL, 0);
586
587         fw_device_put(client->device);
588         kfree(client);
589
590         return 0;
591 }
592
593 static unsigned int fw_device_op_poll(struct file *file, poll_table * pt)
594 {
595         struct client *client = file->private_data;
596
597         poll_wait(file, &client->wait, pt);
598
599         if (!list_empty(&client->event_list))
600                 return POLLIN | POLLRDNORM;
601         else
602                 return 0;
603 }
604
605 const struct file_operations fw_device_ops = {
606         .owner          = THIS_MODULE,
607         .open           = fw_device_op_open,
608         .read           = fw_device_op_read,
609         .unlocked_ioctl = fw_device_op_ioctl,
610         .poll           = fw_device_op_poll,
611         .release        = fw_device_op_release,
612         .mmap           = fw_device_op_mmap,
613
614 #ifdef CONFIG_COMPAT
615         .compat_ioctl   = fw_device_op_compat_ioctl
616 #endif
617 };