Annotation of sys/dev/pci/pci.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: pci.c,v 1.50 2007/05/21 22:10:45 kettenis Exp $ */
2: /* $NetBSD: pci.c,v 1.31 1997/06/06 23:48:04 thorpej Exp $ */
3:
4: /*
5: * Copyright (c) 1995, 1996 Christopher G. Demetriou. All rights reserved.
6: * Copyright (c) 1994 Charles Hannum. All rights reserved.
7: *
8: * Redistribution and use in source and binary forms, with or without
9: * modification, are permitted provided that the following conditions
10: * are met:
11: * 1. Redistributions of source code must retain the above copyright
12: * notice, this list of conditions and the following disclaimer.
13: * 2. Redistributions in binary form must reproduce the above copyright
14: * notice, this list of conditions and the following disclaimer in the
15: * documentation and/or other materials provided with the distribution.
16: * 3. All advertising materials mentioning features or use of this software
17: * must display the following acknowledgement:
18: * This product includes software developed by Charles Hannum.
19: * 4. The name of the author may not be used to endorse or promote products
20: * derived from this software without specific prior written permission.
21: *
22: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32: */
33:
34: /*
35: * PCI bus autoconfiguration.
36: */
37:
38: #include <sys/param.h>
39: #include <sys/systm.h>
40: #include <sys/device.h>
41: #include <sys/malloc.h>
42:
43: #include <dev/pci/pcireg.h>
44: #include <dev/pci/pcivar.h>
45: #include <dev/pci/pcidevs.h>
46:
47: int pcimatch(struct device *, void *, void *);
48: void pciattach(struct device *, struct device *, void *);
49: void pcipower(int, void *);
50:
51: #define NMAPREG ((PCI_MAPREG_END - PCI_MAPREG_START) / \
52: sizeof(pcireg_t))
53: struct pci_dev {
54: LIST_ENTRY(pci_dev) pd_next;
55: struct device *pd_dev;
56: pcitag_t pd_tag; /* pci register tag */
57: pcireg_t pd_csr;
58: pcireg_t pd_bhlc;
59: pcireg_t pd_int;
60: pcireg_t pd_map[NMAPREG];
61: };
62:
63: #ifdef APERTURE
64: extern int allowaperture;
65: #endif
66:
67: struct cfattach pci_ca = {
68: sizeof(struct pci_softc), pcimatch, pciattach
69: };
70:
71: struct cfdriver pci_cd = {
72: NULL, "pci", DV_DULL
73: };
74:
75: int pci_ndomains;
76:
77: int pciprint(void *, const char *);
78: int pcisubmatch(struct device *, void *, void *);
79:
80: #ifdef PCI_MACHDEP_ENUMERATE_BUS
81: #define pci_enumerate_bus PCI_MACHDEP_ENUMERATE_BUS
82: #else
83: int pci_enumerate_bus(struct pci_softc *,
84: int (*)(struct pci_attach_args *), struct pci_attach_args *);
85: #endif
86:
87: /*
88: * Important note about PCI-ISA bridges:
89: *
90: * Callbacks are used to configure these devices so that ISA/EISA bridges
91: * can attach their child busses after PCI configuration is done.
92: *
93: * This works because:
94: * (1) there can be at most one ISA/EISA bridge per PCI bus, and
95: * (2) any ISA/EISA bridges must be attached to primary PCI
96: * busses (i.e. bus zero).
97: *
98: * That boils down to: there can only be one of these outstanding
99: * at a time, it is cleared when configuring PCI bus 0 before any
100: * subdevices have been found, and it is run after all subdevices
101: * of PCI bus 0 have been found.
102: *
103: * This is needed because there are some (legacy) PCI devices which
104: * can show up as ISA/EISA devices as well (the prime example of which
105: * are VGA controllers). If you attach ISA from a PCI-ISA/EISA bridge,
106: * and the bridge is seen before the video board is, the board can show
107: * up as an ISA device, and that can (bogusly) complicate the PCI device's
108: * attach code, or make the PCI device not be properly attached at all.
109: *
110: * We use the generic config_defer() facility to achieve this.
111: */
112:
113: int
114: pcimatch(struct device *parent, void *match, void *aux)
115: {
116: struct cfdata *cf = match;
117: struct pcibus_attach_args *pba = aux;
118:
119: if (strcmp(pba->pba_busname, cf->cf_driver->cd_name))
120: return (0);
121:
122: /* Check the locators */
123: if (cf->pcibuscf_bus != PCIBUS_UNK_BUS &&
124: cf->pcibuscf_bus != pba->pba_bus)
125: return (0);
126:
127: /* sanity */
128: if (pba->pba_bus < 0 || pba->pba_bus > 255)
129: return (0);
130:
131: /*
132: * XXX check other (hardware?) indicators
133: */
134:
135: return (1);
136: }
137:
138: void
139: pciattach(struct device *parent, struct device *self, void *aux)
140: {
141: struct pcibus_attach_args *pba = aux;
142: struct pci_softc *sc = (struct pci_softc *)self;
143:
144: pci_attach_hook(parent, self, pba);
145:
146: printf("\n");
147:
148: LIST_INIT(&sc->sc_devs);
149: sc->sc_powerhook = powerhook_establish(pcipower, sc);
150:
151: sc->sc_iot = pba->pba_iot;
152: sc->sc_memt = pba->pba_memt;
153: sc->sc_dmat = pba->pba_dmat;
154: sc->sc_pc = pba->pba_pc;
155: sc->sc_domain = pba->pba_domain;
156: sc->sc_bus = pba->pba_bus;
157: sc->sc_bridgetag = pba->pba_bridgetag;
158: sc->sc_bridgeih = pba->pba_bridgeih;
159: sc->sc_maxndevs = pci_bus_maxdevs(pba->pba_pc, pba->pba_bus);
160: sc->sc_intrswiz = pba->pba_intrswiz;
161: sc->sc_intrtag = pba->pba_intrtag;
162: pci_enumerate_bus(sc, NULL, NULL);
163: }
164:
165: /* save and restore the pci config space */
166: void
167: pcipower(int why, void *arg)
168: {
169: struct pci_softc *sc = (struct pci_softc *)arg;
170: struct pci_dev *pd;
171: pcireg_t reg;
172: int i;
173:
174: LIST_FOREACH(pd, &sc->sc_devs, pd_next) {
175: if (why != PWR_RESUME) {
176: for (i = 0; i < NMAPREG; i++)
177: pd->pd_map[i] = pci_conf_read(sc->sc_pc,
178: pd->pd_tag, PCI_MAPREG_START + (i * 4));
179: pd->pd_csr = pci_conf_read(sc->sc_pc, pd->pd_tag,
180: PCI_COMMAND_STATUS_REG);
181: pd->pd_bhlc = pci_conf_read(sc->sc_pc, pd->pd_tag,
182: PCI_BHLC_REG);
183: pd->pd_int = pci_conf_read(sc->sc_pc, pd->pd_tag,
184: PCI_INTERRUPT_REG);
185: } else {
186: for (i = 0; i < NMAPREG; i++)
187: pci_conf_write(sc->sc_pc, pd->pd_tag,
188: PCI_MAPREG_START + (i * 4),
189: pd->pd_map[i]);
190: reg = pci_conf_read(sc->sc_pc, pd->pd_tag,
191: PCI_COMMAND_STATUS_REG);
192: pci_conf_write(sc->sc_pc, pd->pd_tag,
193: PCI_COMMAND_STATUS_REG,
194: (reg & 0xffff0000) | (pd->pd_csr & 0x0000ffff));
195: pci_conf_write(sc->sc_pc, pd->pd_tag, PCI_BHLC_REG,
196: pd->pd_bhlc);
197: pci_conf_write(sc->sc_pc, pd->pd_tag, PCI_INTERRUPT_REG,
198: pd->pd_int);
199: }
200: }
201: }
202:
203: int
204: pciprint(void *aux, const char *pnp)
205: {
206: struct pci_attach_args *pa = aux;
207: char devinfo[256];
208:
209: if (pnp) {
210: pci_devinfo(pa->pa_id, pa->pa_class, 1, devinfo,
211: sizeof devinfo);
212: printf("%s at %s", devinfo, pnp);
213: }
214: printf(" dev %d function %d", pa->pa_device, pa->pa_function);
215: if (!pnp) {
216: pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo,
217: sizeof devinfo);
218: printf(" %s", devinfo);
219: }
220:
221: return (UNCONF);
222: }
223:
224: int
225: pcisubmatch(struct device *parent, void *match, void *aux)
226: {
227: struct cfdata *cf = match;
228: struct pci_attach_args *pa = aux;
229:
230: if (cf->pcicf_dev != PCI_UNK_DEV &&
231: cf->pcicf_dev != pa->pa_device)
232: return (0);
233: if (cf->pcicf_function != PCI_UNK_FUNCTION &&
234: cf->pcicf_function != pa->pa_function)
235: return (0);
236:
237: return ((*cf->cf_attach->ca_match)(parent, match, aux));
238: }
239:
240: int
241: pci_probe_device(struct pci_softc *sc, pcitag_t tag,
242: int (*match)(struct pci_attach_args *), struct pci_attach_args *pap)
243: {
244: pci_chipset_tag_t pc = sc->sc_pc;
245: struct pci_attach_args pa;
246: struct pci_dev *pd;
247: struct device *dev;
248: pcireg_t id, csr, class, intr, bhlcr;
249: int ret, pin, bus, device, function;
250:
251: pci_decompose_tag(pc, tag, &bus, &device, &function);
252:
253: bhlcr = pci_conf_read(pc, tag, PCI_BHLC_REG);
254: if (PCI_HDRTYPE_TYPE(bhlcr) > 2)
255: return (0);
256:
257: id = pci_conf_read(pc, tag, PCI_ID_REG);
258: csr = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG);
259: class = pci_conf_read(pc, tag, PCI_CLASS_REG);
260:
261: /* Invalid vendor ID value? */
262: if (PCI_VENDOR(id) == PCI_VENDOR_INVALID)
263: return (0);
264: /* XXX Not invalid, but we've done this ~forever. */
265: if (PCI_VENDOR(id) == 0)
266: return (0);
267:
268: pa.pa_iot = sc->sc_iot;
269: pa.pa_memt = sc->sc_memt;
270: pa.pa_dmat = sc->sc_dmat;
271: pa.pa_pc = pc;
272: pa.pa_domain = sc->sc_domain;
273: pa.pa_bus = bus;
274: pa.pa_device = device;
275: pa.pa_function = function;
276: pa.pa_tag = tag;
277: pa.pa_id = id;
278: pa.pa_class = class;
279: pa.pa_bridgetag = sc->sc_bridgetag;
280: pa.pa_bridgeih = sc->sc_bridgeih;
281:
282: /* This is a simplification of the NetBSD code.
283: We don't support turning off I/O or memory
284: on broken hardware. <csapuntz@stanford.edu> */
285: pa.pa_flags = PCI_FLAGS_IO_ENABLED | PCI_FLAGS_MEM_ENABLED;
286:
287: #ifdef __i386__
288: /*
289: * on i386 we really need to know the device tag
290: * and not the pci bridge tag, in intr_map
291: * to be able to program the device and the
292: * pci interrupt router.
293: */
294: pa.pa_intrtag = tag;
295: pa.pa_intrswiz = 0;
296: #else
297: if (sc->sc_bridgetag == NULL) {
298: pa.pa_intrswiz = 0;
299: pa.pa_intrtag = tag;
300: } else {
301: pa.pa_intrswiz = sc->sc_intrswiz + device;
302: pa.pa_intrtag = sc->sc_intrtag;
303: }
304: #endif
305:
306: intr = pci_conf_read(pc, tag, PCI_INTERRUPT_REG);
307:
308: pin = PCI_INTERRUPT_PIN(intr);
309: pa.pa_rawintrpin = pin;
310: if (pin == PCI_INTERRUPT_PIN_NONE) {
311: /* no interrupt */
312: pa.pa_intrpin = 0;
313: } else {
314: /*
315: * swizzle it based on the number of busses we're
316: * behind and our device number.
317: */
318: pa.pa_intrpin = /* XXX */
319: ((pin + pa.pa_intrswiz - 1) % 4) + 1;
320: }
321: pa.pa_intrline = PCI_INTERRUPT_LINE(intr);
322:
323: if (match != NULL) {
324: ret = (*match)(&pa);
325: if (ret != 0 && pap != NULL)
326: *pap = pa;
327: } else {
328: if ((dev = config_found_sm(&sc->sc_dev, &pa, pciprint,
329: pcisubmatch))) {
330: pcireg_t reg;
331:
332: /* skip header type != 0 */
333: reg = pci_conf_read(pc, tag, PCI_BHLC_REG);
334: if (PCI_HDRTYPE_TYPE(reg) != 0)
335: return(0);
336: if (pci_get_capability(pc, tag,
337: PCI_CAP_PWRMGMT, NULL, NULL) == 0)
338: return(0);
339: if (!(pd = malloc(sizeof *pd, M_DEVBUF,
340: M_NOWAIT)))
341: return(0);
342: pd->pd_tag = tag;
343: pd->pd_dev = dev;
344: LIST_INSERT_HEAD(&sc->sc_devs, pd, pd_next);
345: }
346: }
347:
348: return (ret);
349: }
350:
351: int
352: pci_get_capability(pci_chipset_tag_t pc, pcitag_t tag, int capid,
353: int *offset, pcireg_t *value)
354: {
355: pcireg_t reg;
356: unsigned int ofs;
357:
358: reg = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG);
359: if (!(reg & PCI_STATUS_CAPLIST_SUPPORT))
360: return (0);
361:
362: /* Determine the Capability List Pointer register to start with. */
363: reg = pci_conf_read(pc, tag, PCI_BHLC_REG);
364: switch (PCI_HDRTYPE_TYPE(reg)) {
365: case 0: /* standard device header */
366: ofs = PCI_CAPLISTPTR_REG;
367: break;
368: case 2: /* PCI-CardBus Bridge header */
369: ofs = PCI_CARDBUS_CAPLISTPTR_REG;
370: break;
371: default:
372: return (0);
373: }
374:
375: ofs = PCI_CAPLIST_PTR(pci_conf_read(pc, tag, ofs));
376: while (ofs != 0) {
377: #ifdef DIAGNOSTIC
378: if ((ofs & 3) || (ofs < 0x40))
379: panic("pci_get_capability");
380: #endif
381: reg = pci_conf_read(pc, tag, ofs);
382: if (PCI_CAPLIST_CAP(reg) == capid) {
383: if (offset)
384: *offset = ofs;
385: if (value)
386: *value = reg;
387: return (1);
388: }
389: ofs = PCI_CAPLIST_NEXT(reg);
390: }
391:
392: return (0);
393: }
394:
395: int
396: pci_find_device(struct pci_attach_args *pa,
397: int (*match)(struct pci_attach_args *))
398: {
399: extern struct cfdriver pci_cd;
400: struct device *pcidev;
401: int i;
402:
403: for (i = 0; i < pci_cd.cd_ndevs; i++) {
404: pcidev = pci_cd.cd_devs[i];
405: if (pcidev != NULL &&
406: pci_enumerate_bus((struct pci_softc *)pcidev,
407: match, pa) != 0)
408: return (1);
409: }
410: return (0);
411: }
412:
413: #ifndef PCI_MACHDEP_ENUMERATE_BUS
414: /*
415: * Generic PCI bus enumeration routine. Used unless machine-dependent
416: * code needs to provide something else.
417: */
418: int
419: pci_enumerate_bus(struct pci_softc *sc,
420: int (*match)(struct pci_attach_args *), struct pci_attach_args *pap)
421: {
422: pci_chipset_tag_t pc = sc->sc_pc;
423: int device, function, nfunctions, ret;
424: const struct pci_quirkdata *qd;
425: pcireg_t id, bhlcr;
426: pcitag_t tag;
427:
428: for (device = 0; device < sc->sc_maxndevs; device++) {
429: tag = pci_make_tag(pc, sc->sc_bus, device, 0);
430:
431: bhlcr = pci_conf_read(pc, tag, PCI_BHLC_REG);
432: if (PCI_HDRTYPE_TYPE(bhlcr) > 2)
433: continue;
434:
435: id = pci_conf_read(pc, tag, PCI_ID_REG);
436:
437: /* Invalid vendor ID value? */
438: if (PCI_VENDOR(id) == PCI_VENDOR_INVALID)
439: continue;
440: /* XXX Not invalid, but we've done this ~forever. */
441: if (PCI_VENDOR(id) == 0)
442: continue;
443:
444: qd = pci_lookup_quirkdata(PCI_VENDOR(id), PCI_PRODUCT(id));
445:
446: if (qd != NULL &&
447: (qd->quirks & PCI_QUIRK_MULTIFUNCTION) != 0)
448: nfunctions = 8;
449: else if (qd != NULL &&
450: (qd->quirks & PCI_QUIRK_MONOFUNCTION) != 0)
451: nfunctions = 1;
452: else
453: nfunctions = PCI_HDRTYPE_MULTIFN(bhlcr) ? 8 : 1;
454:
455: for (function = 0; function < nfunctions; function++) {
456: tag = pci_make_tag(pc, sc->sc_bus, device, function);
457: ret = pci_probe_device(sc, tag, match, pap);
458: if (match != NULL && ret != 0)
459: return (ret);
460: }
461: }
462:
463: return (0);
464: }
465: #endif /* PCI_MACHDEP_ENUMERATE_BUS */
466:
467: int
468: pci_matchbyid(struct pci_attach_args *pa, const struct pci_matchid *ids,
469: int nent)
470: {
471: const struct pci_matchid *pm;
472: int i;
473:
474: for (i = 0, pm = ids; i < nent; i++, pm++)
475: if (PCI_VENDOR(pa->pa_id) == pm->pm_vid &&
476: PCI_PRODUCT(pa->pa_id) == pm->pm_pid)
477: return (1);
478: return (0);
479: }
480:
481: #ifdef USER_PCICONF
482: /*
483: * This is the user interface to PCI configuration space.
484: */
485:
486: #include <sys/pciio.h>
487: #include <sys/fcntl.h>
488:
489: #ifdef DEBUG
490: #define PCIDEBUG(x) printf x
491: #else
492: #define PCIDEBUG(x)
493: #endif
494:
495:
496: int pciopen(dev_t dev, int oflags, int devtype, struct proc *p);
497: int pciclose(dev_t dev, int flag, int devtype, struct proc *p);
498: int pciioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p);
499:
500: int
501: pciopen(dev_t dev, int oflags, int devtype, struct proc *p)
502: {
503: PCIDEBUG(("pciopen ndevs: %d\n" , pci_cd.cd_ndevs));
504:
505: if (minor(dev) >= pci_ndomains) {
506: return ENXIO;
507: }
508:
509: #ifndef APERTURE
510: if ((oflags & FWRITE) && securelevel > 0) {
511: return EPERM;
512: }
513: #else
514: if ((oflags & FWRITE) && securelevel > 0 && allowaperture == 0) {
515: return EPERM;
516: }
517: #endif
518: return (0);
519: }
520:
521: int
522: pciclose(dev_t dev, int flag, int devtype, struct proc *p)
523: {
524: PCIDEBUG(("pciclose\n"));
525: return (0);
526: }
527:
528: int
529: pciioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
530: {
531: struct pci_io *io;
532: int i, error;
533: pcitag_t tag;
534: struct pci_softc *pci = NULL;
535: pci_chipset_tag_t pc;
536:
537: io = (struct pci_io *)data;
538:
539: PCIDEBUG(("pciioctl cmd %s", cmd == PCIOCREAD ? "pciocread"
540: : cmd == PCIOCWRITE ? "pciocwrite" : "unknown"));
541: PCIDEBUG((" bus %d dev %d func %d reg %x\n", io->pi_sel.pc_bus,
542: io->pi_sel.pc_dev, io->pi_sel.pc_func, io->pi_reg));
543:
544: for (i = 0; i < pci_cd.cd_ndevs; i++) {
545: pci = pci_cd.cd_devs[i];
546: if (pci != NULL && pci->sc_domain == minor(dev) &&
547: pci->sc_bus == io->pi_sel.pc_bus)
548: break;
549: }
550: if (pci != NULL && pci->sc_bus == io->pi_sel.pc_bus) {
551: pc = pci->sc_pc;
552: } else {
553: error = ENXIO;
554: goto done;
555: }
556: /* Check bounds */
557: if (pci->sc_bus >= 256 ||
558: io->pi_sel.pc_dev >= pci_bus_maxdevs(pc, pci->sc_bus) ||
559: io->pi_sel.pc_func >= 8) {
560: error = EINVAL;
561: goto done;
562: }
563:
564: tag = pci_make_tag(pc, io->pi_sel.pc_bus, io->pi_sel.pc_dev,
565: io->pi_sel.pc_func);
566:
567: switch(cmd) {
568: case PCIOCGETCONF:
569: error = ENODEV;
570: break;
571:
572: case PCIOCREAD:
573: switch(io->pi_width) {
574: case 4:
575: /* Make sure the register is properly aligned */
576: if (io->pi_reg & 0x3)
577: return EINVAL;
578: io->pi_data = pci_conf_read(pc, tag, io->pi_reg);
579: error = 0;
580: break;
581: default:
582: error = ENODEV;
583: break;
584: }
585: break;
586:
587: case PCIOCWRITE:
588: if (!(flag & FWRITE))
589: return EPERM;
590:
591: switch(io->pi_width) {
592: case 4:
593: /* Make sure the register is properly aligned */
594: if (io->pi_reg & 0x3)
595: return EINVAL;
596: pci_conf_write(pc, tag, io->pi_reg, io->pi_data);
597: error = 0;
598: break;
599: default:
600: error = ENODEV;
601: break;
602: }
603: break;
604:
605: default:
606: error = ENOTTY;
607: break;
608: }
609: done:
610: return (error);
611: }
612:
613: #endif
CVSweb