speedwave
驱动牛犊
驱动牛犊
  • 注册日期2002-03-25
  • 最后登录2008-11-11
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:4814回复:23

请教linux pci driver问题!?

楼主#
更多 发布于:2002-04-10 20:38
请问那位大侠能提供一份关于linux下通用pci卡的driver 的编程框架. :)

[编辑 -  4/10/02 作者: speedwave]
sam111
驱动牛犊
驱动牛犊
  • 注册日期2002-10-13
  • 最后登录2007-06-07
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望1点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2003-08-21 09:46
最近我在调DS3131,系统大体框架搭好了,对PCI板子操作没有问题,剩下的只是DS3131的具体问题了。一个人摸索,进展很慢。好在上网方便,搜索了很多资料,很多没有仔细看。我的思路是让系统自动找到PCI卡,然后将卡注册为字符设备,对其操作。目前进展到在用户模式下通过IOCTL读写板子的寄存器。欢迎大家一块交流,互相学习。程序还不完善,很多地方我还在修改。完了我会继续跟贴,欢迎大家指正。谢谢!!


static void pci3131_interrupt(int irq, void *dev_id, struct pt_regs *regs){
drvDev  *card=  (drvDev *)dev_id;
int sm, sdma, sv54;

outb(0x03, card->base+0x02);
wake_up_interruptible(&interrupt_wq);
inb(card->base+0x05);
//////////////////////////////////////////////////////////////////////////////

/*
* In order to acknowledge interrupt we have to read
* three status registers from DS3134: SM (offset 0x20),
* SDMA(offset 0x28) and SV54 (offset 0x30)
*/
sm = 0;
sv54 = 0;
sdma = sysDevRdReg16 ((int)card->base, CHAT_REG_GEN_SDMA);

if (sdma)
{
drvIntCallback(card, sm, sdma, sv54);
}

 ////////////////////////////////////////////////////////////////////////////

}
//-------------------------------------------------------
//  pci probe µÇåh
static int __init pci3131_probe(struct pci_dev *pci_dev, const struct pci_device_id *pci_id){
int minor=0;
drvDev   *card;
u32 len;
u32 pcmd1;
u32 pci3131_base;

    if(pci_enable_device(pci_dev)){  //
                printk(\"<0>pci3131 drive failed to enable PCI3131 hardware\");
                return(-EIO);
        }

    if (pci_set_dma_mask(pci_dev, 0xffffffff))
          printk(\"<0>drive DMA address limits not supported for PCI ds3131 hardware\");
    pci_read_config_dword(pci_dev,0x008,&pcmd1);
//    printk(\"<0>pci3131 008 %X\\n\",pcmd1);
    if((pcmd1>>24&0xff)==6)
     return (0);

//    pci_read_config_dword(pci_dev,0x010,&pcmd1);
 //   printk(\"<0>pci3131 010 %X\\n\",pcmd1);

     pci3131_base = pci_resource_start(pci_dev, 0);
     printk(\"<0>pci3131 driver at %X\\n\",pci3131_base);
    
     len = pci_resource_len(pci_dev, 0);
     printk(\"<0>pci3131 resoure len  %X\\n\",len);
     card = kmalloc(sizeof(drvDev),GFP_KERNEL);

        if (card == NULL) {                            
                printk(\"PCI3131: Can\'t allocate memory. minor=%d.\\n\", minor);
                return( -ENOMEM);
        }
        memset(card,0,sizeof(drvDev));
        card->minor=minor;      
        card->irq=pci_dev->irq;
        card->pci_dev = pci_dev;
        
        if( !request_mem_region(pci_resource_start(pci_dev, 0), pci_resource_len(pci_dev, 0),DRIVER_NAME)){
                printk(\"<0>Unable to reserve I/O space\\n\");
   goto out_free;
        }  
        card->base = (unsigned long) ioremap(pci_resource_start(pci_dev, 0), pci_resource_len(pci_dev, 0));
        if(card->base==NULL)
         {
         printk(KERN_ERR \"PCI 3131: unable to map registers\\n\");
         goto out_release_region;
         }
        pci_set_drvdata(pci_dev, card);  //
        if(request_irq(pci_dev->irq, pci3131_interrupt, SA_INTERRUPT, pci_dev->name, card)){
                printk(\"<0>Unable to allocate irq %d\\n\",pci_dev->irq);
                goto out_unmap;
        }
        
       if(gDrvDevDesc){
                goto out_free_irq;
        }
        //
        gDrvDevDesc=card;
// for test
// readreg(card->base);

//come from DS3134_Open
/* Set PCMD0 */
 pci_read_config_dword(pci_dev,0x004,&pcmd1);
 pcmd1 &=~(0x100);
 pci_write_config_dword(pci_dev,0x004,pcmd1);
 pci_read_config_dword(pci_dev,0x004,&pcmd1);

 BossdrvDevInit(pci_dev, 0);
//  readreg(card->base);
 return(0);

out_free_irq:
        free_irq(pci_dev->irq, card);
out_unmap:
        iounmap((void *)((unsigned long)card->base));
out_release_region:
        release_mem_region(pci_resource_start(pci_dev, 0), pci_resource_len(pci_dev, 0));
out_free:
        kfree(card);
        return -ENODEV;
}

static void pci3131_remove(struct pci_dev *dev_id){
  drvDev  *card;
  int  minor;
  u32  base,len;
  u32  pcmd1;

        
     pci_read_config_dword(dev_id,0x008,&pcmd1);
 //   printk(\"<0>pci3131 008 %X\\n\",pcmd1);
     if((pcmd1>>24&0xff)==6)
     return;

     card =  (drvDev *)pci_get_drvdata(dev_id);
     assert (card != NULL);

     minor =  card->minor;
     gDrvDevDesc=NULL;  
     base = pci_resource_start(dev_id, 0);
     printk(\"<0>pci3131 driver at %X\\n\",base);
     len = pci_resource_len(dev_id, 0);
     printk(\"<0>pci3131 resoure len  %X\\n\",len);
    
     gDrvDevDesc=NULL;
     free_irq(dev_id->irq, card);  
     iounmap((void *)((unsigned long)card->base));
     release_mem_region(base, len);
     kfree(card);                  //
     pci_set_drvdata (dev_id, NULL);
        
}
//--------------------------------------------------------
static int pci3131_open(struct inode *inode, struct file * file){
//        MOD_INC_USE_COUNT;
        return(0);
}
static ssize_t pci3131_read(struct file * file, char * buffer, size_t count, loff_t *ppos){
        return(0);
}
static ssize_t pci3131_write(struct file * file, const char * buffer, size_t count, loff_t *ppos){
        return(count);
}
static int pci3131_ioctl( struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg){

        unsigned char ch, inputSpec, triggerPolarity, intMask, data_low, data_high, busy, int_status;
        unsigned short data;
        struct   int_wait_and_get_ad_t  intWait;
        int minor;
        drvDev *card;

     minor = MINOR(inode->i_rdev); //
        card=gDrvDevDesc;        //

        switch(cmd){                  // ioctl
              case PCI3131_IOC_HARDRESET:
         /*
          * reset the counter to 1, to allow unloading in case
          * of problems. Use 1, not 0, because the invoking
          * process has the device open.
          */
         while (MOD_IN_USE)
             MOD_DEC_USE_COUNT;
         MOD_INC_USE_COUNT;
         /* don\'t break: fall through and reset things */
                // &sup3;&ouml;
                case PCI3131_IOC_SETREG:
                 copy_from_user(&ch, (void *)arg, sizeof(ch)); //
                 printk(\"<0>.....................................set reg 0x10,%X of base %X\\n\",ch,card->base);
                        writew(ch, card->base+0x10);    
                        break;
                case PCI3131_IOC_CONFIG:
                 ConfigureDevice();    
                        break;
                case PCI3131_IOC_RESET:
                 ResetDevice();    
                        break;
                case PCI3131_IOC_STARTTEST:
                 StartDeviceTest();    
                        break;
                
                case SET_CHANNEL:
                        copy_from_user(&ch, (void *)arg, sizeof(ch)); //
                        ch &= 0x0f;
                        ch |= 0x80;
                        outb(ch, card->base);    
                        break;
                case SET_CH_AND_START:
                        copy_from_user(&ch, (void *)arg, sizeof(ch));
                        ch &= 0x0f;
                        outb(ch, card->base);
                        break;
                case SET_INPUT_SPEC:
                        copy_from_user(&inputSpec, (void *)arg, sizeof(inputSpec));
                        outb(inputSpec, card->base+0x01);
                        break;
                case SET_TRIGGER_POLARITY:
                        copy_from_user(&triggerPolarity, (void *)arg, sizeof(triggerPolarity));
                        outb(triggerPolarity, card->base+0x04);
                        break;
                case SET_INT_MASK:
                        copy_from_user(&intMask, (void *)arg, sizeof(intMask));
                        outb(intMask, card->base+0x05);
                        break;
                case SET_DO:
                        copy_from_user(&data, (void *)arg, sizeof(data));
                        outb(data & 0x03,card->base+0x02);
                        break;
                // &Egrave;&euml;&Aacute;&brvbar;
                case GET_DATA:
                 /*
                        data_high=inb(card->base+0x01);
                        if((data_high & 0x80)!=0){
                                return(-BUSY);
                        }
                        data_low=inb(card->base);
                        data=(((data_high)&0x0f)<<8) + data_low;
                        copy_to_user((void *)arg, &data, sizeof(data));
                        */
                        if(card)
                         readreg(card->base);
                        break;
                case GET_BUSY:   //
                        busy=inb(card->base+0x01) & 0x80;
                        copy_to_user((void *)arg, &busy, sizeof(busy)); //
                        break;
                case GET_INT_STATUS: //
                        int_status=inb(card->base+0x05);
                        copy_to_user((void *)arg, &int_status, sizeof(int_status));
                        break;
case WAIT_INTERRUPT:
                      outb(0x00,card->base+0x02);
             copy_from_user(&intWait, (void *)arg, sizeof(intWait));
                        intWait.err=0;
//
                 if ( interruptible_sleep_on_timeout(&interrupt_wq, HZ*intWait.timeOut/1000 ) != 0) {  //
udelay(intWait.adSettringTime);        //
outb(0x00,card->base+0x02); //
// AD
data_high=inb(card->base+0x01);
if(!(data_high & 0x80)){ //
intWait.err=BUSY;  //
copy_to_user((void *)arg, &intWait, sizeof(intWait));
return(-BUSY);
}
data_low=inb(gDrvDevDesc->base); //
intWait.adData=(((data_high)&0x0f)<<8) + data_low;
copy_to_user((void *)arg, &intWait, sizeof(intWait));
}else{
intWait.err=INTWAITTIMEOUT;
copy_to_user((void *)arg, &intWait, sizeof(intWait));
return( -INTWAITTIMEOUT );
}
break;
                default:
return(-ENOTSUPP); //
break;
        }
        return(0);


}

//-------------------------------------------------------
static int pci3131_close(struct inode * inode, struct file * file){
        return(0);
}

//---------------------------------------------------
static struct pci_driver pci3131_pci_driver = {
        name :          DRIVER_NAME,
        id_table :        pci3131_id_table,
        probe :         pci3131_probe,
        remove :        pci3131_remove,
};
static struct file_operations pci3131_ops={
        read :         pci3131_read,
        write :         pci3131_write,
        ioctl :         pci3131_ioctl,
        open :          pci3131_open,
        release :       pci3131_close,
};
// -----------------------------------------------------
static void __exit pci3131_cleanup_module(void){
        unregister_chrdev(pci3131_major, DEVICE_NAME);
        pci_unregister_driver(&pci3131_pci_driver);  
}
static int __init pci3131_init_module(void){
        int retVal;
        if(!pci_register_driver( &pci3131_pci_driver )){
       printk(\"<0> init ds3131 error\\n\");
                pci_unregister_driver( &pci3131_pci_driver);
                return(-ENODEV);
        }
        retVal = register_chrdev(pci3131_major , DEVICE_NAME, &pci3131_ops);
        if(pci3131_major==0){   //
         printk(\"<0> candidate of major = %d\\n\",pci3131_major);
                pci3131_cleanup_module();
                return(-ENODEV);
         }
        if(retVal){
                pci_unregister_driver(&pci3131_pci_driver);
                return(-ENODEV);
        }
        return(0);
}
module_init(pci3131_init_module);
module_exit(pci3131_cleanup_module);
 ;)
spark7
驱动牛犊
驱动牛犊
  • 注册日期2003-08-18
  • 最后登录2003-08-21
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2003-08-18 12:15
spark7@21cn.com
兄弟给我一份,谢谢!
hust_sailor
驱动牛犊
驱动牛犊
  • 注册日期2002-07-10
  • 最后登录2018-05-29
  • 粉丝0
  • 关注0
  • 积分2分
  • 威望10点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2003-06-10 16:54
兄弟,也给我一份吧:dcdu@wtwh.com.cn
speedwave
驱动牛犊
驱动牛犊
  • 注册日期2002-03-25
  • 最后登录2008-11-11
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2003-06-04 10:54
我一直没有收到,你们呢?
nofer
驱动中牛
驱动中牛
  • 注册日期2001-06-08
  • 最后登录2008-12-17
  • 粉丝0
  • 关注0
  • 积分3分
  • 威望30点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2003-06-04 10:22
我也想要,请也给我一份吧
nofer@21cn.com
谢谢! :D
[img]http://www.driverdevelop.com/forum/upload/nofer/2002-11-16_32_740_5.jpg[/img] [size=3]想着梦中天堂的样子不知不觉睡着了。。。。 [/size]
sufeng
驱动牛犊
驱动牛犊
  • 注册日期2002-04-27
  • 最后登录2004-08-10
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2003-06-02 13:50
呵呵,我也想看一下。

多谢了。

sufengtiger@163.net
jjs
jjs
驱动牛犊
驱动牛犊
  • 注册日期2001-06-12
  • 最后登录2004-06-01
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2003-05-29 12:30
也给我一份吧,谢谢!!!!!!!!
xdbupt@163.com
zhangyanping
驱动小牛
驱动小牛
  • 注册日期2003-02-23
  • 最后登录2004-07-23
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2003-05-15 15:47
发给我一份吧,我是新手,老板催的紧,多谢了!
邮箱:ypzhang@cdyw.com
wzxghost
驱动牛犊
驱动牛犊
  • 注册日期2002-03-08
  • 最后登录2010-11-10
  • 粉丝0
  • 关注0
  • 积分67分
  • 威望9点
  • 贡献值0点
  • 好评度7点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2003-03-26 10:52
也给我一份吧,谢谢
mail :wzxghost@yahoo.com.cn
swifthurb
驱动牛犊
驱动牛犊
  • 注册日期2003-01-27
  • 最后登录2003-03-27
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2003-03-26 10:44
我也要,我也要
robin-fox@sohu.com
谢谢了
liaoliao123
驱动牛犊
驱动牛犊
  • 注册日期2002-07-02
  • 最后登录2005-01-11
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2002-07-15 17:02
请问你贴的那个源码在哪?如何找到?
sirroom
驱动大牛
驱动大牛
  • 注册日期2001-07-30
  • 最后登录2018-05-29
  • 粉丝0
  • 关注0
  • 积分6分
  • 威望11点
  • 贡献值1点
  • 好评度0点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2002-05-28 18:28
如果是内核2.4的,偶也要一份,sirroom@163.com 3ks
如果是内核2.2下的,偶不是已经贴了一个源码出来了吗?是偶自已写的.hehe
111
A_Ken
驱动牛犊
驱动牛犊
  • 注册日期2001-07-07
  • 最后登录2002-04-04
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
13楼#
发布于:2002-05-27 20:50
各位,不至于吧,linux source code 里面有的是,一下就刨到了
Agri
驱动牛犊
驱动牛犊
  • 注册日期2002-02-26
  • 最后登录2002-11-29
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
14楼#
发布于:2002-05-27 16:44
写完了没有?能否给我一份.谢谢。agri1234@163.net
Agri
驱动牛犊
驱动牛犊
  • 注册日期2002-02-26
  • 最后登录2002-11-29
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
15楼#
发布于:2002-05-27 16:44
写完了没有?能否给我一份.谢谢
shenhd
驱动牛犊
驱动牛犊
  • 注册日期2001-09-09
  • 最后登录2005-04-14
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
16楼#
发布于:2002-05-04 13:59
给我发一份.谢谢!!!
shenhd@21cn.com
dos
dos
驱动小牛
驱动小牛
  • 注册日期2001-06-13
  • 最后登录2010-02-24
  • 粉丝0
  • 关注0
  • 积分90分
  • 威望9点
  • 贡献值0点
  • 好评度9点
  • 原创分0分
  • 专家分0分
17楼#
发布于:2002-04-22 16:08
真是不好意思,有这么多人感兴趣。但我还没写完呢。
最近一个月公司的事情特别多,我就有四个项目在跑,没日没夜地干。我会继续写,但可能还要在等几天才能发出去,总要测试一下吧。
iamgenius
驱动牛犊
驱动牛犊
  • 注册日期2002-04-22
  • 最后登录2002-04-23
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
18楼#
发布于:2002-04-22 15:37
给我发一个行吗?谢谢!(jiahs@neusoft.com)

kingwah
驱动牛犊
驱动牛犊
  • 注册日期2002-04-19
  • 最后登录2002-04-20
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
19楼#
发布于:2002-04-20 19:19
给我一个行吗? 谢谢

hkcompuman@sinaman.com
 :P
上一页
游客

返回顶部