Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cdb13808 authored by Dominik Brodowski's avatar Dominik Brodowski
Browse files

pcmcia: do not use win_req_t when calling pcmcia_request_window()



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: netdev@vger.kernel.org
CC: linux-wireless@vger.kernel.org
CC: linux-mtd@lists.infradead.org
CC: Jiri Kosina <jkosina@suse.cz>
CC: linux-scsi@vger.kernel.org
Tested-by: default avatarWolfram Sang <w.sang@pengutronix.de>
Signed-off-by: default avatarDominik Brodowski <linux@dominikbrodowski.net>
parent 899611ee
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
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
+37 −50
Original line number Diff line number Diff line
@@ -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:
@@ -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)
@@ -231,17 +219,16 @@ 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;
}
@@ -249,13 +236,13 @@ static int config_ipwireless(struct ipw_dev *ipw)
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);
+0 −4
Original line number Diff line number Diff line
@@ -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;
+29 −24
Original line number Diff line number Diff line
@@ -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;

@@ -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;
@@ -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;

@@ -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);

@@ -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;
+12 −17
Original line number Diff line number Diff line
@@ -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
@@ -582,7 +580,7 @@ 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 */
@@ -590,27 +588,26 @@ static int fmvj18x_get_hwinfo(struct pcmcia_device *link, u_char *node_id)

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;
@@ -638,7 +635,6 @@ 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");

@@ -646,7 +642,6 @@ static void fmvj18x_release(struct pcmcia_device *link)
	tmp = lp->base;
	lp->base = NULL;    /* set NULL before iounmap */
	iounmap(tmp);
	j = pcmcia_release_window(link, link->win);
    }

    pcmcia_disable_device(link);
Loading