]> rtime.felk.cvut.cz Git - can-usb1.git/blob - ulan/host/ul_drv/ul_drv/ul_linpci.c
Initializing repo
[can-usb1.git] / ulan / host / ul_drv / ul_drv / ul_linpci.c
1 /*******************************************************************
2   uLan Communication - uL_DRV - multiplatform uLan driver
3
4   ul_linpci.c   - Linux kernel PCI device support
5
6   (C) Copyright 1996-2004 by Pavel Pisa - project originator
7         http://cmp.felk.cvut.cz/~pisa
8   (C) Copyright 1996-2004 PiKRON Ltd.
9         http://www.pikron.com
10   (C) Copyright 2002-2004 Petr Smolik
11   
12
13   The uLan driver project can be used and distributed 
14   in compliance with any of next licenses
15    - GPL - GNU Public License
16      See file COPYING for details.
17    - LGPL - Lesser GNU Public License
18    - MPL - Mozilla Public License
19    - and other licenses added by project originator
20
21   Code can be modified and re-distributed under any combination
22   of the above listed licenses. If contributor does not agree with
23   some of the licenses, he/she can delete appropriate line.
24   WARNING: if you delete all lines, you are not allowed to
25   distribute code or sources in any form.
26  *******************************************************************/
27
28 /*******************************************************************/
29 /* Linux kernel PCI device support */ 
30
31 /* config space access (byte|word|dword) return to text pcibios_strerror */
32 /* pci_read_config_byte(struct pci_dev *dev, int where, u8 *val) */
33 /* pci_write_config_byte(struct pci_dev *dev, int where, u8 *val) */
34 /* request_region(), request_mem_region() */
35 /* void *pci_get_drvdata (struct pci_dev *pdev) */
36 /* void pci_set_drvdata (struct pci_dev *pdev, void *data) */
37
38 /* default invocation of chip_init for PCI devices */
39 static int /*__devinit*/ 
40   ulan_init_chan(struct pci_dev *dev,char *subdev, 
41                  char *chip_name, ul_drv **pudrv,
42                  ul_chip_init_fnc *chip_init,
43                  int port, int irq, int options)
44 {
45   ul_drv *udrv;
46   int amy_adr=0;
47   int abaud=0;
48   long abaudbase=0;
49   int match;
50   int minor;
51   int ret;
52   int i;
53 #ifdef UL_WITH_DEVFS
54   kc_devfs_handle_t devfs_handle;
55   char dev_name[32];
56 #endif /* UL_WITH_DEVFS */
57   
58   *pudrv=NULL;
59   /* try to find best minor and parameters */
60   match=ulan_init_find_minor("pci",kc_pci_name(dev),subdev,&minor,&i);
61   if(i>=0){
62     abaud=baud[i];amy_adr=my_adr[i]; abaudbase=baudbase[i];
63   }
64
65   /* mem for ul_drv */
66   if(!(udrv=MALLOC(sizeof(ul_drv)))) return -ENOMEM;
67   /* clear memory */
68   memset(udrv,0,sizeof(ul_drv));
69   /* set initial state */
70   ul_drv_new_init_state(udrv, amy_adr);
71   udrv->dev=dev;
72   /* init chip driver */
73   if((ret=(*chip_init)(udrv, port, irq, abaud, abaudbase, options))<0){
74     printk(KERN_CRIT "ulan_init_chan: ERROR - chip_init returned %d\n",ret);
75     FREE(udrv);
76     return -EIO;
77   }
78   /* setups buffers, ports and irq for sucesfully detected device */
79   if((ret=ul_drv_new_start(udrv,ulbuffer))<0){
80     printk(KERN_CRIT "ulan_init_chan: ERROR - ul_drv_new_start returned %d\n",ret);
81     FREE(udrv);
82     return -EIO;
83   }
84   #ifdef UL_WITH_DEVFS
85   sprintf (dev_name, "ulan%d", minor);
86   devfs_handle=kc_devfs_new_cdev(NULL, MKDEV(ulan_major_dev, minor), 
87                         S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP, 
88                         &ulan_fops, udrv, dev_name);
89   udrv->devfs_handle=devfs_handle;
90   #endif /* UL_WITH_DEVFS */
91
92   printk(KERN_INFO "ulan_init_chan: chip=%s minor=%d baud=%d my_adr=%d ready\n",
93          chip_name,/*dev_name*/minor,udrv->baud_val,udrv->my_adr);
94   
95   if(minor>=0) ul_drv_arr[minor]=udrv;
96   *pudrv=udrv;
97   udrv->next_chan=pci_get_drvdata(dev);
98   pci_set_drvdata(dev, udrv);
99   kc_class_device_create(ulan_class, NULL, MKDEV(ulan_major_dev, minor),
100                         kc_pci_dev_to_dev(dev), "ulan%d", minor);
101   return 0;
102 }
103
104
105 static int /*__devinit*/ ulan_init_one_950pci (struct pci_dev *dev,
106                                    const struct pci_device_id *ent)
107 {
108   int chip_options=ent->driver_data;
109   int ret, retall=-ENODEV;
110   char subdev[2];
111   int subno, port, irq;
112   ul_drv *udrv;
113
114   if (pci_enable_device (dev)){
115     printk(KERN_CRIT "ulan_init_one_950pci: Cannot enable device\n");
116     return -EIO;    
117   }
118   port=pci_resource_start(dev,0);
119   irq=dev->irq;
120   if(!irq||!port||!(pci_resource_flags(dev,0)&IORESOURCE_IO)){
121     LOG_FATAL(KERN_CRIT "uLan u950pci_init : bad PCI port or irq !\n");
122     return -ENODEV;
123   }
124   
125   for(subno=0;subno<2;subno++,port+=8){
126     subdev[0]='0'+subno;subdev[1]=0;
127     /* (dev,subdev,chip_name,pudrv,chip_init,port,irq,options) */
128     ret=ulan_init_chan(dev,subdev,"16950-pci",&udrv,&u950pci_init,port,irq,chip_options);
129     if(ret>=0){
130       retall=0;
131     } else {
132       if(retall<0) retall=ret;
133     }
134   }
135   return retall;
136 }
137
138 static int /*__devinit*/ ulan_pci_init_one (struct pci_dev *dev,
139                                    const struct pci_device_id *ent)
140 {
141   unsigned long driver_data=ent->driver_data;
142   printk(KERN_INFO "ulan_init_one: PCI device found at slot : %s\n",
143          kc_pci_name(dev)?kc_pci_name(dev):"unknown");
144   pci_set_drvdata(dev, NULL);
145   switch(driver_data&~0xff){
146     case 0x16954000 :
147       return ulan_init_one_950pci(dev,ent);
148   }
149   printk(KERN_CRIT "ulan_init_one: No device of specified driver_data type\n");
150   return -ENODEV;
151 }
152
153 static void /*__devexit*/ ulan_pci_remove_one (struct pci_dev *dev)
154 {
155   ul_drv *udrv, *next_udrv;
156   int i;
157   udrv=(ul_drv *)pci_get_drvdata(dev);
158   if(!udrv){
159     printk(KERN_CRIT "ulan_remove_one: no uLan drvdata\n");
160     return;
161   }
162   for(;udrv;udrv=next_udrv){
163     if(udrv->magic!=UL_DRV_MAGIC){
164       printk(KERN_CRIT "ulan_remove_one: Wrong uLan MAGIC number!!!\n");
165       return;
166     }
167     next_udrv=udrv->next_chan;
168     if(dev!=udrv->dev){
169       printk(KERN_CRIT "ulan_remove_one: BAD - cross PCI device remove\n");
170     }
171     for(i=0;i<UL_MINORS;i++){
172       if (udrv==ul_drv_arr[i]){
173         kc_class_device_destroy(ulan_class, MKDEV(ulan_major_dev, i));
174         ul_drv_arr[i]=NULL;
175       }
176     }
177
178     #ifdef UL_WITH_DEVFS
179     if(udrv->devfs_handle) kc_devfs_delete(udrv->devfs_handle);
180     #endif /* UL_WITH_DEVFS */
181     ul_drv_free(udrv);
182   }
183   pci_disable_device(dev);
184   pci_set_drvdata(dev, NULL);
185   printk(KERN_INFO "ulan_remove_one: PCI device removed\n");
186 }
187