예제 #1
0
static int pcmcia_device_remove(struct device * dev)
{
	struct pcmcia_device *p_dev;
	struct pcmcia_driver *p_drv;
	int i;

	/* detach the "instance" */
	p_dev = to_pcmcia_dev(dev);
	p_drv = to_pcmcia_drv(dev->driver);
	if (!p_drv)
		return 0;

	if (p_drv->remove)
	       	p_drv->remove(p_dev);

	/* check for proper unloading */
	if (p_dev->state & (CLIENT_IRQ_REQ|CLIENT_IO_REQ|CLIENT_CONFIG_LOCKED))
		printk(KERN_INFO "pcmcia: driver %s did not release config properly\n",
		       p_drv->drv.name);

	for (i = 0; i < MAX_WIN; i++)
		if (p_dev->state & CLIENT_WIN_REQ(i))
			printk(KERN_INFO "pcmcia: driver %s did not release windows properly\n",
			       p_drv->drv.name);

	/* references from pcmcia_probe_device */
	p_dev->state = CLIENT_UNBOUND;
	pcmcia_put_dev(p_dev);
	module_put(p_drv->owner);

	return 0;
}
int pcmcia_release_window(struct pcmcia_device *p_dev, window_handle_t wh)
{
    struct pcmcia_socket *s = p_dev->socket;
    pccard_mem_map *win;

    wh--;
    if (wh >= MAX_WIN)
        return -EINVAL;

    mutex_lock(&s->ops_mutex);
    win = &s->win[wh];

    if (!(p_dev->_win & CLIENT_WIN_REQ(wh))) {
        dev_dbg(&s->dev, "not releasing unknown window\n");
        mutex_unlock(&s->ops_mutex);
        return -EINVAL;
    }

    /* Shut down memory window */
    win->flags &= ~MAP_ACTIVE;
    s->ops->set_mem_map(s, win);
    s->state &= ~SOCKET_WIN_REQ(wh);

    /* Release system memory */
    if (win->res) {
        release_resource(win->res);
        kfree(win->res);
        win->res = NULL;
    }
    p_dev->_win &= ~CLIENT_WIN_REQ(wh);
    mutex_unlock(&s->ops_mutex);

    return 0;
} /* pcmcia_release_window */