]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/ieee1394/iso.c
ieee1394: move some comments from declaration to definition
[karo-tx-linux.git] / drivers / ieee1394 / iso.c
1 /*
2  * IEEE 1394 for Linux
3  *
4  * kernel ISO transmission/reception
5  *
6  * Copyright (C) 2002 Maas Digital LLC
7  *
8  * This code is licensed under the GPL.  See the file COPYING in the root
9  * directory of the kernel sources for details.
10  */
11
12 #include <linux/pci.h>
13 #include <linux/slab.h>
14
15 #include "hosts.h"
16 #include "iso.h"
17
18 /**
19  * hpsb_iso_stop - stop DMA
20  */
21 void hpsb_iso_stop(struct hpsb_iso *iso)
22 {
23         if (!(iso->flags & HPSB_ISO_DRIVER_STARTED))
24                 return;
25
26         iso->host->driver->isoctl(iso, iso->type == HPSB_ISO_XMIT ?
27                                   XMIT_STOP : RECV_STOP, 0);
28         iso->flags &= ~HPSB_ISO_DRIVER_STARTED;
29 }
30
31 /**
32  * hpsb_iso_shutdown - deallocate buffer and DMA context
33  */
34 void hpsb_iso_shutdown(struct hpsb_iso *iso)
35 {
36         if (iso->flags & HPSB_ISO_DRIVER_INIT) {
37                 hpsb_iso_stop(iso);
38                 iso->host->driver->isoctl(iso, iso->type == HPSB_ISO_XMIT ?
39                                           XMIT_SHUTDOWN : RECV_SHUTDOWN, 0);
40                 iso->flags &= ~HPSB_ISO_DRIVER_INIT;
41         }
42
43         dma_region_free(&iso->data_buf);
44         kfree(iso);
45 }
46
47 static struct hpsb_iso *hpsb_iso_common_init(struct hpsb_host *host,
48                                              enum hpsb_iso_type type,
49                                              unsigned int data_buf_size,
50                                              unsigned int buf_packets,
51                                              int channel, int dma_mode,
52                                              int irq_interval,
53                                              void (*callback) (struct hpsb_iso
54                                                                *))
55 {
56         struct hpsb_iso *iso;
57         int dma_direction;
58
59         /* make sure driver supports the ISO API */
60         if (!host->driver->isoctl) {
61                 printk(KERN_INFO
62                        "ieee1394: host driver '%s' does not support the rawiso API\n",
63                        host->driver->name);
64                 return NULL;
65         }
66
67         /* sanitize parameters */
68
69         if (buf_packets < 2)
70                 buf_packets = 2;
71
72         if ((dma_mode < HPSB_ISO_DMA_DEFAULT)
73             || (dma_mode > HPSB_ISO_DMA_PACKET_PER_BUFFER))
74                 dma_mode = HPSB_ISO_DMA_DEFAULT;
75
76         if ((irq_interval < 0) || (irq_interval > buf_packets / 4))
77                 irq_interval = buf_packets / 4;
78         if (irq_interval == 0)  /* really interrupt for each packet */
79                 irq_interval = 1;
80
81         if (channel < -1 || channel >= 64)
82                 return NULL;
83
84         /* channel = -1 is OK for multi-channel recv but not for xmit */
85         if (type == HPSB_ISO_XMIT && channel < 0)
86                 return NULL;
87
88         /* allocate and write the struct hpsb_iso */
89
90         iso =
91             kmalloc(sizeof(*iso) +
92                     buf_packets * sizeof(struct hpsb_iso_packet_info),
93                     GFP_KERNEL);
94         if (!iso)
95                 return NULL;
96
97         iso->infos = (struct hpsb_iso_packet_info *)(iso + 1);
98
99         iso->type = type;
100         iso->host = host;
101         iso->hostdata = NULL;
102         iso->callback = callback;
103         init_waitqueue_head(&iso->waitq);
104         iso->channel = channel;
105         iso->irq_interval = irq_interval;
106         iso->dma_mode = dma_mode;
107         dma_region_init(&iso->data_buf);
108         iso->buf_size = PAGE_ALIGN(data_buf_size);
109         iso->buf_packets = buf_packets;
110         iso->pkt_dma = 0;
111         iso->first_packet = 0;
112         spin_lock_init(&iso->lock);
113
114         if (iso->type == HPSB_ISO_XMIT) {
115                 iso->n_ready_packets = iso->buf_packets;
116                 dma_direction = PCI_DMA_TODEVICE;
117         } else {
118                 iso->n_ready_packets = 0;
119                 dma_direction = PCI_DMA_FROMDEVICE;
120         }
121
122         atomic_set(&iso->overflows, 0);
123         iso->bytes_discarded = 0;
124         iso->flags = 0;
125         iso->prebuffer = 0;
126
127         /* allocate the packet buffer */
128         if (dma_region_alloc
129             (&iso->data_buf, iso->buf_size, host->pdev, dma_direction))
130                 goto err;
131
132         return iso;
133
134       err:
135         hpsb_iso_shutdown(iso);
136         return NULL;
137 }
138
139 /**
140  * hpsb_iso_n_ready - returns number of packets ready to send or receive
141  */
142 int hpsb_iso_n_ready(struct hpsb_iso *iso)
143 {
144         unsigned long flags;
145         int val;
146
147         spin_lock_irqsave(&iso->lock, flags);
148         val = iso->n_ready_packets;
149         spin_unlock_irqrestore(&iso->lock, flags);
150
151         return val;
152 }
153
154 /**
155  * hpsb_iso_xmit_init - allocate the buffer and DMA context
156  */
157 struct hpsb_iso *hpsb_iso_xmit_init(struct hpsb_host *host,
158                                     unsigned int data_buf_size,
159                                     unsigned int buf_packets,
160                                     int channel,
161                                     int speed,
162                                     int irq_interval,
163                                     void (*callback) (struct hpsb_iso *))
164 {
165         struct hpsb_iso *iso = hpsb_iso_common_init(host, HPSB_ISO_XMIT,
166                                                     data_buf_size, buf_packets,
167                                                     channel,
168                                                     HPSB_ISO_DMA_DEFAULT,
169                                                     irq_interval, callback);
170         if (!iso)
171                 return NULL;
172
173         iso->speed = speed;
174
175         /* tell the driver to start working */
176         if (host->driver->isoctl(iso, XMIT_INIT, 0))
177                 goto err;
178
179         iso->flags |= HPSB_ISO_DRIVER_INIT;
180         return iso;
181
182       err:
183         hpsb_iso_shutdown(iso);
184         return NULL;
185 }
186
187 /**
188  * hpsb_iso_recv_init - allocate the buffer and DMA context
189  *
190  * Note, if channel = -1, multi-channel receive is enabled.
191  */
192 struct hpsb_iso *hpsb_iso_recv_init(struct hpsb_host *host,
193                                     unsigned int data_buf_size,
194                                     unsigned int buf_packets,
195                                     int channel,
196                                     int dma_mode,
197                                     int irq_interval,
198                                     void (*callback) (struct hpsb_iso *))
199 {
200         struct hpsb_iso *iso = hpsb_iso_common_init(host, HPSB_ISO_RECV,
201                                                     data_buf_size, buf_packets,
202                                                     channel, dma_mode,
203                                                     irq_interval, callback);
204         if (!iso)
205                 return NULL;
206
207         /* tell the driver to start working */
208         if (host->driver->isoctl(iso, RECV_INIT, 0))
209                 goto err;
210
211         iso->flags |= HPSB_ISO_DRIVER_INIT;
212         return iso;
213
214       err:
215         hpsb_iso_shutdown(iso);
216         return NULL;
217 }
218
219 /**
220  * hpsb_iso_recv_listen_channel
221  *
222  * multi-channel only
223  */
224 int hpsb_iso_recv_listen_channel(struct hpsb_iso *iso, unsigned char channel)
225 {
226         if (iso->type != HPSB_ISO_RECV || iso->channel != -1 || channel >= 64)
227                 return -EINVAL;
228         return iso->host->driver->isoctl(iso, RECV_LISTEN_CHANNEL, channel);
229 }
230
231 /**
232  * hpsb_iso_recv_unlisten_channel
233  *
234  * multi-channel only
235  */
236 int hpsb_iso_recv_unlisten_channel(struct hpsb_iso *iso, unsigned char channel)
237 {
238         if (iso->type != HPSB_ISO_RECV || iso->channel != -1 || channel >= 64)
239                 return -EINVAL;
240         return iso->host->driver->isoctl(iso, RECV_UNLISTEN_CHANNEL, channel);
241 }
242
243 /**
244  * hpsb_iso_recv_set_channel_mask
245  *
246  * multi-channel only
247  */
248 int hpsb_iso_recv_set_channel_mask(struct hpsb_iso *iso, u64 mask)
249 {
250         if (iso->type != HPSB_ISO_RECV || iso->channel != -1)
251                 return -EINVAL;
252         return iso->host->driver->isoctl(iso, RECV_SET_CHANNEL_MASK,
253                                          (unsigned long)&mask);
254 }
255
256 /**
257  * hpsb_iso_recv_flush - check for arrival of new packets
258  *
259  * check for arrival of new packets immediately (even if irq_interval
260  * has not yet been reached)
261  */
262 int hpsb_iso_recv_flush(struct hpsb_iso *iso)
263 {
264         if (iso->type != HPSB_ISO_RECV)
265                 return -EINVAL;
266         return iso->host->driver->isoctl(iso, RECV_FLUSH, 0);
267 }
268
269 static int do_iso_xmit_start(struct hpsb_iso *iso, int cycle)
270 {
271         int retval = iso->host->driver->isoctl(iso, XMIT_START, cycle);
272         if (retval)
273                 return retval;
274
275         iso->flags |= HPSB_ISO_DRIVER_STARTED;
276         return retval;
277 }
278
279 /**
280  * hpsb_iso_xmit_start - start DMA
281  */
282 int hpsb_iso_xmit_start(struct hpsb_iso *iso, int cycle, int prebuffer)
283 {
284         if (iso->type != HPSB_ISO_XMIT)
285                 return -1;
286
287         if (iso->flags & HPSB_ISO_DRIVER_STARTED)
288                 return 0;
289
290         if (cycle < -1)
291                 cycle = -1;
292         else if (cycle >= 8000)
293                 cycle %= 8000;
294
295         iso->xmit_cycle = cycle;
296
297         if (prebuffer < 0)
298                 prebuffer = iso->buf_packets - 1;
299         else if (prebuffer == 0)
300                 prebuffer = 1;
301
302         if (prebuffer >= iso->buf_packets)
303                 prebuffer = iso->buf_packets - 1;
304
305         iso->prebuffer = prebuffer;
306
307         /* remember the starting cycle; DMA will commence from xmit_queue_packets()
308            once enough packets have been buffered */
309         iso->start_cycle = cycle;
310
311         return 0;
312 }
313
314 /**
315  * hpsb_iso_recv_start - start DMA
316  */
317 int hpsb_iso_recv_start(struct hpsb_iso *iso, int cycle, int tag_mask, int sync)
318 {
319         int retval = 0;
320         int isoctl_args[3];
321
322         if (iso->type != HPSB_ISO_RECV)
323                 return -1;
324
325         if (iso->flags & HPSB_ISO_DRIVER_STARTED)
326                 return 0;
327
328         if (cycle < -1)
329                 cycle = -1;
330         else if (cycle >= 8000)
331                 cycle %= 8000;
332
333         isoctl_args[0] = cycle;
334
335         if (tag_mask < 0)
336                 /* match all tags */
337                 tag_mask = 0xF;
338         isoctl_args[1] = tag_mask;
339
340         isoctl_args[2] = sync;
341
342         retval =
343             iso->host->driver->isoctl(iso, RECV_START,
344                                       (unsigned long)&isoctl_args[0]);
345         if (retval)
346                 return retval;
347
348         iso->flags |= HPSB_ISO_DRIVER_STARTED;
349         return retval;
350 }
351
352 /* check to make sure the user has not supplied bogus values of offset/len
353  * that would cause the kernel to access memory outside the buffer */
354 static int hpsb_iso_check_offset_len(struct hpsb_iso *iso,
355                                      unsigned int offset, unsigned short len,
356                                      unsigned int *out_offset,
357                                      unsigned short *out_len)
358 {
359         if (offset >= iso->buf_size)
360                 return -EFAULT;
361
362         /* make sure the packet does not go beyond the end of the buffer */
363         if (offset + len > iso->buf_size)
364                 return -EFAULT;
365
366         /* check for wrap-around */
367         if (offset + len < offset)
368                 return -EFAULT;
369
370         /* now we can trust 'offset' and 'length' */
371         *out_offset = offset;
372         *out_len = len;
373
374         return 0;
375 }
376
377 /**
378  * hpsb_iso_xmit_queue_packet - queue a packet for transmission.
379  *
380  * @offset is relative to the beginning of the DMA buffer, where the packet's
381  * data payload should already have been placed.
382  */
383 int hpsb_iso_xmit_queue_packet(struct hpsb_iso *iso, u32 offset, u16 len,
384                                u8 tag, u8 sy)
385 {
386         struct hpsb_iso_packet_info *info;
387         unsigned long flags;
388         int rv;
389
390         if (iso->type != HPSB_ISO_XMIT)
391                 return -EINVAL;
392
393         /* is there space in the buffer? */
394         if (iso->n_ready_packets <= 0) {
395                 return -EBUSY;
396         }
397
398         info = &iso->infos[iso->first_packet];
399
400         /* check for bogus offset/length */
401         if (hpsb_iso_check_offset_len
402             (iso, offset, len, &info->offset, &info->len))
403                 return -EFAULT;
404
405         info->tag = tag;
406         info->sy = sy;
407
408         spin_lock_irqsave(&iso->lock, flags);
409
410         rv = iso->host->driver->isoctl(iso, XMIT_QUEUE, (unsigned long)info);
411         if (rv)
412                 goto out;
413
414         /* increment cursors */
415         iso->first_packet = (iso->first_packet + 1) % iso->buf_packets;
416         iso->xmit_cycle = (iso->xmit_cycle + 1) % 8000;
417         iso->n_ready_packets--;
418
419         if (iso->prebuffer != 0) {
420                 iso->prebuffer--;
421                 if (iso->prebuffer <= 0) {
422                         iso->prebuffer = 0;
423                         rv = do_iso_xmit_start(iso, iso->start_cycle);
424                 }
425         }
426
427       out:
428         spin_unlock_irqrestore(&iso->lock, flags);
429         return rv;
430 }
431
432 /**
433  * hpsb_iso_xmit_sync - wait until all queued packets have been transmitted
434  */
435 int hpsb_iso_xmit_sync(struct hpsb_iso *iso)
436 {
437         if (iso->type != HPSB_ISO_XMIT)
438                 return -EINVAL;
439
440         return wait_event_interruptible(iso->waitq,
441                                         hpsb_iso_n_ready(iso) ==
442                                         iso->buf_packets);
443 }
444
445 /**
446  * hpsb_iso_packet_sent
447  *
448  * Available to low-level drivers.
449  *
450  * Call after a packet has been transmitted to the bus (interrupt context is
451  * OK).  @cycle is the _exact_ cycle the packet was sent on.  @error should be
452  * non-zero if some sort of error occurred when sending the packet.
453  */
454 void hpsb_iso_packet_sent(struct hpsb_iso *iso, int cycle, int error)
455 {
456         unsigned long flags;
457         spin_lock_irqsave(&iso->lock, flags);
458
459         /* predict the cycle of the next packet to be queued */
460
461         /* jump ahead by the number of packets that are already buffered */
462         cycle += iso->buf_packets - iso->n_ready_packets;
463         cycle %= 8000;
464
465         iso->xmit_cycle = cycle;
466         iso->n_ready_packets++;
467         iso->pkt_dma = (iso->pkt_dma + 1) % iso->buf_packets;
468
469         if (iso->n_ready_packets == iso->buf_packets || error != 0) {
470                 /* the buffer has run empty! */
471                 atomic_inc(&iso->overflows);
472         }
473
474         spin_unlock_irqrestore(&iso->lock, flags);
475 }
476
477 /**
478  * hpsb_iso_packet_received
479  *
480  * Available to low-level drivers.
481  *
482  * Call after a packet has been received (interrupt context is OK).
483  */
484 void hpsb_iso_packet_received(struct hpsb_iso *iso, u32 offset, u16 len,
485                               u16 total_len, u16 cycle, u8 channel, u8 tag,
486                               u8 sy)
487 {
488         unsigned long flags;
489         spin_lock_irqsave(&iso->lock, flags);
490
491         if (iso->n_ready_packets == iso->buf_packets) {
492                 /* overflow! */
493                 atomic_inc(&iso->overflows);
494                 /* Record size of this discarded packet */
495                 iso->bytes_discarded += total_len;
496         } else {
497                 struct hpsb_iso_packet_info *info = &iso->infos[iso->pkt_dma];
498                 info->offset = offset;
499                 info->len = len;
500                 info->total_len = total_len;
501                 info->cycle = cycle;
502                 info->channel = channel;
503                 info->tag = tag;
504                 info->sy = sy;
505
506                 iso->pkt_dma = (iso->pkt_dma + 1) % iso->buf_packets;
507                 iso->n_ready_packets++;
508         }
509
510         spin_unlock_irqrestore(&iso->lock, flags);
511 }
512
513 /**
514  * hpsb_iso_recv_release_packets - release packets, reuse buffer
515  *
516  * @n_packets have been read out of the buffer, re-use the buffer space
517  */
518 int hpsb_iso_recv_release_packets(struct hpsb_iso *iso, unsigned int n_packets)
519 {
520         unsigned long flags;
521         unsigned int i;
522         int rv = 0;
523
524         if (iso->type != HPSB_ISO_RECV)
525                 return -1;
526
527         spin_lock_irqsave(&iso->lock, flags);
528         for (i = 0; i < n_packets; i++) {
529                 rv = iso->host->driver->isoctl(iso, RECV_RELEASE,
530                                                (unsigned long)&iso->infos[iso->
531                                                                           first_packet]);
532                 if (rv)
533                         break;
534
535                 iso->first_packet = (iso->first_packet + 1) % iso->buf_packets;
536                 iso->n_ready_packets--;
537
538                 /* release memory from packets discarded when queue was full  */
539                 if (iso->n_ready_packets == 0) {        /* Release only after all prior packets handled */
540                         if (iso->bytes_discarded != 0) {
541                                 struct hpsb_iso_packet_info inf;
542                                 inf.total_len = iso->bytes_discarded;
543                                 iso->host->driver->isoctl(iso, RECV_RELEASE,
544                                                           (unsigned long)&inf);
545                                 iso->bytes_discarded = 0;
546                         }
547                 }
548         }
549         spin_unlock_irqrestore(&iso->lock, flags);
550         return rv;
551 }
552
553 /**
554  * hpsb_iso_wake
555  *
556  * Available to low-level drivers.
557  *
558  * Call to wake waiting processes after buffer space has opened up.
559  */
560 void hpsb_iso_wake(struct hpsb_iso *iso)
561 {
562         wake_up_interruptible(&iso->waitq);
563
564         if (iso->callback)
565                 iso->callback(iso);
566 }