1 /* 2 * 3 * Intel Management Engine Interface (Intel MEI) Linux driver 4 * Copyright (c) 2003-2012, Intel Corporation. 5 * 6 * This program is free software; you can redistribute it and/or modify it 7 * under the terms and conditions of the GNU General Public License, 8 * version 2, as published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 13 * more details. 14 * 15 */ 16 17 #include <linux/export.h> 18 #include <linux/pci.h> 19 #include <linux/sched.h> 20 #include <linux/wait.h> 21 #include <linux/delay.h> 22 23 #include <linux/mei.h> 24 25 #include "mei_dev.h" 26 #include "hbm.h" 27 #include "client.h" 28 29 const char *mei_dev_state_str(int state) 30 { 31 #define MEI_DEV_STATE(state) case MEI_DEV_##state: return #state 32 switch (state) { 33 MEI_DEV_STATE(INITIALIZING); 34 MEI_DEV_STATE(INIT_CLIENTS); 35 MEI_DEV_STATE(ENABLED); 36 MEI_DEV_STATE(RESETTING); 37 MEI_DEV_STATE(DISABLED); 38 MEI_DEV_STATE(POWER_DOWN); 39 MEI_DEV_STATE(POWER_UP); 40 default: 41 return "unknown"; 42 } 43 #undef MEI_DEV_STATE 44 } 45 46 47 /** 48 * mei_cancel_work. Cancel mei background jobs 49 * 50 * @dev: the device structure 51 * 52 * returns 0 on success or < 0 if the reset hasn't succeeded 53 */ 54 void mei_cancel_work(struct mei_device *dev) 55 { 56 cancel_work_sync(&dev->init_work); 57 cancel_work_sync(&dev->reset_work); 58 59 cancel_delayed_work(&dev->timer_work); 60 } 61 EXPORT_SYMBOL_GPL(mei_cancel_work); 62 63 /** 64 * mei_reset - resets host and fw. 65 * 66 * @dev: the device structure 67 */ 68 int mei_reset(struct mei_device *dev) 69 { 70 enum mei_dev_state state = dev->dev_state; 71 bool interrupts_enabled; 72 int ret; 73 74 if (state != MEI_DEV_INITIALIZING && 75 state != MEI_DEV_DISABLED && 76 state != MEI_DEV_POWER_DOWN && 77 state != MEI_DEV_POWER_UP) 78 dev_warn(&dev->pdev->dev, "unexpected reset: dev_state = %s\n", 79 mei_dev_state_str(state)); 80 81 /* we're already in reset, cancel the init timer 82 * if the reset was called due the hbm protocol error 83 * we need to call it before hw start 84 * so the hbm watchdog won't kick in 85 */ 86 mei_hbm_idle(dev); 87 88 /* enter reset flow */ 89 interrupts_enabled = state != MEI_DEV_POWER_DOWN; 90 dev->dev_state = MEI_DEV_RESETTING; 91 92 dev->reset_count++; 93 if (dev->reset_count > MEI_MAX_CONSEC_RESET) { 94 dev_err(&dev->pdev->dev, "reset: reached maximal consecutive resets: disabling the device\n"); 95 dev->dev_state = MEI_DEV_DISABLED; 96 return -ENODEV; 97 } 98 99 ret = mei_hw_reset(dev, interrupts_enabled); 100 /* fall through and remove the sw state even if hw reset has failed */ 101 102 /* no need to clean up software state in case of power up */ 103 if (state != MEI_DEV_INITIALIZING && 104 state != MEI_DEV_POWER_UP) { 105 106 /* remove all waiting requests */ 107 mei_cl_all_write_clear(dev); 108 109 mei_cl_all_disconnect(dev); 110 111 /* wake up all readers and writers so they can be interrupted */ 112 mei_cl_all_wakeup(dev); 113 114 /* remove entry if already in list */ 115 dev_dbg(&dev->pdev->dev, "remove iamthif and wd from the file list.\n"); 116 mei_cl_unlink(&dev->wd_cl); 117 mei_cl_unlink(&dev->iamthif_cl); 118 mei_amthif_reset_params(dev); 119 memset(&dev->wr_ext_msg, 0, sizeof(dev->wr_ext_msg)); 120 } 121 122 123 dev->me_clients_num = 0; 124 dev->rd_msg_hdr = 0; 125 dev->wd_pending = false; 126 127 if (ret) { 128 dev_err(&dev->pdev->dev, "hw_reset failed ret = %d\n", ret); 129 dev->dev_state = MEI_DEV_DISABLED; 130 return ret; 131 } 132 133 if (state == MEI_DEV_POWER_DOWN) { 134 dev_dbg(&dev->pdev->dev, "powering down: end of reset\n"); 135 dev->dev_state = MEI_DEV_DISABLED; 136 return 0; 137 } 138 139 ret = mei_hw_start(dev); 140 if (ret) { 141 dev_err(&dev->pdev->dev, "hw_start failed ret = %d\n", ret); 142 dev->dev_state = MEI_DEV_DISABLED; 143 return ret; 144 } 145 146 dev_dbg(&dev->pdev->dev, "link is established start sending messages.\n"); 147 148 dev->dev_state = MEI_DEV_INIT_CLIENTS; 149 ret = mei_hbm_start_req(dev); 150 if (ret) { 151 dev_err(&dev->pdev->dev, "hbm_start failed ret = %d\n", ret); 152 dev->dev_state = MEI_DEV_DISABLED; 153 return ret; 154 } 155 156 return 0; 157 } 158 EXPORT_SYMBOL_GPL(mei_reset); 159 160 /** 161 * mei_start - initializes host and fw to start work. 162 * 163 * @dev: the device structure 164 * 165 * returns 0 on success, <0 on failure. 166 */ 167 int mei_start(struct mei_device *dev) 168 { 169 mutex_lock(&dev->device_lock); 170 171 /* acknowledge interrupt and stop interrupts */ 172 mei_clear_interrupts(dev); 173 174 mei_hw_config(dev); 175 176 dev_dbg(&dev->pdev->dev, "reset in start the mei device.\n"); 177 178 dev->dev_state = MEI_DEV_INITIALIZING; 179 dev->reset_count = 0; 180 mei_reset(dev); 181 182 if (dev->dev_state == MEI_DEV_DISABLED) { 183 dev_err(&dev->pdev->dev, "reset failed"); 184 goto err; 185 } 186 187 if (mei_hbm_start_wait(dev)) { 188 dev_err(&dev->pdev->dev, "HBM haven't started"); 189 goto err; 190 } 191 192 if (!mei_host_is_ready(dev)) { 193 dev_err(&dev->pdev->dev, "host is not ready.\n"); 194 goto err; 195 } 196 197 if (!mei_hw_is_ready(dev)) { 198 dev_err(&dev->pdev->dev, "ME is not ready.\n"); 199 goto err; 200 } 201 202 if (!mei_hbm_version_is_supported(dev)) { 203 dev_dbg(&dev->pdev->dev, "MEI start failed.\n"); 204 goto err; 205 } 206 207 dev_dbg(&dev->pdev->dev, "link layer has been established.\n"); 208 209 mutex_unlock(&dev->device_lock); 210 return 0; 211 err: 212 dev_err(&dev->pdev->dev, "link layer initialization failed.\n"); 213 dev->dev_state = MEI_DEV_DISABLED; 214 mutex_unlock(&dev->device_lock); 215 return -ENODEV; 216 } 217 EXPORT_SYMBOL_GPL(mei_start); 218 219 /** 220 * mei_restart - restart device after suspend 221 * 222 * @dev: the device structure 223 * 224 * returns 0 on success or -ENODEV if the restart hasn't succeeded 225 */ 226 int mei_restart(struct mei_device *dev) 227 { 228 int err; 229 230 mutex_lock(&dev->device_lock); 231 232 mei_clear_interrupts(dev); 233 234 dev->dev_state = MEI_DEV_POWER_UP; 235 dev->reset_count = 0; 236 237 err = mei_reset(dev); 238 239 mutex_unlock(&dev->device_lock); 240 241 if (err || dev->dev_state == MEI_DEV_DISABLED) 242 return -ENODEV; 243 244 return 0; 245 } 246 EXPORT_SYMBOL_GPL(mei_restart); 247 248 249 static void mei_reset_work(struct work_struct *work) 250 { 251 struct mei_device *dev = 252 container_of(work, struct mei_device, reset_work); 253 254 mutex_lock(&dev->device_lock); 255 256 mei_reset(dev); 257 258 mutex_unlock(&dev->device_lock); 259 260 if (dev->dev_state == MEI_DEV_DISABLED) 261 dev_err(&dev->pdev->dev, "reset failed"); 262 } 263 264 void mei_stop(struct mei_device *dev) 265 { 266 dev_dbg(&dev->pdev->dev, "stopping the device.\n"); 267 268 mei_cancel_work(dev); 269 270 mei_nfc_host_exit(dev); 271 272 mutex_lock(&dev->device_lock); 273 274 mei_wd_stop(dev); 275 276 dev->dev_state = MEI_DEV_POWER_DOWN; 277 mei_reset(dev); 278 279 mutex_unlock(&dev->device_lock); 280 281 mei_watchdog_unregister(dev); 282 } 283 EXPORT_SYMBOL_GPL(mei_stop); 284 285 286 287 void mei_device_init(struct mei_device *dev) 288 { 289 /* setup our list array */ 290 INIT_LIST_HEAD(&dev->file_list); 291 INIT_LIST_HEAD(&dev->device_list); 292 mutex_init(&dev->device_lock); 293 init_waitqueue_head(&dev->wait_hw_ready); 294 init_waitqueue_head(&dev->wait_recvd_msg); 295 init_waitqueue_head(&dev->wait_stop_wd); 296 dev->dev_state = MEI_DEV_INITIALIZING; 297 dev->reset_count = 0; 298 299 mei_io_list_init(&dev->read_list); 300 mei_io_list_init(&dev->write_list); 301 mei_io_list_init(&dev->write_waiting_list); 302 mei_io_list_init(&dev->ctrl_wr_list); 303 mei_io_list_init(&dev->ctrl_rd_list); 304 305 INIT_DELAYED_WORK(&dev->timer_work, mei_timer); 306 INIT_WORK(&dev->init_work, mei_host_client_init); 307 INIT_WORK(&dev->reset_work, mei_reset_work); 308 309 INIT_LIST_HEAD(&dev->wd_cl.link); 310 INIT_LIST_HEAD(&dev->iamthif_cl.link); 311 mei_io_list_init(&dev->amthif_cmd_list); 312 mei_io_list_init(&dev->amthif_rd_complete_list); 313 314 bitmap_zero(dev->host_clients_map, MEI_CLIENTS_MAX); 315 dev->open_handle_count = 0; 316 317 /* 318 * Reserving the first client ID 319 * 0: Reserved for MEI Bus Message communications 320 */ 321 bitmap_set(dev->host_clients_map, 0, 1); 322 } 323 EXPORT_SYMBOL_GPL(mei_device_init); 324 325