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