Training courses

Kernel and Embedded Linux

Bootlin training courses

Embedded Linux, kernel,
Yocto Project, Buildroot, real-time,
graphics, boot time, debugging...

Bootlin logo

Elixir Cross Referencer

  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
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
.\"     $NetBSD: pci.9,v 1.49 2018/11/02 15:01:18 jmcneill Exp $
.\"
.\" Copyright (c) 2001, 2003 The NetBSD Foundation, Inc.
.\" All rights reserved.
.\"
.\" This code is derived from software contributed to The NetBSD Foundation
.\" by Gregory McGarry.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\"    notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\"    notice, this list of conditions and the following disclaimer in the
.\"    documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
.\" PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd November 2, 2018
.Dt PCI 9
.Os
.Sh NAME
.Nm PCI ,
.Nm pci_activate ,
.Nm pci_bus_devorder ,
.Nm pci_chipset_tag_create ,
.Nm pci_chipset_tag_destroy ,
.Nm pci_conf_read ,
.Nm pci_conf_write ,
.Nm pci_conf_print ,
.Nm pci_conf_capture ,
.Nm pci_conf_restore ,
.Nm pci_find_device ,
.Nm pci_get_capability ,
.Nm pci_get_ht_capability ,
.Nm pci_get_ext_capability ,
.Nm pci_get_segment ,
.Nm pci_mapreg_type ,
.Nm pci_mapreg_map ,
.Nm pci_mapreg_info ,
.Nm pci_intr_map ,
.Nm pci_intr_string ,
.Nm pci_intr_evcnt ,
.Nm pci_intr_establish ,
.Nm pci_intr_establish_xname ,
.Nm pci_intr_disestablish ,
.Nm pci_intr_type ,
.Nm pci_intr_setattr ,
.Nm pci_get_powerstate ,
.Nm pci_set_powerstate ,
.Nm pci_vpd_read ,
.Nm pci_vpd_write ,
.Nm pci_make_tag ,
.Nm pci_decompose_tag ,
.Nm pci_findvendor ,
.Nm pci_devinfo ,
.Nm PCI_VENDOR ,
.Nm PCI_PRODUCT ,
.Nm PCI_REVISION
.Nd Peripheral Component Interconnect
.Sh SYNOPSIS
.In sys/bus.h
.In dev/pci/pcivar.h
.In dev/pci/pcireg.h
.In dev/pci/pcidevs.h
.Ft int
.Fn pci_bus_devorder "pci_chipset_tag_t pc" "int bus" "uint8_t *devs" \
"int maxdevs"
.Ft int
.Fn pci_activate "pci_chipset_tag_t pc" "pcitag_t tag" "device_t dev" \
"int (*wakeup)(pci_chipset_tag_t pc, pcitag_t tag, device_t dev, pcireg_t reg)"
.Ft int
.Fn pci_chipset_tag_create "pci_chipset_tag_t opc" "uint64_t present" \
"const struct pci_overrides *ov" "void *ctx" "pci_chipset_tag_t *pcp"
.Ft void
.Fn pci_chipset_tag_destroy "pci_chipset_tag_t pc"
.Ft pcireg_t
.Fn pci_conf_read "pci_chipset_tag_t pc" "pcitag_t tag" "int reg"
.Ft void
.Fn pci_conf_write "pci_chipset_tag_t pc" "pcitag_t tag" "int reg" \
"pcireg_t val"
.Ft void
.Fn pci_conf_print "pci_chipset_tag_t pc" "pcitag_t tag" \
"void (*func)(pci_chipset_tag_t, pcitag_t, const pcireg_t *)"
.Ft void
.Fn pci_conf_capture "pci_chipset_tag_t pc" "pcitag_t tag" \
"struct pci_conf_state *"
.Ft void
.Fn pci_conf_restore "pci_chipset_tag_t pc" "pcitag_t tag" \
"struct pci_conf_state *"
.Ft int
.Fn pci_find_device "struct pci_attach_args *pa" \
"int (*func)(const struct pci_attach_args *)"
.Ft int
.Fn pci_get_capability "pci_chipset_tag_t pc" "pcitag_t tag" \
"int capid" "int *offsetp" "pcireg_t *valuep"
.Ft int
.Fn pci_get_ht_capability "pci_chipset_tag_t pc" "pcitag_t tag" \
"int capid" "int *offsetp" "pcireg_t *valuep"
.Ft int
.Fn pci_get_ext_capability "pci_chipset_tag_t pc" "pcitag_t tag" \
"int capid" "int *offsetp" "pcireg_t *valuep"
.Ft u_int
.Fn pci_get_segment "pci_chipset_tag_t pc"
.Ft pcireg_t
.Fn pci_mapreg_type "pci_chipset_tag_t pc" "pcitag_t tag" "int reg"
.Ft int
.Fn pci_mapreg_map "const struct pci_attach_args *pa" "int reg" \
"pcireg_t type"  "int busflags" "bus_space_tag_t *tagp" \
"bus_space_handle_t *handlep" "bus_addr_t *basep" "bus_size_t *sizep"
.Ft int
.Fn pci_mapreg_info "pci_chipset_tag_t pc" "pcitag_t tag" "int reg" \
"pcireg_t type" "bus_addr_t *basep" "bus_size_t *sizep" "int *flagsp"
.Ft int
.Fn pci_find_rom "const struct pci_attach_args *pa" \
"bus_space_tag_t bst" "bus_space_handle_t bsh" "int code" \
"bus_space_handle_t *handlep" "bus_space_size_t *sizep"
.Ft int
.Fn pci_intr_map "const struct pci_attach_args *pa" "pci_intr_handle_t *ih"
.Ft const char *
.Fn pci_intr_string "pci_chipset_tag_t pc" "pci_intr_handle_t ih"
.Ft const struct evcnt *
.Fn pci_intr_evcnt "pci_chipset_tag_t pc" "pci_intr_handle_t ih"
.Ft void *
.Fn pci_intr_establish "pci_chipset_tag_t pc" "pci_intr_handle_t ih" \
"int level" "int (*handler)(void *)" "void *arg"
.Ft void *
.Fn pci_intr_establish_xname "pci_chipset_tag_t pc" "pci_intr_handle_t ih" \
"int level" "int (*handler)(void *)" "void *arg" "const char *xname"
.Ft void
.Fn pci_intr_disestablish "pci_chipset_tag_t pc" "void *ih"
.Ft pci_intr_type_t
.Fn pci_intr_type "pci_chipset_tag_t pc" "pci_intr_handle_t ih"
.Ft int
.Fn pci_intr_setattr "pci_chipset_tag_t pc" "pci_intr_handle_t *ih" "int attr" "uint64_t data"
.Ft int
.Fn pci_set_powerstate "pci_chipset_tag_t pc" "pcitag_t tag" \
"pcireg_t newstate"
.Ft int
.Fn pci_get_powerstate "pci_chipset_tag_t pc" "pcitag_t tag" "pcireg_t *state"
.Ft int
.Fn pci_vpd_read "pci_chipset_tag_t pc" "pcitag_t tag" "int offset" \
"int count" "pcireg_t *data"
.Ft int
.Fn pci_vpd_write "pci_chipset_tag_t pc" "pcitag_t tag" "int offset" \
"int count" "pcireg_t *data"
.Ft pcitag_t
.Fn pci_make_tag "pci_chipset_tag_t pc" "int bus" "int device" \
"int function"
.Ft void
.Fn pci_decompose_tag "pci_chipset_tag_t pc" "pcitag_t tag" \
"int *busp" "int *devicep" "int *functionp"
.Ft char *
.Fn pci_findvendor "pcireg_t id"
.Ft void
.Fn pci_devinfo "pcireg_t id" "pcireg_t class" "int show" "char *cp" "size_t len"
.Ft void
.Fn pci_aprint_devinfo "struct pci_attach_args *pa" "const char *naive"
.Ft int
.Fn PCI_VENDOR "pcireg_t id"
.Ft int
.Fn PCI_PRODUCT "pcireg_t id"
.Ft int
.Fn PCI_REVISION "pcireg_t id"
.Sh DESCRIPTION
The machine-independent
.Nm
subsystem provides support for PCI devices.
.Pp
The PCI bus was initially developed by Intel in the early 1990's to
replace the ISA bus for interfacing with their Pentium processor.
The PCI specification is widely regarded as well designed, and the
PCI bus has found widespread acceptance in machines ranging from
Apple's PowerPC-based systems to Sun's UltraSPARC-based machines.
.Pp
The PCI bus is a multiplexed bus, allowing addresses and data on the same
pins for a reduced number of pins.
Data transfers can be 8-bit, 16-bit or 32-bit.
A 64-bit extended PCI bus is also defined.
Multi-byte transfers are little-endian.
The PCI bus operates up to 33MHz and any device on the bus can be
the bus master.
.Pp
AGP is a version of PCI optimised for high-throughput data rates,
particularly for accelerated frame buffers.
.Pp
The PCI bus is a "plug and play" bus, in the sense that devices can be
configured dynamically by software.
The PCI interface chip on a PCI device bus presents a small window
of registers into the PCI configuration space.
These registers contain information about the device such as the vendor
and a product ID.
The configuration registers can also be written to by software to alter
how the device interfaces to the PCI bus.
An important register in the configuration space is the Base Address
Register (BAR).
The BAR is written to by software to map the device registers into a
window of processor address space.
Once this mapping is done, the device registers can be accessed relative
to the base address.
.Sh DATA TYPES
Drivers for devices attached to the
.Nm
will make use of the following data types:
.Bl -tag -width compact
.It Fa pcireg_t
Configuration space register.
.It Fa pci_chipset_tag_t
Chipset tag for the PCI bus.
.It Fa pcitag_t
Configuration tag describing the location and function of the PCI
device.
It contains the tuple
.Ao
bus, device, function
.Ac .
.It Fa pci_intr_handle_t
The opaque handle describing an established interrupt handler.
.It Fa struct pci_attach_args
Devices have their identity recorded in this structure.
It contains the following members:
.Bd -literal
	bus_space_tag_t pa_iot;		/* pci i/o space tag */
	bus_space_tag_t pa_memt;	/* pci mem space tag */
	bus_dma_tag_t pa_dmat;		/* DMA tag */
	pci_chipset_tag_t pa_pc;
	int pa_flags;			/* flags */
	pcitag_t pa_tag;
	pcireg_t pa_id;
	pcireg_t pa_class;
.Ed
.It Fa struct pci_conf_state
Stores the PCI configuration state of a device.
It contains the following member:
.Bd -literal
	pcireg_t reg[16];			/* pci conf register */
.Ed
.It Fa struct pci_overrides
Stores pointers to functions that override the architecture's
default
.Nm
and
.Xr pci_intr 9
implementation.
It contains the following members:
.Bd -literal
	pcireg_t (*ov_conf_read)(void *,
	    pci_chipset_tag_t, pcitag_t, int);
	void (*ov_conf_write)(void *,
	    pci_chipset_tag_t, pcitag_t, int, pcireg_t);
	int (*ov_intr_map)(void *,
	   const struct pci_attach_args *, pci_intr_handle_t *);
	const char *(*ov_intr_string)(void *,
	    pci_chipset_tag_t, pci_intr_handle_t);
	const struct evcnt *(*ov_intr_evcnt)(void *,
	    pci_chipset_tag_t, pci_intr_handle_t);
	void *(*ov_intr_establish)(void *,
	    pci_chipset_tag_t, pci_intr_handle_t,
	    int, int (*)(void *), void *);
	void (*ov_intr_disestablish)(void *,
	    pci_chipset_tag_t, void *);
	pcitag_t (*ov_make_tag)(void *,
	    pci_chipset_tag_t, int, int, int);
	void (*ov_decompose_tag)(void *,
	    pci_chipset_tag_t, pcitag_t, int *, int *, int *);
.Ed
.El
.Sh FUNCTIONS
.Bl -tag -width compact
.It Fn pci_bus_devorder "pc" "bus" "devs" "maxdevs"
Tell how many devices a PCI bus driver should probe
and in what order.
If
.Fa maxdevs
is less than or equal to zero, return 0 and
do not modify
.Fa devs .
Otherwise, return
.Fa maxdevs
or the number of devices on
.Fa bus
to probe, whichever is less, and copy to
.Fa devs
each of the PCI device numbers to probe in the order that they
should be probed.
.Fn pci_bus_devorder
will not copy more than
.Fa maxdevs
device numbers to
.Fa devs .
.It Fn pci_activate "pc" "tag" "dev" "fun"
Attempt to bring the device to state D0.
If the device is not in the D0 state call
.Fa fun
to restore its state.
If
.Fa fun
is
.Dv NULL
then restoring from state D3 is going to fail.
.It Fn pci_chipset_tag_create "opc" "present" "ov" "ctx" "pcp"
Create a copy of the tag
.Fa opc
at
.Fa *pcp .
Except for the behavior
overridden by
.Fa ov ,
.Fa *pcp
inherits the behavior of
.Fa opc
under
.Nm
calls.
.Pp
.Fa ov
contains function pointers corresponding to
.Nm
routines.
Each function pointer has a corresponding bit in
.Fa present ,
and if that bit is 1, the function pointer overrides the corresponding
.Nm
call for the new tag.
Any combination of these bits may be set in
.Fa present :
.Pp
.Bl -tag -width PCI_OVERRIDE_INTR_DISESTABLISH -compact
.It Dv PCI_OVERRIDE_CONF_READ
.It Dv PCI_OVERRIDE_CONF_WRITE
.It Dv PCI_OVERRIDE_INTR_MAP
.It Dv PCI_OVERRIDE_INTR_STRING
.It Dv PCI_OVERRIDE_INTR_EVCNT
.It Dv PCI_OVERRIDE_INTR_ESTABLISH
.It Dv PCI_OVERRIDE_INTR_DISESTABLISH
.It Dv PCI_OVERRIDE_MAKE_TAG
.It Dv PCI_OVERRIDE_DECOMPOSE_TAG
.El
.Pp
.Fn pci_chipset_tag_create
does not copy
.Fa ov .
After a new tag is created
by
.Fn pci_chipset_tag_create ,
.Fa ov
must not be destroyed until after the
tag is destroyed by
.Fn pci_chipset_tag_destroy .
.Pp
The first argument of every override-function is a
.Vt "void *" ,
and
.Fa ctx
is passed in that argument.
.Pp
Return 0 if the call succeeds.
Return
.Dv EOPNOTSUPP
if the architecture does not support overrides.
Return
.Dv EINVAL
if
.Fa present
is 0, if
.Fa ov
is
.Dv NULL ,
or if
.Fa present
indicates that an override is present, but the corresponding override
in
.Fa ov
is
.Dv NULL .
.Pp
If the call does not succeed,
.Fa *pcp
is undefined.
.It Fn pci_chipset_tag_destroy "pc"
Destroy a tag,
.Fa pc ,
created by a prior call to
.Fn pci_chipset_tag_create .
If
.Fa pc
was not created by
.Fn pci_chipset_tag_create ,
results are undefined.
If
.Fa pc
was already destroyed, results are undefined.
.It Fn pci_conf_read "pc" "tag" "reg"
Read from register
.Fa reg
in PCI configuration space.
The argument
.Fa tag
is the PCI tag for the current device attached to PCI chipset
.Fa pc .
.It Fn pci_conf_write "pc" "tag" "reg" "val"
Write to register
.Fa reg
in PCI configuration space.
The argument
.Fa tag
is the PCI tag for the current device attached to PCI chipset
.Fa pc .
.It Fn pci_conf_print "pc" "tag" "func"
Print out most of the registers in the PCI configuration for the
device.
The argument
.Fa tag
is the PCI tag for the current device attached to PCI chipset
.Fa pc .
The argument
.Fa func
is a function called by
.Fn pci_conf_print
to print the device-dependent registers.
This function is only useful for driver development and is usually
wrapped in pre-processor declarations.
.It Fn pci_conf_capture "pc" "tag" "pcs"
Capture PCI configuration space into structure
.Fa pcs .
The argument
.Fa tag
is the PCI tag for the current device attached to the PCI
chipset
.Fa pc .
.It Fn pci_conf_restore "pc" "tag" "pcs"
Restores PCI configuration space from structure
.Fa pcs .
The argument
.Fa tag
is the PCI tag for the current device attached to the PCI
chipset
.Fa pc .
.It Fn pci_find_device "pa" "func"
Find a device using a match function on all probed busses.
The argument
.Fa func
is called by
.Fn pci_find_device
to match a device.
The argument
.Fa pa
is filled in if the device is matched.
.Fn pci_find_device
returns 1 if the device is matched, and zero otherwise.
This function is specifically for use by kernel modules
and its use otherwise is strongly discouraged.
.It Fn pci_get_capability "pc" "tag" "capid" "offsetp" "valuep"
Parse the device capability list in configuration space looking for
capability
.Fa capid .
If
.Fa offsetp
is not
.Dv NULL ,
the register offset in configuration space is returned in
.Fa offsetp .
If
.Fa valuep
is not
.Dv NULL ,
the value of the capability is returned in
.Fa valuep .
The argument
.Fa tag
is the PCI tag for the current device attached to PCI chipset
.Fa pc .
This function returns 1 if the capability was found.
If the capability was not found, it returns zero, and
.Fa offsetp
and
.Fa valuep
remain unchanged.
.It Fn pci_get_ht_capability "pc" "tag" "capid" "offsetp" "valuep"
Parse the device capability list in HyperTransport configuration
space looking for capability
.Fa capid .
If
.Fa offsetp
is not
.Dv NULL ,
the register offset in configuration space is returned in
.Fa offsetp .
If
.Fa valuep
is not
.Dv NULL ,
the value of the capability is returned in
.Fa valuep .
The argument
.Fa tag
is the PCI tag for the current device attached to PCI chipset
.Fa pc .
This function returns 1 if the capability was found.
If the capability was not found, it returns zero, and
.Fa offsetp
and
.Fa valuep
remain unchanged.
.It Fn pci_get_ext_capability "pc" "tag" "capid" "offsetp" "valuep"
Parse the device capability list in extended configuration space looking for
capability
.Fa capid .
If
.Fa offsetp
is not
.Dv NULL ,
the register offset in extended configuration space is returned in
.Fa offsetp .
If
.Fa valuep
is not
.Dv NULL ,
the value of the capability is returned in
.Fa valuep .
The argument
.Fa tag
is the PCI tag for the current device attached to PCI chipset
.Fa pc .
This function returns 1 if the capability was found.
If the capability was not found, it returns zero, and
.Fa offsetp
and
.Fa valuep
remain unchanged.
.It Fn pci_get_segment "pc"
Return the PCI segment number for PCI chipset
.Fa pc .
This machine-dependent function is only available if
.Dv __HAVE_PCI_GET_SEGMENT
is defined in the header
.In machine/pci_machdep.h .
.It Fn pci_mapreg_type "pc" "tag" "reg"
Interrogates the Base Address Register (BAR) in configuration space
specified by
.Fa reg
and returns the default (or current) mapping type.
Valid returns values are:
.Bl -tag -width compact
.It Dv PCI_MAPREG_TYPE_IO
The mapping is to I/O address space.
.It Dv PCI_MAPREG_TYPE_MEM
The mapping is to memory address space.
.It Dv PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT
The mapping is to 64-bit memory address space.
.It Dv PCI_MAPREG_TYPE_ROM
The mapping is to ROM.
Note that in the current implementation,
.Dv PCI_MAPREG_TYPE_ROM
has the same numeric value as
.Dv PCI_MAPREG_TYPE_MEM .
.El
.Pp
The argument
.Fa tag
is the PCI tag for the current device attached to PCI chipset
.Fa pc .
.It Fn pci_mapreg_map "pa" "reg" "type"  "busflags" "tagp" "handlep" "basep" "sizep"
Maps the register windows for the device into kernel virtual address
space.
This function is generally only called during the driver attach step
and takes a pointer to the
.Em struct pci_attach_args
in
.Fa pa .
The physical address of the mapping is in the Base Address Register
(BAR) in configuration space specified by
.Fa reg .
Valid values for the type of mapping
.Fa type ,
which can be obtained from
.Fn pci_mapreg_type ,
are:
.Bl -tag -width compact
.It Dv PCI_MAPREG_TYPE_IO
The mapping should be to I/O address space.
.It Dv PCI_MAPREG_TYPE_MEM
The mapping should be to memory address space.
.It Dv PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT
The mapping should be to 64-bit memory address space.
.It Dv PCI_MAPREG_TYPE_ROM
The mapping is to access ROM.
This type of mapping is only permitted when the value for
.Fa reg
is
.Dv PCI_MAPREG_ROM .
.El
.Pp
The argument
.Fa busflags
are bus-space flags passed to
.Fn bus_space_map
to perform the mapping (see
.Xr bus_space 9 ) .
The bus-space tag and handle for the mapped register window are
returned in
.Fa tagp
and
.Fa handlep
respectively.
The bus-address and size of the mapping are returned in
.Fa basep
and
.Fa sizep
respectively.
If any of
.Fa tagp ,
.Fa handlep ,
.Fa basep ,
or
.Fa sizep
are
.Dv NULL
then
.Fn pci_mapreg_map
does not define their return value.
This function returns zero on success and non-zero on error.
.It Fn pci_mapreg_info "pc" "tag" "reg" "type" "basep" "sizep" "flagsp"
Performs the same operations as
.Fn pci_mapreg_map
but doesn't actually map the register window into kernel virtual
address space.
Returns the bus-address, size and bus flags in
.Fa basep ,
.Fa sizep
and
.Fa flagsp
respectively.
These return values can be used by
.Fn bus_space_map
to actually map the register window into kernel virtual address space.
This function is useful for setting up the registers in configuration
space and deferring the mapping to a later time, such as in a
bus-independent attachment routine.
.Fa pci_mapreg_info
returns zero on success and non-zero on failure.
.It Fn pci_find_rom "pa" "bst" "bsh" "code" "handlep" "sizep"
Locates a suitable ROM image within a PCI expansion ROM previously mapped with
.Fn pci_mapreg_map
and creates a subregion for it with
.Fn bus_space_subregion .
The
.Fa bst
and
.Fa bsh
arguments are the bus tag and handle obtained with the prior call to
.Fn pci_mapreg_map .
Valid values for the image type
.Fa code
are:
.Bl -tag -width compact
.It Dv PCI_ROM_CODE_TYPE_X86
Find a ROM image containing i386 executable code for use by PC BIOS.
.It Dv PCI_ROM_CODE_TYPE_OFW
Find a ROM image containing Forth code for use by Open Firmware.
.It Dv PCI_ROM_CODE_TYPE_HPPA
Find a ROM image containing HP PA/RISC executable code.
.El
.Pp
The created subregion will cover the entire selected ROM image, including
header data.
The handle to this subregion is returned in
.Fa handlep .
The size of the image (and the corresponding subregion) is returned in
.Fa sizep .
This function can only be used with expansion ROMs located at the
.Dv PCI_MAPREG_ROM
base address register (BAR).
.It Fn pci_intr_map "pa" "ih"
See
.Xr pci_intr 9 .
.It Fn pci_intr_string "pc" "ih"
See
.Xr pci_intr 9 .
.It Fn pci_intr_evcnt "pc" "ih"
See
.Xr pci_intr 9 .
.It Fn pci_intr_establish "pc" "ih" "level" "handler" "arg"
See
.Xr pci_intr 9 .
.It Fn pci_intr_establish_xname "pc" "ih" "level" "handler" "arg" "xname"
See
.Xr pci_intr 9 .
.It Fn pci_intr_disestablish "pc" "ih"
See
.Xr pci_intr 9 .
.It Fn pci_intr_type "pc" "ih"
See
.Xr pci_msi 9 .
.It Fn pci_intr_setattr "pc" "ih" "attr" "data"
See
.Xr pci_intr 9 .
.It Fn pci_set_powerstate "pc" "tag" "newstate"
Set power state of the device to newstate.
Valid values for
.Fa newstate
are:
.Pp
.Bl -tag -width PCI_PMCSR_STATE_D0 -compact
.It Dv PCI_PMCSR_STATE_D0
.It Dv PCI_PMCSR_STATE_D1
.It Dv PCI_PMCSR_STATE_D2
.It Dv PCI_PMCSR_STATE_D3
.El
.It Fn pci_get_powerstate "pc" "tag" "state"
Get current power state of the device.
.It Fn pci_vpd_read "pc" "tag" "offset" "count" "data"
Read
.Fa count
32-bit words of Vital Product Data for the device starting at offset
.Fa offset
into the buffer pointed to by
.Fa data .
Returns 0 on success or non-zero if the device has no Vital Product Data
capability or if reading the Vital Product Data fails.
.It Fn pci_vpd_write "pc" "tag" "offset" "count" "data"
Write
.Fa count
32-bit words of Vital Product Data for the device starting at offset
.Fa offset
from the buffer pointed to by
.Fa data .
Returns 0 on success or non-zero if the device has no Vital Product Data
capability of if writing the Vital Product Data fails.
.It Fn pci_make_tag "pc" "bus" "device" "function"
Create a new PCI tag for the PCI device specified by the tuple
.Ao
bus, device, function
.Ac .
This function is not useful to the usual PCI device driver.
It is generally used by drivers of multi-function devices when
attaching other PCI device drivers to each function.
.It Fn pci_decompose_tag "pc" "tag" "busp" "devicep" "fnp"
Decompose the PCI tag
.Fa tag
generated by
.Fn pci_make_tag
into its
.Ao
bus, device, function
.Ac
tuple.
.It Fn pci_findvendor "id"
Return the string of the vendor name for the device specified by
.Fa id .
.It Fn pci_devinfo "id" "class" "show" "cp" "len"
Returns the description string from the in-kernel PCI database for the
device described by
.Fa id
and
.Fa class .
The description string is returned in
.Fa cp ;
the size of that storage is given in
.Fa len .
The argument
.Fa show
specifies whether the PCI subsystem should report the string to the
console.
.It Fn pci_aprint_devinfo "pa" "naive"
Print device information to the console and system log, using the
.Xr aprint_normal 9
and
.Xr aprint_naive 9
functions.
For the device information, the
.Dq pci_devinfo
function above is used, or the
.Ar naive
argument in the
.Dq AB_QUIET
case.
This function is intended to be used early in device attach.
.It Fn PCI_VENDOR "id"
Return the PCI vendor id for device
.Fa id .
.It Fn PCI_PRODUCT "id"
Return the PCI product id for device
.Fa id .
.It Fn PCI_REVISION "id"
Return the PCI product revision for device
.Fa id .
.El
.Sh AUTOCONFIGURATION
During autoconfiguration, a
.Nm
driver will receive a pointer to
.Fa struct pci_attach_args
describing the device attaches to the PCI bus.
Drivers match the device using the
.Fa pa_id
member using
.Fn PCI_VENDOR .
.Fn PCI_PRODUCT
and
.Fn PCI_REVISION .
.Pp
During the driver attach step, drivers can read the device
configuration space using
.Fn pci_conf_read .
The meaning attached to registers in the PCI configuration space are
device-dependent, but will usually contain physical addresses of the
device register windows.
Device options can also be stored into the PCI configuration space using
.Fn pci_conf_write .
For example, the driver can request support for bus-mastering DMA by
writing the option to the PCI configuration space.
.Pp
Device capabilities can be queried using
.Fn pci_get_capability ,
and returns device-specific information which can be found in the PCI
configuration space to alter device operation.
.Pp
After reading the physical addresses of the device register windows
from configuration space, these windows must be mapped into kernel
virtual address space using
.Fn pci_mapreg_map .
Device registers can now be accessed using the standard bus-space API
(see
.Xr bus_space 9 ) .
.Pp
Details of using PCI interrupts is described in
.Xr pci_intr 9 .
.Sh DMA SUPPORT
The PCI bus supports bus-mastering operations from any device on the bus.
The DMA facilities are accessed through the standard
.Xr bus_dma 9
interface.
To support DMA transfers from the device to the host, it is necessary
to enable bus-mastering in the PCI configuration space for the device.
.Pp
During system shutdown, it is necessary to abort any DMA transfers in
progress by registering a shutdown hook (see
.Xr pmf 9 ) .
.Sh CODE REFERENCES
The PCI subsystem itself is implemented within the files
.Pa sys/dev/pci/pci.c ,
.Pa sys/dev/pci/pci_subr.c ,
.Pa sys/dev/pci/pci_map.c ,
.Pa sys/dev/pci/pci_quirks.c ,
and
.Pa sys/dev/pci/pciconf.c .
Machine-dependent portions are implemented within the file
.Pa sys/arch/<arch>/pci/pci_machdep.c .
.Pp
The database of known devices exists within the file
.Pa sys/dev/pci/pcidevs_data.h
and is generated automatically from the file
.Pa sys/dev/pci/pcidevs .
New vendor and product identifiers should be added to this file.
The database can be regenerated using the Makefile
.Pa sys/dev/pci/Makefile.pcidevs .
.Sh SEE ALSO
.Xr pci 4 ,
.Xr autoconf 9 ,
.Xr bus_dma 9 ,
.Xr bus_space 9 ,
.Xr driver 9 ,
.Xr pci_configure_bus 9 ,
.Xr pci_intr 9 ,
.Xr pci_msi 9 ,
.Xr pmf 9
.Sh HISTORY
The machine-independent PCI subsystem appeared in
.Nx 1.2 .