diff options
| author | Steve French <sfrench@us.ibm.com> | 2006-01-12 17:47:08 -0500 |
|---|---|---|
| committer | Steve French <sfrench@us.ibm.com> | 2006-01-12 17:47:08 -0500 |
| commit | 94bc2be31a01a3055ec94176e595dfe208e92d3b (patch) | |
| tree | ebfbe81c6718a6390bfa1b99c6d228237d818576 /drivers/message/i2o/exec-osm.c | |
| parent | c32a0b689cb9cc160cfcd19735bbf50bb70c6ef4 (diff) | |
| parent | 58cba4650a7a414eabd2b40cc9d8e45fcdf192d9 (diff) | |
Merge with /pub/scm/linux/kernel/git/torvalds/linux-2.6.git
Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'drivers/message/i2o/exec-osm.c')
| -rw-r--r-- | drivers/message/i2o/exec-osm.c | 114 |
1 files changed, 58 insertions, 56 deletions
diff --git a/drivers/message/i2o/exec-osm.c b/drivers/message/i2o/exec-osm.c index 9c339a2505b0..9bb9859f6dfe 100644 --- a/drivers/message/i2o/exec-osm.c +++ b/drivers/message/i2o/exec-osm.c | |||
| @@ -33,7 +33,7 @@ | |||
| 33 | #include <linux/workqueue.h> | 33 | #include <linux/workqueue.h> |
| 34 | #include <linux/string.h> | 34 | #include <linux/string.h> |
| 35 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
| 36 | #include <linux/sched.h> /* wait_event_interruptible_timeout() needs this */ | 36 | #include <linux/sched.h> /* wait_event_interruptible_timeout() needs this */ |
| 37 | #include <asm/param.h> /* HZ */ | 37 | #include <asm/param.h> /* HZ */ |
| 38 | #include "core.h" | 38 | #include "core.h" |
| 39 | 39 | ||
| @@ -75,11 +75,9 @@ static struct i2o_exec_wait *i2o_exec_wait_alloc(void) | |||
| 75 | { | 75 | { |
| 76 | struct i2o_exec_wait *wait; | 76 | struct i2o_exec_wait *wait; |
| 77 | 77 | ||
| 78 | wait = kmalloc(sizeof(*wait), GFP_KERNEL); | 78 | wait = kzalloc(sizeof(*wait), GFP_KERNEL); |
| 79 | if (!wait) | 79 | if (!wait) |
| 80 | return ERR_PTR(-ENOMEM); | 80 | return NULL; |
| 81 | |||
| 82 | memset(wait, 0, sizeof(*wait)); | ||
| 83 | 81 | ||
| 84 | INIT_LIST_HEAD(&wait->list); | 82 | INIT_LIST_HEAD(&wait->list); |
| 85 | 83 | ||
| @@ -114,13 +112,12 @@ static void i2o_exec_wait_free(struct i2o_exec_wait *wait) | |||
| 114 | * Returns 0 on success, negative error code on timeout or positive error | 112 | * Returns 0 on success, negative error code on timeout or positive error |
| 115 | * code from reply. | 113 | * code from reply. |
| 116 | */ | 114 | */ |
| 117 | int i2o_msg_post_wait_mem(struct i2o_controller *c, u32 m, unsigned long | 115 | int i2o_msg_post_wait_mem(struct i2o_controller *c, struct i2o_message *msg, |
| 118 | timeout, struct i2o_dma *dma) | 116 | unsigned long timeout, struct i2o_dma *dma) |
| 119 | { | 117 | { |
| 120 | DECLARE_WAIT_QUEUE_HEAD(wq); | 118 | DECLARE_WAIT_QUEUE_HEAD(wq); |
| 121 | struct i2o_exec_wait *wait; | 119 | struct i2o_exec_wait *wait; |
| 122 | static u32 tcntxt = 0x80000000; | 120 | static u32 tcntxt = 0x80000000; |
| 123 | struct i2o_message __iomem *msg = i2o_msg_in_to_virt(c, m); | ||
| 124 | int rc = 0; | 121 | int rc = 0; |
| 125 | 122 | ||
| 126 | wait = i2o_exec_wait_alloc(); | 123 | wait = i2o_exec_wait_alloc(); |
| @@ -138,15 +135,15 @@ int i2o_msg_post_wait_mem(struct i2o_controller *c, u32 m, unsigned long | |||
| 138 | * We will only use transaction contexts >= 0x80000000 for POST WAIT, | 135 | * We will only use transaction contexts >= 0x80000000 for POST WAIT, |
| 139 | * so we could find a POST WAIT reply easier in the reply handler. | 136 | * so we could find a POST WAIT reply easier in the reply handler. |
| 140 | */ | 137 | */ |
| 141 | writel(i2o_exec_driver.context, &msg->u.s.icntxt); | 138 | msg->u.s.icntxt = cpu_to_le32(i2o_exec_driver.context); |
| 142 | wait->tcntxt = tcntxt++; | 139 | wait->tcntxt = tcntxt++; |
| 143 | writel(wait->tcntxt, &msg->u.s.tcntxt); | 140 | msg->u.s.tcntxt = cpu_to_le32(wait->tcntxt); |
| 144 | 141 | ||
| 145 | /* | 142 | /* |
| 146 | * Post the message to the controller. At some point later it will | 143 | * Post the message to the controller. At some point later it will |
| 147 | * return. If we time out before it returns then complete will be zero. | 144 | * return. If we time out before it returns then complete will be zero. |
| 148 | */ | 145 | */ |
| 149 | i2o_msg_post(c, m); | 146 | i2o_msg_post(c, msg); |
| 150 | 147 | ||
| 151 | if (!wait->complete) { | 148 | if (!wait->complete) { |
| 152 | wait->wq = &wq; | 149 | wait->wq = &wq; |
| @@ -266,13 +263,14 @@ static int i2o_msg_post_wait_complete(struct i2o_controller *c, u32 m, | |||
| 266 | * | 263 | * |
| 267 | * Returns number of bytes printed into buffer. | 264 | * Returns number of bytes printed into buffer. |
| 268 | */ | 265 | */ |
| 269 | static ssize_t i2o_exec_show_vendor_id(struct device *d, struct device_attribute *attr, char *buf) | 266 | static ssize_t i2o_exec_show_vendor_id(struct device *d, |
| 267 | struct device_attribute *attr, char *buf) | ||
| 270 | { | 268 | { |
| 271 | struct i2o_device *dev = to_i2o_device(d); | 269 | struct i2o_device *dev = to_i2o_device(d); |
| 272 | u16 id; | 270 | u16 id; |
| 273 | 271 | ||
| 274 | if (i2o_parm_field_get(dev, 0x0000, 0, &id, 2)) { | 272 | if (!i2o_parm_field_get(dev, 0x0000, 0, &id, 2)) { |
| 275 | sprintf(buf, "0x%04x", id); | 273 | sprintf(buf, "0x%04x", le16_to_cpu(id)); |
| 276 | return strlen(buf) + 1; | 274 | return strlen(buf) + 1; |
| 277 | } | 275 | } |
| 278 | 276 | ||
| @@ -286,13 +284,15 @@ static ssize_t i2o_exec_show_vendor_id(struct device *d, struct device_attribute | |||
| 286 | * | 284 | * |
| 287 | * Returns number of bytes printed into buffer. | 285 | * Returns number of bytes printed into buffer. |
| 288 | */ | 286 | */ |
| 289 | static ssize_t i2o_exec_show_product_id(struct device *d, struct device_attribute *attr, char *buf) | 287 | static ssize_t i2o_exec_show_product_id(struct device *d, |
| 288 | struct device_attribute *attr, | ||
| 289 | char *buf) | ||
| 290 | { | 290 | { |
| 291 | struct i2o_device *dev = to_i2o_device(d); | 291 | struct i2o_device *dev = to_i2o_device(d); |
| 292 | u16 id; | 292 | u16 id; |
| 293 | 293 | ||
| 294 | if (i2o_parm_field_get(dev, 0x0000, 1, &id, 2)) { | 294 | if (!i2o_parm_field_get(dev, 0x0000, 1, &id, 2)) { |
| 295 | sprintf(buf, "0x%04x", id); | 295 | sprintf(buf, "0x%04x", le16_to_cpu(id)); |
| 296 | return strlen(buf) + 1; | 296 | return strlen(buf) + 1; |
| 297 | } | 297 | } |
| 298 | 298 | ||
| @@ -362,7 +362,9 @@ static void i2o_exec_lct_modified(struct i2o_controller *c) | |||
| 362 | if (i2o_device_parse_lct(c) != -EAGAIN) | 362 | if (i2o_device_parse_lct(c) != -EAGAIN) |
| 363 | change_ind = c->lct->change_ind + 1; | 363 | change_ind = c->lct->change_ind + 1; |
| 364 | 364 | ||
| 365 | #ifdef CONFIG_I2O_LCT_NOTIFY_ON_CHANGES | ||
| 365 | i2o_exec_lct_notify(c, change_ind); | 366 | i2o_exec_lct_notify(c, change_ind); |
| 367 | #endif | ||
| 366 | }; | 368 | }; |
| 367 | 369 | ||
| 368 | /** | 370 | /** |
| @@ -385,23 +387,22 @@ static int i2o_exec_reply(struct i2o_controller *c, u32 m, | |||
| 385 | u32 context; | 387 | u32 context; |
| 386 | 388 | ||
| 387 | if (le32_to_cpu(msg->u.head[0]) & MSG_FAIL) { | 389 | if (le32_to_cpu(msg->u.head[0]) & MSG_FAIL) { |
| 390 | struct i2o_message __iomem *pmsg; | ||
| 391 | u32 pm; | ||
| 392 | |||
| 388 | /* | 393 | /* |
| 389 | * If Fail bit is set we must take the transaction context of | 394 | * If Fail bit is set we must take the transaction context of |
| 390 | * the preserved message to find the right request again. | 395 | * the preserved message to find the right request again. |
| 391 | */ | 396 | */ |
| 392 | struct i2o_message __iomem *pmsg; | ||
| 393 | u32 pm; | ||
| 394 | 397 | ||
| 395 | pm = le32_to_cpu(msg->body[3]); | 398 | pm = le32_to_cpu(msg->body[3]); |
| 396 | |||
| 397 | pmsg = i2o_msg_in_to_virt(c, pm); | 399 | pmsg = i2o_msg_in_to_virt(c, pm); |
| 400 | context = readl(&pmsg->u.s.tcntxt); | ||
| 398 | 401 | ||
| 399 | i2o_report_status(KERN_INFO, "i2o_core", msg); | 402 | i2o_report_status(KERN_INFO, "i2o_core", msg); |
| 400 | 403 | ||
| 401 | context = readl(&pmsg->u.s.tcntxt); | ||
| 402 | |||
| 403 | /* Release the preserved msg */ | 404 | /* Release the preserved msg */ |
| 404 | i2o_msg_nop(c, pm); | 405 | i2o_msg_nop_mfa(c, pm); |
| 405 | } else | 406 | } else |
| 406 | context = le32_to_cpu(msg->u.s.tcntxt); | 407 | context = le32_to_cpu(msg->u.s.tcntxt); |
| 407 | 408 | ||
| @@ -462,25 +463,26 @@ static void i2o_exec_event(struct i2o_event *evt) | |||
| 462 | */ | 463 | */ |
| 463 | int i2o_exec_lct_get(struct i2o_controller *c) | 464 | int i2o_exec_lct_get(struct i2o_controller *c) |
| 464 | { | 465 | { |
| 465 | struct i2o_message __iomem *msg; | 466 | struct i2o_message *msg; |
| 466 | u32 m; | ||
| 467 | int i = 0; | 467 | int i = 0; |
| 468 | int rc = -EAGAIN; | 468 | int rc = -EAGAIN; |
| 469 | 469 | ||
| 470 | for (i = 1; i <= I2O_LCT_GET_TRIES; i++) { | 470 | for (i = 1; i <= I2O_LCT_GET_TRIES; i++) { |
| 471 | m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET); | 471 | msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET); |
| 472 | if (m == I2O_QUEUE_EMPTY) | 472 | if (IS_ERR(msg)) |
| 473 | return -ETIMEDOUT; | 473 | return PTR_ERR(msg); |
| 474 | 474 | ||
| 475 | writel(EIGHT_WORD_MSG_SIZE | SGL_OFFSET_6, &msg->u.head[0]); | 475 | msg->u.head[0] = |
| 476 | writel(I2O_CMD_LCT_NOTIFY << 24 | HOST_TID << 12 | ADAPTER_TID, | 476 | cpu_to_le32(EIGHT_WORD_MSG_SIZE | SGL_OFFSET_6); |
| 477 | &msg->u.head[1]); | 477 | msg->u.head[1] = |
| 478 | writel(0xffffffff, &msg->body[0]); | 478 | cpu_to_le32(I2O_CMD_LCT_NOTIFY << 24 | HOST_TID << 12 | |
| 479 | writel(0x00000000, &msg->body[1]); | 479 | ADAPTER_TID); |
| 480 | writel(0xd0000000 | c->dlct.len, &msg->body[2]); | 480 | msg->body[0] = cpu_to_le32(0xffffffff); |
| 481 | writel(c->dlct.phys, &msg->body[3]); | 481 | msg->body[1] = cpu_to_le32(0x00000000); |
| 482 | 482 | msg->body[2] = cpu_to_le32(0xd0000000 | c->dlct.len); | |
| 483 | rc = i2o_msg_post_wait(c, m, I2O_TIMEOUT_LCT_GET); | 483 | msg->body[3] = cpu_to_le32(c->dlct.phys); |
| 484 | |||
| 485 | rc = i2o_msg_post_wait(c, msg, I2O_TIMEOUT_LCT_GET); | ||
| 484 | if (rc < 0) | 486 | if (rc < 0) |
| 485 | break; | 487 | break; |
| 486 | 488 | ||
| @@ -506,29 +508,29 @@ static int i2o_exec_lct_notify(struct i2o_controller *c, u32 change_ind) | |||
| 506 | { | 508 | { |
| 507 | i2o_status_block *sb = c->status_block.virt; | 509 | i2o_status_block *sb = c->status_block.virt; |
| 508 | struct device *dev; | 510 | struct device *dev; |
| 509 | struct i2o_message __iomem *msg; | 511 | struct i2o_message *msg; |
| 510 | u32 m; | ||
| 511 | 512 | ||
| 512 | dev = &c->pdev->dev; | 513 | dev = &c->pdev->dev; |
| 513 | 514 | ||
| 514 | if (i2o_dma_realloc(dev, &c->dlct, sb->expected_lct_size, GFP_KERNEL)) | 515 | if (i2o_dma_realloc |
| 516 | (dev, &c->dlct, le32_to_cpu(sb->expected_lct_size), GFP_KERNEL)) | ||
| 515 | return -ENOMEM; | 517 | return -ENOMEM; |
| 516 | 518 | ||
| 517 | m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET); | 519 | msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET); |
| 518 | if (m == I2O_QUEUE_EMPTY) | 520 | if (IS_ERR(msg)) |
| 519 | return -ETIMEDOUT; | 521 | return PTR_ERR(msg); |
| 520 | 522 | ||
| 521 | writel(EIGHT_WORD_MSG_SIZE | SGL_OFFSET_6, &msg->u.head[0]); | 523 | msg->u.head[0] = cpu_to_le32(EIGHT_WORD_MSG_SIZE | SGL_OFFSET_6); |
| 522 | writel(I2O_CMD_LCT_NOTIFY << 24 | HOST_TID << 12 | ADAPTER_TID, | 524 | msg->u.head[1] = cpu_to_le32(I2O_CMD_LCT_NOTIFY << 24 | HOST_TID << 12 | |
| 523 | &msg->u.head[1]); | 525 | ADAPTER_TID); |
| 524 | writel(i2o_exec_driver.context, &msg->u.s.icntxt); | 526 | msg->u.s.icntxt = cpu_to_le32(i2o_exec_driver.context); |
| 525 | writel(0, &msg->u.s.tcntxt); /* FIXME */ | 527 | msg->u.s.tcntxt = cpu_to_le32(0x00000000); |
| 526 | writel(0xffffffff, &msg->body[0]); | 528 | msg->body[0] = cpu_to_le32(0xffffffff); |
| 527 | writel(change_ind, &msg->body[1]); | 529 | msg->body[1] = cpu_to_le32(change_ind); |
| 528 | writel(0xd0000000 | c->dlct.len, &msg->body[2]); | 530 | msg->body[2] = cpu_to_le32(0xd0000000 | c->dlct.len); |
| 529 | writel(c->dlct.phys, &msg->body[3]); | 531 | msg->body[3] = cpu_to_le32(c->dlct.phys); |
| 530 | 532 | ||
| 531 | i2o_msg_post(c, m); | 533 | i2o_msg_post(c, msg); |
| 532 | 534 | ||
| 533 | return 0; | 535 | return 0; |
| 534 | }; | 536 | }; |
