⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 eeprom.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
    /* fill in msg with the opcode & params */    BZERO( msg, BRL1_QSIZE );    if( (subch = sc_open( &sc, L1_ADDR_LOCAL )) < 0 ) {	ROUTER_UNLOCK(path);	FAIL;    }    if( (len = sc_construct_msg( &sc, subch, msg, BRL1_QSIZE,				 L1_ADDR_TASK_GENERAL,				 L1_REQ_SER_NUM, 0 )) < 0 )    {	ROUTER_UNLOCK(path);	sc_close( &sc, subch );	FAIL;    }    /* send the request to the L1 */    if( sc_command( &sc, subch, msg, msg, &len ) ) {	ROUTER_UNLOCK(path);	sc_close( &sc, subch );	FAIL;    }    /* free up subchannel */    ROUTER_UNLOCK(path);    sc_close(&sc, subch);    /* check response */    if( sc_interpret_resp( msg, 2, L1_ARG_ASCII, uid_str ) < 0 )    {	FAIL;    }    *uid = generate_unique_id( uid_str, strlen( uid_str ) );    return EEP_OK;#endif /* CONFIG_SERIAL_SGI_L1_PROTOCOL */}int iobrick_uid_get( nasid_t nasid, uint64_t *uid ){    eeprom_brd_record_t eep;    eeprom_board_ia_t board;    eeprom_chassis_ia_t chassis;    int r;    eep.board_ia = &board;    eep.chassis_ia = &chassis;    eep.spd = NULL;    r = iobrick_eeprom_read( &eep, nasid, IO_BRICK );    if( r != EEP_OK ) {        *uid = rtc_time();        return r;    }    *uid = generate_unique_id( board.serial_num,                               board.serial_num_tl & FIELD_LENGTH_MASK );    return EEP_OK;}int ibrick_mac_addr_get( nasid_t nasid, char *eaddr ){    eeprom_brd_record_t eep;    eeprom_board_ia_t board;    eeprom_chassis_ia_t chassis;    int r;    char *tmp;    eep.board_ia = &board;    eep.chassis_ia = &chassis;    eep.spd = NULL;    r = iobrick_eeprom_read( &eep, nasid, IO_BRICK );    if( (r != EEP_OK) || (board.mac_addr[0] == '\0') ) {	db_printf(( "ibrick_mac_addr_get: "		    "Couldn't read MAC address from EEPROM\n" ));	return EEP_L1;    }    else {	/* successfully read info area */	int ix;	tmp = board.mac_addr;	for( ix = 0; ix < (board.mac_addr_tl & FIELD_LENGTH_MASK); ix++ )	{	    *eaddr++ = *tmp++;	}	*eaddr = '\0';    }    return EEP_OK;}/*  * eeprom_vertex_info_set * * Given a vertex handle, a component designation, a starting nasid * and (in the case of a router) a vector path to the component, this * function will read the EEPROM and attach the resulting information * to the vertex in the same string format as that provided by the * Dallas Semiconductor NIC drivers.  If the vertex already has the * string, this function just returns the string. */extern char *nic_vertex_info_get( devfs_handle_t );extern void nic_vmc_check( devfs_handle_t, char * );#ifdef BRINGUP/* the following were lifted from nic.c - change later? */#define MAX_INFO 2048#define NEWSZ(ptr,sz)   ((ptr) = kern_malloc((sz)))#define DEL(ptr) (kern_free((ptr)))#endif /* BRINGUP */char *eeprom_vertex_info_set( int component, int nasid, devfs_handle_t v,                              net_vec_t path ){        char *info_tmp;        int info_len;        char *info;        /* see if this vertex is already marked */        info_tmp = nic_vertex_info_get(v);        if (info_tmp) return info_tmp;        /* get a temporary place for the data */        NEWSZ(info_tmp, MAX_INFO);        if (!info_tmp) return NULL;        /* read the EEPROM */	if( component & R_BRICK ) {	    if( RBRICK_EEPROM_STR( info_tmp, nasid, path ) != EEP_OK )		return NULL;	}	else {            if( eeprom_str( info_tmp, nasid, component ) != EEP_OK )	        return NULL;	}        /* allocate a smaller final place */        info_len = strlen(info_tmp)+1;        NEWSZ(info, info_len);        if (info) {                strcpy(info, info_tmp);                DEL(info_tmp);        } else {                info = info_tmp;        }        /* add info to the vertex */        hwgraph_info_add_LBL(v, INFO_LBL_NIC,                             (arbitrary_info_t) info);        /* see if someone else got there first */        info_tmp = nic_vertex_info_get(v);        if (info != info_tmp) {            DEL(info);            return info_tmp;        }        /* export the data */        hwgraph_info_export_LBL(v, INFO_LBL_NIC, info_len);        /* trigger all matching callbacks */        nic_vmc_check(v, info);        return info;}/********************************************************************* * * stubs for use until the Bedrock/L1 link is available * */#include <asm/sn/nic.h>/* #define EEPROM_TEST *//* fake eeprom reading functions (replace when the BR/L1 communication * channel is in working order) *//* generate a charater in [0-9A-Z]; if an "extra" character is * specified (such as '_'), include it as one of the possibilities. */char random_eeprom_ch( char extra ) {    char ch;    int modval = 36;    if( extra )	modval++;        ch = rtc_time() % modval;    if( ch < 10 )        ch += '0';    else if( ch >= 10 && ch < 36 )	ch += ('A' - 10);    else	ch = extra;    return ch;}/* create a part number of the form xxx-xxxx-xxx. * It may be important later to generate different * part numbers depending on the component we're * supposed to be "reading" from, so the component * paramter is provided. */void fake_a_part_number( char *buf, int component ){    int i;    switch( component ) {    /* insert component-specific routines here */    case C_BRICK:	strcpy( buf, "030-1266-001" );	break;    default:        for( i = 0; i < 12; i++ ) {	    if( i == 3 || i == 8 )	        buf[i] = '-';	    else	        buf[i] = random_eeprom_ch(0);        }    }}/* create a six-character serial number */void fake_a_serial_number( char *buf, uint64_t ser ){    int i;    static const char hexchars[] = "0123456789ABCDEF";    if (ser) {	for( i = 5; i >=0; i-- ) {	    buf[i] = hexchars[ser & 0xf];	    ser >>= 4;	}    }    else {	for( i = 0; i < 6; i++ )	    buf[i] = random_eeprom_ch(0);    }}void fake_a_product_name( uchar_t *format, char* buf, int component ){    switch( component & BRICK_MASK ) {    case C_BRICK:	if( component & SUBORD_MASK ) {	    strcpy( buf, "C_BRICK_SUB" );	    *format = 0xCB;	}	else {	    strcpy( buf, "IP35" );	    *format = 0xC4;	}	break;    case R_BRICK:        if( component & SUBORD_MASK ) {            strcpy( buf, "R_BRICK_SUB" );            *format = 0xCB;        }        else {            strcpy( buf, "R_BRICK" );            *format = 0xC7;        }        break;    case IO_BRICK:        if( component & SUBORD_MASK ) {            strcpy( buf, "IO_BRICK_SUB" );            *format = 0xCC;        }        else {            strcpy( buf, "IO_BRICK" );            *format = 0xC8;        }        break;    default:	strcpy( buf, "UNK_DEVICE" );	*format = 0xCA;    }}int fake_an_eeprom_record( eeprom_brd_record_t *buf, int component, 			   uint64_t ser ){    eeprom_board_ia_t *board;    eeprom_chassis_ia_t *chassis;    int i, cs;    board = buf->board_ia;    chassis = buf->chassis_ia;    if( !(component & SUBORD_MASK) ) {	if( !chassis )	    return EEP_PARAM;	chassis->format = 0;	chassis->length = 5;	chassis->type = 0x17;	chassis->part_num_tl = 0xCC;	fake_a_part_number( chassis->part_num, component );	chassis->serial_num_tl = 0xC6;	fake_a_serial_number( chassis->serial_num, ser );	cs = chassis->format + chassis->length + chassis->type	    + chassis->part_num_tl + chassis->serial_num_tl;	for( i = 0; i < (chassis->part_num_tl & FIELD_LENGTH_MASK); i++ )	    cs += chassis->part_num[i];	for( i = 0; i < (chassis->serial_num_tl & FIELD_LENGTH_MASK); i++ )	    cs += chassis->serial_num[i];	chassis->checksum = 256 - (cs % 256);    }    if( !board )	return EEP_PARAM;    board->format = 0;    board->length = 10;    board->language = 0;    board->mfg_date = 1789200; /* noon, 5/26/99 */    board->manuf_tl = 0xC3;    strcpy( board->manuf, "SGI" );    fake_a_product_name( &(board->product_tl), board->product, component );    board->serial_num_tl = 0xC6;    fake_a_serial_number( board->serial_num, ser );    board->part_num_tl = 0xCC;    fake_a_part_number( board->part_num, component );    board->board_rev_tl = 0xC2;    board->board_rev[0] = '0';    board->board_rev[1] = '1';    board->eeprom_size_tl = 0x01;    board->eeprom_size = 1;    board->temp_waiver_tl = 0xC2;    board->temp_waiver[0] = '0';    board->temp_waiver[1] = '1';    cs = board->format + board->length + board->language	+ (board->mfg_date & 0xFF)	+ (board->mfg_date & 0xFF00)	+ (board->mfg_date & 0xFF0000)	+ board->manuf_tl + board->product_tl + board->serial_num_tl	+ board->part_num_tl + board->board_rev_tl	+ board->board_rev[0] + board->board_rev[1]	+ board->eeprom_size_tl + board->eeprom_size + board->temp_waiver_tl	+ board->temp_waiver[0] + board->temp_waiver[1];    for( i = 0; i < (board->manuf_tl & FIELD_LENGTH_MASK); i++ )	cs += board->manuf[i];    for( i = 0; i < (board->product_tl & FIELD_LENGTH_MASK); i++ )	cs += board->product[i];    for( i = 0; i < (board->serial_num_tl & FIELD_LENGTH_MASK); i++ )	cs += board->serial_num[i];    for( i = 0; i < (board->part_num_tl & FIELD_LENGTH_MASK); i++ )	cs += board->part_num[i];        board->checksum = 256 - (cs % 256);    return EEP_OK;}#define EEPROM_CHUNKSIZE	64#if defined(EEPROM_DEBUG)#define RETURN_ERROR							\{									\    printk( "read_ia error return, component 0x%x, line %d"		\	    ", address 0x%x, ia code 0x%x\n",				\	    l1_compt, __LINE__, sc->subch[subch].target, ia_code );	\    return EEP_L1;							\}#else#define RETURN_ERROR	return(EEP_L1)#endifint read_ia( l1sc_t *sc, int subch, int l1_compt, 	     int ia_code, char *eep_record ){#if !defined(CONFIG_SERIAL_SGI_L1_PROTOCOL)    return EEP_L1;#else    char msg[BRL1_QSIZE]; 	   /* message buffer */    int len;              	   /* number of bytes used in message buffer */    int ia_len = EEPROM_CHUNKSIZE; /* remaining bytes in info area */    int offset = 0;                /* current offset into info area */    if ( IS_RUNNING_ON_SIMULATOR() )	return EEP_L1;    BZERO( msg, BRL1_QSIZE );    /* retrieve EEPROM data in 64-byte chunks     */    while( ia_len )    {	/* fill in msg with opcode & params */	if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE,				     L1_ADDR_TASK_GENERAL,				     L1_REQ_EEPROM, 8,				     L1_ARG_INT, l1_compt,				     L1_ARG_INT, ia_code,				     L1_ARG_INT, offset,				     L1_ARG_INT, ia_len )) < 0 )	{	    RETURN_ERROR;	}	/* send the request to the L1 */	if( sc_command( sc, subch, msg, msg, &len ) ) {	    RETURN_ERROR;	}	/* check response */	if( sc_interpret_resp( msg, 5, 			       L1_ARG_INT, &ia_len,			       L1_ARG_UNKNOWN, &len, eep_record ) < 0 )	{	    RETURN_ERROR;	}	if( ia_len > EEPROM_CHUNKSIZE )	    ia_len = EEPROM_CHUNKSIZE;	eep_record += EEPROM_CHUNKSIZE;	offset += EEPROM_CHUNKSIZE;    }    return EEP_OK;#endif /* CONFIG_SERIAL_SGI_L1_PROTOCOL */}int read_spd( l1sc_t *sc, int subch, int l1_compt,	      eeprom_spd_u *spd ){#if !defined(CONFIG_SERIAL_SGI_L1_PROTOCOL)    return EEP_L1;#else    char msg[BRL1_QSIZE]; 	    /* message buffer */    int len;              	    /* number of bytes used in message buffer */    int spd_len = EEPROM_CHUNKSIZE; /* remaining bytes in spd record */    int offset = 0;		    /* current offset into spd record */    char *spd_p = spd->bytes;	    /* "thumb" for writing to spd */    if ( IS_RUNNING_ON_SIMULATOR() )	return EEP_L1;    BZERO( msg, BRL1_QSIZE );    /* retrieve EEPROM data in 64-byte chunks     */    while( spd_len )    {	/* fill in msg with opcode & params */	if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE,				     L1_ADDR_TASK_GENERAL,				     L1_REQ_EEPROM, 8,				     L1_ARG_INT, l1_compt,				     L1_ARG_INT, L1_EEP_SPD,				     L1_ARG_INT, offset,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -