/[pkgs]/rpms/kernel/F-9/linux-2.6-alpha-pci.c.patch
ViewVC logotype

Contents of /rpms/kernel/F-9/linux-2.6-alpha-pci.c.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1 - (show annotations) (download) (as text)
Thu Mar 12 12:57:36 2009 UTC (8 months, 2 weeks ago) by oliver
Branch: MAIN
CVS Tags: HEAD
File MIME type: text/x-patch
* Wed Mar 11 2009 Oliver Falk <oliver@linux-kernel.at> 2.6.28.2-7
- Modify kernel spec to build on alpha again
- Remove all alphaev* from spec, as we only build for 'alpha'
- Patches for alpha:
  - linux-2.6.28-alpha-exec_range.patch
    - add execshield dummy functions for alpha
  - linux-2.6-alpha-pci_get_bus_and_slot.patch
    - Do not limit bus/slot search to PCI domain 0 on alpha
  - linux-2.6-alpha-eepro100-cleanup.patch
    - cleanup extraneous "freeing mc frame" messages from driver
  - linux-2.6.28-alpha-pci.h.patch, linux-2.6-alpha-pci.c.patch
    - Platform support for /proc/bus/pci/X/Y mmap()s
1 --- a/arch/alpha/kernel/pci.c.ORIG 2008-10-17 13:10:37.000000000 -0400
2 +++ a/arch/alpha/kernel/pci.c 2008-10-22 08:51:27.000000000 -0400
3 @@ -560,6 +560,176 @@ void pci_iounmap(struct pci_dev *dev, vo
4 EXPORT_SYMBOL(pci_iomap);
5 EXPORT_SYMBOL(pci_iounmap);
6
7 +/* Platform support for /proc/bus/pci/X/Y mmap()s. */
8 +
9 +/* If the user uses a host-bridge as the PCI device, he may use
10 + * this to perform a raw mmap() of the I/O or MEM space behind
11 + * that controller.
12 + *
13 + * This can be useful for execution of x86 PCI bios initialization code
14 + * on a PCI card, like the xfree86 int10 stuff does.
15 + */
16 +static int __pci_mmap_make_offset_bus(struct pci_dev *pdev,
17 + struct vm_area_struct *vma,
18 + enum pci_mmap_state mmap_state)
19 +{
20 + struct pci_controller *hose = pdev->sysdata;
21 + unsigned long space_size, user_offset, user_size;
22 +
23 + if (mmap_state == pci_mmap_io) {
24 + space_size = (hose->io_space->end -
25 + hose->io_space->start) + 1;
26 + } else {
27 + space_size = (hose->mem_space->end -
28 + hose->mem_space->start) + 1;
29 + }
30 +
31 + /* Make sure the request is in range. */
32 + user_offset = vma->vm_pgoff << PAGE_SHIFT;
33 + user_size = vma->vm_end - vma->vm_start;
34 +
35 + if (user_offset >= space_size ||
36 + (user_offset + user_size) > space_size)
37 + return -EINVAL;
38 +
39 + /* FIXME FIXME: for now, only worry about DENSE IO and MEM */
40 + if (mmap_state == pci_mmap_io) {
41 + vma->vm_pgoff = (hose->dense_io_base +
42 + user_offset) >> PAGE_SHIFT;
43 + } else {
44 + vma->vm_pgoff = (hose->dense_mem_base +
45 + user_offset) >> PAGE_SHIFT;
46 + }
47 +
48 + return 0;
49 +}
50 +
51 +/* Adjust vm_pgoff of VMA such that it is the physical page offset
52 + * corresponding to the 32-bit pci bus offset for DEV requested by the user.
53 + *
54 + * Basically, the user finds the base address for his device which he wishes
55 + * to mmap. They read the 32-bit value from the config space base register,
56 + * add whatever PAGE_SIZE multiple offset they wish, and feed this into the
57 + * offset parameter of mmap on /proc/bus/pci/XXX for that device.
58 + *
59 + * Returns negative error code on failure, zero on success.
60 + */
61 +static int __pci_mmap_make_offset(struct pci_dev *pdev,
62 + struct vm_area_struct *vma,
63 + enum pci_mmap_state mmap_state)
64 +{
65 + unsigned long user_paddr, user_size;
66 + int i, err;
67 + unsigned long orig_user_paddr = vma->vm_pgoff << PAGE_SHIFT;
68 +
69 + /* First compute the physical address in vma->vm_pgoff,
70 + * making sure the user offset is within range in the
71 + * appropriate PCI space.
72 + */
73 + err = __pci_mmap_make_offset_bus(pdev, vma, mmap_state);
74 + if (err)
75 + return err;
76 +
77 + /* If this is a mapping on a host bridge, any address
78 + * is OK.
79 + */
80 + if ((pdev->class >> 8) == PCI_CLASS_BRIDGE_HOST)
81 + return err;
82 +
83 + /* Otherwise make sure it's in the range for one of the
84 + * device's resources.
85 + */
86 + user_paddr = vma->vm_pgoff << PAGE_SHIFT;
87 + user_size = vma->vm_end - vma->vm_start;
88 +
89 + for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
90 + struct resource *rp = &pdev->resource[i];
91 +
92 + /* Active? */
93 + if (!rp->flags)
94 + continue;
95 +
96 + /* Same type? */
97 + if (i == PCI_ROM_RESOURCE) {
98 + if (mmap_state != pci_mmap_mem)
99 + continue;
100 + } else {
101 + if ((mmap_state == pci_mmap_io &&
102 + (rp->flags & IORESOURCE_IO) == 0) ||
103 + (mmap_state == pci_mmap_mem &&
104 + (rp->flags & IORESOURCE_MEM) == 0))
105 + continue;
106 + }
107 +
108 + if ((rp->start <= user_paddr) &&
109 + (user_paddr + user_size) <= (rp->end + 1UL))
110 + break;
111 + if ((rp->start <= orig_user_paddr) &&
112 + (orig_user_paddr + user_size) <= (rp->end + 1UL)) {
113 + printk(KERN_WARNING "pci: res-range w/o bus base\n");
114 + break;
115 + }
116 + }
117 +
118 + if (i > PCI_ROM_RESOURCE)
119 + return -EINVAL;
120 +
121 + return 0;
122 +}
123 +
124 +/* Set vm_flags of VMA, as appropriate for this architecture, for a pci device
125 + * mapping.
126 + */
127 +static void __pci_mmap_set_flags(struct pci_dev *dev,
128 + struct vm_area_struct *vma,
129 + enum pci_mmap_state mmap_state)
130 +{
131 + vma->vm_flags |= (VM_IO | VM_RESERVED);
132 +}
133 +
134 +/* Set vm_page_prot of VMA, as appropriate for this architecture, for a pci
135 + * device mapping.
136 + */
137 +static void __pci_mmap_set_pgprot(struct pci_dev *dev,
138 + struct vm_area_struct *vma,
139 + enum pci_mmap_state mmap_state)
140 +{
141 + /* FIXME FIXME *//* Our io_remap_pfn_range takes care of this, do nothing. */
142 +}
143 +
144 +/* Perform the actual remap of the pages for a PCI device mapping, as appropriate
145 + * for this architecture. The region in the process to map is described by vm_start
146 + * and vm_end members of VMA, the base physical address is found in vm_pgoff.
147 + * The pci device structure is provided so that architectures may make mapping
148 + * decisions on a per-device or per-bus basis.
149 + *
150 + * Returns a negative error code on failure, zero on success.
151 + */
152 +int pci_mmap_page_range(struct pci_dev *dev,
153 + struct vm_area_struct *vma,
154 + enum pci_mmap_state mmap_state,
155 + int write_combine)
156 +{
157 + int ret;
158 +
159 + ret = __pci_mmap_make_offset(dev, vma, mmap_state);
160 + if (ret < 0)
161 + return ret;
162 +
163 + __pci_mmap_set_flags(dev, vma, mmap_state);
164 + __pci_mmap_set_pgprot(dev, vma, mmap_state);
165 +
166 + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
167 + ret = io_remap_pfn_range(vma, vma->vm_start,
168 + vma->vm_pgoff,
169 + vma->vm_end - vma->vm_start,
170 + vma->vm_page_prot);
171 + if (ret)
172 + return ret;
173 +
174 + return 0;
175 +}
176 +
177 /* FIXME: Some boxes have multiple ISA bridges! */
178 struct pci_dev *isa_bridge;
179 EXPORT_SYMBOL(isa_bridge);

admin@fedoraproject.org
ViewVC Help
Powered by ViewVC 1.1.2