Version:  2.0.40 2.2.26 2.4.37 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15 3.16 3.17 3.18

Linux/drivers/isdn/hardware/eicon/divasmain.c

  1 /* $Id: divasmain.c,v 1.55.4.6 2005/02/09 19:28:20 armin Exp $
  2  *
  3  * Low level driver for Eicon DIVA Server ISDN cards.
  4  *
  5  * Copyright 2000-2003 by Armin Schindler (mac@melware.de)
  6  * Copyright 2000-2003 Cytronics & Melware (info@melware.de)
  7  *
  8  * This software may be used and distributed according to the terms
  9  * of the GNU General Public License, incorporated herein by reference.
 10  */
 11 
 12 #include <linux/module.h>
 13 #include <linux/init.h>
 14 #include <linux/kernel.h>
 15 #include <asm/uaccess.h>
 16 #include <asm/io.h>
 17 #include <linux/ioport.h>
 18 #include <linux/pci.h>
 19 #include <linux/interrupt.h>
 20 #include <linux/list.h>
 21 #include <linux/poll.h>
 22 #include <linux/kmod.h>
 23 
 24 #include "platform.h"
 25 #undef ID_MASK
 26 #undef N_DATA
 27 #include "pc.h"
 28 #include "di_defs.h"
 29 #include "divasync.h"
 30 #include "diva.h"
 31 #include "di.h"
 32 #include "io.h"
 33 #include "xdi_msg.h"
 34 #include "xdi_adapter.h"
 35 #include "xdi_vers.h"
 36 #include "diva_dma.h"
 37 #include "diva_pci.h"
 38 
 39 static char *main_revision = "$Revision: 1.55.4.6 $";
 40 
 41 static int major;
 42 
 43 static int dbgmask;
 44 
 45 MODULE_DESCRIPTION("Kernel driver for Eicon DIVA Server cards");
 46 MODULE_AUTHOR("Cytronics & Melware, Eicon Networks");
 47 MODULE_LICENSE("GPL");
 48 
 49 module_param(dbgmask, int, 0);
 50 MODULE_PARM_DESC(dbgmask, "initial debug mask");
 51 
 52 static char *DRIVERNAME =
 53         "Eicon DIVA Server driver (http://www.melware.net)";
 54 static char *DRIVERLNAME = "divas";
 55 static char *DEVNAME = "Divas";
 56 char *DRIVERRELEASE_DIVAS = "2.0";
 57 
 58 extern irqreturn_t diva_os_irq_wrapper(int irq, void *context);
 59 extern int create_divas_proc(void);
 60 extern void remove_divas_proc(void);
 61 extern void diva_get_vserial_number(PISDN_ADAPTER IoAdapter, char *buf);
 62 extern int divasfunc_init(int dbgmask);
 63 extern void divasfunc_exit(void);
 64 
 65 typedef struct _diva_os_thread_dpc {
 66         struct tasklet_struct divas_task;
 67         diva_os_soft_isr_t *psoft_isr;
 68 } diva_os_thread_dpc_t;
 69 
 70 /* --------------------------------------------------------------------------
 71    PCI driver interface section
 72    -------------------------------------------------------------------------- */
 73 /*
 74   vendor, device        Vendor and device ID to match (or PCI_ANY_ID)
 75   subvendor,    Subsystem vendor and device ID to match (or PCI_ANY_ID)
 76   subdevice
 77   class,                Device class to match. The class_mask tells which bits
 78   class_mask    of the class are honored during the comparison.
 79   driver_data   Data private to the driver.
 80 */
 81 
 82 #if !defined(PCI_DEVICE_ID_EICON_MAESTRAP_2)
 83 #define PCI_DEVICE_ID_EICON_MAESTRAP_2       0xE015
 84 #endif
 85 
 86 #if !defined(PCI_DEVICE_ID_EICON_4BRI_VOIP)
 87 #define PCI_DEVICE_ID_EICON_4BRI_VOIP        0xE016
 88 #endif
 89 
 90 #if !defined(PCI_DEVICE_ID_EICON_4BRI_2_VOIP)
 91 #define PCI_DEVICE_ID_EICON_4BRI_2_VOIP      0xE017
 92 #endif
 93 
 94 #if !defined(PCI_DEVICE_ID_EICON_BRI2M_2)
 95 #define PCI_DEVICE_ID_EICON_BRI2M_2          0xE018
 96 #endif
 97 
 98 #if !defined(PCI_DEVICE_ID_EICON_MAESTRAP_2_VOIP)
 99 #define PCI_DEVICE_ID_EICON_MAESTRAP_2_VOIP  0xE019
100 #endif
101 
102 #if !defined(PCI_DEVICE_ID_EICON_2F)
103 #define PCI_DEVICE_ID_EICON_2F               0xE01A
104 #endif
105 
106 #if !defined(PCI_DEVICE_ID_EICON_BRI2M_2_VOIP)
107 #define PCI_DEVICE_ID_EICON_BRI2M_2_VOIP     0xE01B
108 #endif
109 
110 /*
111   This table should be sorted by PCI device ID
112 */
113 static struct pci_device_id divas_pci_tbl[] = {
114         /* Diva Server BRI-2M PCI 0xE010 */
115         { PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_MAESTRA),
116           CARDTYPE_MAESTRA_PCI },
117         /* Diva Server 4BRI-8M PCI 0xE012 */
118         { PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_MAESTRAQ),
119           CARDTYPE_DIVASRV_Q_8M_PCI },
120         /* Diva Server 4BRI-8M 2.0 PCI 0xE013 */
121         { PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_MAESTRAQ_U),
122           CARDTYPE_DIVASRV_Q_8M_V2_PCI },
123         /* Diva Server PRI-30M PCI 0xE014 */
124         { PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_MAESTRAP),
125           CARDTYPE_DIVASRV_P_30M_PCI },
126         /* Diva Server PRI 2.0 adapter 0xE015 */
127         { PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_MAESTRAP_2),
128           CARDTYPE_DIVASRV_P_30M_V2_PCI },
129         /* Diva Server Voice 4BRI-8M PCI 0xE016 */
130         { PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_4BRI_VOIP),
131           CARDTYPE_DIVASRV_VOICE_Q_8M_PCI },
132         /* Diva Server Voice 4BRI-8M 2.0 PCI 0xE017 */
133         { PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_4BRI_2_VOIP),
134           CARDTYPE_DIVASRV_VOICE_Q_8M_V2_PCI },
135         /* Diva Server BRI-2M 2.0 PCI 0xE018 */
136         { PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_BRI2M_2),
137           CARDTYPE_DIVASRV_B_2M_V2_PCI },
138         /* Diva Server Voice PRI 2.0 PCI 0xE019 */
139         { PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_MAESTRAP_2_VOIP),
140           CARDTYPE_DIVASRV_VOICE_P_30M_V2_PCI },
141         /* Diva Server 2FX 0xE01A */
142         { PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_2F),
143           CARDTYPE_DIVASRV_B_2F_PCI },
144         /* Diva Server Voice BRI-2M 2.0 PCI 0xE01B */
145         { PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_BRI2M_2_VOIP),
146           CARDTYPE_DIVASRV_VOICE_B_2M_V2_PCI },
147         { 0, }                  /* 0 terminated list. */
148 };
149 MODULE_DEVICE_TABLE(pci, divas_pci_tbl);
150 
151 static int divas_init_one(struct pci_dev *pdev,
152                           const struct pci_device_id *ent);
153 static void divas_remove_one(struct pci_dev *pdev);
154 
155 static struct pci_driver diva_pci_driver = {
156         .name     = "divas",
157         .probe    = divas_init_one,
158         .remove   = divas_remove_one,
159         .id_table = divas_pci_tbl,
160 };
161 
162 /*********************************************************
163  ** little helper functions
164  *********************************************************/
165 static char *getrev(const char *revision)
166 {
167         char *rev;
168         char *p;
169         if ((p = strchr(revision, ':'))) {
170                 rev = p + 2;
171                 p = strchr(rev, '$');
172                 *--p = 0;
173         } else
174                 rev = "1.0";
175         return rev;
176 }
177 
178 void diva_log_info(unsigned char *format, ...)
179 {
180         va_list args;
181         unsigned char line[160];
182 
183         va_start(args, format);
184         vsnprintf(line, sizeof(line), format, args);
185         va_end(args);
186 
187         printk(KERN_INFO "%s: %s\n", DRIVERLNAME, line);
188 }
189 
190 void divas_get_version(char *p)
191 {
192         char tmprev[32];
193 
194         strcpy(tmprev, main_revision);
195         sprintf(p, "%s: %s(%s) %s(%s) major=%d\n", DRIVERLNAME, DRIVERRELEASE_DIVAS,
196                 getrev(tmprev), diva_xdi_common_code_build, DIVA_BUILD, major);
197 }
198 
199 /* --------------------------------------------------------------------------
200    PCI Bus services
201    -------------------------------------------------------------------------- */
202 byte diva_os_get_pci_bus(void *pci_dev_handle)
203 {
204         struct pci_dev *pdev = (struct pci_dev *) pci_dev_handle;
205         return ((byte) pdev->bus->number);
206 }
207 
208 byte diva_os_get_pci_func(void *pci_dev_handle)
209 {
210         struct pci_dev *pdev = (struct pci_dev *) pci_dev_handle;
211         return ((byte) pdev->devfn);
212 }
213 
214 unsigned long divasa_get_pci_irq(unsigned char bus, unsigned char func,
215                                  void *pci_dev_handle)
216 {
217         unsigned char irq = 0;
218         struct pci_dev *dev = (struct pci_dev *) pci_dev_handle;
219 
220         irq = dev->irq;
221 
222         return ((unsigned long) irq);
223 }
224 
225 unsigned long divasa_get_pci_bar(unsigned char bus, unsigned char func,
226                                  int bar, void *pci_dev_handle)
227 {
228         unsigned long ret = 0;
229         struct pci_dev *dev = (struct pci_dev *) pci_dev_handle;
230 
231         if (bar < 6) {
232                 ret = dev->resource[bar].start;
233         }
234 
235         DBG_TRC(("GOT BAR[%d]=%08x", bar, ret));
236 
237         {
238                 unsigned long type = (ret & 0x00000001);
239                 if (type & PCI_BASE_ADDRESS_SPACE_IO) {
240                         DBG_TRC(("  I/O"));
241                         ret &= PCI_BASE_ADDRESS_IO_MASK;
242                 } else {
243                         DBG_TRC(("  memory"));
244                         ret &= PCI_BASE_ADDRESS_MEM_MASK;
245                 }
246                 DBG_TRC(("  final=%08x", ret));
247         }
248 
249         return (ret);
250 }
251 
252 void PCIwrite(byte bus, byte func, int offset, void *data, int length,
253               void *pci_dev_handle)
254 {
255         struct pci_dev *dev = (struct pci_dev *) pci_dev_handle;
256 
257         switch (length) {
258         case 1:         /* byte */
259                 pci_write_config_byte(dev, offset,
260                                       *(unsigned char *) data);
261                 break;
262         case 2:         /* word */
263                 pci_write_config_word(dev, offset,
264                                       *(unsigned short *) data);
265                 break;
266         case 4:         /* dword */
267                 pci_write_config_dword(dev, offset,
268                                        *(unsigned int *) data);
269                 break;
270 
271         default:                /* buffer */
272                 if (!(length % 4) && !(length & 0x03)) {        /* Copy as dword */
273                         dword *p = (dword *) data;
274                         length /= 4;
275 
276                         while (length--) {
277                                 pci_write_config_dword(dev, offset,
278                                                        *(unsigned int *)
279                                                        p++);
280                         }
281                 } else {        /* copy as byte stream */
282                         byte *p = (byte *) data;
283 
284                         while (length--) {
285                                 pci_write_config_byte(dev, offset,
286                                                       *(unsigned char *)
287                                                       p++);
288                         }
289                 }
290         }
291 }
292 
293 void PCIread(byte bus, byte func, int offset, void *data, int length,
294              void *pci_dev_handle)
295 {
296         struct pci_dev *dev = (struct pci_dev *) pci_dev_handle;
297 
298         switch (length) {
299         case 1:         /* byte */
300                 pci_read_config_byte(dev, offset, (unsigned char *) data);
301                 break;
302         case 2:         /* word */
303                 pci_read_config_word(dev, offset, (unsigned short *) data);
304                 break;
305         case 4:         /* dword */
306                 pci_read_config_dword(dev, offset, (unsigned int *) data);
307                 break;
308 
309         default:                /* buffer */
310                 if (!(length % 4) && !(length & 0x03)) {        /* Copy as dword */
311                         dword *p = (dword *) data;
312                         length /= 4;
313 
314                         while (length--) {
315                                 pci_read_config_dword(dev, offset,
316                                                       (unsigned int *)
317                                                       p++);
318                         }
319                 } else {        /* copy as byte stream */
320                         byte *p = (byte *) data;
321 
322                         while (length--) {
323                                 pci_read_config_byte(dev, offset,
324                                                      (unsigned char *)
325                                                      p++);
326                         }
327                 }
328         }
329 }
330 
331 /*
332   Init map with DMA pages. It is not problem if some allocations fail -
333   the channels that will not get one DMA page will use standard PIO
334   interface
335 */
336 static void *diva_pci_alloc_consistent(struct pci_dev *hwdev,
337                                        size_t size,
338                                        dma_addr_t *dma_handle,
339                                        void **addr_handle)
340 {
341         void *addr = pci_alloc_consistent(hwdev, size, dma_handle);
342 
343         *addr_handle = addr;
344 
345         return (addr);
346 }
347 
348 void diva_init_dma_map(void *hdev,
349                        struct _diva_dma_map_entry **ppmap, int nentries)
350 {
351         struct pci_dev *pdev = (struct pci_dev *) hdev;
352         struct _diva_dma_map_entry *pmap =
353                 diva_alloc_dma_map(hdev, nentries);
354 
355         if (pmap) {
356                 int i;
357                 dma_addr_t dma_handle;
358                 void *cpu_addr;
359                 void *addr_handle;
360 
361                 for (i = 0; i < nentries; i++) {
362                         if (!(cpu_addr = diva_pci_alloc_consistent(pdev,
363                                                                    PAGE_SIZE,
364                                                                    &dma_handle,
365                                                                    &addr_handle)))
366                         {
367                                 break;
368                         }
369                         diva_init_dma_map_entry(pmap, i, cpu_addr,
370                                                 (dword) dma_handle,
371                                                 addr_handle);
372                         DBG_TRC(("dma map alloc [%d]=(%08lx:%08x:%08lx)",
373                                  i, (unsigned long) cpu_addr,
374                                  (dword) dma_handle,
375                                  (unsigned long) addr_handle))}
376         }
377 
378         *ppmap = pmap;
379 }
380 
381 /*
382   Free all contained in the map entries and memory used by the map
383   Should be always called after adapter removal from DIDD array
384 */
385 void diva_free_dma_map(void *hdev, struct _diva_dma_map_entry *pmap)
386 {
387         struct pci_dev *pdev = (struct pci_dev *) hdev;
388         int i;
389         dword phys_addr;
390         void *cpu_addr;
391         dma_addr_t dma_handle;
392         void *addr_handle;
393 
394         for (i = 0; (pmap != NULL); i++) {
395                 diva_get_dma_map_entry(pmap, i, &cpu_addr, &phys_addr);
396                 if (!cpu_addr) {
397                         break;
398                 }
399                 addr_handle = diva_get_entry_handle(pmap, i);
400                 dma_handle = (dma_addr_t) phys_addr;
401                 pci_free_consistent(pdev, PAGE_SIZE, addr_handle,
402                                     dma_handle);
403                 DBG_TRC(("dma map free [%d]=(%08lx:%08x:%08lx)", i,
404                          (unsigned long) cpu_addr, (dword) dma_handle,
405                          (unsigned long) addr_handle))
406                         }
407 
408         diva_free_dma_mapping(pmap);
409 }
410 
411 
412 /*********************************************************
413  ** I/O port utilities
414  *********************************************************/
415 
416 int
417 diva_os_register_io_port(void *adapter, int on, unsigned long port,
418                          unsigned long length, const char *name, int id)
419 {
420         if (on) {
421                 if (!request_region(port, length, name)) {
422                         DBG_ERR(("A: I/O: can't register port=%08x", port))
423                                 return (-1);
424                 }
425         } else {
426                 release_region(port, length);
427         }
428         return (0);
429 }
430 
431 void __iomem *divasa_remap_pci_bar(diva_os_xdi_adapter_t *a, int id, unsigned long bar, unsigned long area_length)
432 {
433         void __iomem *ret = ioremap(bar, area_length);
434         DBG_TRC(("remap(%08x)->%p", bar, ret));
435         return (ret);
436 }
437 
438 void divasa_unmap_pci_bar(void __iomem *bar)
439 {
440         if (bar) {
441                 iounmap(bar);
442         }
443 }
444 
445 /*********************************************************
446  ** I/O port access
447  *********************************************************/
448 byte __inline__ inpp(void __iomem *addr)
449 {
450         return (inb((unsigned long) addr));
451 }
452 
453 word __inline__ inppw(void __iomem *addr)
454 {
455         return (inw((unsigned long) addr));
456 }
457 
458 void __inline__ inppw_buffer(void __iomem *addr, void *P, int length)
459 {
460         insw((unsigned long) addr, (word *) P, length >> 1);
461 }
462 
463 void __inline__ outppw_buffer(void __iomem *addr, void *P, int length)
464 {
465         outsw((unsigned long) addr, (word *) P, length >> 1);
466 }
467 
468 void __inline__ outppw(void __iomem *addr, word w)
469 {
470         outw(w, (unsigned long) addr);
471 }
472 
473 void __inline__ outpp(void __iomem *addr, word p)
474 {
475         outb(p, (unsigned long) addr);
476 }
477 
478 /* --------------------------------------------------------------------------
479    IRQ request / remove
480    -------------------------------------------------------------------------- */
481 int diva_os_register_irq(void *context, byte irq, const char *name)
482 {
483         int result = request_irq(irq, diva_os_irq_wrapper,
484                                  IRQF_SHARED, name, context);
485         return (result);
486 }
487 
488 void diva_os_remove_irq(void *context, byte irq)
489 {
490         free_irq(irq, context);
491 }
492 
493 /* --------------------------------------------------------------------------
494    DPC framework implementation
495    -------------------------------------------------------------------------- */
496 static void diva_os_dpc_proc(unsigned long context)
497 {
498         diva_os_thread_dpc_t *psoft_isr = (diva_os_thread_dpc_t *) context;
499         diva_os_soft_isr_t *pisr = psoft_isr->psoft_isr;
500 
501         (*(pisr->callback)) (pisr, pisr->callback_context);
502 }
503 
504 int diva_os_initialize_soft_isr(diva_os_soft_isr_t *psoft_isr,
505                                 diva_os_soft_isr_callback_t callback,
506                                 void *callback_context)
507 {
508         diva_os_thread_dpc_t *pdpc;
509 
510         pdpc = (diva_os_thread_dpc_t *) diva_os_malloc(0, sizeof(*pdpc));
511         if (!(psoft_isr->object = pdpc)) {
512                 return (-1);
513         }
514         memset(pdpc, 0x00, sizeof(*pdpc));
515         psoft_isr->callback = callback;
516         psoft_isr->callback_context = callback_context;
517         pdpc->psoft_isr = psoft_isr;
518         tasklet_init(&pdpc->divas_task, diva_os_dpc_proc, (unsigned long)pdpc);
519 
520         return (0);
521 }
522 
523 int diva_os_schedule_soft_isr(diva_os_soft_isr_t *psoft_isr)
524 {
525         if (psoft_isr && psoft_isr->object) {
526                 diva_os_thread_dpc_t *pdpc =
527                         (diva_os_thread_dpc_t *) psoft_isr->object;
528 
529                 tasklet_schedule(&pdpc->divas_task);
530         }
531 
532         return (1);
533 }
534 
535 int diva_os_cancel_soft_isr(diva_os_soft_isr_t *psoft_isr)
536 {
537         return (0);
538 }
539 
540 void diva_os_remove_soft_isr(diva_os_soft_isr_t *psoft_isr)
541 {
542         if (psoft_isr && psoft_isr->object) {
543                 diva_os_thread_dpc_t *pdpc =
544                         (diva_os_thread_dpc_t *) psoft_isr->object;
545                 void *mem;
546 
547                 tasklet_kill(&pdpc->divas_task);
548                 mem = psoft_isr->object;
549                 psoft_isr->object = NULL;
550                 diva_os_free(0, mem);
551         }
552 }
553 
554 /*
555  * kernel/user space copy functions
556  */
557 static int
558 xdi_copy_to_user(void *os_handle, void __user *dst, const void *src, int length)
559 {
560         if (copy_to_user(dst, src, length)) {
561                 return (-EFAULT);
562         }
563         return (length);
564 }
565 
566 static int
567 xdi_copy_from_user(void *os_handle, void *dst, const void __user *src, int length)
568 {
569         if (copy_from_user(dst, src, length)) {
570                 return (-EFAULT);
571         }
572         return (length);
573 }
574 
575 /*
576  * device node operations
577  */
578 static int divas_open(struct inode *inode, struct file *file)
579 {
580         return (0);
581 }
582 
583 static int divas_release(struct inode *inode, struct file *file)
584 {
585         if (file->private_data) {
586                 diva_xdi_close_adapter(file->private_data, file);
587         }
588         return (0);
589 }
590 
591 static ssize_t divas_write(struct file *file, const char __user *buf,
592                            size_t count, loff_t *ppos)
593 {
594         int ret = -EINVAL;
595 
596         if (!file->private_data) {
597                 file->private_data = diva_xdi_open_adapter(file, buf,
598                                                            count,
599                                                            xdi_copy_from_user);
600         }
601         if (!file->private_data) {
602                 return (-ENODEV);
603         }
604 
605         ret = diva_xdi_write(file->private_data, file,
606                              buf, count, xdi_copy_from_user);
607         switch (ret) {
608         case -1:                /* Message should be removed from rx mailbox first */
609                 ret = -EBUSY;
610                 break;
611         case -2:                /* invalid adapter was specified in this call */
612                 ret = -ENOMEM;
613                 break;
614         case -3:
615                 ret = -ENXIO;
616                 break;
617         }
618         DBG_TRC(("write: ret %d", ret));
619         return (ret);
620 }
621 
622 static ssize_t divas_read(struct file *file, char __user *buf,
623                           size_t count, loff_t *ppos)
624 {
625         int ret = -EINVAL;
626 
627         if (!file->private_data) {
628                 file->private_data = diva_xdi_open_adapter(file, buf,
629                                                            count,
630                                                            xdi_copy_from_user);
631         }
632         if (!file->private_data) {
633                 return (-ENODEV);
634         }
635 
636         ret = diva_xdi_read(file->private_data, file,
637                             buf, count, xdi_copy_to_user);
638         switch (ret) {
639         case -1:                /* RX mailbox is empty */
640                 ret = -EAGAIN;
641                 break;
642         case -2:                /* no memory, mailbox was cleared, last command is failed */
643                 ret = -ENOMEM;
644                 break;
645         case -3:                /* can't copy to user, retry */
646                 ret = -EFAULT;
647                 break;
648         }
649         DBG_TRC(("read: ret %d", ret));
650         return (ret);
651 }
652 
653 static unsigned int divas_poll(struct file *file, poll_table *wait)
654 {
655         if (!file->private_data) {
656                 return (POLLERR);
657         }
658         return (POLLIN | POLLRDNORM);
659 }
660 
661 static const struct file_operations divas_fops = {
662         .owner   = THIS_MODULE,
663         .llseek  = no_llseek,
664         .read    = divas_read,
665         .write   = divas_write,
666         .poll    = divas_poll,
667         .open    = divas_open,
668         .release = divas_release
669 };
670 
671 static void divas_unregister_chrdev(void)
672 {
673         unregister_chrdev(major, DEVNAME);
674 }
675 
676 static int __init divas_register_chrdev(void)
677 {
678         if ((major = register_chrdev(0, DEVNAME, &divas_fops)) < 0)
679         {
680                 printk(KERN_ERR "%s: failed to create /dev entry.\n",
681                        DRIVERLNAME);
682                 return (0);
683         }
684 
685         return (1);
686 }
687 
688 /* --------------------------------------------------------------------------
689    PCI driver section
690    -------------------------------------------------------------------------- */
691 static int divas_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
692 {
693         void *pdiva = NULL;
694         u8 pci_latency;
695         u8 new_latency = 32;
696 
697         DBG_TRC(("%s bus: %08x fn: %08x insertion.\n",
698                  CardProperties[ent->driver_data].Name,
699                  pdev->bus->number, pdev->devfn))
700                 printk(KERN_INFO "%s: %s bus: %08x fn: %08x insertion.\n",
701                        DRIVERLNAME, CardProperties[ent->driver_data].Name,
702                        pdev->bus->number, pdev->devfn);
703 
704         if (pci_enable_device(pdev)) {
705                 DBG_TRC(("%s: %s bus: %08x fn: %08x device init failed.\n",
706                          DRIVERLNAME,
707                          CardProperties[ent->driver_data].Name,
708                          pdev->bus->number,
709                          pdev->devfn))
710                         printk(KERN_ERR
711                                "%s: %s bus: %08x fn: %08x device init failed.\n",
712                                DRIVERLNAME,
713                                CardProperties[ent->driver_data].
714                                Name, pdev->bus->number,
715                                pdev->devfn);
716                 return (-EIO);
717         }
718 
719         pci_set_master(pdev);
720 
721         pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &pci_latency);
722         if (!pci_latency) {
723                 DBG_TRC(("%s: bus: %08x fn: %08x fix latency.\n",
724                          DRIVERLNAME, pdev->bus->number, pdev->devfn))
725                         printk(KERN_INFO
726                                "%s: bus: %08x fn: %08x fix latency.\n",
727                                DRIVERLNAME, pdev->bus->number, pdev->devfn);
728                 pci_write_config_byte(pdev, PCI_LATENCY_TIMER, new_latency);
729         }
730 
731         if (!(pdiva = diva_driver_add_card(pdev, ent->driver_data))) {
732                 DBG_TRC(("%s: %s bus: %08x fn: %08x card init failed.\n",
733                          DRIVERLNAME,
734                          CardProperties[ent->driver_data].Name,
735                          pdev->bus->number,
736                          pdev->devfn))
737                         printk(KERN_ERR
738                                "%s: %s bus: %08x fn: %08x card init failed.\n",
739                                DRIVERLNAME,
740                                CardProperties[ent->driver_data].
741                                Name, pdev->bus->number,
742                                pdev->devfn);
743                 return (-EIO);
744         }
745 
746         pci_set_drvdata(pdev, pdiva);
747 
748         return (0);
749 }
750 
751 static void divas_remove_one(struct pci_dev *pdev)
752 {
753         void *pdiva = pci_get_drvdata(pdev);
754 
755         DBG_TRC(("bus: %08x fn: %08x removal.\n",
756                  pdev->bus->number, pdev->devfn))
757                 printk(KERN_INFO "%s: bus: %08x fn: %08x removal.\n",
758                        DRIVERLNAME, pdev->bus->number, pdev->devfn);
759 
760         if (pdiva) {
761                 diva_driver_remove_card(pdiva);
762         }
763 
764 }
765 
766 /* --------------------------------------------------------------------------
767    Driver Load / Startup
768    -------------------------------------------------------------------------- */
769 static int __init divas_init(void)
770 {
771         char tmprev[50];
772         int ret = 0;
773 
774         printk(KERN_INFO "%s\n", DRIVERNAME);
775         printk(KERN_INFO "%s: Rel:%s  Rev:", DRIVERLNAME, DRIVERRELEASE_DIVAS);
776         strcpy(tmprev, main_revision);
777         printk("%s  Build: %s(%s)\n", getrev(tmprev),
778                diva_xdi_common_code_build, DIVA_BUILD);
779         printk(KERN_INFO "%s: support for: ", DRIVERLNAME);
780 #ifdef CONFIG_ISDN_DIVAS_BRIPCI
781         printk("BRI/PCI ");
782 #endif
783 #ifdef CONFIG_ISDN_DIVAS_PRIPCI
784         printk("PRI/PCI ");
785 #endif
786         printk("adapters\n");
787 
788         if (!divasfunc_init(dbgmask)) {
789                 printk(KERN_ERR "%s: failed to connect to DIDD.\n",
790                        DRIVERLNAME);
791                 ret = -EIO;
792                 goto out;
793         }
794 
795         if (!divas_register_chrdev()) {
796 #ifdef MODULE
797                 divasfunc_exit();
798 #endif
799                 ret = -EIO;
800                 goto out;
801         }
802 
803         if (!create_divas_proc()) {
804 #ifdef MODULE
805                 divas_unregister_chrdev();
806                 divasfunc_exit();
807 #endif
808                 printk(KERN_ERR "%s: failed to create proc entry.\n",
809                        DRIVERLNAME);
810                 ret = -EIO;
811                 goto out;
812         }
813 
814         if ((ret = pci_register_driver(&diva_pci_driver))) {
815 #ifdef MODULE
816                 remove_divas_proc();
817                 divas_unregister_chrdev();
818                 divasfunc_exit();
819 #endif
820                 printk(KERN_ERR "%s: failed to init pci driver.\n",
821                        DRIVERLNAME);
822                 goto out;
823         }
824         printk(KERN_INFO "%s: started with major %d\n", DRIVERLNAME, major);
825 
826 out:
827         return (ret);
828 }
829 
830 /* --------------------------------------------------------------------------
831    Driver Unload
832    -------------------------------------------------------------------------- */
833 static void __exit divas_exit(void)
834 {
835         pci_unregister_driver(&diva_pci_driver);
836         remove_divas_proc();
837         divas_unregister_chrdev();
838         divasfunc_exit();
839 
840         printk(KERN_INFO "%s: module unloaded.\n", DRIVERLNAME);
841 }
842 
843 module_init(divas_init);
844 module_exit(divas_exit);
845 

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us