diff options
author | Markus Lidel <Markus.Lidel@shadowconnect.com> | 2006-01-06 03:19:29 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-06 11:33:53 -0500 |
commit | a1a5ea70a6e9db6332b27fe2d96666e17aa1436b (patch) | |
tree | 7edfe920aa40af94464ab05539d449dbe5689254 /drivers/message/i2o/i2o_block.c | |
parent | 347a8dc3b815f0c0fa62a1df075184ffe4cbdcf1 (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.c | 157 |
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 | */ |
131 | static int i2o_block_device_flush(struct i2o_device *dev) | 131 | static 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 | */ |
182 | static int i2o_block_device_mount(struct i2o_device *dev, u32 media_id) | 182 | static 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 | */ |
211 | static int i2o_block_device_lock(struct i2o_device *dev, u32 media_id) | 211 | static 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 | */ |
239 | static int i2o_block_device_unlock(struct i2o_device *dev, u32 media_id) | 239 | static 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 | */ |
332 | static inline int i2o_block_sglist_alloc(struct i2o_controller *c, | 332 | static 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; |