mISDNinfineon.c 27 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174
  1. /*
  2. * mISDNinfineon.c
  3. * Support for cards based on following Infineon ISDN chipsets
  4. * - ISAC + HSCX
  5. * - IPAC and IPAC-X
  6. * - ISAC-SX + HSCX
  7. *
  8. * Supported cards:
  9. * - Dialogic Diva 2.0
  10. * - Dialogic Diva 2.0U
  11. * - Dialogic Diva 2.01
  12. * - Dialogic Diva 2.02
  13. * - Sedlbauer Speedwin
  14. * - HST Saphir3
  15. * - Develo (former ELSA) Microlink PCI (Quickstep 1000)
  16. * - Develo (former ELSA) Quickstep 3000
  17. * - Berkom Scitel BRIX Quadro
  18. * - Dr.Neuhaus (Sagem) Niccy
  19. *
  20. *
  21. *
  22. * Author Karsten Keil <keil@isdn4linux.de>
  23. *
  24. * Copyright 2009 by Karsten Keil <keil@isdn4linux.de>
  25. *
  26. * This program is free software; you can redistribute it and/or modify
  27. * it under the terms of the GNU General Public License version 2 as
  28. * published by the Free Software Foundation.
  29. *
  30. * This program is distributed in the hope that it will be useful,
  31. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  32. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  33. * GNU General Public License for more details.
  34. *
  35. * You should have received a copy of the GNU General Public License
  36. * along with this program; if not, write to the Free Software
  37. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  38. *
  39. */
  40. #include <linux/interrupt.h>
  41. #include <linux/module.h>
  42. #include <linux/pci.h>
  43. #include <linux/delay.h>
  44. #include <linux/mISDNhw.h>
  45. #include <linux/slab.h>
  46. #include "ipac.h"
  47. #define INFINEON_REV "1.0"
  48. static int inf_cnt;
  49. static u32 debug;
  50. static u32 irqloops = 4;
  51. enum inf_types {
  52. INF_NONE,
  53. INF_DIVA20,
  54. INF_DIVA20U,
  55. INF_DIVA201,
  56. INF_DIVA202,
  57. INF_SPEEDWIN,
  58. INF_SAPHIR3,
  59. INF_QS1000,
  60. INF_QS3000,
  61. INF_NICCY,
  62. INF_SCT_1,
  63. INF_SCT_2,
  64. INF_SCT_3,
  65. INF_SCT_4,
  66. INF_GAZEL_R685,
  67. INF_GAZEL_R753
  68. };
  69. enum addr_mode {
  70. AM_NONE = 0,
  71. AM_IO,
  72. AM_MEMIO,
  73. AM_IND_IO,
  74. };
  75. struct inf_cinfo {
  76. enum inf_types typ;
  77. const char *full;
  78. const char *name;
  79. enum addr_mode cfg_mode;
  80. enum addr_mode addr_mode;
  81. u8 cfg_bar;
  82. u8 addr_bar;
  83. void *irqfunc;
  84. };
  85. struct _ioaddr {
  86. enum addr_mode mode;
  87. union {
  88. void __iomem *p;
  89. struct _ioport io;
  90. } a;
  91. };
  92. struct _iohandle {
  93. enum addr_mode mode;
  94. resource_size_t size;
  95. resource_size_t start;
  96. void __iomem *p;
  97. };
  98. struct inf_hw {
  99. struct list_head list;
  100. struct pci_dev *pdev;
  101. const struct inf_cinfo *ci;
  102. char name[MISDN_MAX_IDLEN];
  103. u32 irq;
  104. u32 irqcnt;
  105. struct _iohandle cfg;
  106. struct _iohandle addr;
  107. struct _ioaddr isac;
  108. struct _ioaddr hscx;
  109. spinlock_t lock; /* HW access lock */
  110. struct ipac_hw ipac;
  111. struct inf_hw *sc[3]; /* slave cards */
  112. };
  113. #define PCI_SUBVENDOR_HST_SAPHIR3 0x52
  114. #define PCI_SUBVENDOR_SEDLBAUER_PCI 0x53
  115. #define PCI_SUB_ID_SEDLBAUER 0x01
  116. static struct pci_device_id infineon_ids[] = {
  117. { PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_DIVA20), INF_DIVA20 },
  118. { PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_DIVA20_U), INF_DIVA20U },
  119. { PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_DIVA201), INF_DIVA201 },
  120. { PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_DIVA202), INF_DIVA202 },
  121. { PCI_VENDOR_ID_TIGERJET, PCI_DEVICE_ID_TIGERJET_100,
  122. PCI_SUBVENDOR_SEDLBAUER_PCI, PCI_SUB_ID_SEDLBAUER, 0, 0,
  123. INF_SPEEDWIN },
  124. { PCI_VENDOR_ID_TIGERJET, PCI_DEVICE_ID_TIGERJET_100,
  125. PCI_SUBVENDOR_HST_SAPHIR3, PCI_SUB_ID_SEDLBAUER, 0, 0, INF_SAPHIR3 },
  126. { PCI_VDEVICE(ELSA, PCI_DEVICE_ID_ELSA_MICROLINK), INF_QS1000 },
  127. { PCI_VDEVICE(ELSA, PCI_DEVICE_ID_ELSA_QS3000), INF_QS3000 },
  128. { PCI_VDEVICE(SATSAGEM, PCI_DEVICE_ID_SATSAGEM_NICCY), INF_NICCY },
  129. { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
  130. PCI_VENDOR_ID_BERKOM, PCI_DEVICE_ID_BERKOM_SCITEL_QUADRO, 0, 0,
  131. INF_SCT_1 },
  132. { PCI_VDEVICE(PLX, PCI_DEVICE_ID_PLX_R685), INF_GAZEL_R685 },
  133. { PCI_VDEVICE(PLX, PCI_DEVICE_ID_PLX_R753), INF_GAZEL_R753 },
  134. { PCI_VDEVICE(PLX, PCI_DEVICE_ID_PLX_DJINN_ITOO), INF_GAZEL_R753 },
  135. { PCI_VDEVICE(PLX, PCI_DEVICE_ID_PLX_OLITEC), INF_GAZEL_R753 },
  136. { }
  137. };
  138. MODULE_DEVICE_TABLE(pci, infineon_ids);
  139. /* PCI interface specific defines */
  140. /* Diva 2.0/2.0U */
  141. #define DIVA_HSCX_PORT 0x00
  142. #define DIVA_HSCX_ALE 0x04
  143. #define DIVA_ISAC_PORT 0x08
  144. #define DIVA_ISAC_ALE 0x0C
  145. #define DIVA_PCI_CTRL 0x10
  146. /* DIVA_PCI_CTRL bits */
  147. #define DIVA_IRQ_BIT 0x01
  148. #define DIVA_RESET_BIT 0x08
  149. #define DIVA_EEPROM_CLK 0x40
  150. #define DIVA_LED_A 0x10
  151. #define DIVA_LED_B 0x20
  152. #define DIVA_IRQ_CLR 0x80
  153. /* Diva 2.01/2.02 */
  154. /* Siemens PITA */
  155. #define PITA_ICR_REG 0x00
  156. #define PITA_INT0_STATUS 0x02
  157. #define PITA_MISC_REG 0x1c
  158. #define PITA_PARA_SOFTRESET 0x01000000
  159. #define PITA_SER_SOFTRESET 0x02000000
  160. #define PITA_PARA_MPX_MODE 0x04000000
  161. #define PITA_INT0_ENABLE 0x00020000
  162. /* TIGER 100 Registers */
  163. #define TIGER_RESET_ADDR 0x00
  164. #define TIGER_EXTERN_RESET 0x01
  165. #define TIGER_AUX_CTRL 0x02
  166. #define TIGER_AUX_DATA 0x03
  167. #define TIGER_AUX_IRQMASK 0x05
  168. #define TIGER_AUX_STATUS 0x07
  169. /* Tiger AUX BITs */
  170. #define TIGER_IOMASK 0xdd /* 1 and 5 are inputs */
  171. #define TIGER_IRQ_BIT 0x02
  172. #define TIGER_IPAC_ALE 0xC0
  173. #define TIGER_IPAC_PORT 0xC8
  174. /* ELSA (now Develo) PCI cards */
  175. #define ELSA_IRQ_ADDR 0x4c
  176. #define ELSA_IRQ_MASK 0x04
  177. #define QS1000_IRQ_OFF 0x01
  178. #define QS3000_IRQ_OFF 0x03
  179. #define QS1000_IRQ_ON 0x41
  180. #define QS3000_IRQ_ON 0x43
  181. /* Dr Neuhaus/Sagem Niccy */
  182. #define NICCY_ISAC_PORT 0x00
  183. #define NICCY_HSCX_PORT 0x01
  184. #define NICCY_ISAC_ALE 0x02
  185. #define NICCY_HSCX_ALE 0x03
  186. #define NICCY_IRQ_CTRL_REG 0x38
  187. #define NICCY_IRQ_ENABLE 0x001f00
  188. #define NICCY_IRQ_DISABLE 0xff0000
  189. #define NICCY_IRQ_BIT 0x800000
  190. /* Scitel PLX */
  191. #define SCT_PLX_IRQ_ADDR 0x4c
  192. #define SCT_PLX_RESET_ADDR 0x50
  193. #define SCT_PLX_IRQ_ENABLE 0x41
  194. #define SCT_PLX_RESET_BIT 0x04
  195. /* Gazel */
  196. #define GAZEL_IPAC_DATA_PORT 0x04
  197. /* Gazel PLX */
  198. #define GAZEL_CNTRL 0x50
  199. #define GAZEL_RESET 0x04
  200. #define GAZEL_RESET_9050 0x40000000
  201. #define GAZEL_INCSR 0x4C
  202. #define GAZEL_ISAC_EN 0x08
  203. #define GAZEL_INT_ISAC 0x20
  204. #define GAZEL_HSCX_EN 0x01
  205. #define GAZEL_INT_HSCX 0x04
  206. #define GAZEL_PCI_EN 0x40
  207. #define GAZEL_IPAC_EN 0x03
  208. static LIST_HEAD(Cards);
  209. static DEFINE_RWLOCK(card_lock); /* protect Cards */
  210. static void
  211. _set_debug(struct inf_hw *card)
  212. {
  213. card->ipac.isac.dch.debug = debug;
  214. card->ipac.hscx[0].bch.debug = debug;
  215. card->ipac.hscx[1].bch.debug = debug;
  216. }
  217. static int
  218. set_debug(const char *val, struct kernel_param *kp)
  219. {
  220. int ret;
  221. struct inf_hw *card;
  222. ret = param_set_uint(val, kp);
  223. if (!ret) {
  224. read_lock(&card_lock);
  225. list_for_each_entry(card, &Cards, list)
  226. _set_debug(card);
  227. read_unlock(&card_lock);
  228. }
  229. return ret;
  230. }
  231. MODULE_AUTHOR("Karsten Keil");
  232. MODULE_LICENSE("GPL v2");
  233. MODULE_VERSION(INFINEON_REV);
  234. module_param_call(debug, set_debug, param_get_uint, &debug, S_IRUGO | S_IWUSR);
  235. MODULE_PARM_DESC(debug, "infineon debug mask");
  236. module_param(irqloops, uint, S_IRUGO | S_IWUSR);
  237. MODULE_PARM_DESC(irqloops, "infineon maximal irqloops (default 4)");
  238. /* Interface functions */
  239. IOFUNC_IO(ISAC, inf_hw, isac.a.io)
  240. IOFUNC_IO(IPAC, inf_hw, hscx.a.io)
  241. IOFUNC_IND(ISAC, inf_hw, isac.a.io)
  242. IOFUNC_IND(IPAC, inf_hw, hscx.a.io)
  243. IOFUNC_MEMIO(ISAC, inf_hw, u32, isac.a.p)
  244. IOFUNC_MEMIO(IPAC, inf_hw, u32, hscx.a.p)
  245. static irqreturn_t
  246. diva_irq(int intno, void *dev_id)
  247. {
  248. struct inf_hw *hw = dev_id;
  249. u8 val;
  250. spin_lock(&hw->lock);
  251. val = inb((u32)hw->cfg.start + DIVA_PCI_CTRL);
  252. if (!(val & DIVA_IRQ_BIT)) { /* for us or shared ? */
  253. spin_unlock(&hw->lock);
  254. return IRQ_NONE; /* shared */
  255. }
  256. hw->irqcnt++;
  257. mISDNipac_irq(&hw->ipac, irqloops);
  258. spin_unlock(&hw->lock);
  259. return IRQ_HANDLED;
  260. }
  261. static irqreturn_t
  262. diva20x_irq(int intno, void *dev_id)
  263. {
  264. struct inf_hw *hw = dev_id;
  265. u8 val;
  266. spin_lock(&hw->lock);
  267. val = readb(hw->cfg.p);
  268. if (!(val & PITA_INT0_STATUS)) { /* for us or shared ? */
  269. spin_unlock(&hw->lock);
  270. return IRQ_NONE; /* shared */
  271. }
  272. hw->irqcnt++;
  273. mISDNipac_irq(&hw->ipac, irqloops);
  274. writeb(PITA_INT0_STATUS, hw->cfg.p); /* ACK PITA INT0 */
  275. spin_unlock(&hw->lock);
  276. return IRQ_HANDLED;
  277. }
  278. static irqreturn_t
  279. tiger_irq(int intno, void *dev_id)
  280. {
  281. struct inf_hw *hw = dev_id;
  282. u8 val;
  283. spin_lock(&hw->lock);
  284. val = inb((u32)hw->cfg.start + TIGER_AUX_STATUS);
  285. if (val & TIGER_IRQ_BIT) { /* for us or shared ? */
  286. spin_unlock(&hw->lock);
  287. return IRQ_NONE; /* shared */
  288. }
  289. hw->irqcnt++;
  290. mISDNipac_irq(&hw->ipac, irqloops);
  291. spin_unlock(&hw->lock);
  292. return IRQ_HANDLED;
  293. }
  294. static irqreturn_t
  295. elsa_irq(int intno, void *dev_id)
  296. {
  297. struct inf_hw *hw = dev_id;
  298. u8 val;
  299. spin_lock(&hw->lock);
  300. val = inb((u32)hw->cfg.start + ELSA_IRQ_ADDR);
  301. if (!(val & ELSA_IRQ_MASK)) {
  302. spin_unlock(&hw->lock);
  303. return IRQ_NONE; /* shared */
  304. }
  305. hw->irqcnt++;
  306. mISDNipac_irq(&hw->ipac, irqloops);
  307. spin_unlock(&hw->lock);
  308. return IRQ_HANDLED;
  309. }
  310. static irqreturn_t
  311. niccy_irq(int intno, void *dev_id)
  312. {
  313. struct inf_hw *hw = dev_id;
  314. u32 val;
  315. spin_lock(&hw->lock);
  316. val = inl((u32)hw->cfg.start + NICCY_IRQ_CTRL_REG);
  317. if (!(val & NICCY_IRQ_BIT)) { /* for us or shared ? */
  318. spin_unlock(&hw->lock);
  319. return IRQ_NONE; /* shared */
  320. }
  321. outl(val, (u32)hw->cfg.start + NICCY_IRQ_CTRL_REG);
  322. hw->irqcnt++;
  323. mISDNipac_irq(&hw->ipac, irqloops);
  324. spin_unlock(&hw->lock);
  325. return IRQ_HANDLED;
  326. }
  327. static irqreturn_t
  328. gazel_irq(int intno, void *dev_id)
  329. {
  330. struct inf_hw *hw = dev_id;
  331. irqreturn_t ret;
  332. spin_lock(&hw->lock);
  333. ret = mISDNipac_irq(&hw->ipac, irqloops);
  334. spin_unlock(&hw->lock);
  335. return ret;
  336. }
  337. static irqreturn_t
  338. ipac_irq(int intno, void *dev_id)
  339. {
  340. struct inf_hw *hw = dev_id;
  341. u8 val;
  342. spin_lock(&hw->lock);
  343. val = hw->ipac.read_reg(hw, IPAC_ISTA);
  344. if (!(val & 0x3f)) {
  345. spin_unlock(&hw->lock);
  346. return IRQ_NONE; /* shared */
  347. }
  348. hw->irqcnt++;
  349. mISDNipac_irq(&hw->ipac, irqloops);
  350. spin_unlock(&hw->lock);
  351. return IRQ_HANDLED;
  352. }
  353. static void
  354. enable_hwirq(struct inf_hw *hw)
  355. {
  356. u16 w;
  357. u32 val;
  358. switch (hw->ci->typ) {
  359. case INF_DIVA201:
  360. case INF_DIVA202:
  361. writel(PITA_INT0_ENABLE, hw->cfg.p);
  362. break;
  363. case INF_SPEEDWIN:
  364. case INF_SAPHIR3:
  365. outb(TIGER_IRQ_BIT, (u32)hw->cfg.start + TIGER_AUX_IRQMASK);
  366. break;
  367. case INF_QS1000:
  368. outb(QS1000_IRQ_ON, (u32)hw->cfg.start + ELSA_IRQ_ADDR);
  369. break;
  370. case INF_QS3000:
  371. outb(QS3000_IRQ_ON, (u32)hw->cfg.start + ELSA_IRQ_ADDR);
  372. break;
  373. case INF_NICCY:
  374. val = inl((u32)hw->cfg.start + NICCY_IRQ_CTRL_REG);
  375. val |= NICCY_IRQ_ENABLE;
  376. outl(val, (u32)hw->cfg.start + NICCY_IRQ_CTRL_REG);
  377. break;
  378. case INF_SCT_1:
  379. w = inw((u32)hw->cfg.start + SCT_PLX_IRQ_ADDR);
  380. w |= SCT_PLX_IRQ_ENABLE;
  381. outw(w, (u32)hw->cfg.start + SCT_PLX_IRQ_ADDR);
  382. break;
  383. case INF_GAZEL_R685:
  384. outb(GAZEL_ISAC_EN + GAZEL_HSCX_EN + GAZEL_PCI_EN,
  385. (u32)hw->cfg.start + GAZEL_INCSR);
  386. break;
  387. case INF_GAZEL_R753:
  388. outb(GAZEL_IPAC_EN + GAZEL_PCI_EN,
  389. (u32)hw->cfg.start + GAZEL_INCSR);
  390. break;
  391. default:
  392. break;
  393. }
  394. }
  395. static void
  396. disable_hwirq(struct inf_hw *hw)
  397. {
  398. u16 w;
  399. u32 val;
  400. switch (hw->ci->typ) {
  401. case INF_DIVA201:
  402. case INF_DIVA202:
  403. writel(0, hw->cfg.p);
  404. break;
  405. case INF_SPEEDWIN:
  406. case INF_SAPHIR3:
  407. outb(0, (u32)hw->cfg.start + TIGER_AUX_IRQMASK);
  408. break;
  409. case INF_QS1000:
  410. outb(QS1000_IRQ_OFF, (u32)hw->cfg.start + ELSA_IRQ_ADDR);
  411. break;
  412. case INF_QS3000:
  413. outb(QS3000_IRQ_OFF, (u32)hw->cfg.start + ELSA_IRQ_ADDR);
  414. break;
  415. case INF_NICCY:
  416. val = inl((u32)hw->cfg.start + NICCY_IRQ_CTRL_REG);
  417. val &= NICCY_IRQ_DISABLE;
  418. outl(val, (u32)hw->cfg.start + NICCY_IRQ_CTRL_REG);
  419. break;
  420. case INF_SCT_1:
  421. w = inw((u32)hw->cfg.start + SCT_PLX_IRQ_ADDR);
  422. w &= (~SCT_PLX_IRQ_ENABLE);
  423. outw(w, (u32)hw->cfg.start + SCT_PLX_IRQ_ADDR);
  424. break;
  425. case INF_GAZEL_R685:
  426. case INF_GAZEL_R753:
  427. outb(0, (u32)hw->cfg.start + GAZEL_INCSR);
  428. break;
  429. default:
  430. break;
  431. }
  432. }
  433. static void
  434. ipac_chip_reset(struct inf_hw *hw)
  435. {
  436. hw->ipac.write_reg(hw, IPAC_POTA2, 0x20);
  437. mdelay(5);
  438. hw->ipac.write_reg(hw, IPAC_POTA2, 0x00);
  439. mdelay(5);
  440. hw->ipac.write_reg(hw, IPAC_CONF, hw->ipac.conf);
  441. hw->ipac.write_reg(hw, IPAC_MASK, 0xc0);
  442. }
  443. static void
  444. reset_inf(struct inf_hw *hw)
  445. {
  446. u16 w;
  447. u32 val;
  448. if (debug & DEBUG_HW)
  449. pr_notice("%s: resetting card\n", hw->name);
  450. switch (hw->ci->typ) {
  451. case INF_DIVA20:
  452. case INF_DIVA20U:
  453. outb(0, (u32)hw->cfg.start + DIVA_PCI_CTRL);
  454. mdelay(10);
  455. outb(DIVA_RESET_BIT, (u32)hw->cfg.start + DIVA_PCI_CTRL);
  456. mdelay(10);
  457. /* Workaround PCI9060 */
  458. outb(9, (u32)hw->cfg.start + 0x69);
  459. outb(DIVA_RESET_BIT | DIVA_LED_A,
  460. (u32)hw->cfg.start + DIVA_PCI_CTRL);
  461. break;
  462. case INF_DIVA201:
  463. writel(PITA_PARA_SOFTRESET | PITA_PARA_MPX_MODE,
  464. hw->cfg.p + PITA_MISC_REG);
  465. mdelay(1);
  466. writel(PITA_PARA_MPX_MODE, hw->cfg.p + PITA_MISC_REG);
  467. mdelay(10);
  468. break;
  469. case INF_DIVA202:
  470. writel(PITA_PARA_SOFTRESET | PITA_PARA_MPX_MODE,
  471. hw->cfg.p + PITA_MISC_REG);
  472. mdelay(1);
  473. writel(PITA_PARA_MPX_MODE | PITA_SER_SOFTRESET,
  474. hw->cfg.p + PITA_MISC_REG);
  475. mdelay(10);
  476. break;
  477. case INF_SPEEDWIN:
  478. case INF_SAPHIR3:
  479. ipac_chip_reset(hw);
  480. hw->ipac.write_reg(hw, IPAC_ACFG, 0xff);
  481. hw->ipac.write_reg(hw, IPAC_AOE, 0x00);
  482. hw->ipac.write_reg(hw, IPAC_PCFG, 0x12);
  483. break;
  484. case INF_QS1000:
  485. case INF_QS3000:
  486. ipac_chip_reset(hw);
  487. hw->ipac.write_reg(hw, IPAC_ACFG, 0x00);
  488. hw->ipac.write_reg(hw, IPAC_AOE, 0x3c);
  489. hw->ipac.write_reg(hw, IPAC_ATX, 0xff);
  490. break;
  491. case INF_NICCY:
  492. break;
  493. case INF_SCT_1:
  494. w = inw((u32)hw->cfg.start + SCT_PLX_RESET_ADDR);
  495. w &= (~SCT_PLX_RESET_BIT);
  496. outw(w, (u32)hw->cfg.start + SCT_PLX_RESET_ADDR);
  497. mdelay(10);
  498. w = inw((u32)hw->cfg.start + SCT_PLX_RESET_ADDR);
  499. w |= SCT_PLX_RESET_BIT;
  500. outw(w, (u32)hw->cfg.start + SCT_PLX_RESET_ADDR);
  501. mdelay(10);
  502. break;
  503. case INF_GAZEL_R685:
  504. val = inl((u32)hw->cfg.start + GAZEL_CNTRL);
  505. val |= (GAZEL_RESET_9050 + GAZEL_RESET);
  506. outl(val, (u32)hw->cfg.start + GAZEL_CNTRL);
  507. val &= ~(GAZEL_RESET_9050 + GAZEL_RESET);
  508. mdelay(4);
  509. outl(val, (u32)hw->cfg.start + GAZEL_CNTRL);
  510. mdelay(10);
  511. hw->ipac.isac.adf2 = 0x87;
  512. hw->ipac.hscx[0].slot = 0x1f;
  513. hw->ipac.hscx[1].slot = 0x23;
  514. break;
  515. case INF_GAZEL_R753:
  516. val = inl((u32)hw->cfg.start + GAZEL_CNTRL);
  517. val |= (GAZEL_RESET_9050 + GAZEL_RESET);
  518. outl(val, (u32)hw->cfg.start + GAZEL_CNTRL);
  519. val &= ~(GAZEL_RESET_9050 + GAZEL_RESET);
  520. mdelay(4);
  521. outl(val, (u32)hw->cfg.start + GAZEL_CNTRL);
  522. mdelay(10);
  523. ipac_chip_reset(hw);
  524. hw->ipac.write_reg(hw, IPAC_ACFG, 0xff);
  525. hw->ipac.write_reg(hw, IPAC_AOE, 0x00);
  526. hw->ipac.conf = 0x01; /* IOM off */
  527. break;
  528. default:
  529. return;
  530. }
  531. enable_hwirq(hw);
  532. }
  533. static int
  534. inf_ctrl(struct inf_hw *hw, u32 cmd, u_long arg)
  535. {
  536. int ret = 0;
  537. switch (cmd) {
  538. case HW_RESET_REQ:
  539. reset_inf(hw);
  540. break;
  541. default:
  542. pr_info("%s: %s unknown command %x %lx\n",
  543. hw->name, __func__, cmd, arg);
  544. ret = -EINVAL;
  545. break;
  546. }
  547. return ret;
  548. }
  549. static int
  550. init_irq(struct inf_hw *hw)
  551. {
  552. int ret, cnt = 3;
  553. u_long flags;
  554. if (!hw->ci->irqfunc)
  555. return -EINVAL;
  556. ret = request_irq(hw->irq, hw->ci->irqfunc, IRQF_SHARED, hw->name, hw);
  557. if (ret) {
  558. pr_info("%s: couldn't get interrupt %d\n", hw->name, hw->irq);
  559. return ret;
  560. }
  561. while (cnt--) {
  562. spin_lock_irqsave(&hw->lock, flags);
  563. reset_inf(hw);
  564. ret = hw->ipac.init(&hw->ipac);
  565. if (ret) {
  566. spin_unlock_irqrestore(&hw->lock, flags);
  567. pr_info("%s: ISAC init failed with %d\n",
  568. hw->name, ret);
  569. break;
  570. }
  571. spin_unlock_irqrestore(&hw->lock, flags);
  572. msleep_interruptible(10);
  573. if (debug & DEBUG_HW)
  574. pr_notice("%s: IRQ %d count %d\n", hw->name,
  575. hw->irq, hw->irqcnt);
  576. if (!hw->irqcnt) {
  577. pr_info("%s: IRQ(%d) got no requests during init %d\n",
  578. hw->name, hw->irq, 3 - cnt);
  579. } else
  580. return 0;
  581. }
  582. free_irq(hw->irq, hw);
  583. return -EIO;
  584. }
  585. static void
  586. release_io(struct inf_hw *hw)
  587. {
  588. if (hw->cfg.mode) {
  589. if (hw->cfg.p) {
  590. release_mem_region(hw->cfg.start, hw->cfg.size);
  591. iounmap(hw->cfg.p);
  592. } else
  593. release_region(hw->cfg.start, hw->cfg.size);
  594. hw->cfg.mode = AM_NONE;
  595. }
  596. if (hw->addr.mode) {
  597. if (hw->addr.p) {
  598. release_mem_region(hw->addr.start, hw->addr.size);
  599. iounmap(hw->addr.p);
  600. } else
  601. release_region(hw->addr.start, hw->addr.size);
  602. hw->addr.mode = AM_NONE;
  603. }
  604. }
  605. static int
  606. setup_io(struct inf_hw *hw)
  607. {
  608. int err = 0;
  609. if (hw->ci->cfg_mode) {
  610. hw->cfg.start = pci_resource_start(hw->pdev, hw->ci->cfg_bar);
  611. hw->cfg.size = pci_resource_len(hw->pdev, hw->ci->cfg_bar);
  612. if (hw->ci->cfg_mode == AM_MEMIO) {
  613. if (!request_mem_region(hw->cfg.start, hw->cfg.size,
  614. hw->name))
  615. err = -EBUSY;
  616. } else {
  617. if (!request_region(hw->cfg.start, hw->cfg.size,
  618. hw->name))
  619. err = -EBUSY;
  620. }
  621. if (err) {
  622. pr_info("mISDN: %s config port %lx (%lu bytes)"
  623. "already in use\n", hw->name,
  624. (ulong)hw->cfg.start, (ulong)hw->cfg.size);
  625. return err;
  626. }
  627. if (hw->ci->cfg_mode == AM_MEMIO)
  628. hw->cfg.p = ioremap(hw->cfg.start, hw->cfg.size);
  629. hw->cfg.mode = hw->ci->cfg_mode;
  630. if (debug & DEBUG_HW)
  631. pr_notice("%s: IO cfg %lx (%lu bytes) mode%d\n",
  632. hw->name, (ulong)hw->cfg.start,
  633. (ulong)hw->cfg.size, hw->ci->cfg_mode);
  634. }
  635. if (hw->ci->addr_mode) {
  636. hw->addr.start = pci_resource_start(hw->pdev, hw->ci->addr_bar);
  637. hw->addr.size = pci_resource_len(hw->pdev, hw->ci->addr_bar);
  638. if (hw->ci->addr_mode == AM_MEMIO) {
  639. if (!request_mem_region(hw->addr.start, hw->addr.size,
  640. hw->name))
  641. err = -EBUSY;
  642. } else {
  643. if (!request_region(hw->addr.start, hw->addr.size,
  644. hw->name))
  645. err = -EBUSY;
  646. }
  647. if (err) {
  648. pr_info("mISDN: %s address port %lx (%lu bytes)"
  649. "already in use\n", hw->name,
  650. (ulong)hw->addr.start, (ulong)hw->addr.size);
  651. return err;
  652. }
  653. if (hw->ci->addr_mode == AM_MEMIO)
  654. hw->addr.p = ioremap(hw->addr.start, hw->addr.size);
  655. hw->addr.mode = hw->ci->addr_mode;
  656. if (debug & DEBUG_HW)
  657. pr_notice("%s: IO addr %lx (%lu bytes) mode%d\n",
  658. hw->name, (ulong)hw->addr.start,
  659. (ulong)hw->addr.size, hw->ci->addr_mode);
  660. }
  661. switch (hw->ci->typ) {
  662. case INF_DIVA20:
  663. case INF_DIVA20U:
  664. hw->ipac.type = IPAC_TYPE_ISAC | IPAC_TYPE_HSCX;
  665. hw->isac.mode = hw->cfg.mode;
  666. hw->isac.a.io.ale = (u32)hw->cfg.start + DIVA_ISAC_ALE;
  667. hw->isac.a.io.port = (u32)hw->cfg.start + DIVA_ISAC_PORT;
  668. hw->hscx.mode = hw->cfg.mode;
  669. hw->hscx.a.io.ale = (u32)hw->cfg.start + DIVA_HSCX_ALE;
  670. hw->hscx.a.io.port = (u32)hw->cfg.start + DIVA_HSCX_PORT;
  671. break;
  672. case INF_DIVA201:
  673. hw->ipac.type = IPAC_TYPE_IPAC;
  674. hw->ipac.isac.off = 0x80;
  675. hw->isac.mode = hw->addr.mode;
  676. hw->isac.a.p = hw->addr.p;
  677. hw->hscx.mode = hw->addr.mode;
  678. hw->hscx.a.p = hw->addr.p;
  679. break;
  680. case INF_DIVA202:
  681. hw->ipac.type = IPAC_TYPE_IPACX;
  682. hw->isac.mode = hw->addr.mode;
  683. hw->isac.a.p = hw->addr.p;
  684. hw->hscx.mode = hw->addr.mode;
  685. hw->hscx.a.p = hw->addr.p;
  686. break;
  687. case INF_SPEEDWIN:
  688. case INF_SAPHIR3:
  689. hw->ipac.type = IPAC_TYPE_IPAC;
  690. hw->ipac.isac.off = 0x80;
  691. hw->isac.mode = hw->cfg.mode;
  692. hw->isac.a.io.ale = (u32)hw->cfg.start + TIGER_IPAC_ALE;
  693. hw->isac.a.io.port = (u32)hw->cfg.start + TIGER_IPAC_PORT;
  694. hw->hscx.mode = hw->cfg.mode;
  695. hw->hscx.a.io.ale = (u32)hw->cfg.start + TIGER_IPAC_ALE;
  696. hw->hscx.a.io.port = (u32)hw->cfg.start + TIGER_IPAC_PORT;
  697. outb(0xff, (ulong)hw->cfg.start);
  698. mdelay(1);
  699. outb(0x00, (ulong)hw->cfg.start);
  700. mdelay(1);
  701. outb(TIGER_IOMASK, (ulong)hw->cfg.start + TIGER_AUX_CTRL);
  702. break;
  703. case INF_QS1000:
  704. case INF_QS3000:
  705. hw->ipac.type = IPAC_TYPE_IPAC;
  706. hw->ipac.isac.off = 0x80;
  707. hw->isac.a.io.ale = (u32)hw->addr.start;
  708. hw->isac.a.io.port = (u32)hw->addr.start + 1;
  709. hw->isac.mode = hw->addr.mode;
  710. hw->hscx.a.io.ale = (u32)hw->addr.start;
  711. hw->hscx.a.io.port = (u32)hw->addr.start + 1;
  712. hw->hscx.mode = hw->addr.mode;
  713. break;
  714. case INF_NICCY:
  715. hw->ipac.type = IPAC_TYPE_ISAC | IPAC_TYPE_HSCX;
  716. hw->isac.mode = hw->addr.mode;
  717. hw->isac.a.io.ale = (u32)hw->addr.start + NICCY_ISAC_ALE;
  718. hw->isac.a.io.port = (u32)hw->addr.start + NICCY_ISAC_PORT;
  719. hw->hscx.mode = hw->addr.mode;
  720. hw->hscx.a.io.ale = (u32)hw->addr.start + NICCY_HSCX_ALE;
  721. hw->hscx.a.io.port = (u32)hw->addr.start + NICCY_HSCX_PORT;
  722. break;
  723. case INF_SCT_1:
  724. hw->ipac.type = IPAC_TYPE_IPAC;
  725. hw->ipac.isac.off = 0x80;
  726. hw->isac.a.io.ale = (u32)hw->addr.start;
  727. hw->isac.a.io.port = hw->isac.a.io.ale + 4;
  728. hw->isac.mode = hw->addr.mode;
  729. hw->hscx.a.io.ale = hw->isac.a.io.ale;
  730. hw->hscx.a.io.port = hw->isac.a.io.port;
  731. hw->hscx.mode = hw->addr.mode;
  732. break;
  733. case INF_SCT_2:
  734. hw->ipac.type = IPAC_TYPE_IPAC;
  735. hw->ipac.isac.off = 0x80;
  736. hw->isac.a.io.ale = (u32)hw->addr.start + 0x08;
  737. hw->isac.a.io.port = hw->isac.a.io.ale + 4;
  738. hw->isac.mode = hw->addr.mode;
  739. hw->hscx.a.io.ale = hw->isac.a.io.ale;
  740. hw->hscx.a.io.port = hw->isac.a.io.port;
  741. hw->hscx.mode = hw->addr.mode;
  742. break;
  743. case INF_SCT_3:
  744. hw->ipac.type = IPAC_TYPE_IPAC;
  745. hw->ipac.isac.off = 0x80;
  746. hw->isac.a.io.ale = (u32)hw->addr.start + 0x10;
  747. hw->isac.a.io.port = hw->isac.a.io.ale + 4;
  748. hw->isac.mode = hw->addr.mode;
  749. hw->hscx.a.io.ale = hw->isac.a.io.ale;
  750. hw->hscx.a.io.port = hw->isac.a.io.port;
  751. hw->hscx.mode = hw->addr.mode;
  752. break;
  753. case INF_SCT_4:
  754. hw->ipac.type = IPAC_TYPE_IPAC;
  755. hw->ipac.isac.off = 0x80;
  756. hw->isac.a.io.ale = (u32)hw->addr.start + 0x20;
  757. hw->isac.a.io.port = hw->isac.a.io.ale + 4;
  758. hw->isac.mode = hw->addr.mode;
  759. hw->hscx.a.io.ale = hw->isac.a.io.ale;
  760. hw->hscx.a.io.port = hw->isac.a.io.port;
  761. hw->hscx.mode = hw->addr.mode;
  762. break;
  763. case INF_GAZEL_R685:
  764. hw->ipac.type = IPAC_TYPE_ISAC | IPAC_TYPE_HSCX;
  765. hw->ipac.isac.off = 0x80;
  766. hw->isac.mode = hw->addr.mode;
  767. hw->isac.a.io.port = (u32)hw->addr.start;
  768. hw->hscx.mode = hw->addr.mode;
  769. hw->hscx.a.io.port = hw->isac.a.io.port;
  770. break;
  771. case INF_GAZEL_R753:
  772. hw->ipac.type = IPAC_TYPE_IPAC;
  773. hw->ipac.isac.off = 0x80;
  774. hw->isac.mode = hw->addr.mode;
  775. hw->isac.a.io.ale = (u32)hw->addr.start;
  776. hw->isac.a.io.port = (u32)hw->addr.start + GAZEL_IPAC_DATA_PORT;
  777. hw->hscx.mode = hw->addr.mode;
  778. hw->hscx.a.io.ale = hw->isac.a.io.ale;
  779. hw->hscx.a.io.port = hw->isac.a.io.port;
  780. break;
  781. default:
  782. return -EINVAL;
  783. }
  784. switch (hw->isac.mode) {
  785. case AM_MEMIO:
  786. ASSIGN_FUNC_IPAC(MIO, hw->ipac);
  787. break;
  788. case AM_IND_IO:
  789. ASSIGN_FUNC_IPAC(IND, hw->ipac);
  790. break;
  791. case AM_IO:
  792. ASSIGN_FUNC_IPAC(IO, hw->ipac);
  793. break;
  794. default:
  795. return -EINVAL;
  796. }
  797. return 0;
  798. }
  799. static void
  800. release_card(struct inf_hw *card) {
  801. ulong flags;
  802. int i;
  803. spin_lock_irqsave(&card->lock, flags);
  804. disable_hwirq(card);
  805. spin_unlock_irqrestore(&card->lock, flags);
  806. card->ipac.isac.release(&card->ipac.isac);
  807. free_irq(card->irq, card);
  808. mISDN_unregister_device(&card->ipac.isac.dch.dev);
  809. release_io(card);
  810. write_lock_irqsave(&card_lock, flags);
  811. list_del(&card->list);
  812. write_unlock_irqrestore(&card_lock, flags);
  813. switch (card->ci->typ) {
  814. case INF_SCT_2:
  815. case INF_SCT_3:
  816. case INF_SCT_4:
  817. break;
  818. case INF_SCT_1:
  819. for (i = 0; i < 3; i++) {
  820. if (card->sc[i])
  821. release_card(card->sc[i]);
  822. card->sc[i] = NULL;
  823. }
  824. default:
  825. pci_disable_device(card->pdev);
  826. pci_set_drvdata(card->pdev, NULL);
  827. break;
  828. }
  829. kfree(card);
  830. inf_cnt--;
  831. }
  832. static int
  833. setup_instance(struct inf_hw *card)
  834. {
  835. int err;
  836. ulong flags;
  837. snprintf(card->name, MISDN_MAX_IDLEN - 1, "%s.%d", card->ci->name,
  838. inf_cnt + 1);
  839. write_lock_irqsave(&card_lock, flags);
  840. list_add_tail(&card->list, &Cards);
  841. write_unlock_irqrestore(&card_lock, flags);
  842. _set_debug(card);
  843. card->ipac.isac.name = card->name;
  844. card->ipac.name = card->name;
  845. card->ipac.owner = THIS_MODULE;
  846. spin_lock_init(&card->lock);
  847. card->ipac.isac.hwlock = &card->lock;
  848. card->ipac.hwlock = &card->lock;
  849. card->ipac.ctrl = (void *)&inf_ctrl;
  850. err = setup_io(card);
  851. if (err)
  852. goto error_setup;
  853. card->ipac.isac.dch.dev.Bprotocols =
  854. mISDNipac_init(&card->ipac, card);
  855. if (card->ipac.isac.dch.dev.Bprotocols == 0)
  856. goto error_setup;
  857. err = mISDN_register_device(&card->ipac.isac.dch.dev,
  858. &card->pdev->dev, card->name);
  859. if (err)
  860. goto error;
  861. err = init_irq(card);
  862. if (!err) {
  863. inf_cnt++;
  864. pr_notice("Infineon %d cards installed\n", inf_cnt);
  865. return 0;
  866. }
  867. mISDN_unregister_device(&card->ipac.isac.dch.dev);
  868. error:
  869. card->ipac.release(&card->ipac);
  870. error_setup:
  871. release_io(card);
  872. write_lock_irqsave(&card_lock, flags);
  873. list_del(&card->list);
  874. write_unlock_irqrestore(&card_lock, flags);
  875. return err;
  876. }
  877. static const struct inf_cinfo inf_card_info[] = {
  878. {
  879. INF_DIVA20,
  880. "Dialogic Diva 2.0",
  881. "diva20",
  882. AM_IND_IO, AM_NONE, 2, 0,
  883. &diva_irq
  884. },
  885. {
  886. INF_DIVA20U,
  887. "Dialogic Diva 2.0U",
  888. "diva20U",
  889. AM_IND_IO, AM_NONE, 2, 0,
  890. &diva_irq
  891. },
  892. {
  893. INF_DIVA201,
  894. "Dialogic Diva 2.01",
  895. "diva201",
  896. AM_MEMIO, AM_MEMIO, 0, 1,
  897. &diva20x_irq
  898. },
  899. {
  900. INF_DIVA202,
  901. "Dialogic Diva 2.02",
  902. "diva202",
  903. AM_MEMIO, AM_MEMIO, 0, 1,
  904. &diva20x_irq
  905. },
  906. {
  907. INF_SPEEDWIN,
  908. "Sedlbauer SpeedWin PCI",
  909. "speedwin",
  910. AM_IND_IO, AM_NONE, 0, 0,
  911. &tiger_irq
  912. },
  913. {
  914. INF_SAPHIR3,
  915. "HST Saphir 3",
  916. "saphir",
  917. AM_IND_IO, AM_NONE, 0, 0,
  918. &tiger_irq
  919. },
  920. {
  921. INF_QS1000,
  922. "Develo Microlink PCI",
  923. "qs1000",
  924. AM_IO, AM_IND_IO, 1, 3,
  925. &elsa_irq
  926. },
  927. {
  928. INF_QS3000,
  929. "Develo QuickStep 3000",
  930. "qs3000",
  931. AM_IO, AM_IND_IO, 1, 3,
  932. &elsa_irq
  933. },
  934. {
  935. INF_NICCY,
  936. "Sagem NICCY",
  937. "niccy",
  938. AM_IO, AM_IND_IO, 0, 1,
  939. &niccy_irq
  940. },
  941. {
  942. INF_SCT_1,
  943. "SciTel Quadro",
  944. "p1_scitel",
  945. AM_IO, AM_IND_IO, 1, 5,
  946. &ipac_irq
  947. },
  948. {
  949. INF_SCT_2,
  950. "SciTel Quadro",
  951. "p2_scitel",
  952. AM_NONE, AM_IND_IO, 0, 4,
  953. &ipac_irq
  954. },
  955. {
  956. INF_SCT_3,
  957. "SciTel Quadro",
  958. "p3_scitel",
  959. AM_NONE, AM_IND_IO, 0, 3,
  960. &ipac_irq
  961. },
  962. {
  963. INF_SCT_4,
  964. "SciTel Quadro",
  965. "p4_scitel",
  966. AM_NONE, AM_IND_IO, 0, 2,
  967. &ipac_irq
  968. },
  969. {
  970. INF_GAZEL_R685,
  971. "Gazel R685",
  972. "gazel685",
  973. AM_IO, AM_IO, 1, 2,
  974. &gazel_irq
  975. },
  976. {
  977. INF_GAZEL_R753,
  978. "Gazel R753",
  979. "gazel753",
  980. AM_IO, AM_IND_IO, 1, 2,
  981. &ipac_irq
  982. },
  983. {
  984. INF_NONE,
  985. }
  986. };
  987. static const struct inf_cinfo *
  988. get_card_info(enum inf_types typ)
  989. {
  990. const struct inf_cinfo *ci = inf_card_info;
  991. while (ci->typ != INF_NONE) {
  992. if (ci->typ == typ)
  993. return ci;
  994. ci++;
  995. }
  996. return NULL;
  997. }
  998. static int
  999. inf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
  1000. {
  1001. int err = -ENOMEM;
  1002. struct inf_hw *card;
  1003. card = kzalloc(sizeof(struct inf_hw), GFP_KERNEL);
  1004. if (!card) {
  1005. pr_info("No memory for Infineon ISDN card\n");
  1006. return err;
  1007. }
  1008. card->pdev = pdev;
  1009. err = pci_enable_device(pdev);
  1010. if (err) {
  1011. kfree(card);
  1012. return err;
  1013. }
  1014. card->ci = get_card_info(ent->driver_data);
  1015. if (!card->ci) {
  1016. pr_info("mISDN: do not have information about adapter at %s\n",
  1017. pci_name(pdev));
  1018. kfree(card);
  1019. pci_disable_device(pdev);
  1020. return -EINVAL;
  1021. } else
  1022. pr_notice("mISDN: found adapter %s at %s\n",
  1023. card->ci->full, pci_name(pdev));
  1024. card->irq = pdev->irq;
  1025. pci_set_drvdata(pdev, card);
  1026. err = setup_instance(card);
  1027. if (err) {
  1028. pci_disable_device(pdev);
  1029. kfree(card);
  1030. pci_set_drvdata(pdev, NULL);
  1031. } else if (ent->driver_data == INF_SCT_1) {
  1032. int i;
  1033. struct inf_hw *sc;
  1034. for (i = 1; i < 4; i++) {
  1035. sc = kzalloc(sizeof(struct inf_hw), GFP_KERNEL);
  1036. if (!sc) {
  1037. release_card(card);
  1038. pci_disable_device(pdev);
  1039. return -ENOMEM;
  1040. }
  1041. sc->irq = card->irq;
  1042. sc->pdev = card->pdev;
  1043. sc->ci = card->ci + i;
  1044. err = setup_instance(sc);
  1045. if (err) {
  1046. pci_disable_device(pdev);
  1047. kfree(sc);
  1048. release_card(card);
  1049. break;
  1050. } else
  1051. card->sc[i - 1] = sc;
  1052. }
  1053. }
  1054. return err;
  1055. }
  1056. static void
  1057. inf_remove(struct pci_dev *pdev)
  1058. {
  1059. struct inf_hw *card = pci_get_drvdata(pdev);
  1060. if (card)
  1061. release_card(card);
  1062. else
  1063. pr_debug("%s: drvdata already removed\n", __func__);
  1064. }
  1065. static struct pci_driver infineon_driver = {
  1066. .name = "ISDN Infineon pci",
  1067. .probe = inf_probe,
  1068. .remove = inf_remove,
  1069. .id_table = infineon_ids,
  1070. };
  1071. static int __init
  1072. infineon_init(void)
  1073. {
  1074. int err;
  1075. pr_notice("Infineon ISDN Driver Rev. %s\n", INFINEON_REV);
  1076. err = pci_register_driver(&infineon_driver);
  1077. return err;
  1078. }
  1079. static void __exit
  1080. infineon_cleanup(void)
  1081. {
  1082. pci_unregister_driver(&infineon_driver);
  1083. }
  1084. module_init(infineon_init);
  1085. module_exit(infineon_cleanup);