/* Copyright (c) 2004 Coraid, Inc.  See COPYING for GPL terms. */
/*
 * aoedev.c
 * AoE device utility functions; maintains device list.
 */

#include <linux/hdreg.h>
#include <linux/blkdev.h>
#include <linux/netdevice.h>
#include "aoe.h"

static struct aoedev *devlist;
static spinlock_t devlist_lock;

struct aoedev *
aoedev_bymac(unsigned char *macaddr)
{
	struct aoedev *d;
	ulong flags;

	spin_lock_irqsave(&devlist_lock, flags);

	for (d=devlist; d; d=d->next)
		if (!memcmp(d->addr, macaddr, 6))
			break;

	spin_unlock_irqrestore(&devlist_lock, flags);
	return d;
}

/* called with devlist lock held */
static struct aoedev *
aoedev_newdev(ulong nframes)
{
	struct aoedev *d;
	struct frame *f, *e;

	d = kcalloc(1, sizeof *d, GFP_ATOMIC);
	if (d == NULL)
		return NULL;
	f = kcalloc(nframes, sizeof *f, GFP_ATOMIC);
	if (f == NULL) {
		kfree(d);
		return NULL;
	}

	d->nframes = nframes;
	d->frames = f;
	e = f + nframes;
	for (; f<e; f++)
		f->tag = FREETAG;

	spin_lock_init(&d->lock);
	init_timer(&d->timer);
	d->bufpool = NULL;	/* defer to aoeblk_gdalloc */
	INIT_LIST_HEAD(&d->bufq);
	d->next = devlist;
	devlist = d;

	return d;
}

void
aoedev_downdev(struct aoedev *d)
{
	struct frame *f, *e;
	struct buf *buf;
	struct bio *bio;

	d->flags |= DEVFL_TKILL;
	del_timer(&d->timer);

	f = d->frames;
	e = f + d->nframes;
	for (; f<e; f->tag = FREETAG, f->buf = NULL, f++) {
		if (f->tag == FREETAG || f->buf == NULL)
			continue;
		buf = f->buf;
		bio = buf->bio;
		if (--buf->nframesout == 0) {
			mempool_free(buf, d->bufpool);
			bio_endio(bio, bio->bi_size, -EIO);
		}
	}
	d->inprocess = NULL;

	while (!list_empty(&d->bufq)) {
		buf = container_of(d->bufq.next, struct buf, bufs);
		list_del(d->bufq.next);
		bio = buf->bio;
		mempool_free(buf, d->bufpool);
		bio_endio(bio, bio->bi_size, -EIO);
	}

	if (d->nopen)
		d->flags |= DEVFL_CLOSEWAIT;
	if (d->gd)
		d->gd->capacity = 0;

	d->flags &= ~DEVFL_UP;
}

struct aoedev *
aoedev_set(ulong sysminor, unsigned char *addr, struct net_device *ifp, ulong bufcnt)
{
	struct aoedev *d;
	ulong flags;

	spin_lock_irqsave(&devlist_lock, flags);

	for (d=devlist; d; d=d->next)
		if (d->sysminor == sysminor
		|| memcmp(d->addr, addr, sizeof d->addr) == 0)
			break;

	if (d == NULL && (d = aoedev_newdev(bufcnt)) == NULL) {
		spin_unlock_irqrestore(&devlist_lock, flags);
		printk(KERN_INFO "aoe: aoedev_set: aoedev_newdev failure.\n");
		return NULL;
	}

	spin_unlock_irqrestore(&devlist_lock, flags);
	spin_lock_irqsave(&d->lock, flags);

	d->ifp = ifp;

	if (d->sysminor != sysminor
	|| memcmp(d->addr, addr, sizeof d->addr)
	|| (d->flags & DEVFL_UP) == 0) {
		aoedev_downdev(d); /* flushes outstanding frames */
		memcpy(d->addr, addr, sizeof d->addr);
		d->sysminor = sysminor;
		d->aoemajor = AOEMAJOR(sysminor);
		d->aoeminor = AOEMINOR(sysminor);
	}

	spin_unlock_irqrestore(&d->lock, flags);
	return d;
}

static void
aoedev_freedev(struct aoedev *d)
{
	if (d->gd) {
		aoedisk_rm_sysfs(d);
		del_gendisk(d->gd);
		put_disk(d->gd);
	}
	kfree(d->frames);
	mempool_destroy(d->bufpool);
	kfree(d);
}

void
aoedev_exit(void)
{
	struct aoedev *d;
	ulong flags;

	flush_scheduled_work();

	while ((d = devlist)) {
		devlist = d->next;

		spin_lock_irqsave(&d->lock, flags);
		aoedev_downdev(d);
		spin_unlock_irqrestore(&d->lock, flags);

		del_timer_sync(&d->timer);
		aoedev_freedev(d);
	}
}

int __init
aoedev_init(void)
{
	spin_lock_init(&devlist_lock);
	return 0;
}

