Update to FreeBSD head 2016-12-10

Git mirror commit 80c55f08a05ab3b26a73b226ccb56adc3122a55c.
This commit is contained in:
Sebastian Huber
2016-12-09 14:19:03 +01:00
parent c4e89a9125
commit 75b706fde4
227 changed files with 3800 additions and 3006 deletions

View File

@@ -3981,7 +3981,7 @@ pci_rescan_method(device_t dev)
if (hdrtype & PCIM_MFDEV)
pcifunchigh = PCIB_MAXFUNCS(pcib);
for (f = 0; f <= pcifunchigh; f++) {
if (REG(PCIR_VENDOR, 2) == 0xfff)
if (REG(PCIR_VENDOR, 2) == 0xffff)
continue;
/*
@@ -4081,6 +4081,7 @@ pci_add_child(device_t bus, struct pci_devinfo *dinfo)
pci_print_verbose(dinfo);
pci_add_resources(bus, dinfo->cfg.dev, 0, 0);
pci_child_added(dinfo->cfg.dev);
EVENTHANDLER_INVOKE(pci_add_device, dinfo->cfg.dev);
}
void
@@ -4617,6 +4618,9 @@ static const struct
{PCIC_CRYPTO, PCIS_CRYPTO_ENTERTAIN, 1, "entertainment crypto"},
{PCIC_DASP, -1, 0, "dasp"},
{PCIC_DASP, PCIS_DASP_DPIO, 1, "DPIO module"},
{PCIC_DASP, PCIS_DASP_PERFCNTRS, 1, "performance counters"},
{PCIC_DASP, PCIS_DASP_COMM_SYNC, 1, "communication synchronizer"},
{PCIC_DASP, PCIS_DASP_MGMT_CARD, 1, "signal processing management"},
{0, 0, 0, NULL}
};
@@ -5009,6 +5013,7 @@ pci_reserve_map(device_t dev, device_t child, int type, int *rid,
struct resource_list *rl = &dinfo->resources;
struct resource *res;
struct pci_map *pm;
uint16_t cmd;
pci_addr_t map, testval;
int mapsize;
@@ -5107,8 +5112,17 @@ pci_reserve_map(device_t dev, device_t child, int type, int *rid,
device_printf(child,
"Lazy allocation of %#jx bytes rid %#x type %d at %#jx\n",
count, *rid, type, rman_get_start(res));
/* Disable decoding via the CMD register before updating the BAR */
cmd = pci_read_config(child, PCIR_COMMAND, 2);
pci_write_config(child, PCIR_COMMAND,
cmd & ~(PCI_BAR_MEM(map) ? PCIM_CMD_MEMEN : PCIM_CMD_PORTEN), 2);
map = rman_get_start(res);
pci_write_bar(child, pm, map);
/* Restore the original value of the CMD register */
pci_write_config(child, PCIR_COMMAND, cmd, 2);
out:
return (res);
}
@@ -5331,6 +5345,8 @@ pci_child_deleted(device_t dev, device_t child)
dinfo = device_get_ivars(child);
rl = &dinfo->resources;
EVENTHANDLER_INVOKE(pci_delete_device, child);
/* Turn off access to resources we're about to free */
if (bus_child_present(child) != 0) {
pci_write_config(child, PCIR_COMMAND, pci_read_config(child,
@@ -5908,3 +5924,165 @@ pci_find_pcie_root_port(device_t dev)
dev = pcib;
}
}
/*
* Wait for pending transactions to complete on a PCI-express function.
*
* The maximum delay is specified in milliseconds in max_delay. Note
* that this function may sleep.
*
* Returns true if the function is idle and false if the timeout is
* exceeded. If dev is not a PCI-express function, this returns true.
*/
bool
pcie_wait_for_pending_transactions(device_t dev, u_int max_delay)
{
struct pci_devinfo *dinfo = device_get_ivars(dev);
uint16_t sta;
int cap;
cap = dinfo->cfg.pcie.pcie_location;
if (cap == 0)
return (true);
sta = pci_read_config(dev, cap + PCIER_DEVICE_STA, 2);
while (sta & PCIEM_STA_TRANSACTION_PND) {
if (max_delay == 0)
return (false);
/* Poll once every 100 milliseconds up to the timeout. */
if (max_delay > 100) {
pause_sbt("pcietp", 100 * SBT_1MS, 0, C_HARDCLOCK);
max_delay -= 100;
} else {
pause_sbt("pcietp", max_delay * SBT_1MS, 0,
C_HARDCLOCK);
max_delay = 0;
}
sta = pci_read_config(dev, cap + PCIER_DEVICE_STA, 2);
}
return (true);
}
/*
* Determine the maximum Completion Timeout in microseconds.
*
* For non-PCI-express functions this returns 0.
*/
int
pcie_get_max_completion_timeout(device_t dev)
{
struct pci_devinfo *dinfo = device_get_ivars(dev);
int cap;
cap = dinfo->cfg.pcie.pcie_location;
if (cap == 0)
return (0);
/*
* Functions using the 1.x spec use the default timeout range of
* 50 microseconds to 50 milliseconds. Functions that do not
* support programmable timeouts also use this range.
*/
if ((dinfo->cfg.pcie.pcie_flags & PCIEM_FLAGS_VERSION) < 2 ||
(pci_read_config(dev, cap + PCIER_DEVICE_CAP2, 4) &
PCIEM_CAP2_COMP_TIMO_RANGES) == 0)
return (50 * 1000);
switch (pci_read_config(dev, cap + PCIER_DEVICE_CTL2, 2) &
PCIEM_CTL2_COMP_TIMO_VAL) {
case PCIEM_CTL2_COMP_TIMO_100US:
return (100);
case PCIEM_CTL2_COMP_TIMO_10MS:
return (10 * 1000);
case PCIEM_CTL2_COMP_TIMO_55MS:
return (55 * 1000);
case PCIEM_CTL2_COMP_TIMO_210MS:
return (210 * 1000);
case PCIEM_CTL2_COMP_TIMO_900MS:
return (900 * 1000);
case PCIEM_CTL2_COMP_TIMO_3500MS:
return (3500 * 1000);
case PCIEM_CTL2_COMP_TIMO_13S:
return (13 * 1000 * 1000);
case PCIEM_CTL2_COMP_TIMO_64S:
return (64 * 1000 * 1000);
default:
return (50 * 1000);
}
}
/*
* Perform a Function Level Reset (FLR) on a device.
*
* This function first waits for any pending transactions to complete
* within the timeout specified by max_delay. If transactions are
* still pending, the function will return false without attempting a
* reset.
*
* If dev is not a PCI-express function or does not support FLR, this
* function returns false.
*
* Note that no registers are saved or restored. The caller is
* responsible for saving and restoring any registers including
* PCI-standard registers via pci_save_state() and
* pci_restore_state().
*/
bool
pcie_flr(device_t dev, u_int max_delay, bool force)
{
struct pci_devinfo *dinfo = device_get_ivars(dev);
uint16_t cmd, ctl;
int compl_delay;
int cap;
cap = dinfo->cfg.pcie.pcie_location;
if (cap == 0)
return (false);
if (!(pci_read_config(dev, cap + PCIER_DEVICE_CAP, 4) & PCIEM_CAP_FLR))
return (false);
/*
* Disable busmastering to prevent generation of new
* transactions while waiting for the device to go idle. If
* the idle timeout fails, the command register is restored
* which will re-enable busmastering.
*/
cmd = pci_read_config(dev, PCIR_COMMAND, 2);
pci_write_config(dev, PCIR_COMMAND, cmd & ~(PCIM_CMD_BUSMASTEREN), 2);
if (!pcie_wait_for_pending_transactions(dev, max_delay)) {
if (!force) {
pci_write_config(dev, PCIR_COMMAND, cmd, 2);
return (false);
}
pci_printf(&dinfo->cfg,
"Resetting with transactions pending after %d ms\n",
max_delay);
/*
* Extend the post-FLR delay to cover the maximum
* Completion Timeout delay of anything in flight
* during the FLR delay. Enforce a minimum delay of
* at least 10ms.
*/
compl_delay = pcie_get_max_completion_timeout(dev) / 1000;
if (compl_delay < 10)
compl_delay = 10;
} else
compl_delay = 0;
/* Initiate the reset. */
ctl = pci_read_config(dev, cap + PCIER_DEVICE_CTL, 2);
pci_write_config(dev, cap + PCIER_DEVICE_CTL, ctl |
PCIEM_CTL_INITIATE_FLR, 2);
/* Wait for 100ms. */
pause_sbt("pcieflr", (100 + compl_delay) * SBT_1MS, 0, C_HARDCLOCK);
if (pci_read_config(dev, cap + PCIER_DEVICE_STA, 2) &
PCIEM_STA_TRANSACTION_PND)
pci_printf(&dinfo->cfg, "Transactions pending after FLR!\n");
return (true);
}