blob: bc94afe57f6300f54ecb484b99380da29ae88a68 [file] [log] [blame]
Henrik Kureliddf4846c2008-08-01 10:00:45 +02001/*
2 * FireSAT DVB driver
3 *
Stefan Richter612262a2008-08-26 00:17:30 +02004 * Copyright (C) 2008 Henrik Kurelid <henrik@kurelid.se>
Henrik Kureliddf4846c2008-08-01 10:00:45 +02005 *
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
Stefan Richter612262a2008-08-26 00:17:30 +020012#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
Henrik Kureliddf4846c2008-08-01 10:00:45 +020022#include "firesat.h"
23
24static void rawiso_activity_cb(struct hpsb_iso *iso);
25
26void 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
35int 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
58static 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