diff options
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/dvb/firewire/firedtv-1394.c | 9 | ||||
-rw-r--r-- | drivers/media/dvb/firewire/firedtv-avc.c | 437 | ||||
-rw-r--r-- | drivers/media/dvb/firewire/firedtv-dvb.c | 1 | ||||
-rw-r--r-- | drivers/media/dvb/firewire/firedtv-fw.c | 2 | ||||
-rw-r--r-- | drivers/media/dvb/firewire/firedtv.h | 6 |
5 files changed, 264 insertions, 191 deletions
diff --git a/drivers/media/dvb/firewire/firedtv-1394.c b/drivers/media/dvb/firewire/firedtv-1394.c index 81a56293540d..c3e0ec2dcfca 100644 --- a/drivers/media/dvb/firewire/firedtv-1394.c +++ b/drivers/media/dvb/firewire/firedtv-1394.c | |||
@@ -90,13 +90,14 @@ static inline struct node_entry *node_of(struct firedtv *fdtv) | |||
90 | return container_of(fdtv->device, struct unit_directory, device)->ne; | 90 | return container_of(fdtv->device, struct unit_directory, device)->ne; |
91 | } | 91 | } |
92 | 92 | ||
93 | static int node_lock(struct firedtv *fdtv, u64 addr, __be32 data[]) | 93 | static int node_lock(struct firedtv *fdtv, u64 addr, void *data) |
94 | { | 94 | { |
95 | quadlet_t *d = data; | ||
95 | int ret; | 96 | int ret; |
96 | 97 | ||
97 | ret = hpsb_node_lock(node_of(fdtv), addr, EXTCODE_COMPARE_SWAP, | 98 | ret = hpsb_node_lock(node_of(fdtv), addr, |
98 | (__force quadlet_t *)&data[1], (__force quadlet_t)data[0]); | 99 | EXTCODE_COMPARE_SWAP, &d[1], d[0]); |
99 | data[0] = data[1]; | 100 | d[0] = d[1]; |
100 | 101 | ||
101 | return ret; | 102 | return ret; |
102 | } | 103 | } |
diff --git a/drivers/media/dvb/firewire/firedtv-avc.c b/drivers/media/dvb/firewire/firedtv-avc.c index 50c42a4b972b..8f3105420756 100644 --- a/drivers/media/dvb/firewire/firedtv-avc.c +++ b/drivers/media/dvb/firewire/firedtv-avc.c | |||
@@ -74,7 +74,6 @@ | |||
74 | #define EN50221_TAG_CA_INFO 0x9f8031 | 74 | #define EN50221_TAG_CA_INFO 0x9f8031 |
75 | 75 | ||
76 | struct avc_command_frame { | 76 | struct avc_command_frame { |
77 | int length; | ||
78 | u8 ctype; | 77 | u8 ctype; |
79 | u8 subunit; | 78 | u8 subunit; |
80 | u8 opcode; | 79 | u8 opcode; |
@@ -82,7 +81,6 @@ struct avc_command_frame { | |||
82 | }; | 81 | }; |
83 | 82 | ||
84 | struct avc_response_frame { | 83 | struct avc_response_frame { |
85 | int length; | ||
86 | u8 response; | 84 | u8 response; |
87 | u8 subunit; | 85 | u8 subunit; |
88 | u8 opcode; | 86 | u8 opcode; |
@@ -202,78 +200,65 @@ static void debug_pmt(char *msg, int length) | |||
202 | 16, 1, msg, length, false); | 200 | 16, 1, msg, length, false); |
203 | } | 201 | } |
204 | 202 | ||
205 | static int __avc_write(struct firedtv *fdtv, | 203 | static int avc_write(struct firedtv *fdtv) |
206 | const struct avc_command_frame *c, struct avc_response_frame *r) | ||
207 | { | 204 | { |
208 | int err, retry; | 205 | int err, retry; |
209 | 206 | ||
210 | if (r) | 207 | fdtv->avc_reply_received = false; |
211 | fdtv->avc_reply_received = false; | ||
212 | 208 | ||
213 | for (retry = 0; retry < 6; retry++) { | 209 | for (retry = 0; retry < 6; retry++) { |
214 | if (unlikely(avc_debug)) | 210 | if (unlikely(avc_debug)) |
215 | debug_fcp(&c->ctype, c->length); | 211 | debug_fcp(fdtv->avc_data, fdtv->avc_data_length); |
216 | 212 | ||
217 | err = fdtv->backend->write(fdtv, FCP_COMMAND_REGISTER, | 213 | err = fdtv->backend->write(fdtv, FCP_COMMAND_REGISTER, |
218 | (void *)&c->ctype, c->length); | 214 | fdtv->avc_data, fdtv->avc_data_length); |
219 | if (err) { | 215 | if (err) { |
220 | fdtv->avc_reply_received = true; | ||
221 | dev_err(fdtv->device, "FCP command write failed\n"); | 216 | dev_err(fdtv->device, "FCP command write failed\n"); |
217 | |||
222 | return err; | 218 | return err; |
223 | } | 219 | } |
224 | 220 | ||
225 | if (!r) | ||
226 | return 0; | ||
227 | |||
228 | /* | 221 | /* |
229 | * AV/C specs say that answers should be sent within 150 ms. | 222 | * AV/C specs say that answers should be sent within 150 ms. |
230 | * Time out after 200 ms. | 223 | * Time out after 200 ms. |
231 | */ | 224 | */ |
232 | if (wait_event_timeout(fdtv->avc_wait, | 225 | if (wait_event_timeout(fdtv->avc_wait, |
233 | fdtv->avc_reply_received, | 226 | fdtv->avc_reply_received, |
234 | msecs_to_jiffies(200)) != 0) { | 227 | msecs_to_jiffies(200)) != 0) |
235 | r->length = fdtv->response_length; | ||
236 | memcpy(&r->response, fdtv->response, r->length); | ||
237 | |||
238 | return 0; | 228 | return 0; |
239 | } | ||
240 | } | 229 | } |
241 | dev_err(fdtv->device, "FCP response timed out\n"); | 230 | dev_err(fdtv->device, "FCP response timed out\n"); |
231 | |||
242 | return -ETIMEDOUT; | 232 | return -ETIMEDOUT; |
243 | } | 233 | } |
244 | 234 | ||
245 | static int avc_write(struct firedtv *fdtv, | 235 | static bool is_register_rc(struct avc_response_frame *r) |
246 | const struct avc_command_frame *c, struct avc_response_frame *r) | ||
247 | { | 236 | { |
248 | int ret; | 237 | return r->opcode == AVC_OPCODE_VENDOR && |
249 | 238 | r->operand[0] == SFE_VENDOR_DE_COMPANYID_0 && | |
250 | if (mutex_lock_interruptible(&fdtv->avc_mutex)) | 239 | r->operand[1] == SFE_VENDOR_DE_COMPANYID_1 && |
251 | return -EINTR; | 240 | r->operand[2] == SFE_VENDOR_DE_COMPANYID_2 && |
252 | 241 | r->operand[3] == SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL; | |
253 | ret = __avc_write(fdtv, c, r); | ||
254 | |||
255 | mutex_unlock(&fdtv->avc_mutex); | ||
256 | return ret; | ||
257 | } | 242 | } |
258 | 243 | ||
259 | int avc_recv(struct firedtv *fdtv, void *data, size_t length) | 244 | int avc_recv(struct firedtv *fdtv, void *data, size_t length) |
260 | { | 245 | { |
261 | struct avc_response_frame *r = | 246 | struct avc_response_frame *r = data; |
262 | data - offsetof(struct avc_response_frame, response); | ||
263 | 247 | ||
264 | if (unlikely(avc_debug)) | 248 | if (unlikely(avc_debug)) |
265 | debug_fcp(data, length); | 249 | debug_fcp(data, length); |
266 | 250 | ||
267 | if (length >= 8 && | 251 | if (length >= 8 && is_register_rc(r)) { |
268 | r->operand[0] == SFE_VENDOR_DE_COMPANYID_0 && | 252 | switch (r->response) { |
269 | r->operand[1] == SFE_VENDOR_DE_COMPANYID_1 && | 253 | case AVC_RESPONSE_CHANGED: |
270 | r->operand[2] == SFE_VENDOR_DE_COMPANYID_2 && | 254 | fdtv_handle_rc(fdtv, r->operand[4] << 8 | r->operand[5]); |
271 | r->operand[3] == SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL) { | ||
272 | if (r->response == AVC_RESPONSE_CHANGED) { | ||
273 | fdtv_handle_rc(fdtv, | ||
274 | r->operand[4] << 8 | r->operand[5]); | ||
275 | schedule_work(&fdtv->remote_ctrl_work); | 255 | schedule_work(&fdtv->remote_ctrl_work); |
276 | } else if (r->response != AVC_RESPONSE_INTERIM) { | 256 | break; |
257 | case AVC_RESPONSE_INTERIM: | ||
258 | if (is_register_rc((void *)fdtv->avc_data)) | ||
259 | goto wake; | ||
260 | break; | ||
261 | default: | ||
277 | dev_info(fdtv->device, | 262 | dev_info(fdtv->device, |
278 | "remote control result = %d\n", r->response); | 263 | "remote control result = %d\n", r->response); |
279 | } | 264 | } |
@@ -285,9 +270,9 @@ int avc_recv(struct firedtv *fdtv, void *data, size_t length) | |||
285 | return -EIO; | 270 | return -EIO; |
286 | } | 271 | } |
287 | 272 | ||
288 | memcpy(fdtv->response, data, length); | 273 | memcpy(fdtv->avc_data, data, length); |
289 | fdtv->response_length = length; | 274 | fdtv->avc_data_length = length; |
290 | 275 | wake: | |
291 | fdtv->avc_reply_received = true; | 276 | fdtv->avc_reply_received = true; |
292 | wake_up(&fdtv->avc_wait); | 277 | wake_up(&fdtv->avc_wait); |
293 | 278 | ||
@@ -319,9 +304,10 @@ static int add_pid_filter(struct firedtv *fdtv, u8 *operand) | |||
319 | * (not supported by the AVC standard) | 304 | * (not supported by the AVC standard) |
320 | */ | 305 | */ |
321 | static void avc_tuner_tuneqpsk(struct firedtv *fdtv, | 306 | static void avc_tuner_tuneqpsk(struct firedtv *fdtv, |
322 | struct dvb_frontend_parameters *params, | 307 | struct dvb_frontend_parameters *params) |
323 | struct avc_command_frame *c) | ||
324 | { | 308 | { |
309 | struct avc_command_frame *c = (void *)fdtv->avc_data; | ||
310 | |||
325 | c->opcode = AVC_OPCODE_VENDOR; | 311 | c->opcode = AVC_OPCODE_VENDOR; |
326 | 312 | ||
327 | c->operand[0] = SFE_VENDOR_DE_COMPANYID_0; | 313 | c->operand[0] = SFE_VENDOR_DE_COMPANYID_0; |
@@ -370,16 +356,17 @@ static void avc_tuner_tuneqpsk(struct firedtv *fdtv, | |||
370 | c->operand[13] = 0x1; | 356 | c->operand[13] = 0x1; |
371 | c->operand[14] = 0xff; | 357 | c->operand[14] = 0xff; |
372 | c->operand[15] = 0xff; | 358 | c->operand[15] = 0xff; |
373 | c->length = 20; | 359 | fdtv->avc_data_length = 20; |
374 | } else { | 360 | } else { |
375 | c->length = 16; | 361 | fdtv->avc_data_length = 16; |
376 | } | 362 | } |
377 | } | 363 | } |
378 | 364 | ||
379 | static void avc_tuner_dsd_dvb_c(struct firedtv *fdtv, | 365 | static void avc_tuner_dsd_dvb_c(struct firedtv *fdtv, |
380 | struct dvb_frontend_parameters *params, | 366 | struct dvb_frontend_parameters *params) |
381 | struct avc_command_frame *c) | ||
382 | { | 367 | { |
368 | struct avc_command_frame *c = (void *)fdtv->avc_data; | ||
369 | |||
383 | c->opcode = AVC_OPCODE_DSD; | 370 | c->opcode = AVC_OPCODE_DSD; |
384 | 371 | ||
385 | c->operand[0] = 0; /* source plug */ | 372 | c->operand[0] = 0; /* source plug */ |
@@ -441,14 +428,15 @@ static void avc_tuner_dsd_dvb_c(struct firedtv *fdtv, | |||
441 | c->operand[21] = 0x00; | 428 | c->operand[21] = 0x00; |
442 | 429 | ||
443 | /* Add PIDs to filter */ | 430 | /* Add PIDs to filter */ |
444 | c->length = ALIGN(22 + add_pid_filter(fdtv, &c->operand[22]) + 3, 4); | 431 | fdtv->avc_data_length = |
432 | ALIGN(22 + add_pid_filter(fdtv, &c->operand[22]) + 3, 4); | ||
445 | } | 433 | } |
446 | 434 | ||
447 | static void avc_tuner_dsd_dvb_t(struct firedtv *fdtv, | 435 | static void avc_tuner_dsd_dvb_t(struct firedtv *fdtv, |
448 | struct dvb_frontend_parameters *params, | 436 | struct dvb_frontend_parameters *params) |
449 | struct avc_command_frame *c) | ||
450 | { | 437 | { |
451 | struct dvb_ofdm_parameters *ofdm = ¶ms->u.ofdm; | 438 | struct dvb_ofdm_parameters *ofdm = ¶ms->u.ofdm; |
439 | struct avc_command_frame *c = (void *)fdtv->avc_data; | ||
452 | 440 | ||
453 | c->opcode = AVC_OPCODE_DSD; | 441 | c->opcode = AVC_OPCODE_DSD; |
454 | 442 | ||
@@ -544,15 +532,18 @@ static void avc_tuner_dsd_dvb_t(struct firedtv *fdtv, | |||
544 | c->operand[16] = 0x00; /* network_ID[1] */ | 532 | c->operand[16] = 0x00; /* network_ID[1] */ |
545 | 533 | ||
546 | /* Add PIDs to filter */ | 534 | /* Add PIDs to filter */ |
547 | c->length = ALIGN(17 + add_pid_filter(fdtv, &c->operand[17]) + 3, 4); | 535 | fdtv->avc_data_length = |
536 | ALIGN(17 + add_pid_filter(fdtv, &c->operand[17]) + 3, 4); | ||
548 | } | 537 | } |
549 | 538 | ||
550 | int avc_tuner_dsd(struct firedtv *fdtv, | 539 | int avc_tuner_dsd(struct firedtv *fdtv, |
551 | struct dvb_frontend_parameters *params) | 540 | struct dvb_frontend_parameters *params) |
552 | { | 541 | { |
553 | char buffer[sizeof(struct avc_command_frame)]; | 542 | struct avc_command_frame *c = (void *)fdtv->avc_data; |
554 | struct avc_command_frame *c = (void *)buffer; | 543 | int ret; |
555 | struct avc_response_frame *r = (void *)buffer; /* FIXME: unused */ | 544 | |
545 | if (mutex_lock_interruptible(&fdtv->avc_mutex)) | ||
546 | return -EINTR; | ||
556 | 547 | ||
557 | memset(c, 0, sizeof(*c)); | 548 | memset(c, 0, sizeof(*c)); |
558 | 549 | ||
@@ -561,36 +552,41 @@ int avc_tuner_dsd(struct firedtv *fdtv, | |||
561 | 552 | ||
562 | switch (fdtv->type) { | 553 | switch (fdtv->type) { |
563 | case FIREDTV_DVB_S: | 554 | case FIREDTV_DVB_S: |
564 | case FIREDTV_DVB_S2: avc_tuner_tuneqpsk(fdtv, params, c); break; | 555 | case FIREDTV_DVB_S2: avc_tuner_tuneqpsk(fdtv, params); break; |
565 | case FIREDTV_DVB_C: avc_tuner_dsd_dvb_c(fdtv, params, c); break; | 556 | case FIREDTV_DVB_C: avc_tuner_dsd_dvb_c(fdtv, params); break; |
566 | case FIREDTV_DVB_T: avc_tuner_dsd_dvb_t(fdtv, params, c); break; | 557 | case FIREDTV_DVB_T: avc_tuner_dsd_dvb_t(fdtv, params); break; |
567 | default: | 558 | default: |
568 | BUG(); | 559 | BUG(); |
569 | } | 560 | } |
570 | 561 | ret = avc_write(fdtv); | |
571 | if (avc_write(fdtv, c, r) < 0) | ||
572 | return -EIO; | ||
573 | |||
574 | msleep(500); | ||
575 | #if 0 | 562 | #if 0 |
576 | /* FIXME: */ | 563 | /* |
577 | /* u8 *status was an out-parameter of avc_tuner_dsd, unused by caller */ | 564 | * FIXME: |
565 | * u8 *status was an out-parameter of avc_tuner_dsd, unused by caller. | ||
566 | * Check for AVC_RESPONSE_ACCEPTED here instead? | ||
567 | */ | ||
578 | if (status) | 568 | if (status) |
579 | *status = r->operand[2]; | 569 | *status = r->operand[2]; |
580 | #endif | 570 | #endif |
581 | return 0; | 571 | mutex_unlock(&fdtv->avc_mutex); |
572 | |||
573 | if (ret == 0) | ||
574 | msleep(500); | ||
575 | |||
576 | return ret; | ||
582 | } | 577 | } |
583 | 578 | ||
584 | int avc_tuner_set_pids(struct firedtv *fdtv, unsigned char pidc, u16 pid[]) | 579 | int avc_tuner_set_pids(struct firedtv *fdtv, unsigned char pidc, u16 pid[]) |
585 | { | 580 | { |
586 | char buffer[sizeof(struct avc_command_frame)]; | 581 | struct avc_command_frame *c = (void *)fdtv->avc_data; |
587 | struct avc_command_frame *c = (void *)buffer; | 582 | int ret, pos, k; |
588 | struct avc_response_frame *r = (void *)buffer; /* FIXME: unused */ | ||
589 | int pos, k; | ||
590 | 583 | ||
591 | if (pidc > 16 && pidc != 0xff) | 584 | if (pidc > 16 && pidc != 0xff) |
592 | return -EINVAL; | 585 | return -EINVAL; |
593 | 586 | ||
587 | if (mutex_lock_interruptible(&fdtv->avc_mutex)) | ||
588 | return -EINTR; | ||
589 | |||
594 | memset(c, 0, sizeof(*c)); | 590 | memset(c, 0, sizeof(*c)); |
595 | 591 | ||
596 | c->ctype = AVC_CTYPE_CONTROL; | 592 | c->ctype = AVC_CTYPE_CONTROL; |
@@ -615,21 +611,26 @@ int avc_tuner_set_pids(struct firedtv *fdtv, unsigned char pidc, u16 pid[]) | |||
615 | c->operand[pos++] = 0x00; /* filter_length */ | 611 | c->operand[pos++] = 0x00; /* filter_length */ |
616 | } | 612 | } |
617 | 613 | ||
618 | c->length = ALIGN(3 + pos, 4); | 614 | fdtv->avc_data_length = ALIGN(3 + pos, 4); |
615 | ret = avc_write(fdtv); | ||
619 | 616 | ||
620 | if (avc_write(fdtv, c, r) < 0) | 617 | /* FIXME: check response code? */ |
621 | return -EIO; | ||
622 | 618 | ||
623 | msleep(50); | 619 | mutex_unlock(&fdtv->avc_mutex); |
624 | return 0; | 620 | |
621 | if (ret == 0) | ||
622 | msleep(50); | ||
623 | |||
624 | return ret; | ||
625 | } | 625 | } |
626 | 626 | ||
627 | int avc_tuner_get_ts(struct firedtv *fdtv) | 627 | int avc_tuner_get_ts(struct firedtv *fdtv) |
628 | { | 628 | { |
629 | char buffer[sizeof(struct avc_command_frame)]; | 629 | struct avc_command_frame *c = (void *)fdtv->avc_data; |
630 | struct avc_command_frame *c = (void *)buffer; | 630 | int ret, sl; |
631 | struct avc_response_frame *r = (void *)buffer; /* FIXME: unused */ | 631 | |
632 | int sl; | 632 | if (mutex_lock_interruptible(&fdtv->avc_mutex)) |
633 | return -EINTR; | ||
633 | 634 | ||
634 | memset(c, 0, sizeof(*c)); | 635 | memset(c, 0, sizeof(*c)); |
635 | 636 | ||
@@ -650,20 +651,27 @@ int avc_tuner_get_ts(struct firedtv *fdtv) | |||
650 | c->operand[8] = 0x00; /* valid_flags [1] */ | 651 | c->operand[8] = 0x00; /* valid_flags [1] */ |
651 | c->operand[7 + sl] = 0x00; /* nr_of_dsit_sel_specs (always 0) */ | 652 | c->operand[7 + sl] = 0x00; /* nr_of_dsit_sel_specs (always 0) */ |
652 | 653 | ||
653 | c->length = fdtv->type == FIREDTV_DVB_T ? 24 : 28; | 654 | fdtv->avc_data_length = fdtv->type == FIREDTV_DVB_T ? 24 : 28; |
655 | ret = avc_write(fdtv); | ||
654 | 656 | ||
655 | if (avc_write(fdtv, c, r) < 0) | 657 | /* FIXME: check response code? */ |
656 | return -EIO; | ||
657 | 658 | ||
658 | msleep(250); | 659 | mutex_unlock(&fdtv->avc_mutex); |
659 | return 0; | 660 | |
661 | if (ret == 0) | ||
662 | msleep(250); | ||
663 | |||
664 | return ret; | ||
660 | } | 665 | } |
661 | 666 | ||
662 | int avc_identify_subunit(struct firedtv *fdtv) | 667 | int avc_identify_subunit(struct firedtv *fdtv) |
663 | { | 668 | { |
664 | char buffer[sizeof(struct avc_command_frame)]; | 669 | struct avc_command_frame *c = (void *)fdtv->avc_data; |
665 | struct avc_command_frame *c = (void *)buffer; | 670 | struct avc_response_frame *r = (void *)fdtv->avc_data; |
666 | struct avc_response_frame *r = (void *)buffer; | 671 | int ret; |
672 | |||
673 | if (mutex_lock_interruptible(&fdtv->avc_mutex)) | ||
674 | return -EINTR; | ||
667 | 675 | ||
668 | memset(c, 0, sizeof(*c)); | 676 | memset(c, 0, sizeof(*c)); |
669 | 677 | ||
@@ -679,28 +687,33 @@ int avc_identify_subunit(struct firedtv *fdtv) | |||
679 | c->operand[5] = 0x00; /* offset highbyte */ | 687 | c->operand[5] = 0x00; /* offset highbyte */ |
680 | c->operand[6] = 0x0d; /* offset lowbyte */ | 688 | c->operand[6] = 0x0d; /* offset lowbyte */ |
681 | 689 | ||
682 | c->length = 12; | 690 | fdtv->avc_data_length = 12; |
683 | 691 | ret = avc_write(fdtv); | |
684 | if (avc_write(fdtv, c, r) < 0) | 692 | if (ret < 0) |
685 | return -EIO; | 693 | goto out; |
686 | 694 | ||
687 | if ((r->response != AVC_RESPONSE_STABLE && | 695 | if ((r->response != AVC_RESPONSE_STABLE && |
688 | r->response != AVC_RESPONSE_ACCEPTED) || | 696 | r->response != AVC_RESPONSE_ACCEPTED) || |
689 | (r->operand[3] << 8) + r->operand[4] != 8) { | 697 | (r->operand[3] << 8) + r->operand[4] != 8) { |
690 | dev_err(fdtv->device, "cannot read subunit identifier\n"); | 698 | dev_err(fdtv->device, "cannot read subunit identifier\n"); |
691 | return -EINVAL; | 699 | ret = -EINVAL; |
692 | } | 700 | } |
693 | return 0; | 701 | out: |
702 | mutex_unlock(&fdtv->avc_mutex); | ||
703 | |||
704 | return ret; | ||
694 | } | 705 | } |
695 | 706 | ||
696 | #define SIZEOF_ANTENNA_INPUT_INFO 22 | 707 | #define SIZEOF_ANTENNA_INPUT_INFO 22 |
697 | 708 | ||
698 | int avc_tuner_status(struct firedtv *fdtv, struct firedtv_tuner_status *stat) | 709 | int avc_tuner_status(struct firedtv *fdtv, struct firedtv_tuner_status *stat) |
699 | { | 710 | { |
700 | char buffer[sizeof(struct avc_command_frame)]; | 711 | struct avc_command_frame *c = (void *)fdtv->avc_data; |
701 | struct avc_command_frame *c = (void *)buffer; | 712 | struct avc_response_frame *r = (void *)fdtv->avc_data; |
702 | struct avc_response_frame *r = (void *)buffer; | 713 | int length, ret; |
703 | int length; | 714 | |
715 | if (mutex_lock_interruptible(&fdtv->avc_mutex)) | ||
716 | return -EINTR; | ||
704 | 717 | ||
705 | memset(c, 0, sizeof(*c)); | 718 | memset(c, 0, sizeof(*c)); |
706 | 719 | ||
@@ -716,21 +729,23 @@ int avc_tuner_status(struct firedtv *fdtv, struct firedtv_tuner_status *stat) | |||
716 | c->operand[5] = 0x00; | 729 | c->operand[5] = 0x00; |
717 | c->operand[6] = 0x00; | 730 | c->operand[6] = 0x00; |
718 | 731 | ||
719 | c->length = 12; | 732 | fdtv->avc_data_length = 12; |
720 | 733 | ret = avc_write(fdtv); | |
721 | if (avc_write(fdtv, c, r) < 0) | 734 | if (ret < 0) |
722 | return -EIO; | 735 | goto out; |
723 | 736 | ||
724 | if (r->response != AVC_RESPONSE_STABLE && | 737 | if (r->response != AVC_RESPONSE_STABLE && |
725 | r->response != AVC_RESPONSE_ACCEPTED) { | 738 | r->response != AVC_RESPONSE_ACCEPTED) { |
726 | dev_err(fdtv->device, "cannot read tuner status\n"); | 739 | dev_err(fdtv->device, "cannot read tuner status\n"); |
727 | return -EINVAL; | 740 | ret = -EINVAL; |
741 | goto out; | ||
728 | } | 742 | } |
729 | 743 | ||
730 | length = r->operand[9]; | 744 | length = r->operand[9]; |
731 | if (r->operand[1] != 0x10 || length != SIZEOF_ANTENNA_INPUT_INFO) { | 745 | if (r->operand[1] != 0x10 || length != SIZEOF_ANTENNA_INPUT_INFO) { |
732 | dev_err(fdtv->device, "got invalid tuner status\n"); | 746 | dev_err(fdtv->device, "got invalid tuner status\n"); |
733 | return -EINVAL; | 747 | ret = -EINVAL; |
748 | goto out; | ||
734 | } | 749 | } |
735 | 750 | ||
736 | stat->active_system = r->operand[10]; | 751 | stat->active_system = r->operand[10]; |
@@ -766,18 +781,22 @@ int avc_tuner_status(struct firedtv *fdtv, struct firedtv_tuner_status *stat) | |||
766 | stat->ca_dvb_flag = r->operand[31] >> 3 & 1; | 781 | stat->ca_dvb_flag = r->operand[31] >> 3 & 1; |
767 | stat->ca_error_flag = r->operand[31] >> 2 & 1; | 782 | stat->ca_error_flag = r->operand[31] >> 2 & 1; |
768 | stat->ca_initialization_status = r->operand[31] >> 1 & 1; | 783 | stat->ca_initialization_status = r->operand[31] >> 1 & 1; |
784 | out: | ||
785 | mutex_unlock(&fdtv->avc_mutex); | ||
769 | 786 | ||
770 | return 0; | 787 | return ret; |
771 | } | 788 | } |
772 | 789 | ||
773 | int avc_lnb_control(struct firedtv *fdtv, char voltage, char burst, | 790 | int avc_lnb_control(struct firedtv *fdtv, char voltage, char burst, |
774 | char conttone, char nrdiseq, | 791 | char conttone, char nrdiseq, |
775 | struct dvb_diseqc_master_cmd *diseqcmd) | 792 | struct dvb_diseqc_master_cmd *diseqcmd) |
776 | { | 793 | { |
777 | char buffer[sizeof(struct avc_command_frame)]; | 794 | struct avc_command_frame *c = (void *)fdtv->avc_data; |
778 | struct avc_command_frame *c = (void *)buffer; | 795 | struct avc_response_frame *r = (void *)fdtv->avc_data; |
779 | struct avc_response_frame *r = (void *)buffer; | 796 | int i, j, k, ret; |
780 | int i, j, k; | 797 | |
798 | if (mutex_lock_interruptible(&fdtv->avc_mutex)) | ||
799 | return -EINTR; | ||
781 | 800 | ||
782 | memset(c, 0, sizeof(*c)); | 801 | memset(c, 0, sizeof(*c)); |
783 | 802 | ||
@@ -805,23 +824,28 @@ int avc_lnb_control(struct firedtv *fdtv, char voltage, char burst, | |||
805 | c->operand[i++] = burst; | 824 | c->operand[i++] = burst; |
806 | c->operand[i++] = conttone; | 825 | c->operand[i++] = conttone; |
807 | 826 | ||
808 | c->length = ALIGN(3 + i, 4); | 827 | fdtv->avc_data_length = ALIGN(3 + i, 4); |
809 | 828 | ret = avc_write(fdtv); | |
810 | if (avc_write(fdtv, c, r) < 0) | 829 | if (ret < 0) |
811 | return -EIO; | 830 | goto out; |
812 | 831 | ||
813 | if (r->response != AVC_RESPONSE_ACCEPTED) { | 832 | if (r->response != AVC_RESPONSE_ACCEPTED) { |
814 | dev_err(fdtv->device, "LNB control failed\n"); | 833 | dev_err(fdtv->device, "LNB control failed\n"); |
815 | return -EINVAL; | 834 | ret = -EINVAL; |
816 | } | 835 | } |
836 | out: | ||
837 | mutex_unlock(&fdtv->avc_mutex); | ||
817 | 838 | ||
818 | return 0; | 839 | return ret; |
819 | } | 840 | } |
820 | 841 | ||
821 | int avc_register_remote_control(struct firedtv *fdtv) | 842 | int avc_register_remote_control(struct firedtv *fdtv) |
822 | { | 843 | { |
823 | char buffer[sizeof(struct avc_command_frame)]; | 844 | struct avc_command_frame *c = (void *)fdtv->avc_data; |
824 | struct avc_command_frame *c = (void *)buffer; | 845 | int ret; |
846 | |||
847 | if (mutex_lock_interruptible(&fdtv->avc_mutex)) | ||
848 | return -EINTR; | ||
825 | 849 | ||
826 | memset(c, 0, sizeof(*c)); | 850 | memset(c, 0, sizeof(*c)); |
827 | 851 | ||
@@ -834,9 +858,14 @@ int avc_register_remote_control(struct firedtv *fdtv) | |||
834 | c->operand[2] = SFE_VENDOR_DE_COMPANYID_2; | 858 | c->operand[2] = SFE_VENDOR_DE_COMPANYID_2; |
835 | c->operand[3] = SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL; | 859 | c->operand[3] = SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL; |
836 | 860 | ||
837 | c->length = 8; | 861 | fdtv->avc_data_length = 8; |
862 | ret = avc_write(fdtv); | ||
838 | 863 | ||
839 | return avc_write(fdtv, c, NULL); | 864 | /* FIXME: check response code? */ |
865 | |||
866 | mutex_unlock(&fdtv->avc_mutex); | ||
867 | |||
868 | return ret; | ||
840 | } | 869 | } |
841 | 870 | ||
842 | void avc_remote_ctrl_work(struct work_struct *work) | 871 | void avc_remote_ctrl_work(struct work_struct *work) |
@@ -851,9 +880,11 @@ void avc_remote_ctrl_work(struct work_struct *work) | |||
851 | #if 0 /* FIXME: unused */ | 880 | #if 0 /* FIXME: unused */ |
852 | int avc_tuner_host2ca(struct firedtv *fdtv) | 881 | int avc_tuner_host2ca(struct firedtv *fdtv) |
853 | { | 882 | { |
854 | char buffer[sizeof(struct avc_command_frame)]; | 883 | struct avc_command_frame *c = (void *)fdtv->avc_data; |
855 | struct avc_command_frame *c = (void *)buffer; | 884 | int ret; |
856 | struct avc_response_frame *r = (void *)buffer; /* FIXME: unused */ | 885 | |
886 | if (mutex_lock_interruptible(&fdtv->avc_mutex)) | ||
887 | return -EINTR; | ||
857 | 888 | ||
858 | memset(c, 0, sizeof(*c)); | 889 | memset(c, 0, sizeof(*c)); |
859 | 890 | ||
@@ -870,12 +901,14 @@ int avc_tuner_host2ca(struct firedtv *fdtv) | |||
870 | c->operand[6] = 0; /* more/last */ | 901 | c->operand[6] = 0; /* more/last */ |
871 | c->operand[7] = 0; /* length */ | 902 | c->operand[7] = 0; /* length */ |
872 | 903 | ||
873 | c->length = 12; | 904 | fdtv->avc_data_length = 12; |
905 | ret = avc_write(fdtv); | ||
874 | 906 | ||
875 | if (avc_write(fdtv, c, r) < 0) | 907 | /* FIXME: check response code? */ |
876 | return -EIO; | ||
877 | 908 | ||
878 | return 0; | 909 | mutex_unlock(&fdtv->avc_mutex); |
910 | |||
911 | return ret; | ||
879 | } | 912 | } |
880 | #endif | 913 | #endif |
881 | 914 | ||
@@ -906,10 +939,12 @@ static int get_ca_object_length(struct avc_response_frame *r) | |||
906 | 939 | ||
907 | int avc_ca_app_info(struct firedtv *fdtv, char *app_info, unsigned int *len) | 940 | int avc_ca_app_info(struct firedtv *fdtv, char *app_info, unsigned int *len) |
908 | { | 941 | { |
909 | char buffer[sizeof(struct avc_command_frame)]; | 942 | struct avc_command_frame *c = (void *)fdtv->avc_data; |
910 | struct avc_command_frame *c = (void *)buffer; | 943 | struct avc_response_frame *r = (void *)fdtv->avc_data; |
911 | struct avc_response_frame *r = (void *)buffer; | 944 | int pos, ret; |
912 | int pos; | 945 | |
946 | if (mutex_lock_interruptible(&fdtv->avc_mutex)) | ||
947 | return -EINTR; | ||
913 | 948 | ||
914 | memset(c, 0, sizeof(*c)); | 949 | memset(c, 0, sizeof(*c)); |
915 | 950 | ||
@@ -924,10 +959,10 @@ int avc_ca_app_info(struct firedtv *fdtv, char *app_info, unsigned int *len) | |||
924 | c->operand[4] = 0; /* slot */ | 959 | c->operand[4] = 0; /* slot */ |
925 | c->operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; /* ca tag */ | 960 | c->operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; /* ca tag */ |
926 | 961 | ||
927 | c->length = 12; | 962 | fdtv->avc_data_length = 12; |
928 | 963 | ret = avc_write(fdtv); | |
929 | if (avc_write(fdtv, c, r) < 0) | 964 | if (ret < 0) |
930 | return -EIO; | 965 | goto out; |
931 | 966 | ||
932 | /* FIXME: check response code and validate response data */ | 967 | /* FIXME: check response code and validate response data */ |
933 | 968 | ||
@@ -939,16 +974,20 @@ int avc_ca_app_info(struct firedtv *fdtv, char *app_info, unsigned int *len) | |||
939 | app_info[4] = 0x01; | 974 | app_info[4] = 0x01; |
940 | memcpy(&app_info[5], &r->operand[pos], 5 + r->operand[pos + 4]); | 975 | memcpy(&app_info[5], &r->operand[pos], 5 + r->operand[pos + 4]); |
941 | *len = app_info[3] + 4; | 976 | *len = app_info[3] + 4; |
977 | out: | ||
978 | mutex_unlock(&fdtv->avc_mutex); | ||
942 | 979 | ||
943 | return 0; | 980 | return ret; |
944 | } | 981 | } |
945 | 982 | ||
946 | int avc_ca_info(struct firedtv *fdtv, char *app_info, unsigned int *len) | 983 | int avc_ca_info(struct firedtv *fdtv, char *app_info, unsigned int *len) |
947 | { | 984 | { |
948 | char buffer[sizeof(struct avc_command_frame)]; | 985 | struct avc_command_frame *c = (void *)fdtv->avc_data; |
949 | struct avc_command_frame *c = (void *)buffer; | 986 | struct avc_response_frame *r = (void *)fdtv->avc_data; |
950 | struct avc_response_frame *r = (void *)buffer; | 987 | int pos, ret; |
951 | int pos; | 988 | |
989 | if (mutex_lock_interruptible(&fdtv->avc_mutex)) | ||
990 | return -EINTR; | ||
952 | 991 | ||
953 | memset(c, 0, sizeof(*c)); | 992 | memset(c, 0, sizeof(*c)); |
954 | 993 | ||
@@ -963,10 +1002,12 @@ int avc_ca_info(struct firedtv *fdtv, char *app_info, unsigned int *len) | |||
963 | c->operand[4] = 0; /* slot */ | 1002 | c->operand[4] = 0; /* slot */ |
964 | c->operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; /* ca tag */ | 1003 | c->operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; /* ca tag */ |
965 | 1004 | ||
966 | c->length = 12; | 1005 | fdtv->avc_data_length = 12; |
1006 | ret = avc_write(fdtv); | ||
1007 | if (ret < 0) | ||
1008 | goto out; | ||
967 | 1009 | ||
968 | if (avc_write(fdtv, c, r) < 0) | 1010 | /* FIXME: check response code and validate response data */ |
969 | return -EIO; | ||
970 | 1011 | ||
971 | pos = get_ca_object_pos(r); | 1012 | pos = get_ca_object_pos(r); |
972 | app_info[0] = (EN50221_TAG_CA_INFO >> 16) & 0xff; | 1013 | app_info[0] = (EN50221_TAG_CA_INFO >> 16) & 0xff; |
@@ -976,15 +1017,19 @@ int avc_ca_info(struct firedtv *fdtv, char *app_info, unsigned int *len) | |||
976 | app_info[4] = r->operand[pos + 0]; | 1017 | app_info[4] = r->operand[pos + 0]; |
977 | app_info[5] = r->operand[pos + 1]; | 1018 | app_info[5] = r->operand[pos + 1]; |
978 | *len = app_info[3] + 4; | 1019 | *len = app_info[3] + 4; |
1020 | out: | ||
1021 | mutex_unlock(&fdtv->avc_mutex); | ||
979 | 1022 | ||
980 | return 0; | 1023 | return ret; |
981 | } | 1024 | } |
982 | 1025 | ||
983 | int avc_ca_reset(struct firedtv *fdtv) | 1026 | int avc_ca_reset(struct firedtv *fdtv) |
984 | { | 1027 | { |
985 | char buffer[sizeof(struct avc_command_frame)]; | 1028 | struct avc_command_frame *c = (void *)fdtv->avc_data; |
986 | struct avc_command_frame *c = (void *)buffer; | 1029 | int ret; |
987 | struct avc_response_frame *r = (void *)buffer; /* FIXME: unused */ | 1030 | |
1031 | if (mutex_lock_interruptible(&fdtv->avc_mutex)) | ||
1032 | return -EINTR; | ||
988 | 1033 | ||
989 | memset(c, 0, sizeof(*c)); | 1034 | memset(c, 0, sizeof(*c)); |
990 | 1035 | ||
@@ -1002,19 +1047,20 @@ int avc_ca_reset(struct firedtv *fdtv) | |||
1002 | c->operand[7] = 1; /* length */ | 1047 | c->operand[7] = 1; /* length */ |
1003 | c->operand[8] = 0; /* force hardware reset */ | 1048 | c->operand[8] = 0; /* force hardware reset */ |
1004 | 1049 | ||
1005 | c->length = 12; | 1050 | fdtv->avc_data_length = 12; |
1051 | ret = avc_write(fdtv); | ||
1006 | 1052 | ||
1007 | if (avc_write(fdtv, c, r) < 0) | 1053 | /* FIXME: check response code? */ |
1008 | return -EIO; | ||
1009 | 1054 | ||
1010 | return 0; | 1055 | mutex_unlock(&fdtv->avc_mutex); |
1056 | |||
1057 | return ret; | ||
1011 | } | 1058 | } |
1012 | 1059 | ||
1013 | int avc_ca_pmt(struct firedtv *fdtv, char *msg, int length) | 1060 | int avc_ca_pmt(struct firedtv *fdtv, char *msg, int length) |
1014 | { | 1061 | { |
1015 | char buffer[sizeof(struct avc_command_frame)]; | 1062 | struct avc_command_frame *c = (void *)fdtv->avc_data; |
1016 | struct avc_command_frame *c = (void *)buffer; | 1063 | struct avc_response_frame *r = (void *)fdtv->avc_data; |
1017 | struct avc_response_frame *r = (void *)buffer; | ||
1018 | int list_management; | 1064 | int list_management; |
1019 | int program_info_length; | 1065 | int program_info_length; |
1020 | int pmt_cmd_id; | 1066 | int pmt_cmd_id; |
@@ -1022,10 +1068,14 @@ int avc_ca_pmt(struct firedtv *fdtv, char *msg, int length) | |||
1022 | int write_pos; | 1068 | int write_pos; |
1023 | int es_info_length; | 1069 | int es_info_length; |
1024 | int crc32_csum; | 1070 | int crc32_csum; |
1071 | int ret; | ||
1025 | 1072 | ||
1026 | if (unlikely(avc_debug & AVC_DEBUG_APPLICATION_PMT)) | 1073 | if (unlikely(avc_debug & AVC_DEBUG_APPLICATION_PMT)) |
1027 | debug_pmt(msg, length); | 1074 | debug_pmt(msg, length); |
1028 | 1075 | ||
1076 | if (mutex_lock_interruptible(&fdtv->avc_mutex)) | ||
1077 | return -EINTR; | ||
1078 | |||
1029 | memset(c, 0, sizeof(*c)); | 1079 | memset(c, 0, sizeof(*c)); |
1030 | 1080 | ||
1031 | c->ctype = AVC_CTYPE_CONTROL; | 1081 | c->ctype = AVC_CTYPE_CONTROL; |
@@ -1124,25 +1174,30 @@ int avc_ca_pmt(struct firedtv *fdtv, char *msg, int length) | |||
1124 | c->operand[write_pos - 2] = (crc32_csum >> 8) & 0xff; | 1174 | c->operand[write_pos - 2] = (crc32_csum >> 8) & 0xff; |
1125 | c->operand[write_pos - 1] = (crc32_csum >> 0) & 0xff; | 1175 | c->operand[write_pos - 1] = (crc32_csum >> 0) & 0xff; |
1126 | 1176 | ||
1127 | c->length = ALIGN(3 + write_pos, 4); | 1177 | fdtv->avc_data_length = ALIGN(3 + write_pos, 4); |
1128 | 1178 | ret = avc_write(fdtv); | |
1129 | if (avc_write(fdtv, c, r) < 0) | 1179 | if (ret < 0) |
1130 | return -EIO; | 1180 | goto out; |
1131 | 1181 | ||
1132 | if (r->response != AVC_RESPONSE_ACCEPTED) { | 1182 | if (r->response != AVC_RESPONSE_ACCEPTED) { |
1133 | dev_err(fdtv->device, | 1183 | dev_err(fdtv->device, |
1134 | "CA PMT failed with response 0x%x\n", r->response); | 1184 | "CA PMT failed with response 0x%x\n", r->response); |
1135 | return -EFAULT; | 1185 | ret = -EFAULT; |
1136 | } | 1186 | } |
1187 | out: | ||
1188 | mutex_unlock(&fdtv->avc_mutex); | ||
1137 | 1189 | ||
1138 | return 0; | 1190 | return ret; |
1139 | } | 1191 | } |
1140 | 1192 | ||
1141 | int avc_ca_get_time_date(struct firedtv *fdtv, int *interval) | 1193 | int avc_ca_get_time_date(struct firedtv *fdtv, int *interval) |
1142 | { | 1194 | { |
1143 | char buffer[sizeof(struct avc_command_frame)]; | 1195 | struct avc_command_frame *c = (void *)fdtv->avc_data; |
1144 | struct avc_command_frame *c = (void *)buffer; | 1196 | struct avc_response_frame *r = (void *)fdtv->avc_data; |
1145 | struct avc_response_frame *r = (void *)buffer; | 1197 | int ret; |
1198 | |||
1199 | if (mutex_lock_interruptible(&fdtv->avc_mutex)) | ||
1200 | return -EINTR; | ||
1146 | 1201 | ||
1147 | memset(c, 0, sizeof(*c)); | 1202 | memset(c, 0, sizeof(*c)); |
1148 | 1203 | ||
@@ -1159,23 +1214,27 @@ int avc_ca_get_time_date(struct firedtv *fdtv, int *interval) | |||
1159 | c->operand[6] = 0; /* more/last */ | 1214 | c->operand[6] = 0; /* more/last */ |
1160 | c->operand[7] = 0; /* length */ | 1215 | c->operand[7] = 0; /* length */ |
1161 | 1216 | ||
1162 | c->length = 12; | 1217 | fdtv->avc_data_length = 12; |
1163 | 1218 | ret = avc_write(fdtv); | |
1164 | if (avc_write(fdtv, c, r) < 0) | 1219 | if (ret < 0) |
1165 | return -EIO; | 1220 | goto out; |
1166 | 1221 | ||
1167 | /* FIXME: check response code and validate response data */ | 1222 | /* FIXME: check response code and validate response data */ |
1168 | 1223 | ||
1169 | *interval = r->operand[get_ca_object_pos(r)]; | 1224 | *interval = r->operand[get_ca_object_pos(r)]; |
1225 | out: | ||
1226 | mutex_unlock(&fdtv->avc_mutex); | ||
1170 | 1227 | ||
1171 | return 0; | 1228 | return ret; |
1172 | } | 1229 | } |
1173 | 1230 | ||
1174 | int avc_ca_enter_menu(struct firedtv *fdtv) | 1231 | int avc_ca_enter_menu(struct firedtv *fdtv) |
1175 | { | 1232 | { |
1176 | char buffer[sizeof(struct avc_command_frame)]; | 1233 | struct avc_command_frame *c = (void *)fdtv->avc_data; |
1177 | struct avc_command_frame *c = (void *)buffer; | 1234 | int ret; |
1178 | struct avc_response_frame *r = (void *)buffer; /* FIXME: unused */ | 1235 | |
1236 | if (mutex_lock_interruptible(&fdtv->avc_mutex)) | ||
1237 | return -EINTR; | ||
1179 | 1238 | ||
1180 | memset(c, 0, sizeof(*c)); | 1239 | memset(c, 0, sizeof(*c)); |
1181 | 1240 | ||
@@ -1192,19 +1251,24 @@ int avc_ca_enter_menu(struct firedtv *fdtv) | |||
1192 | c->operand[6] = 0; /* more/last */ | 1251 | c->operand[6] = 0; /* more/last */ |
1193 | c->operand[7] = 0; /* length */ | 1252 | c->operand[7] = 0; /* length */ |
1194 | 1253 | ||
1195 | c->length = 12; | 1254 | fdtv->avc_data_length = 12; |
1255 | ret = avc_write(fdtv); | ||
1196 | 1256 | ||
1197 | if (avc_write(fdtv, c, r) < 0) | 1257 | /* FIXME: check response code? */ |
1198 | return -EIO; | ||
1199 | 1258 | ||
1200 | return 0; | 1259 | mutex_unlock(&fdtv->avc_mutex); |
1260 | |||
1261 | return ret; | ||
1201 | } | 1262 | } |
1202 | 1263 | ||
1203 | int avc_ca_get_mmi(struct firedtv *fdtv, char *mmi_object, unsigned int *len) | 1264 | int avc_ca_get_mmi(struct firedtv *fdtv, char *mmi_object, unsigned int *len) |
1204 | { | 1265 | { |
1205 | char buffer[sizeof(struct avc_command_frame)]; | 1266 | struct avc_command_frame *c = (void *)fdtv->avc_data; |
1206 | struct avc_command_frame *c = (void *)buffer; | 1267 | struct avc_response_frame *r = (void *)fdtv->avc_data; |
1207 | struct avc_response_frame *r = (void *)buffer; | 1268 | int ret; |
1269 | |||
1270 | if (mutex_lock_interruptible(&fdtv->avc_mutex)) | ||
1271 | return -EINTR; | ||
1208 | 1272 | ||
1209 | memset(c, 0, sizeof(*c)); | 1273 | memset(c, 0, sizeof(*c)); |
1210 | 1274 | ||
@@ -1221,17 +1285,19 @@ int avc_ca_get_mmi(struct firedtv *fdtv, char *mmi_object, unsigned int *len) | |||
1221 | c->operand[6] = 0; /* more/last */ | 1285 | c->operand[6] = 0; /* more/last */ |
1222 | c->operand[7] = 0; /* length */ | 1286 | c->operand[7] = 0; /* length */ |
1223 | 1287 | ||
1224 | c->length = 12; | 1288 | fdtv->avc_data_length = 12; |
1225 | 1289 | ret = avc_write(fdtv); | |
1226 | if (avc_write(fdtv, c, r) < 0) | 1290 | if (ret < 0) |
1227 | return -EIO; | 1291 | goto out; |
1228 | 1292 | ||
1229 | /* FIXME: check response code and validate response data */ | 1293 | /* FIXME: check response code and validate response data */ |
1230 | 1294 | ||
1231 | *len = get_ca_object_length(r); | 1295 | *len = get_ca_object_length(r); |
1232 | memcpy(mmi_object, &r->operand[get_ca_object_pos(r)], *len); | 1296 | memcpy(mmi_object, &r->operand[get_ca_object_pos(r)], *len); |
1297 | out: | ||
1298 | mutex_unlock(&fdtv->avc_mutex); | ||
1233 | 1299 | ||
1234 | return 0; | 1300 | return ret; |
1235 | } | 1301 | } |
1236 | 1302 | ||
1237 | #define CMP_OUTPUT_PLUG_CONTROL_REG_0 0xfffff0000904ULL | 1303 | #define CMP_OUTPUT_PLUG_CONTROL_REG_0 0xfffff0000904ULL |
@@ -1248,6 +1314,7 @@ static int cmp_read(struct firedtv *fdtv, u64 addr, __be32 *data) | |||
1248 | dev_err(fdtv->device, "CMP: read I/O error\n"); | 1314 | dev_err(fdtv->device, "CMP: read I/O error\n"); |
1249 | 1315 | ||
1250 | mutex_unlock(&fdtv->avc_mutex); | 1316 | mutex_unlock(&fdtv->avc_mutex); |
1317 | |||
1251 | return ret; | 1318 | return ret; |
1252 | } | 1319 | } |
1253 | 1320 | ||
@@ -1258,11 +1325,17 @@ static int cmp_lock(struct firedtv *fdtv, u64 addr, __be32 data[]) | |||
1258 | if (mutex_lock_interruptible(&fdtv->avc_mutex)) | 1325 | if (mutex_lock_interruptible(&fdtv->avc_mutex)) |
1259 | return -EINTR; | 1326 | return -EINTR; |
1260 | 1327 | ||
1261 | ret = fdtv->backend->lock(fdtv, addr, data); | 1328 | /* data[] is stack-allocated and should not be DMA-mapped. */ |
1329 | memcpy(fdtv->avc_data, data, 8); | ||
1330 | |||
1331 | ret = fdtv->backend->lock(fdtv, addr, fdtv->avc_data); | ||
1262 | if (ret < 0) | 1332 | if (ret < 0) |
1263 | dev_err(fdtv->device, "CMP: lock I/O error\n"); | 1333 | dev_err(fdtv->device, "CMP: lock I/O error\n"); |
1334 | else | ||
1335 | memcpy(data, fdtv->avc_data, 8); | ||
1264 | 1336 | ||
1265 | mutex_unlock(&fdtv->avc_mutex); | 1337 | mutex_unlock(&fdtv->avc_mutex); |
1338 | |||
1266 | return ret; | 1339 | return ret; |
1267 | } | 1340 | } |
1268 | 1341 | ||
diff --git a/drivers/media/dvb/firewire/firedtv-dvb.c b/drivers/media/dvb/firewire/firedtv-dvb.c index fc9996c13e13..079e8c5b0475 100644 --- a/drivers/media/dvb/firewire/firedtv-dvb.c +++ b/drivers/media/dvb/firewire/firedtv-dvb.c | |||
@@ -277,7 +277,6 @@ struct firedtv *fdtv_alloc(struct device *dev, | |||
277 | 277 | ||
278 | mutex_init(&fdtv->avc_mutex); | 278 | mutex_init(&fdtv->avc_mutex); |
279 | init_waitqueue_head(&fdtv->avc_wait); | 279 | init_waitqueue_head(&fdtv->avc_wait); |
280 | fdtv->avc_reply_received = true; | ||
281 | mutex_init(&fdtv->demux_mutex); | 280 | mutex_init(&fdtv->demux_mutex); |
282 | INIT_WORK(&fdtv->remote_ctrl_work, avc_remote_ctrl_work); | 281 | INIT_WORK(&fdtv->remote_ctrl_work, avc_remote_ctrl_work); |
283 | 282 | ||
diff --git a/drivers/media/dvb/firewire/firedtv-fw.c b/drivers/media/dvb/firewire/firedtv-fw.c index 6223bf01efe9..7a3de16fba06 100644 --- a/drivers/media/dvb/firewire/firedtv-fw.c +++ b/drivers/media/dvb/firewire/firedtv-fw.c | |||
@@ -41,7 +41,7 @@ static int node_req(struct firedtv *fdtv, u64 addr, void *data, size_t len, | |||
41 | return rcode != RCODE_COMPLETE ? -EIO : 0; | 41 | return rcode != RCODE_COMPLETE ? -EIO : 0; |
42 | } | 42 | } |
43 | 43 | ||
44 | static int node_lock(struct firedtv *fdtv, u64 addr, __be32 data[]) | 44 | static int node_lock(struct firedtv *fdtv, u64 addr, void *data) |
45 | { | 45 | { |
46 | return node_req(fdtv, addr, data, 8, TCODE_LOCK_COMPARE_SWAP); | 46 | return node_req(fdtv, addr, data, 8, TCODE_LOCK_COMPARE_SWAP); |
47 | } | 47 | } |
diff --git a/drivers/media/dvb/firewire/firedtv.h b/drivers/media/dvb/firewire/firedtv.h index 35080dbb3c66..78cc28f36914 100644 --- a/drivers/media/dvb/firewire/firedtv.h +++ b/drivers/media/dvb/firewire/firedtv.h | |||
@@ -73,7 +73,7 @@ struct input_dev; | |||
73 | struct firedtv; | 73 | struct firedtv; |
74 | 74 | ||
75 | struct firedtv_backend { | 75 | struct firedtv_backend { |
76 | int (*lock)(struct firedtv *fdtv, u64 addr, __be32 data[]); | 76 | int (*lock)(struct firedtv *fdtv, u64 addr, void *data); |
77 | int (*read)(struct firedtv *fdtv, u64 addr, void *data); | 77 | int (*read)(struct firedtv *fdtv, u64 addr, void *data); |
78 | int (*write)(struct firedtv *fdtv, u64 addr, void *data, size_t len); | 78 | int (*write)(struct firedtv *fdtv, u64 addr, void *data, size_t len); |
79 | int (*start_iso)(struct firedtv *fdtv); | 79 | int (*start_iso)(struct firedtv *fdtv); |
@@ -114,8 +114,8 @@ struct firedtv { | |||
114 | unsigned long channel_active; | 114 | unsigned long channel_active; |
115 | u16 channel_pid[16]; | 115 | u16 channel_pid[16]; |
116 | 116 | ||
117 | size_t response_length; | 117 | int avc_data_length; |
118 | u8 response[512]; | 118 | u8 avc_data[512]; |
119 | }; | 119 | }; |
120 | 120 | ||
121 | /* firedtv-1394.c */ | 121 | /* firedtv-1394.c */ |