/*
 * driver.c - device id matching, driver model, etc.
 *
 * Copyright 2002 Adam Belay <ambx1@neo.rr.com>
 *
 */

#include <linux/config.h>
#include <linux/string.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/ctype.h>
#include <linux/slab.h>
#include <linux/pnp.h>
#include "base.h"

static int compare_func(const char *ida, const char *idb)
{
	int i;
	/* we only need to compare the last 4 chars */
	for (i=3; i<7; i++)
	{
		if (ida[i] != 'X' &&
		    idb[i] != 'X' &&
		    toupper(ida[i]) != toupper(idb[i]))
			return 0;
	}
	return 1;
}

int compare_pnp_id(struct pnp_id *pos, const char *id)
{
	if (!pos || !id || (strlen(id) != 7))
		return 0;
	if (memcmp(id,"ANYDEVS",7)==0)
		return 1;
	while (pos){
		if (memcmp(pos->id,id,3)==0)
			if (compare_func(pos->id,id)==1)
				return 1;
		pos = pos->next;
	}
	return 0;
}

static const struct pnp_device_id * match_device(struct pnp_driver *drv, struct pnp_dev *dev)
{
	const struct pnp_device_id *drv_id = drv->id_table;
	if (!drv_id)
		return NULL;

	while (*drv_id->id) {
		if (compare_pnp_id(dev->id, drv_id->id))
			return drv_id;
		drv_id++;
	}
	return NULL;
}

int pnp_device_attach(struct pnp_dev *pnp_dev)
{
	spin_lock(&pnp_lock);
	if(pnp_dev->status != PNP_READY){
		spin_unlock(&pnp_lock);
		return -EBUSY;
	}
	pnp_dev->status = PNP_ATTACHED;
	spin_unlock(&pnp_lock);
	return 0;
}

void pnp_device_detach(struct pnp_dev *pnp_dev)
{
	spin_lock(&pnp_lock);
	if (pnp_dev->status == PNP_ATTACHED)
		pnp_dev->status = PNP_READY;
	spin_unlock(&pnp_lock);
	pnp_disable_dev(pnp_dev);
}

static int pnp_device_probe(struct device *dev)
{
	int error;
	struct pnp_driver *pnp_drv;
	struct pnp_dev *pnp_dev;
	const struct pnp_device_id *dev_id = NULL;
	pnp_dev = to_pnp_dev(dev);
	pnp_drv = to_pnp_driver(dev->driver);

	pnp_dbg("match found with the PnP device '%s' and the driver '%s'", dev->bus_id,pnp_drv->name);

	error = pnp_device_attach(pnp_dev);
	if (error < 0)
		return error;

	if (pnp_dev->active == 0) {
		if (!(pnp_drv->flags & PNP_DRIVER_RES_DO_NOT_CHANGE)) {
			error = pnp_activate_dev(pnp_dev);
			if (error < 0)
				return error;
		}
	} else if ((pnp_drv->flags & PNP_DRIVER_RES_DISABLE)
		    == PNP_DRIVER_RES_DISABLE) {
		error = pnp_disable_dev(pnp_dev);
		if (error < 0)
			return error;
	}
	error = 0;
	if (pnp_drv->probe) {
		dev_id = match_device(pnp_drv, pnp_dev);
		if (dev_id != NULL)
			error = pnp_drv->probe(pnp_dev, dev_id);
	}
	if (error >= 0){
		pnp_dev->driver = pnp_drv;
		error = 0;
	} else
		goto fail;
	return error;

fail:
	pnp_device_detach(pnp_dev);
	return error;
}

static int pnp_device_remove(struct device *dev)
{
	struct pnp_dev * pnp_dev = to_pnp_dev(dev);
	struct pnp_driver * drv = pnp_dev->driver;

	if (drv) {
		if (drv->remove)
			drv->remove(pnp_dev);
		pnp_dev->driver = NULL;
	}
	pnp_device_detach(pnp_dev);
	return 0;
}

static int pnp_bus_match(struct device *dev, struct device_driver *drv)
{
	struct pnp_dev * pnp_dev = to_pnp_dev(dev);
	struct pnp_driver * pnp_drv = to_pnp_driver(drv);
	if (match_device(pnp_drv, pnp_dev) == NULL)
		return 0;
	return 1;
}

static int pnp_bus_suspend(struct device *dev, pm_message_t state)
{
	struct pnp_dev * pnp_dev = to_pnp_dev(dev);
	struct pnp_driver * pnp_drv = pnp_dev->driver;
	int error;

	if (!pnp_drv)
		return 0;

	if (pnp_drv->suspend) {
		error = pnp_drv->suspend(pnp_dev, state);
		if (error)
			return error;
	}

	if (!(pnp_drv->flags & PNP_DRIVER_RES_DO_NOT_CHANGE) &&
	    pnp_can_disable(pnp_dev)) {
	    	error = pnp_stop_dev(pnp_dev);
	    	if (error)
	    		return error;
	}

	return 0;
}

static int pnp_bus_resume(struct device *dev)
{
	struct pnp_dev * pnp_dev = to_pnp_dev(dev);
	struct pnp_driver * pnp_drv = pnp_dev->driver;
	int error;

	if (!pnp_drv)
		return 0;

	if (!(pnp_drv->flags & PNP_DRIVER_RES_DO_NOT_CHANGE)) {
		error = pnp_start_dev(pnp_dev);
		if (error)
			return error;
	}

	if (pnp_drv->resume)
		return pnp_drv->resume(pnp_dev);

	return 0;
}

struct bus_type pnp_bus_type = {
	.name	= "pnp",
	.match	= pnp_bus_match,
	.suspend = pnp_bus_suspend,
	.resume = pnp_bus_resume,
};


static int count_devices(struct device * dev, void * c)
{
	int * count = c;
	(*count)++;
	return 0;
}

int pnp_register_driver(struct pnp_driver *drv)
{
	int count;

	pnp_dbg("the driver '%s' has been registered", drv->name);

	drv->driver.name = drv->name;
	drv->driver.bus = &pnp_bus_type;
	drv->driver.probe = pnp_device_probe;
	drv->driver.remove = pnp_device_remove;

	count = driver_register(&drv->driver);

	/* get the number of initial matches */
	if (count >= 0){
		count = 0;
		driver_for_each_device(&drv->driver, NULL, &count, count_devices);
	}
	return count;
}

void pnp_unregister_driver(struct pnp_driver *drv)
{
	driver_unregister(&drv->driver);
	pnp_dbg("the driver '%s' has been unregistered", drv->name);
}

/**
 * pnp_add_id - adds an EISA id to the specified device
 * @id: pointer to a pnp_id structure
 * @dev: pointer to the desired device
 *
 */

int pnp_add_id(struct pnp_id *id, struct pnp_dev *dev)
{
	struct pnp_id *ptr;
	if (!id)
		return -EINVAL;
	if (!dev)
		return -EINVAL;
	id->next = NULL;
	ptr = dev->id;
	while (ptr && ptr->next)
		ptr = ptr->next;
	if (ptr)
		ptr->next = id;
	else
		dev->id = id;
	return 0;
}

EXPORT_SYMBOL(pnp_register_driver);
EXPORT_SYMBOL(pnp_unregister_driver);
#if 0
EXPORT_SYMBOL(pnp_add_id);
#endif
EXPORT_SYMBOL(pnp_device_attach);
EXPORT_SYMBOL(pnp_device_detach);
