/*
 * 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/config.h>
#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 <linux/devfs_fs_kernel.h>

#include <asm/uaccess.h>
#include <asm/semaphore.h>
#ifdef CONFIG_PPC
#include <asm/prom.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;
struct notifier_block *adb_client_list = NULL;
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 != _MACH_chrp) && (_machine != _MACH_Pmac) )
		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 = 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 = 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 = 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;
	}

	devfs_mk_cdev(MKDEV(ADB_MAJOR, 0), S_IFCHR | S_IRUSR | S_IWUSR, "adb");

	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");
}
