diff options
Diffstat (limited to 'drivers/message/i2o/exec-osm.c')
-rw-r--r-- | drivers/message/i2o/exec-osm.c | 47 |
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 | */ |
113 | int i2o_msg_post_wait_mem(struct i2o_controller *c, u32 m, unsigned long | 114 | int 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 | */ |
203 | static int i2o_msg_post_wait_complete(struct i2o_controller *c, u32 m, | 204 | static 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 | */ |
323 | static int i2o_exec_reply(struct i2o_controller *c, u32 m, | 322 | static 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); |