Page MenuHomeFreeBSD

D35605.diff
No OneTemporary

D35605.diff

diff --git a/sys/dev/ipmi/ipmi.c b/sys/dev/ipmi/ipmi.c
--- a/sys/dev/ipmi/ipmi.c
+++ b/sys/dev/ipmi/ipmi.c
@@ -76,12 +76,6 @@
IPMI_INIT_DRIVER_REQUEST((req), (addr), (cmd), (reqlen), \
(replylen))
-#ifdef IPMB
-static int ipmi_ipmb_checksum(u_char, int);
-static int ipmi_ipmb_send_message(device_t, u_char, u_char, u_char,
- u_char, u_char, int)
-#endif
-
static d_ioctl_t ipmi_ioctl;
static d_poll_t ipmi_poll;
static d_open_t ipmi_open;
@@ -245,83 +239,16 @@
free(dev, M_IPMI);
}
-#ifdef IPMB
-static int
+static u_char
ipmi_ipmb_checksum(u_char *data, int len)
{
u_char sum = 0;
- for (; len; len--) {
+ for (; len; len--)
sum += *data++;
- }
return (-sum);
}
-/* XXX: Needs work */
-static int
-ipmi_ipmb_send_message(device_t dev, u_char channel, u_char netfn,
- u_char command, u_char seq, u_char *data, int data_len)
-{
- struct ipmi_softc *sc = device_get_softc(dev);
- struct ipmi_request *req;
- u_char slave_addr = 0x52;
- int error;
-
- IPMI_ALLOC_DRIVER_REQUEST(req, IPMI_ADDR(IPMI_APP_REQUEST, 0),
- IPMI_SEND_MSG, data_len + 8, 0);
- req->ir_request[0] = channel;
- req->ir_request[1] = slave_addr;
- req->ir_request[2] = IPMI_ADDR(netfn, 0);
- req->ir_request[3] = ipmi_ipmb_checksum(&req->ir_request[1], 2);
- req->ir_request[4] = sc->ipmi_address;
- req->ir_request[5] = IPMI_ADDR(seq, sc->ipmi_lun);
- req->ir_request[6] = command;
-
- bcopy(data, &req->ir_request[7], data_len);
- temp[data_len + 7] = ipmi_ipmb_checksum(&req->ir_request[4],
- data_len + 3);
-
- ipmi_submit_driver_request(sc, req);
- error = req->ir_error;
-
- return (error);
-}
-
-static int
-ipmi_handle_attn(struct ipmi_softc *sc)
-{
- struct ipmi_request *req;
- int error;
-
- device_printf(sc->ipmi_dev, "BMC has a message\n");
- IPMI_ALLOC_DRIVER_REQUEST(req, IPMI_ADDR(IPMI_APP_REQUEST, 0),
- IPMI_GET_MSG_FLAGS, 0, 1);
-
- ipmi_submit_driver_request(sc, req);
-
- if (req->ir_error == 0 && req->ir_compcode == 0) {
- if (req->ir_reply[0] & IPMI_MSG_BUFFER_FULL) {
- device_printf(sc->ipmi_dev, "message buffer full");
- }
- if (req->ir_reply[0] & IPMI_WDT_PRE_TIMEOUT) {
- device_printf(sc->ipmi_dev,
- "watchdog about to go off");
- }
- if (req->ir_reply[0] & IPMI_MSG_AVAILABLE) {
- IPMI_ALLOC_DRIVER_REQUEST(req,
- IPMI_ADDR(IPMI_APP_REQUEST, 0), IPMI_GET_MSG, 0,
- 16);
-
- device_printf(sc->ipmi_dev, "throw out message ");
- dump_buf(temp, 16);
- }
- }
- error = req->ir_error;
-
- return (error);
-}
-#endif
-
static int
ipmi_ioctl(struct cdev *cdev, u_long cmd, caddr_t data,
int flags, struct thread *td)
@@ -377,38 +304,68 @@
case IPMICTL_SEND_COMMAND_32:
#endif
case IPMICTL_SEND_COMMAND:
- /*
- * XXX: Need to add proper handling of this.
- */
error = copyin(req->addr, &addr, sizeof(addr));
if (error)
return (error);
- IPMI_LOCK(sc);
- /* clear out old stuff in queue of stuff done */
- /* XXX: This seems odd. */
- while ((kreq = TAILQ_FIRST(&dev->ipmi_completed_requests))) {
- TAILQ_REMOVE(&dev->ipmi_completed_requests, kreq,
- ir_link);
- dev->ipmi_requests--;
- ipmi_free_request(kreq);
+ if (addr.addr_type == IPMI_SYSTEM_INTERFACE_ADDR_TYPE) {
+ kreq = ipmi_alloc_request(dev, req->msgid,
+ IPMI_ADDR(req->msg.netfn, 0), req->msg.cmd,
+ req->msg.data_len, IPMI_MAX_RX);
+ error = copyin(req->msg.data, kreq->ir_request,
+ req->msg.data_len);
+ if (error) {
+ ipmi_free_request(kreq);
+ return (error);
+ }
+ IPMI_LOCK(sc);
+ dev->ipmi_requests++;
+ error = sc->ipmi_enqueue_request(sc, kreq);
+ IPMI_UNLOCK(sc);
+ if (error)
+ return (error);
+ break;
}
- IPMI_UNLOCK(sc);
- kreq = ipmi_alloc_request(dev, req->msgid,
- IPMI_ADDR(req->msg.netfn, 0), req->msg.cmd,
- req->msg.data_len, IPMI_MAX_RX);
- error = copyin(req->msg.data, kreq->ir_request,
- req->msg.data_len);
- if (error) {
- ipmi_free_request(kreq);
- return (error);
+ /* Special processing for IPMB commands */
+ struct ipmi_ipmb_addr *iaddr = (struct ipmi_ipmb_addr *)&addr;
+
+ IPMI_ALLOC_DRIVER_REQUEST(kreq, IPMI_ADDR(IPMI_APP_REQUEST, 0),
+ IPMI_SEND_MSG, req->msg.data_len + 8, IPMI_MAX_RX);
+ /* Construct the SEND MSG header */
+ kreq->ir_request[0] = iaddr->channel;
+ kreq->ir_request[1] = iaddr->slave_addr;
+ kreq->ir_request[2] = IPMI_ADDR(req->msg.netfn, iaddr->lun);
+ kreq->ir_request[3] =
+ ipmi_ipmb_checksum(&kreq->ir_request[1], 2);
+ kreq->ir_request[4] = dev->ipmi_address;
+ kreq->ir_request[5] = IPMI_ADDR(0, dev->ipmi_lun);
+ kreq->ir_request[6] = req->msg.cmd;
+ /* Copy the message data */
+ if (req->msg.data_len > 0) {
+ error = copyin(req->msg.data, &kreq->ir_request[7],
+ req->msg.data_len);
+ if (error != 0)
+ return (error);
}
+ kreq->ir_request[req->msg.data_len + 7] =
+ ipmi_ipmb_checksum(&kreq->ir_request[4],
+ req->msg.data_len + 3);
+ error = ipmi_submit_driver_request(sc, kreq, MAX_TIMEOUT);
+ if (error != 0)
+ return (error);
+
+ kreq = ipmi_alloc_request(dev, req->msgid,
+ IPMI_ADDR(IPMI_APP_REQUEST, 0), IPMI_GET_MSG,
+ 0, IPMI_MAX_RX);
+ kreq->ir_ipmb = true;
+ kreq->ir_ipmb_addr = IPMI_ADDR(req->msg.netfn, 0);
+ kreq->ir_ipmb_command = req->msg.cmd;
IPMI_LOCK(sc);
dev->ipmi_requests++;
error = sc->ipmi_enqueue_request(sc, kreq);
IPMI_UNLOCK(sc);
- if (error)
+ if (error != 0)
return (error);
break;
#ifdef IPMICTL_SEND_COMMAND_32
@@ -427,26 +384,38 @@
IPMI_UNLOCK(sc);
return (EAGAIN);
}
- addr.channel = IPMI_BMC_CHANNEL;
- /* XXX */
- recv->recv_type = IPMI_RESPONSE_RECV_TYPE;
- recv->msgid = kreq->ir_msgid;
- recv->msg.netfn = IPMI_REPLY_ADDR(kreq->ir_addr) >> 2;
- recv->msg.cmd = kreq->ir_command;
- error = kreq->ir_error;
- if (error) {
+ if (kreq->ir_error != 0) {
TAILQ_REMOVE(&dev->ipmi_completed_requests, kreq,
ir_link);
dev->ipmi_requests--;
IPMI_UNLOCK(sc);
ipmi_free_request(kreq);
- return (error);
+ return (kreq->ir_error);
}
- len = kreq->ir_replylen + 1;
+
+ recv->recv_type = IPMI_RESPONSE_RECV_TYPE;
+ recv->msgid = kreq->ir_msgid;
+ if (kreq->ir_ipmb) {
+ addr.channel = IPMI_IPMB_CHANNEL;
+ recv->msg.netfn =
+ IPMI_REPLY_ADDR(kreq->ir_ipmb_addr) >> 2;
+ recv->msg.cmd = kreq->ir_ipmb_command;
+ /* Get the compcode of response */
+ kreq->ir_compcode = kreq->ir_reply[6];
+ /* Move the reply head past response header */
+ kreq->ir_reply += 7;
+ len = kreq->ir_replylen - 7;
+ } else {
+ addr.channel = IPMI_BMC_CHANNEL;
+ recv->msg.netfn = IPMI_REPLY_ADDR(kreq->ir_addr) >> 2;
+ recv->msg.cmd = kreq->ir_command;
+ len = kreq->ir_replylen + 1;
+ }
+
if (recv->msg.data_len < len &&
(cmd == IPMICTL_RECEIVE_MSG
#ifdef IPMICTL_RECEIVE_MSG_32
- || cmd == IPMICTL_RECEIVE_MSG_32
+ || cmd == IPMICTL_RECEIVE_MSG_32
#endif
)) {
IPMI_UNLOCK(sc);
@@ -521,7 +490,7 @@
* Request management.
*/
-static __inline void
+__inline void
ipmi_init_request(struct ipmi_request *req, struct ipmi_device *dev, long msgid,
uint8_t addr, uint8_t command, size_t requestlen, size_t replylen)
{
diff --git a/sys/dev/ipmi/ipmivars.h b/sys/dev/ipmi/ipmivars.h
--- a/sys/dev/ipmi/ipmivars.h
+++ b/sys/dev/ipmi/ipmivars.h
@@ -54,6 +54,9 @@
uint8_t ir_addr;
uint8_t ir_command;
uint8_t ir_compcode;
+ bool ir_ipmb;
+ uint8_t ir_ipmb_addr;
+ uint8_t ir_ipmb_command;
};
#define MAX_RES 3
@@ -128,10 +131,6 @@
#define ipmi_ssif_smbus_address _iface.ssif.smbus_address
#define ipmi_ssif_smbus _iface.ssif.smbus
-struct ipmi_ipmb {
- u_char foo;
-};
-
#define KCS_MODE 0x01
#define SMIC_MODE 0x02
#define BT_MODE 0x03
@@ -230,6 +229,8 @@
void ipmi_release_resources(device_t);
/* Manage requests. */
+void ipmi_init_request(struct ipmi_request *, struct ipmi_device *, long,
+ uint8_t, uint8_t, size_t, size_t);
struct ipmi_request *ipmi_alloc_request(struct ipmi_device *, long, uint8_t,
uint8_t, size_t, size_t);
void ipmi_complete_request(struct ipmi_softc *, struct ipmi_request *);
@@ -251,10 +252,6 @@
int ipmi_smic_attach(struct ipmi_softc *);
int ipmi_ssif_attach(struct ipmi_softc *, device_t, int);
-#ifdef IPMB
-int ipmi_handle_attn(struct ipmi_softc *);
-#endif
-
extern int ipmi_attached;
#endif /* !__IPMIVARS_H__ */
diff --git a/sys/sys/ipmi.h b/sys/sys/ipmi.h
--- a/sys/sys/ipmi.h
+++ b/sys/sys/ipmi.h
@@ -33,9 +33,11 @@
#define IPMI_MAX_ADDR_SIZE 0x20
#define IPMI_MAX_RX 1024
-#define IPMI_BMC_SLAVE_ADDR 0x20 /* Linux Default slave address */
+
#define IPMI_BMC_CHANNEL 0x0f /* Linux BMC channel */
+#define IPMI_IPMB_CHANNEL 0x00
+#define IPMI_BMC_SLAVE_ADDR 0x20 /* Linux Default slave address */
#define IPMI_BMC_SMS_LUN 0x02
#define IPMI_SYSTEM_INTERFACE_ADDR_TYPE 0x0c

File Metadata

Mime Type
text/plain
Expires
Sat, May 3, 12:05 AM (13 h, 37 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
17915183
Default Alt Text
D35605.diff (8 KB)

Event Timeline