comparison driver/pt1_pci.c @ 120:3914cc1b2375

- adapted to 3.x kernels - replaced lock/unlock_kernel with mutex - enlarged read size - changed the order in clean up so that the module no longer hangs on being removed - changed channel step of bs17 as the upstream - adopted some useful patches
author Yoshiki Yazawa <yaz@honeyplanet.jp>
date Fri, 06 Jan 2012 17:32:36 +0900
parents 7662d0ecd74b
children f2ae5ddeed7e
comparison
equal deleted inserted replaced
119:7662d0ecd74b 120:3914cc1b2375
31 31
32 #include <linux/fs.h> 32 #include <linux/fs.h>
33 #include <linux/cdev.h> 33 #include <linux/cdev.h>
34 34
35 #include <linux/ioctl.h> 35 #include <linux/ioctl.h>
36 #include <linux/smp_lock.h>
37 36
38 #include "pt1_com.h" 37 #include "pt1_com.h"
39 #include "pt1_pci.h" 38 #include "pt1_pci.h"
40 #include "pt1_tuner.h" 39 #include "pt1_tuner.h"
41 #include "pt1_i2c.h" 40 #include "pt1_i2c.h"
77 #define DMA_SIZE 4096 // DMAバッファサイズ 76 #define DMA_SIZE 4096 // DMAバッファサイズ
78 #define DMA_RING_SIZE 128 // RINGサイズ 77 #define DMA_RING_SIZE 128 // RINGサイズ
79 #define DMA_RING_MAX 511 // 1RINGにいくつ詰めるか(1023はNGで511まで) 78 #define DMA_RING_MAX 511 // 1RINGにいくつ詰めるか(1023はNGで511まで)
80 #define CHANEL_DMA_SIZE (2*1024*1024) // 地デジ用(16Mbps) 79 #define CHANEL_DMA_SIZE (2*1024*1024) // 地デジ用(16Mbps)
81 #define BS_CHANEL_DMA_SIZE (4*1024*1024) // BS用(32Mbps) 80 #define BS_CHANEL_DMA_SIZE (4*1024*1024) // BS用(32Mbps)
81 #define READ_SIZE (16*DMA_SIZE)
82 82
83 typedef struct _DMA_CONTROL{ 83 typedef struct _DMA_CONTROL{
84 dma_addr_t ring_dma[DMA_RING_MAX] ; // DMA情報 84 dma_addr_t ring_dma[DMA_RING_MAX] ; // DMA情報
85 __u32 *data[DMA_RING_MAX]; 85 __u32 *data[DMA_RING_MAX];
86 }DMA_CONTROL; 86 }DMA_CONTROL;
305 if(ring_pos >= DMA_RING_SIZE){ 305 if(ring_pos >= DMA_RING_SIZE){
306 ring_pos = 0 ; 306 ring_pos = 0 ;
307 } 307 }
308 } 308 }
309 309
310 // 頻度を落す(4Kで起動させる) 310 // 頻度を落す(wait until READ_SIZE)
311 for(lp = 0 ; lp < MAX_CHANNEL ; lp++){ 311 for(lp = 0 ; lp < MAX_CHANNEL ; lp++){
312 channel = dev_conf->channel[real_channel[lp]] ; 312 channel = dev_conf->channel[real_channel[lp]] ;
313 if((channel->size >= DMA_SIZE) && (channel->valid == TRUE)){ 313 if((channel->size >= READ_SIZE) && (channel->valid == TRUE)){
314 wake_up(&channel->wait_q); 314 wake_up(&channel->wait_q);
315 } 315 }
316 } 316 }
317 } 317 }
318 schedule_timeout_interruptible(msecs_to_jiffies(1)); 318 schedule_timeout_interruptible(msecs_to_jiffies(10));
319 } 319 }
320 return 0 ; 320 return 0 ;
321 } 321 }
322 static int pt1_open(struct inode *inode, struct file *file) 322 static int pt1_open(struct inode *inode, struct file *file)
323 { 323 {
402 { 402 {
403 PT1_CHANNEL *channel = file->private_data; 403 PT1_CHANNEL *channel = file->private_data;
404 __u32 size ; 404 __u32 size ;
405 unsigned long dummy; 405 unsigned long dummy;
406 406
407 // 4K単位で起こされるのを待つ(CPU負荷対策) 407 // READ_SIZE単位で起こされるのを待つ(CPU負荷対策)
408 if(channel->size < DMA_SIZE){ 408 if(channel->size < READ_SIZE){
409 wait_event_timeout(channel->wait_q, (channel->size >= DMA_SIZE), 409 wait_event_timeout(channel->wait_q, (channel->size >= READ_SIZE),
410 msecs_to_jiffies(500)); 410 msecs_to_jiffies(500));
411 } 411 }
412 mutex_lock(&channel->lock); 412 mutex_lock(&channel->lock);
413 if(!channel->size){ 413 if(!channel->size){
414 size = 0 ; 414 size = 0 ;
532 case START_REC: 532 case START_REC:
533 SetStream(channel->ptr->regs, channel->channel, TRUE); 533 SetStream(channel->ptr->regs, channel->channel, TRUE);
534 return 0 ; 534 return 0 ;
535 case STOP_REC: 535 case STOP_REC:
536 SetStream(channel->ptr->regs, channel->channel, FALSE); 536 SetStream(channel->ptr->regs, channel->channel, FALSE);
537 schedule_timeout_interruptible(msecs_to_jiffies(100));
537 return 0 ; 538 return 0 ;
538 case GET_SIGNAL_STRENGTH: 539 case GET_SIGNAL_STRENGTH:
539 switch(channel->type){ 540 switch(channel->type){
540 case CHANNEL_TYPE_ISDB_S: 541 case CHANNEL_TYPE_ISDB_S:
541 signal = isdb_s_read_signal_strength(channel->ptr->regs, 542 signal = isdb_s_read_signal_strength(channel->ptr->regs,
569 return -EINVAL; 570 return -EINVAL;
570 } 571 }
571 572
572 static long pt1_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg0) 573 static long pt1_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg0)
573 { 574 {
575 PT1_CHANNEL *channel = file->private_data;
574 long ret; 576 long ret;
575 577
576 lock_kernel(); 578 mutex_lock(&channel->lock);
577 ret = pt1_do_ioctl(file, cmd, arg0); 579 ret = pt1_do_ioctl(file, cmd, arg0);
578 unlock_kernel(); 580 mutex_unlock(&channel->lock);
579 581
580 return ret; 582 return ret;
581 } 583 }
582 584
583 static long pt1_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg0) 585 static long pt1_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg0)
605 .open = pt1_open, 607 .open = pt1_open,
606 .release = pt1_release, 608 .release = pt1_release,
607 .read = pt1_read, 609 .read = pt1_read,
608 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36) 610 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36)
609 .ioctl = pt1_ioctl, 611 .ioctl = pt1_ioctl,
610 #endif 612 #else
611 .unlocked_ioctl = pt1_unlocked_ioctl, 613 .unlocked_ioctl = pt1_unlocked_ioctl,
612 .compat_ioctl = pt1_compat_ioctl, 614 .compat_ioctl = pt1_compat_ioctl,
615 #endif
613 .llseek = no_llseek, 616 .llseek = no_llseek,
614 }; 617 };
615 618
616 int pt1_makering(struct pci_dev *pdev, PT1_DEVICE *dev_conf) 619 int pt1_makering(struct pci_dev *pdev, PT1_DEVICE *dev_conf)
617 { 620 {
1002 } 1005 }
1003 1006
1004 1007
1005 static void __exit pt1_pci_cleanup(void) 1008 static void __exit pt1_pci_cleanup(void)
1006 { 1009 {
1010 pci_unregister_driver(&pt1_driver);
1007 class_destroy(pt1video_class); 1011 class_destroy(pt1video_class);
1008 pci_unregister_driver(&pt1_driver);
1009 } 1012 }
1010 1013
1011 module_init(pt1_pci_init); 1014 module_init(pt1_pci_init);
1012 module_exit(pt1_pci_cleanup); 1015 module_exit(pt1_pci_cleanup);