aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pcmcia/pcmcia_resource.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pcmcia/pcmcia_resource.c')
-rw-r--r--drivers/pcmcia/pcmcia_resource.c45
1 files changed, 22 insertions, 23 deletions
diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c
index 08377232d8eb..dbd5571064d1 100644
--- a/drivers/pcmcia/pcmcia_resource.c
+++ b/drivers/pcmcia/pcmcia_resource.c
@@ -88,7 +88,7 @@ static int alloc_io_space(struct pcmcia_socket *s, u_int attr, ioaddr_t *base,
88 } 88 }
89 if ((s->features & SS_CAP_STATIC_MAP) && s->io_offset) { 89 if ((s->features & SS_CAP_STATIC_MAP) && s->io_offset) {
90 *base = s->io_offset | (*base & 0x0fff); 90 *base = s->io_offset | (*base & 0x0fff);
91 s->io[0].Attributes = attr; 91 s->io[0].res->flags = (s->io[0].res->flags & ~IORESOURCE_BITS) | (attr & IORESOURCE_BITS);
92 return 0; 92 return 0;
93 } 93 }
94 /* Check for an already-allocated window that must conflict with 94 /* Check for an already-allocated window that must conflict with
@@ -96,38 +96,36 @@ static int alloc_io_space(struct pcmcia_socket *s, u_int attr, ioaddr_t *base,
96 * potential conflicts, just the most obvious ones. 96 * potential conflicts, just the most obvious ones.
97 */ 97 */
98 for (i = 0; i < MAX_IO_WIN; i++) 98 for (i = 0; i < MAX_IO_WIN; i++)
99 if ((s->io[i].NumPorts != 0) && 99 if ((s->io[i].res) &&
100 ((s->io[i].BasePort & (align-1)) == *base)) 100 ((s->io[i].res->start & (align-1)) == *base))
101 return 1; 101 return 1;
102 for (i = 0; i < MAX_IO_WIN; i++) { 102 for (i = 0; i < MAX_IO_WIN; i++) {
103 if (s->io[i].NumPorts == 0) { 103 if (!s->io[i].res) {
104 s->io[i].res = pcmcia_find_io_region(*base, num, align, s); 104 s->io[i].res = pcmcia_find_io_region(*base, num, align, s);
105 if (s->io[i].res) { 105 if (s->io[i].res) {
106 s->io[i].Attributes = attr; 106 *base = s->io[i].res->start;
107 s->io[i].BasePort = *base = s->io[i].res->start; 107 s->io[i].res->flags = (s->io[i].res->flags & ~IORESOURCE_BITS) | (attr & IORESOURCE_BITS);
108 s->io[i].NumPorts = s->io[i].InUse = num; 108 s->io[i].InUse = num;
109 break; 109 break;
110 } else 110 } else
111 return 1; 111 return 1;
112 } else if (s->io[i].Attributes != attr) 112 } else if ((s->io[i].res->flags & IORESOURCE_BITS) != (attr & IORESOURCE_BITS))
113 continue; 113 continue;
114 /* Try to extend top of window */ 114 /* Try to extend top of window */
115 try = s->io[i].BasePort + s->io[i].NumPorts; 115 try = s->io[i].res->end + 1;
116 if ((*base == 0) || (*base == try)) 116 if ((*base == 0) || (*base == try))
117 if (pcmcia_adjust_io_region(s->io[i].res, s->io[i].res->start, 117 if (pcmcia_adjust_io_region(s->io[i].res, s->io[i].res->start,
118 s->io[i].res->end + num, s) == 0) { 118 s->io[i].res->end + num, s) == 0) {
119 *base = try; 119 *base = try;
120 s->io[i].NumPorts += num;
121 s->io[i].InUse += num; 120 s->io[i].InUse += num;
122 break; 121 break;
123 } 122 }
124 /* Try to extend bottom of window */ 123 /* Try to extend bottom of window */
125 try = s->io[i].BasePort - num; 124 try = s->io[i].res->start - num;
126 if ((*base == 0) || (*base == try)) 125 if ((*base == 0) || (*base == try))
127 if (pcmcia_adjust_io_region(s->io[i].res, s->io[i].res->start - num, 126 if (pcmcia_adjust_io_region(s->io[i].res, s->io[i].res->start - num,
128 s->io[i].res->end, s) == 0) { 127 s->io[i].res->end, s) == 0) {
129 s->io[i].BasePort = *base = try; 128 *base = try;
130 s->io[i].NumPorts += num;
131 s->io[i].InUse += num; 129 s->io[i].InUse += num;
132 break; 130 break;
133 } 131 }
@@ -142,12 +140,13 @@ static void release_io_space(struct pcmcia_socket *s, ioaddr_t base,
142 int i; 140 int i;
143 141
144 for (i = 0; i < MAX_IO_WIN; i++) { 142 for (i = 0; i < MAX_IO_WIN; i++) {
145 if ((s->io[i].BasePort <= base) && 143 if (!s->io[i].res)
146 (s->io[i].BasePort+s->io[i].NumPorts >= base+num)) { 144 continue;
145 if ((s->io[i].res->start <= base) &&
146 (s->io[i].res->end >= base+num-1)) {
147 s->io[i].InUse -= num; 147 s->io[i].InUse -= num;
148 /* Free the window if no one else is using it */ 148 /* Free the window if no one else is using it */
149 if (s->io[i].InUse == 0) { 149 if (s->io[i].InUse == 0) {
150 s->io[i].NumPorts = 0;
151 release_resource(s->io[i].res); 150 release_resource(s->io[i].res);
152 kfree(s->io[i].res); 151 kfree(s->io[i].res);
153 s->io[i].res = NULL; 152 s->io[i].res = NULL;
@@ -224,8 +223,8 @@ int pccard_get_configuration_info(struct pcmcia_socket *s,
224 config->AssignedIRQ = s->irq.AssignedIRQ; 223 config->AssignedIRQ = s->irq.AssignedIRQ;
225 if (config->AssignedIRQ) 224 if (config->AssignedIRQ)
226 config->Attributes |= CONF_ENABLE_IRQ; 225 config->Attributes |= CONF_ENABLE_IRQ;
227 config->BasePort1 = s->io[0].BasePort; 226 config->BasePort1 = s->io[0].res->start;
228 config->NumPorts1 = s->io[0].NumPorts; 227 config->NumPorts1 = s->io[0].res->end - config->BasePort1 + 1;
229 } 228 }
230 return CS_SUCCESS; 229 return CS_SUCCESS;
231 } 230 }
@@ -468,7 +467,7 @@ int pcmcia_release_configuration(struct pcmcia_device *p_dev)
468 } 467 }
469 if (c->state & CONFIG_IO_REQ) 468 if (c->state & CONFIG_IO_REQ)
470 for (i = 0; i < MAX_IO_WIN; i++) { 469 for (i = 0; i < MAX_IO_WIN; i++) {
471 if (s->io[i].NumPorts == 0) 470 if (!s->io[i].res)
472 continue; 471 continue;
473 s->io[i].Config--; 472 s->io[i].Config--;
474 if (s->io[i].Config != 0) 473 if (s->io[i].Config != 0)
@@ -679,10 +678,10 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev,
679 if (c->state & CONFIG_IO_REQ) { 678 if (c->state & CONFIG_IO_REQ) {
680 iomap.speed = io_speed; 679 iomap.speed = io_speed;
681 for (i = 0; i < MAX_IO_WIN; i++) 680 for (i = 0; i < MAX_IO_WIN; i++)
682 if (s->io[i].NumPorts != 0) { 681 if (s->io[i].res) {
683 iomap.map = i; 682 iomap.map = i;
684 iomap.flags = MAP_ACTIVE; 683 iomap.flags = MAP_ACTIVE;
685 switch (s->io[i].Attributes & IO_DATA_PATH_WIDTH) { 684 switch (s->io[i].res->flags & IO_DATA_PATH_WIDTH) {
686 case IO_DATA_PATH_WIDTH_16: 685 case IO_DATA_PATH_WIDTH_16:
687 iomap.flags |= MAP_16BIT; break; 686 iomap.flags |= MAP_16BIT; break;
688 case IO_DATA_PATH_WIDTH_AUTO: 687 case IO_DATA_PATH_WIDTH_AUTO:
@@ -690,8 +689,8 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev,
690 default: 689 default:
691 break; 690 break;
692 } 691 }
693 iomap.start = s->io[i].BasePort; 692 iomap.start = s->io[i].res->start;
694 iomap.stop = iomap.start + s->io[i].NumPorts - 1; 693 iomap.stop = s->io[i].res->end;
695 s->ops->set_io_map(s, &iomap); 694 s->ops->set_io_map(s, &iomap);
696 s->io[i].Config++; 695 s->io[i].Config++;
697 } 696 }