From: Markus Lidel - added new function i2o_msg_in_to_virt and i2o_msg_out_to_virt, to turn an I2O message to a virtual address (original from Alan Cox) - replaced readl with le32_to_cpu where it is not necessary (original from Alan Cox) Signed-off-by: Markus Lidel Signed-off-by: Andrew Morton --- 25-akpm/drivers/message/i2o/exec-osm.c | 10 +++--- 25-akpm/drivers/message/i2o/i2o_block.c | 27 +++++++++--------- 25-akpm/drivers/message/i2o/i2o_scsi.c | 18 ++++++------ 25-akpm/drivers/message/i2o/pci.c | 7 ---- 25-akpm/include/linux/i2o.h | 46 +++++++++++++++++++++++++++++++- 5 files changed, 74 insertions(+), 34 deletions(-) diff -puN drivers/message/i2o/exec-osm.c~i2o-new-functions-to-convert-messages-to-a-virtual-address drivers/message/i2o/exec-osm.c --- 25/drivers/message/i2o/exec-osm.c~i2o-new-functions-to-convert-messages-to-a-virtual-address Fri Oct 8 14:32:36 2004 +++ 25-akpm/drivers/message/i2o/exec-osm.c Fri Oct 8 14:32:36 2004 @@ -322,13 +322,13 @@ static void i2o_exec_lct_modified(struct 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 + if (le32_to_cpu(&msg->u.head[0]) & MSG_FAIL) { // Fail bit is set struct i2o_message *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); @@ -339,10 +339,10 @@ static int i2o_exec_reply(struct i2o_con 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); diff -puN drivers/message/i2o/i2o_block.c~i2o-new-functions-to-convert-messages-to-a-virtual-address drivers/message/i2o/i2o_block.c --- 25/drivers/message/i2o/i2o_block.c~i2o-new-functions-to-convert-messages-to-a-virtual-address Fri Oct 8 14:32:36 2004 +++ 25-akpm/drivers/message/i2o/i2o_block.c Fri Oct 8 14:32:36 2004 @@ -416,7 +416,7 @@ static int i2o_block_reply(struct i2o_co unsigned long flags; /* FAILed message */ - if (unlikely(readl(&msg->u.head[0]) & (1 << 13))) { + if (unlikely(le32_to_cpu(&msg->u.head[0]) & (1 << 13))) { struct i2o_message *pmsg; u32 pm; @@ -430,10 +430,10 @@ static int i2o_block_reply(struct i2o_co * better be on the safe side since no one really follows * the spec to the book :) */ - pm = readl(&msg->body[3]); - pmsg = c->in_queue.virt + pm; + pm = le32_to_cpu(&msg->body[3]); + pmsg = i2o_msg_in_to_virt(c, pm); - req = i2o_cntxt_list_get(c, readl(&pmsg->u.s.tcntxt)); + req = i2o_cntxt_list_get(c, le32_to_cpu(&pmsg->u.s.tcntxt)); if (unlikely(!req)) { printk(KERN_ERR "block-osm: NULL reply received!\n"); return -1; @@ -448,7 +448,7 @@ static int i2o_block_reply(struct i2o_co spin_lock_irqsave(q->queue_lock, flags); while (end_that_request_chunk(req, !req->errors, - readl(&pmsg->body[1]))) ; + le32_to_cpu(&pmsg->body[1]))) ; end_that_request_last(req); dev->open_queue_depth--; @@ -463,7 +463,7 @@ static int i2o_block_reply(struct i2o_co return -1; } - req = i2o_cntxt_list_get(c, readl(&msg->u.s.tcntxt)); + req = i2o_cntxt_list_get(c, le32_to_cpu(&msg->u.s.tcntxt)); if (unlikely(!req)) { printk(KERN_ERR "block-osm: NULL reply received!\n"); return -1; @@ -486,7 +486,7 @@ static int i2o_block_reply(struct i2o_co "I2O Block: Data transfer to deleted device!\n"); spin_lock_irqsave(q->queue_lock, flags); while (end_that_request_chunk - (req, !req->errors, readl(&msg->body[1]))) ; + (req, !req->errors, le32_to_cpu(&msg->body[1]))) ; end_that_request_last(req); dev->open_queue_depth--; @@ -502,7 +502,7 @@ static int i2o_block_reply(struct i2o_co * request in the context. */ - st = readl(&msg->body[0]) >> 24; + st = le32_to_cpu(&msg->body[0]) >> 24; if (st != 0) { int err; @@ -523,7 +523,7 @@ static int i2o_block_reply(struct i2o_co "Volume has changed, waiting for acknowledgement" }; - err = readl(&msg->body[0]) & 0xffff; + err = le32_to_cpu(&msg->body[0]) & 0xffff; /* * Device not ready means two things. One is that the @@ -538,16 +538,17 @@ static int i2o_block_reply(struct i2o_co */ printk(KERN_ERR "/dev/%s error: %s", dev->gd->disk_name, - bsa_errors[readl(&msg->body[0]) & 0xffff]); - if (readl(&msg->body[0]) & 0x00ff0000) + bsa_errors[le32_to_cpu(&msg->body[0]) & 0xffff]); + if (le32_to_cpu(&msg->body[0]) & 0x00ff0000) printk(KERN_ERR " - DDM attempted %d retries", - (readl(&msg->body[0]) >> 16) & 0x00ff); + (le32_to_cpu(&msg->body[0]) >> 16) & 0x00ff); printk(KERN_ERR ".\n"); req->errors++; } else req->errors = 0; - if (!end_that_request_chunk(req, !req->errors, readl(&msg->body[1]))) { + if (!end_that_request_chunk + (req, !req->errors, le32_to_cpu(&msg->body[1]))) { add_disk_randomness(req->rq_disk); spin_lock_irqsave(q->queue_lock, flags); diff -puN drivers/message/i2o/i2o_scsi.c~i2o-new-functions-to-convert-messages-to-a-virtual-address drivers/message/i2o/i2o_scsi.c --- 25/drivers/message/i2o/i2o_scsi.c~i2o-new-functions-to-convert-messages-to-a-virtual-address Fri Oct 8 14:32:36 2004 +++ 25-akpm/drivers/message/i2o/i2o_scsi.c Fri Oct 8 14:32:36 2004 @@ -296,15 +296,15 @@ static int i2o_scsi_reply(struct i2o_con struct device *dev; u8 as, ds, st; - cmd = i2o_cntxt_list_get(c, readl(&msg->u.s.tcntxt)); + cmd = i2o_cntxt_list_get(c, le32_to_cpu(&msg->u.s.tcntxt)); if (msg->u.head[0] & (1 << 13)) { struct i2o_message *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); printk(KERN_ERR "IOP fail.\n"); printk(KERN_ERR "From %d To %d Cmd %d.\n", @@ -339,9 +339,9 @@ static int i2o_scsi_reply(struct i2o_con * Low byte is device status, next is adapter status, * (then one byte reserved), then request status. */ - ds = (u8) readl(&msg->body[0]); - as = (u8) (readl(&msg->body[0]) >> 8); - st = (u8) (readl(&msg->body[0]) >> 24); + ds = (u8) le32_to_cpu(&msg->body[0]); + as = (u8) (le32_to_cpu(&msg->body[0]) >> 8); + st = (u8) (le32_to_cpu(&msg->body[0]) >> 24); /* * Is this a control request coming back - eg an abort ? @@ -350,7 +350,7 @@ static int i2o_scsi_reply(struct i2o_con if (!cmd) { if (st) printk(KERN_WARNING "SCSI abort: %08X", - readl(&msg->body[0])); + le32_to_cpu(&msg->body[0])); printk(KERN_INFO "SCSI abort completed.\n"); return -EFAULT; } @@ -363,7 +363,7 @@ static int i2o_scsi_reply(struct i2o_con switch (st) { case 0x06: - count = readl(&msg->body[1]); + count = le32_to_cpu(&msg->body[1]); if (count < cmd->underflow) { int i; printk(KERN_ERR "SCSI: underflow 0x%08X 0x%08X" @@ -378,7 +378,7 @@ static int i2o_scsi_reply(struct i2o_con break; default: - error = readl(&msg->body[0]); + error = le32_to_cpu(&msg->body[0]); printk(KERN_ERR "scsi-osm: SCSI error %08x\n", error); diff -puN drivers/message/i2o/pci.c~i2o-new-functions-to-convert-messages-to-a-virtual-address drivers/message/i2o/pci.c --- 25/drivers/message/i2o/pci.c~i2o-new-functions-to-convert-messages-to-a-virtual-address Fri Oct 8 14:32:36 2004 +++ 25-akpm/drivers/message/i2o/pci.c Fri Oct 8 14:32:36 2004 @@ -277,7 +277,6 @@ static irqreturn_t i2o_pci_interrupt(int struct device *dev = &c->pdev->dev; struct i2o_message *m; u32 mv; - u32 *msg; /* * Old 960 steppings had a bug in the I2O unit that caused @@ -298,11 +297,7 @@ static irqreturn_t i2o_pci_interrupt(int * Because bus_to_virt is deprecated, we have calculate the * location by ourself! */ - m = (struct i2o_message *)(mv - - (unsigned long)c->out_queue.phys + - (unsigned long)c->out_queue.virt); - - msg = (u32 *) m; + m = i2o_msg_out_to_virt(c, mv); /* * Ensure this message is seen coherently but cachably by diff -puN include/linux/i2o.h~i2o-new-functions-to-convert-messages-to-a-virtual-address include/linux/i2o.h --- 25/include/linux/i2o.h~i2o-new-functions-to-convert-messages-to-a-virtual-address Fri Oct 8 14:32:36 2004 +++ 25-akpm/include/linux/i2o.h Fri Oct 8 14:32:36 2004 @@ -47,7 +47,7 @@ struct i2o_message { u32 function:8; u32 icntxt; /* initiator context */ u32 tcntxt; /* transaction context */ - } s; + } __attribute((packed)) s; u32 head[4]; } u; /* List follows */ @@ -252,6 +252,11 @@ extern int i2o_msg_post_wait_mem(struct extern void i2o_msg_nop(struct i2o_controller *, u32); static inline void i2o_flush_reply(struct i2o_controller *, u32); +static inline struct i2o_message *i2o_msg_in_to_virt(struct i2o_controller *, + u32); +static inline struct i2o_message *i2o_msg_out_to_virt(struct i2o_controller + *, u32); + /* DMA handling functions */ static inline int i2o_dma_alloc(struct device *, struct i2o_dma *, size_t, unsigned int); @@ -502,6 +507,45 @@ static inline void i2o_flush_reply(struc }; /** + * i2o_out_to_virt - Turn an I2O message to a virtual address + * @c: controller + * @m: message engine value + * + * Turn a receive message from an I2O controller bus address into + * a Linux virtual address. The shared page frame is a linear block + * so we simply have to shift the offset. This function does not + * work for sender side messages as they are ioremap objects + * provided by the I2O controller. + */ +static inline struct i2o_message *i2o_msg_out_to_virt(struct i2o_controller *c, + u32 m) +{ + if (unlikely + (m < c->out_queue.phys + || m >= c->out_queue.phys + c->out_queue.len)) + BUG(); + + return c->out_queue.virt + (m - c->out_queue.phys); +}; + +/** + * i2o_msg_in_to_virt - Turn an I2O message to a virtual address + * @c: controller + * @m: message engine value + * + * Turn a send message from an I2O controller bus address into + * a Linux virtual address. The shared page frame is a linear block + * so we simply have to shift the offset. This function does not + * work for receive side messages as they are kmalloc objects + * in a different pool. + */ +static inline struct i2o_message *i2o_msg_in_to_virt(struct i2o_controller *c, + u32 m) +{ + return c->in_queue.virt + m; +}; + +/** * i2o_dma_alloc - Allocate DMA memory * @dev: struct device pointer to the PCI device of the I2O controller * @addr: i2o_dma struct which should get the DMA buffer _