brintos

brintos / linux-shallow public Read only

0
0
Text · 86.0 KiB · 2e88f45 Raw
2795 lines · c
1/*2 * This module provides common API for accessing firmware configuration pages3 *4 * This code is based on drivers/scsi/mpt3sas/mpt3sas_base.c5 * Copyright (C) 2012-2014  LSI Corporation6 * Copyright (C) 2013-2014 Avago Technologies7 *  (mailto: MPT-FusionLinux.pdl@avagotech.com)8 *9 * This program is free software; you can redistribute it and/or10 * modify it under the terms of the GNU General Public License11 * as published by the Free Software Foundation; either version 212 * of the License, or (at your option) any later version.13 *14 * This program is distributed in the hope that it will be useful,15 * but WITHOUT ANY WARRANTY; without even the implied warranty of16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the17 * GNU General Public License for more details.18 *19 * NO WARRANTY20 * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR21 * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT22 * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,23 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is24 * solely responsible for determining the appropriateness of using and25 * distributing the Program and assumes all risks associated with its26 * exercise of rights under this Agreement, including but not limited to27 * the risks and costs of program errors, damage to or loss of data,28 * programs or equipment, and unavailability or interruption of operations.29 30 * DISCLAIMER OF LIABILITY31 * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY32 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL33 * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND34 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR35 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE36 * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED37 * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES38 39 * You should have received a copy of the GNU General Public License40 * along with this program; if not, write to the Free Software41 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,42 * USA.43 */44 45#include <linux/module.h>46#include <linux/kernel.h>47#include <linux/init.h>48#include <linux/errno.h>49#include <linux/blkdev.h>50#include <linux/sched.h>51#include <linux/workqueue.h>52#include <linux/delay.h>53#include <linux/pci.h>54 55#include "mpt3sas_base.h"56 57/* local definitions */58 59/* Timeout for config page request (in seconds) */60#define MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT 1561 62/* Common sgl flags for READING a config page. */63#define MPT3_CONFIG_COMMON_SGLFLAGS ((MPI2_SGE_FLAGS_SIMPLE_ELEMENT | \64	MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER \65	| MPI2_SGE_FLAGS_END_OF_LIST) << MPI2_SGE_FLAGS_SHIFT)66 67/* Common sgl flags for WRITING a config page. */68#define MPT3_CONFIG_COMMON_WRITE_SGLFLAGS ((MPI2_SGE_FLAGS_SIMPLE_ELEMENT | \69	MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER \70	| MPI2_SGE_FLAGS_END_OF_LIST | MPI2_SGE_FLAGS_HOST_TO_IOC) \71	<< MPI2_SGE_FLAGS_SHIFT)72 73/**74 * struct config_request - obtain dma memory via routine75 * @sz: size76 * @page: virt pointer77 * @page_dma: phys pointer78 *79 */80struct config_request {81	u16			sz;82	void			*page;83	dma_addr_t		page_dma;84};85 86/**87 * _config_display_some_debug - debug routine88 * @ioc: per adapter object89 * @smid: system request message index90 * @calling_function_name: string pass from calling function91 * @mpi_reply: reply message frame92 * Context: none.93 *94 * Function for displaying debug info helpful when debugging issues95 * in this module.96 */97static void98_config_display_some_debug(struct MPT3SAS_ADAPTER *ioc, u16 smid,99	char *calling_function_name, MPI2DefaultReply_t *mpi_reply)100{101	Mpi2ConfigRequest_t *mpi_request;102	char *desc = NULL;103 104	mpi_request = mpt3sas_base_get_msg_frame(ioc, smid);105	switch (mpi_request->Header.PageType & MPI2_CONFIG_PAGETYPE_MASK) {106	case MPI2_CONFIG_PAGETYPE_IO_UNIT:107		desc = "io_unit";108		break;109	case MPI2_CONFIG_PAGETYPE_IOC:110		desc = "ioc";111		break;112	case MPI2_CONFIG_PAGETYPE_BIOS:113		desc = "bios";114		break;115	case MPI2_CONFIG_PAGETYPE_RAID_VOLUME:116		desc = "raid_volume";117		break;118	case MPI2_CONFIG_PAGETYPE_MANUFACTURING:119		desc = "manufacturing";120		break;121	case MPI2_CONFIG_PAGETYPE_RAID_PHYSDISK:122		desc = "physdisk";123		break;124	case MPI2_CONFIG_PAGETYPE_EXTENDED:125		switch (mpi_request->ExtPageType) {126		case MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT:127			desc = "sas_io_unit";128			break;129		case MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER:130			desc = "sas_expander";131			break;132		case MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE:133			desc = "sas_device";134			break;135		case MPI2_CONFIG_EXTPAGETYPE_SAS_PHY:136			desc = "sas_phy";137			break;138		case MPI2_CONFIG_EXTPAGETYPE_LOG:139			desc = "log";140			break;141		case MPI2_CONFIG_EXTPAGETYPE_ENCLOSURE:142			desc = "enclosure";143			break;144		case MPI2_CONFIG_EXTPAGETYPE_RAID_CONFIG:145			desc = "raid_config";146			break;147		case MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING:148			desc = "driver_mapping";149			break;150		case MPI2_CONFIG_EXTPAGETYPE_SAS_PORT:151			desc = "sas_port";152			break;153		case MPI2_CONFIG_EXTPAGETYPE_EXT_MANUFACTURING:154			desc = "ext_manufacturing";155			break;156		case MPI2_CONFIG_EXTPAGETYPE_PCIE_IO_UNIT:157			desc = "pcie_io_unit";158			break;159		case MPI2_CONFIG_EXTPAGETYPE_PCIE_SWITCH:160			desc = "pcie_switch";161			break;162		case MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE:163			desc = "pcie_device";164			break;165		case MPI2_CONFIG_EXTPAGETYPE_PCIE_LINK:166			desc = "pcie_link";167			break;168		}169		break;170	}171 172	if (!desc)173		return;174 175	ioc_info(ioc, "%s: %s(%d), action(%d), form(0x%08x), smid(%d)\n",176		 calling_function_name, desc,177		 mpi_request->Header.PageNumber, mpi_request->Action,178		 le32_to_cpu(mpi_request->PageAddress), smid);179 180	if (!mpi_reply)181		return;182 183	if (mpi_reply->IOCStatus || mpi_reply->IOCLogInfo)184		ioc_info(ioc, "\tiocstatus(0x%04x), loginfo(0x%08x)\n",185			 le16_to_cpu(mpi_reply->IOCStatus),186			 le32_to_cpu(mpi_reply->IOCLogInfo));187}188 189/**190 * _config_alloc_config_dma_memory - obtain physical memory191 * @ioc: per adapter object192 * @mem: struct config_request193 *194 * A wrapper for obtaining dma-able memory for config page request.195 *196 * Return: 0 for success, non-zero for failure.197 */198static int199_config_alloc_config_dma_memory(struct MPT3SAS_ADAPTER *ioc,200	struct config_request *mem)201{202	int r = 0;203 204	if (mem->sz > ioc->config_page_sz) {205		mem->page = dma_alloc_coherent(&ioc->pdev->dev, mem->sz,206		    &mem->page_dma, GFP_KERNEL);207		if (!mem->page) {208			ioc_err(ioc, "%s: dma_alloc_coherent failed asking for (%d) bytes!!\n",209				__func__, mem->sz);210			r = -ENOMEM;211		}212	} else { /* use tmp buffer if less than 512 bytes */213		mem->page = ioc->config_page;214		mem->page_dma = ioc->config_page_dma;215	}216	ioc->config_vaddr = mem->page;217	return r;218}219 220/**221 * _config_free_config_dma_memory - wrapper to free the memory222 * @ioc: per adapter object223 * @mem: struct config_request224 *225 * A wrapper to free dma-able memory when using _config_alloc_config_dma_memory.226 *227 * Return: 0 for success, non-zero for failure.228 */229static void230_config_free_config_dma_memory(struct MPT3SAS_ADAPTER *ioc,231	struct config_request *mem)232{233	if (mem->sz > ioc->config_page_sz)234		dma_free_coherent(&ioc->pdev->dev, mem->sz, mem->page,235		    mem->page_dma);236}237 238/**239 * mpt3sas_config_done - config page completion routine240 * @ioc: per adapter object241 * @smid: system request message index242 * @msix_index: MSIX table index supplied by the OS243 * @reply: reply message frame(lower 32bit addr)244 * Context: none.245 *246 * The callback handler when using _config_request.247 *248 * Return: 1 meaning mf should be freed from _base_interrupt249 *         0 means the mf is freed from this function.250 */251u8252mpt3sas_config_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index,253	u32 reply)254{255	MPI2DefaultReply_t *mpi_reply;256 257	if (ioc->config_cmds.status == MPT3_CMD_NOT_USED)258		return 1;259	if (ioc->config_cmds.smid != smid)260		return 1;261	ioc->config_cmds.status |= MPT3_CMD_COMPLETE;262	mpi_reply =  mpt3sas_base_get_reply_virt_addr(ioc, reply);263	if (mpi_reply) {264		ioc->config_cmds.status |= MPT3_CMD_REPLY_VALID;265		memcpy(ioc->config_cmds.reply, mpi_reply,266		    mpi_reply->MsgLength*4);267	}268	ioc->config_cmds.status &= ~MPT3_CMD_PENDING;269	if (ioc->logging_level & MPT_DEBUG_CONFIG)270		_config_display_some_debug(ioc, smid, "config_done", mpi_reply);271	ioc->config_cmds.smid = USHRT_MAX;272	complete(&ioc->config_cmds.done);273	return 1;274}275 276/**277 * _config_request - main routine for sending config page requests278 * @ioc: per adapter object279 * @mpi_request: request message frame280 * @mpi_reply: reply mf payload returned from firmware281 * @timeout: timeout in seconds282 * @config_page: contents of the config page283 * @config_page_sz: size of config page284 * Context: sleep285 *286 * A generic API for config page requests to firmware.287 *288 * The ioc->config_cmds.status flag should be MPT3_CMD_NOT_USED before calling289 * this API.290 *291 * The callback index is set inside `ioc->config_cb_idx.292 *293 * Return: 0 for success, non-zero for failure.294 */295static int296_config_request(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigRequest_t297	*mpi_request, Mpi2ConfigReply_t *mpi_reply, int timeout,298	void *config_page, u16 config_page_sz)299{300	u16 smid;301	Mpi2ConfigRequest_t *config_request;302	int r;303	u8 retry_count, issue_host_reset = 0;304	struct config_request mem;305	u32 ioc_status = UINT_MAX;306 307	mutex_lock(&ioc->config_cmds.mutex);308	if (ioc->config_cmds.status != MPT3_CMD_NOT_USED) {309		ioc_err(ioc, "%s: config_cmd in use\n", __func__);310		mutex_unlock(&ioc->config_cmds.mutex);311		return -EAGAIN;312	}313 314	retry_count = 0;315	memset(&mem, 0, sizeof(struct config_request));316 317	mpi_request->VF_ID = 0; /* TODO */318	mpi_request->VP_ID = 0;319 320	if (config_page) {321		mpi_request->Header.PageVersion = mpi_reply->Header.PageVersion;322		mpi_request->Header.PageNumber = mpi_reply->Header.PageNumber;323		mpi_request->Header.PageType = mpi_reply->Header.PageType;324		mpi_request->Header.PageLength = mpi_reply->Header.PageLength;325		mpi_request->ExtPageLength = mpi_reply->ExtPageLength;326		mpi_request->ExtPageType = mpi_reply->ExtPageType;327		if (mpi_request->Header.PageLength)328			mem.sz = mpi_request->Header.PageLength * 4;329		else330			mem.sz = le16_to_cpu(mpi_reply->ExtPageLength) * 4;331		r = _config_alloc_config_dma_memory(ioc, &mem);332		if (r != 0)333			goto out;334		if (mpi_request->Action ==335		    MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT ||336		    mpi_request->Action ==337		    MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM) {338			ioc->base_add_sg_single(&mpi_request->PageBufferSGE,339			    MPT3_CONFIG_COMMON_WRITE_SGLFLAGS | mem.sz,340			    mem.page_dma);341			memcpy(mem.page, config_page, min_t(u16, mem.sz,342			    config_page_sz));343		} else {344			memset(config_page, 0, config_page_sz);345			ioc->base_add_sg_single(&mpi_request->PageBufferSGE,346			    MPT3_CONFIG_COMMON_SGLFLAGS | mem.sz, mem.page_dma);347			memset(mem.page, 0, min_t(u16, mem.sz, config_page_sz));348		}349	}350 351 retry_config:352	if (retry_count) {353		if (retry_count > 2) { /* attempt only 2 retries */354			r = -EFAULT;355			goto free_mem;356		}357		ioc_info(ioc, "%s: attempting retry (%d)\n",358			 __func__, retry_count);359	}360 361	r = mpt3sas_wait_for_ioc(ioc, MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT);362	if (r) {363		if (r == -ETIME)364			issue_host_reset = 1;365		goto free_mem;366	}367 368	smid = mpt3sas_base_get_smid(ioc, ioc->config_cb_idx);369	if (!smid) {370		ioc_err(ioc, "%s: failed obtaining a smid\n", __func__);371		ioc->config_cmds.status = MPT3_CMD_NOT_USED;372		r = -EAGAIN;373		goto free_mem;374	}375 376	r = 0;377	memset(ioc->config_cmds.reply, 0, sizeof(Mpi2ConfigReply_t));378	ioc->config_cmds.status = MPT3_CMD_PENDING;379	config_request = mpt3sas_base_get_msg_frame(ioc, smid);380	ioc->config_cmds.smid = smid;381	memcpy(config_request, mpi_request, sizeof(Mpi2ConfigRequest_t));382	if (ioc->logging_level & MPT_DEBUG_CONFIG)383		_config_display_some_debug(ioc, smid, "config_request", NULL);384	init_completion(&ioc->config_cmds.done);385	ioc->put_smid_default(ioc, smid);386	wait_for_completion_timeout(&ioc->config_cmds.done, timeout*HZ);387	if (!(ioc->config_cmds.status & MPT3_CMD_COMPLETE)) {388		if (!(ioc->logging_level & MPT_DEBUG_CONFIG))389			_config_display_some_debug(ioc,390			    smid, "config_request", NULL);391		ioc_err(ioc, "%s: command timeout\n", __func__);392		mpt3sas_base_check_cmd_timeout(ioc, ioc->config_cmds.status,393				mpi_request, sizeof(Mpi2ConfigRequest_t) / 4);394		retry_count++;395		if (ioc->config_cmds.smid == smid)396			mpt3sas_base_free_smid(ioc, smid);397		if (ioc->config_cmds.status & MPT3_CMD_RESET)398			goto retry_config;399		if (ioc->shost_recovery || ioc->pci_error_recovery) {400			issue_host_reset = 0;401			r = -EFAULT;402		} else403			issue_host_reset = 1;404		goto free_mem;405	}406 407	if (ioc->config_cmds.status & MPT3_CMD_REPLY_VALID) {408		memcpy(mpi_reply, ioc->config_cmds.reply,409		    sizeof(Mpi2ConfigReply_t));410 411		/* Reply Frame Sanity Checks to workaround FW issues */412		if ((mpi_request->Header.PageType & 0xF) !=413		    (mpi_reply->Header.PageType & 0xF)) {414			if (!(ioc->logging_level & MPT_DEBUG_CONFIG))415				_config_display_some_debug(ioc,416				    smid, "config_request", NULL);417			_debug_dump_mf(mpi_request, ioc->request_sz/4);418			_debug_dump_reply(mpi_reply, ioc->reply_sz/4);419			panic("%s: %s: Firmware BUG: mpi_reply mismatch: Requested PageType(0x%02x) Reply PageType(0x%02x)\n",420			      ioc->name, __func__,421			      mpi_request->Header.PageType & 0xF,422			      mpi_reply->Header.PageType & 0xF);423		}424 425		if (((mpi_request->Header.PageType & 0xF) ==426		    MPI2_CONFIG_PAGETYPE_EXTENDED) &&427		    mpi_request->ExtPageType != mpi_reply->ExtPageType) {428			if (!(ioc->logging_level & MPT_DEBUG_CONFIG))429				_config_display_some_debug(ioc,430				    smid, "config_request", NULL);431			_debug_dump_mf(mpi_request, ioc->request_sz/4);432			_debug_dump_reply(mpi_reply, ioc->reply_sz/4);433			panic("%s: %s: Firmware BUG: mpi_reply mismatch: Requested ExtPageType(0x%02x) Reply ExtPageType(0x%02x)\n",434			      ioc->name, __func__,435			      mpi_request->ExtPageType,436			      mpi_reply->ExtPageType);437		}438		ioc_status = le16_to_cpu(mpi_reply->IOCStatus)439		    & MPI2_IOCSTATUS_MASK;440	}441 442	if (retry_count)443		ioc_info(ioc, "%s: retry (%d) completed!!\n",444			 __func__, retry_count);445 446	if ((ioc_status == MPI2_IOCSTATUS_SUCCESS) &&447	    config_page && mpi_request->Action ==448	    MPI2_CONFIG_ACTION_PAGE_READ_CURRENT) {449		u8 *p = (u8 *)mem.page;450 451		/* Config Page Sanity Checks to workaround FW issues */452		if (p) {453			if ((mpi_request->Header.PageType & 0xF) !=454			    (p[3] & 0xF)) {455				if (!(ioc->logging_level & MPT_DEBUG_CONFIG))456					_config_display_some_debug(ioc,457					    smid, "config_request", NULL);458				_debug_dump_mf(mpi_request, ioc->request_sz/4);459				_debug_dump_reply(mpi_reply, ioc->reply_sz/4);460				_debug_dump_config(p, min_t(u16, mem.sz,461				    config_page_sz)/4);462				panic("%s: %s: Firmware BUG: config page mismatch: Requested PageType(0x%02x) Reply PageType(0x%02x)\n",463				      ioc->name, __func__,464				      mpi_request->Header.PageType & 0xF,465				      p[3] & 0xF);466			}467 468			if (((mpi_request->Header.PageType & 0xF) ==469			    MPI2_CONFIG_PAGETYPE_EXTENDED) &&470			    (mpi_request->ExtPageType != p[6])) {471				if (!(ioc->logging_level & MPT_DEBUG_CONFIG))472					_config_display_some_debug(ioc,473					    smid, "config_request", NULL);474				_debug_dump_mf(mpi_request, ioc->request_sz/4);475				_debug_dump_reply(mpi_reply, ioc->reply_sz/4);476				_debug_dump_config(p, min_t(u16, mem.sz,477				    config_page_sz)/4);478				panic("%s: %s: Firmware BUG: config page mismatch: Requested ExtPageType(0x%02x) Reply ExtPageType(0x%02x)\n",479				      ioc->name, __func__,480				      mpi_request->ExtPageType, p[6]);481			}482		}483		memcpy(config_page, mem.page, min_t(u16, mem.sz,484		    config_page_sz));485	}486 487 free_mem:488	if (config_page)489		_config_free_config_dma_memory(ioc, &mem);490 out:491	ioc->config_cmds.status = MPT3_CMD_NOT_USED;492	mutex_unlock(&ioc->config_cmds.mutex);493 494	if (issue_host_reset) {495		if (ioc->drv_internal_flags & MPT_DRV_INTERNAL_FIRST_PE_ISSUED) {496			mpt3sas_base_hard_reset_handler(ioc, FORCE_BIG_HAMMER);497			r = -EFAULT;498		} else {499			if (mpt3sas_base_check_for_fault_and_issue_reset(ioc))500				return -EFAULT;501			r = -EAGAIN;502		}503	}504	return r;505}506 507/**508 * mpt3sas_config_get_manufacturing_pg0 - obtain manufacturing page 0509 * @ioc: per adapter object510 * @mpi_reply: reply mf payload returned from firmware511 * @config_page: contents of the config page512 * Context: sleep.513 *514 * Return: 0 for success, non-zero for failure.515 */516int517mpt3sas_config_get_manufacturing_pg0(struct MPT3SAS_ADAPTER *ioc,518	Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage0_t *config_page)519{520	Mpi2ConfigRequest_t mpi_request;521	int r;522 523	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));524	mpi_request.Function = MPI2_FUNCTION_CONFIG;525	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;526	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;527	mpi_request.Header.PageNumber = 0;528	mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION;529	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);530	r = _config_request(ioc, &mpi_request, mpi_reply,531	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);532	if (r)533		goto out;534 535	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;536	r = _config_request(ioc, &mpi_request, mpi_reply,537	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,538	    sizeof(*config_page));539 out:540	return r;541}542 543/**544 * mpt3sas_config_get_manufacturing_pg1 - obtain manufacturing page 1545 * @ioc: per adapter object546 * @mpi_reply: reply mf payload returned from firmware547 * @config_page: contents of the config page548 * Context: sleep.549 *550 * Return: 0 for success, non-zero for failure.551 */552int553mpt3sas_config_get_manufacturing_pg1(struct MPT3SAS_ADAPTER *ioc,554	Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage1_t *config_page)555{556	Mpi2ConfigRequest_t mpi_request;557	int r;558 559	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));560	mpi_request.Function = MPI2_FUNCTION_CONFIG;561	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;562	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;563	mpi_request.Header.PageNumber = 1;564	mpi_request.Header.PageVersion = MPI2_MANUFACTURING1_PAGEVERSION;565	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);566	r = _config_request(ioc, &mpi_request, mpi_reply,567		MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);568	if (r)569		goto out;570 571	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;572	r = _config_request(ioc, &mpi_request, mpi_reply,573		MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,574		sizeof(*config_page));575 out:576	return r;577}578 579/**580 * mpt3sas_config_get_manufacturing_pg7 - obtain manufacturing page 7581 * @ioc: per adapter object582 * @mpi_reply: reply mf payload returned from firmware583 * @config_page: contents of the config page584 * @sz: size of buffer passed in config_page585 * Context: sleep.586 *587 * Return: 0 for success, non-zero for failure.588 */589int590mpt3sas_config_get_manufacturing_pg7(struct MPT3SAS_ADAPTER *ioc,591	Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage7_t *config_page,592	u16 sz)593{594	Mpi2ConfigRequest_t mpi_request;595	int r;596 597	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));598	mpi_request.Function = MPI2_FUNCTION_CONFIG;599	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;600	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;601	mpi_request.Header.PageNumber = 7;602	mpi_request.Header.PageVersion = MPI2_MANUFACTURING7_PAGEVERSION;603	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);604	r = _config_request(ioc, &mpi_request, mpi_reply,605	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);606	if (r)607		goto out;608 609	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;610	r = _config_request(ioc, &mpi_request, mpi_reply,611	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,612	    sz);613 out:614	return r;615}616 617/**618 * mpt3sas_config_get_manufacturing_pg10 - obtain manufacturing page 10619 * @ioc: per adapter object620 * @mpi_reply: reply mf payload returned from firmware621 * @config_page: contents of the config page622 * Context: sleep.623 *624 * Return: 0 for success, non-zero for failure.625 */626int627mpt3sas_config_get_manufacturing_pg10(struct MPT3SAS_ADAPTER *ioc,628	Mpi2ConfigReply_t *mpi_reply,629	struct Mpi2ManufacturingPage10_t *config_page)630{631	Mpi2ConfigRequest_t mpi_request;632	int r;633 634	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));635	mpi_request.Function = MPI2_FUNCTION_CONFIG;636	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;637	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;638	mpi_request.Header.PageNumber = 10;639	mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION;640	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);641	r = _config_request(ioc, &mpi_request, mpi_reply,642	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);643	if (r)644		goto out;645 646	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;647	r = _config_request(ioc, &mpi_request, mpi_reply,648	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,649	    sizeof(*config_page));650 out:651	return r;652}653 654/**655 * mpt3sas_config_get_manufacturing_pg11 - obtain manufacturing page 11656 * @ioc: per adapter object657 * @mpi_reply: reply mf payload returned from firmware658 * @config_page: contents of the config page659 * Context: sleep.660 *661 * Return: 0 for success, non-zero for failure.662 */663int664mpt3sas_config_get_manufacturing_pg11(struct MPT3SAS_ADAPTER *ioc,665	Mpi2ConfigReply_t *mpi_reply,666	struct Mpi2ManufacturingPage11_t *config_page)667{668	Mpi2ConfigRequest_t mpi_request;669	int r;670 671	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));672	mpi_request.Function = MPI2_FUNCTION_CONFIG;673	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;674	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;675	mpi_request.Header.PageNumber = 11;676	mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION;677	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);678	r = _config_request(ioc, &mpi_request, mpi_reply,679	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);680	if (r)681		goto out;682 683	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;684	r = _config_request(ioc, &mpi_request, mpi_reply,685	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,686	    sizeof(*config_page));687 out:688	return r;689}690 691/**692 * mpt3sas_config_set_manufacturing_pg11 - set manufacturing page 11693 * @ioc: per adapter object694 * @mpi_reply: reply mf payload returned from firmware695 * @config_page: contents of the config page696 * Context: sleep.697 *698 * Return: 0 for success, non-zero for failure.699 */700int701mpt3sas_config_set_manufacturing_pg11(struct MPT3SAS_ADAPTER *ioc,702	Mpi2ConfigReply_t *mpi_reply,703	struct Mpi2ManufacturingPage11_t *config_page)704{705	Mpi2ConfigRequest_t mpi_request;706	int r;707 708	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));709	mpi_request.Function = MPI2_FUNCTION_CONFIG;710	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;711	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;712	mpi_request.Header.PageNumber = 11;713	mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION;714	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);715	r = _config_request(ioc, &mpi_request, mpi_reply,716	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);717	if (r)718		goto out;719 720	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;721	r = _config_request(ioc, &mpi_request, mpi_reply,722	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,723	    sizeof(*config_page));724 out:725	return r;726}727 728/**729 * mpt3sas_config_get_bios_pg2 - obtain bios page 2730 * @ioc: per adapter object731 * @mpi_reply: reply mf payload returned from firmware732 * @config_page: contents of the config page733 * Context: sleep.734 *735 * Return: 0 for success, non-zero for failure.736 */737int738mpt3sas_config_get_bios_pg2(struct MPT3SAS_ADAPTER *ioc,739	Mpi2ConfigReply_t *mpi_reply, Mpi2BiosPage2_t *config_page)740{741	Mpi2ConfigRequest_t mpi_request;742	int r;743 744	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));745	mpi_request.Function = MPI2_FUNCTION_CONFIG;746	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;747	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS;748	mpi_request.Header.PageNumber = 2;749	mpi_request.Header.PageVersion = MPI2_BIOSPAGE2_PAGEVERSION;750	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);751	r = _config_request(ioc, &mpi_request, mpi_reply,752	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);753	if (r)754		goto out;755 756	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;757	r = _config_request(ioc, &mpi_request, mpi_reply,758	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,759	    sizeof(*config_page));760 out:761	return r;762}763 764/**765 * mpt3sas_config_get_bios_pg3 - obtain bios page 3766 * @ioc: per adapter object767 * @mpi_reply: reply mf payload returned from firmware768 * @config_page: contents of the config page769 * Context: sleep.770 *771 * Return: 0 for success, non-zero for failure.772 */773int774mpt3sas_config_get_bios_pg3(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t775	*mpi_reply, Mpi2BiosPage3_t *config_page)776{777	Mpi2ConfigRequest_t mpi_request;778	int r;779 780	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));781	mpi_request.Function = MPI2_FUNCTION_CONFIG;782	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;783	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS;784	mpi_request.Header.PageNumber = 3;785	mpi_request.Header.PageVersion = MPI2_BIOSPAGE3_PAGEVERSION;786	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);787	r = _config_request(ioc, &mpi_request, mpi_reply,788	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);789	if (r)790		goto out;791 792	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;793	r = _config_request(ioc, &mpi_request, mpi_reply,794	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,795	    sizeof(*config_page));796 797 out:798	return r;799}800 801/**802 * mpt3sas_config_set_bios_pg4 - write out bios page 4803 * @ioc: per adapter object804 * @mpi_reply: reply mf payload returned from firmware805 * @config_page: contents of the config page806 * @sz_config_pg: sizeof the config page807 * Context: sleep.808 *809 * Return: 0 for success, non-zero for failure.810 */811int812mpt3sas_config_set_bios_pg4(struct MPT3SAS_ADAPTER *ioc,813	Mpi2ConfigReply_t *mpi_reply, Mpi2BiosPage4_t *config_page,814	int sz_config_pg)815{816	Mpi2ConfigRequest_t mpi_request;817	int r;818 819	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));820 821	mpi_request.Function = MPI2_FUNCTION_CONFIG;822	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;823	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS;824	mpi_request.Header.PageNumber = 4;825	mpi_request.Header.PageVersion = MPI2_BIOSPAGE4_PAGEVERSION;826 827	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);828 829	r = _config_request(ioc, &mpi_request, mpi_reply,830		MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);831	if (r)832		goto out;833 834	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;835	r = _config_request(ioc, &mpi_request, mpi_reply,836		MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,837		sz_config_pg);838 out:839	return r;840}841 842/**843 * mpt3sas_config_get_bios_pg4 - read bios page 4844 * @ioc: per adapter object845 * @mpi_reply: reply mf payload returned from firmware846 * @config_page: contents of the config page847 * @sz_config_pg: sizeof the config page848 * Context: sleep.849 *850 * Return: 0 for success, non-zero for failure.851 */852int853mpt3sas_config_get_bios_pg4(struct MPT3SAS_ADAPTER *ioc,854	Mpi2ConfigReply_t *mpi_reply, Mpi2BiosPage4_t *config_page,855	int sz_config_pg)856{857	Mpi2ConfigRequest_t mpi_request;858	int r;859 860	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));861	mpi_request.Function = MPI2_FUNCTION_CONFIG;862	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;863	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS;864	mpi_request.Header.PageNumber = 4;865	mpi_request.Header.PageVersion =  MPI2_BIOSPAGE4_PAGEVERSION;866	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);867	r = _config_request(ioc, &mpi_request, mpi_reply,868		MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);869	if (r)870		goto out;871 872	/*873	 * The sizeof the page is variable. Allow for just the874	 * size to be returned875	 */876	if (config_page && sz_config_pg) {877		mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;878 879		r = _config_request(ioc, &mpi_request, mpi_reply,880			MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,881			sz_config_pg);882	}883 884out:885	return r;886}887 888/**889 * mpt3sas_config_get_iounit_pg0 - obtain iounit page 0890 * @ioc: per adapter object891 * @mpi_reply: reply mf payload returned from firmware892 * @config_page: contents of the config page893 * Context: sleep.894 *895 * Return: 0 for success, non-zero for failure.896 */897int898mpt3sas_config_get_iounit_pg0(struct MPT3SAS_ADAPTER *ioc,899	Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage0_t *config_page)900{901	Mpi2ConfigRequest_t mpi_request;902	int r;903 904	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));905	mpi_request.Function = MPI2_FUNCTION_CONFIG;906	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;907	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;908	mpi_request.Header.PageNumber = 0;909	mpi_request.Header.PageVersion = MPI2_IOUNITPAGE0_PAGEVERSION;910	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);911	r = _config_request(ioc, &mpi_request, mpi_reply,912	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);913	if (r)914		goto out;915 916	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;917	r = _config_request(ioc, &mpi_request, mpi_reply,918	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,919	    sizeof(*config_page));920 out:921	return r;922}923 924/**925 * mpt3sas_config_get_iounit_pg1 - obtain iounit page 1926 * @ioc: per adapter object927 * @mpi_reply: reply mf payload returned from firmware928 * @config_page: contents of the config page929 * Context: sleep.930 *931 * Return: 0 for success, non-zero for failure.932 */933int934mpt3sas_config_get_iounit_pg1(struct MPT3SAS_ADAPTER *ioc,935	Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage1_t *config_page)936{937	Mpi2ConfigRequest_t mpi_request;938	int r;939 940	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));941	mpi_request.Function = MPI2_FUNCTION_CONFIG;942	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;943	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;944	mpi_request.Header.PageNumber = 1;945	mpi_request.Header.PageVersion = MPI2_IOUNITPAGE1_PAGEVERSION;946	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);947	r = _config_request(ioc, &mpi_request, mpi_reply,948	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);949	if (r)950		goto out;951 952	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;953	r = _config_request(ioc, &mpi_request, mpi_reply,954	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,955	    sizeof(*config_page));956 out:957	return r;958}959 960/**961 * mpt3sas_config_set_iounit_pg1 - set iounit page 1962 * @ioc: per adapter object963 * @mpi_reply: reply mf payload returned from firmware964 * @config_page: contents of the config page965 * Context: sleep.966 *967 * Return: 0 for success, non-zero for failure.968 */969int970mpt3sas_config_set_iounit_pg1(struct MPT3SAS_ADAPTER *ioc,971	Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage1_t *config_page)972{973	Mpi2ConfigRequest_t mpi_request;974	int r;975 976	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));977	mpi_request.Function = MPI2_FUNCTION_CONFIG;978	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;979	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;980	mpi_request.Header.PageNumber = 1;981	mpi_request.Header.PageVersion = MPI2_IOUNITPAGE1_PAGEVERSION;982	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);983	r = _config_request(ioc, &mpi_request, mpi_reply,984	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);985	if (r)986		goto out;987 988	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;989	r = _config_request(ioc, &mpi_request, mpi_reply,990	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,991	    sizeof(*config_page));992 out:993	return r;994}995 996/**997 * mpt3sas_config_get_iounit_pg3 - obtain iounit page 3998 * @ioc: per adapter object999 * @mpi_reply: reply mf payload returned from firmware1000 * @config_page: contents of the config page1001 * @sz: size of buffer passed in config_page1002 * Context: sleep.1003 *1004 * Return: 0 for success, non-zero for failure.1005 */1006int1007mpt3sas_config_get_iounit_pg3(struct MPT3SAS_ADAPTER *ioc,1008	Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage3_t *config_page, u16 sz)1009{1010	Mpi2ConfigRequest_t mpi_request;1011	int r;1012 1013	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));1014	mpi_request.Function = MPI2_FUNCTION_CONFIG;1015	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;1016	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;1017	mpi_request.Header.PageNumber = 3;1018	mpi_request.Header.PageVersion = MPI2_IOUNITPAGE3_PAGEVERSION;1019	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);1020	r = _config_request(ioc, &mpi_request, mpi_reply,1021	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);1022	if (r)1023		goto out;1024 1025	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;1026	r = _config_request(ioc, &mpi_request, mpi_reply,1027	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);1028 out:1029	return r;1030}1031 1032/**1033 * mpt3sas_config_get_iounit_pg8 - obtain iounit page 81034 * @ioc: per adapter object1035 * @mpi_reply: reply mf payload returned from firmware1036 * @config_page: contents of the config page1037 * Context: sleep.1038 *1039 * Return: 0 for success, non-zero for failure.1040 */1041int1042mpt3sas_config_get_iounit_pg8(struct MPT3SAS_ADAPTER *ioc,1043	Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage8_t *config_page)1044{1045	Mpi2ConfigRequest_t mpi_request;1046	int r;1047 1048	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));1049	mpi_request.Function = MPI2_FUNCTION_CONFIG;1050	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;1051	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;1052	mpi_request.Header.PageNumber = 8;1053	mpi_request.Header.PageVersion = MPI2_IOUNITPAGE8_PAGEVERSION;1054	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);1055	r = _config_request(ioc, &mpi_request, mpi_reply,1056	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);1057	if (r)1058		goto out;1059 1060	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;1061	r = _config_request(ioc, &mpi_request, mpi_reply,1062	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,1063	    sizeof(*config_page));1064 out:1065	return r;1066}1067 1068/**1069 * mpt3sas_config_get_ioc_pg8 - obtain ioc page 81070 * @ioc: per adapter object1071 * @mpi_reply: reply mf payload returned from firmware1072 * @config_page: contents of the config page1073 * Context: sleep.1074 *1075 * Return: 0 for success, non-zero for failure.1076 */1077int1078mpt3sas_config_get_ioc_pg8(struct MPT3SAS_ADAPTER *ioc,1079	Mpi2ConfigReply_t *mpi_reply, Mpi2IOCPage8_t *config_page)1080{1081	Mpi2ConfigRequest_t mpi_request;1082	int r;1083 1084	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));1085	mpi_request.Function = MPI2_FUNCTION_CONFIG;1086	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;1087	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IOC;1088	mpi_request.Header.PageNumber = 8;1089	mpi_request.Header.PageVersion = MPI2_IOCPAGE8_PAGEVERSION;1090	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);1091	r = _config_request(ioc, &mpi_request, mpi_reply,1092	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);1093	if (r)1094		goto out;1095 1096	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;1097	r = _config_request(ioc, &mpi_request, mpi_reply,1098	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,1099	    sizeof(*config_page));1100 out:1101	return r;1102}1103/**1104 * mpt3sas_config_get_ioc_pg1 - obtain ioc page 11105 * @ioc: per adapter object1106 * @mpi_reply: reply mf payload returned from firmware1107 * @config_page: contents of the config page1108 * Context: sleep.1109 *1110 * Return: 0 for success, non-zero for failure.1111 */1112int1113mpt3sas_config_get_ioc_pg1(struct MPT3SAS_ADAPTER *ioc,1114	Mpi2ConfigReply_t *mpi_reply, Mpi2IOCPage1_t *config_page)1115{1116	Mpi2ConfigRequest_t mpi_request;1117	int r;1118 1119	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));1120	mpi_request.Function = MPI2_FUNCTION_CONFIG;1121	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;1122	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IOC;1123	mpi_request.Header.PageNumber = 1;1124	mpi_request.Header.PageVersion = MPI2_IOCPAGE8_PAGEVERSION;1125	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);1126	r = _config_request(ioc, &mpi_request, mpi_reply,1127	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);1128	if (r)1129		goto out;1130 1131	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;1132	r = _config_request(ioc, &mpi_request, mpi_reply,1133	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,1134	    sizeof(*config_page));1135 out:1136	return r;1137}1138 1139/**1140 * mpt3sas_config_set_ioc_pg1 - modify ioc page 11141 * @ioc: per adapter object1142 * @mpi_reply: reply mf payload returned from firmware1143 * @config_page: contents of the config page1144 * Context: sleep.1145 *1146 * Return: 0 for success, non-zero for failure.1147 */1148int1149mpt3sas_config_set_ioc_pg1(struct MPT3SAS_ADAPTER *ioc,1150	Mpi2ConfigReply_t *mpi_reply, Mpi2IOCPage1_t *config_page)1151{1152	Mpi2ConfigRequest_t mpi_request;1153	int r;1154 1155	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));1156	mpi_request.Function = MPI2_FUNCTION_CONFIG;1157	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;1158	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IOC;1159	mpi_request.Header.PageNumber = 1;1160	mpi_request.Header.PageVersion = MPI2_IOCPAGE8_PAGEVERSION;1161	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);1162	r = _config_request(ioc, &mpi_request, mpi_reply,1163	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);1164	if (r)1165		goto out;1166 1167	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;1168	r = _config_request(ioc, &mpi_request, mpi_reply,1169	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,1170	    sizeof(*config_page));1171 out:1172	return r;1173}1174 1175/**1176 * mpt3sas_config_get_sas_device_pg0 - obtain sas device page 01177 * @ioc: per adapter object1178 * @mpi_reply: reply mf payload returned from firmware1179 * @config_page: contents of the config page1180 * @form: GET_NEXT_HANDLE or HANDLE1181 * @handle: device handle1182 * Context: sleep.1183 *1184 * Return: 0 for success, non-zero for failure.1185 */1186int1187mpt3sas_config_get_sas_device_pg0(struct MPT3SAS_ADAPTER *ioc,1188	Mpi2ConfigReply_t *mpi_reply, Mpi2SasDevicePage0_t *config_page,1189	u32 form, u32 handle)1190{1191	Mpi2ConfigRequest_t mpi_request;1192	int r;1193 1194	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));1195	mpi_request.Function = MPI2_FUNCTION_CONFIG;1196	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;1197	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;1198	mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE;1199	mpi_request.Header.PageVersion = MPI2_SASDEVICE0_PAGEVERSION;1200	mpi_request.Header.PageNumber = 0;1201	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);1202	r = _config_request(ioc, &mpi_request, mpi_reply,1203	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);1204	if (r)1205		goto out;1206 1207	mpi_request.PageAddress = cpu_to_le32(form | handle);1208	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;1209	r = _config_request(ioc, &mpi_request, mpi_reply,1210	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,1211	    sizeof(*config_page));1212 out:1213	return r;1214}1215 1216/**1217 * mpt3sas_config_get_sas_device_pg1 - obtain sas device page 11218 * @ioc: per adapter object1219 * @mpi_reply: reply mf payload returned from firmware1220 * @config_page: contents of the config page1221 * @form: GET_NEXT_HANDLE or HANDLE1222 * @handle: device handle1223 * Context: sleep.1224 *1225 * Return: 0 for success, non-zero for failure.1226 */1227int1228mpt3sas_config_get_sas_device_pg1(struct MPT3SAS_ADAPTER *ioc,1229	Mpi2ConfigReply_t *mpi_reply, Mpi2SasDevicePage1_t *config_page,1230	u32 form, u32 handle)1231{1232	Mpi2ConfigRequest_t mpi_request;1233	int r;1234 1235	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));1236	mpi_request.Function = MPI2_FUNCTION_CONFIG;1237	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;1238	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;1239	mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE;1240	mpi_request.Header.PageVersion = MPI2_SASDEVICE1_PAGEVERSION;1241	mpi_request.Header.PageNumber = 1;1242	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);1243	r = _config_request(ioc, &mpi_request, mpi_reply,1244	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);1245	if (r)1246		goto out;1247 1248	mpi_request.PageAddress = cpu_to_le32(form | handle);1249	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;1250	r = _config_request(ioc, &mpi_request, mpi_reply,1251	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,1252	    sizeof(*config_page));1253 out:1254	return r;1255}1256 1257/**1258 * mpt3sas_config_get_pcie_device_pg0 - obtain pcie device page 01259 * @ioc: per adapter object1260 * @mpi_reply: reply mf payload returned from firmware1261 * @config_page: contents of the config page1262 * @form: GET_NEXT_HANDLE or HANDLE1263 * @handle: device handle1264 * Context: sleep.1265 *1266 * Return: 0 for success, non-zero for failure.1267 */1268int1269mpt3sas_config_get_pcie_device_pg0(struct MPT3SAS_ADAPTER *ioc,1270	Mpi2ConfigReply_t *mpi_reply, Mpi26PCIeDevicePage0_t *config_page,1271	u32 form, u32 handle)1272{1273	Mpi2ConfigRequest_t mpi_request;1274	int r;1275 1276	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));1277	mpi_request.Function = MPI2_FUNCTION_CONFIG;1278	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;1279	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;1280	mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE;1281	mpi_request.Header.PageVersion = MPI26_PCIEDEVICE0_PAGEVERSION;1282	mpi_request.Header.PageNumber = 0;1283	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);1284	r = _config_request(ioc, &mpi_request, mpi_reply,1285			MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);1286	if (r)1287		goto out;1288 1289	mpi_request.PageAddress = cpu_to_le32(form | handle);1290	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;1291	r = _config_request(ioc, &mpi_request, mpi_reply,1292			MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,1293			sizeof(*config_page));1294out:1295	return r;1296}1297 1298/**1299 * mpt3sas_config_get_pcie_iounit_pg1 - obtain pcie iounit page 11300 * @ioc: per adapter object1301 * @mpi_reply: reply mf payload returned from firmware1302 * @config_page: contents of the config page1303 * @sz: size of buffer passed in config_page1304 * Context: sleep.1305 *1306 * Returns 0 for success, non-zero for failure.1307 */1308int1309mpt3sas_config_get_pcie_iounit_pg1(struct MPT3SAS_ADAPTER *ioc,1310	Mpi2ConfigReply_t *mpi_reply, Mpi26PCIeIOUnitPage1_t *config_page,1311	u16 sz)1312{1313	Mpi2ConfigRequest_t mpi_request;1314	int r;1315 1316	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));1317	mpi_request.Function = MPI2_FUNCTION_CONFIG;1318	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;1319	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;1320	mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_IO_UNIT;1321	mpi_request.Header.PageVersion = MPI26_PCIEIOUNITPAGE1_PAGEVERSION;1322	mpi_request.Header.PageNumber = 1;1323	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);1324	r = _config_request(ioc, &mpi_request, mpi_reply,1325	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);1326	if (r)1327		goto out;1328	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;1329	r = _config_request(ioc, &mpi_request, mpi_reply,1330	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);1331out:1332	return r;1333}1334 1335/**1336 * mpt3sas_config_get_pcie_device_pg2 - obtain pcie device page 21337 * @ioc: per adapter object1338 * @mpi_reply: reply mf payload returned from firmware1339 * @config_page: contents of the config page1340 * @form: GET_NEXT_HANDLE or HANDLE1341 * @handle: device handle1342 * Context: sleep.1343 *1344 * Return: 0 for success, non-zero for failure.1345 */1346int1347mpt3sas_config_get_pcie_device_pg2(struct MPT3SAS_ADAPTER *ioc,1348	Mpi2ConfigReply_t *mpi_reply, Mpi26PCIeDevicePage2_t *config_page,1349	u32 form, u32 handle)1350{1351	Mpi2ConfigRequest_t mpi_request;1352	int r;1353 1354	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));1355	mpi_request.Function = MPI2_FUNCTION_CONFIG;1356	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;1357	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;1358	mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE;1359	mpi_request.Header.PageVersion = MPI26_PCIEDEVICE2_PAGEVERSION;1360	mpi_request.Header.PageNumber = 2;1361	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);1362	r = _config_request(ioc, &mpi_request, mpi_reply,1363			MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);1364	if (r)1365		goto out;1366 1367	mpi_request.PageAddress = cpu_to_le32(form | handle);1368	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;1369	r = _config_request(ioc, &mpi_request, mpi_reply,1370			MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,1371			sizeof(*config_page));1372out:1373	return r;1374}1375 1376/**1377 * mpt3sas_config_get_number_hba_phys - obtain number of phys on the host1378 * @ioc: per adapter object1379 * @num_phys: pointer returned with the number of phys1380 * Context: sleep.1381 *1382 * Return: 0 for success, non-zero for failure.1383 */1384int1385mpt3sas_config_get_number_hba_phys(struct MPT3SAS_ADAPTER *ioc, u8 *num_phys)1386{1387	Mpi2ConfigRequest_t mpi_request;1388	int r;1389	u16 ioc_status;1390	Mpi2ConfigReply_t mpi_reply;1391	Mpi2SasIOUnitPage0_t config_page;1392 1393	*num_phys = 0;1394	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));1395	mpi_request.Function = MPI2_FUNCTION_CONFIG;1396	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;1397	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;1398	mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;1399	mpi_request.Header.PageNumber = 0;1400	mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE0_PAGEVERSION;1401	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);1402	r = _config_request(ioc, &mpi_request, &mpi_reply,1403	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);1404	if (r)1405		goto out;1406 1407	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;1408	r = _config_request(ioc, &mpi_request, &mpi_reply,1409	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, &config_page,1410	    sizeof(Mpi2SasIOUnitPage0_t));1411	if (!r) {1412		ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &1413		    MPI2_IOCSTATUS_MASK;1414		if (ioc_status == MPI2_IOCSTATUS_SUCCESS)1415			*num_phys = config_page.NumPhys;1416	}1417 out:1418	return r;1419}1420 1421/**1422 * mpt3sas_config_get_sas_iounit_pg0 - obtain sas iounit page 01423 * @ioc: per adapter object1424 * @mpi_reply: reply mf payload returned from firmware1425 * @config_page: contents of the config page1426 * @sz: size of buffer passed in config_page1427 * Context: sleep.1428 *1429 * Calling function should call config_get_number_hba_phys prior to1430 * this function, so enough memory is allocated for config_page.1431 *1432 * Return: 0 for success, non-zero for failure.1433 */1434int1435mpt3sas_config_get_sas_iounit_pg0(struct MPT3SAS_ADAPTER *ioc,1436	Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage0_t *config_page,1437	u16 sz)1438{1439	Mpi2ConfigRequest_t mpi_request;1440	int r;1441 1442	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));1443	mpi_request.Function = MPI2_FUNCTION_CONFIG;1444	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;1445	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;1446	mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;1447	mpi_request.Header.PageNumber = 0;1448	mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE0_PAGEVERSION;1449	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);1450	r = _config_request(ioc, &mpi_request, mpi_reply,1451	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);1452	if (r)1453		goto out;1454 1455	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;1456	r = _config_request(ioc, &mpi_request, mpi_reply,1457	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);1458 out:1459	return r;1460}1461 1462/**1463 * mpt3sas_config_get_sas_iounit_pg1 - obtain sas iounit page 11464 * @ioc: per adapter object1465 * @mpi_reply: reply mf payload returned from firmware1466 * @config_page: contents of the config page1467 * @sz: size of buffer passed in config_page1468 * Context: sleep.1469 *1470 * Calling function should call config_get_number_hba_phys prior to1471 * this function, so enough memory is allocated for config_page.1472 *1473 * Return: 0 for success, non-zero for failure.1474 */1475int1476mpt3sas_config_get_sas_iounit_pg1(struct MPT3SAS_ADAPTER *ioc,1477	Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage1_t *config_page,1478	u16 sz)1479{1480	Mpi2ConfigRequest_t mpi_request;1481	int r;1482 1483	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));1484	mpi_request.Function = MPI2_FUNCTION_CONFIG;1485	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;1486	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;1487	mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;1488	mpi_request.Header.PageNumber = 1;1489	mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE1_PAGEVERSION;1490	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);1491	r = _config_request(ioc, &mpi_request, mpi_reply,1492	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);1493	if (r)1494		goto out;1495 1496	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;1497	r = _config_request(ioc, &mpi_request, mpi_reply,1498	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);1499 out:1500	return r;1501}1502 1503/**1504 * mpt3sas_config_set_sas_iounit_pg1 - send sas iounit page 11505 * @ioc: per adapter object1506 * @mpi_reply: reply mf payload returned from firmware1507 * @config_page: contents of the config page1508 * @sz: size of buffer passed in config_page1509 * Context: sleep.1510 *1511 * Calling function should call config_get_number_hba_phys prior to1512 * this function, so enough memory is allocated for config_page.1513 *1514 * Return: 0 for success, non-zero for failure.1515 */1516int1517mpt3sas_config_set_sas_iounit_pg1(struct MPT3SAS_ADAPTER *ioc,1518	Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage1_t *config_page,1519	u16 sz)1520{1521	Mpi2ConfigRequest_t mpi_request;1522	int r;1523 1524	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));1525	mpi_request.Function = MPI2_FUNCTION_CONFIG;1526	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;1527	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;1528	mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;1529	mpi_request.Header.PageNumber = 1;1530	mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE1_PAGEVERSION;1531	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);1532	r = _config_request(ioc, &mpi_request, mpi_reply,1533	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);1534	if (r)1535		goto out;1536 1537	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;1538	_config_request(ioc, &mpi_request, mpi_reply,1539	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);1540	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;1541	r = _config_request(ioc, &mpi_request, mpi_reply,1542	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);1543 out:1544	return r;1545}1546 1547/**1548 * mpt3sas_config_get_expander_pg0 - obtain expander page 01549 * @ioc: per adapter object1550 * @mpi_reply: reply mf payload returned from firmware1551 * @config_page: contents of the config page1552 * @form: GET_NEXT_HANDLE or HANDLE1553 * @handle: expander handle1554 * Context: sleep.1555 *1556 * Return: 0 for success, non-zero for failure.1557 */1558int1559mpt3sas_config_get_expander_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t1560	*mpi_reply, Mpi2ExpanderPage0_t *config_page, u32 form, u32 handle)1561{1562	Mpi2ConfigRequest_t mpi_request;1563	int r;1564 1565	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));1566	mpi_request.Function = MPI2_FUNCTION_CONFIG;1567	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;1568	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;1569	mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER;1570	mpi_request.Header.PageNumber = 0;1571	mpi_request.Header.PageVersion = MPI2_SASEXPANDER0_PAGEVERSION;1572	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);1573	r = _config_request(ioc, &mpi_request, mpi_reply,1574	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);1575	if (r)1576		goto out;1577 1578	mpi_request.PageAddress = cpu_to_le32(form | handle);1579	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;1580	r = _config_request(ioc, &mpi_request, mpi_reply,1581	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,1582	    sizeof(*config_page));1583 out:1584	return r;1585}1586 1587/**1588 * mpt3sas_config_get_expander_pg1 - obtain expander page 11589 * @ioc: per adapter object1590 * @mpi_reply: reply mf payload returned from firmware1591 * @config_page: contents of the config page1592 * @phy_number: phy number1593 * @handle: expander handle1594 * Context: sleep.1595 *1596 * Return: 0 for success, non-zero for failure.1597 */1598int1599mpt3sas_config_get_expander_pg1(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t1600	*mpi_reply, Mpi2ExpanderPage1_t *config_page, u32 phy_number,1601	u16 handle)1602{1603	Mpi2ConfigRequest_t mpi_request;1604	int r;1605 1606	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));1607	mpi_request.Function = MPI2_FUNCTION_CONFIG;1608	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;1609	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;1610	mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER;1611	mpi_request.Header.PageNumber = 1;1612	mpi_request.Header.PageVersion = MPI2_SASEXPANDER1_PAGEVERSION;1613	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);1614	r = _config_request(ioc, &mpi_request, mpi_reply,1615	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);1616	if (r)1617		goto out;1618 1619	mpi_request.PageAddress =1620	    cpu_to_le32(MPI2_SAS_EXPAND_PGAD_FORM_HNDL_PHY_NUM |1621	    (phy_number << MPI2_SAS_EXPAND_PGAD_PHYNUM_SHIFT) | handle);1622	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;1623	r = _config_request(ioc, &mpi_request, mpi_reply,1624	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,1625	    sizeof(*config_page));1626 out:1627	return r;1628}1629 1630/**1631 * mpt3sas_config_get_enclosure_pg0 - obtain enclosure page 01632 * @ioc: per adapter object1633 * @mpi_reply: reply mf payload returned from firmware1634 * @config_page: contents of the config page1635 * @form: GET_NEXT_HANDLE or HANDLE1636 * @handle: expander handle1637 * Context: sleep.1638 *1639 * Return: 0 for success, non-zero for failure.1640 */1641int1642mpt3sas_config_get_enclosure_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t1643	*mpi_reply, Mpi2SasEnclosurePage0_t *config_page, u32 form, u32 handle)1644{1645	Mpi2ConfigRequest_t mpi_request;1646	int r;1647 1648	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));1649	mpi_request.Function = MPI2_FUNCTION_CONFIG;1650	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;1651	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;1652	mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_ENCLOSURE;1653	mpi_request.Header.PageNumber = 0;1654	mpi_request.Header.PageVersion = MPI2_SASENCLOSURE0_PAGEVERSION;1655	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);1656	r = _config_request(ioc, &mpi_request, mpi_reply,1657	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);1658	if (r)1659		goto out;1660 1661	mpi_request.PageAddress = cpu_to_le32(form | handle);1662	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;1663	r = _config_request(ioc, &mpi_request, mpi_reply,1664	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,1665	    sizeof(*config_page));1666 out:1667	return r;1668}1669 1670/**1671 * mpt3sas_config_get_phy_pg0 - obtain phy page 01672 * @ioc: per adapter object1673 * @mpi_reply: reply mf payload returned from firmware1674 * @config_page: contents of the config page1675 * @phy_number: phy number1676 * Context: sleep.1677 *1678 * Return: 0 for success, non-zero for failure.1679 */1680int1681mpt3sas_config_get_phy_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t1682	*mpi_reply, Mpi2SasPhyPage0_t *config_page, u32 phy_number)1683{1684	Mpi2ConfigRequest_t mpi_request;1685	int r;1686 1687	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));1688	mpi_request.Function = MPI2_FUNCTION_CONFIG;1689	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;1690	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;1691	mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_PHY;1692	mpi_request.Header.PageNumber = 0;1693	mpi_request.Header.PageVersion = MPI2_SASPHY0_PAGEVERSION;1694	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);1695	r = _config_request(ioc, &mpi_request, mpi_reply,1696	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);1697	if (r)1698		goto out;1699 1700	mpi_request.PageAddress =1701	    cpu_to_le32(MPI2_SAS_PHY_PGAD_FORM_PHY_NUMBER | phy_number);1702	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;1703	r = _config_request(ioc, &mpi_request, mpi_reply,1704	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,1705	    sizeof(*config_page));1706 out:1707	return r;1708}1709 1710/**1711 * mpt3sas_config_get_phy_pg1 - obtain phy page 11712 * @ioc: per adapter object1713 * @mpi_reply: reply mf payload returned from firmware1714 * @config_page: contents of the config page1715 * @phy_number: phy number1716 * Context: sleep.1717 *1718 * Return: 0 for success, non-zero for failure.1719 */1720int1721mpt3sas_config_get_phy_pg1(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t1722	*mpi_reply, Mpi2SasPhyPage1_t *config_page, u32 phy_number)1723{1724	Mpi2ConfigRequest_t mpi_request;1725	int r;1726 1727	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));1728	mpi_request.Function = MPI2_FUNCTION_CONFIG;1729	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;1730	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;1731	mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_PHY;1732	mpi_request.Header.PageNumber = 1;1733	mpi_request.Header.PageVersion = MPI2_SASPHY1_PAGEVERSION;1734	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);1735	r = _config_request(ioc, &mpi_request, mpi_reply,1736	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);1737	if (r)1738		goto out;1739 1740	mpi_request.PageAddress =1741	    cpu_to_le32(MPI2_SAS_PHY_PGAD_FORM_PHY_NUMBER | phy_number);1742	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;1743	r = _config_request(ioc, &mpi_request, mpi_reply,1744	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,1745	    sizeof(*config_page));1746 out:1747	return r;1748}1749 1750/**1751 * mpt3sas_config_get_raid_volume_pg1 - obtain raid volume page 11752 * @ioc: per adapter object1753 * @mpi_reply: reply mf payload returned from firmware1754 * @config_page: contents of the config page1755 * @form: GET_NEXT_HANDLE or HANDLE1756 * @handle: volume handle1757 * Context: sleep.1758 *1759 * Return: 0 for success, non-zero for failure.1760 */1761int1762mpt3sas_config_get_raid_volume_pg1(struct MPT3SAS_ADAPTER *ioc,1763	Mpi2ConfigReply_t *mpi_reply, Mpi2RaidVolPage1_t *config_page, u32 form,1764	u32 handle)1765{1766	Mpi2ConfigRequest_t mpi_request;1767	int r;1768 1769	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));1770	mpi_request.Function = MPI2_FUNCTION_CONFIG;1771	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;1772	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;1773	mpi_request.Header.PageNumber = 1;1774	mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE1_PAGEVERSION;1775	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);1776	r = _config_request(ioc, &mpi_request, mpi_reply,1777	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);1778	if (r)1779		goto out;1780 1781	mpi_request.PageAddress = cpu_to_le32(form | handle);1782	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;1783	r = _config_request(ioc, &mpi_request, mpi_reply,1784	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,1785	    sizeof(*config_page));1786 out:1787	return r;1788}1789 1790/**1791 * mpt3sas_config_get_number_pds - obtain number of phys disk assigned to volume1792 * @ioc: per adapter object1793 * @handle: volume handle1794 * @num_pds: returns pds count1795 * Context: sleep.1796 *1797 * Return: 0 for success, non-zero for failure.1798 */1799int1800mpt3sas_config_get_number_pds(struct MPT3SAS_ADAPTER *ioc, u16 handle,1801	u8 *num_pds)1802{1803	Mpi2ConfigRequest_t mpi_request;1804	Mpi2RaidVolPage0_t config_page;1805	Mpi2ConfigReply_t mpi_reply;1806	int r;1807	u16 ioc_status;1808 1809	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));1810	*num_pds = 0;1811	mpi_request.Function = MPI2_FUNCTION_CONFIG;1812	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;1813	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;1814	mpi_request.Header.PageNumber = 0;1815	mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE0_PAGEVERSION;1816	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);1817	r = _config_request(ioc, &mpi_request, &mpi_reply,1818	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);1819	if (r)1820		goto out;1821 1822	mpi_request.PageAddress =1823	    cpu_to_le32(MPI2_RAID_VOLUME_PGAD_FORM_HANDLE | handle);1824	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;1825	r = _config_request(ioc, &mpi_request, &mpi_reply,1826	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, &config_page,1827	    sizeof(Mpi2RaidVolPage0_t));1828	if (!r) {1829		ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &1830		    MPI2_IOCSTATUS_MASK;1831		if (ioc_status == MPI2_IOCSTATUS_SUCCESS)1832			*num_pds = config_page.NumPhysDisks;1833	}1834 1835 out:1836	return r;1837}1838 1839/**1840 * mpt3sas_config_get_raid_volume_pg0 - obtain raid volume page 01841 * @ioc: per adapter object1842 * @mpi_reply: reply mf payload returned from firmware1843 * @config_page: contents of the config page1844 * @form: GET_NEXT_HANDLE or HANDLE1845 * @handle: volume handle1846 * @sz: size of buffer passed in config_page1847 * Context: sleep.1848 *1849 * Return: 0 for success, non-zero for failure.1850 */1851int1852mpt3sas_config_get_raid_volume_pg0(struct MPT3SAS_ADAPTER *ioc,1853	Mpi2ConfigReply_t *mpi_reply, Mpi2RaidVolPage0_t *config_page, u32 form,1854	u32 handle, u16 sz)1855{1856	Mpi2ConfigRequest_t mpi_request;1857	int r;1858 1859	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));1860	mpi_request.Function = MPI2_FUNCTION_CONFIG;1861	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;1862	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;1863	mpi_request.Header.PageNumber = 0;1864	mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE0_PAGEVERSION;1865	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);1866	r = _config_request(ioc, &mpi_request, mpi_reply,1867	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);1868	if (r)1869		goto out;1870 1871	mpi_request.PageAddress = cpu_to_le32(form | handle);1872	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;1873	r = _config_request(ioc, &mpi_request, mpi_reply,1874	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);1875 out:1876	return r;1877}1878 1879/**1880 * mpt3sas_config_get_phys_disk_pg0 - obtain phys disk page 01881 * @ioc: per adapter object1882 * @mpi_reply: reply mf payload returned from firmware1883 * @config_page: contents of the config page1884 * @form: GET_NEXT_PHYSDISKNUM, PHYSDISKNUM, DEVHANDLE1885 * @form_specific: specific to the form1886 * Context: sleep.1887 *1888 * Return: 0 for success, non-zero for failure.1889 */1890int1891mpt3sas_config_get_phys_disk_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t1892	*mpi_reply, Mpi2RaidPhysDiskPage0_t *config_page, u32 form,1893	u32 form_specific)1894{1895	Mpi2ConfigRequest_t mpi_request;1896	int r;1897 1898	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));1899	mpi_request.Function = MPI2_FUNCTION_CONFIG;1900	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;1901	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_PHYSDISK;1902	mpi_request.Header.PageNumber = 0;1903	mpi_request.Header.PageVersion = MPI2_RAIDPHYSDISKPAGE0_PAGEVERSION;1904	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);1905	r = _config_request(ioc, &mpi_request, mpi_reply,1906	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);1907	if (r)1908		goto out;1909 1910	mpi_request.PageAddress = cpu_to_le32(form | form_specific);1911	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;1912	r = _config_request(ioc, &mpi_request, mpi_reply,1913	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,1914	    sizeof(*config_page));1915 out:1916	return r;1917}1918 1919/**1920 * mpt3sas_config_get_driver_trigger_pg0 - obtain driver trigger page 01921 * @ioc: per adapter object1922 * @mpi_reply: reply mf payload returned from firmware1923 * @config_page: contents of the config page1924 * Context: sleep.1925 *1926 * Returns 0 for success, non-zero for failure.1927 */1928int1929mpt3sas_config_get_driver_trigger_pg0(struct MPT3SAS_ADAPTER *ioc,1930	Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage0_t *config_page)1931{1932	Mpi2ConfigRequest_t mpi_request;1933	int r;1934 1935	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));1936	mpi_request.Function = MPI2_FUNCTION_CONFIG;1937	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;1938	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;1939	mpi_request.ExtPageType =1940	    MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;1941	mpi_request.Header.PageNumber = 0;1942	mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE0_PAGEVERSION;1943	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);1944	r = _config_request(ioc, &mpi_request, mpi_reply,1945	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);1946	if (r)1947		goto out;1948 1949	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;1950	r = _config_request(ioc, &mpi_request, mpi_reply,1951	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,1952	    sizeof(*config_page));1953 out:1954	return r;1955}1956 1957/**1958 * _config_set_driver_trigger_pg0 - write driver trigger page 01959 * @ioc: per adapter object1960 * @mpi_reply: reply mf payload returned from firmware1961 * @config_page: contents of the config page1962 * Context: sleep.1963 *1964 * Returns 0 for success, non-zero for failure.1965 */1966static int1967_config_set_driver_trigger_pg0(struct MPT3SAS_ADAPTER *ioc,1968	Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage0_t *config_page)1969{1970	Mpi2ConfigRequest_t mpi_request;1971	int r;1972 1973	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));1974	mpi_request.Function = MPI2_FUNCTION_CONFIG;1975	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;1976	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;1977	mpi_request.ExtPageType =1978	    MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;1979	mpi_request.Header.PageNumber = 0;1980	mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE0_PAGEVERSION;1981	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);1982	r = _config_request(ioc, &mpi_request, mpi_reply,1983	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);1984	if (r)1985		goto out;1986 1987	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;1988	_config_request(ioc, &mpi_request, mpi_reply,1989	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,1990	    sizeof(*config_page));1991	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;1992	r = _config_request(ioc, &mpi_request, mpi_reply,1993	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,1994	    sizeof(*config_page));1995 out:1996	return r;1997}1998 1999/**2000 * mpt3sas_config_update_driver_trigger_pg0 - update driver trigger page 02001 * @ioc: per adapter object2002 * @trigger_flag: trigger type bit map2003 * @set: set ot clear trigger values2004 * Context: sleep.2005 *2006 * Returns 0 for success, non-zero for failure.2007 */2008static int2009mpt3sas_config_update_driver_trigger_pg0(struct MPT3SAS_ADAPTER *ioc,2010	u16 trigger_flag, bool set)2011{2012	Mpi26DriverTriggerPage0_t tg_pg0;2013	Mpi2ConfigReply_t mpi_reply;2014	int rc;2015	u16 flags, ioc_status;2016 2017	rc = mpt3sas_config_get_driver_trigger_pg0(ioc, &mpi_reply, &tg_pg0);2018	if (rc)2019		return rc;2020	ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &2021	    MPI2_IOCSTATUS_MASK;2022	if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {2023		dcprintk(ioc,2024		    ioc_err(ioc,2025		    "%s: Failed to get trigger pg0, ioc_status(0x%04x)\n",2026		    __func__, ioc_status));2027		return -EFAULT;2028	}2029 2030	if (set)2031		flags = le16_to_cpu(tg_pg0.TriggerFlags) | trigger_flag;2032	else2033		flags = le16_to_cpu(tg_pg0.TriggerFlags) & ~trigger_flag;2034 2035	tg_pg0.TriggerFlags = cpu_to_le16(flags);2036 2037	rc = _config_set_driver_trigger_pg0(ioc, &mpi_reply, &tg_pg0);2038	if (rc)2039		return rc;2040	ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &2041	    MPI2_IOCSTATUS_MASK;2042	if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {2043		dcprintk(ioc,2044		    ioc_err(ioc,2045		    "%s: Failed to update trigger pg0, ioc_status(0x%04x)\n",2046		    __func__, ioc_status));2047		return -EFAULT;2048	}2049 2050	return 0;2051}2052 2053/**2054 * mpt3sas_config_get_driver_trigger_pg1 - obtain driver trigger page 12055 * @ioc: per adapter object2056 * @mpi_reply: reply mf payload returned from firmware2057 * @config_page: contents of the config page2058 * Context: sleep.2059 *2060 * Returns 0 for success, non-zero for failure.2061 */2062int2063mpt3sas_config_get_driver_trigger_pg1(struct MPT3SAS_ADAPTER *ioc,2064	Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage1_t *config_page)2065{2066	Mpi2ConfigRequest_t mpi_request;2067	int r;2068 2069	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));2070	mpi_request.Function = MPI2_FUNCTION_CONFIG;2071	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;2072	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;2073	mpi_request.ExtPageType =2074	    MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;2075	mpi_request.Header.PageNumber = 1;2076	mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE1_PAGEVERSION;2077	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);2078	r = _config_request(ioc, &mpi_request, mpi_reply,2079	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);2080	if (r)2081		goto out;2082 2083	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;2084	r = _config_request(ioc, &mpi_request, mpi_reply,2085	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,2086	    sizeof(*config_page));2087 out:2088	return r;2089}2090 2091/**2092 * _config_set_driver_trigger_pg1 - write driver trigger page 12093 * @ioc: per adapter object2094 * @mpi_reply: reply mf payload returned from firmware2095 * @config_page: contents of the config page2096 * Context: sleep.2097 *2098 * Returns 0 for success, non-zero for failure.2099 */2100static int2101_config_set_driver_trigger_pg1(struct MPT3SAS_ADAPTER *ioc,2102	Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage1_t *config_page)2103{2104	Mpi2ConfigRequest_t mpi_request;2105	int r;2106 2107	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));2108	mpi_request.Function = MPI2_FUNCTION_CONFIG;2109	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;2110	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;2111	mpi_request.ExtPageType =2112	    MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;2113	mpi_request.Header.PageNumber = 1;2114	mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE1_PAGEVERSION;2115	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);2116	r = _config_request(ioc, &mpi_request, mpi_reply,2117	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);2118	if (r)2119		goto out;2120 2121	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;2122	_config_request(ioc, &mpi_request, mpi_reply,2123	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,2124	    sizeof(*config_page));2125	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;2126	r = _config_request(ioc, &mpi_request, mpi_reply,2127	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,2128	    sizeof(*config_page));2129 out:2130	return r;2131}2132 2133/**2134 * mpt3sas_config_update_driver_trigger_pg1 - update driver trigger page 12135 * @ioc: per adapter object2136 * @master_tg: Master trigger bit map2137 * @set: set ot clear trigger values2138 * Context: sleep.2139 *2140 * Returns 0 for success, non-zero for failure.2141 */2142int2143mpt3sas_config_update_driver_trigger_pg1(struct MPT3SAS_ADAPTER *ioc,2144	struct SL_WH_MASTER_TRIGGER_T *master_tg, bool set)2145{2146	Mpi26DriverTriggerPage1_t tg_pg1;2147	Mpi2ConfigReply_t mpi_reply;2148	int rc;2149	u16 ioc_status;2150 2151	rc = mpt3sas_config_update_driver_trigger_pg0(ioc,2152	    MPI26_DRIVER_TRIGGER0_FLAG_MASTER_TRIGGER_VALID, set);2153	if (rc)2154		return rc;2155 2156	rc = mpt3sas_config_get_driver_trigger_pg1(ioc, &mpi_reply, &tg_pg1);2157	if (rc)2158		goto out;2159 2160	ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &2161	    MPI2_IOCSTATUS_MASK;2162	if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {2163		dcprintk(ioc,2164		    ioc_err(ioc,2165		    "%s: Failed to get trigger pg1, ioc_status(0x%04x)\n",2166		    __func__, ioc_status));2167		rc = -EFAULT;2168		goto out;2169	}2170 2171	if (set) {2172		tg_pg1.NumMasterTrigger = cpu_to_le16(1);2173		tg_pg1.MasterTriggers[0].MasterTriggerFlags = cpu_to_le32(2174		    master_tg->MasterData);2175	} else {2176		tg_pg1.NumMasterTrigger = 0;2177		tg_pg1.MasterTriggers[0].MasterTriggerFlags = 0;2178	}2179 2180	rc = _config_set_driver_trigger_pg1(ioc, &mpi_reply, &tg_pg1);2181	if (rc)2182		goto out;2183 2184	ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &2185	    MPI2_IOCSTATUS_MASK;2186	if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {2187		dcprintk(ioc,2188		    ioc_err(ioc,2189		    "%s: Failed to get trigger pg1, ioc_status(0x%04x)\n",2190		    __func__, ioc_status));2191		rc = -EFAULT;2192		goto out;2193	}2194 2195	return 0;2196 2197out:2198	mpt3sas_config_update_driver_trigger_pg0(ioc,2199	    MPI26_DRIVER_TRIGGER0_FLAG_MASTER_TRIGGER_VALID, !set);2200 2201	return rc;2202}2203 2204/**2205 * mpt3sas_config_get_driver_trigger_pg2 - obtain driver trigger page 22206 * @ioc: per adapter object2207 * @mpi_reply: reply mf payload returned from firmware2208 * @config_page: contents of the config page2209 * Context: sleep.2210 *2211 * Returns 0 for success, non-zero for failure.2212 */2213int2214mpt3sas_config_get_driver_trigger_pg2(struct MPT3SAS_ADAPTER *ioc,2215	Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage2_t *config_page)2216{2217	Mpi2ConfigRequest_t mpi_request;2218	int r;2219 2220	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));2221	mpi_request.Function = MPI2_FUNCTION_CONFIG;2222	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;2223	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;2224	mpi_request.ExtPageType =2225	    MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;2226	mpi_request.Header.PageNumber = 2;2227	mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE2_PAGEVERSION;2228	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);2229	r = _config_request(ioc, &mpi_request, mpi_reply,2230	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);2231	if (r)2232		goto out;2233 2234	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;2235	r = _config_request(ioc, &mpi_request, mpi_reply,2236	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,2237	    sizeof(*config_page));2238 out:2239	return r;2240}2241 2242/**2243 * _config_set_driver_trigger_pg2 - write driver trigger page 22244 * @ioc: per adapter object2245 * @mpi_reply: reply mf payload returned from firmware2246 * @config_page: contents of the config page2247 * Context: sleep.2248 *2249 * Returns 0 for success, non-zero for failure.2250 */2251static int2252_config_set_driver_trigger_pg2(struct MPT3SAS_ADAPTER *ioc,2253	Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage2_t *config_page)2254{2255	Mpi2ConfigRequest_t mpi_request;2256	int r;2257 2258	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));2259	mpi_request.Function = MPI2_FUNCTION_CONFIG;2260	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;2261	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;2262	mpi_request.ExtPageType =2263	    MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;2264	mpi_request.Header.PageNumber = 2;2265	mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE2_PAGEVERSION;2266	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);2267	r = _config_request(ioc, &mpi_request, mpi_reply,2268	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);2269	if (r)2270		goto out;2271 2272	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;2273	_config_request(ioc, &mpi_request, mpi_reply,2274	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,2275	    sizeof(*config_page));2276	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;2277	r = _config_request(ioc, &mpi_request, mpi_reply,2278	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,2279	    sizeof(*config_page));2280 out:2281	return r;2282}2283 2284/**2285 * mpt3sas_config_update_driver_trigger_pg2 - update driver trigger page 22286 * @ioc: per adapter object2287 * @event_tg: list of Event Triggers2288 * @set: set ot clear trigger values2289 * Context: sleep.2290 *2291 * Returns 0 for success, non-zero for failure.2292 */2293int2294mpt3sas_config_update_driver_trigger_pg2(struct MPT3SAS_ADAPTER *ioc,2295	struct SL_WH_EVENT_TRIGGERS_T *event_tg, bool set)2296{2297	Mpi26DriverTriggerPage2_t tg_pg2;2298	Mpi2ConfigReply_t mpi_reply;2299	int rc, i, count;2300	u16 ioc_status;2301 2302	rc = mpt3sas_config_update_driver_trigger_pg0(ioc,2303	    MPI26_DRIVER_TRIGGER0_FLAG_MPI_EVENT_TRIGGER_VALID, set);2304	if (rc)2305		return rc;2306 2307	rc = mpt3sas_config_get_driver_trigger_pg2(ioc, &mpi_reply, &tg_pg2);2308	if (rc)2309		goto out;2310 2311	ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &2312	    MPI2_IOCSTATUS_MASK;2313	if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {2314		dcprintk(ioc,2315		    ioc_err(ioc,2316		    "%s: Failed to get trigger pg2, ioc_status(0x%04x)\n",2317		    __func__, ioc_status));2318		rc = -EFAULT;2319		goto out;2320	}2321 2322	if (set) {2323		count = event_tg->ValidEntries;2324		tg_pg2.NumMPIEventTrigger = cpu_to_le16(count);2325		for (i = 0; i < count; i++) {2326			tg_pg2.MPIEventTriggers[i].MPIEventCode =2327			    cpu_to_le16(2328			    event_tg->EventTriggerEntry[i].EventValue);2329			tg_pg2.MPIEventTriggers[i].MPIEventCodeSpecific =2330			    cpu_to_le16(2331			    event_tg->EventTriggerEntry[i].LogEntryQualifier);2332		}2333	} else {2334		tg_pg2.NumMPIEventTrigger = 0;2335		memset(&tg_pg2.MPIEventTriggers[0], 0,2336		    NUM_VALID_ENTRIES * sizeof(2337		    MPI26_DRIVER_MPI_EVENT_TRIGGER_ENTRY));2338	}2339 2340	rc = _config_set_driver_trigger_pg2(ioc, &mpi_reply, &tg_pg2);2341	if (rc)2342		goto out;2343 2344	ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &2345	    MPI2_IOCSTATUS_MASK;2346	if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {2347		dcprintk(ioc,2348		    ioc_err(ioc,2349		    "%s: Failed to get trigger pg2, ioc_status(0x%04x)\n",2350		    __func__, ioc_status));2351		rc = -EFAULT;2352		goto out;2353	}2354 2355	return 0;2356 2357out:2358	mpt3sas_config_update_driver_trigger_pg0(ioc,2359	    MPI26_DRIVER_TRIGGER0_FLAG_MPI_EVENT_TRIGGER_VALID, !set);2360 2361	return rc;2362}2363 2364/**2365 * mpt3sas_config_get_driver_trigger_pg3 - obtain driver trigger page 32366 * @ioc: per adapter object2367 * @mpi_reply: reply mf payload returned from firmware2368 * @config_page: contents of the config page2369 * Context: sleep.2370 *2371 * Returns 0 for success, non-zero for failure.2372 */2373int2374mpt3sas_config_get_driver_trigger_pg3(struct MPT3SAS_ADAPTER *ioc,2375	Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage3_t *config_page)2376{2377	Mpi2ConfigRequest_t mpi_request;2378	int r;2379 2380	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));2381	mpi_request.Function = MPI2_FUNCTION_CONFIG;2382	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;2383	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;2384	mpi_request.ExtPageType =2385	    MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;2386	mpi_request.Header.PageNumber = 3;2387	mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE3_PAGEVERSION;2388	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);2389	r = _config_request(ioc, &mpi_request, mpi_reply,2390	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);2391	if (r)2392		goto out;2393 2394	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;2395	r = _config_request(ioc, &mpi_request, mpi_reply,2396	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,2397	    sizeof(*config_page));2398 out:2399	return r;2400}2401 2402/**2403 * _config_set_driver_trigger_pg3 - write driver trigger page 32404 * @ioc: per adapter object2405 * @mpi_reply: reply mf payload returned from firmware2406 * @config_page: contents of the config page2407 * Context: sleep.2408 *2409 * Returns 0 for success, non-zero for failure.2410 */2411static int2412_config_set_driver_trigger_pg3(struct MPT3SAS_ADAPTER *ioc,2413	Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage3_t *config_page)2414{2415	Mpi2ConfigRequest_t mpi_request;2416	int r;2417 2418	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));2419	mpi_request.Function = MPI2_FUNCTION_CONFIG;2420	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;2421	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;2422	mpi_request.ExtPageType =2423	    MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;2424	mpi_request.Header.PageNumber = 3;2425	mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE3_PAGEVERSION;2426	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);2427	r = _config_request(ioc, &mpi_request, mpi_reply,2428	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);2429	if (r)2430		goto out;2431 2432	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;2433	_config_request(ioc, &mpi_request, mpi_reply,2434	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,2435	    sizeof(*config_page));2436	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;2437	r = _config_request(ioc, &mpi_request, mpi_reply,2438	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,2439	    sizeof(*config_page));2440 out:2441	return r;2442}2443 2444/**2445 * mpt3sas_config_update_driver_trigger_pg3 - update driver trigger page 32446 * @ioc: per adapter object2447 * @scsi_tg: scsi trigger list2448 * @set: set ot clear trigger values2449 * Context: sleep.2450 *2451 * Returns 0 for success, non-zero for failure.2452 */2453int2454mpt3sas_config_update_driver_trigger_pg3(struct MPT3SAS_ADAPTER *ioc,2455	struct SL_WH_SCSI_TRIGGERS_T *scsi_tg, bool set)2456{2457	Mpi26DriverTriggerPage3_t tg_pg3;2458	Mpi2ConfigReply_t mpi_reply;2459	int rc, i, count;2460	u16 ioc_status;2461 2462	rc = mpt3sas_config_update_driver_trigger_pg0(ioc,2463	    MPI26_DRIVER_TRIGGER0_FLAG_SCSI_SENSE_TRIGGER_VALID, set);2464	if (rc)2465		return rc;2466 2467	rc = mpt3sas_config_get_driver_trigger_pg3(ioc, &mpi_reply, &tg_pg3);2468	if (rc)2469		goto out;2470 2471	ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &2472	    MPI2_IOCSTATUS_MASK;2473	if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {2474		dcprintk(ioc,2475		    ioc_err(ioc,2476		    "%s: Failed to get trigger pg3, ioc_status(0x%04x)\n",2477		    __func__, ioc_status));2478		return -EFAULT;2479	}2480 2481	if (set) {2482		count = scsi_tg->ValidEntries;2483		tg_pg3.NumSCSISenseTrigger = cpu_to_le16(count);2484		for (i = 0; i < count; i++) {2485			tg_pg3.SCSISenseTriggers[i].ASCQ =2486			    scsi_tg->SCSITriggerEntry[i].ASCQ;2487			tg_pg3.SCSISenseTriggers[i].ASC =2488			    scsi_tg->SCSITriggerEntry[i].ASC;2489			tg_pg3.SCSISenseTriggers[i].SenseKey =2490			    scsi_tg->SCSITriggerEntry[i].SenseKey;2491		}2492	} else {2493		tg_pg3.NumSCSISenseTrigger = 0;2494		memset(&tg_pg3.SCSISenseTriggers[0], 0,2495		    NUM_VALID_ENTRIES * sizeof(2496		    MPI26_DRIVER_SCSI_SENSE_TRIGGER_ENTRY));2497	}2498 2499	rc = _config_set_driver_trigger_pg3(ioc, &mpi_reply, &tg_pg3);2500	if (rc)2501		goto out;2502 2503	ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &2504	    MPI2_IOCSTATUS_MASK;2505	if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {2506		dcprintk(ioc,2507		    ioc_err(ioc,2508		    "%s: Failed to get trigger pg3, ioc_status(0x%04x)\n",2509		     __func__, ioc_status));2510		return -EFAULT;2511	}2512 2513	return 0;2514out:2515	mpt3sas_config_update_driver_trigger_pg0(ioc,2516	    MPI26_DRIVER_TRIGGER0_FLAG_SCSI_SENSE_TRIGGER_VALID, !set);2517 2518	return rc;2519}2520 2521/**2522 * mpt3sas_config_get_driver_trigger_pg4 - obtain driver trigger page 42523 * @ioc: per adapter object2524 * @mpi_reply: reply mf payload returned from firmware2525 * @config_page: contents of the config page2526 * Context: sleep.2527 *2528 * Returns 0 for success, non-zero for failure.2529 */2530int2531mpt3sas_config_get_driver_trigger_pg4(struct MPT3SAS_ADAPTER *ioc,2532	Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage4_t *config_page)2533{2534	Mpi2ConfigRequest_t mpi_request;2535	int r;2536 2537	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));2538	mpi_request.Function = MPI2_FUNCTION_CONFIG;2539	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;2540	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;2541	mpi_request.ExtPageType =2542	    MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;2543	mpi_request.Header.PageNumber = 4;2544	mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE4_PAGEVERSION;2545	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);2546	r = _config_request(ioc, &mpi_request, mpi_reply,2547	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);2548	if (r)2549		goto out;2550 2551	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;2552	r = _config_request(ioc, &mpi_request, mpi_reply,2553	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,2554	    sizeof(*config_page));2555 out:2556	return r;2557}2558 2559/**2560 * _config_set_driver_trigger_pg4 - write driver trigger page 42561 * @ioc: per adapter object2562 * @mpi_reply: reply mf payload returned from firmware2563 * @config_page: contents of the config page2564 * Context: sleep.2565 *2566 * Returns 0 for success, non-zero for failure.2567 */2568static int2569_config_set_driver_trigger_pg4(struct MPT3SAS_ADAPTER *ioc,2570	Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage4_t *config_page)2571{2572	Mpi2ConfigRequest_t mpi_request;2573	int r;2574 2575	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));2576	mpi_request.Function = MPI2_FUNCTION_CONFIG;2577	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;2578	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;2579	mpi_request.ExtPageType =2580	    MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;2581	mpi_request.Header.PageNumber = 4;2582	mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE4_PAGEVERSION;2583	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);2584	r = _config_request(ioc, &mpi_request, mpi_reply,2585	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);2586	if (r)2587		goto out;2588 2589	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;2590	_config_request(ioc, &mpi_request, mpi_reply,2591	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,2592	    sizeof(*config_page));2593	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;2594	r = _config_request(ioc, &mpi_request, mpi_reply,2595	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,2596	    sizeof(*config_page));2597 out:2598	return r;2599}2600 2601/**2602 * mpt3sas_config_update_driver_trigger_pg4 - update driver trigger page 42603 * @ioc: per adapter object2604 * @mpi_tg: mpi trigger list2605 * @set: set ot clear trigger values2606 * Context: sleep.2607 *2608 * Returns 0 for success, non-zero for failure.2609 */2610int2611mpt3sas_config_update_driver_trigger_pg4(struct MPT3SAS_ADAPTER *ioc,2612	struct SL_WH_MPI_TRIGGERS_T *mpi_tg, bool set)2613{2614	Mpi26DriverTriggerPage4_t tg_pg4;2615	Mpi2ConfigReply_t mpi_reply;2616	int rc, i, count;2617	u16 ioc_status;2618 2619	rc = mpt3sas_config_update_driver_trigger_pg0(ioc,2620	    MPI26_DRIVER_TRIGGER0_FLAG_LOGINFO_TRIGGER_VALID, set);2621	if (rc)2622		return rc;2623 2624	rc = mpt3sas_config_get_driver_trigger_pg4(ioc, &mpi_reply, &tg_pg4);2625	if (rc)2626		goto out;2627 2628	ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &2629	    MPI2_IOCSTATUS_MASK;2630	if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {2631		dcprintk(ioc,2632		    ioc_err(ioc,2633		    "%s: Failed to get trigger pg4, ioc_status(0x%04x)\n",2634		    __func__, ioc_status));2635		rc = -EFAULT;2636		goto out;2637	}2638 2639	if (set) {2640		count = mpi_tg->ValidEntries;2641		tg_pg4.NumIOCStatusLogInfoTrigger = cpu_to_le16(count);2642		for (i = 0; i < count; i++) {2643			tg_pg4.IOCStatusLoginfoTriggers[i].IOCStatus =2644			    cpu_to_le16(mpi_tg->MPITriggerEntry[i].IOCStatus);2645			tg_pg4.IOCStatusLoginfoTriggers[i].LogInfo =2646			    cpu_to_le32(mpi_tg->MPITriggerEntry[i].IocLogInfo);2647		}2648	} else {2649		tg_pg4.NumIOCStatusLogInfoTrigger = 0;2650		memset(&tg_pg4.IOCStatusLoginfoTriggers[0], 0,2651		    NUM_VALID_ENTRIES * sizeof(2652		    MPI26_DRIVER_IOCSTATUS_LOGINFO_TRIGGER_ENTRY));2653	}2654 2655	rc = _config_set_driver_trigger_pg4(ioc, &mpi_reply, &tg_pg4);2656	if (rc)2657		goto out;2658 2659	ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &2660	    MPI2_IOCSTATUS_MASK;2661	if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {2662		dcprintk(ioc,2663		    ioc_err(ioc,2664		    "%s: Failed to get trigger pg4, ioc_status(0x%04x)\n",2665		    __func__, ioc_status));2666		rc = -EFAULT;2667		goto out;2668	}2669 2670	return 0;2671 2672out:2673	mpt3sas_config_update_driver_trigger_pg0(ioc,2674	    MPI26_DRIVER_TRIGGER0_FLAG_LOGINFO_TRIGGER_VALID, !set);2675 2676	return rc;2677}2678 2679/**2680 * mpt3sas_config_get_volume_handle - returns volume handle for give hidden2681 * raid components2682 * @ioc: per adapter object2683 * @pd_handle: phys disk handle2684 * @volume_handle: volume handle2685 * Context: sleep.2686 *2687 * Return: 0 for success, non-zero for failure.2688 */2689int2690mpt3sas_config_get_volume_handle(struct MPT3SAS_ADAPTER *ioc, u16 pd_handle,2691	u16 *volume_handle)2692{2693	Mpi2RaidConfigurationPage0_t *config_page = NULL;2694	Mpi2ConfigRequest_t mpi_request;2695	Mpi2ConfigReply_t mpi_reply;2696	int r, i, config_page_sz;2697	u16 ioc_status;2698	int config_num;2699	u16 element_type;2700	u16 phys_disk_dev_handle;2701 2702	*volume_handle = 0;2703	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));2704	mpi_request.Function = MPI2_FUNCTION_CONFIG;2705	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;2706	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;2707	mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_RAID_CONFIG;2708	mpi_request.Header.PageVersion = MPI2_RAIDCONFIG0_PAGEVERSION;2709	mpi_request.Header.PageNumber = 0;2710	ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);2711	r = _config_request(ioc, &mpi_request, &mpi_reply,2712	    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);2713	if (r)2714		goto out;2715 2716	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;2717	config_page_sz = (le16_to_cpu(mpi_reply.ExtPageLength) * 4);2718	config_page = kmalloc(config_page_sz, GFP_KERNEL);2719	if (!config_page) {2720		r = -1;2721		goto out;2722	}2723 2724	config_num = 0xff;2725	while (1) {2726		mpi_request.PageAddress = cpu_to_le32(config_num +2727		    MPI2_RAID_PGAD_FORM_GET_NEXT_CONFIGNUM);2728		r = _config_request(ioc, &mpi_request, &mpi_reply,2729		    MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,2730		    config_page_sz);2731		if (r)2732			goto out;2733		r = -1;2734		ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &2735		    MPI2_IOCSTATUS_MASK;2736		if (ioc_status != MPI2_IOCSTATUS_SUCCESS)2737			goto out;2738		for (i = 0; i < config_page->NumElements; i++) {2739			element_type = le16_to_cpu(config_page->2740			    ConfigElement[i].ElementFlags) &2741			    MPI2_RAIDCONFIG0_EFLAGS_MASK_ELEMENT_TYPE;2742			if (element_type ==2743			    MPI2_RAIDCONFIG0_EFLAGS_VOL_PHYS_DISK_ELEMENT ||2744			    element_type ==2745			    MPI2_RAIDCONFIG0_EFLAGS_OCE_ELEMENT) {2746				phys_disk_dev_handle =2747				    le16_to_cpu(config_page->ConfigElement[i].2748				    PhysDiskDevHandle);2749				if (phys_disk_dev_handle == pd_handle) {2750					*volume_handle =2751					    le16_to_cpu(config_page->2752					    ConfigElement[i].VolDevHandle);2753					r = 0;2754					goto out;2755				}2756			} else if (element_type ==2757			    MPI2_RAIDCONFIG0_EFLAGS_HOT_SPARE_ELEMENT) {2758				*volume_handle = 0;2759				r = 0;2760				goto out;2761			}2762		}2763		config_num = config_page->ConfigNum;2764	}2765 out:2766	kfree(config_page);2767	return r;2768}2769 2770/**2771 * mpt3sas_config_get_volume_wwid - returns wwid given the volume handle2772 * @ioc: per adapter object2773 * @volume_handle: volume handle2774 * @wwid: volume wwid2775 * Context: sleep.2776 *2777 * Return: 0 for success, non-zero for failure.2778 */2779int2780mpt3sas_config_get_volume_wwid(struct MPT3SAS_ADAPTER *ioc, u16 volume_handle,2781	u64 *wwid)2782{2783	Mpi2ConfigReply_t mpi_reply;2784	Mpi2RaidVolPage1_t raid_vol_pg1;2785 2786	*wwid = 0;2787	if (!(mpt3sas_config_get_raid_volume_pg1(ioc, &mpi_reply,2788	    &raid_vol_pg1, MPI2_RAID_VOLUME_PGAD_FORM_HANDLE,2789	    volume_handle))) {2790		*wwid = le64_to_cpu(raid_vol_pg1.WWID);2791		return 0;2792	} else2793		return -1;2794}2795