Rev 1301 | Rev 1307 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1301 | Rev 1302 | ||
---|---|---|---|
Line 49... | Line 49... | ||
49 | 49 | ||
50 | asm volatile ("inl %1, %0 \n" : "=a" (val) : "d" (port)); |
50 | asm volatile ("inl %1, %0 \n" : "=a" (val) : "d"(port)); |
51 | return val; |
51 | return val; |
52 | } |
52 | } |
53 | 53 | ||
54 | static void |
- | |
55 | conf12_init(struct pci_access *a) |
54 | static void conf12_init(struct pci_access *a) |
56 | { |
55 | { |
57 | } |
56 | } |
58 | 57 | ||
59 | static void |
- | |
60 | conf12_cleanup(struct pci_access *a UNUSED) |
58 | static void conf12_cleanup(struct pci_access *a UNUSED) |
61 | { |
59 | { |
62 | } |
60 | } |
63 | 61 | ||
64 | /* |
62 | /* |
65 | * Before we decide to use direct hardware access mechanisms, we try to do some |
63 | * Before we decide to use direct hardware access mechanisms, we try to do some |
Line 70... | Line 68... | ||
70 | * |
68 | * |
71 | * This should be close to trivial, but it isn't, because there are buggy |
69 | * This should be close to trivial, but it isn't, because there are buggy |
72 | * chipsets (yes, you guessed it, by Intel and Compaq) that have no class ID. |
70 | * chipsets (yes, you guessed it, by Intel and Compaq) that have no class ID. |
73 | */ |
71 | */ |
74 | 72 | ||
75 | static int |
- | |
76 | intel_sanity_check(struct pci_access *a, struct pci_methods *m) |
73 | static int intel_sanity_check(struct pci_access *a, struct pci_methods *m) |
77 | { |
74 | { |
78 | struct pci_dev d; |
75 | struct pci_dev d; |
79 | 76 | ||
80 | a->debug("...sanity check"); |
77 | a->debug("...sanity check"); |
81 | d.bus = 0; |
78 | d.bus = 0; |
82 | d.func = 0; |
79 | d.func = 0; |
83 | for(d.dev = 0; d.dev < 32; d.dev++) |
80 | for (d.dev = 0; d.dev < 32; d.dev++) { |
84 | { |
- | |
85 | u16 class, vendor; |
81 | u16 class, vendor; |
- | 82 | if (m-> |
|
86 | if (m->read(&d, PCI_CLASS_DEVICE, (byte *) &class, sizeof(class)) && |
83 | read(&d, PCI_CLASS_DEVICE, (byte *) & class, |
- | 84 | sizeof(class)) |
|
- | 85 | && (class == cpu_to_le16(PCI_CLASS_BRIDGE_HOST) |
|
87 | (class == cpu_to_le16(PCI_CLASS_BRIDGE_HOST) || class == cpu_to_le16(PCI_CLASS_DISPLAY_VGA)) || |
86 | || class == cpu_to_le16(PCI_CLASS_DISPLAY_VGA)) |
88 | m->read(&d, PCI_VENDOR_ID, (byte *) &vendor, sizeof(vendor)) && |
87 | || m->read(&d, PCI_VENDOR_ID, (byte *) & vendor, |
- | 88 | sizeof(vendor)) |
|
- | 89 | && (vendor == cpu_to_le16(PCI_VENDOR_ID_INTEL) |
|
89 | (vendor == cpu_to_le16(PCI_VENDOR_ID_INTEL) || vendor == cpu_to_le16(PCI_VENDOR_ID_COMPAQ))) |
90 | || vendor == cpu_to_le16(PCI_VENDOR_ID_COMPAQ))) { |
90 | { |
- | |
91 | a->debug("...outside the Asylum at 0/%02x/0", d.dev); |
91 | a->debug("...outside the Asylum at 0/%02x/0", |
- | 92 | d.dev); |
|
92 | return 1; |
93 | return 1; |
93 | } |
94 | } |
94 | } |
95 | } |
95 | a->debug("...insane"); |
96 | a->debug("...insane"); |
96 | return 0; |
97 | return 0; |
Line 100... | Line 101... | ||
100 | * Configuration type 1 |
101 | * Configuration type 1 |
101 | */ |
102 | */ |
102 | 103 | ||
103 | #define CONFIG_CMD(bus, device_fn, where) (0x80000000 | (bus << 16) | (device_fn << 8) | (where & ~3)) |
104 | #define CONFIG_CMD(bus, device_fn, where) (0x80000000 | (bus << 16) | (device_fn << 8) | (where & ~3)) |
104 | 105 | ||
105 | static int |
- | |
106 | conf1_detect(struct pci_access *a) |
106 | static int conf1_detect(struct pci_access *a) |
107 | { |
107 | { |
108 | unsigned int tmp; |
108 | unsigned int tmp; |
109 | int res = 0; |
109 | int res = 0; |
110 | 110 | ||
111 | outb (0x01, 0xCFB); |
111 | outb(0x01, 0xCFB); |
Line 117... | Line 117... | ||
117 | if (res) |
117 | if (res) |
118 | res = intel_sanity_check(a, &pm_intel_conf1); |
118 | res = intel_sanity_check(a, &pm_intel_conf1); |
119 | return res; |
119 | return res; |
120 | } |
120 | } |
121 | 121 | ||
122 | static int |
- | |
123 | conf1_read(struct pci_dev *d, int pos, byte *buf, int len) |
122 | static int conf1_read(struct pci_dev *d, int pos, byte * buf, int len) |
124 | { |
123 | { |
125 | int addr = 0xcfc + (pos&3); |
124 | int addr = 0xcfc + (pos & 3); |
126 | 125 | ||
127 | if (pos >= 256) |
126 | if (pos >= 256) |
128 | return 0; |
127 | return 0; |
129 | 128 | ||
- | 129 | outl(0x80000000 | ((d->bus & 0xff) << 16) | |
|
130 | outl(0x80000000 | ((d->bus & 0xff) << 16) | (PCI_DEVFN(d->dev, d->func) << 8) | (pos&~3), 0xcf8); |
130 | (PCI_DEVFN(d->dev, d->func) << 8) | (pos & ~3), 0xcf8); |
131 | 131 | ||
132 | switch (len) |
132 | switch (len) { |
133 | { |
- | |
134 | case 1: |
133 | case 1: |
135 | buf[0] = inb(addr); |
134 | buf[0] = inb(addr); |
136 | break; |
135 | break; |
137 | case 2: |
136 | case 2: |
138 | ((u16 *) buf)[0] = cpu_to_le16(inw(addr)); |
137 | ((u16 *) buf)[0] = cpu_to_le16(inw(addr)); |
Line 144... | Line 143... | ||
144 | return pci_generic_block_read(d, pos, buf, len); |
143 | return pci_generic_block_read(d, pos, buf, len); |
145 | } |
144 | } |
146 | return 1; |
145 | return 1; |
147 | } |
146 | } |
148 | 147 | ||
149 | static int |
- | |
150 | conf1_write(struct pci_dev *d, int pos, byte *buf, int len) |
148 | static int conf1_write(struct pci_dev *d, int pos, byte * buf, int len) |
151 | { |
149 | { |
152 | int addr = 0xcfc + (pos&3); |
150 | int addr = 0xcfc + (pos & 3); |
153 | 151 | ||
154 | if (pos >= 256) |
152 | if (pos >= 256) |
155 | return 0; |
153 | return 0; |
156 | 154 | ||
- | 155 | outl(0x80000000 | ((d->bus & 0xff) << 16) | |
|
157 | outl(0x80000000 | ((d->bus & 0xff) << 16) | (PCI_DEVFN(d->dev, d->func) << 8) | (pos&~3), 0xcf8); |
156 | (PCI_DEVFN(d->dev, d->func) << 8) | (pos & ~3), 0xcf8); |
158 | 157 | ||
159 | switch (len) |
158 | switch (len) { |
160 | { |
- | |
161 | case 1: |
159 | case 1: |
162 | outb(buf[0], addr); |
160 | outb(buf[0], addr); |
163 | break; |
161 | break; |
164 | case 2: |
162 | case 2: |
165 | outw(le16_to_cpu(((u16 *) buf)[0]), addr); |
163 | outw(le16_to_cpu(((u16 *) buf)[0]), addr); |
Line 175... | Line 173... | ||
175 | 173 | ||
176 | /* |
174 | /* |
177 | * Configuration type 2. Obsolete and brain-damaged, but existing. |
175 | * Configuration type 2. Obsolete and brain-damaged, but existing. |
178 | */ |
176 | */ |
179 | 177 | ||
180 | static int |
- | |
181 | conf2_detect(struct pci_access *a) |
178 | static int conf2_detect(struct pci_access *a) |
182 | { |
179 | { |
183 | /* This is ugly and tends to produce false positives. Beware. */ |
180 | /* This is ugly and tends to produce false positives. Beware. */ |
184 | 181 | ||
185 | outb(0x00, 0xCFB); |
182 | outb(0x00, 0xCFB); |
186 | outb(0x00, 0xCF8); |
183 | outb(0x00, 0xCF8); |
Line 189... | Line 186... | ||
189 | return intel_sanity_check(a, &pm_intel_conf2); |
186 | return intel_sanity_check(a, &pm_intel_conf2); |
190 | else |
187 | else |
191 | return 0; |
188 | return 0; |
192 | } |
189 | } |
193 | 190 | ||
194 | static int |
- | |
195 | conf2_read(struct pci_dev *d, int pos, byte *buf, int len) |
191 | static int conf2_read(struct pci_dev *d, int pos, byte * buf, int len) |
196 | { |
192 | { |
197 | int addr = 0xc000 | (d->dev << 8) | pos; |
193 | int addr = 0xc000 | (d->dev << 8) | pos; |
198 | 194 | ||
199 | if (pos >= 256) |
195 | if (pos >= 256) |
200 | return 0; |
196 | return 0; |
Line 202... | Line 198... | ||
202 | if (d->dev >= 16) |
198 | if (d->dev >= 16) |
203 | /* conf2 supports only 16 devices per bus */ |
199 | /* conf2 supports only 16 devices per bus */ |
204 | return 0; |
200 | return 0; |
205 | outb((d->func << 1) | 0xf0, 0xcf8); |
201 | outb((d->func << 1) | 0xf0, 0xcf8); |
206 | outb(d->bus, 0xcfa); |
202 | outb(d->bus, 0xcfa); |
207 | switch (len) |
203 | switch (len) { |
208 | { |
- | |
209 | case 1: |
204 | case 1: |
210 | buf[0] = inb(addr); |
205 | buf[0] = inb(addr); |
211 | break; |
206 | break; |
212 | case 2: |
207 | case 2: |
213 | ((u16 *) buf)[0] = cpu_to_le16(inw(addr)); |
208 | ((u16 *) buf)[0] = cpu_to_le16(inw(addr)); |
Line 221... | Line 216... | ||
221 | } |
216 | } |
222 | outb(0, 0xcf8); |
217 | outb(0, 0xcf8); |
223 | return 1; |
218 | return 1; |
224 | } |
219 | } |
225 | 220 | ||
226 | static int |
- | |
227 | conf2_write(struct pci_dev *d, int pos, byte *buf, int len) |
221 | static int conf2_write(struct pci_dev *d, int pos, byte * buf, int len) |
228 | { |
222 | { |
229 | int addr = 0xc000 | (d->dev << 8) | pos; |
223 | int addr = 0xc000 | (d->dev << 8) | pos; |
230 | 224 | ||
231 | if (pos >= 256) |
225 | if (pos >= 256) |
232 | return 0; |
226 | return 0; |
233 | 227 | ||
234 | if (d->dev >= 16) |
228 | if (d->dev >= 16) |
- | 229 | d->access-> |
|
235 | d->access->error("conf2_write: only first 16 devices exist."); |
230 | error("conf2_write: only first 16 devices exist."); |
236 | outb((d->func << 1) | 0xf0, 0xcf8); |
231 | outb((d->func << 1) | 0xf0, 0xcf8); |
237 | outb(d->bus, 0xcfa); |
232 | outb(d->bus, 0xcfa); |
238 | switch (len) |
233 | switch (len) { |
239 | { |
- | |
240 | case 1: |
234 | case 1: |
241 | outb(buf[0], addr); |
235 | outb(buf[0], addr); |
242 | break; |
236 | break; |
243 | case 2: |
237 | case 2: |
244 | outw(le16_to_cpu(* (u16 *) buf), addr); |
238 | outw(le16_to_cpu(*(u16 *) buf), addr); |