Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 206129
b: refs/heads/master
c: ad0c7be
h: refs/heads/master
i:
  206127: e732535
v: v3
  • Loading branch information
Dominik Brodowski committed Aug 3, 2010
1 parent 0f23c68 commit f48165f
Show file tree
Hide file tree
Showing 7 changed files with 61 additions and 35 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: 8f677ea07a2a934ac74ffa57db0f5617aec15ddf
refs/heads/master: ad0c7be28bc7593da43f494f6d074767ea96ca59
3 changes: 2 additions & 1 deletion trunk/drivers/pcmcia/cs_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ struct pccard_resource_ops {
unsigned int attr,
unsigned int *base,
unsigned int num,
unsigned int align);
unsigned int align,
struct resource **parent);
struct resource* (*find_mem) (unsigned long base, unsigned long num,
unsigned long align, int low,
struct pcmcia_socket *s);
Expand Down
4 changes: 2 additions & 2 deletions trunk/drivers/pcmcia/ds.c
Original file line number Diff line number Diff line change
Expand Up @@ -553,11 +553,11 @@ static struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s,
p_dev->function_config = c;
kref_init(&c->ref);
for (i = 0; i < MAX_IO_WIN; i++) {
c->io[i].name = dev_name(&p_dev->dev);
c->io[i].name = p_dev->devname;
c->io[i].flags = IORESOURCE_IO;
}
for (i = 0; i< MAX_WIN; i++) {
c->mem[i].name = dev_name(&p_dev->dev);
c->mem[i].name = p_dev->devname;
c->mem[i].flags = IORESOURCE_MEM;
}
}
Expand Down
74 changes: 46 additions & 28 deletions trunk/drivers/pcmcia/pcmcia_resource.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,33 @@ struct resource *pcmcia_find_mem_region(u_long base, u_long num, u_long align,
}


static void release_io_space(struct pcmcia_socket *s, struct resource *res)
{
resource_size_t num = resource_size(res);
int i;

dev_dbg(&s->dev, "release_io_space for %pR\n", res);

for (i = 0; i < MAX_IO_WIN; i++) {
if (!s->io[i].res)
continue;
if ((s->io[i].res->start <= res->start) &&
(s->io[i].res->end >= res->end)) {
s->io[i].InUse -= num;
if (res->parent)
release_resource(res);
res->start = res->end = 0;
res->flags = IORESOURCE_IO;
/* Free the window if no one else is using it */
if (s->io[i].InUse == 0) {
release_resource(s->io[i].res);
kfree(s->io[i].res);
s->io[i].res = NULL;
}
}
}
} /* release_io_space */

/** alloc_io_space
*
* Special stuff for managing IO windows, because they are scarce
Expand Down Expand Up @@ -87,43 +114,28 @@ static int alloc_io_space(struct pcmcia_socket *s, struct resource *res,
align = 0;
}

ret = s->resource_ops->find_io(s, res->flags, &base, num, align);
ret = s->resource_ops->find_io(s, res->flags, &base, num, align,
&res->parent);
if (ret) {
dev_dbg(&s->dev, "alloc_io_space request returned %d", ret);
dev_dbg(&s->dev, "alloc_io_space request failed (%d)\n", ret);
return -EINVAL;
}

res->start = base;
res->end = res->start + num - 1;
dev_dbg(&s->dev, "alloc_io_space request returned %pR, %d\n", res, ret);
return 0;
} /* alloc_io_space */


static void release_io_space(struct pcmcia_socket *s, struct resource *res)
{
resource_size_t num = resource_size(res);
int i;

dev_dbg(&s->dev, "release_io_space for %pR\n", res);

for (i = 0; i < MAX_IO_WIN; i++) {
if (!s->io[i].res)
continue;
if ((s->io[i].res->start <= res->start) &&
(s->io[i].res->end >= res->end)) {
s->io[i].InUse -= num;
res->start = res->end = 0;
res->flags = IORESOURCE_IO;
/* Free the window if no one else is using it */
if (s->io[i].InUse == 0) {
release_resource(s->io[i].res);
kfree(s->io[i].res);
s->io[i].res = NULL;
}
if (res->parent) {
ret = request_resource(res->parent, res);
if (ret) {
dev_warn(&s->dev,
"request_resource %pR failed: %d\n", res, ret);
res->parent = NULL;
release_io_space(s, res);
}
}
} /* release_io_space */
dev_dbg(&s->dev, "alloc_io_space request result %d: %pR\n", ret, res);
return ret;
} /* alloc_io_space */


/**
Expand Down Expand Up @@ -401,6 +413,7 @@ int pcmcia_release_window(struct pcmcia_device *p_dev, struct resource *res)

/* Release system memory */
if (win->res) {
release_resource(res);
release_resource(win->res);
kfree(win->res);
win->res = NULL;
Expand Down Expand Up @@ -853,6 +866,11 @@ int pcmcia_request_window(struct pcmcia_device *p_dev, win_req_t *req, window_ha
res->end = req->Base + req->Size - 1;
res->flags &= ~IORESOURCE_BITS;
res->flags |= (req->Attributes & WIN_FLAGS_MAP) | (win->map << 2);
res->flags |= IORESOURCE_MEM;
res->parent = win->res;
if (win->res)
request_resource(&iomem_resource, res);

dev_dbg(&s->dev, "request_window results in %pR\n", res);

mutex_unlock(&s->ops_mutex);
Expand Down
5 changes: 4 additions & 1 deletion trunk/drivers/pcmcia/rsrc_iodyn.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ static struct resource *__iodyn_find_io_region(struct pcmcia_socket *s,

static int iodyn_find_io(struct pcmcia_socket *s, unsigned int attr,
unsigned int *base, unsigned int num,
unsigned int align)
unsigned int align, struct resource **parent)
{
int i, ret = 0;

Expand Down Expand Up @@ -128,6 +128,7 @@ static int iodyn_find_io(struct pcmcia_socket *s, unsigned int attr,
((res->flags & ~IORESOURCE_BITS) |
(attr & IORESOURCE_BITS));
s->io[i].InUse = num;
*parent = res;
return 0;
}

Expand All @@ -139,6 +140,7 @@ static int iodyn_find_io(struct pcmcia_socket *s, unsigned int attr,
continue;
*base = try;
s->io[i].InUse += num;
*parent = res;
return 0;
}

Expand All @@ -151,6 +153,7 @@ static int iodyn_find_io(struct pcmcia_socket *s, unsigned int attr,
continue;
*base = try;
s->io[i].InUse += num;
*parent = res;
return 0;
}
}
Expand Down
3 changes: 2 additions & 1 deletion trunk/drivers/pcmcia/rsrc_mgr.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,12 @@ struct resource *pcmcia_make_resource(unsigned long start, unsigned long end,

static int static_find_io(struct pcmcia_socket *s, unsigned int attr,
unsigned int *base, unsigned int num,
unsigned int align)
unsigned int align, struct resource **parent)
{
if (!s->io_offset)
return -EINVAL;
*base = s->io_offset | (*base & 0x0fff);
*parent = NULL;

return 0;
}
Expand Down
5 changes: 4 additions & 1 deletion trunk/drivers/pcmcia/rsrc_nonstatic.c
Original file line number Diff line number Diff line change
Expand Up @@ -718,7 +718,7 @@ static struct resource *__nonstatic_find_io_region(struct pcmcia_socket *s,

static int nonstatic_find_io(struct pcmcia_socket *s, unsigned int attr,
unsigned int *base, unsigned int num,
unsigned int align)
unsigned int align, struct resource **parent)
{
int i, ret = 0;

Expand Down Expand Up @@ -760,6 +760,7 @@ static int nonstatic_find_io(struct pcmcia_socket *s, unsigned int attr,
((res->flags & ~IORESOURCE_BITS) |
(attr & IORESOURCE_BITS));
s->io[i].InUse = num;
*parent = res;
return 0;
}

Expand All @@ -775,6 +776,7 @@ static int nonstatic_find_io(struct pcmcia_socket *s, unsigned int attr,
continue;
*base = try;
s->io[i].InUse += num;
*parent = res;
return 0;
}
}
Expand All @@ -793,6 +795,7 @@ static int nonstatic_find_io(struct pcmcia_socket *s, unsigned int attr,
continue;
*base = try;
s->io[i].InUse += num;
*parent = res;
return 0;
}
}
Expand Down

0 comments on commit f48165f

Please sign in to comment.