mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-22 17:25:35 +03:00
vblk: Handle SCSI IOCTL case where mx_sb_len is 0
Storage server expectes the mx_sb_len to be set to non-zero value in order to pass on the sense information assosiated with the SCSI command to the user. Some of the open source implementations(Ex:f2fs) that use SG_IO SCSI IOCTL interface set the mx_sb_len to 0. Handle this case in the vblk client driver. Bug 4060482 Change-Id: Ib3779f9cd4beb2822add95d4773909b7d3e7217a Signed-off-by: Sanjith T D <std@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/2894395 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Manish Bhardwaj <mbhardwaj@nvidia.com> Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-cert <svc-mobile-cert@nvidia.com> Reviewed-by: Vipin Kumar <vipink@nvidia.com> GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com>
This commit is contained in:
committed by
mobile promotions
parent
5395e466bf
commit
19cd2b3ccc
@@ -1,6 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
* Copyright (c) 2022-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
@@ -16,6 +16,8 @@
|
|||||||
#include <scsi/sg.h>
|
#include <scsi/sg.h>
|
||||||
#include "tegra_vblk.h"
|
#include "tegra_vblk.h"
|
||||||
|
|
||||||
|
#define UFS_REQUEST_SENS_DATA_LEN 18U
|
||||||
|
|
||||||
int vblk_prep_sg_io(struct vblk_dev *vblkdev,
|
int vblk_prep_sg_io(struct vblk_dev *vblkdev,
|
||||||
struct vblk_ioctl_req *ioctl_req,
|
struct vblk_ioctl_req *ioctl_req,
|
||||||
void __user *user)
|
void __user *user)
|
||||||
@@ -35,6 +37,7 @@ int vblk_prep_sg_io(struct vblk_dev *vblkdev,
|
|||||||
uint32_t data_buf_size_aligned;
|
uint32_t data_buf_size_aligned;
|
||||||
uint32_t ioctl_len;
|
uint32_t ioctl_len;
|
||||||
void *ioctl_buf = NULL;
|
void *ioctl_buf = NULL;
|
||||||
|
uint32_t max_sb_len;
|
||||||
|
|
||||||
hp = kmalloc(header_len, GFP_KERNEL);
|
hp = kmalloc(header_len, GFP_KERNEL);
|
||||||
if (hp == NULL) {
|
if (hp == NULL) {
|
||||||
@@ -59,8 +62,13 @@ int vblk_prep_sg_io(struct vblk_dev *vblkdev,
|
|||||||
err = - EMSGSIZE;
|
err = - EMSGSIZE;
|
||||||
goto free_hp;
|
goto free_hp;
|
||||||
}
|
}
|
||||||
|
if (hp->mx_sb_len == 0)
|
||||||
|
max_sb_len = UFS_REQUEST_SENS_DATA_LEN;
|
||||||
|
else
|
||||||
|
max_sb_len = hp->mx_sb_len;
|
||||||
|
|
||||||
|
data_buf_offset = (sbp_offset + max_sb_len);
|
||||||
|
|
||||||
data_buf_offset = (sbp_offset + hp->mx_sb_len);
|
|
||||||
if (data_buf_offset < sbp_offset) {
|
if (data_buf_offset < sbp_offset) {
|
||||||
err = -EMSGSIZE;
|
err = -EMSGSIZE;
|
||||||
goto free_hp;
|
goto free_hp;
|
||||||
@@ -129,7 +137,7 @@ int vblk_prep_sg_io(struct vblk_dev *vblkdev,
|
|||||||
}
|
}
|
||||||
|
|
||||||
vblk_hp->cmd_len = hp->cmd_len;
|
vblk_hp->cmd_len = hp->cmd_len;
|
||||||
vblk_hp->mx_sb_len = hp->mx_sb_len;
|
vblk_hp->mx_sb_len = max_sb_len;
|
||||||
/* This is actual data len on which storage server needs to act */
|
/* This is actual data len on which storage server needs to act */
|
||||||
vblk_hp->dxfer_len = hp->dxfer_len;
|
vblk_hp->dxfer_len = hp->dxfer_len;
|
||||||
/* This is the data buffer len, data length is strictly dependent on the
|
/* This is the data buffer len, data length is strictly dependent on the
|
||||||
@@ -191,7 +199,11 @@ int vblk_complete_sg_io(struct vblk_dev *vblkdev,
|
|||||||
hp->masked_status = status_byte(vblk_hp->status);
|
hp->masked_status = status_byte(vblk_hp->status);
|
||||||
hp->host_status = host_byte(vblk_hp->status);
|
hp->host_status = host_byte(vblk_hp->status);
|
||||||
hp->driver_status = driver_byte(vblk_hp->status);
|
hp->driver_status = driver_byte(vblk_hp->status);
|
||||||
|
if (hp->mx_sb_len != 0U)
|
||||||
hp->sb_len_wr = vblk_hp->sb_len_wr;
|
hp->sb_len_wr = vblk_hp->sb_len_wr;
|
||||||
|
else
|
||||||
|
hp->sb_len_wr = 0U;
|
||||||
|
|
||||||
/* TODO: Handle the residual length */
|
/* TODO: Handle the residual length */
|
||||||
hp->resid = 0;
|
hp->resid = 0;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user