Annotation of sys/dev/pci/if_sandrv.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: if_sandrv.c,v 1.11 2006/04/20 20:31:12 miod Exp $ */
2:
3: /*-
4: * Copyright (c) 2001-2004 Sangoma Technologies (SAN)
5: * All rights reserved. www.sangoma.com
6: *
7: * This code is written by Alex Feldman <al.feldman@sangoma.com> for SAN.
8: *
9: * Redistribution and use in source and binary forms, with or without
10: * modification, are permitted provided that the following conditions
11: * are met:
12: * 1. Redistributions of source code must retain the above copyright
13: * notice, this list of conditions and the following disclaimer.
14: * 2. Redistributions in binary form must reproduce the above
15: * copyright notice, this list of conditions and the following disclaimer
16: * in the documentation and/or other materials provided with the
17: * distribution.
18: * 3. Neither the name of Sangoma Technologies nor the names of its
19: * contributors may be used to endorse or promote products derived
20: * from this software without specific prior written permission.
21: *
22: * THIS SOFTWARE IS PROVIDED BY SANGOMA TECHNOLOGIES AND CONTRIBUTORS
23: * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24: * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
25: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
26: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
32: * THE POSSIBILITY OF SUCH DAMAGE.
33: */
34:
35: #define __SDLA_HW_LEVEL
36: #define __SDLADRV__
37:
38: #include <sys/types.h>
39: #include <sys/param.h>
40: #include <sys/systm.h>
41: #include <sys/syslog.h>
42: #include <sys/malloc.h>
43: #include <sys/kernel.h>
44:
45: #include <dev/pci/pcireg.h>
46: #include <dev/pci/pcivar.h>
47: #include <dev/pci/if_san_front_end.h>
48: #include <dev/pci/if_sandrv.h>
49:
50: #define EXEC_DELAY 20 /* shared memory access delay, mks */
51: #define EXEC_TIMEOUT (hz*2)
52: #define MAX_NLOOPS (EXEC_DELAY*2000)
53: /* timeout used if jiffies are stopped
54: ** EXEC_DELAY=20
55: ** EXEC_TIMEOUT=EXEC_DELAY*2000 = 40000
56: ** 40000 ~= 80 jiffies = EXEC_TIMEOUT */
57:
58: #define EXEC_HZ_DIVISOR 8/10
59: /* We don't want to wait a full second on sdla_exec
60: ** timeout, thus use HZ * EXEC_HZ_DIVISOR to get
61: ** the number of jiffies we would like to wait */
62:
63: #define IS_SUPPORTED_ADAPTER(hw) ((hw)->type == SDLA_AFT)
64:
65: #define SDLA_CTYPE_NAME(type) \
66: ((type) == SDLA_AFT) ? "AFT" : "Unknown"
67:
68: #define IS_AFT(hw) (hw->type == SDLA_AFT)
69:
70: /* Definitions for identifying and finding S514 PCI adapters */
71: #define V3_VENDOR_ID 0x11B0 /* V3 vendor ID number */
72: #define V3_DEVICE_ID 0x0002 /* V3 device ID number */
73: #define SANGOMA_SUBSYS_VENDOR 0x4753 /* ID for Sangoma */
74:
75: /* Definition for identifying and finding XILINX PCI adapters */
76: #define SANGOMA_PCI_VENDOR 0x1923 /* Old value -> 0x11B0 */
77: #define SANGOMA_PCI_VENDOR_OLD 0x10EE /* Old value -> 0x11B0 */
78: #define SANGOMA_PCI_DEVICE 0x0300 /* Old value -> 0x0200 */
79:
80: #define A101_1TE1_SUBSYS_VENDOR 0xA010 /* A101 with T1/E1 1 line */
81: #define A101_2TE1_SUBSYS_VENDOR 0xA011 /* A101 with T1/E1 2 lines */
82: #define A105_T3_SUBSYS_VENDOR 0xA020 /* A102 with T3 */
83:
84: /* Read PCI SUBVENDOR ID */
85: #define PCI_SUBVENDOR_MASK 0xFFFF
86: #define PCI_SUBVENDOR(pa) (pci_conf_read(pa->pa_pc, pa->pa_tag, \
87: PCI_SUBSYS_ID_REG) & PCI_SUBVENDOR_MASK)
88: #define PCI_DEVICE_MASK 0xFFFF0000
89: #define PCI_DEVICE(id) ((id & PCI_DEVICE_MASK ) >> 16)
90:
91: /* Status values */
92: #define SDLA_MEM_RESERVED 0x0001
93: #define SDLA_MEM_MAPPED 0x0002
94: #define SDLA_IO_MAPPED 0x0004
95: #define SDLA_PCI_ENABLE 0x0008
96:
97: struct san_softc {
98: struct device dev;
99: struct pci_attach_args pa;
100: };
101:
102: typedef struct sdla_hw_probe {
103: int used;
104: unsigned char hw_info[100];
105: LIST_ENTRY(sdla_hw_probe) next;
106: } sdla_hw_probe_t;
107:
108: /*
109: * This structure keeps common parameters per physical card.
110: */
111: typedef struct sdlahw_card {
112: int used;
113: unsigned int type; /* S50x/S514/ADSL/XILINX */
114: unsigned int atype; /* SubVendor ID */
115: unsigned char core_id; /* SubSystem ID [0..7] */
116: unsigned char core_rev; /* SubSystem ID [8..15] */
117: unsigned char pci_extra_ver;
118: unsigned int slot_no;
119: unsigned int bus_no;
120: bus_space_tag_t memt;
121: struct pci_attach_args pa; /* PCI config header info */
122: pci_intr_handle_t ih;
123: LIST_ENTRY(sdlahw_card) next;
124: } sdlahw_card_t;
125:
126: /*
127: * Adapter hardware configuration. Pointer to this structure is passed to all
128: * APIs.
129: */
130: typedef struct sdlahw {
131: int used;
132: unsigned magic;
133: char devname[20];
134: u_int16_t status;
135: int irq; /* interrupt request level */
136: unsigned int cpu_no; /* PCI CPU Number */
137: char auto_pci_cfg; /* Auto PCI configuration */
138: bus_addr_t mem_base_addr;
139: bus_space_handle_t dpmbase; /* dual-port memory base */
140: unsigned dpmsize; /* dual-port memory size */
141: unsigned long memory; /* memory size */
142:
143: unsigned reserved[5];
144: unsigned char hw_info[100];
145:
146: u_int16_t configured;
147: void *arg; /* card structure */
148: sdla_hw_probe_t *hwprobe;
149: sdlahw_card_t *hwcard;
150: LIST_ENTRY(sdlahw) next;
151: } sdlahw_t;
152:
153: /* Entry Point for Low-Level function */
154: int sdladrv_init(void);
155: int sdladrv_exit(void);
156:
157: static int sdla_pci_probe(int, struct pci_attach_args *);
158:
159: /* PCI bus interface function */
160: static int sdla_pci_write_config_word(void *, int, u_int16_t);
161: static int sdla_pci_write_config_dword(void *, int, u_int32_t);
162: static int sdla_pci_read_config_byte(void *, int, u_int8_t *);
163: static int sdla_pci_read_config_word(void *, int, u_int16_t *);
164: static int sdla_pci_read_config_dword(void *, int, u_int32_t *);
165:
166: static int sdla_detect (sdlahw_t *);
167: static int sdla_detect_aft(sdlahw_t *);
168: static int sdla_exec(sdlahw_t *, unsigned long);
169: static void sdla_peek_by_4(sdlahw_t *, unsigned long, void *, unsigned int);
170: static void sdla_poke_by_4(sdlahw_t *, unsigned long, void *, unsigned int);
171:
172: static sdlahw_card_t* sdla_card_register(u_int16_t, int, int);
173: #if 0
174: static int sdla_card_unregister (unsigned char, int, int, int);
175: #endif
176: static sdlahw_card_t* sdla_card_search(u_int16_t, int, int);
177:
178: static sdlahw_t* sdla_hw_register(sdlahw_card_t *, int, int, void *);
179: #if 0
180: static int sdla_hw_unregister(sdlahw_card_t*, int);
181: #endif
182: static sdlahw_t* sdla_hw_search(u_int16_t, int, int, int);
183:
184: static sdlahw_t* sdla_aft_hw_select (sdlahw_card_t *, int, int,
185: struct pci_attach_args *);
186: static void sdla_save_hw_probe (sdlahw_t*, int);
187:
188: /* SDLA PCI device relative entry point */
189: int san_match(struct device *, void *, void *);
190: void san_attach(struct device *, struct device *, void *);
191:
192:
193: struct cfdriver san_cd = {
194: NULL, "san", DV_IFNET
195: };
196:
197: struct cfattach san_ca = {
198: sizeof(struct san_softc), san_match, san_attach
199: };
200:
201: extern int ticks;
202:
203: /* SDLA ISA/PCI varibles */
204: static int Sangoma_cards_no = 0;
205: static int Sangoma_devices_no = 0;
206: static int Sangoma_PCI_cards_no = 0;
207:
208: /* private data */
209: char *san_drvname = "san";
210:
211: /* Array of already initialized PCI slots */
212: static int pci_slot_ar[MAX_S514_CARDS];
213:
214: LIST_HEAD(, sdlahw_card) sdlahw_card_head =
215: LIST_HEAD_INITIALIZER(sdlahw_card_head);
216: LIST_HEAD(, sdlahw) sdlahw_head =
217: LIST_HEAD_INITIALIZER(sdlahw_head);
218: LIST_HEAD(, sdla_hw_probe) sdlahw_probe_head =
219: LIST_HEAD_INITIALIZER(sdlahw_probe_head);
220: static sdla_hw_type_cnt_t sdla_adapter_cnt;
221:
222:
223:
224: /*
225: * PCI Device Driver Entry Points
226: */
227: int
228: san_match(struct device *parent, void *match, void *aux)
229: {
230: struct pci_attach_args* pa = aux;
231: u_int16_t vendor_id = PCI_VENDOR(pa->pa_id);
232: u_int16_t device_id = PCI_DEVICE(pa->pa_id);
233:
234: if ((vendor_id == SANGOMA_PCI_VENDOR ||
235: vendor_id == SANGOMA_PCI_VENDOR_OLD) &&
236: device_id == SANGOMA_PCI_DEVICE) {
237: return (1);
238: }
239: return (0);
240: }
241:
242: #define PCI_CBIO 0x10
243: void
244: san_attach(struct device *parent, struct device *self, void *aux)
245: {
246: struct pci_attach_args* pa = aux;
247: u_int16_t vendor_id = PCI_VENDOR(pa->pa_id);
248: u_int16_t subvendor_id = PCI_SUBVENDOR(pa);
249: int atype = 0x00;
250:
251: atype = PCI_PRODUCT(pci_conf_read(pa->pa_pc, pa->pa_tag,
252: PCI_SUBSYS_ID_REG));
253: switch (vendor_id) {
254: case SANGOMA_PCI_VENDOR_OLD:
255: case SANGOMA_PCI_VENDOR:
256: switch (subvendor_id) {
257: case A101_1TE1_SUBSYS_VENDOR:
258: atype = A101_ADPTR_1TE1;
259: break;
260: case A101_2TE1_SUBSYS_VENDOR:
261: atype = A101_ADPTR_2TE1;
262: break;
263: default:
264: return;
265: }
266: break;
267: default:
268: return;
269: }
270:
271: if (sdla_pci_probe(atype, pa)) {
272: printf(": PCI probe FAILED!\n");
273: return;
274: }
275:
276: #ifdef DEBUG
277: switch (PCI_VENDOR(pa->pa_id)) {
278: case V3_VENDOR_ID:
279: switch (atype) {
280: case S5141_ADPTR_1_CPU_SERIAL:
281: log(LOG_INFO, "%s: Sangoma S5141/FT1 (Single CPU) "
282: "adapter\n", self->dv_xname);
283: break;
284: case S5142_ADPTR_2_CPU_SERIAL:
285: log(LOG_INFO, "%s: Sangoma S5142 (Dual CPU) adapter\n",
286: self->dv_xname);
287: break;
288: case S5143_ADPTR_1_CPU_FT1:
289: log(LOG_INFO, "%s: Sangoma S5143 (Single CPU) "
290: "FT1 adapter\n", self->dv_xname);
291: break;
292: case S5144_ADPTR_1_CPU_T1E1:
293: case S5148_ADPTR_1_CPU_T1E1:
294: log(LOG_INFO, "%s: Sangoma S5144 (Single CPU) "
295: "T1/E1 adapter\n", self->dv_xname);
296: break;
297: case S5145_ADPTR_1_CPU_56K:
298: log(LOG_INFO, "%s: Sangoma S5145 (Single CPU) "
299: "56K adapter\n", self->dv_xname);
300: break;
301: case S5147_ADPTR_2_CPU_T1E1:
302: log(LOG_INFO, "%s: Sangoma S5147 (Dual CPU) "
303: "T1/E1 adapter\n", self->dv_xname);
304: break;
305: }
306: break;
307:
308: case SANGOMA_PCI_VENDOR_OLD:
309: switch (atype) {
310: case A101_ADPTR_1TE1:
311: log(LOG_INFO, "%s: Sangoma AFT (1 channel) "
312: "T1/E1 adapter\n", self->dv_xname);
313: break;
314: case A101_ADPTR_2TE1:
315: log(LOG_INFO, "%s: Sangoma AFT (2 channels) "
316: "T1/E1 adapter\n", self->dv_xname);
317: break;
318: }
319: break;
320: }
321: #endif
322: return;
323: }
324:
325: /*
326: * Module init point.
327: */
328: int
329: sdladrv_init(void)
330: {
331: int volatile i = 0;
332:
333: /* Initialize the PCI Card array, which
334: * will store flags, used to mark
335: * card initialization state */
336: for (i=0; i<MAX_S514_CARDS; i++)
337: pci_slot_ar[i] = 0xFF;
338:
339: bzero(&sdla_adapter_cnt, sizeof(sdla_hw_type_cnt_t));
340:
341: return (0);
342: }
343:
344: /*
345: * Module deinit point.
346: * o release all remaining system resources
347: */
348: int
349: sdladrv_exit(void)
350: {
351: #if 0
352: sdla_hw_probe_t *elm_hw_probe;
353: sdlahw_t *elm_hw;
354: sdlahw_card_t *elm_hw_card;
355:
356:
357: elm_hw = LIST_FIRST(&sdlahw_head);
358: while (elm_hw) {
359: sdlahw_t *tmp = elm_hw;
360: elm_hw = LIST_NEXT(elm_hw, next);
361: if (sdla_hw_unregister(tmp->hwcard, tmp->cpu_no) == EBUSY)
362: return EBUSY;
363: }
364: LIST_INIT(&sdlahw_head);
365:
366: elm_hw_card = LIST_FIRST(&sdlahw_card_head);
367: while (elm_hw_card) {
368: sdlahw_card_t *tmp = elm_hw_card;
369: elm_hw_card = LIST_NEXT(elm_hw_card, next);
370: if (sdla_card_unregister(tmp->hw_type,
371: tmp->slot_no,
372: tmp->bus_no,
373: tmp->ioport) == EBUSY)
374: return EBUSY;
375: }
376: LIST_INIT(&sdlahw_card_head);
377:
378: elm_hw_probe = LIST_FIRST(&sdlahw_probe_head);
379: while (elm_hw_probe) {
380: sdla_hw_probe_t *tmp = elm_hw_probe;
381: elm_hw_probe = LIST_NEXT(elm_hw_probe, next);
382: if (tmp->used){
383: log(LOG_INFO, "HW probe info is in used (%s)\n",
384: elm_hw_probe->hw_info);
385: return EBUSY;
386: }
387: LIST_REMOVE(tmp, next);
388: free(tmp, M_DEVBUF);
389: }
390: #endif
391: return (0);
392: }
393:
394: static void
395: sdla_save_hw_probe(sdlahw_t *hw, int port)
396: {
397: sdla_hw_probe_t *tmp_hw_probe;
398:
399: tmp_hw_probe = malloc(sizeof(sdla_hw_probe_t), M_DEVBUF, M_NOWAIT);
400: if (tmp_hw_probe == NULL)
401: return;
402:
403: bzero(tmp_hw_probe, sizeof(sdla_hw_probe_t));
404:
405: snprintf(tmp_hw_probe->hw_info, sizeof(tmp_hw_probe->hw_info),
406: "%s : SLOT=%d : BUS=%d : IRQ=%d : CPU=%c : PORT=%s",
407: SDLA_ADPTR_DECODE(hw->hwcard->atype), hw->hwcard->slot_no,
408: hw->hwcard->bus_no, hw->irq, SDLA_GET_CPU(hw->cpu_no), "PRI");
409:
410: hw->hwprobe = tmp_hw_probe;
411: tmp_hw_probe->used++;
412: LIST_INSERT_HEAD(&sdlahw_probe_head, tmp_hw_probe, next);
413: }
414:
415: static sdlahw_t*
416: sdla_aft_hw_select(sdlahw_card_t *hwcard, int cpu_no,
417: int irq, struct pci_attach_args *pa)
418: {
419: sdlahw_t* hw = NULL;
420: int number_of_cards = 0;
421:
422: hwcard->type = SDLA_AFT;
423: switch (hwcard->atype) {
424: case A101_ADPTR_1TE1:
425: hw = sdla_hw_register(hwcard, cpu_no, irq, pa);
426: sdla_save_hw_probe(hw, 0);
427: number_of_cards += 1;
428: #ifdef DEBUG
429: log(LOG_INFO, "%s: %s T1/E1 card found (%s rev.%d), "
430: "cpu(s) 1, bus #%d, slot #%d, irq #%d\n", san_drvname,
431: SDLA_ADPTR_DECODE(hwcard->atype),
432: AFT_CORE_ID_DECODE(hwcard->core_id), hwcard->core_rev,
433: hwcard->bus_no, hwcard->slot_no, irq);
434: #endif /* DEBUG */
435: break;
436: case A101_ADPTR_2TE1:
437: hw = sdla_hw_register(hwcard, cpu_no, irq, pa);
438: sdla_save_hw_probe(hw, 0);
439: number_of_cards += 1;
440: #ifdef DEBUG
441: log(LOG_INFO, "%s: %s T1/E1 card found (%s rev.%d), "
442: "cpu(s) 2, bus #%d, slot #%d, irq #%d\n", san_drvname,
443: SDLA_ADPTR_DECODE(hwcard->atype),
444: AFT_CORE_ID_DECODE(hwcard->core_id), hwcard->core_rev,
445: hwcard->bus_no, hwcard->slot_no, irq);
446: #endif /* DEBUG */
447: break;
448: case A105_ADPTR_1_CHN_T3E3:
449:
450: hw = sdla_hw_register(hwcard, cpu_no, irq, pa);
451: sdla_save_hw_probe(hw, 0);
452: number_of_cards += 1;
453: #ifdef DEBUG
454: log(LOG_INFO, "%s: %s T3/E3 card found, cpu(s) 1,"
455: "bus #%d, slot #%d, irq #%d\n", san_drvname,
456: SDLA_ADPTR_DECODE(hwcard->atype),
457: hwcard->bus_no, hwcard->slot_no, irq);
458: #endif /* DEBUG */
459: break;
460: default:
461: log(LOG_INFO, "%s: Unknown adapter %04X "
462: "(bus #%d, slot #%d, irq #%d)!\n", san_drvname,
463: hwcard->atype, hwcard->bus_no, hwcard->slot_no, irq);
464: break;
465: }
466:
467: return (hw);
468: }
469:
470:
471: static int
472: sdla_pci_probe(int atype, struct pci_attach_args *pa)
473: {
474: sdlahw_card_t* hwcard;
475: sdlahw_t* hw;
476: /*sdladev_t* dev = NULL;*/
477: int dual_cpu = 0;
478: int bus, slot, cpu = SDLA_CPU_A;
479: u_int16_t vendor_id, subvendor_id, device_id;
480: u_int8_t irq;
481: pci_intr_handle_t ih;
482: const char* intrstr = NULL;
483:
484: bus = pa->pa_bus;
485: slot = pa->pa_device;
486: vendor_id = PCI_VENDOR(pa->pa_id);
487: subvendor_id = PCI_SUBVENDOR(pa);
488: device_id = PCI_DEVICE(pa->pa_id);
489: irq = (u_int8_t)pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_INTLINE);
490:
491: /* Map and establish the interrupt */
492: if (pci_intr_map(pa, &ih)) {
493: printf(": couldn't map interrupt\n");
494: return (EINVAL);
495: }
496: intrstr = pci_intr_string(pa->pa_pc, ih);
497: if (intrstr != NULL)
498: printf(" %s\n", intrstr);
499:
500: Sangoma_cards_no ++;
501: reg_new_card:
502: Sangoma_PCI_cards_no ++;
503: hwcard = sdla_card_register(atype, slot, bus);
504: if (hwcard == NULL)
505: return (EINVAL);
506:
507: hwcard->memt = pa->pa_memt;
508: hwcard->ih = ih;
509: hwcard->pa = *pa;
510: /* Increment number of available Sangoma devices */
511: Sangoma_devices_no ++;
512: switch (atype) {
513: case A101_ADPTR_1TE1:
514: case A101_ADPTR_2TE1:
515: hw = sdla_aft_hw_select(hwcard, cpu, irq, pa);
516: sdla_adapter_cnt.AFT_adapters++;
517: if (atype == A101_ADPTR_2TE1)
518: dual_cpu = 1;
519: break;
520:
521: }
522:
523: if (hw == NULL)
524: return (EINVAL);
525: if (san_dev_attach(hw, hw->devname, sizeof(hw->devname)))
526: return (EINVAL);
527:
528: hw->used++;
529:
530: if (dual_cpu && cpu == SDLA_CPU_A) {
531: cpu = SDLA_CPU_B;
532: goto reg_new_card;
533: }
534:
535: return (0);
536: }
537:
538: int
539: sdla_intr_establish(void *phw, int (*intr_func)(void*), void* intr_arg)
540: {
541: sdlahw_t *hw = (sdlahw_t*)phw;
542: sdlahw_card_t *hwcard;
543:
544: WAN_ASSERT(hw == NULL);
545: hwcard = hw->hwcard;
546: if (pci_intr_establish(hwcard->pa.pa_pc, hwcard->ih, IPL_NET,
547: intr_func, intr_arg, "san") == NULL)
548: return (EINVAL);
549:
550: return 0;
551: }
552:
553: int
554: sdla_intr_disestablish(void *phw)
555: {
556: sdlahw_t *hw = (sdlahw_t*)phw;
557:
558: log(LOG_INFO, "%s: Disestablish interrupt is not defined!\n",
559: hw->devname);
560: return (EINVAL);
561: }
562:
563: int
564: sdla_get_hw_devices(void)
565: {
566: return (Sangoma_devices_no);
567: }
568:
569: void*
570: sdla_get_hw_adptr_cnt(void)
571: {
572: return (&sdla_adapter_cnt);
573: }
574:
575: static sdlahw_card_t*
576: sdla_card_register(u_int16_t atype, int slot_no, int bus_no)
577: {
578: sdlahw_card_t *new_hwcard, *last_hwcard;
579:
580: new_hwcard = sdla_card_search(atype, slot_no, bus_no);
581: if (new_hwcard)
582: return (new_hwcard);
583:
584: new_hwcard = malloc(sizeof(sdlahw_card_t), M_DEVBUF, M_NOWAIT);
585: if (!new_hwcard)
586: return (NULL);
587:
588: bzero(new_hwcard, sizeof(sdlahw_card_t));
589:
590: new_hwcard->atype = atype;
591: new_hwcard->slot_no = slot_no;
592: new_hwcard->bus_no = bus_no;
593:
594: if (LIST_EMPTY(&sdlahw_card_head)) {
595: /* Initialize SAN HW parameters */
596: sdladrv_init();
597: }
598: LIST_FOREACH(last_hwcard, &sdlahw_card_head, next) {
599: if (!LIST_NEXT(last_hwcard, next))
600: break;
601: }
602:
603: if (last_hwcard)
604: LIST_INSERT_AFTER(last_hwcard, new_hwcard, next);
605: else
606: LIST_INSERT_HEAD(&sdlahw_card_head, new_hwcard, next);
607:
608: return (new_hwcard);
609: }
610:
611: #if 0
612: static int
613: sdla_card_unregister(u_int16_t atype, int slot_no, int bus_no, int ioport)
614: {
615: sdlahw_card_t* tmp_card;
616:
617: LIST_FOREACH(tmp_card, &sdlahw_card_head, next){
618: if (tmp_card->atype != atype){
619: continue;
620: }
621: if (tmp_card->slot_no == slot_no &&
622: tmp_card->bus_no == bus_no){
623: break;
624: }
625: }
626: if (tmp_card == NULL){
627: log(LOG_INFO,
628: "Error: Card didn't find %04X card (slot=%d, bus=%d)\n"
629: atype, slot_no, bus_no);
630: return (EFAULT)
631: }
632: if (tmp_card->used){
633: log(LOG_INFO,
634: "Error: Card is still in used (slot=%d,bus=%d,used=%d)\n",
635: slot_no, bus_no, tmp_card->used);
636: return (EBUSY);
637: }
638: LIST_REMOVE(tmp_card, next);
639: free(tmp_card, M_DEVBUF);
640: return 0;
641: }
642: #endif
643:
644: static sdlahw_card_t*
645: sdla_card_search(u_int16_t atype, int slot_no, int bus_no)
646: {
647: sdlahw_card_t* tmp_card;
648:
649: LIST_FOREACH(tmp_card, &sdlahw_card_head, next) {
650: if (tmp_card->atype != atype)
651: continue;
652:
653: if (tmp_card->slot_no == slot_no &&
654: tmp_card->bus_no == bus_no)
655: return (tmp_card);
656: }
657: return (NULL);
658: }
659:
660: static sdlahw_t*
661: sdla_hw_register(sdlahw_card_t *card, int cpu_no, int irq, void *dev)
662: {
663: sdlahw_t *new_hw, *last_hw;
664:
665: new_hw = sdla_hw_search(card->atype, card->slot_no,
666: card->bus_no, cpu_no);
667: if (new_hw)
668: return (new_hw);
669:
670: new_hw = malloc(sizeof(sdlahw_t), M_DEVBUF, M_NOWAIT);
671: if (!new_hw)
672: return (NULL);
673:
674: bzero(new_hw, sizeof(sdlahw_t));
675:
676: new_hw->cpu_no = cpu_no;
677: new_hw->irq = irq;
678: new_hw->hwcard = card;
679: #if 0
680: new_hw->dev = dev;
681: #endif
682: new_hw->magic = SDLAHW_MAGIC;
683: card->used++;
684:
685: LIST_FOREACH(last_hw, &sdlahw_head, next) {
686: if (!LIST_NEXT(last_hw, next))
687: break;
688: }
689: if (last_hw)
690: LIST_INSERT_AFTER(last_hw, new_hw, next);
691: else
692: LIST_INSERT_HEAD(&sdlahw_head, new_hw, next);
693:
694: return (new_hw);
695: }
696:
697: #if 0
698: static int
699: sdla_hw_unregister(sdlahw_card_t* hwcard, int cpu_no)
700: {
701: sdlahw_t* tmp_hw;
702: int i;
703:
704: LIST_FOREACH(tmp_hw, &sdlahw_head, next) {
705: if (tmp_hw->hwcard != hwcard)
706: continue;
707:
708: if (tmp_hw->cpu_no == cpu_no)
709: break;
710: }
711:
712: if (tmp_hw == NULL) {
713: log(LOG_INFO,
714: "Error: Failed to find device (slot=%d,bus=%d,cpu=%c)\n",
715: hwcard->slot_no, hwcard->bus_no, SDLA_GET_CPU(cpu_no));
716: return (EFAULT);
717: }
718: if (tmp_hw->used) {
719: log(LOG_INFO,
720: "Error: Device is still in used (slot=%d,bus=%d,cpu=%c,%d)\n",
721: hwcard->slot_no,
722: hwcard->bus_no,
723: SDLA_GET_CPU(cpu_no),
724: hwcard->used);
725: return (EBUSY);
726: }
727:
728: tmp_hw->hwprobe = NULL;
729: tmp_hw->hwcard = NULL;
730: hwcard->used--; /* Decrement card usage */
731: LIST_REMOVE(tmp_hw, next);
732: free(tmp_hw, M_DEVBUF);
733:
734: return (0);
735: }
736: #endif
737:
738: static sdlahw_t*
739: sdla_hw_search(u_int16_t atype, int slot_no, int bus_no, int cpu_no)
740: {
741: sdlahw_t* tmp_hw;
742:
743:
744: LIST_FOREACH(tmp_hw, &sdlahw_head, next) {
745: if (tmp_hw->hwcard == NULL) {
746: log(LOG_INFO,
747: "Critical Error: sdla_cpu_search: line %d\n",
748: __LINE__);
749: // XXX REMOVE in LIST_FOREACH
750: LIST_REMOVE(tmp_hw, next);
751: continue;
752: }
753: if (tmp_hw->hwcard->atype != atype) {
754: // XXX why ???
755: LIST_REMOVE(tmp_hw, next);
756: continue;
757: }
758: if (tmp_hw->hwcard->slot_no == slot_no &&
759: tmp_hw->hwcard->bus_no == bus_no &&
760: tmp_hw->cpu_no == cpu_no)
761: return (tmp_hw);
762: }
763:
764: return (NULL);
765: }
766:
767:
768: /*
769: * Set up adapter.
770: * o detect adapter type
771: * o set up adapter shared memory
772: * Return: 0 ok.
773: * < 0 error
774: */
775:
776: int
777: sdla_setup(void *phw)
778: {
779: sdlahw_card_t* hwcard = NULL;
780: sdlahw_t* hw = (sdlahw_t*)phw;
781: int err=0;
782:
783: WAN_ASSERT(hw == NULL);
784: SDLA_MAGIC(hw);
785: WAN_ASSERT(hw->hwcard == NULL);
786: hwcard = hw->hwcard;
787: switch (hwcard->type) {
788: case SDLA_AFT:
789: break;
790:
791: default:
792: log(LOG_INFO, "%s: Invalid card type %x\n",
793: hw->devname, hw->hwcard->type);
794: return (EINVAL);
795: }
796:
797: hw->dpmsize = SDLA_WINDOWSIZE;
798:
799: err = sdla_detect(hw);
800: return (err);
801: }
802:
803:
804: /*
805: * Shut down SDLA: disable shared memory access and interrupts, stop CPU, etc.
806: */
807: int
808: sdla_down(void *phw)
809: {
810: sdlahw_card_t* card = NULL;
811: sdlahw_t* hw = (sdlahw_t*)phw;
812:
813: WAN_ASSERT(hw == NULL);
814: SDLA_MAGIC(hw);
815: WAN_ASSERT(hw->hwcard == NULL);
816: card = hw->hwcard;
817: switch (card->type) {
818: case SDLA_AFT:
819: /* free up the allocated virtual memory */
820: if (hw->status & SDLA_MEM_MAPPED) {
821: bus_space_unmap(hw->hwcard->memt,
822: hw->dpmbase,
823: XILINX_PCI_MEM_SIZE);
824: hw->status &= ~SDLA_MEM_MAPPED;
825: }
826: break;
827:
828: default:
829: return (EINVAL);
830: }
831: return (0);
832: }
833:
834: /*
835: * Read the hardware interrupt status.
836: */
837: int
838: sdla_read_int_stat(void *phw, u_int32_t *int_status)
839: {
840: sdlahw_card_t* card = NULL;
841: sdlahw_t* hw = (sdlahw_t*)phw;
842:
843: WAN_ASSERT(hw == NULL);
844: SDLA_MAGIC(hw);
845: WAN_ASSERT(hw->hwcard == NULL);
846: card = hw->hwcard;
847: switch (card->type) {
848: case SDLA_AFT:
849: sdla_pci_read_config_dword(hw, PCI_INT_STATUS, int_status);
850: }
851: return (0);
852: }
853:
854:
855: /*
856: * Generate an interrupt to adapter's CPU.
857: */
858: int
859: sdla_cmd(void *phw, unsigned long offset, wan_mbox_t *mbox)
860: {
861: sdlahw_t *hw = (sdlahw_t*)phw;
862: int len = sizeof(wan_cmd_t);
863: int err = 0;
864: u_int8_t value;
865:
866: SDLA_MAGIC(hw);
867: len += mbox->wan_data_len;
868:
869: sdla_peek(hw, offset, (void*)&value, 1);
870: if (value != 0x00) {
871: log(LOG_INFO, "%s: opp flag set on entry to sdla_exec!\n",
872: hw->devname);
873: return (0);
874: }
875: mbox->wan_opp_flag = 0x00;
876: sdla_poke(hw, offset, (void*)mbox, len);
877:
878: err = sdla_exec(hw, offset);
879: if (!err) {
880: log(LOG_INFO, "%s: Command 0x%02X failed!\n",
881: hw->devname, mbox->wan_command);
882: return (WAN_CMD_TIMEOUT);
883: }
884: sdla_peek(hw, offset, (void*)mbox, sizeof(wan_cmd_t));
885: if (mbox->wan_data_len) {
886: sdla_peek(hw, offset+offsetof(wan_mbox_t, wan_data),
887: mbox->wan_data, mbox->wan_data_len);
888: }
889:
890: return (mbox->wan_return_code);
891: }
892:
893: /*
894: * Execute Adapter Command.
895: * o Set exec flag.
896: * o Busy-wait until flag is reset.
897: * o Return number of loops made, or 0 if command timed out.
898: */
899: static int
900: sdla_exec(sdlahw_t *hw, unsigned long offset)
901: {
902: volatile unsigned long tstop;
903: volatile unsigned long nloops;
904: u_int8_t value;
905:
906: value = 0x01;
907: sdla_poke(hw, offset, (void*)&value, 1);
908: tstop = ticks + EXEC_TIMEOUT;
909:
910: sdla_peek(hw, offset, (void*)&value, 1);
911: for (nloops = 1; value == 0x01; ++ nloops) {
912: DELAY(EXEC_DELAY);
913: if (ticks > tstop || nloops > MAX_NLOOPS) {
914: log(LOG_INFO, "%s: Timeout %lu ticks (max=%lu) "
915: "loops %lu (max=%u)\n", hw->devname,
916: (ticks-tstop+EXEC_TIMEOUT),
917: (unsigned long)EXEC_TIMEOUT, nloops, MAX_NLOOPS);
918: return (0); /* time is up! */
919: }
920: sdla_peek(hw, offset, (void*)&value, 1);
921: }
922:
923: return (nloops);
924: }
925:
926:
927: /*
928: * Read absolute adapter memory.
929: * Transfer data from adapter's memory to data buffer.
930: *
931: * Note:
932: * Care should be taken when crossing dual-port memory window boundary.
933: * This function is not atomic, so caller must disable interrupt if
934: * interrupt routines are accessing adapter shared memory.
935: */
936: int
937: sdla_peek(void *phw, unsigned long addr, void *buf, unsigned len)
938: {
939: sdlahw_card_t* card = NULL;
940: sdlahw_t* hw = (sdlahw_t*)phw;
941: int err = 0;
942:
943: WAN_ASSERT(hw == NULL);
944: SDLA_MAGIC(hw);
945: WAN_ASSERT(hw->hwcard == NULL);
946: card = hw->hwcard;
947: if (addr + len > hw->memory) /* verify arguments */
948: return (EINVAL);
949:
950: switch (card->type) {
951: case SDLA_AFT:
952: sdla_peek_by_4(hw, addr, buf, len);
953: break;
954:
955: default:
956: log(LOG_INFO, "%s: Invalid card type 0x%X\n",
957: __FUNCTION__,card->type);
958: err = (EINVAL);
959: break;
960: }
961: return (err);
962: }
963:
964:
965: /*
966: * Read data from adapter's memory to a data buffer in 4-byte chunks.
967: * Note that we ensure that the SDLA memory address is on a 4-byte boundary
968: * before we begin moving the data in 4-byte chunks.
969: */
970: static void
971: sdla_peek_by_4(sdlahw_t *hw, unsigned long offset, void *buf, unsigned int len)
972: {
973: /* byte copy data until we get to a 4-byte boundary */
974: while (len && (offset & 0x03)) {
975: sdla_bus_read_1(hw, offset++, (u_int8_t*)buf);
976: ((u_int8_t *)buf)++;
977: len--;
978: }
979:
980: /* copy data in 4-byte chunks */
981: while (len >= 4) {
982: sdla_bus_read_4(hw, offset, (u_int32_t*)buf);
983: (u_int8_t*)buf += 4;
984: offset += 4;
985: len -= 4;
986: }
987:
988: /* byte copy any remaining data */
989: while (len) {
990: sdla_bus_read_1(hw, offset++, (u_int8_t*)buf);
991: ((u_int8_t *)buf)++;
992: len--;
993: }
994: }
995:
996: /*
997: * Write Absolute Adapter Memory.
998: * Transfer data from data buffer to adapter's memory.
999: *
1000: * Note:
1001: * Care should be taken when crossing dual-port memory window boundary.
1002: * This function is not atomic, so caller must disable interrupt if
1003: * interrupt routines are accessing adapter shared memory.
1004: */
1005: int
1006: sdla_poke(void *phw, unsigned long addr, void *buf, unsigned len)
1007: {
1008: sdlahw_card_t* card = NULL;
1009: sdlahw_t* hw = (sdlahw_t*)phw;
1010: int err = 0;
1011:
1012: WAN_ASSERT(hw == NULL);
1013: SDLA_MAGIC(hw);
1014: WAN_ASSERT(hw->hwcard == NULL);
1015: card = hw->hwcard;
1016: if (addr + len > hw->memory) { /* verify arguments */
1017: return (EINVAL);
1018: }
1019:
1020: switch (card->type) {
1021: case SDLA_AFT:
1022: sdla_poke_by_4(hw, addr, buf, len);
1023: break;
1024:
1025: default:
1026: log(LOG_INFO, "%s: Invalid card type 0x%X\n",
1027: __FUNCTION__,card->type);
1028: err = (EINVAL);
1029: break;
1030: }
1031: return (err);
1032: }
1033:
1034:
1035: /*
1036: * Write from a data buffer to adapter's memory in 4-byte chunks.
1037: * Note that we ensure that the SDLA memory address is on a 4-byte boundary
1038: * before we begin moving the data in 4-byte chunks.
1039: */
1040: static void
1041: sdla_poke_by_4(sdlahw_t *hw, unsigned long offset, void *buf, unsigned int len)
1042: {
1043: /* byte copy data until we get to a 4-byte boundary */
1044: while (len && (offset & 0x03)) {
1045: sdla_bus_write_1(hw, offset++, *(char *)buf);
1046: ((char *)buf) ++;
1047: len --;
1048: }
1049:
1050: /* copy data in 4-byte chunks */
1051: while (len >= 4) {
1052: sdla_bus_write_4(hw, offset, *(unsigned long *)buf);
1053: offset += 4;
1054: (char*)buf += 4;
1055: len -= 4;
1056: }
1057:
1058: /* byte copy any remaining data */
1059: while (len) {
1060: sdla_bus_write_1(hw, offset++, *(char *)buf);
1061: ((char *)buf) ++;
1062: len --;
1063: }
1064: }
1065:
1066: int
1067: sdla_poke_byte(void *phw, unsigned long offset, u_int8_t value)
1068: {
1069: sdlahw_t *hw = (sdlahw_t*)phw;
1070:
1071: SDLA_MAGIC(hw);
1072: /* Sangoma ISA card sdla_bus_write_1(hw, offset, value); */
1073: sdla_poke(hw, offset, (void*)&value, 1);
1074: return (0);
1075: }
1076:
1077: int
1078: sdla_set_bit(void *phw, unsigned long offset, u_int8_t value)
1079: {
1080: sdlahw_t *hw = (sdlahw_t*)phw;
1081: u_int8_t tmp;
1082:
1083: SDLA_MAGIC(hw);
1084: /* Sangoma ISA card -> sdla_bus_read_1(hw, offset, &tmp); */
1085: sdla_peek(hw, offset, (void*)&tmp, 1);
1086: tmp |= value;
1087: /* Sangoma ISA card -> sdla_bus_write_1(hw, offset, tmp); */
1088: sdla_poke(hw, offset, (void*)&tmp, 1);
1089: return (0);
1090: }
1091:
1092: int
1093: sdla_clear_bit(void *phw, unsigned long offset, u_int8_t value)
1094: {
1095: sdlahw_t *hw = (sdlahw_t*)phw;
1096: u_int8_t tmp;
1097:
1098: SDLA_MAGIC(hw);
1099: /* Sangoma ISA card -> sdla_bus_read_1(hw, offset, &tmp); */
1100: sdla_peek(hw, offset, (void*)&tmp, 1);
1101: tmp &= ~value;
1102: /* Sangoma ISA card -> sdla_bus_write_1(hw, offset, tmp); */
1103: sdla_poke(hw, offset, (void*)&tmp, 1);
1104: return (0);
1105: }
1106:
1107: /*
1108: * Find the AFT HDLC PCI adapter in the PCI bus.
1109: * Return the number of AFT adapters found (0 if no adapter found).
1110: */
1111: static int
1112: sdla_detect_aft(sdlahw_t *hw)
1113: {
1114: sdlahw_card_t *card;
1115: u_int16_t ut_u16;
1116:
1117: WAN_ASSERT(hw == NULL);
1118: WAN_ASSERT(hw->hwcard == NULL);
1119: card = hw->hwcard;
1120: sdla_pci_read_config_dword(hw,
1121: (hw->cpu_no == SDLA_CPU_A) ? PCI_IO_BASE_DWORD :
1122: PCI_MEM_BASE0_DWORD, (u_int32_t*)&hw->mem_base_addr);
1123: if (!hw->mem_base_addr) {
1124: if (hw->cpu_no == SDLA_CPU_B) {
1125: printf("%s: No PCI memory allocated for CPU #B\n",
1126: hw->devname);
1127: } else {
1128: printf("%s: No PCI memory allocated to card\n",
1129: hw->devname);
1130: }
1131: return (EINVAL);
1132: }
1133: #ifdef DEBUG
1134: log(LOG_INFO, "%s: AFT PCI memory at 0x%lX\n",
1135: hw->devname, (unsigned long)hw->mem_base_addr);
1136: #endif /* DEBUG */
1137: sdla_pci_read_config_byte(hw, PCI_INTLINE, (u_int8_t*)&hw->irq);
1138: if (hw->irq == PCI_IRQ_NOT_ALLOCATED) {
1139: printf("%s: IRQ not allocated to AFT adapter\n", hw->devname);
1140: return (EINVAL);
1141: }
1142:
1143: #ifdef DEBUG
1144: log(LOG_INFO, "%s: IRQ %d allocated to the AFT PCI card\n",
1145: hw->devname, hw->irq);
1146: #endif /* DEBUG */
1147:
1148: hw->memory=XILINX_PCI_MEM_SIZE;
1149:
1150: /* Map the physical PCI memory to virtual memory */
1151: bus_space_map(hw->hwcard->memt, hw->mem_base_addr, XILINX_PCI_MEM_SIZE,
1152: 0, &hw->dpmbase);
1153: if (!hw->dpmbase) {
1154: printf("%s: couldn't map memory\n", hw->devname);
1155: return (EINVAL);
1156: }
1157: hw->status |= SDLA_MEM_MAPPED;
1158:
1159:
1160: /* Enable master operation on PCI and enable bar0 memory */
1161: sdla_pci_read_config_word(hw, XILINX_PCI_CMD_REG, &ut_u16);
1162: ut_u16 |=0x06;
1163: sdla_pci_write_config_word(hw, XILINX_PCI_CMD_REG, ut_u16);
1164:
1165: /* Set PCI Latency of 0xFF*/
1166: sdla_pci_write_config_dword(hw, XILINX_PCI_LATENCY_REG,
1167: XILINX_PCI_LATENCY);
1168:
1169: return (0);
1170: }
1171:
1172:
1173: /*
1174: * Detect adapter type.
1175: */
1176: static int
1177: sdla_detect(sdlahw_t *hw)
1178: {
1179: sdlahw_card_t *card = NULL;
1180: int err = 0;
1181:
1182: WAN_ASSERT(hw == NULL);
1183: WAN_ASSERT(hw->hwcard == NULL);
1184: card = hw->hwcard;
1185: switch (card->type) {
1186: case SDLA_AFT:
1187: err = sdla_detect_aft(hw);
1188: break;
1189: }
1190: if (err)
1191: sdla_down(hw);
1192:
1193: return (err);
1194: }
1195:
1196: int
1197: sdla_is_te1(void *phw)
1198: {
1199: sdlahw_card_t *hwcard = NULL;
1200: sdlahw_t *hw = (sdlahw_t*)phw;
1201:
1202: WAN_ASSERT(hw == NULL);
1203: SDLA_MAGIC(hw);
1204: WAN_ASSERT(hw->hwcard == NULL);
1205: hwcard = hw->hwcard;
1206: switch (hwcard->atype) {
1207: case S5144_ADPTR_1_CPU_T1E1:
1208: case S5147_ADPTR_2_CPU_T1E1:
1209: case S5148_ADPTR_1_CPU_T1E1:
1210: case A101_ADPTR_1TE1:
1211: case A101_ADPTR_2TE1:
1212: return (1);
1213: }
1214: return (0);
1215: }
1216:
1217: int
1218: sdla_check_mismatch(void *phw, unsigned char media)
1219: {
1220: sdlahw_card_t *hwcard = NULL;
1221: sdlahw_t *hw = (sdlahw_t*)phw;
1222:
1223: WAN_ASSERT(hw == NULL);
1224: SDLA_MAGIC(hw);
1225: WAN_ASSERT(hw->hwcard == NULL);
1226: hwcard = hw->hwcard;
1227: if (media == WAN_MEDIA_T1 ||
1228: media == WAN_MEDIA_E1) {
1229: if (hwcard->atype != S5144_ADPTR_1_CPU_T1E1 &&
1230: hwcard->atype != S5147_ADPTR_2_CPU_T1E1 &&
1231: hwcard->atype != S5148_ADPTR_1_CPU_T1E1) {
1232: log(LOG_INFO, "%s: Error: Card type mismatch: "
1233: "User=T1/E1 Actual=%s\n", hw->devname,
1234: SDLA_ADPTR_DECODE(hwcard->atype));
1235: return (EIO);
1236: }
1237: hwcard->atype = S5144_ADPTR_1_CPU_T1E1;
1238:
1239: } else if (media == WAN_MEDIA_56K) {
1240: if (hwcard->atype != S5145_ADPTR_1_CPU_56K) {
1241: log(LOG_INFO, "%s: Error: Card type mismatch: "
1242: "User=56K Actual=%s\n", hw->devname,
1243: SDLA_ADPTR_DECODE(hwcard->atype));
1244: return (EIO);
1245: }
1246: } else {
1247: if (hwcard->atype == S5145_ADPTR_1_CPU_56K ||
1248: hwcard->atype == S5144_ADPTR_1_CPU_T1E1 ||
1249: hwcard->atype == S5147_ADPTR_2_CPU_T1E1 ||
1250: hwcard->atype == S5148_ADPTR_1_CPU_T1E1) {
1251: log(LOG_INFO, "%s: Error: Card type mismatch: "
1252: "User=S514(1/2/3) Actual=%s\n", hw->devname,
1253: SDLA_ADPTR_DECODE(hwcard->atype));
1254: return (EIO);
1255: }
1256: }
1257:
1258: return (0);
1259: }
1260:
1261: int
1262: sdla_getcfg(void *phw, int type, void *value)
1263: {
1264: sdlahw_t* hw = (sdlahw_t*)phw;
1265: sdlahw_card_t *hwcard;
1266:
1267: WAN_ASSERT(hw == NULL);
1268: SDLA_MAGIC(hw);
1269: WAN_ASSERT(hw->hwcard == NULL);
1270: hwcard = hw->hwcard;
1271: switch (type) {
1272: case SDLA_CARDTYPE:
1273: *(u_int16_t*)value = hwcard->type;
1274: break;
1275: case SDLA_MEMBASE:
1276: *(bus_space_handle_t*)value = hw->dpmbase;
1277: break;
1278: case SDLA_MEMEND:
1279: *(u_int32_t*)value = ((unsigned long)hw->dpmbase +
1280: hw->dpmsize - 1);
1281: break;
1282: case SDLA_MEMSIZE:
1283: *(u_int16_t*)value = hw->dpmsize;
1284: break;
1285: case SDLA_MEMORY:
1286: *(u_int32_t*)value = hw->memory;
1287: break;
1288: case SDLA_IRQ:
1289: *(u_int16_t*)value = hw->irq;
1290: break;
1291: case SDLA_ADAPTERTYPE:
1292: *(u_int16_t*)value = hwcard->atype;
1293: break;
1294: case SDLA_CPU:
1295: *(u_int16_t*)value = hw->cpu_no;
1296: break;
1297: case SDLA_SLOT:
1298: *(u_int16_t*)value = hwcard->slot_no;
1299: break;
1300: case SDLA_BUS:
1301: *(u_int16_t*)value = hwcard->bus_no;
1302: break;
1303: case SDLA_DMATAG:
1304: *(bus_dma_tag_t*)value = hwcard->pa.pa_dmat;
1305: break;
1306: case SDLA_PCIEXTRAVER:
1307: *(u_int8_t*)value = hwcard->pci_extra_ver;
1308: break;
1309: case SDLA_BASEADDR:
1310: *(u_int32_t*)value = hw->mem_base_addr;
1311: break;
1312: }
1313: return (0);
1314: }
1315:
1316:
1317: int
1318: sdla_get_hwcard(void *phw, void **phwcard)
1319: {
1320: sdlahw_t *hw = (sdlahw_t*)phw;
1321:
1322: WAN_ASSERT(hw == NULL);
1323: SDLA_MAGIC(hw);
1324:
1325: *phwcard = hw->hwcard;
1326: return (0);
1327: }
1328:
1329:
1330: int
1331: sdla_get_hwprobe(void *phw, void **str)
1332: {
1333: sdlahw_t *hw = (sdlahw_t*)phw;
1334:
1335: WAN_ASSERT(hw == NULL);
1336: SDLA_MAGIC(hw);
1337:
1338: if (hw->hwprobe)
1339: *str = hw->hwprobe->hw_info;
1340:
1341: return (0);
1342: }
1343:
1344: int
1345: sdla_bus_write_1(void *phw, unsigned int offset, u_int8_t value)
1346: {
1347: sdlahw_t *hw = (sdlahw_t*)phw;
1348:
1349: WAN_ASSERT(hw == NULL);
1350: SDLA_MAGIC(hw);
1351: if (!(hw->status & SDLA_MEM_MAPPED))
1352: return (0);
1353: bus_space_write_1(hw->hwcard->memt, hw->dpmbase, offset, value);
1354: return (0);
1355: }
1356:
1357: int
1358: sdla_bus_write_2(void *phw, unsigned int offset, u_int16_t value)
1359: {
1360: sdlahw_t *hw = (sdlahw_t*)phw;
1361:
1362: WAN_ASSERT(hw == NULL);
1363: SDLA_MAGIC(hw);
1364: if (!(hw->status & SDLA_MEM_MAPPED))
1365: return (0);
1366: bus_space_write_2(hw->hwcard->memt, hw->dpmbase, offset, value);
1367: return (0);
1368: }
1369:
1370: int
1371: sdla_bus_write_4(void *phw, unsigned int offset, u_int32_t value)
1372: {
1373: sdlahw_t *hw = (sdlahw_t*)phw;
1374:
1375: WAN_ASSERT(hw == NULL);
1376: SDLA_MAGIC(hw);
1377: if (!(hw->status & SDLA_MEM_MAPPED))
1378: return (0);
1379: bus_space_write_4(hw->hwcard->memt, hw->dpmbase, offset, value);
1380: return (0);
1381: }
1382:
1383: int
1384: sdla_bus_read_1(void *phw, unsigned int offset, u_int8_t *value)
1385: {
1386: sdlahw_t *hw = (sdlahw_t*)phw;
1387:
1388: WAN_ASSERT2(hw == NULL, 0);
1389: SDLA_MAGIC(hw);
1390: if (!(hw->status & SDLA_MEM_MAPPED))
1391: return (0);
1392: *value = bus_space_read_1(hw->hwcard->memt, hw->dpmbase, offset);
1393: return (0);
1394: }
1395:
1396: int
1397: sdla_bus_read_2(void *phw, unsigned int offset, u_int16_t *value)
1398: {
1399: sdlahw_t *hw = (sdlahw_t*)phw;
1400:
1401: WAN_ASSERT2(hw == NULL, 0);
1402: SDLA_MAGIC(hw);
1403: if (!(hw->status & SDLA_MEM_MAPPED))
1404: return (0);
1405: *value = bus_space_read_2(hw->hwcard->memt, hw->dpmbase, offset);
1406: return (0);
1407: }
1408:
1409: int
1410: sdla_bus_read_4(void *phw, unsigned int offset, u_int32_t *value)
1411: {
1412: sdlahw_t *hw = (sdlahw_t*)phw;
1413:
1414: WAN_ASSERT2(hw == NULL, 0);
1415: WAN_ASSERT2(hw->dpmbase == 0, 0);
1416: SDLA_MAGIC(hw);
1417: if (!(hw->status & SDLA_MEM_MAPPED))
1418: return (0);
1419: *value = bus_space_read_4(hw->hwcard->memt, hw->dpmbase, offset);
1420: return (0);
1421: }
1422:
1423: static int
1424: sdla_pci_read_config_dword(void *phw, int reg, u_int32_t *value)
1425: {
1426: sdlahw_t *hw = (sdlahw_t*)phw;
1427: sdlahw_card_t *hwcard;
1428:
1429: WAN_ASSERT(hw == NULL);
1430: SDLA_MAGIC(hw);
1431: WAN_ASSERT(hw->hwcard == NULL);
1432: hwcard = hw->hwcard;
1433: *value = pci_conf_read(hwcard->pa.pa_pc, hwcard->pa.pa_tag, reg);
1434: return (0);
1435: }
1436:
1437: static int
1438: sdla_pci_read_config_word(void *phw, int reg, u_int16_t *value)
1439: {
1440: sdlahw_t *hw = (sdlahw_t*)phw;
1441: sdlahw_card_t *hwcard;
1442: u_int32_t tmp = 0x00;
1443:
1444: WAN_ASSERT(hw == NULL);
1445: SDLA_MAGIC(hw);
1446: WAN_ASSERT(hw->hwcard == NULL);
1447: hwcard = hw->hwcard;
1448: tmp = pci_conf_read(hwcard->pa.pa_pc, hwcard->pa.pa_tag, reg);
1449: *value = (u_int16_t)((tmp >> 16) & 0xFFFF);
1450: return (0);
1451: }
1452:
1453: static int
1454: sdla_pci_read_config_byte(void *phw, int reg, u_int8_t *value)
1455: {
1456: sdlahw_t *hw = (sdlahw_t*)phw;
1457: sdlahw_card_t *hwcard;
1458: u_int32_t tmp = 0x00;
1459:
1460: WAN_ASSERT(hw == NULL);
1461: SDLA_MAGIC(hw);
1462: WAN_ASSERT(hw->hwcard == NULL);
1463: hwcard = hw->hwcard;
1464: tmp = pci_conf_read(hwcard->pa.pa_pc, hwcard->pa.pa_tag, reg);
1465: *value = (u_int8_t)(tmp & 0xFF);
1466: return (0);
1467: }
1468:
1469: static int
1470: sdla_pci_write_config_dword(void *phw, int reg, u_int32_t value)
1471: {
1472: sdlahw_t *hw = (sdlahw_t*)phw;
1473: sdlahw_card_t *card;
1474:
1475: WAN_ASSERT(hw == NULL);
1476: SDLA_MAGIC(hw);
1477: WAN_ASSERT(hw->hwcard == NULL);
1478: card = hw->hwcard;
1479: pci_conf_write(card->pa.pa_pc, card->pa.pa_tag, reg, value);
1480: return (0);
1481: }
1482:
1483: static int
1484: sdla_pci_write_config_word(void *phw, int reg, u_int16_t value)
1485: {
1486: sdlahw_t *hw = (sdlahw_t*)phw;
1487: sdlahw_card_t *card;
1488:
1489: WAN_ASSERT(hw == NULL);
1490: SDLA_MAGIC(hw);
1491: WAN_ASSERT(hw->hwcard == NULL);
1492: card = hw->hwcard;
1493: pci_conf_write(card->pa.pa_pc, card->pa.pa_tag, reg, value);
1494: return (0);
1495: }
CVSweb