aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pcmcia
diff options
context:
space:
mode:
authorDominik Brodowski <linux@dominikbrodowski.net>2010-03-30 12:07:50 -0400
committerDominik Brodowski <linux@dominikbrodowski.net>2010-05-10 04:23:23 -0400
commit059f667d9f81082e94dead14ff3fa7b3b42c98a0 (patch)
treeabd97312659c44cd05dc8b1bf5bc0bb6fba832c2 /drivers/pcmcia
parenta60f22c4af3382b86301d64d6a9d68f30191d4c9 (diff)
pcmcia: call pcmcia_{read,write}_cis_mem with ops_mutex held
This avoids multiple lock takings in several codepaths. Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
Diffstat (limited to 'drivers/pcmcia')
-rw-r--r--drivers/pcmcia/cistpl.c21
-rw-r--r--drivers/pcmcia/pcmcia_ioctl.c4
-rw-r--r--drivers/pcmcia/pcmcia_resource.c13
3 files changed, 19 insertions, 19 deletions
diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c
index e0b09e71d5c0..60d428be0b07 100644
--- a/drivers/pcmcia/cistpl.c
+++ b/drivers/pcmcia/cistpl.c
@@ -129,6 +129,8 @@ static void __iomem *set_cis_map(struct pcmcia_socket *s,
129 129
130/** 130/**
131 * pcmcia_read_cis_mem() - low-level function to read CIS memory 131 * pcmcia_read_cis_mem() - low-level function to read CIS memory
132 *
133 * must be called with ops_mutex held
132 */ 134 */
133int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr, 135int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
134 u_int len, void *ptr) 136 u_int len, void *ptr)
@@ -138,7 +140,6 @@ int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
138 140
139 dev_dbg(&s->dev, "pcmcia_read_cis_mem(%d, %#x, %u)\n", attr, addr, len); 141 dev_dbg(&s->dev, "pcmcia_read_cis_mem(%d, %#x, %u)\n", attr, addr, len);
140 142
141 mutex_lock(&s->ops_mutex);
142 if (attr & IS_INDIRECT) { 143 if (attr & IS_INDIRECT) {
143 /* Indirect accesses use a bunch of special registers at fixed 144 /* Indirect accesses use a bunch of special registers at fixed
144 locations in common memory */ 145 locations in common memory */
@@ -153,7 +154,6 @@ int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
153 if (!sys) { 154 if (!sys) {
154 dev_dbg(&s->dev, "could not map memory\n"); 155 dev_dbg(&s->dev, "could not map memory\n");
155 memset(ptr, 0xff, len); 156 memset(ptr, 0xff, len);
156 mutex_unlock(&s->ops_mutex);
157 return -1; 157 return -1;
158 } 158 }
159 159
@@ -184,7 +184,6 @@ int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
184 if (!sys) { 184 if (!sys) {
185 dev_dbg(&s->dev, "could not map memory\n"); 185 dev_dbg(&s->dev, "could not map memory\n");
186 memset(ptr, 0xff, len); 186 memset(ptr, 0xff, len);
187 mutex_unlock(&s->ops_mutex);
188 return -1; 187 return -1;
189 } 188 }
190 end = sys + s->map_size; 189 end = sys + s->map_size;
@@ -198,7 +197,6 @@ int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
198 addr = 0; 197 addr = 0;
199 } 198 }
200 } 199 }
201 mutex_unlock(&s->ops_mutex);
202 dev_dbg(&s->dev, " %#2.2x %#2.2x %#2.2x %#2.2x ...\n", 200 dev_dbg(&s->dev, " %#2.2x %#2.2x %#2.2x %#2.2x ...\n",
203 *(u_char *)(ptr+0), *(u_char *)(ptr+1), 201 *(u_char *)(ptr+0), *(u_char *)(ptr+1),
204 *(u_char *)(ptr+2), *(u_char *)(ptr+3)); 202 *(u_char *)(ptr+2), *(u_char *)(ptr+3));
@@ -209,7 +207,8 @@ int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
209/** 207/**
210 * pcmcia_write_cis_mem() - low-level function to write CIS memory 208 * pcmcia_write_cis_mem() - low-level function to write CIS memory
211 * 209 *
212 * Probably only useful for writing one-byte registers. 210 * Probably only useful for writing one-byte registers. Must be called
211 * with ops_mutex held.
213 */ 212 */
214void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr, 213void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
215 u_int len, void *ptr) 214 u_int len, void *ptr)
@@ -220,7 +219,6 @@ void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
220 dev_dbg(&s->dev, 219 dev_dbg(&s->dev,
221 "pcmcia_write_cis_mem(%d, %#x, %u)\n", attr, addr, len); 220 "pcmcia_write_cis_mem(%d, %#x, %u)\n", attr, addr, len);
222 221
223 mutex_lock(&s->ops_mutex);
224 if (attr & IS_INDIRECT) { 222 if (attr & IS_INDIRECT) {
225 /* Indirect accesses use a bunch of special registers at fixed 223 /* Indirect accesses use a bunch of special registers at fixed
226 locations in common memory */ 224 locations in common memory */
@@ -234,7 +232,6 @@ void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
234 ((cis_width) ? MAP_16BIT : 0)); 232 ((cis_width) ? MAP_16BIT : 0));
235 if (!sys) { 233 if (!sys) {
236 dev_dbg(&s->dev, "could not map memory\n"); 234 dev_dbg(&s->dev, "could not map memory\n");
237 mutex_unlock(&s->ops_mutex);
238 return; /* FIXME: Error */ 235 return; /* FIXME: Error */
239 } 236 }
240 237
@@ -260,7 +257,6 @@ void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
260 sys = set_cis_map(s, card_offset, flags); 257 sys = set_cis_map(s, card_offset, flags);
261 if (!sys) { 258 if (!sys) {
262 dev_dbg(&s->dev, "could not map memory\n"); 259 dev_dbg(&s->dev, "could not map memory\n");
263 mutex_unlock(&s->ops_mutex);
264 return; /* FIXME: error */ 260 return; /* FIXME: error */
265 } 261 }
266 262
@@ -275,7 +271,6 @@ void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
275 addr = 0; 271 addr = 0;
276 } 272 }
277 } 273 }
278 mutex_unlock(&s->ops_mutex);
279} 274}
280 275
281 276
@@ -314,7 +309,6 @@ static int read_cis_cache(struct pcmcia_socket *s, int attr, u_int addr,
314 return 0; 309 return 0;
315 } 310 }
316 } 311 }
317 mutex_unlock(&s->ops_mutex);
318 312
319 ret = pcmcia_read_cis_mem(s, attr, addr, len, ptr); 313 ret = pcmcia_read_cis_mem(s, attr, addr, len, ptr);
320 314
@@ -326,11 +320,11 @@ static int read_cis_cache(struct pcmcia_socket *s, int attr, u_int addr,
326 cis->len = len; 320 cis->len = len;
327 cis->attr = attr; 321 cis->attr = attr;
328 memcpy(cis->cache, ptr, len); 322 memcpy(cis->cache, ptr, len);
329 mutex_lock(&s->ops_mutex);
330 list_add(&cis->node, &s->cis_cache); 323 list_add(&cis->node, &s->cis_cache);
331 mutex_unlock(&s->ops_mutex);
332 } 324 }
333 } 325 }
326 mutex_unlock(&s->ops_mutex);
327
334 return ret; 328 return ret;
335} 329}
336 330
@@ -386,6 +380,7 @@ int verify_cis_cache(struct pcmcia_socket *s)
386 "no memory for verifying CIS\n"); 380 "no memory for verifying CIS\n");
387 return -ENOMEM; 381 return -ENOMEM;
388 } 382 }
383 mutex_lock(&s->ops_mutex);
389 list_for_each_entry(cis, &s->cis_cache, node) { 384 list_for_each_entry(cis, &s->cis_cache, node) {
390 int len = cis->len; 385 int len = cis->len;
391 386
@@ -395,10 +390,12 @@ int verify_cis_cache(struct pcmcia_socket *s)
395 ret = pcmcia_read_cis_mem(s, cis->attr, cis->addr, len, buf); 390 ret = pcmcia_read_cis_mem(s, cis->attr, cis->addr, len, buf);
396 if (ret || memcmp(buf, cis->cache, len) != 0) { 391 if (ret || memcmp(buf, cis->cache, len) != 0) {
397 kfree(buf); 392 kfree(buf);
393 mutex_unlock(&s->ops_mutex);
398 return -1; 394 return -1;
399 } 395 }
400 } 396 }
401 kfree(buf); 397 kfree(buf);
398 mutex_unlock(&s->ops_mutex);
402 return 0; 399 return 0;
403} 400}
404 401
diff --git a/drivers/pcmcia/pcmcia_ioctl.c b/drivers/pcmcia/pcmcia_ioctl.c
index a42a6c7be10a..ef0c5f133691 100644
--- a/drivers/pcmcia/pcmcia_ioctl.c
+++ b/drivers/pcmcia/pcmcia_ioctl.c
@@ -301,7 +301,9 @@ static int pccard_get_status(struct pcmcia_socket *s,
301 (c->IntType & (INT_MEMORY_AND_IO | INT_ZOOMED_VIDEO))) { 301 (c->IntType & (INT_MEMORY_AND_IO | INT_ZOOMED_VIDEO))) {
302 u_char reg; 302 u_char reg;
303 if (c->CardValues & PRESENT_PIN_REPLACE) { 303 if (c->CardValues & PRESENT_PIN_REPLACE) {
304 mutex_lock(&s->ops_mutex);
304 pcmcia_read_cis_mem(s, 1, (c->ConfigBase+CISREG_PRR)>>1, 1, &reg); 305 pcmcia_read_cis_mem(s, 1, (c->ConfigBase+CISREG_PRR)>>1, 1, &reg);
306 mutex_unlock(&s->ops_mutex);
305 status->CardState |= 307 status->CardState |=
306 (reg & PRR_WP_STATUS) ? CS_EVENT_WRITE_PROTECT : 0; 308 (reg & PRR_WP_STATUS) ? CS_EVENT_WRITE_PROTECT : 0;
307 status->CardState |= 309 status->CardState |=
@@ -315,7 +317,9 @@ static int pccard_get_status(struct pcmcia_socket *s,
315 status->CardState |= CS_EVENT_READY_CHANGE; 317 status->CardState |= CS_EVENT_READY_CHANGE;
316 } 318 }
317 if (c->CardValues & PRESENT_EXT_STATUS) { 319 if (c->CardValues & PRESENT_EXT_STATUS) {
320 mutex_lock(&s->ops_mutex);
318 pcmcia_read_cis_mem(s, 1, (c->ConfigBase+CISREG_ESR)>>1, 1, &reg); 321 pcmcia_read_cis_mem(s, 1, (c->ConfigBase+CISREG_ESR)>>1, 1, &reg);
322 mutex_unlock(&s->ops_mutex);
319 status->CardState |= 323 status->CardState |=
320 (reg & ESR_REQ_ATTN) ? CS_EVENT_REQUEST_ATTENTION : 0; 324 (reg & ESR_REQ_ATTN) ? CS_EVENT_REQUEST_ATTENTION : 0;
321 } 325 }
diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c
index c6419c18a6c8..29f91fac1dff 100644
--- a/drivers/pcmcia/pcmcia_resource.c
+++ b/drivers/pcmcia/pcmcia_resource.c
@@ -123,6 +123,7 @@ int pcmcia_access_configuration_register(struct pcmcia_device *p_dev,
123 config_t *c; 123 config_t *c;
124 int addr; 124 int addr;
125 u_char val; 125 u_char val;
126 int ret = 0;
126 127
127 if (!p_dev || !p_dev->function_config) 128 if (!p_dev || !p_dev->function_config)
128 return -EINVAL; 129 return -EINVAL;
@@ -139,11 +140,10 @@ int pcmcia_access_configuration_register(struct pcmcia_device *p_dev,
139 } 140 }
140 141
141 addr = (c->ConfigBase + reg->Offset) >> 1; 142 addr = (c->ConfigBase + reg->Offset) >> 1;
142 mutex_unlock(&s->ops_mutex);
143 143
144 switch (reg->Action) { 144 switch (reg->Action) {
145 case CS_READ: 145 case CS_READ:
146 pcmcia_read_cis_mem(s, 1, addr, 1, &val); 146 ret = pcmcia_read_cis_mem(s, 1, addr, 1, &val);
147 reg->Value = val; 147 reg->Value = val;
148 break; 148 break;
149 case CS_WRITE: 149 case CS_WRITE:
@@ -152,10 +152,11 @@ int pcmcia_access_configuration_register(struct pcmcia_device *p_dev,
152 break; 152 break;
153 default: 153 default:
154 dev_dbg(&s->dev, "Invalid conf register request\n"); 154 dev_dbg(&s->dev, "Invalid conf register request\n");
155 return -EINVAL; 155 ret = -EINVAL;
156 break; 156 break;
157 } 157 }
158 return 0; 158 mutex_unlock(&s->ops_mutex);
159 return ret;
159} /* pcmcia_access_configuration_register */ 160} /* pcmcia_access_configuration_register */
160EXPORT_SYMBOL(pcmcia_access_configuration_register); 161EXPORT_SYMBOL(pcmcia_access_configuration_register);
161 162
@@ -436,7 +437,6 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev,
436 s->socket.io_irq = 0; 437 s->socket.io_irq = 0;
437 s->ops->set_socket(s, &s->socket); 438 s->ops->set_socket(s, &s->socket);
438 s->lock_count++; 439 s->lock_count++;
439 mutex_unlock(&s->ops_mutex);
440 440
441 /* Set up CIS configuration registers */ 441 /* Set up CIS configuration registers */
442 base = c->ConfigBase = req->ConfigBase; 442 base = c->ConfigBase = req->ConfigBase;
@@ -485,7 +485,6 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev,
485 485
486 /* Configure I/O windows */ 486 /* Configure I/O windows */
487 if (c->state & CONFIG_IO_REQ) { 487 if (c->state & CONFIG_IO_REQ) {
488 mutex_lock(&s->ops_mutex);
489 iomap.speed = io_speed; 488 iomap.speed = io_speed;
490 for (i = 0; i < MAX_IO_WIN; i++) 489 for (i = 0; i < MAX_IO_WIN; i++)
491 if (s->io[i].res) { 490 if (s->io[i].res) {
@@ -504,11 +503,11 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev,
504 s->ops->set_io_map(s, &iomap); 503 s->ops->set_io_map(s, &iomap);
505 s->io[i].Config++; 504 s->io[i].Config++;
506 } 505 }
507 mutex_unlock(&s->ops_mutex);
508 } 506 }
509 507
510 c->state |= CONFIG_LOCKED; 508 c->state |= CONFIG_LOCKED;
511 p_dev->_locked = 1; 509 p_dev->_locked = 1;
510 mutex_unlock(&s->ops_mutex);
512 return 0; 511 return 0;
513} /* pcmcia_request_configuration */ 512} /* pcmcia_request_configuration */
514EXPORT_SYMBOL(pcmcia_request_configuration); 513EXPORT_SYMBOL(pcmcia_request_configuration);