ManagementEngineInterface: intel-MEI.diff

File intel-MEI.diff, 194.5 kB (added by nashif, 1 year ago)

MEI patch for 2.6.23

  • 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 
     133extern int debug; 
     134 
     135#define DBG(format, arg...) do {if (debug) \ 
     136printk(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 
     172struct guid { 
     173        __u32 data1; 
     174        __u16 data2; 
     175        __u16 data3; 
     176        __u8 data4[8]; 
     177}; 
     178 
     179/* File state */ 
     180enum 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 */ 
     189enum 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 
     199enum 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 
     207enum 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 */ 
     217enum 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 */ 
     226struct 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 
     239struct 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 */ 
     251struct 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 
     273struct io_heci_list { 
     274        struct heci_cb_private heci_cb; 
     275        int status; 
     276        struct iamt_heci_device *device_extension; 
     277}; 
     278 
     279struct heci_driver_version { 
     280        __u8 major; 
     281        __u8 minor; 
     282        __u8 hotfix; 
     283        __u16 build; 
     284}; 
     285 
     286 
     287struct heci_client { 
     288        __u32 max_msg_length; 
     289        __u8 protocol_version; 
     290}; 
     291/* 
     292 *  HECI BUS Interface Section 
     293 */ 
     294struct 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 
     303struct hbm_cmd { 
     304        __u8 cmd:7; 
     305        __u8 is_response:1; 
     306}; 
     307 
     308 
     309struct heci_bus_message { 
     310        struct hbm_cmd cmd; 
     311        __u8 command_specific_data[]; 
     312}; 
     313 
     314struct hbm_version { 
     315        __u8 minor_version; 
     316        __u8 major_version; 
     317}; 
     318 
     319struct hbm_host_version_request { 
     320        struct hbm_cmd cmd; 
     321        __u8 reserved; 
     322        struct hbm_version host_version; 
     323}; 
     324 
     325struct hbm_host_version_response { 
     326        struct hbm_cmd cmd; 
     327        int host_version_supported; 
     328        struct hbm_version me_max_version; 
     329}; 
     330 
     331struct hbm_host_stop_request { 
     332        struct hbm_cmd cmd; 
     333        __u8 reason; 
     334        __u8 reserved[2]; 
     335}; 
     336 
     337struct hbm_host_stop_response { 
     338        struct hbm_cmd cmd; 
     339        __u8 reserved[3]; 
     340}; 
     341 
     342struct hbm_me_stop_request { 
     343        struct hbm_cmd cmd; 
     344        __u8 reason; 
     345        __u8 reserved[2]; 
     346}; 
     347 
     348struct hbm_host_enum_request { 
     349        struct hbm_cmd cmd; 
     350        __u8 reserved[3]; 
     351}; 
     352 
     353struct hbm_host_enum_response { 
     354        struct hbm_cmd cmd; 
     355        __u8 reserved[3]; 
     356        __u8 valid_addresses[32]; 
     357}; 
     358 
     359struct 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 
     368struct hbm_props_request { 
     369        struct hbm_cmd cmd; 
     370        __u8 address; 
     371        __u8 reserved[2]; 
     372}; 
     373 
     374 
     375struct 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 
     383struct hbm_client_connect_request { 
     384        struct hbm_cmd cmd; 
     385        __u8 me_addr; 
     386        __u8 host_addr; 
     387        __u8 reserved; 
     388}; 
     389 
     390struct hbm_client_connect_response { 
     391        struct hbm_cmd cmd; 
     392        __u8 me_addr; 
     393        __u8 host_addr; 
     394        __u8 status; 
     395}; 
     396 
     397struct hbm_client_disconnect_request { 
     398        struct hbm_cmd cmd; 
     399        __u8 me_addr; 
     400        __u8 host_addr; 
     401        __u8 reserved[1]; 
     402}; 
     403 
     404struct 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 
     411struct heci_me_client { 
     412        struct heci_client_properties props; 
     413        __u8 client_id; 
     414        __u8 flow_ctrl_creds; 
     415}; 
     416 
     417/* private device struct */ 
     418struct 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 */ 
     541void 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 
     62extern const struct guid heci_pthi_guid; 
     63extern const struct guid heci_wd_guid; 
     64extern const __u8 start_wd_params[]; 
     65extern 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 */ 
     88struct iamt_heci_device *init_heci_device(struct pci_dev *pdev); 
     89void heci_reset(struct iamt_heci_device *dev, int interrupts); 
     90int heci_hw_init(struct iamt_heci_device *dev); 
     91int heci_initialize_clients(void *data); 
     92struct heci_file_private *alloc_priv(struct file *file); 
     93int heci_disconnect_host_client(struct iamt_heci_device *dev, 
     94                                struct heci_file_private *file_ext); 
     95void heci_initialize_list(struct io_heci_list *list, 
     96                          struct iamt_heci_device *dev); 
     97void heci_flush_list(struct io_heci_list *list, 
     98                     struct heci_file_private *file_ext); 
     99void heci_flush_queues(struct iamt_heci_device *dev, 
     100                       struct heci_file_private *file_ext); 
     101 
     102void heci_remove_client_from_file_list(struct iamt_heci_device *dev, 
     103                                       __u8 host_client_id); 
     104 
     105/** 
     106 *  interrupt function prototype 
     107 */ 
     108irqreturn_t heci_isr_interrupt(int irq, void *dev_id); 
     109void heci_wd_timer(unsigned long data); 
     110void heci_bh_handler(struct work_struct *work); 
     111/** 
     112 *  input output function prototype 
     113 */ 
     114int 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 
     119int 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 
     124int 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 
     128int 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 
     132int legacy_ioctl_send_msg(struct iamt_heci_device *device, int if_num, 
     133                              struct heci_message_data k_msg, 
     134                              struct file *file); 
     135 
     136int 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 
     141int heci_start_read(struct iamt_heci_device *device, int if_num, 
     142                    struct heci_file_private *file_ext); 
     143 
     144int pthi_write(struct iamt_heci_device *device, 
     145               struct heci_cb_private *priv_cb); 
     146 
     147int pthi_read(struct iamt_heci_device *device, int if_num, struct file *file, 
     148              char *ubuf, size_t length, loff_t *offset); 
     149 
     150struct 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 
     154void 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 
     57const __u8 watch_dog_data[] = { 
     58        1, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 
     59}; 
     60const __u8 start_wd_params[] = { 0x02, 0x12, 0x13, 0x10 }; 
     61const __u8 stop_wd_params[] = { 0x02, 0x02, 0x14, 0x10 }; 
     62const struct guid heci_asf_guid = { 
     63                0x75B30CD6, 0xA29E, 0x4AF7, 
     64                {0xA7, 0x12, 0xE6, 0x17, 0x43, 0x93, 0xC8, 0xA6} 
     65}; 
     66const struct guid heci_wd_guid = { 
     67        0x05B79A6F, 0x4628, 0x4D7F, 
     68        {0x89, 0x9D, 0xA9, 0x15, 0x14, 0xCB, 0x32, 0xAB} 
     69}; 
     70const 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 */ 
     79int host_start_message(struct iamt_heci_device *dev); 
     80int host_enum_clients_message(struct iamt_heci_device *dev); 
     81int allocate_me_clents_storage(struct iamt_heci_device *dev); 
     82void heci_disable(struct iamt_heci_device *dev); 
     83void host_init_wd(struct iamt_heci_device *dev); 
     84void host_init_legacy(struct iamt_heci_device *dev); 
     85int 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 */ 
     96static 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 */ 
     116void 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 */ 
     134void 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 */ 
     158void 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 */ 
     192struct 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 
     250int 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 */ 
     268int 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 */ 
     330void 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