Annotation of qemu/roms/ipxe/src/drivers/nvs/nvsvpd.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (C) 2010 Michael Brown <[email protected]>.
        !             3:  *
        !             4:  * This program is free software; you can redistribute it and/or
        !             5:  * modify it under the terms of the GNU General Public License as
        !             6:  * published by the Free Software Foundation; either version 2 of the
        !             7:  * License, or any later version.
        !             8:  *
        !             9:  * This program is distributed in the hope that it will be useful, but
        !            10:  * WITHOUT ANY WARRANTY; without even the implied warranty of
        !            11:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
        !            12:  * General Public License for more details.
        !            13:  *
        !            14:  * You should have received a copy of the GNU General Public License
        !            15:  * along with this program; if not, write to the Free Software
        !            16:  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
        !            17:  */
        !            18: 
        !            19: FILE_LICENCE ( GPL2_OR_LATER );
        !            20: 
        !            21: #include <stdio.h>
        !            22: #include <errno.h>
        !            23: #include <ipxe/nvs.h>
        !            24: #include <ipxe/pci.h>
        !            25: #include <ipxe/pcivpd.h>
        !            26: #include <ipxe/nvo.h>
        !            27: #include <ipxe/nvsvpd.h>
        !            28: 
        !            29: /** @file
        !            30:  *
        !            31:  * Non-Volatile Storage using Vital Product Data
        !            32:  *
        !            33:  */
        !            34: 
        !            35: /**
        !            36:  * Read from VPD field
        !            37:  *
        !            38:  * @v nvs              NVS device
        !            39:  * @v field            VPD field descriptor
        !            40:  * @v data             Data buffer
        !            41:  * @v len              Length of data buffer
        !            42:  * @ret rc             Return status code
        !            43:  */
        !            44: static int nvs_vpd_read ( struct nvs_device *nvs, unsigned int field,
        !            45:                          void *data, size_t len ) {
        !            46:        struct nvs_vpd_device *nvsvpd =
        !            47:                container_of ( nvs, struct nvs_vpd_device, nvs );
        !            48:        struct pci_device *pci = nvsvpd->vpd.pci;
        !            49:        unsigned int address;
        !            50:        size_t max_len;
        !            51:        int rc;
        !            52: 
        !            53:        /* Allow reading non-existent field */
        !            54:        if ( len == 0 )
        !            55:                return 0;
        !            56: 
        !            57:        /* Locate VPD field */
        !            58:        if ( ( rc = pci_vpd_find ( &nvsvpd->vpd, field, &address,
        !            59:                                   &max_len ) ) != 0 ) {
        !            60:                DBGC ( pci, PCI_FMT " NVS VPD could not locate field "
        !            61:                       PCI_VPD_FIELD_FMT ": %s\n", PCI_ARGS ( pci ),
        !            62:                       PCI_VPD_FIELD_ARGS ( field ), strerror ( rc ) );
        !            63:                return rc;
        !            64:        }
        !            65: 
        !            66:        /* Sanity check */
        !            67:        if ( len > max_len ) {
        !            68:                DBGC ( pci, PCI_FMT " NVS VPD cannot read %#02zx bytes "
        !            69:                       "beyond field " PCI_VPD_FIELD_FMT " at [%04x,%04zx)\n",
        !            70:                       PCI_ARGS ( pci ), len, PCI_VPD_FIELD_ARGS ( field ),
        !            71:                       address, ( address + max_len ) );
        !            72:                return -ENXIO;
        !            73:        }
        !            74: 
        !            75:        /* Read from VPD field */
        !            76:        if ( ( rc = pci_vpd_read ( &nvsvpd->vpd, address, data, len ) ) != 0 ) {
        !            77:                DBGC ( pci, PCI_FMT " NVS VPD could not read field "
        !            78:                       PCI_VPD_FIELD_FMT " at [%04x,%04zx): %s\n",
        !            79:                       PCI_ARGS ( pci ), PCI_VPD_FIELD_ARGS ( field ),
        !            80:                       address, ( address + len ), strerror ( rc ) );
        !            81:                return rc;
        !            82:        }
        !            83: 
        !            84:        return 0;
        !            85: }
        !            86: 
        !            87: /**
        !            88:  * Write to VPD field
        !            89:  *
        !            90:  * @v nvs              NVS device
        !            91:  * @v field            VPD field descriptor
        !            92:  * @v data             Data buffer
        !            93:  * @v len              Length of data buffer
        !            94:  * @ret rc             Return status code
        !            95:  */
        !            96: static int nvs_vpd_write ( struct nvs_device *nvs, unsigned int field,
        !            97:                           const void *data, size_t len ) {
        !            98:        struct nvs_vpd_device *nvsvpd =
        !            99:                container_of ( nvs, struct nvs_vpd_device, nvs );
        !           100:        struct pci_device *pci = nvsvpd->vpd.pci;
        !           101:        unsigned int address;
        !           102:        size_t max_len;
        !           103:        int rc;
        !           104: 
        !           105:        /* Locate VPD field */
        !           106:        if ( ( rc = pci_vpd_find ( &nvsvpd->vpd, field, &address,
        !           107:                                   &max_len ) ) != 0 ) {
        !           108:                DBGC ( pci, PCI_FMT " NVS VPD could not locate field "
        !           109:                       PCI_VPD_FIELD_FMT ": %s\n", PCI_ARGS ( pci ),
        !           110:                       PCI_VPD_FIELD_ARGS ( field ), strerror ( rc ) );
        !           111:                return rc;
        !           112:        }
        !           113: 
        !           114:        /* Sanity check */
        !           115:        if ( len > max_len ) {
        !           116:                DBGC ( pci, PCI_FMT " NVS VPD cannot write %#02zx bytes "
        !           117:                       "beyond field " PCI_VPD_FIELD_FMT " at [%04x,%04zx)\n",
        !           118:                       PCI_ARGS ( pci ), len, PCI_VPD_FIELD_ARGS ( field ),
        !           119:                       address, ( address + max_len ) );
        !           120:                return -ENXIO;
        !           121:        }
        !           122: 
        !           123:        /* Write field */
        !           124:        if ( ( rc = pci_vpd_write ( &nvsvpd->vpd, address, data,
        !           125:                                    len ) ) != 0 ) {
        !           126:                DBGC ( pci, PCI_FMT " NVS VPD could not write field "
        !           127:                       PCI_VPD_FIELD_FMT " at [%04x,%04zx): %s\n",
        !           128:                       PCI_ARGS ( pci ), PCI_VPD_FIELD_ARGS ( field ),
        !           129:                       address, ( address + len ), strerror ( rc ) );
        !           130:                return rc;
        !           131:        }
        !           132: 
        !           133:        return 0;
        !           134: }
        !           135: 
        !           136: /**
        !           137:  * Resize VPD field
        !           138:  *
        !           139:  * @v nvs              NVS device
        !           140:  * @v field            VPD field descriptor
        !           141:  * @v data             Data buffer
        !           142:  * @v len              Length of data buffer
        !           143:  * @ret rc             Return status code
        !           144:  */
        !           145: static int nvs_vpd_resize ( struct nvs_device *nvs, unsigned int field,
        !           146:                            size_t len ) {
        !           147:        struct nvs_vpd_device *nvsvpd =
        !           148:                container_of ( nvs, struct nvs_vpd_device, nvs );
        !           149:        struct pci_device *pci = nvsvpd->vpd.pci;
        !           150:        unsigned int address;
        !           151:        int rc;
        !           152: 
        !           153:        /* Resize field */
        !           154:        if ( ( rc = pci_vpd_resize ( &nvsvpd->vpd, field, len,
        !           155:                                     &address ) ) != 0 ) {
        !           156:                DBGC ( pci, PCI_FMT " NVS VPD could not resize field "
        !           157:                       PCI_VPD_FIELD_FMT " to %#02zx bytes: %s\n",
        !           158:                       PCI_ARGS ( pci ), PCI_VPD_FIELD_ARGS ( field ),
        !           159:                       len, strerror ( rc ) );
        !           160:                return rc;
        !           161:        }
        !           162: 
        !           163:        return 0;
        !           164: }
        !           165: 
        !           166: /**
        !           167:  * Initialise NVS VPD device
        !           168:  *
        !           169:  * @v nvsvpd           NVS VPD device
        !           170:  * @v pci              PCI device
        !           171:  * @ret rc             Return status code
        !           172:  */
        !           173: int nvs_vpd_init ( struct nvs_vpd_device *nvsvpd, struct pci_device *pci ) {
        !           174:        int rc;
        !           175: 
        !           176:        /* Initialise VPD device */
        !           177:        if ( ( rc = pci_vpd_init ( &nvsvpd->vpd, pci ) ) != 0 ) {
        !           178:                DBGC ( pci, PCI_FMT " NVS could not initialise "
        !           179:                       "VPD: %s\n", PCI_ARGS ( pci ), strerror ( rc ) );
        !           180:                return rc;
        !           181:        }
        !           182: 
        !           183:        /* Initialise NVS device */
        !           184:        nvsvpd->nvs.read = nvs_vpd_read;
        !           185:        nvsvpd->nvs.write = nvs_vpd_write;
        !           186: 
        !           187:        return 0;
        !           188: }
        !           189: 
        !           190: /**
        !           191:  * Resize non-volatile option storage within NVS VPD device
        !           192:  *
        !           193:  * @v nvo              Non-volatile options block
        !           194:  * @v len              New length
        !           195:  * @ret rc             Return status code
        !           196:  */
        !           197: static int nvs_vpd_nvo_resize ( struct nvo_block *nvo, size_t len ) {
        !           198:        int rc;
        !           199: 
        !           200:        /* Resize VPD field */
        !           201:        if ( ( rc = nvs_vpd_resize ( nvo->nvs, nvo->address, len ) ) != 0 )
        !           202:                return rc;
        !           203: 
        !           204:        return 0;
        !           205: }
        !           206: 
        !           207: /**
        !           208:  * Initialise non-volatile option storage within NVS VPD device
        !           209:  *
        !           210:  * @v nvsvpd           NVS VPD device
        !           211:  * @v field            VPD field descriptor
        !           212:  * @v nvo              Non-volatile options block
        !           213:  * @v refcnt           Containing object reference counter, or NULL
        !           214:  */
        !           215: void nvs_vpd_nvo_init ( struct nvs_vpd_device *nvsvpd, unsigned int field,
        !           216:                        struct nvo_block *nvo, struct refcnt *refcnt ) {
        !           217:        struct pci_device *pci = nvsvpd->vpd.pci;
        !           218:        unsigned int address;
        !           219:        size_t len;
        !           220:        int rc;
        !           221: 
        !           222:        /* Locate VPD field, if present */
        !           223:        if ( ( rc = pci_vpd_find ( &nvsvpd->vpd, field, &address,
        !           224:                                   &len ) ) != 0 ) {
        !           225:                DBGC ( pci, PCI_FMT " NVS VPD field " PCI_VPD_FIELD_FMT
        !           226:                       " not present; assuming empty\n",
        !           227:                       PCI_ARGS ( pci ), PCI_VPD_FIELD_ARGS ( field ) );
        !           228:                len = 0;
        !           229:        }
        !           230: 
        !           231:        /* Initialise non-volatile options block */
        !           232:        nvo_init ( nvo, &nvsvpd->nvs, field, len, nvs_vpd_nvo_resize, refcnt );
        !           233: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.