📄 ul_linpci.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 + -