1 #include <linux/slab.h>
2 #include <linux/module.h>
3 #include <linux/kernel.h>
7 #include <pcmcia/cistpl.h>
8 #include "cs_internal.h"
11 struct pcmcia_align_data
{
16 static resource_size_t
pcmcia_align(void *align_data
,
17 const struct resource
*res
,
18 resource_size_t size
, resource_size_t align
)
20 struct pcmcia_align_data
*data
= align_data
;
21 resource_size_t start
;
23 start
= (res
->start
& ~data
->mask
) + data
->offset
;
24 if (start
< res
->start
)
25 start
+= data
->mask
+ 1;
29 static struct resource
*find_io_region(struct pcmcia_socket
*s
,
30 unsigned long base
, int num
,
33 struct resource
*res
= pcmcia_make_resource(0, num
, IORESOURCE_IO
,
35 struct pcmcia_align_data data
;
38 data
.mask
= align
- 1;
39 data
.offset
= base
& data
.mask
;
41 ret
= pci_bus_alloc_resource(s
->cb_dev
->bus
, res
, num
, 1,
42 base
, 0, pcmcia_align
, &data
);
50 static int res_pci_find_io(struct pcmcia_socket
*s
, unsigned int attr
,
51 unsigned int *base
, unsigned int num
,
52 unsigned int align
, struct resource
**parent
)
56 /* Check for an already-allocated window that must conflict with
57 * what was asked for. It is a hack because it does not catch all
58 * potential conflicts, just the most obvious ones.
60 for (i
= 0; i
< MAX_IO_WIN
; i
++) {
67 if ((s
->io
[i
].res
->start
& (align
-1)) == *base
)
71 for (i
= 0; i
< MAX_IO_WIN
; i
++) {
72 struct resource
*res
= s
->io
[i
].res
;
75 if (res
&& (res
->flags
& IORESOURCE_BITS
) !=
76 (attr
& IORESOURCE_BITS
))
83 res
= s
->io
[i
].res
= find_io_region(s
, *base
, num
,
90 ((res
->flags
& ~IORESOURCE_BITS
) |
91 (attr
& IORESOURCE_BITS
));
97 /* Try to extend top of window */
99 if ((*base
== 0) || (*base
== try)) {
100 ret
= adjust_resource(s
->io
[i
].res
, res
->start
,
101 resource_size(res
) + num
);
105 s
->io
[i
].InUse
+= num
;
110 /* Try to extend bottom of window */
111 try = res
->start
- num
;
112 if ((*base
== 0) || (*base
== try)) {
113 ret
= adjust_resource(s
->io
[i
].res
,
115 resource_size(res
) + num
);
119 s
->io
[i
].InUse
+= num
;
127 static struct resource
*res_pci_find_mem(u_long base
, u_long num
,
128 u_long align
, int low
, struct pcmcia_socket
*s
)
130 struct resource
*res
= pcmcia_make_resource(0, num
, IORESOURCE_MEM
,
132 struct pcmcia_align_data data
;
138 data
.mask
= align
- 1;
139 data
.offset
= base
& data
.mask
;
145 ret
= pci_bus_alloc_resource(s
->cb_dev
->bus
,
147 pcmcia_align
, &data
);
157 static int res_pci_init(struct pcmcia_socket
*s
)
159 if (!s
->cb_dev
|| !(s
->features
& SS_CAP_PAGE_REGS
)) {
160 dev_err(&s
->dev
, "not supported by res_pci\n");
166 struct pccard_resource_ops pccard_nonstatic_ops
= {
167 .validate_mem
= NULL
,
168 .find_io
= res_pci_find_io
,
169 .find_mem
= res_pci_find_mem
,
170 .init
= res_pci_init
,
173 EXPORT_SYMBOL(pccard_nonstatic_ops
);