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

📄 l1_command.c

📁 一个2.4.21版本的嵌入式linux内核
💻 C
📖 第 1 页 / 共 3 页
字号:
    /* fill in msg with the opcode & params */    bzero( msg, BRL1_QSIZE );    L1_BUILD_ADDR( &target, compt, rack, bay, 0 );    subch = sc_open( sc, target );    if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE,				 L1_ADDR_TASK_CMD, L1_REQ_EXEC_CMD, 2,				 L1_ARG_ASCII, cmd )) < 0 )    {	sc_close( sc, subch );	return( ELSC_ERROR_CMD_ARGS );    }		       /* send the request to the L1 */    if( SC_COMMAND( sc, subch, msg, msg, &len ) < 0 )    {	sc_close( sc, subch );	return( ELSC_ERROR_CMD_SEND );    }    /* free up subchannel */    sc_close( sc, subch );        /* check response */    if( sc_interpret_resp( msg, 0 ) < 0 )    {	return( ELSC_ERROR_RESP_FORMAT );    }    return 0;}/* * sc_power_down * * Shuts down the c-brick associated with sc, and any attached I/O bricks * or other c-bricks (won't go through r-bricks). */int sc_power_down(l1sc_t *sc){    return sc_command_interp( sc, L1_ADDR_TYPE_L1, L1_ADDR_RACK_LOCAL, 			      L1_ADDR_BAY_LOCAL, "* pwr d" );}/* * sc_power_down_all * * Works similarly to sc_power_down, except that the request is sent to the * closest L2 and EVERYBODY gets turned off. */int sc_power_down_all(l1sc_t *sc){    if( nodepda->num_routers > 0 ) {	return sc_command_interp( sc, L1_ADDR_TYPE_L2, L1_ADDR_RACK_LOCAL, 				  L1_ADDR_BAY_LOCAL, "* pwr d" );    }    else {	return sc_power_down( sc );    }}/* * iobrick routines *//* iobrick_rack_bay_type_get fills in the three int * arguments with the * rack number, bay number and brick type of the L1 being addressed.  Note * that if the L1 operation fails and this function returns an error value,  * garbage may be written to brick_type. */int iobrick_rack_bay_type_get( l1sc_t *sc, uint *rack, 			       uint *bay, uint *brick_type ){    char msg[BRL1_QSIZE];       /* L1 request/response info */    int subch;                  /* system controller subchannel used */    int len;                    /* length of message */    uint32_t buf32;	        /* used to copy 32-bit rack & bay out of msg */    /* fill in msg with the opcode & params */    bzero( msg, BRL1_QSIZE );    if( (subch = sc_open( sc, L1_ADDR_LOCALIO )) < 0 ) {	return( ELSC_ERROR_CMD_SEND );    }    if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE,				 L1_ADDR_TASK_GENERAL,				 L1_REQ_RRBT, 0 )) < 0 )    {	sc_close( sc, subch );	return( ELSC_ERROR_CMD_ARGS );    }    /* send the request to the L1 */    if( sc_command( sc, subch, msg, msg, &len ) ) {	sc_close( sc, subch );	return( ELSC_ERROR_CMD_SEND );    }    /* free up subchannel */    sc_close( sc, subch );    /* check response */    if( sc_interpret_resp( msg, 4, L1_ARG_INT, &buf32, 			           L1_ARG_INT, brick_type ) < 0 )    {	return( ELSC_ERROR_RESP_FORMAT );    }    /* extract rack/bay info     *     * note that the 32-bit value returned by the L1 actually     * only uses the low-order sixteen bits for rack and bay     * information.  A "normal" L1 address puts rack and bay     * information in bit positions 12 through 28.  So if     * we initially shift the value returned 12 bits to the left,     * we can use the L1 addressing #define's to extract the     * values we need (see ksys/l1.h for a complete list of the     * various fields of an L1 address).     */    buf32 <<= L1_ADDR_BAY_SHFT;    *rack = (buf32 & L1_ADDR_RACK_MASK) >> L1_ADDR_RACK_SHFT;    *bay = (buf32 & L1_ADDR_BAY_MASK) >> L1_ADDR_BAY_SHFT;    return 0;}int iobrick_module_get(l1sc_t *sc){    uint rnum, rack, bay, brick_type, t;    int ret;    /* construct module ID from rack and slot info */    if ((ret = iobrick_rack_bay_type_get(sc, &rnum, &bay, &brick_type)) < 0)        return ret;    if (bay > MODULE_BPOS_MASK >> MODULE_BPOS_SHFT)        return ELSC_ERROR_MODULE;    /* Build a moduleid_t-compatible rack number */    rack = 0;               t = rnum / 100;             /* rack class (CPU/IO) */    if (t > RACK_CLASS_MASK(rack) >> RACK_CLASS_SHFT(rack))        return ELSC_ERROR_MODULE;    RACK_ADD_CLASS(rack, t);    rnum %= 100;    t = rnum / 10;              /* rack group */    if (t > RACK_GROUP_MASK(rack) >> RACK_GROUP_SHFT(rack))        return ELSC_ERROR_MODULE;    RACK_ADD_GROUP(rack, t);    t = rnum % 10;              /* rack number (one-based) */    if (t-1 > RACK_NUM_MASK(rack) >> RACK_NUM_SHFT(rack))        return ELSC_ERROR_MODULE;    RACK_ADD_NUM(rack, t);    switch( brick_type ) {      case 'I': 	brick_type = MODULE_IBRICK; break;      case 'P':	brick_type = MODULE_PBRICK; break;      case 'X':	brick_type = MODULE_XBRICK; break;    }    ret = RBT_TO_MODULE(rack, bay, brick_type);    return ret;}/* * iobrick_module_get_nasid() returns a module_id which has the brick * type encoded in bits 15-12, but this is not the true brick type... * The module_id returned by iobrick_module_get_nasid() is modified * to make a PEBRICKs & PXBRICKs look like a PBRICK.  So this routine * iobrick_type_get_nasid() returns the true unmodified brick type. */intiobrick_type_get_nasid(nasid_t nasid){    l1sc_t *sc = get_elsc();    elsc_t tmp_sc;    uint rack, bay, type;    int t, ret;#ifdef PIC_LATER    if (PEBRICK_NODE(nasid)) {        if (peer_iobrick_rack_bay_get(nasid, &rack, &bay)) {            printf("Could not read rack and bay location "                   "of PEBrick at nasid %d\n", nasid);        }        if ((ret = peer_iobrick_type_get(sc, rack, bay, &type)) < 0)            return ret;    }    else#endif	/* PIC_LATER */    if (nasid != get_nasid()) { /* get the io_moduleid from remote node */        elsc_init(&tmp_sc, nasid);        if ((ret = iobrick_rack_bay_type_get(&tmp_sc, &rack, &bay, &type)) < 0)            return ret;    }    else {        if ((ret = iobrick_rack_bay_type_get(sc, &rack, &bay, &type)) < 0)            return ret;    }    /*     * Some brick_types need special treatment.  NOTE: This switch is     * duplicated in iobrick_module_get(),  so if you change this switch     * you must also change it there.     */    switch (type)    {    case L1_BRICKTYPE_IP45:        /* treat speedo2 like Ibrick for moduleid purposes */        type = L1_BRICKTYPE_I;        break;    case L1_BRICKTYPE_X2:        /* give X2 bricks the same moduleid as earlier models */        type = L1_BRICKTYPE_X;        break;    }    /* convert brick_type to lower case */    if ((type >= 'A') && (type <= 'Z'))        type = type - 'A' + 'a';    /* convert to a module.h brick type */    for( t = 0; t < MAX_BRICK_TYPES; t++ ) {        if( brick_types[t] == type )            return t;    }    return -1;    /* unknown brick */}int iobrick_module_get_nasid(nasid_t nasid){    int io_moduleid;    l1sc_t *sc = get_elsc();    elsc_t tmp_sc;#ifdef PIC_LATER    uint rack, bay;    if (PEBRICK_NODE(nasid)) {        if (peer_iobrick_rack_bay_get(nasid, &rack, &bay)) {            printf("Could not read rack and bay location "                   "of PEBrick at nasid %d\n", nasid);        }        io_moduleid = peer_iobrick_module_get(sc, rack, bay);    }    else#endif	/* PIC_LATER */    if (nasid != get_nasid()) { /* get the io_moduleid from remote node */        elsc_init(&tmp_sc, nasid);        io_moduleid = iobrick_module_get(&tmp_sc);    }    else {        io_moduleid = iobrick_module_get(sc);    }    return io_moduleid;}/* iobrick_get_sys_snum asks the attached iobrick for the system * serial number.  This function will only be relevant to the master * cbrick (the one attached to the bootmaster ibrick); other nodes * may call the function, but the value returned to the master node * will be the one used as the system serial number by the kernel. */intiobrick_get_sys_snum( l1sc_t *sc, char *snum_str ){    char msg[BRL1_QSIZE];       /* L1 request/response info */    int subch;                  /* system controller subchannel used */    int len;                    /* length of message */        /* fill in msg with the opcode & params */    bzero( msg, BRL1_QSIZE );    if( (subch = sc_open( sc, L1_ADDR_LOCALIO )) < 0 ) {	return( ELSC_ERROR_CMD_SEND );    }    if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE,				 L1_ADDR_TASK_GENERAL,				 L1_REQ_SYS_SERIAL, 0 )) < 0 )    {	sc_close( sc, subch );	return( ELSC_ERROR_CMD_ARGS );    }    /* send the request to the L1 */    if( sc_command( sc, subch, msg, msg, &len ) ) {	sc_close( sc, subch );	return( ELSC_ERROR_CMD_SEND );    }    /* free up subchannel */    sc_close( sc, subch );    /* check response */    return( sc_interpret_resp( msg, 2, L1_ARG_ASCII, snum_str ) );}/* * The following functions apply (or cut off) power to the specified * pci bus or slot. */intiobrick_pci_pwr( l1sc_t *sc, int bus, int slot, int req_code ){#if 0 /* The "bedrock request" method of performing this function       * seems to be broken in the L1, so for now use the command-       * interpreter method       */    char	msg[BRL1_QSIZE];    int		len;    /* length of message being sent */    int		subch;  /* system controller subchannel used */    /* fill in msg with the opcode & params */    bzero( msg, BRL1_QSIZE );    subch = sc_open( sc, L1_ADDR_LOCALIO );    if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE,				 L1_ADDR_TASK_GENERAL,				 req_code, 4,				 L1_ARG_INT, bus,				 L1_ARG_INT, slot )) < 0 )    {	sc_close( sc, subch );	return( ELSC_ERROR_CMD_ARGS );    }    /* send the request to the L1 */    if( SC_COMMAND(sc, subch, msg, msg, &len ) < 0 )    {	sc_close( sc, subch );	return( ELSC_ERROR_CMD_SEND );    }    /* free up subchannel */    sc_close( sc, subch );    /* check response */    if( sc_interpret_resp( msg, 0 ) < 0 )    {	return( ELSC_ERROR_RESP_FORMAT );    }    return 0;#else    char cmd[64];    char *fxn;    switch( req_code )    {    case L1_REQ_PCI_UP:	fxn = "u";	break;    case L1_REQ_PCI_DOWN:	fxn = "d";	break;    case L1_REQ_PCI_RESET:	fxn = "rst";	break;    default:	return( ELSC_ERROR_CMD_ARGS );    }    if( slot == -1 ) 	sprintf( cmd, "pci %d %s", bus, fxn );    else        sprintf( cmd, "pci %d %d %s", bus, slot, fxn );	    return sc_command_interp( sc, L1_ADDR_TYPE_IOBRICK,	L1_ADDR_RACK_LOCAL, L1_ADDR_BAY_LOCAL, cmd );#endif}				 intiobrick_pci_slot_pwr( l1sc_t *sc, int bus, int slot, int up ){    return iobrick_pci_pwr( sc, bus, slot, up );}intiobrick_pci_bus_pwr( l1sc_t *sc, int bus, int up ){    return iobrick_pci_pwr( sc, bus, -1, up );}intiobrick_pci_slot_rst( l1sc_t *sc, int bus, int slot ){    return iobrick_pci_pwr( sc, bus, slot, L1_REQ_PCI_RESET );}intiobrick_pci_bus_rst( l1sc_t *sc, int bus ){    return iobrick_pci_pwr( sc, bus, -1, L1_REQ_PCI_RESET );}/* get the L1 firmware version for an iobrick */intiobrick_sc_version( l1sc_t *sc, char *result ){    char	msg[BRL1_QSIZE];    int		len;    /* length of message being sent */    int		subch;  /* system controller subchannel used */    int		major,  /* major rev number */	        minor,  /* minor rev number */                bugfix; /* bugfix rev number */    /* fill in msg with the opcode & params */    bzero( msg, BRL1_QSIZE );    subch = sc_open( sc, L1_ADDR_LOCALIO );    if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE,				 L1_ADDR_TASK_GENERAL,				 L1_REQ_FW_REV, 0 )) < 0 )    {	sc_close( sc, subch );	return( ELSC_ERROR_CMD_ARGS );    }    /* send the request to the L1 */    if( SC_COMMAND(sc, subch, msg, msg, &len ) < 0 )    {	sc_close( sc, subch );	return( ELSC_ERROR_CMD_SEND );    }    /* free up subchannel */    sc_close( sc, subch );    /* check response */    if( sc_interpret_resp( msg, 6, L1_ARG_INT, &major,			   L1_ARG_INT, &minor, L1_ARG_INT, &bugfix )	< 0 )    {	return( ELSC_ERROR_RESP_FORMAT );    }    sprintf( result, "%d.%d.%d", major, minor, bugfix );    return 0;}

⌨️ 快捷键说明

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