diff options
Diffstat (limited to 'drivers/scsi/aacraid/commctrl.c')
-rw-r--r-- | drivers/scsi/aacraid/commctrl.c | 286 |
1 files changed, 173 insertions, 113 deletions
diff --git a/drivers/scsi/aacraid/commctrl.c b/drivers/scsi/aacraid/commctrl.c index e21070f4eac1..72b0393b4596 100644 --- a/drivers/scsi/aacraid/commctrl.c +++ b/drivers/scsi/aacraid/commctrl.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * based on the old aacraid driver that is.. | 5 | * based on the old aacraid driver that is.. |
6 | * Adaptec aacraid device driver for Linux. | 6 | * Adaptec aacraid device driver for Linux. |
7 | * | 7 | * |
8 | * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com) | 8 | * Copyright (c) 2000-2007 Adaptec, Inc. (aacraid@adaptec.com) |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of the GNU General Public License as published by | 11 | * it under the terms of the GNU General Public License as published by |
@@ -64,12 +64,15 @@ static int ioctl_send_fib(struct aac_dev * dev, void __user *arg) | |||
64 | unsigned size; | 64 | unsigned size; |
65 | int retval; | 65 | int retval; |
66 | 66 | ||
67 | if (dev->in_reset) { | ||
68 | return -EBUSY; | ||
69 | } | ||
67 | fibptr = aac_fib_alloc(dev); | 70 | fibptr = aac_fib_alloc(dev); |
68 | if(fibptr == NULL) { | 71 | if(fibptr == NULL) { |
69 | return -ENOMEM; | 72 | return -ENOMEM; |
70 | } | 73 | } |
71 | 74 | ||
72 | kfib = fibptr->hw_fib; | 75 | kfib = fibptr->hw_fib_va; |
73 | /* | 76 | /* |
74 | * First copy in the header so that we can check the size field. | 77 | * First copy in the header so that we can check the size field. |
75 | */ | 78 | */ |
@@ -91,9 +94,9 @@ static int ioctl_send_fib(struct aac_dev * dev, void __user *arg) | |||
91 | goto cleanup; | 94 | goto cleanup; |
92 | } | 95 | } |
93 | /* Highjack the hw_fib */ | 96 | /* Highjack the hw_fib */ |
94 | hw_fib = fibptr->hw_fib; | 97 | hw_fib = fibptr->hw_fib_va; |
95 | hw_fib_pa = fibptr->hw_fib_pa; | 98 | hw_fib_pa = fibptr->hw_fib_pa; |
96 | fibptr->hw_fib = kfib = pci_alloc_consistent(dev->pdev, size, &fibptr->hw_fib_pa); | 99 | fibptr->hw_fib_va = kfib = pci_alloc_consistent(dev->pdev, size, &fibptr->hw_fib_pa); |
97 | memset(((char *)kfib) + dev->max_fib_size, 0, size - dev->max_fib_size); | 100 | memset(((char *)kfib) + dev->max_fib_size, 0, size - dev->max_fib_size); |
98 | memcpy(kfib, hw_fib, dev->max_fib_size); | 101 | memcpy(kfib, hw_fib, dev->max_fib_size); |
99 | } | 102 | } |
@@ -137,7 +140,7 @@ cleanup: | |||
137 | if (hw_fib) { | 140 | if (hw_fib) { |
138 | pci_free_consistent(dev->pdev, size, kfib, fibptr->hw_fib_pa); | 141 | pci_free_consistent(dev->pdev, size, kfib, fibptr->hw_fib_pa); |
139 | fibptr->hw_fib_pa = hw_fib_pa; | 142 | fibptr->hw_fib_pa = hw_fib_pa; |
140 | fibptr->hw_fib = hw_fib; | 143 | fibptr->hw_fib_va = hw_fib; |
141 | } | 144 | } |
142 | if (retval != -EINTR) | 145 | if (retval != -EINTR) |
143 | aac_fib_free(fibptr); | 146 | aac_fib_free(fibptr); |
@@ -282,15 +285,15 @@ return_fib: | |||
282 | fib = list_entry(entry, struct fib, fiblink); | 285 | fib = list_entry(entry, struct fib, fiblink); |
283 | fibctx->count--; | 286 | fibctx->count--; |
284 | spin_unlock_irqrestore(&dev->fib_lock, flags); | 287 | spin_unlock_irqrestore(&dev->fib_lock, flags); |
285 | if (copy_to_user(f.fib, fib->hw_fib, sizeof(struct hw_fib))) { | 288 | if (copy_to_user(f.fib, fib->hw_fib_va, sizeof(struct hw_fib))) { |
286 | kfree(fib->hw_fib); | 289 | kfree(fib->hw_fib_va); |
287 | kfree(fib); | 290 | kfree(fib); |
288 | return -EFAULT; | 291 | return -EFAULT; |
289 | } | 292 | } |
290 | /* | 293 | /* |
291 | * Free the space occupied by this copy of the fib. | 294 | * Free the space occupied by this copy of the fib. |
292 | */ | 295 | */ |
293 | kfree(fib->hw_fib); | 296 | kfree(fib->hw_fib_va); |
294 | kfree(fib); | 297 | kfree(fib); |
295 | status = 0; | 298 | status = 0; |
296 | } else { | 299 | } else { |
@@ -340,7 +343,7 @@ int aac_close_fib_context(struct aac_dev * dev, struct aac_fib_context * fibctx) | |||
340 | /* | 343 | /* |
341 | * Free the space occupied by this copy of the fib. | 344 | * Free the space occupied by this copy of the fib. |
342 | */ | 345 | */ |
343 | kfree(fib->hw_fib); | 346 | kfree(fib->hw_fib_va); |
344 | kfree(fib); | 347 | kfree(fib); |
345 | } | 348 | } |
346 | /* | 349 | /* |
@@ -388,10 +391,8 @@ static int close_getadapter_fib(struct aac_dev * dev, void __user *arg) | |||
388 | /* | 391 | /* |
389 | * Extract the fibctx from the input parameters | 392 | * Extract the fibctx from the input parameters |
390 | */ | 393 | */ |
391 | if (fibctx->unique == (u32)(unsigned long)arg) { | 394 | if (fibctx->unique == (u32)(ptrdiff_t)arg) /* We found a winner */ |
392 | /* We found a winner */ | ||
393 | break; | 395 | break; |
394 | } | ||
395 | entry = entry->next; | 396 | entry = entry->next; |
396 | fibctx = NULL; | 397 | fibctx = NULL; |
397 | } | 398 | } |
@@ -465,16 +466,20 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) | |||
465 | void *sg_list[32]; | 466 | void *sg_list[32]; |
466 | u32 sg_indx = 0; | 467 | u32 sg_indx = 0; |
467 | u32 byte_count = 0; | 468 | u32 byte_count = 0; |
468 | u32 actual_fibsize = 0; | 469 | u32 actual_fibsize64, actual_fibsize = 0; |
469 | int i; | 470 | int i; |
470 | 471 | ||
471 | 472 | ||
473 | if (dev->in_reset) { | ||
474 | dprintk((KERN_DEBUG"aacraid: send raw srb -EBUSY\n")); | ||
475 | return -EBUSY; | ||
476 | } | ||
472 | if (!capable(CAP_SYS_ADMIN)){ | 477 | if (!capable(CAP_SYS_ADMIN)){ |
473 | dprintk((KERN_DEBUG"aacraid: No permission to send raw srb\n")); | 478 | dprintk((KERN_DEBUG"aacraid: No permission to send raw srb\n")); |
474 | return -EPERM; | 479 | return -EPERM; |
475 | } | 480 | } |
476 | /* | 481 | /* |
477 | * Allocate and initialize a Fib then setup a BlockWrite command | 482 | * Allocate and initialize a Fib then setup a SRB command |
478 | */ | 483 | */ |
479 | if (!(srbfib = aac_fib_alloc(dev))) { | 484 | if (!(srbfib = aac_fib_alloc(dev))) { |
480 | return -ENOMEM; | 485 | return -ENOMEM; |
@@ -541,129 +546,183 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) | |||
541 | rcode = -EINVAL; | 546 | rcode = -EINVAL; |
542 | goto cleanup; | 547 | goto cleanup; |
543 | } | 548 | } |
544 | if (dev->dac_support == 1) { | 549 | actual_fibsize = sizeof(struct aac_srb) - sizeof(struct sgentry) + |
550 | ((user_srbcmd->sg.count & 0xff) * sizeof(struct sgentry)); | ||
551 | actual_fibsize64 = actual_fibsize + (user_srbcmd->sg.count & 0xff) * | ||
552 | (sizeof(struct sgentry64) - sizeof(struct sgentry)); | ||
553 | /* User made a mistake - should not continue */ | ||
554 | if ((actual_fibsize != fibsize) && (actual_fibsize64 != fibsize)) { | ||
555 | dprintk((KERN_DEBUG"aacraid: Bad Size specified in " | ||
556 | "Raw SRB command calculated fibsize=%lu;%lu " | ||
557 | "user_srbcmd->sg.count=%d aac_srb=%lu sgentry=%lu;%lu " | ||
558 | "issued fibsize=%d\n", | ||
559 | actual_fibsize, actual_fibsize64, user_srbcmd->sg.count, | ||
560 | sizeof(struct aac_srb), sizeof(struct sgentry), | ||
561 | sizeof(struct sgentry64), fibsize)); | ||
562 | rcode = -EINVAL; | ||
563 | goto cleanup; | ||
564 | } | ||
565 | if ((data_dir == DMA_NONE) && user_srbcmd->sg.count) { | ||
566 | dprintk((KERN_DEBUG"aacraid: SG with no direction specified in Raw SRB command\n")); | ||
567 | rcode = -EINVAL; | ||
568 | goto cleanup; | ||
569 | } | ||
570 | byte_count = 0; | ||
571 | if (dev->adapter_info.options & AAC_OPT_SGMAP_HOST64) { | ||
545 | struct user_sgmap64* upsg = (struct user_sgmap64*)&user_srbcmd->sg; | 572 | struct user_sgmap64* upsg = (struct user_sgmap64*)&user_srbcmd->sg; |
546 | struct sgmap64* psg = (struct sgmap64*)&srbcmd->sg; | 573 | struct sgmap64* psg = (struct sgmap64*)&srbcmd->sg; |
547 | struct user_sgmap* usg; | ||
548 | byte_count = 0; | ||
549 | 574 | ||
550 | /* | 575 | /* |
551 | * This should also catch if user used the 32 bit sgmap | 576 | * This should also catch if user used the 32 bit sgmap |
552 | */ | 577 | */ |
553 | actual_fibsize = sizeof(struct aac_srb) - | 578 | if (actual_fibsize64 == fibsize) { |
554 | sizeof(struct sgentry) + | 579 | actual_fibsize = actual_fibsize64; |
555 | ((upsg->count & 0xff) * | 580 | for (i = 0; i < upsg->count; i++) { |
556 | sizeof(struct sgentry)); | 581 | u64 addr; |
557 | if(actual_fibsize != fibsize){ // User made a mistake - should not continue | 582 | void* p; |
558 | dprintk((KERN_DEBUG"aacraid: Bad Size specified in Raw SRB command\n")); | 583 | /* Does this really need to be GFP_DMA? */ |
559 | rcode = -EINVAL; | 584 | p = kmalloc(upsg->sg[i].count,GFP_KERNEL|__GFP_DMA); |
560 | goto cleanup; | 585 | if(p == 0) { |
561 | } | 586 | dprintk((KERN_DEBUG"aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n", |
562 | usg = kmalloc(actual_fibsize - sizeof(struct aac_srb) | 587 | upsg->sg[i].count,i,upsg->count)); |
563 | + sizeof(struct sgmap), GFP_KERNEL); | 588 | rcode = -ENOMEM; |
564 | if (!usg) { | 589 | goto cleanup; |
565 | dprintk((KERN_DEBUG"aacraid: Allocation error in Raw SRB command\n")); | 590 | } |
566 | rcode = -ENOMEM; | 591 | addr = (u64)upsg->sg[i].addr[0]; |
567 | goto cleanup; | 592 | addr += ((u64)upsg->sg[i].addr[1]) << 32; |
568 | } | 593 | sg_user[i] = (void __user *)(ptrdiff_t)addr; |
569 | memcpy (usg, upsg, actual_fibsize - sizeof(struct aac_srb) | 594 | sg_list[i] = p; // save so we can clean up later |
570 | + sizeof(struct sgmap)); | 595 | sg_indx = i; |
571 | actual_fibsize = sizeof(struct aac_srb) - | 596 | |
572 | sizeof(struct sgentry) + ((usg->count & 0xff) * | 597 | if( flags & SRB_DataOut ){ |
573 | sizeof(struct sgentry64)); | 598 | if(copy_from_user(p,sg_user[i],upsg->sg[i].count)){ |
574 | if ((data_dir == DMA_NONE) && upsg->count) { | 599 | dprintk((KERN_DEBUG"aacraid: Could not copy sg data from user\n")); |
575 | kfree (usg); | 600 | rcode = -EFAULT; |
576 | dprintk((KERN_DEBUG"aacraid: SG with no direction specified in Raw SRB command\n")); | 601 | goto cleanup; |
577 | rcode = -EINVAL; | 602 | } |
578 | goto cleanup; | 603 | } |
579 | } | 604 | addr = pci_map_single(dev->pdev, p, upsg->sg[i].count, data_dir); |
580 | 605 | ||
581 | for (i = 0; i < usg->count; i++) { | 606 | psg->sg[i].addr[0] = cpu_to_le32(addr & 0xffffffff); |
582 | u64 addr; | 607 | psg->sg[i].addr[1] = cpu_to_le32(addr>>32); |
583 | void* p; | 608 | byte_count += upsg->sg[i].count; |
584 | /* Does this really need to be GFP_DMA? */ | 609 | psg->sg[i].count = cpu_to_le32(upsg->sg[i].count); |
585 | p = kmalloc(usg->sg[i].count,GFP_KERNEL|__GFP_DMA); | 610 | } |
586 | if(p == 0) { | 611 | } else { |
587 | kfree (usg); | 612 | struct user_sgmap* usg; |
588 | dprintk((KERN_DEBUG"aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n", | 613 | usg = kmalloc(actual_fibsize - sizeof(struct aac_srb) |
589 | usg->sg[i].count,i,usg->count)); | 614 | + sizeof(struct sgmap), GFP_KERNEL); |
615 | if (!usg) { | ||
616 | dprintk((KERN_DEBUG"aacraid: Allocation error in Raw SRB command\n")); | ||
590 | rcode = -ENOMEM; | 617 | rcode = -ENOMEM; |
591 | goto cleanup; | 618 | goto cleanup; |
592 | } | 619 | } |
593 | sg_user[i] = (void __user *)(long)usg->sg[i].addr; | 620 | memcpy (usg, upsg, actual_fibsize - sizeof(struct aac_srb) |
594 | sg_list[i] = p; // save so we can clean up later | 621 | + sizeof(struct sgmap)); |
595 | sg_indx = i; | 622 | actual_fibsize = actual_fibsize64; |
596 | 623 | ||
597 | if( flags & SRB_DataOut ){ | 624 | for (i = 0; i < usg->count; i++) { |
598 | if(copy_from_user(p,sg_user[i],upsg->sg[i].count)){ | 625 | u64 addr; |
626 | void* p; | ||
627 | /* Does this really need to be GFP_DMA? */ | ||
628 | p = kmalloc(usg->sg[i].count,GFP_KERNEL|__GFP_DMA); | ||
629 | if(p == 0) { | ||
599 | kfree (usg); | 630 | kfree (usg); |
600 | dprintk((KERN_DEBUG"aacraid: Could not copy sg data from user\n")); | 631 | dprintk((KERN_DEBUG"aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n", |
601 | rcode = -EFAULT; | 632 | usg->sg[i].count,i,usg->count)); |
633 | rcode = -ENOMEM; | ||
602 | goto cleanup; | 634 | goto cleanup; |
603 | } | 635 | } |
604 | } | 636 | sg_user[i] = (void __user *)(ptrdiff_t)usg->sg[i].addr; |
605 | addr = pci_map_single(dev->pdev, p, usg->sg[i].count, data_dir); | 637 | sg_list[i] = p; // save so we can clean up later |
638 | sg_indx = i; | ||
639 | |||
640 | if( flags & SRB_DataOut ){ | ||
641 | if(copy_from_user(p,sg_user[i],upsg->sg[i].count)){ | ||
642 | kfree (usg); | ||
643 | dprintk((KERN_DEBUG"aacraid: Could not copy sg data from user\n")); | ||
644 | rcode = -EFAULT; | ||
645 | goto cleanup; | ||
646 | } | ||
647 | } | ||
648 | addr = pci_map_single(dev->pdev, p, usg->sg[i].count, data_dir); | ||
606 | 649 | ||
607 | psg->sg[i].addr[0] = cpu_to_le32(addr & 0xffffffff); | 650 | psg->sg[i].addr[0] = cpu_to_le32(addr & 0xffffffff); |
608 | psg->sg[i].addr[1] = cpu_to_le32(addr>>32); | 651 | psg->sg[i].addr[1] = cpu_to_le32(addr>>32); |
609 | psg->sg[i].count = cpu_to_le32(usg->sg[i].count); | 652 | byte_count += usg->sg[i].count; |
610 | byte_count += usg->sg[i].count; | 653 | psg->sg[i].count = cpu_to_le32(usg->sg[i].count); |
654 | } | ||
655 | kfree (usg); | ||
611 | } | 656 | } |
612 | kfree (usg); | ||
613 | |||
614 | srbcmd->count = cpu_to_le32(byte_count); | 657 | srbcmd->count = cpu_to_le32(byte_count); |
615 | psg->count = cpu_to_le32(sg_indx+1); | 658 | psg->count = cpu_to_le32(sg_indx+1); |
616 | status = aac_fib_send(ScsiPortCommand64, srbfib, actual_fibsize, FsaNormal, 1, 1,NULL,NULL); | 659 | status = aac_fib_send(ScsiPortCommand64, srbfib, actual_fibsize, FsaNormal, 1, 1,NULL,NULL); |
617 | } else { | 660 | } else { |
618 | struct user_sgmap* upsg = &user_srbcmd->sg; | 661 | struct user_sgmap* upsg = &user_srbcmd->sg; |
619 | struct sgmap* psg = &srbcmd->sg; | 662 | struct sgmap* psg = &srbcmd->sg; |
620 | byte_count = 0; | 663 | |
621 | 664 | if (actual_fibsize64 == fibsize) { | |
622 | actual_fibsize = sizeof (struct aac_srb) + (((user_srbcmd->sg.count & 0xff) - 1) * sizeof (struct sgentry)); | 665 | struct user_sgmap64* usg = (struct user_sgmap64 *)upsg; |
623 | if(actual_fibsize != fibsize){ // User made a mistake - should not continue | 666 | for (i = 0; i < upsg->count; i++) { |
624 | dprintk((KERN_DEBUG"aacraid: Bad Size specified in " | 667 | u64 addr; |
625 | "Raw SRB command calculated fibsize=%d " | 668 | void* p; |
626 | "user_srbcmd->sg.count=%d aac_srb=%d sgentry=%d " | 669 | /* Does this really need to be GFP_DMA? */ |
627 | "issued fibsize=%d\n", | 670 | p = kmalloc(usg->sg[i].count,GFP_KERNEL|__GFP_DMA); |
628 | actual_fibsize, user_srbcmd->sg.count, | 671 | if(p == 0) { |
629 | sizeof(struct aac_srb), sizeof(struct sgentry), | 672 | dprintk((KERN_DEBUG"aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n", |
630 | fibsize)); | 673 | usg->sg[i].count,i,usg->count)); |
631 | rcode = -EINVAL; | 674 | rcode = -ENOMEM; |
632 | goto cleanup; | ||
633 | } | ||
634 | if ((data_dir == DMA_NONE) && upsg->count) { | ||
635 | dprintk((KERN_DEBUG"aacraid: SG with no direction specified in Raw SRB command\n")); | ||
636 | rcode = -EINVAL; | ||
637 | goto cleanup; | ||
638 | } | ||
639 | for (i = 0; i < upsg->count; i++) { | ||
640 | dma_addr_t addr; | ||
641 | void* p; | ||
642 | p = kmalloc(upsg->sg[i].count, GFP_KERNEL); | ||
643 | if(p == 0) { | ||
644 | dprintk((KERN_DEBUG"aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n", | ||
645 | upsg->sg[i].count, i, upsg->count)); | ||
646 | rcode = -ENOMEM; | ||
647 | goto cleanup; | ||
648 | } | ||
649 | sg_user[i] = (void __user *)(long)upsg->sg[i].addr; | ||
650 | sg_list[i] = p; // save so we can clean up later | ||
651 | sg_indx = i; | ||
652 | |||
653 | if( flags & SRB_DataOut ){ | ||
654 | if(copy_from_user(p, sg_user[i], | ||
655 | upsg->sg[i].count)) { | ||
656 | dprintk((KERN_DEBUG"aacraid: Could not copy sg data from user\n")); | ||
657 | rcode = -EFAULT; | ||
658 | goto cleanup; | 675 | goto cleanup; |
659 | } | 676 | } |
677 | addr = (u64)usg->sg[i].addr[0]; | ||
678 | addr += ((u64)usg->sg[i].addr[1]) << 32; | ||
679 | sg_user[i] = (void __user *)(ptrdiff_t)addr; | ||
680 | sg_list[i] = p; // save so we can clean up later | ||
681 | sg_indx = i; | ||
682 | |||
683 | if( flags & SRB_DataOut ){ | ||
684 | if(copy_from_user(p,sg_user[i],usg->sg[i].count)){ | ||
685 | dprintk((KERN_DEBUG"aacraid: Could not copy sg data from user\n")); | ||
686 | rcode = -EFAULT; | ||
687 | goto cleanup; | ||
688 | } | ||
689 | } | ||
690 | addr = pci_map_single(dev->pdev, p, usg->sg[i].count, data_dir); | ||
691 | |||
692 | psg->sg[i].addr = cpu_to_le32(addr & 0xffffffff); | ||
693 | byte_count += usg->sg[i].count; | ||
694 | psg->sg[i].count = cpu_to_le32(usg->sg[i].count); | ||
660 | } | 695 | } |
661 | addr = pci_map_single(dev->pdev, p, | 696 | } else { |
662 | upsg->sg[i].count, data_dir); | 697 | for (i = 0; i < upsg->count; i++) { |
698 | dma_addr_t addr; | ||
699 | void* p; | ||
700 | p = kmalloc(upsg->sg[i].count, GFP_KERNEL); | ||
701 | if(p == 0) { | ||
702 | dprintk((KERN_DEBUG"aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n", | ||
703 | upsg->sg[i].count, i, upsg->count)); | ||
704 | rcode = -ENOMEM; | ||
705 | goto cleanup; | ||
706 | } | ||
707 | sg_user[i] = (void __user *)(ptrdiff_t)upsg->sg[i].addr; | ||
708 | sg_list[i] = p; // save so we can clean up later | ||
709 | sg_indx = i; | ||
710 | |||
711 | if( flags & SRB_DataOut ){ | ||
712 | if(copy_from_user(p, sg_user[i], | ||
713 | upsg->sg[i].count)) { | ||
714 | dprintk((KERN_DEBUG"aacraid: Could not copy sg data from user\n")); | ||
715 | rcode = -EFAULT; | ||
716 | goto cleanup; | ||
717 | } | ||
718 | } | ||
719 | addr = pci_map_single(dev->pdev, p, | ||
720 | upsg->sg[i].count, data_dir); | ||
663 | 721 | ||
664 | psg->sg[i].addr = cpu_to_le32(addr); | 722 | psg->sg[i].addr = cpu_to_le32(addr); |
665 | psg->sg[i].count = cpu_to_le32(upsg->sg[i].count); | 723 | byte_count += upsg->sg[i].count; |
666 | byte_count += upsg->sg[i].count; | 724 | psg->sg[i].count = cpu_to_le32(upsg->sg[i].count); |
725 | } | ||
667 | } | 726 | } |
668 | srbcmd->count = cpu_to_le32(byte_count); | 727 | srbcmd->count = cpu_to_le32(byte_count); |
669 | psg->count = cpu_to_le32(sg_indx+1); | 728 | psg->count = cpu_to_le32(sg_indx+1); |
@@ -682,7 +741,8 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) | |||
682 | 741 | ||
683 | if( flags & SRB_DataIn ) { | 742 | if( flags & SRB_DataIn ) { |
684 | for(i = 0 ; i <= sg_indx; i++){ | 743 | for(i = 0 ; i <= sg_indx; i++){ |
685 | byte_count = le32_to_cpu((dev->dac_support == 1) | 744 | byte_count = le32_to_cpu( |
745 | (dev->adapter_info.options & AAC_OPT_SGMAP_HOST64) | ||
686 | ? ((struct sgmap64*)&srbcmd->sg)->sg[i].count | 746 | ? ((struct sgmap64*)&srbcmd->sg)->sg[i].count |
687 | : srbcmd->sg.sg[i].count); | 747 | : srbcmd->sg.sg[i].count); |
688 | if(copy_to_user(sg_user[i], sg_list[i], byte_count)){ | 748 | if(copy_to_user(sg_user[i], sg_list[i], byte_count)){ |