Commit c827ba4cb49a30ce581201fd0ba2be77cde412c7
Exists in
master
and in
7 other branches
Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6: [SPARC64]: Update defconfig. [SPARC64]: Add PCI MSI support on Niagara. [SPARC64] IRQ: Use irq_desc->chip_data instead of irq_desc->handler_data [SPARC64]: Add obppath sysfs attribute for SBUS and PCI devices. [PARTITION]: Add whole_disk attribute.
Showing 17 changed files Inline Diff
- arch/sparc64/defconfig
- arch/sparc64/kernel/irq.c
- arch/sparc64/kernel/pci.c
- arch/sparc64/kernel/pci_common.c
- arch/sparc64/kernel/pci_sun4v.c
- arch/sparc64/kernel/pci_sun4v.h
- arch/sparc64/kernel/pci_sun4v_asm.S
- block/ioctl.c
- drivers/pci/Kconfig
- drivers/sbus/sbus.c
- fs/partitions/check.c
- fs/partitions/msdos.c
- fs/partitions/sgi.c
- fs/partitions/sun.c
- include/asm-sparc64/irq.h
- include/asm-sparc64/pbm.h
- include/linux/genhd.h
arch/sparc64/defconfig
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.20-rc2 | 3 | # Linux kernel version: 2.6.20 |
4 | # Thu Dec 28 15:09:49 2006 | 4 | # Sat Feb 10 23:08:12 2007 |
5 | # | 5 | # |
6 | CONFIG_SPARC=y | 6 | CONFIG_SPARC=y |
7 | CONFIG_SPARC64=y | 7 | CONFIG_SPARC64=y |
8 | CONFIG_64BIT=y | 8 | CONFIG_64BIT=y |
9 | CONFIG_MMU=y | 9 | CONFIG_MMU=y |
10 | CONFIG_STACKTRACE_SUPPORT=y | 10 | CONFIG_STACKTRACE_SUPPORT=y |
11 | CONFIG_LOCKDEP_SUPPORT=y | 11 | CONFIG_LOCKDEP_SUPPORT=y |
12 | CONFIG_TIME_INTERPOLATION=y | 12 | CONFIG_TIME_INTERPOLATION=y |
13 | CONFIG_ARCH_MAY_HAVE_PC_FDC=y | 13 | CONFIG_ARCH_MAY_HAVE_PC_FDC=y |
14 | # CONFIG_ARCH_HAS_ILOG2_U32 is not set | 14 | # CONFIG_ARCH_HAS_ILOG2_U32 is not set |
15 | # CONFIG_ARCH_HAS_ILOG2_U64 is not set | 15 | # CONFIG_ARCH_HAS_ILOG2_U64 is not set |
16 | CONFIG_AUDIT_ARCH=y | 16 | CONFIG_AUDIT_ARCH=y |
17 | CONFIG_SPARC64_PAGE_SIZE_8KB=y | 17 | CONFIG_SPARC64_PAGE_SIZE_8KB=y |
18 | # CONFIG_SPARC64_PAGE_SIZE_64KB is not set | 18 | # CONFIG_SPARC64_PAGE_SIZE_64KB is not set |
19 | # CONFIG_SPARC64_PAGE_SIZE_512KB is not set | 19 | # CONFIG_SPARC64_PAGE_SIZE_512KB is not set |
20 | # CONFIG_SPARC64_PAGE_SIZE_4MB is not set | 20 | # CONFIG_SPARC64_PAGE_SIZE_4MB is not set |
21 | CONFIG_SECCOMP=y | 21 | CONFIG_SECCOMP=y |
22 | CONFIG_HZ_100=y | 22 | CONFIG_HZ_100=y |
23 | # CONFIG_HZ_250 is not set | 23 | # CONFIG_HZ_250 is not set |
24 | # CONFIG_HZ_300 is not set | 24 | # CONFIG_HZ_300 is not set |
25 | # CONFIG_HZ_1000 is not set | 25 | # CONFIG_HZ_1000 is not set |
26 | CONFIG_HZ=100 | 26 | CONFIG_HZ=100 |
27 | CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" | 27 | CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" |
28 | 28 | ||
29 | # | 29 | # |
30 | # Code maturity level options | 30 | # Code maturity level options |
31 | # | 31 | # |
32 | CONFIG_EXPERIMENTAL=y | 32 | CONFIG_EXPERIMENTAL=y |
33 | CONFIG_BROKEN_ON_SMP=y | 33 | CONFIG_BROKEN_ON_SMP=y |
34 | CONFIG_INIT_ENV_ARG_LIMIT=32 | 34 | CONFIG_INIT_ENV_ARG_LIMIT=32 |
35 | 35 | ||
36 | # | 36 | # |
37 | # General setup | 37 | # General setup |
38 | # | 38 | # |
39 | CONFIG_LOCALVERSION="" | 39 | CONFIG_LOCALVERSION="" |
40 | # CONFIG_LOCALVERSION_AUTO is not set | 40 | # CONFIG_LOCALVERSION_AUTO is not set |
41 | CONFIG_SWAP=y | 41 | CONFIG_SWAP=y |
42 | CONFIG_SYSVIPC=y | 42 | CONFIG_SYSVIPC=y |
43 | # CONFIG_IPC_NS is not set | 43 | # CONFIG_IPC_NS is not set |
44 | CONFIG_POSIX_MQUEUE=y | 44 | CONFIG_POSIX_MQUEUE=y |
45 | # CONFIG_BSD_PROCESS_ACCT is not set | 45 | # CONFIG_BSD_PROCESS_ACCT is not set |
46 | # CONFIG_TASKSTATS is not set | 46 | # CONFIG_TASKSTATS is not set |
47 | # CONFIG_UTS_NS is not set | 47 | # CONFIG_UTS_NS is not set |
48 | # CONFIG_AUDIT is not set | 48 | # CONFIG_AUDIT is not set |
49 | # CONFIG_IKCONFIG is not set | 49 | # CONFIG_IKCONFIG is not set |
50 | CONFIG_SYSFS_DEPRECATED=y | 50 | CONFIG_SYSFS_DEPRECATED=y |
51 | CONFIG_RELAY=y | 51 | CONFIG_RELAY=y |
52 | CONFIG_INITRAMFS_SOURCE="" | 52 | CONFIG_INITRAMFS_SOURCE="" |
53 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y | 53 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y |
54 | CONFIG_SYSCTL=y | 54 | CONFIG_SYSCTL=y |
55 | # CONFIG_EMBEDDED is not set | 55 | # CONFIG_EMBEDDED is not set |
56 | CONFIG_UID16=y | 56 | CONFIG_UID16=y |
57 | CONFIG_SYSCTL_SYSCALL=y | 57 | CONFIG_SYSCTL_SYSCALL=y |
58 | CONFIG_KALLSYMS=y | 58 | CONFIG_KALLSYMS=y |
59 | # CONFIG_KALLSYMS_ALL is not set | 59 | # CONFIG_KALLSYMS_ALL is not set |
60 | # CONFIG_KALLSYMS_EXTRA_PASS is not set | 60 | # CONFIG_KALLSYMS_EXTRA_PASS is not set |
61 | CONFIG_HOTPLUG=y | 61 | CONFIG_HOTPLUG=y |
62 | CONFIG_PRINTK=y | 62 | CONFIG_PRINTK=y |
63 | CONFIG_BUG=y | 63 | CONFIG_BUG=y |
64 | CONFIG_ELF_CORE=y | 64 | CONFIG_ELF_CORE=y |
65 | CONFIG_BASE_FULL=y | 65 | CONFIG_BASE_FULL=y |
66 | CONFIG_FUTEX=y | 66 | CONFIG_FUTEX=y |
67 | CONFIG_EPOLL=y | 67 | CONFIG_EPOLL=y |
68 | CONFIG_SHMEM=y | 68 | CONFIG_SHMEM=y |
69 | CONFIG_SLAB=y | 69 | CONFIG_SLAB=y |
70 | CONFIG_VM_EVENT_COUNTERS=y | 70 | CONFIG_VM_EVENT_COUNTERS=y |
71 | CONFIG_RT_MUTEXES=y | 71 | CONFIG_RT_MUTEXES=y |
72 | # CONFIG_TINY_SHMEM is not set | 72 | # CONFIG_TINY_SHMEM is not set |
73 | CONFIG_BASE_SMALL=0 | 73 | CONFIG_BASE_SMALL=0 |
74 | # CONFIG_SLOB is not set | 74 | # CONFIG_SLOB is not set |
75 | 75 | ||
76 | # | 76 | # |
77 | # Loadable module support | 77 | # Loadable module support |
78 | # | 78 | # |
79 | CONFIG_MODULES=y | 79 | CONFIG_MODULES=y |
80 | CONFIG_MODULE_UNLOAD=y | 80 | CONFIG_MODULE_UNLOAD=y |
81 | CONFIG_MODULE_FORCE_UNLOAD=y | 81 | CONFIG_MODULE_FORCE_UNLOAD=y |
82 | CONFIG_MODVERSIONS=y | 82 | CONFIG_MODVERSIONS=y |
83 | CONFIG_MODULE_SRCVERSION_ALL=y | 83 | CONFIG_MODULE_SRCVERSION_ALL=y |
84 | CONFIG_KMOD=y | 84 | CONFIG_KMOD=y |
85 | 85 | ||
86 | # | 86 | # |
87 | # Block layer | 87 | # Block layer |
88 | # | 88 | # |
89 | CONFIG_BLOCK=y | 89 | CONFIG_BLOCK=y |
90 | CONFIG_BLK_DEV_IO_TRACE=y | 90 | CONFIG_BLK_DEV_IO_TRACE=y |
91 | 91 | ||
92 | # | 92 | # |
93 | # IO Schedulers | 93 | # IO Schedulers |
94 | # | 94 | # |
95 | CONFIG_IOSCHED_NOOP=y | 95 | CONFIG_IOSCHED_NOOP=y |
96 | CONFIG_IOSCHED_AS=y | 96 | CONFIG_IOSCHED_AS=y |
97 | CONFIG_IOSCHED_DEADLINE=y | 97 | CONFIG_IOSCHED_DEADLINE=y |
98 | CONFIG_IOSCHED_CFQ=y | 98 | CONFIG_IOSCHED_CFQ=y |
99 | CONFIG_DEFAULT_AS=y | 99 | CONFIG_DEFAULT_AS=y |
100 | # CONFIG_DEFAULT_DEADLINE is not set | 100 | # CONFIG_DEFAULT_DEADLINE is not set |
101 | # CONFIG_DEFAULT_CFQ is not set | 101 | # CONFIG_DEFAULT_CFQ is not set |
102 | # CONFIG_DEFAULT_NOOP is not set | 102 | # CONFIG_DEFAULT_NOOP is not set |
103 | CONFIG_DEFAULT_IOSCHED="anticipatory" | 103 | CONFIG_DEFAULT_IOSCHED="anticipatory" |
104 | CONFIG_SYSVIPC_COMPAT=y | 104 | CONFIG_SYSVIPC_COMPAT=y |
105 | CONFIG_GENERIC_HARDIRQS=y | 105 | CONFIG_GENERIC_HARDIRQS=y |
106 | 106 | ||
107 | # | 107 | # |
108 | # General machine setup | 108 | # General machine setup |
109 | # | 109 | # |
110 | # CONFIG_SMP is not set | 110 | # CONFIG_SMP is not set |
111 | # CONFIG_PREEMPT is not set | 111 | # CONFIG_PREEMPT is not set |
112 | CONFIG_CPU_FREQ=y | 112 | CONFIG_CPU_FREQ=y |
113 | CONFIG_CPU_FREQ_TABLE=m | 113 | CONFIG_CPU_FREQ_TABLE=m |
114 | # CONFIG_CPU_FREQ_DEBUG is not set | 114 | # CONFIG_CPU_FREQ_DEBUG is not set |
115 | CONFIG_CPU_FREQ_STAT=m | 115 | CONFIG_CPU_FREQ_STAT=m |
116 | CONFIG_CPU_FREQ_STAT_DETAILS=y | 116 | CONFIG_CPU_FREQ_STAT_DETAILS=y |
117 | CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y | 117 | CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y |
118 | # CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set | 118 | # CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set |
119 | CONFIG_CPU_FREQ_GOV_PERFORMANCE=y | 119 | CONFIG_CPU_FREQ_GOV_PERFORMANCE=y |
120 | CONFIG_CPU_FREQ_GOV_POWERSAVE=m | 120 | CONFIG_CPU_FREQ_GOV_POWERSAVE=m |
121 | CONFIG_CPU_FREQ_GOV_USERSPACE=m | 121 | CONFIG_CPU_FREQ_GOV_USERSPACE=m |
122 | CONFIG_CPU_FREQ_GOV_ONDEMAND=m | 122 | CONFIG_CPU_FREQ_GOV_ONDEMAND=m |
123 | CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m | 123 | CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m |
124 | CONFIG_US3_FREQ=m | 124 | CONFIG_US3_FREQ=m |
125 | CONFIG_US2E_FREQ=m | 125 | CONFIG_US2E_FREQ=m |
126 | CONFIG_RWSEM_XCHGADD_ALGORITHM=y | 126 | CONFIG_RWSEM_XCHGADD_ALGORITHM=y |
127 | CONFIG_GENERIC_FIND_NEXT_BIT=y | 127 | CONFIG_GENERIC_FIND_NEXT_BIT=y |
128 | CONFIG_GENERIC_HWEIGHT=y | 128 | CONFIG_GENERIC_HWEIGHT=y |
129 | CONFIG_GENERIC_CALIBRATE_DELAY=y | 129 | CONFIG_GENERIC_CALIBRATE_DELAY=y |
130 | CONFIG_HUGETLB_PAGE_SIZE_4MB=y | 130 | CONFIG_HUGETLB_PAGE_SIZE_4MB=y |
131 | # CONFIG_HUGETLB_PAGE_SIZE_512K is not set | 131 | # CONFIG_HUGETLB_PAGE_SIZE_512K is not set |
132 | # CONFIG_HUGETLB_PAGE_SIZE_64K is not set | 132 | # CONFIG_HUGETLB_PAGE_SIZE_64K is not set |
133 | CONFIG_ARCH_SELECT_MEMORY_MODEL=y | 133 | CONFIG_ARCH_SELECT_MEMORY_MODEL=y |
134 | CONFIG_ARCH_SPARSEMEM_ENABLE=y | 134 | CONFIG_ARCH_SPARSEMEM_ENABLE=y |
135 | CONFIG_ARCH_SPARSEMEM_DEFAULT=y | 135 | CONFIG_ARCH_SPARSEMEM_DEFAULT=y |
136 | CONFIG_LARGE_ALLOCS=y | 136 | CONFIG_LARGE_ALLOCS=y |
137 | CONFIG_SELECT_MEMORY_MODEL=y | 137 | CONFIG_SELECT_MEMORY_MODEL=y |
138 | # CONFIG_FLATMEM_MANUAL is not set | 138 | # CONFIG_FLATMEM_MANUAL is not set |
139 | # CONFIG_DISCONTIGMEM_MANUAL is not set | 139 | # CONFIG_DISCONTIGMEM_MANUAL is not set |
140 | CONFIG_SPARSEMEM_MANUAL=y | 140 | CONFIG_SPARSEMEM_MANUAL=y |
141 | CONFIG_SPARSEMEM=y | 141 | CONFIG_SPARSEMEM=y |
142 | CONFIG_HAVE_MEMORY_PRESENT=y | 142 | CONFIG_HAVE_MEMORY_PRESENT=y |
143 | # CONFIG_SPARSEMEM_STATIC is not set | 143 | # CONFIG_SPARSEMEM_STATIC is not set |
144 | CONFIG_SPARSEMEM_EXTREME=y | 144 | CONFIG_SPARSEMEM_EXTREME=y |
145 | CONFIG_SPLIT_PTLOCK_CPUS=4 | 145 | CONFIG_SPLIT_PTLOCK_CPUS=4 |
146 | CONFIG_RESOURCES_64BIT=y | 146 | CONFIG_RESOURCES_64BIT=y |
147 | CONFIG_GENERIC_ISA_DMA=y | 147 | CONFIG_GENERIC_ISA_DMA=y |
148 | CONFIG_SBUS=y | 148 | CONFIG_SBUS=y |
149 | CONFIG_SBUSCHAR=y | 149 | CONFIG_SBUSCHAR=y |
150 | CONFIG_SUN_AUXIO=y | 150 | CONFIG_SUN_AUXIO=y |
151 | CONFIG_SUN_IO=y | 151 | CONFIG_SUN_IO=y |
152 | CONFIG_PCI=y | 152 | CONFIG_PCI=y |
153 | CONFIG_PCI_DOMAINS=y | 153 | CONFIG_PCI_DOMAINS=y |
154 | # CONFIG_PCI_MULTITHREAD_PROBE is not set | 154 | CONFIG_PCI_MSI=y |
155 | # CONFIG_PCI_DEBUG is not set | 155 | # CONFIG_PCI_DEBUG is not set |
156 | CONFIG_SUN_OPENPROMFS=m | 156 | CONFIG_SUN_OPENPROMFS=m |
157 | CONFIG_SPARC32_COMPAT=y | 157 | CONFIG_SPARC32_COMPAT=y |
158 | CONFIG_COMPAT=y | 158 | CONFIG_COMPAT=y |
159 | CONFIG_BINFMT_ELF32=y | 159 | CONFIG_BINFMT_ELF32=y |
160 | # CONFIG_BINFMT_AOUT32 is not set | 160 | # CONFIG_BINFMT_AOUT32 is not set |
161 | 161 | ||
162 | # | 162 | # |
163 | # Executable file formats | 163 | # Executable file formats |
164 | # | 164 | # |
165 | CONFIG_BINFMT_ELF=y | 165 | CONFIG_BINFMT_ELF=y |
166 | CONFIG_BINFMT_MISC=m | 166 | CONFIG_BINFMT_MISC=m |
167 | CONFIG_SOLARIS_EMUL=y | 167 | CONFIG_SOLARIS_EMUL=y |
168 | # CONFIG_CMDLINE_BOOL is not set | 168 | # CONFIG_CMDLINE_BOOL is not set |
169 | 169 | ||
170 | # | 170 | # |
171 | # Networking | 171 | # Networking |
172 | # | 172 | # |
173 | CONFIG_NET=y | 173 | CONFIG_NET=y |
174 | 174 | ||
175 | # | 175 | # |
176 | # Networking options | 176 | # Networking options |
177 | # | 177 | # |
178 | # CONFIG_NETDEBUG is not set | 178 | # CONFIG_NETDEBUG is not set |
179 | CONFIG_PACKET=y | 179 | CONFIG_PACKET=y |
180 | CONFIG_PACKET_MMAP=y | 180 | CONFIG_PACKET_MMAP=y |
181 | CONFIG_UNIX=y | 181 | CONFIG_UNIX=y |
182 | CONFIG_XFRM=y | 182 | CONFIG_XFRM=y |
183 | CONFIG_XFRM_USER=m | 183 | CONFIG_XFRM_USER=m |
184 | # CONFIG_XFRM_SUB_POLICY is not set | 184 | # CONFIG_XFRM_SUB_POLICY is not set |
185 | CONFIG_XFRM_MIGRATE=y | ||
185 | CONFIG_NET_KEY=m | 186 | CONFIG_NET_KEY=m |
187 | CONFIG_NET_KEY_MIGRATE=y | ||
186 | CONFIG_INET=y | 188 | CONFIG_INET=y |
187 | CONFIG_IP_MULTICAST=y | 189 | CONFIG_IP_MULTICAST=y |
188 | # CONFIG_IP_ADVANCED_ROUTER is not set | 190 | # CONFIG_IP_ADVANCED_ROUTER is not set |
189 | CONFIG_IP_FIB_HASH=y | 191 | CONFIG_IP_FIB_HASH=y |
190 | # CONFIG_IP_PNP is not set | 192 | # CONFIG_IP_PNP is not set |
191 | CONFIG_NET_IPIP=m | 193 | CONFIG_NET_IPIP=m |
192 | CONFIG_NET_IPGRE=m | 194 | CONFIG_NET_IPGRE=m |
193 | CONFIG_NET_IPGRE_BROADCAST=y | 195 | CONFIG_NET_IPGRE_BROADCAST=y |
194 | CONFIG_IP_MROUTE=y | 196 | CONFIG_IP_MROUTE=y |
195 | CONFIG_IP_PIMSM_V1=y | 197 | CONFIG_IP_PIMSM_V1=y |
196 | CONFIG_IP_PIMSM_V2=y | 198 | CONFIG_IP_PIMSM_V2=y |
197 | CONFIG_ARPD=y | 199 | CONFIG_ARPD=y |
198 | CONFIG_SYN_COOKIES=y | 200 | CONFIG_SYN_COOKIES=y |
199 | CONFIG_INET_AH=y | 201 | CONFIG_INET_AH=y |
200 | CONFIG_INET_ESP=y | 202 | CONFIG_INET_ESP=y |
201 | CONFIG_INET_IPCOMP=y | 203 | CONFIG_INET_IPCOMP=y |
202 | CONFIG_INET_XFRM_TUNNEL=y | 204 | CONFIG_INET_XFRM_TUNNEL=y |
203 | CONFIG_INET_TUNNEL=y | 205 | CONFIG_INET_TUNNEL=y |
204 | CONFIG_INET_XFRM_MODE_TRANSPORT=y | 206 | CONFIG_INET_XFRM_MODE_TRANSPORT=y |
205 | CONFIG_INET_XFRM_MODE_TUNNEL=y | 207 | CONFIG_INET_XFRM_MODE_TUNNEL=y |
206 | CONFIG_INET_XFRM_MODE_BEET=y | 208 | CONFIG_INET_XFRM_MODE_BEET=y |
207 | CONFIG_INET_DIAG=y | 209 | CONFIG_INET_DIAG=y |
208 | CONFIG_INET_TCP_DIAG=y | 210 | CONFIG_INET_TCP_DIAG=y |
209 | # CONFIG_TCP_CONG_ADVANCED is not set | 211 | # CONFIG_TCP_CONG_ADVANCED is not set |
210 | CONFIG_TCP_CONG_CUBIC=y | 212 | CONFIG_TCP_CONG_CUBIC=y |
211 | CONFIG_DEFAULT_TCP_CONG="cubic" | 213 | CONFIG_DEFAULT_TCP_CONG="cubic" |
212 | # CONFIG_TCP_MD5SIG is not set | 214 | # CONFIG_TCP_MD5SIG is not set |
213 | CONFIG_IPV6=m | 215 | CONFIG_IPV6=m |
214 | CONFIG_IPV6_PRIVACY=y | 216 | CONFIG_IPV6_PRIVACY=y |
215 | CONFIG_IPV6_ROUTER_PREF=y | 217 | CONFIG_IPV6_ROUTER_PREF=y |
216 | CONFIG_IPV6_ROUTE_INFO=y | 218 | CONFIG_IPV6_ROUTE_INFO=y |
217 | CONFIG_INET6_AH=m | 219 | CONFIG_INET6_AH=m |
218 | CONFIG_INET6_ESP=m | 220 | CONFIG_INET6_ESP=m |
219 | CONFIG_INET6_IPCOMP=m | 221 | CONFIG_INET6_IPCOMP=m |
220 | # CONFIG_IPV6_MIP6 is not set | 222 | # CONFIG_IPV6_MIP6 is not set |
221 | CONFIG_INET6_XFRM_TUNNEL=m | 223 | CONFIG_INET6_XFRM_TUNNEL=m |
222 | CONFIG_INET6_TUNNEL=m | 224 | CONFIG_INET6_TUNNEL=m |
223 | CONFIG_INET6_XFRM_MODE_TRANSPORT=m | 225 | CONFIG_INET6_XFRM_MODE_TRANSPORT=m |
224 | CONFIG_INET6_XFRM_MODE_TUNNEL=m | 226 | CONFIG_INET6_XFRM_MODE_TUNNEL=m |
225 | CONFIG_INET6_XFRM_MODE_BEET=m | 227 | CONFIG_INET6_XFRM_MODE_BEET=m |
226 | # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set | 228 | # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set |
227 | CONFIG_IPV6_SIT=m | 229 | CONFIG_IPV6_SIT=m |
228 | CONFIG_IPV6_TUNNEL=m | 230 | CONFIG_IPV6_TUNNEL=m |
229 | # CONFIG_IPV6_MULTIPLE_TABLES is not set | 231 | # CONFIG_IPV6_MULTIPLE_TABLES is not set |
230 | # CONFIG_NETWORK_SECMARK is not set | 232 | # CONFIG_NETWORK_SECMARK is not set |
231 | # CONFIG_NETFILTER is not set | 233 | # CONFIG_NETFILTER is not set |
232 | 234 | ||
233 | # | 235 | # |
234 | # DCCP Configuration (EXPERIMENTAL) | 236 | # DCCP Configuration (EXPERIMENTAL) |
235 | # | 237 | # |
236 | CONFIG_IP_DCCP=m | 238 | CONFIG_IP_DCCP=m |
237 | CONFIG_INET_DCCP_DIAG=m | 239 | CONFIG_INET_DCCP_DIAG=m |
238 | CONFIG_IP_DCCP_ACKVEC=y | 240 | CONFIG_IP_DCCP_ACKVEC=y |
239 | 241 | ||
240 | # | 242 | # |
241 | # DCCP CCIDs Configuration (EXPERIMENTAL) | 243 | # DCCP CCIDs Configuration (EXPERIMENTAL) |
242 | # | 244 | # |
243 | CONFIG_IP_DCCP_CCID2=m | 245 | CONFIG_IP_DCCP_CCID2=m |
244 | # CONFIG_IP_DCCP_CCID2_DEBUG is not set | 246 | # CONFIG_IP_DCCP_CCID2_DEBUG is not set |
245 | CONFIG_IP_DCCP_CCID3=m | 247 | CONFIG_IP_DCCP_CCID3=m |
246 | CONFIG_IP_DCCP_TFRC_LIB=m | 248 | CONFIG_IP_DCCP_TFRC_LIB=m |
247 | # CONFIG_IP_DCCP_CCID3_DEBUG is not set | 249 | # CONFIG_IP_DCCP_CCID3_DEBUG is not set |
248 | CONFIG_IP_DCCP_CCID3_RTO=100 | 250 | CONFIG_IP_DCCP_CCID3_RTO=100 |
249 | 251 | ||
250 | # | 252 | # |
251 | # DCCP Kernel Hacking | 253 | # DCCP Kernel Hacking |
252 | # | 254 | # |
253 | # CONFIG_IP_DCCP_DEBUG is not set | 255 | # CONFIG_IP_DCCP_DEBUG is not set |
254 | # CONFIG_NET_DCCPPROBE is not set | 256 | # CONFIG_NET_DCCPPROBE is not set |
255 | 257 | ||
256 | # | 258 | # |
257 | # SCTP Configuration (EXPERIMENTAL) | 259 | # SCTP Configuration (EXPERIMENTAL) |
258 | # | 260 | # |
259 | # CONFIG_IP_SCTP is not set | 261 | # CONFIG_IP_SCTP is not set |
260 | 262 | ||
261 | # | 263 | # |
262 | # TIPC Configuration (EXPERIMENTAL) | 264 | # TIPC Configuration (EXPERIMENTAL) |
263 | # | 265 | # |
264 | # CONFIG_TIPC is not set | 266 | # CONFIG_TIPC is not set |
265 | # CONFIG_ATM is not set | 267 | # CONFIG_ATM is not set |
266 | # CONFIG_BRIDGE is not set | 268 | # CONFIG_BRIDGE is not set |
267 | CONFIG_VLAN_8021Q=m | 269 | CONFIG_VLAN_8021Q=m |
268 | # CONFIG_DECNET is not set | 270 | # CONFIG_DECNET is not set |
269 | # CONFIG_LLC2 is not set | 271 | # CONFIG_LLC2 is not set |
270 | # CONFIG_IPX is not set | 272 | # CONFIG_IPX is not set |
271 | # CONFIG_ATALK is not set | 273 | # CONFIG_ATALK is not set |
272 | # CONFIG_X25 is not set | 274 | # CONFIG_X25 is not set |
273 | # CONFIG_LAPB is not set | 275 | # CONFIG_LAPB is not set |
274 | # CONFIG_ECONET is not set | 276 | # CONFIG_ECONET is not set |
275 | # CONFIG_WAN_ROUTER is not set | 277 | # CONFIG_WAN_ROUTER is not set |
276 | 278 | ||
277 | # | 279 | # |
278 | # QoS and/or fair queueing | 280 | # QoS and/or fair queueing |
279 | # | 281 | # |
280 | # CONFIG_NET_SCHED is not set | 282 | # CONFIG_NET_SCHED is not set |
281 | 283 | ||
282 | # | 284 | # |
283 | # Network testing | 285 | # Network testing |
284 | # | 286 | # |
285 | CONFIG_NET_PKTGEN=m | 287 | CONFIG_NET_PKTGEN=m |
286 | CONFIG_NET_TCPPROBE=m | 288 | CONFIG_NET_TCPPROBE=m |
287 | # CONFIG_HAMRADIO is not set | 289 | # CONFIG_HAMRADIO is not set |
288 | # CONFIG_IRDA is not set | 290 | # CONFIG_IRDA is not set |
289 | # CONFIG_BT is not set | 291 | # CONFIG_BT is not set |
290 | # CONFIG_IEEE80211 is not set | 292 | # CONFIG_IEEE80211 is not set |
291 | 293 | ||
292 | # | 294 | # |
293 | # Device Drivers | 295 | # Device Drivers |
294 | # | 296 | # |
295 | 297 | ||
296 | # | 298 | # |
297 | # Generic Driver Options | 299 | # Generic Driver Options |
298 | # | 300 | # |
299 | CONFIG_STANDALONE=y | 301 | CONFIG_STANDALONE=y |
300 | # CONFIG_PREVENT_FIRMWARE_BUILD is not set | 302 | # CONFIG_PREVENT_FIRMWARE_BUILD is not set |
301 | CONFIG_FW_LOADER=y | 303 | CONFIG_FW_LOADER=y |
302 | # CONFIG_DEBUG_DRIVER is not set | 304 | # CONFIG_DEBUG_DRIVER is not set |
305 | # CONFIG_DEBUG_DEVRES is not set | ||
303 | # CONFIG_SYS_HYPERVISOR is not set | 306 | # CONFIG_SYS_HYPERVISOR is not set |
304 | 307 | ||
305 | # | 308 | # |
306 | # Connector - unified userspace <-> kernelspace linker | 309 | # Connector - unified userspace <-> kernelspace linker |
307 | # | 310 | # |
308 | CONFIG_CONNECTOR=m | 311 | CONFIG_CONNECTOR=m |
309 | 312 | ||
310 | # | 313 | # |
311 | # Memory Technology Devices (MTD) | 314 | # Memory Technology Devices (MTD) |
312 | # | 315 | # |
313 | # CONFIG_MTD is not set | 316 | # CONFIG_MTD is not set |
314 | 317 | ||
315 | # | 318 | # |
316 | # Parallel port support | 319 | # Parallel port support |
317 | # | 320 | # |
318 | # CONFIG_PARPORT is not set | 321 | # CONFIG_PARPORT is not set |
319 | 322 | ||
320 | # | 323 | # |
321 | # Plug and Play support | 324 | # Plug and Play support |
322 | # | 325 | # |
323 | 326 | ||
324 | # | 327 | # |
325 | # Block devices | 328 | # Block devices |
326 | # | 329 | # |
327 | # CONFIG_BLK_DEV_FD is not set | 330 | # CONFIG_BLK_DEV_FD is not set |
328 | # CONFIG_BLK_CPQ_DA is not set | 331 | # CONFIG_BLK_CPQ_DA is not set |
329 | # CONFIG_BLK_CPQ_CISS_DA is not set | 332 | # CONFIG_BLK_CPQ_CISS_DA is not set |
330 | # CONFIG_BLK_DEV_DAC960 is not set | 333 | # CONFIG_BLK_DEV_DAC960 is not set |
331 | # CONFIG_BLK_DEV_UMEM is not set | 334 | # CONFIG_BLK_DEV_UMEM is not set |
332 | # CONFIG_BLK_DEV_COW_COMMON is not set | 335 | # CONFIG_BLK_DEV_COW_COMMON is not set |
333 | CONFIG_BLK_DEV_LOOP=m | 336 | CONFIG_BLK_DEV_LOOP=m |
334 | CONFIG_BLK_DEV_CRYPTOLOOP=m | 337 | CONFIG_BLK_DEV_CRYPTOLOOP=m |
335 | CONFIG_BLK_DEV_NBD=m | 338 | CONFIG_BLK_DEV_NBD=m |
336 | # CONFIG_BLK_DEV_SX8 is not set | 339 | # CONFIG_BLK_DEV_SX8 is not set |
337 | # CONFIG_BLK_DEV_UB is not set | 340 | # CONFIG_BLK_DEV_UB is not set |
338 | # CONFIG_BLK_DEV_RAM is not set | 341 | # CONFIG_BLK_DEV_RAM is not set |
339 | # CONFIG_BLK_DEV_INITRD is not set | 342 | # CONFIG_BLK_DEV_INITRD is not set |
340 | CONFIG_CDROM_PKTCDVD=m | 343 | CONFIG_CDROM_PKTCDVD=m |
341 | CONFIG_CDROM_PKTCDVD_BUFFERS=8 | 344 | CONFIG_CDROM_PKTCDVD_BUFFERS=8 |
342 | CONFIG_CDROM_PKTCDVD_WCACHE=y | 345 | CONFIG_CDROM_PKTCDVD_WCACHE=y |
343 | CONFIG_ATA_OVER_ETH=m | 346 | CONFIG_ATA_OVER_ETH=m |
344 | 347 | ||
345 | # | 348 | # |
346 | # Misc devices | 349 | # Misc devices |
347 | # | 350 | # |
348 | # CONFIG_SGI_IOC4 is not set | 351 | # CONFIG_SGI_IOC4 is not set |
349 | # CONFIG_TIFM_CORE is not set | 352 | # CONFIG_TIFM_CORE is not set |
350 | 353 | ||
351 | # | 354 | # |
352 | # ATA/ATAPI/MFM/RLL support | 355 | # ATA/ATAPI/MFM/RLL support |
353 | # | 356 | # |
354 | CONFIG_IDE=y | 357 | CONFIG_IDE=y |
355 | CONFIG_BLK_DEV_IDE=y | 358 | CONFIG_BLK_DEV_IDE=y |
356 | 359 | ||
357 | # | 360 | # |
358 | # Please see Documentation/ide.txt for help/info on IDE drives | 361 | # Please see Documentation/ide.txt for help/info on IDE drives |
359 | # | 362 | # |
360 | # CONFIG_BLK_DEV_IDE_SATA is not set | 363 | # CONFIG_BLK_DEV_IDE_SATA is not set |
361 | CONFIG_BLK_DEV_IDEDISK=y | 364 | CONFIG_BLK_DEV_IDEDISK=y |
362 | # CONFIG_IDEDISK_MULTI_MODE is not set | 365 | # CONFIG_IDEDISK_MULTI_MODE is not set |
363 | CONFIG_BLK_DEV_IDECD=y | 366 | CONFIG_BLK_DEV_IDECD=y |
364 | # CONFIG_BLK_DEV_IDETAPE is not set | 367 | # CONFIG_BLK_DEV_IDETAPE is not set |
365 | # CONFIG_BLK_DEV_IDEFLOPPY is not set | 368 | # CONFIG_BLK_DEV_IDEFLOPPY is not set |
366 | # CONFIG_BLK_DEV_IDESCSI is not set | 369 | # CONFIG_BLK_DEV_IDESCSI is not set |
367 | # CONFIG_IDE_TASK_IOCTL is not set | 370 | # CONFIG_IDE_TASK_IOCTL is not set |
368 | 371 | ||
369 | # | 372 | # |
370 | # IDE chipset support/bugfixes | 373 | # IDE chipset support/bugfixes |
371 | # | 374 | # |
372 | CONFIG_IDE_GENERIC=y | 375 | CONFIG_IDE_GENERIC=y |
373 | CONFIG_BLK_DEV_IDEPCI=y | 376 | CONFIG_BLK_DEV_IDEPCI=y |
374 | # CONFIG_IDEPCI_SHARE_IRQ is not set | 377 | # CONFIG_IDEPCI_SHARE_IRQ is not set |
375 | # CONFIG_BLK_DEV_OFFBOARD is not set | 378 | # CONFIG_BLK_DEV_OFFBOARD is not set |
376 | # CONFIG_BLK_DEV_GENERIC is not set | 379 | # CONFIG_BLK_DEV_GENERIC is not set |
377 | # CONFIG_BLK_DEV_OPTI621 is not set | 380 | # CONFIG_BLK_DEV_OPTI621 is not set |
378 | CONFIG_BLK_DEV_IDEDMA_PCI=y | 381 | CONFIG_BLK_DEV_IDEDMA_PCI=y |
379 | # CONFIG_BLK_DEV_IDEDMA_FORCED is not set | 382 | # CONFIG_BLK_DEV_IDEDMA_FORCED is not set |
380 | CONFIG_IDEDMA_PCI_AUTO=y | 383 | CONFIG_IDEDMA_PCI_AUTO=y |
381 | CONFIG_IDEDMA_ONLYDISK=y | 384 | CONFIG_IDEDMA_ONLYDISK=y |
382 | # CONFIG_BLK_DEV_AEC62XX is not set | 385 | # CONFIG_BLK_DEV_AEC62XX is not set |
383 | CONFIG_BLK_DEV_ALI15X3=y | 386 | CONFIG_BLK_DEV_ALI15X3=y |
384 | # CONFIG_WDC_ALI15X3 is not set | 387 | # CONFIG_WDC_ALI15X3 is not set |
385 | # CONFIG_BLK_DEV_AMD74XX is not set | 388 | # CONFIG_BLK_DEV_AMD74XX is not set |
386 | # CONFIG_BLK_DEV_CMD64X is not set | 389 | # CONFIG_BLK_DEV_CMD64X is not set |
387 | # CONFIG_BLK_DEV_TRIFLEX is not set | 390 | # CONFIG_BLK_DEV_TRIFLEX is not set |
388 | # CONFIG_BLK_DEV_CY82C693 is not set | 391 | # CONFIG_BLK_DEV_CY82C693 is not set |
389 | # CONFIG_BLK_DEV_CS5520 is not set | 392 | # CONFIG_BLK_DEV_CS5520 is not set |
390 | # CONFIG_BLK_DEV_CS5530 is not set | 393 | # CONFIG_BLK_DEV_CS5530 is not set |
391 | # CONFIG_BLK_DEV_HPT34X is not set | 394 | # CONFIG_BLK_DEV_HPT34X is not set |
392 | # CONFIG_BLK_DEV_HPT366 is not set | 395 | # CONFIG_BLK_DEV_HPT366 is not set |
393 | # CONFIG_BLK_DEV_JMICRON is not set | 396 | # CONFIG_BLK_DEV_JMICRON is not set |
394 | # CONFIG_BLK_DEV_SC1200 is not set | 397 | # CONFIG_BLK_DEV_SC1200 is not set |
395 | # CONFIG_BLK_DEV_PIIX is not set | 398 | # CONFIG_BLK_DEV_PIIX is not set |
399 | # CONFIG_BLK_DEV_IT8213 is not set | ||
396 | # CONFIG_BLK_DEV_IT821X is not set | 400 | # CONFIG_BLK_DEV_IT821X is not set |
397 | # CONFIG_BLK_DEV_NS87415 is not set | 401 | # CONFIG_BLK_DEV_NS87415 is not set |
398 | # CONFIG_BLK_DEV_PDC202XX_OLD is not set | 402 | # CONFIG_BLK_DEV_PDC202XX_OLD is not set |
399 | # CONFIG_BLK_DEV_PDC202XX_NEW is not set | 403 | # CONFIG_BLK_DEV_PDC202XX_NEW is not set |
400 | # CONFIG_BLK_DEV_SVWKS is not set | 404 | # CONFIG_BLK_DEV_SVWKS is not set |
401 | # CONFIG_BLK_DEV_SIIMAGE is not set | 405 | # CONFIG_BLK_DEV_SIIMAGE is not set |
402 | # CONFIG_BLK_DEV_SLC90E66 is not set | 406 | # CONFIG_BLK_DEV_SLC90E66 is not set |
403 | # CONFIG_BLK_DEV_TRM290 is not set | 407 | # CONFIG_BLK_DEV_TRM290 is not set |
404 | # CONFIG_BLK_DEV_VIA82CXXX is not set | 408 | # CONFIG_BLK_DEV_VIA82CXXX is not set |
409 | # CONFIG_BLK_DEV_TC86C001 is not set | ||
405 | # CONFIG_IDE_ARM is not set | 410 | # CONFIG_IDE_ARM is not set |
406 | CONFIG_BLK_DEV_IDEDMA=y | 411 | CONFIG_BLK_DEV_IDEDMA=y |
407 | # CONFIG_IDEDMA_IVB is not set | 412 | # CONFIG_IDEDMA_IVB is not set |
408 | CONFIG_IDEDMA_AUTO=y | 413 | CONFIG_IDEDMA_AUTO=y |
409 | # CONFIG_BLK_DEV_HD is not set | 414 | # CONFIG_BLK_DEV_HD is not set |
410 | 415 | ||
411 | # | 416 | # |
412 | # SCSI device support | 417 | # SCSI device support |
413 | # | 418 | # |
414 | CONFIG_RAID_ATTRS=m | 419 | CONFIG_RAID_ATTRS=m |
415 | CONFIG_SCSI=y | 420 | CONFIG_SCSI=y |
416 | # CONFIG_SCSI_TGT is not set | 421 | # CONFIG_SCSI_TGT is not set |
417 | CONFIG_SCSI_NETLINK=y | 422 | CONFIG_SCSI_NETLINK=y |
418 | CONFIG_SCSI_PROC_FS=y | 423 | CONFIG_SCSI_PROC_FS=y |
419 | 424 | ||
420 | # | 425 | # |
421 | # SCSI support type (disk, tape, CD-ROM) | 426 | # SCSI support type (disk, tape, CD-ROM) |
422 | # | 427 | # |
423 | CONFIG_BLK_DEV_SD=y | 428 | CONFIG_BLK_DEV_SD=y |
424 | # CONFIG_CHR_DEV_ST is not set | 429 | # CONFIG_CHR_DEV_ST is not set |
425 | # CONFIG_CHR_DEV_OSST is not set | 430 | # CONFIG_CHR_DEV_OSST is not set |
426 | CONFIG_BLK_DEV_SR=m | 431 | CONFIG_BLK_DEV_SR=m |
427 | CONFIG_BLK_DEV_SR_VENDOR=y | 432 | CONFIG_BLK_DEV_SR_VENDOR=y |
428 | CONFIG_CHR_DEV_SG=m | 433 | CONFIG_CHR_DEV_SG=m |
429 | # CONFIG_CHR_DEV_SCH is not set | 434 | # CONFIG_CHR_DEV_SCH is not set |
430 | 435 | ||
431 | # | 436 | # |
432 | # Some SCSI devices (e.g. CD jukebox) support multiple LUNs | 437 | # Some SCSI devices (e.g. CD jukebox) support multiple LUNs |
433 | # | 438 | # |
434 | CONFIG_SCSI_MULTI_LUN=y | 439 | CONFIG_SCSI_MULTI_LUN=y |
435 | CONFIG_SCSI_CONSTANTS=y | 440 | CONFIG_SCSI_CONSTANTS=y |
436 | # CONFIG_SCSI_LOGGING is not set | 441 | # CONFIG_SCSI_LOGGING is not set |
437 | # CONFIG_SCSI_SCAN_ASYNC is not set | 442 | # CONFIG_SCSI_SCAN_ASYNC is not set |
438 | 443 | ||
439 | # | 444 | # |
440 | # SCSI Transports | 445 | # SCSI Transports |
441 | # | 446 | # |
442 | CONFIG_SCSI_SPI_ATTRS=y | 447 | CONFIG_SCSI_SPI_ATTRS=y |
443 | CONFIG_SCSI_FC_ATTRS=y | 448 | CONFIG_SCSI_FC_ATTRS=y |
444 | CONFIG_SCSI_ISCSI_ATTRS=m | 449 | CONFIG_SCSI_ISCSI_ATTRS=m |
445 | # CONFIG_SCSI_SAS_ATTRS is not set | 450 | # CONFIG_SCSI_SAS_ATTRS is not set |
446 | # CONFIG_SCSI_SAS_LIBSAS is not set | 451 | # CONFIG_SCSI_SAS_LIBSAS is not set |
447 | 452 | ||
448 | # | 453 | # |
449 | # SCSI low-level drivers | 454 | # SCSI low-level drivers |
450 | # | 455 | # |
451 | CONFIG_ISCSI_TCP=m | 456 | CONFIG_ISCSI_TCP=m |
452 | # CONFIG_BLK_DEV_3W_XXXX_RAID is not set | 457 | # CONFIG_BLK_DEV_3W_XXXX_RAID is not set |
453 | # CONFIG_SCSI_3W_9XXX is not set | 458 | # CONFIG_SCSI_3W_9XXX is not set |
454 | # CONFIG_SCSI_ACARD is not set | 459 | # CONFIG_SCSI_ACARD is not set |
455 | # CONFIG_SCSI_AACRAID is not set | 460 | # CONFIG_SCSI_AACRAID is not set |
456 | # CONFIG_SCSI_AIC7XXX is not set | 461 | # CONFIG_SCSI_AIC7XXX is not set |
457 | # CONFIG_SCSI_AIC7XXX_OLD is not set | 462 | # CONFIG_SCSI_AIC7XXX_OLD is not set |
458 | # CONFIG_SCSI_AIC79XX is not set | 463 | # CONFIG_SCSI_AIC79XX is not set |
459 | # CONFIG_SCSI_AIC94XX is not set | 464 | # CONFIG_SCSI_AIC94XX is not set |
460 | # CONFIG_SCSI_ARCMSR is not set | 465 | # CONFIG_SCSI_ARCMSR is not set |
461 | # CONFIG_MEGARAID_NEWGEN is not set | 466 | # CONFIG_MEGARAID_NEWGEN is not set |
462 | # CONFIG_MEGARAID_LEGACY is not set | 467 | # CONFIG_MEGARAID_LEGACY is not set |
463 | # CONFIG_MEGARAID_SAS is not set | 468 | # CONFIG_MEGARAID_SAS is not set |
464 | # CONFIG_SCSI_HPTIOP is not set | 469 | # CONFIG_SCSI_HPTIOP is not set |
465 | # CONFIG_SCSI_DMX3191D is not set | 470 | # CONFIG_SCSI_DMX3191D is not set |
466 | # CONFIG_SCSI_FUTURE_DOMAIN is not set | 471 | # CONFIG_SCSI_FUTURE_DOMAIN is not set |
467 | # CONFIG_SCSI_IPS is not set | 472 | # CONFIG_SCSI_IPS is not set |
468 | # CONFIG_SCSI_INITIO is not set | 473 | # CONFIG_SCSI_INITIO is not set |
469 | # CONFIG_SCSI_INIA100 is not set | 474 | # CONFIG_SCSI_INIA100 is not set |
470 | # CONFIG_SCSI_STEX is not set | 475 | # CONFIG_SCSI_STEX is not set |
471 | # CONFIG_SCSI_SYM53C8XX_2 is not set | 476 | # CONFIG_SCSI_SYM53C8XX_2 is not set |
472 | # CONFIG_SCSI_QLOGIC_1280 is not set | 477 | # CONFIG_SCSI_QLOGIC_1280 is not set |
473 | # CONFIG_SCSI_QLOGICPTI is not set | 478 | # CONFIG_SCSI_QLOGICPTI is not set |
474 | # CONFIG_SCSI_QLA_FC is not set | 479 | # CONFIG_SCSI_QLA_FC is not set |
475 | # CONFIG_SCSI_QLA_ISCSI is not set | 480 | # CONFIG_SCSI_QLA_ISCSI is not set |
476 | # CONFIG_SCSI_LPFC is not set | 481 | # CONFIG_SCSI_LPFC is not set |
477 | # CONFIG_SCSI_DC395x is not set | 482 | # CONFIG_SCSI_DC395x is not set |
478 | # CONFIG_SCSI_DC390T is not set | 483 | # CONFIG_SCSI_DC390T is not set |
479 | # CONFIG_SCSI_DEBUG is not set | 484 | # CONFIG_SCSI_DEBUG is not set |
480 | # CONFIG_SCSI_SUNESP is not set | 485 | # CONFIG_SCSI_SUNESP is not set |
481 | # CONFIG_SCSI_SRP is not set | 486 | # CONFIG_SCSI_SRP is not set |
482 | 487 | ||
483 | # | 488 | # |
484 | # Serial ATA (prod) and Parallel ATA (experimental) drivers | 489 | # Serial ATA (prod) and Parallel ATA (experimental) drivers |
485 | # | 490 | # |
486 | # CONFIG_ATA is not set | 491 | # CONFIG_ATA is not set |
487 | 492 | ||
488 | # | 493 | # |
489 | # Multi-device support (RAID and LVM) | 494 | # Multi-device support (RAID and LVM) |
490 | # | 495 | # |
491 | CONFIG_MD=y | 496 | CONFIG_MD=y |
492 | CONFIG_BLK_DEV_MD=m | 497 | CONFIG_BLK_DEV_MD=m |
493 | CONFIG_MD_LINEAR=m | 498 | CONFIG_MD_LINEAR=m |
494 | CONFIG_MD_RAID0=m | 499 | CONFIG_MD_RAID0=m |
495 | CONFIG_MD_RAID1=m | 500 | CONFIG_MD_RAID1=m |
496 | CONFIG_MD_RAID10=m | 501 | CONFIG_MD_RAID10=m |
497 | CONFIG_MD_RAID456=m | 502 | CONFIG_MD_RAID456=m |
498 | # CONFIG_MD_RAID5_RESHAPE is not set | 503 | # CONFIG_MD_RAID5_RESHAPE is not set |
499 | CONFIG_MD_MULTIPATH=m | 504 | CONFIG_MD_MULTIPATH=m |
500 | # CONFIG_MD_FAULTY is not set | 505 | # CONFIG_MD_FAULTY is not set |
501 | CONFIG_BLK_DEV_DM=m | 506 | CONFIG_BLK_DEV_DM=m |
502 | # CONFIG_DM_DEBUG is not set | 507 | # CONFIG_DM_DEBUG is not set |
503 | CONFIG_DM_CRYPT=m | 508 | CONFIG_DM_CRYPT=m |
504 | CONFIG_DM_SNAPSHOT=m | 509 | CONFIG_DM_SNAPSHOT=m |
505 | CONFIG_DM_MIRROR=m | 510 | CONFIG_DM_MIRROR=m |
506 | CONFIG_DM_ZERO=m | 511 | CONFIG_DM_ZERO=m |
507 | # CONFIG_DM_MULTIPATH is not set | 512 | # CONFIG_DM_MULTIPATH is not set |
508 | 513 | ||
509 | # | 514 | # |
510 | # Fusion MPT device support | 515 | # Fusion MPT device support |
511 | # | 516 | # |
512 | # CONFIG_FUSION is not set | 517 | # CONFIG_FUSION is not set |
513 | # CONFIG_FUSION_SPI is not set | 518 | # CONFIG_FUSION_SPI is not set |
514 | # CONFIG_FUSION_FC is not set | 519 | # CONFIG_FUSION_FC is not set |
515 | # CONFIG_FUSION_SAS is not set | 520 | # CONFIG_FUSION_SAS is not set |
516 | 521 | ||
517 | # | 522 | # |
518 | # IEEE 1394 (FireWire) support | 523 | # IEEE 1394 (FireWire) support |
519 | # | 524 | # |
520 | # CONFIG_IEEE1394 is not set | 525 | # CONFIG_IEEE1394 is not set |
521 | 526 | ||
522 | # | 527 | # |
523 | # I2O device support | 528 | # I2O device support |
524 | # | 529 | # |
525 | # CONFIG_I2O is not set | 530 | # CONFIG_I2O is not set |
526 | 531 | ||
527 | # | 532 | # |
528 | # Network device support | 533 | # Network device support |
529 | # | 534 | # |
530 | CONFIG_NETDEVICES=y | 535 | CONFIG_NETDEVICES=y |
531 | CONFIG_DUMMY=m | 536 | CONFIG_DUMMY=m |
532 | # CONFIG_BONDING is not set | 537 | # CONFIG_BONDING is not set |
533 | # CONFIG_EQUALIZER is not set | 538 | # CONFIG_EQUALIZER is not set |
534 | # CONFIG_TUN is not set | 539 | # CONFIG_TUN is not set |
535 | 540 | ||
536 | # | 541 | # |
537 | # ARCnet devices | 542 | # ARCnet devices |
538 | # | 543 | # |
539 | # CONFIG_ARCNET is not set | 544 | # CONFIG_ARCNET is not set |
540 | 545 | ||
541 | # | 546 | # |
542 | # PHY device support | 547 | # PHY device support |
543 | # | 548 | # |
544 | # CONFIG_PHYLIB is not set | 549 | # CONFIG_PHYLIB is not set |
545 | 550 | ||
546 | # | 551 | # |
547 | # Ethernet (10 or 100Mbit) | 552 | # Ethernet (10 or 100Mbit) |
548 | # | 553 | # |
549 | CONFIG_NET_ETHERNET=y | 554 | CONFIG_NET_ETHERNET=y |
550 | CONFIG_MII=m | 555 | CONFIG_MII=m |
551 | # CONFIG_SUNLANCE is not set | 556 | # CONFIG_SUNLANCE is not set |
552 | # CONFIG_HAPPYMEAL is not set | 557 | # CONFIG_HAPPYMEAL is not set |
553 | # CONFIG_SUNBMAC is not set | 558 | # CONFIG_SUNBMAC is not set |
554 | # CONFIG_SUNQE is not set | 559 | # CONFIG_SUNQE is not set |
555 | # CONFIG_SUNGEM is not set | 560 | # CONFIG_SUNGEM is not set |
556 | CONFIG_CASSINI=m | 561 | CONFIG_CASSINI=m |
557 | # CONFIG_NET_VENDOR_3COM is not set | 562 | # CONFIG_NET_VENDOR_3COM is not set |
558 | 563 | ||
559 | # | 564 | # |
560 | # Tulip family network device support | 565 | # Tulip family network device support |
561 | # | 566 | # |
562 | # CONFIG_NET_TULIP is not set | 567 | # CONFIG_NET_TULIP is not set |
563 | # CONFIG_HP100 is not set | 568 | # CONFIG_HP100 is not set |
564 | CONFIG_NET_PCI=y | 569 | CONFIG_NET_PCI=y |
565 | # CONFIG_PCNET32 is not set | 570 | # CONFIG_PCNET32 is not set |
566 | # CONFIG_AMD8111_ETH is not set | 571 | # CONFIG_AMD8111_ETH is not set |
567 | # CONFIG_ADAPTEC_STARFIRE is not set | 572 | # CONFIG_ADAPTEC_STARFIRE is not set |
568 | # CONFIG_B44 is not set | 573 | # CONFIG_B44 is not set |
569 | # CONFIG_FORCEDETH is not set | 574 | # CONFIG_FORCEDETH is not set |
570 | # CONFIG_DGRS is not set | 575 | # CONFIG_DGRS is not set |
571 | # CONFIG_EEPRO100 is not set | 576 | # CONFIG_EEPRO100 is not set |
572 | # CONFIG_E100 is not set | 577 | # CONFIG_E100 is not set |
573 | # CONFIG_FEALNX is not set | 578 | # CONFIG_FEALNX is not set |
574 | # CONFIG_NATSEMI is not set | 579 | # CONFIG_NATSEMI is not set |
575 | # CONFIG_NE2K_PCI is not set | 580 | # CONFIG_NE2K_PCI is not set |
576 | # CONFIG_8139CP is not set | 581 | # CONFIG_8139CP is not set |
577 | # CONFIG_8139TOO is not set | 582 | # CONFIG_8139TOO is not set |
578 | # CONFIG_SIS900 is not set | 583 | # CONFIG_SIS900 is not set |
579 | # CONFIG_EPIC100 is not set | 584 | # CONFIG_EPIC100 is not set |
580 | # CONFIG_SUNDANCE is not set | 585 | # CONFIG_SUNDANCE is not set |
581 | # CONFIG_VIA_RHINE is not set | 586 | # CONFIG_VIA_RHINE is not set |
587 | # CONFIG_SC92031 is not set | ||
582 | 588 | ||
583 | # | 589 | # |
584 | # Ethernet (1000 Mbit) | 590 | # Ethernet (1000 Mbit) |
585 | # | 591 | # |
586 | # CONFIG_ACENIC is not set | 592 | # CONFIG_ACENIC is not set |
587 | # CONFIG_DL2K is not set | 593 | # CONFIG_DL2K is not set |
588 | CONFIG_E1000=m | 594 | CONFIG_E1000=m |
589 | CONFIG_E1000_NAPI=y | 595 | CONFIG_E1000_NAPI=y |
590 | # CONFIG_E1000_DISABLE_PACKET_SPLIT is not set | 596 | # CONFIG_E1000_DISABLE_PACKET_SPLIT is not set |
591 | # CONFIG_MYRI_SBUS is not set | 597 | # CONFIG_MYRI_SBUS is not set |
592 | # CONFIG_NS83820 is not set | 598 | # CONFIG_NS83820 is not set |
593 | # CONFIG_HAMACHI is not set | 599 | # CONFIG_HAMACHI is not set |
594 | # CONFIG_YELLOWFIN is not set | 600 | # CONFIG_YELLOWFIN is not set |
595 | # CONFIG_R8169 is not set | 601 | # CONFIG_R8169 is not set |
596 | # CONFIG_SIS190 is not set | 602 | # CONFIG_SIS190 is not set |
597 | # CONFIG_SKGE is not set | 603 | # CONFIG_SKGE is not set |
598 | # CONFIG_SKY2 is not set | 604 | # CONFIG_SKY2 is not set |
599 | # CONFIG_SK98LIN is not set | 605 | # CONFIG_SK98LIN is not set |
600 | # CONFIG_VIA_VELOCITY is not set | 606 | # CONFIG_VIA_VELOCITY is not set |
601 | CONFIG_TIGON3=m | 607 | CONFIG_TIGON3=m |
602 | CONFIG_BNX2=m | 608 | CONFIG_BNX2=m |
603 | # CONFIG_QLA3XXX is not set | 609 | # CONFIG_QLA3XXX is not set |
610 | # CONFIG_ATL1 is not set | ||
604 | 611 | ||
605 | # | 612 | # |
606 | # Ethernet (10000 Mbit) | 613 | # Ethernet (10000 Mbit) |
607 | # | 614 | # |
608 | # CONFIG_CHELSIO_T1 is not set | 615 | # CONFIG_CHELSIO_T1 is not set |
616 | # CONFIG_CHELSIO_T3 is not set | ||
609 | # CONFIG_IXGB is not set | 617 | # CONFIG_IXGB is not set |
610 | # CONFIG_S2IO is not set | 618 | # CONFIG_S2IO is not set |
611 | # CONFIG_MYRI10GE is not set | 619 | # CONFIG_MYRI10GE is not set |
612 | # CONFIG_NETXEN_NIC is not set | 620 | # CONFIG_NETXEN_NIC is not set |
613 | 621 | ||
614 | # | 622 | # |
615 | # Token Ring devices | 623 | # Token Ring devices |
616 | # | 624 | # |
617 | # CONFIG_TR is not set | 625 | # CONFIG_TR is not set |
618 | 626 | ||
619 | # | 627 | # |
620 | # Wireless LAN (non-hamradio) | 628 | # Wireless LAN (non-hamradio) |
621 | # | 629 | # |
622 | # CONFIG_NET_RADIO is not set | 630 | # CONFIG_NET_RADIO is not set |
623 | 631 | ||
624 | # | 632 | # |
625 | # Wan interfaces | 633 | # Wan interfaces |
626 | # | 634 | # |
627 | # CONFIG_WAN is not set | 635 | # CONFIG_WAN is not set |
628 | # CONFIG_FDDI is not set | 636 | # CONFIG_FDDI is not set |
629 | # CONFIG_HIPPI is not set | 637 | # CONFIG_HIPPI is not set |
630 | # CONFIG_PPP is not set | 638 | CONFIG_PPP=m |
639 | CONFIG_PPP_MULTILINK=y | ||
640 | CONFIG_PPP_FILTER=y | ||
641 | CONFIG_PPP_ASYNC=m | ||
642 | CONFIG_PPP_SYNC_TTY=m | ||
643 | CONFIG_PPP_DEFLATE=m | ||
644 | CONFIG_PPP_BSDCOMP=m | ||
645 | CONFIG_PPP_MPPE=m | ||
646 | CONFIG_PPPOE=m | ||
631 | # CONFIG_SLIP is not set | 647 | # CONFIG_SLIP is not set |
648 | CONFIG_SLHC=m | ||
632 | # CONFIG_NET_FC is not set | 649 | # CONFIG_NET_FC is not set |
633 | # CONFIG_SHAPER is not set | 650 | # CONFIG_SHAPER is not set |
634 | # CONFIG_NETCONSOLE is not set | 651 | # CONFIG_NETCONSOLE is not set |
635 | # CONFIG_NETPOLL is not set | 652 | # CONFIG_NETPOLL is not set |
636 | # CONFIG_NET_POLL_CONTROLLER is not set | 653 | # CONFIG_NET_POLL_CONTROLLER is not set |
637 | 654 | ||
638 | # | 655 | # |
639 | # ISDN subsystem | 656 | # ISDN subsystem |
640 | # | 657 | # |
641 | # CONFIG_ISDN is not set | 658 | # CONFIG_ISDN is not set |
642 | 659 | ||
643 | # | 660 | # |
644 | # Telephony Support | 661 | # Telephony Support |
645 | # | 662 | # |
646 | # CONFIG_PHONE is not set | 663 | # CONFIG_PHONE is not set |
647 | 664 | ||
648 | # | 665 | # |
649 | # Input device support | 666 | # Input device support |
650 | # | 667 | # |
651 | CONFIG_INPUT=y | 668 | CONFIG_INPUT=y |
652 | # CONFIG_INPUT_FF_MEMLESS is not set | 669 | # CONFIG_INPUT_FF_MEMLESS is not set |
653 | 670 | ||
654 | # | 671 | # |
655 | # Userland interfaces | 672 | # Userland interfaces |
656 | # | 673 | # |
657 | CONFIG_INPUT_MOUSEDEV=y | 674 | CONFIG_INPUT_MOUSEDEV=y |
658 | CONFIG_INPUT_MOUSEDEV_PSAUX=y | 675 | CONFIG_INPUT_MOUSEDEV_PSAUX=y |
659 | CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 | 676 | CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 |
660 | CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 | 677 | CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 |
661 | # CONFIG_INPUT_JOYDEV is not set | 678 | # CONFIG_INPUT_JOYDEV is not set |
662 | # CONFIG_INPUT_TSDEV is not set | 679 | # CONFIG_INPUT_TSDEV is not set |
663 | CONFIG_INPUT_EVDEV=y | 680 | CONFIG_INPUT_EVDEV=y |
664 | # CONFIG_INPUT_EVBUG is not set | 681 | # CONFIG_INPUT_EVBUG is not set |
665 | 682 | ||
666 | # | 683 | # |
667 | # Input Device Drivers | 684 | # Input Device Drivers |
668 | # | 685 | # |
669 | CONFIG_INPUT_KEYBOARD=y | 686 | CONFIG_INPUT_KEYBOARD=y |
670 | CONFIG_KEYBOARD_ATKBD=y | 687 | CONFIG_KEYBOARD_ATKBD=y |
671 | CONFIG_KEYBOARD_SUNKBD=y | 688 | CONFIG_KEYBOARD_SUNKBD=y |
672 | CONFIG_KEYBOARD_LKKBD=m | 689 | CONFIG_KEYBOARD_LKKBD=m |
673 | # CONFIG_KEYBOARD_XTKBD is not set | 690 | # CONFIG_KEYBOARD_XTKBD is not set |
674 | # CONFIG_KEYBOARD_NEWTON is not set | 691 | # CONFIG_KEYBOARD_NEWTON is not set |
675 | # CONFIG_KEYBOARD_STOWAWAY is not set | 692 | # CONFIG_KEYBOARD_STOWAWAY is not set |
676 | CONFIG_INPUT_MOUSE=y | 693 | CONFIG_INPUT_MOUSE=y |
677 | CONFIG_MOUSE_PS2=y | 694 | CONFIG_MOUSE_PS2=y |
678 | CONFIG_MOUSE_SERIAL=y | 695 | CONFIG_MOUSE_SERIAL=y |
679 | # CONFIG_MOUSE_VSXXXAA is not set | 696 | # CONFIG_MOUSE_VSXXXAA is not set |
680 | # CONFIG_INPUT_JOYSTICK is not set | 697 | # CONFIG_INPUT_JOYSTICK is not set |
681 | # CONFIG_INPUT_TOUCHSCREEN is not set | 698 | # CONFIG_INPUT_TOUCHSCREEN is not set |
682 | CONFIG_INPUT_MISC=y | 699 | CONFIG_INPUT_MISC=y |
683 | CONFIG_INPUT_SPARCSPKR=y | 700 | CONFIG_INPUT_SPARCSPKR=y |
684 | # CONFIG_INPUT_UINPUT is not set | 701 | # CONFIG_INPUT_UINPUT is not set |
685 | 702 | ||
686 | # | 703 | # |
687 | # Hardware I/O ports | 704 | # Hardware I/O ports |
688 | # | 705 | # |
689 | CONFIG_SERIO=y | 706 | CONFIG_SERIO=y |
690 | CONFIG_SERIO_I8042=y | 707 | CONFIG_SERIO_I8042=y |
691 | # CONFIG_SERIO_SERPORT is not set | 708 | # CONFIG_SERIO_SERPORT is not set |
692 | CONFIG_SERIO_PCIPS2=m | 709 | CONFIG_SERIO_PCIPS2=m |
693 | CONFIG_SERIO_LIBPS2=y | 710 | CONFIG_SERIO_LIBPS2=y |
694 | CONFIG_SERIO_RAW=m | 711 | CONFIG_SERIO_RAW=m |
695 | # CONFIG_GAMEPORT is not set | 712 | # CONFIG_GAMEPORT is not set |
696 | 713 | ||
697 | # | 714 | # |
698 | # Character devices | 715 | # Character devices |
699 | # | 716 | # |
700 | CONFIG_VT=y | 717 | CONFIG_VT=y |
701 | CONFIG_VT_CONSOLE=y | 718 | CONFIG_VT_CONSOLE=y |
702 | CONFIG_HW_CONSOLE=y | 719 | CONFIG_HW_CONSOLE=y |
703 | # CONFIG_VT_HW_CONSOLE_BINDING is not set | 720 | # CONFIG_VT_HW_CONSOLE_BINDING is not set |
704 | # CONFIG_SERIAL_NONSTANDARD is not set | 721 | # CONFIG_SERIAL_NONSTANDARD is not set |
705 | 722 | ||
706 | # | 723 | # |
707 | # Serial drivers | 724 | # Serial drivers |
708 | # | 725 | # |
709 | 726 | ||
710 | # | 727 | # |
711 | # Non-8250 serial port support | 728 | # Non-8250 serial port support |
712 | # | 729 | # |
713 | CONFIG_SERIAL_SUNCORE=y | 730 | CONFIG_SERIAL_SUNCORE=y |
714 | # CONFIG_SERIAL_SUNZILOG is not set | 731 | # CONFIG_SERIAL_SUNZILOG is not set |
715 | CONFIG_SERIAL_SUNSU=y | 732 | CONFIG_SERIAL_SUNSU=y |
716 | CONFIG_SERIAL_SUNSU_CONSOLE=y | 733 | CONFIG_SERIAL_SUNSU_CONSOLE=y |
717 | CONFIG_SERIAL_SUNSAB=m | 734 | CONFIG_SERIAL_SUNSAB=m |
718 | CONFIG_SERIAL_SUNHV=y | 735 | CONFIG_SERIAL_SUNHV=y |
719 | CONFIG_SERIAL_CORE=y | 736 | CONFIG_SERIAL_CORE=y |
720 | CONFIG_SERIAL_CORE_CONSOLE=y | 737 | CONFIG_SERIAL_CORE_CONSOLE=y |
721 | # CONFIG_SERIAL_JSM is not set | 738 | # CONFIG_SERIAL_JSM is not set |
722 | CONFIG_UNIX98_PTYS=y | 739 | CONFIG_UNIX98_PTYS=y |
723 | # CONFIG_LEGACY_PTYS is not set | 740 | # CONFIG_LEGACY_PTYS is not set |
724 | 741 | ||
725 | # | 742 | # |
726 | # IPMI | 743 | # IPMI |
727 | # | 744 | # |
728 | # CONFIG_IPMI_HANDLER is not set | 745 | # CONFIG_IPMI_HANDLER is not set |
729 | 746 | ||
730 | # | 747 | # |
731 | # Watchdog Cards | 748 | # Watchdog Cards |
732 | # | 749 | # |
733 | # CONFIG_WATCHDOG is not set | 750 | # CONFIG_WATCHDOG is not set |
734 | # CONFIG_HW_RANDOM is not set | 751 | # CONFIG_HW_RANDOM is not set |
735 | CONFIG_RTC=y | 752 | CONFIG_RTC=y |
736 | # CONFIG_DTLK is not set | 753 | # CONFIG_DTLK is not set |
737 | # CONFIG_R3964 is not set | 754 | # CONFIG_R3964 is not set |
738 | # CONFIG_APPLICOM is not set | 755 | # CONFIG_APPLICOM is not set |
739 | # CONFIG_DRM is not set | 756 | # CONFIG_DRM is not set |
740 | # CONFIG_RAW_DRIVER is not set | 757 | # CONFIG_RAW_DRIVER is not set |
741 | 758 | ||
742 | # | 759 | # |
743 | # TPM devices | 760 | # TPM devices |
744 | # | 761 | # |
745 | # CONFIG_TCG_TPM is not set | 762 | # CONFIG_TCG_TPM is not set |
746 | 763 | ||
747 | # | 764 | # |
748 | # I2C support | 765 | # I2C support |
749 | # | 766 | # |
750 | CONFIG_I2C=y | 767 | CONFIG_I2C=y |
751 | # CONFIG_I2C_CHARDEV is not set | 768 | # CONFIG_I2C_CHARDEV is not set |
752 | 769 | ||
753 | # | 770 | # |
754 | # I2C Algorithms | 771 | # I2C Algorithms |
755 | # | 772 | # |
756 | CONFIG_I2C_ALGOBIT=y | 773 | CONFIG_I2C_ALGOBIT=y |
757 | # CONFIG_I2C_ALGOPCF is not set | 774 | # CONFIG_I2C_ALGOPCF is not set |
758 | # CONFIG_I2C_ALGOPCA is not set | 775 | # CONFIG_I2C_ALGOPCA is not set |
759 | 776 | ||
760 | # | 777 | # |
761 | # I2C Hardware Bus support | 778 | # I2C Hardware Bus support |
762 | # | 779 | # |
763 | # CONFIG_I2C_ALI1535 is not set | 780 | # CONFIG_I2C_ALI1535 is not set |
764 | # CONFIG_I2C_ALI1563 is not set | 781 | # CONFIG_I2C_ALI1563 is not set |
765 | # CONFIG_I2C_ALI15X3 is not set | 782 | # CONFIG_I2C_ALI15X3 is not set |
766 | # CONFIG_I2C_AMD756 is not set | 783 | # CONFIG_I2C_AMD756 is not set |
767 | # CONFIG_I2C_AMD8111 is not set | 784 | # CONFIG_I2C_AMD8111 is not set |
768 | # CONFIG_I2C_I801 is not set | 785 | # CONFIG_I2C_I801 is not set |
769 | # CONFIG_I2C_I810 is not set | 786 | # CONFIG_I2C_I810 is not set |
770 | # CONFIG_I2C_PIIX4 is not set | 787 | # CONFIG_I2C_PIIX4 is not set |
771 | # CONFIG_I2C_NFORCE2 is not set | 788 | # CONFIG_I2C_NFORCE2 is not set |
772 | # CONFIG_I2C_OCORES is not set | 789 | # CONFIG_I2C_OCORES is not set |
773 | # CONFIG_I2C_PARPORT_LIGHT is not set | 790 | # CONFIG_I2C_PARPORT_LIGHT is not set |
774 | # CONFIG_I2C_PROSAVAGE is not set | 791 | # CONFIG_I2C_PROSAVAGE is not set |
775 | # CONFIG_I2C_SAVAGE4 is not set | 792 | # CONFIG_I2C_SAVAGE4 is not set |
776 | # CONFIG_I2C_SIS5595 is not set | 793 | # CONFIG_I2C_SIS5595 is not set |
777 | # CONFIG_I2C_SIS630 is not set | 794 | # CONFIG_I2C_SIS630 is not set |
778 | # CONFIG_I2C_SIS96X is not set | 795 | # CONFIG_I2C_SIS96X is not set |
779 | # CONFIG_I2C_STUB is not set | 796 | # CONFIG_I2C_STUB is not set |
780 | # CONFIG_I2C_VIA is not set | 797 | # CONFIG_I2C_VIA is not set |
781 | # CONFIG_I2C_VIAPRO is not set | 798 | # CONFIG_I2C_VIAPRO is not set |
782 | # CONFIG_I2C_VOODOO3 is not set | 799 | # CONFIG_I2C_VOODOO3 is not set |
783 | # CONFIG_I2C_PCA_ISA is not set | 800 | # CONFIG_I2C_PCA_ISA is not set |
784 | 801 | ||
785 | # | 802 | # |
786 | # Miscellaneous I2C Chip support | 803 | # Miscellaneous I2C Chip support |
787 | # | 804 | # |
788 | # CONFIG_SENSORS_DS1337 is not set | 805 | # CONFIG_SENSORS_DS1337 is not set |
789 | # CONFIG_SENSORS_DS1374 is not set | 806 | # CONFIG_SENSORS_DS1374 is not set |
790 | # CONFIG_SENSORS_EEPROM is not set | 807 | # CONFIG_SENSORS_EEPROM is not set |
791 | # CONFIG_SENSORS_PCF8574 is not set | 808 | # CONFIG_SENSORS_PCF8574 is not set |
792 | # CONFIG_SENSORS_PCA9539 is not set | 809 | # CONFIG_SENSORS_PCA9539 is not set |
793 | # CONFIG_SENSORS_PCF8591 is not set | 810 | # CONFIG_SENSORS_PCF8591 is not set |
794 | # CONFIG_SENSORS_MAX6875 is not set | 811 | # CONFIG_SENSORS_MAX6875 is not set |
795 | # CONFIG_I2C_DEBUG_CORE is not set | 812 | # CONFIG_I2C_DEBUG_CORE is not set |
796 | # CONFIG_I2C_DEBUG_ALGO is not set | 813 | # CONFIG_I2C_DEBUG_ALGO is not set |
797 | # CONFIG_I2C_DEBUG_BUS is not set | 814 | # CONFIG_I2C_DEBUG_BUS is not set |
798 | # CONFIG_I2C_DEBUG_CHIP is not set | 815 | # CONFIG_I2C_DEBUG_CHIP is not set |
799 | 816 | ||
800 | # | 817 | # |
801 | # SPI support | 818 | # SPI support |
802 | # | 819 | # |
803 | # CONFIG_SPI is not set | 820 | # CONFIG_SPI is not set |
804 | # CONFIG_SPI_MASTER is not set | 821 | # CONFIG_SPI_MASTER is not set |
805 | 822 | ||
806 | # | 823 | # |
807 | # Dallas's 1-wire bus | 824 | # Dallas's 1-wire bus |
808 | # | 825 | # |
809 | # CONFIG_W1 is not set | 826 | # CONFIG_W1 is not set |
810 | 827 | ||
811 | # | 828 | # |
812 | # Hardware Monitoring support | 829 | # Hardware Monitoring support |
813 | # | 830 | # |
814 | CONFIG_HWMON=y | 831 | CONFIG_HWMON=y |
815 | # CONFIG_HWMON_VID is not set | 832 | # CONFIG_HWMON_VID is not set |
816 | # CONFIG_SENSORS_ABITUGURU is not set | 833 | # CONFIG_SENSORS_ABITUGURU is not set |
817 | # CONFIG_SENSORS_ADM1021 is not set | 834 | # CONFIG_SENSORS_ADM1021 is not set |
818 | # CONFIG_SENSORS_ADM1025 is not set | 835 | # CONFIG_SENSORS_ADM1025 is not set |
819 | # CONFIG_SENSORS_ADM1026 is not set | 836 | # CONFIG_SENSORS_ADM1026 is not set |
820 | # CONFIG_SENSORS_ADM1031 is not set | 837 | # CONFIG_SENSORS_ADM1031 is not set |
821 | # CONFIG_SENSORS_ADM9240 is not set | 838 | # CONFIG_SENSORS_ADM9240 is not set |
822 | # CONFIG_SENSORS_ASB100 is not set | 839 | # CONFIG_SENSORS_ASB100 is not set |
823 | # CONFIG_SENSORS_ATXP1 is not set | 840 | # CONFIG_SENSORS_ATXP1 is not set |
824 | # CONFIG_SENSORS_DS1621 is not set | 841 | # CONFIG_SENSORS_DS1621 is not set |
825 | # CONFIG_SENSORS_F71805F is not set | 842 | # CONFIG_SENSORS_F71805F is not set |
826 | # CONFIG_SENSORS_FSCHER is not set | 843 | # CONFIG_SENSORS_FSCHER is not set |
827 | # CONFIG_SENSORS_FSCPOS is not set | 844 | # CONFIG_SENSORS_FSCPOS is not set |
828 | # CONFIG_SENSORS_GL518SM is not set | 845 | # CONFIG_SENSORS_GL518SM is not set |
829 | # CONFIG_SENSORS_GL520SM is not set | 846 | # CONFIG_SENSORS_GL520SM is not set |
830 | # CONFIG_SENSORS_IT87 is not set | 847 | # CONFIG_SENSORS_IT87 is not set |
831 | # CONFIG_SENSORS_LM63 is not set | 848 | # CONFIG_SENSORS_LM63 is not set |
832 | # CONFIG_SENSORS_LM75 is not set | 849 | # CONFIG_SENSORS_LM75 is not set |
833 | # CONFIG_SENSORS_LM77 is not set | 850 | # CONFIG_SENSORS_LM77 is not set |
834 | # CONFIG_SENSORS_LM78 is not set | 851 | # CONFIG_SENSORS_LM78 is not set |
835 | # CONFIG_SENSORS_LM80 is not set | 852 | # CONFIG_SENSORS_LM80 is not set |
836 | # CONFIG_SENSORS_LM83 is not set | 853 | # CONFIG_SENSORS_LM83 is not set |
837 | # CONFIG_SENSORS_LM85 is not set | 854 | # CONFIG_SENSORS_LM85 is not set |
838 | # CONFIG_SENSORS_LM87 is not set | 855 | # CONFIG_SENSORS_LM87 is not set |
839 | # CONFIG_SENSORS_LM90 is not set | 856 | # CONFIG_SENSORS_LM90 is not set |
840 | # CONFIG_SENSORS_LM92 is not set | 857 | # CONFIG_SENSORS_LM92 is not set |
841 | # CONFIG_SENSORS_MAX1619 is not set | 858 | # CONFIG_SENSORS_MAX1619 is not set |
842 | # CONFIG_SENSORS_PC87360 is not set | 859 | # CONFIG_SENSORS_PC87360 is not set |
843 | # CONFIG_SENSORS_PC87427 is not set | 860 | # CONFIG_SENSORS_PC87427 is not set |
844 | # CONFIG_SENSORS_SIS5595 is not set | 861 | # CONFIG_SENSORS_SIS5595 is not set |
845 | # CONFIG_SENSORS_SMSC47M1 is not set | 862 | # CONFIG_SENSORS_SMSC47M1 is not set |
846 | # CONFIG_SENSORS_SMSC47M192 is not set | 863 | # CONFIG_SENSORS_SMSC47M192 is not set |
847 | # CONFIG_SENSORS_SMSC47B397 is not set | 864 | # CONFIG_SENSORS_SMSC47B397 is not set |
848 | # CONFIG_SENSORS_VIA686A is not set | 865 | # CONFIG_SENSORS_VIA686A is not set |
849 | # CONFIG_SENSORS_VT1211 is not set | 866 | # CONFIG_SENSORS_VT1211 is not set |
850 | # CONFIG_SENSORS_VT8231 is not set | 867 | # CONFIG_SENSORS_VT8231 is not set |
851 | # CONFIG_SENSORS_W83781D is not set | 868 | # CONFIG_SENSORS_W83781D is not set |
852 | # CONFIG_SENSORS_W83791D is not set | 869 | # CONFIG_SENSORS_W83791D is not set |
853 | # CONFIG_SENSORS_W83792D is not set | 870 | # CONFIG_SENSORS_W83792D is not set |
854 | # CONFIG_SENSORS_W83793 is not set | 871 | # CONFIG_SENSORS_W83793 is not set |
855 | # CONFIG_SENSORS_W83L785TS is not set | 872 | # CONFIG_SENSORS_W83L785TS is not set |
856 | # CONFIG_SENSORS_W83627HF is not set | 873 | # CONFIG_SENSORS_W83627HF is not set |
857 | # CONFIG_SENSORS_W83627EHF is not set | 874 | # CONFIG_SENSORS_W83627EHF is not set |
858 | # CONFIG_HWMON_DEBUG_CHIP is not set | 875 | # CONFIG_HWMON_DEBUG_CHIP is not set |
859 | 876 | ||
860 | # | 877 | # |
861 | # Multimedia devices | 878 | # Multimedia devices |
862 | # | 879 | # |
863 | # CONFIG_VIDEO_DEV is not set | 880 | # CONFIG_VIDEO_DEV is not set |
864 | 881 | ||
865 | # | 882 | # |
866 | # Digital Video Broadcasting Devices | 883 | # Digital Video Broadcasting Devices |
867 | # | 884 | # |
868 | # CONFIG_DVB is not set | 885 | # CONFIG_DVB is not set |
869 | # CONFIG_USB_DABUSB is not set | 886 | # CONFIG_USB_DABUSB is not set |
870 | 887 | ||
871 | # | 888 | # |
872 | # Graphics support | 889 | # Graphics support |
873 | # | 890 | # |
874 | # CONFIG_FIRMWARE_EDID is not set | 891 | # CONFIG_FIRMWARE_EDID is not set |
875 | CONFIG_FB=y | 892 | CONFIG_FB=y |
876 | CONFIG_FB_DDC=y | 893 | CONFIG_FB_DDC=y |
877 | CONFIG_FB_CFB_FILLRECT=y | 894 | CONFIG_FB_CFB_FILLRECT=y |
878 | CONFIG_FB_CFB_COPYAREA=y | 895 | CONFIG_FB_CFB_COPYAREA=y |
879 | CONFIG_FB_CFB_IMAGEBLIT=y | 896 | CONFIG_FB_CFB_IMAGEBLIT=y |
880 | # CONFIG_FB_MACMODES is not set | 897 | # CONFIG_FB_MACMODES is not set |
881 | # CONFIG_FB_BACKLIGHT is not set | 898 | # CONFIG_FB_BACKLIGHT is not set |
882 | CONFIG_FB_MODE_HELPERS=y | 899 | CONFIG_FB_MODE_HELPERS=y |
883 | CONFIG_FB_TILEBLITTING=y | 900 | CONFIG_FB_TILEBLITTING=y |
884 | # CONFIG_FB_CIRRUS is not set | 901 | # CONFIG_FB_CIRRUS is not set |
885 | # CONFIG_FB_PM2 is not set | 902 | # CONFIG_FB_PM2 is not set |
886 | # CONFIG_FB_ASILIANT is not set | 903 | # CONFIG_FB_ASILIANT is not set |
887 | # CONFIG_FB_IMSTT is not set | 904 | # CONFIG_FB_IMSTT is not set |
888 | # CONFIG_FB_SBUS is not set | 905 | # CONFIG_FB_SBUS is not set |
889 | # CONFIG_FB_S1D13XXX is not set | 906 | # CONFIG_FB_S1D13XXX is not set |
890 | # CONFIG_FB_NVIDIA is not set | 907 | # CONFIG_FB_NVIDIA is not set |
891 | # CONFIG_FB_RIVA is not set | 908 | # CONFIG_FB_RIVA is not set |
892 | # CONFIG_FB_MATROX is not set | 909 | # CONFIG_FB_MATROX is not set |
893 | CONFIG_FB_RADEON=y | 910 | CONFIG_FB_RADEON=y |
894 | CONFIG_FB_RADEON_I2C=y | 911 | CONFIG_FB_RADEON_I2C=y |
895 | # CONFIG_FB_RADEON_DEBUG is not set | 912 | # CONFIG_FB_RADEON_DEBUG is not set |
896 | # CONFIG_FB_ATY128 is not set | 913 | # CONFIG_FB_ATY128 is not set |
897 | # CONFIG_FB_ATY is not set | 914 | # CONFIG_FB_ATY is not set |
898 | # CONFIG_FB_SAVAGE is not set | 915 | # CONFIG_FB_SAVAGE is not set |
899 | # CONFIG_FB_SIS is not set | 916 | # CONFIG_FB_SIS is not set |
900 | # CONFIG_FB_NEOMAGIC is not set | 917 | # CONFIG_FB_NEOMAGIC is not set |
901 | # CONFIG_FB_KYRO is not set | 918 | # CONFIG_FB_KYRO is not set |
902 | # CONFIG_FB_3DFX is not set | 919 | # CONFIG_FB_3DFX is not set |
903 | # CONFIG_FB_VOODOO1 is not set | 920 | # CONFIG_FB_VOODOO1 is not set |
904 | # CONFIG_FB_TRIDENT is not set | 921 | # CONFIG_FB_TRIDENT is not set |
905 | # CONFIG_FB_PCI is not set | 922 | # CONFIG_FB_PCI is not set |
906 | # CONFIG_FB_VIRTUAL is not set | 923 | # CONFIG_FB_VIRTUAL is not set |
907 | 924 | ||
908 | # | 925 | # |
909 | # Console display driver support | 926 | # Console display driver support |
910 | # | 927 | # |
911 | # CONFIG_PROM_CONSOLE is not set | 928 | # CONFIG_PROM_CONSOLE is not set |
912 | CONFIG_DUMMY_CONSOLE=y | 929 | CONFIG_DUMMY_CONSOLE=y |
913 | CONFIG_FRAMEBUFFER_CONSOLE=y | 930 | CONFIG_FRAMEBUFFER_CONSOLE=y |
914 | # CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set | 931 | # CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set |
915 | CONFIG_FONTS=y | 932 | CONFIG_FONTS=y |
916 | # CONFIG_FONT_8x8 is not set | 933 | # CONFIG_FONT_8x8 is not set |
917 | # CONFIG_FONT_8x16 is not set | 934 | # CONFIG_FONT_8x16 is not set |
918 | # CONFIG_FONT_6x11 is not set | 935 | # CONFIG_FONT_6x11 is not set |
919 | # CONFIG_FONT_7x14 is not set | 936 | # CONFIG_FONT_7x14 is not set |
920 | # CONFIG_FONT_PEARL_8x8 is not set | 937 | # CONFIG_FONT_PEARL_8x8 is not set |
921 | # CONFIG_FONT_ACORN_8x8 is not set | 938 | # CONFIG_FONT_ACORN_8x8 is not set |
922 | CONFIG_FONT_SUN8x16=y | 939 | CONFIG_FONT_SUN8x16=y |
923 | # CONFIG_FONT_SUN12x22 is not set | 940 | # CONFIG_FONT_SUN12x22 is not set |
924 | # CONFIG_FONT_10x18 is not set | 941 | # CONFIG_FONT_10x18 is not set |
925 | 942 | ||
926 | # | 943 | # |
927 | # Logo configuration | 944 | # Logo configuration |
928 | # | 945 | # |
929 | CONFIG_LOGO=y | 946 | CONFIG_LOGO=y |
930 | # CONFIG_LOGO_LINUX_MONO is not set | 947 | # CONFIG_LOGO_LINUX_MONO is not set |
931 | # CONFIG_LOGO_LINUX_VGA16 is not set | 948 | # CONFIG_LOGO_LINUX_VGA16 is not set |
932 | # CONFIG_LOGO_LINUX_CLUT224 is not set | 949 | # CONFIG_LOGO_LINUX_CLUT224 is not set |
933 | CONFIG_LOGO_SUN_CLUT224=y | 950 | CONFIG_LOGO_SUN_CLUT224=y |
934 | # CONFIG_BACKLIGHT_LCD_SUPPORT is not set | 951 | # CONFIG_BACKLIGHT_LCD_SUPPORT is not set |
935 | 952 | ||
936 | # | 953 | # |
937 | # Sound | 954 | # Sound |
938 | # | 955 | # |
939 | CONFIG_SOUND=m | 956 | CONFIG_SOUND=m |
940 | 957 | ||
941 | # | 958 | # |
942 | # Advanced Linux Sound Architecture | 959 | # Advanced Linux Sound Architecture |
943 | # | 960 | # |
944 | CONFIG_SND=m | 961 | CONFIG_SND=m |
945 | CONFIG_SND_TIMER=m | 962 | CONFIG_SND_TIMER=m |
946 | CONFIG_SND_PCM=m | 963 | CONFIG_SND_PCM=m |
947 | CONFIG_SND_RAWMIDI=m | 964 | CONFIG_SND_RAWMIDI=m |
948 | CONFIG_SND_SEQUENCER=m | 965 | CONFIG_SND_SEQUENCER=m |
949 | CONFIG_SND_SEQ_DUMMY=m | 966 | CONFIG_SND_SEQ_DUMMY=m |
950 | CONFIG_SND_OSSEMUL=y | 967 | CONFIG_SND_OSSEMUL=y |
951 | CONFIG_SND_MIXER_OSS=m | 968 | CONFIG_SND_MIXER_OSS=m |
952 | CONFIG_SND_PCM_OSS=m | 969 | CONFIG_SND_PCM_OSS=m |
953 | CONFIG_SND_PCM_OSS_PLUGINS=y | 970 | CONFIG_SND_PCM_OSS_PLUGINS=y |
954 | CONFIG_SND_SEQUENCER_OSS=y | 971 | CONFIG_SND_SEQUENCER_OSS=y |
955 | # CONFIG_SND_RTCTIMER is not set | 972 | # CONFIG_SND_RTCTIMER is not set |
956 | # CONFIG_SND_DYNAMIC_MINORS is not set | 973 | # CONFIG_SND_DYNAMIC_MINORS is not set |
957 | CONFIG_SND_SUPPORT_OLD_API=y | 974 | CONFIG_SND_SUPPORT_OLD_API=y |
958 | CONFIG_SND_VERBOSE_PROCFS=y | 975 | CONFIG_SND_VERBOSE_PROCFS=y |
959 | # CONFIG_SND_VERBOSE_PRINTK is not set | 976 | # CONFIG_SND_VERBOSE_PRINTK is not set |
960 | # CONFIG_SND_DEBUG is not set | 977 | # CONFIG_SND_DEBUG is not set |
961 | 978 | ||
962 | # | 979 | # |
963 | # Generic devices | 980 | # Generic devices |
964 | # | 981 | # |
965 | CONFIG_SND_MPU401_UART=m | 982 | CONFIG_SND_MPU401_UART=m |
966 | CONFIG_SND_AC97_CODEC=m | 983 | CONFIG_SND_AC97_CODEC=m |
967 | CONFIG_SND_DUMMY=m | 984 | CONFIG_SND_DUMMY=m |
968 | CONFIG_SND_VIRMIDI=m | 985 | CONFIG_SND_VIRMIDI=m |
969 | CONFIG_SND_MTPAV=m | 986 | CONFIG_SND_MTPAV=m |
970 | # CONFIG_SND_SERIAL_U16550 is not set | 987 | # CONFIG_SND_SERIAL_U16550 is not set |
971 | # CONFIG_SND_MPU401 is not set | 988 | # CONFIG_SND_MPU401 is not set |
972 | 989 | ||
973 | # | 990 | # |
974 | # PCI devices | 991 | # PCI devices |
975 | # | 992 | # |
976 | # CONFIG_SND_AD1889 is not set | 993 | # CONFIG_SND_AD1889 is not set |
977 | # CONFIG_SND_ALS300 is not set | 994 | # CONFIG_SND_ALS300 is not set |
978 | CONFIG_SND_ALI5451=m | 995 | CONFIG_SND_ALI5451=m |
979 | # CONFIG_SND_ATIIXP is not set | 996 | # CONFIG_SND_ATIIXP is not set |
980 | # CONFIG_SND_ATIIXP_MODEM is not set | 997 | # CONFIG_SND_ATIIXP_MODEM is not set |
981 | # CONFIG_SND_AU8810 is not set | 998 | # CONFIG_SND_AU8810 is not set |
982 | # CONFIG_SND_AU8820 is not set | 999 | # CONFIG_SND_AU8820 is not set |
983 | # CONFIG_SND_AU8830 is not set | 1000 | # CONFIG_SND_AU8830 is not set |
984 | # CONFIG_SND_AZT3328 is not set | 1001 | # CONFIG_SND_AZT3328 is not set |
985 | # CONFIG_SND_BT87X is not set | 1002 | # CONFIG_SND_BT87X is not set |
986 | # CONFIG_SND_CA0106 is not set | 1003 | # CONFIG_SND_CA0106 is not set |
987 | # CONFIG_SND_CMIPCI is not set | 1004 | # CONFIG_SND_CMIPCI is not set |
988 | # CONFIG_SND_CS4281 is not set | 1005 | # CONFIG_SND_CS4281 is not set |
989 | # CONFIG_SND_CS46XX is not set | 1006 | # CONFIG_SND_CS46XX is not set |
990 | # CONFIG_SND_DARLA20 is not set | 1007 | # CONFIG_SND_DARLA20 is not set |
991 | # CONFIG_SND_GINA20 is not set | 1008 | # CONFIG_SND_GINA20 is not set |
992 | # CONFIG_SND_LAYLA20 is not set | 1009 | # CONFIG_SND_LAYLA20 is not set |
993 | # CONFIG_SND_DARLA24 is not set | 1010 | # CONFIG_SND_DARLA24 is not set |
994 | # CONFIG_SND_GINA24 is not set | 1011 | # CONFIG_SND_GINA24 is not set |
995 | # CONFIG_SND_LAYLA24 is not set | 1012 | # CONFIG_SND_LAYLA24 is not set |
996 | # CONFIG_SND_MONA is not set | 1013 | # CONFIG_SND_MONA is not set |
997 | # CONFIG_SND_MIA is not set | 1014 | # CONFIG_SND_MIA is not set |
998 | # CONFIG_SND_ECHO3G is not set | 1015 | # CONFIG_SND_ECHO3G is not set |
999 | # CONFIG_SND_INDIGO is not set | 1016 | # CONFIG_SND_INDIGO is not set |
1000 | # CONFIG_SND_INDIGOIO is not set | 1017 | # CONFIG_SND_INDIGOIO is not set |
1001 | # CONFIG_SND_INDIGODJ is not set | 1018 | # CONFIG_SND_INDIGODJ is not set |
1002 | # CONFIG_SND_EMU10K1 is not set | 1019 | # CONFIG_SND_EMU10K1 is not set |
1003 | # CONFIG_SND_EMU10K1X is not set | 1020 | # CONFIG_SND_EMU10K1X is not set |
1004 | # CONFIG_SND_ENS1370 is not set | 1021 | # CONFIG_SND_ENS1370 is not set |
1005 | # CONFIG_SND_ENS1371 is not set | 1022 | # CONFIG_SND_ENS1371 is not set |
1006 | # CONFIG_SND_ES1938 is not set | 1023 | # CONFIG_SND_ES1938 is not set |
1007 | # CONFIG_SND_ES1968 is not set | 1024 | # CONFIG_SND_ES1968 is not set |
1008 | # CONFIG_SND_FM801 is not set | 1025 | # CONFIG_SND_FM801 is not set |
1009 | # CONFIG_SND_HDA_INTEL is not set | 1026 | # CONFIG_SND_HDA_INTEL is not set |
1010 | # CONFIG_SND_HDSP is not set | 1027 | # CONFIG_SND_HDSP is not set |
1011 | # CONFIG_SND_HDSPM is not set | 1028 | # CONFIG_SND_HDSPM is not set |
1012 | # CONFIG_SND_ICE1712 is not set | 1029 | # CONFIG_SND_ICE1712 is not set |
1013 | # CONFIG_SND_ICE1724 is not set | 1030 | # CONFIG_SND_ICE1724 is not set |
1014 | # CONFIG_SND_INTEL8X0 is not set | 1031 | # CONFIG_SND_INTEL8X0 is not set |
1015 | # CONFIG_SND_INTEL8X0M is not set | 1032 | # CONFIG_SND_INTEL8X0M is not set |
1016 | # CONFIG_SND_KORG1212 is not set | 1033 | # CONFIG_SND_KORG1212 is not set |
1017 | # CONFIG_SND_MAESTRO3 is not set | 1034 | # CONFIG_SND_MAESTRO3 is not set |
1018 | # CONFIG_SND_MIXART is not set | 1035 | # CONFIG_SND_MIXART is not set |
1019 | # CONFIG_SND_NM256 is not set | 1036 | # CONFIG_SND_NM256 is not set |
1020 | # CONFIG_SND_PCXHR is not set | 1037 | # CONFIG_SND_PCXHR is not set |
1021 | # CONFIG_SND_RIPTIDE is not set | 1038 | # CONFIG_SND_RIPTIDE is not set |
1022 | # CONFIG_SND_RME32 is not set | 1039 | # CONFIG_SND_RME32 is not set |
1023 | # CONFIG_SND_RME96 is not set | 1040 | # CONFIG_SND_RME96 is not set |
1024 | # CONFIG_SND_RME9652 is not set | 1041 | # CONFIG_SND_RME9652 is not set |
1025 | # CONFIG_SND_SONICVIBES is not set | 1042 | # CONFIG_SND_SONICVIBES is not set |
1026 | # CONFIG_SND_TRIDENT is not set | 1043 | # CONFIG_SND_TRIDENT is not set |
1027 | # CONFIG_SND_VIA82XX is not set | 1044 | # CONFIG_SND_VIA82XX is not set |
1028 | # CONFIG_SND_VIA82XX_MODEM is not set | 1045 | # CONFIG_SND_VIA82XX_MODEM is not set |
1029 | # CONFIG_SND_VX222 is not set | 1046 | # CONFIG_SND_VX222 is not set |
1030 | # CONFIG_SND_YMFPCI is not set | 1047 | # CONFIG_SND_YMFPCI is not set |
1031 | # CONFIG_SND_AC97_POWER_SAVE is not set | 1048 | # CONFIG_SND_AC97_POWER_SAVE is not set |
1032 | 1049 | ||
1033 | # | 1050 | # |
1034 | # USB devices | 1051 | # USB devices |
1035 | # | 1052 | # |
1036 | # CONFIG_SND_USB_AUDIO is not set | 1053 | # CONFIG_SND_USB_AUDIO is not set |
1037 | 1054 | ||
1038 | # | 1055 | # |
1039 | # ALSA Sparc devices | 1056 | # ALSA Sparc devices |
1040 | # | 1057 | # |
1041 | # CONFIG_SND_SUN_AMD7930 is not set | 1058 | # CONFIG_SND_SUN_AMD7930 is not set |
1042 | CONFIG_SND_SUN_CS4231=m | 1059 | CONFIG_SND_SUN_CS4231=m |
1043 | # CONFIG_SND_SUN_DBRI is not set | 1060 | # CONFIG_SND_SUN_DBRI is not set |
1044 | 1061 | ||
1045 | # | 1062 | # |
1063 | # SoC audio support | ||
1064 | # | ||
1065 | # CONFIG_SND_SOC is not set | ||
1066 | |||
1067 | # | ||
1046 | # Open Sound System | 1068 | # Open Sound System |
1047 | # | 1069 | # |
1048 | # CONFIG_SOUND_PRIME is not set | 1070 | # CONFIG_SOUND_PRIME is not set |
1049 | CONFIG_AC97_BUS=m | 1071 | CONFIG_AC97_BUS=m |
1050 | 1072 | ||
1051 | # | 1073 | # |
1052 | # HID Devices | 1074 | # HID Devices |
1053 | # | 1075 | # |
1054 | CONFIG_HID=y | 1076 | CONFIG_HID=y |
1077 | # CONFIG_HID_DEBUG is not set | ||
1055 | 1078 | ||
1056 | # | 1079 | # |
1057 | # USB support | 1080 | # USB support |
1058 | # | 1081 | # |
1059 | CONFIG_USB_ARCH_HAS_HCD=y | 1082 | CONFIG_USB_ARCH_HAS_HCD=y |
1060 | CONFIG_USB_ARCH_HAS_OHCI=y | 1083 | CONFIG_USB_ARCH_HAS_OHCI=y |
1061 | CONFIG_USB_ARCH_HAS_EHCI=y | 1084 | CONFIG_USB_ARCH_HAS_EHCI=y |
1062 | CONFIG_USB=y | 1085 | CONFIG_USB=y |
1063 | # CONFIG_USB_DEBUG is not set | 1086 | # CONFIG_USB_DEBUG is not set |
1064 | 1087 | ||
1065 | # | 1088 | # |
1066 | # Miscellaneous USB options | 1089 | # Miscellaneous USB options |
1067 | # | 1090 | # |
1068 | CONFIG_USB_DEVICEFS=y | 1091 | CONFIG_USB_DEVICEFS=y |
1069 | # CONFIG_USB_BANDWIDTH is not set | ||
1070 | # CONFIG_USB_DYNAMIC_MINORS is not set | 1092 | # CONFIG_USB_DYNAMIC_MINORS is not set |
1071 | # CONFIG_USB_MULTITHREAD_PROBE is not set | ||
1072 | # CONFIG_USB_OTG is not set | 1093 | # CONFIG_USB_OTG is not set |
1073 | 1094 | ||
1074 | # | 1095 | # |
1075 | # USB Host Controller Drivers | 1096 | # USB Host Controller Drivers |
1076 | # | 1097 | # |
1077 | CONFIG_USB_EHCI_HCD=m | 1098 | CONFIG_USB_EHCI_HCD=m |
1078 | # CONFIG_USB_EHCI_SPLIT_ISO is not set | 1099 | # CONFIG_USB_EHCI_SPLIT_ISO is not set |
1079 | # CONFIG_USB_EHCI_ROOT_HUB_TT is not set | 1100 | # CONFIG_USB_EHCI_ROOT_HUB_TT is not set |
1080 | # CONFIG_USB_EHCI_TT_NEWSCHED is not set | 1101 | # CONFIG_USB_EHCI_TT_NEWSCHED is not set |
1102 | # CONFIG_USB_EHCI_BIG_ENDIAN_MMIO is not set | ||
1081 | # CONFIG_USB_ISP116X_HCD is not set | 1103 | # CONFIG_USB_ISP116X_HCD is not set |
1082 | CONFIG_USB_OHCI_HCD=y | 1104 | CONFIG_USB_OHCI_HCD=y |
1083 | # CONFIG_USB_OHCI_BIG_ENDIAN is not set | 1105 | # CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set |
1106 | # CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set | ||
1084 | CONFIG_USB_OHCI_LITTLE_ENDIAN=y | 1107 | CONFIG_USB_OHCI_LITTLE_ENDIAN=y |
1085 | CONFIG_USB_UHCI_HCD=m | 1108 | CONFIG_USB_UHCI_HCD=m |
1086 | # CONFIG_USB_SL811_HCD is not set | 1109 | # CONFIG_USB_SL811_HCD is not set |
1087 | 1110 | ||
1088 | # | 1111 | # |
1089 | # USB Device Class drivers | 1112 | # USB Device Class drivers |
1090 | # | 1113 | # |
1091 | # CONFIG_USB_ACM is not set | 1114 | # CONFIG_USB_ACM is not set |
1092 | # CONFIG_USB_PRINTER is not set | 1115 | # CONFIG_USB_PRINTER is not set |
1093 | 1116 | ||
1094 | # | 1117 | # |
1095 | # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' | 1118 | # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' |
1096 | # | 1119 | # |
1097 | 1120 | ||
1098 | # | 1121 | # |
1099 | # may also be needed; see USB_STORAGE Help for more information | 1122 | # may also be needed; see USB_STORAGE Help for more information |
1100 | # | 1123 | # |
1101 | CONFIG_USB_STORAGE=m | 1124 | CONFIG_USB_STORAGE=m |
1102 | # CONFIG_USB_STORAGE_DEBUG is not set | 1125 | # CONFIG_USB_STORAGE_DEBUG is not set |
1103 | # CONFIG_USB_STORAGE_DATAFAB is not set | 1126 | # CONFIG_USB_STORAGE_DATAFAB is not set |
1104 | # CONFIG_USB_STORAGE_FREECOM is not set | 1127 | # CONFIG_USB_STORAGE_FREECOM is not set |
1105 | # CONFIG_USB_STORAGE_ISD200 is not set | 1128 | # CONFIG_USB_STORAGE_ISD200 is not set |
1106 | # CONFIG_USB_STORAGE_DPCM is not set | 1129 | # CONFIG_USB_STORAGE_DPCM is not set |
1107 | # CONFIG_USB_STORAGE_USBAT is not set | 1130 | # CONFIG_USB_STORAGE_USBAT is not set |
1108 | # CONFIG_USB_STORAGE_SDDR09 is not set | 1131 | # CONFIG_USB_STORAGE_SDDR09 is not set |
1109 | # CONFIG_USB_STORAGE_SDDR55 is not set | 1132 | # CONFIG_USB_STORAGE_SDDR55 is not set |
1110 | # CONFIG_USB_STORAGE_JUMPSHOT is not set | 1133 | # CONFIG_USB_STORAGE_JUMPSHOT is not set |
1111 | # CONFIG_USB_STORAGE_ALAUDA is not set | 1134 | # CONFIG_USB_STORAGE_ALAUDA is not set |
1112 | # CONFIG_USB_STORAGE_ONETOUCH is not set | 1135 | # CONFIG_USB_STORAGE_ONETOUCH is not set |
1113 | # CONFIG_USB_STORAGE_KARMA is not set | 1136 | # CONFIG_USB_STORAGE_KARMA is not set |
1114 | # CONFIG_USB_LIBUSUAL is not set | 1137 | # CONFIG_USB_LIBUSUAL is not set |
1115 | 1138 | ||
1116 | # | 1139 | # |
1117 | # USB Input Devices | 1140 | # USB Input Devices |
1118 | # | 1141 | # |
1119 | CONFIG_USB_HID=y | 1142 | CONFIG_USB_HID=y |
1120 | # CONFIG_USB_HIDINPUT_POWERBOOK is not set | 1143 | # CONFIG_USB_HIDINPUT_POWERBOOK is not set |
1121 | # CONFIG_HID_FF is not set | 1144 | # CONFIG_HID_FF is not set |
1122 | CONFIG_USB_HIDDEV=y | 1145 | CONFIG_USB_HIDDEV=y |
1123 | # CONFIG_USB_AIPTEK is not set | 1146 | # CONFIG_USB_AIPTEK is not set |
1124 | # CONFIG_USB_WACOM is not set | 1147 | # CONFIG_USB_WACOM is not set |
1125 | # CONFIG_USB_ACECAD is not set | 1148 | # CONFIG_USB_ACECAD is not set |
1126 | # CONFIG_USB_KBTAB is not set | 1149 | # CONFIG_USB_KBTAB is not set |
1127 | # CONFIG_USB_POWERMATE is not set | 1150 | # CONFIG_USB_POWERMATE is not set |
1128 | # CONFIG_USB_TOUCHSCREEN is not set | 1151 | # CONFIG_USB_TOUCHSCREEN is not set |
1129 | # CONFIG_USB_YEALINK is not set | 1152 | # CONFIG_USB_YEALINK is not set |
1130 | # CONFIG_USB_XPAD is not set | 1153 | # CONFIG_USB_XPAD is not set |
1131 | # CONFIG_USB_ATI_REMOTE is not set | 1154 | # CONFIG_USB_ATI_REMOTE is not set |
1132 | # CONFIG_USB_ATI_REMOTE2 is not set | 1155 | # CONFIG_USB_ATI_REMOTE2 is not set |
1133 | # CONFIG_USB_KEYSPAN_REMOTE is not set | 1156 | # CONFIG_USB_KEYSPAN_REMOTE is not set |
1134 | # CONFIG_USB_APPLETOUCH is not set | 1157 | # CONFIG_USB_APPLETOUCH is not set |
1158 | # CONFIG_USB_GTCO is not set | ||
1135 | 1159 | ||
1136 | # | 1160 | # |
1137 | # USB Imaging devices | 1161 | # USB Imaging devices |
1138 | # | 1162 | # |
1139 | # CONFIG_USB_MDC800 is not set | 1163 | # CONFIG_USB_MDC800 is not set |
1140 | # CONFIG_USB_MICROTEK is not set | 1164 | # CONFIG_USB_MICROTEK is not set |
1141 | 1165 | ||
1142 | # | 1166 | # |
1143 | # USB Network Adapters | 1167 | # USB Network Adapters |
1144 | # | 1168 | # |
1145 | # CONFIG_USB_CATC is not set | 1169 | # CONFIG_USB_CATC is not set |
1146 | # CONFIG_USB_KAWETH is not set | 1170 | # CONFIG_USB_KAWETH is not set |
1147 | # CONFIG_USB_PEGASUS is not set | 1171 | # CONFIG_USB_PEGASUS is not set |
1148 | # CONFIG_USB_RTL8150 is not set | 1172 | # CONFIG_USB_RTL8150 is not set |
1149 | # CONFIG_USB_USBNET_MII is not set | 1173 | # CONFIG_USB_USBNET_MII is not set |
1150 | # CONFIG_USB_USBNET is not set | 1174 | # CONFIG_USB_USBNET is not set |
1151 | # CONFIG_USB_MON is not set | 1175 | # CONFIG_USB_MON is not set |
1152 | 1176 | ||
1153 | # | 1177 | # |
1154 | # USB port drivers | 1178 | # USB port drivers |
1155 | # | 1179 | # |
1156 | 1180 | ||
1157 | # | 1181 | # |
1158 | # USB Serial Converter support | 1182 | # USB Serial Converter support |
1159 | # | 1183 | # |
1160 | # CONFIG_USB_SERIAL is not set | 1184 | # CONFIG_USB_SERIAL is not set |
1161 | 1185 | ||
1162 | # | 1186 | # |
1163 | # USB Miscellaneous drivers | 1187 | # USB Miscellaneous drivers |
1164 | # | 1188 | # |
1165 | # CONFIG_USB_EMI62 is not set | 1189 | # CONFIG_USB_EMI62 is not set |
1166 | # CONFIG_USB_EMI26 is not set | 1190 | # CONFIG_USB_EMI26 is not set |
1167 | # CONFIG_USB_ADUTUX is not set | 1191 | # CONFIG_USB_ADUTUX is not set |
1168 | # CONFIG_USB_AUERSWALD is not set | 1192 | # CONFIG_USB_AUERSWALD is not set |
1169 | # CONFIG_USB_RIO500 is not set | 1193 | # CONFIG_USB_RIO500 is not set |
1170 | # CONFIG_USB_LEGOTOWER is not set | 1194 | # CONFIG_USB_LEGOTOWER is not set |
1171 | # CONFIG_USB_LCD is not set | 1195 | # CONFIG_USB_LCD is not set |
1172 | # CONFIG_USB_LED is not set | 1196 | # CONFIG_USB_LED is not set |
1173 | # CONFIG_USB_CYPRESS_CY7C63 is not set | 1197 | # CONFIG_USB_CYPRESS_CY7C63 is not set |
1174 | # CONFIG_USB_CYTHERM is not set | 1198 | # CONFIG_USB_CYTHERM is not set |
1175 | # CONFIG_USB_PHIDGET is not set | 1199 | # CONFIG_USB_PHIDGET is not set |
1176 | # CONFIG_USB_IDMOUSE is not set | 1200 | # CONFIG_USB_IDMOUSE is not set |
1177 | # CONFIG_USB_FTDI_ELAN is not set | 1201 | # CONFIG_USB_FTDI_ELAN is not set |
1178 | # CONFIG_USB_APPLEDISPLAY is not set | 1202 | # CONFIG_USB_APPLEDISPLAY is not set |
1179 | # CONFIG_USB_SISUSBVGA is not set | 1203 | # CONFIG_USB_SISUSBVGA is not set |
1180 | # CONFIG_USB_LD is not set | 1204 | # CONFIG_USB_LD is not set |
1181 | # CONFIG_USB_TRANCEVIBRATOR is not set | 1205 | # CONFIG_USB_TRANCEVIBRATOR is not set |
1182 | # CONFIG_USB_TEST is not set | 1206 | # CONFIG_USB_TEST is not set |
1183 | 1207 | ||
1184 | # | 1208 | # |
1185 | # USB DSL modem support | 1209 | # USB DSL modem support |
1186 | # | 1210 | # |
1187 | 1211 | ||
1188 | # | 1212 | # |
1189 | # USB Gadget Support | 1213 | # USB Gadget Support |
1190 | # | 1214 | # |
1191 | # CONFIG_USB_GADGET is not set | 1215 | # CONFIG_USB_GADGET is not set |
1192 | 1216 | ||
1193 | # | 1217 | # |
1194 | # MMC/SD Card support | 1218 | # MMC/SD Card support |
1195 | # | 1219 | # |
1196 | # CONFIG_MMC is not set | 1220 | # CONFIG_MMC is not set |
1197 | 1221 | ||
1198 | # | 1222 | # |
1199 | # LED devices | 1223 | # LED devices |
1200 | # | 1224 | # |
1201 | # CONFIG_NEW_LEDS is not set | 1225 | # CONFIG_NEW_LEDS is not set |
1202 | 1226 | ||
1203 | # | 1227 | # |
1204 | # LED drivers | 1228 | # LED drivers |
1205 | # | 1229 | # |
1206 | 1230 | ||
1207 | # | 1231 | # |
1208 | # LED Triggers | 1232 | # LED Triggers |
1209 | # | 1233 | # |
1210 | 1234 | ||
1211 | # | 1235 | # |
1212 | # InfiniBand support | 1236 | # InfiniBand support |
1213 | # | 1237 | # |
1214 | # CONFIG_INFINIBAND is not set | 1238 | # CONFIG_INFINIBAND is not set |
1215 | 1239 | ||
1216 | # | 1240 | # |
1217 | # EDAC - error detection and reporting (RAS) (EXPERIMENTAL) | 1241 | # EDAC - error detection and reporting (RAS) (EXPERIMENTAL) |
1218 | # | 1242 | # |
1219 | 1243 | ||
1220 | # | 1244 | # |
1221 | # Real Time Clock | 1245 | # Real Time Clock |
1222 | # | 1246 | # |
1223 | # CONFIG_RTC_CLASS is not set | 1247 | # CONFIG_RTC_CLASS is not set |
1224 | 1248 | ||
1225 | # | 1249 | # |
1226 | # DMA Engine support | 1250 | # DMA Engine support |
1227 | # | 1251 | # |
1228 | # CONFIG_DMA_ENGINE is not set | 1252 | # CONFIG_DMA_ENGINE is not set |
1229 | 1253 | ||
1230 | # | 1254 | # |
1231 | # DMA Clients | 1255 | # DMA Clients |
1232 | # | 1256 | # |
1233 | 1257 | ||
1234 | # | 1258 | # |
1235 | # DMA Devices | 1259 | # DMA Devices |
1236 | # | 1260 | # |
1237 | 1261 | ||
1238 | # | 1262 | # |
1239 | # Virtualization | 1263 | # Virtualization |
1240 | # | 1264 | # |
1241 | 1265 | ||
1242 | # | 1266 | # |
1243 | # Misc Linux/SPARC drivers | 1267 | # Misc Linux/SPARC drivers |
1244 | # | 1268 | # |
1245 | CONFIG_SUN_OPENPROMIO=m | 1269 | CONFIG_SUN_OPENPROMIO=m |
1246 | CONFIG_SUN_MOSTEK_RTC=y | 1270 | CONFIG_SUN_MOSTEK_RTC=y |
1247 | # CONFIG_OBP_FLASH is not set | 1271 | # CONFIG_OBP_FLASH is not set |
1248 | # CONFIG_SUN_BPP is not set | 1272 | # CONFIG_SUN_BPP is not set |
1249 | # CONFIG_BBC_I2C is not set | 1273 | # CONFIG_BBC_I2C is not set |
1250 | # CONFIG_ENVCTRL is not set | 1274 | # CONFIG_ENVCTRL is not set |
1251 | # CONFIG_DISPLAY7SEG is not set | 1275 | # CONFIG_DISPLAY7SEG is not set |
1252 | 1276 | ||
1253 | # | 1277 | # |
1254 | # Fibre Channel support | 1278 | # Fibre Channel support |
1255 | # | 1279 | # |
1256 | # CONFIG_FC4 is not set | 1280 | # CONFIG_FC4 is not set |
1257 | 1281 | ||
1258 | # | 1282 | # |
1259 | # File systems | 1283 | # File systems |
1260 | # | 1284 | # |
1261 | CONFIG_EXT2_FS=y | 1285 | CONFIG_EXT2_FS=y |
1262 | CONFIG_EXT2_FS_XATTR=y | 1286 | CONFIG_EXT2_FS_XATTR=y |
1263 | CONFIG_EXT2_FS_POSIX_ACL=y | 1287 | CONFIG_EXT2_FS_POSIX_ACL=y |
1264 | CONFIG_EXT2_FS_SECURITY=y | 1288 | CONFIG_EXT2_FS_SECURITY=y |
1265 | # CONFIG_EXT2_FS_XIP is not set | 1289 | # CONFIG_EXT2_FS_XIP is not set |
1266 | CONFIG_EXT3_FS=y | 1290 | CONFIG_EXT3_FS=y |
1267 | CONFIG_EXT3_FS_XATTR=y | 1291 | CONFIG_EXT3_FS_XATTR=y |
1268 | CONFIG_EXT3_FS_POSIX_ACL=y | 1292 | CONFIG_EXT3_FS_POSIX_ACL=y |
1269 | CONFIG_EXT3_FS_SECURITY=y | 1293 | CONFIG_EXT3_FS_SECURITY=y |
1270 | # CONFIG_EXT4DEV_FS is not set | 1294 | # CONFIG_EXT4DEV_FS is not set |
1271 | CONFIG_JBD=y | 1295 | CONFIG_JBD=y |
1272 | # CONFIG_JBD_DEBUG is not set | 1296 | # CONFIG_JBD_DEBUG is not set |
1273 | CONFIG_FS_MBCACHE=y | 1297 | CONFIG_FS_MBCACHE=y |
1274 | # CONFIG_REISERFS_FS is not set | 1298 | # CONFIG_REISERFS_FS is not set |
1275 | # CONFIG_JFS_FS is not set | 1299 | # CONFIG_JFS_FS is not set |
1276 | CONFIG_FS_POSIX_ACL=y | 1300 | CONFIG_FS_POSIX_ACL=y |
1277 | # CONFIG_XFS_FS is not set | 1301 | # CONFIG_XFS_FS is not set |
1278 | # CONFIG_GFS2_FS is not set | 1302 | # CONFIG_GFS2_FS is not set |
1279 | # CONFIG_OCFS2_FS is not set | 1303 | # CONFIG_OCFS2_FS is not set |
1280 | # CONFIG_MINIX_FS is not set | 1304 | # CONFIG_MINIX_FS is not set |
1281 | # CONFIG_ROMFS_FS is not set | 1305 | # CONFIG_ROMFS_FS is not set |
1282 | CONFIG_INOTIFY=y | 1306 | CONFIG_INOTIFY=y |
1283 | CONFIG_INOTIFY_USER=y | 1307 | CONFIG_INOTIFY_USER=y |
1284 | # CONFIG_QUOTA is not set | 1308 | # CONFIG_QUOTA is not set |
1285 | CONFIG_DNOTIFY=y | 1309 | CONFIG_DNOTIFY=y |
1286 | # CONFIG_AUTOFS_FS is not set | 1310 | # CONFIG_AUTOFS_FS is not set |
1287 | # CONFIG_AUTOFS4_FS is not set | 1311 | # CONFIG_AUTOFS4_FS is not set |
1288 | # CONFIG_FUSE_FS is not set | 1312 | # CONFIG_FUSE_FS is not set |
1289 | 1313 | ||
1290 | # | 1314 | # |
1291 | # CD-ROM/DVD Filesystems | 1315 | # CD-ROM/DVD Filesystems |
1292 | # | 1316 | # |
1293 | # CONFIG_ISO9660_FS is not set | 1317 | # CONFIG_ISO9660_FS is not set |
1294 | # CONFIG_UDF_FS is not set | 1318 | # CONFIG_UDF_FS is not set |
1295 | 1319 | ||
1296 | # | 1320 | # |
1297 | # DOS/FAT/NT Filesystems | 1321 | # DOS/FAT/NT Filesystems |
1298 | # | 1322 | # |
1299 | # CONFIG_MSDOS_FS is not set | 1323 | # CONFIG_MSDOS_FS is not set |
1300 | # CONFIG_VFAT_FS is not set | 1324 | # CONFIG_VFAT_FS is not set |
1301 | # CONFIG_NTFS_FS is not set | 1325 | # CONFIG_NTFS_FS is not set |
1302 | 1326 | ||
1303 | # | 1327 | # |
1304 | # Pseudo filesystems | 1328 | # Pseudo filesystems |
1305 | # | 1329 | # |
1306 | CONFIG_PROC_FS=y | 1330 | CONFIG_PROC_FS=y |
1307 | CONFIG_PROC_KCORE=y | 1331 | CONFIG_PROC_KCORE=y |
1308 | CONFIG_PROC_SYSCTL=y | 1332 | CONFIG_PROC_SYSCTL=y |
1309 | CONFIG_SYSFS=y | 1333 | CONFIG_SYSFS=y |
1310 | CONFIG_TMPFS=y | 1334 | CONFIG_TMPFS=y |
1311 | # CONFIG_TMPFS_POSIX_ACL is not set | 1335 | # CONFIG_TMPFS_POSIX_ACL is not set |
1312 | CONFIG_HUGETLBFS=y | 1336 | CONFIG_HUGETLBFS=y |
1313 | CONFIG_HUGETLB_PAGE=y | 1337 | CONFIG_HUGETLB_PAGE=y |
1314 | CONFIG_RAMFS=y | 1338 | CONFIG_RAMFS=y |
1315 | # CONFIG_CONFIGFS_FS is not set | 1339 | # CONFIG_CONFIGFS_FS is not set |
1316 | 1340 | ||
1317 | # | 1341 | # |
1318 | # Miscellaneous filesystems | 1342 | # Miscellaneous filesystems |
1319 | # | 1343 | # |
1320 | # CONFIG_ADFS_FS is not set | 1344 | # CONFIG_ADFS_FS is not set |
1321 | # CONFIG_AFFS_FS is not set | 1345 | # CONFIG_AFFS_FS is not set |
1322 | # CONFIG_ECRYPT_FS is not set | 1346 | # CONFIG_ECRYPT_FS is not set |
1323 | # CONFIG_HFS_FS is not set | 1347 | # CONFIG_HFS_FS is not set |
1324 | # CONFIG_HFSPLUS_FS is not set | 1348 | # CONFIG_HFSPLUS_FS is not set |
1325 | # CONFIG_BEFS_FS is not set | 1349 | # CONFIG_BEFS_FS is not set |
1326 | # CONFIG_BFS_FS is not set | 1350 | # CONFIG_BFS_FS is not set |
1327 | # CONFIG_EFS_FS is not set | 1351 | # CONFIG_EFS_FS is not set |
1328 | # CONFIG_CRAMFS is not set | 1352 | # CONFIG_CRAMFS is not set |
1329 | # CONFIG_VXFS_FS is not set | 1353 | # CONFIG_VXFS_FS is not set |
1330 | # CONFIG_HPFS_FS is not set | 1354 | # CONFIG_HPFS_FS is not set |
1331 | # CONFIG_QNX4FS_FS is not set | 1355 | # CONFIG_QNX4FS_FS is not set |
1332 | # CONFIG_SYSV_FS is not set | 1356 | # CONFIG_SYSV_FS is not set |
1333 | # CONFIG_UFS_FS is not set | 1357 | # CONFIG_UFS_FS is not set |
1334 | 1358 | ||
1335 | # | 1359 | # |
1336 | # Network File Systems | 1360 | # Network File Systems |
1337 | # | 1361 | # |
1338 | # CONFIG_NFS_FS is not set | 1362 | # CONFIG_NFS_FS is not set |
1339 | # CONFIG_NFSD is not set | 1363 | # CONFIG_NFSD is not set |
1340 | # CONFIG_SMB_FS is not set | 1364 | # CONFIG_SMB_FS is not set |
1341 | # CONFIG_CIFS is not set | 1365 | # CONFIG_CIFS is not set |
1342 | # CONFIG_NCP_FS is not set | 1366 | # CONFIG_NCP_FS is not set |
1343 | # CONFIG_CODA_FS is not set | 1367 | # CONFIG_CODA_FS is not set |
1344 | # CONFIG_AFS_FS is not set | 1368 | # CONFIG_AFS_FS is not set |
1345 | # CONFIG_9P_FS is not set | 1369 | # CONFIG_9P_FS is not set |
1346 | 1370 | ||
1347 | # | 1371 | # |
1348 | # Partition Types | 1372 | # Partition Types |
1349 | # | 1373 | # |
1350 | # CONFIG_PARTITION_ADVANCED is not set | 1374 | # CONFIG_PARTITION_ADVANCED is not set |
1351 | CONFIG_MSDOS_PARTITION=y | 1375 | CONFIG_MSDOS_PARTITION=y |
1352 | CONFIG_SUN_PARTITION=y | 1376 | CONFIG_SUN_PARTITION=y |
1353 | 1377 | ||
1354 | # | 1378 | # |
1355 | # Native Language Support | 1379 | # Native Language Support |
1356 | # | 1380 | # |
1357 | CONFIG_NLS=m | 1381 | CONFIG_NLS=m |
1358 | CONFIG_NLS_DEFAULT="iso8859-1" | 1382 | CONFIG_NLS_DEFAULT="iso8859-1" |
1359 | # CONFIG_NLS_CODEPAGE_437 is not set | 1383 | # CONFIG_NLS_CODEPAGE_437 is not set |
1360 | # CONFIG_NLS_CODEPAGE_737 is not set | 1384 | # CONFIG_NLS_CODEPAGE_737 is not set |
1361 | # CONFIG_NLS_CODEPAGE_775 is not set | 1385 | # CONFIG_NLS_CODEPAGE_775 is not set |
1362 | # CONFIG_NLS_CODEPAGE_850 is not set | 1386 | # CONFIG_NLS_CODEPAGE_850 is not set |
1363 | # CONFIG_NLS_CODEPAGE_852 is not set | 1387 | # CONFIG_NLS_CODEPAGE_852 is not set |
1364 | # CONFIG_NLS_CODEPAGE_855 is not set | 1388 | # CONFIG_NLS_CODEPAGE_855 is not set |
1365 | # CONFIG_NLS_CODEPAGE_857 is not set | 1389 | # CONFIG_NLS_CODEPAGE_857 is not set |
1366 | # CONFIG_NLS_CODEPAGE_860 is not set | 1390 | # CONFIG_NLS_CODEPAGE_860 is not set |
1367 | # CONFIG_NLS_CODEPAGE_861 is not set | 1391 | # CONFIG_NLS_CODEPAGE_861 is not set |
1368 | # CONFIG_NLS_CODEPAGE_862 is not set | 1392 | # CONFIG_NLS_CODEPAGE_862 is not set |
1369 | # CONFIG_NLS_CODEPAGE_863 is not set | 1393 | # CONFIG_NLS_CODEPAGE_863 is not set |
1370 | # CONFIG_NLS_CODEPAGE_864 is not set | 1394 | # CONFIG_NLS_CODEPAGE_864 is not set |
1371 | # CONFIG_NLS_CODEPAGE_865 is not set | 1395 | # CONFIG_NLS_CODEPAGE_865 is not set |
1372 | # CONFIG_NLS_CODEPAGE_866 is not set | 1396 | # CONFIG_NLS_CODEPAGE_866 is not set |
1373 | # CONFIG_NLS_CODEPAGE_869 is not set | 1397 | # CONFIG_NLS_CODEPAGE_869 is not set |
1374 | # CONFIG_NLS_CODEPAGE_936 is not set | 1398 | # CONFIG_NLS_CODEPAGE_936 is not set |
1375 | # CONFIG_NLS_CODEPAGE_950 is not set | 1399 | # CONFIG_NLS_CODEPAGE_950 is not set |
1376 | # CONFIG_NLS_CODEPAGE_932 is not set | 1400 | # CONFIG_NLS_CODEPAGE_932 is not set |
1377 | # CONFIG_NLS_CODEPAGE_949 is not set | 1401 | # CONFIG_NLS_CODEPAGE_949 is not set |
1378 | # CONFIG_NLS_CODEPAGE_874 is not set | 1402 | # CONFIG_NLS_CODEPAGE_874 is not set |
1379 | # CONFIG_NLS_ISO8859_8 is not set | 1403 | # CONFIG_NLS_ISO8859_8 is not set |
1380 | # CONFIG_NLS_CODEPAGE_1250 is not set | 1404 | # CONFIG_NLS_CODEPAGE_1250 is not set |
1381 | # CONFIG_NLS_CODEPAGE_1251 is not set | 1405 | # CONFIG_NLS_CODEPAGE_1251 is not set |
1382 | # CONFIG_NLS_ASCII is not set | 1406 | # CONFIG_NLS_ASCII is not set |
1383 | # CONFIG_NLS_ISO8859_1 is not set | 1407 | # CONFIG_NLS_ISO8859_1 is not set |
1384 | # CONFIG_NLS_ISO8859_2 is not set | 1408 | # CONFIG_NLS_ISO8859_2 is not set |
1385 | # CONFIG_NLS_ISO8859_3 is not set | 1409 | # CONFIG_NLS_ISO8859_3 is not set |
1386 | # CONFIG_NLS_ISO8859_4 is not set | 1410 | # CONFIG_NLS_ISO8859_4 is not set |
1387 | # CONFIG_NLS_ISO8859_5 is not set | 1411 | # CONFIG_NLS_ISO8859_5 is not set |
1388 | # CONFIG_NLS_ISO8859_6 is not set | 1412 | # CONFIG_NLS_ISO8859_6 is not set |
1389 | # CONFIG_NLS_ISO8859_7 is not set | 1413 | # CONFIG_NLS_ISO8859_7 is not set |
1390 | # CONFIG_NLS_ISO8859_9 is not set | 1414 | # CONFIG_NLS_ISO8859_9 is not set |
1391 | # CONFIG_NLS_ISO8859_13 is not set | 1415 | # CONFIG_NLS_ISO8859_13 is not set |
1392 | # CONFIG_NLS_ISO8859_14 is not set | 1416 | # CONFIG_NLS_ISO8859_14 is not set |
1393 | # CONFIG_NLS_ISO8859_15 is not set | 1417 | # CONFIG_NLS_ISO8859_15 is not set |
1394 | # CONFIG_NLS_KOI8_R is not set | 1418 | # CONFIG_NLS_KOI8_R is not set |
1395 | # CONFIG_NLS_KOI8_U is not set | 1419 | # CONFIG_NLS_KOI8_U is not set |
1396 | # CONFIG_NLS_UTF8 is not set | 1420 | # CONFIG_NLS_UTF8 is not set |
1397 | 1421 | ||
1398 | # | 1422 | # |
1399 | # Distributed Lock Manager | 1423 | # Distributed Lock Manager |
1400 | # | 1424 | # |
1401 | # CONFIG_DLM is not set | 1425 | # CONFIG_DLM is not set |
1402 | 1426 | ||
1403 | # | 1427 | # |
1404 | # Instrumentation Support | 1428 | # Instrumentation Support |
1405 | # | 1429 | # |
1406 | CONFIG_PROFILING=y | 1430 | CONFIG_PROFILING=y |
1407 | CONFIG_OPROFILE=m | 1431 | CONFIG_OPROFILE=m |
1408 | CONFIG_KPROBES=y | 1432 | CONFIG_KPROBES=y |
1409 | 1433 | ||
1410 | # | 1434 | # |
1411 | # Kernel hacking | 1435 | # Kernel hacking |
1412 | # | 1436 | # |
1413 | CONFIG_TRACE_IRQFLAGS_SUPPORT=y | 1437 | CONFIG_TRACE_IRQFLAGS_SUPPORT=y |
1414 | CONFIG_PRINTK_TIME=y | 1438 | CONFIG_PRINTK_TIME=y |
1415 | CONFIG_ENABLE_MUST_CHECK=y | 1439 | CONFIG_ENABLE_MUST_CHECK=y |
1416 | CONFIG_MAGIC_SYSRQ=y | 1440 | CONFIG_MAGIC_SYSRQ=y |
1417 | # CONFIG_UNUSED_SYMBOLS is not set | 1441 | # CONFIG_UNUSED_SYMBOLS is not set |
1418 | CONFIG_DEBUG_FS=y | 1442 | CONFIG_DEBUG_FS=y |
1419 | # CONFIG_HEADERS_CHECK is not set | 1443 | # CONFIG_HEADERS_CHECK is not set |
1420 | CONFIG_DEBUG_KERNEL=y | 1444 | CONFIG_DEBUG_KERNEL=y |
1421 | CONFIG_LOG_BUF_SHIFT=18 | 1445 | CONFIG_LOG_BUF_SHIFT=18 |
1422 | CONFIG_DETECT_SOFTLOCKUP=y | 1446 | CONFIG_DETECT_SOFTLOCKUP=y |
1423 | CONFIG_SCHEDSTATS=y | 1447 | CONFIG_SCHEDSTATS=y |
1424 | # CONFIG_DEBUG_SLAB is not set | 1448 | # CONFIG_DEBUG_SLAB is not set |
1425 | # CONFIG_DEBUG_RT_MUTEXES is not set | 1449 | # CONFIG_DEBUG_RT_MUTEXES is not set |
1426 | # CONFIG_RT_MUTEX_TESTER is not set | 1450 | # CONFIG_RT_MUTEX_TESTER is not set |
1427 | # CONFIG_DEBUG_SPINLOCK is not set | 1451 | # CONFIG_DEBUG_SPINLOCK is not set |
1428 | # CONFIG_DEBUG_MUTEXES is not set | 1452 | # CONFIG_DEBUG_MUTEXES is not set |
1429 | # CONFIG_DEBUG_RWSEMS is not set | 1453 | # CONFIG_DEBUG_RWSEMS is not set |
1430 | # CONFIG_DEBUG_LOCK_ALLOC is not set | 1454 | # CONFIG_DEBUG_LOCK_ALLOC is not set |
1431 | # CONFIG_PROVE_LOCKING is not set | 1455 | # CONFIG_PROVE_LOCKING is not set |
1432 | # CONFIG_DEBUG_SPINLOCK_SLEEP is not set | 1456 | # CONFIG_DEBUG_SPINLOCK_SLEEP is not set |
1433 | # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set | 1457 | # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set |
1434 | # CONFIG_DEBUG_KOBJECT is not set | 1458 | # CONFIG_DEBUG_KOBJECT is not set |
1435 | CONFIG_DEBUG_BUGVERBOSE=y | 1459 | CONFIG_DEBUG_BUGVERBOSE=y |
1436 | # CONFIG_DEBUG_INFO is not set | 1460 | # CONFIG_DEBUG_INFO is not set |
1437 | # CONFIG_DEBUG_VM is not set | 1461 | # CONFIG_DEBUG_VM is not set |
1438 | # CONFIG_DEBUG_LIST is not set | 1462 | # CONFIG_DEBUG_LIST is not set |
1439 | CONFIG_FORCED_INLINING=y | 1463 | CONFIG_FORCED_INLINING=y |
1440 | # CONFIG_RCU_TORTURE_TEST is not set | 1464 | # CONFIG_RCU_TORTURE_TEST is not set |
1441 | # CONFIG_LKDTM is not set | 1465 | # CONFIG_LKDTM is not set |
1442 | # CONFIG_DEBUG_STACK_USAGE is not set | 1466 | # CONFIG_DEBUG_STACK_USAGE is not set |
1443 | # CONFIG_DEBUG_DCFLUSH is not set | 1467 | # CONFIG_DEBUG_DCFLUSH is not set |
1444 | # CONFIG_STACK_DEBUG is not set | 1468 | # CONFIG_STACK_DEBUG is not set |
1445 | # CONFIG_DEBUG_BOOTMEM is not set | 1469 | # CONFIG_DEBUG_BOOTMEM is not set |
1446 | # CONFIG_DEBUG_PAGEALLOC is not set | 1470 | # CONFIG_DEBUG_PAGEALLOC is not set |
1447 | 1471 | ||
1448 | # | 1472 | # |
1449 | # Security options | 1473 | # Security options |
1450 | # | 1474 | # |
1451 | CONFIG_KEYS=y | 1475 | CONFIG_KEYS=y |
1452 | # CONFIG_KEYS_DEBUG_PROC_KEYS is not set | 1476 | # CONFIG_KEYS_DEBUG_PROC_KEYS is not set |
1453 | # CONFIG_SECURITY is not set | 1477 | # CONFIG_SECURITY is not set |
1454 | 1478 | ||
1455 | # | 1479 | # |
1456 | # Cryptographic options | 1480 | # Cryptographic options |
1457 | # | 1481 | # |
1458 | CONFIG_CRYPTO=y | 1482 | CONFIG_CRYPTO=y |
1459 | CONFIG_CRYPTO_ALGAPI=y | 1483 | CONFIG_CRYPTO_ALGAPI=y |
1460 | CONFIG_CRYPTO_BLKCIPHER=y | 1484 | CONFIG_CRYPTO_BLKCIPHER=y |
1461 | CONFIG_CRYPTO_HASH=y | 1485 | CONFIG_CRYPTO_HASH=y |
1462 | CONFIG_CRYPTO_MANAGER=y | 1486 | CONFIG_CRYPTO_MANAGER=y |
1463 | CONFIG_CRYPTO_HMAC=y | 1487 | CONFIG_CRYPTO_HMAC=y |
1464 | CONFIG_CRYPTO_XCBC=y | 1488 | CONFIG_CRYPTO_XCBC=y |
1465 | CONFIG_CRYPTO_NULL=m | 1489 | CONFIG_CRYPTO_NULL=m |
1466 | CONFIG_CRYPTO_MD4=y | 1490 | CONFIG_CRYPTO_MD4=y |
1467 | CONFIG_CRYPTO_MD5=y | 1491 | CONFIG_CRYPTO_MD5=y |
1468 | CONFIG_CRYPTO_SHA1=y | 1492 | CONFIG_CRYPTO_SHA1=y |
1469 | CONFIG_CRYPTO_SHA256=m | 1493 | CONFIG_CRYPTO_SHA256=m |
1470 | CONFIG_CRYPTO_SHA512=m | 1494 | CONFIG_CRYPTO_SHA512=m |
1471 | CONFIG_CRYPTO_WP512=m | 1495 | CONFIG_CRYPTO_WP512=m |
1472 | CONFIG_CRYPTO_TGR192=m | 1496 | CONFIG_CRYPTO_TGR192=m |
1473 | CONFIG_CRYPTO_GF128MUL=m | 1497 | CONFIG_CRYPTO_GF128MUL=m |
1474 | CONFIG_CRYPTO_ECB=m | 1498 | CONFIG_CRYPTO_ECB=m |
1475 | CONFIG_CRYPTO_CBC=y | 1499 | CONFIG_CRYPTO_CBC=y |
1500 | CONFIG_CRYPTO_PCBC=m | ||
1476 | CONFIG_CRYPTO_LRW=m | 1501 | CONFIG_CRYPTO_LRW=m |
1477 | CONFIG_CRYPTO_DES=y | 1502 | CONFIG_CRYPTO_DES=y |
1503 | CONFIG_CRYPTO_FCRYPT=m | ||
1478 | CONFIG_CRYPTO_BLOWFISH=m | 1504 | CONFIG_CRYPTO_BLOWFISH=m |
1479 | CONFIG_CRYPTO_TWOFISH=m | 1505 | CONFIG_CRYPTO_TWOFISH=m |
1480 | CONFIG_CRYPTO_TWOFISH_COMMON=m | 1506 | CONFIG_CRYPTO_TWOFISH_COMMON=m |
1481 | CONFIG_CRYPTO_SERPENT=m | 1507 | CONFIG_CRYPTO_SERPENT=m |
1482 | CONFIG_CRYPTO_AES=m | 1508 | CONFIG_CRYPTO_AES=m |
1483 | CONFIG_CRYPTO_CAST5=m | 1509 | CONFIG_CRYPTO_CAST5=m |
1484 | CONFIG_CRYPTO_CAST6=m | 1510 | CONFIG_CRYPTO_CAST6=m |
1485 | CONFIG_CRYPTO_TEA=m | 1511 | CONFIG_CRYPTO_TEA=m |
1486 | CONFIG_CRYPTO_ARC4=m | 1512 | CONFIG_CRYPTO_ARC4=m |
1487 | CONFIG_CRYPTO_KHAZAD=m | 1513 | CONFIG_CRYPTO_KHAZAD=m |
1488 | CONFIG_CRYPTO_ANUBIS=m | 1514 | CONFIG_CRYPTO_ANUBIS=m |
1489 | CONFIG_CRYPTO_DEFLATE=y | 1515 | CONFIG_CRYPTO_DEFLATE=y |
1490 | CONFIG_CRYPTO_MICHAEL_MIC=m | 1516 | CONFIG_CRYPTO_MICHAEL_MIC=m |
1491 | CONFIG_CRYPTO_CRC32C=m | 1517 | CONFIG_CRYPTO_CRC32C=m |
1518 | CONFIG_CRYPTO_CAMELLIA=m | ||
1492 | CONFIG_CRYPTO_TEST=m | 1519 | CONFIG_CRYPTO_TEST=m |
1493 | 1520 | ||
1494 | # | 1521 | # |
1495 | # Hardware crypto devices | 1522 | # Hardware crypto devices |
1496 | # | 1523 | # |
1497 | 1524 | ||
1498 | # | 1525 | # |
1499 | # Library routines | 1526 | # Library routines |
1500 | # | 1527 | # |
1501 | CONFIG_BITREVERSE=y | 1528 | CONFIG_BITREVERSE=y |
1502 | CONFIG_CRC_CCITT=m | 1529 | CONFIG_CRC_CCITT=m |
1503 | CONFIG_CRC16=m | 1530 | CONFIG_CRC16=m |
1504 | CONFIG_CRC32=y | 1531 | CONFIG_CRC32=y |
1505 | CONFIG_LIBCRC32C=m | 1532 | CONFIG_LIBCRC32C=m |
1506 | CONFIG_ZLIB_INFLATE=y | 1533 | CONFIG_ZLIB_INFLATE=y |
1507 | CONFIG_ZLIB_DEFLATE=y | 1534 | CONFIG_ZLIB_DEFLATE=y |
1508 | CONFIG_PLIST=y | 1535 | CONFIG_PLIST=y |
arch/sparc64/kernel/irq.c
1 | /* $Id: irq.c,v 1.114 2002/01/11 08:45:38 davem Exp $ | 1 | /* $Id: irq.c,v 1.114 2002/01/11 08:45:38 davem Exp $ |
2 | * irq.c: UltraSparc IRQ handling/init/registry. | 2 | * irq.c: UltraSparc IRQ handling/init/registry. |
3 | * | 3 | * |
4 | * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) | 4 | * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) |
5 | * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be) | 5 | * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be) |
6 | * Copyright (C) 1998 Jakub Jelinek (jj@ultra.linux.cz) | 6 | * Copyright (C) 1998 Jakub Jelinek (jj@ultra.linux.cz) |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <linux/module.h> | 9 | #include <linux/module.h> |
10 | #include <linux/sched.h> | 10 | #include <linux/sched.h> |
11 | #include <linux/ptrace.h> | 11 | #include <linux/ptrace.h> |
12 | #include <linux/errno.h> | 12 | #include <linux/errno.h> |
13 | #include <linux/kernel_stat.h> | 13 | #include <linux/kernel_stat.h> |
14 | #include <linux/signal.h> | 14 | #include <linux/signal.h> |
15 | #include <linux/mm.h> | 15 | #include <linux/mm.h> |
16 | #include <linux/interrupt.h> | 16 | #include <linux/interrupt.h> |
17 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
18 | #include <linux/random.h> | 18 | #include <linux/random.h> |
19 | #include <linux/init.h> | 19 | #include <linux/init.h> |
20 | #include <linux/delay.h> | 20 | #include <linux/delay.h> |
21 | #include <linux/proc_fs.h> | 21 | #include <linux/proc_fs.h> |
22 | #include <linux/seq_file.h> | 22 | #include <linux/seq_file.h> |
23 | #include <linux/bootmem.h> | 23 | #include <linux/bootmem.h> |
24 | #include <linux/irq.h> | 24 | #include <linux/irq.h> |
25 | #include <linux/msi.h> | ||
25 | 26 | ||
26 | #include <asm/ptrace.h> | 27 | #include <asm/ptrace.h> |
27 | #include <asm/processor.h> | 28 | #include <asm/processor.h> |
28 | #include <asm/atomic.h> | 29 | #include <asm/atomic.h> |
29 | #include <asm/system.h> | 30 | #include <asm/system.h> |
30 | #include <asm/irq.h> | 31 | #include <asm/irq.h> |
31 | #include <asm/io.h> | 32 | #include <asm/io.h> |
32 | #include <asm/sbus.h> | 33 | #include <asm/sbus.h> |
33 | #include <asm/iommu.h> | 34 | #include <asm/iommu.h> |
34 | #include <asm/upa.h> | 35 | #include <asm/upa.h> |
35 | #include <asm/oplib.h> | 36 | #include <asm/oplib.h> |
36 | #include <asm/prom.h> | 37 | #include <asm/prom.h> |
37 | #include <asm/timer.h> | 38 | #include <asm/timer.h> |
38 | #include <asm/smp.h> | 39 | #include <asm/smp.h> |
39 | #include <asm/starfire.h> | 40 | #include <asm/starfire.h> |
40 | #include <asm/uaccess.h> | 41 | #include <asm/uaccess.h> |
41 | #include <asm/cache.h> | 42 | #include <asm/cache.h> |
42 | #include <asm/cpudata.h> | 43 | #include <asm/cpudata.h> |
43 | #include <asm/auxio.h> | 44 | #include <asm/auxio.h> |
44 | #include <asm/head.h> | 45 | #include <asm/head.h> |
45 | 46 | ||
46 | /* UPA nodes send interrupt packet to UltraSparc with first data reg | 47 | /* UPA nodes send interrupt packet to UltraSparc with first data reg |
47 | * value low 5 (7 on Starfire) bits holding the IRQ identifier being | 48 | * value low 5 (7 on Starfire) bits holding the IRQ identifier being |
48 | * delivered. We must translate this into a non-vector IRQ so we can | 49 | * delivered. We must translate this into a non-vector IRQ so we can |
49 | * set the softint on this cpu. | 50 | * set the softint on this cpu. |
50 | * | 51 | * |
51 | * To make processing these packets efficient and race free we use | 52 | * To make processing these packets efficient and race free we use |
52 | * an array of irq buckets below. The interrupt vector handler in | 53 | * an array of irq buckets below. The interrupt vector handler in |
53 | * entry.S feeds incoming packets into per-cpu pil-indexed lists. | 54 | * entry.S feeds incoming packets into per-cpu pil-indexed lists. |
54 | * The IVEC handler does not need to act atomically, the PIL dispatch | 55 | * The IVEC handler does not need to act atomically, the PIL dispatch |
55 | * code uses CAS to get an atomic snapshot of the list and clear it | 56 | * code uses CAS to get an atomic snapshot of the list and clear it |
56 | * at the same time. | 57 | * at the same time. |
57 | * | 58 | * |
58 | * If you make changes to ino_bucket, please update hand coded assembler | 59 | * If you make changes to ino_bucket, please update hand coded assembler |
59 | * of the vectored interrupt trap handler(s) in entry.S and sun4v_ivec.S | 60 | * of the vectored interrupt trap handler(s) in entry.S and sun4v_ivec.S |
60 | */ | 61 | */ |
61 | struct ino_bucket { | 62 | struct ino_bucket { |
62 | /* Next handler in per-CPU IRQ worklist. We know that | 63 | /* Next handler in per-CPU IRQ worklist. We know that |
63 | * bucket pointers have the high 32-bits clear, so to | 64 | * bucket pointers have the high 32-bits clear, so to |
64 | * save space we only store the bits we need. | 65 | * save space we only store the bits we need. |
65 | */ | 66 | */ |
66 | /*0x00*/unsigned int irq_chain; | 67 | /*0x00*/unsigned int irq_chain; |
67 | 68 | ||
68 | /* Virtual interrupt number assigned to this INO. */ | 69 | /* Virtual interrupt number assigned to this INO. */ |
69 | /*0x04*/unsigned int virt_irq; | 70 | /*0x04*/unsigned int virt_irq; |
70 | }; | 71 | }; |
71 | 72 | ||
72 | #define NUM_IVECS (IMAP_INR + 1) | 73 | #define NUM_IVECS (IMAP_INR + 1) |
73 | struct ino_bucket ivector_table[NUM_IVECS] __attribute__ ((aligned (SMP_CACHE_BYTES))); | 74 | struct ino_bucket ivector_table[NUM_IVECS] __attribute__ ((aligned (SMP_CACHE_BYTES))); |
74 | 75 | ||
75 | #define __irq_ino(irq) \ | 76 | #define __irq_ino(irq) \ |
76 | (((struct ino_bucket *)(unsigned long)(irq)) - &ivector_table[0]) | 77 | (((struct ino_bucket *)(unsigned long)(irq)) - &ivector_table[0]) |
77 | #define __bucket(irq) ((struct ino_bucket *)(unsigned long)(irq)) | 78 | #define __bucket(irq) ((struct ino_bucket *)(unsigned long)(irq)) |
78 | #define __irq(bucket) ((unsigned int)(unsigned long)(bucket)) | 79 | #define __irq(bucket) ((unsigned int)(unsigned long)(bucket)) |
79 | 80 | ||
80 | /* This has to be in the main kernel image, it cannot be | 81 | /* This has to be in the main kernel image, it cannot be |
81 | * turned into per-cpu data. The reason is that the main | 82 | * turned into per-cpu data. The reason is that the main |
82 | * kernel image is locked into the TLB and this structure | 83 | * kernel image is locked into the TLB and this structure |
83 | * is accessed from the vectored interrupt trap handler. If | 84 | * is accessed from the vectored interrupt trap handler. If |
84 | * access to this structure takes a TLB miss it could cause | 85 | * access to this structure takes a TLB miss it could cause |
85 | * the 5-level sparc v9 trap stack to overflow. | 86 | * the 5-level sparc v9 trap stack to overflow. |
86 | */ | 87 | */ |
87 | #define irq_work(__cpu) &(trap_block[(__cpu)].irq_worklist) | 88 | #define irq_work(__cpu) &(trap_block[(__cpu)].irq_worklist) |
88 | 89 | ||
89 | static unsigned int virt_to_real_irq_table[NR_IRQS]; | 90 | static unsigned int virt_to_real_irq_table[NR_IRQS]; |
90 | static unsigned char virt_irq_cur = 1; | ||
91 | 91 | ||
92 | static unsigned char virt_irq_alloc(unsigned int real_irq) | 92 | static unsigned char virt_irq_alloc(unsigned int real_irq) |
93 | { | 93 | { |
94 | unsigned char ent; | 94 | unsigned char ent; |
95 | 95 | ||
96 | BUILD_BUG_ON(NR_IRQS >= 256); | 96 | BUILD_BUG_ON(NR_IRQS >= 256); |
97 | 97 | ||
98 | ent = virt_irq_cur; | 98 | for (ent = 1; ent < NR_IRQS; ent++) { |
99 | if (!virt_to_real_irq_table[ent]) | ||
100 | break; | ||
101 | } | ||
99 | if (ent >= NR_IRQS) { | 102 | if (ent >= NR_IRQS) { |
100 | printk(KERN_ERR "IRQ: Out of virtual IRQs.\n"); | 103 | printk(KERN_ERR "IRQ: Out of virtual IRQs.\n"); |
101 | return 0; | 104 | return 0; |
102 | } | 105 | } |
103 | 106 | ||
104 | virt_irq_cur = ent + 1; | ||
105 | virt_to_real_irq_table[ent] = real_irq; | 107 | virt_to_real_irq_table[ent] = real_irq; |
106 | 108 | ||
107 | return ent; | 109 | return ent; |
108 | } | 110 | } |
109 | 111 | ||
110 | #if 0 /* Currently unused. */ | 112 | static void virt_irq_free(unsigned int virt_irq) |
111 | static unsigned char real_to_virt_irq(unsigned int real_irq) | ||
112 | { | 113 | { |
113 | struct ino_bucket *bucket = __bucket(real_irq); | 114 | unsigned int real_irq; |
114 | 115 | ||
115 | return bucket->virt_irq; | 116 | if (virt_irq >= NR_IRQS) |
117 | return; | ||
118 | |||
119 | real_irq = virt_to_real_irq_table[virt_irq]; | ||
120 | virt_to_real_irq_table[virt_irq] = 0; | ||
121 | |||
122 | __bucket(real_irq)->virt_irq = 0; | ||
116 | } | 123 | } |
117 | #endif | ||
118 | 124 | ||
119 | static unsigned int virt_to_real_irq(unsigned char virt_irq) | 125 | static unsigned int virt_to_real_irq(unsigned char virt_irq) |
120 | { | 126 | { |
121 | return virt_to_real_irq_table[virt_irq]; | 127 | return virt_to_real_irq_table[virt_irq]; |
122 | } | 128 | } |
123 | 129 | ||
124 | /* | 130 | /* |
125 | * /proc/interrupts printing: | 131 | * /proc/interrupts printing: |
126 | */ | 132 | */ |
127 | 133 | ||
128 | int show_interrupts(struct seq_file *p, void *v) | 134 | int show_interrupts(struct seq_file *p, void *v) |
129 | { | 135 | { |
130 | int i = *(loff_t *) v, j; | 136 | int i = *(loff_t *) v, j; |
131 | struct irqaction * action; | 137 | struct irqaction * action; |
132 | unsigned long flags; | 138 | unsigned long flags; |
133 | 139 | ||
134 | if (i == 0) { | 140 | if (i == 0) { |
135 | seq_printf(p, " "); | 141 | seq_printf(p, " "); |
136 | for_each_online_cpu(j) | 142 | for_each_online_cpu(j) |
137 | seq_printf(p, "CPU%d ",j); | 143 | seq_printf(p, "CPU%d ",j); |
138 | seq_putc(p, '\n'); | 144 | seq_putc(p, '\n'); |
139 | } | 145 | } |
140 | 146 | ||
141 | if (i < NR_IRQS) { | 147 | if (i < NR_IRQS) { |
142 | spin_lock_irqsave(&irq_desc[i].lock, flags); | 148 | spin_lock_irqsave(&irq_desc[i].lock, flags); |
143 | action = irq_desc[i].action; | 149 | action = irq_desc[i].action; |
144 | if (!action) | 150 | if (!action) |
145 | goto skip; | 151 | goto skip; |
146 | seq_printf(p, "%3d: ",i); | 152 | seq_printf(p, "%3d: ",i); |
147 | #ifndef CONFIG_SMP | 153 | #ifndef CONFIG_SMP |
148 | seq_printf(p, "%10u ", kstat_irqs(i)); | 154 | seq_printf(p, "%10u ", kstat_irqs(i)); |
149 | #else | 155 | #else |
150 | for_each_online_cpu(j) | 156 | for_each_online_cpu(j) |
151 | seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); | 157 | seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); |
152 | #endif | 158 | #endif |
153 | seq_printf(p, " %9s", irq_desc[i].chip->typename); | 159 | seq_printf(p, " %9s", irq_desc[i].chip->typename); |
154 | seq_printf(p, " %s", action->name); | 160 | seq_printf(p, " %s", action->name); |
155 | 161 | ||
156 | for (action=action->next; action; action = action->next) | 162 | for (action=action->next; action; action = action->next) |
157 | seq_printf(p, ", %s", action->name); | 163 | seq_printf(p, ", %s", action->name); |
158 | 164 | ||
159 | seq_putc(p, '\n'); | 165 | seq_putc(p, '\n'); |
160 | skip: | 166 | skip: |
161 | spin_unlock_irqrestore(&irq_desc[i].lock, flags); | 167 | spin_unlock_irqrestore(&irq_desc[i].lock, flags); |
162 | } | 168 | } |
163 | return 0; | 169 | return 0; |
164 | } | 170 | } |
165 | 171 | ||
166 | extern unsigned long real_hard_smp_processor_id(void); | 172 | extern unsigned long real_hard_smp_processor_id(void); |
167 | 173 | ||
168 | static unsigned int sun4u_compute_tid(unsigned long imap, unsigned long cpuid) | 174 | static unsigned int sun4u_compute_tid(unsigned long imap, unsigned long cpuid) |
169 | { | 175 | { |
170 | unsigned int tid; | 176 | unsigned int tid; |
171 | 177 | ||
172 | if (this_is_starfire) { | 178 | if (this_is_starfire) { |
173 | tid = starfire_translate(imap, cpuid); | 179 | tid = starfire_translate(imap, cpuid); |
174 | tid <<= IMAP_TID_SHIFT; | 180 | tid <<= IMAP_TID_SHIFT; |
175 | tid &= IMAP_TID_UPA; | 181 | tid &= IMAP_TID_UPA; |
176 | } else { | 182 | } else { |
177 | if (tlb_type == cheetah || tlb_type == cheetah_plus) { | 183 | if (tlb_type == cheetah || tlb_type == cheetah_plus) { |
178 | unsigned long ver; | 184 | unsigned long ver; |
179 | 185 | ||
180 | __asm__ ("rdpr %%ver, %0" : "=r" (ver)); | 186 | __asm__ ("rdpr %%ver, %0" : "=r" (ver)); |
181 | if ((ver >> 32UL) == __JALAPENO_ID || | 187 | if ((ver >> 32UL) == __JALAPENO_ID || |
182 | (ver >> 32UL) == __SERRANO_ID) { | 188 | (ver >> 32UL) == __SERRANO_ID) { |
183 | tid = cpuid << IMAP_TID_SHIFT; | 189 | tid = cpuid << IMAP_TID_SHIFT; |
184 | tid &= IMAP_TID_JBUS; | 190 | tid &= IMAP_TID_JBUS; |
185 | } else { | 191 | } else { |
186 | unsigned int a = cpuid & 0x1f; | 192 | unsigned int a = cpuid & 0x1f; |
187 | unsigned int n = (cpuid >> 5) & 0x1f; | 193 | unsigned int n = (cpuid >> 5) & 0x1f; |
188 | 194 | ||
189 | tid = ((a << IMAP_AID_SHIFT) | | 195 | tid = ((a << IMAP_AID_SHIFT) | |
190 | (n << IMAP_NID_SHIFT)); | 196 | (n << IMAP_NID_SHIFT)); |
191 | tid &= (IMAP_AID_SAFARI | | 197 | tid &= (IMAP_AID_SAFARI | |
192 | IMAP_NID_SAFARI);; | 198 | IMAP_NID_SAFARI);; |
193 | } | 199 | } |
194 | } else { | 200 | } else { |
195 | tid = cpuid << IMAP_TID_SHIFT; | 201 | tid = cpuid << IMAP_TID_SHIFT; |
196 | tid &= IMAP_TID_UPA; | 202 | tid &= IMAP_TID_UPA; |
197 | } | 203 | } |
198 | } | 204 | } |
199 | 205 | ||
200 | return tid; | 206 | return tid; |
201 | } | 207 | } |
202 | 208 | ||
203 | struct irq_handler_data { | 209 | struct irq_handler_data { |
204 | unsigned long iclr; | 210 | unsigned long iclr; |
205 | unsigned long imap; | 211 | unsigned long imap; |
206 | 212 | ||
207 | void (*pre_handler)(unsigned int, void *, void *); | 213 | void (*pre_handler)(unsigned int, void *, void *); |
208 | void *pre_handler_arg1; | 214 | void *pre_handler_arg1; |
209 | void *pre_handler_arg2; | 215 | void *pre_handler_arg2; |
210 | }; | 216 | }; |
211 | 217 | ||
212 | static inline struct ino_bucket *virt_irq_to_bucket(unsigned int virt_irq) | 218 | static inline struct ino_bucket *virt_irq_to_bucket(unsigned int virt_irq) |
213 | { | 219 | { |
214 | unsigned int real_irq = virt_to_real_irq(virt_irq); | 220 | unsigned int real_irq = virt_to_real_irq(virt_irq); |
215 | struct ino_bucket *bucket = NULL; | 221 | struct ino_bucket *bucket = NULL; |
216 | 222 | ||
217 | if (likely(real_irq)) | 223 | if (likely(real_irq)) |
218 | bucket = __bucket(real_irq); | 224 | bucket = __bucket(real_irq); |
219 | 225 | ||
220 | return bucket; | 226 | return bucket; |
221 | } | 227 | } |
222 | 228 | ||
223 | #ifdef CONFIG_SMP | 229 | #ifdef CONFIG_SMP |
224 | static int irq_choose_cpu(unsigned int virt_irq) | 230 | static int irq_choose_cpu(unsigned int virt_irq) |
225 | { | 231 | { |
226 | cpumask_t mask = irq_desc[virt_irq].affinity; | 232 | cpumask_t mask = irq_desc[virt_irq].affinity; |
227 | int cpuid; | 233 | int cpuid; |
228 | 234 | ||
229 | if (cpus_equal(mask, CPU_MASK_ALL)) { | 235 | if (cpus_equal(mask, CPU_MASK_ALL)) { |
230 | static int irq_rover; | 236 | static int irq_rover; |
231 | static DEFINE_SPINLOCK(irq_rover_lock); | 237 | static DEFINE_SPINLOCK(irq_rover_lock); |
232 | unsigned long flags; | 238 | unsigned long flags; |
233 | 239 | ||
234 | /* Round-robin distribution... */ | 240 | /* Round-robin distribution... */ |
235 | do_round_robin: | 241 | do_round_robin: |
236 | spin_lock_irqsave(&irq_rover_lock, flags); | 242 | spin_lock_irqsave(&irq_rover_lock, flags); |
237 | 243 | ||
238 | while (!cpu_online(irq_rover)) { | 244 | while (!cpu_online(irq_rover)) { |
239 | if (++irq_rover >= NR_CPUS) | 245 | if (++irq_rover >= NR_CPUS) |
240 | irq_rover = 0; | 246 | irq_rover = 0; |
241 | } | 247 | } |
242 | cpuid = irq_rover; | 248 | cpuid = irq_rover; |
243 | do { | 249 | do { |
244 | if (++irq_rover >= NR_CPUS) | 250 | if (++irq_rover >= NR_CPUS) |
245 | irq_rover = 0; | 251 | irq_rover = 0; |
246 | } while (!cpu_online(irq_rover)); | 252 | } while (!cpu_online(irq_rover)); |
247 | 253 | ||
248 | spin_unlock_irqrestore(&irq_rover_lock, flags); | 254 | spin_unlock_irqrestore(&irq_rover_lock, flags); |
249 | } else { | 255 | } else { |
250 | cpumask_t tmp; | 256 | cpumask_t tmp; |
251 | 257 | ||
252 | cpus_and(tmp, cpu_online_map, mask); | 258 | cpus_and(tmp, cpu_online_map, mask); |
253 | 259 | ||
254 | if (cpus_empty(tmp)) | 260 | if (cpus_empty(tmp)) |
255 | goto do_round_robin; | 261 | goto do_round_robin; |
256 | 262 | ||
257 | cpuid = first_cpu(tmp); | 263 | cpuid = first_cpu(tmp); |
258 | } | 264 | } |
259 | 265 | ||
260 | return cpuid; | 266 | return cpuid; |
261 | } | 267 | } |
262 | #else | 268 | #else |
263 | static int irq_choose_cpu(unsigned int virt_irq) | 269 | static int irq_choose_cpu(unsigned int virt_irq) |
264 | { | 270 | { |
265 | return real_hard_smp_processor_id(); | 271 | return real_hard_smp_processor_id(); |
266 | } | 272 | } |
267 | #endif | 273 | #endif |
268 | 274 | ||
269 | static void sun4u_irq_enable(unsigned int virt_irq) | 275 | static void sun4u_irq_enable(unsigned int virt_irq) |
270 | { | 276 | { |
271 | irq_desc_t *desc = irq_desc + virt_irq; | 277 | struct irq_handler_data *data = get_irq_chip_data(virt_irq); |
272 | struct irq_handler_data *data = desc->handler_data; | ||
273 | 278 | ||
274 | if (likely(data)) { | 279 | if (likely(data)) { |
275 | unsigned long cpuid, imap; | 280 | unsigned long cpuid, imap; |
276 | unsigned int tid; | 281 | unsigned int tid; |
277 | 282 | ||
278 | cpuid = irq_choose_cpu(virt_irq); | 283 | cpuid = irq_choose_cpu(virt_irq); |
279 | imap = data->imap; | 284 | imap = data->imap; |
280 | 285 | ||
281 | tid = sun4u_compute_tid(imap, cpuid); | 286 | tid = sun4u_compute_tid(imap, cpuid); |
282 | 287 | ||
283 | upa_writel(tid | IMAP_VALID, imap); | 288 | upa_writel(tid | IMAP_VALID, imap); |
284 | } | 289 | } |
285 | } | 290 | } |
286 | 291 | ||
287 | static void sun4u_irq_disable(unsigned int virt_irq) | 292 | static void sun4u_irq_disable(unsigned int virt_irq) |
288 | { | 293 | { |
289 | irq_desc_t *desc = irq_desc + virt_irq; | 294 | struct irq_handler_data *data = get_irq_chip_data(virt_irq); |
290 | struct irq_handler_data *data = desc->handler_data; | ||
291 | 295 | ||
292 | if (likely(data)) { | 296 | if (likely(data)) { |
293 | unsigned long imap = data->imap; | 297 | unsigned long imap = data->imap; |
294 | u32 tmp = upa_readl(imap); | 298 | u32 tmp = upa_readl(imap); |
295 | 299 | ||
296 | tmp &= ~IMAP_VALID; | 300 | tmp &= ~IMAP_VALID; |
297 | upa_writel(tmp, imap); | 301 | upa_writel(tmp, imap); |
298 | } | 302 | } |
299 | } | 303 | } |
300 | 304 | ||
301 | static void sun4u_irq_end(unsigned int virt_irq) | 305 | static void sun4u_irq_end(unsigned int virt_irq) |
302 | { | 306 | { |
303 | irq_desc_t *desc = irq_desc + virt_irq; | 307 | struct irq_handler_data *data = get_irq_chip_data(virt_irq); |
304 | struct irq_handler_data *data = desc->handler_data; | ||
305 | 308 | ||
306 | if (likely(data)) | 309 | if (likely(data)) |
307 | upa_writel(ICLR_IDLE, data->iclr); | 310 | upa_writel(ICLR_IDLE, data->iclr); |
308 | } | 311 | } |
309 | 312 | ||
310 | static void sun4v_irq_enable(unsigned int virt_irq) | 313 | static void sun4v_irq_enable(unsigned int virt_irq) |
311 | { | 314 | { |
312 | struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); | 315 | struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); |
313 | unsigned int ino = bucket - &ivector_table[0]; | 316 | unsigned int ino = bucket - &ivector_table[0]; |
314 | 317 | ||
315 | if (likely(bucket)) { | 318 | if (likely(bucket)) { |
316 | unsigned long cpuid; | 319 | unsigned long cpuid; |
317 | int err; | 320 | int err; |
318 | 321 | ||
319 | cpuid = irq_choose_cpu(virt_irq); | 322 | cpuid = irq_choose_cpu(virt_irq); |
320 | 323 | ||
321 | err = sun4v_intr_settarget(ino, cpuid); | 324 | err = sun4v_intr_settarget(ino, cpuid); |
322 | if (err != HV_EOK) | 325 | if (err != HV_EOK) |
323 | printk("sun4v_intr_settarget(%x,%lu): err(%d)\n", | 326 | printk("sun4v_intr_settarget(%x,%lu): err(%d)\n", |
324 | ino, cpuid, err); | 327 | ino, cpuid, err); |
325 | err = sun4v_intr_setenabled(ino, HV_INTR_ENABLED); | 328 | err = sun4v_intr_setenabled(ino, HV_INTR_ENABLED); |
326 | if (err != HV_EOK) | 329 | if (err != HV_EOK) |
327 | printk("sun4v_intr_setenabled(%x): err(%d)\n", | 330 | printk("sun4v_intr_setenabled(%x): err(%d)\n", |
328 | ino, err); | 331 | ino, err); |
329 | } | 332 | } |
330 | } | 333 | } |
331 | 334 | ||
332 | static void sun4v_irq_disable(unsigned int virt_irq) | 335 | static void sun4v_irq_disable(unsigned int virt_irq) |
333 | { | 336 | { |
334 | struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); | 337 | struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); |
335 | unsigned int ino = bucket - &ivector_table[0]; | 338 | unsigned int ino = bucket - &ivector_table[0]; |
336 | 339 | ||
337 | if (likely(bucket)) { | 340 | if (likely(bucket)) { |
338 | int err; | 341 | int err; |
339 | 342 | ||
340 | err = sun4v_intr_setenabled(ino, HV_INTR_DISABLED); | 343 | err = sun4v_intr_setenabled(ino, HV_INTR_DISABLED); |
341 | if (err != HV_EOK) | 344 | if (err != HV_EOK) |
342 | printk("sun4v_intr_setenabled(%x): " | 345 | printk("sun4v_intr_setenabled(%x): " |
343 | "err(%d)\n", ino, err); | 346 | "err(%d)\n", ino, err); |
344 | } | 347 | } |
345 | } | 348 | } |
346 | 349 | ||
350 | #ifdef CONFIG_PCI_MSI | ||
351 | static void sun4v_msi_enable(unsigned int virt_irq) | ||
352 | { | ||
353 | sun4v_irq_enable(virt_irq); | ||
354 | unmask_msi_irq(virt_irq); | ||
355 | } | ||
356 | |||
357 | static void sun4v_msi_disable(unsigned int virt_irq) | ||
358 | { | ||
359 | mask_msi_irq(virt_irq); | ||
360 | sun4v_irq_disable(virt_irq); | ||
361 | } | ||
362 | #endif | ||
363 | |||
347 | static void sun4v_irq_end(unsigned int virt_irq) | 364 | static void sun4v_irq_end(unsigned int virt_irq) |
348 | { | 365 | { |
349 | struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); | 366 | struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); |
350 | unsigned int ino = bucket - &ivector_table[0]; | 367 | unsigned int ino = bucket - &ivector_table[0]; |
351 | 368 | ||
352 | if (likely(bucket)) { | 369 | if (likely(bucket)) { |
353 | int err; | 370 | int err; |
354 | 371 | ||
355 | err = sun4v_intr_setstate(ino, HV_INTR_STATE_IDLE); | 372 | err = sun4v_intr_setstate(ino, HV_INTR_STATE_IDLE); |
356 | if (err != HV_EOK) | 373 | if (err != HV_EOK) |
357 | printk("sun4v_intr_setstate(%x): " | 374 | printk("sun4v_intr_setstate(%x): " |
358 | "err(%d)\n", ino, err); | 375 | "err(%d)\n", ino, err); |
359 | } | 376 | } |
360 | } | 377 | } |
361 | 378 | ||
362 | static void run_pre_handler(unsigned int virt_irq) | 379 | static void run_pre_handler(unsigned int virt_irq) |
363 | { | 380 | { |
364 | struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); | 381 | struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); |
365 | irq_desc_t *desc = irq_desc + virt_irq; | 382 | struct irq_handler_data *data = get_irq_chip_data(virt_irq); |
366 | struct irq_handler_data *data = desc->handler_data; | ||
367 | 383 | ||
368 | if (likely(data->pre_handler)) { | 384 | if (likely(data->pre_handler)) { |
369 | data->pre_handler(__irq_ino(__irq(bucket)), | 385 | data->pre_handler(__irq_ino(__irq(bucket)), |
370 | data->pre_handler_arg1, | 386 | data->pre_handler_arg1, |
371 | data->pre_handler_arg2); | 387 | data->pre_handler_arg2); |
372 | } | 388 | } |
373 | } | 389 | } |
374 | 390 | ||
375 | static struct irq_chip sun4u_irq = { | 391 | static struct irq_chip sun4u_irq = { |
376 | .typename = "sun4u", | 392 | .typename = "sun4u", |
377 | .enable = sun4u_irq_enable, | 393 | .enable = sun4u_irq_enable, |
378 | .disable = sun4u_irq_disable, | 394 | .disable = sun4u_irq_disable, |
379 | .end = sun4u_irq_end, | 395 | .end = sun4u_irq_end, |
380 | }; | 396 | }; |
381 | 397 | ||
382 | static struct irq_chip sun4u_irq_ack = { | 398 | static struct irq_chip sun4u_irq_ack = { |
383 | .typename = "sun4u+ack", | 399 | .typename = "sun4u+ack", |
384 | .enable = sun4u_irq_enable, | 400 | .enable = sun4u_irq_enable, |
385 | .disable = sun4u_irq_disable, | 401 | .disable = sun4u_irq_disable, |
386 | .ack = run_pre_handler, | 402 | .ack = run_pre_handler, |
387 | .end = sun4u_irq_end, | 403 | .end = sun4u_irq_end, |
388 | }; | 404 | }; |
389 | 405 | ||
390 | static struct irq_chip sun4v_irq = { | 406 | static struct irq_chip sun4v_irq = { |
391 | .typename = "sun4v", | 407 | .typename = "sun4v", |
392 | .enable = sun4v_irq_enable, | 408 | .enable = sun4v_irq_enable, |
393 | .disable = sun4v_irq_disable, | 409 | .disable = sun4v_irq_disable, |
394 | .end = sun4v_irq_end, | 410 | .end = sun4v_irq_end, |
395 | }; | 411 | }; |
396 | 412 | ||
397 | static struct irq_chip sun4v_irq_ack = { | 413 | static struct irq_chip sun4v_irq_ack = { |
398 | .typename = "sun4v+ack", | 414 | .typename = "sun4v+ack", |
399 | .enable = sun4v_irq_enable, | 415 | .enable = sun4v_irq_enable, |
400 | .disable = sun4v_irq_disable, | 416 | .disable = sun4v_irq_disable, |
401 | .ack = run_pre_handler, | 417 | .ack = run_pre_handler, |
402 | .end = sun4v_irq_end, | 418 | .end = sun4v_irq_end, |
403 | }; | 419 | }; |
404 | 420 | ||
421 | #ifdef CONFIG_PCI_MSI | ||
422 | static struct irq_chip sun4v_msi = { | ||
423 | .typename = "sun4v+msi", | ||
424 | .mask = mask_msi_irq, | ||
425 | .unmask = unmask_msi_irq, | ||
426 | .enable = sun4v_msi_enable, | ||
427 | .disable = sun4v_msi_disable, | ||
428 | .ack = run_pre_handler, | ||
429 | .end = sun4v_irq_end, | ||
430 | }; | ||
431 | #endif | ||
432 | |||
405 | void irq_install_pre_handler(int virt_irq, | 433 | void irq_install_pre_handler(int virt_irq, |
406 | void (*func)(unsigned int, void *, void *), | 434 | void (*func)(unsigned int, void *, void *), |
407 | void *arg1, void *arg2) | 435 | void *arg1, void *arg2) |
408 | { | 436 | { |
409 | irq_desc_t *desc = irq_desc + virt_irq; | 437 | struct irq_handler_data *data = get_irq_chip_data(virt_irq); |
410 | struct irq_handler_data *data = desc->handler_data; | 438 | struct irq_chip *chip; |
411 | 439 | ||
412 | data->pre_handler = func; | 440 | data->pre_handler = func; |
413 | data->pre_handler_arg1 = arg1; | 441 | data->pre_handler_arg1 = arg1; |
414 | data->pre_handler_arg2 = arg2; | 442 | data->pre_handler_arg2 = arg2; |
415 | 443 | ||
416 | if (desc->chip == &sun4u_irq_ack || | 444 | chip = get_irq_chip(virt_irq); |
417 | desc->chip == &sun4v_irq_ack) | 445 | if (chip == &sun4u_irq_ack || |
446 | chip == &sun4v_irq_ack | ||
447 | #ifdef CONFIG_PCI_MSI | ||
448 | || chip == &sun4v_msi | ||
449 | #endif | ||
450 | ) | ||
418 | return; | 451 | return; |
419 | 452 | ||
420 | desc->chip = (desc->chip == &sun4u_irq ? | 453 | chip = (chip == &sun4u_irq ? |
421 | &sun4u_irq_ack : &sun4v_irq_ack); | 454 | &sun4u_irq_ack : &sun4v_irq_ack); |
455 | set_irq_chip(virt_irq, chip); | ||
422 | } | 456 | } |
423 | 457 | ||
424 | unsigned int build_irq(int inofixup, unsigned long iclr, unsigned long imap) | 458 | unsigned int build_irq(int inofixup, unsigned long iclr, unsigned long imap) |
425 | { | 459 | { |
426 | struct ino_bucket *bucket; | 460 | struct ino_bucket *bucket; |
427 | struct irq_handler_data *data; | 461 | struct irq_handler_data *data; |
428 | irq_desc_t *desc; | ||
429 | int ino; | 462 | int ino; |
430 | 463 | ||
431 | BUG_ON(tlb_type == hypervisor); | 464 | BUG_ON(tlb_type == hypervisor); |
432 | 465 | ||
433 | ino = (upa_readl(imap) & (IMAP_IGN | IMAP_INO)) + inofixup; | 466 | ino = (upa_readl(imap) & (IMAP_IGN | IMAP_INO)) + inofixup; |
434 | bucket = &ivector_table[ino]; | 467 | bucket = &ivector_table[ino]; |
435 | if (!bucket->virt_irq) { | 468 | if (!bucket->virt_irq) { |
436 | bucket->virt_irq = virt_irq_alloc(__irq(bucket)); | 469 | bucket->virt_irq = virt_irq_alloc(__irq(bucket)); |
437 | irq_desc[bucket->virt_irq].chip = &sun4u_irq; | 470 | set_irq_chip(bucket->virt_irq, &sun4u_irq); |
438 | } | 471 | } |
439 | 472 | ||
440 | desc = irq_desc + bucket->virt_irq; | 473 | data = get_irq_chip_data(bucket->virt_irq); |
441 | if (unlikely(desc->handler_data)) | 474 | if (unlikely(data)) |
442 | goto out; | 475 | goto out; |
443 | 476 | ||
444 | data = kzalloc(sizeof(struct irq_handler_data), GFP_ATOMIC); | 477 | data = kzalloc(sizeof(struct irq_handler_data), GFP_ATOMIC); |
445 | if (unlikely(!data)) { | 478 | if (unlikely(!data)) { |
446 | prom_printf("IRQ: kzalloc(irq_handler_data) failed.\n"); | 479 | prom_printf("IRQ: kzalloc(irq_handler_data) failed.\n"); |
447 | prom_halt(); | 480 | prom_halt(); |
448 | } | 481 | } |
449 | desc->handler_data = data; | 482 | set_irq_chip_data(bucket->virt_irq, data); |
450 | 483 | ||
451 | data->imap = imap; | 484 | data->imap = imap; |
452 | data->iclr = iclr; | 485 | data->iclr = iclr; |
453 | 486 | ||
454 | out: | 487 | out: |
455 | return bucket->virt_irq; | 488 | return bucket->virt_irq; |
456 | } | 489 | } |
457 | 490 | ||
458 | unsigned int sun4v_build_irq(u32 devhandle, unsigned int devino) | 491 | unsigned int sun4v_build_irq(u32 devhandle, unsigned int devino) |
459 | { | 492 | { |
460 | struct ino_bucket *bucket; | 493 | struct ino_bucket *bucket; |
461 | struct irq_handler_data *data; | 494 | struct irq_handler_data *data; |
462 | unsigned long sysino; | 495 | unsigned long sysino; |
463 | irq_desc_t *desc; | ||
464 | 496 | ||
465 | BUG_ON(tlb_type != hypervisor); | 497 | BUG_ON(tlb_type != hypervisor); |
466 | 498 | ||
467 | sysino = sun4v_devino_to_sysino(devhandle, devino); | 499 | sysino = sun4v_devino_to_sysino(devhandle, devino); |
468 | bucket = &ivector_table[sysino]; | 500 | bucket = &ivector_table[sysino]; |
469 | if (!bucket->virt_irq) { | 501 | if (!bucket->virt_irq) { |
470 | bucket->virt_irq = virt_irq_alloc(__irq(bucket)); | 502 | bucket->virt_irq = virt_irq_alloc(__irq(bucket)); |
471 | irq_desc[bucket->virt_irq].chip = &sun4v_irq; | 503 | set_irq_chip(bucket->virt_irq, &sun4v_irq); |
472 | } | 504 | } |
473 | 505 | ||
474 | desc = irq_desc + bucket->virt_irq; | 506 | data = get_irq_chip_data(bucket->virt_irq); |
475 | if (unlikely(desc->handler_data)) | 507 | if (unlikely(data)) |
476 | goto out; | 508 | goto out; |
477 | 509 | ||
478 | data = kzalloc(sizeof(struct irq_handler_data), GFP_ATOMIC); | 510 | data = kzalloc(sizeof(struct irq_handler_data), GFP_ATOMIC); |
479 | if (unlikely(!data)) { | 511 | if (unlikely(!data)) { |
480 | prom_printf("IRQ: kzalloc(irq_handler_data) failed.\n"); | 512 | prom_printf("IRQ: kzalloc(irq_handler_data) failed.\n"); |
481 | prom_halt(); | 513 | prom_halt(); |
482 | } | 514 | } |
483 | desc->handler_data = data; | 515 | set_irq_chip_data(bucket->virt_irq, data); |
484 | 516 | ||
485 | /* Catch accidental accesses to these things. IMAP/ICLR handling | 517 | /* Catch accidental accesses to these things. IMAP/ICLR handling |
486 | * is done by hypervisor calls on sun4v platforms, not by direct | 518 | * is done by hypervisor calls on sun4v platforms, not by direct |
487 | * register accesses. | 519 | * register accesses. |
488 | */ | 520 | */ |
489 | data->imap = ~0UL; | 521 | data->imap = ~0UL; |
490 | data->iclr = ~0UL; | 522 | data->iclr = ~0UL; |
491 | 523 | ||
492 | out: | 524 | out: |
493 | return bucket->virt_irq; | 525 | return bucket->virt_irq; |
494 | } | 526 | } |
527 | |||
528 | #ifdef CONFIG_PCI_MSI | ||
529 | unsigned int sun4v_build_msi(u32 devhandle, unsigned int *virt_irq_p, | ||
530 | unsigned int msi_start, unsigned int msi_end) | ||
531 | { | ||
532 | struct ino_bucket *bucket; | ||
533 | struct irq_handler_data *data; | ||
534 | unsigned long sysino; | ||
535 | unsigned int devino; | ||
536 | |||
537 | BUG_ON(tlb_type != hypervisor); | ||
538 | |||
539 | /* Find a free devino in the given range. */ | ||
540 | for (devino = msi_start; devino < msi_end; devino++) { | ||
541 | sysino = sun4v_devino_to_sysino(devhandle, devino); | ||
542 | bucket = &ivector_table[sysino]; | ||
543 | if (!bucket->virt_irq) | ||
544 | break; | ||
545 | } | ||
546 | if (devino >= msi_end) | ||
547 | return 0; | ||
548 | |||
549 | sysino = sun4v_devino_to_sysino(devhandle, devino); | ||
550 | bucket = &ivector_table[sysino]; | ||
551 | bucket->virt_irq = virt_irq_alloc(__irq(bucket)); | ||
552 | *virt_irq_p = bucket->virt_irq; | ||
553 | set_irq_chip(bucket->virt_irq, &sun4v_msi); | ||
554 | |||
555 | data = get_irq_chip_data(bucket->virt_irq); | ||
556 | if (unlikely(data)) | ||
557 | return devino; | ||
558 | |||
559 | data = kzalloc(sizeof(struct irq_handler_data), GFP_ATOMIC); | ||
560 | if (unlikely(!data)) { | ||
561 | prom_printf("IRQ: kzalloc(irq_handler_data) failed.\n"); | ||
562 | prom_halt(); | ||
563 | } | ||
564 | set_irq_chip_data(bucket->virt_irq, data); | ||
565 | |||
566 | data->imap = ~0UL; | ||
567 | data->iclr = ~0UL; | ||
568 | |||
569 | return devino; | ||
570 | } | ||
571 | |||
572 | void sun4v_destroy_msi(unsigned int virt_irq) | ||
573 | { | ||
574 | virt_irq_free(virt_irq); | ||
575 | } | ||
576 | #endif | ||
495 | 577 | ||
496 | void ack_bad_irq(unsigned int virt_irq) | 578 | void ack_bad_irq(unsigned int virt_irq) |
497 | { | 579 | { |
498 | struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); | 580 | struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); |
499 | unsigned int ino = 0xdeadbeef; | 581 | unsigned int ino = 0xdeadbeef; |
500 | 582 | ||
501 | if (bucket) | 583 | if (bucket) |
502 | ino = bucket - &ivector_table[0]; | 584 | ino = bucket - &ivector_table[0]; |
503 | 585 | ||
504 | printk(KERN_CRIT "Unexpected IRQ from ino[%x] virt_irq[%u]\n", | 586 | printk(KERN_CRIT "Unexpected IRQ from ino[%x] virt_irq[%u]\n", |
505 | ino, virt_irq); | 587 | ino, virt_irq); |
506 | } | 588 | } |
507 | 589 | ||
508 | #ifndef CONFIG_SMP | 590 | #ifndef CONFIG_SMP |
509 | extern irqreturn_t timer_interrupt(int, void *); | 591 | extern irqreturn_t timer_interrupt(int, void *); |
510 | 592 | ||
511 | void timer_irq(int irq, struct pt_regs *regs) | 593 | void timer_irq(int irq, struct pt_regs *regs) |
512 | { | 594 | { |
513 | unsigned long clr_mask = 1 << irq; | 595 | unsigned long clr_mask = 1 << irq; |
514 | unsigned long tick_mask = tick_ops->softint_mask; | 596 | unsigned long tick_mask = tick_ops->softint_mask; |
515 | struct pt_regs *old_regs; | 597 | struct pt_regs *old_regs; |
516 | 598 | ||
517 | if (get_softint() & tick_mask) { | 599 | if (get_softint() & tick_mask) { |
518 | irq = 0; | 600 | irq = 0; |
519 | clr_mask = tick_mask; | 601 | clr_mask = tick_mask; |
520 | } | 602 | } |
521 | clear_softint(clr_mask); | 603 | clear_softint(clr_mask); |
522 | 604 | ||
523 | old_regs = set_irq_regs(regs); | 605 | old_regs = set_irq_regs(regs); |
524 | irq_enter(); | 606 | irq_enter(); |
525 | 607 | ||
526 | kstat_this_cpu.irqs[0]++; | 608 | kstat_this_cpu.irqs[0]++; |
527 | timer_interrupt(irq, NULL); | 609 | timer_interrupt(irq, NULL); |
528 | 610 | ||
529 | irq_exit(); | 611 | irq_exit(); |
530 | set_irq_regs(old_regs); | 612 | set_irq_regs(old_regs); |
531 | } | 613 | } |
532 | #endif | 614 | #endif |
533 | 615 | ||
534 | void handler_irq(int irq, struct pt_regs *regs) | 616 | void handler_irq(int irq, struct pt_regs *regs) |
535 | { | 617 | { |
536 | struct ino_bucket *bucket; | 618 | struct ino_bucket *bucket; |
537 | struct pt_regs *old_regs; | 619 | struct pt_regs *old_regs; |
538 | 620 | ||
539 | clear_softint(1 << irq); | 621 | clear_softint(1 << irq); |
540 | 622 | ||
541 | old_regs = set_irq_regs(regs); | 623 | old_regs = set_irq_regs(regs); |
542 | irq_enter(); | 624 | irq_enter(); |
543 | 625 | ||
544 | /* Sliiiick... */ | 626 | /* Sliiiick... */ |
545 | bucket = __bucket(xchg32(irq_work(smp_processor_id()), 0)); | 627 | bucket = __bucket(xchg32(irq_work(smp_processor_id()), 0)); |
546 | while (bucket) { | 628 | while (bucket) { |
547 | struct ino_bucket *next = __bucket(bucket->irq_chain); | 629 | struct ino_bucket *next = __bucket(bucket->irq_chain); |
548 | 630 | ||
549 | bucket->irq_chain = 0; | 631 | bucket->irq_chain = 0; |
550 | __do_IRQ(bucket->virt_irq); | 632 | __do_IRQ(bucket->virt_irq); |
551 | 633 | ||
552 | bucket = next; | 634 | bucket = next; |
553 | } | 635 | } |
554 | 636 | ||
555 | irq_exit(); | 637 | irq_exit(); |
556 | set_irq_regs(old_regs); | 638 | set_irq_regs(old_regs); |
557 | } | 639 | } |
558 | 640 | ||
559 | struct sun5_timer { | 641 | struct sun5_timer { |
560 | u64 count0; | 642 | u64 count0; |
561 | u64 limit0; | 643 | u64 limit0; |
562 | u64 count1; | 644 | u64 count1; |
563 | u64 limit1; | 645 | u64 limit1; |
564 | }; | 646 | }; |
565 | 647 | ||
566 | static struct sun5_timer *prom_timers; | 648 | static struct sun5_timer *prom_timers; |
567 | static u64 prom_limit0, prom_limit1; | 649 | static u64 prom_limit0, prom_limit1; |
568 | 650 | ||
569 | static void map_prom_timers(void) | 651 | static void map_prom_timers(void) |
570 | { | 652 | { |
571 | struct device_node *dp; | 653 | struct device_node *dp; |
572 | unsigned int *addr; | 654 | unsigned int *addr; |
573 | 655 | ||
574 | /* PROM timer node hangs out in the top level of device siblings... */ | 656 | /* PROM timer node hangs out in the top level of device siblings... */ |
575 | dp = of_find_node_by_path("/"); | 657 | dp = of_find_node_by_path("/"); |
576 | dp = dp->child; | 658 | dp = dp->child; |
577 | while (dp) { | 659 | while (dp) { |
578 | if (!strcmp(dp->name, "counter-timer")) | 660 | if (!strcmp(dp->name, "counter-timer")) |
579 | break; | 661 | break; |
580 | dp = dp->sibling; | 662 | dp = dp->sibling; |
581 | } | 663 | } |
582 | 664 | ||
583 | /* Assume if node is not present, PROM uses different tick mechanism | 665 | /* Assume if node is not present, PROM uses different tick mechanism |
584 | * which we should not care about. | 666 | * which we should not care about. |
585 | */ | 667 | */ |
586 | if (!dp) { | 668 | if (!dp) { |
587 | prom_timers = (struct sun5_timer *) 0; | 669 | prom_timers = (struct sun5_timer *) 0; |
588 | return; | 670 | return; |
589 | } | 671 | } |
590 | 672 | ||
591 | /* If PROM is really using this, it must be mapped by him. */ | 673 | /* If PROM is really using this, it must be mapped by him. */ |
592 | addr = of_get_property(dp, "address", NULL); | 674 | addr = of_get_property(dp, "address", NULL); |
593 | if (!addr) { | 675 | if (!addr) { |
594 | prom_printf("PROM does not have timer mapped, trying to continue.\n"); | 676 | prom_printf("PROM does not have timer mapped, trying to continue.\n"); |
595 | prom_timers = (struct sun5_timer *) 0; | 677 | prom_timers = (struct sun5_timer *) 0; |
596 | return; | 678 | return; |
597 | } | 679 | } |
598 | prom_timers = (struct sun5_timer *) ((unsigned long)addr[0]); | 680 | prom_timers = (struct sun5_timer *) ((unsigned long)addr[0]); |
599 | } | 681 | } |
600 | 682 | ||
601 | static void kill_prom_timer(void) | 683 | static void kill_prom_timer(void) |
602 | { | 684 | { |
603 | if (!prom_timers) | 685 | if (!prom_timers) |
604 | return; | 686 | return; |
605 | 687 | ||
606 | /* Save them away for later. */ | 688 | /* Save them away for later. */ |
607 | prom_limit0 = prom_timers->limit0; | 689 | prom_limit0 = prom_timers->limit0; |
608 | prom_limit1 = prom_timers->limit1; | 690 | prom_limit1 = prom_timers->limit1; |
609 | 691 | ||
610 | /* Just as in sun4c/sun4m PROM uses timer which ticks at IRQ 14. | 692 | /* Just as in sun4c/sun4m PROM uses timer which ticks at IRQ 14. |
611 | * We turn both off here just to be paranoid. | 693 | * We turn both off here just to be paranoid. |
612 | */ | 694 | */ |
613 | prom_timers->limit0 = 0; | 695 | prom_timers->limit0 = 0; |
614 | prom_timers->limit1 = 0; | 696 | prom_timers->limit1 = 0; |
615 | 697 | ||
616 | /* Wheee, eat the interrupt packet too... */ | 698 | /* Wheee, eat the interrupt packet too... */ |
617 | __asm__ __volatile__( | 699 | __asm__ __volatile__( |
618 | " mov 0x40, %%g2\n" | 700 | " mov 0x40, %%g2\n" |
619 | " ldxa [%%g0] %0, %%g1\n" | 701 | " ldxa [%%g0] %0, %%g1\n" |
620 | " ldxa [%%g2] %1, %%g1\n" | 702 | " ldxa [%%g2] %1, %%g1\n" |
621 | " stxa %%g0, [%%g0] %0\n" | 703 | " stxa %%g0, [%%g0] %0\n" |
622 | " membar #Sync\n" | 704 | " membar #Sync\n" |
623 | : /* no outputs */ | 705 | : /* no outputs */ |
624 | : "i" (ASI_INTR_RECEIVE), "i" (ASI_INTR_R) | 706 | : "i" (ASI_INTR_RECEIVE), "i" (ASI_INTR_R) |
625 | : "g1", "g2"); | 707 | : "g1", "g2"); |
626 | } | 708 | } |
627 | 709 | ||
628 | void init_irqwork_curcpu(void) | 710 | void init_irqwork_curcpu(void) |
629 | { | 711 | { |
630 | int cpu = hard_smp_processor_id(); | 712 | int cpu = hard_smp_processor_id(); |
631 | 713 | ||
632 | trap_block[cpu].irq_worklist = 0; | 714 | trap_block[cpu].irq_worklist = 0; |
633 | } | 715 | } |
634 | 716 | ||
635 | static void __cpuinit register_one_mondo(unsigned long paddr, unsigned long type) | 717 | static void __cpuinit register_one_mondo(unsigned long paddr, unsigned long type) |
636 | { | 718 | { |
637 | unsigned long num_entries = 128; | 719 | unsigned long num_entries = 128; |
638 | unsigned long status; | 720 | unsigned long status; |
639 | 721 | ||
640 | status = sun4v_cpu_qconf(type, paddr, num_entries); | 722 | status = sun4v_cpu_qconf(type, paddr, num_entries); |
641 | if (status != HV_EOK) { | 723 | if (status != HV_EOK) { |
642 | prom_printf("SUN4V: sun4v_cpu_qconf(%lu:%lx:%lu) failed, " | 724 | prom_printf("SUN4V: sun4v_cpu_qconf(%lu:%lx:%lu) failed, " |
643 | "err %lu\n", type, paddr, num_entries, status); | 725 | "err %lu\n", type, paddr, num_entries, status); |
644 | prom_halt(); | 726 | prom_halt(); |
645 | } | 727 | } |
646 | } | 728 | } |
647 | 729 | ||
648 | static void __cpuinit sun4v_register_mondo_queues(int this_cpu) | 730 | static void __cpuinit sun4v_register_mondo_queues(int this_cpu) |
649 | { | 731 | { |
650 | struct trap_per_cpu *tb = &trap_block[this_cpu]; | 732 | struct trap_per_cpu *tb = &trap_block[this_cpu]; |
651 | 733 | ||
652 | register_one_mondo(tb->cpu_mondo_pa, HV_CPU_QUEUE_CPU_MONDO); | 734 | register_one_mondo(tb->cpu_mondo_pa, HV_CPU_QUEUE_CPU_MONDO); |
653 | register_one_mondo(tb->dev_mondo_pa, HV_CPU_QUEUE_DEVICE_MONDO); | 735 | register_one_mondo(tb->dev_mondo_pa, HV_CPU_QUEUE_DEVICE_MONDO); |
654 | register_one_mondo(tb->resum_mondo_pa, HV_CPU_QUEUE_RES_ERROR); | 736 | register_one_mondo(tb->resum_mondo_pa, HV_CPU_QUEUE_RES_ERROR); |
655 | register_one_mondo(tb->nonresum_mondo_pa, HV_CPU_QUEUE_NONRES_ERROR); | 737 | register_one_mondo(tb->nonresum_mondo_pa, HV_CPU_QUEUE_NONRES_ERROR); |
656 | } | 738 | } |
657 | 739 | ||
658 | static void __cpuinit alloc_one_mondo(unsigned long *pa_ptr, int use_bootmem) | 740 | static void __cpuinit alloc_one_mondo(unsigned long *pa_ptr, int use_bootmem) |
659 | { | 741 | { |
660 | void *page; | 742 | void *page; |
661 | 743 | ||
662 | if (use_bootmem) | 744 | if (use_bootmem) |
663 | page = alloc_bootmem_low_pages(PAGE_SIZE); | 745 | page = alloc_bootmem_low_pages(PAGE_SIZE); |
664 | else | 746 | else |
665 | page = (void *) get_zeroed_page(GFP_ATOMIC); | 747 | page = (void *) get_zeroed_page(GFP_ATOMIC); |
666 | 748 | ||
667 | if (!page) { | 749 | if (!page) { |
668 | prom_printf("SUN4V: Error, cannot allocate mondo queue.\n"); | 750 | prom_printf("SUN4V: Error, cannot allocate mondo queue.\n"); |
669 | prom_halt(); | 751 | prom_halt(); |
670 | } | 752 | } |
671 | 753 | ||
672 | *pa_ptr = __pa(page); | 754 | *pa_ptr = __pa(page); |
673 | } | 755 | } |
674 | 756 | ||
675 | static void __cpuinit alloc_one_kbuf(unsigned long *pa_ptr, int use_bootmem) | 757 | static void __cpuinit alloc_one_kbuf(unsigned long *pa_ptr, int use_bootmem) |
676 | { | 758 | { |
677 | void *page; | 759 | void *page; |
678 | 760 | ||
679 | if (use_bootmem) | 761 | if (use_bootmem) |
680 | page = alloc_bootmem_low_pages(PAGE_SIZE); | 762 | page = alloc_bootmem_low_pages(PAGE_SIZE); |
681 | else | 763 | else |
682 | page = (void *) get_zeroed_page(GFP_ATOMIC); | 764 | page = (void *) get_zeroed_page(GFP_ATOMIC); |
683 | 765 | ||
684 | if (!page) { | 766 | if (!page) { |
685 | prom_printf("SUN4V: Error, cannot allocate kbuf page.\n"); | 767 | prom_printf("SUN4V: Error, cannot allocate kbuf page.\n"); |
686 | prom_halt(); | 768 | prom_halt(); |
687 | } | 769 | } |
688 | 770 | ||
689 | *pa_ptr = __pa(page); | 771 | *pa_ptr = __pa(page); |
690 | } | 772 | } |
691 | 773 | ||
692 | static void __cpuinit init_cpu_send_mondo_info(struct trap_per_cpu *tb, int use_bootmem) | 774 | static void __cpuinit init_cpu_send_mondo_info(struct trap_per_cpu *tb, int use_bootmem) |
693 | { | 775 | { |
694 | #ifdef CONFIG_SMP | 776 | #ifdef CONFIG_SMP |
695 | void *page; | 777 | void *page; |
696 | 778 | ||
697 | BUILD_BUG_ON((NR_CPUS * sizeof(u16)) > (PAGE_SIZE - 64)); | 779 | BUILD_BUG_ON((NR_CPUS * sizeof(u16)) > (PAGE_SIZE - 64)); |
698 | 780 | ||
699 | if (use_bootmem) | 781 | if (use_bootmem) |
700 | page = alloc_bootmem_low_pages(PAGE_SIZE); | 782 | page = alloc_bootmem_low_pages(PAGE_SIZE); |
701 | else | 783 | else |
702 | page = (void *) get_zeroed_page(GFP_ATOMIC); | 784 | page = (void *) get_zeroed_page(GFP_ATOMIC); |
703 | 785 | ||
704 | if (!page) { | 786 | if (!page) { |
705 | prom_printf("SUN4V: Error, cannot allocate cpu mondo page.\n"); | 787 | prom_printf("SUN4V: Error, cannot allocate cpu mondo page.\n"); |
706 | prom_halt(); | 788 | prom_halt(); |
707 | } | 789 | } |
708 | 790 | ||
709 | tb->cpu_mondo_block_pa = __pa(page); | 791 | tb->cpu_mondo_block_pa = __pa(page); |
710 | tb->cpu_list_pa = __pa(page + 64); | 792 | tb->cpu_list_pa = __pa(page + 64); |
711 | #endif | 793 | #endif |
712 | } | 794 | } |
713 | 795 | ||
714 | /* Allocate and register the mondo and error queues for this cpu. */ | 796 | /* Allocate and register the mondo and error queues for this cpu. */ |
715 | void __cpuinit sun4v_init_mondo_queues(int use_bootmem, int cpu, int alloc, int load) | 797 | void __cpuinit sun4v_init_mondo_queues(int use_bootmem, int cpu, int alloc, int load) |
716 | { | 798 | { |
717 | struct trap_per_cpu *tb = &trap_block[cpu]; | 799 | struct trap_per_cpu *tb = &trap_block[cpu]; |
718 | 800 | ||
719 | if (alloc) { | 801 | if (alloc) { |
720 | alloc_one_mondo(&tb->cpu_mondo_pa, use_bootmem); | 802 | alloc_one_mondo(&tb->cpu_mondo_pa, use_bootmem); |
721 | alloc_one_mondo(&tb->dev_mondo_pa, use_bootmem); | 803 | alloc_one_mondo(&tb->dev_mondo_pa, use_bootmem); |
722 | alloc_one_mondo(&tb->resum_mondo_pa, use_bootmem); | 804 | alloc_one_mondo(&tb->resum_mondo_pa, use_bootmem); |
723 | alloc_one_kbuf(&tb->resum_kernel_buf_pa, use_bootmem); | 805 | alloc_one_kbuf(&tb->resum_kernel_buf_pa, use_bootmem); |
724 | alloc_one_mondo(&tb->nonresum_mondo_pa, use_bootmem); | 806 | alloc_one_mondo(&tb->nonresum_mondo_pa, use_bootmem); |
725 | alloc_one_kbuf(&tb->nonresum_kernel_buf_pa, use_bootmem); | 807 | alloc_one_kbuf(&tb->nonresum_kernel_buf_pa, use_bootmem); |
726 | 808 | ||
727 | init_cpu_send_mondo_info(tb, use_bootmem); | 809 | init_cpu_send_mondo_info(tb, use_bootmem); |
728 | } | 810 | } |
729 | 811 | ||
730 | if (load) { | 812 | if (load) { |
731 | if (cpu != hard_smp_processor_id()) { | 813 | if (cpu != hard_smp_processor_id()) { |
732 | prom_printf("SUN4V: init mondo on cpu %d not %d\n", | 814 | prom_printf("SUN4V: init mondo on cpu %d not %d\n", |
733 | cpu, hard_smp_processor_id()); | 815 | cpu, hard_smp_processor_id()); |
734 | prom_halt(); | 816 | prom_halt(); |
735 | } | 817 | } |
736 | sun4v_register_mondo_queues(cpu); | 818 | sun4v_register_mondo_queues(cpu); |
737 | } | 819 | } |
738 | } | 820 | } |
739 | 821 | ||
740 | static struct irqaction timer_irq_action = { | 822 | static struct irqaction timer_irq_action = { |
741 | .name = "timer", | 823 | .name = "timer", |
742 | }; | 824 | }; |
743 | 825 | ||
744 | /* Only invoked on boot processor. */ | 826 | /* Only invoked on boot processor. */ |
745 | void __init init_IRQ(void) | 827 | void __init init_IRQ(void) |
746 | { | 828 | { |
747 | map_prom_timers(); | 829 | map_prom_timers(); |
748 | kill_prom_timer(); | 830 | kill_prom_timer(); |
749 | memset(&ivector_table[0], 0, sizeof(ivector_table)); | 831 | memset(&ivector_table[0], 0, sizeof(ivector_table)); |
750 | 832 | ||
751 | if (tlb_type == hypervisor) | 833 | if (tlb_type == hypervisor) |
752 | sun4v_init_mondo_queues(1, hard_smp_processor_id(), 1, 1); | 834 | sun4v_init_mondo_queues(1, hard_smp_processor_id(), 1, 1); |
753 | 835 | ||
754 | /* We need to clear any IRQ's pending in the soft interrupt | 836 | /* We need to clear any IRQ's pending in the soft interrupt |
755 | * registers, a spurious one could be left around from the | 837 | * registers, a spurious one could be left around from the |
756 | * PROM timer which we just disabled. | 838 | * PROM timer which we just disabled. |
757 | */ | 839 | */ |
758 | clear_softint(get_softint()); | 840 | clear_softint(get_softint()); |
759 | 841 | ||
760 | /* Now that ivector table is initialized, it is safe | 842 | /* Now that ivector table is initialized, it is safe |
761 | * to receive IRQ vector traps. We will normally take | 843 | * to receive IRQ vector traps. We will normally take |
762 | * one or two right now, in case some device PROM used | 844 | * one or two right now, in case some device PROM used |
763 | * to boot us wants to speak to us. We just ignore them. | 845 | * to boot us wants to speak to us. We just ignore them. |
764 | */ | 846 | */ |
arch/sparc64/kernel/pci.c
1 | /* $Id: pci.c,v 1.39 2002/01/05 01:13:43 davem Exp $ | 1 | /* $Id: pci.c,v 1.39 2002/01/05 01:13:43 davem Exp $ |
2 | * pci.c: UltraSparc PCI controller support. | 2 | * pci.c: UltraSparc PCI controller support. |
3 | * | 3 | * |
4 | * Copyright (C) 1997, 1998, 1999 David S. Miller (davem@redhat.com) | 4 | * Copyright (C) 1997, 1998, 1999 David S. Miller (davem@redhat.com) |
5 | * Copyright (C) 1998, 1999 Eddie C. Dost (ecd@skynet.be) | 5 | * Copyright (C) 1998, 1999 Eddie C. Dost (ecd@skynet.be) |
6 | * Copyright (C) 1999 Jakub Jelinek (jj@ultra.linux.cz) | 6 | * Copyright (C) 1999 Jakub Jelinek (jj@ultra.linux.cz) |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <linux/module.h> | 9 | #include <linux/module.h> |
10 | #include <linux/kernel.h> | 10 | #include <linux/kernel.h> |
11 | #include <linux/string.h> | 11 | #include <linux/string.h> |
12 | #include <linux/sched.h> | 12 | #include <linux/sched.h> |
13 | #include <linux/capability.h> | 13 | #include <linux/capability.h> |
14 | #include <linux/errno.h> | 14 | #include <linux/errno.h> |
15 | #include <linux/smp_lock.h> | 15 | #include <linux/smp_lock.h> |
16 | #include <linux/msi.h> | ||
17 | #include <linux/irq.h> | ||
16 | #include <linux/init.h> | 18 | #include <linux/init.h> |
17 | 19 | ||
18 | #include <asm/uaccess.h> | 20 | #include <asm/uaccess.h> |
19 | #include <asm/pbm.h> | 21 | #include <asm/pbm.h> |
20 | #include <asm/pgtable.h> | 22 | #include <asm/pgtable.h> |
21 | #include <asm/irq.h> | 23 | #include <asm/irq.h> |
22 | #include <asm/ebus.h> | 24 | #include <asm/ebus.h> |
23 | #include <asm/isa.h> | 25 | #include <asm/isa.h> |
24 | #include <asm/prom.h> | 26 | #include <asm/prom.h> |
25 | 27 | ||
26 | unsigned long pci_memspace_mask = 0xffffffffUL; | 28 | unsigned long pci_memspace_mask = 0xffffffffUL; |
27 | 29 | ||
28 | #ifndef CONFIG_PCI | 30 | #ifndef CONFIG_PCI |
29 | /* A "nop" PCI implementation. */ | 31 | /* A "nop" PCI implementation. */ |
30 | asmlinkage int sys_pciconfig_read(unsigned long bus, unsigned long dfn, | 32 | asmlinkage int sys_pciconfig_read(unsigned long bus, unsigned long dfn, |
31 | unsigned long off, unsigned long len, | 33 | unsigned long off, unsigned long len, |
32 | unsigned char *buf) | 34 | unsigned char *buf) |
33 | { | 35 | { |
34 | return 0; | 36 | return 0; |
35 | } | 37 | } |
36 | asmlinkage int sys_pciconfig_write(unsigned long bus, unsigned long dfn, | 38 | asmlinkage int sys_pciconfig_write(unsigned long bus, unsigned long dfn, |
37 | unsigned long off, unsigned long len, | 39 | unsigned long off, unsigned long len, |
38 | unsigned char *buf) | 40 | unsigned char *buf) |
39 | { | 41 | { |
40 | return 0; | 42 | return 0; |
41 | } | 43 | } |
42 | #else | 44 | #else |
43 | 45 | ||
44 | /* List of all PCI controllers found in the system. */ | 46 | /* List of all PCI controllers found in the system. */ |
45 | struct pci_controller_info *pci_controller_root = NULL; | 47 | struct pci_controller_info *pci_controller_root = NULL; |
46 | 48 | ||
47 | /* Each PCI controller found gets a unique index. */ | 49 | /* Each PCI controller found gets a unique index. */ |
48 | int pci_num_controllers = 0; | 50 | int pci_num_controllers = 0; |
49 | 51 | ||
50 | volatile int pci_poke_in_progress; | 52 | volatile int pci_poke_in_progress; |
51 | volatile int pci_poke_cpu = -1; | 53 | volatile int pci_poke_cpu = -1; |
52 | volatile int pci_poke_faulted; | 54 | volatile int pci_poke_faulted; |
53 | 55 | ||
54 | static DEFINE_SPINLOCK(pci_poke_lock); | 56 | static DEFINE_SPINLOCK(pci_poke_lock); |
55 | 57 | ||
56 | void pci_config_read8(u8 *addr, u8 *ret) | 58 | void pci_config_read8(u8 *addr, u8 *ret) |
57 | { | 59 | { |
58 | unsigned long flags; | 60 | unsigned long flags; |
59 | u8 byte; | 61 | u8 byte; |
60 | 62 | ||
61 | spin_lock_irqsave(&pci_poke_lock, flags); | 63 | spin_lock_irqsave(&pci_poke_lock, flags); |
62 | pci_poke_cpu = smp_processor_id(); | 64 | pci_poke_cpu = smp_processor_id(); |
63 | pci_poke_in_progress = 1; | 65 | pci_poke_in_progress = 1; |
64 | pci_poke_faulted = 0; | 66 | pci_poke_faulted = 0; |
65 | __asm__ __volatile__("membar #Sync\n\t" | 67 | __asm__ __volatile__("membar #Sync\n\t" |
66 | "lduba [%1] %2, %0\n\t" | 68 | "lduba [%1] %2, %0\n\t" |
67 | "membar #Sync" | 69 | "membar #Sync" |
68 | : "=r" (byte) | 70 | : "=r" (byte) |
69 | : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L) | 71 | : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L) |
70 | : "memory"); | 72 | : "memory"); |
71 | pci_poke_in_progress = 0; | 73 | pci_poke_in_progress = 0; |
72 | pci_poke_cpu = -1; | 74 | pci_poke_cpu = -1; |
73 | if (!pci_poke_faulted) | 75 | if (!pci_poke_faulted) |
74 | *ret = byte; | 76 | *ret = byte; |
75 | spin_unlock_irqrestore(&pci_poke_lock, flags); | 77 | spin_unlock_irqrestore(&pci_poke_lock, flags); |
76 | } | 78 | } |
77 | 79 | ||
78 | void pci_config_read16(u16 *addr, u16 *ret) | 80 | void pci_config_read16(u16 *addr, u16 *ret) |
79 | { | 81 | { |
80 | unsigned long flags; | 82 | unsigned long flags; |
81 | u16 word; | 83 | u16 word; |
82 | 84 | ||
83 | spin_lock_irqsave(&pci_poke_lock, flags); | 85 | spin_lock_irqsave(&pci_poke_lock, flags); |
84 | pci_poke_cpu = smp_processor_id(); | 86 | pci_poke_cpu = smp_processor_id(); |
85 | pci_poke_in_progress = 1; | 87 | pci_poke_in_progress = 1; |
86 | pci_poke_faulted = 0; | 88 | pci_poke_faulted = 0; |
87 | __asm__ __volatile__("membar #Sync\n\t" | 89 | __asm__ __volatile__("membar #Sync\n\t" |
88 | "lduha [%1] %2, %0\n\t" | 90 | "lduha [%1] %2, %0\n\t" |
89 | "membar #Sync" | 91 | "membar #Sync" |
90 | : "=r" (word) | 92 | : "=r" (word) |
91 | : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L) | 93 | : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L) |
92 | : "memory"); | 94 | : "memory"); |
93 | pci_poke_in_progress = 0; | 95 | pci_poke_in_progress = 0; |
94 | pci_poke_cpu = -1; | 96 | pci_poke_cpu = -1; |
95 | if (!pci_poke_faulted) | 97 | if (!pci_poke_faulted) |
96 | *ret = word; | 98 | *ret = word; |
97 | spin_unlock_irqrestore(&pci_poke_lock, flags); | 99 | spin_unlock_irqrestore(&pci_poke_lock, flags); |
98 | } | 100 | } |
99 | 101 | ||
100 | void pci_config_read32(u32 *addr, u32 *ret) | 102 | void pci_config_read32(u32 *addr, u32 *ret) |
101 | { | 103 | { |
102 | unsigned long flags; | 104 | unsigned long flags; |
103 | u32 dword; | 105 | u32 dword; |
104 | 106 | ||
105 | spin_lock_irqsave(&pci_poke_lock, flags); | 107 | spin_lock_irqsave(&pci_poke_lock, flags); |
106 | pci_poke_cpu = smp_processor_id(); | 108 | pci_poke_cpu = smp_processor_id(); |
107 | pci_poke_in_progress = 1; | 109 | pci_poke_in_progress = 1; |
108 | pci_poke_faulted = 0; | 110 | pci_poke_faulted = 0; |
109 | __asm__ __volatile__("membar #Sync\n\t" | 111 | __asm__ __volatile__("membar #Sync\n\t" |
110 | "lduwa [%1] %2, %0\n\t" | 112 | "lduwa [%1] %2, %0\n\t" |
111 | "membar #Sync" | 113 | "membar #Sync" |
112 | : "=r" (dword) | 114 | : "=r" (dword) |
113 | : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L) | 115 | : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L) |
114 | : "memory"); | 116 | : "memory"); |
115 | pci_poke_in_progress = 0; | 117 | pci_poke_in_progress = 0; |
116 | pci_poke_cpu = -1; | 118 | pci_poke_cpu = -1; |
117 | if (!pci_poke_faulted) | 119 | if (!pci_poke_faulted) |
118 | *ret = dword; | 120 | *ret = dword; |
119 | spin_unlock_irqrestore(&pci_poke_lock, flags); | 121 | spin_unlock_irqrestore(&pci_poke_lock, flags); |
120 | } | 122 | } |
121 | 123 | ||
122 | void pci_config_write8(u8 *addr, u8 val) | 124 | void pci_config_write8(u8 *addr, u8 val) |
123 | { | 125 | { |
124 | unsigned long flags; | 126 | unsigned long flags; |
125 | 127 | ||
126 | spin_lock_irqsave(&pci_poke_lock, flags); | 128 | spin_lock_irqsave(&pci_poke_lock, flags); |
127 | pci_poke_cpu = smp_processor_id(); | 129 | pci_poke_cpu = smp_processor_id(); |
128 | pci_poke_in_progress = 1; | 130 | pci_poke_in_progress = 1; |
129 | pci_poke_faulted = 0; | 131 | pci_poke_faulted = 0; |
130 | __asm__ __volatile__("membar #Sync\n\t" | 132 | __asm__ __volatile__("membar #Sync\n\t" |
131 | "stba %0, [%1] %2\n\t" | 133 | "stba %0, [%1] %2\n\t" |
132 | "membar #Sync" | 134 | "membar #Sync" |
133 | : /* no outputs */ | 135 | : /* no outputs */ |
134 | : "r" (val), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L) | 136 | : "r" (val), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L) |
135 | : "memory"); | 137 | : "memory"); |
136 | pci_poke_in_progress = 0; | 138 | pci_poke_in_progress = 0; |
137 | pci_poke_cpu = -1; | 139 | pci_poke_cpu = -1; |
138 | spin_unlock_irqrestore(&pci_poke_lock, flags); | 140 | spin_unlock_irqrestore(&pci_poke_lock, flags); |
139 | } | 141 | } |
140 | 142 | ||
141 | void pci_config_write16(u16 *addr, u16 val) | 143 | void pci_config_write16(u16 *addr, u16 val) |
142 | { | 144 | { |
143 | unsigned long flags; | 145 | unsigned long flags; |
144 | 146 | ||
145 | spin_lock_irqsave(&pci_poke_lock, flags); | 147 | spin_lock_irqsave(&pci_poke_lock, flags); |
146 | pci_poke_cpu = smp_processor_id(); | 148 | pci_poke_cpu = smp_processor_id(); |
147 | pci_poke_in_progress = 1; | 149 | pci_poke_in_progress = 1; |
148 | pci_poke_faulted = 0; | 150 | pci_poke_faulted = 0; |
149 | __asm__ __volatile__("membar #Sync\n\t" | 151 | __asm__ __volatile__("membar #Sync\n\t" |
150 | "stha %0, [%1] %2\n\t" | 152 | "stha %0, [%1] %2\n\t" |
151 | "membar #Sync" | 153 | "membar #Sync" |
152 | : /* no outputs */ | 154 | : /* no outputs */ |
153 | : "r" (val), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L) | 155 | : "r" (val), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L) |
154 | : "memory"); | 156 | : "memory"); |
155 | pci_poke_in_progress = 0; | 157 | pci_poke_in_progress = 0; |
156 | pci_poke_cpu = -1; | 158 | pci_poke_cpu = -1; |
157 | spin_unlock_irqrestore(&pci_poke_lock, flags); | 159 | spin_unlock_irqrestore(&pci_poke_lock, flags); |
158 | } | 160 | } |
159 | 161 | ||
160 | void pci_config_write32(u32 *addr, u32 val) | 162 | void pci_config_write32(u32 *addr, u32 val) |
161 | { | 163 | { |
162 | unsigned long flags; | 164 | unsigned long flags; |
163 | 165 | ||
164 | spin_lock_irqsave(&pci_poke_lock, flags); | 166 | spin_lock_irqsave(&pci_poke_lock, flags); |
165 | pci_poke_cpu = smp_processor_id(); | 167 | pci_poke_cpu = smp_processor_id(); |
166 | pci_poke_in_progress = 1; | 168 | pci_poke_in_progress = 1; |
167 | pci_poke_faulted = 0; | 169 | pci_poke_faulted = 0; |
168 | __asm__ __volatile__("membar #Sync\n\t" | 170 | __asm__ __volatile__("membar #Sync\n\t" |
169 | "stwa %0, [%1] %2\n\t" | 171 | "stwa %0, [%1] %2\n\t" |
170 | "membar #Sync" | 172 | "membar #Sync" |
171 | : /* no outputs */ | 173 | : /* no outputs */ |
172 | : "r" (val), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L) | 174 | : "r" (val), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L) |
173 | : "memory"); | 175 | : "memory"); |
174 | pci_poke_in_progress = 0; | 176 | pci_poke_in_progress = 0; |
175 | pci_poke_cpu = -1; | 177 | pci_poke_cpu = -1; |
176 | spin_unlock_irqrestore(&pci_poke_lock, flags); | 178 | spin_unlock_irqrestore(&pci_poke_lock, flags); |
177 | } | 179 | } |
178 | 180 | ||
179 | /* Probe for all PCI controllers in the system. */ | 181 | /* Probe for all PCI controllers in the system. */ |
180 | extern void sabre_init(struct device_node *, const char *); | 182 | extern void sabre_init(struct device_node *, const char *); |
181 | extern void psycho_init(struct device_node *, const char *); | 183 | extern void psycho_init(struct device_node *, const char *); |
182 | extern void schizo_init(struct device_node *, const char *); | 184 | extern void schizo_init(struct device_node *, const char *); |
183 | extern void schizo_plus_init(struct device_node *, const char *); | 185 | extern void schizo_plus_init(struct device_node *, const char *); |
184 | extern void tomatillo_init(struct device_node *, const char *); | 186 | extern void tomatillo_init(struct device_node *, const char *); |
185 | extern void sun4v_pci_init(struct device_node *, const char *); | 187 | extern void sun4v_pci_init(struct device_node *, const char *); |
186 | 188 | ||
187 | static struct { | 189 | static struct { |
188 | char *model_name; | 190 | char *model_name; |
189 | void (*init)(struct device_node *, const char *); | 191 | void (*init)(struct device_node *, const char *); |
190 | } pci_controller_table[] __initdata = { | 192 | } pci_controller_table[] __initdata = { |
191 | { "SUNW,sabre", sabre_init }, | 193 | { "SUNW,sabre", sabre_init }, |
192 | { "pci108e,a000", sabre_init }, | 194 | { "pci108e,a000", sabre_init }, |
193 | { "pci108e,a001", sabre_init }, | 195 | { "pci108e,a001", sabre_init }, |
194 | { "SUNW,psycho", psycho_init }, | 196 | { "SUNW,psycho", psycho_init }, |
195 | { "pci108e,8000", psycho_init }, | 197 | { "pci108e,8000", psycho_init }, |
196 | { "SUNW,schizo", schizo_init }, | 198 | { "SUNW,schizo", schizo_init }, |
197 | { "pci108e,8001", schizo_init }, | 199 | { "pci108e,8001", schizo_init }, |
198 | { "SUNW,schizo+", schizo_plus_init }, | 200 | { "SUNW,schizo+", schizo_plus_init }, |
199 | { "pci108e,8002", schizo_plus_init }, | 201 | { "pci108e,8002", schizo_plus_init }, |
200 | { "SUNW,tomatillo", tomatillo_init }, | 202 | { "SUNW,tomatillo", tomatillo_init }, |
201 | { "pci108e,a801", tomatillo_init }, | 203 | { "pci108e,a801", tomatillo_init }, |
202 | { "SUNW,sun4v-pci", sun4v_pci_init }, | 204 | { "SUNW,sun4v-pci", sun4v_pci_init }, |
203 | }; | 205 | }; |
204 | #define PCI_NUM_CONTROLLER_TYPES (sizeof(pci_controller_table) / \ | 206 | #define PCI_NUM_CONTROLLER_TYPES (sizeof(pci_controller_table) / \ |
205 | sizeof(pci_controller_table[0])) | 207 | sizeof(pci_controller_table[0])) |
206 | 208 | ||
207 | static int __init pci_controller_init(const char *model_name, int namelen, struct device_node *dp) | 209 | static int __init pci_controller_init(const char *model_name, int namelen, struct device_node *dp) |
208 | { | 210 | { |
209 | int i; | 211 | int i; |
210 | 212 | ||
211 | for (i = 0; i < PCI_NUM_CONTROLLER_TYPES; i++) { | 213 | for (i = 0; i < PCI_NUM_CONTROLLER_TYPES; i++) { |
212 | if (!strncmp(model_name, | 214 | if (!strncmp(model_name, |
213 | pci_controller_table[i].model_name, | 215 | pci_controller_table[i].model_name, |
214 | namelen)) { | 216 | namelen)) { |
215 | pci_controller_table[i].init(dp, model_name); | 217 | pci_controller_table[i].init(dp, model_name); |
216 | return 1; | 218 | return 1; |
217 | } | 219 | } |
218 | } | 220 | } |
219 | 221 | ||
220 | return 0; | 222 | return 0; |
221 | } | 223 | } |
222 | 224 | ||
223 | static int __init pci_is_controller(const char *model_name, int namelen, struct device_node *dp) | 225 | static int __init pci_is_controller(const char *model_name, int namelen, struct device_node *dp) |
224 | { | 226 | { |
225 | int i; | 227 | int i; |
226 | 228 | ||
227 | for (i = 0; i < PCI_NUM_CONTROLLER_TYPES; i++) { | 229 | for (i = 0; i < PCI_NUM_CONTROLLER_TYPES; i++) { |
228 | if (!strncmp(model_name, | 230 | if (!strncmp(model_name, |
229 | pci_controller_table[i].model_name, | 231 | pci_controller_table[i].model_name, |
230 | namelen)) { | 232 | namelen)) { |
231 | return 1; | 233 | return 1; |
232 | } | 234 | } |
233 | } | 235 | } |
234 | return 0; | 236 | return 0; |
235 | } | 237 | } |
236 | 238 | ||
237 | static int __init pci_controller_scan(int (*handler)(const char *, int, struct device_node *)) | 239 | static int __init pci_controller_scan(int (*handler)(const char *, int, struct device_node *)) |
238 | { | 240 | { |
239 | struct device_node *dp; | 241 | struct device_node *dp; |
240 | int count = 0; | 242 | int count = 0; |
241 | 243 | ||
242 | for_each_node_by_name(dp, "pci") { | 244 | for_each_node_by_name(dp, "pci") { |
243 | struct property *prop; | 245 | struct property *prop; |
244 | int len; | 246 | int len; |
245 | 247 | ||
246 | prop = of_find_property(dp, "model", &len); | 248 | prop = of_find_property(dp, "model", &len); |
247 | if (!prop) | 249 | if (!prop) |
248 | prop = of_find_property(dp, "compatible", &len); | 250 | prop = of_find_property(dp, "compatible", &len); |
249 | 251 | ||
250 | if (prop) { | 252 | if (prop) { |
251 | const char *model = prop->value; | 253 | const char *model = prop->value; |
252 | int item_len = 0; | 254 | int item_len = 0; |
253 | 255 | ||
254 | /* Our value may be a multi-valued string in the | 256 | /* Our value may be a multi-valued string in the |
255 | * case of some compatible properties. For sanity, | 257 | * case of some compatible properties. For sanity, |
256 | * only try the first one. | 258 | * only try the first one. |
257 | */ | 259 | */ |
258 | while (model[item_len] && len) { | 260 | while (model[item_len] && len) { |
259 | len--; | 261 | len--; |
260 | item_len++; | 262 | item_len++; |
261 | } | 263 | } |
262 | 264 | ||
263 | if (handler(model, item_len, dp)) | 265 | if (handler(model, item_len, dp)) |
264 | count++; | 266 | count++; |
265 | } | 267 | } |
266 | } | 268 | } |
267 | 269 | ||
268 | return count; | 270 | return count; |
269 | } | 271 | } |
270 | 272 | ||
271 | 273 | ||
272 | /* Is there some PCI controller in the system? */ | 274 | /* Is there some PCI controller in the system? */ |
273 | int __init pcic_present(void) | 275 | int __init pcic_present(void) |
274 | { | 276 | { |
275 | return pci_controller_scan(pci_is_controller); | 277 | return pci_controller_scan(pci_is_controller); |
276 | } | 278 | } |
277 | 279 | ||
278 | struct pci_iommu_ops *pci_iommu_ops; | 280 | struct pci_iommu_ops *pci_iommu_ops; |
279 | EXPORT_SYMBOL(pci_iommu_ops); | 281 | EXPORT_SYMBOL(pci_iommu_ops); |
280 | 282 | ||
281 | extern struct pci_iommu_ops pci_sun4u_iommu_ops, | 283 | extern struct pci_iommu_ops pci_sun4u_iommu_ops, |
282 | pci_sun4v_iommu_ops; | 284 | pci_sun4v_iommu_ops; |
283 | 285 | ||
284 | /* Find each controller in the system, attach and initialize | 286 | /* Find each controller in the system, attach and initialize |
285 | * software state structure for each and link into the | 287 | * software state structure for each and link into the |
286 | * pci_controller_root. Setup the controller enough such | 288 | * pci_controller_root. Setup the controller enough such |
287 | * that bus scanning can be done. | 289 | * that bus scanning can be done. |
288 | */ | 290 | */ |
289 | static void __init pci_controller_probe(void) | 291 | static void __init pci_controller_probe(void) |
290 | { | 292 | { |
291 | if (tlb_type == hypervisor) | 293 | if (tlb_type == hypervisor) |
292 | pci_iommu_ops = &pci_sun4v_iommu_ops; | 294 | pci_iommu_ops = &pci_sun4v_iommu_ops; |
293 | else | 295 | else |
294 | pci_iommu_ops = &pci_sun4u_iommu_ops; | 296 | pci_iommu_ops = &pci_sun4u_iommu_ops; |
295 | 297 | ||
296 | printk("PCI: Probing for controllers.\n"); | 298 | printk("PCI: Probing for controllers.\n"); |
297 | 299 | ||
298 | pci_controller_scan(pci_controller_init); | 300 | pci_controller_scan(pci_controller_init); |
299 | } | 301 | } |
300 | 302 | ||
301 | static void __init pci_scan_each_controller_bus(void) | 303 | static void __init pci_scan_each_controller_bus(void) |
302 | { | 304 | { |
303 | struct pci_controller_info *p; | 305 | struct pci_controller_info *p; |
304 | 306 | ||
305 | for (p = pci_controller_root; p; p = p->next) | 307 | for (p = pci_controller_root; p; p = p->next) |
306 | p->scan_bus(p); | 308 | p->scan_bus(p); |
307 | } | 309 | } |
308 | 310 | ||
309 | extern void power_init(void); | 311 | extern void power_init(void); |
310 | 312 | ||
311 | static int __init pcibios_init(void) | 313 | static int __init pcibios_init(void) |
312 | { | 314 | { |
313 | pci_controller_probe(); | 315 | pci_controller_probe(); |
314 | if (pci_controller_root == NULL) | 316 | if (pci_controller_root == NULL) |
315 | return 0; | 317 | return 0; |
316 | 318 | ||
317 | pci_scan_each_controller_bus(); | 319 | pci_scan_each_controller_bus(); |
318 | 320 | ||
319 | isa_init(); | 321 | isa_init(); |
320 | ebus_init(); | 322 | ebus_init(); |
321 | power_init(); | 323 | power_init(); |
322 | 324 | ||
323 | return 0; | 325 | return 0; |
324 | } | 326 | } |
325 | 327 | ||
326 | subsys_initcall(pcibios_init); | 328 | subsys_initcall(pcibios_init); |
327 | 329 | ||
328 | void pcibios_fixup_bus(struct pci_bus *pbus) | 330 | void pcibios_fixup_bus(struct pci_bus *pbus) |
329 | { | 331 | { |
330 | struct pci_pbm_info *pbm = pbus->sysdata; | 332 | struct pci_pbm_info *pbm = pbus->sysdata; |
331 | 333 | ||
332 | /* Generic PCI bus probing sets these to point at | 334 | /* Generic PCI bus probing sets these to point at |
333 | * &io{port,mem}_resouce which is wrong for us. | 335 | * &io{port,mem}_resouce which is wrong for us. |
334 | */ | 336 | */ |
335 | pbus->resource[0] = &pbm->io_space; | 337 | pbus->resource[0] = &pbm->io_space; |
336 | pbus->resource[1] = &pbm->mem_space; | 338 | pbus->resource[1] = &pbm->mem_space; |
337 | } | 339 | } |
338 | 340 | ||
339 | struct resource *pcibios_select_root(struct pci_dev *pdev, struct resource *r) | 341 | struct resource *pcibios_select_root(struct pci_dev *pdev, struct resource *r) |
340 | { | 342 | { |
341 | struct pci_pbm_info *pbm = pdev->bus->sysdata; | 343 | struct pci_pbm_info *pbm = pdev->bus->sysdata; |
342 | struct resource *root = NULL; | 344 | struct resource *root = NULL; |
343 | 345 | ||
344 | if (r->flags & IORESOURCE_IO) | 346 | if (r->flags & IORESOURCE_IO) |
345 | root = &pbm->io_space; | 347 | root = &pbm->io_space; |
346 | if (r->flags & IORESOURCE_MEM) | 348 | if (r->flags & IORESOURCE_MEM) |
347 | root = &pbm->mem_space; | 349 | root = &pbm->mem_space; |
348 | 350 | ||
349 | return root; | 351 | return root; |
350 | } | 352 | } |
351 | 353 | ||
352 | void pcibios_update_irq(struct pci_dev *pdev, int irq) | 354 | void pcibios_update_irq(struct pci_dev *pdev, int irq) |
353 | { | 355 | { |
354 | } | 356 | } |
355 | 357 | ||
356 | void pcibios_align_resource(void *data, struct resource *res, | 358 | void pcibios_align_resource(void *data, struct resource *res, |
357 | resource_size_t size, resource_size_t align) | 359 | resource_size_t size, resource_size_t align) |
358 | { | 360 | { |
359 | } | 361 | } |
360 | 362 | ||
361 | int pcibios_enable_device(struct pci_dev *pdev, int mask) | 363 | int pcibios_enable_device(struct pci_dev *pdev, int mask) |
362 | { | 364 | { |
363 | return 0; | 365 | return 0; |
364 | } | 366 | } |
365 | 367 | ||
366 | void pcibios_resource_to_bus(struct pci_dev *pdev, struct pci_bus_region *region, | 368 | void pcibios_resource_to_bus(struct pci_dev *pdev, struct pci_bus_region *region, |
367 | struct resource *res) | 369 | struct resource *res) |
368 | { | 370 | { |
369 | struct pci_pbm_info *pbm = pdev->bus->sysdata; | 371 | struct pci_pbm_info *pbm = pdev->bus->sysdata; |
370 | struct resource zero_res, *root; | 372 | struct resource zero_res, *root; |
371 | 373 | ||
372 | zero_res.start = 0; | 374 | zero_res.start = 0; |
373 | zero_res.end = 0; | 375 | zero_res.end = 0; |
374 | zero_res.flags = res->flags; | 376 | zero_res.flags = res->flags; |
375 | 377 | ||
376 | if (res->flags & IORESOURCE_IO) | 378 | if (res->flags & IORESOURCE_IO) |
377 | root = &pbm->io_space; | 379 | root = &pbm->io_space; |
378 | else | 380 | else |
379 | root = &pbm->mem_space; | 381 | root = &pbm->mem_space; |
380 | 382 | ||
381 | pbm->parent->resource_adjust(pdev, &zero_res, root); | 383 | pbm->parent->resource_adjust(pdev, &zero_res, root); |
382 | 384 | ||
383 | region->start = res->start - zero_res.start; | 385 | region->start = res->start - zero_res.start; |
384 | region->end = res->end - zero_res.start; | 386 | region->end = res->end - zero_res.start; |
385 | } | 387 | } |
386 | EXPORT_SYMBOL(pcibios_resource_to_bus); | 388 | EXPORT_SYMBOL(pcibios_resource_to_bus); |
387 | 389 | ||
388 | void pcibios_bus_to_resource(struct pci_dev *pdev, struct resource *res, | 390 | void pcibios_bus_to_resource(struct pci_dev *pdev, struct resource *res, |
389 | struct pci_bus_region *region) | 391 | struct pci_bus_region *region) |
390 | { | 392 | { |
391 | struct pci_pbm_info *pbm = pdev->bus->sysdata; | 393 | struct pci_pbm_info *pbm = pdev->bus->sysdata; |
392 | struct resource *root; | 394 | struct resource *root; |
393 | 395 | ||
394 | res->start = region->start; | 396 | res->start = region->start; |
395 | res->end = region->end; | 397 | res->end = region->end; |
396 | 398 | ||
397 | if (res->flags & IORESOURCE_IO) | 399 | if (res->flags & IORESOURCE_IO) |
398 | root = &pbm->io_space; | 400 | root = &pbm->io_space; |
399 | else | 401 | else |
400 | root = &pbm->mem_space; | 402 | root = &pbm->mem_space; |
401 | 403 | ||
402 | pbm->parent->resource_adjust(pdev, res, root); | 404 | pbm->parent->resource_adjust(pdev, res, root); |
403 | } | 405 | } |
404 | EXPORT_SYMBOL(pcibios_bus_to_resource); | 406 | EXPORT_SYMBOL(pcibios_bus_to_resource); |
405 | 407 | ||
406 | char * __init pcibios_setup(char *str) | 408 | char * __init pcibios_setup(char *str) |
407 | { | 409 | { |
408 | return str; | 410 | return str; |
409 | } | 411 | } |
410 | 412 | ||
411 | /* Platform support for /proc/bus/pci/X/Y mmap()s. */ | 413 | /* Platform support for /proc/bus/pci/X/Y mmap()s. */ |
412 | 414 | ||
413 | /* If the user uses a host-bridge as the PCI device, he may use | 415 | /* If the user uses a host-bridge as the PCI device, he may use |
414 | * this to perform a raw mmap() of the I/O or MEM space behind | 416 | * this to perform a raw mmap() of the I/O or MEM space behind |
415 | * that controller. | 417 | * that controller. |
416 | * | 418 | * |
417 | * This can be useful for execution of x86 PCI bios initialization code | 419 | * This can be useful for execution of x86 PCI bios initialization code |
418 | * on a PCI card, like the xfree86 int10 stuff does. | 420 | * on a PCI card, like the xfree86 int10 stuff does. |
419 | */ | 421 | */ |
420 | static int __pci_mmap_make_offset_bus(struct pci_dev *pdev, struct vm_area_struct *vma, | 422 | static int __pci_mmap_make_offset_bus(struct pci_dev *pdev, struct vm_area_struct *vma, |
421 | enum pci_mmap_state mmap_state) | 423 | enum pci_mmap_state mmap_state) |
422 | { | 424 | { |
423 | struct pcidev_cookie *pcp = pdev->sysdata; | 425 | struct pcidev_cookie *pcp = pdev->sysdata; |
424 | struct pci_pbm_info *pbm; | 426 | struct pci_pbm_info *pbm; |
425 | struct pci_controller_info *p; | 427 | struct pci_controller_info *p; |
426 | unsigned long space_size, user_offset, user_size; | 428 | unsigned long space_size, user_offset, user_size; |
427 | 429 | ||
428 | if (!pcp) | 430 | if (!pcp) |
429 | return -ENXIO; | 431 | return -ENXIO; |
430 | pbm = pcp->pbm; | 432 | pbm = pcp->pbm; |
431 | if (!pbm) | 433 | if (!pbm) |
432 | return -ENXIO; | 434 | return -ENXIO; |
433 | 435 | ||
434 | p = pbm->parent; | 436 | p = pbm->parent; |
435 | if (p->pbms_same_domain) { | 437 | if (p->pbms_same_domain) { |
436 | unsigned long lowest, highest; | 438 | unsigned long lowest, highest; |
437 | 439 | ||
438 | lowest = ~0UL; highest = 0UL; | 440 | lowest = ~0UL; highest = 0UL; |
439 | if (mmap_state == pci_mmap_io) { | 441 | if (mmap_state == pci_mmap_io) { |
440 | if (p->pbm_A.io_space.flags) { | 442 | if (p->pbm_A.io_space.flags) { |
441 | lowest = p->pbm_A.io_space.start; | 443 | lowest = p->pbm_A.io_space.start; |
442 | highest = p->pbm_A.io_space.end + 1; | 444 | highest = p->pbm_A.io_space.end + 1; |
443 | } | 445 | } |
444 | if (p->pbm_B.io_space.flags) { | 446 | if (p->pbm_B.io_space.flags) { |
445 | if (lowest > p->pbm_B.io_space.start) | 447 | if (lowest > p->pbm_B.io_space.start) |
446 | lowest = p->pbm_B.io_space.start; | 448 | lowest = p->pbm_B.io_space.start; |
447 | if (highest < p->pbm_B.io_space.end + 1) | 449 | if (highest < p->pbm_B.io_space.end + 1) |
448 | highest = p->pbm_B.io_space.end + 1; | 450 | highest = p->pbm_B.io_space.end + 1; |
449 | } | 451 | } |
450 | space_size = highest - lowest; | 452 | space_size = highest - lowest; |
451 | } else { | 453 | } else { |
452 | if (p->pbm_A.mem_space.flags) { | 454 | if (p->pbm_A.mem_space.flags) { |
453 | lowest = p->pbm_A.mem_space.start; | 455 | lowest = p->pbm_A.mem_space.start; |
454 | highest = p->pbm_A.mem_space.end + 1; | 456 | highest = p->pbm_A.mem_space.end + 1; |
455 | } | 457 | } |
456 | if (p->pbm_B.mem_space.flags) { | 458 | if (p->pbm_B.mem_space.flags) { |
457 | if (lowest > p->pbm_B.mem_space.start) | 459 | if (lowest > p->pbm_B.mem_space.start) |
458 | lowest = p->pbm_B.mem_space.start; | 460 | lowest = p->pbm_B.mem_space.start; |
459 | if (highest < p->pbm_B.mem_space.end + 1) | 461 | if (highest < p->pbm_B.mem_space.end + 1) |
460 | highest = p->pbm_B.mem_space.end + 1; | 462 | highest = p->pbm_B.mem_space.end + 1; |
461 | } | 463 | } |
462 | space_size = highest - lowest; | 464 | space_size = highest - lowest; |
463 | } | 465 | } |
464 | } else { | 466 | } else { |
465 | if (mmap_state == pci_mmap_io) { | 467 | if (mmap_state == pci_mmap_io) { |
466 | space_size = (pbm->io_space.end - | 468 | space_size = (pbm->io_space.end - |
467 | pbm->io_space.start) + 1; | 469 | pbm->io_space.start) + 1; |
468 | } else { | 470 | } else { |
469 | space_size = (pbm->mem_space.end - | 471 | space_size = (pbm->mem_space.end - |
470 | pbm->mem_space.start) + 1; | 472 | pbm->mem_space.start) + 1; |
471 | } | 473 | } |
472 | } | 474 | } |
473 | 475 | ||
474 | /* Make sure the request is in range. */ | 476 | /* Make sure the request is in range. */ |
475 | user_offset = vma->vm_pgoff << PAGE_SHIFT; | 477 | user_offset = vma->vm_pgoff << PAGE_SHIFT; |
476 | user_size = vma->vm_end - vma->vm_start; | 478 | user_size = vma->vm_end - vma->vm_start; |
477 | 479 | ||
478 | if (user_offset >= space_size || | 480 | if (user_offset >= space_size || |
479 | (user_offset + user_size) > space_size) | 481 | (user_offset + user_size) > space_size) |
480 | return -EINVAL; | 482 | return -EINVAL; |
481 | 483 | ||
482 | if (p->pbms_same_domain) { | 484 | if (p->pbms_same_domain) { |
483 | unsigned long lowest = ~0UL; | 485 | unsigned long lowest = ~0UL; |
484 | 486 | ||
485 | if (mmap_state == pci_mmap_io) { | 487 | if (mmap_state == pci_mmap_io) { |
486 | if (p->pbm_A.io_space.flags) | 488 | if (p->pbm_A.io_space.flags) |
487 | lowest = p->pbm_A.io_space.start; | 489 | lowest = p->pbm_A.io_space.start; |
488 | if (p->pbm_B.io_space.flags && | 490 | if (p->pbm_B.io_space.flags && |
489 | lowest > p->pbm_B.io_space.start) | 491 | lowest > p->pbm_B.io_space.start) |
490 | lowest = p->pbm_B.io_space.start; | 492 | lowest = p->pbm_B.io_space.start; |
491 | } else { | 493 | } else { |
492 | if (p->pbm_A.mem_space.flags) | 494 | if (p->pbm_A.mem_space.flags) |
493 | lowest = p->pbm_A.mem_space.start; | 495 | lowest = p->pbm_A.mem_space.start; |
494 | if (p->pbm_B.mem_space.flags && | 496 | if (p->pbm_B.mem_space.flags && |
495 | lowest > p->pbm_B.mem_space.start) | 497 | lowest > p->pbm_B.mem_space.start) |
496 | lowest = p->pbm_B.mem_space.start; | 498 | lowest = p->pbm_B.mem_space.start; |
497 | } | 499 | } |
498 | vma->vm_pgoff = (lowest + user_offset) >> PAGE_SHIFT; | 500 | vma->vm_pgoff = (lowest + user_offset) >> PAGE_SHIFT; |
499 | } else { | 501 | } else { |
500 | if (mmap_state == pci_mmap_io) { | 502 | if (mmap_state == pci_mmap_io) { |
501 | vma->vm_pgoff = (pbm->io_space.start + | 503 | vma->vm_pgoff = (pbm->io_space.start + |
502 | user_offset) >> PAGE_SHIFT; | 504 | user_offset) >> PAGE_SHIFT; |
503 | } else { | 505 | } else { |
504 | vma->vm_pgoff = (pbm->mem_space.start + | 506 | vma->vm_pgoff = (pbm->mem_space.start + |
505 | user_offset) >> PAGE_SHIFT; | 507 | user_offset) >> PAGE_SHIFT; |
506 | } | 508 | } |
507 | } | 509 | } |
508 | 510 | ||
509 | return 0; | 511 | return 0; |
510 | } | 512 | } |
511 | 513 | ||
512 | /* Adjust vm_pgoff of VMA such that it is the physical page offset corresponding | 514 | /* Adjust vm_pgoff of VMA such that it is the physical page offset corresponding |
513 | * to the 32-bit pci bus offset for DEV requested by the user. | 515 | * to the 32-bit pci bus offset for DEV requested by the user. |
514 | * | 516 | * |
515 | * Basically, the user finds the base address for his device which he wishes | 517 | * Basically, the user finds the base address for his device which he wishes |
516 | * to mmap. They read the 32-bit value from the config space base register, | 518 | * to mmap. They read the 32-bit value from the config space base register, |
517 | * add whatever PAGE_SIZE multiple offset they wish, and feed this into the | 519 | * add whatever PAGE_SIZE multiple offset they wish, and feed this into the |
518 | * offset parameter of mmap on /proc/bus/pci/XXX for that device. | 520 | * offset parameter of mmap on /proc/bus/pci/XXX for that device. |
519 | * | 521 | * |
520 | * Returns negative error code on failure, zero on success. | 522 | * Returns negative error code on failure, zero on success. |
521 | */ | 523 | */ |
522 | static int __pci_mmap_make_offset(struct pci_dev *dev, struct vm_area_struct *vma, | 524 | static int __pci_mmap_make_offset(struct pci_dev *dev, struct vm_area_struct *vma, |
523 | enum pci_mmap_state mmap_state) | 525 | enum pci_mmap_state mmap_state) |
524 | { | 526 | { |
525 | unsigned long user_offset = vma->vm_pgoff << PAGE_SHIFT; | 527 | unsigned long user_offset = vma->vm_pgoff << PAGE_SHIFT; |
526 | unsigned long user32 = user_offset & pci_memspace_mask; | 528 | unsigned long user32 = user_offset & pci_memspace_mask; |
527 | unsigned long largest_base, this_base, addr32; | 529 | unsigned long largest_base, this_base, addr32; |
528 | int i; | 530 | int i; |
529 | 531 | ||
530 | if ((dev->class >> 8) == PCI_CLASS_BRIDGE_HOST) | 532 | if ((dev->class >> 8) == PCI_CLASS_BRIDGE_HOST) |
531 | return __pci_mmap_make_offset_bus(dev, vma, mmap_state); | 533 | return __pci_mmap_make_offset_bus(dev, vma, mmap_state); |
532 | 534 | ||
533 | /* Figure out which base address this is for. */ | 535 | /* Figure out which base address this is for. */ |
534 | largest_base = 0UL; | 536 | largest_base = 0UL; |
535 | for (i = 0; i <= PCI_ROM_RESOURCE; i++) { | 537 | for (i = 0; i <= PCI_ROM_RESOURCE; i++) { |
536 | struct resource *rp = &dev->resource[i]; | 538 | struct resource *rp = &dev->resource[i]; |
537 | 539 | ||
538 | /* Active? */ | 540 | /* Active? */ |
539 | if (!rp->flags) | 541 | if (!rp->flags) |
540 | continue; | 542 | continue; |
541 | 543 | ||
542 | /* Same type? */ | 544 | /* Same type? */ |
543 | if (i == PCI_ROM_RESOURCE) { | 545 | if (i == PCI_ROM_RESOURCE) { |
544 | if (mmap_state != pci_mmap_mem) | 546 | if (mmap_state != pci_mmap_mem) |
545 | continue; | 547 | continue; |
546 | } else { | 548 | } else { |
547 | if ((mmap_state == pci_mmap_io && | 549 | if ((mmap_state == pci_mmap_io && |
548 | (rp->flags & IORESOURCE_IO) == 0) || | 550 | (rp->flags & IORESOURCE_IO) == 0) || |
549 | (mmap_state == pci_mmap_mem && | 551 | (mmap_state == pci_mmap_mem && |
550 | (rp->flags & IORESOURCE_MEM) == 0)) | 552 | (rp->flags & IORESOURCE_MEM) == 0)) |
551 | continue; | 553 | continue; |
552 | } | 554 | } |
553 | 555 | ||
554 | this_base = rp->start; | 556 | this_base = rp->start; |
555 | 557 | ||
556 | addr32 = (this_base & PAGE_MASK) & pci_memspace_mask; | 558 | addr32 = (this_base & PAGE_MASK) & pci_memspace_mask; |
557 | 559 | ||
558 | if (mmap_state == pci_mmap_io) | 560 | if (mmap_state == pci_mmap_io) |
559 | addr32 &= 0xffffff; | 561 | addr32 &= 0xffffff; |
560 | 562 | ||
561 | if (addr32 <= user32 && this_base > largest_base) | 563 | if (addr32 <= user32 && this_base > largest_base) |
562 | largest_base = this_base; | 564 | largest_base = this_base; |
563 | } | 565 | } |
564 | 566 | ||
565 | if (largest_base == 0UL) | 567 | if (largest_base == 0UL) |
566 | return -EINVAL; | 568 | return -EINVAL; |
567 | 569 | ||
568 | /* Now construct the final physical address. */ | 570 | /* Now construct the final physical address. */ |
569 | if (mmap_state == pci_mmap_io) | 571 | if (mmap_state == pci_mmap_io) |
570 | vma->vm_pgoff = (((largest_base & ~0xffffffUL) | user32) >> PAGE_SHIFT); | 572 | vma->vm_pgoff = (((largest_base & ~0xffffffUL) | user32) >> PAGE_SHIFT); |
571 | else | 573 | else |
572 | vma->vm_pgoff = (((largest_base & ~(pci_memspace_mask)) | user32) >> PAGE_SHIFT); | 574 | vma->vm_pgoff = (((largest_base & ~(pci_memspace_mask)) | user32) >> PAGE_SHIFT); |
573 | 575 | ||
574 | return 0; | 576 | return 0; |
575 | } | 577 | } |
576 | 578 | ||
577 | /* Set vm_flags of VMA, as appropriate for this architecture, for a pci device | 579 | /* Set vm_flags of VMA, as appropriate for this architecture, for a pci device |
578 | * mapping. | 580 | * mapping. |
579 | */ | 581 | */ |
580 | static void __pci_mmap_set_flags(struct pci_dev *dev, struct vm_area_struct *vma, | 582 | static void __pci_mmap_set_flags(struct pci_dev *dev, struct vm_area_struct *vma, |
581 | enum pci_mmap_state mmap_state) | 583 | enum pci_mmap_state mmap_state) |
582 | { | 584 | { |
583 | vma->vm_flags |= (VM_IO | VM_RESERVED); | 585 | vma->vm_flags |= (VM_IO | VM_RESERVED); |
584 | } | 586 | } |
585 | 587 | ||
586 | /* Set vm_page_prot of VMA, as appropriate for this architecture, for a pci | 588 | /* Set vm_page_prot of VMA, as appropriate for this architecture, for a pci |
587 | * device mapping. | 589 | * device mapping. |
588 | */ | 590 | */ |
589 | static void __pci_mmap_set_pgprot(struct pci_dev *dev, struct vm_area_struct *vma, | 591 | static void __pci_mmap_set_pgprot(struct pci_dev *dev, struct vm_area_struct *vma, |
590 | enum pci_mmap_state mmap_state) | 592 | enum pci_mmap_state mmap_state) |
591 | { | 593 | { |
592 | /* Our io_remap_pfn_range takes care of this, do nothing. */ | 594 | /* Our io_remap_pfn_range takes care of this, do nothing. */ |
593 | } | 595 | } |
594 | 596 | ||
595 | /* Perform the actual remap of the pages for a PCI device mapping, as appropriate | 597 | /* Perform the actual remap of the pages for a PCI device mapping, as appropriate |
596 | * for this architecture. The region in the process to map is described by vm_start | 598 | * for this architecture. The region in the process to map is described by vm_start |
597 | * and vm_end members of VMA, the base physical address is found in vm_pgoff. | 599 | * and vm_end members of VMA, the base physical address is found in vm_pgoff. |
598 | * The pci device structure is provided so that architectures may make mapping | 600 | * The pci device structure is provided so that architectures may make mapping |
599 | * decisions on a per-device or per-bus basis. | 601 | * decisions on a per-device or per-bus basis. |
600 | * | 602 | * |
601 | * Returns a negative error code on failure, zero on success. | 603 | * Returns a negative error code on failure, zero on success. |
602 | */ | 604 | */ |
603 | int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, | 605 | int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, |
604 | enum pci_mmap_state mmap_state, | 606 | enum pci_mmap_state mmap_state, |
605 | int write_combine) | 607 | int write_combine) |
606 | { | 608 | { |
607 | int ret; | 609 | int ret; |
608 | 610 | ||
609 | ret = __pci_mmap_make_offset(dev, vma, mmap_state); | 611 | ret = __pci_mmap_make_offset(dev, vma, mmap_state); |
610 | if (ret < 0) | 612 | if (ret < 0) |
611 | return ret; | 613 | return ret; |
612 | 614 | ||
613 | __pci_mmap_set_flags(dev, vma, mmap_state); | 615 | __pci_mmap_set_flags(dev, vma, mmap_state); |
614 | __pci_mmap_set_pgprot(dev, vma, mmap_state); | 616 | __pci_mmap_set_pgprot(dev, vma, mmap_state); |
615 | 617 | ||
616 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); | 618 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); |
617 | ret = io_remap_pfn_range(vma, vma->vm_start, | 619 | ret = io_remap_pfn_range(vma, vma->vm_start, |
618 | vma->vm_pgoff, | 620 | vma->vm_pgoff, |
619 | vma->vm_end - vma->vm_start, | 621 | vma->vm_end - vma->vm_start, |
620 | vma->vm_page_prot); | 622 | vma->vm_page_prot); |
621 | if (ret) | 623 | if (ret) |
622 | return ret; | 624 | return ret; |
623 | 625 | ||
624 | return 0; | 626 | return 0; |
625 | } | 627 | } |
626 | 628 | ||
627 | /* Return the domain nuber for this pci bus */ | 629 | /* Return the domain nuber for this pci bus */ |
628 | 630 | ||
629 | int pci_domain_nr(struct pci_bus *pbus) | 631 | int pci_domain_nr(struct pci_bus *pbus) |
630 | { | 632 | { |
631 | struct pci_pbm_info *pbm = pbus->sysdata; | 633 | struct pci_pbm_info *pbm = pbus->sysdata; |
632 | int ret; | 634 | int ret; |
633 | 635 | ||
634 | if (pbm == NULL || pbm->parent == NULL) { | 636 | if (pbm == NULL || pbm->parent == NULL) { |
635 | ret = -ENXIO; | 637 | ret = -ENXIO; |
636 | } else { | 638 | } else { |
637 | struct pci_controller_info *p = pbm->parent; | 639 | struct pci_controller_info *p = pbm->parent; |
638 | 640 | ||
639 | ret = p->index; | 641 | ret = p->index; |
640 | if (p->pbms_same_domain == 0) | 642 | if (p->pbms_same_domain == 0) |
641 | ret = ((ret << 1) + | 643 | ret = ((ret << 1) + |
642 | ((pbm == &pbm->parent->pbm_B) ? 1 : 0)); | 644 | ((pbm == &pbm->parent->pbm_B) ? 1 : 0)); |
643 | } | 645 | } |
644 | 646 | ||
645 | return ret; | 647 | return ret; |
646 | } | 648 | } |
647 | EXPORT_SYMBOL(pci_domain_nr); | 649 | EXPORT_SYMBOL(pci_domain_nr); |
650 | |||
651 | #ifdef CONFIG_PCI_MSI | ||
652 | int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc) | ||
653 | { | ||
654 | struct pcidev_cookie *pcp = pdev->sysdata; | ||
655 | struct pci_pbm_info *pbm = pcp->pbm; | ||
656 | struct pci_controller_info *p = pbm->parent; | ||
657 | int virt_irq, err; | ||
658 | |||
659 | if (!pbm->msi_num || !p->setup_msi_irq) | ||
660 | return -EINVAL; | ||
661 | |||
662 | err = p->setup_msi_irq(&virt_irq, pdev, desc); | ||
663 | if (err < 0) | ||
664 | return err; | ||
665 | |||
666 | return virt_irq; | ||
667 | } | ||
668 | |||
669 | void arch_teardown_msi_irq(unsigned int virt_irq) | ||
670 | { | ||
671 | struct msi_desc *entry = get_irq_data(virt_irq); | ||
672 | struct pci_dev *pdev = entry->dev; | ||
673 | struct pcidev_cookie *pcp = pdev->sysdata; | ||
674 | struct pci_pbm_info *pbm = pcp->pbm; | ||
675 | struct pci_controller_info *p = pbm->parent; | ||
676 | |||
677 | if (!pbm->msi_num || !p->setup_msi_irq) | ||
678 | return; | ||
679 | |||
680 | return p->teardown_msi_irq(virt_irq, pdev); | ||
681 | } | ||
682 | #endif /* !(CONFIG_PCI_MSI) */ | ||
648 | 683 | ||
649 | #endif /* !(CONFIG_PCI) */ | 684 | #endif /* !(CONFIG_PCI) */ |
650 | 685 |
arch/sparc64/kernel/pci_common.c
1 | /* $Id: pci_common.c,v 1.29 2002/02/01 00:56:03 davem Exp $ | 1 | /* $Id: pci_common.c,v 1.29 2002/02/01 00:56:03 davem Exp $ |
2 | * pci_common.c: PCI controller common support. | 2 | * pci_common.c: PCI controller common support. |
3 | * | 3 | * |
4 | * Copyright (C) 1999 David S. Miller (davem@redhat.com) | 4 | * Copyright (C) 1999 David S. Miller (davem@redhat.com) |
5 | */ | 5 | */ |
6 | 6 | ||
7 | #include <linux/string.h> | 7 | #include <linux/string.h> |
8 | #include <linux/slab.h> | 8 | #include <linux/slab.h> |
9 | #include <linux/init.h> | 9 | #include <linux/init.h> |
10 | #include <linux/pci.h> | ||
11 | #include <linux/device.h> | ||
10 | 12 | ||
11 | #include <asm/pbm.h> | 13 | #include <asm/pbm.h> |
12 | #include <asm/prom.h> | 14 | #include <asm/prom.h> |
13 | #include <asm/of_device.h> | 15 | #include <asm/of_device.h> |
14 | 16 | ||
15 | #include "pci_impl.h" | 17 | #include "pci_impl.h" |
16 | 18 | ||
17 | /* Fix self device of BUS and hook it into BUS->self. | 19 | /* Fix self device of BUS and hook it into BUS->self. |
18 | * The pci_scan_bus does not do this for the host bridge. | 20 | * The pci_scan_bus does not do this for the host bridge. |
19 | */ | 21 | */ |
20 | void __init pci_fixup_host_bridge_self(struct pci_bus *pbus) | 22 | void __init pci_fixup_host_bridge_self(struct pci_bus *pbus) |
21 | { | 23 | { |
22 | struct pci_dev *pdev; | 24 | struct pci_dev *pdev; |
23 | 25 | ||
24 | list_for_each_entry(pdev, &pbus->devices, bus_list) { | 26 | list_for_each_entry(pdev, &pbus->devices, bus_list) { |
25 | if (pdev->class >> 8 == PCI_CLASS_BRIDGE_HOST) { | 27 | if (pdev->class >> 8 == PCI_CLASS_BRIDGE_HOST) { |
26 | pbus->self = pdev; | 28 | pbus->self = pdev; |
27 | return; | 29 | return; |
28 | } | 30 | } |
29 | } | 31 | } |
30 | 32 | ||
31 | prom_printf("PCI: Critical error, cannot find host bridge PDEV.\n"); | 33 | prom_printf("PCI: Critical error, cannot find host bridge PDEV.\n"); |
32 | prom_halt(); | 34 | prom_halt(); |
33 | } | 35 | } |
34 | 36 | ||
35 | /* Find the OBP PROM device tree node for a PCI device. */ | 37 | /* Find the OBP PROM device tree node for a PCI device. */ |
36 | static struct device_node * __init | 38 | static struct device_node * __init |
37 | find_device_prom_node(struct pci_pbm_info *pbm, struct pci_dev *pdev, | 39 | find_device_prom_node(struct pci_pbm_info *pbm, struct pci_dev *pdev, |
38 | struct device_node *bus_node, | 40 | struct device_node *bus_node, |
39 | struct linux_prom_pci_registers **pregs, | 41 | struct linux_prom_pci_registers **pregs, |
40 | int *nregs) | 42 | int *nregs) |
41 | { | 43 | { |
42 | struct device_node *dp; | 44 | struct device_node *dp; |
43 | 45 | ||
44 | *nregs = 0; | 46 | *nregs = 0; |
45 | 47 | ||
46 | /* | 48 | /* |
47 | * Return the PBM's PROM node in case we are it's PCI device, | 49 | * Return the PBM's PROM node in case we are it's PCI device, |
48 | * as the PBM's reg property is different to standard PCI reg | 50 | * as the PBM's reg property is different to standard PCI reg |
49 | * properties. We would delete this device entry otherwise, | 51 | * properties. We would delete this device entry otherwise, |
50 | * which confuses XFree86's device probing... | 52 | * which confuses XFree86's device probing... |
51 | */ | 53 | */ |
52 | if ((pdev->bus->number == pbm->pci_bus->number) && (pdev->devfn == 0) && | 54 | if ((pdev->bus->number == pbm->pci_bus->number) && (pdev->devfn == 0) && |
53 | (pdev->vendor == PCI_VENDOR_ID_SUN) && | 55 | (pdev->vendor == PCI_VENDOR_ID_SUN) && |
54 | (pdev->device == PCI_DEVICE_ID_SUN_PBM || | 56 | (pdev->device == PCI_DEVICE_ID_SUN_PBM || |
55 | pdev->device == PCI_DEVICE_ID_SUN_SCHIZO || | 57 | pdev->device == PCI_DEVICE_ID_SUN_SCHIZO || |
56 | pdev->device == PCI_DEVICE_ID_SUN_TOMATILLO || | 58 | pdev->device == PCI_DEVICE_ID_SUN_TOMATILLO || |
57 | pdev->device == PCI_DEVICE_ID_SUN_SABRE || | 59 | pdev->device == PCI_DEVICE_ID_SUN_SABRE || |
58 | pdev->device == PCI_DEVICE_ID_SUN_HUMMINGBIRD)) | 60 | pdev->device == PCI_DEVICE_ID_SUN_HUMMINGBIRD)) |
59 | return bus_node; | 61 | return bus_node; |
60 | 62 | ||
61 | dp = bus_node->child; | 63 | dp = bus_node->child; |
62 | while (dp) { | 64 | while (dp) { |
63 | struct linux_prom_pci_registers *regs; | 65 | struct linux_prom_pci_registers *regs; |
64 | struct property *prop; | 66 | struct property *prop; |
65 | int len; | 67 | int len; |
66 | 68 | ||
67 | prop = of_find_property(dp, "reg", &len); | 69 | prop = of_find_property(dp, "reg", &len); |
68 | if (!prop) | 70 | if (!prop) |
69 | goto do_next_sibling; | 71 | goto do_next_sibling; |
70 | 72 | ||
71 | regs = prop->value; | 73 | regs = prop->value; |
72 | if (((regs[0].phys_hi >> 8) & 0xff) == pdev->devfn) { | 74 | if (((regs[0].phys_hi >> 8) & 0xff) == pdev->devfn) { |
73 | *pregs = regs; | 75 | *pregs = regs; |
74 | *nregs = len / sizeof(struct linux_prom_pci_registers); | 76 | *nregs = len / sizeof(struct linux_prom_pci_registers); |
75 | return dp; | 77 | return dp; |
76 | } | 78 | } |
77 | 79 | ||
78 | do_next_sibling: | 80 | do_next_sibling: |
79 | dp = dp->sibling; | 81 | dp = dp->sibling; |
80 | } | 82 | } |
81 | 83 | ||
82 | return NULL; | 84 | return NULL; |
83 | } | 85 | } |
84 | 86 | ||
85 | /* Older versions of OBP on PCI systems encode 64-bit MEM | 87 | /* Older versions of OBP on PCI systems encode 64-bit MEM |
86 | * space assignments incorrectly, this fixes them up. We also | 88 | * space assignments incorrectly, this fixes them up. We also |
87 | * take the opportunity here to hide other kinds of bogus | 89 | * take the opportunity here to hide other kinds of bogus |
88 | * assignments. | 90 | * assignments. |
89 | */ | 91 | */ |
90 | static void __init fixup_obp_assignments(struct pci_dev *pdev, | 92 | static void __init fixup_obp_assignments(struct pci_dev *pdev, |
91 | struct pcidev_cookie *pcp) | 93 | struct pcidev_cookie *pcp) |
92 | { | 94 | { |
93 | int i; | 95 | int i; |
94 | 96 | ||
95 | if (pdev->vendor == PCI_VENDOR_ID_AL && | 97 | if (pdev->vendor == PCI_VENDOR_ID_AL && |
96 | (pdev->device == PCI_DEVICE_ID_AL_M7101 || | 98 | (pdev->device == PCI_DEVICE_ID_AL_M7101 || |
97 | pdev->device == PCI_DEVICE_ID_AL_M1533)) { | 99 | pdev->device == PCI_DEVICE_ID_AL_M1533)) { |
98 | int i; | 100 | int i; |
99 | 101 | ||
100 | /* Zap all of the normal resources, they are | 102 | /* Zap all of the normal resources, they are |
101 | * meaningless and generate bogus resource collision | 103 | * meaningless and generate bogus resource collision |
102 | * messages. This is OpenBoot's ill-fated attempt to | 104 | * messages. This is OpenBoot's ill-fated attempt to |
103 | * represent the implicit resources that these devices | 105 | * represent the implicit resources that these devices |
104 | * have. | 106 | * have. |
105 | */ | 107 | */ |
106 | pcp->num_prom_assignments = 0; | 108 | pcp->num_prom_assignments = 0; |
107 | for (i = 0; i < 6; i++) { | 109 | for (i = 0; i < 6; i++) { |
108 | pdev->resource[i].start = | 110 | pdev->resource[i].start = |
109 | pdev->resource[i].end = | 111 | pdev->resource[i].end = |
110 | pdev->resource[i].flags = 0; | 112 | pdev->resource[i].flags = 0; |
111 | } | 113 | } |
112 | pdev->resource[PCI_ROM_RESOURCE].start = | 114 | pdev->resource[PCI_ROM_RESOURCE].start = |
113 | pdev->resource[PCI_ROM_RESOURCE].end = | 115 | pdev->resource[PCI_ROM_RESOURCE].end = |
114 | pdev->resource[PCI_ROM_RESOURCE].flags = 0; | 116 | pdev->resource[PCI_ROM_RESOURCE].flags = 0; |
115 | return; | 117 | return; |
116 | } | 118 | } |
117 | 119 | ||
118 | for (i = 0; i < pcp->num_prom_assignments; i++) { | 120 | for (i = 0; i < pcp->num_prom_assignments; i++) { |
119 | struct linux_prom_pci_registers *ap; | 121 | struct linux_prom_pci_registers *ap; |
120 | int space; | 122 | int space; |
121 | 123 | ||
122 | ap = &pcp->prom_assignments[i]; | 124 | ap = &pcp->prom_assignments[i]; |
123 | space = ap->phys_hi >> 24; | 125 | space = ap->phys_hi >> 24; |
124 | if ((space & 0x3) == 2 && | 126 | if ((space & 0x3) == 2 && |
125 | (space & 0x4) != 0) { | 127 | (space & 0x4) != 0) { |
126 | ap->phys_hi &= ~(0x7 << 24); | 128 | ap->phys_hi &= ~(0x7 << 24); |
127 | ap->phys_hi |= 0x3 << 24; | 129 | ap->phys_hi |= 0x3 << 24; |
128 | } | 130 | } |
129 | } | 131 | } |
130 | } | 132 | } |
131 | 133 | ||
134 | static ssize_t | ||
135 | show_pciobppath_attr(struct device * dev, struct device_attribute * attr, char * buf) | ||
136 | { | ||
137 | struct pci_dev *pdev; | ||
138 | struct pcidev_cookie *sysdata; | ||
139 | |||
140 | pdev = to_pci_dev(dev); | ||
141 | sysdata = pdev->sysdata; | ||
142 | |||
143 | return snprintf (buf, PAGE_SIZE, "%s\n", sysdata->prom_node->full_name); | ||
144 | } | ||
145 | |||
146 | static DEVICE_ATTR(obppath, S_IRUSR | S_IRGRP | S_IROTH, show_pciobppath_attr, NULL); | ||
147 | |||
132 | /* Fill in the PCI device cookie sysdata for the given | 148 | /* Fill in the PCI device cookie sysdata for the given |
133 | * PCI device. This cookie is the means by which one | 149 | * PCI device. This cookie is the means by which one |
134 | * can get to OBP and PCI controller specific information | 150 | * can get to OBP and PCI controller specific information |
135 | * for a PCI device. | 151 | * for a PCI device. |
136 | */ | 152 | */ |
137 | static void __init pdev_cookie_fillin(struct pci_pbm_info *pbm, | 153 | static void __init pdev_cookie_fillin(struct pci_pbm_info *pbm, |
138 | struct pci_dev *pdev, | 154 | struct pci_dev *pdev, |
139 | struct device_node *bus_node) | 155 | struct device_node *bus_node) |
140 | { | 156 | { |
141 | struct linux_prom_pci_registers *pregs = NULL; | 157 | struct linux_prom_pci_registers *pregs = NULL; |
142 | struct pcidev_cookie *pcp; | 158 | struct pcidev_cookie *pcp; |
143 | struct device_node *dp; | 159 | struct device_node *dp; |
144 | struct property *prop; | 160 | struct property *prop; |
145 | int nregs, len; | 161 | int nregs, len, err; |
146 | 162 | ||
147 | dp = find_device_prom_node(pbm, pdev, bus_node, | 163 | dp = find_device_prom_node(pbm, pdev, bus_node, |
148 | &pregs, &nregs); | 164 | &pregs, &nregs); |
149 | if (!dp) { | 165 | if (!dp) { |
150 | /* If it is not in the OBP device tree then | 166 | /* If it is not in the OBP device tree then |
151 | * there must be a damn good reason for it. | 167 | * there must be a damn good reason for it. |
152 | * | 168 | * |
153 | * So what we do is delete the device from the | 169 | * So what we do is delete the device from the |
154 | * PCI device tree completely. This scenario | 170 | * PCI device tree completely. This scenario |
155 | * is seen, for example, on CP1500 for the | 171 | * is seen, for example, on CP1500 for the |
156 | * second EBUS/HappyMeal pair if the external | 172 | * second EBUS/HappyMeal pair if the external |
157 | * connector for it is not present. | 173 | * connector for it is not present. |
158 | */ | 174 | */ |
159 | pci_remove_bus_device(pdev); | 175 | pci_remove_bus_device(pdev); |
160 | return; | 176 | return; |
161 | } | 177 | } |
162 | 178 | ||
163 | pcp = kzalloc(sizeof(*pcp), GFP_ATOMIC); | 179 | pcp = kzalloc(sizeof(*pcp), GFP_ATOMIC); |
164 | if (pcp == NULL) { | 180 | if (pcp == NULL) { |
165 | prom_printf("PCI_COOKIE: Fatal malloc error, aborting...\n"); | 181 | prom_printf("PCI_COOKIE: Fatal malloc error, aborting...\n"); |
166 | prom_halt(); | 182 | prom_halt(); |
167 | } | 183 | } |
168 | pcp->pbm = pbm; | 184 | pcp->pbm = pbm; |
169 | pcp->prom_node = dp; | 185 | pcp->prom_node = dp; |
170 | pcp->op = of_find_device_by_node(dp); | 186 | pcp->op = of_find_device_by_node(dp); |
171 | memcpy(pcp->prom_regs, pregs, | 187 | memcpy(pcp->prom_regs, pregs, |
172 | nregs * sizeof(struct linux_prom_pci_registers)); | 188 | nregs * sizeof(struct linux_prom_pci_registers)); |
173 | pcp->num_prom_regs = nregs; | 189 | pcp->num_prom_regs = nregs; |
174 | 190 | ||
175 | /* We can't have the pcidev_cookie assignments be just | 191 | /* We can't have the pcidev_cookie assignments be just |
176 | * direct pointers into the property value, since they | 192 | * direct pointers into the property value, since they |
177 | * are potentially modified by the probing process. | 193 | * are potentially modified by the probing process. |
178 | */ | 194 | */ |
179 | prop = of_find_property(dp, "assigned-addresses", &len); | 195 | prop = of_find_property(dp, "assigned-addresses", &len); |
180 | if (!prop) { | 196 | if (!prop) { |
181 | pcp->num_prom_assignments = 0; | 197 | pcp->num_prom_assignments = 0; |
182 | } else { | 198 | } else { |
183 | memcpy(pcp->prom_assignments, prop->value, len); | 199 | memcpy(pcp->prom_assignments, prop->value, len); |
184 | pcp->num_prom_assignments = | 200 | pcp->num_prom_assignments = |
185 | (len / sizeof(pcp->prom_assignments[0])); | 201 | (len / sizeof(pcp->prom_assignments[0])); |
186 | } | 202 | } |
187 | 203 | ||
188 | if (strcmp(dp->name, "ebus") == 0) { | 204 | if (strcmp(dp->name, "ebus") == 0) { |
189 | struct linux_prom_ebus_ranges *erng; | 205 | struct linux_prom_ebus_ranges *erng; |
190 | int iter; | 206 | int iter; |
191 | 207 | ||
192 | /* EBUS is special... */ | 208 | /* EBUS is special... */ |
193 | prop = of_find_property(dp, "ranges", &len); | 209 | prop = of_find_property(dp, "ranges", &len); |
194 | if (!prop) { | 210 | if (!prop) { |
195 | prom_printf("EBUS: Fatal error, no range property\n"); | 211 | prom_printf("EBUS: Fatal error, no range property\n"); |
196 | prom_halt(); | 212 | prom_halt(); |
197 | } | 213 | } |
198 | erng = prop->value; | 214 | erng = prop->value; |
199 | len = (len / sizeof(erng[0])); | 215 | len = (len / sizeof(erng[0])); |
200 | for (iter = 0; iter < len; iter++) { | 216 | for (iter = 0; iter < len; iter++) { |
201 | struct linux_prom_ebus_ranges *ep = &erng[iter]; | 217 | struct linux_prom_ebus_ranges *ep = &erng[iter]; |
202 | struct linux_prom_pci_registers *ap; | 218 | struct linux_prom_pci_registers *ap; |
203 | 219 | ||
204 | ap = &pcp->prom_assignments[iter]; | 220 | ap = &pcp->prom_assignments[iter]; |
205 | 221 | ||
206 | ap->phys_hi = ep->parent_phys_hi; | 222 | ap->phys_hi = ep->parent_phys_hi; |
207 | ap->phys_mid = ep->parent_phys_mid; | 223 | ap->phys_mid = ep->parent_phys_mid; |
208 | ap->phys_lo = ep->parent_phys_lo; | 224 | ap->phys_lo = ep->parent_phys_lo; |
209 | ap->size_hi = 0; | 225 | ap->size_hi = 0; |
210 | ap->size_lo = ep->size; | 226 | ap->size_lo = ep->size; |
211 | } | 227 | } |
212 | pcp->num_prom_assignments = len; | 228 | pcp->num_prom_assignments = len; |
213 | } | 229 | } |
214 | 230 | ||
215 | fixup_obp_assignments(pdev, pcp); | 231 | fixup_obp_assignments(pdev, pcp); |
216 | 232 | ||
217 | pdev->sysdata = pcp; | 233 | pdev->sysdata = pcp; |
234 | |||
235 | /* we don't really care if we can create this file or not, | ||
236 | * but we need to assign the result of the call or the world will fall | ||
237 | * under alien invasion and everybody will be frozen on a spaceship | ||
238 | * ready to be eaten on alpha centauri by some green and jelly humanoid. | ||
239 | */ | ||
240 | err = sysfs_create_file(&pdev->dev.kobj, &dev_attr_obppath.attr); | ||
218 | } | 241 | } |
219 | 242 | ||
220 | void __init pci_fill_in_pbm_cookies(struct pci_bus *pbus, | 243 | void __init pci_fill_in_pbm_cookies(struct pci_bus *pbus, |
221 | struct pci_pbm_info *pbm, | 244 | struct pci_pbm_info *pbm, |
222 | struct device_node *dp) | 245 | struct device_node *dp) |
223 | { | 246 | { |
224 | struct pci_dev *pdev, *pdev_next; | 247 | struct pci_dev *pdev, *pdev_next; |
225 | struct pci_bus *this_pbus, *pbus_next; | 248 | struct pci_bus *this_pbus, *pbus_next; |
226 | 249 | ||
227 | /* This must be _safe because the cookie fillin | 250 | /* This must be _safe because the cookie fillin |
228 | routine can delete devices from the tree. */ | 251 | routine can delete devices from the tree. */ |
229 | list_for_each_entry_safe(pdev, pdev_next, &pbus->devices, bus_list) | 252 | list_for_each_entry_safe(pdev, pdev_next, &pbus->devices, bus_list) |
230 | pdev_cookie_fillin(pbm, pdev, dp); | 253 | pdev_cookie_fillin(pbm, pdev, dp); |
231 | 254 | ||
232 | list_for_each_entry_safe(this_pbus, pbus_next, &pbus->children, node) { | 255 | list_for_each_entry_safe(this_pbus, pbus_next, &pbus->children, node) { |
233 | struct pcidev_cookie *pcp = this_pbus->self->sysdata; | 256 | struct pcidev_cookie *pcp = this_pbus->self->sysdata; |
234 | 257 | ||
235 | pci_fill_in_pbm_cookies(this_pbus, pbm, pcp->prom_node); | 258 | pci_fill_in_pbm_cookies(this_pbus, pbm, pcp->prom_node); |
236 | } | 259 | } |
237 | } | 260 | } |
238 | 261 | ||
239 | static void __init bad_assignment(struct pci_dev *pdev, | 262 | static void __init bad_assignment(struct pci_dev *pdev, |
240 | struct linux_prom_pci_registers *ap, | 263 | struct linux_prom_pci_registers *ap, |
241 | struct resource *res, | 264 | struct resource *res, |
242 | int do_prom_halt) | 265 | int do_prom_halt) |
243 | { | 266 | { |
244 | prom_printf("PCI: Bogus PROM assignment. BUS[%02x] DEVFN[%x]\n", | 267 | prom_printf("PCI: Bogus PROM assignment. BUS[%02x] DEVFN[%x]\n", |
245 | pdev->bus->number, pdev->devfn); | 268 | pdev->bus->number, pdev->devfn); |
246 | if (ap) | 269 | if (ap) |
247 | prom_printf("PCI: phys[%08x:%08x:%08x] size[%08x:%08x]\n", | 270 | prom_printf("PCI: phys[%08x:%08x:%08x] size[%08x:%08x]\n", |
248 | ap->phys_hi, ap->phys_mid, ap->phys_lo, | 271 | ap->phys_hi, ap->phys_mid, ap->phys_lo, |
249 | ap->size_hi, ap->size_lo); | 272 | ap->size_hi, ap->size_lo); |
250 | if (res) | 273 | if (res) |
251 | prom_printf("PCI: RES[%016lx-->%016lx:(%lx)]\n", | 274 | prom_printf("PCI: RES[%016lx-->%016lx:(%lx)]\n", |
252 | res->start, res->end, res->flags); | 275 | res->start, res->end, res->flags); |
253 | if (do_prom_halt) | 276 | if (do_prom_halt) |
254 | prom_halt(); | 277 | prom_halt(); |
255 | } | 278 | } |
256 | 279 | ||
257 | static struct resource * | 280 | static struct resource * |
258 | __init get_root_resource(struct linux_prom_pci_registers *ap, | 281 | __init get_root_resource(struct linux_prom_pci_registers *ap, |
259 | struct pci_pbm_info *pbm) | 282 | struct pci_pbm_info *pbm) |
260 | { | 283 | { |
261 | int space = (ap->phys_hi >> 24) & 3; | 284 | int space = (ap->phys_hi >> 24) & 3; |
262 | 285 | ||
263 | switch (space) { | 286 | switch (space) { |
264 | case 0: | 287 | case 0: |
265 | /* Configuration space, silently ignore it. */ | 288 | /* Configuration space, silently ignore it. */ |
266 | return NULL; | 289 | return NULL; |
267 | 290 | ||
268 | case 1: | 291 | case 1: |
269 | /* 16-bit IO space */ | 292 | /* 16-bit IO space */ |
270 | return &pbm->io_space; | 293 | return &pbm->io_space; |
271 | 294 | ||
272 | case 2: | 295 | case 2: |
273 | /* 32-bit MEM space */ | 296 | /* 32-bit MEM space */ |
274 | return &pbm->mem_space; | 297 | return &pbm->mem_space; |
275 | 298 | ||
276 | case 3: | 299 | case 3: |
277 | /* 64-bit MEM space, these are allocated out of | 300 | /* 64-bit MEM space, these are allocated out of |
278 | * the 32-bit mem_space range for the PBM, ie. | 301 | * the 32-bit mem_space range for the PBM, ie. |
279 | * we just zero out the upper 32-bits. | 302 | * we just zero out the upper 32-bits. |
280 | */ | 303 | */ |
281 | return &pbm->mem_space; | 304 | return &pbm->mem_space; |
282 | 305 | ||
283 | default: | 306 | default: |
284 | printk("PCI: What is resource space %x?\n", space); | 307 | printk("PCI: What is resource space %x?\n", space); |
285 | return NULL; | 308 | return NULL; |
286 | }; | 309 | }; |
287 | } | 310 | } |
288 | 311 | ||
289 | static struct resource * | 312 | static struct resource * |
290 | __init get_device_resource(struct linux_prom_pci_registers *ap, | 313 | __init get_device_resource(struct linux_prom_pci_registers *ap, |
291 | struct pci_dev *pdev) | 314 | struct pci_dev *pdev) |
292 | { | 315 | { |
293 | struct resource *res; | 316 | struct resource *res; |
294 | int breg = (ap->phys_hi & 0xff); | 317 | int breg = (ap->phys_hi & 0xff); |
295 | 318 | ||
296 | switch (breg) { | 319 | switch (breg) { |
297 | case PCI_ROM_ADDRESS: | 320 | case PCI_ROM_ADDRESS: |
298 | /* Unfortunately I have seen several cases where | 321 | /* Unfortunately I have seen several cases where |
299 | * buggy FCODE uses a space value of '1' (I/O space) | 322 | * buggy FCODE uses a space value of '1' (I/O space) |
300 | * in the register property for the ROM address | 323 | * in the register property for the ROM address |
301 | * so disable this sanity check for now. | 324 | * so disable this sanity check for now. |
302 | */ | 325 | */ |
303 | #if 0 | 326 | #if 0 |
304 | { | 327 | { |
305 | int space = (ap->phys_hi >> 24) & 3; | 328 | int space = (ap->phys_hi >> 24) & 3; |
306 | 329 | ||
307 | /* It had better be MEM space. */ | 330 | /* It had better be MEM space. */ |
308 | if (space != 2) | 331 | if (space != 2) |
309 | bad_assignment(pdev, ap, NULL, 0); | 332 | bad_assignment(pdev, ap, NULL, 0); |
310 | } | 333 | } |
311 | #endif | 334 | #endif |
312 | res = &pdev->resource[PCI_ROM_RESOURCE]; | 335 | res = &pdev->resource[PCI_ROM_RESOURCE]; |
313 | break; | 336 | break; |
314 | 337 | ||
315 | case PCI_BASE_ADDRESS_0: | 338 | case PCI_BASE_ADDRESS_0: |
316 | case PCI_BASE_ADDRESS_1: | 339 | case PCI_BASE_ADDRESS_1: |
317 | case PCI_BASE_ADDRESS_2: | 340 | case PCI_BASE_ADDRESS_2: |
318 | case PCI_BASE_ADDRESS_3: | 341 | case PCI_BASE_ADDRESS_3: |
319 | case PCI_BASE_ADDRESS_4: | 342 | case PCI_BASE_ADDRESS_4: |
320 | case PCI_BASE_ADDRESS_5: | 343 | case PCI_BASE_ADDRESS_5: |
321 | res = &pdev->resource[(breg - PCI_BASE_ADDRESS_0) / 4]; | 344 | res = &pdev->resource[(breg - PCI_BASE_ADDRESS_0) / 4]; |
322 | break; | 345 | break; |
323 | 346 | ||
324 | default: | 347 | default: |
325 | bad_assignment(pdev, ap, NULL, 0); | 348 | bad_assignment(pdev, ap, NULL, 0); |
326 | res = NULL; | 349 | res = NULL; |
327 | break; | 350 | break; |
328 | }; | 351 | }; |
329 | 352 | ||
330 | return res; | 353 | return res; |
331 | } | 354 | } |
332 | 355 | ||
333 | static void __init pdev_record_assignments(struct pci_pbm_info *pbm, | 356 | static void __init pdev_record_assignments(struct pci_pbm_info *pbm, |
334 | struct pci_dev *pdev) | 357 | struct pci_dev *pdev) |
335 | { | 358 | { |
336 | struct pcidev_cookie *pcp = pdev->sysdata; | 359 | struct pcidev_cookie *pcp = pdev->sysdata; |
337 | int i; | 360 | int i; |
338 | 361 | ||
339 | for (i = 0; i < pcp->num_prom_assignments; i++) { | 362 | for (i = 0; i < pcp->num_prom_assignments; i++) { |
340 | struct linux_prom_pci_registers *ap; | 363 | struct linux_prom_pci_registers *ap; |
341 | struct resource *root, *res; | 364 | struct resource *root, *res; |
342 | 365 | ||
343 | /* The format of this property is specified in | 366 | /* The format of this property is specified in |
344 | * the PCI Bus Binding to IEEE1275-1994. | 367 | * the PCI Bus Binding to IEEE1275-1994. |
345 | */ | 368 | */ |
346 | ap = &pcp->prom_assignments[i]; | 369 | ap = &pcp->prom_assignments[i]; |
347 | root = get_root_resource(ap, pbm); | 370 | root = get_root_resource(ap, pbm); |
348 | res = get_device_resource(ap, pdev); | 371 | res = get_device_resource(ap, pdev); |
349 | if (root == NULL || res == NULL || | 372 | if (root == NULL || res == NULL || |
350 | res->flags == 0) | 373 | res->flags == 0) |
351 | continue; | 374 | continue; |
352 | 375 | ||
353 | /* Ok we know which resource this PROM assignment is | 376 | /* Ok we know which resource this PROM assignment is |
354 | * for, sanity check it. | 377 | * for, sanity check it. |
355 | */ | 378 | */ |
356 | if ((res->start & 0xffffffffUL) != ap->phys_lo) | 379 | if ((res->start & 0xffffffffUL) != ap->phys_lo) |
357 | bad_assignment(pdev, ap, res, 1); | 380 | bad_assignment(pdev, ap, res, 1); |
358 | 381 | ||
359 | /* If it is a 64-bit MEM space assignment, verify that | 382 | /* If it is a 64-bit MEM space assignment, verify that |
360 | * the resource is too and that the upper 32-bits match. | 383 | * the resource is too and that the upper 32-bits match. |
361 | */ | 384 | */ |
362 | if (((ap->phys_hi >> 24) & 3) == 3) { | 385 | if (((ap->phys_hi >> 24) & 3) == 3) { |
363 | if (((res->flags & IORESOURCE_MEM) == 0) || | 386 | if (((res->flags & IORESOURCE_MEM) == 0) || |
364 | ((res->flags & PCI_BASE_ADDRESS_MEM_TYPE_MASK) | 387 | ((res->flags & PCI_BASE_ADDRESS_MEM_TYPE_MASK) |
365 | != PCI_BASE_ADDRESS_MEM_TYPE_64)) | 388 | != PCI_BASE_ADDRESS_MEM_TYPE_64)) |
366 | bad_assignment(pdev, ap, res, 1); | 389 | bad_assignment(pdev, ap, res, 1); |
367 | if ((res->start >> 32) != ap->phys_mid) | 390 | if ((res->start >> 32) != ap->phys_mid) |
368 | bad_assignment(pdev, ap, res, 1); | 391 | bad_assignment(pdev, ap, res, 1); |
369 | 392 | ||
370 | /* PBM cannot generate cpu initiated PIOs | 393 | /* PBM cannot generate cpu initiated PIOs |
371 | * to the full 64-bit space. Therefore the | 394 | * to the full 64-bit space. Therefore the |
372 | * upper 32-bits better be zero. If it is | 395 | * upper 32-bits better be zero. If it is |
373 | * not, just skip it and we will assign it | 396 | * not, just skip it and we will assign it |
374 | * properly ourselves. | 397 | * properly ourselves. |
375 | */ | 398 | */ |
376 | if ((res->start >> 32) != 0UL) { | 399 | if ((res->start >> 32) != 0UL) { |
377 | printk(KERN_ERR "PCI: OBP assigns out of range MEM address " | 400 | printk(KERN_ERR "PCI: OBP assigns out of range MEM address " |
378 | "%016lx for region %ld on device %s\n", | 401 | "%016lx for region %ld on device %s\n", |
379 | res->start, (res - &pdev->resource[0]), pci_name(pdev)); | 402 | res->start, (res - &pdev->resource[0]), pci_name(pdev)); |
380 | continue; | 403 | continue; |
381 | } | 404 | } |
382 | } | 405 | } |
383 | 406 | ||
384 | /* Adjust the resource into the physical address space | 407 | /* Adjust the resource into the physical address space |
385 | * of this PBM. | 408 | * of this PBM. |
386 | */ | 409 | */ |
387 | pbm->parent->resource_adjust(pdev, res, root); | 410 | pbm->parent->resource_adjust(pdev, res, root); |
388 | 411 | ||
389 | if (request_resource(root, res) < 0) { | 412 | if (request_resource(root, res) < 0) { |
390 | int rnum; | 413 | int rnum; |
391 | 414 | ||
392 | /* OK, there is some conflict. But this is fine | 415 | /* OK, there is some conflict. But this is fine |
393 | * since we'll reassign it in the fixup pass. | 416 | * since we'll reassign it in the fixup pass. |
394 | * | 417 | * |
395 | * Do not print the warning for ROM resources | 418 | * Do not print the warning for ROM resources |
396 | * as such a conflict is quite common and | 419 | * as such a conflict is quite common and |
397 | * harmless as the ROM bar is disabled. | 420 | * harmless as the ROM bar is disabled. |
398 | */ | 421 | */ |
399 | rnum = (res - &pdev->resource[0]); | 422 | rnum = (res - &pdev->resource[0]); |
400 | if (rnum != PCI_ROM_RESOURCE) | 423 | if (rnum != PCI_ROM_RESOURCE) |
401 | printk(KERN_ERR "PCI: Resource collision, " | 424 | printk(KERN_ERR "PCI: Resource collision, " |
402 | "region %d " | 425 | "region %d " |
403 | "[%016lx:%016lx] of device %s\n", | 426 | "[%016lx:%016lx] of device %s\n", |
404 | rnum, | 427 | rnum, |
405 | res->start, res->end, | 428 | res->start, res->end, |
406 | pci_name(pdev)); | 429 | pci_name(pdev)); |
407 | } | 430 | } |
408 | } | 431 | } |
409 | } | 432 | } |
410 | 433 | ||
411 | void __init pci_record_assignments(struct pci_pbm_info *pbm, | 434 | void __init pci_record_assignments(struct pci_pbm_info *pbm, |
412 | struct pci_bus *pbus) | 435 | struct pci_bus *pbus) |
413 | { | 436 | { |
414 | struct pci_dev *dev; | 437 | struct pci_dev *dev; |
415 | struct pci_bus *bus; | 438 | struct pci_bus *bus; |
416 | 439 | ||
417 | list_for_each_entry(dev, &pbus->devices, bus_list) | 440 | list_for_each_entry(dev, &pbus->devices, bus_list) |
418 | pdev_record_assignments(pbm, dev); | 441 | pdev_record_assignments(pbm, dev); |
419 | 442 | ||
420 | list_for_each_entry(bus, &pbus->children, node) | 443 | list_for_each_entry(bus, &pbus->children, node) |
421 | pci_record_assignments(pbm, bus); | 444 | pci_record_assignments(pbm, bus); |
422 | } | 445 | } |
423 | 446 | ||
424 | /* Return non-zero if PDEV has implicit I/O resources even | 447 | /* Return non-zero if PDEV has implicit I/O resources even |
425 | * though it may not have an I/O base address register | 448 | * though it may not have an I/O base address register |
426 | * active. | 449 | * active. |
427 | */ | 450 | */ |
428 | static int __init has_implicit_io(struct pci_dev *pdev) | 451 | static int __init has_implicit_io(struct pci_dev *pdev) |
429 | { | 452 | { |
430 | int class = pdev->class >> 8; | 453 | int class = pdev->class >> 8; |
431 | 454 | ||
432 | if (class == PCI_CLASS_NOT_DEFINED || | 455 | if (class == PCI_CLASS_NOT_DEFINED || |
433 | class == PCI_CLASS_NOT_DEFINED_VGA || | 456 | class == PCI_CLASS_NOT_DEFINED_VGA || |
434 | class == PCI_CLASS_STORAGE_IDE || | 457 | class == PCI_CLASS_STORAGE_IDE || |
435 | (pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY) | 458 | (pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY) |
436 | return 1; | 459 | return 1; |
437 | 460 | ||
438 | return 0; | 461 | return 0; |
439 | } | 462 | } |
440 | 463 | ||
441 | static void __init pdev_assign_unassigned(struct pci_pbm_info *pbm, | 464 | static void __init pdev_assign_unassigned(struct pci_pbm_info *pbm, |
442 | struct pci_dev *pdev) | 465 | struct pci_dev *pdev) |
443 | { | 466 | { |
444 | u32 reg; | 467 | u32 reg; |
445 | u16 cmd; | 468 | u16 cmd; |
446 | int i, io_seen, mem_seen; | 469 | int i, io_seen, mem_seen; |
447 | 470 | ||
448 | io_seen = mem_seen = 0; | 471 | io_seen = mem_seen = 0; |
449 | for (i = 0; i < PCI_NUM_RESOURCES; i++) { | 472 | for (i = 0; i < PCI_NUM_RESOURCES; i++) { |
450 | struct resource *root, *res; | 473 | struct resource *root, *res; |
451 | unsigned long size, min, max, align; | 474 | unsigned long size, min, max, align; |
452 | 475 | ||
453 | res = &pdev->resource[i]; | 476 | res = &pdev->resource[i]; |
454 | 477 | ||
455 | if (res->flags & IORESOURCE_IO) | 478 | if (res->flags & IORESOURCE_IO) |
456 | io_seen++; | 479 | io_seen++; |
457 | else if (res->flags & IORESOURCE_MEM) | 480 | else if (res->flags & IORESOURCE_MEM) |
458 | mem_seen++; | 481 | mem_seen++; |
459 | 482 | ||
460 | /* If it is already assigned or the resource does | 483 | /* If it is already assigned or the resource does |
461 | * not exist, there is nothing to do. | 484 | * not exist, there is nothing to do. |
462 | */ | 485 | */ |
463 | if (res->parent != NULL || res->flags == 0UL) | 486 | if (res->parent != NULL || res->flags == 0UL) |
464 | continue; | 487 | continue; |
465 | 488 | ||
466 | /* Determine the root we allocate from. */ | 489 | /* Determine the root we allocate from. */ |
467 | if (res->flags & IORESOURCE_IO) { | 490 | if (res->flags & IORESOURCE_IO) { |
468 | root = &pbm->io_space; | 491 | root = &pbm->io_space; |
469 | min = root->start + 0x400UL; | 492 | min = root->start + 0x400UL; |
470 | max = root->end; | 493 | max = root->end; |
471 | } else { | 494 | } else { |
472 | root = &pbm->mem_space; | 495 | root = &pbm->mem_space; |
473 | min = root->start; | 496 | min = root->start; |
474 | max = min + 0x80000000UL; | 497 | max = min + 0x80000000UL; |
475 | } | 498 | } |
476 | 499 | ||
477 | size = res->end - res->start; | 500 | size = res->end - res->start; |
478 | align = size + 1; | 501 | align = size + 1; |
479 | if (allocate_resource(root, res, size + 1, min, max, align, NULL, NULL) < 0) { | 502 | if (allocate_resource(root, res, size + 1, min, max, align, NULL, NULL) < 0) { |
480 | /* uh oh */ | 503 | /* uh oh */ |
481 | prom_printf("PCI: Failed to allocate resource %d for %s\n", | 504 | prom_printf("PCI: Failed to allocate resource %d for %s\n", |
482 | i, pci_name(pdev)); | 505 | i, pci_name(pdev)); |
483 | prom_halt(); | 506 | prom_halt(); |
484 | } | 507 | } |
485 | 508 | ||
486 | /* Update PCI config space. */ | 509 | /* Update PCI config space. */ |
487 | pbm->parent->base_address_update(pdev, i); | 510 | pbm->parent->base_address_update(pdev, i); |
488 | } | 511 | } |
489 | 512 | ||
490 | /* Special case, disable the ROM. Several devices | 513 | /* Special case, disable the ROM. Several devices |
491 | * act funny (ie. do not respond to memory space writes) | 514 | * act funny (ie. do not respond to memory space writes) |
492 | * when it is left enabled. A good example are Qlogic,ISP | 515 | * when it is left enabled. A good example are Qlogic,ISP |
493 | * adapters. | 516 | * adapters. |
494 | */ | 517 | */ |
495 | pci_read_config_dword(pdev, PCI_ROM_ADDRESS, ®); | 518 | pci_read_config_dword(pdev, PCI_ROM_ADDRESS, ®); |
496 | reg &= ~PCI_ROM_ADDRESS_ENABLE; | 519 | reg &= ~PCI_ROM_ADDRESS_ENABLE; |
497 | pci_write_config_dword(pdev, PCI_ROM_ADDRESS, reg); | 520 | pci_write_config_dword(pdev, PCI_ROM_ADDRESS, reg); |
498 | 521 | ||
499 | /* If we saw I/O or MEM resources, enable appropriate | 522 | /* If we saw I/O or MEM resources, enable appropriate |
500 | * bits in PCI command register. | 523 | * bits in PCI command register. |
501 | */ | 524 | */ |
502 | if (io_seen || mem_seen) { | 525 | if (io_seen || mem_seen) { |
503 | pci_read_config_word(pdev, PCI_COMMAND, &cmd); | 526 | pci_read_config_word(pdev, PCI_COMMAND, &cmd); |
504 | if (io_seen || has_implicit_io(pdev)) | 527 | if (io_seen || has_implicit_io(pdev)) |
505 | cmd |= PCI_COMMAND_IO; | 528 | cmd |= PCI_COMMAND_IO; |
506 | if (mem_seen) | 529 | if (mem_seen) |
507 | cmd |= PCI_COMMAND_MEMORY; | 530 | cmd |= PCI_COMMAND_MEMORY; |
508 | pci_write_config_word(pdev, PCI_COMMAND, cmd); | 531 | pci_write_config_word(pdev, PCI_COMMAND, cmd); |
509 | } | 532 | } |
510 | 533 | ||
511 | /* If this is a PCI bridge or an IDE controller, | 534 | /* If this is a PCI bridge or an IDE controller, |
512 | * enable bus mastering. In the former case also | 535 | * enable bus mastering. In the former case also |
513 | * set the cache line size correctly. | 536 | * set the cache line size correctly. |
514 | */ | 537 | */ |
515 | if (((pdev->class >> 8) == PCI_CLASS_BRIDGE_PCI) || | 538 | if (((pdev->class >> 8) == PCI_CLASS_BRIDGE_PCI) || |
516 | (((pdev->class >> 8) == PCI_CLASS_STORAGE_IDE) && | 539 | (((pdev->class >> 8) == PCI_CLASS_STORAGE_IDE) && |
517 | ((pdev->class & 0x80) != 0))) { | 540 | ((pdev->class & 0x80) != 0))) { |
518 | pci_read_config_word(pdev, PCI_COMMAND, &cmd); | 541 | pci_read_config_word(pdev, PCI_COMMAND, &cmd); |
519 | cmd |= PCI_COMMAND_MASTER; | 542 | cmd |= PCI_COMMAND_MASTER; |
520 | pci_write_config_word(pdev, PCI_COMMAND, cmd); | 543 | pci_write_config_word(pdev, PCI_COMMAND, cmd); |
521 | 544 | ||
522 | if ((pdev->class >> 8) == PCI_CLASS_BRIDGE_PCI) | 545 | if ((pdev->class >> 8) == PCI_CLASS_BRIDGE_PCI) |
523 | pci_write_config_byte(pdev, | 546 | pci_write_config_byte(pdev, |
524 | PCI_CACHE_LINE_SIZE, | 547 | PCI_CACHE_LINE_SIZE, |
525 | (64 / sizeof(u32))); | 548 | (64 / sizeof(u32))); |
526 | } | 549 | } |
527 | } | 550 | } |
528 | 551 | ||
529 | void __init pci_assign_unassigned(struct pci_pbm_info *pbm, | 552 | void __init pci_assign_unassigned(struct pci_pbm_info *pbm, |
530 | struct pci_bus *pbus) | 553 | struct pci_bus *pbus) |
531 | { | 554 | { |
532 | struct pci_dev *dev; | 555 | struct pci_dev *dev; |
533 | struct pci_bus *bus; | 556 | struct pci_bus *bus; |
534 | 557 | ||
535 | list_for_each_entry(dev, &pbus->devices, bus_list) | 558 | list_for_each_entry(dev, &pbus->devices, bus_list) |
536 | pdev_assign_unassigned(pbm, dev); | 559 | pdev_assign_unassigned(pbm, dev); |
537 | 560 | ||
538 | list_for_each_entry(bus, &pbus->children, node) | 561 | list_for_each_entry(bus, &pbus->children, node) |
539 | pci_assign_unassigned(pbm, bus); | 562 | pci_assign_unassigned(pbm, bus); |
540 | } | 563 | } |
541 | 564 | ||
542 | static void __init pdev_fixup_irq(struct pci_dev *pdev) | 565 | static void __init pdev_fixup_irq(struct pci_dev *pdev) |
543 | { | 566 | { |
544 | struct pcidev_cookie *pcp = pdev->sysdata; | 567 | struct pcidev_cookie *pcp = pdev->sysdata; |
545 | struct of_device *op = pcp->op; | 568 | struct of_device *op = pcp->op; |
546 | 569 | ||
547 | if (op->irqs[0] == 0xffffffff) { | 570 | if (op->irqs[0] == 0xffffffff) { |
548 | pdev->irq = PCI_IRQ_NONE; | 571 | pdev->irq = PCI_IRQ_NONE; |
549 | return; | 572 | return; |
550 | } | 573 | } |
551 | 574 | ||
552 | pdev->irq = op->irqs[0]; | 575 | pdev->irq = op->irqs[0]; |
553 | 576 | ||
554 | pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, | 577 | pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, |
555 | pdev->irq & PCI_IRQ_INO); | 578 | pdev->irq & PCI_IRQ_INO); |
556 | } | 579 | } |
557 | 580 | ||
558 | void __init pci_fixup_irq(struct pci_pbm_info *pbm, | 581 | void __init pci_fixup_irq(struct pci_pbm_info *pbm, |
559 | struct pci_bus *pbus) | 582 | struct pci_bus *pbus) |
560 | { | 583 | { |
561 | struct pci_dev *dev; | 584 | struct pci_dev *dev; |
562 | struct pci_bus *bus; | 585 | struct pci_bus *bus; |
563 | 586 | ||
564 | list_for_each_entry(dev, &pbus->devices, bus_list) | 587 | list_for_each_entry(dev, &pbus->devices, bus_list) |
565 | pdev_fixup_irq(dev); | 588 | pdev_fixup_irq(dev); |
566 | 589 | ||
567 | list_for_each_entry(bus, &pbus->children, node) | 590 | list_for_each_entry(bus, &pbus->children, node) |
568 | pci_fixup_irq(pbm, bus); | 591 | pci_fixup_irq(pbm, bus); |
569 | } | 592 | } |
570 | 593 | ||
571 | static void pdev_setup_busmastering(struct pci_dev *pdev, int is_66mhz) | 594 | static void pdev_setup_busmastering(struct pci_dev *pdev, int is_66mhz) |
572 | { | 595 | { |
573 | u16 cmd; | 596 | u16 cmd; |
574 | u8 hdr_type, min_gnt, ltimer; | 597 | u8 hdr_type, min_gnt, ltimer; |
575 | 598 | ||
576 | pci_read_config_word(pdev, PCI_COMMAND, &cmd); | 599 | pci_read_config_word(pdev, PCI_COMMAND, &cmd); |
577 | cmd |= PCI_COMMAND_MASTER; | 600 | cmd |= PCI_COMMAND_MASTER; |
578 | pci_write_config_word(pdev, PCI_COMMAND, cmd); | 601 | pci_write_config_word(pdev, PCI_COMMAND, cmd); |
579 | 602 | ||
580 | /* Read it back, if the mastering bit did not | 603 | /* Read it back, if the mastering bit did not |
581 | * get set, the device does not support bus | 604 | * get set, the device does not support bus |
582 | * mastering so we have nothing to do here. | 605 | * mastering so we have nothing to do here. |
583 | */ | 606 | */ |
584 | pci_read_config_word(pdev, PCI_COMMAND, &cmd); | 607 | pci_read_config_word(pdev, PCI_COMMAND, &cmd); |
585 | if ((cmd & PCI_COMMAND_MASTER) == 0) | 608 | if ((cmd & PCI_COMMAND_MASTER) == 0) |
586 | return; | 609 | return; |
587 | 610 | ||
588 | /* Set correct cache line size, 64-byte on all | 611 | /* Set correct cache line size, 64-byte on all |
589 | * Sparc64 PCI systems. Note that the value is | 612 | * Sparc64 PCI systems. Note that the value is |
590 | * measured in 32-bit words. | 613 | * measured in 32-bit words. |
591 | */ | 614 | */ |
592 | pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, | 615 | pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, |
593 | 64 / sizeof(u32)); | 616 | 64 / sizeof(u32)); |
594 | 617 | ||
595 | pci_read_config_byte(pdev, PCI_HEADER_TYPE, &hdr_type); | 618 | pci_read_config_byte(pdev, PCI_HEADER_TYPE, &hdr_type); |
596 | hdr_type &= ~0x80; | 619 | hdr_type &= ~0x80; |
597 | if (hdr_type != PCI_HEADER_TYPE_NORMAL) | 620 | if (hdr_type != PCI_HEADER_TYPE_NORMAL) |
598 | return; | 621 | return; |
599 | 622 | ||
600 | /* If the latency timer is already programmed with a non-zero | 623 | /* If the latency timer is already programmed with a non-zero |
601 | * value, assume whoever set it (OBP or whoever) knows what | 624 | * value, assume whoever set it (OBP or whoever) knows what |
602 | * they are doing. | 625 | * they are doing. |
603 | */ | 626 | */ |
604 | pci_read_config_byte(pdev, PCI_LATENCY_TIMER, <imer); | 627 | pci_read_config_byte(pdev, PCI_LATENCY_TIMER, <imer); |
605 | if (ltimer != 0) | 628 | if (ltimer != 0) |
606 | return; | 629 | return; |
607 | 630 | ||
608 | /* XXX Since I'm tipping off the min grant value to | 631 | /* XXX Since I'm tipping off the min grant value to |
609 | * XXX choose a suitable latency timer value, I also | 632 | * XXX choose a suitable latency timer value, I also |
610 | * XXX considered making use of the max latency value | 633 | * XXX considered making use of the max latency value |
611 | * XXX as well. Unfortunately I've seen too many bogusly | 634 | * XXX as well. Unfortunately I've seen too many bogusly |
612 | * XXX low settings for it to the point where it lacks | 635 | * XXX low settings for it to the point where it lacks |
613 | * XXX any usefulness. In one case, an ethernet card | 636 | * XXX any usefulness. In one case, an ethernet card |
614 | * XXX claimed a min grant of 10 and a max latency of 5. | 637 | * XXX claimed a min grant of 10 and a max latency of 5. |
615 | * XXX Now, if I had two such cards on the same bus I | 638 | * XXX Now, if I had two such cards on the same bus I |
616 | * XXX could not set the desired burst period (calculated | 639 | * XXX could not set the desired burst period (calculated |
617 | * XXX from min grant) without violating the max latency | 640 | * XXX from min grant) without violating the max latency |
618 | * XXX bound. Duh... | 641 | * XXX bound. Duh... |
619 | * XXX | 642 | * XXX |
620 | * XXX I blame dumb PC bios implementors for stuff like | 643 | * XXX I blame dumb PC bios implementors for stuff like |
621 | * XXX this, most of them don't even try to do something | 644 | * XXX this, most of them don't even try to do something |
622 | * XXX sensible with latency timer values and just set some | 645 | * XXX sensible with latency timer values and just set some |
623 | * XXX default value (usually 32) into every device. | 646 | * XXX default value (usually 32) into every device. |
624 | */ | 647 | */ |
625 | 648 | ||
626 | pci_read_config_byte(pdev, PCI_MIN_GNT, &min_gnt); | 649 | pci_read_config_byte(pdev, PCI_MIN_GNT, &min_gnt); |
627 | 650 | ||
628 | if (min_gnt == 0) { | 651 | if (min_gnt == 0) { |
629 | /* If no min_gnt setting then use a default | 652 | /* If no min_gnt setting then use a default |
630 | * value. | 653 | * value. |
631 | */ | 654 | */ |
632 | if (is_66mhz) | 655 | if (is_66mhz) |
633 | ltimer = 16; | 656 | ltimer = 16; |
634 | else | 657 | else |
635 | ltimer = 32; | 658 | ltimer = 32; |
636 | } else { | 659 | } else { |
637 | int shift_factor; | 660 | int shift_factor; |
638 | 661 | ||
639 | if (is_66mhz) | 662 | if (is_66mhz) |
640 | shift_factor = 2; | 663 | shift_factor = 2; |
641 | else | 664 | else |
642 | shift_factor = 3; | 665 | shift_factor = 3; |
643 | 666 | ||
644 | /* Use a default value when the min_gnt value | 667 | /* Use a default value when the min_gnt value |
645 | * is erroneously high. | 668 | * is erroneously high. |
646 | */ | 669 | */ |
647 | if (((unsigned int) min_gnt << shift_factor) > 512 || | 670 | if (((unsigned int) min_gnt << shift_factor) > 512 || |
648 | ((min_gnt << shift_factor) & 0xff) == 0) { | 671 | ((min_gnt << shift_factor) & 0xff) == 0) { |
649 | ltimer = 8 << shift_factor; | 672 | ltimer = 8 << shift_factor; |
650 | } else { | 673 | } else { |
651 | ltimer = min_gnt << shift_factor; | 674 | ltimer = min_gnt << shift_factor; |
652 | } | 675 | } |
653 | } | 676 | } |
654 | 677 | ||
655 | pci_write_config_byte(pdev, PCI_LATENCY_TIMER, ltimer); | 678 | pci_write_config_byte(pdev, PCI_LATENCY_TIMER, ltimer); |
656 | } | 679 | } |
657 | 680 | ||
658 | void pci_determine_66mhz_disposition(struct pci_pbm_info *pbm, | 681 | void pci_determine_66mhz_disposition(struct pci_pbm_info *pbm, |
659 | struct pci_bus *pbus) | 682 | struct pci_bus *pbus) |
660 | { | 683 | { |
661 | struct pci_dev *pdev; | 684 | struct pci_dev *pdev; |
662 | int all_are_66mhz; | 685 | int all_are_66mhz; |
663 | u16 status; | 686 | u16 status; |
664 | 687 | ||
665 | if (pbm->is_66mhz_capable == 0) { | 688 | if (pbm->is_66mhz_capable == 0) { |
666 | all_are_66mhz = 0; | 689 | all_are_66mhz = 0; |
667 | goto out; | 690 | goto out; |
668 | } | 691 | } |
669 | 692 | ||
670 | all_are_66mhz = 1; | 693 | all_are_66mhz = 1; |
671 | list_for_each_entry(pdev, &pbus->devices, bus_list) { | 694 | list_for_each_entry(pdev, &pbus->devices, bus_list) { |
672 | pci_read_config_word(pdev, PCI_STATUS, &status); | 695 | pci_read_config_word(pdev, PCI_STATUS, &status); |
673 | if (!(status & PCI_STATUS_66MHZ)) { | 696 | if (!(status & PCI_STATUS_66MHZ)) { |
674 | all_are_66mhz = 0; | 697 | all_are_66mhz = 0; |
675 | break; | 698 | break; |
676 | } | 699 | } |
677 | } | 700 | } |
678 | out: | 701 | out: |
679 | pbm->all_devs_66mhz = all_are_66mhz; | 702 | pbm->all_devs_66mhz = all_are_66mhz; |
680 | 703 | ||
681 | printk("PCI%d(PBM%c): Bus running at %dMHz\n", | 704 | printk("PCI%d(PBM%c): Bus running at %dMHz\n", |
682 | pbm->parent->index, | 705 | pbm->parent->index, |
683 | (pbm == &pbm->parent->pbm_A) ? 'A' : 'B', | 706 | (pbm == &pbm->parent->pbm_A) ? 'A' : 'B', |
684 | (all_are_66mhz ? 66 : 33)); | 707 | (all_are_66mhz ? 66 : 33)); |
685 | } | 708 | } |
686 | 709 | ||
687 | void pci_setup_busmastering(struct pci_pbm_info *pbm, | 710 | void pci_setup_busmastering(struct pci_pbm_info *pbm, |
688 | struct pci_bus *pbus) | 711 | struct pci_bus *pbus) |
689 | { | 712 | { |
690 | struct pci_dev *dev; | 713 | struct pci_dev *dev; |
691 | struct pci_bus *bus; | 714 | struct pci_bus *bus; |
692 | int is_66mhz; | 715 | int is_66mhz; |
693 | 716 | ||
694 | is_66mhz = pbm->is_66mhz_capable && pbm->all_devs_66mhz; | 717 | is_66mhz = pbm->is_66mhz_capable && pbm->all_devs_66mhz; |
695 | 718 | ||
696 | list_for_each_entry(dev, &pbus->devices, bus_list) | 719 | list_for_each_entry(dev, &pbus->devices, bus_list) |
697 | pdev_setup_busmastering(dev, is_66mhz); | 720 | pdev_setup_busmastering(dev, is_66mhz); |
698 | 721 | ||
699 | list_for_each_entry(bus, &pbus->children, node) | 722 | list_for_each_entry(bus, &pbus->children, node) |
700 | pci_setup_busmastering(pbm, bus); | 723 | pci_setup_busmastering(pbm, bus); |
701 | } | 724 | } |
702 | 725 | ||
703 | void pci_register_legacy_regions(struct resource *io_res, | 726 | void pci_register_legacy_regions(struct resource *io_res, |
704 | struct resource *mem_res) | 727 | struct resource *mem_res) |
705 | { | 728 | { |
706 | struct resource *p; | 729 | struct resource *p; |
707 | 730 | ||
708 | /* VGA Video RAM. */ | 731 | /* VGA Video RAM. */ |
709 | p = kzalloc(sizeof(*p), GFP_KERNEL); | 732 | p = kzalloc(sizeof(*p), GFP_KERNEL); |
710 | if (!p) | 733 | if (!p) |
711 | return; | 734 | return; |
712 | 735 | ||
713 | p->name = "Video RAM area"; | 736 | p->name = "Video RAM area"; |
714 | p->start = mem_res->start + 0xa0000UL; | 737 | p->start = mem_res->start + 0xa0000UL; |
715 | p->end = p->start + 0x1ffffUL; | 738 | p->end = p->start + 0x1ffffUL; |
716 | p->flags = IORESOURCE_BUSY; | 739 | p->flags = IORESOURCE_BUSY; |
717 | request_resource(mem_res, p); | 740 | request_resource(mem_res, p); |
718 | 741 | ||
719 | p = kzalloc(sizeof(*p), GFP_KERNEL); | 742 | p = kzalloc(sizeof(*p), GFP_KERNEL); |
720 | if (!p) | 743 | if (!p) |
721 | return; | 744 | return; |
722 | 745 | ||
723 | p->name = "System ROM"; | 746 | p->name = "System ROM"; |
724 | p->start = mem_res->start + 0xf0000UL; | 747 | p->start = mem_res->start + 0xf0000UL; |
725 | p->end = p->start + 0xffffUL; | 748 | p->end = p->start + 0xffffUL; |
726 | p->flags = IORESOURCE_BUSY; | 749 | p->flags = IORESOURCE_BUSY; |
727 | request_resource(mem_res, p); | 750 | request_resource(mem_res, p); |
728 | 751 | ||
729 | p = kzalloc(sizeof(*p), GFP_KERNEL); | 752 | p = kzalloc(sizeof(*p), GFP_KERNEL); |
730 | if (!p) | 753 | if (!p) |
731 | return; | 754 | return; |
732 | 755 | ||
733 | p->name = "Video ROM"; | 756 | p->name = "Video ROM"; |
734 | p->start = mem_res->start + 0xc0000UL; | 757 | p->start = mem_res->start + 0xc0000UL; |
735 | p->end = p->start + 0x7fffUL; | 758 | p->end = p->start + 0x7fffUL; |
736 | p->flags = IORESOURCE_BUSY; | 759 | p->flags = IORESOURCE_BUSY; |
737 | request_resource(mem_res, p); | 760 | request_resource(mem_res, p); |
738 | } | 761 | } |
739 | 762 | ||
740 | /* Generic helper routines for PCI error reporting. */ | 763 | /* Generic helper routines for PCI error reporting. */ |
741 | void pci_scan_for_target_abort(struct pci_controller_info *p, | 764 | void pci_scan_for_target_abort(struct pci_controller_info *p, |
742 | struct pci_pbm_info *pbm, | 765 | struct pci_pbm_info *pbm, |
743 | struct pci_bus *pbus) | 766 | struct pci_bus *pbus) |
744 | { | 767 | { |
745 | struct pci_dev *pdev; | 768 | struct pci_dev *pdev; |
746 | struct pci_bus *bus; | 769 | struct pci_bus *bus; |
747 | 770 | ||
748 | list_for_each_entry(pdev, &pbus->devices, bus_list) { | 771 | list_for_each_entry(pdev, &pbus->devices, bus_list) { |
749 | u16 status, error_bits; | 772 | u16 status, error_bits; |
750 | 773 | ||
751 | pci_read_config_word(pdev, PCI_STATUS, &status); | 774 | pci_read_config_word(pdev, PCI_STATUS, &status); |
752 | error_bits = | 775 | error_bits = |
753 | (status & (PCI_STATUS_SIG_TARGET_ABORT | | 776 | (status & (PCI_STATUS_SIG_TARGET_ABORT | |
754 | PCI_STATUS_REC_TARGET_ABORT)); | 777 | PCI_STATUS_REC_TARGET_ABORT)); |
755 | if (error_bits) { | 778 | if (error_bits) { |
756 | pci_write_config_word(pdev, PCI_STATUS, error_bits); | 779 | pci_write_config_word(pdev, PCI_STATUS, error_bits); |
757 | printk("PCI%d(PBM%c): Device [%s] saw Target Abort [%016x]\n", | 780 | printk("PCI%d(PBM%c): Device [%s] saw Target Abort [%016x]\n", |
758 | p->index, ((pbm == &p->pbm_A) ? 'A' : 'B'), | 781 | p->index, ((pbm == &p->pbm_A) ? 'A' : 'B'), |
759 | pci_name(pdev), status); | 782 | pci_name(pdev), status); |
760 | } | 783 | } |
761 | } | 784 | } |
762 | 785 | ||
763 | list_for_each_entry(bus, &pbus->children, node) | 786 | list_for_each_entry(bus, &pbus->children, node) |
764 | pci_scan_for_target_abort(p, pbm, bus); | 787 | pci_scan_for_target_abort(p, pbm, bus); |
765 | } | 788 | } |
766 | 789 | ||
767 | void pci_scan_for_master_abort(struct pci_controller_info *p, | 790 | void pci_scan_for_master_abort(struct pci_controller_info *p, |
768 | struct pci_pbm_info *pbm, | 791 | struct pci_pbm_info *pbm, |
769 | struct pci_bus *pbus) | 792 | struct pci_bus *pbus) |
770 | { | 793 | { |
771 | struct pci_dev *pdev; | 794 | struct pci_dev *pdev; |
772 | struct pci_bus *bus; | 795 | struct pci_bus *bus; |
773 | 796 | ||
774 | list_for_each_entry(pdev, &pbus->devices, bus_list) { | 797 | list_for_each_entry(pdev, &pbus->devices, bus_list) { |
775 | u16 status, error_bits; | 798 | u16 status, error_bits; |
776 | 799 | ||
777 | pci_read_config_word(pdev, PCI_STATUS, &status); | 800 | pci_read_config_word(pdev, PCI_STATUS, &status); |
778 | error_bits = | 801 | error_bits = |
779 | (status & (PCI_STATUS_REC_MASTER_ABORT)); | 802 | (status & (PCI_STATUS_REC_MASTER_ABORT)); |
780 | if (error_bits) { | 803 | if (error_bits) { |
781 | pci_write_config_word(pdev, PCI_STATUS, error_bits); | 804 | pci_write_config_word(pdev, PCI_STATUS, error_bits); |
782 | printk("PCI%d(PBM%c): Device [%s] received Master Abort [%016x]\n", | 805 | printk("PCI%d(PBM%c): Device [%s] received Master Abort [%016x]\n", |
783 | p->index, ((pbm == &p->pbm_A) ? 'A' : 'B'), | 806 | p->index, ((pbm == &p->pbm_A) ? 'A' : 'B'), |
784 | pci_name(pdev), status); | 807 | pci_name(pdev), status); |
785 | } | 808 | } |
786 | } | 809 | } |
787 | 810 | ||
788 | list_for_each_entry(bus, &pbus->children, node) | 811 | list_for_each_entry(bus, &pbus->children, node) |
789 | pci_scan_for_master_abort(p, pbm, bus); | 812 | pci_scan_for_master_abort(p, pbm, bus); |
790 | } | 813 | } |
791 | 814 | ||
792 | void pci_scan_for_parity_error(struct pci_controller_info *p, | 815 | void pci_scan_for_parity_error(struct pci_controller_info *p, |
793 | struct pci_pbm_info *pbm, | 816 | struct pci_pbm_info *pbm, |
794 | struct pci_bus *pbus) | 817 | struct pci_bus *pbus) |
795 | { | 818 | { |
796 | struct pci_dev *pdev; | 819 | struct pci_dev *pdev; |
797 | struct pci_bus *bus; | 820 | struct pci_bus *bus; |
798 | 821 | ||
799 | list_for_each_entry(pdev, &pbus->devices, bus_list) { | 822 | list_for_each_entry(pdev, &pbus->devices, bus_list) { |
800 | u16 status, error_bits; | 823 | u16 status, error_bits; |
801 | 824 | ||
802 | pci_read_config_word(pdev, PCI_STATUS, &status); | 825 | pci_read_config_word(pdev, PCI_STATUS, &status); |
803 | error_bits = | 826 | error_bits = |
804 | (status & (PCI_STATUS_PARITY | | 827 | (status & (PCI_STATUS_PARITY | |
805 | PCI_STATUS_DETECTED_PARITY)); | 828 | PCI_STATUS_DETECTED_PARITY)); |
806 | if (error_bits) { | 829 | if (error_bits) { |
807 | pci_write_config_word(pdev, PCI_STATUS, error_bits); | 830 | pci_write_config_word(pdev, PCI_STATUS, error_bits); |
808 | printk("PCI%d(PBM%c): Device [%s] saw Parity Error [%016x]\n", | 831 | printk("PCI%d(PBM%c): Device [%s] saw Parity Error [%016x]\n", |
809 | p->index, ((pbm == &p->pbm_A) ? 'A' : 'B'), | 832 | p->index, ((pbm == &p->pbm_A) ? 'A' : 'B'), |
810 | pci_name(pdev), status); | 833 | pci_name(pdev), status); |
811 | } | 834 | } |
812 | } | 835 | } |
813 | 836 | ||
814 | list_for_each_entry(bus, &pbus->children, node) | 837 | list_for_each_entry(bus, &pbus->children, node) |
815 | pci_scan_for_parity_error(p, pbm, bus); | 838 | pci_scan_for_parity_error(p, pbm, bus); |
816 | } | 839 | } |
817 | 840 |
arch/sparc64/kernel/pci_sun4v.c
1 | /* pci_sun4v.c: SUN4V specific PCI controller support. | 1 | /* pci_sun4v.c: SUN4V specific PCI controller support. |
2 | * | 2 | * |
3 | * Copyright (C) 2006 David S. Miller (davem@davemloft.net) | 3 | * Copyright (C) 2006 David S. Miller (davem@davemloft.net) |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include <linux/kernel.h> | 6 | #include <linux/kernel.h> |
7 | #include <linux/types.h> | 7 | #include <linux/types.h> |
8 | #include <linux/pci.h> | 8 | #include <linux/pci.h> |
9 | #include <linux/init.h> | 9 | #include <linux/init.h> |
10 | #include <linux/slab.h> | 10 | #include <linux/slab.h> |
11 | #include <linux/interrupt.h> | 11 | #include <linux/interrupt.h> |
12 | #include <linux/percpu.h> | 12 | #include <linux/percpu.h> |
13 | #include <linux/irq.h> | ||
14 | #include <linux/msi.h> | ||
13 | 15 | ||
14 | #include <asm/pbm.h> | 16 | #include <asm/pbm.h> |
15 | #include <asm/iommu.h> | 17 | #include <asm/iommu.h> |
16 | #include <asm/irq.h> | 18 | #include <asm/irq.h> |
17 | #include <asm/upa.h> | 19 | #include <asm/upa.h> |
18 | #include <asm/pstate.h> | 20 | #include <asm/pstate.h> |
19 | #include <asm/oplib.h> | 21 | #include <asm/oplib.h> |
20 | #include <asm/hypervisor.h> | 22 | #include <asm/hypervisor.h> |
21 | #include <asm/prom.h> | 23 | #include <asm/prom.h> |
22 | 24 | ||
23 | #include "pci_impl.h" | 25 | #include "pci_impl.h" |
24 | #include "iommu_common.h" | 26 | #include "iommu_common.h" |
25 | 27 | ||
26 | #include "pci_sun4v.h" | 28 | #include "pci_sun4v.h" |
27 | 29 | ||
28 | #define PGLIST_NENTS (PAGE_SIZE / sizeof(u64)) | 30 | #define PGLIST_NENTS (PAGE_SIZE / sizeof(u64)) |
29 | 31 | ||
30 | struct pci_iommu_batch { | 32 | struct pci_iommu_batch { |
31 | struct pci_dev *pdev; /* Device mapping is for. */ | 33 | struct pci_dev *pdev; /* Device mapping is for. */ |
32 | unsigned long prot; /* IOMMU page protections */ | 34 | unsigned long prot; /* IOMMU page protections */ |
33 | unsigned long entry; /* Index into IOTSB. */ | 35 | unsigned long entry; /* Index into IOTSB. */ |
34 | u64 *pglist; /* List of physical pages */ | 36 | u64 *pglist; /* List of physical pages */ |
35 | unsigned long npages; /* Number of pages in list. */ | 37 | unsigned long npages; /* Number of pages in list. */ |
36 | }; | 38 | }; |
37 | 39 | ||
38 | static DEFINE_PER_CPU(struct pci_iommu_batch, pci_iommu_batch); | 40 | static DEFINE_PER_CPU(struct pci_iommu_batch, pci_iommu_batch); |
39 | 41 | ||
40 | /* Interrupts must be disabled. */ | 42 | /* Interrupts must be disabled. */ |
41 | static inline void pci_iommu_batch_start(struct pci_dev *pdev, unsigned long prot, unsigned long entry) | 43 | static inline void pci_iommu_batch_start(struct pci_dev *pdev, unsigned long prot, unsigned long entry) |
42 | { | 44 | { |
43 | struct pci_iommu_batch *p = &__get_cpu_var(pci_iommu_batch); | 45 | struct pci_iommu_batch *p = &__get_cpu_var(pci_iommu_batch); |
44 | 46 | ||
45 | p->pdev = pdev; | 47 | p->pdev = pdev; |
46 | p->prot = prot; | 48 | p->prot = prot; |
47 | p->entry = entry; | 49 | p->entry = entry; |
48 | p->npages = 0; | 50 | p->npages = 0; |
49 | } | 51 | } |
50 | 52 | ||
51 | /* Interrupts must be disabled. */ | 53 | /* Interrupts must be disabled. */ |
52 | static long pci_iommu_batch_flush(struct pci_iommu_batch *p) | 54 | static long pci_iommu_batch_flush(struct pci_iommu_batch *p) |
53 | { | 55 | { |
54 | struct pcidev_cookie *pcp = p->pdev->sysdata; | 56 | struct pcidev_cookie *pcp = p->pdev->sysdata; |
55 | unsigned long devhandle = pcp->pbm->devhandle; | 57 | unsigned long devhandle = pcp->pbm->devhandle; |
56 | unsigned long prot = p->prot; | 58 | unsigned long prot = p->prot; |
57 | unsigned long entry = p->entry; | 59 | unsigned long entry = p->entry; |
58 | u64 *pglist = p->pglist; | 60 | u64 *pglist = p->pglist; |
59 | unsigned long npages = p->npages; | 61 | unsigned long npages = p->npages; |
60 | 62 | ||
61 | while (npages != 0) { | 63 | while (npages != 0) { |
62 | long num; | 64 | long num; |
63 | 65 | ||
64 | num = pci_sun4v_iommu_map(devhandle, HV_PCI_TSBID(0, entry), | 66 | num = pci_sun4v_iommu_map(devhandle, HV_PCI_TSBID(0, entry), |
65 | npages, prot, __pa(pglist)); | 67 | npages, prot, __pa(pglist)); |
66 | if (unlikely(num < 0)) { | 68 | if (unlikely(num < 0)) { |
67 | if (printk_ratelimit()) | 69 | if (printk_ratelimit()) |
68 | printk("pci_iommu_batch_flush: IOMMU map of " | 70 | printk("pci_iommu_batch_flush: IOMMU map of " |
69 | "[%08lx:%08lx:%lx:%lx:%lx] failed with " | 71 | "[%08lx:%08lx:%lx:%lx:%lx] failed with " |
70 | "status %ld\n", | 72 | "status %ld\n", |
71 | devhandle, HV_PCI_TSBID(0, entry), | 73 | devhandle, HV_PCI_TSBID(0, entry), |
72 | npages, prot, __pa(pglist), num); | 74 | npages, prot, __pa(pglist), num); |
73 | return -1; | 75 | return -1; |
74 | } | 76 | } |
75 | 77 | ||
76 | entry += num; | 78 | entry += num; |
77 | npages -= num; | 79 | npages -= num; |
78 | pglist += num; | 80 | pglist += num; |
79 | } | 81 | } |
80 | 82 | ||
81 | p->entry = entry; | 83 | p->entry = entry; |
82 | p->npages = 0; | 84 | p->npages = 0; |
83 | 85 | ||
84 | return 0; | 86 | return 0; |
85 | } | 87 | } |
86 | 88 | ||
87 | /* Interrupts must be disabled. */ | 89 | /* Interrupts must be disabled. */ |
88 | static inline long pci_iommu_batch_add(u64 phys_page) | 90 | static inline long pci_iommu_batch_add(u64 phys_page) |
89 | { | 91 | { |
90 | struct pci_iommu_batch *p = &__get_cpu_var(pci_iommu_batch); | 92 | struct pci_iommu_batch *p = &__get_cpu_var(pci_iommu_batch); |
91 | 93 | ||
92 | BUG_ON(p->npages >= PGLIST_NENTS); | 94 | BUG_ON(p->npages >= PGLIST_NENTS); |
93 | 95 | ||
94 | p->pglist[p->npages++] = phys_page; | 96 | p->pglist[p->npages++] = phys_page; |
95 | if (p->npages == PGLIST_NENTS) | 97 | if (p->npages == PGLIST_NENTS) |
96 | return pci_iommu_batch_flush(p); | 98 | return pci_iommu_batch_flush(p); |
97 | 99 | ||
98 | return 0; | 100 | return 0; |
99 | } | 101 | } |
100 | 102 | ||
101 | /* Interrupts must be disabled. */ | 103 | /* Interrupts must be disabled. */ |
102 | static inline long pci_iommu_batch_end(void) | 104 | static inline long pci_iommu_batch_end(void) |
103 | { | 105 | { |
104 | struct pci_iommu_batch *p = &__get_cpu_var(pci_iommu_batch); | 106 | struct pci_iommu_batch *p = &__get_cpu_var(pci_iommu_batch); |
105 | 107 | ||
106 | BUG_ON(p->npages >= PGLIST_NENTS); | 108 | BUG_ON(p->npages >= PGLIST_NENTS); |
107 | 109 | ||
108 | return pci_iommu_batch_flush(p); | 110 | return pci_iommu_batch_flush(p); |
109 | } | 111 | } |
110 | 112 | ||
111 | static long pci_arena_alloc(struct pci_iommu_arena *arena, unsigned long npages) | 113 | static long pci_arena_alloc(struct pci_iommu_arena *arena, unsigned long npages) |
112 | { | 114 | { |
113 | unsigned long n, i, start, end, limit; | 115 | unsigned long n, i, start, end, limit; |
114 | int pass; | 116 | int pass; |
115 | 117 | ||
116 | limit = arena->limit; | 118 | limit = arena->limit; |
117 | start = arena->hint; | 119 | start = arena->hint; |
118 | pass = 0; | 120 | pass = 0; |
119 | 121 | ||
120 | again: | 122 | again: |
121 | n = find_next_zero_bit(arena->map, limit, start); | 123 | n = find_next_zero_bit(arena->map, limit, start); |
122 | end = n + npages; | 124 | end = n + npages; |
123 | if (unlikely(end >= limit)) { | 125 | if (unlikely(end >= limit)) { |
124 | if (likely(pass < 1)) { | 126 | if (likely(pass < 1)) { |
125 | limit = start; | 127 | limit = start; |
126 | start = 0; | 128 | start = 0; |
127 | pass++; | 129 | pass++; |
128 | goto again; | 130 | goto again; |
129 | } else { | 131 | } else { |
130 | /* Scanned the whole thing, give up. */ | 132 | /* Scanned the whole thing, give up. */ |
131 | return -1; | 133 | return -1; |
132 | } | 134 | } |
133 | } | 135 | } |
134 | 136 | ||
135 | for (i = n; i < end; i++) { | 137 | for (i = n; i < end; i++) { |
136 | if (test_bit(i, arena->map)) { | 138 | if (test_bit(i, arena->map)) { |
137 | start = i + 1; | 139 | start = i + 1; |
138 | goto again; | 140 | goto again; |
139 | } | 141 | } |
140 | } | 142 | } |
141 | 143 | ||
142 | for (i = n; i < end; i++) | 144 | for (i = n; i < end; i++) |
143 | __set_bit(i, arena->map); | 145 | __set_bit(i, arena->map); |
144 | 146 | ||
145 | arena->hint = end; | 147 | arena->hint = end; |
146 | 148 | ||
147 | return n; | 149 | return n; |
148 | } | 150 | } |
149 | 151 | ||
150 | static void pci_arena_free(struct pci_iommu_arena *arena, unsigned long base, unsigned long npages) | 152 | static void pci_arena_free(struct pci_iommu_arena *arena, unsigned long base, unsigned long npages) |
151 | { | 153 | { |
152 | unsigned long i; | 154 | unsigned long i; |
153 | 155 | ||
154 | for (i = base; i < (base + npages); i++) | 156 | for (i = base; i < (base + npages); i++) |
155 | __clear_bit(i, arena->map); | 157 | __clear_bit(i, arena->map); |
156 | } | 158 | } |
157 | 159 | ||
158 | static void *pci_4v_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr_t *dma_addrp, gfp_t gfp) | 160 | static void *pci_4v_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr_t *dma_addrp, gfp_t gfp) |
159 | { | 161 | { |
160 | struct pcidev_cookie *pcp; | 162 | struct pcidev_cookie *pcp; |
161 | struct pci_iommu *iommu; | 163 | struct pci_iommu *iommu; |
162 | unsigned long flags, order, first_page, npages, n; | 164 | unsigned long flags, order, first_page, npages, n; |
163 | void *ret; | 165 | void *ret; |
164 | long entry; | 166 | long entry; |
165 | 167 | ||
166 | size = IO_PAGE_ALIGN(size); | 168 | size = IO_PAGE_ALIGN(size); |
167 | order = get_order(size); | 169 | order = get_order(size); |
168 | if (unlikely(order >= MAX_ORDER)) | 170 | if (unlikely(order >= MAX_ORDER)) |
169 | return NULL; | 171 | return NULL; |
170 | 172 | ||
171 | npages = size >> IO_PAGE_SHIFT; | 173 | npages = size >> IO_PAGE_SHIFT; |
172 | 174 | ||
173 | first_page = __get_free_pages(gfp, order); | 175 | first_page = __get_free_pages(gfp, order); |
174 | if (unlikely(first_page == 0UL)) | 176 | if (unlikely(first_page == 0UL)) |
175 | return NULL; | 177 | return NULL; |
176 | 178 | ||
177 | memset((char *)first_page, 0, PAGE_SIZE << order); | 179 | memset((char *)first_page, 0, PAGE_SIZE << order); |
178 | 180 | ||
179 | pcp = pdev->sysdata; | 181 | pcp = pdev->sysdata; |
180 | iommu = pcp->pbm->iommu; | 182 | iommu = pcp->pbm->iommu; |
181 | 183 | ||
182 | spin_lock_irqsave(&iommu->lock, flags); | 184 | spin_lock_irqsave(&iommu->lock, flags); |
183 | entry = pci_arena_alloc(&iommu->arena, npages); | 185 | entry = pci_arena_alloc(&iommu->arena, npages); |
184 | spin_unlock_irqrestore(&iommu->lock, flags); | 186 | spin_unlock_irqrestore(&iommu->lock, flags); |
185 | 187 | ||
186 | if (unlikely(entry < 0L)) | 188 | if (unlikely(entry < 0L)) |
187 | goto arena_alloc_fail; | 189 | goto arena_alloc_fail; |
188 | 190 | ||
189 | *dma_addrp = (iommu->page_table_map_base + | 191 | *dma_addrp = (iommu->page_table_map_base + |
190 | (entry << IO_PAGE_SHIFT)); | 192 | (entry << IO_PAGE_SHIFT)); |
191 | ret = (void *) first_page; | 193 | ret = (void *) first_page; |
192 | first_page = __pa(first_page); | 194 | first_page = __pa(first_page); |
193 | 195 | ||
194 | local_irq_save(flags); | 196 | local_irq_save(flags); |
195 | 197 | ||
196 | pci_iommu_batch_start(pdev, | 198 | pci_iommu_batch_start(pdev, |
197 | (HV_PCI_MAP_ATTR_READ | | 199 | (HV_PCI_MAP_ATTR_READ | |
198 | HV_PCI_MAP_ATTR_WRITE), | 200 | HV_PCI_MAP_ATTR_WRITE), |
199 | entry); | 201 | entry); |
200 | 202 | ||
201 | for (n = 0; n < npages; n++) { | 203 | for (n = 0; n < npages; n++) { |
202 | long err = pci_iommu_batch_add(first_page + (n * PAGE_SIZE)); | 204 | long err = pci_iommu_batch_add(first_page + (n * PAGE_SIZE)); |
203 | if (unlikely(err < 0L)) | 205 | if (unlikely(err < 0L)) |
204 | goto iommu_map_fail; | 206 | goto iommu_map_fail; |
205 | } | 207 | } |
206 | 208 | ||
207 | if (unlikely(pci_iommu_batch_end() < 0L)) | 209 | if (unlikely(pci_iommu_batch_end() < 0L)) |
208 | goto iommu_map_fail; | 210 | goto iommu_map_fail; |
209 | 211 | ||
210 | local_irq_restore(flags); | 212 | local_irq_restore(flags); |
211 | 213 | ||
212 | return ret; | 214 | return ret; |
213 | 215 | ||
214 | iommu_map_fail: | 216 | iommu_map_fail: |
215 | /* Interrupts are disabled. */ | 217 | /* Interrupts are disabled. */ |
216 | spin_lock(&iommu->lock); | 218 | spin_lock(&iommu->lock); |
217 | pci_arena_free(&iommu->arena, entry, npages); | 219 | pci_arena_free(&iommu->arena, entry, npages); |
218 | spin_unlock_irqrestore(&iommu->lock, flags); | 220 | spin_unlock_irqrestore(&iommu->lock, flags); |
219 | 221 | ||
220 | arena_alloc_fail: | 222 | arena_alloc_fail: |
221 | free_pages(first_page, order); | 223 | free_pages(first_page, order); |
222 | return NULL; | 224 | return NULL; |
223 | } | 225 | } |
224 | 226 | ||
225 | static void pci_4v_free_consistent(struct pci_dev *pdev, size_t size, void *cpu, dma_addr_t dvma) | 227 | static void pci_4v_free_consistent(struct pci_dev *pdev, size_t size, void *cpu, dma_addr_t dvma) |
226 | { | 228 | { |
227 | struct pcidev_cookie *pcp; | 229 | struct pcidev_cookie *pcp; |
228 | struct pci_iommu *iommu; | 230 | struct pci_iommu *iommu; |
229 | unsigned long flags, order, npages, entry; | 231 | unsigned long flags, order, npages, entry; |
230 | u32 devhandle; | 232 | u32 devhandle; |
231 | 233 | ||
232 | npages = IO_PAGE_ALIGN(size) >> IO_PAGE_SHIFT; | 234 | npages = IO_PAGE_ALIGN(size) >> IO_PAGE_SHIFT; |
233 | pcp = pdev->sysdata; | 235 | pcp = pdev->sysdata; |
234 | iommu = pcp->pbm->iommu; | 236 | iommu = pcp->pbm->iommu; |
235 | devhandle = pcp->pbm->devhandle; | 237 | devhandle = pcp->pbm->devhandle; |
236 | entry = ((dvma - iommu->page_table_map_base) >> IO_PAGE_SHIFT); | 238 | entry = ((dvma - iommu->page_table_map_base) >> IO_PAGE_SHIFT); |
237 | 239 | ||
238 | spin_lock_irqsave(&iommu->lock, flags); | 240 | spin_lock_irqsave(&iommu->lock, flags); |
239 | 241 | ||
240 | pci_arena_free(&iommu->arena, entry, npages); | 242 | pci_arena_free(&iommu->arena, entry, npages); |
241 | 243 | ||
242 | do { | 244 | do { |
243 | unsigned long num; | 245 | unsigned long num; |
244 | 246 | ||
245 | num = pci_sun4v_iommu_demap(devhandle, HV_PCI_TSBID(0, entry), | 247 | num = pci_sun4v_iommu_demap(devhandle, HV_PCI_TSBID(0, entry), |
246 | npages); | 248 | npages); |
247 | entry += num; | 249 | entry += num; |
248 | npages -= num; | 250 | npages -= num; |
249 | } while (npages != 0); | 251 | } while (npages != 0); |
250 | 252 | ||
251 | spin_unlock_irqrestore(&iommu->lock, flags); | 253 | spin_unlock_irqrestore(&iommu->lock, flags); |
252 | 254 | ||
253 | order = get_order(size); | 255 | order = get_order(size); |
254 | if (order < 10) | 256 | if (order < 10) |
255 | free_pages((unsigned long)cpu, order); | 257 | free_pages((unsigned long)cpu, order); |
256 | } | 258 | } |
257 | 259 | ||
258 | static dma_addr_t pci_4v_map_single(struct pci_dev *pdev, void *ptr, size_t sz, int direction) | 260 | static dma_addr_t pci_4v_map_single(struct pci_dev *pdev, void *ptr, size_t sz, int direction) |
259 | { | 261 | { |
260 | struct pcidev_cookie *pcp; | 262 | struct pcidev_cookie *pcp; |
261 | struct pci_iommu *iommu; | 263 | struct pci_iommu *iommu; |
262 | unsigned long flags, npages, oaddr; | 264 | unsigned long flags, npages, oaddr; |
263 | unsigned long i, base_paddr; | 265 | unsigned long i, base_paddr; |
264 | u32 bus_addr, ret; | 266 | u32 bus_addr, ret; |
265 | unsigned long prot; | 267 | unsigned long prot; |
266 | long entry; | 268 | long entry; |
267 | 269 | ||
268 | pcp = pdev->sysdata; | 270 | pcp = pdev->sysdata; |
269 | iommu = pcp->pbm->iommu; | 271 | iommu = pcp->pbm->iommu; |
270 | 272 | ||
271 | if (unlikely(direction == PCI_DMA_NONE)) | 273 | if (unlikely(direction == PCI_DMA_NONE)) |
272 | goto bad; | 274 | goto bad; |
273 | 275 | ||
274 | oaddr = (unsigned long)ptr; | 276 | oaddr = (unsigned long)ptr; |
275 | npages = IO_PAGE_ALIGN(oaddr + sz) - (oaddr & IO_PAGE_MASK); | 277 | npages = IO_PAGE_ALIGN(oaddr + sz) - (oaddr & IO_PAGE_MASK); |
276 | npages >>= IO_PAGE_SHIFT; | 278 | npages >>= IO_PAGE_SHIFT; |
277 | 279 | ||
278 | spin_lock_irqsave(&iommu->lock, flags); | 280 | spin_lock_irqsave(&iommu->lock, flags); |
279 | entry = pci_arena_alloc(&iommu->arena, npages); | 281 | entry = pci_arena_alloc(&iommu->arena, npages); |
280 | spin_unlock_irqrestore(&iommu->lock, flags); | 282 | spin_unlock_irqrestore(&iommu->lock, flags); |
281 | 283 | ||
282 | if (unlikely(entry < 0L)) | 284 | if (unlikely(entry < 0L)) |
283 | goto bad; | 285 | goto bad; |
284 | 286 | ||
285 | bus_addr = (iommu->page_table_map_base + | 287 | bus_addr = (iommu->page_table_map_base + |
286 | (entry << IO_PAGE_SHIFT)); | 288 | (entry << IO_PAGE_SHIFT)); |
287 | ret = bus_addr | (oaddr & ~IO_PAGE_MASK); | 289 | ret = bus_addr | (oaddr & ~IO_PAGE_MASK); |
288 | base_paddr = __pa(oaddr & IO_PAGE_MASK); | 290 | base_paddr = __pa(oaddr & IO_PAGE_MASK); |
289 | prot = HV_PCI_MAP_ATTR_READ; | 291 | prot = HV_PCI_MAP_ATTR_READ; |
290 | if (direction != PCI_DMA_TODEVICE) | 292 | if (direction != PCI_DMA_TODEVICE) |
291 | prot |= HV_PCI_MAP_ATTR_WRITE; | 293 | prot |= HV_PCI_MAP_ATTR_WRITE; |
292 | 294 | ||
293 | local_irq_save(flags); | 295 | local_irq_save(flags); |
294 | 296 | ||
295 | pci_iommu_batch_start(pdev, prot, entry); | 297 | pci_iommu_batch_start(pdev, prot, entry); |
296 | 298 | ||
297 | for (i = 0; i < npages; i++, base_paddr += IO_PAGE_SIZE) { | 299 | for (i = 0; i < npages; i++, base_paddr += IO_PAGE_SIZE) { |
298 | long err = pci_iommu_batch_add(base_paddr); | 300 | long err = pci_iommu_batch_add(base_paddr); |
299 | if (unlikely(err < 0L)) | 301 | if (unlikely(err < 0L)) |
300 | goto iommu_map_fail; | 302 | goto iommu_map_fail; |
301 | } | 303 | } |
302 | if (unlikely(pci_iommu_batch_end() < 0L)) | 304 | if (unlikely(pci_iommu_batch_end() < 0L)) |
303 | goto iommu_map_fail; | 305 | goto iommu_map_fail; |
304 | 306 | ||
305 | local_irq_restore(flags); | 307 | local_irq_restore(flags); |
306 | 308 | ||
307 | return ret; | 309 | return ret; |
308 | 310 | ||
309 | bad: | 311 | bad: |
310 | if (printk_ratelimit()) | 312 | if (printk_ratelimit()) |
311 | WARN_ON(1); | 313 | WARN_ON(1); |
312 | return PCI_DMA_ERROR_CODE; | 314 | return PCI_DMA_ERROR_CODE; |
313 | 315 | ||
314 | iommu_map_fail: | 316 | iommu_map_fail: |
315 | /* Interrupts are disabled. */ | 317 | /* Interrupts are disabled. */ |
316 | spin_lock(&iommu->lock); | 318 | spin_lock(&iommu->lock); |
317 | pci_arena_free(&iommu->arena, entry, npages); | 319 | pci_arena_free(&iommu->arena, entry, npages); |
318 | spin_unlock_irqrestore(&iommu->lock, flags); | 320 | spin_unlock_irqrestore(&iommu->lock, flags); |
319 | 321 | ||
320 | return PCI_DMA_ERROR_CODE; | 322 | return PCI_DMA_ERROR_CODE; |
321 | } | 323 | } |
322 | 324 | ||
323 | static void pci_4v_unmap_single(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz, int direction) | 325 | static void pci_4v_unmap_single(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz, int direction) |
324 | { | 326 | { |
325 | struct pcidev_cookie *pcp; | 327 | struct pcidev_cookie *pcp; |
326 | struct pci_iommu *iommu; | 328 | struct pci_iommu *iommu; |
327 | unsigned long flags, npages; | 329 | unsigned long flags, npages; |
328 | long entry; | 330 | long entry; |
329 | u32 devhandle; | 331 | u32 devhandle; |
330 | 332 | ||
331 | if (unlikely(direction == PCI_DMA_NONE)) { | 333 | if (unlikely(direction == PCI_DMA_NONE)) { |
332 | if (printk_ratelimit()) | 334 | if (printk_ratelimit()) |
333 | WARN_ON(1); | 335 | WARN_ON(1); |
334 | return; | 336 | return; |
335 | } | 337 | } |
336 | 338 | ||
337 | pcp = pdev->sysdata; | 339 | pcp = pdev->sysdata; |
338 | iommu = pcp->pbm->iommu; | 340 | iommu = pcp->pbm->iommu; |
339 | devhandle = pcp->pbm->devhandle; | 341 | devhandle = pcp->pbm->devhandle; |
340 | 342 | ||
341 | npages = IO_PAGE_ALIGN(bus_addr + sz) - (bus_addr & IO_PAGE_MASK); | 343 | npages = IO_PAGE_ALIGN(bus_addr + sz) - (bus_addr & IO_PAGE_MASK); |
342 | npages >>= IO_PAGE_SHIFT; | 344 | npages >>= IO_PAGE_SHIFT; |
343 | bus_addr &= IO_PAGE_MASK; | 345 | bus_addr &= IO_PAGE_MASK; |
344 | 346 | ||
345 | spin_lock_irqsave(&iommu->lock, flags); | 347 | spin_lock_irqsave(&iommu->lock, flags); |
346 | 348 | ||
347 | entry = (bus_addr - iommu->page_table_map_base) >> IO_PAGE_SHIFT; | 349 | entry = (bus_addr - iommu->page_table_map_base) >> IO_PAGE_SHIFT; |
348 | pci_arena_free(&iommu->arena, entry, npages); | 350 | pci_arena_free(&iommu->arena, entry, npages); |
349 | 351 | ||
350 | do { | 352 | do { |
351 | unsigned long num; | 353 | unsigned long num; |
352 | 354 | ||
353 | num = pci_sun4v_iommu_demap(devhandle, HV_PCI_TSBID(0, entry), | 355 | num = pci_sun4v_iommu_demap(devhandle, HV_PCI_TSBID(0, entry), |
354 | npages); | 356 | npages); |
355 | entry += num; | 357 | entry += num; |
356 | npages -= num; | 358 | npages -= num; |
357 | } while (npages != 0); | 359 | } while (npages != 0); |
358 | 360 | ||
359 | spin_unlock_irqrestore(&iommu->lock, flags); | 361 | spin_unlock_irqrestore(&iommu->lock, flags); |
360 | } | 362 | } |
361 | 363 | ||
362 | #define SG_ENT_PHYS_ADDRESS(SG) \ | 364 | #define SG_ENT_PHYS_ADDRESS(SG) \ |
363 | (__pa(page_address((SG)->page)) + (SG)->offset) | 365 | (__pa(page_address((SG)->page)) + (SG)->offset) |
364 | 366 | ||
365 | static inline long fill_sg(long entry, struct pci_dev *pdev, | 367 | static inline long fill_sg(long entry, struct pci_dev *pdev, |
366 | struct scatterlist *sg, | 368 | struct scatterlist *sg, |
367 | int nused, int nelems, unsigned long prot) | 369 | int nused, int nelems, unsigned long prot) |
368 | { | 370 | { |
369 | struct scatterlist *dma_sg = sg; | 371 | struct scatterlist *dma_sg = sg; |
370 | struct scatterlist *sg_end = sg + nelems; | 372 | struct scatterlist *sg_end = sg + nelems; |
371 | unsigned long flags; | 373 | unsigned long flags; |
372 | int i; | 374 | int i; |
373 | 375 | ||
374 | local_irq_save(flags); | 376 | local_irq_save(flags); |
375 | 377 | ||
376 | pci_iommu_batch_start(pdev, prot, entry); | 378 | pci_iommu_batch_start(pdev, prot, entry); |
377 | 379 | ||
378 | for (i = 0; i < nused; i++) { | 380 | for (i = 0; i < nused; i++) { |
379 | unsigned long pteval = ~0UL; | 381 | unsigned long pteval = ~0UL; |
380 | u32 dma_npages; | 382 | u32 dma_npages; |
381 | 383 | ||
382 | dma_npages = ((dma_sg->dma_address & (IO_PAGE_SIZE - 1UL)) + | 384 | dma_npages = ((dma_sg->dma_address & (IO_PAGE_SIZE - 1UL)) + |
383 | dma_sg->dma_length + | 385 | dma_sg->dma_length + |
384 | ((IO_PAGE_SIZE - 1UL))) >> IO_PAGE_SHIFT; | 386 | ((IO_PAGE_SIZE - 1UL))) >> IO_PAGE_SHIFT; |
385 | do { | 387 | do { |
386 | unsigned long offset; | 388 | unsigned long offset; |
387 | signed int len; | 389 | signed int len; |
388 | 390 | ||
389 | /* If we are here, we know we have at least one | 391 | /* If we are here, we know we have at least one |
390 | * more page to map. So walk forward until we | 392 | * more page to map. So walk forward until we |
391 | * hit a page crossing, and begin creating new | 393 | * hit a page crossing, and begin creating new |
392 | * mappings from that spot. | 394 | * mappings from that spot. |
393 | */ | 395 | */ |
394 | for (;;) { | 396 | for (;;) { |
395 | unsigned long tmp; | 397 | unsigned long tmp; |
396 | 398 | ||
397 | tmp = SG_ENT_PHYS_ADDRESS(sg); | 399 | tmp = SG_ENT_PHYS_ADDRESS(sg); |
398 | len = sg->length; | 400 | len = sg->length; |
399 | if (((tmp ^ pteval) >> IO_PAGE_SHIFT) != 0UL) { | 401 | if (((tmp ^ pteval) >> IO_PAGE_SHIFT) != 0UL) { |
400 | pteval = tmp & IO_PAGE_MASK; | 402 | pteval = tmp & IO_PAGE_MASK; |
401 | offset = tmp & (IO_PAGE_SIZE - 1UL); | 403 | offset = tmp & (IO_PAGE_SIZE - 1UL); |
402 | break; | 404 | break; |
403 | } | 405 | } |
404 | if (((tmp ^ (tmp + len - 1UL)) >> IO_PAGE_SHIFT) != 0UL) { | 406 | if (((tmp ^ (tmp + len - 1UL)) >> IO_PAGE_SHIFT) != 0UL) { |
405 | pteval = (tmp + IO_PAGE_SIZE) & IO_PAGE_MASK; | 407 | pteval = (tmp + IO_PAGE_SIZE) & IO_PAGE_MASK; |
406 | offset = 0UL; | 408 | offset = 0UL; |
407 | len -= (IO_PAGE_SIZE - (tmp & (IO_PAGE_SIZE - 1UL))); | 409 | len -= (IO_PAGE_SIZE - (tmp & (IO_PAGE_SIZE - 1UL))); |
408 | break; | 410 | break; |
409 | } | 411 | } |
410 | sg++; | 412 | sg++; |
411 | } | 413 | } |
412 | 414 | ||
413 | pteval = (pteval & IOPTE_PAGE); | 415 | pteval = (pteval & IOPTE_PAGE); |
414 | while (len > 0) { | 416 | while (len > 0) { |
415 | long err; | 417 | long err; |
416 | 418 | ||
417 | err = pci_iommu_batch_add(pteval); | 419 | err = pci_iommu_batch_add(pteval); |
418 | if (unlikely(err < 0L)) | 420 | if (unlikely(err < 0L)) |
419 | goto iommu_map_failed; | 421 | goto iommu_map_failed; |
420 | 422 | ||
421 | pteval += IO_PAGE_SIZE; | 423 | pteval += IO_PAGE_SIZE; |
422 | len -= (IO_PAGE_SIZE - offset); | 424 | len -= (IO_PAGE_SIZE - offset); |
423 | offset = 0; | 425 | offset = 0; |
424 | dma_npages--; | 426 | dma_npages--; |
425 | } | 427 | } |
426 | 428 | ||
427 | pteval = (pteval & IOPTE_PAGE) + len; | 429 | pteval = (pteval & IOPTE_PAGE) + len; |
428 | sg++; | 430 | sg++; |
429 | 431 | ||
430 | /* Skip over any tail mappings we've fully mapped, | 432 | /* Skip over any tail mappings we've fully mapped, |
431 | * adjusting pteval along the way. Stop when we | 433 | * adjusting pteval along the way. Stop when we |
432 | * detect a page crossing event. | 434 | * detect a page crossing event. |
433 | */ | 435 | */ |
434 | while (sg < sg_end && | 436 | while (sg < sg_end && |
435 | (pteval << (64 - IO_PAGE_SHIFT)) != 0UL && | 437 | (pteval << (64 - IO_PAGE_SHIFT)) != 0UL && |
436 | (pteval == SG_ENT_PHYS_ADDRESS(sg)) && | 438 | (pteval == SG_ENT_PHYS_ADDRESS(sg)) && |
437 | ((pteval ^ | 439 | ((pteval ^ |
438 | (SG_ENT_PHYS_ADDRESS(sg) + sg->length - 1UL)) >> IO_PAGE_SHIFT) == 0UL) { | 440 | (SG_ENT_PHYS_ADDRESS(sg) + sg->length - 1UL)) >> IO_PAGE_SHIFT) == 0UL) { |
439 | pteval += sg->length; | 441 | pteval += sg->length; |
440 | sg++; | 442 | sg++; |
441 | } | 443 | } |
442 | if ((pteval << (64 - IO_PAGE_SHIFT)) == 0UL) | 444 | if ((pteval << (64 - IO_PAGE_SHIFT)) == 0UL) |
443 | pteval = ~0UL; | 445 | pteval = ~0UL; |
444 | } while (dma_npages != 0); | 446 | } while (dma_npages != 0); |
445 | dma_sg++; | 447 | dma_sg++; |
446 | } | 448 | } |
447 | 449 | ||
448 | if (unlikely(pci_iommu_batch_end() < 0L)) | 450 | if (unlikely(pci_iommu_batch_end() < 0L)) |
449 | goto iommu_map_failed; | 451 | goto iommu_map_failed; |
450 | 452 | ||
451 | local_irq_restore(flags); | 453 | local_irq_restore(flags); |
452 | return 0; | 454 | return 0; |
453 | 455 | ||
454 | iommu_map_failed: | 456 | iommu_map_failed: |
455 | local_irq_restore(flags); | 457 | local_irq_restore(flags); |
456 | return -1L; | 458 | return -1L; |
457 | } | 459 | } |
458 | 460 | ||
459 | static int pci_4v_map_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems, int direction) | 461 | static int pci_4v_map_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems, int direction) |
460 | { | 462 | { |
461 | struct pcidev_cookie *pcp; | 463 | struct pcidev_cookie *pcp; |
462 | struct pci_iommu *iommu; | 464 | struct pci_iommu *iommu; |
463 | unsigned long flags, npages, prot; | 465 | unsigned long flags, npages, prot; |
464 | u32 dma_base; | 466 | u32 dma_base; |
465 | struct scatterlist *sgtmp; | 467 | struct scatterlist *sgtmp; |
466 | long entry, err; | 468 | long entry, err; |
467 | int used; | 469 | int used; |
468 | 470 | ||
469 | /* Fast path single entry scatterlists. */ | 471 | /* Fast path single entry scatterlists. */ |
470 | if (nelems == 1) { | 472 | if (nelems == 1) { |
471 | sglist->dma_address = | 473 | sglist->dma_address = |
472 | pci_4v_map_single(pdev, | 474 | pci_4v_map_single(pdev, |
473 | (page_address(sglist->page) + sglist->offset), | 475 | (page_address(sglist->page) + sglist->offset), |
474 | sglist->length, direction); | 476 | sglist->length, direction); |
475 | if (unlikely(sglist->dma_address == PCI_DMA_ERROR_CODE)) | 477 | if (unlikely(sglist->dma_address == PCI_DMA_ERROR_CODE)) |
476 | return 0; | 478 | return 0; |
477 | sglist->dma_length = sglist->length; | 479 | sglist->dma_length = sglist->length; |
478 | return 1; | 480 | return 1; |
479 | } | 481 | } |
480 | 482 | ||
481 | pcp = pdev->sysdata; | 483 | pcp = pdev->sysdata; |
482 | iommu = pcp->pbm->iommu; | 484 | iommu = pcp->pbm->iommu; |
483 | 485 | ||
484 | if (unlikely(direction == PCI_DMA_NONE)) | 486 | if (unlikely(direction == PCI_DMA_NONE)) |
485 | goto bad; | 487 | goto bad; |
486 | 488 | ||
487 | /* Step 1: Prepare scatter list. */ | 489 | /* Step 1: Prepare scatter list. */ |
488 | npages = prepare_sg(sglist, nelems); | 490 | npages = prepare_sg(sglist, nelems); |
489 | 491 | ||
490 | /* Step 2: Allocate a cluster and context, if necessary. */ | 492 | /* Step 2: Allocate a cluster and context, if necessary. */ |
491 | spin_lock_irqsave(&iommu->lock, flags); | 493 | spin_lock_irqsave(&iommu->lock, flags); |
492 | entry = pci_arena_alloc(&iommu->arena, npages); | 494 | entry = pci_arena_alloc(&iommu->arena, npages); |
493 | spin_unlock_irqrestore(&iommu->lock, flags); | 495 | spin_unlock_irqrestore(&iommu->lock, flags); |
494 | 496 | ||
495 | if (unlikely(entry < 0L)) | 497 | if (unlikely(entry < 0L)) |
496 | goto bad; | 498 | goto bad; |
497 | 499 | ||
498 | dma_base = iommu->page_table_map_base + | 500 | dma_base = iommu->page_table_map_base + |
499 | (entry << IO_PAGE_SHIFT); | 501 | (entry << IO_PAGE_SHIFT); |
500 | 502 | ||
501 | /* Step 3: Normalize DMA addresses. */ | 503 | /* Step 3: Normalize DMA addresses. */ |
502 | used = nelems; | 504 | used = nelems; |
503 | 505 | ||
504 | sgtmp = sglist; | 506 | sgtmp = sglist; |
505 | while (used && sgtmp->dma_length) { | 507 | while (used && sgtmp->dma_length) { |
506 | sgtmp->dma_address += dma_base; | 508 | sgtmp->dma_address += dma_base; |
507 | sgtmp++; | 509 | sgtmp++; |
508 | used--; | 510 | used--; |
509 | } | 511 | } |
510 | used = nelems - used; | 512 | used = nelems - used; |
511 | 513 | ||
512 | /* Step 4: Create the mappings. */ | 514 | /* Step 4: Create the mappings. */ |
513 | prot = HV_PCI_MAP_ATTR_READ; | 515 | prot = HV_PCI_MAP_ATTR_READ; |
514 | if (direction != PCI_DMA_TODEVICE) | 516 | if (direction != PCI_DMA_TODEVICE) |
515 | prot |= HV_PCI_MAP_ATTR_WRITE; | 517 | prot |= HV_PCI_MAP_ATTR_WRITE; |
516 | 518 | ||
517 | err = fill_sg(entry, pdev, sglist, used, nelems, prot); | 519 | err = fill_sg(entry, pdev, sglist, used, nelems, prot); |
518 | if (unlikely(err < 0L)) | 520 | if (unlikely(err < 0L)) |
519 | goto iommu_map_failed; | 521 | goto iommu_map_failed; |
520 | 522 | ||
521 | return used; | 523 | return used; |
522 | 524 | ||
523 | bad: | 525 | bad: |
524 | if (printk_ratelimit()) | 526 | if (printk_ratelimit()) |
525 | WARN_ON(1); | 527 | WARN_ON(1); |
526 | return 0; | 528 | return 0; |
527 | 529 | ||
528 | iommu_map_failed: | 530 | iommu_map_failed: |
529 | spin_lock_irqsave(&iommu->lock, flags); | 531 | spin_lock_irqsave(&iommu->lock, flags); |
530 | pci_arena_free(&iommu->arena, entry, npages); | 532 | pci_arena_free(&iommu->arena, entry, npages); |
531 | spin_unlock_irqrestore(&iommu->lock, flags); | 533 | spin_unlock_irqrestore(&iommu->lock, flags); |
532 | 534 | ||
533 | return 0; | 535 | return 0; |
534 | } | 536 | } |
535 | 537 | ||
536 | static void pci_4v_unmap_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems, int direction) | 538 | static void pci_4v_unmap_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems, int direction) |
537 | { | 539 | { |
538 | struct pcidev_cookie *pcp; | 540 | struct pcidev_cookie *pcp; |
539 | struct pci_iommu *iommu; | 541 | struct pci_iommu *iommu; |
540 | unsigned long flags, i, npages; | 542 | unsigned long flags, i, npages; |
541 | long entry; | 543 | long entry; |
542 | u32 devhandle, bus_addr; | 544 | u32 devhandle, bus_addr; |
543 | 545 | ||
544 | if (unlikely(direction == PCI_DMA_NONE)) { | 546 | if (unlikely(direction == PCI_DMA_NONE)) { |
545 | if (printk_ratelimit()) | 547 | if (printk_ratelimit()) |
546 | WARN_ON(1); | 548 | WARN_ON(1); |
547 | } | 549 | } |
548 | 550 | ||
549 | pcp = pdev->sysdata; | 551 | pcp = pdev->sysdata; |
550 | iommu = pcp->pbm->iommu; | 552 | iommu = pcp->pbm->iommu; |
551 | devhandle = pcp->pbm->devhandle; | 553 | devhandle = pcp->pbm->devhandle; |
552 | 554 | ||
553 | bus_addr = sglist->dma_address & IO_PAGE_MASK; | 555 | bus_addr = sglist->dma_address & IO_PAGE_MASK; |
554 | 556 | ||
555 | for (i = 1; i < nelems; i++) | 557 | for (i = 1; i < nelems; i++) |
556 | if (sglist[i].dma_length == 0) | 558 | if (sglist[i].dma_length == 0) |
557 | break; | 559 | break; |
558 | i--; | 560 | i--; |
559 | npages = (IO_PAGE_ALIGN(sglist[i].dma_address + sglist[i].dma_length) - | 561 | npages = (IO_PAGE_ALIGN(sglist[i].dma_address + sglist[i].dma_length) - |
560 | bus_addr) >> IO_PAGE_SHIFT; | 562 | bus_addr) >> IO_PAGE_SHIFT; |
561 | 563 | ||
562 | entry = ((bus_addr - iommu->page_table_map_base) >> IO_PAGE_SHIFT); | 564 | entry = ((bus_addr - iommu->page_table_map_base) >> IO_PAGE_SHIFT); |
563 | 565 | ||
564 | spin_lock_irqsave(&iommu->lock, flags); | 566 | spin_lock_irqsave(&iommu->lock, flags); |
565 | 567 | ||
566 | pci_arena_free(&iommu->arena, entry, npages); | 568 | pci_arena_free(&iommu->arena, entry, npages); |
567 | 569 | ||
568 | do { | 570 | do { |
569 | unsigned long num; | 571 | unsigned long num; |
570 | 572 | ||
571 | num = pci_sun4v_iommu_demap(devhandle, HV_PCI_TSBID(0, entry), | 573 | num = pci_sun4v_iommu_demap(devhandle, HV_PCI_TSBID(0, entry), |
572 | npages); | 574 | npages); |
573 | entry += num; | 575 | entry += num; |
574 | npages -= num; | 576 | npages -= num; |
575 | } while (npages != 0); | 577 | } while (npages != 0); |
576 | 578 | ||
577 | spin_unlock_irqrestore(&iommu->lock, flags); | 579 | spin_unlock_irqrestore(&iommu->lock, flags); |
578 | } | 580 | } |
579 | 581 | ||
580 | static void pci_4v_dma_sync_single_for_cpu(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz, int direction) | 582 | static void pci_4v_dma_sync_single_for_cpu(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz, int direction) |
581 | { | 583 | { |
582 | /* Nothing to do... */ | 584 | /* Nothing to do... */ |
583 | } | 585 | } |
584 | 586 | ||
585 | static void pci_4v_dma_sync_sg_for_cpu(struct pci_dev *pdev, struct scatterlist *sglist, int nelems, int direction) | 587 | static void pci_4v_dma_sync_sg_for_cpu(struct pci_dev *pdev, struct scatterlist *sglist, int nelems, int direction) |
586 | { | 588 | { |
587 | /* Nothing to do... */ | 589 | /* Nothing to do... */ |
588 | } | 590 | } |
589 | 591 | ||
590 | struct pci_iommu_ops pci_sun4v_iommu_ops = { | 592 | struct pci_iommu_ops pci_sun4v_iommu_ops = { |
591 | .alloc_consistent = pci_4v_alloc_consistent, | 593 | .alloc_consistent = pci_4v_alloc_consistent, |
592 | .free_consistent = pci_4v_free_consistent, | 594 | .free_consistent = pci_4v_free_consistent, |
593 | .map_single = pci_4v_map_single, | 595 | .map_single = pci_4v_map_single, |
594 | .unmap_single = pci_4v_unmap_single, | 596 | .unmap_single = pci_4v_unmap_single, |
595 | .map_sg = pci_4v_map_sg, | 597 | .map_sg = pci_4v_map_sg, |
596 | .unmap_sg = pci_4v_unmap_sg, | 598 | .unmap_sg = pci_4v_unmap_sg, |
597 | .dma_sync_single_for_cpu = pci_4v_dma_sync_single_for_cpu, | 599 | .dma_sync_single_for_cpu = pci_4v_dma_sync_single_for_cpu, |
598 | .dma_sync_sg_for_cpu = pci_4v_dma_sync_sg_for_cpu, | 600 | .dma_sync_sg_for_cpu = pci_4v_dma_sync_sg_for_cpu, |
599 | }; | 601 | }; |
600 | 602 | ||
601 | /* SUN4V PCI configuration space accessors. */ | 603 | /* SUN4V PCI configuration space accessors. */ |
602 | 604 | ||
603 | struct pdev_entry { | 605 | struct pdev_entry { |
604 | struct pdev_entry *next; | 606 | struct pdev_entry *next; |
605 | u32 devhandle; | 607 | u32 devhandle; |
606 | unsigned int bus; | 608 | unsigned int bus; |
607 | unsigned int device; | 609 | unsigned int device; |
608 | unsigned int func; | 610 | unsigned int func; |
609 | }; | 611 | }; |
610 | 612 | ||
611 | #define PDEV_HTAB_SIZE 16 | 613 | #define PDEV_HTAB_SIZE 16 |
612 | #define PDEV_HTAB_MASK (PDEV_HTAB_SIZE - 1) | 614 | #define PDEV_HTAB_MASK (PDEV_HTAB_SIZE - 1) |
613 | static struct pdev_entry *pdev_htab[PDEV_HTAB_SIZE]; | 615 | static struct pdev_entry *pdev_htab[PDEV_HTAB_SIZE]; |
614 | 616 | ||
615 | static inline unsigned int pdev_hashfn(u32 devhandle, unsigned int bus, unsigned int device, unsigned int func) | 617 | static inline unsigned int pdev_hashfn(u32 devhandle, unsigned int bus, unsigned int device, unsigned int func) |
616 | { | 618 | { |
617 | unsigned int val; | 619 | unsigned int val; |
618 | 620 | ||
619 | val = (devhandle ^ (devhandle >> 4)); | 621 | val = (devhandle ^ (devhandle >> 4)); |
620 | val ^= bus; | 622 | val ^= bus; |
621 | val ^= device; | 623 | val ^= device; |
622 | val ^= func; | 624 | val ^= func; |
623 | 625 | ||
624 | return val & PDEV_HTAB_MASK; | 626 | return val & PDEV_HTAB_MASK; |
625 | } | 627 | } |
626 | 628 | ||
627 | static int pdev_htab_add(u32 devhandle, unsigned int bus, unsigned int device, unsigned int func) | 629 | static int pdev_htab_add(u32 devhandle, unsigned int bus, unsigned int device, unsigned int func) |
628 | { | 630 | { |
629 | struct pdev_entry *p = kmalloc(sizeof(*p), GFP_KERNEL); | 631 | struct pdev_entry *p = kmalloc(sizeof(*p), GFP_KERNEL); |
630 | struct pdev_entry **slot; | 632 | struct pdev_entry **slot; |
631 | 633 | ||
632 | if (!p) | 634 | if (!p) |
633 | return -ENOMEM; | 635 | return -ENOMEM; |
634 | 636 | ||
635 | slot = &pdev_htab[pdev_hashfn(devhandle, bus, device, func)]; | 637 | slot = &pdev_htab[pdev_hashfn(devhandle, bus, device, func)]; |
636 | p->next = *slot; | 638 | p->next = *slot; |
637 | *slot = p; | 639 | *slot = p; |
638 | 640 | ||
639 | p->devhandle = devhandle; | 641 | p->devhandle = devhandle; |
640 | p->bus = bus; | 642 | p->bus = bus; |
641 | p->device = device; | 643 | p->device = device; |
642 | p->func = func; | 644 | p->func = func; |
643 | 645 | ||
644 | return 0; | 646 | return 0; |
645 | } | 647 | } |
646 | 648 | ||
647 | /* Recursively descend into the OBP device tree, rooted at toplevel_node, | 649 | /* Recursively descend into the OBP device tree, rooted at toplevel_node, |
648 | * looking for a PCI device matching bus and devfn. | 650 | * looking for a PCI device matching bus and devfn. |
649 | */ | 651 | */ |
650 | static int obp_find(struct device_node *toplevel_node, unsigned int bus, unsigned int devfn) | 652 | static int obp_find(struct device_node *toplevel_node, unsigned int bus, unsigned int devfn) |
651 | { | 653 | { |
652 | toplevel_node = toplevel_node->child; | 654 | toplevel_node = toplevel_node->child; |
653 | 655 | ||
654 | while (toplevel_node != NULL) { | 656 | while (toplevel_node != NULL) { |
655 | struct linux_prom_pci_registers *regs; | 657 | struct linux_prom_pci_registers *regs; |
656 | struct property *prop; | 658 | struct property *prop; |
657 | int ret; | 659 | int ret; |
658 | 660 | ||
659 | ret = obp_find(toplevel_node, bus, devfn); | 661 | ret = obp_find(toplevel_node, bus, devfn); |
660 | if (ret != 0) | 662 | if (ret != 0) |
661 | return ret; | 663 | return ret; |
662 | 664 | ||
663 | prop = of_find_property(toplevel_node, "reg", NULL); | 665 | prop = of_find_property(toplevel_node, "reg", NULL); |
664 | if (!prop) | 666 | if (!prop) |
665 | goto next_sibling; | 667 | goto next_sibling; |
666 | 668 | ||
667 | regs = prop->value; | 669 | regs = prop->value; |
668 | if (((regs->phys_hi >> 16) & 0xff) == bus && | 670 | if (((regs->phys_hi >> 16) & 0xff) == bus && |
669 | ((regs->phys_hi >> 8) & 0xff) == devfn) | 671 | ((regs->phys_hi >> 8) & 0xff) == devfn) |
670 | break; | 672 | break; |
671 | 673 | ||
672 | next_sibling: | 674 | next_sibling: |
673 | toplevel_node = toplevel_node->sibling; | 675 | toplevel_node = toplevel_node->sibling; |
674 | } | 676 | } |
675 | 677 | ||
676 | return toplevel_node != NULL; | 678 | return toplevel_node != NULL; |
677 | } | 679 | } |
678 | 680 | ||
679 | static int pdev_htab_populate(struct pci_pbm_info *pbm) | 681 | static int pdev_htab_populate(struct pci_pbm_info *pbm) |
680 | { | 682 | { |
681 | u32 devhandle = pbm->devhandle; | 683 | u32 devhandle = pbm->devhandle; |
682 | unsigned int bus; | 684 | unsigned int bus; |
683 | 685 | ||
684 | for (bus = pbm->pci_first_busno; bus <= pbm->pci_last_busno; bus++) { | 686 | for (bus = pbm->pci_first_busno; bus <= pbm->pci_last_busno; bus++) { |
685 | unsigned int devfn; | 687 | unsigned int devfn; |
686 | 688 | ||
687 | for (devfn = 0; devfn < 256; devfn++) { | 689 | for (devfn = 0; devfn < 256; devfn++) { |
688 | unsigned int device = PCI_SLOT(devfn); | 690 | unsigned int device = PCI_SLOT(devfn); |
689 | unsigned int func = PCI_FUNC(devfn); | 691 | unsigned int func = PCI_FUNC(devfn); |
690 | 692 | ||
691 | if (obp_find(pbm->prom_node, bus, devfn)) { | 693 | if (obp_find(pbm->prom_node, bus, devfn)) { |
692 | int err = pdev_htab_add(devhandle, bus, | 694 | int err = pdev_htab_add(devhandle, bus, |
693 | device, func); | 695 | device, func); |
694 | if (err) | 696 | if (err) |
695 | return err; | 697 | return err; |
696 | } | 698 | } |
697 | } | 699 | } |
698 | } | 700 | } |
699 | 701 | ||
700 | return 0; | 702 | return 0; |
701 | } | 703 | } |
702 | 704 | ||
703 | static struct pdev_entry *pdev_find(u32 devhandle, unsigned int bus, unsigned int device, unsigned int func) | 705 | static struct pdev_entry *pdev_find(u32 devhandle, unsigned int bus, unsigned int device, unsigned int func) |
704 | { | 706 | { |
705 | struct pdev_entry *p; | 707 | struct pdev_entry *p; |
706 | 708 | ||
707 | p = pdev_htab[pdev_hashfn(devhandle, bus, device, func)]; | 709 | p = pdev_htab[pdev_hashfn(devhandle, bus, device, func)]; |
708 | while (p) { | 710 | while (p) { |
709 | if (p->devhandle == devhandle && | 711 | if (p->devhandle == devhandle && |
710 | p->bus == bus && | 712 | p->bus == bus && |
711 | p->device == device && | 713 | p->device == device && |
712 | p->func == func) | 714 | p->func == func) |
713 | break; | 715 | break; |
714 | 716 | ||
715 | p = p->next; | 717 | p = p->next; |
716 | } | 718 | } |
717 | 719 | ||
718 | return p; | 720 | return p; |
719 | } | 721 | } |
720 | 722 | ||
721 | static inline int pci_sun4v_out_of_range(struct pci_pbm_info *pbm, unsigned int bus, unsigned int device, unsigned int func) | 723 | static inline int pci_sun4v_out_of_range(struct pci_pbm_info *pbm, unsigned int bus, unsigned int device, unsigned int func) |
722 | { | 724 | { |
723 | if (bus < pbm->pci_first_busno || | 725 | if (bus < pbm->pci_first_busno || |
724 | bus > pbm->pci_last_busno) | 726 | bus > pbm->pci_last_busno) |
725 | return 1; | 727 | return 1; |
726 | return pdev_find(pbm->devhandle, bus, device, func) == NULL; | 728 | return pdev_find(pbm->devhandle, bus, device, func) == NULL; |
727 | } | 729 | } |
728 | 730 | ||
729 | static int pci_sun4v_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, | 731 | static int pci_sun4v_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, |
730 | int where, int size, u32 *value) | 732 | int where, int size, u32 *value) |
731 | { | 733 | { |
732 | struct pci_pbm_info *pbm = bus_dev->sysdata; | 734 | struct pci_pbm_info *pbm = bus_dev->sysdata; |
733 | u32 devhandle = pbm->devhandle; | 735 | u32 devhandle = pbm->devhandle; |
734 | unsigned int bus = bus_dev->number; | 736 | unsigned int bus = bus_dev->number; |
735 | unsigned int device = PCI_SLOT(devfn); | 737 | unsigned int device = PCI_SLOT(devfn); |
736 | unsigned int func = PCI_FUNC(devfn); | 738 | unsigned int func = PCI_FUNC(devfn); |
737 | unsigned long ret; | 739 | unsigned long ret; |
738 | 740 | ||
739 | if (pci_sun4v_out_of_range(pbm, bus, device, func)) { | 741 | if (pci_sun4v_out_of_range(pbm, bus, device, func)) { |
740 | ret = ~0UL; | 742 | ret = ~0UL; |
741 | } else { | 743 | } else { |
742 | ret = pci_sun4v_config_get(devhandle, | 744 | ret = pci_sun4v_config_get(devhandle, |
743 | HV_PCI_DEVICE_BUILD(bus, device, func), | 745 | HV_PCI_DEVICE_BUILD(bus, device, func), |
744 | where, size); | 746 | where, size); |
745 | #if 0 | 747 | #if 0 |
746 | printk("rcfg: [%x:%x:%x:%d]=[%lx]\n", | 748 | printk("rcfg: [%x:%x:%x:%d]=[%lx]\n", |
747 | devhandle, HV_PCI_DEVICE_BUILD(bus, device, func), | 749 | devhandle, HV_PCI_DEVICE_BUILD(bus, device, func), |
748 | where, size, ret); | 750 | where, size, ret); |
749 | #endif | 751 | #endif |
750 | } | 752 | } |
751 | switch (size) { | 753 | switch (size) { |
752 | case 1: | 754 | case 1: |
753 | *value = ret & 0xff; | 755 | *value = ret & 0xff; |
754 | break; | 756 | break; |
755 | case 2: | 757 | case 2: |
756 | *value = ret & 0xffff; | 758 | *value = ret & 0xffff; |
757 | break; | 759 | break; |
758 | case 4: | 760 | case 4: |
759 | *value = ret & 0xffffffff; | 761 | *value = ret & 0xffffffff; |
760 | break; | 762 | break; |
761 | }; | 763 | }; |
762 | 764 | ||
763 | 765 | ||
764 | return PCIBIOS_SUCCESSFUL; | 766 | return PCIBIOS_SUCCESSFUL; |
765 | } | 767 | } |
766 | 768 | ||
767 | static int pci_sun4v_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, | 769 | static int pci_sun4v_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, |
768 | int where, int size, u32 value) | 770 | int where, int size, u32 value) |
769 | { | 771 | { |
770 | struct pci_pbm_info *pbm = bus_dev->sysdata; | 772 | struct pci_pbm_info *pbm = bus_dev->sysdata; |
771 | u32 devhandle = pbm->devhandle; | 773 | u32 devhandle = pbm->devhandle; |
772 | unsigned int bus = bus_dev->number; | 774 | unsigned int bus = bus_dev->number; |
773 | unsigned int device = PCI_SLOT(devfn); | 775 | unsigned int device = PCI_SLOT(devfn); |
774 | unsigned int func = PCI_FUNC(devfn); | 776 | unsigned int func = PCI_FUNC(devfn); |
775 | unsigned long ret; | 777 | unsigned long ret; |
776 | 778 | ||
777 | if (pci_sun4v_out_of_range(pbm, bus, device, func)) { | 779 | if (pci_sun4v_out_of_range(pbm, bus, device, func)) { |
778 | /* Do nothing. */ | 780 | /* Do nothing. */ |
779 | } else { | 781 | } else { |
780 | ret = pci_sun4v_config_put(devhandle, | 782 | ret = pci_sun4v_config_put(devhandle, |
781 | HV_PCI_DEVICE_BUILD(bus, device, func), | 783 | HV_PCI_DEVICE_BUILD(bus, device, func), |
782 | where, size, value); | 784 | where, size, value); |
783 | #if 0 | 785 | #if 0 |
784 | printk("wcfg: [%x:%x:%x:%d] v[%x] == [%lx]\n", | 786 | printk("wcfg: [%x:%x:%x:%d] v[%x] == [%lx]\n", |
785 | devhandle, HV_PCI_DEVICE_BUILD(bus, device, func), | 787 | devhandle, HV_PCI_DEVICE_BUILD(bus, device, func), |
786 | where, size, value, ret); | 788 | where, size, value, ret); |
787 | #endif | 789 | #endif |
788 | } | 790 | } |
789 | return PCIBIOS_SUCCESSFUL; | 791 | return PCIBIOS_SUCCESSFUL; |
790 | } | 792 | } |
791 | 793 | ||
792 | static struct pci_ops pci_sun4v_ops = { | 794 | static struct pci_ops pci_sun4v_ops = { |
793 | .read = pci_sun4v_read_pci_cfg, | 795 | .read = pci_sun4v_read_pci_cfg, |
794 | .write = pci_sun4v_write_pci_cfg, | 796 | .write = pci_sun4v_write_pci_cfg, |
795 | }; | 797 | }; |
796 | 798 | ||
797 | 799 | ||
798 | static void pbm_scan_bus(struct pci_controller_info *p, | 800 | static void pbm_scan_bus(struct pci_controller_info *p, |
799 | struct pci_pbm_info *pbm) | 801 | struct pci_pbm_info *pbm) |
800 | { | 802 | { |
801 | struct pcidev_cookie *cookie = kzalloc(sizeof(*cookie), GFP_KERNEL); | 803 | struct pcidev_cookie *cookie = kzalloc(sizeof(*cookie), GFP_KERNEL); |
802 | 804 | ||
803 | if (!cookie) { | 805 | if (!cookie) { |
804 | prom_printf("%s: Critical allocation failure.\n", pbm->name); | 806 | prom_printf("%s: Critical allocation failure.\n", pbm->name); |
805 | prom_halt(); | 807 | prom_halt(); |
806 | } | 808 | } |
807 | 809 | ||
808 | /* All we care about is the PBM. */ | 810 | /* All we care about is the PBM. */ |
809 | cookie->pbm = pbm; | 811 | cookie->pbm = pbm; |
810 | 812 | ||
811 | pbm->pci_bus = pci_scan_bus(pbm->pci_first_busno, p->pci_ops, pbm); | 813 | pbm->pci_bus = pci_scan_bus(pbm->pci_first_busno, p->pci_ops, pbm); |
812 | #if 0 | 814 | #if 0 |
813 | pci_fixup_host_bridge_self(pbm->pci_bus); | 815 | pci_fixup_host_bridge_self(pbm->pci_bus); |
814 | pbm->pci_bus->self->sysdata = cookie; | 816 | pbm->pci_bus->self->sysdata = cookie; |
815 | #endif | 817 | #endif |
816 | pci_fill_in_pbm_cookies(pbm->pci_bus, pbm, pbm->prom_node); | 818 | pci_fill_in_pbm_cookies(pbm->pci_bus, pbm, pbm->prom_node); |
817 | pci_record_assignments(pbm, pbm->pci_bus); | 819 | pci_record_assignments(pbm, pbm->pci_bus); |
818 | pci_assign_unassigned(pbm, pbm->pci_bus); | 820 | pci_assign_unassigned(pbm, pbm->pci_bus); |
819 | pci_fixup_irq(pbm, pbm->pci_bus); | 821 | pci_fixup_irq(pbm, pbm->pci_bus); |
820 | pci_determine_66mhz_disposition(pbm, pbm->pci_bus); | 822 | pci_determine_66mhz_disposition(pbm, pbm->pci_bus); |
821 | pci_setup_busmastering(pbm, pbm->pci_bus); | 823 | pci_setup_busmastering(pbm, pbm->pci_bus); |
822 | } | 824 | } |
823 | 825 | ||
824 | static void pci_sun4v_scan_bus(struct pci_controller_info *p) | 826 | static void pci_sun4v_scan_bus(struct pci_controller_info *p) |
825 | { | 827 | { |
826 | struct property *prop; | 828 | struct property *prop; |
827 | struct device_node *dp; | 829 | struct device_node *dp; |
828 | 830 | ||
829 | if ((dp = p->pbm_A.prom_node) != NULL) { | 831 | if ((dp = p->pbm_A.prom_node) != NULL) { |
830 | prop = of_find_property(dp, "66mhz-capable", NULL); | 832 | prop = of_find_property(dp, "66mhz-capable", NULL); |
831 | p->pbm_A.is_66mhz_capable = (prop != NULL); | 833 | p->pbm_A.is_66mhz_capable = (prop != NULL); |
832 | 834 | ||
833 | pbm_scan_bus(p, &p->pbm_A); | 835 | pbm_scan_bus(p, &p->pbm_A); |
834 | } | 836 | } |
835 | if ((dp = p->pbm_B.prom_node) != NULL) { | 837 | if ((dp = p->pbm_B.prom_node) != NULL) { |
836 | prop = of_find_property(dp, "66mhz-capable", NULL); | 838 | prop = of_find_property(dp, "66mhz-capable", NULL); |
837 | p->pbm_B.is_66mhz_capable = (prop != NULL); | 839 | p->pbm_B.is_66mhz_capable = (prop != NULL); |
838 | 840 | ||
839 | pbm_scan_bus(p, &p->pbm_B); | 841 | pbm_scan_bus(p, &p->pbm_B); |
840 | } | 842 | } |
841 | 843 | ||
842 | /* XXX register error interrupt handlers XXX */ | 844 | /* XXX register error interrupt handlers XXX */ |
843 | } | 845 | } |
844 | 846 | ||
845 | static void pci_sun4v_base_address_update(struct pci_dev *pdev, int resource) | 847 | static void pci_sun4v_base_address_update(struct pci_dev *pdev, int resource) |
846 | { | 848 | { |
847 | struct pcidev_cookie *pcp = pdev->sysdata; | 849 | struct pcidev_cookie *pcp = pdev->sysdata; |
848 | struct pci_pbm_info *pbm = pcp->pbm; | 850 | struct pci_pbm_info *pbm = pcp->pbm; |
849 | struct resource *res, *root; | 851 | struct resource *res, *root; |
850 | u32 reg; | 852 | u32 reg; |
851 | int where, size, is_64bit; | 853 | int where, size, is_64bit; |
852 | 854 | ||
853 | res = &pdev->resource[resource]; | 855 | res = &pdev->resource[resource]; |
854 | if (resource < 6) { | 856 | if (resource < 6) { |
855 | where = PCI_BASE_ADDRESS_0 + (resource * 4); | 857 | where = PCI_BASE_ADDRESS_0 + (resource * 4); |
856 | } else if (resource == PCI_ROM_RESOURCE) { | 858 | } else if (resource == PCI_ROM_RESOURCE) { |
857 | where = pdev->rom_base_reg; | 859 | where = pdev->rom_base_reg; |
858 | } else { | 860 | } else { |
859 | /* Somebody might have asked allocation of a non-standard resource */ | 861 | /* Somebody might have asked allocation of a non-standard resource */ |
860 | return; | 862 | return; |
861 | } | 863 | } |
862 | 864 | ||
863 | /* XXX 64-bit MEM handling is not %100 correct... XXX */ | 865 | /* XXX 64-bit MEM handling is not %100 correct... XXX */ |
864 | is_64bit = 0; | 866 | is_64bit = 0; |
865 | if (res->flags & IORESOURCE_IO) | 867 | if (res->flags & IORESOURCE_IO) |
866 | root = &pbm->io_space; | 868 | root = &pbm->io_space; |
867 | else { | 869 | else { |
868 | root = &pbm->mem_space; | 870 | root = &pbm->mem_space; |
869 | if ((res->flags & PCI_BASE_ADDRESS_MEM_TYPE_MASK) | 871 | if ((res->flags & PCI_BASE_ADDRESS_MEM_TYPE_MASK) |
870 | == PCI_BASE_ADDRESS_MEM_TYPE_64) | 872 | == PCI_BASE_ADDRESS_MEM_TYPE_64) |
871 | is_64bit = 1; | 873 | is_64bit = 1; |
872 | } | 874 | } |
873 | 875 | ||
874 | size = res->end - res->start; | 876 | size = res->end - res->start; |
875 | pci_read_config_dword(pdev, where, ®); | 877 | pci_read_config_dword(pdev, where, ®); |
876 | reg = ((reg & size) | | 878 | reg = ((reg & size) | |
877 | (((u32)(res->start - root->start)) & ~size)); | 879 | (((u32)(res->start - root->start)) & ~size)); |
878 | if (resource == PCI_ROM_RESOURCE) { | 880 | if (resource == PCI_ROM_RESOURCE) { |
879 | reg |= PCI_ROM_ADDRESS_ENABLE; | 881 | reg |= PCI_ROM_ADDRESS_ENABLE; |
880 | res->flags |= IORESOURCE_ROM_ENABLE; | 882 | res->flags |= IORESOURCE_ROM_ENABLE; |
881 | } | 883 | } |
882 | pci_write_config_dword(pdev, where, reg); | 884 | pci_write_config_dword(pdev, where, reg); |
883 | 885 | ||
884 | /* This knows that the upper 32-bits of the address | 886 | /* This knows that the upper 32-bits of the address |
885 | * must be zero. Our PCI common layer enforces this. | 887 | * must be zero. Our PCI common layer enforces this. |
886 | */ | 888 | */ |
887 | if (is_64bit) | 889 | if (is_64bit) |
888 | pci_write_config_dword(pdev, where + 4, 0); | 890 | pci_write_config_dword(pdev, where + 4, 0); |
889 | } | 891 | } |
890 | 892 | ||
891 | static void pci_sun4v_resource_adjust(struct pci_dev *pdev, | 893 | static void pci_sun4v_resource_adjust(struct pci_dev *pdev, |
892 | struct resource *res, | 894 | struct resource *res, |
893 | struct resource *root) | 895 | struct resource *root) |
894 | { | 896 | { |
895 | res->start += root->start; | 897 | res->start += root->start; |
896 | res->end += root->start; | 898 | res->end += root->start; |
897 | } | 899 | } |
898 | 900 | ||
899 | /* Use ranges property to determine where PCI MEM, I/O, and Config | 901 | /* Use ranges property to determine where PCI MEM, I/O, and Config |
900 | * space are for this PCI bus module. | 902 | * space are for this PCI bus module. |
901 | */ | 903 | */ |
902 | static void pci_sun4v_determine_mem_io_space(struct pci_pbm_info *pbm) | 904 | static void pci_sun4v_determine_mem_io_space(struct pci_pbm_info *pbm) |
903 | { | 905 | { |
904 | int i, saw_mem, saw_io; | 906 | int i, saw_mem, saw_io; |
905 | 907 | ||
906 | saw_mem = saw_io = 0; | 908 | saw_mem = saw_io = 0; |
907 | for (i = 0; i < pbm->num_pbm_ranges; i++) { | 909 | for (i = 0; i < pbm->num_pbm_ranges; i++) { |
908 | struct linux_prom_pci_ranges *pr = &pbm->pbm_ranges[i]; | 910 | struct linux_prom_pci_ranges *pr = &pbm->pbm_ranges[i]; |
909 | unsigned long a; | 911 | unsigned long a; |
910 | int type; | 912 | int type; |
911 | 913 | ||
912 | type = (pr->child_phys_hi >> 24) & 0x3; | 914 | type = (pr->child_phys_hi >> 24) & 0x3; |
913 | a = (((unsigned long)pr->parent_phys_hi << 32UL) | | 915 | a = (((unsigned long)pr->parent_phys_hi << 32UL) | |
914 | ((unsigned long)pr->parent_phys_lo << 0UL)); | 916 | ((unsigned long)pr->parent_phys_lo << 0UL)); |
915 | 917 | ||
916 | switch (type) { | 918 | switch (type) { |
917 | case 1: | 919 | case 1: |
918 | /* 16-bit IO space, 16MB */ | 920 | /* 16-bit IO space, 16MB */ |
919 | pbm->io_space.start = a; | 921 | pbm->io_space.start = a; |
920 | pbm->io_space.end = a + ((16UL*1024UL*1024UL) - 1UL); | 922 | pbm->io_space.end = a + ((16UL*1024UL*1024UL) - 1UL); |
921 | pbm->io_space.flags = IORESOURCE_IO; | 923 | pbm->io_space.flags = IORESOURCE_IO; |
922 | saw_io = 1; | 924 | saw_io = 1; |
923 | break; | 925 | break; |
924 | 926 | ||
925 | case 2: | 927 | case 2: |
926 | /* 32-bit MEM space, 2GB */ | 928 | /* 32-bit MEM space, 2GB */ |
927 | pbm->mem_space.start = a; | 929 | pbm->mem_space.start = a; |
928 | pbm->mem_space.end = a + (0x80000000UL - 1UL); | 930 | pbm->mem_space.end = a + (0x80000000UL - 1UL); |
929 | pbm->mem_space.flags = IORESOURCE_MEM; | 931 | pbm->mem_space.flags = IORESOURCE_MEM; |
930 | saw_mem = 1; | 932 | saw_mem = 1; |
931 | break; | 933 | break; |
932 | 934 | ||
933 | case 3: | 935 | case 3: |
934 | /* XXX 64-bit MEM handling XXX */ | 936 | /* XXX 64-bit MEM handling XXX */ |
935 | 937 | ||
936 | default: | 938 | default: |
937 | break; | 939 | break; |
938 | }; | 940 | }; |
939 | } | 941 | } |
940 | 942 | ||
941 | if (!saw_io || !saw_mem) { | 943 | if (!saw_io || !saw_mem) { |
942 | prom_printf("%s: Fatal error, missing %s PBM range.\n", | 944 | prom_printf("%s: Fatal error, missing %s PBM range.\n", |
943 | pbm->name, | 945 | pbm->name, |
944 | (!saw_io ? "IO" : "MEM")); | 946 | (!saw_io ? "IO" : "MEM")); |
945 | prom_halt(); | 947 | prom_halt(); |
946 | } | 948 | } |
947 | 949 | ||
948 | printk("%s: PCI IO[%lx] MEM[%lx]\n", | 950 | printk("%s: PCI IO[%lx] MEM[%lx]\n", |
949 | pbm->name, | 951 | pbm->name, |
950 | pbm->io_space.start, | 952 | pbm->io_space.start, |
951 | pbm->mem_space.start); | 953 | pbm->mem_space.start); |
952 | } | 954 | } |
953 | 955 | ||
954 | static void pbm_register_toplevel_resources(struct pci_controller_info *p, | 956 | static void pbm_register_toplevel_resources(struct pci_controller_info *p, |
955 | struct pci_pbm_info *pbm) | 957 | struct pci_pbm_info *pbm) |
956 | { | 958 | { |
957 | pbm->io_space.name = pbm->mem_space.name = pbm->name; | 959 | pbm->io_space.name = pbm->mem_space.name = pbm->name; |
958 | 960 | ||
959 | request_resource(&ioport_resource, &pbm->io_space); | 961 | request_resource(&ioport_resource, &pbm->io_space); |
960 | request_resource(&iomem_resource, &pbm->mem_space); | 962 | request_resource(&iomem_resource, &pbm->mem_space); |
961 | pci_register_legacy_regions(&pbm->io_space, | 963 | pci_register_legacy_regions(&pbm->io_space, |
962 | &pbm->mem_space); | 964 | &pbm->mem_space); |
963 | } | 965 | } |
964 | 966 | ||
965 | static unsigned long probe_existing_entries(struct pci_pbm_info *pbm, | 967 | static unsigned long probe_existing_entries(struct pci_pbm_info *pbm, |
966 | struct pci_iommu *iommu) | 968 | struct pci_iommu *iommu) |
967 | { | 969 | { |
968 | struct pci_iommu_arena *arena = &iommu->arena; | 970 | struct pci_iommu_arena *arena = &iommu->arena; |
969 | unsigned long i, cnt = 0; | 971 | unsigned long i, cnt = 0; |
970 | u32 devhandle; | 972 | u32 devhandle; |
971 | 973 | ||
972 | devhandle = pbm->devhandle; | 974 | devhandle = pbm->devhandle; |
973 | for (i = 0; i < arena->limit; i++) { | 975 | for (i = 0; i < arena->limit; i++) { |
974 | unsigned long ret, io_attrs, ra; | 976 | unsigned long ret, io_attrs, ra; |
975 | 977 | ||
976 | ret = pci_sun4v_iommu_getmap(devhandle, | 978 | ret = pci_sun4v_iommu_getmap(devhandle, |
977 | HV_PCI_TSBID(0, i), | 979 | HV_PCI_TSBID(0, i), |
978 | &io_attrs, &ra); | 980 | &io_attrs, &ra); |
979 | if (ret == HV_EOK) { | 981 | if (ret == HV_EOK) { |
980 | if (page_in_phys_avail(ra)) { | 982 | if (page_in_phys_avail(ra)) { |
981 | pci_sun4v_iommu_demap(devhandle, | 983 | pci_sun4v_iommu_demap(devhandle, |
982 | HV_PCI_TSBID(0, i), 1); | 984 | HV_PCI_TSBID(0, i), 1); |
983 | } else { | 985 | } else { |
984 | cnt++; | 986 | cnt++; |
985 | __set_bit(i, arena->map); | 987 | __set_bit(i, arena->map); |
986 | } | 988 | } |
987 | } | 989 | } |
988 | } | 990 | } |
989 | 991 | ||
990 | return cnt; | 992 | return cnt; |
991 | } | 993 | } |
992 | 994 | ||
993 | static void pci_sun4v_iommu_init(struct pci_pbm_info *pbm) | 995 | static void pci_sun4v_iommu_init(struct pci_pbm_info *pbm) |
994 | { | 996 | { |
995 | struct pci_iommu *iommu = pbm->iommu; | 997 | struct pci_iommu *iommu = pbm->iommu; |
996 | struct property *prop; | 998 | struct property *prop; |
997 | unsigned long num_tsb_entries, sz; | 999 | unsigned long num_tsb_entries, sz; |
998 | u32 vdma[2], dma_mask, dma_offset; | 1000 | u32 vdma[2], dma_mask, dma_offset; |
999 | int tsbsize; | 1001 | int tsbsize; |
1000 | 1002 | ||
1001 | prop = of_find_property(pbm->prom_node, "virtual-dma", NULL); | 1003 | prop = of_find_property(pbm->prom_node, "virtual-dma", NULL); |
1002 | if (prop) { | 1004 | if (prop) { |
1003 | u32 *val = prop->value; | 1005 | u32 *val = prop->value; |
1004 | 1006 | ||
1005 | vdma[0] = val[0]; | 1007 | vdma[0] = val[0]; |
1006 | vdma[1] = val[1]; | 1008 | vdma[1] = val[1]; |
1007 | } else { | 1009 | } else { |
1008 | /* No property, use default values. */ | 1010 | /* No property, use default values. */ |
1009 | vdma[0] = 0x80000000; | 1011 | vdma[0] = 0x80000000; |
1010 | vdma[1] = 0x80000000; | 1012 | vdma[1] = 0x80000000; |
1011 | } | 1013 | } |
1012 | 1014 | ||
1013 | dma_mask = vdma[0]; | 1015 | dma_mask = vdma[0]; |
1014 | switch (vdma[1]) { | 1016 | switch (vdma[1]) { |
1015 | case 0x20000000: | 1017 | case 0x20000000: |
1016 | dma_mask |= 0x1fffffff; | 1018 | dma_mask |= 0x1fffffff; |
1017 | tsbsize = 64; | 1019 | tsbsize = 64; |
1018 | break; | 1020 | break; |
1019 | 1021 | ||
1020 | case 0x40000000: | 1022 | case 0x40000000: |
1021 | dma_mask |= 0x3fffffff; | 1023 | dma_mask |= 0x3fffffff; |
1022 | tsbsize = 128; | 1024 | tsbsize = 128; |
1023 | break; | 1025 | break; |
1024 | 1026 | ||
1025 | case 0x80000000: | 1027 | case 0x80000000: |
1026 | dma_mask |= 0x7fffffff; | 1028 | dma_mask |= 0x7fffffff; |
1027 | tsbsize = 256; | 1029 | tsbsize = 256; |
1028 | break; | 1030 | break; |
1029 | 1031 | ||
1030 | default: | 1032 | default: |
1031 | prom_printf("PCI-SUN4V: strange virtual-dma size.\n"); | 1033 | prom_printf("PCI-SUN4V: strange virtual-dma size.\n"); |
1032 | prom_halt(); | 1034 | prom_halt(); |
1033 | }; | 1035 | }; |
1034 | 1036 | ||
1035 | tsbsize *= (8 * 1024); | 1037 | tsbsize *= (8 * 1024); |
1036 | 1038 | ||
1037 | num_tsb_entries = tsbsize / sizeof(iopte_t); | 1039 | num_tsb_entries = tsbsize / sizeof(iopte_t); |
1038 | 1040 | ||
1039 | dma_offset = vdma[0]; | 1041 | dma_offset = vdma[0]; |
1040 | 1042 | ||
1041 | /* Setup initial software IOMMU state. */ | 1043 | /* Setup initial software IOMMU state. */ |
1042 | spin_lock_init(&iommu->lock); | 1044 | spin_lock_init(&iommu->lock); |
1043 | iommu->ctx_lowest_free = 1; | 1045 | iommu->ctx_lowest_free = 1; |
1044 | iommu->page_table_map_base = dma_offset; | 1046 | iommu->page_table_map_base = dma_offset; |
1045 | iommu->dma_addr_mask = dma_mask; | 1047 | iommu->dma_addr_mask = dma_mask; |
1046 | 1048 | ||
1047 | /* Allocate and initialize the free area map. */ | 1049 | /* Allocate and initialize the free area map. */ |
1048 | sz = num_tsb_entries / 8; | 1050 | sz = num_tsb_entries / 8; |
1049 | sz = (sz + 7UL) & ~7UL; | 1051 | sz = (sz + 7UL) & ~7UL; |
1050 | iommu->arena.map = kzalloc(sz, GFP_KERNEL); | 1052 | iommu->arena.map = kzalloc(sz, GFP_KERNEL); |
1051 | if (!iommu->arena.map) { | 1053 | if (!iommu->arena.map) { |
1052 | prom_printf("PCI_IOMMU: Error, kmalloc(arena.map) failed.\n"); | 1054 | prom_printf("PCI_IOMMU: Error, kmalloc(arena.map) failed.\n"); |
1053 | prom_halt(); | 1055 | prom_halt(); |
1054 | } | 1056 | } |
1055 | iommu->arena.limit = num_tsb_entries; | 1057 | iommu->arena.limit = num_tsb_entries; |
1056 | 1058 | ||
1057 | sz = probe_existing_entries(pbm, iommu); | 1059 | sz = probe_existing_entries(pbm, iommu); |
1058 | if (sz) | 1060 | if (sz) |
1059 | printk("%s: Imported %lu TSB entries from OBP\n", | 1061 | printk("%s: Imported %lu TSB entries from OBP\n", |
1060 | pbm->name, sz); | 1062 | pbm->name, sz); |
1061 | } | 1063 | } |
1062 | 1064 | ||
1063 | static void pci_sun4v_get_bus_range(struct pci_pbm_info *pbm) | 1065 | static void pci_sun4v_get_bus_range(struct pci_pbm_info *pbm) |
1064 | { | 1066 | { |
1065 | struct property *prop; | 1067 | struct property *prop; |
1066 | unsigned int *busrange; | 1068 | unsigned int *busrange; |
1067 | 1069 | ||
1068 | prop = of_find_property(pbm->prom_node, "bus-range", NULL); | 1070 | prop = of_find_property(pbm->prom_node, "bus-range", NULL); |
1069 | 1071 | ||
1070 | busrange = prop->value; | 1072 | busrange = prop->value; |
1071 | 1073 | ||
1072 | pbm->pci_first_busno = busrange[0]; | 1074 | pbm->pci_first_busno = busrange[0]; |
1073 | pbm->pci_last_busno = busrange[1]; | 1075 | pbm->pci_last_busno = busrange[1]; |
1074 | 1076 | ||
1075 | } | 1077 | } |
1076 | 1078 | ||
1079 | #ifdef CONFIG_PCI_MSI | ||
1080 | struct pci_sun4v_msiq_entry { | ||
1081 | u64 version_type; | ||
1082 | #define MSIQ_VERSION_MASK 0xffffffff00000000UL | ||
1083 | #define MSIQ_VERSION_SHIFT 32 | ||
1084 | #define MSIQ_TYPE_MASK 0x00000000000000ffUL | ||
1085 | #define MSIQ_TYPE_SHIFT 0 | ||
1086 | #define MSIQ_TYPE_NONE 0x00 | ||
1087 | #define MSIQ_TYPE_MSG 0x01 | ||
1088 | #define MSIQ_TYPE_MSI32 0x02 | ||
1089 | #define MSIQ_TYPE_MSI64 0x03 | ||
1090 | #define MSIQ_TYPE_INTX 0x08 | ||
1091 | #define MSIQ_TYPE_NONE2 0xff | ||
1092 | |||
1093 | u64 intx_sysino; | ||
1094 | u64 reserved1; | ||
1095 | u64 stick; | ||
1096 | u64 req_id; /* bus/device/func */ | ||
1097 | #define MSIQ_REQID_BUS_MASK 0xff00UL | ||
1098 | #define MSIQ_REQID_BUS_SHIFT 8 | ||
1099 | #define MSIQ_REQID_DEVICE_MASK 0x00f8UL | ||
1100 | #define MSIQ_REQID_DEVICE_SHIFT 3 | ||
1101 | #define MSIQ_REQID_FUNC_MASK 0x0007UL | ||
1102 | #define MSIQ_REQID_FUNC_SHIFT 0 | ||
1103 | |||
1104 | u64 msi_address; | ||
1105 | |||
1106 | /* The format of this value is message type dependant. | ||
1107 | * For MSI bits 15:0 are the data from the MSI packet. | ||
1108 | * For MSI-X bits 31:0 are the data from the MSI packet. | ||
1109 | * For MSG, the message code and message routing code where: | ||
1110 | * bits 39:32 is the bus/device/fn of the msg target-id | ||
1111 | * bits 18:16 is the message routing code | ||
1112 | * bits 7:0 is the message code | ||
1113 | * For INTx the low order 2-bits are: | ||
1114 | * 00 - INTA | ||
1115 | * 01 - INTB | ||
1116 | * 10 - INTC | ||
1117 | * 11 - INTD | ||
1118 | */ | ||
1119 | u64 msi_data; | ||
1120 | |||
1121 | u64 reserved2; | ||
1122 | }; | ||
1123 | |||
1124 | /* For now this just runs as a pre-handler for the real interrupt handler. | ||
1125 | * So we just walk through the queue and ACK all the entries, update the | ||
1126 | * head pointer, and return. | ||
1127 | * | ||
1128 | * In the longer term it would be nice to do something more integrated | ||
1129 | * wherein we can pass in some of this MSI info to the drivers. This | ||
1130 | * would be most useful for PCIe fabric error messages, although we could | ||
1131 | * invoke those directly from the loop here in order to pass the info around. | ||
1132 | */ | ||
1133 | static void pci_sun4v_msi_prehandler(unsigned int ino, void *data1, void *data2) | ||
1134 | { | ||
1135 | struct pci_pbm_info *pbm = data1; | ||
1136 | struct pci_sun4v_msiq_entry *base, *ep; | ||
1137 | unsigned long msiqid, orig_head, head, type, err; | ||
1138 | |||
1139 | msiqid = (unsigned long) data2; | ||
1140 | |||
1141 | head = 0xdeadbeef; | ||
1142 | err = pci_sun4v_msiq_gethead(pbm->devhandle, msiqid, &head); | ||
1143 | if (unlikely(err)) | ||
1144 | goto hv_error_get; | ||
1145 | |||
1146 | if (unlikely(head >= (pbm->msiq_ent_count * sizeof(struct pci_sun4v_msiq_entry)))) | ||
1147 | goto bad_offset; | ||
1148 | |||
1149 | head /= sizeof(struct pci_sun4v_msiq_entry); | ||
1150 | orig_head = head; | ||
1151 | base = (pbm->msi_queues + ((msiqid - pbm->msiq_first) * | ||
1152 | (pbm->msiq_ent_count * | ||
1153 | sizeof(struct pci_sun4v_msiq_entry)))); | ||
1154 | ep = &base[head]; | ||
1155 | while ((ep->version_type & MSIQ_TYPE_MASK) != 0) { | ||
1156 | type = (ep->version_type & MSIQ_TYPE_MASK) >> MSIQ_TYPE_SHIFT; | ||
1157 | if (unlikely(type != MSIQ_TYPE_MSI32 && | ||
1158 | type != MSIQ_TYPE_MSI64)) | ||
1159 | goto bad_type; | ||
1160 | |||
1161 | pci_sun4v_msi_setstate(pbm->devhandle, | ||
1162 | ep->msi_data /* msi_num */, | ||
1163 | HV_MSISTATE_IDLE); | ||
1164 | |||
1165 | /* Clear the entry. */ | ||
1166 | ep->version_type &= ~MSIQ_TYPE_MASK; | ||
1167 | |||
1168 | /* Go to next entry in ring. */ | ||
1169 | head++; | ||
1170 | if (head >= pbm->msiq_ent_count) | ||
1171 | head = 0; | ||
1172 | ep = &base[head]; | ||
1173 | } | ||
1174 | |||
1175 | if (likely(head != orig_head)) { | ||
1176 | /* ACK entries by updating head pointer. */ | ||
1177 | head *= sizeof(struct pci_sun4v_msiq_entry); | ||
1178 | err = pci_sun4v_msiq_sethead(pbm->devhandle, msiqid, head); | ||
1179 | if (unlikely(err)) | ||
1180 | goto hv_error_set; | ||
1181 | } | ||
1182 | return; | ||
1183 | |||
1184 | hv_error_set: | ||
1185 | printk(KERN_EMERG "MSI: Hypervisor set head gives error %lu\n", err); | ||
1186 | goto hv_error_cont; | ||
1187 | |||
1188 | hv_error_get: | ||
1189 | printk(KERN_EMERG "MSI: Hypervisor get head gives error %lu\n", err); | ||
1190 | |||
1191 | hv_error_cont: | ||
1192 | printk(KERN_EMERG "MSI: devhandle[%x] msiqid[%lx] head[%lu]\n", | ||
1193 | pbm->devhandle, msiqid, head); | ||
1194 | return; | ||
1195 | |||
1196 | bad_offset: | ||
1197 | printk(KERN_EMERG "MSI: Hypervisor gives bad offset %lx max(%lx)\n", | ||
1198 | head, pbm->msiq_ent_count * sizeof(struct pci_sun4v_msiq_entry)); | ||
1199 | return; | ||
1200 | |||
1201 | bad_type: | ||
1202 | printk(KERN_EMERG "MSI: Entry has bad type %lx\n", type); | ||
1203 | return; | ||
1204 | } | ||
1205 | |||
1206 | static int msi_bitmap_alloc(struct pci_pbm_info *pbm) | ||
1207 | { | ||
1208 | unsigned long size, bits_per_ulong; | ||
1209 | |||
1210 | bits_per_ulong = sizeof(unsigned long) * 8; | ||
1211 | size = (pbm->msi_num + (bits_per_ulong - 1)) & ~(bits_per_ulong - 1); | ||
1212 | size /= 8; | ||
1213 | BUG_ON(size % sizeof(unsigned long)); | ||
1214 | |||
1215 | pbm->msi_bitmap = kzalloc(size, GFP_KERNEL); | ||
1216 | if (!pbm->msi_bitmap) | ||
1217 | return -ENOMEM; | ||
1218 | |||
1219 | return 0; | ||
1220 | } | ||
1221 | |||
1222 | static void msi_bitmap_free(struct pci_pbm_info *pbm) | ||
1223 | { | ||
1224 | kfree(pbm->msi_bitmap); | ||
1225 | pbm->msi_bitmap = NULL; | ||
1226 | } | ||
1227 | |||
1228 | static int msi_queue_alloc(struct pci_pbm_info *pbm) | ||
1229 | { | ||
1230 | unsigned long q_size, alloc_size, pages, order; | ||
1231 | int i; | ||
1232 | |||
1233 | q_size = pbm->msiq_ent_count * sizeof(struct pci_sun4v_msiq_entry); | ||
1234 | alloc_size = (pbm->msiq_num * q_size); | ||
1235 | order = get_order(alloc_size); | ||
1236 | pages = __get_free_pages(GFP_KERNEL | __GFP_COMP, order); | ||
1237 | if (pages == 0UL) { | ||
1238 | printk(KERN_ERR "MSI: Cannot allocate MSI queues (o=%lu).\n", | ||
1239 | order); | ||
1240 | return -ENOMEM; | ||
1241 | } | ||
1242 | memset((char *)pages, 0, PAGE_SIZE << order); | ||
1243 | pbm->msi_queues = (void *) pages; | ||
1244 | |||
1245 | for (i = 0; i < pbm->msiq_num; i++) { | ||
1246 | unsigned long err, base = __pa(pages + (i * q_size)); | ||
1247 | unsigned long ret1, ret2; | ||
1248 | |||
1249 | err = pci_sun4v_msiq_conf(pbm->devhandle, | ||
1250 | pbm->msiq_first + i, | ||
1251 | base, pbm->msiq_ent_count); | ||
1252 | if (err) { | ||
1253 | printk(KERN_ERR "MSI: msiq register fails (err=%lu)\n", | ||
1254 | err); | ||
1255 | goto h_error; | ||
1256 | } | ||
1257 | |||
1258 | err = pci_sun4v_msiq_info(pbm->devhandle, | ||
1259 | pbm->msiq_first + i, | ||
1260 | &ret1, &ret2); | ||
1261 | if (err) { | ||
1262 | printk(KERN_ERR "MSI: Cannot read msiq (err=%lu)\n", | ||
1263 | err); | ||
1264 | goto h_error; | ||
1265 | } | ||
1266 | if (ret1 != base || ret2 != pbm->msiq_ent_count) { | ||
1267 | printk(KERN_ERR "MSI: Bogus qconf " | ||
1268 | "expected[%lx:%x] got[%lx:%lx]\n", | ||
1269 | base, pbm->msiq_ent_count, | ||
1270 | ret1, ret2); | ||
1271 | goto h_error; | ||
1272 | } | ||
1273 | } | ||
1274 | |||
1275 | return 0; | ||
1276 | |||
1277 | h_error: | ||
1278 | free_pages(pages, order); | ||
1279 | return -EINVAL; | ||
1280 | } | ||
1281 | |||
1282 | static void pci_sun4v_msi_init(struct pci_pbm_info *pbm) | ||
1283 | { | ||
1284 | u32 *val; | ||
1285 | int len; | ||
1286 | |||
1287 | val = of_get_property(pbm->prom_node, "#msi-eqs", &len); | ||
1288 | if (!val || len != 4) | ||
1289 | goto no_msi; | ||
1290 | pbm->msiq_num = *val; | ||
1291 | if (pbm->msiq_num) { | ||
1292 | struct msiq_prop { | ||
1293 | u32 first_msiq; | ||
1294 | u32 num_msiq; | ||
1295 | u32 first_devino; | ||
1296 | } *mqp; | ||
1297 | struct msi_range_prop { | ||
1298 | u32 first_msi; | ||
1299 | u32 num_msi; | ||
1300 | } *mrng; | ||
1301 | struct addr_range_prop { | ||
1302 | u32 msi32_high; | ||
1303 | u32 msi32_low; | ||
1304 | u32 msi32_len; | ||
1305 | u32 msi64_high; | ||
1306 | u32 msi64_low; | ||
1307 | u32 msi64_len; | ||
1308 | } *arng; | ||
1309 | |||
1310 | val = of_get_property(pbm->prom_node, "msi-eq-size", &len); | ||
1311 | if (!val || len != 4) | ||
1312 | goto no_msi; | ||
1313 | |||
1314 | pbm->msiq_ent_count = *val; | ||
1315 | |||
1316 | mqp = of_get_property(pbm->prom_node, | ||
1317 | "msi-eq-to-devino", &len); | ||
1318 | if (!mqp || len != sizeof(struct msiq_prop)) | ||
1319 | goto no_msi; | ||
1320 | |||
1321 | pbm->msiq_first = mqp->first_msiq; | ||
1322 | pbm->msiq_first_devino = mqp->first_devino; | ||
1323 | |||
1324 | val = of_get_property(pbm->prom_node, "#msi", &len); | ||
1325 | if (!val || len != 4) | ||
1326 | goto no_msi; | ||
1327 | pbm->msi_num = *val; | ||
1328 | |||
1329 | mrng = of_get_property(pbm->prom_node, "msi-ranges", &len); | ||
1330 | if (!mrng || len != sizeof(struct msi_range_prop)) | ||
1331 | goto no_msi; | ||
1332 | pbm->msi_first = mrng->first_msi; | ||
1333 | |||
1334 | val = of_get_property(pbm->prom_node, "msi-data-mask", &len); | ||
1335 | if (!val || len != 4) | ||
1336 | goto no_msi; | ||
1337 | pbm->msi_data_mask = *val; | ||
1338 | |||
1339 | val = of_get_property(pbm->prom_node, "msix-data-width", &len); | ||
1340 | if (!val || len != 4) | ||
1341 | goto no_msi; | ||
1342 | pbm->msix_data_width = *val; | ||
1343 | |||
1344 | arng = of_get_property(pbm->prom_node, "msi-address-ranges", | ||
1345 | &len); | ||
1346 | if (!arng || len != sizeof(struct addr_range_prop)) | ||
1347 | goto no_msi; | ||
1348 | pbm->msi32_start = ((u64)arng->msi32_high << 32) | | ||
1349 | (u64) arng->msi32_low; | ||
1350 | pbm->msi64_start = ((u64)arng->msi64_high << 32) | | ||
1351 | (u64) arng->msi64_low; | ||
1352 | pbm->msi32_len = arng->msi32_len; | ||
1353 | pbm->msi64_len = arng->msi64_len; | ||
1354 | |||
1355 | if (msi_bitmap_alloc(pbm)) | ||
1356 | goto no_msi; | ||
1357 | |||
1358 | if (msi_queue_alloc(pbm)) { | ||
1359 | msi_bitmap_free(pbm); | ||
1360 | goto no_msi; | ||
1361 | } | ||
1362 | |||
1363 | printk(KERN_INFO "%s: MSI Queue first[%u] num[%u] count[%u] " | ||
1364 | "devino[0x%x]\n", | ||
1365 | pbm->name, | ||
1366 | pbm->msiq_first, pbm->msiq_num, | ||
1367 | pbm->msiq_ent_count, | ||
1368 | pbm->msiq_first_devino); | ||
1369 | printk(KERN_INFO "%s: MSI first[%u] num[%u] mask[0x%x] " | ||
1370 | "width[%u]\n", | ||
1371 | pbm->name, | ||
1372 | pbm->msi_first, pbm->msi_num, pbm->msi_data_mask, | ||
1373 | pbm->msix_data_width); | ||
1374 | printk(KERN_INFO "%s: MSI addr32[0x%lx:0x%x] " | ||
1375 | "addr64[0x%lx:0x%x]\n", | ||
1376 | pbm->name, | ||
1377 | pbm->msi32_start, pbm->msi32_len, | ||
1378 | pbm->msi64_start, pbm->msi64_len); | ||
1379 | printk(KERN_INFO "%s: MSI queues at RA [%p]\n", | ||
1380 | pbm->name, | ||
1381 | pbm->msi_queues); | ||
1382 | } | ||
1383 | |||
1384 | return; | ||
1385 | |||
1386 | no_msi: | ||
1387 | pbm->msiq_num = 0; | ||
1388 | printk(KERN_INFO "%s: No MSI support.\n", pbm->name); | ||
1389 | } | ||
1390 | |||
1391 | static int alloc_msi(struct pci_pbm_info *pbm) | ||
1392 | { | ||
1393 | int i; | ||
1394 | |||
1395 | for (i = 0; i < pbm->msi_num; i++) { | ||
1396 | if (!test_and_set_bit(i, pbm->msi_bitmap)) | ||
1397 | return i + pbm->msi_first; | ||
1398 | } | ||
1399 | |||
1400 | return -ENOENT; | ||
1401 | } | ||
1402 | |||
1403 | static void free_msi(struct pci_pbm_info *pbm, int msi_num) | ||
1404 | { | ||
1405 | msi_num -= pbm->msi_first; | ||
1406 | clear_bit(msi_num, pbm->msi_bitmap); | ||
1407 | } | ||
1408 | |||
1409 | static int pci_sun4v_setup_msi_irq(unsigned int *virt_irq_p, | ||
1410 | struct pci_dev *pdev, | ||
1411 | struct msi_desc *entry) | ||
1412 | { | ||
1413 | struct pcidev_cookie *pcp = pdev->sysdata; | ||
1414 | struct pci_pbm_info *pbm = pcp->pbm; | ||
1415 | unsigned long devino, msiqid; | ||
1416 | struct msi_msg msg; | ||
1417 | int msi_num, err; | ||
1418 | |||
1419 | *virt_irq_p = 0; | ||
1420 | |||
1421 | msi_num = alloc_msi(pbm); | ||
1422 | if (msi_num < 0) | ||
1423 | return msi_num; | ||
1424 | |||
1425 | devino = sun4v_build_msi(pbm->devhandle, virt_irq_p, | ||
1426 | pbm->msiq_first_devino, | ||
1427 | (pbm->msiq_first_devino + | ||
1428 | pbm->msiq_num)); | ||
1429 | err = -ENOMEM; | ||
1430 | if (!devino) | ||
1431 | goto out_err; | ||
1432 | |||
1433 | set_irq_msi(*virt_irq_p, entry); | ||
1434 | |||
1435 | msiqid = ((devino - pbm->msiq_first_devino) + | ||
1436 | pbm->msiq_first); | ||
1437 | |||
1438 | err = -EINVAL; | ||
1439 | if (pci_sun4v_msiq_setstate(pbm->devhandle, msiqid, HV_MSIQSTATE_IDLE)) | ||
1440 | if (err) | ||
1441 | goto out_err; | ||
1442 | |||
1443 | if (pci_sun4v_msiq_setvalid(pbm->devhandle, msiqid, HV_MSIQ_VALID)) | ||
1444 | goto out_err; | ||
1445 | |||
1446 | if (pci_sun4v_msi_setmsiq(pbm->devhandle, | ||
1447 | msi_num, msiqid, | ||
1448 | (entry->msi_attrib.is_64 ? | ||
1449 | HV_MSITYPE_MSI64 : HV_MSITYPE_MSI32))) | ||
1450 | goto out_err; | ||
1451 | |||
1452 | if (pci_sun4v_msi_setstate(pbm->devhandle, msi_num, HV_MSISTATE_IDLE)) | ||
1453 | goto out_err; | ||
1454 | |||
1455 | if (pci_sun4v_msi_setvalid(pbm->devhandle, msi_num, HV_MSIVALID_VALID)) | ||
1456 | goto out_err; | ||
1457 | |||
1458 | pcp->msi_num = msi_num; | ||
1459 | |||
1460 | if (entry->msi_attrib.is_64) { | ||
1461 | msg.address_hi = pbm->msi64_start >> 32; | ||
1462 | msg.address_lo = pbm->msi64_start & 0xffffffff; | ||
1463 | } else { | ||
1464 | msg.address_hi = 0; | ||
1465 | msg.address_lo = pbm->msi32_start; | ||
1466 | } | ||
1467 | msg.data = msi_num; | ||
1468 | write_msi_msg(*virt_irq_p, &msg); | ||
1469 | |||
1470 | irq_install_pre_handler(*virt_irq_p, | ||
1471 | pci_sun4v_msi_prehandler, | ||
1472 | pbm, (void *) msiqid); | ||
1473 | |||
1474 | return 0; | ||
1475 | |||
1476 | out_err: | ||
1477 | free_msi(pbm, msi_num); | ||
1478 | sun4v_destroy_msi(*virt_irq_p); | ||
1479 | *virt_irq_p = 0; | ||
1480 | return err; | ||
1481 | |||
1482 | } | ||
1483 | |||
1484 | static void pci_sun4v_teardown_msi_irq(unsigned int virt_irq, | ||
1485 | struct pci_dev *pdev) | ||
1486 | { | ||
1487 | struct pcidev_cookie *pcp = pdev->sysdata; | ||
1488 | struct pci_pbm_info *pbm = pcp->pbm; | ||
1489 | unsigned long msiqid, err; | ||
1490 | unsigned int msi_num; | ||
1491 | |||
1492 | msi_num = pcp->msi_num; | ||
1493 | err = pci_sun4v_msi_getmsiq(pbm->devhandle, msi_num, &msiqid); | ||
1494 | if (err) { | ||
1495 | printk(KERN_ERR "%s: getmsiq gives error %lu\n", | ||
1496 | pbm->name, err); | ||
1497 | return; | ||
1498 | } | ||
1499 | |||
1500 | pci_sun4v_msi_setvalid(pbm->devhandle, msi_num, HV_MSIVALID_INVALID); | ||
1501 | pci_sun4v_msiq_setvalid(pbm->devhandle, msiqid, HV_MSIQ_INVALID); | ||
1502 | |||
1503 | free_msi(pbm, msi_num); | ||
1504 | |||
1505 | /* The sun4v_destroy_msi() will liberate the devino and thus the MSIQ | ||
1506 | * allocation. | ||
1507 | */ | ||
1508 | sun4v_destroy_msi(virt_irq); | ||
1509 | } | ||
1510 | #else /* CONFIG_PCI_MSI */ | ||
1511 | static void pci_sun4v_msi_init(struct pci_pbm_info *pbm) | ||
1512 | { | ||
1513 | } | ||
1514 | #endif /* !(CONFIG_PCI_MSI) */ | ||
1515 | |||
1077 | static void pci_sun4v_pbm_init(struct pci_controller_info *p, struct device_node *dp, u32 devhandle) | 1516 | static void pci_sun4v_pbm_init(struct pci_controller_info *p, struct device_node *dp, u32 devhandle) |
1078 | { | 1517 | { |
1079 | struct pci_pbm_info *pbm; | 1518 | struct pci_pbm_info *pbm; |
1080 | struct property *prop; | 1519 | struct property *prop; |
1081 | int len, i; | 1520 | int len, i; |
1082 | 1521 | ||
1083 | if (devhandle & 0x40) | 1522 | if (devhandle & 0x40) |
1084 | pbm = &p->pbm_B; | 1523 | pbm = &p->pbm_B; |
1085 | else | 1524 | else |
1086 | pbm = &p->pbm_A; | 1525 | pbm = &p->pbm_A; |
1087 | 1526 | ||
1088 | pbm->parent = p; | 1527 | pbm->parent = p; |
1089 | pbm->prom_node = dp; | 1528 | pbm->prom_node = dp; |
1090 | pbm->pci_first_slot = 1; | 1529 | pbm->pci_first_slot = 1; |
1091 | 1530 | ||
1092 | pbm->devhandle = devhandle; | 1531 | pbm->devhandle = devhandle; |
1093 | 1532 | ||
1094 | pbm->name = dp->full_name; | 1533 | pbm->name = dp->full_name; |
1095 | 1534 | ||
1096 | printk("%s: SUN4V PCI Bus Module\n", pbm->name); | 1535 | printk("%s: SUN4V PCI Bus Module\n", pbm->name); |
1097 | 1536 | ||
1098 | prop = of_find_property(dp, "ranges", &len); | 1537 | prop = of_find_property(dp, "ranges", &len); |
1099 | pbm->pbm_ranges = prop->value; | 1538 | pbm->pbm_ranges = prop->value; |
1100 | pbm->num_pbm_ranges = | 1539 | pbm->num_pbm_ranges = |
1101 | (len / sizeof(struct linux_prom_pci_ranges)); | 1540 | (len / sizeof(struct linux_prom_pci_ranges)); |
1102 | 1541 | ||
1103 | /* Mask out the top 8 bits of the ranges, leaving the real | 1542 | /* Mask out the top 8 bits of the ranges, leaving the real |
1104 | * physical address. | 1543 | * physical address. |
1105 | */ | 1544 | */ |
1106 | for (i = 0; i < pbm->num_pbm_ranges; i++) | 1545 | for (i = 0; i < pbm->num_pbm_ranges; i++) |
1107 | pbm->pbm_ranges[i].parent_phys_hi &= 0x0fffffff; | 1546 | pbm->pbm_ranges[i].parent_phys_hi &= 0x0fffffff; |
1108 | 1547 | ||
1109 | pci_sun4v_determine_mem_io_space(pbm); | 1548 | pci_sun4v_determine_mem_io_space(pbm); |
1110 | pbm_register_toplevel_resources(p, pbm); | 1549 | pbm_register_toplevel_resources(p, pbm); |
1111 | 1550 | ||
1112 | prop = of_find_property(dp, "interrupt-map", &len); | 1551 | prop = of_find_property(dp, "interrupt-map", &len); |
1113 | pbm->pbm_intmap = prop->value; | 1552 | pbm->pbm_intmap = prop->value; |
1114 | pbm->num_pbm_intmap = | 1553 | pbm->num_pbm_intmap = |
1115 | (len / sizeof(struct linux_prom_pci_intmap)); | 1554 | (len / sizeof(struct linux_prom_pci_intmap)); |
1116 | 1555 | ||
1117 | prop = of_find_property(dp, "interrupt-map-mask", NULL); | 1556 | prop = of_find_property(dp, "interrupt-map-mask", NULL); |
1118 | pbm->pbm_intmask = prop->value; | 1557 | pbm->pbm_intmask = prop->value; |
1119 | 1558 | ||
1120 | pci_sun4v_get_bus_range(pbm); | 1559 | pci_sun4v_get_bus_range(pbm); |
1121 | pci_sun4v_iommu_init(pbm); | 1560 | pci_sun4v_iommu_init(pbm); |
1561 | pci_sun4v_msi_init(pbm); | ||
1122 | 1562 | ||
1123 | pdev_htab_populate(pbm); | 1563 | pdev_htab_populate(pbm); |
1124 | } | 1564 | } |
1125 | 1565 | ||
1126 | void sun4v_pci_init(struct device_node *dp, char *model_name) | 1566 | void sun4v_pci_init(struct device_node *dp, char *model_name) |
1127 | { | 1567 | { |
1128 | struct pci_controller_info *p; | 1568 | struct pci_controller_info *p; |
1129 | struct pci_iommu *iommu; | 1569 | struct pci_iommu *iommu; |
1130 | struct property *prop; | 1570 | struct property *prop; |
1131 | struct linux_prom64_registers *regs; | 1571 | struct linux_prom64_registers *regs; |
1132 | u32 devhandle; | 1572 | u32 devhandle; |
1133 | int i; | 1573 | int i; |
1134 | 1574 | ||
1135 | prop = of_find_property(dp, "reg", NULL); | 1575 | prop = of_find_property(dp, "reg", NULL); |
1136 | regs = prop->value; | 1576 | regs = prop->value; |
1137 | 1577 | ||
1138 | devhandle = (regs->phys_addr >> 32UL) & 0x0fffffff; | 1578 | devhandle = (regs->phys_addr >> 32UL) & 0x0fffffff; |
1139 | 1579 | ||
1140 | for (p = pci_controller_root; p; p = p->next) { | 1580 | for (p = pci_controller_root; p; p = p->next) { |
1141 | struct pci_pbm_info *pbm; | 1581 | struct pci_pbm_info *pbm; |
1142 | 1582 | ||
1143 | if (p->pbm_A.prom_node && p->pbm_B.prom_node) | 1583 | if (p->pbm_A.prom_node && p->pbm_B.prom_node) |
1144 | continue; | 1584 | continue; |
1145 | 1585 | ||
1146 | pbm = (p->pbm_A.prom_node ? | 1586 | pbm = (p->pbm_A.prom_node ? |
1147 | &p->pbm_A : | 1587 | &p->pbm_A : |
1148 | &p->pbm_B); | 1588 | &p->pbm_B); |
1149 | 1589 | ||
1150 | if (pbm->devhandle == (devhandle ^ 0x40)) { | 1590 | if (pbm->devhandle == (devhandle ^ 0x40)) { |
1151 | pci_sun4v_pbm_init(p, dp, devhandle); | 1591 | pci_sun4v_pbm_init(p, dp, devhandle); |
1152 | return; | 1592 | return; |
1153 | } | 1593 | } |
1154 | } | 1594 | } |
1155 | 1595 | ||
1156 | for_each_possible_cpu(i) { | 1596 | for_each_possible_cpu(i) { |
1157 | unsigned long page = get_zeroed_page(GFP_ATOMIC); | 1597 | unsigned long page = get_zeroed_page(GFP_ATOMIC); |
1158 | 1598 | ||
1159 | if (!page) | 1599 | if (!page) |
1160 | goto fatal_memory_error; | 1600 | goto fatal_memory_error; |
1161 | 1601 | ||
1162 | per_cpu(pci_iommu_batch, i).pglist = (u64 *) page; | 1602 | per_cpu(pci_iommu_batch, i).pglist = (u64 *) page; |
1163 | } | 1603 | } |
1164 | 1604 | ||
1165 | p = kzalloc(sizeof(struct pci_controller_info), GFP_ATOMIC); | 1605 | p = kzalloc(sizeof(struct pci_controller_info), GFP_ATOMIC); |
1166 | if (!p) | 1606 | if (!p) |
1167 | goto fatal_memory_error; | 1607 | goto fatal_memory_error; |
1168 | 1608 | ||
1169 | iommu = kzalloc(sizeof(struct pci_iommu), GFP_ATOMIC); | 1609 | iommu = kzalloc(sizeof(struct pci_iommu), GFP_ATOMIC); |
1170 | if (!iommu) | 1610 | if (!iommu) |
1171 | goto fatal_memory_error; | 1611 | goto fatal_memory_error; |
1172 | 1612 | ||
1173 | p->pbm_A.iommu = iommu; | 1613 | p->pbm_A.iommu = iommu; |
1174 | 1614 | ||
1175 | iommu = kzalloc(sizeof(struct pci_iommu), GFP_ATOMIC); | 1615 | iommu = kzalloc(sizeof(struct pci_iommu), GFP_ATOMIC); |
1176 | if (!iommu) | 1616 | if (!iommu) |
1177 | goto fatal_memory_error; | 1617 | goto fatal_memory_error; |
1178 | 1618 | ||
1179 | p->pbm_B.iommu = iommu; | 1619 | p->pbm_B.iommu = iommu; |
1180 | 1620 | ||
1181 | p->next = pci_controller_root; | 1621 | p->next = pci_controller_root; |
1182 | pci_controller_root = p; | 1622 | pci_controller_root = p; |
1183 | 1623 | ||
1184 | p->index = pci_num_controllers++; | 1624 | p->index = pci_num_controllers++; |
1185 | p->pbms_same_domain = 0; | 1625 | p->pbms_same_domain = 0; |
1186 | 1626 | ||
1187 | p->scan_bus = pci_sun4v_scan_bus; | 1627 | p->scan_bus = pci_sun4v_scan_bus; |
1188 | p->base_address_update = pci_sun4v_base_address_update; | 1628 | p->base_address_update = pci_sun4v_base_address_update; |
1189 | p->resource_adjust = pci_sun4v_resource_adjust; | 1629 | p->resource_adjust = pci_sun4v_resource_adjust; |
1630 | #ifdef CONFIG_PCI_MSI | ||
1631 | p->setup_msi_irq = pci_sun4v_setup_msi_irq; | ||
1632 | p->teardown_msi_irq = pci_sun4v_teardown_msi_irq; | ||
1633 | #endif | ||
1190 | p->pci_ops = &pci_sun4v_ops; | 1634 | p->pci_ops = &pci_sun4v_ops; |
1191 | 1635 | ||
1192 | /* Like PSYCHO and SCHIZO we have a 2GB aligned area | 1636 | /* Like PSYCHO and SCHIZO we have a 2GB aligned area |
1193 | * for memory space. | 1637 | * for memory space. |
1194 | */ | 1638 | */ |
1195 | pci_memspace_mask = 0x7fffffffUL; | 1639 | pci_memspace_mask = 0x7fffffffUL; |
1196 | 1640 | ||
1197 | pci_sun4v_pbm_init(p, dp, devhandle); | 1641 | pci_sun4v_pbm_init(p, dp, devhandle); |
1198 | return; | 1642 | return; |
1199 | 1643 | ||
1200 | fatal_memory_error: | 1644 | fatal_memory_error: |
1201 | prom_printf("SUN4V_PCI: Fatal memory allocation error.\n"); | 1645 | prom_printf("SUN4V_PCI: Fatal memory allocation error.\n"); |
1202 | prom_halt(); | 1646 | prom_halt(); |
1203 | } | 1647 | } |
1204 | 1648 |
arch/sparc64/kernel/pci_sun4v.h
1 | /* pci_sun4v.h: SUN4V specific PCI controller support. | 1 | /* pci_sun4v.h: SUN4V specific PCI controller support. |
2 | * | 2 | * |
3 | * Copyright (C) 2006 David S. Miller (davem@davemloft.net) | 3 | * Copyright (C) 2006 David S. Miller (davem@davemloft.net) |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #ifndef _PCI_SUN4V_H | 6 | #ifndef _PCI_SUN4V_H |
7 | #define _PCI_SUN4V_H | 7 | #define _PCI_SUN4V_H |
8 | 8 | ||
9 | extern long pci_sun4v_iommu_map(unsigned long devhandle, | 9 | extern long pci_sun4v_iommu_map(unsigned long devhandle, |
10 | unsigned long tsbid, | 10 | unsigned long tsbid, |
11 | unsigned long num_ttes, | 11 | unsigned long num_ttes, |
12 | unsigned long io_attributes, | 12 | unsigned long io_attributes, |
13 | unsigned long io_page_list_pa); | 13 | unsigned long io_page_list_pa); |
14 | extern unsigned long pci_sun4v_iommu_demap(unsigned long devhandle, | 14 | extern unsigned long pci_sun4v_iommu_demap(unsigned long devhandle, |
15 | unsigned long tsbid, | 15 | unsigned long tsbid, |
16 | unsigned long num_ttes); | 16 | unsigned long num_ttes); |
17 | extern unsigned long pci_sun4v_iommu_getmap(unsigned long devhandle, | 17 | extern unsigned long pci_sun4v_iommu_getmap(unsigned long devhandle, |
18 | unsigned long tsbid, | 18 | unsigned long tsbid, |
19 | unsigned long *io_attributes, | 19 | unsigned long *io_attributes, |
20 | unsigned long *real_address); | 20 | unsigned long *real_address); |
21 | extern unsigned long pci_sun4v_config_get(unsigned long devhandle, | 21 | extern unsigned long pci_sun4v_config_get(unsigned long devhandle, |
22 | unsigned long pci_device, | 22 | unsigned long pci_device, |
23 | unsigned long config_offset, | 23 | unsigned long config_offset, |
24 | unsigned long size); | 24 | unsigned long size); |
25 | extern int pci_sun4v_config_put(unsigned long devhandle, | 25 | extern int pci_sun4v_config_put(unsigned long devhandle, |
26 | unsigned long pci_device, | 26 | unsigned long pci_device, |
27 | unsigned long config_offset, | 27 | unsigned long config_offset, |
28 | unsigned long size, | 28 | unsigned long size, |
29 | unsigned long data); | 29 | unsigned long data); |
30 | 30 | ||
31 | extern unsigned long pci_sun4v_msiq_conf(unsigned long devhandle, | ||
32 | unsigned long msiqid, | ||
33 | unsigned long msiq_paddr, | ||
34 | unsigned long num_entries); | ||
35 | extern unsigned long pci_sun4v_msiq_info(unsigned long devhandle, | ||
36 | unsigned long msiqid, | ||
37 | unsigned long *msiq_paddr, | ||
38 | unsigned long *num_entries); | ||
39 | extern unsigned long pci_sun4v_msiq_getvalid(unsigned long devhandle, | ||
40 | unsigned long msiqid, | ||
41 | unsigned long *valid); | ||
42 | extern unsigned long pci_sun4v_msiq_setvalid(unsigned long devhandle, | ||
43 | unsigned long msiqid, | ||
44 | unsigned long valid); | ||
45 | extern unsigned long pci_sun4v_msiq_getstate(unsigned long devhandle, | ||
46 | unsigned long msiqid, | ||
47 | unsigned long *state); | ||
48 | extern unsigned long pci_sun4v_msiq_setstate(unsigned long devhandle, | ||
49 | unsigned long msiqid, | ||
50 | unsigned long state); | ||
51 | extern unsigned long pci_sun4v_msiq_gethead(unsigned long devhandle, | ||
52 | unsigned long msiqid, | ||
53 | unsigned long *head); | ||
54 | extern unsigned long pci_sun4v_msiq_sethead(unsigned long devhandle, | ||
55 | unsigned long msiqid, | ||
56 | unsigned long head); | ||
57 | extern unsigned long pci_sun4v_msiq_gettail(unsigned long devhandle, | ||
58 | unsigned long msiqid, | ||
59 | unsigned long *head); | ||
60 | extern unsigned long pci_sun4v_msi_getvalid(unsigned long devhandle, | ||
61 | unsigned long msinum, | ||
62 | unsigned long *valid); | ||
63 | extern unsigned long pci_sun4v_msi_setvalid(unsigned long devhandle, | ||
64 | unsigned long msinum, | ||
65 | unsigned long valid); | ||
66 | extern unsigned long pci_sun4v_msi_getmsiq(unsigned long devhandle, | ||
67 | unsigned long msinum, | ||
68 | unsigned long *msiq); | ||
69 | extern unsigned long pci_sun4v_msi_setmsiq(unsigned long devhandle, | ||
70 | unsigned long msinum, | ||
71 | unsigned long msiq, | ||
72 | unsigned long msitype); | ||
73 | extern unsigned long pci_sun4v_msi_getstate(unsigned long devhandle, | ||
74 | unsigned long msinum, | ||
75 | unsigned long *state); | ||
76 | extern unsigned long pci_sun4v_msi_setstate(unsigned long devhandle, | ||
77 | unsigned long msinum, | ||
78 | unsigned long state); | ||
79 | extern unsigned long pci_sun4v_msg_getmsiq(unsigned long devhandle, | ||
80 | unsigned long msinum, | ||
81 | unsigned long *msiq); | ||
82 | extern unsigned long pci_sun4v_msg_setmsiq(unsigned long devhandle, | ||
83 | unsigned long msinum, | ||
84 | unsigned long msiq); | ||
85 | extern unsigned long pci_sun4v_msg_getvalid(unsigned long devhandle, | ||
86 | unsigned long msinum, | ||
87 | unsigned long *valid); | ||
88 | extern unsigned long pci_sun4v_msg_setvalid(unsigned long devhandle, | ||
89 | unsigned long msinum, | ||
90 | unsigned long valid); | ||
91 | |||
31 | #endif /* !(_PCI_SUN4V_H) */ | 92 | #endif /* !(_PCI_SUN4V_H) */ |
32 | 93 |
arch/sparc64/kernel/pci_sun4v_asm.S
1 | /* pci_sun4v_asm: Hypervisor calls for PCI support. | 1 | /* pci_sun4v_asm: Hypervisor calls for PCI support. |
2 | * | 2 | * |
3 | * Copyright (C) 2006 David S. Miller <davem@davemloft.net> | 3 | * Copyright (C) 2006 David S. Miller <davem@davemloft.net> |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include <asm/hypervisor.h> | 6 | #include <asm/hypervisor.h> |
7 | 7 | ||
8 | /* %o0: devhandle | 8 | /* %o0: devhandle |
9 | * %o1: tsbid | 9 | * %o1: tsbid |
10 | * %o2: num ttes | 10 | * %o2: num ttes |
11 | * %o3: io_attributes | 11 | * %o3: io_attributes |
12 | * %o4: io_page_list phys address | 12 | * %o4: io_page_list phys address |
13 | * | 13 | * |
14 | * returns %o0: -status if status was non-zero, else | 14 | * returns %o0: -status if status was non-zero, else |
15 | * %o0: num pages mapped | 15 | * %o0: num pages mapped |
16 | */ | 16 | */ |
17 | .globl pci_sun4v_iommu_map | 17 | .globl pci_sun4v_iommu_map |
18 | pci_sun4v_iommu_map: | 18 | pci_sun4v_iommu_map: |
19 | mov %o5, %g1 | 19 | mov %o5, %g1 |
20 | mov HV_FAST_PCI_IOMMU_MAP, %o5 | 20 | mov HV_FAST_PCI_IOMMU_MAP, %o5 |
21 | ta HV_FAST_TRAP | 21 | ta HV_FAST_TRAP |
22 | brnz,pn %o0, 1f | 22 | brnz,pn %o0, 1f |
23 | sub %g0, %o0, %o0 | 23 | sub %g0, %o0, %o0 |
24 | mov %o1, %o0 | 24 | mov %o1, %o0 |
25 | 1: retl | 25 | 1: retl |
26 | nop | 26 | nop |
27 | 27 | ||
28 | /* %o0: devhandle | 28 | /* %o0: devhandle |
29 | * %o1: tsbid | 29 | * %o1: tsbid |
30 | * %o2: num ttes | 30 | * %o2: num ttes |
31 | * | 31 | * |
32 | * returns %o0: num ttes demapped | 32 | * returns %o0: num ttes demapped |
33 | */ | 33 | */ |
34 | .globl pci_sun4v_iommu_demap | 34 | .globl pci_sun4v_iommu_demap |
35 | pci_sun4v_iommu_demap: | 35 | pci_sun4v_iommu_demap: |
36 | mov HV_FAST_PCI_IOMMU_DEMAP, %o5 | 36 | mov HV_FAST_PCI_IOMMU_DEMAP, %o5 |
37 | ta HV_FAST_TRAP | 37 | ta HV_FAST_TRAP |
38 | retl | 38 | retl |
39 | mov %o1, %o0 | 39 | mov %o1, %o0 |
40 | 40 | ||
41 | /* %o0: devhandle | 41 | /* %o0: devhandle |
42 | * %o1: tsbid | 42 | * %o1: tsbid |
43 | * %o2: &io_attributes | 43 | * %o2: &io_attributes |
44 | * %o3: &real_address | 44 | * %o3: &real_address |
45 | * | 45 | * |
46 | * returns %o0: status | 46 | * returns %o0: status |
47 | */ | 47 | */ |
48 | .globl pci_sun4v_iommu_getmap | 48 | .globl pci_sun4v_iommu_getmap |
49 | pci_sun4v_iommu_getmap: | 49 | pci_sun4v_iommu_getmap: |
50 | mov %o2, %o4 | 50 | mov %o2, %o4 |
51 | mov HV_FAST_PCI_IOMMU_GETMAP, %o5 | 51 | mov HV_FAST_PCI_IOMMU_GETMAP, %o5 |
52 | ta HV_FAST_TRAP | 52 | ta HV_FAST_TRAP |
53 | stx %o1, [%o4] | 53 | stx %o1, [%o4] |
54 | stx %o2, [%o3] | 54 | stx %o2, [%o3] |
55 | retl | 55 | retl |
56 | mov %o0, %o0 | 56 | mov %o0, %o0 |
57 | 57 | ||
58 | /* %o0: devhandle | 58 | /* %o0: devhandle |
59 | * %o1: pci_device | 59 | * %o1: pci_device |
60 | * %o2: pci_config_offset | 60 | * %o2: pci_config_offset |
61 | * %o3: size | 61 | * %o3: size |
62 | * | 62 | * |
63 | * returns %o0: data | 63 | * returns %o0: data |
64 | * | 64 | * |
65 | * If there is an error, the data will be returned | 65 | * If there is an error, the data will be returned |
66 | * as all 1's. | 66 | * as all 1's. |
67 | */ | 67 | */ |
68 | .globl pci_sun4v_config_get | 68 | .globl pci_sun4v_config_get |
69 | pci_sun4v_config_get: | 69 | pci_sun4v_config_get: |
70 | mov HV_FAST_PCI_CONFIG_GET, %o5 | 70 | mov HV_FAST_PCI_CONFIG_GET, %o5 |
71 | ta HV_FAST_TRAP | 71 | ta HV_FAST_TRAP |
72 | brnz,a,pn %o1, 1f | 72 | brnz,a,pn %o1, 1f |
73 | mov -1, %o2 | 73 | mov -1, %o2 |
74 | 1: retl | 74 | 1: retl |
75 | mov %o2, %o0 | 75 | mov %o2, %o0 |
76 | 76 | ||
77 | /* %o0: devhandle | 77 | /* %o0: devhandle |
78 | * %o1: pci_device | 78 | * %o1: pci_device |
79 | * %o2: pci_config_offset | 79 | * %o2: pci_config_offset |
80 | * %o3: size | 80 | * %o3: size |
81 | * %o4: data | 81 | * %o4: data |
82 | * | 82 | * |
83 | * returns %o0: status | 83 | * returns %o0: status |
84 | * | 84 | * |
85 | * status will be zero if the operation completed | 85 | * status will be zero if the operation completed |
86 | * successfully, else -1 if not | 86 | * successfully, else -1 if not |
87 | */ | 87 | */ |
88 | .globl pci_sun4v_config_put | 88 | .globl pci_sun4v_config_put |
89 | pci_sun4v_config_put: | 89 | pci_sun4v_config_put: |
90 | mov HV_FAST_PCI_CONFIG_PUT, %o5 | 90 | mov HV_FAST_PCI_CONFIG_PUT, %o5 |
91 | ta HV_FAST_TRAP | 91 | ta HV_FAST_TRAP |
92 | brnz,a,pn %o1, 1f | 92 | brnz,a,pn %o1, 1f |
93 | mov -1, %o1 | 93 | mov -1, %o1 |
94 | 1: retl | 94 | 1: retl |
95 | mov %o1, %o0 | 95 | mov %o1, %o0 |
96 | |||
97 | /* %o0: devhandle | ||
98 | * %o1: msiqid | ||
99 | * %o2: msiq phys address | ||
100 | * %o3: num entries | ||
101 | * | ||
102 | * returns %o0: status | ||
103 | * | ||
104 | * status will be zero if the operation completed | ||
105 | * successfully, else -1 if not | ||
106 | */ | ||
107 | .globl pci_sun4v_msiq_conf | ||
108 | pci_sun4v_msiq_conf: | ||
109 | mov HV_FAST_PCI_MSIQ_CONF, %o5 | ||
110 | ta HV_FAST_TRAP | ||
111 | retl | ||
112 | mov %o0, %o0 | ||
113 | |||
114 | /* %o0: devhandle | ||
115 | * %o1: msiqid | ||
116 | * %o2: &msiq_phys_addr | ||
117 | * %o3: &msiq_num_entries | ||
118 | * | ||
119 | * returns %o0: status | ||
120 | */ | ||
121 | .globl pci_sun4v_msiq_info | ||
122 | pci_sun4v_msiq_info: | ||
123 | mov %o2, %o4 | ||
124 | mov HV_FAST_PCI_MSIQ_INFO, %o5 | ||
125 | ta HV_FAST_TRAP | ||
126 | stx %o1, [%o4] | ||
127 | stx %o2, [%o3] | ||
128 | retl | ||
129 | mov %o0, %o0 | ||
130 | |||
131 | /* %o0: devhandle | ||
132 | * %o1: msiqid | ||
133 | * %o2: &valid | ||
134 | * | ||
135 | * returns %o0: status | ||
136 | */ | ||
137 | .globl pci_sun4v_msiq_getvalid | ||
138 | pci_sun4v_msiq_getvalid: | ||
139 | mov HV_FAST_PCI_MSIQ_GETVALID, %o5 | ||
140 | ta HV_FAST_TRAP | ||
141 | stx %o1, [%o2] | ||
142 | retl | ||
143 | mov %o0, %o0 | ||
144 | |||
145 | /* %o0: devhandle | ||
146 | * %o1: msiqid | ||
147 | * %o2: valid | ||
148 | * | ||
149 | * returns %o0: status | ||
150 | */ | ||
151 | .globl pci_sun4v_msiq_setvalid | ||
152 | pci_sun4v_msiq_setvalid: | ||
153 | mov HV_FAST_PCI_MSIQ_SETVALID, %o5 | ||
154 | ta HV_FAST_TRAP | ||
155 | retl | ||
156 | mov %o0, %o0 | ||
157 | |||
158 | /* %o0: devhandle | ||
159 | * %o1: msiqid | ||
160 | * %o2: &state | ||
161 | * | ||
162 | * returns %o0: status | ||
163 | */ | ||
164 | .globl pci_sun4v_msiq_getstate | ||
165 | pci_sun4v_msiq_getstate: | ||
166 | mov HV_FAST_PCI_MSIQ_GETSTATE, %o5 | ||
167 | ta HV_FAST_TRAP | ||
168 | stx %o1, [%o2] | ||
169 | retl | ||
170 | mov %o0, %o0 | ||
171 | |||
172 | /* %o0: devhandle | ||
173 | * %o1: msiqid | ||
174 | * %o2: state | ||
175 | * | ||
176 | * returns %o0: status | ||
177 | */ | ||
178 | .globl pci_sun4v_msiq_setstate | ||
179 | pci_sun4v_msiq_setstate: | ||
180 | mov HV_FAST_PCI_MSIQ_SETSTATE, %o5 | ||
181 | ta HV_FAST_TRAP | ||
182 | retl | ||
183 | mov %o0, %o0 | ||
184 | |||
185 | /* %o0: devhandle | ||
186 | * %o1: msiqid | ||
187 | * %o2: &head | ||
188 | * | ||
189 | * returns %o0: status | ||
190 | */ | ||
191 | .globl pci_sun4v_msiq_gethead | ||
192 | pci_sun4v_msiq_gethead: | ||
193 | mov HV_FAST_PCI_MSIQ_GETHEAD, %o5 | ||
194 | ta HV_FAST_TRAP | ||
195 | stx %o1, [%o2] | ||
196 | retl | ||
197 | mov %o0, %o0 | ||
198 | |||
199 | /* %o0: devhandle | ||
200 | * %o1: msiqid | ||
201 | * %o2: head | ||
202 | * | ||
203 | * returns %o0: status | ||
204 | */ | ||
205 | .globl pci_sun4v_msiq_sethead | ||
206 | pci_sun4v_msiq_sethead: | ||
207 | mov HV_FAST_PCI_MSIQ_SETHEAD, %o5 | ||
208 | ta HV_FAST_TRAP | ||
209 | retl | ||
210 | mov %o0, %o0 | ||
211 | |||
212 | /* %o0: devhandle | ||
213 | * %o1: msiqid | ||
214 | * %o2: &tail | ||
215 | * | ||
216 | * returns %o0: status | ||
217 | */ | ||
218 | .globl pci_sun4v_msiq_gettail | ||
219 | pci_sun4v_msiq_gettail: | ||
220 | mov HV_FAST_PCI_MSIQ_GETTAIL, %o5 | ||
221 | ta HV_FAST_TRAP | ||
222 | stx %o1, [%o2] | ||
223 | retl | ||
224 | mov %o0, %o0 | ||
225 | |||
226 | /* %o0: devhandle | ||
227 | * %o1: msinum | ||
228 | * %o2: &valid | ||
229 | * | ||
230 | * returns %o0: status | ||
231 | */ | ||
232 | .globl pci_sun4v_msi_getvalid | ||
233 | pci_sun4v_msi_getvalid: | ||
234 | mov HV_FAST_PCI_MSI_GETVALID, %o5 | ||
235 | ta HV_FAST_TRAP | ||
236 | stx %o1, [%o2] | ||
237 | retl | ||
238 | mov %o0, %o0 | ||
239 | |||
240 | /* %o0: devhandle | ||
241 | * %o1: msinum | ||
242 | * %o2: valid | ||
243 | * | ||
244 | * returns %o0: status | ||
245 | */ | ||
246 | .globl pci_sun4v_msi_setvalid | ||
247 | pci_sun4v_msi_setvalid: | ||
248 | mov HV_FAST_PCI_MSI_SETVALID, %o5 | ||
249 | ta HV_FAST_TRAP | ||
250 | retl | ||
251 | mov %o0, %o0 | ||
252 | |||
253 | /* %o0: devhandle | ||
254 | * %o1: msinum | ||
255 | * %o2: &msiq | ||
256 | * | ||
257 | * returns %o0: status | ||
258 | */ | ||
259 | .globl pci_sun4v_msi_getmsiq | ||
260 | pci_sun4v_msi_getmsiq: | ||
261 | mov HV_FAST_PCI_MSI_GETMSIQ, %o5 | ||
262 | ta HV_FAST_TRAP | ||
263 | stx %o1, [%o2] | ||
264 | retl | ||
265 | mov %o0, %o0 | ||
266 | |||
267 | /* %o0: devhandle | ||
268 | * %o1: msinum | ||
269 | * %o2: msitype | ||
270 | * %o3: msiq | ||
271 | * | ||
272 | * returns %o0: status | ||
273 | */ | ||
274 | .globl pci_sun4v_msi_setmsiq | ||
275 | pci_sun4v_msi_setmsiq: | ||
276 | mov HV_FAST_PCI_MSI_SETMSIQ, %o5 | ||
277 | ta HV_FAST_TRAP | ||
278 | retl | ||
279 | mov %o0, %o0 | ||
280 | |||
281 | /* %o0: devhandle | ||
282 | * %o1: msinum | ||
283 | * %o2: &state | ||
284 | * | ||
285 | * returns %o0: status | ||
286 | */ | ||
287 | .globl pci_sun4v_msi_getstate | ||
288 | pci_sun4v_msi_getstate: | ||
289 | mov HV_FAST_PCI_MSI_GETSTATE, %o5 | ||
290 | ta HV_FAST_TRAP | ||
291 | stx %o1, [%o2] | ||
292 | retl | ||
293 | mov %o0, %o0 | ||
294 | |||
295 | /* %o0: devhandle | ||
296 | * %o1: msinum | ||
297 | * %o2: state | ||
298 | * | ||
299 | * returns %o0: status | ||
300 | */ | ||
301 | .globl pci_sun4v_msi_setstate | ||
302 | pci_sun4v_msi_setstate: | ||
303 | mov HV_FAST_PCI_MSI_SETSTATE, %o5 | ||
304 | ta HV_FAST_TRAP | ||
305 | retl | ||
306 | mov %o0, %o0 | ||
307 | |||
308 | /* %o0: devhandle | ||
309 | * %o1: msinum | ||
310 | * %o2: &msiq | ||
311 | * | ||
312 | * returns %o0: status | ||
313 | */ | ||
314 | .globl pci_sun4v_msg_getmsiq | ||
315 | pci_sun4v_msg_getmsiq: | ||
316 | mov HV_FAST_PCI_MSG_GETMSIQ, %o5 | ||
317 | ta HV_FAST_TRAP | ||
318 | stx %o1, [%o2] | ||
319 | retl | ||
320 | mov %o0, %o0 | ||
321 | |||
322 | /* %o0: devhandle | ||
323 | * %o1: msinum | ||
324 | * %o2: msiq | ||
325 | * | ||
326 | * returns %o0: status | ||
327 | */ | ||
328 | .globl pci_sun4v_msg_setmsiq | ||
329 | pci_sun4v_msg_setmsiq: | ||
330 | mov HV_FAST_PCI_MSG_SETMSIQ, %o5 | ||
331 | ta HV_FAST_TRAP | ||
332 | retl | ||
333 | mov %o0, %o0 | ||
334 | |||
335 | /* %o0: devhandle | ||
336 | * %o1: msinum | ||
337 | * %o2: &valid | ||
338 | * | ||
339 | * returns %o0: status | ||
340 | */ | ||
341 | .globl pci_sun4v_msg_getvalid | ||
342 | pci_sun4v_msg_getvalid: | ||
343 | mov HV_FAST_PCI_MSG_GETVALID, %o5 | ||
344 | ta HV_FAST_TRAP | ||
345 | stx %o1, [%o2] | ||
346 | retl | ||
347 | mov %o0, %o0 | ||
348 | |||
349 | /* %o0: devhandle | ||
350 | * %o1: msinum | ||
351 | * %o2: valid | ||
352 | * | ||
353 | * returns %o0: status | ||
354 | */ | ||
355 | .globl pci_sun4v_msg_setvalid | ||
356 | pci_sun4v_msg_setvalid: | ||
357 | mov HV_FAST_PCI_MSG_SETVALID, %o5 | ||
358 | ta HV_FAST_TRAP | ||
359 | retl | ||
360 | mov %o0, %o0 | ||
96 | 361 | ||
362 |
block/ioctl.c
1 | #include <linux/capability.h> | 1 | #include <linux/capability.h> |
2 | #include <linux/blkdev.h> | 2 | #include <linux/blkdev.h> |
3 | #include <linux/blkpg.h> | 3 | #include <linux/blkpg.h> |
4 | #include <linux/hdreg.h> | 4 | #include <linux/hdreg.h> |
5 | #include <linux/backing-dev.h> | 5 | #include <linux/backing-dev.h> |
6 | #include <linux/buffer_head.h> | 6 | #include <linux/buffer_head.h> |
7 | #include <linux/smp_lock.h> | 7 | #include <linux/smp_lock.h> |
8 | #include <linux/blktrace_api.h> | 8 | #include <linux/blktrace_api.h> |
9 | #include <asm/uaccess.h> | 9 | #include <asm/uaccess.h> |
10 | 10 | ||
11 | static int blkpg_ioctl(struct block_device *bdev, struct blkpg_ioctl_arg __user *arg) | 11 | static int blkpg_ioctl(struct block_device *bdev, struct blkpg_ioctl_arg __user *arg) |
12 | { | 12 | { |
13 | struct block_device *bdevp; | 13 | struct block_device *bdevp; |
14 | struct gendisk *disk; | 14 | struct gendisk *disk; |
15 | struct blkpg_ioctl_arg a; | 15 | struct blkpg_ioctl_arg a; |
16 | struct blkpg_partition p; | 16 | struct blkpg_partition p; |
17 | long long start, length; | 17 | long long start, length; |
18 | int part; | 18 | int part; |
19 | int i; | 19 | int i; |
20 | 20 | ||
21 | if (!capable(CAP_SYS_ADMIN)) | 21 | if (!capable(CAP_SYS_ADMIN)) |
22 | return -EACCES; | 22 | return -EACCES; |
23 | if (copy_from_user(&a, arg, sizeof(struct blkpg_ioctl_arg))) | 23 | if (copy_from_user(&a, arg, sizeof(struct blkpg_ioctl_arg))) |
24 | return -EFAULT; | 24 | return -EFAULT; |
25 | if (copy_from_user(&p, a.data, sizeof(struct blkpg_partition))) | 25 | if (copy_from_user(&p, a.data, sizeof(struct blkpg_partition))) |
26 | return -EFAULT; | 26 | return -EFAULT; |
27 | disk = bdev->bd_disk; | 27 | disk = bdev->bd_disk; |
28 | if (bdev != bdev->bd_contains) | 28 | if (bdev != bdev->bd_contains) |
29 | return -EINVAL; | 29 | return -EINVAL; |
30 | part = p.pno; | 30 | part = p.pno; |
31 | if (part <= 0 || part >= disk->minors) | 31 | if (part <= 0 || part >= disk->minors) |
32 | return -EINVAL; | 32 | return -EINVAL; |
33 | switch (a.op) { | 33 | switch (a.op) { |
34 | case BLKPG_ADD_PARTITION: | 34 | case BLKPG_ADD_PARTITION: |
35 | start = p.start >> 9; | 35 | start = p.start >> 9; |
36 | length = p.length >> 9; | 36 | length = p.length >> 9; |
37 | /* check for fit in a hd_struct */ | 37 | /* check for fit in a hd_struct */ |
38 | if (sizeof(sector_t) == sizeof(long) && | 38 | if (sizeof(sector_t) == sizeof(long) && |
39 | sizeof(long long) > sizeof(long)) { | 39 | sizeof(long long) > sizeof(long)) { |
40 | long pstart = start, plength = length; | 40 | long pstart = start, plength = length; |
41 | if (pstart != start || plength != length | 41 | if (pstart != start || plength != length |
42 | || pstart < 0 || plength < 0) | 42 | || pstart < 0 || plength < 0) |
43 | return -EINVAL; | 43 | return -EINVAL; |
44 | } | 44 | } |
45 | /* partition number in use? */ | 45 | /* partition number in use? */ |
46 | mutex_lock(&bdev->bd_mutex); | 46 | mutex_lock(&bdev->bd_mutex); |
47 | if (disk->part[part - 1]) { | 47 | if (disk->part[part - 1]) { |
48 | mutex_unlock(&bdev->bd_mutex); | 48 | mutex_unlock(&bdev->bd_mutex); |
49 | return -EBUSY; | 49 | return -EBUSY; |
50 | } | 50 | } |
51 | /* overlap? */ | 51 | /* overlap? */ |
52 | for (i = 0; i < disk->minors - 1; i++) { | 52 | for (i = 0; i < disk->minors - 1; i++) { |
53 | struct hd_struct *s = disk->part[i]; | 53 | struct hd_struct *s = disk->part[i]; |
54 | 54 | ||
55 | if (!s) | 55 | if (!s) |
56 | continue; | 56 | continue; |
57 | if (!(start+length <= s->start_sect || | 57 | if (!(start+length <= s->start_sect || |
58 | start >= s->start_sect + s->nr_sects)) { | 58 | start >= s->start_sect + s->nr_sects)) { |
59 | mutex_unlock(&bdev->bd_mutex); | 59 | mutex_unlock(&bdev->bd_mutex); |
60 | return -EBUSY; | 60 | return -EBUSY; |
61 | } | 61 | } |
62 | } | 62 | } |
63 | /* all seems OK */ | 63 | /* all seems OK */ |
64 | add_partition(disk, part, start, length); | 64 | add_partition(disk, part, start, length, ADDPART_FLAG_NONE); |
65 | mutex_unlock(&bdev->bd_mutex); | 65 | mutex_unlock(&bdev->bd_mutex); |
66 | return 0; | 66 | return 0; |
67 | case BLKPG_DEL_PARTITION: | 67 | case BLKPG_DEL_PARTITION: |
68 | if (!disk->part[part-1]) | 68 | if (!disk->part[part-1]) |
69 | return -ENXIO; | 69 | return -ENXIO; |
70 | if (disk->part[part - 1]->nr_sects == 0) | 70 | if (disk->part[part - 1]->nr_sects == 0) |
71 | return -ENXIO; | 71 | return -ENXIO; |
72 | bdevp = bdget_disk(disk, part); | 72 | bdevp = bdget_disk(disk, part); |
73 | if (!bdevp) | 73 | if (!bdevp) |
74 | return -ENOMEM; | 74 | return -ENOMEM; |
75 | mutex_lock(&bdevp->bd_mutex); | 75 | mutex_lock(&bdevp->bd_mutex); |
76 | if (bdevp->bd_openers) { | 76 | if (bdevp->bd_openers) { |
77 | mutex_unlock(&bdevp->bd_mutex); | 77 | mutex_unlock(&bdevp->bd_mutex); |
78 | bdput(bdevp); | 78 | bdput(bdevp); |
79 | return -EBUSY; | 79 | return -EBUSY; |
80 | } | 80 | } |
81 | /* all seems OK */ | 81 | /* all seems OK */ |
82 | fsync_bdev(bdevp); | 82 | fsync_bdev(bdevp); |
83 | invalidate_bdev(bdevp, 0); | 83 | invalidate_bdev(bdevp, 0); |
84 | 84 | ||
85 | mutex_lock(&bdev->bd_mutex); | 85 | mutex_lock(&bdev->bd_mutex); |
86 | delete_partition(disk, part); | 86 | delete_partition(disk, part); |
87 | mutex_unlock(&bdev->bd_mutex); | 87 | mutex_unlock(&bdev->bd_mutex); |
88 | mutex_unlock(&bdevp->bd_mutex); | 88 | mutex_unlock(&bdevp->bd_mutex); |
89 | bdput(bdevp); | 89 | bdput(bdevp); |
90 | 90 | ||
91 | return 0; | 91 | return 0; |
92 | default: | 92 | default: |
93 | return -EINVAL; | 93 | return -EINVAL; |
94 | } | 94 | } |
95 | } | 95 | } |
96 | 96 | ||
97 | static int blkdev_reread_part(struct block_device *bdev) | 97 | static int blkdev_reread_part(struct block_device *bdev) |
98 | { | 98 | { |
99 | struct gendisk *disk = bdev->bd_disk; | 99 | struct gendisk *disk = bdev->bd_disk; |
100 | int res; | 100 | int res; |
101 | 101 | ||
102 | if (disk->minors == 1 || bdev != bdev->bd_contains) | 102 | if (disk->minors == 1 || bdev != bdev->bd_contains) |
103 | return -EINVAL; | 103 | return -EINVAL; |
104 | if (!capable(CAP_SYS_ADMIN)) | 104 | if (!capable(CAP_SYS_ADMIN)) |
105 | return -EACCES; | 105 | return -EACCES; |
106 | if (!mutex_trylock(&bdev->bd_mutex)) | 106 | if (!mutex_trylock(&bdev->bd_mutex)) |
107 | return -EBUSY; | 107 | return -EBUSY; |
108 | res = rescan_partitions(disk, bdev); | 108 | res = rescan_partitions(disk, bdev); |
109 | mutex_unlock(&bdev->bd_mutex); | 109 | mutex_unlock(&bdev->bd_mutex); |
110 | return res; | 110 | return res; |
111 | } | 111 | } |
112 | 112 | ||
113 | static int put_ushort(unsigned long arg, unsigned short val) | 113 | static int put_ushort(unsigned long arg, unsigned short val) |
114 | { | 114 | { |
115 | return put_user(val, (unsigned short __user *)arg); | 115 | return put_user(val, (unsigned short __user *)arg); |
116 | } | 116 | } |
117 | 117 | ||
118 | static int put_int(unsigned long arg, int val) | 118 | static int put_int(unsigned long arg, int val) |
119 | { | 119 | { |
120 | return put_user(val, (int __user *)arg); | 120 | return put_user(val, (int __user *)arg); |
121 | } | 121 | } |
122 | 122 | ||
123 | static int put_long(unsigned long arg, long val) | 123 | static int put_long(unsigned long arg, long val) |
124 | { | 124 | { |
125 | return put_user(val, (long __user *)arg); | 125 | return put_user(val, (long __user *)arg); |
126 | } | 126 | } |
127 | 127 | ||
128 | static int put_ulong(unsigned long arg, unsigned long val) | 128 | static int put_ulong(unsigned long arg, unsigned long val) |
129 | { | 129 | { |
130 | return put_user(val, (unsigned long __user *)arg); | 130 | return put_user(val, (unsigned long __user *)arg); |
131 | } | 131 | } |
132 | 132 | ||
133 | static int put_u64(unsigned long arg, u64 val) | 133 | static int put_u64(unsigned long arg, u64 val) |
134 | { | 134 | { |
135 | return put_user(val, (u64 __user *)arg); | 135 | return put_user(val, (u64 __user *)arg); |
136 | } | 136 | } |
137 | 137 | ||
138 | static int blkdev_locked_ioctl(struct file *file, struct block_device *bdev, | 138 | static int blkdev_locked_ioctl(struct file *file, struct block_device *bdev, |
139 | unsigned cmd, unsigned long arg) | 139 | unsigned cmd, unsigned long arg) |
140 | { | 140 | { |
141 | struct backing_dev_info *bdi; | 141 | struct backing_dev_info *bdi; |
142 | int ret, n; | 142 | int ret, n; |
143 | 143 | ||
144 | switch (cmd) { | 144 | switch (cmd) { |
145 | case BLKRAGET: | 145 | case BLKRAGET: |
146 | case BLKFRAGET: | 146 | case BLKFRAGET: |
147 | if (!arg) | 147 | if (!arg) |
148 | return -EINVAL; | 148 | return -EINVAL; |
149 | bdi = blk_get_backing_dev_info(bdev); | 149 | bdi = blk_get_backing_dev_info(bdev); |
150 | if (bdi == NULL) | 150 | if (bdi == NULL) |
151 | return -ENOTTY; | 151 | return -ENOTTY; |
152 | return put_long(arg, (bdi->ra_pages * PAGE_CACHE_SIZE) / 512); | 152 | return put_long(arg, (bdi->ra_pages * PAGE_CACHE_SIZE) / 512); |
153 | case BLKROGET: | 153 | case BLKROGET: |
154 | return put_int(arg, bdev_read_only(bdev) != 0); | 154 | return put_int(arg, bdev_read_only(bdev) != 0); |
155 | case BLKBSZGET: /* get the logical block size (cf. BLKSSZGET) */ | 155 | case BLKBSZGET: /* get the logical block size (cf. BLKSSZGET) */ |
156 | return put_int(arg, block_size(bdev)); | 156 | return put_int(arg, block_size(bdev)); |
157 | case BLKSSZGET: /* get block device hardware sector size */ | 157 | case BLKSSZGET: /* get block device hardware sector size */ |
158 | return put_int(arg, bdev_hardsect_size(bdev)); | 158 | return put_int(arg, bdev_hardsect_size(bdev)); |
159 | case BLKSECTGET: | 159 | case BLKSECTGET: |
160 | return put_ushort(arg, bdev_get_queue(bdev)->max_sectors); | 160 | return put_ushort(arg, bdev_get_queue(bdev)->max_sectors); |
161 | case BLKRASET: | 161 | case BLKRASET: |
162 | case BLKFRASET: | 162 | case BLKFRASET: |
163 | if(!capable(CAP_SYS_ADMIN)) | 163 | if(!capable(CAP_SYS_ADMIN)) |
164 | return -EACCES; | 164 | return -EACCES; |
165 | bdi = blk_get_backing_dev_info(bdev); | 165 | bdi = blk_get_backing_dev_info(bdev); |
166 | if (bdi == NULL) | 166 | if (bdi == NULL) |
167 | return -ENOTTY; | 167 | return -ENOTTY; |
168 | bdi->ra_pages = (arg * 512) / PAGE_CACHE_SIZE; | 168 | bdi->ra_pages = (arg * 512) / PAGE_CACHE_SIZE; |
169 | return 0; | 169 | return 0; |
170 | case BLKBSZSET: | 170 | case BLKBSZSET: |
171 | /* set the logical block size */ | 171 | /* set the logical block size */ |
172 | if (!capable(CAP_SYS_ADMIN)) | 172 | if (!capable(CAP_SYS_ADMIN)) |
173 | return -EACCES; | 173 | return -EACCES; |
174 | if (!arg) | 174 | if (!arg) |
175 | return -EINVAL; | 175 | return -EINVAL; |
176 | if (get_user(n, (int __user *) arg)) | 176 | if (get_user(n, (int __user *) arg)) |
177 | return -EFAULT; | 177 | return -EFAULT; |
178 | if (bd_claim(bdev, file) < 0) | 178 | if (bd_claim(bdev, file) < 0) |
179 | return -EBUSY; | 179 | return -EBUSY; |
180 | ret = set_blocksize(bdev, n); | 180 | ret = set_blocksize(bdev, n); |
181 | bd_release(bdev); | 181 | bd_release(bdev); |
182 | return ret; | 182 | return ret; |
183 | case BLKPG: | 183 | case BLKPG: |
184 | return blkpg_ioctl(bdev, (struct blkpg_ioctl_arg __user *) arg); | 184 | return blkpg_ioctl(bdev, (struct blkpg_ioctl_arg __user *) arg); |
185 | case BLKRRPART: | 185 | case BLKRRPART: |
186 | return blkdev_reread_part(bdev); | 186 | return blkdev_reread_part(bdev); |
187 | case BLKGETSIZE: | 187 | case BLKGETSIZE: |
188 | if ((bdev->bd_inode->i_size >> 9) > ~0UL) | 188 | if ((bdev->bd_inode->i_size >> 9) > ~0UL) |
189 | return -EFBIG; | 189 | return -EFBIG; |
190 | return put_ulong(arg, bdev->bd_inode->i_size >> 9); | 190 | return put_ulong(arg, bdev->bd_inode->i_size >> 9); |
191 | case BLKGETSIZE64: | 191 | case BLKGETSIZE64: |
192 | return put_u64(arg, bdev->bd_inode->i_size); | 192 | return put_u64(arg, bdev->bd_inode->i_size); |
193 | case BLKTRACESTART: | 193 | case BLKTRACESTART: |
194 | case BLKTRACESTOP: | 194 | case BLKTRACESTOP: |
195 | case BLKTRACESETUP: | 195 | case BLKTRACESETUP: |
196 | case BLKTRACETEARDOWN: | 196 | case BLKTRACETEARDOWN: |
197 | return blk_trace_ioctl(bdev, cmd, (char __user *) arg); | 197 | return blk_trace_ioctl(bdev, cmd, (char __user *) arg); |
198 | } | 198 | } |
199 | return -ENOIOCTLCMD; | 199 | return -ENOIOCTLCMD; |
200 | } | 200 | } |
201 | 201 | ||
202 | int blkdev_driver_ioctl(struct inode *inode, struct file *file, | 202 | int blkdev_driver_ioctl(struct inode *inode, struct file *file, |
203 | struct gendisk *disk, unsigned cmd, unsigned long arg) | 203 | struct gendisk *disk, unsigned cmd, unsigned long arg) |
204 | { | 204 | { |
205 | int ret; | 205 | int ret; |
206 | if (disk->fops->unlocked_ioctl) | 206 | if (disk->fops->unlocked_ioctl) |
207 | return disk->fops->unlocked_ioctl(file, cmd, arg); | 207 | return disk->fops->unlocked_ioctl(file, cmd, arg); |
208 | 208 | ||
209 | if (disk->fops->ioctl) { | 209 | if (disk->fops->ioctl) { |
210 | lock_kernel(); | 210 | lock_kernel(); |
211 | ret = disk->fops->ioctl(inode, file, cmd, arg); | 211 | ret = disk->fops->ioctl(inode, file, cmd, arg); |
212 | unlock_kernel(); | 212 | unlock_kernel(); |
213 | return ret; | 213 | return ret; |
214 | } | 214 | } |
215 | 215 | ||
216 | return -ENOTTY; | 216 | return -ENOTTY; |
217 | } | 217 | } |
218 | EXPORT_SYMBOL_GPL(blkdev_driver_ioctl); | 218 | EXPORT_SYMBOL_GPL(blkdev_driver_ioctl); |
219 | 219 | ||
220 | int blkdev_ioctl(struct inode *inode, struct file *file, unsigned cmd, | 220 | int blkdev_ioctl(struct inode *inode, struct file *file, unsigned cmd, |
221 | unsigned long arg) | 221 | unsigned long arg) |
222 | { | 222 | { |
223 | struct block_device *bdev = inode->i_bdev; | 223 | struct block_device *bdev = inode->i_bdev; |
224 | struct gendisk *disk = bdev->bd_disk; | 224 | struct gendisk *disk = bdev->bd_disk; |
225 | int ret, n; | 225 | int ret, n; |
226 | 226 | ||
227 | switch(cmd) { | 227 | switch(cmd) { |
228 | case BLKFLSBUF: | 228 | case BLKFLSBUF: |
229 | if (!capable(CAP_SYS_ADMIN)) | 229 | if (!capable(CAP_SYS_ADMIN)) |
230 | return -EACCES; | 230 | return -EACCES; |
231 | 231 | ||
232 | ret = blkdev_driver_ioctl(inode, file, disk, cmd, arg); | 232 | ret = blkdev_driver_ioctl(inode, file, disk, cmd, arg); |
233 | /* -EINVAL to handle old uncorrected drivers */ | 233 | /* -EINVAL to handle old uncorrected drivers */ |
234 | if (ret != -EINVAL && ret != -ENOTTY) | 234 | if (ret != -EINVAL && ret != -ENOTTY) |
235 | return ret; | 235 | return ret; |
236 | 236 | ||
237 | lock_kernel(); | 237 | lock_kernel(); |
238 | fsync_bdev(bdev); | 238 | fsync_bdev(bdev); |
239 | invalidate_bdev(bdev, 0); | 239 | invalidate_bdev(bdev, 0); |
240 | unlock_kernel(); | 240 | unlock_kernel(); |
241 | return 0; | 241 | return 0; |
242 | 242 | ||
243 | case BLKROSET: | 243 | case BLKROSET: |
244 | ret = blkdev_driver_ioctl(inode, file, disk, cmd, arg); | 244 | ret = blkdev_driver_ioctl(inode, file, disk, cmd, arg); |
245 | /* -EINVAL to handle old uncorrected drivers */ | 245 | /* -EINVAL to handle old uncorrected drivers */ |
246 | if (ret != -EINVAL && ret != -ENOTTY) | 246 | if (ret != -EINVAL && ret != -ENOTTY) |
247 | return ret; | 247 | return ret; |
248 | if (!capable(CAP_SYS_ADMIN)) | 248 | if (!capable(CAP_SYS_ADMIN)) |
249 | return -EACCES; | 249 | return -EACCES; |
250 | if (get_user(n, (int __user *)(arg))) | 250 | if (get_user(n, (int __user *)(arg))) |
251 | return -EFAULT; | 251 | return -EFAULT; |
252 | lock_kernel(); | 252 | lock_kernel(); |
253 | set_device_ro(bdev, n); | 253 | set_device_ro(bdev, n); |
254 | unlock_kernel(); | 254 | unlock_kernel(); |
255 | return 0; | 255 | return 0; |
256 | case HDIO_GETGEO: { | 256 | case HDIO_GETGEO: { |
257 | struct hd_geometry geo; | 257 | struct hd_geometry geo; |
258 | 258 | ||
259 | if (!arg) | 259 | if (!arg) |
260 | return -EINVAL; | 260 | return -EINVAL; |
261 | if (!disk->fops->getgeo) | 261 | if (!disk->fops->getgeo) |
262 | return -ENOTTY; | 262 | return -ENOTTY; |
263 | 263 | ||
264 | /* | 264 | /* |
265 | * We need to set the startsect first, the driver may | 265 | * We need to set the startsect first, the driver may |
266 | * want to override it. | 266 | * want to override it. |
267 | */ | 267 | */ |
268 | geo.start = get_start_sect(bdev); | 268 | geo.start = get_start_sect(bdev); |
269 | ret = disk->fops->getgeo(bdev, &geo); | 269 | ret = disk->fops->getgeo(bdev, &geo); |
270 | if (ret) | 270 | if (ret) |
271 | return ret; | 271 | return ret; |
272 | if (copy_to_user((struct hd_geometry __user *)arg, &geo, | 272 | if (copy_to_user((struct hd_geometry __user *)arg, &geo, |
273 | sizeof(geo))) | 273 | sizeof(geo))) |
274 | return -EFAULT; | 274 | return -EFAULT; |
275 | return 0; | 275 | return 0; |
276 | } | 276 | } |
277 | } | 277 | } |
278 | 278 | ||
279 | lock_kernel(); | 279 | lock_kernel(); |
280 | ret = blkdev_locked_ioctl(file, bdev, cmd, arg); | 280 | ret = blkdev_locked_ioctl(file, bdev, cmd, arg); |
281 | unlock_kernel(); | 281 | unlock_kernel(); |
282 | if (ret != -ENOIOCTLCMD) | 282 | if (ret != -ENOIOCTLCMD) |
283 | return ret; | 283 | return ret; |
284 | 284 | ||
285 | return blkdev_driver_ioctl(inode, file, disk, cmd, arg); | 285 | return blkdev_driver_ioctl(inode, file, disk, cmd, arg); |
286 | } | 286 | } |
287 | 287 | ||
288 | /* Most of the generic ioctls are handled in the normal fallback path. | 288 | /* Most of the generic ioctls are handled in the normal fallback path. |
289 | This assumes the blkdev's low level compat_ioctl always returns | 289 | This assumes the blkdev's low level compat_ioctl always returns |
290 | ENOIOCTLCMD for unknown ioctls. */ | 290 | ENOIOCTLCMD for unknown ioctls. */ |
291 | long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg) | 291 | long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg) |
292 | { | 292 | { |
293 | struct block_device *bdev = file->f_path.dentry->d_inode->i_bdev; | 293 | struct block_device *bdev = file->f_path.dentry->d_inode->i_bdev; |
294 | struct gendisk *disk = bdev->bd_disk; | 294 | struct gendisk *disk = bdev->bd_disk; |
295 | int ret = -ENOIOCTLCMD; | 295 | int ret = -ENOIOCTLCMD; |
296 | if (disk->fops->compat_ioctl) { | 296 | if (disk->fops->compat_ioctl) { |
297 | lock_kernel(); | 297 | lock_kernel(); |
298 | ret = disk->fops->compat_ioctl(file, cmd, arg); | 298 | ret = disk->fops->compat_ioctl(file, cmd, arg); |
299 | unlock_kernel(); | 299 | unlock_kernel(); |
300 | } | 300 | } |
301 | return ret; | 301 | return ret; |
302 | } | 302 | } |
303 | 303 | ||
304 | EXPORT_SYMBOL_GPL(blkdev_ioctl); | 304 | EXPORT_SYMBOL_GPL(blkdev_ioctl); |
305 | 305 |
drivers/pci/Kconfig
1 | # | 1 | # |
2 | # PCI configuration | 2 | # PCI configuration |
3 | # | 3 | # |
4 | config PCI_MSI | 4 | config PCI_MSI |
5 | bool "Message Signaled Interrupts (MSI and MSI-X)" | 5 | bool "Message Signaled Interrupts (MSI and MSI-X)" |
6 | depends on PCI | 6 | depends on PCI |
7 | depends on (X86_LOCAL_APIC && X86_IO_APIC) || IA64 | 7 | depends on (X86_LOCAL_APIC && X86_IO_APIC) || IA64 || SPARC64 |
8 | help | 8 | help |
9 | This allows device drivers to enable MSI (Message Signaled | 9 | This allows device drivers to enable MSI (Message Signaled |
10 | Interrupts). Message Signaled Interrupts enable a device to | 10 | Interrupts). Message Signaled Interrupts enable a device to |
11 | generate an interrupt using an inbound Memory Write on its | 11 | generate an interrupt using an inbound Memory Write on its |
12 | PCI bus instead of asserting a device IRQ pin. | 12 | PCI bus instead of asserting a device IRQ pin. |
13 | 13 | ||
14 | Use of PCI MSI interrupts can be disabled at kernel boot time | 14 | Use of PCI MSI interrupts can be disabled at kernel boot time |
15 | by using the 'pci=nomsi' option. This disables MSI for the | 15 | by using the 'pci=nomsi' option. This disables MSI for the |
16 | entire system. | 16 | entire system. |
17 | 17 | ||
18 | If you don't know what to do here, say N. | 18 | If you don't know what to do here, say N. |
19 | 19 | ||
20 | config PCI_MULTITHREAD_PROBE | 20 | config PCI_MULTITHREAD_PROBE |
21 | bool "PCI Multi-threaded probe (EXPERIMENTAL)" | 21 | bool "PCI Multi-threaded probe (EXPERIMENTAL)" |
22 | depends on PCI && EXPERIMENTAL && BROKEN | 22 | depends on PCI && EXPERIMENTAL && BROKEN |
23 | help | 23 | help |
24 | Say Y here if you want the PCI core to spawn a new thread for | 24 | Say Y here if you want the PCI core to spawn a new thread for |
25 | every PCI device that is probed. This can cause a huge | 25 | every PCI device that is probed. This can cause a huge |
26 | speedup in boot times on multiprocessor machines, and even a | 26 | speedup in boot times on multiprocessor machines, and even a |
27 | smaller speedup on single processor machines. | 27 | smaller speedup on single processor machines. |
28 | 28 | ||
29 | But it can also cause lots of bad things to happen. A number | 29 | But it can also cause lots of bad things to happen. A number |
30 | of PCI drivers cannot properly handle running in this way, | 30 | of PCI drivers cannot properly handle running in this way, |
31 | some will just not work properly at all, while others might | 31 | some will just not work properly at all, while others might |
32 | decide to blow up power supplies with a huge load all at once, | 32 | decide to blow up power supplies with a huge load all at once, |
33 | so use this option at your own risk. | 33 | so use this option at your own risk. |
34 | 34 | ||
35 | It is very unwise to use this option if you are not using a | 35 | It is very unwise to use this option if you are not using a |
36 | boot process that can handle devices being created in any | 36 | boot process that can handle devices being created in any |
37 | order. A program that can create persistent block and network | 37 | order. A program that can create persistent block and network |
38 | device names (like udev) is a good idea if you wish to use | 38 | device names (like udev) is a good idea if you wish to use |
39 | this option. | 39 | this option. |
40 | 40 | ||
41 | Again, use this option at your own risk, you have been warned! | 41 | Again, use this option at your own risk, you have been warned! |
42 | 42 | ||
43 | When in doubt, say N. | 43 | When in doubt, say N. |
44 | 44 | ||
45 | config PCI_DEBUG | 45 | config PCI_DEBUG |
46 | bool "PCI Debugging" | 46 | bool "PCI Debugging" |
47 | depends on PCI && DEBUG_KERNEL | 47 | depends on PCI && DEBUG_KERNEL |
48 | help | 48 | help |
49 | Say Y here if you want the PCI core to produce a bunch of debug | 49 | Say Y here if you want the PCI core to produce a bunch of debug |
50 | messages to the system log. Select this if you are having a | 50 | messages to the system log. Select this if you are having a |
51 | problem with PCI support and want to see more of what is going on. | 51 | problem with PCI support and want to see more of what is going on. |
52 | 52 | ||
53 | When in doubt, say N. | 53 | When in doubt, say N. |
54 | 54 | ||
55 | config HT_IRQ | 55 | config HT_IRQ |
56 | bool "Interrupts on hypertransport devices" | 56 | bool "Interrupts on hypertransport devices" |
57 | default y | 57 | default y |
58 | depends on PCI && X86_LOCAL_APIC && X86_IO_APIC | 58 | depends on PCI && X86_LOCAL_APIC && X86_IO_APIC |
59 | help | 59 | help |
60 | This allows native hypertransport devices to use interrupts. | 60 | This allows native hypertransport devices to use interrupts. |
61 | 61 | ||
62 | If unsure say Y. | 62 | If unsure say Y. |
63 | 63 |
drivers/sbus/sbus.c
1 | /* sbus.c: SBus support routines. | 1 | /* sbus.c: SBus support routines. |
2 | * | 2 | * |
3 | * Copyright (C) 1995, 2006 David S. Miller (davem@davemloft.net) | 3 | * Copyright (C) 1995, 2006 David S. Miller (davem@davemloft.net) |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include <linux/kernel.h> | 6 | #include <linux/kernel.h> |
7 | #include <linux/slab.h> | 7 | #include <linux/slab.h> |
8 | #include <linux/init.h> | 8 | #include <linux/init.h> |
9 | #include <linux/pci.h> | 9 | #include <linux/pci.h> |
10 | #include <linux/device.h> | ||
10 | 11 | ||
11 | #include <asm/system.h> | 12 | #include <asm/system.h> |
12 | #include <asm/sbus.h> | 13 | #include <asm/sbus.h> |
13 | #include <asm/dma.h> | 14 | #include <asm/dma.h> |
14 | #include <asm/oplib.h> | 15 | #include <asm/oplib.h> |
15 | #include <asm/prom.h> | 16 | #include <asm/prom.h> |
16 | #include <asm/of_device.h> | 17 | #include <asm/of_device.h> |
17 | #include <asm/bpp.h> | 18 | #include <asm/bpp.h> |
18 | #include <asm/irq.h> | 19 | #include <asm/irq.h> |
19 | 20 | ||
21 | static ssize_t | ||
22 | show_sbusobppath_attr(struct device * dev, struct device_attribute * attr, char * buf) | ||
23 | { | ||
24 | struct sbus_dev *sbus; | ||
25 | |||
26 | sbus = to_sbus_device(dev); | ||
27 | |||
28 | return snprintf (buf, PAGE_SIZE, "%s\n", sbus->ofdev.node->full_name); | ||
29 | } | ||
30 | |||
31 | static DEVICE_ATTR(obppath, S_IRUSR | S_IRGRP | S_IROTH, show_sbusobppath_attr, NULL); | ||
32 | |||
20 | struct sbus_bus *sbus_root; | 33 | struct sbus_bus *sbus_root; |
21 | 34 | ||
22 | static void __init fill_sbus_device(struct device_node *dp, struct sbus_dev *sdev) | 35 | static void __init fill_sbus_device(struct device_node *dp, struct sbus_dev *sdev) |
23 | { | 36 | { |
24 | unsigned long base; | 37 | unsigned long base; |
25 | void *pval; | 38 | void *pval; |
26 | int len; | 39 | int len, err; |
27 | 40 | ||
28 | sdev->prom_node = dp->node; | 41 | sdev->prom_node = dp->node; |
29 | strcpy(sdev->prom_name, dp->name); | 42 | strcpy(sdev->prom_name, dp->name); |
30 | 43 | ||
31 | pval = of_get_property(dp, "reg", &len); | 44 | pval = of_get_property(dp, "reg", &len); |
32 | sdev->num_registers = 0; | 45 | sdev->num_registers = 0; |
33 | if (pval) { | 46 | if (pval) { |
34 | memcpy(sdev->reg_addrs, pval, len); | 47 | memcpy(sdev->reg_addrs, pval, len); |
35 | 48 | ||
36 | sdev->num_registers = | 49 | sdev->num_registers = |
37 | len / sizeof(struct linux_prom_registers); | 50 | len / sizeof(struct linux_prom_registers); |
38 | 51 | ||
39 | base = (unsigned long) sdev->reg_addrs[0].phys_addr; | 52 | base = (unsigned long) sdev->reg_addrs[0].phys_addr; |
40 | 53 | ||
41 | /* Compute the slot number. */ | 54 | /* Compute the slot number. */ |
42 | if (base >= SUN_SBUS_BVADDR && sparc_cpu_model == sun4m) | 55 | if (base >= SUN_SBUS_BVADDR && sparc_cpu_model == sun4m) |
43 | sdev->slot = sbus_dev_slot(base); | 56 | sdev->slot = sbus_dev_slot(base); |
44 | else | 57 | else |
45 | sdev->slot = sdev->reg_addrs[0].which_io; | 58 | sdev->slot = sdev->reg_addrs[0].which_io; |
46 | } | 59 | } |
47 | 60 | ||
48 | pval = of_get_property(dp, "ranges", &len); | 61 | pval = of_get_property(dp, "ranges", &len); |
49 | sdev->num_device_ranges = 0; | 62 | sdev->num_device_ranges = 0; |
50 | if (pval) { | 63 | if (pval) { |
51 | memcpy(sdev->device_ranges, pval, len); | 64 | memcpy(sdev->device_ranges, pval, len); |
52 | sdev->num_device_ranges = | 65 | sdev->num_device_ranges = |
53 | len / sizeof(struct linux_prom_ranges); | 66 | len / sizeof(struct linux_prom_ranges); |
54 | } | 67 | } |
55 | 68 | ||
56 | sbus_fill_device_irq(sdev); | 69 | sbus_fill_device_irq(sdev); |
57 | 70 | ||
58 | sdev->ofdev.node = dp; | 71 | sdev->ofdev.node = dp; |
59 | if (sdev->parent) | 72 | if (sdev->parent) |
60 | sdev->ofdev.dev.parent = &sdev->parent->ofdev.dev; | 73 | sdev->ofdev.dev.parent = &sdev->parent->ofdev.dev; |
61 | else | 74 | else |
62 | sdev->ofdev.dev.parent = &sdev->bus->ofdev.dev; | 75 | sdev->ofdev.dev.parent = &sdev->bus->ofdev.dev; |
63 | sdev->ofdev.dev.bus = &sbus_bus_type; | 76 | sdev->ofdev.dev.bus = &sbus_bus_type; |
64 | sprintf(sdev->ofdev.dev.bus_id, "sbus[%08x]", dp->node); | 77 | sprintf(sdev->ofdev.dev.bus_id, "sbus[%08x]", dp->node); |
65 | 78 | ||
66 | if (of_device_register(&sdev->ofdev) != 0) | 79 | if (of_device_register(&sdev->ofdev) != 0) |
67 | printk(KERN_DEBUG "sbus: device registration error for %s!\n", | 80 | printk(KERN_DEBUG "sbus: device registration error for %s!\n", |
68 | dp->path_component_name); | 81 | dp->path_component_name); |
82 | |||
83 | /* WE HAVE BEEN INVADED BY ALIENS! */ | ||
84 | err = sysfs_create_file(&sdev->ofdev.dev.kobj, &dev_attr_obppath.attr); | ||
69 | } | 85 | } |
70 | 86 | ||
71 | static void __init sbus_bus_ranges_init(struct device_node *dp, struct sbus_bus *sbus) | 87 | static void __init sbus_bus_ranges_init(struct device_node *dp, struct sbus_bus *sbus) |
72 | { | 88 | { |
73 | void *pval; | 89 | void *pval; |
74 | int len; | 90 | int len; |
75 | 91 | ||
76 | pval = of_get_property(dp, "ranges", &len); | 92 | pval = of_get_property(dp, "ranges", &len); |
77 | sbus->num_sbus_ranges = 0; | 93 | sbus->num_sbus_ranges = 0; |
78 | if (pval) { | 94 | if (pval) { |
79 | memcpy(sbus->sbus_ranges, pval, len); | 95 | memcpy(sbus->sbus_ranges, pval, len); |
80 | sbus->num_sbus_ranges = | 96 | sbus->num_sbus_ranges = |
81 | len / sizeof(struct linux_prom_ranges); | 97 | len / sizeof(struct linux_prom_ranges); |
82 | 98 | ||
83 | sbus_arch_bus_ranges_init(dp->parent, sbus); | 99 | sbus_arch_bus_ranges_init(dp->parent, sbus); |
84 | } | 100 | } |
85 | } | 101 | } |
86 | 102 | ||
87 | static void __init __apply_ranges_to_regs(struct linux_prom_ranges *ranges, | 103 | static void __init __apply_ranges_to_regs(struct linux_prom_ranges *ranges, |
88 | int num_ranges, | 104 | int num_ranges, |
89 | struct linux_prom_registers *regs, | 105 | struct linux_prom_registers *regs, |
90 | int num_regs) | 106 | int num_regs) |
91 | { | 107 | { |
92 | if (num_ranges) { | 108 | if (num_ranges) { |
93 | int regnum; | 109 | int regnum; |
94 | 110 | ||
95 | for (regnum = 0; regnum < num_regs; regnum++) { | 111 | for (regnum = 0; regnum < num_regs; regnum++) { |
96 | int rngnum; | 112 | int rngnum; |
97 | 113 | ||
98 | for (rngnum = 0; rngnum < num_ranges; rngnum++) { | 114 | for (rngnum = 0; rngnum < num_ranges; rngnum++) { |
99 | if (regs[regnum].which_io == ranges[rngnum].ot_child_space) | 115 | if (regs[regnum].which_io == ranges[rngnum].ot_child_space) |
100 | break; | 116 | break; |
101 | } | 117 | } |
102 | if (rngnum == num_ranges) { | 118 | if (rngnum == num_ranges) { |
103 | /* We used to flag this as an error. Actually | 119 | /* We used to flag this as an error. Actually |
104 | * some devices do not report the regs as we expect. | 120 | * some devices do not report the regs as we expect. |
105 | * For example, see SUNW,pln device. In that case | 121 | * For example, see SUNW,pln device. In that case |
106 | * the reg property is in a format internal to that | 122 | * the reg property is in a format internal to that |
107 | * node, ie. it is not in the SBUS register space | 123 | * node, ie. it is not in the SBUS register space |
108 | * per se. -DaveM | 124 | * per se. -DaveM |
109 | */ | 125 | */ |
110 | return; | 126 | return; |
111 | } | 127 | } |
112 | regs[regnum].which_io = ranges[rngnum].ot_parent_space; | 128 | regs[regnum].which_io = ranges[rngnum].ot_parent_space; |
113 | regs[regnum].phys_addr -= ranges[rngnum].ot_child_base; | 129 | regs[regnum].phys_addr -= ranges[rngnum].ot_child_base; |
114 | regs[regnum].phys_addr += ranges[rngnum].ot_parent_base; | 130 | regs[regnum].phys_addr += ranges[rngnum].ot_parent_base; |
115 | } | 131 | } |
116 | } | 132 | } |
117 | } | 133 | } |
118 | 134 | ||
119 | static void __init __fixup_regs_sdev(struct sbus_dev *sdev) | 135 | static void __init __fixup_regs_sdev(struct sbus_dev *sdev) |
120 | { | 136 | { |
121 | if (sdev->num_registers != 0) { | 137 | if (sdev->num_registers != 0) { |
122 | struct sbus_dev *parent = sdev->parent; | 138 | struct sbus_dev *parent = sdev->parent; |
123 | int i; | 139 | int i; |
124 | 140 | ||
125 | while (parent != NULL) { | 141 | while (parent != NULL) { |
126 | __apply_ranges_to_regs(parent->device_ranges, | 142 | __apply_ranges_to_regs(parent->device_ranges, |
127 | parent->num_device_ranges, | 143 | parent->num_device_ranges, |
128 | sdev->reg_addrs, | 144 | sdev->reg_addrs, |
129 | sdev->num_registers); | 145 | sdev->num_registers); |
130 | 146 | ||
131 | parent = parent->parent; | 147 | parent = parent->parent; |
132 | } | 148 | } |
133 | 149 | ||
134 | __apply_ranges_to_regs(sdev->bus->sbus_ranges, | 150 | __apply_ranges_to_regs(sdev->bus->sbus_ranges, |
135 | sdev->bus->num_sbus_ranges, | 151 | sdev->bus->num_sbus_ranges, |
136 | sdev->reg_addrs, | 152 | sdev->reg_addrs, |
137 | sdev->num_registers); | 153 | sdev->num_registers); |
138 | 154 | ||
139 | for (i = 0; i < sdev->num_registers; i++) { | 155 | for (i = 0; i < sdev->num_registers; i++) { |
140 | struct resource *res = &sdev->resource[i]; | 156 | struct resource *res = &sdev->resource[i]; |
141 | 157 | ||
142 | res->start = sdev->reg_addrs[i].phys_addr; | 158 | res->start = sdev->reg_addrs[i].phys_addr; |
143 | res->end = (res->start + | 159 | res->end = (res->start + |
144 | (unsigned long)sdev->reg_addrs[i].reg_size - 1UL); | 160 | (unsigned long)sdev->reg_addrs[i].reg_size - 1UL); |
145 | res->flags = IORESOURCE_IO | | 161 | res->flags = IORESOURCE_IO | |
146 | (sdev->reg_addrs[i].which_io & 0xff); | 162 | (sdev->reg_addrs[i].which_io & 0xff); |
147 | } | 163 | } |
148 | } | 164 | } |
149 | } | 165 | } |
150 | 166 | ||
151 | static void __init sbus_fixup_all_regs(struct sbus_dev *first_sdev) | 167 | static void __init sbus_fixup_all_regs(struct sbus_dev *first_sdev) |
152 | { | 168 | { |
153 | struct sbus_dev *sdev; | 169 | struct sbus_dev *sdev; |
154 | 170 | ||
155 | for (sdev = first_sdev; sdev; sdev = sdev->next) { | 171 | for (sdev = first_sdev; sdev; sdev = sdev->next) { |
156 | if (sdev->child) | 172 | if (sdev->child) |
157 | sbus_fixup_all_regs(sdev->child); | 173 | sbus_fixup_all_regs(sdev->child); |
158 | __fixup_regs_sdev(sdev); | 174 | __fixup_regs_sdev(sdev); |
159 | } | 175 | } |
160 | } | 176 | } |
161 | 177 | ||
162 | /* We preserve the "probe order" of these bus and device lists to give | 178 | /* We preserve the "probe order" of these bus and device lists to give |
163 | * the same ordering as the old code. | 179 | * the same ordering as the old code. |
164 | */ | 180 | */ |
165 | static void __init sbus_insert(struct sbus_bus *sbus, struct sbus_bus **root) | 181 | static void __init sbus_insert(struct sbus_bus *sbus, struct sbus_bus **root) |
166 | { | 182 | { |
167 | while (*root) | 183 | while (*root) |
168 | root = &(*root)->next; | 184 | root = &(*root)->next; |
169 | *root = sbus; | 185 | *root = sbus; |
170 | sbus->next = NULL; | 186 | sbus->next = NULL; |
171 | } | 187 | } |
172 | 188 | ||
173 | static void __init sdev_insert(struct sbus_dev *sdev, struct sbus_dev **root) | 189 | static void __init sdev_insert(struct sbus_dev *sdev, struct sbus_dev **root) |
174 | { | 190 | { |
175 | while (*root) | 191 | while (*root) |
176 | root = &(*root)->next; | 192 | root = &(*root)->next; |
177 | *root = sdev; | 193 | *root = sdev; |
178 | sdev->next = NULL; | 194 | sdev->next = NULL; |
179 | } | 195 | } |
180 | 196 | ||
181 | static void __init walk_children(struct device_node *dp, struct sbus_dev *parent, struct sbus_bus *sbus) | 197 | static void __init walk_children(struct device_node *dp, struct sbus_dev *parent, struct sbus_bus *sbus) |
182 | { | 198 | { |
183 | dp = dp->child; | 199 | dp = dp->child; |
184 | while (dp) { | 200 | while (dp) { |
185 | struct sbus_dev *sdev; | 201 | struct sbus_dev *sdev; |
186 | 202 | ||
187 | sdev = kzalloc(sizeof(struct sbus_dev), GFP_ATOMIC); | 203 | sdev = kzalloc(sizeof(struct sbus_dev), GFP_ATOMIC); |
188 | if (sdev) { | 204 | if (sdev) { |
189 | sdev_insert(sdev, &parent->child); | 205 | sdev_insert(sdev, &parent->child); |
190 | 206 | ||
191 | sdev->bus = sbus; | 207 | sdev->bus = sbus; |
192 | sdev->parent = parent; | 208 | sdev->parent = parent; |
193 | 209 | ||
194 | fill_sbus_device(dp, sdev); | 210 | fill_sbus_device(dp, sdev); |
195 | 211 | ||
196 | walk_children(dp, sdev, sbus); | 212 | walk_children(dp, sdev, sbus); |
197 | } | 213 | } |
198 | dp = dp->sibling; | 214 | dp = dp->sibling; |
199 | } | 215 | } |
200 | } | 216 | } |
201 | 217 | ||
202 | static void __init build_one_sbus(struct device_node *dp, int num_sbus) | 218 | static void __init build_one_sbus(struct device_node *dp, int num_sbus) |
203 | { | 219 | { |
204 | struct sbus_bus *sbus; | 220 | struct sbus_bus *sbus; |
205 | unsigned int sbus_clock; | 221 | unsigned int sbus_clock; |
206 | struct device_node *dev_dp; | 222 | struct device_node *dev_dp; |
207 | 223 | ||
208 | sbus = kzalloc(sizeof(struct sbus_bus), GFP_ATOMIC); | 224 | sbus = kzalloc(sizeof(struct sbus_bus), GFP_ATOMIC); |
209 | if (!sbus) | 225 | if (!sbus) |
210 | return; | 226 | return; |
211 | 227 | ||
212 | sbus_insert(sbus, &sbus_root); | 228 | sbus_insert(sbus, &sbus_root); |
213 | sbus->prom_node = dp->node; | 229 | sbus->prom_node = dp->node; |
214 | 230 | ||
215 | sbus_setup_iommu(sbus, dp); | 231 | sbus_setup_iommu(sbus, dp); |
216 | 232 | ||
217 | printk("sbus%d: ", num_sbus); | 233 | printk("sbus%d: ", num_sbus); |
218 | 234 | ||
219 | sbus_clock = of_getintprop_default(dp, "clock-frequency", | 235 | sbus_clock = of_getintprop_default(dp, "clock-frequency", |
220 | (25*1000*1000)); | 236 | (25*1000*1000)); |
221 | sbus->clock_freq = sbus_clock; | 237 | sbus->clock_freq = sbus_clock; |
222 | 238 | ||
223 | printk("Clock %d.%d MHz\n", (int) ((sbus_clock/1000)/1000), | 239 | printk("Clock %d.%d MHz\n", (int) ((sbus_clock/1000)/1000), |
224 | (int) (((sbus_clock/1000)%1000 != 0) ? | 240 | (int) (((sbus_clock/1000)%1000 != 0) ? |
225 | (((sbus_clock/1000)%1000) + 1000) : 0)); | 241 | (((sbus_clock/1000)%1000) + 1000) : 0)); |
226 | 242 | ||
227 | strcpy(sbus->prom_name, dp->name); | 243 | strcpy(sbus->prom_name, dp->name); |
228 | 244 | ||
229 | sbus_setup_arch_props(sbus, dp); | 245 | sbus_setup_arch_props(sbus, dp); |
230 | 246 | ||
231 | sbus_bus_ranges_init(dp, sbus); | 247 | sbus_bus_ranges_init(dp, sbus); |
232 | 248 | ||
233 | sbus->ofdev.node = dp; | 249 | sbus->ofdev.node = dp; |
234 | sbus->ofdev.dev.parent = NULL; | 250 | sbus->ofdev.dev.parent = NULL; |
235 | sbus->ofdev.dev.bus = &sbus_bus_type; | 251 | sbus->ofdev.dev.bus = &sbus_bus_type; |
236 | sprintf(sbus->ofdev.dev.bus_id, "sbus%d", num_sbus); | 252 | sprintf(sbus->ofdev.dev.bus_id, "sbus%d", num_sbus); |
237 | 253 | ||
238 | if (of_device_register(&sbus->ofdev) != 0) | 254 | if (of_device_register(&sbus->ofdev) != 0) |
239 | printk(KERN_DEBUG "sbus: device registration error for %s!\n", | 255 | printk(KERN_DEBUG "sbus: device registration error for %s!\n", |
240 | sbus->ofdev.dev.bus_id); | 256 | sbus->ofdev.dev.bus_id); |
241 | 257 | ||
242 | dev_dp = dp->child; | 258 | dev_dp = dp->child; |
243 | while (dev_dp) { | 259 | while (dev_dp) { |
244 | struct sbus_dev *sdev; | 260 | struct sbus_dev *sdev; |
245 | 261 | ||
246 | sdev = kzalloc(sizeof(struct sbus_dev), GFP_ATOMIC); | 262 | sdev = kzalloc(sizeof(struct sbus_dev), GFP_ATOMIC); |
247 | if (sdev) { | 263 | if (sdev) { |
248 | sdev_insert(sdev, &sbus->devices); | 264 | sdev_insert(sdev, &sbus->devices); |
249 | 265 | ||
250 | sdev->bus = sbus; | 266 | sdev->bus = sbus; |
251 | sdev->parent = NULL; | 267 | sdev->parent = NULL; |
252 | fill_sbus_device(dev_dp, sdev); | 268 | fill_sbus_device(dev_dp, sdev); |
253 | 269 | ||
254 | walk_children(dev_dp, sdev, sbus); | 270 | walk_children(dev_dp, sdev, sbus); |
255 | } | 271 | } |
256 | dev_dp = dev_dp->sibling; | 272 | dev_dp = dev_dp->sibling; |
257 | } | 273 | } |
258 | 274 | ||
259 | sbus_fixup_all_regs(sbus->devices); | 275 | sbus_fixup_all_regs(sbus->devices); |
260 | 276 | ||
261 | dvma_init(sbus); | 277 | dvma_init(sbus); |
262 | } | 278 | } |
263 | 279 | ||
264 | static int __init sbus_init(void) | 280 | static int __init sbus_init(void) |
265 | { | 281 | { |
266 | struct device_node *dp; | 282 | struct device_node *dp; |
267 | const char *sbus_name = "sbus"; | 283 | const char *sbus_name = "sbus"; |
268 | int num_sbus = 0; | 284 | int num_sbus = 0; |
269 | 285 | ||
270 | if (sbus_arch_preinit()) | 286 | if (sbus_arch_preinit()) |
271 | return 0; | 287 | return 0; |
272 | 288 | ||
273 | if (sparc_cpu_model == sun4d) | 289 | if (sparc_cpu_model == sun4d) |
274 | sbus_name = "sbi"; | 290 | sbus_name = "sbi"; |
275 | 291 | ||
276 | for_each_node_by_name(dp, sbus_name) { | 292 | for_each_node_by_name(dp, sbus_name) { |
277 | build_one_sbus(dp, num_sbus); | 293 | build_one_sbus(dp, num_sbus); |
278 | num_sbus++; | 294 | num_sbus++; |
279 | 295 | ||
280 | } | 296 | } |
281 | 297 | ||
282 | sbus_arch_postinit(); | 298 | sbus_arch_postinit(); |
283 | 299 | ||
284 | return 0; | 300 | return 0; |
285 | } | 301 | } |
286 | 302 | ||
287 | subsys_initcall(sbus_init); | 303 | subsys_initcall(sbus_init); |
288 | 304 |
fs/partitions/check.c
1 | /* | 1 | /* |
2 | * fs/partitions/check.c | 2 | * fs/partitions/check.c |
3 | * | 3 | * |
4 | * Code extracted from drivers/block/genhd.c | 4 | * Code extracted from drivers/block/genhd.c |
5 | * Copyright (C) 1991-1998 Linus Torvalds | 5 | * Copyright (C) 1991-1998 Linus Torvalds |
6 | * Re-organised Feb 1998 Russell King | 6 | * Re-organised Feb 1998 Russell King |
7 | * | 7 | * |
8 | * We now have independent partition support from the | 8 | * We now have independent partition support from the |
9 | * block drivers, which allows all the partition code to | 9 | * block drivers, which allows all the partition code to |
10 | * be grouped in one location, and it to be mostly self | 10 | * be grouped in one location, and it to be mostly self |
11 | * contained. | 11 | * contained. |
12 | * | 12 | * |
13 | * Added needed MAJORS for new pairs, {hdi,hdj}, {hdk,hdl} | 13 | * Added needed MAJORS for new pairs, {hdi,hdj}, {hdk,hdl} |
14 | */ | 14 | */ |
15 | 15 | ||
16 | #include <linux/init.h> | 16 | #include <linux/init.h> |
17 | #include <linux/module.h> | 17 | #include <linux/module.h> |
18 | #include <linux/fs.h> | 18 | #include <linux/fs.h> |
19 | #include <linux/kmod.h> | 19 | #include <linux/kmod.h> |
20 | #include <linux/ctype.h> | 20 | #include <linux/ctype.h> |
21 | 21 | ||
22 | #include "check.h" | 22 | #include "check.h" |
23 | 23 | ||
24 | #include "acorn.h" | 24 | #include "acorn.h" |
25 | #include "amiga.h" | 25 | #include "amiga.h" |
26 | #include "atari.h" | 26 | #include "atari.h" |
27 | #include "ldm.h" | 27 | #include "ldm.h" |
28 | #include "mac.h" | 28 | #include "mac.h" |
29 | #include "msdos.h" | 29 | #include "msdos.h" |
30 | #include "osf.h" | 30 | #include "osf.h" |
31 | #include "sgi.h" | 31 | #include "sgi.h" |
32 | #include "sun.h" | 32 | #include "sun.h" |
33 | #include "ibm.h" | 33 | #include "ibm.h" |
34 | #include "ultrix.h" | 34 | #include "ultrix.h" |
35 | #include "efi.h" | 35 | #include "efi.h" |
36 | #include "karma.h" | 36 | #include "karma.h" |
37 | 37 | ||
38 | #ifdef CONFIG_BLK_DEV_MD | 38 | #ifdef CONFIG_BLK_DEV_MD |
39 | extern void md_autodetect_dev(dev_t dev); | 39 | extern void md_autodetect_dev(dev_t dev); |
40 | #endif | 40 | #endif |
41 | 41 | ||
42 | int warn_no_part = 1; /*This is ugly: should make genhd removable media aware*/ | 42 | int warn_no_part = 1; /*This is ugly: should make genhd removable media aware*/ |
43 | 43 | ||
44 | static int (*check_part[])(struct parsed_partitions *, struct block_device *) = { | 44 | static int (*check_part[])(struct parsed_partitions *, struct block_device *) = { |
45 | /* | 45 | /* |
46 | * Probe partition formats with tables at disk address 0 | 46 | * Probe partition formats with tables at disk address 0 |
47 | * that also have an ADFS boot block at 0xdc0. | 47 | * that also have an ADFS boot block at 0xdc0. |
48 | */ | 48 | */ |
49 | #ifdef CONFIG_ACORN_PARTITION_ICS | 49 | #ifdef CONFIG_ACORN_PARTITION_ICS |
50 | adfspart_check_ICS, | 50 | adfspart_check_ICS, |
51 | #endif | 51 | #endif |
52 | #ifdef CONFIG_ACORN_PARTITION_POWERTEC | 52 | #ifdef CONFIG_ACORN_PARTITION_POWERTEC |
53 | adfspart_check_POWERTEC, | 53 | adfspart_check_POWERTEC, |
54 | #endif | 54 | #endif |
55 | #ifdef CONFIG_ACORN_PARTITION_EESOX | 55 | #ifdef CONFIG_ACORN_PARTITION_EESOX |
56 | adfspart_check_EESOX, | 56 | adfspart_check_EESOX, |
57 | #endif | 57 | #endif |
58 | 58 | ||
59 | /* | 59 | /* |
60 | * Now move on to formats that only have partition info at | 60 | * Now move on to formats that only have partition info at |
61 | * disk address 0xdc0. Since these may also have stale | 61 | * disk address 0xdc0. Since these may also have stale |
62 | * PC/BIOS partition tables, they need to come before | 62 | * PC/BIOS partition tables, they need to come before |
63 | * the msdos entry. | 63 | * the msdos entry. |
64 | */ | 64 | */ |
65 | #ifdef CONFIG_ACORN_PARTITION_CUMANA | 65 | #ifdef CONFIG_ACORN_PARTITION_CUMANA |
66 | adfspart_check_CUMANA, | 66 | adfspart_check_CUMANA, |
67 | #endif | 67 | #endif |
68 | #ifdef CONFIG_ACORN_PARTITION_ADFS | 68 | #ifdef CONFIG_ACORN_PARTITION_ADFS |
69 | adfspart_check_ADFS, | 69 | adfspart_check_ADFS, |
70 | #endif | 70 | #endif |
71 | 71 | ||
72 | #ifdef CONFIG_EFI_PARTITION | 72 | #ifdef CONFIG_EFI_PARTITION |
73 | efi_partition, /* this must come before msdos */ | 73 | efi_partition, /* this must come before msdos */ |
74 | #endif | 74 | #endif |
75 | #ifdef CONFIG_SGI_PARTITION | 75 | #ifdef CONFIG_SGI_PARTITION |
76 | sgi_partition, | 76 | sgi_partition, |
77 | #endif | 77 | #endif |
78 | #ifdef CONFIG_LDM_PARTITION | 78 | #ifdef CONFIG_LDM_PARTITION |
79 | ldm_partition, /* this must come before msdos */ | 79 | ldm_partition, /* this must come before msdos */ |
80 | #endif | 80 | #endif |
81 | #ifdef CONFIG_MSDOS_PARTITION | 81 | #ifdef CONFIG_MSDOS_PARTITION |
82 | msdos_partition, | 82 | msdos_partition, |
83 | #endif | 83 | #endif |
84 | #ifdef CONFIG_OSF_PARTITION | 84 | #ifdef CONFIG_OSF_PARTITION |
85 | osf_partition, | 85 | osf_partition, |
86 | #endif | 86 | #endif |
87 | #ifdef CONFIG_SUN_PARTITION | 87 | #ifdef CONFIG_SUN_PARTITION |
88 | sun_partition, | 88 | sun_partition, |
89 | #endif | 89 | #endif |
90 | #ifdef CONFIG_AMIGA_PARTITION | 90 | #ifdef CONFIG_AMIGA_PARTITION |
91 | amiga_partition, | 91 | amiga_partition, |
92 | #endif | 92 | #endif |
93 | #ifdef CONFIG_ATARI_PARTITION | 93 | #ifdef CONFIG_ATARI_PARTITION |
94 | atari_partition, | 94 | atari_partition, |
95 | #endif | 95 | #endif |
96 | #ifdef CONFIG_MAC_PARTITION | 96 | #ifdef CONFIG_MAC_PARTITION |
97 | mac_partition, | 97 | mac_partition, |
98 | #endif | 98 | #endif |
99 | #ifdef CONFIG_ULTRIX_PARTITION | 99 | #ifdef CONFIG_ULTRIX_PARTITION |
100 | ultrix_partition, | 100 | ultrix_partition, |
101 | #endif | 101 | #endif |
102 | #ifdef CONFIG_IBM_PARTITION | 102 | #ifdef CONFIG_IBM_PARTITION |
103 | ibm_partition, | 103 | ibm_partition, |
104 | #endif | 104 | #endif |
105 | #ifdef CONFIG_KARMA_PARTITION | 105 | #ifdef CONFIG_KARMA_PARTITION |
106 | karma_partition, | 106 | karma_partition, |
107 | #endif | 107 | #endif |
108 | NULL | 108 | NULL |
109 | }; | 109 | }; |
110 | 110 | ||
111 | /* | 111 | /* |
112 | * disk_name() is used by partition check code and the genhd driver. | 112 | * disk_name() is used by partition check code and the genhd driver. |
113 | * It formats the devicename of the indicated disk into | 113 | * It formats the devicename of the indicated disk into |
114 | * the supplied buffer (of size at least 32), and returns | 114 | * the supplied buffer (of size at least 32), and returns |
115 | * a pointer to that same buffer (for convenience). | 115 | * a pointer to that same buffer (for convenience). |
116 | */ | 116 | */ |
117 | 117 | ||
118 | char *disk_name(struct gendisk *hd, int part, char *buf) | 118 | char *disk_name(struct gendisk *hd, int part, char *buf) |
119 | { | 119 | { |
120 | if (!part) | 120 | if (!part) |
121 | snprintf(buf, BDEVNAME_SIZE, "%s", hd->disk_name); | 121 | snprintf(buf, BDEVNAME_SIZE, "%s", hd->disk_name); |
122 | else if (isdigit(hd->disk_name[strlen(hd->disk_name)-1])) | 122 | else if (isdigit(hd->disk_name[strlen(hd->disk_name)-1])) |
123 | snprintf(buf, BDEVNAME_SIZE, "%sp%d", hd->disk_name, part); | 123 | snprintf(buf, BDEVNAME_SIZE, "%sp%d", hd->disk_name, part); |
124 | else | 124 | else |
125 | snprintf(buf, BDEVNAME_SIZE, "%s%d", hd->disk_name, part); | 125 | snprintf(buf, BDEVNAME_SIZE, "%s%d", hd->disk_name, part); |
126 | 126 | ||
127 | return buf; | 127 | return buf; |
128 | } | 128 | } |
129 | 129 | ||
130 | const char *bdevname(struct block_device *bdev, char *buf) | 130 | const char *bdevname(struct block_device *bdev, char *buf) |
131 | { | 131 | { |
132 | int part = MINOR(bdev->bd_dev) - bdev->bd_disk->first_minor; | 132 | int part = MINOR(bdev->bd_dev) - bdev->bd_disk->first_minor; |
133 | return disk_name(bdev->bd_disk, part, buf); | 133 | return disk_name(bdev->bd_disk, part, buf); |
134 | } | 134 | } |
135 | 135 | ||
136 | EXPORT_SYMBOL(bdevname); | 136 | EXPORT_SYMBOL(bdevname); |
137 | 137 | ||
138 | /* | 138 | /* |
139 | * There's very little reason to use this, you should really | 139 | * There's very little reason to use this, you should really |
140 | * have a struct block_device just about everywhere and use | 140 | * have a struct block_device just about everywhere and use |
141 | * bdevname() instead. | 141 | * bdevname() instead. |
142 | */ | 142 | */ |
143 | const char *__bdevname(dev_t dev, char *buffer) | 143 | const char *__bdevname(dev_t dev, char *buffer) |
144 | { | 144 | { |
145 | scnprintf(buffer, BDEVNAME_SIZE, "unknown-block(%u,%u)", | 145 | scnprintf(buffer, BDEVNAME_SIZE, "unknown-block(%u,%u)", |
146 | MAJOR(dev), MINOR(dev)); | 146 | MAJOR(dev), MINOR(dev)); |
147 | return buffer; | 147 | return buffer; |
148 | } | 148 | } |
149 | 149 | ||
150 | EXPORT_SYMBOL(__bdevname); | 150 | EXPORT_SYMBOL(__bdevname); |
151 | 151 | ||
152 | static struct parsed_partitions * | 152 | static struct parsed_partitions * |
153 | check_partition(struct gendisk *hd, struct block_device *bdev) | 153 | check_partition(struct gendisk *hd, struct block_device *bdev) |
154 | { | 154 | { |
155 | struct parsed_partitions *state; | 155 | struct parsed_partitions *state; |
156 | int i, res, err; | 156 | int i, res, err; |
157 | 157 | ||
158 | state = kmalloc(sizeof(struct parsed_partitions), GFP_KERNEL); | 158 | state = kmalloc(sizeof(struct parsed_partitions), GFP_KERNEL); |
159 | if (!state) | 159 | if (!state) |
160 | return NULL; | 160 | return NULL; |
161 | 161 | ||
162 | disk_name(hd, 0, state->name); | 162 | disk_name(hd, 0, state->name); |
163 | printk(KERN_INFO " %s:", state->name); | 163 | printk(KERN_INFO " %s:", state->name); |
164 | if (isdigit(state->name[strlen(state->name)-1])) | 164 | if (isdigit(state->name[strlen(state->name)-1])) |
165 | sprintf(state->name, "p"); | 165 | sprintf(state->name, "p"); |
166 | 166 | ||
167 | state->limit = hd->minors; | 167 | state->limit = hd->minors; |
168 | i = res = err = 0; | 168 | i = res = err = 0; |
169 | while (!res && check_part[i]) { | 169 | while (!res && check_part[i]) { |
170 | memset(&state->parts, 0, sizeof(state->parts)); | 170 | memset(&state->parts, 0, sizeof(state->parts)); |
171 | res = check_part[i++](state, bdev); | 171 | res = check_part[i++](state, bdev); |
172 | if (res < 0) { | 172 | if (res < 0) { |
173 | /* We have hit an I/O error which we don't report now. | 173 | /* We have hit an I/O error which we don't report now. |
174 | * But record it, and let the others do their job. | 174 | * But record it, and let the others do their job. |
175 | */ | 175 | */ |
176 | err = res; | 176 | err = res; |
177 | res = 0; | 177 | res = 0; |
178 | } | 178 | } |
179 | 179 | ||
180 | } | 180 | } |
181 | if (res > 0) | 181 | if (res > 0) |
182 | return state; | 182 | return state; |
183 | if (!err) | 183 | if (!err) |
184 | /* The partition is unrecognized. So report I/O errors if there were any */ | 184 | /* The partition is unrecognized. So report I/O errors if there were any */ |
185 | res = err; | 185 | res = err; |
186 | if (!res) | 186 | if (!res) |
187 | printk(" unknown partition table\n"); | 187 | printk(" unknown partition table\n"); |
188 | else if (warn_no_part) | 188 | else if (warn_no_part) |
189 | printk(" unable to read partition table\n"); | 189 | printk(" unable to read partition table\n"); |
190 | kfree(state); | 190 | kfree(state); |
191 | return ERR_PTR(res); | 191 | return ERR_PTR(res); |
192 | } | 192 | } |
193 | 193 | ||
194 | /* | 194 | /* |
195 | * sysfs bindings for partitions | 195 | * sysfs bindings for partitions |
196 | */ | 196 | */ |
197 | 197 | ||
198 | struct part_attribute { | 198 | struct part_attribute { |
199 | struct attribute attr; | 199 | struct attribute attr; |
200 | ssize_t (*show)(struct hd_struct *,char *); | 200 | ssize_t (*show)(struct hd_struct *,char *); |
201 | ssize_t (*store)(struct hd_struct *,const char *, size_t); | 201 | ssize_t (*store)(struct hd_struct *,const char *, size_t); |
202 | }; | 202 | }; |
203 | 203 | ||
204 | static ssize_t | 204 | static ssize_t |
205 | part_attr_show(struct kobject * kobj, struct attribute * attr, char * page) | 205 | part_attr_show(struct kobject * kobj, struct attribute * attr, char * page) |
206 | { | 206 | { |
207 | struct hd_struct * p = container_of(kobj,struct hd_struct,kobj); | 207 | struct hd_struct * p = container_of(kobj,struct hd_struct,kobj); |
208 | struct part_attribute * part_attr = container_of(attr,struct part_attribute,attr); | 208 | struct part_attribute * part_attr = container_of(attr,struct part_attribute,attr); |
209 | ssize_t ret = 0; | 209 | ssize_t ret = 0; |
210 | if (part_attr->show) | 210 | if (part_attr->show) |
211 | ret = part_attr->show(p, page); | 211 | ret = part_attr->show(p, page); |
212 | return ret; | 212 | return ret; |
213 | } | 213 | } |
214 | static ssize_t | 214 | static ssize_t |
215 | part_attr_store(struct kobject * kobj, struct attribute * attr, | 215 | part_attr_store(struct kobject * kobj, struct attribute * attr, |
216 | const char *page, size_t count) | 216 | const char *page, size_t count) |
217 | { | 217 | { |
218 | struct hd_struct * p = container_of(kobj,struct hd_struct,kobj); | 218 | struct hd_struct * p = container_of(kobj,struct hd_struct,kobj); |
219 | struct part_attribute * part_attr = container_of(attr,struct part_attribute,attr); | 219 | struct part_attribute * part_attr = container_of(attr,struct part_attribute,attr); |
220 | ssize_t ret = 0; | 220 | ssize_t ret = 0; |
221 | 221 | ||
222 | if (part_attr->store) | 222 | if (part_attr->store) |
223 | ret = part_attr->store(p, page, count); | 223 | ret = part_attr->store(p, page, count); |
224 | return ret; | 224 | return ret; |
225 | } | 225 | } |
226 | 226 | ||
227 | static struct sysfs_ops part_sysfs_ops = { | 227 | static struct sysfs_ops part_sysfs_ops = { |
228 | .show = part_attr_show, | 228 | .show = part_attr_show, |
229 | .store = part_attr_store, | 229 | .store = part_attr_store, |
230 | }; | 230 | }; |
231 | 231 | ||
232 | static ssize_t part_uevent_store(struct hd_struct * p, | 232 | static ssize_t part_uevent_store(struct hd_struct * p, |
233 | const char *page, size_t count) | 233 | const char *page, size_t count) |
234 | { | 234 | { |
235 | kobject_uevent(&p->kobj, KOBJ_ADD); | 235 | kobject_uevent(&p->kobj, KOBJ_ADD); |
236 | return count; | 236 | return count; |
237 | } | 237 | } |
238 | static ssize_t part_dev_read(struct hd_struct * p, char *page) | 238 | static ssize_t part_dev_read(struct hd_struct * p, char *page) |
239 | { | 239 | { |
240 | struct gendisk *disk = container_of(p->kobj.parent,struct gendisk,kobj); | 240 | struct gendisk *disk = container_of(p->kobj.parent,struct gendisk,kobj); |
241 | dev_t dev = MKDEV(disk->major, disk->first_minor + p->partno); | 241 | dev_t dev = MKDEV(disk->major, disk->first_minor + p->partno); |
242 | return print_dev_t(page, dev); | 242 | return print_dev_t(page, dev); |
243 | } | 243 | } |
244 | static ssize_t part_start_read(struct hd_struct * p, char *page) | 244 | static ssize_t part_start_read(struct hd_struct * p, char *page) |
245 | { | 245 | { |
246 | return sprintf(page, "%llu\n",(unsigned long long)p->start_sect); | 246 | return sprintf(page, "%llu\n",(unsigned long long)p->start_sect); |
247 | } | 247 | } |
248 | static ssize_t part_size_read(struct hd_struct * p, char *page) | 248 | static ssize_t part_size_read(struct hd_struct * p, char *page) |
249 | { | 249 | { |
250 | return sprintf(page, "%llu\n",(unsigned long long)p->nr_sects); | 250 | return sprintf(page, "%llu\n",(unsigned long long)p->nr_sects); |
251 | } | 251 | } |
252 | static ssize_t part_stat_read(struct hd_struct * p, char *page) | 252 | static ssize_t part_stat_read(struct hd_struct * p, char *page) |
253 | { | 253 | { |
254 | return sprintf(page, "%8u %8llu %8u %8llu\n", | 254 | return sprintf(page, "%8u %8llu %8u %8llu\n", |
255 | p->ios[0], (unsigned long long)p->sectors[0], | 255 | p->ios[0], (unsigned long long)p->sectors[0], |
256 | p->ios[1], (unsigned long long)p->sectors[1]); | 256 | p->ios[1], (unsigned long long)p->sectors[1]); |
257 | } | 257 | } |
258 | static struct part_attribute part_attr_uevent = { | 258 | static struct part_attribute part_attr_uevent = { |
259 | .attr = {.name = "uevent", .mode = S_IWUSR }, | 259 | .attr = {.name = "uevent", .mode = S_IWUSR }, |
260 | .store = part_uevent_store | 260 | .store = part_uevent_store |
261 | }; | 261 | }; |
262 | static struct part_attribute part_attr_dev = { | 262 | static struct part_attribute part_attr_dev = { |
263 | .attr = {.name = "dev", .mode = S_IRUGO }, | 263 | .attr = {.name = "dev", .mode = S_IRUGO }, |
264 | .show = part_dev_read | 264 | .show = part_dev_read |
265 | }; | 265 | }; |
266 | static struct part_attribute part_attr_start = { | 266 | static struct part_attribute part_attr_start = { |
267 | .attr = {.name = "start", .mode = S_IRUGO }, | 267 | .attr = {.name = "start", .mode = S_IRUGO }, |
268 | .show = part_start_read | 268 | .show = part_start_read |
269 | }; | 269 | }; |
270 | static struct part_attribute part_attr_size = { | 270 | static struct part_attribute part_attr_size = { |
271 | .attr = {.name = "size", .mode = S_IRUGO }, | 271 | .attr = {.name = "size", .mode = S_IRUGO }, |
272 | .show = part_size_read | 272 | .show = part_size_read |
273 | }; | 273 | }; |
274 | static struct part_attribute part_attr_stat = { | 274 | static struct part_attribute part_attr_stat = { |
275 | .attr = {.name = "stat", .mode = S_IRUGO }, | 275 | .attr = {.name = "stat", .mode = S_IRUGO }, |
276 | .show = part_stat_read | 276 | .show = part_stat_read |
277 | }; | 277 | }; |
278 | 278 | ||
279 | #ifdef CONFIG_FAIL_MAKE_REQUEST | 279 | #ifdef CONFIG_FAIL_MAKE_REQUEST |
280 | 280 | ||
281 | static ssize_t part_fail_store(struct hd_struct * p, | 281 | static ssize_t part_fail_store(struct hd_struct * p, |
282 | const char *buf, size_t count) | 282 | const char *buf, size_t count) |
283 | { | 283 | { |
284 | int i; | 284 | int i; |
285 | 285 | ||
286 | if (count > 0 && sscanf(buf, "%d", &i) > 0) | 286 | if (count > 0 && sscanf(buf, "%d", &i) > 0) |
287 | p->make_it_fail = (i == 0) ? 0 : 1; | 287 | p->make_it_fail = (i == 0) ? 0 : 1; |
288 | 288 | ||
289 | return count; | 289 | return count; |
290 | } | 290 | } |
291 | static ssize_t part_fail_read(struct hd_struct * p, char *page) | 291 | static ssize_t part_fail_read(struct hd_struct * p, char *page) |
292 | { | 292 | { |
293 | return sprintf(page, "%d\n", p->make_it_fail); | 293 | return sprintf(page, "%d\n", p->make_it_fail); |
294 | } | 294 | } |
295 | static struct part_attribute part_attr_fail = { | 295 | static struct part_attribute part_attr_fail = { |
296 | .attr = {.name = "make-it-fail", .mode = S_IRUGO | S_IWUSR }, | 296 | .attr = {.name = "make-it-fail", .mode = S_IRUGO | S_IWUSR }, |
297 | .store = part_fail_store, | 297 | .store = part_fail_store, |
298 | .show = part_fail_read | 298 | .show = part_fail_read |
299 | }; | 299 | }; |
300 | 300 | ||
301 | #endif | 301 | #endif |
302 | 302 | ||
303 | static struct attribute * default_attrs[] = { | 303 | static struct attribute * default_attrs[] = { |
304 | &part_attr_uevent.attr, | 304 | &part_attr_uevent.attr, |
305 | &part_attr_dev.attr, | 305 | &part_attr_dev.attr, |
306 | &part_attr_start.attr, | 306 | &part_attr_start.attr, |
307 | &part_attr_size.attr, | 307 | &part_attr_size.attr, |
308 | &part_attr_stat.attr, | 308 | &part_attr_stat.attr, |
309 | #ifdef CONFIG_FAIL_MAKE_REQUEST | 309 | #ifdef CONFIG_FAIL_MAKE_REQUEST |
310 | &part_attr_fail.attr, | 310 | &part_attr_fail.attr, |
311 | #endif | 311 | #endif |
312 | NULL, | 312 | NULL, |
313 | }; | 313 | }; |
314 | 314 | ||
315 | extern struct subsystem block_subsys; | 315 | extern struct subsystem block_subsys; |
316 | 316 | ||
317 | static void part_release(struct kobject *kobj) | 317 | static void part_release(struct kobject *kobj) |
318 | { | 318 | { |
319 | struct hd_struct * p = container_of(kobj,struct hd_struct,kobj); | 319 | struct hd_struct * p = container_of(kobj,struct hd_struct,kobj); |
320 | kfree(p); | 320 | kfree(p); |
321 | } | 321 | } |
322 | 322 | ||
323 | struct kobj_type ktype_part = { | 323 | struct kobj_type ktype_part = { |
324 | .release = part_release, | 324 | .release = part_release, |
325 | .default_attrs = default_attrs, | 325 | .default_attrs = default_attrs, |
326 | .sysfs_ops = &part_sysfs_ops, | 326 | .sysfs_ops = &part_sysfs_ops, |
327 | }; | 327 | }; |
328 | 328 | ||
329 | static inline void partition_sysfs_add_subdir(struct hd_struct *p) | 329 | static inline void partition_sysfs_add_subdir(struct hd_struct *p) |
330 | { | 330 | { |
331 | struct kobject *k; | 331 | struct kobject *k; |
332 | 332 | ||
333 | k = kobject_get(&p->kobj); | 333 | k = kobject_get(&p->kobj); |
334 | p->holder_dir = kobject_add_dir(k, "holders"); | 334 | p->holder_dir = kobject_add_dir(k, "holders"); |
335 | kobject_put(k); | 335 | kobject_put(k); |
336 | } | 336 | } |
337 | 337 | ||
338 | static inline void disk_sysfs_add_subdirs(struct gendisk *disk) | 338 | static inline void disk_sysfs_add_subdirs(struct gendisk *disk) |
339 | { | 339 | { |
340 | struct kobject *k; | 340 | struct kobject *k; |
341 | 341 | ||
342 | k = kobject_get(&disk->kobj); | 342 | k = kobject_get(&disk->kobj); |
343 | disk->holder_dir = kobject_add_dir(k, "holders"); | 343 | disk->holder_dir = kobject_add_dir(k, "holders"); |
344 | disk->slave_dir = kobject_add_dir(k, "slaves"); | 344 | disk->slave_dir = kobject_add_dir(k, "slaves"); |
345 | kobject_put(k); | 345 | kobject_put(k); |
346 | } | 346 | } |
347 | 347 | ||
348 | void delete_partition(struct gendisk *disk, int part) | 348 | void delete_partition(struct gendisk *disk, int part) |
349 | { | 349 | { |
350 | struct hd_struct *p = disk->part[part-1]; | 350 | struct hd_struct *p = disk->part[part-1]; |
351 | if (!p) | 351 | if (!p) |
352 | return; | 352 | return; |
353 | if (!p->nr_sects) | 353 | if (!p->nr_sects) |
354 | return; | 354 | return; |
355 | disk->part[part-1] = NULL; | 355 | disk->part[part-1] = NULL; |
356 | p->start_sect = 0; | 356 | p->start_sect = 0; |
357 | p->nr_sects = 0; | 357 | p->nr_sects = 0; |
358 | p->ios[0] = p->ios[1] = 0; | 358 | p->ios[0] = p->ios[1] = 0; |
359 | p->sectors[0] = p->sectors[1] = 0; | 359 | p->sectors[0] = p->sectors[1] = 0; |
360 | sysfs_remove_link(&p->kobj, "subsystem"); | 360 | sysfs_remove_link(&p->kobj, "subsystem"); |
361 | if (p->holder_dir) | 361 | if (p->holder_dir) |
362 | kobject_unregister(p->holder_dir); | 362 | kobject_unregister(p->holder_dir); |
363 | kobject_uevent(&p->kobj, KOBJ_REMOVE); | 363 | kobject_uevent(&p->kobj, KOBJ_REMOVE); |
364 | kobject_del(&p->kobj); | 364 | kobject_del(&p->kobj); |
365 | kobject_put(&p->kobj); | 365 | kobject_put(&p->kobj); |
366 | } | 366 | } |
367 | 367 | ||
368 | void add_partition(struct gendisk *disk, int part, sector_t start, sector_t len) | 368 | void add_partition(struct gendisk *disk, int part, sector_t start, sector_t len, int flags) |
369 | { | 369 | { |
370 | struct hd_struct *p; | 370 | struct hd_struct *p; |
371 | 371 | ||
372 | p = kmalloc(sizeof(*p), GFP_KERNEL); | 372 | p = kmalloc(sizeof(*p), GFP_KERNEL); |
373 | if (!p) | 373 | if (!p) |
374 | return; | 374 | return; |
375 | 375 | ||
376 | memset(p, 0, sizeof(*p)); | 376 | memset(p, 0, sizeof(*p)); |
377 | p->start_sect = start; | 377 | p->start_sect = start; |
378 | p->nr_sects = len; | 378 | p->nr_sects = len; |
379 | p->partno = part; | 379 | p->partno = part; |
380 | p->policy = disk->policy; | 380 | p->policy = disk->policy; |
381 | 381 | ||
382 | if (isdigit(disk->kobj.name[strlen(disk->kobj.name)-1])) | 382 | if (isdigit(disk->kobj.name[strlen(disk->kobj.name)-1])) |
383 | snprintf(p->kobj.name,KOBJ_NAME_LEN,"%sp%d",disk->kobj.name,part); | 383 | snprintf(p->kobj.name,KOBJ_NAME_LEN,"%sp%d",disk->kobj.name,part); |
384 | else | 384 | else |
385 | snprintf(p->kobj.name,KOBJ_NAME_LEN,"%s%d",disk->kobj.name,part); | 385 | snprintf(p->kobj.name,KOBJ_NAME_LEN,"%s%d",disk->kobj.name,part); |
386 | p->kobj.parent = &disk->kobj; | 386 | p->kobj.parent = &disk->kobj; |
387 | p->kobj.ktype = &ktype_part; | 387 | p->kobj.ktype = &ktype_part; |
388 | kobject_init(&p->kobj); | 388 | kobject_init(&p->kobj); |
389 | kobject_add(&p->kobj); | 389 | kobject_add(&p->kobj); |
390 | if (!disk->part_uevent_suppress) | 390 | if (!disk->part_uevent_suppress) |
391 | kobject_uevent(&p->kobj, KOBJ_ADD); | 391 | kobject_uevent(&p->kobj, KOBJ_ADD); |
392 | sysfs_create_link(&p->kobj, &block_subsys.kset.kobj, "subsystem"); | 392 | sysfs_create_link(&p->kobj, &block_subsys.kset.kobj, "subsystem"); |
393 | if (flags & ADDPART_FLAG_WHOLEDISK) { | ||
394 | static struct attribute addpartattr = { | ||
395 | .name = "whole_disk", | ||
396 | .mode = S_IRUSR | S_IRGRP | S_IROTH, | ||
397 | .owner = THIS_MODULE, | ||
398 | }; | ||
399 | |||
400 | sysfs_create_file(&p->kobj, &addpartattr); | ||
401 | } | ||
393 | partition_sysfs_add_subdir(p); | 402 | partition_sysfs_add_subdir(p); |
394 | disk->part[part-1] = p; | 403 | disk->part[part-1] = p; |
395 | } | 404 | } |
396 | 405 | ||
397 | static char *make_block_name(struct gendisk *disk) | 406 | static char *make_block_name(struct gendisk *disk) |
398 | { | 407 | { |
399 | char *name; | 408 | char *name; |
400 | static char *block_str = "block:"; | 409 | static char *block_str = "block:"; |
401 | int size; | 410 | int size; |
402 | char *s; | 411 | char *s; |
403 | 412 | ||
404 | size = strlen(block_str) + strlen(disk->disk_name) + 1; | 413 | size = strlen(block_str) + strlen(disk->disk_name) + 1; |
405 | name = kmalloc(size, GFP_KERNEL); | 414 | name = kmalloc(size, GFP_KERNEL); |
406 | if (!name) | 415 | if (!name) |
407 | return NULL; | 416 | return NULL; |
408 | strcpy(name, block_str); | 417 | strcpy(name, block_str); |
409 | strcat(name, disk->disk_name); | 418 | strcat(name, disk->disk_name); |
410 | /* ewww... some of these buggers have / in name... */ | 419 | /* ewww... some of these buggers have / in name... */ |
411 | s = strchr(name, '/'); | 420 | s = strchr(name, '/'); |
412 | if (s) | 421 | if (s) |
413 | *s = '!'; | 422 | *s = '!'; |
414 | return name; | 423 | return name; |
415 | } | 424 | } |
416 | 425 | ||
417 | static int disk_sysfs_symlinks(struct gendisk *disk) | 426 | static int disk_sysfs_symlinks(struct gendisk *disk) |
418 | { | 427 | { |
419 | struct device *target = get_device(disk->driverfs_dev); | 428 | struct device *target = get_device(disk->driverfs_dev); |
420 | int err; | 429 | int err; |
421 | char *disk_name = NULL; | 430 | char *disk_name = NULL; |
422 | 431 | ||
423 | if (target) { | 432 | if (target) { |
424 | disk_name = make_block_name(disk); | 433 | disk_name = make_block_name(disk); |
425 | if (!disk_name) { | 434 | if (!disk_name) { |
426 | err = -ENOMEM; | 435 | err = -ENOMEM; |
427 | goto err_out; | 436 | goto err_out; |
428 | } | 437 | } |
429 | 438 | ||
430 | err = sysfs_create_link(&disk->kobj, &target->kobj, "device"); | 439 | err = sysfs_create_link(&disk->kobj, &target->kobj, "device"); |
431 | if (err) | 440 | if (err) |
432 | goto err_out_disk_name; | 441 | goto err_out_disk_name; |
433 | 442 | ||
434 | err = sysfs_create_link(&target->kobj, &disk->kobj, disk_name); | 443 | err = sysfs_create_link(&target->kobj, &disk->kobj, disk_name); |
435 | if (err) | 444 | if (err) |
436 | goto err_out_dev_link; | 445 | goto err_out_dev_link; |
437 | } | 446 | } |
438 | 447 | ||
439 | err = sysfs_create_link(&disk->kobj, &block_subsys.kset.kobj, | 448 | err = sysfs_create_link(&disk->kobj, &block_subsys.kset.kobj, |
440 | "subsystem"); | 449 | "subsystem"); |
441 | if (err) | 450 | if (err) |
442 | goto err_out_disk_name_lnk; | 451 | goto err_out_disk_name_lnk; |
443 | 452 | ||
444 | kfree(disk_name); | 453 | kfree(disk_name); |
445 | 454 | ||
446 | return 0; | 455 | return 0; |
447 | 456 | ||
448 | err_out_disk_name_lnk: | 457 | err_out_disk_name_lnk: |
449 | if (target) { | 458 | if (target) { |
450 | sysfs_remove_link(&target->kobj, disk_name); | 459 | sysfs_remove_link(&target->kobj, disk_name); |
451 | err_out_dev_link: | 460 | err_out_dev_link: |
452 | sysfs_remove_link(&disk->kobj, "device"); | 461 | sysfs_remove_link(&disk->kobj, "device"); |
453 | err_out_disk_name: | 462 | err_out_disk_name: |
454 | kfree(disk_name); | 463 | kfree(disk_name); |
455 | err_out: | 464 | err_out: |
456 | put_device(target); | 465 | put_device(target); |
457 | } | 466 | } |
458 | return err; | 467 | return err; |
459 | } | 468 | } |
460 | 469 | ||
461 | /* Not exported, helper to add_disk(). */ | 470 | /* Not exported, helper to add_disk(). */ |
462 | void register_disk(struct gendisk *disk) | 471 | void register_disk(struct gendisk *disk) |
463 | { | 472 | { |
464 | struct block_device *bdev; | 473 | struct block_device *bdev; |
465 | char *s; | 474 | char *s; |
466 | int i; | 475 | int i; |
467 | struct hd_struct *p; | 476 | struct hd_struct *p; |
468 | int err; | 477 | int err; |
469 | 478 | ||
470 | strlcpy(disk->kobj.name,disk->disk_name,KOBJ_NAME_LEN); | 479 | strlcpy(disk->kobj.name,disk->disk_name,KOBJ_NAME_LEN); |
471 | /* ewww... some of these buggers have / in name... */ | 480 | /* ewww... some of these buggers have / in name... */ |
472 | s = strchr(disk->kobj.name, '/'); | 481 | s = strchr(disk->kobj.name, '/'); |
473 | if (s) | 482 | if (s) |
474 | *s = '!'; | 483 | *s = '!'; |
475 | if ((err = kobject_add(&disk->kobj))) | 484 | if ((err = kobject_add(&disk->kobj))) |
476 | return; | 485 | return; |
477 | err = disk_sysfs_symlinks(disk); | 486 | err = disk_sysfs_symlinks(disk); |
478 | if (err) { | 487 | if (err) { |
479 | kobject_del(&disk->kobj); | 488 | kobject_del(&disk->kobj); |
480 | return; | 489 | return; |
481 | } | 490 | } |
482 | disk_sysfs_add_subdirs(disk); | 491 | disk_sysfs_add_subdirs(disk); |
483 | 492 | ||
484 | /* No minors to use for partitions */ | 493 | /* No minors to use for partitions */ |
485 | if (disk->minors == 1) | 494 | if (disk->minors == 1) |
486 | goto exit; | 495 | goto exit; |
487 | 496 | ||
488 | /* No such device (e.g., media were just removed) */ | 497 | /* No such device (e.g., media were just removed) */ |
489 | if (!get_capacity(disk)) | 498 | if (!get_capacity(disk)) |
490 | goto exit; | 499 | goto exit; |
491 | 500 | ||
492 | bdev = bdget_disk(disk, 0); | 501 | bdev = bdget_disk(disk, 0); |
493 | if (!bdev) | 502 | if (!bdev) |
494 | goto exit; | 503 | goto exit; |
495 | 504 | ||
496 | /* scan partition table, but suppress uevents */ | 505 | /* scan partition table, but suppress uevents */ |
497 | bdev->bd_invalidated = 1; | 506 | bdev->bd_invalidated = 1; |
498 | disk->part_uevent_suppress = 1; | 507 | disk->part_uevent_suppress = 1; |
499 | err = blkdev_get(bdev, FMODE_READ, 0); | 508 | err = blkdev_get(bdev, FMODE_READ, 0); |
500 | disk->part_uevent_suppress = 0; | 509 | disk->part_uevent_suppress = 0; |
501 | if (err < 0) | 510 | if (err < 0) |
502 | goto exit; | 511 | goto exit; |
503 | blkdev_put(bdev); | 512 | blkdev_put(bdev); |
504 | 513 | ||
505 | exit: | 514 | exit: |
506 | /* announce disk after possible partitions are already created */ | 515 | /* announce disk after possible partitions are already created */ |
507 | kobject_uevent(&disk->kobj, KOBJ_ADD); | 516 | kobject_uevent(&disk->kobj, KOBJ_ADD); |
508 | 517 | ||
509 | /* announce possible partitions */ | 518 | /* announce possible partitions */ |
510 | for (i = 1; i < disk->minors; i++) { | 519 | for (i = 1; i < disk->minors; i++) { |
511 | p = disk->part[i-1]; | 520 | p = disk->part[i-1]; |
512 | if (!p || !p->nr_sects) | 521 | if (!p || !p->nr_sects) |
513 | continue; | 522 | continue; |
514 | kobject_uevent(&p->kobj, KOBJ_ADD); | 523 | kobject_uevent(&p->kobj, KOBJ_ADD); |
515 | } | 524 | } |
516 | } | 525 | } |
517 | 526 | ||
518 | int rescan_partitions(struct gendisk *disk, struct block_device *bdev) | 527 | int rescan_partitions(struct gendisk *disk, struct block_device *bdev) |
519 | { | 528 | { |
520 | struct parsed_partitions *state; | 529 | struct parsed_partitions *state; |
521 | int p, res; | 530 | int p, res; |
522 | 531 | ||
523 | if (bdev->bd_part_count) | 532 | if (bdev->bd_part_count) |
524 | return -EBUSY; | 533 | return -EBUSY; |
525 | res = invalidate_partition(disk, 0); | 534 | res = invalidate_partition(disk, 0); |
526 | if (res) | 535 | if (res) |
527 | return res; | 536 | return res; |
528 | bdev->bd_invalidated = 0; | 537 | bdev->bd_invalidated = 0; |
529 | for (p = 1; p < disk->minors; p++) | 538 | for (p = 1; p < disk->minors; p++) |
530 | delete_partition(disk, p); | 539 | delete_partition(disk, p); |
531 | if (disk->fops->revalidate_disk) | 540 | if (disk->fops->revalidate_disk) |
532 | disk->fops->revalidate_disk(disk); | 541 | disk->fops->revalidate_disk(disk); |
533 | if (!get_capacity(disk) || !(state = check_partition(disk, bdev))) | 542 | if (!get_capacity(disk) || !(state = check_partition(disk, bdev))) |
534 | return 0; | 543 | return 0; |
535 | if (IS_ERR(state)) /* I/O error reading the partition table */ | 544 | if (IS_ERR(state)) /* I/O error reading the partition table */ |
536 | return PTR_ERR(state); | 545 | return PTR_ERR(state); |
537 | for (p = 1; p < state->limit; p++) { | 546 | for (p = 1; p < state->limit; p++) { |
538 | sector_t size = state->parts[p].size; | 547 | sector_t size = state->parts[p].size; |
539 | sector_t from = state->parts[p].from; | 548 | sector_t from = state->parts[p].from; |
540 | if (!size) | 549 | if (!size) |
541 | continue; | 550 | continue; |
542 | if (from + size > get_capacity(disk)) { | 551 | if (from + size > get_capacity(disk)) { |
543 | printk(" %s: p%d exceeds device capacity\n", | 552 | printk(" %s: p%d exceeds device capacity\n", |
544 | disk->disk_name, p); | 553 | disk->disk_name, p); |
545 | } | 554 | } |
546 | add_partition(disk, p, from, size); | 555 | add_partition(disk, p, from, size, state->parts[p].flags); |
547 | #ifdef CONFIG_BLK_DEV_MD | 556 | #ifdef CONFIG_BLK_DEV_MD |
548 | if (state->parts[p].flags) | 557 | if (state->parts[p].flags & ADDPART_FLAG_RAID) |
549 | md_autodetect_dev(bdev->bd_dev+p); | 558 | md_autodetect_dev(bdev->bd_dev+p); |
550 | #endif | 559 | #endif |
551 | } | 560 | } |
552 | kfree(state); | 561 | kfree(state); |
553 | return 0; | 562 | return 0; |
554 | } | 563 | } |
555 | 564 | ||
556 | unsigned char *read_dev_sector(struct block_device *bdev, sector_t n, Sector *p) | 565 | unsigned char *read_dev_sector(struct block_device *bdev, sector_t n, Sector *p) |
557 | { | 566 | { |
558 | struct address_space *mapping = bdev->bd_inode->i_mapping; | 567 | struct address_space *mapping = bdev->bd_inode->i_mapping; |
559 | struct page *page; | 568 | struct page *page; |
560 | 569 | ||
561 | page = read_mapping_page(mapping, (pgoff_t)(n >> (PAGE_CACHE_SHIFT-9)), | 570 | page = read_mapping_page(mapping, (pgoff_t)(n >> (PAGE_CACHE_SHIFT-9)), |
562 | NULL); | 571 | NULL); |
563 | if (!IS_ERR(page)) { | 572 | if (!IS_ERR(page)) { |
564 | wait_on_page_locked(page); | 573 | wait_on_page_locked(page); |
565 | if (!PageUptodate(page)) | 574 | if (!PageUptodate(page)) |
566 | goto fail; | 575 | goto fail; |
567 | if (PageError(page)) | 576 | if (PageError(page)) |
568 | goto fail; | 577 | goto fail; |
569 | p->v = page; | 578 | p->v = page; |
570 | return (unsigned char *)page_address(page) + ((n & ((1 << (PAGE_CACHE_SHIFT - 9)) - 1)) << 9); | 579 | return (unsigned char *)page_address(page) + ((n & ((1 << (PAGE_CACHE_SHIFT - 9)) - 1)) << 9); |
571 | fail: | 580 | fail: |
572 | page_cache_release(page); | 581 | page_cache_release(page); |
573 | } | 582 | } |
574 | p->v = NULL; | 583 | p->v = NULL; |
575 | return NULL; | 584 | return NULL; |
576 | } | 585 | } |
577 | 586 | ||
578 | EXPORT_SYMBOL(read_dev_sector); | 587 | EXPORT_SYMBOL(read_dev_sector); |
579 | 588 | ||
580 | void del_gendisk(struct gendisk *disk) | 589 | void del_gendisk(struct gendisk *disk) |
581 | { | 590 | { |
582 | int p; | 591 | int p; |
583 | 592 | ||
584 | /* invalidate stuff */ | 593 | /* invalidate stuff */ |
585 | for (p = disk->minors - 1; p > 0; p--) { | 594 | for (p = disk->minors - 1; p > 0; p--) { |
586 | invalidate_partition(disk, p); | 595 | invalidate_partition(disk, p); |
587 | delete_partition(disk, p); | 596 | delete_partition(disk, p); |
588 | } | 597 | } |
589 | invalidate_partition(disk, 0); | 598 | invalidate_partition(disk, 0); |
590 | disk->capacity = 0; | 599 | disk->capacity = 0; |
591 | disk->flags &= ~GENHD_FL_UP; | 600 | disk->flags &= ~GENHD_FL_UP; |
592 | unlink_gendisk(disk); | 601 | unlink_gendisk(disk); |
593 | disk_stat_set_all(disk, 0); | 602 | disk_stat_set_all(disk, 0); |
594 | disk->stamp = 0; | 603 | disk->stamp = 0; |
595 | 604 | ||
596 | kobject_uevent(&disk->kobj, KOBJ_REMOVE); | 605 | kobject_uevent(&disk->kobj, KOBJ_REMOVE); |
597 | if (disk->holder_dir) | 606 | if (disk->holder_dir) |
598 | kobject_unregister(disk->holder_dir); | 607 | kobject_unregister(disk->holder_dir); |
599 | if (disk->slave_dir) | 608 | if (disk->slave_dir) |
600 | kobject_unregister(disk->slave_dir); | 609 | kobject_unregister(disk->slave_dir); |
601 | if (disk->driverfs_dev) { | 610 | if (disk->driverfs_dev) { |
602 | char *disk_name = make_block_name(disk); | 611 | char *disk_name = make_block_name(disk); |
603 | sysfs_remove_link(&disk->kobj, "device"); | 612 | sysfs_remove_link(&disk->kobj, "device"); |
604 | if (disk_name) { | 613 | if (disk_name) { |
605 | sysfs_remove_link(&disk->driverfs_dev->kobj, disk_name); | 614 | sysfs_remove_link(&disk->driverfs_dev->kobj, disk_name); |
606 | kfree(disk_name); | 615 | kfree(disk_name); |
607 | } | 616 | } |
608 | put_device(disk->driverfs_dev); | 617 | put_device(disk->driverfs_dev); |
609 | disk->driverfs_dev = NULL; | 618 | disk->driverfs_dev = NULL; |
610 | } | 619 | } |
611 | sysfs_remove_link(&disk->kobj, "subsystem"); | 620 | sysfs_remove_link(&disk->kobj, "subsystem"); |
612 | kobject_del(&disk->kobj); | 621 | kobject_del(&disk->kobj); |
613 | } | 622 | } |
614 | 623 |
fs/partitions/msdos.c
1 | /* | 1 | /* |
2 | * fs/partitions/msdos.c | 2 | * fs/partitions/msdos.c |
3 | * | 3 | * |
4 | * Code extracted from drivers/block/genhd.c | 4 | * Code extracted from drivers/block/genhd.c |
5 | * Copyright (C) 1991-1998 Linus Torvalds | 5 | * Copyright (C) 1991-1998 Linus Torvalds |
6 | * | 6 | * |
7 | * Thanks to Branko Lankester, lankeste@fwi.uva.nl, who found a bug | 7 | * Thanks to Branko Lankester, lankeste@fwi.uva.nl, who found a bug |
8 | * in the early extended-partition checks and added DM partitions | 8 | * in the early extended-partition checks and added DM partitions |
9 | * | 9 | * |
10 | * Support for DiskManager v6.0x added by Mark Lord, | 10 | * Support for DiskManager v6.0x added by Mark Lord, |
11 | * with information provided by OnTrack. This now works for linux fdisk | 11 | * with information provided by OnTrack. This now works for linux fdisk |
12 | * and LILO, as well as loadlin and bootln. Note that disks other than | 12 | * and LILO, as well as loadlin and bootln. Note that disks other than |
13 | * /dev/hda *must* have a "DOS" type 0x51 partition in the first slot (hda1). | 13 | * /dev/hda *must* have a "DOS" type 0x51 partition in the first slot (hda1). |
14 | * | 14 | * |
15 | * More flexible handling of extended partitions - aeb, 950831 | 15 | * More flexible handling of extended partitions - aeb, 950831 |
16 | * | 16 | * |
17 | * Check partition table on IDE disks for common CHS translations | 17 | * Check partition table on IDE disks for common CHS translations |
18 | * | 18 | * |
19 | * Re-organised Feb 1998 Russell King | 19 | * Re-organised Feb 1998 Russell King |
20 | */ | 20 | */ |
21 | 21 | ||
22 | 22 | ||
23 | #include "check.h" | 23 | #include "check.h" |
24 | #include "msdos.h" | 24 | #include "msdos.h" |
25 | #include "efi.h" | 25 | #include "efi.h" |
26 | 26 | ||
27 | /* | 27 | /* |
28 | * Many architectures don't like unaligned accesses, while | 28 | * Many architectures don't like unaligned accesses, while |
29 | * the nr_sects and start_sect partition table entries are | 29 | * the nr_sects and start_sect partition table entries are |
30 | * at a 2 (mod 4) address. | 30 | * at a 2 (mod 4) address. |
31 | */ | 31 | */ |
32 | #include <asm/unaligned.h> | 32 | #include <asm/unaligned.h> |
33 | 33 | ||
34 | #define SYS_IND(p) (get_unaligned(&p->sys_ind)) | 34 | #define SYS_IND(p) (get_unaligned(&p->sys_ind)) |
35 | #define NR_SECTS(p) ({ __le32 __a = get_unaligned(&p->nr_sects); \ | 35 | #define NR_SECTS(p) ({ __le32 __a = get_unaligned(&p->nr_sects); \ |
36 | le32_to_cpu(__a); \ | 36 | le32_to_cpu(__a); \ |
37 | }) | 37 | }) |
38 | 38 | ||
39 | #define START_SECT(p) ({ __le32 __a = get_unaligned(&p->start_sect); \ | 39 | #define START_SECT(p) ({ __le32 __a = get_unaligned(&p->start_sect); \ |
40 | le32_to_cpu(__a); \ | 40 | le32_to_cpu(__a); \ |
41 | }) | 41 | }) |
42 | 42 | ||
43 | static inline int is_extended_partition(struct partition *p) | 43 | static inline int is_extended_partition(struct partition *p) |
44 | { | 44 | { |
45 | return (SYS_IND(p) == DOS_EXTENDED_PARTITION || | 45 | return (SYS_IND(p) == DOS_EXTENDED_PARTITION || |
46 | SYS_IND(p) == WIN98_EXTENDED_PARTITION || | 46 | SYS_IND(p) == WIN98_EXTENDED_PARTITION || |
47 | SYS_IND(p) == LINUX_EXTENDED_PARTITION); | 47 | SYS_IND(p) == LINUX_EXTENDED_PARTITION); |
48 | } | 48 | } |
49 | 49 | ||
50 | #define MSDOS_LABEL_MAGIC1 0x55 | 50 | #define MSDOS_LABEL_MAGIC1 0x55 |
51 | #define MSDOS_LABEL_MAGIC2 0xAA | 51 | #define MSDOS_LABEL_MAGIC2 0xAA |
52 | 52 | ||
53 | static inline int | 53 | static inline int |
54 | msdos_magic_present(unsigned char *p) | 54 | msdos_magic_present(unsigned char *p) |
55 | { | 55 | { |
56 | return (p[0] == MSDOS_LABEL_MAGIC1 && p[1] == MSDOS_LABEL_MAGIC2); | 56 | return (p[0] == MSDOS_LABEL_MAGIC1 && p[1] == MSDOS_LABEL_MAGIC2); |
57 | } | 57 | } |
58 | 58 | ||
59 | /* Value is EBCDIC 'IBMA' */ | 59 | /* Value is EBCDIC 'IBMA' */ |
60 | #define AIX_LABEL_MAGIC1 0xC9 | 60 | #define AIX_LABEL_MAGIC1 0xC9 |
61 | #define AIX_LABEL_MAGIC2 0xC2 | 61 | #define AIX_LABEL_MAGIC2 0xC2 |
62 | #define AIX_LABEL_MAGIC3 0xD4 | 62 | #define AIX_LABEL_MAGIC3 0xD4 |
63 | #define AIX_LABEL_MAGIC4 0xC1 | 63 | #define AIX_LABEL_MAGIC4 0xC1 |
64 | static int aix_magic_present(unsigned char *p, struct block_device *bdev) | 64 | static int aix_magic_present(unsigned char *p, struct block_device *bdev) |
65 | { | 65 | { |
66 | struct partition *pt = (struct partition *) (p + 0x1be); | 66 | struct partition *pt = (struct partition *) (p + 0x1be); |
67 | Sector sect; | 67 | Sector sect; |
68 | unsigned char *d; | 68 | unsigned char *d; |
69 | int slot, ret = 0; | 69 | int slot, ret = 0; |
70 | 70 | ||
71 | if (!(p[0] == AIX_LABEL_MAGIC1 && | 71 | if (!(p[0] == AIX_LABEL_MAGIC1 && |
72 | p[1] == AIX_LABEL_MAGIC2 && | 72 | p[1] == AIX_LABEL_MAGIC2 && |
73 | p[2] == AIX_LABEL_MAGIC3 && | 73 | p[2] == AIX_LABEL_MAGIC3 && |
74 | p[3] == AIX_LABEL_MAGIC4)) | 74 | p[3] == AIX_LABEL_MAGIC4)) |
75 | return 0; | 75 | return 0; |
76 | /* Assume the partition table is valid if Linux partitions exists */ | 76 | /* Assume the partition table is valid if Linux partitions exists */ |
77 | for (slot = 1; slot <= 4; slot++, pt++) { | 77 | for (slot = 1; slot <= 4; slot++, pt++) { |
78 | if (pt->sys_ind == LINUX_SWAP_PARTITION || | 78 | if (pt->sys_ind == LINUX_SWAP_PARTITION || |
79 | pt->sys_ind == LINUX_RAID_PARTITION || | 79 | pt->sys_ind == LINUX_RAID_PARTITION || |
80 | pt->sys_ind == LINUX_DATA_PARTITION || | 80 | pt->sys_ind == LINUX_DATA_PARTITION || |
81 | pt->sys_ind == LINUX_LVM_PARTITION || | 81 | pt->sys_ind == LINUX_LVM_PARTITION || |
82 | is_extended_partition(pt)) | 82 | is_extended_partition(pt)) |
83 | return 0; | 83 | return 0; |
84 | } | 84 | } |
85 | d = read_dev_sector(bdev, 7, §); | 85 | d = read_dev_sector(bdev, 7, §); |
86 | if (d) { | 86 | if (d) { |
87 | if (d[0] == '_' && d[1] == 'L' && d[2] == 'V' && d[3] == 'M') | 87 | if (d[0] == '_' && d[1] == 'L' && d[2] == 'V' && d[3] == 'M') |
88 | ret = 1; | 88 | ret = 1; |
89 | put_dev_sector(sect); | 89 | put_dev_sector(sect); |
90 | }; | 90 | }; |
91 | return ret; | 91 | return ret; |
92 | } | 92 | } |
93 | 93 | ||
94 | /* | 94 | /* |
95 | * Create devices for each logical partition in an extended partition. | 95 | * Create devices for each logical partition in an extended partition. |
96 | * The logical partitions form a linked list, with each entry being | 96 | * The logical partitions form a linked list, with each entry being |
97 | * a partition table with two entries. The first entry | 97 | * a partition table with two entries. The first entry |
98 | * is the real data partition (with a start relative to the partition | 98 | * is the real data partition (with a start relative to the partition |
99 | * table start). The second is a pointer to the next logical partition | 99 | * table start). The second is a pointer to the next logical partition |
100 | * (with a start relative to the entire extended partition). | 100 | * (with a start relative to the entire extended partition). |
101 | * We do not create a Linux partition for the partition tables, but | 101 | * We do not create a Linux partition for the partition tables, but |
102 | * only for the actual data partitions. | 102 | * only for the actual data partitions. |
103 | */ | 103 | */ |
104 | 104 | ||
105 | static void | 105 | static void |
106 | parse_extended(struct parsed_partitions *state, struct block_device *bdev, | 106 | parse_extended(struct parsed_partitions *state, struct block_device *bdev, |
107 | u32 first_sector, u32 first_size) | 107 | u32 first_sector, u32 first_size) |
108 | { | 108 | { |
109 | struct partition *p; | 109 | struct partition *p; |
110 | Sector sect; | 110 | Sector sect; |
111 | unsigned char *data; | 111 | unsigned char *data; |
112 | u32 this_sector, this_size; | 112 | u32 this_sector, this_size; |
113 | int sector_size = bdev_hardsect_size(bdev) / 512; | 113 | int sector_size = bdev_hardsect_size(bdev) / 512; |
114 | int loopct = 0; /* number of links followed | 114 | int loopct = 0; /* number of links followed |
115 | without finding a data partition */ | 115 | without finding a data partition */ |
116 | int i; | 116 | int i; |
117 | 117 | ||
118 | this_sector = first_sector; | 118 | this_sector = first_sector; |
119 | this_size = first_size; | 119 | this_size = first_size; |
120 | 120 | ||
121 | while (1) { | 121 | while (1) { |
122 | if (++loopct > 100) | 122 | if (++loopct > 100) |
123 | return; | 123 | return; |
124 | if (state->next == state->limit) | 124 | if (state->next == state->limit) |
125 | return; | 125 | return; |
126 | data = read_dev_sector(bdev, this_sector, §); | 126 | data = read_dev_sector(bdev, this_sector, §); |
127 | if (!data) | 127 | if (!data) |
128 | return; | 128 | return; |
129 | 129 | ||
130 | if (!msdos_magic_present(data + 510)) | 130 | if (!msdos_magic_present(data + 510)) |
131 | goto done; | 131 | goto done; |
132 | 132 | ||
133 | p = (struct partition *) (data + 0x1be); | 133 | p = (struct partition *) (data + 0x1be); |
134 | 134 | ||
135 | /* | 135 | /* |
136 | * Usually, the first entry is the real data partition, | 136 | * Usually, the first entry is the real data partition, |
137 | * the 2nd entry is the next extended partition, or empty, | 137 | * the 2nd entry is the next extended partition, or empty, |
138 | * and the 3rd and 4th entries are unused. | 138 | * and the 3rd and 4th entries are unused. |
139 | * However, DRDOS sometimes has the extended partition as | 139 | * However, DRDOS sometimes has the extended partition as |
140 | * the first entry (when the data partition is empty), | 140 | * the first entry (when the data partition is empty), |
141 | * and OS/2 seems to use all four entries. | 141 | * and OS/2 seems to use all four entries. |
142 | */ | 142 | */ |
143 | 143 | ||
144 | /* | 144 | /* |
145 | * First process the data partition(s) | 145 | * First process the data partition(s) |
146 | */ | 146 | */ |
147 | for (i=0; i<4; i++, p++) { | 147 | for (i=0; i<4; i++, p++) { |
148 | u32 offs, size, next; | 148 | u32 offs, size, next; |
149 | if (!NR_SECTS(p) || is_extended_partition(p)) | 149 | if (!NR_SECTS(p) || is_extended_partition(p)) |
150 | continue; | 150 | continue; |
151 | 151 | ||
152 | /* Check the 3rd and 4th entries - | 152 | /* Check the 3rd and 4th entries - |
153 | these sometimes contain random garbage */ | 153 | these sometimes contain random garbage */ |
154 | offs = START_SECT(p)*sector_size; | 154 | offs = START_SECT(p)*sector_size; |
155 | size = NR_SECTS(p)*sector_size; | 155 | size = NR_SECTS(p)*sector_size; |
156 | next = this_sector + offs; | 156 | next = this_sector + offs; |
157 | if (i >= 2) { | 157 | if (i >= 2) { |
158 | if (offs + size > this_size) | 158 | if (offs + size > this_size) |
159 | continue; | 159 | continue; |
160 | if (next < first_sector) | 160 | if (next < first_sector) |
161 | continue; | 161 | continue; |
162 | if (next + size > first_sector + first_size) | 162 | if (next + size > first_sector + first_size) |
163 | continue; | 163 | continue; |
164 | } | 164 | } |
165 | 165 | ||
166 | put_partition(state, state->next, next, size); | 166 | put_partition(state, state->next, next, size); |
167 | if (SYS_IND(p) == LINUX_RAID_PARTITION) | 167 | if (SYS_IND(p) == LINUX_RAID_PARTITION) |
168 | state->parts[state->next].flags = 1; | 168 | state->parts[state->next].flags = ADDPART_FLAG_RAID; |
169 | loopct = 0; | 169 | loopct = 0; |
170 | if (++state->next == state->limit) | 170 | if (++state->next == state->limit) |
171 | goto done; | 171 | goto done; |
172 | } | 172 | } |
173 | /* | 173 | /* |
174 | * Next, process the (first) extended partition, if present. | 174 | * Next, process the (first) extended partition, if present. |
175 | * (So far, there seems to be no reason to make | 175 | * (So far, there seems to be no reason to make |
176 | * parse_extended() recursive and allow a tree | 176 | * parse_extended() recursive and allow a tree |
177 | * of extended partitions.) | 177 | * of extended partitions.) |
178 | * It should be a link to the next logical partition. | 178 | * It should be a link to the next logical partition. |
179 | */ | 179 | */ |
180 | p -= 4; | 180 | p -= 4; |
181 | for (i=0; i<4; i++, p++) | 181 | for (i=0; i<4; i++, p++) |
182 | if (NR_SECTS(p) && is_extended_partition(p)) | 182 | if (NR_SECTS(p) && is_extended_partition(p)) |
183 | break; | 183 | break; |
184 | if (i == 4) | 184 | if (i == 4) |
185 | goto done; /* nothing left to do */ | 185 | goto done; /* nothing left to do */ |
186 | 186 | ||
187 | this_sector = first_sector + START_SECT(p) * sector_size; | 187 | this_sector = first_sector + START_SECT(p) * sector_size; |
188 | this_size = NR_SECTS(p) * sector_size; | 188 | this_size = NR_SECTS(p) * sector_size; |
189 | put_dev_sector(sect); | 189 | put_dev_sector(sect); |
190 | } | 190 | } |
191 | done: | 191 | done: |
192 | put_dev_sector(sect); | 192 | put_dev_sector(sect); |
193 | } | 193 | } |
194 | 194 | ||
195 | /* james@bpgc.com: Solaris has a nasty indicator: 0x82 which also | 195 | /* james@bpgc.com: Solaris has a nasty indicator: 0x82 which also |
196 | indicates linux swap. Be careful before believing this is Solaris. */ | 196 | indicates linux swap. Be careful before believing this is Solaris. */ |
197 | 197 | ||
198 | static void | 198 | static void |
199 | parse_solaris_x86(struct parsed_partitions *state, struct block_device *bdev, | 199 | parse_solaris_x86(struct parsed_partitions *state, struct block_device *bdev, |
200 | u32 offset, u32 size, int origin) | 200 | u32 offset, u32 size, int origin) |
201 | { | 201 | { |
202 | #ifdef CONFIG_SOLARIS_X86_PARTITION | 202 | #ifdef CONFIG_SOLARIS_X86_PARTITION |
203 | Sector sect; | 203 | Sector sect; |
204 | struct solaris_x86_vtoc *v; | 204 | struct solaris_x86_vtoc *v; |
205 | int i; | 205 | int i; |
206 | 206 | ||
207 | v = (struct solaris_x86_vtoc *)read_dev_sector(bdev, offset+1, §); | 207 | v = (struct solaris_x86_vtoc *)read_dev_sector(bdev, offset+1, §); |
208 | if (!v) | 208 | if (!v) |
209 | return; | 209 | return; |
210 | if (le32_to_cpu(v->v_sanity) != SOLARIS_X86_VTOC_SANE) { | 210 | if (le32_to_cpu(v->v_sanity) != SOLARIS_X86_VTOC_SANE) { |
211 | put_dev_sector(sect); | 211 | put_dev_sector(sect); |
212 | return; | 212 | return; |
213 | } | 213 | } |
214 | printk(" %s%d: <solaris:", state->name, origin); | 214 | printk(" %s%d: <solaris:", state->name, origin); |
215 | if (le32_to_cpu(v->v_version) != 1) { | 215 | if (le32_to_cpu(v->v_version) != 1) { |
216 | printk(" cannot handle version %d vtoc>\n", | 216 | printk(" cannot handle version %d vtoc>\n", |
217 | le32_to_cpu(v->v_version)); | 217 | le32_to_cpu(v->v_version)); |
218 | put_dev_sector(sect); | 218 | put_dev_sector(sect); |
219 | return; | 219 | return; |
220 | } | 220 | } |
221 | for (i=0; i<SOLARIS_X86_NUMSLICE && state->next<state->limit; i++) { | 221 | for (i=0; i<SOLARIS_X86_NUMSLICE && state->next<state->limit; i++) { |
222 | struct solaris_x86_slice *s = &v->v_slice[i]; | 222 | struct solaris_x86_slice *s = &v->v_slice[i]; |
223 | if (s->s_size == 0) | 223 | if (s->s_size == 0) |
224 | continue; | 224 | continue; |
225 | printk(" [s%d]", i); | 225 | printk(" [s%d]", i); |
226 | /* solaris partitions are relative to current MS-DOS | 226 | /* solaris partitions are relative to current MS-DOS |
227 | * one; must add the offset of the current partition */ | 227 | * one; must add the offset of the current partition */ |
228 | put_partition(state, state->next++, | 228 | put_partition(state, state->next++, |
229 | le32_to_cpu(s->s_start)+offset, | 229 | le32_to_cpu(s->s_start)+offset, |
230 | le32_to_cpu(s->s_size)); | 230 | le32_to_cpu(s->s_size)); |
231 | } | 231 | } |
232 | put_dev_sector(sect); | 232 | put_dev_sector(sect); |
233 | printk(" >\n"); | 233 | printk(" >\n"); |
234 | #endif | 234 | #endif |
235 | } | 235 | } |
236 | 236 | ||
237 | #if defined(CONFIG_BSD_DISKLABEL) | 237 | #if defined(CONFIG_BSD_DISKLABEL) |
238 | /* | 238 | /* |
239 | * Create devices for BSD partitions listed in a disklabel, under a | 239 | * Create devices for BSD partitions listed in a disklabel, under a |
240 | * dos-like partition. See parse_extended() for more information. | 240 | * dos-like partition. See parse_extended() for more information. |
241 | */ | 241 | */ |
242 | static void | 242 | static void |
243 | parse_bsd(struct parsed_partitions *state, struct block_device *bdev, | 243 | parse_bsd(struct parsed_partitions *state, struct block_device *bdev, |
244 | u32 offset, u32 size, int origin, char *flavour, | 244 | u32 offset, u32 size, int origin, char *flavour, |
245 | int max_partitions) | 245 | int max_partitions) |
246 | { | 246 | { |
247 | Sector sect; | 247 | Sector sect; |
248 | struct bsd_disklabel *l; | 248 | struct bsd_disklabel *l; |
249 | struct bsd_partition *p; | 249 | struct bsd_partition *p; |
250 | 250 | ||
251 | l = (struct bsd_disklabel *)read_dev_sector(bdev, offset+1, §); | 251 | l = (struct bsd_disklabel *)read_dev_sector(bdev, offset+1, §); |
252 | if (!l) | 252 | if (!l) |
253 | return; | 253 | return; |
254 | if (le32_to_cpu(l->d_magic) != BSD_DISKMAGIC) { | 254 | if (le32_to_cpu(l->d_magic) != BSD_DISKMAGIC) { |
255 | put_dev_sector(sect); | 255 | put_dev_sector(sect); |
256 | return; | 256 | return; |
257 | } | 257 | } |
258 | printk(" %s%d: <%s:", state->name, origin, flavour); | 258 | printk(" %s%d: <%s:", state->name, origin, flavour); |
259 | 259 | ||
260 | if (le16_to_cpu(l->d_npartitions) < max_partitions) | 260 | if (le16_to_cpu(l->d_npartitions) < max_partitions) |
261 | max_partitions = le16_to_cpu(l->d_npartitions); | 261 | max_partitions = le16_to_cpu(l->d_npartitions); |
262 | for (p = l->d_partitions; p - l->d_partitions < max_partitions; p++) { | 262 | for (p = l->d_partitions; p - l->d_partitions < max_partitions; p++) { |
263 | u32 bsd_start, bsd_size; | 263 | u32 bsd_start, bsd_size; |
264 | 264 | ||
265 | if (state->next == state->limit) | 265 | if (state->next == state->limit) |
266 | break; | 266 | break; |
267 | if (p->p_fstype == BSD_FS_UNUSED) | 267 | if (p->p_fstype == BSD_FS_UNUSED) |
268 | continue; | 268 | continue; |
269 | bsd_start = le32_to_cpu(p->p_offset); | 269 | bsd_start = le32_to_cpu(p->p_offset); |
270 | bsd_size = le32_to_cpu(p->p_size); | 270 | bsd_size = le32_to_cpu(p->p_size); |
271 | if (offset == bsd_start && size == bsd_size) | 271 | if (offset == bsd_start && size == bsd_size) |
272 | /* full parent partition, we have it already */ | 272 | /* full parent partition, we have it already */ |
273 | continue; | 273 | continue; |
274 | if (offset > bsd_start || offset+size < bsd_start+bsd_size) { | 274 | if (offset > bsd_start || offset+size < bsd_start+bsd_size) { |
275 | printk("bad subpartition - ignored\n"); | 275 | printk("bad subpartition - ignored\n"); |
276 | continue; | 276 | continue; |
277 | } | 277 | } |
278 | put_partition(state, state->next++, bsd_start, bsd_size); | 278 | put_partition(state, state->next++, bsd_start, bsd_size); |
279 | } | 279 | } |
280 | put_dev_sector(sect); | 280 | put_dev_sector(sect); |
281 | if (le16_to_cpu(l->d_npartitions) > max_partitions) | 281 | if (le16_to_cpu(l->d_npartitions) > max_partitions) |
282 | printk(" (ignored %d more)", | 282 | printk(" (ignored %d more)", |
283 | le16_to_cpu(l->d_npartitions) - max_partitions); | 283 | le16_to_cpu(l->d_npartitions) - max_partitions); |
284 | printk(" >\n"); | 284 | printk(" >\n"); |
285 | } | 285 | } |
286 | #endif | 286 | #endif |
287 | 287 | ||
288 | static void | 288 | static void |
289 | parse_freebsd(struct parsed_partitions *state, struct block_device *bdev, | 289 | parse_freebsd(struct parsed_partitions *state, struct block_device *bdev, |
290 | u32 offset, u32 size, int origin) | 290 | u32 offset, u32 size, int origin) |
291 | { | 291 | { |
292 | #ifdef CONFIG_BSD_DISKLABEL | 292 | #ifdef CONFIG_BSD_DISKLABEL |
293 | parse_bsd(state, bdev, offset, size, origin, | 293 | parse_bsd(state, bdev, offset, size, origin, |
294 | "bsd", BSD_MAXPARTITIONS); | 294 | "bsd", BSD_MAXPARTITIONS); |
295 | #endif | 295 | #endif |
296 | } | 296 | } |
297 | 297 | ||
298 | static void | 298 | static void |
299 | parse_netbsd(struct parsed_partitions *state, struct block_device *bdev, | 299 | parse_netbsd(struct parsed_partitions *state, struct block_device *bdev, |
300 | u32 offset, u32 size, int origin) | 300 | u32 offset, u32 size, int origin) |
301 | { | 301 | { |
302 | #ifdef CONFIG_BSD_DISKLABEL | 302 | #ifdef CONFIG_BSD_DISKLABEL |
303 | parse_bsd(state, bdev, offset, size, origin, | 303 | parse_bsd(state, bdev, offset, size, origin, |
304 | "netbsd", BSD_MAXPARTITIONS); | 304 | "netbsd", BSD_MAXPARTITIONS); |
305 | #endif | 305 | #endif |
306 | } | 306 | } |
307 | 307 | ||
308 | static void | 308 | static void |
309 | parse_openbsd(struct parsed_partitions *state, struct block_device *bdev, | 309 | parse_openbsd(struct parsed_partitions *state, struct block_device *bdev, |
310 | u32 offset, u32 size, int origin) | 310 | u32 offset, u32 size, int origin) |
311 | { | 311 | { |
312 | #ifdef CONFIG_BSD_DISKLABEL | 312 | #ifdef CONFIG_BSD_DISKLABEL |
313 | parse_bsd(state, bdev, offset, size, origin, | 313 | parse_bsd(state, bdev, offset, size, origin, |
314 | "openbsd", OPENBSD_MAXPARTITIONS); | 314 | "openbsd", OPENBSD_MAXPARTITIONS); |
315 | #endif | 315 | #endif |
316 | } | 316 | } |
317 | 317 | ||
318 | /* | 318 | /* |
319 | * Create devices for Unixware partitions listed in a disklabel, under a | 319 | * Create devices for Unixware partitions listed in a disklabel, under a |
320 | * dos-like partition. See parse_extended() for more information. | 320 | * dos-like partition. See parse_extended() for more information. |
321 | */ | 321 | */ |
322 | static void | 322 | static void |
323 | parse_unixware(struct parsed_partitions *state, struct block_device *bdev, | 323 | parse_unixware(struct parsed_partitions *state, struct block_device *bdev, |
324 | u32 offset, u32 size, int origin) | 324 | u32 offset, u32 size, int origin) |
325 | { | 325 | { |
326 | #ifdef CONFIG_UNIXWARE_DISKLABEL | 326 | #ifdef CONFIG_UNIXWARE_DISKLABEL |
327 | Sector sect; | 327 | Sector sect; |
328 | struct unixware_disklabel *l; | 328 | struct unixware_disklabel *l; |
329 | struct unixware_slice *p; | 329 | struct unixware_slice *p; |
330 | 330 | ||
331 | l = (struct unixware_disklabel *)read_dev_sector(bdev, offset+29, §); | 331 | l = (struct unixware_disklabel *)read_dev_sector(bdev, offset+29, §); |
332 | if (!l) | 332 | if (!l) |
333 | return; | 333 | return; |
334 | if (le32_to_cpu(l->d_magic) != UNIXWARE_DISKMAGIC || | 334 | if (le32_to_cpu(l->d_magic) != UNIXWARE_DISKMAGIC || |
335 | le32_to_cpu(l->vtoc.v_magic) != UNIXWARE_DISKMAGIC2) { | 335 | le32_to_cpu(l->vtoc.v_magic) != UNIXWARE_DISKMAGIC2) { |
336 | put_dev_sector(sect); | 336 | put_dev_sector(sect); |
337 | return; | 337 | return; |
338 | } | 338 | } |
339 | printk(" %s%d: <unixware:", state->name, origin); | 339 | printk(" %s%d: <unixware:", state->name, origin); |
340 | p = &l->vtoc.v_slice[1]; | 340 | p = &l->vtoc.v_slice[1]; |
341 | /* I omit the 0th slice as it is the same as whole disk. */ | 341 | /* I omit the 0th slice as it is the same as whole disk. */ |
342 | while (p - &l->vtoc.v_slice[0] < UNIXWARE_NUMSLICE) { | 342 | while (p - &l->vtoc.v_slice[0] < UNIXWARE_NUMSLICE) { |
343 | if (state->next == state->limit) | 343 | if (state->next == state->limit) |
344 | break; | 344 | break; |
345 | 345 | ||
346 | if (p->s_label != UNIXWARE_FS_UNUSED) | 346 | if (p->s_label != UNIXWARE_FS_UNUSED) |
347 | put_partition(state, state->next++, | 347 | put_partition(state, state->next++, |
348 | START_SECT(p), NR_SECTS(p)); | 348 | START_SECT(p), NR_SECTS(p)); |
349 | p++; | 349 | p++; |
350 | } | 350 | } |
351 | put_dev_sector(sect); | 351 | put_dev_sector(sect); |
352 | printk(" >\n"); | 352 | printk(" >\n"); |
353 | #endif | 353 | #endif |
354 | } | 354 | } |
355 | 355 | ||
356 | /* | 356 | /* |
357 | * Minix 2.0.0/2.0.2 subpartition support. | 357 | * Minix 2.0.0/2.0.2 subpartition support. |
358 | * Anand Krishnamurthy <anandk@wiproge.med.ge.com> | 358 | * Anand Krishnamurthy <anandk@wiproge.med.ge.com> |
359 | * Rajeev V. Pillai <rajeevvp@yahoo.com> | 359 | * Rajeev V. Pillai <rajeevvp@yahoo.com> |
360 | */ | 360 | */ |
361 | static void | 361 | static void |
362 | parse_minix(struct parsed_partitions *state, struct block_device *bdev, | 362 | parse_minix(struct parsed_partitions *state, struct block_device *bdev, |
363 | u32 offset, u32 size, int origin) | 363 | u32 offset, u32 size, int origin) |
364 | { | 364 | { |
365 | #ifdef CONFIG_MINIX_SUBPARTITION | 365 | #ifdef CONFIG_MINIX_SUBPARTITION |
366 | Sector sect; | 366 | Sector sect; |
367 | unsigned char *data; | 367 | unsigned char *data; |
368 | struct partition *p; | 368 | struct partition *p; |
369 | int i; | 369 | int i; |
370 | 370 | ||
371 | data = read_dev_sector(bdev, offset, §); | 371 | data = read_dev_sector(bdev, offset, §); |
372 | if (!data) | 372 | if (!data) |
373 | return; | 373 | return; |
374 | 374 | ||
375 | p = (struct partition *)(data + 0x1be); | 375 | p = (struct partition *)(data + 0x1be); |
376 | 376 | ||
377 | /* The first sector of a Minix partition can have either | 377 | /* The first sector of a Minix partition can have either |
378 | * a secondary MBR describing its subpartitions, or | 378 | * a secondary MBR describing its subpartitions, or |
379 | * the normal boot sector. */ | 379 | * the normal boot sector. */ |
380 | if (msdos_magic_present (data + 510) && | 380 | if (msdos_magic_present (data + 510) && |
381 | SYS_IND(p) == MINIX_PARTITION) { /* subpartition table present */ | 381 | SYS_IND(p) == MINIX_PARTITION) { /* subpartition table present */ |
382 | 382 | ||
383 | printk(" %s%d: <minix:", state->name, origin); | 383 | printk(" %s%d: <minix:", state->name, origin); |
384 | for (i = 0; i < MINIX_NR_SUBPARTITIONS; i++, p++) { | 384 | for (i = 0; i < MINIX_NR_SUBPARTITIONS; i++, p++) { |
385 | if (state->next == state->limit) | 385 | if (state->next == state->limit) |
386 | break; | 386 | break; |
387 | /* add each partition in use */ | 387 | /* add each partition in use */ |
388 | if (SYS_IND(p) == MINIX_PARTITION) | 388 | if (SYS_IND(p) == MINIX_PARTITION) |
389 | put_partition(state, state->next++, | 389 | put_partition(state, state->next++, |
390 | START_SECT(p), NR_SECTS(p)); | 390 | START_SECT(p), NR_SECTS(p)); |
391 | } | 391 | } |
392 | printk(" >\n"); | 392 | printk(" >\n"); |
393 | } | 393 | } |
394 | put_dev_sector(sect); | 394 | put_dev_sector(sect); |
395 | #endif /* CONFIG_MINIX_SUBPARTITION */ | 395 | #endif /* CONFIG_MINIX_SUBPARTITION */ |
396 | } | 396 | } |
397 | 397 | ||
398 | static struct { | 398 | static struct { |
399 | unsigned char id; | 399 | unsigned char id; |
400 | void (*parse)(struct parsed_partitions *, struct block_device *, | 400 | void (*parse)(struct parsed_partitions *, struct block_device *, |
401 | u32, u32, int); | 401 | u32, u32, int); |
402 | } subtypes[] = { | 402 | } subtypes[] = { |
403 | {FREEBSD_PARTITION, parse_freebsd}, | 403 | {FREEBSD_PARTITION, parse_freebsd}, |
404 | {NETBSD_PARTITION, parse_netbsd}, | 404 | {NETBSD_PARTITION, parse_netbsd}, |
405 | {OPENBSD_PARTITION, parse_openbsd}, | 405 | {OPENBSD_PARTITION, parse_openbsd}, |
406 | {MINIX_PARTITION, parse_minix}, | 406 | {MINIX_PARTITION, parse_minix}, |
407 | {UNIXWARE_PARTITION, parse_unixware}, | 407 | {UNIXWARE_PARTITION, parse_unixware}, |
408 | {SOLARIS_X86_PARTITION, parse_solaris_x86}, | 408 | {SOLARIS_X86_PARTITION, parse_solaris_x86}, |
409 | {NEW_SOLARIS_X86_PARTITION, parse_solaris_x86}, | 409 | {NEW_SOLARIS_X86_PARTITION, parse_solaris_x86}, |
410 | {0, NULL}, | 410 | {0, NULL}, |
411 | }; | 411 | }; |
412 | 412 | ||
413 | int msdos_partition(struct parsed_partitions *state, struct block_device *bdev) | 413 | int msdos_partition(struct parsed_partitions *state, struct block_device *bdev) |
414 | { | 414 | { |
415 | int sector_size = bdev_hardsect_size(bdev) / 512; | 415 | int sector_size = bdev_hardsect_size(bdev) / 512; |
416 | Sector sect; | 416 | Sector sect; |
417 | unsigned char *data; | 417 | unsigned char *data; |
418 | struct partition *p; | 418 | struct partition *p; |
419 | int slot; | 419 | int slot; |
420 | 420 | ||
421 | data = read_dev_sector(bdev, 0, §); | 421 | data = read_dev_sector(bdev, 0, §); |
422 | if (!data) | 422 | if (!data) |
423 | return -1; | 423 | return -1; |
424 | if (!msdos_magic_present(data + 510)) { | 424 | if (!msdos_magic_present(data + 510)) { |
425 | put_dev_sector(sect); | 425 | put_dev_sector(sect); |
426 | return 0; | 426 | return 0; |
427 | } | 427 | } |
428 | 428 | ||
429 | if (aix_magic_present(data, bdev)) { | 429 | if (aix_magic_present(data, bdev)) { |
430 | put_dev_sector(sect); | 430 | put_dev_sector(sect); |
431 | printk( " [AIX]"); | 431 | printk( " [AIX]"); |
432 | return 0; | 432 | return 0; |
433 | } | 433 | } |
434 | 434 | ||
435 | /* | 435 | /* |
436 | * Now that the 55aa signature is present, this is probably | 436 | * Now that the 55aa signature is present, this is probably |
437 | * either the boot sector of a FAT filesystem or a DOS-type | 437 | * either the boot sector of a FAT filesystem or a DOS-type |
438 | * partition table. Reject this in case the boot indicator | 438 | * partition table. Reject this in case the boot indicator |
439 | * is not 0 or 0x80. | 439 | * is not 0 or 0x80. |
440 | */ | 440 | */ |
441 | p = (struct partition *) (data + 0x1be); | 441 | p = (struct partition *) (data + 0x1be); |
442 | for (slot = 1; slot <= 4; slot++, p++) { | 442 | for (slot = 1; slot <= 4; slot++, p++) { |
443 | if (p->boot_ind != 0 && p->boot_ind != 0x80) { | 443 | if (p->boot_ind != 0 && p->boot_ind != 0x80) { |
444 | put_dev_sector(sect); | 444 | put_dev_sector(sect); |
445 | return 0; | 445 | return 0; |
446 | } | 446 | } |
447 | } | 447 | } |
448 | 448 | ||
449 | #ifdef CONFIG_EFI_PARTITION | 449 | #ifdef CONFIG_EFI_PARTITION |
450 | p = (struct partition *) (data + 0x1be); | 450 | p = (struct partition *) (data + 0x1be); |
451 | for (slot = 1 ; slot <= 4 ; slot++, p++) { | 451 | for (slot = 1 ; slot <= 4 ; slot++, p++) { |
452 | /* If this is an EFI GPT disk, msdos should ignore it. */ | 452 | /* If this is an EFI GPT disk, msdos should ignore it. */ |
453 | if (SYS_IND(p) == EFI_PMBR_OSTYPE_EFI_GPT) { | 453 | if (SYS_IND(p) == EFI_PMBR_OSTYPE_EFI_GPT) { |
454 | put_dev_sector(sect); | 454 | put_dev_sector(sect); |
455 | return 0; | 455 | return 0; |
456 | } | 456 | } |
457 | } | 457 | } |
458 | #endif | 458 | #endif |
459 | p = (struct partition *) (data + 0x1be); | 459 | p = (struct partition *) (data + 0x1be); |
460 | 460 | ||
461 | /* | 461 | /* |
462 | * Look for partitions in two passes: | 462 | * Look for partitions in two passes: |
463 | * First find the primary and DOS-type extended partitions. | 463 | * First find the primary and DOS-type extended partitions. |
464 | * On the second pass look inside *BSD, Unixware and Solaris partitions. | 464 | * On the second pass look inside *BSD, Unixware and Solaris partitions. |
465 | */ | 465 | */ |
466 | 466 | ||
467 | state->next = 5; | 467 | state->next = 5; |
468 | for (slot = 1 ; slot <= 4 ; slot++, p++) { | 468 | for (slot = 1 ; slot <= 4 ; slot++, p++) { |
469 | u32 start = START_SECT(p)*sector_size; | 469 | u32 start = START_SECT(p)*sector_size; |
470 | u32 size = NR_SECTS(p)*sector_size; | 470 | u32 size = NR_SECTS(p)*sector_size; |
471 | if (!size) | 471 | if (!size) |
472 | continue; | 472 | continue; |
473 | if (is_extended_partition(p)) { | 473 | if (is_extended_partition(p)) { |
474 | /* prevent someone doing mkfs or mkswap on an | 474 | /* prevent someone doing mkfs or mkswap on an |
475 | extended partition, but leave room for LILO */ | 475 | extended partition, but leave room for LILO */ |
476 | put_partition(state, slot, start, size == 1 ? 1 : 2); | 476 | put_partition(state, slot, start, size == 1 ? 1 : 2); |
477 | printk(" <"); | 477 | printk(" <"); |
478 | parse_extended(state, bdev, start, size); | 478 | parse_extended(state, bdev, start, size); |
479 | printk(" >"); | 479 | printk(" >"); |
480 | continue; | 480 | continue; |
481 | } | 481 | } |
482 | put_partition(state, slot, start, size); | 482 | put_partition(state, slot, start, size); |
483 | if (SYS_IND(p) == LINUX_RAID_PARTITION) | 483 | if (SYS_IND(p) == LINUX_RAID_PARTITION) |
484 | state->parts[slot].flags = 1; | 484 | state->parts[slot].flags = 1; |
485 | if (SYS_IND(p) == DM6_PARTITION) | 485 | if (SYS_IND(p) == DM6_PARTITION) |
486 | printk("[DM]"); | 486 | printk("[DM]"); |
487 | if (SYS_IND(p) == EZD_PARTITION) | 487 | if (SYS_IND(p) == EZD_PARTITION) |
488 | printk("[EZD]"); | 488 | printk("[EZD]"); |
489 | } | 489 | } |
490 | 490 | ||
491 | printk("\n"); | 491 | printk("\n"); |
492 | 492 | ||
493 | /* second pass - output for each on a separate line */ | 493 | /* second pass - output for each on a separate line */ |
494 | p = (struct partition *) (0x1be + data); | 494 | p = (struct partition *) (0x1be + data); |
495 | for (slot = 1 ; slot <= 4 ; slot++, p++) { | 495 | for (slot = 1 ; slot <= 4 ; slot++, p++) { |
496 | unsigned char id = SYS_IND(p); | 496 | unsigned char id = SYS_IND(p); |
497 | int n; | 497 | int n; |
498 | 498 | ||
499 | if (!NR_SECTS(p)) | 499 | if (!NR_SECTS(p)) |
500 | continue; | 500 | continue; |
501 | 501 | ||
502 | for (n = 0; subtypes[n].parse && id != subtypes[n].id; n++) | 502 | for (n = 0; subtypes[n].parse && id != subtypes[n].id; n++) |
503 | ; | 503 | ; |
504 | 504 | ||
505 | if (!subtypes[n].parse) | 505 | if (!subtypes[n].parse) |
506 | continue; | 506 | continue; |
507 | subtypes[n].parse(state, bdev, START_SECT(p)*sector_size, | 507 | subtypes[n].parse(state, bdev, START_SECT(p)*sector_size, |
508 | NR_SECTS(p)*sector_size, slot); | 508 | NR_SECTS(p)*sector_size, slot); |
509 | } | 509 | } |
510 | put_dev_sector(sect); | 510 | put_dev_sector(sect); |
511 | return 1; | 511 | return 1; |
512 | } | 512 | } |
513 | 513 |
fs/partitions/sgi.c
1 | /* | 1 | /* |
2 | * fs/partitions/sgi.c | 2 | * fs/partitions/sgi.c |
3 | * | 3 | * |
4 | * Code extracted from drivers/block/genhd.c | 4 | * Code extracted from drivers/block/genhd.c |
5 | */ | 5 | */ |
6 | 6 | ||
7 | #include "check.h" | 7 | #include "check.h" |
8 | #include "sgi.h" | 8 | #include "sgi.h" |
9 | 9 | ||
10 | struct sgi_disklabel { | 10 | struct sgi_disklabel { |
11 | __be32 magic_mushroom; /* Big fat spliff... */ | 11 | __be32 magic_mushroom; /* Big fat spliff... */ |
12 | __be16 root_part_num; /* Root partition number */ | 12 | __be16 root_part_num; /* Root partition number */ |
13 | __be16 swap_part_num; /* Swap partition number */ | 13 | __be16 swap_part_num; /* Swap partition number */ |
14 | s8 boot_file[16]; /* Name of boot file for ARCS */ | 14 | s8 boot_file[16]; /* Name of boot file for ARCS */ |
15 | u8 _unused0[48]; /* Device parameter useless crapola.. */ | 15 | u8 _unused0[48]; /* Device parameter useless crapola.. */ |
16 | struct sgi_volume { | 16 | struct sgi_volume { |
17 | s8 name[8]; /* Name of volume */ | 17 | s8 name[8]; /* Name of volume */ |
18 | __be32 block_num; /* Logical block number */ | 18 | __be32 block_num; /* Logical block number */ |
19 | __be32 num_bytes; /* How big, in bytes */ | 19 | __be32 num_bytes; /* How big, in bytes */ |
20 | } volume[15]; | 20 | } volume[15]; |
21 | struct sgi_partition { | 21 | struct sgi_partition { |
22 | __be32 num_blocks; /* Size in logical blocks */ | 22 | __be32 num_blocks; /* Size in logical blocks */ |
23 | __be32 first_block; /* First logical block */ | 23 | __be32 first_block; /* First logical block */ |
24 | __be32 type; /* Type of this partition */ | 24 | __be32 type; /* Type of this partition */ |
25 | } partitions[16]; | 25 | } partitions[16]; |
26 | __be32 csum; /* Disk label checksum */ | 26 | __be32 csum; /* Disk label checksum */ |
27 | __be32 _unused1; /* Padding */ | 27 | __be32 _unused1; /* Padding */ |
28 | }; | 28 | }; |
29 | 29 | ||
30 | int sgi_partition(struct parsed_partitions *state, struct block_device *bdev) | 30 | int sgi_partition(struct parsed_partitions *state, struct block_device *bdev) |
31 | { | 31 | { |
32 | int i, csum; | 32 | int i, csum; |
33 | __be32 magic; | 33 | __be32 magic; |
34 | int slot = 1; | 34 | int slot = 1; |
35 | unsigned int start, blocks; | 35 | unsigned int start, blocks; |
36 | __be32 *ui, cs; | 36 | __be32 *ui, cs; |
37 | Sector sect; | 37 | Sector sect; |
38 | struct sgi_disklabel *label; | 38 | struct sgi_disklabel *label; |
39 | struct sgi_partition *p; | 39 | struct sgi_partition *p; |
40 | char b[BDEVNAME_SIZE]; | 40 | char b[BDEVNAME_SIZE]; |
41 | 41 | ||
42 | label = (struct sgi_disklabel *) read_dev_sector(bdev, 0, §); | 42 | label = (struct sgi_disklabel *) read_dev_sector(bdev, 0, §); |
43 | if (!label) | 43 | if (!label) |
44 | return -1; | 44 | return -1; |
45 | p = &label->partitions[0]; | 45 | p = &label->partitions[0]; |
46 | magic = label->magic_mushroom; | 46 | magic = label->magic_mushroom; |
47 | if(be32_to_cpu(magic) != SGI_LABEL_MAGIC) { | 47 | if(be32_to_cpu(magic) != SGI_LABEL_MAGIC) { |
48 | /*printk("Dev %s SGI disklabel: bad magic %08x\n", | 48 | /*printk("Dev %s SGI disklabel: bad magic %08x\n", |
49 | bdevname(bdev, b), be32_to_cpu(magic));*/ | 49 | bdevname(bdev, b), be32_to_cpu(magic));*/ |
50 | put_dev_sector(sect); | 50 | put_dev_sector(sect); |
51 | return 0; | 51 | return 0; |
52 | } | 52 | } |
53 | ui = ((__be32 *) (label + 1)) - 1; | 53 | ui = ((__be32 *) (label + 1)) - 1; |
54 | for(csum = 0; ui >= ((__be32 *) label);) { | 54 | for(csum = 0; ui >= ((__be32 *) label);) { |
55 | cs = *ui--; | 55 | cs = *ui--; |
56 | csum += be32_to_cpu(cs); | 56 | csum += be32_to_cpu(cs); |
57 | } | 57 | } |
58 | if(csum) { | 58 | if(csum) { |
59 | printk(KERN_WARNING "Dev %s SGI disklabel: csum bad, label corrupted\n", | 59 | printk(KERN_WARNING "Dev %s SGI disklabel: csum bad, label corrupted\n", |
60 | bdevname(bdev, b)); | 60 | bdevname(bdev, b)); |
61 | put_dev_sector(sect); | 61 | put_dev_sector(sect); |
62 | return 0; | 62 | return 0; |
63 | } | 63 | } |
64 | /* All SGI disk labels have 16 partitions, disks under Linux only | 64 | /* All SGI disk labels have 16 partitions, disks under Linux only |
65 | * have 15 minor's. Luckily there are always a few zero length | 65 | * have 15 minor's. Luckily there are always a few zero length |
66 | * partitions which we don't care about so we never overflow the | 66 | * partitions which we don't care about so we never overflow the |
67 | * current_minor. | 67 | * current_minor. |
68 | */ | 68 | */ |
69 | for(i = 0; i < 16; i++, p++) { | 69 | for(i = 0; i < 16; i++, p++) { |
70 | blocks = be32_to_cpu(p->num_blocks); | 70 | blocks = be32_to_cpu(p->num_blocks); |
71 | start = be32_to_cpu(p->first_block); | 71 | start = be32_to_cpu(p->first_block); |
72 | if (blocks) { | 72 | if (blocks) { |
73 | put_partition(state, slot, start, blocks); | 73 | put_partition(state, slot, start, blocks); |
74 | if (be32_to_cpu(p->type) == LINUX_RAID_PARTITION) | 74 | if (be32_to_cpu(p->type) == LINUX_RAID_PARTITION) |
75 | state->parts[slot].flags = 1; | 75 | state->parts[slot].flags = ADDPART_FLAG_RAID; |
76 | } | 76 | } |
77 | slot++; | 77 | slot++; |
78 | } | 78 | } |
79 | printk("\n"); | 79 | printk("\n"); |
80 | put_dev_sector(sect); | 80 | put_dev_sector(sect); |
81 | return 1; | 81 | return 1; |
82 | } | 82 | } |
83 | 83 |
fs/partitions/sun.c
1 | /* | 1 | /* |
2 | * fs/partitions/sun.c | 2 | * fs/partitions/sun.c |
3 | * | 3 | * |
4 | * Code extracted from drivers/block/genhd.c | 4 | * Code extracted from drivers/block/genhd.c |
5 | * | 5 | * |
6 | * Copyright (C) 1991-1998 Linus Torvalds | 6 | * Copyright (C) 1991-1998 Linus Torvalds |
7 | * Re-organised Feb 1998 Russell King | 7 | * Re-organised Feb 1998 Russell King |
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include "check.h" | 10 | #include "check.h" |
11 | #include "sun.h" | 11 | #include "sun.h" |
12 | 12 | ||
13 | int sun_partition(struct parsed_partitions *state, struct block_device *bdev) | 13 | int sun_partition(struct parsed_partitions *state, struct block_device *bdev) |
14 | { | 14 | { |
15 | int i; | 15 | int i; |
16 | __be16 csum; | 16 | __be16 csum; |
17 | int slot = 1; | 17 | int slot = 1; |
18 | __be16 *ush; | 18 | __be16 *ush; |
19 | Sector sect; | 19 | Sector sect; |
20 | struct sun_disklabel { | 20 | struct sun_disklabel { |
21 | unsigned char info[128]; /* Informative text string */ | 21 | unsigned char info[128]; /* Informative text string */ |
22 | unsigned char spare0[14]; | 22 | unsigned char spare0[14]; |
23 | struct sun_info { | 23 | struct sun_info { |
24 | unsigned char spare1; | 24 | unsigned char spare1; |
25 | unsigned char id; | 25 | unsigned char id; |
26 | unsigned char spare2; | 26 | unsigned char spare2; |
27 | unsigned char flags; | 27 | unsigned char flags; |
28 | } infos[8]; | 28 | } infos[8]; |
29 | unsigned char spare[246]; /* Boot information etc. */ | 29 | unsigned char spare[246]; /* Boot information etc. */ |
30 | __be16 rspeed; /* Disk rotational speed */ | 30 | __be16 rspeed; /* Disk rotational speed */ |
31 | __be16 pcylcount; /* Physical cylinder count */ | 31 | __be16 pcylcount; /* Physical cylinder count */ |
32 | __be16 sparecyl; /* extra sects per cylinder */ | 32 | __be16 sparecyl; /* extra sects per cylinder */ |
33 | unsigned char spare2[4]; /* More magic... */ | 33 | unsigned char spare2[4]; /* More magic... */ |
34 | __be16 ilfact; /* Interleave factor */ | 34 | __be16 ilfact; /* Interleave factor */ |
35 | __be16 ncyl; /* Data cylinder count */ | 35 | __be16 ncyl; /* Data cylinder count */ |
36 | __be16 nacyl; /* Alt. cylinder count */ | 36 | __be16 nacyl; /* Alt. cylinder count */ |
37 | __be16 ntrks; /* Tracks per cylinder */ | 37 | __be16 ntrks; /* Tracks per cylinder */ |
38 | __be16 nsect; /* Sectors per track */ | 38 | __be16 nsect; /* Sectors per track */ |
39 | unsigned char spare3[4]; /* Even more magic... */ | 39 | unsigned char spare3[4]; /* Even more magic... */ |
40 | struct sun_partition { | 40 | struct sun_partition { |
41 | __be32 start_cylinder; | 41 | __be32 start_cylinder; |
42 | __be32 num_sectors; | 42 | __be32 num_sectors; |
43 | } partitions[8]; | 43 | } partitions[8]; |
44 | __be16 magic; /* Magic number */ | 44 | __be16 magic; /* Magic number */ |
45 | __be16 csum; /* Label xor'd checksum */ | 45 | __be16 csum; /* Label xor'd checksum */ |
46 | } * label; | 46 | } * label; |
47 | struct sun_partition *p; | 47 | struct sun_partition *p; |
48 | unsigned long spc; | 48 | unsigned long spc; |
49 | char b[BDEVNAME_SIZE]; | 49 | char b[BDEVNAME_SIZE]; |
50 | 50 | ||
51 | label = (struct sun_disklabel *)read_dev_sector(bdev, 0, §); | 51 | label = (struct sun_disklabel *)read_dev_sector(bdev, 0, §); |
52 | if (!label) | 52 | if (!label) |
53 | return -1; | 53 | return -1; |
54 | 54 | ||
55 | p = label->partitions; | 55 | p = label->partitions; |
56 | if (be16_to_cpu(label->magic) != SUN_LABEL_MAGIC) { | 56 | if (be16_to_cpu(label->magic) != SUN_LABEL_MAGIC) { |
57 | /* printk(KERN_INFO "Dev %s Sun disklabel: bad magic %04x\n", | 57 | /* printk(KERN_INFO "Dev %s Sun disklabel: bad magic %04x\n", |
58 | bdevname(bdev, b), be16_to_cpu(label->magic)); */ | 58 | bdevname(bdev, b), be16_to_cpu(label->magic)); */ |
59 | put_dev_sector(sect); | 59 | put_dev_sector(sect); |
60 | return 0; | 60 | return 0; |
61 | } | 61 | } |
62 | /* Look at the checksum */ | 62 | /* Look at the checksum */ |
63 | ush = ((__be16 *) (label+1)) - 1; | 63 | ush = ((__be16 *) (label+1)) - 1; |
64 | for (csum = 0; ush >= ((__be16 *) label);) | 64 | for (csum = 0; ush >= ((__be16 *) label);) |
65 | csum ^= *ush--; | 65 | csum ^= *ush--; |
66 | if (csum) { | 66 | if (csum) { |
67 | printk("Dev %s Sun disklabel: Csum bad, label corrupted\n", | 67 | printk("Dev %s Sun disklabel: Csum bad, label corrupted\n", |
68 | bdevname(bdev, b)); | 68 | bdevname(bdev, b)); |
69 | put_dev_sector(sect); | 69 | put_dev_sector(sect); |
70 | return 0; | 70 | return 0; |
71 | } | 71 | } |
72 | 72 | ||
73 | /* All Sun disks have 8 partition entries */ | 73 | /* All Sun disks have 8 partition entries */ |
74 | spc = be16_to_cpu(label->ntrks) * be16_to_cpu(label->nsect); | 74 | spc = be16_to_cpu(label->ntrks) * be16_to_cpu(label->nsect); |
75 | for (i = 0; i < 8; i++, p++) { | 75 | for (i = 0; i < 8; i++, p++) { |
76 | unsigned long st_sector; | 76 | unsigned long st_sector; |
77 | unsigned int num_sectors; | 77 | unsigned int num_sectors; |
78 | 78 | ||
79 | st_sector = be32_to_cpu(p->start_cylinder) * spc; | 79 | st_sector = be32_to_cpu(p->start_cylinder) * spc; |
80 | num_sectors = be32_to_cpu(p->num_sectors); | 80 | num_sectors = be32_to_cpu(p->num_sectors); |
81 | if (num_sectors) { | 81 | if (num_sectors) { |
82 | put_partition(state, slot, st_sector, num_sectors); | 82 | put_partition(state, slot, st_sector, num_sectors); |
83 | state->parts[slot].flags = 0; | ||
83 | if (label->infos[i].id == LINUX_RAID_PARTITION) | 84 | if (label->infos[i].id == LINUX_RAID_PARTITION) |
84 | state->parts[slot].flags = 1; | 85 | state->parts[slot].flags |= ADDPART_FLAG_RAID; |
86 | if (label->infos[i].id == SUN_WHOLE_DISK) | ||
87 | state->parts[slot].flags |= ADDPART_FLAG_WHOLEDISK; | ||
85 | } | 88 | } |
86 | slot++; | 89 | slot++; |
87 | } | 90 | } |
88 | printk("\n"); | 91 | printk("\n"); |
89 | put_dev_sector(sect); | 92 | put_dev_sector(sect); |
90 | return 1; | 93 | return 1; |
91 | } | 94 | } |
92 | 95 |
include/asm-sparc64/irq.h
1 | /* $Id: irq.h,v 1.21 2002/01/23 11:27:36 davem Exp $ | 1 | /* $Id: irq.h,v 1.21 2002/01/23 11:27:36 davem Exp $ |
2 | * irq.h: IRQ registers on the 64-bit Sparc. | 2 | * irq.h: IRQ registers on the 64-bit Sparc. |
3 | * | 3 | * |
4 | * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) | 4 | * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) |
5 | * Copyright (C) 1998 Jakub Jelinek (jj@ultra.linux.cz) | 5 | * Copyright (C) 1998 Jakub Jelinek (jj@ultra.linux.cz) |
6 | */ | 6 | */ |
7 | 7 | ||
8 | #ifndef _SPARC64_IRQ_H | 8 | #ifndef _SPARC64_IRQ_H |
9 | #define _SPARC64_IRQ_H | 9 | #define _SPARC64_IRQ_H |
10 | 10 | ||
11 | #include <linux/linkage.h> | 11 | #include <linux/linkage.h> |
12 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
13 | #include <linux/errno.h> | 13 | #include <linux/errno.h> |
14 | #include <linux/interrupt.h> | 14 | #include <linux/interrupt.h> |
15 | #include <asm/pil.h> | 15 | #include <asm/pil.h> |
16 | #include <asm/ptrace.h> | 16 | #include <asm/ptrace.h> |
17 | 17 | ||
18 | /* IMAP/ICLR register defines */ | 18 | /* IMAP/ICLR register defines */ |
19 | #define IMAP_VALID 0x80000000 /* IRQ Enabled */ | 19 | #define IMAP_VALID 0x80000000 /* IRQ Enabled */ |
20 | #define IMAP_TID_UPA 0x7c000000 /* UPA TargetID */ | 20 | #define IMAP_TID_UPA 0x7c000000 /* UPA TargetID */ |
21 | #define IMAP_TID_JBUS 0x7c000000 /* JBUS TargetID */ | 21 | #define IMAP_TID_JBUS 0x7c000000 /* JBUS TargetID */ |
22 | #define IMAP_TID_SHIFT 26 | 22 | #define IMAP_TID_SHIFT 26 |
23 | #define IMAP_AID_SAFARI 0x7c000000 /* Safari AgentID */ | 23 | #define IMAP_AID_SAFARI 0x7c000000 /* Safari AgentID */ |
24 | #define IMAP_AID_SHIFT 26 | 24 | #define IMAP_AID_SHIFT 26 |
25 | #define IMAP_NID_SAFARI 0x03e00000 /* Safari NodeID */ | 25 | #define IMAP_NID_SAFARI 0x03e00000 /* Safari NodeID */ |
26 | #define IMAP_NID_SHIFT 21 | 26 | #define IMAP_NID_SHIFT 21 |
27 | #define IMAP_IGN 0x000007c0 /* IRQ Group Number */ | 27 | #define IMAP_IGN 0x000007c0 /* IRQ Group Number */ |
28 | #define IMAP_INO 0x0000003f /* IRQ Number */ | 28 | #define IMAP_INO 0x0000003f /* IRQ Number */ |
29 | #define IMAP_INR 0x000007ff /* Full interrupt number*/ | 29 | #define IMAP_INR 0x000007ff /* Full interrupt number*/ |
30 | 30 | ||
31 | #define ICLR_IDLE 0x00000000 /* Idle state */ | 31 | #define ICLR_IDLE 0x00000000 /* Idle state */ |
32 | #define ICLR_TRANSMIT 0x00000001 /* Transmit state */ | 32 | #define ICLR_TRANSMIT 0x00000001 /* Transmit state */ |
33 | #define ICLR_PENDING 0x00000003 /* Pending state */ | 33 | #define ICLR_PENDING 0x00000003 /* Pending state */ |
34 | 34 | ||
35 | /* The largest number of unique interrupt sources we support. | 35 | /* The largest number of unique interrupt sources we support. |
36 | * If this needs to ever be larger than 255, you need to change | 36 | * If this needs to ever be larger than 255, you need to change |
37 | * the type of ino_bucket->virt_irq as appropriate. | 37 | * the type of ino_bucket->virt_irq as appropriate. |
38 | * | 38 | * |
39 | * ino_bucket->virt_irq allocation is made during {sun4v_,}build_irq(). | 39 | * ino_bucket->virt_irq allocation is made during {sun4v_,}build_irq(). |
40 | */ | 40 | */ |
41 | #define NR_IRQS 255 | 41 | #define NR_IRQS 255 |
42 | 42 | ||
43 | extern void irq_install_pre_handler(int virt_irq, | 43 | extern void irq_install_pre_handler(int virt_irq, |
44 | void (*func)(unsigned int, void *, void *), | 44 | void (*func)(unsigned int, void *, void *), |
45 | void *arg1, void *arg2); | 45 | void *arg1, void *arg2); |
46 | #define irq_canonicalize(irq) (irq) | 46 | #define irq_canonicalize(irq) (irq) |
47 | extern unsigned int build_irq(int inofixup, unsigned long iclr, unsigned long imap); | 47 | extern unsigned int build_irq(int inofixup, unsigned long iclr, unsigned long imap); |
48 | extern unsigned int sun4v_build_irq(u32 devhandle, unsigned int devino); | 48 | extern unsigned int sun4v_build_irq(u32 devhandle, unsigned int devino); |
49 | extern unsigned int sun4v_build_msi(u32 devhandle, unsigned int *virt_irq_p, | ||
50 | unsigned int msi_devino_start, | ||
51 | unsigned int msi_devino_end); | ||
52 | extern void sun4v_destroy_msi(unsigned int virt_irq); | ||
49 | extern unsigned int sbus_build_irq(void *sbus, unsigned int ino); | 53 | extern unsigned int sbus_build_irq(void *sbus, unsigned int ino); |
50 | 54 | ||
51 | static __inline__ void set_softint(unsigned long bits) | 55 | static __inline__ void set_softint(unsigned long bits) |
52 | { | 56 | { |
53 | __asm__ __volatile__("wr %0, 0x0, %%set_softint" | 57 | __asm__ __volatile__("wr %0, 0x0, %%set_softint" |
54 | : /* No outputs */ | 58 | : /* No outputs */ |
55 | : "r" (bits)); | 59 | : "r" (bits)); |
56 | } | 60 | } |
57 | 61 | ||
58 | static __inline__ void clear_softint(unsigned long bits) | 62 | static __inline__ void clear_softint(unsigned long bits) |
59 | { | 63 | { |
60 | __asm__ __volatile__("wr %0, 0x0, %%clear_softint" | 64 | __asm__ __volatile__("wr %0, 0x0, %%clear_softint" |
61 | : /* No outputs */ | 65 | : /* No outputs */ |
62 | : "r" (bits)); | 66 | : "r" (bits)); |
63 | } | 67 | } |
64 | 68 | ||
65 | static __inline__ unsigned long get_softint(void) | 69 | static __inline__ unsigned long get_softint(void) |
66 | { | 70 | { |
67 | unsigned long retval; | 71 | unsigned long retval; |
68 | 72 | ||
69 | __asm__ __volatile__("rd %%softint, %0" | 73 | __asm__ __volatile__("rd %%softint, %0" |
70 | : "=r" (retval)); | 74 | : "=r" (retval)); |
71 | return retval; | 75 | return retval; |
72 | } | 76 | } |
73 | 77 | ||
74 | #endif | 78 | #endif |
75 | 79 |
include/asm-sparc64/pbm.h
1 | /* $Id: pbm.h,v 1.27 2001/08/12 13:18:23 davem Exp $ | 1 | /* $Id: pbm.h,v 1.27 2001/08/12 13:18:23 davem Exp $ |
2 | * pbm.h: UltraSparc PCI controller software state. | 2 | * pbm.h: UltraSparc PCI controller software state. |
3 | * | 3 | * |
4 | * Copyright (C) 1997, 1998, 1999 David S. Miller (davem@redhat.com) | 4 | * Copyright (C) 1997, 1998, 1999 David S. Miller (davem@redhat.com) |
5 | */ | 5 | */ |
6 | 6 | ||
7 | #ifndef __SPARC64_PBM_H | 7 | #ifndef __SPARC64_PBM_H |
8 | #define __SPARC64_PBM_H | 8 | #define __SPARC64_PBM_H |
9 | 9 | ||
10 | #include <linux/types.h> | 10 | #include <linux/types.h> |
11 | #include <linux/pci.h> | 11 | #include <linux/pci.h> |
12 | #include <linux/ioport.h> | 12 | #include <linux/ioport.h> |
13 | #include <linux/spinlock.h> | 13 | #include <linux/spinlock.h> |
14 | #include <linux/msi.h> | ||
14 | 15 | ||
15 | #include <asm/io.h> | 16 | #include <asm/io.h> |
16 | #include <asm/page.h> | 17 | #include <asm/page.h> |
17 | #include <asm/oplib.h> | 18 | #include <asm/oplib.h> |
18 | #include <asm/prom.h> | 19 | #include <asm/prom.h> |
19 | #include <asm/of_device.h> | 20 | #include <asm/of_device.h> |
20 | #include <asm/iommu.h> | 21 | #include <asm/iommu.h> |
21 | 22 | ||
22 | /* The abstraction used here is that there are PCI controllers, | 23 | /* The abstraction used here is that there are PCI controllers, |
23 | * each with one (Sabre) or two (PSYCHO/SCHIZO) PCI bus modules | 24 | * each with one (Sabre) or two (PSYCHO/SCHIZO) PCI bus modules |
24 | * underneath. Each PCI bus module uses an IOMMU (shared by both | 25 | * underneath. Each PCI bus module uses an IOMMU (shared by both |
25 | * PBMs of a controller, or per-PBM), and if a streaming buffer | 26 | * PBMs of a controller, or per-PBM), and if a streaming buffer |
26 | * is present, each PCI bus module has it's own. (ie. the IOMMU | 27 | * is present, each PCI bus module has it's own. (ie. the IOMMU |
27 | * might be shared between PBMs, the STC is never shared) | 28 | * might be shared between PBMs, the STC is never shared) |
28 | * Furthermore, each PCI bus module controls it's own autonomous | 29 | * Furthermore, each PCI bus module controls it's own autonomous |
29 | * PCI bus. | 30 | * PCI bus. |
30 | */ | 31 | */ |
31 | 32 | ||
32 | struct pci_controller_info; | 33 | struct pci_controller_info; |
33 | 34 | ||
34 | /* This contains the software state necessary to drive a PCI | 35 | /* This contains the software state necessary to drive a PCI |
35 | * controller's IOMMU. | 36 | * controller's IOMMU. |
36 | */ | 37 | */ |
37 | struct pci_iommu_arena { | 38 | struct pci_iommu_arena { |
38 | unsigned long *map; | 39 | unsigned long *map; |
39 | unsigned int hint; | 40 | unsigned int hint; |
40 | unsigned int limit; | 41 | unsigned int limit; |
41 | }; | 42 | }; |
42 | 43 | ||
43 | struct pci_iommu { | 44 | struct pci_iommu { |
44 | /* This protects the controller's IOMMU and all | 45 | /* This protects the controller's IOMMU and all |
45 | * streaming buffers underneath. | 46 | * streaming buffers underneath. |
46 | */ | 47 | */ |
47 | spinlock_t lock; | 48 | spinlock_t lock; |
48 | 49 | ||
49 | struct pci_iommu_arena arena; | 50 | struct pci_iommu_arena arena; |
50 | 51 | ||
51 | /* IOMMU page table, a linear array of ioptes. */ | 52 | /* IOMMU page table, a linear array of ioptes. */ |
52 | iopte_t *page_table; /* The page table itself. */ | 53 | iopte_t *page_table; /* The page table itself. */ |
53 | 54 | ||
54 | /* Base PCI memory space address where IOMMU mappings | 55 | /* Base PCI memory space address where IOMMU mappings |
55 | * begin. | 56 | * begin. |
56 | */ | 57 | */ |
57 | u32 page_table_map_base; | 58 | u32 page_table_map_base; |
58 | 59 | ||
59 | /* IOMMU Controller Registers */ | 60 | /* IOMMU Controller Registers */ |
60 | unsigned long iommu_control; /* IOMMU control register */ | 61 | unsigned long iommu_control; /* IOMMU control register */ |
61 | unsigned long iommu_tsbbase; /* IOMMU page table base register */ | 62 | unsigned long iommu_tsbbase; /* IOMMU page table base register */ |
62 | unsigned long iommu_flush; /* IOMMU page flush register */ | 63 | unsigned long iommu_flush; /* IOMMU page flush register */ |
63 | unsigned long iommu_ctxflush; /* IOMMU context flush register */ | 64 | unsigned long iommu_ctxflush; /* IOMMU context flush register */ |
64 | 65 | ||
65 | /* This is a register in the PCI controller, which if | 66 | /* This is a register in the PCI controller, which if |
66 | * read will have no side-effects but will guarantee | 67 | * read will have no side-effects but will guarantee |
67 | * completion of all previous writes into IOMMU/STC. | 68 | * completion of all previous writes into IOMMU/STC. |
68 | */ | 69 | */ |
69 | unsigned long write_complete_reg; | 70 | unsigned long write_complete_reg; |
70 | 71 | ||
71 | /* In order to deal with some buggy third-party PCI bridges that | 72 | /* In order to deal with some buggy third-party PCI bridges that |
72 | * do wrong prefetching, we never mark valid mappings as invalid. | 73 | * do wrong prefetching, we never mark valid mappings as invalid. |
73 | * Instead we point them at this dummy page. | 74 | * Instead we point them at this dummy page. |
74 | */ | 75 | */ |
75 | unsigned long dummy_page; | 76 | unsigned long dummy_page; |
76 | unsigned long dummy_page_pa; | 77 | unsigned long dummy_page_pa; |
77 | 78 | ||
78 | /* CTX allocation. */ | 79 | /* CTX allocation. */ |
79 | unsigned long ctx_lowest_free; | 80 | unsigned long ctx_lowest_free; |
80 | unsigned long ctx_bitmap[IOMMU_NUM_CTXS / (sizeof(unsigned long) * 8)]; | 81 | unsigned long ctx_bitmap[IOMMU_NUM_CTXS / (sizeof(unsigned long) * 8)]; |
81 | 82 | ||
82 | /* Here a PCI controller driver describes the areas of | 83 | /* Here a PCI controller driver describes the areas of |
83 | * PCI memory space where DMA to/from physical memory | 84 | * PCI memory space where DMA to/from physical memory |
84 | * are addressed. Drivers interrogate the PCI layer | 85 | * are addressed. Drivers interrogate the PCI layer |
85 | * if their device has addressing limitations. They | 86 | * if their device has addressing limitations. They |
86 | * do so via pci_dma_supported, and pass in a mask of | 87 | * do so via pci_dma_supported, and pass in a mask of |
87 | * DMA address bits their device can actually drive. | 88 | * DMA address bits their device can actually drive. |
88 | * | 89 | * |
89 | * The test for being usable is: | 90 | * The test for being usable is: |
90 | * (device_mask & dma_addr_mask) == dma_addr_mask | 91 | * (device_mask & dma_addr_mask) == dma_addr_mask |
91 | */ | 92 | */ |
92 | u32 dma_addr_mask; | 93 | u32 dma_addr_mask; |
93 | }; | 94 | }; |
94 | 95 | ||
95 | extern void pci_iommu_table_init(struct pci_iommu *iommu, int tsbsize, u32 dma_offset, u32 dma_addr_mask); | 96 | extern void pci_iommu_table_init(struct pci_iommu *iommu, int tsbsize, u32 dma_offset, u32 dma_addr_mask); |
96 | 97 | ||
97 | /* This describes a PCI bus module's streaming buffer. */ | 98 | /* This describes a PCI bus module's streaming buffer. */ |
98 | struct pci_strbuf { | 99 | struct pci_strbuf { |
99 | int strbuf_enabled; /* Present and using it? */ | 100 | int strbuf_enabled; /* Present and using it? */ |
100 | 101 | ||
101 | /* Streaming Buffer Control Registers */ | 102 | /* Streaming Buffer Control Registers */ |
102 | unsigned long strbuf_control; /* STC control register */ | 103 | unsigned long strbuf_control; /* STC control register */ |
103 | unsigned long strbuf_pflush; /* STC page flush register */ | 104 | unsigned long strbuf_pflush; /* STC page flush register */ |
104 | unsigned long strbuf_fsync; /* STC flush synchronization reg */ | 105 | unsigned long strbuf_fsync; /* STC flush synchronization reg */ |
105 | unsigned long strbuf_ctxflush; /* STC context flush register */ | 106 | unsigned long strbuf_ctxflush; /* STC context flush register */ |
106 | unsigned long strbuf_ctxmatch_base; /* STC context flush match reg */ | 107 | unsigned long strbuf_ctxmatch_base; /* STC context flush match reg */ |
107 | unsigned long strbuf_flushflag_pa; /* Physical address of flush flag */ | 108 | unsigned long strbuf_flushflag_pa; /* Physical address of flush flag */ |
108 | volatile unsigned long *strbuf_flushflag; /* The flush flag itself */ | 109 | volatile unsigned long *strbuf_flushflag; /* The flush flag itself */ |
109 | 110 | ||
110 | /* And this is the actual flush flag area. | 111 | /* And this is the actual flush flag area. |
111 | * We allocate extra because the chips require | 112 | * We allocate extra because the chips require |
112 | * a 64-byte aligned area. | 113 | * a 64-byte aligned area. |
113 | */ | 114 | */ |
114 | volatile unsigned long __flushflag_buf[(64 + (64 - 1)) / sizeof(long)]; | 115 | volatile unsigned long __flushflag_buf[(64 + (64 - 1)) / sizeof(long)]; |
115 | }; | 116 | }; |
116 | 117 | ||
117 | #define PCI_STC_FLUSHFLAG_INIT(STC) \ | 118 | #define PCI_STC_FLUSHFLAG_INIT(STC) \ |
118 | (*((STC)->strbuf_flushflag) = 0UL) | 119 | (*((STC)->strbuf_flushflag) = 0UL) |
119 | #define PCI_STC_FLUSHFLAG_SET(STC) \ | 120 | #define PCI_STC_FLUSHFLAG_SET(STC) \ |
120 | (*((STC)->strbuf_flushflag) != 0UL) | 121 | (*((STC)->strbuf_flushflag) != 0UL) |
121 | 122 | ||
122 | /* There can be quite a few ranges and interrupt maps on a PCI | 123 | /* There can be quite a few ranges and interrupt maps on a PCI |
123 | * segment. Thus... | 124 | * segment. Thus... |
124 | */ | 125 | */ |
125 | #define PROM_PCIRNG_MAX 64 | 126 | #define PROM_PCIRNG_MAX 64 |
126 | #define PROM_PCIIMAP_MAX 64 | 127 | #define PROM_PCIIMAP_MAX 64 |
127 | 128 | ||
128 | struct pci_pbm_info { | 129 | struct pci_pbm_info { |
129 | /* PCI controller we sit under. */ | 130 | /* PCI controller we sit under. */ |
130 | struct pci_controller_info *parent; | 131 | struct pci_controller_info *parent; |
131 | 132 | ||
132 | /* Physical address base of controller registers. */ | 133 | /* Physical address base of controller registers. */ |
133 | unsigned long controller_regs; | 134 | unsigned long controller_regs; |
134 | 135 | ||
135 | /* Physical address base of PBM registers. */ | 136 | /* Physical address base of PBM registers. */ |
136 | unsigned long pbm_regs; | 137 | unsigned long pbm_regs; |
137 | 138 | ||
138 | /* Physical address of DMA sync register, if any. */ | 139 | /* Physical address of DMA sync register, if any. */ |
139 | unsigned long sync_reg; | 140 | unsigned long sync_reg; |
140 | 141 | ||
141 | /* Opaque 32-bit system bus Port ID. */ | 142 | /* Opaque 32-bit system bus Port ID. */ |
142 | u32 portid; | 143 | u32 portid; |
143 | 144 | ||
144 | /* Opaque 32-bit handle used for hypervisor calls. */ | 145 | /* Opaque 32-bit handle used for hypervisor calls. */ |
145 | u32 devhandle; | 146 | u32 devhandle; |
146 | 147 | ||
147 | /* Chipset version information. */ | 148 | /* Chipset version information. */ |
148 | int chip_type; | 149 | int chip_type; |
149 | #define PBM_CHIP_TYPE_SABRE 1 | 150 | #define PBM_CHIP_TYPE_SABRE 1 |
150 | #define PBM_CHIP_TYPE_PSYCHO 2 | 151 | #define PBM_CHIP_TYPE_PSYCHO 2 |
151 | #define PBM_CHIP_TYPE_SCHIZO 3 | 152 | #define PBM_CHIP_TYPE_SCHIZO 3 |
152 | #define PBM_CHIP_TYPE_SCHIZO_PLUS 4 | 153 | #define PBM_CHIP_TYPE_SCHIZO_PLUS 4 |
153 | #define PBM_CHIP_TYPE_TOMATILLO 5 | 154 | #define PBM_CHIP_TYPE_TOMATILLO 5 |
154 | int chip_version; | 155 | int chip_version; |
155 | int chip_revision; | 156 | int chip_revision; |
156 | 157 | ||
157 | /* Name used for top-level resources. */ | 158 | /* Name used for top-level resources. */ |
158 | char *name; | 159 | char *name; |
159 | 160 | ||
160 | /* OBP specific information. */ | 161 | /* OBP specific information. */ |
161 | struct device_node *prom_node; | 162 | struct device_node *prom_node; |
162 | struct linux_prom_pci_ranges *pbm_ranges; | 163 | struct linux_prom_pci_ranges *pbm_ranges; |
163 | int num_pbm_ranges; | 164 | int num_pbm_ranges; |
164 | struct linux_prom_pci_intmap *pbm_intmap; | 165 | struct linux_prom_pci_intmap *pbm_intmap; |
165 | int num_pbm_intmap; | 166 | int num_pbm_intmap; |
166 | struct linux_prom_pci_intmask *pbm_intmask; | 167 | struct linux_prom_pci_intmask *pbm_intmask; |
167 | u64 ino_bitmap; | 168 | u64 ino_bitmap; |
168 | 169 | ||
169 | /* PBM I/O and Memory space resources. */ | 170 | /* PBM I/O and Memory space resources. */ |
170 | struct resource io_space; | 171 | struct resource io_space; |
171 | struct resource mem_space; | 172 | struct resource mem_space; |
172 | 173 | ||
173 | /* Base of PCI Config space, can be per-PBM or shared. */ | 174 | /* Base of PCI Config space, can be per-PBM or shared. */ |
174 | unsigned long config_space; | 175 | unsigned long config_space; |
175 | 176 | ||
176 | /* State of 66MHz capabilities on this PBM. */ | 177 | /* State of 66MHz capabilities on this PBM. */ |
177 | int is_66mhz_capable; | 178 | int is_66mhz_capable; |
178 | int all_devs_66mhz; | 179 | int all_devs_66mhz; |
179 | 180 | ||
181 | #ifdef CONFIG_PCI_MSI | ||
182 | /* MSI info. */ | ||
183 | u32 msiq_num; | ||
184 | u32 msiq_ent_count; | ||
185 | u32 msiq_first; | ||
186 | u32 msiq_first_devino; | ||
187 | u32 msi_num; | ||
188 | u32 msi_first; | ||
189 | u32 msi_data_mask; | ||
190 | u32 msix_data_width; | ||
191 | u64 msi32_start; | ||
192 | u64 msi64_start; | ||
193 | u32 msi32_len; | ||
194 | u32 msi64_len; | ||
195 | void *msi_queues; | ||
196 | unsigned long *msi_bitmap; | ||
197 | #endif /* !(CONFIG_PCI_MSI) */ | ||
198 | |||
180 | /* This PBM's streaming buffer. */ | 199 | /* This PBM's streaming buffer. */ |
181 | struct pci_strbuf stc; | 200 | struct pci_strbuf stc; |
182 | 201 | ||
183 | /* IOMMU state, potentially shared by both PBM segments. */ | 202 | /* IOMMU state, potentially shared by both PBM segments. */ |
184 | struct pci_iommu *iommu; | 203 | struct pci_iommu *iommu; |
185 | 204 | ||
186 | /* PCI slot mapping. */ | 205 | /* PCI slot mapping. */ |
187 | unsigned int pci_first_slot; | 206 | unsigned int pci_first_slot; |
188 | 207 | ||
189 | /* Now things for the actual PCI bus probes. */ | 208 | /* Now things for the actual PCI bus probes. */ |
190 | unsigned int pci_first_busno; | 209 | unsigned int pci_first_busno; |
191 | unsigned int pci_last_busno; | 210 | unsigned int pci_last_busno; |
192 | struct pci_bus *pci_bus; | 211 | struct pci_bus *pci_bus; |
193 | }; | 212 | }; |
194 | 213 | ||
195 | struct pci_controller_info { | 214 | struct pci_controller_info { |
196 | /* List of all PCI controllers. */ | 215 | /* List of all PCI controllers. */ |
197 | struct pci_controller_info *next; | 216 | struct pci_controller_info *next; |
198 | 217 | ||
199 | /* Each controller gets a unique index, used mostly for | 218 | /* Each controller gets a unique index, used mostly for |
200 | * error logging purposes. | 219 | * error logging purposes. |
201 | */ | 220 | */ |
202 | int index; | 221 | int index; |
203 | 222 | ||
204 | /* Do the PBMs both exist in the same PCI domain? */ | 223 | /* Do the PBMs both exist in the same PCI domain? */ |
205 | int pbms_same_domain; | 224 | int pbms_same_domain; |
206 | 225 | ||
207 | /* The PCI bus modules controlled by us. */ | 226 | /* The PCI bus modules controlled by us. */ |
208 | struct pci_pbm_info pbm_A; | 227 | struct pci_pbm_info pbm_A; |
209 | struct pci_pbm_info pbm_B; | 228 | struct pci_pbm_info pbm_B; |
210 | 229 | ||
211 | /* Operations which are controller specific. */ | 230 | /* Operations which are controller specific. */ |
212 | void (*scan_bus)(struct pci_controller_info *); | 231 | void (*scan_bus)(struct pci_controller_info *); |
213 | void (*base_address_update)(struct pci_dev *, int); | 232 | void (*base_address_update)(struct pci_dev *, int); |
214 | void (*resource_adjust)(struct pci_dev *, struct resource *, struct resource *); | 233 | void (*resource_adjust)(struct pci_dev *, struct resource *, struct resource *); |
215 | 234 | ||
235 | #ifdef CONFIG_PCI_MSI | ||
236 | int (*setup_msi_irq)(unsigned int *virt_irq_p, struct pci_dev *pdev, | ||
237 | struct msi_desc *entry); | ||
238 | void (*teardown_msi_irq)(unsigned int virt_irq, struct pci_dev *pdev); | ||
239 | #endif | ||
240 | |||
216 | /* Now things for the actual PCI bus probes. */ | 241 | /* Now things for the actual PCI bus probes. */ |
217 | struct pci_ops *pci_ops; | 242 | struct pci_ops *pci_ops; |
218 | unsigned int pci_first_busno; | 243 | unsigned int pci_first_busno; |
219 | unsigned int pci_last_busno; | 244 | unsigned int pci_last_busno; |
220 | }; | 245 | }; |
221 | 246 | ||
222 | /* PCI devices which are not bridges have this placed in their pci_dev | 247 | /* PCI devices which are not bridges have this placed in their pci_dev |
223 | * sysdata member. This makes OBP aware PCI device drivers easier to | 248 | * sysdata member. This makes OBP aware PCI device drivers easier to |
224 | * code. | 249 | * code. |
225 | */ | 250 | */ |
226 | struct pcidev_cookie { | 251 | struct pcidev_cookie { |
227 | struct pci_pbm_info *pbm; | 252 | struct pci_pbm_info *pbm; |
228 | struct device_node *prom_node; | 253 | struct device_node *prom_node; |
229 | struct of_device *op; | 254 | struct of_device *op; |
230 | struct linux_prom_pci_registers prom_regs[PROMREG_MAX]; | 255 | struct linux_prom_pci_registers prom_regs[PROMREG_MAX]; |
231 | int num_prom_regs; | 256 | int num_prom_regs; |
232 | struct linux_prom_pci_registers prom_assignments[PROMREG_MAX]; | 257 | struct linux_prom_pci_registers prom_assignments[PROMREG_MAX]; |
233 | int num_prom_assignments; | 258 | int num_prom_assignments; |
259 | #ifdef CONFIG_PCI_MSI | ||
260 | unsigned int msi_num; | ||
261 | #endif | ||
234 | }; | 262 | }; |
235 | 263 | ||
236 | /* Currently these are the same across all PCI controllers | 264 | /* Currently these are the same across all PCI controllers |
237 | * we support. Someday they may not be... | 265 | * we support. Someday they may not be... |
238 | */ | 266 | */ |
239 | #define PCI_IRQ_IGN 0x000007c0 /* Interrupt Group Number */ | 267 | #define PCI_IRQ_IGN 0x000007c0 /* Interrupt Group Number */ |
240 | #define PCI_IRQ_INO 0x0000003f /* Interrupt Number */ | 268 | #define PCI_IRQ_INO 0x0000003f /* Interrupt Number */ |
241 | 269 | ||
242 | #endif /* !(__SPARC64_PBM_H) */ | 270 | #endif /* !(__SPARC64_PBM_H) */ |
243 | 271 |
include/linux/genhd.h
1 | #ifndef _LINUX_GENHD_H | 1 | #ifndef _LINUX_GENHD_H |
2 | #define _LINUX_GENHD_H | 2 | #define _LINUX_GENHD_H |
3 | 3 | ||
4 | /* | 4 | /* |
5 | * genhd.h Copyright (C) 1992 Drew Eckhardt | 5 | * genhd.h Copyright (C) 1992 Drew Eckhardt |
6 | * Generic hard disk header file by | 6 | * Generic hard disk header file by |
7 | * Drew Eckhardt | 7 | * Drew Eckhardt |
8 | * | 8 | * |
9 | * <drew@colorado.edu> | 9 | * <drew@colorado.edu> |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/types.h> | 12 | #include <linux/types.h> |
13 | 13 | ||
14 | #ifdef CONFIG_BLOCK | 14 | #ifdef CONFIG_BLOCK |
15 | 15 | ||
16 | enum { | 16 | enum { |
17 | /* These three have identical behaviour; use the second one if DOS FDISK gets | 17 | /* These three have identical behaviour; use the second one if DOS FDISK gets |
18 | confused about extended/logical partitions starting past cylinder 1023. */ | 18 | confused about extended/logical partitions starting past cylinder 1023. */ |
19 | DOS_EXTENDED_PARTITION = 5, | 19 | DOS_EXTENDED_PARTITION = 5, |
20 | LINUX_EXTENDED_PARTITION = 0x85, | 20 | LINUX_EXTENDED_PARTITION = 0x85, |
21 | WIN98_EXTENDED_PARTITION = 0x0f, | 21 | WIN98_EXTENDED_PARTITION = 0x0f, |
22 | 22 | ||
23 | SUN_WHOLE_DISK = DOS_EXTENDED_PARTITION, | ||
24 | |||
23 | LINUX_SWAP_PARTITION = 0x82, | 25 | LINUX_SWAP_PARTITION = 0x82, |
24 | LINUX_DATA_PARTITION = 0x83, | 26 | LINUX_DATA_PARTITION = 0x83, |
25 | LINUX_LVM_PARTITION = 0x8e, | 27 | LINUX_LVM_PARTITION = 0x8e, |
26 | LINUX_RAID_PARTITION = 0xfd, /* autodetect RAID partition */ | 28 | LINUX_RAID_PARTITION = 0xfd, /* autodetect RAID partition */ |
27 | 29 | ||
28 | SOLARIS_X86_PARTITION = LINUX_SWAP_PARTITION, | 30 | SOLARIS_X86_PARTITION = LINUX_SWAP_PARTITION, |
29 | NEW_SOLARIS_X86_PARTITION = 0xbf, | 31 | NEW_SOLARIS_X86_PARTITION = 0xbf, |
30 | 32 | ||
31 | DM6_AUX1PARTITION = 0x51, /* no DDO: use xlated geom */ | 33 | DM6_AUX1PARTITION = 0x51, /* no DDO: use xlated geom */ |
32 | DM6_AUX3PARTITION = 0x53, /* no DDO: use xlated geom */ | 34 | DM6_AUX3PARTITION = 0x53, /* no DDO: use xlated geom */ |
33 | DM6_PARTITION = 0x54, /* has DDO: use xlated geom & offset */ | 35 | DM6_PARTITION = 0x54, /* has DDO: use xlated geom & offset */ |
34 | EZD_PARTITION = 0x55, /* EZ-DRIVE */ | 36 | EZD_PARTITION = 0x55, /* EZ-DRIVE */ |
35 | 37 | ||
36 | FREEBSD_PARTITION = 0xa5, /* FreeBSD Partition ID */ | 38 | FREEBSD_PARTITION = 0xa5, /* FreeBSD Partition ID */ |
37 | OPENBSD_PARTITION = 0xa6, /* OpenBSD Partition ID */ | 39 | OPENBSD_PARTITION = 0xa6, /* OpenBSD Partition ID */ |
38 | NETBSD_PARTITION = 0xa9, /* NetBSD Partition ID */ | 40 | NETBSD_PARTITION = 0xa9, /* NetBSD Partition ID */ |
39 | BSDI_PARTITION = 0xb7, /* BSDI Partition ID */ | 41 | BSDI_PARTITION = 0xb7, /* BSDI Partition ID */ |
40 | MINIX_PARTITION = 0x81, /* Minix Partition ID */ | 42 | MINIX_PARTITION = 0x81, /* Minix Partition ID */ |
41 | UNIXWARE_PARTITION = 0x63, /* Same as GNU_HURD and SCO Unix */ | 43 | UNIXWARE_PARTITION = 0x63, /* Same as GNU_HURD and SCO Unix */ |
42 | }; | 44 | }; |
43 | 45 | ||
44 | #ifndef __KERNEL__ | 46 | #ifndef __KERNEL__ |
45 | 47 | ||
46 | struct partition { | 48 | struct partition { |
47 | unsigned char boot_ind; /* 0x80 - active */ | 49 | unsigned char boot_ind; /* 0x80 - active */ |
48 | unsigned char head; /* starting head */ | 50 | unsigned char head; /* starting head */ |
49 | unsigned char sector; /* starting sector */ | 51 | unsigned char sector; /* starting sector */ |
50 | unsigned char cyl; /* starting cylinder */ | 52 | unsigned char cyl; /* starting cylinder */ |
51 | unsigned char sys_ind; /* What partition type */ | 53 | unsigned char sys_ind; /* What partition type */ |
52 | unsigned char end_head; /* end head */ | 54 | unsigned char end_head; /* end head */ |
53 | unsigned char end_sector; /* end sector */ | 55 | unsigned char end_sector; /* end sector */ |
54 | unsigned char end_cyl; /* end cylinder */ | 56 | unsigned char end_cyl; /* end cylinder */ |
55 | unsigned int start_sect; /* starting sector counting from 0 */ | 57 | unsigned int start_sect; /* starting sector counting from 0 */ |
56 | unsigned int nr_sects; /* nr of sectors in partition */ | 58 | unsigned int nr_sects; /* nr of sectors in partition */ |
57 | } __attribute__((packed)); | 59 | } __attribute__((packed)); |
58 | 60 | ||
59 | #endif | 61 | #endif |
60 | 62 | ||
61 | #ifdef __KERNEL__ | 63 | #ifdef __KERNEL__ |
62 | #include <linux/major.h> | 64 | #include <linux/major.h> |
63 | #include <linux/device.h> | 65 | #include <linux/device.h> |
64 | #include <linux/smp.h> | 66 | #include <linux/smp.h> |
65 | #include <linux/string.h> | 67 | #include <linux/string.h> |
66 | #include <linux/fs.h> | 68 | #include <linux/fs.h> |
67 | 69 | ||
68 | struct partition { | 70 | struct partition { |
69 | unsigned char boot_ind; /* 0x80 - active */ | 71 | unsigned char boot_ind; /* 0x80 - active */ |
70 | unsigned char head; /* starting head */ | 72 | unsigned char head; /* starting head */ |
71 | unsigned char sector; /* starting sector */ | 73 | unsigned char sector; /* starting sector */ |
72 | unsigned char cyl; /* starting cylinder */ | 74 | unsigned char cyl; /* starting cylinder */ |
73 | unsigned char sys_ind; /* What partition type */ | 75 | unsigned char sys_ind; /* What partition type */ |
74 | unsigned char end_head; /* end head */ | 76 | unsigned char end_head; /* end head */ |
75 | unsigned char end_sector; /* end sector */ | 77 | unsigned char end_sector; /* end sector */ |
76 | unsigned char end_cyl; /* end cylinder */ | 78 | unsigned char end_cyl; /* end cylinder */ |
77 | __le32 start_sect; /* starting sector counting from 0 */ | 79 | __le32 start_sect; /* starting sector counting from 0 */ |
78 | __le32 nr_sects; /* nr of sectors in partition */ | 80 | __le32 nr_sects; /* nr of sectors in partition */ |
79 | } __attribute__((packed)); | 81 | } __attribute__((packed)); |
80 | 82 | ||
81 | struct hd_struct { | 83 | struct hd_struct { |
82 | sector_t start_sect; | 84 | sector_t start_sect; |
83 | sector_t nr_sects; | 85 | sector_t nr_sects; |
84 | struct kobject kobj; | 86 | struct kobject kobj; |
85 | struct kobject *holder_dir; | 87 | struct kobject *holder_dir; |
86 | unsigned ios[2], sectors[2]; /* READs and WRITEs */ | 88 | unsigned ios[2], sectors[2]; /* READs and WRITEs */ |
87 | int policy, partno; | 89 | int policy, partno; |
88 | #ifdef CONFIG_FAIL_MAKE_REQUEST | 90 | #ifdef CONFIG_FAIL_MAKE_REQUEST |
89 | int make_it_fail; | 91 | int make_it_fail; |
90 | #endif | 92 | #endif |
91 | }; | 93 | }; |
92 | 94 | ||
93 | #define GENHD_FL_REMOVABLE 1 | 95 | #define GENHD_FL_REMOVABLE 1 |
94 | #define GENHD_FL_DRIVERFS 2 | 96 | #define GENHD_FL_DRIVERFS 2 |
95 | #define GENHD_FL_CD 8 | 97 | #define GENHD_FL_CD 8 |
96 | #define GENHD_FL_UP 16 | 98 | #define GENHD_FL_UP 16 |
97 | #define GENHD_FL_SUPPRESS_PARTITION_INFO 32 | 99 | #define GENHD_FL_SUPPRESS_PARTITION_INFO 32 |
98 | #define GENHD_FL_FAIL 64 | 100 | #define GENHD_FL_FAIL 64 |
99 | 101 | ||
100 | struct disk_stats { | 102 | struct disk_stats { |
101 | unsigned long sectors[2]; /* READs and WRITEs */ | 103 | unsigned long sectors[2]; /* READs and WRITEs */ |
102 | unsigned long ios[2]; | 104 | unsigned long ios[2]; |
103 | unsigned long merges[2]; | 105 | unsigned long merges[2]; |
104 | unsigned long ticks[2]; | 106 | unsigned long ticks[2]; |
105 | unsigned long io_ticks; | 107 | unsigned long io_ticks; |
106 | unsigned long time_in_queue; | 108 | unsigned long time_in_queue; |
107 | }; | 109 | }; |
108 | 110 | ||
109 | struct gendisk { | 111 | struct gendisk { |
110 | int major; /* major number of driver */ | 112 | int major; /* major number of driver */ |
111 | int first_minor; | 113 | int first_minor; |
112 | int minors; /* maximum number of minors, =1 for | 114 | int minors; /* maximum number of minors, =1 for |
113 | * disks that can't be partitioned. */ | 115 | * disks that can't be partitioned. */ |
114 | char disk_name[32]; /* name of major driver */ | 116 | char disk_name[32]; /* name of major driver */ |
115 | struct hd_struct **part; /* [indexed by minor] */ | 117 | struct hd_struct **part; /* [indexed by minor] */ |
116 | int part_uevent_suppress; | 118 | int part_uevent_suppress; |
117 | struct block_device_operations *fops; | 119 | struct block_device_operations *fops; |
118 | struct request_queue *queue; | 120 | struct request_queue *queue; |
119 | void *private_data; | 121 | void *private_data; |
120 | sector_t capacity; | 122 | sector_t capacity; |
121 | 123 | ||
122 | int flags; | 124 | int flags; |
123 | struct device *driverfs_dev; | 125 | struct device *driverfs_dev; |
124 | struct kobject kobj; | 126 | struct kobject kobj; |
125 | struct kobject *holder_dir; | 127 | struct kobject *holder_dir; |
126 | struct kobject *slave_dir; | 128 | struct kobject *slave_dir; |
127 | 129 | ||
128 | struct timer_rand_state *random; | 130 | struct timer_rand_state *random; |
129 | int policy; | 131 | int policy; |
130 | 132 | ||
131 | atomic_t sync_io; /* RAID */ | 133 | atomic_t sync_io; /* RAID */ |
132 | unsigned long stamp; | 134 | unsigned long stamp; |
133 | int in_flight; | 135 | int in_flight; |
134 | #ifdef CONFIG_SMP | 136 | #ifdef CONFIG_SMP |
135 | struct disk_stats *dkstats; | 137 | struct disk_stats *dkstats; |
136 | #else | 138 | #else |
137 | struct disk_stats dkstats; | 139 | struct disk_stats dkstats; |
138 | #endif | 140 | #endif |
139 | }; | 141 | }; |
140 | 142 | ||
141 | /* Structure for sysfs attributes on block devices */ | 143 | /* Structure for sysfs attributes on block devices */ |
142 | struct disk_attribute { | 144 | struct disk_attribute { |
143 | struct attribute attr; | 145 | struct attribute attr; |
144 | ssize_t (*show)(struct gendisk *, char *); | 146 | ssize_t (*show)(struct gendisk *, char *); |
145 | ssize_t (*store)(struct gendisk *, const char *, size_t); | 147 | ssize_t (*store)(struct gendisk *, const char *, size_t); |
146 | }; | 148 | }; |
147 | 149 | ||
148 | /* | 150 | /* |
149 | * Macros to operate on percpu disk statistics: | 151 | * Macros to operate on percpu disk statistics: |
150 | * | 152 | * |
151 | * The __ variants should only be called in critical sections. The full | 153 | * The __ variants should only be called in critical sections. The full |
152 | * variants disable/enable preemption. | 154 | * variants disable/enable preemption. |
153 | */ | 155 | */ |
154 | #ifdef CONFIG_SMP | 156 | #ifdef CONFIG_SMP |
155 | #define __disk_stat_add(gendiskp, field, addnd) \ | 157 | #define __disk_stat_add(gendiskp, field, addnd) \ |
156 | (per_cpu_ptr(gendiskp->dkstats, smp_processor_id())->field += addnd) | 158 | (per_cpu_ptr(gendiskp->dkstats, smp_processor_id())->field += addnd) |
157 | 159 | ||
158 | #define disk_stat_read(gendiskp, field) \ | 160 | #define disk_stat_read(gendiskp, field) \ |
159 | ({ \ | 161 | ({ \ |
160 | typeof(gendiskp->dkstats->field) res = 0; \ | 162 | typeof(gendiskp->dkstats->field) res = 0; \ |
161 | int i; \ | 163 | int i; \ |
162 | for_each_possible_cpu(i) \ | 164 | for_each_possible_cpu(i) \ |
163 | res += per_cpu_ptr(gendiskp->dkstats, i)->field; \ | 165 | res += per_cpu_ptr(gendiskp->dkstats, i)->field; \ |
164 | res; \ | 166 | res; \ |
165 | }) | 167 | }) |
166 | 168 | ||
167 | static inline void disk_stat_set_all(struct gendisk *gendiskp, int value) { | 169 | static inline void disk_stat_set_all(struct gendisk *gendiskp, int value) { |
168 | int i; | 170 | int i; |
169 | for_each_possible_cpu(i) | 171 | for_each_possible_cpu(i) |
170 | memset(per_cpu_ptr(gendiskp->dkstats, i), value, | 172 | memset(per_cpu_ptr(gendiskp->dkstats, i), value, |
171 | sizeof (struct disk_stats)); | 173 | sizeof (struct disk_stats)); |
172 | } | 174 | } |
173 | 175 | ||
174 | #else | 176 | #else |
175 | #define __disk_stat_add(gendiskp, field, addnd) \ | 177 | #define __disk_stat_add(gendiskp, field, addnd) \ |
176 | (gendiskp->dkstats.field += addnd) | 178 | (gendiskp->dkstats.field += addnd) |
177 | #define disk_stat_read(gendiskp, field) (gendiskp->dkstats.field) | 179 | #define disk_stat_read(gendiskp, field) (gendiskp->dkstats.field) |
178 | 180 | ||
179 | static inline void disk_stat_set_all(struct gendisk *gendiskp, int value) { | 181 | static inline void disk_stat_set_all(struct gendisk *gendiskp, int value) { |
180 | memset(&gendiskp->dkstats, value, sizeof (struct disk_stats)); | 182 | memset(&gendiskp->dkstats, value, sizeof (struct disk_stats)); |
181 | } | 183 | } |
182 | #endif | 184 | #endif |
183 | 185 | ||
184 | #define disk_stat_add(gendiskp, field, addnd) \ | 186 | #define disk_stat_add(gendiskp, field, addnd) \ |
185 | do { \ | 187 | do { \ |
186 | preempt_disable(); \ | 188 | preempt_disable(); \ |
187 | __disk_stat_add(gendiskp, field, addnd); \ | 189 | __disk_stat_add(gendiskp, field, addnd); \ |
188 | preempt_enable(); \ | 190 | preempt_enable(); \ |
189 | } while (0) | 191 | } while (0) |
190 | 192 | ||
191 | #define __disk_stat_dec(gendiskp, field) __disk_stat_add(gendiskp, field, -1) | 193 | #define __disk_stat_dec(gendiskp, field) __disk_stat_add(gendiskp, field, -1) |
192 | #define disk_stat_dec(gendiskp, field) disk_stat_add(gendiskp, field, -1) | 194 | #define disk_stat_dec(gendiskp, field) disk_stat_add(gendiskp, field, -1) |
193 | 195 | ||
194 | #define __disk_stat_inc(gendiskp, field) __disk_stat_add(gendiskp, field, 1) | 196 | #define __disk_stat_inc(gendiskp, field) __disk_stat_add(gendiskp, field, 1) |
195 | #define disk_stat_inc(gendiskp, field) disk_stat_add(gendiskp, field, 1) | 197 | #define disk_stat_inc(gendiskp, field) disk_stat_add(gendiskp, field, 1) |
196 | 198 | ||
197 | #define __disk_stat_sub(gendiskp, field, subnd) \ | 199 | #define __disk_stat_sub(gendiskp, field, subnd) \ |
198 | __disk_stat_add(gendiskp, field, -subnd) | 200 | __disk_stat_add(gendiskp, field, -subnd) |
199 | #define disk_stat_sub(gendiskp, field, subnd) \ | 201 | #define disk_stat_sub(gendiskp, field, subnd) \ |
200 | disk_stat_add(gendiskp, field, -subnd) | 202 | disk_stat_add(gendiskp, field, -subnd) |
201 | 203 | ||
202 | 204 | ||
203 | /* Inlines to alloc and free disk stats in struct gendisk */ | 205 | /* Inlines to alloc and free disk stats in struct gendisk */ |
204 | #ifdef CONFIG_SMP | 206 | #ifdef CONFIG_SMP |
205 | static inline int init_disk_stats(struct gendisk *disk) | 207 | static inline int init_disk_stats(struct gendisk *disk) |
206 | { | 208 | { |
207 | disk->dkstats = alloc_percpu(struct disk_stats); | 209 | disk->dkstats = alloc_percpu(struct disk_stats); |
208 | if (!disk->dkstats) | 210 | if (!disk->dkstats) |
209 | return 0; | 211 | return 0; |
210 | return 1; | 212 | return 1; |
211 | } | 213 | } |
212 | 214 | ||
213 | static inline void free_disk_stats(struct gendisk *disk) | 215 | static inline void free_disk_stats(struct gendisk *disk) |
214 | { | 216 | { |
215 | free_percpu(disk->dkstats); | 217 | free_percpu(disk->dkstats); |
216 | } | 218 | } |
217 | #else /* CONFIG_SMP */ | 219 | #else /* CONFIG_SMP */ |
218 | static inline int init_disk_stats(struct gendisk *disk) | 220 | static inline int init_disk_stats(struct gendisk *disk) |
219 | { | 221 | { |
220 | return 1; | 222 | return 1; |
221 | } | 223 | } |
222 | 224 | ||
223 | static inline void free_disk_stats(struct gendisk *disk) | 225 | static inline void free_disk_stats(struct gendisk *disk) |
224 | { | 226 | { |
225 | } | 227 | } |
226 | #endif /* CONFIG_SMP */ | 228 | #endif /* CONFIG_SMP */ |
227 | 229 | ||
228 | /* drivers/block/ll_rw_blk.c */ | 230 | /* drivers/block/ll_rw_blk.c */ |
229 | extern void disk_round_stats(struct gendisk *disk); | 231 | extern void disk_round_stats(struct gendisk *disk); |
230 | 232 | ||
231 | /* drivers/block/genhd.c */ | 233 | /* drivers/block/genhd.c */ |
232 | extern int get_blkdev_list(char *, int); | 234 | extern int get_blkdev_list(char *, int); |
233 | extern void add_disk(struct gendisk *disk); | 235 | extern void add_disk(struct gendisk *disk); |
234 | extern void del_gendisk(struct gendisk *gp); | 236 | extern void del_gendisk(struct gendisk *gp); |
235 | extern void unlink_gendisk(struct gendisk *gp); | 237 | extern void unlink_gendisk(struct gendisk *gp); |
236 | extern struct gendisk *get_gendisk(dev_t dev, int *part); | 238 | extern struct gendisk *get_gendisk(dev_t dev, int *part); |
237 | 239 | ||
238 | extern void set_device_ro(struct block_device *bdev, int flag); | 240 | extern void set_device_ro(struct block_device *bdev, int flag); |
239 | extern void set_disk_ro(struct gendisk *disk, int flag); | 241 | extern void set_disk_ro(struct gendisk *disk, int flag); |
240 | 242 | ||
241 | /* drivers/char/random.c */ | 243 | /* drivers/char/random.c */ |
242 | extern void add_disk_randomness(struct gendisk *disk); | 244 | extern void add_disk_randomness(struct gendisk *disk); |
243 | extern void rand_initialize_disk(struct gendisk *disk); | 245 | extern void rand_initialize_disk(struct gendisk *disk); |
244 | 246 | ||
245 | static inline sector_t get_start_sect(struct block_device *bdev) | 247 | static inline sector_t get_start_sect(struct block_device *bdev) |
246 | { | 248 | { |
247 | return bdev->bd_contains == bdev ? 0 : bdev->bd_part->start_sect; | 249 | return bdev->bd_contains == bdev ? 0 : bdev->bd_part->start_sect; |
248 | } | 250 | } |
249 | static inline sector_t get_capacity(struct gendisk *disk) | 251 | static inline sector_t get_capacity(struct gendisk *disk) |
250 | { | 252 | { |
251 | return disk->capacity; | 253 | return disk->capacity; |
252 | } | 254 | } |
253 | static inline void set_capacity(struct gendisk *disk, sector_t size) | 255 | static inline void set_capacity(struct gendisk *disk, sector_t size) |
254 | { | 256 | { |
255 | disk->capacity = size; | 257 | disk->capacity = size; |
256 | } | 258 | } |
257 | 259 | ||
258 | #endif /* __KERNEL__ */ | 260 | #endif /* __KERNEL__ */ |
259 | 261 | ||
260 | #ifdef CONFIG_SOLARIS_X86_PARTITION | 262 | #ifdef CONFIG_SOLARIS_X86_PARTITION |
261 | 263 | ||
262 | #define SOLARIS_X86_NUMSLICE 8 | 264 | #define SOLARIS_X86_NUMSLICE 8 |
263 | #define SOLARIS_X86_VTOC_SANE (0x600DDEEEUL) | 265 | #define SOLARIS_X86_VTOC_SANE (0x600DDEEEUL) |
264 | 266 | ||
265 | struct solaris_x86_slice { | 267 | struct solaris_x86_slice { |
266 | __le16 s_tag; /* ID tag of partition */ | 268 | __le16 s_tag; /* ID tag of partition */ |
267 | __le16 s_flag; /* permission flags */ | 269 | __le16 s_flag; /* permission flags */ |
268 | __le32 s_start; /* start sector no of partition */ | 270 | __le32 s_start; /* start sector no of partition */ |
269 | __le32 s_size; /* # of blocks in partition */ | 271 | __le32 s_size; /* # of blocks in partition */ |
270 | }; | 272 | }; |
271 | 273 | ||
272 | struct solaris_x86_vtoc { | 274 | struct solaris_x86_vtoc { |
273 | unsigned int v_bootinfo[3]; /* info needed by mboot (unsupported) */ | 275 | unsigned int v_bootinfo[3]; /* info needed by mboot (unsupported) */ |
274 | __le32 v_sanity; /* to verify vtoc sanity */ | 276 | __le32 v_sanity; /* to verify vtoc sanity */ |
275 | __le32 v_version; /* layout version */ | 277 | __le32 v_version; /* layout version */ |
276 | char v_volume[8]; /* volume name */ | 278 | char v_volume[8]; /* volume name */ |
277 | __le16 v_sectorsz; /* sector size in bytes */ | 279 | __le16 v_sectorsz; /* sector size in bytes */ |
278 | __le16 v_nparts; /* number of partitions */ | 280 | __le16 v_nparts; /* number of partitions */ |
279 | unsigned int v_reserved[10]; /* free space */ | 281 | unsigned int v_reserved[10]; /* free space */ |
280 | struct solaris_x86_slice | 282 | struct solaris_x86_slice |
281 | v_slice[SOLARIS_X86_NUMSLICE]; /* slice headers */ | 283 | v_slice[SOLARIS_X86_NUMSLICE]; /* slice headers */ |
282 | unsigned int timestamp[SOLARIS_X86_NUMSLICE]; /* timestamp (unsupported) */ | 284 | unsigned int timestamp[SOLARIS_X86_NUMSLICE]; /* timestamp (unsupported) */ |
283 | char v_asciilabel[128]; /* for compatibility */ | 285 | char v_asciilabel[128]; /* for compatibility */ |
284 | }; | 286 | }; |
285 | 287 | ||
286 | #endif /* CONFIG_SOLARIS_X86_PARTITION */ | 288 | #endif /* CONFIG_SOLARIS_X86_PARTITION */ |
287 | 289 | ||
288 | #ifdef CONFIG_BSD_DISKLABEL | 290 | #ifdef CONFIG_BSD_DISKLABEL |
289 | /* | 291 | /* |
290 | * BSD disklabel support by Yossi Gottlieb <yogo@math.tau.ac.il> | 292 | * BSD disklabel support by Yossi Gottlieb <yogo@math.tau.ac.il> |
291 | * updated by Marc Espie <Marc.Espie@openbsd.org> | 293 | * updated by Marc Espie <Marc.Espie@openbsd.org> |
292 | */ | 294 | */ |
293 | 295 | ||
294 | /* check against BSD src/sys/sys/disklabel.h for consistency */ | 296 | /* check against BSD src/sys/sys/disklabel.h for consistency */ |
295 | 297 | ||
296 | #define BSD_DISKMAGIC (0x82564557UL) /* The disk magic number */ | 298 | #define BSD_DISKMAGIC (0x82564557UL) /* The disk magic number */ |
297 | #define BSD_MAXPARTITIONS 16 | 299 | #define BSD_MAXPARTITIONS 16 |
298 | #define OPENBSD_MAXPARTITIONS 16 | 300 | #define OPENBSD_MAXPARTITIONS 16 |
299 | #define BSD_FS_UNUSED 0 /* disklabel unused partition entry ID */ | 301 | #define BSD_FS_UNUSED 0 /* disklabel unused partition entry ID */ |
300 | struct bsd_disklabel { | 302 | struct bsd_disklabel { |
301 | __le32 d_magic; /* the magic number */ | 303 | __le32 d_magic; /* the magic number */ |
302 | __s16 d_type; /* drive type */ | 304 | __s16 d_type; /* drive type */ |
303 | __s16 d_subtype; /* controller/d_type specific */ | 305 | __s16 d_subtype; /* controller/d_type specific */ |
304 | char d_typename[16]; /* type name, e.g. "eagle" */ | 306 | char d_typename[16]; /* type name, e.g. "eagle" */ |
305 | char d_packname[16]; /* pack identifier */ | 307 | char d_packname[16]; /* pack identifier */ |
306 | __u32 d_secsize; /* # of bytes per sector */ | 308 | __u32 d_secsize; /* # of bytes per sector */ |
307 | __u32 d_nsectors; /* # of data sectors per track */ | 309 | __u32 d_nsectors; /* # of data sectors per track */ |
308 | __u32 d_ntracks; /* # of tracks per cylinder */ | 310 | __u32 d_ntracks; /* # of tracks per cylinder */ |
309 | __u32 d_ncylinders; /* # of data cylinders per unit */ | 311 | __u32 d_ncylinders; /* # of data cylinders per unit */ |
310 | __u32 d_secpercyl; /* # of data sectors per cylinder */ | 312 | __u32 d_secpercyl; /* # of data sectors per cylinder */ |
311 | __u32 d_secperunit; /* # of data sectors per unit */ | 313 | __u32 d_secperunit; /* # of data sectors per unit */ |
312 | __u16 d_sparespertrack; /* # of spare sectors per track */ | 314 | __u16 d_sparespertrack; /* # of spare sectors per track */ |
313 | __u16 d_sparespercyl; /* # of spare sectors per cylinder */ | 315 | __u16 d_sparespercyl; /* # of spare sectors per cylinder */ |
314 | __u32 d_acylinders; /* # of alt. cylinders per unit */ | 316 | __u32 d_acylinders; /* # of alt. cylinders per unit */ |
315 | __u16 d_rpm; /* rotational speed */ | 317 | __u16 d_rpm; /* rotational speed */ |
316 | __u16 d_interleave; /* hardware sector interleave */ | 318 | __u16 d_interleave; /* hardware sector interleave */ |
317 | __u16 d_trackskew; /* sector 0 skew, per track */ | 319 | __u16 d_trackskew; /* sector 0 skew, per track */ |
318 | __u16 d_cylskew; /* sector 0 skew, per cylinder */ | 320 | __u16 d_cylskew; /* sector 0 skew, per cylinder */ |
319 | __u32 d_headswitch; /* head switch time, usec */ | 321 | __u32 d_headswitch; /* head switch time, usec */ |
320 | __u32 d_trkseek; /* track-to-track seek, usec */ | 322 | __u32 d_trkseek; /* track-to-track seek, usec */ |
321 | __u32 d_flags; /* generic flags */ | 323 | __u32 d_flags; /* generic flags */ |
322 | #define NDDATA 5 | 324 | #define NDDATA 5 |
323 | __u32 d_drivedata[NDDATA]; /* drive-type specific information */ | 325 | __u32 d_drivedata[NDDATA]; /* drive-type specific information */ |
324 | #define NSPARE 5 | 326 | #define NSPARE 5 |
325 | __u32 d_spare[NSPARE]; /* reserved for future use */ | 327 | __u32 d_spare[NSPARE]; /* reserved for future use */ |
326 | __le32 d_magic2; /* the magic number (again) */ | 328 | __le32 d_magic2; /* the magic number (again) */ |
327 | __le16 d_checksum; /* xor of data incl. partitions */ | 329 | __le16 d_checksum; /* xor of data incl. partitions */ |
328 | 330 | ||
329 | /* filesystem and partition information: */ | 331 | /* filesystem and partition information: */ |
330 | __le16 d_npartitions; /* number of partitions in following */ | 332 | __le16 d_npartitions; /* number of partitions in following */ |
331 | __le32 d_bbsize; /* size of boot area at sn0, bytes */ | 333 | __le32 d_bbsize; /* size of boot area at sn0, bytes */ |
332 | __le32 d_sbsize; /* max size of fs superblock, bytes */ | 334 | __le32 d_sbsize; /* max size of fs superblock, bytes */ |
333 | struct bsd_partition { /* the partition table */ | 335 | struct bsd_partition { /* the partition table */ |
334 | __le32 p_size; /* number of sectors in partition */ | 336 | __le32 p_size; /* number of sectors in partition */ |
335 | __le32 p_offset; /* starting sector */ | 337 | __le32 p_offset; /* starting sector */ |
336 | __le32 p_fsize; /* filesystem basic fragment size */ | 338 | __le32 p_fsize; /* filesystem basic fragment size */ |
337 | __u8 p_fstype; /* filesystem type, see below */ | 339 | __u8 p_fstype; /* filesystem type, see below */ |
338 | __u8 p_frag; /* filesystem fragments per block */ | 340 | __u8 p_frag; /* filesystem fragments per block */ |
339 | __le16 p_cpg; /* filesystem cylinders per group */ | 341 | __le16 p_cpg; /* filesystem cylinders per group */ |
340 | } d_partitions[BSD_MAXPARTITIONS]; /* actually may be more */ | 342 | } d_partitions[BSD_MAXPARTITIONS]; /* actually may be more */ |
341 | }; | 343 | }; |
342 | 344 | ||
343 | #endif /* CONFIG_BSD_DISKLABEL */ | 345 | #endif /* CONFIG_BSD_DISKLABEL */ |
344 | 346 | ||
345 | #ifdef CONFIG_UNIXWARE_DISKLABEL | 347 | #ifdef CONFIG_UNIXWARE_DISKLABEL |
346 | /* | 348 | /* |
347 | * Unixware slices support by Andrzej Krzysztofowicz <ankry@mif.pg.gda.pl> | 349 | * Unixware slices support by Andrzej Krzysztofowicz <ankry@mif.pg.gda.pl> |
348 | * and Krzysztof G. Baranowski <kgb@knm.org.pl> | 350 | * and Krzysztof G. Baranowski <kgb@knm.org.pl> |
349 | */ | 351 | */ |
350 | 352 | ||
351 | #define UNIXWARE_DISKMAGIC (0xCA5E600DUL) /* The disk magic number */ | 353 | #define UNIXWARE_DISKMAGIC (0xCA5E600DUL) /* The disk magic number */ |
352 | #define UNIXWARE_DISKMAGIC2 (0x600DDEEEUL) /* The slice table magic nr */ | 354 | #define UNIXWARE_DISKMAGIC2 (0x600DDEEEUL) /* The slice table magic nr */ |
353 | #define UNIXWARE_NUMSLICE 16 | 355 | #define UNIXWARE_NUMSLICE 16 |
354 | #define UNIXWARE_FS_UNUSED 0 /* Unused slice entry ID */ | 356 | #define UNIXWARE_FS_UNUSED 0 /* Unused slice entry ID */ |
355 | 357 | ||
356 | struct unixware_slice { | 358 | struct unixware_slice { |
357 | __le16 s_label; /* label */ | 359 | __le16 s_label; /* label */ |
358 | __le16 s_flags; /* permission flags */ | 360 | __le16 s_flags; /* permission flags */ |
359 | __le32 start_sect; /* starting sector */ | 361 | __le32 start_sect; /* starting sector */ |
360 | __le32 nr_sects; /* number of sectors in slice */ | 362 | __le32 nr_sects; /* number of sectors in slice */ |
361 | }; | 363 | }; |
362 | 364 | ||
363 | struct unixware_disklabel { | 365 | struct unixware_disklabel { |
364 | __le32 d_type; /* drive type */ | 366 | __le32 d_type; /* drive type */ |
365 | __le32 d_magic; /* the magic number */ | 367 | __le32 d_magic; /* the magic number */ |
366 | __le32 d_version; /* version number */ | 368 | __le32 d_version; /* version number */ |
367 | char d_serial[12]; /* serial number of the device */ | 369 | char d_serial[12]; /* serial number of the device */ |
368 | __le32 d_ncylinders; /* # of data cylinders per device */ | 370 | __le32 d_ncylinders; /* # of data cylinders per device */ |
369 | __le32 d_ntracks; /* # of tracks per cylinder */ | 371 | __le32 d_ntracks; /* # of tracks per cylinder */ |
370 | __le32 d_nsectors; /* # of data sectors per track */ | 372 | __le32 d_nsectors; /* # of data sectors per track */ |
371 | __le32 d_secsize; /* # of bytes per sector */ | 373 | __le32 d_secsize; /* # of bytes per sector */ |
372 | __le32 d_part_start; /* # of first sector of this partition */ | 374 | __le32 d_part_start; /* # of first sector of this partition */ |
373 | __le32 d_unknown1[12]; /* ? */ | 375 | __le32 d_unknown1[12]; /* ? */ |
374 | __le32 d_alt_tbl; /* byte offset of alternate table */ | 376 | __le32 d_alt_tbl; /* byte offset of alternate table */ |
375 | __le32 d_alt_len; /* byte length of alternate table */ | 377 | __le32 d_alt_len; /* byte length of alternate table */ |
376 | __le32 d_phys_cyl; /* # of physical cylinders per device */ | 378 | __le32 d_phys_cyl; /* # of physical cylinders per device */ |
377 | __le32 d_phys_trk; /* # of physical tracks per cylinder */ | 379 | __le32 d_phys_trk; /* # of physical tracks per cylinder */ |
378 | __le32 d_phys_sec; /* # of physical sectors per track */ | 380 | __le32 d_phys_sec; /* # of physical sectors per track */ |
379 | __le32 d_phys_bytes; /* # of physical bytes per sector */ | 381 | __le32 d_phys_bytes; /* # of physical bytes per sector */ |
380 | __le32 d_unknown2; /* ? */ | 382 | __le32 d_unknown2; /* ? */ |
381 | __le32 d_unknown3; /* ? */ | 383 | __le32 d_unknown3; /* ? */ |
382 | __le32 d_pad[8]; /* pad */ | 384 | __le32 d_pad[8]; /* pad */ |
383 | 385 | ||
384 | struct unixware_vtoc { | 386 | struct unixware_vtoc { |
385 | __le32 v_magic; /* the magic number */ | 387 | __le32 v_magic; /* the magic number */ |
386 | __le32 v_version; /* version number */ | 388 | __le32 v_version; /* version number */ |
387 | char v_name[8]; /* volume name */ | 389 | char v_name[8]; /* volume name */ |
388 | __le16 v_nslices; /* # of slices */ | 390 | __le16 v_nslices; /* # of slices */ |
389 | __le16 v_unknown1; /* ? */ | 391 | __le16 v_unknown1; /* ? */ |
390 | __le32 v_reserved[10]; /* reserved */ | 392 | __le32 v_reserved[10]; /* reserved */ |
391 | struct unixware_slice | 393 | struct unixware_slice |
392 | v_slice[UNIXWARE_NUMSLICE]; /* slice headers */ | 394 | v_slice[UNIXWARE_NUMSLICE]; /* slice headers */ |
393 | } vtoc; | 395 | } vtoc; |
394 | 396 | ||
395 | }; /* 408 */ | 397 | }; /* 408 */ |
396 | 398 | ||
397 | #endif /* CONFIG_UNIXWARE_DISKLABEL */ | 399 | #endif /* CONFIG_UNIXWARE_DISKLABEL */ |
398 | 400 | ||
399 | #ifdef CONFIG_MINIX_SUBPARTITION | 401 | #ifdef CONFIG_MINIX_SUBPARTITION |
400 | # define MINIX_NR_SUBPARTITIONS 4 | 402 | # define MINIX_NR_SUBPARTITIONS 4 |
401 | #endif /* CONFIG_MINIX_SUBPARTITION */ | 403 | #endif /* CONFIG_MINIX_SUBPARTITION */ |
402 | 404 | ||
403 | #ifdef __KERNEL__ | 405 | #ifdef __KERNEL__ |
404 | 406 | ||
407 | #define ADDPART_FLAG_NONE 0 | ||
408 | #define ADDPART_FLAG_RAID 1 | ||
409 | #define ADDPART_FLAG_WHOLEDISK 2 | ||
410 | |||
405 | char *disk_name (struct gendisk *hd, int part, char *buf); | 411 | char *disk_name (struct gendisk *hd, int part, char *buf); |
406 | 412 | ||
407 | extern int rescan_partitions(struct gendisk *disk, struct block_device *bdev); | 413 | extern int rescan_partitions(struct gendisk *disk, struct block_device *bdev); |
408 | extern void add_partition(struct gendisk *, int, sector_t, sector_t); | 414 | extern void add_partition(struct gendisk *, int, sector_t, sector_t, int); |
409 | extern void delete_partition(struct gendisk *, int); | 415 | extern void delete_partition(struct gendisk *, int); |
410 | 416 | ||
411 | extern struct gendisk *alloc_disk_node(int minors, int node_id); | 417 | extern struct gendisk *alloc_disk_node(int minors, int node_id); |
412 | extern struct gendisk *alloc_disk(int minors); | 418 | extern struct gendisk *alloc_disk(int minors); |
413 | extern struct kobject *get_disk(struct gendisk *disk); | 419 | extern struct kobject *get_disk(struct gendisk *disk); |
414 | extern void put_disk(struct gendisk *disk); | 420 | extern void put_disk(struct gendisk *disk); |
415 | 421 | ||
416 | extern void blk_register_region(dev_t dev, unsigned long range, | 422 | extern void blk_register_region(dev_t dev, unsigned long range, |
417 | struct module *module, | 423 | struct module *module, |
418 | struct kobject *(*probe)(dev_t, int *, void *), | 424 | struct kobject *(*probe)(dev_t, int *, void *), |
419 | int (*lock)(dev_t, void *), | 425 | int (*lock)(dev_t, void *), |
420 | void *data); | 426 | void *data); |
421 | extern void blk_unregister_region(dev_t dev, unsigned long range); | 427 | extern void blk_unregister_region(dev_t dev, unsigned long range); |
422 | 428 | ||
423 | static inline struct block_device *bdget_disk(struct gendisk *disk, int index) | 429 | static inline struct block_device *bdget_disk(struct gendisk *disk, int index) |
424 | { | 430 | { |
425 | return bdget(MKDEV(disk->major, disk->first_minor) + index); | 431 | return bdget(MKDEV(disk->major, disk->first_minor) + index); |
426 | } | 432 | } |
427 | 433 | ||
428 | #endif | 434 | #endif |
429 | 435 | ||
430 | #endif | 436 | #endif |
431 | 437 | ||
432 | #endif | 438 | #endif |
433 | 439 |