Solaris Source Insight: PCI bus driver moduls - pci_pci driver module

<!-- @page { margin: 0.79in } P { margin-bottom: 0.08in } -->

This time we will look into pci_pci driver module. It's PCI to PCI bus bridge nexus driver. As usual, we can find the source files which implement this module. I tried to type Chinese in OpenOffice, but the font looks so ugly.

 

[allen@blu-xvm-osol:uts]find . -name Makefile/* | 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)

[allen@blu-xvm-osol:uts]find . -name pci_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 linkage information:

 

175 /*

176 * Module linkage information for the kernel.

177 */

178

179 static struct modldrv modldrv = {

180 |_______&mod_driverops, /* Type of module */

181 |_______"Standard PCI to PCI bridge nexus driver",

182 |_______&ppb_ops,|______/* driver ops */

183 };

184

185 static struct modlinkage modlinkage = {

186 |_______MODREV_1,

187 |_______(void *)&modldrv,

188 |_______NULL

189 };

 

Soft state structure is created in _init() and will be allocated attach(). The state structure is defined as below.

 

191 /*

192 * soft state pointer and structure template:

193 */

194 static void *ppb_state;

195

196 typedef struct {

197 |_______dev_info_t *dip;

198 |_______int ppb_fmcap;

199 |_______ddi_iblock_cookie_t ppb_fm_ibc;

200 |_______kmutex_t ppb_mutex;

201 |_______kmutex_t ppb_peek_poke_mutex;

202 |_______kmutex_t ppb_err_mutex;

203

204 |_______/*

205 |_______ * cpr support:

206 |_______ */

207 |_______uint_t config_state_index;

208 |_______struct {

209 |_______|_______dev_info_t *dip;

210 |_______|_______ushort_t command;

211 |_______|_______uchar_t cache_line_size;

212 |_______|_______uchar_t latency_timer;

213 |_______|_______uchar_t header_type;

214 |_______|_______uchar_t sec_latency_timer;

215 |_______|_______ushort_t bridge_control;

216 |_______} config_state[PCI_MAX_CHILDREN];

217

218 |_______uint16_t parent_bus;

219 } ppb_devstate_t;

 

attach() interface first and ignore the DDI_RESUME command.

  1. Set property of "device_type" to "pci".

  2. Allocate and get soft state structure.

  3. FM setup, don't enable ereports if immediate child of npe.

  4. Initialize the mutex locks in soft state structure.

  5. Check all the ancestor of the bridge, if there is a PCIe device, set parent_bus of soft state to PCIE_PCIECAP_DEV_TYPE_PCIE_DEV; otherwise, it is set to PCIE_PCIECAP_DEV_TYPE_PCI_PSEUDO.

  6. Initialize hotplug support on this bus. If itś a PCI-E Endpont Device, pcie_init() is called; otherwise, pcihp_init() is called.

  7. Report the bridge device.

Question: What is the differnce between “PCI-E to PCI bus bridge” and “PCI to PCI bus bridge”? Why bus_parent set to PCIE_PCIECAP_DEV_TYPE_PCIE_DEV when the ancestor of a PCI_PCI bridge is PCI-E device?

 

Answer: with bus_parent set to PCIE_PCIECAP_DEV_TYPE_PCIE_DEV, the platform is a PCI-E platform; otherwise, it is a lagecy PCI platform.

 

 

Picture 1 Tylersburg IOH block diagram

 

 

Dirver Operations:

  • ppb_open()

  • ppb_close()

  • ppb_ioctl()

  • ppb_prop_op()

Call pcie framework interface if it is a PCIe platform; otherwise, call interfaces in misc/pcihp. All hotplug, power management, fault management 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 this request to parent.

  • ppb_ctlops()

ppb_initchild()/ppb_removechild() are used to initialize a child node under this pci-pci bridge. It first merges the pseudo .conf node property. This kind of pseudo nodes are created in init_node() when DDI implementation tries to put the devinfo node at DS_INITIALIZED state. Initialize the PCI-e private data if this bridge is on a PCIE platform. PCIe Bus Private Data contains commonly used PCI/PCIe information and offsets to key registers. Create parent private data and the interrupt vectore data if the node contains “interrupt” property. The last step of initchild() is the support for the "command-preserve" property. ppb_removechild() will be called in init_node() if initchild() returns error.

Device suspend and resume support is implemented via DDI_CTLOPS_ATTACH/DDI_CTLOPS_DETACH bus ctl operations.

Device configure space peek/poke is supported via DDI_CTLOPS_PEEK/DDI_CTLOPS_POKE bus ctl operations.

  • ppb_fm_init()

  • ppb_intr_ops()

This function is defined to intercept certain interrupt services to handle special cases, such as check for hypertransport msi mapping capability.

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值