aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/dvb/firewire/firedtv-1394.c9
-rw-r--r--drivers/media/dvb/firewire/firedtv-avc.c437
-rw-r--r--drivers/media/dvb/firewire/firedtv-dvb.c1
-rw-r--r--drivers/media/dvb/firewire/firedtv-fw.c2
-rw-r--r--drivers/media/dvb/firewire/firedtv.h6
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
93static int node_lock(struct firedtv *fdtv, u64 addr, __be32 data[]) 93static 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
76struct avc_command_frame { 76struct 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
84struct avc_response_frame { 83struct 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
205static int __avc_write(struct firedtv *fdtv, 203static 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
245static int avc_write(struct firedtv *fdtv, 235static 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
259int avc_recv(struct firedtv *fdtv, void *data, size_t length) 244int 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 275wake:
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 */
321static void avc_tuner_tuneqpsk(struct firedtv *fdtv, 306static 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
379static void avc_tuner_dsd_dvb_c(struct firedtv *fdtv, 365static 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
447static void avc_tuner_dsd_dvb_t(struct firedtv *fdtv, 435static 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 = &params->u.ofdm; 438 struct dvb_ofdm_parameters *ofdm = &params->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
550int avc_tuner_dsd(struct firedtv *fdtv, 539int 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
584int avc_tuner_set_pids(struct firedtv *fdtv, unsigned char pidc, u16 pid[]) 579int 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
627int avc_tuner_get_ts(struct firedtv *fdtv) 627int 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
662int avc_identify_subunit(struct firedtv *fdtv) 667int 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; 701out:
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
698int avc_tuner_status(struct firedtv *fdtv, struct firedtv_tuner_status *stat) 709int 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;
784out:
785 mutex_unlock(&fdtv->avc_mutex);
769 786
770 return 0; 787 return ret;
771} 788}
772 789
773int avc_lnb_control(struct firedtv *fdtv, char voltage, char burst, 790int 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 }
836out:
837 mutex_unlock(&fdtv->avc_mutex);
817 838
818 return 0; 839 return ret;
819} 840}
820 841
821int avc_register_remote_control(struct firedtv *fdtv) 842int 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
842void avc_remote_ctrl_work(struct work_struct *work) 871void 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 */
852int avc_tuner_host2ca(struct firedtv *fdtv) 881int 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
907int avc_ca_app_info(struct firedtv *fdtv, char *app_info, unsigned int *len) 940int 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;
977out:
978 mutex_unlock(&fdtv->avc_mutex);
942 979
943 return 0; 980 return ret;
944} 981}
945 982
946int avc_ca_info(struct firedtv *fdtv, char *app_info, unsigned int *len) 983int 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;
1020out:
1021 mutex_unlock(&fdtv->avc_mutex);
979 1022
980 return 0; 1023 return ret;
981} 1024}
982 1025
983int avc_ca_reset(struct firedtv *fdtv) 1026int 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
1013int avc_ca_pmt(struct firedtv *fdtv, char *msg, int length) 1060int 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 }
1187out:
1188 mutex_unlock(&fdtv->avc_mutex);
1137 1189
1138 return 0; 1190 return ret;
1139} 1191}
1140 1192
1141int avc_ca_get_time_date(struct firedtv *fdtv, int *interval) 1193int 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)];
1225out:
1226 mutex_unlock(&fdtv->avc_mutex);
1170 1227
1171 return 0; 1228 return ret;
1172} 1229}
1173 1230
1174int avc_ca_enter_menu(struct firedtv *fdtv) 1231int 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
1203int avc_ca_get_mmi(struct firedtv *fdtv, char *mmi_object, unsigned int *len) 1264int 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);
1297out:
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
44static int node_lock(struct firedtv *fdtv, u64 addr, __be32 data[]) 44static 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;
73struct firedtv; 73struct firedtv;
74 74
75struct firedtv_backend { 75struct 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 */