b3c61f95fa948380a82fba3a2d355b00af5aaceb
[pandora-kernel.git] / drivers / media / dvb / firesat / firesat_iso.c
1 /*
2  * FireSAT DVB driver
3  *
4  * Copyright (C) 2008 Henrik Kurelid <henrik@kurelid.se>
5  *
6  *      This program is free software; you can redistribute it and/or
7  *      modify it under the terms of the GNU General Public License as
8  *      published by the Free Software Foundation; either version 2 of
9  *      the License, or (at your option) any later version.
10  */
11
12 #include <linux/errno.h>
13 #include <linux/kernel.h>
14 #include <linux/list.h>
15 #include <linux/spinlock.h>
16
17 #include <dvb_demux.h>
18
19 #include <dma.h>
20 #include <iso.h>
21 #include <nodemgr.h>
22
23 #include "firesat.h"
24
25 static void rawiso_activity_cb(struct hpsb_iso *iso);
26
27 void tear_down_iso_channel(struct firesat *firesat)
28 {
29         if (firesat->iso_handle != NULL) {
30                 hpsb_iso_stop(firesat->iso_handle);
31                 hpsb_iso_shutdown(firesat->iso_handle);
32         }
33         firesat->iso_handle = NULL;
34 }
35
36 int setup_iso_channel(struct firesat *firesat)
37 {
38         int result;
39         firesat->iso_handle =
40                 hpsb_iso_recv_init(firesat->ud->ne->host,
41                                    256 * 200, //data_buf_size,
42                                    256, //buf_packets,
43                                    firesat->isochannel,
44                                    HPSB_ISO_DMA_DEFAULT, //dma_mode,
45                                    -1, //stat.config.irq_interval,
46                                    rawiso_activity_cb);
47         if (firesat->iso_handle == NULL) {
48                 printk(KERN_ERR "Cannot initialize iso receive.\n");
49                 return -EINVAL;
50         }
51         result = hpsb_iso_recv_start(firesat->iso_handle, -1, -1, 0);
52         if (result != 0) {
53                 printk(KERN_ERR "Cannot start iso receive.\n");
54                 return -EINVAL;
55         }
56         return 0;
57 }
58
59 static void rawiso_activity_cb(struct hpsb_iso *iso)
60 {
61         unsigned int num;
62         unsigned int i;
63         unsigned int packet;
64         unsigned long flags;
65         struct firesat *firesat = NULL;
66         struct firesat *firesat_iterator;
67
68         spin_lock_irqsave(&firesat_list_lock, flags);
69         list_for_each_entry(firesat_iterator, &firesat_list, list) {
70                 if(firesat_iterator->iso_handle == iso) {
71                         firesat = firesat_iterator;
72                         break;
73                 }
74         }
75         spin_unlock_irqrestore(&firesat_list_lock, flags);
76
77         if (firesat) {
78                 packet = iso->first_packet;
79                 num = hpsb_iso_n_ready(iso);
80                 for (i = 0; i < num; i++,
81                              packet = (packet + 1) % iso->buf_packets) {
82                         unsigned char *buf =
83                                 dma_region_i(&iso->data_buf, unsigned char,
84                                              iso->infos[packet].offset +
85                                              sizeof(struct CIPHeader));
86                         int count = (iso->infos[packet].len -
87                                      sizeof(struct CIPHeader)) /
88                                 (188 + sizeof(struct firewireheader));
89                         if (iso->infos[packet].len <= sizeof(struct CIPHeader))
90                                 continue; // ignore empty packet
91
92                         while (count --) {
93                                 if (buf[sizeof(struct firewireheader)] == 0x47)
94                                         dvb_dmx_swfilter_packets(&firesat->demux,
95                                                                  &buf[sizeof(struct firewireheader)], 1);
96                                 else
97                                         printk("%s: invalid packet, skipping\n", __func__);
98                                 buf += 188 + sizeof(struct firewireheader);
99
100                         }
101
102                 }
103                 hpsb_iso_recv_release_packets(iso, num);
104         }
105         else {
106                 printk("%s: packets for unknown iso channel, skipping\n",
107                        __func__);
108                 hpsb_iso_recv_release_packets(iso, hpsb_iso_n_ready(iso));
109         }
110 }
111