eicon_mod.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:44k
源码类别:

嵌入式Linux

开发平台:

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. copy_to_user(p, skb->data, cnt);
  625. else
  626. memcpy(p, skb->data, cnt);
  627. count += cnt;
  628. p += cnt;
  629. if (cnt == skb->len) {
  630. dev_kfree_skb(skb);
  631. if (card->statq_entries > 0)
  632. card->statq_entries--;
  633. } else {
  634. skb_pull(skb, cnt);
  635. skb_queue_head(&card->statq, skb);
  636. spin_unlock_irqrestore(&eicon_lock, flags);
  637. return count;
  638. }
  639. }
  640. card->statq_entries = 0;
  641. spin_unlock_irqrestore(&eicon_lock, flags);
  642. return count;
  643.         }
  644.         printk(KERN_ERR
  645.                "eicon: if_readstatus called with invalid driverId!n");
  646.         return 0;
  647. }
  648. static int
  649. if_sendbuf(int id, int channel, int ack, struct sk_buff *skb)
  650. {
  651.         eicon_card *card = eicon_findcard(id);
  652. eicon_chan *chan;
  653. int ret = 0;
  654. int len;
  655. len = skb->len;
  656.         if (card) {
  657.                 if (!card->flags & EICON_FLAGS_RUNNING)
  658.                         return -ENODEV;
  659.          if (!(chan = find_channel(card, channel)))
  660. return -ENODEV;
  661. if (chan->fsm_state == EICON_STATE_ACTIVE) {
  662. #ifdef CONFIG_ISDN_TTY_FAX
  663. if (chan->l2prot == ISDN_PROTO_L2_FAX) {
  664. if ((ret = idi_faxdata_send(card, chan, skb)) > 0)
  665. ret = len;
  666. }
  667. else
  668. #endif
  669. ret = idi_send_data(card, chan, ack, skb, 1, 1);
  670. return (ret);
  671. } else {
  672. return -ENODEV;
  673. }
  674.         }
  675.         printk(KERN_ERR
  676.                "eicon: if_sendbuf called with invalid driverId!n");
  677.         return -ENODEV;
  678. }
  679. /* jiftime() copied from HiSax */
  680. static inline int jiftime(char *s, long mark)
  681. {
  682.         s += 8;
  683.         *s-- = '';
  684.         *s-- = mark % 10 + '0';
  685.         mark /= 10;
  686.         *s-- = mark % 10 + '0';
  687.         mark /= 10;
  688.         *s-- = '.';
  689.         *s-- = mark % 10 + '0';
  690.         mark /= 10;
  691.         *s-- = mark % 6 + '0';
  692.         mark /= 6;
  693.         *s-- = ':';
  694.         *s-- = mark % 10 + '0';
  695.         mark /= 10;
  696.         *s-- = mark % 10 + '0';
  697.         return(8);
  698. }
  699. void
  700. eicon_putstatus(eicon_card * card, char * buf)
  701. {
  702. ulong flags;
  703. int count;
  704. isdn_ctrl cmd;
  705. u_char *p;
  706. struct sk_buff *skb;
  707. if (!card) {
  708. if (!(card = cards))
  709. return;
  710. }
  711. spin_lock_irqsave(&eicon_lock, flags);
  712. count = strlen(buf);
  713. skb = alloc_skb(count, GFP_ATOMIC);
  714. if (!skb) {
  715. spin_unlock_irqrestore(&eicon_lock, flags);
  716. printk(KERN_ERR "eicon: could not alloc skb in putstatusn");
  717. return;
  718. }
  719. p = skb_put(skb, count);
  720. memcpy(p, buf, count);
  721. skb_queue_tail(&card->statq, skb);
  722. if (card->statq_entries >= MAX_STATUS_BUFFER) {
  723. if ((skb = skb_dequeue(&card->statq))) {
  724. count -= skb->len;
  725. dev_kfree_skb(skb);
  726. } else
  727. count = 0;
  728. } else
  729. card->statq_entries++;
  730. spin_unlock_irqrestore(&eicon_lock, flags);
  731.         if (count) {
  732.                 cmd.command = ISDN_STAT_STAVAIL;
  733.                 cmd.driver = card->myid;
  734.                 cmd.arg = count;
  735. card->interface.statcallb(&cmd);
  736.         }
  737. }
  738. /*
  739.  * Debug and Log 
  740.  */
  741. void
  742. eicon_log(eicon_card * card, int level, const char *fmt, ...)
  743. {
  744. va_list args;
  745. char Line[160];
  746. u_char *p;
  747. if ((DebugVar & level) || (DebugVar & 256)) {
  748. va_start(args, fmt);
  749. if (DebugVar & level) {
  750. if (DebugVar & 256) {
  751. /* log-buffer */
  752. p = Line;
  753. p += jiftime(p, jiffies);
  754. *p++ = 32;
  755. p += vsprintf(p, fmt, args);
  756. *p = 0;
  757. eicon_putstatus(card, Line);
  758. } else {
  759. /* printk, syslogd */
  760. vsprintf(Line, fmt, args);
  761. printk(KERN_DEBUG "%s", Line);
  762. }
  763. }
  764. va_end(args);
  765. }
  766. }
  767. /*
  768.  * Allocate a new card-struct, initialize it
  769.  * link it into cards-list.
  770.  */
  771. static void
  772. eicon_alloccard(int Type, int membase, int irq, char *id, int card_id)
  773. {
  774. int i;
  775. int j;
  776. int qloop;
  777. #ifdef CONFIG_ISDN_DRV_EICON_ISA
  778. char qid[5];
  779. #endif
  780.         eicon_card *card;
  781. qloop = (Type == EICON_CTYPE_QUADRO)?2:0;
  782. for (i = 0; i <= qloop; i++) {
  783. if (!(card = (eicon_card *) kmalloc(sizeof(eicon_card), GFP_KERNEL))) {
  784. eicon_log(card, 1,
  785.        "eicon: (%s) Could not allocate card-struct.n", id);
  786. return;
  787. }
  788. memset((char *) card, 0, sizeof(eicon_card));
  789. skb_queue_head_init(&card->sndq);
  790. skb_queue_head_init(&card->rcvq);
  791. skb_queue_head_init(&card->rackq);
  792. skb_queue_head_init(&card->sackq);
  793. skb_queue_head_init(&card->statq);
  794. card->statq_entries = 0;
  795. card->snd_tq.routine = (void *) (void *) eicon_transmit;
  796. card->snd_tq.data = card;
  797. card->rcv_tq.routine = (void *) (void *) eicon_rcv_dispatch;
  798. card->rcv_tq.data = card;
  799. card->ack_tq.routine = (void *) (void *) eicon_ack_dispatch;
  800. card->ack_tq.data = card;
  801. card->interface.maxbufsize = 4000;
  802. card->interface.command = if_command;
  803. card->interface.writebuf_skb = if_sendbuf;
  804. card->interface.writecmd = if_writecmd;
  805. card->interface.readstat = if_readstatus;
  806. card->interface.features =
  807. ISDN_FEATURE_L2_X75I |
  808. ISDN_FEATURE_L2_HDLC |
  809. ISDN_FEATURE_L2_TRANS |
  810. ISDN_FEATURE_L3_TRANS |
  811. ISDN_FEATURE_P_UNKNOWN;
  812. card->interface.hl_hdrlen = 20;
  813. card->ptype = ISDN_PTYPE_UNKNOWN;
  814. strncpy(card->interface.id, id, sizeof(card->interface.id) - 1);
  815. card->myid = -1;
  816. card->type = Type;
  817. switch (Type) {
  818. #ifdef CONFIG_ISDN_DRV_EICON_ISA
  819. #if CONFIG_MCA /* only needed for MCA */
  820.                         case EICON_CTYPE_S:
  821.                         case EICON_CTYPE_SX:
  822.                         case EICON_CTYPE_SCOM:
  823. if (MCA_bus) {
  824.                                 if (membase == -1)
  825.                                          membase = EICON_ISA_MEMBASE;
  826.                                  if (irq == -1)
  827.                                          irq = EICON_ISA_IRQ;
  828.                                 card->bus = EICON_BUS_MCA;
  829.                                  card->hwif.isa.card = (void *)card;
  830.                                  card->hwif.isa.shmem = (eicon_isa_shmem *)membase;
  831. card->hwif.isa.physmem = (unsigned long)membase;
  832.                                  card->hwif.isa.master = 1;
  833.                                 card->hwif.isa.irq = irq;
  834.                                  card->hwif.isa.type = Type;
  835.                                  card->nchannels = 2;
  836.                                  card->interface.channels = 1;
  837. } else {
  838. printk(KERN_WARNING
  839. "eicon (%s): no MCA bus detected.n",
  840. card->interface.id);
  841. kfree(card);
  842. return;
  843. }
  844.                                 break;
  845. #endif /* CONFIG_MCA */
  846. case EICON_CTYPE_QUADRO:
  847. if (membase == -1)
  848. membase = EICON_ISA_MEMBASE;
  849. if (irq == -1)
  850. irq = EICON_ISA_IRQ;
  851.                                 card->bus = EICON_BUS_ISA;
  852. card->hwif.isa.card = (void *)card;
  853. card->hwif.isa.shmem = (eicon_isa_shmem *)(membase + (i+1) * EICON_ISA_QOFFSET);
  854. card->hwif.isa.physmem = (unsigned long)(membase + (i+1) * EICON_ISA_QOFFSET);
  855. card->hwif.isa.master = 0;
  856. strcpy(card->interface.id, id);
  857. if (id[strlen(id) - 1] == 'a') {
  858. card->interface.id[strlen(id) - 1] = 'a' + i + 1;
  859. } else {
  860. sprintf(qid, "_%c",'2' + i);
  861. strcat(card->interface.id, qid);
  862. }
  863. printk(KERN_INFO "Eicon: Quadro: Driver-Id %s added.n",
  864. card->interface.id);
  865. if (i == 0) {
  866. eicon_card *p = cards;
  867. while(p) {
  868. if ((p->hwif.isa.master) && (p->hwif.isa.irq == irq)) {
  869. p->qnext = card;
  870. break;
  871. }
  872. p = p->next;
  873. }
  874. if (!p) {
  875. eicon_log(card, 1, "eicon_alloccard: Quadro Master not found.n");
  876. kfree(card);
  877. return;
  878. }
  879. } else {
  880. cards->qnext = card;
  881. }
  882. card->hwif.isa.irq = irq;
  883. card->hwif.isa.type = Type;
  884. card->nchannels = 2;
  885. card->interface.channels = 1;
  886. break;
  887. #endif
  888. #ifdef CONFIG_PCI
  889. #ifdef CONFIG_ISDN_DRV_EICON_PCI
  890. case EICON_CTYPE_MAESTRA:
  891.                                 card->bus = EICON_BUS_PCI;
  892. card->interface.features |=
  893. ISDN_FEATURE_L2_V11096 |
  894. ISDN_FEATURE_L2_V11019 |
  895. ISDN_FEATURE_L2_V11038 |
  896. ISDN_FEATURE_L2_MODEM |
  897. ISDN_FEATURE_L2_FAX | 
  898. ISDN_FEATURE_L3_TRANSDSP |
  899. ISDN_FEATURE_L3_FCLASS2;
  900.                                 card->hwif.pci.card = (void *)card;
  901.                                 card->hwif.pci.master = card_id;
  902.                                 card->hwif.pci.irq = irq;
  903.                                 card->hwif.pci.type = Type;
  904. card->flags = 0;
  905.                                 card->nchannels = 2;
  906. card->interface.channels = 1;
  907. break;
  908. case EICON_CTYPE_MAESTRAQ:
  909.                                 card->bus = EICON_BUS_PCI;
  910. card->interface.features |=
  911. ISDN_FEATURE_L2_V11096 |
  912. ISDN_FEATURE_L2_V11019 |
  913. ISDN_FEATURE_L2_V11038 |
  914. ISDN_FEATURE_L2_MODEM |
  915. ISDN_FEATURE_L2_FAX | 
  916. ISDN_FEATURE_L3_TRANSDSP |
  917. ISDN_FEATURE_L3_FCLASS2;
  918.                                 card->hwif.pci.card = (void *)card;
  919.                                 card->hwif.pci.master = card_id;
  920.                                 card->hwif.pci.irq = irq;
  921.                                 card->hwif.pci.type = Type;
  922. card->flags = 0;
  923.                                 card->nchannels = 2;
  924. card->interface.channels = 1;
  925. break;
  926. case EICON_CTYPE_MAESTRAP:
  927.                                 card->bus = EICON_BUS_PCI;
  928. card->interface.features |=
  929. ISDN_FEATURE_L2_V11096 |
  930. ISDN_FEATURE_L2_V11019 |
  931. ISDN_FEATURE_L2_V11038 |
  932. ISDN_FEATURE_L2_MODEM |
  933. ISDN_FEATURE_L2_FAX |
  934. ISDN_FEATURE_L3_TRANSDSP |
  935. ISDN_FEATURE_L3_FCLASS2;
  936.                                 card->hwif.pci.card = (void *)card;
  937.                                 card->hwif.pci.master = card_id;
  938.                                 card->hwif.pci.irq = irq;
  939.                                 card->hwif.pci.type = Type;
  940. card->flags = 0;
  941.                                 card->nchannels = 30;
  942. card->interface.channels = 1;
  943. break;
  944. #endif
  945. #endif
  946. #ifdef CONFIG_ISDN_DRV_EICON_ISA
  947. case EICON_CTYPE_ISABRI:
  948. if (membase == -1)
  949. membase = EICON_ISA_MEMBASE;
  950. if (irq == -1)
  951. irq = EICON_ISA_IRQ;
  952. card->bus = EICON_BUS_ISA;
  953. card->hwif.isa.card = (void *)card;
  954. card->hwif.isa.shmem = (eicon_isa_shmem *)membase;
  955. card->hwif.isa.physmem = (unsigned long)membase;
  956. card->hwif.isa.master = 1;
  957. card->hwif.isa.irq = irq;
  958. card->hwif.isa.type = Type;
  959. card->nchannels = 2;
  960. card->interface.channels = 1;
  961. break;
  962. case EICON_CTYPE_ISAPRI:
  963. if (membase == -1)
  964. membase = EICON_ISA_MEMBASE;
  965. if (irq == -1)
  966. irq = EICON_ISA_IRQ;
  967.                                 card->bus = EICON_BUS_ISA;
  968. card->hwif.isa.card = (void *)card;
  969. card->hwif.isa.shmem = (eicon_isa_shmem *)membase;
  970. card->hwif.isa.physmem = (unsigned long)membase;
  971. card->hwif.isa.master = 1;
  972. card->hwif.isa.irq = irq;
  973. card->hwif.isa.type = Type;
  974. card->nchannels = 30;
  975. card->interface.channels = 1;
  976. break;
  977. #endif
  978. default:
  979. eicon_log(card, 1, "eicon_alloccard: Invalid type %dn", Type);
  980. kfree(card);
  981. return;
  982. }
  983. if (!(card->bch = (eicon_chan *) kmalloc(sizeof(eicon_chan) * (card->nchannels + 1)
  984.  , GFP_KERNEL))) {
  985. eicon_log(card, 1,
  986.        "eicon: (%s) Could not allocate bch-struct.n", id);
  987. kfree(card);
  988. return;
  989. }
  990. for (j=0; j< (card->nchannels + 1); j++) {
  991. memset((char *)&card->bch[j], 0, sizeof(eicon_chan));
  992. card->bch[j].statectrl = 0;
  993. card->bch[j].l2prot = ISDN_PROTO_L2_X75I;
  994. card->bch[j].l3prot = ISDN_PROTO_L3_TRANS;
  995. card->bch[j].e.D3Id = 0;
  996. card->bch[j].e.B2Id = 0;
  997. card->bch[j].e.Req = 0;
  998. card->bch[j].No = j;
  999. card->bch[j].tskb1 = NULL;
  1000. card->bch[j].tskb2 = NULL;
  1001. skb_queue_head_init(&card->bch[j].e.X);
  1002. skb_queue_head_init(&card->bch[j].e.R);
  1003. }
  1004. #ifdef CONFIG_ISDN_DRV_EICON_PCI
  1005. /* *** Diva Server *** */
  1006. if (!(card->dbuf = (DBUFFER *) kmalloc((sizeof(DBUFFER) * (card->nchannels + 1))*2
  1007.  , GFP_KERNEL))) {
  1008. eicon_log(card, 1,
  1009.        "eicon: (%s) Could not allocate DBUFFER-struct.n", id);
  1010. kfree(card);
  1011. kfree(card->bch);
  1012. return;
  1013. }
  1014. if (!(card->sbuf = (BUFFERS *) kmalloc((sizeof(BUFFERS) * (card->nchannels + 1)) * 2, GFP_KERNEL))) {
  1015. eicon_log(card, 1,
  1016.        "eicon: (%s) Could not allocate BUFFERS-struct.n", id);
  1017. kfree(card);
  1018. kfree(card->bch);
  1019. kfree(card->dbuf);
  1020. return;
  1021. }
  1022. if (!(card->sbufp = (char *) kmalloc((270 * (card->nchannels + 1)) * 2, GFP_KERNEL))) {
  1023. eicon_log(card, 1,
  1024.        "eicon: (%s) Could not allocate BUFFERSP-struct.n", id);
  1025. kfree(card);
  1026. kfree(card->bch);
  1027. kfree(card->dbuf);
  1028. kfree(card->sbuf);
  1029. return;
  1030. }
  1031. for (j=0; j< (card->nchannels + 1); j++) {
  1032. memset((char *)&card->dbuf[j], 0, sizeof(DBUFFER));
  1033. card->bch[j].de.RBuffer = (DBUFFER *)&card->dbuf[j];
  1034. memset((char *)&card->dbuf[j+(card->nchannels+1)], 0, sizeof(BUFFERS));
  1035. card->bch[j].be.RBuffer = (DBUFFER *)&card->dbuf[j+(card->nchannels+1)];
  1036. memset((char *)&card->sbuf[j], 0, sizeof(BUFFERS));
  1037. card->bch[j].de.X = (BUFFERS *)&card->sbuf[j];
  1038. memset((char *)&card->sbuf[j+(card->nchannels+1)], 0, sizeof(BUFFERS));
  1039. card->bch[j].be.X = (BUFFERS *)&card->sbuf[j+(card->nchannels+1)];
  1040. memset((char *)&card->sbufp[j], 0, 270);
  1041. card->bch[j].de.X->P = (char *)&card->sbufp[j * 270];
  1042. memset((char *)&card->sbufp[j+(card->nchannels+1)], 0, 270);
  1043. card->bch[j].be.X->P = (char *)&card->sbufp[(j+(card->nchannels+1)) * 270];
  1044. }
  1045. /* *** */
  1046. #endif /* CONFIG_ISDN_DRV_EICON_PCI */
  1047. card->next = cards;
  1048. cards = card;
  1049. }
  1050. }
  1051. /*
  1052.  * register card at linklevel
  1053.  */
  1054. static int
  1055. eicon_registercard(eicon_card * card)
  1056. {
  1057.         switch (card->bus) {
  1058. #ifdef CONFIG_ISDN_DRV_EICON_ISA
  1059. case EICON_BUS_ISA:
  1060. /* TODO something to print */
  1061. break;
  1062. #ifdef CONFIG_MCA
  1063. case EICON_BUS_MCA:
  1064. eicon_isa_printpar(&card->hwif.isa);
  1065. break;
  1066. #endif /* CONFIG_MCA */
  1067. #endif
  1068. case EICON_BUS_PCI:
  1069. break;
  1070. default:
  1071. eicon_log(card, 1,
  1072.        "eicon_registercard: Illegal BUS type %dn",
  1073.        card->bus);
  1074. return -1;
  1075.         }
  1076.         if (!register_isdn(&card->interface)) {
  1077.                 printk(KERN_WARNING
  1078.                        "eicon_registercard: Unable to register %sn",
  1079.                        card->interface.id);
  1080.                 return -1;
  1081.         }
  1082.         card->myid = card->interface.channels;
  1083.         sprintf(card->regname, "%s", card->interface.id);
  1084.         return 0;
  1085. }
  1086. static void __exit
  1087. unregister_card(eicon_card * card)
  1088. {
  1089.         isdn_ctrl cmd;
  1090.         cmd.command = ISDN_STAT_UNLOAD;
  1091.         cmd.driver = card->myid;
  1092.         card->interface.statcallb(&cmd);
  1093.         switch (card->bus) {
  1094. #ifdef CONFIG_ISDN_DRV_EICON_ISA
  1095. case EICON_BUS_ISA:
  1096. #ifdef CONFIG_MCA
  1097. case EICON_BUS_MCA:
  1098. #endif /* CONFIG_MCA */
  1099. eicon_isa_release(&card->hwif.isa);
  1100. break;
  1101. #endif
  1102. case EICON_BUS_PCI:
  1103. break;
  1104. default:
  1105. eicon_log(card, 1,
  1106.        "eicon: Invalid BUS type %dn",
  1107.        card->bus);
  1108. break;
  1109.         }
  1110. }
  1111. static void
  1112. eicon_freecard(eicon_card *card) {
  1113. int i;
  1114. for(i = 0; i < (card->nchannels + 1); i++) {
  1115. skb_queue_purge(&card->bch[i].e.X);
  1116. skb_queue_purge(&card->bch[i].e.R);
  1117. }
  1118. skb_queue_purge(&card->sndq);
  1119. skb_queue_purge(&card->rcvq);
  1120. skb_queue_purge(&card->rackq);
  1121. skb_queue_purge(&card->sackq);
  1122. skb_queue_purge(&card->statq);
  1123. #ifdef CONFIG_ISDN_DRV_EICON_PCI
  1124. kfree(card->sbufp);
  1125. kfree(card->sbuf);
  1126. kfree(card->dbuf);
  1127. #endif
  1128. kfree(card->bch);
  1129. kfree(card);
  1130. }
  1131. int
  1132. eicon_addcard(int Type, int membase, int irq, char *id, int card_id)
  1133. {
  1134. eicon_card *p;
  1135. eicon_card *q = NULL;
  1136. int registered;
  1137. int added = 0;
  1138. int failed = 0;
  1139. #ifdef CONFIG_ISDN_DRV_EICON_ISA
  1140. if (!Type) /* ISA */
  1141. if ((Type = eicon_isa_find_card(membase, irq, id)) < 0)
  1142. return 0;
  1143. #endif
  1144. eicon_alloccard(Type, membase, irq, id, card_id);
  1145.         p = cards;
  1146.         while (p) {
  1147. registered = 0;
  1148. if (!p->interface.statcallb) {
  1149. /* Not yet registered.
  1150.  * Try to register and activate it.
  1151.  */
  1152. added++;
  1153. switch (p->bus) {
  1154. #ifdef CONFIG_ISDN_DRV_EICON_ISA
  1155. case EICON_BUS_ISA:
  1156. case EICON_BUS_MCA:
  1157. if (eicon_registercard(p))
  1158. break;
  1159. registered = 1;
  1160. break;
  1161. #endif
  1162. case EICON_BUS_PCI:
  1163. #ifdef CONFIG_PCI
  1164. #ifdef CONFIG_ISDN_DRV_EICON_PCI
  1165. if (eicon_registercard(p))
  1166. break;
  1167. registered = 1;
  1168. break;
  1169. #endif
  1170. #endif
  1171. default:
  1172. printk(KERN_ERR
  1173.        "eicon: addcard: Invalid BUS type %dn",
  1174.        p->bus);
  1175. }
  1176. } else
  1177. /* Card already registered */
  1178. registered = 1;
  1179.                 if (registered) {
  1180. /* Init OK, next card ... */
  1181.                         q = p;
  1182.                         p = p->next;
  1183.                 } else {
  1184.                         /* registering failed, remove card from list, free memory */
  1185.                         printk(KERN_ERR
  1186.                                "eicon: Initialization of %s failedn",
  1187.                                p->interface.id);
  1188.                         if (q) {
  1189.                                 q->next = p->next;
  1190.                                 eicon_freecard(p);
  1191.                                 p = q->next;
  1192.                         } else {
  1193.                                 cards = p->next;
  1194.                                 eicon_freecard(p);
  1195.                                 p = cards;
  1196.                         }
  1197. failed++;
  1198.                 }
  1199. }
  1200.         return (added - failed);
  1201. }
  1202. static int __init
  1203. eicon_init(void)
  1204. {
  1205. int card_count = 0;
  1206. char tmprev[50];
  1207. DebugVar = 1;
  1208. eicon_lock = (spinlock_t) SPIN_LOCK_UNLOCKED;
  1209.         printk(KERN_INFO "%s Rev: ", DRIVERNAME);
  1210. strcpy(tmprev, eicon_revision);
  1211. printk("%s/", eicon_getrev(tmprev));
  1212. strcpy(tmprev, eicon_pci_revision);
  1213. #ifdef CONFIG_ISDN_DRV_EICON_PCI
  1214. printk("%s/", eicon_getrev(tmprev));
  1215. #else
  1216. printk("---/");
  1217. #endif
  1218. strcpy(tmprev, eicon_isa_revision);
  1219. #ifdef CONFIG_ISDN_DRV_EICON_ISA
  1220. printk("%s/", eicon_getrev(tmprev));
  1221. #else
  1222. printk("---/");
  1223. #endif
  1224. strcpy(tmprev, eicon_idi_revision);
  1225. printk("%sn", eicon_getrev(tmprev));
  1226.         printk(KERN_INFO "%s Release: %s%sn", DRIVERNAME,
  1227. DRIVERRELEASE, DRIVERPATCH);
  1228. #ifdef CONFIG_ISDN_DRV_EICON_ISA
  1229. #ifdef CONFIG_MCA
  1230. /* Check if we have MCA-bus */
  1231.         if (!MCA_bus)
  1232.                 {
  1233.                 printk(KERN_INFO
  1234.                         "eicon: No MCA bus, ISDN-interfaces  not probed.n");
  1235.         } else {
  1236. eicon_log(NULL, 8,
  1237. "eicon_mca_find_card, irq=%d.n", 
  1238. irq);
  1239.                 if (!eicon_mca_find_card(0, membase, irq, id))
  1240.                        card_count++;
  1241.         };
  1242. #else
  1243. card_count = eicon_addcard(0, membase, irq, id, 0);
  1244. #endif /* CONFIG_MCA */
  1245. #endif /* CONFIG_ISDN_DRV_EICON_ISA */
  1246.  
  1247. #ifdef CONFIG_PCI
  1248. #ifdef CONFIG_ISDN_DRV_EICON_PCI
  1249. DivasCardsDiscover();
  1250. card_count += eicon_pci_find_card(id);
  1251. #endif
  1252. #endif
  1253.         if (!cards) {
  1254. #ifdef MODULE
  1255. #ifndef CONFIG_ISDN_DRV_EICON_PCI
  1256. #ifndef CONFIG_ISDN_DRV_EICON_ISA
  1257.                 printk(KERN_INFO "Eicon: Driver is neither ISA nor PCI compiled !n");
  1258.                 printk(KERN_INFO "Eicon: Driver not loaded !n");
  1259. #else
  1260.                 printk(KERN_INFO "Eicon: No cards defined, driver not loaded !n");
  1261. #endif
  1262. #else
  1263.                 printk(KERN_INFO "Eicon: No PCI-cards found, driver not loaded !n");
  1264. #endif
  1265. #endif /* MODULE */
  1266. return -ENODEV;
  1267. } else
  1268. printk(KERN_INFO "Eicon: %d card%s addedn", card_count, 
  1269.                        (card_count>1)?"s":"");
  1270.         return 0;
  1271. }
  1272. #ifdef CONFIG_ISDN_DRV_EICON_PCI
  1273. void DIVA_DIDD_Write(DESCRIPTOR *, int);
  1274. EXPORT_SYMBOL_NOVERS(DIVA_DIDD_Read);
  1275. EXPORT_SYMBOL_NOVERS(DIVA_DIDD_Write);
  1276. EXPORT_SYMBOL_NOVERS(DivasPrintf);
  1277. #else
  1278. int DivasCardNext;
  1279. card_t DivasCards[1];
  1280. #endif
  1281. static void __exit
  1282. eicon_exit(void)
  1283. {
  1284. #if CONFIG_PCI
  1285. #ifdef CONFIG_ISDN_DRV_EICON_PCI
  1286. card_t *pCard;
  1287. word wCardIndex;
  1288. extern int Divas_major;
  1289. int iTmp = 0;
  1290. #endif
  1291. #endif
  1292.         eicon_card *card = cards;
  1293.         eicon_card *last;
  1294.         while (card) {
  1295. #ifdef CONFIG_ISDN_DRV_EICON_ISA
  1296. #ifdef CONFIG_MCA
  1297.          if (MCA_bus)
  1298.                         {
  1299.                         mca_mark_as_unused (card->mca_slot);
  1300.                         mca_set_adapter_procfn(card->mca_slot, NULL, NULL);
  1301.                         };
  1302. #endif /* CONFIG_MCA */
  1303. #endif
  1304.                 unregister_card(card); 
  1305.                 card = card->next;
  1306.         }
  1307.         card = cards;
  1308.         while (card) {
  1309.                 last = card;
  1310.                 card = card->next;
  1311. eicon_freecard(last);
  1312.         }
  1313. #if CONFIG_PCI
  1314. #ifdef CONFIG_ISDN_DRV_EICON_PCI
  1315. pCard = DivasCards;
  1316. for (wCardIndex = 0; wCardIndex < MAX_CARDS; wCardIndex++)
  1317. {
  1318. if ((pCard->hw) && (pCard->hw->in_use))
  1319. {
  1320. (*pCard->card_reset)(pCard);
  1321. UxIsrRemove(pCard->hw, pCard);
  1322. UxCardHandleFree(pCard->hw);
  1323. if(pCard->e_tbl != NULL)
  1324. {
  1325. kfree(pCard->e_tbl);
  1326. }
  1327. if(pCard->hw->card_type == DIA_CARD_TYPE_DIVA_SERVER_B)
  1328. {
  1329. release_region(pCard->hw->io_base,0x20);
  1330. release_region(pCard->hw->reset_base,0x80);
  1331. }
  1332.                         // If this is a 4BRI ...
  1333.                         if (pCard->hw->card_type == DIA_CARD_TYPE_DIVA_SERVER_Q)
  1334.                         {
  1335.                                 // Skip over the next 3 virtual adapters
  1336.                                 wCardIndex += 3;
  1337.                                 // But free their handles
  1338. for (iTmp = 0; iTmp < 3; iTmp++)
  1339. {
  1340. pCard++;
  1341. UxCardHandleFree(pCard->hw);
  1342. if(pCard->e_tbl != NULL)
  1343. {
  1344. kfree(pCard->e_tbl);
  1345. }
  1346. }
  1347.                         }
  1348. }
  1349. pCard++;
  1350. }
  1351. unregister_chrdev(Divas_major, "Divas");
  1352. #endif
  1353. #endif /* CONFIG_PCI */
  1354.         printk(KERN_INFO "%s unloadedn", DRIVERNAME);
  1355. }
  1356. #ifndef MODULE
  1357. static int __init
  1358. eicon_setup(char *line)
  1359. {
  1360.         int i, argc;
  1361. int ints[5];
  1362. char *str;
  1363. str = get_options(line, 4, ints);
  1364.         argc = ints[0];
  1365.         i = 1;
  1366. #ifdef CONFIG_ISDN_DRV_EICON_ISA
  1367.         if (argc) {
  1368. membase = irq = -1;
  1369. if (argc) {
  1370. membase = ints[i];
  1371. i++;
  1372. argc--;
  1373. }
  1374. if (argc) {
  1375. irq = ints[i];
  1376. i++;
  1377. argc--;
  1378. }
  1379. if (strlen(str)) {
  1380. strcpy(id, str);
  1381. } else {
  1382. strcpy(id, "eicon");
  1383.         printk(KERN_INFO "Eicon ISDN active driver setup (id=%s membase=0x%x irq=%d)n",
  1384. id, membase, irq);
  1385. }
  1386. #else
  1387. printk(KERN_INFO "Eicon ISDN active driver setupn");
  1388. #endif
  1389. return(1);
  1390. }
  1391. __setup("eicon=", eicon_setup);
  1392. #endif /* MODULE */
  1393. #ifdef CONFIG_ISDN_DRV_EICON_ISA
  1394. #ifdef CONFIG_MCA
  1395. struct eicon_mca_adapters_struct {
  1396. char * name;
  1397. int adf_id;
  1398. };
  1399. /* possible MCA-brands of eicon cards                                         */
  1400. struct eicon_mca_adapters_struct eicon_mca_adapters[] = {
  1401. { "ISDN-P/2 Adapter", 0x6abb },
  1402. { "ISDN-[S|SX|SCOM]/2 Adapter", 0x6a93 },
  1403. { "DIVA /MCA", 0x6336 },
  1404. { NULL, 0 },
  1405. };
  1406. int eicon_mca_find_card(int type,          /* type-idx of eicon-card          */
  1407.                         int membase,
  1408.         int irq,
  1409. char * id)         /* name of eicon-isdn-dev          */
  1410. {
  1411. int j, curr_slot = 0;
  1412.         eicon_log(NULL, 8,
  1413. "eicon_mca_find_card type: %d, membase: %#x, irq %d n",
  1414. type, membase, irq);
  1415. /* find a no-driver-assigned eicon card                               */
  1416. for (j=0; eicon_mca_adapters[j].adf_id != 0; j++) 
  1417. {
  1418. for ( curr_slot=0; curr_slot<=MCA_MAX_SLOT_NR; curr_slot++) 
  1419. {
  1420. curr_slot = mca_find_unused_adapter(
  1421.          eicon_mca_adapters[j].adf_id, curr_slot);
  1422. if (curr_slot != MCA_NOTFOUND) 
  1423. {
  1424. /* check if pre-set parameters match
  1425.    these of the card, check cards memory      */
  1426. if (!(int) eicon_mca_probe(curr_slot,
  1427.                                                            j,
  1428.                                                     membase, 
  1429.                                                            irq,
  1430.                                                            id))
  1431. {
  1432. return 0;
  1433. /* means: adapter parms did match     */
  1434. };
  1435. };
  1436. break;
  1437. /* MCA_NOTFOUND-branch: no matching adapter of
  1438.    THIS flavor found, next flavor                     */
  1439.              };
  1440. };
  1441. /* all adapter flavors checked without match, finito with:            */
  1442.         return -ENODEV;
  1443. };
  1444. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1445.  *  stolen from 3c523.c/elmc_getinfo, ewe, 10.5.1999 
  1446.  */
  1447. int eicon_info(char * buf, int slot, void *d)
  1448. {
  1449. int len = 0;
  1450. struct eicon_card *dev;
  1451.         dev = (struct eicon_card *) d;
  1452. if (dev == NULL)
  1453. return len;
  1454. len += sprintf(buf+len, "eicon ISDN adapter, type %d.n",dev->type);
  1455. len += sprintf(buf+len, "IRQ: %dn", dev->hwif.isa.irq);
  1456. len += sprintf(buf+len, "MEMBASE: %#lxn", (unsigned long)dev->hwif.isa.shmem);
  1457. return len;
  1458. };
  1459. int eicon_mca_probe(int slot,  /* slot-nr where the card was detected         */
  1460.     int a_idx, /* idx-nr of probed card in eicon_mca_adapters */
  1461.                     int membase,
  1462.                     int irq,
  1463.     char * id) /* name of eicon-isdn-dev                      */
  1464. {
  1465. unsigned char adf_pos0;
  1466. int cards_irq, cards_membase, cards_io;
  1467. int type = EICON_CTYPE_S;
  1468. int irq_array[]={0,3,4,2};
  1469. int irq_array1[]={3,4,0,0,2,10,11,12};
  1470.         adf_pos0 = mca_read_stored_pos(slot,2);
  1471. eicon_log(NULL, 8,
  1472. "eicon_mca_probe irq=%d, membase=%dn", 
  1473. irq,
  1474. membase);
  1475. switch (a_idx) {
  1476. case 0:                /* P/2-Adapter (== PRI/S2M ? )         */
  1477. cards_membase= 0xC0000+((adf_pos0>>4)*0x4000);
  1478. if (membase == -1) { 
  1479. membase = cards_membase;
  1480. } else {
  1481. if (membase != cards_membase)
  1482. return -ENODEV;
  1483. };
  1484. cards_irq=irq_array[((adf_pos0 & 0xC)>>2)];
  1485. if (irq == -1) { 
  1486. irq = cards_irq;
  1487. } else {
  1488. if (irq != cards_irq)
  1489. return -ENODEV;
  1490. };
  1491. cards_io= 0xC00 + ((adf_pos0>>4)*0x10);
  1492. type = EICON_CTYPE_ISAPRI; 
  1493. break;
  1494. case 1:                /* [S|SX|SCOM]/2                       */
  1495. cards_membase= 0xC0000+((adf_pos0>>4)*0x2000);
  1496. if (membase == -1) { 
  1497. membase = cards_membase;
  1498. } else {
  1499. if (membase != cards_membase)
  1500. return -ENODEV;
  1501. };
  1502. cards_irq=irq_array[((adf_pos0 & 0xC)>>2)];
  1503. if (irq == -1) { 
  1504. irq = cards_irq;
  1505. } else {
  1506. if (irq != cards_irq)
  1507. return -ENODEV;
  1508. };
  1509. cards_io= 0xC00 + ((adf_pos0>>4)*0x10);
  1510. type = EICON_CTYPE_SCOM; 
  1511.   break;
  1512. case 2:                /* DIVA/MCA                            */
  1513. cards_io = 0x200+ ((adf_pos0>>4)* 0x20);
  1514. cards_irq = irq_array1[(adf_pos0 & 0x7)];
  1515. if (irq == -1) { 
  1516. irq = cards_irq;
  1517. } else {
  1518. if (irq != cards_irq)
  1519. return -ENODEV;
  1520. };
  1521. type = 0; 
  1522. break;
  1523. default:
  1524. return -ENODEV;
  1525. };
  1526. /* matching membase & irq */
  1527. if ( 1 == eicon_addcard(type, membase, irq, id, 0)) { 
  1528. mca_set_adapter_name(slot, eicon_mca_adapters[a_idx].name);
  1529.    mca_set_adapter_procfn(slot, (MCA_ProcFn) eicon_info, cards);
  1530.          mca_mark_as_used(slot);
  1531. cards->mca_slot = slot; 
  1532. /* card->io noch setzen  oder ?? */
  1533. cards->mca_io = cards_io;
  1534. cards->hwif.isa.io = cards_io;
  1535. /* reset card */
  1536. outb_p(0,cards_io+1);
  1537. eicon_log(NULL, 8, "eicon_addcard: successful for slot # %d.n", 
  1538. cards->mca_slot+1);
  1539. return  0 ; /* eicon_addcard added a card */
  1540. } else {
  1541. return -ENODEV;
  1542. };
  1543. };
  1544. #endif /* CONFIG_MCA */
  1545. #endif /* CONFIG_ISDN_DRV_EICON_ISA */
  1546. module_init(eicon_init);
  1547. module_exit(eicon_exit);