From: <mar...@us...> - 2008-07-22 17:12:57
|
Revision: 206 http://openamt.svn.sourceforge.net/openamt/?rev=206&view=rev Author: marcin_obara Date: 2008-07-22 17:13:05 +0000 (Tue, 22 Jul 2008) Log Message: ----------- 5.0 base for testing code Modified Paths: -------------- heci/branches/testing/COPYING heci/branches/testing/README heci/branches/testing/src/Makefile heci/branches/testing/src/heci.h heci/branches/testing/src/heci_data_structures.h heci/branches/testing/src/heci_init.c heci/branches/testing/src/heci_interface.c heci/branches/testing/src/heci_interface.h heci/branches/testing/src/heci_main.c heci/branches/testing/src/interrupt.c heci/branches/testing/src/io_heci.c heci/branches/testing/src/kcompat.h Added Paths: ----------- heci/branches/testing/src/heci_version.h Removed Paths: ------------- heci/branches/testing/scripts/ heci/branches/testing/src/version.h Modified: heci/branches/testing/COPYING =================================================================== --- heci/branches/testing/COPYING 2008-07-22 16:25:37 UTC (rev 205) +++ heci/branches/testing/COPYING 2008-07-22 17:13:05 UTC (rev 206) @@ -1,7 +1,7 @@ /* * Part of "Intel(R) Manageability Engine Interface" Linux driver * - * Copyright (c) 2007 Intel Corp. + * Copyright (c) 2003 - 2008 Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without Modified: heci/branches/testing/README =================================================================== --- heci/branches/testing/README 2008-07-22 16:25:37 UTC (rev 205) +++ heci/branches/testing/README 2008-07-22 17:13:05 UTC (rev 206) @@ -1,6 +1,6 @@ /+--------------------------------------------------------------------------- // -// Copyright (C) Intel Corporation, 2003 - 2007. +// Copyright (C) Intel Corporation, 2003 - 2008. // // File: README // @@ -26,17 +26,14 @@ Building and installing the Intel(R) Manageability Engine Interface driver: ----------------------------- In order to build and install the Intel(R) Manageability Engine Interface driver, -call "make install" from the /src directory. This builds the Intel(R) -Manageability Engine Interface driver, installs it and the startup script. +call "make install". Call "make uninstall" to uninstall and remove the Intel(R) Manageability Engine -Interface driver and the startup script. In order to load and use the driver -call "modprobe heci" or "insmod heci.ko" and call make_node script from -scripts/ directory. To start heci driver at system boot, startup script need -to be added to desired runlevel. +Interface driver. +In order to load and use the driver call "modprobe heci" or "insmod heci.ko". The Intel(R) Manageability Engine Interface driver may also be built and -installed manually, by first calling "make", then "insmod heci.ko", followed -by "./make_node". Remove by calling "rmmod heci.ko". +installed manually, by first calling "make", then "insmod heci.ko". +Remove by calling "rmmod heci.ko". Accessing The FW Via Intel(R) Manageability Engine Interface driver: ----------------------------- Modified: heci/branches/testing/src/Makefile =================================================================== --- heci/branches/testing/src/Makefile 2008-07-22 16:25:37 UTC (rev 205) +++ heci/branches/testing/src/Makefile 2008-07-22 17:13:05 UTC (rev 206) @@ -3,7 +3,7 @@ # # Part of Intel(R) Manageability Engine Interface Linux driver # -# Copyright (c) 2003 - 2007 Intel Corp. +# Copyright (c) 2003 - 2008 Intel Corp. # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -45,15 +45,11 @@ # core driver files CFILES = heci_init.c interrupt.c heci_interface.c io_heci.c heci_main.c -HFILES = heci.h heci_interface.h +HFILES = heci.h heci_interface.h heci_structures,h heci_version.h kcompat.h ifeq (,$(BUILD_KERNEL)) BUILD_KERNEL = $(shell uname -r) endif -INIT_SCRIPT_PATH = /etc/init.d -INIT_SCRIPT_SRC = ../scripts/heci.sh -INIT_SCRIPT = heci - ########################################################################### # Environment tests @@ -129,27 +125,27 @@ # some additional features are only built on Intel platforms ARCH := $(shell uname -m | sed 's/i.86/i386/') ifeq ($(ARCH),alpha) - CFLAGS += -ffixed-8 -mno-fp-regs + EXTRA_CFLAGS += -ffixed-8 -mno-fp-regs endif ifeq ($(ARCH),x86_64) - CFLAGS += -mcmodel=kernel -mno-red-zone + EXTRA_CFLAGS += -mcmodel=kernel -mno-red-zone endif ifeq ($(ARCH),ppc) - CFLAGS += -msoft-float + EXTRA_CFLAGS += -msoft-float endif ifeq ($(ARCH),ppc64) - CFLAGS += -m64 -msoft-float + EXTRA_CFLAGS += -m64 -msoft-float LDFLAGS += -melf64ppc endif # standard flags for module builds -CFLAGS += -DLINUX -D__KERNEL__ -DMODULE -O2 -pipe -Wall -CFLAGS += -I$(KSRC)/include -I. -CFLAGS += $(shell [ -f $(KSRC)/include/linux/modversions.h ] && \ +EXTRA_CFLAGS += -DLINUX -D__KERNEL__ -DMODULE -O2 -pipe -Wall +EXTRA_CFLAGS += -I$(KSRC)/include -I. +EXTRA_CFLAGS += $(shell [ -f $(KSRC)/include/linux/modversions.h ] && \ echo "-DMODVERSIONS -DEXPORT_SYMTAB \ -include $(KSRC)/include/linux/modversions.h") -CFLAGS += $(CFLAGS_EXTRA) +EXTRA_CFLAGS += $(CFLAGS_EXTRA) RHC := $(KSRC)/include/linux/rhconfig.h ifneq (,$(wildcard $(RHC))) @@ -200,7 +196,7 @@ endif ifeq ($(SMP),1) - CFLAGS += -D__SMP__ + EXTRA_CFLAGS += -D__SMP__ endif @@ -233,6 +229,9 @@ # remove all old versions of the driver find $(INSTALL_MOD_PATH)/lib/modules/$(KVER) -name $(TARGET) -exec rm -f {} \; || true find $(INSTALL_MOD_PATH)/lib/modules/$(KVER) -name $(TARGET).gz -exec rm -f {} \; || true + if [ -e /etc/init.d/heci ] ; then \ + rm -f /etc/init.d/heci ; \ + fi install -D -m 644 $(TARGET) $(INSTALL_MOD_PATH)$(INSTDIR)/$(TARGET) ifeq (,$(INSTALL_MOD_PATH)) /sbin/depmod -a || true @@ -243,13 +242,11 @@ /sbin/depmod -b $(INSTALL_MOD_PATH) -a -n > /dev/null || true endif endif - #copy init script to init.d - install ${INIT_SCRIPT_SRC} ${INIT_SCRIPT_PATH}/${INIT_SCRIPT} .PHONY: clean install uninstall test clean: - rm -rf $(TARGET) $(TARGET:.ko=.o) $(TARGET:.ko=.mod.o) $(TARGET:.ko=.mod.c) $(CFILES:.c=.o) .*cmd .tmp_versions Module.symvers + rm -rf $(TARGET) $(TARGET:.ko=.o) $(TARGET:.ko=.mod.o) $(TARGET:.ko=.mod.c) $(CFILES:.c=.o) .*cmd .tmp_versions Module.symvers Modules.symvers test: @echo $(KVER) @@ -258,7 +255,3 @@ if [ -e $(INSTDIR)/$(TARGET) ]; then \ rm -f ${INSTDIR}/$(TARGET) ; \ fi - #remove init script from init.d - if [ -e ${INIT_SCRIPT_PATH}/${INIT_SCRIPT} ] ; then \ - rm -f ${INIT_SCRIPT_PATH}/${INIT_SCRIPT} ; \ - fi Modified: heci/branches/testing/src/heci.h =================================================================== --- heci/branches/testing/src/heci.h 2008-07-22 16:25:37 UTC (rev 205) +++ heci/branches/testing/src/heci.h 2008-07-22 17:13:05 UTC (rev 206) @@ -1,7 +1,7 @@ /* * Part of Intel(R) Manageability Engine Interface Linux driver * - * Copyright (c) 2003 - 2007 Intel Corp. + * Copyright (c) 2003 - 2008 Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -53,82 +53,124 @@ #include <linux/types.h> #include "heci_data_structures.h" - extern const struct guid heci_pthi_guid; -extern const __u8 start_wd_params[]; -extern const __u8 stop_wd_params[]; +extern const struct guid heci_wd_guid; +extern const __u8 heci_start_wd_params[]; +extern const __u8 heci_stop_wd_params[]; +extern const __u8 heci_wd_state_independence_msg[3][4]; -/** - * memory IO BAR definition +/* + * heci device ID */ -#define BAR_0 0 -#define BAR_1 1 -#define BAR_5 5 -/** - * Number of queue lists used by this driver - */ -#define PCI_HECI_DEVICE_ID1 0x2974 -#define PCI_HECI_DEVICE_ID2 0x2984 -#define PCI_HECI_DEVICE_ID3 0x2994 -#define PCI_HECI_DEVICE_ID4 0x29A4 -#define PCI_HECI_DEVICE_ID5 0x29B4 -#define PCI_HECI_DEVICE_ID6 0x29C4 +#define HECI_DEV_ID_82946GZ 0x2974 /* 82946GZ/GL */ +#define HECI_DEV_ID_82G35 0x2984 /* 82G35 Express */ +#define HECI_DEV_ID_82Q965 0x2994 /* 82Q963/Q965 */ +#define HECI_DEV_ID_82G965 0x29A4 /* 82P965/G965 */ -/** +#define HECI_DEV_ID_82GM965 0x2A04 /* Mobile PM965/GM965 */ +#define HECI_DEV_ID_82GME965 0x2A14 /* Mobile GME965/GLE960 */ + +#define HECI_DEV_ID_ICH9_82Q35 0x29B4 /* 82Q35 Express */ +#define HECI_DEV_ID_ICH9_82G33 0x29C4 /* 82G33/G31/P35/P31 Express */ +#define HECI_DEV_ID_ICH9_82Q33 0x29D4 /* 82Q33 Express */ +#define HECI_DEV_ID_ICH9_82X38 0x29E4 /* 82X38/X48 Express */ +#define HECI_DEV_ID_ICH9_3200 0x29F4 /* 3200/3210 Server */ + +#define HECI_DEV_ID_ICH9_6 0x28B4 /* Bearlake */ +#define HECI_DEV_ID_ICH9_7 0x28C4 /* Bearlake */ +#define HECI_DEV_ID_ICH9_8 0x28D4 /* Bearlake */ +#define HECI_DEV_ID_ICH9_9 0x28E4 /* Bearlake */ +#define HECI_DEV_ID_ICH9_10 0x28F4 /* Bearlake */ + +#define HECI_DEV_ID_ICH9M_1 0x2A44 /* Cantiga */ +#define HECI_DEV_ID_ICH9M_2 0x2A54 /* Cantiga */ +#define HECI_DEV_ID_ICH9M_3 0x2A64 /* Cantiga */ +#define HECI_DEV_ID_ICH9M_4 0x2A74 /* Cantiga */ + +#define HECI_DEV_ID_ICH10_1 0x2E04 /* Eaglelake */ +#define HECI_DEV_ID_ICH10_2 0x2E14 /* Eaglelake */ +#define HECI_DEV_ID_ICH10_3 0x2E24 /* Eaglelake */ +#define HECI_DEV_ID_ICH10_4 0x2E34 /* Eaglelake */ + +/* * heci init function prototypes */ struct iamt_heci_device *init_heci_device(struct pci_dev *pdev); -void heci_reset(struct iamt_heci_device * device_object, int interrupts); -int heci_hw_init(struct iamt_heci_device * device_object); -int heci_initialize_clients(void *data); -struct heci_file_private *alloc_priv(struct file *file); -int heci_disconnect_host_client(struct iamt_heci_device * device_object, - struct heci_file_private * file_extension); +void heci_reset(struct iamt_heci_device *dev, int interrupts); +int heci_hw_init(struct iamt_heci_device *dev); +int heci_task_initialize_clients(void *data); +int heci_initialize_clients(struct iamt_heci_device *dev); +struct heci_file_private *heci_alloc_file_private(struct file *file); +int heci_disconnect_host_client(struct iamt_heci_device *dev, + struct heci_file_private *file_ext); void heci_initialize_list(struct io_heci_list *list, - struct iamt_heci_device * device_object); + struct iamt_heci_device *dev); void heci_flush_list(struct io_heci_list *list, - struct heci_file_private * file_extension); -void heci_flush_queues(struct iamt_heci_device * device_object, - struct heci_file_private * file_extension); + struct heci_file_private *file_ext); +void heci_flush_queues(struct iamt_heci_device *dev, + struct heci_file_private *file_ext); -void heci_remove_client_from_file_list(struct iamt_heci_device * device_object, +void heci_remove_client_from_file_list(struct iamt_heci_device *dev, __u8 host_client_id); -/** +/* * interrupt function prototype */ irqreturn_t heci_isr_interrupt(int irq, void *dev_id); + void heci_wd_timer(unsigned long data); -void heci_bh_handler(struct work_struct *work); -/** + +/* * input output function prototype */ -int heci_ioctl_get_version(struct iamt_heci_device * device, int if_num, +int heci_ioctl_get_version(struct iamt_heci_device *dev, int if_num, struct heci_message_data *u_msg, struct heci_message_data k_msg, - struct heci_file_private * file_extension); -int heci_ioctl_connect_client(struct iamt_heci_device * device, int if_num, + struct heci_file_private *file_ext); + +int heci_ioctl_connect_client(struct iamt_heci_device *dev, int if_num, struct heci_message_data *u_msg, struct heci_message_data k_msg, struct file *file); -int heci_ioctl_wd(struct iamt_heci_device * device, int if_num, + +int heci_ioctl_wd(struct iamt_heci_device *dev, int if_num, struct heci_message_data k_msg, - struct heci_file_private * file_extension); -int legacy_ioctl_send_message(struct iamt_heci_device * device, int if_num, - struct heci_message_data k_msg, - struct file *file); -int legacy_ioctl_receive_message(struct iamt_heci_device * device, int if_num, - struct heci_message_data *u_msg, - struct heci_message_data k_msg, - struct file *file); -int heci_start_read(struct iamt_heci_device * device, int if_num, - struct heci_file_private * file_extension); -int pthi_write(struct iamt_heci_device * device, - struct heci_cb_private *kernel_priv_cb); -int pthi_read(struct iamt_heci_device * device, int if_num, struct file *file, - char *ubuf, size_t length, loff_t* offset); -struct heci_cb_private* find_pthi_read_list_entry(struct iamt_heci_device* device, - struct file* file, struct heci_file_private* file_extension); -void run_next_legacy_cmd(struct iamt_heci_device * device); + struct heci_file_private *file_ext); -#endif /* _HECI_H_ */ +int heci_ioctl_bypass_wd(struct iamt_heci_device *dev, int if_num, + struct heci_message_data k_msg, + struct heci_file_private *file_ext); + +int heci_start_read(struct iamt_heci_device *dev, int if_num, + struct heci_file_private *file_ext); + +int pthi_write(struct iamt_heci_device *dev, + struct heci_cb_private *priv_cb); + +int pthi_read(struct iamt_heci_device *dev, int if_num, struct file *file, + char *ubuf, size_t length, loff_t *offset); + +struct heci_cb_private *find_pthi_read_list_entry( + struct iamt_heci_device *dev, + struct file *file); + +void run_next_iamthif_cmd(struct iamt_heci_device *dev); + +void heci_free_cb_private(struct heci_cb_private *priv_cb); + +/** + * heci_fe_same_id - tell if file private data have same id + * + * @fe1: private data of 1. file object + * @fe2: private data of 2. file object + * + * returns !=0 - if ids are the same, 0 - if differ. + */ +static inline int heci_fe_same_id(const struct heci_file_private *fe1, + const struct heci_file_private *fe2) +{ + return ((fe1->host_client_id == fe2->host_client_id) + && (fe1->me_client_id == fe2->me_client_id)); +} + +#endif /* _HECI_H_ */ Modified: heci/branches/testing/src/heci_data_structures.h =================================================================== --- heci/branches/testing/src/heci_data_structures.h 2008-07-22 16:25:37 UTC (rev 205) +++ heci/branches/testing/src/heci_data_structures.h 2008-07-22 17:13:05 UTC (rev 206) @@ -1,7 +1,7 @@ /* * Part of Intel(R) Manageability Engine Interface Linux driver * - * Copyright (c) 2003 - 2007 Intel Corp. + * Copyright (c) 2003 - 2008 Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -52,116 +52,112 @@ #include <linux/aio.h> #include <linux/types.h> -/** +/* * error code definition */ -#define ESUCCESS 0 #define ESLOTS_OVERFLOW 1 #define ECORRUPTED_MESSAGE_HEADER 1000 #define ECOMPLETE_MESSAGE 1001 -#define FC_MESSAGE_RESERVED_LENGTH 5 -/** +#define HECI_FC_MESSAGE_RESERVED_LENGTH 5 + +/* * Number of queue lists used by this driver */ -#define NUMBER_OF_LISTS 7 +#define HECI_IO_LISTS_NUMBER 7 -#define LEGACY_MTU 4160 -#pragma pack(1) +/* + * Maximum transmission unit (MTU) of heci messages + */ +#define IAMTHIF_MTU 4160 -/** +/* * HECI HW Section */ -/* HECI addresses and defines */ +/* HECI registers */ +/* H_CB_WW - Host Circular Buffer (CB) Write Window register */ #define H_CB_WW 0 +/* H_CSR - Host Control Status register */ #define H_CSR 4 +/* ME_CB_RW - ME Circular Buffer Read Window register (read only) */ #define ME_CB_RW 8 +/* ME_CSR_HA - ME Control Status Host Access register (read only) */ #define ME_CSR_HA 0xC -/* register bits - H_CSR */ - +/* register bits of H_CSR (Host Control Status register) */ +/* Host Circular Buffer Depth - maximum number of 32-bit entries in CB */ #define H_CBD 0xFF000000 +/* Host Circular Buffer Write Pointer */ #define H_CBWP 0x00FF0000 +/* Host Circular Buffer Read Pointer */ #define H_CBRP 0x0000FF00 +/* Host Reset */ #define H_RST 0x00000010 +/* Host Ready */ #define H_RDY 0x00000008 +/* Host Interrupt Generate */ #define H_IG 0x00000004 +/* Host Interrupt Status */ #define H_IS 0x00000002 +/* Host Interrupt Enable */ #define H_IE 0x00000001 -/* register bits - ME_CSR_HA */ +/* register bits of ME_CSR_HA (ME Control Status Host Access register) */ +/* ME CB (Circular Buffer) Depth HRA (Host Read Access) + * - host read only access to ME_CBD */ #define ME_CBD_HRA 0xFF000000 +/* ME CB Write Pointer HRA - host read only access to ME_CBWP */ #define ME_CBWP_HRA 0x00FF0000 +/* ME CB Read Pointer HRA - host read only access to ME_CBRP */ #define ME_CBRP_HRA 0x0000FF00 +/* ME Reset HRA - host read only access to ME_RST */ #define ME_RST_HRA 0x00000010 +/* ME Ready HRA - host read only access to ME_RDY */ #define ME_RDY_HRA 0x00000008 +/* ME Interrupt Generate HRA - host read only access to ME_IG */ #define ME_IG_HRA 0x00000004 +/* ME Interrupt Status HRA - host read only access to ME_IS */ #define ME_IS_HRA 0x00000002 +/* ME Interrupt Enable HRA - host read only access to ME_IE */ #define ME_IE_HRA 0x00000001 -/** - * heci driver use additional char device for legacy mode - */ -#define MINORS_COUNT 2 +#define HECI_MINORS_BASE 1 +#define HECI_MINORS_COUNT 1 -#define LEGACY_MINOR_NUMBER 0 #define HECI_MINOR_NUMBER 1 -#define MAX_OPEN_HANDLE_COUNT 253 -/** +#define HECI_MAX_OPEN_HANDLE_COUNT 253 + +/* * debug kernel print macro define */ -#define INFO(format, arg...) printk(KERN_INFO "%s: " format, THIS_MODULE->name, ## arg) -#define ERR(format, arg...) printk(KERN_ERR "%s: " format, THIS_MODULE->name, ## arg) -#define WARN(format, arg...) printk(KERN_WARNING "%s: " format, THIS_MODULE->name, ## arg) +extern int heci_debug; - -/* Module Parameters */ -#define DEF_PARM(type, name, init, perm, desc) \ - type name = (init); \ - MODULE_PARM_DESC(name, desc); \ - module_param(name, type, perm) - -extern int debug; - -#define DBG(format, arg...) do {if (debug) \ -printk(KERN_ERR "%s: " format , __func__ , ## arg); \ +#define DBG(format, arg...) do { \ + if (heci_debug) \ + printk(KERN_INFO "heci: %s: " format, __func__, ## arg); \ } while (0) -#ifdef HECI_DEBUG -#define assert(expr) do {} while (0) -#else -#define assert(expr) \ - if (!(expr)) { \ - printk("Assertion failed! %s, %s, %s, line=%d\n", \ - #expr, __FILE__, __func__, __LINE__); \ - } -#endif -/** - * time to wait event +/* + * time to wait HECI become ready after init */ #define HECI_INTEROP_TIMEOUT (HZ * 7) -/** +/* * watch dog definition */ #define HECI_WATCHDOG_DATA_SIZE 16 #define HECI_START_WD_DATA_SIZE 20 #define HECI_WD_PARAMS_SIZE 4 +#define HECI_WD_STATE_INDEPENDENCE_MSG_SENT (1 << 0) - #define HECI_WD_HOST_CLIENT_ID 1 -#define HECI_LEGACY_HOST_CLIENT_ID 2 +#define HECI_IAMTHIF_HOST_CLIENT_ID 2 -#undef FALSE -#undef TRUE -#define TRUE 1 -#define FALSE 0 - struct guid { __u32 data1; __u16 data2; @@ -178,8 +174,8 @@ HECI_FILE_DISCONNECTED }; -/* HECI states */ -enum heci_states{ +/* HECI device states */ +enum heci_states { HECI_INITIALIZING = 0, HECI_ENABLED, HECI_RESETING, @@ -189,12 +185,12 @@ HECI_POWER_UP }; -enum legacy_states { - HECI_LEGACY_IDLE, - HECI_LEGACY_WRITING, - HECI_LEGACY_FLOW_CONTROL, - HECI_LEGACY_READING, - HECI_LEGACY_READ_COMPLETE +enum iamthif_states { + HECI_IAMTHIF_IDLE, + HECI_IAMTHIF_WRITING, + HECI_IAMTHIF_FLOW_CONTROL, + HECI_IAMTHIF_READING, + HECI_IAMTHIF_READ_COMPLETE }; enum heci_file_transaction_states { @@ -219,14 +215,12 @@ struct heci_message_data { __u32 size; char *data; -}; -#define SECOND_TO_MILLI 1000 -#define SECOND_TO_MICRO SECOND_TO_MILLI * 1000 -#define SECOND_TO_100NANO SECOND_TO_MICRO * 10 +} __attribute__((packed)); -#define CONNECT_TIMEOUT 3 /* at least 2 seconds */ +#define HECI_CONNECT_TIMEOUT 3 /* at least 2 seconds */ -#define LEGACY_STALL_TIMER 12 /* seconds */ +#define IAMTHIF_STALL_TIMER 12 /* seconds */ +#define IAMTHIF_READ_TIMER 15 /* seconds */ struct heci_cb_private { struct list_head cb_list; @@ -235,6 +229,7 @@ struct heci_message_data request_buffer; struct heci_message_data response_buffer; unsigned long information; + unsigned long read_time; struct file *file_object; }; @@ -246,18 +241,19 @@ wait_queue_head_t tx_wait; wait_queue_head_t rx_wait; wait_queue_head_t wait; - spinlock_t file_lock; - spinlock_t read_io_lock; - spinlock_t write_io_lock; + spinlock_t file_lock; /* file lock */ + spinlock_t read_io_lock; /* read lock */ + spinlock_t write_io_lock; /* write lock */ int read_pending; int status; /* ID of client connected */ __u8 host_client_id; __u8 me_client_id; - __u8 flow_control_credentials; + __u8 flow_ctrl_creds; __u8 timer_count; enum heci_file_transaction_states reading_state; enum heci_file_transaction_states writing_state; + int sm_state; struct heci_cb_private *read_cb; }; @@ -272,138 +268,139 @@ __u8 minor; __u8 hotfix; __u16 build; -}; +} __attribute__((packed)); struct heci_client { - __u32 max_message_length; + __u32 max_msg_length; __u8 protocol_version; -}; +} __attribute__((packed)); + /* * HECI BUS Interface Section */ -struct heci_message_header { - __u32 me_address:8; - __u32 host_address:8; +struct heci_msg_hdr { + __u32 me_addr:8; + __u32 host_addr:8; __u32 length:9; __u32 reserved:6; - __u32 message_complete:1; -}; + __u32 msg_complete:1; +} __attribute__((packed)); -struct hbm_command { - __u8 command:7; +struct hbm_cmd { + __u8 cmd:7; __u8 is_response:1; -}; +} __attribute__((packed)); struct heci_bus_message { - struct hbm_command command; + struct hbm_cmd cmd; __u8 command_specific_data[]; -}; +} __attribute__((packed)); struct hbm_version { __u8 minor_version; __u8 major_version; -}; +} __attribute__((packed)); struct hbm_host_version_request { - struct hbm_command command; + struct hbm_cmd cmd; __u8 reserved; struct hbm_version host_version; -}; +} __attribute__((packed)); struct hbm_host_version_response { - struct hbm_command command; + struct hbm_cmd cmd; int host_version_supported; struct hbm_version me_max_version; -}; +} __attribute__((packed)); struct hbm_host_stop_request { - struct hbm_command command; + struct hbm_cmd cmd; __u8 reason; __u8 reserved[2]; -}; +} __attribute__((packed)); struct hbm_host_stop_response { - struct hbm_command command; + struct hbm_cmd cmd; __u8 reserved[3]; -}; +} __attribute__((packed)); struct hbm_me_stop_request { - struct hbm_command command; + struct hbm_cmd cmd; __u8 reason; __u8 reserved[2]; -}; +} __attribute__((packed)); -struct hbm_host_enumeration_request { - struct hbm_command command; +struct hbm_host_enum_request { + struct hbm_cmd cmd; __u8 reserved[3]; -}; +} __attribute__((packed)); -struct hbm_host_enumeration_response { - struct hbm_command command; +struct hbm_host_enum_response { + struct hbm_cmd cmd; __u8 reserved[3]; __u8 valid_addresses[32]; -}; +} __attribute__((packed)); struct heci_client_properties { struct guid protocol_name; __u8 protocol_version; __u8 max_number_of_connections; __u8 fixed_address; - __u8 single_receive_buffer; - __u32 max_message_length; -}; + __u8 single_recv_buf; + __u32 max_msg_length; +} __attribute__((packed)); -struct hbm_host_client_properties_request { - struct hbm_command command; +struct hbm_props_request { + struct hbm_cmd cmd; __u8 address; __u8 reserved[2]; -}; +} __attribute__((packed)); -struct hbm_host_client_properties_response { - struct hbm_command command; +struct hbm_props_response { + struct hbm_cmd cmd; __u8 address; __u8 status; __u8 reserved[1]; struct heci_client_properties client_properties; -}; +} __attribute__((packed)); struct hbm_client_connect_request { - struct hbm_command command; - __u8 me_address; - __u8 host_address; + struct hbm_cmd cmd; + __u8 me_addr; + __u8 host_addr; __u8 reserved; -}; +} __attribute__((packed)); struct hbm_client_connect_response { - struct hbm_command command; - __u8 me_address; - __u8 host_address; + struct hbm_cmd cmd; + __u8 me_addr; + __u8 host_addr; __u8 status; -}; +} __attribute__((packed)); struct hbm_client_disconnect_request { - struct hbm_command command; - __u8 me_address; - __u8 host_address; + struct hbm_cmd cmd; + __u8 me_addr; + __u8 host_addr; __u8 reserved[1]; -}; +} __attribute__((packed)); struct hbm_flow_control { - struct hbm_command command; - __u8 me_address; - __u8 host_address; - __u8 reserved[FC_MESSAGE_RESERVED_LENGTH]; -}; + struct hbm_cmd cmd; + __u8 me_addr; + __u8 host_addr; + __u8 reserved[HECI_FC_MESSAGE_RESERVED_LENGTH]; +} __attribute__((packed)); struct heci_me_client { - struct heci_client_properties properteis; + struct heci_client_properties props; __u8 client_id; - __u8 flow_control_credentials; -}; + __u8 flow_ctrl_creds; +} __attribute__((packed)); /* private device struct */ struct iamt_heci_device { @@ -411,14 +408,17 @@ /* * lists of queues */ - struct io_heci_list *io_list_array[NUMBER_OF_LISTS]; /* array of pointers to aio lists */ - struct io_heci_list read_list; /* driver read queue */ + /* array of pointers to aio lists */ + struct io_heci_list *io_list_array[HECI_IO_LISTS_NUMBER]; + struct io_heci_list read_list; /* driver read queue */ struct io_heci_list write_list; /* driver write queue */ - struct io_heci_list write_waiting_list; /* driver write waiting queue */ - struct io_heci_list control_write_list; /* driver managed write IOCTL list */ - struct io_heci_list control_read_list; /* driver managed read IOCTL list */ - struct io_heci_list pthi_cmd_list; /* driver managed PTHI list for cmd waiting */ - struct io_heci_list pthi_read_complete_list; /* driver managed PTHI list for read completed pthi command data */ + struct io_heci_list write_waiting_list; /* write waiting queue */ + struct io_heci_list ctrl_wr_list; /* managed write IOCTL list */ + struct io_heci_list ctrl_rd_list; /* managed read IOCTL list */ + struct io_heci_list pthi_cmd_list; /* PTHI list for cmd waiting */ + + /* driver managed PTHI list for reading completed pthi cmd data */ + struct io_heci_list pthi_read_complete_list; /* * list of files */ @@ -432,16 +432,12 @@ /* * lock for the device */ - spinlock_t device_lock; - spinlock_t extra_lock; - /* - * intterupts - */ - int irq; + spinlock_t device_lock; /* device lock*/ struct work_struct work; - int received_message; + int recvd_msg; - struct timer_list timer; + struct task_struct *reinit_tsk; + struct timer_list wd_timer; /* * hw states of host and fw(ME) @@ -451,28 +447,25 @@ /* * waiting queue for receive message from FW */ - wait_queue_head_t wait_received_message; + wait_queue_head_t wait_recvd_msg; wait_queue_head_t wait_stop_wd; /* * heci device states */ enum heci_states heci_state; int stop; - /** - * virtual void GetParam(const char* UserParam); - * read write messages to/from heci fw - */ + __u32 extra_write_index; - __u32 read_message_buffer[128]; /* used for control messages */ - __u32 write_message_buffer[128]; /* used for control messages */ - __u32 extra_message_buffer[8]; /* for control responses */ - __u32 read_message_header; + __u32 rd_msg_buf[128]; /* used for control messages */ + __u32 wr_msg_buf[128]; /* used for control messages */ + __u32 ext_msg_buf[8]; /* for control responses */ + __u32 rd_msg_hdr; struct hbm_version version; int host_buffer_is_empty; - struct heci_file_private wd_file_extension; - struct heci_me_client *me_clients; /* Note: memory has to be allocated */ + struct heci_file_private wd_file_ext; + struct heci_me_client *me_clients; /* Note: memory has to be allocated*/ __u8 heci_me_clients[32]; /* list of existing clients */ __u8 num_heci_me_clients; __u8 heci_host_clients[32]; /* list of existing clients */ @@ -486,21 +479,21 @@ __u16 wd_due_counter; int asf_mode; + int wd_bypass; /* if 1, don't refresh watchdog ME client */ - /* maybe this is not required */ - struct file *legacy_file_object; - struct heci_file_private legacy_file_extension; - int legacy_ioctl; - int legacy_canceled; - __u32 legacy_timer; - __u32 legacy_stall_timer; - unsigned char legacy_message_buffer[LEGACY_MTU]; - __u32 legacy_message_buffer_size; - __u32 legacy_message_buffer_index; - int legacy_flow_control_pending; - enum legacy_states legacy_state; + struct file *iamthif_file_object; + struct heci_file_private iamthif_file_ext; + int iamthif_ioctl; + int iamthif_canceled; + __u32 iamthif_timer; + __u32 iamthif_stall_timer; + unsigned char iamthif_msg_buf[IAMTHIF_MTU]; + __u32 iamthif_msg_buf_size; + __u32 iamthif_msg_buf_index; + int iamthif_flow_control_pending; + enum iamthif_states iamthif_state; - struct heci_cb_private *legacy_current_cb; + struct heci_cb_private *iamthif_current_cb; __u8 write_hang; int need_reset; long open_handle_count; @@ -509,23 +502,29 @@ /** * read_heci_register - Read a byte from the heci device - * @device: the device structure + * + * @dev: the device structure * @offset: offset from which to read the data * - * Return: - * the byte read. + * returns the byte read. */ -__u32 read_heci_register(struct iamt_heci_device * device, - unsigned long offset); +static inline __u32 read_heci_register(struct iamt_heci_device *dev, + unsigned long offset) +{ + return readl(dev->mem_addr + offset); +} /** * write_heci_register - Write 4 bytes to the heci device - * @device: the device structure - * @offset: offset from which to write the data * + * @dev: the device structure + * @offset: offset from which to write the data * @value: the byte to write */ -void write_heci_register(struct iamt_heci_device * device, unsigned long offset, - __u32 value); +static inline void write_heci_register(struct iamt_heci_device *dev, + unsigned long offset, __u32 value) +{ + writel(value, dev->mem_addr + offset); +} -#endif /* _HECI_DATA_STRUCTURES_H_ */ +#endif /* _HECI_DATA_STRUCTURES_H_ */ Modified: heci/branches/testing/src/heci_init.c =================================================================== --- heci/branches/testing/src/heci_init.c 2008-07-22 16:25:37 UTC (rev 205) +++ heci/branches/testing/src/heci_init.c 2008-07-22 17:13:05 UTC (rev 206) @@ -1,7 +1,7 @@ /* * Part of Intel(R) Manageability Engine Interface Linux driver * - * Copyright (c) 2007 Intel Corp. + * Copyright (c) 2003 - 2008 Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -41,919 +41,932 @@ #include <linux/module.h> #include <linux/pci.h> #include <linux/reboot.h> -#include <asm/uaccess.h> #include <linux/poll.h> #include <linux/init.h> #include <linux/kdev_t.h> #include <linux/moduleparam.h> #include <linux/wait.h> #include <linux/delay.h> - +#include <linux/kthread.h> #include "kcompat.h" + #include "heci_data_structures.h" #include "heci_interface.h" #include "heci.h" -const __u8 watch_dog_data[] = - { 1, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 }; -const __u8 start_wd_params[] = { 0x02, 0x12, 0x13, 0x10 }; -const __u8 stop_wd_params[] = { 0x02, 0x02, 0x14, 0x10 }; -const struct guid heci_asf_guid = - { 0x75B30CD6, 0xA29E, 0x4AF7, {0xA7, 0x12, 0xE6, 0x17, 0x43, 0x93, - 0xC8, 0xA6} }; -const struct guid heci_wd_guid = - { 0x05B79A6F, 0x4628, 0x4D7F, {0x89, 0x9D, 0xA9, 0x15, 0x14, 0xCB, - 0x32, 0xAB} }; -const struct guid heci_pthi_guid = - { 0x12f80028, 0xb4b7, 0x4b2d, {0xac, 0xa8, 0x46, 0xe0, 0xff, 0x65, - 0x81, 0x4c} }; +const __u8 heci_start_wd_params[] = { 0x02, 0x12, 0x13, 0x10 }; +const __u8 heci_stop_wd_params[] = { 0x02, 0x02, 0x14, 0x10 }; +const __u8 heci_wd_state_independence_msg[3][4] = { + {0x05, 0x02, 0x51, 0x10}, + {0x05, 0x02, 0x52, 0x10}, + {0x07, 0x02, 0x01, 0x10} +}; -/** +const struct guid heci_asf_guid = { + 0x75B30CD6, 0xA29E, 0x4AF7, + {0xA7, 0x12, 0xE6, 0x17, 0x43, 0x93, 0xC8, 0xA6} +}; +const struct guid heci_wd_guid = { + 0x05B79A6F, 0x4628, 0x4D7F, + {0x89, 0x9D, 0xA9, 0x15, 0x14, 0xCB, 0x32, 0xAB} +}; +const struct guid heci_pthi_guid = { + 0x12f80028, 0xb4b7, 0x4b2d, + {0xac, 0xa8, 0x46, 0xe0, 0xff, 0x65, 0x81, 0x4c} +}; + + +/* * heci init function prototypes */ -int host_start_message(struct iamt_heci_device * device_object); -int host_enum_clients_message(struct iamt_heci_device * device_object); -int allocate_me_clents_storage(struct iamt_heci_device * device_object); -void heci_disable(struct iamt_heci_device * device_object); -void host_init_wd(struct iamt_heci_device * device_object); -void host_init_legacy(struct iamt_heci_device * device_object); +static void heci_check_asf_mode(struct iamt_heci_device *dev); +static int host_start_message(struct iamt_heci_device *dev); +static int host_enum_clients_message(struct iamt_heci_device *dev); +static int allocate_me_clients_storage(struct iamt_heci_device *dev); +static void host_init_wd(struct iamt_heci_device *dev); +static void host_init_iamthif(struct iamt_heci_device *dev); +static int heci_wait_event_int_timeout(struct iamt_heci_device *dev, + long timeout); /** - * heci_initialize_list - Sets up a queue list. + * heci_initialize_list - Sets up a queue list. * - * @list - An instance of our list structure - * @device_object -Device object for our driver - * - * @return : - * none; + * @list: An instance of our list structure + * @dev: Device object for our driver */ void heci_initialize_list(struct io_heci_list *list, - struct iamt_heci_device * device_object) + struct iamt_heci_device *dev) { /* initialize our queue list */ INIT_LIST_HEAD(&list->heci_cb.cb_list); - list->status = ESUCCESS; - list->device_extension = device_object; - return; + list->status = 0; + list->device_extension = dev; } /** - * heci_flush_queues - flush our queues list belong to file_extension. + * heci_flush_queues - flush our queues list belong to file_ext. * - * @device_object -Device object for our driver - * - * @return : - * none; + * @dev: Device object for our driver + * @file_ext: private data of the file object */ -void heci_flush_queues(struct iamt_heci_device * device_object, - struct heci_file_private * file_extension) +void heci_flush_queues(struct iamt_heci_device *dev, + struct heci_file_private *file_ext) { int i; - if (!device_object || !file_extension) + + if (!dev || !file_ext) return; - /* flush our queue list belong to file_extension */ - for (i = 0; i < NUMBER_OF_LISTS; i++) { - DBG("remove list etnry belong to file_extension\n"); - heci_flush_list(device_object->io_list_array[i], - file_extension); - } + /* flush our queue list belong to file_ext */ + for (i = 0; i < HECI_IO_LISTS_NUMBER; i++) { + DBG("remove list entry belong to file_ext\n"); + heci_flush_list(dev->io_list_array[i], file_ext); + } } /** - * heci_flush_list - remove list etnry belong to file_extension. + * heci_flush_list - remove list entry belong to file_ext. * - * @list - An instance of our list structure - * @file_extension -extension of the file object - - * @return : - * none; + * @list: An instance of our list structure + * @file_ext: private data of the file object */ void heci_flush_list(struct io_heci_list *list, - struct heci_file_private * file_extension) + struct heci_file_private *file_ext) { - struct heci_file_private *file_extension_temp = NULL; - struct heci_cb_private *kernel_priv_cb_pos = NULL, *kernel_priv_cb_next = NULL; + struct heci_file_private *file_ext_tmp; + struct heci_cb_private *priv_cb_pos = NULL; + struct heci_cb_private *priv_cb_next = NULL; - if (!list || !file_extension) + if (!list || !file_ext) return; - if (list->status == ESUCCESS - && !list_empty(&list->heci_cb.cb_list)) { - list_for_each_entry_safe(kernel_priv_cb_pos, kernel_priv_cb_next, &list->heci_cb.cb_list, cb_list){ - if (kernel_priv_cb_pos) { - file_extension_temp = - (struct heci_file_private *) - kernel_priv_cb_pos->file_private; - } - if (file_extension_temp) { - if ((file_extension->host_client_id == file_extension_temp-> host_client_id) - && (file_extension->me_client_id == file_extension_temp-> me_client_id)) - list_del(&kernel_priv_cb_pos->cb_list); - } + if (list->status != 0) + return; + if (list_empty(&list->heci_cb.cb_list)) + return; + + list_for_each_entry_safe(priv_cb_pos, priv_cb_next, + &list->heci_cb.cb_list, cb_list) { + if (priv_cb_pos) { + file_ext_tmp = (struct heci_file_private *) + priv_cb_pos->file_private; + if (file_ext_tmp) { + if (heci_fe_same_id(file_ext, file_ext_tmp)) + list_del(&priv_cb_pos->cb_list); + } } } - return; } /** + * heci_reset_iamthif_params - initializes heci device iamthif + * + * @dev: The heci device structure + */ +static void heci_reset_iamthif_params(struct iamt_heci_device *dev) +{ + /* reset iamthif parameters. */ + dev->iamthif_current_cb = NULL; + dev->iamthif_msg_buf_size = 0; + dev->iamthif_msg_buf_index = 0; + dev->iamthif_canceled = 0; + dev->iamthif_file_ext.file = NULL; + dev->iamthif_ioctl = 0; + dev->iamthif_state = HECI_IAMTHIF_IDLE; + dev->iamthif_timer = 0; +} + +/** * init_heci_device - allocates and initializes the heci device structure + * * @pdev: The pci device structure * - * @return : - * The heci_device_device pointer on success, NULL on failure. + * returns The heci_device_device pointer on success, NULL on failure. */ -struct iamt_heci_device *init_heci_device(struct pci_dev * pdev) +struct iamt_heci_device *init_heci_device(struct pci_dev *pdev) { int i; - struct iamt_heci_device *device; - device = kmalloc(sizeof(struct iamt_heci_device), GFP_KERNEL); - if (!device) { + struct iamt_heci_device *dev; + + dev = kzalloc(sizeof(struct iamt_heci_device), GFP_KERNEL); + if (!dev) return NULL; - } /* setup our list array */ - device->io_list_array[0] = &device->read_list; - device->io_list_array[1] = &device->write_list; - device->io_list_array[2] = &device->write_waiting_list; - device->io_list_array[3] = &device->control_write_list; - device->io_list_array[4] = &device->control_read_list; - device->io_list_array[5] = &device->pthi_cmd_list; - device->io_list_array[6] = &device->pthi_read_complete_list; - INIT_LIST_HEAD(&device->file_list); - INIT_LIST_HEAD(&device->wd_file_extension.link); - INIT_LIST_HEAD(&device->legacy_file_extension.link); - spin_lock_init(&device->device_lock); - init_waitqueue_head(&device->wait_received_message); - init_waitqueue_head(&device->wait_stop_wd); - device->open_handle_count = 0; - device->num_heci_me_clients = 0; - device->mem_base = 0; - device->mem_length = 0; - device->extra_write_index = 0; - device->read_message_header = 0; - device->mem_addr = NULL; - device->asf_mode = FALSE; - device->need_reset = FALSE; - device->received_message = FALSE; - device->heci_state = HECI_INITIALIZING; + dev->io_list_array[0] = &dev->read_list; + dev->io_list_array[1] = &dev->write_list; + dev->io_list_array[2] = &dev->write_waiting_list; + dev->io_list_array[3] = &dev->ctrl_wr_list; + dev->io_list_array[4] = &dev->ctrl_rd_list; + dev->io_list_array[5] = &dev->pthi_cmd_list; + dev->io_list_array[6] = &dev->pthi_read_complete_list; + INIT_LIST_HEAD(&dev->file_list); + INIT_LIST_HEAD(&dev->wd_file_ext.link); + INIT_LIST_HEAD(&dev->iamthif_file_ext.link); + spin_lock_init(&dev->device_lock); + init_waitqueue_head(&dev->wait_recvd_msg); + init_waitqueue_head(&dev->wait_stop_wd); + dev->heci_state = HECI_INITIALIZING; + dev->iamthif_state = HECI_IAMTHIF_IDLE; - device->num_heci_me_clients = 0; - device->legacy_current_cb = NULL; - device->legacy_file_object = NULL; - device->legacy_canceled = FALSE; - device->legacy_flow_control_pending = FALSE; - device->legacy_state = HECI_LEGACY_IDLE; - device->legacy_message_buffer_index = 0; - device->wd_pending = FALSE; - device->wd_stoped = FALSE; - - device->me_clients = NULL; /* init work for schedule work */ - INIT_WORK(&device->work, NULL); - for (i = 0; i < NUMBER_OF_LISTS; i++) - heci_initialize_list(device->io_list_array[i], device); - device->pdev = pdev; - return device; + INIT_WORK(&dev->work, NULL); + for (i = 0; i < HECI_IO_LISTS_NUMBER; i++) + heci_initialize_list(dev->io_list_array[i], dev); + dev->pdev = pdev; + return dev; } + + + +static int heci_wait_event_int_timeout(struct iamt_heci_device *dev, + long timeout) +{ + return wait_event_interruptible_timeout(dev->wait_recvd_msg, + (dev->recvd_msg), timeout); +} + /** * heci_hw_init - init host and fw to start work. * - * @device_object -Device object for our driver + * @dev: Device object for our driver * - *@return: - * 0 on success. - * negative on failure + * returns 0 on success, <0 on failure. */ -int heci_hw_init(struct iamt_heci_device * device_object) +int heci_hw_init(struct iamt_heci_device *dev) { int err = 0; - device_object->host_hw_state = - read_heci_register(device_object, H_CSR); - device_object->me_hw_state = - read_heci_register(device_object, ME_CSR_HA); + + dev->host_hw_state = read_heci_register(dev, H_CSR); + dev->me_hw_state = read_heci_register(dev, ME_CSR_HA); DBG("host_hw_state = 0x%08x, mestate = 0x%08x.\n", - device_object->host_hw_state, device_object->me_hw_state); + dev->host_hw_state, dev->me_hw_state); - if ((device_object->host_hw_state & H_IS) == H_IS) { + if ((dev->host_hw_state & H_IS) == H_IS) { /* acknowledge interrupt and stop interupts */ - write_heci_register(device_object, H_CSR, - device_object->host_hw_state); + heci_set_csr_register(dev); } - device_object->received_message = FALSE; + dev->recvd_msg = 0; DBG("reset in start the heci device.\n"); - heci_reset(device_object, TRUE); + heci_reset(dev, 1); DBG("host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n", - device_object->host_hw_state, device_object->me_hw_state); + dev->host_hw_state, dev->me_hw_state); /* wait for ME to turn on ME_RDY */ - if (!device_object->received_message) { - err = - wait_event_interruptible_timeout(device_object-> - wait_received_message, - (device_object-> - received_message), - HECI_INTEROP_TIMEOUT); - } + if (!dev->recvd_msg) + err = heci_wait_event_int_timeout(dev, HECI_INTEROP_TIMEOUT); - if (!err && !device_object->received_message) { - device_object->heci_state = HECI_DISABLED; - DBG("wait_event_interruptible_timeout failed on wait for ME to turn on ME_RDY.\n"); + if (!err && !dev->recvd_msg) { + dev->heci_state = HECI_DISABLED; + DBG("wait_event_interruptible_timeout failed" + "on wait for ME to turn on ME_RDY.\n"); return -ENODEV; } else { - if (!(((device_object->host_hw_state & H_RDY) == H_RDY) - && ((device_object->me_hw_state & ME_RDY_HRA) == - ME_RDY_HRA))) { - device_object->heci_state = HECI_DISABLED; + if (!(((dev->host_hw_state & H_RDY) == H_RDY) + && ((dev->me_hw_state & ME_RDY_HRA) == ME_RDY_HRA))) { + dev->heci_state = HECI_DISABLED; DBG("host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n", - device_object->host_hw_state, - device_object->me_hw_state); + dev->host_hw_state, + dev->me_hw_state); - if (!(device_object->host_hw_state & H_RDY) != H_RDY) + if (!(dev->host_hw_state & H_RDY) != H_RDY) DBG("host turn off H_RDY.\n"); - if (!(device_object->me_hw_state & ME_RDY_HRA) != ME_RDY_HRA) + + if (!(dev->me_hw_state & ME_RDY_HRA) != ME_RDY_HRA) DBG("ME turn off ME_RDY.\n"); - ERR("link layer initialization failed.\n"); + + printk(KERN_ERR + "heci: link layer initialization failed.\n"); return -ENODEV; } } - device_object->received_message = FALSE; + dev->recvd_msg = 0; DBG("host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n", - device_object->host_hw_state, device_object->me_hw_state); + dev->host_hw_state, dev->me_hw_state); DBG("ME turn on ME_RDY and host turn on H_RDY.\n"); - INFO("link layer has been established.\n"); - return ESUCCESS; + printk(KERN_INFO "heci: link layer has been established.\n"); + return 0; } /** - * heci_reset - reset host and fw. + * heci_hw_reset - reset fw via heci csr register. * - * @device_object -Device object for our driver - * @interrupts - if interrupt should be enable after reset. + * @dev: Device object for our driver + * @interrupts: if interrupt should be enable after reset. + */ +static void heci_hw_reset(struct iamt_heci_device *dev, int interrupts) +{ + dev->host_hw_state |= (H_RST | H_IG); + + if (interrupts) + heci_csr_enable_interrupts(dev); + else + heci_csr_disable_interrupts(dev); + + BUG_ON((dev->host_hw_state & H_RST) != H_RST); + BUG_ON((dev->host_hw_state & H_RDY) != 0); +} + +/** + * heci_reset - reset host and fw. * - * @return: - * none; + * @dev: Device object for our driver + * @interrupts: if interrupt should be enable after reset. */ -void heci_reset(struct iamt_heci_device * device_object, int interrupts) +void heci_reset(struct iamt_heci_device *dev, int interrupts) { - struct heci_file_private *file_extension_pos = NULL; - struct heci_file_private *file_extension_next = NULL; - struct heci_cb_private *kernel_priv_cb_pos = NULL, - *kernel_priv_cb_next = NULL; + struct heci_file_private *file_pos = NULL; + struct heci_file_private *file_next = NULL; + struct heci_cb_private *priv_cb_pos = NULL; + struct heci_cb_private *priv_cb_next = NULL; + int unexpected = 0; - if (device_object->heci_state == HECI_RECOVERING_FROM_RESET) { - device_object->need_reset = TRUE; + if (dev->heci_state == HECI_RECOVERING_FROM_RESET) { + dev->need_reset = 1; return; } - device_object->host_hw_state = - read_heci_register(device_object, H_CSR); - DBG("before reset host_hw_state = 0x%08x.\n", - device_object->host_hw_state); + if (dev->heci_state != HECI_INITIALIZING && + dev->heci_state != HECI_DISABLED && + dev->heci_state != HECI_POWER_DOWN && + dev->heci_state != HECI_POWER_UP) + unexpected = 1; - device_object->host_hw_state |= (H_RST | H_IG); + if (dev->reinit_tsk != NULL) { + kthread_stop(dev->reinit_tsk); + dev->reinit_tsk = NULL; + } - if (interrupts) - device_object->host_hw_state |= (H_IE); - else - device_object->host_hw_state &= ~(H_IE); + dev->host_hw_state = read_heci_register(dev, H_CSR); - write_heci_register(device_object, H_CSR, - device_object->host_hw_state); + DBG("before reset host_hw_state = 0x%08x.\n", + dev->host_hw_state); - device_object->host_hw_state = - read_heci_register(device_object, H_CSR); - BUG_ON((device_object->host_hw_state & H_RST) != H_RST); - BUG_ON((device_object->host_hw_state & H_RDY) != 0); + heci_hw_reset(dev, interrupts); - device_object->host_hw_state &= ~H_RST; - device_object->host_hw_state |= H_IG; + dev->host_hw_state &= ~H_RST; + dev->host_hw_state |= H_IG; - write_heci_register(device_object, H_CSR, - device_object->host_hw_state); + write_heci_register(dev, H_CSR, dev->host_hw_state); DBG("currently saved host_hw_state = 0x%08x.\n", - device_object->host_hw_state); + dev->host_hw_state); - device_object->need_reset = FALSE; + dev->need_reset = 0; - if (device_object->heci_state != HECI_INITIALIZING) { - if (device_object->heci_state != HECI_DISABLED) { - device_object->heci_state = HECI_RESETING; + if (dev->heci_state != HECI_INITIALIZING) { + if ((dev->heci_state != HECI_DISABLED) && + (dev->heci_state != HECI_POWER_DOWN)) + dev->heci_state = HECI_RESETING; + + list_for_each_entry_safe(file_pos, + file_next, &dev->file_list, link) { + file_pos->state = HECI_FILE_DISCONNECTED; + file_pos->flow_ctrl_creds = 0; + file_pos->read_cb = NULL; + file_pos->timer_count = 0; } - list_for_each_entry_safe(file_extension_pos, file_extension_next, &device_object->file_list, link) { - file_extension_pos->state = HECI_FILE_DISCONNECTED; - file_extension_pos->flow_control_credentials = 0; - file_extension_pos->read_cb = NULL; - file_extension_pos->timer_count = 0; - } /* remove entry if already in list */ - DBG("list del legacy and wd file list.\n"); - heci_remove_client_from_file_list(device_object, - device_object-> - wd_file_extension. - host_client_id); + DBG("list del iamthif and wd file list.\n"); + heci_remove_client_from_file_list(dev, + dev->wd_file_ext.host_client_id); - heci_remove_client_from_file_list(device_object, - device_object-> - legacy_file_extension. - host_client_id); - /* reset legacy parameters. */ - device_object->legacy_current_cb = NULL; - device_object->legacy_message_buffer_size = 0; - device_object->legacy_message_buffer_index = 0; - device_object->legacy_canceled = FALSE; - device_object->legacy_file_extension.file = NULL; - device_object->legacy_ioctl = FALSE; - device_object->legacy_state = HECI_LEGACY_IDLE; - device_object->legacy_timer = 0; - device_object->wd_due_counter = 0; - device_object->extra_write_index = 0; - device_object->wd_pending = FALSE; + heci_remove_client_from_file_list(dev, + dev->iamthif_file_ext.host_client_id); + + heci_reset_iamthif_params(dev); + dev->wd_due_counter = 0; + dev->extra_write_index = 0; } - device_object->num_heci_me_clients = 0; - device_object->read_message_header = 0; - device_object->stop = FALSE; - device_object->wd_pending = 0; + dev->num_heci_me_clients = 0; + dev->rd_msg_hdr = 0; + dev->stop = 0; + dev->wd_pending = 0; /* update the state of the registers after reset */ - device_object->host_hw_state = - read_heci_register(device_object, H_CSR); - device_object->me_hw_state = - read_heci_register(device_object, ME_CSR_HA); + dev->host_hw_state = read_heci_register(dev, H_CSR); + dev->me_hw_state = read_heci_register(dev, ME_CSR_HA); DBG("after reset host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n", - device_object->host_hw_state, device_object->me_hw_state); + dev->host_hw_state, dev->me_hw_state); - if (device_object->heci_state != HECI_INITIALIZING && - device_object->heci_state != HECI_DISABLED) - ERR("unexpected heci reset.\n"); - //Wake up all readings so they can be interrupted - list_for_each_entry_safe(file_extension_pos,file_extension_next, &device_object->file_list,link) { - if (&file_extension_pos->rx_wait && - waitqueue_active (&file_extension_pos->rx_wait)) { - INFO("Waking up client!\n"); - wake_up_interruptible(&file_extension_pos->rx_wait); - } + if (unexpected) + printk(KERN_WARNING "heci: unexpected reset.\n"); + + /* Wake up all readings so they can be interrupted */ + list_for_each_entry_safe(file_pos, file_next, &dev->file_list, link) { + if (&file_pos->rx_wait && + waitqueue_active(&file_pos->rx_wait)) { + printk(KERN_INFO "heci: Waking up client!\n"); + wake_up_interruptible(&file_pos->rx_wait); } - // remove all waiting requests - if (device_object->write_list.status == ESUCCESS && !list_empty(&device_object->write_list.heci_cb.cb_list)) { - list_for_each_entry_safe(kernel_priv_cb_pos, kernel_priv_cb_next, &device_object->write_list.heci_cb.cb_list, cb_list){ - if (kernel_priv_cb_pos) { - list_del(&kernel_priv_cb_pos->cb_list); - kfree(kernel_priv_cb_pos->request_buffer.data); - kernel_priv_cb_pos->request_buffer.data = NULL; - kfree(kernel_priv_cb_pos->response_buffer.data); - kernel_priv_cb_pos->response_buffer.data = NULL; - kfree(kernel_priv_cb_pos); - kernel_priv_cb_pos = NULL; + } + /* remove all waiting requests */ + if (dev->write_list.status == 0 && + !list_empty(&dev->write_list.heci_cb.cb_list)) { + list_for_each_entry_safe(priv_cb_pos, priv_cb_next, + &dev->write_list.heci_cb.cb_list, cb_list) { + if (priv_cb_pos) { + list_del(&priv_cb_pos->cb_list); + heci_free_cb_private(priv_cb_pos); } } } - - } /** - * heci_disable - reseting in disable routine. + * heci_initialize_clients - heci communication initialization. * - * @device_object -Device object for our driver - * - * @return: - * none; + * @dev: Device object for our driver */ -void heci_disable(struct iamt_heci_device * device_object) +int heci_initialize_clients(struct iamt_heci_device *dev) { - if (device_object->heci_state != HECI_INITIALIZING) - ERR("driver stop request heci state is disable.\n"); - device_object->heci_state = HECI_DISABLED; -} - -/** - * heci_initialize_clients - routine. - * - * @device_object -Device object for our driver - * - * @return: - * none; - */ -int heci_initialize_clients(void *data) -{ - int status; - struct iamt_heci_device *device_object = (struct iamt_heci_device *) data; + + msleep(100); /* FW needs time to be ready to talk with us */ DBG("link is established start sending messages.\n"); /* link is established start sending messages. */ - status = host_start_message(device_object); - if (status) { + status = host_start_message(dev); + if (status != 0) { + spin_lock_bh(&dev->device_lock); + dev->heci_state = HECI_DISABLED; + spin_unlock_bh(&dev->device_lock); DBG("start sending messages failed.\n"); - return -ENODEV; + return status; } - /* enumerate clients */ - status = host_enum_clients_message(device_object); - if (status) { + /* enumerate clients */ + status = host_enum_clients_message(dev); + if (status != 0) { + spin_lock_bh(&dev->device_lock); + dev->heci_state = HECI_DISABLED; + spin_unlock_bh(&dev->device_lock); DBG("enum clients failed.\n"); - return -ENODEV; + return status; } /* allocate storage for ME clients representation */ - status = allocate_me_clents_storage(device_object); - if (status) { + status = allocate_me_clients_storage(dev); + if (status != 0) { + spin_lock_bh(&dev->device_lock); + dev->num_heci_me_clients = 0; + dev->heci_state = HECI_DISABLED; + spin_unlock_bh(&dev->device_lock); DBG("allocate clients failed.\n"); - return -ENODEV; + return status; } + + heci_check_asf_mode(dev); /*heci initialization wd */ - host_init_wd(device_object); - /*heci initialization legacy client */ - host_init_legacy(device_object); - if (device_object->need_reset) { - device_object->need_reset = FALSE; - device_object->heci_state = HECI_DISABLED; + host_init_wd(dev); + /*heci initialization iamthif client */ + host_init_iamthif(dev); + + spin_lock_bh(&dev->device_lock); + if (dev->need_reset) { + dev->need_reset = 0; + dev->heci_state = HECI_DISABLED; + spin_unlock_bh(&dev->device_lock); return -ENODEV; } - memset(device_object->heci_host_clients, 0, - sizeof(device_object->heci_host_clients)); - device_object->open_handle_count = 0; - device_object->heci_host_clients[0] |= 7; - device_object->current_host_client_id = 3; - device_object->heci_state = HECI_ENABLED; + memset(dev->heci_host_clients, 0, sizeof(dev->heci_host_clients)); + dev->open_handle_count = 0; + dev->heci_host_clients[0] |= 7; + dev->current_host_client_id = 3; + dev->heci_state = HECI_ENABLED; + spin_unlock_bh(&dev->device_lock); DBG("initialization heci clients successful.\n"); - return ESUCCESS; + return 0; } /** + * heci_task_initialize_clients - heci reinitialization task + * + * @data: Device object for our driver + */ +int heci_task_initialize_clients(void *data) +{ + int ret; + struct iamt_heci_device *dev = (struct iamt_heci_device *) data; + + spin_lock_bh(&dev->device_lock); + if (dev->reinit_tsk != NULL) { + spin_unlock_bh(&dev->device_lock); + DBG("reinit task already started.\n"); + return 0; + } + dev->reinit_tsk = current; + current->flags |= PF_NOFREEZE; + spin_unlock_bh(&dev->device_lock); + + ret = heci_initialize_clients(dev); + + spin_lock_bh(&dev->device_lock); + dev->reinit_tsk = NULL; + spin_unlock_bh(&dev->device_lock); + + return ret; +} + +/** * host_start_message - heci host send start message. * - * @device_object - Device object for our driver + * @dev: Device object for our driver * - * @return : - * 0 on success, - * negative on failure. + * returns 0 on success, <0 on failure. */ -int host_start_message(struct iamt_heci_device * device_object) +static int host_start_message(struct iamt_heci_device *dev) { - long timeout = 10; /* 10 second */ + long timeout = 60; /* 60 second */ - struct heci_message_header *heci_header; + struct heci_msg_hdr *heci_hdr; struct hbm_host_version_request *host_start_req; struct hbm_host_stop_request *host_stop_req; int err = 0; + /* host start message */ - msleep(100); - heci_header = - (struct heci_message_header *) & device_object-> - write_message_buffer[0]; - heci_header->host_address = 0; - heci_header->me_address = 0; - heci_header->length = sizeof(struct hbm_host_version_request); - heci_header->message_complete = 1; - heci_header->reserved = 0; + heci_hdr = (struct heci_msg_hdr *) &dev->wr_msg_buf[0]; + heci_hdr->host_addr = 0; + heci_hdr->me_addr = 0; + heci_hdr->length = sizeof(struct hbm_host_version_request); + heci_hdr->msg_complete = 1; + heci_hdr->reserved = 0; host_start_req = - (struct hbm_host_version_request *) & device_object-> - write_message_buffer[1]; - memset(host_start_req, 0, sizeof(host_start_req)); - host_start_req->command.command = HOST_START_REQ_CMD; - host_start_req->reserved = 0; + (struct hbm_host_version_request *) &dev->wr_msg_buf[1]; + memset(host_start_req, 0, sizeof(struct hbm_host_version_request)); + host_start_req->cmd.cmd = HOST_START_REQ_CMD; host_start_req->host_version.major_version = HBM_MAJOR_VERSION; host_start_req->host_version.minor_version = HBM_MINOR_VERSION; - device_object->received_message = FALSE; - if (!heci_write_message(device_object, heci_header, + dev->recvd_msg = 0; + if (!heci_write_message(dev, heci_hdr, (unsigned char *) (host_start_req), - heci_header->length)) { - device_object->heci_state = HECI_DISABLED; + heci_hdr->length)) { DBG("send version to fw fail.\n"); return -ENODEV; } - DBG("call wait_event_interruptible_timeout for response message. \n"); + DBG("call wait_event_interruptible_timeout for response message.\n"); /* wait for response */ - err = - wait_event_interruptible_timeout(device_object-> - wait_received_message, - (device_object-> - received_message), - timeout * HZ); - if (!err && !device_object->received_message) { - device_object->heci_state = HECI_DISABLED; - DBG("wait_event_interruptible_timeout failed on host start response message. \n"); + err = heci_wait_event_int_timeout(dev, timeout * HZ); + if (!err && !dev->recvd_msg) { + DBG("wait_timeout failed on host start response message.\n"); return -ENODEV; } - device_object->received_message = FALSE; - DBG("wait_event_interruptible_timeout successful on host start response message. \n"); - if ((device_object->version.major_version != HBM_MAJOR_VERSION) || - (device_object->version.minor_version != HBM_MINOR_VERSION)) { + dev->recvd_msg = 0; + DBG("wait_timeout successful on host start response message.\n"); + if ((dev->version.major_version != HBM_MAJOR_VERSION) || + (dev->version.minor_version != HBM_MINOR_VERSION)) { /* send stop message */ - heci_header->host_address = 0; - heci_header->me_address = 0; - heci_header->length = sizeof(struct hbm_host_stop_request); - heci_header->message_complete = 1; - heci_header->reserved = 0; + heci_hdr->host_addr = 0; + heci_hdr->me_addr = 0; + heci_hdr->length = sizeof(struct hbm_host_stop_request); + heci_hdr->msg_complete = 1; + heci_hdr->reserved = 0; host_stop_req = - (struct hbm_host_stop_request *) & device_object-> - write_message_buffer[1]; + (struct hbm_host_stop_request *) &dev->wr_msg_buf[1]; - memset(host_stop_req, 0, sizeof(host_stop_req)); - host_st... [truncated message content] |