bus-osm.c 4.0 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
/*
 *	Bus Adapter OSM
 *
 *	Copyright (C) 2005	Markus Lidel <Markus.Lidel@shadowconnect.com>
 *
 *	This program is free software; you can redistribute it and/or modify it
 *	under the terms of the GNU General Public License as published by the
 *	Free Software Foundation; either version 2 of the License, or (at your
 *	option) any later version.
 *
 *	Fixes/additions:
 *		Markus Lidel <Markus.Lidel@shadowconnect.com>
 *			initial version.
 */

#include <linux/module.h>
#include <linux/i2o.h>

#define OSM_NAME	"bus-osm"
M
Markus Lidel 已提交
20
#define OSM_VERSION	"1.317"
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
#define OSM_DESCRIPTION	"I2O Bus Adapter OSM"

static struct i2o_driver i2o_bus_driver;

/* Bus OSM class handling definition */
static struct i2o_class_id i2o_bus_class_id[] = {
	{I2O_CLASS_BUS_ADAPTER},
	{I2O_CLASS_END}
};

/**
 *	i2o_bus_scan - Scan the bus for new devices
 *	@dev: I2O device of the bus, which should be scanned
 *
 *	Scans the bus dev for new / removed devices. After the scan a new LCT
 *	will be fetched automatically.
 *
 *	Returns 0 on success or negative error code on failure.
 */
static int i2o_bus_scan(struct i2o_device *dev)
{
42
	struct i2o_message *msg;
43

44 45
	msg = i2o_msg_get_wait(dev->iop, I2O_TIMEOUT_MESSAGE_GET);
	if (IS_ERR(msg))
46 47
		return -ETIMEDOUT;

48 49 50 51
	msg->u.head[0] = cpu_to_le32(FIVE_WORD_MSG_SIZE | SGL_OFFSET_0);
	msg->u.head[1] =
	    cpu_to_le32(I2O_CMD_BUS_SCAN << 24 | HOST_TID << 12 | dev->lct_data.
			tid);
52

53
	return i2o_msg_post_wait(dev->iop, msg, 60);
54 55 56 57 58 59 60 61
};

/**
 *	i2o_bus_store_scan - Scan the I2O Bus Adapter
 *	@d: device which should be scanned
 *
 *	Returns count.
 */
62 63 64
static ssize_t i2o_bus_store_scan(struct device *d,
				  struct device_attribute *attr,
				  const char *buf, size_t count)
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
{
	struct i2o_device *i2o_dev = to_i2o_device(d);
	int rc;

	if ((rc = i2o_bus_scan(i2o_dev)))
		osm_warn("bus scan failed %d\n", rc);

	return count;
}

/* Bus Adapter OSM device attributes */
static DEVICE_ATTR(scan, S_IWUSR, NULL, i2o_bus_store_scan);

/**
 *	i2o_bus_probe - verify if dev is a I2O Bus Adapter device and install it
 *	@dev: device to verify if it is a I2O Bus Adapter device
 *
 *	Because we want all Bus Adapters always return 0.
83
 *	Except when we fail.  Then we are sad.
84
 *
85
 *	Returns 0, except when we fail to excel.
86 87 88 89
 */
static int i2o_bus_probe(struct device *dev)
{
	struct i2o_device *i2o_dev = to_i2o_device(get_device(dev));
90
	int rc;
91

92 93 94
	rc = device_create_file(dev, &dev_attr_scan);
	if (rc)
		goto err_out;
95 96 97 98

	osm_info("device added (TID: %03x)\n", i2o_dev->lct_data.tid);

	return 0;
99 100 101 102

err_out:
	put_device(dev);
	return rc;
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
};

/**
 *	i2o_bus_remove - remove the I2O Bus Adapter device from the system again
 *	@dev: I2O Bus Adapter device which should be removed
 *
 *	Always returns 0.
 */
static int i2o_bus_remove(struct device *dev)
{
	struct i2o_device *i2o_dev = to_i2o_device(dev);

	device_remove_file(dev, &dev_attr_scan);

	put_device(dev);

	osm_info("device removed (TID: %03x)\n", i2o_dev->lct_data.tid);

	return 0;
};

/* Bus Adapter OSM driver struct */
static struct i2o_driver i2o_bus_driver = {
	.name = OSM_NAME,
	.classes = i2o_bus_class_id,
	.driver = {
		   .probe = i2o_bus_probe,
		   .remove = i2o_bus_remove,
		   },
};

/**
 *	i2o_bus_init - Bus Adapter OSM initialization function
 *
 *	Only register the Bus Adapter OSM in the I2O core.
 *
 *	Returns 0 on success or negative error code on failure.
 */
static int __init i2o_bus_init(void)
{
	int rc;

	printk(KERN_INFO OSM_DESCRIPTION " v" OSM_VERSION "\n");

	/* Register Bus Adapter OSM into I2O core */
	rc = i2o_driver_register(&i2o_bus_driver);
	if (rc) {
		osm_err("Could not register Bus Adapter OSM\n");
		return rc;
	}

	return 0;
};

/**
 *	i2o_bus_exit - Bus Adapter OSM exit function
 *
 *	Unregisters Bus Adapter OSM from I2O core.
 */
static void __exit i2o_bus_exit(void)
{
	i2o_driver_unregister(&i2o_bus_driver);
};

MODULE_AUTHOR("Markus Lidel <Markus.Lidel@shadowconnect.com>");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION(OSM_DESCRIPTION);
MODULE_VERSION(OSM_VERSION);

module_init(i2o_bus_init);
module_exit(i2o_bus_exit);