1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26#include "platform.h"
27#include "di_defs.h"
28#include "pc.h"
29#include "pr_pc.h"
30#include "divasync.h"
31#define MIPS_SCOM
32#include "pkmaint.h"
33#include "di.h"
34#include "mi_pc.h"
35#include "io.h"
36extern ADAPTER *adapter[MAX_ADAPTER];
37extern PISDN_ADAPTER IoAdapters[MAX_ADAPTER];
38void request(PISDN_ADAPTER, ENTITY *);
39static void pcm_req(PISDN_ADAPTER, ENTITY *);
40
41
42
43#define ReqFunc(N) \
44 static void Request##N(ENTITY *e) \
45 { if (IoAdapters[N]) (*IoAdapters[N]->DIRequest)(IoAdapters[N], e); }
46ReqFunc(0)
47ReqFunc(1)
48ReqFunc(2)
49ReqFunc(3)
50ReqFunc(4)
51ReqFunc(5)
52ReqFunc(6)
53ReqFunc(7)
54ReqFunc(8)
55ReqFunc(9)
56ReqFunc(10)
57ReqFunc(11)
58ReqFunc(12)
59ReqFunc(13)
60ReqFunc(14)
61ReqFunc(15)
62IDI_CALL Requests[MAX_ADAPTER] =
63{ &Request0, &Request1, &Request2, &Request3,
64 &Request4, &Request5, &Request6, &Request7,
65 &Request8, &Request9, &Request10, &Request11,
66 &Request12, &Request13, &Request14, &Request15
67};
68
69
70
71
72
73static byte extended_xdi_features[DIVA_XDI_EXTENDED_FEATURES_MAX_SZ + 1] = {
74 (DIVA_XDI_EXTENDED_FEATURES_VALID |
75 DIVA_XDI_EXTENDED_FEATURE_SDRAM_BAR |
76 DIVA_XDI_EXTENDED_FEATURE_CAPI_PRMS |
77#if defined(DIVA_IDI_RX_DMA)
78 DIVA_XDI_EXTENDED_FEATURE_CMA |
79 DIVA_XDI_EXTENDED_FEATURE_RX_DMA |
80 DIVA_XDI_EXTENDED_FEATURE_MANAGEMENT_DMA |
81#endif
82 DIVA_XDI_EXTENDED_FEATURE_NO_CANCEL_RC),
83 0
84};
85
86void
87dump_xlog_buffer(PISDN_ADAPTER IoAdapter, Xdesc *xlogDesc)
88{
89 dword logLen;
90 word *Xlog = xlogDesc->buf;
91 word logCnt = xlogDesc->cnt;
92 word logOut = xlogDesc->out / sizeof(*Xlog);
93 DBG_FTL(("%s: ************* XLOG recovery (%d) *************",
94 &IoAdapter->Name[0], (int)logCnt))
95 DBG_FTL(("Microcode: %s", &IoAdapter->ProtocolIdString[0]))
96 for (; logCnt > 0; --logCnt)
97 {
98 if (!GET_WORD(&Xlog[logOut]))
99 {
100 if (--logCnt == 0)
101 break;
102 logOut = 0;
103 }
104 if (GET_WORD(&Xlog[logOut]) <= (logOut * sizeof(*Xlog)))
105 {
106 if (logCnt > 2)
107 {
108 DBG_FTL(("Possibly corrupted XLOG: %d entries left",
109 (int)logCnt))
110 }
111 break;
112 }
113 logLen = (dword)(GET_WORD(&Xlog[logOut]) - (logOut * sizeof(*Xlog)));
114 DBG_FTL_MXLOG(((char *)&Xlog[logOut + 1], (dword)(logLen - 2)))
115 logOut = (GET_WORD(&Xlog[logOut]) + 1) / sizeof(*Xlog);
116 }
117 DBG_FTL(("%s: ***************** end of XLOG *****************",
118 &IoAdapter->Name[0]))
119 }
120
121#if defined(XDI_USE_XLOG)
122static char *(ExceptionCauseTable[]) =
123{
124 "Interrupt",
125 "TLB mod /IBOUND",
126 "TLB load /DBOUND",
127 "TLB store",
128 "Address error load",
129 "Address error store",
130 "Instruction load bus error",
131 "Data load/store bus error",
132 "Syscall",
133 "Breakpoint",
134 "Reverd instruction",
135 "Coprocessor unusable",
136 "Overflow",
137 "TRAP",
138 "VCEI",
139 "Floating Point Exception",
140 "CP2",
141 "Reserved 17",
142 "Reserved 18",
143 "Reserved 19",
144 "Reserved 20",
145 "Reserved 21",
146 "Reserved 22",
147 "WATCH",
148 "Reserved 24",
149 "Reserved 25",
150 "Reserved 26",
151 "Reserved 27",
152 "Reserved 28",
153 "Reserved 29",
154 "Reserved 30",
155 "VCED"
156};
157#endif
158void
159dump_trap_frame(PISDN_ADAPTER IoAdapter, byte __iomem *exceptionFrame)
160{
161 MP_XCPTC __iomem *xcept = (MP_XCPTC __iomem *)exceptionFrame;
162 dword __iomem *regs;
163 regs = &xcept->regs[0];
164 DBG_FTL(("%s: ***************** CPU TRAPPED *****************",
165 &IoAdapter->Name[0]))
166 DBG_FTL(("Microcode: %s", &IoAdapter->ProtocolIdString[0]))
167 DBG_FTL(("Cause: %s",
168 ExceptionCauseTable[(READ_DWORD(&xcept->cr) & 0x0000007c) >> 2]))
169 DBG_FTL(("sr 0x%08x cr 0x%08x epc 0x%08x vaddr 0x%08x",
170 READ_DWORD(&xcept->sr), READ_DWORD(&xcept->cr),
171 READ_DWORD(&xcept->epc), READ_DWORD(&xcept->vaddr)))
172 DBG_FTL(("zero 0x%08x at 0x%08x v0 0x%08x v1 0x%08x",
173 READ_DWORD(®s[0]), READ_DWORD(®s[1]),
174 READ_DWORD(®s[2]), READ_DWORD(®s[3])))
175 DBG_FTL(("a0 0x%08x a1 0x%08x a2 0x%08x a3 0x%08x",
176 READ_DWORD(®s[4]), READ_DWORD(®s[5]),
177 READ_DWORD(®s[6]), READ_DWORD(®s[7])))
178 DBG_FTL(("t0 0x%08x t1 0x%08x t2 0x%08x t3 0x%08x",
179 READ_DWORD(®s[8]), READ_DWORD(®s[9]),
180 READ_DWORD(®s[10]), READ_DWORD(®s[11])))
181 DBG_FTL(("t4 0x%08x t5 0x%08x t6 0x%08x t7 0x%08x",
182 READ_DWORD(®s[12]), READ_DWORD(®s[13]),
183 READ_DWORD(®s[14]), READ_DWORD(®s[15])))
184 DBG_FTL(("s0 0x%08x s1 0x%08x s2 0x%08x s3 0x%08x",
185 READ_DWORD(®s[16]), READ_DWORD(®s[17]),
186 READ_DWORD(®s[18]), READ_DWORD(®s[19])))
187 DBG_FTL(("s4 0x%08x s5 0x%08x s6 0x%08x s7 0x%08x",
188 READ_DWORD(®s[20]), READ_DWORD(®s[21]),
189 READ_DWORD(®s[22]), READ_DWORD(®s[23])))
190 DBG_FTL(("t8 0x%08x t9 0x%08x k0 0x%08x k1 0x%08x",
191 READ_DWORD(®s[24]), READ_DWORD(®s[25]),
192 READ_DWORD(®s[26]), READ_DWORD(®s[27])))
193 DBG_FTL(("gp 0x%08x sp 0x%08x s8 0x%08x ra 0x%08x",
194 READ_DWORD(®s[28]), READ_DWORD(®s[29]),
195 READ_DWORD(®s[30]), READ_DWORD(®s[31])))
196 DBG_FTL(("md 0x%08x|%08x resvd 0x%08x class 0x%08x",
197 READ_DWORD(&xcept->mdhi), READ_DWORD(&xcept->mdlo),
198 READ_DWORD(&xcept->reseverd), READ_DWORD(&xcept->xclass)))
199 }
200
201
202
203void request(PISDN_ADAPTER IoAdapter, ENTITY *e)
204{
205 byte i;
206 diva_os_spin_lock_magic_t irql;
207
208
209
210
211 if (!e->Req)
212 {
213 IDI_SYNC_REQ *syncReq = (IDI_SYNC_REQ *)e;
214 switch (e->Rc)
215 {
216#if defined(DIVA_IDI_RX_DMA)
217 case IDI_SYNC_REQ_DMA_DESCRIPTOR_OPERATION: {
218 diva_xdi_dma_descriptor_operation_t *pI = \
219 &syncReq->xdi_dma_descriptor_operation.info;
220 if (!IoAdapter->dma_map) {
221 pI->operation = -1;
222 pI->descriptor_number = -1;
223 return;
224 }
225 diva_os_enter_spin_lock(&IoAdapter->data_spin_lock, &irql, "dma_op");
226 if (pI->operation == IDI_SYNC_REQ_DMA_DESCRIPTOR_ALLOC) {
227 pI->descriptor_number = diva_alloc_dma_map_entry(\
228 (struct _diva_dma_map_entry *)IoAdapter->dma_map);
229 if (pI->descriptor_number >= 0) {
230 dword dma_magic;
231 void *local_addr;
232 diva_get_dma_map_entry(\
233 (struct _diva_dma_map_entry *)IoAdapter->dma_map,
234 pI->descriptor_number,
235 &local_addr, &dma_magic);
236 pI->descriptor_address = local_addr;
237 pI->descriptor_magic = dma_magic;
238 pI->operation = 0;
239 } else {
240 pI->operation = -1;
241 }
242 } else if ((pI->operation == IDI_SYNC_REQ_DMA_DESCRIPTOR_FREE) &&
243 (pI->descriptor_number >= 0)) {
244 diva_free_dma_map_entry((struct _diva_dma_map_entry *)IoAdapter->dma_map,
245 pI->descriptor_number);
246 pI->descriptor_number = -1;
247 pI->operation = 0;
248 } else {
249 pI->descriptor_number = -1;
250 pI->operation = -1;
251 }
252 diva_os_leave_spin_lock(&IoAdapter->data_spin_lock, &irql, "dma_op");
253 } return;
254#endif
255 case IDI_SYNC_REQ_XDI_GET_LOGICAL_ADAPTER_NUMBER: {
256 diva_xdi_get_logical_adapter_number_s_t *pI = \
257 &syncReq->xdi_logical_adapter_number.info;
258 pI->logical_adapter_number = IoAdapter->ANum;
259 pI->controller = IoAdapter->ControllerNumber;
260 pI->total_controllers = IoAdapter->Properties.Adapters;
261 } return;
262 case IDI_SYNC_REQ_XDI_GET_CAPI_PARAMS: {
263 diva_xdi_get_capi_parameters_t prms, *pI = &syncReq->xdi_capi_prms.info;
264 memset(&prms, 0x00, sizeof(prms));
265 prms.structure_length = min_t(size_t, sizeof(prms), pI->structure_length);
266 memset(pI, 0x00, pI->structure_length);
267 prms.flag_dynamic_l1_down = (IoAdapter->capi_cfg.cfg_1 & \
268 DIVA_XDI_CAPI_CFG_1_DYNAMIC_L1_ON) ? 1 : 0;
269 prms.group_optimization_enabled = (IoAdapter->capi_cfg.cfg_1 & \
270 DIVA_XDI_CAPI_CFG_1_GROUP_POPTIMIZATION_ON) ? 1 : 0;
271 memcpy(pI, &prms, prms.structure_length);
272 } return;
273 case IDI_SYNC_REQ_XDI_GET_ADAPTER_SDRAM_BAR:
274 syncReq->xdi_sdram_bar.info.bar = IoAdapter->sdram_bar;
275 return;
276 case IDI_SYNC_REQ_XDI_GET_EXTENDED_FEATURES: {
277 dword i;
278 diva_xdi_get_extended_xdi_features_t *pI =\
279 &syncReq->xdi_extended_features.info;
280 pI->buffer_length_in_bytes &= ~0x80000000;
281 if (pI->buffer_length_in_bytes && pI->features) {
282 memset(pI->features, 0x00, pI->buffer_length_in_bytes);
283 }
284 for (i = 0; ((pI->features) && (i < pI->buffer_length_in_bytes) &&
285 (i < DIVA_XDI_EXTENDED_FEATURES_MAX_SZ)); i++) {
286 pI->features[i] = extended_xdi_features[i];
287 }
288 if ((pI->buffer_length_in_bytes < DIVA_XDI_EXTENDED_FEATURES_MAX_SZ) ||
289 (!pI->features)) {
290 pI->buffer_length_in_bytes =\
291 (0x80000000 | DIVA_XDI_EXTENDED_FEATURES_MAX_SZ);
292 }
293 } return;
294 case IDI_SYNC_REQ_XDI_GET_STREAM:
295 if (IoAdapter) {
296 diva_xdi_provide_istream_info(&IoAdapter->a,
297 &syncReq->xdi_stream_info.info);
298 } else {
299 syncReq->xdi_stream_info.info.provided_service = 0;
300 }
301 return;
302 case IDI_SYNC_REQ_GET_NAME:
303 if (IoAdapter)
304 {
305 strcpy(&syncReq->GetName.name[0], IoAdapter->Name);
306 DBG_TRC(("xdi: Adapter %d / Name '%s'",
307 IoAdapter->ANum, IoAdapter->Name))
308 return;
309 }
310 syncReq->GetName.name[0] = '\0';
311 break;
312 case IDI_SYNC_REQ_GET_SERIAL:
313 if (IoAdapter)
314 {
315 syncReq->GetSerial.serial = IoAdapter->serialNo;
316 DBG_TRC(("xdi: Adapter %d / SerialNo %ld",
317 IoAdapter->ANum, IoAdapter->serialNo))
318 return;
319 }
320 syncReq->GetSerial.serial = 0;
321 break;
322 case IDI_SYNC_REQ_GET_CARDTYPE:
323 if (IoAdapter)
324 {
325 syncReq->GetCardType.cardtype = IoAdapter->cardType;
326 DBG_TRC(("xdi: Adapter %d / CardType %ld",
327 IoAdapter->ANum, IoAdapter->cardType))
328 return;
329 }
330 syncReq->GetCardType.cardtype = 0;
331 break;
332 case IDI_SYNC_REQ_GET_XLOG:
333 if (IoAdapter)
334 {
335 pcm_req(IoAdapter, e);
336 return;
337 }
338 e->Ind = 0;
339 break;
340 case IDI_SYNC_REQ_GET_DBG_XLOG:
341 if (IoAdapter)
342 {
343 pcm_req(IoAdapter, e);
344 return;
345 }
346 e->Ind = 0;
347 break;
348 case IDI_SYNC_REQ_GET_FEATURES:
349 if (IoAdapter)
350 {
351 syncReq->GetFeatures.features =
352 (unsigned short)IoAdapter->features;
353 return;
354 }
355 syncReq->GetFeatures.features = 0;
356 break;
357 case IDI_SYNC_REQ_PORTDRV_HOOK:
358 if (IoAdapter)
359 {
360 DBG_TRC(("Xdi:IDI_SYNC_REQ_PORTDRV_HOOK - ignored"))
361 return;
362 }
363 break;
364 }
365 if (IoAdapter)
366 {
367 return;
368 }
369 }
370 DBG_TRC(("xdi: Id 0x%x / Req 0x%x / Rc 0x%x", e->Id, e->Req, e->Rc))
371 if (!IoAdapter)
372 {
373 DBG_FTL(("xdi: uninitialized Adapter used - ignore request"))
374 return;
375 }
376 diva_os_enter_spin_lock(&IoAdapter->data_spin_lock, &irql, "data_req");
377
378
379
380 if (!(e->Id & 0x1f))
381 {
382 if (IoAdapter->e_count >= IoAdapter->e_max)
383 {
384 DBG_FTL(("xdi: all Ids in use (max=%d) --> Req ignored",
385 IoAdapter->e_max))
386 diva_os_leave_spin_lock(&IoAdapter->data_spin_lock, &irql, "data_req");
387 return;
388 }
389
390
391
392 for (i = 1; IoAdapter->e_tbl[i].e; ++i);
393 IoAdapter->e_tbl[i].e = e;
394 IoAdapter->e_count++;
395 e->No = (byte)i;
396 e->More = 0;
397 e->RCurrent = 0xff;
398 }
399 else
400 {
401 i = e->No;
402 }
403
404
405
406 if (e->More & XBUSY)
407 {
408 DBG_FTL(("xdi: Id 0x%x busy --> Req 0x%x ignored", e->Id, e->Req))
409 if (!IoAdapter->trapped && IoAdapter->trapFnc)
410 {
411 IoAdapter->trapFnc(IoAdapter);
412
413
414
415 if (IoAdapter->trapped && IoAdapter->os_trap_nfy_Fnc) {
416 (*(IoAdapter->os_trap_nfy_Fnc))(IoAdapter, IoAdapter->ANum);
417 }
418 }
419 diva_os_leave_spin_lock(&IoAdapter->data_spin_lock, &irql, "data_req");
420 return;
421 }
422
423
424
425 e->More |= XBUSY;
426 e->More &= ~XMOREF;
427 e->XCurrent = 0;
428 e->XOffset = 0;
429
430
431
432 IoAdapter->e_tbl[i].next = 0;
433 if (IoAdapter->head)
434 {
435 IoAdapter->e_tbl[IoAdapter->tail].next = i;
436 IoAdapter->tail = i;
437 }
438 else
439 {
440 IoAdapter->head = i;
441 IoAdapter->tail = i;
442 }
443
444
445
446 diva_os_schedule_soft_isr(&IoAdapter->req_soft_isr);
447 diva_os_leave_spin_lock(&IoAdapter->data_spin_lock, &irql, "data_req");
448}
449
450
451
452void DIDpcRoutine(struct _diva_os_soft_isr *psoft_isr, void *Context) {
453 PISDN_ADAPTER IoAdapter = (PISDN_ADAPTER)Context;
454 ADAPTER *a = &IoAdapter->a;
455 diva_os_atomic_t *pin_dpc = &IoAdapter->in_dpc;
456 if (diva_os_atomic_increment(pin_dpc) == 1) {
457 do {
458 if (IoAdapter->tst_irq(a))
459 {
460 if (!IoAdapter->Unavailable)
461 IoAdapter->dpc(a);
462 IoAdapter->clr_irq(a);
463 }
464 IoAdapter->out(a);
465 } while (diva_os_atomic_decrement(pin_dpc) > 0);
466
467
468
469 if (IoAdapter->pcm_pending) {
470 struct pc_maint *pcm;
471 diva_os_spin_lock_magic_t OldIrql;
472 diva_os_enter_spin_lock(&IoAdapter->data_spin_lock,
473 &OldIrql,
474 "data_dpc");
475 pcm = (struct pc_maint *)IoAdapter->pcm_data;
476 switch (IoAdapter->pcm_pending) {
477 case 1:
478 a->ram_out(a, &IoAdapter->pcm->rc, 0);
479 a->ram_out(a, &IoAdapter->pcm->req, pcm->req);
480 IoAdapter->pcm_pending = 2;
481 break;
482 case 2:
483 if ((int)(a->ram_in(a, &IoAdapter->pcm->rc))) {
484 a->ram_in_buffer(a, IoAdapter->pcm, pcm, sizeof(*pcm));
485 IoAdapter->pcm_pending = 3;
486 }
487 break;
488 case 3:
489 break;
490 }
491 diva_os_leave_spin_lock(&IoAdapter->data_spin_lock,
492 &OldIrql,
493 "data_dpc");
494 }
495
496 }
497}
498
499
500
501static void
502pcm_req(PISDN_ADAPTER IoAdapter, ENTITY *e)
503{
504 diva_os_spin_lock_magic_t OldIrql;
505 int i, rc;
506 ADAPTER *a = &IoAdapter->a;
507 struct pc_maint *pcm = (struct pc_maint *)&e->Ind;
508
509
510
511
512 if (IoAdapter->Properties.Card == CARD_MAE)
513 {
514 diva_os_enter_spin_lock(&IoAdapter->data_spin_lock,
515 &OldIrql,
516 "data_pcm_1");
517 IoAdapter->pcm_data = (void *)pcm;
518 IoAdapter->pcm_pending = 1;
519 diva_os_schedule_soft_isr(&IoAdapter->req_soft_isr);
520 diva_os_leave_spin_lock(&IoAdapter->data_spin_lock,
521 &OldIrql,
522 "data_pcm_1");
523 for (rc = 0, i = (IoAdapter->trapped ? 3000 : 250); !rc && (i > 0); --i)
524 {
525 diva_os_sleep(1);
526 if (IoAdapter->pcm_pending == 3) {
527 diva_os_enter_spin_lock(&IoAdapter->data_spin_lock,
528 &OldIrql,
529 "data_pcm_3");
530 IoAdapter->pcm_pending = 0;
531 IoAdapter->pcm_data = NULL;
532 diva_os_leave_spin_lock(&IoAdapter->data_spin_lock,
533 &OldIrql,
534 "data_pcm_3");
535 return;
536 }
537 diva_os_enter_spin_lock(&IoAdapter->data_spin_lock,
538 &OldIrql,
539 "data_pcm_2");
540 diva_os_schedule_soft_isr(&IoAdapter->req_soft_isr);
541 diva_os_leave_spin_lock(&IoAdapter->data_spin_lock,
542 &OldIrql,
543 "data_pcm_2");
544 }
545 diva_os_enter_spin_lock(&IoAdapter->data_spin_lock,
546 &OldIrql,
547 "data_pcm_4");
548 IoAdapter->pcm_pending = 0;
549 IoAdapter->pcm_data = NULL;
550 diva_os_leave_spin_lock(&IoAdapter->data_spin_lock,
551 &OldIrql,
552 "data_pcm_4");
553 goto Trapped;
554 }
555
556
557
558
559 a->ram_out(a, &IoAdapter->pcm->rc, 0);
560 a->ram_out(a, &IoAdapter->pcm->req, pcm->req);
561 for (i = (IoAdapter->trapped ? 3000 : 250); --i > 0;)
562 {
563 diva_os_sleep(1);
564 rc = (int)(a->ram_in(a, &IoAdapter->pcm->rc));
565 if (rc)
566 {
567 a->ram_in_buffer(a, IoAdapter->pcm, pcm, sizeof(*pcm));
568 return;
569 }
570 }
571Trapped:
572 if (IoAdapter->trapFnc)
573 {
574 int trapped = IoAdapter->trapped;
575 IoAdapter->trapFnc(IoAdapter);
576
577
578
579 if (!trapped && IoAdapter->trapped && IoAdapter->os_trap_nfy_Fnc) {
580 (*(IoAdapter->os_trap_nfy_Fnc))(IoAdapter, IoAdapter->ANum);
581 }
582 }
583}
584
585
586
587byte mem_in(ADAPTER *a, void *addr)
588{
589 byte val;
590 volatile byte __iomem *Base = DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io);
591 val = READ_BYTE(Base + (unsigned long)addr);
592 DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);
593 return (val);
594}
595word mem_inw(ADAPTER *a, void *addr)
596{
597 word val;
598 volatile byte __iomem *Base = DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io);
599 val = READ_WORD((Base + (unsigned long)addr));
600 DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);
601 return (val);
602}
603void mem_in_dw(ADAPTER *a, void *addr, dword *data, int dwords)
604{
605 volatile byte __iomem *Base = DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io);
606 while (dwords--) {
607 *data++ = READ_DWORD((Base + (unsigned long)addr));
608 addr += 4;
609 }
610 DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);
611}
612void mem_in_buffer(ADAPTER *a, void *addr, void *buffer, word length)
613{
614 volatile byte __iomem *Base = DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io);
615 memcpy_fromio(buffer, (Base + (unsigned long)addr), length);
616 DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);
617}
618void mem_look_ahead(ADAPTER *a, PBUFFER *RBuffer, ENTITY *e)
619{
620 PISDN_ADAPTER IoAdapter = (PISDN_ADAPTER)a->io;
621 IoAdapter->RBuffer.length = mem_inw(a, &RBuffer->length);
622 mem_in_buffer(a, RBuffer->P, IoAdapter->RBuffer.P,
623 IoAdapter->RBuffer.length);
624 e->RBuffer = (DBUFFER *)&IoAdapter->RBuffer;
625}
626void mem_out(ADAPTER *a, void *addr, byte data)
627{
628 volatile byte __iomem *Base = DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io);
629 WRITE_BYTE(Base + (unsigned long)addr, data);
630 DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);
631}
632void mem_outw(ADAPTER *a, void *addr, word data)
633{
634 volatile byte __iomem *Base = DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io);
635 WRITE_WORD((Base + (unsigned long)addr), data);
636 DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);
637}
638void mem_out_dw(ADAPTER *a, void *addr, const dword *data, int dwords)
639{
640 volatile byte __iomem *Base = DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io);
641 while (dwords--) {
642 WRITE_DWORD((Base + (unsigned long)addr), *data);
643 addr += 4;
644 data++;
645 }
646 DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);
647}
648void mem_out_buffer(ADAPTER *a, void *addr, void *buffer, word length)
649{
650 volatile byte __iomem *Base = DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io);
651 memcpy_toio((Base + (unsigned long)addr), buffer, length);
652 DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);
653}
654void mem_inc(ADAPTER *a, void *addr)
655{
656 volatile byte __iomem *Base = DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io);
657 byte x = READ_BYTE(Base + (unsigned long)addr);
658 WRITE_BYTE(Base + (unsigned long)addr, x + 1);
659 DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);
660}
661
662
663
664byte io_in(ADAPTER *a, void *adr)
665{
666 byte val;
667 byte __iomem *Port = DIVA_OS_MEM_ATTACH_PORT((PISDN_ADAPTER)a->io);
668 outppw(Port + 4, (word)(unsigned long)adr);
669 val = inpp(Port);
670 DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);
671 return (val);
672}
673word io_inw(ADAPTER *a, void *adr)
674{
675 word val;
676 byte __iomem *Port = DIVA_OS_MEM_ATTACH_PORT((PISDN_ADAPTER)a->io);
677 outppw(Port + 4, (word)(unsigned long)adr);
678 val = inppw(Port);
679 DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);
680 return (val);
681}
682void io_in_buffer(ADAPTER *a, void *adr, void *buffer, word len)
683{
684 byte __iomem *Port = DIVA_OS_MEM_ATTACH_PORT((PISDN_ADAPTER)a->io);
685 byte *P = (byte *)buffer;
686 if ((long)adr & 1) {
687 outppw(Port + 4, (word)(unsigned long)adr);
688 *P = inpp(Port);
689 P++;
690 adr = ((byte *) adr) + 1;
691 len--;
692 if (!len) {
693 DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);
694 return;
695 }
696 }
697 outppw(Port + 4, (word)(unsigned long)adr);
698 inppw_buffer(Port, P, len + 1);
699 DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);
700}
701void io_look_ahead(ADAPTER *a, PBUFFER *RBuffer, ENTITY *e)
702{
703 byte __iomem *Port = DIVA_OS_MEM_ATTACH_PORT((PISDN_ADAPTER)a->io);
704 outppw(Port + 4, (word)(unsigned long)RBuffer);
705 ((PISDN_ADAPTER)a->io)->RBuffer.length = inppw(Port);
706 inppw_buffer(Port, ((PISDN_ADAPTER)a->io)->RBuffer.P, ((PISDN_ADAPTER)a->io)->RBuffer.length + 1);
707 e->RBuffer = (DBUFFER *) &(((PISDN_ADAPTER)a->io)->RBuffer);
708 DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);
709}
710void io_out(ADAPTER *a, void *adr, byte data)
711{
712 byte __iomem *Port = DIVA_OS_MEM_ATTACH_PORT((PISDN_ADAPTER)a->io);
713 outppw(Port + 4, (word)(unsigned long)adr);
714 outpp(Port, data);
715 DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);
716}
717void io_outw(ADAPTER *a, void *adr, word data)
718{
719 byte __iomem *Port = DIVA_OS_MEM_ATTACH_PORT((PISDN_ADAPTER)a->io);
720 outppw(Port + 4, (word)(unsigned long)adr);
721 outppw(Port, data);
722 DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);
723}
724void io_out_buffer(ADAPTER *a, void *adr, void *buffer, word len)
725{
726 byte __iomem *Port = DIVA_OS_MEM_ATTACH_PORT((PISDN_ADAPTER)a->io);
727 byte *P = (byte *)buffer;
728 if ((long)adr & 1) {
729 outppw(Port + 4, (word)(unsigned long)adr);
730 outpp(Port, *P);
731 P++;
732 adr = ((byte *) adr) + 1;
733 len--;
734 if (!len) {
735 DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);
736 return;
737 }
738 }
739 outppw(Port + 4, (word)(unsigned long)adr);
740 outppw_buffer(Port, P, len + 1);
741 DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);
742}
743void io_inc(ADAPTER *a, void *adr)
744{
745 byte x;
746 byte __iomem *Port = DIVA_OS_MEM_ATTACH_PORT((PISDN_ADAPTER)a->io);
747 outppw(Port + 4, (word)(unsigned long)adr);
748 x = inpp(Port);
749 outppw(Port + 4, (word)(unsigned long)adr);
750 outpp(Port, x + 1);
751 DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);
752}
753
754
755
756void free_entity(ADAPTER *a, byte e_no)
757{
758 PISDN_ADAPTER IoAdapter;
759 diva_os_spin_lock_magic_t irql;
760 IoAdapter = (PISDN_ADAPTER) a->io;
761 diva_os_enter_spin_lock(&IoAdapter->data_spin_lock, &irql, "data_free");
762 IoAdapter->e_tbl[e_no].e = NULL;
763 IoAdapter->e_count--;
764 diva_os_leave_spin_lock(&IoAdapter->data_spin_lock, &irql, "data_free");
765}
766void assign_queue(ADAPTER *a, byte e_no, word ref)
767{
768 PISDN_ADAPTER IoAdapter;
769 diva_os_spin_lock_magic_t irql;
770 IoAdapter = (PISDN_ADAPTER) a->io;
771 diva_os_enter_spin_lock(&IoAdapter->data_spin_lock, &irql, "data_assign");
772 IoAdapter->e_tbl[e_no].assign_ref = ref;
773 IoAdapter->e_tbl[e_no].next = (byte)IoAdapter->assign;
774 IoAdapter->assign = e_no;
775 diva_os_leave_spin_lock(&IoAdapter->data_spin_lock, &irql, "data_assign");
776}
777byte get_assign(ADAPTER *a, word ref)
778{
779 PISDN_ADAPTER IoAdapter;
780 diva_os_spin_lock_magic_t irql;
781 byte e_no;
782 IoAdapter = (PISDN_ADAPTER) a->io;
783 diva_os_enter_spin_lock(&IoAdapter->data_spin_lock,
784 &irql,
785 "data_assign_get");
786 for (e_no = (byte)IoAdapter->assign;
787 e_no && IoAdapter->e_tbl[e_no].assign_ref != ref;
788 e_no = IoAdapter->e_tbl[e_no].next);
789 diva_os_leave_spin_lock(&IoAdapter->data_spin_lock,
790 &irql,
791 "data_assign_get");
792 return e_no;
793}
794void req_queue(ADAPTER *a, byte e_no)
795{
796 PISDN_ADAPTER IoAdapter;
797 diva_os_spin_lock_magic_t irql;
798 IoAdapter = (PISDN_ADAPTER) a->io;
799 diva_os_enter_spin_lock(&IoAdapter->data_spin_lock, &irql, "data_req_q");
800 IoAdapter->e_tbl[e_no].next = 0;
801 if (IoAdapter->head) {
802 IoAdapter->e_tbl[IoAdapter->tail].next = e_no;
803 IoAdapter->tail = e_no;
804 }
805 else {
806 IoAdapter->head = e_no;
807 IoAdapter->tail = e_no;
808 }
809 diva_os_leave_spin_lock(&IoAdapter->data_spin_lock, &irql, "data_req_q");
810}
811byte look_req(ADAPTER *a)
812{
813 PISDN_ADAPTER IoAdapter;
814 IoAdapter = (PISDN_ADAPTER) a->io;
815 return ((byte)IoAdapter->head);
816}
817void next_req(ADAPTER *a)
818{
819 PISDN_ADAPTER IoAdapter;
820 diva_os_spin_lock_magic_t irql;
821 IoAdapter = (PISDN_ADAPTER) a->io;
822 diva_os_enter_spin_lock(&IoAdapter->data_spin_lock, &irql, "data_req_next");
823 IoAdapter->head = IoAdapter->e_tbl[IoAdapter->head].next;
824 if (!IoAdapter->head) IoAdapter->tail = 0;
825 diva_os_leave_spin_lock(&IoAdapter->data_spin_lock, &irql, "data_req_next");
826}
827
828
829
830ENTITY *entity_ptr(ADAPTER *a, byte e_no)
831{
832 PISDN_ADAPTER IoAdapter;
833 IoAdapter = (PISDN_ADAPTER)a->io;
834 return (IoAdapter->e_tbl[e_no].e);
835}
836void *PTR_X(ADAPTER *a, ENTITY *e)
837{
838 return ((void *) e->X);
839}
840void *PTR_R(ADAPTER *a, ENTITY *e)
841{
842 return ((void *) e->R);
843}
844void *PTR_P(ADAPTER *a, ENTITY *e, void *P)
845{
846 return P;
847}
848void CALLBACK(ADAPTER *a, ENTITY *e)
849{
850 if (e && e->callback)
851 e->callback(e);
852}
853