diff options
Diffstat (limited to 'sys/dev/ipmi/ipmivars.h')
-rw-r--r-- | sys/dev/ipmi/ipmivars.h | 210 |
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__ */ |