libpciaccess-0.13.2/README 0000644 0143106 0000012 00000001770 12172612452 0015370 0 ustar 00alanc staff 0000266 0200005 xorg/lib/libpciaccess - Generic PCI access library
Documentation of the libpciaccess API's can be generated from the
sources via the doxygen command. Information about porting Xorg
drivers to libpciaccess is located at:
http://www.x.org/wiki/PciReworkHowto
For historical reference, the original proposal for this work is at:
http://www.x.org/wiki/PciReworkProposal
All questions regarding this software should be directed at the
Xorg mailing list:
http://lists.freedesktop.org/mailman/listinfo/xorg
Please submit bug reports to the Xorg bugzilla:
https://bugs.freedesktop.org/enter_bug.cgi?product=xorg
The master development code repository can be found at:
git://anongit.freedesktop.org/git/xorg/lib/libpciaccess
http://cgit.freedesktop.org/xorg/lib/libpciaccess
For patch submission instructions, see:
http://www.x.org/wiki/Development/Documentation/SubmittingPatches
For more information on the git code manager, see:
http://wiki.x.org/wiki/GitPage
libpciaccess-0.13.2/config.sub 0000755 0143106 0000012 00000105301 12172612466 0016473 0 ustar 00alanc staff 0000266 0200005 #! /bin/sh
# Configuration validation subroutine script.
# Copyright 1992-2013 Free Software Foundation, Inc.
timestamp='2013-04-24'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see .
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that
# program. This Exception is an additional permission under section 7
# of the GNU General Public License, version 3 ("GPLv3").
# Please send patches with a ChangeLog entry to config-patches@gnu.org.
#
# Configuration subroutine to validate and canonicalize a configuration type.
# Supply the specified configuration type as an argument.
# If it is invalid, we print an error message on stderr and exit with code 1.
# Otherwise, we print the canonical config type on stdout and succeed.
# You can get the latest version of this script from:
# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
# This file is supposed to be the same for all GNU packages
# and recognize all the CPU types, system types and aliases
# that are meaningful with *any* GNU software.
# Each package is responsible for reporting which valid configurations
# it does not support. The user should be able to distinguish
# a failure to support a valid configuration from a meaningless
# configuration.
# The goal of this file is to map all the various variations of a given
# machine specification into a single specification in the form:
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
# or in some cases, the newer four-part form:
# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
# It is wrong to echo any other type of specification.
me=`echo "$0" | sed -e 's,.*/,,'`
usage="\
Usage: $0 [OPTION] CPU-MFR-OPSYS
$0 [OPTION] ALIAS
Canonicalize a configuration name.
Operation modes:
-h, --help print this help, then exit
-t, --time-stamp print date of last modification, then exit
-v, --version print version number, then exit
Report bugs and patches to ."
version="\
GNU config.sub ($timestamp)
Copyright 1992-2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
help="
Try \`$me --help' for more information."
# Parse command line
while test $# -gt 0 ; do
case $1 in
--time-stamp | --time* | -t )
echo "$timestamp" ; exit ;;
--version | -v )
echo "$version" ; exit ;;
--help | --h* | -h )
echo "$usage"; exit ;;
-- ) # Stop option processing
shift; break ;;
- ) # Use stdin as input.
break ;;
-* )
echo "$me: invalid option $1$help"
exit 1 ;;
*local*)
# First pass through any local machine types.
echo $1
exit ;;
* )
break ;;
esac
done
case $# in
0) echo "$me: missing argument$help" >&2
exit 1;;
1) ;;
*) echo "$me: too many arguments$help" >&2
exit 1;;
esac
# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
# Here we must recognize all the valid KERNEL-OS combinations.
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
case $maybe_os in
nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
knetbsd*-gnu* | netbsd*-gnu* | \
kopensolaris*-gnu* | \
storm-chaos* | os2-emx* | rtmk-nova*)
os=-$maybe_os
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
;;
android-linux)
os=-linux-android
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
;;
*)
basic_machine=`echo $1 | sed 's/-[^-]*$//'`
if [ $basic_machine != $1 ]
then os=`echo $1 | sed 's/.*-/-/'`
else os=; fi
;;
esac
### Let's recognize common machines as not being operating systems so
### that things like config.sub decstation-3100 work. We also
### recognize some manufacturers as not being operating systems, so we
### can provide default operating systems below.
case $os in
-sun*os*)
# Prevent following clause from handling this invalid input.
;;
-dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
-att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
-apple | -axis | -knuth | -cray | -microblaze*)
os=
basic_machine=$1
;;
-bluegene*)
os=-cnk
;;
-sim | -cisco | -oki | -wec | -winbond)
os=
basic_machine=$1
;;
-scout)
;;
-wrs)
os=-vxworks
basic_machine=$1
;;
-chorusos*)
os=-chorusos
basic_machine=$1
;;
-chorusrdb)
os=-chorusrdb
basic_machine=$1
;;
-hiux*)
os=-hiuxwe2
;;
-sco6)
os=-sco5v6
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco5)
os=-sco3.2v5
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco4)
os=-sco3.2v4
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco3.2.[4-9]*)
os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco3.2v[4-9]*)
# Don't forget version if it is 3.2v4 or newer.
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco5v6*)
# Don't forget version if it is 3.2v4 or newer.
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco*)
os=-sco3.2v2
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-udk*)
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-isc)
os=-isc2.2
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-clix*)
basic_machine=clipper-intergraph
;;
-isc*)
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-lynx*178)
os=-lynxos178
;;
-lynx*5)
os=-lynxos5
;;
-lynx*)
os=-lynxos
;;
-ptx*)
basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
;;
-windowsnt*)
os=`echo $os | sed -e 's/windowsnt/winnt/'`
;;
-psos*)
os=-psos
;;
-mint | -mint[0-9]*)
basic_machine=m68k-atari
os=-mint
;;
esac
# Decode aliases for certain CPU-COMPANY combinations.
case $basic_machine in
# Recognize the basic CPU types without company name.
# Some are omitted here because they have special meanings below.
1750a | 580 \
| a29k \
| aarch64 | aarch64_be \
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
| am33_2.0 \
| arc | arceb \
| arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
| avr | avr32 \
| be32 | be64 \
| bfin \
| c4x | clipper \
| d10v | d30v | dlx | dsp16xx \
| epiphany \
| fido | fr30 | frv \
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
| hexagon \
| i370 | i860 | i960 | ia64 \
| ip2k | iq2000 \
| le32 | le64 \
| lm32 \
| m32c | m32r | m32rle | m68000 | m68k | m88k \
| maxq | mb | microblaze | microblazeel | mcore | mep | metag \
| mips | mipsbe | mipseb | mipsel | mipsle \
| mips16 \
| mips64 | mips64el \
| mips64octeon | mips64octeonel \
| mips64orion | mips64orionel \
| mips64r5900 | mips64r5900el \
| mips64vr | mips64vrel \
| mips64vr4100 | mips64vr4100el \
| mips64vr4300 | mips64vr4300el \
| mips64vr5000 | mips64vr5000el \
| mips64vr5900 | mips64vr5900el \
| mipsisa32 | mipsisa32el \
| mipsisa32r2 | mipsisa32r2el \
| mipsisa64 | mipsisa64el \
| mipsisa64r2 | mipsisa64r2el \
| mipsisa64sb1 | mipsisa64sb1el \
| mipsisa64sr71k | mipsisa64sr71kel \
| mipsr5900 | mipsr5900el \
| mipstx39 | mipstx39el \
| mn10200 | mn10300 \
| moxie \
| mt \
| msp430 \
| nds32 | nds32le | nds32be \
| nios | nios2 | nios2eb | nios2el \
| ns16k | ns32k \
| open8 \
| or1k | or32 \
| pdp10 | pdp11 | pj | pjl \
| powerpc | powerpc64 | powerpc64le | powerpcle \
| pyramid \
| rl78 | rx \
| score \
| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
| sh64 | sh64le \
| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
| spu \
| tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
| ubicom32 \
| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
| we32k \
| x86 | xc16x | xstormy16 | xtensa \
| z8k | z80)
basic_machine=$basic_machine-unknown
;;
c54x)
basic_machine=tic54x-unknown
;;
c55x)
basic_machine=tic55x-unknown
;;
c6x)
basic_machine=tic6x-unknown
;;
m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip)
basic_machine=$basic_machine-unknown
os=-none
;;
m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
;;
ms1)
basic_machine=mt-unknown
;;
strongarm | thumb | xscale)
basic_machine=arm-unknown
;;
xgate)
basic_machine=$basic_machine-unknown
os=-none
;;
xscaleeb)
basic_machine=armeb-unknown
;;
xscaleel)
basic_machine=armel-unknown
;;
# We use `pc' rather than `unknown'
# because (1) that's what they normally are, and
# (2) the word "unknown" tends to confuse beginning users.
i*86 | x86_64)
basic_machine=$basic_machine-pc
;;
# Object if more than one company name word.
*-*-*)
echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
exit 1
;;
# Recognize the basic CPU types with company name.
580-* \
| a29k-* \
| aarch64-* | aarch64_be-* \
| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
| arm-* | armbe-* | armle-* | armeb-* | armv*-* \
| avr-* | avr32-* \
| be32-* | be64-* \
| bfin-* | bs2000-* \
| c[123]* | c30-* | [cjt]90-* | c4x-* \
| clipper-* | craynv-* | cydra-* \
| d10v-* | d30v-* | dlx-* \
| elxsi-* \
| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
| h8300-* | h8500-* \
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
| hexagon-* \
| i*86-* | i860-* | i960-* | ia64-* \
| ip2k-* | iq2000-* \
| le32-* | le64-* \
| lm32-* \
| m32c-* | m32r-* | m32rle-* \
| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
| m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
| microblaze-* | microblazeel-* \
| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
| mips16-* \
| mips64-* | mips64el-* \
| mips64octeon-* | mips64octeonel-* \
| mips64orion-* | mips64orionel-* \
| mips64r5900-* | mips64r5900el-* \
| mips64vr-* | mips64vrel-* \
| mips64vr4100-* | mips64vr4100el-* \
| mips64vr4300-* | mips64vr4300el-* \
| mips64vr5000-* | mips64vr5000el-* \
| mips64vr5900-* | mips64vr5900el-* \
| mipsisa32-* | mipsisa32el-* \
| mipsisa32r2-* | mipsisa32r2el-* \
| mipsisa64-* | mipsisa64el-* \
| mipsisa64r2-* | mipsisa64r2el-* \
| mipsisa64sb1-* | mipsisa64sb1el-* \
| mipsisa64sr71k-* | mipsisa64sr71kel-* \
| mipsr5900-* | mipsr5900el-* \
| mipstx39-* | mipstx39el-* \
| mmix-* \
| mt-* \
| msp430-* \
| nds32-* | nds32le-* | nds32be-* \
| nios-* | nios2-* | nios2eb-* | nios2el-* \
| none-* | np1-* | ns16k-* | ns32k-* \
| open8-* \
| orion-* \
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
| pyramid-* \
| rl78-* | romp-* | rs6000-* | rx-* \
| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
| sparclite-* \
| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
| tahoe-* \
| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
| tile*-* \
| tron-* \
| ubicom32-* \
| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
| vax-* \
| we32k-* \
| x86-* | x86_64-* | xc16x-* | xps100-* \
| xstormy16-* | xtensa*-* \
| ymp-* \
| z8k-* | z80-*)
;;
# Recognize the basic CPU types without company name, with glob match.
xtensa*)
basic_machine=$basic_machine-unknown
;;
# Recognize the various machine names and aliases which stand
# for a CPU type and a company and sometimes even an OS.
386bsd)
basic_machine=i386-unknown
os=-bsd
;;
3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
basic_machine=m68000-att
;;
3b*)
basic_machine=we32k-att
;;
a29khif)
basic_machine=a29k-amd
os=-udi
;;
abacus)
basic_machine=abacus-unknown
;;
adobe68k)
basic_machine=m68010-adobe
os=-scout
;;
alliant | fx80)
basic_machine=fx80-alliant
;;
altos | altos3068)
basic_machine=m68k-altos
;;
am29k)
basic_machine=a29k-none
os=-bsd
;;
amd64)
basic_machine=x86_64-pc
;;
amd64-*)
basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
amdahl)
basic_machine=580-amdahl
os=-sysv
;;
amiga | amiga-*)
basic_machine=m68k-unknown
;;
amigaos | amigados)
basic_machine=m68k-unknown
os=-amigaos
;;
amigaunix | amix)
basic_machine=m68k-unknown
os=-sysv4
;;
apollo68)
basic_machine=m68k-apollo
os=-sysv
;;
apollo68bsd)
basic_machine=m68k-apollo
os=-bsd
;;
aros)
basic_machine=i386-pc
os=-aros
;;
aux)
basic_machine=m68k-apple
os=-aux
;;
balance)
basic_machine=ns32k-sequent
os=-dynix
;;
blackfin)
basic_machine=bfin-unknown
os=-linux
;;
blackfin-*)
basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
os=-linux
;;
bluegene*)
basic_machine=powerpc-ibm
os=-cnk
;;
c54x-*)
basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
c55x-*)
basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
c6x-*)
basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
c90)
basic_machine=c90-cray
os=-unicos
;;
cegcc)
basic_machine=arm-unknown
os=-cegcc
;;
convex-c1)
basic_machine=c1-convex
os=-bsd
;;
convex-c2)
basic_machine=c2-convex
os=-bsd
;;
convex-c32)
basic_machine=c32-convex
os=-bsd
;;
convex-c34)
basic_machine=c34-convex
os=-bsd
;;
convex-c38)
basic_machine=c38-convex
os=-bsd
;;
cray | j90)
basic_machine=j90-cray
os=-unicos
;;
craynv)
basic_machine=craynv-cray
os=-unicosmp
;;
cr16 | cr16-*)
basic_machine=cr16-unknown
os=-elf
;;
crds | unos)
basic_machine=m68k-crds
;;
crisv32 | crisv32-* | etraxfs*)
basic_machine=crisv32-axis
;;
cris | cris-* | etrax*)
basic_machine=cris-axis
;;
crx)
basic_machine=crx-unknown
os=-elf
;;
da30 | da30-*)
basic_machine=m68k-da30
;;
decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
basic_machine=mips-dec
;;
decsystem10* | dec10*)
basic_machine=pdp10-dec
os=-tops10
;;
decsystem20* | dec20*)
basic_machine=pdp10-dec
os=-tops20
;;
delta | 3300 | motorola-3300 | motorola-delta \
| 3300-motorola | delta-motorola)
basic_machine=m68k-motorola
;;
delta88)
basic_machine=m88k-motorola
os=-sysv3
;;
dicos)
basic_machine=i686-pc
os=-dicos
;;
djgpp)
basic_machine=i586-pc
os=-msdosdjgpp
;;
dpx20 | dpx20-*)
basic_machine=rs6000-bull
os=-bosx
;;
dpx2* | dpx2*-bull)
basic_machine=m68k-bull
os=-sysv3
;;
ebmon29k)
basic_machine=a29k-amd
os=-ebmon
;;
elxsi)
basic_machine=elxsi-elxsi
os=-bsd
;;
encore | umax | mmax)
basic_machine=ns32k-encore
;;
es1800 | OSE68k | ose68k | ose | OSE)
basic_machine=m68k-ericsson
os=-ose
;;
fx2800)
basic_machine=i860-alliant
;;
genix)
basic_machine=ns32k-ns
;;
gmicro)
basic_machine=tron-gmicro
os=-sysv
;;
go32)
basic_machine=i386-pc
os=-go32
;;
h3050r* | hiux*)
basic_machine=hppa1.1-hitachi
os=-hiuxwe2
;;
h8300hms)
basic_machine=h8300-hitachi
os=-hms
;;
h8300xray)
basic_machine=h8300-hitachi
os=-xray
;;
h8500hms)
basic_machine=h8500-hitachi
os=-hms
;;
harris)
basic_machine=m88k-harris
os=-sysv3
;;
hp300-*)
basic_machine=m68k-hp
;;
hp300bsd)
basic_machine=m68k-hp
os=-bsd
;;
hp300hpux)
basic_machine=m68k-hp
os=-hpux
;;
hp3k9[0-9][0-9] | hp9[0-9][0-9])
basic_machine=hppa1.0-hp
;;
hp9k2[0-9][0-9] | hp9k31[0-9])
basic_machine=m68000-hp
;;
hp9k3[2-9][0-9])
basic_machine=m68k-hp
;;
hp9k6[0-9][0-9] | hp6[0-9][0-9])
basic_machine=hppa1.0-hp
;;
hp9k7[0-79][0-9] | hp7[0-79][0-9])
basic_machine=hppa1.1-hp
;;
hp9k78[0-9] | hp78[0-9])
# FIXME: really hppa2.0-hp
basic_machine=hppa1.1-hp
;;
hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
# FIXME: really hppa2.0-hp
basic_machine=hppa1.1-hp
;;
hp9k8[0-9][13679] | hp8[0-9][13679])
basic_machine=hppa1.1-hp
;;
hp9k8[0-9][0-9] | hp8[0-9][0-9])
basic_machine=hppa1.0-hp
;;
hppa-next)
os=-nextstep3
;;
hppaosf)
basic_machine=hppa1.1-hp
os=-osf
;;
hppro)
basic_machine=hppa1.1-hp
os=-proelf
;;
i370-ibm* | ibm*)
basic_machine=i370-ibm
;;
i*86v32)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-sysv32
;;
i*86v4*)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-sysv4
;;
i*86v)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-sysv
;;
i*86sol2)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-solaris2
;;
i386mach)
basic_machine=i386-mach
os=-mach
;;
i386-vsta | vsta)
basic_machine=i386-unknown
os=-vsta
;;
iris | iris4d)
basic_machine=mips-sgi
case $os in
-irix*)
;;
*)
os=-irix4
;;
esac
;;
isi68 | isi)
basic_machine=m68k-isi
os=-sysv
;;
m68knommu)
basic_machine=m68k-unknown
os=-linux
;;
m68knommu-*)
basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
os=-linux
;;
m88k-omron*)
basic_machine=m88k-omron
;;
magnum | m3230)
basic_machine=mips-mips
os=-sysv
;;
merlin)
basic_machine=ns32k-utek
os=-sysv
;;
microblaze*)
basic_machine=microblaze-xilinx
;;
mingw64)
basic_machine=x86_64-pc
os=-mingw64
;;
mingw32)
basic_machine=i386-pc
os=-mingw32
;;
mingw32ce)
basic_machine=arm-unknown
os=-mingw32ce
;;
miniframe)
basic_machine=m68000-convergent
;;
*mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
basic_machine=m68k-atari
os=-mint
;;
mips3*-*)
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
;;
mips3*)
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
;;
monitor)
basic_machine=m68k-rom68k
os=-coff
;;
morphos)
basic_machine=powerpc-unknown
os=-morphos
;;
msdos)
basic_machine=i386-pc
os=-msdos
;;
ms1-*)
basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
;;
msys)
basic_machine=i386-pc
os=-msys
;;
mvs)
basic_machine=i370-ibm
os=-mvs
;;
nacl)
basic_machine=le32-unknown
os=-nacl
;;
ncr3000)
basic_machine=i486-ncr
os=-sysv4
;;
netbsd386)
basic_machine=i386-unknown
os=-netbsd
;;
netwinder)
basic_machine=armv4l-rebel
os=-linux
;;
news | news700 | news800 | news900)
basic_machine=m68k-sony
os=-newsos
;;
news1000)
basic_machine=m68030-sony
os=-newsos
;;
news-3600 | risc-news)
basic_machine=mips-sony
os=-newsos
;;
necv70)
basic_machine=v70-nec
os=-sysv
;;
next | m*-next )
basic_machine=m68k-next
case $os in
-nextstep* )
;;
-ns2*)
os=-nextstep2
;;
*)
os=-nextstep3
;;
esac
;;
nh3000)
basic_machine=m68k-harris
os=-cxux
;;
nh[45]000)
basic_machine=m88k-harris
os=-cxux
;;
nindy960)
basic_machine=i960-intel
os=-nindy
;;
mon960)
basic_machine=i960-intel
os=-mon960
;;
nonstopux)
basic_machine=mips-compaq
os=-nonstopux
;;
np1)
basic_machine=np1-gould
;;
neo-tandem)
basic_machine=neo-tandem
;;
nse-tandem)
basic_machine=nse-tandem
;;
nsr-tandem)
basic_machine=nsr-tandem
;;
op50n-* | op60c-*)
basic_machine=hppa1.1-oki
os=-proelf
;;
openrisc | openrisc-*)
basic_machine=or32-unknown
;;
os400)
basic_machine=powerpc-ibm
os=-os400
;;
OSE68000 | ose68000)
basic_machine=m68000-ericsson
os=-ose
;;
os68k)
basic_machine=m68k-none
os=-os68k
;;
pa-hitachi)
basic_machine=hppa1.1-hitachi
os=-hiuxwe2
;;
paragon)
basic_machine=i860-intel
os=-osf
;;
parisc)
basic_machine=hppa-unknown
os=-linux
;;
parisc-*)
basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
os=-linux
;;
pbd)
basic_machine=sparc-tti
;;
pbb)
basic_machine=m68k-tti
;;
pc532 | pc532-*)
basic_machine=ns32k-pc532
;;
pc98)
basic_machine=i386-pc
;;
pc98-*)
basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pentium | p5 | k5 | k6 | nexgen | viac3)
basic_machine=i586-pc
;;
pentiumpro | p6 | 6x86 | athlon | athlon_*)
basic_machine=i686-pc
;;
pentiumii | pentium2 | pentiumiii | pentium3)
basic_machine=i686-pc
;;
pentium4)
basic_machine=i786-pc
;;
pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pentiumpro-* | p6-* | 6x86-* | athlon-*)
basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pentium4-*)
basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pn)
basic_machine=pn-gould
;;
power) basic_machine=power-ibm
;;
ppc | ppcbe) basic_machine=powerpc-unknown
;;
ppc-* | ppcbe-*)
basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ppcle | powerpclittle | ppc-le | powerpc-little)
basic_machine=powerpcle-unknown
;;
ppcle-* | powerpclittle-*)
basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ppc64) basic_machine=powerpc64-unknown
;;
ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ppc64le | powerpc64little | ppc64-le | powerpc64-little)
basic_machine=powerpc64le-unknown
;;
ppc64le-* | powerpc64little-*)
basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ps2)
basic_machine=i386-ibm
;;
pw32)
basic_machine=i586-unknown
os=-pw32
;;
rdos | rdos64)
basic_machine=x86_64-pc
os=-rdos
;;
rdos32)
basic_machine=i386-pc
os=-rdos
;;
rom68k)
basic_machine=m68k-rom68k
os=-coff
;;
rm[46]00)
basic_machine=mips-siemens
;;
rtpc | rtpc-*)
basic_machine=romp-ibm
;;
s390 | s390-*)
basic_machine=s390-ibm
;;
s390x | s390x-*)
basic_machine=s390x-ibm
;;
sa29200)
basic_machine=a29k-amd
os=-udi
;;
sb1)
basic_machine=mipsisa64sb1-unknown
;;
sb1el)
basic_machine=mipsisa64sb1el-unknown
;;
sde)
basic_machine=mipsisa32-sde
os=-elf
;;
sei)
basic_machine=mips-sei
os=-seiux
;;
sequent)
basic_machine=i386-sequent
;;
sh)
basic_machine=sh-hitachi
os=-hms
;;
sh5el)
basic_machine=sh5le-unknown
;;
sh64)
basic_machine=sh64-unknown
;;
sparclite-wrs | simso-wrs)
basic_machine=sparclite-wrs
os=-vxworks
;;
sps7)
basic_machine=m68k-bull
os=-sysv2
;;
spur)
basic_machine=spur-unknown
;;
st2000)
basic_machine=m68k-tandem
;;
stratus)
basic_machine=i860-stratus
os=-sysv4
;;
strongarm-* | thumb-*)
basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
sun2)
basic_machine=m68000-sun
;;
sun2os3)
basic_machine=m68000-sun
os=-sunos3
;;
sun2os4)
basic_machine=m68000-sun
os=-sunos4
;;
sun3os3)
basic_machine=m68k-sun
os=-sunos3
;;
sun3os4)
basic_machine=m68k-sun
os=-sunos4
;;
sun4os3)
basic_machine=sparc-sun
os=-sunos3
;;
sun4os4)
basic_machine=sparc-sun
os=-sunos4
;;
sun4sol2)
basic_machine=sparc-sun
os=-solaris2
;;
sun3 | sun3-*)
basic_machine=m68k-sun
;;
sun4)
basic_machine=sparc-sun
;;
sun386 | sun386i | roadrunner)
basic_machine=i386-sun
;;
sv1)
basic_machine=sv1-cray
os=-unicos
;;
symmetry)
basic_machine=i386-sequent
os=-dynix
;;
t3e)
basic_machine=alphaev5-cray
os=-unicos
;;
t90)
basic_machine=t90-cray
os=-unicos
;;
tile*)
basic_machine=$basic_machine-unknown
os=-linux-gnu
;;
tx39)
basic_machine=mipstx39-unknown
;;
tx39el)
basic_machine=mipstx39el-unknown
;;
toad1)
basic_machine=pdp10-xkl
os=-tops20
;;
tower | tower-32)
basic_machine=m68k-ncr
;;
tpf)
basic_machine=s390x-ibm
os=-tpf
;;
udi29k)
basic_machine=a29k-amd
os=-udi
;;
ultra3)
basic_machine=a29k-nyu
os=-sym1
;;
v810 | necv810)
basic_machine=v810-nec
os=-none
;;
vaxv)
basic_machine=vax-dec
os=-sysv
;;
vms)
basic_machine=vax-dec
os=-vms
;;
vpp*|vx|vx-*)
basic_machine=f301-fujitsu
;;
vxworks960)
basic_machine=i960-wrs
os=-vxworks
;;
vxworks68)
basic_machine=m68k-wrs
os=-vxworks
;;
vxworks29k)
basic_machine=a29k-wrs
os=-vxworks
;;
w65*)
basic_machine=w65-wdc
os=-none
;;
w89k-*)
basic_machine=hppa1.1-winbond
os=-proelf
;;
xbox)
basic_machine=i686-pc
os=-mingw32
;;
xps | xps100)
basic_machine=xps100-honeywell
;;
xscale-* | xscalee[bl]-*)
basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
;;
ymp)
basic_machine=ymp-cray
os=-unicos
;;
z8k-*-coff)
basic_machine=z8k-unknown
os=-sim
;;
z80-*-coff)
basic_machine=z80-unknown
os=-sim
;;
none)
basic_machine=none-none
os=-none
;;
# Here we handle the default manufacturer of certain CPU types. It is in
# some cases the only manufacturer, in others, it is the most popular.
w89k)
basic_machine=hppa1.1-winbond
;;
op50n)
basic_machine=hppa1.1-oki
;;
op60c)
basic_machine=hppa1.1-oki
;;
romp)
basic_machine=romp-ibm
;;
mmix)
basic_machine=mmix-knuth
;;
rs6000)
basic_machine=rs6000-ibm
;;
vax)
basic_machine=vax-dec
;;
pdp10)
# there are many clones, so DEC is not a safe bet
basic_machine=pdp10-unknown
;;
pdp11)
basic_machine=pdp11-dec
;;
we32k)
basic_machine=we32k-att
;;
sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
basic_machine=sh-unknown
;;
sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
basic_machine=sparc-sun
;;
cydra)
basic_machine=cydra-cydrome
;;
orion)
basic_machine=orion-highlevel
;;
orion105)
basic_machine=clipper-highlevel
;;
mac | mpw | mac-mpw)
basic_machine=m68k-apple
;;
pmac | pmac-mpw)
basic_machine=powerpc-apple
;;
*-unknown)
# Make sure to match an already-canonicalized machine name.
;;
*)
echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
exit 1
;;
esac
# Here we canonicalize certain aliases for manufacturers.
case $basic_machine in
*-digital*)
basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
;;
*-commodore*)
basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
;;
*)
;;
esac
# Decode manufacturer-specific aliases for certain operating systems.
if [ x"$os" != x"" ]
then
case $os in
# First match some system type aliases
# that might get confused with valid system types.
# -solaris* is a basic system type, with this one exception.
-auroraux)
os=-auroraux
;;
-solaris1 | -solaris1.*)
os=`echo $os | sed -e 's|solaris1|sunos4|'`
;;
-solaris)
os=-solaris2
;;
-svr4*)
os=-sysv4
;;
-unixware*)
os=-sysv4.2uw
;;
-gnu/linux*)
os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
;;
# First accept the basic system types.
# The portable systems comes first.
# Each alternative MUST END IN A *, to match a version number.
# -sysv* is not here because it comes later, after sysvr4.
-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
| -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
| -sym* | -kopensolaris* | -plan9* \
| -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
| -aos* | -aros* \
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
| -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
| -bitrig* | -openbsd* | -solidbsd* \
| -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
| -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
| -chorusos* | -chorusrdb* | -cegcc* \
| -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
| -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
| -linux-newlib* | -linux-musl* | -linux-uclibc* \
| -uxpv* | -beos* | -mpeix* | -udk* \
| -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
| -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
| -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
| -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
# Remember, each alternative MUST END IN *, to match a version number.
;;
-qnx*)
case $basic_machine in
x86-* | i*86-*)
;;
*)
os=-nto$os
;;
esac
;;
-nto-qnx*)
;;
-nto*)
os=`echo $os | sed -e 's|nto|nto-qnx|'`
;;
-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
| -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
| -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
;;
-mac*)
os=`echo $os | sed -e 's|mac|macos|'`
;;
-linux-dietlibc)
os=-linux-dietlibc
;;
-linux*)
os=`echo $os | sed -e 's|linux|linux-gnu|'`
;;
-sunos5*)
os=`echo $os | sed -e 's|sunos5|solaris2|'`
;;
-sunos6*)
os=`echo $os | sed -e 's|sunos6|solaris3|'`
;;
-opened*)
os=-openedition
;;
-os400*)
os=-os400
;;
-wince*)
os=-wince
;;
-osfrose*)
os=-osfrose
;;
-osf*)
os=-osf
;;
-utek*)
os=-bsd
;;
-dynix*)
os=-bsd
;;
-acis*)
os=-aos
;;
-atheos*)
os=-atheos
;;
-syllable*)
os=-syllable
;;
-386bsd)
os=-bsd
;;
-ctix* | -uts*)
os=-sysv
;;
-nova*)
os=-rtmk-nova
;;
-ns2 )
os=-nextstep2
;;
-nsk*)
os=-nsk
;;
# Preserve the version number of sinix5.
-sinix5.*)
os=`echo $os | sed -e 's|sinix|sysv|'`
;;
-sinix*)
os=-sysv4
;;
-tpf*)
os=-tpf
;;
-triton*)
os=-sysv3
;;
-oss*)
os=-sysv3
;;
-svr4)
os=-sysv4
;;
-svr3)
os=-sysv3
;;
-sysvr4)
os=-sysv4
;;
# This must come after -sysvr4.
-sysv*)
;;
-ose*)
os=-ose
;;
-es1800*)
os=-ose
;;
-xenix)
os=-xenix
;;
-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
os=-mint
;;
-aros*)
os=-aros
;;
-zvmoe)
os=-zvmoe
;;
-dicos*)
os=-dicos
;;
-nacl*)
;;
-none)
;;
*)
# Get rid of the `-' at the beginning of $os.
os=`echo $os | sed 's/[^-]*-//'`
echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
exit 1
;;
esac
else
# Here we handle the default operating systems that come with various machines.
# The value should be what the vendor currently ships out the door with their
# machine or put another way, the most popular os provided with the machine.
# Note that if you're going to try to match "-MANUFACTURER" here (say,
# "-sun"), then you have to tell the case statement up towards the top
# that MANUFACTURER isn't an operating system. Otherwise, code above
# will signal an error saying that MANUFACTURER isn't an operating
# system, and we'll never get to this point.
case $basic_machine in
score-*)
os=-elf
;;
spu-*)
os=-elf
;;
*-acorn)
os=-riscix1.2
;;
arm*-rebel)
os=-linux
;;
arm*-semi)
os=-aout
;;
c4x-* | tic4x-*)
os=-coff
;;
hexagon-*)
os=-elf
;;
tic54x-*)
os=-coff
;;
tic55x-*)
os=-coff
;;
tic6x-*)
os=-coff
;;
# This must come before the *-dec entry.
pdp10-*)
os=-tops20
;;
pdp11-*)
os=-none
;;
*-dec | vax-*)
os=-ultrix4.2
;;
m68*-apollo)
os=-domain
;;
i386-sun)
os=-sunos4.0.2
;;
m68000-sun)
os=-sunos3
;;
m68*-cisco)
os=-aout
;;
mep-*)
os=-elf
;;
mips*-cisco)
os=-elf
;;
mips*-*)
os=-elf
;;
or1k-*)
os=-elf
;;
or32-*)
os=-coff
;;
*-tti) # must be before sparc entry or we get the wrong os.
os=-sysv3
;;
sparc-* | *-sun)
os=-sunos4.1.1
;;
*-be)
os=-beos
;;
*-haiku)
os=-haiku
;;
*-ibm)
os=-aix
;;
*-knuth)
os=-mmixware
;;
*-wec)
os=-proelf
;;
*-winbond)
os=-proelf
;;
*-oki)
os=-proelf
;;
*-hp)
os=-hpux
;;
*-hitachi)
os=-hiux
;;
i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
os=-sysv
;;
*-cbm)
os=-amigaos
;;
*-dg)
os=-dgux
;;
*-dolphin)
os=-sysv3
;;
m68k-ccur)
os=-rtu
;;
m88k-omron*)
os=-luna
;;
*-next )
os=-nextstep
;;
*-sequent)
os=-ptx
;;
*-crds)
os=-unos
;;
*-ns)
os=-genix
;;
i370-*)
os=-mvs
;;
*-next)
os=-nextstep3
;;
*-gould)
os=-sysv
;;
*-highlevel)
os=-bsd
;;
*-encore)
os=-bsd
;;
*-sgi)
os=-irix
;;
*-siemens)
os=-sysv4
;;
*-masscomp)
os=-rtu
;;
f30[01]-fujitsu | f700-fujitsu)
os=-uxpv
;;
*-rom68k)
os=-coff
;;
*-*bug)
os=-coff
;;
*-apple)
os=-macos
;;
*-atari*)
os=-mint
;;
*)
os=-none
;;
esac
fi
# Here we handle the case where we know the os, and the CPU type, but not the
# manufacturer. We pick the logical manufacturer.
vendor=unknown
case $basic_machine in
*-unknown)
case $os in
-riscix*)
vendor=acorn
;;
-sunos*)
vendor=sun
;;
-cnk*|-aix*)
vendor=ibm
;;
-beos*)
vendor=be
;;
-hpux*)
vendor=hp
;;
-mpeix*)
vendor=hp
;;
-hiux*)
vendor=hitachi
;;
-unos*)
vendor=crds
;;
-dgux*)
vendor=dg
;;
-luna*)
vendor=omron
;;
-genix*)
vendor=ns
;;
-mvs* | -opened*)
vendor=ibm
;;
-os400*)
vendor=ibm
;;
-ptx*)
vendor=sequent
;;
-tpf*)
vendor=ibm
;;
-vxsim* | -vxworks* | -windiss*)
vendor=wrs
;;
-aux*)
vendor=apple
;;
-hms*)
vendor=hitachi
;;
-mpw* | -macos*)
vendor=apple
;;
-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
vendor=atari
;;
-vos*)
vendor=stratus
;;
esac
basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
;;
esac
echo $basic_machine$os
exit
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "timestamp='"
# time-stamp-format: "%:y-%02m-%02d"
# time-stamp-end: "'"
# End:
os=-sym1
;;
v810 | necv810)
basic_machine=v810-nec
os=-none
;;
vaxv)
basic_machine=vax-dec
os=-sysv
;;
vms)
basic_machine=vax-dec
os=-vms
;;
vpp*|vx|vx-*)
basic_machine=f301-fujitsu
;;
vxworks960)
basic_machine=i960-wrs
os=-vxworks
;;
vxworks68)
basic_machine=m68k-wrs
os=-vxworklibpciaccess-0.13.2/src/common_bridge.c 0000644 0143106 0000012 00000024045 12172612452 0020247 0 ustar 00alanc staff 0000266 0200005 /*
* (C) Copyright IBM Corporation 2006
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* on the rights to use, copy, modify, merge, publish, distribute, sub
* license, and/or sell copies of the Software, and to permit persons to whom
* the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
/**
* \file common_bridge.c
* Support routines used to process PCI header information for bridges.
*
* \author Ian Romanick
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include
#include
#include
#include
#if defined(HAVE_STRING_H)
# include
#elif defined(HAVE_STRINGS_H)
# include
#endif
#if defined(HAVE_INTTYPES_H)
# include
#elif defined(HAVE_STDINT_H)
# include
#endif
#include "pciaccess.h"
#include "pciaccess_private.h"
static int
read_bridge_info( struct pci_device_private * priv )
{
uint8_t buf[0x40];
pciaddr_t bytes;
int err;
/* Make sure the device has been probed. If not, header_type won't be
* set and the rest of this function will fail.
*/
err = pci_device_probe(& priv->base);
if (err) {
return err;
}
switch ( priv->header_type & 0x7f ) {
case 0x00:
break;
case 0x01: {
struct pci_bridge_info *info;
info = malloc(sizeof(*info));
if (info != NULL) {
pci_device_cfg_read( (struct pci_device *) priv, buf + 0x18, 0x18,
0x40 - 0x18, & bytes );
info->primary_bus = buf[0x18];
info->secondary_bus = buf[0x19];
info->subordinate_bus = buf[0x1a];
info->secondary_latency_timer = buf[0x1b];
info->io_type = buf[0x1c] & 0x0f;
info->io_base = (((uint32_t) (buf[0x1c] & 0x0f0)) << 8)
+ (((uint32_t) buf[0x30]) << 16)
+ (((uint32_t) buf[0x31]) << 24);
info->io_limit = 0x00000fff
+ (((uint32_t) (buf[0x1d] & 0x0f0)) << 8)
+ (((uint32_t) buf[0x32]) << 16)
+ (((uint32_t) buf[0x33]) << 24);
info->mem_type = buf[0x20] & 0x0f;
info->mem_base = (((uint32_t) (buf[0x20] & 0x0f0)) << 16)
+ (((uint32_t) buf[0x21]) << 24);
info->mem_limit = 0x0000ffff
+ (((uint32_t) (buf[0x22] & 0x0f0)) << 16)
+ (((uint32_t) buf[0x23]) << 24);
info->prefetch_mem_type = buf[0x24] & 0x0f;
info->prefetch_mem_base = (((uint64_t) (buf[0x24] & 0x0f0)) << 16)
+ (((uint64_t) buf[0x25]) << 24)
+ (((uint64_t) buf[0x28]) << 32)
+ (((uint64_t) buf[0x29]) << 40)
+ (((uint64_t) buf[0x2a]) << 48)
+ (((uint64_t) buf[0x2b]) << 56);
info->prefetch_mem_limit = 0x0000ffff
+ (((uint64_t) (buf[0x26] & 0x0f0)) << 16)
+ (((uint64_t) buf[0x27]) << 24)
+ (((uint64_t) buf[0x2c]) << 32)
+ (((uint64_t) buf[0x2d]) << 40)
+ (((uint64_t) buf[0x2e]) << 48)
+ (((uint64_t) buf[0x2f]) << 56);
info->bridge_control = ((uint16_t) buf[0x3e])
+ (((uint16_t) buf[0x3f]) << 8);
info->secondary_status = ((uint16_t) buf[0x1e])
+ (((uint16_t) buf[0x1f]) << 8);
}
priv->bridge.pci = info;
break;
}
case 0x02: {
struct pci_pcmcia_bridge_info *info;
info = malloc(sizeof(*info));
if (info != NULL) {
pci_device_cfg_read( (struct pci_device *) priv, buf + 0x16, 0x16,
0x40 - 0x16, & bytes );
info->primary_bus = buf[0x18];
info->card_bus = buf[0x19];
info->subordinate_bus = buf[0x1a];
info->cardbus_latency_timer = buf[0x1b];
info->mem[0].base = (((uint32_t) buf[0x1c]))
+ (((uint32_t) buf[0x1d]) << 8)
+ (((uint32_t) buf[0x1e]) << 16)
+ (((uint32_t) buf[0x1f]) << 24);
info->mem[0].limit = (((uint32_t) buf[0x20]))
+ (((uint32_t) buf[0x21]) << 8)
+ (((uint32_t) buf[0x22]) << 16)
+ (((uint32_t) buf[0x23]) << 24);
info->mem[1].base = (((uint32_t) buf[0x24]))
+ (((uint32_t) buf[0x25]) << 8)
+ (((uint32_t) buf[0x26]) << 16)
+ (((uint32_t) buf[0x27]) << 24);
info->mem[1].limit = (((uint32_t) buf[0x28]))
+ (((uint32_t) buf[0x29]) << 8)
+ (((uint32_t) buf[0x2a]) << 16)
+ (((uint32_t) buf[0x2b]) << 24);
info->io[0].base = (((uint32_t) buf[0x2c]))
+ (((uint32_t) buf[0x2d]) << 8)
+ (((uint32_t) buf[0x2e]) << 16)
+ (((uint32_t) buf[0x2f]) << 24);
info->io[0].limit = (((uint32_t) buf[0x30]))
+ (((uint32_t) buf[0x31]) << 8)
+ (((uint32_t) buf[0x32]) << 16)
+ (((uint32_t) buf[0x33]) << 24);
info->io[1].base = (((uint32_t) buf[0x34]))
+ (((uint32_t) buf[0x35]) << 8)
+ (((uint32_t) buf[0x36]) << 16)
+ (((uint32_t) buf[0x37]) << 24);
info->io[1].limit = (((uint32_t) buf[0x38]))
+ (((uint32_t) buf[0x39]) << 8)
+ (((uint32_t) buf[0x3a]) << 16)
+ (((uint32_t) buf[0x3b]) << 24);
info->secondary_status = ((uint16_t) buf[0x16])
+ (((uint16_t) buf[0x17]) << 8);
info->bridge_control = ((uint16_t) buf[0x3e])
+ (((uint16_t) buf[0x3f]) << 8);
}
priv->bridge.pcmcia = info;
break;
}
}
return 0;
}
/**
* Get the PCI bridge information for a device
*
* \returns
* If \c dev is a PCI-to-PCI bridge, a pointer to a \c pci_bridge_info
* structure. Otherwise, \c NULL is returned.
*/
const struct pci_bridge_info *
pci_device_get_bridge_info( struct pci_device * dev )
{
struct pci_device_private * priv = (struct pci_device_private *) dev;
if (priv->bridge.pci == NULL) {
read_bridge_info(priv);
}
return (priv->header_type == 1) ? priv->bridge.pci : NULL;
}
/**
* Get the PCMCIA bridge information for a device
*
* \returns
* If \c dev is a PCI-to-PCMCIA bridge, a pointer to a
* \c pci_pcmcia_bridge_info structure. Otherwise, \c NULL is returned.
*/
const struct pci_pcmcia_bridge_info *
pci_device_get_pcmcia_bridge_info( struct pci_device * dev )
{
struct pci_device_private * priv = (struct pci_device_private *) dev;
if (priv->bridge.pcmcia == NULL) {
read_bridge_info(priv);
}
return (priv->header_type == 2) ? priv->bridge.pcmcia : NULL;
}
/**
* Determine the primary, secondary, and subordinate buses for a bridge
*
* Determines the IDs of the primary, secondary, and subordinate buses for
* a specified bridge. Not all bridges directly store this information
* (e.g., PCI-to-ISA bridges). For those bridges, no error is returned, but
* -1 is stored in the bus IDs that don't make sense.
*
* For example, for a PCI-to-ISA bridge, \c primary_bus will be set to the ID
* of the bus containing the device and both \c secondary_bus and
* \c subordinate_bus will be set to -1.
*
* \return
* On success, zero is returned. If \c dev is not a bridge, \c ENODEV is
* returned.
*
* \bug
* Host bridges are handled the same way as PCI-to-ISA bridges. This is
* almost certainly not correct.
*/
int
pci_device_get_bridge_buses(struct pci_device * dev, int *primary_bus,
int *secondary_bus, int *subordinate_bus)
{
struct pci_device_private * priv = (struct pci_device_private *) dev;
/* If the device isn't a bridge, return an error.
*/
if (((dev->device_class >> 16) & 0x0ff) != 0x06) {
return ENODEV;
}
switch ((dev->device_class >> 8) & 0x0ff) {
case 0x00:
/* What to do for host bridges? I'm pretty sure this isn't right.
*/
*primary_bus = dev->bus;
*secondary_bus = -1;
*subordinate_bus = -1;
break;
case 0x01:
case 0x02:
case 0x03:
*primary_bus = dev->bus;
*secondary_bus = -1;
*subordinate_bus = -1;
break;
case 0x04:
if (priv->bridge.pci == NULL)
read_bridge_info(priv);
if ((priv->header_type & 0x7f) == 0x01) {
*primary_bus = priv->bridge.pci->primary_bus;
*secondary_bus = priv->bridge.pci->secondary_bus;
*subordinate_bus = priv->bridge.pci->subordinate_bus;
} else {
*primary_bus = dev->bus;
*secondary_bus = -1;
*subordinate_bus = -1;
}
break;
case 0x07:
if (priv->bridge.pcmcia == NULL)
read_bridge_info(priv);
if ((priv->header_type & 0x7f) == 0x02) {
*primary_bus = priv->bridge.pcmcia->primary_bus;
*secondary_bus = priv->bridge.pcmcia->card_bus;
*subordinate_bus = priv->bridge.pcmcia->subordinate_bus;
} else {
*primary_bus = dev->bus;
*secondary_bus = -1;
*subordinate_bus = -1;
}
break;
}
return 0;
}
#define PCI_CLASS_BRIDGE 0x06
#define PCI_SUBCLASS_BRIDGE_PCI 0x04
#define PCI_CLASS_MASK 0xFF
#define PCI_SUBCLASS_MASK 0xFF
struct pci_device *
pci_device_get_parent_bridge(struct pci_device *dev)
{
struct pci_id_match bridge_match = {
PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY,
(PCI_CLASS_BRIDGE << 16) | (PCI_SUBCLASS_BRIDGE_PCI << 8),
(PCI_CLASS_MASK << 16) | (PCI_SUBCLASS_MASK << 8)
};
struct pci_device *bridge;
struct pci_device_iterator *iter;
if (dev == NULL)
return NULL;
iter = pci_id_match_iterator_create(& bridge_match);
if (iter == NULL)
return NULL;
while ((bridge = pci_device_next(iter)) != NULL) {
if (bridge->domain == dev->domain) {
const struct pci_bridge_info *info =
pci_device_get_bridge_info(bridge);
if (info != NULL) {
if (info->secondary_bus == dev->bus) {
break;
}
}
}
}
pci_iterator_destroy(iter);
return bridge;
}
libpciaccess-0.13.2/src/common_device_name.c 0000644 0143106 0000012 00000030204 12172612452 0021244 0 ustar 00alanc staff 0000266 0200005 /*
* (C) Copyright IBM Corporation 2006
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* on the rights to use, copy, modify, merge, publish, distribute, sub
* license, and/or sell copies of the Software, and to permit persons to whom
* the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
/**
* \file common_device_name.c
* Support routines used to determine the vendor or device names associated
* with a particular device or vendor.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include
#include
#include
#if defined(HAVE_STRING_H)
# include
#elif defined(HAVE_STRINGS_H)
# include
#endif
#if defined(HAVE_INTTYPES_H)
# include
#elif defined(HAVE_STDINT_H)
# include
#endif
#include "pciaccess.h"
#include "pciaccess_private.h"
#define DO_MATCH(a,b) (((a) == PCI_MATCH_ANY) || ((a) == (b)))
#ifdef HAVE_ZLIB
#include
typedef gzFile pci_id_file;
static pci_id_file
pci_id_file_open(void)
{
pci_id_file result;
result = gzopen(PCIIDS_PATH "/pci.ids.gz", "rb");
if (result)
return result;
return gzopen(PCIIDS_PATH "/pci.ids", "rb");
}
#define pci_id_file_gets(l, s, f) gzgets(f, l, s)
#define pci_id_file_close(f) gzclose(f)
#else /* not zlib */
typedef FILE * pci_id_file;
static pci_id_file
pci_id_file_open(void)
{
#ifndef __sun
pci_id_file result;
result = fopen(PCIIDS_PATH "/pci.ids", "re");
if (result)
return result;
#endif
return fopen(PCIIDS_PATH "/pci.ids", "r");
}
#define pci_id_file_gets(l, s, f) fgets(l, s, f)
#define pci_id_file_close(f) fclose(f)
#endif
/**
* Node for sorting vendor IDs.
*
* Each structure forms an internal node of an n-way tree. Each node selects
* \c pci_id_node::bits number of bits from the vendor ID. Starting from the
* root of the tree, a slice of the low-order bits of the vendor ID are
* selected and used as an index into the \c pci_id_node::children array.
*
* At the leaf nodes (i.e., the node entered when all 16 bits of the vendor ID
* have been used), the \c pci_id_node::children is actually an array of
* pointers to \c pci_id_leaf structures.
*
* \todo
* Determine if there is a cleaner way (in the source code) to have the
* \c children array change type based on whether the node is internal or
* a leaf.
*
* \todo
* Currently \c bits is always 4. Decide if this value can ever change
* (i.e., to pull-up levels of the n-way tree when all the children's children
* are full). If it can, rip it out and hard-code it to 4 everywhere.
*/
struct pci_id_node {
unsigned bits;
struct pci_id_node * children[16];
};
struct pci_id_leaf {
uint16_t vendor;
const char * vendor_name;
size_t num_devices;
struct pci_device_leaf * devices;
};
struct pci_device_leaf {
struct pci_id_match id;
const char * device_name;
};
/**
* Root of the PCI vendor ID search tree.
*/
_pci_hidden struct pci_id_node * tree = NULL;
/**
* Get a pointer to the leaf node for a vendor ID.
*
* If the vendor ID does not exist in the tree, it is added.
*/
static struct pci_id_leaf *
insert( uint16_t vendor )
{
struct pci_id_node * n;
unsigned bits = 0;
if ( tree == NULL ) {
tree = calloc( 1, sizeof( struct pci_id_node ) );
tree->bits = 4;
}
n = tree;
while ( n != NULL ) {
const unsigned used_bits = n->bits;
const unsigned mask = (1 << used_bits) - 1;
const unsigned idx = (vendor & (mask << bits)) >> bits;
if ( bits >= 16 ) {
break;
}
bits += used_bits;
if ( n->children[ idx ] == NULL ) {
if ( bits < 16 ) {
struct pci_id_node * child =
calloc( 1, sizeof( struct pci_id_node ) );
child->bits = 4;
n->children[ idx ] = child;
}
else {
struct pci_id_leaf * leaf =
calloc( 1, sizeof( struct pci_id_leaf ) );
leaf->vendor = vendor;
n->children[ idx ] = (struct pci_id_node *) leaf;
}
}
n = n->children[ idx ];
}
return (struct pci_id_leaf *) n;
}
/**
* Populate a vendor node with all the devices associated with that vendor
*
* \param vend Vendor node that is to be filled from the pci.ids file.
*
* \todo
* The parsing in this function should be more rhobust. There are some error
* cases (i.e., a 0-tab line followed by a 2-tab line) that aren't handled
* correctly. I don't think there are any security problems with the code,
* but it's not impossible.
*/
static void
populate_vendor( struct pci_id_leaf * vend, int fill_device_data )
{
pci_id_file f;
char buf[128];
unsigned vendor = PCI_MATCH_ANY;
/* If the device tree for this vendor is already populated, don't do
* anything. This avoids wasted processing and potential memory leaks.
*/
if (vend->num_devices != 0) {
return;
}
f = pci_id_file_open();
/* If the pci.ids file could not be opened, there's nothing we can do.
*/
if (f == NULL) {
return;
}
while( pci_id_file_gets( buf, sizeof( buf ), f ) != NULL ) {
unsigned num_tabs;
char * new_line;
size_t length;
/* Each line either starts with zero, one, or two tabs followed by
* a series of 4 hex digits. Any lines not matching that are ignored.
*/
for ( num_tabs = 0 ; num_tabs < 3 ; num_tabs++ ) {
if ( buf[ num_tabs ] != '\t' ) {
break;
}
}
if ( !isxdigit( buf[ num_tabs + 0 ] )
|| !isxdigit( buf[ num_tabs + 1 ] )
|| !isxdigit( buf[ num_tabs + 2 ] )
|| !isxdigit( buf[ num_tabs + 3 ] ) ) {
continue;
}
new_line = strchr( buf, '\n' );
if ( new_line != NULL ) {
*new_line = '\0';
}
length = strlen( buf );
(void) memset( buf + length, 0, sizeof( buf ) - length );
if ( num_tabs == 0 ) {
vendor = (unsigned) strtoul( & buf[ num_tabs ], NULL, 16 );
if ( vend->vendor == vendor ) {
/* vendor_name may already be set from a previous invocation
* of this function with fill_device_data = 0.
*/
if (vend->vendor_name == NULL) {
vend->vendor_name = strdup( & buf[ num_tabs + 6 ] );
}
/* If we're not going to fill in all of the device data as
* well, then bail out now. We have all the information that
* we need.
*/
if ( ! fill_device_data ) {
break;
}
}
}
else if ( vendor == vend->vendor ) {
struct pci_device_leaf * d;
struct pci_device_leaf * dev;
struct pci_device_leaf * last_dev;
d = realloc( vend->devices, (vend->num_devices + 1)
* sizeof( struct pci_device_leaf ) );
if ( d == NULL ) {
goto cleanup;
}
last_dev = & d[ vend->num_devices - 1 ];
dev = & d[ vend->num_devices ];
vend->num_devices++;
vend->devices = d;
if ( num_tabs == 1 ) {
dev->id.vendor_id = vend->vendor;
dev->id.device_id = (unsigned) strtoul( & buf[ num_tabs ],
NULL, 16 );
dev->id.subvendor_id = PCI_MATCH_ANY;
dev->id.subdevice_id = PCI_MATCH_ANY;
dev->id.device_class = 0;
dev->id.device_class_mask = 0;
dev->id.match_data = 0;
dev->device_name = strdup( & buf[ num_tabs + 6 ] );
}
else {
dev->id = last_dev->id;
dev->id.subvendor_id= (unsigned) strtoul( & buf[ num_tabs ],
NULL, 16 );
dev->id.subdevice_id = (unsigned) strtoul( & buf[ num_tabs + 5 ],
NULL, 16 );
dev->device_name = strdup( & buf[ num_tabs + 5 + 6 ] );
}
}
}
cleanup:
pci_id_file_close( f );
}
/**
* Find the name of the specified device.
*
* Finds the actual product name of the specified device. If a subvendor ID
* and subdevice ID are specified in \c m, the returned name will be the name
* of the subdevice.
*/
static const char *
find_device_name( const struct pci_id_match * m )
{
struct pci_id_leaf * vend;
unsigned i;
if ( m->vendor_id == PCI_MATCH_ANY ) {
return NULL;
}
vend = insert( m->vendor_id );
if ( vend == NULL ) {
return NULL;
}
if ( vend->num_devices == 0 ) {
populate_vendor( vend, 1 );
}
for ( i = 0 ; i < vend->num_devices ; i++ ) {
struct pci_device_leaf * d = & vend->devices[ i ];
if ( DO_MATCH( m->vendor_id, d->id.vendor_id )
&& DO_MATCH( m->device_id, d->id.device_id )
&& DO_MATCH( m->subvendor_id, d->id.subvendor_id )
&& DO_MATCH( m->subdevice_id, d->id.subdevice_id ) ) {
return d->device_name;
}
}
return NULL;
}
/**
* Find the vendor name of the specified device.
*
* Finds the actual vendor name of the specified device. If a subvendor ID
* and subdevice ID are specified in \c m, the returned name will be the name
* associated with the subvendor.
*/
static const char *
find_vendor_name( const struct pci_id_match * m )
{
struct pci_id_leaf * vend;
if ( m->vendor_id == PCI_MATCH_ANY ) {
return NULL;
}
vend = insert( m->vendor_id );
if ( vend == NULL ) {
return NULL;
}
if ( vend->vendor_name == NULL ) {
populate_vendor( vend, 0 );
}
return vend->vendor_name;
}
/**
* Get a name based on an arbitrary PCI search structure.
*/
void
pci_get_strings( const struct pci_id_match * m,
const char ** device_name,
const char ** vendor_name,
const char ** subdevice_name,
const char ** subvendor_name )
{
struct pci_id_match temp;
temp = *m;
temp.subvendor_id = PCI_MATCH_ANY;
temp.subdevice_id = PCI_MATCH_ANY;
if ( device_name != NULL ) {
*device_name = find_device_name( & temp );
}
if ( vendor_name != NULL ) {
*vendor_name = find_vendor_name( & temp );
}
if ( subdevice_name != NULL ) {
*subdevice_name = find_device_name( m );
}
if ( subvendor_name != NULL ) {
*subvendor_name = find_vendor_name( m );
}
}
/**
* Get the name associated with the device's primary device ID.
*/
const char *
pci_device_get_device_name( const struct pci_device * dev )
{
struct pci_id_match m;
m.vendor_id = dev->vendor_id;
m.device_id = dev->device_id;
m.subvendor_id = PCI_MATCH_ANY;
m.subdevice_id = PCI_MATCH_ANY;
m.device_class = 0;
m.device_class_mask = 0;
m.match_data = 0;
return find_device_name( & m );
}
/**
* Get the name associated with the device's subdevice ID.
*/
const char *
pci_device_get_subdevice_name( const struct pci_device * dev )
{
struct pci_id_match m;
if ( (dev->subvendor_id == 0) || (dev->subdevice_id == 0) ) {
return NULL;
}
m.vendor_id = dev->vendor_id;
m.device_id = dev->device_id;
m.subvendor_id = dev->subvendor_id;
m.subdevice_id = dev->subdevice_id;
m.device_class = 0;
m.device_class_mask = 0;
m.match_data = 0;
return find_device_name( & m );
}
/**
* Get the name associated with the device's primary vendor ID.
*/
const char *
pci_device_get_vendor_name( const struct pci_device * dev )
{
struct pci_id_match m;
m.vendor_id = dev->vendor_id;
m.device_id = PCI_MATCH_ANY;
m.subvendor_id = PCI_MATCH_ANY;
m.subdevice_id = PCI_MATCH_ANY;
m.device_class = 0;
m.device_class_mask = 0;
m.match_data = 0;
return find_vendor_name( & m );
}
/**
* Get the name associated with the device's subvendor ID.
*/
const char *
pci_device_get_subvendor_name( const struct pci_device * dev )
{
struct pci_id_match m;
if ( dev->subvendor_id == 0 ) {
return NULL;
}
m.vendor_id = dev->subvendor_id;
m.device_id = PCI_MATCH_ANY;
m.subvendor_id = PCI_MATCH_ANY;
m.subdevice_id = PCI_MATCH_ANY;
m.device_class = 0;
m.device_class_mask = 0;
m.match_data = 0;
return find_vendor_name( & m );
}
FILE * pci_id_file;
static pci_id_file
pci_id_file_open(void)
{
#ifndef __sun
pci_id_file result;
result = fopen(PCIIDS_PATH "/pci.ids", "re");
if (result)
return result;
#endif
return fopen(PCIIDS_PATH "/pci.ids", "r");
}
#define pci_id_file_gets(l, s, f) fgets(l, s, f)
#define pci_id_file_close(f) fclose(f)
#endif
/**
* Node for sorting vendorlibpciaccess-0.13.2/src/common_capability.c 0000644 0143106 0000012 00000012673 12172612452 0021140 0 ustar 00alanc staff 0000266 0200005 /*
* (C) Copyright IBM Corporation 2006
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* on the rights to use, copy, modify, merge, publish, distribute, sub
* license, and/or sell copies of the Software, and to permit persons to whom
* the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
/**
* \file common_capability.c
* Platform independent PCI capability related routines.
*
* In addition to including the interface glue for \c pci_device_get_agp_info,
* this file also contains a generic implementation of that function.
*
* \author Ian Romanick
*/
#include
#include
#include
#include "pciaccess.h"
#include "pciaccess_private.h"
/**
* Generic implementation of \c pci_system_methods::fill_capabilities.
*
* \param dev Device whose capability information is to be processed.
*
* \return
* Zero on success or an errno value on failure.
*
* \todo
* Once more than just the AGP capability is supported, the body of each of
* the cases in the capability processing loop should probably be broken out
* into its own function.
*
* \todo
* Once more than just the AGP capability is supported, some care will need
* to be taken in partial failure cases. If, say, the first capability is
* correctly processed but the second fails, the function would be re-called
* later to try again for the second capability. This could lead to memory
* leaks or other quirky behavior.
*/
_pci_hidden int
pci_fill_capabilities_generic( struct pci_device * dev )
{
struct pci_device_private * const dev_priv =
(struct pci_device_private *) dev;
int err;
uint16_t status;
uint8_t cap_offset;
err = pci_device_cfg_read_u16( dev, & status, 6 );
if ( err ) {
return err;
}
/* Are PCI capabilities supported by this device?
*/
if ( (status & 0x0010) == 0 ) {
return ENOSYS;
}
err = pci_device_cfg_read_u8( dev, & cap_offset, 52 );
if ( err ) {
return err;
}
/* Process each of the capabilities list in the PCI header.
*/
while ( cap_offset != 0 ) {
uint8_t cap_id;
uint8_t next_cap;
err = pci_device_cfg_read_u8( dev, & cap_id, cap_offset );
if ( err ) {
return err;
}
err = pci_device_cfg_read_u8( dev, & next_cap, cap_offset + 1 );
if ( err ) {
return err;
}
switch ( cap_id ) {
case 2: {
struct pci_agp_info * agp_info;
uint32_t agp_status;
uint8_t agp_ver;
err = pci_device_cfg_read_u8( dev, & agp_ver, cap_offset + 2 );
if ( err ) {
return err;
}
err = pci_device_cfg_read_u32( dev, & agp_status, cap_offset + 4 );
if ( err ) {
return err;
}
agp_info = calloc( 1, sizeof( struct pci_agp_info ) );
if ( agp_info == NULL ) {
return ENOMEM;
}
agp_info->config_offset = cap_offset;
agp_info->major_version = (agp_ver & 0x0f0) >> 4;
agp_info->minor_version = (agp_ver & 0x00f);
agp_info->rates = (agp_status & 0x07);
/* If AGP3 is supported, then the meaning of the rates values
* changes.
*/
if ( (agp_status & 0x08) != 0 ) {
agp_info->rates <<= 2;
}
/* Some devices, notably motherboard chipsets, have the AGP3
* capability set and the 4x bit set. This results in an
* impossible 16x mode being listed as available. I'm not 100%
* sure this is the right solution.
*/
agp_info->rates &= 0x0f;
agp_info->fast_writes = (agp_status & 0x0010) != 0;
agp_info->addr64 = (agp_status & 0x0020) != 0;
agp_info->htrans = (agp_status & 0x0040) == 0;
agp_info->gart64 = (agp_status & 0x0080) != 0;
agp_info->coherent = (agp_status & 0x0100) != 0;
agp_info->sideband = (agp_status & 0x0200) != 0;
agp_info->isochronus = (agp_status & 0x10000) != 0;
agp_info->async_req_size = 4 + (1 << ((agp_status & 0xe000) >> 13));
agp_info->calibration_cycle_timing = ((agp_status & 0x1c00) >> 10);
agp_info->max_requests = 1 + ((agp_status & 0xff000000) >> 24);
dev_priv->agp = agp_info;
break;
}
/* No other capabilities are currently handled.
*/
default:
printf( "Unknown cap 0x%02x @ 0x%02x\n", cap_id, cap_offset );
break;
}
cap_offset = next_cap;
}
return 0;
}
/**
* Get AGP capability data for a device.
*/
const struct pci_agp_info *
pci_device_get_agp_info( struct pci_device * dev )
{
struct pci_device_private * dev_priv = (struct pci_device_private *) dev;
if ( dev == NULL ) {
return NULL;
}
if ( dev_priv->agp == NULL ) {
(void) (*pci_sys->methods->fill_capabilities)( dev );
}
return dev_priv->agp;
}
libpciaccess-0.13.2/src/x86_pci.c 0000644 0143106 0000012 00000041553 12172612452 0016726 0 ustar 00alanc staff 0000266 0200005 /*
* Copyright (c) 2009, 2012 Samuel Thibault
* Heavily inspired from the freebsd, netbsd, and openbsd backends
* (C) Copyright Eric Anholt 2006
* (C) Copyright IBM Corporation 2006
* Copyright (c) 2008 Juan Romero Pardines
* Copyright (c) 2008 Mark Kettenis
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#define _GNU_SOURCE
#include
#include
#include
#include
#include
#include
#include
#include
#include "pciaccess.h"
#include "pciaccess_private.h"
#if defined(__GNU__)
#include
static int
x86_enable_io(void)
{
if (!ioperm(0, 0xffff, 1))
return 0;
return errno;
}
static int
x86_disable_io(void)
{
if (!ioperm(0, 0xffff, 0))
return 0;
return errno;
}
#elif defined(__GLIBC__)
#include
static int
x86_enable_io(void)
{
if (!iopl(3))
return 0;
return errno;
}
static int
x86_disable_io(void)
{
if (!iopl(0))
return 0;
return errno;
}
#else
#error How to enable IO ports on this system?
#endif
#define PCI_VENDOR(reg) ((reg) & 0xFFFF)
#define PCI_VENDOR_INVALID 0xFFFF
#define PCI_VENDOR_ID 0x00
#define PCI_SUB_VENDOR_ID 0x2c
#define PCI_VENDOR_ID_COMPAQ 0x0e11
#define PCI_VENDOR_ID_INTEL 0x8086
#define PCI_DEVICE(reg) (((reg) >> 16) & 0xFFFF)
#define PCI_DEVICE_INVALID 0xFFFF
#define PCI_CLASS 0x08
#define PCI_CLASS_DEVICE 0x0a
#define PCI_CLASS_DISPLAY_VGA 0x0300
#define PCI_CLASS_BRIDGE_HOST 0x0600
#define PCIC_DISPLAY 0x03
#define PCIS_DISPLAY_VGA 0x00
#define PCI_HDRTYPE 0x0E
#define PCI_IRQ 0x3C
struct pci_system_x86 {
struct pci_system system;
int (*read)(unsigned bus, unsigned dev, unsigned func, pciaddr_t reg, void *data, unsigned size);
int (*write)(unsigned bus, unsigned dev, unsigned func, pciaddr_t reg, const void *data, unsigned size);
};
static int
pci_system_x86_conf1_probe(void)
{
unsigned long sav;
int res = ENODEV;
outb(0x01, 0xCFB);
sav = inl(0xCF8);
outl(0x80000000, 0xCF8);
if (inl(0xCF8) == 0x80000000)
res = 0;
outl(sav, 0xCF8);
return res;
}
static int
pci_system_x86_conf1_read(unsigned bus, unsigned dev, unsigned func, pciaddr_t reg, void *data, unsigned size)
{
unsigned addr = 0xCFC + (reg & 3);
unsigned long sav;
int ret = 0;
if (bus >= 0x100 || dev >= 32 || func >= 8 || reg >= 0x100 || size > 4 || size == 3)
return EIO;
sav = inl(0xCF8);
outl(0x80000000 | (bus << 16) | (dev << 11) | (func << 8) | (reg & ~3), 0xCF8);
/* NOTE: x86 is already LE */
switch (size) {
case 1: {
uint8_t *val = data;
*val = inb(addr);
break;
}
case 2: {
uint16_t *val = data;
*val = inw(addr);
break;
}
case 4: {
uint32_t *val = data;
*val = inl(addr);
break;
}
}
outl(sav, 0xCF8);
return ret;
}
static int
pci_system_x86_conf1_write(unsigned bus, unsigned dev, unsigned func, pciaddr_t reg, const void *data, unsigned size)
{
unsigned addr = 0xCFC + (reg & 3);
unsigned long sav;
int ret = 0;
if (bus >= 0x100 || dev >= 32 || func >= 8 || reg >= 0x100 || size > 4 || size == 3)
return EIO;
sav = inl(0xCF8);
outl(0x80000000 | (bus << 16) | (dev << 11) | (func << 8) | (reg & ~3), 0xCF8);
/* NOTE: x86 is already LE */
switch (size) {
case 1: {
const uint8_t *val = data;
outb(*val, addr);
break;
}
case 2: {
const uint16_t *val = data;
outw(*val, addr);
break;
}
case 4: {
const uint32_t *val = data;
outl(*val, addr);
break;
}
}
outl(sav, 0xCF8);
return ret;
}
static int
pci_system_x86_conf2_probe(void)
{
outb(0, 0xCFB);
outb(0, 0xCF8);
outb(0, 0xCFA);
if (inb(0xCF8) == 0 && inb(0xCFA) == 0)
return 0;
return ENODEV;
}
static int
pci_system_x86_conf2_read(unsigned bus, unsigned dev, unsigned func, pciaddr_t reg, void *data, unsigned size)
{
unsigned addr = 0xC000 | dev << 8 | reg;
int ret = 0;
if (bus >= 0x100 || dev >= 16 || func >= 8 || reg >= 0x100)
return EIO;
outb((func << 1) | 0xF0, 0xCF8);
outb(bus, 0xCFA);
/* NOTE: x86 is already LE */
switch (size) {
case 1: {
uint8_t *val = data;
*val = inb(addr);
break;
}
case 2: {
uint16_t *val = data;
*val = inw(addr);
break;
}
case 4: {
uint32_t *val = data;
*val = inl(addr);
break;
}
default:
ret = EIO;
break;
}
outb(0, 0xCF8);
return ret;
}
static int
pci_system_x86_conf2_write(unsigned bus, unsigned dev, unsigned func, pciaddr_t reg, const void *data, unsigned size)
{
unsigned addr = 0xC000 | dev << 8 | reg;
int ret = 0;
if (bus >= 0x100 || dev >= 16 || func >= 8 || reg >= 0x100)
return EIO;
outb((func << 1) | 0xF0, 0xCF8);
outb(bus, 0xCFA);
/* NOTE: x86 is already LE */
switch (size) {
case 1: {
const uint8_t *val = data;
outb(*val, addr);
break;
}
case 2: {
const uint16_t *val = data;
outw(*val, addr);
break;
}
case 4: {
const uint32_t *val = data;
outl(*val, addr);
break;
}
default:
ret = EIO;
break;
}
outb(0, 0xCF8);
return ret;
}
/* Check that this really looks like a PCI configuration. */
static int
pci_system_x86_check(struct pci_system_x86 *pci_sys_x86)
{
int dev;
uint16_t class, vendor;
/* Look on bus 0 for a device that is a host bridge, a VGA card,
* or an intel or compaq device. */
for (dev = 0; dev < 32; dev++) {
if (pci_sys_x86->read(0, dev, 0, PCI_CLASS_DEVICE, &class, sizeof(class)))
continue;
if (class == PCI_CLASS_BRIDGE_HOST || class == PCI_CLASS_DISPLAY_VGA)
return 0;
if (pci_sys_x86->read(0, dev, 0, PCI_VENDOR_ID, &vendor, sizeof(vendor)))
continue;
if (vendor == PCI_VENDOR_ID_INTEL || class == PCI_VENDOR_ID_COMPAQ)
return 0;
}
return ENODEV;
}
static int
pci_nfuncs(struct pci_system_x86 *pci_sys_x86, int bus, int dev)
{
uint8_t hdr;
int err;
err = pci_sys_x86->read(bus, dev, 0, PCI_HDRTYPE, &hdr, sizeof(hdr));
if (err)
return err;
return hdr & 0x80 ? 8 : 1;
}
/**
* Read a VGA rom using the 0xc0000 mapping.
*/
static int
pci_device_x86_read_rom(struct pci_device *dev, void *buffer)
{
void *bios;
int memfd;
if ((dev->device_class & 0x00ffff00) !=
((PCIC_DISPLAY << 16) | ( PCIS_DISPLAY_VGA << 8))) {
return ENOSYS;
}
memfd = open("/dev/mem", O_RDONLY | O_CLOEXEC);
if (memfd == -1)
return errno;
bios = mmap(NULL, dev->rom_size, PROT_READ, 0, memfd, 0xc0000);
if (bios == MAP_FAILED) {
close(memfd);
return errno;
}
memcpy(buffer, bios, dev->rom_size);
munmap(bios, dev->rom_size);
close(memfd);
return 0;
}
/** Returns the number of regions (base address registers) the device has */
static int
pci_device_x86_get_num_regions(uint8_t header_type)
{
switch (header_type & 0x7f) {
case 0:
return 6;
case 1:
return 2;
case 2:
return 1;
default:
fprintf(stderr,"unknown header type %02x\n", header_type);
return 0;
}
}
/** Masks out the flag bigs of the base address register value */
static uint32_t
get_map_base( uint32_t val )
{
if (val & 0x01)
return val & ~0x03;
else
return val & ~0x0f;
}
/** Returns the size of a region based on the all-ones test value */
static unsigned
get_test_val_size( uint32_t testval )
{
unsigned size = 1;
if (testval == 0)
return 0;
/* Mask out the flag bits */
testval = get_map_base( testval );
if (!testval)
return 0;
while ((testval & 1) == 0) {
size <<= 1;
testval >>= 1;
}
return size;
}
static int
pci_device_x86_probe(struct pci_device *dev)
{
uint8_t irq, hdrtype;
int err, i, bar;
/* Many of the fields were filled in during initial device enumeration.
* At this point, we need to fill in regions, rom_size, and irq.
*/
err = pci_device_cfg_read_u8(dev, &irq, PCI_IRQ);
if (err)
return err;
dev->irq = irq;
err = pci_device_cfg_read_u8(dev, &hdrtype, PCI_HDRTYPE);
if (err)
return err;
bar = 0x10;
for (i = 0; i < pci_device_x86_get_num_regions(hdrtype); i++, bar += 4) {
uint32_t addr, testval;
/* Get the base address */
err = pci_device_cfg_read_u32(dev, &addr, bar);
if (err != 0)
continue;
/* Test write all ones to the register, then restore it. */
err = pci_device_cfg_write_u32(dev, 0xffffffff, bar);
if (err != 0)
continue;
pci_device_cfg_read_u32(dev, &testval, bar);
err = pci_device_cfg_write_u32(dev, addr, bar);
if (addr & 0x01)
dev->regions[i].is_IO = 1;
if (addr & 0x04)
dev->regions[i].is_64 = 1;
if (addr & 0x08)
dev->regions[i].is_prefetchable = 1;
/* Set the size */
dev->regions[i].size = get_test_val_size(testval);
/* Set the base address value */
if (dev->regions[i].is_64) {
uint32_t top;
err = pci_device_cfg_read_u32(dev, &top, bar + 4);
if (err != 0)
continue;
dev->regions[i].base_addr = ((uint64_t)top << 32) |
get_map_base(addr);
bar += 4;
i++;
} else {
dev->regions[i].base_addr = get_map_base(addr);
}
}
/* If it's a VGA device, set up the rom size for read_rom using the
* 0xc0000 mapping.
*/
if ((dev->device_class & 0x00ffff00) ==
((PCIC_DISPLAY << 16) | (PCIS_DISPLAY_VGA << 8)))
{
dev->rom_size = 64 * 1024;
}
return 0;
}
static int
pci_device_x86_map_range(struct pci_device *dev,
struct pci_device_mapping *map)
{
int memfd = open("/dev/mem", O_RDWR | O_CLOEXEC);
int prot = PROT_READ;
if (memfd == -1)
return errno;
if (map->flags & PCI_DEV_MAP_FLAG_WRITABLE)
prot |= PROT_WRITE;
map->memory = mmap(NULL, map->size, prot, MAP_SHARED, memfd, map->base);
close(memfd);
if (map->memory == MAP_FAILED)
return errno;
return 0;
}
static int
pci_device_x86_read(struct pci_device *dev, void *data,
pciaddr_t offset, pciaddr_t size, pciaddr_t *bytes_read)
{
struct pci_system_x86 *pci_sys_x86 = (struct pci_system_x86 *) pci_sys;
int err;
*bytes_read = 0;
while (size > 0) {
int toread = 1 << (ffs(0x4 + (offset & 0x03)) - 1);
if (toread > size)
toread = size;
err = pci_sys_x86->read(dev->bus, dev->dev, dev->func, offset, data, toread);
if (err)
return err;
offset += toread;
data = (char*)data + toread;
size -= toread;
*bytes_read += toread;
}
return 0;
}
static int
pci_device_x86_write(struct pci_device *dev, const void *data,
pciaddr_t offset, pciaddr_t size, pciaddr_t *bytes_written)
{
struct pci_system_x86 *pci_sys_x86 = (struct pci_system_x86 *) pci_sys;
int err;
*bytes_written = 0;
while (size > 0) {
int towrite = 4;
if (towrite > size)
towrite = size;
if (towrite > 4 - (offset & 0x3))
towrite = 4 - (offset & 0x3);
err = pci_sys_x86->write(dev->bus, dev->dev, dev->func, offset, data, towrite);
if (err)
return err;
offset += towrite;
data = (const char*)data + towrite;
size -= towrite;
*bytes_written += towrite;
}
return 0;
}
static void
pci_system_x86_destroy(void)
{
x86_disable_io();
}
static struct pci_io_handle *
pci_device_x86_open_legacy_io(struct pci_io_handle *ret,
struct pci_device *dev, pciaddr_t base, pciaddr_t size)
{
x86_enable_io();
ret->base = base;
ret->size = size;
return ret;
}
static void
pci_device_x86_close_io(struct pci_device *dev, struct pci_io_handle *handle)
{
/* Like in the Linux case, do not disable I/O, as it may be opened several
* times, and closed fewer times. */
/* x86_disable_io(); */
}
static uint32_t
pci_device_x86_read32(struct pci_io_handle *handle, uint32_t reg)
{
return inl(reg + handle->base);
}
static uint16_t
pci_device_x86_read16(struct pci_io_handle *handle, uint32_t reg)
{
return inw(reg + handle->base);
}
static uint8_t
pci_device_x86_read8(struct pci_io_handle *handle, uint32_t reg)
{
return inb(reg + handle->base);
}
static void
pci_device_x86_write32(struct pci_io_handle *handle, uint32_t reg,
uint32_t data)
{
outl(data, reg + handle->base);
}
static void
pci_device_x86_write16(struct pci_io_handle *handle, uint32_t reg,
uint16_t data)
{
outw(data, reg + handle->base);
}
static void
pci_device_x86_write8(struct pci_io_handle *handle, uint32_t reg,
uint8_t data)
{
outb(data, reg + handle->base);
}
static int
pci_device_x86_map_legacy(struct pci_device *dev, pciaddr_t base,
pciaddr_t size, unsigned map_flags, void **addr)
{
struct pci_device_mapping map;
int err;
map.base = base;
map.size = size;
map.flags = map_flags;
err = pci_device_x86_map_range(dev, &map);
*addr = map.memory;
return err;
}
static int
pci_device_x86_unmap_legacy(struct pci_device *dev, void *addr,
pciaddr_t size)
{
struct pci_device_mapping map;
map.size = size;
map.flags = 0;
map.memory = addr;
return pci_device_generic_unmap_range(dev, &map);
}
static const struct pci_system_methods x86_pci_methods = {
.destroy = pci_system_x86_destroy,
.read_rom = pci_device_x86_read_rom,
.probe = pci_device_x86_probe,
.map_range = pci_device_x86_map_range,
.unmap_range = pci_device_generic_unmap_range,
.read = pci_device_x86_read,
.write = pci_device_x86_write,
.fill_capabilities = pci_fill_capabilities_generic,
.open_legacy_io = pci_device_x86_open_legacy_io,
.close_io = pci_device_x86_close_io,
.read32 = pci_device_x86_read32,
.read16 = pci_device_x86_read16,
.read8 = pci_device_x86_read8,
.write32 = pci_device_x86_write32,
.write16 = pci_device_x86_write16,
.write8 = pci_device_x86_write8,
.map_legacy = pci_device_x86_map_legacy,
.unmap_legacy = pci_device_x86_unmap_legacy,
};
static int pci_probe(struct pci_system_x86 *pci_sys_x86)
{
if (pci_system_x86_conf1_probe() == 0) {
pci_sys_x86->read = pci_system_x86_conf1_read;
pci_sys_x86->write = pci_system_x86_conf1_write;
if (pci_system_x86_check(pci_sys_x86) == 0)
return 0;
}
if (pci_system_x86_conf2_probe() == 0) {
pci_sys_x86->read = pci_system_x86_conf2_read;
pci_sys_x86->write = pci_system_x86_conf2_write;
if (pci_system_x86_check(pci_sys_x86) == 0)
return 0;
}
return ENODEV;
}
_pci_hidden int
pci_system_x86_create(void)
{
struct pci_device_private *device;
int ret, bus, dev, ndevs, func, nfuncs;
struct pci_system_x86 *pci_sys_x86;
uint32_t reg;
ret = x86_enable_io();
if (ret)
return ret;
pci_sys_x86 = calloc(1, sizeof(struct pci_system_x86));
if (pci_sys_x86 == NULL) {
x86_disable_io();
return ENOMEM;
}
pci_sys = &pci_sys_x86->system;
ret = pci_probe(pci_sys_x86);
if (ret) {
x86_disable_io();
free(pci_sys_x86);
pci_sys = NULL;
return ret;
}
pci_sys->methods = &x86_pci_methods;
ndevs = 0;
for (bus = 0; bus < 256; bus++) {
for (dev = 0; dev < 32; dev++) {
nfuncs = pci_nfuncs(pci_sys_x86, bus, dev);
for (func = 0; func < nfuncs; func++) {
if (pci_sys_x86->read(bus, dev, func, PCI_VENDOR_ID, ®, sizeof(reg)) != 0)
continue;
if (PCI_VENDOR(reg) == PCI_VENDOR_INVALID ||
PCI_VENDOR(reg) == 0)
continue;
ndevs++;
}
}
}
pci_sys->num_devices = ndevs;
pci_sys->devices = calloc(ndevs, sizeof(struct pci_device_private));
if (pci_sys->devices == NULL) {
x86_disable_io();
free(pci_sys_x86);
pci_sys = NULL;
return ENOMEM;
}
device = pci_sys->devices;
for (bus = 0; bus < 256; bus++) {
for (dev = 0; dev < 32; dev++) {
nfuncs = pci_nfuncs(pci_sys_x86, bus, dev);
for (func = 0; func < nfuncs; func++) {
if (pci_sys_x86->read(bus, dev, func, PCI_VENDOR_ID, ®, sizeof(reg)) != 0)
continue;
if (PCI_VENDOR(reg) == PCI_VENDOR_INVALID ||
PCI_VENDOR(reg) == 0)
continue;
device->base.domain = 0;
device->base.bus = bus;
device->base.dev = dev;
device->base.func = func;
device->base.vendor_id = PCI_VENDOR(reg);
device->base.device_id = PCI_DEVICE(reg);
if (pci_sys_x86->read(bus, dev, func, PCI_CLASS, ®, sizeof(reg)) != 0)
continue;
device->base.device_class = reg >> 8;
device->base.revision = reg & 0xFF;
if (pci_sys_x86->read(bus, dev, func, PCI_SUB_VENDOR_ID, ®, sizeof(reg)) != 0)
continue;
device->base.subvendor_id = PCI_VENDOR(reg);
device->base.subdevice_id = PCI_DEVICE(reg);
device++;
}
}
}
return 0;
}
t memfd;
if ((dev->device_class & 0x00ffff00) !=
((PCIC_DISPLAY << 16) | ( PCIS_DISPLAY_VGA << 8))) {
return ENOSYS;
}
memfd = open(libpciaccess-0.13.2/src/common_map.c 0000644 0143106 0000012 00000003520 12172612452 0017563 0 ustar 00alanc staff 0000266 0200005 /*
* (C) Copyright IBM Corporation 2007
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* on the rights to use, copy, modify, merge, publish, distribute, sub
* license, and/or sell copies of the Software, and to permit persons to whom
* the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include
#include
#include
#include "pciaccess.h"
#include "pciaccess_private.h"
/**
* \file common_map.c
* Platform independent memory map routines.
*
* \author Ian Romanick
*/
/**
* Unmap the specified region using the munmap.
*
* \param dev Device whose memory region is to be mapped.
* \param map Memory mapping that is to be undone.
*
* \return
* Zero on success or an \c errno value on failure.
*
* \sa pci_device_unmap_range
*/
_pci_hidden int
pci_device_generic_unmap_range(struct pci_device *dev,
struct pci_device_mapping *map)
{
return (munmap(map->memory, map->size) == -1) ? errno : 0;
}
libpciaccess-0.13.2/src/Makefile.am 0000644 0143106 0000012 00000004127 12172612452 0017332 0 ustar 00alanc staff 0000266 0200005 #
# (C) Copyright IBM Corporation 2006
# All Rights Reserved.
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# on the rights to use, copy, modify, merge, publish, distribute, sub
# license, and/or sell copies of the Software, and to permit persons to whom
# the Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice (including the next
# paragraph) shall be included in all copies or substantial portions of the
# Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
# IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
AM_CPPFLAGS = -I$(top_srcdir)/include
AM_CFLAGS = $(CWARNFLAGS) @PCIACCESS_CFLAGS@
lib_LTLIBRARIES = libpciaccess.la
if LINUX
OS_SUPPORT = linux_sysfs.c linux_devmem.c linux_devmem.h
VGA_ARBITER = common_vgaarb.c
endif
if FREEBSD
OS_SUPPORT = freebsd_pci.c
VGA_ARBITER = common_vgaarb_stub.c
endif
if NETBSD
OS_SUPPORT = netbsd_pci.c
VGA_ARBITER = common_vgaarb_stub.c
endif
if OPENBSD
OS_SUPPORT = openbsd_pci.c
# VGA Arbiter code is included in openbsd_pci.c
endif
if SOLARIS
OS_SUPPORT = solx_devfs.c pci_tools.h
VGA_ARBITER = common_vgaarb_stub.c
endif
if GNU
OS_SUPPORT = x86_pci.c
VGA_ARBITER = common_vgaarb_stub.c
endif
libpciaccess_la_SOURCES = common_bridge.c \
common_iterator.c \
common_init.c \
common_interface.c \
common_io.c \
common_capability.c \
common_device_name.c \
common_map.c \
pciaccess_private.h \
$(VGA_ARBITER) \
$(OS_SUPPORT)
libpciaccess_la_LIBADD = $(PCIACCESS_LIBS)
libpciaccess_la_LDFLAGS = -version-number 0:11:1 -no-undefined
libpciaccess-0.13.2/src/linux_devmem.c 0000644 0143106 0000012 00000007441 12172612452 0020140 0 ustar 00alanc staff 0000266 0200005 /*
* (C) Copyright IBM Corporation 2007
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* on the rights to use, copy, modify, merge, publish, distribute, sub
* license, and/or sell copies of the Software, and to permit persons to whom
* the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
/**
* \file linux_devmem.c
* Access PCI subsystem using Linux's the old /dev/mem interface.
*
* \note
* This is currently just a skeleton. It only includes the /dev/mem based
* function for reading the device ROM.
*
* \author Ian Romanick
*/
#define _GNU_SOURCE
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "pciaccess.h"
#include "pciaccess_private.h"
#include "linux_devmem.h"
/**
* Read a device's expansion ROM using /dev/mem.
*
* \note
* This function could probably be used, as-is, on other platforms that have
* a /dev/mem interface.
*
* \bugs
* Before using the VGA special case code, this function should check that
* VGA access are routed to the device. Right?
*/
_pci_hidden int
pci_device_linux_devmem_read_rom(struct pci_device *dev, void *buffer)
{
struct pci_device_private *priv = (struct pci_device_private *) dev;
int fd;
int err = 0;
uint32_t rom_base_tmp;
pciaddr_t rom_base;
pciaddr_t rom_size;
int PCI_ROM;
/* Handle some special cases of legacy devices.
*/
if (priv->base.rom_size == 0) {
/* VGA ROMs are supposed to be at 0xC0000.
*/
if ((priv->base.device_class & 0x00ffff00) == 0x000030000) {
rom_base = 0x000C0000;
rom_size = 0x00010000;
PCI_ROM = 0;
}
else {
/* "Function not implemented."
*/
return ENOSYS;
}
}
else {
rom_base = priv->rom_base;
rom_size = priv->base.rom_size;
PCI_ROM = 1;
}
/* Enable the device's ROM.
*/
if (PCI_ROM) {
err = pci_device_cfg_read_u32(& priv->base, & rom_base_tmp, 48);
if (err) {
return err;
}
if ((rom_base_tmp & 0x000000001) == 0) {
err = pci_device_cfg_write_u32(& priv->base,
rom_base_tmp | 1, 48);
if (err) {
return err;
}
}
}
/* Read the portion of /dev/mem that corresponds to the device's ROM.
*/
fd = open("/dev/mem", O_RDONLY, 0);
if (fd < 0) {
err = errno;
}
else {
size_t bytes;
for (bytes = 0; bytes < rom_size; /* empty */) {
const ssize_t got = pread(fd, buffer, rom_size - bytes,
rom_base + bytes);
if (got == -1) {
err = errno;
break;
}
bytes += got;
}
close(fd);
}
/* Disable the device's ROM.
*/
if (PCI_ROM && ((rom_base_tmp & 0x000000001) == 0)) {
const int tmp_err = pci_device_cfg_write_u32(& priv->base,
rom_base_tmp, 48);
/* Prefer to return the first error that occurred.
*/
if (err == 0) {
err = tmp_err;
}
}
return err;
}
libpciaccess-0.13.2/src/pciaccess_private.h 0000644 0143106 0000012 00000013443 12172612452 0021137 0 ustar 00alanc staff 0000266 0200005 /*
* (C) Copyright IBM Corporation 2006
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* on the rights to use, copy, modify, merge, publish, distribute, sub
* license, and/or sell copies of the Software, and to permit persons to whom
* the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
/**
* \file pciaccess_private.h
* Functions and datastructures that are private to the pciaccess library.
*
* \author Ian Romanick
*/
#if defined(__GNUC__) && (__GNUC__ >= 4)
# define _pci_hidden __attribute__((visibility("hidden")))
#elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550)
# define _pci_hidden __hidden
#else /* not gcc >= 4 and not Sun Studio >= 8 */
# define _pci_hidden
#endif /* GNUC >= 4 */
/*
* O_CLOEXEC fixes an fd leak case (see 'man 2 open' for details). I don't
* know of any OS we support where this isn't available in a sufficiently
* new version, so warn unconditionally.
*/
#include
#ifndef O_CLOEXEC
#warning O_CLOEXEC not available, please upgrade.
#define O_CLOEXEC 0
#endif
struct pci_device_mapping;
int pci_fill_capabilities_generic( struct pci_device * dev );
int pci_device_generic_unmap_range(struct pci_device *dev,
struct pci_device_mapping *map);
struct pci_system_methods {
void (*destroy)( void );
void (*destroy_device)( struct pci_device * dev );
int (*read_rom)( struct pci_device * dev, void * buffer );
int (*probe)( struct pci_device * dev );
int (*map_range)(struct pci_device *dev, struct pci_device_mapping *map);
int (*unmap_range)(struct pci_device * dev,
struct pci_device_mapping *map);
int (*read)(struct pci_device * dev, void * data, pciaddr_t offset,
pciaddr_t size, pciaddr_t * bytes_read );
int (*write)(struct pci_device * dev, const void * data, pciaddr_t offset,
pciaddr_t size, pciaddr_t * bytes_written );
int (*fill_capabilities)( struct pci_device * dev );
void (*enable)( struct pci_device *dev );
int (*boot_vga)( struct pci_device *dev );
int (*has_kernel_driver)( struct pci_device *dev );
struct pci_io_handle *(*open_device_io)( struct pci_io_handle *handle,
struct pci_device *dev, int bar,
pciaddr_t base, pciaddr_t size );
struct pci_io_handle *(*open_legacy_io)( struct pci_io_handle *handle,
struct pci_device *dev,
pciaddr_t base, pciaddr_t size );
void (*close_io)( struct pci_device *dev, struct pci_io_handle *handle );
uint32_t (*read32)( struct pci_io_handle *handle, uint32_t reg );
uint16_t (*read16)( struct pci_io_handle *handle, uint32_t reg );
uint8_t (*read8)( struct pci_io_handle *handle, uint32_t reg );
void (*write32)( struct pci_io_handle *handle, uint32_t reg,
uint32_t data );
void (*write16)( struct pci_io_handle *handle, uint32_t reg,
uint16_t data );
void (*write8)( struct pci_io_handle *handle, uint32_t reg, uint8_t data );
int (*map_legacy)(struct pci_device *dev, pciaddr_t base, pciaddr_t size,
unsigned map_flags, void **addr);
int (*unmap_legacy)(struct pci_device *dev, void *addr, pciaddr_t size);
};
struct pci_device_mapping {
pciaddr_t base;
pciaddr_t size;
unsigned region;
unsigned flags;
void *memory;
};
struct pci_io_handle {
pciaddr_t base;
pciaddr_t size;
void *memory;
int fd;
};
struct pci_device_private {
struct pci_device base;
const char * device_string;
uint8_t header_type;
/**
* \name PCI Capabilities
*/
/*@{*/
const struct pci_agp_info * agp; /**< AGP capability information. */
/*@}*/
/**
* Base address of the device's expansion ROM.
*/
pciaddr_t rom_base;
/**
* \name Bridge information.
*/
/*@{*/
union {
struct pci_bridge_info * pci;
struct pci_pcmcia_bridge_info * pcmcia;
} bridge;
/*@}*/
/**
* \name Mappings active on this device.
*/
/*@{*/
struct pci_device_mapping *mappings;
unsigned num_mappings;
/*@}*/
#ifdef __sun
int is_primary;
#endif
};
/**
* Base type for tracking PCI subsystem information.
*/
struct pci_system {
/**
* Platform dependent implementations of specific API routines.
*/
const struct pci_system_methods * methods;
/**
* Number of known devices in the system.
*/
size_t num_devices;
/**
* Array of known devices.
*/
struct pci_device_private * devices;
#ifdef HAVE_MTRR
int mtrr_fd;
#endif
int vgaarb_fd;
int vga_count;
struct pci_device *vga_target;
struct pci_device *vga_default_dev;
};
extern struct pci_system * pci_sys;
extern int pci_system_linux_sysfs_create( void );
extern int pci_system_freebsd_create( void );
extern int pci_system_netbsd_create( void );
extern int pci_system_openbsd_create( void );
extern void pci_system_openbsd_init_dev_mem( int );
extern int pci_system_solx_devfs_create( void );
extern int pci_system_x86_create( void );
extern void pci_io_cleanup( void );
LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN libpciaccess-0.13.2/src/solx_devfs.c 0000644 0143106 0000012 00000065304 12172612452 0017622 0 ustar 00alanc staff 0000266 0200005 /*
* (C) Copyright IBM Corporation 2006
* Copyright (c) 2007, 2009, 2011, 2012, 2013 Oracle and/or its affiliates.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* on the rights to use, copy, modify, merge, publish, distribute, sub
* license, and/or sell copies of the Software, and to permit persons to whom
* the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
/*
* Solaris devfs interfaces
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "pci_tools.h"
#ifdef __x86
# include
# include
#endif
#include "pciaccess.h"
#include "pciaccess_private.h"
/* #define DEBUG */
#define INITIAL_NUM_DEVICES 256
#define CELL_NUMS_1275 (sizeof(pci_regspec_t) / sizeof(uint_t))
typedef struct i_devnode {
uint8_t bus;
uint8_t dev;
uint8_t func;
di_node_t node;
} i_devnode_t;
typedef struct nexus {
int fd;
int first_bus;
int last_bus;
int domain;
char *path; /* for errors/debugging; fd is all we need */
char *dev_path;
struct nexus *next;
} nexus_t;
typedef struct probe_info {
volatile size_t num_allocated_elems;
volatile size_t num_devices;
struct pci_device_private * volatile devices;
} probe_info_t;
typedef struct probe_args {
probe_info_t *pinfo;
nexus_t *nexus;
int ret;
} probe_args_t;
typedef struct property_info {
const char *name;
int value;
} property_info_t;
static nexus_t *nexus_list = NULL;
#if !defined(__sparc)
static int xsvc_fd = -1;
#endif
#ifdef __sparc
static di_prom_handle_t di_phdl;
static size_t nexus_count = 0;
#endif
/*
* Read config space in native processor endianness. Endian-neutral
* processing can then take place. On big endian machines, MSB and LSB
* of little endian data end up switched if read as little endian.
* They are in correct order if read as big endian.
*/
#if defined(__sparc)
# define NATIVE_ENDIAN PCITOOL_ACC_ATTR_ENDN_BIG
#elif defined(__x86)
# define NATIVE_ENDIAN PCITOOL_ACC_ATTR_ENDN_LTL
#else
# error "ISA is neither __sparc nor __x86"
#endif
#ifdef __sparc
#define MAPPING_DEV_PATH(dev) (((struct pci_device_private *) dev)->device_string)
#endif
static nexus_t *
find_nexus_for_bus( int domain, int bus )
{
nexus_t *nexus;
for (nexus = nexus_list ; nexus != NULL ; nexus = nexus->next) {
if ((domain == nexus->domain) &&
(bus >= nexus->first_bus) && (bus <= nexus->last_bus)) {
return nexus;
}
}
return NULL;
}
/*
* Release all the resources
* Solaris version
*/
static void
pci_system_solx_devfs_destroy( void )
{
/*
* The memory allocated for pci_sys & devices in create routines
* will be freed in pci_system_cleanup.
* Need to free system-specific allocations here.
*/
nexus_t *nexus, *next;
for (nexus = nexus_list ; nexus != NULL ; nexus = next) {
next = nexus->next;
close(nexus->fd);
free(nexus->path);
free(nexus->dev_path);
free(nexus);
}
nexus_list = NULL;
#ifdef __sparc
if (di_phdl != DI_PROM_HANDLE_NIL)
(void) di_prom_fini(di_phdl);
#else
if (xsvc_fd >= 0) {
close(xsvc_fd);
xsvc_fd = -1;
}
#endif
}
#ifdef __sparc
/*
* Release resources per device
*/
static void
pci_system_solx_devfs_destroy_device( struct pci_device *dev )
{
if (MAPPING_DEV_PATH(dev))
di_devfs_path_free((char *) MAPPING_DEV_PATH(dev));
}
#endif
static int
probe_device_node(di_node_t node, void *arg)
{
int *retbuf = NULL;
int len = 0, i;
struct pci_device *pci_base;
probe_info_t *pinfo = ((probe_args_t *)arg)->pinfo;
nexus_t *nexus = ((probe_args_t *)arg)->nexus;
property_info_t property_list[] = {
{ "class-code", 0 },
{ "device-id", 0 },
{ "vendor-id", 0 },
{ "revision-id", 0},
{ "subsystem-vendor-id", 0},
{ "subsystem-id", 0},
};
#define NUM_PROPERTIES sizeof(property_list)/sizeof(property_info_t)
len = di_prop_lookup_ints(DDI_DEV_T_ANY, node, "reg", &retbuf);
#ifdef __sparc
if ((len <= 0) && di_phdl)
len = di_prom_prop_lookup_ints(di_phdl, node, "reg", &retbuf);
#endif
/* Exclude usb devices */
if (len < 5) {
return DI_WALK_CONTINUE;
}
pci_base = &pinfo->devices[pinfo->num_devices].base;
pci_base->domain = nexus->domain;
pci_base->bus = PCI_REG_BUS_G(retbuf[0]);
pci_base->dev = PCI_REG_DEV_G(retbuf[0]);
pci_base->func = PCI_REG_FUNC_G(retbuf[0]);
/* Get property values */
for (i = 0; i < NUM_PROPERTIES; i++) {
len = di_prop_lookup_ints(DDI_DEV_T_ANY, node,
property_list[i].name, &retbuf);
#ifdef __sparc
if ((len <= 0) && di_phdl)
len = di_prom_prop_lookup_ints(di_phdl, node,
property_list[i].name, &retbuf);
#endif
if (len > 0)
property_list[i].value = retbuf[0];
else {
/* a device must have property "class-code", "device-id", "vendor-id" */
if (i < 3)
return DI_WALK_CONTINUE;
#ifdef DEBUG
fprintf(stderr, "cannot get property \"%s\" for nexus = %s :\n",
property_list[i].name, nexus->path);
fprintf(stderr, " domain = %x, busno = %x, devno = %x, funcno = %x\n",
pci_base->domain, pci_base->bus, pci_base->dev, pci_base->func);
#endif
}
}
if ((property_list[1].value == 0) && (property_list[2].value == 0))
return DI_WALK_CONTINUE;
pci_base->device_class = property_list[0].value;
pci_base->device_id = property_list[1].value;
pci_base->vendor_id = property_list[2].value;
pci_base->revision = property_list[3].value;
pci_base->subvendor_id = property_list[4].value;
pci_base->subdevice_id = property_list[5].value;
#ifdef DEBUG
fprintf(stderr,
"nexus = %s, domain = %x, busno = %x, devno = %x, funcno = %x\n",
nexus->path, pci_base->domain, pci_base->bus, pci_base->dev, pci_base->func);
#endif
pinfo->num_devices++;
if (pinfo->num_devices == pinfo->num_allocated_elems) {
struct pci_device_private *new_devs;
size_t new_num_elems = pinfo->num_allocated_elems * 2;
new_devs = realloc(pinfo->devices,
new_num_elems * sizeof (struct pci_device_private));
if (new_devs == NULL) {
(void) fprintf(stderr,
"Error allocating memory for PCI devices:"
" %s\n discarding additional devices\n",
strerror(errno));
((probe_args_t *)arg)->ret = 1;
return (DI_WALK_TERMINATE);
}
(void) memset(&new_devs[pinfo->num_devices], 0,
pinfo->num_allocated_elems *
sizeof (struct pci_device_private));
pinfo->num_allocated_elems = new_num_elems;
pinfo->devices = new_devs;
}
return (DI_WALK_CONTINUE);
}
/*
* This function is called from di_walk_minor() when any PROBE is processed
*/
static int
probe_nexus_node(di_node_t di_node, di_minor_t minor, void *arg)
{
probe_info_t *pinfo = (probe_info_t *)arg;
char *nexus_name, *nexus_dev_path;
nexus_t *nexus;
int fd;
char nexus_path[MAXPATHLEN];
di_prop_t prop;
char *strings;
int *ints;
int numval;
int pci_node = 0;
int first_bus = 0, last_bus = PCI_REG_BUS_G(PCI_REG_BUS_M);
int domain = 0;
di_node_t rnode = DI_NODE_NIL;
#ifdef __sparc
int bus_range_found = 0;
int device_type_found = 0;
di_prom_prop_t prom_prop;
#endif
#ifdef DEBUG
nexus_name = di_devfs_minor_path(minor);
fprintf(stderr, "-- device name: %s\n", nexus_name);
di_devfs_path_free(nexus_name);
#endif
for (prop = di_prop_next(di_node, NULL); prop != NULL;
prop = di_prop_next(di_node, prop)) {
const char *prop_name = di_prop_name(prop);
#ifdef DEBUG
fprintf(stderr, " property: %s\n", prop_name);
#endif
if (strcmp(prop_name, "device_type") == 0) {
numval = di_prop_strings(prop, &strings);
if (numval == 1) {
if (strncmp(strings, "pci", 3) != 0)
/* not a PCI node, bail */
return (DI_WALK_CONTINUE);
else {
pci_node = 1;
#ifdef __sparc
device_type_found = 1;
#endif
}
}
}
else if (strcmp(prop_name, "class-code") == 0) {
/* not a root bus node, bail */
return (DI_WALK_CONTINUE);
}
else if (strcmp(prop_name, "bus-range") == 0) {
numval = di_prop_ints(prop, &ints);
if (numval == 2) {
first_bus = ints[0];
last_bus = ints[1];
#ifdef __sparc
bus_range_found = 1;
#endif
}
}
#ifdef __sparc
domain = nexus_count;
#else
else if (strcmp(prop_name, "pciseg") == 0) {
numval = di_prop_ints(prop, &ints);
if (numval == 1) {
domain = ints[0];
}
}
#endif
}
#ifdef __sparc
if ((!device_type_found) && di_phdl) {
numval = di_prom_prop_lookup_strings(di_phdl, di_node,
"device_type", &strings);
if (numval == 1) {
if (strncmp(strings, "pci", 3) != 0)
return (DI_WALK_CONTINUE);
else
pci_node = 1;
}
}
if ((!bus_range_found) && di_phdl) {
numval = di_prom_prop_lookup_ints(di_phdl, di_node,
"bus-range", &ints);
if (numval == 2) {
first_bus = ints[0];
last_bus = ints[1];
}
}
#endif
if (pci_node != 1)
return (DI_WALK_CONTINUE);
/* we have a PCI root bus node. */
nexus = calloc(1, sizeof(nexus_t));
if (nexus == NULL) {
(void) fprintf(stderr, "Error allocating memory for nexus: %s\n",
strerror(errno));
return (DI_WALK_TERMINATE);
}
nexus->first_bus = first_bus;
nexus->last_bus = last_bus;
nexus->domain = domain;
#ifdef __sparc
nexus_count++;
#endif
nexus_name = di_devfs_minor_path(minor);
if (nexus_name == NULL) {
(void) fprintf(stderr, "Error getting nexus path: %s\n",
strerror(errno));
free(nexus);
return (DI_WALK_CONTINUE);
}
snprintf(nexus_path, sizeof(nexus_path), "/devices%s", nexus_name);
di_devfs_path_free(nexus_name);
#ifdef DEBUG
fprintf(stderr, "nexus = %s, bus-range = %d - %d\n",
nexus_path, first_bus, last_bus);
#endif
if ((fd = open(nexus_path, O_RDWR | O_CLOEXEC)) >= 0) {
probe_args_t args;
nexus->fd = fd;
nexus->path = strdup(nexus_path);
nexus_dev_path = di_devfs_path(di_node);
nexus->dev_path = strdup(nexus_dev_path);
di_devfs_path_free(nexus_dev_path);
if ((rnode = di_init(nexus->dev_path, DINFOCPYALL)) == DI_NODE_NIL) {
(void) fprintf(stderr, "di_init failed: %s\n", strerror(errno));
close(nexus->fd);
free(nexus->path);
free(nexus->dev_path);
free(nexus);
return (DI_WALK_TERMINATE);
}
/* Walk through devices under the rnode */
args.pinfo = pinfo;
args.nexus = nexus;
args.ret = 0;
(void) di_walk_node(rnode, DI_WALK_CLDFIRST, (void *)&args, probe_device_node);
if (args.ret) {
close(nexus->fd);
free(nexus->path);
free(nexus->dev_path);
free(nexus);
di_fini(rnode);
return (DI_WALK_TERMINATE);
}
nexus->next = nexus_list;
nexus_list = nexus;
} else {
(void) fprintf(stderr, "Error opening %s: %s\n",
nexus_path, strerror(errno));
free(nexus);
}
if (rnode != DI_NODE_NIL) {
di_fini(rnode);
}
return DI_WALK_CONTINUE;
}
static int
find_target_node(di_node_t node, void *arg)
{
int *regbuf = NULL;
int len = 0;
uint32_t busno, funcno, devno;
i_devnode_t *devnode = (i_devnode_t *)arg;
/*
* Test the property functions, only for testing
*/
/*
void *prop = DI_PROP_NIL;
(void) fprintf(stderr, "start of node 0x%x\n", node->nodeid);
while ((prop = di_prop_hw_next(node, prop)) != DI_PROP_NIL) {
int i;
(void) fprintf(stderr, "name=%s: ", di_prop_name(prop));
len = 0;
if (!strcmp(di_prop_name(prop), "reg")) {
len = di_prop_ints(prop, ®buf);
}
for (i = 0; i < len; i++) {
fprintf(stderr, "0x%0x.", regbuf[i]);
}
fprintf(stderr, "\n");
}
(void) fprintf(stderr, "end of node 0x%x\n", node->nodeid);
*/
len = di_prop_lookup_ints(DDI_DEV_T_ANY, node, "reg", ®buf);
#ifdef __sparc
if ((len <= 0) && di_phdl)
len = di_prom_prop_lookup_ints(di_phdl, node, "reg", ®buf);
#endif
if (len <= 0) {
#ifdef DEBUG
fprintf(stderr, "error = %x\n", errno);
fprintf(stderr, "can not find assigned-address\n");
#endif
return (DI_WALK_CONTINUE);
}
busno = PCI_REG_BUS_G(regbuf[0]);
devno = PCI_REG_DEV_G(regbuf[0]);
funcno = PCI_REG_FUNC_G(regbuf[0]);
if ((busno == devnode->bus) &&
(devno == devnode->dev) &&
(funcno == devnode->func)) {
devnode->node = node;
return (DI_WALK_TERMINATE);
}
return (DI_WALK_CONTINUE);
}
/*
* Solaris version
*/
static int
pci_device_solx_devfs_probe( struct pci_device * dev )
{
int err = 0;
di_node_t rnode = DI_NODE_NIL;
i_devnode_t args = { 0, 0, 0, DI_NODE_NIL };
int *regbuf;
pci_regspec_t *reg;
int i;
int len = 0;
uint ent = 0;
struct pci_device_private *priv =
(struct pci_device_private *) dev;
nexus_t *nexus;
if ( (nexus = find_nexus_for_bus(dev->domain, dev->bus)) == NULL )
return ENODEV;
pci_device_cfg_read_u8(dev, &priv->header_type, PCI_CONF_HEADER);
pci_device_cfg_read_u8(dev, (uint8_t *)&dev->irq, PCI_CONF_ILINE);
/*
* starting to find if it is MEM/MEM64/IO
* using libdevinfo
*/
if ((rnode = di_init(nexus->dev_path, DINFOCPYALL)) == DI_NODE_NIL) {
err = errno;
(void) fprintf(stderr, "di_init failed: %s\n", strerror(errno));
} else {
args.bus = dev->bus;
args.dev = dev->dev;
args.func = dev->func;
(void) di_walk_node(rnode, DI_WALK_CLDFIRST,
(void *)&args, find_target_node);
}
if (args.node != DI_NODE_NIL) {
int *prop;
#ifdef __sparc
di_minor_t minor;
#endif
priv->is_primary = 0;
#ifdef __sparc
if (minor = di_minor_next(args.node, DI_MINOR_NIL))
MAPPING_DEV_PATH(dev) = di_devfs_minor_path (minor);
else
MAPPING_DEV_PATH(dev) = NULL;
#endif
if (di_prop_lookup_ints(DDI_DEV_T_ANY, args.node,
"primary-controller", &prop) >= 1) {
if (prop[0])
priv->is_primary = 1;
}
/*
* It will succeed for sure, because it was
* successfully called in find_target_node
*/
len = di_prop_lookup_ints(DDI_DEV_T_ANY, args.node,
"assigned-addresses",
®buf);
#ifdef __sparc
if ((len <= 0) && di_phdl) {
len = di_prom_prop_lookup_ints(di_phdl, args.node,
"assigned-addresses", ®buf);
}
#endif
}
if (len <= 0)
goto cleanup;
/*
* Each BAR address get its own region slot in sequence.
* 32 bit BAR:
* BAR 0x10 -> slot0, BAR 0x14 -> slot1...
* 64 bit BAR:
* BAR 0x10 -> slot0, BAR 0x18 -> slot2...,
* slot1 is part of BAR 0x10
* Linux give two region slot for 64 bit address.
*/
for (i = 0; i < len; i = i + (int)CELL_NUMS_1275) {
reg = (pci_regspec_t *)®buf[i];
ent = reg->pci_phys_hi & 0xff;
if (ent > PCI_CONF_ROM) {
fprintf(stderr, "error ent = %d\n", ent);
break;
}
/*
* G35 broken in BAR0
*/
if (ent < PCI_CONF_BASE0) {
/*
* VGA resource here and ignore it
*/
break;
} else if (ent == PCI_CONF_ROM) {
priv->rom_base = reg->pci_phys_low |
((uint64_t)reg->pci_phys_mid << 32);
dev->rom_size = reg->pci_size_low;
} else {
ent = (ent - PCI_CONF_BASE0) >> 2;
/*
* non relocatable resource is excluded
* such like 0xa0000, 0x3b0. If it is met,
* the loop is broken;
*/
if (!PCI_REG_REG_G(reg->pci_phys_hi))
break;
if (reg->pci_phys_hi & PCI_PREFETCH_B) {
dev->regions[ent].is_prefetchable = 1;
}
dev->regions[ent].base_addr = reg->pci_phys_low |
((uint64_t)reg->pci_phys_mid << 32);
dev->regions[ent].size = reg->pci_size_low |
((uint64_t)reg->pci_size_hi << 32);
switch (reg->pci_phys_hi & PCI_REG_ADDR_M) {
case PCI_ADDR_IO:
dev->regions[ent].is_IO = 1;
break;
case PCI_ADDR_MEM32:
break;
case PCI_ADDR_MEM64:
dev->regions[ent].is_64 = 1;
/*
* Skip one slot for 64 bit address
*/
break;
}
}
}
cleanup:
if (rnode != DI_NODE_NIL) {
di_fini(rnode);
}
return (err);
}
/**
* Map a memory region for a device using /dev/xsvc (x86) or fb device (sparc)
*
* \param dev Device whose memory region is to be mapped.
* \param map Parameters of the mapping that is to be created.
*
* \return
* Zero on success or an \c errno value on failure.
*/
static int
pci_device_solx_devfs_map_range(struct pci_device *dev,
struct pci_device_mapping *map)
{
const int prot = ((map->flags & PCI_DEV_MAP_FLAG_WRITABLE) != 0)
? (PROT_READ | PROT_WRITE) : PROT_READ;
int err = 0;
const char *map_dev;
int map_fd;
#ifdef __sparc
char map_dev_buf[128];
if (MAPPING_DEV_PATH(dev)) {
snprintf(map_dev_buf, sizeof (map_dev_buf), "%s%s",
"/devices", MAPPING_DEV_PATH(dev));
map_dev = map_dev_buf;
}
else
map_dev = "/dev/fb0";
map_fd = -1;
#else
/*
* Still uses xsvc to do the user space mapping on x86/x64,
* caches open fd across multiple calls.
*/
map_dev = "/dev/xsvc";
map_fd = xsvc_fd;
#endif
if (map_fd < 0) {
if ((map_fd = open(map_dev, O_RDWR | O_CLOEXEC)) < 0) {
err = errno;
(void) fprintf(stderr, "can not open %s: %s\n", map_dev,
strerror(errno));
return err;
}
}
map->memory = mmap(NULL, map->size, prot, MAP_SHARED, map_fd, map->base);
if (map->memory == MAP_FAILED) {
err = errno;
(void) fprintf(stderr, "map rom region =%llx failed: %s\n",
(unsigned long long) map->base, strerror(errno));
}
#ifdef __sparc
close (map_fd);
#endif
return err;
}
/*
* Solaris version: read the VGA ROM data
*/
static int
pci_device_solx_devfs_read_rom( struct pci_device * dev, void * buffer )
{
int err;
struct pci_device_mapping prom = {
.base = 0xC0000,
.size = 0x10000,
.flags = 0
};
struct pci_device_private *priv =
(struct pci_device_private *) dev;
if (priv->rom_base) {
prom.base = priv->rom_base;
prom.size = dev->rom_size;
}
err = pci_device_solx_devfs_map_range(dev, &prom);
if (err == 0) {
(void) bcopy(prom.memory, buffer, dev->rom_size);
if (munmap(prom.memory, prom.size) == -1) {
err = errno;
}
}
return err;
}
/*
* solaris version: Read the configurations space of the devices
*/
static int
pci_device_solx_devfs_read( struct pci_device * dev, void * data,
pciaddr_t offset, pciaddr_t size,
pciaddr_t * bytes_read )
{
pcitool_reg_t cfg_prg;
int err = 0;
unsigned int i = 0;
nexus_t *nexus;
nexus = find_nexus_for_bus(dev->domain, dev->bus);
*bytes_read = 0;
if ( nexus == NULL ) {
return ENODEV;
}
cfg_prg.offset = offset;
cfg_prg.acc_attr = PCITOOL_ACC_ATTR_SIZE_1 + NATIVE_ENDIAN;
cfg_prg.bus_no = dev->bus;
cfg_prg.dev_no = dev->dev;
cfg_prg.func_no = dev->func;
cfg_prg.barnum = 0;
cfg_prg.user_version = PCITOOL_USER_VERSION;
for (i = 0; i < size; i += PCITOOL_ACC_ATTR_SIZE(PCITOOL_ACC_ATTR_SIZE_1))
{
cfg_prg.offset = offset + i;
if ((err = ioctl(nexus->fd, PCITOOL_DEVICE_GET_REG, &cfg_prg)) != 0) {
fprintf(stderr, "read bdf<%s,%x,%x,%x,%llx> config space failure\n",
nexus->path,
cfg_prg.bus_no,
cfg_prg.dev_no,
cfg_prg.func_no,
(unsigned long long) cfg_prg.offset);
fprintf(stderr, "Failure cause = %x\n", err);
break;
}
((uint8_t *)data)[i] = (uint8_t)cfg_prg.data;
/*
* DWORDS Offset or bytes Offset ??
*/
}
*bytes_read = i;
return (err);
}
/*
* Solaris version
*/
static int
pci_device_solx_devfs_write( struct pci_device * dev, const void * data,
pciaddr_t offset, pciaddr_t size,
pciaddr_t * bytes_written )
{
pcitool_reg_t cfg_prg;
int err = 0;
int cmd;
nexus_t *nexus;
nexus = find_nexus_for_bus(dev->domain, dev->bus);
if ( bytes_written != NULL ) {
*bytes_written = 0;
}
if ( nexus == NULL ) {
return ENODEV;
}
cfg_prg.offset = offset;
switch (size) {
case 1:
cfg_prg.acc_attr = PCITOOL_ACC_ATTR_SIZE_1 + NATIVE_ENDIAN;
cfg_prg.data = *((const uint8_t *)data);
break;
case 2:
cfg_prg.acc_attr = PCITOOL_ACC_ATTR_SIZE_2 + NATIVE_ENDIAN;
cfg_prg.data = *((const uint16_t *)data);
break;
case 4:
cfg_prg.acc_attr = PCITOOL_ACC_ATTR_SIZE_4 + NATIVE_ENDIAN;
cfg_prg.data = *((const uint32_t *)data);
break;
case 8:
cfg_prg.acc_attr = PCITOOL_ACC_ATTR_SIZE_8 + NATIVE_ENDIAN;
cfg_prg.data = *((const uint64_t *)data);
break;
default:
return EINVAL;
}
cfg_prg.bus_no = dev->bus;
cfg_prg.dev_no = dev->dev;
cfg_prg.func_no = dev->func;
cfg_prg.barnum = 0;
cfg_prg.user_version = PCITOOL_USER_VERSION;
/*
* Check if this device is bridge device.
* If it is, it is also a nexus node???
* It seems that there is no explicit
* PCI nexus device for X86, so not applicable
* from pcitool_bus_reg_ops in pci_tools.c
*/
cmd = PCITOOL_DEVICE_SET_REG;
if ((err = ioctl(nexus->fd, cmd, &cfg_prg)) != 0) {
return (err);
}
*bytes_written = size;
return (err);
}
static int pci_device_solx_devfs_boot_vga(struct pci_device *dev)
{
struct pci_device_private *priv =
(struct pci_device_private *) dev;
return (priv->is_primary);
}
static struct pci_io_handle *
pci_device_solx_devfs_open_legacy_io(struct pci_io_handle *ret,
struct pci_device *dev,
pciaddr_t base, pciaddr_t size)
{
#ifdef __x86
if (sysi86(SI86V86, V86SC_IOPL, PS_IOPL) == 0) {
ret->base = base;
ret->size = size;
return ret;
}
#endif
return NULL;
}
static uint32_t
pci_device_solx_devfs_read32(struct pci_io_handle *handle, uint32_t reg)
{
#ifdef __x86
uint16_t port = (uint16_t) (handle->base + reg);
uint32_t ret;
__asm__ __volatile__("inl %1,%0":"=a"(ret):"d"(port));
return ret;
#else
return *(uint32_t *)((uintptr_t)handle->memory + reg);
#endif
}
static uint16_t
pci_device_solx_devfs_read16(struct pci_io_handle *handle, uint32_t reg)
{
#ifdef __x86
uint16_t port = (uint16_t) (handle->base + reg);
uint16_t ret;
__asm__ __volatile__("inw %1,%0":"=a"(ret):"d"(port));
return ret;
#else
return *(uint16_t *)((uintptr_t)handle->memory + reg);
#endif
}
static uint8_t
pci_device_solx_devfs_read8(struct pci_io_handle *handle, uint32_t reg)
{
#ifdef __x86
uint16_t port = (uint16_t) (handle->base + reg);
uint8_t ret;
__asm__ __volatile__("inb %1,%0":"=a"(ret):"d"(port));
return ret;
#else
return *(uint8_t *)((uintptr_t)handle->memory + reg);
#endif
}
static void
pci_device_solx_devfs_write32(struct pci_io_handle *handle, uint32_t reg,
uint32_t data)
{
#ifdef __x86
uint16_t port = (uint16_t) (handle->base + reg);
__asm__ __volatile__("outl %0,%1"::"a"(data), "d"(port));
#else
*(uint16_t *)((uintptr_t)handle->memory + reg) = data;
#endif
}
static void
pci_device_solx_devfs_write16(struct pci_io_handle *handle, uint32_t reg,
uint16_t data)
{
#ifdef __x86
uint16_t port = (uint16_t) (handle->base + reg);
__asm__ __volatile__("outw %0,%1"::"a"(data), "d"(port));
#else
*(uint8_t *)((uintptr_t)handle->memory + reg) = data;
#endif
}
static void
pci_device_solx_devfs_write8(struct pci_io_handle *handle, uint32_t reg,
uint8_t data)
{
#ifdef __x86
uint16_t port = (uint16_t) (handle->base + reg);
__asm__ __volatile__("outb %0,%1"::"a"(data), "d"(port));
#else
*(uint32_t *)((uintptr_t)handle->memory + reg) = data;
#endif
}
static int
pci_device_solx_devfs_map_legacy(struct pci_device *dev, pciaddr_t base,
pciaddr_t size, unsigned map_flags,
void **addr)
{
int err;
struct pci_device_mapping map = {
.base = base,
.size = size,
.flags = map_flags,
};
err = pci_device_solx_devfs_map_range(dev, &map);
if (err == 0)
*addr = map.memory;
return err;
}
static int
pci_device_solx_devfs_unmap_legacy(struct pci_device *dev,
void *addr, pciaddr_t size)
{
struct pci_device_mapping map = {
.memory = addr,
.size = size,
};
return pci_device_generic_unmap_range(dev, &map);
}
static const struct pci_system_methods solx_devfs_methods = {
.destroy = pci_system_solx_devfs_destroy,
#ifdef __sparc
.destroy_device = pci_system_solx_devfs_destroy_device,
#else
.destroy_device = NULL,
#endif
.read_rom = pci_device_solx_devfs_read_rom,
.probe = pci_device_solx_devfs_probe,
.map_range = pci_device_solx_devfs_map_range,
.unmap_range = pci_device_generic_unmap_range,
.read = pci_device_solx_devfs_read,
.write = pci_device_solx_devfs_write,
.fill_capabilities = pci_fill_capabilities_generic,
.boot_vga = pci_device_solx_devfs_boot_vga,
.open_legacy_io = pci_device_solx_devfs_open_legacy_io,
.read32 = pci_device_solx_devfs_read32,
.read16 = pci_device_solx_devfs_read16,
.read8 = pci_device_solx_devfs_read8,
.write32 = pci_device_solx_devfs_write32,
.write16 = pci_device_solx_devfs_write16,
.write8 = pci_device_solx_devfs_write8,
.map_legacy = pci_device_solx_devfs_map_legacy,
.unmap_legacy = pci_device_solx_devfs_unmap_legacy,
};
/*
* Attempt to access PCI subsystem using Solaris's devfs interface.
* Solaris version
*/
_pci_hidden int
pci_system_solx_devfs_create( void )
{
int err = 0;
di_node_t di_node;
probe_info_t pinfo;
struct pci_device_private *devices;
if (nexus_list != NULL) {
return 0;
}
if ((di_node = di_init("/", DINFOCPYALL)) == DI_NODE_NIL) {
err = errno;
(void) fprintf(stderr, "di_init() failed: %s\n",
strerror(errno));
return (err);
}
if ((devices = calloc(INITIAL_NUM_DEVICES,
sizeof (struct pci_device_private))) == NULL) {
err = errno;
di_fini(di_node);
return (err);
}
#ifdef __sparc
if ((di_phdl = di_prom_init()) == DI_PROM_HANDLE_NIL)
(void) fprintf(stderr, "di_prom_init failed: %s\n", strerror(errno));
#endif
pinfo.num_allocated_elems = INITIAL_NUM_DEVICES;
pinfo.num_devices = 0;
pinfo.devices = devices;
#ifdef __sparc
nexus_count = 0;
#endif
(void) di_walk_minor(di_node, DDI_NT_REGACC, 0, &pinfo, probe_nexus_node);
di_fini(di_node);
if ((pci_sys = calloc(1, sizeof (struct pci_system))) == NULL) {
err = errno;
free(devices);
return (err);
}
pci_sys->methods = &solx_devfs_methods;
pci_sys->devices = pinfo.devices;
pci_sys->num_devices = pinfo.num_devices;
return (err);
}
\c errno value on failure.
*/
static int
pci_device_solx_devfs_map_range(struct pci_device *dev,
struct pci_device_mapping *map)
{
const int prot = ((map->flags & PCI_DEV_MAP_FLAG_WRITABLE) != 0)
? (PROT_READ | PROT_WRITE) : PROT_READ;
int err = 0;
const char *map_dev;
int map_fd;
#ifdeflibpciaccess-0.13.2/src/linux_sysfs.c 0000644 0143106 0000012 00000056463 12172612452 0020042 0 ustar 00alanc staff 0000266 0200005 /*
* (C) Copyright IBM Corporation 2006
* All Rights Reserved.
* Copyright 2012 Red Hat, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* on the rights to use, copy, modify, merge, publish, distribute, sub
* license, and/or sell copies of the Software, and to permit persons to whom
* the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
/**
* \file linux_sysfs.c
* Access PCI subsystem using Linux's sysfs interface. This interface is
* available starting somewhere in the late 2.5.x kernel phase, and is the
* preferred method on all 2.6.x kernels.
*
* \author Ian Romanick
*/
#define _GNU_SOURCE
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#if defined(__i386__) || defined(__x86_64__) || defined(__arm__)
#include
#else
#define inb(x) -1
#define inw(x) -1
#define inl(x) -1
#define outb(x,y) do {} while (0)
#define outw(x,y) do {} while (0)
#define outl(x,y) do {} while (0)
#define iopl(x) -1
#endif
#include "config.h"
#ifdef HAVE_MTRR
#include
#include
#endif
#include "pciaccess.h"
#include "pciaccess_private.h"
#include "linux_devmem.h"
static const struct pci_system_methods linux_sysfs_methods;
#define SYS_BUS_PCI "/sys/bus/pci/devices"
static int
pci_device_linux_sysfs_read( struct pci_device * dev, void * data,
pciaddr_t offset, pciaddr_t size,
pciaddr_t * bytes_read );
static int populate_entries(struct pci_system * pci_sys);
/**
* Attempt to access PCI subsystem using Linux's sysfs interface.
*/
_pci_hidden int
pci_system_linux_sysfs_create( void )
{
int err = 0;
struct stat st;
/* If the directory "/sys/bus/pci/devices" exists, then the PCI subsystem
* can be accessed using this interface.
*/
if ( stat( SYS_BUS_PCI, & st ) == 0 ) {
pci_sys = calloc( 1, sizeof( struct pci_system ) );
if ( pci_sys != NULL ) {
pci_sys->methods = & linux_sysfs_methods;
#ifdef HAVE_MTRR
pci_sys->mtrr_fd = open("/proc/mtrr", O_WRONLY | O_CLOEXEC);
#endif
err = populate_entries(pci_sys);
}
else {
err = ENOMEM;
}
}
else {
err = errno;
}
return err;
}
/**
* Filter out the names "." and ".." from the scanned sysfs entries.
*
* \param d Directory entry being processed by \c scandir.
*
* \return
* Zero if the entry name matches either "." or "..", non-zero otherwise.
*
* \sa scandir, populate_entries
*/
static int
scan_sys_pci_filter( const struct dirent * d )
{
return !((strcmp( d->d_name, "." ) == 0)
|| (strcmp( d->d_name, ".." ) == 0));
}
int
populate_entries( struct pci_system * p )
{
struct dirent ** devices = NULL;
int n;
int i;
int err = 0;
n = scandir( SYS_BUS_PCI, & devices, scan_sys_pci_filter, alphasort );
if ( n > 0 ) {
p->num_devices = n;
p->devices = calloc( n, sizeof( struct pci_device_private ) );
if (p->devices != NULL) {
for (i = 0 ; i < n ; i++) {
uint8_t config[48];
pciaddr_t bytes;
unsigned dom, bus, dev, func;
struct pci_device_private *device =
(struct pci_device_private *) &p->devices[i];
sscanf(devices[i]->d_name, "%04x:%02x:%02x.%1u",
& dom, & bus, & dev, & func);
device->base.domain = dom;
device->base.bus = bus;
device->base.dev = dev;
device->base.func = func;
err = pci_device_linux_sysfs_read(& device->base, config, 0,
48, & bytes);
if ((bytes == 48) && !err) {
device->base.vendor_id = (uint16_t)config[0]
+ ((uint16_t)config[1] << 8);
device->base.device_id = (uint16_t)config[2]
+ ((uint16_t)config[3] << 8);
device->base.device_class = (uint32_t)config[9]
+ ((uint32_t)config[10] << 8)
+ ((uint32_t)config[11] << 16);
device->base.revision = config[8];
device->base.subvendor_id = (uint16_t)config[44]
+ ((uint16_t)config[45] << 8);
device->base.subdevice_id = (uint16_t)config[46]
+ ((uint16_t)config[47] << 8);
}
if (err) {
break;
}
}
}
else {
err = ENOMEM;
}
}
for (i = 0; i < n; i++)
free(devices[i]);
free(devices);
if (err) {
free(p->devices);
p->devices = NULL;
}
return err;
}
static int
pci_device_linux_sysfs_probe( struct pci_device * dev )
{
char name[256];
uint8_t config[256];
char resource[512];
int fd;
pciaddr_t bytes;
unsigned i;
int err;
err = pci_device_linux_sysfs_read( dev, config, 0, 256, & bytes );
if ( bytes >= 64 ) {
struct pci_device_private *priv = (struct pci_device_private *) dev;
dev->irq = config[60];
priv->header_type = config[14];
/* The PCI config registers can be used to obtain information
* about the memory and I/O regions for the device. However,
* doing so requires some tricky parsing (to correctly handle
* 64-bit memory regions) and requires writing to the config
* registers. Since we'd like to avoid having to deal with the
* parsing issues and non-root users can write to PCI config
* registers, we use a different file in the device's sysfs
* directory called "resource".
*
* The resource file contains all of the needed information in
* a format that is consistent across all platforms. Each BAR
* and the expansion ROM have a single line of data containing
* 3, 64-bit hex values: the first address in the region,
* the last address in the region, and the region's flags.
*/
snprintf( name, 255, "%s/%04x:%02x:%02x.%1u/resource",
SYS_BUS_PCI,
dev->domain,
dev->bus,
dev->dev,
dev->func );
fd = open( name, O_RDONLY | O_CLOEXEC);
if ( fd != -1 ) {
char * next;
pciaddr_t low_addr;
pciaddr_t high_addr;
pciaddr_t flags;
bytes = read( fd, resource, 512 );
resource[511] = '\0';
close( fd );
next = resource;
for ( i = 0 ; i < 6 ; i++ ) {
dev->regions[i].base_addr = strtoull( next, & next, 16 );
high_addr = strtoull( next, & next, 16 );
flags = strtoull( next, & next, 16 );
if ( dev->regions[i].base_addr != 0 ) {
dev->regions[i].size = (high_addr
- dev->regions[i].base_addr) + 1;
dev->regions[i].is_IO = (flags & 0x01);
dev->regions[i].is_64 = (flags & 0x04);
dev->regions[i].is_prefetchable = (flags & 0x08);
}
}
low_addr = strtoull( next, & next, 16 );
high_addr = strtoull( next, & next, 16 );
flags = strtoull( next, & next, 16 );
if ( low_addr != 0 ) {
priv->rom_base = low_addr;
dev->rom_size = (high_addr - low_addr) + 1;
}
}
}
return err;
}
static int
pci_device_linux_sysfs_read_rom( struct pci_device * dev, void * buffer )
{
char name[256];
int fd;
struct stat st;
int err = 0;
size_t rom_size;
size_t total_bytes;
snprintf( name, 255, "%s/%04x:%02x:%02x.%1u/rom",
SYS_BUS_PCI,
dev->domain,
dev->bus,
dev->dev,
dev->func );
fd = open( name, O_RDWR | O_CLOEXEC);
if ( fd == -1 ) {
#ifdef LINUX_ROM
/* If reading the ROM using sysfs fails, fall back to the old
* /dev/mem based interface.
* disable this for newer kernels using configure
*/
return pci_device_linux_devmem_read_rom(dev, buffer);
#else
return errno;
#endif
}
if ( fstat( fd, & st ) == -1 ) {
close( fd );
return errno;
}
rom_size = st.st_size;
if ( rom_size == 0 )
rom_size = 0x10000;
/* This is a quirky thing on Linux. Even though the ROM and the file
* for the ROM in sysfs are read-only, the string "1" must be written to
* the file to enable the ROM. After the data has been read, "0" must be
* written to the file to disable the ROM.
*/
write( fd, "1", 1 );
lseek( fd, 0, SEEK_SET );
for ( total_bytes = 0 ; total_bytes < rom_size ; /* empty */ ) {
const int bytes = read( fd, (char *) buffer + total_bytes,
rom_size - total_bytes );
if ( bytes == -1 ) {
err = errno;
break;
}
else if ( bytes == 0 ) {
break;
}
total_bytes += bytes;
}
lseek( fd, 0, SEEK_SET );
write( fd, "0", 1 );
close( fd );
return err;
}
static int
pci_device_linux_sysfs_read( struct pci_device * dev, void * data,
pciaddr_t offset, pciaddr_t size,
pciaddr_t * bytes_read )
{
char name[256];
pciaddr_t temp_size = size;
int err = 0;
int fd;
char *data_bytes = data;
if ( bytes_read != NULL ) {
*bytes_read = 0;
}
/* Each device has a directory under sysfs. Within that directory there
* is a file named "config". This file used to access the PCI config
* space. It is used here to obtain most of the information about the
* device.
*/
snprintf( name, 255, "%s/%04x:%02x:%02x.%1u/config",
SYS_BUS_PCI,
dev->domain,
dev->bus,
dev->dev,
dev->func );
fd = open( name, O_RDONLY | O_CLOEXEC);
if ( fd == -1 ) {
return errno;
}
while ( temp_size > 0 ) {
const ssize_t bytes = pread64( fd, data_bytes, temp_size, offset );
/* If zero bytes were read, then we assume it's the end of the
* config file.
*/
if (bytes == 0)
break;
if ( bytes < 0 ) {
err = errno;
break;
}
temp_size -= bytes;
offset += bytes;
data_bytes += bytes;
}
if ( bytes_read != NULL ) {
*bytes_read = size - temp_size;
}
close( fd );
return err;
}
static int
pci_device_linux_sysfs_write( struct pci_device * dev, const void * data,
pciaddr_t offset, pciaddr_t size,
pciaddr_t * bytes_written )
{
char name[256];
pciaddr_t temp_size = size;
int err = 0;
int fd;
const char *data_bytes = data;
if ( bytes_written != NULL ) {
*bytes_written = 0;
}
/* Each device has a directory under sysfs. Within that directory there
* is a file named "config". This file used to access the PCI config
* space. It is used here to obtain most of the information about the
* device.
*/
snprintf( name, 255, "%s/%04x:%02x:%02x.%1u/config",
SYS_BUS_PCI,
dev->domain,
dev->bus,
dev->dev,
dev->func );
fd = open( name, O_WRONLY | O_CLOEXEC);
if ( fd == -1 ) {
return errno;
}
while ( temp_size > 0 ) {
const ssize_t bytes = pwrite64( fd, data_bytes, temp_size, offset );
/* If zero bytes were written, then we assume it's the end of the
* config file.
*/
if ( bytes == 0 )
break;
if ( bytes < 0 ) {
err = errno;
break;
}
temp_size -= bytes;
offset += bytes;
data_bytes += bytes;
}
if ( bytes_written != NULL ) {
*bytes_written = size - temp_size;
}
close( fd );
return err;
}
static int
pci_device_linux_sysfs_map_range_wc(struct pci_device *dev,
struct pci_device_mapping *map)
{
char name[256];
int fd;
const int prot = ((map->flags & PCI_DEV_MAP_FLAG_WRITABLE) != 0)
? (PROT_READ | PROT_WRITE) : PROT_READ;
const int open_flags = ((map->flags & PCI_DEV_MAP_FLAG_WRITABLE) != 0)
? O_RDWR : O_RDONLY;
const off_t offset = map->base - dev->regions[map->region].base_addr;
snprintf(name, 255, "%s/%04x:%02x:%02x.%1u/resource%u_wc",
SYS_BUS_PCI,
dev->domain,
dev->bus,
dev->dev,
dev->func,
map->region);
fd = open(name, open_flags | O_CLOEXEC);
if (fd == -1)
return errno;
map->memory = mmap(NULL, map->size, prot, MAP_SHARED, fd, offset);
if (map->memory == MAP_FAILED) {
map->memory = NULL;
close(fd);
return errno;
}
close(fd);
return 0;
}
/**
* Map a memory region for a device using the Linux sysfs interface.
*
* \param dev Device whose memory region is to be mapped.
* \param map Parameters of the mapping that is to be created.
*
* \return
* Zero on success or an \c errno value on failure.
*
* \sa pci_device_map_rrange, pci_device_linux_sysfs_unmap_range
*
* \todo
* Some older 2.6.x kernels don't implement the resourceN files. On those
* systems /dev/mem must be used. On these systems it is also possible that
* \c mmap64 may need to be used.
*/
static int
pci_device_linux_sysfs_map_range(struct pci_device *dev,
struct pci_device_mapping *map)
{
char name[256];
int fd;
int err = 0;
const int prot = ((map->flags & PCI_DEV_MAP_FLAG_WRITABLE) != 0)
? (PROT_READ | PROT_WRITE) : PROT_READ;
const int open_flags = ((map->flags & PCI_DEV_MAP_FLAG_WRITABLE) != 0)
? O_RDWR : O_RDONLY;
const off_t offset = map->base - dev->regions[map->region].base_addr;
#ifdef HAVE_MTRR
struct mtrr_sentry sentry = {
.base = map->base,
.size = map->size,
.type = MTRR_TYPE_UNCACHABLE
};
#endif
/* For WC mappings, try sysfs resourceN_wc file first */
if ((map->flags & PCI_DEV_MAP_FLAG_WRITE_COMBINE) &&
!pci_device_linux_sysfs_map_range_wc(dev, map))
return 0;
snprintf(name, 255, "%s/%04x:%02x:%02x.%1u/resource%u",
SYS_BUS_PCI,
dev->domain,
dev->bus,
dev->dev,
dev->func,
map->region);
fd = open(name, open_flags | O_CLOEXEC);
if (fd == -1) {
return errno;
}
map->memory = mmap(NULL, map->size, prot, MAP_SHARED, fd, offset);
if (map->memory == MAP_FAILED) {
map->memory = NULL;
close(fd);
return errno;
}
#ifdef HAVE_MTRR
if ((map->flags & PCI_DEV_MAP_FLAG_CACHABLE) != 0) {
sentry.type = MTRR_TYPE_WRBACK;
} else if ((map->flags & PCI_DEV_MAP_FLAG_WRITE_COMBINE) != 0) {
sentry.type = MTRR_TYPE_WRCOMB;
}
if (pci_sys->mtrr_fd != -1 && sentry.type != MTRR_TYPE_UNCACHABLE) {
if (ioctl(pci_sys->mtrr_fd, MTRRIOC_ADD_ENTRY, &sentry) < 0) {
/* FIXME: Should we report an error in this case?
*/
fprintf(stderr, "error setting MTRR "
"(base = 0x%08lx, size = 0x%08x, type = %u) %s (%d)\n",
sentry.base, sentry.size, sentry.type,
strerror(errno), errno);
/* err = errno;*/
}
/* KLUDGE ALERT -- rewrite the PTEs to turn off the CD and WT bits */
mprotect (map->memory, map->size, PROT_NONE);
err = mprotect (map->memory, map->size, PROT_READ|PROT_WRITE);
if (err != 0) {
fprintf(stderr, "mprotect(PROT_READ | PROT_WRITE) failed: %s\n",
strerror(errno));
fprintf(stderr, "remapping without mprotect performance kludge.\n");
munmap(map->memory, map->size);
map->memory = mmap(NULL, map->size, prot, MAP_SHARED, fd, offset);
if (map->memory == MAP_FAILED) {
map->memory = NULL;
close(fd);
return errno;
}
}
}
#endif
close(fd);
return 0;
}
/**
* Unmap a memory region for a device using the Linux sysfs interface.
*
* \param dev Device whose memory region is to be unmapped.
* \param map Parameters of the mapping that is to be destroyed.
*
* \return
* Zero on success or an \c errno value on failure.
*
* \sa pci_device_map_rrange, pci_device_linux_sysfs_map_range
*
* \todo
* Some older 2.6.x kernels don't implement the resourceN files. On those
* systems /dev/mem must be used. On these systems it is also possible that
* \c mmap64 may need to be used.
*/
static int
pci_device_linux_sysfs_unmap_range(struct pci_device *dev,
struct pci_device_mapping *map)
{
int err = 0;
#ifdef HAVE_MTRR
struct mtrr_sentry sentry = {
.base = map->base,
.size = map->size,
.type = MTRR_TYPE_UNCACHABLE
};
#endif
err = pci_device_generic_unmap_range (dev, map);
if (err)
return err;
#ifdef HAVE_MTRR
if ((map->flags & PCI_DEV_MAP_FLAG_CACHABLE) != 0) {
sentry.type = MTRR_TYPE_WRBACK;
} else if ((map->flags & PCI_DEV_MAP_FLAG_WRITE_COMBINE) != 0) {
sentry.type = MTRR_TYPE_WRCOMB;
}
if (pci_sys->mtrr_fd != -1 && sentry.type != MTRR_TYPE_UNCACHABLE) {
if (ioctl(pci_sys->mtrr_fd, MTRRIOC_DEL_ENTRY, &sentry) < 0) {
/* FIXME: Should we report an error in this case?
*/
fprintf(stderr, "error setting MTRR "
"(base = 0x%08lx, size = 0x%08x, type = %u) %s (%d)\n",
sentry.base, sentry.size, sentry.type,
strerror(errno), errno);
/* err = errno;*/
}
}
#endif
return err;
}
static void pci_device_linux_sysfs_enable(struct pci_device *dev)
{
char name[256];
int fd;
snprintf( name, 255, "%s/%04x:%02x:%02x.%1u/enable",
SYS_BUS_PCI,
dev->domain,
dev->bus,
dev->dev,
dev->func );
fd = open( name, O_RDWR | O_CLOEXEC);
if (fd == -1)
return;
write( fd, "1", 1 );
close(fd);
}
static int pci_device_linux_sysfs_boot_vga(struct pci_device *dev)
{
char name[256];
char reply[3];
int fd, bytes_read;
int ret = 0;
snprintf( name, 255, "%s/%04x:%02x:%02x.%1u/boot_vga",
SYS_BUS_PCI,
dev->domain,
dev->bus,
dev->dev,
dev->func );
fd = open( name, O_RDONLY | O_CLOEXEC);
if (fd == -1)
return 0;
bytes_read = read(fd, reply, 1);
if (bytes_read != 1)
goto out;
if (reply[0] == '1')
ret = 1;
out:
close(fd);
return ret;
}
static int pci_device_linux_sysfs_has_kernel_driver(struct pci_device *dev)
{
char name[256];
struct stat dummy;
int ret;
snprintf( name, 255, "%s/%04x:%02x:%02x.%1u/driver",
SYS_BUS_PCI,
dev->domain,
dev->bus,
dev->dev,
dev->func );
ret = stat(name, &dummy);
if (ret < 0)
return 0;
return 1;
}
static struct pci_io_handle *
pci_device_linux_sysfs_open_device_io(struct pci_io_handle *ret,
struct pci_device *dev, int bar,
pciaddr_t base, pciaddr_t size)
{
char name[PATH_MAX];
snprintf(name, PATH_MAX, "%s/%04x:%02x:%02x.%1u/resource%d",
SYS_BUS_PCI, dev->domain, dev->bus, dev->dev, dev->func, bar);
ret->fd = open(name, O_RDWR | O_CLOEXEC);
if (ret->fd < 0)
return NULL;
ret->base = base;
ret->size = size;
return ret;
}
static struct pci_io_handle *
pci_device_linux_sysfs_open_legacy_io(struct pci_io_handle *ret,
struct pci_device *dev, pciaddr_t base,
pciaddr_t size)
{
char name[PATH_MAX];
/* First check if there's a legacy io method for the device */
while (dev) {
snprintf(name, PATH_MAX, "/sys/class/pci_bus/%04x:%02x/legacy_io",
dev->domain, dev->bus);
ret->fd = open(name, O_RDWR | O_CLOEXEC);
if (ret->fd >= 0)
break;
dev = pci_device_get_parent_bridge(dev);
}
/*
* You would think you'd want to use /dev/port here. Don't make that
* mistake, /dev/port only does byte-wide i/o cycles which means it
* doesn't work. If you think this is stupid, well, you're right.
*/
/* If we've no other choice, iopl */
if (ret->fd < 0) {
if (iopl(3))
return NULL;
}
ret->base = base;
ret->size = size;
return ret;
}
static void
pci_device_linux_sysfs_close_io(struct pci_device *dev,
struct pci_io_handle *handle)
{
if (handle->fd > -1)
close(handle->fd);
}
static uint32_t
pci_device_linux_sysfs_read32(struct pci_io_handle *handle, uint32_t port)
{
uint32_t ret;
if (handle->fd > -1)
pread(handle->fd, &ret, 4, port + handle->base);
else
ret = inl(port + handle->base);
return ret;
}
static uint16_t
pci_device_linux_sysfs_read16(struct pci_io_handle *handle, uint32_t port)
{
uint16_t ret;
if (handle->fd > -1)
pread(handle->fd, &ret, 2, port + handle->base);
else
ret = inw(port + handle->base);
return ret;
}
static uint8_t
pci_device_linux_sysfs_read8(struct pci_io_handle *handle, uint32_t port)
{
uint8_t ret;
if (handle->fd > -1)
pread(handle->fd, &ret, 1, port + handle->base);
else
ret = inb(port + handle->base);
return ret;
}
static void
pci_device_linux_sysfs_write32(struct pci_io_handle *handle, uint32_t port,
uint32_t data)
{
if (handle->fd > -1)
pwrite(handle->fd, &data, 4, port + handle->base);
else
outl(data, port + handle->base);
}
static void
pci_device_linux_sysfs_write16(struct pci_io_handle *handle, uint32_t port,
uint16_t data)
{
if (handle->fd > -1)
pwrite(handle->fd, &data, 2, port + handle->base);
else
outw(data, port + handle->base);
}
static void
pci_device_linux_sysfs_write8(struct pci_io_handle *handle, uint32_t port,
uint8_t data)
{
if (handle->fd > -1)
pwrite(handle->fd, &data, 1, port + handle->base);
else
outb(data, port + handle->base);
}
static int
pci_device_linux_sysfs_map_legacy(struct pci_device *dev, pciaddr_t base,
pciaddr_t size, unsigned map_flags, void **addr)
{
char name[PATH_MAX];
int flags = O_RDONLY;
int prot = PROT_READ;
int fd;
int ret=0;
if (map_flags & PCI_DEV_MAP_FLAG_WRITABLE) {
flags = O_RDWR; /* O_RDWR != O_WRONLY | O_RDONLY */;
prot |= PROT_WRITE;
}
/* First check if there's a legacy memory method for the device */
while (dev) {
snprintf(name, PATH_MAX, "/sys/class/pci_bus/%04x:%02x/legacy_mem",
dev->domain, dev->bus);
fd = open(name, flags | O_CLOEXEC);
if (fd >= 0)
break;
dev = pci_device_get_parent_bridge(dev);
}
/* If not, /dev/mem is the best we can do */
if (!dev)
fd = open("/dev/mem", flags | O_CLOEXEC);
if (fd < 0)
return errno;
*addr = mmap(NULL, size, prot, MAP_SHARED, fd, base);
if (*addr == MAP_FAILED) {
ret = errno;
}
close(fd);
return ret;
}
static int
pci_device_linux_sysfs_unmap_legacy(struct pci_device *dev, void *addr, pciaddr_t size)
{
return munmap(addr, size);
}
static void
pci_system_linux_destroy(void)
{
#ifdef HAVE_MTRR
if (pci_sys->mtrr_fd != -1)
close(pci_sys->mtrr_fd);
#endif
}
static const struct pci_system_methods linux_sysfs_methods = {
.destroy = pci_system_linux_destroy,
.destroy_device = NULL,
.read_rom = pci_device_linux_sysfs_read_rom,
.probe = pci_device_linux_sysfs_probe,
.map_range = pci_device_linux_sysfs_map_range,
.unmap_range = pci_device_linux_sysfs_unmap_range,
.read = pci_device_linux_sysfs_read,
.write = pci_device_linux_sysfs_write,
.fill_capabilities = pci_fill_capabilities_generic,
.enable = pci_device_linux_sysfs_enable,
.boot_vga = pci_device_linux_sysfs_boot_vga,
.has_kernel_driver = pci_device_linux_sysfs_has_kernel_driver,
.open_device_io = pci_device_linux_sysfs_open_device_io,
.open_legacy_io = pci_device_linux_sysfs_open_legacy_io,
.close_io = pci_device_linux_sysfs_close_io,
.read32 = pci_device_linux_sysfs_read32,
.read16 = pci_device_linux_sysfs_read16,
.read8 = pci_device_linux_sysfs_read8,
.write32 = pci_device_linux_sysfs_write32,
.write16 = pci_device_linux_sysfs_write16,
.write8 = pci_device_linux_sysfs_write8,
.map_legacy = pci_device_linux_sysfs_map_legacy,
.unmap_legacy = pci_device_linux_sysfs_unmap_legacy,
};
size = map->size,
.type = MTRR_TYPE_UNCACHABLE
};
#endif
/* For WC mappings, try sysfs resourceN_wc file first */
if ((map->flags & PCI_DEV_MAP_FLAG_WRITE_COMBINE) &&
!pci_device_linux_sysfslibpciaccess-0.13.2/src/Makefile.in 0000644 0143106 0000012 00000061310 12172612466 0017345 0 ustar 00alanc staff 0000266 0200005 # Makefile.in generated by automake 1.14 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2013 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
#
# (C) Copyright IBM Corporation 2006
# All Rights Reserved.
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# on the rights to use, copy, modify, merge, publish, distribute, sub
# license, and/or sell copies of the Software, and to permit persons to whom
# the Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice (including the next
# paragraph) shall be included in all copies or substantial portions of the
# Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
# IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
VPATH = @srcdir@
am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
*) echo "am__make_running_with_option: internal error: invalid" \
"target option '$${target_option-}' specified" >&2; \
exit 1;; \
esac; \
has_opt=no; \
sane_makeflags=$$MAKEFLAGS; \
if $(am__is_gnu_make); then \
sane_makeflags=$$MFLAGS; \
else \
case $$MAKEFLAGS in \
*\\[\ \ ]*) \
bs=\\; \
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
esac; \
fi; \
skip_next=no; \
strip_trailopt () \
{ \
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
}; \
for flg in $$sane_makeflags; do \
test $$skip_next = yes && { skip_next=no; continue; }; \
case $$flg in \
*=*|--*) continue;; \
-*I) strip_trailopt 'I'; skip_next=yes;; \
-*I?*) strip_trailopt 'I';; \
-*O) strip_trailopt 'O'; skip_next=yes;; \
-*O?*) strip_trailopt 'O';; \
-*l) strip_trailopt 'l'; skip_next=yes;; \
-*l?*) strip_trailopt 'l';; \
-[dEDm]) skip_next=yes;; \
-[JT]) skip_next=yes;; \
esac; \
case $$flg in \
*$$target_option*) has_opt=yes; break;; \
esac; \
done; \
test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = src
DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
$(top_srcdir)/depcomp
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_define_dir.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
*) f=$$p;; \
esac;
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
am__install_max = 40
am__nobase_strip_setup = \
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
am__nobase_strip = \
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
am__nobase_list = $(am__nobase_strip_setup); \
for p in $$list; do echo "$$p $$p"; done | \
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
if (++n[$$2] == $(am__install_max)) \
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
END { for (dir in files) print dir, files[dir] }'
am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__uninstall_files_from_dir = { \
test -z "$$files" \
|| { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \
$(am__cd) "$$dir" && rm -f $$files; }; \
}
am__installdirs = "$(DESTDIR)$(libdir)"
LTLIBRARIES = $(lib_LTLIBRARIES)
am__DEPENDENCIES_1 =
libpciaccess_la_DEPENDENCIES = $(am__DEPENDENCIES_1)
am__libpciaccess_la_SOURCES_DIST = common_bridge.c common_iterator.c \
common_init.c common_interface.c common_io.c \
common_capability.c common_device_name.c common_map.c \
pciaccess_private.h common_vgaarb_stub.c common_vgaarb.c \
freebsd_pci.c x86_pci.c linux_sysfs.c linux_devmem.c \
linux_devmem.h netbsd_pci.c openbsd_pci.c solx_devfs.c \
pci_tools.h
@FREEBSD_FALSE@@GNU_FALSE@@LINUX_FALSE@@NETBSD_FALSE@@SOLARIS_TRUE@am__objects_1 = common_vgaarb_stub.lo
@FREEBSD_FALSE@@GNU_FALSE@@LINUX_FALSE@@NETBSD_TRUE@am__objects_1 = common_vgaarb_stub.lo
@FREEBSD_FALSE@@GNU_FALSE@@LINUX_TRUE@am__objects_1 = \
@FREEBSD_FALSE@@GNU_FALSE@@LINUX_TRUE@ common_vgaarb.lo
@FREEBSD_FALSE@@GNU_TRUE@am__objects_1 = common_vgaarb_stub.lo
@FREEBSD_TRUE@am__objects_1 = common_vgaarb_stub.lo
@FREEBSD_FALSE@@GNU_FALSE@@LINUX_FALSE@@NETBSD_FALSE@@OPENBSD_FALSE@@SOLARIS_TRUE@am__objects_2 = solx_devfs.lo
@FREEBSD_FALSE@@GNU_FALSE@@LINUX_FALSE@@NETBSD_FALSE@@OPENBSD_TRUE@am__objects_2 = openbsd_pci.lo
@FREEBSD_FALSE@@GNU_FALSE@@LINUX_FALSE@@NETBSD_TRUE@am__objects_2 = netbsd_pci.lo
@FREEBSD_FALSE@@GNU_FALSE@@LINUX_TRUE@am__objects_2 = linux_sysfs.lo \
@FREEBSD_FALSE@@GNU_FALSE@@LINUX_TRUE@ linux_devmem.lo
@FREEBSD_FALSE@@GNU_TRUE@am__objects_2 = x86_pci.lo
@FREEBSD_TRUE@am__objects_2 = freebsd_pci.lo
am_libpciaccess_la_OBJECTS = common_bridge.lo common_iterator.lo \
common_init.lo common_interface.lo common_io.lo \
common_capability.lo common_device_name.lo common_map.lo \
$(am__objects_1) $(am__objects_2)
libpciaccess_la_OBJECTS = $(am_libpciaccess_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
am__v_lt_0 = --silent
am__v_lt_1 =
libpciaccess_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
$(AM_CFLAGS) $(CFLAGS) $(libpciaccess_la_LDFLAGS) $(LDFLAGS) \
-o $@
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo " GEN " $@;
am__v_GEN_1 =
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 =
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CFLAGS) $(CFLAGS)
AM_V_CC = $(am__v_CC_@AM_V@)
am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
am__v_CC_0 = @echo " CC " $@;
am__v_CC_1 =
CCLD = $(CC)
LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
AM_V_CCLD = $(am__v_CCLD_@AM_V@)
am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
am__v_CCLD_0 = @echo " CCLD " $@;
am__v_CCLD_1 =
SOURCES = $(libpciaccess_la_SOURCES)
DIST_SOURCES = $(am__libpciaccess_la_SOURCES_DIST)
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
# Read a list of newline-separated strings from the standard input,
# and print each of them once, without duplicates. Input order is
# *not* preserved.
am__uniquify_input = $(AWK) '\
BEGIN { nonempty = 0; } \
{ items[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in items) print i; }; } \
'
# Make sure the list of sources is unique. This is necessary because,
# e.g., the same source file might be shared among _SOURCES variables
# for different programs/libraries.
am__define_uniq_tagged_files = \
list='$(am__tagged_files)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
ADMIN_MAN_DIR = @ADMIN_MAN_DIR@
ADMIN_MAN_SUFFIX = @ADMIN_MAN_SUFFIX@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
APP_MAN_DIR = @APP_MAN_DIR@
APP_MAN_SUFFIX = @APP_MAN_SUFFIX@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
BASE_CFLAGS = @BASE_CFLAGS@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CHANGELOG_CMD = @CHANGELOG_CMD@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CWARNFLAGS = @CWARNFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DRIVER_MAN_DIR = @DRIVER_MAN_DIR@
DRIVER_MAN_SUFFIX = @DRIVER_MAN_SUFFIX@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
FILE_MAN_DIR = @FILE_MAN_DIR@
FILE_MAN_SUFFIX = @FILE_MAN_SUFFIX@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_CMD = @INSTALL_CMD@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIB_MAN_DIR = @LIB_MAN_DIR@
LIB_MAN_SUFFIX = @LIB_MAN_SUFFIX@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MAN_SUBSTS = @MAN_SUBSTS@
MISC_MAN_DIR = @MISC_MAN_DIR@
MISC_MAN_SUFFIX = @MISC_MAN_SUFFIX@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PCIACCESS_CFLAGS = @PCIACCESS_CFLAGS@
PCIACCESS_LIBS = @PCIACCESS_LIBS@
PCIIDS_PATH = @PCIIDS_PATH@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRICT_CFLAGS = @STRICT_CFLAGS@
STRIP = @STRIP@
VERSION = @VERSION@
XORG_MAN_PAGE = @XORG_MAN_PAGE@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
AM_CPPFLAGS = -I$(top_srcdir)/include
AM_CFLAGS = $(CWARNFLAGS) @PCIACCESS_CFLAGS@
lib_LTLIBRARIES = libpciaccess.la
@FREEBSD_TRUE@OS_SUPPORT = freebsd_pci.c
@GNU_TRUE@OS_SUPPORT = x86_pci.c
@LINUX_TRUE@OS_SUPPORT = linux_sysfs.c linux_devmem.c linux_devmem.h
@NETBSD_TRUE@OS_SUPPORT = netbsd_pci.c
@OPENBSD_TRUE@OS_SUPPORT = openbsd_pci.c
# VGA Arbiter code is included in openbsd_pci.c
@SOLARIS_TRUE@OS_SUPPORT = solx_devfs.c pci_tools.h
@FREEBSD_TRUE@VGA_ARBITER = common_vgaarb_stub.c
@GNU_TRUE@VGA_ARBITER = common_vgaarb_stub.c
@LINUX_TRUE@VGA_ARBITER = common_vgaarb.c
@NETBSD_TRUE@VGA_ARBITER = common_vgaarb_stub.c
@SOLARIS_TRUE@VGA_ARBITER = common_vgaarb_stub.c
libpciaccess_la_SOURCES = common_bridge.c \
common_iterator.c \
common_init.c \
common_interface.c \
common_io.c \
common_capability.c \
common_device_name.c \
common_map.c \
pciaccess_private.h \
$(VGA_ARBITER) \
$(OS_SUPPORT)
libpciaccess_la_LIBADD = $(PCIACCESS_LIBS)
libpciaccess_la_LDFLAGS = -version-number 0:11:1 -no-undefined
all: all-am
.SUFFIXES:
.SUFFIXES: .c .lo .o .obj
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign src/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
@$(NORMAL_INSTALL)
@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
list2=; for p in $$list; do \
if test -f $$p; then \
list2="$$list2 $$p"; \
else :; fi; \
done; \
test -z "$$list2" || { \
echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \
$(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
}
uninstall-libLTLIBRARIES:
@$(NORMAL_UNINSTALL)
@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
for p in $$list; do \
$(am__strip_dir) \
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
done
clean-libLTLIBRARIES:
-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
@list='$(lib_LTLIBRARIES)'; \
locs=`for p in $$list; do echo $$p; done | \
sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
sort -u`; \
test -z "$$locs" || { \
echo rm -f $${locs}; \
rm -f $${locs}; \
}
libpciaccess.la: $(libpciaccess_la_OBJECTS) $(libpciaccess_la_DEPENDENCIES) $(EXTRA_libpciaccess_la_DEPENDENCIES)
$(AM_V_CCLD)$(libpciaccess_la_LINK) -rpath $(libdir) $(libpciaccess_la_OBJECTS) $(libpciaccess_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/common_bridge.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/common_capability.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/common_device_name.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/common_init.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/common_interface.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/common_io.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/common_iterator.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/common_map.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/common_vgaarb.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/common_vgaarb_stub.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/freebsd_pci.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/linux_devmem.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/linux_sysfs.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/netbsd_pci.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openbsd_pci.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/solx_devfs.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/x86_pci.Plo@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
.c.obj:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
.c.lo:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
ID: $(am__tagged_files)
$(am__define_uniq_tagged_files); mkid -fID $$unique
tags: tags-am
TAGS: tags
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
set x; \
here=`pwd`; \
$(am__define_uniq_tagged_files); \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: ctags-am
CTAGS: ctags
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
$(am__define_uniq_tagged_files); \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
cscopelist: cscopelist-am
cscopelist-am: $(am__tagged_files)
list='$(am__tagged_files)'; \
case "$(srcdir)" in \
[\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
*) sdir=$(subdir)/$(srcdir) ;; \
esac; \
for i in $$list; do \
if test -f "$$i"; then \
echo "$(subdir)/$$i"; \
else \
echo "$$sdir/$$i"; \
fi; \
done >> $(top_builddir)/cscope.files
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(LTLIBRARIES)
installdirs:
for dir in "$(DESTDIR)$(libdir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
if test -z '$(STRIP)'; then \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
install; \
else \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am:
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am: install-libLTLIBRARIES
install-html: install-html-am
install-html-am:
install-info: install-info-am
install-info-am:
install-man:
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-libLTLIBRARIES
.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
clean-libLTLIBRARIES clean-libtool cscopelist-am ctags \
ctags-am distclean distclean-compile distclean-generic \
distclean-libtool distclean-tags distdir dvi dvi-am html \
html-am info info-am install install-am install-data \
install-data-am install-dvi install-dvi-am install-exec \
install-exec-am install-html install-html-am install-info \
install-info-am install-libLTLIBRARIES install-man install-pdf \
install-pdf-am install-ps install-ps-am install-strip \
installcheck installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags tags-am uninstall uninstall-am uninstall-libLTLIBRARIES
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
AGS) am--refresh
$(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
@$(NORMAL_INSTALL)
libpciaccess-0.13.2/src/openbsd_pci.c 0000644 0143106 0000012 00000043722 12172612452 0017733 0 ustar 00alanc staff 0000266 0200005 /*
* Copyright (c) 2008, 2011 Mark Kettenis
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "pciaccess.h"
#include "pciaccess_private.h"
/*
* This should allow for 16 domains, which should cover everything
* except perhaps the really big fridge-sized sparc64 server machines
* that are unlikely to have any graphics hardware in them.
*/
static int pcifd[16];
static int ndomains;
static int aperturefd = -1;
static int
pci_read(int domain, int bus, int dev, int func, uint32_t reg, uint32_t *val)
{
struct pci_io io;
int err;
bzero(&io, sizeof(io));
io.pi_sel.pc_bus = bus;
io.pi_sel.pc_dev = dev;
io.pi_sel.pc_func = func;
io.pi_reg = reg;
io.pi_width = 4;
err = ioctl(pcifd[domain], PCIOCREAD, &io);
if (err)
return (err);
*val = io.pi_data;
return 0;
}
static int
pci_write(int domain, int bus, int dev, int func, uint32_t reg, uint32_t val)
{
struct pci_io io;
bzero(&io, sizeof(io));
io.pi_sel.pc_bus = bus;
io.pi_sel.pc_dev = dev;
io.pi_sel.pc_func = func;
io.pi_reg = reg;
io.pi_width = 4;
io.pi_data = val;
return ioctl(pcifd[domain], PCIOCWRITE, &io);
}
/**
* Read a VGA ROM
*
*/
static int
pci_device_openbsd_read_rom(struct pci_device *device, void *buffer)
{
struct pci_device_private *priv = (struct pci_device_private *)device;
unsigned char *bios;
pciaddr_t rom_base;
pciaddr_t rom_size;
u_int32_t csr, rom;
int pci_rom, domain, bus, dev, func;
domain = device->domain;
if (domain < 0 || domain >= ndomains)
return ENXIO;
bus = device->bus;
dev = device->dev;
func = device->func;
if (aperturefd == -1)
return ENOSYS;
if (priv->base.rom_size == 0) {
#if defined(__alpha__) || defined(__amd64__) || defined(__i386__)
if ((device->device_class & 0x00ffff00) ==
((PCI_CLASS_DISPLAY << 16) |
(PCI_SUBCLASS_DISPLAY_VGA << 8))) {
rom_base = 0xc0000;
rom_size = 0x10000;
pci_rom = 0;
} else
#endif
return ENOSYS;
} else {
rom_base = priv->rom_base;
rom_size = priv->base.rom_size;
pci_rom = 1;
pci_read(domain, bus, dev, func, PCI_COMMAND_STATUS_REG, &csr);
pci_write(domain, bus, dev, func, PCI_COMMAND_STATUS_REG,
csr | PCI_COMMAND_MEM_ENABLE);
pci_read(domain, bus, dev, func, PCI_ROM_REG, &rom);
pci_write(domain, bus, dev, func, PCI_ROM_REG,
rom | PCI_ROM_ENABLE);
}
bios = mmap(NULL, rom_size, PROT_READ, MAP_SHARED,
aperturefd, (off_t)rom_base);
if (bios == MAP_FAILED)
return errno;
memcpy(buffer, bios, rom_size);
munmap(bios, rom_size);
if (pci_rom) {
/* Restore PCI config space */
pci_write(domain, bus, dev, func, PCI_ROM_REG, rom);
pci_write(domain, bus, dev, func, PCI_COMMAND_STATUS_REG, csr);
}
return 0;
}
static int
pci_nfuncs(int domain, int bus, int dev)
{
uint32_t hdr;
if (domain < 0 || domain >= ndomains)
return ENXIO;
if (pci_read(domain, bus, dev, 0, PCI_BHLC_REG, &hdr) != 0)
return -1;
return (PCI_HDRTYPE_MULTIFN(hdr) ? 8 : 1);
}
static int
pci_device_openbsd_map_range(struct pci_device *dev,
struct pci_device_mapping *map)
{
struct mem_range_desc mr;
struct mem_range_op mo;
int prot = PROT_READ;
if (map->flags & PCI_DEV_MAP_FLAG_WRITABLE)
prot |= PROT_WRITE;
map->memory = mmap(NULL, map->size, prot, MAP_SHARED, aperturefd,
map->base);
if (map->memory == MAP_FAILED)
return errno;
#if defined(__i386__) || defined(__amd64__)
/* No need to set an MTRR if it's the default mode. */
if ((map->flags & PCI_DEV_MAP_FLAG_CACHABLE) ||
(map->flags & PCI_DEV_MAP_FLAG_WRITE_COMBINE)) {
mr.mr_base = map->base;
mr.mr_len = map->size;
mr.mr_flags = 0;
if (map->flags & PCI_DEV_MAP_FLAG_CACHABLE)
mr.mr_flags |= MDF_WRITEBACK;
if (map->flags & PCI_DEV_MAP_FLAG_WRITE_COMBINE)
mr.mr_flags |= MDF_WRITECOMBINE;
strlcpy(mr.mr_owner, "pciaccess", sizeof(mr.mr_owner));
mo.mo_desc = &mr;
mo.mo_arg[0] = MEMRANGE_SET_UPDATE;
if (ioctl(aperturefd, MEMRANGE_SET, &mo))
(void)fprintf(stderr, "mtrr set failed: %s\n",
strerror(errno));
}
#endif
return 0;
}
static int
pci_device_openbsd_unmap_range(struct pci_device *dev,
struct pci_device_mapping *map)
{
#if defined(__i386__) || defined(__amd64__)
struct mem_range_desc mr;
struct mem_range_op mo;
if ((map->flags & PCI_DEV_MAP_FLAG_CACHABLE) ||
(map->flags & PCI_DEV_MAP_FLAG_WRITE_COMBINE)) {
mr.mr_base = map->base;
mr.mr_len = map->size;
mr.mr_flags = MDF_UNCACHEABLE;
strlcpy(mr.mr_owner, "pciaccess", sizeof(mr.mr_owner));
mo.mo_desc = &mr;
mo.mo_arg[0] = MEMRANGE_SET_REMOVE;
(void)ioctl(aperturefd, MEMRANGE_SET, &mo);
}
#endif
return pci_device_generic_unmap_range(dev, map);
}
static int
pci_device_openbsd_read(struct pci_device *dev, void *data,
pciaddr_t offset, pciaddr_t size, pciaddr_t *bytes_read)
{
struct pci_io io;
io.pi_sel.pc_bus = dev->bus;
io.pi_sel.pc_dev = dev->dev;
io.pi_sel.pc_func = dev->func;
*bytes_read = 0;
while (size > 0) {
int toread = MIN(size, 4 - (offset & 0x3));
io.pi_reg = (offset & ~0x3);
io.pi_width = 4;
if (ioctl(pcifd[dev->domain], PCIOCREAD, &io) == -1)
return errno;
io.pi_data = htole32(io.pi_data);
io.pi_data >>= ((offset & 0x3) * 8);
memcpy(data, &io.pi_data, toread);
offset += toread;
data = (char *)data + toread;
size -= toread;
*bytes_read += toread;
}
return 0;
}
static int
pci_device_openbsd_write(struct pci_device *dev, const void *data,
pciaddr_t offset, pciaddr_t size, pciaddr_t *bytes_written)
{
struct pci_io io;
if ((offset % 4) != 0 || (size % 4) != 0)
return EINVAL;
io.pi_sel.pc_bus = dev->bus;
io.pi_sel.pc_dev = dev->dev;
io.pi_sel.pc_func = dev->func;
*bytes_written = 0;
while (size > 0) {
io.pi_reg = offset;
io.pi_width = 4;
memcpy(&io.pi_data, data, 4);
if (ioctl(pcifd[dev->domain], PCIOCWRITE, &io) == -1)
return errno;
offset += 4;
data = (char *)data + 4;
size -= 4;
*bytes_written += 4;
}
return 0;
}
static void
pci_system_openbsd_destroy(void)
{
int domain;
for (domain = 0; domain < ndomains; domain++)
close(pcifd[domain]);
ndomains = 0;
}
static int
pci_device_openbsd_probe(struct pci_device *device)
{
struct pci_device_private *priv = (struct pci_device_private *)device;
struct pci_mem_region *region;
uint64_t reg64, size64;
uint32_t bar, reg, size;
int domain, bus, dev, func, err;
domain = device->domain;
bus = device->bus;
dev = device->dev;
func = device->func;
err = pci_read(domain, bus, dev, func, PCI_BHLC_REG, ®);
if (err)
return err;
priv->header_type = PCI_HDRTYPE_TYPE(reg);
if (priv->header_type != 0)
return 0;
region = device->regions;
for (bar = PCI_MAPREG_START; bar < PCI_MAPREG_END;
bar += sizeof(uint32_t), region++) {
err = pci_read(domain, bus, dev, func, bar, ®);
if (err)
return err;
/* Probe the size of the region. */
err = pci_write(domain, bus, dev, func, bar, ~0);
if (err)
return err;
pci_read(domain, bus, dev, func, bar, &size);
pci_write(domain, bus, dev, func, bar, reg);
if (PCI_MAPREG_TYPE(reg) == PCI_MAPREG_TYPE_IO) {
region->is_IO = 1;
region->base_addr = PCI_MAPREG_IO_ADDR(reg);
region->size = PCI_MAPREG_IO_SIZE(size);
} else {
if (PCI_MAPREG_MEM_PREFETCHABLE(reg))
region->is_prefetchable = 1;
switch(PCI_MAPREG_MEM_TYPE(reg)) {
case PCI_MAPREG_MEM_TYPE_32BIT:
case PCI_MAPREG_MEM_TYPE_32BIT_1M:
region->base_addr = PCI_MAPREG_MEM_ADDR(reg);
region->size = PCI_MAPREG_MEM_SIZE(size);
break;
case PCI_MAPREG_MEM_TYPE_64BIT:
region->is_64 = 1;
reg64 = reg;
size64 = size;
bar += sizeof(uint32_t);
err = pci_read(domain, bus, dev, func, bar, ®);
if (err)
return err;
reg64 |= (uint64_t)reg << 32;
err = pci_write(domain, bus, dev, func, bar, ~0);
if (err)
return err;
pci_read(domain, bus, dev, func, bar, &size);
pci_write(domain, bus, dev, func, bar, reg64 >> 32);
size64 |= (uint64_t)size << 32;
region->base_addr = PCI_MAPREG_MEM64_ADDR(reg64);
region->size = PCI_MAPREG_MEM64_SIZE(size64);
region++;
break;
}
}
}
/* Probe expansion ROM if present */
err = pci_read(domain, bus, dev, func, PCI_ROM_REG, ®);
if (err)
return err;
if (reg != 0) {
err = pci_write(domain, bus, dev, func, PCI_ROM_REG, ~PCI_ROM_ENABLE);
if (err)
return err;
pci_read(domain, bus, dev, func, PCI_ROM_REG, &size);
pci_write(domain, bus, dev, func, PCI_ROM_REG, reg);
if (PCI_ROM_ADDR(reg) != 0) {
priv->rom_base = PCI_ROM_ADDR(reg);
device->rom_size = PCI_ROM_SIZE(size);
}
}
return 0;
}
#if defined(__i386__) || defined(__amd64__)
#include
#include
#endif
static struct pci_io_handle *
pci_device_openbsd_open_legacy_io(struct pci_io_handle *ret,
struct pci_device *dev, pciaddr_t base, pciaddr_t size)
{
#if defined(__i386__)
struct i386_iopl_args ia;
ia.iopl = 1;
if (sysarch(I386_IOPL, &ia))
return NULL;
ret->base = base;
ret->size = size;
return ret;
#elif defined(__amd64__)
struct amd64_iopl_args ia;
ia.iopl = 1;
if (sysarch(AMD64_IOPL, &ia))
return NULL;
ret->base = base;
ret->size = size;
return ret;
#elif defined(PCI_MAGIC_IO_RANGE)
ret->memory = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED,
aperturefd, PCI_MAGIC_IO_RANGE + base);
if (ret->memory == MAP_FAILED)
return NULL;
ret->base = base;
ret->size = size;
return ret;
#else
return NULL;
#endif
}
static uint32_t
pci_device_openbsd_read32(struct pci_io_handle *handle, uint32_t reg)
{
#if defined(__i386__) || defined(__amd64__)
return inl(handle->base + reg);
#else
return *(uint32_t *)((uintptr_t)handle->memory + reg);
#endif
}
static uint16_t
pci_device_openbsd_read16(struct pci_io_handle *handle, uint32_t reg)
{
#if defined(__i386__) || defined(__amd64__)
return inw(handle->base + reg);
#else
return *(uint16_t *)((uintptr_t)handle->memory + reg);
#endif
}
static uint8_t
pci_device_openbsd_read8(struct pci_io_handle *handle, uint32_t reg)
{
#if defined(__i386__) || defined(__amd64__)
return inb(handle->base + reg);
#else
return *(uint8_t *)((uintptr_t)handle->memory + reg);
#endif
}
static void
pci_device_openbsd_write32(struct pci_io_handle *handle, uint32_t reg,
uint32_t data)
{
#if defined(__i386__) || defined(__amd64__)
outl(handle->base + reg, data);
#else
*(uint16_t *)((uintptr_t)handle->memory + reg) = data;
#endif
}
static void
pci_device_openbsd_write16(struct pci_io_handle *handle, uint32_t reg,
uint16_t data)
{
#if defined(__i386__) || defined(__amd64__)
outw(handle->base + reg, data);
#else
*(uint8_t *)((uintptr_t)handle->memory + reg) = data;
#endif
}
static void
pci_device_openbsd_write8(struct pci_io_handle *handle, uint32_t reg,
uint8_t data)
{
#if defined(__i386__) || defined(__amd64__)
outb(handle->base + reg, data);
#else
*(uint32_t *)((uintptr_t)handle->memory + reg) = data;
#endif
}
static int
pci_device_openbsd_map_legacy(struct pci_device *dev, pciaddr_t base,
pciaddr_t size, unsigned map_flags, void **addr)
{
struct pci_device_mapping map;
int err;
map.base = base;
map.size = size;
map.flags = map_flags;
map.memory = NULL;
err = pci_device_openbsd_map_range(dev, &map);
*addr = map.memory;
return err;
}
static int
pci_device_openbsd_unmap_legacy(struct pci_device *dev, void *addr,
pciaddr_t size)
{
struct pci_device_mapping map;
map.memory = addr;
map.size = size;
map.flags = 0;
return pci_device_openbsd_unmap_range(dev, &map);
}
static const struct pci_system_methods openbsd_pci_methods = {
pci_system_openbsd_destroy,
NULL,
pci_device_openbsd_read_rom,
pci_device_openbsd_probe,
pci_device_openbsd_map_range,
pci_device_openbsd_unmap_range,
pci_device_openbsd_read,
pci_device_openbsd_write,
pci_fill_capabilities_generic,
NULL,
NULL,
NULL,
NULL,
pci_device_openbsd_open_legacy_io,
NULL,
pci_device_openbsd_read32,
pci_device_openbsd_read16,
pci_device_openbsd_read8,
pci_device_openbsd_write32,
pci_device_openbsd_write16,
pci_device_openbsd_write8,
pci_device_openbsd_map_legacy,
pci_device_openbsd_unmap_legacy
};
int
pci_system_openbsd_create(void)
{
struct pci_device_private *device;
int domain, bus, dev, func, ndevs, nfuncs;
char path[MAXPATHLEN];
uint32_t reg;
if (ndomains > 0)
return 0;
for (domain = 0; domain < sizeof(pcifd) / sizeof(pcifd[0]); domain++) {
snprintf(path, sizeof(path), "/dev/pci%d", domain);
pcifd[domain] = open(path, O_RDWR | O_CLOEXEC);
if (pcifd[domain] == -1)
break;
ndomains++;
}
if (ndomains == 0)
return ENXIO;
pci_sys = calloc(1, sizeof(struct pci_system));
if (pci_sys == NULL) {
for (domain = 0; domain < ndomains; domain++)
close(pcifd[domain]);
ndomains = 0;
return ENOMEM;
}
pci_sys->methods = &openbsd_pci_methods;
ndevs = 0;
for (domain = 0; domain < ndomains; domain++) {
for (bus = 0; bus < 256; bus++) {
for (dev = 0; dev < 32; dev++) {
nfuncs = pci_nfuncs(domain, bus, dev);
for (func = 0; func < nfuncs; func++) {
if (pci_read(domain, bus, dev, func,
PCI_ID_REG, ®) != 0)
continue;
if (PCI_VENDOR(reg) == PCI_VENDOR_INVALID ||
PCI_VENDOR(reg) == 0)
continue;
ndevs++;
}
}
}
}
pci_sys->num_devices = ndevs;
pci_sys->devices = calloc(ndevs, sizeof(struct pci_device_private));
if (pci_sys->devices == NULL) {
free(pci_sys);
pci_sys = NULL;
for (domain = 0; domain < ndomains; domain++)
close(pcifd[domain]);
ndomains = 0;
return ENOMEM;
}
device = pci_sys->devices;
for (domain = 0; domain < ndomains; domain++) {
for (bus = 0; bus < 256; bus++) {
for (dev = 0; dev < 32; dev++) {
nfuncs = pci_nfuncs(domain, bus, dev);
for (func = 0; func < nfuncs; func++) {
if (pci_read(domain, bus, dev, func,
PCI_ID_REG, ®) != 0)
continue;
if (PCI_VENDOR(reg) == PCI_VENDOR_INVALID ||
PCI_VENDOR(reg) == 0)
continue;
device->base.domain = domain;
device->base.bus = bus;
device->base.dev = dev;
device->base.func = func;
device->base.vendor_id = PCI_VENDOR(reg);
device->base.device_id = PCI_PRODUCT(reg);
if (pci_read(domain, bus, dev, func,
PCI_CLASS_REG, ®) != 0)
continue;
device->base.device_class =
PCI_INTERFACE(reg) |
PCI_CLASS(reg) << 16 |
PCI_SUBCLASS(reg) << 8;
device->base.revision = PCI_REVISION(reg);
if (pci_read(domain, bus, dev, func,
PCI_SUBVEND_0, ®) != 0)
continue;
device->base.subvendor_id = PCI_VENDOR(reg);
device->base.subdevice_id = PCI_PRODUCT(reg);
device->base.vgaarb_rsrc =
VGA_ARB_RSRC_LEGACY_IO |
VGA_ARB_RSRC_LEGACY_MEM;
device++;
}
}
}
}
return 0;
}
void
pci_system_openbsd_init_dev_mem(int fd)
{
aperturefd = fd;
}
int
pci_device_vgaarb_init(void)
{
struct pci_device *dev = pci_sys->vga_target;
struct pci_device_iterator *iter;
struct pci_id_match vga_match = {
PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY,
(PCI_CLASS_DISPLAY << 16) | (PCI_SUBCLASS_DISPLAY_VGA << 8),
0x00ffff00
};
struct pci_vga pv;
int err;
pv.pv_sel.pc_bus = 0;
pv.pv_sel.pc_dev = 0;
pv.pv_sel.pc_func = 0;
err = ioctl(pcifd[0], PCIOCGETVGA, &pv);
if (err)
return err;
pci_sys->vga_target = pci_device_find_by_slot(0, pv.pv_sel.pc_bus,
pv.pv_sel.pc_dev, pv.pv_sel.pc_func);
/* Count the number of VGA devices in domain 0. */
iter = pci_id_match_iterator_create(&vga_match);
if (iter == NULL)
return -1;
pci_sys->vga_count = 0;
while ((dev = pci_device_next(iter)) != NULL) {
if (dev->domain == 0)
pci_sys->vga_count++;
}
pci_iterator_destroy(iter);
return 0;
}
void
pci_device_vgaarb_fini(void)
{
struct pci_device *dev;
struct pci_vga pv;
if (pci_sys == NULL)
return;
dev = pci_sys->vga_target;
if (dev == NULL)
return;
pv.pv_sel.pc_bus = dev->bus;
pv.pv_sel.pc_dev = dev->dev;
pv.pv_sel.pc_func = dev->func;
pv.pv_lock = PCI_VGA_UNLOCK;
ioctl(pcifd[dev->domain], PCIOCSETVGA, &pv);
}
int
pci_device_vgaarb_set_target(struct pci_device *dev)
{
pci_sys->vga_target = dev;
return (0);
}
int
pci_device_vgaarb_lock(void)
{
struct pci_device *dev = pci_sys->vga_target;
struct pci_vga pv;
if (dev == NULL)
return -1;
#if 0
if (dev->vgaarb_rsrc == 0 || pci_sys->vga_count == 1)
return 0;
#else
if (pci_sys->vga_count == 1)
return 0;
#endif
pv.pv_sel.pc_bus = dev->bus;
pv.pv_sel.pc_dev = dev->dev;
pv.pv_sel.pc_func = dev->func;
pv.pv_lock = PCI_VGA_LOCK;
return ioctl(pcifd[dev->domain], PCIOCSETVGA, &pv);
}
int
pci_device_vgaarb_unlock(void)
{
struct pci_device *dev = pci_sys->vga_target;
struct pci_vga pv;
if (dev == NULL)
return -1;
#if 0
if (dev->vgaarb_rsrc == 0 || pci_sys->vga_count == 1)
return 0;
#else
if (pci_sys->vga_count == 1)
return 0;
#endif
pv.pv_sel.pc_bus = dev->bus;
pv.pv_sel.pc_dev = dev->dev;
pv.pv_sel.pc_func = dev->func;
pv.pv_lock = PCI_VGA_UNLOCK;
return ioctl(pcifd[dev->domain], PCIOCSETVGA, &pv);
}
int
pci_device_vgaarb_get_info(struct pci_device *dev, int *vga_count,
int *rsrc_decodes)
{
*vga_count = pci_sys->vga_count;
if (dev)
*rsrc_decodes = dev->vgaarb_rsrc;
return 0;
}
int
pci_device_vgaarb_decodes(int rsrc_decodes)
{
struct pci_device *dev = pci_sys->vga_target;
if (dev == NULL)
return -1;
dev->vgaarb_rsrc = rsrc_decodes;
return 0;
}
if (PCI_MAPREG_MEM_PREFETCHABLE(reg))
libpciaccess-0.13.2/src/common_io.c 0000644 0143106 0000012 00000013017 12172612452 0017417 0 ustar 00alanc staff 0000266 0200005 /*
* Copyright 2009 Red Hat, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software")
* to deal in the software without restriction, including without limitation
* on the rights to use, copy, modify, merge, publish, distribute, sub
* license, and/or sell copies of the Software, and to permit persons to whom
* them Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTIBILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Author:
* Adam Jackson
*/
#include
#include
#include "pciaccess.h"
#include "pciaccess_private.h"
static struct pci_io_handle *
new_io_handle(void)
{
struct pci_io_handle *new;
new = malloc(sizeof(struct pci_io_handle));
if (!new)
return NULL;
return new;
}
static void
delete_io_handle(struct pci_io_handle *handle)
{
free(handle);
return;
}
_pci_hidden void
pci_io_cleanup(void)
{
}
/**
* Open a handle to a PCI device I/O range. The \c base and \c size
* requested must fit entirely within a single I/O BAR on the device.
* \c size is in bytes.
*
* \returns
* An opaque handle to the I/O BAR, or \c NULL on error.
*/
struct pci_io_handle *
pci_device_open_io(struct pci_device *dev, pciaddr_t base, pciaddr_t size)
{
struct pci_io_handle *ret;
int bar;
if (!pci_sys->methods->open_device_io)
return NULL;
for (bar = 0; bar < 6; bar++) {
struct pci_mem_region *region = &(dev->regions[bar]);
if (!region->is_IO)
continue;
if (base < region->base_addr || base > (region->base_addr+region->size))
continue;
if ((base + size) > (region->base_addr + region->size))
continue;
ret = new_io_handle();
if (!ret)
return NULL;
if (!pci_sys->methods->open_device_io(ret, dev, bar, base, size)) {
delete_io_handle(ret);
return NULL;
}
return ret;
}
return NULL;
}
/**
* Open a handle to the legacy I/O space for the PCI domain containing
* \c dev. \c size is in bytes.
*
* \returns
* An opaque handle to the requested range, or \c NULL on error.
*/
struct pci_io_handle *
pci_legacy_open_io(struct pci_device *dev, pciaddr_t base, pciaddr_t size)
{
struct pci_io_handle *ret;
if (!pci_sys->methods->open_legacy_io)
return NULL;
ret = new_io_handle();
if (!ret)
return NULL;
if (!pci_sys->methods->open_legacy_io(ret, dev, base, size)) {
delete_io_handle(ret);
return NULL;
}
return ret;
}
/**
* Close an I/O handle.
*/
void
pci_device_close_io(struct pci_device *dev, struct pci_io_handle *handle)
{
if (dev && handle && pci_sys->methods->close_io)
pci_sys->methods->close_io(dev, handle);
delete_io_handle(handle);
}
/**
* Read a 32-bit value from the I/O space. \c reg is relative to the
* \c base specified when the handle was opened. Some platforms may
* require that \c reg be 32-bit-aligned.
*
* \returns
* The value read from the I/O port, or undefined on any error.
*/
uint32_t
pci_io_read32(struct pci_io_handle *handle, uint32_t reg)
{
if (reg + 4 > handle->size)
return UINT32_MAX;
return pci_sys->methods->read32(handle, reg);
}
/**
* Read a 16-bit value from the I/O space. \c reg is relative to the
* \c base specified when the handle was opened. Some platforms may
* require that \c reg be 16-bit-aligned.
*
* \returns
* The value read from the I/O port, or undefined on any error.
*/
uint16_t
pci_io_read16(struct pci_io_handle *handle, uint32_t reg)
{
if (reg + 2 > handle->size)
return UINT16_MAX;
return pci_sys->methods->read16(handle, reg);
}
/**
* Read a 8-bit value from the I/O space. \c reg is relative to the
* \c base specified when the handle was opened.
*
* \returns
* The value read from the I/O port, or undefined on any error.
*/
uint8_t
pci_io_read8(struct pci_io_handle *handle, uint32_t reg)
{
if (reg + 1 > handle->size)
return UINT8_MAX;
return pci_sys->methods->read8(handle, reg);
}
/**
* Write a 32-bit value to the I/O space. \c reg is relative to the
* \c base specified when the handle was opened. Some platforms may
* require that \c reg be 32-bit-aligned.
*/
void
pci_io_write32(struct pci_io_handle *handle, uint32_t reg, uint32_t data)
{
if (reg + 4 > handle->size)
return;
pci_sys->methods->write32(handle, reg, data);
}
/**
* Write a 16-bit value to the I/O space. \c reg is relative to the
* \c base specified when the handle was opened. Some platforms may
* require that \c reg be 16-bit-aligned.
*/
void
pci_io_write16(struct pci_io_handle *handle, uint32_t reg, uint16_t data)
{
if (reg + 2 > handle->size)
return;
pci_sys->methods->write16(handle, reg, data);
}
/**
* Write a 8-bit value to the I/O space. \c reg is relative to the
* \c base specified when the handle was opened.
*/
void
pci_io_write8(struct pci_io_handle *handle, uint32_t reg, uint8_t data)
{
if (reg + 1 > handle->size)
return;
pci_sys->methods->write8(handle, reg, data);
}
he legacy I/O space for the PCI domain containing
* \c dev. \c size is in bytes.
*
* \returns
* An opaque handle to the requested range, or \c NULL on error.
*/
struct pci_io_handle *
pci_legacy_open_io(struct pci_device *dev, pciaddr_t base, pciaddr_t size)
{
struct pci_io_handle *ret;
if (!pci_sys->methods->open_legacy_io)
return NULL;
ret = new_io_handle();
if (!ret)
return NULL;
if (!pci_sys->methods->open_legacy_io(ret, dev, base, size)) {
delete_io_handle(libpciaccess-0.13.2/src/netbsd_pci.c 0000644 0143106 0000012 00000056746 12172612452 0017572 0 ustar 00alanc staff 0000266 0200005 /*
* Copyright (c) 2008 Juan Romero Pardines
* Copyright (c) 2008 Mark Kettenis
* Copyright (c) 2009 Michael Lorenz
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include
#include
#include
#include
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef HAVE_MTRR
#include
#include
#ifdef _X86_SYSARCH_L
/* NetBSD 5.x and newer */
#define netbsd_set_mtrr(mr, num) _X86_SYSARCH_L(set_mtrr)(mr, num)
#else
/* NetBSD 4.x and older */
#ifdef __i386__
#define netbsd_set_mtrr(mr, num) i386_set_mtrr((mr), (num))
#endif
#ifdef __amd64__
#define netbsd_set_mtrr(mr, num) x86_64_set_mtrr((mr), (num))
#endif
#endif
#endif
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "pciaccess.h"
#include "pciaccess_private.h"
typedef struct _pcibus {
int fd; /* /dev/pci* */
int num; /* bus number */
int maxdevs; /* maximum number of devices */
} PciBus;
static PciBus buses[32]; /* indexed by pci_device.domain */
static int nbuses = 0; /* number of buses found */
/*
* NetBSD's userland has a /dev/pci* entry for each bus but userland has no way
* to tell if a bus is a subordinate of another one or if it's on a different
* host bridge. On some architectures ( macppc for example ) all root buses have
* bus number 0 but on sparc64 for example the two roots in an Ultra60 have
* different bus numbers - one is 0 and the other 128.
* With each /dev/pci* we can map everything on the same root and we can also
* see all devices on the same root, trying to do that causes problems though:
* - since we can't tell which /dev/pci* is a subordinate we would find some
* devices more than once
* - we would have to guess subordinate bus numbers which is a waste of time
* since we can ask each /dev/pci* for its bus number so we can scan only the
* buses we know exist, not all 256 which may exist in each domain.
* - some bus_space_mmap() methods may limit mappings to address ranges which
* belong to known devices on that bus only.
* Each host bridge may or may not have its own IO range, to avoid guesswork
* here each /dev/pci* will let userland map its appropriate IO range at
* PCI_MAGIC_IO_RANGE if defined in
* With all this we should be able to use any PCI graphics device on any PCI
* bus on any architecture as long as Xorg has a driver, without allowing
* arbitrary mappings via /dev/mem and without userland having to know or care
* about translating bus addresses to physical addresses or the other way
* around.
*/
static int
pci_read(int domain, int bus, int dev, int func, uint32_t reg, uint32_t *val)
{
uint32_t rval;
if ((domain < 0) || (domain > nbuses))
return -1;
if (pcibus_conf_read(buses[domain].fd, (unsigned int)bus,
(unsigned int)dev, (unsigned int)func, reg, &rval) == -1)
return (-1);
*val = rval;
return 0;
}
static int
pci_write(int domain, int bus, int dev, int func, uint32_t reg, uint32_t val)
{
if ((domain < 0) || (domain > nbuses))
return -1;
return pcibus_conf_write(buses[domain].fd, (unsigned int)bus,
(unsigned int)dev, (unsigned int)func, reg, val);
}
static int
pci_nfuncs(int domain, int bus, int dev)
{
uint32_t hdr;
if ((domain < 0) || (domain > nbuses))
return -1;
if (pci_read(domain, bus, dev, 0, PCI_BHLC_REG, &hdr) != 0)
return -1;
return (PCI_HDRTYPE_MULTIFN(hdr) ? 8 : 1);
}
/*ARGSUSED*/
static int
pci_device_netbsd_map_range(struct pci_device *dev,
struct pci_device_mapping *map)
{
#ifdef HAVE_MTRR
struct mtrr m;
int n = 1;
#endif
int prot, ret = 0;
prot = PROT_READ;
if (map->flags & PCI_DEV_MAP_FLAG_WRITABLE)
prot |= PROT_WRITE;
map->memory = mmap(NULL, (size_t)map->size, prot, MAP_SHARED,
buses[dev->domain].fd, (off_t)map->base);
if (map->memory == MAP_FAILED)
return errno;
#ifdef HAVE_MTRR
memset(&m, 0, sizeof(m));
/* No need to set an MTRR if it's the default mode. */
if ((map->flags & PCI_DEV_MAP_FLAG_CACHABLE) ||
(map->flags & PCI_DEV_MAP_FLAG_WRITE_COMBINE)) {
m.base = map->base;
m.flags = MTRR_VALID | MTRR_PRIVATE;
m.len = map->size;
m.owner = getpid();
if (map->flags & PCI_DEV_MAP_FLAG_CACHABLE)
m.type = MTRR_TYPE_WB;
if (map->flags & PCI_DEV_MAP_FLAG_WRITE_COMBINE)
m.type = MTRR_TYPE_WC;
if ((netbsd_set_mtrr(&m, &n)) == -1) {
fprintf(stderr, "mtrr set failed: %s\n",
strerror(errno));
}
}
#endif
return ret;
}
static int
pci_device_netbsd_unmap_range(struct pci_device *dev,
struct pci_device_mapping *map)
{
#ifdef HAVE_MTRR
struct mtrr m;
int n = 1;
memset(&m, 0, sizeof(m));
if ((map->flags & PCI_DEV_MAP_FLAG_CACHABLE) ||
(map->flags & PCI_DEV_MAP_FLAG_WRITE_COMBINE)) {
m.base = map->base;
m.flags = 0;
m.len = map->size;
m.type = MTRR_TYPE_UC;
(void)netbsd_set_mtrr(&m, &n);
}
#endif
return pci_device_generic_unmap_range(dev, map);
}
static int
pci_device_netbsd_read(struct pci_device *dev, void *data,
pciaddr_t offset, pciaddr_t size, pciaddr_t *bytes_read)
{
u_int reg, rval;
*bytes_read = 0;
while (size > 0) {
size_t toread = MIN(size, 4 - (offset & 0x3));
reg = (u_int)(offset & ~0x3);
if ((pcibus_conf_read(buses[dev->domain].fd,
(unsigned int)dev->bus, (unsigned int)dev->dev,
(unsigned int)dev->func, reg, &rval)) == -1)
return errno;
rval = htole32(rval);
rval >>= ((offset & 0x3) * 8);
memcpy(data, &rval, toread);
offset += toread;
data = (char *)data + toread;
size -= toread;
*bytes_read += toread;
}
return 0;
}
static int
pci_device_netbsd_write(struct pci_device *dev, const void *data,
pciaddr_t offset, pciaddr_t size, pciaddr_t *bytes_written)
{
u_int reg, val;
if ((offset % 4) != 0 || (size % 4) != 0)
return EINVAL;
*bytes_written = 0;
while (size > 0) {
reg = (u_int)offset;
memcpy(&val, data, 4);
if ((pcibus_conf_write(buses[dev->domain].fd,
(unsigned int)dev->bus, (unsigned int)dev->dev,
(unsigned int)dev->func, reg, val)) == -1)
return errno;
offset += 4;
data = (const char *)data + 4;
size -= 4;
*bytes_written += 4;
}
return 0;
}
#if defined(WSDISPLAYIO_GET_BUSID)
static int
pci_device_netbsd_boot_vga(struct pci_device *dev)
{
int ret;
struct wsdisplayio_bus_id busid;
int fd;
fd = open("/dev/ttyE0", O_RDONLY);
if (fd == -1) {
fprintf(stderr, "failed to open /dev/ttyE0: %s\n",
strerror(errno));
return 0;
}
ret = ioctl(fd, WSDISPLAYIO_GET_BUSID, &busid);
close(fd);
if (ret == -1) {
fprintf(stderr, "ioctl WSDISPLAYIO_GET_BUSID failed: %s\n",
strerror(errno));
return 0;
}
if (busid.bus_type != WSDISPLAYIO_BUS_PCI)
return 0;
if (busid.ubus.pci.domain != dev->domain)
return 0;
if (busid.ubus.pci.bus != dev->bus)
return 0;
if (busid.ubus.pci.device != dev->dev)
return 0;
if (busid.ubus.pci.function != dev->func)
return 0;
return 1;
}
#endif
static void
pci_system_netbsd_destroy(void)
{
int i;
for (i = 0; i < nbuses; i++) {
close(buses[i].fd);
}
free(pci_sys);
pci_sys = NULL;
}
static int
pci_device_netbsd_probe(struct pci_device *device)
{
struct pci_device_private *priv =
(struct pci_device_private *)(void *)device;
struct pci_mem_region *region;
uint64_t reg64, size64;
uint32_t bar, reg, size;
int bus, dev, func, err, domain;
domain = device->domain;
bus = device->bus;
dev = device->dev;
func = device->func;
/* Enable the device if necessary */
err = pci_read(domain, bus, dev, func, PCI_COMMAND_STATUS_REG, ®);
if (err)
return err;
if ((reg & (PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE | PCI_COMMAND_MASTER_ENABLE)) !=
(PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE | PCI_COMMAND_MASTER_ENABLE)) {
reg |= PCI_COMMAND_IO_ENABLE |
PCI_COMMAND_MEM_ENABLE |
PCI_COMMAND_MASTER_ENABLE;
err = pci_write(domain, bus, dev, func, PCI_COMMAND_STATUS_REG,
reg);
if (err)
return err;
}
err = pci_read(domain, bus, dev, func, PCI_BHLC_REG, ®);
if (err)
return err;
priv->header_type = PCI_HDRTYPE_TYPE(reg);
if (priv->header_type != 0)
return 0;
region = device->regions;
for (bar = PCI_MAPREG_START; bar < PCI_MAPREG_END;
bar += sizeof(uint32_t), region++) {
err = pci_read(domain, bus, dev, func, bar, ®);
if (err)
return err;
/* Probe the size of the region. */
err = pci_write(domain, bus, dev, func, bar, (unsigned int)~0);
if (err)
return err;
pci_read(domain, bus, dev, func, bar, &size);
pci_write(domain, bus, dev, func, bar, reg);
if (PCI_MAPREG_TYPE(reg) == PCI_MAPREG_TYPE_IO) {
region->is_IO = 1;
region->base_addr = PCI_MAPREG_IO_ADDR(reg);
region->size = PCI_MAPREG_IO_SIZE(size);
} else {
if (PCI_MAPREG_MEM_PREFETCHABLE(reg))
region->is_prefetchable = 1;
switch(PCI_MAPREG_MEM_TYPE(reg)) {
case PCI_MAPREG_MEM_TYPE_32BIT:
case PCI_MAPREG_MEM_TYPE_32BIT_1M:
region->base_addr = PCI_MAPREG_MEM_ADDR(reg);
region->size = PCI_MAPREG_MEM_SIZE(size);
break;
case PCI_MAPREG_MEM_TYPE_64BIT:
region->is_64 = 1;
reg64 = reg;
size64 = size;
bar += sizeof(uint32_t);
err = pci_read(domain, bus, dev, func, bar, ®);
if (err)
return err;
reg64 |= (uint64_t)reg << 32;
err = pci_write(domain, bus, dev, func, bar,
(unsigned int)~0);
if (err)
return err;
pci_read(domain, bus, dev, func, bar, &size);
pci_write(domain, bus, dev, func, bar,
(unsigned int)(reg64 >> 32));
size64 |= (uint64_t)size << 32;
region->base_addr =
(unsigned long)PCI_MAPREG_MEM64_ADDR(reg64);
region->size =
(unsigned long)PCI_MAPREG_MEM64_SIZE(size64);
region++;
break;
}
}
}
/* Probe expansion ROM if present */
err = pci_read(domain, bus, dev, func, PCI_MAPREG_ROM, ®);
if (err)
return err;
if (reg != 0) {
err = pci_write(domain, bus, dev, func, PCI_MAPREG_ROM,
(uint32_t)(~PCI_MAPREG_ROM_ENABLE));
if (err)
return err;
pci_read(domain, bus, dev, func, PCI_MAPREG_ROM, &size);
pci_write(domain, bus, dev, func, PCI_MAPREG_ROM, reg);
if ((reg & PCI_MAPREG_MEM_ADDR_MASK) != 0) {
priv->rom_base = reg & PCI_MAPREG_MEM_ADDR_MASK;
device->rom_size = -(size & PCI_MAPREG_MEM_ADDR_MASK);
}
}
return 0;
}
/**
* Read a VGA rom using the 0xc0000 mapping.
*
* This function should be extended to handle access through PCI resources,
* which should be more reliable when available.
*/
static int
pci_device_netbsd_read_rom(struct pci_device *dev, void *buffer)
{
struct pci_device_private *priv = (struct pci_device_private *)(void *)dev;
void *bios;
pciaddr_t rom_base;
size_t rom_size;
uint32_t bios_val, command_val;
int pci_rom;
if (((priv->base.device_class >> 16) & 0xff) != PCI_CLASS_DISPLAY ||
((priv->base.device_class >> 8) & 0xff) != PCI_SUBCLASS_DISPLAY_VGA)
return ENOSYS;
if (priv->rom_base == 0) {
#if defined(__amd64__) || defined(__i386__)
/*
* We need a way to detect when this isn't the console and reject
* this request outright.
*/
rom_base = 0xc0000;
rom_size = 0x10000;
pci_rom = 0;
#else
return ENOSYS;
#endif
} else {
rom_base = priv->rom_base;
rom_size = dev->rom_size;
pci_rom = 1;
if ((pcibus_conf_read(buses[dev->domain].fd, (unsigned int)dev->bus,
(unsigned int)dev->dev, (unsigned int)dev->func,
PCI_COMMAND_STATUS_REG, &command_val)) == -1)
return errno;
if ((command_val & PCI_COMMAND_MEM_ENABLE) == 0) {
if ((pcibus_conf_write(buses[dev->domain].fd,
(unsigned int)dev->bus, (unsigned int)dev->dev,
(unsigned int)dev->func, PCI_COMMAND_STATUS_REG,
command_val | PCI_COMMAND_MEM_ENABLE)) == -1)
return errno;
}
if ((pcibus_conf_read(buses[dev->domain].fd, (unsigned int)dev->bus,
(unsigned int)dev->dev, (unsigned int)dev->func,
PCI_MAPREG_ROM, &bios_val)) == -1)
return errno;
if ((bios_val & PCI_MAPREG_ROM_ENABLE) == 0) {
if ((pcibus_conf_write(buses[dev->domain].fd,
(unsigned int)dev->bus,
(unsigned int)dev->dev, (unsigned int)dev->func,
PCI_MAPREG_ROM, bios_val | PCI_MAPREG_ROM_ENABLE)) == -1)
return errno;
}
}
fprintf(stderr, "Using rom_base = 0x%lx 0x%lx (pci_rom=%d)\n",
(long)rom_base, (long)rom_size, pci_rom);
bios = mmap(NULL, rom_size, PROT_READ, MAP_SHARED, buses[dev->domain].fd,
(off_t)rom_base);
if (bios == MAP_FAILED) {
int serrno = errno;
return serrno;
}
memcpy(buffer, bios, rom_size);
munmap(bios, rom_size);
if (pci_rom) {
if ((command_val & PCI_COMMAND_MEM_ENABLE) == 0) {
if ((pcibus_conf_write(buses[dev->domain].fd,
(unsigned int)dev->bus,
(unsigned int)dev->dev, (unsigned int)dev->func,
PCI_COMMAND_STATUS_REG, command_val)) == -1)
return errno;
}
if ((bios_val & PCI_MAPREG_ROM_ENABLE) == 0) {
if ((pcibus_conf_write(buses[dev->domain].fd,
(unsigned int)dev->bus,
(unsigned int)dev->dev, (unsigned int)dev->func,
PCI_MAPREG_ROM, bios_val)) == -1)
return errno;
}
}
return 0;
}
#if defined(__i386__) || defined(__amd64__)
#include
/*
* Functions to provide access to x86 programmed I/O instructions.
*
* The in[bwl]() and out[bwl]() functions are split into two varieties: one to
* use a small, constant, 8-bit port number, and another to use a large or
* variable port number. The former can be compiled as a smaller instruction.
*/
#ifdef __OPTIMIZE__
#define __use_immediate_port(port) \
(__builtin_constant_p((port)) && (port) < 0x100)
#else
#define __use_immediate_port(port) 0
#endif
#define inb(port) \
(/* CONSTCOND */ __use_immediate_port(port) ? __inbc(port) : __inb(port))
static __inline u_int8_t
__inbc(unsigned port)
{
u_int8_t data;
__asm __volatile("inb %w1,%0" : "=a" (data) : "id" (port));
return data;
}
static __inline u_int8_t
__inb(unsigned port)
{
u_int8_t data;
__asm __volatile("inb %w1,%0" : "=a" (data) : "d" (port));
return data;
}
static __inline void
insb(unsigned port, void *addr, int cnt)
{
void *dummy1;
int dummy2;
__asm __volatile("cld\n\trepne\n\tinsb" :
"=D" (dummy1), "=c" (dummy2) :
"d" (port), "0" (addr), "1" (cnt) :
"memory");
}
#define inw(port) \
(/* CONSTCOND */ __use_immediate_port(port) ? __inwc(port) : __inw(port))
static __inline u_int16_t
__inwc(unsigned port)
{
u_int16_t data;
__asm __volatile("inw %w1,%0" : "=a" (data) : "id" (port));
return data;
}
static __inline u_int16_t
__inw(unsigned port)
{
u_int16_t data;
__asm __volatile("inw %w1,%0" : "=a" (data) : "d" (port));
return data;
}
static __inline void
insw(unsigned port, void *addr, int cnt)
{
void *dummy1;
int dummy2;
__asm __volatile("cld\n\trepne\n\tinsw" :
"=D" (dummy1), "=c" (dummy2) :
"d" (port), "0" (addr), "1" (cnt) :
"memory");
}
#define inl(port) \
(/* CONSTCOND */ __use_immediate_port(port) ? __inlc(port) : __inl(port))
static __inline u_int32_t
__inlc(unsigned port)
{
u_int32_t data;
__asm __volatile("inl %w1,%0" : "=a" (data) : "id" (port));
return data;
}
static __inline u_int32_t
__inl(unsigned port)
{
u_int32_t data;
__asm __volatile("inl %w1,%0" : "=a" (data) : "d" (port));
return data;
}
static __inline void
insl(unsigned port, void *addr, int cnt)
{
void *dummy1;
int dummy2;
__asm __volatile("cld\n\trepne\n\tinsl" :
"=D" (dummy1), "=c" (dummy2) :
"d" (port), "0" (addr), "1" (cnt) :
"memory");
}
#define outb(port, data) \
(/* CONSTCOND */__use_immediate_port(port) ? __outbc(port, data) : \
__outb(port, data))
static __inline void
__outbc(unsigned port, u_int8_t data)
{
__asm __volatile("outb %0,%w1" : : "a" (data), "id" (port));
}
static __inline void
__outb(unsigned port, u_int8_t data)
{
__asm __volatile("outb %0,%w1" : : "a" (data), "d" (port));
}
static __inline void
outsb(unsigned port, const void *addr, int cnt)
{
void *dummy1;
int dummy2;
__asm __volatile("cld\n\trepne\n\toutsb" :
"=S" (dummy1), "=c" (dummy2) :
"d" (port), "0" (addr), "1" (cnt));
}
#define outw(port, data) \
(/* CONSTCOND */ __use_immediate_port(port) ? __outwc(port, data) : \
__outw(port, data))
static __inline void
__outwc(unsigned port, u_int16_t data)
{
__asm __volatile("outw %0,%w1" : : "a" (data), "id" (port));
}
static __inline void
__outw(unsigned port, u_int16_t data)
{
__asm __volatile("outw %0,%w1" : : "a" (data), "d" (port));
}
static __inline void
outsw(unsigned port, const void *addr, int cnt)
{
void *dummy1;
int dummy2;
__asm __volatile("cld\n\trepne\n\toutsw" :
"=S" (dummy1), "=c" (dummy2) :
"d" (port), "0" (addr), "1" (cnt));
}
#define outl(port, data) \
(/* CONSTCOND */ __use_immediate_port(port) ? __outlc(port, data) : \
__outl(port, data))
static __inline void
__outlc(unsigned port, u_int32_t data)
{
__asm __volatile("outl %0,%w1" : : "a" (data), "id" (port));
}
static __inline void
__outl(unsigned port, u_int32_t data)
{
__asm __volatile("outl %0,%w1" : : "a" (data), "d" (port));
}
static __inline void
outsl(unsigned port, const void *addr, int cnt)
{
void *dummy1;
int dummy2;
__asm __volatile("cld\n\trepne\n\toutsl" :
"=S" (dummy1), "=c" (dummy2) :
"d" (port), "0" (addr), "1" (cnt));
}
#endif
static struct pci_io_handle *
pci_device_netbsd_open_legacy_io(struct pci_io_handle *ret,
struct pci_device *dev, pciaddr_t base, pciaddr_t size)
{
#if defined(__i386__)
struct i386_iopl_args ia;
ia.iopl = 1;
if (sysarch(I386_IOPL, &ia))
return NULL;
ret->base = base;
ret->size = size;
return ret;
#elif defined(__amd64__)
struct x86_64_iopl_args ia;
ia.iopl = 1;
if (sysarch(X86_64_IOPL, &ia))
return NULL;
ret->base = base;
ret->size = size;
return ret;
#else
return NULL;
#endif
}
static uint32_t
pci_device_netbsd_read32(struct pci_io_handle *handle, uint32_t reg)
{
#if defined(__i386__) || defined(__amd64__)
return inl(handle->base + reg);
#else
return *(uint32_t *)((uintptr_t)handle->memory + reg);
#endif
}
static uint16_t
pci_device_netbsd_read16(struct pci_io_handle *handle, uint32_t reg)
{
#if defined(__i386__) || defined(__amd64__)
return inw(handle->base + reg);
#else
return *(uint16_t *)((uintptr_t)handle->memory + reg);
#endif
}
static uint8_t
pci_device_netbsd_read8(struct pci_io_handle *handle, uint32_t reg)
{
#if defined(__i386__) || defined(__amd64__)
return inb(handle->base + reg);
#else
return *(uint8_t *)((uintptr_t)handle->memory + reg);
#endif
}
static void
pci_device_netbsd_write32(struct pci_io_handle *handle, uint32_t reg,
uint32_t data)
{
#if defined(__i386__) || defined(__amd64__)
outl(handle->base + reg, data);
#else
*(uint16_t *)((uintptr_t)handle->memory + reg) = data;
#endif
}
static void
pci_device_netbsd_write16(struct pci_io_handle *handle, uint32_t reg,
uint16_t data)
{
#if defined(__i386__) || defined(__amd64__)
outw(handle->base + reg, data);
#else
*(uint8_t *)((uintptr_t)handle->memory + reg) = data;
#endif
}
static void
pci_device_netbsd_write8(struct pci_io_handle *handle, uint32_t reg,
uint8_t data)
{
#if defined(__i386__) || defined(__amd64__)
outb(handle->base + reg, data);
#else
*(uint32_t *)((uintptr_t)handle->memory + reg) = data;
#endif
}
static int
pci_device_netbsd_map_legacy(struct pci_device *dev, pciaddr_t base,
pciaddr_t size, unsigned map_flags, void **addr)
{
struct pci_device_mapping map;
int err;
map.base = base;
map.size = size;
map.flags = map_flags;
map.memory = NULL;
err = pci_device_netbsd_map_range(dev, &map);
*addr = map.memory;
return err;
}
static int
pci_device_netbsd_unmap_legacy(struct pci_device *dev, void *addr,
pciaddr_t size)
{
struct pci_device_mapping map;
map.memory = addr;
map.size = size;
map.flags = 0;
return pci_device_netbsd_unmap_range(dev, &map);
}
static const struct pci_system_methods netbsd_pci_methods = {
.destroy = pci_system_netbsd_destroy,
.destroy_device = NULL,
.read_rom = pci_device_netbsd_read_rom,
.probe = pci_device_netbsd_probe,
.map_range = pci_device_netbsd_map_range,
.unmap_range = pci_device_netbsd_unmap_range,
.read = pci_device_netbsd_read,
.write = pci_device_netbsd_write,
.fill_capabilities = pci_fill_capabilities_generic,
#if defined(WSDISPLAYIO_GET_BUSID)
.boot_vga = pci_device_netbsd_boot_vga,
#else
.boot_vga = NULL,
#endif
.open_legacy_io = pci_device_netbsd_open_legacy_io,
.read32 = pci_device_netbsd_read32,
.read16 = pci_device_netbsd_read16,
.read8 = pci_device_netbsd_read8,
.write32 = pci_device_netbsd_write32,
.write16 = pci_device_netbsd_write16,
.write8 = pci_device_netbsd_write8,
.map_legacy = pci_device_netbsd_map_legacy,
.unmap_legacy = pci_device_netbsd_unmap_legacy,
};
int
pci_system_netbsd_create(void)
{
struct pci_device_private *device;
int bus, dev, func, ndevs, nfuncs, domain, pcifd;
uint32_t reg;
char netbsd_devname[32];
struct pciio_businfo businfo;
pci_sys = calloc(1, sizeof(struct pci_system));
pci_sys->methods = &netbsd_pci_methods;
ndevs = 0;
nbuses = 0;
snprintf(netbsd_devname, 32, "/dev/pci%d", nbuses);
pcifd = open(netbsd_devname, O_RDWR | O_CLOEXEC);
while (pcifd > 0) {
ioctl(pcifd, PCI_IOC_BUSINFO, &businfo);
buses[nbuses].fd = pcifd;
buses[nbuses].num = bus = businfo.busno;
buses[nbuses].maxdevs = businfo.maxdevs;
domain = nbuses;
nbuses++;
for (dev = 0; dev < businfo.maxdevs; dev++) {
nfuncs = pci_nfuncs(domain, bus, dev);
for (func = 0; func < nfuncs; func++) {
if (pci_read(domain, bus, dev, func, PCI_ID_REG,
®) != 0)
continue;
if (PCI_VENDOR(reg) == PCI_VENDOR_INVALID ||
PCI_VENDOR(reg) == 0)
continue;
ndevs++;
}
}
snprintf(netbsd_devname, 32, "/dev/pci%d", nbuses);
pcifd = open(netbsd_devname, O_RDWR);
}
pci_sys->num_devices = ndevs;
pci_sys->devices = calloc(ndevs, sizeof(struct pci_device_private));
if (pci_sys->devices == NULL) {
int i;
for (i = 0; i < nbuses; i++)
close(buses[i].fd);
free(pci_sys);
return ENOMEM;
}
device = pci_sys->devices;
for (domain = 0; domain < nbuses; domain++) {
bus = buses[domain].num;
for (dev = 0; dev < buses[domain].maxdevs; dev++) {
nfuncs = pci_nfuncs(domain, bus, dev);
for (func = 0; func < nfuncs; func++) {
if (pci_read(domain, bus, dev, func,
PCI_ID_REG, ®) != 0)
continue;
if (PCI_VENDOR(reg) == PCI_VENDOR_INVALID ||
PCI_VENDOR(reg) == 0)
continue;
device->base.domain = domain;
device->base.bus = bus;
device->base.dev = dev;
device->base.func = func;
device->base.vendor_id = PCI_VENDOR(reg);
device->base.device_id = PCI_PRODUCT(reg);
if (pci_read(domain, bus, dev, func,
PCI_CLASS_REG, ®) != 0)
continue;
device->base.device_class =
PCI_INTERFACE(reg) | PCI_CLASS(reg) << 16 |
PCI_SUBCLASS(reg) << 8;
device->base.revision = PCI_REVISION(reg);
if (pci_read(domain, bus, dev, func,
PCI_SUBSYS_ID_REG, ®) != 0)
continue;
device->base.subvendor_id = PCI_VENDOR(reg);
device->base.subdevice_id = PCI_PRODUCT(reg);
device++;
}
}
}
return 0;
}
ned int)dev->bus,
(unsiglibpciaccess-0.13.2/src/common_init.c 0000644 0143106 0000012 00000006316 12172612452 0017757 0 ustar 00alanc staff 0000266 0200005 /*
* (C) Copyright IBM Corporation 2006
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* on the rights to use, copy, modify, merge, publish, distribute, sub
* license, and/or sell copies of the Software, and to permit persons to whom
* the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
/**
* \file common_init.c
* Platform independent routines for initializing access to the PCI system.
*
* \author Ian Romanick
*/
#include
#include
#include "pciaccess.h"
#include "pciaccess_private.h"
_pci_hidden struct pci_system * pci_sys;
/**
* Initialize the PCI subsystem for access.
*
* \return
* Zero on success or an errno value on failure. In particular, if no
* platform-specific initializers are available, \c ENOSYS will be returned.
*
* \sa pci_system_cleanup
*/
int
pci_system_init( void )
{
int err = ENOSYS;
#ifdef linux
err = pci_system_linux_sysfs_create();
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
err = pci_system_freebsd_create();
#elif defined(__NetBSD__)
err = pci_system_netbsd_create();
#elif defined(__OpenBSD__)
err = pci_system_openbsd_create();
#elif defined(__sun)
err = pci_system_solx_devfs_create();
#elif defined(__GNU__)
err = pci_system_x86_create();
#endif
return err;
}
void
pci_system_init_dev_mem(int fd)
{
#ifdef __OpenBSD__
pci_system_openbsd_init_dev_mem(fd);
#endif
}
/**
* Shutdown all access to the PCI subsystem.
*
* \sa pci_system_init
*/
void
pci_system_cleanup( void )
{
unsigned i;
unsigned j;
if ( pci_sys == NULL ) {
return;
}
pci_io_cleanup();
if ( pci_sys->devices ) {
for ( i = 0 ; i < pci_sys->num_devices ; i++ ) {
for ( j = 0 ; j < 6 ; j++ ) {
(void) pci_device_unmap_region( & pci_sys->devices[i].base, j );
}
free( (char *) pci_sys->devices[i].device_string );
free( (char *) pci_sys->devices[i].agp );
pci_sys->devices[i].device_string = NULL;
pci_sys->devices[i].agp = NULL;
if ( pci_sys->methods->destroy_device != NULL ) {
(*pci_sys->methods->destroy_device)( & pci_sys->devices[i].base );
}
}
free( pci_sys->devices );
pci_sys->devices = NULL;
pci_sys->num_devices = 0;
}
if ( pci_sys->methods->destroy != NULL ) {
(*pci_sys->methods->destroy)();
}
free( pci_sys );
pci_sys = NULL;
}
VIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN libpciaccess-0.13.2/src/freebsd_pci.c 0000644 0143106 0000012 00000047542 12172612452 0017717 0 ustar 00alanc staff 0000266 0200005 /*
* (C) Copyright Eric Anholt 2006
* (C) Copyright IBM Corporation 2006
* (C) Copyright Mark Kettenis 2011
* (C) Copyright Robert Millan 2012
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* on the rights to use, copy, modify, merge, publish, distribute, sub
* license, and/or sell copies of the Software, and to permit persons to whom
* the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
/**
* \file freebsd_pci.c
*
* Access the kernel PCI support using /dev/pci's ioctl and mmap interface.
*
* \author Eric Anholt
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "config.h"
#include "pciaccess.h"
#include "pciaccess_private.h"
#define PCIC_DISPLAY 0x03
#define PCIS_DISPLAY_VGA 0x00
#define PCIS_DISPLAY_XGA 0x01
#define PCIS_DISPLAY_3D 0x02
#define PCIS_DISPLAY_OTHER 0x80
/* Registers taken from pcireg.h */
#define PCIR_COMMAND 0x04
#define PCIM_CMD_PORTEN 0x0001
#define PCIM_CMD_MEMEN 0x0002
#define PCIR_BIOS 0x30
#define PCIM_BIOS_ENABLE 0x01
#define PCIM_BIOS_ADDR_MASK 0xfffff800
#define PCIR_BARS 0x10
#define PCIR_BAR(x) (PCIR_BARS + (x) * 4)
#define PCI_BAR_IO(x) (((x) & PCIM_BAR_SPACE) == PCIM_BAR_IO_SPACE)
#define PCI_BAR_MEM(x) (((x) & PCIM_BAR_SPACE) == PCIM_BAR_MEM_SPACE)
#define PCIM_BAR_MEM_TYPE 0x00000006
#define PCIM_BAR_MEM_64 4
#define PCIM_BAR_MEM_PREFETCH 0x00000008
#define PCIM_BAR_SPACE 0x00000001
#define PCIM_BAR_MEM_SPACE 0
#define PCIM_BAR_IO_SPACE 1
/**
* FreeBSD private pci_system structure that extends the base pci_system
* structure.
*
* It is initialized once and used as a global, just as pci_system is used.
*/
_pci_hidden
struct freebsd_pci_system {
/* This must be the first entry in the structure, as pci_system_cleanup()
* frees pci_sys.
*/
struct pci_system pci_sys;
int pcidev; /**< fd for /dev/pci */
} *freebsd_pci_sys;
/**
* Map a memory region for a device using /dev/mem.
*
* \param dev Device whose memory region is to be mapped.
* \param map Parameters of the mapping that is to be created.
*
* \return
* Zero on success or an \c errno value on failure.
*/
static int
pci_device_freebsd_map_range(struct pci_device *dev,
struct pci_device_mapping *map)
{
const int prot = ((map->flags & PCI_DEV_MAP_FLAG_WRITABLE) != 0)
? (PROT_READ | PROT_WRITE) : PROT_READ;
struct mem_range_desc mrd;
struct mem_range_op mro;
int fd, err = 0;
fd = open("/dev/mem", O_RDWR | O_CLOEXEC);
if (fd == -1)
return errno;
map->memory = mmap(NULL, map->size, prot, MAP_SHARED, fd, map->base);
if (map->memory == MAP_FAILED) {
err = errno;
}
mrd.mr_base = map->base;
mrd.mr_len = map->size;
strncpy(mrd.mr_owner, "pciaccess", sizeof(mrd.mr_owner));
if (map->flags & PCI_DEV_MAP_FLAG_CACHABLE)
mrd.mr_flags = MDF_WRITEBACK;
else if (map->flags & PCI_DEV_MAP_FLAG_WRITE_COMBINE)
mrd.mr_flags = MDF_WRITECOMBINE;
else
mrd.mr_flags = MDF_UNCACHEABLE;
mro.mo_desc = &mrd;
mro.mo_arg[0] = MEMRANGE_SET_UPDATE;
/* No need to set an MTRR if it's the default mode. */
if (mrd.mr_flags != MDF_UNCACHEABLE) {
if (ioctl(fd, MEMRANGE_SET, &mro)) {
fprintf(stderr, "failed to set mtrr: %s\n", strerror(errno));
}
}
close(fd);
return err;
}
static int
pci_device_freebsd_unmap_range( struct pci_device *dev,
struct pci_device_mapping *map )
{
struct mem_range_desc mrd;
struct mem_range_op mro;
int fd;
if ((map->flags & PCI_DEV_MAP_FLAG_CACHABLE) ||
(map->flags & PCI_DEV_MAP_FLAG_WRITE_COMBINE))
{
fd = open("/dev/mem", O_RDWR | O_CLOEXEC);
if (fd != -1) {
mrd.mr_base = map->base;
mrd.mr_len = map->size;
strncpy(mrd.mr_owner, "pciaccess", sizeof(mrd.mr_owner));
mrd.mr_flags = MDF_UNCACHEABLE;
mro.mo_desc = &mrd;
mro.mo_arg[0] = MEMRANGE_SET_REMOVE;
if (ioctl(fd, MEMRANGE_SET, &mro)) {
fprintf(stderr, "failed to unset mtrr: %s\n", strerror(errno));
}
close(fd);
} else {
fprintf(stderr, "Failed to open /dev/mem\n");
}
}
return pci_device_generic_unmap_range(dev, map);
}
static int
pci_device_freebsd_read( struct pci_device * dev, void * data,
pciaddr_t offset, pciaddr_t size,
pciaddr_t * bytes_read )
{
struct pci_io io;
#if HAVE_PCI_IO_PC_DOMAIN
io.pi_sel.pc_domain = dev->domain;
#endif
io.pi_sel.pc_bus = dev->bus;
io.pi_sel.pc_dev = dev->dev;
io.pi_sel.pc_func = dev->func;
*bytes_read = 0;
while ( size > 0 ) {
int toread = (size < 4) ? size : 4;
/* Only power of two allowed. */
if (toread == 3)
toread = 2;
io.pi_reg = offset;
io.pi_width = toread;
if ( ioctl( freebsd_pci_sys->pcidev, PCIOCREAD, &io ) < 0 )
return errno;
memcpy(data, &io.pi_data, toread );
offset += toread;
data = (char *)data + toread;
size -= toread;
*bytes_read += toread;
}
return 0;
}
static int
pci_device_freebsd_write( struct pci_device * dev, const void * data,
pciaddr_t offset, pciaddr_t size,
pciaddr_t * bytes_written )
{
struct pci_io io;
#if HAVE_PCI_IO_PC_DOMAIN
io.pi_sel.pc_domain = dev->domain;
#endif
io.pi_sel.pc_bus = dev->bus;
io.pi_sel.pc_dev = dev->dev;
io.pi_sel.pc_func = dev->func;
*bytes_written = 0;
while ( size > 0 ) {
int towrite = (size < 4 ? size : 4);
/* Only power of two allowed. */
if (towrite == 3)
towrite = 2;
io.pi_reg = offset;
io.pi_width = towrite;
memcpy( &io.pi_data, data, towrite );
if ( ioctl( freebsd_pci_sys->pcidev, PCIOCWRITE, &io ) < 0 )
return errno;
offset += towrite;
data = (char *)data + towrite;
size -= towrite;
*bytes_written += towrite;
}
return 0;
}
/**
* Read a VGA rom using the 0xc0000 mapping.
*
* This function should be extended to handle access through PCI resources,
* which should be more reliable when available.
*/
static int
pci_device_freebsd_read_rom( struct pci_device * dev, void * buffer )
{
struct pci_device_private *priv = (struct pci_device_private *) dev;
void *bios;
pciaddr_t rom_base;
uint32_t rom;
uint16_t reg;
int pci_rom, memfd;
if ( ( dev->device_class & 0x00ffff00 ) !=
( ( PCIC_DISPLAY << 16 ) | ( PCIS_DISPLAY_VGA << 8 ) ) )
{
return ENOSYS;
}
if (priv->rom_base == 0) {
#if defined(__amd64__) || defined(__i386__)
rom_base = 0xc0000;
pci_rom = 0;
#else
return ENOSYS;
#endif
} else {
rom_base = priv->rom_base;
pci_rom = 1;
pci_device_cfg_read_u16( dev, ®, PCIR_COMMAND );
pci_device_cfg_write_u16( dev, reg | PCIM_CMD_MEMEN, PCIR_COMMAND );
pci_device_cfg_read_u32( dev, &rom, PCIR_BIOS );
pci_device_cfg_write_u32( dev, rom | PCIM_BIOS_ENABLE, PCIR_BIOS );
}
printf("Using rom_base = 0x%lx\n", (long)rom_base);
memfd = open( "/dev/mem", O_RDONLY | O_CLOEXEC );
if ( memfd == -1 )
return errno;
bios = mmap( NULL, dev->rom_size, PROT_READ, 0, memfd, rom_base );
if ( bios == MAP_FAILED ) {
close( memfd );
return errno;
}
memcpy( buffer, bios, dev->rom_size );
munmap( bios, dev->rom_size );
close( memfd );
if (pci_rom) {
pci_device_cfg_write_u32( dev, PCIR_BIOS, rom );
pci_device_cfg_write_u16( dev, PCIR_COMMAND, reg );
}
return 0;
}
/** Returns the number of regions (base address registers) the device has */
static int
pci_device_freebsd_get_num_regions( struct pci_device * dev )
{
struct pci_device_private *priv = (struct pci_device_private *) dev;
switch (priv->header_type) {
case 0:
return 6;
case 1:
return 2;
case 2:
return 1;
default:
printf("unknown header type %02x\n", priv->header_type);
return 0;
}
}
#ifdef PCIOCGETBAR
static int
pci_device_freebsd_probe( struct pci_device * dev )
{
struct pci_device_private *priv = (struct pci_device_private *) dev;
struct pci_bar_io bar;
uint8_t irq;
int err, i;
#if HAVE_PCI_IO_PC_DOMAIN
bar.pbi_sel.pc_domain = dev->domain;
#endif
bar.pbi_sel.pc_bus = dev->bus;
bar.pbi_sel.pc_dev = dev->dev;
bar.pbi_sel.pc_func = dev->func;
/* Many of the fields were filled in during initial device enumeration.
* At this point, we need to fill in regions, rom_size, and irq.
*/
err = pci_device_cfg_read_u8( dev, &irq, 60 );
if (err)
return errno;
dev->irq = irq;
for (i = 0; i < pci_device_freebsd_get_num_regions( dev ); i++) {
bar.pbi_reg = PCIR_BAR(i);
if ( ioctl( freebsd_pci_sys->pcidev, PCIOCGETBAR, &bar ) < 0 )
continue;
if (PCI_BAR_IO(bar.pbi_base))
dev->regions[i].is_IO = 1;
if ((bar.pbi_base & PCIM_BAR_MEM_TYPE) == PCIM_BAR_MEM_64)
dev->regions[i].is_64 = 1;
if (bar.pbi_base & PCIM_BAR_MEM_PREFETCH)
dev->regions[i].is_prefetchable = 1;
dev->regions[i].base_addr = bar.pbi_base & ~((uint64_t)0xf);
dev->regions[i].size = bar.pbi_length;
}
/* If it's a VGA device, set up the rom size for read_rom using the
* 0xc0000 mapping.
*/
if ((dev->device_class & 0x00ffff00) ==
((PCIC_DISPLAY << 16) | (PCIS_DISPLAY_VGA << 8))) {
dev->rom_size = 64 * 1024;
}
return 0;
}
#else
/** Masks out the flag bigs of the base address register value */
static uint32_t
get_map_base( uint32_t val )
{
if (val & 0x01)
return val & ~0x03;
else
return val & ~0x0f;
}
/** Returns the size of a region based on the all-ones test value */
static int
get_test_val_size( uint32_t testval )
{
if (testval == 0)
return 0;
/* Mask out the flag bits */
testval = get_map_base( testval );
return 1 << (ffs(testval) - 1);
}
/**
* Sets the address and size information for the region from config space
* registers.
*
* This would be much better provided by a kernel interface.
*
* \return 0 on success, or an errno value.
*/
static int
pci_device_freebsd_get_region_info( struct pci_device * dev, int region,
int bar )
{
uint32_t addr, testval;
uint16_t cmd;
int err;
/* Get the base address */
err = pci_device_cfg_read_u32( dev, &addr, bar );
if (err != 0)
return err;
/*
* We are going to be doing evil things to the registers here
* so disable them via the command register first.
*/
err = pci_device_cfg_read_u16( dev, &cmd, PCIR_COMMAND );
if (err != 0)
return err;
err = pci_device_cfg_write_u16( dev,
cmd & ~(PCI_BAR_MEM(addr) ? PCIM_CMD_MEMEN : PCIM_CMD_PORTEN),
PCIR_COMMAND );
if (err != 0)
return err;
/* Test write all ones to the register, then restore it. */
err = pci_device_cfg_write_u32( dev, 0xffffffff, bar );
if (err != 0)
return err;
err = pci_device_cfg_read_u32( dev, &testval, bar );
if (err != 0)
return err;
err = pci_device_cfg_write_u32( dev, addr, bar );
if (err != 0)
return err;
/* Restore the command register */
err = pci_device_cfg_write_u16( dev, cmd, PCIR_COMMAND );
if (err != 0)
return err;
if (addr & 0x01)
dev->regions[region].is_IO = 1;
if (addr & 0x04)
dev->regions[region].is_64 = 1;
if (addr & 0x08)
dev->regions[region].is_prefetchable = 1;
/* Set the size */
dev->regions[region].size = get_test_val_size( testval );
printf("size = 0x%lx\n", (long)dev->regions[region].size);
/* Set the base address value */
if (dev->regions[region].is_64) {
uint32_t top;
err = pci_device_cfg_read_u32( dev, &top, bar + 4 );
if (err != 0)
return err;
dev->regions[region].base_addr = ((uint64_t)top << 32) |
get_map_base(addr);
} else {
dev->regions[region].base_addr = get_map_base(addr);
}
return 0;
}
static int
pci_device_freebsd_probe( struct pci_device * dev )
{
struct pci_device_private *priv = (struct pci_device_private *) dev;
uint32_t reg, size;
uint8_t irq;
int err, i, bar;
/* Many of the fields were filled in during initial device enumeration.
* At this point, we need to fill in regions, rom_size, and irq.
*/
err = pci_device_cfg_read_u8( dev, &irq, 60 );
if (err)
return errno;
dev->irq = irq;
bar = 0x10;
for (i = 0; i < pci_device_freebsd_get_num_regions( dev ); i++) {
pci_device_freebsd_get_region_info( dev, i, bar );
if (dev->regions[i].is_64) {
bar += 0x08;
i++;
} else
bar += 0x04;
}
/* If it's a VGA device, set up the rom size for read_rom */
if ((dev->device_class & 0x00ffff00) ==
((PCIC_DISPLAY << 16) | (PCIS_DISPLAY_VGA << 8)))
{
err = pci_device_cfg_read_u32( dev, ®, PCIR_BIOS );
if (err)
return errno;
if (reg == 0) {
dev->rom_size = 0x10000;
return 0;
}
err = pci_device_cfg_write_u32( dev, ~PCIM_BIOS_ENABLE, PCIR_BIOS );
if (err)
return errno;
pci_device_cfg_read_u32( dev, &size, PCIR_BIOS );
pci_device_cfg_write_u32( dev, reg, PCIR_BIOS );
if ((reg & PCIM_BIOS_ADDR_MASK) != 0) {
priv->rom_base = (reg & PCIM_BIOS_ADDR_MASK);
dev->rom_size = -(size & PCIM_BIOS_ADDR_MASK);
}
}
return 0;
}
#endif
static void
pci_system_freebsd_destroy(void)
{
close(freebsd_pci_sys->pcidev);
free(freebsd_pci_sys->pci_sys.devices);
freebsd_pci_sys = NULL;
}
#if defined(__i386__) || defined(__amd64__)
#include
#endif
static struct pci_io_handle *
pci_device_freebsd_open_legacy_io(struct pci_io_handle *ret,
struct pci_device *dev, pciaddr_t base, pciaddr_t size)
{
#if defined(__i386__) || defined(__amd64__)
ret->fd = open("/dev/io", O_RDWR | O_CLOEXEC);
if (ret->fd < 0)
return NULL;
ret->base = base;
ret->size = size;
return ret;
#elif defined(PCI_MAGIC_IO_RANGE)
ret->memory = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED,
aperturefd, PCI_MAGIC_IO_RANGE + base);
if (ret->memory == MAP_FAILED)
return NULL;
ret->base = base;
ret->size = size;
return ret;
#else
return NULL;
#endif
}
#if defined(__i386__) || defined(__amd64__)
static void
pci_device_freebsd_close_io(struct pci_device *dev, struct pci_io_handle *handle)
{
if (handle->fd > -1)
close(handle->fd);
}
#endif
static uint32_t
pci_device_freebsd_read32(struct pci_io_handle *handle, uint32_t reg)
{
#if defined(__i386__) || defined(__amd64__)
return inl(handle->base + reg);
#else
return *(uint32_t *)((uintptr_t)handle->memory + reg);
#endif
}
static uint16_t
pci_device_freebsd_read16(struct pci_io_handle *handle, uint32_t reg)
{
#if defined(__i386__) || defined(__amd64__)
return inw(handle->base + reg);
#else
return *(uint16_t *)((uintptr_t)handle->memory + reg);
#endif
}
static uint8_t
pci_device_freebsd_read8(struct pci_io_handle *handle, uint32_t reg)
{
#if defined(__i386__) || defined(__amd64__)
return inb(handle->base + reg);
#else
return *(uint8_t *)((uintptr_t)handle->memory + reg);
#endif
}
static void
pci_device_freebsd_write32(struct pci_io_handle *handle, uint32_t reg,
uint32_t data)
{
#if defined(__i386__) || defined(__amd64__)
outl(handle->base + reg, data);
#else
*(uint16_t *)((uintptr_t)handle->memory + reg) = data;
#endif
}
static void
pci_device_freebsd_write16(struct pci_io_handle *handle, uint32_t reg,
uint16_t data)
{
#if defined(__i386__) || defined(__amd64__)
outw(handle->base + reg, data);
#else
*(uint8_t *)((uintptr_t)handle->memory + reg) = data;
#endif
}
static void
pci_device_freebsd_write8(struct pci_io_handle *handle, uint32_t reg,
uint8_t data)
{
#if defined(__i386__) || defined(__amd64__)
outb(handle->base + reg, data);
#else
*(uint32_t *)((uintptr_t)handle->memory + reg) = data;
#endif
}
static int
pci_device_freebsd_map_legacy(struct pci_device *dev, pciaddr_t base,
pciaddr_t size, unsigned map_flags, void **addr)
{
struct pci_device_mapping map;
int err;
map.base = base;
map.size = size;
map.flags = map_flags;
map.memory = NULL;
err = pci_device_freebsd_map_range(dev, &map);
*addr = map.memory;
return err;
}
static int
pci_device_freebsd_unmap_legacy(struct pci_device *dev, void *addr,
pciaddr_t size)
{
struct pci_device_mapping map;
map.memory = addr;
map.size = size;
map.flags = 0;
return pci_device_freebsd_unmap_range(dev, &map);
}
static const struct pci_system_methods freebsd_pci_methods = {
.destroy = pci_system_freebsd_destroy,
.destroy_device = NULL, /* nothing to do for this */
.read_rom = pci_device_freebsd_read_rom,
.probe = pci_device_freebsd_probe,
.map_range = pci_device_freebsd_map_range,
.unmap_range = pci_device_freebsd_unmap_range,
.read = pci_device_freebsd_read,
.write = pci_device_freebsd_write,
.fill_capabilities = pci_fill_capabilities_generic,
.open_legacy_io = pci_device_freebsd_open_legacy_io,
#if defined(__i386__) || defined(__amd64__)
.close_io = pci_device_freebsd_close_io,
#endif
.read32 = pci_device_freebsd_read32,
.read16 = pci_device_freebsd_read16,
.read8 = pci_device_freebsd_read8,
.write32 = pci_device_freebsd_write32,
.write16 = pci_device_freebsd_write16,
.write8 = pci_device_freebsd_write8,
.map_legacy = pci_device_freebsd_map_legacy,
.unmap_legacy = pci_device_freebsd_unmap_legacy,
};
/**
* Attempt to access the FreeBSD PCI interface.
*/
_pci_hidden int
pci_system_freebsd_create( void )
{
struct pci_conf_io pciconfio;
struct pci_conf pciconf[255];
int pcidev;
int i;
/* Try to open the PCI device */
pcidev = open( "/dev/pci", O_RDWR | O_CLOEXEC );
if ( pcidev == -1 )
return ENXIO;
freebsd_pci_sys = calloc( 1, sizeof( struct freebsd_pci_system ) );
if ( freebsd_pci_sys == NULL ) {
close( pcidev );
return ENOMEM;
}
pci_sys = &freebsd_pci_sys->pci_sys;
pci_sys->methods = & freebsd_pci_methods;
freebsd_pci_sys->pcidev = pcidev;
/* Probe the list of devices known by the system */
bzero( &pciconfio, sizeof( struct pci_conf_io ) );
pciconfio.match_buf_len = sizeof(pciconf);
pciconfio.matches = pciconf;
if ( ioctl( pcidev, PCIOCGETCONF, &pciconfio ) == -1) {
free( pci_sys );
close( pcidev );
return errno;
}
if (pciconfio.status == PCI_GETCONF_ERROR ) {
free( pci_sys );
close( pcidev );
return EINVAL;
}
/* Translate the list of devices into pciaccess's format. */
pci_sys->num_devices = pciconfio.num_matches;
pci_sys->devices = calloc( pciconfio.num_matches,
sizeof( struct pci_device_private ) );
for ( i = 0; i < pciconfio.num_matches; i++ ) {
struct pci_conf *p = &pciconf[ i ];
#if HAVE_PCI_IO_PC_DOMAIN
pci_sys->devices[ i ].base.domain = p->pc_sel.pc_domain;
#else
pci_sys->devices[ i ].base.domain = 0;
#endif
pci_sys->devices[ i ].base.bus = p->pc_sel.pc_bus;
pci_sys->devices[ i ].base.dev = p->pc_sel.pc_dev;
pci_sys->devices[ i ].base.func = p->pc_sel.pc_func;
pci_sys->devices[ i ].base.vendor_id = p->pc_vendor;
pci_sys->devices[ i ].base.device_id = p->pc_device;
pci_sys->devices[ i ].base.subvendor_id = p->pc_subvendor;
pci_sys->devices[ i ].base.subdevice_id = p->pc_subdevice;
pci_sys->devices[ i ].base.revision = p->pc_revid;
pci_sys->devices[ i ].base.device_class = (uint32_t)p->pc_class << 16 |
(uint32_t)p->pc_subclass << 8 | (uint32_t)p->pc_progif;
pci_sys->devices[ i ].header_type = p->pc_hdr & 0x7f;
}
return 0;
}
he
* 0xc0000 mapping.
*/
if ((dev->device_class & 0x00ffff00) ==
((PCIC_DISPLAY << 16) | (PCIS_DISPLAY_VGA << 8))) {
dev->rom_size = 64 libpciaccess-0.13.2/src/common_iterator.c 0000644 0143106 0000012 00000012632 12172612452 0020643 0 ustar 00alanc staff 0000266 0200005 /*
* (C) Copyright IBM Corporation 2006
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* on the rights to use, copy, modify, merge, publish, distribute, sub
* license, and/or sell copies of the Software, and to permit persons to whom
* the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
/**
* \file common_iterator.c
* Platform independent iterator support routines.
*
* \author Ian Romanick
*/
#include
#include
#include "pciaccess.h"
#include "pciaccess_private.h"
/**
* Track device iteration state
*
* \private
*/
struct pci_device_iterator {
unsigned next_index;
enum {
match_any,
match_slot,
match_id
} mode;
union {
struct pci_slot_match slot;
struct pci_id_match id;
} match;
};
/**
* Create an iterator based on a regular expression.
*
* \return
* A pointer to a fully initialized \c pci_device_iterator structure on
* success, or \c NULL on failure.
*
* \sa pci_id_match_iterator_create, pci_device_next, pci_iterator_destroy
*/
struct pci_device_iterator *
pci_slot_match_iterator_create( const struct pci_slot_match * match )
{
struct pci_device_iterator * iter;
if ( pci_sys == NULL ) {
return NULL;
}
iter = malloc( sizeof( *iter ) );
if ( iter != NULL ) {
iter->next_index = 0;
if ( match != NULL ) {
iter->mode = match_slot;
(void) memcpy( & iter->match.slot, match, sizeof( *match ) );
}
else {
iter->mode = match_any;
}
}
return iter;
}
/**
* Create an iterator based on a regular expression.
*
* \return
* A pointer to a fully initialized \c pci_device_iterator structure on
* success, or \c NULL on failure.
*
* \sa pci_slot_match_iterator_create, pci_device_next, pci_iterator_destroy
*/
struct pci_device_iterator *
pci_id_match_iterator_create( const struct pci_id_match * match )
{
struct pci_device_iterator * iter;
if ( pci_sys == NULL ) {
return NULL;
}
iter = malloc( sizeof( *iter ) );
if ( iter != NULL ) {
iter->next_index = 0;
if ( match != NULL ) {
iter->mode = match_id;
(void) memcpy( & iter->match.id, match, sizeof( *match ) );
}
else {
iter->mode = match_any;
}
}
return iter;
}
/**
* Destroy an iterator previously created with \c pci_iterator_create.
*
* \param iter Iterator to be destroyed.
*
* \sa pci_device_next, pci_iterator_create
*/
void
pci_iterator_destroy( struct pci_device_iterator * iter )
{
if ( iter != NULL ) {
free( iter );
}
}
/**
* Iterate to the next PCI device.
*
* \param iter Device iterator returned by \c pci_device_iterate.
*
* \return
* A pointer to a \c pci_device, or \c NULL when all devices have been
* iterated.
*/
struct pci_device *
pci_device_next( struct pci_device_iterator * iter )
{
struct pci_device_private * d = NULL;
if (!iter)
return NULL;
switch( iter->mode ) {
case match_any:
if ( iter->next_index < pci_sys->num_devices ) {
d = & pci_sys->devices[ iter->next_index ];
iter->next_index++;
}
break;
case match_slot: {
while ( iter->next_index < pci_sys->num_devices ) {
struct pci_device_private * const temp =
& pci_sys->devices[ iter->next_index ];
iter->next_index++;
if ( PCI_ID_COMPARE( iter->match.slot.domain, temp->base.domain )
&& PCI_ID_COMPARE( iter->match.slot.bus, temp->base.bus )
&& PCI_ID_COMPARE( iter->match.slot.dev, temp->base.dev )
&& PCI_ID_COMPARE( iter->match.slot.func, temp->base.func ) ) {
d = temp;
break;
}
}
break;
}
case match_id: {
while ( iter->next_index < pci_sys->num_devices ) {
struct pci_device_private * const temp =
& pci_sys->devices[ iter->next_index ];
iter->next_index++;
if ( PCI_ID_COMPARE( iter->match.id.vendor_id, temp->base.vendor_id )
&& PCI_ID_COMPARE( iter->match.id.device_id, temp->base.device_id )
&& PCI_ID_COMPARE( iter->match.id.subvendor_id, temp->base.subvendor_id )
&& PCI_ID_COMPARE( iter->match.id.subdevice_id, temp->base.subdevice_id )
&& ((temp->base.device_class & iter->match.id.device_class_mask)
== iter->match.id.device_class) ) {
d = temp;
break;
}
}
break;
}
}
return (struct pci_device *) d;
}
struct pci_device *
pci_device_find_by_slot( uint32_t domain, uint32_t bus, uint32_t dev,
uint32_t func )
{
struct pci_device_iterator iter;
iter.next_index = 0;
iter.mode = match_slot;
iter.match.slot.domain = domain;
iter.match.slot.bus = bus;
iter.match.slot.dev = dev;
iter.match.slot.func = func;
return pci_device_next( & iter );
}
libpciaccess-0.13.2/src/pci_tools.h 0000644 0143106 0000012 00000015163 12172612452 0017444 0 ustar 00alanc staff 0000266 0200005 /*
* Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifndef _SYS_PCI_TOOLS_H
#define _SYS_PCI_TOOLS_H
#pragma ident "@(#)pci_tools.h 1.4 05/09/28 SMI"
#include
#ifdef __cplusplus
extern "C" {
#endif
/*
* Versioning. Have different versions for userland program and drivers, so
* they can all stay in sync with each other.
*/
#define PCITOOL_USER_VERSION 1
#define PCITOOL_DRVR_VERSION 1
/* File suffixes for nexus pcitool nodes. */
#define PCI_MINOR_REG "reg"
#define PCI_MINOR_INTR "intr"
/*
* Ioctls for PCI tools.
*/
#define PCITOOL_IOC (('P' << 24) | ('C' << 16) | ('T' << 8))
/* Read/write a device on a PCI bus, in physical space. */
#define PCITOOL_DEVICE_GET_REG (PCITOOL_IOC | 1)
#define PCITOOL_DEVICE_SET_REG (PCITOOL_IOC | 2)
/* Read/write the PCI nexus bridge, in physical space. */
#define PCITOOL_NEXUS_GET_REG (PCITOOL_IOC | 3)
#define PCITOOL_NEXUS_SET_REG (PCITOOL_IOC | 4)
/* Get/set interrupt-CPU mapping for PCI devices. */
#define PCITOOL_DEVICE_GET_INTR (PCITOOL_IOC | 5)
#define PCITOOL_DEVICE_SET_INTR (PCITOOL_IOC | 6)
/* Return the number of supported interrupts on a PCI bus. */
#define PCITOOL_DEVICE_NUM_INTR (PCITOOL_IOC | 7)
/*
* This file contains data structures for the pci tool.
*/
#define PCITOOL_CONFIG 0
#define PCITOOL_BAR0 1
#define PCITOOL_BAR1 2
#define PCITOOL_BAR2 3
#define PCITOOL_BAR3 4
#define PCITOOL_BAR4 5
#define PCITOOL_BAR5 6
#define PCITOOL_ROM 7
/*
* Pass this through barnum to signal to use a base addr instead.
* This is for platforms which do not have a way to automatically map
* a selected bank to a base addr.
*/
#define PCITOOL_BASE 0xFF
/*
* BAR corresponding to space desired.
*/
typedef enum {
config = PCITOOL_CONFIG,
bar0 = PCITOOL_BAR0,
bar1 = PCITOOL_BAR1,
bar2 = PCITOOL_BAR2,
bar3 = PCITOOL_BAR3,
bar4 = PCITOOL_BAR4,
bar5 = PCITOOL_BAR5,
rom = PCITOOL_ROM
} pcitool_bars_t;
/*
* PCITOOL error numbers.
*/
typedef enum {
PCITOOL_SUCCESS = 0x0,
PCITOOL_INVALID_CPUID,
PCITOOL_INVALID_INO,
PCITOOL_PENDING_INTRTIMEOUT,
PCITOOL_REGPROP_NOTWELLFORMED,
PCITOOL_INVALID_ADDRESS,
PCITOOL_NOT_ALIGNED,
PCITOOL_OUT_OF_RANGE,
PCITOOL_END_OF_RANGE,
PCITOOL_ROM_DISABLED,
PCITOOL_ROM_WRITE,
PCITOOL_IO_ERROR,
PCITOOL_INVALID_SIZE
} pcitool_errno_t;
/*
* PCITOOL_DEVICE_SET_INTR ioctl data structure to re-assign the interrupts.
*/
typedef struct pcitool_intr_set {
uint16_t user_version; /* Userland program version - to krnl */
uint16_t drvr_version; /* Driver version - from kernel */
uint32_t ino; /* interrupt to set - to kernel */
uint32_t cpu_id; /* to: cpu to set / from: old cpu returned */
pcitool_errno_t status; /* from kernel */
} pcitool_intr_set_t;
/*
* PCITOOL_DEVICE_GET_INTR ioctl data structure to dump out the
* ino mapping information.
*/
typedef struct pcitool_intr_dev {
uint32_t dev_inst; /* device instance - from kernel */
char driver_name[MAXMODCONFNAME]; /* from kernel */
char path[MAXPATHLEN]; /* device path - from kernel */
} pcitool_intr_dev_t;
typedef struct pcitool_intr_get {
uint16_t user_version; /* Userland program version - to krnl */
uint16_t drvr_version; /* Driver version - from kernel */
uint32_t ino; /* interrupt number - to kernel */
uint8_t num_devs_ret; /* room for this # of devs to be */
/* returned - to kernel */
/* # devs returned - from kernel */
uint8_t num_devs; /* # devs on this ino - from kernel */
/* intrs enabled for devs if > 0 */
uint8_t ctlr; /* controller number - from kernel */
uint32_t cpu_id; /* cpu of interrupt - from kernel */
pcitool_errno_t status; /* returned status - from kernel */
pcitool_intr_dev_t dev[1]; /* start of variable device list */
/* from kernel */
} pcitool_intr_get_t;
/*
* Get the size needed to return the number of devices wanted.
* Can't say num_devs - 1 as num_devs may be unsigned.
*/
#define PCITOOL_IGET_SIZE(num_devs) \
(sizeof (pcitool_intr_get_t) - \
sizeof (pcitool_intr_dev_t) + \
(num_devs * sizeof (pcitool_intr_dev_t)))
/*
* Size and endian fields for acc_attr bitmask.
*/
#define PCITOOL_ACC_ATTR_SIZE_MASK 0x3
#define PCITOOL_ACC_ATTR_SIZE_1 0x0
#define PCITOOL_ACC_ATTR_SIZE_2 0x1
#define PCITOOL_ACC_ATTR_SIZE_4 0x2
#define PCITOOL_ACC_ATTR_SIZE_8 0x3
#define PCITOOL_ACC_ATTR_SIZE(x) (1 << (x & PCITOOL_ACC_ATTR_SIZE_MASK))
#define PCITOOL_ACC_ATTR_ENDN_MASK 0x100
#define PCITOOL_ACC_ATTR_ENDN_LTL 0x0
#define PCITOOL_ACC_ATTR_ENDN_BIG 0x100
#define PCITOOL_ACC_IS_BIG_ENDIAN(x) (x & PCITOOL_ACC_ATTR_ENDN_BIG)
/*
* Data structure to read and write to pci device registers.
* This is the argument to the following ioctls:
* PCITOOL_DEVICE_SET/GET_REG
* PCITOOL_NEXUS_SET/GET_REG
*/
typedef struct pcitool_reg {
uint16_t user_version; /* Userland program version - to krnl */
uint16_t drvr_version; /* Driver version - from kernel */
uint8_t bus_no; /* pci bus - to kernel */
uint8_t dev_no; /* pci dev - to kernel */
uint8_t func_no; /* pci function - to kernel */
uint8_t barnum; /* bank (DEVCTL_NEXUS_SET/GET_REG) or */
/* BAR from pcitools_bar_t */
/* (DEVCTL_DEVICE_SET/GET_REG) */
/* to kernel */
uint64_t offset; /* to kernel */
uint32_t acc_attr; /* access attributes - to kernel */
uint32_t padding1; /* 8-byte align next uint64_t for X86 */
uint64_t data; /* to/from kernel, 64-bit alignment */
uint32_t status; /* from kernel */
uint32_t padding2; /* 8-byte align next uint64_t for X86 */
uint64_t phys_addr; /* from kernel, 64-bit alignment */
} pcitool_reg_t;
#ifdef __cplusplus
}
#endif
#endif /* _SYS_PCI_TOOLS_H */
libpciaccess-0.13.2/src/common_vgaarb.c 0000644 0143106 0000012 00000017520 12172612452 0020255 0 ustar 00alanc staff 0000266 0200005 /*
* Copyright (c) 2007 Paulo R. Zanoni, Tiago Vignatti
* 2009 Tiago Vignatti
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include
#include
#include
#include
#include
#include
#include
#include "config.h"
#include "pciaccess.h"
#include "pciaccess_private.h"
#define BUFSIZE 64
static int
parse_string_to_decodes_rsrc(char *input, int *vga_count, struct pci_slot_match *match)
{
char *tok;
char *input_sp = NULL, *count_sp, *pci_sp;
char tmp[32];
tok = strtok_r(input,",",&input_sp);
if (!tok)
goto fail;
strncpy(tmp, input, 15);
tmp[15] = 0;
tok = strtok_r(tmp,":",&count_sp);
if (!tok)
goto fail;
tok = strtok_r(NULL, ":",&count_sp);
if (!tok)
goto fail;
*vga_count = strtoul(tok, NULL, 10);
if (*vga_count == LONG_MAX)
goto fail;
#ifdef DEBUG
fprintf(stderr,"vga count is %d\n", *vga_count);
#endif
tok = strtok_r(NULL, ",",&input_sp);
if (!tok)
goto fail;
if (match) {
strncpy(tmp, tok, 32);
tmp[31] = 0;
tok = strtok_r(tmp, ":", &pci_sp);
if (!tok)
goto fail;
tok = strtok_r(NULL, ":", &pci_sp);
if (!tok)
goto fail;
match->domain = strtoul(tok, NULL, 16);
tok = strtok_r(NULL, ":", &pci_sp);
if (!tok)
goto fail;
match->bus = strtoul(tok, NULL, 16);
tok = strtok_r(NULL, ".", &pci_sp);
if (!tok)
goto fail;
match->dev = strtoul(tok, NULL, 16);
tok = strtok_r(NULL, ".", &pci_sp);
if (!tok)
goto fail;
match->func = strtoul(tok, NULL, 16);
}
tok = strtok_r(NULL, ",",&input_sp);
if (!tok)
goto fail;
tok = strtok_r(tok, "=", &input_sp);
if (!tok)
goto fail;
tok = strtok_r(NULL, "=", &input_sp);
if (!tok)
goto fail;
if (!strncmp(tok, "io+mem", 6))
return VGA_ARB_RSRC_LEGACY_IO | VGA_ARB_RSRC_LEGACY_MEM;
if (!strncmp(tok, "io", 2))
return VGA_ARB_RSRC_LEGACY_IO;
if (!strncmp(tok, "mem", 3))
return VGA_ARB_RSRC_LEGACY_MEM;
fail:
return VGA_ARB_RSRC_NONE;
}
int
pci_device_vgaarb_init(void)
{
struct pci_slot_match match;
char buf[BUFSIZE];
int ret, rsrc;
if (!pci_sys)
return -1;
if ((pci_sys->vgaarb_fd = open ("/dev/vga_arbiter", O_RDWR | O_CLOEXEC)) < 0) {
return errno;
}
ret = read(pci_sys->vgaarb_fd, buf, BUFSIZE);
if (ret <= 0)
return -1;
memset(&match, 0xff, sizeof(match));
/* need to find the device to go back to and what it was decoding */
rsrc = parse_string_to_decodes_rsrc(buf, &pci_sys->vga_count, &match);
pci_sys->vga_default_dev = pci_device_find_by_slot(match.domain, match.bus, match.dev, match.func);
if (pci_sys->vga_default_dev)
pci_sys->vga_default_dev->vgaarb_rsrc = rsrc;
return 0;
}
void
pci_device_vgaarb_fini(void)
{
if (!pci_sys)
return;
close(pci_sys->vgaarb_fd);
}
/**
* Writes message on vga device. The messages are defined by the kernel
* implementation.
*
* \param fd vga arbiter device.
* \param buf message itself.
* \param len message length.
*
* \return
* Zero on success, 1 if something gets wrong and 2 if fd is busy (only for
* 'trylock')
*/
static int
vgaarb_write(int fd, char *buf, int len)
{
int ret;
buf[len] = '\0';
ret = write(fd, buf, len);
if (ret == -1) {
/* the user may have called "trylock" and didn't get the lock */
if (errno == EBUSY)
return 2;
#ifdef DEBUG
fprintf(stderr, "write error");
#endif
return 1;
}
else if (ret != len) {
/* it's need to receive the exactly amount required. */
#ifdef DEBUG
fprintf(stderr, "write error: wrote different than expected\n");
#endif
return 1;
}
#ifdef DEBUG
fprintf(stderr, "%s: successfully wrote: '%s'\n", __FUNCTION__, buf);
#endif
return 0;
}
static const char *
rsrc_to_str(int iostate)
{
switch (iostate) {
case VGA_ARB_RSRC_LEGACY_IO | VGA_ARB_RSRC_LEGACY_MEM:
return "io+mem";
case VGA_ARB_RSRC_LEGACY_IO:
return "io";
case VGA_ARB_RSRC_LEGACY_MEM:
return "mem";
}
return "none";
}
int
pci_device_vgaarb_set_target(struct pci_device *dev)
{
int len;
char buf[BUFSIZE];
int ret;
if (!dev)
dev = pci_sys->vga_default_dev;
if (!dev)
return -1;
len = snprintf(buf, BUFSIZE, "target PCI:%04x:%02x:%02x.%x",
dev->domain, dev->bus, dev->dev, dev->func);
ret = vgaarb_write(pci_sys->vgaarb_fd, buf, len);
if (ret)
return ret;
ret = read(pci_sys->vgaarb_fd, buf, BUFSIZE);
if (ret <= 0)
return -1;
dev->vgaarb_rsrc = parse_string_to_decodes_rsrc(buf, &pci_sys->vga_count, NULL);
pci_sys->vga_target = dev;
return 0;
}
int
pci_device_vgaarb_decodes(int new_vgaarb_rsrc)
{
int len;
char buf[BUFSIZE];
int ret;
struct pci_device *dev = pci_sys->vga_target;
if (!dev)
return -1;
if (dev->vgaarb_rsrc == new_vgaarb_rsrc)
return 0;
len = snprintf(buf, BUFSIZE, "decodes %s", rsrc_to_str(new_vgaarb_rsrc));
ret = vgaarb_write(pci_sys->vgaarb_fd, buf, len);
if (ret == 0)
dev->vgaarb_rsrc = new_vgaarb_rsrc;
ret = read(pci_sys->vgaarb_fd, buf, BUFSIZE);
if (ret <= 0)
return -1;
parse_string_to_decodes_rsrc(buf, &pci_sys->vga_count, NULL);
return ret;
}
int
pci_device_vgaarb_lock(void)
{
int len;
char buf[BUFSIZE];
struct pci_device *dev = pci_sys->vga_target;
if (!dev)
return -1;
if (dev->vgaarb_rsrc == 0 || pci_sys->vga_count == 1)
return 0;
len = snprintf(buf, BUFSIZE, "lock %s", rsrc_to_str(dev->vgaarb_rsrc));
return vgaarb_write(pci_sys->vgaarb_fd, buf, len);
}
int
pci_device_vgaarb_trylock(void)
{
int len;
char buf[BUFSIZE];
struct pci_device *dev = pci_sys->vga_target;
if (!dev)
return -1;
if (dev->vgaarb_rsrc == 0 || pci_sys->vga_count == 1)
return 0;
len = snprintf(buf, BUFSIZE, "trylock %s", rsrc_to_str(dev->vgaarb_rsrc));
return vgaarb_write(pci_sys->vgaarb_fd, buf, len);
}
int
pci_device_vgaarb_unlock(void)
{
int len;
char buf[BUFSIZE];
struct pci_device *dev = pci_sys->vga_target;
if (!dev)
return -1;
if (dev->vgaarb_rsrc == 0 || pci_sys->vga_count == 1)
return 0;
len = snprintf(buf, BUFSIZE, "unlock %s", rsrc_to_str(dev->vgaarb_rsrc));
return vgaarb_write(pci_sys->vgaarb_fd, buf, len);
}
int pci_device_vgaarb_get_info(struct pci_device *dev, int *vga_count, int *rsrc_decodes)
{
*vga_count = pci_sys->vga_count;
if (!dev)
return 0;
*rsrc_decodes = dev->vgaarb_rsrc;
return 0;
}
t, rsrc;
if (!pci_sys)
return -1;
if ((pci_sys->vgaarb_fd = open ("/dev/vga_arbiter", O_RDWR | O_CLOEXEC)) < 0) {
return errno;
}
ret = read(libpciaccess-0.13.2/src/common_vgaarb_stub.c 0000644 0143106 0000012 00000003503 12172612452 0021306 0 ustar 00alanc staff 0000266 0200005 /*
* Copyright (c) 2009 Tiago Vignatti
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include
#include "pciaccess.h"
int
pci_device_vgaarb_init(void)
{
#ifdef DEBUG
fprintf(stderr, "%s: You're using VGA arbiter stub functions!\n",
__FUNCTION__);
#endif
return -1;
}
void
pci_device_vgaarb_fini(void)
{
}
int
pci_device_vgaarb_set_target(struct pci_device *dev)
{
return -1;
}
int
pci_device_vgaarb_decodes(int new_vga_rsrc)
{
return -1;
}
int
pci_device_vgaarb_lock(void)
{
return -1;
}
int
pci_device_vgaarb_trylock(void)
{
return -1;
}
int
pci_device_vgaarb_unlock(void)
{
return 0;
}
int pci_device_vgaarb_get_info(struct pci_device *dev, int *vga_count,
int *rsrc_decodes)
{
return -1;
}
libpciaccess-0.13.2/src/linux_devmem.h 0000644 0143106 0000012 00000002646 12172612452 0020147 0 ustar 00alanc staff 0000266 0200005 /*
* (C) Copyright IBM Corporation 2007
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* on the rights to use, copy, modify, merge, publish, distribute, sub
* license, and/or sell copies of the Software, and to permit persons to whom
* the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
/**
* \file linux_devmem.h
* Functions and datastructures that are private to the /dev/mem based
* back-end for pciaccess.
*
* \author Ian Romanick
*/
extern int pci_device_linux_devmem_read_rom(struct pci_device *dev,
void *buffer);
libpciaccess-0.13.2/src/common_interface.c 0000644 0143106 0000012 00000044172 12172612452 0020756 0 ustar 00alanc staff 0000266 0200005 /*
* (C) Copyright IBM Corporation 2006
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* on the rights to use, copy, modify, merge, publish, distribute, sub
* license, and/or sell copies of the Software, and to permit persons to whom
* the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
/**
* \file common_interface.c
* Platform independent interface glue.
*
* \author Ian Romanick
*/
#include
#include
#include
#include "pciaccess.h"
#include "pciaccess_private.h"
#if defined(__linux__) || defined(__GLIBC__)
#include
#if __BYTE_ORDER == __BIG_ENDIAN
# define LETOH_16(x) bswap_16(x)
# define HTOLE_16(x) bswap_16(x)
# define LETOH_32(x) bswap_32(x)
# define HTOLE_32(x) bswap_32(x)
#else
# define LETOH_16(x) (x)
# define HTOLE_16(x) (x)
# define LETOH_32(x) (x)
# define HTOLE_32(x) (x)
#endif /* linux */
#elif defined(__sun)
#include
#ifdef _BIG_ENDIAN
# define LETOH_16(x) BSWAP_16(x)
# define HTOLE_16(x) BSWAP_16(x)
# define LETOH_32(x) BSWAP_32(x)
# define HTOLE_32(x) BSWAP_32(x)
#else
# define LETOH_16(x) (x)
# define HTOLE_16(x) (x)
# define LETOH_32(x) (x)
# define HTOLE_32(x) (x)
#endif /* Solaris */
#else
#include
#define HTOLE_16(x) htole16(x)
#define HTOLE_32(x) htole32(x)
#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__NetBSD__)
#define LETOH_16(x) le16toh(x)
#define LETOH_32(x) le32toh(x)
#else
#define LETOH_16(x) letoh16(x)
#define LETOH_32(x) letoh32(x)
#endif
#endif /* others */
/**
* Read a device's expansion ROM.
*
* Reads the device's expansion ROM and stores the data in the memory pointed
* to by \c buffer. The buffer must be at least \c pci_device::rom_size
* bytes.
*
* \param dev Device whose expansion ROM is to be read.
* \param buffer Memory in which to store the ROM.
*
* \return
* Zero on success or an \c errno value on failure.
*/
int
pci_device_read_rom( struct pci_device * dev, void * buffer )
{
if ( (dev == NULL) || (buffer == NULL) ) {
return EFAULT;
}
return (pci_sys->methods->read_rom)( dev, buffer );
}
/**
* Probe a PCI (VGA) device to determine if its the boot VGA device
*
* \param dev Device whose VGA status to query
* \return
* Zero if not the boot VGA, 1 if the boot VGA.
*/
int
pci_device_is_boot_vga( struct pci_device * dev )
{
if (!pci_sys->methods->boot_vga)
return 0;
return pci_sys->methods->boot_vga( dev );
}
/**
* Probe a PCI device to determine if a kernel driver is attached.
*
* \param dev Device to query
* \return
* Zero if no driver attached, 1 if attached kernel drviver
*/
int
pci_device_has_kernel_driver( struct pci_device * dev )
{
if (!pci_sys->methods->has_kernel_driver)
return 0;
return pci_sys->methods->has_kernel_driver( dev );
}
/**
* Probe a PCI device to learn information about the device.
*
* Probes a PCI device to learn various information about the device. Before
* calling this function, the only public fields in the \c pci_device
* structure that have valid values are \c pci_device::domain,
* \c pci_device::bus, \c pci_device::dev, and \c pci_device::func.
*
* \param dev Device to be probed.
*
* \return
* Zero on success or an \c errno value on failure.
*/
int
pci_device_probe( struct pci_device * dev )
{
if ( dev == NULL ) {
return EFAULT;
}
return (pci_sys->methods->probe)( dev );
}
/**
* Map the specified BAR so that it can be accessed by the CPU.
*
* Maps the specified BAR for access by the processor. The pointer to the
* mapped region is stored in the \c pci_mem_region::memory pointer for the
* BAR.
*
* \param dev Device whose memory region is to be mapped.
* \param region Region, on the range [0, 5], that is to be mapped.
* \param write_enable Map for writing (non-zero).
*
* \return
* Zero on success or an \c errno value on failure.
*
* \sa pci_device_map_range, pci_device_unmap_range
* \deprecated
*/
int
pci_device_map_region(struct pci_device * dev, unsigned region,
int write_enable)
{
const unsigned map_flags =
(write_enable) ? PCI_DEV_MAP_FLAG_WRITABLE : 0;
if ((region > 5) || (dev->regions[region].size == 0)) {
return ENOENT;
}
if (dev->regions[region].memory != NULL) {
return 0;
}
return pci_device_map_range(dev, dev->regions[region].base_addr,
dev->regions[region].size, map_flags,
&dev->regions[region].memory);
}
/**
* Map the specified memory range so that it can be accessed by the CPU.
*
* Maps the specified memory range for access by the processor. The pointer
* to the mapped region is stored in \c addr. In addition, the
* \c pci_mem_region::memory pointer for the BAR will be updated.
*
* \param dev Device whose memory region is to be mapped.
* \param base Base address of the range to be mapped.
* \param size Size of the range to be mapped.
* \param write_enable Map for writing (non-zero).
* \param addr Location to store the mapped address.
*
* \return
* Zero on success or an \c errno value on failure.
*
* \sa pci_device_map_range
*/
int pci_device_map_memory_range(struct pci_device *dev,
pciaddr_t base, pciaddr_t size,
int write_enable, void **addr)
{
return pci_device_map_range(dev, base, size,
(write_enable) ? PCI_DEV_MAP_FLAG_WRITABLE : 0,
addr);
}
/**
* Map the specified memory range so that it can be accessed by the CPU.
*
* Maps the specified memory range for access by the processor. The pointer
* to the mapped region is stored in \c addr. In addition, the
* \c pci_mem_region::memory pointer for the BAR will be updated.
*
* \param dev Device whose memory region is to be mapped.
* \param base Base address of the range to be mapped.
* \param size Size of the range to be mapped.
* \param map_flags Flag bits controlling how the mapping is accessed.
* \param addr Location to store the mapped address.
*
* \return
* Zero on success or an \c errno value on failure.
*
* \sa pci_device_unmap_range
*/
int
pci_device_map_range(struct pci_device *dev, pciaddr_t base,
pciaddr_t size, unsigned map_flags,
void **addr)
{
struct pci_device_private *const devp =
(struct pci_device_private *) dev;
struct pci_device_mapping *mappings;
unsigned region;
unsigned i;
int err = 0;
*addr = NULL;
if (dev == NULL) {
return EFAULT;
}
for (region = 0; region < 6; region++) {
const struct pci_mem_region * const r = &dev->regions[region];
if (r->size != 0) {
if ((r->base_addr <= base) && ((r->base_addr + r->size) > base)) {
if ((base + size) > (r->base_addr + r->size)) {
return E2BIG;
}
break;
}
}
}
if (region > 5) {
return ENOENT;
}
/* Make sure that there isn't already a mapping with the same base and
* size.
*/
for (i = 0; i < devp->num_mappings; i++) {
if ((devp->mappings[i].base == base)
&& (devp->mappings[i].size == size)) {
return EINVAL;
}
}
mappings = realloc(devp->mappings,
(sizeof(devp->mappings[0]) * (devp->num_mappings + 1)));
if (mappings == NULL) {
return ENOMEM;
}
mappings[devp->num_mappings].base = base;
mappings[devp->num_mappings].size = size;
mappings[devp->num_mappings].region = region;
mappings[devp->num_mappings].flags = map_flags;
mappings[devp->num_mappings].memory = NULL;
if (dev->regions[region].memory == NULL) {
err = (*pci_sys->methods->map_range)(dev,
&mappings[devp->num_mappings]);
}
if (err == 0) {
*addr = mappings[devp->num_mappings].memory;
devp->num_mappings++;
} else {
mappings = realloc(mappings,
(sizeof(mappings[0]) * devp->num_mappings));
}
devp->mappings = mappings;
return err;
}
/**
* Unmap the specified BAR so that it can no longer be accessed by the CPU.
*
* Unmaps the specified BAR that was previously mapped via
* \c pci_device_map_region.
*
* \param dev Device whose memory region is to be mapped.
* \param region Region, on the range [0, 5], that is to be mapped.
*
* \return
* Zero on success or an \c errno value on failure.
*
* \sa pci_device_map_range, pci_device_unmap_range
* \deprecated
*/
int
pci_device_unmap_region( struct pci_device * dev, unsigned region )
{
int err;
if (dev == NULL) {
return EFAULT;
}
if ((region > 5) || (dev->regions[region].size == 0)) {
return ENOENT;
}
err = pci_device_unmap_range(dev, dev->regions[region].memory,
dev->regions[region].size);
if (!err) {
dev->regions[region].memory = NULL;
}
return err;
}
/**
* Unmap the specified memory range so that it can no longer be accessed by the CPU.
*
* Unmaps the specified memory range that was previously mapped via
* \c pci_device_map_memory_range.
*
* \param dev Device whose memory is to be unmapped.
* \param memory Pointer to the base of the mapped range.
* \param size Size, in bytes, of the range to be unmapped.
*
* \return
* Zero on success or an \c errno value on failure.
*
* \sa pci_device_map_range, pci_device_unmap_range
* \deprecated
*/
int
pci_device_unmap_memory_range(struct pci_device *dev, void *memory,
pciaddr_t size)
{
return pci_device_unmap_range(dev, memory, size);
}
/**
* Unmap the specified memory range so that it can no longer be accessed by the CPU.
*
* Unmaps the specified memory range that was previously mapped via
* \c pci_device_map_memory_range.
*
* \param dev Device whose memory is to be unmapped.
* \param memory Pointer to the base of the mapped range.
* \param size Size, in bytes, of the range to be unmapped.
*
* \return
* Zero on success or an \c errno value on failure.
*
* \sa pci_device_map_range
*/
int
pci_device_unmap_range(struct pci_device *dev, void *memory,
pciaddr_t size)
{
struct pci_device_private *const devp =
(struct pci_device_private *) dev;
unsigned i;
int err;
if (dev == NULL) {
return EFAULT;
}
for (i = 0; i < devp->num_mappings; i++) {
if ((devp->mappings[i].memory == memory)
&& (devp->mappings[i].size == size)) {
break;
}
}
if (i == devp->num_mappings) {
return ENOENT;
}
err = (*pci_sys->methods->unmap_range)(dev, &devp->mappings[i]);
if (!err) {
const unsigned entries_to_move = (devp->num_mappings - i) - 1;
if (entries_to_move > 0) {
(void) memmove(&devp->mappings[i],
&devp->mappings[i + 1],
entries_to_move * sizeof(devp->mappings[0]));
}
devp->num_mappings--;
devp->mappings = realloc(devp->mappings,
(sizeof(devp->mappings[0]) * devp->num_mappings));
}
return err;
}
/**
* Read arbitrary bytes from device's PCI config space
*
* Reads data from the device's PCI configuration space. As with the system
* read command, less data may be returned, without an error, than was
* requested. This is particularly the case if a non-root user tries to read
* beyond the first 64-bytes of configuration space.
*
* \param dev Device whose PCI configuration data is to be read.
* \param data Location to store the data
* \param offset Initial byte offset to read
* \param size Total number of bytes to read
* \param bytes_read Location to store the actual number of bytes read. This
* pointer may be \c NULL.
*
* \returns
* Zero on success or an errno value on failure.
*
* \note
* Data read from PCI configuration space using this routine is \b not
* byte-swapped to the host's byte order. PCI configuration data is always
* stored in little-endian order, and that is what this routine returns.
*/
int
pci_device_cfg_read( struct pci_device * dev, void * data,
pciaddr_t offset, pciaddr_t size,
pciaddr_t * bytes_read )
{
pciaddr_t scratch;
if ( (dev == NULL) || (data == NULL) ) {
return EFAULT;
}
return pci_sys->methods->read( dev, data, offset, size,
(bytes_read == NULL)
? & scratch : bytes_read );
}
int
pci_device_cfg_read_u8( struct pci_device * dev, uint8_t * data,
pciaddr_t offset )
{
pciaddr_t bytes;
int err = pci_device_cfg_read( dev, data, offset, 1, & bytes );
if ( (err == 0) && (bytes != 1) ) {
err = ENXIO;
}
return err;
}
int
pci_device_cfg_read_u16( struct pci_device * dev, uint16_t * data,
pciaddr_t offset )
{
pciaddr_t bytes;
int err = pci_device_cfg_read( dev, data, offset, 2, & bytes );
if ( (err == 0) && (bytes != 2) ) {
err = ENXIO;
}
*data = LETOH_16( *data );
return err;
}
int
pci_device_cfg_read_u32( struct pci_device * dev, uint32_t * data,
pciaddr_t offset )
{
pciaddr_t bytes;
int err = pci_device_cfg_read( dev, data, offset, 4, & bytes );
if ( (err == 0) && (bytes != 4) ) {
err = ENXIO;
}
*data = LETOH_32( *data );
return err;
}
/**
* Write arbitrary bytes to device's PCI config space
*
* Writes data to the device's PCI configuration space. As with the system
* write command, less data may be written, without an error, than was
* requested.
*
* \param dev Device whose PCI configuration data is to be written.
* \param data Location of the source data
* \param offset Initial byte offset to write
* \param size Total number of bytes to write
* \param bytes_read Location to store the actual number of bytes written.
* This pointer may be \c NULL.
*
* \returns
* Zero on success or an errno value on failure.
*
* \note
* Data written to PCI configuration space using this routine is \b not
* byte-swapped from the host's byte order. PCI configuration data is always
* stored in little-endian order, so data written with this routine should be
* put in that order in advance.
*/
int
pci_device_cfg_write( struct pci_device * dev, const void * data,
pciaddr_t offset, pciaddr_t size,
pciaddr_t * bytes_written )
{
pciaddr_t scratch;
if ( (dev == NULL) || (data == NULL) ) {
return EFAULT;
}
return pci_sys->methods->write( dev, data, offset, size,
(bytes_written == NULL)
? & scratch : bytes_written );
}
int
pci_device_cfg_write_u8(struct pci_device *dev, uint8_t data,
pciaddr_t offset)
{
pciaddr_t bytes;
int err = pci_device_cfg_write(dev, & data, offset, 1, & bytes);
if ( (err == 0) && (bytes != 1) ) {
err = ENOSPC;
}
return err;
}
int
pci_device_cfg_write_u16(struct pci_device *dev, uint16_t data,
pciaddr_t offset)
{
pciaddr_t bytes;
const uint16_t temp = HTOLE_16(data);
int err = pci_device_cfg_write( dev, & temp, offset, 2, & bytes );
if ( (err == 0) && (bytes != 2) ) {
err = ENOSPC;
}
return err;
}
int
pci_device_cfg_write_u32(struct pci_device *dev, uint32_t data,
pciaddr_t offset)
{
pciaddr_t bytes;
const uint32_t temp = HTOLE_32(data);
int err = pci_device_cfg_write( dev, & temp, offset, 4, & bytes );
if ( (err == 0) && (bytes != 4) ) {
err = ENOSPC;
}
return err;
}
int
pci_device_cfg_write_bits( struct pci_device * dev, uint32_t mask,
uint32_t data, pciaddr_t offset )
{
uint32_t temp;
int err;
err = pci_device_cfg_read_u32( dev, & temp, offset );
if ( ! err ) {
temp &= ~mask;
temp |= data;
err = pci_device_cfg_write_u32(dev, temp, offset);
}
return err;
}
void
pci_device_enable(struct pci_device *dev)
{
if (dev == NULL) {
return;
}
if (pci_sys->methods->enable)
pci_sys->methods->enable(dev);
}
/**
* Map the legacy memory space for the PCI domain containing \c dev.
*
* \param dev Device whose memory region is to be mapped.
* \param base Base address of the range to be mapped.
* \param size Size of the range to be mapped.
* \param map_flags Flag bits controlling how the mapping is accessed.
* \param addr Location to store the mapped address.
*
* \returns
* Zero on success or an \c errno value on failure.
*/
int
pci_device_map_legacy(struct pci_device *dev, pciaddr_t base, pciaddr_t size,
unsigned map_flags, void **addr)
{
if (base > 0x100000 || base + size > 0x100000)
return EINVAL;
if (!pci_sys->methods->map_legacy)
return ENOSYS;
return pci_sys->methods->map_legacy(dev, base, size, map_flags, addr);
}
/**
* Unmap the legacy memory space for the PCI domain containing \c dev.
*
* \param dev Device whose memory region is to be unmapped.
* \param addr Location of the mapped address.
* \param size Size of the range to be unmapped.
*
* \returns
* Zero on success or an \c errno value on failure.
*/
int
pci_device_unmap_legacy(struct pci_device *dev, void *addr, pciaddr_t size)
{
if (!pci_sys->methods->unmap_legacy)
return ENOSYS;
return pci_sys->methods->unmap_legacy(dev, addr, size);
}
(sizeof(devp->mappings[0]) * (devp->num_mappings + 1)));
if (mappings == NULL) {
return ENOMEM;
}
mappings[devp->num_mappings].base = base;
mappings[devp->num_mappings].size = size;
mappings[devp->num_mappings].region = region;
mappings[devp->num_mappings].flags = map_flags;
mappings[devp->num_mappings].memory = NULL;
if (dev->regions[relibpciaccess-0.13.2/configure.ac 0000644 0143106 0000012 00000010313 12172612452 0016767 0 ustar 00alanc staff 0000266 0200005 # (C) Copyright IBM Corporation 2006
# All Rights Reserved.
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# on the rights to use, copy, modify, merge, publish, distribute, sub
# license, and/or sell copies of the Software, and to permit persons to whom
# the Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice (including the next
# paragraph) shall be included in all copies or substantial portions of the
# Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
# IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
#
# Initialize Autoconf
AC_PREREQ([2.60])
AC_INIT([libpciaccess],[0.13.2],
[https://bugs.freedesktop.org/enter_bug.cgi?product=xorg&component=libpciaccess],[libpciaccess])
AC_CONFIG_SRCDIR([Makefile.am])
AC_CONFIG_HEADERS([config.h])
# Initialize Automake
AM_INIT_AUTOMAKE([foreign dist-bzip2])
AC_USE_SYSTEM_EXTENSIONS
# Initialize libtool
AC_PROG_LIBTOOL
# Require X.Org macros 1.8 or later
m4_ifndef([XORG_MACROS_VERSION],
[m4_fatal([must install xorg-macros 1.8 or later before running autoconf/autogen])])
XORG_MACROS_VERSION(1.8)
XORG_DEFAULT_OPTIONS
pciids_path=/usr/share/hwdata
AC_ARG_WITH(pciids-path, AS_HELP_STRING([--with-pciids-path=PCIIDS_PATH],
[Path to pci.ids file]), [pciids_path="$withval"])
AX_DEFINE_DIR(PCIIDS_PATH, pciids_path, [Path to pci.ids])
AC_ARG_ENABLE(linux-rom-fallback, AS_HELP_STRING([--enable-linux-rom-fallback],
[Enable support for falling back to /dev/mem for roms (default: disabled)]),
[LINUX_ROM=$enableval],[LINUX_ROM=no])
if test "x$LINUX_ROM" = xyes; then
AC_DEFINE(LINUX_ROM, 1, [Linux ROM read fallback])
fi
use_zlib=no
AC_ARG_WITH(zlib, AS_HELP_STRING([--with-zlib],
[Enable zlib support to read gzip compressed pci.ids]),
[use_zlib="$withval"])
if test "x$use_zlib" = xyes; then
AC_CHECK_LIB(z, gzopen,
[PCIACCESS_LIBS="$PCIACCESS_LIBS -lz"],
[AC_MSG_ERROR(Check for zlib library failed)])
AC_CHECK_HEADER([zlib.h],
[AC_DEFINE(HAVE_ZLIB, 1, [Use zlib to read gzip compressed pci.ids])],
[AC_MSG_ERROR(Check for zlib.h header file failed)])
fi
case $host_os in
*freebsd* | *dragonfly*)
freebsd=yes
;;
*linux*)
linux=yes
;;
*netbsd*)
case $host in
*i386*)
PCIACCESS_LIBS="-li386 -lpci"
;;
*x86_64*|*amd64*)
PCIACCESS_LIBS="-lx86_64 -lpci"
;;
esac
netbsd=yes
;;
*openbsd*)
openbsd=yes
;;
*solaris*)
solaris=yes
PCIACCESS_LIBS="$PCIACCESS_LIBS -ldevinfo"
;;
gnu*)
gnu=yes
;;
esac
AM_CONDITIONAL(LINUX, [test "x$linux" = xyes])
AM_CONDITIONAL(FREEBSD, [test "x$freebsd" = xyes])
AM_CONDITIONAL(NETBSD, [test "x$netbsd" = xyes])
AM_CONDITIONAL(OPENBSD, [test "x$openbsd" = xyes])
AM_CONDITIONAL(SOLARIS, [test "x$solaris" = xyes])
AM_CONDITIONAL(GNU, [test "x$gnu" = xyes])
AC_SYS_LARGEFILE
AC_CHECK_HEADERS([err.h])
if test "x$netbsd" = xyes; then
AC_CHECK_HEADERS([machine/sysarch.h])
AC_CHECK_HEADERS([machine/mtrr.h], [have_mtrr_h="yes"], [have_mtrr_h="no"],
[#ifdef HAVE_MACHINE_SYSARCH_H
#include
#include
#endif
])
else
AC_CHECK_HEADER([asm/mtrr.h], [have_mtrr_h="yes"], [have_mtrr_h="no"])
fi
if test "x$have_mtrr_h" = xyes; then
AC_DEFINE(HAVE_MTRR, 1, [Use MTRRs on mappings])
fi
# check for the pci_io.pi_sel.pc_domain
AC_CHECK_MEMBER([struct pci_io.pi_sel.pc_domain],
[AC_DEFINE(HAVE_PCI_IO_PC_DOMAIN,1,[Have the pci_io.pi_sel.pc_domain member.])],
[],
[ #include
#include
])
AC_SUBST(PCIACCESS_CFLAGS)
AC_SUBST(PCIACCESS_LIBS)
AC_CONFIG_FILES([Makefile
include/Makefile
man/Makefile
src/Makefile
scanpci/Makefile
pciaccess.pc])
AC_OUTPUT
th=/usr/share/hwdata
AC_ARG_WITH(pciids-path, AS_HELP_STRING([--with-pciids-path=PCIIDS_PATH],
[Path to pci.ids file]), [pciids_path="$withval"])
AX_DEFINE_DIR(PCIIDS_PATH, pciids_path, [Path to pci.ids])
AC_ARG_ENABLE(linux-rom-fallback, AS_HELP_STRING([--enable-linux-rom-fallback],
[Enable support for libpciaccess-0.13.2/scanpci/scanpci.c 0000644 0143106 0000012 00000014514 12172612452 0017714 0 ustar 00alanc staff 0000266 0200005 /*
* (C) Copyright IBM Corporation 2006
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* on the rights to use, copy, modify, merge, publish, distribute, sub
* license, and/or sell copies of the Software, and to permit persons to whom
* the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include
#include
#include
#include
#ifdef HAVE_ERR_H
#include
#else
# include
# include
# define err(exitcode, format, args...) \
errx(exitcode, format ": %s", ## args, strerror(errno))
# define errx(exitcode, format, args...) \
{ warnx(format, ## args); exit(exitcode); }
# define warn(format, args...) \
warnx(format ": %s", ## args, strerror(errno))
# define warnx(format, args...) \
fprintf(stderr, format "\n", ## args)
#endif
#include "pciaccess.h"
#include "pciaccess_private.h"
static void
print_pci_bridge( const struct pci_bridge_info * info )
{
printf( " Bus: primary=%02"PRIx8", secondary=%02"PRIx8", subordinate=%02"PRIx8", "
"sec-latency=%"PRIu8"\n",
info->primary_bus,
info->secondary_bus,
info->subordinate_bus,
info->secondary_latency_timer );
printf( " I/O behind bridge: %08"PRIx32"-%08"PRIx32"\n",
info->io_base,
info->io_limit );
printf( " Memory behind bridge: %08"PRIx32"-%08"PRIx32"\n",
info->mem_base,
info->mem_limit );
printf( " Prefetchable memory behind bridge: %08"PRIx64"-%08"PRIx64"\n",
info->prefetch_mem_base,
info->prefetch_mem_limit );
}
static void
print_pci_device( struct pci_device * dev, int verbose )
{
const char * dev_name;
const char * vend_name;
vend_name = pci_device_get_vendor_name( dev );
dev_name = pci_device_get_device_name( dev );
if ( dev_name == NULL ) {
dev_name = "Device unknown";
}
printf("\npci ");
if (dev->domain != 0)
printf("domain 0x%04x ", dev->domain);
printf("bus 0x%04x cardnum 0x%02x function 0x%02x:"
" vendor 0x%04x device 0x%04x\n",
dev->bus,
dev->dev,
dev->func,
dev->vendor_id,
dev->device_id );
if ( vend_name != NULL ) {
printf( " %s %s\n", vend_name, dev_name );
}
else {
printf( " %s\n", dev_name );
}
if ( verbose ) {
unsigned i;
uint16_t command, status;
uint8_t bist;
uint8_t header_type;
uint8_t latency_timer;
uint8_t cache_line_size;
uint8_t max_latency;
uint8_t min_grant;
uint8_t int_pin;
vend_name = pci_device_get_subvendor_name( dev );
dev_name = pci_device_get_subdevice_name( dev );
if ( dev_name == NULL ) {
dev_name = "Card unknown";
}
printf( " CardVendor 0x%04x card 0x%04x (",
dev->subvendor_id,
dev->subdevice_id );
if ( vend_name != NULL ) {
printf( "%s, %s)\n", vend_name, dev_name );
}
else {
printf( "%s)\n", dev_name );
}
pci_device_cfg_read_u16( dev, & command, 4 );
pci_device_cfg_read_u16( dev, & status, 6 );
printf( " STATUS 0x%04x COMMAND 0x%04x\n",
status,
command );
printf( " CLASS 0x%02x 0x%02x 0x%02x REVISION 0x%02x\n",
(dev->device_class >> 16) & 0x0ff,
(dev->device_class >> 8) & 0x0ff,
(dev->device_class >> 0) & 0x0ff,
dev->revision );
pci_device_cfg_read_u8( dev, & cache_line_size, 12 );
pci_device_cfg_read_u8( dev, & latency_timer, 13 );
pci_device_cfg_read_u8( dev, & header_type, 14 );
pci_device_cfg_read_u8( dev, & bist, 15 );
printf( " BIST 0x%02x HEADER 0x%02x LATENCY 0x%02x CACHE 0x%02x\n",
bist,
header_type,
latency_timer,
cache_line_size );
pci_device_probe( dev );
for ( i = 0 ; i < 6 ; i++ ) {
if ( dev->regions[i].base_addr != 0 ) {
printf( " BASE%u 0x%0*"PRIxPTR" SIZE %zu %s",
i,
dev->regions[i].is_64 ? 16 : 8,
(intptr_t) dev->regions[i].base_addr,
(size_t) dev->regions[i].size,
(dev->regions[i].is_IO) ? "I/O" :
((dev->regions[i].is_64) ? "MEM64" : "MEM"));
if ( ! dev->regions[i].is_IO ) {
if ( dev->regions[i].is_prefetchable ) {
printf( " PREFETCHABLE" );
}
}
printf( "\n" );
}
}
if ( dev->rom_size ) {
struct pci_device_private *priv =
(struct pci_device_private *) dev;
printf( " BASEROM 0x%08"PRIxPTR" SIZE %zu\n",
(intptr_t) priv->rom_base, (size_t) dev->rom_size);
}
pci_device_cfg_read_u8( dev, & int_pin, 61 );
pci_device_cfg_read_u8( dev, & min_grant, 62 );
pci_device_cfg_read_u8( dev, & max_latency, 63 );
printf( " MAX_LAT 0x%02x MIN_GNT 0x%02x INT_PIN 0x%02x INT_LINE 0x%02x\n",
max_latency,
min_grant,
int_pin,
dev->irq );
if ( (dev->device_class >> 16) == 0x06 ) {
const void * info;
if ( (info = pci_device_get_bridge_info(dev)) != NULL ) {
print_pci_bridge( (const struct pci_bridge_info *) info );
}
else if ( (info = pci_device_get_pcmcia_bridge_info(dev)) != NULL ) {
/* Nothing yet. */
}
}
}
}
int main( int argc, char ** argv )
{
struct pci_device_iterator * iter;
struct pci_device * dev;
int ret;
int verbose = 0;
int c;
int errors = 0;
while ((c = getopt(argc, argv, "v")) != -1) {
switch (c) {
case 'v':
verbose = 1;
break;
case '?':
errors++;
}
}
if (errors != 0) {
fprintf(stderr, "usage: %s [-v]\n", argv[0]);
exit(2);
}
ret = pci_system_init();
if (ret != 0)
err(1, "Couldn't initialize PCI system");
iter = pci_slot_match_iterator_create( NULL );
while ( (dev = pci_device_next( iter )) != NULL ) {
print_pci_device( dev, verbose );
}
pci_system_cleanup();
return 0;
}
libpciaccess-0.13.2/scanpci/Makefile.in 0000644 0143106 0000012 00000045064 12172612466 0020206 0 ustar 00alanc staff 0000266 0200005 # Makefile.in generated by automake 1.14 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2013 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
#
# (C) Copyright IBM Corporation 2006
# All Rights Reserved.
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# on the rights to use, copy, modify, merge, publish, distribute, sub
# license, and/or sell copies of the Software, and to permit persons to whom
# the Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice (including the next
# paragraph) shall be included in all copies or substantial portions of the
# Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
# IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
VPATH = @srcdir@
am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
*) echo "am__make_running_with_option: internal error: invalid" \
"target option '$${target_option-}' specified" >&2; \
exit 1;; \
esac; \
has_opt=no; \
sane_makeflags=$$MAKEFLAGS; \
if $(am__is_gnu_make); then \
sane_makeflags=$$MFLAGS; \
else \
case $$MAKEFLAGS in \
*\\[\ \ ]*) \
bs=\\; \
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
esac; \
fi; \
skip_next=no; \
strip_trailopt () \
{ \
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
}; \
for flg in $$sane_makeflags; do \
test $$skip_next = yes && { skip_next=no; continue; }; \
case $$flg in \
*=*|--*) continue;; \
-*I) strip_trailopt 'I'; skip_next=yes;; \
-*I?*) strip_trailopt 'I';; \
-*O) strip_trailopt 'O'; skip_next=yes;; \
-*O?*) strip_trailopt 'O';; \
-*l) strip_trailopt 'l'; skip_next=yes;; \
-*l?*) strip_trailopt 'l';; \
-[dEDm]) skip_next=yes;; \
-[JT]) skip_next=yes;; \
esac; \
case $$flg in \
*$$target_option*) has_opt=yes; break;; \
esac; \
done; \
test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
noinst_PROGRAMS = scanpci$(EXEEXT)
subdir = scanpci
DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
$(top_srcdir)/depcomp
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_define_dir.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
PROGRAMS = $(noinst_PROGRAMS)
am_scanpci_OBJECTS = scanpci.$(OBJEXT)
scanpci_OBJECTS = $(am_scanpci_OBJECTS)
scanpci_LDADD = $(LDADD)
scanpci_DEPENDENCIES = $(top_builddir)/src/libpciaccess.la
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
am__v_lt_0 = --silent
am__v_lt_1 =
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo " GEN " $@;
am__v_GEN_1 =
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 =
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CFLAGS) $(CFLAGS)
AM_V_CC = $(am__v_CC_@AM_V@)
am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
am__v_CC_0 = @echo " CC " $@;
am__v_CC_1 =
CCLD = $(CC)
LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
AM_V_CCLD = $(am__v_CCLD_@AM_V@)
am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
am__v_CCLD_0 = @echo " CCLD " $@;
am__v_CCLD_1 =
SOURCES = $(scanpci_SOURCES)
DIST_SOURCES = $(scanpci_SOURCES)
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
# Read a list of newline-separated strings from the standard input,
# and print each of them once, without duplicates. Input order is
# *not* preserved.
am__uniquify_input = $(AWK) '\
BEGIN { nonempty = 0; } \
{ items[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in items) print i; }; } \
'
# Make sure the list of sources is unique. This is necessary because,
# e.g., the same source file might be shared among _SOURCES variables
# for different programs/libraries.
am__define_uniq_tagged_files = \
list='$(am__tagged_files)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
ADMIN_MAN_DIR = @ADMIN_MAN_DIR@
ADMIN_MAN_SUFFIX = @ADMIN_MAN_SUFFIX@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
APP_MAN_DIR = @APP_MAN_DIR@
APP_MAN_SUFFIX = @APP_MAN_SUFFIX@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
BASE_CFLAGS = @BASE_CFLAGS@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CHANGELOG_CMD = @CHANGELOG_CMD@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CWARNFLAGS = @CWARNFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DRIVER_MAN_DIR = @DRIVER_MAN_DIR@
DRIVER_MAN_SUFFIX = @DRIVER_MAN_SUFFIX@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
FILE_MAN_DIR = @FILE_MAN_DIR@
FILE_MAN_SUFFIX = @FILE_MAN_SUFFIX@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_CMD = @INSTALL_CMD@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIB_MAN_DIR = @LIB_MAN_DIR@
LIB_MAN_SUFFIX = @LIB_MAN_SUFFIX@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MAN_SUBSTS = @MAN_SUBSTS@
MISC_MAN_DIR = @MISC_MAN_DIR@
MISC_MAN_SUFFIX = @MISC_MAN_SUFFIX@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PCIACCESS_CFLAGS = @PCIACCESS_CFLAGS@
PCIACCESS_LIBS = @PCIACCESS_LIBS@
PCIIDS_PATH = @PCIIDS_PATH@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRICT_CFLAGS = @STRICT_CFLAGS@
STRIP = @STRIP@
VERSION = @VERSION@
XORG_MAN_PAGE = @XORG_MAN_PAGE@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/src
LDADD = $(top_builddir)/src/libpciaccess.la
scanpci_SOURCES = scanpci.c
all: all-am
.SUFFIXES:
.SUFFIXES: .c .lo .o .obj
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign scanpci/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign scanpci/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
clean-noinstPROGRAMS:
@list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \
echo " rm -f" $$list; \
rm -f $$list || exit $$?; \
test -n "$(EXEEXT)" || exit 0; \
list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
echo " rm -f" $$list; \
rm -f $$list
scanpci$(EXEEXT): $(scanpci_OBJECTS) $(scanpci_DEPENDENCIES) $(EXTRA_scanpci_DEPENDENCIES)
@rm -f scanpci$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(scanpci_OBJECTS) $(scanpci_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scanpci.Po@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
.c.obj:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
.c.lo:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
ID: $(am__tagged_files)
$(am__define_uniq_tagged_files); mkid -fID $$unique
tags: tags-am
TAGS: tags
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
set x; \
here=`pwd`; \
$(am__define_uniq_tagged_files); \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: ctags-am
CTAGS: ctags
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
$(am__define_uniq_tagged_files); \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
cscopelist: cscopelist-am
cscopelist-am: $(am__tagged_files)
list='$(am__tagged_files)'; \
case "$(srcdir)" in \
[\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
*) sdir=$(subdir)/$(srcdir) ;; \
esac; \
for i in $$list; do \
if test -f "$$i"; then \
echo "$(subdir)/$$i"; \
else \
echo "$$sdir/$$i"; \
fi; \
done >> $(top_builddir)/cscope.files
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(PROGRAMS)
installdirs:
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
if test -z '$(STRIP)'; then \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
install; \
else \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \
mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am:
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am:
install-html: install-html-am
install-html-am:
install-info: install-info-am
install-info-am:
install-man:
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am:
.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
clean-libtool clean-noinstPROGRAMS cscopelist-am ctags \
ctags-am distclean distclean-compile distclean-generic \
distclean-libtool distclean-tags distdir dvi dvi-am html \
html-am info info-am install install-am install-data \
install-data-am install-dvi install-dvi-am install-exec \
install-exec-am install-html install-html-am install-info \
install-info-am install-man install-pdf install-pdf-am \
install-ps install-ps-am install-strip installcheck \
installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags tags-am uninstall uninstall-am
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
TRIP@
VERSION = @VERSION@
XORG_MAN_PAGE = @XORG_MAN_PAGE@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
buillibpciaccess-0.13.2/scanpci/Makefile.am 0000644 0143106 0000012 00000002440 12172612452 0020157 0 ustar 00alanc staff 0000266 0200005 #
# (C) Copyright IBM Corporation 2006
# All Rights Reserved.
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# on the rights to use, copy, modify, merge, publish, distribute, sub
# license, and/or sell copies of the Software, and to permit persons to whom
# the Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice (including the next
# paragraph) shall be included in all copies or substantial portions of the
# Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
# IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
noinst_PROGRAMS = scanpci
AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/src
LDADD = $(top_builddir)/src/libpciaccess.la
scanpci_SOURCES = scanpci.c
on
# on the rights to use, copy, modify, merge, publish, distribute, sub
# license, and/or sell copies of the Software, and to permit persons to whom
# the Software is furnished to do so, subject to the following conditions:libpciaccess-0.13.2/pciaccess.pc.in 0000644 0143106 0000012 00000000376 12172612452 0017377 0 ustar 00alanc staff 0000266 0200005 prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: pciaccess
Description: Library providing generic access to the PCI bus and devices.
Version: @PACKAGE_VERSION@
Cflags: -I${includedir}
Libs: -L${libdir} -lpciaccess
libpciaccess-0.13.2/ChangeLog 0000644 0143106 0000012 00000242757 12172612561 0016277 0 ustar 00alanc staff 0000266 0200005 commit aa7925c4a798b9ed2cd43bd3c99c2df2a1824311
Author: Alan Coopersmith
Date: Sat Jul 20 15:53:42 2013 -0700
libpciaccess 0.13.2
Signed-off-by: Alan Coopersmith
commit bdcb46d33c6514278d2209fd00ed58c580da5ff3
Author: John Martin
Date: Sat Jul 20 15:49:05 2013 -0700
Fix Sun bug #7035791: scanpci should report 64 bit registers
On a system which has allocated 64-bit device addresses scanpci -v
will show entries such as:
[...]
BASE0 0xce000000 SIZE 16777216 MEM
BASE1 0x00000fc1f8000000 SIZE 134217728 MEM64 PREFETCHABLE
BASE3 0x00000fc1f6000000 SIZE 33554432 MEM64 PREFETCHABLE
[...]
instead of:
[...]
BASE0 0xce000000 SIZE 16777216 MEM
BASE1 0xf8000000 SIZE 134217728 MEM PREFETCHABLE
BASE3 0xf6000000 SIZE 33554432 MEM PREFETCHABLE
[...]
Signed-off-by: Alan Coopersmith
commit f806b95d029d36c977befed4096734f6461efa08
Author: Alan Coopersmith
Date: Sat Jul 20 15:00:40 2013 -0700
Resync COPYING file with copyrights/licenses from code
Signed-off-by: Alan Coopersmith
commit 3bf035fcfd0ad55220f484f7fb5d5f18690bdb10
Author: Alan Coopersmith
Date: Sat Jul 6 10:09:31 2013 -0700
pci_device_solx_devfs_probe: implicit conversion changes signedness warnings
solx_devfs.c:615:32: warning: implicit conversion changes signedness:
'unsigned long' to 'int' [-Wsign-conversion]
for (i = 0; i < len; i = i + CELL_NUMS_1275) {
~ ~~^~~~~~~~~~~~~~~~
solx_devfs.c:615:30: warning: implicit conversion changes signedness:
'int' to 'unsigned long' [-Wsign-conversion]
for (i = 0; i < len; i = i + CELL_NUMS_1275) {
^ ~
Signed-off-by: Alan Coopersmith
commit 883acb4bf30735c7d8f3147341345fa9e3bc76b2
Author: Alan Coopersmith
Date: Sat Jul 6 10:00:44 2013 -0700
Solaris: Remove #defines for Ultra 45 southbridge device ids
Workaround for these chipsets was removed in commit d76fb36d9c28be0f7c
with the switch of probing methods from the PCI address poking that upset
them to using the already collected data from the kernel via devinfo,
but the #define to identify them was left behind unused - remove it too.
Signed-off-by: Alan Coopersmith
commit 3773eea8d4e22aaedf675051e5e96af53b925152
Author: Alan Coopersmith
Date: Sat Jul 6 09:56:46 2013 -0700
pci_device_solx_devfs_read: fix sign conversion/comparison warnings
Fixes:
solx_devfs.c:824:19: warning: comparison of integers of different signs: 'int' and 'pciaddr_t' (aka 'unsigned long') [-Wsign-compare]
for (i = 0; i < size; i += PCITOOL_ACC_ATTR_SIZE(PCITOOL_ACC_ATTR_SIZE_1))
~ ^ ~~~~
solx_devfs.c:826:28: warning: implicit conversion changes signedness: 'int' to 'unsigned long' [-Wsign-conversion]
cfg_prg.offset = offset + i;
~ ^
solx_devfs.c:844:19: warning: implicit conversion changes signedness: 'int' to 'pciaddr_t' (aka 'unsigned long') [-Wsign-conversion]
*bytes_read = i;
~ ^
Signed-off-by: Alan Coopersmith
commit 22f4b45056587f5700b87d09e9fe91bbb0eda4c5
Author: Thomas Klausner
Date: Sat Jun 29 20:49:54 2013 +0200
Support more pci functions on NetBSD.
Signed-off-by: Thomas Klausner
Signed-off-by: Alan Coopersmith
commit 9a13ecb8f1462efaf741fed293e29ba38757ff70
Author: Thomas Klausner
Date: Sat Jun 29 20:49:53 2013 +0200
Fix build on NetBSD-4.
Signed-off-by: Thomas Klausner
Reviewed-by: Matthieu Herrb
Signed-off-by: Alan Coopersmith
commit 1d364cb2f5b5cb1b18601735f42bada7a521be19
Author: Thomas Klausner
Date: Sat Jun 29 20:49:52 2013 +0200
Enable boot_vga support only if WSDISPLAYIO_GET_BUSID is defined.
Fixes build on NetBSD-5.
Signed-off-by: Thomas Klausner
Reviewed-by: Matthieu Herrb
Signed-off-by: Alan Coopersmith
commit 7f388e466bd7fbb7f9eba531e494e7efbd3a65dc
Author: Alan Coopersmith
Date: Mon Jun 24 21:20:27 2013 -0700
pci_id_file_open: move variable inside the #ifndef that uses it
Clears up gcc warning on Solaris:
common_device_name.c: In function 'pci_id_file_open':
common_device_name.c:83:17: warning: unused variable 'result' [-Wunused-variable]
Signed-off-by: Alan Coopersmith
commit a39f054649e773a4b33bf8f52152f7c5139bb90e
Author: Alan Coopersmith
Date: Mon Jun 24 21:09:52 2013 -0700
Define PCI_MATCH_ANY as an unsigned int
Clears a bunch of clang warnings of the forms:
common_device_name.c:345:23: warning: comparison of integers of different signs:
'const uint32_t' (aka 'const unsigned int') and 'int' [-Wsign-compare]
if ( m->vendor_id == PCI_MATCH_ANY ) {
~~~~~~~~~~~~ ^ ~~~~~~~~~~~~~
common_device_name.c:498:19: warning: implicit conversion changes signedness:
'int' to 'uint32_t' (aka 'unsigned int') [-Wsign-conversion]
m.device_id = PCI_MATCH_ANY;
~ ^~~~~~~~~~~~~
Signed-off-by: Alan Coopersmith
commit 5aff35d1ef659babd71f44f7963e4e908dcd86c4
Author: Thomas Klausner
Date: Tue Jun 11 11:46:26 2013 +0200
Update NetBSD support.
Signed-off-by: Michael Lorenz
Signed-off-by: Thomas Klausner
Reviewed-by: Matthieu Herrb
Signed-off-by: Alan Coopersmith
commit c10c86e5856596778cb8322aec8ce663b1f1bea5
Author: Thomas Klausner
Date: Tue Jun 11 11:45:50 2013 +0200
Move 'const' to correct place, so it has meaning.
Reviewed-by: Alan Coopersmith
Signed-off-by: Alan Coopersmith
commit 719888a9ec5ef5a45698dea8a9642091c433ff29
Author: Thomas Klausner
Date: Sun Jun 2 22:38:39 2013 +0200
Protect config.h like usual.
Signed-off-by: Alan Coopersmith
commit 434cd73d23cf5dc60d2047047378b59cadb0d5bb
Author: Alan Coopersmith
Date: Fri Jun 7 20:31:37 2013 -0700
Bug 63583 - add legacy IO routines for FreeBSD
https://bugs.freedesktop.org/show_bug.cgi?id=63583
Reviewed-by: Mark Kettenis
Signed-off-by: Jung-uk Kim
Signed-off-by: Alan Coopersmith
commit d76fb36d9c28be0f7c43e0ca1e961c30a7781bd4
Author: Henry Zhao
Date: Thu Jan 10 17:53:09 2013 -0800
Solaris: probe improvement
Remove pcitool dependency in probing phase. Use the data
collected from devinfo tree instead in creating pci file
system.
Signed-off-by: Henry Zhao
Signed-off-by: Alan Coopersmith
commit 3e17f069682a226c14bb29c802e776c6e39f7e8f
Author: Henry Zhao
Date: Tue Dec 18 15:10:46 2012 -0800
Solaris: Add domain support for sparc platform
As a result the code of finding nexus node for a device in sparc is
simplified and made the same as x86.
Signed-off-by: Henry Zhao
Signed-off-by: Alan Coopersmith
commit 897cad2620ffbd6ecbbaea2a67fb973ec7990198
Author: Colin Walters
Date: Wed Jan 4 17:37:06 2012 -0500
autogen.sh: Implement GNOME Build API
http://people.gnome.org/~walters/docs/build-api.txt
Signed-off-by: Adam Jackson
commit d69019c5b744348d6e5032ef87f4a743f68cb112
Author: Adam Jackson
Date: Tue Jan 15 14:28:48 2013 -0500
configure: Remove AM_MAINTAINER_MODE
Signed-off-by: Adam Jackson
commit 0ad7b5c548ecf409a1fdd835bde52a8cf5371b7a
Author: Egbert Eich
Date: Mon Jul 4 07:38:33 2011 +0200
PCI: set correct mask value when matching for bridges.
The mask must not be zero otherwise the matching condition will never
be true: ((val & mask) == set).
Signed-off-by: Egbert Eich
Reviewed-by: Guillem Jover
commit 72e0c0b4d4680b7a7b4b42be525d406635dae40f
Author: Henry Zhao
Date: Fri Apr 6 17:26:59 2012 -0700
scanpci: print meaningful info on BASEROM
Signed-off-by: Henry Zhao
Signed-off-by: Alan Coopersmith
commit ba53031899611a1653656034a1a3de9b71e5bc85
Author: Henry Zhao
Date: Fri Apr 6 16:52:42 2012 -0700
libpciaccess: sparc rom read fix
Get rom address and size from device's "assigned-addresses" property
if they exist.
Signed-off-by: Henry Zhao
Signed-off-by: Alan Coopersmith
commit 2edddd4c4eb4258f4347c40e76bf0d5f1bcf51a7
Author: Henry Zhao
Date: Fri Oct 5 12:41:36 2012 -0700
libpciaccess: implementation of boot_vga in Solaris
Signed-off-by: Henry Zhao
Signed-off-by: Alan Coopersmith
commit 630b00a0847df9acf53391e6415bdfcd13fdae68
Author: Mark Logan
Date: Tue Sep 18 13:28:18 2012 -0700
libpciaccess: fix memory usage errors
This patch fixes memory usage errors that only occur on large SPARC
machines with more than 256 PCI devices. In this case, memory is being
used after it has been freed by calls to both free() and realloc().
This error was introduced by a previous patch:
2011-03-30 Solaris support for multiple PCI segments (domains)
Signed-off-by: Mark Logan
Signed-off-by: Alan Coopersmith
commit 09f5b48f559888339450bb4a79d178c94da34638
Author: Samuel Thibault
Date: Thu May 31 20:00:34 2012 +0200
Implement legacy io & map for x86 backend
Add the legacy io and map methods for the x86 backend, using ioperm,
in/out, and the existing mmap method.
Signed-off-by: Samuel Thibault
commit 9f2d95e61896f41adb8087fb805eb37899cce55f
Author: Alan Coopersmith
Date: Wed Apr 18 22:17:54 2012 -0700
Solaris: refactor pci_device_solx_devfs_map_range to reduce code duplication
The sparc & x86 cases were doing essentially the same things with
different paths, so make the path setup be inside the platform
specific #ifdefs, make the open, mmap, & error handling common code.
Signed-off-by: Alan Coopersmith
commit d50292ca8cbbaa5e0c92627f3d7813194c7c83ac
Author: Alan Coopersmith
Date: Wed Apr 18 15:30:30 2012 -0700
Solaris: Implement map_legacy & legacy_io functions
Signed-off-by: Alan Coopersmith
Reviewed-by: Jay Cotton
commit 2ff2996dcb4cfd83da6df4504b68b492b983204b
Author: Julien Cristau
Date: Mon Apr 9 19:05:27 2012 +0200
Bump to 0.13.1
Signed-off-by: Julien Cristau
commit 6f9d9f1e1b093939bc459be606fba72f1d6dfc76
Author: Matthieu Herrb
Date: Mon Apr 2 08:22:23 2012 +0200
Fix pci_io_handle allocation routines.
The previous version of new_io_handle() would invalidate all previous
allocations when realloc moves the base pointer of the ios array.
Since I cannot figure out where this array is useful, just get rid of
it, providing sound stable memory allocation.
Fixes vgaHWSaveFonts() in 1.12 xserver on OpenBSD, but other
sub-systems relaying on pci_io could be affected too.
Signed-off-by: Matthieu Herrb
Tested-by: Tormod Volden
commit 725f5669bc03ed9a766e2c51c465e082172e6dae
Author: Thordur Bjornsson
Date: Wed Mar 14 14:45:52 2012 +0100
Fix openbsd_pci.c:pci_device_vgaarb_set_target();
A return (0) got lost, add it back.
Signed-off-by: Matthieu Herrb
Reviewed-by: Mark Kettenis
commit b16336c0b389ace07f7418f5a021bfbc68fec2b6
Author: Adam Jackson
Date: Mon Mar 5 11:01:01 2012 -0500
linux: Fix out[bwl] macros on non-I/O architectures
Signed-off-by: Adam Jackson
commit fa15fbcdbcfed09ea269ca3fb5f0e3dc2446e66f
Merge: d2dc9f9 bf70556
Author: Adam Jackson
Date: Mon Mar 5 11:00:14 2012 -0500
Merge branch 'master' of ssh://git.freedesktop.org/git/xorg/lib/libpciaccess
commit bf705561d347bc5459bc0af033595c66541cac3e
Author: Jeremy Huddleston
Date: Sat Mar 3 18:19:11 2012 -0800
configure.ac: Bump to 0.13
Signed-off-by: Jeremy Huddleston
commit d2dc9f9daa45504f035b169aba94d0b154fd29f0
Author: Adam Jackson
Date: Mon Feb 27 11:19:50 2012 -0500
Use O_CLOEXEC for internal file descriptors
Well, almost all of them. zlib doesn't support "e" in the mode string
in gzopen() though it will silently accept and ignore it, and Solaris appears
not to support "e" in the mode string at all.
Signed-off-by: Adam Jackson
commit f550c1347d3518874fe1c1d417a57322ee6b52db
Author: Adam Jackson
Date: Mon Feb 27 10:43:20 2012 -0500
linux: Don't use /dev/port
Reviewed-by: Jeremy Huddleston
Signed-off-by: Adam Jackson
commit 2a58cd13c3d14cd2ea57826b56e9906ecfc5648a
Author: Mathias Krause
Date: Fri Feb 24 09:39:31 2012 +0100
Use correct type for pci_id file accessor functions
This fixes the compiler warning of using the wrong type for gzgets() and
gzclose() as they want a gzFile argument, not a pointer to gzFile. The
abstraction layer pci_id_file should just abstract the full type.
Signed-off-by: Mathias Krause
Reviewed-by: Jeremy Huddleston
commit 167ffb1c4e431763e30c894131e704bb3599c7c1
Author: Alan Coopersmith
Date: Wed Feb 8 22:14:08 2012 -0800
solx_devfs.c: fix gcc warnings about casting away const when reading data
solx_devfs.c: In function `pci_device_solx_devfs_write':
solx_devfs.c:1085: warning: cast discards qualifiers from pointer target type
solx_devfs.c:1089: warning: cast discards qualifiers from pointer target type
solx_devfs.c:1093: warning: cast discards qualifiers from pointer target type
solx_devfs.c:1097: warning: cast discards qualifiers from pointer target type
Signed-off-by: Alan Coopersmith