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