Changeset 20a9b85 in mainline for pci/libpci/i386-ports.c
- Timestamp:
- 2006-05-09T10:55:02Z (19 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 46ec2c06
- Parents:
- 4a7c273
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pci/libpci/i386-ports.c
r4a7c273 r20a9b85 15 15 static inline void outb(u8 b, u16 port) 16 16 { 17 asm volatile ("outb %0, %1\n" : 17 asm volatile ("outb %0, %1\n" :: "a" (b), "d" (port)); 18 18 } 19 19 20 20 static inline void outw(u16 w, u16 port) 21 21 { 22 asm volatile ("outw %0, %1\n" : 22 asm volatile ("outw %0, %1\n" :: "a" (w), "d" (port)); 23 23 } 24 24 25 25 static inline void outl(u32 l, u16 port) 26 26 { 27 asm volatile ("outl %0, %1\n" : 27 asm volatile ("outl %0, %1\n" :: "a" (l), "d" (port)); 28 28 } 29 29 … … 31 31 { 32 32 u8 val; 33 34 asm volatile ("inb %1, %0 \n" : "=a" (val) : "d" 33 34 asm volatile ("inb %1, %0 \n" : "=a" (val) : "d"(port)); 35 35 return val; 36 36 } … … 39 39 { 40 40 u16 val; 41 42 asm volatile ("inw %1, %0 \n" : "=a" (val) : "d" 41 42 asm volatile ("inw %1, %0 \n" : "=a" (val) : "d"(port)); 43 43 return val; 44 44 } … … 47 47 { 48 48 u32 val; 49 50 asm volatile ("inl %1, %0 \n" : "=a" (val) : "d" 49 50 asm volatile ("inl %1, %0 \n" : "=a" (val) : "d"(port)); 51 51 return val; 52 52 } 53 53 54 static void 55 conf12_init(struct pci_access *a) 56 { 57 } 58 59 static void 60 conf12_cleanup(struct pci_access *a UNUSED) 54 static void conf12_init(struct pci_access *a) 55 { 56 } 57 58 static void conf12_cleanup(struct pci_access *a UNUSED) 61 59 { 62 60 } … … 73 71 */ 74 72 75 static int 76 intel_sanity_check(struct pci_access *a, struct pci_methods *m) 77 { 78 struct pci_dev d; 79 80 a->debug("...sanity check"); 81 d.bus = 0; 82 d.func = 0; 83 for(d.dev = 0; d.dev < 32; d.dev++) 84 { 85 u16 class, vendor; 86 if (m->read(&d, PCI_CLASS_DEVICE, (byte *) &class, sizeof(class)) && 87 (class == cpu_to_le16(PCI_CLASS_BRIDGE_HOST) || class == cpu_to_le16(PCI_CLASS_DISPLAY_VGA)) || 88 m->read(&d, PCI_VENDOR_ID, (byte *) &vendor, sizeof(vendor)) && 89 (vendor == cpu_to_le16(PCI_VENDOR_ID_INTEL) || vendor == cpu_to_le16(PCI_VENDOR_ID_COMPAQ))) 90 { 91 a->debug("...outside the Asylum at 0/%02x/0", d.dev); 92 return 1; 93 } 94 } 95 a->debug("...insane"); 96 return 0; 73 static int intel_sanity_check(struct pci_access *a, struct pci_methods *m) 74 { 75 struct pci_dev d; 76 77 a->debug("...sanity check"); 78 d.bus = 0; 79 d.func = 0; 80 for (d.dev = 0; d.dev < 32; d.dev++) { 81 u16 class, vendor; 82 if (m-> 83 read(&d, PCI_CLASS_DEVICE, (byte *) & class, 84 sizeof(class)) 85 && (class == cpu_to_le16(PCI_CLASS_BRIDGE_HOST) 86 || class == cpu_to_le16(PCI_CLASS_DISPLAY_VGA)) 87 || m->read(&d, PCI_VENDOR_ID, (byte *) & vendor, 88 sizeof(vendor)) 89 && (vendor == cpu_to_le16(PCI_VENDOR_ID_INTEL) 90 || vendor == cpu_to_le16(PCI_VENDOR_ID_COMPAQ))) { 91 a->debug("...outside the Asylum at 0/%02x/0", 92 d.dev); 93 return 1; 94 } 95 } 96 a->debug("...insane"); 97 return 0; 97 98 } 98 99 … … 103 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) 107 { 108 unsigned int tmp; 109 int res = 0; 110 111 outb (0x01, 0xCFB); 112 tmp = inl (0xCF8); 113 outl (0x80000000, 0xCF8); 114 if (inl (0xCF8) == 0x80000000) 115 res = 1; 116 outl (tmp, 0xCF8); 117 if (res) 118 res = intel_sanity_check(a, &pm_intel_conf1); 119 return res; 120 } 121 122 static int 123 conf1_read(struct pci_dev *d, int pos, byte *buf, int len) 124 { 125 int addr = 0xcfc + (pos&3); 126 127 if (pos >= 256) 128 return 0; 129 130 outl(0x80000000 | ((d->bus & 0xff) << 16) | (PCI_DEVFN(d->dev, d->func) << 8) | (pos&~3), 0xcf8); 131 132 switch (len) 133 { 134 case 1: 135 buf[0] = inb(addr); 136 break; 137 case 2: 138 ((u16 *) buf)[0] = cpu_to_le16(inw(addr)); 139 break; 140 case 4: 141 ((u32 *) buf)[0] = cpu_to_le32(inl(addr)); 142 break; 143 default: 144 return pci_generic_block_read(d, pos, buf, len); 145 } 146 return 1; 147 } 148 149 static int 150 conf1_write(struct pci_dev *d, int pos, byte *buf, int len) 151 { 152 int addr = 0xcfc + (pos&3); 153 154 if (pos >= 256) 155 return 0; 156 157 outl(0x80000000 | ((d->bus & 0xff) << 16) | (PCI_DEVFN(d->dev, d->func) << 8) | (pos&~3), 0xcf8); 158 159 switch (len) 160 { 161 case 1: 162 outb(buf[0], addr); 163 break; 164 case 2: 165 outw(le16_to_cpu(((u16 *) buf)[0]), addr); 166 break; 167 case 4: 168 outl(le32_to_cpu(((u32 *) buf)[0]), addr); 169 break; 170 default: 171 return pci_generic_block_write(d, pos, buf, len); 172 } 173 return 1; 106 static int conf1_detect(struct pci_access *a) 107 { 108 unsigned int tmp; 109 int res = 0; 110 111 outb(0x01, 0xCFB); 112 tmp = inl(0xCF8); 113 outl(0x80000000, 0xCF8); 114 if (inl(0xCF8) == 0x80000000) 115 res = 1; 116 outl(tmp, 0xCF8); 117 if (res) 118 res = intel_sanity_check(a, &pm_intel_conf1); 119 return res; 120 } 121 122 static int conf1_read(struct pci_dev *d, int pos, byte * buf, int len) 123 { 124 int addr = 0xcfc + (pos & 3); 125 126 if (pos >= 256) 127 return 0; 128 129 outl(0x80000000 | ((d->bus & 0xff) << 16) | 130 (PCI_DEVFN(d->dev, d->func) << 8) | (pos & ~3), 0xcf8); 131 132 switch (len) { 133 case 1: 134 buf[0] = inb(addr); 135 break; 136 case 2: 137 ((u16 *) buf)[0] = cpu_to_le16(inw(addr)); 138 break; 139 case 4: 140 ((u32 *) buf)[0] = cpu_to_le32(inl(addr)); 141 break; 142 default: 143 return pci_generic_block_read(d, pos, buf, len); 144 } 145 return 1; 146 } 147 148 static int conf1_write(struct pci_dev *d, int pos, byte * buf, int len) 149 { 150 int addr = 0xcfc + (pos & 3); 151 152 if (pos >= 256) 153 return 0; 154 155 outl(0x80000000 | ((d->bus & 0xff) << 16) | 156 (PCI_DEVFN(d->dev, d->func) << 8) | (pos & ~3), 0xcf8); 157 158 switch (len) { 159 case 1: 160 outb(buf[0], addr); 161 break; 162 case 2: 163 outw(le16_to_cpu(((u16 *) buf)[0]), addr); 164 break; 165 case 4: 166 outl(le32_to_cpu(((u32 *) buf)[0]), addr); 167 break; 168 default: 169 return pci_generic_block_write(d, pos, buf, len); 170 } 171 return 1; 174 172 } 175 173 … … 178 176 */ 179 177 180 static int 181 conf2_detect(struct pci_access *a) 182 { 183 /* This is ugly and tends to produce false positives. Beware. */ 184 185 outb(0x00, 0xCFB); 186 outb(0x00, 0xCF8); 187 outb(0x00, 0xCFA); 188 if (inb(0xCF8) == 0x00 && inb(0xCFA) == 0x00) 189 return intel_sanity_check(a, &pm_intel_conf2); 190 else 191 return 0; 192 } 193 194 static int 195 conf2_read(struct pci_dev *d, int pos, byte *buf, int len) 196 { 197 int addr = 0xc000 | (d->dev << 8) | pos; 198 199 if (pos >= 256) 200 return 0; 201 202 if (d->dev >= 16) 203 /* conf2 supports only 16 devices per bus */ 204 return 0; 205 outb((d->func << 1) | 0xf0, 0xcf8); 206 outb(d->bus, 0xcfa); 207 switch (len) 208 { 209 case 1: 210 buf[0] = inb(addr); 211 break; 212 case 2: 213 ((u16 *) buf)[0] = cpu_to_le16(inw(addr)); 214 break; 215 case 4: 216 ((u32 *) buf)[0] = cpu_to_le32(inl(addr)); 217 break; 218 default: 219 outb(0, 0xcf8); 220 return pci_generic_block_read(d, pos, buf, len); 221 } 222 outb(0, 0xcf8); 223 return 1; 224 } 225 226 static int 227 conf2_write(struct pci_dev *d, int pos, byte *buf, int len) 228 { 229 int addr = 0xc000 | (d->dev << 8) | pos; 230 231 if (pos >= 256) 232 return 0; 233 234 if (d->dev >= 16) 235 d->access->error("conf2_write: only first 16 devices exist."); 236 outb((d->func << 1) | 0xf0, 0xcf8); 237 outb(d->bus, 0xcfa); 238 switch (len) 239 { 240 case 1: 241 outb(buf[0], addr); 242 break; 243 case 2: 244 outw(le16_to_cpu(* (u16 *) buf), addr); 245 break; 246 case 4: 247 outl(le32_to_cpu(* (u32 *) buf), addr); 248 break; 249 default: 250 outb(0, 0xcf8); 251 return pci_generic_block_write(d, pos, buf, len); 252 } 253 outb(0, 0xcf8); 254 return 1; 178 static int conf2_detect(struct pci_access *a) 179 { 180 /* This is ugly and tends to produce false positives. Beware. */ 181 182 outb(0x00, 0xCFB); 183 outb(0x00, 0xCF8); 184 outb(0x00, 0xCFA); 185 if (inb(0xCF8) == 0x00 && inb(0xCFA) == 0x00) 186 return intel_sanity_check(a, &pm_intel_conf2); 187 else 188 return 0; 189 } 190 191 static int conf2_read(struct pci_dev *d, int pos, byte * buf, int len) 192 { 193 int addr = 0xc000 | (d->dev << 8) | pos; 194 195 if (pos >= 256) 196 return 0; 197 198 if (d->dev >= 16) 199 /* conf2 supports only 16 devices per bus */ 200 return 0; 201 outb((d->func << 1) | 0xf0, 0xcf8); 202 outb(d->bus, 0xcfa); 203 switch (len) { 204 case 1: 205 buf[0] = inb(addr); 206 break; 207 case 2: 208 ((u16 *) buf)[0] = cpu_to_le16(inw(addr)); 209 break; 210 case 4: 211 ((u32 *) buf)[0] = cpu_to_le32(inl(addr)); 212 break; 213 default: 214 outb(0, 0xcf8); 215 return pci_generic_block_read(d, pos, buf, len); 216 } 217 outb(0, 0xcf8); 218 return 1; 219 } 220 221 static int conf2_write(struct pci_dev *d, int pos, byte * buf, int len) 222 { 223 int addr = 0xc000 | (d->dev << 8) | pos; 224 225 if (pos >= 256) 226 return 0; 227 228 if (d->dev >= 16) 229 d->access-> 230 error("conf2_write: only first 16 devices exist."); 231 outb((d->func << 1) | 0xf0, 0xcf8); 232 outb(d->bus, 0xcfa); 233 switch (len) { 234 case 1: 235 outb(buf[0], addr); 236 break; 237 case 2: 238 outw(le16_to_cpu(*(u16 *) buf), addr); 239 break; 240 case 4: 241 outl(le32_to_cpu(*(u32 *) buf), addr); 242 break; 243 default: 244 outb(0, 0xcf8); 245 return pci_generic_block_write(d, pos, buf, len); 246 } 247 outb(0, 0xcf8); 248 return 1; 255 249 } 256 250 257 251 struct pci_methods pm_intel_conf1 = { 258 259 NULL,/* config */260 261 262 263 264 265 266 267 NULL,/* init_dev */268 NULL/* cleanup_dev */252 "Intel-conf1", 253 NULL, /* config */ 254 conf1_detect, 255 conf12_init, 256 conf12_cleanup, 257 pci_generic_scan, 258 pci_generic_fill_info, 259 conf1_read, 260 conf1_write, 261 NULL, /* init_dev */ 262 NULL /* cleanup_dev */ 269 263 }; 270 264 271 265 struct pci_methods pm_intel_conf2 = { 272 273 NULL,/* config */274 275 276 277 278 279 280 281 NULL,/* init_dev */282 NULL/* cleanup_dev */266 "Intel-conf2", 267 NULL, /* config */ 268 conf2_detect, 269 conf12_init, 270 conf12_cleanup, 271 pci_generic_scan, 272 pci_generic_fill_info, 273 conf2_read, 274 conf2_write, 275 NULL, /* init_dev */ 276 NULL /* cleanup_dev */ 283 277 };
Note:
See TracChangeset
for help on using the changeset viewer.