125930707SCorey Minyard /* 225930707SCorey Minyard * ipmi_ssif.c 325930707SCorey Minyard * 425930707SCorey Minyard * The interface to the IPMI driver for SMBus access to a SMBus 525930707SCorey Minyard * compliant device. Called SSIF by the IPMI spec. 625930707SCorey Minyard * 725930707SCorey Minyard * Author: Intel Corporation 825930707SCorey Minyard * Todd Davis <todd.c.davis@intel.com> 925930707SCorey Minyard * 1025930707SCorey Minyard * Rewritten by Corey Minyard <minyard@acm.org> to support the 1125930707SCorey Minyard * non-blocking I2C interface, add support for multi-part 1225930707SCorey Minyard * transactions, add PEC support, and general clenaup. 1325930707SCorey Minyard * 1425930707SCorey Minyard * Copyright 2003 Intel Corporation 1525930707SCorey Minyard * Copyright 2005 MontaVista Software 1625930707SCorey Minyard * 1725930707SCorey Minyard * This program is free software; you can redistribute it and/or modify it 1825930707SCorey Minyard * under the terms of the GNU General Public License as published by the 1925930707SCorey Minyard * Free Software Foundation; either version 2 of the License, or (at your 2025930707SCorey Minyard * option) any later version. 2125930707SCorey Minyard */ 2225930707SCorey Minyard 2325930707SCorey Minyard /* 2425930707SCorey Minyard * This file holds the "policy" for the interface to the SSIF state 2525930707SCorey Minyard * machine. It does the configuration, handles timers and interrupts, 2625930707SCorey Minyard * and drives the real SSIF state machine. 2725930707SCorey Minyard */ 2825930707SCorey Minyard 2925930707SCorey Minyard /* 3025930707SCorey Minyard * TODO: Figure out how to use SMB alerts. This will require a new 3125930707SCorey Minyard * interface into the I2C driver, I believe. 3225930707SCorey Minyard */ 3325930707SCorey Minyard 3425930707SCorey Minyard #if defined(MODVERSIONS) 3525930707SCorey Minyard #include <linux/modversions.h> 3625930707SCorey Minyard #endif 3725930707SCorey Minyard 3825930707SCorey Minyard #include <linux/module.h> 3925930707SCorey Minyard #include <linux/moduleparam.h> 4025930707SCorey Minyard #include <linux/sched.h> 4125930707SCorey Minyard #include <linux/seq_file.h> 4225930707SCorey Minyard #include <linux/timer.h> 4325930707SCorey Minyard #include <linux/delay.h> 4425930707SCorey Minyard #include <linux/errno.h> 4525930707SCorey Minyard #include <linux/spinlock.h> 4625930707SCorey Minyard #include <linux/slab.h> 4725930707SCorey Minyard #include <linux/list.h> 4825930707SCorey Minyard #include <linux/i2c.h> 4925930707SCorey Minyard #include <linux/ipmi_smi.h> 5025930707SCorey Minyard #include <linux/init.h> 5125930707SCorey Minyard #include <linux/dmi.h> 5225930707SCorey Minyard #include <linux/kthread.h> 5325930707SCorey Minyard #include <linux/acpi.h> 54e3fe1427SCorey Minyard #include <linux/ctype.h> 55526290aaSAmitoj Kaur Chawla #include <linux/time64.h> 5625930707SCorey Minyard 5725930707SCorey Minyard #define PFX "ipmi_ssif: " 5825930707SCorey Minyard #define DEVICE_NAME "ipmi_ssif" 5925930707SCorey Minyard 6025930707SCorey Minyard #define IPMI_GET_SYSTEM_INTERFACE_CAPABILITIES_CMD 0x57 6125930707SCorey Minyard 6225930707SCorey Minyard #define SSIF_IPMI_REQUEST 2 6325930707SCorey Minyard #define SSIF_IPMI_MULTI_PART_REQUEST_START 6 6425930707SCorey Minyard #define SSIF_IPMI_MULTI_PART_REQUEST_MIDDLE 7 6525930707SCorey Minyard #define SSIF_IPMI_RESPONSE 3 6625930707SCorey Minyard #define SSIF_IPMI_MULTI_PART_RESPONSE_MIDDLE 9 6725930707SCorey Minyard 6825930707SCorey Minyard /* ssif_debug is a bit-field 6925930707SCorey Minyard * SSIF_DEBUG_MSG - commands and their responses 7025930707SCorey Minyard * SSIF_DEBUG_STATES - message states 7125930707SCorey Minyard * SSIF_DEBUG_TIMING - Measure times between events in the driver 7225930707SCorey Minyard */ 7325930707SCorey Minyard #define SSIF_DEBUG_TIMING 4 7425930707SCorey Minyard #define SSIF_DEBUG_STATE 2 7525930707SCorey Minyard #define SSIF_DEBUG_MSG 1 7625930707SCorey Minyard #define SSIF_NODEBUG 0 7725930707SCorey Minyard #define SSIF_DEFAULT_DEBUG (SSIF_NODEBUG) 7825930707SCorey Minyard 7925930707SCorey Minyard /* 8025930707SCorey Minyard * Timer values 8125930707SCorey Minyard */ 8225930707SCorey Minyard #define SSIF_MSG_USEC 20000 /* 20ms between message tries. */ 8325930707SCorey Minyard #define SSIF_MSG_PART_USEC 5000 /* 5ms for a message part */ 8425930707SCorey Minyard 8525930707SCorey Minyard /* How many times to we retry sending/receiving the message. */ 8625930707SCorey Minyard #define SSIF_SEND_RETRIES 5 8725930707SCorey Minyard #define SSIF_RECV_RETRIES 250 8825930707SCorey Minyard 8925930707SCorey Minyard #define SSIF_MSG_MSEC (SSIF_MSG_USEC / 1000) 9025930707SCorey Minyard #define SSIF_MSG_JIFFIES ((SSIF_MSG_USEC * 1000) / TICK_NSEC) 9125930707SCorey Minyard #define SSIF_MSG_PART_JIFFIES ((SSIF_MSG_PART_USEC * 1000) / TICK_NSEC) 9225930707SCorey Minyard 9325930707SCorey Minyard enum ssif_intf_state { 9425930707SCorey Minyard SSIF_NORMAL, 9525930707SCorey Minyard SSIF_GETTING_FLAGS, 9625930707SCorey Minyard SSIF_GETTING_EVENTS, 9725930707SCorey Minyard SSIF_CLEARING_FLAGS, 9825930707SCorey Minyard SSIF_GETTING_MESSAGES, 9925930707SCorey Minyard /* FIXME - add watchdog stuff. */ 10025930707SCorey Minyard }; 10125930707SCorey Minyard 10225930707SCorey Minyard #define SSIF_IDLE(ssif) ((ssif)->ssif_state == SSIF_NORMAL \ 10325930707SCorey Minyard && (ssif)->curr_msg == NULL) 10425930707SCorey Minyard 10525930707SCorey Minyard /* 10625930707SCorey Minyard * Indexes into stats[] in ssif_info below. 10725930707SCorey Minyard */ 10825930707SCorey Minyard enum ssif_stat_indexes { 10925930707SCorey Minyard /* Number of total messages sent. */ 11025930707SCorey Minyard SSIF_STAT_sent_messages = 0, 11125930707SCorey Minyard 11225930707SCorey Minyard /* 11325930707SCorey Minyard * Number of message parts sent. Messages may be broken into 11425930707SCorey Minyard * parts if they are long. 11525930707SCorey Minyard */ 11625930707SCorey Minyard SSIF_STAT_sent_messages_parts, 11725930707SCorey Minyard 11825930707SCorey Minyard /* 11925930707SCorey Minyard * Number of time a message was retried. 12025930707SCorey Minyard */ 12125930707SCorey Minyard SSIF_STAT_send_retries, 12225930707SCorey Minyard 12325930707SCorey Minyard /* 12425930707SCorey Minyard * Number of times the send of a message failed. 12525930707SCorey Minyard */ 12625930707SCorey Minyard SSIF_STAT_send_errors, 12725930707SCorey Minyard 12825930707SCorey Minyard /* 12925930707SCorey Minyard * Number of message responses received. 13025930707SCorey Minyard */ 13125930707SCorey Minyard SSIF_STAT_received_messages, 13225930707SCorey Minyard 13325930707SCorey Minyard /* 13425930707SCorey Minyard * Number of message fragments received. 13525930707SCorey Minyard */ 13625930707SCorey Minyard SSIF_STAT_received_message_parts, 13725930707SCorey Minyard 13825930707SCorey Minyard /* 13925930707SCorey Minyard * Number of times the receive of a message was retried. 14025930707SCorey Minyard */ 14125930707SCorey Minyard SSIF_STAT_receive_retries, 14225930707SCorey Minyard 14325930707SCorey Minyard /* 14425930707SCorey Minyard * Number of errors receiving messages. 14525930707SCorey Minyard */ 14625930707SCorey Minyard SSIF_STAT_receive_errors, 14725930707SCorey Minyard 14825930707SCorey Minyard /* 14925930707SCorey Minyard * Number of times a flag fetch was requested. 15025930707SCorey Minyard */ 15125930707SCorey Minyard SSIF_STAT_flag_fetches, 15225930707SCorey Minyard 15325930707SCorey Minyard /* 15425930707SCorey Minyard * Number of times the hardware didn't follow the state machine. 15525930707SCorey Minyard */ 15625930707SCorey Minyard SSIF_STAT_hosed, 15725930707SCorey Minyard 15825930707SCorey Minyard /* 15925930707SCorey Minyard * Number of received events. 16025930707SCorey Minyard */ 16125930707SCorey Minyard SSIF_STAT_events, 16225930707SCorey Minyard 16325930707SCorey Minyard /* Number of asyncronous messages received. */ 16425930707SCorey Minyard SSIF_STAT_incoming_messages, 16525930707SCorey Minyard 16625930707SCorey Minyard /* Number of watchdog pretimeouts. */ 16725930707SCorey Minyard SSIF_STAT_watchdog_pretimeouts, 16825930707SCorey Minyard 16991620521SCorey Minyard /* Number of alers received. */ 17091620521SCorey Minyard SSIF_STAT_alerts, 17191620521SCorey Minyard 17225930707SCorey Minyard /* Always add statistics before this value, it must be last. */ 17325930707SCorey Minyard SSIF_NUM_STATS 17425930707SCorey Minyard }; 17525930707SCorey Minyard 17625930707SCorey Minyard struct ssif_addr_info { 17725930707SCorey Minyard struct i2c_board_info binfo; 17825930707SCorey Minyard char *adapter_name; 17925930707SCorey Minyard int debug; 18025930707SCorey Minyard int slave_addr; 18125930707SCorey Minyard enum ipmi_addr_src addr_src; 18225930707SCorey Minyard union ipmi_smi_info_union addr_info; 18325930707SCorey Minyard 18425930707SCorey Minyard struct mutex clients_mutex; 18525930707SCorey Minyard struct list_head clients; 18625930707SCorey Minyard 18725930707SCorey Minyard struct list_head link; 18825930707SCorey Minyard }; 18925930707SCorey Minyard 19025930707SCorey Minyard struct ssif_info; 19125930707SCorey Minyard 19225930707SCorey Minyard typedef void (*ssif_i2c_done)(struct ssif_info *ssif_info, int result, 19325930707SCorey Minyard unsigned char *data, unsigned int len); 19425930707SCorey Minyard 19525930707SCorey Minyard struct ssif_info { 19625930707SCorey Minyard ipmi_smi_t intf; 19725930707SCorey Minyard int intf_num; 19825930707SCorey Minyard spinlock_t lock; 19925930707SCorey Minyard struct ipmi_smi_msg *waiting_msg; 20025930707SCorey Minyard struct ipmi_smi_msg *curr_msg; 20125930707SCorey Minyard enum ssif_intf_state ssif_state; 20225930707SCorey Minyard unsigned long ssif_debug; 20325930707SCorey Minyard 20425930707SCorey Minyard struct ipmi_smi_handlers handlers; 20525930707SCorey Minyard 20625930707SCorey Minyard enum ipmi_addr_src addr_source; /* ACPI, PCI, SMBIOS, hardcode, etc. */ 20725930707SCorey Minyard union ipmi_smi_info_union addr_info; 20825930707SCorey Minyard 20925930707SCorey Minyard /* 21025930707SCorey Minyard * Flags from the last GET_MSG_FLAGS command, used when an ATTN 21125930707SCorey Minyard * is set to hold the flags until we are done handling everything 21225930707SCorey Minyard * from the flags. 21325930707SCorey Minyard */ 21425930707SCorey Minyard #define RECEIVE_MSG_AVAIL 0x01 21525930707SCorey Minyard #define EVENT_MSG_BUFFER_FULL 0x02 21625930707SCorey Minyard #define WDT_PRE_TIMEOUT_INT 0x08 21725930707SCorey Minyard unsigned char msg_flags; 21825930707SCorey Minyard 21991620521SCorey Minyard u8 global_enables; 22025930707SCorey Minyard bool has_event_buffer; 22191620521SCorey Minyard bool supports_alert; 22291620521SCorey Minyard 22391620521SCorey Minyard /* 22491620521SCorey Minyard * Used to tell what we should do with alerts. If we are 22591620521SCorey Minyard * waiting on a response, read the data immediately. 22691620521SCorey Minyard */ 22791620521SCorey Minyard bool got_alert; 22891620521SCorey Minyard bool waiting_alert; 22925930707SCorey Minyard 23025930707SCorey Minyard /* 23125930707SCorey Minyard * If set to true, this will request events the next time the 23225930707SCorey Minyard * state machine is idle. 23325930707SCorey Minyard */ 23425930707SCorey Minyard bool req_events; 23525930707SCorey Minyard 23625930707SCorey Minyard /* 23725930707SCorey Minyard * If set to true, this will request flags the next time the 23825930707SCorey Minyard * state machine is idle. 23925930707SCorey Minyard */ 24025930707SCorey Minyard bool req_flags; 24125930707SCorey Minyard 24225930707SCorey Minyard /* 24325930707SCorey Minyard * Used to perform timer operations when run-to-completion 24425930707SCorey Minyard * mode is on. This is a countdown timer. 24525930707SCorey Minyard */ 24625930707SCorey Minyard int rtc_us_timer; 24725930707SCorey Minyard 24825930707SCorey Minyard /* Used for sending/receiving data. +1 for the length. */ 24925930707SCorey Minyard unsigned char data[IPMI_MAX_MSG_LENGTH + 1]; 25025930707SCorey Minyard unsigned int data_len; 25125930707SCorey Minyard 25225930707SCorey Minyard /* Temp receive buffer, gets copied into data. */ 25325930707SCorey Minyard unsigned char recv[I2C_SMBUS_BLOCK_MAX]; 25425930707SCorey Minyard 25525930707SCorey Minyard struct i2c_client *client; 25625930707SCorey Minyard ssif_i2c_done done_handler; 25725930707SCorey Minyard 25825930707SCorey Minyard /* Thread interface handling */ 25925930707SCorey Minyard struct task_struct *thread; 26025930707SCorey Minyard struct completion wake_thread; 26125930707SCorey Minyard bool stopping; 26225930707SCorey Minyard int i2c_read_write; 26325930707SCorey Minyard int i2c_command; 26425930707SCorey Minyard unsigned char *i2c_data; 26525930707SCorey Minyard unsigned int i2c_size; 26625930707SCorey Minyard 26725930707SCorey Minyard /* From the device id response. */ 26825930707SCorey Minyard struct ipmi_device_id device_id; 26925930707SCorey Minyard 27025930707SCorey Minyard struct timer_list retry_timer; 27125930707SCorey Minyard int retries_left; 27225930707SCorey Minyard 27325930707SCorey Minyard /* Info from SSIF cmd */ 27425930707SCorey Minyard unsigned char max_xmit_msg_size; 27525930707SCorey Minyard unsigned char max_recv_msg_size; 27625930707SCorey Minyard unsigned int multi_support; 27725930707SCorey Minyard int supports_pec; 27825930707SCorey Minyard 27925930707SCorey Minyard #define SSIF_NO_MULTI 0 28025930707SCorey Minyard #define SSIF_MULTI_2_PART 1 28125930707SCorey Minyard #define SSIF_MULTI_n_PART 2 28225930707SCorey Minyard unsigned char *multi_data; 28325930707SCorey Minyard unsigned int multi_len; 28425930707SCorey Minyard unsigned int multi_pos; 28525930707SCorey Minyard 28625930707SCorey Minyard atomic_t stats[SSIF_NUM_STATS]; 28725930707SCorey Minyard }; 28825930707SCorey Minyard 28925930707SCorey Minyard #define ssif_inc_stat(ssif, stat) \ 29025930707SCorey Minyard atomic_inc(&(ssif)->stats[SSIF_STAT_ ## stat]) 29125930707SCorey Minyard #define ssif_get_stat(ssif, stat) \ 29225930707SCorey Minyard ((unsigned int) atomic_read(&(ssif)->stats[SSIF_STAT_ ## stat])) 29325930707SCorey Minyard 29425930707SCorey Minyard static bool initialized; 29525930707SCorey Minyard 29625930707SCorey Minyard static atomic_t next_intf = ATOMIC_INIT(0); 29725930707SCorey Minyard 29825930707SCorey Minyard static void return_hosed_msg(struct ssif_info *ssif_info, 29925930707SCorey Minyard struct ipmi_smi_msg *msg); 30025930707SCorey Minyard static void start_next_msg(struct ssif_info *ssif_info, unsigned long *flags); 30125930707SCorey Minyard static int start_send(struct ssif_info *ssif_info, 30225930707SCorey Minyard unsigned char *data, 30325930707SCorey Minyard unsigned int len); 30425930707SCorey Minyard 30525930707SCorey Minyard static unsigned long *ipmi_ssif_lock_cond(struct ssif_info *ssif_info, 30625930707SCorey Minyard unsigned long *flags) 30725930707SCorey Minyard { 30825930707SCorey Minyard spin_lock_irqsave(&ssif_info->lock, *flags); 30925930707SCorey Minyard return flags; 31025930707SCorey Minyard } 31125930707SCorey Minyard 31225930707SCorey Minyard static void ipmi_ssif_unlock_cond(struct ssif_info *ssif_info, 31325930707SCorey Minyard unsigned long *flags) 31425930707SCorey Minyard { 31525930707SCorey Minyard spin_unlock_irqrestore(&ssif_info->lock, *flags); 31625930707SCorey Minyard } 31725930707SCorey Minyard 31825930707SCorey Minyard static void deliver_recv_msg(struct ssif_info *ssif_info, 31925930707SCorey Minyard struct ipmi_smi_msg *msg) 32025930707SCorey Minyard { 32125930707SCorey Minyard ipmi_smi_t intf = ssif_info->intf; 32225930707SCorey Minyard 32325930707SCorey Minyard if (!intf) { 32425930707SCorey Minyard ipmi_free_smi_msg(msg); 32525930707SCorey Minyard } else if (msg->rsp_size < 0) { 32625930707SCorey Minyard return_hosed_msg(ssif_info, msg); 32725930707SCorey Minyard pr_err(PFX 32825930707SCorey Minyard "Malformed message in deliver_recv_msg: rsp_size = %d\n", 32925930707SCorey Minyard msg->rsp_size); 33025930707SCorey Minyard } else { 33125930707SCorey Minyard ipmi_smi_msg_received(intf, msg); 33225930707SCorey Minyard } 33325930707SCorey Minyard } 33425930707SCorey Minyard 33525930707SCorey Minyard static void return_hosed_msg(struct ssif_info *ssif_info, 33625930707SCorey Minyard struct ipmi_smi_msg *msg) 33725930707SCorey Minyard { 33825930707SCorey Minyard ssif_inc_stat(ssif_info, hosed); 33925930707SCorey Minyard 34025930707SCorey Minyard /* Make it a response */ 34125930707SCorey Minyard msg->rsp[0] = msg->data[0] | 4; 34225930707SCorey Minyard msg->rsp[1] = msg->data[1]; 34325930707SCorey Minyard msg->rsp[2] = 0xFF; /* Unknown error. */ 34425930707SCorey Minyard msg->rsp_size = 3; 34525930707SCorey Minyard 34625930707SCorey Minyard deliver_recv_msg(ssif_info, msg); 34725930707SCorey Minyard } 34825930707SCorey Minyard 34925930707SCorey Minyard /* 35025930707SCorey Minyard * Must be called with the message lock held. This will release the 35125930707SCorey Minyard * message lock. Note that the caller will check SSIF_IDLE and start a 35225930707SCorey Minyard * new operation, so there is no need to check for new messages to 35325930707SCorey Minyard * start in here. 35425930707SCorey Minyard */ 35525930707SCorey Minyard static void start_clear_flags(struct ssif_info *ssif_info, unsigned long *flags) 35625930707SCorey Minyard { 35725930707SCorey Minyard unsigned char msg[3]; 35825930707SCorey Minyard 35925930707SCorey Minyard ssif_info->msg_flags &= ~WDT_PRE_TIMEOUT_INT; 36025930707SCorey Minyard ssif_info->ssif_state = SSIF_CLEARING_FLAGS; 36125930707SCorey Minyard ipmi_ssif_unlock_cond(ssif_info, flags); 36225930707SCorey Minyard 36325930707SCorey Minyard /* Make sure the watchdog pre-timeout flag is not set at startup. */ 36425930707SCorey Minyard msg[0] = (IPMI_NETFN_APP_REQUEST << 2); 36525930707SCorey Minyard msg[1] = IPMI_CLEAR_MSG_FLAGS_CMD; 36625930707SCorey Minyard msg[2] = WDT_PRE_TIMEOUT_INT; 36725930707SCorey Minyard 36825930707SCorey Minyard if (start_send(ssif_info, msg, 3) != 0) { 36925930707SCorey Minyard /* Error, just go to normal state. */ 37025930707SCorey Minyard ssif_info->ssif_state = SSIF_NORMAL; 37125930707SCorey Minyard } 37225930707SCorey Minyard } 37325930707SCorey Minyard 37425930707SCorey Minyard static void start_flag_fetch(struct ssif_info *ssif_info, unsigned long *flags) 37525930707SCorey Minyard { 37625930707SCorey Minyard unsigned char mb[2]; 37725930707SCorey Minyard 37825930707SCorey Minyard ssif_info->req_flags = false; 37925930707SCorey Minyard ssif_info->ssif_state = SSIF_GETTING_FLAGS; 38025930707SCorey Minyard ipmi_ssif_unlock_cond(ssif_info, flags); 38125930707SCorey Minyard 38225930707SCorey Minyard mb[0] = (IPMI_NETFN_APP_REQUEST << 2); 38325930707SCorey Minyard mb[1] = IPMI_GET_MSG_FLAGS_CMD; 38425930707SCorey Minyard if (start_send(ssif_info, mb, 2) != 0) 38525930707SCorey Minyard ssif_info->ssif_state = SSIF_NORMAL; 38625930707SCorey Minyard } 38725930707SCorey Minyard 38825930707SCorey Minyard static void check_start_send(struct ssif_info *ssif_info, unsigned long *flags, 38925930707SCorey Minyard struct ipmi_smi_msg *msg) 39025930707SCorey Minyard { 39125930707SCorey Minyard if (start_send(ssif_info, msg->data, msg->data_size) != 0) { 39225930707SCorey Minyard unsigned long oflags; 39325930707SCorey Minyard 39425930707SCorey Minyard flags = ipmi_ssif_lock_cond(ssif_info, &oflags); 39525930707SCorey Minyard ssif_info->curr_msg = NULL; 39625930707SCorey Minyard ssif_info->ssif_state = SSIF_NORMAL; 39725930707SCorey Minyard ipmi_ssif_unlock_cond(ssif_info, flags); 39825930707SCorey Minyard ipmi_free_smi_msg(msg); 39925930707SCorey Minyard } 40025930707SCorey Minyard } 40125930707SCorey Minyard 40225930707SCorey Minyard static void start_event_fetch(struct ssif_info *ssif_info, unsigned long *flags) 40325930707SCorey Minyard { 40425930707SCorey Minyard struct ipmi_smi_msg *msg; 40525930707SCorey Minyard 40625930707SCorey Minyard ssif_info->req_events = false; 40725930707SCorey Minyard 40825930707SCorey Minyard msg = ipmi_alloc_smi_msg(); 40925930707SCorey Minyard if (!msg) { 41025930707SCorey Minyard ssif_info->ssif_state = SSIF_NORMAL; 411cf9806f3SDan Carpenter ipmi_ssif_unlock_cond(ssif_info, flags); 41225930707SCorey Minyard return; 41325930707SCorey Minyard } 41425930707SCorey Minyard 41525930707SCorey Minyard ssif_info->curr_msg = msg; 41625930707SCorey Minyard ssif_info->ssif_state = SSIF_GETTING_EVENTS; 41725930707SCorey Minyard ipmi_ssif_unlock_cond(ssif_info, flags); 41825930707SCorey Minyard 41925930707SCorey Minyard msg->data[0] = (IPMI_NETFN_APP_REQUEST << 2); 42025930707SCorey Minyard msg->data[1] = IPMI_READ_EVENT_MSG_BUFFER_CMD; 42125930707SCorey Minyard msg->data_size = 2; 42225930707SCorey Minyard 42325930707SCorey Minyard check_start_send(ssif_info, flags, msg); 42425930707SCorey Minyard } 42525930707SCorey Minyard 42625930707SCorey Minyard static void start_recv_msg_fetch(struct ssif_info *ssif_info, 42725930707SCorey Minyard unsigned long *flags) 42825930707SCorey Minyard { 42925930707SCorey Minyard struct ipmi_smi_msg *msg; 43025930707SCorey Minyard 43125930707SCorey Minyard msg = ipmi_alloc_smi_msg(); 43225930707SCorey Minyard if (!msg) { 43325930707SCorey Minyard ssif_info->ssif_state = SSIF_NORMAL; 434cf9806f3SDan Carpenter ipmi_ssif_unlock_cond(ssif_info, flags); 43525930707SCorey Minyard return; 43625930707SCorey Minyard } 43725930707SCorey Minyard 43825930707SCorey Minyard ssif_info->curr_msg = msg; 43925930707SCorey Minyard ssif_info->ssif_state = SSIF_GETTING_MESSAGES; 44025930707SCorey Minyard ipmi_ssif_unlock_cond(ssif_info, flags); 44125930707SCorey Minyard 44225930707SCorey Minyard msg->data[0] = (IPMI_NETFN_APP_REQUEST << 2); 44325930707SCorey Minyard msg->data[1] = IPMI_GET_MSG_CMD; 44425930707SCorey Minyard msg->data_size = 2; 44525930707SCorey Minyard 44625930707SCorey Minyard check_start_send(ssif_info, flags, msg); 44725930707SCorey Minyard } 44825930707SCorey Minyard 44925930707SCorey Minyard /* 45025930707SCorey Minyard * Must be called with the message lock held. This will release the 45125930707SCorey Minyard * message lock. Note that the caller will check SSIF_IDLE and start a 45225930707SCorey Minyard * new operation, so there is no need to check for new messages to 45325930707SCorey Minyard * start in here. 45425930707SCorey Minyard */ 45525930707SCorey Minyard static void handle_flags(struct ssif_info *ssif_info, unsigned long *flags) 45625930707SCorey Minyard { 45725930707SCorey Minyard if (ssif_info->msg_flags & WDT_PRE_TIMEOUT_INT) { 45825930707SCorey Minyard ipmi_smi_t intf = ssif_info->intf; 45925930707SCorey Minyard /* Watchdog pre-timeout */ 46025930707SCorey Minyard ssif_inc_stat(ssif_info, watchdog_pretimeouts); 46125930707SCorey Minyard start_clear_flags(ssif_info, flags); 46225930707SCorey Minyard if (intf) 46325930707SCorey Minyard ipmi_smi_watchdog_pretimeout(intf); 46425930707SCorey Minyard } else if (ssif_info->msg_flags & RECEIVE_MSG_AVAIL) 46525930707SCorey Minyard /* Messages available. */ 46625930707SCorey Minyard start_recv_msg_fetch(ssif_info, flags); 46725930707SCorey Minyard else if (ssif_info->msg_flags & EVENT_MSG_BUFFER_FULL) 46825930707SCorey Minyard /* Events available. */ 46925930707SCorey Minyard start_event_fetch(ssif_info, flags); 47025930707SCorey Minyard else { 47125930707SCorey Minyard ssif_info->ssif_state = SSIF_NORMAL; 47225930707SCorey Minyard ipmi_ssif_unlock_cond(ssif_info, flags); 47325930707SCorey Minyard } 47425930707SCorey Minyard } 47525930707SCorey Minyard 47625930707SCorey Minyard static int ipmi_ssif_thread(void *data) 47725930707SCorey Minyard { 47825930707SCorey Minyard struct ssif_info *ssif_info = data; 47925930707SCorey Minyard 48025930707SCorey Minyard while (!kthread_should_stop()) { 48125930707SCorey Minyard int result; 48225930707SCorey Minyard 48325930707SCorey Minyard /* Wait for something to do */ 484d0acf734SCorey Minyard result = wait_for_completion_interruptible( 485d0acf734SCorey Minyard &ssif_info->wake_thread); 48625930707SCorey Minyard if (ssif_info->stopping) 48725930707SCorey Minyard break; 488d0acf734SCorey Minyard if (result == -ERESTARTSYS) 489d0acf734SCorey Minyard continue; 490d0acf734SCorey Minyard init_completion(&ssif_info->wake_thread); 49125930707SCorey Minyard 49225930707SCorey Minyard if (ssif_info->i2c_read_write == I2C_SMBUS_WRITE) { 49325930707SCorey Minyard result = i2c_smbus_write_block_data( 4943d69d43bSCorey Minyard ssif_info->client, ssif_info->i2c_command, 49525930707SCorey Minyard ssif_info->i2c_data[0], 49625930707SCorey Minyard ssif_info->i2c_data + 1); 49725930707SCorey Minyard ssif_info->done_handler(ssif_info, result, NULL, 0); 49825930707SCorey Minyard } else { 49925930707SCorey Minyard result = i2c_smbus_read_block_data( 5003d69d43bSCorey Minyard ssif_info->client, ssif_info->i2c_command, 50125930707SCorey Minyard ssif_info->i2c_data); 50225930707SCorey Minyard if (result < 0) 50325930707SCorey Minyard ssif_info->done_handler(ssif_info, result, 50425930707SCorey Minyard NULL, 0); 50525930707SCorey Minyard else 50625930707SCorey Minyard ssif_info->done_handler(ssif_info, 0, 50725930707SCorey Minyard ssif_info->i2c_data, 50825930707SCorey Minyard result); 50925930707SCorey Minyard } 51025930707SCorey Minyard } 51125930707SCorey Minyard 51225930707SCorey Minyard return 0; 51325930707SCorey Minyard } 51425930707SCorey Minyard 51525930707SCorey Minyard static int ssif_i2c_send(struct ssif_info *ssif_info, 51625930707SCorey Minyard ssif_i2c_done handler, 51725930707SCorey Minyard int read_write, int command, 51825930707SCorey Minyard unsigned char *data, unsigned int size) 51925930707SCorey Minyard { 52025930707SCorey Minyard ssif_info->done_handler = handler; 52125930707SCorey Minyard 52225930707SCorey Minyard ssif_info->i2c_read_write = read_write; 52325930707SCorey Minyard ssif_info->i2c_command = command; 52425930707SCorey Minyard ssif_info->i2c_data = data; 52525930707SCorey Minyard ssif_info->i2c_size = size; 52625930707SCorey Minyard complete(&ssif_info->wake_thread); 52725930707SCorey Minyard return 0; 52825930707SCorey Minyard } 52925930707SCorey Minyard 53025930707SCorey Minyard 53125930707SCorey Minyard static void msg_done_handler(struct ssif_info *ssif_info, int result, 53225930707SCorey Minyard unsigned char *data, unsigned int len); 53325930707SCorey Minyard 53491620521SCorey Minyard static void start_get(struct ssif_info *ssif_info) 53525930707SCorey Minyard { 53625930707SCorey Minyard int rv; 53725930707SCorey Minyard 53825930707SCorey Minyard ssif_info->rtc_us_timer = 0; 5393d69d43bSCorey Minyard ssif_info->multi_pos = 0; 54025930707SCorey Minyard 54125930707SCorey Minyard rv = ssif_i2c_send(ssif_info, msg_done_handler, I2C_SMBUS_READ, 54225930707SCorey Minyard SSIF_IPMI_RESPONSE, 54325930707SCorey Minyard ssif_info->recv, I2C_SMBUS_BLOCK_DATA); 54425930707SCorey Minyard if (rv < 0) { 54525930707SCorey Minyard /* request failed, just return the error. */ 54625930707SCorey Minyard if (ssif_info->ssif_debug & SSIF_DEBUG_MSG) 54725930707SCorey Minyard pr_info("Error from i2c_non_blocking_op(5)\n"); 54825930707SCorey Minyard 54925930707SCorey Minyard msg_done_handler(ssif_info, -EIO, NULL, 0); 55025930707SCorey Minyard } 55125930707SCorey Minyard } 55225930707SCorey Minyard 55391620521SCorey Minyard static void retry_timeout(unsigned long data) 55491620521SCorey Minyard { 55591620521SCorey Minyard struct ssif_info *ssif_info = (void *) data; 55691620521SCorey Minyard unsigned long oflags, *flags; 55791620521SCorey Minyard bool waiting; 55891620521SCorey Minyard 55991620521SCorey Minyard if (ssif_info->stopping) 56091620521SCorey Minyard return; 56191620521SCorey Minyard 56291620521SCorey Minyard flags = ipmi_ssif_lock_cond(ssif_info, &oflags); 56391620521SCorey Minyard waiting = ssif_info->waiting_alert; 56491620521SCorey Minyard ssif_info->waiting_alert = false; 56591620521SCorey Minyard ipmi_ssif_unlock_cond(ssif_info, flags); 56691620521SCorey Minyard 56791620521SCorey Minyard if (waiting) 56891620521SCorey Minyard start_get(ssif_info); 56991620521SCorey Minyard } 57091620521SCorey Minyard 57191620521SCorey Minyard 572b4f21054SBenjamin Tissoires static void ssif_alert(struct i2c_client *client, enum i2c_alert_protocol type, 573b4f21054SBenjamin Tissoires unsigned int data) 57491620521SCorey Minyard { 57591620521SCorey Minyard struct ssif_info *ssif_info = i2c_get_clientdata(client); 57691620521SCorey Minyard unsigned long oflags, *flags; 57791620521SCorey Minyard bool do_get = false; 57891620521SCorey Minyard 579b4f21054SBenjamin Tissoires if (type != I2C_PROTOCOL_SMBUS_ALERT) 580b4f21054SBenjamin Tissoires return; 581b4f21054SBenjamin Tissoires 58291620521SCorey Minyard ssif_inc_stat(ssif_info, alerts); 58391620521SCorey Minyard 58491620521SCorey Minyard flags = ipmi_ssif_lock_cond(ssif_info, &oflags); 58591620521SCorey Minyard if (ssif_info->waiting_alert) { 58691620521SCorey Minyard ssif_info->waiting_alert = false; 58791620521SCorey Minyard del_timer(&ssif_info->retry_timer); 58891620521SCorey Minyard do_get = true; 58991620521SCorey Minyard } else if (ssif_info->curr_msg) { 59091620521SCorey Minyard ssif_info->got_alert = true; 59191620521SCorey Minyard } 59291620521SCorey Minyard ipmi_ssif_unlock_cond(ssif_info, flags); 59391620521SCorey Minyard if (do_get) 59491620521SCorey Minyard start_get(ssif_info); 59591620521SCorey Minyard } 59691620521SCorey Minyard 59725930707SCorey Minyard static int start_resend(struct ssif_info *ssif_info); 59825930707SCorey Minyard 59925930707SCorey Minyard static void msg_done_handler(struct ssif_info *ssif_info, int result, 60025930707SCorey Minyard unsigned char *data, unsigned int len) 60125930707SCorey Minyard { 60225930707SCorey Minyard struct ipmi_smi_msg *msg; 60325930707SCorey Minyard unsigned long oflags, *flags; 60425930707SCorey Minyard int rv; 60525930707SCorey Minyard 60625930707SCorey Minyard /* 60725930707SCorey Minyard * We are single-threaded here, so no need for a lock until we 60825930707SCorey Minyard * start messing with driver states or the queues. 60925930707SCorey Minyard */ 61025930707SCorey Minyard 61125930707SCorey Minyard if (result < 0) { 61225930707SCorey Minyard ssif_info->retries_left--; 61325930707SCorey Minyard if (ssif_info->retries_left > 0) { 61425930707SCorey Minyard ssif_inc_stat(ssif_info, receive_retries); 61525930707SCorey Minyard 61691620521SCorey Minyard flags = ipmi_ssif_lock_cond(ssif_info, &oflags); 61791620521SCorey Minyard ssif_info->waiting_alert = true; 61891620521SCorey Minyard ssif_info->rtc_us_timer = SSIF_MSG_USEC; 61925930707SCorey Minyard mod_timer(&ssif_info->retry_timer, 62025930707SCorey Minyard jiffies + SSIF_MSG_JIFFIES); 62191620521SCorey Minyard ipmi_ssif_unlock_cond(ssif_info, flags); 62225930707SCorey Minyard return; 62325930707SCorey Minyard } 62425930707SCorey Minyard 62525930707SCorey Minyard ssif_inc_stat(ssif_info, receive_errors); 62625930707SCorey Minyard 62725930707SCorey Minyard if (ssif_info->ssif_debug & SSIF_DEBUG_MSG) 62825930707SCorey Minyard pr_info("Error in msg_done_handler: %d\n", result); 62925930707SCorey Minyard len = 0; 63025930707SCorey Minyard goto continue_op; 63125930707SCorey Minyard } 63225930707SCorey Minyard 63325930707SCorey Minyard if ((len > 1) && (ssif_info->multi_pos == 0) 63425930707SCorey Minyard && (data[0] == 0x00) && (data[1] == 0x01)) { 63525930707SCorey Minyard /* Start of multi-part read. Start the next transaction. */ 63625930707SCorey Minyard int i; 63725930707SCorey Minyard 63825930707SCorey Minyard ssif_inc_stat(ssif_info, received_message_parts); 63925930707SCorey Minyard 64025930707SCorey Minyard /* Remove the multi-part read marker. */ 64125930707SCorey Minyard len -= 2; 6423d69d43bSCorey Minyard for (i = 0; i < len; i++) 6433d69d43bSCorey Minyard ssif_info->data[i] = data[i+2]; 64425930707SCorey Minyard ssif_info->multi_len = len; 64525930707SCorey Minyard ssif_info->multi_pos = 1; 64625930707SCorey Minyard 64725930707SCorey Minyard rv = ssif_i2c_send(ssif_info, msg_done_handler, I2C_SMBUS_READ, 64825930707SCorey Minyard SSIF_IPMI_MULTI_PART_RESPONSE_MIDDLE, 64925930707SCorey Minyard ssif_info->recv, I2C_SMBUS_BLOCK_DATA); 65025930707SCorey Minyard if (rv < 0) { 65125930707SCorey Minyard if (ssif_info->ssif_debug & SSIF_DEBUG_MSG) 65225930707SCorey Minyard pr_info("Error from i2c_non_blocking_op(1)\n"); 65325930707SCorey Minyard 65425930707SCorey Minyard result = -EIO; 65525930707SCorey Minyard } else 65625930707SCorey Minyard return; 65725930707SCorey Minyard } else if (ssif_info->multi_pos) { 65825930707SCorey Minyard /* Middle of multi-part read. Start the next transaction. */ 65925930707SCorey Minyard int i; 66025930707SCorey Minyard unsigned char blocknum; 66125930707SCorey Minyard 66225930707SCorey Minyard if (len == 0) { 66325930707SCorey Minyard result = -EIO; 66425930707SCorey Minyard if (ssif_info->ssif_debug & SSIF_DEBUG_MSG) 66525930707SCorey Minyard pr_info(PFX "Middle message with no data\n"); 66625930707SCorey Minyard 66725930707SCorey Minyard goto continue_op; 66825930707SCorey Minyard } 66925930707SCorey Minyard 6703d69d43bSCorey Minyard blocknum = data[0]; 67125930707SCorey Minyard 67225930707SCorey Minyard if (ssif_info->multi_len + len - 1 > IPMI_MAX_MSG_LENGTH) { 67325930707SCorey Minyard /* Received message too big, abort the operation. */ 67425930707SCorey Minyard result = -E2BIG; 67525930707SCorey Minyard if (ssif_info->ssif_debug & SSIF_DEBUG_MSG) 67625930707SCorey Minyard pr_info("Received message too big\n"); 67725930707SCorey Minyard 67825930707SCorey Minyard goto continue_op; 67925930707SCorey Minyard } 68025930707SCorey Minyard 68125930707SCorey Minyard /* Remove the blocknum from the data. */ 68225930707SCorey Minyard len--; 6833d69d43bSCorey Minyard for (i = 0; i < len; i++) 6843d69d43bSCorey Minyard ssif_info->data[i + ssif_info->multi_len] = data[i + 1]; 68525930707SCorey Minyard ssif_info->multi_len += len; 68625930707SCorey Minyard if (blocknum == 0xff) { 68725930707SCorey Minyard /* End of read */ 68825930707SCorey Minyard len = ssif_info->multi_len; 68925930707SCorey Minyard data = ssif_info->data; 6903d69d43bSCorey Minyard } else if (blocknum + 1 != ssif_info->multi_pos) { 69125930707SCorey Minyard /* 69225930707SCorey Minyard * Out of sequence block, just abort. Block 69325930707SCorey Minyard * numbers start at zero for the second block, 69425930707SCorey Minyard * but multi_pos starts at one, so the +1. 69525930707SCorey Minyard */ 69625930707SCorey Minyard result = -EIO; 69725930707SCorey Minyard } else { 69825930707SCorey Minyard ssif_inc_stat(ssif_info, received_message_parts); 69925930707SCorey Minyard 70025930707SCorey Minyard ssif_info->multi_pos++; 70125930707SCorey Minyard 70225930707SCorey Minyard rv = ssif_i2c_send(ssif_info, msg_done_handler, 70325930707SCorey Minyard I2C_SMBUS_READ, 70425930707SCorey Minyard SSIF_IPMI_MULTI_PART_RESPONSE_MIDDLE, 70525930707SCorey Minyard ssif_info->recv, 70625930707SCorey Minyard I2C_SMBUS_BLOCK_DATA); 70725930707SCorey Minyard if (rv < 0) { 70825930707SCorey Minyard if (ssif_info->ssif_debug & SSIF_DEBUG_MSG) 70925930707SCorey Minyard pr_info(PFX 71091620521SCorey Minyard "Error from ssif_i2c_send\n"); 71125930707SCorey Minyard 71225930707SCorey Minyard result = -EIO; 71325930707SCorey Minyard } else 71425930707SCorey Minyard return; 71525930707SCorey Minyard } 71625930707SCorey Minyard } 71725930707SCorey Minyard 71825930707SCorey Minyard if (result < 0) { 71925930707SCorey Minyard ssif_inc_stat(ssif_info, receive_errors); 72025930707SCorey Minyard } else { 72125930707SCorey Minyard ssif_inc_stat(ssif_info, received_messages); 72225930707SCorey Minyard ssif_inc_stat(ssif_info, received_message_parts); 72325930707SCorey Minyard } 72425930707SCorey Minyard 72525930707SCorey Minyard 72625930707SCorey Minyard continue_op: 72725930707SCorey Minyard if (ssif_info->ssif_debug & SSIF_DEBUG_STATE) 72825930707SCorey Minyard pr_info(PFX "DONE 1: state = %d, result=%d.\n", 72925930707SCorey Minyard ssif_info->ssif_state, result); 73025930707SCorey Minyard 73125930707SCorey Minyard flags = ipmi_ssif_lock_cond(ssif_info, &oflags); 73225930707SCorey Minyard msg = ssif_info->curr_msg; 73325930707SCorey Minyard if (msg) { 73425930707SCorey Minyard msg->rsp_size = len; 73525930707SCorey Minyard if (msg->rsp_size > IPMI_MAX_MSG_LENGTH) 73625930707SCorey Minyard msg->rsp_size = IPMI_MAX_MSG_LENGTH; 73725930707SCorey Minyard memcpy(msg->rsp, data, msg->rsp_size); 73825930707SCorey Minyard ssif_info->curr_msg = NULL; 73925930707SCorey Minyard } 74025930707SCorey Minyard 74125930707SCorey Minyard switch (ssif_info->ssif_state) { 74225930707SCorey Minyard case SSIF_NORMAL: 74325930707SCorey Minyard ipmi_ssif_unlock_cond(ssif_info, flags); 74425930707SCorey Minyard if (!msg) 74525930707SCorey Minyard break; 74625930707SCorey Minyard 74725930707SCorey Minyard if (result < 0) 74825930707SCorey Minyard return_hosed_msg(ssif_info, msg); 74925930707SCorey Minyard else 75025930707SCorey Minyard deliver_recv_msg(ssif_info, msg); 75125930707SCorey Minyard break; 75225930707SCorey Minyard 75325930707SCorey Minyard case SSIF_GETTING_FLAGS: 75425930707SCorey Minyard /* We got the flags from the SSIF, now handle them. */ 75525930707SCorey Minyard if ((result < 0) || (len < 4) || (data[2] != 0)) { 75625930707SCorey Minyard /* 75725930707SCorey Minyard * Error fetching flags, or invalid length, 75825930707SCorey Minyard * just give up for now. 75925930707SCorey Minyard */ 76025930707SCorey Minyard ssif_info->ssif_state = SSIF_NORMAL; 76125930707SCorey Minyard ipmi_ssif_unlock_cond(ssif_info, flags); 76225930707SCorey Minyard pr_warn(PFX "Error getting flags: %d %d, %x\n", 76325930707SCorey Minyard result, len, data[2]); 76425930707SCorey Minyard } else if (data[0] != (IPMI_NETFN_APP_REQUEST | 1) << 2 76525930707SCorey Minyard || data[1] != IPMI_GET_MSG_FLAGS_CMD) { 76625930707SCorey Minyard pr_warn(PFX "Invalid response getting flags: %x %x\n", 76725930707SCorey Minyard data[0], data[1]); 76825930707SCorey Minyard } else { 76925930707SCorey Minyard ssif_inc_stat(ssif_info, flag_fetches); 77025930707SCorey Minyard ssif_info->msg_flags = data[3]; 77125930707SCorey Minyard handle_flags(ssif_info, flags); 77225930707SCorey Minyard } 77325930707SCorey Minyard break; 77425930707SCorey Minyard 77525930707SCorey Minyard case SSIF_CLEARING_FLAGS: 77625930707SCorey Minyard /* We cleared the flags. */ 77725930707SCorey Minyard if ((result < 0) || (len < 3) || (data[2] != 0)) { 77825930707SCorey Minyard /* Error clearing flags */ 77925930707SCorey Minyard pr_warn(PFX "Error clearing flags: %d %d, %x\n", 78025930707SCorey Minyard result, len, data[2]); 78125930707SCorey Minyard } else if (data[0] != (IPMI_NETFN_APP_REQUEST | 1) << 2 78225930707SCorey Minyard || data[1] != IPMI_CLEAR_MSG_FLAGS_CMD) { 78325930707SCorey Minyard pr_warn(PFX "Invalid response clearing flags: %x %x\n", 78425930707SCorey Minyard data[0], data[1]); 78525930707SCorey Minyard } 78625930707SCorey Minyard ssif_info->ssif_state = SSIF_NORMAL; 78725930707SCorey Minyard ipmi_ssif_unlock_cond(ssif_info, flags); 78825930707SCorey Minyard break; 78925930707SCorey Minyard 79025930707SCorey Minyard case SSIF_GETTING_EVENTS: 79125930707SCorey Minyard if ((result < 0) || (len < 3) || (msg->rsp[2] != 0)) { 79225930707SCorey Minyard /* Error getting event, probably done. */ 79325930707SCorey Minyard msg->done(msg); 79425930707SCorey Minyard 79525930707SCorey Minyard /* Take off the event flag. */ 79625930707SCorey Minyard ssif_info->msg_flags &= ~EVENT_MSG_BUFFER_FULL; 79725930707SCorey Minyard handle_flags(ssif_info, flags); 79825930707SCorey Minyard } else if (msg->rsp[0] != (IPMI_NETFN_APP_REQUEST | 1) << 2 79925930707SCorey Minyard || msg->rsp[1] != IPMI_READ_EVENT_MSG_BUFFER_CMD) { 80025930707SCorey Minyard pr_warn(PFX "Invalid response getting events: %x %x\n", 80125930707SCorey Minyard msg->rsp[0], msg->rsp[1]); 80225930707SCorey Minyard msg->done(msg); 80325930707SCorey Minyard /* Take off the event flag. */ 80425930707SCorey Minyard ssif_info->msg_flags &= ~EVENT_MSG_BUFFER_FULL; 80525930707SCorey Minyard handle_flags(ssif_info, flags); 80625930707SCorey Minyard } else { 80725930707SCorey Minyard handle_flags(ssif_info, flags); 80825930707SCorey Minyard ssif_inc_stat(ssif_info, events); 80925930707SCorey Minyard deliver_recv_msg(ssif_info, msg); 81025930707SCorey Minyard } 81125930707SCorey Minyard break; 81225930707SCorey Minyard 81325930707SCorey Minyard case SSIF_GETTING_MESSAGES: 81425930707SCorey Minyard if ((result < 0) || (len < 3) || (msg->rsp[2] != 0)) { 81525930707SCorey Minyard /* Error getting event, probably done. */ 81625930707SCorey Minyard msg->done(msg); 81725930707SCorey Minyard 81825930707SCorey Minyard /* Take off the msg flag. */ 81925930707SCorey Minyard ssif_info->msg_flags &= ~RECEIVE_MSG_AVAIL; 82025930707SCorey Minyard handle_flags(ssif_info, flags); 82125930707SCorey Minyard } else if (msg->rsp[0] != (IPMI_NETFN_APP_REQUEST | 1) << 2 82225930707SCorey Minyard || msg->rsp[1] != IPMI_GET_MSG_CMD) { 82325930707SCorey Minyard pr_warn(PFX "Invalid response clearing flags: %x %x\n", 82425930707SCorey Minyard msg->rsp[0], msg->rsp[1]); 82525930707SCorey Minyard msg->done(msg); 82625930707SCorey Minyard 82725930707SCorey Minyard /* Take off the msg flag. */ 82825930707SCorey Minyard ssif_info->msg_flags &= ~RECEIVE_MSG_AVAIL; 82925930707SCorey Minyard handle_flags(ssif_info, flags); 83025930707SCorey Minyard } else { 83125930707SCorey Minyard ssif_inc_stat(ssif_info, incoming_messages); 83225930707SCorey Minyard handle_flags(ssif_info, flags); 83325930707SCorey Minyard deliver_recv_msg(ssif_info, msg); 83425930707SCorey Minyard } 83525930707SCorey Minyard break; 83625930707SCorey Minyard } 83725930707SCorey Minyard 83825930707SCorey Minyard flags = ipmi_ssif_lock_cond(ssif_info, &oflags); 83925930707SCorey Minyard if (SSIF_IDLE(ssif_info) && !ssif_info->stopping) { 84025930707SCorey Minyard if (ssif_info->req_events) 84125930707SCorey Minyard start_event_fetch(ssif_info, flags); 84225930707SCorey Minyard else if (ssif_info->req_flags) 84325930707SCorey Minyard start_flag_fetch(ssif_info, flags); 84425930707SCorey Minyard else 84525930707SCorey Minyard start_next_msg(ssif_info, flags); 84625930707SCorey Minyard } else 84725930707SCorey Minyard ipmi_ssif_unlock_cond(ssif_info, flags); 84825930707SCorey Minyard 84925930707SCorey Minyard if (ssif_info->ssif_debug & SSIF_DEBUG_STATE) 85025930707SCorey Minyard pr_info(PFX "DONE 2: state = %d.\n", ssif_info->ssif_state); 85125930707SCorey Minyard } 85225930707SCorey Minyard 85325930707SCorey Minyard static void msg_written_handler(struct ssif_info *ssif_info, int result, 85425930707SCorey Minyard unsigned char *data, unsigned int len) 85525930707SCorey Minyard { 85625930707SCorey Minyard int rv; 85725930707SCorey Minyard 85825930707SCorey Minyard /* We are single-threaded here, so no need for a lock. */ 85925930707SCorey Minyard if (result < 0) { 86025930707SCorey Minyard ssif_info->retries_left--; 86125930707SCorey Minyard if (ssif_info->retries_left > 0) { 86225930707SCorey Minyard if (!start_resend(ssif_info)) { 86325930707SCorey Minyard ssif_inc_stat(ssif_info, send_retries); 86425930707SCorey Minyard return; 86525930707SCorey Minyard } 86625930707SCorey Minyard /* request failed, just return the error. */ 86725930707SCorey Minyard ssif_inc_stat(ssif_info, send_errors); 86825930707SCorey Minyard 86925930707SCorey Minyard if (ssif_info->ssif_debug & SSIF_DEBUG_MSG) 87025930707SCorey Minyard pr_info(PFX 87125930707SCorey Minyard "Out of retries in msg_written_handler\n"); 87225930707SCorey Minyard msg_done_handler(ssif_info, -EIO, NULL, 0); 87325930707SCorey Minyard return; 87425930707SCorey Minyard } 87525930707SCorey Minyard 87625930707SCorey Minyard ssif_inc_stat(ssif_info, send_errors); 87725930707SCorey Minyard 87825930707SCorey Minyard /* 87925930707SCorey Minyard * Got an error on transmit, let the done routine 88025930707SCorey Minyard * handle it. 88125930707SCorey Minyard */ 88225930707SCorey Minyard if (ssif_info->ssif_debug & SSIF_DEBUG_MSG) 88325930707SCorey Minyard pr_info("Error in msg_written_handler: %d\n", result); 88425930707SCorey Minyard 88525930707SCorey Minyard msg_done_handler(ssif_info, result, NULL, 0); 88625930707SCorey Minyard return; 88725930707SCorey Minyard } 88825930707SCorey Minyard 88925930707SCorey Minyard if (ssif_info->multi_data) { 8903d69d43bSCorey Minyard /* 8913d69d43bSCorey Minyard * In the middle of a multi-data write. See the comment 8923d69d43bSCorey Minyard * in the SSIF_MULTI_n_PART case in the probe function 8933d69d43bSCorey Minyard * for details on the intricacies of this. 8943d69d43bSCorey Minyard */ 89525930707SCorey Minyard int left; 8966de65fcfSJoeseph Chang unsigned char *data_to_send; 89725930707SCorey Minyard 89825930707SCorey Minyard ssif_inc_stat(ssif_info, sent_messages_parts); 89925930707SCorey Minyard 90025930707SCorey Minyard left = ssif_info->multi_len - ssif_info->multi_pos; 90125930707SCorey Minyard if (left > 32) 90225930707SCorey Minyard left = 32; 90325930707SCorey Minyard /* Length byte. */ 90425930707SCorey Minyard ssif_info->multi_data[ssif_info->multi_pos] = left; 9056de65fcfSJoeseph Chang data_to_send = ssif_info->multi_data + ssif_info->multi_pos; 90625930707SCorey Minyard ssif_info->multi_pos += left; 90725930707SCorey Minyard if (left < 32) 90825930707SCorey Minyard /* 90925930707SCorey Minyard * Write is finished. Note that we must end 91025930707SCorey Minyard * with a write of less than 32 bytes to 91125930707SCorey Minyard * complete the transaction, even if it is 91225930707SCorey Minyard * zero bytes. 91325930707SCorey Minyard */ 91425930707SCorey Minyard ssif_info->multi_data = NULL; 91525930707SCorey Minyard 91625930707SCorey Minyard rv = ssif_i2c_send(ssif_info, msg_written_handler, 91725930707SCorey Minyard I2C_SMBUS_WRITE, 91825930707SCorey Minyard SSIF_IPMI_MULTI_PART_REQUEST_MIDDLE, 9196de65fcfSJoeseph Chang data_to_send, 92025930707SCorey Minyard I2C_SMBUS_BLOCK_DATA); 92125930707SCorey Minyard if (rv < 0) { 92225930707SCorey Minyard /* request failed, just return the error. */ 92325930707SCorey Minyard ssif_inc_stat(ssif_info, send_errors); 92425930707SCorey Minyard 92525930707SCorey Minyard if (ssif_info->ssif_debug & SSIF_DEBUG_MSG) 92625930707SCorey Minyard pr_info("Error from i2c_non_blocking_op(3)\n"); 92725930707SCorey Minyard msg_done_handler(ssif_info, -EIO, NULL, 0); 92825930707SCorey Minyard } 92925930707SCorey Minyard } else { 93021c8f915SCorey Minyard /* Ready to request the result. */ 93191620521SCorey Minyard unsigned long oflags, *flags; 93291620521SCorey Minyard 93325930707SCorey Minyard ssif_inc_stat(ssif_info, sent_messages); 93425930707SCorey Minyard ssif_inc_stat(ssif_info, sent_messages_parts); 93525930707SCorey Minyard 93691620521SCorey Minyard flags = ipmi_ssif_lock_cond(ssif_info, &oflags); 93721c8f915SCorey Minyard if (ssif_info->got_alert) { 93821c8f915SCorey Minyard /* The result is already ready, just start it. */ 93991620521SCorey Minyard ssif_info->got_alert = false; 94091620521SCorey Minyard ipmi_ssif_unlock_cond(ssif_info, flags); 94121c8f915SCorey Minyard start_get(ssif_info); 94291620521SCorey Minyard } else { 94325930707SCorey Minyard /* Wait a jiffie then request the next message */ 94491620521SCorey Minyard ssif_info->waiting_alert = true; 94525930707SCorey Minyard ssif_info->retries_left = SSIF_RECV_RETRIES; 94625930707SCorey Minyard ssif_info->rtc_us_timer = SSIF_MSG_PART_USEC; 94725930707SCorey Minyard mod_timer(&ssif_info->retry_timer, 94825930707SCorey Minyard jiffies + SSIF_MSG_PART_JIFFIES); 94991620521SCorey Minyard ipmi_ssif_unlock_cond(ssif_info, flags); 95091620521SCorey Minyard } 95125930707SCorey Minyard } 95225930707SCorey Minyard } 95325930707SCorey Minyard 95425930707SCorey Minyard static int start_resend(struct ssif_info *ssif_info) 95525930707SCorey Minyard { 95625930707SCorey Minyard int rv; 95725930707SCorey Minyard int command; 95825930707SCorey Minyard 95991620521SCorey Minyard ssif_info->got_alert = false; 96091620521SCorey Minyard 96125930707SCorey Minyard if (ssif_info->data_len > 32) { 96225930707SCorey Minyard command = SSIF_IPMI_MULTI_PART_REQUEST_START; 96325930707SCorey Minyard ssif_info->multi_data = ssif_info->data; 96425930707SCorey Minyard ssif_info->multi_len = ssif_info->data_len; 96525930707SCorey Minyard /* 96625930707SCorey Minyard * Subtle thing, this is 32, not 33, because we will 96725930707SCorey Minyard * overwrite the thing at position 32 (which was just 96825930707SCorey Minyard * transmitted) with the new length. 96925930707SCorey Minyard */ 97025930707SCorey Minyard ssif_info->multi_pos = 32; 97125930707SCorey Minyard ssif_info->data[0] = 32; 97225930707SCorey Minyard } else { 97325930707SCorey Minyard ssif_info->multi_data = NULL; 97425930707SCorey Minyard command = SSIF_IPMI_REQUEST; 97525930707SCorey Minyard ssif_info->data[0] = ssif_info->data_len; 97625930707SCorey Minyard } 97725930707SCorey Minyard 97825930707SCorey Minyard rv = ssif_i2c_send(ssif_info, msg_written_handler, I2C_SMBUS_WRITE, 97925930707SCorey Minyard command, ssif_info->data, I2C_SMBUS_BLOCK_DATA); 98025930707SCorey Minyard if (rv && (ssif_info->ssif_debug & SSIF_DEBUG_MSG)) 98125930707SCorey Minyard pr_info("Error from i2c_non_blocking_op(4)\n"); 98225930707SCorey Minyard return rv; 98325930707SCorey Minyard } 98425930707SCorey Minyard 98525930707SCorey Minyard static int start_send(struct ssif_info *ssif_info, 98625930707SCorey Minyard unsigned char *data, 98725930707SCorey Minyard unsigned int len) 98825930707SCorey Minyard { 98925930707SCorey Minyard if (len > IPMI_MAX_MSG_LENGTH) 99025930707SCorey Minyard return -E2BIG; 99125930707SCorey Minyard if (len > ssif_info->max_xmit_msg_size) 99225930707SCorey Minyard return -E2BIG; 99325930707SCorey Minyard 99425930707SCorey Minyard ssif_info->retries_left = SSIF_SEND_RETRIES; 99525930707SCorey Minyard memcpy(ssif_info->data + 1, data, len); 99625930707SCorey Minyard ssif_info->data_len = len; 99725930707SCorey Minyard return start_resend(ssif_info); 99825930707SCorey Minyard } 99925930707SCorey Minyard 100025930707SCorey Minyard /* Must be called with the message lock held. */ 100125930707SCorey Minyard static void start_next_msg(struct ssif_info *ssif_info, unsigned long *flags) 100225930707SCorey Minyard { 100325930707SCorey Minyard struct ipmi_smi_msg *msg; 100425930707SCorey Minyard unsigned long oflags; 100525930707SCorey Minyard 100625930707SCorey Minyard restart: 100725930707SCorey Minyard if (!SSIF_IDLE(ssif_info)) { 100825930707SCorey Minyard ipmi_ssif_unlock_cond(ssif_info, flags); 100925930707SCorey Minyard return; 101025930707SCorey Minyard } 101125930707SCorey Minyard 101225930707SCorey Minyard if (!ssif_info->waiting_msg) { 101325930707SCorey Minyard ssif_info->curr_msg = NULL; 101425930707SCorey Minyard ipmi_ssif_unlock_cond(ssif_info, flags); 101525930707SCorey Minyard } else { 101625930707SCorey Minyard int rv; 101725930707SCorey Minyard 101825930707SCorey Minyard ssif_info->curr_msg = ssif_info->waiting_msg; 101925930707SCorey Minyard ssif_info->waiting_msg = NULL; 102025930707SCorey Minyard ipmi_ssif_unlock_cond(ssif_info, flags); 102125930707SCorey Minyard rv = start_send(ssif_info, 102225930707SCorey Minyard ssif_info->curr_msg->data, 102325930707SCorey Minyard ssif_info->curr_msg->data_size); 102425930707SCorey Minyard if (rv) { 102525930707SCorey Minyard msg = ssif_info->curr_msg; 102625930707SCorey Minyard ssif_info->curr_msg = NULL; 102725930707SCorey Minyard return_hosed_msg(ssif_info, msg); 102825930707SCorey Minyard flags = ipmi_ssif_lock_cond(ssif_info, &oflags); 102925930707SCorey Minyard goto restart; 103025930707SCorey Minyard } 103125930707SCorey Minyard } 103225930707SCorey Minyard } 103325930707SCorey Minyard 103425930707SCorey Minyard static void sender(void *send_info, 103525930707SCorey Minyard struct ipmi_smi_msg *msg) 103625930707SCorey Minyard { 103725930707SCorey Minyard struct ssif_info *ssif_info = (struct ssif_info *) send_info; 103825930707SCorey Minyard unsigned long oflags, *flags; 103925930707SCorey Minyard 104025930707SCorey Minyard BUG_ON(ssif_info->waiting_msg); 104125930707SCorey Minyard ssif_info->waiting_msg = msg; 104225930707SCorey Minyard 104325930707SCorey Minyard flags = ipmi_ssif_lock_cond(ssif_info, &oflags); 104425930707SCorey Minyard start_next_msg(ssif_info, flags); 104525930707SCorey Minyard 104625930707SCorey Minyard if (ssif_info->ssif_debug & SSIF_DEBUG_TIMING) { 1047526290aaSAmitoj Kaur Chawla struct timespec64 t; 104825930707SCorey Minyard 1049526290aaSAmitoj Kaur Chawla ktime_get_real_ts64(&t); 1050526290aaSAmitoj Kaur Chawla pr_info("**Enqueue %02x %02x: %lld.%6.6ld\n", 10511421c935SCorey Minyard msg->data[0], msg->data[1], 1052526290aaSAmitoj Kaur Chawla (long long) t.tv_sec, (long) t.tv_nsec / NSEC_PER_USEC); 105325930707SCorey Minyard } 105425930707SCorey Minyard } 105525930707SCorey Minyard 105625930707SCorey Minyard static int get_smi_info(void *send_info, struct ipmi_smi_info *data) 105725930707SCorey Minyard { 105825930707SCorey Minyard struct ssif_info *ssif_info = send_info; 105925930707SCorey Minyard 106025930707SCorey Minyard data->addr_src = ssif_info->addr_source; 106125930707SCorey Minyard data->dev = &ssif_info->client->dev; 106225930707SCorey Minyard data->addr_info = ssif_info->addr_info; 106325930707SCorey Minyard get_device(data->dev); 106425930707SCorey Minyard 106525930707SCorey Minyard return 0; 106625930707SCorey Minyard } 106725930707SCorey Minyard 106825930707SCorey Minyard /* 106925930707SCorey Minyard * Instead of having our own timer to periodically check the message 107025930707SCorey Minyard * flags, we let the message handler drive us. 107125930707SCorey Minyard */ 107225930707SCorey Minyard static void request_events(void *send_info) 107325930707SCorey Minyard { 107425930707SCorey Minyard struct ssif_info *ssif_info = (struct ssif_info *) send_info; 107525930707SCorey Minyard unsigned long oflags, *flags; 107625930707SCorey Minyard 107725930707SCorey Minyard if (!ssif_info->has_event_buffer) 107825930707SCorey Minyard return; 107925930707SCorey Minyard 108025930707SCorey Minyard flags = ipmi_ssif_lock_cond(ssif_info, &oflags); 108125930707SCorey Minyard /* 108225930707SCorey Minyard * Request flags first, not events, because the lower layer 108325930707SCorey Minyard * doesn't have a way to send an attention. But make sure 108425930707SCorey Minyard * event checking still happens. 108525930707SCorey Minyard */ 108625930707SCorey Minyard ssif_info->req_events = true; 108725930707SCorey Minyard if (SSIF_IDLE(ssif_info)) 108825930707SCorey Minyard start_flag_fetch(ssif_info, flags); 108925930707SCorey Minyard else { 109025930707SCorey Minyard ssif_info->req_flags = true; 109125930707SCorey Minyard ipmi_ssif_unlock_cond(ssif_info, flags); 109225930707SCorey Minyard } 109325930707SCorey Minyard } 109425930707SCorey Minyard 109525930707SCorey Minyard static int inc_usecount(void *send_info) 109625930707SCorey Minyard { 109725930707SCorey Minyard struct ssif_info *ssif_info = send_info; 109825930707SCorey Minyard 1099be8647d2SCorey Minyard if (!i2c_get_adapter(i2c_adapter_id(ssif_info->client->adapter))) 110025930707SCorey Minyard return -ENODEV; 110125930707SCorey Minyard 110225930707SCorey Minyard i2c_use_client(ssif_info->client); 110325930707SCorey Minyard return 0; 110425930707SCorey Minyard } 110525930707SCorey Minyard 110625930707SCorey Minyard static void dec_usecount(void *send_info) 110725930707SCorey Minyard { 110825930707SCorey Minyard struct ssif_info *ssif_info = send_info; 110925930707SCorey Minyard 111025930707SCorey Minyard i2c_release_client(ssif_info->client); 111125930707SCorey Minyard i2c_put_adapter(ssif_info->client->adapter); 111225930707SCorey Minyard } 111325930707SCorey Minyard 111425930707SCorey Minyard static int ssif_start_processing(void *send_info, 111525930707SCorey Minyard ipmi_smi_t intf) 111625930707SCorey Minyard { 111725930707SCorey Minyard struct ssif_info *ssif_info = send_info; 111825930707SCorey Minyard 111925930707SCorey Minyard ssif_info->intf = intf; 112025930707SCorey Minyard 112125930707SCorey Minyard return 0; 112225930707SCorey Minyard } 112325930707SCorey Minyard 112425930707SCorey Minyard #define MAX_SSIF_BMCS 4 112525930707SCorey Minyard 112625930707SCorey Minyard static unsigned short addr[MAX_SSIF_BMCS]; 112725930707SCorey Minyard static int num_addrs; 112825930707SCorey Minyard module_param_array(addr, ushort, &num_addrs, 0); 112925930707SCorey Minyard MODULE_PARM_DESC(addr, "The addresses to scan for IPMI BMCs on the SSIFs."); 113025930707SCorey Minyard 113125930707SCorey Minyard static char *adapter_name[MAX_SSIF_BMCS]; 113225930707SCorey Minyard static int num_adapter_names; 113325930707SCorey Minyard module_param_array(adapter_name, charp, &num_adapter_names, 0); 113425930707SCorey Minyard MODULE_PARM_DESC(adapter_name, "The string name of the I2C device that has the BMC. By default all devices are scanned."); 113525930707SCorey Minyard 113625930707SCorey Minyard static int slave_addrs[MAX_SSIF_BMCS]; 113725930707SCorey Minyard static int num_slave_addrs; 113825930707SCorey Minyard module_param_array(slave_addrs, int, &num_slave_addrs, 0); 113925930707SCorey Minyard MODULE_PARM_DESC(slave_addrs, 114025930707SCorey Minyard "The default IPMB slave address for the controller."); 114125930707SCorey Minyard 1142bf2d0877SCorey Minyard static bool alerts_broken; 1143bf2d0877SCorey Minyard module_param(alerts_broken, bool, 0); 1144bf2d0877SCorey Minyard MODULE_PARM_DESC(alerts_broken, "Don't enable alerts for the controller."); 1145bf2d0877SCorey Minyard 114625930707SCorey Minyard /* 114725930707SCorey Minyard * Bit 0 enables message debugging, bit 1 enables state debugging, and 114825930707SCorey Minyard * bit 2 enables timing debugging. This is an array indexed by 114925930707SCorey Minyard * interface number" 115025930707SCorey Minyard */ 115125930707SCorey Minyard static int dbg[MAX_SSIF_BMCS]; 115225930707SCorey Minyard static int num_dbg; 115325930707SCorey Minyard module_param_array(dbg, int, &num_dbg, 0); 115425930707SCorey Minyard MODULE_PARM_DESC(dbg, "Turn on debugging."); 115525930707SCorey Minyard 115625930707SCorey Minyard static bool ssif_dbg_probe; 115725930707SCorey Minyard module_param_named(dbg_probe, ssif_dbg_probe, bool, 0); 115825930707SCorey Minyard MODULE_PARM_DESC(dbg_probe, "Enable debugging of probing of adapters."); 115925930707SCorey Minyard 1160fedb25eaSShailendra Verma static bool ssif_tryacpi = true; 116125930707SCorey Minyard module_param_named(tryacpi, ssif_tryacpi, bool, 0); 116225930707SCorey Minyard MODULE_PARM_DESC(tryacpi, "Setting this to zero will disable the default scan of the interfaces identified via ACPI"); 116325930707SCorey Minyard 1164fedb25eaSShailendra Verma static bool ssif_trydmi = true; 116525930707SCorey Minyard module_param_named(trydmi, ssif_trydmi, bool, 0); 116625930707SCorey Minyard MODULE_PARM_DESC(trydmi, "Setting this to zero will disable the default scan of the interfaces identified via DMI (SMBIOS)"); 116725930707SCorey Minyard 116825930707SCorey Minyard static DEFINE_MUTEX(ssif_infos_mutex); 116925930707SCorey Minyard static LIST_HEAD(ssif_infos); 117025930707SCorey Minyard 117125930707SCorey Minyard static int ssif_remove(struct i2c_client *client) 117225930707SCorey Minyard { 117325930707SCorey Minyard struct ssif_info *ssif_info = i2c_get_clientdata(client); 117425930707SCorey Minyard int rv; 117525930707SCorey Minyard 117625930707SCorey Minyard if (!ssif_info) 117725930707SCorey Minyard return 0; 117825930707SCorey Minyard 117925930707SCorey Minyard /* 118025930707SCorey Minyard * After this point, we won't deliver anything asychronously 118125930707SCorey Minyard * to the message handler. We can unregister ourself. 118225930707SCorey Minyard */ 118325930707SCorey Minyard rv = ipmi_unregister_smi(ssif_info->intf); 118425930707SCorey Minyard if (rv) { 118525930707SCorey Minyard pr_err(PFX "Unable to unregister device: errno=%d\n", rv); 118625930707SCorey Minyard return rv; 118725930707SCorey Minyard } 118825930707SCorey Minyard ssif_info->intf = NULL; 118925930707SCorey Minyard 119025930707SCorey Minyard /* make sure the driver is not looking for flags any more. */ 119125930707SCorey Minyard while (ssif_info->ssif_state != SSIF_NORMAL) 119225930707SCorey Minyard schedule_timeout(1); 119325930707SCorey Minyard 119425930707SCorey Minyard ssif_info->stopping = true; 119525930707SCorey Minyard del_timer_sync(&ssif_info->retry_timer); 119625930707SCorey Minyard if (ssif_info->thread) { 119725930707SCorey Minyard complete(&ssif_info->wake_thread); 119825930707SCorey Minyard kthread_stop(ssif_info->thread); 119925930707SCorey Minyard } 120025930707SCorey Minyard 120125930707SCorey Minyard /* 120225930707SCorey Minyard * No message can be outstanding now, we have removed the 120325930707SCorey Minyard * upper layer and it permitted us to do so. 120425930707SCorey Minyard */ 120525930707SCorey Minyard kfree(ssif_info); 120625930707SCorey Minyard return 0; 120725930707SCorey Minyard } 120825930707SCorey Minyard 120925930707SCorey Minyard static int do_cmd(struct i2c_client *client, int len, unsigned char *msg, 121025930707SCorey Minyard int *resp_len, unsigned char *resp) 121125930707SCorey Minyard { 121225930707SCorey Minyard int retry_cnt; 121325930707SCorey Minyard int ret; 121425930707SCorey Minyard 121525930707SCorey Minyard retry_cnt = SSIF_SEND_RETRIES; 121625930707SCorey Minyard retry1: 121725930707SCorey Minyard ret = i2c_smbus_write_block_data(client, SSIF_IPMI_REQUEST, len, msg); 121825930707SCorey Minyard if (ret) { 121925930707SCorey Minyard retry_cnt--; 122025930707SCorey Minyard if (retry_cnt > 0) 122125930707SCorey Minyard goto retry1; 122225930707SCorey Minyard return -ENODEV; 122325930707SCorey Minyard } 122425930707SCorey Minyard 122525930707SCorey Minyard ret = -ENODEV; 122625930707SCorey Minyard retry_cnt = SSIF_RECV_RETRIES; 122725930707SCorey Minyard while (retry_cnt > 0) { 122825930707SCorey Minyard ret = i2c_smbus_read_block_data(client, SSIF_IPMI_RESPONSE, 122925930707SCorey Minyard resp); 123025930707SCorey Minyard if (ret > 0) 123125930707SCorey Minyard break; 123225930707SCorey Minyard msleep(SSIF_MSG_MSEC); 123325930707SCorey Minyard retry_cnt--; 123425930707SCorey Minyard if (retry_cnt <= 0) 123525930707SCorey Minyard break; 123625930707SCorey Minyard } 123725930707SCorey Minyard 123825930707SCorey Minyard if (ret > 0) { 123925930707SCorey Minyard /* Validate that the response is correct. */ 124025930707SCorey Minyard if (ret < 3 || 124125930707SCorey Minyard (resp[0] != (msg[0] | (1 << 2))) || 124225930707SCorey Minyard (resp[1] != msg[1])) 124325930707SCorey Minyard ret = -EINVAL; 124425930707SCorey Minyard else { 124525930707SCorey Minyard *resp_len = ret; 124625930707SCorey Minyard ret = 0; 124725930707SCorey Minyard } 124825930707SCorey Minyard } 124925930707SCorey Minyard 125025930707SCorey Minyard return ret; 125125930707SCorey Minyard } 125225930707SCorey Minyard 125325930707SCorey Minyard static int ssif_detect(struct i2c_client *client, struct i2c_board_info *info) 125425930707SCorey Minyard { 125525930707SCorey Minyard unsigned char *resp; 125625930707SCorey Minyard unsigned char msg[3]; 125725930707SCorey Minyard int rv; 125825930707SCorey Minyard int len; 125925930707SCorey Minyard 126025930707SCorey Minyard resp = kmalloc(IPMI_MAX_MSG_LENGTH, GFP_KERNEL); 126125930707SCorey Minyard if (!resp) 126225930707SCorey Minyard return -ENOMEM; 126325930707SCorey Minyard 126425930707SCorey Minyard /* Do a Get Device ID command, since it is required. */ 126525930707SCorey Minyard msg[0] = IPMI_NETFN_APP_REQUEST << 2; 126625930707SCorey Minyard msg[1] = IPMI_GET_DEVICE_ID_CMD; 126725930707SCorey Minyard rv = do_cmd(client, 2, msg, &len, resp); 126825930707SCorey Minyard if (rv) 126925930707SCorey Minyard rv = -ENODEV; 127025930707SCorey Minyard else 127125930707SCorey Minyard strlcpy(info->type, DEVICE_NAME, I2C_NAME_SIZE); 127225930707SCorey Minyard kfree(resp); 127325930707SCorey Minyard return rv; 127425930707SCorey Minyard } 127525930707SCorey Minyard 127625930707SCorey Minyard static int smi_type_proc_show(struct seq_file *m, void *v) 127725930707SCorey Minyard { 1278d6c5dc18SJoe Perches seq_puts(m, "ssif\n"); 1279d6c5dc18SJoe Perches 12805e33cd0cSJoe Perches return 0; 128125930707SCorey Minyard } 128225930707SCorey Minyard 128325930707SCorey Minyard static int smi_type_proc_open(struct inode *inode, struct file *file) 128425930707SCorey Minyard { 128525930707SCorey Minyard return single_open(file, smi_type_proc_show, inode->i_private); 128625930707SCorey Minyard } 128725930707SCorey Minyard 128825930707SCorey Minyard static const struct file_operations smi_type_proc_ops = { 128925930707SCorey Minyard .open = smi_type_proc_open, 129025930707SCorey Minyard .read = seq_read, 129125930707SCorey Minyard .llseek = seq_lseek, 129225930707SCorey Minyard .release = single_release, 129325930707SCorey Minyard }; 129425930707SCorey Minyard 129525930707SCorey Minyard static int smi_stats_proc_show(struct seq_file *m, void *v) 129625930707SCorey Minyard { 129725930707SCorey Minyard struct ssif_info *ssif_info = m->private; 129825930707SCorey Minyard 129925930707SCorey Minyard seq_printf(m, "sent_messages: %u\n", 130025930707SCorey Minyard ssif_get_stat(ssif_info, sent_messages)); 130125930707SCorey Minyard seq_printf(m, "sent_messages_parts: %u\n", 130225930707SCorey Minyard ssif_get_stat(ssif_info, sent_messages_parts)); 130325930707SCorey Minyard seq_printf(m, "send_retries: %u\n", 130425930707SCorey Minyard ssif_get_stat(ssif_info, send_retries)); 130525930707SCorey Minyard seq_printf(m, "send_errors: %u\n", 130625930707SCorey Minyard ssif_get_stat(ssif_info, send_errors)); 130725930707SCorey Minyard seq_printf(m, "received_messages: %u\n", 130825930707SCorey Minyard ssif_get_stat(ssif_info, received_messages)); 130925930707SCorey Minyard seq_printf(m, "received_message_parts: %u\n", 131025930707SCorey Minyard ssif_get_stat(ssif_info, received_message_parts)); 131125930707SCorey Minyard seq_printf(m, "receive_retries: %u\n", 131225930707SCorey Minyard ssif_get_stat(ssif_info, receive_retries)); 131325930707SCorey Minyard seq_printf(m, "receive_errors: %u\n", 131425930707SCorey Minyard ssif_get_stat(ssif_info, receive_errors)); 131525930707SCorey Minyard seq_printf(m, "flag_fetches: %u\n", 131625930707SCorey Minyard ssif_get_stat(ssif_info, flag_fetches)); 131725930707SCorey Minyard seq_printf(m, "hosed: %u\n", 131825930707SCorey Minyard ssif_get_stat(ssif_info, hosed)); 131925930707SCorey Minyard seq_printf(m, "events: %u\n", 132025930707SCorey Minyard ssif_get_stat(ssif_info, events)); 132125930707SCorey Minyard seq_printf(m, "watchdog_pretimeouts: %u\n", 132225930707SCorey Minyard ssif_get_stat(ssif_info, watchdog_pretimeouts)); 132391620521SCorey Minyard seq_printf(m, "alerts: %u\n", 132491620521SCorey Minyard ssif_get_stat(ssif_info, alerts)); 132525930707SCorey Minyard return 0; 132625930707SCorey Minyard } 132725930707SCorey Minyard 132825930707SCorey Minyard static int smi_stats_proc_open(struct inode *inode, struct file *file) 132925930707SCorey Minyard { 133025930707SCorey Minyard return single_open(file, smi_stats_proc_show, PDE_DATA(inode)); 133125930707SCorey Minyard } 133225930707SCorey Minyard 133325930707SCorey Minyard static const struct file_operations smi_stats_proc_ops = { 133425930707SCorey Minyard .open = smi_stats_proc_open, 133525930707SCorey Minyard .read = seq_read, 133625930707SCorey Minyard .llseek = seq_lseek, 133725930707SCorey Minyard .release = single_release, 133825930707SCorey Minyard }; 133925930707SCorey Minyard 1340b0e9aaa9SCorey Minyard static int strcmp_nospace(char *s1, char *s2) 1341b0e9aaa9SCorey Minyard { 1342b0e9aaa9SCorey Minyard while (*s1 && *s2) { 1343b0e9aaa9SCorey Minyard while (isspace(*s1)) 1344b0e9aaa9SCorey Minyard s1++; 1345b0e9aaa9SCorey Minyard while (isspace(*s2)) 1346b0e9aaa9SCorey Minyard s2++; 1347b0e9aaa9SCorey Minyard if (*s1 > *s2) 1348b0e9aaa9SCorey Minyard return 1; 1349b0e9aaa9SCorey Minyard if (*s1 < *s2) 1350b0e9aaa9SCorey Minyard return -1; 1351b0e9aaa9SCorey Minyard s1++; 1352b0e9aaa9SCorey Minyard s2++; 1353b0e9aaa9SCorey Minyard } 1354b0e9aaa9SCorey Minyard return 0; 1355b0e9aaa9SCorey Minyard } 1356b0e9aaa9SCorey Minyard 135725930707SCorey Minyard static struct ssif_addr_info *ssif_info_find(unsigned short addr, 135825930707SCorey Minyard char *adapter_name, 135925930707SCorey Minyard bool match_null_name) 136025930707SCorey Minyard { 136125930707SCorey Minyard struct ssif_addr_info *info, *found = NULL; 136225930707SCorey Minyard 136325930707SCorey Minyard restart: 136425930707SCorey Minyard list_for_each_entry(info, &ssif_infos, link) { 136525930707SCorey Minyard if (info->binfo.addr == addr) { 136625930707SCorey Minyard if (info->adapter_name || adapter_name) { 136725930707SCorey Minyard if (!info->adapter_name != !adapter_name) { 136825930707SCorey Minyard /* One is NULL and one is not */ 136925930707SCorey Minyard continue; 137025930707SCorey Minyard } 1371b0e9aaa9SCorey Minyard if (adapter_name && 1372b0e9aaa9SCorey Minyard strcmp_nospace(info->adapter_name, 1373b0e9aaa9SCorey Minyard adapter_name)) 1374b0e9aaa9SCorey Minyard /* Names do not match */ 137525930707SCorey Minyard continue; 137625930707SCorey Minyard } 137725930707SCorey Minyard found = info; 137825930707SCorey Minyard break; 137925930707SCorey Minyard } 138025930707SCorey Minyard } 138125930707SCorey Minyard 138225930707SCorey Minyard if (!found && match_null_name) { 138325930707SCorey Minyard /* Try to get an exact match first, then try with a NULL name */ 138425930707SCorey Minyard adapter_name = NULL; 138525930707SCorey Minyard match_null_name = false; 138625930707SCorey Minyard goto restart; 138725930707SCorey Minyard } 138825930707SCorey Minyard 138925930707SCorey Minyard return found; 139025930707SCorey Minyard } 139125930707SCorey Minyard 139225930707SCorey Minyard static bool check_acpi(struct ssif_info *ssif_info, struct device *dev) 139325930707SCorey Minyard { 139425930707SCorey Minyard #ifdef CONFIG_ACPI 139525930707SCorey Minyard acpi_handle acpi_handle; 139625930707SCorey Minyard 139725930707SCorey Minyard acpi_handle = ACPI_HANDLE(dev); 139825930707SCorey Minyard if (acpi_handle) { 139925930707SCorey Minyard ssif_info->addr_source = SI_ACPI; 140025930707SCorey Minyard ssif_info->addr_info.acpi_info.acpi_handle = acpi_handle; 140125930707SCorey Minyard return true; 140225930707SCorey Minyard } 140325930707SCorey Minyard #endif 140425930707SCorey Minyard return false; 140525930707SCorey Minyard } 140625930707SCorey Minyard 140794671710SCorey Minyard static int find_slave_address(struct i2c_client *client, int slave_addr) 140894671710SCorey Minyard { 140994671710SCorey Minyard struct ssif_addr_info *info; 141094671710SCorey Minyard 141194671710SCorey Minyard if (slave_addr) 141294671710SCorey Minyard return slave_addr; 141394671710SCorey Minyard 141494671710SCorey Minyard /* 141594671710SCorey Minyard * Came in without a slave address, search around to see if 141694671710SCorey Minyard * the other sources have a slave address. This lets us pick 141794671710SCorey Minyard * up an SMBIOS slave address when using ACPI. 141894671710SCorey Minyard */ 141994671710SCorey Minyard list_for_each_entry(info, &ssif_infos, link) { 142094671710SCorey Minyard if (info->binfo.addr != client->addr) 142194671710SCorey Minyard continue; 1422bf10ff69SColin Ian King if (info->adapter_name && strcmp_nospace(info->adapter_name, 142394671710SCorey Minyard client->adapter->name)) 142494671710SCorey Minyard continue; 142594671710SCorey Minyard if (info->slave_addr) { 142694671710SCorey Minyard slave_addr = info->slave_addr; 142794671710SCorey Minyard break; 142894671710SCorey Minyard } 142994671710SCorey Minyard } 143094671710SCorey Minyard 143194671710SCorey Minyard return slave_addr; 143294671710SCorey Minyard } 143394671710SCorey Minyard 143491620521SCorey Minyard /* 143591620521SCorey Minyard * Global enables we care about. 143691620521SCorey Minyard */ 143791620521SCorey Minyard #define GLOBAL_ENABLES_MASK (IPMI_BMC_EVT_MSG_BUFF | IPMI_BMC_RCV_MSG_INTR | \ 143891620521SCorey Minyard IPMI_BMC_EVT_MSG_INTR) 143991620521SCorey Minyard 144025930707SCorey Minyard static int ssif_probe(struct i2c_client *client, const struct i2c_device_id *id) 144125930707SCorey Minyard { 144225930707SCorey Minyard unsigned char msg[3]; 144325930707SCorey Minyard unsigned char *resp; 144425930707SCorey Minyard struct ssif_info *ssif_info; 144525930707SCorey Minyard int rv = 0; 144625930707SCorey Minyard int len; 144725930707SCorey Minyard int i; 144825930707SCorey Minyard u8 slave_addr = 0; 144925930707SCorey Minyard struct ssif_addr_info *addr_info = NULL; 145025930707SCorey Minyard 145125930707SCorey Minyard 145225930707SCorey Minyard resp = kmalloc(IPMI_MAX_MSG_LENGTH, GFP_KERNEL); 145325930707SCorey Minyard if (!resp) 145425930707SCorey Minyard return -ENOMEM; 145525930707SCorey Minyard 145625930707SCorey Minyard ssif_info = kzalloc(sizeof(*ssif_info), GFP_KERNEL); 145725930707SCorey Minyard if (!ssif_info) { 145825930707SCorey Minyard kfree(resp); 145925930707SCorey Minyard return -ENOMEM; 146025930707SCorey Minyard } 146125930707SCorey Minyard 146225930707SCorey Minyard if (!check_acpi(ssif_info, &client->dev)) { 146325930707SCorey Minyard addr_info = ssif_info_find(client->addr, client->adapter->name, 146425930707SCorey Minyard true); 146525930707SCorey Minyard if (!addr_info) { 146625930707SCorey Minyard /* Must have come in through sysfs. */ 146725930707SCorey Minyard ssif_info->addr_source = SI_HOTMOD; 146825930707SCorey Minyard } else { 146925930707SCorey Minyard ssif_info->addr_source = addr_info->addr_src; 147025930707SCorey Minyard ssif_info->ssif_debug = addr_info->debug; 147125930707SCorey Minyard ssif_info->addr_info = addr_info->addr_info; 147225930707SCorey Minyard slave_addr = addr_info->slave_addr; 147325930707SCorey Minyard } 147425930707SCorey Minyard } 147525930707SCorey Minyard 147694671710SCorey Minyard slave_addr = find_slave_address(client, slave_addr); 147794671710SCorey Minyard 147825930707SCorey Minyard pr_info(PFX "Trying %s-specified SSIF interface at i2c address 0x%x, adapter %s, slave address 0x%x\n", 147925930707SCorey Minyard ipmi_addr_src_to_str(ssif_info->addr_source), 148025930707SCorey Minyard client->addr, client->adapter->name, slave_addr); 148125930707SCorey Minyard 148225930707SCorey Minyard /* 148325930707SCorey Minyard * Do a Get Device ID command, since it comes back with some 148425930707SCorey Minyard * useful info. 148525930707SCorey Minyard */ 148625930707SCorey Minyard msg[0] = IPMI_NETFN_APP_REQUEST << 2; 148725930707SCorey Minyard msg[1] = IPMI_GET_DEVICE_ID_CMD; 148825930707SCorey Minyard rv = do_cmd(client, 2, msg, &len, resp); 148925930707SCorey Minyard if (rv) 149025930707SCorey Minyard goto out; 149125930707SCorey Minyard 149225930707SCorey Minyard rv = ipmi_demangle_device_id(resp, len, &ssif_info->device_id); 149325930707SCorey Minyard if (rv) 149425930707SCorey Minyard goto out; 149525930707SCorey Minyard 149625930707SCorey Minyard ssif_info->client = client; 149725930707SCorey Minyard i2c_set_clientdata(client, ssif_info); 149825930707SCorey Minyard 149925930707SCorey Minyard /* Now check for system interface capabilities */ 150025930707SCorey Minyard msg[0] = IPMI_NETFN_APP_REQUEST << 2; 150125930707SCorey Minyard msg[1] = IPMI_GET_SYSTEM_INTERFACE_CAPABILITIES_CMD; 150225930707SCorey Minyard msg[2] = 0; /* SSIF */ 150325930707SCorey Minyard rv = do_cmd(client, 3, msg, &len, resp); 150425930707SCorey Minyard if (!rv && (len >= 3) && (resp[2] == 0)) { 150525930707SCorey Minyard if (len < 7) { 150625930707SCorey Minyard if (ssif_dbg_probe) 150725930707SCorey Minyard pr_info(PFX "SSIF info too short: %d\n", len); 150825930707SCorey Minyard goto no_support; 150925930707SCorey Minyard } 151025930707SCorey Minyard 151125930707SCorey Minyard /* Got a good SSIF response, handle it. */ 151225930707SCorey Minyard ssif_info->max_xmit_msg_size = resp[5]; 151325930707SCorey Minyard ssif_info->max_recv_msg_size = resp[6]; 151425930707SCorey Minyard ssif_info->multi_support = (resp[4] >> 6) & 0x3; 151525930707SCorey Minyard ssif_info->supports_pec = (resp[4] >> 3) & 0x1; 151625930707SCorey Minyard 151725930707SCorey Minyard /* Sanitize the data */ 151825930707SCorey Minyard switch (ssif_info->multi_support) { 151925930707SCorey Minyard case SSIF_NO_MULTI: 152025930707SCorey Minyard if (ssif_info->max_xmit_msg_size > 32) 152125930707SCorey Minyard ssif_info->max_xmit_msg_size = 32; 152225930707SCorey Minyard if (ssif_info->max_recv_msg_size > 32) 152325930707SCorey Minyard ssif_info->max_recv_msg_size = 32; 152425930707SCorey Minyard break; 152525930707SCorey Minyard 152625930707SCorey Minyard case SSIF_MULTI_2_PART: 15273d69d43bSCorey Minyard if (ssif_info->max_xmit_msg_size > 63) 15283d69d43bSCorey Minyard ssif_info->max_xmit_msg_size = 63; 152925930707SCorey Minyard if (ssif_info->max_recv_msg_size > 62) 153025930707SCorey Minyard ssif_info->max_recv_msg_size = 62; 153125930707SCorey Minyard break; 153225930707SCorey Minyard 153325930707SCorey Minyard case SSIF_MULTI_n_PART: 15343d69d43bSCorey Minyard /* 15353d69d43bSCorey Minyard * The specification is rather confusing at 15363d69d43bSCorey Minyard * this point, but I think I understand what 15373d69d43bSCorey Minyard * is meant. At least I have a workable 15383d69d43bSCorey Minyard * solution. With multi-part messages, you 15393d69d43bSCorey Minyard * cannot send a message that is a multiple of 15403d69d43bSCorey Minyard * 32-bytes in length, because the start and 15413d69d43bSCorey Minyard * middle messages are 32-bytes and the end 15423d69d43bSCorey Minyard * message must be at least one byte. You 15433d69d43bSCorey Minyard * can't fudge on an extra byte, that would 15443d69d43bSCorey Minyard * screw up things like fru data writes. So 15453d69d43bSCorey Minyard * we limit the length to 63 bytes. That way 15463d69d43bSCorey Minyard * a 32-byte message gets sent as a single 15473d69d43bSCorey Minyard * part. A larger message will be a 32-byte 15483d69d43bSCorey Minyard * start and the next message is always going 15493d69d43bSCorey Minyard * to be 1-31 bytes in length. Not ideal, but 15503d69d43bSCorey Minyard * it should work. 15513d69d43bSCorey Minyard */ 15523d69d43bSCorey Minyard if (ssif_info->max_xmit_msg_size > 63) 15533d69d43bSCorey Minyard ssif_info->max_xmit_msg_size = 63; 155425930707SCorey Minyard break; 155525930707SCorey Minyard 155625930707SCorey Minyard default: 155725930707SCorey Minyard /* Data is not sane, just give up. */ 155825930707SCorey Minyard goto no_support; 155925930707SCorey Minyard } 156025930707SCorey Minyard } else { 156125930707SCorey Minyard no_support: 156225930707SCorey Minyard /* Assume no multi-part or PEC support */ 156325930707SCorey Minyard pr_info(PFX "Error fetching SSIF: %d %d %2.2x, your system probably doesn't support this command so using defaults\n", 156425930707SCorey Minyard rv, len, resp[2]); 156525930707SCorey Minyard 156625930707SCorey Minyard ssif_info->max_xmit_msg_size = 32; 156725930707SCorey Minyard ssif_info->max_recv_msg_size = 32; 156825930707SCorey Minyard ssif_info->multi_support = SSIF_NO_MULTI; 156925930707SCorey Minyard ssif_info->supports_pec = 0; 157025930707SCorey Minyard } 157125930707SCorey Minyard 157225930707SCorey Minyard /* Make sure the NMI timeout is cleared. */ 157325930707SCorey Minyard msg[0] = IPMI_NETFN_APP_REQUEST << 2; 157425930707SCorey Minyard msg[1] = IPMI_CLEAR_MSG_FLAGS_CMD; 157525930707SCorey Minyard msg[2] = WDT_PRE_TIMEOUT_INT; 157625930707SCorey Minyard rv = do_cmd(client, 3, msg, &len, resp); 157725930707SCorey Minyard if (rv || (len < 3) || (resp[2] != 0)) 157825930707SCorey Minyard pr_warn(PFX "Unable to clear message flags: %d %d %2.2x\n", 157925930707SCorey Minyard rv, len, resp[2]); 158025930707SCorey Minyard 158125930707SCorey Minyard /* Attempt to enable the event buffer. */ 158225930707SCorey Minyard msg[0] = IPMI_NETFN_APP_REQUEST << 2; 158325930707SCorey Minyard msg[1] = IPMI_GET_BMC_GLOBAL_ENABLES_CMD; 158425930707SCorey Minyard rv = do_cmd(client, 2, msg, &len, resp); 158525930707SCorey Minyard if (rv || (len < 4) || (resp[2] != 0)) { 158625930707SCorey Minyard pr_warn(PFX "Error getting global enables: %d %d %2.2x\n", 158725930707SCorey Minyard rv, len, resp[2]); 158825930707SCorey Minyard rv = 0; /* Not fatal */ 158925930707SCorey Minyard goto found; 159025930707SCorey Minyard } 159125930707SCorey Minyard 159291620521SCorey Minyard ssif_info->global_enables = resp[3]; 159391620521SCorey Minyard 159425930707SCorey Minyard if (resp[3] & IPMI_BMC_EVT_MSG_BUFF) { 159525930707SCorey Minyard ssif_info->has_event_buffer = true; 159625930707SCorey Minyard /* buffer is already enabled, nothing to do. */ 159725930707SCorey Minyard goto found; 159825930707SCorey Minyard } 159925930707SCorey Minyard 160025930707SCorey Minyard msg[0] = IPMI_NETFN_APP_REQUEST << 2; 160125930707SCorey Minyard msg[1] = IPMI_SET_BMC_GLOBAL_ENABLES_CMD; 160291620521SCorey Minyard msg[2] = ssif_info->global_enables | IPMI_BMC_EVT_MSG_BUFF; 160325930707SCorey Minyard rv = do_cmd(client, 3, msg, &len, resp); 160425930707SCorey Minyard if (rv || (len < 2)) { 160591620521SCorey Minyard pr_warn(PFX "Error setting global enables: %d %d %2.2x\n", 160625930707SCorey Minyard rv, len, resp[2]); 160725930707SCorey Minyard rv = 0; /* Not fatal */ 160825930707SCorey Minyard goto found; 160925930707SCorey Minyard } 161025930707SCorey Minyard 161191620521SCorey Minyard if (resp[2] == 0) { 161225930707SCorey Minyard /* A successful return means the event buffer is supported. */ 161325930707SCorey Minyard ssif_info->has_event_buffer = true; 161491620521SCorey Minyard ssif_info->global_enables |= IPMI_BMC_EVT_MSG_BUFF; 161591620521SCorey Minyard } 161691620521SCorey Minyard 1617bf2d0877SCorey Minyard /* Some systems don't behave well if you enable alerts. */ 1618bf2d0877SCorey Minyard if (alerts_broken) 1619bf2d0877SCorey Minyard goto found; 1620bf2d0877SCorey Minyard 162191620521SCorey Minyard msg[0] = IPMI_NETFN_APP_REQUEST << 2; 162291620521SCorey Minyard msg[1] = IPMI_SET_BMC_GLOBAL_ENABLES_CMD; 162391620521SCorey Minyard msg[2] = ssif_info->global_enables | IPMI_BMC_RCV_MSG_INTR; 162491620521SCorey Minyard rv = do_cmd(client, 3, msg, &len, resp); 162591620521SCorey Minyard if (rv || (len < 2)) { 162691620521SCorey Minyard pr_warn(PFX "Error setting global enables: %d %d %2.2x\n", 162791620521SCorey Minyard rv, len, resp[2]); 162891620521SCorey Minyard rv = 0; /* Not fatal */ 162991620521SCorey Minyard goto found; 163091620521SCorey Minyard } 163191620521SCorey Minyard 163291620521SCorey Minyard if (resp[2] == 0) { 163391620521SCorey Minyard /* A successful return means the alert is supported. */ 163491620521SCorey Minyard ssif_info->supports_alert = true; 163591620521SCorey Minyard ssif_info->global_enables |= IPMI_BMC_RCV_MSG_INTR; 163691620521SCorey Minyard } 163725930707SCorey Minyard 163825930707SCorey Minyard found: 163925930707SCorey Minyard ssif_info->intf_num = atomic_inc_return(&next_intf); 164025930707SCorey Minyard 164125930707SCorey Minyard if (ssif_dbg_probe) { 164225930707SCorey Minyard pr_info("ssif_probe: i2c_probe found device at i2c address %x\n", 164325930707SCorey Minyard client->addr); 164425930707SCorey Minyard } 164525930707SCorey Minyard 164625930707SCorey Minyard spin_lock_init(&ssif_info->lock); 164725930707SCorey Minyard ssif_info->ssif_state = SSIF_NORMAL; 164836cb82daSGeliang Tang setup_timer(&ssif_info->retry_timer, retry_timeout, 164936cb82daSGeliang Tang (unsigned long)ssif_info); 165025930707SCorey Minyard 165125930707SCorey Minyard for (i = 0; i < SSIF_NUM_STATS; i++) 165225930707SCorey Minyard atomic_set(&ssif_info->stats[i], 0); 165325930707SCorey Minyard 165425930707SCorey Minyard if (ssif_info->supports_pec) 165525930707SCorey Minyard ssif_info->client->flags |= I2C_CLIENT_PEC; 165625930707SCorey Minyard 165725930707SCorey Minyard ssif_info->handlers.owner = THIS_MODULE; 165825930707SCorey Minyard ssif_info->handlers.start_processing = ssif_start_processing; 165925930707SCorey Minyard ssif_info->handlers.get_smi_info = get_smi_info; 166025930707SCorey Minyard ssif_info->handlers.sender = sender; 166125930707SCorey Minyard ssif_info->handlers.request_events = request_events; 166225930707SCorey Minyard ssif_info->handlers.inc_usecount = inc_usecount; 166325930707SCorey Minyard ssif_info->handlers.dec_usecount = dec_usecount; 166425930707SCorey Minyard 166525930707SCorey Minyard { 166625930707SCorey Minyard unsigned int thread_num; 166725930707SCorey Minyard 1668be8647d2SCorey Minyard thread_num = ((i2c_adapter_id(ssif_info->client->adapter) 1669be8647d2SCorey Minyard << 8) | 167025930707SCorey Minyard ssif_info->client->addr); 167125930707SCorey Minyard init_completion(&ssif_info->wake_thread); 167225930707SCorey Minyard ssif_info->thread = kthread_run(ipmi_ssif_thread, ssif_info, 167325930707SCorey Minyard "kssif%4.4x", thread_num); 167425930707SCorey Minyard if (IS_ERR(ssif_info->thread)) { 167525930707SCorey Minyard rv = PTR_ERR(ssif_info->thread); 167625930707SCorey Minyard dev_notice(&ssif_info->client->dev, 167725930707SCorey Minyard "Could not start kernel thread: error %d\n", 167825930707SCorey Minyard rv); 167925930707SCorey Minyard goto out; 168025930707SCorey Minyard } 168125930707SCorey Minyard } 168225930707SCorey Minyard 168325930707SCorey Minyard rv = ipmi_register_smi(&ssif_info->handlers, 168425930707SCorey Minyard ssif_info, 168525930707SCorey Minyard &ssif_info->device_id, 168625930707SCorey Minyard &ssif_info->client->dev, 168725930707SCorey Minyard slave_addr); 168825930707SCorey Minyard if (rv) { 168925930707SCorey Minyard pr_err(PFX "Unable to register device: error %d\n", rv); 169025930707SCorey Minyard goto out; 169125930707SCorey Minyard } 169225930707SCorey Minyard 169325930707SCorey Minyard rv = ipmi_smi_add_proc_entry(ssif_info->intf, "type", 169425930707SCorey Minyard &smi_type_proc_ops, 169525930707SCorey Minyard ssif_info); 169625930707SCorey Minyard if (rv) { 169725930707SCorey Minyard pr_err(PFX "Unable to create proc entry: %d\n", rv); 169825930707SCorey Minyard goto out_err_unreg; 169925930707SCorey Minyard } 170025930707SCorey Minyard 170125930707SCorey Minyard rv = ipmi_smi_add_proc_entry(ssif_info->intf, "ssif_stats", 170225930707SCorey Minyard &smi_stats_proc_ops, 170325930707SCorey Minyard ssif_info); 170425930707SCorey Minyard if (rv) { 170525930707SCorey Minyard pr_err(PFX "Unable to create proc entry: %d\n", rv); 170625930707SCorey Minyard goto out_err_unreg; 170725930707SCorey Minyard } 170825930707SCorey Minyard 170925930707SCorey Minyard out: 171025930707SCorey Minyard if (rv) 171125930707SCorey Minyard kfree(ssif_info); 171225930707SCorey Minyard kfree(resp); 171325930707SCorey Minyard return rv; 171425930707SCorey Minyard 171525930707SCorey Minyard out_err_unreg: 171625930707SCorey Minyard ipmi_unregister_smi(ssif_info->intf); 171725930707SCorey Minyard goto out; 171825930707SCorey Minyard } 171925930707SCorey Minyard 172025930707SCorey Minyard static int ssif_adapter_handler(struct device *adev, void *opaque) 172125930707SCorey Minyard { 172225930707SCorey Minyard struct ssif_addr_info *addr_info = opaque; 172325930707SCorey Minyard 172425930707SCorey Minyard if (adev->type != &i2c_adapter_type) 172525930707SCorey Minyard return 0; 172625930707SCorey Minyard 172725930707SCorey Minyard i2c_new_device(to_i2c_adapter(adev), &addr_info->binfo); 172825930707SCorey Minyard 172925930707SCorey Minyard if (!addr_info->adapter_name) 173025930707SCorey Minyard return 1; /* Only try the first I2C adapter by default. */ 173125930707SCorey Minyard return 0; 173225930707SCorey Minyard } 173325930707SCorey Minyard 173425930707SCorey Minyard static int new_ssif_client(int addr, char *adapter_name, 173525930707SCorey Minyard int debug, int slave_addr, 173625930707SCorey Minyard enum ipmi_addr_src addr_src) 173725930707SCorey Minyard { 173825930707SCorey Minyard struct ssif_addr_info *addr_info; 173925930707SCorey Minyard int rv = 0; 174025930707SCorey Minyard 174125930707SCorey Minyard mutex_lock(&ssif_infos_mutex); 174225930707SCorey Minyard if (ssif_info_find(addr, adapter_name, false)) { 174325930707SCorey Minyard rv = -EEXIST; 174425930707SCorey Minyard goto out_unlock; 174525930707SCorey Minyard } 174625930707SCorey Minyard 174725930707SCorey Minyard addr_info = kzalloc(sizeof(*addr_info), GFP_KERNEL); 174825930707SCorey Minyard if (!addr_info) { 174925930707SCorey Minyard rv = -ENOMEM; 175025930707SCorey Minyard goto out_unlock; 175125930707SCorey Minyard } 175225930707SCorey Minyard 175325930707SCorey Minyard if (adapter_name) { 175425930707SCorey Minyard addr_info->adapter_name = kstrdup(adapter_name, GFP_KERNEL); 175525930707SCorey Minyard if (!addr_info->adapter_name) { 175625930707SCorey Minyard kfree(addr_info); 175725930707SCorey Minyard rv = -ENOMEM; 175825930707SCorey Minyard goto out_unlock; 175925930707SCorey Minyard } 176025930707SCorey Minyard } 176125930707SCorey Minyard 176225930707SCorey Minyard strncpy(addr_info->binfo.type, DEVICE_NAME, 176325930707SCorey Minyard sizeof(addr_info->binfo.type)); 176425930707SCorey Minyard addr_info->binfo.addr = addr; 176525930707SCorey Minyard addr_info->binfo.platform_data = addr_info; 176625930707SCorey Minyard addr_info->debug = debug; 176725930707SCorey Minyard addr_info->slave_addr = slave_addr; 176825930707SCorey Minyard addr_info->addr_src = addr_src; 176925930707SCorey Minyard 177025930707SCorey Minyard list_add_tail(&addr_info->link, &ssif_infos); 177125930707SCorey Minyard 177225930707SCorey Minyard if (initialized) 177325930707SCorey Minyard i2c_for_each_dev(addr_info, ssif_adapter_handler); 177425930707SCorey Minyard /* Otherwise address list will get it */ 177525930707SCorey Minyard 177625930707SCorey Minyard out_unlock: 177725930707SCorey Minyard mutex_unlock(&ssif_infos_mutex); 177825930707SCorey Minyard return rv; 177925930707SCorey Minyard } 178025930707SCorey Minyard 178125930707SCorey Minyard static void free_ssif_clients(void) 178225930707SCorey Minyard { 178325930707SCorey Minyard struct ssif_addr_info *info, *tmp; 178425930707SCorey Minyard 178525930707SCorey Minyard mutex_lock(&ssif_infos_mutex); 178625930707SCorey Minyard list_for_each_entry_safe(info, tmp, &ssif_infos, link) { 178725930707SCorey Minyard list_del(&info->link); 178825930707SCorey Minyard kfree(info->adapter_name); 178925930707SCorey Minyard kfree(info); 179025930707SCorey Minyard } 179125930707SCorey Minyard mutex_unlock(&ssif_infos_mutex); 179225930707SCorey Minyard } 179325930707SCorey Minyard 179425930707SCorey Minyard static unsigned short *ssif_address_list(void) 179525930707SCorey Minyard { 179625930707SCorey Minyard struct ssif_addr_info *info; 179725930707SCorey Minyard unsigned int count = 0, i; 179825930707SCorey Minyard unsigned short *address_list; 179925930707SCorey Minyard 180025930707SCorey Minyard list_for_each_entry(info, &ssif_infos, link) 180125930707SCorey Minyard count++; 180225930707SCorey Minyard 180325930707SCorey Minyard address_list = kzalloc(sizeof(*address_list) * (count + 1), GFP_KERNEL); 180425930707SCorey Minyard if (!address_list) 180525930707SCorey Minyard return NULL; 180625930707SCorey Minyard 180725930707SCorey Minyard i = 0; 180825930707SCorey Minyard list_for_each_entry(info, &ssif_infos, link) { 180925930707SCorey Minyard unsigned short addr = info->binfo.addr; 181025930707SCorey Minyard int j; 181125930707SCorey Minyard 181225930707SCorey Minyard for (j = 0; j < i; j++) { 181325930707SCorey Minyard if (address_list[j] == addr) 181425930707SCorey Minyard goto skip_addr; 181525930707SCorey Minyard } 181625930707SCorey Minyard address_list[i] = addr; 181725930707SCorey Minyard skip_addr: 181825930707SCorey Minyard i++; 181925930707SCorey Minyard } 182025930707SCorey Minyard address_list[i] = I2C_CLIENT_END; 182125930707SCorey Minyard 182225930707SCorey Minyard return address_list; 182325930707SCorey Minyard } 182425930707SCorey Minyard 182525930707SCorey Minyard #ifdef CONFIG_ACPI 18265186cf9cSMathias Krause static const struct acpi_device_id ssif_acpi_match[] = { 182725930707SCorey Minyard { "IPI0001", 0 }, 182825930707SCorey Minyard { }, 182925930707SCorey Minyard }; 183025930707SCorey Minyard MODULE_DEVICE_TABLE(acpi, ssif_acpi_match); 183125930707SCorey Minyard 183225930707SCorey Minyard /* 183325930707SCorey Minyard * Once we get an ACPI failure, we don't try any more, because we go 183425930707SCorey Minyard * through the tables sequentially. Once we don't find a table, there 183525930707SCorey Minyard * are no more. 183625930707SCorey Minyard */ 183725930707SCorey Minyard static int acpi_failure; 183825930707SCorey Minyard 183925930707SCorey Minyard /* 184025930707SCorey Minyard * Defined in the IPMI 2.0 spec. 184125930707SCorey Minyard */ 184225930707SCorey Minyard struct SPMITable { 184325930707SCorey Minyard s8 Signature[4]; 184425930707SCorey Minyard u32 Length; 184525930707SCorey Minyard u8 Revision; 184625930707SCorey Minyard u8 Checksum; 184725930707SCorey Minyard s8 OEMID[6]; 184825930707SCorey Minyard s8 OEMTableID[8]; 184925930707SCorey Minyard s8 OEMRevision[4]; 185025930707SCorey Minyard s8 CreatorID[4]; 185125930707SCorey Minyard s8 CreatorRevision[4]; 185225930707SCorey Minyard u8 InterfaceType; 185325930707SCorey Minyard u8 IPMIlegacy; 185425930707SCorey Minyard s16 SpecificationRevision; 185525930707SCorey Minyard 185625930707SCorey Minyard /* 185725930707SCorey Minyard * Bit 0 - SCI interrupt supported 185825930707SCorey Minyard * Bit 1 - I/O APIC/SAPIC 185925930707SCorey Minyard */ 186025930707SCorey Minyard u8 InterruptType; 186125930707SCorey Minyard 186225930707SCorey Minyard /* 186325930707SCorey Minyard * If bit 0 of InterruptType is set, then this is the SCI 186425930707SCorey Minyard * interrupt in the GPEx_STS register. 186525930707SCorey Minyard */ 186625930707SCorey Minyard u8 GPE; 186725930707SCorey Minyard 186825930707SCorey Minyard s16 Reserved; 186925930707SCorey Minyard 187025930707SCorey Minyard /* 187125930707SCorey Minyard * If bit 1 of InterruptType is set, then this is the I/O 187225930707SCorey Minyard * APIC/SAPIC interrupt. 187325930707SCorey Minyard */ 187425930707SCorey Minyard u32 GlobalSystemInterrupt; 187525930707SCorey Minyard 187625930707SCorey Minyard /* The actual register address. */ 187725930707SCorey Minyard struct acpi_generic_address addr; 187825930707SCorey Minyard 187925930707SCorey Minyard u8 UID[4]; 188025930707SCorey Minyard 188125930707SCorey Minyard s8 spmi_id[1]; /* A '\0' terminated array starts here. */ 188225930707SCorey Minyard }; 188325930707SCorey Minyard 188425930707SCorey Minyard static int try_init_spmi(struct SPMITable *spmi) 188525930707SCorey Minyard { 188625930707SCorey Minyard unsigned short myaddr; 188725930707SCorey Minyard 188825930707SCorey Minyard if (num_addrs >= MAX_SSIF_BMCS) 188925930707SCorey Minyard return -1; 189025930707SCorey Minyard 189125930707SCorey Minyard if (spmi->IPMIlegacy != 1) { 189225930707SCorey Minyard pr_warn("IPMI: Bad SPMI legacy: %d\n", spmi->IPMIlegacy); 189325930707SCorey Minyard return -ENODEV; 189425930707SCorey Minyard } 189525930707SCorey Minyard 189625930707SCorey Minyard if (spmi->InterfaceType != 4) 189725930707SCorey Minyard return -ENODEV; 189825930707SCorey Minyard 189925930707SCorey Minyard if (spmi->addr.space_id != ACPI_ADR_SPACE_SMBUS) { 190025930707SCorey Minyard pr_warn(PFX "Invalid ACPI SSIF I/O Address type: %d\n", 190125930707SCorey Minyard spmi->addr.space_id); 190225930707SCorey Minyard return -EIO; 190325930707SCorey Minyard } 190425930707SCorey Minyard 190570f95b76SCorey Minyard myaddr = spmi->addr.address & 0x7f; 190625930707SCorey Minyard 190725930707SCorey Minyard return new_ssif_client(myaddr, NULL, 0, 0, SI_SPMI); 190825930707SCorey Minyard } 190925930707SCorey Minyard 191025930707SCorey Minyard static void spmi_find_bmc(void) 191125930707SCorey Minyard { 191225930707SCorey Minyard acpi_status status; 191325930707SCorey Minyard struct SPMITable *spmi; 191425930707SCorey Minyard int i; 191525930707SCorey Minyard 191625930707SCorey Minyard if (acpi_disabled) 191725930707SCorey Minyard return; 191825930707SCorey Minyard 191925930707SCorey Minyard if (acpi_failure) 192025930707SCorey Minyard return; 192125930707SCorey Minyard 192225930707SCorey Minyard for (i = 0; ; i++) { 192325930707SCorey Minyard status = acpi_get_table(ACPI_SIG_SPMI, i+1, 192425930707SCorey Minyard (struct acpi_table_header **)&spmi); 192525930707SCorey Minyard if (status != AE_OK) 192625930707SCorey Minyard return; 192725930707SCorey Minyard 192825930707SCorey Minyard try_init_spmi(spmi); 192925930707SCorey Minyard } 193025930707SCorey Minyard } 193125930707SCorey Minyard #else 193225930707SCorey Minyard static void spmi_find_bmc(void) { } 193325930707SCorey Minyard #endif 193425930707SCorey Minyard 193525930707SCorey Minyard #ifdef CONFIG_DMI 193625930707SCorey Minyard static int decode_dmi(const struct dmi_device *dmi_dev) 193725930707SCorey Minyard { 193825930707SCorey Minyard struct dmi_header *dm = dmi_dev->device_data; 193925930707SCorey Minyard u8 *data = (u8 *) dm; 194025930707SCorey Minyard u8 len = dm->length; 194125930707SCorey Minyard unsigned short myaddr; 194225930707SCorey Minyard int slave_addr; 194325930707SCorey Minyard 194425930707SCorey Minyard if (num_addrs >= MAX_SSIF_BMCS) 194525930707SCorey Minyard return -1; 194625930707SCorey Minyard 194725930707SCorey Minyard if (len < 9) 194825930707SCorey Minyard return -1; 194925930707SCorey Minyard 195025930707SCorey Minyard if (data[0x04] != 4) /* Not SSIF */ 195125930707SCorey Minyard return -1; 195225930707SCorey Minyard 195325930707SCorey Minyard if ((data[8] >> 1) == 0) { 195425930707SCorey Minyard /* 195525930707SCorey Minyard * Some broken systems put the I2C address in 195625930707SCorey Minyard * the slave address field. We try to 195725930707SCorey Minyard * accommodate them here. 195825930707SCorey Minyard */ 195925930707SCorey Minyard myaddr = data[6] >> 1; 196025930707SCorey Minyard slave_addr = 0; 196125930707SCorey Minyard } else { 196225930707SCorey Minyard myaddr = data[8] >> 1; 196325930707SCorey Minyard slave_addr = data[6]; 196425930707SCorey Minyard } 196525930707SCorey Minyard 196694671710SCorey Minyard return new_ssif_client(myaddr, NULL, 0, slave_addr, SI_SMBIOS); 196725930707SCorey Minyard } 196825930707SCorey Minyard 196925930707SCorey Minyard static void dmi_iterator(void) 197025930707SCorey Minyard { 197125930707SCorey Minyard const struct dmi_device *dev = NULL; 197225930707SCorey Minyard 197325930707SCorey Minyard while ((dev = dmi_find_device(DMI_DEV_TYPE_IPMI, NULL, dev))) 197425930707SCorey Minyard decode_dmi(dev); 197525930707SCorey Minyard } 197625930707SCorey Minyard #else 197725930707SCorey Minyard static void dmi_iterator(void) { } 197825930707SCorey Minyard #endif 197925930707SCorey Minyard 198025930707SCorey Minyard static const struct i2c_device_id ssif_id[] = { 198125930707SCorey Minyard { DEVICE_NAME, 0 }, 198225930707SCorey Minyard { } 198325930707SCorey Minyard }; 198425930707SCorey Minyard MODULE_DEVICE_TABLE(i2c, ssif_id); 198525930707SCorey Minyard 198625930707SCorey Minyard static struct i2c_driver ssif_i2c_driver = { 198725930707SCorey Minyard .class = I2C_CLASS_HWMON, 198825930707SCorey Minyard .driver = { 198925930707SCorey Minyard .name = DEVICE_NAME 199025930707SCorey Minyard }, 199125930707SCorey Minyard .probe = ssif_probe, 199225930707SCorey Minyard .remove = ssif_remove, 199391620521SCorey Minyard .alert = ssif_alert, 199425930707SCorey Minyard .id_table = ssif_id, 199525930707SCorey Minyard .detect = ssif_detect 199625930707SCorey Minyard }; 199725930707SCorey Minyard 199825930707SCorey Minyard static int init_ipmi_ssif(void) 199925930707SCorey Minyard { 200025930707SCorey Minyard int i; 200125930707SCorey Minyard int rv; 200225930707SCorey Minyard 200325930707SCorey Minyard if (initialized) 200425930707SCorey Minyard return 0; 200525930707SCorey Minyard 200625930707SCorey Minyard pr_info("IPMI SSIF Interface driver\n"); 200725930707SCorey Minyard 200825930707SCorey Minyard /* build list for i2c from addr list */ 200925930707SCorey Minyard for (i = 0; i < num_addrs; i++) { 201025930707SCorey Minyard rv = new_ssif_client(addr[i], adapter_name[i], 201125930707SCorey Minyard dbg[i], slave_addrs[i], 201225930707SCorey Minyard SI_HARDCODED); 2013d467f7a4SCorey Minyard if (rv) 201425930707SCorey Minyard pr_err(PFX 201525930707SCorey Minyard "Couldn't add hardcoded device at addr 0x%x\n", 201625930707SCorey Minyard addr[i]); 201725930707SCorey Minyard } 201825930707SCorey Minyard 201925930707SCorey Minyard if (ssif_tryacpi) 202025930707SCorey Minyard ssif_i2c_driver.driver.acpi_match_table = 202125930707SCorey Minyard ACPI_PTR(ssif_acpi_match); 202225930707SCorey Minyard if (ssif_trydmi) 202325930707SCorey Minyard dmi_iterator(); 202425930707SCorey Minyard if (ssif_tryacpi) 202525930707SCorey Minyard spmi_find_bmc(); 202625930707SCorey Minyard 202725930707SCorey Minyard ssif_i2c_driver.address_list = ssif_address_list(); 202825930707SCorey Minyard 202925930707SCorey Minyard rv = i2c_add_driver(&ssif_i2c_driver); 203025930707SCorey Minyard if (!rv) 203125930707SCorey Minyard initialized = true; 203225930707SCorey Minyard 203325930707SCorey Minyard return rv; 203425930707SCorey Minyard } 203525930707SCorey Minyard module_init(init_ipmi_ssif); 203625930707SCorey Minyard 203725930707SCorey Minyard static void cleanup_ipmi_ssif(void) 203825930707SCorey Minyard { 203925930707SCorey Minyard if (!initialized) 204025930707SCorey Minyard return; 204125930707SCorey Minyard 204225930707SCorey Minyard initialized = false; 204325930707SCorey Minyard 204425930707SCorey Minyard i2c_del_driver(&ssif_i2c_driver); 204525930707SCorey Minyard 204625930707SCorey Minyard free_ssif_clients(); 204725930707SCorey Minyard } 204825930707SCorey Minyard module_exit(cleanup_ipmi_ssif); 204925930707SCorey Minyard 205025930707SCorey Minyard MODULE_AUTHOR("Todd C Davis <todd.c.davis@intel.com>, Corey Minyard <minyard@acm.org>"); 205125930707SCorey Minyard MODULE_DESCRIPTION("IPMI driver for management controllers on a SMBus"); 205225930707SCorey Minyard MODULE_LICENSE("GPL"); 2053