smbios_settings.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2008 Michael Brown <mbrown@fensystems.co.uk>.
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License as
00006  * published by the Free Software Foundation; either version 2 of the
00007  * License, or any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful, but
00010  * WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software
00016  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00017  */
00018 
00019 FILE_LICENCE ( GPL2_OR_LATER );
00020 
00021 #include <stdint.h>
00022 #include <string.h>
00023 #include <errno.h>
00024 #include <gpxe/settings.h>
00025 #include <gpxe/init.h>
00026 #include <gpxe/uuid.h>
00027 #include <gpxe/smbios.h>
00028 
00029 /** SMBIOS settings tag magic number */
00030 #define SMBIOS_TAG_MAGIC 0x5B /* "SmBios" */
00031 
00032 /**
00033  * Construct SMBIOS empty tag
00034  *
00035  * @ret tag             SMBIOS setting tag
00036  */
00037 #define SMBIOS_EMPTY_TAG ( SMBIOS_TAG_MAGIC << 24 )
00038 
00039 /**
00040  * Construct SMBIOS raw-data tag
00041  *
00042  * @v _type             SMBIOS structure type number
00043  * @v _structure        SMBIOS structure data type
00044  * @v _field            Field within SMBIOS structure data type
00045  * @ret tag             SMBIOS setting tag
00046  */
00047 #define SMBIOS_RAW_TAG( _type, _structure, _field )             \
00048         ( ( SMBIOS_TAG_MAGIC << 24 ) |                          \
00049           ( (_type) << 16 ) |                                   \
00050           ( offsetof ( _structure, _field ) << 8 ) |            \
00051           ( sizeof ( ( ( _structure * ) 0 )->_field ) ) )
00052 
00053 /**
00054  * Construct SMBIOS string tag
00055  *
00056  * @v _type             SMBIOS structure type number
00057  * @v _structure        SMBIOS structure data type
00058  * @v _field            Field within SMBIOS structure data type
00059  * @ret tag             SMBIOS setting tag
00060  */
00061 #define SMBIOS_STRING_TAG( _type, _structure, _field )          \
00062         ( ( SMBIOS_TAG_MAGIC << 24 ) |                          \
00063           ( (_type) << 16 ) |                                   \
00064           ( offsetof ( _structure, _field ) << 8 ) )
00065 
00066 /**
00067  * Fetch value of SMBIOS setting
00068  *
00069  * @v settings          Settings block, or NULL to search all blocks
00070  * @v setting           Setting to fetch
00071  * @v data              Buffer to fill with setting data
00072  * @v len               Length of buffer
00073  * @ret len             Length of setting data, or negative error
00074  */
00075 static int smbios_fetch ( struct settings *settings __unused,
00076                           struct setting *setting,
00077                           void *data, size_t len ) {
00078         struct smbios_structure structure;
00079         unsigned int tag_magic;
00080         unsigned int tag_type;
00081         unsigned int tag_offset;
00082         unsigned int tag_len;
00083         int rc;
00084 
00085         /* Split tag into type, offset and length */
00086         tag_magic = ( setting->tag >> 24 );
00087         tag_type = ( ( setting->tag >> 16 ) & 0xff );
00088         tag_offset = ( ( setting->tag >> 8 ) & 0xff );
00089         tag_len = ( setting->tag & 0xff );
00090         if ( tag_magic != SMBIOS_TAG_MAGIC )
00091                 return -ENOENT;
00092 
00093         /* Find SMBIOS structure */
00094         if ( ( rc = find_smbios_structure ( tag_type, &structure ) ) != 0 )
00095                 return rc;
00096 
00097         {
00098                 uint8_t buf[structure.header.len];
00099 
00100                 /* Read SMBIOS structure */
00101                 if ( ( rc = read_smbios_structure ( &structure, buf,
00102                                                     sizeof ( buf ) ) ) != 0 )
00103                         return rc;
00104 
00105                 if ( tag_len == 0 ) {
00106                         /* String */
00107                         return read_smbios_string ( &structure,
00108                                                     buf[tag_offset],
00109                                                     data, len );
00110                 } else {
00111                         /* Raw data */
00112                         if ( len > tag_len )
00113                                 len = tag_len;
00114                         memcpy ( data, &buf[tag_offset], len );
00115                         return tag_len;
00116                 }
00117         }
00118 }
00119 
00120 /** SMBIOS settings operations */
00121 static struct settings_operations smbios_settings_operations = {
00122         .fetch = smbios_fetch,
00123 };
00124 
00125 /** SMBIOS settings */
00126 static struct settings smbios_settings = {
00127         .refcnt = NULL,
00128         .name = "smbios",
00129         .tag_magic = SMBIOS_EMPTY_TAG,
00130         .siblings = LIST_HEAD_INIT ( smbios_settings.siblings ),
00131         .children = LIST_HEAD_INIT ( smbios_settings.children ),
00132         .op = &smbios_settings_operations,
00133 };
00134 
00135 /** Initialise SMBIOS settings */
00136 static void smbios_init ( void ) {
00137         int rc;
00138 
00139         if ( ( rc = register_settings ( &smbios_settings, NULL ) ) != 0 ) {
00140                 DBG ( "SMBIOS could not register settings: %s\n",
00141                       strerror ( rc ) );
00142                 return;
00143         }
00144 }
00145 
00146 /** SMBIOS settings initialiser */
00147 struct init_fn smbios_init_fn __init_fn ( INIT_NORMAL ) = {
00148         .initialise = smbios_init,
00149 };
00150 
00151 /** UUID setting obtained via SMBIOS */
00152 struct setting uuid_setting __setting = {
00153         .name = "uuid",
00154         .description = "UUID",
00155         .tag = SMBIOS_RAW_TAG ( SMBIOS_TYPE_SYSTEM_INFORMATION,
00156                                 struct smbios_system_information, uuid ),
00157         .type = &setting_type_uuid,
00158 };
00159 
00160 /** Other SMBIOS named settings */
00161 struct setting smbios_named_settings[] __setting = {
00162         {
00163                 .name = "manufacturer",
00164                 .description = "Manufacturer",
00165                 .tag = SMBIOS_STRING_TAG ( SMBIOS_TYPE_SYSTEM_INFORMATION,
00166                                            struct smbios_system_information,
00167                                            manufacturer ),
00168                 .type = &setting_type_string,
00169         },
00170         {
00171                 .name = "product",
00172                 .description = "Product name",
00173                 .tag = SMBIOS_STRING_TAG ( SMBIOS_TYPE_SYSTEM_INFORMATION,
00174                                            struct smbios_system_information,
00175                                            product ),
00176                 .type = &setting_type_string,
00177         },
00178         {
00179                 .name = "serial",
00180                 .description = "Serial number",
00181                 .tag = SMBIOS_STRING_TAG ( SMBIOS_TYPE_SYSTEM_INFORMATION,
00182                                            struct smbios_system_information,
00183                                            serial ),
00184                 .type = &setting_type_string,
00185         },
00186         {
00187                 .name = "asset",
00188                 .description = "Asset tag",
00189                 .tag = SMBIOS_STRING_TAG ( SMBIOS_TYPE_ENCLOSURE_INFORMATION,
00190                                            struct smbios_enclosure_information,
00191                                            asset_tag ),
00192                 .type = &setting_type_string,
00193         },
00194 };

Generated on Tue Apr 6 20:01:09 2010 for gPXE by  doxygen 1.5.7.1