From patchwork Tue May 14 14:28:57 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ranjan Kumar X-Patchwork-Id: 797643 Received: from mail-pf1-f181.google.com (mail-pf1-f181.google.com [209.85.210.181]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9D251171098 for ; Tue, 14 May 2024 14:32:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.181 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715697139; cv=none; b=R1G6Vw7ij8L8GQtu/sqJK6B3UNCtoTfdFiAnSr46fP9XTXi7ZQP4JNyvDXNYicu3I6rgqVMPX6AInNQIINCl1VysuLDLMgr4nlRtSD4As//lJqfXEgQMC7yuI0Zp9zvFNIgPBhe4NQg7fyg2vQ54d9szX3Sa3kQ4ULCctPqiWUI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715697139; c=relaxed/simple; bh=1bSDMY6jr2R0ELqe83a5iZvUjcqng5ST7tnUR493Tgs=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=JvWY4Icsce9oFyg12E6F41SS8HfyIFoRNu6ttWlA8/+T8qyHP0ivDoyyZ+nY0V/UoTx60JQ0vb75a96ieQkFSPtej27ENbnTei8WHTrBxvsgiF8d699uJTqqo5LH6BIVGXPaWM6q3NQ9ZAZVmwDoMsMqzL0aWiPsGF/sZo7uDgg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=broadcom.com; spf=fail smtp.mailfrom=broadcom.com; dkim=pass (1024-bit key) header.d=broadcom.com header.i=@broadcom.com header.b=D4+nxQpe; arc=none smtp.client-ip=209.85.210.181 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=broadcom.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=broadcom.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=broadcom.com header.i=@broadcom.com header.b="D4+nxQpe" Received: by mail-pf1-f181.google.com with SMTP id d2e1a72fcca58-6f4e59191a1so3181471b3a.1 for ; Tue, 14 May 2024 07:32:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=broadcom.com; s=google; t=1715697136; x=1716301936; darn=vger.kernel.org; h=mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:from:to:cc:subject:date:message-id:reply-to; bh=hFlhn9S/drNiZHOAn7VuuWyKebjJFzZ6EQlW8y92D2U=; b=D4+nxQpeijeBFLk+XoLetr+ciK1r4AGuW+3I0YWxtJfhWtu38tSuQAfCnkyyIFnTAH MmtGLhl0zVyBicFTKCx9ObnYvCITIQnMa4E1TrWJvwvBmIO6mEpWmXXUuQ9EStwH+H77 Dxg9W6QMScpnBAaeWyY9OLkBVqu6Ce+CFUzBY= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1715697136; x=1716301936; h=mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=hFlhn9S/drNiZHOAn7VuuWyKebjJFzZ6EQlW8y92D2U=; b=ro+E+vtThhp0ydUMMr1LbzjUK2Kev5jGzmWzM7FM9O1ODeR+Qbhpufx3r5oH+82yk9 jXymwBUx8KkRM/lEaFsa8tCdEqc0Oyn/AnXHK21GV+KlTfM9emR2h2Gx4C4GC+DeJTVp JKaxds/1m2/m+GT0nYuh0yfl4a8ysgWd64ipmKJsAVISTuZbru3EX9niRj6DtjoxmZ4D P2tc/hUISdx8HYhcDtkL7pkSB5Bjh1d3PuvAkJQo/jpZxx1gq5hN0emsNlWfA/rlznRa QJWWTYAvX0o8mksv+Py8BIqt+XG+CwrTGVm5M6hj93v5PLRGYDGvKD6t1T5jQhjXMzOV NLfw== X-Gm-Message-State: AOJu0YyWi52TKk8Q3xdWAQ1/kBxdSgCHweuVXzaoQFiHKlQLo2QV6hdj +WHa4y7Bf2qXMfDbqLlTK0/vPA4C2G6NA/uMKRFt+l7GsvWh04ut1UqXGORB6RZA/cEoZINu8xb 3jqbiV+8MtdJzmCgl2uNi8M66aVk98o6kLQXNY/x9oFeVAAnx0IvoPX1nDLFBGuLKwQDquJ4pT7 mNzXP0HkWu7Cgq6GEWemocPaVRYzp1hpntYcyqpsJXehjpdg== X-Google-Smtp-Source: AGHT+IFiuQ6Kc6umxqrQ5IzExdBV5qjPzbocVscCErmGY1oEzcMNkX3+Qqhz7xKsuqdRkln9glCHqQ== X-Received: by 2002:a05:6a00:2daa:b0:6f3:ebc4:4407 with SMTP id d2e1a72fcca58-6f4e0299e1amr14070220b3a.4.1715697136146; Tue, 14 May 2024 07:32:16 -0700 (PDT) Received: from localhost.localdomain ([192.19.234.250]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-63560731046sm7849104a12.67.2024.05.14.07.32.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 14 May 2024 07:32:15 -0700 (PDT) From: Ranjan Kumar To: linux-scsi@vger.kernel.org, martin.petersen@oracle.com Cc: rajsekhar.chundru@broadcom.com, sathya.prakash@broadcom.com, sumit.saxena@broadcom.com, chandrakanth.patil@broadcom.com, prayas.patel@broadcom.com, Ranjan Kumar Subject: [PATCH v1 5/6] mpi3mr: Ioctl support for HDB Date: Tue, 14 May 2024 19:58:57 +0530 Message-Id: <20240514142858.51992-6-ranjan.kumar@broadcom.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20240514142858.51992-1-ranjan.kumar@broadcom.com> References: <20240514142858.51992-1-ranjan.kumar@broadcom.com> Precedence: bulk X-Mailing-List: linux-scsi@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 This patch provides interfaces for applications to manage the host diagnostic buffers and update the automatic diag buffer capture triggers. Signed-off-by: Sathya Prakash Signed-off-by: Ranjan Kumar --- drivers/scsi/mpi3mr/mpi3mr.h | 14 ++ drivers/scsi/mpi3mr/mpi3mr_app.c | 265 ++++++++++++++++++++++++++++ include/uapi/scsi/scsi_bsg_mpi3mr.h | 3 +- 3 files changed, 281 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/mpi3mr/mpi3mr.h b/drivers/scsi/mpi3mr/mpi3mr.h index 259f58b347fd..e27e37650f92 100644 --- a/drivers/scsi/mpi3mr/mpi3mr.h +++ b/drivers/scsi/mpi3mr/mpi3mr.h @@ -201,6 +201,20 @@ extern atomic64_t event_counter; #define MPI3MR_HDB_TRIGGER_TYPE_SOFT_RESET 4 #define MPI3MR_HDB_TRIGGER_TYPE_FW_RELEASED 5 +#define MPI3MR_HDB_REFRESH_TYPE_RESERVED 0 +#define MPI3MR_HDB_REFRESH_TYPE_CURRENT 1 +#define MPI3MR_HDB_REFRESH_TYPE_DEFAULT 2 +#define MPI3MR_HDB_HDB_REFRESH_TYPE_PERSISTENT 3 + +#define MPI3MR_DEFAULT_HDB_SZ (4 * 1024 * 1024) +#define MPI3MR_MAX_NUM_HDB 2 + +#define MPI3MR_HDB_QUERY_ELEMENT_TRIGGER_FORMAT_INDEX 0 +#define MPI3MR_HDB_QUERY_ELEMENT_TRIGGER_FORMAT_DATA 1 + + + + /* Driver Host Diag Buffer (drv_db) */ #define MPI3MR_MIN_DIAG_HOST_BUFFER_SZ ((32 * 1024) + \ sizeof(struct mpi3_driver_buffer_header)) diff --git a/drivers/scsi/mpi3mr/mpi3mr_app.c b/drivers/scsi/mpi3mr/mpi3mr_app.c index 95f6c37fd977..126f0be48c93 100644 --- a/drivers/scsi/mpi3mr/mpi3mr_app.c +++ b/drivers/scsi/mpi3mr/mpi3mr_app.c @@ -938,6 +938,259 @@ static struct mpi3mr_ioc *mpi3mr_bsg_verify_adapter(int ioc_number) return NULL; } +/** + * mpi3mr_bsg_refresh_hdb_triggers - Refresh HDB trigger data + * @mrioc: Adapter instance reference + * @job: BSG Job pointer + * + * This function reads the controller trigger config page as + * defined by the input page type and refreshes the driver's + * local trigger information structures with the controller's + * config page data. + * + * Return: 0 on success and proper error codes on failure + */ +static long +mpi3mr_bsg_refresh_hdb_triggers(struct mpi3mr_ioc *mrioc, + struct bsg_job *job) +{ + struct mpi3mr_bsg_out_refresh_hdb_triggers refresh_triggers; + uint32_t data_out_sz; + u8 page_action; + long rval = -EINVAL; + + data_out_sz = job->request_payload.payload_len; + + if (data_out_sz != sizeof(refresh_triggers)) { + dprint_bsg_err(mrioc, "%s: invalid size argument\n", + __func__); + return rval; + } + + if (mrioc->unrecoverable) { + dprint_bsg_err(mrioc, "%s: unrecoverable controller\n", + __func__); + return -EFAULT; + } + if (mrioc->reset_in_progress) { + dprint_bsg_err(mrioc, "%s: reset in progress\n", __func__); + return -EAGAIN; + } + + sg_copy_to_buffer(job->request_payload.sg_list, + job->request_payload.sg_cnt, + &refresh_triggers, sizeof(refresh_triggers)); + + switch (refresh_triggers.page_type) { + case MPI3MR_HDB_REFRESH_TYPE_CURRENT: + page_action = MPI3_CONFIG_ACTION_READ_CURRENT; + break; + case MPI3MR_HDB_REFRESH_TYPE_DEFAULT: + page_action = MPI3_CONFIG_ACTION_READ_DEFAULT; + break; + case MPI3MR_HDB_HDB_REFRESH_TYPE_PERSISTENT: + page_action = MPI3_CONFIG_ACTION_READ_PERSISTENT; + break; + default: + dprint_bsg_err(mrioc, + "%s: unsupported refresh trigger, page_type %d\n", + __func__, refresh_triggers.page_type); + return rval; + } + rval = mpi3mr_refresh_trigger(mrioc, page_action); + + return rval; +} + +/** + * mpi3mr_bsg_upload_hdb - Upload a specific HDB to user space + * @mrioc: Adapter instance reference + * @job: BSG Job pointer + * + * Return: 0 on success and proper error codes on failure + */ +static long mpi3mr_bsg_upload_hdb(struct mpi3mr_ioc *mrioc, + struct bsg_job *job) +{ + struct mpi3mr_bsg_out_upload_hdb upload_hdb; + struct diag_buffer_desc *diag_buffer; + uint32_t data_out_size; + uint32_t data_in_size; + + data_out_size = job->request_payload.payload_len; + data_in_size = job->reply_payload.payload_len; + + if (data_out_size != sizeof(upload_hdb)) { + dprint_bsg_err(mrioc, "%s: invalid size argument\n", + __func__); + return -EINVAL; + } + + sg_copy_to_buffer(job->request_payload.sg_list, + job->request_payload.sg_cnt, + &upload_hdb, sizeof(upload_hdb)); + + if ((!upload_hdb.length) || (data_in_size != upload_hdb.length)) { + dprint_bsg_err(mrioc, "%s: invalid length argument\n", + __func__); + return -EINVAL; + } + diag_buffer = mpi3mr_diag_buffer_for_type(mrioc, upload_hdb.buf_type); + if ((!diag_buffer) || (!diag_buffer->addr)) { + dprint_bsg_err(mrioc, "%s: invalid buffer type %d\n", + __func__, upload_hdb.buf_type); + return -EINVAL; + } + + if ((diag_buffer->status != MPI3MR_HDB_BUFSTATUS_RELEASED) && + (diag_buffer->status != MPI3MR_HDB_BUFSTATUS_POSTED_PAUSED)) { + dprint_bsg_err(mrioc, + "%s: invalid buffer status %d for type %d\n", + __func__, diag_buffer->status, upload_hdb.buf_type); + return -EINVAL; + } + + if ((upload_hdb.start_offset + upload_hdb.length) > diag_buffer->size) { + dprint_bsg_err(mrioc, + "%s: invalid start offset %d, length %d for type %d\n", + __func__, upload_hdb.start_offset, upload_hdb.length, + upload_hdb.buf_type); + return -EINVAL; + } + sg_copy_from_buffer(job->reply_payload.sg_list, + job->reply_payload.sg_cnt, + (diag_buffer->addr + upload_hdb.start_offset), + data_in_size); + return 0; +} + +/** + * mpi3mr_bsg_repost_hdb - Re-post HDB + * @mrioc: Adapter instance reference + * @job: BSG job pointer + * + * This function retrieves the HDB descriptor corresponding to a + * given buffer type and if the HDB is in released status then + * posts the HDB with the firmware. + * + * Return: 0 on success and proper error codes on failure + */ +static long mpi3mr_bsg_repost_hdb(struct mpi3mr_ioc *mrioc, + struct bsg_job *job) +{ + struct mpi3mr_bsg_out_repost_hdb repost_hdb; + struct diag_buffer_desc *diag_buffer; + uint32_t data_out_sz; + + data_out_sz = job->request_payload.payload_len; + + if (data_out_sz != sizeof(repost_hdb)) { + dprint_bsg_err(mrioc, "%s: invalid size argument\n", + __func__); + return -EINVAL; + } + if (mrioc->unrecoverable) { + dprint_bsg_err(mrioc, "%s: unrecoverable controller\n", + __func__); + return -EFAULT; + } + if (mrioc->reset_in_progress) { + dprint_bsg_err(mrioc, "%s: reset in progress\n", __func__); + return -EAGAIN; + } + + sg_copy_to_buffer(job->request_payload.sg_list, + job->request_payload.sg_cnt, + &repost_hdb, sizeof(repost_hdb)); + + diag_buffer = mpi3mr_diag_buffer_for_type(mrioc, repost_hdb.buf_type); + if ((!diag_buffer) || (!diag_buffer->addr)) { + dprint_bsg_err(mrioc, "%s: invalid buffer type %d\n", + __func__, repost_hdb.buf_type); + return -EINVAL; + } + + if (diag_buffer->status != MPI3MR_HDB_BUFSTATUS_RELEASED) { + dprint_bsg_err(mrioc, + "%s: invalid buffer status %d for type %d\n", + __func__, diag_buffer->status, repost_hdb.buf_type); + return -EINVAL; + } + + if (mpi3mr_issue_diag_buf_post(mrioc, diag_buffer)) { + dprint_bsg_err(mrioc, "%s: post failed for type %d\n", + __func__, repost_hdb.buf_type); + return -EFAULT; + } + mpi3mr_set_trigger_data_in_hdb(diag_buffer, + MPI3MR_HDB_TRIGGER_TYPE_UNKNOWN, NULL, 1); + + return 0; +} + +/** + * mpi3mr_bsg_query_hdb - Handler for query HDB command + * @mrioc: Adapter instance reference + * @job: BSG job pointer + * + * This function prepares and copies the host diagnostic buffer + * entries to the user buffer. + * + * Return: 0 on success and proper error codes on failure + */ +static long mpi3mr_bsg_query_hdb(struct mpi3mr_ioc *mrioc, + struct bsg_job *job) +{ + long rval = 0; + struct mpi3mr_bsg_in_hdb_status *hbd_status; + struct mpi3mr_hdb_entry *hbd_status_entry; + u32 length, min_length; + u8 i; + struct diag_buffer_desc *diag_buffer; + uint32_t data_in_sz = 0; + + data_in_sz = job->request_payload.payload_len; + + length = (sizeof(*hbd_status) + ((MPI3MR_MAX_NUM_HDB - 1) * + sizeof(*hbd_status_entry))); + hbd_status = kmalloc(length, GFP_KERNEL); + if (!hbd_status) + return -ENOMEM; + hbd_status_entry = &hbd_status->entry[0]; + + hbd_status->num_hdb_types = MPI3MR_MAX_NUM_HDB; + for (i = 0; i < MPI3MR_MAX_NUM_HDB; i++) { + diag_buffer = &mrioc->diag_buffers[i]; + hbd_status_entry->buf_type = diag_buffer->type; + hbd_status_entry->status = diag_buffer->status; + hbd_status_entry->trigger_type = diag_buffer->trigger_type; + memcpy(&hbd_status_entry->trigger_data, + &diag_buffer->trigger_data, + sizeof(hbd_status_entry->trigger_data)); + hbd_status_entry->size = (diag_buffer->size / 1024); + hbd_status_entry++; + } + hbd_status->element_trigger_format = + MPI3MR_HDB_QUERY_ELEMENT_TRIGGER_FORMAT_DATA; + + if (data_in_sz < 4) { + dprint_bsg_err(mrioc, "%s: invalid size passed\n", __func__); + rval = -EINVAL; + goto out; + } + min_length = min(data_in_sz, length); + if (job->request_payload.payload_len >= min_length) { + sg_copy_from_buffer(job->request_payload.sg_list, + job->request_payload.sg_cnt, + hbd_status, min_length); + rval = 0; + } +out: + kfree(hbd_status); + return rval; +} + + /** * mpi3mr_enable_logdata - Handler for log data enable * @mrioc: Adapter instance reference @@ -1366,6 +1619,18 @@ static long mpi3mr_bsg_process_drv_cmds(struct bsg_job *job) case MPI3MR_DRVBSG_OPCODE_PELENABLE: rval = mpi3mr_bsg_pel_enable(mrioc, job); break; + case MPI3MR_DRVBSG_OPCODE_QUERY_HDB: + rval = mpi3mr_bsg_query_hdb(mrioc, job); + break; + case MPI3MR_DRVBSG_OPCODE_REPOST_HDB: + rval = mpi3mr_bsg_repost_hdb(mrioc, job); + break; + case MPI3MR_DRVBSG_OPCODE_UPLOAD_HDB: + rval = mpi3mr_bsg_upload_hdb(mrioc, job); + break; + case MPI3MR_DRVBSG_OPCODE_REFRESH_HDB_TRIGGERS: + rval = mpi3mr_bsg_refresh_hdb_triggers(mrioc, job); + break; case MPI3MR_DRVBSG_OPCODE_UNKNOWN: default: pr_err("%s: unsupported driver command opcode %d\n", diff --git a/include/uapi/scsi/scsi_bsg_mpi3mr.h b/include/uapi/scsi/scsi_bsg_mpi3mr.h index c72ce387286a..92a0eb190e1c 100644 --- a/include/uapi/scsi/scsi_bsg_mpi3mr.h +++ b/include/uapi/scsi/scsi_bsg_mpi3mr.h @@ -296,6 +296,7 @@ struct mpi3mr_hdb_entry { * multiple hdb entries. * * @num_hdb_types: Number of host diag buffer types supported + * @element_trigger_format: Element trigger format * @rsvd1: Reserved * @rsvd2: Reserved * @rsvd3: Reserved @@ -303,7 +304,7 @@ struct mpi3mr_hdb_entry { */ struct mpi3mr_bsg_in_hdb_status { __u8 num_hdb_types; - __u8 rsvd1; + __u8 element_trigger_format; __u16 rsvd2; __u32 rsvd3; struct mpi3mr_hdb_entry entry[1];