// SPDX-License-Identifier: GPL-2.0-only
/*
 * ds.c -- 16-bit PCMCIA core support
 *
 * The initial developer of the original code is David A. Hinds
 * <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
 * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
 *
 * (C) 1999		David A. Hinds
 * (C) 2003 - 2010	Dominik Brodowski
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/list.h>
#include <linux/delay.h>
#include <linux/workqueue.h>
#include <linux/crc32.h>
#include <linux/firmware.h>
#include <linux/kref.h>
#include <linux/dma-mapping.h>
#include <linux/slab.h>

#include <pcmcia/cistpl.h>
#include <pcmcia/ds.h>
#include <pcmcia/ss.h>

#include "cs_internal.h"

/*====================================================================*/

/* Module parameters */

MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
MODULE_DESCRIPTION("PCMCIA Driver Services");
MODULE_LICENSE("GPL");


/*====================================================================*/

static void pcmcia_check_driver(struct pcmcia_driver *p_drv)
{
	const struct pcmcia_device_id *did = p_drv->id_table;
	unsigned int i;
	u32 hash;

	if (!p_drv->probe || !p_drv->remove)
		printk(KERN_DEBUG "pcmcia: %s lacks a requisite callback "
		       "function\n", p_drv->name);

	while (did && did->match_flags) {
		for (i = 0; i < 4; i++) {
			if (!did->prod_id[i])
				continue;

			hash = crc32(0, did->prod_id[i], strlen(did->prod_id[i]));
			if (hash == did->prod_id_hash[i])
				continue;

			printk(KERN_DEBUG "pcmcia: %s: invalid hash for "
			       "product string \"%s\": is 0x%x, should "
			       "be 0x%x\n", p_drv->name, did->prod_id[i],
			       did->prod_id_hash[i], hash);
			printk(KERN_DEBUG "pcmcia: see "
				"Documentation/pcmcia/devicetable.rst for "
				"details\n");
		}
		did++;
	}

	return;
}


/*======================================================================*/


struct pcmcia_dynid {
	struct list_head		node;
	struct pcmcia_device_id		id;
};

/**
 * new_id_store() - add a new PCMCIA device ID to this driver and re-probe devices
 * @driver: target device driver
 * @buf: buffer for scanning device ID data
 * @count: input size
 *
 * Adds a new dynamic PCMCIA device ID to this driver,
 * and causes the driver to probe for all devices again.
 */
static ssize_t
new_id_store(struct device_driver *driver, const char *buf, size_t count)
{
	struct pcmcia_dynid *dynid;
	struct pcmcia_driver *pdrv = to_pcmcia_drv(driver);
	__u16 match_flags, manf_id, card_id;
	__u8 func_id, function, device_no;
	__u32 prod_id_hash[4] = {0, 0, 0, 0};
	int fields = 0;
	int retval = 0;

	fields = sscanf(buf, "%hx %hx %hx %hhx %hhx %hhx %x %x %x %x",
			&match_flags, &manf_id, &card_id, &func_id, &function, &device_no,
			&prod_id_hash[0], &prod_id_hash[1], &prod_id_hash[2], &prod_id_hash[3]);
	if (fields < 6)
		return -EINVAL;

	dynid = kzalloc_obj(struct pcmcia_dynid);
	if (!dynid)
		return -ENOMEM;

	dynid->id.match_flags = match_flags;
	dynid->id.manf_id = manf_id;
	dynid->id.card_id = card_id;
	dynid->id.func_id = func_id;
	dynid->id.function = function;
	dynid->id.device_no = device_no;
	memcpy(dynid->id.prod_id_hash, prod_id_hash, sizeof(__u32) * 4);

	mutex_lock(&pdrv->dynids.lock);
	list_add_tail(&dynid->node, &pdrv->dynids.list);
	mutex_unlock(&pdrv->dynids.lock);

	retval = driver_attach(&pdrv->drv);

	if (retval)
		return retval;
	return count;
}
static DRIVER_ATTR_WO(new_id);

static void
pcmcia_free_dynids(struct pcmcia_driver *drv)
{
	struct pcmcia_dynid *dynid, *n;

	mutex_lock(&drv->dynids.lock);
	list_for_each_entry_safe(dynid, n, &drv->dynids.list, node) {
		list_del(&dynid->node);
		kfree(dynid);
	}
	mutex_unlock(&drv->dynids.lock);
}

static int
pcmcia_create_newid_file(struct pcmcia_driver *drv)
{
	int error = 0;
	if (drv->probe != NULL)
		error = driver_create_file(&drv->drv, &driver_attr_new_id);
	return error;
}

static void
pcmcia_remove_newid_file(struct pcmcia_driver *drv)
{
	driver_remove_file(&drv->drv, &driver_attr_new_id);
}

/**
 * pcmcia_register_driver - register a PCMCIA driver with the bus core
 * @driver: the &driver being registered
 *
 * Registers a PCMCIA driver with the PCMCIA bus core.
 */
int pcmcia_register_driver(struct pcmcia_driver *driver)
{
	int error;

	if (!driver)
		return -EINVAL;

	pcmcia_check_driver(driver);

	/* initialize common fields */
	driver->drv.bus = &pcmcia_bus_type;
	driver->drv.owner = driver->owner;
	driver->drv.name = driver->name;
	mutex_init(&driver->dynids.lock);
	INIT_LIST_HEAD(&driver->dynids.list);

	pr_debug("registering driver %s\n", driver->name);

	error = driver_register(&driver->drv);
	if (error < 0)
		return error;

	error = pcmcia_create_newid_file(driver);
	if (error)
		driver_unregister(&driver->drv);

	return error;
}
EXPORT_SYMBOL(pcmcia_register_driver);

/**
 * pcmcia_unregister_driver - unregister a PCMCIA driver with the bus core
 * @driver: the &driver being unregistered
 */
void pcmcia_unregister_driver(struct pcmcia_driver *driver)
{
	pr_debug("unregistering driver %s\n", driver->name);
	pcmcia_remove_newid_file(driver);
	driver_unregister(&driver->drv);
	pcmcia_free_dynids(driver);
}
EXPORT_SYMBOL(pcmcia_unregister_driver);


/* pcmcia_device handling */

static struct pcmcia_device *pcmcia_get_dev(struct pcmcia_device *p_dev)
{
	struct device *tmp_dev;
	tmp_dev = get_device(&p_dev->dev);
	if (!tmp_dev)
		return NULL;
	return to_pcmcia_dev(tmp_dev);
}

static void pcmcia_put_dev(struct pcmcia_device *p_dev)
{
	if (p_dev)
		put_device(&p_dev->dev);
}

static void pcmcia_release_function(struct kref *ref)
{
	struct config_t *c = container_of(ref, struct config_t, ref);
	pr_debug("releasing config_t\n");
	kfree(c);
}

static void pcmcia_release_dev(struct device *dev)
{
	struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
	int i;
	dev_dbg(dev, "releasing device\n");
	pcmcia_put_socket(p_dev->socket);
	for (i = 0; i < 4; i++)
		kfree(p_dev->prod_id[i]);
	kfree(p_dev->devname);
	kref_put(&p_dev->function_config->ref, pcmcia_release_function);
	kfree(p_dev);
}


static int pcmcia_device_probe(struct device *dev)
{
	struct pcmcia_device *p_dev;
	struct pcmcia_driver *p_drv;
	struct pcmcia_socket *s;
	cistpl_config_t cis_config;
	int ret = 0;

	dev = get_device(dev);
	if (!dev)
		return -ENODEV;

	p_dev = to_pcmcia_dev(dev);
	p_drv = to_pcmcia_drv(dev->driver);
	s = p_dev->socket;

	dev_dbg(dev, "trying to bind to %s\n", p_drv->name);

	if ((!p_drv->probe) || (!p_dev->function_config) ||
	    (!try_module_get(p_drv->owner))) {
		ret = -EINVAL;
		goto put_dev;
	}

	/* set up some more device information */
	ret = pccard_read_tuple(p_dev->socket, p_dev->func, CISTPL_CONFIG,
				&cis_config);
	if (!ret) {
		p_dev->config_base = cis_config.base;
		p_dev->config_regs = cis_config.rmask[0];
		dev_dbg(dev, "base %x, regs %x", p_dev->config_base,
			p_dev->config_regs);
	} else {
		dev_info(dev,
			 "pcmcia: could not parse base and rmask0 of CIS\n");
		p_dev->config_base = 0;
		p_dev->config_regs = 0;
	}

	ret = p_drv->probe(p_dev);
	if (ret) {
		dev_dbg(dev, "binding to %s failed with %d\n",
			   p_drv->name, ret);
		goto put_module;
	}
	dev_dbg(dev, "%s bound: Vpp %d.%d, idx %x, IRQ %d", p_drv->name,
		p_dev->vpp/10, p_dev->vpp%10, p_dev->config_index, p_dev->irq);
	dev_dbg(dev, "resources: ioport %pR %pR iomem %pR %pR %pR",
		p_dev->resource[0], p_dev->resource[1], p_dev->resource[2],
		p_dev->resource[3], p_dev->resource[4]);

	mutex_lock(&s->ops_mutex);
	if ((s->pcmcia_pfc) &&
	    (p_dev->socket->device_count == 1) && (p_dev->device_no == 0))
		pcmcia_parse_uevents(s, PCMCIA_UEVENT_REQUERY);
	mutex_unlock(&s->ops_mutex);

put_module:
	if (ret)
		module_put(p_drv->owner);
put_dev:
	if (ret)
		put_device(dev);
	return ret;
}


/*
 * Removes a PCMCIA card from the device tree and socket list.
 */
static void pcmcia_card_remove(struct pcmcia_socket *s, struct pcmcia_device *leftover)
{
	struct pcmcia_device	*p_dev;
	struct pcmcia_device	*tmp;

	dev_dbg(leftover ? &leftover->dev : &s->dev,
		   "pcmcia_card_remove(%d) %s\n", s->sock,
		   leftover ? leftover->devname : "");

	mutex_lock(&s->ops_mutex);
	if (!leftover)
		s->device_count = 0;
	else
		s->device_count = 1;
	mutex_unlock(&s->ops_mutex);

	/* unregister all pcmcia_devices registered with this socket, except leftover */
	list_for_each_entry_safe(p_dev, tmp, &s->devices_list, socket_device_list) {
		if (p_dev == leftover)
			continue;

		mutex_lock(&s->ops_mutex);
		list_del(&p_dev->socket_device_list);
		mutex_unlock(&s->ops_mutex);

		dev_dbg(&p_dev->dev, "unregistering device\n");
		device_unregister(&p_dev->dev);
	}

	return;
}

static void pcmcia_device_remove(struct device *dev)
{
	struct pcmcia_device *p_dev;
	struct pcmcia_driver *p_drv;
	int i;

	p_dev = to_pcmcia_dev(dev);
	p_drv = to_pcmcia_drv(dev->driver);

	dev_dbg(dev, "removing device\n");

	/* If we're removing the primary module driving a
	 * pseudo multi-function card, we need to unbind
	 * all devices
	 */
	if ((p_dev->socket->pcmcia_pfc) &&
	    (p_dev->socket->device_count > 0) &&
	    (p_dev->device_no == 0))
		pcmcia_card_remove(p_dev->socket, p_dev);

	/* detach the "instance" */
	if (p_drv->remove)
		p_drv->remove(p_dev);

	/* check for proper unloading */
	if (p_dev->_irq || p_dev->_io || p_dev->_locked)
		dev_info(dev,
			 "pcmcia: driver %s did not release config properly\n",
			 p_drv->name);

	for (i = 0; i < MAX_WIN; i++)
		if (p_dev->_win & CLIENT_WIN_REQ(i))
			dev_info(dev,
				 "pcmcia: driver %s did not release window properly\n",
				 p_drv->name);

	/* references from pcmcia_device_probe */
	pcmcia_put_dev(p_dev);
	module_put(p_drv->owner);
}


/*
 * pcmcia_device_query -- determine information about a pcmcia device
 */
static int pcmcia_device_query(struct pcmcia_device *p_dev)
{
	cistpl_manfid_t manf_id;
	cistpl_funcid_t func_id;
	cistpl_vers_1_t	*vers1;
	unsigned int i;

	vers1 = kmalloc_obj(*vers1);
	if (!vers1)
		return -ENOMEM;

	if (!pccard_read_tuple(p_dev->socket, BIND_FN_ALL,
			       CISTPL_MANFID, &manf_id)) {
		mutex_lock(&p_dev->socket->ops_mutex);
		p_dev->manf_id = manf_id.manf;
		p_dev->card_id = manf_id.card;
		p_dev->has_manf_id = 1;
		p_dev->has_card_id = 1;
		mutex_unlock(&p_dev->socket->ops_mutex);
	}

	if (!pccard_read_tuple(p_dev->socket, p_dev->func,
			       CISTPL_FUNCID, &func_id)) {
		mutex_lock(&p_dev->socket->ops_mutex);
		p_dev->func_id = func_id.func;
		p_dev->has_func_id = 1;
		mutex_unlock(&p_dev->socket->ops_mutex);
	} else {
		/* rule of thumb: cards with no FUNCID, but with
		 * common memory device geometry information, are
		 * probably memory cards (from pcmcia-cs) */
		cistpl_device_geo_t *devgeo;

		devgeo = kmalloc_obj(*devgeo);
		if (!devgeo) {
			kfree(vers1);
			return -ENOMEM;
		}
		if (!pccard_read_tuple(p_dev->socket, p_dev->func,
				      CISTPL_DEVICE_GEO, devgeo)) {
			dev_dbg(&p_dev->dev,
				   "mem device geometry probably means "
				   "FUNCID_MEMORY\n");
			mutex_lock(&p_dev->socket->ops_mutex);
			p_dev->func_id = CISTPL_FUNCID_MEMORY;
			p_dev->has_func_id = 1;
			mutex_unlock(&p_dev->socket->ops_mutex);
		}
		kfree(devgeo);
	}

	if (!pccard_read_tuple(p_dev->socket, BIND_FN_ALL, CISTPL_VERS_1,
			       vers1)) {
		mutex_lock(&p_dev->socket->ops_mutex);
		for (i = 0; i < min_t(unsigned int, 4, vers1->ns); i++) {
			char *tmp;
			unsigned int length;
			char *new;

			tmp = vers1->str + vers1->ofs[i];

			length = strlen(tmp) + 1;
			if ((length < 2) || (length > 255))
				continue;

			new = kstrdup(tmp, GFP_KERNEL);
			if (!new)
				continue;

			tmp = p_dev->prod_id[i];
			p_dev->prod_id[i] = new;
			kfree(tmp);
		}
		mutex_unlock(&p_dev->socket->ops_mutex);
	}

	kfree(vers1);
	return 0;
}


static struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s,
					       unsigned int function)
{
	struct pcmcia_device *p_dev, *tmp_dev;
	int i;

	s = pcmcia_get_socket(s);
	if (!s)
		return NULL;

	pr_debug("adding device to %d, function %d\n", s->sock, function);

	p_dev = kzalloc_obj(struct pcmcia_device);
	if (!p_dev)
		goto err_put;

	mutex_lock(&s->ops_mutex);
	p_dev->device_no = (s->device_count++);
	mutex_unlock(&s->ops_mutex);

	/* max of 2 PFC devices */
	if ((p_dev->device_no >= 2) && (function == 0))
		goto err_free;

	/* max of 4 devices overall */
	if (p_dev->device_no >= 4)
		goto err_free;

	p_dev->socket = s;
	p_dev->func   = function;

	p_dev->dev.bus = &pcmcia_bus_type;
	p_dev->dev.parent = s->dev.parent;
	p_dev->dev.release = pcmcia_release_dev;
	/* by default don't allow DMA */
	p_dev->dma_mask = 0;
	p_dev->dev.dma_mask = &p_dev->dma_mask;
	p_dev->devname = kasprintf(GFP_KERNEL, "pcmcia%s", dev_name(&p_dev->dev));
	if (!p_dev->devname)
		goto err_free;
	dev_dbg(&p_dev->dev, "devname is %s\n", p_dev->devname);

	mutex_lock(&s->ops_mutex);

	/*
	 * p_dev->function_config must be the same for all card functions.
	 * Note that this is serialized by ops_mutex, so that only one
	 * such struct will be created.
	 */
	list_for_each_entry(tmp_dev, &s->devices_list, socket_device_list)
		if (p_dev->func == tmp_dev->func) {
			p_dev->function_config = tmp_dev->function_config;
			p_dev->irq = tmp_dev->irq;
			kref_get(&p_dev->function_config->ref);
		}

	/* Add to the list in pcmcia_bus_socket */
	list_add(&p_dev->socket_device_list, &s->devices_list);

	if (pcmcia_setup_irq(p_dev))
		dev_warn(&p_dev->dev,
			"IRQ setup failed -- device might not work\n");

	if (!p_dev->function_config) {
		config_t *c;
		dev_dbg(&p_dev->dev, "creating config_t\n");
		c = kzalloc_obj(struct config_t);
		if (!c) {
			mutex_unlock(&s->ops_mutex);
			goto err_unreg;
		}
		p_dev->function_config = c;
		kref_init(&c->ref);
		for (i = 0; i < MAX_IO_WIN; i++) {
			c->io[i].name = p_dev->devname;
			c->io[i].flags = IORESOURCE_IO;
		}
		for (i = 0; i < MAX_WIN; i++) {
			c->mem[i].name = p_dev->devname;
			c->mem[i].flags = IORESOURCE_MEM;
		}
	}
	for (i = 0; i < MAX_IO_WIN; i++)
		p_dev->resource[i] = &p_dev->function_config->io[i];
	for (; i < (MAX_IO_WIN + MAX_WIN); i++)
		p_dev->resource[i] = &p_dev->function_config->mem[i-MAX_IO_WIN];

	mutex_unlock(&s->ops_mutex);

	dev_notice(&p_dev->dev, "pcmcia: registering new device %s (IRQ: %d)\n",
		   p_dev->devname, p_dev->irq);

	pcmcia_device_query(p_dev);

	dev_set_name(&p_dev->dev, "%d.%d", p_dev->socket->sock, p_dev->device_no);
	if (device_register(&p_dev->dev)) {
		mutex_lock(&s->ops_mutex);
		list_del(&p_dev->socket_device_list);
		s->device_count--;
		mutex_unlock(&s->ops_mutex);
		put_device(&p_dev->dev);
		return NULL;
	}

	return p_dev;

 err_unreg:
	mutex_lock(&s->ops_mutex);
	list_del(&p_dev->socket_device_list);
	mutex_unlock(&s->ops_mutex);

 err_free:
	mutex_lock(&s->ops_mutex);
	s->device_count--;
	mutex_unlock(&s->ops_mutex);

	for (i = 0; i < 4; i++)
		kfree(p_dev->prod_id[i]);
	kfree(p_dev->devname);
	kfree(p_dev);
 err_put:
	pcmcia_put_socket(s);

	return NULL;
}


static int pcmcia_card_add(struct pcmcia_socket *s)
{
	cistpl_longlink_mfc_t mfc;
	unsigned int no_funcs, i, no_chains;
	int ret = -EAGAIN;

	mutex_lock(&s->ops_mutex);
	if (!(s->resource_setup_done)) {
		dev_dbg(&s->dev,
			   "no resources available, delaying card_add\n");
		mutex_unlock(&s->ops_mutex);
		return -EAGAIN; /* try again, but later... */
	}

	if (pcmcia_validate_mem(s)) {
		dev_dbg(&s->dev, "validating mem resources failed, "
		       "delaying card_add\n");
		mutex_unlock(&s->ops_mutex);
		return -EAGAIN; /* try again, but later... */
	}
	mutex_unlock(&s->ops_mutex);

	ret = pccard_validate_cis(s, &no_chains);
	if (ret || !no_chains) {
#if defined(CONFIG_MTD_PCMCIA_ANONYMOUS)
		/* Set up as an anonymous card. If we don't have anonymous
		   memory support then just error the card as there is no
		   point trying to second guess.

		   Note: some cards have just a device entry, it may be
		   worth extending support to cover these in future */
		if (ret == -EIO) {
			dev_info(&s->dev, "no CIS, assuming an anonymous memory card.\n");
			pcmcia_replace_cis(s, "\xFF", 1);
			no_chains = 1;
			ret = 0;
		} else
#endif
		{
			dev_dbg(&s->dev, "invalid CIS or invalid resources\n");
			return -ENODEV;
		}
	}

	if (!pccard_read_tuple(s, BIND_FN_ALL, CISTPL_LONGLINK_MFC, &mfc))
		no_funcs = mfc.nfn;
	else
		no_funcs = 1;
	s->functions = no_funcs;

	for (i = 0; i < no_funcs; i++)
		pcmcia_device_add(s, i);

	return ret;
}


static int pcmcia_requery_callback(struct device *dev, void *_data)
{
	struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
	if (!p_dev->dev.driver) {
		dev_dbg(dev, "update device information\n");
		pcmcia_device_query(p_dev);
	}

	return 0;
}


static void pcmcia_requery(struct pcmcia_socket *s)
{
	int has_pfc;

	if (!(s->state & SOCKET_PRESENT))
		return;

	if (s->functions == 0) {
		pcmcia_card_add(s);
		return;
	}

	/* some device information might have changed because of a CIS
	 * update or because we can finally read it correctly... so
	 * determine it again, overwriting old values if necessary. */
	bus_for_each_dev(&pcmcia_bus_type, NULL, NULL, pcmcia_requery_callback);

	/* if the CIS changed, we need to check whether the number of
	 * functions changed. */
	if (s->fake_cis) {
		int old_funcs, new_funcs;
		cistpl_longlink_mfc_t mfc;

		/* does this cis override add or remove functions? */
		old_funcs = s->functions;

		if (!pccard_read_tuple(s, BIND_FN_ALL, CISTPL_LONGLINK_MFC,
					&mfc))
			new_funcs = mfc.nfn;
		else
			new_funcs = 1;
		if (old_funcs != new_funcs) {
			/* we need to re-start */
			pcmcia_card_remove(s, NULL);
			s->functions = 0;
			pcmcia_card_add(s);
		}
	}

	/* If the PCMCIA device consists of two pseudo devices,
	 * call pcmcia_device_add() -- which will fail if both
	 * devices are already registered. */
	mutex_lock(&s->ops_mutex);
	has_pfc = s->pcmcia_pfc;
	mutex_unlock(&s->ops_mutex);
	if (has_pfc)
		pcmcia_device_add(s, 0);

	/* we re-scan all devices, not just the ones connected to this
	 * socket. This does not matter, though. */
	if (bus_rescan_devices(&pcmcia_bus_type))
		dev_warn(&s->dev, "rescanning the bus failed\n");
}


#ifdef CONFIG_PCMCIA_LOAD_CIS

/**
 * pcmcia_load_firmware - load CIS from userspace if device-provided is broken
 * @dev: the pcmcia device which needs a CIS override
 * @filename: requested filename in /lib/firmware/
 *
 * This uses the in-kernel firmware loading mechanism to use a "fake CIS" if
 * the one provided by the card is broken. The firmware files reside in
 * /lib/firmware/ in userspace.
 */
static int pcmcia_load_firmware(struct pcmcia_device *dev, char *filename)
{
	struct pcmcia_socket *s = dev->socket;
	const struct firmware *fw;
	int ret = -ENOMEM;
	cistpl_longlink_mfc_t mfc;
	int old_funcs, new_funcs = 1;

	if (!filename)
		return -EINVAL;

	dev_dbg(&dev->dev, "trying to load CIS file %s\n", filename);

	if (request_firmware(&fw, filename, &dev->dev) == 0) {
		if (fw->size >= CISTPL_MAX_CIS_SIZE) {
			ret = -EINVAL;
			dev_err(&dev->dev, "pcmcia: CIS override is too big\n");
			goto release;
		}

		if (!pcmcia_replace_cis(s, fw->data, fw->size))
			ret = 0;
		else {
			dev_err(&dev->dev, "pcmcia: CIS override failed\n");
			goto release;
		}

		/* we need to re-start if the number of functions changed */
		old_funcs = s->functions;
		if (!pccard_read_tuple(s, BIND_FN_ALL, CISTPL_LONGLINK_MFC,
					&mfc))
			new_funcs = mfc.nfn;

		if (old_funcs != new_funcs)
			ret = -EBUSY;

		/* update information */
		pcmcia_device_query(dev);

		/* requery (as number of functions might have changed) */
		pcmcia_parse_uevents(s, PCMCIA_UEVENT_REQUERY);
	}
 release:
	release_firmware(fw);

	return ret;
}

#else /* !CONFIG_PCMCIA_LOAD_CIS */

static inline int pcmcia_load_firmware(struct pcmcia_device *dev,
				       char *filename)
{
	return -ENODEV;
}

#endif


static inline int pcmcia_devmatch(struct pcmcia_device *dev,
				  const struct pcmcia_device_id *did)
{
	if (did->match_flags & PCMCIA_DEV_ID_MATCH_MANF_ID) {
		if ((!dev->has_manf_id) || (dev->manf_id != did->manf_id))
			return 0;
	}

	if (did->match_flags & PCMCIA_DEV_ID_MATCH_CARD_ID) {
		if ((!dev->has_card_id) || (dev->card_id != did->card_id))
			return 0;
	}

	if (did->match_flags & PCMCIA_DEV_ID_MATCH_FUNCTION) {
		if (dev->func != did->function)
			return 0;
	}

	if (did->match_flags & PCMCIA_DEV_ID_MATCH_PROD_ID1) {
		if (!dev->prod_id[0])
			return 0;
		if (strcmp(did->prod_id[0], dev->prod_id[0]))
			return 0;
	}

	if (did->match_flags & PCMCIA_DEV_ID_MATCH_PROD_ID2) {
		if (!dev->prod_id[1])
			return 0;
		if (strcmp(did->prod_id[1], dev->prod_id[1]))
			return 0;
	}

	if (did->match_flags & PCMCIA_DEV_ID_MATCH_PROD_ID3) {
		if (!dev->prod_id[2])
			return 0;
		if (strcmp(did->prod_id[2], dev->prod_id[2]))
			return 0;
	}

	if (did->match_flags & PCMCIA_DEV_ID_MATCH_PROD_ID4) {
		if (!dev->prod_id[3])
			return 0;
		if (strcmp(did->prod_id[3], dev->prod_id[3]))
			return 0;
	}

	if (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) {
		dev_dbg(&dev->dev, "this is a pseudo-multi-function device\n");
		mutex_lock(&dev->socket->ops_mutex);
		dev->socket->pcmcia_pfc = 1;
		mutex_unlock(&dev->socket->ops_mutex);
		if (dev->device_no != did->device_no)
			return 0;
	}

	if (did->match_flags & PCMCIA_DEV_ID_MATCH_FUNC_ID) {
		int ret;

		if ((!dev->has_func_id) || (dev->func_id != did->func_id))
			return 0;

		/* if this is a pseudo-multi-function device,
		 * we need explicit matches */
		if (dev->socket->pcmcia_pfc)
			return 0;
		if (dev->device_no)
			return 0;

		/* also, FUNC_ID matching needs to be activated by userspace
		 * after it has re-checked that there is no possible module
		 * with a prod_id/manf_id/card_id match.
		 */
		mutex_lock(&dev->socket->ops_mutex);
		ret = dev->allow_func_id_match;
		mutex_unlock(&dev->socket->ops_mutex);

		if (!ret) {
			dev_dbg(&dev->dev,
				"skipping FUNC_ID match until userspace ACK\n");
			return 0;
		}
	}

	if (did->match_flags & PCMCIA_DEV_ID_MATCH_FAKE_CIS) {
		dev_dbg(&dev->dev, "device needs a fake CIS\n");
		if (!dev->socket->fake_cis)
			if (pcmcia_load_firmware(dev, did->cisfile))
				return 0;
	}

	if (did->match_flags & PCMCIA_DEV_ID_MATCH_ANONYMOUS) {
		int i;
		for (i = 0; i < 4; i++)
			if (dev->prod_id[i])
				return 0;
		if (dev->has_manf_id || dev->has_card_id || dev->has_func_id)
			return 0;
	}

	return 1;
}


static int pcmcia_bus_match(struct device *dev, const struct device_driver *drv)
{
	struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
	struct pcmcia_driver *p_drv = to_pcmcia_drv(drv);
	const struct pcmcia_device_id *did = p_drv->id_table;
	struct pcmcia_dynid *dynid;

	/* match dynamic devices first */
	mutex_lock(&p_drv->dynids.lock);
	list_for_each_entry(dynid, &p_drv->dynids.list, node) {
		dev_dbg(dev, "trying to match to %s\n", drv->name);
		if (pcmcia_devmatch(p_dev, &dynid->id)) {
			dev_dbg(dev, "matched to %s\n", drv->name);
			mutex_unlock(&p_drv->dynids.lock);
			return 1;
		}
	}
	mutex_unlock(&p_drv->dynids.lock);

	while (did && did->match_flags) {
		dev_dbg(dev, "trying to match to %s\n", drv->name);
		if (pcmcia_devmatch(p_dev, did)) {
			dev_dbg(dev, "matched to %s\n", drv->name);
			return 1;
		}
		did++;
	}

	return 0;
}

static int pcmcia_bus_uevent(const struct device *dev, struct kobj_uevent_env *env)
{
	const struct pcmcia_device *p_dev;
	int i;
	u32 hash[4] = { 0, 0, 0, 0};

	if (!dev)
		return -ENODEV;

	p_dev = to_pcmcia_dev(dev);

	/* calculate hashes */
	for (i = 0; i < 4; i++) {
		if (!p_dev->prod_id[i])
			continue;
		hash[i] = crc32(0, p_dev->prod_id[i], strlen(p_dev->prod_id[i]));
	}

	if (add_uevent_var(env, "SOCKET_NO=%u", p_dev->socket->sock))
		return -ENOMEM;

	if (add_uevent_var(env, "DEVICE_NO=%02X", p_dev->device_no))
		return -ENOMEM;

	if (add_uevent_var(env, "MODALIAS=pcmcia:m%04Xc%04Xf%02Xfn%02Xpfn%02X"
			   "pa%08Xpb%08Xpc%08Xpd%08X",
			   p_dev->has_manf_id ? p_dev->manf_id : 0,
			   p_dev->has_card_id ? p_dev->card_id : 0,
			   p_dev->has_func_id ? p_dev->func_id : 0,
			   p_dev->func,
			   p_dev->device_no,
			   hash[0],
			   hash[1],
			   hash[2],
			   hash[3]))
		return -ENOMEM;

	return 0;
}

/************************ runtime PM support ***************************/

static int pcmcia_dev_suspend(struct device *dev);
static int pcmcia_dev_resume(struct device *dev);

static int runtime_suspend(struct device *dev)
{
	int rc;

	device_lock(dev);
	rc = pcmcia_dev_suspend(dev);
	device_unlock(dev);
	return rc;
}

static int runtime_resume(struct device *dev)
{
	int rc;

	device_lock(dev);
	rc = pcmcia_dev_resume(dev);
	device_unlock(dev);
	return rc;
}

/************************ per-device sysfs output ***************************/

#define pcmcia_device_attr(field, test, format)				\
static ssize_t field##_show (struct device *dev, struct device_attribute *attr, char *buf)		\
{									\
	struct pcmcia_device *p_dev = to_pcmcia_dev(dev);		\
	return p_dev->test ? sysfs_emit(buf, format, p_dev->field) : -ENODEV; \
}									\
static DEVICE_ATTR_RO(field);

#define pcmcia_device_stringattr(name, field)					\
static ssize_t name##_show (struct device *dev, struct device_attribute *attr, char *buf)		\
{									\
	struct pcmcia_device *p_dev = to_pcmcia_dev(dev);		\
	return p_dev->field ? sysfs_emit(buf, "%s\n", p_dev->field) : -ENODEV; \
}									\
static DEVICE_ATTR_RO(name);

pcmcia_device_attr(func_id, has_func_id, "0x%02x\n");
pcmcia_device_attr(manf_id, has_manf_id, "0x%04x\n");
pcmcia_device_attr(card_id, has_card_id, "0x%04x\n");
pcmcia_device_stringattr(prod_id1, prod_id[0]);
pcmcia_device_stringattr(prod_id2, prod_id[1]);
pcmcia_device_stringattr(prod_id3, prod_id[2]);
pcmcia_device_stringattr(prod_id4, prod_id[3]);

static ssize_t function_show(struct device *dev, struct device_attribute *attr,
			     char *buf)
{
	struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
	return p_dev->socket ? sysfs_emit(buf, "0x%02x\n", p_dev->func) : -ENODEV;
}
static DEVICE_ATTR_RO(function);

static ssize_t resources_show(struct device *dev,
			      struct device_attribute *attr, char *buf)
{
	struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
	int i, at = 0;

	for (i = 0; i < PCMCIA_NUM_RESOURCES; i++)
		at += sysfs_emit_at(buf, at, "%pr\n", p_dev->resource[i]);

	return at;
}
static DEVICE_ATTR_RO(resources);

static ssize_t pm_state_show(struct device *dev, struct device_attribute *attr, char *buf)
{
	struct pcmcia_device *p_dev = to_pcmcia_dev(dev);

	if (p_dev->suspended)
		return sysfs_emit(buf, "off\n");
	else
		return sysfs_emit(buf, "on\n");
}

static ssize_t pm_state_store(struct device *dev, struct device_attribute *attr,
			      const char *buf, size_t count)
{
	struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
	int ret = 0;

	if (!count)
		return -EINVAL;

	if ((!p_dev->suspended) && !strncmp(buf, "off", 3))
		ret = runtime_suspend(dev);
	else if (p_dev->suspended && !strncmp(buf, "on", 2))
		ret = runtime_resume(dev);

	return ret ? ret : count;
}
static DEVICE_ATTR_RW(pm_state);

static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, char *buf)
{
	struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
	int i;
	u32 hash[4] = { 0, 0, 0, 0};

	/* calculate hashes */
	for (i = 0; i < 4; i++) {
		if (!p_dev->prod_id[i])
			continue;
		hash[i] = crc32(0, p_dev->prod_id[i],
				strlen(p_dev->prod_id[i]));
	}
	return sysfs_emit(buf, "pcmcia:m%04Xc%04Xf%02Xfn%02Xpfn%02Xpa%08Xpb%08Xpc%08Xpd%08X\n",
				p_dev->has_manf_id ? p_dev->manf_id : 0,
				p_dev->has_card_id ? p_dev->card_id : 0,
				p_dev->has_func_id ? p_dev->func_id : 0,
				p_dev->func, p_dev->device_no,
				hash[0], hash[1], hash[2], hash[3]);
}
static DEVICE_ATTR_RO(modalias);

static ssize_t allow_func_id_match_store(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t count)
{
	struct pcmcia_device *p_dev = to_pcmcia_dev(dev);

	if (!count)
		return -EINVAL;

	mutex_lock(&p_dev->socket->ops_mutex);
	p_dev->allow_func_id_match = 1;
	mutex_unlock(&p_dev->socket->ops_mutex);
	pcmcia_parse_uevents(p_dev->socket, PCMCIA_UEVENT_REQUERY);

	return count;
}
static DEVICE_ATTR_WO(allow_func_id_match);

static struct attribute *pcmcia_dev_attrs[] = {
	&dev_attr_resources.attr,
	&dev_attr_pm_state.attr,
	&dev_attr_function.attr,
	&dev_attr_func_id.attr,
	&dev_attr_manf_id.attr,
	&dev_attr_card_id.attr,
	&dev_attr_prod_id1.attr,
	&dev_attr_prod_id2.attr,
	&dev_attr_prod_id3.attr,
	&dev_attr_prod_id4.attr,
	&dev_attr_modalias.attr,
	&dev_attr_allow_func_id_match.attr,
	NULL,
};
ATTRIBUTE_GROUPS(pcmcia_dev);

/* PM support, also needed for reset */

static int pcmcia_dev_suspend(struct device *dev)
{
	struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
	struct pcmcia_driver *p_drv = NULL;
	int ret = 0;

	mutex_lock(&p_dev->socket->ops_mutex);
	if (p_dev->suspended) {
		mutex_unlock(&p_dev->socket->ops_mutex);
		return 0;
	}
	p_dev->suspended = 1;
	mutex_unlock(&p_dev->socket->ops_mutex);

	dev_dbg(dev, "suspending\n");

	if (dev->driver)
		p_drv = to_pcmcia_drv(dev->driver);

	if (!p_drv)
		goto out;

	if (p_drv->suspend) {
		ret = p_drv->suspend(p_dev);
		if (ret) {
			dev_err(dev,
				"pcmcia: device %s (driver %s) did not want to go to sleep (%d)\n",
				p_dev->devname, p_drv->name, ret);
			mutex_lock(&p_dev->socket->ops_mutex);
			p_dev->suspended = 0;
			mutex_unlock(&p_dev->socket->ops_mutex);
			goto out;
		}
	}

	if (p_dev->device_no == p_dev->func) {
		dev_dbg(dev, "releasing configuration\n");
		pcmcia_release_configuration(p_dev);
	}

 out:
	return ret;
}


static int pcmcia_dev_resume(struct device *dev)
{
	struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
	struct pcmcia_driver *p_drv = NULL;
	int ret = 0;

	mutex_lock(&p_dev->socket->ops_mutex);
	if (!p_dev->suspended) {
		mutex_unlock(&p_dev->socket->ops_mutex);
		return 0;
	}
	p_dev->suspended = 0;
	mutex_unlock(&p_dev->socket->ops_mutex);

	dev_dbg(dev, "resuming\n");

	if (dev->driver)
		p_drv = to_pcmcia_drv(dev->driver);

	if (!p_drv)
		goto out;

	if (p_dev->device_no == p_dev->func) {
		dev_dbg(dev, "requesting configuration\n");
		ret = pcmcia_enable_device(p_dev);
		if (ret)
			goto out;
	}

	if (p_drv->resume)
		ret = p_drv->resume(p_dev);

 out:
	return ret;
}


static int pcmcia_bus_suspend_callback(struct device *dev, void *_data)
{
	struct pcmcia_socket *skt = _data;
	struct pcmcia_device *p_dev = to_pcmcia_dev(dev);

	if (p_dev->socket != skt || p_dev->suspended)
		return 0;

	return runtime_suspend(dev);
}

static int pcmcia_bus_resume_callback(struct device *dev, void *_data)
{
	struct pcmcia_socket *skt = _data;
	struct pcmcia_device *p_dev = to_pcmcia_dev(dev);

	if (p_dev->socket != skt || !p_dev->suspended)
		return 0;

	runtime_resume(dev);

	return 0;
}

static int pcmcia_bus_resume(struct pcmcia_socket *skt)
{
	dev_dbg(&skt->dev, "resuming socket %d\n", skt->sock);
	bus_for_each_dev(&pcmcia_bus_type, NULL, skt, pcmcia_bus_resume_callback);
	return 0;
}

static int pcmcia_bus_suspend(struct pcmcia_socket *skt)
{
	dev_dbg(&skt->dev, "suspending socket %d\n", skt->sock);
	if (bus_for_each_dev(&pcmcia_bus_type, NULL, skt,
			     pcmcia_bus_suspend_callback)) {
		pcmcia_bus_resume(skt);
		return -EIO;
	}
	return 0;
}

static int pcmcia_bus_remove(struct pcmcia_socket *skt)
{
	atomic_set(&skt->present, 0);
	pcmcia_card_remove(skt, NULL);

	mutex_lock(&skt->ops_mutex);
	destroy_cis_cache(skt);
	pcmcia_cleanup_irq(skt);
	mutex_unlock(&skt->ops_mutex);

	return 0;
}

static int pcmcia_bus_add(struct pcmcia_socket *skt)
{
	atomic_set(&skt->present, 1);

	mutex_lock(&skt->ops_mutex);
	skt->pcmcia_pfc = 0;
	destroy_cis_cache(skt); /* to be on the safe side... */
	mutex_unlock(&skt->ops_mutex);

	pcmcia_card_add(skt);

	return 0;
}

static int pcmcia_bus_early_resume(struct pcmcia_socket *skt)
{
	if (!verify_cis_cache(skt))
		return 0;

	dev_dbg(&skt->dev, "cis mismatch - different card\n");

	/* first, remove the card */
	pcmcia_bus_remove(skt);

	mutex_lock(&skt->ops_mutex);
	destroy_cis_cache(skt);
	kfree(skt->fake_cis);
	skt->fake_cis = NULL;
	skt->functions = 0;
	mutex_unlock(&skt->ops_mutex);

	/* now, add the new card */
	pcmcia_bus_add(skt);
	return 0;
}


/*
 * NOTE: This is racy. There's no guarantee the card will still be
 * physically present, even if the call to this function returns
 * non-NULL. Furthermore, the device driver most likely is unbound
 * almost immediately, so the timeframe where pcmcia_dev_present
 * returns NULL is probably really, really small.
 */
struct pcmcia_device *pcmcia_dev_present(struct pcmcia_device *_p_dev)
{
	struct pcmcia_device *p_dev;
	struct pcmcia_device *ret = NULL;

	p_dev = pcmcia_get_dev(_p_dev);
	if (!p_dev)
		return NULL;

	if (atomic_read(&p_dev->socket->present) != 0)
		ret = p_dev;

	pcmcia_put_dev(p_dev);
	return ret;
}
EXPORT_SYMBOL(pcmcia_dev_present);


static struct pcmcia_callback pcmcia_bus_callback = {
	.owner = THIS_MODULE,
	.add = pcmcia_bus_add,
	.remove = pcmcia_bus_remove,
	.requery = pcmcia_requery,
	.validate = pccard_validate_cis,
	.suspend = pcmcia_bus_suspend,
	.early_resume = pcmcia_bus_early_resume,
	.resume = pcmcia_bus_resume,
};

static int pcmcia_bus_add_socket(struct device *dev)
{
	struct pcmcia_socket *socket = dev_get_drvdata(dev);
	int ret;

	socket = pcmcia_get_socket(socket);
	if (!socket) {
		dev_err(dev, "PCMCIA obtaining reference to socket failed\n");
		return -ENODEV;
	}

	ret = sysfs_create_bin_file(&dev->kobj, &pccard_cis_attr);
	if (ret) {
		dev_err(dev, "PCMCIA registration failed\n");
		pcmcia_put_socket(socket);
		return ret;
	}

	INIT_LIST_HEAD(&socket->devices_list);
	socket->pcmcia_pfc = 0;
	socket->device_count = 0;
	atomic_set(&socket->present, 0);

	ret = pccard_register_pcmcia(socket, &pcmcia_bus_callback);
	if (ret) {
		dev_err(dev, "PCMCIA registration failed\n");
		pcmcia_put_socket(socket);
		return ret;
	}

	return 0;
}

static void pcmcia_bus_remove_socket(struct device *dev)
{
	struct pcmcia_socket *socket = dev_get_drvdata(dev);

	if (!socket)
		return;

	pccard_register_pcmcia(socket, NULL);

	/* unregister any unbound devices */
	mutex_lock(&socket->skt_mutex);
	pcmcia_card_remove(socket, NULL);
	release_cis_mem(socket);
	mutex_unlock(&socket->skt_mutex);

	sysfs_remove_bin_file(&dev->kobj, &pccard_cis_attr);

	pcmcia_put_socket(socket);

	return;
}


/* the pcmcia_bus_interface is used to handle pcmcia socket devices */
static struct class_interface pcmcia_bus_interface __refdata = {
	.class = &pcmcia_socket_class,
	.add_dev = &pcmcia_bus_add_socket,
	.remove_dev = &pcmcia_bus_remove_socket,
};

static const struct dev_pm_ops pcmcia_bus_pm_ops = {
	SET_SYSTEM_SLEEP_PM_OPS(pcmcia_dev_suspend, pcmcia_dev_resume)
};

const struct bus_type pcmcia_bus_type = {
	.name = "pcmcia",
	.uevent = pcmcia_bus_uevent,
	.match = pcmcia_bus_match,
	.dev_groups = pcmcia_dev_groups,
	.probe = pcmcia_device_probe,
	.remove = pcmcia_device_remove,
	.pm = &pcmcia_bus_pm_ops,
};


static int __init init_pcmcia_bus(void)
{
	int ret;

	ret = bus_register(&pcmcia_bus_type);
	if (ret < 0) {
		printk(KERN_WARNING "pcmcia: bus_register error: %d\n", ret);
		return ret;
	}
	ret = class_interface_register(&pcmcia_bus_interface);
	if (ret < 0) {
		printk(KERN_WARNING
			"pcmcia: class_interface_register error: %d\n", ret);
		bus_unregister(&pcmcia_bus_type);
		return ret;
	}

	return 0;
}
fs_initcall(init_pcmcia_bus); /* one level after subsys_initcall so that
			       * pcmcia_socket_class is already registered */


static void __exit exit_pcmcia_bus(void)
{
	class_interface_unregister(&pcmcia_bus_interface);

	bus_unregister(&pcmcia_bus_type);
}
module_exit(exit_pcmcia_bus);


MODULE_ALIAS("ds");
