eicon_mod.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:44k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /* $Id: eicon_mod.c,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
  2.  *
  3.  * ISDN lowlevel-module for Eicon active cards.
  4.  * 
  5.  * Copyright 1997      by Fritz Elfert (fritz@isdn4linux.de)
  6.  * Copyright 1998-2000 by Armin Schindler (mac@melware.de) 
  7.  * Copyright 1999,2000 Cytronics & Melware (info@melware.de)
  8.  * 
  9.  * This software may be used and distributed according to the terms
  10.  * of the GNU General Public License, incorporated herein by reference.
  11.  *
  12.  * Thanks to    Eicon Networks for
  13.  *              documents, informations and hardware.
  14.  *
  15.  * Deutsche Mailbox Saar-Lor-Lux GmbH
  16.  * for sponsoring and testing fax
  17.  * capabilities with Diva Server cards.
  18.  * (dor@deutschemailbox.de)
  19.  *
  20.  */
  21. #define DRIVERNAME "Eicon active ISDN driver"
  22. #define DRIVERRELEASE "2.0"
  23. #define DRIVERPATCH ".16"
  24. #include <linux/config.h>
  25. #include <linux/module.h>
  26. #include <linux/init.h>
  27. #ifdef CONFIG_MCA
  28. #include <linux/mca.h>
  29. #endif /* CONFIG_MCA */
  30. #include "eicon.h"
  31. #include "../avmb1/capicmd.h"  /* this should be moved in a common place */
  32. #undef N_DATA
  33. #include "adapter.h"
  34. #include "uxio.h"
  35. #define INCLUDE_INLINE_FUNCS
  36. static eicon_card *cards = (eicon_card *) NULL;   /* glob. var , contains
  37.                                                      start of card-list   */
  38. static char *eicon_revision = "$Revision: 1.1.4.1 $";
  39. extern char *eicon_pci_revision;
  40. extern char *eicon_isa_revision;
  41. extern char *eicon_idi_revision;
  42. extern int do_ioctl(struct inode *pDivasInode, struct file *pDivasFile,
  43. unsigned int command, unsigned long arg);
  44. extern void eicon_pci_init_conf(eicon_card *card);
  45. #ifdef MODULE
  46. #define MOD_USE_COUNT (GET_USE_COUNT (&__this_module))
  47. #endif
  48. #define EICON_CTRL_VERSION 2 
  49. ulong DebugVar;
  50. spinlock_t eicon_lock;
  51. DESCRIPTOR idi_d[32];
  52. /* Parameters to be set by insmod */
  53. #ifdef CONFIG_ISDN_DRV_EICON_ISA
  54. static int   membase      = -1;
  55. static int   irq          = -1;
  56. #endif
  57. static char *id           = "";
  58. MODULE_DESCRIPTION(             "ISDN4Linux: Driver for Eicon active ISDN cards");
  59. MODULE_AUTHOR(                  "Armin Schindler");
  60. MODULE_LICENSE(                 "GPL");
  61. MODULE_PARM_DESC(id,    "ID-String of first card");
  62. MODULE_PARM(id,            "s");
  63. #ifdef CONFIG_ISDN_DRV_EICON_ISA
  64. MODULE_PARM_DESC(membase, "Base address of first ISA card");
  65. MODULE_PARM_DESC(irq,     "IRQ of first card");
  66. MODULE_PARM(membase,     "i");
  67. MODULE_PARM(irq,           "i");
  68. #endif
  69. char *eicon_ctype_name[] = {
  70.         "ISDN-S",
  71.         "ISDN-SX",
  72.         "ISDN-SCOM",
  73.         "ISDN-QUADRO",
  74.         "ISDN-S2M",
  75.         "DIVA Server BRI/PCI",
  76.         "DIVA Server 4BRI/PCI",
  77.         "DIVA Server 4BRI/PCI",
  78.         "DIVA Server PRI/PCI"
  79. };
  80. static char *
  81. eicon_getrev(const char *revision)
  82. {
  83. char *rev;
  84. char *p;
  85. if ((p = strchr(revision, ':'))) {
  86. rev = p + 2;
  87. p = strchr(rev, '$');
  88. *--p = 0;
  89. } else rev = "?.??";
  90. return rev;
  91. }
  92. static eicon_chan *
  93. find_channel(eicon_card *card, int channel)
  94. {
  95. if ((channel >= 0) && (channel < card->nchannels))
  96.          return &(card->bch[channel]);
  97. eicon_log(card, 1, "eicon: Invalid channel %dn", channel);
  98. return NULL;
  99. }
  100. #ifdef CONFIG_PCI
  101. #ifdef CONFIG_ISDN_DRV_EICON_PCI
  102. /*
  103.  * Find pcicard with given card number 
  104.  */
  105. static inline eicon_card *
  106. eicon_findnpcicard(int driverid)
  107. {
  108.         eicon_card *p = cards;
  109.         while (p) {
  110.                 if ((p->regname[strlen(p->regname)-1] == (driverid + '0')) &&
  111. (p->bus == EICON_BUS_PCI))
  112.                         return p;
  113.                 p = p->next;
  114.         }
  115.         return (eicon_card *) 0;
  116. }
  117. #endif
  118. #endif /* CONFIG_PCI */
  119. static void
  120. eicon_rcv_dispatch(struct eicon_card *card)
  121. {
  122. switch (card->bus) {
  123. case EICON_BUS_ISA:
  124. case EICON_BUS_MCA:
  125. case EICON_BUS_PCI:
  126. eicon_io_rcv_dispatch(card);
  127. break;
  128. default:
  129. eicon_log(card, 1,
  130.        "eicon_ack_dispatch: Illegal bustype %dn", card->bus);
  131. }
  132. }
  133. static void
  134. eicon_ack_dispatch(struct eicon_card *card)
  135. {
  136. switch (card->bus) {
  137. case EICON_BUS_ISA:
  138. case EICON_BUS_MCA:
  139. case EICON_BUS_PCI:
  140. eicon_io_ack_dispatch(card);
  141. break;
  142. default:
  143. eicon_log(card, 1,
  144.         "eicon_ack_dispatch: Illegal bustype %dn", card->bus);
  145. }
  146. }
  147. static void
  148. eicon_transmit(struct eicon_card *card)
  149. {
  150. switch (card->bus) {
  151. case EICON_BUS_ISA:
  152. case EICON_BUS_MCA:
  153. case EICON_BUS_PCI:
  154. eicon_io_transmit(card);
  155. break;
  156. default:
  157. eicon_log(card, 1,
  158.        "eicon_transmit: Illegal bustype %dn", card->bus);
  159. }
  160. }
  161. static int
  162. eicon_command(eicon_card * card, isdn_ctrl * c)
  163. {
  164.         ulong a;
  165.         eicon_chan *chan;
  166. eicon_cdef cdef;
  167. #ifdef CONFIG_PCI
  168. #ifdef CONFIG_ISDN_DRV_EICON_PCI
  169. dia_start_t dstart;
  170.         int idi_length = 0;
  171. #endif
  172. #endif
  173. isdn_ctrl cmd;
  174. int ret = 0;
  175. unsigned long flags;
  176.  
  177. eicon_log(card, 16, "eicon_cmd 0x%x with arg 0x%lx (0x%lx)n",
  178. c->command, c->arg, (ulong) *c->parm.num);
  179.         switch (c->command) {
  180. case ISDN_CMD_IOCTL:
  181. memcpy(&a, c->parm.num, sizeof(ulong));
  182. switch (c->arg) {
  183. case EICON_IOCTL_GETVER:
  184. return(EICON_CTRL_VERSION);
  185. case EICON_IOCTL_GETTYPE:
  186. if (card->bus == EICON_BUS_PCI) {
  187. copy_to_user((char *)a, &card->hwif.pci.master, sizeof(int));
  188. }
  189. return(card->type);
  190. case EICON_IOCTL_GETMMIO:
  191. switch (card->bus) {
  192. case EICON_BUS_ISA:
  193. case EICON_BUS_MCA:
  194. return (int)card->hwif.isa.shmem;
  195. default:
  196. eicon_log(card, 1,
  197.        "eicon: Illegal BUS type %dn",
  198.        card->bus);
  199. ret = -ENODEV;
  200. }
  201. #ifdef CONFIG_ISDN_DRV_EICON_ISA
  202. case EICON_IOCTL_SETMMIO:
  203. if (card->flags & EICON_FLAGS_LOADED)
  204. return -EBUSY;
  205. switch (card->bus) {
  206. case EICON_BUS_ISA:
  207. if (eicon_isa_find_card(a,
  208. card->hwif.isa.irq,
  209. card->regname) < 0)
  210. return -EFAULT;
  211. card->hwif.isa.shmem = (eicon_isa_shmem *)a;
  212. return 0;
  213. case EICON_BUS_MCA:
  214. #if CONFIG_MCA
  215. if (eicon_mca_find_card(
  216. 0, a,
  217. card->hwif.isa.irq,
  218. card->regname) < 0)
  219. return -EFAULT;
  220. card->hwif.isa.shmem = (eicon_isa_shmem *)a;
  221. return 0;
  222. #endif /* CONFIG_MCA */
  223. default:
  224. eicon_log(card, 1,
  225.        "eicon: Illegal BUS type %dn",
  226.        card->bus);
  227. ret = -ENODEV;
  228. }
  229. #endif
  230. case EICON_IOCTL_GETIRQ:
  231. switch (card->bus) {
  232. case EICON_BUS_ISA:
  233. case EICON_BUS_MCA:
  234. return card->hwif.isa.irq;
  235. default:
  236. eicon_log(card, 1,
  237.        "eicon: Illegal BUS type %dn",
  238.        card->bus);
  239. ret = -ENODEV;
  240. }
  241. case EICON_IOCTL_SETIRQ:
  242. if (card->flags & EICON_FLAGS_LOADED)
  243. return -EBUSY;
  244. if ((a < 2) || (a > 15))
  245. return -EFAULT;
  246. switch (card->bus) {
  247. case EICON_BUS_ISA:
  248. case EICON_BUS_MCA:
  249. card->hwif.isa.irq = a;
  250. return 0;
  251. default:
  252. eicon_log(card, 1,
  253.        "eicon: Illegal BUS type %dn",
  254.        card->bus);
  255. ret = -ENODEV;
  256. }
  257. #ifdef CONFIG_ISDN_DRV_EICON_ISA
  258. case EICON_IOCTL_LOADBOOT:
  259. if (card->flags & EICON_FLAGS_RUNNING)
  260. return -EBUSY;  
  261. switch (card->bus) {
  262. case EICON_BUS_ISA:
  263. case EICON_BUS_MCA:
  264. ret = eicon_isa_bootload(
  265. &(card->hwif.isa),
  266. &(((eicon_codebuf *)a)->isa));
  267. break;
  268. default:
  269. eicon_log(card, 1,
  270.        "eicon: Illegal BUS type %dn",
  271.        card->bus);
  272. ret = -ENODEV;
  273. }
  274. return ret;
  275. #endif
  276. #ifdef CONFIG_ISDN_DRV_EICON_ISA
  277. case EICON_IOCTL_LOADISA:
  278. if (card->flags & EICON_FLAGS_RUNNING)
  279. return -EBUSY;  
  280. switch (card->bus) {
  281. case EICON_BUS_ISA:
  282. case EICON_BUS_MCA:
  283. ret = eicon_isa_load(
  284. &(card->hwif.isa),
  285. &(((eicon_codebuf *)a)->isa));
  286. if (!ret) {
  287.                                                                 card->flags |= EICON_FLAGS_LOADED;
  288.                                                                 card->flags |= EICON_FLAGS_RUNNING;
  289. if (card->hwif.isa.channels > 1) {
  290. cmd.command = ISDN_STAT_ADDCH;
  291. cmd.driver = card->myid;
  292. cmd.arg = card->hwif.isa.channels - 1;
  293. card->interface.statcallb(&cmd);
  294. }
  295. cmd.command = ISDN_STAT_RUN;    
  296. cmd.driver = card->myid;        
  297. cmd.arg = 0;                    
  298. card->interface.statcallb(&cmd);
  299. }
  300. break;
  301. default:
  302. eicon_log(card, 1,
  303.        "eicon: Illegal BUS type %dn",
  304.        card->bus);
  305. ret = -ENODEV;
  306. }
  307. return ret;
  308. #endif
  309. case EICON_IOCTL_MANIF:
  310. if (!card->flags & EICON_FLAGS_RUNNING)
  311. return -ENODEV;
  312. if (!card->d)
  313. return -ENODEV;
  314. if (!card->d->features & DI_MANAGE)
  315. return -ENODEV;
  316. ret = eicon_idi_manage(
  317. card, 
  318. (eicon_manifbuf *)a);
  319. return ret;
  320. case EICON_IOCTL_GETXLOG:
  321. return -ENODEV;
  322. case EICON_IOCTL_ADDCARD:
  323. if ((ret = copy_from_user(&cdef, (char *)a, sizeof(cdef))))
  324. return -EFAULT;
  325. if (!(eicon_addcard(0, cdef.membase, cdef.irq, cdef.id, 0)))
  326. return -EIO;
  327. return 0;
  328. case EICON_IOCTL_DEBUGVAR:
  329. DebugVar = a;
  330. eicon_log(card, 1, "Eicon: Debug Value set to %ldn", DebugVar);
  331. return 0;
  332. #ifdef MODULE
  333. case EICON_IOCTL_FREEIT:
  334. while (MOD_USE_COUNT > 0) MOD_DEC_USE_COUNT;
  335. MOD_INC_USE_COUNT;
  336. return 0;
  337. #endif
  338. case EICON_IOCTL_LOADPCI:
  339. eicon_log(card, 1, "Eicon: Wrong version of load-utility,n");
  340. eicon_log(card, 1, "Eicon: re-compile eiconctrl !n");
  341. eicon_log(card, 1, "Eicon: Maybe update of utility is necessary !n");
  342. return -EINVAL;
  343. default:
  344. #ifdef CONFIG_PCI
  345. #ifdef CONFIG_ISDN_DRV_EICON_PCI
  346. if (c->arg < EICON_IOCTL_DIA_OFFSET)
  347. return -EINVAL;
  348. if (copy_from_user(&dstart, (char *)a, sizeof(dstart)))
  349. return -1;
  350. if (!(card = eicon_findnpcicard(dstart.card_id)))
  351. return -EINVAL;
  352. ret = do_ioctl(NULL, NULL,
  353. c->arg - EICON_IOCTL_DIA_OFFSET,
  354. (unsigned long) a);
  355. if (((c->arg - EICON_IOCTL_DIA_OFFSET)==DIA_IOCTL_START) && (!ret)) {
  356. if (card->type != EICON_CTYPE_MAESTRAQ) {
  357. DIVA_DIDD_Read(idi_d, sizeof(idi_d));
  358.                                                         for(idi_length = 0; idi_length < 32; idi_length++) {
  359.                                                           if (idi_d[idi_length].type == 0) break;
  360.                                                         }
  361.                                                         if ((idi_length < 1) || (idi_length >= 32)) {
  362.                   eicon_log(card, 1, "eicon: invalid idi table length.n");
  363.                                                           break;
  364.                                                         }
  365. card->d = &idi_d[idi_length - 1];
  366. card->flags |= EICON_FLAGS_LOADED;
  367. card->flags |= EICON_FLAGS_RUNNING;
  368. eicon_pci_init_conf(card);
  369. if (card->d->channels > 1) {
  370. cmd.command = ISDN_STAT_ADDCH;
  371. cmd.driver = card->myid;
  372. cmd.arg = card->d->channels - 1;
  373. card->interface.statcallb(&cmd);
  374. }
  375. cmd.command = ISDN_STAT_RUN;    
  376. cmd.driver = card->myid;        
  377. cmd.arg = 0;                    
  378. card->interface.statcallb(&cmd);
  379. eicon_log(card, 1, "Eicon: %s started, %d channels (feat. 0x%x)n",
  380. (card->type == EICON_CTYPE_MAESTRA) ? "BRI" : "PRI",
  381. card->d->channels, card->d->features);
  382. } else {
  383. int i;
  384. DIVA_DIDD_Read(idi_d, sizeof(idi_d));
  385.                                                         for(idi_length = 0; idi_length < 32; idi_length++)
  386.                                                           if (idi_d[idi_length].type == 0) break;
  387.                                                         if ((idi_length < 1) || (idi_length >= 32)) {
  388.                   eicon_log(card, 1, "eicon: invalid idi table length.n");
  389.                                                           break;
  390.                                                         }
  391.          for(i = 3; i >= 0; i--) {
  392. if (!(card = eicon_findnpcicard(dstart.card_id - i)))
  393. return -EINVAL;
  394. card->flags |= EICON_FLAGS_LOADED;
  395. card->flags |= EICON_FLAGS_RUNNING;
  396. card->d = &idi_d[idi_length - (i+1)];
  397. eicon_pci_init_conf(card);
  398. if (card->d->channels > 1) {
  399. cmd.command = ISDN_STAT_ADDCH;
  400. cmd.driver = card->myid;
  401. cmd.arg = card->d->channels - 1;
  402. card->interface.statcallb(&cmd);
  403. }
  404. cmd.command = ISDN_STAT_RUN;    
  405. cmd.driver = card->myid;        
  406. cmd.arg = 0;                    
  407. card->interface.statcallb(&cmd);
  408. eicon_log(card, 1, "Eicon: %d/4BRI started, %d channels (feat. 0x%x)n",
  409. 4-i, card->d->channels, card->d->features);
  410. }
  411. }
  412. }
  413. return ret;
  414. #else
  415. return -EINVAL;
  416. #endif
  417. #endif /* CONFIG_PCI */
  418. }
  419. break;
  420. case ISDN_CMD_DIAL:
  421. if (!card->flags & EICON_FLAGS_RUNNING)
  422. return -ENODEV;
  423. if (!(chan = find_channel(card, c->arg & 0x1f)))
  424. break;
  425. spin_lock_irqsave(&eicon_lock, flags);
  426. if ((chan->fsm_state != EICON_STATE_NULL) && (chan->fsm_state != EICON_STATE_LISTEN)) {
  427. spin_unlock_irqrestore(&eicon_lock, flags);
  428. eicon_log(card, 1, "Dial on channel %d with state %dn",
  429. chan->No, chan->fsm_state);
  430. return -EBUSY;
  431. }
  432. chan->fsm_state = EICON_STATE_OCALL;
  433. spin_unlock_irqrestore(&eicon_lock, flags);
  434. ret = idi_connect_req(card, chan, c->parm.setup.phone,
  435.      c->parm.setup.eazmsn,
  436.      c->parm.setup.si1,
  437.      c->parm.setup.si2);
  438. if (ret) {
  439. cmd.driver = card->myid;
  440. cmd.command = ISDN_STAT_DHUP;
  441. cmd.arg &= 0x1f;
  442. card->interface.statcallb(&cmd);
  443. }
  444. return ret;
  445. case ISDN_CMD_ACCEPTD:
  446. if (!card->flags & EICON_FLAGS_RUNNING)
  447. return -ENODEV;
  448. if (!(chan = find_channel(card, c->arg & 0x1f)))
  449. break;
  450. if (chan->fsm_state == EICON_STATE_ICALL) { 
  451. idi_connect_res(card, chan);
  452. }
  453. return 0;
  454. case ISDN_CMD_ACCEPTB:
  455. if (!card->flags & EICON_FLAGS_RUNNING)
  456. return -ENODEV;
  457. return 0;
  458. case ISDN_CMD_HANGUP:
  459. if (!card->flags & EICON_FLAGS_RUNNING)
  460. return -ENODEV;
  461. if (!(chan = find_channel(card, c->arg & 0x1f)))
  462. break;
  463. idi_hangup(card, chan);
  464. return 0;
  465. case ISDN_CMD_SETEAZ:
  466. if (!card->flags & EICON_FLAGS_RUNNING)
  467. return -ENODEV;
  468. if (!(chan = find_channel(card, c->arg & 0x1f)))
  469. break;
  470. chan->eazmask = 0x3ff;
  471. eicon_idi_listen_req(card, chan);
  472. return 0;
  473. case ISDN_CMD_CLREAZ:
  474. if (!card->flags & EICON_FLAGS_RUNNING)
  475. return -ENODEV;
  476. if (!(chan = find_channel(card, c->arg & 0x1f)))
  477. break;
  478. chan->eazmask = 0;
  479. eicon_idi_listen_req(card, chan);
  480. return 0;
  481. case ISDN_CMD_SETL2:
  482. if (!card->flags & EICON_FLAGS_RUNNING)
  483. return -ENODEV;
  484. if (!(chan = find_channel(card, c->arg & 0x1f)))
  485. break;
  486. chan->l2prot = (c->arg >> 8);
  487. return 0;
  488. case ISDN_CMD_GETL2:
  489. if (!card->flags & EICON_FLAGS_RUNNING)
  490. return -ENODEV;
  491. if (!(chan = find_channel(card, c->arg & 0x1f)))
  492. break;
  493. return chan->l2prot;
  494. case ISDN_CMD_SETL3:
  495. if (!card->flags & EICON_FLAGS_RUNNING)
  496. return -ENODEV;
  497. if (!(chan = find_channel(card, c->arg & 0x1f)))
  498. break;
  499. chan->l3prot = (c->arg >> 8);
  500. #ifdef CONFIG_ISDN_TTY_FAX
  501. if (chan->l3prot == ISDN_PROTO_L3_FCLASS2) {
  502. chan->fax = c->parm.fax;
  503. eicon_log(card, 128, "idi_cmd: Ch%d: SETL3 struct fax=0x%xn",chan->No, chan->fax);
  504. }
  505. #endif
  506. return 0;
  507. case ISDN_CMD_GETL3:
  508. if (!card->flags & EICON_FLAGS_RUNNING)
  509. return -ENODEV;
  510. if (!(chan = find_channel(card, c->arg & 0x1f)))
  511. break;
  512. return chan->l3prot;
  513. case ISDN_CMD_GETEAZ:
  514. if (!card->flags & EICON_FLAGS_RUNNING)
  515. return -ENODEV;
  516. eicon_log(card, 1, "eicon CMD_GETEAZ not implementedn");
  517. return 0;
  518. case ISDN_CMD_SETSIL:
  519. if (!card->flags & EICON_FLAGS_RUNNING)
  520. return -ENODEV;
  521. eicon_log(card, 1, "eicon CMD_SETSIL not implementedn");
  522. return 0;
  523. case ISDN_CMD_GETSIL:
  524. if (!card->flags & EICON_FLAGS_RUNNING)
  525. return -ENODEV;
  526. eicon_log(card, 1, "eicon CMD_GETSIL not implementedn");
  527. return 0;
  528. case ISDN_CMD_LOCK:
  529. MOD_INC_USE_COUNT;
  530. return 0;
  531. case ISDN_CMD_UNLOCK:
  532. MOD_DEC_USE_COUNT;
  533. return 0;
  534. #ifdef CONFIG_ISDN_TTY_FAX
  535. case ISDN_CMD_FAXCMD:
  536. if (!card->flags & EICON_FLAGS_RUNNING)
  537. return -ENODEV;
  538. if (!(chan = find_channel(card, c->arg & 0x1f)))
  539. break;
  540. if (!chan->fax)
  541. break;
  542. idi_fax_cmd(card, chan);
  543. return 0;
  544. #endif
  545. case ISDN_CMD_AUDIO:
  546. if (!card->flags & EICON_FLAGS_RUNNING)
  547. return -ENODEV;
  548. if (!(chan = find_channel(card, c->arg & 0x1f)))
  549. break;
  550. idi_audio_cmd(card, chan, c->arg >> 8, c->parm.num);
  551. return 0;
  552. case CAPI_PUT_MESSAGE:
  553. if (!card->flags & EICON_FLAGS_RUNNING)
  554. return -ENODEV;
  555. if (!(chan = find_channel(card, c->arg & 0x1f)))
  556. break;
  557. if (c->parm.cmsg.Length < 8)
  558. break;
  559. switch(c->parm.cmsg.Command) {
  560. case CAPI_FACILITY:
  561. if (c->parm.cmsg.Subcommand == CAPI_REQ)
  562. return(capipmsg(card, chan, &c->parm.cmsg));
  563. break;
  564. case CAPI_MANUFACTURER:
  565. default:
  566. break;
  567. }
  568. return 0;
  569.         }
  570.         return -EINVAL;
  571. }
  572. /*
  573.  * Find card with given driverId
  574.  */
  575. static inline eicon_card *
  576. eicon_findcard(int driverid)
  577. {
  578.         eicon_card *p = cards;
  579.         while (p) {
  580.                 if (p->myid == driverid)
  581.                         return p;
  582.                 p = p->next;
  583.         }
  584.         return (eicon_card *) 0;
  585. }
  586. /*
  587.  * Wrapper functions for interface to linklevel
  588.  */
  589. static int
  590. if_command(isdn_ctrl * c)
  591. {
  592.         eicon_card *card = eicon_findcard(c->driver);
  593.         if (card)
  594.                 return (eicon_command(card, c));
  595.         printk(KERN_ERR
  596.              "eicon: if_command %d called with invalid driverId %d!n",
  597.                c->command, c->driver);
  598.         return -ENODEV;
  599. }
  600. static int
  601. if_writecmd(const u_char * buf, int len, int user, int id, int channel)
  602. {
  603.         return (len);
  604. }
  605. static int
  606. if_readstatus(u_char * buf, int len, int user, int id, int channel)
  607. {
  608. int count = 0;
  609. int cnt = 0;
  610. ulong flags = 0;
  611. u_char *p = buf;
  612. struct sk_buff *skb;
  613.         eicon_card *card = eicon_findcard(id);
  614.         if (card) {
  615.                 if (!card->flags & EICON_FLAGS_RUNNING)
  616.                         return -ENODEV;
  617. spin_lock_irqsave(&eicon_lock, flags);
  618. while((skb = skb_dequeue(&card->statq))) {
  619. if ((skb->len + count) > len)
  620. cnt = len - count;
  621. else
  622. cnt = skb->len;
  623. if (user) {
  624. spin_unlock_irqrestore(&eicon_lock, flags);
  625. copy_to_user(p, skb->data, cnt);
  626. spin_lock_irqsave(&eicon_lock, flags);
  627. }
  628. else
  629. memcpy(p, skb->data, cnt);
  630. count += cnt;
  631. p += cnt;
  632. if (cnt == skb->len) {
  633. dev_kfree_skb(skb);
  634. if (card->statq_entries > 0)
  635. card->statq_entries--;
  636. } else {
  637. skb_pull(skb, cnt);
  638. skb_queue_head(&card->statq, skb);
  639. spin_unlock_irqrestore(&eicon_lock, flags);
  640. return count;
  641. }
  642. }
  643. card->statq_entries = 0;
  644. spin_unlock_irqrestore(&eicon_lock, flags);
  645. return count;
  646.         }
  647.         printk(KERN_ERR
  648.                "eicon: if_readstatus called with invalid driverId!n");
  649.         return 0;
  650. }
  651. static int
  652. if_sendbuf(int id, int channel, int ack, struct sk_buff *skb)
  653. {
  654.         eicon_card *card = eicon_findcard(id);
  655. eicon_chan *chan;
  656. int ret = 0;
  657. int len;
  658. len = skb->len;
  659.         if (card) {
  660.                 if (!card->flags & EICON_FLAGS_RUNNING)
  661.                         return -ENODEV;
  662.          if (!(chan = find_channel(card, channel)))
  663. return -ENODEV;
  664. if (chan->fsm_state == EICON_STATE_ACTIVE) {
  665. #ifdef CONFIG_ISDN_TTY_FAX
  666. if (chan->l2prot == ISDN_PROTO_L2_FAX) {
  667. if ((ret = idi_faxdata_send(card, chan, skb)) > 0)
  668. ret = len;
  669. }
  670. else
  671. #endif
  672. ret = idi_send_data(card, chan, ack, skb, 1, 1);
  673. return (ret);
  674. } else {
  675. return -ENODEV;
  676. }
  677.         }
  678.         printk(KERN_ERR
  679.                "eicon: if_sendbuf called with invalid driverId!n");
  680.         return -ENODEV;
  681. }
  682. /* jiftime() copied from HiSax */
  683. static inline int jiftime(char *s, long mark)
  684. {
  685.         s += 8;
  686.         *s-- = '';
  687.         *s-- = mark % 10 + '0';
  688.         mark /= 10;
  689.         *s-- = mark % 10 + '0';
  690.         mark /= 10;
  691.         *s-- = '.';
  692.         *s-- = mark % 10 + '0';
  693.         mark /= 10;
  694.         *s-- = mark % 6 + '0';
  695.         mark /= 6;
  696.         *s-- = ':';
  697.         *s-- = mark % 10 + '0';
  698.         mark /= 10;
  699.         *s-- = mark % 10 + '0';
  700.         return(8);
  701. }
  702. void
  703. eicon_putstatus(eicon_card * card, char * buf)
  704. {
  705. ulong flags;
  706. int count;
  707. isdn_ctrl cmd;
  708. u_char *p;
  709. struct sk_buff *skb;
  710. if (!card) {
  711. if (!(card = cards))
  712. return;
  713. }
  714. spin_lock_irqsave(&eicon_lock, flags);
  715. count = strlen(buf);
  716. skb = alloc_skb(count, GFP_ATOMIC);
  717. if (!skb) {
  718. spin_unlock_irqrestore(&eicon_lock, flags);
  719. printk(KERN_ERR "eicon: could not alloc skb in putstatusn");
  720. return;
  721. }
  722. p = skb_put(skb, count);
  723. memcpy(p, buf, count);
  724. skb_queue_tail(&card->statq, skb);
  725. if (card->statq_entries >= MAX_STATUS_BUFFER) {
  726. if ((skb = skb_dequeue(&card->statq))) {
  727. count -= skb->len;
  728. dev_kfree_skb(skb);
  729. } else
  730. count = 0;
  731. } else
  732. card->statq_entries++;
  733. spin_unlock_irqrestore(&eicon_lock, flags);
  734.         if (count) {
  735.                 cmd.command = ISDN_STAT_STAVAIL;
  736.                 cmd.driver = card->myid;
  737.                 cmd.arg = count;
  738. card->interface.statcallb(&cmd);
  739.         }
  740. }
  741. /*
  742.  * Debug and Log 
  743.  */
  744. void
  745. eicon_log(eicon_card * card, int level, const char *fmt, ...)
  746. {
  747. va_list args;
  748. char Line[160];
  749. u_char *p;
  750. if ((DebugVar & level) || (DebugVar & 256)) {
  751. va_start(args, fmt);
  752. if (DebugVar & level) {
  753. if (DebugVar & 256) {
  754. /* log-buffer */
  755. p = Line;
  756. p += jiftime(p, jiffies);
  757. *p++ = 32;
  758. p += vsprintf(p, fmt, args);
  759. *p = 0;
  760. eicon_putstatus(card, Line);
  761. } else {
  762. /* printk, syslogd */
  763. vsprintf(Line, fmt, args);
  764. printk(KERN_DEBUG "%s", Line);
  765. }
  766. }
  767. va_end(args);
  768. }
  769. }
  770. /*
  771.  * Allocate a new card-struct, initialize it
  772.  * link it into cards-list.
  773.  */
  774. static void
  775. eicon_alloccard(int Type, int membase, int irq, char *id, int card_id)
  776. {
  777. int i;
  778. int j;
  779. int qloop;
  780. #ifdef CONFIG_ISDN_DRV_EICON_ISA
  781. char qid[5];
  782. #endif
  783.         eicon_card *card;
  784. qloop = (Type == EICON_CTYPE_QUADRO)?2:0;
  785. for (i = 0; i <= qloop; i++) {
  786. if (!(card = (eicon_card *) kmalloc(sizeof(eicon_card), GFP_KERNEL))) {
  787. eicon_log(card, 1,
  788.        "eicon: (%s) Could not allocate card-struct.n", id);
  789. return;
  790. }
  791. memset((char *) card, 0, sizeof(eicon_card));
  792. skb_queue_head_init(&card->sndq);
  793. skb_queue_head_init(&card->rcvq);
  794. skb_queue_head_init(&card->rackq);
  795. skb_queue_head_init(&card->sackq);
  796. skb_queue_head_init(&card->statq);
  797. card->statq_entries = 0;
  798. card->snd_tq.routine = (void *) (void *) eicon_transmit;
  799. card->snd_tq.data = card;
  800. card->rcv_tq.routine = (void *) (void *) eicon_rcv_dispatch;
  801. card->rcv_tq.data = card;
  802. card->ack_tq.routine = (void *) (void *) eicon_ack_dispatch;
  803. card->ack_tq.data = card;
  804. card->interface.maxbufsize = 4000;
  805. card->interface.command = if_command;
  806. card->interface.writebuf_skb = if_sendbuf;
  807. card->interface.writecmd = if_writecmd;
  808. card->interface.readstat = if_readstatus;
  809. card->interface.features =
  810. ISDN_FEATURE_L2_X75I |
  811. ISDN_FEATURE_L2_HDLC |
  812. ISDN_FEATURE_L2_TRANS |
  813. ISDN_FEATURE_L3_TRANS |
  814. ISDN_FEATURE_P_UNKNOWN;
  815. card->interface.hl_hdrlen = 20;
  816. card->ptype = ISDN_PTYPE_UNKNOWN;
  817. strncpy(card->interface.id, id, sizeof(card->interface.id) - 1);
  818. card->myid = -1;
  819. card->type = Type;
  820. switch (Type) {
  821. #ifdef CONFIG_ISDN_DRV_EICON_ISA
  822. #if CONFIG_MCA /* only needed for MCA */
  823.                         case EICON_CTYPE_S:
  824.                         case EICON_CTYPE_SX:
  825.                         case EICON_CTYPE_SCOM:
  826. if (MCA_bus) {
  827.                                 if (membase == -1)
  828.                                          membase = EICON_ISA_MEMBASE;
  829.                                  if (irq == -1)
  830.                                          irq = EICON_ISA_IRQ;
  831.                                 card->bus = EICON_BUS_MCA;
  832.                                  card->hwif.isa.card = (void *)card;
  833.                                  card->hwif.isa.shmem = (eicon_isa_shmem *)membase;
  834. card->hwif.isa.physmem = (unsigned long)membase;
  835.                                  card->hwif.isa.master = 1;
  836.                                 card->hwif.isa.irq = irq;
  837.                                  card->hwif.isa.type = Type;
  838.                                  card->nchannels = 2;
  839.                                  card->interface.channels = 1;
  840. } else {
  841. printk(KERN_WARNING
  842. "eicon (%s): no MCA bus detected.n",
  843. card->interface.id);
  844. kfree(card);
  845. return;
  846. }
  847.                                 break;
  848. #endif /* CONFIG_MCA */
  849. case EICON_CTYPE_QUADRO:
  850. if (membase == -1)
  851. membase = EICON_ISA_MEMBASE;
  852. if (irq == -1)
  853. irq = EICON_ISA_IRQ;
  854.                                 card->bus = EICON_BUS_ISA;
  855. card->hwif.isa.card = (void *)card;
  856. card->hwif.isa.shmem = (eicon_isa_shmem *)(membase + (i+1) * EICON_ISA_QOFFSET);
  857. card->hwif.isa.physmem = (unsigned long)(membase + (i+1) * EICON_ISA_QOFFSET);
  858. card->hwif.isa.master = 0;
  859. strcpy(card->interface.id, id);
  860. if (id[strlen(id) - 1] == 'a') {
  861. card->interface.id[strlen(id) - 1] = 'a' + i + 1;
  862. } else {
  863. sprintf(qid, "_%c",'2' + i);
  864. strcat(card->interface.id, qid);
  865. }
  866. printk(KERN_INFO "Eicon: Quadro: Driver-Id %s added.n",
  867. card->interface.id);
  868. if (i == 0) {
  869. eicon_card *p = cards;
  870. while(p) {
  871. if ((p->hwif.isa.master) && (p->hwif.isa.irq == irq)) {
  872. p->qnext = card;
  873. break;
  874. }
  875. p = p->next;
  876. }
  877. if (!p) {
  878. eicon_log(card, 1, "eicon_alloccard: Quadro Master not found.n");
  879. kfree(card);
  880. return;
  881. }
  882. } else {
  883. cards->qnext = card;
  884. }
  885. card->hwif.isa.irq = irq;
  886. card->hwif.isa.type = Type;
  887. card->nchannels = 2;
  888. card->interface.channels = 1;
  889. break;
  890. #endif
  891. #ifdef CONFIG_PCI
  892. #ifdef CONFIG_ISDN_DRV_EICON_PCI
  893. case EICON_CTYPE_MAESTRA:
  894.                                 card->bus = EICON_BUS_PCI;
  895. card->interface.features |=
  896. ISDN_FEATURE_L2_V11096 |
  897. ISDN_FEATURE_L2_V11019 |
  898. ISDN_FEATURE_L2_V11038 |
  899. ISDN_FEATURE_L2_MODEM |
  900. ISDN_FEATURE_L2_FAX | 
  901. ISDN_FEATURE_L3_TRANSDSP |
  902. ISDN_FEATURE_L3_FCLASS2;
  903.                                 card->hwif.pci.card = (void *)card;
  904.                                 card->hwif.pci.master = card_id;
  905.                                 card->hwif.pci.irq = irq;
  906.                                 card->hwif.pci.type = Type;
  907. card->flags = 0;
  908.                                 card->nchannels = 2;
  909. card->interface.channels = 1;
  910. break;
  911. case EICON_CTYPE_MAESTRAQ:
  912.                                 card->bus = EICON_BUS_PCI;
  913. card->interface.features |=
  914. ISDN_FEATURE_L2_V11096 |
  915. ISDN_FEATURE_L2_V11019 |
  916. ISDN_FEATURE_L2_V11038 |
  917. ISDN_FEATURE_L2_MODEM |
  918. ISDN_FEATURE_L2_FAX | 
  919. ISDN_FEATURE_L3_TRANSDSP |
  920. ISDN_FEATURE_L3_FCLASS2;
  921.                                 card->hwif.pci.card = (void *)card;
  922.                                 card->hwif.pci.master = card_id;
  923.                                 card->hwif.pci.irq = irq;
  924.                                 card->hwif.pci.type = Type;
  925. card->flags = 0;
  926.                                 card->nchannels = 2;
  927. card->interface.channels = 1;
  928. break;
  929. case EICON_CTYPE_MAESTRAP:
  930.                                 card->bus = EICON_BUS_PCI;
  931. card->interface.features |=
  932. ISDN_FEATURE_L2_V11096 |
  933. ISDN_FEATURE_L2_V11019 |
  934. ISDN_FEATURE_L2_V11038 |
  935. ISDN_FEATURE_L2_MODEM |
  936. ISDN_FEATURE_L2_FAX |
  937. ISDN_FEATURE_L3_TRANSDSP |
  938. ISDN_FEATURE_L3_FCLASS2;
  939.                                 card->hwif.pci.card = (void *)card;
  940.                                 card->hwif.pci.master = card_id;
  941.                                 card->hwif.pci.irq = irq;
  942.                                 card->hwif.pci.type = Type;
  943. card->flags = 0;
  944.                                 card->nchannels = 30;
  945. card->interface.channels = 1;
  946. break;
  947. #endif
  948. #endif
  949. #ifdef CONFIG_ISDN_DRV_EICON_ISA
  950. case EICON_CTYPE_ISABRI:
  951. if (membase == -1)
  952. membase = EICON_ISA_MEMBASE;
  953. if (irq == -1)
  954. irq = EICON_ISA_IRQ;
  955. card->bus = EICON_BUS_ISA;
  956. card->hwif.isa.card = (void *)card;
  957. card->hwif.isa.shmem = (eicon_isa_shmem *)membase;
  958. card->hwif.isa.physmem = (unsigned long)membase;
  959. card->hwif.isa.master = 1;
  960. card->hwif.isa.irq = irq;
  961. card->hwif.isa.type = Type;
  962. card->nchannels = 2;
  963. card->interface.channels = 1;
  964. break;
  965. case EICON_CTYPE_ISAPRI:
  966. if (membase == -1)
  967. membase = EICON_ISA_MEMBASE;
  968. if (irq == -1)
  969. irq = EICON_ISA_IRQ;
  970.                                 card->bus = EICON_BUS_ISA;
  971. card->hwif.isa.card = (void *)card;
  972. card->hwif.isa.shmem = (eicon_isa_shmem *)membase;
  973. card->hwif.isa.physmem = (unsigned long)membase;
  974. card->hwif.isa.master = 1;
  975. card->hwif.isa.irq = irq;
  976. card->hwif.isa.type = Type;
  977. card->nchannels = 30;
  978. card->interface.channels = 1;
  979. break;
  980. #endif
  981. default:
  982. eicon_log(card, 1, "eicon_alloccard: Invalid type %dn", Type);
  983. kfree(card);
  984. return;
  985. }
  986. if (!(card->bch = (eicon_chan *) kmalloc(sizeof(eicon_chan) * (card->nchannels + 1)
  987.  , GFP_KERNEL))) {
  988. eicon_log(card, 1,
  989.        "eicon: (%s) Could not allocate bch-struct.n", id);
  990. kfree(card);
  991. return;
  992. }
  993. for (j=0; j< (card->nchannels + 1); j++) {
  994. memset((char *)&card->bch[j], 0, sizeof(eicon_chan));
  995. card->bch[j].statectrl = 0;
  996. card->bch[j].l2prot = ISDN_PROTO_L2_X75I;
  997. card->bch[j].l3prot = ISDN_PROTO_L3_TRANS;
  998. card->bch[j].e.D3Id = 0;
  999. card->bch[j].e.B2Id = 0;
  1000. card->bch[j].e.Req = 0;
  1001. card->bch[j].No = j;
  1002. card->bch[j].tskb1 = NULL;
  1003. card->bch[j].tskb2 = NULL;
  1004. skb_queue_head_init(&card->bch[j].e.X);
  1005. skb_queue_head_init(&card->bch[j].e.R);
  1006. }
  1007. #ifdef CONFIG_ISDN_DRV_EICON_PCI
  1008. /* *** Diva Server *** */
  1009. if (!(card->dbuf = (DBUFFER *) kmalloc((sizeof(DBUFFER) * (card->nchannels + 1))*2
  1010.  , GFP_KERNEL))) {
  1011. eicon_log(card, 1,
  1012.        "eicon: (%s) Could not allocate DBUFFER-struct.n", id);
  1013. kfree(card);
  1014. kfree(card->bch);
  1015. return;
  1016. }
  1017. if (!(card->sbuf = (BUFFERS *) kmalloc((sizeof(BUFFERS) * (card->nchannels + 1)) * 2, GFP_KERNEL))) {
  1018. eicon_log(card, 1,
  1019.        "eicon: (%s) Could not allocate BUFFERS-struct.n", id);
  1020. kfree(card);
  1021. kfree(card->bch);
  1022. kfree(card->dbuf);
  1023. return;
  1024. }
  1025. if (!(card->sbufp = (char *) kmalloc((270 * (card->nchannels + 1)) * 2, GFP_KERNEL))) {
  1026. eicon_log(card, 1,
  1027.        "eicon: (%s) Could not allocate BUFFERSP-struct.n", id);
  1028. kfree(card);
  1029. kfree(card->bch);
  1030. kfree(card->dbuf);
  1031. kfree(card->sbuf);
  1032. return;
  1033. }
  1034. for (j=0; j< (card->nchannels + 1); j++) {
  1035. memset((char *)&card->dbuf[j], 0, sizeof(DBUFFER));
  1036. card->bch[j].de.RBuffer = (DBUFFER *)&card->dbuf[j];
  1037. memset((char *)&card->dbuf[j+(card->nchannels+1)], 0, sizeof(BUFFERS));
  1038. card->bch[j].be.RBuffer = (DBUFFER *)&card->dbuf[j+(card->nchannels+1)];
  1039. memset((char *)&card->sbuf[j], 0, sizeof(BUFFERS));
  1040. card->bch[j].de.X = (BUFFERS *)&card->sbuf[j];
  1041. memset((char *)&card->sbuf[j+(card->nchannels+1)], 0, sizeof(BUFFERS));
  1042. card->bch[j].be.X = (BUFFERS *)&card->sbuf[j+(card->nchannels+1)];
  1043. memset((char *)&card->sbufp[j], 0, 270);
  1044. card->bch[j].de.X->P = (char *)&card->sbufp[j * 270];
  1045. memset((char *)&card->sbufp[j+(card->nchannels+1)], 0, 270);
  1046. card->bch[j].be.X->P = (char *)&card->sbufp[(j+(card->nchannels+1)) * 270];
  1047. }
  1048. /* *** */
  1049. #endif /* CONFIG_ISDN_DRV_EICON_PCI */
  1050. card->next = cards;
  1051. cards = card;
  1052. }
  1053. }
  1054. /*
  1055.  * register card at linklevel
  1056.  */
  1057. static int
  1058. eicon_registercard(eicon_card * card)
  1059. {
  1060.         switch (card->bus) {
  1061. #ifdef CONFIG_ISDN_DRV_EICON_ISA
  1062. case EICON_BUS_ISA:
  1063. /* TODO something to print */
  1064. break;
  1065. #ifdef CONFIG_MCA
  1066. case EICON_BUS_MCA:
  1067. eicon_isa_printpar(&card->hwif.isa);
  1068. break;
  1069. #endif /* CONFIG_MCA */
  1070. #endif
  1071. case EICON_BUS_PCI:
  1072. break;
  1073. default:
  1074. eicon_log(card, 1,
  1075.        "eicon_registercard: Illegal BUS type %dn",
  1076.        card->bus);
  1077. return -1;
  1078.         }
  1079.         if (!register_isdn(&card->interface)) {
  1080.                 printk(KERN_WARNING
  1081.                        "eicon_registercard: Unable to register %sn",
  1082.                        card->interface.id);
  1083.                 return -1;
  1084.         }
  1085.         card->myid = card->interface.channels;
  1086.         sprintf(card->regname, "%s", card->interface.id);
  1087.         return 0;
  1088. }
  1089. static void __exit
  1090. unregister_card(eicon_card * card)
  1091. {
  1092.         isdn_ctrl cmd;
  1093.         cmd.command = ISDN_STAT_UNLOAD;
  1094.         cmd.driver = card->myid;
  1095.         card->interface.statcallb(&cmd);
  1096.         switch (card->bus) {
  1097. #ifdef CONFIG_ISDN_DRV_EICON_ISA
  1098. case EICON_BUS_ISA:
  1099. #ifdef CONFIG_MCA
  1100. case EICON_BUS_MCA:
  1101. #endif /* CONFIG_MCA */
  1102. eicon_isa_release(&card->hwif.isa);
  1103. break;
  1104. #endif
  1105. case EICON_BUS_PCI:
  1106. break;
  1107. default:
  1108. eicon_log(card, 1,
  1109.        "eicon: Invalid BUS type %dn",
  1110.        card->bus);
  1111. break;
  1112.         }
  1113. }
  1114. static void
  1115. eicon_freecard(eicon_card *card) {
  1116. int i;
  1117. for(i = 0; i < (card->nchannels + 1); i++) {
  1118. skb_queue_purge(&card->bch[i].e.X);
  1119. skb_queue_purge(&card->bch[i].e.R);
  1120. }
  1121. skb_queue_purge(&card->sndq);
  1122. skb_queue_purge(&card->rcvq);
  1123. skb_queue_purge(&card->rackq);
  1124. skb_queue_purge(&card->sackq);
  1125. skb_queue_purge(&card->statq);
  1126. #ifdef CONFIG_ISDN_DRV_EICON_PCI
  1127. kfree(card->sbufp);
  1128. kfree(card->sbuf);
  1129. kfree(card->dbuf);
  1130. #endif
  1131. kfree(card->bch);
  1132. kfree(card);
  1133. }
  1134. int
  1135. eicon_addcard(int Type, int membase, int irq, char *id, int card_id)
  1136. {
  1137. eicon_card *p;
  1138. eicon_card *q = NULL;
  1139. int registered;
  1140. int added = 0;
  1141. int failed = 0;
  1142. #ifdef CONFIG_ISDN_DRV_EICON_ISA
  1143. if (!Type) /* ISA */
  1144. if ((Type = eicon_isa_find_card(membase, irq, id)) < 0)
  1145. return 0;
  1146. #endif
  1147. eicon_alloccard(Type, membase, irq, id, card_id);
  1148.         p = cards;
  1149.         while (p) {
  1150. registered = 0;
  1151. if (!p->interface.statcallb) {
  1152. /* Not yet registered.
  1153.  * Try to register and activate it.
  1154.  */
  1155. added++;
  1156. switch (p->bus) {
  1157. #ifdef CONFIG_ISDN_DRV_EICON_ISA
  1158. case EICON_BUS_ISA:
  1159. case EICON_BUS_MCA:
  1160. if (eicon_registercard(p))
  1161. break;
  1162. registered = 1;
  1163. break;
  1164. #endif
  1165. case EICON_BUS_PCI:
  1166. #ifdef CONFIG_PCI
  1167. #ifdef CONFIG_ISDN_DRV_EICON_PCI
  1168. if (eicon_registercard(p))
  1169. break;
  1170. registered = 1;
  1171. break;
  1172. #endif
  1173. #endif
  1174. default:
  1175. printk(KERN_ERR
  1176.        "eicon: addcard: Invalid BUS type %dn",
  1177.        p->bus);
  1178. }
  1179. } else
  1180. /* Card already registered */
  1181. registered = 1;
  1182.                 if (registered) {
  1183. /* Init OK, next card ... */
  1184.                         q = p;
  1185.                         p = p->next;
  1186.                 } else {
  1187.                         /* registering failed, remove card from list, free memory */
  1188.                         printk(KERN_ERR
  1189.                                "eicon: Initialization of %s failedn",
  1190.                                p->interface.id);
  1191.                         if (q) {
  1192.                                 q->next = p->next;
  1193.                                 eicon_freecard(p);
  1194.                                 p = q->next;
  1195.                         } else {
  1196.                                 cards = p->next;
  1197.                                 eicon_freecard(p);
  1198.                                 p = cards;
  1199.                         }
  1200. failed++;
  1201.                 }
  1202. }
  1203.         return (added - failed);
  1204. }
  1205. static int __init
  1206. eicon_init(void)
  1207. {
  1208. int card_count = 0;
  1209. char tmprev[50];
  1210. DebugVar = 1;
  1211. eicon_lock = (spinlock_t) SPIN_LOCK_UNLOCKED;
  1212.         printk(KERN_INFO "%s Rev: ", DRIVERNAME);
  1213. strcpy(tmprev, eicon_revision);
  1214. printk("%s/", eicon_getrev(tmprev));
  1215. strcpy(tmprev, eicon_pci_revision);
  1216. #ifdef CONFIG_ISDN_DRV_EICON_PCI
  1217. printk("%s/", eicon_getrev(tmprev));
  1218. #else
  1219. printk("---/");
  1220. #endif
  1221. strcpy(tmprev, eicon_isa_revision);
  1222. #ifdef CONFIG_ISDN_DRV_EICON_ISA
  1223. printk("%s/", eicon_getrev(tmprev));
  1224. #else
  1225. printk("---/");
  1226. #endif
  1227. strcpy(tmprev, eicon_idi_revision);
  1228. printk("%sn", eicon_getrev(tmprev));
  1229.         printk(KERN_INFO "%s Release: %s%sn", DRIVERNAME,
  1230. DRIVERRELEASE, DRIVERPATCH);
  1231. #ifdef CONFIG_ISDN_DRV_EICON_ISA
  1232. #ifdef CONFIG_MCA
  1233. /* Check if we have MCA-bus */
  1234.         if (!MCA_bus)
  1235.                 {
  1236.                 printk(KERN_INFO
  1237.                         "eicon: No MCA bus, ISDN-interfaces  not probed.n");
  1238.         } else {
  1239. eicon_log(NULL, 8,
  1240. "eicon_mca_find_card, irq=%d.n", 
  1241. irq);
  1242.                 if (!eicon_mca_find_card(0, membase, irq, id))
  1243.                        card_count++;
  1244.         };
  1245. #else
  1246. card_count = eicon_addcard(0, membase, irq, id, 0);
  1247. #endif /* CONFIG_MCA */
  1248. #endif /* CONFIG_ISDN_DRV_EICON_ISA */
  1249.  
  1250. #ifdef CONFIG_PCI
  1251. #ifdef CONFIG_ISDN_DRV_EICON_PCI
  1252. DivasCardsDiscover();
  1253. card_count += eicon_pci_find_card(id);
  1254. #endif
  1255. #endif
  1256.         if (!cards) {
  1257. #ifdef MODULE
  1258. #ifndef CONFIG_ISDN_DRV_EICON_PCI
  1259. #ifndef CONFIG_ISDN_DRV_EICON_ISA
  1260.                 printk(KERN_INFO "Eicon: Driver is neither ISA nor PCI compiled !n");
  1261.                 printk(KERN_INFO "Eicon: Driver not loaded !n");
  1262. #else
  1263.                 printk(KERN_INFO "Eicon: No cards defined, driver not loaded !n");
  1264. #endif
  1265. #else
  1266.                 printk(KERN_INFO "Eicon: No PCI-cards found, driver not loaded !n");
  1267. #endif
  1268. #endif /* MODULE */
  1269. return -ENODEV;
  1270. } else
  1271. printk(KERN_INFO "Eicon: %d card%s addedn", card_count, 
  1272.                        (card_count>1)?"s":"");
  1273.         return 0;
  1274. }
  1275. #ifdef CONFIG_ISDN_DRV_EICON_PCI
  1276. void DIVA_DIDD_Write(DESCRIPTOR *, int);
  1277. EXPORT_SYMBOL_NOVERS(DIVA_DIDD_Read);
  1278. EXPORT_SYMBOL_NOVERS(DIVA_DIDD_Write);
  1279. EXPORT_SYMBOL_NOVERS(DivasPrintf);
  1280. #else
  1281. int DivasCardNext;
  1282. card_t DivasCards[1];
  1283. #endif
  1284. static void __exit
  1285. eicon_exit(void)
  1286. {
  1287. #if CONFIG_PCI
  1288. #ifdef CONFIG_ISDN_DRV_EICON_PCI
  1289. card_t *pCard;
  1290. word wCardIndex;
  1291. extern int Divas_major;
  1292. int iTmp = 0;
  1293. #endif
  1294. #endif
  1295.         eicon_card *card = cards;
  1296.         eicon_card *last;
  1297.         while (card) {
  1298. #ifdef CONFIG_ISDN_DRV_EICON_ISA
  1299. #ifdef CONFIG_MCA
  1300.          if (MCA_bus)
  1301.                         {
  1302.                         mca_mark_as_unused (card->mca_slot);
  1303.                         mca_set_adapter_procfn(card->mca_slot, NULL, NULL);
  1304.                         };
  1305. #endif /* CONFIG_MCA */
  1306. #endif
  1307.                 unregister_card(card); 
  1308.                 card = card->next;
  1309.         }
  1310.         card = cards;
  1311.         while (card) {
  1312.                 last = card;
  1313.                 card = card->next;
  1314. eicon_freecard(last);
  1315.         }
  1316. #if CONFIG_PCI
  1317. #ifdef CONFIG_ISDN_DRV_EICON_PCI
  1318. pCard = DivasCards;
  1319. for (wCardIndex = 0; wCardIndex < MAX_CARDS; wCardIndex++)
  1320. {
  1321. if ((pCard->hw) && (pCard->hw->in_use))
  1322. {
  1323. (*pCard->card_reset)(pCard);
  1324. UxIsrRemove(pCard->hw, pCard);
  1325. UxCardHandleFree(pCard->hw);
  1326. if(pCard->e_tbl != NULL)
  1327. {
  1328. kfree(pCard->e_tbl);
  1329. }
  1330. if(pCard->hw->card_type == DIA_CARD_TYPE_DIVA_SERVER_B)
  1331. {
  1332. release_region(pCard->hw->io_base,0x20);
  1333. release_region(pCard->hw->reset_base,0x80);
  1334. }
  1335.                         // If this is a 4BRI ...
  1336.                         if (pCard->hw->card_type == DIA_CARD_TYPE_DIVA_SERVER_Q)
  1337.                         {
  1338.                                 // Skip over the next 3 virtual adapters
  1339.                                 wCardIndex += 3;
  1340.                                 // But free their handles
  1341. for (iTmp = 0; iTmp < 3; iTmp++)
  1342. {
  1343. pCard++;
  1344. UxCardHandleFree(pCard->hw);
  1345. if(pCard->e_tbl != NULL)
  1346. {
  1347. kfree(pCard->e_tbl);
  1348. }
  1349. }
  1350.                         }
  1351. }
  1352. pCard++;
  1353. }
  1354. unregister_chrdev(Divas_major, "Divas");
  1355. #endif
  1356. #endif /* CONFIG_PCI */
  1357.         printk(KERN_INFO "%s unloadedn", DRIVERNAME);
  1358. }
  1359. #ifndef MODULE
  1360. static int __init
  1361. eicon_setup(char *line)
  1362. {
  1363.         int i, argc;
  1364. int ints[5];
  1365. char *str;
  1366. str = get_options(line, 4, ints);
  1367.         argc = ints[0];
  1368.         i = 1;
  1369. #ifdef CONFIG_ISDN_DRV_EICON_ISA
  1370.         if (argc) {
  1371. membase = irq = -1;
  1372. if (argc) {
  1373. membase = ints[i];
  1374. i++;
  1375. argc--;
  1376. }
  1377. if (argc) {
  1378. irq = ints[i];
  1379. i++;
  1380. argc--;
  1381. }
  1382. if (strlen(str)) {
  1383. strcpy(id, str);
  1384. } else {
  1385. strcpy(id, "eicon");
  1386.         printk(KERN_INFO "Eicon ISDN active driver setup (id=%s membase=0x%x irq=%d)n",
  1387. id, membase, irq);
  1388. }
  1389. #else
  1390. printk(KERN_INFO "Eicon ISDN active driver setupn");
  1391. #endif
  1392. return(1);
  1393. }
  1394. __setup("eicon=", eicon_setup);
  1395. #endif /* MODULE */
  1396. #ifdef CONFIG_ISDN_DRV_EICON_ISA
  1397. #ifdef CONFIG_MCA
  1398. struct eicon_mca_adapters_struct {
  1399. char * name;
  1400. int adf_id;
  1401. };
  1402. /* possible MCA-brands of eicon cards                                         */
  1403. struct eicon_mca_adapters_struct eicon_mca_adapters[] = {
  1404. { "ISDN-P/2 Adapter", 0x6abb },
  1405. { "ISDN-[S|SX|SCOM]/2 Adapter", 0x6a93 },
  1406. { "DIVA /MCA", 0x6336 },
  1407. { NULL, 0 },
  1408. };
  1409. int eicon_mca_find_card(int type,          /* type-idx of eicon-card          */
  1410.                         int membase,
  1411.         int irq,
  1412. char * id)         /* name of eicon-isdn-dev          */
  1413. {
  1414. int j, curr_slot = 0;
  1415.         eicon_log(NULL, 8,
  1416. "eicon_mca_find_card type: %d, membase: %#x, irq %d n",
  1417. type, membase, irq);
  1418. /* find a no-driver-assigned eicon card                               */
  1419. for (j=0; eicon_mca_adapters[j].adf_id != 0; j++) 
  1420. {
  1421. for ( curr_slot=0; curr_slot<=MCA_MAX_SLOT_NR; curr_slot++) 
  1422. {
  1423. curr_slot = mca_find_unused_adapter(
  1424.          eicon_mca_adapters[j].adf_id, curr_slot);
  1425. if (curr_slot != MCA_NOTFOUND) 
  1426. {
  1427. /* check if pre-set parameters match
  1428.    these of the card, check cards memory      */
  1429. if (!(int) eicon_mca_probe(curr_slot,
  1430.                                                            j,
  1431.                                                     membase, 
  1432.                                                            irq,
  1433.                                                            id))
  1434. {
  1435. return 0;
  1436. /* means: adapter parms did match     */
  1437. };
  1438. };
  1439. break;
  1440. /* MCA_NOTFOUND-branch: no matching adapter of
  1441.    THIS flavor found, next flavor                     */
  1442.              };
  1443. };
  1444. /* all adapter flavors checked without match, finito with:            */
  1445.         return -ENODEV;
  1446. };
  1447. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1448.  *  stolen from 3c523.c/elmc_getinfo, ewe, 10.5.1999 
  1449.  */
  1450. int eicon_info(char * buf, int slot, void *d)
  1451. {
  1452. int len = 0;
  1453. struct eicon_card *dev;
  1454.         dev = (struct eicon_card *) d;
  1455. if (dev == NULL)
  1456. return len;
  1457. len += sprintf(buf+len, "eicon ISDN adapter, type %d.n",dev->type);
  1458. len += sprintf(buf+len, "IRQ: %dn", dev->hwif.isa.irq);
  1459. len += sprintf(buf+len, "MEMBASE: %#lxn", (unsigned long)dev->hwif.isa.shmem);
  1460. return len;
  1461. };
  1462. int eicon_mca_probe(int slot,  /* slot-nr where the card was detected         */
  1463.     int a_idx, /* idx-nr of probed card in eicon_mca_adapters */
  1464.                     int membase,
  1465.                     int irq,
  1466.     char * id) /* name of eicon-isdn-dev                      */
  1467. {
  1468. unsigned char adf_pos0;
  1469. int cards_irq, cards_membase, cards_io;
  1470. int type = EICON_CTYPE_S;
  1471. int irq_array[]={0,3,4,2};
  1472. int irq_array1[]={3,4,0,0,2,10,11,12};
  1473.         adf_pos0 = mca_read_stored_pos(slot,2);
  1474. eicon_log(NULL, 8,
  1475. "eicon_mca_probe irq=%d, membase=%dn", 
  1476. irq,
  1477. membase);
  1478. switch (a_idx) {
  1479. case 0:                /* P/2-Adapter (== PRI/S2M ? )         */
  1480. cards_membase= 0xC0000+((adf_pos0>>4)*0x4000);
  1481. if (membase == -1) { 
  1482. membase = cards_membase;
  1483. } else {
  1484. if (membase != cards_membase)
  1485. return -ENODEV;
  1486. };
  1487. cards_irq=irq_array[((adf_pos0 & 0xC)>>2)];
  1488. if (irq == -1) { 
  1489. irq = cards_irq;
  1490. } else {
  1491. if (irq != cards_irq)
  1492. return -ENODEV;
  1493. };
  1494. cards_io= 0xC00 + ((adf_pos0>>4)*0x10);
  1495. type = EICON_CTYPE_ISAPRI; 
  1496. break;
  1497. case 1:                /* [S|SX|SCOM]/2                       */
  1498. cards_membase= 0xC0000+((adf_pos0>>4)*0x2000);
  1499. if (membase == -1) { 
  1500. membase = cards_membase;
  1501. } else {
  1502. if (membase != cards_membase)
  1503. return -ENODEV;
  1504. };
  1505. cards_irq=irq_array[((adf_pos0 & 0xC)>>2)];
  1506. if (irq == -1) { 
  1507. irq = cards_irq;
  1508. } else {
  1509. if (irq != cards_irq)
  1510. return -ENODEV;
  1511. };
  1512. cards_io= 0xC00 + ((adf_pos0>>4)*0x10);
  1513. type = EICON_CTYPE_SCOM; 
  1514.   break;
  1515. case 2:                /* DIVA/MCA                            */
  1516. cards_io = 0x200+ ((adf_pos0>>4)* 0x20);
  1517. cards_irq = irq_array1[(adf_pos0 & 0x7)];
  1518. if (irq == -1) { 
  1519. irq = cards_irq;
  1520. } else {
  1521. if (irq != cards_irq)
  1522. return -ENODEV;
  1523. };
  1524. type = 0; 
  1525. break;
  1526. default:
  1527. return -ENODEV;
  1528. };
  1529. /* matching membase & irq */
  1530. if ( 1 == eicon_addcard(type, membase, irq, id, 0)) { 
  1531. mca_set_adapter_name(slot, eicon_mca_adapters[a_idx].name);
  1532.    mca_set_adapter_procfn(slot, (MCA_ProcFn) eicon_info, cards);
  1533.          mca_mark_as_used(slot);
  1534. cards->mca_slot = slot; 
  1535. /* card->io noch setzen  oder ?? */
  1536. cards->mca_io = cards_io;
  1537. cards->hwif.isa.io = cards_io;
  1538. /* reset card */
  1539. outb_p(0,cards_io+1);
  1540. eicon_log(NULL, 8, "eicon_addcard: successful for slot # %d.n", 
  1541. cards->mca_slot+1);
  1542. return  0 ; /* eicon_addcard added a card */
  1543. } else {
  1544. return -ENODEV;
  1545. };
  1546. };
  1547. #endif /* CONFIG_MCA */
  1548. #endif /* CONFIG_ISDN_DRV_EICON_ISA */
  1549. module_init(eicon_init);
  1550. module_exit(eicon_exit);