1// SPDX-License-Identifier: GPL-2.0
2#include <linux/device.h>
3#include <linux/pci.h>
4#include "pci.h"
5
6/*
7 * On the state of PCI's devres implementation:
8 *
9 * The older PCI devres API has one significant problem:
10 *
11 * It is very strongly tied to the statically allocated mapping table in struct
12 * pcim_iomap_devres below. This is mostly solved in the sense of the pcim_
13 * functions in this file providing things like ranged mapping by bypassing
14 * this table, whereas the functions that were present in the old API still
15 * enter the mapping addresses into the table for users of the old API.
16 *
17 * TODO:
18 * Remove the legacy table entirely once all calls to pcim_iomap_table() in
19 * the kernel have been removed.
20 */
21
22/*
23 * Legacy struct storing addresses to whole mapped BARs.
24 */
25struct pcim_iomap_devres {
26 void __iomem *table[PCI_NUM_RESOURCES];
27};
28
29/* Used to restore the old INTx state on driver detach. */
30struct pcim_intx_devres {
31 int orig_intx;
32};
33
34enum pcim_addr_devres_type {
35 /* Default initializer. */
36 PCIM_ADDR_DEVRES_TYPE_INVALID,
37
38 /* A requested region spanning an entire BAR. */
39 PCIM_ADDR_DEVRES_TYPE_REGION,
40
41 /*
42 * A requested region spanning an entire BAR, and a mapping for
43 * the entire BAR.
44 */
45 PCIM_ADDR_DEVRES_TYPE_REGION_MAPPING,
46
47 /*
48 * A mapping within a BAR, either spanning the whole BAR or just a
49 * range. Without a requested region.
50 */
51 PCIM_ADDR_DEVRES_TYPE_MAPPING,
52};
53
54/*
55 * This struct envelops IO or MEM addresses, i.e., mappings and region
56 * requests, because those are very frequently requested and released
57 * together.
58 */
59struct pcim_addr_devres {
60 enum pcim_addr_devres_type type;
61 void __iomem *baseaddr;
62 unsigned long offset;
63 unsigned long len;
64 int bar;
65};
66
67static inline void pcim_addr_devres_clear(struct pcim_addr_devres *res)
68{
69 memset(s: res, c: 0, n: sizeof(*res));
70 res->bar = -1;
71}
72
73static void pcim_addr_resource_release(struct device *dev, void *resource_raw)
74{
75 struct pci_dev *pdev = to_pci_dev(dev);
76 struct pcim_addr_devres *res = resource_raw;
77
78 switch (res->type) {
79 case PCIM_ADDR_DEVRES_TYPE_REGION:
80 pci_release_region(pdev, res->bar);
81 break;
82 case PCIM_ADDR_DEVRES_TYPE_REGION_MAPPING:
83 pci_iounmap(dev: pdev, res->baseaddr);
84 pci_release_region(pdev, res->bar);
85 break;
86 case PCIM_ADDR_DEVRES_TYPE_MAPPING:
87 pci_iounmap(dev: pdev, res->baseaddr);
88 break;
89 default:
90 break;
91 }
92}
93
94static struct pcim_addr_devres *pcim_addr_devres_alloc(struct pci_dev *pdev)
95{
96 struct pcim_addr_devres *res;
97
98 res = devres_alloc_node(pcim_addr_resource_release, sizeof(*res),
99 GFP_KERNEL, dev_to_node(&pdev->dev));
100 if (res)
101 pcim_addr_devres_clear(res);
102 return res;
103}
104
105/* Just for consistency and readability. */
106static inline void pcim_addr_devres_free(struct pcim_addr_devres *res)
107{
108 devres_free(res);
109}
110
111/*
112 * Used by devres to identify a pcim_addr_devres.
113 */
114static int pcim_addr_resources_match(struct device *dev,
115 void *a_raw, void *b_raw)
116{
117 struct pcim_addr_devres *a, *b;
118
119 a = a_raw;
120 b = b_raw;
121
122 if (a->type != b->type)
123 return 0;
124
125 switch (a->type) {
126 case PCIM_ADDR_DEVRES_TYPE_REGION:
127 case PCIM_ADDR_DEVRES_TYPE_REGION_MAPPING:
128 return a->bar == b->bar;
129 case PCIM_ADDR_DEVRES_TYPE_MAPPING:
130 return a->baseaddr == b->baseaddr;
131 default:
132 return 0;
133 }
134}
135
136static void devm_pci_unmap_iospace(struct device *dev, void *ptr)
137{
138 struct resource **res = ptr;
139
140 pci_unmap_iospace(res: *res);
141}
142
143/**
144 * devm_pci_remap_iospace - Managed pci_remap_iospace()
145 * @dev: Generic device to remap IO address for
146 * @res: Resource describing the I/O space
147 * @phys_addr: physical address of range to be mapped
148 *
149 * Managed pci_remap_iospace(). Map is automatically unmapped on driver
150 * detach.
151 */
152int devm_pci_remap_iospace(struct device *dev, const struct resource *res,
153 phys_addr_t phys_addr)
154{
155 const struct resource **ptr;
156 int error;
157
158 ptr = devres_alloc(devm_pci_unmap_iospace, sizeof(*ptr), GFP_KERNEL);
159 if (!ptr)
160 return -ENOMEM;
161
162 error = pci_remap_iospace(res, phys_addr);
163 if (error) {
164 devres_free(res: ptr);
165 } else {
166 *ptr = res;
167 devres_add(dev, res: ptr);
168 }
169
170 return error;
171}
172EXPORT_SYMBOL(devm_pci_remap_iospace);
173
174/**
175 * devm_pci_remap_cfgspace - Managed pci_remap_cfgspace()
176 * @dev: Generic device to remap IO address for
177 * @offset: Resource address to map
178 * @size: Size of map
179 *
180 * Managed pci_remap_cfgspace(). Map is automatically unmapped on driver
181 * detach.
182 */
183void __iomem *devm_pci_remap_cfgspace(struct device *dev,
184 resource_size_t offset,
185 resource_size_t size)
186{
187 void __iomem **ptr, *addr;
188
189 ptr = devres_alloc(devm_ioremap_release, sizeof(*ptr), GFP_KERNEL);
190 if (!ptr)
191 return NULL;
192
193 addr = pci_remap_cfgspace(offset, size);
194 if (addr) {
195 *ptr = addr;
196 devres_add(dev, res: ptr);
197 } else
198 devres_free(res: ptr);
199
200 return addr;
201}
202EXPORT_SYMBOL(devm_pci_remap_cfgspace);
203
204/**
205 * devm_pci_remap_cfg_resource - check, request region and ioremap cfg resource
206 * @dev: generic device to handle the resource for
207 * @res: configuration space resource to be handled
208 *
209 * Checks that a resource is a valid memory region, requests the memory
210 * region and ioremaps with pci_remap_cfgspace() API that ensures the
211 * proper PCI configuration space memory attributes are guaranteed.
212 *
213 * All operations are managed and will be undone on driver detach.
214 *
215 * Returns a pointer to the remapped memory or an IOMEM_ERR_PTR() encoded error
216 * code on failure. Usage example::
217 *
218 * res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
219 * base = devm_pci_remap_cfg_resource(&pdev->dev, res);
220 * if (IS_ERR(base))
221 * return PTR_ERR(base);
222 */
223void __iomem *devm_pci_remap_cfg_resource(struct device *dev,
224 struct resource *res)
225{
226 resource_size_t size;
227 const char *name;
228 void __iomem *dest_ptr;
229
230 BUG_ON(!dev);
231
232 if (!res || resource_type(res) != IORESOURCE_MEM) {
233 dev_err(dev, "invalid resource\n");
234 return IOMEM_ERR_PTR(-EINVAL);
235 }
236
237 size = resource_size(res);
238
239 if (res->name)
240 name = devm_kasprintf(dev, GFP_KERNEL, fmt: "%s %s", dev_name(dev),
241 res->name);
242 else
243 name = devm_kstrdup(dev, s: dev_name(dev), GFP_KERNEL);
244 if (!name)
245 return IOMEM_ERR_PTR(-ENOMEM);
246
247 if (!devm_request_mem_region(dev, res->start, size, name)) {
248 dev_err(dev, "can't request region for resource %pR\n", res);
249 return IOMEM_ERR_PTR(-EBUSY);
250 }
251
252 dest_ptr = devm_pci_remap_cfgspace(dev, res->start, size);
253 if (!dest_ptr) {
254 dev_err(dev, "ioremap failed for resource %pR\n", res);
255 devm_release_mem_region(dev, res->start, size);
256 dest_ptr = IOMEM_ERR_PTR(-ENOMEM);
257 }
258
259 return dest_ptr;
260}
261EXPORT_SYMBOL(devm_pci_remap_cfg_resource);
262
263static void __pcim_clear_mwi(void *pdev_raw)
264{
265 struct pci_dev *pdev = pdev_raw;
266
267 pci_clear_mwi(dev: pdev);
268}
269
270/**
271 * pcim_set_mwi - a device-managed pci_set_mwi()
272 * @pdev: the PCI device for which MWI is enabled
273 *
274 * Managed pci_set_mwi().
275 *
276 * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
277 */
278int pcim_set_mwi(struct pci_dev *pdev)
279{
280 int ret;
281
282 ret = devm_add_action(&pdev->dev, __pcim_clear_mwi, pdev);
283 if (ret != 0)
284 return ret;
285
286 ret = pci_set_mwi(dev: pdev);
287 if (ret != 0)
288 devm_remove_action(dev: &pdev->dev, action: __pcim_clear_mwi, data: pdev);
289
290 return ret;
291}
292EXPORT_SYMBOL(pcim_set_mwi);
293
294static inline bool mask_contains_bar(int mask, int bar)
295{
296 return mask & BIT(bar);
297}
298
299static void pcim_intx_restore(struct device *dev, void *data)
300{
301 struct pci_dev *pdev = to_pci_dev(dev);
302 struct pcim_intx_devres *res = data;
303
304 pci_intx(dev: pdev, enable: res->orig_intx);
305}
306
307static void save_orig_intx(struct pci_dev *pdev, struct pcim_intx_devres *res)
308{
309 u16 pci_command;
310
311 pci_read_config_word(dev: pdev, PCI_COMMAND, val: &pci_command);
312 res->orig_intx = !(pci_command & PCI_COMMAND_INTX_DISABLE);
313}
314
315/**
316 * pcim_intx - managed pci_intx()
317 * @pdev: the PCI device to operate on
318 * @enable: boolean: whether to enable or disable PCI INTx
319 *
320 * Returns: 0 on success, -ENOMEM on error.
321 *
322 * Enable/disable PCI INTx for device @pdev.
323 * Restore the original state on driver detach.
324 */
325int pcim_intx(struct pci_dev *pdev, int enable)
326{
327 struct pcim_intx_devres *res;
328 struct device *dev = &pdev->dev;
329
330 /*
331 * pcim_intx() must only restore the INTx value that existed before the
332 * driver was loaded, i.e., before it called pcim_intx() for the
333 * first time.
334 */
335 res = devres_find(dev, release: pcim_intx_restore, NULL, NULL);
336 if (!res) {
337 res = devres_alloc(pcim_intx_restore, sizeof(*res), GFP_KERNEL);
338 if (!res)
339 return -ENOMEM;
340
341 save_orig_intx(pdev, res);
342 devres_add(dev, res);
343 }
344
345 pci_intx(dev: pdev, enable);
346
347 return 0;
348}
349EXPORT_SYMBOL_GPL(pcim_intx);
350
351static void pcim_disable_device(void *pdev_raw)
352{
353 struct pci_dev *pdev = pdev_raw;
354
355 if (!pdev->pinned)
356 pci_disable_device(dev: pdev);
357
358 pdev->is_managed = false;
359}
360
361/**
362 * pcim_enable_device - Managed pci_enable_device()
363 * @pdev: PCI device to be initialized
364 *
365 * Returns: 0 on success, negative error code on failure.
366 *
367 * Managed pci_enable_device(). Device will automatically be disabled on
368 * driver detach.
369 */
370int pcim_enable_device(struct pci_dev *pdev)
371{
372 int ret;
373
374 ret = devm_add_action(&pdev->dev, pcim_disable_device, pdev);
375 if (ret != 0)
376 return ret;
377
378 /*
379 * We prefer removing the action in case of an error over
380 * devm_add_action_or_reset() because the latter could theoretically be
381 * disturbed by users having pinned the device too soon.
382 */
383 ret = pci_enable_device(dev: pdev);
384 if (ret != 0) {
385 devm_remove_action(dev: &pdev->dev, action: pcim_disable_device, data: pdev);
386 return ret;
387 }
388
389 pdev->is_managed = true;
390
391 return ret;
392}
393EXPORT_SYMBOL(pcim_enable_device);
394
395/**
396 * pcim_pin_device - Pin managed PCI device
397 * @pdev: PCI device to pin
398 *
399 * Pin managed PCI device @pdev. Pinned device won't be disabled on driver
400 * detach. @pdev must have been enabled with pcim_enable_device().
401 */
402void pcim_pin_device(struct pci_dev *pdev)
403{
404 pdev->pinned = true;
405}
406EXPORT_SYMBOL(pcim_pin_device);
407
408static void pcim_iomap_release(struct device *gendev, void *res)
409{
410 /*
411 * Do nothing. This is legacy code.
412 *
413 * Cleanup of the mappings is now done directly through the callbacks
414 * registered when creating them.
415 */
416}
417
418/**
419 * pcim_iomap_table - access iomap allocation table (DEPRECATED)
420 * @pdev: PCI device to access iomap table for
421 *
422 * Returns:
423 * Const pointer to array of __iomem pointers on success, NULL on failure.
424 *
425 * Access iomap allocation table for @dev. If iomap table doesn't
426 * exist and @pdev is managed, it will be allocated. All iomaps
427 * recorded in the iomap table are automatically unmapped on driver
428 * detach.
429 *
430 * This function might sleep when the table is first allocated but can
431 * be safely called without context and guaranteed to succeed once
432 * allocated.
433 *
434 * This function is DEPRECATED. Do not use it in new code. Instead, obtain a
435 * mapping's address directly from one of the pcim_* mapping functions. For
436 * example:
437 * void __iomem \*mappy = pcim_iomap(pdev, bar, length);
438 */
439void __iomem * const *pcim_iomap_table(struct pci_dev *pdev)
440{
441 struct pcim_iomap_devres *dr, *new_dr;
442
443 dr = devres_find(dev: &pdev->dev, release: pcim_iomap_release, NULL, NULL);
444 if (dr)
445 return dr->table;
446
447 new_dr = devres_alloc_node(pcim_iomap_release, sizeof(*new_dr), GFP_KERNEL,
448 dev_to_node(&pdev->dev));
449 if (!new_dr)
450 return NULL;
451 dr = devres_get(dev: &pdev->dev, new_res: new_dr, NULL, NULL);
452 return dr->table;
453}
454EXPORT_SYMBOL(pcim_iomap_table);
455
456/*
457 * Fill the legacy mapping-table, so that drivers using the old API can
458 * still get a BAR's mapping address through pcim_iomap_table().
459 */
460static int pcim_add_mapping_to_legacy_table(struct pci_dev *pdev,
461 void __iomem *mapping, int bar)
462{
463 void __iomem **legacy_iomap_table;
464
465 if (!pci_bar_index_is_valid(bar))
466 return -EINVAL;
467
468 legacy_iomap_table = (void __iomem **)pcim_iomap_table(pdev);
469 if (!legacy_iomap_table)
470 return -ENOMEM;
471
472 /* The legacy mechanism doesn't allow for duplicate mappings. */
473 WARN_ON(legacy_iomap_table[bar]);
474
475 legacy_iomap_table[bar] = mapping;
476
477 return 0;
478}
479
480/*
481 * Remove a mapping. The table only contains whole-BAR mappings, so this will
482 * never interfere with ranged mappings.
483 */
484static void pcim_remove_mapping_from_legacy_table(struct pci_dev *pdev,
485 void __iomem *addr)
486{
487 int bar;
488 void __iomem **legacy_iomap_table;
489
490 legacy_iomap_table = (void __iomem **)pcim_iomap_table(pdev);
491 if (!legacy_iomap_table)
492 return;
493
494 for (bar = 0; bar < PCI_STD_NUM_BARS; bar++) {
495 if (legacy_iomap_table[bar] == addr) {
496 legacy_iomap_table[bar] = NULL;
497 return;
498 }
499 }
500}
501
502/*
503 * The same as pcim_remove_mapping_from_legacy_table(), but identifies the
504 * mapping by its BAR index.
505 */
506static void pcim_remove_bar_from_legacy_table(struct pci_dev *pdev, int bar)
507{
508 void __iomem **legacy_iomap_table;
509
510 if (!pci_bar_index_is_valid(bar))
511 return;
512
513 legacy_iomap_table = (void __iomem **)pcim_iomap_table(pdev);
514 if (!legacy_iomap_table)
515 return;
516
517 legacy_iomap_table[bar] = NULL;
518}
519
520/**
521 * pcim_iomap - Managed pcim_iomap()
522 * @pdev: PCI device to iomap for
523 * @bar: BAR to iomap
524 * @maxlen: Maximum length of iomap
525 *
526 * Returns: __iomem pointer on success, NULL on failure.
527 *
528 * Managed pci_iomap(). Map is automatically unmapped on driver detach. If
529 * desired, unmap manually only with pcim_iounmap().
530 *
531 * This SHOULD only be used once per BAR.
532 *
533 * NOTE:
534 * Contrary to the other pcim_* functions, this function does not return an
535 * IOMEM_ERR_PTR() on failure, but a simple NULL. This is done for backwards
536 * compatibility.
537 */
538void __iomem *pcim_iomap(struct pci_dev *pdev, int bar, unsigned long maxlen)
539{
540 void __iomem *mapping;
541 struct pcim_addr_devres *res;
542
543 if (!pci_bar_index_is_valid(bar))
544 return NULL;
545
546 res = pcim_addr_devres_alloc(pdev);
547 if (!res)
548 return NULL;
549 res->type = PCIM_ADDR_DEVRES_TYPE_MAPPING;
550
551 mapping = pci_iomap(dev: pdev, bar, max: maxlen);
552 if (!mapping)
553 goto err_iomap;
554 res->baseaddr = mapping;
555
556 if (pcim_add_mapping_to_legacy_table(pdev, mapping, bar) != 0)
557 goto err_table;
558
559 devres_add(dev: &pdev->dev, res);
560 return mapping;
561
562err_table:
563 pci_iounmap(dev: pdev, mapping);
564err_iomap:
565 pcim_addr_devres_free(res);
566 return NULL;
567}
568EXPORT_SYMBOL(pcim_iomap);
569
570/**
571 * pcim_iounmap - Managed pci_iounmap()
572 * @pdev: PCI device to iounmap for
573 * @addr: Address to unmap
574 *
575 * Managed pci_iounmap(). @addr must have been mapped using a pcim_* mapping
576 * function.
577 */
578void pcim_iounmap(struct pci_dev *pdev, void __iomem *addr)
579{
580 struct pcim_addr_devres res_searched;
581
582 pcim_addr_devres_clear(res: &res_searched);
583 res_searched.type = PCIM_ADDR_DEVRES_TYPE_MAPPING;
584 res_searched.baseaddr = addr;
585
586 if (devres_release(dev: &pdev->dev, release: pcim_addr_resource_release,
587 match: pcim_addr_resources_match, match_data: &res_searched) != 0) {
588 /* Doesn't exist. User passed nonsense. */
589 return;
590 }
591
592 pcim_remove_mapping_from_legacy_table(pdev, addr);
593}
594EXPORT_SYMBOL(pcim_iounmap);
595
596/**
597 * pcim_iomap_region - Request and iomap a PCI BAR
598 * @pdev: PCI device to map IO resources for
599 * @bar: Index of a BAR to map
600 * @name: Name of the driver requesting the resource
601 *
602 * Returns: __iomem pointer on success, an IOMEM_ERR_PTR on failure.
603 *
604 * Mapping and region will get automatically released on driver detach. If
605 * desired, release manually only with pcim_iounmap_region().
606 */
607void __iomem *pcim_iomap_region(struct pci_dev *pdev, int bar,
608 const char *name)
609{
610 int ret;
611 struct pcim_addr_devres *res;
612
613 if (!pci_bar_index_is_valid(bar))
614 return IOMEM_ERR_PTR(-EINVAL);
615
616 res = pcim_addr_devres_alloc(pdev);
617 if (!res)
618 return IOMEM_ERR_PTR(-ENOMEM);
619
620 res->type = PCIM_ADDR_DEVRES_TYPE_REGION_MAPPING;
621 res->bar = bar;
622
623 ret = pci_request_region(pdev, bar, name);
624 if (ret != 0)
625 goto err_region;
626
627 res->baseaddr = pci_iomap(dev: pdev, bar, max: 0);
628 if (!res->baseaddr) {
629 ret = -EINVAL;
630 goto err_iomap;
631 }
632
633 devres_add(dev: &pdev->dev, res);
634 return res->baseaddr;
635
636err_iomap:
637 pci_release_region(pdev, bar);
638err_region:
639 pcim_addr_devres_free(res);
640
641 return IOMEM_ERR_PTR(ret);
642}
643EXPORT_SYMBOL(pcim_iomap_region);
644
645/**
646 * pcim_iounmap_region - Unmap and release a PCI BAR
647 * @pdev: PCI device to operate on
648 * @bar: Index of BAR to unmap and release
649 *
650 * Unmap a BAR and release its region manually. Only pass BARs that were
651 * previously mapped by pcim_iomap_region().
652 */
653void pcim_iounmap_region(struct pci_dev *pdev, int bar)
654{
655 struct pcim_addr_devres res_searched;
656
657 pcim_addr_devres_clear(res: &res_searched);
658 res_searched.type = PCIM_ADDR_DEVRES_TYPE_REGION_MAPPING;
659 res_searched.bar = bar;
660
661 devres_release(dev: &pdev->dev, release: pcim_addr_resource_release,
662 match: pcim_addr_resources_match, match_data: &res_searched);
663}
664EXPORT_SYMBOL(pcim_iounmap_region);
665
666/**
667 * pcim_iomap_regions - Request and iomap PCI BARs (DEPRECATED)
668 * @pdev: PCI device to map IO resources for
669 * @mask: Mask of BARs to request and iomap
670 * @name: Name of the driver requesting the resources
671 *
672 * Returns: 0 on success, negative error code on failure.
673 *
674 * Request and iomap regions specified by @mask.
675 *
676 * This function is DEPRECATED. Do not use it in new code.
677 * Use pcim_iomap_region() instead.
678 */
679int pcim_iomap_regions(struct pci_dev *pdev, int mask, const char *name)
680{
681 int ret;
682 int bar;
683 void __iomem *mapping;
684
685 for (bar = 0; bar < DEVICE_COUNT_RESOURCE; bar++) {
686 if (!mask_contains_bar(mask, bar))
687 continue;
688
689 mapping = pcim_iomap_region(pdev, bar, name);
690 if (IS_ERR(ptr: mapping)) {
691 ret = PTR_ERR(ptr: mapping);
692 goto err;
693 }
694 ret = pcim_add_mapping_to_legacy_table(pdev, mapping, bar);
695 if (ret != 0)
696 goto err;
697 }
698
699 return 0;
700
701err:
702 while (--bar >= 0) {
703 pcim_iounmap_region(pdev, bar);
704 pcim_remove_bar_from_legacy_table(pdev, bar);
705 }
706
707 return ret;
708}
709EXPORT_SYMBOL(pcim_iomap_regions);
710
711/**
712 * pcim_request_region - Request a PCI BAR
713 * @pdev: PCI device to request region for
714 * @bar: Index of BAR to request
715 * @name: Name of the driver requesting the resource
716 *
717 * Returns: 0 on success, a negative error code on failure.
718 *
719 * Request region specified by @bar.
720 *
721 * The region will automatically be released on driver detach. If desired,
722 * release manually only with pcim_release_region().
723 */
724int pcim_request_region(struct pci_dev *pdev, int bar, const char *name)
725{
726 int ret;
727 struct pcim_addr_devres *res;
728
729 if (!pci_bar_index_is_valid(bar))
730 return -EINVAL;
731
732 res = pcim_addr_devres_alloc(pdev);
733 if (!res)
734 return -ENOMEM;
735 res->type = PCIM_ADDR_DEVRES_TYPE_REGION;
736 res->bar = bar;
737
738 ret = pci_request_region(pdev, bar, name);
739 if (ret != 0) {
740 pcim_addr_devres_free(res);
741 return ret;
742 }
743
744 devres_add(dev: &pdev->dev, res);
745 return 0;
746}
747EXPORT_SYMBOL(pcim_request_region);
748
749/**
750 * pcim_release_region - Release a PCI BAR
751 * @pdev: PCI device to operate on
752 * @bar: Index of BAR to release
753 *
754 * Release a region manually that was previously requested by
755 * pcim_request_region().
756 */
757static void pcim_release_region(struct pci_dev *pdev, int bar)
758{
759 struct pcim_addr_devres res_searched;
760
761 pcim_addr_devres_clear(res: &res_searched);
762 res_searched.type = PCIM_ADDR_DEVRES_TYPE_REGION;
763 res_searched.bar = bar;
764
765 devres_release(dev: &pdev->dev, release: pcim_addr_resource_release,
766 match: pcim_addr_resources_match, match_data: &res_searched);
767}
768
769
770/**
771 * pcim_release_all_regions - Release all regions of a PCI-device
772 * @pdev: the PCI device
773 *
774 * Release all regions previously requested through pcim_request_region()
775 * or pcim_request_all_regions().
776 *
777 * Can be called from any context, i.e., not necessarily as a counterpart to
778 * pcim_request_all_regions().
779 */
780static void pcim_release_all_regions(struct pci_dev *pdev)
781{
782 int bar;
783
784 for (bar = 0; bar < PCI_STD_NUM_BARS; bar++)
785 pcim_release_region(pdev, bar);
786}
787
788/**
789 * pcim_request_all_regions - Request all regions
790 * @pdev: PCI device to map IO resources for
791 * @name: name of the driver requesting the resources
792 *
793 * Returns: 0 on success, negative error code on failure.
794 *
795 * Requested regions will automatically be released at driver detach. If
796 * desired, release individual regions with pcim_release_region() or all of
797 * them at once with pcim_release_all_regions().
798 */
799int pcim_request_all_regions(struct pci_dev *pdev, const char *name)
800{
801 int ret;
802 int bar;
803
804 for (bar = 0; bar < PCI_STD_NUM_BARS; bar++) {
805 ret = pcim_request_region(pdev, bar, name);
806 if (ret != 0)
807 goto err;
808 }
809
810 return 0;
811
812err:
813 pcim_release_all_regions(pdev);
814
815 return ret;
816}
817EXPORT_SYMBOL(pcim_request_all_regions);
818
819/**
820 * pcim_iomap_range - Create a ranged __iomap mapping within a PCI BAR
821 * @pdev: PCI device to map IO resources for
822 * @bar: Index of the BAR
823 * @offset: Offset from the begin of the BAR
824 * @len: Length in bytes for the mapping
825 *
826 * Returns: __iomem pointer on success, an IOMEM_ERR_PTR on failure.
827 *
828 * Creates a new IO-Mapping within the specified @bar, ranging from @offset to
829 * @offset + @len.
830 *
831 * The mapping will automatically get unmapped on driver detach. If desired,
832 * release manually only with pcim_iounmap().
833 */
834void __iomem *pcim_iomap_range(struct pci_dev *pdev, int bar,
835 unsigned long offset, unsigned long len)
836{
837 void __iomem *mapping;
838 struct pcim_addr_devres *res;
839
840 if (!pci_bar_index_is_valid(bar))
841 return IOMEM_ERR_PTR(-EINVAL);
842
843 res = pcim_addr_devres_alloc(pdev);
844 if (!res)
845 return IOMEM_ERR_PTR(-ENOMEM);
846
847 mapping = pci_iomap_range(dev: pdev, bar, offset, maxlen: len);
848 if (!mapping) {
849 pcim_addr_devres_free(res);
850 return IOMEM_ERR_PTR(-EINVAL);
851 }
852
853 res->type = PCIM_ADDR_DEVRES_TYPE_MAPPING;
854 res->baseaddr = mapping;
855
856 /*
857 * Ranged mappings don't get added to the legacy-table, since the table
858 * only ever keeps track of whole BARs.
859 */
860
861 devres_add(dev: &pdev->dev, res);
862 return mapping;
863}
864EXPORT_SYMBOL(pcim_iomap_range);
865