/*
 * 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);

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

	if (hwhi->use < 0)
		BUG();

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