Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2)  *  linux/drivers/scsi/esas2r/esas2r_vda.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *      esas2r driver VDA firmware interface functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *  Copyright (c) 2001-2013 ATTO Technology, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *  (mailto:linuxdrivers@attotech.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  *  This program is free software; you can redistribute it and/or modify
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  *  it under the terms of the GNU General Public License as published by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  *  the Free Software Foundation; version 2 of the License.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  *  This program is distributed in the hope that it will be useful,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17)  *  GNU General Public License for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19)  *  NO WARRANTY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)  *  THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21)  *  CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22)  *  LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)  *  MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24)  *  solely responsible for determining the appropriateness of using and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25)  *  distributing the Program and assumes all risks associated with its
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26)  *  exercise of rights under this Agreement, including but not limited to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27)  *  the risks and costs of program errors, damage to or loss of data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28)  *  programs or equipment, and unavailability or interruption of operations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30)  *  DISCLAIMER OF LIABILITY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31)  *  NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32)  *  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33)  *  DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34)  *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35)  *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36)  *  USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37)  *  HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39)  *  You should have received a copy of the GNU General Public License
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40)  *  along with this program; if not, write to the Free Software
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41)  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) #include "esas2r.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) static u8 esas2r_vdaioctl_versions[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	ATTO_VDA_VER_UNSUPPORTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	ATTO_VDA_FLASH_VER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	ATTO_VDA_VER_UNSUPPORTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	ATTO_VDA_VER_UNSUPPORTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	ATTO_VDA_CLI_VER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	ATTO_VDA_VER_UNSUPPORTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	ATTO_VDA_CFG_VER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	ATTO_VDA_MGT_VER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	ATTO_VDA_GSV_VER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) static void clear_vda_request(struct esas2r_request *rq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) static void esas2r_complete_vda_ioctl(struct esas2r_adapter *a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 				      struct esas2r_request *rq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) /* Prepare a VDA IOCTL request to be sent to the firmware. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) bool esas2r_process_vda_ioctl(struct esas2r_adapter *a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 			      struct atto_ioctl_vda *vi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 			      struct esas2r_request *rq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 			      struct esas2r_sg_context *sgc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	u32 datalen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	struct atto_vda_sge *firstsg = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	u8 vercnt = (u8)ARRAY_SIZE(esas2r_vdaioctl_versions);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	vi->status = ATTO_STS_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	vi->vda_status = RS_PENDING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	if (vi->function >= vercnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 		vi->status = ATTO_STS_INV_FUNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	if (vi->version > esas2r_vdaioctl_versions[vi->function]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 		vi->status = ATTO_STS_INV_VERSION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	if (test_bit(AF_DEGRADED_MODE, &a->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 		vi->status = ATTO_STS_DEGRADED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	if (vi->function != VDA_FUNC_SCSI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 		clear_vda_request(rq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	rq->vrq->scsi.function = vi->function;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	rq->interrupt_cb = esas2r_complete_vda_ioctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	rq->interrupt_cx = vi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	switch (vi->function) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	case VDA_FUNC_FLASH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 		if (vi->cmd.flash.sub_func != VDA_FLASH_FREAD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 		    && vi->cmd.flash.sub_func != VDA_FLASH_FWRITE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 		    && vi->cmd.flash.sub_func != VDA_FLASH_FINFO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 			vi->status = ATTO_STS_INV_FUNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 		if (vi->cmd.flash.sub_func != VDA_FLASH_FINFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 			datalen = vi->data_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 		rq->vrq->flash.length = cpu_to_le32(datalen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 		rq->vrq->flash.sub_func = vi->cmd.flash.sub_func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 		memcpy(rq->vrq->flash.data.file.file_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 		       vi->cmd.flash.data.file.file_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 		       sizeof(vi->cmd.flash.data.file.file_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 		firstsg = rq->vrq->flash.data.file.sge;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	case VDA_FUNC_CLI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 		datalen = vi->data_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 		rq->vrq->cli.cmd_rsp_len =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 			cpu_to_le32(vi->cmd.cli.cmd_rsp_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 		rq->vrq->cli.length = cpu_to_le32(datalen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 		firstsg = rq->vrq->cli.sge;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	case VDA_FUNC_MGT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 		u8 *cmdcurr_offset = sgc->cur_offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 				     - offsetof(struct atto_ioctl_vda, data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 				     + offsetof(struct atto_ioctl_vda, cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 				     + offsetof(struct atto_ioctl_vda_mgt_cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 						data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 		 * build the data payload SGL here first since
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 		 * esas2r_sgc_init() will modify the S/G list offset for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 		 * management SGL (which is built below where the data SGL is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 		 * usually built).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 		if (vi->data_length) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 			u32 payldlen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 			if (vi->cmd.mgt.mgt_func == VDAMGT_DEV_HEALTH_REQ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 			    || vi->cmd.mgt.mgt_func == VDAMGT_DEV_METRICS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 				rq->vrq->mgt.payld_sglst_offset =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 					(u8)offsetof(struct atto_vda_mgmt_req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 						     payld_sge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 				payldlen = vi->data_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 				datalen = vi->cmd.mgt.data_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 			} else if (vi->cmd.mgt.mgt_func == VDAMGT_DEV_INFO2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 				   || vi->cmd.mgt.mgt_func ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 				   VDAMGT_DEV_INFO2_BYADDR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 				datalen = vi->data_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 				cmdcurr_offset = sgc->cur_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 				vi->status = ATTO_STS_INV_PARAM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 				return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 			/* Setup the length so building the payload SGL works */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 			rq->vrq->mgt.length = cpu_to_le32(datalen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 			if (payldlen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 				rq->vrq->mgt.payld_length =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 					cpu_to_le32(payldlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 				esas2r_sgc_init(sgc, a, rq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 						rq->vrq->mgt.payld_sge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 				sgc->length = payldlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 				if (!esas2r_build_sg_list(a, rq, sgc)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 					vi->status = ATTO_STS_OUT_OF_RSRC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 					return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 			datalen = vi->cmd.mgt.data_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 			rq->vrq->mgt.length = cpu_to_le32(datalen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 		 * Now that the payload SGL is built, if any, setup to build
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 		 * the management SGL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 		firstsg = rq->vrq->mgt.sge;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 		sgc->cur_offset = cmdcurr_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 		/* Finish initializing the management request. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 		rq->vrq->mgt.mgt_func = vi->cmd.mgt.mgt_func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 		rq->vrq->mgt.scan_generation = vi->cmd.mgt.scan_generation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 		rq->vrq->mgt.dev_index =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 			cpu_to_le32(vi->cmd.mgt.dev_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 		esas2r_nuxi_mgt_data(rq->vrq->mgt.mgt_func, &vi->cmd.mgt.data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	case VDA_FUNC_CFG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 		if (vi->data_length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 		    || vi->cmd.cfg.data_length == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 			vi->status = ATTO_STS_INV_PARAM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 		if (vi->cmd.cfg.cfg_func == VDA_CFG_INIT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 			vi->status = ATTO_STS_INV_FUNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 		rq->vrq->cfg.sub_func = vi->cmd.cfg.cfg_func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 		rq->vrq->cfg.length = cpu_to_le32(vi->cmd.cfg.data_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 		if (vi->cmd.cfg.cfg_func == VDA_CFG_GET_INIT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 			memcpy(&rq->vrq->cfg.data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 			       &vi->cmd.cfg.data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 			       vi->cmd.cfg.data_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 			esas2r_nuxi_cfg_data(rq->vrq->cfg.sub_func,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 					     &rq->vrq->cfg.data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 			vi->status = ATTO_STS_INV_FUNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	case VDA_FUNC_GSV:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 		vi->cmd.gsv.rsp_len = vercnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 		memcpy(vi->cmd.gsv.version_info, esas2r_vdaioctl_versions,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 		       vercnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 		vi->vda_status = RS_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 		vi->status = ATTO_STS_INV_FUNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	if (datalen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 		esas2r_sgc_init(sgc, a, rq, firstsg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 		sgc->length = datalen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 		if (!esas2r_build_sg_list(a, rq, sgc)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 			vi->status = ATTO_STS_OUT_OF_RSRC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	esas2r_start_request(a, rq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) static void esas2r_complete_vda_ioctl(struct esas2r_adapter *a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 				      struct esas2r_request *rq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	struct atto_ioctl_vda *vi = (struct atto_ioctl_vda *)rq->interrupt_cx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 	vi->vda_status = rq->req_stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	switch (vi->function) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	case VDA_FUNC_FLASH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 		if (vi->cmd.flash.sub_func == VDA_FLASH_FINFO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 		    || vi->cmd.flash.sub_func == VDA_FLASH_FREAD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 			vi->cmd.flash.data.file.file_size =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 				le32_to_cpu(rq->func_rsp.flash_rsp.file_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 	case VDA_FUNC_MGT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 		vi->cmd.mgt.scan_generation =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 			rq->func_rsp.mgt_rsp.scan_generation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 		vi->cmd.mgt.dev_index = le16_to_cpu(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 			rq->func_rsp.mgt_rsp.dev_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 		if (vi->data_length == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 			vi->cmd.mgt.data_length =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 				le32_to_cpu(rq->func_rsp.mgt_rsp.length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 		esas2r_nuxi_mgt_data(rq->vrq->mgt.mgt_func, &vi->cmd.mgt.data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	case VDA_FUNC_CFG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 		if (vi->cmd.cfg.cfg_func == VDA_CFG_GET_INIT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 			struct atto_ioctl_vda_cfg_cmd *cfg = &vi->cmd.cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 			struct atto_vda_cfg_rsp *rsp = &rq->func_rsp.cfg_rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 			char buf[sizeof(cfg->data.init.fw_release) + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 			cfg->data_length =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 				cpu_to_le32(sizeof(struct atto_vda_cfg_init));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 			cfg->data.init.vda_version =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 				le32_to_cpu(rsp->vda_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 			cfg->data.init.fw_build = rsp->fw_build;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 			snprintf(buf, sizeof(buf), "%1.1u.%2.2u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 				 (int)LOBYTE(le16_to_cpu(rsp->fw_release)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 				 (int)HIBYTE(le16_to_cpu(rsp->fw_release)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 			memcpy(&cfg->data.init.fw_release, buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 			       sizeof(cfg->data.init.fw_release));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 			if (LOWORD(LOBYTE(cfg->data.init.fw_build)) == 'A')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 				cfg->data.init.fw_version =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 					cfg->data.init.fw_build;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 				cfg->data.init.fw_version =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 					cfg->data.init.fw_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 			esas2r_nuxi_cfg_data(rq->vrq->cfg.sub_func,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 					     &vi->cmd.cfg.data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	case VDA_FUNC_CLI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 		vi->cmd.cli.cmd_rsp_len =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 			le32_to_cpu(rq->func_rsp.cli_rsp.cmd_rsp_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) /* Build a flash VDA request. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) void esas2r_build_flash_req(struct esas2r_adapter *a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 			    struct esas2r_request *rq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 			    u8 sub_func,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 			    u8 cksum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 			    u32 addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 			    u32 length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	struct atto_vda_flash_req *vrq = &rq->vrq->flash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 	clear_vda_request(rq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 	rq->vrq->scsi.function = VDA_FUNC_FLASH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 	if (sub_func == VDA_FLASH_BEGINW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 	    || sub_func == VDA_FLASH_WRITE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 	    || sub_func == VDA_FLASH_READ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 		vrq->sg_list_offset = (u8)offsetof(struct atto_vda_flash_req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 						   data.sge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	vrq->length = cpu_to_le32(length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 	vrq->flash_addr = cpu_to_le32(addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 	vrq->checksum = cksum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 	vrq->sub_func = sub_func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) /* Build a VDA management request. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) void esas2r_build_mgt_req(struct esas2r_adapter *a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 			  struct esas2r_request *rq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 			  u8 sub_func,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 			  u8 scan_gen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 			  u16 dev_index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 			  u32 length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 			  void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 	struct atto_vda_mgmt_req *vrq = &rq->vrq->mgt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 	clear_vda_request(rq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 	rq->vrq->scsi.function = VDA_FUNC_MGT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 	vrq->mgt_func = sub_func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 	vrq->scan_generation = scan_gen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 	vrq->dev_index = cpu_to_le16(dev_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 	vrq->length = cpu_to_le32(length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 	if (vrq->length) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 		if (test_bit(AF_LEGACY_SGE_MODE, &a->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 			vrq->sg_list_offset = (u8)offsetof(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 				struct atto_vda_mgmt_req, sge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 			vrq->sge[0].length = cpu_to_le32(SGE_LAST | length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 			vrq->sge[0].address = cpu_to_le64(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 				rq->vrq_md->phys_addr +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 				sizeof(union atto_vda_req));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 			vrq->sg_list_offset = (u8)offsetof(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 				struct atto_vda_mgmt_req, prde);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 			vrq->prde[0].ctl_len = cpu_to_le32(length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 			vrq->prde[0].address = cpu_to_le64(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 				rq->vrq_md->phys_addr +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 				sizeof(union atto_vda_req));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 	if (data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 		esas2r_nuxi_mgt_data(sub_func, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 		memcpy(&rq->vda_rsp_data->mgt_data.data.bytes[0], data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 		       length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) /* Build a VDA asyncronous event (AE) request. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) void esas2r_build_ae_req(struct esas2r_adapter *a, struct esas2r_request *rq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 	struct atto_vda_ae_req *vrq = &rq->vrq->ae;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 	clear_vda_request(rq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 	rq->vrq->scsi.function = VDA_FUNC_AE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 	vrq->length = cpu_to_le32(sizeof(struct atto_vda_ae_data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 	if (test_bit(AF_LEGACY_SGE_MODE, &a->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 		vrq->sg_list_offset =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 			(u8)offsetof(struct atto_vda_ae_req, sge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 		vrq->sge[0].length = cpu_to_le32(SGE_LAST | vrq->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 		vrq->sge[0].address = cpu_to_le64(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 			rq->vrq_md->phys_addr +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 			sizeof(union atto_vda_req));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 		vrq->sg_list_offset = (u8)offsetof(struct atto_vda_ae_req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 						   prde);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 		vrq->prde[0].ctl_len = cpu_to_le32(vrq->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 		vrq->prde[0].address = cpu_to_le64(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 			rq->vrq_md->phys_addr +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 			sizeof(union atto_vda_req));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) /* Build a VDA CLI request. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) void esas2r_build_cli_req(struct esas2r_adapter *a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 			  struct esas2r_request *rq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 			  u32 length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 			  u32 cmd_rsp_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 	struct atto_vda_cli_req *vrq = &rq->vrq->cli;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 	clear_vda_request(rq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 	rq->vrq->scsi.function = VDA_FUNC_CLI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 	vrq->length = cpu_to_le32(length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 	vrq->cmd_rsp_len = cpu_to_le32(cmd_rsp_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 	vrq->sg_list_offset = (u8)offsetof(struct atto_vda_cli_req, sge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) /* Build a VDA IOCTL request. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) void esas2r_build_ioctl_req(struct esas2r_adapter *a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 			    struct esas2r_request *rq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 			    u32 length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 			    u8 sub_func)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 	struct atto_vda_ioctl_req *vrq = &rq->vrq->ioctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 	clear_vda_request(rq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 	rq->vrq->scsi.function = VDA_FUNC_IOCTL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 	vrq->length = cpu_to_le32(length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 	vrq->sub_func = sub_func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 	vrq->sg_list_offset = (u8)offsetof(struct atto_vda_ioctl_req, sge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) /* Build a VDA configuration request. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) void esas2r_build_cfg_req(struct esas2r_adapter *a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 			  struct esas2r_request *rq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 			  u8 sub_func,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 			  u32 length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 			  void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 	struct atto_vda_cfg_req *vrq = &rq->vrq->cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 	clear_vda_request(rq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 	rq->vrq->scsi.function = VDA_FUNC_CFG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 	vrq->sub_func = sub_func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 	vrq->length = cpu_to_le32(length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 	if (data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 		esas2r_nuxi_cfg_data(sub_func, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 		memcpy(&vrq->data, data, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) static void clear_vda_request(struct esas2r_request *rq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 	u32 handle = rq->vrq->scsi.handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 	memset(rq->vrq, 0, sizeof(*rq->vrq));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 	rq->vrq->scsi.handle = handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 	rq->req_stat = RS_PENDING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 	/* since the data buffer is separate clear that too */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 	memset(rq->data_buf, 0, ESAS2R_DATA_BUF_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 	 * Setup next and prev pointer in case the request is not going through
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 	 * esas2r_start_request().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 	INIT_LIST_HEAD(&rq->req_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) }