diff options
Diffstat (limited to 'drivers/media/dvb/firewire/firedtv-1394.c')
-rw-r--r-- | drivers/media/dvb/firewire/firedtv-1394.c | 53 |
1 files changed, 34 insertions, 19 deletions
diff --git a/drivers/media/dvb/firewire/firedtv-1394.c b/drivers/media/dvb/firewire/firedtv-1394.c index 2b6eeeab5b25..26333b4f4d3e 100644 --- a/drivers/media/dvb/firewire/firedtv-1394.c +++ b/drivers/media/dvb/firewire/firedtv-1394.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * FireDTV driver (formerly known as FireSAT) | 2 | * FireDTV driver -- ieee1394 I/O backend |
3 | * | 3 | * |
4 | * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com> | 4 | * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com> |
5 | * Copyright (C) 2007-2008 Ben Backx <ben@bbackx.com> | 5 | * Copyright (C) 2007-2008 Ben Backx <ben@bbackx.com> |
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/errno.h> | 15 | #include <linux/errno.h> |
16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
17 | #include <linux/list.h> | 17 | #include <linux/list.h> |
18 | #include <linux/slab.h> | ||
18 | #include <linux/spinlock.h> | 19 | #include <linux/spinlock.h> |
19 | #include <linux/types.h> | 20 | #include <linux/types.h> |
20 | 21 | ||
@@ -26,13 +27,16 @@ | |||
26 | #include <iso.h> | 27 | #include <iso.h> |
27 | #include <nodemgr.h> | 28 | #include <nodemgr.h> |
28 | 29 | ||
30 | #include <dvb_demux.h> | ||
31 | |||
29 | #include "firedtv.h" | 32 | #include "firedtv.h" |
30 | 33 | ||
31 | static LIST_HEAD(node_list); | 34 | static LIST_HEAD(node_list); |
32 | static DEFINE_SPINLOCK(node_list_lock); | 35 | static DEFINE_SPINLOCK(node_list_lock); |
33 | 36 | ||
34 | #define FIREWIRE_HEADER_SIZE 4 | 37 | #define CIP_HEADER_SIZE 8 |
35 | #define CIP_HEADER_SIZE 8 | 38 | #define MPEG2_TS_HEADER_SIZE 4 |
39 | #define MPEG2_TS_SOURCE_PACKET_SIZE (4 + 188) | ||
36 | 40 | ||
37 | static void rawiso_activity_cb(struct hpsb_iso *iso) | 41 | static void rawiso_activity_cb(struct hpsb_iso *iso) |
38 | { | 42 | { |
@@ -62,20 +66,20 @@ static void rawiso_activity_cb(struct hpsb_iso *iso) | |||
62 | buf = dma_region_i(&iso->data_buf, unsigned char, | 66 | buf = dma_region_i(&iso->data_buf, unsigned char, |
63 | iso->infos[packet].offset + CIP_HEADER_SIZE); | 67 | iso->infos[packet].offset + CIP_HEADER_SIZE); |
64 | count = (iso->infos[packet].len - CIP_HEADER_SIZE) / | 68 | count = (iso->infos[packet].len - CIP_HEADER_SIZE) / |
65 | (188 + FIREWIRE_HEADER_SIZE); | 69 | MPEG2_TS_SOURCE_PACKET_SIZE; |
66 | 70 | ||
67 | /* ignore empty packet */ | 71 | /* ignore empty packet */ |
68 | if (iso->infos[packet].len <= CIP_HEADER_SIZE) | 72 | if (iso->infos[packet].len <= CIP_HEADER_SIZE) |
69 | continue; | 73 | continue; |
70 | 74 | ||
71 | while (count--) { | 75 | while (count--) { |
72 | if (buf[FIREWIRE_HEADER_SIZE] == 0x47) | 76 | if (buf[MPEG2_TS_HEADER_SIZE] == 0x47) |
73 | dvb_dmx_swfilter_packets(&fdtv->demux, | 77 | dvb_dmx_swfilter_packets(&fdtv->demux, |
74 | &buf[FIREWIRE_HEADER_SIZE], 1); | 78 | &buf[MPEG2_TS_HEADER_SIZE], 1); |
75 | else | 79 | else |
76 | dev_err(fdtv->device, | 80 | dev_err(fdtv->device, |
77 | "skipping invalid packet\n"); | 81 | "skipping invalid packet\n"); |
78 | buf += 188 + FIREWIRE_HEADER_SIZE; | 82 | buf += MPEG2_TS_SOURCE_PACKET_SIZE; |
79 | } | 83 | } |
80 | } | 84 | } |
81 | out: | 85 | out: |
@@ -87,15 +91,21 @@ static inline struct node_entry *node_of(struct firedtv *fdtv) | |||
87 | return container_of(fdtv->device, struct unit_directory, device)->ne; | 91 | return container_of(fdtv->device, struct unit_directory, device)->ne; |
88 | } | 92 | } |
89 | 93 | ||
90 | static int node_lock(struct firedtv *fdtv, u64 addr, void *data, __be32 arg) | 94 | static int node_lock(struct firedtv *fdtv, u64 addr, void *data) |
91 | { | 95 | { |
92 | return hpsb_node_lock(node_of(fdtv), addr, EXTCODE_COMPARE_SWAP, data, | 96 | quadlet_t *d = data; |
93 | (__force quadlet_t)arg); | 97 | int ret; |
98 | |||
99 | ret = hpsb_node_lock(node_of(fdtv), addr, | ||
100 | EXTCODE_COMPARE_SWAP, &d[1], d[0]); | ||
101 | d[0] = d[1]; | ||
102 | |||
103 | return ret; | ||
94 | } | 104 | } |
95 | 105 | ||
96 | static int node_read(struct firedtv *fdtv, u64 addr, void *data, size_t len) | 106 | static int node_read(struct firedtv *fdtv, u64 addr, void *data) |
97 | { | 107 | { |
98 | return hpsb_node_read(node_of(fdtv), addr, data, len); | 108 | return hpsb_node_read(node_of(fdtv), addr, data, 4); |
99 | } | 109 | } |
100 | 110 | ||
101 | static int node_write(struct firedtv *fdtv, u64 addr, void *data, size_t len) | 111 | static int node_write(struct firedtv *fdtv, u64 addr, void *data, size_t len) |
@@ -184,9 +194,13 @@ static int node_probe(struct device *dev) | |||
184 | int kv_len, err; | 194 | int kv_len, err; |
185 | void *kv_str; | 195 | void *kv_str; |
186 | 196 | ||
187 | kv_len = (ud->model_name_kv->value.leaf.len - 2) * sizeof(quadlet_t); | 197 | if (ud->model_name_kv) { |
188 | kv_str = CSR1212_TEXTUAL_DESCRIPTOR_LEAF_DATA(ud->model_name_kv); | 198 | kv_len = (ud->model_name_kv->value.leaf.len - 2) * 4; |
189 | 199 | kv_str = CSR1212_TEXTUAL_DESCRIPTOR_LEAF_DATA(ud->model_name_kv); | |
200 | } else { | ||
201 | kv_len = 0; | ||
202 | kv_str = NULL; | ||
203 | } | ||
190 | fdtv = fdtv_alloc(dev, &fdtv_1394_backend, kv_str, kv_len); | 204 | fdtv = fdtv_alloc(dev, &fdtv_1394_backend, kv_str, kv_len); |
191 | if (!fdtv) | 205 | if (!fdtv) |
192 | return -ENOMEM; | 206 | return -ENOMEM; |
@@ -212,6 +226,7 @@ static int node_probe(struct device *dev) | |||
212 | goto fail; | 226 | goto fail; |
213 | 227 | ||
214 | avc_register_remote_control(fdtv); | 228 | avc_register_remote_control(fdtv); |
229 | |||
215 | return 0; | 230 | return 0; |
216 | fail: | 231 | fail: |
217 | spin_lock_irq(&node_list_lock); | 232 | spin_lock_irq(&node_list_lock); |
@@ -220,6 +235,7 @@ fail: | |||
220 | fdtv_unregister_rc(fdtv); | 235 | fdtv_unregister_rc(fdtv); |
221 | fail_free: | 236 | fail_free: |
222 | kfree(fdtv); | 237 | kfree(fdtv); |
238 | |||
223 | return err; | 239 | return err; |
224 | } | 240 | } |
225 | 241 | ||
@@ -233,10 +249,9 @@ static int node_remove(struct device *dev) | |||
233 | list_del(&fdtv->list); | 249 | list_del(&fdtv->list); |
234 | spin_unlock_irq(&node_list_lock); | 250 | spin_unlock_irq(&node_list_lock); |
235 | 251 | ||
236 | cancel_work_sync(&fdtv->remote_ctrl_work); | ||
237 | fdtv_unregister_rc(fdtv); | 252 | fdtv_unregister_rc(fdtv); |
238 | |||
239 | kfree(fdtv); | 253 | kfree(fdtv); |
254 | |||
240 | return 0; | 255 | return 0; |
241 | } | 256 | } |
242 | 257 | ||
@@ -252,6 +267,7 @@ static int node_update(struct unit_directory *ud) | |||
252 | 267 | ||
253 | static struct hpsb_protocol_driver fdtv_driver = { | 268 | static struct hpsb_protocol_driver fdtv_driver = { |
254 | .name = "firedtv", | 269 | .name = "firedtv", |
270 | .id_table = fdtv_id_table, | ||
255 | .update = node_update, | 271 | .update = node_update, |
256 | .driver = { | 272 | .driver = { |
257 | .probe = node_probe, | 273 | .probe = node_probe, |
@@ -264,12 +280,11 @@ static struct hpsb_highlevel fdtv_highlevel = { | |||
264 | .fcp_request = fcp_request, | 280 | .fcp_request = fcp_request, |
265 | }; | 281 | }; |
266 | 282 | ||
267 | int __init fdtv_1394_init(struct ieee1394_device_id id_table[]) | 283 | int __init fdtv_1394_init(void) |
268 | { | 284 | { |
269 | int ret; | 285 | int ret; |
270 | 286 | ||
271 | hpsb_register_highlevel(&fdtv_highlevel); | 287 | hpsb_register_highlevel(&fdtv_highlevel); |
272 | fdtv_driver.id_table = id_table; | ||
273 | ret = hpsb_register_protocol(&fdtv_driver); | 288 | ret = hpsb_register_protocol(&fdtv_driver); |
274 | if (ret) { | 289 | if (ret) { |
275 | printk(KERN_ERR "firedtv: failed to register protocol\n"); | 290 | printk(KERN_ERR "firedtv: failed to register protocol\n"); |