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

嵌入式Linux

开发平台:

Unix_Linux

  1. /* $Id: eicon_io.c,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
  2.  *
  3.  * ISDN low-level module for Eicon active ISDN-Cards.
  4.  * Code for communicating with hardware.
  5.  *
  6.  * Copyright 1999,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.  */
  16. #include <linux/config.h>
  17. #include "eicon.h"
  18. #include "uxio.h"
  19. void
  20. eicon_io_rcv_dispatch(eicon_card *ccard) {
  21. ulong flags;
  22.         struct sk_buff *skb, *skb2, *skb_new;
  23.         eicon_IND *ind, *ind2, *ind_new;
  24.         eicon_chan *chan;
  25.         if (!ccard) {
  26.         eicon_log(ccard, 1, "eicon_err: NULL card in rcv_dispatch !n");
  27.                 return;
  28.         }
  29. while((skb = skb_dequeue(&ccard->rcvq))) {
  30.          ind = (eicon_IND *)skb->data;
  31. spin_lock_irqsave(&eicon_lock, flags);
  32.          if ((chan = ccard->IdTable[ind->IndId]) == NULL) {
  33. spin_unlock_irqrestore(&eicon_lock, flags);
  34. if (DebugVar & 1) {
  35. switch(ind->Ind) {
  36. case N_DISC_ACK: 
  37. /* doesn't matter if this happens */ 
  38. break;
  39. default: 
  40. eicon_log(ccard, 1, "idi: Indication for unknown channel Ind=%d Id=%xn", ind->Ind, ind->IndId);
  41. eicon_log(ccard, 1, "idi_hdl: Ch??: Ind=%d Id=%x Ch=%d MInd=%d MLen=%d Len=%dn",
  42. ind->Ind,ind->IndId,ind->IndCh,ind->MInd,ind->MLength,ind->RBuffer.length);
  43. }
  44. }
  45.                 dev_kfree_skb(skb);
  46.                 continue;
  47.         }
  48. spin_unlock_irqrestore(&eicon_lock, flags);
  49. if (chan->e.complete) { /* check for rec-buffer chaining */
  50. if (ind->MLength == ind->RBuffer.length) {
  51. chan->e.complete = 1;
  52. idi_handle_ind(ccard, skb);
  53. continue;
  54. }
  55. else {
  56. chan->e.complete = 0;
  57. ind->Ind = ind->MInd;
  58. skb_queue_tail(&chan->e.R, skb);
  59. continue;
  60. }
  61. }
  62. else {
  63. if (!(skb2 = skb_dequeue(&chan->e.R))) {
  64. chan->e.complete = 1;
  65.                  eicon_log(ccard, 1, "eicon: buffer incomplete, but 0 in queuen");
  66.                  dev_kfree_skb(skb);
  67. continue;
  68. }
  69.          ind2 = (eicon_IND *)skb2->data;
  70. skb_new = alloc_skb(((sizeof(eicon_IND)-1)+ind->RBuffer.length+ind2->RBuffer.length),
  71. GFP_ATOMIC);
  72. if (!skb_new) {
  73.                  eicon_log(ccard, 1, "eicon_io: skb_alloc failed in rcv_dispatch()n");
  74.                  dev_kfree_skb(skb);
  75.                  dev_kfree_skb(skb2);
  76. continue;
  77. }
  78. ind_new = (eicon_IND *)skb_put(skb_new,
  79. ((sizeof(eicon_IND)-1)+ind->RBuffer.length+ind2->RBuffer.length));
  80. ind_new->Ind = ind2->Ind;
  81. ind_new->IndId = ind2->IndId;
  82. ind_new->IndCh = ind2->IndCh;
  83. ind_new->MInd = ind2->MInd;
  84. ind_new->MLength = ind2->MLength;
  85. ind_new->RBuffer.length = ind2->RBuffer.length + ind->RBuffer.length;
  86. memcpy(&ind_new->RBuffer.P, &ind2->RBuffer.P, ind2->RBuffer.length);
  87. memcpy((&ind_new->RBuffer.P)+ind2->RBuffer.length, &ind->RBuffer.P, ind->RBuffer.length);
  88.                  dev_kfree_skb(skb);
  89.                  dev_kfree_skb(skb2);
  90. if (ind->MLength == ind->RBuffer.length) {
  91. chan->e.complete = 2;
  92. idi_handle_ind(ccard, skb_new);
  93. continue;
  94. }
  95. else {
  96. chan->e.complete = 0;
  97. skb_queue_tail(&chan->e.R, skb_new);
  98. continue;
  99. }
  100. }
  101. }
  102. }
  103. void
  104. eicon_io_ack_dispatch(eicon_card *ccard) {
  105.         struct sk_buff *skb;
  106.         if (!ccard) {
  107. eicon_log(ccard, 1, "eicon_err: NULL card in ack_dispatch!n");
  108.                 return;
  109.         }
  110. while((skb = skb_dequeue(&ccard->rackq))) {
  111. idi_handle_ack(ccard, skb);
  112. }
  113. }
  114. /*
  115.  *  IO-Functions for ISA cards
  116.  */
  117. u8 ram_inb(eicon_card *card, void *adr) {
  118.         u32 addr = (u32) adr;
  119. return(readb(addr));
  120. }
  121. u16 ram_inw(eicon_card *card, void *adr) {
  122.         u32 addr = (u32) adr;
  123. return(readw(addr));
  124. }
  125. void ram_outb(eicon_card *card, void *adr, u8 data) {
  126.         u32 addr = (u32) adr;
  127. writeb(data, addr);
  128. }
  129. void ram_outw(eicon_card *card, void *adr , u16 data) {
  130.         u32 addr = (u32) adr;
  131. writew(data, addr);
  132. }
  133. void ram_copyfromcard(eicon_card *card, void *adrto, void *adr, int len) {
  134. memcpy_fromio(adrto, adr, len);
  135. }
  136. void ram_copytocard(eicon_card *card, void *adrto, void *adr, int len) {
  137. memcpy_toio(adrto, adr, len);
  138. }
  139. #ifdef CONFIG_ISDN_DRV_EICON_PCI
  140. /*
  141.  *  IDI-Callback function
  142.  */
  143. void
  144. eicon_idi_callback(ENTITY *de)
  145. {
  146. eicon_card *ccard = (eicon_card *)de->R;
  147. struct sk_buff *skb;
  148. eicon_RC *ack;
  149. eicon_IND *ind;
  150. int len = 0;
  151. if (de->complete == 255) {
  152. /* Return Code */
  153. skb = alloc_skb(sizeof(eicon_RC), GFP_ATOMIC);
  154. if (!skb) {
  155. eicon_log(ccard, 1, "eicon_io: skb_alloc failed in _idi_callback()n");
  156. } else {
  157. ack = (eicon_RC *)skb_put(skb, sizeof(eicon_RC));
  158. ack->Rc = de->Rc;
  159. if (de->Rc == ASSIGN_OK) {
  160. ack->RcId = de->Id;
  161. de->user[1] = de->Id;
  162. } else {
  163. ack->RcId = de->user[1];
  164. }
  165. ack->RcCh = de->RcCh;
  166. ack->Reference = de->user[0];
  167. skb_queue_tail(&ccard->rackq, skb);
  168. eicon_schedule_ack(ccard);
  169. eicon_log(ccard, 128, "idi_cbk: Ch%d: Rc=%x Id=%x RLen=%x compl=%xn",
  170. de->user[0], de->Rc, ack->RcId, de->RLength, de->complete);
  171. }
  172. } else {
  173. /* Indication */
  174. if (de->complete) {
  175. len = de->RLength;
  176. } else {
  177. len = 270;
  178. if (de->RLength <= 270)
  179. eicon_log(ccard, 1, "eicon_cbk: ind not complete but <= 270n");
  180. }
  181. skb = alloc_skb((sizeof(eicon_IND) + len - 1), GFP_ATOMIC);
  182. if (!skb) {
  183. eicon_log(ccard, 1, "eicon_io: skb_alloc failed in _idi_callback()n");
  184. } else {
  185. ind = (eicon_IND *)skb_put(skb, (sizeof(eicon_IND) + len - 1));
  186. ind->Ind = de->Ind;
  187. ind->IndId = de->user[1];
  188. ind->IndCh = de->IndCh;
  189. ind->MInd  = de->Ind;
  190. ind->RBuffer.length = len;
  191. ind->MLength = de->RLength;
  192. memcpy(&ind->RBuffer.P, &de->RBuffer->P, len);
  193. skb_queue_tail(&ccard->rcvq, skb);
  194. eicon_schedule_rx(ccard);
  195. eicon_log(ccard, 128, "idi_cbk: Ch%d: Ind=%x Id=%x RLen=%x compl=%xn",
  196. de->user[0], de->Ind, ind->IndId, de->RLength, de->complete);
  197. }
  198. }
  199. de->RNum = 0;
  200. de->RNR = 0;
  201. de->Rc = 0;
  202. de->Ind = 0;
  203. }
  204. #endif /* CONFIG_ISDN_DRV_EICON_PCI */
  205. /*
  206.  *  Transmit-Function
  207.  */
  208. void
  209. eicon_io_transmit(eicon_card *ccard) {
  210.         eicon_isa_card *isa_card;
  211.         struct sk_buff *skb;
  212.         struct sk_buff *skb2;
  213.         unsigned long flags;
  214. eicon_pr_ram  *prram = 0;
  215. eicon_isa_com *com = 0;
  216. eicon_REQ *ReqOut = 0;
  217. eicon_REQ *reqbuf = 0;
  218. eicon_chan *chan;
  219. eicon_chan_ptr *chan2;
  220. int ReqCount;
  221. int scom = 0;
  222. int tmp = 0;
  223. int tmpid = 0;
  224. int quloop = 1;
  225. int dlev = 0;
  226. ENTITY *ep = 0;
  227. isa_card = &ccard->hwif.isa;
  228.         if (!ccard) {
  229.                 eicon_log(ccard, 1, "eicon_transmit: NULL card!n");
  230.                 return;
  231.         }
  232. switch(ccard->type) {
  233. #ifdef CONFIG_ISDN_DRV_EICON_ISA
  234. case EICON_CTYPE_S:
  235. case EICON_CTYPE_SX:
  236. case EICON_CTYPE_SCOM:
  237. case EICON_CTYPE_QUADRO:
  238. scom = 1;
  239. com = (eicon_isa_com *)isa_card->shmem;
  240. break;
  241. case EICON_CTYPE_S2M:
  242. scom = 0;
  243. prram = (eicon_pr_ram *)isa_card->shmem;
  244. break;
  245. #endif
  246. #ifdef CONFIG_ISDN_DRV_EICON_PCI
  247. case EICON_CTYPE_MAESTRAP:
  248. scom = 2;
  249. break;
  250. case EICON_CTYPE_MAESTRAQ:
  251. scom = 2;
  252. break;
  253. case EICON_CTYPE_MAESTRA:
  254. scom = 2;
  255. break;
  256. #endif
  257. default:
  258.                  eicon_log(ccard, 1, "eicon_transmit: unsupported card-type!n");
  259. return;
  260. }
  261. ReqCount = 0;
  262. if (!(skb2 = skb_dequeue(&ccard->sndq)))
  263. quloop = 0; 
  264. while(quloop) { 
  265. spin_lock_irqsave(&eicon_lock, flags);
  266. switch (scom) {
  267.   case 1:
  268. if ((ram_inb(ccard, &com->Req)) || (ccard->ReadyInt)) {
  269. if (!ccard->ReadyInt) {
  270. tmp = ram_inb(ccard, &com->ReadyInt) + 1;
  271. ram_outb(ccard, &com->ReadyInt, tmp);
  272. ccard->ReadyInt++;
  273. }
  274. spin_unlock_irqrestore(&eicon_lock, flags);
  275.                          skb_queue_head(&ccard->sndq, skb2);
  276.                          eicon_log(ccard, 32, "eicon: transmit: Card not readyn");
  277.                         return;
  278. }
  279. break;
  280.   case 0:
  281.                 if (!(ram_inb(ccard, &prram->ReqOutput) - ram_inb(ccard, &prram->ReqInput))) {
  282. spin_unlock_irqrestore(&eicon_lock, flags);
  283.                          skb_queue_head(&ccard->sndq, skb2);
  284.                          eicon_log(ccard, 32, "eicon: transmit: Card not readyn");
  285.                         return;
  286.                  }
  287. break;
  288. }
  289. spin_unlock_irqrestore(&eicon_lock, flags);
  290. chan2 = (eicon_chan_ptr *)skb2->data;
  291. chan = chan2->ptr;
  292. if (!chan->e.busy) {
  293.  if((skb = skb_dequeue(&chan->e.X))) { 
  294.   reqbuf = (eicon_REQ *)skb->data;
  295.   if ((reqbuf->Reference) && (chan->e.B2Id == 0) && (reqbuf->ReqId & 0x1f)) {
  296. eicon_log(ccard, 16, "eicon: transmit: error Id=0 on %d (Net)n", chan->No); 
  297.   } else {
  298. spin_lock_irqsave(&eicon_lock, flags);
  299. switch (scom) {
  300.   case 1:
  301. ram_outw(ccard, &com->XBuffer.length, reqbuf->XBuffer.length);
  302. ram_copytocard(ccard, &com->XBuffer.P, &reqbuf->XBuffer.P, reqbuf->XBuffer.length);
  303. ram_outb(ccard, &com->ReqCh, reqbuf->ReqCh);
  304. break;
  305.   case 0:
  306. /* get address of next available request buffer */
  307. ReqOut = (eicon_REQ *)&prram->B[ram_inw(ccard, &prram->NextReq)];
  308. ram_outw(ccard, &ReqOut->XBuffer.length, reqbuf->XBuffer.length);
  309. ram_copytocard(ccard, &ReqOut->XBuffer.P, &reqbuf->XBuffer.P, reqbuf->XBuffer.length);
  310. ram_outb(ccard, &ReqOut->ReqCh, reqbuf->ReqCh);
  311. ram_outb(ccard, &ReqOut->Req, reqbuf->Req); 
  312. break;
  313. }
  314. dlev = 160;
  315. if (reqbuf->ReqId & 0x1f) { /* if this is no ASSIGN */
  316. if (!reqbuf->Reference) { /* Signal Layer */
  317. switch (scom) {
  318.   case 1:
  319. ram_outb(ccard, &com->ReqId, chan->e.D3Id); 
  320. break;
  321.   case 0:
  322. ram_outb(ccard, &ReqOut->ReqId, chan->e.D3Id); 
  323. break;
  324.   case 2:
  325. ep = &chan->de;
  326. break;
  327. }
  328. tmpid = chan->e.D3Id;
  329. chan->e.ReqCh = 0; 
  330. }
  331. else { /* Net Layer */
  332. switch(scom) {
  333.   case 1:
  334. ram_outb(ccard, &com->ReqId, chan->e.B2Id); 
  335. break;
  336.   case 0:
  337. ram_outb(ccard, &ReqOut->ReqId, chan->e.B2Id); 
  338. break;
  339.   case 2:
  340. ep = &chan->be;
  341. break;
  342. }
  343. tmpid = chan->e.B2Id;
  344. chan->e.ReqCh = 1;
  345. if (((reqbuf->Req & 0x0f) == 0x08) ||
  346.    ((reqbuf->Req & 0x0f) == 0x01)) { /* Send Data */
  347. chan->waitq = reqbuf->XBuffer.length;
  348. chan->waitpq += reqbuf->XBuffer.length;
  349. dlev = 128;
  350. }
  351. }
  352. } else { /* It is an ASSIGN */
  353. switch(scom) {
  354.   case 1:
  355. ram_outb(ccard, &com->ReqId, reqbuf->ReqId); 
  356. break;
  357.   case 0:
  358. ram_outb(ccard, &ReqOut->ReqId, reqbuf->ReqId); 
  359. break;
  360.   case 2:
  361. if (!reqbuf->Reference) 
  362. ep = &chan->de;
  363. else
  364. ep = &chan->be;
  365. ep->Id = reqbuf->ReqId;
  366. break;
  367. }
  368. tmpid = reqbuf->ReqId;
  369. if (!reqbuf->Reference) 
  370. chan->e.ReqCh = 0; 
  371.  else
  372. chan->e.ReqCh = 1; 
  373. switch(scom) {
  374.   case 1:
  375.   chan->e.ref = ccard->ref_out++;
  376. break;
  377.   case 0:
  378.   chan->e.ref = ram_inw(ccard, &ReqOut->Reference);
  379. break;
  380.   case 2:
  381. chan->e.ref = chan->No;
  382. break;
  383. }
  384. chan->e.Req = reqbuf->Req;
  385. ReqCount++; 
  386. switch (scom) {
  387.   case 1:
  388. ram_outb(ccard, &com->Req, reqbuf->Req); 
  389. break;
  390.   case 0:
  391. ram_outw(ccard, &prram->NextReq, ram_inw(ccard, &ReqOut->next)); 
  392. break;
  393.   case 2:
  394. #ifdef CONFIG_ISDN_DRV_EICON_PCI
  395. if (!ep) break;
  396. ep->callback = eicon_idi_callback;
  397. ep->R = (BUFFERS *)ccard;
  398. ep->user[0] = (word)chan->No;
  399. ep->user[1] = (word)tmpid;
  400. ep->XNum = 1;
  401. ep->RNum = 0;
  402. ep->RNR = 0;
  403. ep->Rc = 0;
  404. ep->Ind = 0;
  405. ep->X->PLength = reqbuf->XBuffer.length;
  406. memcpy(ep->X->P, &reqbuf->XBuffer.P, reqbuf->XBuffer.length);
  407. ep->ReqCh = reqbuf->ReqCh;
  408. ep->Req = reqbuf->Req;
  409. #endif
  410. break;
  411. }
  412. chan->e.busy = 1;
  413. spin_unlock_irqrestore(&eicon_lock, flags);
  414.                 eicon_log(ccard, dlev, "eicon: Req=%d Id=%x Ch=%d Len=%d Ref=%dn", 
  415. reqbuf->Req, tmpid, 
  416. reqbuf->ReqCh, reqbuf->XBuffer.length,
  417. chan->e.ref); 
  418. #ifdef CONFIG_ISDN_DRV_EICON_PCI
  419. if (scom == 2) {
  420. if (ep) {
  421. ccard->d->request(ep);
  422. if (ep->Rc)
  423. eicon_idi_callback(ep);
  424. }
  425. }
  426. #endif
  427.   }
  428.   dev_kfree_skb(skb);
  429.  }
  430.  dev_kfree_skb(skb2);
  431. else {
  432. skb_queue_tail(&ccard->sackq, skb2);
  433.                  eicon_log(ccard, 128, "eicon: transmit: busy chan %dn", chan->No); 
  434. }
  435. switch(scom) {
  436. case 1:
  437. quloop = 0;
  438. break;
  439. case 0:
  440. case 2:
  441. if (!(skb2 = skb_dequeue(&ccard->sndq)))
  442. quloop = 0;
  443. break;
  444. }
  445. }
  446. if (!scom)
  447. ram_outb(ccard, &prram->ReqInput, (__u8)(ram_inb(ccard, &prram->ReqInput) + ReqCount)); 
  448. while((skb = skb_dequeue(&ccard->sackq))) { 
  449. skb_queue_tail(&ccard->sndq, skb);
  450. }
  451. }
  452. #ifdef CONFIG_ISDN_DRV_EICON_ISA
  453. /*
  454.  * IRQ handler 
  455.  */
  456. void
  457. eicon_irq(int irq, void *dev_id, struct pt_regs *regs) {
  458. eicon_card *ccard = (eicon_card *)dev_id;
  459.         eicon_isa_card *isa_card;
  460. eicon_pr_ram  *prram = 0;
  461. eicon_isa_com *com = 0;
  462.         eicon_RC *RcIn;
  463.         eicon_IND *IndIn;
  464. struct sk_buff *skb;
  465.         int Count = 0;
  466. int Rc = 0;
  467. int Ind = 0;
  468. unsigned char *irqprobe = 0;
  469. int scom = 0;
  470. int tmp = 0;
  471. int dlev = 0;
  472.         if (!ccard) {
  473.                 eicon_log(ccard, 1, "eicon_irq: spurious interrupt %dn", irq);
  474.                 return;
  475.         }
  476. if (ccard->type == EICON_CTYPE_QUADRO) {
  477. tmp = 4;
  478. while(tmp) {
  479. com = (eicon_isa_com *)ccard->hwif.isa.shmem;
  480. if ((readb(ccard->hwif.isa.intack))) { /* quadro found */
  481. break;
  482. }
  483. ccard = ccard->qnext;
  484. tmp--;
  485. }
  486. }
  487. isa_card = &ccard->hwif.isa;
  488. switch(ccard->type) {
  489. case EICON_CTYPE_S:
  490. case EICON_CTYPE_SX:
  491. case EICON_CTYPE_SCOM:
  492. case EICON_CTYPE_QUADRO:
  493. scom = 1;
  494. com = (eicon_isa_com *)isa_card->shmem;
  495. irqprobe = &isa_card->irqprobe;
  496. break;
  497. case EICON_CTYPE_S2M:
  498. scom = 0;
  499. prram = (eicon_pr_ram *)isa_card->shmem;
  500. irqprobe = &isa_card->irqprobe;
  501. break;
  502. default:
  503.                  eicon_log(ccard, 1, "eicon_irq: unsupported card-type!n");
  504. return;
  505. }
  506. if (*irqprobe) {
  507. switch(ccard->type) {
  508. case EICON_CTYPE_S:
  509. case EICON_CTYPE_SX:
  510. case EICON_CTYPE_SCOM:
  511. case EICON_CTYPE_QUADRO:
  512. if (readb(isa_card->intack)) {
  513.                          writeb(0, &com->Rc);
  514. writeb(0, isa_card->intack);
  515. }
  516. (*irqprobe)++;
  517. break;
  518. case EICON_CTYPE_S2M:
  519. if (readb(isa_card->intack)) {
  520.                          writeb(0, &prram->RcOutput);
  521. writeb(0, isa_card->intack);
  522. }
  523. (*irqprobe)++;
  524. break;
  525. }
  526. return;
  527. }
  528. switch(ccard->type) {
  529. case EICON_CTYPE_S:
  530. case EICON_CTYPE_SX:
  531. case EICON_CTYPE_SCOM:
  532. case EICON_CTYPE_QUADRO:
  533. case EICON_CTYPE_S2M:
  534. if (!(readb(isa_card->intack))) { /* card did not interrupt */
  535. eicon_log(ccard, 1, "eicon: IRQ: card reports no interrupt!n");
  536. return;
  537. break;
  538. }
  539.     if (scom) {
  540.         /* if a return code is available ...  */
  541. if ((tmp = ram_inb(ccard, &com->Rc))) {
  542. eicon_RC *ack;
  543. if (tmp == READY_INT) {
  544.                         eicon_log(ccard, 64, "eicon: IRQ Rc=READY_INTn");
  545. if (ccard->ReadyInt) {
  546. ccard->ReadyInt--;
  547. ram_outb(ccard, &com->Rc, 0);
  548. eicon_schedule_tx(ccard);
  549. }
  550. } else {
  551. skb = alloc_skb(sizeof(eicon_RC), GFP_ATOMIC);
  552. if (!skb) {
  553.                  eicon_log(ccard, 1, "eicon_io: skb_alloc failed in _irq()n");
  554. } else {
  555. ack = (eicon_RC *)skb_put(skb, sizeof(eicon_RC));
  556. ack->Rc = tmp;
  557. ack->RcId = ram_inb(ccard, &com->RcId);
  558. ack->RcCh = ram_inb(ccard, &com->RcCh);
  559. ack->Reference = ccard->ref_in++;
  560.                          eicon_log(ccard, 128, "eicon: IRQ Rc=%d Id=%x Ch=%d Ref=%dn",
  561. tmp,ack->RcId,ack->RcCh,ack->Reference);
  562. skb_queue_tail(&ccard->rackq, skb);
  563. eicon_schedule_ack(ccard);
  564. }
  565. ram_outb(ccard, &com->Req, 0);
  566. ram_outb(ccard, &com->Rc, 0);
  567. }
  568. } else {
  569.         /* if an indication is available ...  */
  570. if ((tmp = ram_inb(ccard, &com->Ind))) {
  571. eicon_IND *ind;
  572. int len = ram_inw(ccard, &com->RBuffer.length);
  573. skb = alloc_skb((sizeof(eicon_IND) + len - 1), GFP_ATOMIC);
  574. if (!skb) {
  575.                  eicon_log(ccard, 1, "eicon_io: skb_alloc failed in _irq()n");
  576. } else {
  577. ind = (eicon_IND *)skb_put(skb, (sizeof(eicon_IND) + len - 1));
  578. ind->Ind = tmp;
  579. ind->IndId = ram_inb(ccard, &com->IndId);
  580. ind->IndCh = ram_inb(ccard, &com->IndCh);
  581. ind->MInd  = ram_inb(ccard, &com->MInd);
  582. ind->MLength = ram_inw(ccard, &com->MLength);
  583. ind->RBuffer.length = len;
  584. if ((tmp == 1) || (tmp == 8))
  585. dlev = 128;
  586. else
  587. dlev = 192;
  588.                         eicon_log(ccard, dlev, "eicon: IRQ Ind=%d Id=%x Ch=%d MInd=%d MLen=%d Len=%dn",
  589. tmp,ind->IndId,ind->IndCh,ind->MInd,ind->MLength,len);
  590. ram_copyfromcard(ccard, &ind->RBuffer.P, &com->RBuffer.P, len);
  591. skb_queue_tail(&ccard->rcvq, skb);
  592. eicon_schedule_rx(ccard);
  593. }
  594. ram_outb(ccard, &com->Ind, 0);
  595. }
  596. }
  597.     } else {
  598.         /* if return codes are available ...  */
  599.         if((Count = ram_inb(ccard, &prram->RcOutput))) {
  600. eicon_RC *ack;
  601.                 /* get the buffer address of the first return code */
  602.                 RcIn = (eicon_RC *)&prram->B[ram_inw(ccard, &prram->NextRc)];
  603.                 /* for all return codes do ...  */
  604.                 while(Count--) {
  605.                         if((Rc=ram_inb(ccard, &RcIn->Rc))) {
  606. skb = alloc_skb(sizeof(eicon_RC), GFP_ATOMIC);
  607. if (!skb) {
  608.                  eicon_log(ccard, 1, "eicon_io: skb_alloc failed in _irq()n");
  609. } else {
  610. ack = (eicon_RC *)skb_put(skb, sizeof(eicon_RC));
  611. ack->Rc = Rc;
  612. ack->RcId = ram_inb(ccard, &RcIn->RcId);
  613. ack->RcCh = ram_inb(ccard, &RcIn->RcCh);
  614. ack->Reference = ram_inw(ccard, &RcIn->Reference);
  615.                           eicon_log(ccard, 128, "eicon: IRQ Rc=%d Id=%x Ch=%d Ref=%dn",
  616. Rc,ack->RcId,ack->RcCh,ack->Reference);
  617. skb_queue_tail(&ccard->rackq, skb);
  618. eicon_schedule_ack(ccard);
  619. }
  620.                         ram_outb(ccard, &RcIn->Rc, 0);
  621.                         }
  622.                         /* get buffer address of next return code   */
  623.                         RcIn = (eicon_RC *)&prram->B[ram_inw(ccard, &RcIn->next)];
  624.                 }
  625.                 /* clear all return codes (no chaining!) */
  626.                 ram_outb(ccard, &prram->RcOutput, 0);
  627.         }
  628.         /* if indications are available ... */
  629.         if((Count = ram_inb(ccard, &prram->IndOutput))) {
  630. eicon_IND *ind;
  631.                 /* get the buffer address of the first indication */
  632.                 IndIn = (eicon_IND *)&prram->B[ram_inw(ccard, &prram->NextInd)];
  633.                 /* for all indications do ... */
  634.                 while(Count--) {
  635. Ind = ram_inb(ccard, &IndIn->Ind);
  636. if(Ind) {
  637. int len = ram_inw(ccard, &IndIn->RBuffer.length);
  638. skb = alloc_skb((sizeof(eicon_IND) + len - 1), GFP_ATOMIC);
  639. if (!skb) {
  640.                  eicon_log(ccard, 1, "eicon_io: skb_alloc failed in _irq()n");
  641. } else {
  642. ind = (eicon_IND *)skb_put(skb, (sizeof(eicon_IND) + len - 1));
  643. ind->Ind = Ind;
  644. ind->IndId = ram_inb(ccard, &IndIn->IndId);
  645. ind->IndCh = ram_inb(ccard, &IndIn->IndCh);
  646. ind->MInd  = ram_inb(ccard, &IndIn->MInd);
  647. ind->MLength = ram_inw(ccard, &IndIn->MLength);
  648. ind->RBuffer.length = len;
  649. if ((Ind == 1) || (Ind == 8))
  650. dlev = 128;
  651. else
  652. dlev = 192;
  653.                           eicon_log(ccard, dlev, "eicon: IRQ Ind=%d Id=%x Ch=%d MInd=%d MLen=%d Len=%dn",
  654. Ind,ind->IndId,ind->IndCh,ind->MInd,ind->MLength,len);
  655.                                 ram_copyfromcard(ccard, &ind->RBuffer.P, &IndIn->RBuffer.P, len);
  656. skb_queue_tail(&ccard->rcvq, skb);
  657. eicon_schedule_rx(ccard);
  658. }
  659. ram_outb(ccard, &IndIn->Ind, 0);
  660.                         }
  661.                         /* get buffer address of next indication  */
  662.                         IndIn = (eicon_IND *)&prram->B[ram_inw(ccard, &IndIn->next)];
  663.                 }
  664.                 ram_outb(ccard, &prram->IndOutput, 0);
  665.         }
  666.     } 
  667. /* clear interrupt */
  668. switch(ccard->type) {
  669. case EICON_CTYPE_QUADRO:
  670. writeb(0, isa_card->intack);
  671. writeb(0, &com[0x401]);
  672. break;
  673. case EICON_CTYPE_S:
  674. case EICON_CTYPE_SX:
  675. case EICON_CTYPE_SCOM:
  676. case EICON_CTYPE_S2M:
  677. writeb(0, isa_card->intack);
  678. break;
  679. }
  680.   return;
  681. }
  682. #endif