Commit 9c405186 authored by Russell King's avatar Russell King

[PCMCIA] 04-memres

Make find_mem_region() return a struct resource.  We preserve
pccard_mem_map's sys_start and sys_stop elements for the moment
since socket drivers are relying on this information for setting
up their windows.
parent a99a281c
...@@ -85,13 +85,15 @@ INT_MODULE_PARM(cis_width, 0); /* 16-bit CIS? */ ...@@ -85,13 +85,15 @@ INT_MODULE_PARM(cis_width, 0); /* 16-bit CIS? */
void release_cis_mem(struct pcmcia_socket *s) void release_cis_mem(struct pcmcia_socket *s)
{ {
if (s->cis_mem.sys_start != 0) { if (s->cis_mem.flags & MAP_ACTIVE) {
s->cis_mem.flags &= ~MAP_ACTIVE; s->cis_mem.flags &= ~MAP_ACTIVE;
s->ops->set_mem_map(s, &s->cis_mem); s->ops->set_mem_map(s, &s->cis_mem);
if (!(s->features & SS_CAP_STATIC_MAP)) if (s->cis_mem.res) {
release_mem_region(s->cis_mem.sys_start, s->map_size); release_resource(s->cis_mem.res);
kfree(s->cis_mem.res);
s->cis_mem.res = NULL;
}
iounmap(s->cis_virt); iounmap(s->cis_virt);
s->cis_mem.sys_start = 0;
s->cis_virt = NULL; s->cis_virt = NULL;
} }
} }
...@@ -105,16 +107,16 @@ static unsigned char * ...@@ -105,16 +107,16 @@ static unsigned char *
set_cis_map(struct pcmcia_socket *s, unsigned int card_offset, unsigned int flags) set_cis_map(struct pcmcia_socket *s, unsigned int card_offset, unsigned int flags)
{ {
pccard_mem_map *mem = &s->cis_mem; pccard_mem_map *mem = &s->cis_mem;
if (!(s->features & SS_CAP_STATIC_MAP) && if (!(s->features & SS_CAP_STATIC_MAP) && mem->res == NULL) {
mem->sys_start == 0) { mem->res = find_mem_region(0, s->map_size, s->map_size, 0,
mem->sys_start = 0; "card services", s);
if (find_mem_region(&mem->sys_start, s->map_size, if (mem->res == NULL) {
s->map_size, 0, "card services", s)) {
printk(KERN_NOTICE "cs: unable to map card memory!\n"); printk(KERN_NOTICE "cs: unable to map card memory!\n");
return NULL; return NULL;
} }
mem->sys_stop = mem->sys_start+s->map_size-1; mem->sys_start = mem->res->start;
s->cis_virt = ioremap(mem->sys_start, s->map_size); mem->sys_stop = mem->res->end;
s->cis_virt = ioremap(mem->res->start, s->map_size);
} }
mem->card_start = card_offset; mem->card_start = card_offset;
mem->flags = flags; mem->flags = flags;
......
...@@ -1100,8 +1100,8 @@ int pcmcia_get_window(window_handle_t *handle, int idx, win_req_t *req) ...@@ -1100,8 +1100,8 @@ int pcmcia_get_window(window_handle_t *handle, int idx, win_req_t *req)
if (w == MAX_WIN) if (w == MAX_WIN)
return CS_NO_MORE_ITEMS; return CS_NO_MORE_ITEMS;
win = &s->win[w]; win = &s->win[w];
req->Base = win->ctl.sys_start; req->Base = win->ctl.res->start;
req->Size = win->ctl.sys_stop - win->ctl.sys_start + 1; req->Size = win->ctl.res->end - win->ctl.res->start + 1;
req->AccessSpeed = win->ctl.speed; req->AccessSpeed = win->ctl.speed;
req->Attributes = 0; req->Attributes = 0;
if (win->ctl.flags & MAP_ATTRIB) if (win->ctl.flags & MAP_ATTRIB)
...@@ -1548,8 +1548,11 @@ int pcmcia_release_window(window_handle_t win) ...@@ -1548,8 +1548,11 @@ int pcmcia_release_window(window_handle_t win)
s->state &= ~SOCKET_WIN_REQ(win->index); s->state &= ~SOCKET_WIN_REQ(win->index);
/* Release system memory */ /* Release system memory */
if(!(s->features & SS_CAP_STATIC_MAP)) if (win->ctl.res) {
release_mem_region(win->ctl.sys_start, win->ctl.sys_stop - win->ctl.sys_start + 1); release_resource(win->ctl.res);
kfree(win->ctl.res);
win->ctl.res = NULL;
}
win->handle->state &= ~CLIENT_WIN_REQ(win->index); win->handle->state &= ~CLIENT_WIN_REQ(win->index);
win->magic = 0; win->magic = 0;
...@@ -1871,14 +1874,19 @@ int pcmcia_request_window(client_handle_t *handle, win_req_t *req, window_handle ...@@ -1871,14 +1874,19 @@ int pcmcia_request_window(client_handle_t *handle, win_req_t *req, window_handle
win->index = w; win->index = w;
win->handle = *handle; win->handle = *handle;
win->sock = s; win->sock = s;
win->ctl.sys_start = req->Base;
if (!(s->features & SS_CAP_STATIC_MAP) && if (!(s->features & SS_CAP_STATIC_MAP)) {
find_mem_region(&win->ctl.sys_start, req->Size, align, win->ctl.res = find_mem_region(req->Base, req->Size, align,
(req->Attributes & WIN_MAP_BELOW_1MB), (req->Attributes & WIN_MAP_BELOW_1MB),
(*handle)->dev_info, s)) (*handle)->dev_info, s);
return CS_IN_USE; if (!win->ctl.res)
win->ctl.sys_stop = win->ctl.sys_start + req->Size - 1; return CS_IN_USE;
win->ctl.sys_start = win->ctl.res->start;
win->ctl.sys_stop = win->ctl.res->end;
} else {
win->ctl.sys_start = req->Base;
win->ctl.sys_stop = req->Base + req->Size - 1;
}
(*handle)->state |= CLIENT_WIN_REQ(w); (*handle)->state |= CLIENT_WIN_REQ(w);
/* Configure the socket controller */ /* Configure the socket controller */
......
...@@ -185,7 +185,7 @@ struct resource *find_io_region(unsigned long base, int num, unsigned long align ...@@ -185,7 +185,7 @@ struct resource *find_io_region(unsigned long base, int num, unsigned long align
char *name, struct pcmcia_socket *s); char *name, struct pcmcia_socket *s);
int adjust_io_region(struct resource *res, unsigned long r_start, int adjust_io_region(struct resource *res, unsigned long r_start,
unsigned long r_end, struct pcmcia_socket *s); unsigned long r_end, struct pcmcia_socket *s);
int find_mem_region(u_long *base, u_long num, u_long align, struct resource *find_mem_region(u_long base, u_long num, u_long align,
int low, char *name, struct pcmcia_socket *s); int low, char *name, struct pcmcia_socket *s);
int try_irq(u_int Attributes, int irq, int specific); int try_irq(u_int Attributes, int irq, int specific);
void undo_irq(u_int Attributes, int irq); void undo_irq(u_int Attributes, int irq);
......
...@@ -420,12 +420,12 @@ static void set_bridge_state(int sock) ...@@ -420,12 +420,12 @@ static void set_bridge_state(int sock)
static int i82092aa_init(struct pcmcia_socket *sock) static int i82092aa_init(struct pcmcia_socket *sock)
{ {
int i; int i;
struct resource res = { .start = 0, .end = 0x0fff };
pccard_io_map io = { 0, 0, 0, 0, 1 }; pccard_io_map io = { 0, 0, 0, 0, 1 };
pccard_mem_map mem = { 0, 0, 0, 0, 0, 0 }; pccard_mem_map mem = { .res = &res, .sys_stop = 0x0fff, };
enter("i82092aa_init"); enter("i82092aa_init");
mem.sys_stop = 0x0fff;
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
io.map = i; io.map = i;
i82092aa_set_io_map(sock, &io); i82092aa_set_io_map(sock, &io);
......
...@@ -1308,10 +1308,10 @@ static int pcic_set_mem_map(struct pcmcia_socket *s, struct pccard_mem_map *mem) ...@@ -1308,10 +1308,10 @@ static int pcic_set_mem_map(struct pcmcia_socket *s, struct pccard_mem_map *mem)
static int pcic_init(struct pcmcia_socket *s) static int pcic_init(struct pcmcia_socket *s)
{ {
int i; int i;
struct resource res = { .start = 0, .end = 0x1000 };
pccard_io_map io = { 0, 0, 0, 0, 1 }; pccard_io_map io = { 0, 0, 0, 0, 1 };
pccard_mem_map mem = { 0, 0, 0, 0, 0, 0 }; pccard_mem_map mem = { .res = &res, .sys_stop = 0x1000, };
mem.sys_stop = 0x1000;
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
io.map = i; io.map = i;
pcic_set_io_map(s, &io); pcic_set_io_map(s, &io);
......
...@@ -563,10 +563,10 @@ static int pd6729_suspend(struct pcmcia_socket *sock) ...@@ -563,10 +563,10 @@ static int pd6729_suspend(struct pcmcia_socket *sock)
static int pd6729_init(struct pcmcia_socket *sock) static int pd6729_init(struct pcmcia_socket *sock)
{ {
int i; int i;
struct resource res = { .end = 0x0fff };
pccard_io_map io = { 0, 0, 0, 0, 1 }; pccard_io_map io = { 0, 0, 0, 0, 1 };
pccard_mem_map mem = { 0, 0, 0, 0, 0, 0 }; pccard_mem_map mem = { .res = &res, .sys_stop = 0x0fff };
mem.sys_stop = 0x0fff;
pd6729_set_socket(sock, &dead_socket); pd6729_set_socket(sock, &dead_socket);
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
io.map = i; io.map = i;
......
...@@ -303,6 +303,7 @@ static int readable(struct pcmcia_socket *s, struct resource *res, cisinfo_t *in ...@@ -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_start = res->start;
s->cis_mem.sys_stop = res->end; s->cis_mem.sys_stop = res->end;
s->cis_mem.res = res;
s->cis_virt = ioremap(res->start, s->map_size); s->cis_virt = ioremap(res->start, s->map_size);
if (s->cis_virt) { if (s->cis_virt) {
ret = pcmcia_validate_cis(s->clients, info); ret = pcmcia_validate_cis(s->clients, info);
...@@ -313,6 +314,7 @@ static int readable(struct pcmcia_socket *s, struct resource *res, cisinfo_t *in ...@@ -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_start = 0;
s->cis_mem.sys_stop = 0; s->cis_mem.sys_stop = 0;
s->cis_mem.res = NULL;
if ((ret != 0) || (info->Chains == 0)) if ((ret != 0) || (info->Chains == 0))
return 0; return 0;
return 1; return 1;
...@@ -332,6 +334,7 @@ static int checksum(struct pcmcia_socket *s, struct resource *res) ...@@ -332,6 +334,7 @@ static int checksum(struct pcmcia_socket *s, struct resource *res)
map.speed = 0; map.speed = 0;
map.sys_start = res->start; map.sys_start = res->start;
map.sys_stop = res->end; map.sys_stop = res->end;
map.res = res;
map.card_start = 0; map.card_start = 0;
s->ops->set_mem_map(s, &map); s->ops->set_mem_map(s, &map);
...@@ -661,8 +664,8 @@ struct resource *find_io_region(unsigned long base, int num, ...@@ -661,8 +664,8 @@ struct resource *find_io_region(unsigned long base, int num,
return res; return res;
} }
int find_mem_region(u_long *base, u_long num, u_long align, struct resource *find_mem_region(u_long base, u_long num, u_long align,
int low, char *name, struct pcmcia_socket *s) 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, name);
struct pcmcia_align_data data; struct pcmcia_align_data data;
...@@ -672,16 +675,16 @@ int find_mem_region(u_long *base, u_long num, u_long align, ...@@ -672,16 +675,16 @@ int find_mem_region(u_long *base, u_long num, u_long align,
low = low || !(s->features & SS_CAP_PAGE_REGS); low = low || !(s->features & SS_CAP_PAGE_REGS);
data.mask = align - 1; data.mask = align - 1;
data.offset = *base & data.mask; data.offset = base & data.mask;
data.map = &mem_db; data.map = &mem_db;
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
if (low) { if (low) {
max = 0x100000UL; max = 0x100000UL;
min = *base < max ? *base : 0; min = base < max ? base : 0;
} else { } else {
max = ~0UL; max = ~0UL;
min = 0x100000UL + *base; min = 0x100000UL + base;
} }
down(&rsrc_sem); down(&rsrc_sem);
...@@ -702,10 +705,9 @@ int find_mem_region(u_long *base, u_long num, u_long align, ...@@ -702,10 +705,9 @@ int find_mem_region(u_long *base, u_long num, u_long align,
if (ret != 0) { if (ret != 0) {
kfree(res); kfree(res);
} else { res = NULL;
*base = res->start;
} }
return ret; return res;
} }
/*====================================================================== /*======================================================================
......
...@@ -868,10 +868,10 @@ static int tcic_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *m ...@@ -868,10 +868,10 @@ static int tcic_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *m
static int tcic_init(struct pcmcia_socket *s) static int tcic_init(struct pcmcia_socket *s)
{ {
int i; int i;
struct resource res = { .start = 0, .end = 0x1000 };
pccard_io_map io = { 0, 0, 0, 0, 1 }; pccard_io_map io = { 0, 0, 0, 0, 1 };
pccard_mem_map mem = { 0, 0, 0, 0, 0, 0 }; pccard_mem_map mem = { .res = &res, .sys_stop = 0x1000, };
mem.sys_stop = 0x1000;
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
io.map = i; io.map = i;
tcic_set_io_map(s, &io); tcic_set_io_map(s, &io);
......
...@@ -445,10 +445,10 @@ static void yenta_interrupt_wrapper(unsigned long data) ...@@ -445,10 +445,10 @@ static void yenta_interrupt_wrapper(unsigned long data)
static void yenta_clear_maps(struct yenta_socket *socket) static void yenta_clear_maps(struct yenta_socket *socket)
{ {
int i; int i;
struct resource res = { .start = 0, .end = 0x0fff };
pccard_io_map io = { 0, 0, 0, 0, 1 }; pccard_io_map io = { 0, 0, 0, 0, 1 };
pccard_mem_map mem = { 0, 0, 0, 0, 0, 0 }; pccard_mem_map mem = { .res = &res, .sys_stop = 0x0fff, };
mem.sys_stop = 0x0fff;
yenta_set_socket(&socket->socket, &dead_socket); yenta_set_socket(&socket->socket, &dead_socket);
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
io.map = i; io.map = i;
......
...@@ -105,6 +105,7 @@ typedef struct pccard_mem_map { ...@@ -105,6 +105,7 @@ typedef struct pccard_mem_map {
u_short speed; u_short speed;
u_long sys_start, sys_stop; u_long sys_start, sys_stop;
u_int card_start; u_int card_start;
struct resource *res;
} pccard_mem_map; } pccard_mem_map;
typedef struct cb_bridge_map { typedef struct cb_bridge_map {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment