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