aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/message/i2o/i2o_block.c
diff options
context:
space:
mode:
authorMarkus Lidel <Markus.Lidel@shadowconnect.com>2006-01-06 03:19:29 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-01-06 11:33:53 -0500
commita1a5ea70a6e9db6332b27fe2d96666e17aa1436b (patch)
tree7edfe920aa40af94464ab05539d449dbe5689254 /drivers/message/i2o/i2o_block.c
parent347a8dc3b815f0c0fa62a1df075184ffe4cbdcf1 (diff)
[PATCH] I2O: changed I2O API to create I2O messages in kernel memory
Changed the I2O API to create I2O messages first in kernel memory and then transfer it at once over the PCI bus instead of sending each quad-word over the PCI bus. Signed-off-by: Markus Lidel <Markus.Lidel@shadowconnect.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/message/i2o/i2o_block.c')
-rw-r--r--drivers/message/i2o/i2o_block.c157
1 files changed, 79 insertions, 78 deletions
diff --git a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c
index f283b5bafdd3..2bd15c70773b 100644
--- a/drivers/message/i2o/i2o_block.c
+++ b/drivers/message/i2o/i2o_block.c
@@ -130,20 +130,20 @@ static int i2o_block_remove(struct device *dev)
130 */ 130 */
131static int i2o_block_device_flush(struct i2o_device *dev) 131static int i2o_block_device_flush(struct i2o_device *dev)
132{ 132{
133 struct i2o_message __iomem *msg; 133 struct i2o_message *msg;
134 u32 m;
135 134
136 m = i2o_msg_get_wait(dev->iop, &msg, I2O_TIMEOUT_MESSAGE_GET); 135 msg = i2o_msg_get_wait(dev->iop, I2O_TIMEOUT_MESSAGE_GET);
137 if (m == I2O_QUEUE_EMPTY) 136 if (IS_ERR(msg))
138 return -ETIMEDOUT; 137 return PTR_ERR(msg);
139 138
140 writel(FIVE_WORD_MSG_SIZE | SGL_OFFSET_0, &msg->u.head[0]); 139 msg->u.head[0] = cpu_to_le32(FIVE_WORD_MSG_SIZE | SGL_OFFSET_0);
141 writel(I2O_CMD_BLOCK_CFLUSH << 24 | HOST_TID << 12 | dev->lct_data.tid, 140 msg->u.head[1] =
142 &msg->u.head[1]); 141 cpu_to_le32(I2O_CMD_BLOCK_CFLUSH << 24 | HOST_TID << 12 | dev->
143 writel(60 << 16, &msg->body[0]); 142 lct_data.tid);
143 msg->body[0] = cpu_to_le32(60 << 16);
144 osm_debug("Flushing...\n"); 144 osm_debug("Flushing...\n");
145 145
146 return i2o_msg_post_wait(dev->iop, m, 60); 146 return i2o_msg_post_wait(dev->iop, msg, 60);
147}; 147};
148 148
149/** 149/**
@@ -181,21 +181,21 @@ static int i2o_block_issue_flush(request_queue_t * queue, struct gendisk *disk,
181 */ 181 */
182static int i2o_block_device_mount(struct i2o_device *dev, u32 media_id) 182static int i2o_block_device_mount(struct i2o_device *dev, u32 media_id)
183{ 183{
184 struct i2o_message __iomem *msg; 184 struct i2o_message *msg;
185 u32 m; 185
186 186 msg = i2o_msg_get_wait(dev->iop, I2O_TIMEOUT_MESSAGE_GET);
187 m = i2o_msg_get_wait(dev->iop, &msg, I2O_TIMEOUT_MESSAGE_GET); 187 if (IS_ERR(msg))
188 if (m == I2O_QUEUE_EMPTY) 188 return PTR_ERR(msg);
189 return -ETIMEDOUT; 189
190 190 msg->u.head[0] = cpu_to_le32(FIVE_WORD_MSG_SIZE | SGL_OFFSET_0);
191 writel(FIVE_WORD_MSG_SIZE | SGL_OFFSET_0, &msg->u.head[0]); 191 msg->u.head[1] =
192 writel(I2O_CMD_BLOCK_MMOUNT << 24 | HOST_TID << 12 | dev->lct_data.tid, 192 cpu_to_le32(I2O_CMD_BLOCK_MMOUNT << 24 | HOST_TID << 12 | dev->
193 &msg->u.head[1]); 193 lct_data.tid);
194 writel(-1, &msg->body[0]); 194 msg->body[0] = cpu_to_le32(-1);
195 writel(0, &msg->body[1]); 195 msg->body[1] = cpu_to_le32(0x00000000);
196 osm_debug("Mounting...\n"); 196 osm_debug("Mounting...\n");
197 197
198 return i2o_msg_post_wait(dev->iop, m, 2); 198 return i2o_msg_post_wait(dev->iop, msg, 2);
199}; 199};
200 200
201/** 201/**
@@ -210,20 +210,20 @@ static int i2o_block_device_mount(struct i2o_device *dev, u32 media_id)
210 */ 210 */
211static int i2o_block_device_lock(struct i2o_device *dev, u32 media_id) 211static int i2o_block_device_lock(struct i2o_device *dev, u32 media_id)
212{ 212{
213 struct i2o_message __iomem *msg; 213 struct i2o_message *msg;
214 u32 m;
215 214
216 m = i2o_msg_get_wait(dev->iop, &msg, I2O_TIMEOUT_MESSAGE_GET); 215 msg = i2o_msg_get_wait(dev->iop, I2O_TIMEOUT_MESSAGE_GET);
217 if (m == I2O_QUEUE_EMPTY) 216 if (IS_ERR(msg) == I2O_QUEUE_EMPTY)
218 return -ETIMEDOUT; 217 return PTR_ERR(msg);
219 218
220 writel(FIVE_WORD_MSG_SIZE | SGL_OFFSET_0, &msg->u.head[0]); 219 msg->u.head[0] = cpu_to_le32(FIVE_WORD_MSG_SIZE | SGL_OFFSET_0);
221 writel(I2O_CMD_BLOCK_MLOCK << 24 | HOST_TID << 12 | dev->lct_data.tid, 220 msg->u.head[1] =
222 &msg->u.head[1]); 221 cpu_to_le32(I2O_CMD_BLOCK_MLOCK << 24 | HOST_TID << 12 | dev->
223 writel(-1, &msg->body[0]); 222 lct_data.tid);
223 msg->body[0] = cpu_to_le32(-1);
224 osm_debug("Locking...\n"); 224 osm_debug("Locking...\n");
225 225
226 return i2o_msg_post_wait(dev->iop, m, 2); 226 return i2o_msg_post_wait(dev->iop, msg, 2);
227}; 227};
228 228
229/** 229/**
@@ -238,20 +238,20 @@ static int i2o_block_device_lock(struct i2o_device *dev, u32 media_id)
238 */ 238 */
239static int i2o_block_device_unlock(struct i2o_device *dev, u32 media_id) 239static int i2o_block_device_unlock(struct i2o_device *dev, u32 media_id)
240{ 240{
241 struct i2o_message __iomem *msg; 241 struct i2o_message *msg;
242 u32 m;
243 242
244 m = i2o_msg_get_wait(dev->iop, &msg, I2O_TIMEOUT_MESSAGE_GET); 243 msg = i2o_msg_get_wait(dev->iop, I2O_TIMEOUT_MESSAGE_GET);
245 if (m == I2O_QUEUE_EMPTY) 244 if (IS_ERR(msg))
246 return -ETIMEDOUT; 245 return PTR_ERR(msg);
247 246
248 writel(FIVE_WORD_MSG_SIZE | SGL_OFFSET_0, &msg->u.head[0]); 247 msg->u.head[0] = cpu_to_le32(FIVE_WORD_MSG_SIZE | SGL_OFFSET_0);
249 writel(I2O_CMD_BLOCK_MUNLOCK << 24 | HOST_TID << 12 | dev->lct_data.tid, 248 msg->u.head[1] =
250 &msg->u.head[1]); 249 cpu_to_le32(I2O_CMD_BLOCK_MUNLOCK << 24 | HOST_TID << 12 | dev->
251 writel(media_id, &msg->body[0]); 250 lct_data.tid);
251 msg->body[0] = cpu_to_le32(media_id);
252 osm_debug("Unlocking...\n"); 252 osm_debug("Unlocking...\n");
253 253
254 return i2o_msg_post_wait(dev->iop, m, 2); 254 return i2o_msg_post_wait(dev->iop, msg, 2);
255}; 255};
256 256
257/** 257/**
@@ -267,21 +267,21 @@ static int i2o_block_device_power(struct i2o_block_device *dev, u8 op)
267{ 267{
268 struct i2o_device *i2o_dev = dev->i2o_dev; 268 struct i2o_device *i2o_dev = dev->i2o_dev;
269 struct i2o_controller *c = i2o_dev->iop; 269 struct i2o_controller *c = i2o_dev->iop;
270 struct i2o_message __iomem *msg; 270 struct i2o_message *msg;
271 u32 m;
272 int rc; 271 int rc;
273 272
274 m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET); 273 msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET);
275 if (m == I2O_QUEUE_EMPTY) 274 if (IS_ERR(msg))
276 return -ETIMEDOUT; 275 return PTR_ERR(msg);
277 276
278 writel(FOUR_WORD_MSG_SIZE | SGL_OFFSET_0, &msg->u.head[0]); 277 msg->u.head[0] = cpu_to_le32(FOUR_WORD_MSG_SIZE | SGL_OFFSET_0);
279 writel(I2O_CMD_BLOCK_POWER << 24 | HOST_TID << 12 | i2o_dev->lct_data. 278 msg->u.head[1] =
280 tid, &msg->u.head[1]); 279 cpu_to_le32(I2O_CMD_BLOCK_POWER << 24 | HOST_TID << 12 | i2o_dev->
281 writel(op << 24, &msg->body[0]); 280 lct_data.tid);
281 msg->body[0] = cpu_to_le32(op << 24);
282 osm_debug("Power...\n"); 282 osm_debug("Power...\n");
283 283
284 rc = i2o_msg_post_wait(c, m, 60); 284 rc = i2o_msg_post_wait(c, msg, 60);
285 if (!rc) 285 if (!rc)
286 dev->power = op; 286 dev->power = op;
287 287
@@ -331,7 +331,7 @@ static inline void i2o_block_request_free(struct i2o_block_request *ireq)
331 */ 331 */
332static inline int i2o_block_sglist_alloc(struct i2o_controller *c, 332static inline int i2o_block_sglist_alloc(struct i2o_controller *c,
333 struct i2o_block_request *ireq, 333 struct i2o_block_request *ireq,
334 u32 __iomem ** mptr) 334 u32 ** mptr)
335{ 335{
336 int nents; 336 int nents;
337 enum dma_data_direction direction; 337 enum dma_data_direction direction;
@@ -745,10 +745,9 @@ static int i2o_block_transfer(struct request *req)
745 struct i2o_block_device *dev = req->rq_disk->private_data; 745 struct i2o_block_device *dev = req->rq_disk->private_data;
746 struct i2o_controller *c; 746 struct i2o_controller *c;
747 int tid = dev->i2o_dev->lct_data.tid; 747 int tid = dev->i2o_dev->lct_data.tid;
748 struct i2o_message __iomem *msg; 748 struct i2o_message *msg;
749 u32 __iomem *mptr; 749 u32 *mptr;
750 struct i2o_block_request *ireq = req->special; 750 struct i2o_block_request *ireq = req->special;
751 u32 m;
752 u32 tcntxt; 751 u32 tcntxt;
753 u32 sgl_offset = SGL_OFFSET_8; 752 u32 sgl_offset = SGL_OFFSET_8;
754 u32 ctl_flags = 0x00000000; 753 u32 ctl_flags = 0x00000000;
@@ -763,9 +762,9 @@ static int i2o_block_transfer(struct request *req)
763 762
764 c = dev->i2o_dev->iop; 763 c = dev->i2o_dev->iop;
765 764
766 m = i2o_msg_get(c, &msg); 765 msg = i2o_msg_get(c);
767 if (m == I2O_QUEUE_EMPTY) { 766 if (IS_ERR(msg)) {
768 rc = -EBUSY; 767 rc = PTR_ERR(msg);
769 goto exit; 768 goto exit;
770 } 769 }
771 770
@@ -775,8 +774,8 @@ static int i2o_block_transfer(struct request *req)
775 goto nop_msg; 774 goto nop_msg;
776 } 775 }
777 776
778 writel(i2o_block_driver.context, &msg->u.s.icntxt); 777 msg->u.s.icntxt = cpu_to_le32(i2o_block_driver.context);
779 writel(tcntxt, &msg->u.s.tcntxt); 778 msg->u.s.tcntxt = cpu_to_le32(tcntxt);
780 779
781 mptr = &msg->body[0]; 780 mptr = &msg->body[0];
782 781
@@ -834,11 +833,11 @@ static int i2o_block_transfer(struct request *req)
834 833
835 sgl_offset = SGL_OFFSET_12; 834 sgl_offset = SGL_OFFSET_12;
836 835
837 writel(I2O_CMD_PRIVATE << 24 | HOST_TID << 12 | tid, 836 msg->u.head[1] =
838 &msg->u.head[1]); 837 cpu_to_le32(I2O_CMD_PRIVATE << 24 | HOST_TID << 12 | tid);
839 838
840 writel(I2O_VENDOR_DPT << 16 | I2O_CMD_SCSI_EXEC, mptr++); 839 *mptr++ = cpu_to_le32(I2O_VENDOR_DPT << 16 | I2O_CMD_SCSI_EXEC);
841 writel(tid, mptr++); 840 *mptr++ = cpu_to_le32(tid);
842 841
843 /* 842 /*
844 * ENABLE_DISCONNECT 843 * ENABLE_DISCONNECT
@@ -853,22 +852,24 @@ static int i2o_block_transfer(struct request *req)
853 scsi_flags = 0xa0a0000a; 852 scsi_flags = 0xa0a0000a;
854 } 853 }
855 854
856 writel(scsi_flags, mptr++); 855 *mptr++ = cpu_to_le32(scsi_flags);
857 856
858 *((u32 *) & cmd[2]) = cpu_to_be32(req->sector * hwsec); 857 *((u32 *) & cmd[2]) = cpu_to_be32(req->sector * hwsec);
859 *((u16 *) & cmd[7]) = cpu_to_be16(req->nr_sectors * hwsec); 858 *((u16 *) & cmd[7]) = cpu_to_be16(req->nr_sectors * hwsec);
860 859
861 memcpy_toio(mptr, cmd, 10); 860 memcpy(mptr, cmd, 10);
862 mptr += 4; 861 mptr += 4;
863 writel(req->nr_sectors << KERNEL_SECTOR_SHIFT, mptr++); 862 *mptr++ = cpu_to_le32(req->nr_sectors << KERNEL_SECTOR_SHIFT);
864 } else 863 } else
865#endif 864#endif
866 { 865 {
867 writel(cmd | HOST_TID << 12 | tid, &msg->u.head[1]); 866 msg->u.head[1] = cpu_to_le32(cmd | HOST_TID << 12 | tid);
868 writel(ctl_flags, mptr++); 867 *mptr++ = cpu_to_le32(ctl_flags);
869 writel(req->nr_sectors << KERNEL_SECTOR_SHIFT, mptr++); 868 *mptr++ = cpu_to_le32(req->nr_sectors << KERNEL_SECTOR_SHIFT);
870 writel((u32) (req->sector << KERNEL_SECTOR_SHIFT), mptr++); 869 *mptr++ =
871 writel(req->sector >> (32 - KERNEL_SECTOR_SHIFT), mptr++); 870 cpu_to_le32((u32) (req->sector << KERNEL_SECTOR_SHIFT));
871 *mptr++ =
872 cpu_to_le32(req->sector >> (32 - KERNEL_SECTOR_SHIFT));
872 } 873 }
873 874
874 if (!i2o_block_sglist_alloc(c, ireq, &mptr)) { 875 if (!i2o_block_sglist_alloc(c, ireq, &mptr)) {
@@ -876,13 +877,13 @@ static int i2o_block_transfer(struct request *req)
876 goto context_remove; 877 goto context_remove;
877 } 878 }
878 879
879 writel(I2O_MESSAGE_SIZE(mptr - &msg->u.head[0]) | 880 msg->u.head[0] =
880 sgl_offset, &msg->u.head[0]); 881 cpu_to_le32(I2O_MESSAGE_SIZE(mptr - &msg->u.head[0]) | sgl_offset);
881 882
882 list_add_tail(&ireq->queue, &dev->open_queue); 883 list_add_tail(&ireq->queue, &dev->open_queue);
883 dev->open_queue_depth++; 884 dev->open_queue_depth++;
884 885
885 i2o_msg_post(c, m); 886 i2o_msg_post(c, msg);
886 887
887 return 0; 888 return 0;
888 889
@@ -890,7 +891,7 @@ static int i2o_block_transfer(struct request *req)
890 i2o_cntxt_list_remove(c, req); 891 i2o_cntxt_list_remove(c, req);
891 892
892 nop_msg: 893 nop_msg:
893 i2o_msg_nop(c, m); 894 i2o_msg_nop(c, msg);
894 895
895 exit: 896 exit:
896 return rc; 897 return rc;