This source file includes following definitions.
- pcimatch
- pciattach
- pcipower
- pciprint
- pcisubmatch
- pci_probe_device
- pci_get_capability
- pci_find_device
- pci_enumerate_bus
- pci_matchbyid
- pciopen
- pciclose
- pciioctl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
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;
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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
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
123 if (cf->pcibuscf_bus != PCIBUS_UNK_BUS &&
124 cf->pcibuscf_bus != pba->pba_bus)
125 return (0);
126
127
128 if (pba->pba_bus < 0 || pba->pba_bus > 255)
129 return (0);
130
131
132
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
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
262 if (PCI_VENDOR(id) == PCI_VENDOR_INVALID)
263 return (0);
264
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
283
284
285 pa.pa_flags = PCI_FLAGS_IO_ENABLED | PCI_FLAGS_MEM_ENABLED;
286
287 #ifdef __i386__
288
289
290
291
292
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
312 pa.pa_intrpin = 0;
313 } else {
314
315
316
317
318 pa.pa_intrpin =
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
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
363 reg = pci_conf_read(pc, tag, PCI_BHLC_REG);
364 switch (PCI_HDRTYPE_TYPE(reg)) {
365 case 0:
366 ofs = PCI_CAPLISTPTR_REG;
367 break;
368 case 2:
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
416
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
438 if (PCI_VENDOR(id) == PCI_VENDOR_INVALID)
439 continue;
440
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
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
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
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
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
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