^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) }