diff options
author | Mark Haverkamp <markh@osdl.org> | 2005-05-16 21:28:42 -0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.(none)> | 2005-05-20 16:48:00 -0400 |
commit | 7c00ffa314bf0fb0e23858bbebad33b48b6abbb9 (patch) | |
tree | 4d6b65bb5a2c8fecf48a8c6402c2cc867aa2fe6c /drivers/scsi/aacraid/commctrl.c | |
parent | 672b2d38da4fff4c4452685a25fb88b65243d1a6 (diff) |
[SCSI] 2.6 aacraid: Variable FIB size (updated patch)
New code from the Adaptec driver. Performance enhancement for newer
adapters. I hope that this isn't too big for a single patch. I believe
that other than the few small cleanups mentioned, that the changes are
all related.
- Added Variable FIB size negotiation for new adapters.
- Added support to maximize scatter gather tables and thus permit
requests larger than 64KB/each.
- Limit Scatter Gather to 34 elements for ROMB platforms.
- aac_printf is only enabled with AAC_QUIRK_34SG
- Large FIB ioctl support
- some minor cleanup
Passes sparse check.
I have tested it on x86 and ppc64 machines.
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/aacraid/commctrl.c')
-rw-r--r-- | drivers/scsi/aacraid/commctrl.c | 180 |
1 files changed, 115 insertions, 65 deletions
diff --git a/drivers/scsi/aacraid/commctrl.c b/drivers/scsi/aacraid/commctrl.c index e6da87d17832..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,16 +81,21 @@ 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_le16(TakeABreakPt)) { | 101 | if (kfib->header.Command == cpu_to_le16(TakeABreakPt)) { |
@@ -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(le16_to_cpu(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, le16_to_cpu(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 | /** |
@@ -399,6 +415,7 @@ static int check_revision(struct aac_dev *dev, void __user *arg) | |||
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 |
@@ -427,7 +444,7 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) | |||
427 | 444 | ||
428 | 445 | ||
429 | if (!capable(CAP_SYS_ADMIN)){ | 446 | if (!capable(CAP_SYS_ADMIN)){ |
430 | printk(KERN_DEBUG"aacraid: No permission to send raw srb\n"); | 447 | dprintk((KERN_DEBUG"aacraid: No permission to send raw srb\n")); |
431 | return -EPERM; | 448 | return -EPERM; |
432 | } | 449 | } |
433 | /* | 450 | /* |
@@ -440,20 +457,26 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) | |||
440 | 457 | ||
441 | srbcmd = (struct aac_srb*) fib_data(srbfib); | 458 | srbcmd = (struct aac_srb*) fib_data(srbfib); |
442 | 459 | ||
460 | memset(sg_list, 0, sizeof(sg_list)); /* cleanup may take issue */ | ||
443 | if(copy_from_user(&fibsize, &user_srb->count,sizeof(u32))){ | 461 | if(copy_from_user(&fibsize, &user_srb->count,sizeof(u32))){ |
444 | 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")); |
445 | rcode = -EFAULT; | 463 | rcode = -EFAULT; |
446 | goto cleanup; | 464 | goto cleanup; |
447 | } | 465 | } |
448 | 466 | ||
449 | if (fibsize > FIB_DATA_SIZE_IN_BYTES) { | 467 | if (fibsize > (dev->max_fib_size - sizeof(struct aac_fibhdr))) { |
450 | rcode = -EINVAL; | 468 | rcode = -EINVAL; |
451 | goto cleanup; | 469 | goto cleanup; |
452 | } | 470 | } |
453 | 471 | ||
454 | user_srbcmd = kmalloc(GFP_KERNEL, fibsize); | 472 | user_srbcmd = kmalloc(GFP_KERNEL, fibsize); |
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 | } | ||
455 | if(copy_from_user(user_srbcmd, user_srb,fibsize)){ | 478 | if(copy_from_user(user_srbcmd, user_srb,fibsize)){ |
456 | printk(KERN_DEBUG"aacraid: Could not copy srb from user\n"); | 479 | dprintk((KERN_DEBUG"aacraid: Could not copy srb from user\n")); |
457 | rcode = -EFAULT; | 480 | rcode = -EFAULT; |
458 | goto cleanup; | 481 | goto cleanup; |
459 | } | 482 | } |
@@ -464,12 +487,12 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) | |||
464 | // Fix up srb for endian and force some values | 487 | // Fix up srb for endian and force some values |
465 | 488 | ||
466 | srbcmd->function = cpu_to_le32(SRBF_ExecuteScsi); // Force this | 489 | srbcmd->function = cpu_to_le32(SRBF_ExecuteScsi); // Force this |
467 | srbcmd->channel = cpu_to_le32(user_srbcmd->channel); | 490 | srbcmd->channel = cpu_to_le32(user_srbcmd->channel); |
468 | srbcmd->id = cpu_to_le32(user_srbcmd->id); | 491 | srbcmd->id = cpu_to_le32(user_srbcmd->id); |
469 | srbcmd->lun = cpu_to_le32(user_srbcmd->lun); | 492 | srbcmd->lun = cpu_to_le32(user_srbcmd->lun); |
470 | srbcmd->flags = cpu_to_le32(user_srbcmd->flags); | 493 | srbcmd->flags = cpu_to_le32(flags); |
471 | srbcmd->timeout = cpu_to_le32(user_srbcmd->timeout); | 494 | srbcmd->timeout = cpu_to_le32(user_srbcmd->timeout); |
472 | srbcmd->retry_limit = 0; | 495 | srbcmd->retry_limit =cpu_to_le32(0); // Obsolete parameter |
473 | srbcmd->cdb_size = cpu_to_le32(user_srbcmd->cdb_size); | 496 | srbcmd->cdb_size = cpu_to_le32(user_srbcmd->cdb_size); |
474 | 497 | ||
475 | switch (flags & (SRB_DataIn | SRB_DataOut)) { | 498 | switch (flags & (SRB_DataIn | SRB_DataOut)) { |
@@ -485,75 +508,98 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) | |||
485 | default: | 508 | default: |
486 | data_dir = DMA_NONE; | 509 | data_dir = DMA_NONE; |
487 | } | 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 | } | ||
488 | if (dev->dac_support == 1) { | 517 | if (dev->dac_support == 1) { |
489 | struct user_sgmap64* upsg = (struct user_sgmap64*)&user_srbcmd->sg; | 518 | struct user_sgmap64* upsg = (struct user_sgmap64*)&user_srbcmd->sg; |
490 | struct sgmap64* psg = (struct sgmap64*)&user_srbcmd->sg; | 519 | struct sgmap64* psg = (struct sgmap64*)&user_srbcmd->sg; |
520 | struct user_sgmap* usg; | ||
491 | byte_count = 0; | 521 | byte_count = 0; |
492 | 522 | ||
493 | /* | 523 | /* |
494 | * This should also catch if user used the 32 bit sgmap | 524 | * This should also catch if user used the 32 bit sgmap |
495 | */ | 525 | */ |
496 | actual_fibsize = sizeof(struct aac_srb) - | 526 | actual_fibsize = sizeof(struct aac_srb) - |
497 | sizeof(struct sgentry) + | 527 | sizeof(struct sgentry) + |
498 | ((user_srbcmd->sg.count & 0xff) * | 528 | ((upsg->count & 0xff) * |
499 | sizeof(struct sgentry64)); | 529 | sizeof(struct sgentry)); |
500 | if(actual_fibsize != fibsize){ // User made a mistake - should not continue | 530 | if(actual_fibsize != fibsize){ // User made a mistake - should not continue |
501 | 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")); |
502 | rcode = -EINVAL; | 532 | rcode = -EINVAL; |
503 | goto cleanup; | 533 | goto cleanup; |
504 | } | 534 | } |
505 | if ((data_dir == DMA_NONE) && upsg->count) { | 535 | usg = kmalloc(actual_fibsize - sizeof(struct aac_srb) |
506 | 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")); | ||
507 | rcode = -EINVAL; | 550 | rcode = -EINVAL; |
508 | goto cleanup; | 551 | goto cleanup; |
509 | } | 552 | } |
510 | 553 | ||
511 | for (i = 0; i < upsg->count; i++) { | 554 | for (i = 0; i < usg->count; i++) { |
512 | u64 addr; | 555 | u64 addr; |
513 | void* p; | 556 | void* p; |
514 | p = kmalloc(upsg->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); | ||
515 | if(p == 0) { | 559 | if(p == 0) { |
516 | printk(KERN_DEBUG"aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n", | 560 | kfree (usg); |
517 | upsg->sg[i].count,i,upsg->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)); | ||
518 | rcode = -ENOMEM; | 563 | rcode = -ENOMEM; |
519 | goto cleanup; | 564 | goto cleanup; |
520 | } | 565 | } |
521 | sg_user[i] = (void __user *)upsg->sg[i].addr; | 566 | sg_user[i] = (void __user *)usg->sg[i].addr; |
522 | sg_list[i] = p; // save so we can clean up later | 567 | sg_list[i] = p; // save so we can clean up later |
523 | sg_indx = i; | 568 | sg_indx = i; |
524 | 569 | ||
525 | if( flags & SRB_DataOut ){ | 570 | if( flags & SRB_DataOut ){ |
526 | if(copy_from_user(p,sg_user[i],upsg->sg[i].count)){ | 571 | if(copy_from_user(p,sg_user[i],upsg->sg[i].count)){ |
527 | 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")); | ||
528 | rcode = -EFAULT; | 574 | rcode = -EFAULT; |
529 | goto cleanup; | 575 | goto cleanup; |
530 | } | 576 | } |
531 | } | 577 | } |
532 | addr = pci_map_single(dev->pdev, p, upsg->sg[i].count, data_dir); | 578 | addr = pci_map_single(dev->pdev, p, usg->sg[i].count, data_dir); |
533 | 579 | ||
534 | psg->sg[i].addr[0] = cpu_to_le32(addr & 0xffffffff); | 580 | psg->sg[i].addr[0] = cpu_to_le32(addr & 0xffffffff); |
535 | psg->sg[i].addr[1] = cpu_to_le32(addr >> 32); | 581 | psg->sg[i].addr[1] = cpu_to_le32(addr>>32); |
536 | psg->sg[i].count = cpu_to_le32(upsg->sg[i].count); | 582 | psg->sg[i].count = cpu_to_le32(usg->sg[i].count); |
537 | byte_count += upsg->sg[i].count; | 583 | byte_count += usg->sg[i].count; |
538 | } | 584 | } |
585 | kfree (usg); | ||
539 | 586 | ||
540 | srbcmd->count = cpu_to_le32(byte_count); | 587 | srbcmd->count = cpu_to_le32(byte_count); |
588 | psg->count = cpu_to_le32(sg_indx+1); | ||
541 | 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); |
542 | } else { | 590 | } else { |
543 | struct user_sgmap* upsg = &user_srbcmd->sg; | 591 | struct user_sgmap* upsg = &user_srbcmd->sg; |
544 | struct sgmap* psg = &srbcmd->sg; | 592 | struct sgmap* psg = &srbcmd->sg; |
545 | byte_count = 0; | 593 | byte_count = 0; |
546 | 594 | ||
547 | actual_fibsize = sizeof (struct aac_srb) + | 595 | actual_fibsize = sizeof (struct aac_srb) + (((le32_to_cpu(srbcmd->sg.count) & 0xff) - 1) * sizeof (struct sgentry)); |
548 | (((le32_to_cpu(srbcmd->sg.count) & 0xff) - 1) * | ||
549 | sizeof (struct sgentry)); | ||
550 | if(actual_fibsize != fibsize){ // User made a mistake - should not continue | 596 | if(actual_fibsize != fibsize){ // User made a mistake - should not continue |
551 | 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")); |
552 | rcode = -EINVAL; | 598 | rcode = -EINVAL; |
553 | goto cleanup; | 599 | goto cleanup; |
554 | } | 600 | } |
555 | if ((data_dir == DMA_NONE) && upsg->count) { | 601 | if ((data_dir == DMA_NONE) && upsg->count) { |
556 | 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")); |
557 | rcode = -EINVAL; | 603 | rcode = -EINVAL; |
558 | goto cleanup; | 604 | goto cleanup; |
559 | } | 605 | } |
@@ -562,44 +608,48 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) | |||
562 | void* p; | 608 | void* p; |
563 | p = kmalloc(upsg->sg[i].count, GFP_KERNEL); | 609 | p = kmalloc(upsg->sg[i].count, GFP_KERNEL); |
564 | if(p == 0) { | 610 | if(p == 0) { |
565 | 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", |
566 | upsg->sg[i].count, i, upsg->count); | 612 | upsg->sg[i].count, i, upsg->count)); |
567 | rcode = -ENOMEM; | 613 | rcode = -ENOMEM; |
568 | goto cleanup; | 614 | goto cleanup; |
569 | } | 615 | } |
570 | sg_user[i] = (void __user *)upsg->sg[i].addr; | 616 | sg_user[i] = (void __user *)upsg->sg[i].addr; |
571 | sg_list[i] = p; // save so we can clean up later | 617 | sg_list[i] = p; // save so we can clean up later |
572 | sg_indx = i; | 618 | sg_indx = i; |
573 | 619 | ||
574 | if( flags & SRB_DataOut ){ | 620 | if( flags & SRB_DataOut ){ |
575 | if(copy_from_user(p, sg_user[i], | 621 | if(copy_from_user(p, sg_user[i], |
576 | upsg->sg[i].count)) { | 622 | upsg->sg[i].count)) { |
577 | printk(KERN_DEBUG"aacraid: Could not copy sg data from user\n"); | 623 | dprintk((KERN_DEBUG"aacraid: Could not copy sg data from user\n")); |
578 | rcode = -EFAULT; | 624 | rcode = -EFAULT; |
579 | goto cleanup; | 625 | goto cleanup; |
580 | } | 626 | } |
581 | } | 627 | } |
582 | addr = pci_map_single(dev->pdev, p, | 628 | addr = pci_map_single(dev->pdev, p, |
583 | upsg->sg[i].count, data_dir); | 629 | upsg->sg[i].count, data_dir); |
584 | 630 | ||
585 | psg->sg[i].addr = cpu_to_le32(addr); | 631 | psg->sg[i].addr = cpu_to_le32(addr); |
586 | psg->sg[i].count = cpu_to_le32(upsg->sg[i].count); | 632 | psg->sg[i].count = cpu_to_le32(upsg->sg[i].count); |
587 | byte_count += upsg->sg[i].count; | 633 | byte_count += upsg->sg[i].count; |
588 | } | 634 | } |
589 | srbcmd->count = cpu_to_le32(byte_count); | 635 | srbcmd->count = cpu_to_le32(byte_count); |
636 | psg->count = cpu_to_le32(sg_indx+1); | ||
590 | 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); |
591 | } | 638 | } |
592 | 639 | ||
593 | if (status != 0){ | 640 | if (status != 0){ |
594 | 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")); |
595 | rcode = -1; | 642 | rcode = -1; |
596 | goto cleanup; | 643 | goto cleanup; |
597 | } | 644 | } |
598 | 645 | ||
599 | if( flags & SRB_DataIn ) { | 646 | if( flags & SRB_DataIn ) { |
600 | for(i = 0 ; i <= sg_indx; i++){ | 647 | for(i = 0 ; i <= sg_indx; i++){ |
601 | 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) |
602 | 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")); | ||
603 | rcode = -EFAULT; | 653 | rcode = -EFAULT; |
604 | goto cleanup; | 654 | goto cleanup; |
605 | 655 | ||
@@ -609,7 +659,7 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) | |||
609 | 659 | ||
610 | reply = (struct aac_srb_reply *) fib_data(srbfib); | 660 | reply = (struct aac_srb_reply *) fib_data(srbfib); |
611 | 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))){ |
612 | printk(KERN_DEBUG"aacraid: Could not copy reply to user\n"); | 662 | dprintk((KERN_DEBUG"aacraid: Could not copy reply to user\n")); |
613 | rcode = -EFAULT; | 663 | rcode = -EFAULT; |
614 | goto cleanup; | 664 | goto cleanup; |
615 | } | 665 | } |
@@ -625,7 +675,6 @@ cleanup: | |||
625 | return rcode; | 675 | return rcode; |
626 | } | 676 | } |
627 | 677 | ||
628 | |||
629 | struct aac_pci_info { | 678 | struct aac_pci_info { |
630 | u32 bus; | 679 | u32 bus; |
631 | u32 slot; | 680 | u32 slot; |
@@ -640,11 +689,11 @@ static int aac_get_pci_info(struct aac_dev* dev, void __user *arg) | |||
640 | pci_info.slot = PCI_SLOT(dev->pdev->devfn); | 689 | pci_info.slot = PCI_SLOT(dev->pdev->devfn); |
641 | 690 | ||
642 | 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))) { |
643 | printk(KERN_DEBUG "aacraid: Could not copy pci info\n"); | 692 | dprintk((KERN_DEBUG "aacraid: Could not copy pci info\n")); |
644 | return -EFAULT; | 693 | return -EFAULT; |
645 | } | 694 | } |
646 | return 0; | 695 | return 0; |
647 | } | 696 | } |
648 | 697 | ||
649 | 698 | ||
650 | 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) |
@@ -663,6 +712,7 @@ int aac_do_ioctl(struct aac_dev * dev, int cmd, void __user *arg) | |||
663 | case FSACTL_MINIPORT_REV_CHECK: | 712 | case FSACTL_MINIPORT_REV_CHECK: |
664 | status = check_revision(dev, arg); | 713 | status = check_revision(dev, arg); |
665 | break; | 714 | break; |
715 | case FSACTL_SEND_LARGE_FIB: | ||
666 | case FSACTL_SENDFIB: | 716 | case FSACTL_SENDFIB: |
667 | status = ioctl_send_fib(dev, arg); | 717 | status = ioctl_send_fib(dev, arg); |
668 | break; | 718 | break; |