comparison driver/pt1_pci.c @ 31:289794dc265f

adapted to use of multiple number of pt1: - now pt1_open() checks major number. - passes unique device name to device_create(). - handles device[] bit carefully.
author Yoshiki Yazawa <yaz@honeyplanet.jp>
date Tue, 03 Mar 2009 05:15:40 +0900
parents eb694d8e4c7e
children 65c8ac567074
comparison
equal deleted inserted replaced
30:eb694d8e4c7e 31:289794dc265f
49 MODULE_AUTHOR("Tomoaki Ishikawa tomy@users.sourceforge.jp"); 49 MODULE_AUTHOR("Tomoaki Ishikawa tomy@users.sourceforge.jp");
50 #define DRIVER_DESC "PCI earthsoft PT1 driver" 50 #define DRIVER_DESC "PCI earthsoft PT1 driver"
51 MODULE_DESCRIPTION(DRIVER_DESC); 51 MODULE_DESCRIPTION(DRIVER_DESC);
52 MODULE_LICENSE("GPL"); 52 MODULE_LICENSE("GPL");
53 53
54 static int debug = 1; /* 1 normal messages, 0 quiet .. 7 verbose. */ 54 static int debug = 7; /* 1 normal messages, 0 quiet .. 7 verbose. */
55 static int lnb = 0; /* LNB OFF:0 +11V:1 +15V:2 */ 55 static int lnb = 0; /* LNB OFF:0 +11V:1 +15V:2 */
56 56
57 module_param(debug, int, 0); 57 module_param(debug, int, 0);
58 module_param(lnb, int, 0); 58 module_param(lnb, int, 0);
59 MODULE_PARM_DESC(debug, "debug level (1-2)"); 59 MODULE_PARM_DESC(debug, "debug level (1-2)");
95 struct mutex lock ; 95 struct mutex lock ;
96 dma_addr_t ring_dma[DMA_RING_SIZE] ; // DMA¾ðÊó 96 dma_addr_t ring_dma[DMA_RING_SIZE] ; // DMA¾ðÊó
97 void *dmaptr[DMA_RING_SIZE] ; 97 void *dmaptr[DMA_RING_SIZE] ;
98 struct task_struct *kthread; 98 struct task_struct *kthread;
99 dev_t dev ; 99 dev_t dev ;
100 int card_number;
100 __u32 base_minor ; 101 __u32 base_minor ;
101 struct cdev cdev[MAX_CHANNEL]; 102 struct cdev cdev[MAX_CHANNEL];
102 wait_queue_head_t dma_wait_q ;// for poll on reading 103 wait_queue_head_t dma_wait_q ;// for poll on reading
103 DMA_CONTROL dmactl[DMA_RING_SIZE]; 104 DMA_CONTROL dmactl[DMA_RING_SIZE];
104 PT1_CHANNEL *channel[MAX_CHANNEL]; 105 PT1_CHANNEL *channel[MAX_CHANNEL];
282 return 0 ; 283 return 0 ;
283 } 284 }
284 static int pt1_open(struct inode *inode, struct file *file) 285 static int pt1_open(struct inode *inode, struct file *file)
285 { 286 {
286 287
288 int major = imajor(inode);
287 int minor = iminor(inode); 289 int minor = iminor(inode);
288 int lp ; 290 int lp ;
289 int lp2 ; 291 int lp2 ;
290 PT1_CHANNEL *channel ; 292 PT1_CHANNEL *channel ;
291 293
292 for(lp = 0 ; lp < MAX_PCI_DEVICE ; lp++){ 294 for(lp = 0 ; lp < MAX_PCI_DEVICE ; lp++){
293 if(device[lp] == NULL){ 295 if(device[lp] == NULL){
294 return -EIO ; 296 return -EIO ;
295 } 297 }
296 if((device[lp]->base_minor <= minor) && 298
297 ((device[lp]->base_minor + MAX_CHANNEL) > minor)){ 299 if(MAJOR(device[lp]->dev) == major &&
300 device[lp]->base_minor <= minor &&
301 device[lp]->base_minor + MAX_CHANNEL > minor) {
302
298 mutex_lock(&device[lp]->lock); 303 mutex_lock(&device[lp]->lock);
299 for(lp2 = 0 ; lp2 < MAX_CHANNEL ; lp2++){ 304 for(lp2 = 0 ; lp2 < MAX_CHANNEL ; lp2++){
300 channel = device[lp]->channel[lp2] ; 305 channel = device[lp]->channel[lp2] ;
301 if(channel->minor == minor){ 306 if(channel->minor == minor){
302 if(channel->valid == TRUE){ 307 if(channel->valid == TRUE){
327 PT1_CHANNEL *channel = file->private_data; 332 PT1_CHANNEL *channel = file->private_data;
328 333
329 mutex_lock(&channel->ptr->lock); 334 mutex_lock(&channel->ptr->lock);
330 SetStream(channel->ptr->regs, channel->channel, FALSE); 335 SetStream(channel->ptr->regs, channel->channel, FALSE);
331 channel->valid = FALSE ; 336 channel->valid = FALSE ;
332 printk(KERN_INFO "(%d)Drop=%08d:%08d:%08d:%08d\n", iminor(inode), channel->drop, 337 printk(KERN_INFO "(%d:%d)Drop=%08d:%08d:%08d:%08d\n", imajor(inode), iminor(inode), channel->drop,
333 channel->overflow, channel->counetererr, channel->transerr); 338 channel->overflow, channel->counetererr, channel->transerr);
334 channel->overflow = 0 ; 339 channel->overflow = 0 ;
335 channel->counetererr = 0 ; 340 channel->counetererr = 0 ;
336 channel->transerr = 0 ; 341 channel->transerr = 0 ;
337 channel->drop = 0 ; 342 channel->drop = 0 ;
651 init_waitqueue_head(&dev_conf->dma_wait_q); 656 init_waitqueue_head(&dev_conf->dma_wait_q);
652 657
653 minor = MINOR(dev_conf->dev) ; 658 minor = MINOR(dev_conf->dev) ;
654 dev_conf->base_minor = minor ; 659 dev_conf->base_minor = minor ;
655 for(lp = 0 ; lp < MAX_PCI_DEVICE ; lp++){ 660 for(lp = 0 ; lp < MAX_PCI_DEVICE ; lp++){
661 printk(KERN_INFO "PT1: device[%d]=%p\n", lp, device[lp]);
656 if(device[lp] == NULL){ 662 if(device[lp] == NULL){
657 device[lp] = dev_conf ; 663 device[lp] = dev_conf ;
664 dev_conf->card_number = lp;
658 break ; 665 break ;
659 } 666 }
660 } 667 }
661 for(lp = 0 ; lp < MAX_CHANNEL ; lp++){ 668 for(lp = 0 ; lp < MAX_CHANNEL ; lp++){
662 cdev_init(&dev_conf->cdev[lp], &pt1_fops); 669 cdev_init(&dev_conf->cdev[lp], &pt1_fops);
663 dev_conf->cdev[lp].owner = THIS_MODULE; 670 dev_conf->cdev[lp].owner = THIS_MODULE;
664 cdev_add(&dev_conf->cdev[lp], MKDEV(MAJOR(dev_conf->dev), (MINOR(dev_conf->dev) + lp)), 1); 671 cdev_add(&dev_conf->cdev[lp],
672 MKDEV(MAJOR(dev_conf->dev), (MINOR(dev_conf->dev) + lp)), 1);
665 channel = kzalloc(sizeof(PT1_CHANNEL), GFP_KERNEL); 673 channel = kzalloc(sizeof(PT1_CHANNEL), GFP_KERNEL);
666 if(!channel){ 674 if(!channel){
667 printk(KERN_ERR "PT1:out of memory !"); 675 printk(KERN_ERR "PT1:out of memory !");
668 return -ENOMEM ; 676 return -ENOMEM ;
669 } 677 }
697 } 705 }
698 if(channel->buf == NULL){ 706 if(channel->buf == NULL){
699 goto out_err_v4l; 707 goto out_err_v4l;
700 } 708 }
701 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) 709 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
702 device_create(pt1video_class, NULL, MKDEV(MAJOR(dev_conf->dev), 710 printk(KERN_INFO "PT1: card_number = %d\n",
703 (MINOR(dev_conf->dev) + lp)), NULL, 711 dev_conf->card_number);
704 "pt1video%u", MINOR(dev_conf->dev) + lp); 712 device_create(pt1video_class,
713 NULL,
714 MKDEV(MAJOR(dev_conf->dev),
715 (MINOR(dev_conf->dev) + lp)),
716 NULL,
717 "pt1video%u",
718 MINOR(dev_conf->dev) + lp +
719 dev_conf->card_number * MAX_CHANNEL);
705 #else 720 #else
706 device_create(pt1video_class, NULL, MKDEV(MAJOR(dev_conf->dev), 721 device_create(pt1video_class,
707 (MINOR(dev_conf->dev) + lp)), 722 NULL,
708 "pt1video%u", MINOR(dev_conf->dev) + lp); 723 MKDEV(MAJOR(dev_conf->dev),
724 (MINOR(dev_conf->dev) + lp)),
725 "pt1video%u",
726 MINOR(dev_conf->dev) + lp +
727 dev_conf->card_number * MAX_CHANNEL);
709 #endif 728 #endif
710 729
711 #if 0 730 #if 0
712 dev_conf->vdev[lp] = video_device_alloc(); 731 dev_conf->vdev[lp] = video_device_alloc();
713 memcpy(dev_conf->vdev[lp], &pt1_template, sizeof(pt1_template)); 732 memcpy(dev_conf->vdev[lp], &pt1_template, sizeof(pt1_template));
714 video_set_drvdata(dev_conf->vdev[lp], channel); 733 video_set_drvdata(dev_conf->vdev[lp], channel);
715 video_register_device(dev_conf->vdev[lp], VFL_TYPE_GRABBER, -1); 734 video_register_device(dev_conf->vdev[lp], VFL_TYPE_GRABBER, -1);
716 #endif 735 #endif
717 } 736 }
737
718 if(pt1_dma_init(pdev, dev_conf) < 0){ 738 if(pt1_dma_init(pdev, dev_conf) < 0){
719 goto out_err_dma; 739 goto out_err_dma;
720 } 740 }
721 dev_conf->kthread = kthread_run(pt1_thread, dev_conf, "pt1"); 741 dev_conf->kthread = kthread_run(pt1_thread, dev_conf, "pt1");
722 pci_set_drvdata(pdev, dev_conf); 742 pci_set_drvdata(pdev, dev_conf);
771 if(dev_conf->channel[lp] != NULL){ 791 if(dev_conf->channel[lp] != NULL){
772 cdev_del(&dev_conf->cdev[lp]); 792 cdev_del(&dev_conf->cdev[lp]);
773 kfree(dev_conf->channel[lp]->buf); 793 kfree(dev_conf->channel[lp]->buf);
774 kfree(dev_conf->channel[lp]); 794 kfree(dev_conf->channel[lp]);
775 } 795 }
776 device_destroy(pt1video_class, 796 device_destroy(pt1video_class,
777 MKDEV(MAJOR(dev_conf->dev), (MINOR(dev_conf->dev) + lp))); 797 MKDEV(MAJOR(dev_conf->dev),
778 } 798 (MINOR(dev_conf->dev) + lp)));
799 }
800
779 unregister_chrdev_region(dev_conf->dev, MAX_CHANNEL); 801 unregister_chrdev_region(dev_conf->dev, MAX_CHANNEL);
780 writel(0xb0b0000, dev_conf->regs); 802 writel(0xb0b0000, dev_conf->regs);
781 writel(0, dev_conf->regs + 4); 803 writel(0, dev_conf->regs + 4);
782 settuner_reset(dev_conf->regs, LNB_OFF, TUNER_POWER_OFF); 804 settuner_reset(dev_conf->regs, LNB_OFF, TUNER_POWER_OFF);
783 release_mem_region(dev_conf->mmio_start, dev_conf->mmio_len); 805 release_mem_region(dev_conf->mmio_start, dev_conf->mmio_len);
784 iounmap(dev_conf->regs); 806 iounmap(dev_conf->regs);
807 device[dev_conf->card_number] = NULL;
785 kfree(dev_conf); 808 kfree(dev_conf);
786 } 809 }
787 pci_set_drvdata(pdev, NULL); 810 pci_set_drvdata(pdev, NULL);
788 } 811 }
789 #ifdef CONFIG_PM 812 #ifdef CONFIG_PM
824 847
825 848
826 static void __exit pt1_pci_cleanup(void) 849 static void __exit pt1_pci_cleanup(void)
827 { 850 {
828 class_destroy(pt1video_class); 851 class_destroy(pt1video_class);
829 pci_unregister_driver (&pt1_driver); 852 pci_unregister_driver(&pt1_driver);
830 } 853 }
831 854
832 module_init(pt1_pci_init); 855 module_init(pt1_pci_init);
833 module_exit(pt1_pci_cleanup); 856 module_exit(pt1_pci_cleanup);