/* Copyright (c) 2006 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;

int
aoedev_isbusy(struct aoedev *d)
{
	struct frame *f, *e;

	f = d->frames;
	e = f + d->nframes;
	do {
		if (f->tag != FREETAG)
			return 1;
	} while (++f < e);

	return 0;
}

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

static void
dummy_timer(ulong vp)
{
	struct aoedev *d;

	d = (struct aoedev *)vp;
	if (d->flags & DEVFL_TKILL)
		return;
	d->timer.expires = jiffies + HZ;
	add_timer(&d->timer);
}

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

	d = kzalloc(sizeof *d, GFP_ATOMIC);
	f = kcalloc(nframes, sizeof *f, GFP_ATOMIC);
 	switch (!d || !f) {
 	case 0:
 		d->nframes = nframes;
 		d->frames = f;
 		e = f + nframes;
 		for (; f<e; f++) {
 			f->tag = FREETAG;
 			f->skb = new_skb(ETH_ZLEN);
 			if (!f->skb)
 				break;
 		}
 		if (f == e)
 			break;
 		while (f > d->frames) {
 			f--;
 			dev_kfree_skb(f->skb);
 		}
 	default:
 		if (f)
 			kfree(f);
 		if (d)
 			kfree(d);
		return NULL;
	}
	INIT_WORK(&d->work, aoecmd_sleepwork, d);
	spin_lock_init(&d->lock);
	init_timer(&d->timer);
	d->timer.data = (ulong) d;
	d->timer.function = dummy_timer;
	d->timer.expires = jiffies + HZ;
	add_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;

	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);
		}
		skb_shinfo(f->skb)->nr_frags = f->skb->data_len = 0;
	}
	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->gd)
		d->gd->capacity = 0;

	d->flags &= ~(DEVFL_UP | DEVFL_PAUSE);
}

/* find it or malloc it */
struct aoedev *
aoedev_by_sysminor_m(ulong sysminor, ulong bufcnt)
{
	struct aoedev *d;
	ulong flags;

	spin_lock_irqsave(&devlist_lock, flags);

	for (d=devlist; d; d=d->next)
		if (d->sysminor == sysminor)
			break;

	if (d == NULL) {
		d = aoedev_newdev(bufcnt);
	 	if (d == NULL) {
			spin_unlock_irqrestore(&devlist_lock, flags);
			printk(KERN_INFO "aoe: aoedev_newdev failure.\n");
			return NULL;
		}
		d->sysminor = sysminor;
		d->aoemajor = AOEMAJOR(sysminor);
		d->aoeminor = AOEMINOR(sysminor);
	}

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

static void
aoedev_freedev(struct aoedev *d)
{
	struct frame *f, *e;

	if (d->gd) {
		aoedisk_rm_sysfs(d);
		del_gendisk(d->gd);
		put_disk(d->gd);
	}
	f = d->frames;
	e = f + d->nframes;
	for (; f<e; f++) {
		skb_shinfo(f->skb)->nr_frags = 0;
		dev_kfree_skb(f->skb);
	}
	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);
		d->flags |= DEVFL_TKILL;
		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;
}

