Annotation of sys/arch/mvmeppc/pci/mpcpcibr.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: mpcpcibr.c,v 1.18 2006/12/14 17:36:12 kettenis Exp $ */
2:
3: /*
4: * Copyright (c) 2001 Steve Murphree, Jr.
5: *
6: * Redistribution and use in source and binary forms, with or without
7: * modification, are permitted provided that the following conditions
8: * are met:
9: * 1. Redistributions of source code must retain the above copyright
10: * notice, this list of conditions and the following disclaimer.
11: * 2. Redistributions in binary form must reproduce the above copyright
12: * notice, this list of conditions and the following disclaimer in the
13: * documentation and/or other materials provided with the distribution.
14: * 3. All advertising materials mentioning features or use of this software
15: * must display the following acknowledgement:
16: * This product includes software developed under OpenBSD for RTMX Inc
17: * by Per Fogelstrom, Opsycon AB.
18: * 4. The name of the author may not be used to endorse or promote products
19: * derived from this software without specific prior written permission.
20: *
21: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
22: * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24: * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
25: * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31: * SUCH DAMAGE.
32: *
33: */
34:
35: /*
36: * Motorola 'Raven' PCI BUS Bridge driver.
37: * specialized hooks for different config methods.
38: */
39:
40: #include <sys/param.h>
41: #include <sys/systm.h>
42: #include <sys/kernel.h>
43: #include <sys/malloc.h>
44: #include <sys/device.h>
45: #include <sys/proc.h>
46: #include <uvm/uvm_extern.h>
47:
48: #include <machine/autoconf.h>
49: #include <machine/bus.h>
50: #include <machine/pcb.h>
51:
52: #include <dev/pci/pcireg.h>
53: #include <dev/pci/pcivar.h>
54: #include <dev/pci/pcidevs.h>
55:
56: #include <mvmeppc/pci/pcibrvar.h>
57: #include <mvmeppc/dev/ravenreg.h>
58: #include <mvmeppc/dev/ravenvar.h>
59:
60: int mpcpcibrmatch(struct device *, void *, void *);
61: void mpcpcibrattach(struct device *, struct device *, void *);
62:
63: void mpc_attach_hook(struct device *, struct device *,
64: struct pcibus_attach_args *);
65: int mpc_bus_maxdevs(void *, int);
66: pcitag_t mpc_make_tag(void *, int, int, int);
67: void mpc_decompose_tag(void *, pcitag_t, int *, int *, int *);
68: pcireg_t mpc_conf_read(void *, pcitag_t, int);
69: void mpc_conf_write(void *, pcitag_t, int, pcireg_t);
70:
71: int mpc_intr_map(void *, pcitag_t, int, int, pci_intr_handle_t *);
72: const char *mpc_intr_string(void *, pci_intr_handle_t);
73: int mpc_intr_line(void *, pci_intr_handle_t);
74: void *mpc_intr_establish(void *, pci_intr_handle_t,
75: int, int (*)(void *), void *, char *);
76: void mpc_intr_disestablish(void *, void *);
77: int mpc_ether_hw_addr(struct ppc_pci_chipset *, u_int8_t *);
78:
79: void mpc_cfg_write_1(struct pcibr_config *, u_int32_t, u_int8_t);
80: void mpc_cfg_write_2(struct pcibr_config *, u_int32_t, u_int16_t);
81: void mpc_cfg_write_4(struct pcibr_config *, u_int32_t, u_int32_t);
82:
83: u_int8_t mpc_cfg_read_1(struct pcibr_config *, u_int32_t);
84: u_int16_t mpc_cfg_read_2(struct pcibr_config *, u_int32_t);
85: u_int32_t mpc_cfg_read_4(struct pcibr_config *, u_int32_t);
86:
87: u_int32_t pci_iack(void);
88: u_int32_t mpc_gen_config_reg(void *, pcitag_t, int);
89:
90: struct cfattach mpcpcibr_ca = {
91: sizeof(struct pcibr_softc), mpcpcibrmatch, mpcpcibrattach,
92: };
93:
94: struct cfdriver mpcpcibr_cd = {
95: NULL, "mpcpcibr", DV_DULL,
96: };
97:
98: int mpcpcibrprint(void *, const char *pnp);
99:
100: struct pcibr_config mpc_config;
101:
102: struct powerpc_bus_dma_tag pci_bus_dma_tag = {
103: NULL,
104: _bus_dmamap_create,
105: _bus_dmamap_destroy,
106: _bus_dmamap_load,
107: _bus_dmamap_load_mbuf,
108: _bus_dmamap_load_uio,
109: _bus_dmamap_load_raw,
110: _bus_dmamap_unload,
111: _bus_dmamap_sync,
112: _bus_dmamem_alloc,
113: _bus_dmamem_free,
114: _bus_dmamem_map,
115: _bus_dmamem_unmap,
116: _bus_dmamem_mmap
117: };
118:
119: extern u_int8_t *ravenregs;
120: extern vaddr_t isaspace_va;
121:
122: struct raven_setup {
123: unsigned int pci_reg;
124: u_int32_t value;
125: };
126:
127: const struct raven_setup raven_prep_setup[] = {
128: /* PCI registers */
129: { RAVEN_PCI_MEM, RAVEN_PCI_MEM_VAL },
130: { RAVEN_PCI_PSADD0, RAVEN_PCI_PSADD0_VAL },
131: { RAVEN_PCI_PSOFF0, RAVEN_PCI_PSOFF0_VAL },
132: { RAVEN_PCI_PSADD1, RAVEN_PCI_PSADD1_VAL },
133: { RAVEN_PCI_PSOFF1, RAVEN_PCI_PSOFF1_VAL },
134: { RAVEN_PCI_PSADD2, RAVEN_PCI_PSADD2_VAL },
135: { RAVEN_PCI_PSOFF2, RAVEN_PCI_PSOFF2_VAL },
136: { RAVEN_PCI_PSADD3, RAVEN_PCI_PSADD3_VAL },
137: { RAVEN_PCI_PSOFF3, RAVEN_PCI_PSOFF3_VAL },
138:
139: #ifdef notyet
140: /* Universe PCI registers */
141: { 0x100, 0xc0825100 },
142: { 0x104, 0x01000000 },
143: { 0x108, 0x30000000 },
144: { 0x10c, 0x00000000 },
145: { 0x114, 0xc0425100 },
146: { 0x118, 0x30000000 },
147: { 0x11c, 0x38000000 },
148: { 0x120, 0x00000000 },
149: { 0x128, 0x00000000 },
150: { 0x12c, 0x00000000 },
151: { 0x130, 0x00000000 },
152: { 0x134, 0x00000000 },
153: { 0x13c, 0x00000000 },
154: { 0x140, 0x00000000 },
155: { 0x144, 0x00000000 },
156: { 0x148, 0x00000000 },
157: { 0x188, 0xc0a05338 },
158:
159: /* Default Universe VME Slave Map */
160: { 0xf00, 0xc0f20001 },
161: { 0xf04, 0x40000000 },
162: { 0xf08, 0x40001000 },
163: { 0xf0c, 0xc0001000 },
164: { 0xf14, 0xe0f200c0 },
165: { 0xf18, 0x10000000 },
166: { 0xf1c, 0x20000000 },
167: { 0xf20, 0x70000000 },
168: { 0xf28, 0x00000000 },
169: { 0xf2c, 0x00000000 },
170: { 0xf30, 0x00000000 },
171: { 0xf34, 0x00000000 },
172: { 0xf3c, 0x00000000 },
173: { 0xf40, 0x00000000 },
174: { 0xf44, 0x00000000 },
175: { 0xf48, 0x00000000 },
176: #endif
177:
178: { 0, 0 },
179: };
180:
181: int
182: mpcpcibrmatch(parent, match, aux)
183: struct device *parent;
184: void *match, *aux;
185: {
186: /* We must be a child of the raven device */
187: if (strcmp(parent->dv_cfdata->cf_driver->cd_name, "raven") != 0)
188: return (0);
189:
190: return 1;
191: }
192:
193: void
194: mpcpcibrattach(parent, self, aux)
195: struct device *parent, *self;
196: void *aux;
197: {
198: struct pcibr_softc *sc = (struct pcibr_softc *)self;
199: struct pcibr_config *lcp;
200: struct pcibus_attach_args pba;
201: const struct raven_setup *rs;
202:
203: lcp = sc->sc_pcibr = &mpc_config;
204:
205: sc->sc_membus_space = prep_mem_space_tag;
206: sc->sc_iobus_space = prep_io_space_tag;
207:
208: lcp->lc_pc.pc_conf_v = lcp;
209: lcp->lc_pc.pc_attach_hook = mpc_attach_hook;
210: lcp->lc_pc.pc_bus_maxdevs = mpc_bus_maxdevs;
211: lcp->lc_pc.pc_make_tag = mpc_make_tag;
212: lcp->lc_pc.pc_decompose_tag = mpc_decompose_tag;
213: lcp->lc_pc.pc_conf_read = mpc_conf_read;
214: lcp->lc_pc.pc_conf_write = mpc_conf_write;
215: lcp->lc_pc.pc_ether_hw_addr = mpc_ether_hw_addr;
216: lcp->lc_iot = &sc->sc_iobus_space;
217: lcp->lc_memt = &sc->sc_membus_space;
218:
219: lcp->ioh_cf8 = (PREP_CONFIG_ADD - RAVEN_P_ISA_IO_SPACE) +
220: (bus_space_handle_t)isaspace_va;
221: lcp->ioh_cfc = (PREP_CONFIG_DAT - RAVEN_P_ISA_IO_SPACE) +
222: (bus_space_handle_t)isaspace_va;
223:
224: lcp->config_type = 0;
225:
226: lcp->lc_pc.pc_intr_v = lcp;
227: lcp->lc_pc.pc_intr_map = mpc_intr_map;
228: lcp->lc_pc.pc_intr_string = mpc_intr_string;
229: lcp->lc_pc.pc_intr_line = mpc_intr_line;
230: lcp->lc_pc.pc_intr_establish = mpc_intr_establish;
231: lcp->lc_pc.pc_intr_disestablish = mpc_intr_disestablish;
232:
233: printf(": revision 0x%x\n",
234: mpc_cfg_read_1(lcp, RAVEN_PCI_REVID));
235: pba.pba_dmat = &pci_bus_dma_tag;
236:
237: pba.pba_busname = "pci";
238: pba.pba_iot = &sc->sc_iobus_space;
239: pba.pba_memt = &sc->sc_membus_space;
240: pba.pba_pc = &lcp->lc_pc;
241: pba.pba_domain = pci_ndomains++;
242: pba.pba_bus = 0;
243:
244: /*
245: * Set up PREP environment
246: */
247:
248: *(u_int32_t *)(ravenregs + RAVEN_MSADD0) = RAVEN_MSADD0_PREP;
249: *(u_int32_t *)(ravenregs + RAVEN_MSOFF0) = RAVEN_MSOFF0_PREP;
250: *(u_int32_t *)(ravenregs + RAVEN_MSADD1) = RAVEN_MSADD1_PREP;
251: *(u_int32_t *)(ravenregs + RAVEN_MSOFF1) = RAVEN_MSOFF1_PREP;
252: *(u_int32_t *)(ravenregs + RAVEN_MSADD2) = RAVEN_MSADD2_PREP;
253: *(u_int32_t *)(ravenregs + RAVEN_MSOFF2) = RAVEN_MSOFF2_PREP;
254: *(u_int32_t *)(ravenregs + RAVEN_MSADD3) = RAVEN_MSADD3_PREP;
255: *(u_int32_t *)(ravenregs + RAVEN_MSOFF3) = RAVEN_MSOFF3_PREP;
256:
257: for (rs = raven_prep_setup; rs->pci_reg != 0; rs++) {
258: mpc_cfg_write_4(lcp, rs->pci_reg, rs->value);
259: }
260:
261: /* enable mem and io mapping, and bus master */
262: mpc_cfg_write_2(lcp, RAVEN_PCI_CMD,
263: RAVEN_CMD_IOSP | RAVEN_CMD_MEMSP | RAVEN_CMD_MASTR);
264:
265: config_found(self, &pba, mpcpcibrprint);
266: }
267:
268: int
269: mpcpcibrprint(aux, pnp)
270: void *aux;
271: const char *pnp;
272: {
273: struct pcibus_attach_args *pba = aux;
274:
275: if (pnp)
276: printf("%s at %s", pba->pba_busname, pnp);
277: printf(" bus %d", pba->pba_bus);
278: return (UNCONF);
279: }
280:
281: void
282: mpc_attach_hook(parent, self, pba)
283: struct device *parent, *self;
284: struct pcibus_attach_args *pba;
285: {
286: }
287:
288: int
289: mpc_ether_hw_addr(p, ethaddr)
290: struct ppc_pci_chipset *p;
291: u_int8_t *ethaddr;
292: {
293: printf("mpc_ether_hw_addr not supported\n");
294: return (0);
295: }
296:
297: int
298: mpc_bus_maxdevs(cpv, busno)
299: void *cpv;
300: int busno;
301: {
302: return (32);
303: }
304:
305: #define BUS_SHIFT 16
306: #define DEVICE_SHIFT 11
307: #define FNC_SHIFT 8
308:
309: pcitag_t
310: mpc_make_tag(cpv, bus, dev, fnc)
311: void *cpv;
312: int bus, dev, fnc;
313: {
314: return (bus << BUS_SHIFT) | (dev << DEVICE_SHIFT) | (fnc << FNC_SHIFT);
315: }
316:
317: void
318: mpc_decompose_tag(cpv, tag, busp, devp, fncp)
319: void *cpv;
320: pcitag_t tag;
321: int *busp, *devp, *fncp;
322: {
323: if (busp != NULL)
324: *busp = (tag >> BUS_SHIFT) & 0xff;
325: if (devp != NULL)
326: *devp = (tag >> DEVICE_SHIFT) & 0x1f;
327: if (fncp != NULL)
328: *fncp = (tag >> FNC_SHIFT) & 0x7;
329: }
330:
331: u_int32_t
332: mpc_gen_config_reg(cpv, tag, offset)
333: void *cpv;
334: pcitag_t tag;
335: int offset;
336: {
337: #if 0
338: struct pcibr_config *cp = cpv;
339: unsigned int bus, dev, fcn;
340: #endif
341: u_int32_t reg;
342:
343: #if 0
344: mpc_decompose_tag(cpv, tag, &bus, &dev, &fcn);
345:
346: if (cp->config_type & 1) {
347: /* Config Mechanism #2 */
348: if (bus == 0) {
349: if (dev < 11) {
350: return 0xffffffff;
351: }
352: /*
353: * Need to do config type 0 operation
354: * 1 << (11?+dev) | fcn << 8 | reg
355: * 11? is because pci spec states
356: * that 11-15 is reserved.
357: */
358: reg = 1 << (dev) | fcn << 8 | offset;
359:
360: } else {
361: if (dev > 15) {
362: return 0xffffffff;
363: }
364: /*
365: * config type 1
366: */
367: reg = tag | offset | 1;
368:
369: }
370: } else {
371: #else
372: {
373: #endif
374: /* config mechanism #2, type 0 */
375: /* standard cf8/cfc config */
376: reg = 0x80000000 | tag | offset;
377:
378: }
379: return reg;
380: }
381:
382: /*#define DEBUG_CONFIG */
383: pcireg_t
384: mpc_conf_read(cpv, tag, offset)
385: void *cpv;
386: pcitag_t tag;
387: int offset;
388: {
389: struct pcibr_config *cp = cpv;
390: pcireg_t data;
391: u_int32_t reg;
392: int s;
393: int daddr = 0;
394: faultbuf env;
395: void *oldh;
396:
397: if (offset & 3 || offset < 0 || offset >= 0x100) {
398: #ifdef DEBUG_CONFIG
399: printf ("pci_conf_read: bad reg %x\n", offset);
400: #endif
401: return (~0);
402: }
403:
404: reg = mpc_gen_config_reg(cpv, tag, offset);
405: /* if invalid tag, return -1 */
406: if (reg == 0xffffffff) {
407: return (~0);
408: }
409:
410: if ((cp->config_type & 2) && (offset & 0x04)) {
411: daddr += 4;
412: }
413:
414: s = splhigh();
415:
416: oldh = curpcb->pcb_onfault;
417: if (setfault(&env)) {
418: /* did we fault during the read? */
419: curpcb->pcb_onfault = oldh;
420: return (~0);
421: }
422:
423: bus_space_write_4(cp->lc_iot, cp->ioh_cf8, 0, reg);
424: bus_space_read_4(cp->lc_iot, cp->ioh_cf8, 0); /* XXX */
425: data = bus_space_read_4(cp->lc_iot, cp->ioh_cfc, daddr);
426: bus_space_write_4(cp->lc_iot, cp->ioh_cf8, 0, 0); /* disable */
427: bus_space_read_4(cp->lc_iot, cp->ioh_cf8, 0); /* XXX */
428:
429: curpcb->pcb_onfault = oldh;
430:
431: splx(s);
432: #ifdef DEBUG_CONFIG
433: if (!((offset == 0) && (data == 0xffffffff))) {
434: unsigned int bus, dev, fcn;
435: mpc_decompose_tag(cpv, tag, &bus, &dev, &fcn);
436: printf("mpc_conf_read bus %x dev %x fcn %x offset %x", bus, dev, fcn,
437: offset);
438: printf(" daddr %x reg %x",daddr, reg);
439: printf(" data %x\n", data);
440: }
441: #endif
442:
443: return (data);
444: }
445:
446: void
447: mpc_conf_write(cpv, tag, offset, data)
448: void *cpv;
449: pcitag_t tag;
450: int offset;
451: pcireg_t data;
452: {
453: struct pcibr_config *cp = cpv;
454: u_int32_t reg;
455: int s;
456: int daddr = 0;
457:
458: reg = mpc_gen_config_reg(cpv, tag, offset);
459:
460: /* if invalid tag, return ??? */
461: if (reg == 0xffffffff) {
462: return;
463: }
464: if ((cp->config_type & 2) && (offset & 0x04))
465: daddr += 4;
466:
467: #ifdef DEBUG_CONFIG
468: {
469: unsigned int bus, dev, fcn;
470: mpc_decompose_tag(cpv, tag, &bus, &dev, &fcn);
471: printf("mpc_conf_write bus %x dev %x fcn %x offset %x", bus,
472: dev, fcn, offset);
473: printf(" daddr %x reg %x",daddr, reg);
474: printf(" data %x\n", data);
475: }
476: #endif
477:
478: s = splhigh();
479:
480: bus_space_write_4(cp->lc_iot, cp->ioh_cf8, 0, reg);
481: bus_space_read_4(cp->lc_iot, cp->ioh_cf8, 0); /* XXX */
482: bus_space_write_4(cp->lc_iot, cp->ioh_cfc, daddr, data);
483: bus_space_write_4(cp->lc_iot, cp->ioh_cf8, 0, 0); /* disable */
484: bus_space_read_4(cp->lc_iot, cp->ioh_cf8, 0); /* XXX */
485:
486: splx(s);
487: }
488:
489: /*ARGSUSED*/
490: int
491: mpc_intr_map(lcv, bustag, buspin, line, ihp)
492: void *lcv;
493: pcitag_t bustag;
494: int buspin, line;
495: pci_intr_handle_t *ihp;
496: {
497: int error = 0;
498:
499: *ihp = -1;
500: if (buspin == 0) {
501: error = 1; /* No IRQ used. */
502: } else if (buspin > 4) {
503: printf("mpc_intr_map: bad interrupt pin %d\n", buspin);
504: error = 1;
505: }
506:
507: if (!error)
508: *ihp = line;
509: return error;
510: }
511:
512: const char *
513: mpc_intr_string(lcv, ih)
514: void *lcv;
515: pci_intr_handle_t ih;
516: {
517: static char str[16];
518:
519: snprintf(str, sizeof str, "irq %ld", ih);
520: return (str);
521: }
522:
523: int
524: mpc_intr_line(lcv, ih)
525: void *lcv;
526: pci_intr_handle_t ih;
527: {
528: return (ih);
529: }
530:
531: typedef void *(intr_establish_t)(void *, pci_intr_handle_t, int, int,
532: int (*func)(void *), void *, char *);
533: typedef void (intr_disestablish_t)(void *, void *);
534: extern intr_establish_t *intr_establish_func;
535: extern intr_disestablish_t *intr_disestablish_func;
536:
537: void *
538: mpc_intr_establish(lcv, ih, level, func, arg, name)
539: void *lcv;
540: pci_intr_handle_t ih;
541: int level;
542: int (*func)(void *);
543: void *arg;
544: char *name;
545: {
546: return (*intr_establish_func)(lcv, ih, IST_LEVEL, level, func, arg,
547: name);
548: }
549:
550: void
551: mpc_intr_disestablish(lcv, cookie)
552: void *lcv, *cookie;
553: {
554: (*intr_disestablish_func)(lcv, cookie);
555: }
556:
557: u_int32_t
558: pci_iack()
559: {
560: /* do pci IACK cycle */
561: /* this should be bus allocated. */
562: volatile u_int8_t *iack = ravenregs + RAVEN_PIACK;
563: u_int8_t val;
564:
565: val = *iack;
566: return val;
567: }
568:
569: void
570: mpc_cfg_write_1(cp, reg, val)
571: struct pcibr_config *cp;
572: u_int32_t reg;
573: u_int8_t val;
574: {
575: int s;
576:
577: s = splhigh();
578: bus_space_write_4(cp->lc_iot, cp->ioh_cf8, 0, RAVEN_REGOFFS(reg));
579: bus_space_write_1(cp->lc_iot, cp->ioh_cfc, 0, val);
580: splx(s);
581: }
582:
583: void
584: mpc_cfg_write_2(cp, reg, val)
585: struct pcibr_config *cp;
586: u_int32_t reg;
587: u_int16_t val;
588: {
589: int s;
590:
591: s = splhigh();
592: bus_space_write_4(cp->lc_iot, cp->ioh_cf8, 0, RAVEN_REGOFFS(reg));
593: bus_space_write_2(cp->lc_iot, cp->ioh_cfc, 0, val);
594: splx(s);
595: }
596:
597: void
598: mpc_cfg_write_4(cp, reg, val)
599: struct pcibr_config *cp;
600: u_int32_t reg;
601: u_int32_t val;
602: {
603: int s;
604:
605: s = splhigh();
606: bus_space_write_4(cp->lc_iot, cp->ioh_cf8, 0, RAVEN_REGOFFS(reg));
607: bus_space_write_4(cp->lc_iot, cp->ioh_cfc, 0, val);
608: splx(s);
609: }
610:
611: u_int8_t
612: mpc_cfg_read_1(cp, reg)
613: struct pcibr_config *cp;
614: u_int32_t reg;
615: {
616: u_int8_t _v_;
617: int s;
618:
619: s = splhigh();
620: bus_space_write_4(cp->lc_iot, cp->ioh_cf8, 0, RAVEN_REGOFFS(reg));
621: _v_ = bus_space_read_1(cp->lc_iot, cp->ioh_cfc, 0);
622: splx(s);
623: return (_v_);
624: }
625:
626: u_int16_t
627: mpc_cfg_read_2(cp, reg)
628: struct pcibr_config *cp;
629: u_int32_t reg;
630: {
631: u_int16_t _v_;
632: int s;
633:
634: s = splhigh();
635: bus_space_write_4(cp->lc_iot, cp->ioh_cf8, 0, RAVEN_REGOFFS(reg));
636: _v_ = bus_space_read_2(cp->lc_iot, cp->ioh_cfc, 0);
637: splx(s);
638: return (_v_);
639: }
640:
641: u_int32_t
642: mpc_cfg_read_4(cp, reg)
643: struct pcibr_config *cp;
644: u_int32_t reg;
645: {
646: u_int32_t _v_;
647: int s;
648:
649: s = splhigh();
650: bus_space_write_4(cp->lc_iot, cp->ioh_cf8, 0, RAVEN_REGOFFS(reg));
651: _v_ = bus_space_read_4(cp->lc_iot, cp->ioh_cfc, 0);
652: splx(s);
653: return (_v_);
654: }
CVSweb