[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>
This commit is contained in:
committed by
James Bottomley
parent
7bebf5c79c
commit
f4c9a1317d
@@ -696,6 +696,35 @@ megasas_make_sgl64(struct megasas_instance *instance, struct scsi_cmnd *scp,
|
|||||||
return sge_count;
|
return sge_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* megasas_make_sgl_skinny - Prepares IEEE SGL
|
||||||
|
* @instance: Adapter soft state
|
||||||
|
* @scp: SCSI command from the mid-layer
|
||||||
|
* @mfi_sgl: SGL to be filled in
|
||||||
|
*
|
||||||
|
* If successful, this function returns the number of SG elements. Otherwise,
|
||||||
|
* it returnes -1.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
megasas_make_sgl_skinny(struct megasas_instance *instance,
|
||||||
|
struct scsi_cmnd *scp, union megasas_sgl *mfi_sgl)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int sge_count;
|
||||||
|
struct scatterlist *os_sgl;
|
||||||
|
|
||||||
|
sge_count = scsi_dma_map(scp);
|
||||||
|
|
||||||
|
if (sge_count) {
|
||||||
|
scsi_for_each_sg(scp, os_sgl, sge_count, i) {
|
||||||
|
mfi_sgl->sge_skinny[i].length = sg_dma_len(os_sgl);
|
||||||
|
mfi_sgl->sge_skinny[i].phys_addr =
|
||||||
|
sg_dma_address(os_sgl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sge_count;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* megasas_get_frame_count - Computes the number of frames
|
* megasas_get_frame_count - Computes the number of frames
|
||||||
* @frame_type : type of frame- io or pthru frame
|
* @frame_type : type of frame- io or pthru frame
|
||||||
@@ -704,7 +733,8 @@ megasas_make_sgl64(struct megasas_instance *instance, struct scsi_cmnd *scp,
|
|||||||
* Returns the number of frames required for numnber of sge's (sge_count)
|
* Returns the number of frames required for numnber of sge's (sge_count)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static u32 megasas_get_frame_count(u8 sge_count, u8 frame_type)
|
static u32 megasas_get_frame_count(struct megasas_instance *instance,
|
||||||
|
u8 sge_count, u8 frame_type)
|
||||||
{
|
{
|
||||||
int num_cnt;
|
int num_cnt;
|
||||||
int sge_bytes;
|
int sge_bytes;
|
||||||
@@ -714,6 +744,10 @@ static u32 megasas_get_frame_count(u8 sge_count, u8 frame_type)
|
|||||||
sge_sz = (IS_DMA64) ? sizeof(struct megasas_sge64) :
|
sge_sz = (IS_DMA64) ? sizeof(struct megasas_sge64) :
|
||||||
sizeof(struct megasas_sge32);
|
sizeof(struct megasas_sge32);
|
||||||
|
|
||||||
|
if (instance->flag_ieee) {
|
||||||
|
sge_sz = sizeof(struct megasas_sge_skinny);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Main frame can contain 2 SGEs for 64-bit SGLs and
|
* Main frame can contain 2 SGEs for 64-bit SGLs and
|
||||||
* 3 SGEs for 32-bit SGLs for ldio &
|
* 3 SGEs for 32-bit SGLs for ldio &
|
||||||
@@ -721,12 +755,16 @@ static u32 megasas_get_frame_count(u8 sge_count, u8 frame_type)
|
|||||||
* 2 SGEs for 32-bit SGLs for pthru frame
|
* 2 SGEs for 32-bit SGLs for pthru frame
|
||||||
*/
|
*/
|
||||||
if (unlikely(frame_type == PTHRU_FRAME)) {
|
if (unlikely(frame_type == PTHRU_FRAME)) {
|
||||||
if (IS_DMA64)
|
if (instance->flag_ieee == 1) {
|
||||||
|
num_cnt = sge_count - 1;
|
||||||
|
} else if (IS_DMA64)
|
||||||
num_cnt = sge_count - 1;
|
num_cnt = sge_count - 1;
|
||||||
else
|
else
|
||||||
num_cnt = sge_count - 2;
|
num_cnt = sge_count - 2;
|
||||||
} else {
|
} else {
|
||||||
if (IS_DMA64)
|
if (instance->flag_ieee == 1) {
|
||||||
|
num_cnt = sge_count - 1;
|
||||||
|
} else if (IS_DMA64)
|
||||||
num_cnt = sge_count - 2;
|
num_cnt = sge_count - 2;
|
||||||
else
|
else
|
||||||
num_cnt = sge_count - 3;
|
num_cnt = sge_count - 3;
|
||||||
@@ -775,6 +813,10 @@ megasas_build_dcdb(struct megasas_instance *instance, struct scsi_cmnd *scp,
|
|||||||
else if (scp->sc_data_direction == PCI_DMA_NONE)
|
else if (scp->sc_data_direction == PCI_DMA_NONE)
|
||||||
flags = MFI_FRAME_DIR_NONE;
|
flags = MFI_FRAME_DIR_NONE;
|
||||||
|
|
||||||
|
if (instance->flag_ieee == 1) {
|
||||||
|
flags |= MFI_FRAME_IEEE;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Prepare the DCDB frame
|
* Prepare the DCDB frame
|
||||||
*/
|
*/
|
||||||
@@ -804,7 +846,11 @@ megasas_build_dcdb(struct megasas_instance *instance, struct scsi_cmnd *scp,
|
|||||||
/*
|
/*
|
||||||
* Construct SGL
|
* Construct SGL
|
||||||
*/
|
*/
|
||||||
if (IS_DMA64) {
|
if (instance->flag_ieee == 1) {
|
||||||
|
pthru->flags |= MFI_FRAME_SGL64;
|
||||||
|
pthru->sge_count = megasas_make_sgl_skinny(instance, scp,
|
||||||
|
&pthru->sgl);
|
||||||
|
} else if (IS_DMA64) {
|
||||||
pthru->flags |= MFI_FRAME_SGL64;
|
pthru->flags |= MFI_FRAME_SGL64;
|
||||||
pthru->sge_count = megasas_make_sgl64(instance, scp,
|
pthru->sge_count = megasas_make_sgl64(instance, scp,
|
||||||
&pthru->sgl);
|
&pthru->sgl);
|
||||||
@@ -823,7 +869,7 @@ megasas_build_dcdb(struct megasas_instance *instance, struct scsi_cmnd *scp,
|
|||||||
* Compute the total number of frames this command consumes. FW uses
|
* Compute the total number of frames this command consumes. FW uses
|
||||||
* this number to pull sufficient number of frames from host memory.
|
* this number to pull sufficient number of frames from host memory.
|
||||||
*/
|
*/
|
||||||
cmd->frame_count = megasas_get_frame_count(pthru->sge_count,
|
cmd->frame_count = megasas_get_frame_count(instance, pthru->sge_count,
|
||||||
PTHRU_FRAME);
|
PTHRU_FRAME);
|
||||||
|
|
||||||
return cmd->frame_count;
|
return cmd->frame_count;
|
||||||
@@ -854,6 +900,10 @@ megasas_build_ldio(struct megasas_instance *instance, struct scsi_cmnd *scp,
|
|||||||
else if (scp->sc_data_direction == PCI_DMA_FROMDEVICE)
|
else if (scp->sc_data_direction == PCI_DMA_FROMDEVICE)
|
||||||
flags = MFI_FRAME_DIR_READ;
|
flags = MFI_FRAME_DIR_READ;
|
||||||
|
|
||||||
|
if (instance->flag_ieee == 1) {
|
||||||
|
flags |= MFI_FRAME_IEEE;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Prepare the Logical IO frame: 2nd bit is zero for all read cmds
|
* Prepare the Logical IO frame: 2nd bit is zero for all read cmds
|
||||||
*/
|
*/
|
||||||
@@ -924,7 +974,11 @@ megasas_build_ldio(struct megasas_instance *instance, struct scsi_cmnd *scp,
|
|||||||
/*
|
/*
|
||||||
* Construct SGL
|
* Construct SGL
|
||||||
*/
|
*/
|
||||||
if (IS_DMA64) {
|
if (instance->flag_ieee) {
|
||||||
|
ldio->flags |= MFI_FRAME_SGL64;
|
||||||
|
ldio->sge_count = megasas_make_sgl_skinny(instance, scp,
|
||||||
|
&ldio->sgl);
|
||||||
|
} else if (IS_DMA64) {
|
||||||
ldio->flags |= MFI_FRAME_SGL64;
|
ldio->flags |= MFI_FRAME_SGL64;
|
||||||
ldio->sge_count = megasas_make_sgl64(instance, scp, &ldio->sgl);
|
ldio->sge_count = megasas_make_sgl64(instance, scp, &ldio->sgl);
|
||||||
} else
|
} else
|
||||||
@@ -941,7 +995,8 @@ megasas_build_ldio(struct megasas_instance *instance, struct scsi_cmnd *scp,
|
|||||||
* Compute the total number of frames this command consumes. FW uses
|
* Compute the total number of frames this command consumes. FW uses
|
||||||
* this number to pull sufficient number of frames from host memory.
|
* this number to pull sufficient number of frames from host memory.
|
||||||
*/
|
*/
|
||||||
cmd->frame_count = megasas_get_frame_count(ldio->sge_count, IO_FRAME);
|
cmd->frame_count = megasas_get_frame_count(instance,
|
||||||
|
ldio->sge_count, IO_FRAME);
|
||||||
|
|
||||||
return cmd->frame_count;
|
return cmd->frame_count;
|
||||||
}
|
}
|
||||||
@@ -1929,6 +1984,10 @@ static int megasas_create_frame_pool(struct megasas_instance *instance)
|
|||||||
sge_sz = (IS_DMA64) ? sizeof(struct megasas_sge64) :
|
sge_sz = (IS_DMA64) ? sizeof(struct megasas_sge64) :
|
||||||
sizeof(struct megasas_sge32);
|
sizeof(struct megasas_sge32);
|
||||||
|
|
||||||
|
if (instance->flag_ieee) {
|
||||||
|
sge_sz = sizeof(struct megasas_sge_skinny);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Calculated the number of 64byte frames required for SGL
|
* Calculated the number of 64byte frames required for SGL
|
||||||
*/
|
*/
|
||||||
@@ -2725,6 +2784,11 @@ megasas_register_aen(struct megasas_instance *instance, u32 seq_num,
|
|||||||
dcmd->sgl.sge32[0].phys_addr = (u32) instance->evt_detail_h;
|
dcmd->sgl.sge32[0].phys_addr = (u32) instance->evt_detail_h;
|
||||||
dcmd->sgl.sge32[0].length = sizeof(struct megasas_evt_detail);
|
dcmd->sgl.sge32[0].length = sizeof(struct megasas_evt_detail);
|
||||||
|
|
||||||
|
if (instance->aen_cmd != NULL) {
|
||||||
|
megasas_return_cmd(instance, cmd);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Store reference to the cmd used to register for AEN. When an
|
* Store reference to the cmd used to register for AEN. When an
|
||||||
* application wants us to register for AEN, we have to abort this
|
* 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)
|
|||||||
*instance->producer = 0;
|
*instance->producer = 0;
|
||||||
*instance->consumer = 0;
|
*instance->consumer = 0;
|
||||||
megasas_poll_wait_aen = 0;
|
megasas_poll_wait_aen = 0;
|
||||||
|
instance->flag_ieee = 0;
|
||||||
|
|
||||||
instance->evt_detail = pci_alloc_consistent(pdev,
|
instance->evt_detail = pci_alloc_consistent(pdev,
|
||||||
sizeof(struct
|
sizeof(struct
|
||||||
@@ -2933,6 +2998,7 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||||||
|
|
||||||
if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
|
if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
|
||||||
(instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
|
(instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
|
||||||
|
instance->flag_ieee = 1;
|
||||||
sema_init(&instance->ioctl_sem, MEGASAS_SKINNY_INT_CMDS);
|
sema_init(&instance->ioctl_sem, MEGASAS_SKINNY_INT_CMDS);
|
||||||
} else
|
} else
|
||||||
sema_init(&instance->ioctl_sem, MEGASAS_INT_CMDS);
|
sema_init(&instance->ioctl_sem, MEGASAS_INT_CMDS);
|
||||||
|
@@ -96,6 +96,7 @@
|
|||||||
#define MFI_FRAME_DIR_WRITE 0x0008
|
#define MFI_FRAME_DIR_WRITE 0x0008
|
||||||
#define MFI_FRAME_DIR_READ 0x0010
|
#define MFI_FRAME_DIR_READ 0x0010
|
||||||
#define MFI_FRAME_DIR_BOTH 0x0018
|
#define MFI_FRAME_DIR_BOTH 0x0018
|
||||||
|
#define MFI_FRAME_IEEE 0x0020
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Definition for cmd_status
|
* Definition for cmd_status
|
||||||
@@ -732,10 +733,17 @@ struct megasas_sge64 {
|
|||||||
|
|
||||||
} __attribute__ ((packed));
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
struct megasas_sge_skinny {
|
||||||
|
u64 phys_addr;
|
||||||
|
u32 length;
|
||||||
|
u32 flag;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
union megasas_sgl {
|
union megasas_sgl {
|
||||||
|
|
||||||
struct megasas_sge32 sge32[1];
|
struct megasas_sge32 sge32[1];
|
||||||
struct megasas_sge64 sge64[1];
|
struct megasas_sge64 sge64[1];
|
||||||
|
struct megasas_sge_skinny sge_skinny[1];
|
||||||
|
|
||||||
} __attribute__ ((packed));
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
@@ -1210,6 +1218,7 @@ struct megasas_instance {
|
|||||||
|
|
||||||
u8 flag;
|
u8 flag;
|
||||||
u8 unload;
|
u8 unload;
|
||||||
|
u8 flag_ieee;
|
||||||
unsigned long last_time;
|
unsigned long last_time;
|
||||||
|
|
||||||
struct timer_list io_completion_timer;
|
struct timer_list io_completion_timer;
|
||||||
|
Reference in New Issue
Block a user