1989f2807SJerry Jelinek /* 2989f2807SJerry Jelinek * Copyright (c) 2006 IronPort Systems Inc. <ambrisko@ironport.com> 3989f2807SJerry Jelinek * All rights reserved. 4989f2807SJerry Jelinek * 5989f2807SJerry Jelinek * Redistribution and use in source and binary forms, with or without 6989f2807SJerry Jelinek * modification, are permitted provided that the following conditions 7989f2807SJerry Jelinek * are met: 8989f2807SJerry Jelinek * 1. Redistributions of source code must retain the above copyright 9989f2807SJerry Jelinek * notice, this list of conditions and the following disclaimer. 10989f2807SJerry Jelinek * 2. Redistributions in binary form must reproduce the above copyright 11989f2807SJerry Jelinek * notice, this list of conditions and the following disclaimer in the 12989f2807SJerry Jelinek * documentation and/or other materials provided with the distribution. 13989f2807SJerry Jelinek * 14989f2807SJerry Jelinek * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15989f2807SJerry Jelinek * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16989f2807SJerry Jelinek * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17989f2807SJerry Jelinek * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18989f2807SJerry Jelinek * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19989f2807SJerry Jelinek * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20989f2807SJerry Jelinek * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21989f2807SJerry Jelinek * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22989f2807SJerry Jelinek * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23989f2807SJerry Jelinek * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24989f2807SJerry Jelinek * SUCH DAMAGE. 25989f2807SJerry Jelinek * 26989f2807SJerry Jelinek * $FreeBSD: src/sys/dev/ipmi/ipmivars.h,v 1.3 2008/08/28 02:13:53 jhb Exp $ 27989f2807SJerry Jelinek */ 28989f2807SJerry Jelinek 29989f2807SJerry Jelinek /* 30989f2807SJerry Jelinek * Copyright 2012, Joyent, Inc. All rights reserved. 311e393477SMarcel Telka * Copyright 2013 Nexenta Systems, Inc. All rights reserved. 32989f2807SJerry Jelinek */ 33989f2807SJerry Jelinek 34989f2807SJerry Jelinek #ifndef _IPMIVARS_H_ 35989f2807SJerry Jelinek #define _IPMIVARS_H_ 36989f2807SJerry Jelinek 37989f2807SJerry Jelinek #include <sys/types.h> 38989f2807SJerry Jelinek #include <sys/queue.h> 39989f2807SJerry Jelinek 40989f2807SJerry Jelinek #ifdef __cplusplus 41989f2807SJerry Jelinek extern "C" { 42989f2807SJerry Jelinek #endif 43989f2807SJerry Jelinek 44989f2807SJerry Jelinek struct ipmi_device; 45989f2807SJerry Jelinek struct ipmi_request; 46989f2807SJerry Jelinek 471e393477SMarcel Telka typedef enum { 481e393477SMarcel Telka IRS_ALLOCATED, 491e393477SMarcel Telka IRS_QUEUED, 501e393477SMarcel Telka IRS_PROCESSED, 511e393477SMarcel Telka IRS_COMPLETED, 521e393477SMarcel Telka IRS_CANCELED 531e393477SMarcel Telka } ir_status_t; 541e393477SMarcel Telka 55989f2807SJerry Jelinek struct ipmi_request { 56989f2807SJerry Jelinek TAILQ_ENTRY(ipmi_request) ir_link; 57989f2807SJerry Jelinek struct ipmi_device *ir_owner; /* Driver uses NULL. */ 58989f2807SJerry Jelinek uchar_t *ir_request; /* Request is data to send to BMC. */ 59989f2807SJerry Jelinek size_t ir_requestlen; 60989f2807SJerry Jelinek uchar_t *ir_reply; /* Reply is data read from BMC. */ 61989f2807SJerry Jelinek size_t ir_replybuflen; /* Length of ir_reply[] buffer. */ 62989f2807SJerry Jelinek int ir_replylen; /* Length of reply from BMC. */ 63989f2807SJerry Jelinek int ir_error; 64989f2807SJerry Jelinek long ir_msgid; 65989f2807SJerry Jelinek uint8_t ir_addr; 66989f2807SJerry Jelinek uint8_t ir_command; 67989f2807SJerry Jelinek uint8_t ir_compcode; 68989f2807SJerry Jelinek int ir_sz; /* size of request */ 691e393477SMarcel Telka 701e393477SMarcel Telka kcondvar_t ir_cv; 711e393477SMarcel Telka ir_status_t ir_status; 72989f2807SJerry Jelinek }; 73989f2807SJerry Jelinek 74989f2807SJerry Jelinek #define MAX_RES 3 75989f2807SJerry Jelinek #define KCS_DATA 0 76989f2807SJerry Jelinek #define KCS_CTL_STS 1 77989f2807SJerry Jelinek #define SMIC_DATA 0 78989f2807SJerry Jelinek #define SMIC_CTL_STS 1 79989f2807SJerry Jelinek #define SMIC_FLAGS 2 80989f2807SJerry Jelinek 81*cc944374SMarcel Telka #define IPMI_BUSY 0x1 82*cc944374SMarcel Telka #define IPMI_CLOSING 0x2 83*cc944374SMarcel Telka 84989f2807SJerry Jelinek /* Per file descriptor data. */ 85989f2807SJerry Jelinek typedef struct ipmi_device { 86989f2807SJerry Jelinek TAILQ_HEAD(, ipmi_request) ipmi_completed_requests; 87989f2807SJerry Jelinek pollhead_t *ipmi_pollhead; 88989f2807SJerry Jelinek int ipmi_requests; 89989f2807SJerry Jelinek uchar_t ipmi_address; /* IPMB address. */ 90989f2807SJerry Jelinek uchar_t ipmi_lun; 91989f2807SJerry Jelinek dev_t ipmi_dev; 92989f2807SJerry Jelinek list_node_t ipmi_node; /* list link for open devs */ 93*cc944374SMarcel Telka int ipmi_status; 94*cc944374SMarcel Telka kcondvar_t ipmi_cv; 95989f2807SJerry Jelinek } ipmi_device_t; 96989f2807SJerry Jelinek 97989f2807SJerry Jelinek struct ipmi_softc { 98989f2807SJerry Jelinek int ipmi_io_rid; 99989f2807SJerry Jelinek int ipmi_io_type; 100989f2807SJerry Jelinek uint64_t ipmi_io_address; 101989f2807SJerry Jelinek int ipmi_io_mode; 102989f2807SJerry Jelinek int ipmi_io_spacing; 103989f2807SJerry Jelinek int ipmi_io_irq; 104989f2807SJerry Jelinek void *ipmi_irq; 105989f2807SJerry Jelinek int ipmi_detaching; 106989f2807SJerry Jelinek TAILQ_HEAD(, ipmi_request) ipmi_pending_requests; 107989f2807SJerry Jelinek kmutex_t ipmi_lock; 108989f2807SJerry Jelinek kcondvar_t ipmi_request_added; 109989f2807SJerry Jelinek taskq_t *ipmi_kthread; 110989f2807SJerry Jelinek int (*ipmi_startup)(struct ipmi_softc *); 111989f2807SJerry Jelinek int (*ipmi_enqueue_request)(struct ipmi_softc *, 112989f2807SJerry Jelinek struct ipmi_request *); 113989f2807SJerry Jelinek }; 114989f2807SJerry Jelinek 115989f2807SJerry Jelinek #define KCS_MODE 0x01 116989f2807SJerry Jelinek #define SMIC_MODE 0x02 117989f2807SJerry Jelinek #define BT_MODE 0x03 118989f2807SJerry Jelinek #define SSIF_MODE 0x04 119989f2807SJerry Jelinek 120989f2807SJerry Jelinek /* KCS status flags */ 121989f2807SJerry Jelinek #define KCS_STATUS_OBF 0x01 /* Data Out ready from BMC */ 122989f2807SJerry Jelinek #define KCS_STATUS_IBF 0x02 /* Data In from System */ 123989f2807SJerry Jelinek #define KCS_STATUS_SMS_ATN 0x04 /* Ready in RX queue */ 124989f2807SJerry Jelinek #define KCS_STATUS_C_D 0x08 /* Command/Data register write */ 125989f2807SJerry Jelinek #define KCS_STATUS_OEM1 0x10 126989f2807SJerry Jelinek #define KCS_STATUS_OEM2 0x20 127989f2807SJerry Jelinek #define KCS_STATUS_S0 0x40 128989f2807SJerry Jelinek #define KCS_STATUS_S1 0x80 129989f2807SJerry Jelinek #define KCS_STATUS_STATE(x) ((x)>>6) 130989f2807SJerry Jelinek #define KCS_STATUS_STATE_IDLE 0x0 131989f2807SJerry Jelinek #define KCS_STATUS_STATE_READ 0x1 132989f2807SJerry Jelinek #define KCS_STATUS_STATE_WRITE 0x2 133989f2807SJerry Jelinek #define KCS_STATUS_STATE_ERROR 0x3 134989f2807SJerry Jelinek #define KCS_IFACE_STATUS_OK 0x00 135989f2807SJerry Jelinek #define KCS_IFACE_STATUS_ABORT 0x01 136989f2807SJerry Jelinek #define KCS_IFACE_STATUS_ILLEGAL 0x02 137989f2807SJerry Jelinek #define KCS_IFACE_STATUS_LENGTH_ERR 0x06 138989f2807SJerry Jelinek #define KCS_IFACE_STATUS_UNKNOWN_ERR 0xff 139989f2807SJerry Jelinek 140989f2807SJerry Jelinek /* KCS control codes */ 141989f2807SJerry Jelinek #define KCS_CONTROL_GET_STATUS_ABORT 0x60 142989f2807SJerry Jelinek #define KCS_CONTROL_WRITE_START 0x61 143989f2807SJerry Jelinek #define KCS_CONTROL_WRITE_END 0x62 144989f2807SJerry Jelinek #define KCS_DATA_IN_READ 0x68 145989f2807SJerry Jelinek 146989f2807SJerry Jelinek /* SMIC status flags */ 147989f2807SJerry Jelinek #define SMIC_STATUS_BUSY 0x01 /* System set and BMC clears it */ 148989f2807SJerry Jelinek #define SMIC_STATUS_SMS_ATN 0x04 /* BMC has a message */ 149989f2807SJerry Jelinek #define SMIC_STATUS_EVT_ATN 0x08 /* Event has been RX */ 150989f2807SJerry Jelinek #define SMIC_STATUS_SMI 0x10 /* asserted SMI */ 151989f2807SJerry Jelinek #define SMIC_STATUS_TX_RDY 0x40 /* Ready to accept WRITE */ 152989f2807SJerry Jelinek #define SMIC_STATUS_RX_RDY 0x80 /* Ready to read */ 153989f2807SJerry Jelinek #define SMIC_STATUS_RESERVED 0x22 154989f2807SJerry Jelinek 155989f2807SJerry Jelinek /* SMIC control codes */ 156989f2807SJerry Jelinek #define SMIC_CC_SMS_GET_STATUS 0x40 157989f2807SJerry Jelinek #define SMIC_CC_SMS_WR_START 0x41 158989f2807SJerry Jelinek #define SMIC_CC_SMS_WR_NEXT 0x42 159989f2807SJerry Jelinek #define SMIC_CC_SMS_WR_END 0x43 160989f2807SJerry Jelinek #define SMIC_CC_SMS_RD_START 0x44 161989f2807SJerry Jelinek #define SMIC_CC_SMS_RD_NEXT 0x45 162989f2807SJerry Jelinek #define SMIC_CC_SMS_RD_END 0x46 163989f2807SJerry Jelinek 164989f2807SJerry Jelinek /* SMIC status codes */ 165989f2807SJerry Jelinek #define SMIC_SC_SMS_RDY 0xc0 166989f2807SJerry Jelinek #define SMIC_SC_SMS_WR_START 0xc1 167989f2807SJerry Jelinek #define SMIC_SC_SMS_WR_NEXT 0xc2 168989f2807SJerry Jelinek #define SMIC_SC_SMS_WR_END 0xc3 169989f2807SJerry Jelinek #define SMIC_SC_SMS_RD_START 0xc4 170989f2807SJerry Jelinek #define SMIC_SC_SMS_RD_NEXT 0xc5 171989f2807SJerry Jelinek #define SMIC_SC_SMS_RD_END 0xc6 172989f2807SJerry Jelinek 173989f2807SJerry Jelinek #define IPMI_ADDR(netfn, lun) ((netfn) << 2 | (lun)) 174989f2807SJerry Jelinek #define IPMI_REPLY_ADDR(addr) ((addr) + 0x4) 175989f2807SJerry Jelinek 176989f2807SJerry Jelinek #define IPMI_LOCK(sc) mutex_enter(&(sc)->ipmi_lock) 177989f2807SJerry Jelinek #define IPMI_UNLOCK(sc) mutex_exit(&(sc)->ipmi_lock) 178989f2807SJerry Jelinek #define IPMI_LOCK_ASSERT(sc) ASSERT(MUTEX_HELD(&(sc)->ipmi_lock)) 179989f2807SJerry Jelinek 180989f2807SJerry Jelinek #define ipmi_alloc_driver_request(addr, cmd, reqlen, replylen) \ 181989f2807SJerry Jelinek ipmi_alloc_request(NULL, 0, (addr), (cmd), (reqlen), (replylen)) 182989f2807SJerry Jelinek 183989f2807SJerry Jelinek #define INB(sc, x) \ 184989f2807SJerry Jelinek inb((sc)->ipmi_io_address + ((sc)->ipmi_io_spacing * (x))) 185989f2807SJerry Jelinek #define OUTB(sc, x, value) \ 186989f2807SJerry Jelinek outb((sc)->ipmi_io_address + ((sc)->ipmi_io_spacing * (x)), value) 187989f2807SJerry Jelinek 188989f2807SJerry Jelinek #define MAX_TIMEOUT (3 * hz) 189989f2807SJerry Jelinek 190989f2807SJerry Jelinek /* Manage requests. */ 191989f2807SJerry Jelinek void ipmi_complete_request(struct ipmi_softc *, struct ipmi_request *); 192989f2807SJerry Jelinek struct ipmi_request *ipmi_dequeue_request(struct ipmi_softc *); 193989f2807SJerry Jelinek int ipmi_polled_enqueue_request(struct ipmi_softc *, struct ipmi_request *); 194989f2807SJerry Jelinek struct ipmi_request *ipmi_alloc_request(struct ipmi_device *, long msgid, 195989f2807SJerry Jelinek uint8_t, uint8_t, size_t, size_t); 196989f2807SJerry Jelinek void ipmi_free_request(struct ipmi_request *); 197989f2807SJerry Jelinek 198989f2807SJerry Jelinek /* Interface attach routines. */ 199e1c99a74SAlek Pinchuk boolean_t ipmi_startup(struct ipmi_softc *sc); 200989f2807SJerry Jelinek int ipmi_kcs_attach(struct ipmi_softc *); 201989f2807SJerry Jelinek 202e1c99a74SAlek Pinchuk /* Interface detach cleanup */ 203e1c99a74SAlek Pinchuk void ipmi_shutdown(struct ipmi_softc *sc); 204e1c99a74SAlek Pinchuk 205989f2807SJerry Jelinek #ifdef __cplusplus 206989f2807SJerry Jelinek } 207989f2807SJerry Jelinek #endif 208989f2807SJerry Jelinek 209989f2807SJerry Jelinek #endif /* _IPMIVARS_H_ */ 210