aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/message/i2o/exec-osm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/message/i2o/exec-osm.c')
-rw-r--r--drivers/message/i2o/exec-osm.c131
1 files changed, 95 insertions, 36 deletions
diff --git a/drivers/message/i2o/exec-osm.c b/drivers/message/i2o/exec-osm.c
index 79c1cbfb8f44..bda2c62648ba 100644
--- a/drivers/message/i2o/exec-osm.c
+++ b/drivers/message/i2o/exec-osm.c
@@ -30,6 +30,7 @@
30#include <linux/module.h> 30#include <linux/module.h>
31#include <linux/i2o.h> 31#include <linux/i2o.h>
32#include <linux/delay.h> 32#include <linux/delay.h>
33#include "core.h"
33 34
34#define OSM_NAME "exec-osm" 35#define OSM_NAME "exec-osm"
35 36
@@ -37,9 +38,6 @@ struct i2o_driver i2o_exec_driver;
37 38
38static int i2o_exec_lct_notify(struct i2o_controller *c, u32 change_ind); 39static int i2o_exec_lct_notify(struct i2o_controller *c, u32 change_ind);
39 40
40/* Module internal functions from other sources */
41extern int i2o_device_parse_lct(struct i2o_controller *);
42
43/* global wait list for POST WAIT */ 41/* global wait list for POST WAIT */
44static LIST_HEAD(i2o_exec_wait_list); 42static LIST_HEAD(i2o_exec_wait_list);
45 43
@@ -50,7 +48,7 @@ struct i2o_exec_wait {
50 u32 tcntxt; /* transaction context from reply */ 48 u32 tcntxt; /* transaction context from reply */
51 int complete; /* 1 if reply received otherwise 0 */ 49 int complete; /* 1 if reply received otherwise 0 */
52 u32 m; /* message id */ 50 u32 m; /* message id */
53 struct i2o_message __iomem *msg; /* pointer to the reply message */ 51 struct i2o_message *msg; /* pointer to the reply message */
54 struct list_head list; /* node in global wait list */ 52 struct list_head list; /* node in global wait list */
55}; 53};
56 54
@@ -108,7 +106,8 @@ static void i2o_exec_wait_free(struct i2o_exec_wait *wait)
108 * buffer must not be freed. Instead the event completion will free them 106 * buffer must not be freed. Instead the event completion will free them
109 * for you. In all other cases the buffer are your problem. 107 * for you. In all other cases the buffer are your problem.
110 * 108 *
111 * Returns 0 on success or negative error code on failure. 109 * Returns 0 on success, negative error code on timeout or positive error
110 * code from reply.
112 */ 111 */
113int i2o_msg_post_wait_mem(struct i2o_controller *c, u32 m, unsigned long 112int i2o_msg_post_wait_mem(struct i2o_controller *c, u32 m, unsigned long
114 timeout, struct i2o_dma *dma) 113 timeout, struct i2o_dma *dma)
@@ -116,7 +115,7 @@ int i2o_msg_post_wait_mem(struct i2o_controller *c, u32 m, unsigned long
116 DECLARE_WAIT_QUEUE_HEAD(wq); 115 DECLARE_WAIT_QUEUE_HEAD(wq);
117 struct i2o_exec_wait *wait; 116 struct i2o_exec_wait *wait;
118 static u32 tcntxt = 0x80000000; 117 static u32 tcntxt = 0x80000000;
119 struct i2o_message __iomem *msg = c->in_queue.virt + m; 118 struct i2o_message __iomem *msg = i2o_msg_in_to_virt(c, m);
120 int rc = 0; 119 int rc = 0;
121 120
122 wait = i2o_exec_wait_alloc(); 121 wait = i2o_exec_wait_alloc();
@@ -153,7 +152,7 @@ int i2o_msg_post_wait_mem(struct i2o_controller *c, u32 m, unsigned long
153 list_add(&wait->list, &i2o_exec_wait_list); 152 list_add(&wait->list, &i2o_exec_wait_list);
154 153
155 wait_event_interruptible_timeout(wq, wait->complete, 154 wait_event_interruptible_timeout(wq, wait->complete,
156 timeout * HZ); 155 timeout * HZ);
157 156
158 wait->wq = NULL; 157 wait->wq = NULL;
159 } 158 }
@@ -161,8 +160,7 @@ int i2o_msg_post_wait_mem(struct i2o_controller *c, u32 m, unsigned long
161 barrier(); 160 barrier();
162 161
163 if (wait->complete) { 162 if (wait->complete) {
164 if (readl(&wait->msg->body[0]) >> 24) 163 rc = le32_to_cpu(wait->msg->body[0]) >> 24;
165 rc = readl(&wait->msg->body[0]) & 0xff;
166 i2o_flush_reply(c, wait->m); 164 i2o_flush_reply(c, wait->m);
167 i2o_exec_wait_free(wait); 165 i2o_exec_wait_free(wait);
168 } else { 166 } else {
@@ -187,6 +185,7 @@ int i2o_msg_post_wait_mem(struct i2o_controller *c, u32 m, unsigned long
187 * @c: I2O controller which answers 185 * @c: I2O controller which answers
188 * @m: message id 186 * @m: message id
189 * @msg: pointer to the I2O reply message 187 * @msg: pointer to the I2O reply message
188 * @context: transaction context of request
190 * 189 *
191 * This function is called in interrupt context only. If the reply reached 190 * This function is called in interrupt context only. If the reply reached
192 * before the timeout, the i2o_exec_wait struct is filled with the message 191 * before the timeout, the i2o_exec_wait struct is filled with the message
@@ -201,16 +200,12 @@ int i2o_msg_post_wait_mem(struct i2o_controller *c, u32 m, unsigned long
201 * message must also be given back to the controller. 200 * message must also be given back to the controller.
202 */ 201 */
203static int i2o_msg_post_wait_complete(struct i2o_controller *c, u32 m, 202static int i2o_msg_post_wait_complete(struct i2o_controller *c, u32 m,
204 struct i2o_message __iomem *msg) 203 struct i2o_message *msg, u32 context)
205{ 204{
206 struct i2o_exec_wait *wait, *tmp; 205 struct i2o_exec_wait *wait, *tmp;
207 static spinlock_t lock; 206 unsigned long flags;
207 static spinlock_t lock = SPIN_LOCK_UNLOCKED;
208 int rc = 1; 208 int rc = 1;
209 u32 context;
210
211 spin_lock_init(&lock);
212
213 context = readl(&msg->u.s.tcntxt);
214 209
215 /* 210 /*
216 * We need to search through the i2o_exec_wait_list to see if the given 211 * We need to search through the i2o_exec_wait_list to see if the given
@@ -219,11 +214,13 @@ static int i2o_msg_post_wait_complete(struct i2o_controller *c, u32 m,
219 * already expired. Not much we can do about that except log it for 214 * already expired. Not much we can do about that except log it for
220 * debug purposes, increase timeout, and recompile. 215 * debug purposes, increase timeout, and recompile.
221 */ 216 */
222 spin_lock(&lock); 217 spin_lock_irqsave(&lock, flags);
223 list_for_each_entry_safe(wait, tmp, &i2o_exec_wait_list, list) { 218 list_for_each_entry_safe(wait, tmp, &i2o_exec_wait_list, list) {
224 if (wait->tcntxt == context) { 219 if (wait->tcntxt == context) {
225 list_del(&wait->list); 220 list_del(&wait->list);
226 221
222 spin_unlock_irqrestore(&lock, flags);
223
227 wait->m = m; 224 wait->m = m;
228 wait->msg = msg; 225 wait->msg = msg;
229 wait->complete = 1; 226 wait->complete = 1;
@@ -245,21 +242,63 @@ static int i2o_msg_post_wait_complete(struct i2o_controller *c, u32 m,
245 rc = -1; 242 rc = -1;
246 } 243 }
247 244
248 spin_unlock(&lock);
249
250 return rc; 245 return rc;
251 } 246 }
252 } 247 }
253 248
254 spin_unlock(&lock); 249 spin_unlock_irqrestore(&lock, flags);
255 250
256 pr_debug("%s: Bogus reply in POST WAIT (tr-context: %08x)!\n", c->name, 251 osm_warn("%s: Bogus reply in POST WAIT (tr-context: %08x)!\n", c->name,
257 context); 252 context);
258 253
259 return -1; 254 return -1;
260}; 255};
261 256
262/** 257/**
258 * i2o_exec_show_vendor_id - Displays Vendor ID of controller
259 * @d: device of which the Vendor ID should be displayed
260 * @buf: buffer into which the Vendor ID should be printed
261 *
262 * Returns number of bytes printed into buffer.
263 */
264static ssize_t i2o_exec_show_vendor_id(struct device *d, struct device_attribute *attr, char *buf)
265{
266 struct i2o_device *dev = to_i2o_device(d);
267 u16 id;
268
269 if (i2o_parm_field_get(dev, 0x0000, 0, &id, 2)) {
270 sprintf(buf, "0x%04x", id);
271 return strlen(buf) + 1;
272 }
273
274 return 0;
275};
276
277/**
278 * i2o_exec_show_product_id - Displays Product ID of controller
279 * @d: device of which the Product ID should be displayed
280 * @buf: buffer into which the Product ID should be printed
281 *
282 * Returns number of bytes printed into buffer.
283 */
284static ssize_t i2o_exec_show_product_id(struct device *d, struct device_attribute *attr, char *buf)
285{
286 struct i2o_device *dev = to_i2o_device(d);
287 u16 id;
288
289 if (i2o_parm_field_get(dev, 0x0000, 1, &id, 2)) {
290 sprintf(buf, "0x%04x", id);
291 return strlen(buf) + 1;
292 }
293
294 return 0;
295};
296
297/* Exec-OSM device attributes */
298static DEVICE_ATTR(vendor_id, S_IRUGO, i2o_exec_show_vendor_id, NULL);
299static DEVICE_ATTR(product_id, S_IRUGO, i2o_exec_show_product_id, NULL);
300
301/**
263 * i2o_exec_probe - Called if a new I2O device (executive class) appears 302 * i2o_exec_probe - Called if a new I2O device (executive class) appears
264 * @dev: I2O device which should be probed 303 * @dev: I2O device which should be probed
265 * 304 *
@@ -271,10 +310,16 @@ static int i2o_msg_post_wait_complete(struct i2o_controller *c, u32 m,
271static int i2o_exec_probe(struct device *dev) 310static int i2o_exec_probe(struct device *dev)
272{ 311{
273 struct i2o_device *i2o_dev = to_i2o_device(dev); 312 struct i2o_device *i2o_dev = to_i2o_device(dev);
313 struct i2o_controller *c = i2o_dev->iop;
274 314
275 i2o_event_register(i2o_dev, &i2o_exec_driver, 0, 0xffffffff); 315 i2o_event_register(i2o_dev, &i2o_exec_driver, 0, 0xffffffff);
276 316
277 i2o_dev->iop->exec = i2o_dev; 317 c->exec = i2o_dev;
318
319 i2o_exec_lct_notify(c, c->lct->change_ind + 1);
320
321 device_create_file(dev, &dev_attr_vendor_id);
322 device_create_file(dev, &dev_attr_product_id);
278 323
279 return 0; 324 return 0;
280}; 325};
@@ -289,6 +334,9 @@ static int i2o_exec_probe(struct device *dev)
289 */ 334 */
290static int i2o_exec_remove(struct device *dev) 335static int i2o_exec_remove(struct device *dev)
291{ 336{
337 device_remove_file(dev, &dev_attr_product_id);
338 device_remove_file(dev, &dev_attr_vendor_id);
339
292 i2o_event_register(to_i2o_device(dev), &i2o_exec_driver, 0, 0); 340 i2o_event_register(to_i2o_device(dev), &i2o_exec_driver, 0, 0);
293 341
294 return 0; 342 return 0;
@@ -300,12 +348,16 @@ static int i2o_exec_remove(struct device *dev)
300 * 348 *
301 * This function handles asynchronus LCT NOTIFY replies. It parses the 349 * This function handles asynchronus LCT NOTIFY replies. It parses the
302 * new LCT and if the buffer for the LCT was to small sends a LCT NOTIFY 350 * new LCT and if the buffer for the LCT was to small sends a LCT NOTIFY
303 * again. 351 * again, otherwise send LCT NOTIFY to get informed on next LCT change.
304 */ 352 */
305static void i2o_exec_lct_modified(struct i2o_controller *c) 353static void i2o_exec_lct_modified(struct i2o_controller *c)
306{ 354{
307 if (i2o_device_parse_lct(c) == -EAGAIN) 355 u32 change_ind = 0;
308 i2o_exec_lct_notify(c, 0); 356
357 if (i2o_device_parse_lct(c) != -EAGAIN)
358 change_ind = c->lct->change_ind + 1;
359
360 i2o_exec_lct_notify(c, change_ind);
309}; 361};
310 362
311/** 363/**
@@ -325,8 +377,14 @@ static void i2o_exec_lct_modified(struct i2o_controller *c)
325static int i2o_exec_reply(struct i2o_controller *c, u32 m, 377static int i2o_exec_reply(struct i2o_controller *c, u32 m,
326 struct i2o_message *msg) 378 struct i2o_message *msg)
327{ 379{
328 if (le32_to_cpu(msg->u.head[0]) & MSG_FAIL) { // Fail bit is set 380 u32 context;
329 struct i2o_message __iomem *pmsg; /* preserved message */ 381
382 if (le32_to_cpu(msg->u.head[0]) & MSG_FAIL) {
383 /*
384 * If Fail bit is set we must take the transaction context of
385 * the preserved message to find the right request again.
386 */
387 struct i2o_message __iomem *pmsg;
330 u32 pm; 388 u32 pm;
331 389
332 pm = le32_to_cpu(msg->body[3]); 390 pm = le32_to_cpu(msg->body[3]);
@@ -335,15 +393,15 @@ static int i2o_exec_reply(struct i2o_controller *c, u32 m,
335 393
336 i2o_report_status(KERN_INFO, "i2o_core", msg); 394 i2o_report_status(KERN_INFO, "i2o_core", msg);
337 395
338 /* Release the preserved msg by resubmitting it as a NOP */ 396 context = readl(&pmsg->u.s.tcntxt);
339 i2o_msg_nop(c, pm);
340 397
341 /* If reply to i2o_post_wait failed, return causes a timeout */ 398 /* Release the preserved msg */
342 return -1; 399 i2o_msg_nop(c, pm);
343 } 400 } else
401 context = le32_to_cpu(msg->u.s.tcntxt);
344 402
345 if (le32_to_cpu(msg->u.s.tcntxt) & 0x80000000) 403 if (context & 0x80000000)
346 return i2o_msg_post_wait_complete(c, m, msg); 404 return i2o_msg_post_wait_complete(c, m, msg, context);
347 405
348 if ((le32_to_cpu(msg->u.head[1]) >> 24) == I2O_CMD_LCT_NOTIFY) { 406 if ((le32_to_cpu(msg->u.head[1]) >> 24) == I2O_CMD_LCT_NOTIFY) {
349 struct work_struct *work; 407 struct work_struct *work;
@@ -381,8 +439,9 @@ static int i2o_exec_reply(struct i2o_controller *c, u32 m,
381 */ 439 */
382static void i2o_exec_event(struct i2o_event *evt) 440static void i2o_exec_event(struct i2o_event *evt)
383{ 441{
384 osm_info("Event received from device: %d\n", 442 if (likely(evt->i2o_dev))
385 evt->i2o_dev->lct_data.tid); 443 osm_debug("Event received from device: %d\n",
444 evt->i2o_dev->lct_data.tid);
386 kfree(evt); 445 kfree(evt);
387}; 446};
388 447