Rev 1627 | Rev 1631 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1627 | Rev 1628 | ||
---|---|---|---|
Line 6... | Line 6... | ||
6 | 6 | ||
Line 7... | Line 7... | ||
7 | LIST_HEAD(pci_root_buses); |
7 | LIST_HEAD(pci_root_buses); |
Line 8... | Line 8... | ||
8 | 8 | ||
- | 9 | #define IO_SPACE_LIMIT 0xffff |
|
Line 9... | Line 10... | ||
9 | #define IO_SPACE_LIMIT 0xffff |
10 | #define PCIBIOS_SUCCESSFUL 0x00 |
10 | 11 | ||
11 | struct resource ioport_resource = { |
12 | struct resource ioport_resource = { |
12 | .name = "PCI IO", |
13 | .name = "PCI IO", |
Line 21... | Line 22... | ||
21 | .end = -1, |
22 | .end = -1, |
22 | .flags = IORESOURCE_MEM, |
23 | .flags = IORESOURCE_MEM, |
23 | }; |
24 | }; |
24 | 25 | ||
Line -... | Line 26... | ||
- | 26 | #define PCI_FIND_CAP_TTL 48 |
|
Line 25... | Line 27... | ||
25 | 27 | ||
- | 28 | static int __pci_find_next_cap_ttl(struct pci_bus *bus, unsigned int devfn, |
|
26 | static inline int pci_domain_nr(struct pci_bus *bus) |
29 | u8 pos, int cap, int *ttl) |
- | 30 | { |
|
- | 31 | u8 id; |
|
- | 32 | ||
- | 33 | while ((*ttl)--) { |
|
- | 34 | pci_bus_read_config_byte(bus, devfn, pos, &pos); |
|
- | 35 | if (pos < 0x40) |
|
- | 36 | break; |
|
- | 37 | pos &= ~3; |
|
- | 38 | pci_bus_read_config_byte(bus, devfn, pos + PCI_CAP_LIST_ID, |
|
- | 39 | &id); |
|
- | 40 | if (id == 0xff) |
|
- | 41 | break; |
|
- | 42 | if (id == cap) |
|
- | 43 | return pos; |
|
- | 44 | pos += PCI_CAP_LIST_NEXT; |
|
- | 45 | } |
|
- | 46 | return 0; |
|
- | 47 | } |
|
- | 48 | ||
- | 49 | static int __pci_find_next_cap(struct pci_bus *bus, unsigned int devfn, |
|
- | 50 | u8 pos, int cap) |
|
- | 51 | { |
|
- | 52 | int ttl = PCI_FIND_CAP_TTL; |
|
- | 53 | ||
- | 54 | return __pci_find_next_cap_ttl(bus, devfn, pos, cap, &ttl); |
|
- | 55 | } |
|
- | 56 | static int __pci_bus_find_cap_start(struct pci_bus *bus, |
|
- | 57 | unsigned int devfn, u8 hdr_type) |
|
- | 58 | { |
|
- | 59 | u16 status; |
|
- | 60 | ||
- | 61 | pci_bus_read_config_word(bus, devfn, PCI_STATUS, &status); |
|
- | 62 | if (!(status & PCI_STATUS_CAP_LIST)) |
|
- | 63 | return 0; |
|
- | 64 | ||
- | 65 | switch (hdr_type) { |
|
- | 66 | case PCI_HEADER_TYPE_NORMAL: |
|
- | 67 | case PCI_HEADER_TYPE_BRIDGE: |
|
- | 68 | return PCI_CAPABILITY_LIST; |
|
- | 69 | case PCI_HEADER_TYPE_CARDBUS: |
|
- | 70 | return PCI_CB_CAPABILITY_LIST; |
|
- | 71 | default: |
|
- | 72 | return 0; |
|
- | 73 | } |
|
- | 74 | ||
- | 75 | return 0; |
|
- | 76 | } |
|
- | 77 | ||
- | 78 | ||
- | 79 | /** |
|
- | 80 | * pci_find_capability - query for devices' capabilities |
|
- | 81 | * @dev: PCI device to query |
|
- | 82 | * @cap: capability code |
|
- | 83 | * |
|
- | 84 | * Tell if a device supports a given PCI capability. |
|
- | 85 | * Returns the address of the requested capability structure within the |
|
27 | { |
86 | * device's PCI configuration space or 0 in case the device does not |
- | 87 | * support it. Possible values for @cap: |
|
- | 88 | * |
|
- | 89 | * %PCI_CAP_ID_PM Power Management |
|
- | 90 | * %PCI_CAP_ID_AGP Accelerated Graphics Port |
|
- | 91 | * %PCI_CAP_ID_VPD Vital Product Data |
|
- | 92 | * %PCI_CAP_ID_SLOTID Slot Identification |
|
- | 93 | * %PCI_CAP_ID_MSI Message Signalled Interrupts |
|
- | 94 | * %PCI_CAP_ID_CHSWP CompactPCI HotSwap |
|
- | 95 | * %PCI_CAP_ID_PCIX PCI-X |
|
- | 96 | * %PCI_CAP_ID_EXP PCI Express |
|
- | 97 | */ |
|
- | 98 | int pci_find_capability(struct pci_dev *dev, int cap) |
|
- | 99 | { |
|
- | 100 | int pos; |
|
- | 101 | ||
- | 102 | pos = __pci_bus_find_cap_start(dev->bus, dev->devfn, dev->hdr_type); |
|
- | 103 | if (pos) |
|
- | 104 | pos = __pci_find_next_cap(dev->bus, dev->devfn, pos, cap); |
|
28 | struct pci_sysdata *sd = bus->sysdata; |
105 | |
29 | return sd->domain; |
106 | return pos; |
Line -... | Line 107... | ||
- | 107 | } |
|
30 | } |
108 | |
31 | 109 | ||
32 | static struct pci_bus * pci_alloc_bus(void) |
110 | static struct pci_bus * pci_alloc_bus(void) |
Line 33... | Line 111... | ||
33 | { |
111 | { |
Line 147... | Line 225... | ||
147 | return b; |
225 | return b; |
148 | } |
226 | } |
149 | 227 | ||
Line -... | Line 228... | ||
- | 228 | ||
- | 229 | /** |
|
- | 230 | * pci_get_slot - locate PCI device for a given PCI slot |
|
- | 231 | * @bus: PCI bus on which desired PCI device resides |
|
- | 232 | * @devfn: encodes number of PCI slot in which the desired PCI |
|
- | 233 | * device resides and the logical device number within that slot |
|
- | 234 | * in case of multi-function devices. |
|
- | 235 | * |
|
- | 236 | * Given a PCI bus and slot/function number, the desired PCI device |
|
- | 237 | * is located in the list of PCI devices. |
|
- | 238 | * If the device is found, its reference count is increased and this |
|
- | 239 | * function returns a pointer to its data structure. The caller must |
|
- | 240 | * decrement the reference count by calling pci_dev_put(). |
|
- | 241 | * If no device is found, %NULL is returned. |
|
- | 242 | */ |
|
- | 243 | struct pci_dev * pci_get_slot(struct pci_bus *bus, unsigned int devfn) |
|
- | 244 | { |
|
- | 245 | struct list_head *tmp; |
|
- | 246 | struct pci_dev *dev; |
|
- | 247 | ||
- | 248 | // WARN_ON(in_interrupt()); |
|
- | 249 | // down_read(&pci_bus_sem); |
|
- | 250 | ||
- | 251 | list_for_each(tmp, &bus->devices) { |
|
- | 252 | dev = pci_dev_b(tmp); |
|
- | 253 | if (dev->devfn == devfn) |
|
- | 254 | goto out; |
|
- | 255 | } |
|
- | 256 | ||
- | 257 | dev = NULL; |
|
- | 258 | out: |
|
- | 259 | // pci_dev_get(dev); |
|
- | 260 | // up_read(&pci_bus_sem); |
|
- | 261 | return dev; |
|
- | 262 | } |
|
- | 263 | ||
- | 264 | ||
- | 265 | ||
- | 266 | ||
- | 267 | /** |
|
- | 268 | * pci_find_ext_capability - Find an extended capability |
|
- | 269 | * @dev: PCI device to query |
|
- | 270 | * @cap: capability code |
|
- | 271 | * |
|
- | 272 | * Returns the address of the requested extended capability structure |
|
- | 273 | * within the device's PCI configuration space or 0 if the device does |
|
- | 274 | * not support it. Possible values for @cap: |
|
- | 275 | * |
|
- | 276 | * %PCI_EXT_CAP_ID_ERR Advanced Error Reporting |
|
- | 277 | * %PCI_EXT_CAP_ID_VC Virtual Channel |
|
- | 278 | * %PCI_EXT_CAP_ID_DSN Device Serial Number |
|
- | 279 | * %PCI_EXT_CAP_ID_PWR Power Budgeting |
|
- | 280 | */ |
|
- | 281 | int pci_find_ext_capability(struct pci_dev *dev, int cap) |
|
- | 282 | { |
|
- | 283 | u32 header; |
|
- | 284 | int ttl; |
|
- | 285 | int pos = PCI_CFG_SPACE_SIZE; |
|
- | 286 | ||
- | 287 | /* minimum 8 bytes per capability */ |
|
- | 288 | ttl = (PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE) / 8; |
|
- | 289 | ||
- | 290 | if (dev->cfg_size <= PCI_CFG_SPACE_SIZE) |
|
- | 291 | return 0; |
|
- | 292 | ||
- | 293 | if (pci_read_config_dword(dev, pos, &header) != PCIBIOS_SUCCESSFUL) |
|
- | 294 | return 0; |
|
- | 295 | ||
- | 296 | /* |
|
- | 297 | * If we have no capabilities, this is indicated by cap ID, |
|
- | 298 | * cap version and next pointer all being 0. |
|
- | 299 | */ |
|
- | 300 | if (header == 0) |
|
- | 301 | return 0; |
|
- | 302 | ||
- | 303 | while (ttl-- > 0) { |
|
- | 304 | if (PCI_EXT_CAP_ID(header) == cap) |
|
- | 305 | return pos; |
|
- | 306 | ||
- | 307 | pos = PCI_EXT_CAP_NEXT(header); |
|
- | 308 | if (pos < PCI_CFG_SPACE_SIZE) |
|
- | 309 | break; |
|
- | 310 | ||
- | 311 | if (pci_read_config_dword(dev, pos, &header) != PCIBIOS_SUCCESSFUL) |
|
- | 312 | break; |
|
- | 313 | } |
|
- | 314 | ||
- | 315 | return 0; |
|
- | 316 | }>=>> |