Skip to content

Commit

Permalink
pcmcia: do not use win_req_t when calling pcmcia_request_window()
Browse files Browse the repository at this point in the history
Instead of win_req_t, drivers are now requested to fill out
struct pcmcia_device *p_dev->resource[2,3,4,5] for up to four iomem
ranges. After a call to pcmcia_request_window(), the windows found there
are reserved and may be used until pcmcia_release_window() is called.

CC: [email protected]
CC: [email protected]
CC: [email protected]
CC: Jiri Kosina <[email protected]>
CC: [email protected]
Tested-by: Wolfram Sang <[email protected]>
Signed-off-by: Dominik Brodowski <[email protected]>
  • Loading branch information
Dominik Brodowski committed Sep 29, 2010
1 parent 899611e commit cdb1380
Show file tree
Hide file tree
Showing 16 changed files with 241 additions and 277 deletions.
7 changes: 7 additions & 0 deletions Documentation/pcmcia/driver-changes.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
This file details changes in 2.6 which affect PCMCIA card driver authors:
* pcmcia_request_window changes (as of 2.6.36)
Instead of win_req_t, drivers are now requested to fill out
struct pcmcia_device *p_dev->resource[2,3,4,5] for up to four ioport
ranges. After a call to pcmcia_request_window(), the regions found there
are reserved and may be used immediately -- until pcmcia_release_window()
is called.

* pcmcia_request_io changes (as of 2.6.36)
Instead of io_req_t, drivers are now requested to fill out
struct pcmcia_device *p_dev->resource[0,1] for up to two ioport
Expand Down
87 changes: 37 additions & 50 deletions drivers/char/pcmcia/ipwireless/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,62 +105,54 @@ static int ipwireless_probe(struct pcmcia_device *p_dev,
if (cfg->mem.nwin == 0)
return 0;

ipw->request_common_memory.Attributes =
p_dev->resource[2]->flags |=
WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM | WIN_ENABLE;
ipw->request_common_memory.Base = cfg->mem.win[0].host_addr;
ipw->request_common_memory.Size = cfg->mem.win[0].len;
if (ipw->request_common_memory.Size < 0x1000)
ipw->request_common_memory.Size = 0x1000;
ipw->request_common_memory.AccessSpeed = 0;

ret = pcmcia_request_window(p_dev, &ipw->request_common_memory,
&ipw->handle_common_memory);
p_dev->resource[2]->start = cfg->mem.win[0].host_addr;
p_dev->resource[2]->end = cfg->mem.win[0].len;
if (p_dev->resource[2]->end < 0x1000)
p_dev->resource[2]->end = 0x1000;

ret = pcmcia_request_window(p_dev, p_dev->resource[2], 0);
if (ret != 0)
goto exit1;

ret = pcmcia_map_mem_page(p_dev, ipw->handle_common_memory,
ret = pcmcia_map_mem_page(p_dev, p_dev->resource[2],
cfg->mem.win[0].card_addr);

if (ret != 0)
goto exit2;

ipw->is_v2_card = cfg->mem.win[0].len == 0x100;

ipw->common_memory = ioremap(ipw->request_common_memory.Base,
ipw->request_common_memory.Size);
request_mem_region(ipw->request_common_memory.Base,
ipw->request_common_memory.Size,
ipw->attr_memory = ioremap(p_dev->resource[2]->start,
resource_size(p_dev->resource[2]));
request_mem_region(p_dev->resource[2]->start,
resource_size(p_dev->resource[2]),
IPWIRELESS_PCCARD_NAME);

ipw->request_attr_memory.Attributes =
WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_AM | WIN_ENABLE;
ipw->request_attr_memory.Base = 0;
ipw->request_attr_memory.Size = 0; /* this used to be 0x1000 */
ipw->request_attr_memory.AccessSpeed = 0;

ret = pcmcia_request_window(p_dev, &ipw->request_attr_memory,
&ipw->handle_attr_memory);

p_dev->resource[3]->flags |= WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_AM |
WIN_ENABLE;
p_dev->resource[3]->end = 0; /* this used to be 0x1000 */
ret = pcmcia_request_window(p_dev, p_dev->resource[3], 0);
if (ret != 0)
goto exit2;

ret = pcmcia_map_mem_page(p_dev, ipw->handle_attr_memory, 0);
ret = pcmcia_map_mem_page(p_dev, p_dev->resource[3], 0);
if (ret != 0)
goto exit3;

ipw->attr_memory = ioremap(ipw->request_attr_memory.Base,
ipw->request_attr_memory.Size);
request_mem_region(ipw->request_attr_memory.Base,
ipw->request_attr_memory.Size, IPWIRELESS_PCCARD_NAME);
ipw->attr_memory = ioremap(p_dev->resource[3]->start,
resource_size(p_dev->resource[3]));
request_mem_region(p_dev->resource[3]->start,
resource_size(p_dev->resource[3]),
IPWIRELESS_PCCARD_NAME);

return 0;

exit3:
exit2:
if (ipw->common_memory) {
release_mem_region(ipw->request_common_memory.Base,
ipw->request_common_memory.Size);
release_mem_region(p_dev->resource[2]->start,
resource_size(p_dev->resource[2]));
iounmap(ipw->common_memory);
}
exit1:
Expand Down Expand Up @@ -201,13 +193,9 @@ static int config_ipwireless(struct ipw_dev *ipw)
(unsigned int) link->irq);
if (ipw->attr_memory && ipw->common_memory)
printk(KERN_INFO IPWIRELESS_PCCARD_NAME
": attr memory 0x%08lx-0x%08lx, common memory 0x%08lx-0x%08lx\n",
ipw->request_attr_memory.Base,
ipw->request_attr_memory.Base
+ ipw->request_attr_memory.Size - 1,
ipw->request_common_memory.Base,
ipw->request_common_memory.Base
+ ipw->request_common_memory.Size - 1);
": attr memory %pR, common memory %pR\n",
link->resource[3],
link->resource[2]);

ipw->network = ipwireless_network_create(ipw->hardware);
if (!ipw->network)
Expand All @@ -231,31 +219,30 @@ static int config_ipwireless(struct ipw_dev *ipw)
return 0;

exit:
if (ipw->attr_memory) {
release_mem_region(ipw->request_attr_memory.Base,
ipw->request_attr_memory.Size);
iounmap(ipw->attr_memory);

}
if (ipw->common_memory) {
release_mem_region(ipw->request_common_memory.Base,
ipw->request_common_memory.Size);
release_mem_region(link->resource[2]->start,
resource_size(link->resource[2]));
iounmap(ipw->common_memory);
}
if (ipw->attr_memory) {
release_mem_region(link->resource[3]->start,
resource_size(link->resource[3]));
iounmap(ipw->attr_memory);
}
pcmcia_disable_device(link);
return -1;
}

static void release_ipwireless(struct ipw_dev *ipw)
{
if (ipw->common_memory) {
release_mem_region(ipw->request_common_memory.Base,
ipw->request_common_memory.Size);
release_mem_region(ipw->link->resource[2]->start,
resource_size(ipw->link->resource[2]));
iounmap(ipw->common_memory);
}
if (ipw->attr_memory) {
release_mem_region(ipw->request_attr_memory.Base,
ipw->request_attr_memory.Size);
release_mem_region(ipw->link->resource[3]->start,
resource_size(ipw->link->resource[3]));
iounmap(ipw->attr_memory);
}
pcmcia_disable_device(ipw->link);
Expand Down
4 changes: 0 additions & 4 deletions drivers/char/pcmcia/ipwireless/main.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,9 @@ struct ipw_dev {
struct pcmcia_device *link;
int is_v2_card;

window_handle_t handle_attr_memory;
void __iomem *attr_memory;
win_req_t request_attr_memory;

window_handle_t handle_common_memory;
void __iomem *common_memory;
win_req_t request_common_memory;

/* Reference to attribute memory, containing CIS data */
void *attribute_memory;
Expand Down
53 changes: 29 additions & 24 deletions drivers/mtd/maps/pcmciamtd.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ MODULE_PARM_DESC(mem_type, "Set Memory type (0=Flash, 1=RAM, 2=ROM, default=0)")
static caddr_t remap_window(struct map_info *map, unsigned long to)
{
struct pcmciamtd_dev *dev = (struct pcmciamtd_dev *)map->map_priv_1;
window_handle_t win = (window_handle_t)map->map_priv_2;
struct resource *win = (struct resource *) map->map_priv_2;
unsigned int offset;
int ret;

Expand Down Expand Up @@ -339,7 +339,7 @@ static void pcmciamtd_release(struct pcmcia_device *link)

DEBUG(3, "link = 0x%p", link);

if (link->win) {
if (link->resource[2]->end) {
if(dev->win_base) {
iounmap(dev->win_base);
dev->win_base = NULL;
Expand Down Expand Up @@ -491,9 +491,8 @@ static int pcmciamtd_config(struct pcmcia_device *link)
{
struct pcmciamtd_dev *dev = link->priv;
struct mtd_info *mtd = NULL;
win_req_t req;
int ret;
int i;
int i, j = 0;
static char *probes[] = { "jedec_probe", "cfi_probe" };
int new_name = 0;

Expand All @@ -520,28 +519,34 @@ static int pcmciamtd_config(struct pcmcia_device *link)
* smaller windows until we succeed
*/

req.Attributes = WIN_MEMORY_TYPE_CM | WIN_ENABLE;
req.Attributes |= (dev->pcmcia_map.bankwidth == 1) ? WIN_DATA_WIDTH_8 : WIN_DATA_WIDTH_16;
req.Base = 0;
req.AccessSpeed = mem_speed;
link->win = (window_handle_t)link;
req.Size = (force_size) ? force_size << 20 : MAX_PCMCIA_ADDR;
link->resource[2]->flags |= WIN_MEMORY_TYPE_CM | WIN_ENABLE;
link->resource[2]->flags |= (dev->pcmcia_map.bankwidth == 1) ?
WIN_DATA_WIDTH_8 : WIN_DATA_WIDTH_16;
link->resource[2]->start = 0;
link->resource[2]->end = (force_size) ? force_size << 20 :
MAX_PCMCIA_ADDR;
dev->win_size = 0;

do {
int ret;
DEBUG(2, "requesting window with size = %dKiB memspeed = %d",
req.Size >> 10, req.AccessSpeed);
ret = pcmcia_request_window(link, &req, &link->win);
DEBUG(2, "requesting window with size = %luKiB memspeed = %d",
(unsigned long) resource_size(link->resource[2]) >> 10,
mem_speed);
ret = pcmcia_request_window(link, link->resource[2], mem_speed);
DEBUG(2, "ret = %d dev->win_size = %d", ret, dev->win_size);
if(ret) {
req.Size >>= 1;
j++;
link->resource[2]->start = 0;
link->resource[2]->end = (force_size) ?
force_size << 20 : MAX_PCMCIA_ADDR;
link->resource[2]->end >>= j;
} else {
DEBUG(2, "Got window of size %dKiB", req.Size >> 10);
dev->win_size = req.Size;
DEBUG(2, "Got window of size %luKiB", (unsigned long)
resource_size(link->resource[2]) >> 10);
dev->win_size = resource_size(link->resource[2]);
break;
}
} while(req.Size >= 0x1000);
} while (link->resource[2]->end >= 0x1000);

DEBUG(2, "dev->win_size = %d", dev->win_size);

Expand All @@ -553,20 +558,20 @@ static int pcmciamtd_config(struct pcmcia_device *link)
DEBUG(1, "Allocated a window of %dKiB", dev->win_size >> 10);

/* Get write protect status */
DEBUG(2, "window handle = 0x%8.8lx", (unsigned long)link->win);
dev->win_base = ioremap(req.Base, req.Size);
dev->win_base = ioremap(link->resource[2]->start,
resource_size(link->resource[2]));
if(!dev->win_base) {
dev_err(&dev->p_dev->dev, "ioremap(%lu, %u) failed\n",
req.Base, req.Size);
dev_err(&dev->p_dev->dev, "ioremap(%pR) failed\n",
link->resource[2]);
pcmciamtd_release(link);
return -ENODEV;
}
DEBUG(1, "mapped window dev = %p req.base = 0x%lx base = %p size = 0x%x",
dev, req.Base, dev->win_base, req.Size);
DEBUG(1, "mapped window dev = %p @ %pR, base = %p",
dev, link->resource[2], dev->win_base);

dev->offset = 0;
dev->pcmcia_map.map_priv_1 = (unsigned long)dev;
dev->pcmcia_map.map_priv_2 = (unsigned long)link->win;
dev->pcmcia_map.map_priv_2 = (unsigned long)link->resource[2];

dev->vpp = (vpp) ? vpp : link->socket->socket.Vpp;
link->conf.Attributes = 0;
Expand Down
29 changes: 12 additions & 17 deletions drivers/net/pcmcia/fmvj18x_cs.c
Original file line number Diff line number Diff line change
Expand Up @@ -544,20 +544,18 @@ static int fmvj18x_config(struct pcmcia_device *link)

static int fmvj18x_get_hwinfo(struct pcmcia_device *link, u_char *node_id)
{
win_req_t req;
u_char __iomem *base;
int i, j;

/* Allocate a small memory window */
req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
req.Base = 0; req.Size = 0;
req.AccessSpeed = 0;
i = pcmcia_request_window(link, &req, &link->win);
link->resource[2]->flags |= WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
link->resource[2]->start = 0; link->resource[2]->end = 0;
i = pcmcia_request_window(link, link->resource[2], 0);
if (i != 0)
return -1;

base = ioremap(req.Base, req.Size);
pcmcia_map_mem_page(link, link->win, 0);
base = ioremap(link->resource[2]->start, resource_size(link->resource[2]));
pcmcia_map_mem_page(link, link->resource[2], 0);

/*
* MBH10304 CISTPL_FUNCE_LAN_NODE_ID format
Expand All @@ -582,35 +580,34 @@ static int fmvj18x_get_hwinfo(struct pcmcia_device *link, u_char *node_id)
}

iounmap(base);
j = pcmcia_release_window(link, link->win);
j = pcmcia_release_window(link, link->resource[2]);
return (i != 0x200) ? 0 : -1;

} /* fmvj18x_get_hwinfo */
/*====================================================================*/

static int fmvj18x_setup_mfc(struct pcmcia_device *link)
{
win_req_t req;
int i;
struct net_device *dev = link->priv;
unsigned int ioaddr;
local_info_t *lp = netdev_priv(dev);

/* Allocate a small memory window */
req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
req.Base = 0; req.Size = 0;
req.AccessSpeed = 0;
i = pcmcia_request_window(link, &req, &link->win);
link->resource[3]->flags = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
link->resource[3]->start = link->resource[3]->end = 0;
i = pcmcia_request_window(link, link->resource[3], 0);
if (i != 0)
return -1;

lp->base = ioremap(req.Base, req.Size);
lp->base = ioremap(link->resource[3]->start,
resource_size(link->resource[3]));
if (lp->base == NULL) {
printk(KERN_NOTICE "fmvj18x_cs: ioremap failed\n");
return -1;
}

i = pcmcia_map_mem_page(link, link->win, 0);
i = pcmcia_map_mem_page(link, link->resource[3], 0);
if (i != 0) {
iounmap(lp->base);
lp->base = NULL;
Expand Down Expand Up @@ -638,15 +635,13 @@ static void fmvj18x_release(struct pcmcia_device *link)
struct net_device *dev = link->priv;
local_info_t *lp = netdev_priv(dev);
u_char __iomem *tmp;
int j;

dev_dbg(&link->dev, "fmvj18x_release\n");

if (lp->base != NULL) {
tmp = lp->base;
lp->base = NULL; /* set NULL before iounmap */
iounmap(tmp);
j = pcmcia_release_window(link, link->win);
}

pcmcia_disable_device(link);
Expand Down
Loading

0 comments on commit cdb1380

Please sign in to comment.