diff options
Diffstat (limited to 'drivers/scsi/megaraid')
-rw-r--r-- | drivers/scsi/megaraid/megaraid_sas.c | 72 |
1 files changed, 47 insertions, 25 deletions
diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c index 38733b6009a4..e177fc5c5dd0 100644 --- a/drivers/scsi/megaraid/megaraid_sas.c +++ b/drivers/scsi/megaraid/megaraid_sas.c | |||
@@ -495,6 +495,46 @@ megasas_make_sgl64(struct megasas_instance *instance, struct scsi_cmnd *scp, | |||
495 | return sge_count; | 495 | return sge_count; |
496 | } | 496 | } |
497 | 497 | ||
498 | /** | ||
499 | * megasas_get_frame_count - Computes the number of frames | ||
500 | * @sge_count : number of sg elements | ||
501 | * | ||
502 | * Returns the number of frames required for numnber of sge's (sge_count) | ||
503 | */ | ||
504 | |||
505 | u32 megasas_get_frame_count(u8 sge_count) | ||
506 | { | ||
507 | int num_cnt; | ||
508 | int sge_bytes; | ||
509 | u32 sge_sz; | ||
510 | u32 frame_count=0; | ||
511 | |||
512 | sge_sz = (IS_DMA64) ? sizeof(struct megasas_sge64) : | ||
513 | sizeof(struct megasas_sge32); | ||
514 | |||
515 | /* | ||
516 | * Main frame can contain 2 SGEs for 64-bit SGLs and | ||
517 | * 3 SGEs for 32-bit SGLs | ||
518 | */ | ||
519 | if (IS_DMA64) | ||
520 | num_cnt = sge_count - 2; | ||
521 | else | ||
522 | num_cnt = sge_count - 3; | ||
523 | |||
524 | if(num_cnt>0){ | ||
525 | sge_bytes = sge_sz * num_cnt; | ||
526 | |||
527 | frame_count = (sge_bytes / MEGAMFI_FRAME_SIZE) + | ||
528 | ((sge_bytes % MEGAMFI_FRAME_SIZE) ? 1 : 0) ; | ||
529 | } | ||
530 | /* Main frame */ | ||
531 | frame_count +=1; | ||
532 | |||
533 | if (frame_count > 7) | ||
534 | frame_count = 8; | ||
535 | return frame_count; | ||
536 | } | ||
537 | |||
498 | /** | 538 | /** |
499 | * megasas_build_dcdb - Prepares a direct cdb (DCDB) command | 539 | * megasas_build_dcdb - Prepares a direct cdb (DCDB) command |
500 | * @instance: Adapter soft state | 540 | * @instance: Adapter soft state |
@@ -508,8 +548,6 @@ static int | |||
508 | megasas_build_dcdb(struct megasas_instance *instance, struct scsi_cmnd *scp, | 548 | megasas_build_dcdb(struct megasas_instance *instance, struct scsi_cmnd *scp, |
509 | struct megasas_cmd *cmd) | 549 | struct megasas_cmd *cmd) |
510 | { | 550 | { |
511 | u32 sge_sz; | ||
512 | int sge_bytes; | ||
513 | u32 is_logical; | 551 | u32 is_logical; |
514 | u32 device_id; | 552 | u32 device_id; |
515 | u16 flags = 0; | 553 | u16 flags = 0; |
@@ -544,9 +582,6 @@ megasas_build_dcdb(struct megasas_instance *instance, struct scsi_cmnd *scp, | |||
544 | /* | 582 | /* |
545 | * Construct SGL | 583 | * Construct SGL |
546 | */ | 584 | */ |
547 | sge_sz = (IS_DMA64) ? sizeof(struct megasas_sge64) : | ||
548 | sizeof(struct megasas_sge32); | ||
549 | |||
550 | if (IS_DMA64) { | 585 | if (IS_DMA64) { |
551 | pthru->flags |= MFI_FRAME_SGL64; | 586 | pthru->flags |= MFI_FRAME_SGL64; |
552 | pthru->sge_count = megasas_make_sgl64(instance, scp, | 587 | pthru->sge_count = megasas_make_sgl64(instance, scp, |
@@ -562,17 +597,11 @@ megasas_build_dcdb(struct megasas_instance *instance, struct scsi_cmnd *scp, | |||
562 | pthru->sense_buf_phys_addr_hi = 0; | 597 | pthru->sense_buf_phys_addr_hi = 0; |
563 | pthru->sense_buf_phys_addr_lo = cmd->sense_phys_addr; | 598 | pthru->sense_buf_phys_addr_lo = cmd->sense_phys_addr; |
564 | 599 | ||
565 | sge_bytes = sge_sz * pthru->sge_count; | ||
566 | |||
567 | /* | 600 | /* |
568 | * Compute the total number of frames this command consumes. FW uses | 601 | * Compute the total number of frames this command consumes. FW uses |
569 | * this number to pull sufficient number of frames from host memory. | 602 | * this number to pull sufficient number of frames from host memory. |
570 | */ | 603 | */ |
571 | cmd->frame_count = (sge_bytes / MEGAMFI_FRAME_SIZE) + | 604 | cmd->frame_count = megasas_get_frame_count(pthru->sge_count); |
572 | ((sge_bytes % MEGAMFI_FRAME_SIZE) ? 1 : 0) + 1; | ||
573 | |||
574 | if (cmd->frame_count > 7) | ||
575 | cmd->frame_count = 8; | ||
576 | 605 | ||
577 | return cmd->frame_count; | 606 | return cmd->frame_count; |
578 | } | 607 | } |
@@ -589,8 +618,6 @@ static int | |||
589 | megasas_build_ldio(struct megasas_instance *instance, struct scsi_cmnd *scp, | 618 | megasas_build_ldio(struct megasas_instance *instance, struct scsi_cmnd *scp, |
590 | struct megasas_cmd *cmd) | 619 | struct megasas_cmd *cmd) |
591 | { | 620 | { |
592 | u32 sge_sz; | ||
593 | int sge_bytes; | ||
594 | u32 device_id; | 621 | u32 device_id; |
595 | u8 sc = scp->cmnd[0]; | 622 | u8 sc = scp->cmnd[0]; |
596 | u16 flags = 0; | 623 | u16 flags = 0; |
@@ -605,7 +632,7 @@ megasas_build_ldio(struct megasas_instance *instance, struct scsi_cmnd *scp, | |||
605 | flags = MFI_FRAME_DIR_READ; | 632 | flags = MFI_FRAME_DIR_READ; |
606 | 633 | ||
607 | /* | 634 | /* |
608 | * Preare the Logical IO frame: 2nd bit is zero for all read cmds | 635 | * Prepare the Logical IO frame: 2nd bit is zero for all read cmds |
609 | */ | 636 | */ |
610 | ldio->cmd = (sc & 0x02) ? MFI_CMD_LD_WRITE : MFI_CMD_LD_READ; | 637 | ldio->cmd = (sc & 0x02) ? MFI_CMD_LD_WRITE : MFI_CMD_LD_READ; |
611 | ldio->cmd_status = 0x0; | 638 | ldio->cmd_status = 0x0; |
@@ -674,9 +701,6 @@ megasas_build_ldio(struct megasas_instance *instance, struct scsi_cmnd *scp, | |||
674 | /* | 701 | /* |
675 | * Construct SGL | 702 | * Construct SGL |
676 | */ | 703 | */ |
677 | sge_sz = (IS_DMA64) ? sizeof(struct megasas_sge64) : | ||
678 | sizeof(struct megasas_sge32); | ||
679 | |||
680 | if (IS_DMA64) { | 704 | if (IS_DMA64) { |
681 | ldio->flags |= MFI_FRAME_SGL64; | 705 | ldio->flags |= MFI_FRAME_SGL64; |
682 | ldio->sge_count = megasas_make_sgl64(instance, scp, &ldio->sgl); | 706 | ldio->sge_count = megasas_make_sgl64(instance, scp, &ldio->sgl); |
@@ -690,13 +714,11 @@ megasas_build_ldio(struct megasas_instance *instance, struct scsi_cmnd *scp, | |||
690 | ldio->sense_buf_phys_addr_hi = 0; | 714 | ldio->sense_buf_phys_addr_hi = 0; |
691 | ldio->sense_buf_phys_addr_lo = cmd->sense_phys_addr; | 715 | ldio->sense_buf_phys_addr_lo = cmd->sense_phys_addr; |
692 | 716 | ||
693 | sge_bytes = sge_sz * ldio->sge_count; | 717 | /* |
694 | 718 | * Compute the total number of frames this command consumes. FW uses | |
695 | cmd->frame_count = (sge_bytes / MEGAMFI_FRAME_SIZE) + | 719 | * this number to pull sufficient number of frames from host memory. |
696 | ((sge_bytes % MEGAMFI_FRAME_SIZE) ? 1 : 0) + 1; | 720 | */ |
697 | 721 | cmd->frame_count = megasas_get_frame_count(ldio->sge_count); | |
698 | if (cmd->frame_count > 7) | ||
699 | cmd->frame_count = 8; | ||
700 | 722 | ||
701 | return cmd->frame_count; | 723 | return cmd->frame_count; |
702 | } | 724 | } |