bc94afe57f6300f54ecb484b99380da29ae88a68
[linux-2.6-block.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
22 #include "firesat.h"
23
24 static void rawiso_activity_cb(struct hpsb_iso *iso);
25
26 void tear_down_iso_channel(struct firesat *firesat)
27 {
28         if (firesat->iso_handle != NULL) {
29                 hpsb_iso_stop(firesat->iso_handle);
30                 hpsb_iso_shutdown(firesat->iso_handle);
31         }
32         firesat->iso_handle = NULL;
33 }
34
35 int setup_iso_channel(struct firesat *firesat)
36 {
37         int result;
38         firesat->iso_handle =
39                 hpsb_iso_recv_init(firesat->host,
40                                    256 * 200, //data_buf_size,
41                                    256, //buf_packets,
42                                    firesat->isochannel,
43                                    HPSB_ISO_DMA_DEFAULT, //dma_mode,
44                                    -1, //stat.config.irq_interval,
45                                    rawiso_activity_cb);
46         if (firesat->iso_handle == NULL) {
47                 printk(KERN_ERR "Cannot initialize iso receive.\n");
48                 return -EINVAL;
49         }
50         result = hpsb_iso_recv_start(firesat->iso_handle, -1, -1, 0);
51         if (result != 0) {
52                 printk(KERN_ERR "Cannot start iso receive.\n");
53                 return -EINVAL;
54         }
55         return 0;
56 }
57
58 static void rawiso_activity_cb(struct hpsb_iso *iso)
59 {
60         unsigned int num;
61         unsigned int i;
62 /*      unsigned int j; */
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 /*                      printk("%s: Handling packets (%d): ", __func__, */
92 /*                             iso->infos[packet].len); */
93 /*                      for (j = 0; j < iso->infos[packet].len - */
94 /*                                   sizeof(struct CIPHeader); j++) */
95 /*                              printk("%02X,", buf[j]); */
96 /*                      printk("\n"); */
97                         while (count --) {
98                                 if (buf[sizeof(struct firewireheader)] == 0x47)
99                                         dvb_dmx_swfilter_packets(&firesat->demux,
100                                                                  &buf[sizeof(struct firewireheader)], 1);
101                                 else
102                                         printk("%s: invalid packet, skipping\n", __func__);
103                                 buf += 188 + sizeof(struct firewireheader);
104
105                         }
106
107                 }
108                 hpsb_iso_recv_release_packets(iso, num);
109         }
110         else {
111                 printk("%s: packets for unknown iso channel, skipping\n",
112                        __func__);
113                 hpsb_iso_recv_release_packets(iso, hpsb_iso_n_ready(iso));
114         }
115 }
116