Mercurial > pt1.oyama
diff 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 |
line wrap: on
line diff
--- a/driver/pt1_pci.c Sun Mar 01 23:32:38 2009 +0900 +++ b/driver/pt1_pci.c Tue Mar 03 05:15:40 2009 +0900 @@ -51,7 +51,7 @@ MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); -static int debug = 1; /* 1 normal messages, 0 quiet .. 7 verbose. */ +static int debug = 7; /* 1 normal messages, 0 quiet .. 7 verbose. */ static int lnb = 0; /* LNB OFF:0 +11V:1 +15V:2 */ module_param(debug, int, 0); @@ -97,6 +97,7 @@ void *dmaptr[DMA_RING_SIZE] ; struct task_struct *kthread; dev_t dev ; + int card_number; __u32 base_minor ; struct cdev cdev[MAX_CHANNEL]; wait_queue_head_t dma_wait_q ;// for poll on reading @@ -284,6 +285,7 @@ static int pt1_open(struct inode *inode, struct file *file) { + int major = imajor(inode); int minor = iminor(inode); int lp ; int lp2 ; @@ -293,8 +295,11 @@ if(device[lp] == NULL){ return -EIO ; } - if((device[lp]->base_minor <= minor) && - ((device[lp]->base_minor + MAX_CHANNEL) > minor)){ + + if(MAJOR(device[lp]->dev) == major && + device[lp]->base_minor <= minor && + device[lp]->base_minor + MAX_CHANNEL > minor) { + mutex_lock(&device[lp]->lock); for(lp2 = 0 ; lp2 < MAX_CHANNEL ; lp2++){ channel = device[lp]->channel[lp2] ; @@ -329,7 +334,7 @@ mutex_lock(&channel->ptr->lock); SetStream(channel->ptr->regs, channel->channel, FALSE); channel->valid = FALSE ; - printk(KERN_INFO "(%d)Drop=%08d:%08d:%08d:%08d\n", iminor(inode), channel->drop, + printk(KERN_INFO "(%d:%d)Drop=%08d:%08d:%08d:%08d\n", imajor(inode), iminor(inode), channel->drop, channel->overflow, channel->counetererr, channel->transerr); channel->overflow = 0 ; channel->counetererr = 0 ; @@ -653,15 +658,18 @@ minor = MINOR(dev_conf->dev) ; dev_conf->base_minor = minor ; for(lp = 0 ; lp < MAX_PCI_DEVICE ; lp++){ + printk(KERN_INFO "PT1: device[%d]=%p\n", lp, device[lp]); if(device[lp] == NULL){ device[lp] = dev_conf ; + dev_conf->card_number = lp; break ; } } for(lp = 0 ; lp < MAX_CHANNEL ; lp++){ cdev_init(&dev_conf->cdev[lp], &pt1_fops); dev_conf->cdev[lp].owner = THIS_MODULE; - cdev_add(&dev_conf->cdev[lp], MKDEV(MAJOR(dev_conf->dev), (MINOR(dev_conf->dev) + lp)), 1); + cdev_add(&dev_conf->cdev[lp], + MKDEV(MAJOR(dev_conf->dev), (MINOR(dev_conf->dev) + lp)), 1); channel = kzalloc(sizeof(PT1_CHANNEL), GFP_KERNEL); if(!channel){ printk(KERN_ERR "PT1:out of memory !"); @@ -699,13 +707,24 @@ goto out_err_v4l; } #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) - device_create(pt1video_class, NULL, MKDEV(MAJOR(dev_conf->dev), - (MINOR(dev_conf->dev) + lp)), NULL, - "pt1video%u", MINOR(dev_conf->dev) + lp); + printk(KERN_INFO "PT1: card_number = %d\n", + dev_conf->card_number); + device_create(pt1video_class, + NULL, + MKDEV(MAJOR(dev_conf->dev), + (MINOR(dev_conf->dev) + lp)), + NULL, + "pt1video%u", + MINOR(dev_conf->dev) + lp + + dev_conf->card_number * MAX_CHANNEL); #else - device_create(pt1video_class, NULL, MKDEV(MAJOR(dev_conf->dev), - (MINOR(dev_conf->dev) + lp)), - "pt1video%u", MINOR(dev_conf->dev) + lp); + device_create(pt1video_class, + NULL, + MKDEV(MAJOR(dev_conf->dev), + (MINOR(dev_conf->dev) + lp)), + "pt1video%u", + MINOR(dev_conf->dev) + lp + + dev_conf->card_number * MAX_CHANNEL); #endif #if 0 @@ -715,6 +734,7 @@ video_register_device(dev_conf->vdev[lp], VFL_TYPE_GRABBER, -1); #endif } + if(pt1_dma_init(pdev, dev_conf) < 0){ goto out_err_dma; } @@ -773,15 +793,18 @@ kfree(dev_conf->channel[lp]->buf); kfree(dev_conf->channel[lp]); } - device_destroy(pt1video_class, - MKDEV(MAJOR(dev_conf->dev), (MINOR(dev_conf->dev) + lp))); + device_destroy(pt1video_class, + MKDEV(MAJOR(dev_conf->dev), + (MINOR(dev_conf->dev) + lp))); } + unregister_chrdev_region(dev_conf->dev, MAX_CHANNEL); writel(0xb0b0000, dev_conf->regs); writel(0, dev_conf->regs + 4); settuner_reset(dev_conf->regs, LNB_OFF, TUNER_POWER_OFF); release_mem_region(dev_conf->mmio_start, dev_conf->mmio_len); iounmap(dev_conf->regs); + device[dev_conf->card_number] = NULL; kfree(dev_conf); } pci_set_drvdata(pdev, NULL); @@ -826,7 +849,7 @@ static void __exit pt1_pci_cleanup(void) { class_destroy(pt1video_class); - pci_unregister_driver (&pt1_driver); + pci_unregister_driver(&pt1_driver); } module_init(pt1_pci_init);