Import changeset
[linux-flexiantxendom0-3.2.10.git] / drivers / isdn / eicon / lincfg.c
1
2 /*
3  *
4  * Copyright (C) Eicon Technology Corporation, 2000.
5  *
6  * This source file is supplied for the exclusive use with Eicon
7  * Technology Corporation's range of DIVA Server Adapters.
8  *
9  * Eicon File Revision :    1.9  
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2, or (at your option)
14  * any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY 
18  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
19  * See the GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24  *
25  */
26
27
28 #include <linux/fs.h>
29 #undef N_DATA   /* Because we have our own definition */
30
31 #include <asm/segment.h>
32 #include <asm/io.h>
33
34 #include "sys.h"
35 #include "idi.h"
36 #include "constant.h"
37 #include "divas.h"
38 #undef ID_MASK
39 #include "pc.h"
40 #include "pr_pc.h"
41
42 #include "adapter.h"
43 #include "uxio.h"
44
45 #include <linux/pci.h>
46 #include <linux/kernel.h>
47 #include <linux/ioport.h>
48
49 #define HW_ID_EICON_PCI                 0x1133
50 #define HW_ID_DIVA_SERVER_P             0xE014
51 #define HW_ID_DIVA_SERVER_B_ST  0xE010
52 #define HW_ID_DIVA_SERVER_B_U   0xE013
53 #define HW_ID_DIVA_SERVER_Q     0xE012
54
55 struct file_operations Divas_fops;
56 int Divas_major;
57
58 extern int do_ioctl(struct inode *pDivasInode, struct file *pDivasFile, 
59                          unsigned int command, unsigned long arg);
60 extern unsigned int do_poll(struct file *pFile, struct poll_table_struct *pPollTable);
61 extern ssize_t do_read(struct file *pFile, char *pUserBuffer, size_t BufferSize, loff_t *pOffset);
62 extern int do_open(struct inode *, struct file *);
63 extern int do_release(struct inode *, struct file *);
64
65 int FPGA_Done=0;
66
67 int DivasCardsDiscover(void)
68 {
69         word wNumCards = 0, wDeviceIndex = 0;
70         byte byBus, byFunc;
71         word wPCIConsultation, PCItmp;
72         dword j, i;
73         unsigned int PCIserial;
74         dia_card_t Card;
75         byte *b;
76         
77         while (wDeviceIndex < 10)
78         {
79                 wPCIConsultation = pcibios_find_device(HW_ID_EICON_PCI, 
80                                 HW_ID_DIVA_SERVER_Q, 
81                                 wDeviceIndex, 
82                                 &byBus, &byFunc);
83
84                 if (wPCIConsultation == PCIBIOS_SUCCESSFUL)
85                 {
86
87                         dword dwRAM, dwDivasIOBase, dwCFG, dwCTL;                       
88                         byte byIRQ;
89                         
90                         printk(KERN_DEBUG "Divas: DIVA Server 4BRI Found\n");
91                         pcibios_read_config_dword(byBus, byFunc, PCI_BASE_ADDRESS_2,(unsigned int *) &dwRAM);
92                         dwRAM &= 0xFFC00000;
93                         
94                         pcibios_read_config_dword(byBus, byFunc, PCI_BASE_ADDRESS_1,(unsigned int *) &dwDivasIOBase);
95                         dwDivasIOBase &= 0xFFFFFF00;
96                         
97                         pcibios_read_config_dword(byBus, byFunc, PCI_BASE_ADDRESS_0,(unsigned int *) &dwCFG);
98                         dwCFG &= 0xFFFFFF00;
99                         
100                         pcibios_read_config_dword(byBus, byFunc, PCI_BASE_ADDRESS_3,(unsigned int *) &dwCTL);
101                         dwCTL &= 0xFFFFE000;
102                         
103
104                         pcibios_read_config_byte(byBus, byFunc, PCI_INTERRUPT_LINE, &byIRQ);
105                         /* Retrieve the serial number */
106
107                         pcibios_write_config_word(byBus,byFunc,0x4E,0x00FC);
108
109                         for (j=0, PCItmp=0; j<10000 && !PCItmp; j++)
110                         {
111                                 pcibios_read_config_word(byBus,byFunc,0x4E, &PCItmp);
112                                 PCItmp &= 0x8000;  // extract done flag
113                         }
114
115                         pcibios_read_config_dword(byBus,byFunc,0x50, &PCIserial);
116
117                 
118                         Card.memory[DIVAS_RAM_MEMORY] = ioremap(dwRAM, 0x400000);
119                         Card.memory[DIVAS_CTL_MEMORY] = ioremap(dwCTL, 0x2000);
120                         Card.memory[DIVAS_CFG_MEMORY] = ioremap(dwCFG, 0x100);
121                         Card.io_base=dwDivasIOBase;
122
123                         Card.irq = byIRQ;
124                         
125                         Card.card_type = DIA_CARD_TYPE_DIVA_SERVER_Q;
126                         Card.bus_type = DIA_BUS_TYPE_PCI;
127         
128                         FPGA_Done = 0;
129
130                         /* Create four virtual card structures as we want to treat 
131                            the 4Bri card as 4 Bri cards*/
132                         for(i=0;i<4;i++)
133                         {
134
135                                 b=Card.memory[DIVAS_RAM_MEMORY];
136                                 b+=(MQ_PROTCODE_OFFSET) * (i==0?0:1); 
137                                 DPRINTF(("divas: offset = 0x%x", i* MQ_PROTCODE_OFFSET));
138                                 Card.memory[DIVAS_RAM_MEMORY]=b;
139  
140                                 b = Card.memory[DIVAS_RAM_MEMORY];
141                                 b += MQ_SM_OFFSET;
142                                 Card.memory[DIVAS_SHARED_MEMORY] = b;
143
144                                 Card.bus_num = byBus;
145                                 Card.func_num = byFunc;
146                                 Card.slot = -1;
147
148                         
149                                 /* Fill in Name */
150                                 Card.name[0] = 'D';
151                                 Card.name[1] = 'I';
152                                 Card.name[2] = 'V';
153                                 Card.name[3] = 'A';
154                                 Card.name[4] = 'S';
155                                 Card.name[5] = 'Q';
156                                 Card.name[6] = '0' + i;
157                                 Card.name[7] = '\0';
158
159                                 Card.serial = PCIserial;
160
161                                 Card.card_id = wNumCards;
162
163                                 if (DivasCardNew(&Card) != 0)
164                                 {
165                                         // Force for loop to terminate
166                                         i = 4;
167                                         continue;
168                                 }
169                                 wNumCards++;
170
171                         }//for
172                 }
173                 wDeviceIndex++;
174         }
175
176         wDeviceIndex = 0;
177
178         while (wDeviceIndex < 10)
179         {
180                 wPCIConsultation = pcibios_find_device(HW_ID_EICON_PCI, 
181                                 HW_ID_DIVA_SERVER_B_ST, 
182                                 wDeviceIndex, 
183                                 &byBus, &byFunc);
184
185                 if (wPCIConsultation == PCIBIOS_SUCCESSFUL)
186                 {
187                         dword dwPLXIOBase, dwDivasIOBase;
188                         byte byIRQ;
189
190                         printk(KERN_DEBUG "Divas: DIVA Server BRI (S/T) Found\n");
191                         pcibios_read_config_dword(byBus, byFunc, PCI_BASE_ADDRESS_1, (unsigned int *) &dwPLXIOBase);
192                         dwPLXIOBase &= 0xFFFFFF80;
193
194                         pcibios_read_config_dword(byBus, byFunc, PCI_BASE_ADDRESS_2, (unsigned int *) &dwDivasIOBase);
195                         dwDivasIOBase &= 0xFFFFFFFC;
196
197                         pcibios_read_config_byte(byBus, byFunc, PCI_INTERRUPT_LINE, &byIRQ);
198
199                         Card.card_id = wNumCards;
200                         Card.card_type = DIA_CARD_TYPE_DIVA_SERVER_B;
201                         Card.bus_type = DIA_BUS_TYPE_PCI;
202                         Card.irq = byIRQ;
203                         Card.reset_base = dwPLXIOBase;
204                         Card.io_base = dwDivasIOBase;
205                         Card.bus_num = byBus;
206                         Card.func_num = byFunc;
207                         Card.slot = -1;
208                         Card.name[0] = 'D';
209                         Card.name[1] = 'I';
210                         Card.name[2] = 'V';
211                         Card.name[3] = 'A';
212                         Card.name[4] = 'S';
213                         Card.name[5] = 'B';
214                         Card.name[6] = '\0';
215
216                         if (check_region(Card.io_base, 0x20))
217                         {
218                                 printk(KERN_WARNING "Divas: DIVA I/O Base already in use 0x%x-0x%x\n", Card.io_base, Card.io_base + 0x1F);
219                                 wDeviceIndex++;
220                                 continue;
221                         }
222
223                         if (check_region(Card.reset_base, 0x80))
224                         {
225                                 printk(KERN_WARNING "Divas: PLX I/O Base already in use 0x%x-0x%x\n", Card.reset_base, Card.reset_base + 0x7F);
226                                 wDeviceIndex++;
227                                 continue;
228                         }
229
230                         if (DivasCardNew(&Card) != 0)
231                         {
232                                 wDeviceIndex++;
233                                 continue;
234                         }
235                         wNumCards++;
236                 }
237
238                 wPCIConsultation = pcibios_find_device(HW_ID_EICON_PCI, 
239                                 HW_ID_DIVA_SERVER_B_U, 
240                                 wDeviceIndex, 
241                                 &byBus, &byFunc);
242
243                 if (wPCIConsultation == PCIBIOS_SUCCESSFUL)
244                 {
245                         dword dwPLXIOBase, dwDivasIOBase;
246                         byte byIRQ;
247
248                         printk(KERN_DEBUG "Divas: DIVA Server BRI (U) Found\n");
249
250                         pcibios_read_config_dword(byBus, byFunc, PCI_BASE_ADDRESS_1, (unsigned int *) &dwPLXIOBase);
251                         dwPLXIOBase &= 0xFFFFFF80;
252
253                         pcibios_read_config_dword(byBus, byFunc, PCI_BASE_ADDRESS_2, (unsigned int *) &dwDivasIOBase);
254                         dwDivasIOBase &= 0xFFFFFFFC;
255
256                         pcibios_read_config_byte(byBus, byFunc, PCI_INTERRUPT_LINE, &byIRQ);
257
258                         Card.card_id = wNumCards;
259                         Card.card_type = DIA_CARD_TYPE_DIVA_SERVER_B;
260                         Card.bus_type = DIA_BUS_TYPE_PCI;
261                         Card.irq = byIRQ;
262                         Card.reset_base = dwPLXIOBase;
263                         Card.io_base = dwDivasIOBase;
264                         Card.bus_num = byBus;
265                         Card.func_num = byFunc;
266                         Card.slot = -1;
267                         Card.name[0] = 'D';
268                         Card.name[1] = 'I';
269                         Card.name[2] = 'V';
270                         Card.name[3] = 'A';
271                         Card.name[4] = 'S';
272                         Card.name[5] = 'B';
273                         Card.name[6] = '\0';
274
275                         if (check_region(Card.io_base, 0x20))
276                         {
277                                 printk(KERN_WARNING "Divas: DIVA I/O Base already in use 0x%x-0x%x\n", Card.io_base, Card.io_base + 0x1F);      
278                                 wDeviceIndex++;
279                                 continue;
280                         }
281
282                         if (check_region(Card.reset_base, 0x80))
283                         {
284                                 printk(KERN_WARNING "Divas: PLX I/O Base already in use 0x%x-0x%x\n", Card.reset_base, Card.reset_base + 0x7F);
285                                 wDeviceIndex++;
286                                 continue;
287                         }
288
289                         if (DivasCardNew(&Card) != 0)
290                         {
291                                 wDeviceIndex++;
292                                 continue;
293                         }
294                         wNumCards++;
295                 }
296
297                 wDeviceIndex++;
298         }
299
300         wDeviceIndex = 0;
301
302         while (wDeviceIndex < 10)
303         {
304                 wPCIConsultation = pcibios_find_device(HW_ID_EICON_PCI, 
305                                 HW_ID_DIVA_SERVER_P, 
306                                 wDeviceIndex, 
307                                 &byBus, &byFunc);
308
309                 if (wPCIConsultation == PCIBIOS_SUCCESSFUL)
310                 {
311                         dword dwRAM, dwREG, dwCFG;
312                         byte byIRQ;
313
314                         printk(KERN_DEBUG "Divas: DIVA Server PRI Found\n");
315
316                         pcibios_read_config_dword(byBus, byFunc, PCI_BASE_ADDRESS_0, (unsigned int *) &dwRAM);
317                         dwRAM &= 0xFFFFF000;
318
319                         pcibios_read_config_dword(byBus, byFunc, PCI_BASE_ADDRESS_2, (unsigned int *) &dwREG);
320                         dwREG &= 0xFFFFF000;
321                         
322                         pcibios_read_config_dword(byBus, byFunc, PCI_BASE_ADDRESS_4, (unsigned int *) &dwCFG);
323                         dwCFG &= 0xFFFFF000;
324
325                         pcibios_read_config_byte(byBus, byFunc, PCI_INTERRUPT_LINE, &byIRQ);
326
327                         Card.memory[DIVAS_RAM_MEMORY] = ioremap(dwRAM, 0x10000);
328                         Card.memory[DIVAS_REG_MEMORY] = ioremap(dwREG, 0x4000);
329                         Card.memory[DIVAS_CFG_MEMORY] = ioremap(dwCFG, 0x1000);
330                         Card.memory[DIVAS_SHARED_MEMORY] = Card.memory[DIVAS_RAM_MEMORY] + DIVAS_SHARED_OFFSET;
331
332 /*                      pcibios_read_config_dword(byBus, byFunc, PCI_BASE_ADDRESS_1, (unsigned int *) &dwPLXIOBase);
333                         dwPLXIOBase &= 0xFFFFFFFc;
334
335                         pcibios_read_config_dword(byBus, byFunc, PCI_BASE_ADDRESS_2, (unsigned int *) &dwDivasIOBase);
336                         dwDivasIOBase &= 0xFFFFFF80;
337
338                         pcibios_read_config_byte(byBus, byFunc, PCI_INTERRUPT_LINE, &byIRQ);
339 */
340                         Card.card_id = wNumCards;
341                         Card.card_type = DIA_CARD_TYPE_DIVA_SERVER;
342                         Card.bus_type = DIA_BUS_TYPE_PCI;
343                         Card.irq = byIRQ;
344 /*                      Card.reset_base = dwPLXIOBase;
345                         Card.io_base = dwDivasIOBase;*/
346                         Card.bus_num = byBus;
347                         Card.func_num = byFunc;
348                         Card.slot = -1;
349                         Card.name[0] = 'D';
350                         Card.name[1] = 'I';
351                         Card.name[2] = 'V';
352                         Card.name[3] = 'A';
353                         Card.name[4] = 'S';
354                         Card.name[5] = 'P';
355                         Card.name[6] = '\0';
356
357                         if (DivasCardNew(&Card) != 0)
358                         {
359                                 wDeviceIndex++;
360                                 continue;
361                         }
362                         wNumCards++;
363                 }
364
365                 wDeviceIndex++;
366         }
367
368
369         printk(KERN_INFO "Divas: %d cards detected\n", wNumCards);
370
371         if(wNumCards == 0)
372         {
373                 return -1;
374         }
375
376         Divas_fops.ioctl = do_ioctl;
377         Divas_fops.poll = do_poll;
378         Divas_fops.read = do_read;
379         Divas_fops.open = do_open;
380         Divas_fops.release = do_release;
381
382         Divas_major = register_chrdev(0, "Divas", &Divas_fops);
383
384         if (Divas_major < 0)
385         {
386                 printk(KERN_WARNING "Divas: Unable to register character driver\n");
387                 return -1;
388         }
389
390         return 0;
391 }
392
393 /* Error return -1 */
394 int DivasConfigGet(dia_card_t *card)
395 {
396         /* Retrieve Config from O/S? Not in Linux */
397         return 0;
398 }
399
400 dia_config_t *DivasConfig(card_t *card, dia_config_t *config)
401 {
402         /*      If config retrieved from OS then copy the data into a dia_config_t structure here
403                 and return the pointer here. If the config 'came from above' then just 
404
405                         return config;
406         */
407
408         return config;
409 }
410