ManagementEngineInterface: intel-MEI.diff
| File intel-MEI.diff, 194.5 kB (added by nashif, 1 year ago) |
|---|
-
a/drivers/char/heci/heci_data_structures.h
old new 1 /* 2 * Part of Intel(R) Manageability Engine Interface Linux driver 3 * 4 * Copyright (c) 2003 - 2007 Intel Corp. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions, and the following disclaimer, 12 * without modification. 13 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 14 * substantially similar to the "NO WARRANTY" disclaimer below 15 * ("Disclaimer") and any redistribution must be conditioned upon 16 * including a substantially similar Disclaimer requirement for further 17 * binary redistribution. 18 * 3. Neither the names of the above-listed copyright holders nor the names 19 * of any contributors may be used to endorse or promote products derived 20 * from this software without specific prior written permission. 21 * 22 * Alternatively, this software may be distributed under the terms of the 23 * GNU General Public License ("GPL") version 2 as published by the Free 24 * Software Foundation. 25 * 26 * NO WARRANTY 27 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 28 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 29 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 30 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 31 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 35 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 36 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37 * POSSIBILITY OF SUCH DAMAGES. 38 * 39 */ 40 41 #ifndef _HECI_DATA_STRUCTURES_H_ 42 #define _HECI_DATA_STRUCTURES_H_ 43 44 #include <linux/version.h> 45 #include <linux/spinlock.h> 46 #include <linux/list.h> 47 #include <linux/pci.h> 48 #include <linux/timer.h> 49 #include <linux/interrupt.h> 50 #include <linux/workqueue.h> 51 #include <linux/module.h> 52 #include <linux/aio.h> 53 #include <linux/types.h> 54 55 /** 56 * error code definition 57 */ 58 #define ESUCCESS 0 59 #define ESLOTS_OVERFLOW 1 60 #define ECORRUPTED_MESSAGE_HEADER 1000 61 #define ECOMPLETE_MESSAGE 1001 62 #define FC_MESSAGE_RESERVED_LENGTH 5 63 64 /** 65 * Number of queue lists used by this driver 66 */ 67 #define NUMBER_OF_LISTS 7 68 69 #define LEGACY_MTU 4160 70 #pragma pack(1) 71 72 73 /** 74 * HECI HW Section 75 */ 76 77 /* HECI addresses and defines */ 78 #define H_CB_WW 0 79 #define H_CSR 4 80 #define ME_CB_RW 8 81 #define ME_CSR_HA 0xC 82 83 84 /* register bits - H_CSR */ 85 86 #define H_CBD 0xFF000000 87 #define H_CBWP 0x00FF0000 88 #define H_CBRP 0x0000FF00 89 #define H_RST 0x00000010 90 #define H_RDY 0x00000008 91 #define H_IG 0x00000004 92 #define H_IS 0x00000002 93 #define H_IE 0x00000001 94 95 96 /* register bits - ME_CSR_HA */ 97 #define ME_CBD_HRA 0xFF000000 98 #define ME_CBWP_HRA 0x00FF0000 99 #define ME_CBRP_HRA 0x0000FF00 100 #define ME_RST_HRA 0x00000010 101 #define ME_RDY_HRA 0x00000008 102 #define ME_IG_HRA 0x00000004 103 #define ME_IS_HRA 0x00000002 104 #define ME_IE_HRA 0x00000001 105 106 /** 107 * heci driver use additional char device for legacy mode 108 */ 109 #define MINORS_COUNT 2 110 111 #define LEGACY_MINOR_NUMBER 0 112 #define HECI_MINOR_NUMBER 1 113 #define MAX_OPEN_HANDLE_COUNT 253 114 /** 115 * debug kernel print macro define 116 */ 117 #define INFO(format, arg...) \ 118 printk(KERN_INFO "%s: " format, THIS_MODULE->name, ## arg) 119 #define ERR(format, arg...) \ 120 printk(KERN_ERR "%s: " format, THIS_MODULE->name, ## arg) 121 #define WARN(format, arg...) \ 122 printk(KERN_WARNING "%s: " format, THIS_MODULE->name, ## arg) 123 124 125 /* Module Parameters */ 126 /* 127 #define DEF_PARM(type, name, init, perm, desc) \ 128 type name = (init); \ 129 MODULE_PARM_DESC(name, desc); \ 130 module_param(name, type, perm) 131 */ 132 133 extern int debug; 134 135 #define DBG(format, arg...) do {if (debug) \ 136 printk(KERN_ERR "%s: " format , __func__ , ## arg); \ 137 } while (0) 138 139 /* 140 #ifdef HECI_DEBUG 141 #define assert(expr) do {} while (0) 142 #else 143 #define assert(expr) \ 144 if (!(expr)) { \ 145 printk("Assertion failed! %s, %s, %s, line=%d\n", \ 146 #expr, __FILE__, __func__, __LINE__); \ 147 } 148 #endif 149 */ 150 151 /** 152 * time to wait event 153 */ 154 #define HECI_INTEROP_TIMEOUT (HZ * 7) 155 156 /** 157 * watch dog definition 158 */ 159 #define HECI_WATCHDOG_DATA_SIZE 16 160 #define HECI_START_WD_DATA_SIZE 20 161 #define HECI_WD_PARAMS_SIZE 4 162 163 164 #define HECI_WD_HOST_CLIENT_ID 1 165 #define HECI_LEGACY_HOST_CLIENT_ID 2 166 167 #undef FALSE 168 #undef TRUE 169 #define TRUE 1 170 #define FALSE 0 171 172 struct guid { 173 __u32 data1; 174 __u16 data2; 175 __u16 data3; 176 __u8 data4[8]; 177 }; 178 179 /* File state */ 180 enum file_state { 181 HECI_FILE_INITIALIZING = 0, 182 HECI_FILE_CONNECTING, 183 HECI_FILE_CONNECTED, 184 HECI_FILE_DISCONNECTING, 185 HECI_FILE_DISCONNECTED 186 }; 187 188 /* HECI states */ 189 enum heci_states{ 190 HECI_INITIALIZING = 0, 191 HECI_ENABLED, 192 HECI_RESETING, 193 HECI_DISABLED, 194 HECI_RECOVERING_FROM_RESET, 195 HECI_POWER_DOWN, 196 HECI_POWER_UP 197 }; 198 199 enum legacy_states { 200 HECI_LEGACY_IDLE, 201 HECI_LEGACY_WRITING, 202 HECI_LEGACY_FLOW_CONTROL, 203 HECI_LEGACY_READING, 204 HECI_LEGACY_READ_COMPLETE 205 }; 206 207 enum heci_file_transaction_states { 208 HECI_IDLE, 209 HECI_WRITING, 210 HECI_WRITE_COMPLETE, 211 HECI_FLOW_CONTROL, 212 HECI_READING, 213 HECI_READ_COMPLETE 214 }; 215 216 /* HECI CB */ 217 enum heci_cb_major_types { 218 HECI_READ = 0, 219 HECI_WRITE, 220 HECI_IOCTL, 221 HECI_OPEN, 222 HECI_CLOSE 223 }; 224 225 /* HECI user data struct */ 226 struct heci_message_data { 227 __u32 size; 228 char *data; 229 }; 230 #define SECOND_TO_MILLI 1000 231 #define SECOND_TO_MICRO SECOND_TO_MILLI * 1000 232 #define SECOND_TO_100NANO SECOND_TO_MICRO * 10 233 234 #define CONNECT_TIMEOUT 3 /* at least 2 seconds */ 235 236 #define LEGACY_STALL_TIMER 12 /* seconds */ 237 #define LEGACY_READ_TIMER 15 /* seconds */ 238 239 struct heci_cb_private { 240 struct list_head cb_list; 241 enum heci_cb_major_types major_file_operations; 242 void *file_private; 243 struct heci_message_data request_buffer; 244 struct heci_message_data response_buffer; 245 unsigned long information; 246 unsigned long read_time; 247 struct file *file_object; 248 }; 249 250 /* Private file struct */ 251 struct heci_file_private { 252 struct list_head link; 253 struct file *file; 254 enum file_state state; 255 wait_queue_head_t tx_wait; 256 wait_queue_head_t rx_wait; 257 wait_queue_head_t wait; 258 spinlock_t file_lock; /*file lock */ 259 spinlock_t read_io_lock; /*read lock */ 260 spinlock_t write_io_lock; /*write lock */ 261 int read_pending; 262 int status; 263 /* ID of client connected */ 264 __u8 host_client_id; 265 __u8 me_client_id; 266 __u8 flow_ctrl_creds; 267 __u8 timer_count; 268 enum heci_file_transaction_states reading_state; 269 enum heci_file_transaction_states writing_state; 270 struct heci_cb_private *read_cb; 271 }; 272 273 struct io_heci_list { 274 struct heci_cb_private heci_cb; 275 int status; 276 struct iamt_heci_device *device_extension; 277 }; 278 279 struct heci_driver_version { 280 __u8 major; 281 __u8 minor; 282 __u8 hotfix; 283 __u16 build; 284 }; 285 286 287 struct heci_client { 288 __u32 max_msg_length; 289 __u8 protocol_version; 290 }; 291 /* 292 * HECI BUS Interface Section 293 */ 294 struct heci_msg_hdr { 295 __u32 me_addr:8; 296 __u32 host_addr:8; 297 __u32 length:9; 298 __u32 reserved:6; 299 __u32 msg_complete:1; 300 }; 301 302 303 struct hbm_cmd { 304 __u8 cmd:7; 305 __u8 is_response:1; 306 }; 307 308 309 struct heci_bus_message { 310 struct hbm_cmd cmd; 311 __u8 command_specific_data[]; 312 }; 313 314 struct hbm_version { 315 __u8 minor_version; 316 __u8 major_version; 317 }; 318 319 struct hbm_host_version_request { 320 struct hbm_cmd cmd; 321 __u8 reserved; 322 struct hbm_version host_version; 323 }; 324 325 struct hbm_host_version_response { 326 struct hbm_cmd cmd; 327 int host_version_supported; 328 struct hbm_version me_max_version; 329 }; 330 331 struct hbm_host_stop_request { 332 struct hbm_cmd cmd; 333 __u8 reason; 334 __u8 reserved[2]; 335 }; 336 337 struct hbm_host_stop_response { 338 struct hbm_cmd cmd; 339 __u8 reserved[3]; 340 }; 341 342 struct hbm_me_stop_request { 343 struct hbm_cmd cmd; 344 __u8 reason; 345 __u8 reserved[2]; 346 }; 347 348 struct hbm_host_enum_request { 349 struct hbm_cmd cmd; 350 __u8 reserved[3]; 351 }; 352 353 struct hbm_host_enum_response { 354 struct hbm_cmd cmd; 355 __u8 reserved[3]; 356 __u8 valid_addresses[32]; 357 }; 358 359 struct heci_client_properties { 360 struct guid protocol_name; 361 __u8 protocol_version; 362 __u8 max_number_of_connections; 363 __u8 fixed_address; 364 __u8 single_recv_buf; 365 __u32 max_msg_length; 366 }; 367 368 struct hbm_props_request { 369 struct hbm_cmd cmd; 370 __u8 address; 371 __u8 reserved[2]; 372 }; 373 374 375 struct hbm_props_response { 376 struct hbm_cmd cmd; 377 __u8 address; 378 __u8 status; 379 __u8 reserved[1]; 380 struct heci_client_properties client_properties; 381 }; 382 383 struct hbm_client_connect_request { 384 struct hbm_cmd cmd; 385 __u8 me_addr; 386 __u8 host_addr; 387 __u8 reserved; 388 }; 389 390 struct hbm_client_connect_response { 391 struct hbm_cmd cmd; 392 __u8 me_addr; 393 __u8 host_addr; 394 __u8 status; 395 }; 396 397 struct hbm_client_disconnect_request { 398 struct hbm_cmd cmd; 399 __u8 me_addr; 400 __u8 host_addr; 401 __u8 reserved[1]; 402 }; 403 404 struct hbm_flow_control { 405 struct hbm_cmd cmd; 406 __u8 me_addr; 407 __u8 host_addr; 408 __u8 reserved[FC_MESSAGE_RESERVED_LENGTH]; 409 }; 410 411 struct heci_me_client { 412 struct heci_client_properties props; 413 __u8 client_id; 414 __u8 flow_ctrl_creds; 415 }; 416 417 /* private device struct */ 418 struct iamt_heci_device { 419 struct pci_dev *pdev; /* pointer to pci device struct */ 420 /* 421 * lists of queues 422 */ 423 /* array of pointers to aio lists */ 424 struct io_heci_list *io_list_array[NUMBER_OF_LISTS]; 425 struct io_heci_list read_list; /* driver read queue */ 426 struct io_heci_list write_list; /* driver write queue */ 427 struct io_heci_list write_waiting_list; /* write waiting queue */ 428 struct io_heci_list ctrl_wr_list; /* managed write IOCTL list */ 429 struct io_heci_list ctrl_rd_list; /* managed read IOCTL list */ 430 struct io_heci_list pthi_cmd_list; /* PTHI list for cmd waiting */ 431 432 /* driver managed PTHI list for read completed pthi cmd data */ 433 struct io_heci_list pthi_read_complete_list; 434 /* 435 * list of files 436 */ 437 struct list_head file_list; 438 /* 439 * memory of device 440 */ 441 unsigned int mem_base; 442 unsigned int mem_length; 443 char *mem_addr; 444 /* 445 * lock for the device 446 */ 447 spinlock_t device_lock; /* device lock*/ 448 spinlock_t extra_lock; /* extra lock */ 449 /* 450 * intterupts 451 */ 452 int irq; 453 struct work_struct work; 454 int recvd_msg; 455 456 struct timer_list timer; 457 struct timer_list wd_timer; 458 /* 459 * hw states of host and fw(ME) 460 */ 461 __u32 host_hw_state; 462 __u32 me_hw_state; 463 /* 464 * waiting queue for receive message from FW 465 */ 466 wait_queue_head_t wait_recvd_msg; 467 wait_queue_head_t wait_stop_wd; 468 /* 469 * heci device states 470 */ 471 enum heci_states heci_state; 472 int stop; 473 /** 474 * virtual void GetParam(const char* UserParam); 475 * read write messages to/from heci fw 476 */ 477 __u32 extra_write_index; 478 __u32 rd_msg_buf[128]; /* used for control messages */ 479 __u32 wr_msg_buf[128];/* used for control messages */ 480 __u32 ext_msg_buf[8]; /* for control responses */ 481 __u32 rd_msg_hdr; 482 483 struct hbm_version version; 484 485 int host_buffer_is_empty; 486 struct heci_file_private wd_file_ext; 487 struct heci_me_client *me_clients; /* Note: memory has to be allocated*/ 488 __u8 heci_me_clients[32]; /* list of existing clients */ 489 __u8 num_heci_me_clients; 490 __u8 heci_host_clients[32]; /* list of existing clients */ 491 __u8 current_host_client_id; 492 493 int wd_pending; 494 int wd_stoped; 495 __u16 wd_timeout; /* seconds ((wd_data[1] << 8) + wd_data[0]) */ 496 unsigned char wd_data[HECI_START_WD_DATA_SIZE]; 497 498 499 __u16 wd_due_counter; 500 int asf_mode; 501 int wd_bypass; /* if true,don't refresh watchdog ME client */ 502 503 /* maybe this is not required */ 504 struct file *legacy_file_object; 505 struct heci_file_private legacy_file_ext; 506 int legacy_ioctl; 507 int legacy_canceled; 508 __u32 legacy_timer; 509 __u32 legacy_stall_timer; 510 unsigned char legacy_msg_buf[LEGACY_MTU]; 511 __u32 legacy_msg_buf_size; 512 __u32 legacy_msg_buf_index; 513 int legacy_flow_control_pending; 514 enum legacy_states legacy_state; 515 516 struct heci_cb_private *legacy_current_cb; 517 __u8 write_hang; 518 int need_reset; 519 long open_handle_count; 520 521 }; 522 523 /** 524 * read_heci_register - Read a byte from the heci device 525 * @device: the device structure 526 * @offset: offset from which to read the data 527 * 528 * Return: 529 * the byte read. 530 */ 531 __u32 read_heci_register(struct iamt_heci_device *device, 532 unsigned long offset); 533 534 /** 535 * write_heci_register - Write 4 bytes to the heci device 536 * @device: the device structure 537 * @offset: offset from which to write the data 538 * 539 * @value: the byte to write 540 */ 541 void write_heci_register(struct iamt_heci_device *device, unsigned long offset, 542 __u32 value); 543 544 #endif /* _HECI_DATA_STRUCTURES_H_ */ -
a/drivers/char/heci/heci.h
old new 1 /* 2 * Part of Intel(R) Manageability Engine Interface Linux driver 3 * 4 * Copyright (c) 2003 - 2007 Intel Corp. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions, and the following disclaimer, 12 * without modification. 13 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 14 * substantially similar to the "NO WARRANTY" disclaimer below 15 * ("Disclaimer") and any redistribution must be conditioned upon 16 * including a substantially similar Disclaimer requirement for further 17 * binary redistribution. 18 * 3. Neither the names of the above-listed copyright holders nor the names 19 * of any contributors may be used to endorse or promote products derived 20 * from this software without specific prior written permission. 21 * 22 * Alternatively, this software may be distributed under the terms of the 23 * GNU General Public License ("GPL") version 2 as published by the Free 24 * Software Foundation. 25 * 26 * NO WARRANTY 27 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 28 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 29 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 30 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 31 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 35 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 36 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37 * POSSIBILITY OF SUCH DAMAGES. 38 * 39 */ 40 41 #ifndef _HECI_H_ 42 #define _HECI_H_ 43 44 #include <linux/version.h> 45 #include <linux/spinlock.h> 46 #include <linux/list.h> 47 #include <linux/pci.h> 48 #include <linux/timer.h> 49 #include <linux/interrupt.h> 50 #include <linux/workqueue.h> 51 #include <linux/module.h> 52 #include <linux/aio.h> 53 #include <linux/types.h> 54 #include "heci_data_structures.h" 55 56 #define SHUTDOWN_METHOD(method) .shutdown = method, 57 #define HECI_REBOOT_NOTIFIER(reboot_notifier, driver, reboot_function) 58 #define REGISTER_REBOOT_NOTIFIER(reboot_notifier) 59 #define UNREGISTER_REBOOT_NOTIFIER(reboot_notifier) 60 #define heci_reboot_notifier 61 62 extern const struct guid heci_pthi_guid; 63 extern const struct guid heci_wd_guid; 64 extern const __u8 start_wd_params[]; 65 extern const __u8 stop_wd_params[]; 66 67 /** 68 * memory IO BAR definition 69 */ 70 #define BAR_0 0 71 #define BAR_1 1 72 #define BAR_5 5 73 /** 74 * Number of queue lists used by this driver 75 */ 76 #define PCI_HECI_DEVICE_ID1 0x2974 77 #define PCI_HECI_DEVICE_ID2 0x2984 78 #define PCI_HECI_DEVICE_ID3 0x2994 79 #define PCI_HECI_DEVICE_ID4 0x29A4 80 #define PCI_HECI_DEVICE_ID5 0x29B4 81 #define PCI_HECI_DEVICE_ID6 0x29C4 82 #define PCI_HECI_DEVICE_ID7 0x29E4 83 #define PCI_HECI_DEVICE_ID8 0x29F4 84 85 /** 86 * heci init function prototypes 87 */ 88 struct iamt_heci_device *init_heci_device(struct pci_dev *pdev); 89 void heci_reset(struct iamt_heci_device *dev, int interrupts); 90 int heci_hw_init(struct iamt_heci_device *dev); 91 int heci_initialize_clients(void *data); 92 struct heci_file_private *alloc_priv(struct file *file); 93 int heci_disconnect_host_client(struct iamt_heci_device *dev, 94 struct heci_file_private *file_ext); 95 void heci_initialize_list(struct io_heci_list *list, 96 struct iamt_heci_device *dev); 97 void heci_flush_list(struct io_heci_list *list, 98 struct heci_file_private *file_ext); 99 void heci_flush_queues(struct iamt_heci_device *dev, 100 struct heci_file_private *file_ext); 101 102 void heci_remove_client_from_file_list(struct iamt_heci_device *dev, 103 __u8 host_client_id); 104 105 /** 106 * interrupt function prototype 107 */ 108 irqreturn_t heci_isr_interrupt(int irq, void *dev_id); 109 void heci_wd_timer(unsigned long data); 110 void heci_bh_handler(struct work_struct *work); 111 /** 112 * input output function prototype 113 */ 114 int heci_ioctl_get_version(struct iamt_heci_device *device, int if_num, 115 struct heci_message_data *u_msg, 116 struct heci_message_data k_msg, 117 struct heci_file_private *file_ext); 118 119 int heci_ioctl_connect_client(struct iamt_heci_device *device, int if_num, 120 struct heci_message_data *u_msg, 121 struct heci_message_data k_msg, 122 struct file *file); 123 124 int heci_ioctl_wd(struct iamt_heci_device *device, int if_num, 125 struct heci_message_data k_msg, 126 struct heci_file_private *file_ext); 127 128 int heci_ioctl_bypass_wd(struct iamt_heci_device *device, int if_num, 129 struct heci_message_data k_msg, 130 struct heci_file_private *file_ext); 131 132 int legacy_ioctl_send_msg(struct iamt_heci_device *device, int if_num, 133 struct heci_message_data k_msg, 134 struct file *file); 135 136 int legacy_ioctl_recv_msg(struct iamt_heci_device *device, int if_num, 137 struct heci_message_data *u_msg, 138 struct heci_message_data k_msg, 139 struct file *file); 140 141 int heci_start_read(struct iamt_heci_device *device, int if_num, 142 struct heci_file_private *file_ext); 143 144 int pthi_write(struct iamt_heci_device *device, 145 struct heci_cb_private *priv_cb); 146 147 int pthi_read(struct iamt_heci_device *device, int if_num, struct file *file, 148 char *ubuf, size_t length, loff_t *offset); 149 150 struct heci_cb_private *find_pthi_read_list_entry( 151 struct iamt_heci_device *device, 152 struct file *file, struct heci_file_private *file_ext); 153 154 void run_next_legacy_cmd(struct iamt_heci_device *device); 155 156 157 158 #endif /* _HECI_H_ */ -
a/drivers/char/heci/heci_init.c
old new 1 /* 2 * Part of Intel(R) Manageability Engine Interface Linux driver 3 * 4 * Copyright (c) 2007 Intel Corp. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions, and the following disclaimer, 12 * without modification. 13 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 14 * substantially similar to the "NO WARRANTY" disclaimer below 15 * ("Disclaimer") and any redistribution must be conditioned upon 16 * including a substantially similar Disclaimer requirement for further 17 * binary redistribution. 18 * 3. Neither the names of the above-listed copyright holders nor the names 19 * of any contributors may be used to endorse or promote products derived 20 * from this software without specific prior written permission. 21 * 22 * Alternatively, this software may be distributed under the terms of the 23 * GNU General Public License ("GPL") version 2 as published by the Free 24 * Software Foundation. 25 * 26 * NO WARRANTY 27 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 28 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 29 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 30 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 31 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 35 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 36 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37 * POSSIBILITY OF SUCH DAMAGES. 38 * 39 */ 40 41 #include <linux/module.h> 42 #include <linux/pci.h> 43 #include <linux/reboot.h> 44 #include <linux/uaccess.h> 45 #include <linux/poll.h> 46 #include <linux/init.h> 47 #include <linux/kdev_t.h> 48 #include <linux/moduleparam.h> 49 #include <linux/wait.h> 50 #include <linux/delay.h> 51 52 #include "heci_data_structures.h" 53 #include "heci_interface.h" 54 #include "heci.h" 55 56 57 const __u8 watch_dog_data[] = { 58 1, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 59 }; 60 const __u8 start_wd_params[] = { 0x02, 0x12, 0x13, 0x10 }; 61 const __u8 stop_wd_params[] = { 0x02, 0x02, 0x14, 0x10 }; 62 const struct guid heci_asf_guid = { 63 0x75B30CD6, 0xA29E, 0x4AF7, 64 {0xA7, 0x12, 0xE6, 0x17, 0x43, 0x93, 0xC8, 0xA6} 65 }; 66 const struct guid heci_wd_guid = { 67 0x05B79A6F, 0x4628, 0x4D7F, 68 {0x89, 0x9D, 0xA9, 0x15, 0x14, 0xCB, 0x32, 0xAB} 69 }; 70 const struct guid heci_pthi_guid = { 71 0x12f80028, 0xb4b7, 0x4b2d, 72 {0xac, 0xa8, 0x46, 0xe0, 0xff, 0x65, 0x81, 0x4c} 73 }; 74 75 76 /** 77 * heci init function prototypes 78 */ 79 int host_start_message(struct iamt_heci_device *dev); 80 int host_enum_clients_message(struct iamt_heci_device *dev); 81 int allocate_me_clents_storage(struct iamt_heci_device *dev); 82 void heci_disable(struct iamt_heci_device *dev); 83 void host_init_wd(struct iamt_heci_device *dev); 84 void host_init_legacy(struct iamt_heci_device *dev); 85 int heci_wait_event_int_timeout(struct iamt_heci_device *dev, long timeout); 86 87 /** 88 * same_id - tell if they have same id 89 * @fe1 -file extension 90 * @fe2 -file extension 91 * 92 * @return : 93 * 0 on success, 94 * negative on failure. 95 */ 96 static int same_id(struct heci_file_private *fe1, 97 struct heci_file_private *fe2) 98 { 99 if ((fe1->host_client_id == fe2->host_client_id) 100 && (fe1->me_client_id == fe2->me_client_id)) { 101 return 1; 102 } else { 103 return 0; 104 } 105 } 106 107 /** 108 * heci_initialize_list - Sets up a queue list. 109 * 110 * @list - An instance of our list structure 111 * @dev -Device object for our driver 112 * 113 * @return : 114 * none; 115 */ 116 void heci_initialize_list(struct io_heci_list *list, 117 struct iamt_heci_device *dev) 118 { 119 /* initialize our queue list */ 120 INIT_LIST_HEAD(&list->heci_cb.cb_list); 121 list->status = ESUCCESS; 122 list->device_extension = dev; 123 return; 124 } 125 126 /** 127 * heci_flush_queues - flush our queues list belong to file_ext. 128 * 129 * @dev -Device object for our driver 130 * 131 * @return : 132 * none; 133 */ 134 void heci_flush_queues(struct iamt_heci_device *dev, 135 struct heci_file_private *file_ext) 136 { 137 int i; 138 if (!dev || !file_ext) 139 return; 140 /* flush our queue list belong to file_ext */ 141 for (i = 0; i < NUMBER_OF_LISTS; i++) { 142 DBG("remove list etnry belong to file_ext\n"); 143 heci_flush_list(dev->io_list_array[i], file_ext); 144 } 145 146 } 147 148 149 /** 150 * heci_flush_list - remove list etnry belong to file_ext. 151 * 152 * @list - An instance of our list structure 153 * @file_ext -extension of the file object 154 155 * @return : 156 * none; 157 */ 158 void heci_flush_list(struct io_heci_list *list, 159 struct heci_file_private *file_ext) 160 { 161 struct heci_file_private *file_ext_tmp = NULL; 162 struct heci_cb_private *priv_cb_pos = NULL; 163 struct heci_cb_private *priv_cb_next = NULL; 164 165 if (!list || !file_ext) 166 return; 167 if (list->status == ESUCCESS 168 && !list_empty(&list->heci_cb.cb_list)) { 169 list_for_each_entry_safe(priv_cb_pos, 170 priv_cb_next, &list->heci_cb.cb_list, cb_list) { 171 if (priv_cb_pos) 172 file_ext_tmp = (struct heci_file_private *) 173 priv_cb_pos->file_private; 174 175 if (file_ext_tmp) { 176 if (same_id(file_ext, file_ext_tmp)) 177 list_del(&priv_cb_pos->cb_list); 178 } 179 180 } 181 } 182 return; 183 } 184 185 /** 186 * init_heci_device - allocates and initializes the heci device structure 187 * @pdev: The pci device structure 188 * 189 * @return : 190 * The heci_device_device pointer on success, NULL on failure. 191 */ 192 struct iamt_heci_device *init_heci_device(struct pci_dev *pdev) 193 { 194 int i; 195 struct iamt_heci_device *device; 196 197 device = kmalloc(sizeof(struct iamt_heci_device), GFP_KERNEL); 198 if (!device) 199 return NULL; 200 201 /* setup our list array */ 202 device->io_list_array[0] = &device->read_list; 203 device->io_list_array[1] = &device->write_list; 204 device->io_list_array[2] = &device->write_waiting_list; 205 device->io_list_array[3] = &device->ctrl_wr_list; 206 device->io_list_array[4] = &device->ctrl_rd_list; 207 device->io_list_array[5] = &device->pthi_cmd_list; 208 device->io_list_array[6] = &device->pthi_read_complete_list; 209 INIT_LIST_HEAD(&device->file_list); 210 INIT_LIST_HEAD(&device->wd_file_ext.link); 211 INIT_LIST_HEAD(&device->legacy_file_ext.link); 212 spin_lock_init(&device->device_lock); 213 init_waitqueue_head(&device->wait_recvd_msg); 214 init_waitqueue_head(&device->wait_stop_wd); 215 device->open_handle_count = 0; 216 device->num_heci_me_clients = 0; 217 device->mem_base = 0; 218 device->mem_length = 0; 219 device->extra_write_index = 0; 220 device->rd_msg_hdr = 0; 221 device->mem_addr = NULL; 222 device->asf_mode = FALSE; 223 device->need_reset = FALSE; 224 device->recvd_msg = FALSE; 225 device->heci_state = HECI_INITIALIZING; 226 227 device->num_heci_me_clients = 0; 228 device->legacy_current_cb = NULL; 229 device->legacy_file_object = NULL; 230 device->legacy_canceled = FALSE; 231 device->legacy_flow_control_pending = FALSE; 232 device->legacy_state = HECI_LEGACY_IDLE; 233 device->legacy_msg_buf_index = 0; 234 device->wd_pending = FALSE; 235 device->wd_stoped = FALSE; 236 device->wd_bypass = FALSE; 237 238 device->me_clients = NULL; 239 /* init work for schedule work */ 240 INIT_WORK(&device->work, NULL); 241 for (i = 0; i < NUMBER_OF_LISTS; i++) 242 heci_initialize_list(device->io_list_array[i], device); 243 device->pdev = pdev; 244 return device; 245 } 246 247 248 249 250 int heci_wait_event_int_timeout(struct iamt_heci_device *dev, 251 long timeout) 252 { 253 int err = 0; 254 err = wait_event_interruptible_timeout(dev->wait_recvd_msg, 255 (dev->recvd_msg), timeout); 256 return err; 257 } 258 259 /** 260 * heci_hw_init - init host and fw to start work. 261 * 262 * @dev -Device object for our driver 263 * 264 *@return: 265 * 0 on success. 266 * negative on failure 267 */ 268 int heci_hw_init(struct iamt_heci_device *dev) 269 { 270 int err = 0; 271 dev->host_hw_state = read_heci_register(dev, H_CSR); 272 dev->me_hw_state = read_heci_register(dev, ME_CSR_HA); 273 DBG("host_hw_state = 0x%08x, mestate = 0x%08x.\n", 274 dev->host_hw_state, dev->me_hw_state); 275 276 if ((dev->host_hw_state & H_IS) == H_IS) { 277 /* acknowledge interrupt and stop interupts */ 278 write_heci_register(dev, H_CSR, dev->host_hw_state); 279 } 280 dev->recvd_msg = FALSE; 281 DBG("reset in start the heci device.\n"); 282 283 heci_reset(dev, TRUE); 284 285 DBG("host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n", 286 dev->host_hw_state, dev->me_hw_state); 287 288 /* wait for ME to turn on ME_RDY */ 289 if (!dev->recvd_msg) 290 err = heci_wait_event_int_timeout(dev, HECI_INTEROP_TIMEOUT); 291 292 if (!err && !dev->recvd_msg) { 293 dev->heci_state = HECI_DISABLED; 294 DBG("wait_event_interruptible_timeout failed" \ 295 "on wait for ME to turn on ME_RDY.\n"); 296 return -ENODEV; 297 } else { 298 if (!(((dev->host_hw_state & H_RDY) == H_RDY) 299 && ((dev->me_hw_state & ME_RDY_HRA) == ME_RDY_HRA))) { 300 dev->heci_state = HECI_DISABLED; 301 DBG("host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n", 302 dev->host_hw_state, 303 dev->me_hw_state); 304 305 if (!(dev->host_hw_state & H_RDY) != H_RDY) 306 DBG("host turn off H_RDY.\n"); 307 if (!(dev->me_hw_state & ME_RDY_HRA) != ME_RDY_HRA) 308 DBG("ME turn off ME_RDY.\n"); 309 ERR("link layer initialization failed.\n"); 310 return -ENODEV; 311 } 312 } 313 dev->recvd_msg = FALSE; 314 DBG("host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n", 315 dev->host_hw_state, dev->me_hw_state); 316 DBG("ME turn on ME_RDY and host turn on H_RDY.\n"); 317 INFO("link layer has been established.\n"); 318 return ESUCCESS; 319 } 320 321 /** 322 * heci_reset - reset host and fw. 323 * 324 * @dev -Device object for our driver 325 * @interrupts - if interrupt should be enable after reset. 326 * 327 * @return: 328 * none; 329 */ 330 void heci_reset(struct iamt_heci_device *dev, int interrupts) 331 { 332 struct heci_file_private *file_pos = NULL; 333 struct heci_file_private *file_next = NULL; 334 struct heci_cb_private *priv_cb_pos = NULL; 335 struct heci_cb_private *priv_cb_next = NULL; 336 337 if (dev->heci_state == HECI_RECOVERING_FROM_RESET) { 338 dev->need_reset = TRUE; 339 return; 340 } 341 dev->host_hw_state = read_heci_register(dev, H_CSR); 342 343 DBG("before reset host_hw_state = 0x%08x.\n", 344 dev->host_hw_state); 345 346 dev->host_hw_state |= (H_RST | H_IG); 347 348 if (interrupts) 349 dev->host_hw_state |= (H_IE); 350 else 351 dev->host_hw_state &= ~(H_IE); 352 353 write_heci_register(dev, H_CSR, dev->host_hw_state); 354 355 dev->host_hw_state = read_heci_register(dev, H_CSR); 356 BUG_ON((dev->host_hw_state & H_RST) != H_RST); 357 BUG_ON((dev->host_hw_state & H_RDY) != 0); 358 359 dev->host_hw_state &= ~H_RST; 360 dev->host_hw_state |= H_IG; 361 362 write_heci_register(dev, H_CSR, dev->host_hw_state); 363 364 DBG("currently saved host_hw_state = 0x%08x.\n", 365 dev->host_hw_state); 366 367 dev->need_reset = FALSE; 368 369 if (dev->heci_state != HECI_INITIALIZING) { 370 if (dev->heci_state != HECI_DISABLED) 371 dev->heci_state = HECI_RESETING; 372 373 list_for_each_entry_safe(file_pos, 374 file_next, &dev->file_list, link) { 375 file_pos->state = HECI_FILE_DISCONNECTED; 376 file_pos->flow_ctrl_creds = 0; 377 file_pos->read_cb = NULL; 378 file_pos->timer_count = 0; 379 } 380 /* remove entry if already in list */ 381