/*
 * Copyright (C) 2004 Red Hat, Inc. All rights reserved.
 *
 * This file is released under the GPL.
 *
 * Multipath hardware handler registration.
 */

#include "dm.h"
#include "dm-hw-handler.h"

#include <linux/slab.h>

struct hwh_internal {
	struct hw_handler_type hwht;

	struct list_head list;
	long use;
};

#define hwht_to_hwhi(__hwht) container_of((__hwht), struct hwh_internal, hwht)

static LIST_HEAD(_hw_handlers);
static DECLARE_RWSEM(_hwh_lock);

static struct hwh_internal *__find_hw_handler_type(const char *name)
{
	struct hwh_internal *hwhi;

	list_for_each_entry(hwhi, &_hw_handlers, list) {
		if (!strcmp(name, hwhi->hwht.name))
			return hwhi;
	}

	return NULL;
}

static struct hwh_internal *get_hw_handler(const char *name)
{
	struct hwh_internal *hwhi;

	down_read(&_hwh_lock);
	hwhi = __find_hw_handler_type(name);
	if (hwhi) {
		if ((hwhi->use == 0) && !try_module_get(hwhi->hwht.module))
			hwhi = NULL;
		else
			hwhi->use++;
	}
	up_read(&_hwh_lock);

	return hwhi;
}

struct hw_handler_type *dm_get_hw_handler(const char *name)
{
	struct hwh_internal *hwhi;

	if (!name)
		return NULL;

	hwhi = get_hw_handler(name);
	if (!hwhi) {
		request_module("dm-%s", name);
		hwhi = get_hw_handler(name);
	}

	return hwhi ? &hwhi->hwht : NULL;
}

void dm_put_hw_handler(struct hw_handler_type *hwht)
{
	struct hwh_internal *hwhi;

	if (!hwht)
		return;

	down_read(&_hwh_lock);
	hwhi = __find_hw_handler_type(hwht->name);
	if (!hwhi)
		goto out;

	if (--hwhi->use == 0)
		module_put(hwhi->hwht.module);

	BUG_ON(hwhi->use < 0);

      out:
	up_read(&_hwh_lock);
}

static struct hwh_internal *_alloc_hw_handler(struct hw_handler_type *hwht)
{
	struct hwh_internal *hwhi = kmalloc(sizeof(*hwhi), GFP_KERNEL);

	if (hwhi) {
		memset(hwhi, 0, sizeof(*hwhi));
		hwhi->hwht = *hwht;
	}

	return hwhi;
}

int dm_register_hw_handler(struct hw_handler_type *hwht)
{
	int r = 0;
	struct hwh_internal *hwhi = _alloc_hw_handler(hwht);

	if (!hwhi)
		return -ENOMEM;

	down_write(&_hwh_lock);

	if (__find_hw_handler_type(hwht->name)) {
		kfree(hwhi);
		r = -EEXIST;
	} else
		list_add(&hwhi->list, &_hw_handlers);

	up_write(&_hwh_lock);

	return r;
}

int dm_unregister_hw_handler(struct hw_handler_type *hwht)
{
	struct hwh_internal *hwhi;

	down_write(&_hwh_lock);

	hwhi = __find_hw_handler_type(hwht->name);
	if (!hwhi) {
		up_write(&_hwh_lock);
		return -EINVAL;
	}

	if (hwhi->use) {
		up_write(&_hwh_lock);
		return -ETXTBSY;
	}

	list_del(&hwhi->list);

	up_write(&_hwh_lock);

	kfree(hwhi);

	return 0;
}

unsigned dm_scsi_err_handler(struct hw_handler *hwh, struct bio *bio)
{
#if 0
	int sense_key, asc, ascq;

	if (bio->bi_error & BIO_SENSE) {
		/* FIXME: This is just an initial guess. */
		/* key / asc / ascq */
		sense_key = (bio->bi_error >> 16) & 0xff;
		asc = (bio->bi_error >> 8) & 0xff;
		ascq = bio->bi_error & 0xff;

		switch (sense_key) {
			/* This block as a whole comes from the device.
			 * So no point retrying on another path. */
		case 0x03:	/* Medium error */
		case 0x05:	/* Illegal request */
		case 0x07:	/* Data protect */
		case 0x08:	/* Blank check */
		case 0x0a:	/* copy aborted */
		case 0x0c:	/* obsolete - no clue ;-) */
		case 0x0d:	/* volume overflow */
		case 0x0e:	/* data miscompare */
		case 0x0f:	/* reserved - no idea either. */
			return MP_ERROR_IO;

			/* For these errors it's unclear whether they
			 * come from the device or the controller.
			 * So just lets try a different path, and if
			 * it eventually succeeds, user-space will clear
			 * the paths again... */
		case 0x02:	/* Not ready */
		case 0x04:	/* Hardware error */
		case 0x09:	/* vendor specific */
		case 0x0b:	/* Aborted command */
			return MP_FAIL_PATH;

		case 0x06:	/* Unit attention - might want to decode */
			if (asc == 0x04 && ascq == 0x01)
				/* "Unit in the process of
				 * becoming ready" */
				return 0;
			return MP_FAIL_PATH;

			/* FIXME: For Unit Not Ready we may want
			 * to have a generic pg activation
			 * feature (START_UNIT). */

			/* Should these two ever end up in the
			 * error path? I don't think so. */
		case 0x00:	/* No sense */
		case 0x01:	/* Recovered error */
			return 0;
		}
	}
#endif

	/* We got no idea how to decode the other kinds of errors ->
	 * assume generic error condition. */
	return MP_FAIL_PATH;
}

EXPORT_SYMBOL_GPL(dm_register_hw_handler);
EXPORT_SYMBOL_GPL(dm_unregister_hw_handler);
EXPORT_SYMBOL_GPL(dm_scsi_err_handler);
