1 /* 2 * The PCI Library -- User Access 3 * 4 * Copyright (c) 1997--2014 Martin Mares <[email protected]> 5 * 6 * Can be freely distributed and used under the terms of the GNU GPL. 7 */ 8 9 #include <stdio.h> 10 #include <stdlib.h> 11 #include <stdarg.h> 12 #include <string.h> 13 14 #include "internal.h" 15 16 void 17 pci_scan_bus(struct pci_access *a) 18 { 19 a->methods->scan(a); 20 } 21 22 struct pci_dev * 23 pci_alloc_dev(struct pci_access *a) 24 { 25 struct pci_dev *d = pci_malloc(a, sizeof(struct pci_dev)); 26 27 memset(d, 0, sizeof(*d)); 28 d->access = a; 29 d->methods = a->methods; 30 d->hdrtype = -1; 31 d->numa_node = -1; 32 if (d->methods->init_dev) 33 d->methods->init_dev(d); 34 return d; 35 } 36 37 int 38 pci_link_dev(struct pci_access *a, struct pci_dev *d) 39 { 40 d->next = a->devices; 41 a->devices = d; 42 43 return 1; 44 } 45 46 struct pci_dev * 47 pci_get_dev(struct pci_access *a, int domain, int bus, int dev, int func) 48 { 49 struct pci_dev *d = pci_alloc_dev(a); 50 51 d->domain = domain; 52 d->bus = bus; 53 d->dev = dev; 54 d->func = func; 55 return d; 56 } 57 58 void pci_free_dev(struct pci_dev *d) 59 { 60 if (d->methods->cleanup_dev) 61 d->methods->cleanup_dev(d); 62 pci_free_caps(d); 63 pci_mfree(d->module_alias); 64 pci_mfree(d->label); 65 pci_mfree(d->phy_slot); 66 pci_mfree(d); 67 } 68 69 static inline void 70 pci_read_data(struct pci_dev *d, void *buf, int pos, int len) 71 { 72 if (pos & (len-1)) 73 d->access->error("Unaligned read: pos=%02x, len=%d", pos, len); 74 if (pos + len <= d->cache_len) 75 memcpy(buf, d->cache + pos, len); 76 else if (!d->methods->read(d, pos, buf, len)) 77 memset(buf, 0xff, len); 78 } 79 80 byte 81 pci_read_byte(struct pci_dev *d, int pos) 82 { 83 byte buf; 84 pci_read_data(d, &buf, pos, 1); 85 return buf; 86 } 87 88 word 89 pci_read_word(struct pci_dev *d, int pos) 90 { 91 word buf; 92 pci_read_data(d, &buf, pos, 2); 93 return le16_to_cpu(buf); 94 } 95 96 u32 97 pci_read_long(struct pci_dev *d, int pos) 98 { 99 u32 buf; 100 pci_read_data(d, &buf, pos, 4); 101 return le32_to_cpu(buf); 102 } 103 104 int 105 pci_read_block(struct pci_dev *d, int pos, byte *buf, int len) 106 { 107 return d->methods->read(d, pos, buf, len); 108 } 109 110 int 111 pci_read_vpd(struct pci_dev *d, int pos, byte *buf, int len) 112 { 113 return d->methods->read_vpd ? d->methods->read_vpd(d, pos, buf, len) : 0; 114 } 115 116 static inline int 117 pci_write_data(struct pci_dev *d, void *buf, int pos, int len) 118 { 119 if (pos & (len-1)) 120 d->access->error("Unaligned write: pos=%02x,len=%d", pos, len); 121 if (pos + len <= d->cache_len) 122 memcpy(d->cache + pos, buf, len); 123 return d->methods->write(d, pos, buf, len); 124 } 125 126 int 127 pci_write_byte(struct pci_dev *d, int pos, byte data) 128 { 129 return pci_write_data(d, &data, pos, 1); 130 } 131 132 int 133 pci_write_word(struct pci_dev *d, int pos, word data) 134 { 135 word buf = cpu_to_le16(data); 136 return pci_write_data(d, &buf, pos, 2); 137 } 138 139 int 140 pci_write_long(struct pci_dev *d, int pos, u32 data) 141 { 142 u32 buf = cpu_to_le32(data); 143 return pci_write_data(d, &buf, pos, 4); 144 } 145 146 int 147 pci_write_block(struct pci_dev *d, int pos, byte *buf, int len) 148 { 149 if (pos < d->cache_len) 150 { 151 int l = (pos + len >= d->cache_len) ? (d->cache_len - pos) : len; 152 memcpy(d->cache + pos, buf, l); 153 } 154 return d->methods->write(d, pos, buf, len); 155 } 156 157 int 158 pci_fill_info_v35(struct pci_dev *d, int flags) 159 { 160 if (flags & PCI_FILL_RESCAN) 161 { 162 flags &= ~PCI_FILL_RESCAN; 163 d->known_fields = 0; 164 pci_free_caps(d); 165 } 166 if (flags & ~d->known_fields) 167 d->known_fields |= d->methods->fill_info(d, flags & ~d->known_fields); 168 return d->known_fields; 169 } 170 171 /* In version 3.1, pci_fill_info got new flags => versioned alias */ 172 /* In versions 3.2, 3.3, 3.4 and 3.5, the same has happened */ 173 STATIC_ALIAS(int pci_fill_info(struct pci_dev *d, int flags), pci_fill_info_v35(d, flags)); 174 DEFINE_ALIAS(int pci_fill_info_v30(struct pci_dev *d, int flags), pci_fill_info_v35); 175 DEFINE_ALIAS(int pci_fill_info_v31(struct pci_dev *d, int flags), pci_fill_info_v35); 176 DEFINE_ALIAS(int pci_fill_info_v32(struct pci_dev *d, int flags), pci_fill_info_v35); 177 DEFINE_ALIAS(int pci_fill_info_v33(struct pci_dev *d, int flags), pci_fill_info_v35); 178 DEFINE_ALIAS(int pci_fill_info_v34(struct pci_dev *d, int flags), pci_fill_info_v35); 179 SYMBOL_VERSION(pci_fill_info_v30, pci_fill_info@LIBPCI_3.0); 180 SYMBOL_VERSION(pci_fill_info_v31, pci_fill_info@LIBPCI_3.1); 181 SYMBOL_VERSION(pci_fill_info_v32, pci_fill_info@LIBPCI_3.2); 182 SYMBOL_VERSION(pci_fill_info_v33, pci_fill_info@LIBPCI_3.3); 183 SYMBOL_VERSION(pci_fill_info_v34, pci_fill_info@LIBPCI_3.4); 184 SYMBOL_VERSION(pci_fill_info_v35, pci_fill_info@@LIBPCI_3.5); 185 186 void 187 pci_setup_cache(struct pci_dev *d, byte *cache, int len) 188 { 189 d->cache = cache; 190 d->cache_len = len; 191 } 192