mpt3sas_config.c 86 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794
  1. /*
  2. * This module provides common API for accessing firmware configuration pages
  3. *
  4. * This code is based on drivers/scsi/mpt3sas/mpt3sas_base.c
  5. * Copyright (C) 2012-2014 LSI Corporation
  6. * Copyright (C) 2013-2014 Avago Technologies
  7. * (mailto: [email protected])
  8. *
  9. * This program is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU General Public License
  11. * as published by the Free Software Foundation; either version 2
  12. * 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 of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * NO WARRANTY
  20. * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
  21. * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
  22. * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
  23. * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
  24. * solely responsible for determining the appropriateness of using and
  25. * distributing the Program and assumes all risks associated with its
  26. * exercise of rights under this Agreement, including but not limited to
  27. * the risks and costs of program errors, damage to or loss of data,
  28. * programs or equipment, and unavailability or interruption of operations.
  29. * DISCLAIMER OF LIABILITY
  30. * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
  31. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  32. * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
  33. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
  34. * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
  35. * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
  36. * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
  37. * You should have received a copy of the GNU General Public License
  38. * along with this program; if not, write to the Free Software
  39. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
  40. * USA.
  41. */
  42. #include <linux/module.h>
  43. #include <linux/kernel.h>
  44. #include <linux/init.h>
  45. #include <linux/errno.h>
  46. #include <linux/blkdev.h>
  47. #include <linux/sched.h>
  48. #include <linux/workqueue.h>
  49. #include <linux/delay.h>
  50. #include <linux/pci.h>
  51. #include "mpt3sas_base.h"
  52. /* local definitions */
  53. /* Timeout for config page request (in seconds) */
  54. #define MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT 15
  55. /* Common sgl flags for READING a config page. */
  56. #define MPT3_CONFIG_COMMON_SGLFLAGS ((MPI2_SGE_FLAGS_SIMPLE_ELEMENT | \
  57. MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER \
  58. | MPI2_SGE_FLAGS_END_OF_LIST) << MPI2_SGE_FLAGS_SHIFT)
  59. /* Common sgl flags for WRITING a config page. */
  60. #define MPT3_CONFIG_COMMON_WRITE_SGLFLAGS ((MPI2_SGE_FLAGS_SIMPLE_ELEMENT | \
  61. MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER \
  62. | MPI2_SGE_FLAGS_END_OF_LIST | MPI2_SGE_FLAGS_HOST_TO_IOC) \
  63. << MPI2_SGE_FLAGS_SHIFT)
  64. /**
  65. * struct config_request - obtain dma memory via routine
  66. * @sz: size
  67. * @page: virt pointer
  68. * @page_dma: phys pointer
  69. *
  70. */
  71. struct config_request {
  72. u16 sz;
  73. void *page;
  74. dma_addr_t page_dma;
  75. };
  76. /**
  77. * _config_display_some_debug - debug routine
  78. * @ioc: per adapter object
  79. * @smid: system request message index
  80. * @calling_function_name: string pass from calling function
  81. * @mpi_reply: reply message frame
  82. * Context: none.
  83. *
  84. * Function for displaying debug info helpful when debugging issues
  85. * in this module.
  86. */
  87. static void
  88. _config_display_some_debug(struct MPT3SAS_ADAPTER *ioc, u16 smid,
  89. char *calling_function_name, MPI2DefaultReply_t *mpi_reply)
  90. {
  91. Mpi2ConfigRequest_t *mpi_request;
  92. char *desc = NULL;
  93. mpi_request = mpt3sas_base_get_msg_frame(ioc, smid);
  94. switch (mpi_request->Header.PageType & MPI2_CONFIG_PAGETYPE_MASK) {
  95. case MPI2_CONFIG_PAGETYPE_IO_UNIT:
  96. desc = "io_unit";
  97. break;
  98. case MPI2_CONFIG_PAGETYPE_IOC:
  99. desc = "ioc";
  100. break;
  101. case MPI2_CONFIG_PAGETYPE_BIOS:
  102. desc = "bios";
  103. break;
  104. case MPI2_CONFIG_PAGETYPE_RAID_VOLUME:
  105. desc = "raid_volume";
  106. break;
  107. case MPI2_CONFIG_PAGETYPE_MANUFACTURING:
  108. desc = "manufacturing";
  109. break;
  110. case MPI2_CONFIG_PAGETYPE_RAID_PHYSDISK:
  111. desc = "physdisk";
  112. break;
  113. case MPI2_CONFIG_PAGETYPE_EXTENDED:
  114. switch (mpi_request->ExtPageType) {
  115. case MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT:
  116. desc = "sas_io_unit";
  117. break;
  118. case MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER:
  119. desc = "sas_expander";
  120. break;
  121. case MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE:
  122. desc = "sas_device";
  123. break;
  124. case MPI2_CONFIG_EXTPAGETYPE_SAS_PHY:
  125. desc = "sas_phy";
  126. break;
  127. case MPI2_CONFIG_EXTPAGETYPE_LOG:
  128. desc = "log";
  129. break;
  130. case MPI2_CONFIG_EXTPAGETYPE_ENCLOSURE:
  131. desc = "enclosure";
  132. break;
  133. case MPI2_CONFIG_EXTPAGETYPE_RAID_CONFIG:
  134. desc = "raid_config";
  135. break;
  136. case MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING:
  137. desc = "driver_mapping";
  138. break;
  139. case MPI2_CONFIG_EXTPAGETYPE_SAS_PORT:
  140. desc = "sas_port";
  141. break;
  142. case MPI2_CONFIG_EXTPAGETYPE_EXT_MANUFACTURING:
  143. desc = "ext_manufacturing";
  144. break;
  145. case MPI2_CONFIG_EXTPAGETYPE_PCIE_IO_UNIT:
  146. desc = "pcie_io_unit";
  147. break;
  148. case MPI2_CONFIG_EXTPAGETYPE_PCIE_SWITCH:
  149. desc = "pcie_switch";
  150. break;
  151. case MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE:
  152. desc = "pcie_device";
  153. break;
  154. case MPI2_CONFIG_EXTPAGETYPE_PCIE_LINK:
  155. desc = "pcie_link";
  156. break;
  157. }
  158. break;
  159. }
  160. if (!desc)
  161. return;
  162. ioc_info(ioc, "%s: %s(%d), action(%d), form(0x%08x), smid(%d)\n",
  163. calling_function_name, desc,
  164. mpi_request->Header.PageNumber, mpi_request->Action,
  165. le32_to_cpu(mpi_request->PageAddress), smid);
  166. if (!mpi_reply)
  167. return;
  168. if (mpi_reply->IOCStatus || mpi_reply->IOCLogInfo)
  169. ioc_info(ioc, "\tiocstatus(0x%04x), loginfo(0x%08x)\n",
  170. le16_to_cpu(mpi_reply->IOCStatus),
  171. le32_to_cpu(mpi_reply->IOCLogInfo));
  172. }
  173. /**
  174. * _config_alloc_config_dma_memory - obtain physical memory
  175. * @ioc: per adapter object
  176. * @mem: struct config_request
  177. *
  178. * A wrapper for obtaining dma-able memory for config page request.
  179. *
  180. * Return: 0 for success, non-zero for failure.
  181. */
  182. static int
  183. _config_alloc_config_dma_memory(struct MPT3SAS_ADAPTER *ioc,
  184. struct config_request *mem)
  185. {
  186. int r = 0;
  187. if (mem->sz > ioc->config_page_sz) {
  188. mem->page = dma_alloc_coherent(&ioc->pdev->dev, mem->sz,
  189. &mem->page_dma, GFP_KERNEL);
  190. if (!mem->page) {
  191. ioc_err(ioc, "%s: dma_alloc_coherent failed asking for (%d) bytes!!\n",
  192. __func__, mem->sz);
  193. r = -ENOMEM;
  194. }
  195. } else { /* use tmp buffer if less than 512 bytes */
  196. mem->page = ioc->config_page;
  197. mem->page_dma = ioc->config_page_dma;
  198. }
  199. ioc->config_vaddr = mem->page;
  200. return r;
  201. }
  202. /**
  203. * _config_free_config_dma_memory - wrapper to free the memory
  204. * @ioc: per adapter object
  205. * @mem: struct config_request
  206. *
  207. * A wrapper to free dma-able memory when using _config_alloc_config_dma_memory.
  208. *
  209. * Return: 0 for success, non-zero for failure.
  210. */
  211. static void
  212. _config_free_config_dma_memory(struct MPT3SAS_ADAPTER *ioc,
  213. struct config_request *mem)
  214. {
  215. if (mem->sz > ioc->config_page_sz)
  216. dma_free_coherent(&ioc->pdev->dev, mem->sz, mem->page,
  217. mem->page_dma);
  218. }
  219. /**
  220. * mpt3sas_config_done - config page completion routine
  221. * @ioc: per adapter object
  222. * @smid: system request message index
  223. * @msix_index: MSIX table index supplied by the OS
  224. * @reply: reply message frame(lower 32bit addr)
  225. * Context: none.
  226. *
  227. * The callback handler when using _config_request.
  228. *
  229. * Return: 1 meaning mf should be freed from _base_interrupt
  230. * 0 means the mf is freed from this function.
  231. */
  232. u8
  233. mpt3sas_config_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
  234. u32 reply)
  235. {
  236. MPI2DefaultReply_t *mpi_reply;
  237. if (ioc->config_cmds.status == MPT3_CMD_NOT_USED)
  238. return 1;
  239. if (ioc->config_cmds.smid != smid)
  240. return 1;
  241. ioc->config_cmds.status |= MPT3_CMD_COMPLETE;
  242. mpi_reply = mpt3sas_base_get_reply_virt_addr(ioc, reply);
  243. if (mpi_reply) {
  244. ioc->config_cmds.status |= MPT3_CMD_REPLY_VALID;
  245. memcpy(ioc->config_cmds.reply, mpi_reply,
  246. mpi_reply->MsgLength*4);
  247. }
  248. ioc->config_cmds.status &= ~MPT3_CMD_PENDING;
  249. if (ioc->logging_level & MPT_DEBUG_CONFIG)
  250. _config_display_some_debug(ioc, smid, "config_done", mpi_reply);
  251. ioc->config_cmds.smid = USHRT_MAX;
  252. complete(&ioc->config_cmds.done);
  253. return 1;
  254. }
  255. /**
  256. * _config_request - main routine for sending config page requests
  257. * @ioc: per adapter object
  258. * @mpi_request: request message frame
  259. * @mpi_reply: reply mf payload returned from firmware
  260. * @timeout: timeout in seconds
  261. * @config_page: contents of the config page
  262. * @config_page_sz: size of config page
  263. * Context: sleep
  264. *
  265. * A generic API for config page requests to firmware.
  266. *
  267. * The ioc->config_cmds.status flag should be MPT3_CMD_NOT_USED before calling
  268. * this API.
  269. *
  270. * The callback index is set inside `ioc->config_cb_idx.
  271. *
  272. * Return: 0 for success, non-zero for failure.
  273. */
  274. static int
  275. _config_request(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigRequest_t
  276. *mpi_request, Mpi2ConfigReply_t *mpi_reply, int timeout,
  277. void *config_page, u16 config_page_sz)
  278. {
  279. u16 smid;
  280. Mpi2ConfigRequest_t *config_request;
  281. int r;
  282. u8 retry_count, issue_host_reset = 0;
  283. struct config_request mem;
  284. u32 ioc_status = UINT_MAX;
  285. mutex_lock(&ioc->config_cmds.mutex);
  286. if (ioc->config_cmds.status != MPT3_CMD_NOT_USED) {
  287. ioc_err(ioc, "%s: config_cmd in use\n", __func__);
  288. mutex_unlock(&ioc->config_cmds.mutex);
  289. return -EAGAIN;
  290. }
  291. retry_count = 0;
  292. memset(&mem, 0, sizeof(struct config_request));
  293. mpi_request->VF_ID = 0; /* TODO */
  294. mpi_request->VP_ID = 0;
  295. if (config_page) {
  296. mpi_request->Header.PageVersion = mpi_reply->Header.PageVersion;
  297. mpi_request->Header.PageNumber = mpi_reply->Header.PageNumber;
  298. mpi_request->Header.PageType = mpi_reply->Header.PageType;
  299. mpi_request->Header.PageLength = mpi_reply->Header.PageLength;
  300. mpi_request->ExtPageLength = mpi_reply->ExtPageLength;
  301. mpi_request->ExtPageType = mpi_reply->ExtPageType;
  302. if (mpi_request->Header.PageLength)
  303. mem.sz = mpi_request->Header.PageLength * 4;
  304. else
  305. mem.sz = le16_to_cpu(mpi_reply->ExtPageLength) * 4;
  306. r = _config_alloc_config_dma_memory(ioc, &mem);
  307. if (r != 0)
  308. goto out;
  309. if (mpi_request->Action ==
  310. MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT ||
  311. mpi_request->Action ==
  312. MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM) {
  313. ioc->base_add_sg_single(&mpi_request->PageBufferSGE,
  314. MPT3_CONFIG_COMMON_WRITE_SGLFLAGS | mem.sz,
  315. mem.page_dma);
  316. memcpy(mem.page, config_page, min_t(u16, mem.sz,
  317. config_page_sz));
  318. } else {
  319. memset(config_page, 0, config_page_sz);
  320. ioc->base_add_sg_single(&mpi_request->PageBufferSGE,
  321. MPT3_CONFIG_COMMON_SGLFLAGS | mem.sz, mem.page_dma);
  322. memset(mem.page, 0, min_t(u16, mem.sz, config_page_sz));
  323. }
  324. }
  325. retry_config:
  326. if (retry_count) {
  327. if (retry_count > 2) { /* attempt only 2 retries */
  328. r = -EFAULT;
  329. goto free_mem;
  330. }
  331. ioc_info(ioc, "%s: attempting retry (%d)\n",
  332. __func__, retry_count);
  333. }
  334. r = mpt3sas_wait_for_ioc(ioc, MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT);
  335. if (r) {
  336. if (r == -ETIME)
  337. issue_host_reset = 1;
  338. goto free_mem;
  339. }
  340. smid = mpt3sas_base_get_smid(ioc, ioc->config_cb_idx);
  341. if (!smid) {
  342. ioc_err(ioc, "%s: failed obtaining a smid\n", __func__);
  343. ioc->config_cmds.status = MPT3_CMD_NOT_USED;
  344. r = -EAGAIN;
  345. goto free_mem;
  346. }
  347. r = 0;
  348. memset(ioc->config_cmds.reply, 0, sizeof(Mpi2ConfigReply_t));
  349. ioc->config_cmds.status = MPT3_CMD_PENDING;
  350. config_request = mpt3sas_base_get_msg_frame(ioc, smid);
  351. ioc->config_cmds.smid = smid;
  352. memcpy(config_request, mpi_request, sizeof(Mpi2ConfigRequest_t));
  353. if (ioc->logging_level & MPT_DEBUG_CONFIG)
  354. _config_display_some_debug(ioc, smid, "config_request", NULL);
  355. init_completion(&ioc->config_cmds.done);
  356. ioc->put_smid_default(ioc, smid);
  357. wait_for_completion_timeout(&ioc->config_cmds.done, timeout*HZ);
  358. if (!(ioc->config_cmds.status & MPT3_CMD_COMPLETE)) {
  359. if (!(ioc->logging_level & MPT_DEBUG_CONFIG))
  360. _config_display_some_debug(ioc,
  361. smid, "config_request", NULL);
  362. ioc_err(ioc, "%s: command timeout\n", __func__);
  363. mpt3sas_base_check_cmd_timeout(ioc, ioc->config_cmds.status,
  364. mpi_request, sizeof(Mpi2ConfigRequest_t) / 4);
  365. retry_count++;
  366. if (ioc->config_cmds.smid == smid)
  367. mpt3sas_base_free_smid(ioc, smid);
  368. if (ioc->config_cmds.status & MPT3_CMD_RESET)
  369. goto retry_config;
  370. if (ioc->shost_recovery || ioc->pci_error_recovery) {
  371. issue_host_reset = 0;
  372. r = -EFAULT;
  373. } else
  374. issue_host_reset = 1;
  375. goto free_mem;
  376. }
  377. if (ioc->config_cmds.status & MPT3_CMD_REPLY_VALID) {
  378. memcpy(mpi_reply, ioc->config_cmds.reply,
  379. sizeof(Mpi2ConfigReply_t));
  380. /* Reply Frame Sanity Checks to workaround FW issues */
  381. if ((mpi_request->Header.PageType & 0xF) !=
  382. (mpi_reply->Header.PageType & 0xF)) {
  383. if (!(ioc->logging_level & MPT_DEBUG_CONFIG))
  384. _config_display_some_debug(ioc,
  385. smid, "config_request", NULL);
  386. _debug_dump_mf(mpi_request, ioc->request_sz/4);
  387. _debug_dump_reply(mpi_reply, ioc->reply_sz/4);
  388. panic("%s: %s: Firmware BUG: mpi_reply mismatch: Requested PageType(0x%02x) Reply PageType(0x%02x)\n",
  389. ioc->name, __func__,
  390. mpi_request->Header.PageType & 0xF,
  391. mpi_reply->Header.PageType & 0xF);
  392. }
  393. if (((mpi_request->Header.PageType & 0xF) ==
  394. MPI2_CONFIG_PAGETYPE_EXTENDED) &&
  395. mpi_request->ExtPageType != mpi_reply->ExtPageType) {
  396. if (!(ioc->logging_level & MPT_DEBUG_CONFIG))
  397. _config_display_some_debug(ioc,
  398. smid, "config_request", NULL);
  399. _debug_dump_mf(mpi_request, ioc->request_sz/4);
  400. _debug_dump_reply(mpi_reply, ioc->reply_sz/4);
  401. panic("%s: %s: Firmware BUG: mpi_reply mismatch: Requested ExtPageType(0x%02x) Reply ExtPageType(0x%02x)\n",
  402. ioc->name, __func__,
  403. mpi_request->ExtPageType,
  404. mpi_reply->ExtPageType);
  405. }
  406. ioc_status = le16_to_cpu(mpi_reply->IOCStatus)
  407. & MPI2_IOCSTATUS_MASK;
  408. }
  409. if (retry_count)
  410. ioc_info(ioc, "%s: retry (%d) completed!!\n",
  411. __func__, retry_count);
  412. if ((ioc_status == MPI2_IOCSTATUS_SUCCESS) &&
  413. config_page && mpi_request->Action ==
  414. MPI2_CONFIG_ACTION_PAGE_READ_CURRENT) {
  415. u8 *p = (u8 *)mem.page;
  416. /* Config Page Sanity Checks to workaround FW issues */
  417. if (p) {
  418. if ((mpi_request->Header.PageType & 0xF) !=
  419. (p[3] & 0xF)) {
  420. if (!(ioc->logging_level & MPT_DEBUG_CONFIG))
  421. _config_display_some_debug(ioc,
  422. smid, "config_request", NULL);
  423. _debug_dump_mf(mpi_request, ioc->request_sz/4);
  424. _debug_dump_reply(mpi_reply, ioc->reply_sz/4);
  425. _debug_dump_config(p, min_t(u16, mem.sz,
  426. config_page_sz)/4);
  427. panic("%s: %s: Firmware BUG: config page mismatch: Requested PageType(0x%02x) Reply PageType(0x%02x)\n",
  428. ioc->name, __func__,
  429. mpi_request->Header.PageType & 0xF,
  430. p[3] & 0xF);
  431. }
  432. if (((mpi_request->Header.PageType & 0xF) ==
  433. MPI2_CONFIG_PAGETYPE_EXTENDED) &&
  434. (mpi_request->ExtPageType != p[6])) {
  435. if (!(ioc->logging_level & MPT_DEBUG_CONFIG))
  436. _config_display_some_debug(ioc,
  437. smid, "config_request", NULL);
  438. _debug_dump_mf(mpi_request, ioc->request_sz/4);
  439. _debug_dump_reply(mpi_reply, ioc->reply_sz/4);
  440. _debug_dump_config(p, min_t(u16, mem.sz,
  441. config_page_sz)/4);
  442. panic("%s: %s: Firmware BUG: config page mismatch: Requested ExtPageType(0x%02x) Reply ExtPageType(0x%02x)\n",
  443. ioc->name, __func__,
  444. mpi_request->ExtPageType, p[6]);
  445. }
  446. }
  447. memcpy(config_page, mem.page, min_t(u16, mem.sz,
  448. config_page_sz));
  449. }
  450. free_mem:
  451. if (config_page)
  452. _config_free_config_dma_memory(ioc, &mem);
  453. out:
  454. ioc->config_cmds.status = MPT3_CMD_NOT_USED;
  455. mutex_unlock(&ioc->config_cmds.mutex);
  456. if (issue_host_reset) {
  457. if (ioc->drv_internal_flags & MPT_DRV_INTERNAL_FIRST_PE_ISSUED) {
  458. mpt3sas_base_hard_reset_handler(ioc, FORCE_BIG_HAMMER);
  459. r = -EFAULT;
  460. } else {
  461. if (mpt3sas_base_check_for_fault_and_issue_reset(ioc))
  462. return -EFAULT;
  463. r = -EAGAIN;
  464. }
  465. }
  466. return r;
  467. }
  468. /**
  469. * mpt3sas_config_get_manufacturing_pg0 - obtain manufacturing page 0
  470. * @ioc: per adapter object
  471. * @mpi_reply: reply mf payload returned from firmware
  472. * @config_page: contents of the config page
  473. * Context: sleep.
  474. *
  475. * Return: 0 for success, non-zero for failure.
  476. */
  477. int
  478. mpt3sas_config_get_manufacturing_pg0(struct MPT3SAS_ADAPTER *ioc,
  479. Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage0_t *config_page)
  480. {
  481. Mpi2ConfigRequest_t mpi_request;
  482. int r;
  483. memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  484. mpi_request.Function = MPI2_FUNCTION_CONFIG;
  485. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  486. mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;
  487. mpi_request.Header.PageNumber = 0;
  488. mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION;
  489. ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
  490. r = _config_request(ioc, &mpi_request, mpi_reply,
  491. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
  492. if (r)
  493. goto out;
  494. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
  495. r = _config_request(ioc, &mpi_request, mpi_reply,
  496. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
  497. sizeof(*config_page));
  498. out:
  499. return r;
  500. }
  501. /**
  502. * mpt3sas_config_get_manufacturing_pg1 - obtain manufacturing page 1
  503. * @ioc: per adapter object
  504. * @mpi_reply: reply mf payload returned from firmware
  505. * @config_page: contents of the config page
  506. * Context: sleep.
  507. *
  508. * Return: 0 for success, non-zero for failure.
  509. */
  510. int
  511. mpt3sas_config_get_manufacturing_pg1(struct MPT3SAS_ADAPTER *ioc,
  512. Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage1_t *config_page)
  513. {
  514. Mpi2ConfigRequest_t mpi_request;
  515. int r;
  516. memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  517. mpi_request.Function = MPI2_FUNCTION_CONFIG;
  518. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  519. mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;
  520. mpi_request.Header.PageNumber = 1;
  521. mpi_request.Header.PageVersion = MPI2_MANUFACTURING1_PAGEVERSION;
  522. ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
  523. r = _config_request(ioc, &mpi_request, mpi_reply,
  524. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
  525. if (r)
  526. goto out;
  527. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
  528. r = _config_request(ioc, &mpi_request, mpi_reply,
  529. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
  530. sizeof(*config_page));
  531. out:
  532. return r;
  533. }
  534. /**
  535. * mpt3sas_config_get_manufacturing_pg7 - obtain manufacturing page 7
  536. * @ioc: per adapter object
  537. * @mpi_reply: reply mf payload returned from firmware
  538. * @config_page: contents of the config page
  539. * @sz: size of buffer passed in config_page
  540. * Context: sleep.
  541. *
  542. * Return: 0 for success, non-zero for failure.
  543. */
  544. int
  545. mpt3sas_config_get_manufacturing_pg7(struct MPT3SAS_ADAPTER *ioc,
  546. Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage7_t *config_page,
  547. u16 sz)
  548. {
  549. Mpi2ConfigRequest_t mpi_request;
  550. int r;
  551. memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  552. mpi_request.Function = MPI2_FUNCTION_CONFIG;
  553. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  554. mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;
  555. mpi_request.Header.PageNumber = 7;
  556. mpi_request.Header.PageVersion = MPI2_MANUFACTURING7_PAGEVERSION;
  557. ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
  558. r = _config_request(ioc, &mpi_request, mpi_reply,
  559. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
  560. if (r)
  561. goto out;
  562. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
  563. r = _config_request(ioc, &mpi_request, mpi_reply,
  564. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
  565. sz);
  566. out:
  567. return r;
  568. }
  569. /**
  570. * mpt3sas_config_get_manufacturing_pg10 - obtain manufacturing page 10
  571. * @ioc: per adapter object
  572. * @mpi_reply: reply mf payload returned from firmware
  573. * @config_page: contents of the config page
  574. * Context: sleep.
  575. *
  576. * Return: 0 for success, non-zero for failure.
  577. */
  578. int
  579. mpt3sas_config_get_manufacturing_pg10(struct MPT3SAS_ADAPTER *ioc,
  580. Mpi2ConfigReply_t *mpi_reply,
  581. struct Mpi2ManufacturingPage10_t *config_page)
  582. {
  583. Mpi2ConfigRequest_t mpi_request;
  584. int r;
  585. memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  586. mpi_request.Function = MPI2_FUNCTION_CONFIG;
  587. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  588. mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;
  589. mpi_request.Header.PageNumber = 10;
  590. mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION;
  591. ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
  592. r = _config_request(ioc, &mpi_request, mpi_reply,
  593. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
  594. if (r)
  595. goto out;
  596. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
  597. r = _config_request(ioc, &mpi_request, mpi_reply,
  598. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
  599. sizeof(*config_page));
  600. out:
  601. return r;
  602. }
  603. /**
  604. * mpt3sas_config_get_manufacturing_pg11 - obtain manufacturing page 11
  605. * @ioc: per adapter object
  606. * @mpi_reply: reply mf payload returned from firmware
  607. * @config_page: contents of the config page
  608. * Context: sleep.
  609. *
  610. * Return: 0 for success, non-zero for failure.
  611. */
  612. int
  613. mpt3sas_config_get_manufacturing_pg11(struct MPT3SAS_ADAPTER *ioc,
  614. Mpi2ConfigReply_t *mpi_reply,
  615. struct Mpi2ManufacturingPage11_t *config_page)
  616. {
  617. Mpi2ConfigRequest_t mpi_request;
  618. int r;
  619. memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  620. mpi_request.Function = MPI2_FUNCTION_CONFIG;
  621. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  622. mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;
  623. mpi_request.Header.PageNumber = 11;
  624. mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION;
  625. ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
  626. r = _config_request(ioc, &mpi_request, mpi_reply,
  627. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
  628. if (r)
  629. goto out;
  630. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
  631. r = _config_request(ioc, &mpi_request, mpi_reply,
  632. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
  633. sizeof(*config_page));
  634. out:
  635. return r;
  636. }
  637. /**
  638. * mpt3sas_config_set_manufacturing_pg11 - set manufacturing page 11
  639. * @ioc: per adapter object
  640. * @mpi_reply: reply mf payload returned from firmware
  641. * @config_page: contents of the config page
  642. * Context: sleep.
  643. *
  644. * Return: 0 for success, non-zero for failure.
  645. */
  646. int
  647. mpt3sas_config_set_manufacturing_pg11(struct MPT3SAS_ADAPTER *ioc,
  648. Mpi2ConfigReply_t *mpi_reply,
  649. struct Mpi2ManufacturingPage11_t *config_page)
  650. {
  651. Mpi2ConfigRequest_t mpi_request;
  652. int r;
  653. memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  654. mpi_request.Function = MPI2_FUNCTION_CONFIG;
  655. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  656. mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;
  657. mpi_request.Header.PageNumber = 11;
  658. mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION;
  659. ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
  660. r = _config_request(ioc, &mpi_request, mpi_reply,
  661. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
  662. if (r)
  663. goto out;
  664. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
  665. r = _config_request(ioc, &mpi_request, mpi_reply,
  666. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
  667. sizeof(*config_page));
  668. out:
  669. return r;
  670. }
  671. /**
  672. * mpt3sas_config_get_bios_pg2 - obtain bios page 2
  673. * @ioc: per adapter object
  674. * @mpi_reply: reply mf payload returned from firmware
  675. * @config_page: contents of the config page
  676. * Context: sleep.
  677. *
  678. * Return: 0 for success, non-zero for failure.
  679. */
  680. int
  681. mpt3sas_config_get_bios_pg2(struct MPT3SAS_ADAPTER *ioc,
  682. Mpi2ConfigReply_t *mpi_reply, Mpi2BiosPage2_t *config_page)
  683. {
  684. Mpi2ConfigRequest_t mpi_request;
  685. int r;
  686. memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  687. mpi_request.Function = MPI2_FUNCTION_CONFIG;
  688. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  689. mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS;
  690. mpi_request.Header.PageNumber = 2;
  691. mpi_request.Header.PageVersion = MPI2_BIOSPAGE2_PAGEVERSION;
  692. ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
  693. r = _config_request(ioc, &mpi_request, mpi_reply,
  694. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
  695. if (r)
  696. goto out;
  697. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
  698. r = _config_request(ioc, &mpi_request, mpi_reply,
  699. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
  700. sizeof(*config_page));
  701. out:
  702. return r;
  703. }
  704. /**
  705. * mpt3sas_config_get_bios_pg3 - obtain bios page 3
  706. * @ioc: per adapter object
  707. * @mpi_reply: reply mf payload returned from firmware
  708. * @config_page: contents of the config page
  709. * Context: sleep.
  710. *
  711. * Return: 0 for success, non-zero for failure.
  712. */
  713. int
  714. mpt3sas_config_get_bios_pg3(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
  715. *mpi_reply, Mpi2BiosPage3_t *config_page)
  716. {
  717. Mpi2ConfigRequest_t mpi_request;
  718. int r;
  719. memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  720. mpi_request.Function = MPI2_FUNCTION_CONFIG;
  721. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  722. mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS;
  723. mpi_request.Header.PageNumber = 3;
  724. mpi_request.Header.PageVersion = MPI2_BIOSPAGE3_PAGEVERSION;
  725. ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
  726. r = _config_request(ioc, &mpi_request, mpi_reply,
  727. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
  728. if (r)
  729. goto out;
  730. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
  731. r = _config_request(ioc, &mpi_request, mpi_reply,
  732. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
  733. sizeof(*config_page));
  734. out:
  735. return r;
  736. }
  737. /**
  738. * mpt3sas_config_set_bios_pg4 - write out bios page 4
  739. * @ioc: per adapter object
  740. * @mpi_reply: reply mf payload returned from firmware
  741. * @config_page: contents of the config page
  742. * @sz_config_pg: sizeof the config page
  743. * Context: sleep.
  744. *
  745. * Return: 0 for success, non-zero for failure.
  746. */
  747. int
  748. mpt3sas_config_set_bios_pg4(struct MPT3SAS_ADAPTER *ioc,
  749. Mpi2ConfigReply_t *mpi_reply, Mpi2BiosPage4_t *config_page,
  750. int sz_config_pg)
  751. {
  752. Mpi2ConfigRequest_t mpi_request;
  753. int r;
  754. memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  755. mpi_request.Function = MPI2_FUNCTION_CONFIG;
  756. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  757. mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS;
  758. mpi_request.Header.PageNumber = 4;
  759. mpi_request.Header.PageVersion = MPI2_BIOSPAGE4_PAGEVERSION;
  760. ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
  761. r = _config_request(ioc, &mpi_request, mpi_reply,
  762. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
  763. if (r)
  764. goto out;
  765. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
  766. r = _config_request(ioc, &mpi_request, mpi_reply,
  767. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
  768. sz_config_pg);
  769. out:
  770. return r;
  771. }
  772. /**
  773. * mpt3sas_config_get_bios_pg4 - read bios page 4
  774. * @ioc: per adapter object
  775. * @mpi_reply: reply mf payload returned from firmware
  776. * @config_page: contents of the config page
  777. * @sz_config_pg: sizeof the config page
  778. * Context: sleep.
  779. *
  780. * Return: 0 for success, non-zero for failure.
  781. */
  782. int
  783. mpt3sas_config_get_bios_pg4(struct MPT3SAS_ADAPTER *ioc,
  784. Mpi2ConfigReply_t *mpi_reply, Mpi2BiosPage4_t *config_page,
  785. int sz_config_pg)
  786. {
  787. Mpi2ConfigRequest_t mpi_request;
  788. int r;
  789. memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  790. mpi_request.Function = MPI2_FUNCTION_CONFIG;
  791. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  792. mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS;
  793. mpi_request.Header.PageNumber = 4;
  794. mpi_request.Header.PageVersion = MPI2_BIOSPAGE4_PAGEVERSION;
  795. ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
  796. r = _config_request(ioc, &mpi_request, mpi_reply,
  797. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
  798. if (r)
  799. goto out;
  800. /*
  801. * The sizeof the page is variable. Allow for just the
  802. * size to be returned
  803. */
  804. if (config_page && sz_config_pg) {
  805. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
  806. r = _config_request(ioc, &mpi_request, mpi_reply,
  807. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
  808. sz_config_pg);
  809. }
  810. out:
  811. return r;
  812. }
  813. /**
  814. * mpt3sas_config_get_iounit_pg0 - obtain iounit page 0
  815. * @ioc: per adapter object
  816. * @mpi_reply: reply mf payload returned from firmware
  817. * @config_page: contents of the config page
  818. * Context: sleep.
  819. *
  820. * Return: 0 for success, non-zero for failure.
  821. */
  822. int
  823. mpt3sas_config_get_iounit_pg0(struct MPT3SAS_ADAPTER *ioc,
  824. Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage0_t *config_page)
  825. {
  826. Mpi2ConfigRequest_t mpi_request;
  827. int r;
  828. memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  829. mpi_request.Function = MPI2_FUNCTION_CONFIG;
  830. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  831. mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
  832. mpi_request.Header.PageNumber = 0;
  833. mpi_request.Header.PageVersion = MPI2_IOUNITPAGE0_PAGEVERSION;
  834. ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
  835. r = _config_request(ioc, &mpi_request, mpi_reply,
  836. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
  837. if (r)
  838. goto out;
  839. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
  840. r = _config_request(ioc, &mpi_request, mpi_reply,
  841. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
  842. sizeof(*config_page));
  843. out:
  844. return r;
  845. }
  846. /**
  847. * mpt3sas_config_get_iounit_pg1 - obtain iounit page 1
  848. * @ioc: per adapter object
  849. * @mpi_reply: reply mf payload returned from firmware
  850. * @config_page: contents of the config page
  851. * Context: sleep.
  852. *
  853. * Return: 0 for success, non-zero for failure.
  854. */
  855. int
  856. mpt3sas_config_get_iounit_pg1(struct MPT3SAS_ADAPTER *ioc,
  857. Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage1_t *config_page)
  858. {
  859. Mpi2ConfigRequest_t mpi_request;
  860. int r;
  861. memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  862. mpi_request.Function = MPI2_FUNCTION_CONFIG;
  863. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  864. mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
  865. mpi_request.Header.PageNumber = 1;
  866. mpi_request.Header.PageVersion = MPI2_IOUNITPAGE1_PAGEVERSION;
  867. ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
  868. r = _config_request(ioc, &mpi_request, mpi_reply,
  869. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
  870. if (r)
  871. goto out;
  872. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
  873. r = _config_request(ioc, &mpi_request, mpi_reply,
  874. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
  875. sizeof(*config_page));
  876. out:
  877. return r;
  878. }
  879. /**
  880. * mpt3sas_config_set_iounit_pg1 - set iounit page 1
  881. * @ioc: per adapter object
  882. * @mpi_reply: reply mf payload returned from firmware
  883. * @config_page: contents of the config page
  884. * Context: sleep.
  885. *
  886. * Return: 0 for success, non-zero for failure.
  887. */
  888. int
  889. mpt3sas_config_set_iounit_pg1(struct MPT3SAS_ADAPTER *ioc,
  890. Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage1_t *config_page)
  891. {
  892. Mpi2ConfigRequest_t mpi_request;
  893. int r;
  894. memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  895. mpi_request.Function = MPI2_FUNCTION_CONFIG;
  896. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  897. mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
  898. mpi_request.Header.PageNumber = 1;
  899. mpi_request.Header.PageVersion = MPI2_IOUNITPAGE1_PAGEVERSION;
  900. ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
  901. r = _config_request(ioc, &mpi_request, mpi_reply,
  902. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
  903. if (r)
  904. goto out;
  905. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
  906. r = _config_request(ioc, &mpi_request, mpi_reply,
  907. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
  908. sizeof(*config_page));
  909. out:
  910. return r;
  911. }
  912. /**
  913. * mpt3sas_config_get_iounit_pg3 - obtain iounit page 3
  914. * @ioc: per adapter object
  915. * @mpi_reply: reply mf payload returned from firmware
  916. * @config_page: contents of the config page
  917. * @sz: size of buffer passed in config_page
  918. * Context: sleep.
  919. *
  920. * Return: 0 for success, non-zero for failure.
  921. */
  922. int
  923. mpt3sas_config_get_iounit_pg3(struct MPT3SAS_ADAPTER *ioc,
  924. Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage3_t *config_page, u16 sz)
  925. {
  926. Mpi2ConfigRequest_t mpi_request;
  927. int r;
  928. memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  929. mpi_request.Function = MPI2_FUNCTION_CONFIG;
  930. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  931. mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
  932. mpi_request.Header.PageNumber = 3;
  933. mpi_request.Header.PageVersion = MPI2_IOUNITPAGE3_PAGEVERSION;
  934. ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
  935. r = _config_request(ioc, &mpi_request, mpi_reply,
  936. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
  937. if (r)
  938. goto out;
  939. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
  940. r = _config_request(ioc, &mpi_request, mpi_reply,
  941. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
  942. out:
  943. return r;
  944. }
  945. /**
  946. * mpt3sas_config_get_iounit_pg8 - obtain iounit page 8
  947. * @ioc: per adapter object
  948. * @mpi_reply: reply mf payload returned from firmware
  949. * @config_page: contents of the config page
  950. * Context: sleep.
  951. *
  952. * Return: 0 for success, non-zero for failure.
  953. */
  954. int
  955. mpt3sas_config_get_iounit_pg8(struct MPT3SAS_ADAPTER *ioc,
  956. Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage8_t *config_page)
  957. {
  958. Mpi2ConfigRequest_t mpi_request;
  959. int r;
  960. memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  961. mpi_request.Function = MPI2_FUNCTION_CONFIG;
  962. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  963. mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
  964. mpi_request.Header.PageNumber = 8;
  965. mpi_request.Header.PageVersion = MPI2_IOUNITPAGE8_PAGEVERSION;
  966. ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
  967. r = _config_request(ioc, &mpi_request, mpi_reply,
  968. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
  969. if (r)
  970. goto out;
  971. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
  972. r = _config_request(ioc, &mpi_request, mpi_reply,
  973. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
  974. sizeof(*config_page));
  975. out:
  976. return r;
  977. }
  978. /**
  979. * mpt3sas_config_get_ioc_pg8 - obtain ioc page 8
  980. * @ioc: per adapter object
  981. * @mpi_reply: reply mf payload returned from firmware
  982. * @config_page: contents of the config page
  983. * Context: sleep.
  984. *
  985. * Return: 0 for success, non-zero for failure.
  986. */
  987. int
  988. mpt3sas_config_get_ioc_pg8(struct MPT3SAS_ADAPTER *ioc,
  989. Mpi2ConfigReply_t *mpi_reply, Mpi2IOCPage8_t *config_page)
  990. {
  991. Mpi2ConfigRequest_t mpi_request;
  992. int r;
  993. memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  994. mpi_request.Function = MPI2_FUNCTION_CONFIG;
  995. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  996. mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IOC;
  997. mpi_request.Header.PageNumber = 8;
  998. mpi_request.Header.PageVersion = MPI2_IOCPAGE8_PAGEVERSION;
  999. ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
  1000. r = _config_request(ioc, &mpi_request, mpi_reply,
  1001. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
  1002. if (r)
  1003. goto out;
  1004. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
  1005. r = _config_request(ioc, &mpi_request, mpi_reply,
  1006. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
  1007. sizeof(*config_page));
  1008. out:
  1009. return r;
  1010. }
  1011. /**
  1012. * mpt3sas_config_get_ioc_pg1 - obtain ioc page 1
  1013. * @ioc: per adapter object
  1014. * @mpi_reply: reply mf payload returned from firmware
  1015. * @config_page: contents of the config page
  1016. * Context: sleep.
  1017. *
  1018. * Return: 0 for success, non-zero for failure.
  1019. */
  1020. int
  1021. mpt3sas_config_get_ioc_pg1(struct MPT3SAS_ADAPTER *ioc,
  1022. Mpi2ConfigReply_t *mpi_reply, Mpi2IOCPage1_t *config_page)
  1023. {
  1024. Mpi2ConfigRequest_t mpi_request;
  1025. int r;
  1026. memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  1027. mpi_request.Function = MPI2_FUNCTION_CONFIG;
  1028. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  1029. mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IOC;
  1030. mpi_request.Header.PageNumber = 1;
  1031. mpi_request.Header.PageVersion = MPI2_IOCPAGE8_PAGEVERSION;
  1032. ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
  1033. r = _config_request(ioc, &mpi_request, mpi_reply,
  1034. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
  1035. if (r)
  1036. goto out;
  1037. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
  1038. r = _config_request(ioc, &mpi_request, mpi_reply,
  1039. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
  1040. sizeof(*config_page));
  1041. out:
  1042. return r;
  1043. }
  1044. /**
  1045. * mpt3sas_config_set_ioc_pg1 - modify ioc page 1
  1046. * @ioc: per adapter object
  1047. * @mpi_reply: reply mf payload returned from firmware
  1048. * @config_page: contents of the config page
  1049. * Context: sleep.
  1050. *
  1051. * Return: 0 for success, non-zero for failure.
  1052. */
  1053. int
  1054. mpt3sas_config_set_ioc_pg1(struct MPT3SAS_ADAPTER *ioc,
  1055. Mpi2ConfigReply_t *mpi_reply, Mpi2IOCPage1_t *config_page)
  1056. {
  1057. Mpi2ConfigRequest_t mpi_request;
  1058. int r;
  1059. memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  1060. mpi_request.Function = MPI2_FUNCTION_CONFIG;
  1061. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  1062. mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IOC;
  1063. mpi_request.Header.PageNumber = 1;
  1064. mpi_request.Header.PageVersion = MPI2_IOCPAGE8_PAGEVERSION;
  1065. ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
  1066. r = _config_request(ioc, &mpi_request, mpi_reply,
  1067. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
  1068. if (r)
  1069. goto out;
  1070. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
  1071. r = _config_request(ioc, &mpi_request, mpi_reply,
  1072. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
  1073. sizeof(*config_page));
  1074. out:
  1075. return r;
  1076. }
  1077. /**
  1078. * mpt3sas_config_get_sas_device_pg0 - obtain sas device page 0
  1079. * @ioc: per adapter object
  1080. * @mpi_reply: reply mf payload returned from firmware
  1081. * @config_page: contents of the config page
  1082. * @form: GET_NEXT_HANDLE or HANDLE
  1083. * @handle: device handle
  1084. * Context: sleep.
  1085. *
  1086. * Return: 0 for success, non-zero for failure.
  1087. */
  1088. int
  1089. mpt3sas_config_get_sas_device_pg0(struct MPT3SAS_ADAPTER *ioc,
  1090. Mpi2ConfigReply_t *mpi_reply, Mpi2SasDevicePage0_t *config_page,
  1091. u32 form, u32 handle)
  1092. {
  1093. Mpi2ConfigRequest_t mpi_request;
  1094. int r;
  1095. memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  1096. mpi_request.Function = MPI2_FUNCTION_CONFIG;
  1097. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  1098. mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
  1099. mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE;
  1100. mpi_request.Header.PageVersion = MPI2_SASDEVICE0_PAGEVERSION;
  1101. mpi_request.Header.PageNumber = 0;
  1102. ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
  1103. r = _config_request(ioc, &mpi_request, mpi_reply,
  1104. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
  1105. if (r)
  1106. goto out;
  1107. mpi_request.PageAddress = cpu_to_le32(form | handle);
  1108. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
  1109. r = _config_request(ioc, &mpi_request, mpi_reply,
  1110. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
  1111. sizeof(*config_page));
  1112. out:
  1113. return r;
  1114. }
  1115. /**
  1116. * mpt3sas_config_get_sas_device_pg1 - obtain sas device page 1
  1117. * @ioc: per adapter object
  1118. * @mpi_reply: reply mf payload returned from firmware
  1119. * @config_page: contents of the config page
  1120. * @form: GET_NEXT_HANDLE or HANDLE
  1121. * @handle: device handle
  1122. * Context: sleep.
  1123. *
  1124. * Return: 0 for success, non-zero for failure.
  1125. */
  1126. int
  1127. mpt3sas_config_get_sas_device_pg1(struct MPT3SAS_ADAPTER *ioc,
  1128. Mpi2ConfigReply_t *mpi_reply, Mpi2SasDevicePage1_t *config_page,
  1129. u32 form, u32 handle)
  1130. {
  1131. Mpi2ConfigRequest_t mpi_request;
  1132. int r;
  1133. memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  1134. mpi_request.Function = MPI2_FUNCTION_CONFIG;
  1135. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  1136. mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
  1137. mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE;
  1138. mpi_request.Header.PageVersion = MPI2_SASDEVICE1_PAGEVERSION;
  1139. mpi_request.Header.PageNumber = 1;
  1140. ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
  1141. r = _config_request(ioc, &mpi_request, mpi_reply,
  1142. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
  1143. if (r)
  1144. goto out;
  1145. mpi_request.PageAddress = cpu_to_le32(form | handle);
  1146. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
  1147. r = _config_request(ioc, &mpi_request, mpi_reply,
  1148. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
  1149. sizeof(*config_page));
  1150. out:
  1151. return r;
  1152. }
  1153. /**
  1154. * mpt3sas_config_get_pcie_device_pg0 - obtain pcie device page 0
  1155. * @ioc: per adapter object
  1156. * @mpi_reply: reply mf payload returned from firmware
  1157. * @config_page: contents of the config page
  1158. * @form: GET_NEXT_HANDLE or HANDLE
  1159. * @handle: device handle
  1160. * Context: sleep.
  1161. *
  1162. * Return: 0 for success, non-zero for failure.
  1163. */
  1164. int
  1165. mpt3sas_config_get_pcie_device_pg0(struct MPT3SAS_ADAPTER *ioc,
  1166. Mpi2ConfigReply_t *mpi_reply, Mpi26PCIeDevicePage0_t *config_page,
  1167. u32 form, u32 handle)
  1168. {
  1169. Mpi2ConfigRequest_t mpi_request;
  1170. int r;
  1171. memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  1172. mpi_request.Function = MPI2_FUNCTION_CONFIG;
  1173. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  1174. mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
  1175. mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE;
  1176. mpi_request.Header.PageVersion = MPI26_PCIEDEVICE0_PAGEVERSION;
  1177. mpi_request.Header.PageNumber = 0;
  1178. ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
  1179. r = _config_request(ioc, &mpi_request, mpi_reply,
  1180. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
  1181. if (r)
  1182. goto out;
  1183. mpi_request.PageAddress = cpu_to_le32(form | handle);
  1184. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
  1185. r = _config_request(ioc, &mpi_request, mpi_reply,
  1186. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
  1187. sizeof(*config_page));
  1188. out:
  1189. return r;
  1190. }
  1191. /**
  1192. * mpt3sas_config_get_pcie_iounit_pg1 - obtain pcie iounit page 1
  1193. * @ioc: per adapter object
  1194. * @mpi_reply: reply mf payload returned from firmware
  1195. * @config_page: contents of the config page
  1196. * @sz: size of buffer passed in config_page
  1197. * Context: sleep.
  1198. *
  1199. * Returns 0 for success, non-zero for failure.
  1200. */
  1201. int
  1202. mpt3sas_config_get_pcie_iounit_pg1(struct MPT3SAS_ADAPTER *ioc,
  1203. Mpi2ConfigReply_t *mpi_reply, Mpi26PCIeIOUnitPage1_t *config_page,
  1204. u16 sz)
  1205. {
  1206. Mpi2ConfigRequest_t mpi_request;
  1207. int r;
  1208. memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  1209. mpi_request.Function = MPI2_FUNCTION_CONFIG;
  1210. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  1211. mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
  1212. mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_IO_UNIT;
  1213. mpi_request.Header.PageVersion = MPI26_PCIEIOUNITPAGE1_PAGEVERSION;
  1214. mpi_request.Header.PageNumber = 1;
  1215. ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
  1216. r = _config_request(ioc, &mpi_request, mpi_reply,
  1217. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
  1218. if (r)
  1219. goto out;
  1220. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
  1221. r = _config_request(ioc, &mpi_request, mpi_reply,
  1222. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
  1223. out:
  1224. return r;
  1225. }
  1226. /**
  1227. * mpt3sas_config_get_pcie_device_pg2 - obtain pcie device page 2
  1228. * @ioc: per adapter object
  1229. * @mpi_reply: reply mf payload returned from firmware
  1230. * @config_page: contents of the config page
  1231. * @form: GET_NEXT_HANDLE or HANDLE
  1232. * @handle: device handle
  1233. * Context: sleep.
  1234. *
  1235. * Return: 0 for success, non-zero for failure.
  1236. */
  1237. int
  1238. mpt3sas_config_get_pcie_device_pg2(struct MPT3SAS_ADAPTER *ioc,
  1239. Mpi2ConfigReply_t *mpi_reply, Mpi26PCIeDevicePage2_t *config_page,
  1240. u32 form, u32 handle)
  1241. {
  1242. Mpi2ConfigRequest_t mpi_request;
  1243. int r;
  1244. memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  1245. mpi_request.Function = MPI2_FUNCTION_CONFIG;
  1246. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  1247. mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
  1248. mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE;
  1249. mpi_request.Header.PageVersion = MPI26_PCIEDEVICE2_PAGEVERSION;
  1250. mpi_request.Header.PageNumber = 2;
  1251. ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
  1252. r = _config_request(ioc, &mpi_request, mpi_reply,
  1253. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
  1254. if (r)
  1255. goto out;
  1256. mpi_request.PageAddress = cpu_to_le32(form | handle);
  1257. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
  1258. r = _config_request(ioc, &mpi_request, mpi_reply,
  1259. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
  1260. sizeof(*config_page));
  1261. out:
  1262. return r;
  1263. }
  1264. /**
  1265. * mpt3sas_config_get_number_hba_phys - obtain number of phys on the host
  1266. * @ioc: per adapter object
  1267. * @num_phys: pointer returned with the number of phys
  1268. * Context: sleep.
  1269. *
  1270. * Return: 0 for success, non-zero for failure.
  1271. */
  1272. int
  1273. mpt3sas_config_get_number_hba_phys(struct MPT3SAS_ADAPTER *ioc, u8 *num_phys)
  1274. {
  1275. Mpi2ConfigRequest_t mpi_request;
  1276. int r;
  1277. u16 ioc_status;
  1278. Mpi2ConfigReply_t mpi_reply;
  1279. Mpi2SasIOUnitPage0_t config_page;
  1280. *num_phys = 0;
  1281. memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  1282. mpi_request.Function = MPI2_FUNCTION_CONFIG;
  1283. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  1284. mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
  1285. mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
  1286. mpi_request.Header.PageNumber = 0;
  1287. mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE0_PAGEVERSION;
  1288. ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
  1289. r = _config_request(ioc, &mpi_request, &mpi_reply,
  1290. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
  1291. if (r)
  1292. goto out;
  1293. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
  1294. r = _config_request(ioc, &mpi_request, &mpi_reply,
  1295. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, &config_page,
  1296. sizeof(Mpi2SasIOUnitPage0_t));
  1297. if (!r) {
  1298. ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
  1299. MPI2_IOCSTATUS_MASK;
  1300. if (ioc_status == MPI2_IOCSTATUS_SUCCESS)
  1301. *num_phys = config_page.NumPhys;
  1302. }
  1303. out:
  1304. return r;
  1305. }
  1306. /**
  1307. * mpt3sas_config_get_sas_iounit_pg0 - obtain sas iounit page 0
  1308. * @ioc: per adapter object
  1309. * @mpi_reply: reply mf payload returned from firmware
  1310. * @config_page: contents of the config page
  1311. * @sz: size of buffer passed in config_page
  1312. * Context: sleep.
  1313. *
  1314. * Calling function should call config_get_number_hba_phys prior to
  1315. * this function, so enough memory is allocated for config_page.
  1316. *
  1317. * Return: 0 for success, non-zero for failure.
  1318. */
  1319. int
  1320. mpt3sas_config_get_sas_iounit_pg0(struct MPT3SAS_ADAPTER *ioc,
  1321. Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage0_t *config_page,
  1322. u16 sz)
  1323. {
  1324. Mpi2ConfigRequest_t mpi_request;
  1325. int r;
  1326. memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  1327. mpi_request.Function = MPI2_FUNCTION_CONFIG;
  1328. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  1329. mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
  1330. mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
  1331. mpi_request.Header.PageNumber = 0;
  1332. mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE0_PAGEVERSION;
  1333. ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
  1334. r = _config_request(ioc, &mpi_request, mpi_reply,
  1335. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
  1336. if (r)
  1337. goto out;
  1338. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
  1339. r = _config_request(ioc, &mpi_request, mpi_reply,
  1340. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
  1341. out:
  1342. return r;
  1343. }
  1344. /**
  1345. * mpt3sas_config_get_sas_iounit_pg1 - obtain sas iounit page 1
  1346. * @ioc: per adapter object
  1347. * @mpi_reply: reply mf payload returned from firmware
  1348. * @config_page: contents of the config page
  1349. * @sz: size of buffer passed in config_page
  1350. * Context: sleep.
  1351. *
  1352. * Calling function should call config_get_number_hba_phys prior to
  1353. * this function, so enough memory is allocated for config_page.
  1354. *
  1355. * Return: 0 for success, non-zero for failure.
  1356. */
  1357. int
  1358. mpt3sas_config_get_sas_iounit_pg1(struct MPT3SAS_ADAPTER *ioc,
  1359. Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage1_t *config_page,
  1360. u16 sz)
  1361. {
  1362. Mpi2ConfigRequest_t mpi_request;
  1363. int r;
  1364. memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  1365. mpi_request.Function = MPI2_FUNCTION_CONFIG;
  1366. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  1367. mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
  1368. mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
  1369. mpi_request.Header.PageNumber = 1;
  1370. mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE1_PAGEVERSION;
  1371. ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
  1372. r = _config_request(ioc, &mpi_request, mpi_reply,
  1373. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
  1374. if (r)
  1375. goto out;
  1376. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
  1377. r = _config_request(ioc, &mpi_request, mpi_reply,
  1378. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
  1379. out:
  1380. return r;
  1381. }
  1382. /**
  1383. * mpt3sas_config_set_sas_iounit_pg1 - send sas iounit page 1
  1384. * @ioc: per adapter object
  1385. * @mpi_reply: reply mf payload returned from firmware
  1386. * @config_page: contents of the config page
  1387. * @sz: size of buffer passed in config_page
  1388. * Context: sleep.
  1389. *
  1390. * Calling function should call config_get_number_hba_phys prior to
  1391. * this function, so enough memory is allocated for config_page.
  1392. *
  1393. * Return: 0 for success, non-zero for failure.
  1394. */
  1395. int
  1396. mpt3sas_config_set_sas_iounit_pg1(struct MPT3SAS_ADAPTER *ioc,
  1397. Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage1_t *config_page,
  1398. u16 sz)
  1399. {
  1400. Mpi2ConfigRequest_t mpi_request;
  1401. int r;
  1402. memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  1403. mpi_request.Function = MPI2_FUNCTION_CONFIG;
  1404. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  1405. mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
  1406. mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
  1407. mpi_request.Header.PageNumber = 1;
  1408. mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE1_PAGEVERSION;
  1409. ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
  1410. r = _config_request(ioc, &mpi_request, mpi_reply,
  1411. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
  1412. if (r)
  1413. goto out;
  1414. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
  1415. _config_request(ioc, &mpi_request, mpi_reply,
  1416. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
  1417. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;
  1418. r = _config_request(ioc, &mpi_request, mpi_reply,
  1419. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
  1420. out:
  1421. return r;
  1422. }
  1423. /**
  1424. * mpt3sas_config_get_expander_pg0 - obtain expander page 0
  1425. * @ioc: per adapter object
  1426. * @mpi_reply: reply mf payload returned from firmware
  1427. * @config_page: contents of the config page
  1428. * @form: GET_NEXT_HANDLE or HANDLE
  1429. * @handle: expander handle
  1430. * Context: sleep.
  1431. *
  1432. * Return: 0 for success, non-zero for failure.
  1433. */
  1434. int
  1435. mpt3sas_config_get_expander_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
  1436. *mpi_reply, Mpi2ExpanderPage0_t *config_page, u32 form, u32 handle)
  1437. {
  1438. Mpi2ConfigRequest_t mpi_request;
  1439. int r;
  1440. memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  1441. mpi_request.Function = MPI2_FUNCTION_CONFIG;
  1442. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  1443. mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
  1444. mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
  1445. mpi_request.Header.PageNumber = 0;
  1446. mpi_request.Header.PageVersion = MPI2_SASEXPANDER0_PAGEVERSION;
  1447. ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
  1448. r = _config_request(ioc, &mpi_request, mpi_reply,
  1449. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
  1450. if (r)
  1451. goto out;
  1452. mpi_request.PageAddress = cpu_to_le32(form | handle);
  1453. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
  1454. r = _config_request(ioc, &mpi_request, mpi_reply,
  1455. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
  1456. sizeof(*config_page));
  1457. out:
  1458. return r;
  1459. }
  1460. /**
  1461. * mpt3sas_config_get_expander_pg1 - obtain expander page 1
  1462. * @ioc: per adapter object
  1463. * @mpi_reply: reply mf payload returned from firmware
  1464. * @config_page: contents of the config page
  1465. * @phy_number: phy number
  1466. * @handle: expander handle
  1467. * Context: sleep.
  1468. *
  1469. * Return: 0 for success, non-zero for failure.
  1470. */
  1471. int
  1472. mpt3sas_config_get_expander_pg1(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
  1473. *mpi_reply, Mpi2ExpanderPage1_t *config_page, u32 phy_number,
  1474. u16 handle)
  1475. {
  1476. Mpi2ConfigRequest_t mpi_request;
  1477. int r;
  1478. memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  1479. mpi_request.Function = MPI2_FUNCTION_CONFIG;
  1480. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  1481. mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
  1482. mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
  1483. mpi_request.Header.PageNumber = 1;
  1484. mpi_request.Header.PageVersion = MPI2_SASEXPANDER1_PAGEVERSION;
  1485. ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
  1486. r = _config_request(ioc, &mpi_request, mpi_reply,
  1487. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
  1488. if (r)
  1489. goto out;
  1490. mpi_request.PageAddress =
  1491. cpu_to_le32(MPI2_SAS_EXPAND_PGAD_FORM_HNDL_PHY_NUM |
  1492. (phy_number << MPI2_SAS_EXPAND_PGAD_PHYNUM_SHIFT) | handle);
  1493. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
  1494. r = _config_request(ioc, &mpi_request, mpi_reply,
  1495. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
  1496. sizeof(*config_page));
  1497. out:
  1498. return r;
  1499. }
  1500. /**
  1501. * mpt3sas_config_get_enclosure_pg0 - obtain enclosure page 0
  1502. * @ioc: per adapter object
  1503. * @mpi_reply: reply mf payload returned from firmware
  1504. * @config_page: contents of the config page
  1505. * @form: GET_NEXT_HANDLE or HANDLE
  1506. * @handle: expander handle
  1507. * Context: sleep.
  1508. *
  1509. * Return: 0 for success, non-zero for failure.
  1510. */
  1511. int
  1512. mpt3sas_config_get_enclosure_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
  1513. *mpi_reply, Mpi2SasEnclosurePage0_t *config_page, u32 form, u32 handle)
  1514. {
  1515. Mpi2ConfigRequest_t mpi_request;
  1516. int r;
  1517. memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  1518. mpi_request.Function = MPI2_FUNCTION_CONFIG;
  1519. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  1520. mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
  1521. mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_ENCLOSURE;
  1522. mpi_request.Header.PageNumber = 0;
  1523. mpi_request.Header.PageVersion = MPI2_SASENCLOSURE0_PAGEVERSION;
  1524. ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
  1525. r = _config_request(ioc, &mpi_request, mpi_reply,
  1526. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
  1527. if (r)
  1528. goto out;
  1529. mpi_request.PageAddress = cpu_to_le32(form | handle);
  1530. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
  1531. r = _config_request(ioc, &mpi_request, mpi_reply,
  1532. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
  1533. sizeof(*config_page));
  1534. out:
  1535. return r;
  1536. }
  1537. /**
  1538. * mpt3sas_config_get_phy_pg0 - obtain phy page 0
  1539. * @ioc: per adapter object
  1540. * @mpi_reply: reply mf payload returned from firmware
  1541. * @config_page: contents of the config page
  1542. * @phy_number: phy number
  1543. * Context: sleep.
  1544. *
  1545. * Return: 0 for success, non-zero for failure.
  1546. */
  1547. int
  1548. mpt3sas_config_get_phy_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
  1549. *mpi_reply, Mpi2SasPhyPage0_t *config_page, u32 phy_number)
  1550. {
  1551. Mpi2ConfigRequest_t mpi_request;
  1552. int r;
  1553. memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  1554. mpi_request.Function = MPI2_FUNCTION_CONFIG;
  1555. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  1556. mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
  1557. mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_PHY;
  1558. mpi_request.Header.PageNumber = 0;
  1559. mpi_request.Header.PageVersion = MPI2_SASPHY0_PAGEVERSION;
  1560. ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
  1561. r = _config_request(ioc, &mpi_request, mpi_reply,
  1562. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
  1563. if (r)
  1564. goto out;
  1565. mpi_request.PageAddress =
  1566. cpu_to_le32(MPI2_SAS_PHY_PGAD_FORM_PHY_NUMBER | phy_number);
  1567. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
  1568. r = _config_request(ioc, &mpi_request, mpi_reply,
  1569. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
  1570. sizeof(*config_page));
  1571. out:
  1572. return r;
  1573. }
  1574. /**
  1575. * mpt3sas_config_get_phy_pg1 - obtain phy page 1
  1576. * @ioc: per adapter object
  1577. * @mpi_reply: reply mf payload returned from firmware
  1578. * @config_page: contents of the config page
  1579. * @phy_number: phy number
  1580. * Context: sleep.
  1581. *
  1582. * Return: 0 for success, non-zero for failure.
  1583. */
  1584. int
  1585. mpt3sas_config_get_phy_pg1(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
  1586. *mpi_reply, Mpi2SasPhyPage1_t *config_page, u32 phy_number)
  1587. {
  1588. Mpi2ConfigRequest_t mpi_request;
  1589. int r;
  1590. memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  1591. mpi_request.Function = MPI2_FUNCTION_CONFIG;
  1592. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  1593. mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
  1594. mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_PHY;
  1595. mpi_request.Header.PageNumber = 1;
  1596. mpi_request.Header.PageVersion = MPI2_SASPHY1_PAGEVERSION;
  1597. ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
  1598. r = _config_request(ioc, &mpi_request, mpi_reply,
  1599. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
  1600. if (r)
  1601. goto out;
  1602. mpi_request.PageAddress =
  1603. cpu_to_le32(MPI2_SAS_PHY_PGAD_FORM_PHY_NUMBER | phy_number);
  1604. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
  1605. r = _config_request(ioc, &mpi_request, mpi_reply,
  1606. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
  1607. sizeof(*config_page));
  1608. out:
  1609. return r;
  1610. }
  1611. /**
  1612. * mpt3sas_config_get_raid_volume_pg1 - obtain raid volume page 1
  1613. * @ioc: per adapter object
  1614. * @mpi_reply: reply mf payload returned from firmware
  1615. * @config_page: contents of the config page
  1616. * @form: GET_NEXT_HANDLE or HANDLE
  1617. * @handle: volume handle
  1618. * Context: sleep.
  1619. *
  1620. * Return: 0 for success, non-zero for failure.
  1621. */
  1622. int
  1623. mpt3sas_config_get_raid_volume_pg1(struct MPT3SAS_ADAPTER *ioc,
  1624. Mpi2ConfigReply_t *mpi_reply, Mpi2RaidVolPage1_t *config_page, u32 form,
  1625. u32 handle)
  1626. {
  1627. Mpi2ConfigRequest_t mpi_request;
  1628. int r;
  1629. memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  1630. mpi_request.Function = MPI2_FUNCTION_CONFIG;
  1631. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  1632. mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;
  1633. mpi_request.Header.PageNumber = 1;
  1634. mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE1_PAGEVERSION;
  1635. ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
  1636. r = _config_request(ioc, &mpi_request, mpi_reply,
  1637. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
  1638. if (r)
  1639. goto out;
  1640. mpi_request.PageAddress = cpu_to_le32(form | handle);
  1641. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
  1642. r = _config_request(ioc, &mpi_request, mpi_reply,
  1643. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
  1644. sizeof(*config_page));
  1645. out:
  1646. return r;
  1647. }
  1648. /**
  1649. * mpt3sas_config_get_number_pds - obtain number of phys disk assigned to volume
  1650. * @ioc: per adapter object
  1651. * @handle: volume handle
  1652. * @num_pds: returns pds count
  1653. * Context: sleep.
  1654. *
  1655. * Return: 0 for success, non-zero for failure.
  1656. */
  1657. int
  1658. mpt3sas_config_get_number_pds(struct MPT3SAS_ADAPTER *ioc, u16 handle,
  1659. u8 *num_pds)
  1660. {
  1661. Mpi2ConfigRequest_t mpi_request;
  1662. Mpi2RaidVolPage0_t config_page;
  1663. Mpi2ConfigReply_t mpi_reply;
  1664. int r;
  1665. u16 ioc_status;
  1666. memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  1667. *num_pds = 0;
  1668. mpi_request.Function = MPI2_FUNCTION_CONFIG;
  1669. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  1670. mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;
  1671. mpi_request.Header.PageNumber = 0;
  1672. mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE0_PAGEVERSION;
  1673. ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
  1674. r = _config_request(ioc, &mpi_request, &mpi_reply,
  1675. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
  1676. if (r)
  1677. goto out;
  1678. mpi_request.PageAddress =
  1679. cpu_to_le32(MPI2_RAID_VOLUME_PGAD_FORM_HANDLE | handle);
  1680. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
  1681. r = _config_request(ioc, &mpi_request, &mpi_reply,
  1682. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, &config_page,
  1683. sizeof(Mpi2RaidVolPage0_t));
  1684. if (!r) {
  1685. ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
  1686. MPI2_IOCSTATUS_MASK;
  1687. if (ioc_status == MPI2_IOCSTATUS_SUCCESS)
  1688. *num_pds = config_page.NumPhysDisks;
  1689. }
  1690. out:
  1691. return r;
  1692. }
  1693. /**
  1694. * mpt3sas_config_get_raid_volume_pg0 - obtain raid volume page 0
  1695. * @ioc: per adapter object
  1696. * @mpi_reply: reply mf payload returned from firmware
  1697. * @config_page: contents of the config page
  1698. * @form: GET_NEXT_HANDLE or HANDLE
  1699. * @handle: volume handle
  1700. * @sz: size of buffer passed in config_page
  1701. * Context: sleep.
  1702. *
  1703. * Return: 0 for success, non-zero for failure.
  1704. */
  1705. int
  1706. mpt3sas_config_get_raid_volume_pg0(struct MPT3SAS_ADAPTER *ioc,
  1707. Mpi2ConfigReply_t *mpi_reply, Mpi2RaidVolPage0_t *config_page, u32 form,
  1708. u32 handle, u16 sz)
  1709. {
  1710. Mpi2ConfigRequest_t mpi_request;
  1711. int r;
  1712. memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  1713. mpi_request.Function = MPI2_FUNCTION_CONFIG;
  1714. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  1715. mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;
  1716. mpi_request.Header.PageNumber = 0;
  1717. mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE0_PAGEVERSION;
  1718. ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
  1719. r = _config_request(ioc, &mpi_request, mpi_reply,
  1720. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
  1721. if (r)
  1722. goto out;
  1723. mpi_request.PageAddress = cpu_to_le32(form | handle);
  1724. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
  1725. r = _config_request(ioc, &mpi_request, mpi_reply,
  1726. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
  1727. out:
  1728. return r;
  1729. }
  1730. /**
  1731. * mpt3sas_config_get_phys_disk_pg0 - obtain phys disk page 0
  1732. * @ioc: per adapter object
  1733. * @mpi_reply: reply mf payload returned from firmware
  1734. * @config_page: contents of the config page
  1735. * @form: GET_NEXT_PHYSDISKNUM, PHYSDISKNUM, DEVHANDLE
  1736. * @form_specific: specific to the form
  1737. * Context: sleep.
  1738. *
  1739. * Return: 0 for success, non-zero for failure.
  1740. */
  1741. int
  1742. mpt3sas_config_get_phys_disk_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t
  1743. *mpi_reply, Mpi2RaidPhysDiskPage0_t *config_page, u32 form,
  1744. u32 form_specific)
  1745. {
  1746. Mpi2ConfigRequest_t mpi_request;
  1747. int r;
  1748. memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  1749. mpi_request.Function = MPI2_FUNCTION_CONFIG;
  1750. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  1751. mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_PHYSDISK;
  1752. mpi_request.Header.PageNumber = 0;
  1753. mpi_request.Header.PageVersion = MPI2_RAIDPHYSDISKPAGE0_PAGEVERSION;
  1754. ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
  1755. r = _config_request(ioc, &mpi_request, mpi_reply,
  1756. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
  1757. if (r)
  1758. goto out;
  1759. mpi_request.PageAddress = cpu_to_le32(form | form_specific);
  1760. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
  1761. r = _config_request(ioc, &mpi_request, mpi_reply,
  1762. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
  1763. sizeof(*config_page));
  1764. out:
  1765. return r;
  1766. }
  1767. /**
  1768. * mpt3sas_config_get_driver_trigger_pg0 - obtain driver trigger page 0
  1769. * @ioc: per adapter object
  1770. * @mpi_reply: reply mf payload returned from firmware
  1771. * @config_page: contents of the config page
  1772. * Context: sleep.
  1773. *
  1774. * Returns 0 for success, non-zero for failure.
  1775. */
  1776. int
  1777. mpt3sas_config_get_driver_trigger_pg0(struct MPT3SAS_ADAPTER *ioc,
  1778. Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage0_t *config_page)
  1779. {
  1780. Mpi2ConfigRequest_t mpi_request;
  1781. int r;
  1782. memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  1783. mpi_request.Function = MPI2_FUNCTION_CONFIG;
  1784. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  1785. mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
  1786. mpi_request.ExtPageType =
  1787. MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
  1788. mpi_request.Header.PageNumber = 0;
  1789. mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE0_PAGEVERSION;
  1790. ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
  1791. r = _config_request(ioc, &mpi_request, mpi_reply,
  1792. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
  1793. if (r)
  1794. goto out;
  1795. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
  1796. r = _config_request(ioc, &mpi_request, mpi_reply,
  1797. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
  1798. sizeof(*config_page));
  1799. out:
  1800. return r;
  1801. }
  1802. /**
  1803. * _config_set_driver_trigger_pg0 - write driver trigger page 0
  1804. * @ioc: per adapter object
  1805. * @mpi_reply: reply mf payload returned from firmware
  1806. * @config_page: contents of the config page
  1807. * Context: sleep.
  1808. *
  1809. * Returns 0 for success, non-zero for failure.
  1810. */
  1811. static int
  1812. _config_set_driver_trigger_pg0(struct MPT3SAS_ADAPTER *ioc,
  1813. Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage0_t *config_page)
  1814. {
  1815. Mpi2ConfigRequest_t mpi_request;
  1816. int r;
  1817. memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  1818. mpi_request.Function = MPI2_FUNCTION_CONFIG;
  1819. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  1820. mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
  1821. mpi_request.ExtPageType =
  1822. MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
  1823. mpi_request.Header.PageNumber = 0;
  1824. mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE0_PAGEVERSION;
  1825. ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
  1826. r = _config_request(ioc, &mpi_request, mpi_reply,
  1827. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
  1828. if (r)
  1829. goto out;
  1830. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
  1831. _config_request(ioc, &mpi_request, mpi_reply,
  1832. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
  1833. sizeof(*config_page));
  1834. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;
  1835. r = _config_request(ioc, &mpi_request, mpi_reply,
  1836. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
  1837. sizeof(*config_page));
  1838. out:
  1839. return r;
  1840. }
  1841. /**
  1842. * mpt3sas_config_update_driver_trigger_pg0 - update driver trigger page 0
  1843. * @ioc: per adapter object
  1844. * @trigger_flag: trigger type bit map
  1845. * @set: set ot clear trigger values
  1846. * Context: sleep.
  1847. *
  1848. * Returns 0 for success, non-zero for failure.
  1849. */
  1850. static int
  1851. mpt3sas_config_update_driver_trigger_pg0(struct MPT3SAS_ADAPTER *ioc,
  1852. u16 trigger_flag, bool set)
  1853. {
  1854. Mpi26DriverTriggerPage0_t tg_pg0;
  1855. Mpi2ConfigReply_t mpi_reply;
  1856. int rc;
  1857. u16 flags, ioc_status;
  1858. rc = mpt3sas_config_get_driver_trigger_pg0(ioc, &mpi_reply, &tg_pg0);
  1859. if (rc)
  1860. return rc;
  1861. ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
  1862. MPI2_IOCSTATUS_MASK;
  1863. if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
  1864. dcprintk(ioc,
  1865. ioc_err(ioc,
  1866. "%s: Failed to get trigger pg0, ioc_status(0x%04x)\n",
  1867. __func__, ioc_status));
  1868. return -EFAULT;
  1869. }
  1870. if (set)
  1871. flags = le16_to_cpu(tg_pg0.TriggerFlags) | trigger_flag;
  1872. else
  1873. flags = le16_to_cpu(tg_pg0.TriggerFlags) & ~trigger_flag;
  1874. tg_pg0.TriggerFlags = cpu_to_le16(flags);
  1875. rc = _config_set_driver_trigger_pg0(ioc, &mpi_reply, &tg_pg0);
  1876. if (rc)
  1877. return rc;
  1878. ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
  1879. MPI2_IOCSTATUS_MASK;
  1880. if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
  1881. dcprintk(ioc,
  1882. ioc_err(ioc,
  1883. "%s: Failed to update trigger pg0, ioc_status(0x%04x)\n",
  1884. __func__, ioc_status));
  1885. return -EFAULT;
  1886. }
  1887. return 0;
  1888. }
  1889. /**
  1890. * mpt3sas_config_get_driver_trigger_pg1 - obtain driver trigger page 1
  1891. * @ioc: per adapter object
  1892. * @mpi_reply: reply mf payload returned from firmware
  1893. * @config_page: contents of the config page
  1894. * Context: sleep.
  1895. *
  1896. * Returns 0 for success, non-zero for failure.
  1897. */
  1898. int
  1899. mpt3sas_config_get_driver_trigger_pg1(struct MPT3SAS_ADAPTER *ioc,
  1900. Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage1_t *config_page)
  1901. {
  1902. Mpi2ConfigRequest_t mpi_request;
  1903. int r;
  1904. memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  1905. mpi_request.Function = MPI2_FUNCTION_CONFIG;
  1906. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  1907. mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
  1908. mpi_request.ExtPageType =
  1909. MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
  1910. mpi_request.Header.PageNumber = 1;
  1911. mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE1_PAGEVERSION;
  1912. ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
  1913. r = _config_request(ioc, &mpi_request, mpi_reply,
  1914. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
  1915. if (r)
  1916. goto out;
  1917. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
  1918. r = _config_request(ioc, &mpi_request, mpi_reply,
  1919. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
  1920. sizeof(*config_page));
  1921. out:
  1922. return r;
  1923. }
  1924. /**
  1925. * _config_set_driver_trigger_pg1 - write driver trigger page 1
  1926. * @ioc: per adapter object
  1927. * @mpi_reply: reply mf payload returned from firmware
  1928. * @config_page: contents of the config page
  1929. * Context: sleep.
  1930. *
  1931. * Returns 0 for success, non-zero for failure.
  1932. */
  1933. static int
  1934. _config_set_driver_trigger_pg1(struct MPT3SAS_ADAPTER *ioc,
  1935. Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage1_t *config_page)
  1936. {
  1937. Mpi2ConfigRequest_t mpi_request;
  1938. int r;
  1939. memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  1940. mpi_request.Function = MPI2_FUNCTION_CONFIG;
  1941. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  1942. mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
  1943. mpi_request.ExtPageType =
  1944. MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
  1945. mpi_request.Header.PageNumber = 1;
  1946. mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE1_PAGEVERSION;
  1947. ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
  1948. r = _config_request(ioc, &mpi_request, mpi_reply,
  1949. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
  1950. if (r)
  1951. goto out;
  1952. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
  1953. _config_request(ioc, &mpi_request, mpi_reply,
  1954. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
  1955. sizeof(*config_page));
  1956. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;
  1957. r = _config_request(ioc, &mpi_request, mpi_reply,
  1958. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
  1959. sizeof(*config_page));
  1960. out:
  1961. return r;
  1962. }
  1963. /**
  1964. * mpt3sas_config_update_driver_trigger_pg1 - update driver trigger page 1
  1965. * @ioc: per adapter object
  1966. * @master_tg: Master trigger bit map
  1967. * @set: set ot clear trigger values
  1968. * Context: sleep.
  1969. *
  1970. * Returns 0 for success, non-zero for failure.
  1971. */
  1972. int
  1973. mpt3sas_config_update_driver_trigger_pg1(struct MPT3SAS_ADAPTER *ioc,
  1974. struct SL_WH_MASTER_TRIGGER_T *master_tg, bool set)
  1975. {
  1976. Mpi26DriverTriggerPage1_t tg_pg1;
  1977. Mpi2ConfigReply_t mpi_reply;
  1978. int rc;
  1979. u16 ioc_status;
  1980. rc = mpt3sas_config_update_driver_trigger_pg0(ioc,
  1981. MPI26_DRIVER_TRIGGER0_FLAG_MASTER_TRIGGER_VALID, set);
  1982. if (rc)
  1983. return rc;
  1984. rc = mpt3sas_config_get_driver_trigger_pg1(ioc, &mpi_reply, &tg_pg1);
  1985. if (rc)
  1986. goto out;
  1987. ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
  1988. MPI2_IOCSTATUS_MASK;
  1989. if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
  1990. dcprintk(ioc,
  1991. ioc_err(ioc,
  1992. "%s: Failed to get trigger pg1, ioc_status(0x%04x)\n",
  1993. __func__, ioc_status));
  1994. rc = -EFAULT;
  1995. goto out;
  1996. }
  1997. if (set) {
  1998. tg_pg1.NumMasterTrigger = cpu_to_le16(1);
  1999. tg_pg1.MasterTriggers[0].MasterTriggerFlags = cpu_to_le32(
  2000. master_tg->MasterData);
  2001. } else {
  2002. tg_pg1.NumMasterTrigger = 0;
  2003. tg_pg1.MasterTriggers[0].MasterTriggerFlags = 0;
  2004. }
  2005. rc = _config_set_driver_trigger_pg1(ioc, &mpi_reply, &tg_pg1);
  2006. if (rc)
  2007. goto out;
  2008. ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
  2009. MPI2_IOCSTATUS_MASK;
  2010. if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
  2011. dcprintk(ioc,
  2012. ioc_err(ioc,
  2013. "%s: Failed to get trigger pg1, ioc_status(0x%04x)\n",
  2014. __func__, ioc_status));
  2015. rc = -EFAULT;
  2016. goto out;
  2017. }
  2018. return 0;
  2019. out:
  2020. mpt3sas_config_update_driver_trigger_pg0(ioc,
  2021. MPI26_DRIVER_TRIGGER0_FLAG_MASTER_TRIGGER_VALID, !set);
  2022. return rc;
  2023. }
  2024. /**
  2025. * mpt3sas_config_get_driver_trigger_pg2 - obtain driver trigger page 2
  2026. * @ioc: per adapter object
  2027. * @mpi_reply: reply mf payload returned from firmware
  2028. * @config_page: contents of the config page
  2029. * Context: sleep.
  2030. *
  2031. * Returns 0 for success, non-zero for failure.
  2032. */
  2033. int
  2034. mpt3sas_config_get_driver_trigger_pg2(struct MPT3SAS_ADAPTER *ioc,
  2035. Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage2_t *config_page)
  2036. {
  2037. Mpi2ConfigRequest_t mpi_request;
  2038. int r;
  2039. memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  2040. mpi_request.Function = MPI2_FUNCTION_CONFIG;
  2041. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  2042. mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
  2043. mpi_request.ExtPageType =
  2044. MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
  2045. mpi_request.Header.PageNumber = 2;
  2046. mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE2_PAGEVERSION;
  2047. ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
  2048. r = _config_request(ioc, &mpi_request, mpi_reply,
  2049. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
  2050. if (r)
  2051. goto out;
  2052. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
  2053. r = _config_request(ioc, &mpi_request, mpi_reply,
  2054. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
  2055. sizeof(*config_page));
  2056. out:
  2057. return r;
  2058. }
  2059. /**
  2060. * _config_set_driver_trigger_pg2 - write driver trigger page 2
  2061. * @ioc: per adapter object
  2062. * @mpi_reply: reply mf payload returned from firmware
  2063. * @config_page: contents of the config page
  2064. * Context: sleep.
  2065. *
  2066. * Returns 0 for success, non-zero for failure.
  2067. */
  2068. static int
  2069. _config_set_driver_trigger_pg2(struct MPT3SAS_ADAPTER *ioc,
  2070. Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage2_t *config_page)
  2071. {
  2072. Mpi2ConfigRequest_t mpi_request;
  2073. int r;
  2074. memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  2075. mpi_request.Function = MPI2_FUNCTION_CONFIG;
  2076. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  2077. mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
  2078. mpi_request.ExtPageType =
  2079. MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
  2080. mpi_request.Header.PageNumber = 2;
  2081. mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE2_PAGEVERSION;
  2082. ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
  2083. r = _config_request(ioc, &mpi_request, mpi_reply,
  2084. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
  2085. if (r)
  2086. goto out;
  2087. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
  2088. _config_request(ioc, &mpi_request, mpi_reply,
  2089. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
  2090. sizeof(*config_page));
  2091. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;
  2092. r = _config_request(ioc, &mpi_request, mpi_reply,
  2093. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
  2094. sizeof(*config_page));
  2095. out:
  2096. return r;
  2097. }
  2098. /**
  2099. * mpt3sas_config_update_driver_trigger_pg2 - update driver trigger page 2
  2100. * @ioc: per adapter object
  2101. * @event_tg: list of Event Triggers
  2102. * @set: set ot clear trigger values
  2103. * Context: sleep.
  2104. *
  2105. * Returns 0 for success, non-zero for failure.
  2106. */
  2107. int
  2108. mpt3sas_config_update_driver_trigger_pg2(struct MPT3SAS_ADAPTER *ioc,
  2109. struct SL_WH_EVENT_TRIGGERS_T *event_tg, bool set)
  2110. {
  2111. Mpi26DriverTriggerPage2_t tg_pg2;
  2112. Mpi2ConfigReply_t mpi_reply;
  2113. int rc, i, count;
  2114. u16 ioc_status;
  2115. rc = mpt3sas_config_update_driver_trigger_pg0(ioc,
  2116. MPI26_DRIVER_TRIGGER0_FLAG_MPI_EVENT_TRIGGER_VALID, set);
  2117. if (rc)
  2118. return rc;
  2119. rc = mpt3sas_config_get_driver_trigger_pg2(ioc, &mpi_reply, &tg_pg2);
  2120. if (rc)
  2121. goto out;
  2122. ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
  2123. MPI2_IOCSTATUS_MASK;
  2124. if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
  2125. dcprintk(ioc,
  2126. ioc_err(ioc,
  2127. "%s: Failed to get trigger pg2, ioc_status(0x%04x)\n",
  2128. __func__, ioc_status));
  2129. rc = -EFAULT;
  2130. goto out;
  2131. }
  2132. if (set) {
  2133. count = event_tg->ValidEntries;
  2134. tg_pg2.NumMPIEventTrigger = cpu_to_le16(count);
  2135. for (i = 0; i < count; i++) {
  2136. tg_pg2.MPIEventTriggers[i].MPIEventCode =
  2137. cpu_to_le16(
  2138. event_tg->EventTriggerEntry[i].EventValue);
  2139. tg_pg2.MPIEventTriggers[i].MPIEventCodeSpecific =
  2140. cpu_to_le16(
  2141. event_tg->EventTriggerEntry[i].LogEntryQualifier);
  2142. }
  2143. } else {
  2144. tg_pg2.NumMPIEventTrigger = 0;
  2145. memset(&tg_pg2.MPIEventTriggers[0], 0,
  2146. NUM_VALID_ENTRIES * sizeof(
  2147. MPI26_DRIVER_MPI_EVENT_TIGGER_ENTRY));
  2148. }
  2149. rc = _config_set_driver_trigger_pg2(ioc, &mpi_reply, &tg_pg2);
  2150. if (rc)
  2151. goto out;
  2152. ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
  2153. MPI2_IOCSTATUS_MASK;
  2154. if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
  2155. dcprintk(ioc,
  2156. ioc_err(ioc,
  2157. "%s: Failed to get trigger pg2, ioc_status(0x%04x)\n",
  2158. __func__, ioc_status));
  2159. rc = -EFAULT;
  2160. goto out;
  2161. }
  2162. return 0;
  2163. out:
  2164. mpt3sas_config_update_driver_trigger_pg0(ioc,
  2165. MPI26_DRIVER_TRIGGER0_FLAG_MPI_EVENT_TRIGGER_VALID, !set);
  2166. return rc;
  2167. }
  2168. /**
  2169. * mpt3sas_config_get_driver_trigger_pg3 - obtain driver trigger page 3
  2170. * @ioc: per adapter object
  2171. * @mpi_reply: reply mf payload returned from firmware
  2172. * @config_page: contents of the config page
  2173. * Context: sleep.
  2174. *
  2175. * Returns 0 for success, non-zero for failure.
  2176. */
  2177. int
  2178. mpt3sas_config_get_driver_trigger_pg3(struct MPT3SAS_ADAPTER *ioc,
  2179. Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage3_t *config_page)
  2180. {
  2181. Mpi2ConfigRequest_t mpi_request;
  2182. int r;
  2183. memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  2184. mpi_request.Function = MPI2_FUNCTION_CONFIG;
  2185. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  2186. mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
  2187. mpi_request.ExtPageType =
  2188. MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
  2189. mpi_request.Header.PageNumber = 3;
  2190. mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE3_PAGEVERSION;
  2191. ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
  2192. r = _config_request(ioc, &mpi_request, mpi_reply,
  2193. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
  2194. if (r)
  2195. goto out;
  2196. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
  2197. r = _config_request(ioc, &mpi_request, mpi_reply,
  2198. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
  2199. sizeof(*config_page));
  2200. out:
  2201. return r;
  2202. }
  2203. /**
  2204. * _config_set_driver_trigger_pg3 - write driver trigger page 3
  2205. * @ioc: per adapter object
  2206. * @mpi_reply: reply mf payload returned from firmware
  2207. * @config_page: contents of the config page
  2208. * Context: sleep.
  2209. *
  2210. * Returns 0 for success, non-zero for failure.
  2211. */
  2212. static int
  2213. _config_set_driver_trigger_pg3(struct MPT3SAS_ADAPTER *ioc,
  2214. Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage3_t *config_page)
  2215. {
  2216. Mpi2ConfigRequest_t mpi_request;
  2217. int r;
  2218. memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  2219. mpi_request.Function = MPI2_FUNCTION_CONFIG;
  2220. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  2221. mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
  2222. mpi_request.ExtPageType =
  2223. MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
  2224. mpi_request.Header.PageNumber = 3;
  2225. mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE3_PAGEVERSION;
  2226. ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
  2227. r = _config_request(ioc, &mpi_request, mpi_reply,
  2228. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
  2229. if (r)
  2230. goto out;
  2231. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
  2232. _config_request(ioc, &mpi_request, mpi_reply,
  2233. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
  2234. sizeof(*config_page));
  2235. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;
  2236. r = _config_request(ioc, &mpi_request, mpi_reply,
  2237. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
  2238. sizeof(*config_page));
  2239. out:
  2240. return r;
  2241. }
  2242. /**
  2243. * mpt3sas_config_update_driver_trigger_pg3 - update driver trigger page 3
  2244. * @ioc: per adapter object
  2245. * @scsi_tg: scsi trigger list
  2246. * @set: set ot clear trigger values
  2247. * Context: sleep.
  2248. *
  2249. * Returns 0 for success, non-zero for failure.
  2250. */
  2251. int
  2252. mpt3sas_config_update_driver_trigger_pg3(struct MPT3SAS_ADAPTER *ioc,
  2253. struct SL_WH_SCSI_TRIGGERS_T *scsi_tg, bool set)
  2254. {
  2255. Mpi26DriverTriggerPage3_t tg_pg3;
  2256. Mpi2ConfigReply_t mpi_reply;
  2257. int rc, i, count;
  2258. u16 ioc_status;
  2259. rc = mpt3sas_config_update_driver_trigger_pg0(ioc,
  2260. MPI26_DRIVER_TRIGGER0_FLAG_SCSI_SENSE_TRIGGER_VALID, set);
  2261. if (rc)
  2262. return rc;
  2263. rc = mpt3sas_config_get_driver_trigger_pg3(ioc, &mpi_reply, &tg_pg3);
  2264. if (rc)
  2265. goto out;
  2266. ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
  2267. MPI2_IOCSTATUS_MASK;
  2268. if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
  2269. dcprintk(ioc,
  2270. ioc_err(ioc,
  2271. "%s: Failed to get trigger pg3, ioc_status(0x%04x)\n",
  2272. __func__, ioc_status));
  2273. return -EFAULT;
  2274. }
  2275. if (set) {
  2276. count = scsi_tg->ValidEntries;
  2277. tg_pg3.NumSCSISenseTrigger = cpu_to_le16(count);
  2278. for (i = 0; i < count; i++) {
  2279. tg_pg3.SCSISenseTriggers[i].ASCQ =
  2280. scsi_tg->SCSITriggerEntry[i].ASCQ;
  2281. tg_pg3.SCSISenseTriggers[i].ASC =
  2282. scsi_tg->SCSITriggerEntry[i].ASC;
  2283. tg_pg3.SCSISenseTriggers[i].SenseKey =
  2284. scsi_tg->SCSITriggerEntry[i].SenseKey;
  2285. }
  2286. } else {
  2287. tg_pg3.NumSCSISenseTrigger = 0;
  2288. memset(&tg_pg3.SCSISenseTriggers[0], 0,
  2289. NUM_VALID_ENTRIES * sizeof(
  2290. MPI26_DRIVER_SCSI_SENSE_TIGGER_ENTRY));
  2291. }
  2292. rc = _config_set_driver_trigger_pg3(ioc, &mpi_reply, &tg_pg3);
  2293. if (rc)
  2294. goto out;
  2295. ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
  2296. MPI2_IOCSTATUS_MASK;
  2297. if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
  2298. dcprintk(ioc,
  2299. ioc_err(ioc,
  2300. "%s: Failed to get trigger pg3, ioc_status(0x%04x)\n",
  2301. __func__, ioc_status));
  2302. return -EFAULT;
  2303. }
  2304. return 0;
  2305. out:
  2306. mpt3sas_config_update_driver_trigger_pg0(ioc,
  2307. MPI26_DRIVER_TRIGGER0_FLAG_SCSI_SENSE_TRIGGER_VALID, !set);
  2308. return rc;
  2309. }
  2310. /**
  2311. * mpt3sas_config_get_driver_trigger_pg4 - obtain driver trigger page 4
  2312. * @ioc: per adapter object
  2313. * @mpi_reply: reply mf payload returned from firmware
  2314. * @config_page: contents of the config page
  2315. * Context: sleep.
  2316. *
  2317. * Returns 0 for success, non-zero for failure.
  2318. */
  2319. int
  2320. mpt3sas_config_get_driver_trigger_pg4(struct MPT3SAS_ADAPTER *ioc,
  2321. Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage4_t *config_page)
  2322. {
  2323. Mpi2ConfigRequest_t mpi_request;
  2324. int r;
  2325. memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  2326. mpi_request.Function = MPI2_FUNCTION_CONFIG;
  2327. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  2328. mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
  2329. mpi_request.ExtPageType =
  2330. MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
  2331. mpi_request.Header.PageNumber = 4;
  2332. mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE4_PAGEVERSION;
  2333. ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
  2334. r = _config_request(ioc, &mpi_request, mpi_reply,
  2335. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
  2336. if (r)
  2337. goto out;
  2338. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
  2339. r = _config_request(ioc, &mpi_request, mpi_reply,
  2340. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
  2341. sizeof(*config_page));
  2342. out:
  2343. return r;
  2344. }
  2345. /**
  2346. * _config_set_driver_trigger_pg4 - write driver trigger page 4
  2347. * @ioc: per adapter object
  2348. * @mpi_reply: reply mf payload returned from firmware
  2349. * @config_page: contents of the config page
  2350. * Context: sleep.
  2351. *
  2352. * Returns 0 for success, non-zero for failure.
  2353. */
  2354. static int
  2355. _config_set_driver_trigger_pg4(struct MPT3SAS_ADAPTER *ioc,
  2356. Mpi2ConfigReply_t *mpi_reply, Mpi26DriverTriggerPage4_t *config_page)
  2357. {
  2358. Mpi2ConfigRequest_t mpi_request;
  2359. int r;
  2360. memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  2361. mpi_request.Function = MPI2_FUNCTION_CONFIG;
  2362. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  2363. mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
  2364. mpi_request.ExtPageType =
  2365. MPI2_CONFIG_EXTPAGETYPE_DRIVER_PERSISTENT_TRIGGER;
  2366. mpi_request.Header.PageNumber = 4;
  2367. mpi_request.Header.PageVersion = MPI26_DRIVER_TRIGGER_PAGE4_PAGEVERSION;
  2368. ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
  2369. r = _config_request(ioc, &mpi_request, mpi_reply,
  2370. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
  2371. if (r)
  2372. goto out;
  2373. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
  2374. _config_request(ioc, &mpi_request, mpi_reply,
  2375. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
  2376. sizeof(*config_page));
  2377. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;
  2378. r = _config_request(ioc, &mpi_request, mpi_reply,
  2379. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
  2380. sizeof(*config_page));
  2381. out:
  2382. return r;
  2383. }
  2384. /**
  2385. * mpt3sas_config_update_driver_trigger_pg4 - update driver trigger page 4
  2386. * @ioc: per adapter object
  2387. * @mpi_tg: mpi trigger list
  2388. * @set: set ot clear trigger values
  2389. * Context: sleep.
  2390. *
  2391. * Returns 0 for success, non-zero for failure.
  2392. */
  2393. int
  2394. mpt3sas_config_update_driver_trigger_pg4(struct MPT3SAS_ADAPTER *ioc,
  2395. struct SL_WH_MPI_TRIGGERS_T *mpi_tg, bool set)
  2396. {
  2397. Mpi26DriverTriggerPage4_t tg_pg4;
  2398. Mpi2ConfigReply_t mpi_reply;
  2399. int rc, i, count;
  2400. u16 ioc_status;
  2401. rc = mpt3sas_config_update_driver_trigger_pg0(ioc,
  2402. MPI26_DRIVER_TRIGGER0_FLAG_LOGINFO_TRIGGER_VALID, set);
  2403. if (rc)
  2404. return rc;
  2405. rc = mpt3sas_config_get_driver_trigger_pg4(ioc, &mpi_reply, &tg_pg4);
  2406. if (rc)
  2407. goto out;
  2408. ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
  2409. MPI2_IOCSTATUS_MASK;
  2410. if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
  2411. dcprintk(ioc,
  2412. ioc_err(ioc,
  2413. "%s: Failed to get trigger pg4, ioc_status(0x%04x)\n",
  2414. __func__, ioc_status));
  2415. rc = -EFAULT;
  2416. goto out;
  2417. }
  2418. if (set) {
  2419. count = mpi_tg->ValidEntries;
  2420. tg_pg4.NumIOCStatusLogInfoTrigger = cpu_to_le16(count);
  2421. for (i = 0; i < count; i++) {
  2422. tg_pg4.IOCStatusLoginfoTriggers[i].IOCStatus =
  2423. cpu_to_le16(mpi_tg->MPITriggerEntry[i].IOCStatus);
  2424. tg_pg4.IOCStatusLoginfoTriggers[i].LogInfo =
  2425. cpu_to_le32(mpi_tg->MPITriggerEntry[i].IocLogInfo);
  2426. }
  2427. } else {
  2428. tg_pg4.NumIOCStatusLogInfoTrigger = 0;
  2429. memset(&tg_pg4.IOCStatusLoginfoTriggers[0], 0,
  2430. NUM_VALID_ENTRIES * sizeof(
  2431. MPI26_DRIVER_IOCSTATUS_LOGINFO_TIGGER_ENTRY));
  2432. }
  2433. rc = _config_set_driver_trigger_pg4(ioc, &mpi_reply, &tg_pg4);
  2434. if (rc)
  2435. goto out;
  2436. ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
  2437. MPI2_IOCSTATUS_MASK;
  2438. if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
  2439. dcprintk(ioc,
  2440. ioc_err(ioc,
  2441. "%s: Failed to get trigger pg4, ioc_status(0x%04x)\n",
  2442. __func__, ioc_status));
  2443. rc = -EFAULT;
  2444. goto out;
  2445. }
  2446. return 0;
  2447. out:
  2448. mpt3sas_config_update_driver_trigger_pg0(ioc,
  2449. MPI26_DRIVER_TRIGGER0_FLAG_LOGINFO_TRIGGER_VALID, !set);
  2450. return rc;
  2451. }
  2452. /**
  2453. * mpt3sas_config_get_volume_handle - returns volume handle for give hidden
  2454. * raid components
  2455. * @ioc: per adapter object
  2456. * @pd_handle: phys disk handle
  2457. * @volume_handle: volume handle
  2458. * Context: sleep.
  2459. *
  2460. * Return: 0 for success, non-zero for failure.
  2461. */
  2462. int
  2463. mpt3sas_config_get_volume_handle(struct MPT3SAS_ADAPTER *ioc, u16 pd_handle,
  2464. u16 *volume_handle)
  2465. {
  2466. Mpi2RaidConfigurationPage0_t *config_page = NULL;
  2467. Mpi2ConfigRequest_t mpi_request;
  2468. Mpi2ConfigReply_t mpi_reply;
  2469. int r, i, config_page_sz;
  2470. u16 ioc_status;
  2471. int config_num;
  2472. u16 element_type;
  2473. u16 phys_disk_dev_handle;
  2474. *volume_handle = 0;
  2475. memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
  2476. mpi_request.Function = MPI2_FUNCTION_CONFIG;
  2477. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  2478. mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
  2479. mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_RAID_CONFIG;
  2480. mpi_request.Header.PageVersion = MPI2_RAIDCONFIG0_PAGEVERSION;
  2481. mpi_request.Header.PageNumber = 0;
  2482. ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE);
  2483. r = _config_request(ioc, &mpi_request, &mpi_reply,
  2484. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
  2485. if (r)
  2486. goto out;
  2487. mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
  2488. config_page_sz = (le16_to_cpu(mpi_reply.ExtPageLength) * 4);
  2489. config_page = kmalloc(config_page_sz, GFP_KERNEL);
  2490. if (!config_page) {
  2491. r = -1;
  2492. goto out;
  2493. }
  2494. config_num = 0xff;
  2495. while (1) {
  2496. mpi_request.PageAddress = cpu_to_le32(config_num +
  2497. MPI2_RAID_PGAD_FORM_GET_NEXT_CONFIGNUM);
  2498. r = _config_request(ioc, &mpi_request, &mpi_reply,
  2499. MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
  2500. config_page_sz);
  2501. if (r)
  2502. goto out;
  2503. r = -1;
  2504. ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
  2505. MPI2_IOCSTATUS_MASK;
  2506. if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
  2507. goto out;
  2508. for (i = 0; i < config_page->NumElements; i++) {
  2509. element_type = le16_to_cpu(config_page->
  2510. ConfigElement[i].ElementFlags) &
  2511. MPI2_RAIDCONFIG0_EFLAGS_MASK_ELEMENT_TYPE;
  2512. if (element_type ==
  2513. MPI2_RAIDCONFIG0_EFLAGS_VOL_PHYS_DISK_ELEMENT ||
  2514. element_type ==
  2515. MPI2_RAIDCONFIG0_EFLAGS_OCE_ELEMENT) {
  2516. phys_disk_dev_handle =
  2517. le16_to_cpu(config_page->ConfigElement[i].
  2518. PhysDiskDevHandle);
  2519. if (phys_disk_dev_handle == pd_handle) {
  2520. *volume_handle =
  2521. le16_to_cpu(config_page->
  2522. ConfigElement[i].VolDevHandle);
  2523. r = 0;
  2524. goto out;
  2525. }
  2526. } else if (element_type ==
  2527. MPI2_RAIDCONFIG0_EFLAGS_HOT_SPARE_ELEMENT) {
  2528. *volume_handle = 0;
  2529. r = 0;
  2530. goto out;
  2531. }
  2532. }
  2533. config_num = config_page->ConfigNum;
  2534. }
  2535. out:
  2536. kfree(config_page);
  2537. return r;
  2538. }
  2539. /**
  2540. * mpt3sas_config_get_volume_wwid - returns wwid given the volume handle
  2541. * @ioc: per adapter object
  2542. * @volume_handle: volume handle
  2543. * @wwid: volume wwid
  2544. * Context: sleep.
  2545. *
  2546. * Return: 0 for success, non-zero for failure.
  2547. */
  2548. int
  2549. mpt3sas_config_get_volume_wwid(struct MPT3SAS_ADAPTER *ioc, u16 volume_handle,
  2550. u64 *wwid)
  2551. {
  2552. Mpi2ConfigReply_t mpi_reply;
  2553. Mpi2RaidVolPage1_t raid_vol_pg1;
  2554. *wwid = 0;
  2555. if (!(mpt3sas_config_get_raid_volume_pg1(ioc, &mpi_reply,
  2556. &raid_vol_pg1, MPI2_RAID_VOLUME_PGAD_FORM_HANDLE,
  2557. volume_handle))) {
  2558. *wwid = le64_to_cpu(raid_vol_pg1.WWID);
  2559. return 0;
  2560. } else
  2561. return -1;
  2562. }