• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* $Id: os_pri.c,v 1.32 2004/03/21 17:26:01 armin Exp $ */
2 
3 #include "platform.h"
4 #include "debuglib.h"
5 #include "cardtype.h"
6 #include "pc.h"
7 #include "pr_pc.h"
8 #include "di_defs.h"
9 #include "dsp_defs.h"
10 #include "di.h"
11 #include "io.h"
12 
13 #include "xdi_msg.h"
14 #include "xdi_adapter.h"
15 #include "os_pri.h"
16 #include "diva_pci.h"
17 #include "mi_pc.h"
18 #include "pc_maint.h"
19 #include "dsp_tst.h"
20 #include "diva_dma.h"
21 #include "dsrv_pri.h"
22 
23 /* --------------------------------------------------------------------------
24    OS Dependent part of XDI driver for DIVA PRI Adapter
25 
26    DSP detection/validation by Anthony Booth (Eicon Networks, www.eicon.com)
27    -------------------------------------------------------------------------- */
28 
29 #define DIVA_PRI_NO_PCI_BIOS_WORKAROUND 1
30 
31 extern int diva_card_read_xlog(diva_os_xdi_adapter_t *a);
32 
33 /*
34 **  IMPORTS
35 */
36 extern void prepare_pri_functions(PISDN_ADAPTER IoAdapter);
37 extern void prepare_pri2_functions(PISDN_ADAPTER IoAdapter);
38 extern void diva_xdi_display_adapter_features(int card);
39 
40 static int diva_pri_cleanup_adapter(diva_os_xdi_adapter_t *a);
41 static int diva_pri_cmd_card_proc(struct _diva_os_xdi_adapter *a,
42 				  diva_xdi_um_cfg_cmd_t *cmd, int length);
43 static int pri_get_serial_number(diva_os_xdi_adapter_t *a);
44 static int diva_pri_stop_adapter(diva_os_xdi_adapter_t *a);
45 static dword diva_pri_detect_dsps(diva_os_xdi_adapter_t *a);
46 
47 /*
48 **  Check card revision
49 */
pri_is_rev_2_card(int card_ordinal)50 static int pri_is_rev_2_card(int card_ordinal)
51 {
52 	switch (card_ordinal) {
53 	case CARDTYPE_DIVASRV_P_30M_V2_PCI:
54 	case CARDTYPE_DIVASRV_VOICE_P_30M_V2_PCI:
55 		return (1);
56 	}
57 	return (0);
58 }
59 
diva_pri_set_addresses(diva_os_xdi_adapter_t * a)60 static void diva_pri_set_addresses(diva_os_xdi_adapter_t *a)
61 {
62 	a->resources.pci.mem_type_id[MEM_TYPE_ADDRESS] = 0;
63 	a->resources.pci.mem_type_id[MEM_TYPE_CONTROL] = 2;
64 	a->resources.pci.mem_type_id[MEM_TYPE_CONFIG] = 4;
65 	a->resources.pci.mem_type_id[MEM_TYPE_RAM] = 0;
66 	a->resources.pci.mem_type_id[MEM_TYPE_RESET] = 2;
67 	a->resources.pci.mem_type_id[MEM_TYPE_CFG] = 4;
68 	a->resources.pci.mem_type_id[MEM_TYPE_PROM] = 3;
69 
70 	a->xdi_adapter.Address = a->resources.pci.addr[0];
71 	a->xdi_adapter.Control = a->resources.pci.addr[2];
72 	a->xdi_adapter.Config = a->resources.pci.addr[4];
73 
74 	a->xdi_adapter.ram = a->resources.pci.addr[0];
75 	a->xdi_adapter.ram += MP_SHARED_RAM_OFFSET;
76 
77 	a->xdi_adapter.reset = a->resources.pci.addr[2];
78 	a->xdi_adapter.reset += MP_RESET;
79 
80 	a->xdi_adapter.cfg = a->resources.pci.addr[4];
81 	a->xdi_adapter.cfg += MP_IRQ_RESET;
82 
83 	a->xdi_adapter.sdram_bar = a->resources.pci.bar[0];
84 
85 	a->xdi_adapter.prom = a->resources.pci.addr[3];
86 }
87 
88 /*
89 **  BAR0 - SDRAM, MP_MEMORY_SIZE, MP2_MEMORY_SIZE by Rev.2
90 **  BAR1 - DEVICES,				0x1000
91 **  BAR2 - CONTROL (REG), 0x2000
92 **  BAR3 - FLASH (REG),		0x8000
93 **  BAR4 - CONFIG (CFG),	0x1000
94 */
diva_pri_init_card(diva_os_xdi_adapter_t * a)95 int diva_pri_init_card(diva_os_xdi_adapter_t *a)
96 {
97 	int bar = 0;
98 	int pri_rev_2;
99 	unsigned long bar_length[5] = {
100 		MP_MEMORY_SIZE,
101 		0x1000,
102 		0x2000,
103 		0x8000,
104 		0x1000
105 	};
106 
107 	pri_rev_2 = pri_is_rev_2_card(a->CardOrdinal);
108 
109 	if (pri_rev_2) {
110 		bar_length[0] = MP2_MEMORY_SIZE;
111 	}
112 	/*
113 	  Set properties
114 	*/
115 	a->xdi_adapter.Properties = CardProperties[a->CardOrdinal];
116 	DBG_LOG(("Load %s", a->xdi_adapter.Properties.Name))
117 
118 		/*
119 		  First initialization step: get and check hardware resoures.
120 		  Do not map resources and do not acecess card at this step
121 		*/
122 		for (bar = 0; bar < 5; bar++) {
123 			a->resources.pci.bar[bar] =
124 				divasa_get_pci_bar(a->resources.pci.bus,
125 						   a->resources.pci.func, bar,
126 						   a->resources.pci.hdev);
127 			if (!a->resources.pci.bar[bar]
128 			    || (a->resources.pci.bar[bar] == 0xFFFFFFF0)) {
129 				DBG_ERR(("A: invalid bar[%d]=%08x", bar,
130 					 a->resources.pci.bar[bar]))
131 					return (-1);
132 			}
133 		}
134 	a->resources.pci.irq =
135 		(byte) divasa_get_pci_irq(a->resources.pci.bus,
136 					  a->resources.pci.func,
137 					  a->resources.pci.hdev);
138 	if (!a->resources.pci.irq) {
139 		DBG_ERR(("A: invalid irq"));
140 		return (-1);
141 	}
142 
143 	/*
144 	  Map all BAR's
145 	*/
146 	for (bar = 0; bar < 5; bar++) {
147 		a->resources.pci.addr[bar] =
148 			divasa_remap_pci_bar(a, bar, a->resources.pci.bar[bar],
149 					     bar_length[bar]);
150 		if (!a->resources.pci.addr[bar]) {
151 			DBG_ERR(("A: A(%d), can't map bar[%d]",
152 				 a->controller, bar))
153 				diva_pri_cleanup_adapter(a);
154 			return (-1);
155 		}
156 	}
157 
158 	/*
159 	  Set all memory areas
160 	*/
161 	diva_pri_set_addresses(a);
162 
163 	/*
164 	  Get Serial Number of this adapter
165 	*/
166 	if (pri_get_serial_number(a)) {
167 		dword serNo;
168 		serNo = a->resources.pci.bar[1] & 0xffff0000;
169 		serNo |= ((dword) a->resources.pci.bus) << 8;
170 		serNo += (a->resources.pci.func + a->controller + 1);
171 		a->xdi_adapter.serialNo = serNo & ~0xFF000000;
172 		DBG_ERR(("A: A(%d) can't get Serial Number, generated serNo=%ld",
173 			 a->controller, a->xdi_adapter.serialNo))
174 			}
175 
176 
177 	/*
178 	  Initialize os objects
179 	*/
180 	if (diva_os_initialize_spin_lock(&a->xdi_adapter.isr_spin_lock, "isr")) {
181 		diva_pri_cleanup_adapter(a);
182 		return (-1);
183 	}
184 	if (diva_os_initialize_spin_lock
185 	    (&a->xdi_adapter.data_spin_lock, "data")) {
186 		diva_pri_cleanup_adapter(a);
187 		return (-1);
188 	}
189 
190 	strcpy(a->xdi_adapter.req_soft_isr.dpc_thread_name, "kdivasprid");
191 
192 	if (diva_os_initialize_soft_isr(&a->xdi_adapter.req_soft_isr,
193 					DIDpcRoutine, &a->xdi_adapter)) {
194 		diva_pri_cleanup_adapter(a);
195 		return (-1);
196 	}
197 
198 	/*
199 	  Do not initialize second DPC - only one thread will be created
200 	*/
201 	a->xdi_adapter.isr_soft_isr.object =
202 		a->xdi_adapter.req_soft_isr.object;
203 
204 	/*
205 	  Next step of card initialization:
206 	  set up all interface pointers
207 	*/
208 	a->xdi_adapter.Channels = CardProperties[a->CardOrdinal].Channels;
209 	a->xdi_adapter.e_max = CardProperties[a->CardOrdinal].E_info;
210 
211 	a->xdi_adapter.e_tbl =
212 		diva_os_malloc(0, a->xdi_adapter.e_max * sizeof(E_INFO));
213 	if (!a->xdi_adapter.e_tbl) {
214 		diva_pri_cleanup_adapter(a);
215 		return (-1);
216 	}
217 	memset(a->xdi_adapter.e_tbl, 0x00, a->xdi_adapter.e_max * sizeof(E_INFO));
218 
219 	a->xdi_adapter.a.io = &a->xdi_adapter;
220 	a->xdi_adapter.DIRequest = request;
221 	a->interface.cleanup_adapter_proc = diva_pri_cleanup_adapter;
222 	a->interface.cmd_proc = diva_pri_cmd_card_proc;
223 
224 	if (pri_rev_2) {
225 		prepare_pri2_functions(&a->xdi_adapter);
226 	} else {
227 		prepare_pri_functions(&a->xdi_adapter);
228 	}
229 
230 	a->dsp_mask = diva_pri_detect_dsps(a);
231 
232 	/*
233 	  Allocate DMA map
234 	*/
235 	if (pri_rev_2) {
236 		diva_init_dma_map(a->resources.pci.hdev,
237 				  (struct _diva_dma_map_entry **) &a->xdi_adapter.dma_map, 32);
238 	}
239 
240 	/*
241 	  Set IRQ handler
242 	*/
243 	a->xdi_adapter.irq_info.irq_nr = a->resources.pci.irq;
244 	sprintf(a->xdi_adapter.irq_info.irq_name,
245 		"DIVA PRI %ld", (long) a->xdi_adapter.serialNo);
246 
247 	if (diva_os_register_irq(a, a->xdi_adapter.irq_info.irq_nr,
248 				 a->xdi_adapter.irq_info.irq_name)) {
249 		diva_pri_cleanup_adapter(a);
250 		return (-1);
251 	}
252 	a->xdi_adapter.irq_info.registered = 1;
253 
254 	diva_log_info("%s IRQ:%d SerNo:%d", a->xdi_adapter.Properties.Name,
255 		      a->resources.pci.irq, a->xdi_adapter.serialNo);
256 
257 	return (0);
258 }
259 
diva_pri_cleanup_adapter(diva_os_xdi_adapter_t * a)260 static int diva_pri_cleanup_adapter(diva_os_xdi_adapter_t *a)
261 {
262 	int bar = 0;
263 
264 	/*
265 	  Stop Adapter if adapter is running
266 	*/
267 	if (a->xdi_adapter.Initialized) {
268 		diva_pri_stop_adapter(a);
269 	}
270 
271 	/*
272 	  Remove ISR Handler
273 	*/
274 	if (a->xdi_adapter.irq_info.registered) {
275 		diva_os_remove_irq(a, a->xdi_adapter.irq_info.irq_nr);
276 	}
277 	a->xdi_adapter.irq_info.registered = 0;
278 
279 	/*
280 	  Step 1: unmap all BAR's, if any was mapped
281 	*/
282 	for (bar = 0; bar < 5; bar++) {
283 		if (a->resources.pci.bar[bar]
284 		    && a->resources.pci.addr[bar]) {
285 			divasa_unmap_pci_bar(a->resources.pci.addr[bar]);
286 			a->resources.pci.bar[bar] = 0;
287 			a->resources.pci.addr[bar] = NULL;
288 		}
289 	}
290 
291 	/*
292 	  Free OS objects
293 	*/
294 	diva_os_cancel_soft_isr(&a->xdi_adapter.isr_soft_isr);
295 	diva_os_cancel_soft_isr(&a->xdi_adapter.req_soft_isr);
296 
297 	diva_os_remove_soft_isr(&a->xdi_adapter.req_soft_isr);
298 	a->xdi_adapter.isr_soft_isr.object = NULL;
299 
300 	diva_os_destroy_spin_lock(&a->xdi_adapter.isr_spin_lock, "rm");
301 	diva_os_destroy_spin_lock(&a->xdi_adapter.data_spin_lock, "rm");
302 
303 	/*
304 	  Free memory accupied by XDI adapter
305 	*/
306 	if (a->xdi_adapter.e_tbl) {
307 		diva_os_free(0, a->xdi_adapter.e_tbl);
308 		a->xdi_adapter.e_tbl = NULL;
309 	}
310 	a->xdi_adapter.Channels = 0;
311 	a->xdi_adapter.e_max = 0;
312 
313 
314 	/*
315 	  Free adapter DMA map
316 	*/
317 	diva_free_dma_map(a->resources.pci.hdev,
318 			  (struct _diva_dma_map_entry *) a->xdi_adapter.
319 			  dma_map);
320 	a->xdi_adapter.dma_map = NULL;
321 
322 
323 	/*
324 	  Detach this adapter from debug driver
325 	*/
326 
327 	return (0);
328 }
329 
330 /*
331 **  Activate On Board Boot Loader
332 */
diva_pri_reset_adapter(PISDN_ADAPTER IoAdapter)333 static int diva_pri_reset_adapter(PISDN_ADAPTER IoAdapter)
334 {
335 	dword i;
336 	struct mp_load __iomem *boot;
337 
338 	if (!IoAdapter->Address || !IoAdapter->reset) {
339 		return (-1);
340 	}
341 	if (IoAdapter->Initialized) {
342 		DBG_ERR(("A: A(%d) can't reset PRI adapter - please stop first",
343 			 IoAdapter->ANum))
344 			return (-1);
345 	}
346 
347 	boot = (struct mp_load __iomem *) DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter);
348 	WRITE_DWORD(&boot->err, 0);
349 	DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
350 
351 	IoAdapter->rstFnc(IoAdapter);
352 
353 	diva_os_wait(10);
354 
355 	boot = (struct mp_load __iomem *) DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter);
356 	i = READ_DWORD(&boot->live);
357 
358 	diva_os_wait(10);
359 	if (i == READ_DWORD(&boot->live)) {
360 		DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
361 		DBG_ERR(("A: A(%d) CPU on PRI %ld is not alive!",
362 			 IoAdapter->ANum, IoAdapter->serialNo))
363 			return (-1);
364 	}
365 	if (READ_DWORD(&boot->err)) {
366 		DBG_ERR(("A: A(%d) PRI %ld Board Selftest failed, error=%08lx",
367 			 IoAdapter->ANum, IoAdapter->serialNo,
368 			 READ_DWORD(&boot->err)))
369 			DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
370 		return (-1);
371 	}
372 	DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
373 
374 	/*
375 	  Forget all outstanding entities
376 	*/
377 	IoAdapter->e_count = 0;
378 	if (IoAdapter->e_tbl) {
379 		memset(IoAdapter->e_tbl, 0x00,
380 		       IoAdapter->e_max * sizeof(E_INFO));
381 	}
382 	IoAdapter->head = 0;
383 	IoAdapter->tail = 0;
384 	IoAdapter->assign = 0;
385 	IoAdapter->trapped = 0;
386 
387 	memset(&IoAdapter->a.IdTable[0], 0x00,
388 	       sizeof(IoAdapter->a.IdTable));
389 	memset(&IoAdapter->a.IdTypeTable[0], 0x00,
390 	       sizeof(IoAdapter->a.IdTypeTable));
391 	memset(&IoAdapter->a.FlowControlIdTable[0], 0x00,
392 	       sizeof(IoAdapter->a.FlowControlIdTable));
393 	memset(&IoAdapter->a.FlowControlSkipTable[0], 0x00,
394 	       sizeof(IoAdapter->a.FlowControlSkipTable));
395 	memset(&IoAdapter->a.misc_flags_table[0], 0x00,
396 	       sizeof(IoAdapter->a.misc_flags_table));
397 	memset(&IoAdapter->a.rx_stream[0], 0x00,
398 	       sizeof(IoAdapter->a.rx_stream));
399 	memset(&IoAdapter->a.tx_stream[0], 0x00,
400 	       sizeof(IoAdapter->a.tx_stream));
401 	memset(&IoAdapter->a.tx_pos[0], 0x00, sizeof(IoAdapter->a.tx_pos));
402 	memset(&IoAdapter->a.rx_pos[0], 0x00, sizeof(IoAdapter->a.rx_pos));
403 
404 	return (0);
405 }
406 
407 static int
diva_pri_write_sdram_block(PISDN_ADAPTER IoAdapter,dword address,const byte * data,dword length,dword limit)408 diva_pri_write_sdram_block(PISDN_ADAPTER IoAdapter,
409 			   dword address,
410 			   const byte *data, dword length, dword limit)
411 {
412 	byte __iomem *p = DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter);
413 	byte __iomem *mem = p;
414 
415 	if (((address + length) >= limit) || !mem) {
416 		DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, p);
417 		DBG_ERR(("A: A(%d) write PRI address=0x%08lx",
418 			 IoAdapter->ANum, address + length))
419 			return (-1);
420 	}
421 	mem += address;
422 
423 	/* memcpy_toio(), maybe? */
424 	while (length--) {
425 		WRITE_BYTE(mem++, *data++);
426 	}
427 
428 	DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, p);
429 	return (0);
430 }
431 
432 static int
diva_pri_start_adapter(PISDN_ADAPTER IoAdapter,dword start_address,dword features)433 diva_pri_start_adapter(PISDN_ADAPTER IoAdapter,
434 		       dword start_address, dword features)
435 {
436 	dword i;
437 	int started = 0;
438 	byte __iomem *p;
439 	struct mp_load __iomem *boot = (struct mp_load __iomem *) DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter);
440 	ADAPTER *a = &IoAdapter->a;
441 
442 	if (IoAdapter->Initialized) {
443 		DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
444 		DBG_ERR(("A: A(%d) pri_start_adapter, adapter already running",
445 			 IoAdapter->ANum))
446 			return (-1);
447 	}
448 	if (!boot) {
449 		DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
450 		DBG_ERR(("A: PRI %ld can't start, adapter not mapped",
451 			 IoAdapter->serialNo))
452 			return (-1);
453 	}
454 
455 	sprintf(IoAdapter->Name, "A(%d)", (int) IoAdapter->ANum);
456 	DBG_LOG(("A(%d) start PRI at 0x%08lx", IoAdapter->ANum,
457 		 start_address))
458 
459 		WRITE_DWORD(&boot->addr, start_address);
460 	WRITE_DWORD(&boot->cmd, 3);
461 
462 	for (i = 0; i < 300; ++i) {
463 		diva_os_wait(10);
464 		if ((READ_DWORD(&boot->signature) >> 16) == 0x4447) {
465 			DBG_LOG(("A(%d) Protocol startup time %d.%02d seconds",
466 				 IoAdapter->ANum, (i / 100), (i % 100)))
467 				started = 1;
468 			break;
469 		}
470 	}
471 
472 	if (!started) {
473 		byte __iomem *p = (byte __iomem *)boot;
474 		dword TrapId;
475 		dword debug;
476 		TrapId = READ_DWORD(&p[0x80]);
477 		debug = READ_DWORD(&p[0x1c]);
478 		DBG_ERR(("A(%d) Adapter start failed 0x%08lx, TrapId=%08lx, debug=%08lx",
479 			 IoAdapter->ANum, READ_DWORD(&boot->signature),
480 			 TrapId, debug))
481 			DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
482 		if (IoAdapter->trapFnc) {
483 			(*(IoAdapter->trapFnc)) (IoAdapter);
484 		}
485 		IoAdapter->stop(IoAdapter);
486 		return (-1);
487 	}
488 	DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
489 
490 	IoAdapter->Initialized = true;
491 
492 	/*
493 	  Check Interrupt
494 	*/
495 	IoAdapter->IrqCount = 0;
496 	p = DIVA_OS_MEM_ATTACH_CFG(IoAdapter);
497 	WRITE_DWORD(p, (dword)~0x03E00000);
498 	DIVA_OS_MEM_DETACH_CFG(IoAdapter, p);
499 	a->ReadyInt = 1;
500 	a->ram_out(a, &PR_RAM->ReadyInt, 1);
501 
502 	for (i = 100; !IoAdapter->IrqCount && (i-- > 0); diva_os_wait(10));
503 
504 	if (!IoAdapter->IrqCount) {
505 		DBG_ERR(("A: A(%d) interrupt test failed",
506 			 IoAdapter->ANum))
507 			IoAdapter->Initialized = false;
508 		IoAdapter->stop(IoAdapter);
509 		return (-1);
510 	}
511 
512 	IoAdapter->Properties.Features = (word) features;
513 
514 	diva_xdi_display_adapter_features(IoAdapter->ANum);
515 
516 	DBG_LOG(("A(%d) PRI adapter successfully started", IoAdapter->ANum))
517 		/*
518 		  Register with DIDD
519 		*/
520 		diva_xdi_didd_register_adapter(IoAdapter->ANum);
521 
522 	return (0);
523 }
524 
diva_pri_clear_interrupts(diva_os_xdi_adapter_t * a)525 static void diva_pri_clear_interrupts(diva_os_xdi_adapter_t *a)
526 {
527 	PISDN_ADAPTER IoAdapter = &a->xdi_adapter;
528 
529 	/*
530 	  clear any pending interrupt
531 	*/
532 	IoAdapter->disIrq(IoAdapter);
533 
534 	IoAdapter->tst_irq(&IoAdapter->a);
535 	IoAdapter->clr_irq(&IoAdapter->a);
536 	IoAdapter->tst_irq(&IoAdapter->a);
537 
538 	/*
539 	  kill pending dpcs
540 	*/
541 	diva_os_cancel_soft_isr(&IoAdapter->req_soft_isr);
542 	diva_os_cancel_soft_isr(&IoAdapter->isr_soft_isr);
543 }
544 
545 /*
546 **  Stop Adapter, but do not unmap/unregister - adapter
547 **  will be restarted later
548 */
diva_pri_stop_adapter(diva_os_xdi_adapter_t * a)549 static int diva_pri_stop_adapter(diva_os_xdi_adapter_t *a)
550 {
551 	PISDN_ADAPTER IoAdapter = &a->xdi_adapter;
552 	int i = 100;
553 
554 	if (!IoAdapter->ram) {
555 		return (-1);
556 	}
557 	if (!IoAdapter->Initialized) {
558 		DBG_ERR(("A: A(%d) can't stop PRI adapter - not running",
559 			 IoAdapter->ANum))
560 			return (-1);	/* nothing to stop */
561 	}
562 	IoAdapter->Initialized = 0;
563 
564 	/*
565 	  Disconnect Adapter from DIDD
566 	*/
567 	diva_xdi_didd_remove_adapter(IoAdapter->ANum);
568 
569 	/*
570 	  Stop interrupts
571 	*/
572 	a->clear_interrupts_proc = diva_pri_clear_interrupts;
573 	IoAdapter->a.ReadyInt = 1;
574 	IoAdapter->a.ram_inc(&IoAdapter->a, &PR_RAM->ReadyInt);
575 	do {
576 		diva_os_sleep(10);
577 	} while (i-- && a->clear_interrupts_proc);
578 
579 	if (a->clear_interrupts_proc) {
580 		diva_pri_clear_interrupts(a);
581 		a->clear_interrupts_proc = NULL;
582 		DBG_ERR(("A: A(%d) no final interrupt from PRI adapter",
583 			 IoAdapter->ANum))
584 			}
585 	IoAdapter->a.ReadyInt = 0;
586 
587 	/*
588 	  Stop and reset adapter
589 	*/
590 	IoAdapter->stop(IoAdapter);
591 
592 	return (0);
593 }
594 
595 /*
596 **  Process commands form configuration/download framework and from
597 **  user mode
598 **
599 **  return 0 on success
600 */
601 static int
diva_pri_cmd_card_proc(struct _diva_os_xdi_adapter * a,diva_xdi_um_cfg_cmd_t * cmd,int length)602 diva_pri_cmd_card_proc(struct _diva_os_xdi_adapter *a,
603 		       diva_xdi_um_cfg_cmd_t *cmd, int length)
604 {
605 	int ret = -1;
606 
607 	if (cmd->adapter != a->controller) {
608 		DBG_ERR(("A: pri_cmd, invalid controller=%d != %d",
609 			 cmd->adapter, a->controller))
610 			return (-1);
611 	}
612 
613 	switch (cmd->command) {
614 	case DIVA_XDI_UM_CMD_GET_CARD_ORDINAL:
615 		a->xdi_mbox.data_length = sizeof(dword);
616 		a->xdi_mbox.data =
617 			diva_os_malloc(0, a->xdi_mbox.data_length);
618 		if (a->xdi_mbox.data) {
619 			*(dword *) a->xdi_mbox.data =
620 				(dword) a->CardOrdinal;
621 			a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
622 			ret = 0;
623 		}
624 		break;
625 
626 	case DIVA_XDI_UM_CMD_GET_SERIAL_NR:
627 		a->xdi_mbox.data_length = sizeof(dword);
628 		a->xdi_mbox.data =
629 			diva_os_malloc(0, a->xdi_mbox.data_length);
630 		if (a->xdi_mbox.data) {
631 			*(dword *) a->xdi_mbox.data =
632 				(dword) a->xdi_adapter.serialNo;
633 			a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
634 			ret = 0;
635 		}
636 		break;
637 
638 	case DIVA_XDI_UM_CMD_GET_PCI_HW_CONFIG:
639 		a->xdi_mbox.data_length = sizeof(dword) * 9;
640 		a->xdi_mbox.data =
641 			diva_os_malloc(0, a->xdi_mbox.data_length);
642 		if (a->xdi_mbox.data) {
643 			int i;
644 			dword *data = (dword *) a->xdi_mbox.data;
645 
646 			for (i = 0; i < 8; i++) {
647 				*data++ = a->resources.pci.bar[i];
648 			}
649 			*data++ = (dword) a->resources.pci.irq;
650 			a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
651 			ret = 0;
652 		}
653 		break;
654 
655 	case DIVA_XDI_UM_CMD_RESET_ADAPTER:
656 		ret = diva_pri_reset_adapter(&a->xdi_adapter);
657 		break;
658 
659 	case DIVA_XDI_UM_CMD_WRITE_SDRAM_BLOCK:
660 		ret = diva_pri_write_sdram_block(&a->xdi_adapter,
661 						 cmd->command_data.
662 						 write_sdram.offset,
663 						 (byte *)&cmd[1],
664 						 cmd->command_data.
665 						 write_sdram.length,
666 						 pri_is_rev_2_card(a->
667 								   CardOrdinal)
668 						 ? MP2_MEMORY_SIZE :
669 						 MP_MEMORY_SIZE);
670 		break;
671 
672 	case DIVA_XDI_UM_CMD_STOP_ADAPTER:
673 		ret = diva_pri_stop_adapter(a);
674 		break;
675 
676 	case DIVA_XDI_UM_CMD_START_ADAPTER:
677 		ret = diva_pri_start_adapter(&a->xdi_adapter,
678 					     cmd->command_data.start.
679 					     offset,
680 					     cmd->command_data.start.
681 					     features);
682 		break;
683 
684 	case DIVA_XDI_UM_CMD_SET_PROTOCOL_FEATURES:
685 		a->xdi_adapter.features =
686 			cmd->command_data.features.features;
687 		a->xdi_adapter.a.protocol_capabilities =
688 			a->xdi_adapter.features;
689 		DBG_TRC(("Set raw protocol features (%08x)",
690 			 a->xdi_adapter.features))
691 			ret = 0;
692 		break;
693 
694 	case DIVA_XDI_UM_CMD_GET_CARD_STATE:
695 		a->xdi_mbox.data_length = sizeof(dword);
696 		a->xdi_mbox.data =
697 			diva_os_malloc(0, a->xdi_mbox.data_length);
698 		if (a->xdi_mbox.data) {
699 			dword *data = (dword *) a->xdi_mbox.data;
700 			if (!a->xdi_adapter.ram ||
701 			    !a->xdi_adapter.reset ||
702 			    !a->xdi_adapter.cfg) {
703 				*data = 3;
704 			} else if (a->xdi_adapter.trapped) {
705 				*data = 2;
706 			} else if (a->xdi_adapter.Initialized) {
707 				*data = 1;
708 			} else {
709 				*data = 0;
710 			}
711 			a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
712 			ret = 0;
713 		}
714 		break;
715 
716 	case DIVA_XDI_UM_CMD_READ_XLOG_ENTRY:
717 		ret = diva_card_read_xlog(a);
718 		break;
719 
720 	case DIVA_XDI_UM_CMD_READ_SDRAM:
721 		if (a->xdi_adapter.Address) {
722 			if (
723 				(a->xdi_mbox.data_length =
724 				 cmd->command_data.read_sdram.length)) {
725 				if (
726 					(a->xdi_mbox.data_length +
727 					 cmd->command_data.read_sdram.offset) <
728 					a->xdi_adapter.MemorySize) {
729 					a->xdi_mbox.data =
730 						diva_os_malloc(0,
731 							       a->xdi_mbox.
732 							       data_length);
733 					if (a->xdi_mbox.data) {
734 						byte __iomem *p = DIVA_OS_MEM_ATTACH_ADDRESS(&a->xdi_adapter);
735 						byte __iomem *src = p;
736 						byte *dst = a->xdi_mbox.data;
737 						dword len = a->xdi_mbox.data_length;
738 
739 						src += cmd->command_data.read_sdram.offset;
740 
741 						while (len--) {
742 							*dst++ = READ_BYTE(src++);
743 						}
744 						a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
745 						DIVA_OS_MEM_DETACH_ADDRESS(&a->xdi_adapter, p);
746 						ret = 0;
747 					}
748 				}
749 			}
750 		}
751 		break;
752 
753 	default:
754 		DBG_ERR(("A: A(%d) invalid cmd=%d", a->controller,
755 			 cmd->command))
756 			}
757 
758 	return (ret);
759 }
760 
761 /*
762 **  Get Serial Number
763 */
pri_get_serial_number(diva_os_xdi_adapter_t * a)764 static int pri_get_serial_number(diva_os_xdi_adapter_t *a)
765 {
766 	byte data[64];
767 	int i;
768 	dword len = sizeof(data);
769 	volatile byte __iomem *config;
770 	volatile byte __iomem *flash;
771 	byte c;
772 
773 /*
774  *  First set some GT6401x config registers before accessing the BOOT-ROM
775  */
776 	config = DIVA_OS_MEM_ATTACH_CONFIG(&a->xdi_adapter);
777 	c = READ_BYTE(&config[0xc3c]);
778 	if (!(c & 0x08)) {
779 		WRITE_BYTE(&config[0xc3c], c);	/* Base Address enable register */
780 	}
781 	WRITE_BYTE(&config[LOW_BOOTCS_DREG], 0x00);
782 	WRITE_BYTE(&config[HI_BOOTCS_DREG], 0xFF);
783 	DIVA_OS_MEM_DETACH_CONFIG(&a->xdi_adapter, config);
784 /*
785  *  Read only the last 64 bytes of manufacturing data
786  */
787 	memset(data, '\0', len);
788 	flash = DIVA_OS_MEM_ATTACH_PROM(&a->xdi_adapter);
789 	for (i = 0; i < len; i++) {
790 		data[i] = READ_BYTE(&flash[0x8000 - len + i]);
791 	}
792 	DIVA_OS_MEM_DETACH_PROM(&a->xdi_adapter, flash);
793 
794 	config = DIVA_OS_MEM_ATTACH_CONFIG(&a->xdi_adapter);
795 	WRITE_BYTE(&config[LOW_BOOTCS_DREG], 0xFC);	/* Disable FLASH EPROM access */
796 	WRITE_BYTE(&config[HI_BOOTCS_DREG], 0xFF);
797 	DIVA_OS_MEM_DETACH_CONFIG(&a->xdi_adapter, config);
798 
799 	if (memcmp(&data[48], "DIVAserverPR", 12)) {
800 #if !defined(DIVA_PRI_NO_PCI_BIOS_WORKAROUND)	/* { */
801 		word cmd = 0, cmd_org;
802 		void *addr;
803 		dword addr1, addr3, addr4;
804 		byte Bus, Slot;
805 		void *hdev;
806 		addr4 = a->resources.pci.bar[4];
807 		addr3 = a->resources.pci.bar[3];	/* flash  */
808 		addr1 = a->resources.pci.bar[1];	/* unused */
809 
810 		DBG_ERR(("A: apply Compaq BIOS workaround"))
811 			DBG_LOG(("%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
812 				 data[0], data[1], data[2], data[3],
813 				 data[4], data[5], data[6], data[7]))
814 
815 			Bus = a->resources.pci.bus;
816 		Slot = a->resources.pci.func;
817 		hdev = a->resources.pci.hdev;
818 		PCIread(Bus, Slot, 0x04, &cmd_org, sizeof(cmd_org), hdev);
819 		PCIwrite(Bus, Slot, 0x04, &cmd, sizeof(cmd), hdev);
820 
821 		PCIwrite(Bus, Slot, 0x14, &addr4, sizeof(addr4), hdev);
822 		PCIwrite(Bus, Slot, 0x20, &addr1, sizeof(addr1), hdev);
823 
824 		PCIwrite(Bus, Slot, 0x04, &cmd_org, sizeof(cmd_org), hdev);
825 
826 		addr = a->resources.pci.addr[1];
827 		a->resources.pci.addr[1] = a->resources.pci.addr[4];
828 		a->resources.pci.addr[4] = addr;
829 
830 		addr1 = a->resources.pci.bar[1];
831 		a->resources.pci.bar[1] = a->resources.pci.bar[4];
832 		a->resources.pci.bar[4] = addr1;
833 
834 		/*
835 		  Try to read Flash again
836 		*/
837 		len = sizeof(data);
838 
839 		config = DIVA_OS_MEM_ATTACH_CONFIG(&a->xdi_adapter);
840 		if (!(config[0xc3c] & 0x08)) {
841 			config[0xc3c] |= 0x08;	/* Base Address enable register */
842 		}
843 		config[LOW_BOOTCS_DREG] = 0x00;
844 		config[HI_BOOTCS_DREG] = 0xFF;
845 		DIVA_OS_MEM_DETACH_CONFIG(&a->xdi_adapter, config);
846 
847 		memset(data, '\0', len);
848 		flash = DIVA_OS_MEM_ATTACH_PROM(&a->xdi_adapter);
849 		for (i = 0; i < len; i++) {
850 			data[i] = flash[0x8000 - len + i];
851 		}
852 		DIVA_OS_MEM_ATTACH_PROM(&a->xdi_adapter, flash);
853 		config = DIVA_OS_MEM_ATTACH_CONFIG(&a->xdi_adapter);
854 		config[LOW_BOOTCS_DREG] = 0xFC;
855 		config[HI_BOOTCS_DREG] = 0xFF;
856 		DIVA_OS_MEM_DETACH_CONFIG(&a->xdi_adapter, config);
857 
858 		if (memcmp(&data[48], "DIVAserverPR", 12)) {
859 			DBG_ERR(("A: failed to read serial number"))
860 				DBG_LOG(("%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
861 					 data[0], data[1], data[2], data[3],
862 					 data[4], data[5], data[6], data[7]))
863 				return (-1);
864 		}
865 #else				/* } { */
866 		DBG_ERR(("A: failed to read DIVA signature word"))
867 			DBG_LOG(("%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
868 				 data[0], data[1], data[2], data[3],
869 				 data[4], data[5], data[6], data[7]))
870 			DBG_LOG(("%02x:%02x:%02x:%02x", data[47], data[46],
871 				 data[45], data[44]))
872 #endif				/* } */
873 			}
874 
875 	a->xdi_adapter.serialNo =
876 		(data[47] << 24) | (data[46] << 16) | (data[45] << 8) |
877 		data[44];
878 	if (!a->xdi_adapter.serialNo
879 	    || (a->xdi_adapter.serialNo == 0xffffffff)) {
880 		a->xdi_adapter.serialNo = 0;
881 		DBG_ERR(("A: failed to read serial number"))
882 			return (-1);
883 	}
884 
885 	DBG_LOG(("Serial No.          : %ld", a->xdi_adapter.serialNo))
886 		DBG_TRC(("Board Revision      : %d.%02d", (int) data[41],
887 			 (int) data[40]))
888 		DBG_TRC(("PLD revision        : %d.%02d", (int) data[33],
889 			 (int) data[32]))
890 		DBG_TRC(("Boot loader version : %d.%02d", (int) data[37],
891 			 (int) data[36]))
892 
893 		DBG_TRC(("Manufacturing Date  : %d/%02d/%02d  (yyyy/mm/dd)",
894 			 (int) ((data[28] > 90) ? 1900 : 2000) +
895 			 (int) data[28], (int) data[29], (int) data[30]))
896 
897 		return (0);
898 }
899 
diva_os_prepare_pri2_functions(PISDN_ADAPTER IoAdapter)900 void diva_os_prepare_pri2_functions(PISDN_ADAPTER IoAdapter)
901 {
902 }
903 
diva_os_prepare_pri_functions(PISDN_ADAPTER IoAdapter)904 void diva_os_prepare_pri_functions(PISDN_ADAPTER IoAdapter)
905 {
906 }
907 
908 /*
909 **  Checks presence of DSP on board
910 */
911 static int
dsp_check_presence(volatile byte __iomem * addr,volatile byte __iomem * data,int dsp)912 dsp_check_presence(volatile byte __iomem *addr, volatile byte __iomem *data, int dsp)
913 {
914 	word pattern;
915 
916 	WRITE_WORD(addr, 0x4000);
917 	WRITE_WORD(data, DSP_SIGNATURE_PROBE_WORD);
918 
919 	WRITE_WORD(addr, 0x4000);
920 	pattern = READ_WORD(data);
921 
922 	if (pattern != DSP_SIGNATURE_PROBE_WORD) {
923 		DBG_TRC(("W: DSP[%d] %04x(is) != %04x(should)",
924 			 dsp, pattern, DSP_SIGNATURE_PROBE_WORD))
925 			return (-1);
926 	}
927 
928 	WRITE_WORD(addr, 0x4000);
929 	WRITE_WORD(data, ~DSP_SIGNATURE_PROBE_WORD);
930 
931 	WRITE_WORD(addr, 0x4000);
932 	pattern = READ_WORD(data);
933 
934 	if (pattern != (word)~DSP_SIGNATURE_PROBE_WORD) {
935 		DBG_ERR(("A: DSP[%d] %04x(is) != %04x(should)",
936 			 dsp, pattern, (word)~DSP_SIGNATURE_PROBE_WORD))
937 			return (-2);
938 	}
939 
940 	DBG_TRC(("DSP[%d] present", dsp))
941 
942 		return (0);
943 }
944 
945 
946 /*
947 **  Check if DSP's are present and operating
948 **  Information about detected DSP's is returned as bit mask
949 **  Bit 0  - DSP1
950 **  ...
951 **  ...
952 **  ...
953 **  Bit 29 - DSP30
954 */
diva_pri_detect_dsps(diva_os_xdi_adapter_t * a)955 static dword diva_pri_detect_dsps(diva_os_xdi_adapter_t *a)
956 {
957 	byte __iomem *base;
958 	byte __iomem *p;
959 	dword ret = 0;
960 	dword row_offset[7] = {
961 		0x00000000,
962 		0x00000800,	/* 1 - ROW 1 */
963 		0x00000840,	/* 2 - ROW 2 */
964 		0x00001000,	/* 3 - ROW 3 */
965 		0x00001040,	/* 4 - ROW 4 */
966 		0x00000000	/* 5 - ROW 0 */
967 	};
968 
969 	byte __iomem *dsp_addr_port;
970 	byte __iomem *dsp_data_port;
971 	byte row_state;
972 	int dsp_row = 0, dsp_index, dsp_num;
973 
974 	if (!a->xdi_adapter.Control || !a->xdi_adapter.reset) {
975 		return (0);
976 	}
977 
978 	p = DIVA_OS_MEM_ATTACH_RESET(&a->xdi_adapter);
979 	WRITE_BYTE(p, _MP_RISC_RESET | _MP_DSP_RESET);
980 	DIVA_OS_MEM_DETACH_RESET(&a->xdi_adapter, p);
981 	diva_os_wait(5);
982 
983 	base = DIVA_OS_MEM_ATTACH_CONTROL(&a->xdi_adapter);
984 
985 	for (dsp_num = 0; dsp_num < 30; dsp_num++) {
986 		dsp_row = dsp_num / 7 + 1;
987 		dsp_index = dsp_num % 7;
988 
989 		dsp_data_port = base;
990 		dsp_addr_port = base;
991 
992 		dsp_data_port += row_offset[dsp_row];
993 		dsp_addr_port += row_offset[dsp_row];
994 
995 		dsp_data_port += (dsp_index * 8);
996 		dsp_addr_port += (dsp_index * 8) + 0x80;
997 
998 		if (!dsp_check_presence
999 		    (dsp_addr_port, dsp_data_port, dsp_num + 1)) {
1000 			ret |= (1 << dsp_num);
1001 		}
1002 	}
1003 	DIVA_OS_MEM_DETACH_CONTROL(&a->xdi_adapter, base);
1004 
1005 	p = DIVA_OS_MEM_ATTACH_RESET(&a->xdi_adapter);
1006 	WRITE_BYTE(p, _MP_RISC_RESET | _MP_LED1 | _MP_LED2);
1007 	DIVA_OS_MEM_DETACH_RESET(&a->xdi_adapter, p);
1008 	diva_os_wait(5);
1009 
1010 	/*
1011 	  Verify modules
1012 	*/
1013 	for (dsp_row = 0; dsp_row < 4; dsp_row++) {
1014 		row_state = ((ret >> (dsp_row * 7)) & 0x7F);
1015 		if (row_state && (row_state != 0x7F)) {
1016 			for (dsp_index = 0; dsp_index < 7; dsp_index++) {
1017 				if (!(row_state & (1 << dsp_index))) {
1018 					DBG_ERR(("A: MODULE[%d]-DSP[%d] failed",
1019 						 dsp_row + 1,
1020 						 dsp_index + 1))
1021 						}
1022 			}
1023 		}
1024 	}
1025 
1026 	if (!(ret & 0x10000000)) {
1027 		DBG_ERR(("A: ON BOARD-DSP[1] failed"))
1028 			}
1029 	if (!(ret & 0x20000000)) {
1030 		DBG_ERR(("A: ON BOARD-DSP[2] failed"))
1031 			}
1032 
1033 	/*
1034 	  Print module population now
1035 	*/
1036 	DBG_LOG(("+-----------------------+"))
1037 		DBG_LOG(("| DSP MODULE POPULATION |"))
1038 		DBG_LOG(("+-----------------------+"))
1039 		DBG_LOG(("|  1  |  2  |  3  |  4  |"))
1040 		DBG_LOG(("+-----------------------+"))
1041 		DBG_LOG(("|  %s  |  %s  |  %s  |  %s  |",
1042 			 ((ret >> (0 * 7)) & 0x7F) ? "Y" : "N",
1043 			 ((ret >> (1 * 7)) & 0x7F) ? "Y" : "N",
1044 			 ((ret >> (2 * 7)) & 0x7F) ? "Y" : "N",
1045 			 ((ret >> (3 * 7)) & 0x7F) ? "Y" : "N"))
1046 		DBG_LOG(("+-----------------------+"))
1047 
1048 		DBG_LOG(("DSP's(present-absent):%08x-%08x", ret,
1049 			 ~ret & 0x3fffffff))
1050 
1051 		return (ret);
1052 }
1053