diff options
author | bo yang <bo.yang@lsi.com> | 2008-03-17 03:36:43 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-04-07 13:19:00 -0400 |
commit | d532dbe2cb71586ab520dbef732d1af54a689313 (patch) | |
tree | a344ad2cd18de7d8f16e65c357ae3c0c30493277 /drivers/scsi/megaraid | |
parent | b70a41e077b3405d4b41d34db31b39c05bf142b5 (diff) |
[SCSI] megaraid_sas: Fix the frame count calculation
When Driver sent wrong frame count to firmware. As this particular
command is sent to drive, FW is seeing continuous chip resets and so
the command will timeout.
Signed-off-by Bo Yang<bo.yang@lsi.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi/megaraid')
-rw-r--r-- | drivers/scsi/megaraid/megaraid_sas.c | 31 | ||||
-rw-r--r-- | drivers/scsi/megaraid/megaraid_sas.h | 4 |
2 files changed, 25 insertions, 10 deletions
diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c index 4014225300a..ffd1390b155 100644 --- a/drivers/scsi/megaraid/megaraid_sas.c +++ b/drivers/scsi/megaraid/megaraid_sas.c | |||
@@ -488,12 +488,13 @@ megasas_make_sgl64(struct megasas_instance *instance, struct scsi_cmnd *scp, | |||
488 | 488 | ||
489 | /** | 489 | /** |
490 | * megasas_get_frame_count - Computes the number of frames | 490 | * megasas_get_frame_count - Computes the number of frames |
491 | * @frame_type : type of frame- io or pthru frame | ||
491 | * @sge_count : number of sg elements | 492 | * @sge_count : number of sg elements |
492 | * | 493 | * |
493 | * Returns the number of frames required for numnber of sge's (sge_count) | 494 | * Returns the number of frames required for numnber of sge's (sge_count) |
494 | */ | 495 | */ |
495 | 496 | ||
496 | static u32 megasas_get_frame_count(u8 sge_count) | 497 | static u32 megasas_get_frame_count(u8 sge_count, u8 frame_type) |
497 | { | 498 | { |
498 | int num_cnt; | 499 | int num_cnt; |
499 | int sge_bytes; | 500 | int sge_bytes; |
@@ -504,13 +505,22 @@ static u32 megasas_get_frame_count(u8 sge_count) | |||
504 | sizeof(struct megasas_sge32); | 505 | sizeof(struct megasas_sge32); |
505 | 506 | ||
506 | /* | 507 | /* |
507 | * Main frame can contain 2 SGEs for 64-bit SGLs and | 508 | * Main frame can contain 2 SGEs for 64-bit SGLs and |
508 | * 3 SGEs for 32-bit SGLs | 509 | * 3 SGEs for 32-bit SGLs for ldio & |
509 | */ | 510 | * 1 SGEs for 64-bit SGLs and |
510 | if (IS_DMA64) | 511 | * 2 SGEs for 32-bit SGLs for pthru frame |
511 | num_cnt = sge_count - 2; | 512 | */ |
512 | else | 513 | if (unlikely(frame_type == PTHRU_FRAME)) { |
513 | num_cnt = sge_count - 3; | 514 | if (IS_DMA64) |
515 | num_cnt = sge_count - 1; | ||
516 | else | ||
517 | num_cnt = sge_count - 2; | ||
518 | } else { | ||
519 | if (IS_DMA64) | ||
520 | num_cnt = sge_count - 2; | ||
521 | else | ||
522 | num_cnt = sge_count - 3; | ||
523 | } | ||
514 | 524 | ||
515 | if(num_cnt>0){ | 525 | if(num_cnt>0){ |
516 | sge_bytes = sge_sz * num_cnt; | 526 | sge_bytes = sge_sz * num_cnt; |
@@ -592,7 +602,8 @@ megasas_build_dcdb(struct megasas_instance *instance, struct scsi_cmnd *scp, | |||
592 | * Compute the total number of frames this command consumes. FW uses | 602 | * Compute the total number of frames this command consumes. FW uses |
593 | * this number to pull sufficient number of frames from host memory. | 603 | * this number to pull sufficient number of frames from host memory. |
594 | */ | 604 | */ |
595 | cmd->frame_count = megasas_get_frame_count(pthru->sge_count); | 605 | cmd->frame_count = megasas_get_frame_count(pthru->sge_count, |
606 | PTHRU_FRAME); | ||
596 | 607 | ||
597 | return cmd->frame_count; | 608 | return cmd->frame_count; |
598 | } | 609 | } |
@@ -709,7 +720,7 @@ megasas_build_ldio(struct megasas_instance *instance, struct scsi_cmnd *scp, | |||
709 | * Compute the total number of frames this command consumes. FW uses | 720 | * Compute the total number of frames this command consumes. FW uses |
710 | * this number to pull sufficient number of frames from host memory. | 721 | * this number to pull sufficient number of frames from host memory. |
711 | */ | 722 | */ |
712 | cmd->frame_count = megasas_get_frame_count(ldio->sge_count); | 723 | cmd->frame_count = megasas_get_frame_count(ldio->sge_count, IO_FRAME); |
713 | 724 | ||
714 | return cmd->frame_count; | 725 | return cmd->frame_count; |
715 | } | 726 | } |
diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index 6466bdf548c..fbbfe2ea049 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h | |||
@@ -542,6 +542,10 @@ struct megasas_ctrl_info { | |||
542 | 542 | ||
543 | #define MEGASAS_FW_BUSY 1 | 543 | #define MEGASAS_FW_BUSY 1 |
544 | 544 | ||
545 | /* Frame Type */ | ||
546 | #define IO_FRAME 0 | ||
547 | #define PTHRU_FRAME 1 | ||
548 | |||
545 | /* | 549 | /* |
546 | * When SCSI mid-layer calls driver's reset routine, driver waits for | 550 | * When SCSI mid-layer calls driver's reset routine, driver waits for |
547 | * MEGASAS_RESET_WAIT_TIME seconds for all outstanding IO to complete. Note | 551 | * MEGASAS_RESET_WAIT_TIME seconds for all outstanding IO to complete. Note |