aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/pcmcia/Kconfig2
-rw-r--r--drivers/pcmcia/Makefile7
-rw-r--r--drivers/pcmcia/cs_internal.h8
-rw-r--r--drivers/pcmcia/rsrc_iodyn.c107
-rw-r--r--drivers/pcmcia/rsrc_mgr.c110
-rw-r--r--drivers/pcmcia/rsrc_nonstatic.c24
6 files changed, 141 insertions, 117 deletions
diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig
index d189e4743e69..4c5b53f62079 100644
--- a/drivers/pcmcia/Kconfig
+++ b/drivers/pcmcia/Kconfig
@@ -317,7 +317,7 @@ config ELECTRA_CF
317 PA Semi Electra eval board. 317 PA Semi Electra eval board.
318 318
319config PCCARD_NONSTATIC 319config PCCARD_NONSTATIC
320 tristate 320 bool
321 321
322config PCCARD_IODYN 322config PCCARD_IODYN
323 bool 323 bool
diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile
index 8122b03e2ae5..7031d0a4f4b0 100644
--- a/drivers/pcmcia/Makefile
+++ b/drivers/pcmcia/Makefile
@@ -2,7 +2,7 @@
2# Makefile for the kernel pcmcia subsystem (c/o David Hinds) 2# Makefile for the kernel pcmcia subsystem (c/o David Hinds)
3# 3#
4 4
5pcmcia_core-y += cs.o rsrc_mgr.o socket_sysfs.o 5pcmcia_core-y += cs.o socket_sysfs.o
6pcmcia_core-$(CONFIG_CARDBUS) += cardbus.o 6pcmcia_core-$(CONFIG_CARDBUS) += cardbus.o
7obj-$(CONFIG_PCCARD) += pcmcia_core.o 7obj-$(CONFIG_PCCARD) += pcmcia_core.o
8 8
@@ -10,7 +10,10 @@ pcmcia-y += ds.o pcmcia_resource.o cistpl.o pcmcia_cis.o
10pcmcia-$(CONFIG_PCMCIA_IOCTL) += pcmcia_ioctl.o 10pcmcia-$(CONFIG_PCMCIA_IOCTL) += pcmcia_ioctl.o
11obj-$(CONFIG_PCMCIA) += pcmcia.o 11obj-$(CONFIG_PCMCIA) += pcmcia.o
12 12
13obj-$(CONFIG_PCCARD_NONSTATIC) += rsrc_nonstatic.o 13pcmcia_rsrc-y += rsrc_mgr.o
14pcmcia_rsrc-$(CONFIG_PCCARD_NONSTATIC) += rsrc_nonstatic.o
15pcmcia_rsrc-$(CONFIG_PCCARD_IODYN) += rsrc_iodyn.o
16obj-$(CONFIG_PCCARD) += pcmcia_rsrc.o
14 17
15 18
16# socket drivers 19# socket drivers
diff --git a/drivers/pcmcia/cs_internal.h b/drivers/pcmcia/cs_internal.h
index 74d91c8849ba..ab000ea67296 100644
--- a/drivers/pcmcia/cs_internal.h
+++ b/drivers/pcmcia/cs_internal.h
@@ -89,6 +89,14 @@ struct pccard_resource_ops {
89 89
90 90
91/* 91/*
92 * Stuff internal to module "pcmcia_rsrc":
93 */
94extern int static_init(struct pcmcia_socket *s);
95extern struct resource *pcmcia_make_resource(unsigned long start,
96 unsigned long end,
97 int flags, const char *name);
98
99/*
92 * Stuff internal to module "pcmcia_core": 100 * Stuff internal to module "pcmcia_core":
93 */ 101 */
94 102
diff --git a/drivers/pcmcia/rsrc_iodyn.c b/drivers/pcmcia/rsrc_iodyn.c
new file mode 100644
index 000000000000..3fa808b582f6
--- /dev/null
+++ b/drivers/pcmcia/rsrc_iodyn.c
@@ -0,0 +1,107 @@
1/*
2 * rsrc_iodyn.c -- Resource management routines for MEM-static sockets.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * The initial developer of the original code is David A. Hinds
9 * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
10 * are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
11 *
12 * (C) 1999 David A. Hinds
13 */
14
15#include <linux/module.h>
16#include <linux/kernel.h>
17
18#include <pcmcia/cs_types.h>
19#include <pcmcia/ss.h>
20#include <pcmcia/cs.h>
21#include <pcmcia/cistpl.h>
22#include "cs_internal.h"
23
24
25struct pcmcia_align_data {
26 unsigned long mask;
27 unsigned long offset;
28};
29
30static resource_size_t pcmcia_align(void *align_data,
31 const struct resource *res,
32 resource_size_t size, resource_size_t align)
33{
34 struct pcmcia_align_data *data = align_data;
35 resource_size_t start;
36
37 start = (res->start & ~data->mask) + data->offset;
38 if (start < res->start)
39 start += data->mask + 1;
40
41#ifdef CONFIG_X86
42 if (res->flags & IORESOURCE_IO) {
43 if (start & 0x300)
44 start = (start + 0x3ff) & ~0x3ff;
45 }
46#endif
47
48#ifdef CONFIG_M68K
49 if (res->flags & IORESOURCE_IO) {
50 if ((res->start + size - 1) >= 1024)
51 start = res->end;
52 }
53#endif
54
55 return start;
56}
57
58
59static int iodyn_adjust_io_region(struct resource *res, unsigned long r_start,
60 unsigned long r_end, struct pcmcia_socket *s)
61{
62 return adjust_resource(res, r_start, r_end - r_start + 1);
63}
64
65
66static struct resource *iodyn_find_io_region(unsigned long base, int num,
67 unsigned long align, struct pcmcia_socket *s)
68{
69 struct resource *res = pcmcia_make_resource(0, num, IORESOURCE_IO,
70 dev_name(&s->dev));
71 struct pcmcia_align_data data;
72 unsigned long min = base;
73 int ret;
74
75 if (align == 0)
76 align = 0x10000;
77
78 data.mask = align - 1;
79 data.offset = base & data.mask;
80
81#ifdef CONFIG_PCI
82 if (s->cb_dev) {
83 ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num, 1,
84 min, 0, pcmcia_align, &data);
85 } else
86#endif
87 ret = allocate_resource(&ioport_resource, res, num, min, ~0UL,
88 1, pcmcia_align, &data);
89
90 if (ret != 0) {
91 kfree(res);
92 res = NULL;
93 }
94 return res;
95}
96
97struct pccard_resource_ops pccard_iodyn_ops = {
98 .validate_mem = NULL,
99 .adjust_io_region = iodyn_adjust_io_region,
100 .find_io = iodyn_find_io_region,
101 .find_mem = NULL,
102 .add_io = NULL,
103 .add_mem = NULL,
104 .init = static_init,
105 .exit = NULL,
106};
107EXPORT_SYMBOL(pccard_iodyn_ops);
diff --git a/drivers/pcmcia/rsrc_mgr.c b/drivers/pcmcia/rsrc_mgr.c
index ffa5f3cae57b..71838cae890c 100644
--- a/drivers/pcmcia/rsrc_mgr.c
+++ b/drivers/pcmcia/rsrc_mgr.c
@@ -22,7 +22,7 @@
22#include <pcmcia/cistpl.h> 22#include <pcmcia/cistpl.h>
23#include "cs_internal.h" 23#include "cs_internal.h"
24 24
25static int static_init(struct pcmcia_socket *s) 25int static_init(struct pcmcia_socket *s)
26{ 26{
27 /* the good thing about SS_CAP_STATIC_MAP sockets is 27 /* the good thing about SS_CAP_STATIC_MAP sockets is
28 * that they don't need a resource database */ 28 * that they don't need a resource database */
@@ -32,118 +32,34 @@ static int static_init(struct pcmcia_socket *s)
32 return 0; 32 return 0;
33} 33}
34 34
35 35struct resource *pcmcia_make_resource(unsigned long start, unsigned long end,
36struct pccard_resource_ops pccard_static_ops = { 36 int flags, const char *name)
37 .validate_mem = NULL,
38 .adjust_io_region = NULL,
39 .find_io = NULL,
40 .find_mem = NULL,
41 .add_io = NULL,
42 .add_mem = NULL,
43 .init = static_init,
44 .exit = NULL,
45};
46EXPORT_SYMBOL(pccard_static_ops);
47
48
49#ifdef CONFIG_PCCARD_IODYN
50
51static struct resource *
52make_resource(unsigned long b, unsigned long n, int flags, char *name)
53{ 37{
54 struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL); 38 struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL);
55 39
56 if (res) { 40 if (res) {
57 res->name = name; 41 res->name = name;
58 res->start = b; 42 res->start = start;
59 res->end = b + n - 1; 43 res->end = start + end - 1;
60 res->flags = flags; 44 res->flags = flags;
61 } 45 }
62 return res; 46 return res;
63} 47}
64 48
65struct pcmcia_align_data {
66 unsigned long mask;
67 unsigned long offset;
68};
69
70static resource_size_t pcmcia_align(void *align_data,
71 const struct resource *res,
72 resource_size_t size, resource_size_t align)
73{
74 struct pcmcia_align_data *data = align_data;
75 resource_size_t start;
76
77 start = (res->start & ~data->mask) + data->offset;
78 if (start < res->start)
79 start += data->mask + 1;
80
81#ifdef CONFIG_X86
82 if (res->flags & IORESOURCE_IO) {
83 if (start & 0x300)
84 start = (start + 0x3ff) & ~0x3ff;
85 }
86#endif
87
88#ifdef CONFIG_M68K
89 if (res->flags & IORESOURCE_IO) {
90 if ((res->start + size - 1) >= 1024)
91 start = res->end;
92 }
93#endif
94
95 return start;
96}
97
98
99static int iodyn_adjust_io_region(struct resource *res, unsigned long r_start,
100 unsigned long r_end, struct pcmcia_socket *s)
101{
102 return adjust_resource(res, r_start, r_end - r_start + 1);
103}
104
105
106static struct resource *iodyn_find_io_region(unsigned long base, int num,
107 unsigned long align, struct pcmcia_socket *s)
108{
109 struct resource *res = make_resource(0, num, IORESOURCE_IO,
110 dev_name(&s->dev));
111 struct pcmcia_align_data data;
112 unsigned long min = base;
113 int ret;
114
115 if (align == 0)
116 align = 0x10000;
117 49
118 data.mask = align - 1; 50struct pccard_resource_ops pccard_static_ops = {
119 data.offset = base & data.mask;
120
121#ifdef CONFIG_PCI
122 if (s->cb_dev) {
123 ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num, 1,
124 min, 0, pcmcia_align, &data);
125 } else
126#endif
127 ret = allocate_resource(&ioport_resource, res, num, min, ~0UL,
128 1, pcmcia_align, &data);
129
130 if (ret != 0) {
131 kfree(res);
132 res = NULL;
133 }
134 return res;
135}
136
137struct pccard_resource_ops pccard_iodyn_ops = {
138 .validate_mem = NULL, 51 .validate_mem = NULL,
139 .adjust_io_region = iodyn_adjust_io_region, 52 .adjust_io_region = NULL,
140 .find_io = iodyn_find_io_region, 53 .find_io = NULL,
141 .find_mem = NULL, 54 .find_mem = NULL,
142 .add_io = NULL, 55 .add_io = NULL,
143 .add_mem = NULL, 56 .add_mem = NULL,
144 .init = static_init, 57 .init = static_init,
145 .exit = NULL, 58 .exit = NULL,
146}; 59};
147EXPORT_SYMBOL(pccard_iodyn_ops); 60EXPORT_SYMBOL(pccard_static_ops);
61
148 62
149#endif /* CONFIG_PCCARD_IODYN */ 63MODULE_AUTHOR("David A. Hinds, Dominik Brodowski");
64MODULE_LICENSE("GPL");
65MODULE_ALIAS("rsrc_nonstatic");
diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c
index a6eb7b59ba9f..c5ebc603b058 100644
--- a/drivers/pcmcia/rsrc_nonstatic.c
+++ b/drivers/pcmcia/rsrc_nonstatic.c
@@ -34,8 +34,10 @@
34#include <pcmcia/cistpl.h> 34#include <pcmcia/cistpl.h>
35#include "cs_internal.h" 35#include "cs_internal.h"
36 36
37/* moved to rsrc_mgr.c
37MODULE_AUTHOR("David A. Hinds, Dominik Brodowski"); 38MODULE_AUTHOR("David A. Hinds, Dominik Brodowski");
38MODULE_LICENSE("GPL"); 39MODULE_LICENSE("GPL");
40*/
39 41
40/* Parameters that can be set with 'insmod' */ 42/* Parameters that can be set with 'insmod' */
41 43
@@ -70,27 +72,13 @@ struct socket_data {
70======================================================================*/ 72======================================================================*/
71 73
72static struct resource * 74static struct resource *
73make_resource(resource_size_t b, resource_size_t n, int flags, const char *name)
74{
75 struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL);
76
77 if (res) {
78 res->name = name;
79 res->start = b;
80 res->end = b + n - 1;
81 res->flags = flags;
82 }
83 return res;
84}
85
86static struct resource *
87claim_region(struct pcmcia_socket *s, resource_size_t base, 75claim_region(struct pcmcia_socket *s, resource_size_t base,
88 resource_size_t size, int type, char *name) 76 resource_size_t size, int type, char *name)
89{ 77{
90 struct resource *res, *parent; 78 struct resource *res, *parent;
91 79
92 parent = type & IORESOURCE_MEM ? &iomem_resource : &ioport_resource; 80 parent = type & IORESOURCE_MEM ? &iomem_resource : &ioport_resource;
93 res = make_resource(base, size, type | IORESOURCE_BUSY, name); 81 res = pcmcia_make_resource(base, size, type | IORESOURCE_BUSY, name);
94 82
95 if (res) { 83 if (res) {
96#ifdef CONFIG_PCI 84#ifdef CONFIG_PCI
@@ -698,7 +686,8 @@ static int nonstatic_adjust_io_region(struct resource *res, unsigned long r_star
698static struct resource *nonstatic_find_io_region(unsigned long base, int num, 686static struct resource *nonstatic_find_io_region(unsigned long base, int num,
699 unsigned long align, struct pcmcia_socket *s) 687 unsigned long align, struct pcmcia_socket *s)
700{ 688{
701 struct resource *res = make_resource(0, num, IORESOURCE_IO, dev_name(&s->dev)); 689 struct resource *res = pcmcia_make_resource(0, num, IORESOURCE_IO,
690 dev_name(&s->dev));
702 struct socket_data *s_data = s->resource_data; 691 struct socket_data *s_data = s->resource_data;
703 struct pcmcia_align_data data; 692 struct pcmcia_align_data data;
704 unsigned long min = base; 693 unsigned long min = base;
@@ -730,7 +719,8 @@ static struct resource *nonstatic_find_io_region(unsigned long base, int num,
730static struct resource *nonstatic_find_mem_region(u_long base, u_long num, 719static struct resource *nonstatic_find_mem_region(u_long base, u_long num,
731 u_long align, int low, struct pcmcia_socket *s) 720 u_long align, int low, struct pcmcia_socket *s)
732{ 721{
733 struct resource *res = make_resource(0, num, IORESOURCE_MEM, dev_name(&s->dev)); 722 struct resource *res = pcmcia_make_resource(0, num, IORESOURCE_MEM,
723 dev_name(&s->dev));
734 struct socket_data *s_data = s->resource_data; 724 struct socket_data *s_data = s->resource_data;
735 struct pcmcia_align_data data; 725 struct pcmcia_align_data data;
736 unsigned long min, max; 726 unsigned long min, max;