diff options
Diffstat (limited to 'drivers/message/i2o/bus-osm.c')
-rw-r--r-- | drivers/message/i2o/bus-osm.c | 164 |
1 files changed, 164 insertions, 0 deletions
diff --git a/drivers/message/i2o/bus-osm.c b/drivers/message/i2o/bus-osm.c new file mode 100644 index 000000000000..d43c35894ae9 --- /dev/null +++ b/drivers/message/i2o/bus-osm.c | |||
@@ -0,0 +1,164 @@ | |||
1 | /* | ||
2 | * Bus Adapter OSM | ||
3 | * | ||
4 | * Copyright (C) 2005 Markus Lidel <Markus.Lidel@shadowconnect.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License as published by the | ||
8 | * Free Software Foundation; either version 2 of the License, or (at your | ||
9 | * option) any later version. | ||
10 | * | ||
11 | * Fixes/additions: | ||
12 | * Markus Lidel <Markus.Lidel@shadowconnect.com> | ||
13 | * initial version. | ||
14 | */ | ||
15 | |||
16 | #include <linux/module.h> | ||
17 | #include <linux/i2o.h> | ||
18 | |||
19 | #define OSM_NAME "bus-osm" | ||
20 | #define OSM_VERSION "$Rev$" | ||
21 | #define OSM_DESCRIPTION "I2O Bus Adapter OSM" | ||
22 | |||
23 | static struct i2o_driver i2o_bus_driver; | ||
24 | |||
25 | /* Bus OSM class handling definition */ | ||
26 | static struct i2o_class_id i2o_bus_class_id[] = { | ||
27 | {I2O_CLASS_BUS_ADAPTER}, | ||
28 | {I2O_CLASS_END} | ||
29 | }; | ||
30 | |||
31 | /** | ||
32 | * i2o_bus_scan - Scan the bus for new devices | ||
33 | * @dev: I2O device of the bus, which should be scanned | ||
34 | * | ||
35 | * Scans the bus dev for new / removed devices. After the scan a new LCT | ||
36 | * will be fetched automatically. | ||
37 | * | ||
38 | * Returns 0 on success or negative error code on failure. | ||
39 | */ | ||
40 | static int i2o_bus_scan(struct i2o_device *dev) | ||
41 | { | ||
42 | struct i2o_message __iomem *msg; | ||
43 | u32 m; | ||
44 | |||
45 | m = i2o_msg_get_wait(dev->iop, &msg, I2O_TIMEOUT_MESSAGE_GET); | ||
46 | if (m == I2O_QUEUE_EMPTY) | ||
47 | return -ETIMEDOUT; | ||
48 | |||
49 | writel(FIVE_WORD_MSG_SIZE | SGL_OFFSET_0, &msg->u.head[0]); | ||
50 | writel(I2O_CMD_BUS_SCAN << 24 | HOST_TID << 12 | dev->lct_data.tid, | ||
51 | &msg->u.head[1]); | ||
52 | |||
53 | return i2o_msg_post_wait(dev->iop, m, 60); | ||
54 | }; | ||
55 | |||
56 | /** | ||
57 | * i2o_bus_store_scan - Scan the I2O Bus Adapter | ||
58 | * @d: device which should be scanned | ||
59 | * | ||
60 | * Returns count. | ||
61 | */ | ||
62 | static ssize_t i2o_bus_store_scan(struct device *d, const char *buf, | ||
63 | size_t count) | ||
64 | { | ||
65 | struct i2o_device *i2o_dev = to_i2o_device(d); | ||
66 | int rc; | ||
67 | |||
68 | if ((rc = i2o_bus_scan(i2o_dev))) | ||
69 | osm_warn("bus scan failed %d\n", rc); | ||
70 | |||
71 | return count; | ||
72 | } | ||
73 | |||
74 | /* Bus Adapter OSM device attributes */ | ||
75 | static DEVICE_ATTR(scan, S_IWUSR, NULL, i2o_bus_store_scan); | ||
76 | |||
77 | /** | ||
78 | * i2o_bus_probe - verify if dev is a I2O Bus Adapter device and install it | ||
79 | * @dev: device to verify if it is a I2O Bus Adapter device | ||
80 | * | ||
81 | * Because we want all Bus Adapters always return 0. | ||
82 | * | ||
83 | * Returns 0. | ||
84 | */ | ||
85 | static int i2o_bus_probe(struct device *dev) | ||
86 | { | ||
87 | struct i2o_device *i2o_dev = to_i2o_device(get_device(dev)); | ||
88 | |||
89 | device_create_file(dev, &dev_attr_scan); | ||
90 | |||
91 | osm_info("device added (TID: %03x)\n", i2o_dev->lct_data.tid); | ||
92 | |||
93 | return 0; | ||
94 | }; | ||
95 | |||
96 | /** | ||
97 | * i2o_bus_remove - remove the I2O Bus Adapter device from the system again | ||
98 | * @dev: I2O Bus Adapter device which should be removed | ||
99 | * | ||
100 | * Always returns 0. | ||
101 | */ | ||
102 | static int i2o_bus_remove(struct device *dev) | ||
103 | { | ||
104 | struct i2o_device *i2o_dev = to_i2o_device(dev); | ||
105 | |||
106 | device_remove_file(dev, &dev_attr_scan); | ||
107 | |||
108 | put_device(dev); | ||
109 | |||
110 | osm_info("device removed (TID: %03x)\n", i2o_dev->lct_data.tid); | ||
111 | |||
112 | return 0; | ||
113 | }; | ||
114 | |||
115 | /* Bus Adapter OSM driver struct */ | ||
116 | static struct i2o_driver i2o_bus_driver = { | ||
117 | .name = OSM_NAME, | ||
118 | .classes = i2o_bus_class_id, | ||
119 | .driver = { | ||
120 | .probe = i2o_bus_probe, | ||
121 | .remove = i2o_bus_remove, | ||
122 | }, | ||
123 | }; | ||
124 | |||
125 | /** | ||
126 | * i2o_bus_init - Bus Adapter OSM initialization function | ||
127 | * | ||
128 | * Only register the Bus Adapter OSM in the I2O core. | ||
129 | * | ||
130 | * Returns 0 on success or negative error code on failure. | ||
131 | */ | ||
132 | static int __init i2o_bus_init(void) | ||
133 | { | ||
134 | int rc; | ||
135 | |||
136 | printk(KERN_INFO OSM_DESCRIPTION " v" OSM_VERSION "\n"); | ||
137 | |||
138 | /* Register Bus Adapter OSM into I2O core */ | ||
139 | rc = i2o_driver_register(&i2o_bus_driver); | ||
140 | if (rc) { | ||
141 | osm_err("Could not register Bus Adapter OSM\n"); | ||
142 | return rc; | ||
143 | } | ||
144 | |||
145 | return 0; | ||
146 | }; | ||
147 | |||
148 | /** | ||
149 | * i2o_bus_exit - Bus Adapter OSM exit function | ||
150 | * | ||
151 | * Unregisters Bus Adapter OSM from I2O core. | ||
152 | */ | ||
153 | static void __exit i2o_bus_exit(void) | ||
154 | { | ||
155 | i2o_driver_unregister(&i2o_bus_driver); | ||
156 | }; | ||
157 | |||
158 | MODULE_AUTHOR("Markus Lidel <Markus.Lidel@shadowconnect.com>"); | ||
159 | MODULE_LICENSE("GPL"); | ||
160 | MODULE_DESCRIPTION(OSM_DESCRIPTION); | ||
161 | MODULE_VERSION(OSM_VERSION); | ||
162 | |||
163 | module_init(i2o_bus_init); | ||
164 | module_exit(i2o_bus_exit); | ||