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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * Driver for AVM Fritz!PCI, Fritz!PCI v2, Fritz!PnP ISDN cards
  3.  *
  4.  * Author       Kai Germaschewski
  5.  * Copyright    2001 by Kai Germaschewski  <kai.germaschewski@gmx.de>
  6.  *              2001 by Karsten Keil       <keil@isdn4linux.de>
  7.  * 
  8.  * based upon Karsten Keil's original avm_pci.c driver
  9.  *
  10.  * This software may be used and distributed according to the terms
  11.  * of the GNU General Public License, incorporated herein by reference.
  12.  *
  13.  * Thanks to Wizard Computersysteme GmbH, Bremervoerde and
  14.  *           SoHaNet Technology GmbH, Berlin
  15.  * for supporting the development of this driver
  16.  */
  17. /* TODO:
  18.  *
  19.  * o POWER PC
  20.  * o clean up debugging
  21.  * o tx_skb at PH_DEACTIVATE time
  22.  */
  23. #include <linux/version.h>
  24. #include <linux/module.h>
  25. #include <linux/init.h>
  26. #include <linux/pci.h>
  27. #include <linux/isapnp.h>
  28. #include <linux/kmod.h>
  29. #include <linux/slab.h>
  30. #include <linux/skbuff.h>
  31. #include <linux/netdevice.h>
  32. #include <asm/io.h>
  33. #include "hisax_fcpcipnp.h"
  34. // debugging cruft
  35. #define __debug_variable debug
  36. #include "hisax_debug.h"
  37. #ifdef CONFIG_HISAX_DEBUG
  38. static int debug = 0;
  39. MODULE_PARM(debug, "i");
  40. #endif
  41. MODULE_AUTHOR("Kai Germaschewski <kai.germaschewski@gmx.de>/Karsten Keil <kkeil@suse.de>");
  42. MODULE_DESCRIPTION("AVM Fritz!PCI/PnP ISDN driver");
  43. static struct pci_device_id fcpci_ids[] __devinitdata = {
  44. { PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_A1   , PCI_ANY_ID, PCI_ANY_ID,
  45.   0, 0, (unsigned long) "Fritz!Card PCI" },
  46. { PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_A1_V2, PCI_ANY_ID, PCI_ANY_ID,
  47.   0, 0, (unsigned long) "Fritz!Card PCI v2" },
  48. { }
  49. };
  50. MODULE_DEVICE_TABLE(pci, fcpci_ids);
  51. static struct isapnp_device_id fcpnp_ids[] __devinitdata = {
  52. { ISAPNP_VENDOR('A', 'V', 'M'), ISAPNP_FUNCTION(0x0900),
  53.   ISAPNP_VENDOR('A', 'V', 'M'), ISAPNP_FUNCTION(0x0900), 
  54.   (unsigned long) "Fritz!Card PnP" },
  55. { }
  56. };
  57. MODULE_DEVICE_TABLE(isapnp, fcpnp_ids);
  58. static int protocol = 2;       /* EURO-ISDN Default */
  59. MODULE_PARM(protocol, "i");
  60. MODULE_LICENSE("GPL");
  61. // ----------------------------------------------------------------------
  62. #define  AVM_INDEX              0x04
  63. #define  AVM_DATA               0x10
  64. #define  AVM_IDX_HDLC_1 0x00
  65. #define  AVM_IDX_HDLC_2 0x01
  66. #define  AVM_IDX_ISAC_FIFO 0x02
  67. #define  AVM_IDX_ISAC_REG_LOW 0x04
  68. #define  AVM_IDX_ISAC_REG_HIGH 0x06
  69. #define  AVM_STATUS0            0x02
  70. #define  AVM_STATUS0_IRQ_ISAC 0x01
  71. #define  AVM_STATUS0_IRQ_HDLC 0x02
  72. #define  AVM_STATUS0_IRQ_TIMER 0x04
  73. #define  AVM_STATUS0_IRQ_MASK 0x07
  74. #define  AVM_STATUS0_RESET 0x01
  75. #define  AVM_STATUS0_DIS_TIMER 0x02
  76. #define  AVM_STATUS0_RES_TIMER 0x04
  77. #define  AVM_STATUS0_ENA_IRQ 0x08
  78. #define  AVM_STATUS0_TESTBIT 0x10
  79. #define  AVM_STATUS1            0x03
  80. #define  AVM_STATUS1_ENA_IOM 0x80
  81. #define  HDLC_FIFO 0x0
  82. #define  HDLC_STATUS 0x4
  83. #define  HDLC_CTRL 0x4
  84. #define  HDLC_MODE_ITF_FLG 0x01
  85. #define  HDLC_MODE_TRANS 0x02
  86. #define  HDLC_MODE_CCR_7 0x04
  87. #define  HDLC_MODE_CCR_16 0x08
  88. #define  HDLC_MODE_TESTLOOP 0x80
  89. #define  HDLC_INT_XPR 0x80
  90. #define  HDLC_INT_XDU 0x40
  91. #define  HDLC_INT_RPR 0x20
  92. #define  HDLC_INT_MASK 0xE0
  93. #define  HDLC_STAT_RME 0x01
  94. #define  HDLC_STAT_RDO 0x10
  95. #define  HDLC_STAT_CRCVFRRAB 0x0E
  96. #define  HDLC_STAT_CRCVFR 0x06
  97. #define  HDLC_STAT_RML_MASK 0x3f00
  98. #define  HDLC_CMD_XRS 0x80
  99. #define  HDLC_CMD_XME 0x01
  100. #define  HDLC_CMD_RRS 0x20
  101. #define  HDLC_CMD_XML_MASK 0x3f00
  102. #define  AVM_HDLC_FIFO_1        0x10
  103. #define  AVM_HDLC_FIFO_2        0x18
  104. #define  AVM_HDLC_STATUS_1      0x14
  105. #define  AVM_HDLC_STATUS_2      0x1c
  106. #define  AVM_ISACSX_INDEX       0x04
  107. #define  AVM_ISACSX_DATA        0x08
  108. // ----------------------------------------------------------------------
  109. // Fritz!PCI
  110. static unsigned char fcpci_read_isac(struct isac *isac, unsigned char offset)
  111. {
  112. struct fritz_adapter *adapter = isac->priv;
  113. unsigned char idx = (offset > 0x2f) ? 
  114. AVM_IDX_ISAC_REG_HIGH : AVM_IDX_ISAC_REG_LOW;
  115. unsigned char val;
  116. unsigned long flags;
  117. spin_lock_irqsave(&adapter->hw_lock, flags);
  118. outb(idx, adapter->io + AVM_INDEX);
  119. val = inb(adapter->io + AVM_DATA + (offset & 0xf));
  120.   spin_unlock_irqrestore(&adapter->hw_lock, flags);
  121. DBG(0x1000, " port %#x, value %#x",
  122.     offset, val);
  123. return val;
  124. }
  125. static void fcpci_write_isac(struct isac *isac, unsigned char offset,
  126.      unsigned char value)
  127. {
  128. struct fritz_adapter *adapter = isac->priv;
  129. unsigned char idx = (offset > 0x2f) ? 
  130. AVM_IDX_ISAC_REG_HIGH : AVM_IDX_ISAC_REG_LOW;
  131. unsigned long flags;
  132. DBG(0x1000, " port %#x, value %#x",
  133.     offset, value);
  134. spin_lock_irqsave(&adapter->hw_lock, flags);
  135. outb(idx, adapter->io + AVM_INDEX);
  136. outb(value, adapter->io + AVM_DATA + (offset & 0xf));
  137.   spin_unlock_irqrestore(&adapter->hw_lock, flags);
  138. }
  139. static void fcpci_read_isac_fifo(struct isac *isac, unsigned char * data, 
  140.  int size)
  141. {
  142. struct fritz_adapter *adapter = isac->priv;
  143. unsigned long flags;
  144. spin_lock_irqsave(&adapter->hw_lock, flags);
  145. outb(AVM_IDX_ISAC_FIFO, adapter->io + AVM_INDEX);
  146. insb(adapter->io + AVM_DATA, data, size);
  147.   spin_unlock_irqrestore(&adapter->hw_lock, flags);
  148. }
  149. static void fcpci_write_isac_fifo(struct isac *isac, unsigned char * data, 
  150.   int size)
  151. {
  152. struct fritz_adapter *adapter = isac->priv;
  153. unsigned long flags;
  154. spin_lock_irqsave(&adapter->hw_lock, flags);
  155. outb(AVM_IDX_ISAC_FIFO, adapter->io + AVM_INDEX);
  156. outsb(adapter->io + AVM_DATA, data, size);
  157.   spin_unlock_irqrestore(&adapter->hw_lock, flags);
  158. }
  159. static u32 fcpci_read_hdlc_status(struct fritz_adapter *adapter, int nr)
  160. {
  161. u32 val;
  162. int idx = nr ? AVM_IDX_HDLC_2 : AVM_IDX_HDLC_1;
  163. unsigned long flags;
  164. spin_lock_irqsave(&adapter->hw_lock, flags);
  165. outl(idx, adapter->io + AVM_INDEX);
  166. val = inl(adapter->io + AVM_DATA + HDLC_STATUS);
  167. spin_unlock_irqrestore(&adapter->hw_lock, flags);
  168. return val;
  169. }
  170. static void __fcpci_write_ctrl(struct fritz_bcs *bcs, int which)
  171. {
  172. struct fritz_adapter *adapter = bcs->adapter;
  173. int idx = bcs->channel ? AVM_IDX_HDLC_2 : AVM_IDX_HDLC_1;
  174. DBG(0x40, "hdlc %c wr%x ctrl %x",
  175.     'A' + bcs->channel, which, bcs->ctrl.ctrl);
  176. outl(idx, adapter->io + AVM_INDEX);
  177. outl(bcs->ctrl.ctrl, adapter->io + AVM_DATA + HDLC_CTRL);
  178. }
  179. static void fcpci_write_ctrl(struct fritz_bcs *bcs, int which)
  180. {
  181. struct fritz_adapter *adapter = bcs->adapter;
  182. unsigned long flags;
  183. spin_lock_irqsave(&adapter->hw_lock, flags);
  184. __fcpci_write_ctrl(bcs, which);
  185. spin_unlock_irqrestore(&adapter->hw_lock, flags);
  186. }
  187. // ----------------------------------------------------------------------
  188. // Fritz!PCI v2
  189. static unsigned char fcpci2_read_isac(struct isac *isac, unsigned char offset)
  190. {
  191. struct fritz_adapter *adapter = isac->priv;
  192. unsigned char val;
  193. unsigned long flags;
  194. spin_lock_irqsave(&adapter->hw_lock, flags);
  195. outl(offset, adapter->io + AVM_ISACSX_INDEX);
  196. val = inl(adapter->io + AVM_ISACSX_DATA);
  197.   spin_unlock_irqrestore(&adapter->hw_lock, flags);
  198. DBG(0x1000, " port %#x, value %#x",
  199.     offset, val);
  200. return val;
  201. }
  202. static void fcpci2_write_isac(struct isac *isac, unsigned char offset, 
  203.       unsigned char value)
  204. {
  205. struct fritz_adapter *adapter = isac->priv;
  206. unsigned long flags;
  207. DBG(0x1000, " port %#x, value %#x",
  208.     offset, value);
  209. spin_lock_irqsave(&adapter->hw_lock, flags);
  210. outl(offset, adapter->io + AVM_ISACSX_INDEX);
  211. outl(value, adapter->io + AVM_ISACSX_DATA);
  212.   spin_unlock_irqrestore(&adapter->hw_lock, flags);
  213. }
  214. static void fcpci2_read_isac_fifo(struct isac *isac, unsigned char * data, 
  215.   int size)
  216. {
  217. struct fritz_adapter *adapter = isac->priv;
  218. int i;
  219. unsigned long flags;
  220. spin_lock_irqsave(&adapter->hw_lock, flags);
  221. outl(0, adapter->io + AVM_ISACSX_INDEX);
  222. for (i = 0; i < size; i++)
  223. data[i] = inl(adapter->io + AVM_ISACSX_DATA);
  224.   spin_unlock_irqrestore(&adapter->hw_lock, flags);
  225. }
  226. static void fcpci2_write_isac_fifo(struct isac *isac, unsigned char * data, 
  227.    int size)
  228. {
  229. struct fritz_adapter *adapter = isac->priv;
  230. int i;
  231. unsigned long flags;
  232. spin_lock_irqsave(&adapter->hw_lock, flags);
  233. outl(0, adapter->io + AVM_ISACSX_INDEX);
  234. for (i = 0; i < size; i++)
  235. outl(data[i], adapter->io + AVM_ISACSX_DATA);
  236.   spin_unlock_irqrestore(&adapter->hw_lock, flags);
  237. }
  238. static u32 fcpci2_read_hdlc_status(struct fritz_adapter *adapter, int nr)
  239. {
  240. int offset = nr ? AVM_HDLC_STATUS_2 : AVM_HDLC_STATUS_1;
  241. return inl(adapter->io + offset);
  242. }
  243. static void fcpci2_write_ctrl(struct fritz_bcs *bcs, int which)
  244. {
  245. struct fritz_adapter *adapter = bcs->adapter;
  246. int offset = bcs->channel ? AVM_HDLC_STATUS_2 : AVM_HDLC_STATUS_1;
  247. DBG(0x40, "hdlc %c wr%x ctrl %x",
  248.     'A' + bcs->channel, which, bcs->ctrl.ctrl);
  249. outl(bcs->ctrl.ctrl, adapter->io + offset);
  250. }
  251. // ----------------------------------------------------------------------
  252. // Fritz!PnP (ISAC access as for Fritz!PCI)
  253. static u32 fcpnp_read_hdlc_status(struct fritz_adapter *adapter, int nr)
  254. {
  255. unsigned char idx = nr ? AVM_IDX_HDLC_2 : AVM_IDX_HDLC_1;
  256. u32 val;
  257. unsigned long flags;
  258. spin_lock_irqsave(&adapter->hw_lock, flags);
  259. outb(idx, adapter->io + AVM_INDEX);
  260. val = inb(adapter->io + AVM_DATA + HDLC_STATUS);
  261. if (val & HDLC_INT_RPR)
  262. val |= inb(adapter->io + AVM_DATA + HDLC_STATUS + 1) << 8;
  263. spin_unlock_irqrestore(&adapter->hw_lock, flags);
  264. return val;
  265. }
  266. static void __fcpnp_write_ctrl(struct fritz_bcs *bcs, int which)
  267. {
  268. struct fritz_adapter *adapter = bcs->adapter;
  269. unsigned char idx = bcs->channel ? AVM_IDX_HDLC_2 : AVM_IDX_HDLC_1;
  270. DBG(0x40, "hdlc %c wr%x ctrl %x",
  271.     'A' + bcs->channel, which, bcs->ctrl.ctrl);
  272. outb(idx, adapter->io + AVM_INDEX);
  273. if (which & 4)
  274. outb(bcs->ctrl.sr.mode, 
  275.      adapter->io + AVM_DATA + HDLC_STATUS + 2);
  276. if (which & 2)
  277. outb(bcs->ctrl.sr.xml, 
  278.      adapter->io + AVM_DATA + HDLC_STATUS + 1);
  279. if (which & 1)
  280. outb(bcs->ctrl.sr.cmd,
  281.      adapter->io + AVM_DATA + HDLC_STATUS + 0);
  282. }
  283. static void fcpnp_write_ctrl(struct fritz_bcs *bcs, int which)
  284. {
  285. struct fritz_adapter *adapter = bcs->adapter;
  286. unsigned long flags;
  287. spin_lock_irqsave(&adapter->hw_lock, flags);
  288. __fcpnp_write_ctrl(bcs, which);
  289. spin_unlock_irqrestore(&adapter->hw_lock, flags);
  290. }
  291. // ----------------------------------------------------------------------
  292. static inline void B_L1L2(struct fritz_bcs *bcs, int pr, void *arg)
  293. {
  294. struct hisax_if *ifc = (struct hisax_if *) &bcs->b_if;
  295. DBG(2, "pr %#x", pr);
  296. ifc->l1l2(ifc, pr, arg);
  297. }
  298. static void hdlc_fill_fifo(struct fritz_bcs *bcs)
  299. {
  300. struct fritz_adapter *adapter = bcs->adapter;
  301. struct sk_buff *skb = bcs->tx_skb;
  302. int count;
  303. int fifo_size = 32;
  304. unsigned long flags;
  305. unsigned char *p;
  306. DBG(0x40, "hdlc_fill_fifo");
  307. if (skb->len == 0)
  308. BUG();
  309. bcs->ctrl.sr.cmd &= ~HDLC_CMD_XME;
  310. if (bcs->tx_skb->len > fifo_size) {
  311. count = fifo_size;
  312. } else {
  313. count = bcs->tx_skb->len;
  314. if (bcs->mode != L1_MODE_TRANS)
  315. bcs->ctrl.sr.cmd |= HDLC_CMD_XME;
  316. }
  317. DBG(0x40, "hdlc_fill_fifo %d/%d", count, bcs->tx_skb->len);
  318. p = bcs->tx_skb->data;
  319. skb_pull(bcs->tx_skb, count);
  320. bcs->tx_cnt += count;
  321. bcs->ctrl.sr.xml = ((count == fifo_size) ? 0 : count);
  322. switch (adapter->type) {
  323. case AVM_FRITZ_PCI:
  324. spin_lock_irqsave(&adapter->hw_lock, flags);
  325. // sets the correct AVM_INDEX, too
  326. __fcpci_write_ctrl(bcs, 3);
  327. outsl(adapter->io + AVM_DATA + HDLC_FIFO,
  328.       p, (count + 3) / 4);
  329. spin_unlock_irqrestore(&adapter->hw_lock, flags);
  330. break;
  331. case AVM_FRITZ_PCIV2:
  332. fcpci2_write_ctrl(bcs, 3);
  333. outsl(adapter->io + 
  334.       (bcs->channel ? AVM_HDLC_FIFO_2 : AVM_HDLC_FIFO_1),
  335.       p, (count + 3) / 4);
  336. break;
  337. case AVM_FRITZ_PNP:
  338. spin_lock_irqsave(&adapter->hw_lock, flags);
  339. // sets the correct AVM_INDEX, too
  340. __fcpnp_write_ctrl(bcs, 3);
  341. outsb(adapter->io + AVM_DATA, p, count);
  342. spin_unlock_irqrestore(&adapter->hw_lock, flags);
  343. break;
  344. }
  345. }
  346. static inline void hdlc_empty_fifo(struct fritz_bcs *bcs, int count)
  347. {
  348. struct fritz_adapter *adapter = bcs->adapter;
  349. unsigned char *p;
  350. unsigned char idx = bcs->channel ? AVM_IDX_HDLC_2 : AVM_IDX_HDLC_1;
  351. DBG(0x10, "hdlc_empty_fifo %d", count);
  352. if (bcs->rcvidx + count > HSCX_BUFMAX) {
  353. DBG(0x10, "hdlc_empty_fifo: incoming packet too large");
  354. return;
  355. }
  356. p = bcs->rcvbuf + bcs->rcvidx;
  357. bcs->rcvidx += count;
  358. switch (adapter->type) {
  359. case AVM_FRITZ_PCI:
  360. spin_lock(&adapter->hw_lock);
  361. outl(idx, adapter->io + AVM_INDEX);
  362. insl(adapter->io + AVM_DATA + HDLC_FIFO, 
  363.      p, (count + 3) / 4);
  364. spin_unlock(&adapter->hw_lock);
  365. break;
  366. case AVM_FRITZ_PCIV2:
  367. insl(adapter->io + 
  368.      (bcs->channel ? AVM_HDLC_FIFO_2 : AVM_HDLC_FIFO_1),
  369.      p, (count + 3) / 4);
  370. break;
  371. case AVM_FRITZ_PNP:
  372. spin_lock(&adapter->hw_lock);
  373. outb(idx, adapter->io + AVM_INDEX);
  374. insb(adapter->io + AVM_DATA, p, count);
  375. spin_unlock(&adapter->hw_lock);
  376. break;
  377. }
  378. }
  379. static inline void hdlc_rpr_irq(struct fritz_bcs *bcs, u32 stat)
  380. {
  381. struct fritz_adapter *adapter = bcs->adapter;
  382. struct sk_buff *skb;
  383. int len;
  384. if (stat & HDLC_STAT_RDO) {
  385. DBG(0x10, "RDO");
  386. bcs->ctrl.sr.xml = 0;
  387. bcs->ctrl.sr.cmd |= HDLC_CMD_RRS;
  388. adapter->write_ctrl(bcs, 1);
  389. bcs->ctrl.sr.cmd &= ~HDLC_CMD_RRS;
  390. adapter->write_ctrl(bcs, 1);
  391. bcs->rcvidx = 0;
  392. return;
  393. }
  394. len = (stat & HDLC_STAT_RML_MASK) >> 8;
  395. if (len == 0)
  396. len = 32;
  397. hdlc_empty_fifo(bcs, len);
  398. if ((stat & HDLC_STAT_RME) || (bcs->mode == L1_MODE_TRANS)) {
  399. if (((stat & HDLC_STAT_CRCVFRRAB)== HDLC_STAT_CRCVFR) ||
  400.     (bcs->mode == L1_MODE_TRANS)) {
  401. skb = dev_alloc_skb(bcs->rcvidx);
  402. if (!skb) {
  403. printk(KERN_WARNING "HDLC: receive out of memoryn");
  404. } else {
  405. memcpy(skb_put(skb, bcs->rcvidx), bcs->rcvbuf,
  406.        bcs->rcvidx);
  407. DBG_SKB(1, skb);
  408. B_L1L2(bcs, PH_DATA | INDICATION, skb);
  409. }
  410. bcs->rcvidx = 0;
  411. } else {
  412. DBG(0x10, "ch%d invalid frame %#x",
  413.     bcs->channel, stat);
  414. bcs->rcvidx = 0;
  415. }
  416. }
  417. }
  418. static inline void hdlc_xdu_irq(struct fritz_bcs *bcs)
  419. {
  420. struct fritz_adapter *adapter = bcs->adapter;
  421. /* Here we lost an TX interrupt, so
  422.  * restart transmitting the whole frame.
  423.  */
  424. bcs->ctrl.sr.xml = 0;
  425. bcs->ctrl.sr.cmd |= HDLC_CMD_XRS;
  426. adapter->write_ctrl(bcs, 1);
  427. bcs->ctrl.sr.cmd &= ~HDLC_CMD_XRS;
  428. adapter->write_ctrl(bcs, 1);
  429. if (!bcs->tx_skb) {
  430. DBG(0x10, "XDU without skb");
  431. return;
  432. }
  433. skb_push(bcs->tx_skb, bcs->tx_cnt);
  434. bcs->tx_cnt = 0;
  435. }
  436. static inline void hdlc_xpr_irq(struct fritz_bcs *bcs)
  437. {
  438. struct sk_buff *skb;
  439. skb = bcs->tx_skb;
  440. if (!skb)
  441. return;
  442. if (skb->len) {
  443. hdlc_fill_fifo(bcs);
  444. return;
  445. }
  446. bcs->tx_cnt = 0;
  447. bcs->tx_skb = NULL;
  448. B_L1L2(bcs, PH_DATA | CONFIRM, (void *) skb->truesize);
  449. dev_kfree_skb_irq(skb);
  450. }
  451. static void hdlc_irq_one(struct fritz_bcs *bcs, u32 stat)
  452. {
  453. DBG(0x10, "ch%d stat %#x", bcs->channel, stat);
  454. if (stat & HDLC_INT_RPR) {
  455. DBG(0x10, "RPR");
  456. hdlc_rpr_irq(bcs, stat);
  457. }
  458. if (stat & HDLC_INT_XDU) {
  459. DBG(0x10, "XDU");
  460. hdlc_xdu_irq(bcs);
  461. }
  462. if (stat & HDLC_INT_XPR) {
  463. DBG(0x10, "XPR");
  464. hdlc_xpr_irq(bcs);
  465. }
  466. }
  467. static inline void hdlc_irq(struct fritz_adapter *adapter)
  468. {
  469. int nr;
  470. u32 stat;
  471. for (nr = 0; nr < 2; nr++) {
  472. stat = adapter->read_hdlc_status(adapter, nr);
  473. DBG(0x10, "HDLC %c stat %#x", 'A' + nr, stat);
  474. if (stat & HDLC_INT_MASK)
  475. hdlc_irq_one(&adapter->bcs[nr], stat);
  476. }
  477. }
  478. static void modehdlc(struct fritz_bcs *bcs, int mode)
  479. {
  480. struct fritz_adapter *adapter = bcs->adapter;
  481. DBG(0x40, "hdlc %c mode %d --> %d",
  482.     'A' + bcs->channel, bcs->mode, mode);
  483. if (bcs->mode == mode)
  484. return;
  485. bcs->ctrl.ctrl = 0;
  486. bcs->ctrl.sr.cmd  = HDLC_CMD_XRS | HDLC_CMD_RRS;
  487. switch (mode) {
  488. case L1_MODE_NULL:
  489. bcs->ctrl.sr.mode = HDLC_MODE_TRANS;
  490. adapter->write_ctrl(bcs, 5);
  491. break;
  492. case L1_MODE_TRANS:
  493. case L1_MODE_HDLC:
  494. bcs->rcvidx = 0;
  495. bcs->tx_cnt = 0;
  496. bcs->tx_skb = NULL;
  497. if (mode == L1_MODE_TRANS)
  498. bcs->ctrl.sr.mode = HDLC_MODE_TRANS;
  499. else
  500. bcs->ctrl.sr.mode = HDLC_MODE_ITF_FLG;
  501. adapter->write_ctrl(bcs, 5);
  502. bcs->ctrl.sr.cmd = HDLC_CMD_XRS;
  503. adapter->write_ctrl(bcs, 1);
  504. bcs->ctrl.sr.cmd = 0;
  505. break;
  506. }
  507. bcs->mode = mode;
  508. }
  509. static void fritz_b_l2l1(struct hisax_if *ifc, int pr, void *arg)
  510. {
  511. struct fritz_bcs *bcs = ifc->priv;
  512. struct sk_buff *skb = arg;
  513. int mode;
  514. DBG(0x10, "pr %#x", pr);
  515. switch (pr) {
  516. case PH_DATA | REQUEST:
  517. if (bcs->tx_skb)
  518. BUG();
  519. bcs->tx_skb = skb;
  520. DBG_SKB(1, skb);
  521. hdlc_fill_fifo(bcs);
  522. break;
  523. case PH_ACTIVATE | REQUEST:
  524. mode = (int) arg;
  525. DBG(4,"B%d,PH_ACTIVATE_REQUEST %d", bcs->channel + 1, mode);
  526. modehdlc(bcs, mode);
  527. B_L1L2(bcs, PH_ACTIVATE | INDICATION, NULL);
  528. break;
  529. case PH_DEACTIVATE | REQUEST:
  530. DBG(4,"B%d,PH_DEACTIVATE_REQUEST", bcs->channel + 1);
  531. modehdlc(bcs, L1_MODE_NULL);
  532. B_L1L2(bcs, PH_DEACTIVATE | INDICATION, NULL);
  533. break;
  534. }
  535. }
  536. // ----------------------------------------------------------------------
  537. static void fcpci2_irq(int intno, void *dev, struct pt_regs *regs)
  538. {
  539. struct fritz_adapter *adapter = dev;
  540. unsigned char val;
  541. val = inb(adapter->io + AVM_STATUS0);
  542. if (!(val & AVM_STATUS0_IRQ_MASK))
  543. /* hopefully a shared  IRQ reqest */
  544. return;
  545. DBG(2, "STATUS0 %#x", val);
  546. if (val & AVM_STATUS0_IRQ_ISAC)
  547. isacsx_irq(&adapter->isac);
  548. if (val & AVM_STATUS0_IRQ_HDLC)
  549. hdlc_irq(adapter);
  550. }
  551. static void fcpci_irq(int intno, void *dev, struct pt_regs *regs)
  552. {
  553. struct fritz_adapter *adapter = dev;
  554. unsigned char sval;
  555. sval = inb(adapter->io + 2);
  556. if ((sval & AVM_STATUS0_IRQ_MASK) == AVM_STATUS0_IRQ_MASK)
  557. /* possibly a shared  IRQ reqest */
  558. return;
  559. DBG(2, "sval %#x", sval);
  560. if (!(sval & AVM_STATUS0_IRQ_ISAC))
  561. isac_irq(&adapter->isac);
  562. if (!(sval & AVM_STATUS0_IRQ_HDLC))
  563. hdlc_irq(adapter);
  564. }
  565. // ----------------------------------------------------------------------
  566. static inline void fcpci2_init(struct fritz_adapter *adapter)
  567. {
  568. outb(AVM_STATUS0_RES_TIMER, adapter->io + AVM_STATUS0);
  569. outb(AVM_STATUS0_ENA_IRQ, adapter->io + AVM_STATUS0);
  570. }
  571. static inline void fcpci_init(struct fritz_adapter *adapter)
  572. {
  573. outb(AVM_STATUS0_DIS_TIMER | AVM_STATUS0_RES_TIMER | 
  574.      AVM_STATUS0_ENA_IRQ, adapter->io + AVM_STATUS0);
  575. outb(AVM_STATUS1_ENA_IOM | adapter->irq, 
  576.      adapter->io + AVM_STATUS1);
  577. set_current_state(TASK_UNINTERRUPTIBLE);
  578. schedule_timeout(50*HZ / 1000); /* Timeout 50ms */
  579. }
  580. // ----------------------------------------------------------------------
  581. static int __devinit fcpcipnp_setup(struct fritz_adapter *adapter)
  582. {
  583. u32 val = 0;
  584. int retval;
  585. DBG(1,"");
  586. isac_init(&adapter->isac); // FIXME is this okay now
  587. retval = -EBUSY;
  588. if (!request_region(adapter->io, 32, "fcpcipnp"))
  589. goto err;
  590. switch (adapter->type) {
  591. case AVM_FRITZ_PCIV2:
  592. retval = request_irq(adapter->irq, fcpci2_irq, SA_SHIRQ, 
  593.      "fcpcipnp", adapter);
  594. break;
  595. case AVM_FRITZ_PCI:
  596. retval = request_irq(adapter->irq, fcpci_irq, SA_SHIRQ,
  597.      "fcpcipnp", adapter);
  598. break;
  599. case AVM_FRITZ_PNP:
  600. retval = request_irq(adapter->irq, fcpci_irq, 0,
  601.      "fcpcipnp", adapter);
  602. break;
  603. }
  604. if (retval)
  605. goto err_region;
  606. switch (adapter->type) {
  607. case AVM_FRITZ_PCIV2:
  608. case AVM_FRITZ_PCI:
  609. val = inl(adapter->io);
  610. break;
  611. case AVM_FRITZ_PNP:
  612. val = inb(adapter->io);
  613. val |= inb(adapter->io + 1) << 8;
  614. break;
  615. }
  616. DBG(1, "stat %#x Class %X Rev %d",
  617.     val, val & 0xff, (val>>8) & 0xff);
  618. spin_lock_init(&adapter->hw_lock);
  619. adapter->isac.priv = adapter;
  620. switch (adapter->type) {
  621. case AVM_FRITZ_PCIV2:
  622. adapter->isac.read_isac       = &fcpci2_read_isac;;
  623. adapter->isac.write_isac      = &fcpci2_write_isac;
  624. adapter->isac.read_isac_fifo  = &fcpci2_read_isac_fifo;
  625. adapter->isac.write_isac_fifo = &fcpci2_write_isac_fifo;
  626. adapter->read_hdlc_status     = &fcpci2_read_hdlc_status;
  627. adapter->write_ctrl           = &fcpci2_write_ctrl;
  628. break;
  629. case AVM_FRITZ_PCI:
  630. adapter->isac.read_isac       = &fcpci_read_isac;;
  631. adapter->isac.write_isac      = &fcpci_write_isac;
  632. adapter->isac.read_isac_fifo  = &fcpci_read_isac_fifo;
  633. adapter->isac.write_isac_fifo = &fcpci_write_isac_fifo;
  634. adapter->read_hdlc_status     = &fcpci_read_hdlc_status;
  635. adapter->write_ctrl           = &fcpci_write_ctrl;
  636. break;
  637. case AVM_FRITZ_PNP:
  638. adapter->isac.read_isac       = &fcpci_read_isac;;
  639. adapter->isac.write_isac      = &fcpci_write_isac;
  640. adapter->isac.read_isac_fifo  = &fcpci_read_isac_fifo;
  641. adapter->isac.write_isac_fifo = &fcpci_write_isac_fifo;
  642. adapter->read_hdlc_status     = &fcpnp_read_hdlc_status;
  643. adapter->write_ctrl           = &fcpnp_write_ctrl;
  644. break;
  645. }
  646. // Reset
  647. outb(0, adapter->io + AVM_STATUS0);
  648. set_current_state(TASK_UNINTERRUPTIBLE);
  649. schedule_timeout(50 * HZ / 1000); // 50 msec
  650. outb(AVM_STATUS0_RESET, adapter->io + AVM_STATUS0);
  651. set_current_state(TASK_UNINTERRUPTIBLE);
  652. schedule_timeout(50 * HZ / 1000); // 50 msec
  653. outb(0, adapter->io + AVM_STATUS0);
  654. set_current_state(TASK_UNINTERRUPTIBLE);
  655. schedule_timeout(10 * HZ / 1000); // 10 msec
  656. switch (adapter->type) {
  657. case AVM_FRITZ_PCIV2:
  658. fcpci2_init(adapter);
  659. isacsx_setup(&adapter->isac);
  660. break;
  661. case AVM_FRITZ_PCI:
  662. case AVM_FRITZ_PNP:
  663. fcpci_init(adapter);
  664. isac_setup(&adapter->isac);
  665. break;
  666. }
  667. val = adapter->read_hdlc_status(adapter, 0);
  668. DBG(0x20, "HDLC A STA %x", val);
  669. val = adapter->read_hdlc_status(adapter, 1);
  670. DBG(0x20, "HDLC B STA %x", val);
  671. adapter->bcs[0].mode = -1;
  672. adapter->bcs[1].mode = -1;
  673. modehdlc(&adapter->bcs[0], L1_MODE_NULL);
  674. modehdlc(&adapter->bcs[1], L1_MODE_NULL);
  675. return 0;
  676.  err_region:
  677. release_region(adapter->io, 32);
  678.  err:
  679. return retval;
  680. }
  681. static void __devexit fcpcipnp_release(struct fritz_adapter *adapter)
  682. {
  683. DBG(1,"");
  684. outb(0, adapter->io + AVM_STATUS0);
  685. free_irq(adapter->irq, adapter);
  686. release_region(adapter->io, 32);
  687. }
  688. // ----------------------------------------------------------------------
  689. static struct fritz_adapter * __devinit 
  690. new_adapter(struct pci_dev *pdev)
  691. {
  692. struct fritz_adapter *adapter;
  693. struct hisax_b_if *b_if[2];
  694. int i;
  695. adapter = kmalloc(sizeof(struct fritz_adapter), GFP_KERNEL);
  696. if (!adapter)
  697. return NULL;
  698. memset(adapter, 0, sizeof(struct fritz_adapter));
  699. SET_MODULE_OWNER(&adapter->isac.hisax_d_if);
  700. adapter->isac.hisax_d_if.ifc.priv = &adapter->isac;
  701. adapter->isac.hisax_d_if.ifc.l2l1 = isac_d_l2l1;
  702. for (i = 0; i < 2; i++) {
  703. adapter->bcs[i].adapter = adapter;
  704. adapter->bcs[i].channel = i;
  705. adapter->bcs[i].b_if.ifc.priv = &adapter->bcs[i];
  706. adapter->bcs[i].b_if.ifc.l2l1 = fritz_b_l2l1;
  707. }
  708. pci_set_drvdata(pdev, adapter);
  709. for (i = 0; i < 2; i++)
  710. b_if[i] = &adapter->bcs[i].b_if;
  711. hisax_register(&adapter->isac.hisax_d_if, b_if, "fcpcipnp", protocol);
  712. return adapter;
  713. }
  714. static void delete_adapter(struct fritz_adapter *adapter)
  715. {
  716. hisax_unregister(&adapter->isac.hisax_d_if);
  717. kfree(adapter);
  718. }
  719. static int __devinit fcpci_probe(struct pci_dev *pdev,
  720.  const struct pci_device_id *ent)
  721. {
  722. struct fritz_adapter *adapter;
  723. int retval;
  724. retval = -ENOMEM;
  725. adapter = new_adapter(pdev);
  726. if (!adapter)
  727. goto err;
  728. if (pdev->device == PCI_DEVICE_ID_AVM_A1_V2) 
  729. adapter->type = AVM_FRITZ_PCIV2;
  730. else
  731. adapter->type = AVM_FRITZ_PCI;
  732. retval = pci_enable_device(pdev);
  733. if (retval)
  734. goto err_free;
  735. adapter->io = pci_resource_start(pdev, 1);
  736. adapter->irq = pdev->irq;
  737. printk(KERN_INFO "hisax_fcpcipnp: found adapter %s at %sn",
  738.        (char *) ent->driver_data, pdev->slot_name);
  739. retval = fcpcipnp_setup(adapter);
  740. if (retval)
  741. goto err_free;
  742. return 0;
  743.  err_free:
  744. delete_adapter(adapter);
  745.  err:
  746. return retval;
  747. }
  748. static int __devinit fcpnp_probe(struct pci_dev *pdev,
  749.  const struct isapnp_device_id *ent)
  750. {
  751. struct fritz_adapter *adapter;
  752. int retval;
  753. retval = -ENOMEM;
  754. adapter = new_adapter(pdev);
  755. if (!adapter)
  756. goto err;
  757. adapter->type = AVM_FRITZ_PNP;
  758. pdev->prepare(pdev);
  759. pdev->deactivate(pdev); // why?
  760. pdev->activate(pdev);
  761. adapter->io = pdev->resource[0].start;
  762. adapter->irq = pdev->irq_resource[0].start;
  763. printk(KERN_INFO "hisax_fcpcipnp: found adapter %s at IO %#x irq %dn",
  764.        (char *) ent->driver_data, adapter->io, adapter->irq);
  765. retval = fcpcipnp_setup(adapter);
  766. if (retval)
  767. goto err_free;
  768. return 0;
  769.  err_free:
  770. delete_adapter(adapter);
  771.  err:
  772. return retval;
  773. }
  774. static void __devexit fcpci_remove(struct pci_dev *pdev)
  775. {
  776. struct fritz_adapter *adapter = pci_get_drvdata(pdev);
  777. fcpcipnp_release(adapter);
  778. pci_disable_device(pdev);
  779. delete_adapter(adapter);
  780. }
  781. static void __devexit fcpnp_remove(struct pci_dev *pdev)
  782. {
  783. struct fritz_adapter *adapter = pci_get_drvdata(pdev);
  784. fcpcipnp_release(adapter);
  785. pdev->deactivate(pdev);
  786. delete_adapter(adapter);
  787. }
  788. static struct pci_driver fcpci_driver = {
  789. name:     "fcpci",
  790. probe:    fcpci_probe,
  791. remove:   __devexit_p(fcpci_remove),
  792. id_table: fcpci_ids,
  793. };
  794. static struct isapnp_driver fcpnp_driver = {
  795. name:     "fcpnp",
  796. probe:    fcpnp_probe,
  797. remove:   __devexit_p(fcpnp_remove),
  798. id_table: fcpnp_ids,
  799. };
  800. static int __init hisax_fcpcipnp_init(void)
  801. {
  802. int retval, pci_nr_found;
  803. printk(KERN_INFO "hisax_fcpcipnp: Fritz!Card PCI/PCIv2/PnP ISDN driver v0.0.1n");
  804. retval = pci_register_driver(&fcpci_driver);
  805. if (retval < 0)
  806. goto out;
  807. pci_nr_found = retval;
  808. retval = isapnp_register_driver(&fcpnp_driver);
  809. if (retval < 0)
  810. goto out_unregister_pci;
  811. #if !defined(CONFIG_HOTPLUG) || defined(MODULE)
  812. if (pci_nr_found + retval == 0) {
  813. retval = -ENODEV;
  814. goto out_unregister_isapnp;
  815. }
  816. #endif
  817. return 0;
  818. #if !defined(CONFIG_HOTPLUG) || defined(MODULE)
  819.  out_unregister_isapnp:
  820. isapnp_unregister_driver(&fcpnp_driver);
  821. #endif
  822.  out_unregister_pci:
  823. pci_unregister_driver(&fcpci_driver);
  824.  out:
  825. return retval;
  826. }
  827. static void __exit hisax_fcpcipnp_exit(void)
  828. {
  829. isapnp_unregister_driver(&fcpnp_driver);
  830. pci_unregister_driver(&fcpci_driver);
  831. }
  832. module_init(hisax_fcpcipnp_init);
  833. module_exit(hisax_fcpcipnp_exit);