/* 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_by_aoeaddr(int maj, int min)
{
	struct aoedev *d;
	ulong flags;

	spin_lock_irqsave(&devlist_lock, flags);

	for (d=devlist; d; d=d->next)
		if (d->aoemajor == maj && d->aoeminor == min)
			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
	|| (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);
	if (d->bufpool)
		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;
}

