projects/linux·blob master · refs

861 lines · 20.8 KiB

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(res, 0, 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(pdev, res->baseaddr);
84 pci_release_region(pdev, res->bar);
85 break;
86 case PCIM_ADDR_DEVRES_TYPE_MAPPING:
87 pci_iounmap(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);
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(ptr);
165 } else {
166 *ptr = res;
167 devres_add(dev, 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, ptr);
197 } else
198 devres_free(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, "%s %s", dev_name(dev),
241 res->name);
242 else
243 name = devm_kstrdup(dev, 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(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(pdev);
287 if (ret != 0)
288 devm_remove_action(&pdev->dev, __pcim_clear_mwi, 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(pdev, 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(pdev, PCI_COMMAND, &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, 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(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(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(pdev);
384 if (ret != 0) {
385 devm_remove_action(&pdev->dev, pcim_disable_device, 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(&pdev->dev, 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(&pdev->dev, 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 legacy_iomap_table[bar] = mapping;
473
474 return 0;
475}
476
477/*
478 * Remove a mapping. The table only contains whole-BAR mappings, so this will
479 * never interfere with ranged mappings.
480 */
481static void pcim_remove_mapping_from_legacy_table(struct pci_dev *pdev,
482 void __iomem *addr)
483{
484 int bar;
485 void __iomem **legacy_iomap_table;
486
487 legacy_iomap_table = (void __iomem **)pcim_iomap_table(pdev);
488 if (!legacy_iomap_table)
489 return;
490
491 for (bar = 0; bar < PCI_STD_NUM_BARS; bar++) {
492 if (legacy_iomap_table[bar] == addr) {
493 legacy_iomap_table[bar] = NULL;
494 return;
495 }
496 }
497}
498
499/*
500 * The same as pcim_remove_mapping_from_legacy_table(), but identifies the
501 * mapping by its BAR index.
502 */
503static void pcim_remove_bar_from_legacy_table(struct pci_dev *pdev, int bar)
504{
505 void __iomem **legacy_iomap_table;
506
507 if (!pci_bar_index_is_valid(bar))
508 return;
509
510 legacy_iomap_table = (void __iomem **)pcim_iomap_table(pdev);
511 if (!legacy_iomap_table)
512 return;
513
514 legacy_iomap_table[bar] = NULL;
515}
516
517/**
518 * pcim_iomap - Managed pcim_iomap()
519 * @pdev: PCI device to iomap for
520 * @bar: BAR to iomap
521 * @maxlen: Maximum length of iomap
522 *
523 * Returns: __iomem pointer on success, NULL on failure.
524 *
525 * Managed pci_iomap(). Map is automatically unmapped on driver detach. If
526 * desired, unmap manually only with pcim_iounmap().
527 *
528 * This SHOULD only be used once per BAR.
529 *
530 * NOTE:
531 * Contrary to the other pcim_* functions, this function does not return an
532 * IOMEM_ERR_PTR() on failure, but a simple NULL. This is done for backwards
533 * compatibility.
534 */
535void __iomem *pcim_iomap(struct pci_dev *pdev, int bar, unsigned long maxlen)
536{
537 void __iomem *mapping;
538 struct pcim_addr_devres *res;
539
540 if (!pci_bar_index_is_valid(bar))
541 return NULL;
542
543 res = pcim_addr_devres_alloc(pdev);
544 if (!res)
545 return NULL;
546 res->type = PCIM_ADDR_DEVRES_TYPE_MAPPING;
547
548 mapping = pci_iomap(pdev, bar, maxlen);
549 if (!mapping)
550 goto err_iomap;
551 res->baseaddr = mapping;
552
553 if (pcim_add_mapping_to_legacy_table(pdev, mapping, bar) != 0)
554 goto err_table;
555
556 devres_add(&pdev->dev, res);
557 return mapping;
558
559err_table:
560 pci_iounmap(pdev, mapping);
561err_iomap:
562 pcim_addr_devres_free(res);
563 return NULL;
564}
565EXPORT_SYMBOL(pcim_iomap);
566
567/**
568 * pcim_iounmap - Managed pci_iounmap()
569 * @pdev: PCI device to iounmap for
570 * @addr: Address to unmap
571 *
572 * Managed pci_iounmap(). @addr must have been mapped using a pcim_* mapping
573 * function.
574 */
575void pcim_iounmap(struct pci_dev *pdev, void __iomem *addr)
576{
577 struct pcim_addr_devres res_searched;
578
579 pcim_addr_devres_clear(&res_searched);
580 res_searched.type = PCIM_ADDR_DEVRES_TYPE_MAPPING;
581 res_searched.baseaddr = addr;
582
583 if (devres_release(&pdev->dev, pcim_addr_resource_release,
584 pcim_addr_resources_match, &res_searched) != 0) {
585 /* Doesn't exist. User passed nonsense. */
586 return;
587 }
588
589 pcim_remove_mapping_from_legacy_table(pdev, addr);
590}
591EXPORT_SYMBOL(pcim_iounmap);
592
593/**
594 * pcim_iomap_region - Request and iomap a PCI BAR
595 * @pdev: PCI device to map IO resources for
596 * @bar: Index of a BAR to map
597 * @name: Name of the driver requesting the resource
598 *
599 * Returns: __iomem pointer on success, an IOMEM_ERR_PTR on failure.
600 *
601 * Mapping and region will get automatically released on driver detach. If
602 * desired, release manually only with pcim_iounmap_region().
603 */
604void __iomem *pcim_iomap_region(struct pci_dev *pdev, int bar,
605 const char *name)
606{
607 int ret;
608 struct pcim_addr_devres *res;
609
610 if (!pci_bar_index_is_valid(bar))
611 return IOMEM_ERR_PTR(-EINVAL);
612
613 res = pcim_addr_devres_alloc(pdev);
614 if (!res)
615 return IOMEM_ERR_PTR(-ENOMEM);
616
617 res->type = PCIM_ADDR_DEVRES_TYPE_REGION_MAPPING;
618 res->bar = bar;
619
620 ret = pci_request_region(pdev, bar, name);
621 if (ret != 0)
622 goto err_region;
623
624 res->baseaddr = pci_iomap(pdev, bar, 0);
625 if (!res->baseaddr) {
626 ret = -EINVAL;
627 goto err_iomap;
628 }
629
630 devres_add(&pdev->dev, res);
631 return res->baseaddr;
632
633err_iomap:
634 pci_release_region(pdev, bar);
635err_region:
636 pcim_addr_devres_free(res);
637
638 return IOMEM_ERR_PTR(ret);
639}
640EXPORT_SYMBOL(pcim_iomap_region);
641
642/**
643 * pcim_iounmap_region - Unmap and release a PCI BAR
644 * @pdev: PCI device to operate on
645 * @bar: Index of BAR to unmap and release
646 *
647 * Unmap a BAR and release its region manually. Only pass BARs that were
648 * previously mapped by pcim_iomap_region().
649 */
650void pcim_iounmap_region(struct pci_dev *pdev, int bar)
651{
652 struct pcim_addr_devres res_searched;
653
654 pcim_addr_devres_clear(&res_searched);
655 res_searched.type = PCIM_ADDR_DEVRES_TYPE_REGION_MAPPING;
656 res_searched.bar = bar;
657
658 devres_release(&pdev->dev, pcim_addr_resource_release,
659 pcim_addr_resources_match, &res_searched);
660}
661EXPORT_SYMBOL(pcim_iounmap_region);
662
663/**
664 * pcim_iomap_regions - Request and iomap PCI BARs (DEPRECATED)
665 * @pdev: PCI device to map IO resources for
666 * @mask: Mask of BARs to request and iomap
667 * @name: Name of the driver requesting the resources
668 *
669 * Returns: 0 on success, negative error code on failure.
670 *
671 * Request and iomap regions specified by @mask.
672 *
673 * This function is DEPRECATED. Do not use it in new code.
674 * Use pcim_iomap_region() instead.
675 */
676int pcim_iomap_regions(struct pci_dev *pdev, int mask, const char *name)
677{
678 int ret;
679 int bar;
680 void __iomem *mapping;
681
682 for (bar = 0; bar < DEVICE_COUNT_RESOURCE; bar++) {
683 if (!mask_contains_bar(mask, bar))
684 continue;
685
686 mapping = pcim_iomap_region(pdev, bar, name);
687 if (IS_ERR(mapping)) {
688 ret = PTR_ERR(mapping);
689 goto err;
690 }
691 ret = pcim_add_mapping_to_legacy_table(pdev, mapping, bar);
692 if (ret != 0)
693 goto err;
694 }
695
696 return 0;
697
698err:
699 while (--bar >= 0) {
700 pcim_iounmap_region(pdev, bar);
701 pcim_remove_bar_from_legacy_table(pdev, bar);
702 }
703
704 return ret;
705}
706EXPORT_SYMBOL(pcim_iomap_regions);
707
708/**
709 * pcim_request_region - Request a PCI BAR
710 * @pdev: PCI device to request region for
711 * @bar: Index of BAR to request
712 * @name: Name of the driver requesting the resource
713 *
714 * Returns: 0 on success, a negative error code on failure.
715 *
716 * Request region specified by @bar.
717 *
718 * The region will automatically be released on driver detach. If desired,
719 * release manually only with pcim_release_region().
720 */
721int pcim_request_region(struct pci_dev *pdev, int bar, const char *name)
722{
723 int ret;
724 struct pcim_addr_devres *res;
725
726 if (!pci_bar_index_is_valid(bar))
727 return -EINVAL;
728
729 res = pcim_addr_devres_alloc(pdev);
730 if (!res)
731 return -ENOMEM;
732 res->type = PCIM_ADDR_DEVRES_TYPE_REGION;
733 res->bar = bar;
734
735 ret = pci_request_region(pdev, bar, name);
736 if (ret != 0) {
737 pcim_addr_devres_free(res);
738 return ret;
739 }
740
741 devres_add(&pdev->dev, res);
742 return 0;
743}
744EXPORT_SYMBOL(pcim_request_region);
745
746/**
747 * pcim_release_region - Release a PCI BAR
748 * @pdev: PCI device to operate on
749 * @bar: Index of BAR to release
750 *
751 * Release a region manually that was previously requested by
752 * pcim_request_region().
753 */
754static void pcim_release_region(struct pci_dev *pdev, int bar)
755{
756 struct pcim_addr_devres res_searched;
757
758 pcim_addr_devres_clear(&res_searched);
759 res_searched.type = PCIM_ADDR_DEVRES_TYPE_REGION;
760 res_searched.bar = bar;
761
762 devres_release(&pdev->dev, pcim_addr_resource_release,
763 pcim_addr_resources_match, &res_searched);
764}
765
766
767/**
768 * pcim_release_all_regions - Release all regions of a PCI-device
769 * @pdev: the PCI device
770 *
771 * Release all regions previously requested through pcim_request_region()
772 * or pcim_request_all_regions().
773 *
774 * Can be called from any context, i.e., not necessarily as a counterpart to
775 * pcim_request_all_regions().
776 */
777static void pcim_release_all_regions(struct pci_dev *pdev)
778{
779 int bar;
780
781 for (bar = 0; bar < PCI_STD_NUM_BARS; bar++)
782 pcim_release_region(pdev, bar);
783}
784
785/**
786 * pcim_request_all_regions - Request all regions
787 * @pdev: PCI device to map IO resources for
788 * @name: name of the driver requesting the resources
789 *
790 * Returns: 0 on success, negative error code on failure.
791 *
792 * Requested regions will automatically be released at driver detach. If
793 * desired, release individual regions with pcim_release_region() or all of
794 * them at once with pcim_release_all_regions().
795 */
796int pcim_request_all_regions(struct pci_dev *pdev, const char *name)
797{
798 int ret;
799 int bar;
800
801 for (bar = 0; bar < PCI_STD_NUM_BARS; bar++) {
802 ret = pcim_request_region(pdev, bar, name);
803 if (ret != 0)
804 goto err;
805 }
806
807 return 0;
808
809err:
810 pcim_release_all_regions(pdev);
811
812 return ret;
813}
814EXPORT_SYMBOL(pcim_request_all_regions);
815
816/**
817 * pcim_iomap_range - Create a ranged __iomap mapping within a PCI BAR
818 * @pdev: PCI device to map IO resources for
819 * @bar: Index of the BAR
820 * @offset: Offset from the begin of the BAR
821 * @len: Length in bytes for the mapping
822 *
823 * Returns: __iomem pointer on success, an IOMEM_ERR_PTR on failure.
824 *
825 * Creates a new IO-Mapping within the specified @bar, ranging from @offset to
826 * @offset + @len.
827 *
828 * The mapping will automatically get unmapped on driver detach. If desired,
829 * release manually only with pcim_iounmap().
830 */
831void __iomem *pcim_iomap_range(struct pci_dev *pdev, int bar,
832 unsigned long offset, unsigned long len)
833{
834 void __iomem *mapping;
835 struct pcim_addr_devres *res;
836
837 if (!pci_bar_index_is_valid(bar))
838 return IOMEM_ERR_PTR(-EINVAL);
839
840 res = pcim_addr_devres_alloc(pdev);
841 if (!res)
842 return IOMEM_ERR_PTR(-ENOMEM);
843
844 mapping = pci_iomap_range(pdev, bar, offset, len);
845 if (!mapping) {
846 pcim_addr_devres_free(res);
847 return IOMEM_ERR_PTR(-EINVAL);
848 }
849
850 res->type = PCIM_ADDR_DEVRES_TYPE_MAPPING;
851 res->baseaddr = mapping;
852
853 /*
854 * Ranged mappings don't get added to the legacy-table, since the table
855 * only ever keeps track of whole BARs.
856 */
857
858 devres_add(&pdev->dev, res);
859 return mapping;
860}
861EXPORT_SYMBOL(pcim_iomap_range);