import of upstream 2.4.34.4 from kernel.org
[linux-2.4.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/slab.h>
13 #include <linux/sched.h>
14 #include "iso.h"
15
16 void hpsb_iso_stop(struct hpsb_iso *iso)
17 {
18         if (!(iso->flags & HPSB_ISO_DRIVER_STARTED))
19                 return;
20
21         iso->host->driver->isoctl(iso, iso->type == HPSB_ISO_XMIT ?
22                                   XMIT_STOP : RECV_STOP, 0);
23         iso->flags &= ~HPSB_ISO_DRIVER_STARTED;
24 }
25
26 void hpsb_iso_shutdown(struct hpsb_iso *iso)
27 {
28         if (iso->flags & HPSB_ISO_DRIVER_INIT) {
29                 hpsb_iso_stop(iso);
30                 iso->host->driver->isoctl(iso, iso->type == HPSB_ISO_XMIT ?
31                                           XMIT_SHUTDOWN : RECV_SHUTDOWN, 0);
32                 iso->flags &= ~HPSB_ISO_DRIVER_INIT;
33         }
34
35         dma_region_free(&iso->data_buf);
36         kfree(iso);
37 }
38
39 static struct hpsb_iso* hpsb_iso_common_init(struct hpsb_host *host, enum hpsb_iso_type type,
40                                              unsigned int data_buf_size,
41                                              unsigned int buf_packets,
42                                              int channel,
43                                              int irq_interval,
44                                              void (*callback)(struct hpsb_iso*))
45 {
46         struct hpsb_iso *iso;
47         int dma_direction;
48
49         /* make sure driver supports the ISO API */
50         if (!host->driver->isoctl) {
51                 printk(KERN_INFO "ieee1394: host driver '%s' does not support the rawiso API\n",
52                        host->driver->name);
53                 return NULL;
54         }
55
56         /* sanitize parameters */
57
58         if (buf_packets < 2)
59                 buf_packets = 2;
60
61         if (irq_interval < 1 || irq_interval > buf_packets / 2)
62                 irq_interval = buf_packets / 2;
63
64         if (channel < -1 || channel >= 64)
65                 return NULL;
66
67         /* channel = -1 is OK for multi-channel recv but not for xmit */
68         if (type == HPSB_ISO_XMIT && channel < 0)
69                 return NULL;
70
71         /* allocate and write the struct hpsb_iso */
72
73         iso = kmalloc(sizeof(*iso) + buf_packets * sizeof(struct hpsb_iso_packet_info), GFP_KERNEL);
74         if (!iso)
75                 return NULL;
76
77         iso->infos = (struct hpsb_iso_packet_info *)(iso + 1);
78
79         iso->type = type;
80         iso->host = host;
81         iso->hostdata = NULL;
82         iso->callback = callback;
83         init_waitqueue_head(&iso->waitq);
84         iso->channel = channel;
85         iso->irq_interval = irq_interval;
86         dma_region_init(&iso->data_buf);
87         iso->buf_size = round_up_to_page(data_buf_size);
88         iso->buf_packets = buf_packets;
89         iso->pkt_dma = 0;
90         iso->first_packet = 0;
91         spin_lock_init(&iso->lock);
92
93         if (iso->type == HPSB_ISO_XMIT) {
94                 iso->n_ready_packets = iso->buf_packets;
95                 dma_direction = PCI_DMA_TODEVICE;
96         } else {
97                 iso->n_ready_packets = 0;
98                 dma_direction = PCI_DMA_FROMDEVICE;
99         }
100
101         atomic_set(&iso->overflows, 0);
102         iso->flags = 0;
103         iso->prebuffer = 0;
104
105         /* allocate the packet buffer */
106         if (dma_region_alloc(&iso->data_buf, iso->buf_size, host->pdev, dma_direction))
107                 goto err;
108
109         return iso;
110
111 err:
112         hpsb_iso_shutdown(iso);
113         return NULL;
114 }
115
116 int hpsb_iso_n_ready(struct hpsb_iso* iso)
117 {
118         unsigned long flags;
119         int val;
120
121         spin_lock_irqsave(&iso->lock, flags);
122         val = iso->n_ready_packets;
123         spin_unlock_irqrestore(&iso->lock, flags);
124
125         return val;
126 }
127
128
129 struct hpsb_iso* hpsb_iso_xmit_init(struct hpsb_host *host,
130                                     unsigned int data_buf_size,
131                                     unsigned int buf_packets,
132                                     int channel,
133                                     int speed,
134                                     int irq_interval,
135                                     void (*callback)(struct hpsb_iso*))
136 {
137         struct hpsb_iso *iso = hpsb_iso_common_init(host, HPSB_ISO_XMIT,
138                                                     data_buf_size, buf_packets,
139                                                     channel, irq_interval, callback);
140         if (!iso)
141                 return NULL;
142
143         iso->speed = speed;
144
145         /* tell the driver to start working */
146         if (host->driver->isoctl(iso, XMIT_INIT, 0))
147                 goto err;
148
149         iso->flags |= HPSB_ISO_DRIVER_INIT;
150         return iso;
151
152 err:
153         hpsb_iso_shutdown(iso);
154         return NULL;
155 }
156
157 struct hpsb_iso* hpsb_iso_recv_init(struct hpsb_host *host,
158                                     unsigned int data_buf_size,
159                                     unsigned int buf_packets,
160                                     int channel,
161                                     int irq_interval,
162                                     void (*callback)(struct hpsb_iso*))
163 {
164         struct hpsb_iso *iso = hpsb_iso_common_init(host, HPSB_ISO_RECV,
165                                                     data_buf_size, buf_packets,
166                                                     channel, irq_interval, callback);
167         if (!iso)
168                 return NULL;
169
170         /* tell the driver to start working */
171         if (host->driver->isoctl(iso, RECV_INIT, 0))
172                 goto err;
173
174         iso->flags |= HPSB_ISO_DRIVER_INIT;
175         return iso;
176
177 err:
178         hpsb_iso_shutdown(iso);
179         return NULL;
180 }
181
182 int hpsb_iso_recv_listen_channel(struct hpsb_iso *iso, unsigned char channel)
183 {
184         if (iso->type != HPSB_ISO_RECV || iso->channel != -1 || channel >= 64)
185                 return -EINVAL;
186         return iso->host->driver->isoctl(iso, RECV_LISTEN_CHANNEL, channel);
187 }
188
189 int hpsb_iso_recv_unlisten_channel(struct hpsb_iso *iso, unsigned char channel)
190 {
191        if (iso->type != HPSB_ISO_RECV || iso->channel != -1 || channel >= 64)
192                return -EINVAL;
193        return iso->host->driver->isoctl(iso, RECV_UNLISTEN_CHANNEL, channel);
194 }
195
196 int hpsb_iso_recv_set_channel_mask(struct hpsb_iso *iso, u64 mask)
197 {
198         if (iso->type != HPSB_ISO_RECV || iso->channel != -1)
199                 return -EINVAL;
200         return iso->host->driver->isoctl(iso, RECV_SET_CHANNEL_MASK, (unsigned long) &mask);
201 }
202
203 int hpsb_iso_recv_flush(struct hpsb_iso *iso)
204 {
205         if (iso->type != HPSB_ISO_RECV)
206                 return -EINVAL;
207         return iso->host->driver->isoctl(iso, RECV_FLUSH, 0);
208 }
209
210 static int do_iso_xmit_start(struct hpsb_iso *iso, int cycle)
211 {
212         int retval = iso->host->driver->isoctl(iso, XMIT_START, cycle);
213         if (retval)
214                 return retval;
215
216         iso->flags |= HPSB_ISO_DRIVER_STARTED;
217         return retval;
218 }
219
220 int hpsb_iso_xmit_start(struct hpsb_iso *iso, int cycle, int prebuffer)
221 {
222         if (iso->type != HPSB_ISO_XMIT)
223                 return -1;
224
225         if (iso->flags & HPSB_ISO_DRIVER_STARTED)
226                 return 0;
227
228         if (cycle < -1)
229                 cycle = -1;
230         else if (cycle >= 8000)
231                 cycle %= 8000;
232
233         iso->xmit_cycle = cycle;
234
235         if (prebuffer < 0)
236                 prebuffer = iso->buf_packets;
237         else if (prebuffer == 0)
238                 prebuffer = 1;
239
240         if (prebuffer > iso->buf_packets)
241                 prebuffer = iso->buf_packets;
242
243         iso->prebuffer = prebuffer;
244
245         /* remember the starting cycle; DMA will commence from xmit_queue_packets()
246            once enough packets have been buffered */
247         iso->start_cycle = cycle;
248
249         return 0;
250 }
251
252 int hpsb_iso_recv_start(struct hpsb_iso *iso, int cycle, int tag_mask, int sync)
253 {
254         int retval = 0;
255         int isoctl_args[3];
256
257         if (iso->type != HPSB_ISO_RECV)
258                 return -1;
259
260         if (iso->flags & HPSB_ISO_DRIVER_STARTED)
261                 return 0;
262
263         if (cycle < -1)
264                 cycle = -1;
265         else if (cycle >= 8000)
266                 cycle %= 8000;
267
268         isoctl_args[0] = cycle;
269         
270         if (tag_mask < 0)
271                 /* match all tags */
272                 tag_mask = 0xF;
273         isoctl_args[1] = tag_mask;
274
275         isoctl_args[2] = sync;
276
277         retval = iso->host->driver->isoctl(iso, RECV_START, (unsigned long) &isoctl_args[0]);
278         if (retval)
279                 return retval;
280
281         iso->flags |= HPSB_ISO_DRIVER_STARTED;
282         return retval;
283 }
284
285 /* check to make sure the user has not supplied bogus values of offset/len
286    that would cause the kernel to access memory outside the buffer */
287
288 static int hpsb_iso_check_offset_len(struct hpsb_iso *iso,
289                                      unsigned int offset, unsigned short len,
290                                      unsigned int *out_offset, unsigned short *out_len)
291 {
292         if (offset >= iso->buf_size)
293                 return -EFAULT;
294
295         /* make sure the packet does not go beyond the end of the buffer */
296         if (offset + len > iso->buf_size)
297                 return -EFAULT;
298
299         /* check for wrap-around */
300         if (offset + len < offset)
301                 return -EFAULT;
302
303         /* now we can trust 'offset' and 'length' */
304         *out_offset = offset;
305         *out_len = len;
306
307         return 0;
308 }
309
310
311 int hpsb_iso_xmit_queue_packet(struct hpsb_iso *iso, u32 offset, u16 len, u8 tag, u8 sy)
312 {
313         struct hpsb_iso_packet_info *info;
314         unsigned long flags;
315         int rv;
316
317         if (iso->type != HPSB_ISO_XMIT)
318                 return -EINVAL;
319
320         /* is there space in the buffer? */
321         if (iso->n_ready_packets <= 0) {
322                 return -EBUSY;
323         }
324
325         info = &iso->infos[iso->first_packet];
326
327         /* check for bogus offset/length */
328         if (hpsb_iso_check_offset_len(iso, offset, len, &info->offset, &info->len))
329                 return -EFAULT;
330
331         info->tag = tag;
332         info->sy = sy;
333
334         spin_lock_irqsave(&iso->lock, flags);
335
336         rv = iso->host->driver->isoctl(iso, XMIT_QUEUE, (unsigned long) info);
337         if (rv)
338                 goto out;
339
340         /* increment cursors */
341         iso->first_packet = (iso->first_packet+1) % iso->buf_packets;
342         iso->xmit_cycle = (iso->xmit_cycle+1) % 8000;
343         iso->n_ready_packets--;
344
345         if (iso->prebuffer != 0) {
346                 iso->prebuffer--;
347                 if (iso->prebuffer <= 0) {
348                         iso->prebuffer = 0;
349                         rv = do_iso_xmit_start(iso, iso->start_cycle);
350                 }
351         }
352
353 out:    
354         spin_unlock_irqrestore(&iso->lock, flags);
355         return rv;
356 }
357
358 int hpsb_iso_xmit_sync(struct hpsb_iso *iso)
359 {
360         if (iso->type != HPSB_ISO_XMIT)
361                 return -EINVAL;
362
363         return wait_event_interruptible(iso->waitq, hpsb_iso_n_ready(iso) == iso->buf_packets);
364 }
365
366 void hpsb_iso_packet_sent(struct hpsb_iso *iso, int cycle, int error)
367 {
368         unsigned long flags;
369         spin_lock_irqsave(&iso->lock, flags);
370
371         /* predict the cycle of the next packet to be queued */
372
373         /* jump ahead by the number of packets that are already buffered */
374         cycle += iso->buf_packets - iso->n_ready_packets;
375         cycle %= 8000;
376
377         iso->xmit_cycle = cycle;
378         iso->n_ready_packets++;
379         iso->pkt_dma = (iso->pkt_dma + 1) % iso->buf_packets;
380
381         if (iso->n_ready_packets == iso->buf_packets || error != 0) {
382                 /* the buffer has run empty! */
383                 atomic_inc(&iso->overflows);
384         }
385
386         spin_unlock_irqrestore(&iso->lock, flags);
387 }
388
389 void hpsb_iso_packet_received(struct hpsb_iso *iso, u32 offset, u16 len,
390                               u16 cycle, u8 channel, u8 tag, u8 sy)
391 {
392         unsigned long flags;
393         spin_lock_irqsave(&iso->lock, flags);
394
395         if (iso->n_ready_packets == iso->buf_packets) {
396                 /* overflow! */
397                 atomic_inc(&iso->overflows);
398         } else {
399                 struct hpsb_iso_packet_info *info = &iso->infos[iso->pkt_dma];
400                 info->offset = offset;
401                 info->len = len;
402                 info->cycle = cycle;
403                 info->channel = channel;
404                 info->tag = tag;
405                 info->sy = sy;
406
407                 iso->pkt_dma = (iso->pkt_dma+1) % iso->buf_packets;
408                 iso->n_ready_packets++;
409         }
410
411         spin_unlock_irqrestore(&iso->lock, flags);
412 }
413
414 int hpsb_iso_recv_release_packets(struct hpsb_iso *iso, unsigned int n_packets)
415 {
416         unsigned long flags;
417         unsigned int i;
418         int rv = 0;
419
420         if (iso->type != HPSB_ISO_RECV)
421                 return -1;
422
423         spin_lock_irqsave(&iso->lock, flags);
424         for (i = 0; i < n_packets; i++) {
425                 rv = iso->host->driver->isoctl(iso, RECV_RELEASE,
426                                                (unsigned long) &iso->infos[iso->first_packet]);
427                 if (rv)
428                         break;
429
430                 iso->first_packet = (iso->first_packet+1) % iso->buf_packets;
431                 iso->n_ready_packets--;
432         }
433         spin_unlock_irqrestore(&iso->lock, flags);
434         return rv;
435 }
436
437 void hpsb_iso_wake(struct hpsb_iso *iso)
438 {
439         wake_up_interruptible(&iso->waitq);
440
441         if (iso->callback)
442                 iso->callback(iso);
443 }