/* Copyright (c) 2004 Coraid, Inc.  See COPYING for GPL terms. */
/*
 * aoeblk.c
 * block device routines
 */

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

static kmem_cache_t *buf_pool_cache;

/* add attributes for our block devices in sysfs */
static ssize_t aoedisk_show_state(struct gendisk * disk, char *page)
{
	struct aoedev *d = disk->private_data;

	return snprintf(page, PAGE_SIZE,
			"%s%s\n",
			(d->flags & DEVFL_UP) ? "up" : "down",
			(d->flags & DEVFL_CLOSEWAIT) ? ",closewait" : "");
}
static ssize_t aoedisk_show_mac(struct gendisk * disk, char *page)
{
	struct aoedev *d = disk->private_data;

	return snprintf(page, PAGE_SIZE, "%012llx\n",
			(unsigned long long)mac_addr(d->addr));
}
static ssize_t aoedisk_show_netif(struct gendisk * disk, char *page)
{
	struct aoedev *d = disk->private_data;

	return snprintf(page, PAGE_SIZE, "%s\n", d->ifp->name);
}
/* firmware version */
static ssize_t aoedisk_show_fwver(struct gendisk * disk, char *page)
{
	struct aoedev *d = disk->private_data;

	return snprintf(page, PAGE_SIZE, "0x%04x\n", (unsigned int) d->fw_ver);
}

static struct disk_attribute disk_attr_state = {
	.attr = {.name = "state", .mode = S_IRUGO },
	.show = aoedisk_show_state
};
static struct disk_attribute disk_attr_mac = {
	.attr = {.name = "mac", .mode = S_IRUGO },
	.show = aoedisk_show_mac
};
static struct disk_attribute disk_attr_netif = {
	.attr = {.name = "netif", .mode = S_IRUGO },
	.show = aoedisk_show_netif
};
static struct disk_attribute disk_attr_fwver = {
	.attr = {.name = "firmware-version", .mode = S_IRUGO },
	.show = aoedisk_show_fwver
};

static void
aoedisk_add_sysfs(struct aoedev *d)
{
	sysfs_create_file(&d->gd->kobj, &disk_attr_state.attr);
	sysfs_create_file(&d->gd->kobj, &disk_attr_mac.attr);
	sysfs_create_file(&d->gd->kobj, &disk_attr_netif.attr);
	sysfs_create_file(&d->gd->kobj, &disk_attr_fwver.attr);
}
void
aoedisk_rm_sysfs(struct aoedev *d)
{
	sysfs_remove_link(&d->gd->kobj, "state");
	sysfs_remove_link(&d->gd->kobj, "mac");
	sysfs_remove_link(&d->gd->kobj, "netif");
	sysfs_remove_link(&d->gd->kobj, "firmware-version");
}

static int
aoeblk_open(struct inode *inode, struct file *filp)
{
	struct aoedev *d;
	ulong flags;

	d = inode->i_bdev->bd_disk->private_data;

	spin_lock_irqsave(&d->lock, flags);
	if (d->flags & DEVFL_UP) {
		d->nopen++;
		spin_unlock_irqrestore(&d->lock, flags);
		return 0;
	}
	spin_unlock_irqrestore(&d->lock, flags);
	return -ENODEV;
}

static int
aoeblk_release(struct inode *inode, struct file *filp)
{
	struct aoedev *d;
	ulong flags;

	d = inode->i_bdev->bd_disk->private_data;

	spin_lock_irqsave(&d->lock, flags);

	if (--d->nopen == 0 && (d->flags & DEVFL_CLOSEWAIT)) {
		d->flags &= ~DEVFL_CLOSEWAIT;
		spin_unlock_irqrestore(&d->lock, flags);
		aoecmd_cfg(d->aoemajor, d->aoeminor);
		return 0;
	}
	spin_unlock_irqrestore(&d->lock, flags);

	return 0;
}

static int
aoeblk_make_request(request_queue_t *q, struct bio *bio)
{
	struct aoedev *d;
	struct buf *buf;
	struct sk_buff *sl;
	ulong flags;

	blk_queue_bounce(q, &bio);

	d = bio->bi_bdev->bd_disk->private_data;
	buf = mempool_alloc(d->bufpool, GFP_NOIO);
	if (buf == NULL) {
		printk(KERN_INFO "aoe: aoeblk_make_request: buf allocation "
			"failure\n");
		bio_endio(bio, bio->bi_size, -ENOMEM);
		return 0;
	}
	memset(buf, 0, sizeof(*buf));
	INIT_LIST_HEAD(&buf->bufs);
	buf->start_time = jiffies;
	buf->bio = bio;
	buf->resid = bio->bi_size;
	buf->sector = bio->bi_sector;
	buf->bv = buf->bio->bi_io_vec;
	buf->bv_resid = buf->bv->bv_len;
	buf->bufaddr = page_address(buf->bv->bv_page) + buf->bv->bv_offset;

	spin_lock_irqsave(&d->lock, flags);

	if ((d->flags & DEVFL_UP) == 0) {
		printk(KERN_INFO "aoe: aoeblk_make_request: device %ld.%ld is not up\n",
			d->aoemajor, d->aoeminor);
		spin_unlock_irqrestore(&d->lock, flags);
		mempool_free(buf, d->bufpool);
		bio_endio(bio, bio->bi_size, -ENXIO);
		return 0;
	}

	list_add_tail(&buf->bufs, &d->bufq);
	aoecmd_work(d);

	sl = d->sendq_hd;
	d->sendq_hd = d->sendq_tl = NULL;

	spin_unlock_irqrestore(&d->lock, flags);

	aoenet_xmit(sl);
	return 0;
}

/* This ioctl implementation expects userland to have the device node
 * permissions set so that only priviledged users can open an aoe
 * block device directly.
 */
static int
aoeblk_ioctl(struct inode *inode, struct file *filp, uint cmd, ulong arg)
{
	struct aoedev *d;

	if (!arg)
		return -EINVAL;

	d = inode->i_bdev->bd_disk->private_data;
	if ((d->flags & DEVFL_UP) == 0) {
		printk(KERN_ERR "aoe: aoeblk_ioctl: disk not up\n");
		return -ENODEV;
	}

	if (cmd == HDIO_GETGEO) {
		d->geo.start = get_start_sect(inode->i_bdev);
		if (!copy_to_user((void __user *) arg, &d->geo, sizeof d->geo))
			return 0;
		return -EFAULT;
	}
	printk(KERN_INFO "aoe: aoeblk_ioctl: unknown ioctl %d\n", cmd);
	return -EINVAL;
}

static struct block_device_operations aoe_bdops = {
	.open = aoeblk_open,
	.release = aoeblk_release,
	.ioctl = aoeblk_ioctl,
	.owner = THIS_MODULE,
};

/* alloc_disk and add_disk can sleep */
void
aoeblk_gdalloc(void *vp)
{
	struct aoedev *d = vp;
	struct gendisk *gd;
	ulong flags;

	gd = alloc_disk(AOE_PARTITIONS);
	if (gd == NULL) {
		printk(KERN_ERR "aoe: aoeblk_gdalloc: cannot allocate disk "
			"structure for %ld.%ld\n", d->aoemajor, d->aoeminor);
		spin_lock_irqsave(&d->lock, flags);
		d->flags &= ~DEVFL_WORKON;
		spin_unlock_irqrestore(&d->lock, flags);
		return;
	}

	d->bufpool = mempool_create(MIN_BUFS,
				    mempool_alloc_slab, mempool_free_slab,
				    buf_pool_cache);
	if (d->bufpool == NULL) {
		printk(KERN_ERR "aoe: aoeblk_gdalloc: cannot allocate bufpool "
			"for %ld.%ld\n", d->aoemajor, d->aoeminor);
		put_disk(gd);
		spin_lock_irqsave(&d->lock, flags);
		d->flags &= ~DEVFL_WORKON;
		spin_unlock_irqrestore(&d->lock, flags);
		return;
	}

	spin_lock_irqsave(&d->lock, flags);
	blk_queue_make_request(&d->blkq, aoeblk_make_request);
	gd->major = AOE_MAJOR;
	gd->first_minor = d->sysminor * AOE_PARTITIONS;
	gd->fops = &aoe_bdops;
	gd->private_data = d;
	gd->capacity = d->ssize;
	snprintf(gd->disk_name, sizeof gd->disk_name, "etherd/e%ld.%ld",
		d->aoemajor, d->aoeminor);

	gd->queue = &d->blkq;
	d->gd = gd;
	d->flags &= ~DEVFL_WORKON;
	d->flags |= DEVFL_UP;

	spin_unlock_irqrestore(&d->lock, flags);

	add_disk(gd);
	aoedisk_add_sysfs(d);
	
	printk(KERN_INFO "aoe: %012llx e%lu.%lu v%04x has %llu "
		"sectors\n", (unsigned long long)mac_addr(d->addr),
		d->aoemajor, d->aoeminor,
		d->fw_ver, (long long)d->ssize);
}

void
aoeblk_exit(void)
{
	kmem_cache_destroy(buf_pool_cache);
}

int __init
aoeblk_init(void)
{
	buf_pool_cache = kmem_cache_create("aoe_bufs", 
					   sizeof(struct buf),
					   0, 0, NULL, NULL);
	if (buf_pool_cache == NULL)
		return -ENOMEM;

	return 0;
}

