The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/mpr/mpr_config.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 2011-2015 LSI Corp.
    3  * Copyright (c) 2013-2016 Avago Technologies
    4  * All rights reserved.
    5  *
    6  * Redistribution and use in source and binary forms, with or without
    7  * modification, are permitted provided that the following conditions
    8  * are met:
    9  * 1. Redistributions of source code must retain the above copyright
   10  *    notice, this list of conditions and the following disclaimer.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  *
   15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   25  * SUCH DAMAGE.
   26  *
   27  * Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD
   28  */
   29 
   30 #include <sys/cdefs.h>
   31 __FBSDID("$FreeBSD$");
   32 
   33 /* TODO Move headers to mprvar */
   34 #include <sys/types.h>
   35 #include <sys/param.h>
   36 #include <sys/lock.h>
   37 #include <sys/mutex.h>
   38 #include <sys/systm.h>
   39 #include <sys/kernel.h>
   40 #include <sys/malloc.h>
   41 #include <sys/kthread.h>
   42 #include <sys/taskqueue.h>
   43 #include <sys/bus.h>
   44 #include <sys/endian.h>
   45 #include <sys/sysctl.h>
   46 #include <sys/eventhandler.h>
   47 #include <sys/uio.h>
   48 #include <machine/bus.h>
   49 #include <machine/resource.h>
   50 #include <dev/mpr/mpi/mpi2_type.h>
   51 #include <dev/mpr/mpi/mpi2.h>
   52 #include <dev/mpr/mpi/mpi2_ioc.h>
   53 #include <dev/mpr/mpi/mpi2_sas.h>
   54 #include <dev/mpr/mpi/mpi2_pci.h>
   55 #include <dev/mpr/mpi/mpi2_cnfg.h>
   56 #include <dev/mpr/mpi/mpi2_init.h>
   57 #include <dev/mpr/mpi/mpi2_tool.h>
   58 #include <dev/mpr/mpr_ioctl.h>
   59 #include <dev/mpr/mprvar.h>
   60 
   61 /**
   62  * mpr_config_get_ioc_pg8 - obtain ioc page 8
   63  * @sc: per adapter object
   64  * @mpi_reply: reply mf payload returned from firmware
   65  * @config_page: contents of the config page
   66  * Context: sleep.
   67  *
   68  * Returns 0 for success, non-zero for failure.
   69  */
   70 int
   71 mpr_config_get_ioc_pg8(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply,
   72     Mpi2IOCPage8_t *config_page)
   73 {
   74         MPI2_CONFIG_REQUEST *request;
   75         MPI2_CONFIG_REPLY *reply;
   76         struct mpr_command *cm;
   77         MPI2_CONFIG_PAGE_IOC_8 *page = NULL;
   78         int error = 0;
   79         u16 ioc_status;
   80 
   81         mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
   82 
   83         if ((cm = mpr_alloc_command(sc)) == NULL) {
   84                 printf("%s: command alloc failed @ line %d\n", __func__,
   85                     __LINE__);
   86                 error = EBUSY;
   87                 goto out;
   88         }
   89         request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
   90         bzero(request, sizeof(MPI2_CONFIG_REQUEST));
   91         request->Function = MPI2_FUNCTION_CONFIG;
   92         request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
   93         request->Header.PageType = MPI2_CONFIG_PAGETYPE_IOC;
   94         request->Header.PageNumber = 8;
   95         request->Header.PageLength = request->Header.PageVersion = 0;
   96         cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
   97         cm->cm_data = NULL;
   98         error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
   99         if (cm != NULL)
  100                 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
  101         if (error || (reply == NULL)) {
  102                 /* FIXME */
  103                 /*
  104                  * If the request returns an error then we need to do a diag
  105                  * reset
  106                  */ 
  107                 printf("%s: request for header completed with error %d",
  108                     __func__, error);
  109                 error = ENXIO;
  110                 goto out;
  111         }
  112         ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
  113         bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
  114         if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
  115                 /* FIXME */
  116                 /*
  117                  * If the request returns an error then we need to do a diag
  118                  * reset
  119                  */ 
  120                 printf("%s: header read with error; iocstatus = 0x%x\n",
  121                     __func__, ioc_status);
  122                 error = ENXIO;
  123                 goto out;
  124         }
  125         /* We have to do free and alloc for the reply-free and reply-post
  126          * counters to match - Need to review the reply FIFO handling.
  127          */
  128         mpr_free_command(sc, cm);
  129         
  130         if ((cm = mpr_alloc_command(sc)) == NULL) {
  131                 printf("%s: command alloc failed @ line %d\n", __func__,
  132                     __LINE__);
  133                 error = EBUSY;
  134                 goto out;
  135         }
  136         request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
  137         bzero(request, sizeof(MPI2_CONFIG_REQUEST));
  138         request->Function = MPI2_FUNCTION_CONFIG;
  139         request->Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
  140         request->Header.PageType = MPI2_CONFIG_PAGETYPE_IOC;
  141         request->Header.PageNumber = 8;
  142         request->Header.PageVersion = mpi_reply->Header.PageVersion;
  143         request->Header.PageLength = mpi_reply->Header.PageLength;
  144         cm->cm_length =  le16toh(mpi_reply->Header.PageLength) * 4;
  145         cm->cm_sge = &request->PageBufferSGE;
  146         cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
  147         cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
  148         cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
  149         page = malloc((cm->cm_length), M_MPR, M_ZERO | M_NOWAIT);
  150         if (!page) {
  151                 printf("%s: page alloc failed\n", __func__);
  152                 error = ENOMEM;
  153                 goto out;
  154         }
  155         cm->cm_data = page;
  156 
  157         error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
  158         if (cm != NULL)
  159                 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
  160         if (error || (reply == NULL)) {
  161                 /* FIXME */
  162                 /*
  163                  * If the request returns an error then we need to do a diag
  164                  * reset
  165                  */ 
  166                 printf("%s: request for page completed with error %d",
  167                     __func__, error);
  168                 error = ENXIO;
  169                 goto out;
  170         }
  171         ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
  172         bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
  173         if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
  174                 /* FIXME */
  175                 /*
  176                  * If the request returns an error then we need to do a diag
  177                  * reset
  178                  */ 
  179                 printf("%s: page read with error; iocstatus = 0x%x\n",
  180                     __func__, ioc_status);
  181                 error = ENXIO;
  182                 goto out;
  183         }
  184         bcopy(page, config_page, MIN(cm->cm_length, (sizeof(Mpi2IOCPage8_t))));
  185 
  186 out:
  187         free(page, M_MPR);
  188         if (cm)
  189                 mpr_free_command(sc, cm);
  190         return (error);
  191 }
  192 
  193 /**
  194  * mpr_config_get_iounit_pg8 - obtain iounit page 8
  195  * @sc: per adapter object
  196  * @mpi_reply: reply mf payload returned from firmware
  197  * @config_page: contents of the config page
  198  * Context: sleep.
  199  *
  200  * Returns 0 for success, non-zero for failure.
  201  */
  202 int
  203 mpr_config_get_iounit_pg8(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply,
  204     Mpi2IOUnitPage8_t *config_page)
  205 {
  206         MPI2_CONFIG_REQUEST *request;
  207         MPI2_CONFIG_REPLY *reply;
  208         struct mpr_command *cm;
  209         MPI2_CONFIG_PAGE_IO_UNIT_8 *page = NULL;
  210         int error = 0;
  211         u16 ioc_status;
  212 
  213         mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
  214 
  215         if ((cm = mpr_alloc_command(sc)) == NULL) {
  216                 printf("%s: command alloc failed @ line %d\n", __func__,
  217                     __LINE__);
  218                 error = EBUSY;
  219                 goto out;
  220         }
  221         request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
  222         bzero(request, sizeof(MPI2_CONFIG_REQUEST));
  223         request->Function = MPI2_FUNCTION_CONFIG;
  224         request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  225         request->Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
  226         request->Header.PageNumber = 8;
  227         request->Header.PageLength = request->Header.PageVersion = 0;
  228         cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
  229         cm->cm_data = NULL;
  230         error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
  231         if (cm != NULL)
  232                 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
  233         if (error || (reply == NULL)) {
  234                 /* FIXME */
  235                 /*
  236                  * If the request returns an error then we need to do a diag
  237                  * reset
  238                  */ 
  239                 printf("%s: request for header completed with error %d",
  240                     __func__, error);
  241                 error = ENXIO;
  242                 goto out;
  243         }
  244         ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
  245         bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
  246         if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
  247                 /* FIXME */
  248                 /*
  249                  * If the request returns an error then we need to do a diag
  250                  * reset
  251                  */ 
  252                 printf("%s: header read with error; iocstatus = 0x%x\n",
  253                     __func__, ioc_status);
  254                 error = ENXIO;
  255                 goto out;
  256         }
  257         /* We have to do free and alloc for the reply-free and reply-post
  258          * counters to match - Need to review the reply FIFO handling.
  259          */
  260         mpr_free_command(sc, cm);
  261         
  262         if ((cm = mpr_alloc_command(sc)) == NULL) {
  263                 printf("%s: command alloc failed @ line %d\n", __func__,
  264                     __LINE__);
  265                 error = EBUSY;
  266                 goto out;
  267         }
  268         request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
  269         bzero(request, sizeof(MPI2_CONFIG_REQUEST));
  270         request->Function = MPI2_FUNCTION_CONFIG;
  271         request->Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
  272         request->Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
  273         request->Header.PageNumber = 8;
  274         request->Header.PageVersion = mpi_reply->Header.PageVersion;
  275         request->Header.PageLength = mpi_reply->Header.PageLength;
  276         cm->cm_length =  le16toh(mpi_reply->Header.PageLength) * 4;
  277         cm->cm_sge = &request->PageBufferSGE;
  278         cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
  279         cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
  280         cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
  281         page = malloc((cm->cm_length), M_MPR, M_ZERO | M_NOWAIT);
  282         if (!page) {
  283                 printf("%s: page alloc failed\n", __func__);
  284                 error = ENOMEM;
  285                 goto out;
  286         }
  287         cm->cm_data = page;
  288 
  289         error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
  290         if (cm != NULL)
  291                 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
  292         if (error || (reply == NULL)) {
  293                 /* FIXME */
  294                 /*
  295                  * If the request returns an error then we need to do a diag
  296                  * reset
  297                  */ 
  298                 printf("%s: request for page completed with error %d",
  299                     __func__, error);
  300                 error = ENXIO;
  301                 goto out;
  302         }
  303         ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
  304         bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
  305         if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
  306                 /* FIXME */
  307                 /*
  308                  * If the request returns an error then we need to do a diag
  309                  * reset
  310                  */ 
  311                 printf("%s: page read with error; iocstatus = 0x%x\n",
  312                     __func__, ioc_status);
  313                 error = ENXIO;
  314                 goto out;
  315         }
  316         bcopy(page, config_page, MIN(cm->cm_length,
  317             (sizeof(Mpi2IOUnitPage8_t))));
  318 
  319 out:
  320         free(page, M_MPR);
  321         if (cm)
  322                 mpr_free_command(sc, cm);
  323         return (error);
  324 }
  325 
  326 /**
  327  * mpr_base_static_config_pages - static start of day config pages.
  328  * @sc: per adapter object
  329  *
  330  * Return nothing.
  331  */
  332 void
  333 mpr_base_static_config_pages(struct mpr_softc *sc)
  334 {
  335         Mpi2ConfigReply_t       mpi_reply;
  336         int                     retry;
  337 
  338         retry = 0;
  339         while (mpr_config_get_ioc_pg8(sc, &mpi_reply, &sc->ioc_pg8)) {
  340                 retry++;
  341                 if (retry > 5) {
  342                         /* We need to Handle this situation */
  343                         /*FIXME*/
  344                         break;
  345                 }
  346         }
  347         retry = 0;
  348         while (mpr_config_get_iounit_pg8(sc, &mpi_reply, &sc->iounit_pg8)) {
  349                 retry++;
  350                 if (retry > 5) {
  351                         /* We need to Handle this situation */
  352                         /*FIXME*/
  353                         break;
  354                 }
  355         }
  356 }
  357 
  358 /**
  359  * mpr_config_get_dpm_pg0 - obtain driver persistent mapping page0
  360  * @sc: per adapter object
  361  * @mpi_reply: reply mf payload returned from firmware
  362  * @config_page: contents of the config page
  363  * @sz: size of buffer passed in config_page
  364  * Context: sleep.
  365  *
  366  * Returns 0 for success, non-zero for failure.
  367  */
  368 int
  369 mpr_config_get_dpm_pg0(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply,
  370     Mpi2DriverMappingPage0_t *config_page, u16 sz)
  371 {
  372         MPI2_CONFIG_REQUEST *request;
  373         MPI2_CONFIG_REPLY *reply;
  374         struct mpr_command *cm;
  375         Mpi2DriverMappingPage0_t *page = NULL;
  376         int error = 0;
  377         u16 ioc_status;
  378 
  379         mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
  380 
  381         memset(config_page, 0, sz);
  382         if ((cm = mpr_alloc_command(sc)) == NULL) {
  383                 printf("%s: command alloc failed @ line %d\n", __func__,
  384                     __LINE__);
  385                 error = EBUSY;
  386                 goto out;
  387         }
  388         request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
  389         bzero(request, sizeof(MPI2_CONFIG_REQUEST));
  390         request->Function = MPI2_FUNCTION_CONFIG;
  391         request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  392         request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
  393         request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING;
  394         request->Header.PageNumber = 0;
  395         request->ExtPageLength = request->Header.PageVersion = 0;
  396         request->PageAddress = sc->max_dpm_entries <<
  397             MPI2_DPM_PGAD_ENTRY_COUNT_SHIFT;
  398         cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
  399         cm->cm_data = NULL;
  400         error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
  401         if (cm != NULL)
  402                 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
  403         if (error || (reply == NULL)) {
  404                 /* FIXME */
  405                 /*
  406                  * If the request returns an error then we need to do a diag
  407                  * reset
  408                  */ 
  409                 printf("%s: request for header completed with error %d",
  410                     __func__, error);
  411                 error = ENXIO;
  412                 goto out;
  413         }
  414         ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
  415         bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
  416         if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
  417                 /* FIXME */
  418                 /*
  419                  * If the request returns an error then we need to do a diag
  420                  * reset
  421                  */ 
  422                 printf("%s: header read with error; iocstatus = 0x%x\n",
  423                     __func__, ioc_status);
  424                 error = ENXIO;
  425                 goto out;
  426         }
  427         /* We have to do free and alloc for the reply-free and reply-post
  428          * counters to match - Need to review the reply FIFO handling.
  429          */
  430         mpr_free_command(sc, cm);
  431 
  432         if ((cm = mpr_alloc_command(sc)) == NULL) {
  433                 printf("%s: command alloc failed @ line %d\n", __func__,
  434                     __LINE__);
  435                 error = EBUSY;
  436                 goto out;
  437         }
  438         request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
  439         bzero(request, sizeof(MPI2_CONFIG_REQUEST));
  440         request->Function = MPI2_FUNCTION_CONFIG;
  441         request->Action = MPI2_CONFIG_ACTION_PAGE_READ_NVRAM;
  442         request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
  443         request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING;
  444         request->Header.PageNumber = 0;
  445         request->Header.PageVersion = mpi_reply->Header.PageVersion;
  446         request->PageAddress = sc->max_dpm_entries <<
  447             MPI2_DPM_PGAD_ENTRY_COUNT_SHIFT;
  448         request->ExtPageLength = mpi_reply->ExtPageLength;
  449         cm->cm_length =  le16toh(request->ExtPageLength) * 4;
  450         cm->cm_sge = &request->PageBufferSGE;
  451         cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
  452         cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
  453         cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
  454         page = malloc(cm->cm_length, M_MPR, M_ZERO|M_NOWAIT);
  455         if (!page) {
  456                 printf("%s: page alloc failed\n", __func__);
  457                 error = ENOMEM;
  458                 goto out;
  459         }
  460         cm->cm_data = page;
  461         error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
  462         if (cm != NULL)
  463                 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
  464         if (error || (reply == NULL)) {
  465                 /* FIXME */
  466                 /*
  467                  * If the request returns an error then we need to do a diag
  468                  * reset
  469                  */ 
  470                 printf("%s: request for page completed with error %d",
  471                     __func__, error);
  472                 error = ENXIO;
  473                 goto out;
  474         }
  475         ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
  476         bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
  477         if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
  478                 /* FIXME */
  479                 /*
  480                  * If the request returns an error then we need to do a diag
  481                  * reset
  482                  */ 
  483                 printf("%s: page read with error; iocstatus = 0x%x\n",
  484                     __func__, ioc_status);
  485                 error = ENXIO;
  486                 goto out;
  487         }
  488         bcopy(page, config_page, MIN(cm->cm_length, sz));
  489 out:
  490         free(page, M_MPR);
  491         if (cm)
  492                 mpr_free_command(sc, cm);
  493         return (error);
  494 }
  495 
  496 /**
  497  * mpr_config_set_dpm_pg0 - write an entry in driver persistent mapping page0
  498  * @sc: per adapter object
  499  * @mpi_reply: reply mf payload returned from firmware
  500  * @config_page: contents of the config page
  501  * @entry_idx: entry index in DPM Page0 to be modified
  502  * Context: sleep.
  503  *
  504  * Returns 0 for success, non-zero for failure.
  505  */
  506 
  507 int mpr_config_set_dpm_pg0(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply,
  508     Mpi2DriverMappingPage0_t *config_page, u16 entry_idx)
  509 {
  510         MPI2_CONFIG_REQUEST *request;
  511         MPI2_CONFIG_REPLY *reply;
  512         struct mpr_command *cm;
  513         MPI2_CONFIG_PAGE_DRIVER_MAPPING_0 *page = NULL; 
  514         int error = 0;
  515         u16 ioc_status;
  516 
  517         mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
  518 
  519         if ((cm = mpr_alloc_command(sc)) == NULL) {
  520                 printf("%s: command alloc failed @ line %d\n", __func__,
  521                     __LINE__);
  522                 error = EBUSY;
  523                 goto out;
  524         }
  525         request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
  526         bzero(request, sizeof(MPI2_CONFIG_REQUEST));
  527         request->Function = MPI2_FUNCTION_CONFIG;
  528         request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  529         request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
  530         request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING;
  531         request->Header.PageNumber = 0;
  532         request->ExtPageLength = request->Header.PageVersion = 0;
  533         /* We can remove below two lines ????*/
  534         request->PageAddress = 1 << MPI2_DPM_PGAD_ENTRY_COUNT_SHIFT;
  535         request->PageAddress |= htole16(entry_idx);
  536         cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
  537         cm->cm_data = NULL;
  538         error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
  539         if (cm != NULL)
  540                 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
  541         if (error || (reply == NULL)) {
  542                 /* FIXME */
  543                 /*
  544                  * If the request returns an error then we need to do a diag
  545                  * reset
  546                  */ 
  547                 printf("%s: request for header completed with error %d",
  548                     __func__, error);
  549                 error = ENXIO;
  550                 goto out;
  551         }
  552         ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
  553         bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
  554         if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
  555                 /* FIXME */
  556                 /*
  557                  * If the request returns an error then we need to do a diag
  558                  * reset
  559                  */ 
  560                 printf("%s: header read with error; iocstatus = 0x%x\n",
  561                     __func__, ioc_status);
  562                 error = ENXIO;
  563                 goto out;
  564         }
  565         /* We have to do free and alloc for the reply-free and reply-post
  566          * counters to match - Need to review the reply FIFO handling.
  567          */     
  568         mpr_free_command(sc, cm);
  569 
  570         if ((cm = mpr_alloc_command(sc)) == NULL) {
  571                 printf("%s: command alloc failed @ line %d\n", __func__,
  572                     __LINE__);
  573                 error = EBUSY;
  574                 goto out;
  575         }
  576         request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
  577         bzero(request, sizeof(MPI2_CONFIG_REQUEST));
  578         request->Function = MPI2_FUNCTION_CONFIG;
  579         request->Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;
  580         request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
  581         request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING;
  582         request->Header.PageNumber = 0;
  583         request->Header.PageVersion = mpi_reply->Header.PageVersion;
  584         request->ExtPageLength = mpi_reply->ExtPageLength;
  585         request->PageAddress = 1 << MPI2_DPM_PGAD_ENTRY_COUNT_SHIFT;
  586         request->PageAddress |= htole16(entry_idx);
  587         cm->cm_length = le16toh(mpi_reply->ExtPageLength) * 4;
  588         cm->cm_sge = &request->PageBufferSGE;
  589         cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
  590         cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAOUT;
  591         cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
  592         page = malloc(cm->cm_length, M_MPR, M_ZERO | M_NOWAIT);
  593         if (!page) {
  594                 printf("%s: page alloc failed\n", __func__);
  595                 error = ENOMEM;
  596                 goto out;
  597         }
  598         bcopy(config_page, page, MIN(cm->cm_length, 
  599             (sizeof(Mpi2DriverMappingPage0_t))));
  600         cm->cm_data = page;
  601         error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
  602         if (cm != NULL)
  603                 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
  604         if (error || (reply == NULL)) {
  605                 /* FIXME */
  606                 /*
  607                  * If the request returns an error then we need to do a diag
  608                  * reset
  609                  */ 
  610                 printf("%s: request to write page completed with error %d",
  611                     __func__, error);
  612                 error = ENXIO;
  613                 goto out;
  614         }
  615         ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
  616         bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
  617         if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
  618                 /* FIXME */
  619                 /*
  620                  * If the request returns an error then we need to do a diag
  621                  * reset
  622                  */ 
  623                 printf("%s: page written with error; iocstatus = 0x%x\n",
  624                     __func__, ioc_status);
  625                 error = ENXIO;
  626                 goto out;
  627         }
  628 out:
  629         free(page, M_MPR);
  630         if (cm)
  631                 mpr_free_command(sc, cm);
  632         return (error);
  633 }
  634 
  635 /**
  636  * mpr_config_get_sas_device_pg0 - obtain sas device page 0
  637  * @sc: per adapter object
  638  * @mpi_reply: reply mf payload returned from firmware
  639  * @config_page: contents of the config page
  640  * @form: GET_NEXT_HANDLE or HANDLE
  641  * @handle: device handle
  642  * Context: sleep.
  643  *
  644  * Returns 0 for success, non-zero for failure.
  645  */
  646 int
  647 mpr_config_get_sas_device_pg0(struct mpr_softc *sc, Mpi2ConfigReply_t
  648     *mpi_reply, Mpi2SasDevicePage0_t *config_page, u32 form, u16 handle)
  649 {
  650         MPI2_CONFIG_REQUEST *request;
  651         MPI2_CONFIG_REPLY *reply;
  652         struct mpr_command *cm;
  653         Mpi2SasDevicePage0_t *page = NULL;
  654         int error = 0;
  655         u16 ioc_status;
  656 
  657         mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
  658 
  659         if ((cm = mpr_alloc_command(sc)) == NULL) {
  660                 printf("%s: command alloc failed @ line %d\n", __func__,
  661                     __LINE__);
  662                 error = EBUSY;
  663                 goto out;
  664         }
  665         request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
  666         bzero(request, sizeof(MPI2_CONFIG_REQUEST));
  667         request->Function = MPI2_FUNCTION_CONFIG;
  668         request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  669         request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
  670         request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE;
  671         request->Header.PageNumber = 0;
  672         request->ExtPageLength = request->Header.PageVersion = 0;
  673         cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
  674         cm->cm_data = NULL;
  675         error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
  676         if (cm != NULL)
  677                 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
  678         if (error || (reply == NULL)) {
  679                 /* FIXME */
  680                 /*
  681                  * If the request returns an error then we need to do a diag
  682                  * reset
  683                  */ 
  684                 printf("%s: request for header completed with error %d",
  685                     __func__, error);
  686                 error = ENXIO;
  687                 goto out;
  688         }
  689         ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
  690         bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
  691         if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
  692                 /* FIXME */
  693                 /*
  694                  * If the request returns an error then we need to do a diag
  695                  * reset
  696                  */ 
  697                 printf("%s: header read with error; iocstatus = 0x%x\n",
  698                     __func__, ioc_status);
  699                 error = ENXIO;
  700                 goto out;
  701         }
  702         /* We have to do free and alloc for the reply-free and reply-post
  703          * counters to match - Need to review the reply FIFO handling.
  704          */
  705         mpr_free_command(sc, cm);
  706 
  707         if ((cm = mpr_alloc_command(sc)) == NULL) {
  708                 printf("%s: command alloc failed @ line %d\n", __func__,
  709                     __LINE__);
  710                 error = EBUSY;
  711                 goto out;
  712         }
  713         request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
  714         bzero(request, sizeof(MPI2_CONFIG_REQUEST));
  715         request->Function = MPI2_FUNCTION_CONFIG;
  716         request->Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
  717         request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
  718         request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE;
  719         request->Header.PageNumber = 0;
  720         request->Header.PageVersion = mpi_reply->Header.PageVersion;
  721         request->ExtPageLength = mpi_reply->ExtPageLength;
  722         request->PageAddress = htole32(form | handle);
  723         cm->cm_length = le16toh(mpi_reply->ExtPageLength) * 4;
  724         cm->cm_sge = &request->PageBufferSGE;
  725         cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
  726         cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
  727         cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
  728         page = malloc(cm->cm_length, M_MPR, M_ZERO | M_NOWAIT);
  729         if (!page) {
  730                 printf("%s: page alloc failed\n", __func__);
  731                 error = ENOMEM;
  732                 goto out;
  733         }
  734         cm->cm_data = page;
  735 
  736         error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
  737         if (cm != NULL)
  738                 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
  739         if (error || (reply == NULL)) {
  740                 /* FIXME */
  741                 /*
  742                  * If the request returns an error then we need to do a diag
  743                  * reset
  744                  */ 
  745                 printf("%s: request for page completed with error %d",
  746                     __func__, error);
  747                 error = ENXIO;
  748                 goto out;
  749         }
  750         ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
  751         bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
  752         if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
  753                 /* FIXME */
  754                 /*
  755                  * If the request returns an error then we need to do a diag
  756                  * reset
  757                  */ 
  758                 printf("%s: page read with error; iocstatus = 0x%x\n",
  759                     __func__, ioc_status);
  760                 error = ENXIO;
  761                 goto out;
  762         }
  763         bcopy(page, config_page, MIN(cm->cm_length, 
  764             sizeof(Mpi2SasDevicePage0_t)));
  765 out:
  766         free(page, M_MPR);
  767         if (cm)
  768                 mpr_free_command(sc, cm);
  769         return (error);
  770 }
  771 
  772 /**
  773  * mpr_config_get_pcie_device_pg0 - obtain PCIe device page 0
  774  * @sc: per adapter object
  775  * @mpi_reply: reply mf payload returned from firmware
  776  * @config_page: contents of the config page
  777  * @form: GET_NEXT_HANDLE or HANDLE
  778  * @handle: device handle
  779  * Context: sleep.
  780  *
  781  * Returns 0 for success, non-zero for failure.
  782  */
  783 int
  784 mpr_config_get_pcie_device_pg0(struct mpr_softc *sc, Mpi2ConfigReply_t
  785     *mpi_reply, Mpi26PCIeDevicePage0_t *config_page, u32 form, u16 handle)
  786 {
  787         MPI2_CONFIG_REQUEST *request;
  788         MPI2_CONFIG_REPLY *reply;
  789         struct mpr_command *cm;
  790         Mpi26PCIeDevicePage0_t *page = NULL;
  791         int error = 0;
  792         u16 ioc_status;
  793 
  794         mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
  795 
  796         if ((cm = mpr_alloc_command(sc)) == NULL) {
  797                 printf("%s: command alloc failed @ line %d\n", __func__,
  798                     __LINE__);
  799                 error = EBUSY;
  800                 goto out;
  801         }
  802         request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
  803         bzero(request, sizeof(MPI2_CONFIG_REQUEST));
  804         request->Function = MPI2_FUNCTION_CONFIG;
  805         request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  806         request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
  807         request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE;
  808         request->Header.PageNumber = 0;
  809         request->ExtPageLength = request->Header.PageVersion = 0;
  810         cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
  811         cm->cm_data = NULL;
  812         error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
  813         if (cm != NULL)
  814                 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
  815         if (error || (reply == NULL)) {
  816                 /* FIXME */
  817                 /*
  818                  * If the request returns an error then we need to do a diag
  819                  * reset
  820                  */ 
  821                 printf("%s: request for header completed with error %d",
  822                     __func__, error);
  823                 error = ENXIO;
  824                 goto out;
  825         }
  826         ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
  827         bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
  828         if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
  829                 /* FIXME */
  830                 /*
  831                  * If the request returns an error then we need to do a diag
  832                  * reset
  833                  */ 
  834                 printf("%s: header read with error; iocstatus = 0x%x\n",
  835                     __func__, ioc_status);
  836                 error = ENXIO;
  837                 goto out;
  838         }
  839         /* We have to do free and alloc for the reply-free and reply-post
  840          * counters to match - Need to review the reply FIFO handling.
  841          */
  842         mpr_free_command(sc, cm);
  843 
  844         if ((cm = mpr_alloc_command(sc)) == NULL) {
  845                 printf("%s: command alloc failed @ line %d\n", __func__,
  846                     __LINE__);
  847                 error = EBUSY;
  848                 goto out;
  849         }
  850         request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
  851         bzero(request, sizeof(MPI2_CONFIG_REQUEST));
  852         request->Function = MPI2_FUNCTION_CONFIG;
  853         request->Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
  854         request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
  855         request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE;
  856         request->Header.PageNumber = 0;
  857         request->Header.PageVersion = mpi_reply->Header.PageVersion;
  858         request->ExtPageLength = mpi_reply->ExtPageLength;
  859         request->PageAddress = htole32(form | handle);
  860         cm->cm_length = le16toh(mpi_reply->ExtPageLength) * 4;
  861         cm->cm_sge = &request->PageBufferSGE;
  862         cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
  863         cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
  864         cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
  865         page = malloc(cm->cm_length, M_MPR, M_ZERO | M_NOWAIT);
  866         if (!page) {
  867                 printf("%s: page alloc failed\n", __func__);
  868                 error = ENOMEM;
  869                 goto out;
  870         }
  871         cm->cm_data = page;
  872 
  873         error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
  874         if (cm != NULL)
  875                 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
  876         if (error || (reply == NULL)) {
  877                 /* FIXME */
  878                 /*
  879                  * If the request returns an error then we need to do a diag
  880                  * reset
  881                  */ 
  882                 printf("%s: request for page completed with error %d",
  883                     __func__, error);
  884                 error = ENXIO;
  885                 goto out;
  886         }
  887         ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
  888         bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
  889         if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
  890                 /* FIXME */
  891                 /*
  892                  * If the request returns an error then we need to do a diag
  893                  * reset
  894                  */ 
  895                 printf("%s: page read with error; iocstatus = 0x%x\n",
  896                     __func__, ioc_status);
  897                 error = ENXIO;
  898                 goto out;
  899         }
  900         bcopy(page, config_page, MIN(cm->cm_length, 
  901             sizeof(Mpi26PCIeDevicePage0_t)));
  902 out:
  903         free(page, M_MPR);
  904         if (cm)
  905                 mpr_free_command(sc, cm);
  906         return (error);
  907 }
  908 
  909 /**
  910  * mpr_config_get_pcie_device_pg2 - obtain PCIe device page 2
  911  * @sc: per adapter object
  912  * @mpi_reply: reply mf payload returned from firmware
  913  * @config_page: contents of the config page
  914  * @form: GET_NEXT_HANDLE or HANDLE
  915  * @handle: device handle
  916  * Context: sleep.
  917  *
  918  * Returns 0 for success, non-zero for failure.
  919  */
  920 int
  921 mpr_config_get_pcie_device_pg2(struct mpr_softc *sc, Mpi2ConfigReply_t
  922     *mpi_reply, Mpi26PCIeDevicePage2_t *config_page, u32 form, u16 handle)
  923 {
  924         MPI2_CONFIG_REQUEST *request;
  925         MPI2_CONFIG_REPLY *reply;
  926         struct mpr_command *cm;
  927         Mpi26PCIeDevicePage2_t *page = NULL;
  928         int error = 0;
  929         u16 ioc_status;
  930 
  931         mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
  932 
  933         if ((cm = mpr_alloc_command(sc)) == NULL) {
  934                 printf("%s: command alloc failed @ line %d\n", __func__,
  935                     __LINE__);
  936                 error = EBUSY;
  937                 goto out;
  938         }
  939         request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
  940         bzero(request, sizeof(MPI2_CONFIG_REQUEST));
  941         request->Function = MPI2_FUNCTION_CONFIG;
  942         request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
  943         request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
  944         request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE;
  945         request->Header.PageNumber = 2;
  946         request->ExtPageLength = request->Header.PageVersion = 0;
  947         cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
  948         cm->cm_data = NULL;
  949         error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
  950         if (cm != NULL)
  951                 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
  952         if (error || (reply == NULL)) {
  953                 /* FIXME */
  954                 /*
  955                  * If the request returns an error then we need to do a diag
  956                  * reset
  957                  */ 
  958                 printf("%s: request for header completed with error %d",
  959                     __func__, error);
  960                 error = ENXIO;
  961                 goto out;
  962         }
  963         ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
  964         bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
  965         if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
  966                 /* FIXME */
  967                 /*
  968                  * If the request returns an error then we need to do a diag
  969                  * reset
  970                  */ 
  971                 printf("%s: header read with error; iocstatus = 0x%x\n",
  972                     __func__, ioc_status);
  973                 error = ENXIO;
  974                 goto out;
  975         }
  976         /* We have to do free and alloc for the reply-free and reply-post
  977          * counters to match - Need to review the reply FIFO handling.
  978          */
  979         mpr_free_command(sc, cm);
  980 
  981         if ((cm = mpr_alloc_command(sc)) == NULL) {
  982                 printf("%s: command alloc failed @ line %d\n", __func__,
  983                     __LINE__);
  984                 error = EBUSY;
  985                 goto out;
  986         }
  987         request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
  988         bzero(request, sizeof(MPI2_CONFIG_REQUEST));
  989         request->Function = MPI2_FUNCTION_CONFIG;
  990         request->Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
  991         request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
  992         request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE;
  993         request->Header.PageNumber = 2;
  994         request->Header.PageVersion = mpi_reply->Header.PageVersion;
  995         request->ExtPageLength = mpi_reply->ExtPageLength;
  996         request->PageAddress = htole32(form | handle);
  997         cm->cm_length = le16toh(mpi_reply->ExtPageLength) * 4;
  998         cm->cm_sge = &request->PageBufferSGE;
  999         cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
 1000         cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
 1001         cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
 1002         page = malloc(cm->cm_length, M_MPR, M_ZERO | M_NOWAIT);
 1003         if (!page) {
 1004                 printf("%s: page alloc failed\n", __func__);
 1005                 error = ENOMEM;
 1006                 goto out;
 1007         }
 1008         cm->cm_data = page;
 1009 
 1010         error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
 1011         if (cm != NULL)
 1012                 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
 1013         if (error || (reply == NULL)) {
 1014                 /* FIXME */
 1015                 /*
 1016                  * If the request returns an error then we need to do a diag
 1017                  * reset
 1018                  */ 
 1019                 printf("%s: request for page completed with error %d",
 1020                     __func__, error);
 1021                 error = ENXIO;
 1022                 goto out;
 1023         }
 1024         ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
 1025         bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
 1026         if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
 1027                 /* FIXME */
 1028                 /*
 1029                  * If the request returns an error then we need to do a diag
 1030                  * reset
 1031                  */ 
 1032                 printf("%s: page read with error; iocstatus = 0x%x\n",
 1033                     __func__, ioc_status);
 1034                 error = ENXIO;
 1035                 goto out;
 1036         }
 1037         bcopy(page, config_page, MIN(cm->cm_length, 
 1038             sizeof(Mpi26PCIeDevicePage2_t)));
 1039 out:
 1040         free(page, M_MPR);
 1041         if (cm)
 1042                 mpr_free_command(sc, cm);
 1043         return (error);
 1044 }
 1045 
 1046 /**
 1047  * mpr_config_get_bios_pg3 - obtain BIOS page 3
 1048  * @sc: per adapter object
 1049  * @mpi_reply: reply mf payload returned from firmware
 1050  * @config_page: contents of the config page
 1051  * Context: sleep.
 1052  *
 1053  * Returns 0 for success, non-zero for failure.
 1054  */
 1055 int
 1056 mpr_config_get_bios_pg3(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply,
 1057     Mpi2BiosPage3_t *config_page)
 1058 {
 1059         MPI2_CONFIG_REQUEST *request;
 1060         MPI2_CONFIG_REPLY *reply;
 1061         struct mpr_command *cm;
 1062         Mpi2BiosPage3_t *page = NULL;
 1063         int error = 0;
 1064         u16 ioc_status;
 1065 
 1066         mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
 1067 
 1068         if ((cm = mpr_alloc_command(sc)) == NULL) {
 1069                 printf("%s: command alloc failed @ line %d\n", __func__,
 1070                     __LINE__);
 1071                 error = EBUSY;
 1072                 goto out;
 1073         }
 1074         request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
 1075         bzero(request, sizeof(MPI2_CONFIG_REQUEST));
 1076         request->Function = MPI2_FUNCTION_CONFIG;
 1077         request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
 1078         request->Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS;
 1079         request->Header.PageNumber = 3;
 1080         request->Header.PageLength = request->Header.PageVersion = 0;
 1081         cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
 1082         cm->cm_data = NULL;
 1083         error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
 1084         if (cm != NULL)
 1085                 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
 1086         if (error || (reply == NULL)) {
 1087                 /* FIXME */
 1088                 /*
 1089                  * If the request returns an error then we need to do a diag
 1090                  * reset
 1091                  */ 
 1092                 printf("%s: request for header completed with error %d",
 1093                     __func__, error);
 1094                 error = ENXIO;
 1095                 goto out;
 1096         }
 1097         ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
 1098         bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
 1099         if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
 1100                 /* FIXME */
 1101                 /*
 1102                  * If the request returns an error then we need to do a diag
 1103                  * reset
 1104                  */ 
 1105                 printf("%s: header read with error; iocstatus = 0x%x\n",
 1106                     __func__, ioc_status);
 1107                 error = ENXIO;
 1108                 goto out;
 1109         }
 1110         /* We have to do free and alloc for the reply-free and reply-post
 1111          * counters to match - Need to review the reply FIFO handling.
 1112          */
 1113         mpr_free_command(sc, cm);
 1114 
 1115         if ((cm = mpr_alloc_command(sc)) == NULL) {
 1116                 printf("%s: command alloc failed @ line %d\n", __func__,
 1117                     __LINE__);
 1118                 error = EBUSY;
 1119                 goto out;
 1120         }
 1121         request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
 1122         bzero(request, sizeof(MPI2_CONFIG_REQUEST));
 1123         request->Function = MPI2_FUNCTION_CONFIG;
 1124         request->Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
 1125         request->Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS;
 1126         request->Header.PageNumber = 3;
 1127         request->Header.PageVersion = mpi_reply->Header.PageVersion;
 1128         request->Header.PageLength = mpi_reply->Header.PageLength;
 1129         cm->cm_length = le16toh(mpi_reply->Header.PageLength) * 4;
 1130         cm->cm_sge = &request->PageBufferSGE;
 1131         cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
 1132         cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
 1133         cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
 1134         page = malloc(cm->cm_length, M_MPR, M_ZERO | M_NOWAIT);
 1135         if (!page) {
 1136                 printf("%s: page alloc failed\n", __func__);
 1137                 error = ENOMEM;
 1138                 goto out;
 1139         }
 1140         cm->cm_data = page;
 1141 
 1142         error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
 1143         if (cm != NULL)
 1144                 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
 1145         if (error || (reply == NULL)) {
 1146                 /* FIXME */
 1147                 /*
 1148                  * If the request returns an error then we need to do a diag
 1149                  * reset
 1150                  */ 
 1151                 printf("%s: request for page completed with error %d",
 1152                     __func__, error);
 1153                 error = ENXIO;
 1154                 goto out;
 1155         }
 1156         ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
 1157         bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
 1158         if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
 1159                 /* FIXME */
 1160                 /*
 1161                  * If the request returns an error then we need to do a diag
 1162                  * reset
 1163                  */ 
 1164                 printf("%s: page read with error; iocstatus = 0x%x\n",
 1165                     __func__, ioc_status);
 1166                 error = ENXIO;
 1167                 goto out;
 1168         }
 1169         bcopy(page, config_page, MIN(cm->cm_length, sizeof(Mpi2BiosPage3_t)));
 1170 out:
 1171         free(page, M_MPR);
 1172         if (cm)
 1173                 mpr_free_command(sc, cm);
 1174         return (error);
 1175 }
 1176 
 1177 /**
 1178  * mpr_config_get_raid_volume_pg0 - obtain raid volume page 0
 1179  * @sc: per adapter object
 1180  * @mpi_reply: reply mf payload returned from firmware
 1181  * @config_page: contents of the config page
 1182  * @page_address: form and handle value used to get page
 1183  * Context: sleep.
 1184  *
 1185  * Returns 0 for success, non-zero for failure.
 1186  */
 1187 int
 1188 mpr_config_get_raid_volume_pg0(struct mpr_softc *sc, Mpi2ConfigReply_t
 1189     *mpi_reply, Mpi2RaidVolPage0_t *config_page, u32 page_address)
 1190 {
 1191         MPI2_CONFIG_REQUEST *request;
 1192         MPI2_CONFIG_REPLY *reply = NULL;
 1193         struct mpr_command *cm;
 1194         Mpi2RaidVolPage0_t *page = NULL;
 1195         int error = 0;
 1196         u16 ioc_status;
 1197 
 1198         mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
 1199 
 1200         if ((cm = mpr_alloc_command(sc)) == NULL) {
 1201                 printf("%s: command alloc failed @ line %d\n", __func__,
 1202                     __LINE__);
 1203                 error = EBUSY;
 1204                 goto out;
 1205         }
 1206         request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
 1207         bzero(request, sizeof(MPI2_CONFIG_REQUEST));
 1208         request->Function = MPI2_FUNCTION_CONFIG;
 1209         request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
 1210         request->Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;
 1211         request->Header.PageNumber = 0;
 1212         request->Header.PageLength = request->Header.PageVersion = 0;
 1213         cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
 1214         cm->cm_data = NULL;
 1215 
 1216         /*
 1217          * This page must be polled because the IOC isn't ready yet when this
 1218          * page is needed.
 1219          */
 1220         error = mpr_request_polled(sc, &cm);
 1221         if (cm != NULL)
 1222                 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
 1223         if (error || (reply == NULL)) {
 1224                 /* FIXME */
 1225                 /* If the poll returns error then we need to do diag reset */ 
 1226                 printf("%s: poll for header completed with error %d",
 1227                     __func__, error);
 1228                 error = ENXIO;
 1229                 goto out;
 1230         }
 1231         ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
 1232         bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
 1233         if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
 1234                 /* FIXME */
 1235                 /* If the poll returns error then we need to do diag reset */ 
 1236                 printf("%s: header read with error; iocstatus = 0x%x\n",
 1237                     __func__, ioc_status);
 1238                 error = ENXIO;
 1239                 goto out;
 1240         }
 1241         /* We have to do free and alloc for the reply-free and reply-post
 1242          * counters to match - Need to review the reply FIFO handling.
 1243          */
 1244         mpr_free_command(sc, cm);
 1245 
 1246         if ((cm = mpr_alloc_command(sc)) == NULL) {
 1247                 printf("%s: command alloc failed @ line %d\n", __func__,
 1248                     __LINE__);
 1249                 error = EBUSY;
 1250                 goto out;
 1251         }
 1252         request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
 1253         bzero(request, sizeof(MPI2_CONFIG_REQUEST));
 1254         request->Function = MPI2_FUNCTION_CONFIG;
 1255         request->Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
 1256         request->Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;
 1257         request->Header.PageNumber = 0;
 1258         request->Header.PageLength = mpi_reply->Header.PageLength;
 1259         request->Header.PageVersion = mpi_reply->Header.PageVersion;
 1260         request->PageAddress = page_address;
 1261         cm->cm_length = le16toh(mpi_reply->Header.PageLength) * 4;
 1262         cm->cm_sge = &request->PageBufferSGE;
 1263         cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
 1264         cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
 1265         cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
 1266         page = malloc(cm->cm_length, M_MPR, M_ZERO | M_NOWAIT);
 1267         if (!page) {
 1268                 printf("%s: page alloc failed\n", __func__);
 1269                 error = ENOMEM;
 1270                 goto out;
 1271         }
 1272         cm->cm_data = page;
 1273 
 1274         /*
 1275          * This page must be polled because the IOC isn't ready yet when this
 1276          * page is needed.
 1277          */
 1278         error = mpr_request_polled(sc, &cm);
 1279         if (cm != NULL)
 1280                 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
 1281         if (error || (reply == NULL)) {
 1282                 /* FIXME */
 1283                 /* If the poll returns error then we need to do diag reset */ 
 1284                 printf("%s: poll for page completed with error %d",
 1285                     __func__, error);
 1286                 error = ENXIO;
 1287                 goto out;
 1288         }
 1289         ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
 1290         bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
 1291         if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
 1292                 /* FIXME */
 1293                 /* If the poll returns error then we need to do diag reset */ 
 1294                 printf("%s: page read with error; iocstatus = 0x%x\n",
 1295                     __func__, ioc_status);
 1296                 error = ENXIO;
 1297                 goto out;
 1298         }
 1299         bcopy(page, config_page, cm->cm_length);
 1300 out:
 1301         free(page, M_MPR);
 1302         if (cm)
 1303                 mpr_free_command(sc, cm);
 1304         return (error);
 1305 }
 1306 
 1307 /**
 1308  * mpr_config_get_raid_volume_pg1 - obtain raid volume page 1
 1309  * @sc: per adapter object
 1310  * @mpi_reply: reply mf payload returned from firmware
 1311  * @config_page: contents of the config page
 1312  * @form: GET_NEXT_HANDLE or HANDLE
 1313  * @handle: volume handle
 1314  * Context: sleep.
 1315  *
 1316  * Returns 0 for success, non-zero for failure.
 1317  */
 1318 int
 1319 mpr_config_get_raid_volume_pg1(struct mpr_softc *sc, Mpi2ConfigReply_t
 1320     *mpi_reply, Mpi2RaidVolPage1_t *config_page, u32 form, u16 handle)
 1321 {
 1322         MPI2_CONFIG_REQUEST *request;
 1323         MPI2_CONFIG_REPLY *reply;
 1324         struct mpr_command *cm;
 1325         Mpi2RaidVolPage1_t *page = NULL;
 1326         int error = 0;
 1327         u16 ioc_status;
 1328 
 1329         mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
 1330 
 1331         if ((cm = mpr_alloc_command(sc)) == NULL) {
 1332                 printf("%s: command alloc failed @ line %d\n", __func__,
 1333                     __LINE__);
 1334                 error = EBUSY;
 1335                 goto out;
 1336         }
 1337         request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
 1338         bzero(request, sizeof(MPI2_CONFIG_REQUEST));
 1339         request->Function = MPI2_FUNCTION_CONFIG;
 1340         request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
 1341         request->Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;
 1342         request->Header.PageNumber = 1;
 1343         request->Header.PageLength = request->Header.PageVersion = 0;
 1344         cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
 1345         cm->cm_data = NULL;
 1346         error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
 1347         if (cm != NULL)
 1348                 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
 1349         if (error || (reply == NULL)) {
 1350                 /* FIXME */
 1351                 /*
 1352                  * If the request returns an error then we need to do a diag
 1353                  * reset
 1354                  */ 
 1355                 printf("%s: request for header completed with error %d",
 1356                     __func__, error);
 1357                 error = ENXIO;
 1358                 goto out;
 1359         }
 1360         ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
 1361         bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
 1362         if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
 1363                 /* FIXME */
 1364                 /*
 1365                  * If the request returns an error then we need to do a diag
 1366                  * reset
 1367                  */ 
 1368                 printf("%s: header read with error; iocstatus = 0x%x\n",
 1369                     __func__, ioc_status);
 1370                 error = ENXIO;
 1371                 goto out;
 1372         }
 1373         /* We have to do free and alloc for the reply-free and reply-post
 1374          * counters to match - Need to review the reply FIFO handling.
 1375          */
 1376         mpr_free_command(sc, cm);
 1377 
 1378         if ((cm = mpr_alloc_command(sc)) == NULL) {
 1379                 printf("%s: command alloc failed @ line %d\n", __func__,
 1380                     __LINE__);
 1381                 error = EBUSY;
 1382                 goto out;
 1383         }
 1384         request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
 1385         bzero(request, sizeof(MPI2_CONFIG_REQUEST));
 1386         request->Function = MPI2_FUNCTION_CONFIG;
 1387         request->Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
 1388         request->Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;
 1389         request->Header.PageNumber = 1;
 1390         request->Header.PageLength = mpi_reply->Header.PageLength;
 1391         request->Header.PageVersion = mpi_reply->Header.PageVersion;
 1392         request->PageAddress = htole32(form | handle);
 1393         cm->cm_length = le16toh(mpi_reply->Header.PageLength) * 4;
 1394         cm->cm_sge = &request->PageBufferSGE;
 1395         cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
 1396         cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
 1397         cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
 1398         page = malloc(cm->cm_length, M_MPR, M_ZERO | M_NOWAIT);
 1399         if (!page) {
 1400                 printf("%s: page alloc failed\n", __func__);
 1401                 error = ENOMEM;
 1402                 goto out;
 1403         }
 1404         cm->cm_data = page;
 1405 
 1406         error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
 1407         if (cm != NULL)
 1408                 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
 1409         if (error || (reply == NULL)) {
 1410                 /* FIXME */
 1411                 /*
 1412                  * If the request returns an error then we need to do a diag
 1413                  * reset
 1414                  */ 
 1415                 printf("%s: request for page completed with error %d",
 1416                     __func__, error);
 1417                 error = ENXIO;
 1418                 goto out;
 1419         }
 1420         ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
 1421         bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
 1422         if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
 1423                 /* FIXME */
 1424                 /*
 1425                  * If the request returns an error then we need to do a diag
 1426                  * reset
 1427                  */ 
 1428                 printf("%s: page read with error; iocstatus = 0x%x\n",
 1429                     __func__, ioc_status);
 1430                 error = ENXIO;
 1431                 goto out;
 1432         }
 1433         bcopy(page, config_page, MIN(cm->cm_length,
 1434             sizeof(Mpi2RaidVolPage1_t)));
 1435 out:
 1436         free(page, M_MPR);
 1437         if (cm)
 1438                 mpr_free_command(sc, cm);
 1439         return (error);
 1440 }
 1441 
 1442 /**
 1443  * mpr_config_get_volume_wwid - returns wwid given the volume handle
 1444  * @sc: per adapter object
 1445  * @volume_handle: volume handle
 1446  * @wwid: volume wwid
 1447  * Context: sleep.
 1448  *
 1449  * Returns 0 for success, non-zero for failure.
 1450  */
 1451 int
 1452 mpr_config_get_volume_wwid(struct mpr_softc *sc, u16 volume_handle, u64 *wwid)
 1453 {
 1454         Mpi2ConfigReply_t mpi_reply;
 1455         Mpi2RaidVolPage1_t raid_vol_pg1;
 1456 
 1457         *wwid = 0;
 1458         if (!(mpr_config_get_raid_volume_pg1(sc, &mpi_reply, &raid_vol_pg1,
 1459             MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, volume_handle))) {
 1460                 *wwid = le64toh((u64)raid_vol_pg1.WWID.High << 32 |
 1461                     raid_vol_pg1.WWID.Low);
 1462                 return 0;
 1463         } else
 1464                 return -1;
 1465 }
 1466 
 1467 /**
 1468  * mpr_config_get_pd_pg0 - obtain raid phys disk page 0
 1469  * @sc: per adapter object
 1470  * @mpi_reply: reply mf payload returned from firmware
 1471  * @config_page: contents of the config page
 1472  * @page_address: form and handle value used to get page
 1473  * Context: sleep.
 1474  *
 1475  * Returns 0 for success, non-zero for failure.
 1476  */
 1477 int
 1478 mpr_config_get_raid_pd_pg0(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply,
 1479     Mpi2RaidPhysDiskPage0_t *config_page, u32 page_address)
 1480 {
 1481         MPI2_CONFIG_REQUEST *request;
 1482         MPI2_CONFIG_REPLY *reply = NULL;
 1483         struct mpr_command *cm;
 1484         Mpi2RaidPhysDiskPage0_t *page = NULL;
 1485         int error = 0;
 1486         u16 ioc_status;
 1487 
 1488         mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
 1489 
 1490         if ((cm = mpr_alloc_command(sc)) == NULL) {
 1491                 printf("%s: command alloc failed @ line %d\n", __func__,
 1492                     __LINE__);
 1493                 error = EBUSY;
 1494                 goto out;
 1495         }
 1496         request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
 1497         bzero(request, sizeof(MPI2_CONFIG_REQUEST));
 1498         request->Function = MPI2_FUNCTION_CONFIG;
 1499         request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
 1500         request->Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_PHYSDISK;
 1501         request->Header.PageNumber = 0;
 1502         request->Header.PageLength = request->Header.PageVersion = 0;
 1503         cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
 1504         cm->cm_data = NULL;
 1505 
 1506         /*
 1507          * This page must be polled because the IOC isn't ready yet when this
 1508          * page is needed.
 1509          */
 1510         error = mpr_request_polled(sc, &cm);
 1511         if (cm != NULL)
 1512                 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
 1513         if (error || (reply == NULL)) {
 1514                 /* FIXME */
 1515                 /* If the poll returns error then we need to do diag reset */ 
 1516                 printf("%s: poll for header completed with error %d",
 1517                     __func__, error);
 1518                 error = ENXIO;
 1519                 goto out;
 1520         }
 1521         ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
 1522         bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
 1523         if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
 1524                 /* FIXME */
 1525                 /* If the poll returns error then we need to do diag reset */ 
 1526                 printf("%s: header read with error; iocstatus = 0x%x\n",
 1527                     __func__, ioc_status);
 1528                 error = ENXIO;
 1529                 goto out;
 1530         }
 1531         /* We have to do free and alloc for the reply-free and reply-post
 1532          * counters to match - Need to review the reply FIFO handling.
 1533          */
 1534         mpr_free_command(sc, cm);
 1535 
 1536         if ((cm = mpr_alloc_command(sc)) == NULL) {
 1537                 printf("%s: command alloc failed @ line %d\n", __func__,
 1538                     __LINE__);
 1539                 error = EBUSY;
 1540                 goto out;
 1541         }
 1542         request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
 1543         bzero(request, sizeof(MPI2_CONFIG_REQUEST));
 1544         request->Function = MPI2_FUNCTION_CONFIG;
 1545         request->Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
 1546         request->Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_PHYSDISK;
 1547         request->Header.PageNumber = 0;
 1548         request->Header.PageLength = mpi_reply->Header.PageLength;
 1549         request->Header.PageVersion = mpi_reply->Header.PageVersion;
 1550         request->PageAddress = page_address;
 1551         cm->cm_length = le16toh(mpi_reply->Header.PageLength) * 4;
 1552         cm->cm_sge = &request->PageBufferSGE;
 1553         cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
 1554         cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
 1555         cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
 1556         page = malloc(cm->cm_length, M_MPR, M_ZERO | M_NOWAIT);
 1557         if (!page) {
 1558                 printf("%s: page alloc failed\n", __func__);
 1559                 error = ENOMEM;
 1560                 goto out;
 1561         }
 1562         cm->cm_data = page;
 1563 
 1564         /*
 1565          * This page must be polled because the IOC isn't ready yet when this
 1566          * page is needed.
 1567          */
 1568         error = mpr_request_polled(sc, &cm);
 1569         if (cm != NULL)
 1570                 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
 1571         if (error || (reply == NULL)) {
 1572                 /* FIXME */
 1573                 /* If the poll returns error then we need to do diag reset */ 
 1574                 printf("%s: poll for page completed with error %d",
 1575                     __func__, error);
 1576                 error = ENXIO;
 1577                 goto out;
 1578         }
 1579         ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
 1580         bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
 1581         if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
 1582                 /* FIXME */
 1583                 /* If the poll returns error then we need to do diag reset */ 
 1584                 printf("%s: page read with error; iocstatus = 0x%x\n",
 1585                     __func__, ioc_status);
 1586                 error = ENXIO;
 1587                 goto out;
 1588         }
 1589         bcopy(page, config_page, MIN(cm->cm_length,
 1590             sizeof(Mpi2RaidPhysDiskPage0_t)));
 1591 out:
 1592         free(page, M_MPR);
 1593         if (cm)
 1594                 mpr_free_command(sc, cm);
 1595         return (error);
 1596 }

Cache object: 24289916bf941b5141886b85cbe60cd6


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.