1/*- 2 * Copyright (c) 1997, Stefan Esser <se@freebsd.org> 3 * Copyright (c) 2000, Michael Smith <msmith@freebsd.org> 4 * Copyright (c) 2000, BSDi 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions --- 13 unchanged lines hidden (view full) --- 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29#include <sys/cdefs.h> |
30__FBSDID("$FreeBSD: head/sys/dev/pci/pci.c 232472 2012-03-03 18:08:57Z jhb $"); |
31 32#include "opt_bus.h" 33 34#include <sys/param.h> 35#include <sys/systm.h> 36#include <sys/malloc.h> 37#include <sys/module.h> 38#include <sys/linker.h> --- 133 unchanged lines hidden (view full) --- 172 DEVMETHOD(pci_disable_busmaster, pci_disable_busmaster_method), 173 DEVMETHOD(pci_enable_io, pci_enable_io_method), 174 DEVMETHOD(pci_disable_io, pci_disable_io_method), 175 DEVMETHOD(pci_get_vpd_ident, pci_get_vpd_ident_method), 176 DEVMETHOD(pci_get_vpd_readonly, pci_get_vpd_readonly_method), 177 DEVMETHOD(pci_get_powerstate, pci_get_powerstate_method), 178 DEVMETHOD(pci_set_powerstate, pci_set_powerstate_method), 179 DEVMETHOD(pci_assign_interrupt, pci_assign_interrupt_method), |
180 DEVMETHOD(pci_find_cap, pci_find_cap_method), |
181 DEVMETHOD(pci_find_extcap, pci_find_extcap_method), |
182 DEVMETHOD(pci_find_htcap, pci_find_htcap_method), |
183 DEVMETHOD(pci_alloc_msi, pci_alloc_msi_method), 184 DEVMETHOD(pci_alloc_msix, pci_alloc_msix_method), 185 DEVMETHOD(pci_remap_msix, pci_remap_msix_method), 186 DEVMETHOD(pci_release_msi, pci_release_msi_method), 187 DEVMETHOD(pci_msi_count, pci_msi_count_method), 188 DEVMETHOD(pci_msix_count, pci_msix_count_method), 189 190 DEVMETHOD_END --- 543 unchanged lines hidden (view full) --- 734 pcix_chipset = 1; 735 break; 736 case PCIY_EXPRESS: /* PCI-express */ 737 /* 738 * Assume we have a PCI-express chipset if we have 739 * at least one PCI-express device. 740 */ 741 pcie_chipset = 1; |
742 cfg->pcie.pcie_location = ptr; 743 val = REG(ptr + PCIR_EXPRESS_FLAGS, 2); 744 cfg->pcie.pcie_type = val & PCIM_EXP_FLAGS_TYPE; |
745 break; 746 default: 747 break; 748 } 749 } 750 751#if defined(__i386__) || defined(__amd64__) || defined(__powerpc__) 752 /* --- 401 unchanged lines hidden (view full) --- 1154 return (0); 1155 } 1156 1157 *vptr = NULL; 1158 return (ENXIO); 1159} 1160 1161/* |
1162 * Find the requested HyperTransport capability and return the offset 1163 * in configuration space via the pointer provided. The function 1164 * returns 0 on success and an error code otherwise. |
1165 */ 1166int |
1167pci_find_htcap_method(device_t dev, device_t child, int capability, int *capreg) 1168{ 1169 int ptr, error; 1170 uint16_t val; 1171 1172 error = pci_find_cap(child, PCIY_HT, &ptr); 1173 if (error) 1174 return (error); 1175 1176 /* 1177 * Traverse the capabilities list checking each HT capability 1178 * to see if it matches the requested HT capability. 1179 */ 1180 while (ptr != 0) { 1181 val = pci_read_config(child, ptr + PCIR_HT_COMMAND, 2); 1182 if (capability == PCIM_HTCAP_SLAVE || 1183 capability == PCIM_HTCAP_HOST) 1184 val &= 0xe000; 1185 else 1186 val &= PCIM_HTCMD_CAP_MASK; 1187 if (val == capability) { 1188 if (capreg != NULL) 1189 *capreg = ptr; 1190 return (0); 1191 } 1192 1193 /* Skip to the next HT capability. */ 1194 while (ptr != 0) { 1195 ptr = pci_read_config(child, ptr + PCICAP_NEXTPTR, 1); 1196 if (pci_read_config(child, ptr + PCICAP_ID, 1) == 1197 PCIY_HT) 1198 break; 1199 } 1200 } 1201 return (ENOENT); 1202} 1203 1204/* 1205 * Find the requested capability and return the offset in 1206 * configuration space via the pointer provided. The function returns 1207 * 0 on success and an error code otherwise. 1208 */ 1209int 1210pci_find_cap_method(device_t dev, device_t child, int capability, |
1211 int *capreg) 1212{ 1213 struct pci_devinfo *dinfo = device_get_ivars(child); 1214 pcicfgregs *cfg = &dinfo->cfg; 1215 u_int32_t status; 1216 u_int8_t ptr; 1217 1218 /* --- 31 unchanged lines hidden (view full) --- 1250 } 1251 ptr = pci_read_config(child, ptr + PCICAP_NEXTPTR, 1); 1252 } 1253 1254 return (ENOENT); 1255} 1256 1257/* |
1258 * Find the requested extended capability and return the offset in 1259 * configuration space via the pointer provided. The function returns 1260 * 0 on success and an error code otherwise. 1261 */ 1262int 1263pci_find_extcap_method(device_t dev, device_t child, int capability, 1264 int *capreg) 1265{ 1266 struct pci_devinfo *dinfo = device_get_ivars(child); 1267 pcicfgregs *cfg = &dinfo->cfg; 1268 uint32_t ecap; 1269 uint16_t ptr; 1270 1271 /* Only supported for PCI-express devices. */ 1272 if (cfg->pcie.pcie_location == 0) 1273 return (ENXIO); 1274 1275 ptr = PCIR_EXTCAP; 1276 ecap = pci_read_config(child, ptr, 4); 1277 if (ecap == 0xffffffff || ecap == 0) 1278 return (ENOENT); 1279 for (;;) { 1280 if (PCI_EXTCAP_ID(ecap) == capability) { 1281 if (capreg != NULL) 1282 *capreg = ptr; 1283 return (0); 1284 } 1285 ptr = PCI_EXTCAP_NEXTPTR(ecap); 1286 if (ptr == 0) 1287 break; 1288 ecap = pci_read_config(child, ptr, 4); 1289 } 1290 1291 return (ENOENT); 1292} 1293 1294/* |
1295 * Support for MSI-X message interrupts. 1296 */ 1297void 1298pci_enable_msix(device_t dev, u_int index, uint64_t address, uint32_t data) 1299{ 1300 struct pci_devinfo *dinfo = device_get_ivars(dev); 1301 struct pcicfg_msix *msix = &dinfo->cfg.msix; 1302 uint32_t offset; --- 473 unchanged lines hidden (view full) --- 1776 pci_write_config(dev, ht->ht_msimap + PCIR_HT_COMMAND, 1777 ht->ht_msictrl, 2); 1778 } 1779} 1780 1781int 1782pci_get_max_read_req(device_t dev) 1783{ |
1784 struct pci_devinfo *dinfo = device_get_ivars(dev); |
1785 int cap; 1786 uint16_t val; 1787 |
1788 cap = dinfo->cfg.pcie.pcie_location; 1789 if (cap == 0) |
1790 return (0); 1791 val = pci_read_config(dev, cap + PCIR_EXPRESS_DEVICE_CTL, 2); 1792 val &= PCIM_EXP_CTL_MAX_READ_REQUEST; 1793 val >>= 12; 1794 return (1 << (val + 7)); 1795} 1796 1797int 1798pci_set_max_read_req(device_t dev, int size) 1799{ |
1800 struct pci_devinfo *dinfo = device_get_ivars(dev); |
1801 int cap; 1802 uint16_t val; 1803 |
1804 cap = dinfo->cfg.pcie.pcie_location; 1805 if (cap == 0) |
1806 return (0); 1807 if (size < 128) 1808 size = 128; 1809 if (size > 4096) 1810 size = 4096; 1811 size = (1 << (fls(size) - 1)); 1812 val = pci_read_config(dev, cap + PCIR_EXPRESS_DEVICE_CTL, 2); 1813 val &= ~PCIM_EXP_CTL_MAX_READ_REQUEST; --- 2776 unchanged lines hidden --- |