/*
 * Device driver for the Apple Desktop Bus
 * and the /dev/adb device on macintoshes.
 *
 * Copyright (C) 1996 Paul Mackerras.
 *
 * Modified to declare controllers as structures, added
 * client notification of bus reset and handles PowerBook
 * sleep, by Benjamin Herrenschmidt.
 *
 * To do:
 *
 * - /sys/bus/adb to list the devices and infos
 * - more /dev/adb to allow userland to receive the
 *   flow of auto-polling datas from a given device.
 * - move bus probe to a kernel thread
 */

#include <linux/types.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/smp_lock.h>
#include <linux/adb.h>
#include <linux/cuda.h>
#include <linux/pmu.h>
#include <linux/notifier.h>
#include <linux/wait.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/spinlock.h>
#include <linux/completion.h>
#include <linux/device.h>

#include <asm/uaccess.h>
#include <asm/semaphore.h>
#ifdef CONFIG_PPC
#include <asm/prom.h>
#include <asm/machdep.h>
#endif


EXPORT_SYMBOL(adb_controller);
EXPORT_SYMBOL(adb_client_list);

extern struct adb_driver via_macii_driver;
extern struct adb_driver via_maciisi_driver;
extern struct adb_driver via_cuda_driver;
extern struct adb_driver adb_iop_driver;
extern struct adb_driver via_pmu_driver;
extern struct adb_driver macio_adb_driver;

static struct adb_driver *adb_driver_list[] = {
#ifdef CONFIG_ADB_MACII
	&via_macii_driver,
#endif
#ifdef CONFIG_ADB_MACIISI
	&via_maciisi_driver,
#endif
#ifdef CONFIG_ADB_CUDA
	&via_cuda_driver,
#endif
#ifdef CONFIG_ADB_IOP
	&adb_iop_driver,
#endif
#if defined(CONFIG_ADB_PMU) || defined(CONFIG_ADB_PMU68K)
	&via_pmu_driver,
#endif
#ifdef CONFIG_ADB_MACIO
	&macio_adb_driver,
#endif
	NULL
};

static struct class *adb_dev_class;

struct adb_driver *adb_controller;
BLOCKING_NOTIFIER_HEAD(adb_client_list);
static int adb_got_sleep;
static int adb_inited;
static pid_t adb_probe_task_pid;
static DECLARE_MUTEX(adb_probe_mutex);
static struct completion adb_probe_task_comp;
static int sleepy_trackpad;
static int autopoll_devs;
int __adb_probe_sync;

#ifdef CONFIG_PM
static int adb_notify_sleep(struct pmu_sleep_notifier *self, int when);
static struct pmu_sleep_notifier adb_sleep_notifier = {
	adb_notify_sleep,
	SLEEP_LEVEL_ADB,
};
#endif

static int adb_scan_bus(void);
static int do_adb_reset_bus(void);
static void adbdev_init(void);
static int try_handler_change(int, int);

static struct adb_handler {
	void (*handler)(unsigned char *, int, struct pt_regs *, int);
	int original_address;
	int handler_id;
	int busy;
} adb_handler[16];

/*
 * The adb_handler_sem mutex protects all accesses to the original_address
 * and handler_id fields of adb_handler[i] for all i, and changes to the
 * handler field.
 * Accesses to the handler field are protected by the adb_handler_lock
 * rwlock.  It is held across all calls to any handler, so that by the
 * time adb_unregister returns, we know that the old handler isn't being
 * called.
 */
static DECLARE_MUTEX(adb_handler_sem);
static DEFINE_RWLOCK(adb_handler_lock);

#if 0
static void printADBreply(struct adb_request *req)
{
        int i;

        printk("adb reply (%d)", req->reply_len);
        for(i = 0; i < req->reply_len; i++)
                printk(" %x", req->reply[i]);
        printk("\n");

}
#endif


static __inline__ void adb_wait_ms(unsigned int ms)
{
	if (current->pid && adb_probe_task_pid &&
	  adb_probe_task_pid == current->pid)
		msleep(ms);
	else
		mdelay(ms);
}

static int adb_scan_bus(void)
{
	int i, highFree=0, noMovement;
	int devmask = 0;
	struct adb_request req;
	
	/* assumes adb_handler[] is all zeroes at this point */
	for (i = 1; i < 16; i++) {
		/* see if there is anything at address i */
		adb_request(&req, NULL, ADBREQ_SYNC | ADBREQ_REPLY, 1,
                            (i << 4) | 0xf);
		if (req.reply_len > 1)
			/* one or more devices at this address */
			adb_handler[i].original_address = i;
		else if (i > highFree)
			highFree = i;
	}

	/* Note we reset noMovement to 0 each time we move a device */
	for (noMovement = 1; noMovement < 2 && highFree > 0; noMovement++) {
		for (i = 1; i < 16; i++) {
			if (adb_handler[i].original_address == 0)
				continue;
			/*
			 * Send a "talk register 3" command to address i
			 * to provoke a collision if there is more than
			 * one device at this address.
			 */
			adb_request(&req, NULL, ADBREQ_SYNC | ADBREQ_REPLY, 1,
				    (i << 4) | 0xf);
			/*
			 * Move the device(s) which didn't detect a
			 * collision to address `highFree'.  Hopefully
			 * this only moves one device.
			 */
			adb_request(&req, NULL, ADBREQ_SYNC, 3,
				    (i<< 4) | 0xb, (highFree | 0x60), 0xfe);
			/*
			 * See if anybody actually moved. This is suggested
			 * by HW TechNote 01:
			 *
			 * http://developer.apple.com/technotes/hw/hw_01.html
			 */
			adb_request(&req, NULL, ADBREQ_SYNC | ADBREQ_REPLY, 1,
				    (highFree << 4) | 0xf);
			if (req.reply_len <= 1) continue;
			/*
			 * Test whether there are any device(s) left
			 * at address i.
			 */
			adb_request(&req, NULL, ADBREQ_SYNC | ADBREQ_REPLY, 1,
				    (i << 4) | 0xf);
			if (req.reply_len > 1) {
				/*
				 * There are still one or more devices
				 * left at address i.  Register the one(s)
				 * we moved to `highFree', and find a new
				 * value for highFree.
				 */
				adb_handler[highFree].original_address =
					adb_handler[i].original_address;
				while (highFree > 0 &&
				       adb_handler[highFree].original_address)
					highFree--;
				if (highFree <= 0)
					break;

				noMovement = 0;
			}
			else {
				/*
				 * No devices left at address i; move the
				 * one(s) we moved to `highFree' back to i.
				 */
				adb_request(&req, NULL, ADBREQ_SYNC, 3,
					    (highFree << 4) | 0xb,
					    (i | 0x60), 0xfe);
			}
		}	
	}

	/* Now fill in the handler_id field of the adb_handler entries. */
	printk(KERN_DEBUG "adb devices:");
	for (i = 1; i < 16; i++) {
		if (adb_handler[i].original_address == 0)
			continue;
		adb_request(&req, NULL, ADBREQ_SYNC | ADBREQ_REPLY, 1,
			    (i << 4) | 0xf);
		adb_handler[i].handler_id = req.reply[2];
		printk(" [%d]: %d %x", i, adb_handler[i].original_address,
		       adb_handler[i].handler_id);
		devmask |= 1 << i;
	}
	printk("\n");
	return devmask;
}

/*
 * This kernel task handles ADB probing. It dies once probing is
 * completed.
 */
static int
adb_probe_task(void *x)
{
	sigset_t blocked;

	strcpy(current->comm, "kadbprobe");

	sigfillset(&blocked);
	sigprocmask(SIG_BLOCK, &blocked, NULL);
	flush_signals(current);

	printk(KERN_INFO "adb: starting probe task...\n");
	do_adb_reset_bus();
	printk(KERN_INFO "adb: finished probe task...\n");
	
	adb_probe_task_pid = 0;
	up(&adb_probe_mutex);
	
	return 0;
}

static void
__adb_probe_task(void *data)
{
	adb_probe_task_pid = kernel_thread(adb_probe_task, NULL, SIGCHLD | CLONE_KERNEL);
}

static DECLARE_WORK(adb_reset_work, __adb_probe_task, NULL);

int
adb_reset_bus(void)
{
	if (__adb_probe_sync) {
		do_adb_reset_bus();
		return 0;
	}

	down(&adb_probe_mutex);
	schedule_work(&adb_reset_work);
	return 0;
}

int __init adb_init(void)
{
	struct adb_driver *driver;
	int i;

#ifdef CONFIG_PPC32
	if (!machine_is(chrp) && !machine_is(powermac))
		return 0;
#endif
#ifdef CONFIG_MAC
	if (!MACH_IS_MAC)
		return 0;
#endif

	/* xmon may do early-init */
	if (adb_inited)
		return 0;
	adb_inited = 1;
		
	adb_controller = NULL;

	i = 0;
	while ((driver = adb_driver_list[i++]) != NULL) {
		if (!driver->probe()) {
			adb_controller = driver;
			break;
		}
	}
	if ((adb_controller == NULL) || adb_controller->init()) {
		printk(KERN_WARNING "Warning: no ADB interface detected\n");
		adb_controller = NULL;
	} else {
#ifdef CONFIG_PM
		pmu_register_sleep_notifier(&adb_sleep_notifier);
#endif /* CONFIG_PM */
#ifdef CONFIG_PPC
		if (machine_is_compatible("AAPL,PowerBook1998") ||
			machine_is_compatible("PowerBook1,1"))
			sleepy_trackpad = 1;
#endif /* CONFIG_PPC */
		init_completion(&adb_probe_task_comp);
		adbdev_init();
		adb_reset_bus();
	}
	return 0;
}

__initcall(adb_init);

#ifdef CONFIG_PM
/*
 * notify clients before sleep and reset bus afterwards
 */
int
adb_notify_sleep(struct pmu_sleep_notifier *self, int when)
{
	int ret;
	
	switch (when) {
	case PBOOK_SLEEP_REQUEST:
		adb_got_sleep = 1;
		/* We need to get a lock on the probe thread */
		down(&adb_probe_mutex);
		/* Stop autopoll */
		if (adb_controller->autopoll)
			adb_controller->autopoll(0);
		ret = blocking_notifier_call_chain(&adb_client_list,
				ADB_MSG_POWERDOWN, NULL);
		if (ret & NOTIFY_STOP_MASK) {
			up(&adb_probe_mutex);
			return PBOOK_SLEEP_REFUSE;
		}
		break;
	case PBOOK_SLEEP_REJECT:
		if (adb_got_sleep) {
			adb_got_sleep = 0;
			up(&adb_probe_mutex);
			adb_reset_bus();
		}
		break;
		
	case PBOOK_SLEEP_NOW:
		break;
	case PBOOK_WAKE:
		adb_got_sleep = 0;
		up(&adb_probe_mutex);
		adb_reset_bus();
		break;
	}
	return PBOOK_SLEEP_OK;
}
#endif /* CONFIG_PM */

static int
do_adb_reset_bus(void)
{
	int ret, nret;
	
	if (adb_controller == NULL)
		return -ENXIO;
		
	if (adb_controller->autopoll)
		adb_controller->autopoll(0);

	nret = blocking_notifier_call_chain(&adb_client_list,
			ADB_MSG_PRE_RESET, NULL);
	if (nret & NOTIFY_STOP_MASK) {
		if (adb_controller->autopoll)
			adb_controller->autopoll(autopoll_devs);
		return -EBUSY;
	}

	if (sleepy_trackpad) {
		/* Let the trackpad settle down */
		adb_wait_ms(500);
	}

	down(&adb_handler_sem);
	write_lock_irq(&adb_handler_lock);
	memset(adb_handler, 0, sizeof(adb_handler));
	write_unlock_irq(&adb_handler_lock);

	/* That one is still a bit synchronous, oh well... */
	if (adb_controller->reset_bus)
		ret = adb_controller->reset_bus();
	else
		ret = 0;

	if (sleepy_trackpad) {
		/* Let the trackpad settle down */
		adb_wait_ms(1500);
	}

	if (!ret) {
		autopoll_devs = adb_scan_bus();
		if (adb_controller->autopoll)
			adb_controller->autopoll(autopoll_devs);
	}
	up(&adb_handler_sem);

	nret = blocking_notifier_call_chain(&adb_client_list,
			ADB_MSG_POST_RESET, NULL);
	if (nret & NOTIFY_STOP_MASK)
		return -EBUSY;
	
	return ret;
}

void
adb_poll(void)
{
	if ((adb_controller == NULL)||(adb_controller->poll == NULL))
		return;
	adb_controller->poll();
}

static void
adb_probe_wakeup(struct adb_request *req)
{
	complete(&adb_probe_task_comp);
}

/* Static request used during probe */
static struct adb_request adb_sreq;
static unsigned long adb_sreq_lock; // Use semaphore ! */ 

int
adb_request(struct adb_request *req, void (*done)(struct adb_request *),
	    int flags, int nbytes, ...)
{
	va_list list;
	int i, use_sreq;
	int rc;

	if ((adb_controller == NULL) || (adb_controller->send_request == NULL))
		return -ENXIO;
	if (nbytes < 1)
		return -EINVAL;
	if (req == NULL && (flags & ADBREQ_NOSEND))
		return -EINVAL;
	
	if (req == NULL) {
		if (test_and_set_bit(0,&adb_sreq_lock)) {
			printk("adb.c: Warning: contention on static request !\n");
			return -EPERM;
		}
		req = &adb_sreq;
		flags |= ADBREQ_SYNC;
		use_sreq = 1;
	} else
		use_sreq = 0;
	req->nbytes = nbytes+1;
	req->done = done;
	req->reply_expected = flags & ADBREQ_REPLY;
	req->data[0] = ADB_PACKET;
	va_start(list, nbytes);
	for (i = 0; i < nbytes; ++i)
		req->data[i+1] = va_arg(list, int);
	va_end(list);

	if (flags & ADBREQ_NOSEND)
		return 0;

	/* Synchronous requests send from the probe thread cause it to
	 * block. Beware that the "done" callback will be overriden !
	 */
	if ((flags & ADBREQ_SYNC) &&
	    (current->pid && adb_probe_task_pid &&
	    adb_probe_task_pid == current->pid)) {
		req->done = adb_probe_wakeup;
		rc = adb_controller->send_request(req, 0);
		if (rc || req->complete)
			goto bail;
		wait_for_completion(&adb_probe_task_comp);
		rc = 0;
		goto bail;
	}

	rc = adb_controller->send_request(req, flags & ADBREQ_SYNC);
bail:
	if (use_sreq)
		clear_bit(0, &adb_sreq_lock);

	return rc;
}

 /* Ultimately this should return the number of devices with
    the given default id.
    And it does it now ! Note: changed behaviour: This function
    will now register if default_id _and_ handler_id both match
    but handler_id can be left to 0 to match with default_id only.
    When handler_id is set, this function will try to adjust
    the handler_id id it doesn't match. */
int
adb_register(int default_id, int handler_id, struct adb_ids *ids,
	     void (*handler)(unsigned char *, int, struct pt_regs *, int))
{
	int i;

	down(&adb_handler_sem);
	ids->nids = 0;
	for (i = 1; i < 16; i++) {
		if ((adb_handler[i].original_address == default_id) &&
		    (!handler_id || (handler_id == adb_handler[i].handler_id) || 
		    try_handler_change(i, handler_id))) {
			if (adb_handler[i].handler != 0) {
				printk(KERN_ERR
				       "Two handlers for ADB device %d\n",
				       default_id);
				continue;
			}
			write_lock_irq(&adb_handler_lock);
			adb_handler[i].handler = handler;
			write_unlock_irq(&adb_handler_lock);
			ids->id[ids->nids++] = i;
		}
	}
	up(&adb_handler_sem);
	return ids->nids;
}

int
adb_unregister(int index)
{
	int ret = -ENODEV;

	down(&adb_handler_sem);
	write_lock_irq(&adb_handler_lock);
	if (adb_handler[index].handler) {
		while(adb_handler[index].busy) {
			write_unlock_irq(&adb_handler_lock);
			yield();
			write_lock_irq(&adb_handler_lock);
		}
		ret = 0;
		adb_handler[index].handler = NULL;
	}
	write_unlock_irq(&adb_handler_lock);
	up(&adb_handler_sem);
	return ret;
}

void
adb_input(unsigned char *buf, int nb, struct pt_regs *regs, int autopoll)
{
	int i, id;
	static int dump_adb_input = 0;
	unsigned long flags;
	
	void (*handler)(unsigned char *, int, struct pt_regs *, int);

	/* We skip keystrokes and mouse moves when the sleep process
	 * has been started. We stop autopoll, but this is another security
	 */
	if (adb_got_sleep)
		return;
		
	id = buf[0] >> 4;
	if (dump_adb_input) {
		printk(KERN_INFO "adb packet: ");
		for (i = 0; i < nb; ++i)
			printk(" %x", buf[i]);
		printk(", id = %d\n", id);
	}
	write_lock_irqsave(&adb_handler_lock, flags);
	handler = adb_handler[id].handler;
	if (handler != NULL)
		adb_handler[id].busy = 1;
	write_unlock_irqrestore(&adb_handler_lock, flags);
	if (handler != NULL) {
		(*handler)(buf, nb, regs, autopoll);
		wmb();
		adb_handler[id].busy = 0;
	}
		
}

/* Try to change handler to new_id. Will return 1 if successful. */
static int try_handler_change(int address, int new_id)
{
	struct adb_request req;

	if (adb_handler[address].handler_id == new_id)
	    return 1;
	adb_request(&req, NULL, ADBREQ_SYNC, 3,
	    ADB_WRITEREG(address, 3), address | 0x20, new_id);
	adb_request(&req, NULL, ADBREQ_SYNC | ADBREQ_REPLY, 1,
	    ADB_READREG(address, 3));
	if (req.reply_len < 2)
	    return 0;
	if (req.reply[2] != new_id)
	    return 0;
	adb_handler[address].handler_id = req.reply[2];

	return 1;
}

int
adb_try_handler_change(int address, int new_id)
{
	int ret;

	down(&adb_handler_sem);
	ret = try_handler_change(address, new_id);
	up(&adb_handler_sem);
	return ret;
}

int
adb_get_infos(int address, int *original_address, int *handler_id)
{
	down(&adb_handler_sem);
	*original_address = adb_handler[address].original_address;
	*handler_id = adb_handler[address].handler_id;
	up(&adb_handler_sem);

	return (*original_address != 0);
}


/*
 * /dev/adb device driver.
 */

#define ADB_MAJOR	56	/* major number for /dev/adb */

struct adbdev_state {
	spinlock_t	lock;
	atomic_t	n_pending;
	struct adb_request *completed;
  	wait_queue_head_t wait_queue;
	int		inuse;
};

static void adb_write_done(struct adb_request *req)
{
	struct adbdev_state *state = (struct adbdev_state *) req->arg;
	unsigned long flags;

	if (!req->complete) {
		req->reply_len = 0;
		req->complete = 1;
	}
	spin_lock_irqsave(&state->lock, flags);
	atomic_dec(&state->n_pending);
	if (!state->inuse) {
		kfree(req);
		if (atomic_read(&state->n_pending) == 0) {
			spin_unlock_irqrestore(&state->lock, flags);
			kfree(state);
			return;
		}
	} else {
		struct adb_request **ap = &state->completed;
		while (*ap != NULL)
			ap = &(*ap)->next;
		req->next = NULL;
		*ap = req;
		wake_up_interruptible(&state->wait_queue);
	}
	spin_unlock_irqrestore(&state->lock, flags);
}

static int
do_adb_query(struct adb_request *req)
{
	int	ret = -EINVAL;

	switch(req->data[1])
	{
	case ADB_QUERY_GETDEVINFO:
		if (req->nbytes < 3)
			break;
		down(&adb_handler_sem);
		req->reply[0] = adb_handler[req->data[2]].original_address;
		req->reply[1] = adb_handler[req->data[2]].handler_id;
		up(&adb_handler_sem);
		req->complete = 1;
		req->reply_len = 2;
		adb_write_done(req);
		ret = 0;
		break;
	}
	return ret;
}

static int adb_open(struct inode *inode, struct file *file)
{
	struct adbdev_state *state;

	if (iminor(inode) > 0 || adb_controller == NULL)
		return -ENXIO;
	state = kmalloc(sizeof(struct adbdev_state), GFP_KERNEL);
	if (state == 0)
		return -ENOMEM;
	file->private_data = state;
	spin_lock_init(&state->lock);
	atomic_set(&state->n_pending, 0);
	state->completed = NULL;
	init_waitqueue_head(&state->wait_queue);
	state->inuse = 1;

	return 0;
}

static int adb_release(struct inode *inode, struct file *file)
{
	struct adbdev_state *state = file->private_data;
	unsigned long flags;

	lock_kernel();
	if (state) {
		file->private_data = NULL;
		spin_lock_irqsave(&state->lock, flags);
		if (atomic_read(&state->n_pending) == 0
		    && state->completed == NULL) {
			spin_unlock_irqrestore(&state->lock, flags);
			kfree(state);
		} else {
			state->inuse = 0;
			spin_unlock_irqrestore(&state->lock, flags);
		}
	}
	unlock_kernel();
	return 0;
}

static ssize_t adb_read(struct file *file, char __user *buf,
			size_t count, loff_t *ppos)
{
	int ret = 0;
	struct adbdev_state *state = file->private_data;
	struct adb_request *req;
	wait_queue_t wait = __WAITQUEUE_INITIALIZER(wait,current);
	unsigned long flags;

	if (count < 2)
		return -EINVAL;
	if (count > sizeof(req->reply))
		count = sizeof(req->reply);
	if (!access_ok(VERIFY_WRITE, buf, count))
		return -EFAULT;

	req = NULL;
	spin_lock_irqsave(&state->lock, flags);
	add_wait_queue(&state->wait_queue, &wait);
	current->state = TASK_INTERRUPTIBLE;

	for (;;) {
		req = state->completed;
		if (req != NULL)
			state->completed = req->next;
		else if (atomic_read(&state->n_pending) == 0)
			ret = -EIO;
		if (req != NULL || ret != 0)
			break;
		
		if (file->f_flags & O_NONBLOCK) {
			ret = -EAGAIN;
			break;
		}
		if (signal_pending(current)) {
			ret = -ERESTARTSYS;
			break;
		}
		spin_unlock_irqrestore(&state->lock, flags);
		schedule();
		spin_lock_irqsave(&state->lock, flags);
	}

	current->state = TASK_RUNNING;
	remove_wait_queue(&state->wait_queue, &wait);
	spin_unlock_irqrestore(&state->lock, flags);
	
	if (ret)
		return ret;

	ret = req->reply_len;
	if (ret > count)
		ret = count;
	if (ret > 0 && copy_to_user(buf, req->reply, ret))
		ret = -EFAULT;

	kfree(req);
	return ret;
}

static ssize_t adb_write(struct file *file, const char __user *buf,
			 size_t count, loff_t *ppos)
{
	int ret/*, i*/;
	struct adbdev_state *state = file->private_data;
	struct adb_request *req;

	if (count < 2 || count > sizeof(req->data))
		return -EINVAL;
	if (adb_controller == NULL)
		return -ENXIO;
	if (!access_ok(VERIFY_READ, buf, count))
		return -EFAULT;

	req = (struct adb_request *) kmalloc(sizeof(struct adb_request),
					     GFP_KERNEL);
	if (req == NULL)
		return -ENOMEM;

	req->nbytes = count;
	req->done = adb_write_done;
	req->arg = (void *) state;
	req->complete = 0;
	
	ret = -EFAULT;
	if (copy_from_user(req->data, buf, count))
		goto out;

	atomic_inc(&state->n_pending);

	/* If a probe is in progress or we are sleeping, wait for it to complete */
	down(&adb_probe_mutex);

	/* Queries are special requests sent to the ADB driver itself */
	if (req->data[0] == ADB_QUERY) {
		if (count > 1)
			ret = do_adb_query(req);
		else
			ret = -EINVAL;
		up(&adb_probe_mutex);
	}
	/* Special case for ADB_BUSRESET request, all others are sent to
	   the controller */
	else if ((req->data[0] == ADB_PACKET)&&(count > 1)
		&&(req->data[1] == ADB_BUSRESET)) {
		ret = do_adb_reset_bus();
		up(&adb_probe_mutex);
		atomic_dec(&state->n_pending);
		if (ret == 0)
			ret = count;
		goto out;
	} else {	
		req->reply_expected = ((req->data[1] & 0xc) == 0xc);
		if (adb_controller && adb_controller->send_request)
			ret = adb_controller->send_request(req, 0);
		else
			ret = -ENXIO;
		up(&adb_probe_mutex);
	}

	if (ret != 0) {
		atomic_dec(&state->n_pending);
		goto out;
	}
	return count;

out:
	kfree(req);
	return ret;
}

static struct file_operations adb_fops = {
	.owner		= THIS_MODULE,
	.llseek		= no_llseek,
	.read		= adb_read,
	.write		= adb_write,
	.open		= adb_open,
	.release	= adb_release,
};

static void
adbdev_init(void)
{
	if (register_chrdev(ADB_MAJOR, "adb", &adb_fops)) {
		printk(KERN_ERR "adb: unable to get major %d\n", ADB_MAJOR);
		return;
	}

	adb_dev_class = class_create(THIS_MODULE, "adb");
	if (IS_ERR(adb_dev_class))
		return;
	class_device_create(adb_dev_class, NULL, MKDEV(ADB_MAJOR, 0), NULL, "adb");
}
