Rev 3022 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 3022 | Rev 4204 | ||
---|---|---|---|
Line 7... | Line 7... | ||
7 | * |
7 | * |
8 | * Can be freely distributed and used under the terms of the GNU GPL. |
8 | * Can be freely distributed and used under the terms of the GNU GPL. |
9 | */ |
9 | */ |
10 | 10 | ||
11 | #include <unistd.h> |
11 | #include <unistd.h> |
- | 12 | #include <ddi.h> |
|
- | 13 | #include <libarch/ddi.h> |
|
12 | 14 | ||
13 | #include "internal.h" |
15 | #include "internal.h" |
14 | 16 | ||
15 | static inline void outb(u8 b, u16 port) |
- | |
16 | { |
- | |
17 | asm volatile ("outb %0, %1\n" :: "a" (b), "d" (port)); |
- | |
18 | } |
- | |
19 | - | ||
20 | static inline void outw(u16 w, u16 port) |
- | |
21 | { |
- | |
22 | asm volatile ("outw %0, %1\n" :: "a" (w), "d" (port)); |
- | |
23 | } |
- | |
24 | - | ||
25 | static inline void outl(u32 l, u16 port) |
- | |
26 | { |
- | |
27 | asm volatile ("outl %0, %1\n" :: "a" (l), "d" (port)); |
- | |
28 | } |
- | |
29 | - | ||
30 | static inline u8 inb(u16 port) |
- | |
31 | { |
- | |
32 | u8 val; |
- | |
33 | - | ||
34 | asm volatile ("inb %1, %0 \n" : "=a" (val) : "d"(port)); |
- | |
35 | return val; |
- | |
36 | } |
- | |
37 | - | ||
38 | static inline u16 inw(u16 port) |
- | |
39 | { |
- | |
40 | u16 val; |
- | |
41 | - | ||
42 | asm volatile ("inw %1, %0 \n" : "=a" (val) : "d"(port)); |
- | |
43 | return val; |
- | |
44 | } |
- | |
45 | - | ||
46 | static inline u32 inl(u16 port) |
- | |
47 | { |
- | |
48 | u32 val; |
- | |
49 | - | ||
50 | asm volatile ("inl %1, %0 \n" : "=a" (val) : "d"(port)); |
- | |
51 | return val; |
- | |
52 | } |
- | |
53 | 17 | ||
54 | static void conf12_init(struct pci_access *a) |
18 | static void conf12_init(struct pci_access *a) |
55 | { |
19 | { |
56 | } |
20 | } |
57 | 21 | ||
Line 105... | Line 69... | ||
105 | static int conf1_detect(struct pci_access *a) |
69 | static int conf1_detect(struct pci_access *a) |
106 | { |
70 | { |
107 | unsigned int tmp; |
71 | unsigned int tmp; |
108 | int res = 0; |
72 | int res = 0; |
109 | 73 | ||
110 | outb(0x01, 0xCFB); |
74 | pio_write_8(0xCFB, 0x01); |
111 | tmp = inl(0xCF8); |
75 | tmp = pio_read_32(0xCF8); |
112 | outl(0x80000000, 0xCF8); |
76 | pio_write_32(0xCF8, 0x80000000); |
113 | if (inl(0xCF8) == 0x80000000) |
77 | if (pio_read_32(0xCF8) == 0x80000000) { |
114 | res = 1; |
78 | res = 1; |
- | 79 | } |
|
115 | outl(tmp, 0xCF8); |
80 | pio_write_32(0xCF8, tmp); |
116 | if (res) |
81 | if (res) { |
117 | res = intel_sanity_check(a, &pm_intel_conf1); |
82 | res = intel_sanity_check(a, &pm_intel_conf1); |
- | 83 | } |
|
118 | return res; |
84 | return res; |
119 | } |
85 | } |
120 | 86 | ||
121 | static int conf1_read(struct pci_dev *d, int pos, byte * buf, int len) |
87 | static int conf1_read(struct pci_dev *d, int pos, byte * buf, int len) |
122 | { |
88 | { |
123 | int addr = 0xcfc + (pos & 3); |
89 | int addr = 0xcfc + (pos & 3); |
124 | 90 | ||
125 | if (pos >= 256) |
91 | if (pos >= 256) |
126 | return 0; |
92 | return 0; |
127 | 93 | ||
128 | outl(0x80000000 | ((d->bus & 0xff) << 16) | |
94 | pio_write_32(0xcf8, 0x80000000 | ((d->bus & 0xff) << 16) | |
129 | (PCI_DEVFN(d->dev, d->func) << 8) | (pos & ~3), 0xcf8); |
95 | (PCI_DEVFN(d->dev, d->func) << 8) | (pos & ~3)); |
130 | 96 | ||
131 | switch (len) { |
97 | switch (len) { |
132 | case 1: |
98 | case 1: |
133 | buf[0] = inb(addr); |
99 | buf[0] = pio_read_8(addr); |
134 | break; |
100 | break; |
135 | case 2: |
101 | case 2: |
136 | ((u16 *) buf)[0] = cpu_to_le16(inw(addr)); |
102 | ((u16 *) buf)[0] = cpu_to_le16(pio_read_16(addr)); |
137 | break; |
103 | break; |
138 | case 4: |
104 | case 4: |
139 | ((u32 *) buf)[0] = cpu_to_le32(inl(addr)); |
105 | ((u32 *) buf)[0] = cpu_to_le32(pio_read_32(addr)); |
140 | break; |
106 | break; |
141 | default: |
107 | default: |
142 | return pci_generic_block_read(d, pos, buf, len); |
108 | return pci_generic_block_read(d, pos, buf, len); |
143 | } |
109 | } |
144 | return 1; |
110 | return 1; |
Line 149... | Line 115... | ||
149 | int addr = 0xcfc + (pos & 3); |
115 | int addr = 0xcfc + (pos & 3); |
150 | 116 | ||
151 | if (pos >= 256) |
117 | if (pos >= 256) |
152 | return 0; |
118 | return 0; |
153 | 119 | ||
154 | outl(0x80000000 | ((d->bus & 0xff) << 16) | |
120 | pio_write_32(0xcf8, 0x80000000 | ((d->bus & 0xff) << 16) | |
155 | (PCI_DEVFN(d->dev, d->func) << 8) | (pos & ~3), 0xcf8); |
121 | (PCI_DEVFN(d->dev, d->func) << 8) | (pos & ~3)); |
156 | 122 | ||
157 | switch (len) { |
123 | switch (len) { |
158 | case 1: |
124 | case 1: |
159 | outb(buf[0], addr); |
125 | pio_write_8(addr, buf[0]); |
160 | break; |
126 | break; |
161 | case 2: |
127 | case 2: |
162 | outw(le16_to_cpu(((u16 *) buf)[0]), addr); |
128 | pio_write_16(addr, le16_to_cpu(((u16 *) buf)[0])); |
163 | break; |
129 | break; |
164 | case 4: |
130 | case 4: |
165 | outl(le32_to_cpu(((u32 *) buf)[0]), addr); |
131 | pio_write_32(addr, le32_to_cpu(((u32 *) buf)[0])); |
166 | break; |
132 | break; |
167 | default: |
133 | default: |
168 | return pci_generic_block_write(d, pos, buf, len); |
134 | return pci_generic_block_write(d, pos, buf, len); |
169 | } |
135 | } |
170 | return 1; |
136 | return 1; |
Line 175... | Line 141... | ||
175 | */ |
141 | */ |
176 | 142 | ||
177 | static int conf2_detect(struct pci_access *a) |
143 | static int conf2_detect(struct pci_access *a) |
178 | { |
144 | { |
179 | /* This is ugly and tends to produce false positives. Beware. */ |
145 | /* This is ugly and tends to produce false positives. Beware. */ |
180 | outb(0x00, 0xCFB); |
146 | pio_write_8(0xCFB, 0x00); |
181 | outb(0x00, 0xCF8); |
147 | pio_write_8(0xCF8, 0x00); |
182 | outb(0x00, 0xCFA); |
148 | pio_write_8(0xCFA, 0x00); |
183 | if (inb(0xCF8) == 0x00 && inb(0xCFA) == 0x00) |
149 | if (pio_read_8(0xCF8) == 0x00 && pio_read_8(0xCFA) == 0x00) |
184 | return intel_sanity_check(a, &pm_intel_conf2); |
150 | return intel_sanity_check(a, &pm_intel_conf2); |
185 | else |
151 | else |
186 | return 0; |
152 | return 0; |
187 | } |
153 | } |
188 | 154 | ||
Line 194... | Line 160... | ||
194 | return 0; |
160 | return 0; |
195 | 161 | ||
196 | if (d->dev >= 16) |
162 | if (d->dev >= 16) |
197 | /* conf2 supports only 16 devices per bus */ |
163 | /* conf2 supports only 16 devices per bus */ |
198 | return 0; |
164 | return 0; |
199 | outb((d->func << 1) | 0xf0, 0xcf8); |
165 | pio_write_8(0xcf8, (d->func << 1) | 0xf0); |
200 | outb(d->bus, 0xcfa); |
166 | pio_write_8(0xcfa, d->bus); |
201 | switch (len) { |
167 | switch (len) { |
202 | case 1: |
168 | case 1: |
203 | buf[0] = inb(addr); |
169 | buf[0] = pio_read_8(addr); |
204 | break; |
170 | break; |
205 | case 2: |
171 | case 2: |
206 | ((u16 *) buf)[0] = cpu_to_le16(inw(addr)); |
172 | ((u16 *) buf)[0] = cpu_to_le16(pio_read_16(addr)); |
207 | break; |
173 | break; |
208 | case 4: |
174 | case 4: |
209 | ((u32 *) buf)[0] = cpu_to_le32(inl(addr)); |
175 | ((u32 *) buf)[0] = cpu_to_le32(pio_read_32(addr)); |
210 | break; |
176 | break; |
211 | default: |
177 | default: |
212 | outb(0, 0xcf8); |
178 | pio_write_8(0xcf8, 0); |
213 | return pci_generic_block_read(d, pos, buf, len); |
179 | return pci_generic_block_read(d, pos, buf, len); |
214 | } |
180 | } |
215 | outb(0, 0xcf8); |
181 | pio_write_8((void *)0xcf8, 0); |
216 | return 1; |
182 | return 1; |
217 | } |
183 | } |
218 | 184 | ||
219 | static int conf2_write(struct pci_dev *d, int pos, byte * buf, int len) |
185 | static int conf2_write(struct pci_dev *d, int pos, byte * buf, int len) |
220 | { |
186 | { |
Line 223... | Line 189... | ||
223 | if (pos >= 256) |
189 | if (pos >= 256) |
224 | return 0; |
190 | return 0; |
225 | 191 | ||
226 | if (d->dev >= 16) |
192 | if (d->dev >= 16) |
227 | d->access->error("conf2_write: only first 16 devices exist."); |
193 | d->access->error("conf2_write: only first 16 devices exist."); |
228 | outb((d->func << 1) | 0xf0, 0xcf8); |
194 | pio_write_8(0xcf8, (d->func << 1) | 0xf0); |
229 | outb(d->bus, 0xcfa); |
195 | pio_write_8(0xcfa, d->bus); |
230 | switch (len) { |
196 | switch (len) { |
231 | case 1: |
197 | case 1: |
232 | outb(buf[0], addr); |
198 | pio_write_8(addr, buf[0]); |
233 | break; |
199 | break; |
234 | case 2: |
200 | case 2: |
235 | outw(le16_to_cpu(*(u16 *) buf), addr); |
201 | pio_write_16(addr, le16_to_cpu(*(u16 *) buf)); |
236 | break; |
202 | break; |
237 | case 4: |
203 | case 4: |
238 | outl(le32_to_cpu(*(u32 *) buf), addr); |
204 | pio_write_32(addr, le32_to_cpu(*(u32 *) buf)); |
239 | break; |
205 | break; |
240 | default: |
206 | default: |
241 | outb(0, 0xcf8); |
207 | pio_write_8(0xcf8, 0); |
242 | return pci_generic_block_write(d, pos, buf, len); |
208 | return pci_generic_block_write(d, pos, buf, len); |
243 | } |
209 | } |
244 | outb(0, 0xcf8); |
210 | pio_write_8(0xcf8, 0); |
245 | return 1; |
211 | return 1; |
246 | } |
212 | } |
247 | 213 | ||
248 | struct pci_methods pm_intel_conf1 = { |
214 | struct pci_methods pm_intel_conf1 = { |
249 | "Intel-conf1", |
215 | "Intel-conf1", |