X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fmedia%2Fdvb%2Fttusb-dec%2Fttusb_dec.c;h=44dea32118483e9dbf14868dd927b84fdfad7ea1;hb=9464c7cf61b9433057924c36e6e02f303a00e768;hp=505bdaff5a7eea16ff148ba87d9f74d7ea93043b;hpb=cace1c4618b6c6442b7dc973e935e7f3268e4aa7;p=linux-2.6.git diff --git a/drivers/media/dvb/ttusb-dec/ttusb_dec.c b/drivers/media/dvb/ttusb-dec/ttusb_dec.c index 505bdaff5..44dea3211 100644 --- a/drivers/media/dvb/ttusb-dec/ttusb_dec.c +++ b/drivers/media/dvb/ttusb-dec/ttusb_dec.c @@ -20,7 +20,8 @@ * */ -#include +#include + #include #include #include @@ -28,7 +29,6 @@ #include #include #include -#include #include #include #include @@ -116,7 +116,7 @@ struct ttusb_dec { unsigned int out_pipe; unsigned int irq_pipe; enum ttusb_dec_interface interface; - struct semaphore usb_sem; + struct mutex usb_mutex; void *irq_buffer; struct urb *irq_urb; @@ -125,7 +125,7 @@ struct ttusb_dec { dma_addr_t iso_dma_handle; struct urb *iso_urb[ISO_BUF_COUNT]; int iso_stream_count; - struct semaphore iso_sem; + struct mutex iso_mutex; u8 packet[MAX_PVA_LENGTH + 4]; enum ttusb_dec_packet_type packet_type; @@ -153,7 +153,8 @@ struct ttusb_dec { struct list_head filter_info_list; spinlock_t filter_info_list_lock; - struct input_dev rc_input_dev; + struct input_dev *rc_input_dev; + char rc_phys[64]; int active; /* Loaded successfully */ }; @@ -236,9 +237,9 @@ static void ttusb_dec_handle_irq( struct urb *urb, struct pt_regs *regs) * this should/could be added later ... * for now lets report each signal as a key down and up*/ dprintk("%s:rc signal:%d\n", __FUNCTION__, buffer[4]); - input_report_key(&dec->rc_input_dev,rc_keys[buffer[4]-1],1); - input_report_key(&dec->rc_input_dev,rc_keys[buffer[4]-1],0); - input_sync(&dec->rc_input_dev); + input_report_key(dec->rc_input_dev, rc_keys[buffer[4] - 1], 1); + input_report_key(dec->rc_input_dev, rc_keys[buffer[4] - 1], 0); + input_sync(dec->rc_input_dev); } exit: retval = usb_submit_urb(urb, GFP_ATOMIC); @@ -273,9 +274,9 @@ static int ttusb_dec_send_command(struct ttusb_dec *dec, const u8 command, if (!b) return -ENOMEM; - if ((result = down_interruptible(&dec->usb_sem))) { + if ((result = mutex_lock_interruptible(&dec->usb_mutex))) { kfree(b); - printk("%s: Failed to down usb semaphore.\n", __FUNCTION__); + printk("%s: Failed to lock usb mutex.\n", __FUNCTION__); return result; } @@ -300,7 +301,7 @@ static int ttusb_dec_send_command(struct ttusb_dec *dec, const u8 command, if (result) { printk("%s: command bulk message failed: error %d\n", __FUNCTION__, result); - up(&dec->usb_sem); + mutex_unlock(&dec->usb_mutex); kfree(b); return result; } @@ -311,7 +312,7 @@ static int ttusb_dec_send_command(struct ttusb_dec *dec, const u8 command, if (result) { printk("%s: result bulk message failed: error %d\n", __FUNCTION__, result); - up(&dec->usb_sem); + mutex_unlock(&dec->usb_mutex); kfree(b); return result; } else { @@ -327,7 +328,7 @@ static int ttusb_dec_send_command(struct ttusb_dec *dec, const u8 command, if (cmd_result && b[3] > 0) memcpy(cmd_result, &b[4], b[3]); - up(&dec->usb_sem); + mutex_unlock(&dec->usb_mutex); kfree(b); return 0; @@ -369,7 +370,7 @@ static int ttusb_dec_get_stb_state (struct ttusb_dec *dec, unsigned int *mode, static int ttusb_dec_audio_pes2ts_cb(void *priv, unsigned char *data) { - struct ttusb_dec *dec = (struct ttusb_dec *)priv; + struct ttusb_dec *dec = priv; dec->audio_filter->feed->cb.ts(data, 188, NULL, 0, &dec->audio_filter->feed->feed.ts, @@ -380,7 +381,7 @@ static int ttusb_dec_audio_pes2ts_cb(void *priv, unsigned char *data) static int ttusb_dec_video_pes2ts_cb(void *priv, unsigned char *data) { - struct ttusb_dec *dec = (struct ttusb_dec *)priv; + struct ttusb_dec *dec = priv; dec->video_filter->feed->cb.ts(data, 188, NULL, 0, &dec->video_filter->feed->feed.ts, @@ -835,7 +836,7 @@ static void ttusb_dec_stop_iso_xfer(struct ttusb_dec *dec) dprintk("%s\n", __FUNCTION__); - if (down_interruptible(&dec->iso_sem)) + if (mutex_lock_interruptible(&dec->iso_mutex)) return; dec->iso_stream_count--; @@ -845,7 +846,7 @@ static void ttusb_dec_stop_iso_xfer(struct ttusb_dec *dec) usb_kill_urb(dec->iso_urb[i]); } - up(&dec->iso_sem); + mutex_unlock(&dec->iso_mutex); } /* Setting the interface of the DEC tends to take down the USB communications @@ -890,7 +891,7 @@ static int ttusb_dec_start_iso_xfer(struct ttusb_dec *dec) dprintk("%s\n", __FUNCTION__); - if (down_interruptible(&dec->iso_sem)) + if (mutex_lock_interruptible(&dec->iso_mutex)) return -EAGAIN; if (!dec->iso_stream_count) { @@ -911,7 +912,7 @@ static int ttusb_dec_start_iso_xfer(struct ttusb_dec *dec) i--; } - up(&dec->iso_sem); + mutex_unlock(&dec->iso_mutex); return result; } } @@ -919,7 +920,7 @@ static int ttusb_dec_start_iso_xfer(struct ttusb_dec *dec) dec->iso_stream_count++; - up(&dec->iso_sem); + mutex_unlock(&dec->iso_mutex); return 0; } @@ -965,8 +966,8 @@ static int ttusb_dec_start_ts_feed(struct dvb_demux_feed *dvbdmxfeed) case DMX_TS_PES_TELETEXT: dec->pid[DMX_PES_TELETEXT] = dvbdmxfeed->pid; - dprintk(" pes_type: DMX_TS_PES_TELETEXT\n"); - break; + dprintk(" pes_type: DMX_TS_PES_TELETEXT(not supported)\n"); + return -ENOSYS; case DMX_TS_PES_PCR: dprintk(" pes_type: DMX_TS_PES_PCR\n"); @@ -975,8 +976,8 @@ static int ttusb_dec_start_ts_feed(struct dvb_demux_feed *dvbdmxfeed) break; case DMX_TS_PES_OTHER: - dprintk(" pes_type: DMX_TS_PES_OTHER\n"); - break; + dprintk(" pes_type: DMX_TS_PES_OTHER(not supported)\n"); + return -ENOSYS; default: dprintk(" pes_type: unknown (%d)\n", dvbdmxfeed->pes_type); @@ -1182,29 +1183,37 @@ static void ttusb_dec_init_tasklet(struct ttusb_dec *dec) (unsigned long)dec); } -static void ttusb_init_rc( struct ttusb_dec *dec) +static int ttusb_init_rc( struct ttusb_dec *dec) { + struct input_dev *input_dev; u8 b[] = { 0x00, 0x01 }; int i; - init_input_dev(&dec->rc_input_dev); + usb_make_path(dec->udev, dec->rc_phys, sizeof(dec->rc_phys)); + strlcpy(dec->rc_phys, "/input0", sizeof(dec->rc_phys)); - dec->rc_input_dev.name = "ttusb_dec remote control"; - dec->rc_input_dev.evbit[0] = BIT(EV_KEY); - dec->rc_input_dev.keycodesize = sizeof(u16); - dec->rc_input_dev.keycodemax = 0x1a; - dec->rc_input_dev.keycode = rc_keys; + dec->rc_input_dev = input_dev = input_allocate_device(); + if (!input_dev) + return -ENOMEM; - for (i = 0; i < sizeof(rc_keys)/sizeof(rc_keys[0]); i++) - set_bit(rc_keys[i], dec->rc_input_dev.keybit); + input_dev->name = "ttusb_dec remote control"; + input_dev->phys = dec->rc_phys; + input_dev->evbit[0] = BIT(EV_KEY); + input_dev->keycodesize = sizeof(u16); + input_dev->keycodemax = 0x1a; + input_dev->keycode = rc_keys; - input_register_device(&dec->rc_input_dev); + for (i = 0; i < ARRAY_SIZE(rc_keys); i++) + set_bit(rc_keys[i], input_dev->keybit); - if(usb_submit_urb(dec->irq_urb,GFP_KERNEL)) { + input_register_device(input_dev); + + if (usb_submit_urb(dec->irq_urb, GFP_KERNEL)) printk("%s: usb_submit_urb failed\n",__FUNCTION__); - } /* enable irq pipe */ ttusb_dec_send_command(dec,0xb0,sizeof(b),b,NULL,NULL); + + return 0; } static void ttusb_dec_init_v_pes(struct ttusb_dec *dec) @@ -1221,8 +1230,8 @@ static int ttusb_dec_init_usb(struct ttusb_dec *dec) { dprintk("%s\n", __FUNCTION__); - sema_init(&dec->usb_sem, 1); - sema_init(&dec->iso_sem, 1); + mutex_init(&dec->usb_mutex); + mutex_init(&dec->iso_mutex); dec->command_pipe = usb_sndbulkpipe(dec->udev, COMMAND_PIPE); dec->result_pipe = usb_rcvbulkpipe(dec->udev, RESULT_PIPE); @@ -1281,6 +1290,7 @@ static int ttusb_dec_boot_dsp(struct ttusb_dec *dec) if (firmware_size < 60) { printk("%s: firmware size too small for DSP code (%zu < 60).\n", __FUNCTION__, firmware_size); + release_firmware(fw_entry); return -1; } @@ -1294,6 +1304,7 @@ static int ttusb_dec_boot_dsp(struct ttusb_dec *dec) printk("%s: crc32 check of DSP code failed (calculated " "0x%08x != 0x%08x in file), file invalid.\n", __FUNCTION__, crc32_csum, crc32_check); + release_firmware(fw_entry); return -1; } memcpy(idstring, &firmware[36], 20); @@ -1308,15 +1319,19 @@ static int ttusb_dec_boot_dsp(struct ttusb_dec *dec) result = ttusb_dec_send_command(dec, 0x41, sizeof(b0), b0, NULL, NULL); - if (result) + if (result) { + release_firmware(fw_entry); return result; + } trans_count = 0; j = 0; b = kmalloc(ARM_PACKET_SIZE, GFP_KERNEL); - if (b == NULL) + if (b == NULL) { + release_firmware(fw_entry); return -ENOMEM; + } for (i = 0; i < firmware_size; i += COMMAND_PACKET_SIZE) { size = firmware_size - i; @@ -1345,6 +1360,7 @@ static int ttusb_dec_boot_dsp(struct ttusb_dec *dec) result = ttusb_dec_send_command(dec, 0x43, sizeof(b1), b1, NULL, NULL); + release_firmware(fw_entry); kfree(b); return result; @@ -1379,6 +1395,7 @@ static int ttusb_dec_init_stb(struct ttusb_dec *dec) /* We can't trust the USB IDs that some firmwares give the box */ switch (model) { + case 0x00070001: case 0x00070008: case 0x0007000c: ttusb_dec_set_model(dec, TTUSB_DEC3000S); @@ -1507,15 +1524,18 @@ static void ttusb_dec_exit_rc(struct ttusb_dec *dec) * As the irq is submitted after the interface is changed, * this is the best method i figured out. * Any others?*/ - if(dec->interface == TTUSB_DEC_INTERFACE_IN) + if (dec->interface == TTUSB_DEC_INTERFACE_IN) usb_kill_urb(dec->irq_urb); usb_free_urb(dec->irq_urb); usb_buffer_free(dec->udev,IRQ_PACKET_SIZE, - dec->irq_buffer, dec->irq_dma_handle); + dec->irq_buffer, dec->irq_dma_handle); - input_unregister_device(&dec->rc_input_dev); + if (dec->rc_input_dev) { + input_unregister_device(dec->rc_input_dev); + dec->rc_input_dev = NULL; + } } @@ -1569,7 +1589,7 @@ static int fe_send_command(struct dvb_frontend* fe, const u8 command, int param_length, const u8 params[], int *result_length, u8 cmd_result[]) { - struct ttusb_dec* dec = (struct ttusb_dec*) fe->dvb->priv; + struct ttusb_dec* dec = fe->dvb->priv; return ttusb_dec_send_command(dec, command, param_length, params, result_length, cmd_result); } @@ -1587,15 +1607,13 @@ static int ttusb_dec_probe(struct usb_interface *intf, udev = interface_to_usbdev(intf); - if (!(dec = kmalloc(sizeof(struct ttusb_dec), GFP_KERNEL))) { + if (!(dec = kzalloc(sizeof(struct ttusb_dec), GFP_KERNEL))) { printk("%s: couldn't allocate memory.\n", __FUNCTION__); return -ENOMEM; } usb_set_intfdata(intf, (void *)dec); - memset(dec, 0, sizeof(struct ttusb_dec)); - switch (le16_to_cpu(id->idProduct)) { case 0x1006: ttusb_dec_set_model(dec, TTUSB_DEC3000S); @@ -1653,7 +1671,7 @@ static int ttusb_dec_probe(struct usb_interface *intf, ttusb_dec_set_interface(dec, TTUSB_DEC_INTERFACE_IN); - if(enable_rc) + if (enable_rc) ttusb_init_rc(dec); return 0;