#include <linux/module.h>
#include <linux/i2o.h>
+#include <linux/delay.h>
+
+#define OSM_NAME "exec-osm"
struct i2o_driver i2o_exec_driver;
+static int i2o_exec_lct_notify(struct i2o_controller *c, u32 change_ind);
+
/* Module internal functions from other sources */
extern int i2o_device_parse_lct(struct i2o_controller *);
u32 tcntxt; /* transaction context from reply */
int complete; /* 1 if reply received otherwise 0 */
u32 m; /* message id */
- struct i2o_message *msg; /* pointer to the reply message */
+ struct i2o_message __iomem *msg; /* pointer to the reply message */
struct list_head list; /* node in global wait list */
};
timeout, struct i2o_dma *dma)
{
DECLARE_WAIT_QUEUE_HEAD(wq);
- DEFINE_WAIT(wait);
- struct i2o_exec_wait *iwait;
+ struct i2o_exec_wait *wait;
static u32 tcntxt = 0x80000000;
- struct i2o_message *msg = c->in_queue.virt + m;
+ struct i2o_message __iomem *msg = c->in_queue.virt + m;
int rc = 0;
- iwait = i2o_exec_wait_alloc();
- if (!iwait)
+ wait = i2o_exec_wait_alloc();
+ if (!wait)
return -ENOMEM;
if (tcntxt == 0xffffffff)
tcntxt = 0x80000000;
if (dma)
- iwait->dma = *dma;
+ wait->dma = *dma;
/*
* Fill in the message initiator context and transaction context.
* so we could find a POST WAIT reply easier in the reply handler.
*/
writel(i2o_exec_driver.context, &msg->u.s.icntxt);
- iwait->tcntxt = tcntxt++;
- writel(iwait->tcntxt, &msg->u.s.tcntxt);
+ wait->tcntxt = tcntxt++;
+ writel(wait->tcntxt, &msg->u.s.tcntxt);
/*
* Post the message to the controller. At some point later it will
*/
i2o_msg_post(c, m);
- if (!iwait->complete) {
- iwait->wq = &wq;
+ if (!wait->complete) {
+ wait->wq = &wq;
/*
* we add elements add the head, because if a entry in the list
* will never be removed, we have to iterate over it every time
*/
- list_add(&iwait->list, &i2o_exec_wait_list);
+ list_add(&wait->list, &i2o_exec_wait_list);
- prepare_to_wait(&wq, &wait, TASK_INTERRUPTIBLE);
+ wait_event_interruptible_timeout(wq, wait->complete,
+ timeout * HZ);
- if (!iwait->complete)
- schedule_timeout(timeout * HZ);
-
- finish_wait(&wq, &wait);
-
- iwait->wq = NULL;
+ wait->wq = NULL;
}
barrier();
- if (iwait->complete) {
- if (readl(&iwait->msg->body[0]) >> 24)
- rc = readl(&iwait->msg->body[0]) & 0xff;
- i2o_flush_reply(c, iwait->m);
- i2o_exec_wait_free(iwait);
+ if (wait->complete) {
+ if (readl(&wait->msg->body[0]) >> 24)
+ rc = readl(&wait->msg->body[0]) & 0xff;
+ i2o_flush_reply(c, wait->m);
+ i2o_exec_wait_free(wait);
} else {
/*
* We cannot remove it now. This is important. When it does
* message must also be given back to the controller.
*/
static int i2o_msg_post_wait_complete(struct i2o_controller *c, u32 m,
- struct i2o_message *msg)
+ struct i2o_message __iomem *msg)
{
struct i2o_exec_wait *wait, *tmp;
- static spinlock_t lock = SPIN_LOCK_UNLOCKED;
+ static spinlock_t lock;
int rc = 1;
u32 context;
+ spin_lock_init(&lock);
+
context = readl(&msg->u.s.tcntxt);
/*
dev = &c->pdev->dev;
- pr_debug("timedout reply received!\n");
+ pr_debug("%s: timedout reply received!\n",
+ c->name);
i2o_dma_free(dev, &wait->dma);
i2o_exec_wait_free(wait);
rc = -1;
spin_unlock(&lock);
- pr_debug("i2o: Bogus reply in POST WAIT (tr-context: %08x)!\n",
+ pr_debug("%s: Bogus reply in POST WAIT (tr-context: %08x)!\n", c->name,
context);
return -1;
static int i2o_exec_reply(struct i2o_controller *c, u32 m,
struct i2o_message *msg)
{
- if (readl(&msg->u.head[0]) & MSG_FAIL) { // Fail bit is set
- struct i2o_message *pmsg; /* preserved message */
+ if (le32_to_cpu(msg->u.head[0]) & MSG_FAIL) { // Fail bit is set
+ struct i2o_message __iomem *pmsg; /* preserved message */
u32 pm;
- pm = readl(&msg->body[3]);
+ pm = le32_to_cpu(msg->body[3]);
- pmsg = c->in_queue.virt + pm;
+ pmsg = i2o_msg_in_to_virt(c, pm);
i2o_report_status(KERN_INFO, "i2o_core", msg);
return -1;
}
- if (readl(&msg->u.s.tcntxt) & 0x80000000)
+ if (le32_to_cpu(msg->u.s.tcntxt) & 0x80000000)
return i2o_msg_post_wait_complete(c, m, msg);
- if ((readl(&msg->u.head[1]) >> 24) == I2O_CMD_LCT_NOTIFY) {
+ if ((le32_to_cpu(msg->u.head[1]) >> 24) == I2O_CMD_LCT_NOTIFY) {
struct work_struct *work;
pr_debug("%s: LCT notify received\n", c->name);
*/
static void i2o_exec_event(struct i2o_event *evt)
{
- printk(KERN_INFO "Event received from device: %d\n",
- evt->i2o_dev->lct_data.tid);
+ osm_info("Event received from device: %d\n",
+ evt->i2o_dev->lct_data.tid);
kfree(evt);
};
*/
int i2o_exec_lct_get(struct i2o_controller *c)
{
- struct i2o_message *msg;
+ struct i2o_message __iomem *msg;
u32 m;
int i = 0;
int rc = -EAGAIN;
* replies immediately after the request. If change_ind > 0 the reply is
* send after change indicator of the LCT is > change_ind.
*/
-int i2o_exec_lct_notify(struct i2o_controller *c, u32 change_ind)
+static int i2o_exec_lct_notify(struct i2o_controller *c, u32 change_ind)
{
i2o_status_block *sb = c->status_block.virt;
struct device *dev;
- struct i2o_message *msg;
+ struct i2o_message __iomem *msg;
u32 m;
dev = &c->pdev->dev;
/* Exec OSM driver struct */
struct i2o_driver i2o_exec_driver = {
- .name = "exec-osm",
+ .name = OSM_NAME,
.reply = i2o_exec_reply,
.event = i2o_exec_event,
.classes = i2o_exec_class_id,
EXPORT_SYMBOL(i2o_msg_post_wait_mem);
EXPORT_SYMBOL(i2o_exec_lct_get);
-EXPORT_SYMBOL(i2o_exec_lct_notify);