Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
io.c
Go to the documentation of this file.
1 
2 /*
3  *
4  Copyright (c) Eicon Networks, 2002.
5  *
6  This source file is supplied for the use with
7  Eicon Networks range of DIVA Server Adapters.
8  *
9  Eicon File Revision : 2.1
10  *
11  This program is free software; you can redistribute it and/or modify
12  it under the terms of the GNU General Public License as published by
13  the Free Software Foundation; either version 2, or (at your option)
14  any later version.
15  *
16  This program is distributed in the hope that it will be useful,
17  but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
18  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19  See the GNU General Public License for more details.
20  *
21  You should have received a copy of the GNU General Public License
22  along with this program; if not, write to the Free Software
23  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
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" /* pc_main.h, packed in os-dependent fashion */
33 #include "di.h"
34 #include "mi_pc.h"
35 #include "io.h"
36 extern ADAPTER *adapter[MAX_ADAPTER];
39 static void pcm_req(PISDN_ADAPTER, ENTITY *);
40 /* --------------------------------------------------------------------------
41  local functions
42  -------------------------------------------------------------------------- */
43 #define ReqFunc(N) \
44  static void Request##N(ENTITY *e) \
45  { if (IoAdapters[N]) (*IoAdapters[N]->DIRequest)(IoAdapters[N], e); }
47 ReqFunc(1)
48 ReqFunc(2)
49 ReqFunc(3)
50 ReqFunc(4)
51 ReqFunc(5)
52 ReqFunc(6)
53 ReqFunc(7)
54 ReqFunc(8)
55 ReqFunc(9)
56 ReqFunc(10)
57 ReqFunc(11)
58 ReqFunc(12)
59 ReqFunc(13)
60 ReqFunc(14)
61 ReqFunc(15)
62 IDI_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  This array should indicate all new services, that this version of XDI
71  is able to provide to his clients
72 */
73 static byte extended_xdi_features[DIVA_XDI_EXTENDED_FEATURES_MAX_SZ + 1] = {
77 #if defined(DIVA_IDI_RX_DMA)
81 #endif
83  0
84 };
85 /*****************************************************************************/
86 void
87 dump_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)
122 static 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
158 void
159 dump_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(&regs[0]), READ_DWORD(&regs[1]),
174  READ_DWORD(&regs[2]), READ_DWORD(&regs[3])))
175  DBG_FTL(("a0 0x%08x a1 0x%08x a2 0x%08x a3 0x%08x",
176  READ_DWORD(&regs[4]), READ_DWORD(&regs[5]),
177  READ_DWORD(&regs[6]), READ_DWORD(&regs[7])))
178  DBG_FTL(("t0 0x%08x t1 0x%08x t2 0x%08x t3 0x%08x",
179  READ_DWORD(&regs[8]), READ_DWORD(&regs[9]),
180  READ_DWORD(&regs[10]), READ_DWORD(&regs[11])))
181  DBG_FTL(("t4 0x%08x t5 0x%08x t6 0x%08x t7 0x%08x",
182  READ_DWORD(&regs[12]), READ_DWORD(&regs[13]),
183  READ_DWORD(&regs[14]), READ_DWORD(&regs[15])))
184  DBG_FTL(("s0 0x%08x s1 0x%08x s2 0x%08x s3 0x%08x",
185  READ_DWORD(&regs[16]), READ_DWORD(&regs[17]),
186  READ_DWORD(&regs[18]), READ_DWORD(&regs[19])))
187  DBG_FTL(("s4 0x%08x s5 0x%08x s6 0x%08x s7 0x%08x",
188  READ_DWORD(&regs[20]), READ_DWORD(&regs[21]),
189  READ_DWORD(&regs[22]), READ_DWORD(&regs[23])))
190  DBG_FTL(("t8 0x%08x t9 0x%08x k0 0x%08x k1 0x%08x",
191  READ_DWORD(&regs[24]), READ_DWORD(&regs[25]),
192  READ_DWORD(&regs[26]), READ_DWORD(&regs[27])))
193  DBG_FTL(("gp 0x%08x sp 0x%08x s8 0x%08x ra 0x%08x",
194  READ_DWORD(&regs[28]), READ_DWORD(&regs[29]),
195  READ_DWORD(&regs[30]), READ_DWORD(&regs[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  Real XDI Request function
202  -------------------------------------------------------------------------- */
203 void request(PISDN_ADAPTER IoAdapter, ENTITY *e)
204 {
205  byte i;
207 /*
208  * if the Req field in the entity structure is 0,
209  * we treat this request as a special function call
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)
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");
228  (struct _diva_dma_map_entry *)IoAdapter->dma_map);
229  if (pI->descriptor_number >= 0) {
230  dword dma_magic;
231  void *local_addr;
233  (struct _diva_dma_map_entry *)IoAdapter->dma_map,
234  pI->descriptor_number,
235  &local_addr, &dma_magic);
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)) {
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
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;
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;
274  syncReq->xdi_sdram_bar.info.bar = IoAdapter->sdram_bar;
275  return;
277  dword i;
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  }
289  (!pI->features)) {
291  (0x80000000 | DIVA_XDI_EXTENDED_FEATURES_MAX_SZ);
292  }
293  } return;
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;
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;
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;
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;
333  if (IoAdapter)
334  {
335  pcm_req(IoAdapter, e);
336  return;
337  }
338  e->Ind = 0;
339  break;
341  if (IoAdapter)
342  {
343  pcm_req(IoAdapter, e);
344  return;
345  }
346  e->Ind = 0;
347  break;
349  if (IoAdapter)
350  {
351  syncReq->GetFeatures.features =
352  (unsigned short)IoAdapter->features;
353  return;
354  }
355  syncReq->GetFeatures.features = 0;
356  break;
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  * assign an entity
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  * find a new free id
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  * if the entity is still busy, ignore the request call
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  Firs trap, also notify user if supported
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  * initialize transmit status variables
424  */
425  e->More |= XBUSY;
426  e->More &= ~XMOREF;
427  e->XCurrent = 0;
428  e->XOffset = 0;
429 /*
430  * queue this entity in the adapter request queue
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  * queue the DPC to process the request
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  Main DPC routine
451  --------------------------------------------------------------------- */
452 void 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  Look for XLOG request (cards with indirect addressing)
468  ---------------------------------------------------------------- */
469  if (IoAdapter->pcm_pending) {
470  struct pc_maint *pcm;
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: /* ask card for XLOG */
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: /* Try to get XLOG from the card */
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: /* let XDI recovery XLOG */
489  break;
490  }
491  diva_os_leave_spin_lock(&IoAdapter->data_spin_lock,
492  &OldIrql,
493  "data_dpc");
494  }
495  /* ---------------------------------------------------------------- */
496  }
497 }
498 /* --------------------------------------------------------------------------
499  XLOG interface
500  -------------------------------------------------------------------------- */
501 static void
502 pcm_req(PISDN_ADAPTER IoAdapter, ENTITY *e)
503 {
505  int i, rc;
506  ADAPTER *a = &IoAdapter->a;
507  struct pc_maint *pcm = (struct pc_maint *)&e->Ind;
508 /*
509  * special handling of I/O based card interface
510  * the memory access isn't an atomic operation !
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;
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");
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  * memory based shared ram is accessible from different
557  * processors without disturbing concurrent processes.
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  }
571 Trapped:
572  if (IoAdapter->trapFnc)
573  {
574  int trapped = IoAdapter->trapped;
575  IoAdapter->trapFnc(IoAdapter);
576  /*
577  Firs trap, also notify user if supported
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 /* ram access functions for memory mapped cards */
586 /*------------------------------------------------------------------*/
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);
593  return (val);
594 }
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));
601  return (val);
602 }
603 void 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  }
611 }
612 void 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);
617 }
618 void 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 }
626 void 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);
631 }
632 void 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);
637 }
638 void 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  }
647 }
648 void 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);
653 }
654 void 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);
660 }
661 /*------------------------------------------------------------------*/
662 /* ram access functions for io-mapped cards */
663 /*------------------------------------------------------------------*/
664 byte io_in(ADAPTER *a, void *adr)
665 {
666  byte val;
668  outppw(Port + 4, (word)(unsigned long)adr);
669  val = inpp(Port);
671  return (val);
672 }
673 word io_inw(ADAPTER *a, void *adr)
674 {
675  word val;
677  outppw(Port + 4, (word)(unsigned long)adr);
678  val = inppw(Port);
680  return (val);
681 }
682 void io_in_buffer(ADAPTER *a, void *adr, void *buffer, word len)
683 {
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) {
694  return;
695  }
696  }
697  outppw(Port + 4, (word)(unsigned long)adr);
698  inppw_buffer(Port, P, len + 1);
700 }
701 void io_look_ahead(ADAPTER *a, PBUFFER *RBuffer, ENTITY *e)
702 {
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);
709 }
710 void io_out(ADAPTER *a, void *adr, byte data)
711 {
713  outppw(Port + 4, (word)(unsigned long)adr);
714  outpp(Port, data);
716 }
717 void io_outw(ADAPTER *a, void *adr, word data)
718 {
720  outppw(Port + 4, (word)(unsigned long)adr);
721  outppw(Port, data);
723 }
724 void io_out_buffer(ADAPTER *a, void *adr, void *buffer, word len)
725 {
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) {
736  return;
737  }
738  }
739  outppw(Port + 4, (word)(unsigned long)adr);
740  outppw_buffer(Port, P, len + 1);
742 }
743 void io_inc(ADAPTER *a, void *adr)
744 {
745  byte x;
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);
752 }
753 /*------------------------------------------------------------------*/
754 /* OS specific functions related to queuing of entities */
755 /*------------------------------------------------------------------*/
756 void free_entity(ADAPTER *a, byte e_no)
757 {
758  PISDN_ADAPTER IoAdapter;
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 }
766 void assign_queue(ADAPTER *a, byte e_no, word ref)
767 {
768  PISDN_ADAPTER IoAdapter;
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 }
778 {
779  PISDN_ADAPTER IoAdapter;
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 }
794 void req_queue(ADAPTER *a, byte e_no)
795 {
796  PISDN_ADAPTER IoAdapter;
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 }
812 {
813  PISDN_ADAPTER IoAdapter;
814  IoAdapter = (PISDN_ADAPTER) a->io;
815  return ((byte)IoAdapter->head);
816 }
818 {
819  PISDN_ADAPTER IoAdapter;
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 /* memory map functions */
829 /*------------------------------------------------------------------*/
831 {
832  PISDN_ADAPTER IoAdapter;
833  IoAdapter = (PISDN_ADAPTER)a->io;
834  return (IoAdapter->e_tbl[e_no].e);
835 }
836 void *PTR_X(ADAPTER *a, ENTITY *e)
837 {
838  return ((void *) e->X);
839 }
840 void *PTR_R(ADAPTER *a, ENTITY *e)
841 {
842  return ((void *) e->R);
843 }
844 void *PTR_P(ADAPTER *a, ENTITY *e, void *P)
845 {
846  return P;
847 }
848 void CALLBACK(ADAPTER *a, ENTITY *e)
849 {
850  if (e && e->callback)
851  e->callback(e);
852 }