]> rtime.felk.cvut.cz Git - can-usb1.git/blob - ulan/host/ul_drv/ul_drv/ul_linusb.c
Initializing repo
[can-usb1.git] / ulan / host / ul_drv / ul_drv / ul_linusb.c
1 /*******************************************************************
2   uLan Communication - uL_DRV - multiplatform uLan driver
3
4   ul_linusb.c   - Linux USB specific support routines
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 /* USB Devices Support */
30
31 int ul_usb_ps1_init(ul_drv *udrv, int port, int irq, int baud, long baudbase, int options);
32
33
34 static int /*__devinit*/ 
35   ul_usb_init_chan(struct usb_device *dev, unsigned int ifnum,
36                  const struct usb_device_id *ent, ul_drv **pudrv,
37                  ul_chip_init_fnc *chip_init, int options)
38 {
39   ul_drv *udrv;
40   int amy_adr=0;
41   int abaud=0;
42   long abaudbase=0;
43   int match;
44   int minor;
45   int ret;
46   int i;
47 #ifdef UL_WITH_DEVFS
48   kc_devfs_handle_t devfs_handle;
49   char dev_name[32];
50 #endif /* UL_WITH_DEVFS */
51   
52   *pudrv=NULL;
53   /* try to find best minor and parameters */
54   match=ulan_init_find_minor("usb","unknown","unknown",&minor,&i);
55   if(i>=0){
56     abaud=baud[i];amy_adr=my_adr[i]; abaudbase=baudbase[i];
57   }
58
59   /* mem for ul_drv */
60   if(!(udrv=MALLOC(sizeof(ul_drv)))) return -ENOMEM;
61   /* clear memory */
62   memset(udrv,0,sizeof(ul_drv));
63   /* set initial state */
64   ul_drv_new_init_state(udrv, amy_adr);
65   udrv->dev=(struct pci_dev *)dev;
66   /* init chip driver */
67   if((ret=(*chip_init)(udrv, ifnum, 0, abaud, abaudbase, options))<0){
68     printk(KERN_CRIT "ul_usb_init_chan: ERROR - chip_init returned %d\n",ret);
69     FREE(udrv);
70     return -EIO;
71   }
72   /* setups buffers, ports and irq for sucesfully detected device */
73   if((ret=ul_drv_new_start(udrv,ulbuffer))<0){
74     printk(KERN_CRIT "ulan_init_chan: ERROR - ul_drv_new_start returned %d\n",ret);
75     FREE(udrv);
76     return -EIO;
77   }
78   #ifdef UL_WITH_DEVFS
79   sprintf (dev_name, "ulan%d", minor);
80   devfs_handle=kc_devfs_new_cdev(NULL, MKDEV(ulan_major_dev, minor), 
81                         S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP, 
82                         &ulan_fops, udrv, dev_name);
83   udrv->devfs_handle=devfs_handle;
84   #endif /* UL_WITH_DEVFS */
85
86   printk(KERN_INFO "ul_usb_init_chan: minor=%d baud=%d my_adr=%d ready\n",
87          minor,udrv->baud_val,udrv->my_adr);
88   
89   if(minor>=0){
90     ul_drv_arr[minor]=udrv;
91     kc_class_device_create(ulan_class, NULL, MKDEV(ulan_major_dev, minor),
92                         kc_usb_dev_to_dev(dev), "ulan%d", minor);
93   }
94
95   *pudrv=udrv;
96   return 0;
97 }
98
99 #if (LINUX_VERSION_CODE < VERSION(2,5,41))
100 static void *ul_usb_probe(struct usb_device *dev, unsigned int ifnum, const struct usb_device_id *id)
101 {
102   unsigned long driver_info=id->driver_info;
103   ul_drv *udrv;
104   printk(KERN_INFO "ulan_init_one: USB device found devnum=%d, ifnum=%d\n",
105          dev->devnum, ifnum);
106   switch(driver_info&~0xff){
107     case  UL_USB_HW_PS1:
108       if(ul_usb_init_chan(dev,ifnum,id,&udrv,ul_usb_ps1_init,driver_info)<0)
109         return NULL;
110       printk(KERN_INFO "ul_usb_probe: data type\n");
111       return udrv;
112   }
113   printk(KERN_CRIT "ul_usb_probe: No device of specified driver_data type\n");
114   return NULL;
115 }
116 #else /* 2.5.41 */
117 static int ul_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
118 {
119   struct usb_device *dev = interface_to_usbdev(intf);
120   int ifnum = intf->altsetting->desc.bInterfaceNumber;
121   unsigned long driver_info=id->driver_info;
122   ul_drv *udrv;
123   dev_set_drvdata(&intf->dev,NULL);
124   printk(KERN_INFO "ulan_init_one: USB device found devnum=%d, ifnum=%d\n",
125          dev->devnum, ifnum);
126   switch(driver_info&~0xff){
127     case  UL_USB_HW_PS1:
128       if(ul_usb_init_chan(dev,ifnum,id,&udrv,ul_usb_ps1_init,driver_info)<0)
129         return -EIO;
130       printk(KERN_INFO "ul_usb_probe: data type\n");
131       dev_set_drvdata(&intf->dev,udrv);
132       return 0;
133   }
134   printk(KERN_CRIT "ul_usb_probe: No device of specified driver_data type\n");
135   return -EIO;
136 }
137 #endif /* 2.5.41 */
138
139 #if (LINUX_VERSION_CODE < VERSION(2,5,41))
140 static void ul_usb_disconnect(struct usb_device *dev, void *ptr)
141 {
142   ul_drv *udrv, *next_udrv;
143   int i;
144   udrv=(ul_drv *)ptr;
145   if(!udrv){
146     printk(KERN_CRIT "ulan_remove_one: no uLan drvdata\n");
147     return;
148   }
149   for(;udrv;udrv=next_udrv){
150     if(udrv->magic!=UL_DRV_MAGIC){
151       printk(KERN_CRIT "ulan_remove_one: Wrong uLan MAGIC number!!!\n");
152       return;
153     }
154     next_udrv=udrv->next_chan;
155     if(dev!=(struct usb_device *)udrv->dev){
156       printk(KERN_CRIT "ul_usb_disconnect: BAD - cross USB device remove\n");
157     }
158     for(i=0;i<UL_MINORS;i++){
159       if (udrv==ul_drv_arr[i]) ul_drv_arr[i]=NULL;
160     }
161     #ifdef UL_WITH_DEVFS
162     if(udrv->devfs_handle) kc_devfs_delete(udrv->devfs_handle);
163     #endif /* UL_WITH_DEVFS */
164     ul_drv_free(udrv);
165   }
166   printk(KERN_INFO "ul_usb_disconnect: USB device removed\n");
167 }
168 #else /* 2.5.41 */
169 static void ul_usb_disconnect(struct usb_interface *intf)
170 {
171   struct usb_device *dev = interface_to_usbdev(intf);
172   ul_drv *udrv, *next_udrv;
173   int i;
174   udrv=(ul_drv *)dev_get_drvdata(&intf->dev);
175   dev_set_drvdata(&intf->dev,NULL);
176   if(!udrv){
177     printk(KERN_CRIT "ulan_remove_one: no uLan drvdata\n");
178     return;
179   }
180   for(;udrv;udrv=next_udrv){
181     if(udrv->magic!=UL_DRV_MAGIC){
182       printk(KERN_CRIT "ulan_remove_one: Wrong uLan MAGIC number!!!\n");
183       return;
184     }
185     next_udrv=udrv->next_chan;
186     if(dev!=(struct usb_device *)udrv->dev){
187       printk(KERN_CRIT "ul_usb_disconnect: BAD - cross USB device remove\n");
188     }
189     for(i=0;i<UL_MINORS;i++){
190       if (udrv==ul_drv_arr[i]){
191         ul_drv_arr[i]=NULL;
192         kc_class_device_destroy(ulan_class, MKDEV(ulan_major_dev, i));
193       }
194     }
195     #ifdef UL_WITH_DEVFS
196     if(udrv->devfs_handle) kc_devfs_delete(udrv->devfs_handle);
197     #endif /* UL_WITH_DEVFS */
198     ul_drv_free(udrv);
199   }
200   printk(KERN_INFO "ul_usb_disconnect: USB device removed\n");
201 }
202 #endif /* 2.5.41 */