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/sfxge/common/siena_vpd.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  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
    3  *
    4  * Copyright (c) 2009-2016 Solarflare Communications Inc.
    5  * All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions are met:
    9  *
   10  * 1. Redistributions of source code must retain the above copyright notice,
   11  *    this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright notice,
   13  *    this list of conditions and the following disclaimer in the documentation
   14  *    and/or other materials provided with the distribution.
   15  *
   16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
   17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
   18  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   19  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
   20  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   21  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   22  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
   23  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
   24  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
   25  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
   26  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   27  *
   28  * The views and conclusions contained in the software and documentation are
   29  * those of the authors and should not be interpreted as representing official
   30  * policies, either expressed or implied, of the FreeBSD Project.
   31  */
   32 
   33 #include <sys/cdefs.h>
   34 __FBSDID("$FreeBSD$");
   35 
   36 #include "efx.h"
   37 #include "efx_impl.h"
   38 
   39 #if EFSYS_OPT_VPD
   40 
   41 #if EFSYS_OPT_SIENA
   42 
   43 static  __checkReturn                   efx_rc_t
   44 siena_vpd_get_static(
   45         __in                            efx_nic_t *enp,
   46         __in                            uint32_t partn,
   47         __deref_out_bcount_opt(*sizep)  caddr_t *svpdp,
   48         __out                           size_t *sizep)
   49 {
   50         siena_mc_static_config_hdr_t *scfg;
   51         caddr_t svpd;
   52         size_t size;
   53         uint8_t cksum;
   54         unsigned int vpd_offset;
   55         unsigned int vpd_length;
   56         unsigned int hdr_length;
   57         unsigned int pos;
   58         unsigned int region;
   59         efx_rc_t rc;
   60 
   61         EFSYS_ASSERT(partn == MC_CMD_NVRAM_TYPE_STATIC_CFG_PORT0 ||
   62                     partn == MC_CMD_NVRAM_TYPE_STATIC_CFG_PORT1);
   63 
   64         /* Allocate sufficient memory for the entire static cfg area */
   65         if ((rc = siena_nvram_partn_size(enp, partn, &size)) != 0)
   66                 goto fail1;
   67 
   68         if (size < SIENA_NVRAM_CHUNK) {
   69                 rc = EINVAL;
   70                 goto fail2;
   71         }
   72 
   73         EFSYS_KMEM_ALLOC(enp->en_esip, size, scfg);
   74         if (scfg == NULL) {
   75                 rc = ENOMEM;
   76                 goto fail3;
   77         }
   78 
   79         if ((rc = siena_nvram_partn_read(enp, partn, 0,
   80             (caddr_t)scfg, SIENA_NVRAM_CHUNK)) != 0)
   81                 goto fail4;
   82 
   83         /* Verify the magic number */
   84         if (EFX_DWORD_FIELD(scfg->magic, EFX_DWORD_0) !=
   85             SIENA_MC_STATIC_CONFIG_MAGIC) {
   86                 rc = EINVAL;
   87                 goto fail5;
   88         }
   89 
   90         /* All future versions of the structure must be backwards compatible */
   91         EFX_STATIC_ASSERT(SIENA_MC_STATIC_CONFIG_VERSION == 0);
   92 
   93         hdr_length = EFX_WORD_FIELD(scfg->length, EFX_WORD_0);
   94         vpd_offset = EFX_DWORD_FIELD(scfg->static_vpd_offset, EFX_DWORD_0);
   95         vpd_length = EFX_DWORD_FIELD(scfg->static_vpd_length, EFX_DWORD_0);
   96 
   97         /* Verify the hdr doesn't overflow the sector size */
   98         if (hdr_length > size || vpd_offset > size || vpd_length > size ||
   99             vpd_length + vpd_offset > size) {
  100                 rc = EINVAL;
  101                 goto fail6;
  102         }
  103 
  104         /* Read the remainder of scfg + static vpd */
  105         region = vpd_offset + vpd_length;
  106         if (region > SIENA_NVRAM_CHUNK) {
  107                 if ((rc = siena_nvram_partn_read(enp, partn, SIENA_NVRAM_CHUNK,
  108                     (caddr_t)scfg + SIENA_NVRAM_CHUNK,
  109                     region - SIENA_NVRAM_CHUNK)) != 0)
  110                         goto fail7;
  111         }
  112 
  113         /* Verify checksum */
  114         cksum = 0;
  115         for (pos = 0; pos < hdr_length; pos++)
  116                 cksum += ((uint8_t *)scfg)[pos];
  117         if (cksum != 0) {
  118                 rc = EINVAL;
  119                 goto fail8;
  120         }
  121 
  122         if (vpd_length == 0)
  123                 svpd = NULL;
  124         else {
  125                 /* Copy the vpd data out */
  126                 EFSYS_KMEM_ALLOC(enp->en_esip, vpd_length, svpd);
  127                 if (svpd == NULL) {
  128                         rc = ENOMEM;
  129                         goto fail9;
  130                 }
  131                 memcpy(svpd, (caddr_t)scfg + vpd_offset, vpd_length);
  132         }
  133 
  134         EFSYS_KMEM_FREE(enp->en_esip, size, scfg);
  135 
  136         *svpdp = svpd;
  137         *sizep = vpd_length;
  138 
  139         return (0);
  140 
  141 fail9:
  142         EFSYS_PROBE(fail9);
  143 fail8:
  144         EFSYS_PROBE(fail8);
  145 fail7:
  146         EFSYS_PROBE(fail7);
  147 fail6:
  148         EFSYS_PROBE(fail6);
  149 fail5:
  150         EFSYS_PROBE(fail5);
  151 fail4:
  152         EFSYS_PROBE(fail4);
  153 
  154         EFSYS_KMEM_FREE(enp->en_esip, size, scfg);
  155 
  156 fail3:
  157         EFSYS_PROBE(fail3);
  158 fail2:
  159         EFSYS_PROBE(fail2);
  160 fail1:
  161         EFSYS_PROBE1(fail1, efx_rc_t, rc);
  162 
  163         return (rc);
  164 }
  165 
  166         __checkReturn           efx_rc_t
  167 siena_vpd_init(
  168         __in                    efx_nic_t *enp)
  169 {
  170         efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
  171         caddr_t svpd = NULL;
  172         unsigned int partn;
  173         size_t size = 0;
  174         efx_rc_t rc;
  175 
  176         EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA);
  177 
  178         partn = (emip->emi_port == 1)
  179                 ? MC_CMD_NVRAM_TYPE_STATIC_CFG_PORT0
  180                 : MC_CMD_NVRAM_TYPE_STATIC_CFG_PORT1;
  181 
  182         /*
  183          * We need the static VPD sector to present a unified static+dynamic
  184          * VPD, that is, basically on every read, write, verify cycle. Since
  185          * it should *never* change we can just cache it here.
  186          */
  187         if ((rc = siena_vpd_get_static(enp, partn, &svpd, &size)) != 0)
  188                 goto fail1;
  189 
  190         if (svpd != NULL && size > 0) {
  191                 if ((rc = efx_vpd_hunk_verify(svpd, size, NULL)) != 0)
  192                         goto fail2;
  193         }
  194 
  195         enp->en_u.siena.enu_svpd = svpd;
  196         enp->en_u.siena.enu_svpd_length = size;
  197 
  198         return (0);
  199 
  200 fail2:
  201         EFSYS_PROBE(fail2);
  202 
  203         EFSYS_KMEM_FREE(enp->en_esip, size, svpd);
  204 fail1:
  205         EFSYS_PROBE1(fail1, efx_rc_t, rc);
  206 
  207         return (rc);
  208 }
  209 
  210         __checkReturn           efx_rc_t
  211 siena_vpd_size(
  212         __in                    efx_nic_t *enp,
  213         __out                   size_t *sizep)
  214 {
  215         efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
  216         uint32_t partn;
  217         efx_rc_t rc;
  218 
  219         EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA);
  220 
  221         /*
  222          * This function returns the total size the user should allocate
  223          * for all VPD operations. We've already cached the static vpd,
  224          * so we just need to return an upper bound on the dynamic vpd.
  225          * Since the dynamic_config structure can change under our feet,
  226          * (as version numbers are inserted), just be safe and return the
  227          * total size of the dynamic_config *sector*
  228          */
  229         partn = (emip->emi_port == 1)
  230                 ? MC_CMD_NVRAM_TYPE_DYNAMIC_CFG_PORT0
  231                 : MC_CMD_NVRAM_TYPE_DYNAMIC_CFG_PORT1;
  232 
  233         if ((rc = siena_nvram_partn_size(enp, partn, sizep)) != 0)
  234                 goto fail1;
  235 
  236         return (0);
  237 
  238 fail1:
  239         EFSYS_PROBE1(fail1, efx_rc_t, rc);
  240 
  241         return (rc);
  242 }
  243 
  244         __checkReturn           efx_rc_t
  245 siena_vpd_read(
  246         __in                    efx_nic_t *enp,
  247         __out_bcount(size)      caddr_t data,
  248         __in                    size_t size)
  249 {
  250         efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
  251         siena_mc_dynamic_config_hdr_t *dcfg = NULL;
  252         unsigned int vpd_length;
  253         unsigned int vpd_offset;
  254         unsigned int dcfg_partn;
  255         size_t dcfg_size;
  256         efx_rc_t rc;
  257 
  258         EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA);
  259 
  260         dcfg_partn = (emip->emi_port == 1)
  261                 ? MC_CMD_NVRAM_TYPE_DYNAMIC_CFG_PORT0
  262                 : MC_CMD_NVRAM_TYPE_DYNAMIC_CFG_PORT1;
  263 
  264         if ((rc = siena_nvram_get_dynamic_cfg(enp, dcfg_partn,
  265             B_TRUE, &dcfg, &dcfg_size)) != 0)
  266                 goto fail1;
  267 
  268         vpd_length = EFX_DWORD_FIELD(dcfg->dynamic_vpd_length, EFX_DWORD_0);
  269         vpd_offset = EFX_DWORD_FIELD(dcfg->dynamic_vpd_offset, EFX_DWORD_0);
  270 
  271         if (vpd_length > size) {
  272                 rc = EFAULT;    /* Invalid dcfg: header bigger than sector */
  273                 goto fail2;
  274         }
  275 
  276         EFSYS_ASSERT3U(vpd_length, <=, size);
  277         memcpy(data, (caddr_t)dcfg + vpd_offset, vpd_length);
  278 
  279         /* Pad data with all-1s, consistent with update operations */
  280         memset(data + vpd_length, 0xff, size - vpd_length);
  281 
  282         EFSYS_KMEM_FREE(enp->en_esip, dcfg_size, dcfg);
  283 
  284         return (0);
  285 
  286 fail2:
  287         EFSYS_PROBE(fail2);
  288 
  289         EFSYS_KMEM_FREE(enp->en_esip, dcfg_size, dcfg);
  290 fail1:
  291         EFSYS_PROBE1(fail1, efx_rc_t, rc);
  292 
  293         return (rc);
  294 }
  295 
  296         __checkReturn           efx_rc_t
  297 siena_vpd_verify(
  298         __in                    efx_nic_t *enp,
  299         __in_bcount(size)       caddr_t data,
  300         __in                    size_t size)
  301 {
  302         efx_vpd_tag_t stag;
  303         efx_vpd_tag_t dtag;
  304         efx_vpd_keyword_t skey;
  305         efx_vpd_keyword_t dkey;
  306         unsigned int scont;
  307         unsigned int dcont;
  308 
  309         efx_rc_t rc;
  310 
  311         EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA);
  312 
  313         /*
  314          * Strictly you could take the view that dynamic vpd is optional.
  315          * Instead, to conform more closely to the read/verify/reinit()
  316          * paradigm, we require dynamic vpd. siena_vpd_reinit() will
  317          * reinitialize it as required.
  318          */
  319         if ((rc = efx_vpd_hunk_verify(data, size, NULL)) != 0)
  320                 goto fail1;
  321 
  322         /*
  323          * Verify that there is no duplication between the static and
  324          * dynamic cfg sectors.
  325          */
  326         if (enp->en_u.siena.enu_svpd_length == 0)
  327                 goto done;
  328 
  329         dcont = 0;
  330         _NOTE(CONSTANTCONDITION)
  331         while (1) {
  332                 if ((rc = efx_vpd_hunk_next(data, size, &dtag,
  333                     &dkey, NULL, NULL, &dcont)) != 0)
  334                         goto fail2;
  335                 if (dcont == 0)
  336                         break;
  337 
  338                 /*
  339                  * Skip the RV keyword. It should be present in both the static
  340                  * and dynamic cfg sectors.
  341                  */
  342                 if (dtag == EFX_VPD_RO && dkey == EFX_VPD_KEYWORD('R', 'V'))
  343                         continue;
  344 
  345                 scont = 0;
  346                 _NOTE(CONSTANTCONDITION)
  347                 while (1) {
  348                         if ((rc = efx_vpd_hunk_next(
  349                             enp->en_u.siena.enu_svpd,
  350                             enp->en_u.siena.enu_svpd_length, &stag, &skey,
  351                             NULL, NULL, &scont)) != 0)
  352                                 goto fail3;
  353                         if (scont == 0)
  354                                 break;
  355 
  356                         if (stag == dtag && skey == dkey) {
  357                                 rc = EEXIST;
  358                                 goto fail4;
  359                         }
  360                 }
  361         }
  362 
  363 done:
  364         return (0);
  365 
  366 fail4:
  367         EFSYS_PROBE(fail4);
  368 fail3:
  369         EFSYS_PROBE(fail3);
  370 fail2:
  371         EFSYS_PROBE(fail2);
  372 fail1:
  373         EFSYS_PROBE1(fail1, efx_rc_t, rc);
  374 
  375         return (rc);
  376 }
  377 
  378         __checkReturn           efx_rc_t
  379 siena_vpd_reinit(
  380         __in                    efx_nic_t *enp,
  381         __in_bcount(size)       caddr_t data,
  382         __in                    size_t size)
  383 {
  384         boolean_t wantpid;
  385         efx_rc_t rc;
  386 
  387         /*
  388          * Only create a PID if the dynamic cfg doesn't have one
  389          */
  390         if (enp->en_u.siena.enu_svpd_length == 0)
  391                 wantpid = B_TRUE;
  392         else {
  393                 unsigned int offset;
  394                 uint8_t length;
  395 
  396                 rc = efx_vpd_hunk_get(enp->en_u.siena.enu_svpd,
  397                                     enp->en_u.siena.enu_svpd_length,
  398                                     EFX_VPD_ID, 0, &offset, &length);
  399                 if (rc == 0)
  400                         wantpid = B_FALSE;
  401                 else if (rc == ENOENT)
  402                         wantpid = B_TRUE;
  403                 else
  404                         goto fail1;
  405         }
  406 
  407         if ((rc = efx_vpd_hunk_reinit(data, size, wantpid)) != 0)
  408                 goto fail2;
  409 
  410         return (0);
  411 
  412 fail2:
  413         EFSYS_PROBE(fail2);
  414 fail1:
  415         EFSYS_PROBE1(fail1, efx_rc_t, rc);
  416 
  417         return (rc);
  418 }
  419 
  420         __checkReturn           efx_rc_t
  421 siena_vpd_get(
  422         __in                    efx_nic_t *enp,
  423         __in_bcount(size)       caddr_t data,
  424         __in                    size_t size,
  425         __inout                 efx_vpd_value_t *evvp)
  426 {
  427         unsigned int offset;
  428         uint8_t length;
  429         efx_rc_t rc;
  430 
  431         EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA);
  432 
  433         /* Attempt to satisfy the request from svpd first */
  434         if (enp->en_u.siena.enu_svpd_length > 0) {
  435                 if ((rc = efx_vpd_hunk_get(enp->en_u.siena.enu_svpd,
  436                     enp->en_u.siena.enu_svpd_length, evvp->evv_tag,
  437                     evvp->evv_keyword, &offset, &length)) == 0) {
  438                         evvp->evv_length = length;
  439                         memcpy(evvp->evv_value,
  440                             enp->en_u.siena.enu_svpd + offset, length);
  441                         return (0);
  442                 } else if (rc != ENOENT)
  443                         goto fail1;
  444         }
  445 
  446         /* And then from the provided data buffer */
  447         if ((rc = efx_vpd_hunk_get(data, size, evvp->evv_tag,
  448             evvp->evv_keyword, &offset, &length)) != 0) {
  449                 if (rc == ENOENT)
  450                         return (rc);
  451 
  452                 goto fail2;
  453         }
  454 
  455         evvp->evv_length = length;
  456         memcpy(evvp->evv_value, data + offset, length);
  457 
  458         return (0);
  459 
  460 fail2:
  461         EFSYS_PROBE(fail2);
  462 fail1:
  463         EFSYS_PROBE1(fail1, efx_rc_t, rc);
  464 
  465         return (rc);
  466 }
  467 
  468         __checkReturn           efx_rc_t
  469 siena_vpd_set(
  470         __in                    efx_nic_t *enp,
  471         __in_bcount(size)       caddr_t data,
  472         __in                    size_t size,
  473         __in                    efx_vpd_value_t *evvp)
  474 {
  475         efx_rc_t rc;
  476 
  477         EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA);
  478 
  479         /* If the provided (tag,keyword) exists in svpd, then it is readonly */
  480         if (enp->en_u.siena.enu_svpd_length > 0) {
  481                 unsigned int offset;
  482                 uint8_t length;
  483 
  484                 if ((rc = efx_vpd_hunk_get(enp->en_u.siena.enu_svpd,
  485                     enp->en_u.siena.enu_svpd_length, evvp->evv_tag,
  486                     evvp->evv_keyword, &offset, &length)) == 0) {
  487                         rc = EACCES;
  488                         goto fail1;
  489                 }
  490         }
  491 
  492         if ((rc = efx_vpd_hunk_set(data, size, evvp)) != 0)
  493                 goto fail2;
  494 
  495         return (0);
  496 
  497 fail2:
  498         EFSYS_PROBE(fail2);
  499 fail1:
  500         EFSYS_PROBE1(fail1, efx_rc_t, rc);
  501 
  502         return (rc);
  503 }
  504 
  505         __checkReturn           efx_rc_t
  506 siena_vpd_next(
  507         __in                    efx_nic_t *enp,
  508         __in_bcount(size)       caddr_t data,
  509         __in                    size_t size,
  510         __out                   efx_vpd_value_t *evvp,
  511         __inout                 unsigned int *contp)
  512 {
  513         _NOTE(ARGUNUSED(enp, data, size, evvp, contp))
  514 
  515         return (ENOTSUP);
  516 }
  517 
  518         __checkReturn           efx_rc_t
  519 siena_vpd_write(
  520         __in                    efx_nic_t *enp,
  521         __in_bcount(size)       caddr_t data,
  522         __in                    size_t size)
  523 {
  524         efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
  525         siena_mc_dynamic_config_hdr_t *dcfg = NULL;
  526         unsigned int vpd_offset;
  527         unsigned int dcfg_partn;
  528         unsigned int hdr_length;
  529         unsigned int pos;
  530         uint8_t cksum;
  531         size_t partn_size, dcfg_size;
  532         size_t vpd_length;
  533         efx_rc_t rc;
  534 
  535         EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA);
  536 
  537         /* Determine total length of all tags */
  538         if ((rc = efx_vpd_hunk_length(data, size, &vpd_length)) != 0)
  539                 goto fail1;
  540 
  541         /* Lock dynamic config sector for write, and read structure only */
  542         dcfg_partn = (emip->emi_port == 1)
  543                 ? MC_CMD_NVRAM_TYPE_DYNAMIC_CFG_PORT0
  544                 : MC_CMD_NVRAM_TYPE_DYNAMIC_CFG_PORT1;
  545 
  546         if ((rc = siena_nvram_partn_size(enp, dcfg_partn, &partn_size)) != 0)
  547                 goto fail2;
  548 
  549         if ((rc = siena_nvram_partn_lock(enp, dcfg_partn)) != 0)
  550                 goto fail3;
  551 
  552         if ((rc = siena_nvram_get_dynamic_cfg(enp, dcfg_partn,
  553             B_FALSE, &dcfg, &dcfg_size)) != 0)
  554                 goto fail4;
  555 
  556         hdr_length = EFX_WORD_FIELD(dcfg->length, EFX_WORD_0);
  557 
  558         /* Allocated memory should have room for the new VPD */
  559         if (hdr_length + vpd_length > dcfg_size) {
  560                 rc = ENOSPC;
  561                 goto fail5;
  562         }
  563 
  564         /* Copy in new vpd and update header */
  565         vpd_offset = dcfg_size - vpd_length;
  566         EFX_POPULATE_DWORD_1(dcfg->dynamic_vpd_offset, EFX_DWORD_0, vpd_offset);
  567         memcpy((caddr_t)dcfg + vpd_offset, data, vpd_length);
  568         EFX_POPULATE_DWORD_1(dcfg->dynamic_vpd_length, EFX_DWORD_0, vpd_length);
  569 
  570         /* Update the checksum */
  571         cksum = 0;
  572         for (pos = 0; pos < hdr_length; pos++)
  573                 cksum += ((uint8_t *)dcfg)[pos];
  574         dcfg->csum.eb_u8[0] -= cksum;
  575 
  576         /* Erase and write the new sector */
  577         if ((rc = siena_nvram_partn_erase(enp, dcfg_partn, 0, partn_size)) != 0)
  578                 goto fail6;
  579 
  580         /* Write out the new structure to nvram */
  581         if ((rc = siena_nvram_partn_write(enp, dcfg_partn, 0, (caddr_t)dcfg,
  582             vpd_offset + vpd_length)) != 0)
  583                 goto fail7;
  584 
  585         EFSYS_KMEM_FREE(enp->en_esip, dcfg_size, dcfg);
  586 
  587         siena_nvram_partn_unlock(enp, dcfg_partn, NULL);
  588 
  589         return (0);
  590 
  591 fail7:
  592         EFSYS_PROBE(fail7);
  593 fail6:
  594         EFSYS_PROBE(fail6);
  595 fail5:
  596         EFSYS_PROBE(fail5);
  597 
  598         EFSYS_KMEM_FREE(enp->en_esip, dcfg_size, dcfg);
  599 fail4:
  600         EFSYS_PROBE(fail4);
  601 
  602         siena_nvram_partn_unlock(enp, dcfg_partn, NULL);
  603 fail3:
  604         EFSYS_PROBE(fail3);
  605 fail2:
  606         EFSYS_PROBE(fail2);
  607 fail1:
  608         EFSYS_PROBE1(fail1, efx_rc_t, rc);
  609 
  610         return (rc);
  611 }
  612 
  613                                 void
  614 siena_vpd_fini(
  615         __in                    efx_nic_t *enp)
  616 {
  617         EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA);
  618 
  619         if (enp->en_u.siena.enu_svpd_length > 0) {
  620                 EFSYS_KMEM_FREE(enp->en_esip, enp->en_u.siena.enu_svpd_length,
  621                                 enp->en_u.siena.enu_svpd);
  622 
  623                 enp->en_u.siena.enu_svpd = NULL;
  624                 enp->en_u.siena.enu_svpd_length = 0;
  625         }
  626 }
  627 
  628 #endif  /* EFSYS_OPT_SIENA */
  629 
  630 #endif  /* EFSYS_OPT_VPD */

Cache object: d85d368599629d7b62b3a27a87e8e7bd


[ 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.