[go: nahoru, domu]

126780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove/*
226780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove *  linux/drivers/scsi/esas2r/esas2r_vda.c
326780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove *      esas2r driver VDA firmware interface functions
426780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove *
526780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove *  Copyright (c) 2001-2013 ATTO Technology, Inc.
626780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove *  (mailto:linuxdrivers@attotech.com)
726780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove */
826780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
926780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove/*
1026780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove *  This program is free software; you can redistribute it and/or modify
1126780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove *  it under the terms of the GNU General Public License as published by
1226780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove *  the Free Software Foundation; version 2 of the License.
1326780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove *
1426780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove *  This program is distributed in the hope that it will be useful,
1526780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove *  but WITHOUT ANY WARRANTY; without even the implied warranty of
1626780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1726780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove *  GNU General Public License for more details.
1826780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove *
1926780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove *  NO WARRANTY
2026780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove *  THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
2126780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove *  CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
2226780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove *  LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
2326780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove *  MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
2426780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove *  solely responsible for determining the appropriateness of using and
2526780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove *  distributing the Program and assumes all risks associated with its
2626780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove *  exercise of rights under this Agreement, including but not limited to
2726780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove *  the risks and costs of program errors, damage to or loss of data,
2826780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove *  programs or equipment, and unavailability or interruption of operations.
2926780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove *
3026780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove *  DISCLAIMER OF LIABILITY
3126780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove *  NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
3226780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove *  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3326780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove *  DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
3426780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
3526780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
3626780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove *  USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
3726780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove *  HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
3826780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove *
3926780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove *  You should have received a copy of the GNU General Public License
4026780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove *  along with this program; if not, write to the Free Software
4126780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
4226780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove */
4326780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4426780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
4526780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove#include "esas2r.h"
4626780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
4726780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grovestatic u8 esas2r_vdaioctl_versions[] = {
4826780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	ATTO_VDA_VER_UNSUPPORTED,
4926780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	ATTO_VDA_FLASH_VER,
5026780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	ATTO_VDA_VER_UNSUPPORTED,
5126780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	ATTO_VDA_VER_UNSUPPORTED,
5226780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	ATTO_VDA_CLI_VER,
5326780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	ATTO_VDA_VER_UNSUPPORTED,
5426780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	ATTO_VDA_CFG_VER,
5526780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	ATTO_VDA_MGT_VER,
5626780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	ATTO_VDA_GSV_VER
5726780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove};
5826780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
5926780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grovestatic void clear_vda_request(struct esas2r_request *rq);
6026780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
6126780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grovestatic void esas2r_complete_vda_ioctl(struct esas2r_adapter *a,
6226780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove				      struct esas2r_request *rq);
6326780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
6426780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove/* Prepare a VDA IOCTL request to be sent to the firmware. */
6526780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grovebool esas2r_process_vda_ioctl(struct esas2r_adapter *a,
6626780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			      struct atto_ioctl_vda *vi,
6726780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			      struct esas2r_request *rq,
6826780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			      struct esas2r_sg_context *sgc)
6926780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove{
7026780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	u32 datalen = 0;
7126780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	struct atto_vda_sge *firstsg = NULL;
7226780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	u8 vercnt = (u8)ARRAY_SIZE(esas2r_vdaioctl_versions);
7326780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
7426780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	vi->status = ATTO_STS_SUCCESS;
7526780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	vi->vda_status = RS_PENDING;
7626780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
7726780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	if (vi->function >= vercnt) {
7826780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		vi->status = ATTO_STS_INV_FUNC;
7926780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		return false;
8026780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	}
8126780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
8226780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	if (vi->version > esas2r_vdaioctl_versions[vi->function]) {
8326780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		vi->status = ATTO_STS_INV_VERSION;
8426780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		return false;
8526780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	}
8626780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
879588d24e36003b53f76e43b4fadfc5b35207be04Bradley Grove	if (test_bit(AF_DEGRADED_MODE, &a->flags)) {
8826780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		vi->status = ATTO_STS_DEGRADED;
8926780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		return false;
9026780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	}
9126780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
9226780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	if (vi->function != VDA_FUNC_SCSI)
9326780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		clear_vda_request(rq);
9426780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
9526780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	rq->vrq->scsi.function = vi->function;
9626780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	rq->interrupt_cb = esas2r_complete_vda_ioctl;
9726780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	rq->interrupt_cx = vi;
9826780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
9926780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	switch (vi->function) {
10026780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	case VDA_FUNC_FLASH:
10126780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
10226780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		if (vi->cmd.flash.sub_func != VDA_FLASH_FREAD
10326780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		    && vi->cmd.flash.sub_func != VDA_FLASH_FWRITE
10426780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		    && vi->cmd.flash.sub_func != VDA_FLASH_FINFO) {
10526780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			vi->status = ATTO_STS_INV_FUNC;
10626780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			return false;
10726780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		}
10826780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
10926780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		if (vi->cmd.flash.sub_func != VDA_FLASH_FINFO)
11026780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			datalen = vi->data_length;
11126780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
11226780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		rq->vrq->flash.length = cpu_to_le32(datalen);
11326780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		rq->vrq->flash.sub_func = vi->cmd.flash.sub_func;
11426780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
11526780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		memcpy(rq->vrq->flash.data.file.file_name,
11626780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		       vi->cmd.flash.data.file.file_name,
11726780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		       sizeof(vi->cmd.flash.data.file.file_name));
11826780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
11926780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		firstsg = rq->vrq->flash.data.file.sge;
12026780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		break;
12126780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
12226780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	case VDA_FUNC_CLI:
12326780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
12426780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		datalen = vi->data_length;
12526780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
12626780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		rq->vrq->cli.cmd_rsp_len =
12726780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			cpu_to_le32(vi->cmd.cli.cmd_rsp_len);
12826780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		rq->vrq->cli.length = cpu_to_le32(datalen);
12926780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
13026780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		firstsg = rq->vrq->cli.sge;
13126780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		break;
13226780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
13326780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	case VDA_FUNC_MGT:
13426780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	{
13526780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		u8 *cmdcurr_offset = sgc->cur_offset
13626780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove				     - offsetof(struct atto_ioctl_vda, data)
13726780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove				     + offsetof(struct atto_ioctl_vda, cmd)
13826780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove				     + offsetof(struct atto_ioctl_vda_mgt_cmd,
13926780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove						data);
14026780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		/*
14126780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		 * build the data payload SGL here first since
14226780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		 * esas2r_sgc_init() will modify the S/G list offset for the
14326780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		 * management SGL (which is built below where the data SGL is
14426780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		 * usually built).
14526780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		 */
14626780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
14726780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		if (vi->data_length) {
14826780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			u32 payldlen = 0;
14926780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
15026780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			if (vi->cmd.mgt.mgt_func == VDAMGT_DEV_HEALTH_REQ
15126780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			    || vi->cmd.mgt.mgt_func == VDAMGT_DEV_METRICS) {
15226780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove				rq->vrq->mgt.payld_sglst_offset =
15326780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove					(u8)offsetof(struct atto_vda_mgmt_req,
15426780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove						     payld_sge);
15526780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
15626780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove				payldlen = vi->data_length;
15726780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove				datalen = vi->cmd.mgt.data_length;
15826780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			} else if (vi->cmd.mgt.mgt_func == VDAMGT_DEV_INFO2
15926780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove				   || vi->cmd.mgt.mgt_func ==
16026780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove				   VDAMGT_DEV_INFO2_BYADDR) {
16126780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove				datalen = vi->data_length;
16226780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove				cmdcurr_offset = sgc->cur_offset;
16326780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			} else {
16426780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove				vi->status = ATTO_STS_INV_PARAM;
16526780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove				return false;
16626780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			}
16726780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
16826780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			/* Setup the length so building the payload SGL works */
16926780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			rq->vrq->mgt.length = cpu_to_le32(datalen);
17026780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
17126780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			if (payldlen) {
17226780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove				rq->vrq->mgt.payld_length =
17326780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove					cpu_to_le32(payldlen);
17426780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
17526780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove				esas2r_sgc_init(sgc, a, rq,
17626780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove						rq->vrq->mgt.payld_sge);
17726780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove				sgc->length = payldlen;
17826780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
17926780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove				if (!esas2r_build_sg_list(a, rq, sgc)) {
18026780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove					vi->status = ATTO_STS_OUT_OF_RSRC;
18126780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove					return false;
18226780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove				}
18326780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			}
18426780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		} else {
18526780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			datalen = vi->cmd.mgt.data_length;
18626780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
18726780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			rq->vrq->mgt.length = cpu_to_le32(datalen);
18826780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		}
18926780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
19026780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		/*
19126780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		 * Now that the payload SGL is built, if any, setup to build
19226780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		 * the management SGL.
19326780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		 */
19426780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		firstsg = rq->vrq->mgt.sge;
19526780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		sgc->cur_offset = cmdcurr_offset;
19626780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
19726780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		/* Finish initializing the management request. */
19826780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		rq->vrq->mgt.mgt_func = vi->cmd.mgt.mgt_func;
19926780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		rq->vrq->mgt.scan_generation = vi->cmd.mgt.scan_generation;
20026780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		rq->vrq->mgt.dev_index =
20126780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			cpu_to_le32(vi->cmd.mgt.dev_index);
20226780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
20326780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		esas2r_nuxi_mgt_data(rq->vrq->mgt.mgt_func, &vi->cmd.mgt.data);
20426780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		break;
20526780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	}
20626780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
20726780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	case VDA_FUNC_CFG:
20826780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
20926780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		if (vi->data_length
21026780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		    || vi->cmd.cfg.data_length == 0) {
21126780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			vi->status = ATTO_STS_INV_PARAM;
21226780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			return false;
21326780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		}
21426780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
21526780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		if (vi->cmd.cfg.cfg_func == VDA_CFG_INIT) {
21626780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			vi->status = ATTO_STS_INV_FUNC;
21726780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			return false;
21826780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		}
21926780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
22026780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		rq->vrq->cfg.sub_func = vi->cmd.cfg.cfg_func;
22126780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		rq->vrq->cfg.length = cpu_to_le32(vi->cmd.cfg.data_length);
22226780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
22326780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		if (vi->cmd.cfg.cfg_func == VDA_CFG_GET_INIT) {
22426780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			memcpy(&rq->vrq->cfg.data,
22526780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			       &vi->cmd.cfg.data,
22626780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			       vi->cmd.cfg.data_length);
22726780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
22826780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			esas2r_nuxi_cfg_data(rq->vrq->cfg.sub_func,
22926780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove					     &rq->vrq->cfg.data);
23026780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		} else {
23126780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			vi->status = ATTO_STS_INV_FUNC;
23226780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
23326780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			return false;
23426780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		}
23526780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
23626780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		break;
23726780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
23826780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	case VDA_FUNC_GSV:
23926780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
24026780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		vi->cmd.gsv.rsp_len = vercnt;
24126780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
24226780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		memcpy(vi->cmd.gsv.version_info, esas2r_vdaioctl_versions,
24326780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		       vercnt);
24426780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
24526780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		vi->vda_status = RS_SUCCESS;
24626780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		break;
24726780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
24826780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	default:
24926780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
25026780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		vi->status = ATTO_STS_INV_FUNC;
25126780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		return false;
25226780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	}
25326780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
25426780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	if (datalen) {
25526780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		esas2r_sgc_init(sgc, a, rq, firstsg);
25626780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		sgc->length = datalen;
25726780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
25826780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		if (!esas2r_build_sg_list(a, rq, sgc)) {
25926780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			vi->status = ATTO_STS_OUT_OF_RSRC;
26026780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			return false;
26126780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		}
26226780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	}
26326780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
26426780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	esas2r_start_request(a, rq);
26526780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
26626780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	return true;
26726780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove}
26826780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
26926780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grovestatic void esas2r_complete_vda_ioctl(struct esas2r_adapter *a,
27026780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove				      struct esas2r_request *rq)
27126780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove{
27226780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	struct atto_ioctl_vda *vi = (struct atto_ioctl_vda *)rq->interrupt_cx;
27326780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
27426780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	vi->vda_status = rq->req_stat;
27526780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
27626780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	switch (vi->function) {
27726780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	case VDA_FUNC_FLASH:
27826780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
27926780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		if (vi->cmd.flash.sub_func == VDA_FLASH_FINFO
28026780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		    || vi->cmd.flash.sub_func == VDA_FLASH_FREAD)
28126780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			vi->cmd.flash.data.file.file_size =
28226780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove				le32_to_cpu(rq->func_rsp.flash_rsp.file_size);
28326780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
28426780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		break;
28526780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
28626780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	case VDA_FUNC_MGT:
28726780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
28826780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		vi->cmd.mgt.scan_generation =
28926780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			rq->func_rsp.mgt_rsp.scan_generation;
29026780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		vi->cmd.mgt.dev_index = le16_to_cpu(
29126780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			rq->func_rsp.mgt_rsp.dev_index);
29226780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
29326780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		if (vi->data_length == 0)
29426780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			vi->cmd.mgt.data_length =
29526780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove				le32_to_cpu(rq->func_rsp.mgt_rsp.length);
29626780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
29726780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		esas2r_nuxi_mgt_data(rq->vrq->mgt.mgt_func, &vi->cmd.mgt.data);
29826780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		break;
29926780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
30026780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	case VDA_FUNC_CFG:
30126780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
30226780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		if (vi->cmd.cfg.cfg_func == VDA_CFG_GET_INIT) {
30326780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			struct atto_ioctl_vda_cfg_cmd *cfg = &vi->cmd.cfg;
30426780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			struct atto_vda_cfg_rsp *rsp = &rq->func_rsp.cfg_rsp;
305eaf74a06f13aa0e4e7e2024cb6db2ccedd3d32e3Bradley Grove			char buf[sizeof(cfg->data.init.fw_release) + 1];
30626780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
30726780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			cfg->data_length =
30826780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove				cpu_to_le32(sizeof(struct atto_vda_cfg_init));
30926780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			cfg->data.init.vda_version =
31026780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove				le32_to_cpu(rsp->vda_version);
31126780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			cfg->data.init.fw_build = rsp->fw_build;
31226780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
3130f3c7b99f33f7a9c743a752bba2414615c48e270Bradley Grove			snprintf(buf, sizeof(buf), "%1.1u.%2.2u",
3140f3c7b99f33f7a9c743a752bba2414615c48e270Bradley Grove				 (int)LOBYTE(le16_to_cpu(rsp->fw_release)),
3150f3c7b99f33f7a9c743a752bba2414615c48e270Bradley Grove				 (int)HIBYTE(le16_to_cpu(rsp->fw_release)));
31626780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
317eaf74a06f13aa0e4e7e2024cb6db2ccedd3d32e3Bradley Grove			memcpy(&cfg->data.init.fw_release, buf,
318eaf74a06f13aa0e4e7e2024cb6db2ccedd3d32e3Bradley Grove			       sizeof(cfg->data.init.fw_release));
319eaf74a06f13aa0e4e7e2024cb6db2ccedd3d32e3Bradley Grove
32026780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			if (LOWORD(LOBYTE(cfg->data.init.fw_build)) == 'A')
32126780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove				cfg->data.init.fw_version =
32226780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove					cfg->data.init.fw_build;
32326780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			else
32426780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove				cfg->data.init.fw_version =
32526780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove					cfg->data.init.fw_release;
32626780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		} else {
32726780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			esas2r_nuxi_cfg_data(rq->vrq->cfg.sub_func,
32826780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove					     &vi->cmd.cfg.data);
32926780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		}
33026780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
33126780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		break;
33226780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
33326780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	case VDA_FUNC_CLI:
33426780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
33526780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		vi->cmd.cli.cmd_rsp_len =
33626780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			le32_to_cpu(rq->func_rsp.cli_rsp.cmd_rsp_len);
33726780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		break;
33826780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
33926780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	default:
34026780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
34126780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		break;
34226780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	}
34326780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove}
34426780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
34526780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove/* Build a flash VDA request. */
34626780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grovevoid esas2r_build_flash_req(struct esas2r_adapter *a,
34726780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			    struct esas2r_request *rq,
34826780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			    u8 sub_func,
34926780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			    u8 cksum,
35026780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			    u32 addr,
35126780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			    u32 length)
35226780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove{
35326780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	struct atto_vda_flash_req *vrq = &rq->vrq->flash;
35426780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
35526780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	clear_vda_request(rq);
35626780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
35726780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	rq->vrq->scsi.function = VDA_FUNC_FLASH;
35826780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
35926780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	if (sub_func == VDA_FLASH_BEGINW
36026780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	    || sub_func == VDA_FLASH_WRITE
36126780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	    || sub_func == VDA_FLASH_READ)
36226780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		vrq->sg_list_offset = (u8)offsetof(struct atto_vda_flash_req,
36326780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove						   data.sge);
36426780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
36526780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	vrq->length = cpu_to_le32(length);
36626780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	vrq->flash_addr = cpu_to_le32(addr);
36726780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	vrq->checksum = cksum;
36826780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	vrq->sub_func = sub_func;
36926780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove}
37026780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
37126780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove/* Build a VDA management request. */
37226780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grovevoid esas2r_build_mgt_req(struct esas2r_adapter *a,
37326780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			  struct esas2r_request *rq,
37426780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			  u8 sub_func,
37526780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			  u8 scan_gen,
37626780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			  u16 dev_index,
37726780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			  u32 length,
37826780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			  void *data)
37926780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove{
38026780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	struct atto_vda_mgmt_req *vrq = &rq->vrq->mgt;
38126780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
38226780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	clear_vda_request(rq);
38326780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
38426780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	rq->vrq->scsi.function = VDA_FUNC_MGT;
38526780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
38626780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	vrq->mgt_func = sub_func;
38726780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	vrq->scan_generation = scan_gen;
38826780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	vrq->dev_index = cpu_to_le16(dev_index);
38926780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	vrq->length = cpu_to_le32(length);
39026780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
39126780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	if (vrq->length) {
3929588d24e36003b53f76e43b4fadfc5b35207be04Bradley Grove		if (test_bit(AF_LEGACY_SGE_MODE, &a->flags)) {
39326780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			vrq->sg_list_offset = (u8)offsetof(
39426780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove				struct atto_vda_mgmt_req, sge);
39526780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
39626780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			vrq->sge[0].length = cpu_to_le32(SGE_LAST | length);
39726780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			vrq->sge[0].address = cpu_to_le64(
39826780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove				rq->vrq_md->phys_addr +
39926780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove				sizeof(union atto_vda_req));
40026780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		} else {
40126780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			vrq->sg_list_offset = (u8)offsetof(
40226780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove				struct atto_vda_mgmt_req, prde);
40326780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
40426780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			vrq->prde[0].ctl_len = cpu_to_le32(length);
40526780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			vrq->prde[0].address = cpu_to_le64(
40626780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove				rq->vrq_md->phys_addr +
40726780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove				sizeof(union atto_vda_req));
40826780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		}
40926780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	}
41026780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
41126780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	if (data) {
41226780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		esas2r_nuxi_mgt_data(sub_func, data);
41326780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
41426780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		memcpy(&rq->vda_rsp_data->mgt_data.data.bytes[0], data,
41526780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		       length);
41626780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	}
41726780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove}
41826780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
41926780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove/* Build a VDA asyncronous event (AE) request. */
42026780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grovevoid esas2r_build_ae_req(struct esas2r_adapter *a, struct esas2r_request *rq)
42126780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove{
42226780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	struct atto_vda_ae_req *vrq = &rq->vrq->ae;
42326780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
42426780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	clear_vda_request(rq);
42526780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
42626780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	rq->vrq->scsi.function = VDA_FUNC_AE;
42726780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
42826780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	vrq->length = cpu_to_le32(sizeof(struct atto_vda_ae_data));
42926780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
4309588d24e36003b53f76e43b4fadfc5b35207be04Bradley Grove	if (test_bit(AF_LEGACY_SGE_MODE, &a->flags)) {
43126780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		vrq->sg_list_offset =
43226780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			(u8)offsetof(struct atto_vda_ae_req, sge);
43326780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		vrq->sge[0].length = cpu_to_le32(SGE_LAST | vrq->length);
43426780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		vrq->sge[0].address = cpu_to_le64(
43526780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			rq->vrq_md->phys_addr +
43626780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			sizeof(union atto_vda_req));
43726780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	} else {
43826780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		vrq->sg_list_offset = (u8)offsetof(struct atto_vda_ae_req,
43926780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove						   prde);
44026780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		vrq->prde[0].ctl_len = cpu_to_le32(vrq->length);
44126780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		vrq->prde[0].address = cpu_to_le64(
44226780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			rq->vrq_md->phys_addr +
44326780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			sizeof(union atto_vda_req));
44426780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	}
44526780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove}
44626780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
44726780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove/* Build a VDA CLI request. */
44826780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grovevoid esas2r_build_cli_req(struct esas2r_adapter *a,
44926780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			  struct esas2r_request *rq,
45026780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			  u32 length,
45126780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			  u32 cmd_rsp_len)
45226780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove{
45326780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	struct atto_vda_cli_req *vrq = &rq->vrq->cli;
45426780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
45526780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	clear_vda_request(rq);
45626780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
45726780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	rq->vrq->scsi.function = VDA_FUNC_CLI;
45826780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
45926780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	vrq->length = cpu_to_le32(length);
46026780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	vrq->cmd_rsp_len = cpu_to_le32(cmd_rsp_len);
46126780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	vrq->sg_list_offset = (u8)offsetof(struct atto_vda_cli_req, sge);
46226780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove}
46326780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
46426780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove/* Build a VDA IOCTL request. */
46526780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grovevoid esas2r_build_ioctl_req(struct esas2r_adapter *a,
46626780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			    struct esas2r_request *rq,
46726780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			    u32 length,
46826780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			    u8 sub_func)
46926780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove{
47026780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	struct atto_vda_ioctl_req *vrq = &rq->vrq->ioctl;
47126780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
47226780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	clear_vda_request(rq);
47326780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
47426780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	rq->vrq->scsi.function = VDA_FUNC_IOCTL;
47526780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
47626780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	vrq->length = cpu_to_le32(length);
47726780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	vrq->sub_func = sub_func;
47826780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	vrq->sg_list_offset = (u8)offsetof(struct atto_vda_ioctl_req, sge);
47926780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove}
48026780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
48126780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove/* Build a VDA configuration request. */
48226780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grovevoid esas2r_build_cfg_req(struct esas2r_adapter *a,
48326780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			  struct esas2r_request *rq,
48426780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			  u8 sub_func,
48526780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			  u32 length,
48626780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove			  void *data)
48726780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove{
48826780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	struct atto_vda_cfg_req *vrq = &rq->vrq->cfg;
48926780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
49026780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	clear_vda_request(rq);
49126780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
49226780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	rq->vrq->scsi.function = VDA_FUNC_CFG;
49326780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
49426780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	vrq->sub_func = sub_func;
49526780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	vrq->length = cpu_to_le32(length);
49626780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
49726780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	if (data) {
49826780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		esas2r_nuxi_cfg_data(sub_func, data);
49926780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
50026780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove		memcpy(&vrq->data, data, length);
50126780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	}
50226780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove}
50326780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
50426780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grovestatic void clear_vda_request(struct esas2r_request *rq)
50526780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove{
50626780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	u32 handle = rq->vrq->scsi.handle;
50726780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
50826780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	memset(rq->vrq, 0, sizeof(*rq->vrq));
50926780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
51026780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	rq->vrq->scsi.handle = handle;
51126780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
51226780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	rq->req_stat = RS_PENDING;
51326780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
51426780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	/* since the data buffer is separate clear that too */
51526780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
51626780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	memset(rq->data_buf, 0, ESAS2R_DATA_BUF_LEN);
51726780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
51826780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	/*
51926780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	 * Setup next and prev pointer in case the request is not going through
52026780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	 * esas2r_start_request().
52126780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	 */
52226780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove
52326780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove	INIT_LIST_HEAD(&rq->req_list);
52426780d9e12edf45c0b98315de272b1feff5a8e93Bradley Grove}
525