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