X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fpcmcia%2Frsrc_mgr.c;h=6869e209dfbfa197fd5aafbf24cc4e0cc90489db;hb=9bf4aaab3e101692164d49b7ca357651eb691cb6;hp=2e606be988be3ca99ab05551509b6c1c6c17008f;hpb=db216c3d5e4c040e557a50f8f5d35d5c415e8c1c;p=linux-2.6.git diff --git a/drivers/pcmcia/rsrc_mgr.c b/drivers/pcmcia/rsrc_mgr.c index 2e606be98..6869e209d 100644 --- a/drivers/pcmcia/rsrc_mgr.c +++ b/drivers/pcmcia/rsrc_mgr.c @@ -118,7 +118,7 @@ make_resource(unsigned long b, unsigned long n, int flags, char *name) res->name = name; res->start = b; res->end = b + n - 1; - res->flags = flags | IORESOURCE_BUSY; + res->flags = flags; } return res; } @@ -303,6 +303,7 @@ static int readable(struct pcmcia_socket *s, struct resource *res, cisinfo_t *in s->cis_mem.sys_start = res->start; s->cis_mem.sys_stop = res->end; + s->cis_mem.res = res; s->cis_virt = ioremap(res->start, s->map_size); if (s->cis_virt) { ret = pcmcia_validate_cis(s->clients, info); @@ -313,6 +314,7 @@ static int readable(struct pcmcia_socket *s, struct resource *res, cisinfo_t *in } s->cis_mem.sys_start = 0; s->cis_mem.sys_stop = 0; + s->cis_mem.res = NULL; if ((ret != 0) || (info->Chains == 0)) return 0; return 1; @@ -332,6 +334,7 @@ static int checksum(struct pcmcia_socket *s, struct resource *res) map.speed = 0; map.sys_start = res->start; map.sys_stop = res->end; + map.res = res; map.card_start = 0; s->ops->set_mem_map(s, &map); @@ -454,7 +457,7 @@ static u_long inv_probe(resource_map_t *m, struct pcmcia_socket *s) return do_mem_probe(m->base, m->num, s); } -void validate_mem(struct pcmcia_socket *s) +static void validate_mem(struct pcmcia_socket *s) { resource_map_t *m, mm; static u_char order[] = { 0xd0, 0xe0, 0xc0, 0xf0 }; @@ -462,9 +465,6 @@ void validate_mem(struct pcmcia_socket *s) u_long b, i, ok = 0; int force_low = !(s->features & SS_CAP_PAGE_REGS); - if (!probe_mem) - return; - down(&rsrc_sem); /* We do up to four passes through the list */ if (!force_low) { @@ -500,12 +500,12 @@ void validate_mem(struct pcmcia_socket *s) #else /* CONFIG_PCMCIA_PROBE */ -void validate_mem(struct pcmcia_socket *s) +static void validate_mem(struct pcmcia_socket *s) { resource_map_t *m, mm; static int done = 0; - if (probe_mem && done++ == 0) { + if (done++ == 0) { down(&rsrc_sem); for (m = mem_db.next; m != &mem_db; m = mm.next) { mm = *m; @@ -518,6 +518,18 @@ void validate_mem(struct pcmcia_socket *s) #endif /* CONFIG_PCMCIA_PROBE */ +void pcmcia_validate_mem(struct pcmcia_socket *s) +{ + down(&s->skt_sem); + + if (probe_mem && s->state & SOCKET_PRESENT) + validate_mem(s); + + up(&s->skt_sem); +} + +EXPORT_SYMBOL(pcmcia_validate_mem); + struct pcmcia_align_data { unsigned long mask; unsigned long offset; @@ -622,7 +634,7 @@ int adjust_io_region(struct resource *res, unsigned long r_start, struct resource *find_io_region(unsigned long base, int num, unsigned long align, char *name, struct pcmcia_socket *s) { - struct resource *res = make_resource(0, num, IORESOURCE_IO, name); + struct resource *res = make_resource(0, num, IORESOURCE_IO, s->dev.class_id); struct pcmcia_align_data data; unsigned long min = base; int ret; @@ -641,8 +653,8 @@ struct resource *find_io_region(unsigned long base, int num, min, 0, pcmcia_align, &data); } else #endif - ret = allocate_resource(&ioport_resource, res, num, min, ~0UL, 0, - pcmcia_align, &data); + ret = allocate_resource(&ioport_resource, res, num, min, ~0UL, + 1, pcmcia_align, &data); up(&rsrc_sem); if (ret != 0) { @@ -652,10 +664,10 @@ struct resource *find_io_region(unsigned long base, int num, return res; } -int find_mem_region(u_long *base, u_long num, u_long align, - int low, char *name, struct pcmcia_socket *s) +struct resource *find_mem_region(u_long base, u_long num, u_long align, + int low, char *name, struct pcmcia_socket *s) { - struct resource *res = make_resource(0, num, IORESOURCE_MEM, name); + struct resource *res = make_resource(0, num, IORESOURCE_MEM, s->dev.class_id); struct pcmcia_align_data data; unsigned long min, max; int ret, i; @@ -663,16 +675,16 @@ int find_mem_region(u_long *base, u_long num, u_long align, low = low || !(s->features & SS_CAP_PAGE_REGS); data.mask = align - 1; - data.offset = *base & data.mask; + data.offset = base & data.mask; data.map = &mem_db; for (i = 0; i < 2; i++) { if (low) { max = 0x100000UL; - min = *base < max ? *base : 0; + min = base < max ? base : 0; } else { max = ~0UL; - min = 0x100000UL + *base; + min = 0x100000UL + base; } down(&rsrc_sem); @@ -684,7 +696,7 @@ int find_mem_region(u_long *base, u_long num, u_long align, } else #endif ret = allocate_resource(&iomem_resource, res, num, min, - max, 0, pcmcia_align, &data); + max, 1, pcmcia_align, &data); up(&rsrc_sem); if (ret == 0 || low) break; @@ -693,10 +705,9 @@ int find_mem_region(u_long *base, u_long num, u_long align, if (ret != 0) { kfree(res); - } else { - *base = res->start; + res = NULL; } - return ret; + return res; } /*======================================================================