📄 eeprom.c
字号:
L1_ARG_INT, spd_len )) < 0 ) { return( EEP_L1 ); } /* send the request to the L1 */ if( sc_command( sc, subch, msg, msg, &len ) ) { return( EEP_L1 ); } /* check response */ if( sc_interpret_resp( msg, 5, L1_ARG_INT, &spd_len, L1_ARG_UNKNOWN, &len, spd_p ) < 0 ) { return( EEP_L1 ); } if( spd_len > EEPROM_CHUNKSIZE ) spd_len = EEPROM_CHUNKSIZE; spd_p += EEPROM_CHUNKSIZE; offset += EEPROM_CHUNKSIZE; } return EEP_OK;#endif /* CONFIG_SERIAL_SGI_L1_PROTOCOL */}int read_chassis_ia( l1sc_t *sc, int subch, int l1_compt, eeprom_chassis_ia_t *ia ){ char eep_record[512]; /* scratch area for building up info area */ char *eep_rec_p = eep_record; /* thumb for moving through eep_record */ int checksum = 0; /* use to verify eeprom record checksum */ int i; /* Read in info area record from the L1. */ if( read_ia( sc, subch, l1_compt, L1_EEP_CHASSIS, eep_record ) != EEP_OK ) { return EEP_L1; } /* Now we've got the whole info area. Transfer it to the data structure. */ eep_rec_p = eep_record; ia->format = *eep_rec_p++; ia->length = *eep_rec_p++; if( ia->length == 0 ) { /* since we're using 8*ia->length-1 as an array index later, make * sure it's sane. */ db_printf(( "read_chassis_ia: eeprom length byte of ZERO\n" )); return EEP_L1; } ia->type = *eep_rec_p++; ia->part_num_tl = *eep_rec_p++; (void)BCOPY( eep_rec_p, ia->part_num, (ia->part_num_tl & FIELD_LENGTH_MASK) ); eep_rec_p += (ia->part_num_tl & FIELD_LENGTH_MASK); ia->serial_num_tl = *eep_rec_p++; BCOPY( eep_rec_p, ia->serial_num, (ia->serial_num_tl & FIELD_LENGTH_MASK) ); eep_rec_p += (ia->serial_num_tl & FIELD_LENGTH_MASK); ia->checksum = eep_record[(8 * ia->length) - 1]; /* verify checksum */ eep_rec_p = eep_record; checksum = 0; for( i = 0; i < (8 * ia->length); i++ ) { checksum += *eep_rec_p++; } if( (checksum & 0xff) != 0 ) { db_printf(( "read_chassis_ia: bad checksum\n" )); db_printf(( "read_chassis_ia: target 0x%x uart 0x%x\n", sc->subch[subch].target, sc->uart )); return EEP_BAD_CHECKSUM; } return EEP_OK;}int read_board_ia( l1sc_t *sc, int subch, int l1_compt, eeprom_board_ia_t *ia ){ char eep_record[512]; /* scratch area for building up info area */ char *eep_rec_p = eep_record; /* thumb for moving through eep_record */ int checksum = 0; /* running checksum total */ int i; BZERO( ia, sizeof( eeprom_board_ia_t ) ); /* Read in info area record from the L1. */ if( read_ia( sc, subch, l1_compt, L1_EEP_BOARD, eep_record ) != EEP_OK ) { db_printf(( "read_board_ia: error reading info area from L1\n" )); return EEP_L1; } /* Now we've got the whole info area. Transfer it to the data structure. */ eep_rec_p = eep_record; ia->format = *eep_rec_p++; ia->length = *eep_rec_p++; if( ia->length == 0 ) { /* since we're using 8*ia->length-1 as an array index later, make * sure it's sane. */ db_printf(( "read_board_ia: eeprom length byte of ZERO\n" )); return EEP_L1; } ia->language = *eep_rec_p++; ia->mfg_date = eeprom_xlate_board_mfr_date( (uchar_t *)eep_rec_p ); eep_rec_p += 3; ia->manuf_tl = *eep_rec_p++; BCOPY( eep_rec_p, ia->manuf, (ia->manuf_tl & FIELD_LENGTH_MASK) ); eep_rec_p += (ia->manuf_tl & FIELD_LENGTH_MASK); ia->product_tl = *eep_rec_p++; BCOPY( eep_rec_p, ia->product, (ia->product_tl & FIELD_LENGTH_MASK) ); eep_rec_p += (ia->product_tl & FIELD_LENGTH_MASK); ia->serial_num_tl = *eep_rec_p++; BCOPY(eep_rec_p, ia->serial_num, (ia->serial_num_tl & FIELD_LENGTH_MASK)); eep_rec_p += (ia->serial_num_tl & FIELD_LENGTH_MASK); ia->part_num_tl = *eep_rec_p++; BCOPY( eep_rec_p, ia->part_num, (ia->part_num_tl & FIELD_LENGTH_MASK) ); eep_rec_p += (ia->part_num_tl & FIELD_LENGTH_MASK); eep_rec_p++; /* we do not use the FRU file id */ ia->board_rev_tl = *eep_rec_p++; BCOPY( eep_rec_p, ia->board_rev, (ia->board_rev_tl & FIELD_LENGTH_MASK) ); eep_rec_p += (ia->board_rev_tl & FIELD_LENGTH_MASK); ia->eeprom_size_tl = *eep_rec_p++; ia->eeprom_size = *eep_rec_p++; ia->temp_waiver_tl = *eep_rec_p++; BCOPY( eep_rec_p, ia->temp_waiver, (ia->temp_waiver_tl & FIELD_LENGTH_MASK) ); eep_rec_p += (ia->temp_waiver_tl & FIELD_LENGTH_MASK); /* if there's more, we must be reading a main board; get * additional fields */ if( ((unsigned char)*eep_rec_p != (unsigned char)EEPROM_EOF) ) { ia->ekey_G_tl = *eep_rec_p++; BCOPY( eep_rec_p, (char *)&ia->ekey_G, ia->ekey_G_tl & FIELD_LENGTH_MASK ); eep_rec_p += (ia->ekey_G_tl & FIELD_LENGTH_MASK); ia->ekey_P_tl = *eep_rec_p++; BCOPY( eep_rec_p, (char *)&ia->ekey_P, ia->ekey_P_tl & FIELD_LENGTH_MASK ); eep_rec_p += (ia->ekey_P_tl & FIELD_LENGTH_MASK); ia->ekey_Y_tl = *eep_rec_p++; BCOPY( eep_rec_p, (char *)&ia->ekey_Y, ia->ekey_Y_tl & FIELD_LENGTH_MASK ); eep_rec_p += (ia->ekey_Y_tl & FIELD_LENGTH_MASK); /* * need to get a couple more fields if this is an I brick */ if( ((unsigned char)*eep_rec_p != (unsigned char)EEPROM_EOF) ) { ia->mac_addr_tl = *eep_rec_p++; BCOPY( eep_rec_p, ia->mac_addr, ia->mac_addr_tl & FIELD_LENGTH_MASK ); eep_rec_p += (ia->mac_addr_tl & FIELD_LENGTH_MASK); ia->ieee1394_cfg_tl = *eep_rec_p++; BCOPY( eep_rec_p, ia->ieee1394_cfg, ia->ieee1394_cfg_tl & FIELD_LENGTH_MASK ); } } ia->checksum = eep_record[(ia->length * 8) - 1]; /* verify checksum */ eep_rec_p = eep_record; checksum = 0; for( i = 0; i < (8 * ia->length); i++ ) { checksum += *eep_rec_p++; } if( (checksum & 0xff) != 0 ) { db_printf(( "read_board_ia: bad checksum\n" )); db_printf(( "read_board_ia: target 0x%x uart 0x%x\n", sc->subch[subch].target, sc->uart )); return EEP_BAD_CHECKSUM; } return EEP_OK;}int _cbrick_eeprom_read( eeprom_brd_record_t *buf, l1sc_t *scp, int component ){#if !defined(CONFIG_SERIAL_SGI_L1_PROTOCOL) return EEP_L1;#else int r; uint64_t uid = 0; char uid_str[32]; int l1_compt, subch; if ( IS_RUNNING_ON_SIMULATOR() ) return EEP_L1; /* make sure we're targeting a cbrick */ if( !(component & C_BRICK) ) return EEP_PARAM; /* If the promlog variable pointed to by IP27LOG_OVNIC is set, * use that value for the cbrick UID rather than the EEPROM * serial number. */#ifdef LOG_GETENV if( ip27log_getenv( scp->nasid, IP27LOG_OVNIC, uid_str, "0", 0 ) >= 0 ) { db_printf(( "_cbrick_eeprom_read: " "Overriding UID with environment variable %s\n", IP27LOG_OVNIC )); uid = strtoull( uid_str, NULL, 0 ); }#endif if( (subch = sc_open( scp, L1_ADDR_LOCAL )) < 0 ) return EEP_L1; switch( component ) { case C_BRICK: /* c-brick motherboard */ l1_compt = L1_EEP_NODE; r = read_chassis_ia( scp, subch, l1_compt, buf->chassis_ia ); if( r != EEP_OK ) { sc_close( scp, subch ); db_printf(( "_cbrick_eeprom_read: using a fake eeprom record\n" )); return fake_an_eeprom_record( buf, component, uid ); } if( uid ) { /* If IP27LOG_OVNIC is set, we want to put that value * in as our UID. */ fake_a_serial_number( buf->chassis_ia->serial_num, uid ); buf->chassis_ia->serial_num_tl = 6; } break; case C_PIMM: /* one of the PIMM boards */ l1_compt = L1_EEP_PIMM( component & COMPT_MASK ); break; case C_DIMM: /* one of the DIMMs */ l1_compt = L1_EEP_DIMM( component & COMPT_MASK ); r = read_spd( scp, subch, l1_compt, buf->spd ); sc_close( scp, subch ); return r; default: /* unsupported board type */ sc_close( scp, subch ); return EEP_PARAM; } r = read_board_ia( scp, subch, l1_compt, buf->board_ia ); sc_close( scp, subch ); if( r != EEP_OK ) { db_printf(( "_cbrick_eeprom_read: using a fake eeprom record\n" )); return fake_an_eeprom_record( buf, component, uid ); } return EEP_OK;#endif /* CONFIG_SERIAL_SGI_L1_PROTOCOL */}int cbrick_eeprom_read( eeprom_brd_record_t *buf, nasid_t nasid, int component ){#if !defined(CONFIG_SERIAL_SGI_L1_PROTOCOL) return EEP_L1;#else l1sc_t *scp; int local = (nasid == get_nasid()); if ( IS_RUNNING_ON_SIMULATOR() ) return EEP_L1; /* If this brick is retrieving its own uid, use the local l1sc_t to * arbitrate access to the l1; otherwise, set up a new one (prom) or * use an existing remote l1sc_t (kernel) */ if( local ) { scp = get_l1sc(); } else { elsc_t *get_elsc(void); scp = get_elsc(); } return _cbrick_eeprom_read( buf, scp, component );#endif /* CONFIG_SERIAL_SGI_L1_PROTOCOL */}int iobrick_eeprom_read( eeprom_brd_record_t *buf, nasid_t nasid, int component ){#if !defined(CONFIG_SERIAL_SGI_L1_PROTOCOL) return EEP_L1;#else int r; int l1_compt, subch; l1sc_t *scp; int local = (nasid == get_nasid()); if ( IS_RUNNING_ON_SIMULATOR() ) return EEP_L1; /* make sure we're talking to an applicable brick */ if( !(component & IO_BRICK) ) { return EEP_PARAM; } /* If we're talking to this c-brick's attached io brick, use * the local l1sc_t; otherwise, set up a new one (prom) or * use an existing remote l1sc_t (kernel) */ if( local ) { scp = get_l1sc(); } else { elsc_t *get_elsc(void); scp = get_elsc(); } if( (subch = sc_open( scp, L1_ADDR_LOCALIO )) < 0 ) return EEP_L1; switch( component ) { case IO_BRICK: /* IO brick motherboard */ l1_compt = L1_EEP_LOGIC; r = read_chassis_ia( scp, subch, l1_compt, buf->chassis_ia ); if( r != EEP_OK ) { sc_close( scp, subch );#ifdef BRINGUP /* Once EEPROMs are universally available, remove this */ r = fake_an_eeprom_record( buf, component, rtc_time() );#endif /* BRINGUP */ return r; } break; case IO_POWER: /* IO brick power board */ l1_compt = L1_EEP_POWER; break; default: /* unsupported board type */ sc_close( scp, subch ); return EEP_PARAM; } r = read_board_ia( scp, subch, l1_compt, buf->board_ia ); sc_close( scp, subch ); if( r != EEP_OK ) { return r; } return EEP_OK;#endif /* CONFIG_SERIAL_SGI_L1_PROTOCOL */ }int vector_eeprom_read( eeprom_brd_record_t *buf, nasid_t nasid, net_vec_t path, int component ){#if !defined(CONFIG_SERIAL_SGI_L1_PROTOCOL) return EEP_L1;#else int r; uint64_t uid = 0; int l1_compt, subch; l1sc_t sc; if ( IS_RUNNING_ON_SIMULATOR() ) return EEP_L1; /* make sure we're targeting an applicable brick */ if( !(component & VECTOR) ) return EEP_PARAM; switch( component & BRICK_MASK ) { case R_BRICK: ROUTER_LOCK( path ); sc_init( &sc, nasid, path ); if( (subch = sc_open( &sc, L1_ADDR_LOCAL )) < 0 ) { db_printf(( "vector_eeprom_read: couldn't open subch\n" )); ROUTER_UNLOCK(path); return EEP_L1; } switch( component ) { case R_BRICK: /* r-brick motherboard */ l1_compt = L1_EEP_LOGIC; r = read_chassis_ia( &sc, subch, l1_compt, buf->chassis_ia ); if( r != EEP_OK ) { sc_close( &sc, subch ); ROUTER_UNLOCK( path ); printk( "vector_eeprom_read: couldn't get rbrick eeprom info;" " using current time as uid\n" ); uid = rtc_time(); db_printf(("vector_eeprom_read: using a fake eeprom record\n")); return fake_an_eeprom_record( buf, component, uid ); } break; case R_POWER: /* r-brick power board */ l1_compt = L1_EEP_POWER; break; default: /* unsupported board type */ sc_close( &sc, subch ); ROUTER_UNLOCK( path ); return EEP_PARAM; } r = read_board_ia( &sc, subch, l1_compt, buf->board_ia ); sc_close( &sc, subch ); ROUTER_UNLOCK( path ); if( r != EEP_OK ) { db_printf(( "vector_eeprom_read: using a fake eeprom record\n" )); return fake_an_eeprom_record( buf, component, uid ); } return EEP_OK; case C_BRICK: sc_init( &sc, nasid, path ); return _cbrick_eeprom_read( buf, &sc, component ); default: /* unsupported brick type */ return EEP_PARAM; }#endif /* CONFIG_SERIAL_SGI_L1_PROTOCOL */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -