Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F116043101
D35605.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
8 KB
Referenced Files
None
Subscribers
None
D35605.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D35605: ipmi: handle ipmb requests
Attached
Detach File
Event Timeline
Log In to Comment