diff options
Diffstat (limited to 'drivers/message/i2o/i2o_config.c')
-rw-r--r-- | drivers/message/i2o/i2o_config.c | 196 |
1 files changed, 95 insertions, 101 deletions
diff --git a/drivers/message/i2o/i2o_config.c b/drivers/message/i2o/i2o_config.c index 3c3a7abebb1b..89daf67b764d 100644 --- a/drivers/message/i2o/i2o_config.c +++ b/drivers/message/i2o/i2o_config.c | |||
@@ -36,12 +36,12 @@ | |||
36 | 36 | ||
37 | #include <asm/uaccess.h> | 37 | #include <asm/uaccess.h> |
38 | 38 | ||
39 | #include "core.h" | ||
40 | |||
41 | #define SG_TABLESIZE 30 | 39 | #define SG_TABLESIZE 30 |
42 | 40 | ||
43 | static int i2o_cfg_ioctl(struct inode *inode, struct file *fp, unsigned int cmd, | 41 | extern int i2o_parm_issue(struct i2o_device *, int, void *, int, void *, int); |
44 | unsigned long arg); | 42 | |
43 | static int i2o_cfg_ioctl(struct inode *, struct file *, unsigned int, | ||
44 | unsigned long); | ||
45 | 45 | ||
46 | static spinlock_t i2o_config_lock; | 46 | static spinlock_t i2o_config_lock; |
47 | 47 | ||
@@ -230,8 +230,7 @@ static int i2o_cfg_swdl(unsigned long arg) | |||
230 | struct i2o_sw_xfer __user *pxfer = (struct i2o_sw_xfer __user *)arg; | 230 | struct i2o_sw_xfer __user *pxfer = (struct i2o_sw_xfer __user *)arg; |
231 | unsigned char maxfrag = 0, curfrag = 1; | 231 | unsigned char maxfrag = 0, curfrag = 1; |
232 | struct i2o_dma buffer; | 232 | struct i2o_dma buffer; |
233 | struct i2o_message __iomem *msg; | 233 | struct i2o_message *msg; |
234 | u32 m; | ||
235 | unsigned int status = 0, swlen = 0, fragsize = 8192; | 234 | unsigned int status = 0, swlen = 0, fragsize = 8192; |
236 | struct i2o_controller *c; | 235 | struct i2o_controller *c; |
237 | 236 | ||
@@ -257,31 +256,34 @@ static int i2o_cfg_swdl(unsigned long arg) | |||
257 | if (!c) | 256 | if (!c) |
258 | return -ENXIO; | 257 | return -ENXIO; |
259 | 258 | ||
260 | m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET); | 259 | msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET); |
261 | if (m == I2O_QUEUE_EMPTY) | 260 | if (IS_ERR(msg)) |
262 | return -EBUSY; | 261 | return PTR_ERR(msg); |
263 | 262 | ||
264 | if (i2o_dma_alloc(&c->pdev->dev, &buffer, fragsize, GFP_KERNEL)) { | 263 | if (i2o_dma_alloc(&c->pdev->dev, &buffer, fragsize, GFP_KERNEL)) { |
265 | i2o_msg_nop(c, m); | 264 | i2o_msg_nop(c, msg); |
266 | return -ENOMEM; | 265 | return -ENOMEM; |
267 | } | 266 | } |
268 | 267 | ||
269 | __copy_from_user(buffer.virt, kxfer.buf, fragsize); | 268 | __copy_from_user(buffer.virt, kxfer.buf, fragsize); |
270 | 269 | ||
271 | writel(NINE_WORD_MSG_SIZE | SGL_OFFSET_7, &msg->u.head[0]); | 270 | msg->u.head[0] = cpu_to_le32(NINE_WORD_MSG_SIZE | SGL_OFFSET_7); |
272 | writel(I2O_CMD_SW_DOWNLOAD << 24 | HOST_TID << 12 | ADAPTER_TID, | 271 | msg->u.head[1] = |
273 | &msg->u.head[1]); | 272 | cpu_to_le32(I2O_CMD_SW_DOWNLOAD << 24 | HOST_TID << 12 | |
274 | writel(i2o_config_driver.context, &msg->u.head[2]); | 273 | ADAPTER_TID); |
275 | writel(0, &msg->u.head[3]); | 274 | msg->u.head[2] = cpu_to_le32(i2o_config_driver.context); |
276 | writel((((u32) kxfer.flags) << 24) | (((u32) kxfer.sw_type) << 16) | | 275 | msg->u.head[3] = cpu_to_le32(0); |
277 | (((u32) maxfrag) << 8) | (((u32) curfrag)), &msg->body[0]); | 276 | msg->body[0] = |
278 | writel(swlen, &msg->body[1]); | 277 | cpu_to_le32((((u32) kxfer.flags) << 24) | (((u32) kxfer. |
279 | writel(kxfer.sw_id, &msg->body[2]); | 278 | sw_type) << 16) | |
280 | writel(0xD0000000 | fragsize, &msg->body[3]); | 279 | (((u32) maxfrag) << 8) | (((u32) curfrag))); |
281 | writel(buffer.phys, &msg->body[4]); | 280 | msg->body[1] = cpu_to_le32(swlen); |
281 | msg->body[2] = cpu_to_le32(kxfer.sw_id); | ||
282 | msg->body[3] = cpu_to_le32(0xD0000000 | fragsize); | ||
283 | msg->body[4] = cpu_to_le32(buffer.phys); | ||
282 | 284 | ||
283 | osm_debug("swdl frag %d/%d (size %d)\n", curfrag, maxfrag, fragsize); | 285 | osm_debug("swdl frag %d/%d (size %d)\n", curfrag, maxfrag, fragsize); |
284 | status = i2o_msg_post_wait_mem(c, m, 60, &buffer); | 286 | status = i2o_msg_post_wait_mem(c, msg, 60, &buffer); |
285 | 287 | ||
286 | if (status != -ETIMEDOUT) | 288 | if (status != -ETIMEDOUT) |
287 | i2o_dma_free(&c->pdev->dev, &buffer); | 289 | i2o_dma_free(&c->pdev->dev, &buffer); |
@@ -302,8 +304,7 @@ static int i2o_cfg_swul(unsigned long arg) | |||
302 | struct i2o_sw_xfer __user *pxfer = (struct i2o_sw_xfer __user *)arg; | 304 | struct i2o_sw_xfer __user *pxfer = (struct i2o_sw_xfer __user *)arg; |
303 | unsigned char maxfrag = 0, curfrag = 1; | 305 | unsigned char maxfrag = 0, curfrag = 1; |
304 | struct i2o_dma buffer; | 306 | struct i2o_dma buffer; |
305 | struct i2o_message __iomem *msg; | 307 | struct i2o_message *msg; |
306 | u32 m; | ||
307 | unsigned int status = 0, swlen = 0, fragsize = 8192; | 308 | unsigned int status = 0, swlen = 0, fragsize = 8192; |
308 | struct i2o_controller *c; | 309 | struct i2o_controller *c; |
309 | int ret = 0; | 310 | int ret = 0; |
@@ -330,30 +331,30 @@ static int i2o_cfg_swul(unsigned long arg) | |||
330 | if (!c) | 331 | if (!c) |
331 | return -ENXIO; | 332 | return -ENXIO; |
332 | 333 | ||
333 | m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET); | 334 | msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET); |
334 | if (m == I2O_QUEUE_EMPTY) | 335 | if (IS_ERR(msg)) |
335 | return -EBUSY; | 336 | return PTR_ERR(msg); |
336 | 337 | ||
337 | if (i2o_dma_alloc(&c->pdev->dev, &buffer, fragsize, GFP_KERNEL)) { | 338 | if (i2o_dma_alloc(&c->pdev->dev, &buffer, fragsize, GFP_KERNEL)) { |
338 | i2o_msg_nop(c, m); | 339 | i2o_msg_nop(c, msg); |
339 | return -ENOMEM; | 340 | return -ENOMEM; |
340 | } | 341 | } |
341 | 342 | ||
342 | writel(NINE_WORD_MSG_SIZE | SGL_OFFSET_7, &msg->u.head[0]); | 343 | msg->u.head[0] = cpu_to_le32(NINE_WORD_MSG_SIZE | SGL_OFFSET_7); |
343 | writel(I2O_CMD_SW_UPLOAD << 24 | HOST_TID << 12 | ADAPTER_TID, | 344 | msg->u.head[1] = |
344 | &msg->u.head[1]); | 345 | cpu_to_le32(I2O_CMD_SW_UPLOAD << 24 | HOST_TID << 12 | ADAPTER_TID); |
345 | writel(i2o_config_driver.context, &msg->u.head[2]); | 346 | msg->u.head[2] = cpu_to_le32(i2o_config_driver.context); |
346 | writel(0, &msg->u.head[3]); | 347 | msg->u.head[3] = cpu_to_le32(0); |
347 | writel((u32) kxfer.flags << 24 | (u32) kxfer. | 348 | msg->body[0] = |
348 | sw_type << 16 | (u32) maxfrag << 8 | (u32) curfrag, | 349 | cpu_to_le32((u32) kxfer.flags << 24 | (u32) kxfer. |
349 | &msg->body[0]); | 350 | sw_type << 16 | (u32) maxfrag << 8 | (u32) curfrag); |
350 | writel(swlen, &msg->body[1]); | 351 | msg->body[1] = cpu_to_le32(swlen); |
351 | writel(kxfer.sw_id, &msg->body[2]); | 352 | msg->body[2] = cpu_to_le32(kxfer.sw_id); |
352 | writel(0xD0000000 | fragsize, &msg->body[3]); | 353 | msg->body[3] = cpu_to_le32(0xD0000000 | fragsize); |
353 | writel(buffer.phys, &msg->body[4]); | 354 | msg->body[4] = cpu_to_le32(buffer.phys); |
354 | 355 | ||
355 | osm_debug("swul frag %d/%d (size %d)\n", curfrag, maxfrag, fragsize); | 356 | osm_debug("swul frag %d/%d (size %d)\n", curfrag, maxfrag, fragsize); |
356 | status = i2o_msg_post_wait_mem(c, m, 60, &buffer); | 357 | status = i2o_msg_post_wait_mem(c, msg, 60, &buffer); |
357 | 358 | ||
358 | if (status != I2O_POST_WAIT_OK) { | 359 | if (status != I2O_POST_WAIT_OK) { |
359 | if (status != -ETIMEDOUT) | 360 | if (status != -ETIMEDOUT) |
@@ -380,8 +381,7 @@ static int i2o_cfg_swdel(unsigned long arg) | |||
380 | struct i2o_controller *c; | 381 | struct i2o_controller *c; |
381 | struct i2o_sw_xfer kxfer; | 382 | struct i2o_sw_xfer kxfer; |
382 | struct i2o_sw_xfer __user *pxfer = (struct i2o_sw_xfer __user *)arg; | 383 | struct i2o_sw_xfer __user *pxfer = (struct i2o_sw_xfer __user *)arg; |
383 | struct i2o_message __iomem *msg; | 384 | struct i2o_message *msg; |
384 | u32 m; | ||
385 | unsigned int swlen; | 385 | unsigned int swlen; |
386 | int token; | 386 | int token; |
387 | 387 | ||
@@ -395,21 +395,21 @@ static int i2o_cfg_swdel(unsigned long arg) | |||
395 | if (!c) | 395 | if (!c) |
396 | return -ENXIO; | 396 | return -ENXIO; |
397 | 397 | ||
398 | m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET); | 398 | msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET); |
399 | if (m == I2O_QUEUE_EMPTY) | 399 | if (IS_ERR(msg)) |
400 | return -EBUSY; | 400 | return PTR_ERR(msg); |
401 | 401 | ||
402 | writel(SEVEN_WORD_MSG_SIZE | SGL_OFFSET_0, &msg->u.head[0]); | 402 | msg->u.head[0] = cpu_to_le32(SEVEN_WORD_MSG_SIZE | SGL_OFFSET_0); |
403 | writel(I2O_CMD_SW_REMOVE << 24 | HOST_TID << 12 | ADAPTER_TID, | 403 | msg->u.head[1] = |
404 | &msg->u.head[1]); | 404 | cpu_to_le32(I2O_CMD_SW_REMOVE << 24 | HOST_TID << 12 | ADAPTER_TID); |
405 | writel(i2o_config_driver.context, &msg->u.head[2]); | 405 | msg->u.head[2] = cpu_to_le32(i2o_config_driver.context); |
406 | writel(0, &msg->u.head[3]); | 406 | msg->u.head[3] = cpu_to_le32(0); |
407 | writel((u32) kxfer.flags << 24 | (u32) kxfer.sw_type << 16, | 407 | msg->body[0] = |
408 | &msg->body[0]); | 408 | cpu_to_le32((u32) kxfer.flags << 24 | (u32) kxfer.sw_type << 16); |
409 | writel(swlen, &msg->body[1]); | 409 | msg->body[1] = cpu_to_le32(swlen); |
410 | writel(kxfer.sw_id, &msg->body[2]); | 410 | msg->body[2] = cpu_to_le32(kxfer.sw_id); |
411 | 411 | ||
412 | token = i2o_msg_post_wait(c, m, 10); | 412 | token = i2o_msg_post_wait(c, msg, 10); |
413 | 413 | ||
414 | if (token != I2O_POST_WAIT_OK) { | 414 | if (token != I2O_POST_WAIT_OK) { |
415 | osm_info("swdel failed, DetailedStatus = %d\n", token); | 415 | osm_info("swdel failed, DetailedStatus = %d\n", token); |
@@ -423,25 +423,24 @@ static int i2o_cfg_validate(unsigned long arg) | |||
423 | { | 423 | { |
424 | int token; | 424 | int token; |
425 | int iop = (int)arg; | 425 | int iop = (int)arg; |
426 | struct i2o_message __iomem *msg; | 426 | struct i2o_message *msg; |
427 | u32 m; | ||
428 | struct i2o_controller *c; | 427 | struct i2o_controller *c; |
429 | 428 | ||
430 | c = i2o_find_iop(iop); | 429 | c = i2o_find_iop(iop); |
431 | if (!c) | 430 | if (!c) |
432 | return -ENXIO; | 431 | return -ENXIO; |
433 | 432 | ||
434 | m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET); | 433 | msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET); |
435 | if (m == I2O_QUEUE_EMPTY) | 434 | if (IS_ERR(msg)) |
436 | return -EBUSY; | 435 | return PTR_ERR(msg); |
437 | 436 | ||
438 | writel(FOUR_WORD_MSG_SIZE | SGL_OFFSET_0, &msg->u.head[0]); | 437 | msg->u.head[0] = cpu_to_le32(FOUR_WORD_MSG_SIZE | SGL_OFFSET_0); |
439 | writel(I2O_CMD_CONFIG_VALIDATE << 24 | HOST_TID << 12 | iop, | 438 | msg->u.head[1] = |
440 | &msg->u.head[1]); | 439 | cpu_to_le32(I2O_CMD_CONFIG_VALIDATE << 24 | HOST_TID << 12 | iop); |
441 | writel(i2o_config_driver.context, &msg->u.head[2]); | 440 | msg->u.head[2] = cpu_to_le32(i2o_config_driver.context); |
442 | writel(0, &msg->u.head[3]); | 441 | msg->u.head[3] = cpu_to_le32(0); |
443 | 442 | ||
444 | token = i2o_msg_post_wait(c, m, 10); | 443 | token = i2o_msg_post_wait(c, msg, 10); |
445 | 444 | ||
446 | if (token != I2O_POST_WAIT_OK) { | 445 | if (token != I2O_POST_WAIT_OK) { |
447 | osm_info("Can't validate configuration, ErrorStatus = %d\n", | 446 | osm_info("Can't validate configuration, ErrorStatus = %d\n", |
@@ -454,8 +453,7 @@ static int i2o_cfg_validate(unsigned long arg) | |||
454 | 453 | ||
455 | static int i2o_cfg_evt_reg(unsigned long arg, struct file *fp) | 454 | static int i2o_cfg_evt_reg(unsigned long arg, struct file *fp) |
456 | { | 455 | { |
457 | struct i2o_message __iomem *msg; | 456 | struct i2o_message *msg; |
458 | u32 m; | ||
459 | struct i2o_evt_id __user *pdesc = (struct i2o_evt_id __user *)arg; | 457 | struct i2o_evt_id __user *pdesc = (struct i2o_evt_id __user *)arg; |
460 | struct i2o_evt_id kdesc; | 458 | struct i2o_evt_id kdesc; |
461 | struct i2o_controller *c; | 459 | struct i2o_controller *c; |
@@ -474,18 +472,19 @@ static int i2o_cfg_evt_reg(unsigned long arg, struct file *fp) | |||
474 | if (!d) | 472 | if (!d) |
475 | return -ENODEV; | 473 | return -ENODEV; |
476 | 474 | ||
477 | m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET); | 475 | msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET); |
478 | if (m == I2O_QUEUE_EMPTY) | 476 | if (IS_ERR(msg)) |
479 | return -EBUSY; | 477 | return PTR_ERR(msg); |
480 | 478 | ||
481 | writel(FOUR_WORD_MSG_SIZE | SGL_OFFSET_0, &msg->u.head[0]); | 479 | msg->u.head[0] = cpu_to_le32(FOUR_WORD_MSG_SIZE | SGL_OFFSET_0); |
482 | writel(I2O_CMD_UTIL_EVT_REGISTER << 24 | HOST_TID << 12 | kdesc.tid, | 480 | msg->u.head[1] = |
483 | &msg->u.head[1]); | 481 | cpu_to_le32(I2O_CMD_UTIL_EVT_REGISTER << 24 | HOST_TID << 12 | |
484 | writel(i2o_config_driver.context, &msg->u.head[2]); | 482 | kdesc.tid); |
485 | writel(i2o_cntxt_list_add(c, fp->private_data), &msg->u.head[3]); | 483 | msg->u.head[2] = cpu_to_le32(i2o_config_driver.context); |
486 | writel(kdesc.evt_mask, &msg->body[0]); | 484 | msg->u.head[3] = cpu_to_le32(i2o_cntxt_list_add(c, fp->private_data)); |
485 | msg->body[0] = cpu_to_le32(kdesc.evt_mask); | ||
487 | 486 | ||
488 | i2o_msg_post(c, m); | 487 | i2o_msg_post(c, msg); |
489 | 488 | ||
490 | return 0; | 489 | return 0; |
491 | } | 490 | } |
@@ -537,7 +536,6 @@ static int i2o_cfg_passthru32(struct file *file, unsigned cmnd, | |||
537 | u32 sg_index = 0; | 536 | u32 sg_index = 0; |
538 | i2o_status_block *sb; | 537 | i2o_status_block *sb; |
539 | struct i2o_message *msg; | 538 | struct i2o_message *msg; |
540 | u32 m; | ||
541 | unsigned int iop; | 539 | unsigned int iop; |
542 | 540 | ||
543 | cmd = (struct i2o_cmd_passthru32 __user *)arg; | 541 | cmd = (struct i2o_cmd_passthru32 __user *)arg; |
@@ -553,7 +551,7 @@ static int i2o_cfg_passthru32(struct file *file, unsigned cmnd, | |||
553 | return -ENXIO; | 551 | return -ENXIO; |
554 | } | 552 | } |
555 | 553 | ||
556 | m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET); | 554 | msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET); |
557 | 555 | ||
558 | sb = c->status_block.virt; | 556 | sb = c->status_block.virt; |
559 | 557 | ||
@@ -585,19 +583,15 @@ static int i2o_cfg_passthru32(struct file *file, unsigned cmnd, | |||
585 | reply_size >>= 16; | 583 | reply_size >>= 16; |
586 | reply_size <<= 2; | 584 | reply_size <<= 2; |
587 | 585 | ||
588 | reply = kmalloc(reply_size, GFP_KERNEL); | 586 | reply = kzalloc(reply_size, GFP_KERNEL); |
589 | if (!reply) { | 587 | if (!reply) { |
590 | printk(KERN_WARNING "%s: Could not allocate reply buffer\n", | 588 | printk(KERN_WARNING "%s: Could not allocate reply buffer\n", |
591 | c->name); | 589 | c->name); |
592 | return -ENOMEM; | 590 | return -ENOMEM; |
593 | } | 591 | } |
594 | memset(reply, 0, reply_size); | ||
595 | 592 | ||
596 | sg_offset = (msg->u.head[0] >> 4) & 0x0f; | 593 | sg_offset = (msg->u.head[0] >> 4) & 0x0f; |
597 | 594 | ||
598 | writel(i2o_config_driver.context, &msg->u.s.icntxt); | ||
599 | writel(i2o_cntxt_list_add(c, reply), &msg->u.s.tcntxt); | ||
600 | |||
601 | memset(sg_list, 0, sizeof(sg_list[0]) * SG_TABLESIZE); | 595 | memset(sg_list, 0, sizeof(sg_list[0]) * SG_TABLESIZE); |
602 | if (sg_offset) { | 596 | if (sg_offset) { |
603 | struct sg_simple_element *sg; | 597 | struct sg_simple_element *sg; |
@@ -631,7 +625,7 @@ static int i2o_cfg_passthru32(struct file *file, unsigned cmnd, | |||
631 | goto cleanup; | 625 | goto cleanup; |
632 | } | 626 | } |
633 | sg_size = sg[i].flag_count & 0xffffff; | 627 | sg_size = sg[i].flag_count & 0xffffff; |
634 | p = &(sg_list[sg_index++]); | 628 | p = &(sg_list[sg_index]); |
635 | /* Allocate memory for the transfer */ | 629 | /* Allocate memory for the transfer */ |
636 | if (i2o_dma_alloc | 630 | if (i2o_dma_alloc |
637 | (&c->pdev->dev, p, sg_size, | 631 | (&c->pdev->dev, p, sg_size, |
@@ -642,6 +636,7 @@ static int i2o_cfg_passthru32(struct file *file, unsigned cmnd, | |||
642 | rcode = -ENOMEM; | 636 | rcode = -ENOMEM; |
643 | goto sg_list_cleanup; | 637 | goto sg_list_cleanup; |
644 | } | 638 | } |
639 | sg_index++; | ||
645 | /* Copy in the user's SG buffer if necessary */ | 640 | /* Copy in the user's SG buffer if necessary */ |
646 | if (sg[i]. | 641 | if (sg[i]. |
647 | flag_count & 0x04000000 /*I2O_SGL_FLAGS_DIR */ ) { | 642 | flag_count & 0x04000000 /*I2O_SGL_FLAGS_DIR */ ) { |
@@ -662,9 +657,11 @@ static int i2o_cfg_passthru32(struct file *file, unsigned cmnd, | |||
662 | } | 657 | } |
663 | } | 658 | } |
664 | 659 | ||
665 | rcode = i2o_msg_post_wait(c, m, 60); | 660 | rcode = i2o_msg_post_wait(c, msg, 60); |
666 | if (rcode) | 661 | if (rcode) { |
662 | reply[4] = ((u32) rcode) << 24; | ||
667 | goto sg_list_cleanup; | 663 | goto sg_list_cleanup; |
664 | } | ||
668 | 665 | ||
669 | if (sg_offset) { | 666 | if (sg_offset) { |
670 | u32 msg[I2O_OUTBOUND_MSG_FRAME_SIZE]; | 667 | u32 msg[I2O_OUTBOUND_MSG_FRAME_SIZE]; |
@@ -714,6 +711,7 @@ static int i2o_cfg_passthru32(struct file *file, unsigned cmnd, | |||
714 | } | 711 | } |
715 | } | 712 | } |
716 | 713 | ||
714 | sg_list_cleanup: | ||
717 | /* Copy back the reply to user space */ | 715 | /* Copy back the reply to user space */ |
718 | if (reply_size) { | 716 | if (reply_size) { |
719 | // we wrote our own values for context - now restore the user supplied ones | 717 | // we wrote our own values for context - now restore the user supplied ones |
@@ -731,7 +729,6 @@ static int i2o_cfg_passthru32(struct file *file, unsigned cmnd, | |||
731 | } | 729 | } |
732 | } | 730 | } |
733 | 731 | ||
734 | sg_list_cleanup: | ||
735 | for (i = 0; i < sg_index; i++) | 732 | for (i = 0; i < sg_index; i++) |
736 | i2o_dma_free(&c->pdev->dev, &sg_list[i]); | 733 | i2o_dma_free(&c->pdev->dev, &sg_list[i]); |
737 | 734 | ||
@@ -780,8 +777,7 @@ static int i2o_cfg_passthru(unsigned long arg) | |||
780 | u32 i = 0; | 777 | u32 i = 0; |
781 | void *p = NULL; | 778 | void *p = NULL; |
782 | i2o_status_block *sb; | 779 | i2o_status_block *sb; |
783 | struct i2o_message __iomem *msg; | 780 | struct i2o_message *msg; |
784 | u32 m; | ||
785 | unsigned int iop; | 781 | unsigned int iop; |
786 | 782 | ||
787 | if (get_user(iop, &cmd->iop) || get_user(user_msg, &cmd->msg)) | 783 | if (get_user(iop, &cmd->iop) || get_user(user_msg, &cmd->msg)) |
@@ -793,7 +789,7 @@ static int i2o_cfg_passthru(unsigned long arg) | |||
793 | return -ENXIO; | 789 | return -ENXIO; |
794 | } | 790 | } |
795 | 791 | ||
796 | m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET); | 792 | msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET); |
797 | 793 | ||
798 | sb = c->status_block.virt; | 794 | sb = c->status_block.virt; |
799 | 795 | ||
@@ -820,19 +816,15 @@ static int i2o_cfg_passthru(unsigned long arg) | |||
820 | reply_size >>= 16; | 816 | reply_size >>= 16; |
821 | reply_size <<= 2; | 817 | reply_size <<= 2; |
822 | 818 | ||
823 | reply = kmalloc(reply_size, GFP_KERNEL); | 819 | reply = kzalloc(reply_size, GFP_KERNEL); |
824 | if (!reply) { | 820 | if (!reply) { |
825 | printk(KERN_WARNING "%s: Could not allocate reply buffer\n", | 821 | printk(KERN_WARNING "%s: Could not allocate reply buffer\n", |
826 | c->name); | 822 | c->name); |
827 | return -ENOMEM; | 823 | return -ENOMEM; |
828 | } | 824 | } |
829 | memset(reply, 0, reply_size); | ||
830 | 825 | ||
831 | sg_offset = (msg->u.head[0] >> 4) & 0x0f; | 826 | sg_offset = (msg->u.head[0] >> 4) & 0x0f; |
832 | 827 | ||
833 | writel(i2o_config_driver.context, &msg->u.s.icntxt); | ||
834 | writel(i2o_cntxt_list_add(c, reply), &msg->u.s.tcntxt); | ||
835 | |||
836 | memset(sg_list, 0, sizeof(sg_list[0]) * SG_TABLESIZE); | 828 | memset(sg_list, 0, sizeof(sg_list[0]) * SG_TABLESIZE); |
837 | if (sg_offset) { | 829 | if (sg_offset) { |
838 | struct sg_simple_element *sg; | 830 | struct sg_simple_element *sg; |
@@ -894,9 +886,11 @@ static int i2o_cfg_passthru(unsigned long arg) | |||
894 | } | 886 | } |
895 | } | 887 | } |
896 | 888 | ||
897 | rcode = i2o_msg_post_wait(c, m, 60); | 889 | rcode = i2o_msg_post_wait(c, msg, 60); |
898 | if (rcode) | 890 | if (rcode) { |
891 | reply[4] = ((u32) rcode) << 24; | ||
899 | goto sg_list_cleanup; | 892 | goto sg_list_cleanup; |
893 | } | ||
900 | 894 | ||
901 | if (sg_offset) { | 895 | if (sg_offset) { |
902 | u32 msg[128]; | 896 | u32 msg[128]; |
@@ -946,6 +940,7 @@ static int i2o_cfg_passthru(unsigned long arg) | |||
946 | } | 940 | } |
947 | } | 941 | } |
948 | 942 | ||
943 | sg_list_cleanup: | ||
949 | /* Copy back the reply to user space */ | 944 | /* Copy back the reply to user space */ |
950 | if (reply_size) { | 945 | if (reply_size) { |
951 | // we wrote our own values for context - now restore the user supplied ones | 946 | // we wrote our own values for context - now restore the user supplied ones |
@@ -962,7 +957,6 @@ static int i2o_cfg_passthru(unsigned long arg) | |||
962 | } | 957 | } |
963 | } | 958 | } |
964 | 959 | ||
965 | sg_list_cleanup: | ||
966 | for (i = 0; i < sg_index; i++) | 960 | for (i = 0; i < sg_index; i++) |
967 | kfree(sg_list[i]); | 961 | kfree(sg_list[i]); |
968 | 962 | ||