Solaris Source Insight: PCI bus driver moduls
<!--@page { margin: 0.79in }P { margin-bottom: 0.08in }-->This time we will look into pci_pcidriver module. It's PCI to PCI bus bridge nexus driver. As usual, wecan find the source files which implement this module. I tried totype Chinese in OpenOffice, but the font looks so ugly.
find . -nameMakefile\* | xargs grep PCI_PCINEXUS_OBJS
./intel/Makefile.files:PCI_PCINEXUS_OBJS+= pci_pci.o
./intel/pci_pci/Makefile:OBJECTS=$(PCI_PCINEXUS_OBJS:%=$(OBJS_DIR)/%)
./intel/pci_pci/Makefile:LINTS=$(PCI_PCINEXUS_OBJS:%.o=$(LINTS_DIR)/%.ln)
find . -namepci_pci.c
./sun4u/io/pci/pci_pci.c
./intel/io/pci/pci_pci.c
As usual, if no further notification,all source code is from intel/io/pci/pci_pci.c. Module linkageinformation:
175 /*
176* Module linkage information forthe kernel.
177*/
178
179 static struct modldrv modldrv = {
180 |_______&mod_driverops, /*Type of module */
181 |_______"Standard PCI to PCIbridge nexus driver",
182 |_______&ppb_ops,|______/*driver ops */
183 };
184
185 static struct modlinkagemodlinkage = {
186 |_______MODREV_1,
187 |_______(void *)&modldrv,
188 |_______NULL
189 };
Soft state structure is created in_init() and will be allocated attach(). The state structure isdefined as below.
191 /*
192* soft state pointer andstructure template:
193*/
194 static void *ppb_state;
195
196 typedef struct {
197 |_______dev_info_t *dip;
198 |_______int ppb_fmcap;
199 |_______ddi_iblock_cookie_tppb_fm_ibc;
200 |_______kmutex_t ppb_mutex;
201 |_______kmutex_tppb_peek_poke_mutex;
202 |_______kmutex_t ppb_err_mutex;
203
204 |_______/*
205 |_______ * cpr support:
206 |_______ */
207 |_______uint_tconfig_state_index;
208 |_______struct {
209 |_______|_______dev_info_t *dip;
210 |_______|_______ushort_t command;
211 |_______|_______uchar_tcache_line_size;
212 |_______|_______uchar_tlatency_timer;
213 |_______|_______uchar_theader_type;
214 |_______|_______uchar_tsec_latency_timer;
215 |_______|_______ushort_tbridge_control;
216 |_______}config_state;
217
218 |_______uint16_t parent_bus;
219 } ppb_devstate_t;
attach() interface first and ignore theDDI_RESUME command.
[*]Set property of "device_type"to "pci".
[*]Allocate and get soft statestructure.
[*]FM setup, don't enable ereports ifimmediate child of npe.
[*]Initialize the mutex locks in softstate structure.
[*]Check all the ancestor of thebridge, if there is a PCIe device, set parent_bus of soft state toPCIE_PCIECAP_DEV_TYPE_PCIE_DEV; otherwise, it is set toPCIE_PCIECAP_DEV_TYPE_PCI_PSEUDO.
[*]Initialize hotplug support on thisbus. If itś a PCI-E Endpont Device, pcie_init() is called;otherwise, pcihp_init() is called.
[*]Report the bridge device.
Question: What is the differnce between“PCI-E to PCI bus bridge” and “PCI to PCI bus bridge”? Whybus_parent set toPCIE_PCIECAP_DEV_TYPE_PCIE_DEV when the ancestorof a PCI_PCI bridge is PCI-E device?
Answer: withbus_parent set to PCIE_PCIECAP_DEV_TYPE_PCIE_DEV, the platform is a PCI-E platform;otherwise, it is a lagecy PCI platform.
http://p.blog.csdn.net/images/p_blog_csdn_net/hotsolaris/EntryImages/20091118/Tylersburg_IOH.gif
Picture 1 Tylersburg IOHblock diagram
Dirver Operations:
[*]ppb_open()
[*]ppb_close()
[*]ppb_ioctl()
[*]ppb_prop_op()
Call pcieframework interface if it is a PCIe platform; otherwise, callinterfaces in misc/pcihp. All hotplug, power management, faultmanagement interfaces of a PCI-e device are exported via misc/pcie,which is called PCI Express framework. For a legacy PCI platform,hotplug is supported by misc/pcihp.
972 |_______/*
973 |_______ *Ioctls will be handled by PCI Express framework for all
974 |_______ *PCIe platforms
975 |_______ */
976 |_______if(ppb_p->parent_bus == PCIE_PCIECAP_DEV_TYPE_PCIE_DEV)
977|_______|_______return (pcie_ioctl(ppb_p->dip, dev, cmd, arg,mode, credp,
978|_______|_______ rvalp));
979
980|_______return ((pcihp_get_cb_ops())->cb_ioctl(dev, cmd, arg,mode, credp,
981 |_______ rvalp));
Bus Operation:
[*]ppb_bus_map()
Escalate thisrequest to parent.
[*]ppb_ctlops()
ppb_initchild()/ppb_removechild()are used to initialize a child node under this pci-pci bridge. Itfirst merges the pseudo .conf node property. This kind of pseudonodes are created in init_node() when DDI implementation tries to putthe devinfo node at DS_INITIALIZED state. Initialize the PCI-eprivate data if this bridge is on a PCIE platform. PCIe Bus PrivateData contains commonly used PCI/PCIe information and offsets to keyregisters. Create parent private data and the interrupt vectore dataif the node contains “interrupt” property. The last step ofinitchild() is the support for the "command-preserve"property. ppb_removechild() will be called in init_node() ifinitchild() returns error.
Device suspend andresume support is implemented via DDI_CTLOPS_ATTACH/DDI_CTLOPS_DETACHbus ctl operations.
Device configurespace peek/poke is supported via DDI_CTLOPS_PEEK/DDI_CTLOPS_POKE busctl operations.
[*]ppb_fm_init()
[*]ppb_intr_ops()
This function isdefined to intercept certain interrupt services to handle specialcases, such as check for hypertransport msi mapping capability.
页:
[1]