summaryrefslogtreecommitdiffstats
path: root/sys/dev/ipmi/ipmivars.h
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/ipmi/ipmivars.h')
-rw-r--r--sys/dev/ipmi/ipmivars.h210
1 files changed, 169 insertions, 41 deletions
diff --git a/sys/dev/ipmi/ipmivars.h b/sys/dev/ipmi/ipmivars.h
index c793eab..c56fb88 100644
--- a/sys/dev/ipmi/ipmivars.h
+++ b/sys/dev/ipmi/ipmivars.h
@@ -26,50 +26,116 @@
* $FreeBSD$
*/
+#ifndef __IPMIVARS_H__
+#define __IPMIVARS_H__
+
struct ipmi_get_info {
- int kcs_mode;
- int smic_mode;
+ int iface_type;
uint64_t address;
int offset;
int io_mode;
+ int irq;
+};
+
+struct ipmi_device;
+
+struct ipmi_request {
+ TAILQ_ENTRY(ipmi_request) ir_link;
+ struct ipmi_device *ir_owner; /* Driver uses NULL. */
+ u_char *ir_request; /* Request is data to send to BMC. */
+ size_t ir_requestlen;
+ u_char *ir_reply; /* Reply is data read from BMC. */
+ size_t ir_replybuflen; /* Length of ir_reply[] buffer. */
+ int ir_replylen; /* Length of reply from BMC. */
+ int ir_error;
+ long ir_msgid;
+ uint8_t ir_addr;
+ uint8_t ir_command;
+ uint8_t ir_compcode;
+};
+
+#define MAX_RES 3
+#define KCS_DATA 0
+#define KCS_CTL_STS 1
+#define SMIC_DATA 0
+#define SMIC_CTL_STS 1
+#define SMIC_FLAGS 2
+
+struct ipmi_softc;
+
+/* Per struct cdev data. */
+struct ipmi_device {
+ TAILQ_ENTRY(ipmi_device) ipmi_link;
+ TAILQ_HEAD(,ipmi_request) ipmi_completed_requests;
+ struct selinfo ipmi_select;
+ struct ipmi_softc *ipmi_softc;
+ struct cdev *ipmi_cdev;
+ int ipmi_open;
+ int ipmi_closing;
+ int ipmi_requests;
+ u_char ipmi_address; /* IPMB address. */
+ u_char ipmi_lun;
+};
+
+struct ipmi_kcs {
+};
+
+struct ipmi_smic {
+};
+
+struct ipmi_ssif {
+ device_t smbus;
+ int smbus_address;
};
struct ipmi_softc {
device_t ipmi_dev;
- device_t ipmi_smbios_dev;
- struct cdev *ipmi_dev_t;
- int ipmi_refcnt;
- struct smbios_table_entry *ipmi_smbios;
- struct ipmi_get_info ipmi_bios_info;
- int ipmi_kcs_status_reg;
- int ipmi_kcs_command_reg;
- int ipmi_kcs_data_out_reg;
- int ipmi_kcs_data_in_reg;
- int ipmi_smic_data;
- int ipmi_smic_ctl_sts;
- int ipmi_smic_flags;
+ union {
+ struct ipmi_kcs kcs;
+ struct ipmi_smic smic;
+ struct ipmi_ssif ssif;
+ } _iface;
int ipmi_io_rid;
- struct resource * ipmi_io_res;
- int ipmi_mem_rid;
- struct resource * ipmi_mem_res;
+ int ipmi_io_type;
+ struct resource *ipmi_io_res[MAX_RES];
+ int ipmi_io_spacing;
int ipmi_irq_rid;
- struct resource * ipmi_irq_res;
+ struct resource *ipmi_irq_res;
void *ipmi_irq;
- u_char ipmi_address;
- u_char ipmi_lun;
- int ipmi_busy;
- struct selinfo ipmi_select;
- int ipmi_timestamp;
- int ipmi_requests;
- struct callout_handle ipmi_timeout_handle;
- TAILQ_HEAD(,ipmi_done_list) ipmi_done;
- eventhandler_tag ipmi_ev_tag;
+ int ipmi_detaching;
+#ifdef CLONING
+ int ipmi_cloning;
+ u_int ipmi_cdev_mask;
+ TAILQ_HEAD(,ipmi_device) ipmi_cdevs;
+#else
+ struct ipmi_device ipmi_idev;
+#endif
+ TAILQ_HEAD(,ipmi_request) ipmi_pending_requests;
+#ifdef CLONING
+ eventhandler_tag ipmi_clone_tag;
+#endif
+ eventhandler_tag ipmi_watchdog_tag;
+ struct intr_config_hook ipmi_ich;
+ struct mtx ipmi_lock;
+ struct cv ipmi_request_added;
+ struct proc *ipmi_kthread;
+ driver_intr_t *ipmi_intr;
+ int (*ipmi_startup)(struct ipmi_softc *);
+ int (*ipmi_enqueue_request)(struct ipmi_softc *, struct ipmi_request *);
};
+#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
+#define SSIF_MODE 0x04
+
/* KCS status flags */
#define KCS_STATUS_OBF 0x01 /* Data Out ready from BMC */
#define KCS_STATUS_IBF 0x02 /* Data In from System */
@@ -84,11 +150,13 @@ struct ipmi_ipmb {
#define KCS_STATUS_STATE_READ 0x1
#define KCS_STATUS_STATE_WRITE 0x2
#define KCS_STATUS_STATE_ERROR 0x3
+#define KCS_IFACE_STATUS_OK 0x00
#define KCS_IFACE_STATUS_ABORT 0x01
#define KCS_IFACE_STATUS_ILLEGAL 0x02
#define KCS_IFACE_STATUS_LENGTH_ERR 0x06
+#define KCS_IFACE_STATUS_UNKNOWN_ERR 0xff
-/* KCD control codes */
+/* KCS control codes */
#define KCS_CONTROL_GET_STATUS_ABORT 0x60
#define KCS_CONTROL_WRITE_START 0x61
#define KCS_CONTROL_WRITE_END 0x62
@@ -98,9 +166,10 @@ struct ipmi_ipmb {
#define SMIC_STATUS_BUSY 0x01 /* System set and BMC clears it */
#define SMIC_STATUS_SMS_ATN 0x04 /* BMC has a message */
#define SMIC_STATUS_EVT_ATN 0x08 /* Event has been RX */
-#define SMIC_STATUS_SMI 0x08 /* asserted SMI */
+#define SMIC_STATUS_SMI 0x10 /* asserted SMI */
#define SMIC_STATUS_TX_RDY 0x40 /* Ready to accept WRITE */
#define SMIC_STATUS_RX_RDY 0x80 /* Ready to read */
+#define SMIC_STATUS_RESERVED 0x22
/* SMIC control codes */
#define SMIC_CC_SMS_GET_STATUS 0x40
@@ -120,19 +189,78 @@ struct ipmi_ipmb {
#define SMIC_SC_SMS_RD_NEXT 0xc5
#define SMIC_SC_SMS_RD_END 0xc6
-#define RES(x) (x)->ipmi_io_res ? (x)->ipmi_io_res : (x)->ipmi_mem_res
-#define INB(sc, x) bus_space_read_1(rman_get_bustag(RES(sc)), \
- rman_get_bushandle(RES(sc)), (x))
-#define OUTB(sc, x, value) bus_space_write_1(rman_get_bustag(RES(sc)), \
- rman_get_bushandle(RES(sc)), (x), value)
+#define IPMI_ADDR(netfn, lun) ((netfn) << 2 | (lun))
+#define IPMI_REPLY_ADDR(addr) ((addr) + 0x4)
+
+#define IPMI_LOCK(sc) mtx_lock(&(sc)->ipmi_lock)
+#define IPMI_UNLOCK(sc) mtx_unlock(&(sc)->ipmi_lock)
+#define IPMI_LOCK_ASSERT(sc) mtx_assert(&(sc)->ipmi_lock, MA_OWNED)
+
+#define ipmi_alloc_driver_request(addr, cmd, reqlen, replylen) \
+ ipmi_alloc_request(NULL, 0, (addr), (cmd), (reqlen), (replylen))
-int ipmi_attach(device_t);
-int ipmi_detach(device_t);
-int ipmi_smbios_query(device_t);
-int ipmi_smbios_probe(device_t);
-int ipmi_read(device_t, u_char *, int);
-void ipmi_intr(void *);
+#if __FreeBSD_version < 601105
+#define bus_read_1(r, o) \
+ bus_space_read_1(rman_get_bustag(r), rman_get_bushandle(r), (o))
+#define bus_write_1(r, o, v) \
+ bus_space_write_1(rman_get_bustag(r), rman_get_bushandle(r), (o), (v))
+#endif
+
+/* I/O to a single I/O resource. */
+#define INB_SINGLE(sc, x) \
+ bus_read_1((sc)->ipmi_io_res[0], (sc)->ipmi_io_spacing * (x))
+#define OUTB_SINGLE(sc, x, value) \
+ bus_write_1((sc)->ipmi_io_res[0], (sc)->ipmi_io_spacing * (x), value)
+
+/* I/O with each register in its in I/O resource. */
+#define INB_MULTIPLE(sc, x) \
+ bus_read_1((sc)->ipmi_io_res[(x)], 0)
+#define OUTB_MULTIPLE(sc, x, value) \
+ bus_write_1((sc)->ipmi_io_res[(x)], 0, value)
+
+/*
+ * Determine I/O method based on whether or not we have more than one I/O
+ * resource.
+ */
+#define INB(sc, x) \
+ ((sc)->ipmi_io_res[1] != NULL ? INB_MULTIPLE(sc, x) : INB_SINGLE(sc, x))
+#define OUTB(sc, x, value) \
+ ((sc)->ipmi_io_res[1] != NULL ? OUTB_MULTIPLE(sc, x, value) : \
+ OUTB_SINGLE(sc, x, value))
+
+#define MAX_TIMEOUT 3 * hz
+
+int ipmi_attach(device_t);
+int ipmi_detach(device_t);
+void ipmi_release_resources(device_t);
+
+/* Manage requests. */
+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 *);
+struct ipmi_request *ipmi_dequeue_request(struct ipmi_softc *);
+void ipmi_free_request(struct ipmi_request *);
+int ipmi_polled_enqueue_request(struct ipmi_softc *, struct ipmi_request *);
+int ipmi_submit_driver_request(struct ipmi_softc *, struct ipmi_request *,
+ int);
+
+/* Identify BMC interface via SMBIOS. */
+int ipmi_smbios_identify(struct ipmi_get_info *);
+
+/* Match BMC PCI device listed in SMBIOS. */
+const char *ipmi_pci_match(uint16_t, uint16_t);
+
+/* Interface attach routines. */
+int ipmi_kcs_attach(struct ipmi_softc *);
+int ipmi_kcs_probe_align(struct ipmi_softc *);
+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
-device_t ipmi_smbios_identify (driver_t *driver, device_t parent);
extern devclass_t ipmi_devclass;
extern int ipmi_attached;
+
+#endif /* !__IPMIVARS_H__ */
OpenPOWER on IntegriCloud