aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/megaraid
diff options
context:
space:
mode:
authorYang, Bo <Bo.Yang@lsi.com>2009-10-06 16:43:28 -0400
committerJames Bottomley <James.Bottomley@suse.de>2009-10-29 13:03:20 -0400
commitf4c9a1317d32bb0af7546ef0c1dcc3be52dc8d0a (patch)
tree2c0f83b914aaf34902365d244728d6a22808bfd7 /drivers/scsi/megaraid
parent7bebf5c79cb62766c76c6c1b9c77b86496fd363e (diff)
[SCSI] megaraid_sas: add the IEEE SGE support to SAS2 controller
To increase the performance, megaraid sas driver added the IEEE SGE support to support SAS2 controller. Signed-off-by Bo Yang<bo.yang@lsi.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/megaraid')
-rw-r--r--drivers/scsi/megaraid/megaraid_sas.c80
-rw-r--r--drivers/scsi/megaraid/megaraid_sas.h9
2 files changed, 82 insertions, 7 deletions
diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c
index 5afd65121725..4c04a68bad6c 100644
--- a/drivers/scsi/megaraid/megaraid_sas.c
+++ b/drivers/scsi/megaraid/megaraid_sas.c
@@ -696,6 +696,35 @@ megasas_make_sgl64(struct megasas_instance *instance, struct scsi_cmnd *scp,
696 return sge_count; 696 return sge_count;
697} 697}
698 698
699/**
700 * megasas_make_sgl_skinny - Prepares IEEE SGL
701 * @instance: Adapter soft state
702 * @scp: SCSI command from the mid-layer
703 * @mfi_sgl: SGL to be filled in
704 *
705 * If successful, this function returns the number of SG elements. Otherwise,
706 * it returnes -1.
707 */
708static int
709megasas_make_sgl_skinny(struct megasas_instance *instance,
710 struct scsi_cmnd *scp, union megasas_sgl *mfi_sgl)
711{
712 int i;
713 int sge_count;
714 struct scatterlist *os_sgl;
715
716 sge_count = scsi_dma_map(scp);
717
718 if (sge_count) {
719 scsi_for_each_sg(scp, os_sgl, sge_count, i) {
720 mfi_sgl->sge_skinny[i].length = sg_dma_len(os_sgl);
721 mfi_sgl->sge_skinny[i].phys_addr =
722 sg_dma_address(os_sgl);
723 }
724 }
725 return sge_count;
726}
727
699 /** 728 /**
700 * megasas_get_frame_count - Computes the number of frames 729 * megasas_get_frame_count - Computes the number of frames
701 * @frame_type : type of frame- io or pthru frame 730 * @frame_type : type of frame- io or pthru frame
@@ -704,7 +733,8 @@ megasas_make_sgl64(struct megasas_instance *instance, struct scsi_cmnd *scp,
704 * Returns the number of frames required for numnber of sge's (sge_count) 733 * Returns the number of frames required for numnber of sge's (sge_count)
705 */ 734 */
706 735
707static u32 megasas_get_frame_count(u8 sge_count, u8 frame_type) 736static u32 megasas_get_frame_count(struct megasas_instance *instance,
737 u8 sge_count, u8 frame_type)
708{ 738{
709 int num_cnt; 739 int num_cnt;
710 int sge_bytes; 740 int sge_bytes;
@@ -714,6 +744,10 @@ static u32 megasas_get_frame_count(u8 sge_count, u8 frame_type)
714 sge_sz = (IS_DMA64) ? sizeof(struct megasas_sge64) : 744 sge_sz = (IS_DMA64) ? sizeof(struct megasas_sge64) :
715 sizeof(struct megasas_sge32); 745 sizeof(struct megasas_sge32);
716 746
747 if (instance->flag_ieee) {
748 sge_sz = sizeof(struct megasas_sge_skinny);
749 }
750
717 /* 751 /*
718 * Main frame can contain 2 SGEs for 64-bit SGLs and 752 * Main frame can contain 2 SGEs for 64-bit SGLs and
719 * 3 SGEs for 32-bit SGLs for ldio & 753 * 3 SGEs for 32-bit SGLs for ldio &
@@ -721,12 +755,16 @@ static u32 megasas_get_frame_count(u8 sge_count, u8 frame_type)
721 * 2 SGEs for 32-bit SGLs for pthru frame 755 * 2 SGEs for 32-bit SGLs for pthru frame
722 */ 756 */
723 if (unlikely(frame_type == PTHRU_FRAME)) { 757 if (unlikely(frame_type == PTHRU_FRAME)) {
724 if (IS_DMA64) 758 if (instance->flag_ieee == 1) {
759 num_cnt = sge_count - 1;
760 } else if (IS_DMA64)
725 num_cnt = sge_count - 1; 761 num_cnt = sge_count - 1;
726 else 762 else
727 num_cnt = sge_count - 2; 763 num_cnt = sge_count - 2;
728 } else { 764 } else {
729 if (IS_DMA64) 765 if (instance->flag_ieee == 1) {
766 num_cnt = sge_count - 1;
767 } else if (IS_DMA64)
730 num_cnt = sge_count - 2; 768 num_cnt = sge_count - 2;
731 else 769 else
732 num_cnt = sge_count - 3; 770 num_cnt = sge_count - 3;
@@ -775,6 +813,10 @@ megasas_build_dcdb(struct megasas_instance *instance, struct scsi_cmnd *scp,
775 else if (scp->sc_data_direction == PCI_DMA_NONE) 813 else if (scp->sc_data_direction == PCI_DMA_NONE)
776 flags = MFI_FRAME_DIR_NONE; 814 flags = MFI_FRAME_DIR_NONE;
777 815
816 if (instance->flag_ieee == 1) {
817 flags |= MFI_FRAME_IEEE;
818 }
819
778 /* 820 /*
779 * Prepare the DCDB frame 821 * Prepare the DCDB frame
780 */ 822 */
@@ -804,7 +846,11 @@ megasas_build_dcdb(struct megasas_instance *instance, struct scsi_cmnd *scp,
804 /* 846 /*
805 * Construct SGL 847 * Construct SGL
806 */ 848 */
807 if (IS_DMA64) { 849 if (instance->flag_ieee == 1) {
850 pthru->flags |= MFI_FRAME_SGL64;
851 pthru->sge_count = megasas_make_sgl_skinny(instance, scp,
852 &pthru->sgl);
853 } else if (IS_DMA64) {
808 pthru->flags |= MFI_FRAME_SGL64; 854 pthru->flags |= MFI_FRAME_SGL64;
809 pthru->sge_count = megasas_make_sgl64(instance, scp, 855 pthru->sge_count = megasas_make_sgl64(instance, scp,
810 &pthru->sgl); 856 &pthru->sgl);
@@ -823,7 +869,7 @@ megasas_build_dcdb(struct megasas_instance *instance, struct scsi_cmnd *scp,
823 * Compute the total number of frames this command consumes. FW uses 869 * Compute the total number of frames this command consumes. FW uses
824 * this number to pull sufficient number of frames from host memory. 870 * this number to pull sufficient number of frames from host memory.
825 */ 871 */
826 cmd->frame_count = megasas_get_frame_count(pthru->sge_count, 872 cmd->frame_count = megasas_get_frame_count(instance, pthru->sge_count,
827 PTHRU_FRAME); 873 PTHRU_FRAME);
828 874
829 return cmd->frame_count; 875 return cmd->frame_count;
@@ -854,6 +900,10 @@ megasas_build_ldio(struct megasas_instance *instance, struct scsi_cmnd *scp,
854 else if (scp->sc_data_direction == PCI_DMA_FROMDEVICE) 900 else if (scp->sc_data_direction == PCI_DMA_FROMDEVICE)
855 flags = MFI_FRAME_DIR_READ; 901 flags = MFI_FRAME_DIR_READ;
856 902
903 if (instance->flag_ieee == 1) {
904 flags |= MFI_FRAME_IEEE;
905 }
906
857 /* 907 /*
858 * Prepare the Logical IO frame: 2nd bit is zero for all read cmds 908 * Prepare the Logical IO frame: 2nd bit is zero for all read cmds
859 */ 909 */
@@ -924,7 +974,11 @@ megasas_build_ldio(struct megasas_instance *instance, struct scsi_cmnd *scp,
924 /* 974 /*
925 * Construct SGL 975 * Construct SGL
926 */ 976 */
927 if (IS_DMA64) { 977 if (instance->flag_ieee) {
978 ldio->flags |= MFI_FRAME_SGL64;
979 ldio->sge_count = megasas_make_sgl_skinny(instance, scp,
980 &ldio->sgl);
981 } else if (IS_DMA64) {
928 ldio->flags |= MFI_FRAME_SGL64; 982 ldio->flags |= MFI_FRAME_SGL64;
929 ldio->sge_count = megasas_make_sgl64(instance, scp, &ldio->sgl); 983 ldio->sge_count = megasas_make_sgl64(instance, scp, &ldio->sgl);
930 } else 984 } else
@@ -941,7 +995,8 @@ megasas_build_ldio(struct megasas_instance *instance, struct scsi_cmnd *scp,
941 * Compute the total number of frames this command consumes. FW uses 995 * Compute the total number of frames this command consumes. FW uses
942 * this number to pull sufficient number of frames from host memory. 996 * this number to pull sufficient number of frames from host memory.
943 */ 997 */
944 cmd->frame_count = megasas_get_frame_count(ldio->sge_count, IO_FRAME); 998 cmd->frame_count = megasas_get_frame_count(instance,
999 ldio->sge_count, IO_FRAME);
945 1000
946 return cmd->frame_count; 1001 return cmd->frame_count;
947} 1002}
@@ -1929,6 +1984,10 @@ static int megasas_create_frame_pool(struct megasas_instance *instance)
1929 sge_sz = (IS_DMA64) ? sizeof(struct megasas_sge64) : 1984 sge_sz = (IS_DMA64) ? sizeof(struct megasas_sge64) :
1930 sizeof(struct megasas_sge32); 1985 sizeof(struct megasas_sge32);
1931 1986
1987 if (instance->flag_ieee) {
1988 sge_sz = sizeof(struct megasas_sge_skinny);
1989 }
1990
1932 /* 1991 /*
1933 * Calculated the number of 64byte frames required for SGL 1992 * Calculated the number of 64byte frames required for SGL
1934 */ 1993 */
@@ -2725,6 +2784,11 @@ megasas_register_aen(struct megasas_instance *instance, u32 seq_num,
2725 dcmd->sgl.sge32[0].phys_addr = (u32) instance->evt_detail_h; 2784 dcmd->sgl.sge32[0].phys_addr = (u32) instance->evt_detail_h;
2726 dcmd->sgl.sge32[0].length = sizeof(struct megasas_evt_detail); 2785 dcmd->sgl.sge32[0].length = sizeof(struct megasas_evt_detail);
2727 2786
2787 if (instance->aen_cmd != NULL) {
2788 megasas_return_cmd(instance, cmd);
2789 return 0;
2790 }
2791
2728 /* 2792 /*
2729 * Store reference to the cmd used to register for AEN. When an 2793 * Store reference to the cmd used to register for AEN. When an
2730 * application wants us to register for AEN, we have to abort this 2794 * application wants us to register for AEN, we have to abort this
@@ -2895,6 +2959,7 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
2895 *instance->producer = 0; 2959 *instance->producer = 0;
2896 *instance->consumer = 0; 2960 *instance->consumer = 0;
2897 megasas_poll_wait_aen = 0; 2961 megasas_poll_wait_aen = 0;
2962 instance->flag_ieee = 0;
2898 2963
2899 instance->evt_detail = pci_alloc_consistent(pdev, 2964 instance->evt_detail = pci_alloc_consistent(pdev,
2900 sizeof(struct 2965 sizeof(struct
@@ -2933,6 +2998,7 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
2933 2998
2934 if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) || 2999 if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
2935 (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY)) { 3000 (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
3001 instance->flag_ieee = 1;
2936 sema_init(&instance->ioctl_sem, MEGASAS_SKINNY_INT_CMDS); 3002 sema_init(&instance->ioctl_sem, MEGASAS_SKINNY_INT_CMDS);
2937 } else 3003 } else
2938 sema_init(&instance->ioctl_sem, MEGASAS_INT_CMDS); 3004 sema_init(&instance->ioctl_sem, MEGASAS_INT_CMDS);
diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h
index 4c78cd32e757..a1fd44bc1817 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -96,6 +96,7 @@
96#define MFI_FRAME_DIR_WRITE 0x0008 96#define MFI_FRAME_DIR_WRITE 0x0008
97#define MFI_FRAME_DIR_READ 0x0010 97#define MFI_FRAME_DIR_READ 0x0010
98#define MFI_FRAME_DIR_BOTH 0x0018 98#define MFI_FRAME_DIR_BOTH 0x0018
99#define MFI_FRAME_IEEE 0x0020
99 100
100/* 101/*
101 * Definition for cmd_status 102 * Definition for cmd_status
@@ -732,10 +733,17 @@ struct megasas_sge64 {
732 733
733} __attribute__ ((packed)); 734} __attribute__ ((packed));
734 735
736struct megasas_sge_skinny {
737 u64 phys_addr;
738 u32 length;
739 u32 flag;
740} __packed;
741
735union megasas_sgl { 742union megasas_sgl {
736 743
737 struct megasas_sge32 sge32[1]; 744 struct megasas_sge32 sge32[1];
738 struct megasas_sge64 sge64[1]; 745 struct megasas_sge64 sge64[1];
746 struct megasas_sge_skinny sge_skinny[1];
739 747
740} __attribute__ ((packed)); 748} __attribute__ ((packed));
741 749
@@ -1210,6 +1218,7 @@ struct megasas_instance {
1210 1218
1211 u8 flag; 1219 u8 flag;
1212 u8 unload; 1220 u8 unload;
1221 u8 flag_ieee;
1213 unsigned long last_time; 1222 unsigned long last_time;
1214 1223
1215 struct timer_list io_completion_timer; 1224 struct timer_list io_completion_timer;