⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ul_linpci.c

📁 linux下的RS485的驱动 值得一看
💻 C
字号:
/*******************************************************************  uLan Communication - uL_DRV - multiplatform uLan driver  ul_linpci.c	- Linux kernel PCI device support  (C) Copyright 1996-2004 by Pavel Pisa - project originator        http://cmp.felk.cvut.cz/~pisa  (C) Copyright 1996-2004 PiKRON Ltd.        http://www.pikron.com  (C) Copyright 2002-2004 Petr Smolik    The uLan driver project can be used and distributed   in compliance with any of next licenses   - GPL - GNU Public License     See file COPYING for details.   - LGPL - Lesser GNU Public License   - MPL - Mozilla Public License   - and other licenses added by project originator  Code can be modified and re-distributed under any combination  of the above listed licenses. If contributor does not agree with  some of the licenses, he/she can delete appropriate line.  WARNING: if you delete all lines, you are not allowed to  distribute code or sources in any form. *******************************************************************//*******************************************************************//* Linux kernel PCI device support */ /* config space access (byte|word|dword) return to text pcibios_strerror *//* pci_read_config_byte(struct pci_dev *dev, int where, u8 *val) *//* pci_write_config_byte(struct pci_dev *dev, int where, u8 *val) *//* request_region(), request_mem_region() *//* void *pci_get_drvdata (struct pci_dev *pdev) *//* void pci_set_drvdata (struct pci_dev *pdev, void *data) *//* default invocation of chip_init for PCI devices */static int /*__devinit*/   ulan_init_chan(struct pci_dev *dev,char *subdev,   		 char *chip_name, ul_drv **pudrv,                 ul_chip_init_fnc *chip_init,                 int port, int irq, int options){  ul_drv *udrv;  int amy_adr=0;  int abaud=0;  long abaudbase=0;  int match;  int minor;  int ret;  int i;#ifdef UL_WITH_DEVFS  kc_devfs_handle_t devfs_handle;  char dev_name[32];#endif /* UL_WITH_DEVFS */    *pudrv=NULL;  /* try to find best minor and parameters */  match=ulan_init_find_minor("pci",kc_pci_name(dev),subdev,&minor,&i);  if(i>=0){    abaud=baud[i];amy_adr=my_adr[i]; abaudbase=baudbase[i];  }  /* mem for ul_drv */  if(!(udrv=MALLOC(sizeof(ul_drv)))) return -ENOMEM;  /* clear memory */  memset(udrv,0,sizeof(ul_drv));  /* set initial state */  ul_drv_new_init_state(udrv, amy_adr);  udrv->dev=dev;  /* init chip driver */  if((ret=(*chip_init)(udrv, port, irq, abaud, abaudbase, options))<0){    printk(KERN_CRIT "ulan_init_chan: ERROR - chip_init returned %d\n",ret);    FREE(udrv);    return -EIO;  }  /* setups buffers, ports and irq for sucesfully detected device */  if((ret=ul_drv_new_start(udrv,ulbuffer))<0){    printk(KERN_CRIT "ulan_init_chan: ERROR - ul_drv_new_start returned %d\n",ret);    FREE(udrv);    return -EIO;  }  #ifdef UL_WITH_DEVFS  sprintf (dev_name, "ulan%d", minor);  devfs_handle=kc_devfs_new_cdev(NULL, MKDEV(ulan_major_dev, minor), 			S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP, 			&ulan_fops, udrv, dev_name);  udrv->devfs_handle=devfs_handle;  #endif /* UL_WITH_DEVFS */  printk(KERN_INFO "ulan_init_chan: chip=%s minor=%d baud=%d my_adr=%d ready\n",	 chip_name,/*dev_name*/minor,udrv->baud_val,udrv->my_adr);    if(minor>=0) ul_drv_arr[minor]=udrv;  *pudrv=udrv;  udrv->next_chan=pci_get_drvdata(dev);  pci_set_drvdata(dev, udrv);  kc_class_device_create(ulan_class, NULL, MKDEV(ulan_major_dev, minor),			kc_pci_dev_to_dev(dev), "ulan%d", minor);  return 0;}static int /*__devinit*/ ulan_init_one_950pci (struct pci_dev *dev,				   const struct pci_device_id *ent){  int chip_options=ent->driver_data;  int ret, retall=-ENODEV;  char subdev[2];  int subno, port, irq;  ul_drv *udrv;  if (pci_enable_device (dev)){    printk(KERN_CRIT "ulan_init_one_950pci: Cannot enable device\n");    return -EIO;      }  port=pci_resource_start(dev,0);  irq=dev->irq;  if(!irq||!port||!(pci_resource_flags(dev,0)&IORESOURCE_IO)){    LOG_FATAL(KERN_CRIT "uLan u950pci_init : bad PCI port or irq !\n");    return -ENODEV;  }    for(subno=0;subno<2;subno++,port+=8){    subdev[0]='0'+subno;subdev[1]=0;    /* (dev,subdev,chip_name,pudrv,chip_init,port,irq,options) */    ret=ulan_init_chan(dev,subdev,"16950-pci",&udrv,&u950pci_init,port,irq,chip_options);    if(ret>=0){      retall=0;    } else {      if(retall<0) retall=ret;    }  }  return retall;}static int /*__devinit*/ ulan_pci_init_one (struct pci_dev *dev,				   const struct pci_device_id *ent){  unsigned long driver_data=ent->driver_data;  printk(KERN_INFO "ulan_init_one: PCI device found at slot : %s\n",         kc_pci_name(dev)?kc_pci_name(dev):"unknown");  pci_set_drvdata(dev, NULL);  switch(driver_data&~0xff){    case 0x16954000 :      return ulan_init_one_950pci(dev,ent);  }  printk(KERN_CRIT "ulan_init_one: No device of specified driver_data type\n");  return -ENODEV;}static void /*__devexit*/ ulan_pci_remove_one (struct pci_dev *dev){  ul_drv *udrv, *next_udrv;  int i;  udrv=(ul_drv *)pci_get_drvdata(dev);  if(!udrv){    printk(KERN_CRIT "ulan_remove_one: no uLan drvdata\n");    return;  }  for(;udrv;udrv=next_udrv){    if(udrv->magic!=UL_DRV_MAGIC){      printk(KERN_CRIT "ulan_remove_one: Wrong uLan MAGIC number!!!\n");      return;    }    next_udrv=udrv->next_chan;    if(dev!=udrv->dev){      printk(KERN_CRIT "ulan_remove_one: BAD - cross PCI device remove\n");    }    for(i=0;i<UL_MINORS;i++){      if (udrv==ul_drv_arr[i]){        kc_class_device_destroy(ulan_class, MKDEV(ulan_major_dev, i));        ul_drv_arr[i]=NULL;      }    }    #ifdef UL_WITH_DEVFS    if(udrv->devfs_handle) kc_devfs_delete(udrv->devfs_handle);    #endif /* UL_WITH_DEVFS */    ul_drv_free(udrv);  }  pci_disable_device(dev);  pci_set_drvdata(dev, NULL);  printk(KERN_INFO "ulan_remove_one: PCI device removed\n");}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -