Changeset 20a9b85 in mainline for pci/libpci/generic.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/generic.c
r4a7c273 r20a9b85 13 13 #include "internal.h" 14 14 15 void 16 pci_generic_scan_bus(struct pci_access *a, byte *busmap, int bus) 17 { 18 int dev, multi, ht; 19 struct pci_dev *t; 20 21 a->debug("Scanning bus %02x for devices...\n", bus); 22 if (busmap[bus]) 23 { 24 a->warning("Bus %02x seen twice (firmware bug). Ignored.", bus); 25 return; 26 } 27 busmap[bus] = 1; 28 t = pci_alloc_dev(a); 29 t->bus = bus; 30 for(dev=0; dev<32; dev++) 31 { 32 t->dev = dev; 33 multi = 0; 34 for(t->func=0; !t->func || multi && t->func<8; t->func++) 35 { 36 u32 vd = pci_read_long(t, PCI_VENDOR_ID); 37 struct pci_dev *d; 38 39 if (!vd || vd == 0xffffffff) 40 continue; 41 ht = pci_read_byte(t, PCI_HEADER_TYPE); 42 if (!t->func) 43 multi = ht & 0x80; 44 ht &= 0x7f; 45 d = pci_alloc_dev(a); 46 d->bus = t->bus; 47 d->dev = t->dev; 48 d->func = t->func; 49 d->vendor_id = vd & 0xffff; 50 d->device_id = vd >> 16U; 51 d->known_fields = PCI_FILL_IDENT; 52 d->hdrtype = ht; 53 pci_link_dev(a, d); 54 switch (ht) 55 { 56 case PCI_HEADER_TYPE_NORMAL: 57 break; 58 case PCI_HEADER_TYPE_BRIDGE: 59 case PCI_HEADER_TYPE_CARDBUS: 60 pci_generic_scan_bus(a, busmap, pci_read_byte(t, PCI_SECONDARY_BUS)); 61 break; 62 default: 63 a->debug("Device %04x:%02x:%02x.%d has unknown header type %02x.\n", d->domain, d->bus, d->dev, d->func, ht); 64 } 65 } 66 } 67 pci_free_dev(t); 68 } 69 70 void 71 pci_generic_scan(struct pci_access *a) 72 { 73 byte busmap[256]; 74 75 bzero(busmap, sizeof(busmap)); 76 pci_generic_scan_bus(a, busmap, 0); 77 } 78 79 int 80 pci_generic_fill_info(struct pci_dev *d, int flags) 81 { 82 struct pci_access *a = d->access; 83 84 if ((flags & (PCI_FILL_BASES | PCI_FILL_ROM_BASE)) && d->hdrtype < 0) 85 d->hdrtype = pci_read_byte(d, PCI_HEADER_TYPE) & 0x7f; 86 if (flags & PCI_FILL_IDENT) 87 { 88 d->vendor_id = pci_read_word(d, PCI_VENDOR_ID); 89 d->device_id = pci_read_word(d, PCI_DEVICE_ID); 90 } 91 if (flags & PCI_FILL_IRQ) 92 d->irq = pci_read_byte(d, PCI_INTERRUPT_LINE); 93 if (flags & PCI_FILL_BASES) 94 { 95 int cnt = 0, i; 96 bzero(d->base_addr, sizeof(d->base_addr)); 97 switch (d->hdrtype) 98 { 99 case PCI_HEADER_TYPE_NORMAL: 100 cnt = 6; 101 break; 102 case PCI_HEADER_TYPE_BRIDGE: 103 cnt = 2; 104 break; 105 case PCI_HEADER_TYPE_CARDBUS: 106 cnt = 1; 107 break; 108 } 109 if (cnt) 110 { 111 for(i=0; i<cnt; i++) 112 { 113 u32 x = pci_read_long(d, PCI_BASE_ADDRESS_0 + i*4); 114 if (!x || x == (u32) ~0) 115 continue; 116 if ((x & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO) 117 d->base_addr[i] = x; 118 else 119 { 120 if ((x & PCI_BASE_ADDRESS_MEM_TYPE_MASK) != PCI_BASE_ADDRESS_MEM_TYPE_64) 121 d->base_addr[i] = x; 122 else if (i >= cnt-1) 123 a->warning("%04x:%02x:%02x.%d: Invalid 64-bit address seen for BAR %d.", d->domain, d->bus, d->dev, d->func, i); 124 else 125 { 126 u32 y = pci_read_long(d, PCI_BASE_ADDRESS_0 + (++i)*4); 15 void pci_generic_scan_bus(struct pci_access *a, byte * busmap, int bus) 16 { 17 int dev, multi, ht; 18 struct pci_dev *t; 19 20 a->debug("Scanning bus %02x for devices...\n", bus); 21 if (busmap[bus]) { 22 a->warning("Bus %02x seen twice (firmware bug). Ignored.", 23 bus); 24 return; 25 } 26 busmap[bus] = 1; 27 t = pci_alloc_dev(a); 28 t->bus = bus; 29 for (dev = 0; dev < 32; dev++) { 30 t->dev = dev; 31 multi = 0; 32 for (t->func = 0; !t->func || multi && t->func < 8; 33 t->func++) { 34 u32 vd = pci_read_long(t, PCI_VENDOR_ID); 35 struct pci_dev *d; 36 37 if (!vd || vd == 0xffffffff) 38 continue; 39 ht = pci_read_byte(t, PCI_HEADER_TYPE); 40 if (!t->func) 41 multi = ht & 0x80; 42 ht &= 0x7f; 43 d = pci_alloc_dev(a); 44 d->bus = t->bus; 45 d->dev = t->dev; 46 d->func = t->func; 47 d->vendor_id = vd & 0xffff; 48 d->device_id = vd >> 16U; 49 d->known_fields = PCI_FILL_IDENT; 50 d->hdrtype = ht; 51 pci_link_dev(a, d); 52 switch (ht) { 53 case PCI_HEADER_TYPE_NORMAL: 54 break; 55 case PCI_HEADER_TYPE_BRIDGE: 56 case PCI_HEADER_TYPE_CARDBUS: 57 pci_generic_scan_bus(a, busmap, 58 pci_read_byte(t, 59 PCI_SECONDARY_BUS)); 60 break; 61 default: 62 a->debug 63 ("Device %04x:%02x:%02x.%d has unknown header type %02x.\n", 64 d->domain, d->bus, d->dev, d->func, 65 ht); 66 } 67 } 68 } 69 pci_free_dev(t); 70 } 71 72 void pci_generic_scan(struct pci_access *a) 73 { 74 byte busmap[256]; 75 76 bzero(busmap, sizeof(busmap)); 77 pci_generic_scan_bus(a, busmap, 0); 78 } 79 80 int pci_generic_fill_info(struct pci_dev *d, int flags) 81 { 82 struct pci_access *a = d->access; 83 84 if ((flags & (PCI_FILL_BASES | PCI_FILL_ROM_BASE)) 85 && d->hdrtype < 0) 86 d->hdrtype = pci_read_byte(d, PCI_HEADER_TYPE) & 0x7f; 87 if (flags & PCI_FILL_IDENT) { 88 d->vendor_id = pci_read_word(d, PCI_VENDOR_ID); 89 d->device_id = pci_read_word(d, PCI_DEVICE_ID); 90 } 91 if (flags & PCI_FILL_IRQ) 92 d->irq = pci_read_byte(d, PCI_INTERRUPT_LINE); 93 if (flags & PCI_FILL_BASES) { 94 int cnt = 0, i; 95 bzero(d->base_addr, sizeof(d->base_addr)); 96 switch (d->hdrtype) { 97 case PCI_HEADER_TYPE_NORMAL: 98 cnt = 6; 99 break; 100 case PCI_HEADER_TYPE_BRIDGE: 101 cnt = 2; 102 break; 103 case PCI_HEADER_TYPE_CARDBUS: 104 cnt = 1; 105 break; 106 } 107 if (cnt) { 108 for (i = 0; i < cnt; i++) { 109 u32 x = 110 pci_read_long(d, 111 PCI_BASE_ADDRESS_0 + 112 i * 4); 113 if (!x || x == (u32) ~ 0) 114 continue; 115 if ((x & PCI_BASE_ADDRESS_SPACE) == 116 PCI_BASE_ADDRESS_SPACE_IO) 117 d->base_addr[i] = x; 118 else { 119 if ((x & 120 PCI_BASE_ADDRESS_MEM_TYPE_MASK) 121 != 122 PCI_BASE_ADDRESS_MEM_TYPE_64) 123 d->base_addr[i] = x; 124 else if (i >= cnt - 1) 125 a->warning 126 ("%04x:%02x:%02x.%d: Invalid 64-bit address seen for BAR %d.", 127 d->domain, d->bus, 128 d->dev, d->func, i); 129 else { 130 u32 y = 131 pci_read_long(d, 132 PCI_BASE_ADDRESS_0 133 + 134 (++i) * 135 4); 127 136 #ifdef PCI_HAVE_64BIT_ADDRESS 128 d->base_addr[i-1] = x | (((pciaddr_t) y) << 32); 137 d->base_addr[i - 1] = 138 x | (((pciaddr_t) y) << 139 32); 129 140 #else 130 if (y) 131 a->warning("%04x:%02x:%02x.%d 64-bit device address ignored.", d->domain, d->bus, d->dev, d->func); 132 else 133 d->base_addr[i-1] = x; 141 if (y) 142 a->warning 143 ("%04x:%02x:%02x.%d 64-bit device address ignored.", 144 d->domain, 145 d->bus, 146 d->dev, 147 d->func); 148 else 149 d->base_addr[i - 150 1] = 151 x; 134 152 #endif 135 } 136 } 137 } 138 } 139 } 140 if (flags & PCI_FILL_ROM_BASE) 141 { 142 int reg = 0; 143 d->rom_base_addr = 0; 144 switch (d->hdrtype) 145 { 146 case PCI_HEADER_TYPE_NORMAL: 147 reg = PCI_ROM_ADDRESS; 148 break; 149 case PCI_HEADER_TYPE_BRIDGE: 150 reg = PCI_ROM_ADDRESS1; 151 break; 152 } 153 if (reg) 154 { 155 u32 u = pci_read_long(d, reg); 156 if (u != 0xffffffff) 157 d->rom_base_addr = u; 158 } 159 } 160 return flags & ~PCI_FILL_SIZES; 153 } 154 } 155 } 156 } 157 } 158 if (flags & PCI_FILL_ROM_BASE) { 159 int reg = 0; 160 d->rom_base_addr = 0; 161 switch (d->hdrtype) { 162 case PCI_HEADER_TYPE_NORMAL: 163 reg = PCI_ROM_ADDRESS; 164 break; 165 case PCI_HEADER_TYPE_BRIDGE: 166 reg = PCI_ROM_ADDRESS1; 167 break; 168 } 169 if (reg) { 170 u32 u = pci_read_long(d, reg); 171 if (u != 0xffffffff) 172 d->rom_base_addr = u; 173 } 174 } 175 return flags & ~PCI_FILL_SIZES; 161 176 } 162 177 163 178 static int 164 pci_generic_block_op(struct pci_dev *d, int pos, byte *buf, int len, 165 int (*r)(struct pci_dev *d, int pos, byte *buf, int len)) 166 { 167 if ((pos & 1) && len >= 1) 168 { 169 if (!r(d, pos, buf, 1)) 170 return 0; 171 pos++; buf++; len--; 172 } 173 if ((pos & 3) && len >= 2) 174 { 175 if (!r(d, pos, buf, 2)) 176 return 0; 177 pos += 2; buf += 2; len -= 2; 178 } 179 while (len >= 4) 180 { 181 if (!r(d, pos, buf, 4)) 182 return 0; 183 pos += 4; buf += 4; len -= 4; 184 } 185 if (len >= 2) 186 { 187 if (!r(d, pos, buf, 2)) 188 return 0; 189 pos += 2; buf += 2; len -= 2; 190 } 191 if (len && !r(d, pos, buf, 1)) 192 return 0; 193 return 1; 194 } 195 196 int 197 pci_generic_block_read(struct pci_dev *d, int pos, byte *buf, int len) 198 { 199 return pci_generic_block_op(d, pos, buf, len, d->access->methods->read); 200 } 201 202 int 203 pci_generic_block_write(struct pci_dev *d, int pos, byte *buf, int len) 204 { 205 return pci_generic_block_op(d, pos, buf, len, d->access->methods->write); 206 } 179 pci_generic_block_op(struct pci_dev *d, int pos, byte * buf, int len, 180 int (*r) (struct pci_dev * d, int pos, byte * buf, 181 int len)) 182 { 183 if ((pos & 1) && len >= 1) { 184 if (!r(d, pos, buf, 1)) 185 return 0; 186 pos++; 187 buf++; 188 len--; 189 } 190 if ((pos & 3) && len >= 2) { 191 if (!r(d, pos, buf, 2)) 192 return 0; 193 pos += 2; 194 buf += 2; 195 len -= 2; 196 } 197 while (len >= 4) { 198 if (!r(d, pos, buf, 4)) 199 return 0; 200 pos += 4; 201 buf += 4; 202 len -= 4; 203 } 204 if (len >= 2) { 205 if (!r(d, pos, buf, 2)) 206 return 0; 207 pos += 2; 208 buf += 2; 209 len -= 2; 210 } 211 if (len && !r(d, pos, buf, 1)) 212 return 0; 213 return 1; 214 } 215 216 int pci_generic_block_read(struct pci_dev *d, int pos, byte * buf, int len) 217 { 218 return pci_generic_block_op(d, pos, buf, len, 219 d->access->methods->read); 220 } 221 222 int pci_generic_block_write(struct pci_dev *d, int pos, byte * buf, int len) 223 { 224 return pci_generic_block_op(d, pos, buf, len, 225 d->access->methods->write); 226 }
Note:
See TracChangeset
for help on using the changeset viewer.