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

嵌入式Linux

开发平台:

Unix_Linux

  1. /* $Id: avm_pci.c,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
  2.  *
  3.  * low level stuff for AVM Fritz!PCI and ISA PnP isdn cards
  4.  *
  5.  * Author       Karsten Keil
  6.  * Copyright    by Karsten Keil      <keil@isdn4linux.de>
  7.  *
  8.  * This software may be used and distributed according to the terms
  9.  * of the GNU General Public License, incorporated herein by reference.
  10.  *
  11.  * Thanks to AVM, Berlin for information
  12.  *
  13.  */
  14. #define __NO_VERSION__
  15. #include <linux/config.h>
  16. #include <linux/init.h>
  17. #include "hisax.h"
  18. #include "isac.h"
  19. #include "isdnl1.h"
  20. #include <linux/pci.h>
  21. #include <linux/interrupt.h>
  22. extern const char *CardType[];
  23. static const char *avm_pci_rev = "$Revision: 1.1.4.1 $";
  24. #define  AVM_FRITZ_PCI 1
  25. #define  AVM_FRITZ_PNP 2
  26. #define  HDLC_FIFO 0x0
  27. #define  HDLC_STATUS 0x4
  28. #define  AVM_HDLC_1 0x00
  29. #define  AVM_HDLC_2 0x01
  30. #define  AVM_ISAC_FIFO 0x02
  31. #define  AVM_ISAC_REG_LOW 0x04
  32. #define  AVM_ISAC_REG_HIGH 0x06
  33. #define  AVM_STATUS0_IRQ_ISAC 0x01
  34. #define  AVM_STATUS0_IRQ_HDLC 0x02
  35. #define  AVM_STATUS0_IRQ_TIMER 0x04
  36. #define  AVM_STATUS0_IRQ_MASK 0x07
  37. #define  AVM_STATUS0_RESET 0x01
  38. #define  AVM_STATUS0_DIS_TIMER 0x02
  39. #define  AVM_STATUS0_RES_TIMER 0x04
  40. #define  AVM_STATUS0_ENA_IRQ 0x08
  41. #define  AVM_STATUS0_TESTBIT 0x10
  42. #define  AVM_STATUS1_INT_SEL 0x0f
  43. #define  AVM_STATUS1_ENA_IOM 0x80
  44. #define  HDLC_MODE_ITF_FLG 0x01
  45. #define  HDLC_MODE_TRANS 0x02
  46. #define  HDLC_MODE_CCR_7 0x04
  47. #define  HDLC_MODE_CCR_16 0x08
  48. #define  HDLC_MODE_TESTLOOP 0x80
  49. #define  HDLC_INT_XPR 0x80
  50. #define  HDLC_INT_XDU 0x40
  51. #define  HDLC_INT_RPR 0x20
  52. #define  HDLC_INT_MASK 0xE0
  53. #define  HDLC_STAT_RME 0x01
  54. #define  HDLC_STAT_RDO 0x10
  55. #define  HDLC_STAT_CRCVFRRAB 0x0E
  56. #define  HDLC_STAT_CRCVFR 0x06
  57. #define  HDLC_STAT_RML_MASK 0x3f00
  58. #define  HDLC_CMD_XRS 0x80
  59. #define  HDLC_CMD_XME 0x01
  60. #define  HDLC_CMD_RRS 0x20
  61. #define  HDLC_CMD_XML_MASK 0x3f00
  62. /* Interface functions */
  63. static u_char
  64. ReadISAC(struct IsdnCardState *cs, u_char offset)
  65. {
  66. register u_char idx = (offset > 0x2f) ? AVM_ISAC_REG_HIGH : AVM_ISAC_REG_LOW;
  67. register u_char val;
  68. register long flags;
  69. save_flags(flags);
  70. cli();
  71. outb(idx, cs->hw.avm.cfg_reg + 4);
  72. val = inb(cs->hw.avm.isac + (offset & 0xf));
  73. restore_flags(flags);
  74. return (val);
  75. }
  76. static void
  77. WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value)
  78. {
  79. register u_char idx = (offset > 0x2f) ? AVM_ISAC_REG_HIGH : AVM_ISAC_REG_LOW;
  80. register long flags;
  81. save_flags(flags);
  82. cli();
  83. outb(idx, cs->hw.avm.cfg_reg + 4);
  84. outb(value, cs->hw.avm.isac + (offset & 0xf));
  85. restore_flags(flags);
  86. }
  87. static void
  88. ReadISACfifo(struct IsdnCardState *cs, u_char * data, int size)
  89. {
  90. outb(AVM_ISAC_FIFO, cs->hw.avm.cfg_reg + 4);
  91. insb(cs->hw.avm.isac, data, size);
  92. }
  93. static void
  94. WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size)
  95. {
  96. outb(AVM_ISAC_FIFO, cs->hw.avm.cfg_reg + 4);
  97. outsb(cs->hw.avm.isac, data, size);
  98. }
  99. static inline u_int
  100. ReadHDLCPCI(struct IsdnCardState *cs, int chan, u_char offset)
  101. {
  102. register u_int idx = chan ? AVM_HDLC_2 : AVM_HDLC_1;
  103. register u_int val;
  104. register long flags;
  105. save_flags(flags);
  106. cli();
  107. outl(idx, cs->hw.avm.cfg_reg + 4);
  108. val = inl(cs->hw.avm.isac + offset);
  109. restore_flags(flags);
  110. return (val);
  111. }
  112. static inline void
  113. WriteHDLCPCI(struct IsdnCardState *cs, int chan, u_char offset, u_int value)
  114. {
  115. register u_int idx = chan ? AVM_HDLC_2 : AVM_HDLC_1;
  116. register long flags;
  117. save_flags(flags);
  118. cli();
  119. outl(idx, cs->hw.avm.cfg_reg + 4);
  120. outl(value, cs->hw.avm.isac + offset);
  121. restore_flags(flags);
  122. }
  123. static inline u_char
  124. ReadHDLCPnP(struct IsdnCardState *cs, int chan, u_char offset)
  125. {
  126. register u_char idx = chan ? AVM_HDLC_2 : AVM_HDLC_1;
  127. register u_char val;
  128. register long flags;
  129. save_flags(flags);
  130. cli();
  131. outb(idx, cs->hw.avm.cfg_reg + 4);
  132. val = inb(cs->hw.avm.isac + offset);
  133. restore_flags(flags);
  134. return (val);
  135. }
  136. static inline void
  137. WriteHDLCPnP(struct IsdnCardState *cs, int chan, u_char offset, u_char value)
  138. {
  139. register u_char idx = chan ? AVM_HDLC_2 : AVM_HDLC_1;
  140. register long flags;
  141. save_flags(flags);
  142. cli();
  143. outb(idx, cs->hw.avm.cfg_reg + 4);
  144. outb(value, cs->hw.avm.isac + offset);
  145. restore_flags(flags);
  146. }
  147. static u_char
  148. ReadHDLC_s(struct IsdnCardState *cs, int chan, u_char offset)
  149. {
  150. return(0xff & ReadHDLCPCI(cs, chan, offset));
  151. }
  152. static void
  153. WriteHDLC_s(struct IsdnCardState *cs, int chan, u_char offset, u_char value)
  154. {
  155. WriteHDLCPCI(cs, chan, offset, value);
  156. }
  157. static inline
  158. struct BCState *Sel_BCS(struct IsdnCardState *cs, int channel)
  159. {
  160. if (cs->bcs[0].mode && (cs->bcs[0].channel == channel))
  161. return(&cs->bcs[0]);
  162. else if (cs->bcs[1].mode && (cs->bcs[1].channel == channel))
  163. return(&cs->bcs[1]);
  164. else
  165. return(NULL);
  166. }
  167. void inline
  168. hdlc_sched_event(struct BCState *bcs, int event)
  169. {
  170. bcs->event |= 1 << event;
  171. queue_task(&bcs->tqueue, &tq_immediate);
  172. mark_bh(IMMEDIATE_BH);
  173. }
  174. void
  175. write_ctrl(struct BCState *bcs, int which) {
  176. if (bcs->cs->debug & L1_DEB_HSCX)
  177. debugl1(bcs->cs, "hdlc %c wr%x ctrl %x",
  178. 'A' + bcs->channel, which, bcs->hw.hdlc.ctrl.ctrl);
  179. if (bcs->cs->subtyp == AVM_FRITZ_PCI) {
  180. WriteHDLCPCI(bcs->cs, bcs->channel, HDLC_STATUS, bcs->hw.hdlc.ctrl.ctrl);
  181. } else {
  182. if (which & 4)
  183. WriteHDLCPnP(bcs->cs, bcs->channel, HDLC_STATUS + 2,
  184. bcs->hw.hdlc.ctrl.sr.mode);
  185. if (which & 2)
  186. WriteHDLCPnP(bcs->cs, bcs->channel, HDLC_STATUS + 1,
  187. bcs->hw.hdlc.ctrl.sr.xml);
  188. if (which & 1)
  189. WriteHDLCPnP(bcs->cs, bcs->channel, HDLC_STATUS,
  190. bcs->hw.hdlc.ctrl.sr.cmd);
  191. }
  192. }
  193. void
  194. modehdlc(struct BCState *bcs, int mode, int bc)
  195. {
  196. struct IsdnCardState *cs = bcs->cs;
  197. int hdlc = bcs->channel;
  198. if (cs->debug & L1_DEB_HSCX)
  199. debugl1(cs, "hdlc %c mode %d --> %d ichan %d --> %d",
  200. 'A' + hdlc, bcs->mode, mode, hdlc, bc);
  201. bcs->hw.hdlc.ctrl.ctrl = 0;
  202. switch (mode) {
  203. case (-1): /* used for init */
  204. bcs->mode = 1;
  205. bcs->channel = bc;
  206. bc = 0;
  207. case (L1_MODE_NULL):
  208. if (bcs->mode == L1_MODE_NULL)
  209. return;
  210. bcs->hw.hdlc.ctrl.sr.cmd  = HDLC_CMD_XRS | HDLC_CMD_RRS;
  211. bcs->hw.hdlc.ctrl.sr.mode = HDLC_MODE_TRANS;
  212. write_ctrl(bcs, 5);
  213. bcs->mode = L1_MODE_NULL;
  214. bcs->channel = bc;
  215. break;
  216. case (L1_MODE_TRANS):
  217. bcs->mode = mode;
  218. bcs->channel = bc;
  219. bcs->hw.hdlc.ctrl.sr.cmd  = HDLC_CMD_XRS | HDLC_CMD_RRS;
  220. bcs->hw.hdlc.ctrl.sr.mode = HDLC_MODE_TRANS;
  221. write_ctrl(bcs, 5);
  222. bcs->hw.hdlc.ctrl.sr.cmd = HDLC_CMD_XRS;
  223. write_ctrl(bcs, 1);
  224. bcs->hw.hdlc.ctrl.sr.cmd = 0;
  225. hdlc_sched_event(bcs, B_XMTBUFREADY);
  226. break;
  227. case (L1_MODE_HDLC):
  228. bcs->mode = mode;
  229. bcs->channel = bc;
  230. bcs->hw.hdlc.ctrl.sr.cmd  = HDLC_CMD_XRS | HDLC_CMD_RRS;
  231. bcs->hw.hdlc.ctrl.sr.mode = HDLC_MODE_ITF_FLG;
  232. write_ctrl(bcs, 5);
  233. bcs->hw.hdlc.ctrl.sr.cmd = HDLC_CMD_XRS;
  234. write_ctrl(bcs, 1);
  235. bcs->hw.hdlc.ctrl.sr.cmd = 0;
  236. hdlc_sched_event(bcs, B_XMTBUFREADY);
  237. break;
  238. }
  239. }
  240. static inline void
  241. hdlc_empty_fifo(struct BCState *bcs, int count)
  242. {
  243. register u_int *ptr;
  244. u_char *p;
  245. u_char idx = bcs->channel ? AVM_HDLC_2 : AVM_HDLC_1;
  246. int cnt=0;
  247. struct IsdnCardState *cs = bcs->cs;
  248. if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO))
  249. debugl1(cs, "hdlc_empty_fifo %d", count);
  250. if (bcs->hw.hdlc.rcvidx + count > HSCX_BUFMAX) {
  251. if (cs->debug & L1_DEB_WARN)
  252. debugl1(cs, "hdlc_empty_fifo: incoming packet too large");
  253. return;
  254. }
  255. ptr = (u_int *) p = bcs->hw.hdlc.rcvbuf + bcs->hw.hdlc.rcvidx;
  256. bcs->hw.hdlc.rcvidx += count;
  257. if (cs->subtyp == AVM_FRITZ_PCI) {
  258. outl(idx, cs->hw.avm.cfg_reg + 4);
  259. while (cnt < count) {
  260. #ifdef __powerpc__
  261. #ifdef CONFIG_APUS
  262. *ptr++ = in_le32((unsigned *)(cs->hw.avm.isac +_IO_BASE));
  263. #else
  264. *ptr++ = in_be32((unsigned *)(cs->hw.avm.isac +_IO_BASE));
  265. #endif /* CONFIG_APUS */
  266. #else
  267. *ptr++ = inl(cs->hw.avm.isac);
  268. #endif /* __powerpc__ */
  269. cnt += 4;
  270. }
  271. } else {
  272. outb(idx, cs->hw.avm.cfg_reg + 4);
  273. while (cnt < count) {
  274. *p++ = inb(cs->hw.avm.isac);
  275. cnt++;
  276. }
  277. }
  278. if (cs->debug & L1_DEB_HSCX_FIFO) {
  279. char *t = bcs->blog;
  280. if (cs->subtyp == AVM_FRITZ_PNP)
  281. p = (u_char *) ptr;
  282. t += sprintf(t, "hdlc_empty_fifo %c cnt %d",
  283.      bcs->channel ? 'B' : 'A', count);
  284. QuickHex(t, p, count);
  285. debugl1(cs, bcs->blog);
  286. }
  287. }
  288. static inline void
  289. hdlc_fill_fifo(struct BCState *bcs)
  290. {
  291. struct IsdnCardState *cs = bcs->cs;
  292. int count, cnt =0;
  293. int fifo_size = 32;
  294. u_char *p;
  295. u_int *ptr;
  296. if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO))
  297. debugl1(cs, "hdlc_fill_fifo");
  298. if (!bcs->tx_skb)
  299. return;
  300. if (bcs->tx_skb->len <= 0)
  301. return;
  302. bcs->hw.hdlc.ctrl.sr.cmd &= ~HDLC_CMD_XME;
  303. if (bcs->tx_skb->len > fifo_size) {
  304. count = fifo_size;
  305. } else {
  306. count = bcs->tx_skb->len;
  307. if (bcs->mode != L1_MODE_TRANS)
  308. bcs->hw.hdlc.ctrl.sr.cmd |= HDLC_CMD_XME;
  309. }
  310. if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO))
  311. debugl1(cs, "hdlc_fill_fifo %d/%ld", count, bcs->tx_skb->len);
  312. ptr = (u_int *) p = bcs->tx_skb->data;
  313. skb_pull(bcs->tx_skb, count);
  314. bcs->tx_cnt -= count;
  315. bcs->hw.hdlc.count += count;
  316. bcs->hw.hdlc.ctrl.sr.xml = ((count == fifo_size) ? 0 : count);
  317. write_ctrl(bcs, 3);  /* sets the correct index too */
  318. if (cs->subtyp == AVM_FRITZ_PCI) {
  319. while (cnt<count) {
  320. #ifdef __powerpc__
  321. #ifdef CONFIG_APUS
  322. out_le32((unsigned *)(cs->hw.avm.isac +_IO_BASE), *ptr++);
  323. #else
  324. out_be32((unsigned *)(cs->hw.avm.isac +_IO_BASE), *ptr++);
  325. #endif /* CONFIG_APUS */
  326. #else
  327. outl(*ptr++, cs->hw.avm.isac);
  328. #endif /* __powerpc__ */
  329. cnt += 4;
  330. }
  331. } else {
  332. while (cnt<count) {
  333. outb(*p++, cs->hw.avm.isac);
  334. cnt++;
  335. }
  336. }
  337. if (cs->debug & L1_DEB_HSCX_FIFO) {
  338. char *t = bcs->blog;
  339. if (cs->subtyp == AVM_FRITZ_PNP)
  340. p = (u_char *) ptr;
  341. t += sprintf(t, "hdlc_fill_fifo %c cnt %d",
  342.      bcs->channel ? 'B' : 'A', count);
  343. QuickHex(t, p, count);
  344. debugl1(cs, bcs->blog);
  345. }
  346. }
  347. static void
  348. fill_hdlc(struct BCState *bcs)
  349. {
  350. long flags;
  351. save_flags(flags);
  352. cli();
  353. hdlc_fill_fifo(bcs);
  354. restore_flags(flags);
  355. }
  356. static inline void
  357. HDLC_irq(struct BCState *bcs, u_int stat) {
  358. int len;
  359. struct sk_buff *skb;
  360. if (bcs->cs->debug & L1_DEB_HSCX)
  361. debugl1(bcs->cs, "ch%d stat %#x", bcs->channel, stat);
  362. if (stat & HDLC_INT_RPR) {
  363. if (stat & HDLC_STAT_RDO) {
  364. if (bcs->cs->debug & L1_DEB_HSCX)
  365. debugl1(bcs->cs, "RDO");
  366. else
  367. debugl1(bcs->cs, "ch%d stat %#x", bcs->channel, stat);
  368. bcs->hw.hdlc.ctrl.sr.xml = 0;
  369. bcs->hw.hdlc.ctrl.sr.cmd |= HDLC_CMD_RRS;
  370. write_ctrl(bcs, 1);
  371. bcs->hw.hdlc.ctrl.sr.cmd &= ~HDLC_CMD_RRS;
  372. write_ctrl(bcs, 1);
  373. bcs->hw.hdlc.rcvidx = 0;
  374. } else {
  375. if (!(len = (stat & HDLC_STAT_RML_MASK)>>8))
  376. len = 32;
  377. hdlc_empty_fifo(bcs, len);
  378. if ((stat & HDLC_STAT_RME) || (bcs->mode == L1_MODE_TRANS)) {
  379. if (((stat & HDLC_STAT_CRCVFRRAB)==HDLC_STAT_CRCVFR) ||
  380. (bcs->mode == L1_MODE_TRANS)) {
  381. if (!(skb = dev_alloc_skb(bcs->hw.hdlc.rcvidx)))
  382. printk(KERN_WARNING "HDLC: receive out of memoryn");
  383. else {
  384. memcpy(skb_put(skb, bcs->hw.hdlc.rcvidx),
  385. bcs->hw.hdlc.rcvbuf, bcs->hw.hdlc.rcvidx);
  386. skb_queue_tail(&bcs->rqueue, skb);
  387. }
  388. bcs->hw.hdlc.rcvidx = 0;
  389. hdlc_sched_event(bcs, B_RCVBUFREADY);
  390. } else {
  391. if (bcs->cs->debug & L1_DEB_HSCX)
  392. debugl1(bcs->cs, "invalid frame");
  393. else
  394. debugl1(bcs->cs, "ch%d invalid frame %#x", bcs->channel, stat);
  395. bcs->hw.hdlc.rcvidx = 0;
  396. }
  397. }
  398. }
  399. }
  400. if (stat & HDLC_INT_XDU) {
  401. /* Here we lost an TX interrupt, so
  402.  * restart transmitting the whole frame.
  403.  */
  404. if (bcs->tx_skb) {
  405. skb_push(bcs->tx_skb, bcs->hw.hdlc.count);
  406. bcs->tx_cnt += bcs->hw.hdlc.count;
  407. bcs->hw.hdlc.count = 0;
  408. // hdlc_sched_event(bcs, B_XMTBUFREADY);
  409. if (bcs->cs->debug & L1_DEB_WARN)
  410. debugl1(bcs->cs, "ch%d XDU", bcs->channel);
  411. } else if (bcs->cs->debug & L1_DEB_WARN)
  412. debugl1(bcs->cs, "ch%d XDU without skb", bcs->channel);
  413. bcs->hw.hdlc.ctrl.sr.xml = 0;
  414. bcs->hw.hdlc.ctrl.sr.cmd |= HDLC_CMD_XRS;
  415. write_ctrl(bcs, 1);
  416. bcs->hw.hdlc.ctrl.sr.cmd &= ~HDLC_CMD_XRS;
  417. write_ctrl(bcs, 1);
  418. hdlc_fill_fifo(bcs);
  419. } else if (stat & HDLC_INT_XPR) {
  420. if (bcs->tx_skb) {
  421. if (bcs->tx_skb->len) {
  422. hdlc_fill_fifo(bcs);
  423. return;
  424. } else {
  425. if (bcs->st->lli.l1writewakeup &&
  426. (PACKET_NOACK != bcs->tx_skb->pkt_type))
  427. bcs->st->lli.l1writewakeup(bcs->st, bcs->hw.hdlc.count);
  428. dev_kfree_skb_irq(bcs->tx_skb);
  429. bcs->hw.hdlc.count = 0;
  430. bcs->tx_skb = NULL;
  431. }
  432. }
  433. if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) {
  434. bcs->hw.hdlc.count = 0;
  435. test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
  436. hdlc_fill_fifo(bcs);
  437. } else {
  438. test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
  439. hdlc_sched_event(bcs, B_XMTBUFREADY);
  440. }
  441. }
  442. }
  443. inline void
  444. HDLC_irq_main(struct IsdnCardState *cs)
  445. {
  446. u_int stat;
  447. long  flags;
  448. struct BCState *bcs;
  449. save_flags(flags);
  450. cli();
  451. if (cs->subtyp == AVM_FRITZ_PCI) {
  452. stat = ReadHDLCPCI(cs, 0, HDLC_STATUS);
  453. } else {
  454. stat = ReadHDLCPnP(cs, 0, HDLC_STATUS);
  455. if (stat & HDLC_INT_RPR)
  456. stat |= (ReadHDLCPnP(cs, 0, HDLC_STATUS+1))<<8;
  457. }
  458. if (stat & HDLC_INT_MASK) {
  459. if (!(bcs = Sel_BCS(cs, 0))) {
  460. if (cs->debug)
  461. debugl1(cs, "hdlc spurious channel 0 IRQ");
  462. } else
  463. HDLC_irq(bcs, stat);
  464. }
  465. if (cs->subtyp == AVM_FRITZ_PCI) {
  466. stat = ReadHDLCPCI(cs, 1, HDLC_STATUS);
  467. } else {
  468. stat = ReadHDLCPnP(cs, 1, HDLC_STATUS);
  469. if (stat & HDLC_INT_RPR)
  470. stat |= (ReadHDLCPnP(cs, 1, HDLC_STATUS+1))<<8;
  471. }
  472. if (stat & HDLC_INT_MASK) {
  473. if (!(bcs = Sel_BCS(cs, 1))) {
  474. if (cs->debug)
  475. debugl1(cs, "hdlc spurious channel 1 IRQ");
  476. } else
  477. HDLC_irq(bcs, stat);
  478. }
  479. restore_flags(flags);
  480. }
  481. void
  482. hdlc_l2l1(struct PStack *st, int pr, void *arg)
  483. {
  484. struct sk_buff *skb = arg;
  485. long flags;
  486. switch (pr) {
  487. case (PH_DATA | REQUEST):
  488. save_flags(flags);
  489. cli();
  490. if (st->l1.bcs->tx_skb) {
  491. skb_queue_tail(&st->l1.bcs->squeue, skb);
  492. restore_flags(flags);
  493. } else {
  494. st->l1.bcs->tx_skb = skb;
  495. test_and_set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
  496. st->l1.bcs->hw.hdlc.count = 0;
  497. restore_flags(flags);
  498. st->l1.bcs->cs->BC_Send_Data(st->l1.bcs);
  499. }
  500. break;
  501. case (PH_PULL | INDICATION):
  502. if (st->l1.bcs->tx_skb) {
  503. printk(KERN_WARNING "hdlc_l2l1: this shouldn't happenn");
  504. break;
  505. }
  506. test_and_set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
  507. st->l1.bcs->tx_skb = skb;
  508. st->l1.bcs->hw.hdlc.count = 0;
  509. st->l1.bcs->cs->BC_Send_Data(st->l1.bcs);
  510. break;
  511. case (PH_PULL | REQUEST):
  512. if (!st->l1.bcs->tx_skb) {
  513. test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
  514. st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
  515. } else
  516. test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
  517. break;
  518. case (PH_ACTIVATE | REQUEST):
  519. test_and_set_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag);
  520. modehdlc(st->l1.bcs, st->l1.mode, st->l1.bc);
  521. l1_msg_b(st, pr, arg);
  522. break;
  523. case (PH_DEACTIVATE | REQUEST):
  524. l1_msg_b(st, pr, arg);
  525. break;
  526. case (PH_DEACTIVATE | CONFIRM):
  527. test_and_clear_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag);
  528. test_and_clear_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
  529. modehdlc(st->l1.bcs, 0, st->l1.bc);
  530. st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL);
  531. break;
  532. }
  533. }
  534. void
  535. close_hdlcstate(struct BCState *bcs)
  536. {
  537. modehdlc(bcs, 0, 0);
  538. if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
  539. if (bcs->hw.hdlc.rcvbuf) {
  540. kfree(bcs->hw.hdlc.rcvbuf);
  541. bcs->hw.hdlc.rcvbuf = NULL;
  542. }
  543. if (bcs->blog) {
  544. kfree(bcs->blog);
  545. bcs->blog = NULL;
  546. }
  547. skb_queue_purge(&bcs->rqueue);
  548. skb_queue_purge(&bcs->squeue);
  549. if (bcs->tx_skb) {
  550. dev_kfree_skb_any(bcs->tx_skb);
  551. bcs->tx_skb = NULL;
  552. test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
  553. }
  554. }
  555. }
  556. int
  557. open_hdlcstate(struct IsdnCardState *cs, struct BCState *bcs)
  558. {
  559. if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) {
  560. if (!(bcs->hw.hdlc.rcvbuf = kmalloc(HSCX_BUFMAX, GFP_ATOMIC))) {
  561. printk(KERN_WARNING
  562.        "HiSax: No memory for hdlc.rcvbufn");
  563. return (1);
  564. }
  565. if (!(bcs->blog = kmalloc(MAX_BLOG_SPACE, GFP_ATOMIC))) {
  566. printk(KERN_WARNING
  567. "HiSax: No memory for bcs->blogn");
  568. test_and_clear_bit(BC_FLG_INIT, &bcs->Flag);
  569. kfree(bcs->hw.hdlc.rcvbuf);
  570. bcs->hw.hdlc.rcvbuf = NULL;
  571. return (2);
  572. }
  573. skb_queue_head_init(&bcs->rqueue);
  574. skb_queue_head_init(&bcs->squeue);
  575. }
  576. bcs->tx_skb = NULL;
  577. test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
  578. bcs->event = 0;
  579. bcs->hw.hdlc.rcvidx = 0;
  580. bcs->tx_cnt = 0;
  581. return (0);
  582. }
  583. int
  584. setstack_hdlc(struct PStack *st, struct BCState *bcs)
  585. {
  586. bcs->channel = st->l1.bc;
  587. if (open_hdlcstate(st->l1.hardware, bcs))
  588. return (-1);
  589. st->l1.bcs = bcs;
  590. st->l2.l2l1 = hdlc_l2l1;
  591. setstack_manager(st);
  592. bcs->st = st;
  593. setstack_l1_B(st);
  594. return (0);
  595. }
  596. void __init
  597. clear_pending_hdlc_ints(struct IsdnCardState *cs)
  598. {
  599. u_int val;
  600. if (cs->subtyp == AVM_FRITZ_PCI) {
  601. val = ReadHDLCPCI(cs, 0, HDLC_STATUS);
  602. debugl1(cs, "HDLC 1 STA %x", val);
  603. val = ReadHDLCPCI(cs, 1, HDLC_STATUS);
  604. debugl1(cs, "HDLC 2 STA %x", val);
  605. } else {
  606. val = ReadHDLCPnP(cs, 0, HDLC_STATUS);
  607. debugl1(cs, "HDLC 1 STA %x", val);
  608. val = ReadHDLCPnP(cs, 0, HDLC_STATUS + 1);
  609. debugl1(cs, "HDLC 1 RML %x", val);
  610. val = ReadHDLCPnP(cs, 0, HDLC_STATUS + 2);
  611. debugl1(cs, "HDLC 1 MODE %x", val);
  612. val = ReadHDLCPnP(cs, 0, HDLC_STATUS + 3);
  613. debugl1(cs, "HDLC 1 VIN %x", val);
  614. val = ReadHDLCPnP(cs, 1, HDLC_STATUS);
  615. debugl1(cs, "HDLC 2 STA %x", val);
  616. val = ReadHDLCPnP(cs, 1, HDLC_STATUS + 1);
  617. debugl1(cs, "HDLC 2 RML %x", val);
  618. val = ReadHDLCPnP(cs, 1, HDLC_STATUS + 2);
  619. debugl1(cs, "HDLC 2 MODE %x", val);
  620. val = ReadHDLCPnP(cs, 1, HDLC_STATUS + 3);
  621. debugl1(cs, "HDLC 2 VIN %x", val);
  622. }
  623. }
  624. void __init
  625. inithdlc(struct IsdnCardState *cs)
  626. {
  627. cs->bcs[0].BC_SetStack = setstack_hdlc;
  628. cs->bcs[1].BC_SetStack = setstack_hdlc;
  629. cs->bcs[0].BC_Close = close_hdlcstate;
  630. cs->bcs[1].BC_Close = close_hdlcstate;
  631. modehdlc(cs->bcs, -1, 0);
  632. modehdlc(cs->bcs + 1, -1, 1);
  633. }
  634. static void
  635. avm_pcipnp_interrupt(int intno, void *dev_id, struct pt_regs *regs)
  636. {
  637. struct IsdnCardState *cs = dev_id;
  638. u_char val;
  639. u_char sval;
  640. if (!cs) {
  641. printk(KERN_WARNING "AVM PCI: Spurious interrupt!n");
  642. return;
  643. }
  644. sval = inb(cs->hw.avm.cfg_reg + 2);
  645. if ((sval & AVM_STATUS0_IRQ_MASK) == AVM_STATUS0_IRQ_MASK)
  646. /* possible a shared  IRQ reqest */
  647. return;
  648. if (!(sval & AVM_STATUS0_IRQ_ISAC)) {
  649. val = ReadISAC(cs, ISAC_ISTA);
  650. isac_interrupt(cs, val);
  651. }
  652. if (!(sval & AVM_STATUS0_IRQ_HDLC)) {
  653. HDLC_irq_main(cs);
  654. }
  655. WriteISAC(cs, ISAC_MASK, 0xFF);
  656. WriteISAC(cs, ISAC_MASK, 0x0);
  657. }
  658. static void
  659. reset_avmpcipnp(struct IsdnCardState *cs)
  660. {
  661. long flags;
  662. printk(KERN_INFO "AVM PCI/PnP: resetn");
  663. save_flags(flags);
  664. sti();
  665. outb(AVM_STATUS0_RESET | AVM_STATUS0_DIS_TIMER, cs->hw.avm.cfg_reg + 2);
  666. set_current_state(TASK_UNINTERRUPTIBLE);
  667. schedule_timeout((10*HZ)/1000); /* Timeout 10ms */
  668. outb(AVM_STATUS0_DIS_TIMER | AVM_STATUS0_RES_TIMER | AVM_STATUS0_ENA_IRQ, cs->hw.avm.cfg_reg + 2);
  669. outb(AVM_STATUS1_ENA_IOM | cs->irq, cs->hw.avm.cfg_reg + 3);
  670. set_current_state(TASK_UNINTERRUPTIBLE);
  671. schedule_timeout((10*HZ)/1000); /* Timeout 10ms */
  672. printk(KERN_INFO "AVM PCI/PnP: S1 %xn", inb(cs->hw.avm.cfg_reg + 3));
  673. }
  674. static int
  675. AVM_card_msg(struct IsdnCardState *cs, int mt, void *arg)
  676. {
  677. switch (mt) {
  678. case CARD_RESET:
  679. reset_avmpcipnp(cs);
  680. return(0);
  681. case CARD_RELEASE:
  682. outb(0, cs->hw.avm.cfg_reg + 2);
  683. release_region(cs->hw.avm.cfg_reg, 32);
  684. return(0);
  685. case CARD_INIT:
  686. clear_pending_isac_ints(cs);
  687. initisac(cs);
  688. clear_pending_hdlc_ints(cs);
  689. inithdlc(cs);
  690. outb(AVM_STATUS0_DIS_TIMER | AVM_STATUS0_RES_TIMER,
  691. cs->hw.avm.cfg_reg + 2);
  692. WriteISAC(cs, ISAC_MASK, 0);
  693. outb(AVM_STATUS0_DIS_TIMER | AVM_STATUS0_RES_TIMER |
  694. AVM_STATUS0_ENA_IRQ, cs->hw.avm.cfg_reg + 2);
  695. /* RESET Receiver and Transmitter */
  696. WriteISAC(cs, ISAC_CMDR, 0x41);
  697. return(0);
  698. case CARD_TEST:
  699. return(0);
  700. }
  701. return(0);
  702. }
  703. static struct pci_dev *dev_avm __initdata = NULL;
  704. int __init
  705. setup_avm_pcipnp(struct IsdnCard *card)
  706. {
  707. u_int val, ver;
  708. struct IsdnCardState *cs = card->cs;
  709. char tmp[64];
  710. strcpy(tmp, avm_pci_rev);
  711. printk(KERN_INFO "HiSax: AVM PCI driver Rev. %sn", HiSax_getrev(tmp));
  712. if (cs->typ != ISDN_CTYPE_FRITZPCI)
  713. return (0);
  714. if (card->para[1]) {
  715. cs->hw.avm.cfg_reg = card->para[1];
  716. cs->irq = card->para[0];
  717. cs->subtyp = AVM_FRITZ_PNP;
  718. } else {
  719. #if CONFIG_PCI
  720. if (!pci_present()) {
  721. printk(KERN_ERR "FritzPCI: no PCI bus presentn");
  722. return(0);
  723. }
  724. if ((dev_avm = pci_find_device(PCI_VENDOR_ID_AVM,
  725. PCI_DEVICE_ID_AVM_A1,  dev_avm))) {
  726. cs->irq = dev_avm->irq;
  727. if (!cs->irq) {
  728. printk(KERN_ERR "FritzPCI: No IRQ for PCI card foundn");
  729. return(0);
  730. }
  731. if (pci_enable_device(dev_avm))
  732. return(0);
  733. cs->hw.avm.cfg_reg = pci_resource_start(dev_avm, 1);
  734. if (!cs->hw.avm.cfg_reg) {
  735. printk(KERN_ERR "FritzPCI: No IO-Adr for PCI card foundn");
  736. return(0);
  737. }
  738. cs->subtyp = AVM_FRITZ_PCI;
  739. } else {
  740. printk(KERN_WARNING "FritzPCI: No PCI card foundn");
  741. return(0);
  742. }
  743. cs->irq_flags |= SA_SHIRQ;
  744. #else
  745. printk(KERN_WARNING "FritzPCI: NO_PCI_BIOSn");
  746. return (0);
  747. #endif /* CONFIG_PCI */
  748. }
  749. cs->hw.avm.isac = cs->hw.avm.cfg_reg + 0x10;
  750. if (check_region((cs->hw.avm.cfg_reg), 32)) {
  751. printk(KERN_WARNING
  752.        "HiSax: %s config port %x-%x already in usen",
  753.        CardType[card->typ],
  754.        cs->hw.avm.cfg_reg,
  755.        cs->hw.avm.cfg_reg + 31);
  756. return (0);
  757. } else {
  758. request_region(cs->hw.avm.cfg_reg, 32,
  759. (cs->subtyp == AVM_FRITZ_PCI) ? "avm PCI" : "avm PnP");
  760. }
  761. switch (cs->subtyp) {
  762.   case AVM_FRITZ_PCI:
  763. val = inl(cs->hw.avm.cfg_reg);
  764. printk(KERN_INFO "AVM PCI: stat %#xn", val);
  765. printk(KERN_INFO "AVM PCI: Class %X Rev %dn",
  766. val & 0xff, (val>>8) & 0xff);
  767. cs->BC_Read_Reg = &ReadHDLC_s;
  768. cs->BC_Write_Reg = &WriteHDLC_s;
  769. break;
  770.   case AVM_FRITZ_PNP:
  771. val = inb(cs->hw.avm.cfg_reg);
  772. ver = inb(cs->hw.avm.cfg_reg + 1);
  773. printk(KERN_INFO "AVM PnP: Class %X Rev %dn", val, ver);
  774. reset_avmpcipnp(cs);
  775. cs->BC_Read_Reg = &ReadHDLCPnP;
  776. cs->BC_Write_Reg = &WriteHDLCPnP;
  777. break;
  778.   default:
  779.    printk(KERN_WARNING "AVM unknown subtype %dn", cs->subtyp);
  780.    return(0);
  781. }
  782. printk(KERN_INFO "HiSax: %s config irq:%d base:0x%Xn",
  783. (cs->subtyp == AVM_FRITZ_PCI) ? "AVM Fritz!PCI" : "AVM Fritz!PnP",
  784. cs->irq, cs->hw.avm.cfg_reg);
  785. cs->readisac = &ReadISAC;
  786. cs->writeisac = &WriteISAC;
  787. cs->readisacfifo = &ReadISACfifo;
  788. cs->writeisacfifo = &WriteISACfifo;
  789. cs->BC_Send_Data = &fill_hdlc;
  790. cs->cardmsg = &AVM_card_msg;
  791. cs->irq_func = &avm_pcipnp_interrupt;
  792. ISACVersion(cs, (cs->subtyp == AVM_FRITZ_PCI) ? "AVM PCI:" : "AVM PnP:");
  793. return (1);
  794. }