IPMI driver

ipmi_msghandler: IPMI的核心,負責處理所有的message,IPMI user及IPMI的physical interface (SMI, System Management Interface)都綁在msghandler上。但只提供kernelland的interface,userland則需另一個下一個driver (devintf)。

ipmi_devintf: userland的 IOCTL。

ipmi_si: 不同system interface (如SMIC, BT, SSIF和KCS)的driver。下面的範例即需要這個。

ipmi_watchdog: 一個watchdog timer來監控系統

ipmi_poweroff: 藉由IPMI關機

 

IPMI addressing

目前有兩種address type:

system interface (範例中使用):

struct ipmi_system_interface_addr
{
int addr_type;
short channel;
};

  這裡 addr_type設為IPMI_SYSTEM_INTERFACE_ADDR_TYPE,channel則是IPMI_BMC_CHANNEL。

另一個IPMB沒用過:

struct ipmi_ipmb_addr
{
    int addr_type;
short channel;
unsigned char slave_addr;
unsigned char lun;
};

  這裡channel通常填0。

 

IPMI message

struct ipmi_msg
{
unsigned char netfn;
unsigned char lun;
unsigned char cmd;
unsigned char *data;
int data_len;
};

Front Panel 有四顆telco alarm LED: PWR/CRI/MJR/MNR,以下為透過IPMI kernel driver傳送IPMI message給BMC來控制LED。

#include <linux/ipmi.h>
#include <linux/ipmi_smi.h>

#define IPMI_MAX_INTF            (4)
static ipmi_user_t ipmi_mh_user = NULL;


static void msg_handler(struct ipmi_recv_msg *msg,void* handler_data)
{
    ipmi_free_recv_msg(msg);
    return;
}


static struct ipmi_user_hndl ipmi_hndlrs = {   .ipmi_recv_hndl = msg_handler,};

static int Led_ctrl_entry_point()

    int rv;

    struct ipmi_system_interface_addr addr;
    uint8_t data[4] = {0};

    struct kernel_ipmi_msg msg;
   
    for (i=0; i<IPMI_MAX_INTF && rv; i++) {
        rv = ipmi_create_user(i, &ipmi_hndlrs, NULL, &ipmi_mh_user);
    }

    if (rv < 0) {
        V54_PRINTF("warning: create user fail, watchdog broken\n");
    }

    addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; //0x0c
    addr.channel = IPMI_BMC_CHANNEL;  //0xf
    addr.lun = 0;

    msg.netfn = IPMI_NETFUNC_APP;  //0x06
    msg.cmd = IPMI_ALARMS_CMD; //0x52
    data[0] = 0x03;
    data[1] = 0x40;
    data[2] = 0x1;
    data[3] = 0xf7; //Turn on PWR 
    msg.data_len = sizeof(data);
    msg.data = data;
    rv = ipmi_request_settime(t5520ur_led_user, (struct ipmi_addr*)&addr, 0, &msg,NULL, 1, -1, 0);

    if (rv) {
        printk("warning: send request fail, led broken\n");
    }
    ipmi_destroy_user(ipmi_mh_user);

    return 0;

}

kezeodsnx 發表在 痞客邦 PIXNET 留言(0) 人氣()