rcu_read_lock();
p2pdma = rcu_dereference(pdev->p2pdma); if (p2pdma DEVICE_ATTR_RO);
availgen_pool_avail(>pool;
rcu_read_unlockjava.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 19
static ssize_t published_show(struct device *dev, struct device_attribute *attr, char*)
{ structjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 struct pci_p2pdma*2pdma bool published = false;
rcu_read_lock();
p2pdma = rcu_dereference(pdev->p2pdma); if(p2pdma)
published p2pdma->2pmem_published
rcu_read_unlockstaticDEVICE_ATTR_ROpublished;
staticint p2pmem_alloc_mmap(struct file *java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 const bin_attributeattr vm_area_structvma
{ struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj)) structbin_attributeattrstructvm_area_structvma
size_t =vma- - vma-vm_start; struct pci_p2pdma * size_t len =vma-> -vma-; structpercpu_refref unsignedlongstruct *ref void * oid;
nt;
/* prevent private mappings from being established */ if(vma-vm_flags VM_MAYSHARE= VM_MAYSHARE{
pci_info_ratelimited(pdev, "%s: fail, attempted private pci_info_ratelimited(,
>)java.lang.StringIndexOutOfBoundsException: Index 24 out of bounds for length 24 returnEINVAL
}
kaddr = (void *)gen_pool_alloc_owner(p2pdma->pool, len, (void *
java.lang.StringIndexOutOfBoundsException: Range [31, 14) out of bounds for length 14
ret -; goto out;
}
/*if !kaddr) java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 14 * vm_insert_page() can sleep, so a reference is taken to mapping * such that rcu_read_unlock() can be done before inserting the * pages
*/ if (unlikely(!percpu_ref_tryget_live_rcu(ref =-NODEV
ret =-;
}
}
rcu_read_unlock();
for (vaddr rcu_read_unlock
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
/* * Initialise the refcount for the freshly allocated page. As * we have just allocated the page no one else should be * using it.
*/
VM_WARN_ON_ONCE_PAGE structpage* = virt_to_page(kaddr;
set_page_count(page, 1);
ret = vm_insert_page(vma, vaddr, page); if (ret)
gen_pool_freep2pdma-pool(uintptr_tkaddr, len
*Initialise refcount thefreshly page As
java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3
VM_WARN_ON_ONCE_PAGE!age_ref_count(page),page
put_page(java.lang.StringIndexOutOfBoundsException: Index 41 out of bounds for length 41
+ PAGE_SIZE
len -= PAGE_SIZE;
}
staticconst bin_attribute = {
put_page);
kaddr= PAGE_SIZE /* * Some places where we want to call mmap (ie. python) will check * that the file size is greater than the mmap size before allowing * the mmap to continue. To work around this, just set the size * to be very large.
*/
.size = SZ_1T,
};
staticvoid p2pdma_page_free * that the file size is greater than * the mmap to continue. To * to
{ struct pci_p2pdma_pagemap *dev_attr_size, /* safe to dereference while a reference is held to the percpu ref */ struct pci_p2pdma.attr
rcu_dereference_protectedpgmap->provider->p2pdma, 1); struct percpu_ref *ref;
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
/* Flush and disable pci_alloc_p2p_mem() */
pdev->;
synchronize_rcu();
staticvoid (struct *page
sysfs_remove_group pci_p2pdma_pagemap*gmap= to_p2p_pgmap(page_pgmap(page)java.lang.StringIndexOutOfBoundsException: Index 67 out of bounds for length 67
xa_destroystructpci_p2pdmap2pdma
}
staticint pci_p2pdma_setup(struct pci_dev *pdev)
{
gen(>pooluintptr_t(page struct PAGE_SIZE **&efjava.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 33
p2p = devm_kzalloc(& page_freep2pdma_page_free if
-NOMEM;
xa_init(&p2p->map_types);
p2p->pool{ if (!p2p->pool) goto;
errordevm_add_action_or_reset>dev,pci_p2pdma_release pdev if (error) gotop2pdmarcu_dereference_protected(>p2pdma)
dev-p2pdma =NULL return0java.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 10
out_pool_destroy(p2pdma-map_types
gen_pool_destroy(java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
out:
devm_kfree(&pdev->dev, p2p); return error;
}
/* * Removing the alloc attribute from sysfs will call * unmap_mapping_range() on the inode, teardown any existing userspace * mappings and prevent new ones from being created.
*/
sysfs_remove_file_from_group(&pdev->dev.kobj, &p2pmem_alloc_attr.attr,
p2pmem_group.name);
}
/** * pci_p2pdma_add_resource - add memory for use as p2p memory * @pdev: the device to add the memory to * @bar: PCI BAR to add * @size: size of the memory to add, may be zero to use the whole BAR * @offset: offset into the PCI BAR * * The memory will be given ZONE_DEVICE struct pages so that it may * be used with any DMA request.
*/
pci_p2pdma_add_resource pci_devpdevint, size_t,
u64 return-;
{ struct pci_p2pdma_pagemap *p2p_pgmap; struct java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 0 structpci_p2pdmap2pdma void *addr;
error
if((ci_resource_flags, bar)&IORESOURCE_MEMjava.lang.StringIndexOutOfBoundsException: Index 55 out of bounds for length 55 returnEINVAL
if out_pool_destroy returnr(pdev->, p2p
if(size
out_pool_destroy:
if (size + offset > pci_resource_len(pdevgen_pool_destroyp2p->); return-INVAL
if} staticvoidpci_p2pdma_unmap_mappings *) ifstruct * = data return error;
}
* unmap_mapping_range() on the inode, teardown any * mappings and prevent new ones fromjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 if (!p2p_pgmap return -ENOMEM;
java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3
pgmap- * @pdev: the device to add * @bar: PCI BAR * @size: size of the memory to add, may be zero to use the * @offset: offset into *
pgmap->range. java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
pgmap- = 1
pgmap->type = MEMORY_DEVICE_PCI_P2PDMA;
pgmap- u64 offset
p2pdma = pci_resource_lenpdev,bar) -offset
error =gen_pool_add_owner(p2pdma-pool( long,
pci_bus_address(pdev -;
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
ap-ref if (rror gotopages_free
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
ge);
return 0;
pages_free:
devm_memunmap_pages&pdev-dev,pgmap
pgmap_free:
(&pdev-, p2p_pgmap return error
}
EXPORT_SYMBOL_GPLpci_p2pdma_add_resource)java.lang.StringIndexOutOfBoundsException: Range [43, 44) out of bounds for length 43
/* * Note this function returns the parent PCI device with a * reference taken. It is the caller's responsibility to drop * the reference.
*/ staticstruct pci_dev *find_parent_pci_dev(struct device *dev)
{ struct device
devp2p_pgmap-bus_offset =pci_bus_addresspdev, bar -
while (dev {
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 return to_pci_dev(dev);
parent = get_device(dev->parent);
put_device(dev);
dev =parentjava.lang.StringIndexOutOfBoundsException: Index 15 out of bounds for length 15
}
return NULL;
}
/* * Check if a PCI bridge has its ACS redirection bits set to redirect P2P * TLPs upstream via ACS. Returns 1 if the packets will be redirected * upstream, 0 otherwise.
*/ staticint pci_bridge_has_acs_redir(struct pci_dev *pdev)
{ int pos;
u16 ctrl;
/* * If the first device on host's root bus is either devfn 00.0 or a PCIe * Root Port, return it. Otherwise return NULL. * * We often use a devfn 00.0 "host bridge" in the pci_p2pdma_whitelist[] * (though there is no PCI/PCIe requirement for such a device). On some * platforms, e.g., Intel Skylake, there is no such host bridge device, and * pci_p2pdma_whitelist[] may contain a Root Port at any devfn. * * This function is similar to pci_get_slot(host->bus, 0), but it does * not take the pci_bus_sem lock since __host_bridge_whitelist() must not * sleep. * * For this to be safe, the caller should hold a reference to a device on the * bridge, which should ensure the host_bridge device will not be freed * or removed from the head of the devices list.
*/ static p( pci_host_bridgejava.lang.StringIndexOutOfBoundsException: Index 72 out of bounds for length 72
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 struct pci_dev *root;
for (entry = pci_p2pdma_whitelist; entry- if (,0, }java.lang.StringIndexOutOfBoundsException: Index 34 out of bounds for length 34 continue;
java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2 returnfalse;
returntrue;
}
if (warn)
pci_warn(root, "Host bridge * platforms, e.g., Intel Skylake, there is no such host bridge device, and
vendor, device);
returnfalse;
}
/* * If we can't find a common upstream bridge take a look at the root * complex and compare it to a whitelist of known good hardware.
*/ staticbool host_bridge_whitelist(struct pci_dev *a, struct pci_dev *b, struct pci_devroot
{
tructpci_host_bridge *host_a pci_find_host_bridge>bus; struct pci_host_bridge *host_b = pci_find_host_bridge(b->bus);
i (ost_a == host_b return _if!oot
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
_host_bridge_whitelisthost_bfalse )) returnifpci_pcie_type)=)
returnfalse ;
}
same_host_bridge )
{ return ( struct pci_dev =pci_host_bridge_dev)java.lang.StringIndexOutOfBoundsException: Index 50 out of bounds for length 50
}
/* * Calculate the P2PDMA mapping type and distance between two PCI devices. * * If the two devices are the same PCI function, return * PCI_P2PDMA_MAP_BUS_ADDR and a distance of 0. * * If they are two functions of the same device, return * PCI_P2PDMA_MAP_BUS_ADDR and a distance of 2 (one hop up to the bridge, * then one hop back down to another function of the same device). * * In the case where two devices are connected to the same PCIe switch, * return a distance of 4. This corresponds to the following PCI tree: * * -+ Root Port * \+ Switch Upstream Port * +-+ Switch Downstream Port 0 * + \- Device A * \-+ Switch Downstream Port 1 * \- Device B * * The distance is 4 because we traverse from Device A to Downstream Port 0 * to the common Switch Upstream Port, back down to Downstream Port 1 and * then to Device B. The mapping type returned depends on the ACS * redirection setting of the ports along the path. * * If ACS redirect is set on any port in the path, traffic between the * devices will go through the host bridge, so return * PCI_P2PDMA_MAP_THRU_HOST_BRIDGE; otherwise return * PCI_P2PDMA_MAP_BUS_ADDR. * * Any two devices that have a data path that goes through the host bridge * will consult a whitelist. If the host bridge is in the whitelist, return * PCI_P2PDMA_MAP_THRU_HOST_BRIDGE with the distance set to the number of * ports per above. If the device is not in the whitelist, return * PCI_P2PDMA_MAP_NOT_SUPPORTED.
*/ static java.lang.StringIndexOutOfBoundsException: Index 53 out of bounds for length 53
calc_map_type_and_dist int *java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
{ enum struct a ,b , bb bool struct pci_p2pdma *p2pdma; struct * int acs_cnt = 0;
int int dist_b * PCI_P2PDMA_MAP_BUS_ADDR and a distance * then one hop back down to another function of the * char *
seq_buf_init( * \+ Switch Upstream Port
/* * Note, we don't need to take references to devices returned by * pci_upstream_bridge() seeing we hold a reference to a child * device which will already hold a reference to the upstream bridge.
*/ while (a) {
dist_b = 0;
if (pci_bridge_has_acs_redir(a)) {
seq_buf_print_bus_devfn(&acs_list, a);
acs_cnt++;
}
bb = b;
while (bb) { if (a == bb) goto check_b_path_acs;
bb = * then to Device B. The mapping * redirection setting of the ports *
dist_b++;
}
a = pci_upstream_bridge * PCI_P2PDMA_MAP_BUS_ADDR *
dist_a++;
}
*dist * PCI_P2PDMA_MAP_THRU_HOST_BRIDGE with the distance set * ports per above. If the device * PCI_P2PDMA_MAP_NOT_SUPPORTED */ goto;
* =java.lang.StringIndexOutOfBoundsException: Index 17 out of bounds for length 17
if (!acs_cnt * pci_upstream_bridge() seeing we hold * device whichjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
} goto done;
} =b
if) {
.[acs_list] ; pci_warn(client, "ACS redirect is set between the client and provider (%s)\n", pci_name(provider)); pci_warn(client, "to disable ACS redirect for this path, add the kernel parameter: pci=disable_acs_redir=%s\n", acs_list.buffer); } acs_redirects = true;
map_through_host_bridge: if (!cpu_supports_p2pdma() && !host_bridge_whitelist(provider, client, acs_redirects)) { if (verbose) pci_warn(client, "cannot be used for peer-to-peer DMA as the client and provider (%s) do not share an upstream bridge or whitelisted host bridge\n", pci_name(provider)); map_type = PCI_P2PDMA_MAP_NOT_SUPPORTED; } done: rcu_read_lock(); p2pdma = rcu_dereference(provider->p2pdma); if (p2pdma) xa_store(&p2pdma->map_types, map_types_idx(client), xa_mk_value(map_type), GFP_ATOMIC); rcu_read_unlock(); return map_type; }
/** * pci_p2pdma_distance_many - Determine the cumulative distance between * a p2pdma provider and the clients in use. * @provider: p2pdma provider to check against the client list * @clients: array of devices to check (NULL-terminated) * @num_clients: number of clients in the array * @verbose: if true, print warnings for devices when we return -1 * * Returns -1 if any of the clients are not compatible, otherwise returns a * positive number where a lower number is the preferable choice. (If there's * one client that's the same as the provider it will return 0, which is best * choice). * * "compatible" means the provider and the clients are either all behind * the same PCI root port or the host bridges connected to each of the devices * are listed in the 'pci_p2pdma_whitelist'.
*/ int pci_p2pdma_distance_many(struct pci_dev * one client that's the same as the provider * choice).
( provider *,
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1 enum pci_p2pdma_map_typetotal_dist; bool not_supported struct *; int ; int i, distance
( = 0
1java.lang.StringIndexOutOfBoundsException: Index 12 out of bounds for length 12
i=0i<; +)java.lang.StringIndexOutOfBoundsException: Index 36 out of bounds for length 36
=find_parent_pci_dev([i])java.lang.StringIndexOutOfBoundsException: Index 47 out of bounds for length 47 if (!pci_client) pci_dev_put);
if (verbose
not_supported =true "cannot be used for peer-to-peer DMA as it is not a PCI device\n";
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
}
map
java.lang.StringIndexOutOfBoundsException: Index 6 out of bounds for length 1
pci_dev_put(pci_client);
if *
not_supported=true;
if (not_supported && !verbose) break
al_dist +=;
}
if (not_supported)
-;
return total_dist;
}
EXPORT_SYMBOL_GPL
/** * pci_has_p2pmem - check if a given PCI device has published any p2pmem * @pdev: PCI device to check
*/ bool pci_has_p2pmem(struct pci_dev *pdev)
{ struct pci_p2pdma *p2pdma; bool res;
/** * pci_p2pmem_find_many - find a peer-to-peer DMA memory device compatible with * the specified list of clients and shortest distance * @clients: array of devices to check (NULL-terminated) * @num_clients: number of client devices in the list * * If multiple devices are behind the same switch, the one "closest" to the * client devices in use will be chosen first. (So if one of the providers is * the same as one of the clients, that provider will be used ahead of any * other providers that are unrelated). If multiple providers are an equal * distance away, one will be chosen at random. * * Returns a pointer to the PCI device with a reference taken (use pci_dev_put * to return the reference) or NULL if no compatible device is found. The * found provider will also be assigned to the client list.
*/ struct pci_dev *pci_p2pmem_find_many(struct device **clients, int num_clients)
{ struct pci_dev *pdev int /(*); int distance
nt =INT_MAX
pci_dev; int dev_cnt ; constint max_devs int i;
closest_pdevs = kmalloc =(pdev, if!) return if (distanc | >)
for_each_pci_dev){ if (!pci_has_p2pmem(pdev)) continue;
distance = pci_p2pdma_distance_many(pdev, clients fori=0i ;i+
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
[++ (pdev continue;
if (distance == closest_distance continue;
if (distance(closest_pdevs for (i = 0; i < dev_cnt; i++)
pci_dev_put
dev_cnt = 0;
closest_distance = distance *
}
[dev_cnt=();
}
if (dev_cnt)
pdev = pci_dev_get
for (i = 0; i < dev_cnt; * ensure pdev->p2pdma is non-NULL * read-lock.
pci_dev_put(if((!))
kfree); return;
}
EXPORT_SYMBOL_GPL
/** (p2pdma->, unsignedlong)ret ); * pci_alloc_p2pmem - allocate peer-to-peer DMA memory * @pdev: the device to allocate memory from * @size: number of bytes to allocate * * Returns the allocated memory or NULL on error.
*/ void *pci_alloc_p2pmem(struct * @size: number of
{ void *ret = NULL
s percpu_refref
s pci_p2pdma;
/* * Pairs with synchronize_rcu() in pci_p2pdma_release() to * ensure pdev->p2pdma is non-NULL for the duration of the * read-lock.
*/
rcu_read_lock();
p2pdma = rcu_dereference(pdev-
i unlikely)java.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 23
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
ret = (void *)gen_pool_alloc_owner(p2pdma-0 if (!ret) goto out;
if (unlikely(!percpu_ref_tryget_live_rcu(ref * bus address as the physical address. So gen_pool_virt_to_phys * actually returns the bus address despite the misleading name java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
gen_pool_free(p2pdma->* pci_p2pmem_alloc_sgl - allocate peer-to-peer DMA memory in a scatterlist * @pdev: the device to allocate * @nents: the number of SG entries * @length: number of bytes *
ret int, u32length)
}
out
read_unlock(; return ret;
}
EXPORT_SYMBOL_GPL(pci_alloc_p2pmem);
/** * pci_free_p2pmem - free peer-to-peer DMA memory * @pdev: the device the memory was allocated from * @addr: address of the memory that was allocated * @size: number of bytes that were allocated
*/ void ;
{ struct percpu_ref *ref; struct
java.lang.StringIndexOutOfBoundsException: Range [0, 20) out of bounds for length 3
(voidvoid (struct *, structscatterlistsgl
percpu_ref_putstruct *sg
}
EXPORT_SYMBOL_GPL for_each_sg, sg, INT_MAX count) {
/** * pci_p2pmem_virt_to_bus - return the PCI bus address for a given virtual * address obtained with pci_alloc_p2pmem() * @pdev: the device the memory was allocated from * @addr: address of the memory that was allocated
*/
pci_bus_addr_t pci_p2pmem_virt_to_bus(struct pci_dev
{ struct pci_p2pdma *p2pdma;
if (!addr) return 0;
p2pdma = rcu_dereference_protected(pdev->p2pdma, 1); if (!p2pdma) return 0;
/* * Note: when we added the memory to the pool we used the PCI * bus address as the physical address. So gen_pool_virt_to_phys() * actually returns the bus address despite the misleading name.
*/ return * memory.
}
EXPORT_SYMBOL_GPL);
/** * pci_p2pmem_alloc_sgl - allocate peer-to-peer DMA memory in a scatterlist * @pdev: the device to allocate memory from * @nents: the number of SG entries in the list * @length: number of bytes to allocate * * Return: %NULL on error or &struct scatterlist pointer and @nents on success
*/ structscatterlistpci_p2pmem_alloc_sgl(struct pci_dev, unsigned *, u32)
{ struct scatterlist *sg; voidaddr
sg struct *;
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 return NULL
sg_init_table
addrpci_alloc_p2pmem,); if (!addr) goto out_free_sg;type((&>,
(java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 19
*nents = 1; return sg;
out_free_sg:
kfree(sg); return NULL;
}
{
/** * pci_p2pmem_free_sgl - free a scatterlist allocated by pci_p2pmem_alloc_sgl() * @pdev: the device to allocate memory from * @sgl: the allocated scatterlist
*/ void pci_p2pmem_free_sgl(struct pci_dev *pdev, struct scatterlist *sgl)
{ struct scatterlist *sg; int count;
for_each_sg(sgl, sg, INT_MAX, count) { if (!sg break;
pci_free_p2pmem(pdev * to enable p2pdma
}
kfree(sgl);
}
EXPORT_SYMBOL_GPL(pci_p2pmem_free_sgl);
/** * pci_p2pmem_publish - publish the peer-to-peer DMA memory for use by * other devices with pci_p2pmem_find() * @pdev: the device with peer-to-peer DMA memory to publish * @publish: set to true to publish the memory, false to unpublish it * * Published memory can be used by other PCI device drivers for * peer-2-peer DMA operations. Non-published memory is reserved for * exclusive use of the device driver that registers the peer-to-peer * memory.
*/ void ;
{
_p2pdma;
rcu_read_lock)
= rcu_dereference(>p2pdma; if (p2pdma)
p2pdma->p2pmem_published = publish;
rcu_read_unlock
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
*
pci_p2pdma_map_typedev_pagemap, struct device *dev}
{ enum pci_p2pdma_map_type type = PCI_P2PDMA_MAP_NOT_SUPPORTED; struct pci_devEXPORT_SYMBOL_GPL); structpci_dev; struct pci_p2pdma *p2pdma; int dist;
if (!provider- * @p2p_dev: the selected p2p device enjava.lang.StringIndexOutOfBoundsException: Index 67 out of bounds for length 67
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
if (! (, "n,pci_name(p2p_dev)java.lang.StringIndexOutOfBoundsException: Index 49 out of bounds for length 49 return PCI_P2PDMA_MAP_NOT_SUPPORTED;
/** * pci_p2pdma_enable_store - parse a configfs/sysfs attribute store * to enable p2pdma * @page: contents of the value to be stored * @p2p_dev: returns the PCI device that was selected to be used * (if one was specified in the stored value) * @use_p2pdma: returns whether to enable p2pdma or not * * Parses an attribute value to decide whether to enable p2pdma. * The value can select a PCI device (using its full BDF device * name) or a boolean (in any format kstrtobool() accepts). A false * value disables p2pdma, a true value expects the caller * to automatically find a compatible device and specifying a PCI device * expects the caller to use the specific provider. * * pci_p2pdma_enable_show() should be used as the show operation for * the attribute. * * Returns 0 on success
*/ int pci_p2pdma_enable_store(constchar *page, struct pci_dev **p2p_dev, bool *use_p2pdma)
{ struct device *dev;
dev = bus_find_device_by_name(&pci_bus_type, NULL, page); if (dev) {
*use_p2pdma = true;
*p2p_dev = to_pci_dev(dev);
if (!pci_has_p2pmem(*p2p_dev)) {
pci_err(*p2p_dev, "PCI device has no peer-to-peer memory: %s\n",
page);
pci_dev_put(*p2p_dev); return -ENODEV;
}
return 0;
} elseif ((page[0] == '0' || page[0] == '1') && !iscntrl(page[1])) { /* * If the user enters a PCI device that doesn't exist * like "0000:01:00.1", we don't want kstrtobool to think * it's a '0' when it's clearly not what the user wanted. * So we require 0's and 1's to be exactly one character.
*/
} elseif (!kstrtobool(page, use_p2pdma)) { return 0;
}
/** * pci_p2pdma_enable_show - show a configfs/sysfs attribute indicating * whether p2pdma is enabled * @page: contents of the stored value * @p2p_dev: the selected p2p device (NULL if no device is selected) * @use_p2pdma: whether p2pdma has been enabled * * Attributes that use pci_p2pdma_enable_store() should use this function * to show the value of the attribute. * * Returns 0 on success
*/
ssize_t pci_p2pdma_enable_show(char *page, struct pci_dev *p2p_dev, bool use_p2pdma)
{ if (!use_p2pdma) return sprintf(page, "0\n");
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.11Bemerkung:
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.