Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 181966
b: refs/heads/master
c: 904e377
h: refs/heads/master
v: v3
  • Loading branch information
Dominik Brodowski committed Jan 17, 2010
1 parent d369c53 commit 34a5ce9
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 11 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: fa0b3bc504ff813cc05988bb30bbb6c6a0263eb4
refs/heads/master: 904e377744bfdcea276c27167fa6a609929f39dc
24 changes: 16 additions & 8 deletions trunk/drivers/pcmcia/cistpl.c
Original file line number Diff line number Diff line change
Expand Up @@ -319,22 +319,23 @@ remove_cis_cache(struct pcmcia_socket *s, int attr, u_int addr, u_int len)
}
}

/**
* destroy_cis_cache() - destroy the CIS cache
* @s: pcmcia_socket for which CIS cache shall be destroyed
*
* This destroys the CIS cache but keeps any fake CIS alive.
*/

void destroy_cis_cache(struct pcmcia_socket *s)
{
struct list_head *l, *n;
struct cis_cache_entry *cis;

list_for_each_safe(l, n, &s->cis_cache) {
struct cis_cache_entry *cis = list_entry(l, struct cis_cache_entry, node);

cis = list_entry(l, struct cis_cache_entry, node);
list_del(&cis->node);
kfree(cis);
}

/*
* If there was a fake CIS, destroy that as well.
*/
kfree(s->fake_cis);
s->fake_cis = NULL;
}
EXPORT_SYMBOL(destroy_cis_cache);

Expand Down Expand Up @@ -1596,6 +1597,9 @@ int pccard_validate_cis(struct pcmcia_socket *s, unsigned int *info)
if (!s)
return -EINVAL;

/* We do not want to validate the CIS cache... */
destroy_cis_cache(s);

tuple = kmalloc(sizeof(*tuple), GFP_KERNEL);
if (tuple == NULL) {
dev_printk(KERN_WARNING, &s->dev, "no memory to validate CIS\n");
Expand Down Expand Up @@ -1647,6 +1651,10 @@ int pccard_validate_cis(struct pcmcia_socket *s, unsigned int *info)
count = 0;

done:
/* invalidate CIS cache on failure */
if (!dev_ok || !ident_ok || !count)
destroy_cis_cache(s);

if (info)
*info = count;
kfree(tuple);
Expand Down
4 changes: 4 additions & 0 deletions trunk/drivers/pcmcia/cs.c
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,8 @@ static void socket_shutdown(struct pcmcia_socket *s)
s->irq.AssignedIRQ = s->irq.Config = 0;
s->lock_count = 0;
destroy_cis_cache(s);
kfree(s->fake_cis);
s->fake_cis = NULL;
#ifdef CONFIG_CARDBUS
cb_free(s);
#endif
Expand Down Expand Up @@ -577,6 +579,8 @@ static int socket_late_resume(struct pcmcia_socket *skt)
dev_dbg(&skt->dev, "cis mismatch - different card\n");
socket_remove_drivers(skt);
destroy_cis_cache(skt);
kfree(skt->fake_cis);
skt->fake_cis = NULL;
/*
* Workaround: give DS time to schedule removal.
* Remove me once the 100ms delay is eliminated
Expand Down
3 changes: 1 addition & 2 deletions trunk/drivers/pcmcia/rsrc_nonstatic.c
Original file line number Diff line number Diff line change
Expand Up @@ -281,10 +281,9 @@ static int readable(struct pcmcia_socket *s, struct resource *res,
s->cis_virt = ioremap(res->start, s->map_size);
if (s->cis_virt) {
ret = pccard_validate_cis(s, count);
/* invalidate mapping and CIS cache */
/* invalidate mapping */
iounmap(s->cis_virt);
s->cis_virt = NULL;
destroy_cis_cache(s);
}
s->cis_mem.res = NULL;
if ((ret != 0) || (*count == 0))
Expand Down

0 comments on commit 34a5ce9

Please sign in to comment.