From patchwork Wed Nov 11 12:00:24 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sreekanth Reddy X-Patchwork-Id: 7595571 Return-Path: X-Original-To: patchwork-linux-scsi@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 3B733BF90C for ; Wed, 11 Nov 2015 12:08:31 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 2E35C204FF for ; Wed, 11 Nov 2015 12:08:30 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 037B32075F for ; Wed, 11 Nov 2015 12:08:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752720AbbKKMBz (ORCPT ); Wed, 11 Nov 2015 07:01:55 -0500 Received: from mail-pa0-f46.google.com ([209.85.220.46]:35267 "EHLO mail-pa0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752190AbbKKMBs (ORCPT ); Wed, 11 Nov 2015 07:01:48 -0500 Received: by pasz6 with SMTP id z6so30627965pas.2 for ; Wed, 11 Nov 2015 04:01:48 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=avagotech.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=IEisthqRN5MjTbVi++uiW5tHAbXiGPKBa+aYBPr9zM0=; b=IUnfvrpTBkcWdgHVqZHgHDVTCKKFV9/9+zEUFkg84SZKesMEpu951gtpPVjrJQa9Bh u0bcgCSqxYfOU1ycl7Z+bTtOFuynbDBImDoD9N2+oCRZ0v9xAKYfsFmEA2vXiuzkrjFS /piu3kSBmsfOh/W9QpnE20IkA5Xe4G0n6HhHw= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=IEisthqRN5MjTbVi++uiW5tHAbXiGPKBa+aYBPr9zM0=; b=mm+6kf/wqTmVfv+j5PT5hWTFMfdhF9cgOK+NlFOrZRx8EwVRKonSw4XpqSgGMJTYTg g0w3gcNlY7avy9qNsSEt6NQdMCteNL07Nbc11ibtjd/9oh4XLrSZeLqVyggR97qfDZDf PUYLwngfXYS8JJ1iyYQzlmblLDP387t/yXFFz5y78hM1GqT2ftp3sC/p+inDFoAUu1Yb ryGl73bqgqGaZVR648ZwVYlXIlKXr3cbUuI7sAykhsxORKns+wlKW47ck5HNDBE10Okl ESvf0ZgpriEmDEGZAHoh1B2cdtRG20CseNg6yRrs+W9HWFxRmw8yAg5/6I5w2Jol2K2V iSGQ== X-Gm-Message-State: ALoCoQmfbYLQTwluWNlhQQee84goiT7wfxtf8IeseI+/93KvSQk+O273pPmmILrMwz7GBbqsE+Km X-Received: by 10.66.102.101 with SMTP id fn5mr13976594pab.66.1447243307697; Wed, 11 Nov 2015 04:01:47 -0800 (PST) Received: from host1.lsi.com ([192.19.239.250]) by smtp.gmail.com with ESMTPSA id zi1sm9180851pbc.10.2015.11.11.04.01.42 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 11 Nov 2015 04:01:46 -0800 (PST) From: Sreekanth Reddy X-Google-Original-From: Sreekanth Reddy To: jejb@kernel.org Cc: martin.petersen@oracle.com, linux-scsi@vger.kernel.org, JBottomley@Parallels.com, Sathya.Prakash@avagotech.com, kashyap.desai@avagotech.com, linux-kernel@vger.kernel.org, hch@infradead.org, chaitra.basappa@avagotech.com, suganath-prabu.subramani@avagotech.com, Sreekanth Reddy , Sreekanth Reddy Subject: [PATCH RESEND 08/25] mpt3sas: For an IO, build MPI SGL LIST on GEN2 HBA's and build IEEE SGL LIST on GEN3 HBA's Date: Wed, 11 Nov 2015 17:30:24 +0530 Message-Id: <1447243241-10912-9-git-send-email-Sreekanth.Reddy@avagotech.com> X-Mailer: git-send-email 2.0.2 In-Reply-To: <1447243241-10912-1-git-send-email-Sreekanth.Reddy@avagotech.com> References: <1447243241-10912-1-git-send-email-Sreekanth.Reddy@avagotech.com> Sender: linux-scsi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org X-Spam-Status: No, score=-7.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,RP_MATCHES_RCVD,T_DKIM_INVALID,UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Sreekanth Reddy Gen2 HBA's uses MPI Scatter Gather Lists where as Gen3 HBA's uses IEEE Scatter Gather Lists. So modify the common code part in such a way that it will build IEEE SGL table for Gen3 HBA's and it will build MPI SGL table for Gen2 HBA's. Signed-off-by: Sreekanth Reddy --- drivers/scsi/mpt3sas/mpt3sas_base.c | 181 +++++++++++++++++++++++++++++++++--- 1 file changed, 168 insertions(+), 13 deletions(-) diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c index 31d0ca8..62dc312 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.c +++ b/drivers/scsi/mpt3sas/mpt3sas_base.c @@ -1318,6 +1318,149 @@ _base_build_zero_len_sge_ieee(struct MPT3SAS_ADAPTER *ioc, void *paddr) } /** + * _base_build_sg_scmd - main sg creation routine + * @ioc: per adapter object + * @scmd: scsi command + * @smid: system request message index + * Context: none. + * + * The main routine that builds scatter gather table from a given + * scsi request sent via the .queuecommand main handler. + * + * Returns 0 success, anything else error + */ +static int +_base_build_sg_scmd(struct MPT3SAS_ADAPTER *ioc, + struct scsi_cmnd *scmd, u16 smid) +{ + Mpi2SCSIIORequest_t *mpi_request; + dma_addr_t chain_dma; + struct scatterlist *sg_scmd; + void *sg_local, *chain; + u32 chain_offset; + u32 chain_length; + u32 chain_flags; + int sges_left; + u32 sges_in_segment; + u32 sgl_flags; + u32 sgl_flags_last_element; + u32 sgl_flags_end_buffer; + struct chain_tracker *chain_req; + + mpi_request = mpt3sas_base_get_msg_frame(ioc, smid); + + /* init scatter gather flags */ + sgl_flags = MPI2_SGE_FLAGS_SIMPLE_ELEMENT; + if (scmd->sc_data_direction == DMA_TO_DEVICE) + sgl_flags |= MPI2_SGE_FLAGS_HOST_TO_IOC; + sgl_flags_last_element = (sgl_flags | MPI2_SGE_FLAGS_LAST_ELEMENT) + << MPI2_SGE_FLAGS_SHIFT; + sgl_flags_end_buffer = (sgl_flags | MPI2_SGE_FLAGS_LAST_ELEMENT | + MPI2_SGE_FLAGS_END_OF_BUFFER | MPI2_SGE_FLAGS_END_OF_LIST) + << MPI2_SGE_FLAGS_SHIFT; + sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT; + + sg_scmd = scsi_sglist(scmd); + sges_left = scsi_dma_map(scmd); + if (sges_left < 0) { + sdev_printk(KERN_ERR, scmd->device, + "pci_map_sg failed: request for %d bytes!\n", + scsi_bufflen(scmd)); + return -ENOMEM; + } + + sg_local = &mpi_request->SGL; + sges_in_segment = ioc->max_sges_in_main_message; + if (sges_left <= sges_in_segment) + goto fill_in_last_segment; + + mpi_request->ChainOffset = (offsetof(Mpi2SCSIIORequest_t, SGL) + + (sges_in_segment * ioc->sge_size))/4; + + /* fill in main message segment when there is a chain following */ + while (sges_in_segment) { + if (sges_in_segment == 1) + ioc->base_add_sg_single(sg_local, + sgl_flags_last_element | sg_dma_len(sg_scmd), + sg_dma_address(sg_scmd)); + else + ioc->base_add_sg_single(sg_local, sgl_flags | + sg_dma_len(sg_scmd), sg_dma_address(sg_scmd)); + sg_scmd = sg_next(sg_scmd); + sg_local += ioc->sge_size; + sges_left--; + sges_in_segment--; + } + + /* initializing the chain flags and pointers */ + chain_flags = MPI2_SGE_FLAGS_CHAIN_ELEMENT << MPI2_SGE_FLAGS_SHIFT; + chain_req = _base_get_chain_buffer_tracker(ioc, smid); + if (!chain_req) + return -1; + chain = chain_req->chain_buffer; + chain_dma = chain_req->chain_buffer_dma; + do { + sges_in_segment = (sges_left <= + ioc->max_sges_in_chain_message) ? sges_left : + ioc->max_sges_in_chain_message; + chain_offset = (sges_left == sges_in_segment) ? + 0 : (sges_in_segment * ioc->sge_size)/4; + chain_length = sges_in_segment * ioc->sge_size; + if (chain_offset) { + chain_offset = chain_offset << + MPI2_SGE_CHAIN_OFFSET_SHIFT; + chain_length += ioc->sge_size; + } + ioc->base_add_sg_single(sg_local, chain_flags | chain_offset | + chain_length, chain_dma); + sg_local = chain; + if (!chain_offset) + goto fill_in_last_segment; + + /* fill in chain segments */ + while (sges_in_segment) { + if (sges_in_segment == 1) + ioc->base_add_sg_single(sg_local, + sgl_flags_last_element | + sg_dma_len(sg_scmd), + sg_dma_address(sg_scmd)); + else + ioc->base_add_sg_single(sg_local, sgl_flags | + sg_dma_len(sg_scmd), + sg_dma_address(sg_scmd)); + sg_scmd = sg_next(sg_scmd); + sg_local += ioc->sge_size; + sges_left--; + sges_in_segment--; + } + + chain_req = _base_get_chain_buffer_tracker(ioc, smid); + if (!chain_req) + return -1; + chain = chain_req->chain_buffer; + chain_dma = chain_req->chain_buffer_dma; + } while (1); + + + fill_in_last_segment: + + /* fill the last segment */ + while (sges_left) { + if (sges_left == 1) + ioc->base_add_sg_single(sg_local, sgl_flags_end_buffer | + sg_dma_len(sg_scmd), sg_dma_address(sg_scmd)); + else + ioc->base_add_sg_single(sg_local, sgl_flags | + sg_dma_len(sg_scmd), sg_dma_address(sg_scmd)); + sg_scmd = sg_next(sg_scmd); + sg_local += ioc->sge_size; + sges_left--; + } + + return 0; +} + +/** * _base_build_sg_scmd_ieee - main sg creation routine for IEEE format * @ioc: per adapter object * @scmd: scsi command @@ -2850,8 +2993,12 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc, int sleep_flag) /* command line tunables for max sgl entries */ if (max_sgl_entries != -1) sg_tablesize = max_sgl_entries; - else - sg_tablesize = MPT3SAS_SG_DEPTH; + else { + if (ioc->hba_mpi_version_belonged == MPI2_VERSION) + sg_tablesize = MPT2SAS_SG_DEPTH; + else + sg_tablesize = MPT3SAS_SG_DEPTH; + } if (sg_tablesize < MPT_MIN_PHYS_SEGMENTS) sg_tablesize = MPT_MIN_PHYS_SEGMENTS; @@ -4878,17 +5025,25 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc) if (r) goto out_free_resources; - /* - * In SAS3.0, - * SCSI_IO, SMP_PASSTHRU, SATA_PASSTHRU, Target Assist, and - * Target Status - all require the IEEE formated scatter gather - * elements. - */ - - ioc->build_sg_scmd = &_base_build_sg_scmd_ieee; - ioc->build_sg = &_base_build_sg_ieee; - ioc->build_zero_len_sge = &_base_build_zero_len_sge_ieee; - ioc->sge_size_ieee = sizeof(Mpi2IeeeSgeSimple64_t); + switch (ioc->hba_mpi_version_belonged) { + case MPI2_VERSION: + ioc->build_sg_scmd = &_base_build_sg_scmd; + ioc->build_sg = &_base_build_sg; + ioc->build_zero_len_sge = &_base_build_zero_len_sge; + break; + case MPI25_VERSION: + /* + * In SAS3.0, + * SCSI_IO, SMP_PASSTHRU, SATA_PASSTHRU, Target Assist, and + * Target Status - all require the IEEE formated scatter gather + * elements. + */ + ioc->build_sg_scmd = &_base_build_sg_scmd_ieee; + ioc->build_sg = &_base_build_sg_ieee; + ioc->build_zero_len_sge = &_base_build_zero_len_sge_ieee; + ioc->sge_size_ieee = sizeof(Mpi2IeeeSgeSimple64_t); + break; + } /* * These function pointers for other requests that don't