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.c47
1 files changed, 26 insertions, 21 deletions
diff --git a/drivers/message/i2o/exec-osm.c b/drivers/message/i2o/exec-osm.c
index 1e28e886f1ca..5581344fbba6 100644
--- a/drivers/message/i2o/exec-osm.c
+++ b/drivers/message/i2o/exec-osm.c
@@ -108,7 +108,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 108 * buffer must not be freed. Instead the event completion will free them
109 * for you. In all other cases the buffer are your problem. 109 * for you. In all other cases the buffer are your problem.
110 * 110 *
111 * Returns 0 on success or negative error code on failure. 111 * Returns 0 on success, negative error code on timeout or positive error
112 * code from reply.
112 */ 113 */
113int i2o_msg_post_wait_mem(struct i2o_controller *c, u32 m, unsigned long 114int i2o_msg_post_wait_mem(struct i2o_controller *c, u32 m, unsigned long
114 timeout, struct i2o_dma *dma) 115 timeout, struct i2o_dma *dma)
@@ -116,7 +117,7 @@ int i2o_msg_post_wait_mem(struct i2o_controller *c, u32 m, unsigned long
116 DECLARE_WAIT_QUEUE_HEAD(wq); 117 DECLARE_WAIT_QUEUE_HEAD(wq);
117 struct i2o_exec_wait *wait; 118 struct i2o_exec_wait *wait;
118 static u32 tcntxt = 0x80000000; 119 static u32 tcntxt = 0x80000000;
119 struct i2o_message __iomem *msg = c->in_queue.virt + m; 120 struct i2o_message __iomem *msg = i2o_msg_in_to_virt(c, m);
120 int rc = 0; 121 int rc = 0;
121 122
122 wait = i2o_exec_wait_alloc(); 123 wait = i2o_exec_wait_alloc();
@@ -161,8 +162,7 @@ int i2o_msg_post_wait_mem(struct i2o_controller *c, u32 m, unsigned long
161 barrier(); 162 barrier();
162 163
163 if (wait->complete) { 164 if (wait->complete) {
164 if (readl(&wait->msg->body[0]) >> 24) 165 rc = readl(&wait->msg->body[0]) >> 24;
165 rc = readl(&wait->msg->body[0]) & 0xff;
166 i2o_flush_reply(c, wait->m); 166 i2o_flush_reply(c, wait->m);
167 i2o_exec_wait_free(wait); 167 i2o_exec_wait_free(wait);
168 } else { 168 } else {
@@ -187,6 +187,7 @@ int i2o_msg_post_wait_mem(struct i2o_controller *c, u32 m, unsigned long
187 * @c: I2O controller which answers 187 * @c: I2O controller which answers
188 * @m: message id 188 * @m: message id
189 * @msg: pointer to the I2O reply message 189 * @msg: pointer to the I2O reply message
190 * @context: transaction context of request
190 * 191 *
191 * This function is called in interrupt context only. If the reply reached 192 * 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 193 * before the timeout, the i2o_exec_wait struct is filled with the message
@@ -201,14 +202,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. 202 * message must also be given back to the controller.
202 */ 203 */
203static int i2o_msg_post_wait_complete(struct i2o_controller *c, u32 m, 204static int i2o_msg_post_wait_complete(struct i2o_controller *c, u32 m,
204 struct i2o_message __iomem *msg) 205 struct i2o_message __iomem *msg,
206 u32 context)
205{ 207{
206 struct i2o_exec_wait *wait, *tmp; 208 struct i2o_exec_wait *wait, *tmp;
207 static spinlock_t lock = SPIN_LOCK_UNLOCKED; 209 static spinlock_t lock = SPIN_LOCK_UNLOCKED;
208 int rc = 1; 210 int rc = 1;
209 u32 context;
210
211 context = readl(&msg->u.s.tcntxt);
212 211
213 /* 212 /*
214 * We need to search through the i2o_exec_wait_list to see if the given 213 * We need to search through the i2o_exec_wait_list to see if the given
@@ -251,7 +250,7 @@ static int i2o_msg_post_wait_complete(struct i2o_controller *c, u32 m,
251 250
252 spin_unlock(&lock); 251 spin_unlock(&lock);
253 252
254 pr_debug("%s: Bogus reply in POST WAIT (tr-context: %08x)!\n", c->name, 253 osm_warn("%s: Bogus reply in POST WAIT (tr-context: %08x)!\n", c->name,
255 context); 254 context);
256 255
257 return -1; 256 return -1;
@@ -321,29 +320,35 @@ static void i2o_exec_lct_modified(struct i2o_controller *c)
321 * code on failure and if the reply should be flushed. 320 * code on failure and if the reply should be flushed.
322 */ 321 */
323static int i2o_exec_reply(struct i2o_controller *c, u32 m, 322static int i2o_exec_reply(struct i2o_controller *c, u32 m,
324 struct i2o_message *msg) 323 struct i2o_message __iomem *msg)
325{ 324{
326 if (le32_to_cpu(msg->u.head[0]) & MSG_FAIL) { // Fail bit is set 325 u32 context;
327 struct i2o_message __iomem *pmsg; /* preserved message */ 326
327 if (readl(&msg->u.head[0]) & MSG_FAIL) {
328 /*
329 * If Fail bit is set we must take the transaction context of
330 * the preserved message to find the right request again.
331 */
332 struct i2o_message __iomem *pmsg;
328 u32 pm; 333 u32 pm;
329 334
330 pm = le32_to_cpu(msg->body[3]); 335 pm = readl(&msg->body[3]);
331 336
332 pmsg = i2o_msg_in_to_virt(c, pm); 337 pmsg = i2o_msg_in_to_virt(c, pm);
333 338
334 i2o_report_status(KERN_INFO, "i2o_core", msg); 339 i2o_report_status(KERN_INFO, "i2o_core", msg);
335 340
336 /* Release the preserved msg by resubmitting it as a NOP */ 341 context = readl(&pmsg->u.s.tcntxt);
337 i2o_msg_nop(c, pm);
338 342
339 /* If reply to i2o_post_wait failed, return causes a timeout */ 343 /* Release the preserved msg */
340 return -1; 344 i2o_msg_nop(c, pm);
341 } 345 } else
346 context = readl(&msg->u.s.tcntxt);
342 347
343 if (le32_to_cpu(msg->u.s.tcntxt) & 0x80000000) 348 if (context & 0x80000000)
344 return i2o_msg_post_wait_complete(c, m, msg); 349 return i2o_msg_post_wait_complete(c, m, msg, context);
345 350
346 if ((le32_to_cpu(msg->u.head[1]) >> 24) == I2O_CMD_LCT_NOTIFY) { 351 if ((readl(&msg->u.head[1]) >> 24) == I2O_CMD_LCT_NOTIFY) {
347 struct work_struct *work; 352 struct work_struct *work;
348 353
349 pr_debug("%s: LCT notify received\n", c->name); 354 pr_debug("%s: LCT notify received\n", c->name);