aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/megaraid
diff options
context:
space:
mode:
authorbo yang <bo.yang@lsi.com>2008-03-17 03:36:43 -0400
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-04-07 13:19:00 -0400
commitd532dbe2cb71586ab520dbef732d1af54a689313 (patch)
treea344ad2cd18de7d8f16e65c357ae3c0c30493277 /drivers/scsi/megaraid
parentb70a41e077b3405d4b41d34db31b39c05bf142b5 (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.c31
-rw-r--r--drivers/scsi/megaraid/megaraid_sas.h4
2 files changed, 25 insertions, 10 deletions
diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c
index 4014225300a0..ffd1390b155b 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
496static u32 megasas_get_frame_count(u8 sge_count) 497static 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 6466bdf548c2..fbbfe2ea049f 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