mISDNinfineon.c 27 KB

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