Solaris Source Insight: PCI bus driver moduls - npe Part 3

Wed Nov 11 13:41:56 CST 2009

driver operation

Driver operation is defined for leaf device drivers or bus nexus drivers supporting direct user process access (open/close/etc). Driver operation for npe module is very simple.

[i86pc/io/pciex/npe.c]

120 struct cb_ops npe_cb_ops = {

121 |_______npe_open,|______|_______|_______/* open */

122 |_______npe_close,|_____|_______|_______/* close */

123 |_______nodev,|_|_______|_______|_______/* strategy */

124 |_______nodev,|_|_______|_______|_______/* print */

125 |_______nodev,|_|_______|_______|_______/* dump */

126 |_______nodev,|_|_______|_______|_______/* read */

127 |_______nodev,|_|_______|_______|_______/* write */

128 |_______npe_ioctl,|_____|_______|_______/* ioctl */

129 |_______nodev,|_|_______|_______|_______/* devmap */

130 |_______nodev,|_|_______|_______|_______/* mmap */

131 |_______nodev,|_|_______|_______|_______/* segmap */

132 |_______nochpoll,|______|_______|_______/* poll */

133 |_______pcie_prop_op,|__|_______|_______/* cb_prop_op */

134 |_______NULL,|__|_______|_______|_______/* streamtab */

135 |_______D_NEW | D_MP | D_HOTPLUG,|______/* Driver compatibility flag */

136 |_______CB_REV,||_______|_______|_______/* rev */

137 |_______nodev,|_|_______|_______|_______/* int (*cb_aread)() */

138 |_______nodev|__|_______|_______|_______/* int (*cb_awrite)() */

139 };

It defines a character driver interface. User level applications can open/close the corresponding device file and issue some ioctl command again it. In npe's open() and close() functions, locks and state machine are used to serialize the controls. Two types of ioctl controls are supported by now, one is for pci tool, which is a common interface for user level applications to read/write pci configure spaces, bind the interrupt and so on (we will come back to the implementation later); another is for common device control, which is routed to pcie_ioclt() for further action.

Bus operations

Npe is a nexus bus driver module, so the its sole is the bus operations.

[i86pc/io/pciex/npe.c]

83 struct bus_ops npe_bus_ops = {

84 |_______BUSO_REV,

85 |_______npe_bus_map,

86 |_______NULL,

87 |_______NULL,

88 |_______NULL,

89 |_______i_ddi_map_fault,

90 |_______ddi_dma_map,

91 |_______ddi_dma_allochdl,

92 |_______ddi_dma_freehdl,

93 |_______ddi_dma_bindhdl,

94 |_______ddi_dma_unbindhdl,

95 |_______ddi_dma_flush,

96 |_______ddi_dma_win,

97 |_______ddi_dma_mctl,

98 |_______npe_ctlops,

99 |_______ddi_bus_prop_op,

100 |_______0,|_____|_______|_______/* (*bus_get_eventcookie)();|___*/

101 |_______0,|_____|_______|_______/* (*bus_add_eventcall)();|_____*/

102 |_______0,|_____|_______|_______/* (*bus_remove_eventcall)();|__*/

103 |_______0,|_____|_______|_______/* (*bus_post_event)();||_______*/

104 |_______0,|_____|_______|_______/* (*bus_intr_ctl)(); */

105 |_______0,|_____|_______|_______/* (*bus_config)(); */

106 |_______0,|_____|_______|_______/* (*bus_unconfig)(); */

107 |_______npe_fm_init,|___|_______/* (*bus_fm_init)(); */

108 |_______NULL,|__|_______|_______/* (*bus_fm_fini)(); */

109 |_______NULL,|__|_______|_______/* (*bus_fm_access_enter)(); */

110 |_______NULL,|__|_______|_______/* (*bus_fm_access_exit)(); */

111 |_______NULL,|__|_______|_______/* (*bus_power)(); */

112 |_______npe_intr_ops,|__|_______/* (*bus_intr_op)(); */

113 |_______pcie_hp_common_ops|_____/* (*bus_hp_op)(); */

114 };

The definition of “struct bus_ops” is in common/sys/devops.h. Not all entries are valid for a specific bus operation version. The comments along with the structure definition is enough for understanding.

[common/sys/devops.h]

118 /*

119 * bus_ops:|____bus nexus drivers only.

120 *

121 * These functions are used to implement the Sun DDI functions

122 * described elsewhere.

123 *

124 * Only nexus drivers support these entry points.

125 *

126 * The following bus nexus functions are provided in the bus nexus

127 * driver operations structure. Note that all functions take both

128 * their dip and the requesters dip except for the child functions since

129 * they will be called from outside the ddi.

130 *

131 *|_____bus_map||_______|_______- Map/unmap/control IU -> device mappings.

132 *|_____bus_get_intrspec|_______- get interrupt specification by number

133 *|_____bus_add_intrspec|_______- add interrupt specification, return cookie

134 *|_____bus_remove_intrspec|____- remove interrupt specification

135 *|_____bus_map_fault|__|_______- bus fault handler

136 *|_____bus_dma_map|____|_______- setup dma mapping

137 *|_____bus_dma_mapctl|_|_______- control (and free) dma mapping

138 *|_____bus_ctl||_______|_______- generic control operations

139 *|_____bus_prop_op|____|________ request for property

140 */

  • bus_map()

We have looked at npe_bus_map() when we tried to find the answer for how PCI leaf drviers access the configure space. The address spaces for a device were encoded in “reg” and “assigned-addresses” properties. Below comments describe the decoding logic.

[common/sys/pci.h]

1100 /*

1101 * This structure represents one entry of the 1275 "reg" property and

1102 * "assigned-addresses" property for a PCI node. For the "reg" property, it

1103 * may be one of an arbitrary length array for devices with multiple address

1104 * windows. For the "assigned-addresses" property, it denotes an assigned

1105 * physical address on the PCI bus. It may be one entry of the six entries

1106 * for devices with multiple base registers.

1107 *

1108 * The physical address format is:

1109 *

1110 * Bit#: 33222222 22221111 11111100 00000000

1111 * 10987654 32109876 54321098 76543210

1112 *

1113 * pci_phys_hi cell: npt000ss bbbbbbbb dddddfff rrrrrrrr

1114 * pci_phys_mid cell: hhhhhhhh hhhhhhhh hhhhhhhh hhhhhhhh

1115 * pci_phys_low cell: llllllll llllllll llllllll llllllll

1116 *

1117 * n is 0 if the address is relocatable, 1 otherwise

1118 * p is 1 if the addressable region is "prefetchable", 0 otherwise

1119 * t is 1 if the address is aliased (for non-relocatable I/O), below

1120 *|_____ 1MB (for mem), or below 64 KB (for relocatable I/O).

1121 * ss is the type code, denoting which address space

1122 * bbbbbbbb is the 8-bit bus number

1123 * ddddd is the 5-bit device number

1124 * fff is the 3-bit function number

1125 * rrrrrrrr is the 8-bit register number

1126 *|_____ should be zero for non-relocatable, when ss is 01, or 10

1127 * hh...hhh is the 32-bit unsigned number

1128 * ll...lll is the 32-bit unsigned number

1129 *

1130 * The physical size format is:

1131 *

1132 * pci_size_hi cell: hhhhhhhh hhhhhhhh hhhhhhhh hhhhhhhh

1133 * pci_size_low cell: llllllll llllllll llllllll llllllll

1134 *

1135 * hh...hhh is the 32-bit unsigned number

1136 * ll...lll is the 32-bit unsigned number

1137 */

1138 struct pci_phys_spec {

1139 |_______uint_t pci_phys_hi;|____|_______/* child's address, hi word */

1140 |_______uint_t pci_phys_mid;|___|_______/* child's address, middle word */

1141 |_______uint_t pci_phys_low;|___|_______/* child's address, low word */

1142 |_______uint_t pci_size_hi;|____|_______/* high word of size field */

1143 |_______uint_t pci_size_low;|___|_______/* low word of size field */

1144 };

1145

1146 typedef struct pci_phys_spec pci_regspec_t;

The actual map operation is passed to npe's parent (rootnex). However, pci system has different “reg” and “assigned-addresses” encoding logic. Hence, in this bus map function, most part is to convert the data from “pci_regspec_t” to “struct regspec” according to the map type and the encoding logic.

  • bus_ctl()

To be continued …

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值