diff options
Diffstat (limited to 'drivers/scsi/aacraid/commctrl.c')
-rw-r--r-- | drivers/scsi/aacraid/commctrl.c | 221 |
1 files changed, 139 insertions, 82 deletions
diff --git a/drivers/scsi/aacraid/commctrl.c b/drivers/scsi/aacraid/commctrl.c index 30dd1f7120f4..fc268a410c27 100644 --- a/drivers/scsi/aacraid/commctrl.c +++ b/drivers/scsi/aacraid/commctrl.c | |||
@@ -51,15 +51,22 @@ | |||
51 | * This routine sends a fib to the adapter on behalf of a user level | 51 | * This routine sends a fib to the adapter on behalf of a user level |
52 | * program. | 52 | * program. |
53 | */ | 53 | */ |
54 | # define AAC_DEBUG_PREAMBLE KERN_INFO | ||
55 | # define AAC_DEBUG_POSTAMBLE | ||
54 | 56 | ||
55 | static int ioctl_send_fib(struct aac_dev * dev, void __user *arg) | 57 | static int ioctl_send_fib(struct aac_dev * dev, void __user *arg) |
56 | { | 58 | { |
57 | struct hw_fib * kfib; | 59 | struct hw_fib * kfib; |
58 | struct fib *fibptr; | 60 | struct fib *fibptr; |
61 | struct hw_fib * hw_fib = (struct hw_fib *)0; | ||
62 | dma_addr_t hw_fib_pa = (dma_addr_t)0LL; | ||
63 | unsigned size; | ||
64 | int retval; | ||
59 | 65 | ||
60 | fibptr = fib_alloc(dev); | 66 | fibptr = fib_alloc(dev); |
61 | if(fibptr == NULL) | 67 | if(fibptr == NULL) { |
62 | return -ENOMEM; | 68 | return -ENOMEM; |
69 | } | ||
63 | 70 | ||
64 | kfib = fibptr->hw_fib; | 71 | kfib = fibptr->hw_fib; |
65 | /* | 72 | /* |
@@ -74,19 +81,24 @@ static int ioctl_send_fib(struct aac_dev * dev, void __user *arg) | |||
74 | * will not overrun the buffer when we copy the memory. Return | 81 | * will not overrun the buffer when we copy the memory. Return |
75 | * an error if we would. | 82 | * an error if we would. |
76 | */ | 83 | */ |
77 | if (le16_to_cpu(kfib->header.Size) > | 84 | size = le16_to_cpu(kfib->header.Size) + sizeof(struct aac_fibhdr); |
78 | sizeof(struct hw_fib) - sizeof(struct aac_fibhdr)) { | 85 | if (size < le16_to_cpu(kfib->header.SenderSize)) |
79 | fib_free(fibptr); | 86 | size = le16_to_cpu(kfib->header.SenderSize); |
80 | return -EINVAL; | 87 | if (size > dev->max_fib_size) { |
88 | /* Highjack the hw_fib */ | ||
89 | hw_fib = fibptr->hw_fib; | ||
90 | hw_fib_pa = fibptr->hw_fib_pa; | ||
91 | fibptr->hw_fib = kfib = pci_alloc_consistent(dev->pdev, size, &fibptr->hw_fib_pa); | ||
92 | memset(((char *)kfib) + dev->max_fib_size, 0, size - dev->max_fib_size); | ||
93 | memcpy(kfib, hw_fib, dev->max_fib_size); | ||
81 | } | 94 | } |
82 | 95 | ||
83 | if (copy_from_user(kfib, arg, le16_to_cpu(kfib->header.Size) + | 96 | if (copy_from_user(kfib, arg, size)) { |
84 | sizeof(struct aac_fibhdr))) { | 97 | retval = -EFAULT; |
85 | fib_free(fibptr); | 98 | goto cleanup; |
86 | return -EFAULT; | ||
87 | } | 99 | } |
88 | 100 | ||
89 | if (kfib->header.Command == cpu_to_le32(TakeABreakPt)) { | 101 | if (kfib->header.Command == cpu_to_le16(TakeABreakPt)) { |
90 | aac_adapter_interrupt(dev); | 102 | aac_adapter_interrupt(dev); |
91 | /* | 103 | /* |
92 | * Since we didn't really send a fib, zero out the state to allow | 104 | * Since we didn't really send a fib, zero out the state to allow |
@@ -94,16 +106,15 @@ static int ioctl_send_fib(struct aac_dev * dev, void __user *arg) | |||
94 | */ | 106 | */ |
95 | kfib->header.XferState = 0; | 107 | kfib->header.XferState = 0; |
96 | } else { | 108 | } else { |
97 | int retval = fib_send(kfib->header.Command, fibptr, | 109 | retval = fib_send(le16_to_cpu(kfib->header.Command), fibptr, |
98 | le16_to_cpu(kfib->header.Size) , FsaNormal, | 110 | le16_to_cpu(kfib->header.Size) , FsaNormal, |
99 | 1, 1, NULL, NULL); | 111 | 1, 1, NULL, NULL); |
100 | if (retval) { | 112 | if (retval) { |
101 | fib_free(fibptr); | 113 | goto cleanup; |
102 | return retval; | ||
103 | } | 114 | } |
104 | if (fib_complete(fibptr) != 0) { | 115 | if (fib_complete(fibptr) != 0) { |
105 | fib_free(fibptr); | 116 | retval = -EINVAL; |
106 | return -EINVAL; | 117 | goto cleanup; |
107 | } | 118 | } |
108 | } | 119 | } |
109 | /* | 120 | /* |
@@ -114,12 +125,17 @@ static int ioctl_send_fib(struct aac_dev * dev, void __user *arg) | |||
114 | * was already included by the adapter.) | 125 | * was already included by the adapter.) |
115 | */ | 126 | */ |
116 | 127 | ||
117 | if (copy_to_user(arg, (void *)kfib, kfib->header.Size)) { | 128 | retval = 0; |
118 | fib_free(fibptr); | 129 | if (copy_to_user(arg, (void *)kfib, size)) |
119 | return -EFAULT; | 130 | retval = -EFAULT; |
131 | cleanup: | ||
132 | if (hw_fib) { | ||
133 | pci_free_consistent(dev->pdev, size, kfib, fibptr->hw_fib_pa); | ||
134 | fibptr->hw_fib_pa = hw_fib_pa; | ||
135 | fibptr->hw_fib = hw_fib; | ||
120 | } | 136 | } |
121 | fib_free(fibptr); | 137 | fib_free(fibptr); |
122 | return 0; | 138 | return retval; |
123 | } | 139 | } |
124 | 140 | ||
125 | /** | 141 | /** |
@@ -391,26 +407,28 @@ static int check_revision(struct aac_dev *dev, void __user *arg) | |||
391 | struct revision response; | 407 | struct revision response; |
392 | 408 | ||
393 | response.compat = 1; | 409 | response.compat = 1; |
394 | response.version = dev->adapter_info.kernelrev; | 410 | response.version = le32_to_cpu(dev->adapter_info.kernelrev); |
395 | response.build = dev->adapter_info.kernelbuild; | 411 | response.build = le32_to_cpu(dev->adapter_info.kernelbuild); |
396 | 412 | ||
397 | if (copy_to_user(arg, &response, sizeof(response))) | 413 | if (copy_to_user(arg, &response, sizeof(response))) |
398 | return -EFAULT; | 414 | return -EFAULT; |
399 | return 0; | 415 | return 0; |
400 | } | 416 | } |
401 | 417 | ||
418 | |||
402 | /** | 419 | /** |
403 | * | 420 | * |
404 | * aac_send_raw_scb | 421 | * aac_send_raw_scb |
405 | * | 422 | * |
406 | */ | 423 | */ |
407 | 424 | ||
408 | int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) | 425 | static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) |
409 | { | 426 | { |
410 | struct fib* srbfib; | 427 | struct fib* srbfib; |
411 | int status; | 428 | int status; |
412 | struct aac_srb *srbcmd; | 429 | struct aac_srb *srbcmd = NULL; |
413 | struct aac_srb __user *user_srb = arg; | 430 | struct user_aac_srb *user_srbcmd = NULL; |
431 | struct user_aac_srb __user *user_srb = arg; | ||
414 | struct aac_srb_reply __user *user_reply; | 432 | struct aac_srb_reply __user *user_reply; |
415 | struct aac_srb_reply* reply; | 433 | struct aac_srb_reply* reply; |
416 | u32 fibsize = 0; | 434 | u32 fibsize = 0; |
@@ -426,7 +444,7 @@ int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) | |||
426 | 444 | ||
427 | 445 | ||
428 | if (!capable(CAP_SYS_ADMIN)){ | 446 | if (!capable(CAP_SYS_ADMIN)){ |
429 | printk(KERN_DEBUG"aacraid: No permission to send raw srb\n"); | 447 | dprintk((KERN_DEBUG"aacraid: No permission to send raw srb\n")); |
430 | return -EPERM; | 448 | return -EPERM; |
431 | } | 449 | } |
432 | /* | 450 | /* |
@@ -439,37 +457,45 @@ int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) | |||
439 | 457 | ||
440 | srbcmd = (struct aac_srb*) fib_data(srbfib); | 458 | srbcmd = (struct aac_srb*) fib_data(srbfib); |
441 | 459 | ||
460 | memset(sg_list, 0, sizeof(sg_list)); /* cleanup may take issue */ | ||
442 | if(copy_from_user(&fibsize, &user_srb->count,sizeof(u32))){ | 461 | if(copy_from_user(&fibsize, &user_srb->count,sizeof(u32))){ |
443 | printk(KERN_DEBUG"aacraid: Could not copy data size from user\n"); | 462 | dprintk((KERN_DEBUG"aacraid: Could not copy data size from user\n")); |
444 | rcode = -EFAULT; | 463 | rcode = -EFAULT; |
445 | goto cleanup; | 464 | goto cleanup; |
446 | } | 465 | } |
447 | 466 | ||
448 | if (fibsize > FIB_DATA_SIZE_IN_BYTES) { | 467 | if (fibsize > (dev->max_fib_size - sizeof(struct aac_fibhdr))) { |
449 | rcode = -EINVAL; | 468 | rcode = -EINVAL; |
450 | goto cleanup; | 469 | goto cleanup; |
451 | } | 470 | } |
452 | 471 | ||
453 | if(copy_from_user(srbcmd, user_srb,fibsize)){ | 472 | user_srbcmd = kmalloc(GFP_KERNEL, fibsize); |
454 | printk(KERN_DEBUG"aacraid: Could not copy srb from user\n"); | 473 | if (!user_srbcmd) { |
474 | dprintk((KERN_DEBUG"aacraid: Could not make a copy of the srb\n")); | ||
475 | rcode = -ENOMEM; | ||
476 | goto cleanup; | ||
477 | } | ||
478 | if(copy_from_user(user_srbcmd, user_srb,fibsize)){ | ||
479 | dprintk((KERN_DEBUG"aacraid: Could not copy srb from user\n")); | ||
455 | rcode = -EFAULT; | 480 | rcode = -EFAULT; |
456 | goto cleanup; | 481 | goto cleanup; |
457 | } | 482 | } |
458 | 483 | ||
459 | user_reply = arg+fibsize; | 484 | user_reply = arg+fibsize; |
460 | 485 | ||
461 | flags = srbcmd->flags; | 486 | flags = user_srbcmd->flags; /* from user in cpu order */ |
462 | // Fix up srb for endian and force some values | 487 | // Fix up srb for endian and force some values |
488 | |||
463 | srbcmd->function = cpu_to_le32(SRBF_ExecuteScsi); // Force this | 489 | srbcmd->function = cpu_to_le32(SRBF_ExecuteScsi); // Force this |
464 | srbcmd->channel = cpu_to_le32(srbcmd->channel); | 490 | srbcmd->channel = cpu_to_le32(user_srbcmd->channel); |
465 | srbcmd->id = cpu_to_le32(srbcmd->id); | 491 | srbcmd->id = cpu_to_le32(user_srbcmd->id); |
466 | srbcmd->lun = cpu_to_le32(srbcmd->lun); | 492 | srbcmd->lun = cpu_to_le32(user_srbcmd->lun); |
467 | srbcmd->flags = cpu_to_le32(srbcmd->flags); | 493 | srbcmd->flags = cpu_to_le32(flags); |
468 | srbcmd->timeout = cpu_to_le32(srbcmd->timeout); | 494 | srbcmd->timeout = cpu_to_le32(user_srbcmd->timeout); |
469 | srbcmd->retry_limit =cpu_to_le32(0); // Obsolete parameter | 495 | srbcmd->retry_limit =cpu_to_le32(0); // Obsolete parameter |
470 | srbcmd->cdb_size = cpu_to_le32(srbcmd->cdb_size); | 496 | srbcmd->cdb_size = cpu_to_le32(user_srbcmd->cdb_size); |
471 | 497 | ||
472 | switch (srbcmd->flags & (SRB_DataIn | SRB_DataOut)) { | 498 | switch (flags & (SRB_DataIn | SRB_DataOut)) { |
473 | case SRB_DataOut: | 499 | case SRB_DataOut: |
474 | data_dir = DMA_TO_DEVICE; | 500 | data_dir = DMA_TO_DEVICE; |
475 | break; | 501 | break; |
@@ -482,118 +508,148 @@ int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) | |||
482 | default: | 508 | default: |
483 | data_dir = DMA_NONE; | 509 | data_dir = DMA_NONE; |
484 | } | 510 | } |
511 | if (le32_to_cpu(srbcmd->sg.count) > (sizeof(sg_list)/sizeof(sg_list[0]))) { | ||
512 | dprintk((KERN_DEBUG"aacraid: too many sg entries %d\n", | ||
513 | le32_to_cpu(srbcmd->sg.count))); | ||
514 | rcode = -EINVAL; | ||
515 | goto cleanup; | ||
516 | } | ||
485 | if (dev->dac_support == 1) { | 517 | if (dev->dac_support == 1) { |
486 | struct sgmap64* psg = (struct sgmap64*)&srbcmd->sg; | 518 | struct user_sgmap64* upsg = (struct user_sgmap64*)&user_srbcmd->sg; |
519 | struct sgmap64* psg = (struct sgmap64*)&user_srbcmd->sg; | ||
520 | struct user_sgmap* usg; | ||
487 | byte_count = 0; | 521 | byte_count = 0; |
488 | 522 | ||
489 | /* | 523 | /* |
490 | * This should also catch if user used the 32 bit sgmap | 524 | * This should also catch if user used the 32 bit sgmap |
491 | */ | 525 | */ |
492 | actual_fibsize = sizeof(struct aac_srb) - | 526 | actual_fibsize = sizeof(struct aac_srb) - |
493 | sizeof(struct sgentry) + ((srbcmd->sg.count & 0xff) * | 527 | sizeof(struct sgentry) + |
494 | sizeof(struct sgentry64)); | 528 | ((upsg->count & 0xff) * |
529 | sizeof(struct sgentry)); | ||
495 | if(actual_fibsize != fibsize){ // User made a mistake - should not continue | 530 | if(actual_fibsize != fibsize){ // User made a mistake - should not continue |
496 | printk(KERN_DEBUG"aacraid: Bad Size specified in Raw SRB command\n"); | 531 | dprintk((KERN_DEBUG"aacraid: Bad Size specified in Raw SRB command\n")); |
497 | rcode = -EINVAL; | 532 | rcode = -EINVAL; |
498 | goto cleanup; | 533 | goto cleanup; |
499 | } | 534 | } |
500 | if ((data_dir == DMA_NONE) && psg->count) { | 535 | usg = kmalloc(actual_fibsize - sizeof(struct aac_srb) |
501 | printk(KERN_DEBUG"aacraid: SG with no direction specified in Raw SRB command\n"); | 536 | + sizeof(struct sgmap), GFP_KERNEL); |
537 | if (!usg) { | ||
538 | dprintk((KERN_DEBUG"aacraid: Allocation error in Raw SRB command\n")); | ||
539 | rcode = -ENOMEM; | ||
540 | goto cleanup; | ||
541 | } | ||
542 | memcpy (usg, upsg, actual_fibsize - sizeof(struct aac_srb) | ||
543 | + sizeof(struct sgmap)); | ||
544 | actual_fibsize = sizeof(struct aac_srb) - | ||
545 | sizeof(struct sgentry) + ((usg->count & 0xff) * | ||
546 | sizeof(struct sgentry64)); | ||
547 | if ((data_dir == DMA_NONE) && upsg->count) { | ||
548 | kfree (usg); | ||
549 | dprintk((KERN_DEBUG"aacraid: SG with no direction specified in Raw SRB command\n")); | ||
502 | rcode = -EINVAL; | 550 | rcode = -EINVAL; |
503 | goto cleanup; | 551 | goto cleanup; |
504 | } | 552 | } |
505 | 553 | ||
506 | for (i = 0; i < psg->count; i++) { | 554 | for (i = 0; i < usg->count; i++) { |
507 | dma_addr_t addr; | 555 | u64 addr; |
508 | u64 le_addr; | ||
509 | void* p; | 556 | void* p; |
510 | p = kmalloc(psg->sg[i].count,GFP_KERNEL|__GFP_DMA); | 557 | /* Does this really need to be GFP_DMA? */ |
558 | p = kmalloc(usg->sg[i].count,GFP_KERNEL|__GFP_DMA); | ||
511 | if(p == 0) { | 559 | if(p == 0) { |
512 | printk(KERN_DEBUG"aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n", | 560 | kfree (usg); |
513 | psg->sg[i].count,i,psg->count); | 561 | dprintk((KERN_DEBUG"aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n", |
562 | usg->sg[i].count,i,usg->count)); | ||
514 | rcode = -ENOMEM; | 563 | rcode = -ENOMEM; |
515 | goto cleanup; | 564 | goto cleanup; |
516 | } | 565 | } |
517 | sg_user[i] = (void __user *)psg->sg[i].addr; | 566 | sg_user[i] = (void __user *)usg->sg[i].addr; |
518 | sg_list[i] = p; // save so we can clean up later | 567 | sg_list[i] = p; // save so we can clean up later |
519 | sg_indx = i; | 568 | sg_indx = i; |
520 | 569 | ||
521 | if( flags & SRB_DataOut ){ | 570 | if( flags & SRB_DataOut ){ |
522 | if(copy_from_user(p,sg_user[i],psg->sg[i].count)){ | 571 | if(copy_from_user(p,sg_user[i],upsg->sg[i].count)){ |
523 | printk(KERN_DEBUG"aacraid: Could not copy sg data from user\n"); | 572 | kfree (usg); |
573 | dprintk((KERN_DEBUG"aacraid: Could not copy sg data from user\n")); | ||
524 | rcode = -EFAULT; | 574 | rcode = -EFAULT; |
525 | goto cleanup; | 575 | goto cleanup; |
526 | } | 576 | } |
527 | } | 577 | } |
528 | addr = pci_map_single(dev->pdev, p, psg->sg[i].count, data_dir); | 578 | addr = pci_map_single(dev->pdev, p, usg->sg[i].count, data_dir); |
529 | 579 | ||
530 | le_addr = cpu_to_le64(addr); | 580 | psg->sg[i].addr[0] = cpu_to_le32(addr & 0xffffffff); |
531 | psg->sg[i].addr[1] = (u32)(le_addr>>32); | 581 | psg->sg[i].addr[1] = cpu_to_le32(addr>>32); |
532 | psg->sg[i].addr[0] = (u32)(le_addr & 0xffffffff); | 582 | psg->sg[i].count = cpu_to_le32(usg->sg[i].count); |
533 | psg->sg[i].count = cpu_to_le32(psg->sg[i].count); | 583 | byte_count += usg->sg[i].count; |
534 | byte_count += psg->sg[i].count; | ||
535 | } | 584 | } |
585 | kfree (usg); | ||
536 | 586 | ||
537 | srbcmd->count = cpu_to_le32(byte_count); | 587 | srbcmd->count = cpu_to_le32(byte_count); |
588 | psg->count = cpu_to_le32(sg_indx+1); | ||
538 | status = fib_send(ScsiPortCommand64, srbfib, actual_fibsize, FsaNormal, 1, 1,NULL,NULL); | 589 | status = fib_send(ScsiPortCommand64, srbfib, actual_fibsize, FsaNormal, 1, 1,NULL,NULL); |
539 | } else { | 590 | } else { |
591 | struct user_sgmap* upsg = &user_srbcmd->sg; | ||
540 | struct sgmap* psg = &srbcmd->sg; | 592 | struct sgmap* psg = &srbcmd->sg; |
541 | byte_count = 0; | 593 | byte_count = 0; |
542 | 594 | ||
543 | actual_fibsize = sizeof (struct aac_srb) + | 595 | actual_fibsize = sizeof (struct aac_srb) + (((le32_to_cpu(srbcmd->sg.count) & 0xff) - 1) * sizeof (struct sgentry)); |
544 | (((le32_to_cpu(srbcmd->sg.count) & 0xff) - 1) * | ||
545 | sizeof (struct sgentry)); | ||
546 | if(actual_fibsize != fibsize){ // User made a mistake - should not continue | 596 | if(actual_fibsize != fibsize){ // User made a mistake - should not continue |
547 | printk(KERN_DEBUG"aacraid: Bad Size specified in Raw SRB command\n"); | 597 | dprintk((KERN_DEBUG"aacraid: Bad Size specified in Raw SRB command\n")); |
548 | rcode = -EINVAL; | 598 | rcode = -EINVAL; |
549 | goto cleanup; | 599 | goto cleanup; |
550 | } | 600 | } |
551 | if ((data_dir == DMA_NONE) && psg->count) { | 601 | if ((data_dir == DMA_NONE) && upsg->count) { |
552 | printk(KERN_DEBUG"aacraid: SG with no direction specified in Raw SRB command\n"); | 602 | dprintk((KERN_DEBUG"aacraid: SG with no direction specified in Raw SRB command\n")); |
553 | rcode = -EINVAL; | 603 | rcode = -EINVAL; |
554 | goto cleanup; | 604 | goto cleanup; |
555 | } | 605 | } |
556 | for (i = 0; i < psg->count; i++) { | 606 | for (i = 0; i < upsg->count; i++) { |
557 | dma_addr_t addr; | 607 | dma_addr_t addr; |
558 | void* p; | 608 | void* p; |
559 | p = kmalloc(psg->sg[i].count,GFP_KERNEL); | 609 | p = kmalloc(upsg->sg[i].count, GFP_KERNEL); |
560 | if(p == 0) { | 610 | if(p == 0) { |
561 | printk(KERN_DEBUG"aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n", | 611 | dprintk((KERN_DEBUG"aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n", |
562 | psg->sg[i].count,i,psg->count); | 612 | upsg->sg[i].count, i, upsg->count)); |
563 | rcode = -ENOMEM; | 613 | rcode = -ENOMEM; |
564 | goto cleanup; | 614 | goto cleanup; |
565 | } | 615 | } |
566 | sg_user[i] = (void __user *)(psg->sg[i].addr); | 616 | sg_user[i] = (void __user *)upsg->sg[i].addr; |
567 | sg_list[i] = p; // save so we can clean up later | 617 | sg_list[i] = p; // save so we can clean up later |
568 | sg_indx = i; | 618 | sg_indx = i; |
569 | 619 | ||
570 | if( flags & SRB_DataOut ){ | 620 | if( flags & SRB_DataOut ){ |
571 | if(copy_from_user(p,sg_user[i],psg->sg[i].count)){ | 621 | if(copy_from_user(p, sg_user[i], |
572 | printk(KERN_DEBUG"aacraid: Could not copy sg data from user\n"); | 622 | upsg->sg[i].count)) { |
623 | dprintk((KERN_DEBUG"aacraid: Could not copy sg data from user\n")); | ||
573 | rcode = -EFAULT; | 624 | rcode = -EFAULT; |
574 | goto cleanup; | 625 | goto cleanup; |
575 | } | 626 | } |
576 | } | 627 | } |
577 | addr = pci_map_single(dev->pdev, p, psg->sg[i].count, data_dir); | 628 | addr = pci_map_single(dev->pdev, p, |
629 | upsg->sg[i].count, data_dir); | ||
578 | 630 | ||
579 | psg->sg[i].addr = cpu_to_le32(addr); | 631 | psg->sg[i].addr = cpu_to_le32(addr); |
580 | psg->sg[i].count = cpu_to_le32(psg->sg[i].count); | 632 | psg->sg[i].count = cpu_to_le32(upsg->sg[i].count); |
581 | byte_count += psg->sg[i].count; | 633 | byte_count += upsg->sg[i].count; |
582 | } | 634 | } |
583 | srbcmd->count = cpu_to_le32(byte_count); | 635 | srbcmd->count = cpu_to_le32(byte_count); |
636 | psg->count = cpu_to_le32(sg_indx+1); | ||
584 | status = fib_send(ScsiPortCommand, srbfib, actual_fibsize, FsaNormal, 1, 1, NULL, NULL); | 637 | status = fib_send(ScsiPortCommand, srbfib, actual_fibsize, FsaNormal, 1, 1, NULL, NULL); |
585 | } | 638 | } |
586 | 639 | ||
587 | if (status != 0){ | 640 | if (status != 0){ |
588 | printk(KERN_DEBUG"aacraid: Could not send raw srb fib to hba\n"); | 641 | dprintk((KERN_DEBUG"aacraid: Could not send raw srb fib to hba\n")); |
589 | rcode = -1; | 642 | rcode = -1; |
590 | goto cleanup; | 643 | goto cleanup; |
591 | } | 644 | } |
592 | 645 | ||
593 | if( flags & SRB_DataIn ) { | 646 | if( flags & SRB_DataIn ) { |
594 | for(i = 0 ; i <= sg_indx; i++){ | 647 | for(i = 0 ; i <= sg_indx; i++){ |
595 | if(copy_to_user(sg_user[i],sg_list[i],le32_to_cpu(srbcmd->sg.sg[i].count))){ | 648 | byte_count = le32_to_cpu((dev->dac_support == 1) |
596 | printk(KERN_DEBUG"aacraid: Could not copy sg data to user\n"); | 649 | ? ((struct sgmap64*)&srbcmd->sg)->sg[i].count |
650 | : srbcmd->sg.sg[i].count); | ||
651 | if(copy_to_user(sg_user[i], sg_list[i], byte_count)){ | ||
652 | dprintk((KERN_DEBUG"aacraid: Could not copy sg data to user\n")); | ||
597 | rcode = -EFAULT; | 653 | rcode = -EFAULT; |
598 | goto cleanup; | 654 | goto cleanup; |
599 | 655 | ||
@@ -603,12 +659,13 @@ int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) | |||
603 | 659 | ||
604 | reply = (struct aac_srb_reply *) fib_data(srbfib); | 660 | reply = (struct aac_srb_reply *) fib_data(srbfib); |
605 | if(copy_to_user(user_reply,reply,sizeof(struct aac_srb_reply))){ | 661 | if(copy_to_user(user_reply,reply,sizeof(struct aac_srb_reply))){ |
606 | printk(KERN_DEBUG"aacraid: Could not copy reply to user\n"); | 662 | dprintk((KERN_DEBUG"aacraid: Could not copy reply to user\n")); |
607 | rcode = -EFAULT; | 663 | rcode = -EFAULT; |
608 | goto cleanup; | 664 | goto cleanup; |
609 | } | 665 | } |
610 | 666 | ||
611 | cleanup: | 667 | cleanup: |
668 | kfree(user_srbcmd); | ||
612 | for(i=0; i <= sg_indx; i++){ | 669 | for(i=0; i <= sg_indx; i++){ |
613 | kfree(sg_list[i]); | 670 | kfree(sg_list[i]); |
614 | } | 671 | } |
@@ -618,14 +675,13 @@ cleanup: | |||
618 | return rcode; | 675 | return rcode; |
619 | } | 676 | } |
620 | 677 | ||
621 | |||
622 | struct aac_pci_info { | 678 | struct aac_pci_info { |
623 | u32 bus; | 679 | u32 bus; |
624 | u32 slot; | 680 | u32 slot; |
625 | }; | 681 | }; |
626 | 682 | ||
627 | 683 | ||
628 | int aac_get_pci_info(struct aac_dev* dev, void __user *arg) | 684 | static int aac_get_pci_info(struct aac_dev* dev, void __user *arg) |
629 | { | 685 | { |
630 | struct aac_pci_info pci_info; | 686 | struct aac_pci_info pci_info; |
631 | 687 | ||
@@ -633,11 +689,11 @@ int aac_get_pci_info(struct aac_dev* dev, void __user *arg) | |||
633 | pci_info.slot = PCI_SLOT(dev->pdev->devfn); | 689 | pci_info.slot = PCI_SLOT(dev->pdev->devfn); |
634 | 690 | ||
635 | if (copy_to_user(arg, &pci_info, sizeof(struct aac_pci_info))) { | 691 | if (copy_to_user(arg, &pci_info, sizeof(struct aac_pci_info))) { |
636 | printk(KERN_DEBUG "aacraid: Could not copy pci info\n"); | 692 | dprintk((KERN_DEBUG "aacraid: Could not copy pci info\n")); |
637 | return -EFAULT; | 693 | return -EFAULT; |
638 | } | 694 | } |
639 | return 0; | 695 | return 0; |
640 | } | 696 | } |
641 | 697 | ||
642 | 698 | ||
643 | int aac_do_ioctl(struct aac_dev * dev, int cmd, void __user *arg) | 699 | int aac_do_ioctl(struct aac_dev * dev, int cmd, void __user *arg) |
@@ -656,6 +712,7 @@ int aac_do_ioctl(struct aac_dev * dev, int cmd, void __user *arg) | |||
656 | case FSACTL_MINIPORT_REV_CHECK: | 712 | case FSACTL_MINIPORT_REV_CHECK: |
657 | status = check_revision(dev, arg); | 713 | status = check_revision(dev, arg); |
658 | break; | 714 | break; |
715 | case FSACTL_SEND_LARGE_FIB: | ||
659 | case FSACTL_SENDFIB: | 716 | case FSACTL_SENDFIB: |
660 | status = ioctl_send_fib(dev, arg); | 717 | status = ioctl_send_fib(dev, arg); |
661 | break; | 718 | break; |