<|start_filename|>3rdpart/tslib-1.15/plugins/touchkit-raw.c<|end_filename|>
/*
 * SPDX-License-Identifier: LGPL-2.1
 */
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <termios.h>
#include <string.h>

#include "config.h"
#include "tslib-private.h"

/*
 * TouchKit RS232 driver
 * (controller type SAT4000UR)
 * 2009.07  <NAME>
 *
 * Packet format for position report (5 bytes):
 * [0] 1 0 0 0 0 0 0 t = header (t=touched)
 * [1] 0 0 0 0 X X X X = X coord most significant bits
 * [2] 0 X X X X X X X = X coord less significant bits
 * [3] 0 0 0 0 Y Y Y Y = Y coord most significant bits
 * [4] 0 Y Y Y Y Y Y Y = Y coord less significant bits
 *
 * Problem: sometimes some packets overlap, so it is possible
 * to find a new packet in the middle of another packet.
 * -> check that no byte in the packet (but the first one)
 *    have its first bit set (0x80 = start)
 *
 * This file is placed under the LGPL.  Please see the file
 * COPYING for more details.
 */

enum {
	PACKET_SIZE = 5,
	BUFFER_SIZE = 100,
	PACKET_SIGNATURE = 0x81
};

/* Is is a start of packet ? */
#define IsStart(x) (((x)|1) == PACKET_SIGNATURE)

static int touchkit_init(int dev)
{
	struct termios tty;

	tcgetattr(dev, &tty);
	tty.c_iflag = IGNBRK | IGNPAR;
	tty.c_oflag = 0;
	tty.c_lflag = 0;
#ifdef __linux__
	tty.c_line = 0;
#endif
	tty.c_cc[VTIME] = 0;
	tty.c_cc[VMIN] = 1;
	tty.c_cflag = CS8 | CREAD | CLOCAL | HUPCL;
	tty.c_cflag |= B9600;
	tcsetattr(dev, TCSAFLUSH, &tty);

	return 1;
}

static int touchkit_read(struct tslib_module_info *inf, struct ts_sample *samp,
			 __attribute__ ((unused)) int nr)
{
	static int initDone;
	/* enough space for 2 "normal" packets */
	static unsigned char buffer[BUFFER_SIZE];
	static int pos;
	int ret;
	struct tsdev *ts = inf->dev;
	int p;
	int total = 0;
	int q;

	if (initDone == 0) {
		initDone = touchkit_init(ts->fd);
		if (initDone == -1)
			return -1;
	}
	/* read some new bytes (enough for 1 normal packet) */
	ret = read(ts->fd, buffer + pos, PACKET_SIZE);
	if (ret <= 0)
		return -1;

	pos += ret;
	if (pos < PACKET_SIZE)
		return 0;

	/* find start */
	for (p = 0; p < pos; ++p)
		if (IsStart(buffer[p])) {
			/* we have enough data for a packet ? */
			if (p + PACKET_SIZE > pos) {
				if (p > 0) {
					/*
					 * we have found a start >0, it means
					 * we have garbage at beginning of
					 * buffer so let's shift data to ignore
					 * this garbage
					 */
					memcpy(buffer, buffer + p, pos - p);
					pos -= p;
				}
				break;
			}

			unsigned char *data = buffer + p;

			/* check if all bytes are ok (no 'start' embedded) */
			for (q = 1; q < PACKET_SIZE; ++q)
				if (IsStart(buffer[p + q]))
					break;
			if (q < PACKET_SIZE) {
#ifdef DEBUG
				fprintf(stderr,
					"Start found within packet [%X %X %X %X %X] ignore %d bytes\n",
					data[0], data[1], data[2], data[3],
					data[4], q);
#endif
				p += q - 1;
				continue;
			}
			/* now let's decode it */
			samp->x = (data[1] & 0x000F) << 7 | (data[2] & 0x007F);
			samp->y =
			    ((data[3] & 0x000F) << 7 | (data[4] & 0x007F));
			samp->pressure = (data[0] & 1) ? 200 : 0;
			gettimeofday(&samp->tv, NULL);
#ifdef DEBUG
			fprintf(stderr,
				"RAW -------------------------> data=[%X %X %X %X %X]  x=%d y=%d pres=%d\n",
				data[0], data[1], data[2], data[3], data[4],
				samp->x, samp->y, samp->pressure);
#endif
			samp++;

			/* now remove it */
			memcpy(buffer, buffer + p + PACKET_SIZE,
			       pos - p - PACKET_SIZE);
			pos -= p + PACKET_SIZE;
			total = 1;
			break;
		}

	return total;
}

static const struct tslib_ops touchkit_ops = {
	.read = touchkit_read,
};

TSAPI struct tslib_module_info *touchkit_mod_init(__attribute__ ((unused)) struct tsdev *dev,
						  __attribute__ ((unused)) const char *params)
{
	struct tslib_module_info *m;

	m = malloc(sizeof(struct tslib_module_info));
	if (m == NULL)
		return NULL;

	m->ops = &touchkit_ops;
	return m;
}
#ifndef TSLIB_STATIC_TOUCHKIT_MODULE
	TSLIB_MODULE_INIT(touchkit_mod_init);
#endif


<|start_filename|>apps/ecat-master/main/gui.c<|end_filename|>
/*
 * gui.c
 *
 *  Created on: Mar 16, 2018
 *      Author: morris
 */
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <pthread.h>
#include <unistd.h>
#include "lv_drivers/display/fbdev.h"
#include "indev_tslib.h"
#include "gui.h"
#include "ecat.h"
#include "utils.h"

static lv_obj_t * chart_temp = NULL;
static lv_chart_series_t * ch1ser1 = NULL;
static lv_chart_series_t * ch1ser2 = NULL;
static lv_obj_t * gauge = NULL;

static bool thread_running = true;
/* 互斥锁 */
static pthread_mutex_t mutex;
/* 控制变量 */
static unsigned int control_value = 0;

static void hal_disp_init(void) {
	/* 初始化Linux Frame Buffer设备 */
	fbdev_init();
	/* 注册显示器驱动 */
	lv_disp_drv_t disp_drv;
	lv_disp_drv_init(&disp_drv);
	disp_drv.disp_flush = fbdev_flush; /* 将内部图像缓存刷新到显示器上 */
	lv_disp_drv_register(&disp_drv);
}

static void hal_input_init(void) {
	/* 初始化输入设备和tslib中间件 */
	indev_init();
	/* 注册输入设备 */
	lv_indev_drv_t indev_drv;
	lv_indev_drv_init(&indev_drv);
	indev_drv.type = LV_INDEV_TYPE_POINTER;
	indev_drv.read = indev_ts_read;
	lv_indev_drv_register(&indev_drv);
}

static void charts_temp(lv_obj_t* parent) {
	chart_temp = lv_chart_create(parent, NULL);
	lv_obj_set_size(chart_temp, 400, 200);
	lv_obj_align(chart_temp, NULL, LV_ALIGN_CENTER, 0, 0);
	lv_chart_set_type(chart_temp, LV_CHART_TYPE_POINT | LV_CHART_TYPE_LINE);
	lv_chart_set_series_opa(chart_temp, LV_OPA_70);
	lv_chart_set_series_width(chart_temp, 4);
	lv_chart_set_range(chart_temp, 0, 1000);
	/* 向charts中插入数据 */
	ch1ser1 = lv_chart_add_series(chart_temp, LV_COLOR_RED);
	ch1ser2 = lv_chart_add_series(chart_temp, LV_COLOR_BLUE);
}

static void guage_cpu(lv_obj_t* parent) {
	static lv_color_t needle_colors[] = { LV_COLOR_RED };
	gauge = lv_gauge_create(parent, NULL);
	lv_gauge_set_needle_count(gauge,
			sizeof(needle_colors) / sizeof(needle_colors[0]), needle_colors);
	lv_obj_align(gauge, NULL, LV_ALIGN_CENTER, 0, 0);
	/* 设置仪表盘指针的数据 */
	lv_gauge_set_value(gauge, 0, 50);
}

static lv_res_t on_led_switch_toggled(lv_obj_t * sw) {
	/* 根据绝对坐标判断具体的开关 */
	unsigned int led_bit = 0;
	led_bit += sw->coords.y1 / 50 - 1;
	if (sw->coords.x1 > 200) {
		led_bit += 4;
	}
	/* 更新控制变量 */
	pthread_mutex_lock(&mutex);
	control_value &= ~(1 << led_bit);
	control_value |= (lv_sw_get_state(sw) << led_bit);
	pthread_mutex_unlock(&mutex);
	return LV_RES_OK;
}

static void control_panel(lv_obj_t* parent) {
	char name[10];
	int i;
	lv_obj_t* labels[8];
	lv_obj_t* switches[8];
	/* 创建8个LED标签，布局 */
	for (i = 0; i < 8; i++) {
		labels[i] = lv_label_create(parent, NULL);
		sprintf(name, "LED%d", i + 1);
		lv_label_set_text(labels[i], name);
	}
	lv_obj_align(labels[0], NULL, LV_ALIGN_IN_TOP_LEFT, 50, 20);
	for (i = 1; i < 4; i++) {
		lv_obj_align(labels[i], labels[i - 1], LV_ALIGN_OUT_BOTTOM_MID, 0, 30);
	}
	for (i = 4; i < 8; i++) {
		lv_obj_align(labels[i], labels[i - 4], LV_ALIGN_OUT_RIGHT_MID, 200, 0);
	}
	/* 创建8个开关，布局 */
	for (i = 0; i < 8; i++) {
		switches[i] = lv_sw_create(parent, NULL);
		lv_obj_align(switches[i], labels[i], LV_ALIGN_OUT_RIGHT_MID, 5, 0);
		lv_sw_set_action(switches[i], on_led_switch_toggled);
	}
}

static void* gui_tick(void *arg) {
	pthread_mutex_lock(&mutex);
	while (thread_running) {
		pthread_mutex_unlock(&mutex);
		lv_tick_inc(1);
		lv_task_handler();
		usleep(1000);
		pthread_mutex_lock(&mutex);
	}
	pthread_mutex_unlock(&mutex);
	pthread_mutex_destroy(&mutex);
	pthread_exit(arg);
}

int gui_init(void) {
	int ret;
	pthread_t thread_hdl;
	pthread_attr_t attr;

	/* 初始化LittlevGL库 */
	lv_init();
	/* 初始化显示器底层硬件 */
	hal_disp_init();
	/* 初始化输入设备底层硬件 */
	hal_input_init();

	/* 创建一个屏幕 */
	lv_obj_t *scr = lv_obj_create(NULL, NULL);
	lv_scr_load(scr);

	/* 初始化alien主题 */
	lv_theme_t *th = lv_theme_alien_init(100, NULL);
	lv_theme_set_current(th);

	/* 创建Tab视图容器 */
	lv_obj_t *tabview = lv_tabview_create(lv_scr_act(), NULL);

	/* 创建三个标签选项卡 */
	lv_obj_t *tab1 = lv_tabview_add_tab(tabview, SYMBOL_LOOP);
	lv_obj_t *tab2 = lv_tabview_add_tab(tabview, SYMBOL_HOME);
	lv_obj_t *tab3 = lv_tabview_add_tab(tabview, SYMBOL_SETTINGS);

	/* 创建仪表盘 */
	guage_cpu(tab1);
	/* 创建charts */
	charts_temp(tab2);
	/* 创建控制面板 */
	control_panel(tab3);
	/* 设置默认显示页 */
	lv_tabview_set_tab_act(tabview, 1, false);

	/* 初始化互斥锁 */
	pthread_mutex_init(&mutex, NULL);
	/* 设置线程的分离属性 */
	pthread_attr_init(&attr);
	ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
	if (ret) {
		perror("pthread_attr_setdetachstate");
		goto err;
	}
	/* 设置线程的绑定属性 */
	ret = pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
	if (ret) {
		perror("pthread_attr_setscope");
		goto err;
	}
	/* 创建线程 */
	ret = pthread_create(&thread_hdl, &attr, gui_tick, NULL);
	if (ret) {
		perror("pthread_create");
		goto err;
	}
	/* 释放线程属性对象 */
	pthread_attr_destroy(&attr);
	return 0;
	err:
	/* 释放线程属性对象 */
	pthread_attr_destroy(&attr);
	/* 释放互斥锁对象 */
	pthread_mutex_destroy(&mutex);
	return ret;
}

void gui_stop(void) {
	indev_stop();
	pthread_mutex_lock(&mutex);
	thread_running = false;
	pthread_mutex_unlock(&mutex);
}

void gui_user_work(void* arg) {
	ecat_user* user_data = (ecat_user*) arg;
	uint8_t usage;
	utils_cpu_usage(&usage);
	lv_gauge_set_value(gauge, 0, usage);
	lv_chart_set_next(chart_temp, ch1ser1, user_data->sensor_temp0);
	lv_chart_set_next(chart_temp, ch1ser2, user_data->sensor_temp1);
	pthread_mutex_lock(&mutex);
	user_data->blink0 = control_value;
	pthread_mutex_unlock(&mutex);
	user_data->blink1++;
}


<|start_filename|>3rdpart/tslib-1.15/src/ts_read.c<|end_filename|>
/*
 *  tslib/src/ts_read.c
 *
 *  Copyright (C) 2001 <NAME>.
 *
 * This file is placed under the LGPL.  Please see the file
 * COPYING for more details.
 *
 * SPDX-License-Identifier: LGPL-2.1
 *
 *
 * Read touch samples as tslib sample structs
 */
#include "config.h"

#include "tslib-private.h"

#ifdef DEBUG
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#endif

int ts_read(struct tsdev *ts, struct ts_sample *samp, int nr)
{
	int result;
#ifdef DEBUG
	int i;
#endif

	result = ts->list->ops->read(ts->list, samp, nr);
#ifdef DEBUG
	for (i = 0; i < result; i++) {
		fprintf(stderr, "TS_READ----> x = %d, y = %d, pressure = %d\n",
			samp->x, samp->y, samp->pressure);

		samp++;
	}
#endif
	return result;

}

int ts_read_mt(struct tsdev *ts, struct ts_sample_mt **samp, int max_slots,
	       int nr)
{
	int result;
#ifdef DEBUG
	int i, j;
#endif

	result = ts->list->ops->read_mt(ts->list, samp, max_slots, nr);
#ifdef DEBUG
	for (j = 0; j < result; j++) {
		for (i = 0; i < max_slots; i++) {
			if (!(samp[j][i].valid & TSLIB_MT_VALID))
				continue;

			ts_error("TS_READ_MT----> slot %d: x = %d, y = %d, pressure = %d\n",
				 samp[j][i].slot, samp[j][i].x, samp[j][i].y,
				 samp[j][i].pressure);
		}
	}
#endif
	return result;

}


<|start_filename|>3rdpart/ethercat-1.5.2/master/soe_request.h<|end_filename|>
/******************************************************************************
 *
 *  $Id: soe_request.h,v 7d9fb723fc4b 2010/07/20 08:52:31 fp $
 *
 *  Copyright (C) 2006-2008  <NAME>, Ingenieurgemeinschaft IgH
 *
 *  This file is part of the IgH EtherCAT Master.
 *
 *  The IgH EtherCAT Master is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License version 2, as
 *  published by the Free Software Foundation.
 *
 *  The IgH EtherCAT Master is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 *  Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with the IgH EtherCAT Master; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 *****************************************************************************/

/**
   \file
   EtherCAT SoE request structure.
*/

/*****************************************************************************/

#ifndef __EC_SOE_REQUEST_H__
#define __EC_SOE_REQUEST_H__

#include <linux/list.h>

#include "globals.h"

/*****************************************************************************/

/** Sercos-over-EtherCAT request.
 */
typedef struct {
    struct list_head list; /**< List item. */
    uint8_t drive_no; /**< Drive number. */
    uint16_t idn; /**< Sercos ID-Number. */
    ec_al_state_t al_state; /**< AL state (only valid for IDN config). */
    uint8_t *data; /**< Pointer to SDO data. */
    size_t mem_size; /**< Size of SDO data memory. */
    size_t data_size; /**< Size of SDO data. */
    ec_direction_t dir; /**< Direction. EC_DIR_OUTPUT means writing to the
                          slave, EC_DIR_INPUT means reading from the slave. */
    ec_internal_request_state_t state; /**< Request state. */
    unsigned long jiffies_sent; /**< Jiffies, when the upload/download
                                     request was sent. */
    uint16_t error_code; /**< SoE error code. */
} ec_soe_request_t;

/*****************************************************************************/

void ec_soe_request_init(ec_soe_request_t *);
void ec_soe_request_clear(ec_soe_request_t *);

int ec_soe_request_copy(ec_soe_request_t *, const ec_soe_request_t *);
void ec_soe_request_set_drive_no(ec_soe_request_t *, uint8_t);
void ec_soe_request_set_idn(ec_soe_request_t *, uint16_t);
int ec_soe_request_alloc(ec_soe_request_t *, size_t);
int ec_soe_request_copy_data(ec_soe_request_t *, const uint8_t *, size_t);
int ec_soe_request_append_data(ec_soe_request_t *, const uint8_t *, size_t);
void ec_soe_request_read(ec_soe_request_t *);
void ec_soe_request_write(ec_soe_request_t *);

/*****************************************************************************/

#endif


<|start_filename|>3rdpart/ethercat-1.5.2/tool/Makefile<|end_filename|>
# Makefile.in generated by automake 1.11.1 from Makefile.am.
# tool/Makefile.  Generated from Makefile.in by configure.

# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
# Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.



#------------------------------------------------------------------------------
#
#  $Id: Makefile.am,v bc2d4bf9cbe5 2012/09/06 18:22:24 fp $
#
#  Copyright (C) 2006-2008  <NAME>, Ingenieurgemeinschaft IgH
#
#  This file is part of the IgH EtherCAT Master.
#
#  The IgH EtherCAT Master is free software; you can redistribute it and/or
#  modify it under the terms of the GNU General Public License version 2, as
#  published by the Free Software Foundation.
#
#  The IgH EtherCAT Master is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
#  Public License for more details.
#
#  You should have received a copy of the GNU General Public License along
#  with the IgH EtherCAT Master; if not, write to the Free Software
#  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
#
#  ---
#
#  The license mentioned above concerns the source code only. Using the
#  EtherCAT technology and brand is only permitted in compliance with the
#  industrial property and similar rights of Beckhoff Automation GmbH.
#
#  ---
#
#  vim: syntax=automake
#
#------------------------------------------------------------------------------



pkgdatadir = $(datadir)/ethercat
pkgincludedir = $(includedir)/ethercat
pkglibdir = $(libdir)/ethercat
pkglibexecdir = $(libexecdir)/ethercat
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = x86_64-unknown-linux-gnu
host_triplet = arm-unknown-linux-gnueabihf
bin_PROGRAMS = ethercat$(EXEEXT)
am__append_1 = CommandEoe.cpp
#am__append_2 = CommandEoe.cpp CommandEoe.h
am__append_3 = CommandEoe.h
subdir = tool
DIST_COMMON = $(am__noinst_HEADERS_DIST) $(srcdir)/Makefile.am \
	$(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
	$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
	$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
	$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
	$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
am__installdirs = "$(DESTDIR)$(bindir)"
PROGRAMS = $(bin_PROGRAMS)
am__ethercat_SOURCES_DIST = ../master/soe_errors.c Command.cpp \
	CommandAlias.cpp CommandCStruct.cpp CommandConfig.cpp \
	CommandData.cpp CommandDebug.cpp CommandDomains.cpp \
	CommandDownload.cpp CommandFoeRead.cpp CommandFoeWrite.cpp \
	CommandGraph.cpp CommandMaster.cpp CommandPdos.cpp \
	CommandRegRead.cpp CommandRegWrite.cpp CommandRescan.cpp \
	CommandSdos.cpp CommandSiiRead.cpp CommandSiiWrite.cpp \
	CommandSlaves.cpp CommandSoeRead.cpp CommandSoeWrite.cpp \
	CommandStates.cpp CommandUpload.cpp CommandVersion.cpp \
	CommandXml.cpp DataTypeHandler.cpp FoeCommand.cpp \
	MasterDevice.cpp NumberListParser.cpp SdoCommand.cpp \
	SoeCommand.cpp main.cpp sii_crc.cpp CommandEoe.cpp
am__objects_1 = ethercat-CommandEoe.$(OBJEXT)
am_ethercat_OBJECTS = soe_errors.$(OBJEXT) ethercat-Command.$(OBJEXT) \
	ethercat-CommandAlias.$(OBJEXT) \
	ethercat-CommandCStruct.$(OBJEXT) \
	ethercat-CommandConfig.$(OBJEXT) \
	ethercat-CommandData.$(OBJEXT) ethercat-CommandDebug.$(OBJEXT) \
	ethercat-CommandDomains.$(OBJEXT) \
	ethercat-CommandDownload.$(OBJEXT) \
	ethercat-CommandFoeRead.$(OBJEXT) \
	ethercat-CommandFoeWrite.$(OBJEXT) \
	ethercat-CommandGraph.$(OBJEXT) \
	ethercat-CommandMaster.$(OBJEXT) \
	ethercat-CommandPdos.$(OBJEXT) \
	ethercat-CommandRegRead.$(OBJEXT) \
	ethercat-CommandRegWrite.$(OBJEXT) \
	ethercat-CommandRescan.$(OBJEXT) \
	ethercat-CommandSdos.$(OBJEXT) \
	ethercat-CommandSiiRead.$(OBJEXT) \
	ethercat-CommandSiiWrite.$(OBJEXT) \
	ethercat-CommandSlaves.$(OBJEXT) \
	ethercat-CommandSoeRead.$(OBJEXT) \
	ethercat-CommandSoeWrite.$(OBJEXT) \
	ethercat-CommandStates.$(OBJEXT) \
	ethercat-CommandUpload.$(OBJEXT) \
	ethercat-CommandVersion.$(OBJEXT) \
	ethercat-CommandXml.$(OBJEXT) \
	ethercat-DataTypeHandler.$(OBJEXT) \
	ethercat-FoeCommand.$(OBJEXT) ethercat-MasterDevice.$(OBJEXT) \
	ethercat-NumberListParser.$(OBJEXT) \
	ethercat-SdoCommand.$(OBJEXT) ethercat-SoeCommand.$(OBJEXT) \
	ethercat-main.$(OBJEXT) ethercat-sii_crc.$(OBJEXT) \
	$(am__objects_1)
ethercat_OBJECTS = $(am_ethercat_OBJECTS)
ethercat_LDADD = $(LDADD)
ethercat_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
	$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(ethercat_CXXFLAGS) \
	$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
DEFAULT_INCLUDES = -I. -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/autoconf/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
	--mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
	--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
	$(LDFLAGS) -o $@
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
	--mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
CXXLD = $(CXX)
CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
	--mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
	$(LDFLAGS) -o $@
SOURCES = $(ethercat_SOURCES)
DIST_SOURCES = $(am__ethercat_SOURCES_DIST)
am__noinst_HEADERS_DIST = Command.h CommandAlias.h CommandCStruct.h \
	CommandConfig.h CommandData.h CommandDebug.h CommandDomains.h \
	CommandDownload.h CommandFoeRead.h CommandFoeWrite.h \
	CommandGraph.h CommandMaster.h CommandPdos.h CommandRegRead.h \
	CommandRegWrite.h CommandRescan.h CommandSdos.h \
	CommandSiiRead.h CommandSiiWrite.h CommandSlaves.h \
	CommandSoeRead.h CommandSoeWrite.h CommandStates.h \
	CommandUpload.h CommandVersion.h CommandXml.h \
	DataTypeHandler.h FoeCommand.h MasterDevice.h \
	NumberListParser.h SdoCommand.h SoeCommand.h sii_crc.h \
	CommandEoe.h
HEADERS = $(noinst_HEADERS)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = ${SHELL} /home/morris/SUDA_V3S/3rdpart/ethercat-1.5.2/autoconf/missing --run aclocal-1.11
AMTAR = ${SHELL} /home/morris/SUDA_V3S/3rdpart/ethercat-1.5.2/autoconf/missing --run tar
AR = arm-linux-gnueabihf-ar
AUTOCONF = ${SHELL} /home/morris/SUDA_V3S/3rdpart/ethercat-1.5.2/autoconf/missing --run autoconf
AUTOHEADER = ${SHELL} /home/morris/SUDA_V3S/3rdpart/ethercat-1.5.2/autoconf/missing --run autoheader
AUTOMAKE = ${SHELL} /home/morris/SUDA_V3S/3rdpart/ethercat-1.5.2/autoconf/missing --run automake-1.11
AWK = gawk
CC = arm-linux-gnueabihf-gcc
CCDEPMODE = depmode=gcc3
CFLAGS = -g -O2
CPP = arm-linux-gnueabihf-gcc -E
CPPFLAGS = 
CXX = arm-linux-gnueabihf-g++
CXXCPP = arm-linux-gnueabihf-g++ -E
CXXDEPMODE = depmode=gcc3
CXXFLAGS = -g -O2
CYGPATH_W = echo
DEFS = -DHAVE_CONFIG_H
DEPDIR = .deps
DLLTOOL = false
DSYMUTIL = 
DUMPBIN = 
E1000E_LAYOUT_3_4 = 0
ECHO_C = 
ECHO_N = -n
ECHO_T = 
EGREP = /bin/grep -E
ENABLE_8139TOO = 0
ENABLE_DEBUG_IF = 0
ENABLE_E100 = 0
ENABLE_E1000 = 0
ENABLE_E1000E = 0
ENABLE_EOE = 1
ENABLE_GENERIC = 1
ENABLE_R8169 = 0
ENABLE_RTAI = 0
ENABLE_RTDM = 0
ENABLE_TTY = 0
ENABLE_XENOMAI = 0
EXEEXT = 
FGREP = /bin/grep -F
GREP = /bin/grep
INSTALL = /usr/bin/install -c
INSTALL_DATA = ${INSTALL} -m 644
INSTALL_MOD_DIR = ethercat
INSTALL_PROGRAM = ${INSTALL}
INSTALL_SCRIPT = ${INSTALL}
INSTALL_STRIP_PROGRAM = $(install_sh) -c -s
KERNEL_8139TOO = 4.13
KERNEL_E100 = 4.13
KERNEL_E1000 = 4.13
KERNEL_E1000E = 4.13
KERNEL_R8169 = 4.13
LD = arm-linux-gnueabihf-ld
LDFLAGS = 
LIBOBJS = 
LIBS = 
LIBTOOL = $(SHELL) $(top_builddir)/libtool
LINUX_SOURCE_DIR = /home/morris/SUDA_V3S/kernel/linux-zero-4.13.y/
LIPO = 
LN_S = ln -s
LTLIBOBJS = 
MAKEINFO = ${SHELL} /home/morris/SUDA_V3S/3rdpart/ethercat-1.5.2/autoconf/missing --run makeinfo
MANIFEST_TOOL = :
MKDIR_P = /bin/mkdir -p
NM = arm-linux-gnueabihf-nm
NMEDIT = 
OBJDUMP = arm-linux-gnueabihf-objdump
OBJEXT = o
OTOOL = 
OTOOL64 = 
PACKAGE = ethercat
PACKAGE_BUGREPORT = <EMAIL>
PACKAGE_NAME = ethercat
PACKAGE_STRING = ethercat 1.5.2
PACKAGE_TARNAME = ethercat
PACKAGE_URL = 
PACKAGE_VERSION = 1.5.2
PATH_SEPARATOR = :
RANLIB = arm-linux-gnueabihf-ranlib
RTAI_DIR = 
RTAI_LXRT_CFLAGS = 
RTAI_LXRT_LDFLAGS = 
SED = /bin/sed
SET_MAKE = 
SHELL = /bin/bash
STRIP = arm-linux-gnueabihf-strip
VERSION = 1.5.2
XENOMAI_DIR = 
XENOMAI_NATIVE_CFLAGS = 
XENOMAI_NATIVE_LDFLAGS = 
XENOMAI_POSIX_CFLAGS = 
XENOMAI_POSIX_LDFLAGS = 
XENOMAI_RTDM_CFLAGS = 
XENOMAI_RTDM_LDFLAGS = 
abs_builddir = /home/morris/SUDA_V3S/3rdpart/ethercat-1.5.2/tool
abs_srcdir = /home/morris/SUDA_V3S/3rdpart/ethercat-1.5.2/tool
abs_top_builddir = /home/morris/SUDA_V3S/3rdpart/ethercat-1.5.2
abs_top_srcdir = /home/morris/SUDA_V3S/3rdpart/ethercat-1.5.2
ac_ct_AR = 
ac_ct_CC = 
ac_ct_CXX = 
ac_ct_DUMPBIN = 
am__include = include
am__leading_dot = .
am__quote = 
am__tar = ${AMTAR} chof - "$$tardir"
am__untar = ${AMTAR} xf -
bindir = ${exec_prefix}/bin
build = x86_64-unknown-linux-gnu
build_alias = 
build_cpu = x86_64
build_os = linux-gnu
build_vendor = unknown
builddir = .
datadir = ${datarootdir}
datarootdir = ${prefix}/share
docdir = ${datarootdir}/doc/${PACKAGE_TARNAME}
dvidir = ${docdir}
exec_prefix = ${prefix}
host = arm-unknown-linux-gnueabihf
host_alias = arm-linux-gnueabihf
host_cpu = arm
host_os = linux-gnueabihf
host_vendor = unknown
htmldir = ${docdir}
includedir = ${prefix}/include
infodir = ${datarootdir}/info
install_sh = ${SHELL} /home/morris/SUDA_V3S/3rdpart/ethercat-1.5.2/autoconf/install-sh
libdir = ${exec_prefix}/lib
libexecdir = ${exec_prefix}/libexec
localedir = ${datarootdir}/locale
localstatedir = ${prefix}/var
mandir = ${datarootdir}/man
mkdir_p = /bin/mkdir -p
oldincludedir = /usr/include
pdfdir = ${docdir}
prefix = /home/morris/SUDA_V3S/rootfs/multistrap/rootfs/opt/ethercat
program_transform_name = s,x,x,
psdir = ${docdir}
sbindir = ${exec_prefix}/sbin
sharedstatedir = ${prefix}/com
srcdir = .
sysconfdir = ${prefix}/etc
target_alias = 
top_build_prefix = ../
top_builddir = ..
top_srcdir = ..
EXTRA_DIST = $(am__append_2)
ethercat_SOURCES = ../master/soe_errors.c Command.cpp CommandAlias.cpp \
	CommandCStruct.cpp CommandConfig.cpp CommandData.cpp \
	CommandDebug.cpp CommandDomains.cpp CommandDownload.cpp \
	CommandFoeRead.cpp CommandFoeWrite.cpp CommandGraph.cpp \
	CommandMaster.cpp CommandPdos.cpp CommandRegRead.cpp \
	CommandRegWrite.cpp CommandRescan.cpp CommandSdos.cpp \
	CommandSiiRead.cpp CommandSiiWrite.cpp CommandSlaves.cpp \
	CommandSoeRead.cpp CommandSoeWrite.cpp CommandStates.cpp \
	CommandUpload.cpp CommandVersion.cpp CommandXml.cpp \
	DataTypeHandler.cpp FoeCommand.cpp MasterDevice.cpp \
	NumberListParser.cpp SdoCommand.cpp SoeCommand.cpp main.cpp \
	sii_crc.cpp $(am__append_1)
noinst_HEADERS = Command.h CommandAlias.h CommandCStruct.h \
	CommandConfig.h CommandData.h CommandDebug.h CommandDomains.h \
	CommandDownload.h CommandFoeRead.h CommandFoeWrite.h \
	CommandGraph.h CommandMaster.h CommandPdos.h CommandRegRead.h \
	CommandRegWrite.h CommandRescan.h CommandSdos.h \
	CommandSiiRead.h CommandSiiWrite.h CommandSlaves.h \
	CommandSoeRead.h CommandSoeWrite.h CommandStates.h \
	CommandUpload.h CommandVersion.h CommandXml.h \
	DataTypeHandler.h FoeCommand.h MasterDevice.h \
	NumberListParser.h SdoCommand.h SoeCommand.h sii_crc.h \
	$(am__append_3)
REV = `if test -s $(top_srcdir)/revision; then \
		cat $(top_srcdir)/revision; \
	else \
		hg id -i $(top_srcdir) 2>/dev/null || echo "unknown"; \
	fi`

ethercat_CXXFLAGS = \
	-I$(top_srcdir)/include \
	-I$(top_srcdir)/master \
	-Wall -DREV=$(REV) \
	-fno-strict-aliasing

all: all-am

.SUFFIXES:
.SUFFIXES: .c .cpp .lo .o .obj
$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
	@for dep in $?; do \
	  case '$(am__configure_deps)' in \
	    *$$dep*) \
	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
	        && { if test -f $@; then exit 0; else break; fi; }; \
	      exit 1;; \
	  esac; \
	done; \
	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tool/Makefile'; \
	$(am__cd) $(top_srcdir) && \
	  $(AUTOMAKE) --gnu tool/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
	@case '$?' in \
	  *config.status*) \
	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
	  *) \
	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
	esac;

$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh

$(top_srcdir)/configure:  $(am__configure_deps)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
install-binPROGRAMS: $(bin_PROGRAMS)
	@$(NORMAL_INSTALL)
	test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
	@list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
	for p in $$list; do echo "$$p $$p"; done | \
	sed 's/$(EXEEXT)$$//' | \
	while read p p1; do if test -f $$p || test -f $$p1; \
	  then echo "$$p"; echo "$$p"; else :; fi; \
	done | \
	sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \
	    -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
	sed 'N;N;N;s,\n, ,g' | \
	$(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
	  { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
	    if ($$2 == $$4) files[d] = files[d] " " $$1; \
	    else { print "f", $$3 "/" $$4, $$1; } } \
	  END { for (d in files) print "f", d, files[d] }' | \
	while read type dir files; do \
	    if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
	    test -z "$$files" || { \
	    echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \
	    $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
	    } \
	; done

uninstall-binPROGRAMS:
	@$(NORMAL_UNINSTALL)
	@list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
	files=`for p in $$list; do echo "$$p"; done | \
	  sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
	      -e 's/$$/$(EXEEXT)/' `; \
	test -n "$$list" || exit 0; \
	echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
	cd "$(DESTDIR)$(bindir)" && rm -f $$files

clean-binPROGRAMS:
	@list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \
	echo " rm -f" $$list; \
	rm -f $$list || exit $$?; \
	test -n "$(EXEEXT)" || exit 0; \
	list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
	echo " rm -f" $$list; \
	rm -f $$list
ethercat$(EXEEXT): $(ethercat_OBJECTS) $(ethercat_DEPENDENCIES) 
	@rm -f ethercat$(EXEEXT)
	$(ethercat_LINK) $(ethercat_OBJECTS) $(ethercat_LDADD) $(LIBS)

mostlyclean-compile:
	-rm -f *.$(OBJEXT)

distclean-compile:
	-rm -f *.tab.c

include ./$(DEPDIR)/ethercat-Command.Po
include ./$(DEPDIR)/ethercat-CommandAlias.Po
include ./$(DEPDIR)/ethercat-CommandCStruct.Po
include ./$(DEPDIR)/ethercat-CommandConfig.Po
include ./$(DEPDIR)/ethercat-CommandData.Po
include ./$(DEPDIR)/ethercat-CommandDebug.Po
include ./$(DEPDIR)/ethercat-CommandDomains.Po
include ./$(DEPDIR)/ethercat-CommandDownload.Po
include ./$(DEPDIR)/ethercat-CommandEoe.Po
include ./$(DEPDIR)/ethercat-CommandFoeRead.Po
include ./$(DEPDIR)/ethercat-CommandFoeWrite.Po
include ./$(DEPDIR)/ethercat-CommandGraph.Po
include ./$(DEPDIR)/ethercat-CommandMaster.Po
include ./$(DEPDIR)/ethercat-CommandPdos.Po
include ./$(DEPDIR)/ethercat-CommandRegRead.Po
include ./$(DEPDIR)/ethercat-CommandRegWrite.Po
include ./$(DEPDIR)/ethercat-CommandRescan.Po
include ./$(DEPDIR)/ethercat-CommandSdos.Po
include ./$(DEPDIR)/ethercat-CommandSiiRead.Po
include ./$(DEPDIR)/ethercat-CommandSiiWrite.Po
include ./$(DEPDIR)/ethercat-CommandSlaves.Po
include ./$(DEPDIR)/ethercat-CommandSoeRead.Po
include ./$(DEPDIR)/ethercat-CommandSoeWrite.Po
include ./$(DEPDIR)/ethercat-CommandStates.Po
include ./$(DEPDIR)/ethercat-CommandUpload.Po
include ./$(DEPDIR)/ethercat-CommandVersion.Po
include ./$(DEPDIR)/ethercat-CommandXml.Po
include ./$(DEPDIR)/ethercat-DataTypeHandler.Po
include ./$(DEPDIR)/ethercat-FoeCommand.Po
include ./$(DEPDIR)/ethercat-MasterDevice.Po
include ./$(DEPDIR)/ethercat-NumberListParser.Po
include ./$(DEPDIR)/ethercat-SdoCommand.Po
include ./$(DEPDIR)/ethercat-SoeCommand.Po
include ./$(DEPDIR)/ethercat-main.Po
include ./$(DEPDIR)/ethercat-sii_crc.Po
include ./$(DEPDIR)/soe_errors.Po

.c.o:
	$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
	$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
#	source='$<' object='$@' libtool=no \
#	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
#	$(COMPILE) -c $<

.c.obj:
	$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
	$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
#	source='$<' object='$@' libtool=no \
#	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
#	$(COMPILE) -c `$(CYGPATH_W) '$<'`

.c.lo:
	$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
	$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
#	source='$<' object='$@' libtool=yes \
#	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
#	$(LTCOMPILE) -c -o $@ $<

soe_errors.o: ../master/soe_errors.c
	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT soe_errors.o -MD -MP -MF $(DEPDIR)/soe_errors.Tpo -c -o soe_errors.o `test -f '../master/soe_errors.c' || echo '$(srcdir)/'`../master/soe_errors.c
	$(am__mv) $(DEPDIR)/soe_errors.Tpo $(DEPDIR)/soe_errors.Po
#	source='../master/soe_errors.c' object='soe_errors.o' libtool=no \
#	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
#	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o soe_errors.o `test -f '../master/soe_errors.c' || echo '$(srcdir)/'`../master/soe_errors.c

soe_errors.obj: ../master/soe_errors.c
	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT soe_errors.obj -MD -MP -MF $(DEPDIR)/soe_errors.Tpo -c -o soe_errors.obj `if test -f '../master/soe_errors.c'; then $(CYGPATH_W) '../master/soe_errors.c'; else $(CYGPATH_W) '$(srcdir)/../master/soe_errors.c'; fi`
	$(am__mv) $(DEPDIR)/soe_errors.Tpo $(DEPDIR)/soe_errors.Po
#	source='../master/soe_errors.c' object='soe_errors.obj' libtool=no \
#	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
#	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o soe_errors.obj `if test -f '../master/soe_errors.c'; then $(CYGPATH_W) '../master/soe_errors.c'; else $(CYGPATH_W) '$(srcdir)/../master/soe_errors.c'; fi`

.cpp.o:
	$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
	$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
#	source='$<' object='$@' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXXCOMPILE) -c -o $@ $<

.cpp.obj:
	$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
	$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
#	source='$<' object='$@' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`

.cpp.lo:
	$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
	$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
#	source='$<' object='$@' libtool=yes \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(LTCXXCOMPILE) -c -o $@ $<

ethercat-Command.o: Command.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-Command.o -MD -MP -MF $(DEPDIR)/ethercat-Command.Tpo -c -o ethercat-Command.o `test -f 'Command.cpp' || echo '$(srcdir)/'`Command.cpp
	$(am__mv) $(DEPDIR)/ethercat-Command.Tpo $(DEPDIR)/ethercat-Command.Po
#	source='Command.cpp' object='ethercat-Command.o' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-Command.o `test -f 'Command.cpp' || echo '$(srcdir)/'`Command.cpp

ethercat-Command.obj: Command.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-Command.obj -MD -MP -MF $(DEPDIR)/ethercat-Command.Tpo -c -o ethercat-Command.obj `if test -f 'Command.cpp'; then $(CYGPATH_W) 'Command.cpp'; else $(CYGPATH_W) '$(srcdir)/Command.cpp'; fi`
	$(am__mv) $(DEPDIR)/ethercat-Command.Tpo $(DEPDIR)/ethercat-Command.Po
#	source='Command.cpp' object='ethercat-Command.obj' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-Command.obj `if test -f 'Command.cpp'; then $(CYGPATH_W) 'Command.cpp'; else $(CYGPATH_W) '$(srcdir)/Command.cpp'; fi`

ethercat-CommandAlias.o: CommandAlias.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-CommandAlias.o -MD -MP -MF $(DEPDIR)/ethercat-CommandAlias.Tpo -c -o ethercat-CommandAlias.o `test -f 'CommandAlias.cpp' || echo '$(srcdir)/'`CommandAlias.cpp
	$(am__mv) $(DEPDIR)/ethercat-CommandAlias.Tpo $(DEPDIR)/ethercat-CommandAlias.Po
#	source='CommandAlias.cpp' object='ethercat-CommandAlias.o' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-CommandAlias.o `test -f 'CommandAlias.cpp' || echo '$(srcdir)/'`CommandAlias.cpp

ethercat-CommandAlias.obj: CommandAlias.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-CommandAlias.obj -MD -MP -MF $(DEPDIR)/ethercat-CommandAlias.Tpo -c -o ethercat-CommandAlias.obj `if test -f 'CommandAlias.cpp'; then $(CYGPATH_W) 'CommandAlias.cpp'; else $(CYGPATH_W) '$(srcdir)/CommandAlias.cpp'; fi`
	$(am__mv) $(DEPDIR)/ethercat-CommandAlias.Tpo $(DEPDIR)/ethercat-CommandAlias.Po
#	source='CommandAlias.cpp' object='ethercat-CommandAlias.obj' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-CommandAlias.obj `if test -f 'CommandAlias.cpp'; then $(CYGPATH_W) 'CommandAlias.cpp'; else $(CYGPATH_W) '$(srcdir)/CommandAlias.cpp'; fi`

ethercat-CommandCStruct.o: CommandCStruct.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-CommandCStruct.o -MD -MP -MF $(DEPDIR)/ethercat-CommandCStruct.Tpo -c -o ethercat-CommandCStruct.o `test -f 'CommandCStruct.cpp' || echo '$(srcdir)/'`CommandCStruct.cpp
	$(am__mv) $(DEPDIR)/ethercat-CommandCStruct.Tpo $(DEPDIR)/ethercat-CommandCStruct.Po
#	source='CommandCStruct.cpp' object='ethercat-CommandCStruct.o' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-CommandCStruct.o `test -f 'CommandCStruct.cpp' || echo '$(srcdir)/'`CommandCStruct.cpp

ethercat-CommandCStruct.obj: CommandCStruct.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-CommandCStruct.obj -MD -MP -MF $(DEPDIR)/ethercat-CommandCStruct.Tpo -c -o ethercat-CommandCStruct.obj `if test -f 'CommandCStruct.cpp'; then $(CYGPATH_W) 'CommandCStruct.cpp'; else $(CYGPATH_W) '$(srcdir)/CommandCStruct.cpp'; fi`
	$(am__mv) $(DEPDIR)/ethercat-CommandCStruct.Tpo $(DEPDIR)/ethercat-CommandCStruct.Po
#	source='CommandCStruct.cpp' object='ethercat-CommandCStruct.obj' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-CommandCStruct.obj `if test -f 'CommandCStruct.cpp'; then $(CYGPATH_W) 'CommandCStruct.cpp'; else $(CYGPATH_W) '$(srcdir)/CommandCStruct.cpp'; fi`

ethercat-CommandConfig.o: CommandConfig.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-CommandConfig.o -MD -MP -MF $(DEPDIR)/ethercat-CommandConfig.Tpo -c -o ethercat-CommandConfig.o `test -f 'CommandConfig.cpp' || echo '$(srcdir)/'`CommandConfig.cpp
	$(am__mv) $(DEPDIR)/ethercat-CommandConfig.Tpo $(DEPDIR)/ethercat-CommandConfig.Po
#	source='CommandConfig.cpp' object='ethercat-CommandConfig.o' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-CommandConfig.o `test -f 'CommandConfig.cpp' || echo '$(srcdir)/'`CommandConfig.cpp

ethercat-CommandConfig.obj: CommandConfig.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-CommandConfig.obj -MD -MP -MF $(DEPDIR)/ethercat-CommandConfig.Tpo -c -o ethercat-CommandConfig.obj `if test -f 'CommandConfig.cpp'; then $(CYGPATH_W) 'CommandConfig.cpp'; else $(CYGPATH_W) '$(srcdir)/CommandConfig.cpp'; fi`
	$(am__mv) $(DEPDIR)/ethercat-CommandConfig.Tpo $(DEPDIR)/ethercat-CommandConfig.Po
#	source='CommandConfig.cpp' object='ethercat-CommandConfig.obj' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-CommandConfig.obj `if test -f 'CommandConfig.cpp'; then $(CYGPATH_W) 'CommandConfig.cpp'; else $(CYGPATH_W) '$(srcdir)/CommandConfig.cpp'; fi`

ethercat-CommandData.o: CommandData.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-CommandData.o -MD -MP -MF $(DEPDIR)/ethercat-CommandData.Tpo -c -o ethercat-CommandData.o `test -f 'CommandData.cpp' || echo '$(srcdir)/'`CommandData.cpp
	$(am__mv) $(DEPDIR)/ethercat-CommandData.Tpo $(DEPDIR)/ethercat-CommandData.Po
#	source='CommandData.cpp' object='ethercat-CommandData.o' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-CommandData.o `test -f 'CommandData.cpp' || echo '$(srcdir)/'`CommandData.cpp

ethercat-CommandData.obj: CommandData.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-CommandData.obj -MD -MP -MF $(DEPDIR)/ethercat-CommandData.Tpo -c -o ethercat-CommandData.obj `if test -f 'CommandData.cpp'; then $(CYGPATH_W) 'CommandData.cpp'; else $(CYGPATH_W) '$(srcdir)/CommandData.cpp'; fi`
	$(am__mv) $(DEPDIR)/ethercat-CommandData.Tpo $(DEPDIR)/ethercat-CommandData.Po
#	source='CommandData.cpp' object='ethercat-CommandData.obj' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-CommandData.obj `if test -f 'CommandData.cpp'; then $(CYGPATH_W) 'CommandData.cpp'; else $(CYGPATH_W) '$(srcdir)/CommandData.cpp'; fi`

ethercat-CommandDebug.o: CommandDebug.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-CommandDebug.o -MD -MP -MF $(DEPDIR)/ethercat-CommandDebug.Tpo -c -o ethercat-CommandDebug.o `test -f 'CommandDebug.cpp' || echo '$(srcdir)/'`CommandDebug.cpp
	$(am__mv) $(DEPDIR)/ethercat-CommandDebug.Tpo $(DEPDIR)/ethercat-CommandDebug.Po
#	source='CommandDebug.cpp' object='ethercat-CommandDebug.o' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-CommandDebug.o `test -f 'CommandDebug.cpp' || echo '$(srcdir)/'`CommandDebug.cpp

ethercat-CommandDebug.obj: CommandDebug.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-CommandDebug.obj -MD -MP -MF $(DEPDIR)/ethercat-CommandDebug.Tpo -c -o ethercat-CommandDebug.obj `if test -f 'CommandDebug.cpp'; then $(CYGPATH_W) 'CommandDebug.cpp'; else $(CYGPATH_W) '$(srcdir)/CommandDebug.cpp'; fi`
	$(am__mv) $(DEPDIR)/ethercat-CommandDebug.Tpo $(DEPDIR)/ethercat-CommandDebug.Po
#	source='CommandDebug.cpp' object='ethercat-CommandDebug.obj' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-CommandDebug.obj `if test -f 'CommandDebug.cpp'; then $(CYGPATH_W) 'CommandDebug.cpp'; else $(CYGPATH_W) '$(srcdir)/CommandDebug.cpp'; fi`

ethercat-CommandDomains.o: CommandDomains.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-CommandDomains.o -MD -MP -MF $(DEPDIR)/ethercat-CommandDomains.Tpo -c -o ethercat-CommandDomains.o `test -f 'CommandDomains.cpp' || echo '$(srcdir)/'`CommandDomains.cpp
	$(am__mv) $(DEPDIR)/ethercat-CommandDomains.Tpo $(DEPDIR)/ethercat-CommandDomains.Po
#	source='CommandDomains.cpp' object='ethercat-CommandDomains.o' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-CommandDomains.o `test -f 'CommandDomains.cpp' || echo '$(srcdir)/'`CommandDomains.cpp

ethercat-CommandDomains.obj: CommandDomains.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-CommandDomains.obj -MD -MP -MF $(DEPDIR)/ethercat-CommandDomains.Tpo -c -o ethercat-CommandDomains.obj `if test -f 'CommandDomains.cpp'; then $(CYGPATH_W) 'CommandDomains.cpp'; else $(CYGPATH_W) '$(srcdir)/CommandDomains.cpp'; fi`
	$(am__mv) $(DEPDIR)/ethercat-CommandDomains.Tpo $(DEPDIR)/ethercat-CommandDomains.Po
#	source='CommandDomains.cpp' object='ethercat-CommandDomains.obj' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-CommandDomains.obj `if test -f 'CommandDomains.cpp'; then $(CYGPATH_W) 'CommandDomains.cpp'; else $(CYGPATH_W) '$(srcdir)/CommandDomains.cpp'; fi`

ethercat-CommandDownload.o: CommandDownload.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-CommandDownload.o -MD -MP -MF $(DEPDIR)/ethercat-CommandDownload.Tpo -c -o ethercat-CommandDownload.o `test -f 'CommandDownload.cpp' || echo '$(srcdir)/'`CommandDownload.cpp
	$(am__mv) $(DEPDIR)/ethercat-CommandDownload.Tpo $(DEPDIR)/ethercat-CommandDownload.Po
#	source='CommandDownload.cpp' object='ethercat-CommandDownload.o' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-CommandDownload.o `test -f 'CommandDownload.cpp' || echo '$(srcdir)/'`CommandDownload.cpp

ethercat-CommandDownload.obj: CommandDownload.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-CommandDownload.obj -MD -MP -MF $(DEPDIR)/ethercat-CommandDownload.Tpo -c -o ethercat-CommandDownload.obj `if test -f 'CommandDownload.cpp'; then $(CYGPATH_W) 'CommandDownload.cpp'; else $(CYGPATH_W) '$(srcdir)/CommandDownload.cpp'; fi`
	$(am__mv) $(DEPDIR)/ethercat-CommandDownload.Tpo $(DEPDIR)/ethercat-CommandDownload.Po
#	source='CommandDownload.cpp' object='ethercat-CommandDownload.obj' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-CommandDownload.obj `if test -f 'CommandDownload.cpp'; then $(CYGPATH_W) 'CommandDownload.cpp'; else $(CYGPATH_W) '$(srcdir)/CommandDownload.cpp'; fi`

ethercat-CommandFoeRead.o: CommandFoeRead.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-CommandFoeRead.o -MD -MP -MF $(DEPDIR)/ethercat-CommandFoeRead.Tpo -c -o ethercat-CommandFoeRead.o `test -f 'CommandFoeRead.cpp' || echo '$(srcdir)/'`CommandFoeRead.cpp
	$(am__mv) $(DEPDIR)/ethercat-CommandFoeRead.Tpo $(DEPDIR)/ethercat-CommandFoeRead.Po
#	source='CommandFoeRead.cpp' object='ethercat-CommandFoeRead.o' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-CommandFoeRead.o `test -f 'CommandFoeRead.cpp' || echo '$(srcdir)/'`CommandFoeRead.cpp

ethercat-CommandFoeRead.obj: CommandFoeRead.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-CommandFoeRead.obj -MD -MP -MF $(DEPDIR)/ethercat-CommandFoeRead.Tpo -c -o ethercat-CommandFoeRead.obj `if test -f 'CommandFoeRead.cpp'; then $(CYGPATH_W) 'CommandFoeRead.cpp'; else $(CYGPATH_W) '$(srcdir)/CommandFoeRead.cpp'; fi`
	$(am__mv) $(DEPDIR)/ethercat-CommandFoeRead.Tpo $(DEPDIR)/ethercat-CommandFoeRead.Po
#	source='CommandFoeRead.cpp' object='ethercat-CommandFoeRead.obj' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-CommandFoeRead.obj `if test -f 'CommandFoeRead.cpp'; then $(CYGPATH_W) 'CommandFoeRead.cpp'; else $(CYGPATH_W) '$(srcdir)/CommandFoeRead.cpp'; fi`

ethercat-CommandFoeWrite.o: CommandFoeWrite.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-CommandFoeWrite.o -MD -MP -MF $(DEPDIR)/ethercat-CommandFoeWrite.Tpo -c -o ethercat-CommandFoeWrite.o `test -f 'CommandFoeWrite.cpp' || echo '$(srcdir)/'`CommandFoeWrite.cpp
	$(am__mv) $(DEPDIR)/ethercat-CommandFoeWrite.Tpo $(DEPDIR)/ethercat-CommandFoeWrite.Po
#	source='CommandFoeWrite.cpp' object='ethercat-CommandFoeWrite.o' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-CommandFoeWrite.o `test -f 'CommandFoeWrite.cpp' || echo '$(srcdir)/'`CommandFoeWrite.cpp

ethercat-CommandFoeWrite.obj: CommandFoeWrite.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-CommandFoeWrite.obj -MD -MP -MF $(DEPDIR)/ethercat-CommandFoeWrite.Tpo -c -o ethercat-CommandFoeWrite.obj `if test -f 'CommandFoeWrite.cpp'; then $(CYGPATH_W) 'CommandFoeWrite.cpp'; else $(CYGPATH_W) '$(srcdir)/CommandFoeWrite.cpp'; fi`
	$(am__mv) $(DEPDIR)/ethercat-CommandFoeWrite.Tpo $(DEPDIR)/ethercat-CommandFoeWrite.Po
#	source='CommandFoeWrite.cpp' object='ethercat-CommandFoeWrite.obj' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-CommandFoeWrite.obj `if test -f 'CommandFoeWrite.cpp'; then $(CYGPATH_W) 'CommandFoeWrite.cpp'; else $(CYGPATH_W) '$(srcdir)/CommandFoeWrite.cpp'; fi`

ethercat-CommandGraph.o: CommandGraph.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-CommandGraph.o -MD -MP -MF $(DEPDIR)/ethercat-CommandGraph.Tpo -c -o ethercat-CommandGraph.o `test -f 'CommandGraph.cpp' || echo '$(srcdir)/'`CommandGraph.cpp
	$(am__mv) $(DEPDIR)/ethercat-CommandGraph.Tpo $(DEPDIR)/ethercat-CommandGraph.Po
#	source='CommandGraph.cpp' object='ethercat-CommandGraph.o' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-CommandGraph.o `test -f 'CommandGraph.cpp' || echo '$(srcdir)/'`CommandGraph.cpp

ethercat-CommandGraph.obj: CommandGraph.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-CommandGraph.obj -MD -MP -MF $(DEPDIR)/ethercat-CommandGraph.Tpo -c -o ethercat-CommandGraph.obj `if test -f 'CommandGraph.cpp'; then $(CYGPATH_W) 'CommandGraph.cpp'; else $(CYGPATH_W) '$(srcdir)/CommandGraph.cpp'; fi`
	$(am__mv) $(DEPDIR)/ethercat-CommandGraph.Tpo $(DEPDIR)/ethercat-CommandGraph.Po
#	source='CommandGraph.cpp' object='ethercat-CommandGraph.obj' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-CommandGraph.obj `if test -f 'CommandGraph.cpp'; then $(CYGPATH_W) 'CommandGraph.cpp'; else $(CYGPATH_W) '$(srcdir)/CommandGraph.cpp'; fi`

ethercat-CommandMaster.o: CommandMaster.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-CommandMaster.o -MD -MP -MF $(DEPDIR)/ethercat-CommandMaster.Tpo -c -o ethercat-CommandMaster.o `test -f 'CommandMaster.cpp' || echo '$(srcdir)/'`CommandMaster.cpp
	$(am__mv) $(DEPDIR)/ethercat-CommandMaster.Tpo $(DEPDIR)/ethercat-CommandMaster.Po
#	source='CommandMaster.cpp' object='ethercat-CommandMaster.o' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-CommandMaster.o `test -f 'CommandMaster.cpp' || echo '$(srcdir)/'`CommandMaster.cpp

ethercat-CommandMaster.obj: CommandMaster.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-CommandMaster.obj -MD -MP -MF $(DEPDIR)/ethercat-CommandMaster.Tpo -c -o ethercat-CommandMaster.obj `if test -f 'CommandMaster.cpp'; then $(CYGPATH_W) 'CommandMaster.cpp'; else $(CYGPATH_W) '$(srcdir)/CommandMaster.cpp'; fi`
	$(am__mv) $(DEPDIR)/ethercat-CommandMaster.Tpo $(DEPDIR)/ethercat-CommandMaster.Po
#	source='CommandMaster.cpp' object='ethercat-CommandMaster.obj' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-CommandMaster.obj `if test -f 'CommandMaster.cpp'; then $(CYGPATH_W) 'CommandMaster.cpp'; else $(CYGPATH_W) '$(srcdir)/CommandMaster.cpp'; fi`

ethercat-CommandPdos.o: CommandPdos.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-CommandPdos.o -MD -MP -MF $(DEPDIR)/ethercat-CommandPdos.Tpo -c -o ethercat-CommandPdos.o `test -f 'CommandPdos.cpp' || echo '$(srcdir)/'`CommandPdos.cpp
	$(am__mv) $(DEPDIR)/ethercat-CommandPdos.Tpo $(DEPDIR)/ethercat-CommandPdos.Po
#	source='CommandPdos.cpp' object='ethercat-CommandPdos.o' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-CommandPdos.o `test -f 'CommandPdos.cpp' || echo '$(srcdir)/'`CommandPdos.cpp

ethercat-CommandPdos.obj: CommandPdos.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-CommandPdos.obj -MD -MP -MF $(DEPDIR)/ethercat-CommandPdos.Tpo -c -o ethercat-CommandPdos.obj `if test -f 'CommandPdos.cpp'; then $(CYGPATH_W) 'CommandPdos.cpp'; else $(CYGPATH_W) '$(srcdir)/CommandPdos.cpp'; fi`
	$(am__mv) $(DEPDIR)/ethercat-CommandPdos.Tpo $(DEPDIR)/ethercat-CommandPdos.Po
#	source='CommandPdos.cpp' object='ethercat-CommandPdos.obj' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-CommandPdos.obj `if test -f 'CommandPdos.cpp'; then $(CYGPATH_W) 'CommandPdos.cpp'; else $(CYGPATH_W) '$(srcdir)/CommandPdos.cpp'; fi`

ethercat-CommandRegRead.o: CommandRegRead.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-CommandRegRead.o -MD -MP -MF $(DEPDIR)/ethercat-CommandRegRead.Tpo -c -o ethercat-CommandRegRead.o `test -f 'CommandRegRead.cpp' || echo '$(srcdir)/'`CommandRegRead.cpp
	$(am__mv) $(DEPDIR)/ethercat-CommandRegRead.Tpo $(DEPDIR)/ethercat-CommandRegRead.Po
#	source='CommandRegRead.cpp' object='ethercat-CommandRegRead.o' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-CommandRegRead.o `test -f 'CommandRegRead.cpp' || echo '$(srcdir)/'`CommandRegRead.cpp

ethercat-CommandRegRead.obj: CommandRegRead.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-CommandRegRead.obj -MD -MP -MF $(DEPDIR)/ethercat-CommandRegRead.Tpo -c -o ethercat-CommandRegRead.obj `if test -f 'CommandRegRead.cpp'; then $(CYGPATH_W) 'CommandRegRead.cpp'; else $(CYGPATH_W) '$(srcdir)/CommandRegRead.cpp'; fi`
	$(am__mv) $(DEPDIR)/ethercat-CommandRegRead.Tpo $(DEPDIR)/ethercat-CommandRegRead.Po
#	source='CommandRegRead.cpp' object='ethercat-CommandRegRead.obj' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-CommandRegRead.obj `if test -f 'CommandRegRead.cpp'; then $(CYGPATH_W) 'CommandRegRead.cpp'; else $(CYGPATH_W) '$(srcdir)/CommandRegRead.cpp'; fi`

ethercat-CommandRegWrite.o: CommandRegWrite.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-CommandRegWrite.o -MD -MP -MF $(DEPDIR)/ethercat-CommandRegWrite.Tpo -c -o ethercat-CommandRegWrite.o `test -f 'CommandRegWrite.cpp' || echo '$(srcdir)/'`CommandRegWrite.cpp
	$(am__mv) $(DEPDIR)/ethercat-CommandRegWrite.Tpo $(DEPDIR)/ethercat-CommandRegWrite.Po
#	source='CommandRegWrite.cpp' object='ethercat-CommandRegWrite.o' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-CommandRegWrite.o `test -f 'CommandRegWrite.cpp' || echo '$(srcdir)/'`CommandRegWrite.cpp

ethercat-CommandRegWrite.obj: CommandRegWrite.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-CommandRegWrite.obj -MD -MP -MF $(DEPDIR)/ethercat-CommandRegWrite.Tpo -c -o ethercat-CommandRegWrite.obj `if test -f 'CommandRegWrite.cpp'; then $(CYGPATH_W) 'CommandRegWrite.cpp'; else $(CYGPATH_W) '$(srcdir)/CommandRegWrite.cpp'; fi`
	$(am__mv) $(DEPDIR)/ethercat-CommandRegWrite.Tpo $(DEPDIR)/ethercat-CommandRegWrite.Po
#	source='CommandRegWrite.cpp' object='ethercat-CommandRegWrite.obj' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-CommandRegWrite.obj `if test -f 'CommandRegWrite.cpp'; then $(CYGPATH_W) 'CommandRegWrite.cpp'; else $(CYGPATH_W) '$(srcdir)/CommandRegWrite.cpp'; fi`

ethercat-CommandRescan.o: CommandRescan.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-CommandRescan.o -MD -MP -MF $(DEPDIR)/ethercat-CommandRescan.Tpo -c -o ethercat-CommandRescan.o `test -f 'CommandRescan.cpp' || echo '$(srcdir)/'`CommandRescan.cpp
	$(am__mv) $(DEPDIR)/ethercat-CommandRescan.Tpo $(DEPDIR)/ethercat-CommandRescan.Po
#	source='CommandRescan.cpp' object='ethercat-CommandRescan.o' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-CommandRescan.o `test -f 'CommandRescan.cpp' || echo '$(srcdir)/'`CommandRescan.cpp

ethercat-CommandRescan.obj: CommandRescan.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-CommandRescan.obj -MD -MP -MF $(DEPDIR)/ethercat-CommandRescan.Tpo -c -o ethercat-CommandRescan.obj `if test -f 'CommandRescan.cpp'; then $(CYGPATH_W) 'CommandRescan.cpp'; else $(CYGPATH_W) '$(srcdir)/CommandRescan.cpp'; fi`
	$(am__mv) $(DEPDIR)/ethercat-CommandRescan.Tpo $(DEPDIR)/ethercat-CommandRescan.Po
#	source='CommandRescan.cpp' object='ethercat-CommandRescan.obj' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-CommandRescan.obj `if test -f 'CommandRescan.cpp'; then $(CYGPATH_W) 'CommandRescan.cpp'; else $(CYGPATH_W) '$(srcdir)/CommandRescan.cpp'; fi`

ethercat-CommandSdos.o: CommandSdos.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-CommandSdos.o -MD -MP -MF $(DEPDIR)/ethercat-CommandSdos.Tpo -c -o ethercat-CommandSdos.o `test -f 'CommandSdos.cpp' || echo '$(srcdir)/'`CommandSdos.cpp
	$(am__mv) $(DEPDIR)/ethercat-CommandSdos.Tpo $(DEPDIR)/ethercat-CommandSdos.Po
#	source='CommandSdos.cpp' object='ethercat-CommandSdos.o' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-CommandSdos.o `test -f 'CommandSdos.cpp' || echo '$(srcdir)/'`CommandSdos.cpp

ethercat-CommandSdos.obj: CommandSdos.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-CommandSdos.obj -MD -MP -MF $(DEPDIR)/ethercat-CommandSdos.Tpo -c -o ethercat-CommandSdos.obj `if test -f 'CommandSdos.cpp'; then $(CYGPATH_W) 'CommandSdos.cpp'; else $(CYGPATH_W) '$(srcdir)/CommandSdos.cpp'; fi`
	$(am__mv) $(DEPDIR)/ethercat-CommandSdos.Tpo $(DEPDIR)/ethercat-CommandSdos.Po
#	source='CommandSdos.cpp' object='ethercat-CommandSdos.obj' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-CommandSdos.obj `if test -f 'CommandSdos.cpp'; then $(CYGPATH_W) 'CommandSdos.cpp'; else $(CYGPATH_W) '$(srcdir)/CommandSdos.cpp'; fi`

ethercat-CommandSiiRead.o: CommandSiiRead.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-CommandSiiRead.o -MD -MP -MF $(DEPDIR)/ethercat-CommandSiiRead.Tpo -c -o ethercat-CommandSiiRead.o `test -f 'CommandSiiRead.cpp' || echo '$(srcdir)/'`CommandSiiRead.cpp
	$(am__mv) $(DEPDIR)/ethercat-CommandSiiRead.Tpo $(DEPDIR)/ethercat-CommandSiiRead.Po
#	source='CommandSiiRead.cpp' object='ethercat-CommandSiiRead.o' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-CommandSiiRead.o `test -f 'CommandSiiRead.cpp' || echo '$(srcdir)/'`CommandSiiRead.cpp

ethercat-CommandSiiRead.obj: CommandSiiRead.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-CommandSiiRead.obj -MD -MP -MF $(DEPDIR)/ethercat-CommandSiiRead.Tpo -c -o ethercat-CommandSiiRead.obj `if test -f 'CommandSiiRead.cpp'; then $(CYGPATH_W) 'CommandSiiRead.cpp'; else $(CYGPATH_W) '$(srcdir)/CommandSiiRead.cpp'; fi`
	$(am__mv) $(DEPDIR)/ethercat-CommandSiiRead.Tpo $(DEPDIR)/ethercat-CommandSiiRead.Po
#	source='CommandSiiRead.cpp' object='ethercat-CommandSiiRead.obj' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-CommandSiiRead.obj `if test -f 'CommandSiiRead.cpp'; then $(CYGPATH_W) 'CommandSiiRead.cpp'; else $(CYGPATH_W) '$(srcdir)/CommandSiiRead.cpp'; fi`

ethercat-CommandSiiWrite.o: CommandSiiWrite.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-CommandSiiWrite.o -MD -MP -MF $(DEPDIR)/ethercat-CommandSiiWrite.Tpo -c -o ethercat-CommandSiiWrite.o `test -f 'CommandSiiWrite.cpp' || echo '$(srcdir)/'`CommandSiiWrite.cpp
	$(am__mv) $(DEPDIR)/ethercat-CommandSiiWrite.Tpo $(DEPDIR)/ethercat-CommandSiiWrite.Po
#	source='CommandSiiWrite.cpp' object='ethercat-CommandSiiWrite.o' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-CommandSiiWrite.o `test -f 'CommandSiiWrite.cpp' || echo '$(srcdir)/'`CommandSiiWrite.cpp

ethercat-CommandSiiWrite.obj: CommandSiiWrite.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-CommandSiiWrite.obj -MD -MP -MF $(DEPDIR)/ethercat-CommandSiiWrite.Tpo -c -o ethercat-CommandSiiWrite.obj `if test -f 'CommandSiiWrite.cpp'; then $(CYGPATH_W) 'CommandSiiWrite.cpp'; else $(CYGPATH_W) '$(srcdir)/CommandSiiWrite.cpp'; fi`
	$(am__mv) $(DEPDIR)/ethercat-CommandSiiWrite.Tpo $(DEPDIR)/ethercat-CommandSiiWrite.Po
#	source='CommandSiiWrite.cpp' object='ethercat-CommandSiiWrite.obj' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-CommandSiiWrite.obj `if test -f 'CommandSiiWrite.cpp'; then $(CYGPATH_W) 'CommandSiiWrite.cpp'; else $(CYGPATH_W) '$(srcdir)/CommandSiiWrite.cpp'; fi`

ethercat-CommandSlaves.o: CommandSlaves.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-CommandSlaves.o -MD -MP -MF $(DEPDIR)/ethercat-CommandSlaves.Tpo -c -o ethercat-CommandSlaves.o `test -f 'CommandSlaves.cpp' || echo '$(srcdir)/'`CommandSlaves.cpp
	$(am__mv) $(DEPDIR)/ethercat-CommandSlaves.Tpo $(DEPDIR)/ethercat-CommandSlaves.Po
#	source='CommandSlaves.cpp' object='ethercat-CommandSlaves.o' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-CommandSlaves.o `test -f 'CommandSlaves.cpp' || echo '$(srcdir)/'`CommandSlaves.cpp

ethercat-CommandSlaves.obj: CommandSlaves.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-CommandSlaves.obj -MD -MP -MF $(DEPDIR)/ethercat-CommandSlaves.Tpo -c -o ethercat-CommandSlaves.obj `if test -f 'CommandSlaves.cpp'; then $(CYGPATH_W) 'CommandSlaves.cpp'; else $(CYGPATH_W) '$(srcdir)/CommandSlaves.cpp'; fi`
	$(am__mv) $(DEPDIR)/ethercat-CommandSlaves.Tpo $(DEPDIR)/ethercat-CommandSlaves.Po
#	source='CommandSlaves.cpp' object='ethercat-CommandSlaves.obj' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-CommandSlaves.obj `if test -f 'CommandSlaves.cpp'; then $(CYGPATH_W) 'CommandSlaves.cpp'; else $(CYGPATH_W) '$(srcdir)/CommandSlaves.cpp'; fi`

ethercat-CommandSoeRead.o: CommandSoeRead.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-CommandSoeRead.o -MD -MP -MF $(DEPDIR)/ethercat-CommandSoeRead.Tpo -c -o ethercat-CommandSoeRead.o `test -f 'CommandSoeRead.cpp' || echo '$(srcdir)/'`CommandSoeRead.cpp
	$(am__mv) $(DEPDIR)/ethercat-CommandSoeRead.Tpo $(DEPDIR)/ethercat-CommandSoeRead.Po
#	source='CommandSoeRead.cpp' object='ethercat-CommandSoeRead.o' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-CommandSoeRead.o `test -f 'CommandSoeRead.cpp' || echo '$(srcdir)/'`CommandSoeRead.cpp

ethercat-CommandSoeRead.obj: CommandSoeRead.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-CommandSoeRead.obj -MD -MP -MF $(DEPDIR)/ethercat-CommandSoeRead.Tpo -c -o ethercat-CommandSoeRead.obj `if test -f 'CommandSoeRead.cpp'; then $(CYGPATH_W) 'CommandSoeRead.cpp'; else $(CYGPATH_W) '$(srcdir)/CommandSoeRead.cpp'; fi`
	$(am__mv) $(DEPDIR)/ethercat-CommandSoeRead.Tpo $(DEPDIR)/ethercat-CommandSoeRead.Po
#	source='CommandSoeRead.cpp' object='ethercat-CommandSoeRead.obj' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-CommandSoeRead.obj `if test -f 'CommandSoeRead.cpp'; then $(CYGPATH_W) 'CommandSoeRead.cpp'; else $(CYGPATH_W) '$(srcdir)/CommandSoeRead.cpp'; fi`

ethercat-CommandSoeWrite.o: CommandSoeWrite.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-CommandSoeWrite.o -MD -MP -MF $(DEPDIR)/ethercat-CommandSoeWrite.Tpo -c -o ethercat-CommandSoeWrite.o `test -f 'CommandSoeWrite.cpp' || echo '$(srcdir)/'`CommandSoeWrite.cpp
	$(am__mv) $(DEPDIR)/ethercat-CommandSoeWrite.Tpo $(DEPDIR)/ethercat-CommandSoeWrite.Po
#	source='CommandSoeWrite.cpp' object='ethercat-CommandSoeWrite.o' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-CommandSoeWrite.o `test -f 'CommandSoeWrite.cpp' || echo '$(srcdir)/'`CommandSoeWrite.cpp

ethercat-CommandSoeWrite.obj: CommandSoeWrite.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-CommandSoeWrite.obj -MD -MP -MF $(DEPDIR)/ethercat-CommandSoeWrite.Tpo -c -o ethercat-CommandSoeWrite.obj `if test -f 'CommandSoeWrite.cpp'; then $(CYGPATH_W) 'CommandSoeWrite.cpp'; else $(CYGPATH_W) '$(srcdir)/CommandSoeWrite.cpp'; fi`
	$(am__mv) $(DEPDIR)/ethercat-CommandSoeWrite.Tpo $(DEPDIR)/ethercat-CommandSoeWrite.Po
#	source='CommandSoeWrite.cpp' object='ethercat-CommandSoeWrite.obj' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-CommandSoeWrite.obj `if test -f 'CommandSoeWrite.cpp'; then $(CYGPATH_W) 'CommandSoeWrite.cpp'; else $(CYGPATH_W) '$(srcdir)/CommandSoeWrite.cpp'; fi`

ethercat-CommandStates.o: CommandStates.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-CommandStates.o -MD -MP -MF $(DEPDIR)/ethercat-CommandStates.Tpo -c -o ethercat-CommandStates.o `test -f 'CommandStates.cpp' || echo '$(srcdir)/'`CommandStates.cpp
	$(am__mv) $(DEPDIR)/ethercat-CommandStates.Tpo $(DEPDIR)/ethercat-CommandStates.Po
#	source='CommandStates.cpp' object='ethercat-CommandStates.o' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-CommandStates.o `test -f 'CommandStates.cpp' || echo '$(srcdir)/'`CommandStates.cpp

ethercat-CommandStates.obj: CommandStates.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-CommandStates.obj -MD -MP -MF $(DEPDIR)/ethercat-CommandStates.Tpo -c -o ethercat-CommandStates.obj `if test -f 'CommandStates.cpp'; then $(CYGPATH_W) 'CommandStates.cpp'; else $(CYGPATH_W) '$(srcdir)/CommandStates.cpp'; fi`
	$(am__mv) $(DEPDIR)/ethercat-CommandStates.Tpo $(DEPDIR)/ethercat-CommandStates.Po
#	source='CommandStates.cpp' object='ethercat-CommandStates.obj' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-CommandStates.obj `if test -f 'CommandStates.cpp'; then $(CYGPATH_W) 'CommandStates.cpp'; else $(CYGPATH_W) '$(srcdir)/CommandStates.cpp'; fi`

ethercat-CommandUpload.o: CommandUpload.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-CommandUpload.o -MD -MP -MF $(DEPDIR)/ethercat-CommandUpload.Tpo -c -o ethercat-CommandUpload.o `test -f 'CommandUpload.cpp' || echo '$(srcdir)/'`CommandUpload.cpp
	$(am__mv) $(DEPDIR)/ethercat-CommandUpload.Tpo $(DEPDIR)/ethercat-CommandUpload.Po
#	source='CommandUpload.cpp' object='ethercat-CommandUpload.o' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-CommandUpload.o `test -f 'CommandUpload.cpp' || echo '$(srcdir)/'`CommandUpload.cpp

ethercat-CommandUpload.obj: CommandUpload.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-CommandUpload.obj -MD -MP -MF $(DEPDIR)/ethercat-CommandUpload.Tpo -c -o ethercat-CommandUpload.obj `if test -f 'CommandUpload.cpp'; then $(CYGPATH_W) 'CommandUpload.cpp'; else $(CYGPATH_W) '$(srcdir)/CommandUpload.cpp'; fi`
	$(am__mv) $(DEPDIR)/ethercat-CommandUpload.Tpo $(DEPDIR)/ethercat-CommandUpload.Po
#	source='CommandUpload.cpp' object='ethercat-CommandUpload.obj' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-CommandUpload.obj `if test -f 'CommandUpload.cpp'; then $(CYGPATH_W) 'CommandUpload.cpp'; else $(CYGPATH_W) '$(srcdir)/CommandUpload.cpp'; fi`

ethercat-CommandVersion.o: CommandVersion.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-CommandVersion.o -MD -MP -MF $(DEPDIR)/ethercat-CommandVersion.Tpo -c -o ethercat-CommandVersion.o `test -f 'CommandVersion.cpp' || echo '$(srcdir)/'`CommandVersion.cpp
	$(am__mv) $(DEPDIR)/ethercat-CommandVersion.Tpo $(DEPDIR)/ethercat-CommandVersion.Po
#	source='CommandVersion.cpp' object='ethercat-CommandVersion.o' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-CommandVersion.o `test -f 'CommandVersion.cpp' || echo '$(srcdir)/'`CommandVersion.cpp

ethercat-CommandVersion.obj: CommandVersion.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-CommandVersion.obj -MD -MP -MF $(DEPDIR)/ethercat-CommandVersion.Tpo -c -o ethercat-CommandVersion.obj `if test -f 'CommandVersion.cpp'; then $(CYGPATH_W) 'CommandVersion.cpp'; else $(CYGPATH_W) '$(srcdir)/CommandVersion.cpp'; fi`
	$(am__mv) $(DEPDIR)/ethercat-CommandVersion.Tpo $(DEPDIR)/ethercat-CommandVersion.Po
#	source='CommandVersion.cpp' object='ethercat-CommandVersion.obj' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-CommandVersion.obj `if test -f 'CommandVersion.cpp'; then $(CYGPATH_W) 'CommandVersion.cpp'; else $(CYGPATH_W) '$(srcdir)/CommandVersion.cpp'; fi`

ethercat-CommandXml.o: CommandXml.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-CommandXml.o -MD -MP -MF $(DEPDIR)/ethercat-CommandXml.Tpo -c -o ethercat-CommandXml.o `test -f 'CommandXml.cpp' || echo '$(srcdir)/'`CommandXml.cpp
	$(am__mv) $(DEPDIR)/ethercat-CommandXml.Tpo $(DEPDIR)/ethercat-CommandXml.Po
#	source='CommandXml.cpp' object='ethercat-CommandXml.o' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-CommandXml.o `test -f 'CommandXml.cpp' || echo '$(srcdir)/'`CommandXml.cpp

ethercat-CommandXml.obj: CommandXml.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-CommandXml.obj -MD -MP -MF $(DEPDIR)/ethercat-CommandXml.Tpo -c -o ethercat-CommandXml.obj `if test -f 'CommandXml.cpp'; then $(CYGPATH_W) 'CommandXml.cpp'; else $(CYGPATH_W) '$(srcdir)/CommandXml.cpp'; fi`
	$(am__mv) $(DEPDIR)/ethercat-CommandXml.Tpo $(DEPDIR)/ethercat-CommandXml.Po
#	source='CommandXml.cpp' object='ethercat-CommandXml.obj' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-CommandXml.obj `if test -f 'CommandXml.cpp'; then $(CYGPATH_W) 'CommandXml.cpp'; else $(CYGPATH_W) '$(srcdir)/CommandXml.cpp'; fi`

ethercat-DataTypeHandler.o: DataTypeHandler.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-DataTypeHandler.o -MD -MP -MF $(DEPDIR)/ethercat-DataTypeHandler.Tpo -c -o ethercat-DataTypeHandler.o `test -f 'DataTypeHandler.cpp' || echo '$(srcdir)/'`DataTypeHandler.cpp
	$(am__mv) $(DEPDIR)/ethercat-DataTypeHandler.Tpo $(DEPDIR)/ethercat-DataTypeHandler.Po
#	source='DataTypeHandler.cpp' object='ethercat-DataTypeHandler.o' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-DataTypeHandler.o `test -f 'DataTypeHandler.cpp' || echo '$(srcdir)/'`DataTypeHandler.cpp

ethercat-DataTypeHandler.obj: DataTypeHandler.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-DataTypeHandler.obj -MD -MP -MF $(DEPDIR)/ethercat-DataTypeHandler.Tpo -c -o ethercat-DataTypeHandler.obj `if test -f 'DataTypeHandler.cpp'; then $(CYGPATH_W) 'DataTypeHandler.cpp'; else $(CYGPATH_W) '$(srcdir)/DataTypeHandler.cpp'; fi`
	$(am__mv) $(DEPDIR)/ethercat-DataTypeHandler.Tpo $(DEPDIR)/ethercat-DataTypeHandler.Po
#	source='DataTypeHandler.cpp' object='ethercat-DataTypeHandler.obj' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-DataTypeHandler.obj `if test -f 'DataTypeHandler.cpp'; then $(CYGPATH_W) 'DataTypeHandler.cpp'; else $(CYGPATH_W) '$(srcdir)/DataTypeHandler.cpp'; fi`

ethercat-FoeCommand.o: FoeCommand.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-FoeCommand.o -MD -MP -MF $(DEPDIR)/ethercat-FoeCommand.Tpo -c -o ethercat-FoeCommand.o `test -f 'FoeCommand.cpp' || echo '$(srcdir)/'`FoeCommand.cpp
	$(am__mv) $(DEPDIR)/ethercat-FoeCommand.Tpo $(DEPDIR)/ethercat-FoeCommand.Po
#	source='FoeCommand.cpp' object='ethercat-FoeCommand.o' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-FoeCommand.o `test -f 'FoeCommand.cpp' || echo '$(srcdir)/'`FoeCommand.cpp

ethercat-FoeCommand.obj: FoeCommand.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-FoeCommand.obj -MD -MP -MF $(DEPDIR)/ethercat-FoeCommand.Tpo -c -o ethercat-FoeCommand.obj `if test -f 'FoeCommand.cpp'; then $(CYGPATH_W) 'FoeCommand.cpp'; else $(CYGPATH_W) '$(srcdir)/FoeCommand.cpp'; fi`
	$(am__mv) $(DEPDIR)/ethercat-FoeCommand.Tpo $(DEPDIR)/ethercat-FoeCommand.Po
#	source='FoeCommand.cpp' object='ethercat-FoeCommand.obj' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-FoeCommand.obj `if test -f 'FoeCommand.cpp'; then $(CYGPATH_W) 'FoeCommand.cpp'; else $(CYGPATH_W) '$(srcdir)/FoeCommand.cpp'; fi`

ethercat-MasterDevice.o: MasterDevice.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-MasterDevice.o -MD -MP -MF $(DEPDIR)/ethercat-MasterDevice.Tpo -c -o ethercat-MasterDevice.o `test -f 'MasterDevice.cpp' || echo '$(srcdir)/'`MasterDevice.cpp
	$(am__mv) $(DEPDIR)/ethercat-MasterDevice.Tpo $(DEPDIR)/ethercat-MasterDevice.Po
#	source='MasterDevice.cpp' object='ethercat-MasterDevice.o' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-MasterDevice.o `test -f 'MasterDevice.cpp' || echo '$(srcdir)/'`MasterDevice.cpp

ethercat-MasterDevice.obj: MasterDevice.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-MasterDevice.obj -MD -MP -MF $(DEPDIR)/ethercat-MasterDevice.Tpo -c -o ethercat-MasterDevice.obj `if test -f 'MasterDevice.cpp'; then $(CYGPATH_W) 'MasterDevice.cpp'; else $(CYGPATH_W) '$(srcdir)/MasterDevice.cpp'; fi`
	$(am__mv) $(DEPDIR)/ethercat-MasterDevice.Tpo $(DEPDIR)/ethercat-MasterDevice.Po
#	source='MasterDevice.cpp' object='ethercat-MasterDevice.obj' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-MasterDevice.obj `if test -f 'MasterDevice.cpp'; then $(CYGPATH_W) 'MasterDevice.cpp'; else $(CYGPATH_W) '$(srcdir)/MasterDevice.cpp'; fi`

ethercat-NumberListParser.o: NumberListParser.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-NumberListParser.o -MD -MP -MF $(DEPDIR)/ethercat-NumberListParser.Tpo -c -o ethercat-NumberListParser.o `test -f 'NumberListParser.cpp' || echo '$(srcdir)/'`NumberListParser.cpp
	$(am__mv) $(DEPDIR)/ethercat-NumberListParser.Tpo $(DEPDIR)/ethercat-NumberListParser.Po
#	source='NumberListParser.cpp' object='ethercat-NumberListParser.o' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-NumberListParser.o `test -f 'NumberListParser.cpp' || echo '$(srcdir)/'`NumberListParser.cpp

ethercat-NumberListParser.obj: NumberListParser.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-NumberListParser.obj -MD -MP -MF $(DEPDIR)/ethercat-NumberListParser.Tpo -c -o ethercat-NumberListParser.obj `if test -f 'NumberListParser.cpp'; then $(CYGPATH_W) 'NumberListParser.cpp'; else $(CYGPATH_W) '$(srcdir)/NumberListParser.cpp'; fi`
	$(am__mv) $(DEPDIR)/ethercat-NumberListParser.Tpo $(DEPDIR)/ethercat-NumberListParser.Po
#	source='NumberListParser.cpp' object='ethercat-NumberListParser.obj' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-NumberListParser.obj `if test -f 'NumberListParser.cpp'; then $(CYGPATH_W) 'NumberListParser.cpp'; else $(CYGPATH_W) '$(srcdir)/NumberListParser.cpp'; fi`

ethercat-SdoCommand.o: SdoCommand.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-SdoCommand.o -MD -MP -MF $(DEPDIR)/ethercat-SdoCommand.Tpo -c -o ethercat-SdoCommand.o `test -f 'SdoCommand.cpp' || echo '$(srcdir)/'`SdoCommand.cpp
	$(am__mv) $(DEPDIR)/ethercat-SdoCommand.Tpo $(DEPDIR)/ethercat-SdoCommand.Po
#	source='SdoCommand.cpp' object='ethercat-SdoCommand.o' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-SdoCommand.o `test -f 'SdoCommand.cpp' || echo '$(srcdir)/'`SdoCommand.cpp

ethercat-SdoCommand.obj: SdoCommand.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-SdoCommand.obj -MD -MP -MF $(DEPDIR)/ethercat-SdoCommand.Tpo -c -o ethercat-SdoCommand.obj `if test -f 'SdoCommand.cpp'; then $(CYGPATH_W) 'SdoCommand.cpp'; else $(CYGPATH_W) '$(srcdir)/SdoCommand.cpp'; fi`
	$(am__mv) $(DEPDIR)/ethercat-SdoCommand.Tpo $(DEPDIR)/ethercat-SdoCommand.Po
#	source='SdoCommand.cpp' object='ethercat-SdoCommand.obj' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-SdoCommand.obj `if test -f 'SdoCommand.cpp'; then $(CYGPATH_W) 'SdoCommand.cpp'; else $(CYGPATH_W) '$(srcdir)/SdoCommand.cpp'; fi`

ethercat-SoeCommand.o: SoeCommand.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-SoeCommand.o -MD -MP -MF $(DEPDIR)/ethercat-SoeCommand.Tpo -c -o ethercat-SoeCommand.o `test -f 'SoeCommand.cpp' || echo '$(srcdir)/'`SoeCommand.cpp
	$(am__mv) $(DEPDIR)/ethercat-SoeCommand.Tpo $(DEPDIR)/ethercat-SoeCommand.Po
#	source='SoeCommand.cpp' object='ethercat-SoeCommand.o' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-SoeCommand.o `test -f 'SoeCommand.cpp' || echo '$(srcdir)/'`SoeCommand.cpp

ethercat-SoeCommand.obj: SoeCommand.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-SoeCommand.obj -MD -MP -MF $(DEPDIR)/ethercat-SoeCommand.Tpo -c -o ethercat-SoeCommand.obj `if test -f 'SoeCommand.cpp'; then $(CYGPATH_W) 'SoeCommand.cpp'; else $(CYGPATH_W) '$(srcdir)/SoeCommand.cpp'; fi`
	$(am__mv) $(DEPDIR)/ethercat-SoeCommand.Tpo $(DEPDIR)/ethercat-SoeCommand.Po
#	source='SoeCommand.cpp' object='ethercat-SoeCommand.obj' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-SoeCommand.obj `if test -f 'SoeCommand.cpp'; then $(CYGPATH_W) 'SoeCommand.cpp'; else $(CYGPATH_W) '$(srcdir)/SoeCommand.cpp'; fi`

ethercat-main.o: main.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-main.o -MD -MP -MF $(DEPDIR)/ethercat-main.Tpo -c -o ethercat-main.o `test -f 'main.cpp' || echo '$(srcdir)/'`main.cpp
	$(am__mv) $(DEPDIR)/ethercat-main.Tpo $(DEPDIR)/ethercat-main.Po
#	source='main.cpp' object='ethercat-main.o' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-main.o `test -f 'main.cpp' || echo '$(srcdir)/'`main.cpp

ethercat-main.obj: main.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-main.obj -MD -MP -MF $(DEPDIR)/ethercat-main.Tpo -c -o ethercat-main.obj `if test -f 'main.cpp'; then $(CYGPATH_W) 'main.cpp'; else $(CYGPATH_W) '$(srcdir)/main.cpp'; fi`
	$(am__mv) $(DEPDIR)/ethercat-main.Tpo $(DEPDIR)/ethercat-main.Po
#	source='main.cpp' object='ethercat-main.obj' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-main.obj `if test -f 'main.cpp'; then $(CYGPATH_W) 'main.cpp'; else $(CYGPATH_W) '$(srcdir)/main.cpp'; fi`

ethercat-sii_crc.o: sii_crc.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-sii_crc.o -MD -MP -MF $(DEPDIR)/ethercat-sii_crc.Tpo -c -o ethercat-sii_crc.o `test -f 'sii_crc.cpp' || echo '$(srcdir)/'`sii_crc.cpp
	$(am__mv) $(DEPDIR)/ethercat-sii_crc.Tpo $(DEPDIR)/ethercat-sii_crc.Po
#	source='sii_crc.cpp' object='ethercat-sii_crc.o' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-sii_crc.o `test -f 'sii_crc.cpp' || echo '$(srcdir)/'`sii_crc.cpp

ethercat-sii_crc.obj: sii_crc.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-sii_crc.obj -MD -MP -MF $(DEPDIR)/ethercat-sii_crc.Tpo -c -o ethercat-sii_crc.obj `if test -f 'sii_crc.cpp'; then $(CYGPATH_W) 'sii_crc.cpp'; else $(CYGPATH_W) '$(srcdir)/sii_crc.cpp'; fi`
	$(am__mv) $(DEPDIR)/ethercat-sii_crc.Tpo $(DEPDIR)/ethercat-sii_crc.Po
#	source='sii_crc.cpp' object='ethercat-sii_crc.obj' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-sii_crc.obj `if test -f 'sii_crc.cpp'; then $(CYGPATH_W) 'sii_crc.cpp'; else $(CYGPATH_W) '$(srcdir)/sii_crc.cpp'; fi`

ethercat-CommandEoe.o: CommandEoe.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-CommandEoe.o -MD -MP -MF $(DEPDIR)/ethercat-CommandEoe.Tpo -c -o ethercat-CommandEoe.o `test -f 'CommandEoe.cpp' || echo '$(srcdir)/'`CommandEoe.cpp
	$(am__mv) $(DEPDIR)/ethercat-CommandEoe.Tpo $(DEPDIR)/ethercat-CommandEoe.Po
#	source='CommandEoe.cpp' object='ethercat-CommandEoe.o' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-CommandEoe.o `test -f 'CommandEoe.cpp' || echo '$(srcdir)/'`CommandEoe.cpp

ethercat-CommandEoe.obj: CommandEoe.cpp
	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -MT ethercat-CommandEoe.obj -MD -MP -MF $(DEPDIR)/ethercat-CommandEoe.Tpo -c -o ethercat-CommandEoe.obj `if test -f 'CommandEoe.cpp'; then $(CYGPATH_W) 'CommandEoe.cpp'; else $(CYGPATH_W) '$(srcdir)/CommandEoe.cpp'; fi`
	$(am__mv) $(DEPDIR)/ethercat-CommandEoe.Tpo $(DEPDIR)/ethercat-CommandEoe.Po
#	source='CommandEoe.cpp' object='ethercat-CommandEoe.obj' libtool=no \
#	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
#	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ethercat_CXXFLAGS) $(CXXFLAGS) -c -o ethercat-CommandEoe.obj `if test -f 'CommandEoe.cpp'; then $(CYGPATH_W) 'CommandEoe.cpp'; else $(CYGPATH_W) '$(srcdir)/CommandEoe.cpp'; fi`

mostlyclean-libtool:
	-rm -f *.lo

clean-libtool:
	-rm -rf .libs _libs

ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
	unique=`for i in $$list; do \
	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
	  done | \
	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
	      END { if (nonempty) { for (i in files) print i; }; }'`; \
	mkid -fID $$unique
tags: TAGS

TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
		$(TAGS_FILES) $(LISP)
	set x; \
	here=`pwd`; \
	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
	unique=`for i in $$list; do \
	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
	  done | \
	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
	      END { if (nonempty) { for (i in files) print i; }; }'`; \
	shift; \
	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
	  test -n "$$unique" || unique=$$empty_fix; \
	  if test $$# -gt 0; then \
	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
	      "$$@" $$unique; \
	  else \
	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
	      $$unique; \
	  fi; \
	fi
ctags: CTAGS
CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
		$(TAGS_FILES) $(LISP)
	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
	unique=`for i in $$list; do \
	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
	  done | \
	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
	      END { if (nonempty) { for (i in files) print i; }; }'`; \
	test -z "$(CTAGS_ARGS)$$unique" \
	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
	     $$unique

GTAGS:
	here=`$(am__cd) $(top_builddir) && pwd` \
	  && $(am__cd) $(top_srcdir) \
	  && gtags -i $(GTAGS_ARGS) "$$here"

distclean-tags:
	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags

distdir: $(DISTFILES)
	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
	list='$(DISTFILES)'; \
	  dist_files=`for file in $$list; do echo $$file; done | \
	  sed -e "s|^$$srcdirstrip/||;t" \
	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
	case $$dist_files in \
	  */*) $(MKDIR_P) `echo "$$dist_files" | \
			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
			   sort -u` ;; \
	esac; \
	for file in $$dist_files; do \
	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
	  if test -d $$d/$$file; then \
	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
	    if test -d "$(distdir)/$$file"; then \
	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
	    fi; \
	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
	    fi; \
	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
	  else \
	    test -f "$(distdir)/$$file" \
	    || cp -p $$d/$$file "$(distdir)/$$file" \
	    || exit 1; \
	  fi; \
	done
check-am: all-am
check: check-am
all-am: Makefile $(PROGRAMS) $(HEADERS)
installdirs:
	for dir in "$(DESTDIR)$(bindir)"; do \
	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
	done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am

install-am: all-am
	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am

installcheck: installcheck-am
install-strip:
	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
	  `test -z '$(STRIP)' || \
	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:

clean-generic:

distclean-generic:
	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)

maintainer-clean-generic:
	@echo "This command is intended for maintainers to use"
	@echo "it deletes files that may require special tools to rebuild."
clean: clean-am

clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am

distclean: distclean-am
	-rm -rf ./$(DEPDIR)
	-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
	distclean-tags

dvi: dvi-am

dvi-am:

html: html-am

html-am:

info: info-am

info-am:

install-data-am:

install-dvi: install-dvi-am

install-dvi-am:

install-exec-am: install-binPROGRAMS

install-html: install-html-am

install-html-am:

install-info: install-info-am

install-info-am:

install-man:

install-pdf: install-pdf-am

install-pdf-am:

install-ps: install-ps-am

install-ps-am:

installcheck-am:

maintainer-clean: maintainer-clean-am
	-rm -rf ./$(DEPDIR)
	-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic

mostlyclean: mostlyclean-am

mostlyclean-am: mostlyclean-compile mostlyclean-generic \
	mostlyclean-libtool

pdf: pdf-am

pdf-am:

ps: ps-am

ps-am:

uninstall-am: uninstall-binPROGRAMS

.MAKE: install-am install-strip

.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \
	clean-generic clean-libtool ctags distclean distclean-compile \
	distclean-generic distclean-libtool distclean-tags distdir dvi \
	dvi-am html html-am info info-am install install-am \
	install-binPROGRAMS install-data install-data-am install-dvi \
	install-dvi-am install-exec install-exec-am install-html \
	install-html-am install-info install-info-am install-man \
	install-pdf install-pdf-am install-ps install-ps-am \
	install-strip installcheck installcheck-am installdirs \
	maintainer-clean maintainer-clean-generic mostlyclean \
	mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
	pdf pdf-am ps ps-am tags uninstall uninstall-am \
	uninstall-binPROGRAMS


#------------------------------------------------------------------------------

# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:


<|start_filename|>3rdpart/ethercat-1.5.2/master/pdo.c<|end_filename|>
/******************************************************************************
 *
 *  $Id: pdo.c,v ec403cf308eb 2013/02/12 14:46:43 fp $
 *
 *  Copyright (C) 2006-2008  <NAME>, Ingenieurgemeinschaft IgH
 *
 *  This file is part of the IgH EtherCAT Master.
 *
 *  The IgH EtherCAT Master is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License version 2, as
 *  published by the Free Software Foundation.
 *
 *  The IgH EtherCAT Master is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 *  Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with the IgH EtherCAT Master; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 *****************************************************************************/

/**
   \file
   EtherCAT process data object methods.
*/

/*****************************************************************************/

#include <linux/slab.h>
#include <linux/err.h>

#include "pdo.h"

/*****************************************************************************/

/** PDO constructor.
 */
void ec_pdo_init(
        ec_pdo_t *pdo /**< EtherCAT PDO */
        )
{
    pdo->sync_index = -1; // not assigned
    pdo->name = NULL;
    INIT_LIST_HEAD(&pdo->entries);
}

/*****************************************************************************/

/** PDO copy constructor.
 *
 * \retval  0 Success.
 * \retval <0 Error code.
 */
int ec_pdo_init_copy(
        ec_pdo_t *pdo, /**< PDO to create. */
        const ec_pdo_t *other_pdo /**< PDO to copy from. */
        )
{
    int ret = 0;

    pdo->index = other_pdo->index;
    pdo->sync_index = other_pdo->sync_index;
    pdo->name = NULL;
    INIT_LIST_HEAD(&pdo->entries);

    ret = ec_pdo_set_name(pdo, other_pdo->name);
    if (ret < 0)
        goto out_return;

    ret = ec_pdo_copy_entries(pdo, other_pdo);
    if (ret < 0)
        goto out_clear;

    return 0;

out_clear:
    ec_pdo_clear(pdo);
out_return:
    return ret;
}

/*****************************************************************************/

/** PDO destructor.
 */
void ec_pdo_clear(ec_pdo_t *pdo /**< EtherCAT PDO. */)
{
    if (pdo->name)
        kfree(pdo->name);

    ec_pdo_clear_entries(pdo);
}

/*****************************************************************************/

/** Clear PDO entry list.
 */
void ec_pdo_clear_entries(ec_pdo_t *pdo /**< EtherCAT PDO. */)
{
    ec_pdo_entry_t *entry, *next;

    // free all PDO entries
    list_for_each_entry_safe(entry, next, &pdo->entries, list) {
        list_del(&entry->list);
        ec_pdo_entry_clear(entry);
        kfree(entry);
    }
}

/*****************************************************************************/

/** Set PDO name.
 *
 * \retval  0 Success.
 * \retval <0 Error code.
 */
int ec_pdo_set_name(
        ec_pdo_t *pdo, /**< PDO. */
        const char *name /**< New name. */
        )
{
    unsigned int len;

    if (pdo->name && name && !strcmp(pdo->name, name))
        return 0;

    if (pdo->name)
        kfree(pdo->name);

    if (name && (len = strlen(name))) {
        if (!(pdo->name = (char *) kmalloc(len + 1, GFP_KERNEL))) {
            EC_ERR("Failed to allocate PDO name.\n");
            return -ENOMEM;
        }
        memcpy(pdo->name, name, len + 1);
    } else {
        pdo->name = NULL;
    }

    return 0;
}

/*****************************************************************************/

/** Add a new PDO entry to the configuration.
 *
 * \retval Pointer to the added entry, otherwise a ERR_PTR() code.
 */
ec_pdo_entry_t *ec_pdo_add_entry(
        ec_pdo_t *pdo, /**< PDO. */
        uint16_t index, /**< New entry's index. */
        uint8_t subindex, /**< New entry's subindex. */
        uint8_t bit_length /**< New entry's bit length. */
        )
{
    ec_pdo_entry_t *entry;

    if (!(entry = kmalloc(sizeof(ec_pdo_entry_t), GFP_KERNEL))) {
        EC_ERR("Failed to allocate memory for PDO entry.\n");
        return ERR_PTR(-ENOMEM);
    }

    ec_pdo_entry_init(entry);
    entry->index = index;
    entry->subindex = subindex;
    entry->bit_length = bit_length;
    list_add_tail(&entry->list, &pdo->entries);
    return entry;
}

/*****************************************************************************/

/** Copy PDO entries from another PDO.
 *
 * \retval  0 Success.
 * \retval <0 Error code.
 */
int ec_pdo_copy_entries(
        ec_pdo_t *pdo, /**< PDO whos entries shall be replaced. */
        const ec_pdo_t *other /**< Pdo with entries to copy. */
        )
{
    ec_pdo_entry_t *entry, *other_entry;
    int ret;

    ec_pdo_clear_entries(pdo);

    list_for_each_entry(other_entry, &other->entries, list) {
        if (!(entry = (ec_pdo_entry_t *)
                    kmalloc(sizeof(ec_pdo_entry_t), GFP_KERNEL))) {
            EC_ERR("Failed to allocate memory for PDO entry copy.\n");
            return -ENOMEM;
        }

        ret = ec_pdo_entry_init_copy(entry, other_entry);
        if (ret < 0) {
            kfree(entry);
            return ret;
        }

        list_add_tail(&entry->list, &pdo->entries);
    }

    return 0;
}

/*****************************************************************************/

/** Compares the entries of two PDOs.
 *
 * \retval 1 The entries of the given PDOs are equal.
 * \retval 0 The entries of the given PDOs differ.
 */
int ec_pdo_equal_entries(
        const ec_pdo_t *pdo1, /**< First PDO. */
        const ec_pdo_t *pdo2 /**< Second PDO. */
        )
{
    const struct list_head *head1, *head2, *item1, *item2;
    const ec_pdo_entry_t *entry1, *entry2;

    head1 = item1 = &pdo1->entries;
    head2 = item2 = &pdo2->entries;

    while (1) {
        item1 = item1->next;
        item2 = item2->next;

        if ((item1 == head1) ^ (item2 == head2)) // unequal lengths
            return 0;
        if (item1 == head1) // both finished
            break;

        entry1 = list_entry(item1, ec_pdo_entry_t, list);
        entry2 = list_entry(item2, ec_pdo_entry_t, list);
        if (!ec_pdo_entry_equal(entry1, entry2))
            return 0;
    }

    return 1;
}

/*****************************************************************************/

/** Get the number of PDO entries.
 *
 * \return Number of PDO entries.
 */
unsigned int ec_pdo_entry_count(
        const ec_pdo_t *pdo /**< PDO. */
        )
{
    const ec_pdo_entry_t *entry;
    unsigned int num = 0;

    list_for_each_entry(entry, &pdo->entries, list) {
        num++;
    }

    return num;
}

/*****************************************************************************/

/** Finds a PDO entry via its position in the list.
 *
 * Const version.
 *
 * \return Search result, or NULL.
 */
const ec_pdo_entry_t *ec_pdo_find_entry_by_pos_const(
        const ec_pdo_t *pdo, /**< PDO. */
        unsigned int pos /**< Position in the list. */
        )
{
    const ec_pdo_entry_t *entry;

    list_for_each_entry(entry, &pdo->entries, list) {
        if (pos--)
            continue;
        return entry;
    }

    return NULL;
}

/*****************************************************************************/

/** Outputs the PDOs in the list.
 */
void ec_pdo_print_entries(
        const ec_pdo_t *pdo /**< PDO. */
        )
{
    const ec_pdo_entry_t *entry;

    if (list_empty(&pdo->entries)) {
        printk("(none)");
    } else {
        list_for_each_entry(entry, &pdo->entries, list) {
            printk("0x%04X:%02X/%u",
                    entry->index, entry->subindex, entry->bit_length);
            if (entry->list.next != &pdo->entries)
                printk(" ");
        }
    }
}

/*****************************************************************************/


<|start_filename|>3rdpart/ethercat-1.5.2/master/device.c<|end_filename|>
/******************************************************************************
 *
 *  $Id: device.c,v ec403cf308eb 2013/02/12 14:46:43 fp $
 *
 *  Copyright (C) 2006-2008  <NAME>, Ingenieurgemeinschaft IgH
 *
 *  This file is part of the IgH EtherCAT Master.
 *
 *  The IgH EtherCAT Master is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License version 2, as
 *  published by the Free Software Foundation.
 *
 *  The IgH EtherCAT Master is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 *  Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with the IgH EtherCAT Master; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 *****************************************************************************/

/**
   \file
   EtherCAT device methods.
*/

/*****************************************************************************/

#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/if_ether.h>
#include <linux/netdevice.h>

#include "device.h"
#include "master.h"

#ifdef EC_DEBUG_RING
#define timersub(a, b, result) \
    do { \
        (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \
        (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \
        if ((result)->tv_usec < 0) { \
            --(result)->tv_sec; \
            (result)->tv_usec += 1000000; \
        } \
    } while (0)
#endif

/*****************************************************************************/

/** Constructor.
 *
 * \return 0 in case of success, else < 0
 */
int ec_device_init(
        ec_device_t *device, /**< EtherCAT device */
        ec_master_t *master /**< master owning the device */
        )
{
    int ret;
    unsigned int i;
    struct ethhdr *eth;
#ifdef EC_DEBUG_IF
    char ifname[10];
    char mb = 'x';
#endif

    device->master = master;
    device->dev = NULL;
    device->poll = NULL;
    device->module = NULL;
    device->open = 0;
    device->link_state = 0;
    for (i = 0; i < EC_TX_RING_SIZE; i++) {
        device->tx_skb[i] = NULL;
    }
    device->tx_ring_index = 0;
#ifdef EC_HAVE_CYCLES
    device->cycles_poll = 0;
#endif
#ifdef EC_DEBUG_RING
    device->timeval_poll.tv_sec = 0;
    device->timeval_poll.tv_usec = 0;
#endif
    device->jiffies_poll = 0;

    ec_device_clear_stats(device);

#ifdef EC_DEBUG_RING
    for (i = 0; i < EC_DEBUG_RING_SIZE; i++) {
        ec_debug_frame_t *df = &device->debug_frames[i];
        df->dir = TX;
        df->t.tv_sec = 0;
        df->t.tv_usec = 0;
        memset(df->data, 0, EC_MAX_DATA_SIZE);
        df->data_size = 0;
    }
#endif
#ifdef EC_DEBUG_RING
    device->debug_frame_index = 0;
    device->debug_frame_count = 0;
#endif

#ifdef EC_DEBUG_IF
    if (device == &master->devices[EC_DEVICE_MAIN]) {
        mb = 'm';
    }
    else {
        mb = 'b';
    }

    sprintf(ifname, "ecdbg%c%u", mb, master->index);

    ret = ec_debug_init(&device->dbg, device, ifname);
    if (ret < 0) {
        EC_MASTER_ERR(master, "Failed to init debug device!\n");
        goto out_return;
    }
#endif

    for (i = 0; i < EC_TX_RING_SIZE; i++) {
        if (!(device->tx_skb[i] = dev_alloc_skb(ETH_FRAME_LEN))) {
            EC_MASTER_ERR(master, "Error allocating device socket buffer!\n");
            ret = -ENOMEM;
            goto out_tx_ring;
        }

        // add Ethernet-II-header
        skb_reserve(device->tx_skb[i], ETH_HLEN);
        eth = (struct ethhdr *) skb_push(device->tx_skb[i], ETH_HLEN);
        eth->h_proto = htons(0x88A4);
        memset(eth->h_dest, 0xFF, ETH_ALEN);
    }

    return 0;

out_tx_ring:
    for (i = 0; i < EC_TX_RING_SIZE; i++) {
        if (device->tx_skb[i]) {
            dev_kfree_skb(device->tx_skb[i]);
        }
    }
#ifdef EC_DEBUG_IF
    ec_debug_clear(&device->dbg);
out_return:
#endif
    return ret;
}

/*****************************************************************************/

/** Destructor.
 */
void ec_device_clear(
        ec_device_t *device /**< EtherCAT device */
        )
{
    unsigned int i;

    if (device->open) {
        ec_device_close(device);
    }
    for (i = 0; i < EC_TX_RING_SIZE; i++)
        dev_kfree_skb(device->tx_skb[i]);
#ifdef EC_DEBUG_IF
    ec_debug_clear(&device->dbg);
#endif
}

/*****************************************************************************/

/** Associate with net_device.
 */
void ec_device_attach(
        ec_device_t *device, /**< EtherCAT device */
        struct net_device *net_dev, /**< net_device structure */
        ec_pollfunc_t poll, /**< pointer to device's poll function */
        struct module *module /**< the device's module */
        )
{
    unsigned int i;
    struct ethhdr *eth;

    ec_device_detach(device); // resets fields

    device->dev = net_dev;
    device->poll = poll;
    device->module = module;

    for (i = 0; i < EC_TX_RING_SIZE; i++) {
        device->tx_skb[i]->dev = net_dev;
        eth = (struct ethhdr *) (device->tx_skb[i]->data);
        memcpy(eth->h_source, net_dev->dev_addr, ETH_ALEN);
    }

#ifdef EC_DEBUG_IF
    ec_debug_register(&device->dbg, net_dev);
#endif
}

/*****************************************************************************/

/** Disconnect from net_device.
 */
void ec_device_detach(
        ec_device_t *device /**< EtherCAT device */
        )
{
    unsigned int i;

#ifdef EC_DEBUG_IF
    ec_debug_unregister(&device->dbg);
#endif

    device->dev = NULL;
    device->poll = NULL;
    device->module = NULL;
    device->open = 0;
    device->link_state = 0; // down

    ec_device_clear_stats(device);

    for (i = 0; i < EC_TX_RING_SIZE; i++) {
        device->tx_skb[i]->dev = NULL;
    }
}

/*****************************************************************************/

/** Opens the EtherCAT device.
 *
 * \return 0 in case of success, else < 0
 */
int ec_device_open(
        ec_device_t *device /**< EtherCAT device */
        )
{
    int ret;

    if (!device->dev) {
        EC_MASTER_ERR(device->master, "No net_device to open!\n");
        return -ENODEV;
    }

    if (device->open) {
        EC_MASTER_WARN(device->master, "Device already opened!\n");
        return 0;
    }

    device->link_state = 0;

    ec_device_clear_stats(device);

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)
    ret = device->dev->netdev_ops->ndo_open(device->dev);
#else
    ret = device->dev->open(device->dev);
#endif
    if (!ret)
        device->open = 1;

    return ret;
}

/*****************************************************************************/

/** Stops the EtherCAT device.
 *
 * \return 0 in case of success, else < 0
 */
int ec_device_close(
        ec_device_t *device /**< EtherCAT device */
        )
{
    int ret;

    if (!device->dev) {
        EC_MASTER_ERR(device->master, "No device to close!\n");
        return -ENODEV;
    }

    if (!device->open) {
        EC_MASTER_WARN(device->master, "Device already closed!\n");
        return 0;
    }

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)
    ret = device->dev->netdev_ops->ndo_stop(device->dev);
#else
    ret = device->dev->stop(device->dev);
#endif
    if (!ret)
        device->open = 0;

    return ret;
}

/*****************************************************************************/

/** Returns a pointer to the device's transmit memory.
 *
 * \return pointer to the TX socket buffer
 */
uint8_t *ec_device_tx_data(
        ec_device_t *device /**< EtherCAT device */
        )
{
    /* cycle through socket buffers, because otherwise there is a race
     * condition, if multiple frames are sent and the DMA is not scheduled in
     * between. */
    device->tx_ring_index++;
    device->tx_ring_index %= EC_TX_RING_SIZE;
    return device->tx_skb[device->tx_ring_index]->data + ETH_HLEN;
}

/*****************************************************************************/

/** Sends the content of the transmit socket buffer.
 *
 * Cuts the socket buffer content to the (now known) size, and calls the
 * start_xmit() function of the assigned net_device.
 */
void ec_device_send(
        ec_device_t *device, /**< EtherCAT device */
        size_t size /**< number of bytes to send */
        )
{
    struct sk_buff *skb = device->tx_skb[device->tx_ring_index];

    // set the right length for the data
    skb->len = ETH_HLEN + size;

    if (unlikely(device->master->debug_level > 1)) {
        EC_MASTER_DBG(device->master, 2, "Sending frame:\n");
        ec_print_data(skb->data, ETH_HLEN + size);
    }

    // start sending
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)
    if (device->dev->netdev_ops->ndo_start_xmit(skb, device->dev) ==
            NETDEV_TX_OK)
#else
    if (device->dev->hard_start_xmit(skb, device->dev) == NETDEV_TX_OK)
#endif
    {
        device->tx_count++;
        device->master->device_stats.tx_count++;
        device->tx_bytes += ETH_HLEN + size;
        device->master->device_stats.tx_bytes += ETH_HLEN + size;
#ifdef EC_DEBUG_IF
        ec_debug_send(&device->dbg, skb->data, ETH_HLEN + size);
#endif
#ifdef EC_DEBUG_RING
        ec_device_debug_ring_append(
                device, TX, skb->data + ETH_HLEN, size);
#endif
    } else {
        device->tx_errors++;
    }
}

/*****************************************************************************/

/** Clears the frame statistics.
 */
void ec_device_clear_stats(
        ec_device_t *device /**< EtherCAT device */
        )
{
    unsigned int i;

    // zero frame statistics
    device->tx_count = 0;
    device->last_tx_count = 0;
    device->rx_count = 0;
    device->last_rx_count = 0;
    device->tx_bytes = 0;
    device->last_tx_bytes = 0;
    device->rx_bytes = 0;
    device->last_rx_bytes = 0;
    device->tx_errors = 0;

    for (i = 0; i < EC_RATE_COUNT; i++) {
        device->tx_frame_rates[i] = 0;
        device->rx_frame_rates[i] = 0;
        device->tx_byte_rates[i] = 0;
        device->rx_byte_rates[i] = 0;
    }
}

/*****************************************************************************/

#ifdef EC_DEBUG_RING
/** Appends frame data to the debug ring.
 */
void ec_device_debug_ring_append(
        ec_device_t *device, /**< EtherCAT device */
        ec_debug_frame_dir_t dir, /**< direction */
        const void *data, /**< frame data */
        size_t size /**< data size */
        )
{
    ec_debug_frame_t *df = &device->debug_frames[device->debug_frame_index];

    df->dir = dir;
    if (dir == TX) {
        do_gettimeofday(&df->t);
    }
    else {
        df->t = device->timeval_poll;
    }
    memcpy(df->data, data, size);
    df->data_size = size;

    device->debug_frame_index++;
    device->debug_frame_index %= EC_DEBUG_RING_SIZE;
    if (unlikely(device->debug_frame_count < EC_DEBUG_RING_SIZE))
        device->debug_frame_count++;
}

/*****************************************************************************/

/** Outputs the debug ring.
 */
void ec_device_debug_ring_print(
        const ec_device_t *device /**< EtherCAT device */
        )
{
    int i;
    unsigned int ring_index;
    const ec_debug_frame_t *df;
    struct timeval t0, diff;

    // calculate index of the newest frame in the ring to get its time
    ring_index = (device->debug_frame_index + EC_DEBUG_RING_SIZE - 1)
        % EC_DEBUG_RING_SIZE;
    t0 = device->debug_frames[ring_index].t;

    EC_MASTER_DBG(device->master, 1, "Debug ring %u:\n", ring_index);

    // calculate index of the oldest frame in the ring
    ring_index = (device->debug_frame_index + EC_DEBUG_RING_SIZE
            - device->debug_frame_count) % EC_DEBUG_RING_SIZE;

    for (i = 0; i < device->debug_frame_count; i++) {
        df = &device->debug_frames[ring_index];
        timersub(&t0, &df->t, &diff);

        EC_MASTER_DBG(device->master, 1, "Frame %u, dt=%u.%06u s, %s:\n",
                i + 1 - device->debug_frame_count,
                (unsigned int) diff.tv_sec,
                (unsigned int) diff.tv_usec,
                (df->dir == TX) ? "TX" : "RX");
        ec_print_data(df->data, df->data_size);

        ring_index++;
        ring_index %= EC_DEBUG_RING_SIZE;
    }
}
#endif

/*****************************************************************************/

/** Calls the poll function of the assigned net_device.
 *
 * The master itself works without using interrupts. Therefore the processing
 * of received data and status changes of the network device has to be
 * done by the master calling the ISR "manually".
 */
void ec_device_poll(
        ec_device_t *device /**< EtherCAT device */
        )
{
#ifdef EC_HAVE_CYCLES
    device->cycles_poll = get_cycles();
#endif
    device->jiffies_poll = jiffies;
#ifdef EC_DEBUG_RING
    do_gettimeofday(&device->timeval_poll);
#endif
    device->poll(device->dev);
}

/*****************************************************************************/

/** Update device statistics.
 */
void ec_device_update_stats(
        ec_device_t *device /**< EtherCAT device */
        )
{
    unsigned int i;

    s32 tx_frame_rate = (device->tx_count - device->last_tx_count) * 1000;
    s32 rx_frame_rate = (device->rx_count - device->last_rx_count) * 1000;
    s32 tx_byte_rate = (device->tx_bytes - device->last_tx_bytes);
    s32 rx_byte_rate = (device->rx_bytes - device->last_rx_bytes);

    /* Low-pass filter:
     *      Y_n = y_(n - 1) + T / tau * (x - y_(n - 1))   | T = 1
     *   -> Y_n += (x - y_(n - 1)) / tau
     */
    for (i = 0; i < EC_RATE_COUNT; i++) {
        s32 n = rate_intervals[i];
        device->tx_frame_rates[i] +=
            (tx_frame_rate - device->tx_frame_rates[i]) / n;
        device->rx_frame_rates[i] +=
            (rx_frame_rate - device->rx_frame_rates[i]) / n;
        device->tx_byte_rates[i] +=
            (tx_byte_rate - device->tx_byte_rates[i]) / n;
        device->rx_byte_rates[i] +=
            (rx_byte_rate - device->rx_byte_rates[i]) / n;
    }

    device->last_tx_count = device->tx_count;
    device->last_rx_count = device->rx_count;
    device->last_tx_bytes = device->tx_bytes;
    device->last_rx_bytes = device->rx_bytes;
}

/******************************************************************************
 *  Device interface
 *****************************************************************************/

/** Withdraws an EtherCAT device from the master.
 *
 * The device is disconnected from the master and all device ressources
 * are freed.
 *
 * \attention Before calling this function, the ecdev_stop() function has
 *            to be called, to be sure that the master does not use the device
 *            any more.
 * \ingroup DeviceInterface
 */
void ecdev_withdraw(ec_device_t *device /**< EtherCAT device */)
{
    ec_master_t *master = device->master;
    char dev_str[20], mac_str[20];

    ec_mac_print(device->dev->dev_addr, mac_str);

    if (device == &master->devices[EC_DEVICE_MAIN]) {
        sprintf(dev_str, "main");
    } else if (device == &master->devices[EC_DEVICE_BACKUP]) {
        sprintf(dev_str, "backup");
    } else {
        EC_MASTER_WARN(master, "%s() called with unknown device %s!\n",
                __func__, mac_str);
        sprintf(dev_str, "UNKNOWN");
    }

    EC_MASTER_INFO(master, "Releasing %s device %s.\n", dev_str, mac_str);

    down(&master->device_sem);
    ec_device_detach(device);
    up(&master->device_sem);
}

/*****************************************************************************/

/** Opens the network device and makes the master enter IDLE phase.
 *
 * \return 0 on success, else < 0
 * \ingroup DeviceInterface
 */
int ecdev_open(ec_device_t *device /**< EtherCAT device */)
{
    int ret;
    ec_master_t *master = device->master;
    unsigned int all_open = 1, dev_idx;

    ret = ec_device_open(device);
    if (ret) {
        EC_MASTER_ERR(master, "Failed to open device!\n");
        return ret;
    }

    for (dev_idx = EC_DEVICE_MAIN;
            dev_idx < ec_master_num_devices(device->master); dev_idx++) {
        if (!master->devices[dev_idx].open) {
            all_open = 0;
            break;
        }
    }

    if (all_open) {
        ret = ec_master_enter_idle_phase(device->master);
        if (ret) {
            EC_MASTER_ERR(device->master, "Failed to enter IDLE phase!\n");
            return ret;
        }
    }

    return 0;
}

/*****************************************************************************/

/** Makes the master leave IDLE phase and closes the network device.
 *
 * \return 0 on success, else < 0
 * \ingroup DeviceInterface
 */
void ecdev_close(ec_device_t *device /**< EtherCAT device */)
{
    ec_master_t *master = device->master;

    if (master->phase == EC_IDLE) {
        ec_master_leave_idle_phase(master);
    }

    if (ec_device_close(device)) {
        EC_MASTER_WARN(master, "Failed to close device!\n");
    }
}

/*****************************************************************************/

/** Accepts a received frame.
 *
 * Forwards the received data to the master. The master will analyze the frame
 * and dispatch the received commands to the sending instances.
 *
 * \ingroup DeviceInterface
 */
void ecdev_receive(
        ec_device_t *device, /**< EtherCAT device */
        const void *data, /**< pointer to received data */
        size_t size /**< number of bytes received */
        )
{
    const void *ec_data = data + ETH_HLEN;
    size_t ec_size = size - ETH_HLEN;

    if (unlikely(!data)) {
        EC_MASTER_WARN(device->master, "%s() called with NULL data.\n",
                __func__);
        return;
    }

    device->rx_count++;
    device->master->device_stats.rx_count++;
    device->rx_bytes += size;
    device->master->device_stats.rx_bytes += size;

    if (unlikely(device->master->debug_level > 1)) {
        EC_MASTER_DBG(device->master, 2, "Received frame:\n");
        ec_print_data(data, size);
    }

#ifdef EC_DEBUG_IF
    ec_debug_send(&device->dbg, data, size);
#endif
#ifdef EC_DEBUG_RING
    ec_device_debug_ring_append(device, RX, ec_data, ec_size);
#endif

    ec_master_receive_datagrams(device->master, ec_data, ec_size);
}

/*****************************************************************************/

/** Sets a new link state.
 *
 * If the device notifies the master about the link being down, the master
 * will not try to send frames using this device.
 *
 * \ingroup DeviceInterface
 */
void ecdev_set_link(
        ec_device_t *device, /**< EtherCAT device */
        uint8_t state /**< new link state */
        )
{
    if (unlikely(!device)) {
        EC_WARN("ecdev_set_link() called with null device!\n");
        return;
    }

    if (likely(state != device->link_state)) {
        device->link_state = state;
        EC_MASTER_INFO(device->master,
                "Link state of %s changed to %s.\n",
                device->dev->name, (state ? "UP" : "DOWN"));
    }
}

/*****************************************************************************/

/** Reads the link state.
 *
 * \ingroup DeviceInterface
 *
 * \return Link state.
 */
uint8_t ecdev_get_link(
        const ec_device_t *device /**< EtherCAT device */
        )
{
    if (unlikely(!device)) {
        EC_WARN("ecdev_get_link() called with null device!\n");
        return 0;
    }

    return device->link_state;
}

/*****************************************************************************/

/** \cond */

EXPORT_SYMBOL(ecdev_withdraw);
EXPORT_SYMBOL(ecdev_open);
EXPORT_SYMBOL(ecdev_close);
EXPORT_SYMBOL(ecdev_receive);
EXPORT_SYMBOL(ecdev_get_link);
EXPORT_SYMBOL(ecdev_set_link);

/** \endcond */

/*****************************************************************************/


<|start_filename|>3rdpart/ethercat-1.5.2/master/module.c<|end_filename|>
/******************************************************************************
 *
 *  $Id: module.c,v ec403cf308eb 2013/02/12 14:46:43 fp $
 *
 *  Copyright (C) 2006-2008  <NAME>, Ingenieurgemeinschaft IgH
 *
 *  This file is part of the IgH EtherCAT Master.
 *
 *  The IgH EtherCAT Master is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License version 2, as
 *  published by the Free Software Foundation.
 *
 *  The IgH EtherCAT Master is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 *  Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with the IgH EtherCAT Master; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 *****************************************************************************/

/** \file
 * EtherCAT master driver module.
 */

/*****************************************************************************/

#include <linux/module.h>
#include <linux/device.h>
#include <linux/err.h>

#include "globals.h"
#include "master.h"
#include "device.h"

/*****************************************************************************/

#define MAX_MASTERS 32 /**< Maximum number of masters. */

/*****************************************************************************/

int __init ec_init_module(void);
void __exit ec_cleanup_module(void);

static int ec_mac_parse(uint8_t *, const char *, int);

/*****************************************************************************/

static char *main_devices[MAX_MASTERS]; /**< Main devices parameter. */
static unsigned int master_count; /**< Number of masters. */
static char *backup_devices[MAX_MASTERS]; /**< Backup devices parameter. */
static unsigned int backup_count; /**< Number of backup devices. */
static unsigned int debug_level;  /**< Debug level parameter. */

static ec_master_t *masters; /**< Array of masters. */
static struct semaphore master_sem; /**< Master semaphore. */

dev_t device_number; /**< Device number for master cdevs. */
struct class *class; /**< Device class. */

static uint8_t macs[MAX_MASTERS][2][ETH_ALEN]; /**< MAC addresses. */

char *ec_master_version_str = EC_MASTER_VERSION; /**< Version string. */

/*****************************************************************************/

/** \cond */

MODULE_AUTHOR("<NAME> <<EMAIL>>");
MODULE_DESCRIPTION("EtherCAT master driver module");
MODULE_LICENSE("GPL");
MODULE_VERSION(EC_MASTER_VERSION);

module_param_array(main_devices, charp, &master_count, S_IRUGO);
MODULE_PARM_DESC(main_devices, "MAC addresses of main devices");
module_param_array(backup_devices, charp, &backup_count, S_IRUGO);
MODULE_PARM_DESC(backup_devices, "MAC addresses of backup devices");
module_param_named(debug_level, debug_level, uint, S_IRUGO);
MODULE_PARM_DESC(debug_level, "Debug level");

/** \endcond */

/*****************************************************************************/

/** Module initialization.
 *
 * Initializes \a master_count masters.
 * \return 0 on success, else < 0
 */
int __init ec_init_module(void)
{
    int i, ret = 0;

    EC_INFO("Master driver %s\n", EC_MASTER_VERSION);

    sema_init(&master_sem, 1);

    if (master_count) {
        if (alloc_chrdev_region(&device_number,
                    0, master_count, "EtherCAT")) {
            EC_ERR("Failed to obtain device number(s)!\n");
            ret = -EBUSY;
            goto out_return;
        }
    }

    class = class_create(THIS_MODULE, "EtherCAT");
    if (IS_ERR(class)) {
        EC_ERR("Failed to create device class.\n");
        ret = PTR_ERR(class);
        goto out_cdev;
    }

    // zero MAC addresses
    memset(macs, 0x00, sizeof(uint8_t) * MAX_MASTERS * 2 * ETH_ALEN);

    // process MAC parameters
    for (i = 0; i < master_count; i++) {
        ret = ec_mac_parse(macs[i][0], main_devices[i], 0);
        if (ret)
            goto out_class;

        if (i < backup_count) {
            ret = ec_mac_parse(macs[i][1], backup_devices[i], 1);
            if (ret)
                goto out_class;
        }
    }

    // initialize static master variables
    ec_master_init_static();

    if (master_count) {
        if (!(masters = kmalloc(sizeof(ec_master_t) * master_count,
                        GFP_KERNEL))) {
            EC_ERR("Failed to allocate memory"
                    " for EtherCAT masters.\n");
            ret = -ENOMEM;
            goto out_class;
        }
    }

    for (i = 0; i < master_count; i++) {
        ret = ec_master_init(&masters[i], i, macs[i][0], macs[i][1],
                    device_number, class, debug_level);
        if (ret)
            goto out_free_masters;
    }

    EC_INFO("%u master%s waiting for devices.\n",
            master_count, (master_count == 1 ? "" : "s"));
    return ret;

out_free_masters:
    for (i--; i >= 0; i--)
        ec_master_clear(&masters[i]);
    kfree(masters);
out_class:
    class_destroy(class);
out_cdev:
    if (master_count)
        unregister_chrdev_region(device_number, master_count);
out_return:
    return ret;
}

/*****************************************************************************/

/** Module cleanup.
 *
 * Clears all master instances.
 */
void __exit ec_cleanup_module(void)
{
    unsigned int i;

    for (i = 0; i < master_count; i++) {
        ec_master_clear(&masters[i]);
    }

    if (master_count)
        kfree(masters);

    class_destroy(class);

    if (master_count)
        unregister_chrdev_region(device_number, master_count);

    EC_INFO("Master module cleaned up.\n");
}

/*****************************************************************************/

/** Get the number of masters.
 */
unsigned int ec_master_count(void)
{
    return master_count;
}

/*****************************************************************************
 * MAC address functions
 ****************************************************************************/

/**
 * \return true, if two MAC addresses are equal.
 */
int ec_mac_equal(
        const uint8_t *mac1, /**< First MAC address. */
        const uint8_t *mac2 /**< Second MAC address. */
        )
{
    unsigned int i;

    for (i = 0; i < ETH_ALEN; i++)
        if (mac1[i] != mac2[i])
            return 0;

    return 1;
}

/*****************************************************************************/

/** Maximum MAC string size.
 */
#define EC_MAX_MAC_STRING_SIZE (3 * ETH_ALEN)

/** Print a MAC address to a buffer.
 *
 * The buffer size must be at least EC_MAX_MAC_STRING_SIZE.
 *
 * \return number of bytes written.
 */
ssize_t ec_mac_print(
        const uint8_t *mac, /**< MAC address */
        char *buffer /**< Target buffer. */
        )
{
    off_t off = 0;
    unsigned int i;

    for (i = 0; i < ETH_ALEN; i++) {
        off += sprintf(buffer + off, "%02X", mac[i]);
        if (i < ETH_ALEN - 1) off += sprintf(buffer + off, ":");
    }

    return off;
}

/*****************************************************************************/

/**
 * \return true, if the MAC address is all-zero.
 */
int ec_mac_is_zero(
        const uint8_t *mac /**< MAC address. */
        )
{
    unsigned int i;

    for (i = 0; i < ETH_ALEN; i++)
        if (mac[i])
            return 0;

    return 1;
}

/*****************************************************************************/

/**
 * \return true, if the given MAC address is the broadcast address.
 */
int ec_mac_is_broadcast(
        const uint8_t *mac /**< MAC address. */
        )
{
    unsigned int i;

    for (i = 0; i < ETH_ALEN; i++)
        if (mac[i] != 0xff)
            return 0;

    return 1;
}

/*****************************************************************************/

/** Parse a MAC address from a string.
 *
 * The MAC address must match the regular expression
 * "([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}".
 *
 * \return 0 on success, else < 0
 */
static int ec_mac_parse(uint8_t *mac, const char *src, int allow_empty)
{
    unsigned int i, value;
    const char *orig = src;
    char *rem;

    if (!strlen(src)) {
        if (allow_empty){
            return 0;
        } else {
            EC_ERR("MAC address may not be empty.\n");
            return -EINVAL;
        }
    }

    for (i = 0; i < ETH_ALEN; i++) {
        value = simple_strtoul(src, &rem, 16);
        if (rem != src + 2
                || value > 0xFF
                || (i < ETH_ALEN - 1 && *rem != ':')) {
            EC_ERR("Invalid MAC address \"%s\".\n", orig);
            return -EINVAL;
        }
        mac[i] = value;
        if (i < ETH_ALEN - 1) {
            src = rem + 1; // skip colon
        }
    }

    return 0;
}

/*****************************************************************************/

/** Outputs frame contents for debugging purposes.
 * If the data block is larger than 256 bytes, only the first 128
 * and the last 128 bytes will be shown
 */
void ec_print_data(const uint8_t *data, /**< pointer to data */
                   size_t size /**< number of bytes to output */
                   )
{
    unsigned int i;

    EC_DBG("");
    for (i = 0; i < size; i++) {
        printk("%02X ", data[i]);

        if ((i + 1) % 16 == 0 && i < size - 1) {
            printk("\n");
            EC_DBG("");
        }

        if (i + 1 == 128 && size > 256) {
            printk("dropped %zu bytes\n", size - 128 - i);
            i = size - 128;
            EC_DBG("");
        }
    }
    printk("\n");
}

/*****************************************************************************/

/** Outputs frame contents and differences for debugging purposes.
 */
void ec_print_data_diff(const uint8_t *d1, /**< first data */
                        const uint8_t *d2, /**< second data */
                        size_t size /** number of bytes to output */
                        )
{
    unsigned int i;

    EC_DBG("");
    for (i = 0; i < size; i++) {
        if (d1[i] == d2[i]) printk(".. ");
        else printk("%02X ", d2[i]);
        if ((i + 1) % 16 == 0) {
            printk("\n");
            EC_DBG("");
        }
    }
    printk("\n");
}

/*****************************************************************************/

/** Prints slave states in clear text.
 *
 * \return Size of the created string.
 */
size_t ec_state_string(uint8_t states, /**< slave states */
                       char *buffer, /**< target buffer
                                       (min. EC_STATE_STRING_SIZE bytes) */
                       uint8_t multi /**< Show multi-state mask. */
                       )
{
    off_t off = 0;
    unsigned int first = 1;

    if (!states) {
        off += sprintf(buffer + off, "(unknown)");
        return off;
    }

    if (multi) { // multiple slaves
        if (states & EC_SLAVE_STATE_INIT) {
            off += sprintf(buffer + off, "INIT");
            first = 0;
        }
        if (states & EC_SLAVE_STATE_PREOP) {
            if (!first) off += sprintf(buffer + off, ", ");
            off += sprintf(buffer + off, "PREOP");
            first = 0;
        }
        if (states & EC_SLAVE_STATE_SAFEOP) {
            if (!first) off += sprintf(buffer + off, ", ");
            off += sprintf(buffer + off, "SAFEOP");
            first = 0;
        }
        if (states & EC_SLAVE_STATE_OP) {
            if (!first) off += sprintf(buffer + off, ", ");
            off += sprintf(buffer + off, "OP");
        }
    } else { // single slave
        if ((states & EC_SLAVE_STATE_MASK) == EC_SLAVE_STATE_INIT) {
            off += sprintf(buffer + off, "INIT");
        } else if ((states & EC_SLAVE_STATE_MASK) == EC_SLAVE_STATE_PREOP) {
            off += sprintf(buffer + off, "PREOP");
        } else if ((states & EC_SLAVE_STATE_MASK) == EC_SLAVE_STATE_BOOT) {
            off += sprintf(buffer + off, "BOOT");
        } else if ((states & EC_SLAVE_STATE_MASK) == EC_SLAVE_STATE_SAFEOP) {
            off += sprintf(buffer + off, "SAFEOP");
        } else if ((states & EC_SLAVE_STATE_MASK) == EC_SLAVE_STATE_OP) {
            off += sprintf(buffer + off, "OP");
        } else {
            off += sprintf(buffer + off, "(invalid)");
        }
        first = 0;
    }

    if (states & EC_SLAVE_STATE_ACK_ERR) {
        if (!first) off += sprintf(buffer + off, " + ");
        off += sprintf(buffer + off, "ERROR");
    }

    return off;
}

/******************************************************************************
 *  Device interface
 *****************************************************************************/

/** Device names.
 */
const char *ec_device_names[2] = {
    "main",
    "backup"
};

/** Offers an EtherCAT device to a certain master.
 *
 * The master decides, if it wants to use the device for EtherCAT operation,
 * or not. It is important, that the offered net_device is not used by the
 * kernel IP stack. If the master, accepted the offer, the address of the
 * newly created EtherCAT device is returned, else \a NULL is returned.
 *
 * \return Pointer to device, if accepted, or NULL if declined.
 * \ingroup DeviceInterface
 */
ec_device_t *ecdev_offer(
        struct net_device *net_dev, /**< net_device to offer */
        ec_pollfunc_t poll, /**< device poll function */
        struct module *module /**< pointer to the module */
        )
{
    ec_master_t *master;
    char str[EC_MAX_MAC_STRING_SIZE];
    unsigned int i, dev_idx;

    for (i = 0; i < master_count; i++) {
        master = &masters[i];
        ec_mac_print(net_dev->dev_addr, str);

        if (down_interruptible(&master->device_sem)) {
            EC_MASTER_WARN(master, "%s() interrupted!\n", __func__);
            return NULL;
        }

        for (dev_idx = EC_DEVICE_MAIN;
                dev_idx < ec_master_num_devices(master); dev_idx++) {
            if (!master->devices[dev_idx].dev
                && (ec_mac_equal(master->macs[dev_idx], net_dev->dev_addr)
                    || ec_mac_is_broadcast(master->macs[dev_idx]))) {

                EC_INFO("Accepting %s as %s device for master %u.\n",
                        str, ec_device_names[dev_idx != 0], master->index);

                ec_device_attach(&master->devices[dev_idx],
                        net_dev, poll, module);
                up(&master->device_sem);

                snprintf(net_dev->name, IFNAMSIZ, "ec%c%u",
                        ec_device_names[dev_idx != 0][0], master->index);

                return &master->devices[dev_idx]; // offer accepted
            }
        }

        up(&master->device_sem);

        EC_MASTER_DBG(master, 1, "Master declined device %s.\n", str);
    }

    return NULL; // offer declined
}

/******************************************************************************
 * Application interface
 *****************************************************************************/

/** Request a master.
 *
 * Same as ecrt_request_master(), but with ERR_PTR() return value.
 *
 * \return Requested master.
 */
ec_master_t *ecrt_request_master_err(
        unsigned int master_index /**< Master index. */
        )
{
    ec_master_t *master, *errptr = NULL;
    unsigned int dev_idx = EC_DEVICE_MAIN;

    EC_INFO("Requesting master %u...\n", master_index);

    if (master_index >= master_count) {
        EC_ERR("Invalid master index %u.\n", master_index);
        errptr = ERR_PTR(-EINVAL);
        goto out_return;
    }
    master = &masters[master_index];

    if (down_interruptible(&master_sem)) {
        errptr = ERR_PTR(-EINTR);
        goto out_return;
    }

    if (master->reserved) {
        up(&master_sem);
        EC_MASTER_ERR(master, "Master already in use!\n");
        errptr = ERR_PTR(-EBUSY);
        goto out_return;
    }
    master->reserved = 1;
    up(&master_sem);

    if (down_interruptible(&master->device_sem)) {
        errptr = ERR_PTR(-EINTR);
        goto out_release;
    }

    if (master->phase != EC_IDLE) {
        up(&master->device_sem);
        EC_MASTER_ERR(master, "Master still waiting for devices!\n");
        errptr = ERR_PTR(-ENODEV);
        goto out_release;
    }

    for (; dev_idx < ec_master_num_devices(master); dev_idx++) {
        ec_device_t *device = &master->devices[dev_idx];
        if (!try_module_get(device->module)) {
            up(&master->device_sem);
            EC_MASTER_ERR(master, "Device module is unloading!\n");
            errptr = ERR_PTR(-ENODEV);
            goto out_module_put;
        }
    }

    up(&master->device_sem);

    if (ec_master_enter_operation_phase(master)) {
        EC_MASTER_ERR(master, "Failed to enter OPERATION phase!\n");
        errptr = ERR_PTR(-EIO);
        goto out_module_put;
    }

    EC_INFO("Successfully requested master %u.\n", master_index);
    return master;

 out_module_put:
    for (; dev_idx > 0; dev_idx--) {
        ec_device_t *device = &master->devices[dev_idx - 1];
        module_put(device->module);
    }
 out_release:
    master->reserved = 0;
 out_return:
    return errptr;
}

/*****************************************************************************/

ec_master_t *ecrt_request_master(unsigned int master_index)
{
    ec_master_t *master = ecrt_request_master_err(master_index);
    return IS_ERR(master) ? NULL : master;
}

/*****************************************************************************/

void ecrt_release_master(ec_master_t *master)
{
    unsigned int dev_idx;

    EC_MASTER_INFO(master, "Releasing master...\n");

    if (!master->reserved) {
        EC_MASTER_WARN(master, "%s(): Master was was not requested!\n",
                __func__);
        return;
    }

    ec_master_leave_operation_phase(master);

    for (dev_idx = EC_DEVICE_MAIN; dev_idx < ec_master_num_devices(master);
            dev_idx++) {
        module_put(master->devices[dev_idx].module);
    }

    master->reserved = 0;

    EC_MASTER_INFO(master, "Released.\n");
}

/*****************************************************************************/

unsigned int ecrt_version_magic(void)
{
    return ECRT_VERSION_MAGIC;
}

/*****************************************************************************/

/** Global request state type translation table.
 *
 * Translates an internal request state to an external one.
 */
const ec_request_state_t ec_request_state_translation_table[] = {
    EC_REQUEST_UNUSED,  // EC_INT_REQUEST_INIT,
    EC_REQUEST_BUSY,    // EC_INT_REQUEST_QUEUED,
    EC_REQUEST_BUSY,    // EC_INT_REQUEST_BUSY,
    EC_REQUEST_SUCCESS, // EC_INT_REQUEST_SUCCESS,
    EC_REQUEST_ERROR    // EC_INT_REQUEST_FAILURE
};

/*****************************************************************************/

/** \cond */

module_init(ec_init_module);
module_exit(ec_cleanup_module);

EXPORT_SYMBOL(ecdev_offer);

EXPORT_SYMBOL(ecrt_request_master);
EXPORT_SYMBOL(ecrt_release_master);
EXPORT_SYMBOL(ecrt_version_magic);

/** \endcond */

/*****************************************************************************/


<|start_filename|>kernel/modules/virtual_serial/vser.h<|end_filename|>
#pragma once

struct option
{
    unsigned int datab;
    unsigned int parity;
    unsigned int stopb;
};

#define VS_MAGIC 's'

#define VS_SET_BAUD _IOW(VS_MAGIC, 0, unsigned int)
#define VS_GET_BAUD _IOR(VS_MAGIC, 1, unsigned int)
#define VS_SET_FMT _IOW(VS_MAGIC, 2, struct option)
#define VS_GET_FMT _IOR(VS_MAGIC, 3, struct option)


<|start_filename|>3rdpart/tslib-1.15/plugins/mk712-raw.c<|end_filename|>
/*
 * SPDX-License-Identifier: LGPL-2.1
 */
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>

#include "config.h"
#include "tslib-private.h"

struct mk712_ts_event { /* Used in the Hitachi Webpad */
	unsigned int header;
	unsigned int x;
	unsigned int y;
	unsigned int reserved;
};

static int mk712_read(struct tslib_module_info *inf, struct ts_sample *samp,
		      int nr)
{
	struct tsdev *ts = inf->dev;
	struct mk712_ts_event *mk712_evt;
	int ret;
	int nr_read;

	mk712_evt = alloca(sizeof(*mk712_evt) * nr);
	ret = read(ts->fd, mk712_evt, sizeof(*mk712_evt) * nr);
	if (ret > 0) {
		nr_read = ret / sizeof(*mk712_evt);
		while (ret >= (int)sizeof(*mk712_evt)) {
			samp->x = (short)mk712_evt->x;
			samp->y = (short)mk712_evt->y;
			if (mk712_evt->header == 0)
				samp->pressure = 1;
			else
				samp->pressure = 0;
#ifdef DEBUG
	fprintf(stderr, "RAW---------------------------> %d %d %d\n",
		samp->x, samp->y, samp->pressure);
#endif /*DEBUG*/
			gettimeofday(&samp->tv, NULL);
			samp++;
			mk712_evt++;
			ret -= sizeof(*mk712_evt);
		}
	} else {
		return -1;
	}

	ret = nr_read;
	return ret;
}

static const struct tslib_ops mk712_ops = {
	.read	= mk712_read,
};

TSAPI struct tslib_module_info *mk712_mod_init(__attribute__ ((unused)) struct tsdev *dev,
					       __attribute__ ((unused))const char *params)
{
	struct tslib_module_info *m;

	m = malloc(sizeof(struct tslib_module_info));
	if (m == NULL)
		return NULL;

	m->ops = &mk712_ops;
	return m;
}

#ifndef TSLIB_STATIC_MK712_MODULE
	TSLIB_MODULE_INIT(mk712_mod_init);
#endif


<|start_filename|>3rdpart/ethercat-1.5.2/tool/CommandData.cpp<|end_filename|>
/*****************************************************************************
 *
 *  $Id: CommandData.cpp,v d461b1f07296 2012/11/30 19:15:31 fp $
 *
 *  Copyright (C) 2006-2009  <NAME>, Ingenieurgemeinschaft IgH
 *
 *  This file is part of the IgH EtherCAT Master.
 *
 *  The IgH EtherCAT Master is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License version 2, as
 *  published by the Free Software Foundation.
 *
 *  The IgH EtherCAT Master is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 *  Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with the IgH EtherCAT Master; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 *  vim: expandtab
 *
 ****************************************************************************/

#include <iostream>
using namespace std;

#include "CommandData.h"
#include "MasterDevice.h"

/*****************************************************************************/

CommandData::CommandData():
    Command("data", "Output binary domain process data.")
{
}

/*****************************************************************************/

string CommandData::helpString(const string &binaryBaseName) const
{
    stringstream str;

    str << binaryBaseName << " " << getName() << " [OPTIONS]" << endl
        << endl
        << getBriefDescription() << endl
        << endl
        << "Data of multiple domains are concatenated." << endl
        << endl
        << "Command-specific options:" << endl
        << "  --domain -d <index>  Positive numerical domain index." << endl
        << "                       If omitted, data of all domains" << endl
        << "                       are output." << endl
        << endl
        << numericInfo();

    return str.str();
}

/****************************************************************************/

void CommandData::execute(const StringVector &args)
{
    MasterIndexList masterIndices;
    DomainList domains;
    DomainList::const_iterator di;

    if (args.size()) {
        stringstream err;
        err << "'" << getName() << "' takes no arguments!";
        throwInvalidUsageException(err);
    }

    masterIndices = getMasterIndices();
    MasterIndexList::const_iterator mi;
    for (mi = masterIndices.begin();
            mi != masterIndices.end(); mi++) {
        ec_ioctl_master_t io;
        MasterDevice m(*mi);
        m.open(MasterDevice::Read);
        m.getMaster(&io);

        domains = selectedDomains(m, io);

        for (di = domains.begin(); di != domains.end(); di++) {
            outputDomainData(m, *di);
        }
    }
}

/****************************************************************************/

void CommandData::outputDomainData(
        MasterDevice &m,
        const ec_ioctl_domain_t &domain
        )
{
    ec_ioctl_domain_data_t data;
    unsigned char *processData;
    unsigned int i;

    if (!domain.data_size)
        return;

    processData = new unsigned char[domain.data_size];

    try {
        m.getData(&data, domain.index, domain.data_size, processData);
    } catch (MasterDeviceException &e) {
        delete [] processData;
        throw e;
    }

    for (i = 0; i < data.data_size; i++)
        cout << processData[i];
    cout.flush();

    delete [] processData;
}

/****************************************************************************/


<|start_filename|>3rdpart/ethercat-1.5.2/tool/main.cpp<|end_filename|>
/*****************************************************************************
 *
 *  $Id: main.cpp,v 960cc1bb6b4a 2012/10/24 16:21:52 fp $
 *
 *  Copyright (C) 2006-2009  <NAME>, Ingenieurgemeinschaft IgH
 *
 *  This file is part of the IgH EtherCAT Master.
 *
 *  The IgH EtherCAT Master is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License version 2, as
 *  published by the Free Software Foundation.
 *
 *  The IgH EtherCAT Master is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 *  Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with the IgH EtherCAT Master; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 ****************************************************************************/

#include <getopt.h>
#include <libgen.h> // basename()
#include <stdlib.h>

#include <iostream>
#include <iomanip>
using namespace std;

#include "CommandAlias.h"
#include "CommandConfig.h"
#include "CommandCStruct.h"
#include "CommandData.h"
#include "CommandDebug.h"
#include "CommandDomains.h"
#include "CommandDownload.h"
#ifdef EC_EOE
# include "CommandEoe.h"
#endif
#include "CommandFoeRead.h"
#include "CommandFoeWrite.h"
#include "CommandGraph.h"
#include "CommandMaster.h"
#include "CommandPdos.h"
#include "CommandRegRead.h"
#include "CommandRegWrite.h"
#include "CommandRescan.h"
#include "CommandSdos.h"
#include "CommandSiiRead.h"
#include "CommandSiiWrite.h"
#include "CommandSlaves.h"
#include "CommandSoeRead.h"
#include "CommandSoeWrite.h"
#include "CommandStates.h"
#include "CommandUpload.h"
#include "CommandVersion.h"
#include "CommandXml.h"

#include "MasterDevice.h"

/*****************************************************************************/

typedef list<Command *> CommandList;
CommandList commandList;

string binaryBaseName;
string commandName;
Command::StringVector commandArgs;

// option variables
string masters = "-"; // all masters
string positions = "-"; // all positions
string aliases = "-"; // all aliases
string domains = "-"; // all domains
string dataTypeStr;
Command::Verbosity verbosity = Command::Normal;
bool force = false;
bool helpRequested = false;
string outputFile;
string skin;

/*****************************************************************************/

string usage()
{
    stringstream str;
    CommandList::const_iterator ci;
    size_t maxWidth = 0;

    for (ci = commandList.begin(); ci != commandList.end(); ci++) {
        if ((*ci)->getName().length() > maxWidth) {
            maxWidth = (*ci)->getName().length();
        }
    }

    str << "Usage: " << binaryBaseName << " <COMMAND> [OPTIONS] [ARGUMENTS]"
        << endl << endl
        << "Commands (can be abbreviated):" << endl;

    str << left;
    for (ci = commandList.begin(); ci != commandList.end(); ci++) {
        str << "  " << setw(maxWidth) << (*ci)->getName()
            << "  " << (*ci)->getBriefDescription() << endl;
    }

    str << endl
        << "Global options:" << endl
        << "  --master  -m <master>  Comma separated list of masters" << endl
        << "                         to select, ranges are allowed." << endl
        << "                         Examples: '1,3', '5-7,9', '-3'." << endl
        << "                         Default: '-' (all)."
        << endl
        << "  --force   -f           Force a command." << endl
        << "  --quiet   -q           Output less information." << endl
        << "  --verbose -v           Output more information." << endl
        << "  --help    -h           Show this help." << endl
        << endl
        << Command::numericInfo()
        << endl
        << "Call '" << binaryBaseName
        << " <COMMAND> --help' for command-specific help." << endl
        << endl
        << "Send bug reports to " << PACKAGE_BUGREPORT << "." << endl;

    return str.str();
}

/*****************************************************************************/

void getOptions(int argc, char **argv)
{
    int c, argCount;
    stringstream str;

    static struct option longOptions[] = {
        //name,         has_arg,           flag, val
        {"master",      required_argument, NULL, 'm'},
        {"alias",       required_argument, NULL, 'a'},
        {"position",    required_argument, NULL, 'p'},
        {"domain",      required_argument, NULL, 'd'},
        {"type",        required_argument, NULL, 't'},
        {"output-file", required_argument, NULL, 'o'},
        {"skin",        required_argument, NULL, 's'},
        {"force",       no_argument,       NULL, 'f'},
        {"quiet",       no_argument,       NULL, 'q'},
        {"verbose",     no_argument,       NULL, 'v'},
        {"help",        no_argument,       NULL, 'h'},
        {}
    };

    do {
        c = getopt_long(argc, argv, "m:a:p:d:t:o:s:fqvh", longOptions, NULL);

        switch (c) {
            case 'm':
                masters = optarg;
                break;

            case 'a':
                aliases = optarg;
                break;

            case 'p':
                positions = optarg;
                break;

            case 'd':
                domains = optarg;
                break;

            case 't':
                dataTypeStr = optarg;
                break;

            case 'o':
                outputFile = optarg;
                break;

            case 's':
                skin = optarg;
                break;

            case 'f':
                force = true;
                break;

            case 'q':
                verbosity = Command::Quiet;
                break;

            case 'v':
                verbosity = Command::Verbose;
                break;

            case 'h':
                helpRequested = true;
                break;

            case '?':
                cerr << endl << usage();
                exit(1);

            default:
                break;
        }
    }
    while (c != -1);

    argCount = argc - optind;

    if (!argCount) {
        if (helpRequested) {
            cout << usage();
            exit(0);
        } else {
            cerr << "Please specify a command!" << endl
                << endl << usage();
            exit(1);
        }
    }

    commandName = argv[optind];
    while (++optind < argc)
        commandArgs.push_back(string(argv[optind]));
}

/****************************************************************************/

list<Command *> getMatchingCommands(const string &cmdStr)
{
    CommandList::iterator ci;
    list<Command *> res;

    // find matching commands from beginning of the string
    for (ci = commandList.begin(); ci != commandList.end(); ci++) {
        if ((*ci)->matchesSubstr(cmdStr)) {
            res.push_back(*ci);
        }
    }

    if (!res.size()) { // nothing found
        // find /any/ matching commands
        for (ci = commandList.begin(); ci != commandList.end(); ci++) {
            if ((*ci)->matchesAbbrev(cmdStr)) {
                res.push_back(*ci);
            }
        }
    }

    return res;
}

/****************************************************************************/

int main(int argc, char **argv)
{
    int retval = 0;
    list<Command *> matchingCommands;
    list<Command *>::const_iterator ci;
    Command *cmd;

    binaryBaseName = basename(argv[0]);

    commandList.push_back(new CommandAlias());
    commandList.push_back(new CommandConfig());
    commandList.push_back(new CommandCStruct());
    commandList.push_back(new CommandData());
    commandList.push_back(new CommandDebug());
    commandList.push_back(new CommandDomains());
    commandList.push_back(new CommandDownload());
#ifdef EC_EOE
    commandList.push_back(new CommandEoe());
#endif
    commandList.push_back(new CommandFoeRead());
    commandList.push_back(new CommandFoeWrite());
    commandList.push_back(new CommandGraph());
    commandList.push_back(new CommandMaster());
    commandList.push_back(new CommandPdos());
    commandList.push_back(new CommandRegRead());
    commandList.push_back(new CommandRegWrite());
    commandList.push_back(new CommandRescan());
    commandList.push_back(new CommandSdos());
    commandList.push_back(new CommandSiiRead());
    commandList.push_back(new CommandSiiWrite());
    commandList.push_back(new CommandSlaves());
    commandList.push_back(new CommandSoeRead());
    commandList.push_back(new CommandSoeWrite());
    commandList.push_back(new CommandStates());
    commandList.push_back(new CommandUpload());
    commandList.push_back(new CommandVersion());
    commandList.push_back(new CommandXml());

    getOptions(argc, argv);

    matchingCommands = getMatchingCommands(commandName);

    if (matchingCommands.size()) {
        if (matchingCommands.size() == 1) {
            cmd = matchingCommands.front();
            if (!helpRequested) {
                try {
                    cmd->setMasters(masters);
                    cmd->setVerbosity(verbosity);
                    cmd->setAliases(aliases);
                    cmd->setPositions(positions);
                    cmd->setDomains(domains);
                    cmd->setDataType(dataTypeStr);
                    cmd->setOutputFile(outputFile);
                    cmd->setSkin(skin);
                    cmd->setForce(force);
                    cmd->execute(commandArgs);
                } catch (InvalidUsageException &e) {
                    cerr << e.what() << endl << endl;
                    cerr << cmd->helpString(binaryBaseName);
                    retval = 1;
                } catch (CommandException &e) {
                    cerr << e.what() << endl;
                    retval = 1;
                } catch (MasterDeviceException &e) {
                    cerr << e.what() << endl;
                    retval = 1;
                }
            } else {
                cout << cmd->helpString(binaryBaseName);
            }
        } else {
            cerr << "Ambiguous command abbreviation! Matching:" << endl;
            for (ci = matchingCommands.begin();
                    ci != matchingCommands.end();
                    ci++) {
                cerr << (*ci)->getName() << endl;
            }
            cerr << endl << usage();
            retval = 1;
        }
    } else {
        cerr << "Unknown command " << commandName << "!" << endl
            << endl << usage();
        retval = 1;
    }

    return retval;
}

/****************************************************************************/


<|start_filename|>3rdpart/ethercat-1.5.2/devices/generic.c<|end_filename|>
/******************************************************************************
 *
 *  $Id: generic.c,v e69a5010914f 2011/12/14 15:47:28 fp $
 *
 *  Copyright (C) 2006-2008  <NAME>, Ingenieurgemeinschaft IgH
 *
 *  This file is part of the IgH EtherCAT Master.
 *
 *  The IgH EtherCAT Master is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License version 2, as
 *  published by the Free Software Foundation.
 *
 *  The IgH EtherCAT Master is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 *  Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with the IgH EtherCAT Master; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 *****************************************************************************/

/** \file
 * EtherCAT generic Ethernet device module.
 */

/*****************************************************************************/

#include <linux/module.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/version.h>
#include <linux/if_arp.h> /* ARPHRD_ETHER */
#include <linux/etherdevice.h>

#include "../globals.h"
#include "ecdev.h"

#define PFX "ec_generic: "

#define ETH_P_ETHERCAT 0x88A4

#define EC_GEN_RX_BUF_SIZE 1600

/*****************************************************************************/

int __init ec_gen_init_module(void);
void __exit ec_gen_cleanup_module(void);

/*****************************************************************************/

/** \cond */

MODULE_AUTHOR("<NAME> <<EMAIL>>");
MODULE_DESCRIPTION("EtherCAT master generic Ethernet device module");
MODULE_LICENSE("GPL");
MODULE_VERSION(EC_MASTER_VERSION);

/** \endcond */

struct list_head generic_devices;

typedef struct {
    struct list_head list;
    struct net_device *netdev;
    struct net_device *used_netdev;
    struct socket *socket;
    ec_device_t *ecdev;
    uint8_t *rx_buf;
} ec_gen_device_t;

typedef struct {
    struct list_head list;
    struct net_device *netdev;
    char name[IFNAMSIZ];
    int ifindex;
    uint8_t dev_addr[ETH_ALEN];
} ec_gen_interface_desc_t;

int ec_gen_device_open(ec_gen_device_t *);
int ec_gen_device_stop(ec_gen_device_t *);
int ec_gen_device_start_xmit(ec_gen_device_t *, struct sk_buff *);
void ec_gen_device_poll(ec_gen_device_t *);

/*****************************************************************************/

static int ec_gen_netdev_open(struct net_device *dev)
{
    ec_gen_device_t *gendev = *((ec_gen_device_t **) netdev_priv(dev));
    return ec_gen_device_open(gendev);
}

/*****************************************************************************/

static int ec_gen_netdev_stop(struct net_device *dev)
{
    ec_gen_device_t *gendev = *((ec_gen_device_t **) netdev_priv(dev));
    return ec_gen_device_stop(gendev);
}

/*****************************************************************************/

static int ec_gen_netdev_start_xmit(
        struct sk_buff *skb,
        struct net_device *dev
        )
{
    ec_gen_device_t *gendev = *((ec_gen_device_t **) netdev_priv(dev));
    return ec_gen_device_start_xmit(gendev, skb);
}

/*****************************************************************************/

void ec_gen_poll(struct net_device *dev)
{
    ec_gen_device_t *gendev = *((ec_gen_device_t **) netdev_priv(dev));
    ec_gen_device_poll(gendev);
}

/*****************************************************************************/

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)
static const struct net_device_ops ec_gen_netdev_ops = {
    .ndo_open       = ec_gen_netdev_open,
    .ndo_stop       = ec_gen_netdev_stop,
    .ndo_start_xmit = ec_gen_netdev_start_xmit,
};
#endif

/*****************************************************************************/

/** Init generic device.
 */
int ec_gen_device_init(
        ec_gen_device_t *dev
        )
{
    ec_gen_device_t **priv;
    char null = 0x00;

    dev->ecdev = NULL;
    dev->socket = NULL;
    dev->rx_buf = NULL;

    dev->netdev = alloc_netdev(sizeof(ec_gen_device_t *), &null, NET_NAME_UNKNOWN, ether_setup);
    if (!dev->netdev) {
        return -ENOMEM;
    }

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)
    dev->netdev->netdev_ops = &ec_gen_netdev_ops;
#else
    dev->netdev->open = ec_gen_netdev_open;
    dev->netdev->stop = ec_gen_netdev_stop;
    dev->netdev->hard_start_xmit = ec_gen_netdev_start_xmit;
#endif

    priv = netdev_priv(dev->netdev);
    *priv = dev;

    return 0;
}

/*****************************************************************************/

/** Clear generic device.
 */
void ec_gen_device_clear(
        ec_gen_device_t *dev
        )
{
    if (dev->ecdev) {
        ecdev_close(dev->ecdev);
        ecdev_withdraw(dev->ecdev);
    }
    if (dev->socket) {
        sock_release(dev->socket);
    }
    free_netdev(dev->netdev);

    if (dev->rx_buf) {
        kfree(dev->rx_buf);
    }
}

/*****************************************************************************/

/** Creates a network socket.
 */
int ec_gen_device_create_socket(
        ec_gen_device_t *dev,
        ec_gen_interface_desc_t *desc
        )
{
    int ret;
    struct sockaddr_ll sa;

    dev->rx_buf = kmalloc(EC_GEN_RX_BUF_SIZE, GFP_KERNEL);
    if (!dev->rx_buf) {
        return -ENOMEM;
    }

    ret = sock_create_kern(&init_net, PF_PACKET, SOCK_RAW, htons(ETH_P_ETHERCAT),
            &dev->socket);
    if (ret) {
        printk(KERN_ERR PFX "Failed to create socket (ret = %i).\n", ret);
        return ret;
    }

    printk(KERN_ERR PFX "Binding socket to interface %i (%s).\n",
            desc->ifindex, desc->name);

    memset(&sa, 0x00, sizeof(sa));
    sa.sll_family = AF_PACKET;
    sa.sll_protocol = htons(ETH_P_ETHERCAT);
    sa.sll_ifindex = desc->ifindex;
    ret = kernel_bind(dev->socket, (struct sockaddr *) &sa, sizeof(sa));
    if (ret) {
        printk(KERN_ERR PFX "Failed to bind() socket to interface"
                " (ret = %i).\n", ret);
        sock_release(dev->socket);
        dev->socket = NULL;
        return ret;
    }

    return 0;
}

/*****************************************************************************/

/** Offer generic device to master.
 */
int ec_gen_device_offer(
        ec_gen_device_t *dev,
        ec_gen_interface_desc_t *desc
        )
{
    int ret = 0;

    dev->used_netdev = desc->netdev;
    memcpy(dev->netdev->dev_addr, desc->dev_addr, ETH_ALEN);

    dev->ecdev = ecdev_offer(dev->netdev, ec_gen_poll, THIS_MODULE);
    if (dev->ecdev) {
        if (ec_gen_device_create_socket(dev, desc)) {
            ecdev_withdraw(dev->ecdev);
            dev->ecdev = NULL;
        } else if (ecdev_open(dev->ecdev)) {
            ecdev_withdraw(dev->ecdev);
            dev->ecdev = NULL;
        } else {
            ecdev_set_link(dev->ecdev, netif_carrier_ok(dev->used_netdev)); // FIXME
            ret = 1;
        }
    }

    return ret;
}

/*****************************************************************************/

/** Open the device.
 */
int ec_gen_device_open(
        ec_gen_device_t *dev
        )
{
    return 0;
}

/*****************************************************************************/

/** Stop the device.
 */
int ec_gen_device_stop(
        ec_gen_device_t *dev
        )
{
    return 0;
}

/*****************************************************************************/

int ec_gen_device_start_xmit(
        ec_gen_device_t *dev,
        struct sk_buff *skb
        )
{
    struct msghdr msg;
    struct kvec iov;
    size_t len = skb->len;
    int ret;

    ecdev_set_link(dev->ecdev, netif_carrier_ok(dev->used_netdev));

    iov.iov_base = skb->data;
    iov.iov_len = len;
    memset(&msg, 0, sizeof(msg));

    ret = kernel_sendmsg(dev->socket, &msg, &iov, 1, len);

    return ret == len ? NETDEV_TX_OK : NETDEV_TX_BUSY;
}

/*****************************************************************************/

/** Polls the device.
 */
void ec_gen_device_poll(
        ec_gen_device_t *dev
        )
{
    struct msghdr msg;
    struct kvec iov;
    int ret, budget = 10; // FIXME

    ecdev_set_link(dev->ecdev, netif_carrier_ok(dev->used_netdev));

    do {
        iov.iov_base = dev->rx_buf;
        iov.iov_len = EC_GEN_RX_BUF_SIZE;
        memset(&msg, 0, sizeof(msg));

        ret = kernel_recvmsg(dev->socket, &msg, &iov, 1, iov.iov_len,
                MSG_DONTWAIT);
        if (ret > 0) {
            ecdev_receive(dev->ecdev, dev->rx_buf, ret);
        } else if (ret < 0) {
            break;
        }
        budget--;
    } while (budget);
}

/*****************************************************************************/

/** Offer device.
 */
int offer_device(
        ec_gen_interface_desc_t *desc
        )
{
    ec_gen_device_t *gendev;
    int ret = 0;

    gendev = kmalloc(sizeof(ec_gen_device_t), GFP_KERNEL);
    if (!gendev) {
        return -ENOMEM;
    }

    ret = ec_gen_device_init(gendev);
    if (ret) {
        kfree(gendev);
        return ret;
    }

    if (ec_gen_device_offer(gendev, desc)) {
        list_add_tail(&gendev->list, &generic_devices);
    } else {
        ec_gen_device_clear(gendev);
        kfree(gendev);
    }

    return ret;
}

/*****************************************************************************/

/** Clear devices.
 */
void clear_devices(void)
{
    ec_gen_device_t *gendev, *next;

    list_for_each_entry_safe(gendev, next, &generic_devices, list) {
        list_del(&gendev->list);
        ec_gen_device_clear(gendev);
        kfree(gendev);
    }
}

/*****************************************************************************/

/** Module initialization.
 *
 * Initializes \a master_count masters.
 * \return 0 on success, else < 0
 */
int __init ec_gen_init_module(void)
{
    int ret = 0;
    struct list_head descs;
    struct net_device *netdev;
    ec_gen_interface_desc_t *desc, *next;

    printk(KERN_INFO PFX "EtherCAT master generic Ethernet device module %s\n",
            EC_MASTER_VERSION);

    INIT_LIST_HEAD(&generic_devices);
    INIT_LIST_HEAD(&descs);

    read_lock(&dev_base_lock);
    for_each_netdev(&init_net, netdev) {
        if (netdev->type != ARPHRD_ETHER)
            continue;
        desc = kmalloc(sizeof(ec_gen_interface_desc_t), GFP_ATOMIC);
        if (!desc) {
            ret = -ENOMEM;
            read_unlock(&dev_base_lock);
            goto out_err;
        }
        strncpy(desc->name, netdev->name, IFNAMSIZ);
        desc->netdev = netdev;
        desc->ifindex = netdev->ifindex;
        memcpy(desc->dev_addr, netdev->dev_addr, ETH_ALEN);
        list_add_tail(&desc->list, &descs);
    }
    read_unlock(&dev_base_lock);

    list_for_each_entry_safe(desc, next, &descs, list) {
        ret = offer_device(desc);
        if (ret) {
            goto out_err;
        }
        kfree(desc);
    }
    return ret;

out_err:
    list_for_each_entry_safe(desc, next, &descs, list) {
        list_del(&desc->list);
        kfree(desc);
    }
    clear_devices();
    return ret;
}

/*****************************************************************************/

/** Module cleanup.
 *
 * Clears all master instances.
 */
void __exit ec_gen_cleanup_module(void)
{
    clear_devices();
    printk(KERN_INFO PFX "Unloading.\n");
}

/*****************************************************************************/

/** \cond */

module_init(ec_gen_init_module);
module_exit(ec_gen_cleanup_module);

/** \endcond */

/*****************************************************************************/


<|start_filename|>3rdpart/tslib-1.15/config.h<|end_filename|>
/* config.h.  Generated from config.h.in by configure.  */
/* config.h.in.  Generated from configure.ac by autoheader.  */

/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
   systems. This function is required for `alloca.c' support on those systems.
   */
/* #undef CRAY_STACKSEG_END */

/* Define to 1 if using `alloca.c'. */
/* #undef C_ALLOCA */

/* Define to 1 if you have `alloca', as a function or macro. */
#define HAVE_ALLOCA 1

/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
   */
#define HAVE_ALLOCA_H 1

/* Define to 1 if you have the <dirent.h> header file. */
#define HAVE_DIRENT_H 1

/* Define to 1 if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H 1

/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
/* #undef HAVE_DOPRNT */

/* Define to 1 if you have the <errno.h> header file. */
#define HAVE_ERRNO_H 1

/* Define to 1 if you have the <fcntl.h> header file. */
#define HAVE_FCNTL_H 1

/* Define to 1 if you have the `getpagesize' function. */
#define HAVE_GETPAGESIZE 1

/* Define to 1 if you have the `gettimeofday' function. */
#define HAVE_GETTIMEOFDAY 1

/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1

/* Define to 1 if you have the `dl' library (-ldl). */
#define HAVE_LIBDL 1

/* Define to 1 if you have the `SDL2' library (-lSDL2). */
/* #undef HAVE_LIBSDL2 */

/* Define to 1 if you have the <limits.h> header file. */
#define HAVE_LIMITS_H 1

/* Define to 1 if you have the <linux/spi/cy8mrln.h> header file. */
/* #undef HAVE_LINUX_SPI_CY8MRLN_H */

/* Define to 1 if you have the `memmove' function. */
#define HAVE_MEMMOVE 1

/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1

/* Define to 1 if you have the `memset' function. */
#define HAVE_MEMSET 1

/* Define to 1 if you have a working `mmap' system call. */
/* #undef HAVE_MMAP */

/* Define to 1 if you have the `munmap' function. */
#define HAVE_MUNMAP 1

/* Use SDL2. */
/* #undef HAVE_SDL2 */

/* Define to 1 if you have the `select' function. */
#define HAVE_SELECT 1

/* Define to 1 if `stat' has the bug that it succeeds when given the
   zero-length file name argument. */
#define HAVE_STAT_EMPTY_STRING_BUG 1

/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1

/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1

/* Define to 1 if you have the `strcasecmp' function. */
#define HAVE_STRCASECMP 1

/* Define to 1 if you have the `strchr' function. */
#define HAVE_STRCHR 1

/* Define to 1 if you have the `strdup' function. */
#define HAVE_STRDUP 1

/* Define to 1 if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1

/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1

/* Define to 1 if you have the `strsep' function. */
#define HAVE_STRSEP 1

/* Define to 1 if you have the `strtol' function. */
#define HAVE_STRTOL 1

/* Define to 1 if you have the `strtoul' function. */
#define HAVE_STRTOUL 1

/* Define to 1 if you have the <sys/ioctl.h> header file. */
#define HAVE_SYS_IOCTL_H 1

/* Define to 1 if you have the <sys/param.h> header file. */
#define HAVE_SYS_PARAM_H 1

/* Define to 1 if you have the <sys/select.h> header file. */
#define HAVE_SYS_SELECT_H 1

/* Define to 1 if you have the <sys/socket.h> header file. */
#define HAVE_SYS_SOCKET_H 1

/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1

/* Define to 1 if you have the <sys/time.h> header file. */
#define HAVE_SYS_TIME_H 1

/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1

/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1

/* Define to 1 if you have the `vprintf' function. */
#define HAVE_VPRINTF 1

/* library age number */
#define LIBTS_VERSION_AGE 9

/* library current number */
#define LIBTS_VERSION_CURRENT 9

/* library revision number */
#define LIBTS_VERSION_REVISION 0

/* Define to 1 if `lstat' dereferences a symlink specified with a trailing
   slash. */
/* #undef LSTAT_FOLLOWS_SLASHED_SYMLINK */

/* Define to the sub-directory where libtool stores uninstalled libraries. */
#define LT_OBJDIR ".libs/"

/* Name of package */
#define PACKAGE "tslib"

/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "<EMAIL>"

/* Define to the full name of this package. */
#define PACKAGE_NAME "tslib"

/* Define to the full name and version of this package. */
#define PACKAGE_STRING "tslib 1.15"

/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "tslib"

/* Define to the home page for this package. */
#define PACKAGE_URL "http://tslib.org"

/* Define to the version of this package. */
#define PACKAGE_VERSION "1.15"

/* Define as the return type of signal handlers (`int' or `void'). */
#define RETSIGTYPE void

/* Define to the type of arg 1 for `select'. */
#define SELECT_TYPE_ARG1 int

/* Define to the type of args 2, 3 and 4 for `select'. */
#define SELECT_TYPE_ARG234 (fd_set *)

/* Define to the type of arg 5 for `select'. */
#define SELECT_TYPE_ARG5 (struct timeval *)

/* If using the C implementation of alloca, define if you know the
   direction of stack growth for your system; otherwise it will be
   automatically deduced at runtime.
	STACK_DIRECTION > 0 => grows toward higher addresses
	STACK_DIRECTION < 0 => grows toward lower addresses
	STACK_DIRECTION = 0 => direction of growth unknown */
/* #undef STACK_DIRECTION */

/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1

/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
#define TIME_WITH_SYS_TIME 1

/* whether arctic2 should be build as part of libts or as a separate shared
   library which is dlopen()-ed at runtime */
/* #undef TSLIB_STATIC_ARCTIC2_MODULE */

/* whether collie should be build as part of libts or as a separate shared
   library which is dlopen()-ed at runtime */
/* #undef TSLIB_STATIC_COLLIE_MODULE */

/* whether corgi should be build as part of libts or as a separate shared
   library which is dlopen()-ed at runtime */
/* #undef TSLIB_STATIC_CORGI_MODULE */

/* whether cy8mrln-palmpre should be build as part of libts or as a separate
   shared library which is dlopen()-ed at runtime */
/* #undef TSLIB_STATIC_CY8MRLN_PALMPRE_MODULE */

/* whether debounce should be build as part of libts or as a separate shared
   library which is dlopen()-ed at runtime */
/* #undef TSLIB_STATIC_DEBOUNCE_MODULE */

/* whether dejitter should be build as part of libts or as a separate shared
   library which is dlopen()-ed at runtime */
/* #undef TSLIB_STATIC_DEJITTER_MODULE */

/* whether dmc_dus3000 should be build as part of libts or as a separate
   shared library which is dlopen()-ed at runtime */
/* #undef TSLIB_STATIC_DMC_DUS3000_MODULE */

/* whether dmc should be build as part of libts or as a separate shared
   library which is dlopen()-ed at runtime */
/* #undef TSLIB_STATIC_DMC_MODULE */

/* whether galax should be build as part of libts or as a separate shared
   library which is dlopen()-ed at runtime */
/* #undef TSLIB_STATIC_GALAX_MODULE */

/* whether h3600 should be build as part of libts or as a separate shared
   library which is dlopen()-ed at runtime */
/* #undef TSLIB_STATIC_H3600_MODULE */

/* whether iir should be build as part of libts or as a separate shared
   library which is dlopen()-ed at runtime */
/* #undef TSLIB_STATIC_IIR_MODULE */

/* whether input should be build as part of libts or as a separate shared
   library which is dlopen()-ed at runtime */
/* #undef TSLIB_STATIC_INPUT_MODULE */

/* whether invert should be build as part of libts or as a separate shared
   library which is dlopen()-ed at runtime */
/* #undef TSLIB_STATIC_INVERT_MODULE */

/* whether linear-h2200 should be build as part of libts or as a separate
   shared library which is dlopen()-ed at runtime */
/* #undef TSLIB_STATIC_LINEAR_H2200_MODULE */

/* whether linear should be build as part of libts or as a separate shared
   library which is dlopen()-ed at runtime */
/* #undef TSLIB_STATIC_LINEAR_MODULE */

/* whether lowpass should be build as part of libts or as a separate shared
   library which is dlopen()-ed at runtime */
/* #undef TSLIB_STATIC_LOWPASS_MODULE */

/* whether median should be build as part of libts or as a separate shared
   library which is dlopen()-ed at runtime */
/* #undef TSLIB_STATIC_MEDIAN_MODULE */

/* whether mk712 should be build as part of libts or as a separate shared
   library which is dlopen()-ed at runtime */
/* #undef TSLIB_STATIC_MK712_MODULE */

/* whether pthres should be build as part of libts or as a separate shared
   library which is dlopen()-ed at runtime */
/* #undef TSLIB_STATIC_PTHRES_MODULE */

/* whether skip should be build as part of libts or as a separate shared
   library which is dlopen()-ed at runtime */
/* #undef TSLIB_STATIC_SKIP_MODULE */

/* whether tatung should be build as part of libts or as a separate shared
   library which is dlopen()-ed at runtime */
/* #undef TSLIB_STATIC_TATUNG_MODULE */

/* whether touchkit should be build as part of libts or as a separate shared
   library which is dlopen()-ed at runtime */
/* #undef TSLIB_STATIC_TOUCHKIT_MODULE */

/* whether ucb1x00 should be build as part of libts or as a separate shared
   library which is dlopen()-ed at runtime */
/* #undef TSLIB_STATIC_UCB1X00_MODULE */

/* whether variance should be build as part of libts or as a separate shared
   library which is dlopen()-ed at runtime */
/* #undef TSLIB_STATIC_VARIANCE_MODULE */

/* whether waveshare should be build as part of libts or as a separate shared
   library which is dlopen()-ed at runtime */
/* #undef TSLIB_STATIC_WAVESHARE_MODULE */

/* Version number of package */
#define VERSION "1.15"

/* Define for Solaris 2.5.1 so the uint8_t typedef from <sys/synch.h>,
   <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
   #define below would cause a syntax error. */
/* #undef _UINT8_T */

/* Define to empty if `const' does not conform to ANSI C. */
/* #undef const */

/* Define to `__inline__' or `__inline' if that's what the C compiler
   calls it, or to nothing if 'inline' is not supported under any name.  */
#ifndef __cplusplus
/* #undef inline */
#endif

/* Define to `unsigned int' if <sys/types.h> does not define. */
/* #undef size_t */

/* Define to the type of an unsigned integer type of width exactly 16 bits if
   such a type exists and the standard includes do not define it. */
/* #undef uint16_t */

/* Define to the type of an unsigned integer type of width exactly 8 bits if
   such a type exists and the standard includes do not define it. */
/* #undef uint8_t */


<|start_filename|>3rdpart/ethercat-1.5.2/master/sdo_request.c<|end_filename|>
/******************************************************************************
 *
 *  $Id: sdo_request.c,v ec403cf308eb 2013/02/12 14:46:43 fp $
 *
 *  Copyright (C) 2006-2008  <NAME>, Ingenieurgemeinschaft IgH
 *
 *  This file is part of the IgH EtherCAT Master.
 *
 *  The IgH EtherCAT Master is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License version 2, as
 *  published by the Free Software Foundation.
 *
 *  The IgH EtherCAT Master is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 *  Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with the IgH EtherCAT Master; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 *****************************************************************************/

/** \file
 * Canopen over EtherCAT SDO request functions.
 */

/*****************************************************************************/

#include <linux/module.h>
#include <linux/jiffies.h>
#include <linux/slab.h>

#include "sdo_request.h"

/*****************************************************************************/

/** Default timeout in ms to wait for SDO transfer responses.
 */
#define EC_SDO_REQUEST_RESPONSE_TIMEOUT 1000

/*****************************************************************************/

void ec_sdo_request_clear_data(ec_sdo_request_t *);

/*****************************************************************************/

/** SDO request constructor.
 */
void ec_sdo_request_init(
        ec_sdo_request_t *req /**< SDO request. */
        )
{
    req->complete_access = 0;
    req->data = NULL;
    req->mem_size = 0;
    req->data_size = 0;
    req->dir = EC_DIR_INVALID;
    req->issue_timeout = 0; // no timeout
    req->response_timeout = EC_SDO_REQUEST_RESPONSE_TIMEOUT;
    req->state = EC_INT_REQUEST_INIT;
    req->errno = 0;
    req->abort_code = 0x00000000;
}

/*****************************************************************************/

/** SDO request destructor.
 */
void ec_sdo_request_clear(
        ec_sdo_request_t *req /**< SDO request. */
        )
{
    ec_sdo_request_clear_data(req);
}

/*****************************************************************************/

/** Copy another SDO request.
 *
 * \attention Only the index subindex and data are copied.
 *
 * \return Zero on success, otherwise a negative error code.
 */
int ec_sdo_request_copy(
        ec_sdo_request_t *req, /**< SDO request. */
        const ec_sdo_request_t *other /**< Other SDO request to copy from. */
        )
{
    req->complete_access = other->complete_access;
    req->index = other->index;
    req->subindex = other->subindex;
    return ec_sdo_request_copy_data(req, other->data, other->data_size);
}

/*****************************************************************************/

/** SDO request destructor.
 */
void ec_sdo_request_clear_data(
        ec_sdo_request_t *req /**< SDO request. */
        )
{
    if (req->data) {
        kfree(req->data);
        req->data = NULL;
    }

    req->mem_size = 0;
    req->data_size = 0;
}

/*****************************************************************************/

/** Pre-allocates the data memory.
 *
 * If the \a mem_size is already bigger than \a size, nothing is done.
 *
 * \return 0 on success, otherwise -ENOMEM.
 */
int ec_sdo_request_alloc(
        ec_sdo_request_t *req, /**< SDO request. */
        size_t size /**< Data size to allocate. */
        )
{
    if (size <= req->mem_size)
        return 0;

    ec_sdo_request_clear_data(req);

    if (!(req->data = (uint8_t *) kmalloc(size, GFP_KERNEL))) {
        EC_ERR("Failed to allocate %zu bytes of SDO memory.\n", size);
        return -ENOMEM;
    }

    req->mem_size = size;
    req->data_size = 0;
    return 0;
}

/*****************************************************************************/

/** Copies SDO data from an external source.
 *
 * If the \a mem_size is to small, new memory is allocated.
 *
 * \retval  0 Success.
 * \retval <0 Error code.
 */
int ec_sdo_request_copy_data(
        ec_sdo_request_t *req, /**< SDO request. */
        const uint8_t *source, /**< Source data. */
        size_t size /**< Number of bytes in \a source. */
        )
{
    int ret = ec_sdo_request_alloc(req, size);
    if (ret < 0)
        return ret;

    memcpy(req->data, source, size);
    req->data_size = size;
    return 0;
}

/*****************************************************************************/

/** Checks, if the timeout was exceeded.
 *
 * \return non-zero if the timeout was exceeded, else zero.
 */
int ec_sdo_request_timed_out(const ec_sdo_request_t *req /**< SDO request. */)
{
    return req->issue_timeout
        && jiffies - req->jiffies_start > HZ * req->issue_timeout / 1000;
}

/*****************************************************************************
 * Application interface.
 ****************************************************************************/

void ecrt_sdo_request_index(ec_sdo_request_t *req, uint16_t index,
        uint8_t subindex)
{
    req->index = index;
    req->subindex = subindex;
}

/*****************************************************************************/

void ecrt_sdo_request_timeout(ec_sdo_request_t *req, uint32_t timeout)
{
    req->issue_timeout = timeout;
}

/*****************************************************************************/

uint8_t *ecrt_sdo_request_data(ec_sdo_request_t *req)
{
    return req->data;
}

/*****************************************************************************/

size_t ecrt_sdo_request_data_size(const ec_sdo_request_t *req)
{
    return req->data_size;
}

/*****************************************************************************/

ec_request_state_t ecrt_sdo_request_state(const ec_sdo_request_t *req)
{
   return ec_request_state_translation_table[req->state];
}

/*****************************************************************************/

void ecrt_sdo_request_read(ec_sdo_request_t *req)
{
    req->dir = EC_DIR_INPUT;
    req->state = EC_INT_REQUEST_QUEUED;
    req->errno = 0;
    req->abort_code = 0x00000000;
    req->jiffies_start = jiffies;
}

/*****************************************************************************/

void ecrt_sdo_request_write(ec_sdo_request_t *req)
{
    req->dir = EC_DIR_OUTPUT;
    req->state = EC_INT_REQUEST_QUEUED;
    req->errno = 0;
    req->abort_code = 0x00000000;
    req->jiffies_start = jiffies;
}

/*****************************************************************************/

/** \cond */

EXPORT_SYMBOL(ecrt_sdo_request_index);
EXPORT_SYMBOL(ecrt_sdo_request_timeout);
EXPORT_SYMBOL(ecrt_sdo_request_data);
EXPORT_SYMBOL(ecrt_sdo_request_data_size);
EXPORT_SYMBOL(ecrt_sdo_request_state);
EXPORT_SYMBOL(ecrt_sdo_request_read);
EXPORT_SYMBOL(ecrt_sdo_request_write);

/** \endcond */

/*****************************************************************************/


<|start_filename|>3rdpart/ethercat-1.5.2/devices/e1000/e1000_ethtool-2.6.13-ethercat.c<|end_filename|>
/*******************************************************************************

  
  Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
  
  This program is free software; you can redistribute it and/or modify it 
  under the terms of the GNU General Public License as published by the Free 
  Software Foundation; either version 2 of the License, or (at your option) 
  any later version.
  
  This program is distributed in the hope that it will be useful, but WITHOUT 
  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for 
  more details.
  
  You should have received a copy of the GNU General Public License along with
  this program; if not, write to the Free Software Foundation, Inc., 59 
  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  
  The full GNU General Public License is included in this distribution in the
  file called LICENSE.
  
  Contact Information:
  Linux NICS <<EMAIL>>
  Intel Corporation, 5200 N.E. <NAME>ung Parkway, Hillsboro, OR 97124-6497

*******************************************************************************/

/* ethtool support for e1000 */

#include "e1000-2.6.13-ethercat.h"

#include <asm/uaccess.h>

extern char e1000_driver_name[];
extern char e1000_driver_version[];

extern int e1000_up(struct e1000_adapter *adapter);
extern void e1000_down(struct e1000_adapter *adapter);
extern void e1000_reset(struct e1000_adapter *adapter);
extern int e1000_set_spd_dplx(struct e1000_adapter *adapter, uint16_t spddplx);
extern int e1000_setup_rx_resources(struct e1000_adapter *adapter);
extern int e1000_setup_tx_resources(struct e1000_adapter *adapter);
extern void e1000_free_rx_resources(struct e1000_adapter *adapter);
extern void e1000_free_tx_resources(struct e1000_adapter *adapter);
extern void e1000_update_stats(struct e1000_adapter *adapter);

struct e1000_stats {
	char stat_string[ETH_GSTRING_LEN];
	int sizeof_stat;
	int stat_offset;
};

#define E1000_STAT(m) sizeof(((struct e1000_adapter *)0)->m), \
		      offsetof(struct e1000_adapter, m)
static const struct e1000_stats e1000_gstrings_stats[] = {
	{ "rx_packets", E1000_STAT(net_stats.rx_packets) },
	{ "tx_packets", E1000_STAT(net_stats.tx_packets) },
	{ "rx_bytes", E1000_STAT(net_stats.rx_bytes) },
	{ "tx_bytes", E1000_STAT(net_stats.tx_bytes) },
	{ "rx_errors", E1000_STAT(net_stats.rx_errors) },
	{ "tx_errors", E1000_STAT(net_stats.tx_errors) },
	{ "rx_dropped", E1000_STAT(net_stats.rx_dropped) },
	{ "tx_dropped", E1000_STAT(net_stats.tx_dropped) },
	{ "multicast", E1000_STAT(net_stats.multicast) },
	{ "collisions", E1000_STAT(net_stats.collisions) },
	{ "rx_length_errors", E1000_STAT(net_stats.rx_length_errors) },
	{ "rx_over_errors", E1000_STAT(net_stats.rx_over_errors) },
	{ "rx_crc_errors", E1000_STAT(net_stats.rx_crc_errors) },
	{ "rx_frame_errors", E1000_STAT(net_stats.rx_frame_errors) },
	{ "rx_fifo_errors", E1000_STAT(net_stats.rx_fifo_errors) },
	{ "rx_no_buffer_count", E1000_STAT(stats.rnbc) },
	{ "rx_missed_errors", E1000_STAT(net_stats.rx_missed_errors) },
	{ "tx_aborted_errors", E1000_STAT(net_stats.tx_aborted_errors) },
	{ "tx_carrier_errors", E1000_STAT(net_stats.tx_carrier_errors) },
	{ "tx_fifo_errors", E1000_STAT(net_stats.tx_fifo_errors) },
	{ "tx_heartbeat_errors", E1000_STAT(net_stats.tx_heartbeat_errors) },
	{ "tx_window_errors", E1000_STAT(net_stats.tx_window_errors) },
	{ "tx_abort_late_coll", E1000_STAT(stats.latecol) },
	{ "tx_deferred_ok", E1000_STAT(stats.dc) },
	{ "tx_single_coll_ok", E1000_STAT(stats.scc) },
	{ "tx_multi_coll_ok", E1000_STAT(stats.mcc) },
	{ "rx_long_length_errors", E1000_STAT(stats.roc) },
	{ "rx_short_length_errors", E1000_STAT(stats.ruc) },
	{ "rx_align_errors", E1000_STAT(stats.algnerrc) },
	{ "tx_tcp_seg_good", E1000_STAT(stats.tsctc) },
	{ "tx_tcp_seg_failed", E1000_STAT(stats.tsctfc) },
	{ "rx_flow_control_xon", E1000_STAT(stats.xonrxc) },
	{ "rx_flow_control_xoff", E1000_STAT(stats.xoffrxc) },
	{ "tx_flow_control_xon", E1000_STAT(stats.xontxc) },
	{ "tx_flow_control_xoff", E1000_STAT(stats.xofftxc) },
	{ "rx_long_byte_count", E1000_STAT(stats.gorcl) },
	{ "rx_csum_offload_good", E1000_STAT(hw_csum_good) },
	{ "rx_csum_offload_errors", E1000_STAT(hw_csum_err) }
};
#define E1000_STATS_LEN	\
	sizeof(e1000_gstrings_stats) / sizeof(struct e1000_stats)
static const char e1000_gstrings_test[][ETH_GSTRING_LEN] = {
	"Register test  (offline)", "Eeprom test    (offline)",
	"Interrupt test (offline)", "Loopback test  (offline)",
	"Link test   (on/offline)"
};
#define E1000_TEST_LEN sizeof(e1000_gstrings_test) / ETH_GSTRING_LEN

static int
e1000_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
{
	struct e1000_adapter *adapter = netdev_priv(netdev);
	struct e1000_hw *hw = &adapter->hw;

	if(hw->media_type == e1000_media_type_copper) {

		ecmd->supported = (SUPPORTED_10baseT_Half |
		                   SUPPORTED_10baseT_Full |
		                   SUPPORTED_100baseT_Half |
		                   SUPPORTED_100baseT_Full |
		                   SUPPORTED_1000baseT_Full|
		                   SUPPORTED_Autoneg |
		                   SUPPORTED_TP);

		ecmd->advertising = ADVERTISED_TP;

		if(hw->autoneg == 1) {
			ecmd->advertising |= ADVERTISED_Autoneg;

			/* the e1000 autoneg seems to match ethtool nicely */

			ecmd->advertising |= hw->autoneg_advertised;
		}

		ecmd->port = PORT_TP;
		ecmd->phy_address = hw->phy_addr;

		if(hw->mac_type == e1000_82543)
			ecmd->transceiver = XCVR_EXTERNAL;
		else
			ecmd->transceiver = XCVR_INTERNAL;

	} else {
		ecmd->supported   = (SUPPORTED_1000baseT_Full |
				     SUPPORTED_FIBRE |
				     SUPPORTED_Autoneg);

		ecmd->advertising = (ADVERTISED_1000baseT_Full |
				     ADVERTISED_FIBRE |
				     ADVERTISED_Autoneg);

		ecmd->port = PORT_FIBRE;

		if(hw->mac_type >= e1000_82545)
			ecmd->transceiver = XCVR_INTERNAL;
		else
			ecmd->transceiver = XCVR_EXTERNAL;
	}

	if ((adapter->ecdev && ecdev_get_link(adapter->ecdev))
            || (!adapter->ecdev && netif_carrier_ok(adapter->netdev))) {
		e1000_get_speed_and_duplex(hw, &adapter->link_speed,
		                                   &adapter->link_duplex);
		ecmd->speed = adapter->link_speed;

		/* unfortunatly FULL_DUPLEX != DUPLEX_FULL
		 *          and HALF_DUPLEX != DUPLEX_HALF */

		if(adapter->link_duplex == FULL_DUPLEX)
			ecmd->duplex = DUPLEX_FULL;
		else
			ecmd->duplex = DUPLEX_HALF;
	} else {
		ecmd->speed = -1;
		ecmd->duplex = -1;
	}

	ecmd->autoneg = ((hw->media_type == e1000_media_type_fiber) ||
			 hw->autoneg) ? AUTONEG_ENABLE : AUTONEG_DISABLE;
	return 0;
}

static int
e1000_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
{
	struct e1000_adapter *adapter = netdev_priv(netdev);
	struct e1000_hw *hw = &adapter->hw;

	if(ecmd->autoneg == AUTONEG_ENABLE) {
		hw->autoneg = 1;
		if(hw->media_type == e1000_media_type_fiber)
			hw->autoneg_advertised = ADVERTISED_1000baseT_Full |
				     ADVERTISED_FIBRE |
				     ADVERTISED_Autoneg;
		else 
			hw->autoneg_advertised = ADVERTISED_10baseT_Half |
						  ADVERTISED_10baseT_Full |
						  ADVERTISED_100baseT_Half |
						  ADVERTISED_100baseT_Full |
						  ADVERTISED_1000baseT_Full|
						  ADVERTISED_Autoneg |
						  ADVERTISED_TP;
		ecmd->advertising = hw->autoneg_advertised;
	} else
		if(e1000_set_spd_dplx(adapter, ecmd->speed + ecmd->duplex))
			return -EINVAL;

	/* reset the link */

	if (adapter->ecdev || netif_running(adapter->netdev)) {
		e1000_down(adapter);
		e1000_reset(adapter);
		e1000_up(adapter);
	} else
		e1000_reset(adapter);

	return 0;
}

static void
e1000_get_pauseparam(struct net_device *netdev,
                     struct ethtool_pauseparam *pause)
{
	struct e1000_adapter *adapter = netdev_priv(netdev);
	struct e1000_hw *hw = &adapter->hw;

	pause->autoneg = 
		(adapter->fc_autoneg ? AUTONEG_ENABLE : AUTONEG_DISABLE);
	
	if(hw->fc == e1000_fc_rx_pause)
		pause->rx_pause = 1;
	else if(hw->fc == e1000_fc_tx_pause)
		pause->tx_pause = 1;
	else if(hw->fc == e1000_fc_full) {
		pause->rx_pause = 1;
		pause->tx_pause = 1;
	}
}

static int
e1000_set_pauseparam(struct net_device *netdev,
                     struct ethtool_pauseparam *pause)
{
	struct e1000_adapter *adapter = netdev_priv(netdev);
	struct e1000_hw *hw = &adapter->hw;
	
	adapter->fc_autoneg = pause->autoneg;

	if(pause->rx_pause && pause->tx_pause)
		hw->fc = e1000_fc_full;
	else if(pause->rx_pause && !pause->tx_pause)
		hw->fc = e1000_fc_rx_pause;
	else if(!pause->rx_pause && pause->tx_pause)
		hw->fc = e1000_fc_tx_pause;
	else if(!pause->rx_pause && !pause->tx_pause)
		hw->fc = e1000_fc_none;

	hw->original_fc = hw->fc;

	if(adapter->fc_autoneg == AUTONEG_ENABLE) {
		if (adapter->ecdev || netif_running(adapter->netdev)) {
			e1000_down(adapter);
			e1000_up(adapter);
		} else
			e1000_reset(adapter);
	}
	else
		return ((hw->media_type == e1000_media_type_fiber) ?
			e1000_setup_link(hw) : e1000_force_mac_fc(hw));
	
	return 0;
}

static uint32_t
e1000_get_rx_csum(struct net_device *netdev)
{
	struct e1000_adapter *adapter = netdev_priv(netdev);
	return adapter->rx_csum;
}

static int
e1000_set_rx_csum(struct net_device *netdev, uint32_t data)
{
	struct e1000_adapter *adapter = netdev_priv(netdev);
	adapter->rx_csum = data;

	if (adapter->ecdev || netif_running(netdev)) {
		e1000_down(adapter);
		e1000_up(adapter);
	} else
		e1000_reset(adapter);
	return 0;
}
	
static uint32_t
e1000_get_tx_csum(struct net_device *netdev)
{
	return (netdev->features & NETIF_F_HW_CSUM) != 0;
}

static int
e1000_set_tx_csum(struct net_device *netdev, uint32_t data)
{
	struct e1000_adapter *adapter = netdev_priv(netdev);

	if(adapter->hw.mac_type < e1000_82543) {
		if (!data)
			return -EINVAL;
		return 0;
	}

	if (data)
		netdev->features |= NETIF_F_HW_CSUM;
	else
		netdev->features &= ~NETIF_F_HW_CSUM;

	return 0;
}

#ifdef NETIF_F_TSO
static int
e1000_set_tso(struct net_device *netdev, uint32_t data)
{
	struct e1000_adapter *adapter = netdev_priv(netdev);
	if((adapter->hw.mac_type < e1000_82544) ||
	    (adapter->hw.mac_type == e1000_82547)) 
		return data ? -EINVAL : 0;

	if (data)
		netdev->features |= NETIF_F_TSO;
	else
		netdev->features &= ~NETIF_F_TSO;
	return 0;
} 
#endif /* NETIF_F_TSO */

static uint32_t
e1000_get_msglevel(struct net_device *netdev)
{
	struct e1000_adapter *adapter = netdev_priv(netdev);
	return adapter->msg_enable;
}

static void
e1000_set_msglevel(struct net_device *netdev, uint32_t data)
{
	struct e1000_adapter *adapter = netdev_priv(netdev);
	adapter->msg_enable = data;
}

static int 
e1000_get_regs_len(struct net_device *netdev)
{
#define E1000_REGS_LEN 32
	return E1000_REGS_LEN * sizeof(uint32_t);
}

static void
e1000_get_regs(struct net_device *netdev,
	       struct ethtool_regs *regs, void *p)
{
	struct e1000_adapter *adapter = netdev_priv(netdev);
	struct e1000_hw *hw = &adapter->hw;
	uint32_t *regs_buff = p;
	uint16_t phy_data;

	memset(p, 0, E1000_REGS_LEN * sizeof(uint32_t));

	regs->version = (1 << 24) | (hw->revision_id << 16) | hw->device_id;

	regs_buff[0]  = E1000_READ_REG(hw, CTRL);
	regs_buff[1]  = E1000_READ_REG(hw, STATUS);

	regs_buff[2]  = E1000_READ_REG(hw, RCTL);
	regs_buff[3]  = E1000_READ_REG(hw, RDLEN);
	regs_buff[4]  = E1000_READ_REG(hw, RDH);
	regs_buff[5]  = E1000_READ_REG(hw, RDT);
	regs_buff[6]  = E1000_READ_REG(hw, RDTR);

	regs_buff[7]  = E1000_READ_REG(hw, TCTL);
	regs_buff[8]  = E1000_READ_REG(hw, TDLEN);
	regs_buff[9]  = E1000_READ_REG(hw, TDH);
	regs_buff[10] = E1000_READ_REG(hw, TDT);
	regs_buff[11] = E1000_READ_REG(hw, TIDV);

	regs_buff[12] = adapter->hw.phy_type;  /* PHY type (IGP=1, M88=0) */
	if(hw->phy_type == e1000_phy_igp) {
		e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT,
				    IGP01E1000_PHY_AGC_A);
		e1000_read_phy_reg(hw, IGP01E1000_PHY_AGC_A &
				   IGP01E1000_PHY_PAGE_SELECT, &phy_data);
		regs_buff[13] = (uint32_t)phy_data; /* cable length */
		e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT,
				    IGP01E1000_PHY_AGC_B);
		e1000_read_phy_reg(hw, IGP01E1000_PHY_AGC_B &
				   IGP01E1000_PHY_PAGE_SELECT, &phy_data);
		regs_buff[14] = (uint32_t)phy_data; /* cable length */
		e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT,
				    IGP01E1000_PHY_AGC_C);
		e1000_read_phy_reg(hw, IGP01E1000_PHY_AGC_C &
				   IGP01E1000_PHY_PAGE_SELECT, &phy_data);
		regs_buff[15] = (uint32_t)phy_data; /* cable length */
		e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT,
				    IGP01E1000_PHY_AGC_D);
		e1000_read_phy_reg(hw, IGP01E1000_PHY_AGC_D &
				   IGP01E1000_PHY_PAGE_SELECT, &phy_data);
		regs_buff[16] = (uint32_t)phy_data; /* cable length */
		regs_buff[17] = 0; /* extended 10bt distance (not needed) */
		e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT, 0x0);
		e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS &
				   IGP01E1000_PHY_PAGE_SELECT, &phy_data);
		regs_buff[18] = (uint32_t)phy_data; /* cable polarity */
		e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT,
				    IGP01E1000_PHY_PCS_INIT_REG);
		e1000_read_phy_reg(hw, IGP01E1000_PHY_PCS_INIT_REG &
				   IGP01E1000_PHY_PAGE_SELECT, &phy_data);
		regs_buff[19] = (uint32_t)phy_data; /* cable polarity */
		regs_buff[20] = 0; /* polarity correction enabled (always) */
		regs_buff[22] = 0; /* phy receive errors (unavailable) */
		regs_buff[23] = regs_buff[18]; /* mdix mode */
		e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT, 0x0);
	} else {
        	e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data);
		regs_buff[13] = (uint32_t)phy_data; /* cable length */
		regs_buff[14] = 0;  /* Dummy (to align w/ IGP phy reg dump) */
		regs_buff[15] = 0;  /* Dummy (to align w/ IGP phy reg dump) */
		regs_buff[16] = 0;  /* Dummy (to align w/ IGP phy reg dump) */
        	e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
		regs_buff[17] = (uint32_t)phy_data; /* extended 10bt distance */
		regs_buff[18] = regs_buff[13]; /* cable polarity */
		regs_buff[19] = 0;  /* Dummy (to align w/ IGP phy reg dump) */
		regs_buff[20] = regs_buff[17]; /* polarity correction */
		/* phy receive errors */
		regs_buff[22] = adapter->phy_stats.receive_errors;
		regs_buff[23] = regs_buff[13]; /* mdix mode */
	}
	regs_buff[21] = adapter->phy_stats.idle_errors;  /* phy idle errors */
	e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_data);
	regs_buff[24] = (uint32_t)phy_data;  /* phy local receiver status */
	regs_buff[25] = regs_buff[24];  /* phy remote receiver status */
	if(hw->mac_type >= e1000_82540 &&
	   hw->media_type == e1000_media_type_copper) {
		regs_buff[26] = E1000_READ_REG(hw, MANC);
	}
}

static int
e1000_get_eeprom_len(struct net_device *netdev)
{
	struct e1000_adapter *adapter = netdev_priv(netdev);
	return adapter->hw.eeprom.word_size * 2;
}

static int
e1000_get_eeprom(struct net_device *netdev,
                      struct ethtool_eeprom *eeprom, uint8_t *bytes)
{
	struct e1000_adapter *adapter = netdev_priv(netdev);
	struct e1000_hw *hw = &adapter->hw;
	uint16_t *eeprom_buff;
	int first_word, last_word;
	int ret_val = 0;
	uint16_t i;

	if(eeprom->len == 0)
		return -EINVAL;

	eeprom->magic = hw->vendor_id | (hw->device_id << 16);

	first_word = eeprom->offset >> 1;
	last_word = (eeprom->offset + eeprom->len - 1) >> 1;

	eeprom_buff = kmalloc(sizeof(uint16_t) *
			(last_word - first_word + 1), GFP_KERNEL);
	if(!eeprom_buff)
		return -ENOMEM;

	if(hw->eeprom.type == e1000_eeprom_spi)
		ret_val = e1000_read_eeprom(hw, first_word,
					    last_word - first_word + 1,
					    eeprom_buff);
	else {
		for (i = 0; i < last_word - first_word + 1; i++)
			if((ret_val = e1000_read_eeprom(hw, first_word + i, 1,
							&eeprom_buff[i])))
				break;
	}

	/* Device's eeprom is always little-endian, word addressable */
	for (i = 0; i < last_word - first_word + 1; i++)
		le16_to_cpus(&eeprom_buff[i]);

	memcpy(bytes, (uint8_t *)eeprom_buff + (eeprom->offset & 1),
			eeprom->len);
	kfree(eeprom_buff);

	return ret_val;
}

static int
e1000_set_eeprom(struct net_device *netdev,
                      struct ethtool_eeprom *eeprom, uint8_t *bytes)
{
	struct e1000_adapter *adapter = netdev_priv(netdev);
	struct e1000_hw *hw = &adapter->hw;
	uint16_t *eeprom_buff;
	void *ptr;
	int max_len, first_word, last_word, ret_val = 0;
	uint16_t i;

	if(eeprom->len == 0)
		return -EOPNOTSUPP;

	if(eeprom->magic != (hw->vendor_id | (hw->device_id << 16)))
		return -EFAULT;

	max_len = hw->eeprom.word_size * 2;

	first_word = eeprom->offset >> 1;
	last_word = (eeprom->offset + eeprom->len - 1) >> 1;
	eeprom_buff = kmalloc(max_len, GFP_KERNEL);
	if(!eeprom_buff)
		return -ENOMEM;

	ptr = (void *)eeprom_buff;

	if(eeprom->offset & 1) {
		/* need read/modify/write of first changed EEPROM word */
		/* only the second byte of the word is being modified */
		ret_val = e1000_read_eeprom(hw, first_word, 1,
					    &eeprom_buff[0]);
		ptr++;
	}
	if(((eeprom->offset + eeprom->len) & 1) && (ret_val == 0)) {
		/* need read/modify/write of last changed EEPROM word */
		/* only the first byte of the word is being modified */
		ret_val = e1000_read_eeprom(hw, last_word, 1,
		                  &eeprom_buff[last_word - first_word]);
	}

	/* Device's eeprom is always little-endian, word addressable */
	for (i = 0; i < last_word - first_word + 1; i++)
		le16_to_cpus(&eeprom_buff[i]);

	memcpy(ptr, bytes, eeprom->len);

	for (i = 0; i < last_word - first_word + 1; i++)
		eeprom_buff[i] = cpu_to_le16(eeprom_buff[i]);

	ret_val = e1000_write_eeprom(hw, first_word,
				     last_word - first_word + 1, eeprom_buff);

	/* Update the checksum over the first part of the EEPROM if needed */
	if((ret_val == 0) && first_word <= EEPROM_CHECKSUM_REG)
		e1000_update_eeprom_checksum(hw);

	kfree(eeprom_buff);
	return ret_val;
}

static void
e1000_get_drvinfo(struct net_device *netdev,
                       struct ethtool_drvinfo *drvinfo)
{
	struct e1000_adapter *adapter = netdev_priv(netdev);

	strncpy(drvinfo->driver,  e1000_driver_name, 32);
	strncpy(drvinfo->version, e1000_driver_version, 32);
	strncpy(drvinfo->fw_version, "N/A", 32);
	strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32);
	drvinfo->n_stats = E1000_STATS_LEN;
	drvinfo->testinfo_len = E1000_TEST_LEN;
	drvinfo->regdump_len = e1000_get_regs_len(netdev);
	drvinfo->eedump_len = e1000_get_eeprom_len(netdev);
}

static void
e1000_get_ringparam(struct net_device *netdev,
                    struct ethtool_ringparam *ring)
{
	struct e1000_adapter *adapter = netdev_priv(netdev);
	e1000_mac_type mac_type = adapter->hw.mac_type;
	struct e1000_desc_ring *txdr = &adapter->tx_ring;
	struct e1000_desc_ring *rxdr = &adapter->rx_ring;

	ring->rx_max_pending = (mac_type < e1000_82544) ? E1000_MAX_RXD :
		E1000_MAX_82544_RXD;
	ring->tx_max_pending = (mac_type < e1000_82544) ? E1000_MAX_TXD :
		E1000_MAX_82544_TXD;
	ring->rx_mini_max_pending = 0;
	ring->rx_jumbo_max_pending = 0;
	ring->rx_pending = rxdr->count;
	ring->tx_pending = txdr->count;
	ring->rx_mini_pending = 0;
	ring->rx_jumbo_pending = 0;
}

static int 
e1000_set_ringparam(struct net_device *netdev,
                    struct ethtool_ringparam *ring)
{
	struct e1000_adapter *adapter = netdev_priv(netdev);
	e1000_mac_type mac_type = adapter->hw.mac_type;
	struct e1000_desc_ring *txdr = &adapter->tx_ring;
	struct e1000_desc_ring *rxdr = &adapter->rx_ring;
	struct e1000_desc_ring tx_old, tx_new, rx_old, rx_new;
	int err;

    if (adapter->ecdev)
        return -EBUSY;

	tx_old = adapter->tx_ring;
	rx_old = adapter->rx_ring;

	if((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
		return -EINVAL;

	if(netif_running(adapter->netdev))
		e1000_down(adapter);

	rxdr->count = max(ring->rx_pending,(uint32_t)E1000_MIN_RXD);
	rxdr->count = min(rxdr->count,(uint32_t)(mac_type < e1000_82544 ?
		E1000_MAX_RXD : E1000_MAX_82544_RXD));
	E1000_ROUNDUP(rxdr->count, REQ_RX_DESCRIPTOR_MULTIPLE); 

	txdr->count = max(ring->tx_pending,(uint32_t)E1000_MIN_TXD);
	txdr->count = min(txdr->count,(uint32_t)(mac_type < e1000_82544 ?
		E1000_MAX_TXD : E1000_MAX_82544_TXD));
	E1000_ROUNDUP(txdr->count, REQ_TX_DESCRIPTOR_MULTIPLE); 

	if(netif_running(adapter->netdev)) {
		/* Try to get new resources before deleting old */
		if((err = e1000_setup_rx_resources(adapter)))
			goto err_setup_rx;
		if((err = e1000_setup_tx_resources(adapter)))
			goto err_setup_tx;

		/* save the new, restore the old in order to free it,
		 * then restore the new back again */

		rx_new = adapter->rx_ring;
		tx_new = adapter->tx_ring;
		adapter->rx_ring = rx_old;
		adapter->tx_ring = tx_old;
		e1000_free_rx_resources(adapter);
		e1000_free_tx_resources(adapter);
		adapter->rx_ring = rx_new;
		adapter->tx_ring = tx_new;
		if((err = e1000_up(adapter)))
			return err;
	}

	return 0;
err_setup_tx:
	e1000_free_rx_resources(adapter);
err_setup_rx:
	adapter->rx_ring = rx_old;
	adapter->tx_ring = tx_old;
	e1000_up(adapter);
	return err;
}

#define REG_PATTERN_TEST(R, M, W)                                              \
{                                                                              \
	uint32_t pat, value;                                                   \
	uint32_t test[] =                                                      \
		{0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF};              \
	for(pat = 0; pat < sizeof(test)/sizeof(test[0]); pat++) {              \
		E1000_WRITE_REG(&adapter->hw, R, (test[pat] & W));             \
		value = E1000_READ_REG(&adapter->hw, R);                       \
		if(value != (test[pat] & W & M)) {                             \
			DPRINTK(DRV, ERR, "pattern test reg %04X failed: got " \
			        "0x%08X expected 0x%08X\n",                    \
			        E1000_##R, value, (test[pat] & W & M));        \
			*data = (adapter->hw.mac_type < e1000_82543) ?         \
				E1000_82542_##R : E1000_##R;                   \
			return 1;                                              \
		}                                                              \
	}                                                                      \
}

#define REG_SET_AND_CHECK(R, M, W)                                             \
{                                                                              \
	uint32_t value;                                                        \
	E1000_WRITE_REG(&adapter->hw, R, W & M);                               \
	value = E1000_READ_REG(&adapter->hw, R);                               \
	if((W & M) != (value & M)) {                                          \
		DPRINTK(DRV, ERR, "set/check reg %04X test failed: got 0x%08X "\
		        "expected 0x%08X\n", E1000_##R, (value & M), (W & M)); \
		*data = (adapter->hw.mac_type < e1000_82543) ?                 \
			E1000_82542_##R : E1000_##R;                           \
		return 1;                                                      \
	}                                                                      \
}

static int
e1000_reg_test(struct e1000_adapter *adapter, uint64_t *data)
{
	uint32_t value, before, after;
	uint32_t i, toggle;

	/* The status register is Read Only, so a write should fail.
	 * Some bits that get toggled are ignored.
	 */
        switch (adapter->hw.mac_type) {
	case e1000_82573:
		toggle = 0x7FFFF033;
		break;
	default:
		toggle = 0xFFFFF833;
		break;
	}

	before = E1000_READ_REG(&adapter->hw, STATUS);
	value = (E1000_READ_REG(&adapter->hw, STATUS) & toggle);
	E1000_WRITE_REG(&adapter->hw, STATUS, toggle);
	after = E1000_READ_REG(&adapter->hw, STATUS) & toggle;
	if(value != after) {
		DPRINTK(DRV, ERR, "failed STATUS register test got: "
		        "0x%08X expected: 0x%08X\n", after, value);
		*data = 1;
		return 1;
	}
	/* restore previous status */
	E1000_WRITE_REG(&adapter->hw, STATUS, before);

	REG_PATTERN_TEST(FCAL, 0xFFFFFFFF, 0xFFFFFFFF);
	REG_PATTERN_TEST(FCAH, 0x0000FFFF, 0xFFFFFFFF);
	REG_PATTERN_TEST(FCT, 0x0000FFFF, 0xFFFFFFFF);
	REG_PATTERN_TEST(VET, 0x0000FFFF, 0xFFFFFFFF);
	REG_PATTERN_TEST(RDTR, 0x0000FFFF, 0xFFFFFFFF);
	REG_PATTERN_TEST(RDBAH, 0xFFFFFFFF, 0xFFFFFFFF);
	REG_PATTERN_TEST(RDLEN, 0x000FFF80, 0x000FFFFF);
	REG_PATTERN_TEST(RDH, 0x0000FFFF, 0x0000FFFF);
	REG_PATTERN_TEST(RDT, 0x0000FFFF, 0x0000FFFF);
	REG_PATTERN_TEST(FCRTH, 0x0000FFF8, 0x0000FFF8);
	REG_PATTERN_TEST(FCTTV, 0x0000FFFF, 0x0000FFFF);
	REG_PATTERN_TEST(TIPG, 0x3FFFFFFF, 0x3FFFFFFF);
	REG_PATTERN_TEST(TDBAH, 0xFFFFFFFF, 0xFFFFFFFF);
	REG_PATTERN_TEST(TDLEN, 0x000FFF80, 0x000FFFFF);

	REG_SET_AND_CHECK(RCTL, 0xFFFFFFFF, 0x00000000);
	REG_SET_AND_CHECK(RCTL, 0x06DFB3FE, 0x003FFFFB);
	REG_SET_AND_CHECK(TCTL, 0xFFFFFFFF, 0x00000000);

	if(adapter->hw.mac_type >= e1000_82543) {

		REG_SET_AND_CHECK(RCTL, 0x06DFB3FE, 0xFFFFFFFF);
		REG_PATTERN_TEST(RDBAL, 0xFFFFFFF0, 0xFFFFFFFF);
		REG_PATTERN_TEST(TXCW, 0xC000FFFF, 0x0000FFFF);
		REG_PATTERN_TEST(TDBAL, 0xFFFFFFF0, 0xFFFFFFFF);
		REG_PATTERN_TEST(TIDV, 0x0000FFFF, 0x0000FFFF);

		for(i = 0; i < E1000_RAR_ENTRIES; i++) {
			REG_PATTERN_TEST(RA + ((i << 1) << 2), 0xFFFFFFFF,
					 0xFFFFFFFF);
			REG_PATTERN_TEST(RA + (((i << 1) + 1) << 2), 0x8003FFFF,
					 0xFFFFFFFF);
		}

	} else {

		REG_SET_AND_CHECK(RCTL, 0xFFFFFFFF, 0x01FFFFFF);
		REG_PATTERN_TEST(RDBAL, 0xFFFFF000, 0xFFFFFFFF);
		REG_PATTERN_TEST(TXCW, 0x0000FFFF, 0x0000FFFF);
		REG_PATTERN_TEST(TDBAL, 0xFFFFF000, 0xFFFFFFFF);

	}

	for(i = 0; i < E1000_MC_TBL_SIZE; i++)
		REG_PATTERN_TEST(MTA + (i << 2), 0xFFFFFFFF, 0xFFFFFFFF);

	*data = 0;
	return 0;
}

static int
e1000_eeprom_test(struct e1000_adapter *adapter, uint64_t *data)
{
	uint16_t temp;
	uint16_t checksum = 0;
	uint16_t i;

	*data = 0;
	/* Read and add up the contents of the EEPROM */
	for(i = 0; i < (EEPROM_CHECKSUM_REG + 1); i++) {
		if((e1000_read_eeprom(&adapter->hw, i, 1, &temp)) < 0) {
			*data = 1;
			break;
		}
		checksum += temp;
	}

	/* If Checksum is not Correct return error else test passed */
	if((checksum != (uint16_t) EEPROM_SUM) && !(*data))
		*data = 2;

	return *data;
}

static irqreturn_t
e1000_test_intr(int irq,
		void *data,
		struct pt_regs *regs)
{
	struct net_device *netdev = (struct net_device *) data;
	struct e1000_adapter *adapter = netdev_priv(netdev);

	adapter->test_icr |= E1000_READ_REG(&adapter->hw, ICR);

	return IRQ_HANDLED;
}

static int
e1000_intr_test(struct e1000_adapter *adapter, uint64_t *data)
{
	struct net_device *netdev = adapter->netdev;
 	uint32_t mask, i=0, shared_int = TRUE;
 	uint32_t irq = adapter->pdev->irq;

	*data = 0;

	/* Hook up test interrupt handler just for this test */
 	if(!request_irq(irq, &e1000_test_intr, 0, netdev->name, netdev)) {
 		shared_int = FALSE;
 	} else if(request_irq(irq, &e1000_test_intr, SA_SHIRQ,
			      netdev->name, netdev)){
		*data = 1;
		return -1;
	}

	/* Disable all the interrupts */
	E1000_WRITE_REG(&adapter->hw, IMC, 0xFFFFFFFF);
	msec_delay(10);

	/* Test each interrupt */
	for(; i < 10; i++) {

		/* Interrupt to test */
		mask = 1 << i;

 		if(!shared_int) {
 			/* Disable the interrupt to be reported in
 			 * the cause register and then force the same
 			 * interrupt and see if one gets posted.  If
 			 * an interrupt was posted to the bus, the
 			 * test failed.
 			 */
 			adapter->test_icr = 0;
 			E1000_WRITE_REG(&adapter->hw, IMC, mask);
 			E1000_WRITE_REG(&adapter->hw, ICS, mask);
 			msec_delay(10);
 
 			if(adapter->test_icr & mask) {
 				*data = 3;
 				break;
 			}
		}

		/* Enable the interrupt to be reported in
		 * the cause register and then force the same
		 * interrupt and see if one gets posted.  If
		 * an interrupt was not posted to the bus, the
		 * test failed.
		 */
		adapter->test_icr = 0;
		E1000_WRITE_REG(&adapter->hw, IMS, mask);
		E1000_WRITE_REG(&adapter->hw, ICS, mask);
		msec_delay(10);

		if(!(adapter->test_icr & mask)) {
			*data = 4;
			break;
		}

 		if(!shared_int) {
			/* Disable the other interrupts to be reported in
			 * the cause register and then force the other
			 * interrupts and see if any get posted.  If
			 * an interrupt was posted to the bus, the
			 * test failed.
			 */
			adapter->test_icr = 0;
			E1000_WRITE_REG(&adapter->hw, IMC, ~mask & 0x00007FFF);
			E1000_WRITE_REG(&adapter->hw, ICS, ~mask & 0x00007FFF);
			msec_delay(10);

			if(adapter->test_icr) {
				*data = 5;
				break;
			}
		}
	}

	/* Disable all the interrupts */
	E1000_WRITE_REG(&adapter->hw, IMC, 0xFFFFFFFF);
	msec_delay(10);

	/* Unhook test interrupt handler */
	free_irq(irq, netdev);

	return *data;
}

static void
e1000_free_desc_rings(struct e1000_adapter *adapter)
{
	struct e1000_desc_ring *txdr = &adapter->test_tx_ring;
	struct e1000_desc_ring *rxdr = &adapter->test_rx_ring;
	struct pci_dev *pdev = adapter->pdev;
	int i;

	if(txdr->desc && txdr->buffer_info) {
		for(i = 0; i < txdr->count; i++) {
			if(txdr->buffer_info[i].dma)
				pci_unmap_single(pdev, txdr->buffer_info[i].dma,
						 txdr->buffer_info[i].length,
						 PCI_DMA_TODEVICE);
			if(txdr->buffer_info[i].skb)
				dev_kfree_skb(txdr->buffer_info[i].skb);
		}
	}

	if(rxdr->desc && rxdr->buffer_info) {
		for(i = 0; i < rxdr->count; i++) {
			if(rxdr->buffer_info[i].dma)
				pci_unmap_single(pdev, rxdr->buffer_info[i].dma,
						 rxdr->buffer_info[i].length,
						 PCI_DMA_FROMDEVICE);
			if(rxdr->buffer_info[i].skb)
				dev_kfree_skb(rxdr->buffer_info[i].skb);
		}
	}

	if(txdr->desc)
		pci_free_consistent(pdev, txdr->size, txdr->desc, txdr->dma);
	if(rxdr->desc)
		pci_free_consistent(pdev, rxdr->size, rxdr->desc, rxdr->dma);

	if(txdr->buffer_info)
		kfree(txdr->buffer_info);
	if(rxdr->buffer_info)
		kfree(rxdr->buffer_info);

	return;
}

static int
e1000_setup_desc_rings(struct e1000_adapter *adapter)
{
	struct e1000_desc_ring *txdr = &adapter->test_tx_ring;
	struct e1000_desc_ring *rxdr = &adapter->test_rx_ring;
	struct pci_dev *pdev = adapter->pdev;
	uint32_t rctl;
	int size, i, ret_val;

	/* Setup Tx descriptor ring and Tx buffers */

	if(!txdr->count)
		txdr->count = E1000_DEFAULT_TXD;   

	size = txdr->count * sizeof(struct e1000_buffer);
	if(!(txdr->buffer_info = kmalloc(size, GFP_KERNEL))) {
		ret_val = 1;
		goto err_nomem;
	}
	memset(txdr->buffer_info, 0, size);

	txdr->size = txdr->count * sizeof(struct e1000_tx_desc);
	E1000_ROUNDUP(txdr->size, 4096);
	if(!(txdr->desc = pci_alloc_consistent(pdev, txdr->size, &txdr->dma))) {
		ret_val = 2;
		goto err_nomem;
	}
	memset(txdr->desc, 0, txdr->size);
	txdr->next_to_use = txdr->next_to_clean = 0;

	E1000_WRITE_REG(&adapter->hw, TDBAL,
			((uint64_t) txdr->dma & 0x00000000FFFFFFFF));
	E1000_WRITE_REG(&adapter->hw, TDBAH, ((uint64_t) txdr->dma >> 32));
	E1000_WRITE_REG(&adapter->hw, TDLEN,
			txdr->count * sizeof(struct e1000_tx_desc));
	E1000_WRITE_REG(&adapter->hw, TDH, 0);
	E1000_WRITE_REG(&adapter->hw, TDT, 0);
	E1000_WRITE_REG(&adapter->hw, TCTL,
			E1000_TCTL_PSP | E1000_TCTL_EN |
			E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT |
			E1000_FDX_COLLISION_DISTANCE << E1000_COLD_SHIFT);

	for(i = 0; i < txdr->count; i++) {
		struct e1000_tx_desc *tx_desc = E1000_TX_DESC(*txdr, i);
		struct sk_buff *skb;
		unsigned int size = 1024;

		if(!(skb = alloc_skb(size, GFP_KERNEL))) {
			ret_val = 3;
			goto err_nomem;
		}
		skb_put(skb, size);
		txdr->buffer_info[i].skb = skb;
		txdr->buffer_info[i].length = skb->len;
		txdr->buffer_info[i].dma =
			pci_map_single(pdev, skb->data, skb->len,
				       PCI_DMA_TODEVICE);
		tx_desc->buffer_addr = cpu_to_le64(txdr->buffer_info[i].dma);
		tx_desc->lower.data = cpu_to_le32(skb->len);
		tx_desc->lower.data |= cpu_to_le32(E1000_TXD_CMD_EOP |
						   E1000_TXD_CMD_IFCS |
						   E1000_TXD_CMD_RPS);
		tx_desc->upper.data = 0;
	}

	/* Setup Rx descriptor ring and Rx buffers */

	if(!rxdr->count)
		rxdr->count = E1000_DEFAULT_RXD;   

	size = rxdr->count * sizeof(struct e1000_buffer);
	if(!(rxdr->buffer_info = kmalloc(size, GFP_KERNEL))) {
		ret_val = 4;
		goto err_nomem;
	}
	memset(rxdr->buffer_info, 0, size);

	rxdr->size = rxdr->count * sizeof(struct e1000_rx_desc);
	if(!(rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma))) {
		ret_val = 5;
		goto err_nomem;
	}
	memset(rxdr->desc, 0, rxdr->size);
	rxdr->next_to_use = rxdr->next_to_clean = 0;

	rctl = E1000_READ_REG(&adapter->hw, RCTL);
	E1000_WRITE_REG(&adapter->hw, RCTL, rctl & ~E1000_RCTL_EN);
	E1000_WRITE_REG(&adapter->hw, RDBAL,
			((uint64_t) rxdr->dma & 0xFFFFFFFF));
	E1000_WRITE_REG(&adapter->hw, RDBAH, ((uint64_t) rxdr->dma >> 32));
	E1000_WRITE_REG(&adapter->hw, RDLEN, rxdr->size);
	E1000_WRITE_REG(&adapter->hw, RDH, 0);
	E1000_WRITE_REG(&adapter->hw, RDT, 0);
	rctl = E1000_RCTL_EN | E1000_RCTL_BAM | E1000_RCTL_SZ_2048 |
		E1000_RCTL_LBM_NO | E1000_RCTL_RDMTS_HALF |
		(adapter->hw.mc_filter_type << E1000_RCTL_MO_SHIFT);
	E1000_WRITE_REG(&adapter->hw, RCTL, rctl);

	for(i = 0; i < rxdr->count; i++) {
		struct e1000_rx_desc *rx_desc = E1000_RX_DESC(*rxdr, i);
		struct sk_buff *skb;

		if(!(skb = alloc_skb(E1000_RXBUFFER_2048 + NET_IP_ALIGN,
				GFP_KERNEL))) {
			ret_val = 6;
			goto err_nomem;
		}
		skb_reserve(skb, NET_IP_ALIGN);
		rxdr->buffer_info[i].skb = skb;
		rxdr->buffer_info[i].length = E1000_RXBUFFER_2048;
		rxdr->buffer_info[i].dma =
			pci_map_single(pdev, skb->data, E1000_RXBUFFER_2048,
				       PCI_DMA_FROMDEVICE);
		rx_desc->buffer_addr = cpu_to_le64(rxdr->buffer_info[i].dma);
		memset(skb->data, 0x00, skb->len);
	}

	return 0;

err_nomem:
	e1000_free_desc_rings(adapter);
	return ret_val;
}

static void
e1000_phy_disable_receiver(struct e1000_adapter *adapter)
{
	/* Write out to PHY registers 29 and 30 to disable the Receiver. */
	e1000_write_phy_reg(&adapter->hw, 29, 0x001F);
	e1000_write_phy_reg(&adapter->hw, 30, 0x8FFC);
	e1000_write_phy_reg(&adapter->hw, 29, 0x001A);
	e1000_write_phy_reg(&adapter->hw, 30, 0x8FF0);
}

static void
e1000_phy_reset_clk_and_crs(struct e1000_adapter *adapter)
{
	uint16_t phy_reg;

	/* Because we reset the PHY above, we need to re-force TX_CLK in the
	 * Extended PHY Specific Control Register to 25MHz clock.  This
	 * value defaults back to a 2.5MHz clock when the PHY is reset.
	 */
	e1000_read_phy_reg(&adapter->hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_reg);
	phy_reg |= M88E1000_EPSCR_TX_CLK_25;
	e1000_write_phy_reg(&adapter->hw,
		M88E1000_EXT_PHY_SPEC_CTRL, phy_reg);

	/* In addition, because of the s/w reset above, we need to enable
	 * CRS on TX.  This must be set for both full and half duplex
	 * operation.
	 */
	e1000_read_phy_reg(&adapter->hw, M88E1000_PHY_SPEC_CTRL, &phy_reg);
	phy_reg |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
	e1000_write_phy_reg(&adapter->hw,
		M88E1000_PHY_SPEC_CTRL, phy_reg);
}

static int
e1000_nonintegrated_phy_loopback(struct e1000_adapter *adapter)
{
	uint32_t ctrl_reg;
	uint16_t phy_reg;

	/* Setup the Device Control Register for PHY loopback test. */

	ctrl_reg = E1000_READ_REG(&adapter->hw, CTRL);
	ctrl_reg |= (E1000_CTRL_ILOS |		/* Invert Loss-Of-Signal */
		     E1000_CTRL_FRCSPD |	/* Set the Force Speed Bit */
		     E1000_CTRL_FRCDPX |	/* Set the Force Duplex Bit */
		     E1000_CTRL_SPD_1000 |	/* Force Speed to 1000 */
		     E1000_CTRL_FD);		/* Force Duplex to FULL */

	E1000_WRITE_REG(&adapter->hw, CTRL, ctrl_reg);

	/* Read the PHY Specific Control Register (0x10) */
	e1000_read_phy_reg(&adapter->hw, M88E1000_PHY_SPEC_CTRL, &phy_reg);

	/* Clear Auto-Crossover bits in PHY Specific Control Register
	 * (bits 6:5).
	 */
	phy_reg &= ~M88E1000_PSCR_AUTO_X_MODE;
	e1000_write_phy_reg(&adapter->hw, M88E1000_PHY_SPEC_CTRL, phy_reg);

	/* Perform software reset on the PHY */
	e1000_phy_reset(&adapter->hw);

	/* Have to setup TX_CLK and TX_CRS after software reset */
	e1000_phy_reset_clk_and_crs(adapter);

	e1000_write_phy_reg(&adapter->hw, PHY_CTRL, 0x8100);

	/* Wait for reset to complete. */
	udelay(500);

	/* Have to setup TX_CLK and TX_CRS after software reset */
	e1000_phy_reset_clk_and_crs(adapter);

	/* Write out to PHY registers 29 and 30 to disable the Receiver. */
	e1000_phy_disable_receiver(adapter);

	/* Set the loopback bit in the PHY control register. */
	e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &phy_reg);
	phy_reg |= MII_CR_LOOPBACK;
	e1000_write_phy_reg(&adapter->hw, PHY_CTRL, phy_reg);

	/* Setup TX_CLK and TX_CRS one more time. */
	e1000_phy_reset_clk_and_crs(adapter);

	/* Check Phy Configuration */
	e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &phy_reg);
	if(phy_reg != 0x4100)
		 return 9;

	e1000_read_phy_reg(&adapter->hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_reg);
	if(phy_reg != 0x0070)
		return 10;

	e1000_read_phy_reg(&adapter->hw, 29, &phy_reg);
	if(phy_reg != 0x001A)
		return 11;

	return 0;
}

static int
e1000_integrated_phy_loopback(struct e1000_adapter *adapter)
{
	uint32_t ctrl_reg = 0;
	uint32_t stat_reg = 0;

	adapter->hw.autoneg = FALSE;

	if(adapter->hw.phy_type == e1000_phy_m88) {
		/* Auto-MDI/MDIX Off */
		e1000_write_phy_reg(&adapter->hw,
				    M88E1000_PHY_SPEC_CTRL, 0x0808);
		/* reset to update Auto-MDI/MDIX */
		e1000_write_phy_reg(&adapter->hw, PHY_CTRL, 0x9140);
		/* autoneg off */
		e1000_write_phy_reg(&adapter->hw, PHY_CTRL, 0x8140);
	}
	/* force 1000, set loopback */
	e1000_write_phy_reg(&adapter->hw, PHY_CTRL, 0x4140);

	/* Now set up the MAC to the same speed/duplex as the PHY. */
	ctrl_reg = E1000_READ_REG(&adapter->hw, CTRL);
	ctrl_reg &= ~E1000_CTRL_SPD_SEL; /* Clear the speed sel bits */
	ctrl_reg |= (E1000_CTRL_FRCSPD | /* Set the Force Speed Bit */
		     E1000_CTRL_FRCDPX | /* Set the Force Duplex Bit */
		     E1000_CTRL_SPD_1000 |/* Force Speed to 1000 */
		     E1000_CTRL_FD);	 /* Force Duplex to FULL */

	if(adapter->hw.media_type == e1000_media_type_copper &&
	   adapter->hw.phy_type == e1000_phy_m88) {
		ctrl_reg |= E1000_CTRL_ILOS; /* Invert Loss of Signal */
	} else {
		/* Set the ILOS bit on the fiber Nic is half
		 * duplex link is detected. */
		stat_reg = E1000_READ_REG(&adapter->hw, STATUS);
		if((stat_reg & E1000_STATUS_FD) == 0)
			ctrl_reg |= (E1000_CTRL_ILOS | E1000_CTRL_SLU);
	}

	E1000_WRITE_REG(&adapter->hw, CTRL, ctrl_reg);

	/* Disable the receiver on the PHY so when a cable is plugged in, the
	 * PHY does not begin to autoneg when a cable is reconnected to the NIC.
	 */
	if(adapter->hw.phy_type == e1000_phy_m88)
		e1000_phy_disable_receiver(adapter);

	udelay(500);

	return 0;
}

static int
e1000_set_phy_loopback(struct e1000_adapter *adapter)
{
	uint16_t phy_reg = 0;
	uint16_t count = 0;

	switch (adapter->hw.mac_type) {
	case e1000_82543:
		if(adapter->hw.media_type == e1000_media_type_copper) {
			/* Attempt to setup Loopback mode on Non-integrated PHY.
			 * Some PHY registers get corrupted at random, so
			 * attempt this 10 times.
			 */
			while(e1000_nonintegrated_phy_loopback(adapter) &&
			      count++ < 10);
			if(count < 11)
				return 0;
		}
		break;

	case e1000_82544:
	case e1000_82540:
	case e1000_82545:
	case e1000_82545_rev_3:
	case e1000_82546:
	case e1000_82546_rev_3:
	case e1000_82541:
	case e1000_82541_rev_2:
	case e1000_82547:
	case e1000_82547_rev_2:
	case e1000_82573:
		return e1000_integrated_phy_loopback(adapter);
		break;

	default:
		/* Default PHY loopback work is to read the MII
		 * control register and assert bit 14 (loopback mode).
		 */
		e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &phy_reg);
		phy_reg |= MII_CR_LOOPBACK;
		e1000_write_phy_reg(&adapter->hw, PHY_CTRL, phy_reg);
		return 0;
		break;
	}

	return 8;
}

static int
e1000_setup_loopback_test(struct e1000_adapter *adapter)
{
	uint32_t rctl;

	if(adapter->hw.media_type == e1000_media_type_fiber ||
	   adapter->hw.media_type == e1000_media_type_internal_serdes) {
		if(adapter->hw.mac_type == e1000_82545 ||
		   adapter->hw.mac_type == e1000_82546 ||
		   adapter->hw.mac_type == e1000_82545_rev_3 ||
		   adapter->hw.mac_type == e1000_82546_rev_3)
			return e1000_set_phy_loopback(adapter);
		else {
			rctl = E1000_READ_REG(&adapter->hw, RCTL);
			rctl |= E1000_RCTL_LBM_TCVR;
			E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
			return 0;
		}
	} else if(adapter->hw.media_type == e1000_media_type_copper)
		return e1000_set_phy_loopback(adapter);

	return 7;
}

static void
e1000_loopback_cleanup(struct e1000_adapter *adapter)
{
	uint32_t rctl;
	uint16_t phy_reg;

	rctl = E1000_READ_REG(&adapter->hw, RCTL);
	rctl &= ~(E1000_RCTL_LBM_TCVR | E1000_RCTL_LBM_MAC);
	E1000_WRITE_REG(&adapter->hw, RCTL, rctl);

	if(adapter->hw.media_type == e1000_media_type_copper ||
	   ((adapter->hw.media_type == e1000_media_type_fiber ||
	     adapter->hw.media_type == e1000_media_type_internal_serdes) &&
	    (adapter->hw.mac_type == e1000_82545 ||
	     adapter->hw.mac_type == e1000_82546 ||
	     adapter->hw.mac_type == e1000_82545_rev_3 ||
	     adapter->hw.mac_type == e1000_82546_rev_3))) {
		adapter->hw.autoneg = TRUE;
		e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &phy_reg);
		if(phy_reg & MII_CR_LOOPBACK) {
			phy_reg &= ~MII_CR_LOOPBACK;
			e1000_write_phy_reg(&adapter->hw, PHY_CTRL, phy_reg);
			e1000_phy_reset(&adapter->hw);
		}
	}
}

static void
e1000_create_lbtest_frame(struct sk_buff *skb, unsigned int frame_size)
{
	memset(skb->data, 0xFF, frame_size);
	frame_size = (frame_size % 2) ? (frame_size - 1) : frame_size;
	memset(&skb->data[frame_size / 2], 0xAA, frame_size / 2 - 1);
	memset(&skb->data[frame_size / 2 + 10], 0xBE, 1);
	memset(&skb->data[frame_size / 2 + 12], 0xAF, 1);
}

static int
e1000_check_lbtest_frame(struct sk_buff *skb, unsigned int frame_size)
{
	frame_size = (frame_size % 2) ? (frame_size - 1) : frame_size;
	if(*(skb->data + 3) == 0xFF) {
		if((*(skb->data + frame_size / 2 + 10) == 0xBE) &&
		   (*(skb->data + frame_size / 2 + 12) == 0xAF)) {
			return 0;
		}
	}
	return 13;
}

static int
e1000_run_loopback_test(struct e1000_adapter *adapter)
{
	struct e1000_desc_ring *txdr = &adapter->test_tx_ring;
	struct e1000_desc_ring *rxdr = &adapter->test_rx_ring;
	struct pci_dev *pdev = adapter->pdev;
	int i, j, k, l, lc, good_cnt, ret_val=0;
	unsigned long time;

	E1000_WRITE_REG(&adapter->hw, RDT, rxdr->count - 1);

	/* Calculate the loop count based on the largest descriptor ring 
	 * The idea is to wrap the largest ring a number of times using 64
	 * send/receive pairs during each loop
	 */

	if(rxdr->count <= txdr->count)
		lc = ((txdr->count / 64) * 2) + 1;
	else
		lc = ((rxdr->count / 64) * 2) + 1;

	k = l = 0;
	for(j = 0; j <= lc; j++) { /* loop count loop */
		for(i = 0; i < 64; i++) { /* send the packets */
			e1000_create_lbtest_frame(txdr->buffer_info[i].skb, 
					1024);
			pci_dma_sync_single_for_device(pdev, 
					txdr->buffer_info[k].dma,
				    	txdr->buffer_info[k].length,
				    	PCI_DMA_TODEVICE);
			if(unlikely(++k == txdr->count)) k = 0;
		}
		E1000_WRITE_REG(&adapter->hw, TDT, k);
		msec_delay(200);
		time = jiffies; /* set the start time for the receive */
		good_cnt = 0;
		do { /* receive the sent packets */
			pci_dma_sync_single_for_cpu(pdev, 
					rxdr->buffer_info[l].dma,
				    	rxdr->buffer_info[l].length,
				    	PCI_DMA_FROMDEVICE);
	
			ret_val = e1000_check_lbtest_frame(
					rxdr->buffer_info[l].skb,
				   	1024);
			if(!ret_val)
				good_cnt++;
			if(unlikely(++l == rxdr->count)) l = 0;
			/* time + 20 msecs (200 msecs on 2.4) is more than 
			 * enough time to complete the receives, if it's 
			 * exceeded, break and error off
			 */
		} while (good_cnt < 64 && jiffies < (time + 20));
		if(good_cnt != 64) {
			ret_val = 13; /* ret_val is the same as mis-compare */
			break; 
		}
		if(jiffies >= (time + 2)) {
			ret_val = 14; /* error code for time out error */
			break;
		}
	} /* end loop count loop */
	return ret_val;
}

static int
e1000_loopback_test(struct e1000_adapter *adapter, uint64_t *data)
{
	if((*data = e1000_setup_desc_rings(adapter))) goto err_loopback;
	if((*data = e1000_setup_loopback_test(adapter))) goto err_loopback;
	*data = e1000_run_loopback_test(adapter);
	e1000_loopback_cleanup(adapter);
	e1000_free_desc_rings(adapter);
err_loopback:
	return *data;
}

static int
e1000_link_test(struct e1000_adapter *adapter, uint64_t *data)
{
	*data = 0;
	if (adapter->hw.media_type == e1000_media_type_internal_serdes) {
		int i = 0;
		adapter->hw.serdes_link_down = TRUE;

		/* On some blade server designs, link establishment
		 * could take as long as 2-3 minutes */
		do {
			e1000_check_for_link(&adapter->hw);
			if (adapter->hw.serdes_link_down == FALSE)
				return *data;
			msec_delay(20);
		} while (i++ < 3750);

		*data = 1;
	} else {
		e1000_check_for_link(&adapter->hw);
		if(adapter->hw.autoneg)  /* if auto_neg is set wait for it */
			msec_delay(4000);

		if(!(E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_LU)) {
			*data = 1;
		}
	}
	return *data;
}

static int 
e1000_diag_test_count(struct net_device *netdev)
{
	return E1000_TEST_LEN;
}

static void
e1000_diag_test(struct net_device *netdev,
		   struct ethtool_test *eth_test, uint64_t *data)
{
	struct e1000_adapter *adapter = netdev_priv(netdev);
	boolean_t if_running = adapter->ecdev || netif_running(netdev);

	if(eth_test->flags == ETH_TEST_FL_OFFLINE) {
		/* Offline tests */

		/* save speed, duplex, autoneg settings */
		uint16_t autoneg_advertised = adapter->hw.autoneg_advertised;
		uint8_t forced_speed_duplex = adapter->hw.forced_speed_duplex;
		uint8_t autoneg = adapter->hw.autoneg;

		/* Link test performed before hardware reset so autoneg doesn't
		 * interfere with test result */
		if(e1000_link_test(adapter, &data[4]))
			eth_test->flags |= ETH_TEST_FL_FAILED;

		if(if_running)
			e1000_down(adapter);
		else
			e1000_reset(adapter);

		if(e1000_reg_test(adapter, &data[0]))
			eth_test->flags |= ETH_TEST_FL_FAILED;

		e1000_reset(adapter);
		if(e1000_eeprom_test(adapter, &data[1]))
			eth_test->flags |= ETH_TEST_FL_FAILED;

		e1000_reset(adapter);
		if(e1000_intr_test(adapter, &data[2]))
			eth_test->flags |= ETH_TEST_FL_FAILED;

		e1000_reset(adapter);
		if(e1000_loopback_test(adapter, &data[3]))
			eth_test->flags |= ETH_TEST_FL_FAILED;

		/* restore speed, duplex, autoneg settings */
		adapter->hw.autoneg_advertised = autoneg_advertised;
		adapter->hw.forced_speed_duplex = forced_speed_duplex;
		adapter->hw.autoneg = autoneg;

		e1000_reset(adapter);
		if(if_running)
			e1000_up(adapter);
	} else {
		/* Online tests */
		if(e1000_link_test(adapter, &data[4]))
			eth_test->flags |= ETH_TEST_FL_FAILED;

		/* Offline tests aren't run; pass by default */
		data[0] = 0;
		data[1] = 0;
		data[2] = 0;
		data[3] = 0;
	}
}

static void
e1000_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
{
	struct e1000_adapter *adapter = netdev_priv(netdev);
	struct e1000_hw *hw = &adapter->hw;

	switch(adapter->hw.device_id) {
	case E1000_DEV_ID_82542:
	case E1000_DEV_ID_82543GC_FIBER:
	case E1000_DEV_ID_82543GC_COPPER:
	case E1000_DEV_ID_82544EI_FIBER:
	case E1000_DEV_ID_82546EB_QUAD_COPPER:
	case E1000_DEV_ID_82545EM_FIBER:
	case E1000_DEV_ID_82545EM_COPPER:
		wol->supported = 0;
		wol->wolopts   = 0;
		return;

	case E1000_DEV_ID_82546EB_FIBER:
	case E1000_DEV_ID_82546GB_FIBER:
		/* Wake events only supported on port A for dual fiber */
		if(E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1) {
			wol->supported = 0;
			wol->wolopts   = 0;
			return;
		}
		/* Fall Through */

	default:
		wol->supported = WAKE_UCAST | WAKE_MCAST |
				 WAKE_BCAST | WAKE_MAGIC;

		wol->wolopts = 0;
		if(adapter->wol & E1000_WUFC_EX)
			wol->wolopts |= WAKE_UCAST;
		if(adapter->wol & E1000_WUFC_MC)
			wol->wolopts |= WAKE_MCAST;
		if(adapter->wol & E1000_WUFC_BC)
			wol->wolopts |= WAKE_BCAST;
		if(adapter->wol & E1000_WUFC_MAG)
			wol->wolopts |= WAKE_MAGIC;
		return;
	}
}

static int
e1000_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
{
	struct e1000_adapter *adapter = netdev_priv(netdev);
	struct e1000_hw *hw = &adapter->hw;

	switch(adapter->hw.device_id) {
	case E1000_DEV_ID_82542:
	case E1000_DEV_ID_82543GC_FIBER:
	case E1000_DEV_ID_82543GC_COPPER:
	case E1000_DEV_ID_82544EI_FIBER:
	case E1000_DEV_ID_82546EB_QUAD_COPPER:
	case E1000_DEV_ID_82545EM_FIBER:
	case E1000_DEV_ID_82545EM_COPPER:
		return wol->wolopts ? -EOPNOTSUPP : 0;

	case E1000_DEV_ID_82546EB_FIBER:
	case E1000_DEV_ID_82546GB_FIBER:
		/* Wake events only supported on port A for dual fiber */
		if(E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1)
			return wol->wolopts ? -EOPNOTSUPP : 0;
		/* Fall Through */

	default:
		if(wol->wolopts & (WAKE_PHY | WAKE_ARP | WAKE_MAGICSECURE))
			return -EOPNOTSUPP;

		adapter->wol = 0;

		if(wol->wolopts & WAKE_UCAST)
			adapter->wol |= E1000_WUFC_EX;
		if(wol->wolopts & WAKE_MCAST)
			adapter->wol |= E1000_WUFC_MC;
		if(wol->wolopts & WAKE_BCAST)
			adapter->wol |= E1000_WUFC_BC;
		if(wol->wolopts & WAKE_MAGIC)
			adapter->wol |= E1000_WUFC_MAG;
	}

	return 0;
}

/* toggle LED 4 times per second = 2 "blinks" per second */
#define E1000_ID_INTERVAL	(HZ/4)

/* bit defines for adapter->led_status */
#define E1000_LED_ON		0

static void
e1000_led_blink_callback(unsigned long data)
{
	struct e1000_adapter *adapter = (struct e1000_adapter *) data;

	if(test_and_change_bit(E1000_LED_ON, &adapter->led_status))
		e1000_led_off(&adapter->hw);
	else
		e1000_led_on(&adapter->hw);

	mod_timer(&adapter->blink_timer, jiffies + E1000_ID_INTERVAL);
}

static int
e1000_phys_id(struct net_device *netdev, uint32_t data)
{
	struct e1000_adapter *adapter = netdev_priv(netdev);

	if(!data || data > (uint32_t)(MAX_SCHEDULE_TIMEOUT / HZ))
		data = (uint32_t)(MAX_SCHEDULE_TIMEOUT / HZ);

	if(adapter->hw.mac_type < e1000_82573) {
		if(!adapter->blink_timer.function) {
			init_timer(&adapter->blink_timer);
			adapter->blink_timer.function = e1000_led_blink_callback;
			adapter->blink_timer.data = (unsigned long) adapter;
		}
		e1000_setup_led(&adapter->hw);
		mod_timer(&adapter->blink_timer, jiffies);
		msleep_interruptible(data * 1000);
		del_timer_sync(&adapter->blink_timer);
	}
	else {
		E1000_WRITE_REG(&adapter->hw, LEDCTL, (E1000_LEDCTL_LED2_BLINK_RATE |
			E1000_LEDCTL_LED1_BLINK | E1000_LEDCTL_LED2_BLINK | 
			(E1000_LEDCTL_MODE_LED_ON << E1000_LEDCTL_LED2_MODE_SHIFT) |
			(E1000_LEDCTL_MODE_LINK_ACTIVITY << E1000_LEDCTL_LED1_MODE_SHIFT) |
			(E1000_LEDCTL_MODE_LED_OFF << E1000_LEDCTL_LED0_MODE_SHIFT)));
		msleep_interruptible(data * 1000);
	}

	e1000_led_off(&adapter->hw);
	clear_bit(E1000_LED_ON, &adapter->led_status);
	e1000_cleanup_led(&adapter->hw);

	return 0;
}

static int
e1000_nway_reset(struct net_device *netdev)
{
	struct e1000_adapter *adapter = netdev_priv(netdev);
	if (adapter->ecdev || netif_running(netdev)) {
		e1000_down(adapter);
		e1000_up(adapter);
	}
	return 0;
}

static int 
e1000_get_stats_count(struct net_device *netdev)
{
	return E1000_STATS_LEN;
}

static void 
e1000_get_ethtool_stats(struct net_device *netdev, 
		struct ethtool_stats *stats, uint64_t *data)
{
	struct e1000_adapter *adapter = netdev_priv(netdev);
	int i;

	e1000_update_stats(adapter);
	for(i = 0; i < E1000_STATS_LEN; i++) {
		char *p = (char *)adapter+e1000_gstrings_stats[i].stat_offset;	
		data[i] = (e1000_gstrings_stats[i].sizeof_stat == 
			sizeof(uint64_t)) ? *(uint64_t *)p : *(uint32_t *)p;
	}
}

static void 
e1000_get_strings(struct net_device *netdev, uint32_t stringset, uint8_t *data)
{
	int i;

	switch(stringset) {
	case ETH_SS_TEST:
		memcpy(data, *e1000_gstrings_test, 
			E1000_TEST_LEN*ETH_GSTRING_LEN);
		break;
	case ETH_SS_STATS:
		for (i=0; i < E1000_STATS_LEN; i++) {
			memcpy(data + i * ETH_GSTRING_LEN, 
			e1000_gstrings_stats[i].stat_string,
			ETH_GSTRING_LEN);
		}
		break;
	}
}

struct ethtool_ops e1000_ethtool_ops = {
	.get_settings           = e1000_get_settings,
	.set_settings           = e1000_set_settings,
	.get_drvinfo            = e1000_get_drvinfo,
	.get_regs_len           = e1000_get_regs_len,
	.get_regs               = e1000_get_regs,
	.get_wol                = e1000_get_wol,
	.set_wol                = e1000_set_wol,
	.get_msglevel	        = e1000_get_msglevel,
	.set_msglevel	        = e1000_set_msglevel,
	.nway_reset             = e1000_nway_reset,
	.get_link               = ethtool_op_get_link,
	.get_eeprom_len         = e1000_get_eeprom_len,
	.get_eeprom             = e1000_get_eeprom,
	.set_eeprom             = e1000_set_eeprom,
	.get_ringparam          = e1000_get_ringparam,
	.set_ringparam          = e1000_set_ringparam,
	.get_pauseparam		= e1000_get_pauseparam,
	.set_pauseparam		= e1000_set_pauseparam,
	.get_rx_csum		= e1000_get_rx_csum,
	.set_rx_csum		= e1000_set_rx_csum,
	.get_tx_csum		= e1000_get_tx_csum,
	.set_tx_csum		= e1000_set_tx_csum,
	.get_sg			= ethtool_op_get_sg,
	.set_sg			= ethtool_op_set_sg,
#ifdef NETIF_F_TSO
	.get_tso		= ethtool_op_get_tso,
	.set_tso		= e1000_set_tso,
#endif
	.self_test_count        = e1000_diag_test_count,
	.self_test              = e1000_diag_test,
	.get_strings            = e1000_get_strings,
	.phys_id                = e1000_phys_id,
	.get_stats_count        = e1000_get_stats_count,
	.get_ethtool_stats      = e1000_get_ethtool_stats,
};

void e1000_set_ethtool_ops(struct net_device *netdev)
{
	SET_ETHTOOL_OPS(netdev, &e1000_ethtool_ops);
}


<|start_filename|>3rdpart/ethercat-1.5.2/lib/reg_request.c<|end_filename|>
/******************************************************************************
 *
 *  $Id: reg_request.c,v 2c3ccdde3919 2012/11/14 21:12:57 fp $
 *
 *  Copyright (C) 2012  <NAME>, Ingenieurgemeinschaft IgH
 *
 *  This file is part of the IgH EtherCAT master userspace library.
 *
 *  The IgH EtherCAT master userspace library is free software; you can
 *  redistribute it and/or modify it under the terms of the GNU Lesser General
 *  Public License as published by the Free Software Foundation; version 2.1
 *  of the License.
 *
 *  The IgH EtherCAT master userspace library is distributed in the hope that
 *  it will be useful, but WITHOUT ANY WARRANTY; without even the implied
 *  warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public License
 *  along with the IgH EtherCAT master userspace library. If not, see
 *  <http://www.gnu.org/licenses/>.
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 *****************************************************************************/

/** \file
 * EtherCAT register request functions.
 */

/*****************************************************************************/

#include <stdio.h>
#include <string.h>

#include "ioctl.h"
#include "reg_request.h"
#include "slave_config.h"
#include "master.h"

/*****************************************************************************/

void ec_reg_request_clear(ec_reg_request_t *reg)
{
    if (reg->data) {
        free(reg->data);
    }
}

/*****************************************************************************
 * Application interface.
 ****************************************************************************/

uint8_t *ecrt_reg_request_data(ec_reg_request_t *reg)
{
    return reg->data;
}

/*****************************************************************************/

ec_request_state_t ecrt_reg_request_state(ec_reg_request_t *reg)
{
    ec_ioctl_reg_request_t io;
    int ret;

    io.config_index = reg->config->index;
    io.request_index = reg->index;

    ret = ioctl(reg->config->master->fd, EC_IOCTL_REG_REQUEST_STATE, &io);
    if (EC_IOCTL_IS_ERROR(ret)) {
        fprintf(stderr, "Failed to get register request state: %s\n",
                strerror(EC_IOCTL_ERRNO(ret)));
        return EC_REQUEST_ERROR;
    }

    if (io.new_data) { // new data waiting to be copied

        io.data = reg->data;
        io.mem_size = reg->mem_size;

        ret = ioctl(reg->config->master->fd,
                EC_IOCTL_REG_REQUEST_DATA, &io);
        if (EC_IOCTL_IS_ERROR(ret)) {
            fprintf(stderr, "Failed to get register data: %s\n",
                    strerror(EC_IOCTL_ERRNO(ret)));
            return EC_REQUEST_ERROR;
        }
    }

    return io.state;
}

/*****************************************************************************/

void ecrt_reg_request_write(ec_reg_request_t *reg, uint16_t address,
        size_t size)
{
    ec_ioctl_reg_request_t io;
    int ret;

    io.config_index = reg->config->index;
    io.request_index = reg->index;
    io.data = reg->data;
    io.address = address;
    io.transfer_size = size;

    ret = ioctl(reg->config->master->fd, EC_IOCTL_REG_REQUEST_WRITE, &io);
    if (EC_IOCTL_IS_ERROR(ret)) {
        fprintf(stderr, "Failed to command an register write operation: %s\n",
                strerror(EC_IOCTL_ERRNO(ret)));
    }
}

/*****************************************************************************/

void ecrt_reg_request_read(ec_reg_request_t *reg, uint16_t address,
        size_t size)
{
    ec_ioctl_reg_request_t io;
    int ret;

    io.config_index = reg->config->index;
    io.request_index = reg->index;
    io.address = address;
    io.transfer_size = size;

    ret = ioctl(reg->config->master->fd, EC_IOCTL_REG_REQUEST_READ, &io);
    if (EC_IOCTL_IS_ERROR(ret)) {
        fprintf(stderr, "Failed to command an register read operation: %s\n",
                strerror(EC_IOCTL_ERRNO(ret)));
    }
}

/*****************************************************************************/


<|start_filename|>3rdpart/tslib-1.15/tests/fbutils-bsd.c<|end_filename|>
/*
 * fbutils-bsd.c
 *
 * Utility routines for framebuffer interaction
 *
 * Copyright 2002 <NAME> and <NAME>
 *
 * This file is placed under the GPL.  Please see the
 * file COPYING for details.
 *
 * SPDX-License-Identifier: GPL-2.0+
 */

#include "config.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/fcntl.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/time.h>

#include <sys/consio.h>
#include <sys/fbio.h>

#include "font.h"
#include "fbutils.h"

union multiptr {
	unsigned char *p8;
	unsigned short *p16;
	unsigned long *p32;
};

static int fbsize;
static unsigned char *fbuffer;
static unsigned char **line_addr;
static int fb_fd;
static int bytes_per_pixel;
static unsigned colormap[256];

/* extern */
uint32_t xres, yres;
int8_t rotation;

static char *defaultfbdevice = "/dev/fb0";
static char *fbdevice;

int open_framebuffer(void)
{
	int y;
	unsigned addr;
	struct fbtype fb;
	int line_length;

	if ((fbdevice = getenv("TSLIB_FBDEVICE")) == NULL)
		fbdevice = defaultfbdevice;

	fb_fd = open(fbdevice, O_RDWR);
	if (fb_fd == -1) {
		perror("open fbdevice");
		return -1;
	}


	if (ioctl(fb_fd, FBIOGTYPE, &fb) != 0) {
		perror("ioctl(FBIOGTYPE)");
		return -1;
	}

	if (ioctl(fb_fd, FBIO_GETLINEWIDTH, &line_length) != 0) {
		perror("ioctl(FBIO_GETLINEWIDTH)");
		return -1;
	}

	if (rotation & 1) {
		/* 1 or 3 */
		y = fb.fb_height;
		yres = fb.fb_width;
		xres = y;
	} else {
		/* 0 or 2 */
		xres = fb.fb_width;
		yres = fb.fb_height;
	}

	int pagemask = getpagesize() - 1;

	fbsize = ((int) line_length*yres + pagemask) & ~pagemask;

	fbuffer = (unsigned char *)mmap(0, fbsize, PROT_READ | PROT_WRITE, MAP_SHARED, fb_fd, 0);
	if (fbuffer == (unsigned char *)-1) {
		perror("mmap framebuffer");
		close(fb_fd);
		return -1;
	}
	memset(fbuffer, 0, fbsize);

	bytes_per_pixel = (fb.fb_depth + 7) / 8;
	line_addr = malloc(sizeof(line_addr) * fb.fb_height);
	addr = 0;
	for (y = 0; y < fb.fb_height; y++, addr += line_length)
		line_addr[y] = fbuffer + addr;

	return 0;
}

void close_framebuffer(void)
{
	munmap(fbuffer, fbsize);
	close(fb_fd);

	free(line_addr);
}

void put_cross(int x, int y, unsigned colidx)
{
	fprintf(stderr, "%d %d, %d\n", x, y, colidx);

	line(x - 10, y, x - 2, y, colidx);
	line(x + 2, y, x + 10, y, colidx);
	line(x, y - 10, x, y - 2, colidx);
	line(x, y + 2, x, y + 10, colidx);

#if 1
	line(x - 6, y - 9, x - 9, y - 9, colidx + 1);
	line(x - 9, y - 8, x - 9, y - 6, colidx + 1);
	line(x - 9, y + 6, x - 9, y + 9, colidx + 1);
	line(x - 8, y + 9, x - 6, y + 9, colidx + 1);
	line(x + 6, y + 9, x + 9, y + 9, colidx + 1);
	line(x + 9, y + 8, x + 9, y + 6, colidx + 1);
	line(x + 9, y - 6, x + 9, y - 9, colidx + 1);
	line(x + 8, y - 9, x + 6, y - 9, colidx + 1);
#else
	line(x - 7, y - 7, x - 4, y - 4, colidx + 1);
	line(x - 7, y + 7, x - 4, y + 4, colidx + 1);
	line(x + 4, y - 4, x + 7, y - 7, colidx + 1);
	line(x + 4, y + 4, x + 7, y + 7, colidx + 1);
#endif
}

void put_char(int x, int y, int c, int colidx)
{
	int i, j, bits;

	for (i = 0; i < font_vga_8x8.height; i++) {
		bits = font_vga_8x8.data[font_vga_8x8.height * c + i];
		for (j = 0; j < font_vga_8x8.width; j++, bits <<= 1)
			if (bits & 0x80)
				pixel(x + j, y + i, colidx);
	}
}

void put_string(int x, int y, char *s, unsigned colidx)
{
	int i;

	for (i = 0; *s; i++, x += font_vga_8x8.width, s++)
		put_char (x, y, *s, colidx);
}

void put_string_center(int x, int y, char *s, unsigned colidx)
{
	size_t sl = strlen(s);

	put_string(x - (sl / 2) * font_vga_8x8.width,
		   y - font_vga_8x8.height / 2, s, colidx);
}

void setcolor(unsigned colidx, unsigned value)
{
	unsigned res;
	unsigned char red, green, blue;

#ifdef DEBUG
	if (colidx > 255) {
		fprintf(stderr, "WARNING: color index = %u, must be <256\n",
			colidx);
		return;
	}
#endif

	red = (value >> 16) & 0xff;
	green = (value >> 8) & 0xff;
	blue = value & 0xff;

	switch (bytes_per_pixel) {
	case 1:
		res = value;
		break;
	case 2:
		res = ((red >> 3) << 11) | ((green >> 2) << 5) | (blue >> 3);
		break;
	case 3:
	case 4:
	default:
		res = value;

	}
        colormap[colidx] = res;
}

static void __pixel_loc(int32_t x, int32_t y, union multiptr *loc)
{
	switch (rotation) {
	case 0:
	default:
		loc->p8 = line_addr[y] + x * bytes_per_pixel;
		break;
	case 1:
		loc->p8 = line_addr[x] + (yres - y - 1) * bytes_per_pixel;
		break;
	case 2:
		loc->p8 = line_addr[yres - y - 1] + (xres - x - 1) * bytes_per_pixel;
		break;
	case 3:
		loc->p8 = line_addr[xres - x - 1] + y * bytes_per_pixel;
		break;
	}
}

static inline void __setpixel(union multiptr loc, unsigned xormode, unsigned color)
{
	switch (bytes_per_pixel) {
	case 1:
	default:
		if (xormode)
			*loc.p8 ^= color;
		else
			*loc.p8 = color;
		break;
	case 2:
		if (xormode)
			*loc.p16 ^= color;
		else
			*loc.p16 = color;
		break;
	case 3:
		if (xormode) {
			*loc.p8++ ^= (color >> 16) & 0xff;
			*loc.p8++ ^= (color >> 8) & 0xff;
			*loc.p8 ^= color & 0xff;
		} else {
			*loc.p8++ = (color >> 16) & 0xff;
			*loc.p8++ = (color >> 8) & 0xff;
			*loc.p8 = color & 0xff;
		}
		break;
	case 4:
		if (xormode)
			*loc.p32 ^= color;
		else
			*loc.p32 = color;
		break;
	}
}

void pixel(int x, int y, unsigned colidx)
{
	unsigned xormode;
	union multiptr loc;

	if ((x < 0) || ((uint32_t)x >= xres) ||
	    (y < 0) || ((uint32_t)y >= yres))
		return;

	xormode = colidx & XORMODE;
	colidx &= ~XORMODE;

#ifdef DEBUG
	if (colidx > 255) {
		fprintf(stderr, "WARNING: color value = %u, must be <256\n",
			 colidx);
		return;
	}
#endif

	__pixel_loc(x, y, &loc);
	__setpixel(loc, xormode, colormap[colidx]);
}

void line(int x1, int y1, int x2, int y2, unsigned colidx)
{
	int tmp;
	int dx = x2 - x1;
	int dy = y2 - y1;

	if (abs(dx) < abs(dy)) {
		if (y1 > y2) {
			tmp = x1; x1 = x2; x2 = tmp;
			tmp = y1; y1 = y2; y2 = tmp;
			dx = -dx; dy = -dy;
		}
		x1 <<= 16;
		/* dy is apriori >0 */
		dx = (dx << 16) / dy;
		while (y1 <= y2) {
			pixel(x1 >> 16, y1, colidx);
			x1 += dx;
			y1++;
		}
	} else {
		if (x1 > x2) {
			tmp = x1; x1 = x2; x2 = tmp;
			tmp = y1; y1 = y2; y2 = tmp;
			dx = -dx; dy = -dy;
		}
		y1 <<= 16;
		dy = dx ? (dy << 16) / dx : 0;
		while (x1 <= x2) {
			pixel(x1, y1 >> 16, colidx);
			y1 += dy;
			x1++;
		}
	}
}

void rect(int x1, int y1, int x2, int y2, unsigned colidx)
{
	line(x1, y1, x2, y1, colidx);
	line(x2, y1+1, x2, y2-1, colidx);
	line(x2, y2, x1, y2, colidx);
	line(x1, y2-1, x1, y1+1, colidx);
}

void fillrect(int x1, int y1, int x2, int y2, unsigned colidx)
{
	int tmp;
	unsigned xormode;
	union multiptr loc;

	/* Clipping and sanity checking */
	if (x1 > x2) { tmp = x1; x1 = x2; x2 = tmp; }
	if (y1 > y2) { tmp = y1; y1 = y2; y2 = tmp; }
	if (x1 < 0) x1 = 0; if ((uint32_t)x1 >= xres) x1 = xres - 1;
	if (x2 < 0) x2 = 0; if ((uint32_t)x2 >= xres) x2 = xres - 1;
	if (y1 < 0) y1 = 0; if ((uint32_t)y1 >= yres) y1 = yres - 1;
	if (y2 < 0) y2 = 0; if ((uint32_t)y2 >= yres) y2 = yres - 1;

	if ((x1 > x2) || (y1 > y2))
		return;

	xormode = colidx & XORMODE;
	colidx &= ~XORMODE;

#ifdef DEBUG
	if (colidx > 255) {
		fprintf(stderr, "WARNING: color value = %u, must be <256\n",
			 colidx);
		return;
	}
#endif

	colidx = colormap[colidx];

	for (; y1 <= y2; y1++) {
		for (tmp = x1; tmp <= x2; tmp++) {
			__pixel_loc(tmp, y1, &loc);
			__setpixel(loc, xormode, colidx);
			loc.p8 += bytes_per_pixel;
		}
	}
}


<|start_filename|>3rdpart/ethercat-1.5.2/devices/e1000/e1000_hw-3.0-ethercat.h<|end_filename|>
/*******************************************************************************

  Intel PRO/1000 Linux driver
  Copyright(c) 1999 - 2006 Intel Corporation.

  This program is free software; you can redistribute it and/or modify it
  under the terms and conditions of the GNU General Public License,
  version 2, as published by the Free Software Foundation.

  This program is distributed in the hope it will be useful, but WITHOUT
  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  more details.

  You should have received a copy of the GNU General Public License along with
  this program; if not, write to the Free Software Foundation, Inc.,
  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.

  The full GNU General Public License is included in this distribution in
  the file called "COPYING".

  Contact Information:
  Linux NICS <<EMAIL>>
  e1000-devel Mailing List <<EMAIL>>
  Intel Corporation, 5200 N.E. <NAME> Parkway, Hillsboro, OR 97124-6497

*******************************************************************************/

/* e1000_hw.h
 * Structures, enums, and macros for the MAC
 */

#ifndef _E1000_HW_H_
#define _E1000_HW_H_

#include "e1000_osdep-3.0-ethercat.h"


/* Forward declarations of structures used by the shared code */
struct e1000_hw;
struct e1000_hw_stats;

/* Enumerated types specific to the e1000 hardware */
/* Media Access Controllers */
typedef enum {
	e1000_undefined = 0,
	e1000_82542_rev2_0,
	e1000_82542_rev2_1,
	e1000_82543,
	e1000_82544,
	e1000_82540,
	e1000_82545,
	e1000_82545_rev_3,
	e1000_82546,
	e1000_ce4100,
	e1000_82546_rev_3,
	e1000_82541,
	e1000_82541_rev_2,
	e1000_82547,
	e1000_82547_rev_2,
	e1000_num_macs
} e1000_mac_type;

typedef enum {
	e1000_eeprom_uninitialized = 0,
	e1000_eeprom_spi,
	e1000_eeprom_microwire,
	e1000_eeprom_flash,
	e1000_eeprom_none,	/* No NVM support */
	e1000_num_eeprom_types
} e1000_eeprom_type;

/* Media Types */
typedef enum {
	e1000_media_type_copper = 0,
	e1000_media_type_fiber = 1,
	e1000_media_type_internal_serdes = 2,
	e1000_num_media_types
} e1000_media_type;

typedef enum {
	e1000_10_half = 0,
	e1000_10_full = 1,
	e1000_100_half = 2,
	e1000_100_full = 3
} e1000_speed_duplex_type;

/* Flow Control Settings */
typedef enum {
	E1000_FC_NONE = 0,
	E1000_FC_RX_PAUSE = 1,
	E1000_FC_TX_PAUSE = 2,
	E1000_FC_FULL = 3,
	E1000_FC_DEFAULT = 0xFF
} e1000_fc_type;

struct e1000_shadow_ram {
	u16 eeprom_word;
	bool modified;
};

/* PCI bus types */
typedef enum {
	e1000_bus_type_unknown = 0,
	e1000_bus_type_pci,
	e1000_bus_type_pcix,
	e1000_bus_type_reserved
} e1000_bus_type;

/* PCI bus speeds */
typedef enum {
	e1000_bus_speed_unknown = 0,
	e1000_bus_speed_33,
	e1000_bus_speed_66,
	e1000_bus_speed_100,
	e1000_bus_speed_120,
	e1000_bus_speed_133,
	e1000_bus_speed_reserved
} e1000_bus_speed;

/* PCI bus widths */
typedef enum {
	e1000_bus_width_unknown = 0,
	e1000_bus_width_32,
	e1000_bus_width_64,
	e1000_bus_width_reserved
} e1000_bus_width;

/* PHY status info structure and supporting enums */
typedef enum {
	e1000_cable_length_50 = 0,
	e1000_cable_length_50_80,
	e1000_cable_length_80_110,
	e1000_cable_length_110_140,
	e1000_cable_length_140,
	e1000_cable_length_undefined = 0xFF
} e1000_cable_length;

typedef enum {
	e1000_gg_cable_length_60 = 0,
	e1000_gg_cable_length_60_115 = 1,
	e1000_gg_cable_length_115_150 = 2,
	e1000_gg_cable_length_150 = 4
} e1000_gg_cable_length;

typedef enum {
	e1000_igp_cable_length_10 = 10,
	e1000_igp_cable_length_20 = 20,
	e1000_igp_cable_length_30 = 30,
	e1000_igp_cable_length_40 = 40,
	e1000_igp_cable_length_50 = 50,
	e1000_igp_cable_length_60 = 60,
	e1000_igp_cable_length_70 = 70,
	e1000_igp_cable_length_80 = 80,
	e1000_igp_cable_length_90 = 90,
	e1000_igp_cable_length_100 = 100,
	e1000_igp_cable_length_110 = 110,
	e1000_igp_cable_length_115 = 115,
	e1000_igp_cable_length_120 = 120,
	e1000_igp_cable_length_130 = 130,
	e1000_igp_cable_length_140 = 140,
	e1000_igp_cable_length_150 = 150,
	e1000_igp_cable_length_160 = 160,
	e1000_igp_cable_length_170 = 170,
	e1000_igp_cable_length_180 = 180
} e1000_igp_cable_length;

typedef enum {
	e1000_10bt_ext_dist_enable_normal = 0,
	e1000_10bt_ext_dist_enable_lower,
	e1000_10bt_ext_dist_enable_undefined = 0xFF
} e1000_10bt_ext_dist_enable;

typedef enum {
	e1000_rev_polarity_normal = 0,
	e1000_rev_polarity_reversed,
	e1000_rev_polarity_undefined = 0xFF
} e1000_rev_polarity;

typedef enum {
	e1000_downshift_normal = 0,
	e1000_downshift_activated,
	e1000_downshift_undefined = 0xFF
} e1000_downshift;

typedef enum {
	e1000_smart_speed_default = 0,
	e1000_smart_speed_on,
	e1000_smart_speed_off
} e1000_smart_speed;

typedef enum {
	e1000_polarity_reversal_enabled = 0,
	e1000_polarity_reversal_disabled,
	e1000_polarity_reversal_undefined = 0xFF
} e1000_polarity_reversal;

typedef enum {
	e1000_auto_x_mode_manual_mdi = 0,
	e1000_auto_x_mode_manual_mdix,
	e1000_auto_x_mode_auto1,
	e1000_auto_x_mode_auto2,
	e1000_auto_x_mode_undefined = 0xFF
} e1000_auto_x_mode;

typedef enum {
	e1000_1000t_rx_status_not_ok = 0,
	e1000_1000t_rx_status_ok,
	e1000_1000t_rx_status_undefined = 0xFF
} e1000_1000t_rx_status;

typedef enum {
	e1000_phy_m88 = 0,
	e1000_phy_igp,
	e1000_phy_8211,
	e1000_phy_8201,
	e1000_phy_undefined = 0xFF
} e1000_phy_type;

typedef enum {
	e1000_ms_hw_default = 0,
	e1000_ms_force_master,
	e1000_ms_force_slave,
	e1000_ms_auto
} e1000_ms_type;

typedef enum {
	e1000_ffe_config_enabled = 0,
	e1000_ffe_config_active,
	e1000_ffe_config_blocked
} e1000_ffe_config;

typedef enum {
	e1000_dsp_config_disabled = 0,
	e1000_dsp_config_enabled,
	e1000_dsp_config_activated,
	e1000_dsp_config_undefined = 0xFF
} e1000_dsp_config;

struct e1000_phy_info {
	e1000_cable_length cable_length;
	e1000_10bt_ext_dist_enable extended_10bt_distance;
	e1000_rev_polarity cable_polarity;
	e1000_downshift downshift;
	e1000_polarity_reversal polarity_correction;
	e1000_auto_x_mode mdix_mode;
	e1000_1000t_rx_status local_rx;
	e1000_1000t_rx_status remote_rx;
};

struct e1000_phy_stats {
	u32 idle_errors;
	u32 receive_errors;
};

struct e1000_eeprom_info {
	e1000_eeprom_type type;
	u16 word_size;
	u16 opcode_bits;
	u16 address_bits;
	u16 delay_usec;
	u16 page_size;
};

/* Flex ASF Information */
#define E1000_HOST_IF_MAX_SIZE  2048

typedef enum {
	e1000_byte_align = 0,
	e1000_word_align = 1,
	e1000_dword_align = 2
} e1000_align_type;

/* Error Codes */
#define E1000_SUCCESS      0
#define E1000_ERR_EEPROM   1
#define E1000_ERR_PHY      2
#define E1000_ERR_CONFIG   3
#define E1000_ERR_PARAM    4
#define E1000_ERR_MAC_TYPE 5
#define E1000_ERR_PHY_TYPE 6
#define E1000_ERR_RESET   9
#define E1000_ERR_MASTER_REQUESTS_PENDING 10
#define E1000_ERR_HOST_INTERFACE_COMMAND 11
#define E1000_BLK_PHY_RESET   12

#define E1000_BYTE_SWAP_WORD(_value) ((((_value) & 0x00ff) << 8) | \
                                     (((_value) & 0xff00) >> 8))

/* Function prototypes */
/* Initialization */
s32 e1000_reset_hw(struct e1000_hw *hw);
s32 e1000_init_hw(struct e1000_hw *hw);
s32 e1000_set_mac_type(struct e1000_hw *hw);
void e1000_set_media_type(struct e1000_hw *hw);

/* Link Configuration */
s32 e1000_setup_link(struct e1000_hw *hw);
s32 e1000_phy_setup_autoneg(struct e1000_hw *hw);
void e1000_config_collision_dist(struct e1000_hw *hw);
s32 e1000_check_for_link(struct e1000_hw *hw);
s32 e1000_get_speed_and_duplex(struct e1000_hw *hw, u16 * speed, u16 * duplex);
s32 e1000_force_mac_fc(struct e1000_hw *hw);

/* PHY */
s32 e1000_read_phy_reg(struct e1000_hw *hw, u32 reg_addr, u16 * phy_data);
s32 e1000_write_phy_reg(struct e1000_hw *hw, u32 reg_addr, u16 data);
s32 e1000_phy_hw_reset(struct e1000_hw *hw);
s32 e1000_phy_reset(struct e1000_hw *hw);
s32 e1000_phy_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info);
s32 e1000_validate_mdi_setting(struct e1000_hw *hw);

/* EEPROM Functions */
s32 e1000_init_eeprom_params(struct e1000_hw *hw);

/* MNG HOST IF functions */
u32 e1000_enable_mng_pass_thru(struct e1000_hw *hw);

#define E1000_MNG_DHCP_TX_PAYLOAD_CMD   64
#define E1000_HI_MAX_MNG_DATA_LENGTH    0x6F8	/* Host Interface data length */

#define E1000_MNG_DHCP_COMMAND_TIMEOUT  10	/* Time in ms to process MNG command */
#define E1000_MNG_DHCP_COOKIE_OFFSET    0x6F0	/* Cookie offset */
#define E1000_MNG_DHCP_COOKIE_LENGTH    0x10	/* Cookie length */
#define E1000_MNG_IAMT_MODE             0x3
#define E1000_MNG_ICH_IAMT_MODE         0x2
#define E1000_IAMT_SIGNATURE            0x544D4149	/* Intel(R) Active Management Technology signature */

#define E1000_MNG_DHCP_COOKIE_STATUS_PARSING_SUPPORT 0x1	/* DHCP parsing enabled */
#define E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT    0x2	/* DHCP parsing enabled */
#define E1000_VFTA_ENTRY_SHIFT                       0x5
#define E1000_VFTA_ENTRY_MASK                        0x7F
#define E1000_VFTA_ENTRY_BIT_SHIFT_MASK              0x1F

struct e1000_host_mng_command_header {
	u8 command_id;
	u8 checksum;
	u16 reserved1;
	u16 reserved2;
	u16 command_length;
};

struct e1000_host_mng_command_info {
	struct e1000_host_mng_command_header command_header;	/* Command Head/Command Result Head has 4 bytes */
	u8 command_data[E1000_HI_MAX_MNG_DATA_LENGTH];	/* Command data can length 0..0x658 */
};
#ifdef __BIG_ENDIAN
struct e1000_host_mng_dhcp_cookie {
	u32 signature;
	u16 vlan_id;
	u8 reserved0;
	u8 status;
	u32 reserved1;
	u8 checksum;
	u8 reserved3;
	u16 reserved2;
};
#else
struct e1000_host_mng_dhcp_cookie {
	u32 signature;
	u8 status;
	u8 reserved0;
	u16 vlan_id;
	u32 reserved1;
	u16 reserved2;
	u8 reserved3;
	u8 checksum;
};
#endif

bool e1000_check_mng_mode(struct e1000_hw *hw);
s32 e1000_read_eeprom(struct e1000_hw *hw, u16 reg, u16 words, u16 * data);
s32 e1000_validate_eeprom_checksum(struct e1000_hw *hw);
s32 e1000_update_eeprom_checksum(struct e1000_hw *hw);
s32 e1000_write_eeprom(struct e1000_hw *hw, u16 reg, u16 words, u16 * data);
s32 e1000_read_mac_addr(struct e1000_hw *hw);

/* Filters (multicast, vlan, receive) */
u32 e1000_hash_mc_addr(struct e1000_hw *hw, u8 * mc_addr);
void e1000_mta_set(struct e1000_hw *hw, u32 hash_value);
void e1000_rar_set(struct e1000_hw *hw, u8 * mc_addr, u32 rar_index);
void e1000_write_vfta(struct e1000_hw *hw, u32 offset, u32 value);

/* LED functions */
s32 e1000_setup_led(struct e1000_hw *hw);
s32 e1000_cleanup_led(struct e1000_hw *hw);
s32 e1000_led_on(struct e1000_hw *hw);
s32 e1000_led_off(struct e1000_hw *hw);
s32 e1000_blink_led_start(struct e1000_hw *hw);

/* Adaptive IFS Functions */

/* Everything else */
void e1000_reset_adaptive(struct e1000_hw *hw);
void e1000_update_adaptive(struct e1000_hw *hw);
void e1000_tbi_adjust_stats(struct e1000_hw *hw, struct e1000_hw_stats *stats,
			    u32 frame_len, u8 * mac_addr);
void e1000_get_bus_info(struct e1000_hw *hw);
void e1000_pci_set_mwi(struct e1000_hw *hw);
void e1000_pci_clear_mwi(struct e1000_hw *hw);
void e1000_pcix_set_mmrbc(struct e1000_hw *hw, int mmrbc);
int e1000_pcix_get_mmrbc(struct e1000_hw *hw);
/* Port I/O is only supported on 82544 and newer */
void e1000_io_write(struct e1000_hw *hw, unsigned long port, u32 value);

#define E1000_READ_REG_IO(a, reg) \
    e1000_read_reg_io((a), E1000_##reg)
#define E1000_WRITE_REG_IO(a, reg, val) \
    e1000_write_reg_io((a), E1000_##reg, val)

/* PCI Device IDs */
#define E1000_DEV_ID_82542               0x1000
#define E1000_DEV_ID_82543GC_FIBER       0x1001
#define E1000_DEV_ID_82543GC_COPPER      0x1004
#define E1000_DEV_ID_82544EI_COPPER      0x1008
#define E1000_DEV_ID_82544EI_FIBER       0x1009
#define E1000_DEV_ID_82544GC_COPPER      0x100C
#define E1000_DEV_ID_82544GC_LOM         0x100D
#define E1000_DEV_ID_82540EM             0x100E
#define E1000_DEV_ID_82540EM_LOM         0x1015
#define E1000_DEV_ID_82540EP_LOM         0x1016
#define E1000_DEV_ID_82540EP             0x1017
#define E1000_DEV_ID_82540EP_LP          0x101E
#define E1000_DEV_ID_82545EM_COPPER      0x100F
#define E1000_DEV_ID_82545EM_FIBER       0x1011
#define E1000_DEV_ID_82545GM_COPPER      0x1026
#define E1000_DEV_ID_82545GM_FIBER       0x1027
#define E1000_DEV_ID_82545GM_SERDES      0x1028
#define E1000_DEV_ID_82546EB_COPPER      0x1010
#define E1000_DEV_ID_82546EB_FIBER       0x1012
#define E1000_DEV_ID_82546EB_QUAD_COPPER 0x101D
#define E1000_DEV_ID_82541EI             0x1013
#define E1000_DEV_ID_82541EI_MOBILE      0x1018
#define E1000_DEV_ID_82541ER_LOM         0x1014
#define E1000_DEV_ID_82541ER             0x1078
#define E1000_DEV_ID_82547GI             0x1075
#define E1000_DEV_ID_82541GI             0x1076
#define E1000_DEV_ID_82541GI_MOBILE      0x1077
#define E1000_DEV_ID_82541GI_LF          0x107C
#define E1000_DEV_ID_82546GB_COPPER      0x1079
#define E1000_DEV_ID_82546GB_FIBER       0x107A
#define E1000_DEV_ID_82546GB_SERDES      0x107B
#define E1000_DEV_ID_82546GB_PCIE        0x108A
#define E1000_DEV_ID_82546GB_QUAD_COPPER 0x1099
#define E1000_DEV_ID_82547EI             0x1019
#define E1000_DEV_ID_82547EI_MOBILE      0x101A
#define E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3 0x10B5
#define E1000_DEV_ID_INTEL_CE4100_GBE    0x2E6E

#define NODE_ADDRESS_SIZE 6
#define ETH_LENGTH_OF_ADDRESS 6

/* MAC decode size is 128K - This is the size of BAR0 */
#define MAC_DECODE_SIZE (128 * 1024)

#define E1000_82542_2_0_REV_ID 2
#define E1000_82542_2_1_REV_ID 3
#define E1000_REVISION_0       0
#define E1000_REVISION_1       1
#define E1000_REVISION_2       2
#define E1000_REVISION_3       3

#define SPEED_10    10
#define SPEED_100   100
#define SPEED_1000  1000
#define HALF_DUPLEX 1
#define FULL_DUPLEX 2

/* The sizes (in bytes) of a ethernet packet */
#define ENET_HEADER_SIZE             14
#define MINIMUM_ETHERNET_FRAME_SIZE  64	/* With FCS */
#define ETHERNET_FCS_SIZE            4
#define MINIMUM_ETHERNET_PACKET_SIZE \
    (MINIMUM_ETHERNET_FRAME_SIZE - ETHERNET_FCS_SIZE)
#define CRC_LENGTH                   ETHERNET_FCS_SIZE
#define MAX_JUMBO_FRAME_SIZE         0x3F00

/* 802.1q VLAN Packet Sizes */
#define VLAN_TAG_SIZE  4	/* 802.3ac tag (not DMAed) */

/* Ethertype field values */
#define ETHERNET_IEEE_VLAN_TYPE 0x8100	/* 802.3ac packet */
#define ETHERNET_IP_TYPE        0x0800	/* IP packets */
#define ETHERNET_ARP_TYPE       0x0806	/* Address Resolution Protocol (ARP) */

/* Packet Header defines */
#define IP_PROTOCOL_TCP    6
#define IP_PROTOCOL_UDP    0x11

/* This defines the bits that are set in the Interrupt Mask
 * Set/Read Register.  Each bit is documented below:
 *   o RXDMT0 = Receive Descriptor Minimum Threshold hit (ring 0)
 *   o RXSEQ  = Receive Sequence Error
 */
#define POLL_IMS_ENABLE_MASK ( \
    E1000_IMS_RXDMT0 |         \
    E1000_IMS_RXSEQ)

/* This defines the bits that are set in the Interrupt Mask
 * Set/Read Register.  Each bit is documented below:
 *   o RXT0   = Receiver Timer Interrupt (ring 0)
 *   o TXDW   = Transmit Descriptor Written Back
 *   o RXDMT0 = Receive Descriptor Minimum Threshold hit (ring 0)
 *   o RXSEQ  = Receive Sequence Error
 *   o LSC    = Link Status Change
 */
#define IMS_ENABLE_MASK ( \
    E1000_IMS_RXT0   |    \
    E1000_IMS_TXDW   |    \
    E1000_IMS_RXDMT0 |    \
    E1000_IMS_RXSEQ  |    \
    E1000_IMS_LSC)

/* Number of high/low register pairs in the RAR. The RAR (Receive Address
 * Registers) holds the directed and multicast addresses that we monitor. We
 * reserve one of these spots for our directed address, allowing us room for
 * E1000_RAR_ENTRIES - 1 multicast addresses.
 */
#define E1000_RAR_ENTRIES 15

#define MIN_NUMBER_OF_DESCRIPTORS  8
#define MAX_NUMBER_OF_DESCRIPTORS  0xFFF8

/* Receive Descriptor */
struct e1000_rx_desc {
	__le64 buffer_addr;	/* Address of the descriptor's data buffer */
	__le16 length;		/* Length of data DMAed into data buffer */
	__le16 csum;		/* Packet checksum */
	u8 status;		/* Descriptor status */
	u8 errors;		/* Descriptor Errors */
	__le16 special;
};

/* Receive Descriptor - Extended */
union e1000_rx_desc_extended {
	struct {
		__le64 buffer_addr;
		__le64 reserved;
	} read;
	struct {
		struct {
			__le32 mrq;	/* Multiple Rx Queues */
			union {
				__le32 rss;	/* RSS Hash */
				struct {
					__le16 ip_id;	/* IP id */
					__le16 csum;	/* Packet Checksum */
				} csum_ip;
			} hi_dword;
		} lower;
		struct {
			__le32 status_error;	/* ext status/error */
			__le16 length;
			__le16 vlan;	/* VLAN tag */
		} upper;
	} wb;			/* writeback */
};

#define MAX_PS_BUFFERS 4
/* Receive Descriptor - Packet Split */
union e1000_rx_desc_packet_split {
	struct {
		/* one buffer for protocol header(s), three data buffers */
		__le64 buffer_addr[MAX_PS_BUFFERS];
	} read;
	struct {
		struct {
			__le32 mrq;	/* Multiple Rx Queues */
			union {
				__le32 rss;	/* RSS Hash */
				struct {
					__le16 ip_id;	/* IP id */
					__le16 csum;	/* Packet Checksum */
				} csum_ip;
			} hi_dword;
		} lower;
		struct {
			__le32 status_error;	/* ext status/error */
			__le16 length0;	/* length of buffer 0 */
			__le16 vlan;	/* VLAN tag */
		} middle;
		struct {
			__le16 header_status;
			__le16 length[3];	/* length of buffers 1-3 */
		} upper;
		__le64 reserved;
	} wb;			/* writeback */
};

/* Receive Descriptor bit definitions */
#define E1000_RXD_STAT_DD       0x01	/* Descriptor Done */
#define E1000_RXD_STAT_EOP      0x02	/* End of Packet */
#define E1000_RXD_STAT_IXSM     0x04	/* Ignore checksum */
#define E1000_RXD_STAT_VP       0x08	/* IEEE VLAN Packet */
#define E1000_RXD_STAT_UDPCS    0x10	/* UDP xsum calculated */
#define E1000_RXD_STAT_TCPCS    0x20	/* TCP xsum calculated */
#define E1000_RXD_STAT_IPCS     0x40	/* IP xsum calculated */
#define E1000_RXD_STAT_PIF      0x80	/* passed in-exact filter */
#define E1000_RXD_STAT_IPIDV    0x200	/* IP identification valid */
#define E1000_RXD_STAT_UDPV     0x400	/* Valid UDP checksum */
#define E1000_RXD_STAT_ACK      0x8000	/* ACK Packet indication */
#define E1000_RXD_ERR_CE        0x01	/* CRC Error */
#define E1000_RXD_ERR_SE        0x02	/* Symbol Error */
#define E1000_RXD_ERR_SEQ       0x04	/* Sequence Error */
#define E1000_RXD_ERR_CXE       0x10	/* Carrier Extension Error */
#define E1000_RXD_ERR_TCPE      0x20	/* TCP/UDP Checksum Error */
#define E1000_RXD_ERR_IPE       0x40	/* IP Checksum Error */
#define E1000_RXD_ERR_RXE       0x80	/* Rx Data Error */
#define E1000_RXD_SPC_VLAN_MASK 0x0FFF	/* VLAN ID is in lower 12 bits */
#define E1000_RXD_SPC_PRI_MASK  0xE000	/* Priority is in upper 3 bits */
#define E1000_RXD_SPC_PRI_SHIFT 13
#define E1000_RXD_SPC_CFI_MASK  0x1000	/* CFI is bit 12 */
#define E1000_RXD_SPC_CFI_SHIFT 12

#define E1000_RXDEXT_STATERR_CE    0x01000000
#define E1000_RXDEXT_STATERR_SE    0x02000000
#define E1000_RXDEXT_STATERR_SEQ   0x04000000
#define E1000_RXDEXT_STATERR_CXE   0x10000000
#define E1000_RXDEXT_STATERR_TCPE  0x20000000
#define E1000_RXDEXT_STATERR_IPE   0x40000000
#define E1000_RXDEXT_STATERR_RXE   0x80000000

#define E1000_RXDPS_HDRSTAT_HDRSP        0x00008000
#define E1000_RXDPS_HDRSTAT_HDRLEN_MASK  0x000003FF

/* mask to determine if packets should be dropped due to frame errors */
#define E1000_RXD_ERR_FRAME_ERR_MASK ( \
    E1000_RXD_ERR_CE  |                \
    E1000_RXD_ERR_SE  |                \
    E1000_RXD_ERR_SEQ |                \
    E1000_RXD_ERR_CXE |                \
    E1000_RXD_ERR_RXE)

/* Same mask, but for extended and packet split descriptors */
#define E1000_RXDEXT_ERR_FRAME_ERR_MASK ( \
    E1000_RXDEXT_STATERR_CE  |            \
    E1000_RXDEXT_STATERR_SE  |            \
    E1000_RXDEXT_STATERR_SEQ |            \
    E1000_RXDEXT_STATERR_CXE |            \
    E1000_RXDEXT_STATERR_RXE)

/* Transmit Descriptor */
struct e1000_tx_desc {
	__le64 buffer_addr;	/* Address of the descriptor's data buffer */
	union {
		__le32 data;
		struct {
			__le16 length;	/* Data buffer length */
			u8 cso;	/* Checksum offset */
			u8 cmd;	/* Descriptor control */
		} flags;
	} lower;
	union {
		__le32 data;
		struct {
			u8 status;	/* Descriptor status */
			u8 css;	/* Checksum start */
			__le16 special;
		} fields;
	} upper;
};

/* Transmit Descriptor bit definitions */
#define E1000_TXD_DTYP_D     0x00100000	/* Data Descriptor */
#define E1000_TXD_DTYP_C     0x00000000	/* Context Descriptor */
#define E1000_TXD_POPTS_IXSM 0x01	/* Insert IP checksum */
#define E1000_TXD_POPTS_TXSM 0x02	/* Insert TCP/UDP checksum */
#define E1000_TXD_CMD_EOP    0x01000000	/* End of Packet */
#define E1000_TXD_CMD_IFCS   0x02000000	/* Insert FCS (Ethernet CRC) */
#define E1000_TXD_CMD_IC     0x04000000	/* Insert Checksum */
#define E1000_TXD_CMD_RS     0x08000000	/* Report Status */
#define E1000_TXD_CMD_RPS    0x10000000	/* Report Packet Sent */
#define E1000_TXD_CMD_DEXT   0x20000000	/* Descriptor extension (0 = legacy) */
#define E1000_TXD_CMD_VLE    0x40000000	/* Add VLAN tag */
#define E1000_TXD_CMD_IDE    0x80000000	/* Enable Tidv register */
#define E1000_TXD_STAT_DD    0x00000001	/* Descriptor Done */
#define E1000_TXD_STAT_EC    0x00000002	/* Excess Collisions */
#define E1000_TXD_STAT_LC    0x00000004	/* Late Collisions */
#define E1000_TXD_STAT_TU    0x00000008	/* Transmit underrun */
#define E1000_TXD_CMD_TCP    0x01000000	/* TCP packet */
#define E1000_TXD_CMD_IP     0x02000000	/* IP packet */
#define E1000_TXD_CMD_TSE    0x04000000	/* TCP Seg enable */
#define E1000_TXD_STAT_TC    0x00000004	/* Tx Underrun */

/* Offload Context Descriptor */
struct e1000_context_desc {
	union {
		__le32 ip_config;
		struct {
			u8 ipcss;	/* IP checksum start */
			u8 ipcso;	/* IP checksum offset */
			__le16 ipcse;	/* IP checksum end */
		} ip_fields;
	} lower_setup;
	union {
		__le32 tcp_config;
		struct {
			u8 tucss;	/* TCP checksum start */
			u8 tucso;	/* TCP checksum offset */
			__le16 tucse;	/* TCP checksum end */
		} tcp_fields;
	} upper_setup;
	__le32 cmd_and_length;	/* */
	union {
		__le32 data;
		struct {
			u8 status;	/* Descriptor status */
			u8 hdr_len;	/* Header length */
			__le16 mss;	/* Maximum segment size */
		} fields;
	} tcp_seg_setup;
};

/* Offload data descriptor */
struct e1000_data_desc {
	__le64 buffer_addr;	/* Address of the descriptor's buffer address */
	union {
		__le32 data;
		struct {
			__le16 length;	/* Data buffer length */
			u8 typ_len_ext;	/* */
			u8 cmd;	/* */
		} flags;
	} lower;
	union {
		__le32 data;
		struct {
			u8 status;	/* Descriptor status */
			u8 popts;	/* Packet Options */
			__le16 special;	/* */
		} fields;
	} upper;
};

/* Filters */
#define E1000_NUM_UNICAST          16	/* Unicast filter entries */
#define E1000_MC_TBL_SIZE          128	/* Multicast Filter Table (4096 bits) */
#define E1000_VLAN_FILTER_TBL_SIZE 128	/* VLAN Filter Table (4096 bits) */

/* Receive Address Register */
struct e1000_rar {
	volatile __le32 low;	/* receive address low */
	volatile __le32 high;	/* receive address high */
};

/* Number of entries in the Multicast Table Array (MTA). */
#define E1000_NUM_MTA_REGISTERS 128

/* IPv4 Address Table Entry */
struct e1000_ipv4_at_entry {
	volatile u32 ipv4_addr;	/* IP Address (RW) */
	volatile u32 reserved;
};

/* Four wakeup IP addresses are supported */
#define E1000_WAKEUP_IP_ADDRESS_COUNT_MAX 4
#define E1000_IP4AT_SIZE                  E1000_WAKEUP_IP_ADDRESS_COUNT_MAX
#define E1000_IP6AT_SIZE                  1

/* IPv6 Address Table Entry */
struct e1000_ipv6_at_entry {
	volatile u8 ipv6_addr[16];
};

/* Flexible Filter Length Table Entry */
struct e1000_fflt_entry {
	volatile u32 length;	/* Flexible Filter Length (RW) */
	volatile u32 reserved;
};

/* Flexible Filter Mask Table Entry */
struct e1000_ffmt_entry {
	volatile u32 mask;	/* Flexible Filter Mask (RW) */
	volatile u32 reserved;
};

/* Flexible Filter Value Table Entry */
struct e1000_ffvt_entry {
	volatile u32 value;	/* Flexible Filter Value (RW) */
	volatile u32 reserved;
};

/* Four Flexible Filters are supported */
#define E1000_FLEXIBLE_FILTER_COUNT_MAX 4

/* Each Flexible Filter is at most 128 (0x80) bytes in length */
#define E1000_FLEXIBLE_FILTER_SIZE_MAX  128

#define E1000_FFLT_SIZE E1000_FLEXIBLE_FILTER_COUNT_MAX
#define E1000_FFMT_SIZE E1000_FLEXIBLE_FILTER_SIZE_MAX
#define E1000_FFVT_SIZE E1000_FLEXIBLE_FILTER_SIZE_MAX

#define E1000_DISABLE_SERDES_LOOPBACK   0x0400

/* Register Set. (82543, 82544)
 *
 * Registers are defined to be 32 bits and  should be accessed as 32 bit values.
 * These registers are physically located on the NIC, but are mapped into the
 * host memory address space.
 *
 * RW - register is both readable and writable
 * RO - register is read only
 * WO - register is write only
 * R/clr - register is read only and is cleared when read
 * A - register array
 */
#define E1000_CTRL     0x00000	/* Device Control - RW */
#define E1000_CTRL_DUP 0x00004	/* Device Control Duplicate (Shadow) - RW */
#define E1000_STATUS   0x00008	/* Device Status - RO */
#define E1000_EECD     0x00010	/* EEPROM/Flash Control - RW */
#define E1000_EERD     0x00014	/* EEPROM Read - RW */
#define E1000_CTRL_EXT 0x00018	/* Extended Device Control - RW */
#define E1000_FLA      0x0001C	/* Flash Access - RW */
#define E1000_MDIC     0x00020	/* MDI Control - RW */

extern void __iomem *ce4100_gbe_mdio_base_virt;
#define INTEL_CE_GBE_MDIO_RCOMP_BASE    (ce4100_gbe_mdio_base_virt)
#define E1000_MDIO_STS  (INTEL_CE_GBE_MDIO_RCOMP_BASE + 0)
#define E1000_MDIO_CMD  (INTEL_CE_GBE_MDIO_RCOMP_BASE + 4)
#define E1000_MDIO_DRV  (INTEL_CE_GBE_MDIO_RCOMP_BASE + 8)
#define E1000_MDC_CMD   (INTEL_CE_GBE_MDIO_RCOMP_BASE + 0xC)
#define E1000_RCOMP_CTL (INTEL_CE_GBE_MDIO_RCOMP_BASE + 0x20)
#define E1000_RCOMP_STS (INTEL_CE_GBE_MDIO_RCOMP_BASE + 0x24)

#define E1000_SCTL     0x00024	/* SerDes Control - RW */
#define E1000_FEXTNVM  0x00028	/* Future Extended NVM register */
#define E1000_FCAL     0x00028	/* Flow Control Address Low - RW */
#define E1000_FCAH     0x0002C	/* Flow Control Address High -RW */
#define E1000_FCT      0x00030	/* Flow Control Type - RW */
#define E1000_VET      0x00038	/* VLAN Ether Type - RW */
#define E1000_ICR      0x000C0	/* Interrupt Cause Read - R/clr */
#define E1000_ITR      0x000C4	/* Interrupt Throttling Rate - RW */
#define E1000_ICS      0x000C8	/* Interrupt Cause Set - WO */
#define E1000_IMS      0x000D0	/* Interrupt Mask Set - RW */
#define E1000_IMC      0x000D8	/* Interrupt Mask Clear - WO */
#define E1000_IAM      0x000E0	/* Interrupt Acknowledge Auto Mask */

/* Auxiliary Control Register. This register is CE4100 specific,
 * RMII/RGMII function is switched by this register - RW
 * Following are bits definitions of the Auxiliary Control Register
 */
#define E1000_CTL_AUX  0x000E0
#define E1000_CTL_AUX_END_SEL_SHIFT     10
#define E1000_CTL_AUX_ENDIANESS_SHIFT   8
#define E1000_CTL_AUX_RGMII_RMII_SHIFT  0

/* descriptor and packet transfer use CTL_AUX.ENDIANESS */
#define E1000_CTL_AUX_DES_PKT   (0x0 << E1000_CTL_AUX_END_SEL_SHIFT)
/* descriptor use CTL_AUX.ENDIANESS, packet use default */
#define E1000_CTL_AUX_DES       (0x1 << E1000_CTL_AUX_END_SEL_SHIFT)
/* descriptor use default, packet use CTL_AUX.ENDIANESS */
#define E1000_CTL_AUX_PKT       (0x2 << E1000_CTL_AUX_END_SEL_SHIFT)
/* all use CTL_AUX.ENDIANESS */
#define E1000_CTL_AUX_ALL       (0x3 << E1000_CTL_AUX_END_SEL_SHIFT)

#define E1000_CTL_AUX_RGMII     (0x0 << E1000_CTL_AUX_RGMII_RMII_SHIFT)
#define E1000_CTL_AUX_RMII      (0x1 << E1000_CTL_AUX_RGMII_RMII_SHIFT)

/* LW little endian, Byte big endian */
#define E1000_CTL_AUX_LWLE_BBE  (0x0 << E1000_CTL_AUX_ENDIANESS_SHIFT)
#define E1000_CTL_AUX_LWLE_BLE  (0x1 << E1000_CTL_AUX_ENDIANESS_SHIFT)
#define E1000_CTL_AUX_LWBE_BBE  (0x2 << E1000_CTL_AUX_ENDIANESS_SHIFT)
#define E1000_CTL_AUX_LWBE_BLE  (0x3 << E1000_CTL_AUX_ENDIANESS_SHIFT)

#define E1000_RCTL     0x00100	/* RX Control - RW */
#define E1000_RDTR1    0x02820	/* RX Delay Timer (1) - RW */
#define E1000_RDBAL1   0x02900	/* RX Descriptor Base Address Low (1) - RW */
#define E1000_RDBAH1   0x02904	/* RX Descriptor Base Address High (1) - RW */
#define E1000_RDLEN1   0x02908	/* RX Descriptor Length (1) - RW */
#define E1000_RDH1     0x02910	/* RX Descriptor Head (1) - RW */
#define E1000_RDT1     0x02918	/* RX Descriptor Tail (1) - RW */
#define E1000_FCTTV    0x00170	/* Flow Control Transmit Timer Value - RW */
#define E1000_TXCW     0x00178	/* TX Configuration Word - RW */
#define E1000_RXCW     0x00180	/* RX Configuration Word - RO */
#define E1000_TCTL     0x00400	/* TX Control - RW */
#define E1000_TCTL_EXT 0x00404	/* Extended TX Control - RW */
#define E1000_TIPG     0x00410	/* TX Inter-packet gap -RW */
#define E1000_TBT      0x00448	/* TX Burst Timer - RW */
#define E1000_AIT      0x00458	/* Adaptive Interframe Spacing Throttle - RW */
#define E1000_LEDCTL   0x00E00	/* LED Control - RW */
#define E1000_EXTCNF_CTRL  0x00F00	/* Extended Configuration Control */
#define E1000_EXTCNF_SIZE  0x00F08	/* Extended Configuration Size */
#define E1000_PHY_CTRL     0x00F10	/* PHY Control Register in CSR */
#define FEXTNVM_SW_CONFIG  0x0001
#define E1000_PBA      0x01000	/* Packet Buffer Allocation - RW */
#define E1000_PBS      0x01008	/* Packet Buffer Size */
#define E1000_EEMNGCTL 0x01010	/* MNG EEprom Control */
#define E1000_FLASH_UPDATES 1000
#define E1000_EEARBC   0x01024	/* EEPROM Auto Read Bus Control */
#define E1000_FLASHT   0x01028	/* FLASH Timer Register */
#define E1000_EEWR     0x0102C	/* EEPROM Write Register - RW */
#define E1000_FLSWCTL  0x01030	/* FLASH control register */
#define E1000_FLSWDATA 0x01034	/* FLASH data register */
#define E1000_FLSWCNT  0x01038	/* FLASH Access Counter */
#define E1000_FLOP     0x0103C	/* FLASH Opcode Register */
#define E1000_ERT      0x02008	/* Early Rx Threshold - RW */
#define E1000_FCRTL    0x02160	/* Flow Control Receive Threshold Low - RW */
#define E1000_FCRTH    0x02168	/* Flow Control Receive Threshold High - RW */
#define E1000_PSRCTL   0x02170	/* Packet Split Receive Control - RW */
#define E1000_RDBAL    0x02800	/* RX Descriptor Base Address Low - RW */
#define E1000_RDBAH    0x02804	/* RX Descriptor Base Address High - RW */
#define E1000_RDLEN    0x02808	/* RX Descriptor Length - RW */
#define E1000_RDH      0x02810	/* RX Descriptor Head - RW */
#define E1000_RDT      0x02818	/* RX Descriptor Tail - RW */
#define E1000_RDTR     0x02820	/* RX Delay Timer - RW */
#define E1000_RDBAL0   E1000_RDBAL	/* RX Desc Base Address Low (0) - RW */
#define E1000_RDBAH0   E1000_RDBAH	/* RX Desc Base Address High (0) - RW */
#define E1000_RDLEN0   E1000_RDLEN	/* RX Desc Length (0) - RW */
#define E1000_RDH0     E1000_RDH	/* RX Desc Head (0) - RW */
#define E1000_RDT0     E1000_RDT	/* RX Desc Tail (0) - RW */
#define E1000_RDTR0    E1000_RDTR	/* RX Delay Timer (0) - RW */
#define E1000_RXDCTL   0x02828	/* RX Descriptor Control queue 0 - RW */
#define E1000_RXDCTL1  0x02928	/* RX Descriptor Control queue 1 - RW */
#define E1000_RADV     0x0282C	/* RX Interrupt Absolute Delay Timer - RW */
#define E1000_RSRPD    0x02C00	/* RX Small Packet Detect - RW */
#define E1000_RAID     0x02C08	/* Receive Ack Interrupt Delay - RW */
#define E1000_TXDMAC   0x03000	/* TX DMA Control - RW */
#define E1000_KABGTXD  0x03004	/* AFE Band Gap Transmit Ref Data */
#define E1000_TDFH     0x03410	/* TX Data FIFO Head - RW */
#define E1000_TDFT     0x03418	/* TX Data FIFO Tail - RW */
#define E1000_TDFHS    0x03420	/* TX Data FIFO Head Saved - RW */
#define E1000_TDFTS    0x03428	/* TX Data FIFO Tail Saved - RW */
#define E1000_TDFPC    0x03430	/* TX Data FIFO Packet Count - RW */
#define E1000_TDBAL    0x03800	/* TX Descriptor Base Address Low - RW */
#define E1000_TDBAH    0x03804	/* TX Descriptor Base Address High - RW */
#define E1000_TDLEN    0x03808	/* TX Descriptor Length - RW */
#define E1000_TDH      0x03810	/* TX Descriptor Head - RW */
#define E1000_TDT      0x03818	/* TX Descripotr Tail - RW */
#define E1000_TIDV     0x03820	/* TX Interrupt Delay Value - RW */
#define E1000_TXDCTL   0x03828	/* TX Descriptor Control - RW */
#define E1000_TADV     0x0382C	/* TX Interrupt Absolute Delay Val - RW */
#define E1000_TSPMT    0x03830	/* TCP Segmentation PAD & Min Threshold - RW */
#define E1000_TARC0    0x03840	/* TX Arbitration Count (0) */
#define E1000_TDBAL1   0x03900	/* TX Desc Base Address Low (1) - RW */
#define E1000_TDBAH1   0x03904	/* TX Desc Base Address High (1) - RW */
#define E1000_TDLEN1   0x03908	/* TX Desc Length (1) - RW */
#define E1000_TDH1     0x03910	/* TX Desc Head (1) - RW */
#define E1000_TDT1     0x03918	/* TX Desc Tail (1) - RW */
#define E1000_TXDCTL1  0x03928	/* TX Descriptor Control (1) - RW */
#define E1000_TARC1    0x03940	/* TX Arbitration Count (1) */
#define E1000_CRCERRS  0x04000	/* CRC Error Count - R/clr */
#define E1000_ALGNERRC 0x04004	/* Alignment Error Count - R/clr */
#define E1000_SYMERRS  0x04008	/* Symbol Error Count - R/clr */
#define E1000_RXERRC   0x0400C	/* Receive Error Count - R/clr */
#define E1000_MPC      0x04010	/* Missed Packet Count - R/clr */
#define E1000_SCC      0x04014	/* Single Collision Count - R/clr */
#define E1000_ECOL     0x04018	/* Excessive Collision Count - R/clr */
#define E1000_MCC      0x0401C	/* Multiple Collision Count - R/clr */
#define E1000_LATECOL  0x04020	/* Late Collision Count - R/clr */
#define E1000_COLC     0x04028	/* Collision Count - R/clr */
#define E1000_DC       0x04030	/* Defer Count - R/clr */
#define E1000_TNCRS    0x04034	/* TX-No CRS - R/clr */
#define E1000_SEC      0x04038	/* Sequence Error Count - R/clr */
#define E1000_CEXTERR  0x0403C	/* Carrier Extension Error Count - R/clr */
#define E1000_RLEC     0x04040	/* Receive Length Error Count - R/clr */
#define E1000_XONRXC   0x04048	/* XON RX Count - R/clr */
#define E1000_XONTXC   0x0404C	/* XON TX Count - R/clr */
#define E1000_XOFFRXC  0x04050	/* XOFF RX Count - R/clr */
#define E1000_XOFFTXC  0x04054	/* XOFF TX Count - R/clr */
#define E1000_FCRUC    0x04058	/* Flow Control RX Unsupported Count- R/clr */
#define E1000_PRC64    0x0405C	/* Packets RX (64 bytes) - R/clr */
#define E1000_PRC127   0x04060	/* Packets RX (65-127 bytes) - R/clr */
#define E1000_PRC255   0x04064	/* Packets RX (128-255 bytes) - R/clr */
#define E1000_PRC511   0x04068	/* Packets RX (255-511 bytes) - R/clr */
#define E1000_PRC1023  0x0406C	/* Packets RX (512-1023 bytes) - R/clr */
#define E1000_PRC1522  0x04070	/* Packets RX (1024-1522 bytes) - R/clr */
#define E1000_GPRC     0x04074	/* Good Packets RX Count - R/clr */
#define E1000_BPRC     0x04078	/* Broadcast Packets RX Count - R/clr */
#define E1000_MPRC     0x0407C	/* Multicast Packets RX Count - R/clr */
#define E1000_GPTC     0x04080	/* Good Packets TX Count - R/clr */
#define E1000_GORCL    0x04088	/* Good Octets RX Count Low - R/clr */
#define E1000_GORCH    0x0408C	/* Good Octets RX Count High - R/clr */
#define E1000_GOTCL    0x04090	/* Good Octets TX Count Low - R/clr */
#define E1000_GOTCH    0x04094	/* Good Octets TX Count High - R/clr */
#define E1000_RNBC     0x040A0	/* RX No Buffers Count - R/clr */
#define E1000_RUC      0x040A4	/* RX Undersize Count - R/clr */
#define E1000_RFC      0x040A8	/* RX Fragment Count - R/clr */
#define E1000_ROC      0x040AC	/* RX Oversize Count - R/clr */
#define E1000_RJC      0x040B0	/* RX Jabber Count - R/clr */
#define E1000_MGTPRC   0x040B4	/* Management Packets RX Count - R/clr */
#define E1000_MGTPDC   0x040B8	/* Management Packets Dropped Count - R/clr */
#define E1000_MGTPTC   0x040BC	/* Management Packets TX Count - R/clr */
#define E1000_TORL     0x040C0	/* Total Octets RX Low - R/clr */
#define E1000_TORH     0x040C4	/* Total Octets RX High - R/clr */
#define E1000_TOTL     0x040C8	/* Total Octets TX Low - R/clr */
#define E1000_TOTH     0x040CC	/* Total Octets TX High - R/clr */
#define E1000_TPR      0x040D0	/* Total Packets RX - R/clr */
#define E1000_TPT      0x040D4	/* Total Packets TX - R/clr */
#define E1000_PTC64    0x040D8	/* Packets TX (64 bytes) - R/clr */
#define E1000_PTC127   0x040DC	/* Packets TX (65-127 bytes) - R/clr */
#define E1000_PTC255   0x040E0	/* Packets TX (128-255 bytes) - R/clr */
#define E1000_PTC511   0x040E4	/* Packets TX (256-511 bytes) - R/clr */
#define E1000_PTC1023  0x040E8	/* Packets TX (512-1023 bytes) - R/clr */
#define E1000_PTC1522  0x040EC	/* Packets TX (1024-1522 Bytes) - R/clr */
#define E1000_MPTC     0x040F0	/* Multicast Packets TX Count - R/clr */
#define E1000_BPTC     0x040F4	/* Broadcast Packets TX Count - R/clr */
#define E1000_TSCTC    0x040F8	/* TCP Segmentation Context TX - R/clr */
#define E1000_TSCTFC   0x040FC	/* TCP Segmentation Context TX Fail - R/clr */
#define E1000_IAC      0x04100	/* Interrupt Assertion Count */
#define E1000_ICRXPTC  0x04104	/* Interrupt Cause Rx Packet Timer Expire Count */
#define E1000_ICRXATC  0x04108	/* Interrupt Cause Rx Absolute Timer Expire Count */
#define E1000_ICTXPTC  0x0410C	/* Interrupt Cause Tx Packet Timer Expire Count */
#define E1000_ICTXATC  0x04110	/* Interrupt Cause Tx Absolute Timer Expire Count */
#define E1000_ICTXQEC  0x04118	/* Interrupt Cause Tx Queue Empty Count */
#define E1000_ICTXQMTC 0x0411C	/* Interrupt Cause Tx Queue Minimum Threshold Count */
#define E1000_ICRXDMTC 0x04120	/* Interrupt Cause Rx Descriptor Minimum Threshold Count */
#define E1000_ICRXOC   0x04124	/* Interrupt Cause Receiver Overrun Count */
#define E1000_RXCSUM   0x05000	/* RX Checksum Control - RW */
#define E1000_RFCTL    0x05008	/* Receive Filter Control */
#define E1000_MTA      0x05200	/* Multicast Table Array - RW Array */
#define E1000_RA       0x05400	/* Receive Address - RW Array */
#define E1000_VFTA     0x05600	/* VLAN Filter Table Array - RW Array */
#define E1000_WUC      0x05800	/* Wakeup Control - RW */
#define E1000_WUFC     0x05808	/* Wakeup Filter Control - RW */
#define E1000_WUS      0x05810	/* Wakeup Status - RO */
#define E1000_MANC     0x05820	/* Management Control - RW */
#define E1000_IPAV     0x05838	/* IP Address Valid - RW */
#define E1000_IP4AT    0x05840	/* IPv4 Address Table - RW Array */
#define E1000_IP6AT    0x05880	/* IPv6 Address Table - RW Array */
#define E1000_WUPL     0x05900	/* Wakeup Packet Length - RW */
#define E1000_WUPM     0x05A00	/* Wakeup Packet Memory - RO A */
#define E1000_FFLT     0x05F00	/* Flexible Filter Length Table - RW Array */
#define E1000_HOST_IF  0x08800	/* Host Interface */
#define E1000_FFMT     0x09000	/* Flexible Filter Mask Table - RW Array */
#define E1000_FFVT     0x09800	/* Flexible Filter Value Table - RW Array */

#define E1000_KUMCTRLSTA 0x00034	/* MAC-PHY interface - RW */
#define E1000_MDPHYA     0x0003C	/* PHY address - RW */
#define E1000_MANC2H     0x05860	/* Management Control To Host - RW */
#define E1000_SW_FW_SYNC 0x05B5C	/* Software-Firmware Synchronization - RW */

#define E1000_GCR       0x05B00	/* PCI-Ex Control */
#define E1000_GSCL_1    0x05B10	/* PCI-Ex Statistic Control #1 */
#define E1000_GSCL_2    0x05B14	/* PCI-Ex Statistic Control #2 */
#define E1000_GSCL_3    0x05B18	/* PCI-Ex Statistic Control #3 */
#define E1000_GSCL_4    0x05B1C	/* PCI-Ex Statistic Control #4 */
#define E1000_FACTPS    0x05B30	/* Function Active and Power State to MNG */
#define E1000_SWSM      0x05B50	/* SW Semaphore */
#define E1000_FWSM      0x05B54	/* FW Semaphore */
#define E1000_FFLT_DBG  0x05F04	/* Debug Register */
#define E1000_HICR      0x08F00	/* Host Interface Control */

/* RSS registers */
#define E1000_CPUVEC    0x02C10	/* CPU Vector Register - RW */
#define E1000_MRQC      0x05818	/* Multiple Receive Control - RW */
#define E1000_RETA      0x05C00	/* Redirection Table - RW Array */
#define E1000_RSSRK     0x05C80	/* RSS Random Key - RW Array */
#define E1000_RSSIM     0x05864	/* RSS Interrupt Mask */
#define E1000_RSSIR     0x05868	/* RSS Interrupt Request */
/* Register Set (82542)
 *
 * Some of the 82542 registers are located at different offsets than they are
 * in more current versions of the 8254x. Despite the difference in location,
 * the registers function in the same manner.
 */
#define E1000_82542_CTL_AUX  E1000_CTL_AUX
#define E1000_82542_CTRL     E1000_CTRL
#define E1000_82542_CTRL_DUP E1000_CTRL_DUP
#define E1000_82542_STATUS   E1000_STATUS
#define E1000_82542_EECD     E1000_EECD
#define E1000_82542_EERD     E1000_EERD
#define E1000_82542_CTRL_EXT E1000_CTRL_EXT
#define E1000_82542_FLA      E1000_FLA
#define E1000_82542_MDIC     E1000_MDIC
#define E1000_82542_SCTL     E1000_SCTL
#define E1000_82542_FEXTNVM  E1000_FEXTNVM
#define E1000_82542_FCAL     E1000_FCAL
#define E1000_82542_FCAH     E1000_FCAH
#define E1000_82542_FCT      E1000_FCT
#define E1000_82542_VET      E1000_VET
#define E1000_82542_RA       0x00040
#define E1000_82542_ICR      E1000_ICR
#define E1000_82542_ITR      E1000_ITR
#define E1000_82542_ICS      E1000_ICS
#define E1000_82542_IMS      E1000_IMS
#define E1000_82542_IMC      E1000_IMC
#define E1000_82542_RCTL     E1000_RCTL
#define E1000_82542_RDTR     0x00108
#define E1000_82542_RDBAL    0x00110
#define E1000_82542_RDBAH    0x00114
#define E1000_82542_RDLEN    0x00118
#define E1000_82542_RDH      0x00120
#define E1000_82542_RDT      0x00128
#define E1000_82542_RDTR0    E1000_82542_RDTR
#define E1000_82542_RDBAL0   E1000_82542_RDBAL
#define E1000_82542_RDBAH0   E1000_82542_RDBAH
#define E1000_82542_RDLEN0   E1000_82542_RDLEN
#define E1000_82542_RDH0     E1000_82542_RDH
#define E1000_82542_RDT0     E1000_82542_RDT
#define E1000_82542_SRRCTL(_n) (0x280C + ((_n) << 8))	/* Split and Replication
							 * RX Control - RW */
#define E1000_82542_DCA_RXCTRL(_n) (0x02814 + ((_n) << 8))
#define E1000_82542_RDBAH3   0x02B04	/* RX Desc Base High Queue 3 - RW */
#define E1000_82542_RDBAL3   0x02B00	/* RX Desc Low Queue 3 - RW */
#define E1000_82542_RDLEN3   0x02B08	/* RX Desc Length Queue 3 - RW */
#define E1000_82542_RDH3     0x02B10	/* RX Desc Head Queue 3 - RW */
#define E1000_82542_RDT3     0x02B18	/* RX Desc Tail Queue 3 - RW */
#define E1000_82542_RDBAL2   0x02A00	/* RX Desc Base Low Queue 2 - RW */
#define E1000_82542_RDBAH2   0x02A04	/* RX Desc Base High Queue 2 - RW */
#define E1000_82542_RDLEN2   0x02A08	/* RX Desc Length Queue 2 - RW */
#define E1000_82542_RDH2     0x02A10	/* RX Desc Head Queue 2 - RW */
#define E1000_82542_RDT2     0x02A18	/* RX Desc Tail Queue 2 - RW */
#define E1000_82542_RDTR1    0x00130
#define E1000_82542_RDBAL1   0x00138
#define E1000_82542_RDBAH1   0x0013C
#define E1000_82542_RDLEN1   0x00140
#define E1000_82542_RDH1     0x00148
#define E1000_82542_RDT1     0x00150
#define E1000_82542_FCRTH    0x00160
#define E1000_82542_FCRTL    0x00168
#define E1000_82542_FCTTV    E1000_FCTTV
#define E1000_82542_TXCW     E1000_TXCW
#define E1000_82542_RXCW     E1000_RXCW
#define E1000_82542_MTA      0x00200
#define E1000_82542_TCTL     E1000_TCTL
#define E1000_82542_TCTL_EXT E1000_TCTL_EXT
#define E1000_82542_TIPG     E1000_TIPG
#define E1000_82542_TDBAL    0x00420
#define E1000_82542_TDBAH    0x00424
#define E1000_82542_TDLEN    0x00428
#define E1000_82542_TDH      0x00430
#define E1000_82542_TDT      0x00438
#define E1000_82542_TIDV     0x00440
#define E1000_82542_TBT      E1000_TBT
#define E1000_82542_AIT      E1000_AIT
#define E1000_82542_VFTA     0x00600
#define E1000_82542_LEDCTL   E1000_LEDCTL
#define E1000_82542_PBA      E1000_PBA
#define E1000_82542_PBS      E1000_PBS
#define E1000_82542_EEMNGCTL E1000_EEMNGCTL
#define E1000_82542_EEARBC   E1000_EEARBC
#define E1000_82542_FLASHT   E1000_FLASHT
#define E1000_82542_EEWR     E1000_EEWR
#define E1000_82542_FLSWCTL  E1000_FLSWCTL
#define E1000_82542_FLSWDATA E1000_FLSWDATA
#define E1000_82542_FLSWCNT  E1000_FLSWCNT
#define E1000_82542_FLOP     E1000_FLOP
#define E1000_82542_EXTCNF_CTRL  E1000_EXTCNF_CTRL
#define E1000_82542_EXTCNF_SIZE  E1000_EXTCNF_SIZE
#define E1000_82542_PHY_CTRL E1000_PHY_CTRL
#define E1000_82542_ERT      E1000_ERT
#define E1000_82542_RXDCTL   E1000_RXDCTL
#define E1000_82542_RXDCTL1  E1000_RXDCTL1
#define E1000_82542_RADV     E1000_RADV
#define E1000_82542_RSRPD    E1000_RSRPD
#define E1000_82542_TXDMAC   E1000_TXDMAC
#define E1000_82542_KABGTXD  E1000_KABGTXD
#define E1000_82542_TDFHS    E1000_TDFHS
#define E1000_82542_TDFTS    E1000_TDFTS
#define E1000_82542_TDFPC    E1000_TDFPC
#define E1000_82542_TXDCTL   E1000_TXDCTL
#define E1000_82542_TADV     E1000_TADV
#define E1000_82542_TSPMT    E1000_TSPMT
#define E1000_82542_CRCERRS  E1000_CRCERRS
#define E1000_82542_ALGNERRC E1000_ALGNERRC
#define E1000_82542_SYMERRS  E1000_SYMERRS
#define E1000_82542_RXERRC   E1000_RXERRC
#define E1000_82542_MPC      E1000_MPC
#define E1000_82542_SCC      E1000_SCC
#define E1000_82542_ECOL     E1000_ECOL
#define E1000_82542_MCC      E1000_MCC
#define E1000_82542_LATECOL  E1000_LATECOL
#define E1000_82542_COLC     E1000_COLC
#define E1000_82542_DC       E1000_DC
#define E1000_82542_TNCRS    E1000_TNCRS
#define E1000_82542_SEC      E1000_SEC
#define E1000_82542_CEXTERR  E1000_CEXTERR
#define E1000_82542_RLEC     E1000_RLEC
#define E1000_82542_XONRXC   E1000_XONRXC
#define E1000_82542_XONTXC   E1000_XONTXC
#define E1000_82542_XOFFRXC  E1000_XOFFRXC
#define E1000_82542_XOFFTXC  E1000_XOFFTXC
#define E1000_82542_FCRUC    E1000_FCRUC
#define E1000_82542_PRC64    E1000_PRC64
#define E1000_82542_PRC127   E1000_PRC127
#define E1000_82542_PRC255   E1000_PRC255
#define E1000_82542_PRC511   E1000_PRC511
#define E1000_82542_PRC1023  E1000_PRC1023
#define E1000_82542_PRC1522  E1000_PRC1522
#define E1000_82542_GPRC     E1000_GPRC
#define E1000_82542_BPRC     E1000_BPRC
#define E1000_82542_MPRC     E1000_MPRC
#define E1000_82542_GPTC     E1000_GPTC
#define E1000_82542_GORCL    E1000_GORCL
#define E1000_82542_GORCH    E1000_GORCH
#define E1000_82542_GOTCL    E1000_GOTCL
#define E1000_82542_GOTCH    E1000_GOTCH
#define E1000_82542_RNBC     E1000_RNBC
#define E1000_82542_RUC      E1000_RUC
#define E1000_82542_RFC      E1000_RFC
#define E1000_82542_ROC      E1000_ROC
#define E1000_82542_RJC      E1000_RJC
#define E1000_82542_MGTPRC   E1000_MGTPRC
#define E1000_82542_MGTPDC   E1000_MGTPDC
#define E1000_82542_MGTPTC   E1000_MGTPTC
#define E1000_82542_TORL     E1000_TORL
#define E1000_82542_TORH     E1000_TORH
#define E1000_82542_TOTL     E1000_TOTL
#define E1000_82542_TOTH     E1000_TOTH
#define E1000_82542_TPR      E1000_TPR
#define E1000_82542_TPT      E1000_TPT
#define E1000_82542_PTC64    E1000_PTC64
#define E1000_82542_PTC127   E1000_PTC127
#define E1000_82542_PTC255   E1000_PTC255
#define E1000_82542_PTC511   E1000_PTC511
#define E1000_82542_PTC1023  E1000_PTC1023
#define E1000_82542_PTC1522  E1000_PTC1522
#define E1000_82542_MPTC     E1000_MPTC
#define E1000_82542_BPTC     E1000_BPTC
#define E1000_82542_TSCTC    E1000_TSCTC
#define E1000_82542_TSCTFC   E1000_TSCTFC
#define E1000_82542_RXCSUM   E1000_RXCSUM
#define E1000_82542_WUC      E1000_WUC
#define E1000_82542_WUFC     E1000_WUFC
#define E1000_82542_WUS      E1000_WUS
#define E1000_82542_MANC     E1000_MANC
#define E1000_82542_IPAV     E1000_IPAV
#define E1000_82542_IP4AT    E1000_IP4AT
#define E1000_82542_IP6AT    E1000_IP6AT
#define E1000_82542_WUPL     E1000_WUPL
#define E1000_82542_WUPM     E1000_WUPM
#define E1000_82542_FFLT     E1000_FFLT
#define E1000_82542_TDFH     0x08010
#define E1000_82542_TDFT     0x08018
#define E1000_82542_FFMT     E1000_FFMT
#define E1000_82542_FFVT     E1000_FFVT
#define E1000_82542_HOST_IF  E1000_HOST_IF
#define E1000_82542_IAM         E1000_IAM
#define E1000_82542_EEMNGCTL    E1000_EEMNGCTL
#define E1000_82542_PSRCTL      E1000_PSRCTL
#define E1000_82542_RAID        E1000_RAID
#define E1000_82542_TARC0       E1000_TARC0
#define E1000_82542_TDBAL1      E1000_TDBAL1
#define E1000_82542_TDBAH1      E1000_TDBAH1
#define E1000_82542_TDLEN1      E1000_TDLEN1
#define E1000_82542_TDH1        E1000_TDH1
#define E1000_82542_TDT1        E1000_TDT1
#define E1000_82542_TXDCTL1     E1000_TXDCTL1
#define E1000_82542_TARC1       E1000_TARC1
#define E1000_82542_RFCTL       E1000_RFCTL
#define E1000_82542_GCR         E1000_GCR
#define E1000_82542_GSCL_1      E1000_GSCL_1
#define E1000_82542_GSCL_2      E1000_GSCL_2
#define E1000_82542_GSCL_3      E1000_GSCL_3
#define E1000_82542_GSCL_4      E1000_GSCL_4
#define E1000_82542_FACTPS      E1000_FACTPS
#define E1000_82542_SWSM        E1000_SWSM
#define E1000_82542_FWSM        E1000_FWSM
#define E1000_82542_FFLT_DBG    E1000_FFLT_DBG
#define E1000_82542_IAC         E1000_IAC
#define E1000_82542_ICRXPTC     E1000_ICRXPTC
#define E1000_82542_ICRXATC     E1000_ICRXATC
#define E1000_82542_ICTXPTC     E1000_ICTXPTC
#define E1000_82542_ICTXATC     E1000_ICTXATC
#define E1000_82542_ICTXQEC     E1000_ICTXQEC
#define E1000_82542_ICTXQMTC    E1000_ICTXQMTC
#define E1000_82542_ICRXDMTC    E1000_ICRXDMTC
#define E1000_82542_ICRXOC      E1000_ICRXOC
#define E1000_82542_HICR        E1000_HICR

#define E1000_82542_CPUVEC      E1000_CPUVEC
#define E1000_82542_MRQC        E1000_MRQC
#define E1000_82542_RETA        E1000_RETA
#define E1000_82542_RSSRK       E1000_RSSRK
#define E1000_82542_RSSIM       E1000_RSSIM
#define E1000_82542_RSSIR       E1000_RSSIR
#define E1000_82542_KUMCTRLSTA E1000_KUMCTRLSTA
#define E1000_82542_SW_FW_SYNC E1000_SW_FW_SYNC

/* Statistics counters collected by the MAC */
struct e1000_hw_stats {
	u64 crcerrs;
	u64 algnerrc;
	u64 symerrs;
	u64 rxerrc;
	u64 txerrc;
	u64 mpc;
	u64 scc;
	u64 ecol;
	u64 mcc;
	u64 latecol;
	u64 colc;
	u64 dc;
	u64 tncrs;
	u64 sec;
	u64 cexterr;
	u64 rlec;
	u64 xonrxc;
	u64 xontxc;
	u64 xoffrxc;
	u64 xofftxc;
	u64 fcruc;
	u64 prc64;
	u64 prc127;
	u64 prc255;
	u64 prc511;
	u64 prc1023;
	u64 prc1522;
	u64 gprc;
	u64 bprc;
	u64 mprc;
	u64 gptc;
	u64 gorcl;
	u64 gorch;
	u64 gotcl;
	u64 gotch;
	u64 rnbc;
	u64 ruc;
	u64 rfc;
	u64 roc;
	u64 rlerrc;
	u64 rjc;
	u64 mgprc;
	u64 mgpdc;
	u64 mgptc;
	u64 torl;
	u64 torh;
	u64 totl;
	u64 toth;
	u64 tpr;
	u64 tpt;
	u64 ptc64;
	u64 ptc127;
	u64 ptc255;
	u64 ptc511;
	u64 ptc1023;
	u64 ptc1522;
	u64 mptc;
	u64 bptc;
	u64 tsctc;
	u64 tsctfc;
	u64 iac;
	u64 icrxptc;
	u64 icrxatc;
	u64 ictxptc;
	u64 ictxatc;
	u64 ictxqec;
	u64 ictxqmtc;
	u64 icrxdmtc;
	u64 icrxoc;
};

/* Structure containing variables used by the shared code (e1000_hw.c) */
struct e1000_hw {
	u8 __iomem *hw_addr;
	u8 __iomem *flash_address;
	e1000_mac_type mac_type;
	e1000_phy_type phy_type;
	u32 phy_init_script;
	e1000_media_type media_type;
	void *back;
	struct e1000_shadow_ram *eeprom_shadow_ram;
	u32 flash_bank_size;
	u32 flash_base_addr;
	e1000_fc_type fc;
	e1000_bus_speed bus_speed;
	e1000_bus_width bus_width;
	e1000_bus_type bus_type;
	struct e1000_eeprom_info eeprom;
	e1000_ms_type master_slave;
	e1000_ms_type original_master_slave;
	e1000_ffe_config ffe_config_state;
	u32 asf_firmware_present;
	u32 eeprom_semaphore_present;
	unsigned long io_base;
	u32 phy_id;
	u32 phy_revision;
	u32 phy_addr;
	u32 original_fc;
	u32 txcw;
	u32 autoneg_failed;
	u32 max_frame_size;
	u32 min_frame_size;
	u32 mc_filter_type;
	u32 num_mc_addrs;
	u32 collision_delta;
	u32 tx_packet_delta;
	u32 ledctl_default;
	u32 ledctl_mode1;
	u32 ledctl_mode2;
	bool tx_pkt_filtering;
	struct e1000_host_mng_dhcp_cookie mng_cookie;
	u16 phy_spd_default;
	u16 autoneg_advertised;
	u16 pci_cmd_word;
	u16 fc_high_water;
	u16 fc_low_water;
	u16 fc_pause_time;
	u16 current_ifs_val;
	u16 ifs_min_val;
	u16 ifs_max_val;
	u16 ifs_step_size;
	u16 ifs_ratio;
	u16 device_id;
	u16 vendor_id;
	u16 subsystem_id;
	u16 subsystem_vendor_id;
	u8 revision_id;
	u8 autoneg;
	u8 mdix;
	u8 forced_speed_duplex;
	u8 wait_autoneg_complete;
	u8 dma_fairness;
	u8 mac_addr[NODE_ADDRESS_SIZE];
	u8 perm_mac_addr[NODE_ADDRESS_SIZE];
	bool disable_polarity_correction;
	bool speed_downgraded;
	e1000_smart_speed smart_speed;
	e1000_dsp_config dsp_config_state;
	bool get_link_status;
	bool serdes_has_link;
	bool tbi_compatibility_en;
	bool tbi_compatibility_on;
	bool laa_is_present;
	bool phy_reset_disable;
	bool initialize_hw_bits_disable;
	bool fc_send_xon;
	bool fc_strict_ieee;
	bool report_tx_early;
	bool adaptive_ifs;
	bool ifs_params_forced;
	bool in_ifs_mode;
	bool mng_reg_access_disabled;
	bool leave_av_bit_off;
	bool bad_tx_carr_stats_fd;
	bool has_smbus;
};

#define E1000_EEPROM_SWDPIN0   0x0001	/* SWDPIN 0 EEPROM Value */
#define E1000_EEPROM_LED_LOGIC 0x0020	/* Led Logic Word */
#define E1000_EEPROM_RW_REG_DATA   16	/* Offset to data in EEPROM read/write registers */
#define E1000_EEPROM_RW_REG_DONE   2	/* Offset to READ/WRITE done bit */
#define E1000_EEPROM_RW_REG_START  1	/* First bit for telling part to start operation */
#define E1000_EEPROM_RW_ADDR_SHIFT 2	/* Shift to the address bits */
#define E1000_EEPROM_POLL_WRITE    1	/* Flag for polling for write complete */
#define E1000_EEPROM_POLL_READ     0	/* Flag for polling for read complete */
/* Register Bit Masks */
/* Device Control */
#define E1000_CTRL_FD       0x00000001	/* Full duplex.0=half; 1=full */
#define E1000_CTRL_BEM      0x00000002	/* Endian Mode.0=little,1=big */
#define E1000_CTRL_PRIOR    0x00000004	/* Priority on PCI. 0=rx,1=fair */
#define E1000_CTRL_GIO_MASTER_DISABLE 0x00000004	/*Blocks new Master requests */
#define E1000_CTRL_LRST     0x00000008	/* Link reset. 0=normal,1=reset */
#define E1000_CTRL_TME      0x00000010	/* Test mode. 0=normal,1=test */
#define E1000_CTRL_SLE      0x00000020	/* Serial Link on 0=dis,1=en */
#define E1000_CTRL_ASDE     0x00000020	/* Auto-speed detect enable */
#define E1000_CTRL_SLU      0x00000040	/* Set link up (Force Link) */
#define E1000_CTRL_ILOS     0x00000080	/* Invert Loss-Of Signal */
#define E1000_CTRL_SPD_SEL  0x00000300	/* Speed Select Mask */
#define E1000_CTRL_SPD_10   0x00000000	/* Force 10Mb */
#define E1000_CTRL_SPD_100  0x00000100	/* Force 100Mb */
#define E1000_CTRL_SPD_1000 0x00000200	/* Force 1Gb */
#define E1000_CTRL_BEM32    0x00000400	/* Big Endian 32 mode */
#define E1000_CTRL_FRCSPD   0x00000800	/* Force Speed */
#define E1000_CTRL_FRCDPX   0x00001000	/* Force Duplex */
#define E1000_CTRL_D_UD_EN  0x00002000	/* Dock/Undock enable */
#define E1000_CTRL_D_UD_POLARITY 0x00004000	/* Defined polarity of Dock/Undock indication in SDP[0] */
#define E1000_CTRL_FORCE_PHY_RESET 0x00008000	/* Reset both PHY ports, through PHYRST_N pin */
#define E1000_CTRL_EXT_LINK_EN 0x00010000	/* enable link status from external LINK_0 and LINK_1 pins */
#define E1000_CTRL_SWDPIN0  0x00040000	/* SWDPIN 0 value */
#define E1000_CTRL_SWDPIN1  0x00080000	/* SWDPIN 1 value */
#define E1000_CTRL_SWDPIN2  0x00100000	/* SWDPIN 2 value */
#define E1000_CTRL_SWDPIN3  0x00200000	/* SWDPIN 3 value */
#define E1000_CTRL_SWDPIO0  0x00400000	/* SWDPIN 0 Input or output */
#define E1000_CTRL_SWDPIO1  0x00800000	/* SWDPIN 1 input or output */
#define E1000_CTRL_SWDPIO2  0x01000000	/* SWDPIN 2 input or output */
#define E1000_CTRL_SWDPIO3  0x02000000	/* SWDPIN 3 input or output */
#define E1000_CTRL_RST      0x04000000	/* Global reset */
#define E1000_CTRL_RFCE     0x08000000	/* Receive Flow Control enable */
#define E1000_CTRL_TFCE     0x10000000	/* Transmit flow control enable */
#define E1000_CTRL_RTE      0x20000000	/* Routing tag enable */
#define E1000_CTRL_VME      0x40000000	/* IEEE VLAN mode enable */
#define E1000_CTRL_PHY_RST  0x80000000	/* PHY Reset */
#define E1000_CTRL_SW2FW_INT 0x02000000	/* Initiate an interrupt to manageability engine */

/* Device Status */
#define E1000_STATUS_FD         0x00000001	/* Full duplex.0=half,1=full */
#define E1000_STATUS_LU         0x00000002	/* Link up.0=no,1=link */
#define E1000_STATUS_FUNC_MASK  0x0000000C	/* PCI Function Mask */
#define E1000_STATUS_FUNC_SHIFT 2
#define E1000_STATUS_FUNC_0     0x00000000	/* Function 0 */
#define E1000_STATUS_FUNC_1     0x00000004	/* Function 1 */
#define E1000_STATUS_TXOFF      0x00000010	/* transmission paused */
#define E1000_STATUS_TBIMODE    0x00000020	/* TBI mode */
#define E1000_STATUS_SPEED_MASK 0x000000C0
#define E1000_STATUS_SPEED_10   0x00000000	/* Speed 10Mb/s */
#define E1000_STATUS_SPEED_100  0x00000040	/* Speed 100Mb/s */
#define E1000_STATUS_SPEED_1000 0x00000080	/* Speed 1000Mb/s */
#define E1000_STATUS_LAN_INIT_DONE 0x00000200	/* Lan Init Completion
						   by EEPROM/Flash */
#define E1000_STATUS_ASDV       0x00000300	/* Auto speed detect value */
#define E1000_STATUS_DOCK_CI    0x00000800	/* Change in Dock/Undock state. Clear on write '0'. */
#define E1000_STATUS_GIO_MASTER_ENABLE 0x00080000	/* Status of Master requests. */
#define E1000_STATUS_MTXCKOK    0x00000400	/* MTX clock running OK */
#define E1000_STATUS_PCI66      0x00000800	/* In 66Mhz slot */
#define E1000_STATUS_BUS64      0x00001000	/* In 64 bit slot */
#define E1000_STATUS_PCIX_MODE  0x00002000	/* PCI-X mode */
#define E1000_STATUS_PCIX_SPEED 0x0000C000	/* PCI-X bus speed */
#define E1000_STATUS_BMC_SKU_0  0x00100000	/* BMC USB redirect disabled */
#define E1000_STATUS_BMC_SKU_1  0x00200000	/* BMC SRAM disabled */
#define E1000_STATUS_BMC_SKU_2  0x00400000	/* BMC SDRAM disabled */
#define E1000_STATUS_BMC_CRYPTO 0x00800000	/* BMC crypto disabled */
#define E1000_STATUS_BMC_LITE   0x01000000	/* BMC external code execution disabled */
#define E1000_STATUS_RGMII_ENABLE 0x02000000	/* RGMII disabled */
#define E1000_STATUS_FUSE_8       0x04000000
#define E1000_STATUS_FUSE_9       0x08000000
#define E1000_STATUS_SERDES0_DIS  0x10000000	/* SERDES disabled on port 0 */
#define E1000_STATUS_SERDES1_DIS  0x20000000	/* SERDES disabled on port 1 */

/* Constants used to interpret the masked PCI-X bus speed. */
#define E1000_STATUS_PCIX_SPEED_66  0x00000000	/* PCI-X bus speed  50-66 MHz */
#define E1000_STATUS_PCIX_SPEED_100 0x00004000	/* PCI-X bus speed  66-100 MHz */
#define E1000_STATUS_PCIX_SPEED_133 0x00008000	/* PCI-X bus speed 100-133 MHz */

/* EEPROM/Flash Control */
#define E1000_EECD_SK        0x00000001	/* EEPROM Clock */
#define E1000_EECD_CS        0x00000002	/* EEPROM Chip Select */
#define E1000_EECD_DI        0x00000004	/* EEPROM Data In */
#define E1000_EECD_DO        0x00000008	/* EEPROM Data Out */
#define E1000_EECD_FWE_MASK  0x00000030
#define E1000_EECD_FWE_DIS   0x00000010	/* Disable FLASH writes */
#define E1000_EECD_FWE_EN    0x00000020	/* Enable FLASH writes */
#define E1000_EECD_FWE_SHIFT 4
#define E1000_EECD_REQ       0x00000040	/* EEPROM Access Request */
#define E1000_EECD_GNT       0x00000080	/* EEPROM Access Grant */
#define E1000_EECD_PRES      0x00000100	/* EEPROM Present */
#define E1000_EECD_SIZE      0x00000200	/* EEPROM Size (0=64 word 1=256 word) */
#define E1000_EECD_ADDR_BITS 0x00000400	/* EEPROM Addressing bits based on type
					 * (0-small, 1-large) */
#define E1000_EECD_TYPE      0x00002000	/* EEPROM Type (1-SPI, 0-Microwire) */
#ifndef E1000_EEPROM_GRANT_ATTEMPTS
#define E1000_EEPROM_GRANT_ATTEMPTS 1000	/* EEPROM # attempts to gain grant */
#endif
#define E1000_EECD_AUTO_RD          0x00000200	/* EEPROM Auto Read done */
#define E1000_EECD_SIZE_EX_MASK     0x00007800	/* EEprom Size */
#define E1000_EECD_SIZE_EX_SHIFT    11
#define E1000_EECD_NVADDS    0x00018000	/* NVM Address Size */
#define E1000_EECD_SELSHAD   0x00020000	/* Select Shadow RAM */
#define E1000_EECD_INITSRAM  0x00040000	/* Initialize Shadow RAM */
#define E1000_EECD_FLUPD     0x00080000	/* Update FLASH */
#define E1000_EECD_AUPDEN    0x00100000	/* Enable Autonomous FLASH update */
#define E1000_EECD_SHADV     0x00200000	/* Shadow RAM Data Valid */
#define E1000_EECD_SEC1VAL   0x00400000	/* Sector One Valid */
#define E1000_EECD_SECVAL_SHIFT      22
#define E1000_STM_OPCODE     0xDB00
#define E1000_HICR_FW_RESET  0xC0

#define E1000_SHADOW_RAM_WORDS     2048
#define E1000_ICH_NVM_SIG_WORD     0x13
#define E1000_ICH_NVM_SIG_MASK     0xC0

/* EEPROM Read */
#define E1000_EERD_START      0x00000001	/* Start Read */
#define E1000_EERD_DONE       0x00000010	/* Read Done */
#define E1000_EERD_ADDR_SHIFT 8
#define E1000_EERD_ADDR_MASK  0x0000FF00	/* Read Address */
#define E1000_EERD_DATA_SHIFT 16
#define E1000_EERD_DATA_MASK  0xFFFF0000	/* Read Data */

/* SPI EEPROM Status Register */
#define EEPROM_STATUS_RDY_SPI  0x01
#define EEPROM_STATUS_WEN_SPI  0x02
#define EEPROM_STATUS_BP0_SPI  0x04
#define EEPROM_STATUS_BP1_SPI  0x08
#define EEPROM_STATUS_WPEN_SPI 0x80

/* Extended Device Control */
#define E1000_CTRL_EXT_GPI0_EN   0x00000001	/* Maps SDP4 to GPI0 */
#define E1000_CTRL_EXT_GPI1_EN   0x00000002	/* Maps SDP5 to GPI1 */
#define E1000_CTRL_EXT_PHYINT_EN E1000_CTRL_EXT_GPI1_EN
#define E1000_CTRL_EXT_GPI2_EN   0x00000004	/* Maps SDP6 to GPI2 */
#define E1000_CTRL_EXT_GPI3_EN   0x00000008	/* Maps SDP7 to GPI3 */
#define E1000_CTRL_EXT_SDP4_DATA 0x00000010	/* Value of SW Defineable Pin 4 */
#define E1000_CTRL_EXT_SDP5_DATA 0x00000020	/* Value of SW Defineable Pin 5 */
#define E1000_CTRL_EXT_PHY_INT   E1000_CTRL_EXT_SDP5_DATA
#define E1000_CTRL_EXT_SDP6_DATA 0x00000040	/* Value of SW Defineable Pin 6 */
#define E1000_CTRL_EXT_SDP7_DATA 0x00000080	/* Value of SW Defineable Pin 7 */
#define E1000_CTRL_EXT_SDP4_DIR  0x00000100	/* Direction of SDP4 0=in 1=out */
#define E1000_CTRL_EXT_SDP5_DIR  0x00000200	/* Direction of SDP5 0=in 1=out */
#define E1000_CTRL_EXT_SDP6_DIR  0x00000400	/* Direction of SDP6 0=in 1=out */
#define E1000_CTRL_EXT_SDP7_DIR  0x00000800	/* Direction of SDP7 0=in 1=out */
#define E1000_CTRL_EXT_ASDCHK    0x00001000	/* Initiate an ASD sequence */
#define E1000_CTRL_EXT_EE_RST    0x00002000	/* Reinitialize from EEPROM */
#define E1000_CTRL_EXT_IPS       0x00004000	/* Invert Power State */
#define E1000_CTRL_EXT_SPD_BYPS  0x00008000	/* Speed Select Bypass */
#define E1000_CTRL_EXT_RO_DIS    0x00020000	/* Relaxed Ordering disable */
#define E1000_CTRL_EXT_LINK_MODE_MASK 0x00C00000
#define E1000_CTRL_EXT_LINK_MODE_GMII 0x00000000
#define E1000_CTRL_EXT_LINK_MODE_TBI  0x00C00000
#define E1000_CTRL_EXT_LINK_MODE_KMRN 0x00000000
#define E1000_CTRL_EXT_LINK_MODE_SERDES  0x00C00000
#define E1000_CTRL_EXT_LINK_MODE_SGMII   0x00800000
#define E1000_CTRL_EXT_WR_WMARK_MASK  0x03000000
#define E1000_CTRL_EXT_WR_WMARK_256   0x00000000
#define E1000_CTRL_EXT_WR_WMARK_320   0x01000000
#define E1000_CTRL_EXT_WR_WMARK_384   0x02000000
#define E1000_CTRL_EXT_WR_WMARK_448   0x03000000
#define E1000_CTRL_EXT_DRV_LOAD       0x10000000	/* Driver loaded bit for FW */
#define E1000_CTRL_EXT_IAME           0x08000000	/* Interrupt acknowledge Auto-mask */
#define E1000_CTRL_EXT_INT_TIMER_CLR  0x20000000	/* Clear Interrupt timers after IMS clear */
#define E1000_CRTL_EXT_PB_PAREN       0x01000000	/* packet buffer parity error detection enabled */
#define E1000_CTRL_EXT_DF_PAREN       0x02000000	/* descriptor FIFO parity error detection enable */
#define E1000_CTRL_EXT_GHOST_PAREN    0x40000000

/* MDI Control */
#define E1000_MDIC_DATA_MASK 0x0000FFFF
#define E1000_MDIC_REG_MASK  0x001F0000
#define E1000_MDIC_REG_SHIFT 16
#define E1000_MDIC_PHY_MASK  0x03E00000
#define E1000_MDIC_PHY_SHIFT 21
#define E1000_MDIC_OP_WRITE  0x04000000
#define E1000_MDIC_OP_READ   0x08000000
#define E1000_MDIC_READY     0x10000000
#define E1000_MDIC_INT_EN    0x20000000
#define E1000_MDIC_ERROR     0x40000000

#define INTEL_CE_GBE_MDIC_OP_WRITE      0x04000000
#define INTEL_CE_GBE_MDIC_OP_READ       0x00000000
#define INTEL_CE_GBE_MDIC_GO            0x80000000
#define INTEL_CE_GBE_MDIC_READ_ERROR    0x80000000

#define E1000_KUMCTRLSTA_MASK           0x0000FFFF
#define E1000_KUMCTRLSTA_OFFSET         0x001F0000
#define E1000_KUMCTRLSTA_OFFSET_SHIFT   16
#define E1000_KUMCTRLSTA_REN            0x00200000

#define E1000_KUMCTRLSTA_OFFSET_FIFO_CTRL      0x00000000
#define E1000_KUMCTRLSTA_OFFSET_CTRL           0x00000001
#define E1000_KUMCTRLSTA_OFFSET_INB_CTRL       0x00000002
#define E1000_KUMCTRLSTA_OFFSET_DIAG           0x00000003
#define E1000_KUMCTRLSTA_OFFSET_TIMEOUTS       0x00000004
#define E1000_KUMCTRLSTA_OFFSET_INB_PARAM      0x00000009
#define E1000_KUMCTRLSTA_OFFSET_HD_CTRL        0x00000010
#define E1000_KUMCTRLSTA_OFFSET_M2P_SERDES     0x0000001E
#define E1000_KUMCTRLSTA_OFFSET_M2P_MODES      0x0000001F

/* FIFO Control */
#define E1000_KUMCTRLSTA_FIFO_CTRL_RX_BYPASS   0x00000008
#define E1000_KUMCTRLSTA_FIFO_CTRL_TX_BYPASS   0x00000800

/* In-Band Control */
#define E1000_KUMCTRLSTA_INB_CTRL_LINK_STATUS_TX_TIMEOUT_DEFAULT    0x00000500
#define E1000_KUMCTRLSTA_INB_CTRL_DIS_PADDING  0x00000010

/* Half-Duplex Control */
#define E1000_KUMCTRLSTA_HD_CTRL_10_100_DEFAULT 0x00000004
#define E1000_KUMCTRLSTA_HD_CTRL_1000_DEFAULT  0x00000000

#define E1000_KUMCTRLSTA_OFFSET_K0S_CTRL       0x0000001E

#define E1000_KUMCTRLSTA_DIAG_FELPBK           0x2000
#define E1000_KUMCTRLSTA_DIAG_NELPBK           0x1000

#define E1000_KUMCTRLSTA_K0S_100_EN            0x2000
#define E1000_KUMCTRLSTA_K0S_GBE_EN            0x1000
#define E1000_KUMCTRLSTA_K0S_ENTRY_LATENCY_MASK   0x0003

#define E1000_KABGTXD_BGSQLBIAS                0x00050000

#define E1000_PHY_CTRL_SPD_EN                  0x00000001
#define E1000_PHY_CTRL_D0A_LPLU                0x00000002
#define E1000_PHY_CTRL_NOND0A_LPLU             0x00000004
#define E1000_PHY_CTRL_NOND0A_GBE_DISABLE      0x00000008
#define E1000_PHY_CTRL_GBE_DISABLE             0x00000040
#define E1000_PHY_CTRL_B2B_EN                  0x00000080

/* LED Control */
#define E1000_LEDCTL_LED0_MODE_MASK       0x0000000F
#define E1000_LEDCTL_LED0_MODE_SHIFT      0
#define E1000_LEDCTL_LED0_BLINK_RATE      0x0000020
#define E1000_LEDCTL_LED0_IVRT            0x00000040
#define E1000_LEDCTL_LED0_BLINK           0x00000080
#define E1000_LEDCTL_LED1_MODE_MASK       0x00000F00
#define E1000_LEDCTL_LED1_MODE_SHIFT      8
#define E1000_LEDCTL_LED1_BLINK_RATE      0x0002000
#define E1000_LEDCTL_LED1_IVRT            0x00004000
#define E1000_LEDCTL_LED1_BLINK           0x00008000
#define E1000_LEDCTL_LED2_MODE_MASK       0x000F0000
#define E1000_LEDCTL_LED2_MODE_SHIFT      16
#define E1000_LEDCTL_LED2_BLINK_RATE      0x00200000
#define E1000_LEDCTL_LED2_IVRT            0x00400000
#define E1000_LEDCTL_LED2_BLINK           0x00800000
#define E1000_LEDCTL_LED3_MODE_MASK       0x0F000000
#define E1000_LEDCTL_LED3_MODE_SHIFT      24
#define E1000_LEDCTL_LED3_BLINK_RATE      0x20000000
#define E1000_LEDCTL_LED3_IVRT            0x40000000
#define E1000_LEDCTL_LED3_BLINK           0x80000000

#define E1000_LEDCTL_MODE_LINK_10_1000  0x0
#define E1000_LEDCTL_MODE_LINK_100_1000 0x1
#define E1000_LEDCTL_MODE_LINK_UP       0x2
#define E1000_LEDCTL_MODE_ACTIVITY      0x3
#define E1000_LEDCTL_MODE_LINK_ACTIVITY 0x4
#define E1000_LEDCTL_MODE_LINK_10       0x5
#define E1000_LEDCTL_MODE_LINK_100      0x6
#define E1000_LEDCTL_MODE_LINK_1000     0x7
#define E1000_LEDCTL_MODE_PCIX_MODE     0x8
#define E1000_LEDCTL_MODE_FULL_DUPLEX   0x9
#define E1000_LEDCTL_MODE_COLLISION     0xA
#define E1000_LEDCTL_MODE_BUS_SPEED     0xB
#define E1000_LEDCTL_MODE_BUS_SIZE      0xC
#define E1000_LEDCTL_MODE_PAUSED        0xD
#define E1000_LEDCTL_MODE_LED_ON        0xE
#define E1000_LEDCTL_MODE_LED_OFF       0xF

/* Receive Address */
#define E1000_RAH_AV  0x80000000	/* Receive descriptor valid */

/* Interrupt Cause Read */
#define E1000_ICR_TXDW          0x00000001	/* Transmit desc written back */
#define E1000_ICR_TXQE          0x00000002	/* Transmit Queue empty */
#define E1000_ICR_LSC           0x00000004	/* Link Status Change */
#define E1000_ICR_RXSEQ         0x00000008	/* rx sequence error */
#define E1000_ICR_RXDMT0        0x00000010	/* rx desc min. threshold (0) */
#define E1000_ICR_RXO           0x00000040	/* rx overrun */
#define E1000_ICR_RXT0          0x00000080	/* rx timer intr (ring 0) */
#define E1000_ICR_MDAC          0x00000200	/* MDIO access complete */
#define E1000_ICR_RXCFG         0x00000400	/* RX /c/ ordered set */
#define E1000_ICR_GPI_EN0       0x00000800	/* GP Int 0 */
#define E1000_ICR_GPI_EN1       0x00001000	/* GP Int 1 */
#define E1000_ICR_GPI_EN2       0x00002000	/* GP Int 2 */
#define E1000_ICR_GPI_EN3       0x00004000	/* GP Int 3 */
#define E1000_ICR_TXD_LOW       0x00008000
#define E1000_ICR_SRPD          0x00010000
#define E1000_ICR_ACK           0x00020000	/* Receive Ack frame */
#define E1000_ICR_MNG           0x00040000	/* Manageability event */
#define E1000_ICR_DOCK          0x00080000	/* Dock/Undock */
#define E1000_ICR_INT_ASSERTED  0x80000000	/* If this bit asserted, the driver should claim the interrupt */
#define E1000_ICR_RXD_FIFO_PAR0 0x00100000	/* queue 0 Rx descriptor FIFO parity error */
#define E1000_ICR_TXD_FIFO_PAR0 0x00200000	/* queue 0 Tx descriptor FIFO parity error */
#define E1000_ICR_HOST_ARB_PAR  0x00400000	/* host arb read buffer parity error */
#define E1000_ICR_PB_PAR        0x00800000	/* packet buffer parity error */
#define E1000_ICR_RXD_FIFO_PAR1 0x01000000	/* queue 1 Rx descriptor FIFO parity error */
#define E1000_ICR_TXD_FIFO_PAR1 0x02000000	/* queue 1 Tx descriptor FIFO parity error */
#define E1000_ICR_ALL_PARITY    0x03F00000	/* all parity error bits */
#define E1000_ICR_DSW           0x00000020	/* FW changed the status of DISSW bit in the FWSM */
#define E1000_ICR_PHYINT        0x00001000	/* LAN connected device generates an interrupt */
#define E1000_ICR_EPRST         0x00100000	/* ME hardware reset occurs */

/* Interrupt Cause Set */
#define E1000_ICS_TXDW      E1000_ICR_TXDW	/* Transmit desc written back */
#define E1000_ICS_TXQE      E1000_ICR_TXQE	/* Transmit Queue empty */
#define E1000_ICS_LSC       E1000_ICR_LSC	/* Link Status Change */
#define E1000_ICS_RXSEQ     E1000_ICR_RXSEQ	/* rx sequence error */
#define E1000_ICS_RXDMT0    E1000_ICR_RXDMT0	/* rx desc min. threshold */
#define E1000_ICS_RXO       E1000_ICR_RXO	/* rx overrun */
#define E1000_ICS_RXT0      E1000_ICR_RXT0	/* rx timer intr */
#define E1000_ICS_MDAC      E1000_ICR_MDAC	/* MDIO access complete */
#define E1000_ICS_RXCFG     E1000_ICR_RXCFG	/* RX /c/ ordered set */
#define E1000_ICS_GPI_EN0   E1000_ICR_GPI_EN0	/* GP Int 0 */
#define E1000_ICS_GPI_EN1   E1000_ICR_GPI_EN1	/* GP Int 1 */
#define E1000_ICS_GPI_EN2   E1000_ICR_GPI_EN2	/* GP Int 2 */
#define E1000_ICS_GPI_EN3   E1000_ICR_GPI_EN3	/* GP Int 3 */
#define E1000_ICS_TXD_LOW   E1000_ICR_TXD_LOW
#define E1000_ICS_SRPD      E1000_ICR_SRPD
#define E1000_ICS_ACK       E1000_ICR_ACK	/* Receive Ack frame */
#define E1000_ICS_MNG       E1000_ICR_MNG	/* Manageability event */
#define E1000_ICS_DOCK      E1000_ICR_DOCK	/* Dock/Undock */
#define E1000_ICS_RXD_FIFO_PAR0 E1000_ICR_RXD_FIFO_PAR0	/* queue 0 Rx descriptor FIFO parity error */
#define E1000_ICS_TXD_FIFO_PAR0 E1000_ICR_TXD_FIFO_PAR0	/* queue 0 Tx descriptor FIFO parity error */
#define E1000_ICS_HOST_ARB_PAR  E1000_ICR_HOST_ARB_PAR	/* host arb read buffer parity error */
#define E1000_ICS_PB_PAR        E1000_ICR_PB_PAR	/* packet buffer parity error */
#define E1000_ICS_RXD_FIFO_PAR1 E1000_ICR_RXD_FIFO_PAR1	/* queue 1 Rx descriptor FIFO parity error */
#define E1000_ICS_TXD_FIFO_PAR1 E1000_ICR_TXD_FIFO_PAR1	/* queue 1 Tx descriptor FIFO parity error */
#define E1000_ICS_DSW       E1000_ICR_DSW
#define E1000_ICS_PHYINT    E1000_ICR_PHYINT
#define E1000_ICS_EPRST     E1000_ICR_EPRST

/* Interrupt Mask Set */
#define E1000_IMS_TXDW      E1000_ICR_TXDW	/* Transmit desc written back */
#define E1000_IMS_TXQE      E1000_ICR_TXQE	/* Transmit Queue empty */
#define E1000_IMS_LSC       E1000_ICR_LSC	/* Link Status Change */
#define E1000_IMS_RXSEQ     E1000_ICR_RXSEQ	/* rx sequence error */
#define E1000_IMS_RXDMT0    E1000_ICR_RXDMT0	/* rx desc min. threshold */
#define E1000_IMS_RXO       E1000_ICR_RXO	/* rx overrun */
#define E1000_IMS_RXT0      E1000_ICR_RXT0	/* rx timer intr */
#define E1000_IMS_MDAC      E1000_ICR_MDAC	/* MDIO access complete */
#define E1000_IMS_RXCFG     E1000_ICR_RXCFG	/* RX /c/ ordered set */
#define E1000_IMS_GPI_EN0   E1000_ICR_GPI_EN0	/* GP Int 0 */
#define E1000_IMS_GPI_EN1   E1000_ICR_GPI_EN1	/* GP Int 1 */
#define E1000_IMS_GPI_EN2   E1000_ICR_GPI_EN2	/* GP Int 2 */
#define E1000_IMS_GPI_EN3   E1000_ICR_GPI_EN3	/* GP Int 3 */
#define E1000_IMS_TXD_LOW   E1000_ICR_TXD_LOW
#define E1000_IMS_SRPD      E1000_ICR_SRPD
#define E1000_IMS_ACK       E1000_ICR_ACK	/* Receive Ack frame */
#define E1000_IMS_MNG       E1000_ICR_MNG	/* Manageability event */
#define E1000_IMS_DOCK      E1000_ICR_DOCK	/* Dock/Undock */
#define E1000_IMS_RXD_FIFO_PAR0 E1000_ICR_RXD_FIFO_PAR0	/* queue 0 Rx descriptor FIFO parity error */
#define E1000_IMS_TXD_FIFO_PAR0 E1000_ICR_TXD_FIFO_PAR0	/* queue 0 Tx descriptor FIFO parity error */
#define E1000_IMS_HOST_ARB_PAR  E1000_ICR_HOST_ARB_PAR	/* host arb read buffer parity error */
#define E1000_IMS_PB_PAR        E1000_ICR_PB_PAR	/* packet buffer parity error */
#define E1000_IMS_RXD_FIFO_PAR1 E1000_ICR_RXD_FIFO_PAR1	/* queue 1 Rx descriptor FIFO parity error */
#define E1000_IMS_TXD_FIFO_PAR1 E1000_ICR_TXD_FIFO_PAR1	/* queue 1 Tx descriptor FIFO parity error */
#define E1000_IMS_DSW       E1000_ICR_DSW
#define E1000_IMS_PHYINT    E1000_ICR_PHYINT
#define E1000_IMS_EPRST     E1000_ICR_EPRST

/* Interrupt Mask Clear */
#define E1000_IMC_TXDW      E1000_ICR_TXDW	/* Transmit desc written back */
#define E1000_IMC_TXQE      E1000_ICR_TXQE	/* Transmit Queue empty */
#define E1000_IMC_LSC       E1000_ICR_LSC	/* Link Status Change */
#define E1000_IMC_RXSEQ     E1000_ICR_RXSEQ	/* rx sequence error */
#define E1000_IMC_RXDMT0    E1000_ICR_RXDMT0	/* rx desc min. threshold */
#define E1000_IMC_RXO       E1000_ICR_RXO	/* rx overrun */
#define E1000_IMC_RXT0      E1000_ICR_RXT0	/* rx timer intr */
#define E1000_IMC_MDAC      E1000_ICR_MDAC	/* MDIO access complete */
#define E1000_IMC_RXCFG     E1000_ICR_RXCFG	/* RX /c/ ordered set */
#define E1000_IMC_GPI_EN0   E1000_ICR_GPI_EN0	/* GP Int 0 */
#define E1000_IMC_GPI_EN1   E1000_ICR_GPI_EN1	/* GP Int 1 */
#define E1000_IMC_GPI_EN2   E1000_ICR_GPI_EN2	/* GP Int 2 */
#define E1000_IMC_GPI_EN3   E1000_ICR_GPI_EN3	/* GP Int 3 */
#define E1000_IMC_TXD_LOW   E1000_ICR_TXD_LOW
#define E1000_IMC_SRPD      E1000_ICR_SRPD
#define E1000_IMC_ACK       E1000_ICR_ACK	/* Receive Ack frame */
#define E1000_IMC_MNG       E1000_ICR_MNG	/* Manageability event */
#define E1000_IMC_DOCK      E1000_ICR_DOCK	/* Dock/Undock */
#define E1000_IMC_RXD_FIFO_PAR0 E1000_ICR_RXD_FIFO_PAR0	/* queue 0 Rx descriptor FIFO parity error */
#define E1000_IMC_TXD_FIFO_PAR0 E1000_ICR_TXD_FIFO_PAR0	/* queue 0 Tx descriptor FIFO parity error */
#define E1000_IMC_HOST_ARB_PAR  E1000_ICR_HOST_ARB_PAR	/* host arb read buffer parity error */
#define E1000_IMC_PB_PAR        E1000_ICR_PB_PAR	/* packet buffer parity error */
#define E1000_IMC_RXD_FIFO_PAR1 E1000_ICR_RXD_FIFO_PAR1	/* queue 1 Rx descriptor FIFO parity error */
#define E1000_IMC_TXD_FIFO_PAR1 E1000_ICR_TXD_FIFO_PAR1	/* queue 1 Tx descriptor FIFO parity error */
#define E1000_IMC_DSW       E1000_ICR_DSW
#define E1000_IMC_PHYINT    E1000_ICR_PHYINT
#define E1000_IMC_EPRST     E1000_ICR_EPRST

/* Receive Control */
#define E1000_RCTL_RST            0x00000001	/* Software reset */
#define E1000_RCTL_EN             0x00000002	/* enable */
#define E1000_RCTL_SBP            0x00000004	/* store bad packet */
#define E1000_RCTL_UPE            0x00000008	/* unicast promiscuous enable */
#define E1000_RCTL_MPE            0x00000010	/* multicast promiscuous enab */
#define E1000_RCTL_LPE            0x00000020	/* long packet enable */
#define E1000_RCTL_LBM_NO         0x00000000	/* no loopback mode */
#define E1000_RCTL_LBM_MAC        0x00000040	/* MAC loopback mode */
#define E1000_RCTL_LBM_SLP        0x00000080	/* serial link loopback mode */
#define E1000_RCTL_LBM_TCVR       0x000000C0	/* tcvr loopback mode */
#define E1000_RCTL_DTYP_MASK      0x00000C00	/* Descriptor type mask */
#define E1000_RCTL_DTYP_PS        0x00000400	/* Packet Split descriptor */
#define E1000_RCTL_RDMTS_HALF     0x00000000	/* rx desc min threshold size */
#define E1000_RCTL_RDMTS_QUAT     0x00000100	/* rx desc min threshold size */
#define E1000_RCTL_RDMTS_EIGTH    0x00000200	/* rx desc min threshold size */
#define E1000_RCTL_MO_SHIFT       12	/* multicast offset shift */
#define E1000_RCTL_MO_0           0x00000000	/* multicast offset 11:0 */
#define E1000_RCTL_MO_1           0x00001000	/* multicast offset 12:1 */
#define E1000_RCTL_MO_2           0x00002000	/* multicast offset 13:2 */
#define E1000_RCTL_MO_3           0x00003000	/* multicast offset 15:4 */
#define E1000_RCTL_MDR            0x00004000	/* multicast desc ring 0 */
#define E1000_RCTL_BAM            0x00008000	/* broadcast enable */
/* these buffer sizes are valid if E1000_RCTL_BSEX is 0 */
#define E1000_RCTL_SZ_2048        0x00000000	/* rx buffer size 2048 */
#define E1000_RCTL_SZ_1024        0x00010000	/* rx buffer size 1024 */
#define E1000_RCTL_SZ_512         0x00020000	/* rx buffer size 512 */
#define E1000_RCTL_SZ_256         0x00030000	/* rx buffer size 256 */
/* these buffer sizes are valid if E1000_RCTL_BSEX is 1 */
#define E1000_RCTL_SZ_16384       0x00010000	/* rx buffer size 16384 */
#define E1000_RCTL_SZ_8192        0x00020000	/* rx buffer size 8192 */
#define E1000_RCTL_SZ_4096        0x00030000	/* rx buffer size 4096 */
#define E1000_RCTL_VFE            0x00040000	/* vlan filter enable */
#define E1000_RCTL_CFIEN          0x00080000	/* canonical form enable */
#define E1000_RCTL_CFI            0x00100000	/* canonical form indicator */
#define E1000_RCTL_DPF            0x00400000	/* discard pause frames */
#define E1000_RCTL_PMCF           0x00800000	/* pass MAC control frames */
#define E1000_RCTL_BSEX           0x02000000	/* Buffer size extension */
#define E1000_RCTL_SECRC          0x04000000	/* Strip Ethernet CRC */
#define E1000_RCTL_FLXBUF_MASK    0x78000000	/* Flexible buffer size */
#define E1000_RCTL_FLXBUF_SHIFT   27	/* Flexible buffer shift */

/* Use byte values for the following shift parameters
 * Usage:
 *     psrctl |= (((ROUNDUP(value0, 128) >> E1000_PSRCTL_BSIZE0_SHIFT) &
 *                  E1000_PSRCTL_BSIZE0_MASK) |
 *                ((ROUNDUP(value1, 1024) >> E1000_PSRCTL_BSIZE1_SHIFT) &
 *                  E1000_PSRCTL_BSIZE1_MASK) |
 *                ((ROUNDUP(value2, 1024) << E1000_PSRCTL_BSIZE2_SHIFT) &
 *                  E1000_PSRCTL_BSIZE2_MASK) |
 *                ((ROUNDUP(value3, 1024) << E1000_PSRCTL_BSIZE3_SHIFT) |;
 *                  E1000_PSRCTL_BSIZE3_MASK))
 * where value0 = [128..16256],  default=256
 *       value1 = [1024..64512], default=4096
 *       value2 = [0..64512],    default=4096
 *       value3 = [0..64512],    default=0
 */

#define E1000_PSRCTL_BSIZE0_MASK   0x0000007F
#define E1000_PSRCTL_BSIZE1_MASK   0x00003F00
#define E1000_PSRCTL_BSIZE2_MASK   0x003F0000
#define E1000_PSRCTL_BSIZE3_MASK   0x3F000000

#define E1000_PSRCTL_BSIZE0_SHIFT  7	/* Shift _right_ 7 */
#define E1000_PSRCTL_BSIZE1_SHIFT  2	/* Shift _right_ 2 */
#define E1000_PSRCTL_BSIZE2_SHIFT  6	/* Shift _left_ 6 */
#define E1000_PSRCTL_BSIZE3_SHIFT 14	/* Shift _left_ 14 */

/* SW_W_SYNC definitions */
#define E1000_SWFW_EEP_SM     0x0001
#define E1000_SWFW_PHY0_SM    0x0002
#define E1000_SWFW_PHY1_SM    0x0004
#define E1000_SWFW_MAC_CSR_SM 0x0008

/* Receive Descriptor */
#define E1000_RDT_DELAY 0x0000ffff	/* Delay timer (1=1024us) */
#define E1000_RDT_FPDB  0x80000000	/* Flush descriptor block */
#define E1000_RDLEN_LEN 0x0007ff80	/* descriptor length */
#define E1000_RDH_RDH   0x0000ffff	/* receive descriptor head */
#define E1000_RDT_RDT   0x0000ffff	/* receive descriptor tail */

/* Flow Control */
#define E1000_FCRTH_RTH  0x0000FFF8	/* Mask Bits[15:3] for RTH */
#define E1000_FCRTH_XFCE 0x80000000	/* External Flow Control Enable */
#define E1000_FCRTL_RTL  0x0000FFF8	/* Mask Bits[15:3] for RTL */
#define E1000_FCRTL_XONE 0x80000000	/* Enable XON frame transmission */

/* Header split receive */
#define E1000_RFCTL_ISCSI_DIS           0x00000001
#define E1000_RFCTL_ISCSI_DWC_MASK      0x0000003E
#define E1000_RFCTL_ISCSI_DWC_SHIFT     1
#define E1000_RFCTL_NFSW_DIS            0x00000040
#define E1000_RFCTL_NFSR_DIS            0x00000080
#define E1000_RFCTL_NFS_VER_MASK        0x00000300
#define E1000_RFCTL_NFS_VER_SHIFT       8
#define E1000_RFCTL_IPV6_DIS            0x00000400
#define E1000_RFCTL_IPV6_XSUM_DIS       0x00000800
#define E1000_RFCTL_ACK_DIS             0x00001000
#define E1000_RFCTL_ACKD_DIS            0x00002000
#define E1000_RFCTL_IPFRSP_DIS          0x00004000
#define E1000_RFCTL_EXTEN               0x00008000
#define E1000_RFCTL_IPV6_EX_DIS         0x00010000
#define E1000_RFCTL_NEW_IPV6_EXT_DIS    0x00020000

/* Receive Descriptor Control */
#define E1000_RXDCTL_PTHRESH 0x0000003F	/* RXDCTL Prefetch Threshold */
#define E1000_RXDCTL_HTHRESH 0x00003F00	/* RXDCTL Host Threshold */
#define E1000_RXDCTL_WTHRESH 0x003F0000	/* RXDCTL Writeback Threshold */
#define E1000_RXDCTL_GRAN    0x01000000	/* RXDCTL Granularity */

/* Transmit Descriptor Control */
#define E1000_TXDCTL_PTHRESH 0x0000003F	/* TXDCTL Prefetch Threshold */
#define E1000_TXDCTL_HTHRESH 0x00003F00	/* TXDCTL Host Threshold */
#define E1000_TXDCTL_WTHRESH 0x003F0000	/* TXDCTL Writeback Threshold */
#define E1000_TXDCTL_GRAN    0x01000000	/* TXDCTL Granularity */
#define E1000_TXDCTL_LWTHRESH 0xFE000000	/* TXDCTL Low Threshold */
#define E1000_TXDCTL_FULL_TX_DESC_WB 0x01010000	/* GRAN=1, WTHRESH=1 */
#define E1000_TXDCTL_COUNT_DESC 0x00400000	/* Enable the counting of desc.
						   still to be processed. */
/* Transmit Configuration Word */
#define E1000_TXCW_FD         0x00000020	/* TXCW full duplex */
#define E1000_TXCW_HD         0x00000040	/* TXCW half duplex */
#define E1000_TXCW_PAUSE      0x00000080	/* TXCW sym pause request */
#define E1000_TXCW_ASM_DIR    0x00000100	/* TXCW astm pause direction */
#define E1000_TXCW_PAUSE_MASK 0x00000180	/* TXCW pause request mask */
#define E1000_TXCW_RF         0x00003000	/* TXCW remote fault */
#define E1000_TXCW_NP         0x00008000	/* TXCW next page */
#define E1000_TXCW_CW         0x0000ffff	/* TxConfigWord mask */
#define E1000_TXCW_TXC        0x40000000	/* Transmit Config control */
#define E1000_TXCW_ANE        0x80000000	/* Auto-neg enable */

/* Receive Configuration Word */
#define E1000_RXCW_CW    0x0000ffff	/* RxConfigWord mask */
#define E1000_RXCW_NC    0x04000000	/* Receive config no carrier */
#define E1000_RXCW_IV    0x08000000	/* Receive config invalid */
#define E1000_RXCW_CC    0x10000000	/* Receive config change */
#define E1000_RXCW_C     0x20000000	/* Receive config */
#define E1000_RXCW_SYNCH 0x40000000	/* Receive config synch */
#define E1000_RXCW_ANC   0x80000000	/* Auto-neg complete */

/* Transmit Control */
#define E1000_TCTL_RST    0x00000001	/* software reset */
#define E1000_TCTL_EN     0x00000002	/* enable tx */
#define E1000_TCTL_BCE    0x00000004	/* busy check enable */
#define E1000_TCTL_PSP    0x00000008	/* pad short packets */
#define E1000_TCTL_CT     0x00000ff0	/* collision threshold */
#define E1000_TCTL_COLD   0x003ff000	/* collision distance */
#define E1000_TCTL_SWXOFF 0x00400000	/* SW Xoff transmission */
#define E1000_TCTL_PBE    0x00800000	/* Packet Burst Enable */
#define E1000_TCTL_RTLC   0x01000000	/* Re-transmit on late collision */
#define E1000_TCTL_NRTU   0x02000000	/* No Re-transmit on underrun */
#define E1000_TCTL_MULR   0x10000000	/* Multiple request support */
/* Extended Transmit Control */
#define E1000_TCTL_EXT_BST_MASK  0x000003FF	/* Backoff Slot Time */
#define E1000_TCTL_EXT_GCEX_MASK 0x000FFC00	/* Gigabit Carry Extend Padding */

/* Receive Checksum Control */
#define E1000_RXCSUM_PCSS_MASK 0x000000FF	/* Packet Checksum Start */
#define E1000_RXCSUM_IPOFL     0x00000100	/* IPv4 checksum offload */
#define E1000_RXCSUM_TUOFL     0x00000200	/* TCP / UDP checksum offload */
#define E1000_RXCSUM_IPV6OFL   0x00000400	/* IPv6 checksum offload */
#define E1000_RXCSUM_IPPCSE    0x00001000	/* IP payload checksum enable */
#define E1000_RXCSUM_PCSD      0x00002000	/* packet checksum disabled */

/* Multiple Receive Queue Control */
#define E1000_MRQC_ENABLE_MASK              0x00000003
#define E1000_MRQC_ENABLE_RSS_2Q            0x00000001
#define E1000_MRQC_ENABLE_RSS_INT           0x00000004
#define E1000_MRQC_RSS_FIELD_MASK           0xFFFF0000
#define E1000_MRQC_RSS_FIELD_IPV4_TCP       0x00010000
#define E1000_MRQC_RSS_FIELD_IPV4           0x00020000
#define E1000_MRQC_RSS_FIELD_IPV6_TCP_EX    0x00040000
#define E1000_MRQC_RSS_FIELD_IPV6_EX        0x00080000
#define E1000_MRQC_RSS_FIELD_IPV6           0x00100000
#define E1000_MRQC_RSS_FIELD_IPV6_TCP       0x00200000

/* Definitions for power management and wakeup registers */
/* Wake Up Control */
#define E1000_WUC_APME       0x00000001	/* APM Enable */
#define E1000_WUC_PME_EN     0x00000002	/* PME Enable */
#define E1000_WUC_PME_STATUS 0x00000004	/* PME Status */
#define E1000_WUC_APMPME     0x00000008	/* Assert PME on APM Wakeup */
#define E1000_WUC_SPM        0x80000000	/* Enable SPM */

/* Wake Up Filter Control */
#define E1000_WUFC_LNKC 0x00000001	/* Link Status Change Wakeup Enable */
#define E1000_WUFC_MAG  0x00000002	/* Magic Packet Wakeup Enable */
#define E1000_WUFC_EX   0x00000004	/* Directed Exact Wakeup Enable */
#define E1000_WUFC_MC   0x00000008	/* Directed Multicast Wakeup Enable */
#define E1000_WUFC_BC   0x00000010	/* Broadcast Wakeup Enable */
#define E1000_WUFC_ARP  0x00000020	/* ARP Request Packet Wakeup Enable */
#define E1000_WUFC_IPV4 0x00000040	/* Directed IPv4 Packet Wakeup Enable */
#define E1000_WUFC_IPV6 0x00000080	/* Directed IPv6 Packet Wakeup Enable */
#define E1000_WUFC_IGNORE_TCO      0x00008000	/* Ignore WakeOn TCO packets */
#define E1000_WUFC_FLX0 0x00010000	/* Flexible Filter 0 Enable */
#define E1000_WUFC_FLX1 0x00020000	/* Flexible Filter 1 Enable */
#define E1000_WUFC_FLX2 0x00040000	/* Flexible Filter 2 Enable */
#define E1000_WUFC_FLX3 0x00080000	/* Flexible Filter 3 Enable */
#define E1000_WUFC_ALL_FILTERS 0x000F00FF	/* Mask for all wakeup filters */
#define E1000_WUFC_FLX_OFFSET 16	/* Offset to the Flexible Filters bits */
#define E1000_WUFC_FLX_FILTERS 0x000F0000	/* Mask for the 4 flexible filters */

/* Wake Up Status */
#define E1000_WUS_LNKC 0x00000001	/* Link Status Changed */
#define E1000_WUS_MAG  0x00000002	/* Magic Packet Received */
#define E1000_WUS_EX   0x00000004	/* Directed Exact Received */
#define E1000_WUS_MC   0x00000008	/* Directed Multicast Received */
#define E1000_WUS_BC   0x00000010	/* Broadcast Received */
#define E1000_WUS_ARP  0x00000020	/* ARP Request Packet Received */
#define E1000_WUS_IPV4 0x00000040	/* Directed IPv4 Packet Wakeup Received */
#define E1000_WUS_IPV6 0x00000080	/* Directed IPv6 Packet Wakeup Received */
#define E1000_WUS_FLX0 0x00010000	/* Flexible Filter 0 Match */
#define E1000_WUS_FLX1 0x00020000	/* Flexible Filter 1 Match */
#define E1000_WUS_FLX2 0x00040000	/* Flexible Filter 2 Match */
#define E1000_WUS_FLX3 0x00080000	/* Flexible Filter 3 Match */
#define E1000_WUS_FLX_FILTERS 0x000F0000	/* Mask for the 4 flexible filters */

/* Management Control */
#define E1000_MANC_SMBUS_EN      0x00000001	/* SMBus Enabled - RO */
#define E1000_MANC_ASF_EN        0x00000002	/* ASF Enabled - RO */
#define E1000_MANC_R_ON_FORCE    0x00000004	/* Reset on Force TCO - RO */
#define E1000_MANC_RMCP_EN       0x00000100	/* Enable RCMP 026Fh Filtering */
#define E1000_MANC_0298_EN       0x00000200	/* Enable RCMP 0298h Filtering */
#define E1000_MANC_IPV4_EN       0x00000400	/* Enable IPv4 */
#define E1000_MANC_IPV6_EN       0x00000800	/* Enable IPv6 */
#define E1000_MANC_SNAP_EN       0x00001000	/* Accept LLC/SNAP */
#define E1000_MANC_ARP_EN        0x00002000	/* Enable ARP Request Filtering */
#define E1000_MANC_NEIGHBOR_EN   0x00004000	/* Enable Neighbor Discovery
						 * Filtering */
#define E1000_MANC_ARP_RES_EN    0x00008000	/* Enable ARP response Filtering */
#define E1000_MANC_TCO_RESET     0x00010000	/* TCO Reset Occurred */
#define E1000_MANC_RCV_TCO_EN    0x00020000	/* Receive TCO Packets Enabled */
#define E1000_MANC_REPORT_STATUS 0x00040000	/* Status Reporting Enabled */
#define E1000_MANC_RCV_ALL       0x00080000	/* Receive All Enabled */
#define E1000_MANC_BLK_PHY_RST_ON_IDE   0x00040000	/* Block phy resets */
#define E1000_MANC_EN_MAC_ADDR_FILTER   0x00100000	/* Enable MAC address
							 * filtering */
#define E1000_MANC_EN_MNG2HOST   0x00200000	/* Enable MNG packets to host
						 * memory */
#define E1000_MANC_EN_IP_ADDR_FILTER    0x00400000	/* Enable IP address
							 * filtering */
#define E1000_MANC_EN_XSUM_FILTER   0x00800000	/* Enable checksum filtering */
#define E1000_MANC_BR_EN         0x01000000	/* Enable broadcast filtering */
#define E1000_MANC_SMB_REQ       0x01000000	/* SMBus Request */
#define E1000_MANC_SMB_GNT       0x02000000	/* SMBus Grant */
#define E1000_MANC_SMB_CLK_IN    0x04000000	/* SMBus Clock In */
#define E1000_MANC_SMB_DATA_IN   0x08000000	/* SMBus Data In */
#define E1000_MANC_SMB_DATA_OUT  0x10000000	/* SMBus Data Out */
#define E1000_MANC_SMB_CLK_OUT   0x20000000	/* SMBus Clock Out */

#define E1000_MANC_SMB_DATA_OUT_SHIFT  28	/* SMBus Data Out Shift */
#define E1000_MANC_SMB_CLK_OUT_SHIFT   29	/* SMBus Clock Out Shift */

/* SW Semaphore Register */
#define E1000_SWSM_SMBI         0x00000001	/* Driver Semaphore bit */
#define E1000_SWSM_SWESMBI      0x00000002	/* FW Semaphore bit */
#define E1000_SWSM_WMNG         0x00000004	/* Wake MNG Clock */
#define E1000_SWSM_DRV_LOAD     0x00000008	/* Driver Loaded Bit */

/* FW Semaphore Register */
#define E1000_FWSM_MODE_MASK    0x0000000E	/* FW mode */
#define E1000_FWSM_MODE_SHIFT            1
#define E1000_FWSM_FW_VALID     0x00008000	/* FW established a valid mode */

#define E1000_FWSM_RSPCIPHY        0x00000040	/* Reset PHY on PCI reset */
#define E1000_FWSM_DISSW           0x10000000	/* FW disable SW Write Access */
#define E1000_FWSM_SKUSEL_MASK     0x60000000	/* LAN SKU select */
#define E1000_FWSM_SKUEL_SHIFT     29
#define E1000_FWSM_SKUSEL_EMB      0x0	/* Embedded SKU */
#define E1000_FWSM_SKUSEL_CONS     0x1	/* Consumer SKU */
#define E1000_FWSM_SKUSEL_PERF_100 0x2	/* Perf & Corp 10/100 SKU */
#define E1000_FWSM_SKUSEL_PERF_GBE 0x3	/* Perf & Copr GbE SKU */

/* FFLT Debug Register */
#define E1000_FFLT_DBG_INVC     0x00100000	/* Invalid /C/ code handling */

typedef enum {
	e1000_mng_mode_none = 0,
	e1000_mng_mode_asf,
	e1000_mng_mode_pt,
	e1000_mng_mode_ipmi,
	e1000_mng_mode_host_interface_only
} e1000_mng_mode;

/* Host Interface Control Register */
#define E1000_HICR_EN           0x00000001	/* Enable Bit - RO */
#define E1000_HICR_C            0x00000002	/* Driver sets this bit when done
						 * to put command in RAM */
#define E1000_HICR_SV           0x00000004	/* Status Validity */
#define E1000_HICR_FWR          0x00000080	/* FW reset. Set by the Host */

/* Host Interface Command Interface - Address range 0x8800-0x8EFF */
#define E1000_HI_MAX_DATA_LENGTH         252	/* Host Interface data length */
#define E1000_HI_MAX_BLOCK_BYTE_LENGTH  1792	/* Number of bytes in range */
#define E1000_HI_MAX_BLOCK_DWORD_LENGTH  448	/* Number of dwords in range */
#define E1000_HI_COMMAND_TIMEOUT         500	/* Time in ms to process HI command */

struct e1000_host_command_header {
	u8 command_id;
	u8 command_length;
	u8 command_options;	/* I/F bits for command, status for return */
	u8 checksum;
};
struct e1000_host_command_info {
	struct e1000_host_command_header command_header;	/* Command Head/Command Result Head has 4 bytes */
	u8 command_data[E1000_HI_MAX_DATA_LENGTH];	/* Command data can length 0..252 */
};

/* Host SMB register #0 */
#define E1000_HSMC0R_CLKIN      0x00000001	/* SMB Clock in */
#define E1000_HSMC0R_DATAIN     0x00000002	/* SMB Data in */
#define E1000_HSMC0R_DATAOUT    0x00000004	/* SMB Data out */
#define E1000_HSMC0R_CLKOUT     0x00000008	/* SMB Clock out */

/* Host SMB register #1 */
#define E1000_HSMC1R_CLKIN      E1000_HSMC0R_CLKIN
#define E1000_HSMC1R_DATAIN     E1000_HSMC0R_DATAIN
#define E1000_HSMC1R_DATAOUT    E1000_HSMC0R_DATAOUT
#define E1000_HSMC1R_CLKOUT     E1000_HSMC0R_CLKOUT

/* FW Status Register */
#define E1000_FWSTS_FWS_MASK    0x000000FF	/* FW Status */

/* Wake Up Packet Length */
#define E1000_WUPL_LENGTH_MASK 0x0FFF	/* Only the lower 12 bits are valid */

#define E1000_MDALIGN          4096

/* PCI-Ex registers*/

/* PCI-Ex Control Register */
#define E1000_GCR_RXD_NO_SNOOP          0x00000001
#define E1000_GCR_RXDSCW_NO_SNOOP       0x00000002
#define E1000_GCR_RXDSCR_NO_SNOOP       0x00000004
#define E1000_GCR_TXD_NO_SNOOP          0x00000008
#define E1000_GCR_TXDSCW_NO_SNOOP       0x00000010
#define E1000_GCR_TXDSCR_NO_SNOOP       0x00000020

#define PCI_EX_NO_SNOOP_ALL (E1000_GCR_RXD_NO_SNOOP         | \
                             E1000_GCR_RXDSCW_NO_SNOOP      | \
                             E1000_GCR_RXDSCR_NO_SNOOP      | \
                             E1000_GCR_TXD_NO_SNOOP         | \
                             E1000_GCR_TXDSCW_NO_SNOOP      | \
                             E1000_GCR_TXDSCR_NO_SNOOP)

#define PCI_EX_82566_SNOOP_ALL PCI_EX_NO_SNOOP_ALL

#define E1000_GCR_L1_ACT_WITHOUT_L0S_RX 0x08000000
/* Function Active and Power State to MNG */
#define E1000_FACTPS_FUNC0_POWER_STATE_MASK         0x00000003
#define E1000_FACTPS_LAN0_VALID                     0x00000004
#define E1000_FACTPS_FUNC0_AUX_EN                   0x00000008
#define E1000_FACTPS_FUNC1_POWER_STATE_MASK         0x000000C0
#define E1000_FACTPS_FUNC1_POWER_STATE_SHIFT        6
#define E1000_FACTPS_LAN1_VALID                     0x00000100
#define E1000_FACTPS_FUNC1_AUX_EN                   0x00000200
#define E1000_FACTPS_FUNC2_POWER_STATE_MASK         0x00003000
#define E1000_FACTPS_FUNC2_POWER_STATE_SHIFT        12
#define E1000_FACTPS_IDE_ENABLE                     0x00004000
#define E1000_FACTPS_FUNC2_AUX_EN                   0x00008000
#define E1000_FACTPS_FUNC3_POWER_STATE_MASK         0x000C0000
#define E1000_FACTPS_FUNC3_POWER_STATE_SHIFT        18
#define E1000_FACTPS_SP_ENABLE                      0x00100000
#define E1000_FACTPS_FUNC3_AUX_EN                   0x00200000
#define E1000_FACTPS_FUNC4_POWER_STATE_MASK         0x03000000
#define E1000_FACTPS_FUNC4_POWER_STATE_SHIFT        24
#define E1000_FACTPS_IPMI_ENABLE                    0x04000000
#define E1000_FACTPS_FUNC4_AUX_EN                   0x08000000
#define E1000_FACTPS_MNGCG                          0x20000000
#define E1000_FACTPS_LAN_FUNC_SEL                   0x40000000
#define E1000_FACTPS_PM_STATE_CHANGED               0x80000000

/* PCI-Ex Config Space */
#define PCI_EX_LINK_STATUS           0x12
#define PCI_EX_LINK_WIDTH_MASK       0x3F0
#define PCI_EX_LINK_WIDTH_SHIFT      4

/* EEPROM Commands - Microwire */
#define EEPROM_READ_OPCODE_MICROWIRE  0x6	/* EEPROM read opcode */
#define EEPROM_WRITE_OPCODE_MICROWIRE 0x5	/* EEPROM write opcode */
#define EEPROM_ERASE_OPCODE_MICROWIRE 0x7	/* EEPROM erase opcode */
#define EEPROM_EWEN_OPCODE_MICROWIRE  0x13	/* EEPROM erase/write enable */
#define EEPROM_EWDS_OPCODE_MICROWIRE  0x10	/* EEPROM erase/write disable */

/* EEPROM Commands - SPI */
#define EEPROM_MAX_RETRY_SPI        5000	/* Max wait of 5ms, for RDY signal */
#define EEPROM_READ_OPCODE_SPI      0x03	/* EEPROM read opcode */
#define EEPROM_WRITE_OPCODE_SPI     0x02	/* EEPROM write opcode */
#define EEPROM_A8_OPCODE_SPI        0x08	/* opcode bit-3 = address bit-8 */
#define EEPROM_WREN_OPCODE_SPI      0x06	/* EEPROM set Write Enable latch */
#define EEPROM_WRDI_OPCODE_SPI      0x04	/* EEPROM reset Write Enable latch */
#define EEPROM_RDSR_OPCODE_SPI      0x05	/* EEPROM read Status register */
#define EEPROM_WRSR_OPCODE_SPI      0x01	/* EEPROM write Status register */
#define EEPROM_ERASE4K_OPCODE_SPI   0x20	/* EEPROM ERASE 4KB */
#define EEPROM_ERASE64K_OPCODE_SPI  0xD8	/* EEPROM ERASE 64KB */
#define EEPROM_ERASE256_OPCODE_SPI  0xDB	/* EEPROM ERASE 256B */

/* EEPROM Size definitions */
#define EEPROM_WORD_SIZE_SHIFT  6
#define EEPROM_SIZE_SHIFT       10
#define EEPROM_SIZE_MASK        0x1C00

/* EEPROM Word Offsets */
#define EEPROM_COMPAT                 0x0003
#define EEPROM_ID_LED_SETTINGS        0x0004
#define EEPROM_VERSION                0x0005
#define EEPROM_SERDES_AMPLITUDE       0x0006	/* For SERDES output amplitude adjustment. */
#define EEPROM_PHY_CLASS_WORD         0x0007
#define EEPROM_INIT_CONTROL1_REG      0x000A
#define EEPROM_INIT_CONTROL2_REG      0x000F
#define EEPROM_SWDEF_PINS_CTRL_PORT_1 0x0010
#define EEPROM_INIT_CONTROL3_PORT_B   0x0014
#define EEPROM_INIT_3GIO_3            0x001A
#define EEPROM_SWDEF_PINS_CTRL_PORT_0 0x0020
#define EEPROM_INIT_CONTROL3_PORT_A   0x0024
#define EEPROM_CFG                    0x0012
#define EEPROM_FLASH_VERSION          0x0032
#define EEPROM_CHECKSUM_REG           0x003F

#define E1000_EEPROM_CFG_DONE         0x00040000	/* MNG config cycle done */
#define E1000_EEPROM_CFG_DONE_PORT_1  0x00080000	/* ...for second port */

/* Word definitions for ID LED Settings */
#define ID_LED_RESERVED_0000 0x0000
#define ID_LED_RESERVED_FFFF 0xFFFF
#define ID_LED_DEFAULT       ((ID_LED_OFF1_ON2 << 12) | \
                              (ID_LED_OFF1_OFF2 << 8) | \
                              (ID_LED_DEF1_DEF2 << 4) | \
                              (ID_LED_DEF1_DEF2))
#define ID_LED_DEF1_DEF2     0x1
#define ID_LED_DEF1_ON2      0x2
#define ID_LED_DEF1_OFF2     0x3
#define ID_LED_ON1_DEF2      0x4
#define ID_LED_ON1_ON2       0x5
#define ID_LED_ON1_OFF2      0x6
#define ID_LED_OFF1_DEF2     0x7
#define ID_LED_OFF1_ON2      0x8
#define ID_LED_OFF1_OFF2     0x9

#define IGP_ACTIVITY_LED_MASK   0xFFFFF0FF
#define IGP_ACTIVITY_LED_ENABLE 0x0300
#define IGP_LED3_MODE           0x07000000

/* Mask bits for SERDES amplitude adjustment in Word 6 of the EEPROM */
#define EEPROM_SERDES_AMPLITUDE_MASK  0x000F

/* Mask bit for PHY class in Word 7 of the EEPROM */
#define EEPROM_PHY_CLASS_A   0x8000

/* Mask bits for fields in Word 0x0a of the EEPROM */
#define EEPROM_WORD0A_ILOS   0x0010
#define EEPROM_WORD0A_SWDPIO 0x01E0
#define EEPROM_WORD0A_LRST   0x0200
#define EEPROM_WORD0A_FD     0x0400
#define EEPROM_WORD0A_66MHZ  0x0800

/* Mask bits for fields in Word 0x0f of the EEPROM */
#define EEPROM_WORD0F_PAUSE_MASK 0x3000
#define EEPROM_WORD0F_PAUSE      0x1000
#define EEPROM_WORD0F_ASM_DIR    0x2000
#define EEPROM_WORD0F_ANE        0x0800
#define EEPROM_WORD0F_SWPDIO_EXT 0x00F0
#define EEPROM_WORD0F_LPLU       0x0001

/* Mask bits for fields in Word 0x10/0x20 of the EEPROM */
#define EEPROM_WORD1020_GIGA_DISABLE         0x0010
#define EEPROM_WORD1020_GIGA_DISABLE_NON_D0A 0x0008

/* Mask bits for fields in Word 0x1a of the EEPROM */
#define EEPROM_WORD1A_ASPM_MASK  0x000C

/* For checksumming, the sum of all words in the EEPROM should equal 0xBABA. */
#define EEPROM_SUM 0xBABA

/* EEPROM Map defines (WORD OFFSETS)*/
#define EEPROM_NODE_ADDRESS_BYTE_0 0
#define EEPROM_PBA_BYTE_1          8

#define EEPROM_RESERVED_WORD          0xFFFF

/* EEPROM Map Sizes (Byte Counts) */
#define PBA_SIZE 4

/* Collision related configuration parameters */
#define E1000_COLLISION_THRESHOLD       15
#define E1000_CT_SHIFT                  4
/* Collision distance is a 0-based value that applies to
 * half-duplex-capable hardware only. */
#define E1000_COLLISION_DISTANCE        63
#define E1000_COLLISION_DISTANCE_82542  64
#define E1000_FDX_COLLISION_DISTANCE    E1000_COLLISION_DISTANCE
#define E1000_HDX_COLLISION_DISTANCE    E1000_COLLISION_DISTANCE
#define E1000_COLD_SHIFT                12

/* Number of Transmit and Receive Descriptors must be a multiple of 8 */
#define REQ_TX_DESCRIPTOR_MULTIPLE  8
#define REQ_RX_DESCRIPTOR_MULTIPLE  8

/* Default values for the transmit IPG register */
#define DEFAULT_82542_TIPG_IPGT        10
#define DEFAULT_82543_TIPG_IPGT_FIBER  9
#define DEFAULT_82543_TIPG_IPGT_COPPER 8

#define E1000_TIPG_IPGT_MASK  0x000003FF
#define E1000_TIPG_IPGR1_MASK 0x000FFC00
#define E1000_TIPG_IPGR2_MASK 0x3FF00000

#define DEFAULT_82542_TIPG_IPGR1 2
#define DEFAULT_82543_TIPG_IPGR1 8
#define E1000_TIPG_IPGR1_SHIFT  10

#define DEFAULT_82542_TIPG_IPGR2 10
#define DEFAULT_82543_TIPG_IPGR2 6
#define E1000_TIPG_IPGR2_SHIFT  20

#define E1000_TXDMAC_DPP 0x00000001

/* Adaptive IFS defines */
#define TX_THRESHOLD_START     8
#define TX_THRESHOLD_INCREMENT 10
#define TX_THRESHOLD_DECREMENT 1
#define TX_THRESHOLD_STOP      190
#define TX_THRESHOLD_DISABLE   0
#define TX_THRESHOLD_TIMER_MS  10000
#define MIN_NUM_XMITS          1000
#define IFS_MAX                80
#define IFS_STEP               10
#define IFS_MIN                40
#define IFS_RATIO              4

/* Extended Configuration Control and Size */
#define E1000_EXTCNF_CTRL_PCIE_WRITE_ENABLE 0x00000001
#define E1000_EXTCNF_CTRL_PHY_WRITE_ENABLE  0x00000002
#define E1000_EXTCNF_CTRL_D_UD_ENABLE       0x00000004
#define E1000_EXTCNF_CTRL_D_UD_LATENCY      0x00000008
#define E1000_EXTCNF_CTRL_D_UD_OWNER        0x00000010
#define E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP 0x00000020
#define E1000_EXTCNF_CTRL_MDIO_HW_OWNERSHIP 0x00000040
#define E1000_EXTCNF_CTRL_EXT_CNF_POINTER   0x0FFF0000

#define E1000_EXTCNF_SIZE_EXT_PHY_LENGTH    0x000000FF
#define E1000_EXTCNF_SIZE_EXT_DOCK_LENGTH   0x0000FF00
#define E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH   0x00FF0000
#define E1000_EXTCNF_CTRL_LCD_WRITE_ENABLE  0x00000001
#define E1000_EXTCNF_CTRL_SWFLAG            0x00000020

/* PBA constants */
#define E1000_PBA_8K 0x0008	/* 8KB, default Rx allocation */
#define E1000_PBA_12K 0x000C	/* 12KB, default Rx allocation */
#define E1000_PBA_16K 0x0010	/* 16KB, default TX allocation */
#define E1000_PBA_20K 0x0014
#define E1000_PBA_22K 0x0016
#define E1000_PBA_24K 0x0018
#define E1000_PBA_30K 0x001E
#define E1000_PBA_32K 0x0020
#define E1000_PBA_34K 0x0022
#define E1000_PBA_38K 0x0026
#define E1000_PBA_40K 0x0028
#define E1000_PBA_48K 0x0030	/* 48KB, default RX allocation */

#define E1000_PBS_16K E1000_PBA_16K

/* Flow Control Constants */
#define FLOW_CONTROL_ADDRESS_LOW  0x00C28001
#define FLOW_CONTROL_ADDRESS_HIGH 0x00000100
#define FLOW_CONTROL_TYPE         0x8808

/* The historical defaults for the flow control values are given below. */
#define FC_DEFAULT_HI_THRESH        (0x8000)	/* 32KB */
#define FC_DEFAULT_LO_THRESH        (0x4000)	/* 16KB */
#define FC_DEFAULT_TX_TIMER         (0x100)	/* ~130 us */

/* PCIX Config space */
#define PCIX_COMMAND_REGISTER    0xE6
#define PCIX_STATUS_REGISTER_LO  0xE8
#define PCIX_STATUS_REGISTER_HI  0xEA

#define PCIX_COMMAND_MMRBC_MASK      0x000C
#define PCIX_COMMAND_MMRBC_SHIFT     0x2
#define PCIX_STATUS_HI_MMRBC_MASK    0x0060
#define PCIX_STATUS_HI_MMRBC_SHIFT   0x5
#define PCIX_STATUS_HI_MMRBC_4K      0x3
#define PCIX_STATUS_HI_MMRBC_2K      0x2

/* Number of bits required to shift right the "pause" bits from the
 * EEPROM (bits 13:12) to the "pause" (bits 8:7) field in the TXCW register.
 */
#define PAUSE_SHIFT 5

/* Number of bits required to shift left the "SWDPIO" bits from the
 * EEPROM (bits 8:5) to the "SWDPIO" (bits 25:22) field in the CTRL register.
 */
#define SWDPIO_SHIFT 17

/* Number of bits required to shift left the "SWDPIO_EXT" bits from the
 * EEPROM word F (bits 7:4) to the bits 11:8 of The Extended CTRL register.
 */
#define SWDPIO__EXT_SHIFT 4

/* Number of bits required to shift left the "ILOS" bit from the EEPROM
 * (bit 4) to the "ILOS" (bit 7) field in the CTRL register.
 */
#define ILOS_SHIFT  3

#define RECEIVE_BUFFER_ALIGN_SIZE  (256)

/* Number of milliseconds we wait for auto-negotiation to complete */
#define LINK_UP_TIMEOUT             500

/* Number of milliseconds we wait for Eeprom auto read bit done after MAC reset */
#define AUTO_READ_DONE_TIMEOUT      10
/* Number of milliseconds we wait for PHY configuration done after MAC reset */
#define PHY_CFG_TIMEOUT             100

#define E1000_TX_BUFFER_SIZE ((u32)1514)

/* The carrier extension symbol, as received by the NIC. */
#define CARRIER_EXTENSION   0x0F

/* TBI_ACCEPT macro definition:
 *
 * This macro requires:
 *      adapter = a pointer to struct e1000_hw
 *      status = the 8 bit status field of the RX descriptor with EOP set
 *      error = the 8 bit error field of the RX descriptor with EOP set
 *      length = the sum of all the length fields of the RX descriptors that
 *               make up the current frame
 *      last_byte = the last byte of the frame DMAed by the hardware
 *      max_frame_length = the maximum frame length we want to accept.
 *      min_frame_length = the minimum frame length we want to accept.
 *
 * This macro is a conditional that should be used in the interrupt
 * handler's Rx processing routine when RxErrors have been detected.
 *
 * Typical use:
 *  ...
 *  if (TBI_ACCEPT) {
 *      accept_frame = true;
 *      e1000_tbi_adjust_stats(adapter, MacAddress);
 *      frame_length--;
 *  } else {
 *      accept_frame = false;
 *  }
 *  ...
 */

#define TBI_ACCEPT(adapter, status, errors, length, last_byte) \
    ((adapter)->tbi_compatibility_on && \
     (((errors) & E1000_RXD_ERR_FRAME_ERR_MASK) == E1000_RXD_ERR_CE) && \
     ((last_byte) == CARRIER_EXTENSION) && \
     (((status) & E1000_RXD_STAT_VP) ? \
          (((length) > ((adapter)->min_frame_size - VLAN_TAG_SIZE)) && \
           ((length) <= ((adapter)->max_frame_size + 1))) : \
          (((length) > (adapter)->min_frame_size) && \
           ((length) <= ((adapter)->max_frame_size + VLAN_TAG_SIZE + 1)))))

/* Structures, enums, and macros for the PHY */

/* Bit definitions for the Management Data IO (MDIO) and Management Data
 * Clock (MDC) pins in the Device Control Register.
 */
#define E1000_CTRL_PHY_RESET_DIR  E1000_CTRL_SWDPIO0
#define E1000_CTRL_PHY_RESET      E1000_CTRL_SWDPIN0
#define E1000_CTRL_MDIO_DIR       E1000_CTRL_SWDPIO2
#define E1000_CTRL_MDIO           E1000_CTRL_SWDPIN2
#define E1000_CTRL_MDC_DIR        E1000_CTRL_SWDPIO3
#define E1000_CTRL_MDC            E1000_CTRL_SWDPIN3
#define E1000_CTRL_PHY_RESET_DIR4 E1000_CTRL_EXT_SDP4_DIR
#define E1000_CTRL_PHY_RESET4     E1000_CTRL_EXT_SDP4_DATA

/* PHY 1000 MII Register/Bit Definitions */
/* PHY Registers defined by IEEE */
#define PHY_CTRL         0x00	/* Control Register */
#define PHY_STATUS       0x01	/* Status Register */
#define PHY_ID1          0x02	/* Phy Id Reg (word 1) */
#define PHY_ID2          0x03	/* Phy Id Reg (word 2) */
#define PHY_AUTONEG_ADV  0x04	/* Autoneg Advertisement */
#define PHY_LP_ABILITY   0x05	/* Link Partner Ability (Base Page) */
#define PHY_AUTONEG_EXP  0x06	/* Autoneg Expansion Reg */
#define PHY_NEXT_PAGE_TX 0x07	/* Next Page TX */
#define PHY_LP_NEXT_PAGE 0x08	/* Link Partner Next Page */
#define PHY_1000T_CTRL   0x09	/* 1000Base-T Control Reg */
#define PHY_1000T_STATUS 0x0A	/* 1000Base-T Status Reg */
#define PHY_EXT_STATUS   0x0F	/* Extended Status Reg */

#define MAX_PHY_REG_ADDRESS        0x1F	/* 5 bit address bus (0-0x1F) */
#define MAX_PHY_MULTI_PAGE_REG     0xF	/* Registers equal on all pages */

/* M88E1000 Specific Registers */
#define M88E1000_PHY_SPEC_CTRL     0x10	/* PHY Specific Control Register */
#define M88E1000_PHY_SPEC_STATUS   0x11	/* PHY Specific Status Register */
#define M88E1000_INT_ENABLE        0x12	/* Interrupt Enable Register */
#define M88E1000_INT_STATUS        0x13	/* Interrupt Status Register */
#define M88E1000_EXT_PHY_SPEC_CTRL 0x14	/* Extended PHY Specific Control */
#define M88E1000_RX_ERR_CNTR       0x15	/* Receive Error Counter */

#define M88E1000_PHY_EXT_CTRL      0x1A	/* PHY extend control register */
#define M88E1000_PHY_PAGE_SELECT   0x1D	/* Reg 29 for page number setting */
#define M88E1000_PHY_GEN_CONTROL   0x1E	/* Its meaning depends on reg 29 */
#define M88E1000_PHY_VCO_REG_BIT8  0x100	/* Bits 8 & 11 are adjusted for */
#define M88E1000_PHY_VCO_REG_BIT11 0x800	/* improved BER performance */

#define IGP01E1000_IEEE_REGS_PAGE  0x0000
#define IGP01E1000_IEEE_RESTART_AUTONEG 0x3300
#define IGP01E1000_IEEE_FORCE_GIGA      0x0140

/* IGP01E1000 Specific Registers */
#define IGP01E1000_PHY_PORT_CONFIG 0x10	/* PHY Specific Port Config Register */
#define IGP01E1000_PHY_PORT_STATUS 0x11	/* PHY Specific Status Register */
#define IGP01E1000_PHY_PORT_CTRL   0x12	/* PHY Specific Control Register */
#define IGP01E1000_PHY_LINK_HEALTH 0x13	/* PHY Link Health Register */
#define IGP01E1000_GMII_FIFO       0x14	/* GMII FIFO Register */
#define IGP01E1000_PHY_CHANNEL_QUALITY 0x15	/* PHY Channel Quality Register */
#define IGP02E1000_PHY_POWER_MGMT      0x19
#define IGP01E1000_PHY_PAGE_SELECT     0x1F	/* PHY Page Select Core Register */

/* IGP01E1000 AGC Registers - stores the cable length values*/
#define IGP01E1000_PHY_AGC_A        0x1172
#define IGP01E1000_PHY_AGC_B        0x1272
#define IGP01E1000_PHY_AGC_C        0x1472
#define IGP01E1000_PHY_AGC_D        0x1872

/* IGP02E1000 AGC Registers for cable length values */
#define IGP02E1000_PHY_AGC_A        0x11B1
#define IGP02E1000_PHY_AGC_B        0x12B1
#define IGP02E1000_PHY_AGC_C        0x14B1
#define IGP02E1000_PHY_AGC_D        0x18B1

/* IGP01E1000 DSP Reset Register */
#define IGP01E1000_PHY_DSP_RESET   0x1F33
#define IGP01E1000_PHY_DSP_SET     0x1F71
#define IGP01E1000_PHY_DSP_FFE     0x1F35

#define IGP01E1000_PHY_CHANNEL_NUM    4
#define IGP02E1000_PHY_CHANNEL_NUM    4

#define IGP01E1000_PHY_AGC_PARAM_A    0x1171
#define IGP01E1000_PHY_AGC_PARAM_B    0x1271
#define IGP01E1000_PHY_AGC_PARAM_C    0x1471
#define IGP01E1000_PHY_AGC_PARAM_D    0x1871

#define IGP01E1000_PHY_EDAC_MU_INDEX        0xC000
#define IGP01E1000_PHY_EDAC_SIGN_EXT_9_BITS 0x8000

#define IGP01E1000_PHY_ANALOG_TX_STATE      0x2890
#define IGP01E1000_PHY_ANALOG_CLASS_A       0x2000
#define IGP01E1000_PHY_FORCE_ANALOG_ENABLE  0x0004
#define IGP01E1000_PHY_DSP_FFE_CM_CP        0x0069

#define IGP01E1000_PHY_DSP_FFE_DEFAULT      0x002A
/* IGP01E1000 PCS Initialization register - stores the polarity status when
 * speed = 1000 Mbps. */
#define IGP01E1000_PHY_PCS_INIT_REG  0x00B4
#define IGP01E1000_PHY_PCS_CTRL_REG  0x00B5

#define IGP01E1000_ANALOG_REGS_PAGE  0x20C0

/* PHY Control Register */
#define MII_CR_SPEED_SELECT_MSB 0x0040	/* bits 6,13: 10=1000, 01=100, 00=10 */
#define MII_CR_COLL_TEST_ENABLE 0x0080	/* Collision test enable */
#define MII_CR_FULL_DUPLEX      0x0100	/* FDX =1, half duplex =0 */
#define MII_CR_RESTART_AUTO_NEG 0x0200	/* Restart auto negotiation */
#define MII_CR_ISOLATE          0x0400	/* Isolate PHY from MII */
#define MII_CR_POWER_DOWN       0x0800	/* Power down */
#define MII_CR_AUTO_NEG_EN      0x1000	/* Auto Neg Enable */
#define MII_CR_SPEED_SELECT_LSB 0x2000	/* bits 6,13: 10=1000, 01=100, 00=10 */
#define MII_CR_LOOPBACK         0x4000	/* 0 = normal, 1 = loopback */
#define MII_CR_RESET            0x8000	/* 0 = normal, 1 = PHY reset */

/* PHY Status Register */
#define MII_SR_EXTENDED_CAPS     0x0001	/* Extended register capabilities */
#define MII_SR_JABBER_DETECT     0x0002	/* Jabber Detected */
#define MII_SR_LINK_STATUS       0x0004	/* Link Status 1 = link */
#define MII_SR_AUTONEG_CAPS      0x0008	/* Auto Neg Capable */
#define MII_SR_REMOTE_FAULT      0x0010	/* Remote Fault Detect */
#define MII_SR_AUTONEG_COMPLETE  0x0020	/* Auto Neg Complete */
#define MII_SR_PREAMBLE_SUPPRESS 0x0040	/* Preamble may be suppressed */
#define MII_SR_EXTENDED_STATUS   0x0100	/* Ext. status info in Reg 0x0F */
#define MII_SR_100T2_HD_CAPS     0x0200	/* 100T2 Half Duplex Capable */
#define MII_SR_100T2_FD_CAPS     0x0400	/* 100T2 Full Duplex Capable */
#define MII_SR_10T_HD_CAPS       0x0800	/* 10T   Half Duplex Capable */
#define MII_SR_10T_FD_CAPS       0x1000	/* 10T   Full Duplex Capable */
#define MII_SR_100X_HD_CAPS      0x2000	/* 100X  Half Duplex Capable */
#define MII_SR_100X_FD_CAPS      0x4000	/* 100X  Full Duplex Capable */
#define MII_SR_100T4_CAPS        0x8000	/* 100T4 Capable */

/* Autoneg Advertisement Register */
#define NWAY_AR_SELECTOR_FIELD 0x0001	/* indicates IEEE 802.3 CSMA/CD */
#define NWAY_AR_10T_HD_CAPS    0x0020	/* 10T   Half Duplex Capable */
#define NWAY_AR_10T_FD_CAPS    0x0040	/* 10T   Full Duplex Capable */
#define NWAY_AR_100TX_HD_CAPS  0x0080	/* 100TX Half Duplex Capable */
#define NWAY_AR_100TX_FD_CAPS  0x0100	/* 100TX Full Duplex Capable */
#define NWAY_AR_100T4_CAPS     0x0200	/* 100T4 Capable */
#define NWAY_AR_PAUSE          0x0400	/* Pause operation desired */
#define NWAY_AR_ASM_DIR        0x0800	/* Asymmetric Pause Direction bit */
#define NWAY_AR_REMOTE_FAULT   0x2000	/* Remote Fault detected */
#define NWAY_AR_NEXT_PAGE      0x8000	/* Next Page ability supported */

/* Link Partner Ability Register (Base Page) */
#define NWAY_LPAR_SELECTOR_FIELD 0x0000	/* LP protocol selector field */
#define NWAY_LPAR_10T_HD_CAPS    0x0020	/* LP is 10T   Half Duplex Capable */
#define NWAY_LPAR_10T_FD_CAPS    0x0040	/* LP is 10T   Full Duplex Capable */
#define NWAY_LPAR_100TX_HD_CAPS  0x0080	/* LP is 100TX Half Duplex Capable */
#define NWAY_LPAR_100TX_FD_CAPS  0x0100	/* LP is 100TX Full Duplex Capable */
#define NWAY_LPAR_100T4_CAPS     0x0200	/* LP is 100T4 Capable */
#define NWAY_LPAR_PAUSE          0x0400	/* LP Pause operation desired */
#define NWAY_LPAR_ASM_DIR        0x0800	/* LP Asymmetric Pause Direction bit */
#define NWAY_LPAR_REMOTE_FAULT   0x2000	/* LP has detected Remote Fault */
#define NWAY_LPAR_ACKNOWLEDGE    0x4000	/* LP has rx'd link code word */
#define NWAY_LPAR_NEXT_PAGE      0x8000	/* Next Page ability supported */

/* Autoneg Expansion Register */
#define NWAY_ER_LP_NWAY_CAPS      0x0001	/* LP has Auto Neg Capability */
#define NWAY_ER_PAGE_RXD          0x0002	/* LP is 10T   Half Duplex Capable */
#define NWAY_ER_NEXT_PAGE_CAPS    0x0004	/* LP is 10T   Full Duplex Capable */
#define NWAY_ER_LP_NEXT_PAGE_CAPS 0x0008	/* LP is 100TX Half Duplex Capable */
#define NWAY_ER_PAR_DETECT_FAULT  0x0010	/* LP is 100TX Full Duplex Capable */

/* Next Page TX Register */
#define NPTX_MSG_CODE_FIELD 0x0001	/* NP msg code or unformatted data */
#define NPTX_TOGGLE         0x0800	/* Toggles between exchanges
					 * of different NP
					 */
#define NPTX_ACKNOWLDGE2    0x1000	/* 1 = will comply with msg
					 * 0 = cannot comply with msg
					 */
#define NPTX_MSG_PAGE       0x2000	/* formatted(1)/unformatted(0) pg */
#define NPTX_NEXT_PAGE      0x8000	/* 1 = addition NP will follow
					 * 0 = sending last NP
					 */

/* Link Partner Next Page Register */
#define LP_RNPR_MSG_CODE_FIELD 0x0001	/* NP msg code or unformatted data */
#define LP_RNPR_TOGGLE         0x0800	/* Toggles between exchanges
					 * of different NP
					 */
#define LP_RNPR_ACKNOWLDGE2    0x1000	/* 1 = will comply with msg
					 * 0 = cannot comply with msg
					 */
#define LP_RNPR_MSG_PAGE       0x2000	/* formatted(1)/unformatted(0) pg */
#define LP_RNPR_ACKNOWLDGE     0x4000	/* 1 = ACK / 0 = NO ACK */
#define LP_RNPR_NEXT_PAGE      0x8000	/* 1 = addition NP will follow
					 * 0 = sending last NP
					 */

/* 1000BASE-T Control Register */
#define CR_1000T_ASYM_PAUSE      0x0080	/* Advertise asymmetric pause bit */
#define CR_1000T_HD_CAPS         0x0100	/* Advertise 1000T HD capability */
#define CR_1000T_FD_CAPS         0x0200	/* Advertise 1000T FD capability  */
#define CR_1000T_REPEATER_DTE    0x0400	/* 1=Repeater/switch device port */
					/* 0=DTE device */
#define CR_1000T_MS_VALUE        0x0800	/* 1=Configure PHY as Master */
					/* 0=Configure PHY as Slave */
#define CR_1000T_MS_ENABLE       0x1000	/* 1=Master/Slave manual config value */
					/* 0=Automatic Master/Slave config */
#define CR_1000T_TEST_MODE_NORMAL 0x0000	/* Normal Operation */
#define CR_1000T_TEST_MODE_1     0x2000	/* Transmit Waveform test */
#define CR_1000T_TEST_MODE_2     0x4000	/* Master Transmit Jitter test */
#define CR_1000T_TEST_MODE_3     0x6000	/* Slave Transmit Jitter test */
#define CR_1000T_TEST_MODE_4     0x8000	/* Transmitter Distortion test */

/* 1000BASE-T Status Register */
#define SR_1000T_IDLE_ERROR_CNT   0x00FF	/* Num idle errors since last read */
#define SR_1000T_ASYM_PAUSE_DIR   0x0100	/* LP asymmetric pause direction bit */
#define SR_1000T_LP_HD_CAPS       0x0400	/* LP is 1000T HD capable */
#define SR_1000T_LP_FD_CAPS       0x0800	/* LP is 1000T FD capable */
#define SR_1000T_REMOTE_RX_STATUS 0x1000	/* Remote receiver OK */
#define SR_1000T_LOCAL_RX_STATUS  0x2000	/* Local receiver OK */
#define SR_1000T_MS_CONFIG_RES    0x4000	/* 1=Local TX is Master, 0=Slave */
#define SR_1000T_MS_CONFIG_FAULT  0x8000	/* Master/Slave config fault */
#define SR_1000T_REMOTE_RX_STATUS_SHIFT          12
#define SR_1000T_LOCAL_RX_STATUS_SHIFT           13
#define SR_1000T_PHY_EXCESSIVE_IDLE_ERR_COUNT    5
#define FFE_IDLE_ERR_COUNT_TIMEOUT_20            20
#define FFE_IDLE_ERR_COUNT_TIMEOUT_100           100

/* Extended Status Register */
#define IEEE_ESR_1000T_HD_CAPS 0x1000	/* 1000T HD capable */
#define IEEE_ESR_1000T_FD_CAPS 0x2000	/* 1000T FD capable */
#define IEEE_ESR_1000X_HD_CAPS 0x4000	/* 1000X HD capable */
#define IEEE_ESR_1000X_FD_CAPS 0x8000	/* 1000X FD capable */

#define PHY_TX_POLARITY_MASK   0x0100	/* register 10h bit 8 (polarity bit) */
#define PHY_TX_NORMAL_POLARITY 0	/* register 10h bit 8 (normal polarity) */

#define AUTO_POLARITY_DISABLE  0x0010	/* register 11h bit 4 */
				      /* (0=enable, 1=disable) */

/* M88E1000 PHY Specific Control Register */
#define M88E1000_PSCR_JABBER_DISABLE    0x0001	/* 1=Jabber Function disabled */
#define M88E1000_PSCR_POLARITY_REVERSAL 0x0002	/* 1=Polarity Reversal enabled */
#define M88E1000_PSCR_SQE_TEST          0x0004	/* 1=SQE Test enabled */
#define M88E1000_PSCR_CLK125_DISABLE    0x0010	/* 1=CLK125 low,
						 * 0=CLK125 toggling
						 */
#define M88E1000_PSCR_MDI_MANUAL_MODE  0x0000	/* MDI Crossover Mode bits 6:5 */
					       /* Manual MDI configuration */
#define M88E1000_PSCR_MDIX_MANUAL_MODE 0x0020	/* Manual MDIX configuration */
#define M88E1000_PSCR_AUTO_X_1000T     0x0040	/* 1000BASE-T: Auto crossover,
						 *  100BASE-TX/10BASE-T:
						 *  MDI Mode
						 */
#define M88E1000_PSCR_AUTO_X_MODE      0x0060	/* Auto crossover enabled
						 * all speeds.
						 */
#define M88E1000_PSCR_10BT_EXT_DIST_ENABLE 0x0080
					/* 1=Enable Extended 10BASE-T distance
					 * (Lower 10BASE-T RX Threshold)
					 * 0=Normal 10BASE-T RX Threshold */
#define M88E1000_PSCR_MII_5BIT_ENABLE      0x0100
					/* 1=5-Bit interface in 100BASE-TX
					 * 0=MII interface in 100BASE-TX */
#define M88E1000_PSCR_SCRAMBLER_DISABLE    0x0200	/* 1=Scrambler disable */
#define M88E1000_PSCR_FORCE_LINK_GOOD      0x0400	/* 1=Force link good */
#define M88E1000_PSCR_ASSERT_CRS_ON_TX     0x0800	/* 1=Assert CRS on Transmit */

#define M88E1000_PSCR_POLARITY_REVERSAL_SHIFT    1
#define M88E1000_PSCR_AUTO_X_MODE_SHIFT          5
#define M88E1000_PSCR_10BT_EXT_DIST_ENABLE_SHIFT 7

/* M88E1000 PHY Specific Status Register */
#define M88E1000_PSSR_JABBER             0x0001	/* 1=Jabber */
#define M88E1000_PSSR_REV_POLARITY       0x0002	/* 1=Polarity reversed */
#define M88E1000_PSSR_DOWNSHIFT          0x0020	/* 1=Downshifted */
#define M88E1000_PSSR_MDIX               0x0040	/* 1=MDIX; 0=MDI */
#define M88E1000_PSSR_CABLE_LENGTH       0x0380	/* 0=<50M;1=50-80M;2=80-110M;
						 * 3=110-140M;4=>140M */
#define M88E1000_PSSR_LINK               0x0400	/* 1=Link up, 0=Link down */
#define M88E1000_PSSR_SPD_DPLX_RESOLVED  0x0800	/* 1=Speed & Duplex resolved */
#define M88E1000_PSSR_PAGE_RCVD          0x1000	/* 1=Page received */
#define M88E1000_PSSR_DPLX               0x2000	/* 1=Duplex 0=Half Duplex */
#define M88E1000_PSSR_SPEED              0xC000	/* Speed, bits 14:15 */
#define M88E1000_PSSR_10MBS              0x0000	/* 00=10Mbs */
#define M88E1000_PSSR_100MBS             0x4000	/* 01=100Mbs */
#define M88E1000_PSSR_1000MBS            0x8000	/* 10=1000Mbs */

#define M88E1000_PSSR_REV_POLARITY_SHIFT 1
#define M88E1000_PSSR_DOWNSHIFT_SHIFT    5
#define M88E1000_PSSR_MDIX_SHIFT         6
#define M88E1000_PSSR_CABLE_LENGTH_SHIFT 7

/* M88E1000 Extended PHY Specific Control Register */
#define M88E1000_EPSCR_FIBER_LOOPBACK 0x4000	/* 1=Fiber loopback */
#define M88E1000_EPSCR_DOWN_NO_IDLE   0x8000	/* 1=Lost lock detect enabled.
						 * Will assert lost lock and bring
						 * link down if idle not seen
						 * within 1ms in 1000BASE-T
						 */
/* Number of times we will attempt to autonegotiate before downshifting if we
 * are the master */
#define M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK 0x0C00
#define M88E1000_EPSCR_MASTER_DOWNSHIFT_1X   0x0000
#define M88E1000_EPSCR_MASTER_DOWNSHIFT_2X   0x0400
#define M88E1000_EPSCR_MASTER_DOWNSHIFT_3X   0x0800
#define M88E1000_EPSCR_MASTER_DOWNSHIFT_4X   0x0C00
/* Number of times we will attempt to autonegotiate before downshifting if we
 * are the slave */
#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK  0x0300
#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_DIS   0x0000
#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X    0x0100
#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_2X    0x0200
#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_3X    0x0300
#define M88E1000_EPSCR_TX_CLK_2_5     0x0060	/* 2.5 MHz TX_CLK */
#define M88E1000_EPSCR_TX_CLK_25      0x0070	/* 25  MHz TX_CLK */
#define M88E1000_EPSCR_TX_CLK_0       0x0000	/* NO  TX_CLK */

/* M88EC018 Rev 2 specific DownShift settings */
#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_MASK  0x0E00
#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_1X    0x0000
#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_2X    0x0200
#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_3X    0x0400
#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_4X    0x0600
#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_5X    0x0800
#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_6X    0x0A00
#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_7X    0x0C00
#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_8X    0x0E00

/* IGP01E1000 Specific Port Config Register - R/W */
#define IGP01E1000_PSCFR_AUTO_MDIX_PAR_DETECT  0x0010
#define IGP01E1000_PSCFR_PRE_EN                0x0020
#define IGP01E1000_PSCFR_SMART_SPEED           0x0080
#define IGP01E1000_PSCFR_DISABLE_TPLOOPBACK    0x0100
#define IGP01E1000_PSCFR_DISABLE_JABBER        0x0400
#define IGP01E1000_PSCFR_DISABLE_TRANSMIT      0x2000

/* IGP01E1000 Specific Port Status Register - R/O */
#define IGP01E1000_PSSR_AUTONEG_FAILED         0x0001	/* RO LH SC */
#define IGP01E1000_PSSR_POLARITY_REVERSED      0x0002
#define IGP01E1000_PSSR_CABLE_LENGTH           0x007C
#define IGP01E1000_PSSR_FULL_DUPLEX            0x0200
#define IGP01E1000_PSSR_LINK_UP                0x0400
#define IGP01E1000_PSSR_MDIX                   0x0800
#define IGP01E1000_PSSR_SPEED_MASK             0xC000	/* speed bits mask */
#define IGP01E1000_PSSR_SPEED_10MBPS           0x4000
#define IGP01E1000_PSSR_SPEED_100MBPS          0x8000
#define IGP01E1000_PSSR_SPEED_1000MBPS         0xC000
#define IGP01E1000_PSSR_CABLE_LENGTH_SHIFT     0x0002	/* shift right 2 */
#define IGP01E1000_PSSR_MDIX_SHIFT             0x000B	/* shift right 11 */

/* IGP01E1000 Specific Port Control Register - R/W */
#define IGP01E1000_PSCR_TP_LOOPBACK            0x0010
#define IGP01E1000_PSCR_CORRECT_NC_SCMBLR      0x0200
#define IGP01E1000_PSCR_TEN_CRS_SELECT         0x0400
#define IGP01E1000_PSCR_FLIP_CHIP              0x0800
#define IGP01E1000_PSCR_AUTO_MDIX              0x1000
#define IGP01E1000_PSCR_FORCE_MDI_MDIX         0x2000	/* 0-MDI, 1-MDIX */

/* IGP01E1000 Specific Port Link Health Register */
#define IGP01E1000_PLHR_SS_DOWNGRADE           0x8000
#define IGP01E1000_PLHR_GIG_SCRAMBLER_ERROR    0x4000
#define IGP01E1000_PLHR_MASTER_FAULT           0x2000
#define IGP01E1000_PLHR_MASTER_RESOLUTION      0x1000
#define IGP01E1000_PLHR_GIG_REM_RCVR_NOK       0x0800	/* LH */
#define IGP01E1000_PLHR_IDLE_ERROR_CNT_OFLOW   0x0400	/* LH */
#define IGP01E1000_PLHR_DATA_ERR_1             0x0200	/* LH */
#define IGP01E1000_PLHR_DATA_ERR_0             0x0100
#define IGP01E1000_PLHR_AUTONEG_FAULT          0x0040
#define IGP01E1000_PLHR_AUTONEG_ACTIVE         0x0010
#define IGP01E1000_PLHR_VALID_CHANNEL_D        0x0008
#define IGP01E1000_PLHR_VALID_CHANNEL_C        0x0004
#define IGP01E1000_PLHR_VALID_CHANNEL_B        0x0002
#define IGP01E1000_PLHR_VALID_CHANNEL_A        0x0001

/* IGP01E1000 Channel Quality Register */
#define IGP01E1000_MSE_CHANNEL_D        0x000F
#define IGP01E1000_MSE_CHANNEL_C        0x00F0
#define IGP01E1000_MSE_CHANNEL_B        0x0F00
#define IGP01E1000_MSE_CHANNEL_A        0xF000

#define IGP02E1000_PM_SPD                         0x0001	/* Smart Power Down */
#define IGP02E1000_PM_D3_LPLU                     0x0004	/* Enable LPLU in non-D0a modes */
#define IGP02E1000_PM_D0_LPLU                     0x0002	/* Enable LPLU in D0a mode */

/* IGP01E1000 DSP reset macros */
#define DSP_RESET_ENABLE     0x0
#define DSP_RESET_DISABLE    0x2
#define E1000_MAX_DSP_RESETS 10

/* IGP01E1000 & IGP02E1000 AGC Registers */

#define IGP01E1000_AGC_LENGTH_SHIFT 7	/* Coarse - 13:11, Fine - 10:7 */
#define IGP02E1000_AGC_LENGTH_SHIFT 9	/* Coarse - 15:13, Fine - 12:9 */

/* IGP02E1000 AGC Register Length 9-bit mask */
#define IGP02E1000_AGC_LENGTH_MASK  0x7F

/* 7 bits (3 Coarse + 4 Fine) --> 128 optional values */
#define IGP01E1000_AGC_LENGTH_TABLE_SIZE 128
#define IGP02E1000_AGC_LENGTH_TABLE_SIZE 113

/* The precision error of the cable length is +/- 10 meters */
#define IGP01E1000_AGC_RANGE    10
#define IGP02E1000_AGC_RANGE    15

/* IGP01E1000 PCS Initialization register */
/* bits 3:6 in the PCS registers stores the channels polarity */
#define IGP01E1000_PHY_POLARITY_MASK    0x0078

/* IGP01E1000 GMII FIFO Register */
#define IGP01E1000_GMII_FLEX_SPD               0x10	/* Enable flexible speed
							 * on Link-Up */
#define IGP01E1000_GMII_SPD                    0x20	/* Enable SPD */

/* IGP01E1000 Analog Register */
#define IGP01E1000_ANALOG_SPARE_FUSE_STATUS       0x20D1
#define IGP01E1000_ANALOG_FUSE_STATUS             0x20D0
#define IGP01E1000_ANALOG_FUSE_CONTROL            0x20DC
#define IGP01E1000_ANALOG_FUSE_BYPASS             0x20DE

#define IGP01E1000_ANALOG_FUSE_POLY_MASK            0xF000
#define IGP01E1000_ANALOG_FUSE_FINE_MASK            0x0F80
#define IGP01E1000_ANALOG_FUSE_COARSE_MASK          0x0070
#define IGP01E1000_ANALOG_SPARE_FUSE_ENABLED        0x0100
#define IGP01E1000_ANALOG_FUSE_ENABLE_SW_CONTROL    0x0002

#define IGP01E1000_ANALOG_FUSE_COARSE_THRESH        0x0040
#define IGP01E1000_ANALOG_FUSE_COARSE_10            0x0010
#define IGP01E1000_ANALOG_FUSE_FINE_1               0x0080
#define IGP01E1000_ANALOG_FUSE_FINE_10              0x0500

/* Bit definitions for valid PHY IDs. */
/* I = Integrated
 * E = External
 */
#define M88_VENDOR         0x0141
#define M88E1000_E_PHY_ID  0x01410C50
#define M88E1000_I_PHY_ID  0x01410C30
#define M88E1011_I_PHY_ID  0x01410C20
#define IGP01E1000_I_PHY_ID  0x02A80380
#define M88E1000_12_PHY_ID M88E1000_E_PHY_ID
#define M88E1000_14_PHY_ID M88E1000_E_PHY_ID
#define M88E1011_I_REV_4   0x04
#define M88E1111_I_PHY_ID  0x01410CC0
#define M88E1118_E_PHY_ID  0x01410E40
#define L1LXT971A_PHY_ID   0x001378E0

#define RTL8211B_PHY_ID    0x001CC910
#define RTL8201N_PHY_ID    0x8200
#define RTL_PHY_CTRL_FD    0x0100 /* Full duplex.0=half; 1=full */
#define RTL_PHY_CTRL_SPD_100    0x200000 /* Force 100Mb */

/* Bits...
 * 15-5: page
 * 4-0: register offset
 */
#define PHY_PAGE_SHIFT        5
#define PHY_REG(page, reg)    \
        (((page) << PHY_PAGE_SHIFT) | ((reg) & MAX_PHY_REG_ADDRESS))

#define IGP3_PHY_PORT_CTRL           \
        PHY_REG(769, 17)	/* Port General Configuration */
#define IGP3_PHY_RATE_ADAPT_CTRL \
        PHY_REG(769, 25)	/* Rate Adapter Control Register */

#define IGP3_KMRN_FIFO_CTRL_STATS \
        PHY_REG(770, 16)	/* KMRN FIFO's control/status register */
#define IGP3_KMRN_POWER_MNG_CTRL \
        PHY_REG(770, 17)	/* KMRN Power Management Control Register */
#define IGP3_KMRN_INBAND_CTRL \
        PHY_REG(770, 18)	/* KMRN Inband Control Register */
#define IGP3_KMRN_DIAG \
        PHY_REG(770, 19)	/* KMRN Diagnostic register */
#define IGP3_KMRN_DIAG_PCS_LOCK_LOSS 0x0002	/* RX PCS is not synced */
#define IGP3_KMRN_ACK_TIMEOUT \
        PHY_REG(770, 20)	/* KMRN Acknowledge Timeouts register */

#define IGP3_VR_CTRL \
        PHY_REG(776, 18)	/* Voltage regulator control register */
#define IGP3_VR_CTRL_MODE_SHUT       0x0200	/* Enter powerdown, shutdown VRs */
#define IGP3_VR_CTRL_MODE_MASK       0x0300	/* Shutdown VR Mask */

#define IGP3_CAPABILITY \
        PHY_REG(776, 19)	/* IGP3 Capability Register */

/* Capabilities for SKU Control  */
#define IGP3_CAP_INITIATE_TEAM       0x0001	/* Able to initiate a team */
#define IGP3_CAP_WFM                 0x0002	/* Support WoL and PXE */
#define IGP3_CAP_ASF                 0x0004	/* Support ASF */
#define IGP3_CAP_LPLU                0x0008	/* Support Low Power Link Up */
#define IGP3_CAP_DC_AUTO_SPEED       0x0010	/* Support AC/DC Auto Link Speed */
#define IGP3_CAP_SPD                 0x0020	/* Support Smart Power Down */
#define IGP3_CAP_MULT_QUEUE          0x0040	/* Support 2 tx & 2 rx queues */
#define IGP3_CAP_RSS                 0x0080	/* Support RSS */
#define IGP3_CAP_8021PQ              0x0100	/* Support 802.1Q & 802.1p */
#define IGP3_CAP_AMT_CB              0x0200	/* Support active manageability and circuit breaker */

#define IGP3_PPC_JORDAN_EN           0x0001
#define IGP3_PPC_JORDAN_GIGA_SPEED   0x0002

#define IGP3_KMRN_PMC_EE_IDLE_LINK_DIS         0x0001
#define IGP3_KMRN_PMC_K0S_ENTRY_LATENCY_MASK   0x001E
#define IGP3_KMRN_PMC_K0S_MODE1_EN_GIGA        0x0020
#define IGP3_KMRN_PMC_K0S_MODE1_EN_100         0x0040

#define IGP3E1000_PHY_MISC_CTRL                0x1B	/* Misc. Ctrl register */
#define IGP3_PHY_MISC_DUPLEX_MANUAL_SET        0x1000	/* Duplex Manual Set */

#define IGP3_KMRN_EXT_CTRL  PHY_REG(770, 18)
#define IGP3_KMRN_EC_DIS_INBAND    0x0080

#define IGP03E1000_E_PHY_ID  0x02A80390
#define IFE_E_PHY_ID         0x02A80330	/* 10/100 PHY */
#define IFE_PLUS_E_PHY_ID    0x02A80320
#define IFE_C_E_PHY_ID       0x02A80310

#define IFE_PHY_EXTENDED_STATUS_CONTROL   0x10	/* 100BaseTx Extended Status, Control and Address */
#define IFE_PHY_SPECIAL_CONTROL           0x11	/* 100BaseTx PHY special control register */
#define IFE_PHY_RCV_FALSE_CARRIER         0x13	/* 100BaseTx Receive False Carrier Counter */
#define IFE_PHY_RCV_DISCONNECT            0x14	/* 100BaseTx Receive Disconnect Counter */
#define IFE_PHY_RCV_ERROT_FRAME           0x15	/* 100BaseTx Receive Error Frame Counter */
#define IFE_PHY_RCV_SYMBOL_ERR            0x16	/* Receive Symbol Error Counter */
#define IFE_PHY_PREM_EOF_ERR              0x17	/* 100BaseTx Receive Premature End Of Frame Error Counter */
#define IFE_PHY_RCV_EOF_ERR               0x18	/* 10BaseT Receive End Of Frame Error Counter */
#define IFE_PHY_TX_JABBER_DETECT          0x19	/* 10BaseT Transmit Jabber Detect Counter */
#define IFE_PHY_EQUALIZER                 0x1A	/* PHY Equalizer Control and Status */
#define IFE_PHY_SPECIAL_CONTROL_LED       0x1B	/* PHY special control and LED configuration */
#define IFE_PHY_MDIX_CONTROL              0x1C	/* MDI/MDI-X Control register */
#define IFE_PHY_HWI_CONTROL               0x1D	/* Hardware Integrity Control (HWI) */

#define IFE_PESC_REDUCED_POWER_DOWN_DISABLE  0x2000	/* Default 1 = Disable auto reduced power down */
#define IFE_PESC_100BTX_POWER_DOWN           0x0400	/* Indicates the power state of 100BASE-TX */
#define IFE_PESC_10BTX_POWER_DOWN            0x0200	/* Indicates the power state of 10BASE-T */
#define IFE_PESC_POLARITY_REVERSED           0x0100	/* Indicates 10BASE-T polarity */
#define IFE_PESC_PHY_ADDR_MASK               0x007C	/* Bit 6:2 for sampled PHY address */
#define IFE_PESC_SPEED                       0x0002	/* Auto-negotiation speed result 1=100Mbs, 0=10Mbs */
#define IFE_PESC_DUPLEX                      0x0001	/* Auto-negotiation duplex result 1=Full, 0=Half */
#define IFE_PESC_POLARITY_REVERSED_SHIFT     8

#define IFE_PSC_DISABLE_DYNAMIC_POWER_DOWN   0x0100	/* 1 = Dynamic Power Down disabled */
#define IFE_PSC_FORCE_POLARITY               0x0020	/* 1=Reversed Polarity, 0=Normal */
#define IFE_PSC_AUTO_POLARITY_DISABLE        0x0010	/* 1=Auto Polarity Disabled, 0=Enabled */
#define IFE_PSC_JABBER_FUNC_DISABLE          0x0001	/* 1=Jabber Disabled, 0=Normal Jabber Operation */
#define IFE_PSC_FORCE_POLARITY_SHIFT         5
#define IFE_PSC_AUTO_POLARITY_DISABLE_SHIFT  4

#define IFE_PMC_AUTO_MDIX                    0x0080	/* 1=enable MDI/MDI-X feature, default 0=disabled */
#define IFE_PMC_FORCE_MDIX                   0x0040	/* 1=force MDIX-X, 0=force MDI */
#define IFE_PMC_MDIX_STATUS                  0x0020	/* 1=MDI-X, 0=MDI */
#define IFE_PMC_AUTO_MDIX_COMPLETE           0x0010	/* Resolution algorithm is completed */
#define IFE_PMC_MDIX_MODE_SHIFT              6
#define IFE_PHC_MDIX_RESET_ALL_MASK          0x0000	/* Disable auto MDI-X */

#define IFE_PHC_HWI_ENABLE                   0x8000	/* Enable the HWI feature */
#define IFE_PHC_ABILITY_CHECK                0x4000	/* 1= Test Passed, 0=failed */
#define IFE_PHC_TEST_EXEC                    0x2000	/* PHY launch test pulses on the wire */
#define IFE_PHC_HIGHZ                        0x0200	/* 1 = Open Circuit */
#define IFE_PHC_LOWZ                         0x0400	/* 1 = Short Circuit */
#define IFE_PHC_LOW_HIGH_Z_MASK              0x0600	/* Mask for indication type of problem on the line */
#define IFE_PHC_DISTANCE_MASK                0x01FF	/* Mask for distance to the cable problem, in 80cm granularity */
#define IFE_PHC_RESET_ALL_MASK               0x0000	/* Disable HWI */
#define IFE_PSCL_PROBE_MODE                  0x0020	/* LED Probe mode */
#define IFE_PSCL_PROBE_LEDS_OFF              0x0006	/* Force LEDs 0 and 2 off */
#define IFE_PSCL_PROBE_LEDS_ON               0x0007	/* Force LEDs 0 and 2 on */

#define ICH_FLASH_COMMAND_TIMEOUT            5000	/* 5000 uSecs - adjusted */
#define ICH_FLASH_ERASE_TIMEOUT              3000000	/* Up to 3 seconds - worst case */
#define ICH_FLASH_CYCLE_REPEAT_COUNT         10	/* 10 cycles */
#define ICH_FLASH_SEG_SIZE_256               256
#define ICH_FLASH_SEG_SIZE_4K                4096
#define ICH_FLASH_SEG_SIZE_64K               65536

#define ICH_CYCLE_READ                       0x0
#define ICH_CYCLE_RESERVED                   0x1
#define ICH_CYCLE_WRITE                      0x2
#define ICH_CYCLE_ERASE                      0x3

#define ICH_FLASH_GFPREG   0x0000
#define ICH_FLASH_HSFSTS   0x0004
#define ICH_FLASH_HSFCTL   0x0006
#define ICH_FLASH_FADDR    0x0008
#define ICH_FLASH_FDATA0   0x0010
#define ICH_FLASH_FRACC    0x0050
#define ICH_FLASH_FREG0    0x0054
#define ICH_FLASH_FREG1    0x0058
#define ICH_FLASH_FREG2    0x005C
#define ICH_FLASH_FREG3    0x0060
#define ICH_FLASH_FPR0     0x0074
#define ICH_FLASH_FPR1     0x0078
#define ICH_FLASH_SSFSTS   0x0090
#define ICH_FLASH_SSFCTL   0x0092
#define ICH_FLASH_PREOP    0x0094
#define ICH_FLASH_OPTYPE   0x0096
#define ICH_FLASH_OPMENU   0x0098

#define ICH_FLASH_REG_MAPSIZE      0x00A0
#define ICH_FLASH_SECTOR_SIZE      4096
#define ICH_GFPREG_BASE_MASK       0x1FFF
#define ICH_FLASH_LINEAR_ADDR_MASK 0x00FFFFFF

/* Miscellaneous PHY bit definitions. */
#define PHY_PREAMBLE        0xFFFFFFFF
#define PHY_SOF             0x01
#define PHY_OP_READ         0x02
#define PHY_OP_WRITE        0x01
#define PHY_TURNAROUND      0x02
#define PHY_PREAMBLE_SIZE   32
#define MII_CR_SPEED_1000   0x0040
#define MII_CR_SPEED_100    0x2000
#define MII_CR_SPEED_10     0x0000
#define E1000_PHY_ADDRESS   0x01
#define PHY_AUTO_NEG_TIME   45	/* 4.5 Seconds */
#define PHY_FORCE_TIME      20	/* 2.0 Seconds */
#define PHY_REVISION_MASK   0xFFFFFFF0
#define DEVICE_SPEED_MASK   0x00000300	/* Device Ctrl Reg Speed Mask */
#define REG4_SPEED_MASK     0x01E0
#define REG9_SPEED_MASK     0x0300
#define ADVERTISE_10_HALF   0x0001
#define ADVERTISE_10_FULL   0x0002
#define ADVERTISE_100_HALF  0x0004
#define ADVERTISE_100_FULL  0x0008
#define ADVERTISE_1000_HALF 0x0010
#define ADVERTISE_1000_FULL 0x0020
#define AUTONEG_ADVERTISE_SPEED_DEFAULT 0x002F	/* Everything but 1000-Half */
#define AUTONEG_ADVERTISE_10_100_ALL    0x000F	/* All 10/100 speeds */
#define AUTONEG_ADVERTISE_10_ALL        0x0003	/* 10Mbps Full & Half speeds */

#endif /* _E1000_HW_H_ */


<|start_filename|>3rdpart/ethercat-1.5.2/tool/MasterDevice.cpp<|end_filename|>
/*****************************************************************************
 *
 *  $Id: MasterDevice.cpp,v bc2d4bf9cbe5 2012/09/06 18:22:24 fp $
 *
 *  Copyright (C) 2006-2009  <NAME>, Ingenieurgemeinschaft IgH
 *
 *  This file is part of the IgH EtherCAT Master.
 *
 *  The IgH EtherCAT Master is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License version 2, as
 *  published by the Free Software Foundation.
 *
 *  The IgH EtherCAT Master is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 *  Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with the IgH EtherCAT Master; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 ****************************************************************************/

#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <string.h>
#include <unistd.h>

#include <sstream>
#include <iomanip>
using namespace std;

#include "MasterDevice.h"

/****************************************************************************/

MasterDevice::MasterDevice(unsigned int index):
    index(index),
    masterCount(0U),
    fd(-1)
{
}

/****************************************************************************/

MasterDevice::~MasterDevice()
{
    close();
}

/****************************************************************************/

void MasterDevice::setIndex(unsigned int i)
{
    index = i;
}

/****************************************************************************/

void MasterDevice::open(Permissions perm)
{
    stringstream deviceName;

    if (fd == -1) { // not already open
        ec_ioctl_module_t module_data;
        deviceName << "/dev/EtherCAT" << index;

        if ((fd = ::open(deviceName.str().c_str(),
                        perm == ReadWrite ? O_RDWR : O_RDONLY)) == -1) {
            stringstream err;
            err << "Failed to open master device " << deviceName.str() << ": "
                << strerror(errno);
            throw MasterDeviceException(err);
        }

        getModule(&module_data);
        if (module_data.ioctl_version_magic != EC_IOCTL_VERSION_MAGIC) {
            stringstream err;
            err << "ioctl() version magic is differing: "
                << deviceName.str() << ": " << module_data.ioctl_version_magic
                << ", ethercat tool: " << EC_IOCTL_VERSION_MAGIC;
            throw MasterDeviceException(err);
        }
        masterCount = module_data.master_count;
    }
}

/****************************************************************************/

void MasterDevice::close()
{
    if (fd != -1) {
        ::close(fd);
        fd = -1;
    }
}

/****************************************************************************/

void MasterDevice::getModule(ec_ioctl_module_t *data)
{
    if (ioctl(fd, EC_IOCTL_MODULE, data) < 0) {
        stringstream err;
        err << "Failed to get module information: " << strerror(errno);
        throw MasterDeviceException(err);
    }
}

/****************************************************************************/

void MasterDevice::getMaster(ec_ioctl_master_t *data)
{
    if (ioctl(fd, EC_IOCTL_MASTER, data) < 0) {
        stringstream err;
        err << "Failed to get master information: " << strerror(errno);
        throw MasterDeviceException(err);
    }
}

/****************************************************************************/

void MasterDevice::getConfig(ec_ioctl_config_t *data, unsigned int index)
{
    data->config_index = index;

    if (ioctl(fd, EC_IOCTL_CONFIG, data) < 0) {
        stringstream err;
        err << "Failed to get slave configuration: " << strerror(errno);
        throw MasterDeviceException(err);
    }
}

/****************************************************************************/

void MasterDevice::getConfigPdo(
        ec_ioctl_config_pdo_t *data,
        unsigned int index,
        uint8_t sync_index,
        uint16_t pdo_pos
        )
{
    data->config_index = index;
    data->sync_index = sync_index;
    data->pdo_pos = pdo_pos;

    if (ioctl(fd, EC_IOCTL_CONFIG_PDO, data) < 0) {
        stringstream err;
        err << "Failed to get slave config PDO: " << strerror(errno);
        throw MasterDeviceException(err);
    }
}

/****************************************************************************/

void MasterDevice::getConfigPdoEntry(
        ec_ioctl_config_pdo_entry_t *data,
        unsigned int index,
        uint8_t sync_index,
        uint16_t pdo_pos,
        uint8_t entry_pos
        )
{
    data->config_index = index;
    data->sync_index = sync_index;
    data->pdo_pos = pdo_pos;
    data->entry_pos = entry_pos;

    if (ioctl(fd, EC_IOCTL_CONFIG_PDO_ENTRY, data) < 0) {
        stringstream err;
        err << "Failed to get slave config PDO entry: " << strerror(errno);
        throw MasterDeviceException(err);
    }
}

/****************************************************************************/

void MasterDevice::getConfigSdo(
        ec_ioctl_config_sdo_t *data,
        unsigned int index,
        unsigned int sdo_pos
        )
{
    data->config_index = index;
    data->sdo_pos = sdo_pos;

    if (ioctl(fd, EC_IOCTL_CONFIG_SDO, data) < 0) {
        stringstream err;
        err << "Failed to get slave config SDO: " << strerror(errno);
        throw MasterDeviceException(err);
    }
}

/****************************************************************************/

void MasterDevice::getConfigIdn(
        ec_ioctl_config_idn_t *data,
        unsigned int index,
        unsigned int pos
        )
{
    data->config_index = index;
    data->idn_pos = pos;

    if (ioctl(fd, EC_IOCTL_CONFIG_IDN, data) < 0) {
        stringstream err;
        err << "Failed to get slave config IDN: " << strerror(errno);
        throw MasterDeviceException(err);
    }
}

/****************************************************************************/

void MasterDevice::getDomain(ec_ioctl_domain_t *data, unsigned int index)
{
    data->index = index;

    if (ioctl(fd, EC_IOCTL_DOMAIN, data)) {
        stringstream err;
        err << "Failed to get domain: ";
        if (errno == EINVAL)
            err << "Domain " << index << " does not exist!";
        else
            err << strerror(errno);
        throw MasterDeviceException(err);
    }
}

/****************************************************************************/

void MasterDevice::getData(ec_ioctl_domain_data_t *data,
        unsigned int domainIndex, unsigned int dataSize, unsigned char *mem)
{
    data->domain_index = domainIndex;
    data->data_size = dataSize;
    data->target = mem;

    if (ioctl(fd, EC_IOCTL_DOMAIN_DATA, data) < 0) {
        stringstream err;
        err << "Failed to get domain data: " << strerror(errno);
        throw MasterDeviceException(err);
    }
}

/****************************************************************************/

void MasterDevice::getSlave(ec_ioctl_slave_t *slave, uint16_t slaveIndex)
{
    slave->position = slaveIndex;

    if (ioctl(fd, EC_IOCTL_SLAVE, slave)) {
        stringstream err;
        err << "Failed to get slave: ";
        if (errno == EINVAL)
            err << "Slave " << slaveIndex << " does not exist!";
        else
            err << strerror(errno);
        throw MasterDeviceException(err);
    }
}

/****************************************************************************/

void MasterDevice::getFmmu(
        ec_ioctl_domain_fmmu_t *fmmu,
        unsigned int domainIndex,
        unsigned int fmmuIndex
        )
{
    fmmu->domain_index = domainIndex;
    fmmu->fmmu_index = fmmuIndex;

    if (ioctl(fd, EC_IOCTL_DOMAIN_FMMU, fmmu)) {
        stringstream err;
        err << "Failed to get domain FMMU: " << strerror(errno);
        throw MasterDeviceException(err);
    }
}

/****************************************************************************/

void MasterDevice::getSync(
        ec_ioctl_slave_sync_t *sync,
        uint16_t slaveIndex,
        uint8_t syncIndex
        )
{
    sync->slave_position = slaveIndex;
    sync->sync_index = syncIndex;

    if (ioctl(fd, EC_IOCTL_SLAVE_SYNC, sync)) {
        stringstream err;
        err << "Failed to get sync manager: " << strerror(errno);
        throw MasterDeviceException(err);
    }
}

/****************************************************************************/

void MasterDevice::getPdo(
        ec_ioctl_slave_sync_pdo_t *pdo,
        uint16_t slaveIndex,
        uint8_t syncIndex,
        uint8_t pdoPos
        )
{
    pdo->slave_position = slaveIndex;
    pdo->sync_index = syncIndex;
    pdo->pdo_pos = pdoPos;

    if (ioctl(fd, EC_IOCTL_SLAVE_SYNC_PDO, pdo)) {
        stringstream err;
        err << "Failed to get PDO: " << strerror(errno);
        throw MasterDeviceException(err);
    }
}

/****************************************************************************/

void MasterDevice::getPdoEntry(
        ec_ioctl_slave_sync_pdo_entry_t *entry,
        uint16_t slaveIndex,
        uint8_t syncIndex,
        uint8_t pdoPos,
        uint8_t entryPos
        )
{
    entry->slave_position = slaveIndex;
    entry->sync_index = syncIndex;
    entry->pdo_pos = pdoPos;
    entry->entry_pos = entryPos;

    if (ioctl(fd, EC_IOCTL_SLAVE_SYNC_PDO_ENTRY, entry)) {
        stringstream err;
        err << "Failed to get PDO entry: " << strerror(errno);
        throw MasterDeviceException(err);
    }
}

/****************************************************************************/

void MasterDevice::getSdo(
        ec_ioctl_slave_sdo_t *sdo,
        uint16_t slaveIndex,
        uint16_t sdoPosition
        )
{
    sdo->slave_position = slaveIndex;
    sdo->sdo_position = sdoPosition;

    if (ioctl(fd, EC_IOCTL_SLAVE_SDO, sdo)) {
        stringstream err;
        err << "Failed to get SDO: " << strerror(errno);
        throw MasterDeviceException(err);
    }
}

/****************************************************************************/

void MasterDevice::getSdoEntry(
        ec_ioctl_slave_sdo_entry_t *entry,
        uint16_t slaveIndex,
        int sdoSpec,
        uint8_t entrySubindex
        )
{
    entry->slave_position = slaveIndex;
    entry->sdo_spec = sdoSpec;
    entry->sdo_entry_subindex = entrySubindex;

    if (ioctl(fd, EC_IOCTL_SLAVE_SDO_ENTRY, entry)) {
        stringstream err;
        err << "Failed to get SDO entry: " << strerror(errno);
        throw MasterDeviceException(err);
    }
}

/****************************************************************************/

void MasterDevice::readSii(
        ec_ioctl_slave_sii_t *data
        )
{
    if (ioctl(fd, EC_IOCTL_SLAVE_SII_READ, data) < 0) {
        stringstream err;
        err << "Failed to read SII: " << strerror(errno);
        throw MasterDeviceException(err);
    }
}

/****************************************************************************/

void MasterDevice::writeSii(
        ec_ioctl_slave_sii_t *data
        )
{
    if (ioctl(fd, EC_IOCTL_SLAVE_SII_WRITE, data) < 0) {
        stringstream err;
        err << "Failed to write SII: " << strerror(errno);
        throw MasterDeviceException(err);
    }
}

/****************************************************************************/

void MasterDevice::readReg(
        ec_ioctl_slave_reg_t *data
        )
{
    if (ioctl(fd, EC_IOCTL_SLAVE_REG_READ, data) < 0) {
        stringstream err;
        err << "Failed to read register: " << strerror(errno);
        throw MasterDeviceException(err);
    }
}

/****************************************************************************/

void MasterDevice::writeReg(
        ec_ioctl_slave_reg_t *data
        )
{
    if (ioctl(fd, EC_IOCTL_SLAVE_REG_WRITE, data) < 0) {
        stringstream err;
        err << "Failed to write register: " << strerror(errno);
        throw MasterDeviceException(err);
    }
}

/****************************************************************************/

void MasterDevice::readFoe(
        ec_ioctl_slave_foe_t *data
        )
{
    if (ioctl(fd, EC_IOCTL_SLAVE_FOE_READ, data) < 0) {
        stringstream err;
        err << "Failed to read via FoE: " << strerror(errno);
        throw MasterDeviceException(err);
    }
}

/****************************************************************************/

void MasterDevice::writeFoe(
        ec_ioctl_slave_foe_t *data
        )
{
    if (ioctl(fd, EC_IOCTL_SLAVE_FOE_WRITE, data) < 0) {
        stringstream err;
        err << "Failed to write via FoE: " << strerror(errno);
        throw MasterDeviceException(err);
    }
}

/****************************************************************************/

void MasterDevice::setDebug(unsigned int debugLevel)
{
    if (ioctl(fd, EC_IOCTL_MASTER_DEBUG, debugLevel) < 0) {
        stringstream err;
        err << "Failed to set debug level: " << strerror(errno);
        throw MasterDeviceException(err);
    }
}

/****************************************************************************/

void MasterDevice::rescan()
{
    if (ioctl(fd, EC_IOCTL_MASTER_RESCAN, 0) < 0) {
        stringstream err;
        err << "Failed to command rescan: " << strerror(errno);
        throw MasterDeviceException(err);
    }
}

/****************************************************************************/

void MasterDevice::sdoDownload(ec_ioctl_slave_sdo_download_t *data)
{
    if (ioctl(fd, EC_IOCTL_SLAVE_SDO_DOWNLOAD, data) < 0) {
        stringstream err;
        if (errno == EIO && data->abort_code) {
            throw MasterDeviceSdoAbortException(data->abort_code);
        } else {
            err << "Failed to download SDO: " << strerror(errno);
            throw MasterDeviceException(err);
        }
    }
}

/****************************************************************************/

void MasterDevice::sdoUpload(ec_ioctl_slave_sdo_upload_t *data)
{
    if (ioctl(fd, EC_IOCTL_SLAVE_SDO_UPLOAD, data) < 0) {
        stringstream err;
        if (errno == EIO && data->abort_code) {
            throw MasterDeviceSdoAbortException(data->abort_code);
        } else {
            err << "Failed to upload SDO: " << strerror(errno);
            throw MasterDeviceException(err);
        }
    }
}

/****************************************************************************/

void MasterDevice::requestState(
        uint16_t slavePosition,
        uint8_t state
        )
{
    ec_ioctl_slave_state_t data;

    data.slave_position = slavePosition;
    data.al_state = state;

    if (ioctl(fd, EC_IOCTL_SLAVE_STATE, &data)) {
        stringstream err;
        err << "Failed to request slave state: ";
        if (errno == EINVAL)
            err << "Slave " << slavePosition << " does not exist!";
        else
            err << strerror(errno);
        throw MasterDeviceException(err);
    }
}

/****************************************************************************/

#ifdef EC_EOE

void MasterDevice::getEoeHandler(
        ec_ioctl_eoe_handler_t *eoe,
        uint16_t eoeHandlerIndex
        )
{
    eoe->eoe_index = eoeHandlerIndex;

    if (ioctl(fd, EC_IOCTL_EOE_HANDLER, eoe)) {
        stringstream err;
        err << "Failed to get EoE handler: " << strerror(errno);
        throw MasterDeviceException(err);
    }
}

#endif

/****************************************************************************/

void MasterDevice::readSoe(ec_ioctl_slave_soe_read_t *data)
{
    if (ioctl(fd, EC_IOCTL_SLAVE_SOE_READ, data) < 0) {
        if (errno == EIO && data->error_code) {
            throw MasterDeviceSoeException(data->error_code);
        } else {
            stringstream err;
            err << "Failed to read IDN: " << strerror(errno);
            throw MasterDeviceException(err);
        }
    }
}

/****************************************************************************/

void MasterDevice::writeSoe(ec_ioctl_slave_soe_write_t *data)
{
    if (ioctl(fd, EC_IOCTL_SLAVE_SOE_WRITE, data) < 0) {
        if (errno == EIO && data->error_code) {
            throw MasterDeviceSoeException(data->error_code);
        } else {
            stringstream err;
            err << "Failed to write IDN: " << strerror(errno);
            throw MasterDeviceException(err);
        }
    }
}

/*****************************************************************************/


<|start_filename|>3rdpart/tslib-1.15/tests/testutils.h<|end_filename|>
#ifndef _TESTUTILS_H
#define _TESTUTILS_H
/*
 *  tslib/tests/testutils.h
 *
 *  Copyright (C) 2004 <NAME> <<EMAIL>>
 *
 * This file is placed under the GPL.
 *
 * SPDX-License-Identifier: GPL-2.0+
 *
 *
 * Misc utils for ts test programs
 */

#define RESET   "\033[0m"
#define RED     "\033[31m"
#define GREEN   "\033[32m"
#define BLUE    "\033[34m"
#define YELLOW  "\033[33m"

struct ts_button {
	int x, y, w, h;
	char *text;
	int flags;
#define BUTTON_ACTIVE 0x00000001
};

void button_draw(struct ts_button *button);
int button_handle(struct ts_button *button, int x, int y, unsigned int pressure);
void getxy(struct tsdev *ts, int *x, int *y);
void ts_flush(struct tsdev *ts);
void print_ascii_logo(void);

#endif /* _TESTUTILS_H */


<|start_filename|>3rdpart/ethercat-1.5.2/tool/CommandSdos.cpp<|end_filename|>
/*****************************************************************************
 *
 *  $Id: CommandSdos.cpp,v bc2d4bf9cbe5 2012/09/06 18:22:24 fp $
 *
 *  Copyright (C) 2006-2009  <NAME>, Ingenieurgemeinschaft IgH
 *
 *  This file is part of the IgH EtherCAT Master.
 *
 *  The IgH EtherCAT Master is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License version 2, as
 *  published by the Free Software Foundation.
 *
 *  The IgH EtherCAT Master is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 *  Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with the IgH EtherCAT Master; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 ****************************************************************************/

#include <iostream>
#include <iomanip>
using namespace std;

#include "CommandSdos.h"
#include "MasterDevice.h"

/*****************************************************************************/

CommandSdos::CommandSdos():
    SdoCommand("sdos", "List SDO dictionaries.")
{
}

/*****************************************************************************/

string CommandSdos::helpString(const string &binaryBaseName) const
{
    stringstream str;

    str << binaryBaseName << " " << getName() << " [OPTIONS]" << endl
        << endl
        << getBriefDescription() << endl
        << endl
        << "SDO dictionary information is displayed in two layers," << endl
        << "which are indented accordingly:" << endl
        << endl
        << "1) SDOs - Hexadecimal SDO index and the name. Example:" << endl
        << endl
        << "   SDO 0x1018, \"Identity object\"" << endl
        << endl
        << "2) SDO entries - SDO index and SDO entry subindex (both" << endl
        << "   hexadecimal) followed by the access rights (see" << endl
        << "   below), the data type, the length in bit, and the" << endl
        << "   description. Example:" << endl
        << endl
        << "   0x1018:01, rwrwrw, uint32, 32 bit, \"Vendor id\"" << endl
        << endl
        << "The access rights are specified for the AL states PREOP," << endl
        << "SAFEOP and OP. An 'r' means, that the entry is readable" << endl
        << "in the corresponding state, an 'w' means writable," << endl
        << "respectively. If a right is not granted, a dash '-' is" << endl
        << "shown." << endl
        << endl
        << "If the --quiet option is given, only the SDOs are output."
        << endl << endl
        << "Command-specific options:" << endl
        << "  --alias    -a <alias>" << endl
        << "  --position -p <pos>    Slave selection. See the help of" << endl
        << "                         the 'slaves' command." << endl
        << "  --quiet    -q          Only output SDOs (without the" << endl
        << "                         SDO entries)." << endl
        << endl
        << numericInfo();

    return str.str();
}

/****************************************************************************/

void CommandSdos::execute(const StringVector &args)
{
	MasterIndexList masterIndices;
    SlaveList slaves;
    SlaveList::const_iterator si;
    bool showHeader, multiMaster;

    if (args.size()) {
        stringstream err;
        err << "'" << getName() << "' takes no arguments!";
        throwInvalidUsageException(err);
    }

	masterIndices = getMasterIndices();
    multiMaster = masterIndices.size() > 1;
    MasterIndexList::const_iterator mi;
    for (mi = masterIndices.begin();
            mi != masterIndices.end(); mi++) {
        MasterDevice m(*mi);
        m.open(MasterDevice::Read);
        slaves = selectedSlaves(m);
        showHeader = multiMaster || slaves.size() > 1;

        for (si = slaves.begin(); si != slaves.end(); si++) {
            listSlaveSdos(m, *si, showHeader);
        }
    }
}

/****************************************************************************/

void CommandSdos::listSlaveSdos(
        MasterDevice &m,
        const ec_ioctl_slave_t &slave,
        bool showHeader
        )
{
    ec_ioctl_slave_sdo_t sdo;
    ec_ioctl_slave_sdo_entry_t entry;
    unsigned int i, j;
    const DataType *d;

    if (showHeader && slave.sdo_count)
        cout << "=== Master " << m.getIndex()
            << ", Slave " << slave.position << " ===" << endl;

    for (i = 0; i < slave.sdo_count; i++) {
        m.getSdo(&sdo, slave.position, i);

        cout << "SDO 0x"
            << hex << setfill('0')
            << setw(4) << sdo.sdo_index
            << ", \"" << sdo.name << "\"" << endl;

        if (getVerbosity() == Quiet)
            continue;

        for (j = 0; j <= sdo.max_subindex; j++) {
            m.getSdoEntry(&entry, slave.position, -i, j);

            cout << "  0x" << hex << setfill('0')
                << setw(4) << sdo.sdo_index << ":"
                << setw(2) << (unsigned int) entry.sdo_entry_subindex
                << ", "
                << (entry.read_access[EC_SDO_ENTRY_ACCESS_PREOP] ? "r" : "-")
                << (entry.write_access[EC_SDO_ENTRY_ACCESS_PREOP] ? "w" : "-")
                << (entry.read_access[EC_SDO_ENTRY_ACCESS_SAFEOP] ? "r" : "-")
                << (entry.write_access[EC_SDO_ENTRY_ACCESS_SAFEOP] ? "w" : "-")
                << (entry.read_access[EC_SDO_ENTRY_ACCESS_OP] ? "r" : "-")
                << (entry.write_access[EC_SDO_ENTRY_ACCESS_OP] ? "w" : "-")
                << ", ";

            if ((d = findDataType(entry.data_type))) {
                cout << d->name;
            } else {
                cout << "type " << setw(4) << entry.data_type;
            }

            cout << ", " << dec << entry.bit_length << " bit, \""
                << entry.description << "\"" << endl;
        }
    }
}

/*****************************************************************************/


<|start_filename|>3rdpart/tslib-1.15/plugins/invert.c<|end_filename|>
/*
 * tslib/plugins/invert.c
 *
 * Copyright 2017 <NAME> <<EMAIL>>
 *
 * SPDX-License-Identifier: LGPL-2.1
 *
 *
 * Simply inverts values in X and/or Y direction around given point
 */
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <stdint.h>

#include "config.h"
#include "tslib.h"
#include "tslib-filter.h"

struct tslib_invert {
	struct		tslib_module_info module;
	int32_t		x0;
	int32_t		y0;
	uint8_t		invert_x;
	uint8_t		invert_y;
};

static int invert_read(struct tslib_module_info *info, struct ts_sample *samp, int nr)
{
	struct tslib_invert *ctx = (struct tslib_invert *)info;
	int count = 0;

	while (count < nr) {
		if (info->next->ops->read(info->next, samp, 1) < 1)
			return count;

		if (ctx->invert_x)
			samp->x = ctx->x0 - samp->x;

		if (ctx->invert_y)
			samp->y = ctx->y0 - samp->y;
	}
	return count;
}

static int invert_read_mt(struct tslib_module_info *info,
			  struct ts_sample_mt **samp,
			  int max_slots, int nr)
{
	struct tslib_invert *ctx = (struct tslib_invert *)info;
	int ret;
	int i, j;

	if (!info->next->ops->read_mt)
		return -ENOSYS;

	ret = info->next->ops->read_mt(info->next, samp, max_slots, nr);
	if (ret < 0)
		return ret;

#ifdef DEBUG
	if (ret == 0)
		fprintf(stderr, "INVERT: couldn't read data\n");

	printf("INVERT: read %d samples (mem: %d nr x %d slots)\n",
		ret, nr, max_slots);
#endif

	for (i = 0; i < ret; i++) {
		for (j = 0; j < max_slots; j++) {
			if (!(samp[i][j].valid & TSLIB_MT_VALID))
				continue;

			if (ctx->invert_x)
				samp[i][j].x = ctx->x0 - samp[i][j].x;

			if (ctx->invert_y)
				samp[i][j].y = ctx->y0 - samp[i][j].y;

		#ifdef DEBUG
			printf("INVERT: new val slot %d:  X %d  Y %d\n",
				j, samp[i][j].x, samp[i][j].y);
		#endif
		}
	}

	return ret;
}

static int invert_fini(struct tslib_module_info *info)
{
	free(info);

	return 0;
}

static const struct tslib_ops invert_ops = {
	.read		= invert_read,
	.read_mt	= invert_read_mt,
	.fini		= invert_fini,
};

static int invert_opt(struct tslib_module_info *inf, char *str, void *data)
{
	struct tslib_invert *ctx = (struct tslib_invert *)inf;
	long v;
	int32_t err = errno;

	v = strtol(str, NULL, 0);

	if (v == LONG_MAX && errno == ERANGE)
		return -1;

	errno = err;
	switch ((int)(intptr_t)data) {
	case 1:
		ctx->invert_x = 1;
		ctx->x0 = v;
		break;

	case 2:
		ctx->invert_y = 1;
		ctx->y0 = v;
		break;

	default:
		return -1;
	}

	return 0;
}

static const struct tslib_vars invert_vars[] = {
	{ "x0",	(void *)1, invert_opt },
	{ "y0", (void *)2, invert_opt },
};

#define NR_VARS (sizeof(invert_vars) / sizeof(invert_vars[0]))

TSAPI struct tslib_module_info *invert_mod_init(__attribute__ ((unused)) struct tsdev *dev,
						const char *params)
{
	struct tslib_invert *ctx;

	ctx = malloc(sizeof(struct tslib_invert));
	if (ctx == NULL)
		return NULL;

	memset(ctx, 0, sizeof(*ctx));
	ctx->module.ops = &invert_ops;

	ctx->invert_x = 0;
	ctx->invert_y = 0;

	if (tslib_parse_vars(&ctx->module, invert_vars, NR_VARS, params)) {
		free(ctx);
		return NULL;
	}

	return &ctx->module;
}

#ifndef TSLIB_STATIC_INVERT_MODULE
	TSLIB_MODULE_INIT(invert_mod_init);
#endif


<|start_filename|>kernel/modules/devmodel/vdev.c<|end_filename|>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>

#include <linux/device.h>

extern struct bus_type vbus;

static void vdev_release(struct device *dev)
{
}

/* 定义vdev对象，代表设备 */
static struct device vdev = {
	.init_name = "vdev",
	.bus = &vbus, //指定设备所属的总线，这样注册的时候就会挂在vbus总线下
	.release = vdev_release,
};

static int __init vdev_init(void)
{
	/* 注册设备 */
	return device_register(&vdev);
}

static void __exit vdev_exit(void)
{
	/* 注销设备 */
	device_unregister(&vdev);
}

module_init(vdev_init);
module_exit(vdev_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("suda-morris <<EMAIL>>");
MODULE_DESCRIPTION("A virtual device");


<|start_filename|>3rdpart/ethercat-1.5.2/tool/CommandXml.cpp<|end_filename|>
/*****************************************************************************
 *
 *  $Id: CommandXml.cpp,v bc2d4bf9cbe5 2012/09/06 18:22:24 fp $
 *
 *  Copyright (C) 2006-2009  <NAME>, Ingenieurgemeinschaft IgH
 *
 *  This file is part of the IgH EtherCAT Master.
 *
 *  The IgH EtherCAT Master is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License version 2, as
 *  published by the Free Software Foundation.
 *
 *  The IgH EtherCAT Master is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 *  Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with the IgH EtherCAT Master; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 ****************************************************************************/

#include <iostream>
#include <iomanip>
#include <string.h>
using namespace std;

#include "CommandXml.h"
#include "MasterDevice.h"

/*****************************************************************************/

CommandXml::CommandXml():
    Command("xml", "Generate slave information XML.")
{
}

/*****************************************************************************/

string CommandXml::helpString(const string &binaryBaseName) const
{
    stringstream str;

    str << binaryBaseName << " " << getName() << " [OPTIONS]" << endl
        << endl
        << getBriefDescription() << endl
        << endl
        << "Note that the PDO information can either originate" << endl
        << "from the SII or from the CoE communication area. For" << endl
        << "slaves, that support configuring PDO assignment and" << endl
        << "mapping, the output depends on the last configuration." << endl
        << endl
        << "Command-specific options:" << endl
        << "  --alias    -a <alias>" << endl
        << "  --position -p <pos>    Slave selection. See the help of" << endl
        << "                         the 'slaves' command." << endl
        << endl
        << numericInfo();

    return str.str();
}

/****************************************************************************/

void CommandXml::execute(const StringVector &args)
{
    SlaveList slaves;
    SlaveList::const_iterator si;

    if (args.size()) {
        stringstream err;
        err << "'" << getName() << "' takes no arguments!";
        throwInvalidUsageException(err);
    }

    MasterDevice m(getSingleMasterIndex());
    m.open(MasterDevice::Read);
    slaves = selectedSlaves(m);

    cout << "<?xml version=\"1.0\" ?>" << endl;
    if (slaves.size() > 1) {
        cout << "<EtherCATInfoList>" << endl;
    }

    for (si = slaves.begin(); si != slaves.end(); si++) {
        generateSlaveXml(m, *si, slaves.size() > 1 ? 1 : 0);
    }

    if (slaves.size() > 1) {
        cout << "</EtherCATInfoList>" << endl;
    }
}

/****************************************************************************/

void CommandXml::generateSlaveXml(
        MasterDevice &m,
        const ec_ioctl_slave_t &slave,
        unsigned int indent
        )
{
    ec_ioctl_slave_sync_t sync;
    ec_ioctl_slave_sync_pdo_t pdo;
    string pdoType, in;
    ec_ioctl_slave_sync_pdo_entry_t entry;
    unsigned int i, j, k;

    for (i = 0; i < indent; i++) {
        in += "  ";
    }

    cout
        << in << "<EtherCATInfo>" << endl
        << in << "  <!-- Slave " << slave.position << " -->" << endl
        << in << "  <Vendor>" << endl
        << in << "    <Id>" << slave.vendor_id << "</Id>" << endl
        << in << "  </Vendor>" << endl
        << in << "  <Descriptions>" << endl
        << in << "    <Devices>" << endl
        << in << "      <Device>" << endl
        << in << "        <Type ProductCode=\"#x"
        << hex << setfill('0') << setw(8) << slave.product_code
        << "\" RevisionNo=\"#x"
        << hex << setfill('0') << setw(8) << slave.revision_number
        << "\">" << slave.order << "</Type>" << endl;

    if (strlen(slave.name)) {
        cout
            << in << "        <Name><![CDATA["
            << slave.name
            << "]]></Name>" << endl;
    }

    for (i = 0; i < slave.sync_count; i++) {
        m.getSync(&sync, slave.position, i);

        cout
            << in << "        <Sm Enable=\"" << dec << (unsigned int) sync.enable
            << "\" StartAddress=\"#x" << hex << sync.physical_start_address
            << "\" ControlByte=\"#x" << hex << (unsigned int) sync.control_register
            << "\" DefaultSize=\"" << dec << sync.default_size
            << "\" />" << endl;
    }

    for (i = 0; i < slave.sync_count; i++) {
        m.getSync(&sync, slave.position, i);

        for (j = 0; j < sync.pdo_count; j++) {
            m.getPdo(&pdo, slave.position, i, j);
            pdoType = (sync.control_register & 0x04 ? "R" : "T");
            pdoType += "xPdo"; // last 2 letters lowercase in XML!

            cout
                << in << "        <" << pdoType
                << " Sm=\"" << i << "\" Fixed=\"1\" Mandatory=\"1\">" << endl
                << in << "          <Index>#x"
                << hex << setfill('0') << setw(4) << pdo.index
                << "</Index>" << endl
                << in << "          <Name>" << pdo.name << "</Name>" << endl;

            for (k = 0; k < pdo.entry_count; k++) {
                m.getPdoEntry(&entry, slave.position, i, j, k);

                cout
                    << in << "          <Entry>" << endl
                    << in << "            <Index>#x"
                    << hex << setfill('0') << setw(4) << entry.index
                    << "</Index>" << endl;
                if (entry.index)
                    cout
                        << in << "            <SubIndex>"
                        << dec << (unsigned int) entry.subindex
                        << "</SubIndex>" << endl;

                cout
                    << in << "            <BitLen>"
                    << dec << (unsigned int) entry.bit_length
                    << "</BitLen>" << endl;

                if (entry.index) {
                    cout
                        << in << "            <Name>" << entry.name
                        << "</Name>" << endl
                        << in << "            <DataType>";

                    if (entry.bit_length == 1) {
                        cout << "BOOL";
                    } else if (!(entry.bit_length % 8)) {
                        if (entry.bit_length <= 64) {
                            cout << "UINT" << (unsigned int) entry.bit_length;
                        } else {
                            cout << "STRING("
                                << (unsigned int) (entry.bit_length / 8)
                                << ")";
                        }
                    } else {
                        cout << "BIT" << (unsigned int) entry.bit_length;
                    }

                    cout << "</DataType>" << endl;
                }

                cout << in << "          </Entry>" << endl;
            }

            cout
                << in << "        </" << pdoType << ">" << endl;
        }
    }

    cout
        << in << "      </Device>" << endl
        << in << "    </Devices>" << endl
        << in << "  </Descriptions>" << endl
        << in << "</EtherCATInfo>" << endl;
}

/*****************************************************************************/


<|start_filename|>kernel/modules/virtual_framebuffer/vfb.c<|end_filename|>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>

#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/mm.h>
#include <linux/uaccess.h>

#define VFB_MAJOR 256
#define VFB_MINOR 1
#define VFB_DEV_CNT 1
#define VFB_DEV_NAME "vfbdev"

struct vfb_dev
{
    struct cdev cdev;
    unsigned char *buf;
};

static struct vfb_dev vfbdev;

static int vfb_open(struct inode *inode, struct file *filp)
{
    return 0;
}

static int vfb_release(struct inode *inode, struct file *filp)
{
    return 0;
}

static int vfb_mmap(struct file *filp, struct vm_area_struct *vma)
{
    int ret;
    /*
    ** vma用来描述一片映射区域的结构指针，一个进程有很多片映射的区域，每一个区域都有这样对应的一个结构，这些结构通过链表和红黑树组织在一起
    ** 第二个参数是用户指定的映射之后的虚拟起始地址
    ** 第三个参数是物理内存所对应的页框号(物理地址除以页的大小)
    ** 第四个参数是想要映射的空间的大小
    ** 最后一个参数代表该内存区域的访问权限
    ** 完了之后，这片物理内存区域将会被映射到用户空间
    */
    ret = remap_pfn_range(vma, vma->vm_start, virt_to_phys(vfbdev.buf) >> PAGE_SHIFT, vma->vm_end - vma->vm_start, vma->vm_page_prot);
    return ret ? -EAGAIN : 0;
}

static ssize_t vfb_read(struct file *filp, char __user *buf, size_t count, loff_t *pos)
{
    int ret = 0;
    size_t len = count;
    /* 越界调整 */
    if (*pos + len > PAGE_SIZE)
    {
        len = PAGE_SIZE - *pos;
    }
    /* copy_to_user返回未复制成功的字节数 */
    ret = copy_to_user(buf, vfbdev.buf + *pos, len);
    *pos += len - ret;
    return len - ret;
}

static loff_t vfb_llseek(struct file *filp, loff_t off, int whence)
{
    loff_t newpos;
    switch (whence)
    {
    case SEEK_SET:
        newpos = off;
        break;
    case SEEK_CUR:
        newpos = filp->f_pos + off;
        break;
    case SEEK_END:
        newpos = PAGE_SIZE + off;
        break;
    default:
        return -EINVAL;
    }
    /* 判断新位置是否合法 */
    if (newpos < 0 || newpos > PAGE_SIZE)
    {
        return -EINVAL;
    }
    /* 更新文件的位置值 */
    filp->f_pos = newpos;
    return newpos;
}

static struct file_operations vfb_ops = {
    .owner = THIS_MODULE,
    .open = vfb_open,
    .release = vfb_release,
    .read = vfb_read,
    .mmap = vfb_mmap,
    .llseek = vfb_llseek,
};

/* 模块初始化函数 */
static int __init vfb_init(void)
{
    int ret;
    dev_t dev;
    unsigned long addr;

    dev = MKDEV(VFB_MAJOR, VFB_MINOR);
    /* 向内核注册设备号，静态方式 */
    ret = register_chrdev_region(dev, VFB_DEV_CNT, VFB_DEV_NAME);
    if (ret)
    {
        goto reg_err;
    }
    /* 初始化cdev对象，绑定ops */
    cdev_init(&vfbdev.cdev, &vfb_ops);
    vfbdev.cdev.owner = THIS_MODULE;
    /* 添加到内核中的cdev_map散列表中 */
    ret = cdev_add(&vfbdev.cdev, dev, VFB_DEV_CNT);
    if (ret)
    {
        goto add_err;
    }

    /* 动态申请一页内存(内核空间按照页来管理内存，在进行映射时，地址要按照页大小对齐) */
    addr = __get_free_page(GFP_KERNEL); //内核空间的内存
    if (!addr)
    {
        goto get_err;
    }
    vfbdev.buf = (unsigned char *)addr;
    memset(vfbdev.buf, 0, PAGE_SIZE);

    return 0;
get_err:
    cdev_del(&vfbdev.cdev);
add_err:
    unregister_chrdev_region(dev, VFB_DEV_CNT);
reg_err:
    return ret;
}

/* 模块清理函数 */
static void __exit vfb_exit(void)
{
    dev_t dev;

    dev = MKDEV(VFB_MAJOR, VFB_MINOR);
    /* 释放申请的内存 */
    free_page((unsigned long)vfbdev.buf);
    cdev_del(&vfbdev.cdev);
    unregister_chrdev_region(dev, VFB_DEV_CNT);
}

/* 为模块初始化函数和清理函数取别名 */
module_init(vfb_init);
module_exit(vfb_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("suda-morris <<EMAIL>>");
MODULE_DESCRIPTION("A simple module");
MODULE_ALIAS("virtual-frame-buffer");

<|start_filename|>3rdpart/ethercat-1.5.2/devices/e1000/e1000_hw-2.6.26-orig.c<|end_filename|>
/*******************************************************************************

  Intel PRO/1000 Linux driver
  Copyright(c) 1999 - 2006 Intel Corporation.

  This program is free software; you can redistribute it and/or modify it
  under the terms and conditions of the GNU General Public License,
  version 2, as published by the Free Software Foundation.

  This program is distributed in the hope it will be useful, but WITHOUT
  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  more details.

  You should have received a copy of the GNU General Public License along with
  this program; if not, write to the Free Software Foundation, Inc.,
  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.

  The full GNU General Public License is included in this distribution in
  the file called "COPYING".

  Contact Information:
  Linux NICS <<EMAIL>>
  e1000-devel Mailing List <<EMAIL>>
  Intel Corporation, 5200 N.E. <NAME> Parkway, Hillsboro, OR 97124-6497

*******************************************************************************/

/* e1000_hw.c
 * Shared functions for accessing and configuring the MAC
 */


#include "e1000_hw.h"

static s32 e1000_swfw_sync_acquire(struct e1000_hw *hw, u16 mask);
static void e1000_swfw_sync_release(struct e1000_hw *hw, u16 mask);
static s32 e1000_read_kmrn_reg(struct e1000_hw *hw, u32 reg_addr, u16 *data);
static s32 e1000_write_kmrn_reg(struct e1000_hw *hw, u32 reg_addr, u16 data);
static s32 e1000_get_software_semaphore(struct e1000_hw *hw);
static void e1000_release_software_semaphore(struct e1000_hw *hw);

static u8 e1000_arc_subsystem_valid(struct e1000_hw *hw);
static s32 e1000_check_downshift(struct e1000_hw *hw);
static s32 e1000_check_polarity(struct e1000_hw *hw, e1000_rev_polarity *polarity);
static void e1000_clear_hw_cntrs(struct e1000_hw *hw);
static void e1000_clear_vfta(struct e1000_hw *hw);
static s32 e1000_commit_shadow_ram(struct e1000_hw *hw);
static s32 e1000_config_dsp_after_link_change(struct e1000_hw *hw,
						  bool link_up);
static s32 e1000_config_fc_after_link_up(struct e1000_hw *hw);
static s32 e1000_detect_gig_phy(struct e1000_hw *hw);
static s32 e1000_erase_ich8_4k_segment(struct e1000_hw *hw, u32 bank);
static s32 e1000_get_auto_rd_done(struct e1000_hw *hw);
static s32 e1000_get_cable_length(struct e1000_hw *hw, u16 *min_length, u16 *max_length);
static s32 e1000_get_hw_eeprom_semaphore(struct e1000_hw *hw);
static s32 e1000_get_phy_cfg_done(struct e1000_hw *hw);
static s32 e1000_get_software_flag(struct e1000_hw *hw);
static s32 e1000_ich8_cycle_init(struct e1000_hw *hw);
static s32 e1000_ich8_flash_cycle(struct e1000_hw *hw, u32 timeout);
static s32 e1000_id_led_init(struct e1000_hw *hw);
static s32 e1000_init_lcd_from_nvm_config_region(struct e1000_hw *hw, u32 cnf_base_addr, u32 cnf_size);
static s32 e1000_init_lcd_from_nvm(struct e1000_hw *hw);
static void e1000_init_rx_addrs(struct e1000_hw *hw);
static void e1000_initialize_hardware_bits(struct e1000_hw *hw);
static bool e1000_is_onboard_nvm_eeprom(struct e1000_hw *hw);
static s32 e1000_kumeran_lock_loss_workaround(struct e1000_hw *hw);
static s32 e1000_mng_enable_host_if(struct e1000_hw *hw);
static s32 e1000_mng_host_if_write(struct e1000_hw *hw, u8 *buffer, u16 length, u16 offset, u8 *sum);
static s32 e1000_mng_write_cmd_header(struct e1000_hw* hw, struct e1000_host_mng_command_header* hdr);
static s32 e1000_mng_write_commit(struct e1000_hw *hw);
static s32 e1000_phy_ife_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info);
static s32 e1000_phy_igp_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info);
static s32 e1000_read_eeprom_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data);
static s32 e1000_write_eeprom_eewr(struct e1000_hw *hw, u16 offset, u16 words, u16 *data);
static s32 e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int eerd);
static s32 e1000_phy_m88_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info);
static void e1000_put_hw_eeprom_semaphore(struct e1000_hw *hw);
static s32 e1000_read_ich8_byte(struct e1000_hw *hw, u32 index, u8 *data);
static s32 e1000_verify_write_ich8_byte(struct e1000_hw *hw, u32 index, u8 byte);
static s32 e1000_write_ich8_byte(struct e1000_hw *hw, u32 index, u8 byte);
static s32 e1000_read_ich8_word(struct e1000_hw *hw, u32 index, u16 *data);
static s32 e1000_read_ich8_data(struct e1000_hw *hw, u32 index, u32 size, u16 *data);
static s32 e1000_write_ich8_data(struct e1000_hw *hw, u32 index, u32 size, u16 data);
static s32 e1000_read_eeprom_ich8(struct e1000_hw *hw, u16 offset, u16 words, u16 *data);
static s32 e1000_write_eeprom_ich8(struct e1000_hw *hw, u16 offset, u16 words, u16 *data);
static void e1000_release_software_flag(struct e1000_hw *hw);
static s32 e1000_set_d3_lplu_state(struct e1000_hw *hw, bool active);
static s32 e1000_set_d0_lplu_state(struct e1000_hw *hw, bool active);
static s32 e1000_set_pci_ex_no_snoop(struct e1000_hw *hw, u32 no_snoop);
static void e1000_set_pci_express_master_disable(struct e1000_hw *hw);
static s32 e1000_wait_autoneg(struct e1000_hw *hw);
static void e1000_write_reg_io(struct e1000_hw *hw, u32 offset, u32 value);
static s32 e1000_set_phy_type(struct e1000_hw *hw);
static void e1000_phy_init_script(struct e1000_hw *hw);
static s32 e1000_setup_copper_link(struct e1000_hw *hw);
static s32 e1000_setup_fiber_serdes_link(struct e1000_hw *hw);
static s32 e1000_adjust_serdes_amplitude(struct e1000_hw *hw);
static s32 e1000_phy_force_speed_duplex(struct e1000_hw *hw);
static s32 e1000_config_mac_to_phy(struct e1000_hw *hw);
static void e1000_raise_mdi_clk(struct e1000_hw *hw, u32 *ctrl);
static void e1000_lower_mdi_clk(struct e1000_hw *hw, u32 *ctrl);
static void e1000_shift_out_mdi_bits(struct e1000_hw *hw, u32 data,
                                     u16 count);
static u16 e1000_shift_in_mdi_bits(struct e1000_hw *hw);
static s32 e1000_phy_reset_dsp(struct e1000_hw *hw);
static s32 e1000_write_eeprom_spi(struct e1000_hw *hw, u16 offset,
                                      u16 words, u16 *data);
static s32 e1000_write_eeprom_microwire(struct e1000_hw *hw,
                                            u16 offset, u16 words,
                                            u16 *data);
static s32 e1000_spi_eeprom_ready(struct e1000_hw *hw);
static void e1000_raise_ee_clk(struct e1000_hw *hw, u32 *eecd);
static void e1000_lower_ee_clk(struct e1000_hw *hw, u32 *eecd);
static void e1000_shift_out_ee_bits(struct e1000_hw *hw, u16 data,
                                    u16 count);
static s32 e1000_write_phy_reg_ex(struct e1000_hw *hw, u32 reg_addr,
                                      u16 phy_data);
static s32 e1000_read_phy_reg_ex(struct e1000_hw *hw,u32 reg_addr,
                                     u16 *phy_data);
static u16 e1000_shift_in_ee_bits(struct e1000_hw *hw, u16 count);
static s32 e1000_acquire_eeprom(struct e1000_hw *hw);
static void e1000_release_eeprom(struct e1000_hw *hw);
static void e1000_standby_eeprom(struct e1000_hw *hw);
static s32 e1000_set_vco_speed(struct e1000_hw *hw);
static s32 e1000_polarity_reversal_workaround(struct e1000_hw *hw);
static s32 e1000_set_phy_mode(struct e1000_hw *hw);
static s32 e1000_host_if_read_cookie(struct e1000_hw *hw, u8 *buffer);
static u8 e1000_calculate_mng_checksum(char *buffer, u32 length);
static s32 e1000_configure_kmrn_for_10_100(struct e1000_hw *hw,
                                               u16 duplex);
static s32 e1000_configure_kmrn_for_1000(struct e1000_hw *hw);

/* IGP cable length table */
static const
u16 e1000_igp_cable_length_table[IGP01E1000_AGC_LENGTH_TABLE_SIZE] =
    { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
      5, 10, 10, 10, 10, 10, 10, 10, 20, 20, 20, 20, 20, 25, 25, 25,
      25, 25, 25, 25, 30, 30, 30, 30, 40, 40, 40, 40, 40, 40, 40, 40,
      40, 50, 50, 50, 50, 50, 50, 50, 60, 60, 60, 60, 60, 60, 60, 60,
      60, 70, 70, 70, 70, 70, 70, 80, 80, 80, 80, 80, 80, 90, 90, 90,
      90, 90, 90, 90, 90, 90, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
      100, 100, 100, 100, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110,
      110, 110, 110, 110, 110, 110, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120};

static const
u16 e1000_igp_2_cable_length_table[IGP02E1000_AGC_LENGTH_TABLE_SIZE] =
    { 0, 0, 0, 0, 0, 0, 0, 0, 3, 5, 8, 11, 13, 16, 18, 21,
      0, 0, 0, 3, 6, 10, 13, 16, 19, 23, 26, 29, 32, 35, 38, 41,
      6, 10, 14, 18, 22, 26, 30, 33, 37, 41, 44, 48, 51, 54, 58, 61,
      21, 26, 31, 35, 40, 44, 49, 53, 57, 61, 65, 68, 72, 75, 79, 82,
      40, 45, 51, 56, 61, 66, 70, 75, 79, 83, 87, 91, 94, 98, 101, 104,
      60, 66, 72, 77, 82, 87, 92, 96, 100, 104, 108, 111, 114, 117, 119, 121,
      83, 89, 95, 100, 105, 109, 113, 116, 119, 122, 124,
      104, 109, 114, 118, 121, 124};

/******************************************************************************
 * Set the phy type member in the hw struct.
 *
 * hw - Struct containing variables accessed by shared code
 *****************************************************************************/
static s32
e1000_set_phy_type(struct e1000_hw *hw)
{
    DEBUGFUNC("e1000_set_phy_type");

    if (hw->mac_type == e1000_undefined)
        return -E1000_ERR_PHY_TYPE;

    switch (hw->phy_id) {
    case M88E1000_E_PHY_ID:
    case M88E1000_I_PHY_ID:
    case M88E1011_I_PHY_ID:
    case M88E1111_I_PHY_ID:
        hw->phy_type = e1000_phy_m88;
        break;
    case IGP01E1000_I_PHY_ID:
        if (hw->mac_type == e1000_82541 ||
            hw->mac_type == e1000_82541_rev_2 ||
            hw->mac_type == e1000_82547 ||
            hw->mac_type == e1000_82547_rev_2) {
            hw->phy_type = e1000_phy_igp;
            break;
        }
    case IGP03E1000_E_PHY_ID:
        hw->phy_type = e1000_phy_igp_3;
        break;
    case IFE_E_PHY_ID:
    case IFE_PLUS_E_PHY_ID:
    case IFE_C_E_PHY_ID:
        hw->phy_type = e1000_phy_ife;
        break;
    case GG82563_E_PHY_ID:
        if (hw->mac_type == e1000_80003es2lan) {
            hw->phy_type = e1000_phy_gg82563;
            break;
        }
        /* Fall Through */
    default:
        /* Should never have loaded on this device */
        hw->phy_type = e1000_phy_undefined;
        return -E1000_ERR_PHY_TYPE;
    }

    return E1000_SUCCESS;
}

/******************************************************************************
 * IGP phy init script - initializes the GbE PHY
 *
 * hw - Struct containing variables accessed by shared code
 *****************************************************************************/
static void
e1000_phy_init_script(struct e1000_hw *hw)
{
    u32 ret_val;
    u16 phy_saved_data;

    DEBUGFUNC("e1000_phy_init_script");

    if (hw->phy_init_script) {
        msleep(20);

        /* Save off the current value of register 0x2F5B to be restored at
         * the end of this routine. */
        ret_val = e1000_read_phy_reg(hw, 0x2F5B, &phy_saved_data);

        /* Disabled the PHY transmitter */
        e1000_write_phy_reg(hw, 0x2F5B, 0x0003);

        msleep(20);

        e1000_write_phy_reg(hw,0x0000,0x0140);

        msleep(5);

        switch (hw->mac_type) {
        case e1000_82541:
        case e1000_82547:
            e1000_write_phy_reg(hw, 0x1F95, 0x0001);

            e1000_write_phy_reg(hw, 0x1F71, 0xBD21);

            e1000_write_phy_reg(hw, 0x1F79, 0x0018);

            e1000_write_phy_reg(hw, 0x1F30, 0x1600);

            e1000_write_phy_reg(hw, 0x1F31, 0x0014);

            e1000_write_phy_reg(hw, 0x1F32, 0x161C);

            e1000_write_phy_reg(hw, 0x1F94, 0x0003);

            e1000_write_phy_reg(hw, 0x1F96, 0x003F);

            e1000_write_phy_reg(hw, 0x2010, 0x0008);
            break;

        case e1000_82541_rev_2:
        case e1000_82547_rev_2:
            e1000_write_phy_reg(hw, 0x1F73, 0x0099);
            break;
        default:
            break;
        }

        e1000_write_phy_reg(hw, 0x0000, 0x3300);

        msleep(20);

        /* Now enable the transmitter */
        e1000_write_phy_reg(hw, 0x2F5B, phy_saved_data);

        if (hw->mac_type == e1000_82547) {
            u16 fused, fine, coarse;

            /* Move to analog registers page */
            e1000_read_phy_reg(hw, IGP01E1000_ANALOG_SPARE_FUSE_STATUS, &fused);

            if (!(fused & IGP01E1000_ANALOG_SPARE_FUSE_ENABLED)) {
                e1000_read_phy_reg(hw, IGP01E1000_ANALOG_FUSE_STATUS, &fused);

                fine = fused & IGP01E1000_ANALOG_FUSE_FINE_MASK;
                coarse = fused & IGP01E1000_ANALOG_FUSE_COARSE_MASK;

                if (coarse > IGP01E1000_ANALOG_FUSE_COARSE_THRESH) {
                    coarse -= IGP01E1000_ANALOG_FUSE_COARSE_10;
                    fine -= IGP01E1000_ANALOG_FUSE_FINE_1;
                } else if (coarse == IGP01E1000_ANALOG_FUSE_COARSE_THRESH)
                    fine -= IGP01E1000_ANALOG_FUSE_FINE_10;

                fused = (fused & IGP01E1000_ANALOG_FUSE_POLY_MASK) |
                        (fine & IGP01E1000_ANALOG_FUSE_FINE_MASK) |
                        (coarse & IGP01E1000_ANALOG_FUSE_COARSE_MASK);

                e1000_write_phy_reg(hw, IGP01E1000_ANALOG_FUSE_CONTROL, fused);
                e1000_write_phy_reg(hw, IGP01E1000_ANALOG_FUSE_BYPASS,
                                    IGP01E1000_ANALOG_FUSE_ENABLE_SW_CONTROL);
            }
        }
    }
}

/******************************************************************************
 * Set the mac type member in the hw struct.
 *
 * hw - Struct containing variables accessed by shared code
 *****************************************************************************/
s32
e1000_set_mac_type(struct e1000_hw *hw)
{
	DEBUGFUNC("e1000_set_mac_type");

	switch (hw->device_id) {
	case E1000_DEV_ID_82542:
		switch (hw->revision_id) {
		case E1000_82542_2_0_REV_ID:
			hw->mac_type = e1000_82542_rev2_0;
			break;
		case E1000_82542_2_1_REV_ID:
			hw->mac_type = e1000_82542_rev2_1;
			break;
		default:
			/* Invalid 82542 revision ID */
			return -E1000_ERR_MAC_TYPE;
		}
		break;
	case E1000_DEV_ID_82543GC_FIBER:
	case E1000_DEV_ID_82543GC_COPPER:
		hw->mac_type = e1000_82543;
		break;
	case E1000_DEV_ID_82544EI_COPPER:
	case E1000_DEV_ID_82544EI_FIBER:
	case E1000_DEV_ID_82544GC_COPPER:
	case E1000_DEV_ID_82544GC_LOM:
		hw->mac_type = e1000_82544;
		break;
	case E1000_DEV_ID_82540EM:
	case E1000_DEV_ID_82540EM_LOM:
	case E1000_DEV_ID_82540EP:
	case E1000_DEV_ID_82540EP_LOM:
	case E1000_DEV_ID_82540EP_LP:
		hw->mac_type = e1000_82540;
		break;
	case E1000_DEV_ID_82545EM_COPPER:
	case E1000_DEV_ID_82545EM_FIBER:
		hw->mac_type = e1000_82545;
		break;
	case E1000_DEV_ID_82545GM_COPPER:
	case E1000_DEV_ID_82545GM_FIBER:
	case E1000_DEV_ID_82545GM_SERDES:
		hw->mac_type = e1000_82545_rev_3;
		break;
	case E1000_DEV_ID_82546EB_COPPER:
	case E1000_DEV_ID_82546EB_FIBER:
	case E1000_DEV_ID_82546EB_QUAD_COPPER:
		hw->mac_type = e1000_82546;
		break;
	case E1000_DEV_ID_82546GB_COPPER:
	case E1000_DEV_ID_82546GB_FIBER:
	case E1000_DEV_ID_82546GB_SERDES:
	case E1000_DEV_ID_82546GB_PCIE:
	case E1000_DEV_ID_82546GB_QUAD_COPPER:
	case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3:
		hw->mac_type = e1000_82546_rev_3;
		break;
	case E1000_DEV_ID_82541EI:
	case E1000_DEV_ID_82541EI_MOBILE:
	case E1000_DEV_ID_82541ER_LOM:
		hw->mac_type = e1000_82541;
		break;
	case E1000_DEV_ID_82541ER:
	case E1000_DEV_ID_82541GI:
	case E1000_DEV_ID_82541GI_LF:
	case E1000_DEV_ID_82541GI_MOBILE:
		hw->mac_type = e1000_82541_rev_2;
		break;
	case E1000_DEV_ID_82547EI:
	case E1000_DEV_ID_82547EI_MOBILE:
		hw->mac_type = e1000_82547;
		break;
	case E1000_DEV_ID_82547GI:
		hw->mac_type = e1000_82547_rev_2;
		break;
	case E1000_DEV_ID_82571EB_COPPER:
	case E1000_DEV_ID_82571EB_FIBER:
	case E1000_DEV_ID_82571EB_SERDES:
	case E1000_DEV_ID_82571EB_SERDES_DUAL:
	case E1000_DEV_ID_82571EB_SERDES_QUAD:
	case E1000_DEV_ID_82571EB_QUAD_COPPER:
	case E1000_DEV_ID_82571PT_QUAD_COPPER:
	case E1000_DEV_ID_82571EB_QUAD_FIBER:
	case E1000_DEV_ID_82571EB_QUAD_COPPER_LOWPROFILE:
		hw->mac_type = e1000_82571;
		break;
	case E1000_DEV_ID_82572EI_COPPER:
	case E1000_DEV_ID_82572EI_FIBER:
	case E1000_DEV_ID_82572EI_SERDES:
	case E1000_DEV_ID_82572EI:
		hw->mac_type = e1000_82572;
		break;
	case E1000_DEV_ID_82573E:
	case E1000_DEV_ID_82573E_IAMT:
	case E1000_DEV_ID_82573L:
		hw->mac_type = e1000_82573;
		break;
	case E1000_DEV_ID_80003ES2LAN_COPPER_SPT:
	case E1000_DEV_ID_80003ES2LAN_SERDES_SPT:
	case E1000_DEV_ID_80003ES2LAN_COPPER_DPT:
	case E1000_DEV_ID_80003ES2LAN_SERDES_DPT:
		hw->mac_type = e1000_80003es2lan;
		break;
	case E1000_DEV_ID_ICH8_IGP_M_AMT:
	case E1000_DEV_ID_ICH8_IGP_AMT:
	case E1000_DEV_ID_ICH8_IGP_C:
	case E1000_DEV_ID_ICH8_IFE:
	case E1000_DEV_ID_ICH8_IFE_GT:
	case E1000_DEV_ID_ICH8_IFE_G:
	case E1000_DEV_ID_ICH8_IGP_M:
		hw->mac_type = e1000_ich8lan;
		break;
	default:
		/* Should never have loaded on this device */
		return -E1000_ERR_MAC_TYPE;
	}

	switch (hw->mac_type) {
	case e1000_ich8lan:
		hw->swfwhw_semaphore_present = true;
		hw->asf_firmware_present = true;
		break;
	case e1000_80003es2lan:
		hw->swfw_sync_present = true;
		/* fall through */
	case e1000_82571:
	case e1000_82572:
	case e1000_82573:
		hw->eeprom_semaphore_present = true;
		/* fall through */
	case e1000_82541:
	case e1000_82547:
	case e1000_82541_rev_2:
	case e1000_82547_rev_2:
		hw->asf_firmware_present = true;
		break;
	default:
		break;
	}

	/* The 82543 chip does not count tx_carrier_errors properly in
	 * FD mode
	 */
	if (hw->mac_type == e1000_82543)
		hw->bad_tx_carr_stats_fd = true;

	/* capable of receiving management packets to the host */
	if (hw->mac_type >= e1000_82571)
		hw->has_manc2h = true;

	/* In rare occasions, ESB2 systems would end up started without
	 * the RX unit being turned on.
	 */
	if (hw->mac_type == e1000_80003es2lan)
		hw->rx_needs_kicking = true;

	if (hw->mac_type > e1000_82544)
		hw->has_smbus = true;

	return E1000_SUCCESS;
}

/*****************************************************************************
 * Set media type and TBI compatibility.
 *
 * hw - Struct containing variables accessed by shared code
 * **************************************************************************/
void
e1000_set_media_type(struct e1000_hw *hw)
{
    u32 status;

    DEBUGFUNC("e1000_set_media_type");

    if (hw->mac_type != e1000_82543) {
        /* tbi_compatibility is only valid on 82543 */
        hw->tbi_compatibility_en = false;
    }

    switch (hw->device_id) {
    case E1000_DEV_ID_82545GM_SERDES:
    case E1000_DEV_ID_82546GB_SERDES:
    case E1000_DEV_ID_82571EB_SERDES:
    case E1000_DEV_ID_82571EB_SERDES_DUAL:
    case E1000_DEV_ID_82571EB_SERDES_QUAD:
    case E1000_DEV_ID_82572EI_SERDES:
    case E1000_DEV_ID_80003ES2LAN_SERDES_DPT:
        hw->media_type = e1000_media_type_internal_serdes;
        break;
    default:
        switch (hw->mac_type) {
        case e1000_82542_rev2_0:
        case e1000_82542_rev2_1:
            hw->media_type = e1000_media_type_fiber;
            break;
        case e1000_ich8lan:
        case e1000_82573:
            /* The STATUS_TBIMODE bit is reserved or reused for the this
             * device.
             */
            hw->media_type = e1000_media_type_copper;
            break;
        default:
            status = E1000_READ_REG(hw, STATUS);
            if (status & E1000_STATUS_TBIMODE) {
                hw->media_type = e1000_media_type_fiber;
                /* tbi_compatibility not valid on fiber */
                hw->tbi_compatibility_en = false;
            } else {
                hw->media_type = e1000_media_type_copper;
            }
            break;
        }
    }
}

/******************************************************************************
 * Reset the transmit and receive units; mask and clear all interrupts.
 *
 * hw - Struct containing variables accessed by shared code
 *****************************************************************************/
s32
e1000_reset_hw(struct e1000_hw *hw)
{
    u32 ctrl;
    u32 ctrl_ext;
    u32 icr;
    u32 manc;
    u32 led_ctrl;
    u32 timeout;
    u32 extcnf_ctrl;
    s32 ret_val;

    DEBUGFUNC("e1000_reset_hw");

    /* For 82542 (rev 2.0), disable MWI before issuing a device reset */
    if (hw->mac_type == e1000_82542_rev2_0) {
        DEBUGOUT("Disabling MWI on 82542 rev 2.0\n");
        e1000_pci_clear_mwi(hw);
    }

    if (hw->bus_type == e1000_bus_type_pci_express) {
        /* Prevent the PCI-E bus from sticking if there is no TLP connection
         * on the last TLP read/write transaction when MAC is reset.
         */
        if (e1000_disable_pciex_master(hw) != E1000_SUCCESS) {
            DEBUGOUT("PCI-E Master disable polling has failed.\n");
        }
    }

    /* Clear interrupt mask to stop board from generating interrupts */
    DEBUGOUT("Masking off all interrupts\n");
    E1000_WRITE_REG(hw, IMC, 0xffffffff);

    /* Disable the Transmit and Receive units.  Then delay to allow
     * any pending transactions to complete before we hit the MAC with
     * the global reset.
     */
    E1000_WRITE_REG(hw, RCTL, 0);
    E1000_WRITE_REG(hw, TCTL, E1000_TCTL_PSP);
    E1000_WRITE_FLUSH(hw);

    /* The tbi_compatibility_on Flag must be cleared when Rctl is cleared. */
    hw->tbi_compatibility_on = false;

    /* Delay to allow any outstanding PCI transactions to complete before
     * resetting the device
     */
    msleep(10);

    ctrl = E1000_READ_REG(hw, CTRL);

    /* Must reset the PHY before resetting the MAC */
    if ((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
        E1000_WRITE_REG(hw, CTRL, (ctrl | E1000_CTRL_PHY_RST));
        msleep(5);
    }

    /* Must acquire the MDIO ownership before MAC reset.
     * Ownership defaults to firmware after a reset. */
    if (hw->mac_type == e1000_82573) {
        timeout = 10;

        extcnf_ctrl = E1000_READ_REG(hw, EXTCNF_CTRL);
        extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP;

        do {
            E1000_WRITE_REG(hw, EXTCNF_CTRL, extcnf_ctrl);
            extcnf_ctrl = E1000_READ_REG(hw, EXTCNF_CTRL);

            if (extcnf_ctrl & E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP)
                break;
            else
                extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP;

            msleep(2);
            timeout--;
        } while (timeout);
    }

    /* Workaround for ICH8 bit corruption issue in FIFO memory */
    if (hw->mac_type == e1000_ich8lan) {
        /* Set Tx and Rx buffer allocation to 8k apiece. */
        E1000_WRITE_REG(hw, PBA, E1000_PBA_8K);
        /* Set Packet Buffer Size to 16k. */
        E1000_WRITE_REG(hw, PBS, E1000_PBS_16K);
    }

    /* Issue a global reset to the MAC.  This will reset the chip's
     * transmit, receive, DMA, and link units.  It will not effect
     * the current PCI configuration.  The global reset bit is self-
     * clearing, and should clear within a microsecond.
     */
    DEBUGOUT("Issuing a global reset to MAC\n");

    switch (hw->mac_type) {
        case e1000_82544:
        case e1000_82540:
        case e1000_82545:
        case e1000_82546:
        case e1000_82541:
        case e1000_82541_rev_2:
            /* These controllers can't ack the 64-bit write when issuing the
             * reset, so use IO-mapping as a workaround to issue the reset */
            E1000_WRITE_REG_IO(hw, CTRL, (ctrl | E1000_CTRL_RST));
            break;
        case e1000_82545_rev_3:
        case e1000_82546_rev_3:
            /* Reset is performed on a shadow of the control register */
            E1000_WRITE_REG(hw, CTRL_DUP, (ctrl | E1000_CTRL_RST));
            break;
        case e1000_ich8lan:
            if (!hw->phy_reset_disable &&
                e1000_check_phy_reset_block(hw) == E1000_SUCCESS) {
                /* e1000_ich8lan PHY HW reset requires MAC CORE reset
                 * at the same time to make sure the interface between
                 * MAC and the external PHY is reset.
                 */
                ctrl |= E1000_CTRL_PHY_RST;
            }

            e1000_get_software_flag(hw);
            E1000_WRITE_REG(hw, CTRL, (ctrl | E1000_CTRL_RST));
            msleep(5);
            break;
        default:
            E1000_WRITE_REG(hw, CTRL, (ctrl | E1000_CTRL_RST));
            break;
    }

    /* After MAC reset, force reload of EEPROM to restore power-on settings to
     * device.  Later controllers reload the EEPROM automatically, so just wait
     * for reload to complete.
     */
    switch (hw->mac_type) {
        case e1000_82542_rev2_0:
        case e1000_82542_rev2_1:
        case e1000_82543:
        case e1000_82544:
            /* Wait for reset to complete */
            udelay(10);
            ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
            ctrl_ext |= E1000_CTRL_EXT_EE_RST;
            E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
            E1000_WRITE_FLUSH(hw);
            /* Wait for EEPROM reload */
            msleep(2);
            break;
        case e1000_82541:
        case e1000_82541_rev_2:
        case e1000_82547:
        case e1000_82547_rev_2:
            /* Wait for EEPROM reload */
            msleep(20);
            break;
        case e1000_82573:
            if (!e1000_is_onboard_nvm_eeprom(hw)) {
                udelay(10);
                ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
                ctrl_ext |= E1000_CTRL_EXT_EE_RST;
                E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
                E1000_WRITE_FLUSH(hw);
            }
            /* fall through */
        default:
            /* Auto read done will delay 5ms or poll based on mac type */
            ret_val = e1000_get_auto_rd_done(hw);
            if (ret_val)
                return ret_val;
            break;
    }

    /* Disable HW ARPs on ASF enabled adapters */
    if (hw->mac_type >= e1000_82540 && hw->mac_type <= e1000_82547_rev_2) {
        manc = E1000_READ_REG(hw, MANC);
        manc &= ~(E1000_MANC_ARP_EN);
        E1000_WRITE_REG(hw, MANC, manc);
    }

    if ((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
        e1000_phy_init_script(hw);

        /* Configure activity LED after PHY reset */
        led_ctrl = E1000_READ_REG(hw, LEDCTL);
        led_ctrl &= IGP_ACTIVITY_LED_MASK;
        led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE);
        E1000_WRITE_REG(hw, LEDCTL, led_ctrl);
    }

    /* Clear interrupt mask to stop board from generating interrupts */
    DEBUGOUT("Masking off all interrupts\n");
    E1000_WRITE_REG(hw, IMC, 0xffffffff);

    /* Clear any pending interrupt events. */
    icr = E1000_READ_REG(hw, ICR);

    /* If MWI was previously enabled, reenable it. */
    if (hw->mac_type == e1000_82542_rev2_0) {
        if (hw->pci_cmd_word & PCI_COMMAND_INVALIDATE)
            e1000_pci_set_mwi(hw);
    }

    if (hw->mac_type == e1000_ich8lan) {
        u32 kab = E1000_READ_REG(hw, KABGTXD);
        kab |= E1000_KABGTXD_BGSQLBIAS;
        E1000_WRITE_REG(hw, KABGTXD, kab);
    }

    return E1000_SUCCESS;
}

/******************************************************************************
 *
 * Initialize a number of hardware-dependent bits
 *
 * hw: Struct containing variables accessed by shared code
 *
 * This function contains hardware limitation workarounds for PCI-E adapters
 *
 *****************************************************************************/
static void
e1000_initialize_hardware_bits(struct e1000_hw *hw)
{
    if ((hw->mac_type >= e1000_82571) && (!hw->initialize_hw_bits_disable)) {
        /* Settings common to all PCI-express silicon */
        u32 reg_ctrl, reg_ctrl_ext;
        u32 reg_tarc0, reg_tarc1;
        u32 reg_tctl;
        u32 reg_txdctl, reg_txdctl1;

        /* link autonegotiation/sync workarounds */
        reg_tarc0 = E1000_READ_REG(hw, TARC0);
        reg_tarc0 &= ~((1 << 30)|(1 << 29)|(1 << 28)|(1 << 27));

        /* Enable not-done TX descriptor counting */
        reg_txdctl = E1000_READ_REG(hw, TXDCTL);
        reg_txdctl |= E1000_TXDCTL_COUNT_DESC;
        E1000_WRITE_REG(hw, TXDCTL, reg_txdctl);
        reg_txdctl1 = E1000_READ_REG(hw, TXDCTL1);
        reg_txdctl1 |= E1000_TXDCTL_COUNT_DESC;
        E1000_WRITE_REG(hw, TXDCTL1, reg_txdctl1);

        switch (hw->mac_type) {
            case e1000_82571:
            case e1000_82572:
                /* Clear PHY TX compatible mode bits */
                reg_tarc1 = E1000_READ_REG(hw, TARC1);
                reg_tarc1 &= ~((1 << 30)|(1 << 29));

                /* link autonegotiation/sync workarounds */
                reg_tarc0 |= ((1 << 26)|(1 << 25)|(1 << 24)|(1 << 23));

                /* TX ring control fixes */
                reg_tarc1 |= ((1 << 26)|(1 << 25)|(1 << 24));

                /* Multiple read bit is reversed polarity */
                reg_tctl = E1000_READ_REG(hw, TCTL);
                if (reg_tctl & E1000_TCTL_MULR)
                    reg_tarc1 &= ~(1 << 28);
                else
                    reg_tarc1 |= (1 << 28);

                E1000_WRITE_REG(hw, TARC1, reg_tarc1);
                break;
            case e1000_82573:
                reg_ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
                reg_ctrl_ext &= ~(1 << 23);
                reg_ctrl_ext |= (1 << 22);

                /* TX byte count fix */
                reg_ctrl = E1000_READ_REG(hw, CTRL);
                reg_ctrl &= ~(1 << 29);

                E1000_WRITE_REG(hw, CTRL_EXT, reg_ctrl_ext);
                E1000_WRITE_REG(hw, CTRL, reg_ctrl);
                break;
            case e1000_80003es2lan:
                /* improve small packet performace for fiber/serdes */
                if ((hw->media_type == e1000_media_type_fiber) ||
                    (hw->media_type == e1000_media_type_internal_serdes)) {
                    reg_tarc0 &= ~(1 << 20);
                }

                /* Multiple read bit is reversed polarity */
                reg_tctl = E1000_READ_REG(hw, TCTL);
                reg_tarc1 = E1000_READ_REG(hw, TARC1);
                if (reg_tctl & E1000_TCTL_MULR)
                    reg_tarc1 &= ~(1 << 28);
                else
                    reg_tarc1 |= (1 << 28);

                E1000_WRITE_REG(hw, TARC1, reg_tarc1);
                break;
            case e1000_ich8lan:
                /* Reduce concurrent DMA requests to 3 from 4 */
                if ((hw->revision_id < 3) ||
                    ((hw->device_id != E1000_DEV_ID_ICH8_IGP_M_AMT) &&
                     (hw->device_id != E1000_DEV_ID_ICH8_IGP_M)))
                    reg_tarc0 |= ((1 << 29)|(1 << 28));

                reg_ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
                reg_ctrl_ext |= (1 << 22);
                E1000_WRITE_REG(hw, CTRL_EXT, reg_ctrl_ext);

                /* workaround TX hang with TSO=on */
                reg_tarc0 |= ((1 << 27)|(1 << 26)|(1 << 24)|(1 << 23));

                /* Multiple read bit is reversed polarity */
                reg_tctl = E1000_READ_REG(hw, TCTL);
                reg_tarc1 = E1000_READ_REG(hw, TARC1);
                if (reg_tctl & E1000_TCTL_MULR)
                    reg_tarc1 &= ~(1 << 28);
                else
                    reg_tarc1 |= (1 << 28);

                /* workaround TX hang with TSO=on */
                reg_tarc1 |= ((1 << 30)|(1 << 26)|(1 << 24));

                E1000_WRITE_REG(hw, TARC1, reg_tarc1);
                break;
            default:
                break;
        }

        E1000_WRITE_REG(hw, TARC0, reg_tarc0);
    }
}

/******************************************************************************
 * Performs basic configuration of the adapter.
 *
 * hw - Struct containing variables accessed by shared code
 *
 * Assumes that the controller has previously been reset and is in a
 * post-reset uninitialized state. Initializes the receive address registers,
 * multicast table, and VLAN filter table. Calls routines to setup link
 * configuration and flow control settings. Clears all on-chip counters. Leaves
 * the transmit and receive units disabled and uninitialized.
 *****************************************************************************/
s32
e1000_init_hw(struct e1000_hw *hw)
{
    u32 ctrl;
    u32 i;
    s32 ret_val;
    u32 mta_size;
    u32 reg_data;
    u32 ctrl_ext;

    DEBUGFUNC("e1000_init_hw");

    /* force full DMA clock frequency for 10/100 on ICH8 A0-B0 */
    if ((hw->mac_type == e1000_ich8lan) &&
        ((hw->revision_id < 3) ||
         ((hw->device_id != E1000_DEV_ID_ICH8_IGP_M_AMT) &&
          (hw->device_id != E1000_DEV_ID_ICH8_IGP_M)))) {
            reg_data = E1000_READ_REG(hw, STATUS);
            reg_data &= ~0x80000000;
            E1000_WRITE_REG(hw, STATUS, reg_data);
    }

    /* Initialize Identification LED */
    ret_val = e1000_id_led_init(hw);
    if (ret_val) {
        DEBUGOUT("Error Initializing Identification LED\n");
        return ret_val;
    }

    /* Set the media type and TBI compatibility */
    e1000_set_media_type(hw);

    /* Must be called after e1000_set_media_type because media_type is used */
    e1000_initialize_hardware_bits(hw);

    /* Disabling VLAN filtering. */
    DEBUGOUT("Initializing the IEEE VLAN\n");
    /* VET hardcoded to standard value and VFTA removed in ICH8 LAN */
    if (hw->mac_type != e1000_ich8lan) {
        if (hw->mac_type < e1000_82545_rev_3)
            E1000_WRITE_REG(hw, VET, 0);
        e1000_clear_vfta(hw);
    }

    /* For 82542 (rev 2.0), disable MWI and put the receiver into reset */
    if (hw->mac_type == e1000_82542_rev2_0) {
        DEBUGOUT("Disabling MWI on 82542 rev 2.0\n");
        e1000_pci_clear_mwi(hw);
        E1000_WRITE_REG(hw, RCTL, E1000_RCTL_RST);
        E1000_WRITE_FLUSH(hw);
        msleep(5);
    }

    /* Setup the receive address. This involves initializing all of the Receive
     * Address Registers (RARs 0 - 15).
     */
    e1000_init_rx_addrs(hw);

    /* For 82542 (rev 2.0), take the receiver out of reset and enable MWI */
    if (hw->mac_type == e1000_82542_rev2_0) {
        E1000_WRITE_REG(hw, RCTL, 0);
        E1000_WRITE_FLUSH(hw);
        msleep(1);
        if (hw->pci_cmd_word & PCI_COMMAND_INVALIDATE)
            e1000_pci_set_mwi(hw);
    }

    /* Zero out the Multicast HASH table */
    DEBUGOUT("Zeroing the MTA\n");
    mta_size = E1000_MC_TBL_SIZE;
    if (hw->mac_type == e1000_ich8lan)
        mta_size = E1000_MC_TBL_SIZE_ICH8LAN;
    for (i = 0; i < mta_size; i++) {
        E1000_WRITE_REG_ARRAY(hw, MTA, i, 0);
        /* use write flush to prevent Memory Write Block (MWB) from
         * occuring when accessing our register space */
        E1000_WRITE_FLUSH(hw);
    }

    /* Set the PCI priority bit correctly in the CTRL register.  This
     * determines if the adapter gives priority to receives, or if it
     * gives equal priority to transmits and receives.  Valid only on
     * 82542 and 82543 silicon.
     */
    if (hw->dma_fairness && hw->mac_type <= e1000_82543) {
        ctrl = E1000_READ_REG(hw, CTRL);
        E1000_WRITE_REG(hw, CTRL, ctrl | E1000_CTRL_PRIOR);
    }

    switch (hw->mac_type) {
    case e1000_82545_rev_3:
    case e1000_82546_rev_3:
        break;
    default:
        /* Workaround for PCI-X problem when BIOS sets MMRBC incorrectly. */
	if (hw->bus_type == e1000_bus_type_pcix && e1000_pcix_get_mmrbc(hw) > 2048)
		e1000_pcix_set_mmrbc(hw, 2048);
	break;
    }

    /* More time needed for PHY to initialize */
    if (hw->mac_type == e1000_ich8lan)
        msleep(15);

    /* Call a subroutine to configure the link and setup flow control. */
    ret_val = e1000_setup_link(hw);

    /* Set the transmit descriptor write-back policy */
    if (hw->mac_type > e1000_82544) {
        ctrl = E1000_READ_REG(hw, TXDCTL);
        ctrl = (ctrl & ~E1000_TXDCTL_WTHRESH) | E1000_TXDCTL_FULL_TX_DESC_WB;
        E1000_WRITE_REG(hw, TXDCTL, ctrl);
    }

    if (hw->mac_type == e1000_82573) {
        e1000_enable_tx_pkt_filtering(hw);
    }

    switch (hw->mac_type) {
    default:
        break;
    case e1000_80003es2lan:
        /* Enable retransmit on late collisions */
        reg_data = E1000_READ_REG(hw, TCTL);
        reg_data |= E1000_TCTL_RTLC;
        E1000_WRITE_REG(hw, TCTL, reg_data);

        /* Configure Gigabit Carry Extend Padding */
        reg_data = E1000_READ_REG(hw, TCTL_EXT);
        reg_data &= ~E1000_TCTL_EXT_GCEX_MASK;
        reg_data |= DEFAULT_80003ES2LAN_TCTL_EXT_GCEX;
        E1000_WRITE_REG(hw, TCTL_EXT, reg_data);

        /* Configure Transmit Inter-Packet Gap */
        reg_data = E1000_READ_REG(hw, TIPG);
        reg_data &= ~E1000_TIPG_IPGT_MASK;
        reg_data |= DEFAULT_80003ES2LAN_TIPG_IPGT_1000;
        E1000_WRITE_REG(hw, TIPG, reg_data);

        reg_data = E1000_READ_REG_ARRAY(hw, FFLT, 0x0001);
        reg_data &= ~0x00100000;
        E1000_WRITE_REG_ARRAY(hw, FFLT, 0x0001, reg_data);
        /* Fall through */
    case e1000_82571:
    case e1000_82572:
    case e1000_ich8lan:
        ctrl = E1000_READ_REG(hw, TXDCTL1);
        ctrl = (ctrl & ~E1000_TXDCTL_WTHRESH) | E1000_TXDCTL_FULL_TX_DESC_WB;
        E1000_WRITE_REG(hw, TXDCTL1, ctrl);
        break;
    }


    if (hw->mac_type == e1000_82573) {
        u32 gcr = E1000_READ_REG(hw, GCR);
        gcr |= E1000_GCR_L1_ACT_WITHOUT_L0S_RX;
        E1000_WRITE_REG(hw, GCR, gcr);
    }

    /* Clear all of the statistics registers (clear on read).  It is
     * important that we do this after we have tried to establish link
     * because the symbol error count will increment wildly if there
     * is no link.
     */
    e1000_clear_hw_cntrs(hw);

    /* ICH8 No-snoop bits are opposite polarity.
     * Set to snoop by default after reset. */
    if (hw->mac_type == e1000_ich8lan)
        e1000_set_pci_ex_no_snoop(hw, PCI_EX_82566_SNOOP_ALL);

    if (hw->device_id == E1000_DEV_ID_82546GB_QUAD_COPPER ||
        hw->device_id == E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3) {
        ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
        /* Relaxed ordering must be disabled to avoid a parity
         * error crash in a PCI slot. */
        ctrl_ext |= E1000_CTRL_EXT_RO_DIS;
        E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
    }

    return ret_val;
}

/******************************************************************************
 * Adjust SERDES output amplitude based on EEPROM setting.
 *
 * hw - Struct containing variables accessed by shared code.
 *****************************************************************************/
static s32
e1000_adjust_serdes_amplitude(struct e1000_hw *hw)
{
    u16 eeprom_data;
    s32  ret_val;

    DEBUGFUNC("e1000_adjust_serdes_amplitude");

    if (hw->media_type != e1000_media_type_internal_serdes)
        return E1000_SUCCESS;

    switch (hw->mac_type) {
    case e1000_82545_rev_3:
    case e1000_82546_rev_3:
        break;
    default:
        return E1000_SUCCESS;
    }

    ret_val = e1000_read_eeprom(hw, EEPROM_SERDES_AMPLITUDE, 1, &eeprom_data);
    if (ret_val) {
        return ret_val;
    }

    if (eeprom_data != EEPROM_RESERVED_WORD) {
        /* Adjust SERDES output amplitude only. */
        eeprom_data &= EEPROM_SERDES_AMPLITUDE_MASK;
        ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_EXT_CTRL, eeprom_data);
        if (ret_val)
            return ret_val;
    }

    return E1000_SUCCESS;
}

/******************************************************************************
 * Configures flow control and link settings.
 *
 * hw - Struct containing variables accessed by shared code
 *
 * Determines which flow control settings to use. Calls the apropriate media-
 * specific link configuration function. Configures the flow control settings.
 * Assuming the adapter has a valid link partner, a valid link should be
 * established. Assumes the hardware has previously been reset and the
 * transmitter and receiver are not enabled.
 *****************************************************************************/
s32
e1000_setup_link(struct e1000_hw *hw)
{
    u32 ctrl_ext;
    s32 ret_val;
    u16 eeprom_data;

    DEBUGFUNC("e1000_setup_link");

    /* In the case of the phy reset being blocked, we already have a link.
     * We do not have to set it up again. */
    if (e1000_check_phy_reset_block(hw))
        return E1000_SUCCESS;

    /* Read and store word 0x0F of the EEPROM. This word contains bits
     * that determine the hardware's default PAUSE (flow control) mode,
     * a bit that determines whether the HW defaults to enabling or
     * disabling auto-negotiation, and the direction of the
     * SW defined pins. If there is no SW over-ride of the flow
     * control setting, then the variable hw->fc will
     * be initialized based on a value in the EEPROM.
     */
    if (hw->fc == E1000_FC_DEFAULT) {
        switch (hw->mac_type) {
        case e1000_ich8lan:
        case e1000_82573:
            hw->fc = E1000_FC_FULL;
            break;
        default:
            ret_val = e1000_read_eeprom(hw, EEPROM_INIT_CONTROL2_REG,
                                        1, &eeprom_data);
            if (ret_val) {
                DEBUGOUT("EEPROM Read Error\n");
                return -E1000_ERR_EEPROM;
            }
            if ((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) == 0)
                hw->fc = E1000_FC_NONE;
            else if ((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) ==
                    EEPROM_WORD0F_ASM_DIR)
                hw->fc = E1000_FC_TX_PAUSE;
            else
                hw->fc = E1000_FC_FULL;
            break;
        }
    }

    /* We want to save off the original Flow Control configuration just
     * in case we get disconnected and then reconnected into a different
     * hub or switch with different Flow Control capabilities.
     */
    if (hw->mac_type == e1000_82542_rev2_0)
        hw->fc &= (~E1000_FC_TX_PAUSE);

    if ((hw->mac_type < e1000_82543) && (hw->report_tx_early == 1))
        hw->fc &= (~E1000_FC_RX_PAUSE);

    hw->original_fc = hw->fc;

    DEBUGOUT1("After fix-ups FlowControl is now = %x\n", hw->fc);

    /* Take the 4 bits from EEPROM word 0x0F that determine the initial
     * polarity value for the SW controlled pins, and setup the
     * Extended Device Control reg with that info.
     * This is needed because one of the SW controlled pins is used for
     * signal detection.  So this should be done before e1000_setup_pcs_link()
     * or e1000_phy_setup() is called.
     */
    if (hw->mac_type == e1000_82543) {
        ret_val = e1000_read_eeprom(hw, EEPROM_INIT_CONTROL2_REG,
                                    1, &eeprom_data);
        if (ret_val) {
            DEBUGOUT("EEPROM Read Error\n");
            return -E1000_ERR_EEPROM;
        }
        ctrl_ext = ((eeprom_data & EEPROM_WORD0F_SWPDIO_EXT) <<
                    SWDPIO__EXT_SHIFT);
        E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
    }

    /* Call the necessary subroutine to configure the link. */
    ret_val = (hw->media_type == e1000_media_type_copper) ?
              e1000_setup_copper_link(hw) :
              e1000_setup_fiber_serdes_link(hw);

    /* Initialize the flow control address, type, and PAUSE timer
     * registers to their default values.  This is done even if flow
     * control is disabled, because it does not hurt anything to
     * initialize these registers.
     */
    DEBUGOUT("Initializing the Flow Control address, type and timer regs\n");

    /* FCAL/H and FCT are hardcoded to standard values in e1000_ich8lan. */
    if (hw->mac_type != e1000_ich8lan) {
        E1000_WRITE_REG(hw, FCT, FLOW_CONTROL_TYPE);
        E1000_WRITE_REG(hw, FCAH, FLOW_CONTROL_ADDRESS_HIGH);
        E1000_WRITE_REG(hw, FCAL, FLOW_CONTROL_ADDRESS_LOW);
    }

    E1000_WRITE_REG(hw, FCTTV, hw->fc_pause_time);

    /* Set the flow control receive threshold registers.  Normally,
     * these registers will be set to a default threshold that may be
     * adjusted later by the driver's runtime code.  However, if the
     * ability to transmit pause frames in not enabled, then these
     * registers will be set to 0.
     */
    if (!(hw->fc & E1000_FC_TX_PAUSE)) {
        E1000_WRITE_REG(hw, FCRTL, 0);
        E1000_WRITE_REG(hw, FCRTH, 0);
    } else {
        /* We need to set up the Receive Threshold high and low water marks
         * as well as (optionally) enabling the transmission of XON frames.
         */
        if (hw->fc_send_xon) {
            E1000_WRITE_REG(hw, FCRTL, (hw->fc_low_water | E1000_FCRTL_XONE));
            E1000_WRITE_REG(hw, FCRTH, hw->fc_high_water);
        } else {
            E1000_WRITE_REG(hw, FCRTL, hw->fc_low_water);
            E1000_WRITE_REG(hw, FCRTH, hw->fc_high_water);
        }
    }
    return ret_val;
}

/******************************************************************************
 * Sets up link for a fiber based or serdes based adapter
 *
 * hw - Struct containing variables accessed by shared code
 *
 * Manipulates Physical Coding Sublayer functions in order to configure
 * link. Assumes the hardware has been previously reset and the transmitter
 * and receiver are not enabled.
 *****************************************************************************/
static s32
e1000_setup_fiber_serdes_link(struct e1000_hw *hw)
{
    u32 ctrl;
    u32 status;
    u32 txcw = 0;
    u32 i;
    u32 signal = 0;
    s32 ret_val;

    DEBUGFUNC("e1000_setup_fiber_serdes_link");

    /* On 82571 and 82572 Fiber connections, SerDes loopback mode persists
     * until explicitly turned off or a power cycle is performed.  A read to
     * the register does not indicate its status.  Therefore, we ensure
     * loopback mode is disabled during initialization.
     */
    if (hw->mac_type == e1000_82571 || hw->mac_type == e1000_82572)
        E1000_WRITE_REG(hw, SCTL, E1000_DISABLE_SERDES_LOOPBACK);

    /* On adapters with a MAC newer than 82544, SWDP 1 will be
     * set when the optics detect a signal. On older adapters, it will be
     * cleared when there is a signal.  This applies to fiber media only.
     * If we're on serdes media, adjust the output amplitude to value
     * set in the EEPROM.
     */
    ctrl = E1000_READ_REG(hw, CTRL);
    if (hw->media_type == e1000_media_type_fiber)
        signal = (hw->mac_type > e1000_82544) ? E1000_CTRL_SWDPIN1 : 0;

    ret_val = e1000_adjust_serdes_amplitude(hw);
    if (ret_val)
        return ret_val;

    /* Take the link out of reset */
    ctrl &= ~(E1000_CTRL_LRST);

    /* Adjust VCO speed to improve BER performance */
    ret_val = e1000_set_vco_speed(hw);
    if (ret_val)
        return ret_val;

    e1000_config_collision_dist(hw);

    /* Check for a software override of the flow control settings, and setup
     * the device accordingly.  If auto-negotiation is enabled, then software
     * will have to set the "PAUSE" bits to the correct value in the Tranmsit
     * Config Word Register (TXCW) and re-start auto-negotiation.  However, if
     * auto-negotiation is disabled, then software will have to manually
     * configure the two flow control enable bits in the CTRL register.
     *
     * The possible values of the "fc" parameter are:
     *      0:  Flow control is completely disabled
     *      1:  Rx flow control is enabled (we can receive pause frames, but
     *          not send pause frames).
     *      2:  Tx flow control is enabled (we can send pause frames but we do
     *          not support receiving pause frames).
     *      3:  Both Rx and TX flow control (symmetric) are enabled.
     */
    switch (hw->fc) {
    case E1000_FC_NONE:
        /* Flow control is completely disabled by a software over-ride. */
        txcw = (E1000_TXCW_ANE | E1000_TXCW_FD);
        break;
    case E1000_FC_RX_PAUSE:
        /* RX Flow control is enabled and TX Flow control is disabled by a
         * software over-ride. Since there really isn't a way to advertise
         * that we are capable of RX Pause ONLY, we will advertise that we
         * support both symmetric and asymmetric RX PAUSE. Later, we will
         *  disable the adapter's ability to send PAUSE frames.
         */
        txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK);
        break;
    case E1000_FC_TX_PAUSE:
        /* TX Flow control is enabled, and RX Flow control is disabled, by a
         * software over-ride.
         */
        txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_ASM_DIR);
        break;
    case E1000_FC_FULL:
        /* Flow control (both RX and TX) is enabled by a software over-ride. */
        txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK);
        break;
    default:
        DEBUGOUT("Flow control param set incorrectly\n");
        return -E1000_ERR_CONFIG;
        break;
    }

    /* Since auto-negotiation is enabled, take the link out of reset (the link
     * will be in reset, because we previously reset the chip). This will
     * restart auto-negotiation.  If auto-neogtiation is successful then the
     * link-up status bit will be set and the flow control enable bits (RFCE
     * and TFCE) will be set according to their negotiated value.
     */
    DEBUGOUT("Auto-negotiation enabled\n");

    E1000_WRITE_REG(hw, TXCW, txcw);
    E1000_WRITE_REG(hw, CTRL, ctrl);
    E1000_WRITE_FLUSH(hw);

    hw->txcw = txcw;
    msleep(1);

    /* If we have a signal (the cable is plugged in) then poll for a "Link-Up"
     * indication in the Device Status Register.  Time-out if a link isn't
     * seen in 500 milliseconds seconds (Auto-negotiation should complete in
     * less than 500 milliseconds even if the other end is doing it in SW).
     * For internal serdes, we just assume a signal is present, then poll.
     */
    if (hw->media_type == e1000_media_type_internal_serdes ||
       (E1000_READ_REG(hw, CTRL) & E1000_CTRL_SWDPIN1) == signal) {
        DEBUGOUT("Looking for Link\n");
        for (i = 0; i < (LINK_UP_TIMEOUT / 10); i++) {
            msleep(10);
            status = E1000_READ_REG(hw, STATUS);
            if (status & E1000_STATUS_LU) break;
        }
        if (i == (LINK_UP_TIMEOUT / 10)) {
            DEBUGOUT("Never got a valid link from auto-neg!!!\n");
            hw->autoneg_failed = 1;
            /* AutoNeg failed to achieve a link, so we'll call
             * e1000_check_for_link. This routine will force the link up if
             * we detect a signal. This will allow us to communicate with
             * non-autonegotiating link partners.
             */
            ret_val = e1000_check_for_link(hw);
            if (ret_val) {
                DEBUGOUT("Error while checking for link\n");
                return ret_val;
            }
            hw->autoneg_failed = 0;
        } else {
            hw->autoneg_failed = 0;
            DEBUGOUT("Valid Link Found\n");
        }
    } else {
        DEBUGOUT("No Signal Detected\n");
    }
    return E1000_SUCCESS;
}

/******************************************************************************
* Make sure we have a valid PHY and change PHY mode before link setup.
*
* hw - Struct containing variables accessed by shared code
******************************************************************************/
static s32
e1000_copper_link_preconfig(struct e1000_hw *hw)
{
    u32 ctrl;
    s32 ret_val;
    u16 phy_data;

    DEBUGFUNC("e1000_copper_link_preconfig");

    ctrl = E1000_READ_REG(hw, CTRL);
    /* With 82543, we need to force speed and duplex on the MAC equal to what
     * the PHY speed and duplex configuration is. In addition, we need to
     * perform a hardware reset on the PHY to take it out of reset.
     */
    if (hw->mac_type > e1000_82543) {
        ctrl |= E1000_CTRL_SLU;
        ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
        E1000_WRITE_REG(hw, CTRL, ctrl);
    } else {
        ctrl |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX | E1000_CTRL_SLU);
        E1000_WRITE_REG(hw, CTRL, ctrl);
        ret_val = e1000_phy_hw_reset(hw);
        if (ret_val)
            return ret_val;
    }

    /* Make sure we have a valid PHY */
    ret_val = e1000_detect_gig_phy(hw);
    if (ret_val) {
        DEBUGOUT("Error, did not detect valid phy.\n");
        return ret_val;
    }
    DEBUGOUT1("Phy ID = %x \n", hw->phy_id);

    /* Set PHY to class A mode (if necessary) */
    ret_val = e1000_set_phy_mode(hw);
    if (ret_val)
        return ret_val;

    if ((hw->mac_type == e1000_82545_rev_3) ||
       (hw->mac_type == e1000_82546_rev_3)) {
        ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
        phy_data |= 0x00000008;
        ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
    }

    if (hw->mac_type <= e1000_82543 ||
        hw->mac_type == e1000_82541 || hw->mac_type == e1000_82547 ||
        hw->mac_type == e1000_82541_rev_2 || hw->mac_type == e1000_82547_rev_2)
        hw->phy_reset_disable = false;

   return E1000_SUCCESS;
}


/********************************************************************
* Copper link setup for e1000_phy_igp series.
*
* hw - Struct containing variables accessed by shared code
*********************************************************************/
static s32
e1000_copper_link_igp_setup(struct e1000_hw *hw)
{
    u32 led_ctrl;
    s32 ret_val;
    u16 phy_data;

    DEBUGFUNC("e1000_copper_link_igp_setup");

    if (hw->phy_reset_disable)
        return E1000_SUCCESS;

    ret_val = e1000_phy_reset(hw);
    if (ret_val) {
        DEBUGOUT("Error Resetting the PHY\n");
        return ret_val;
    }

    /* Wait 15ms for MAC to configure PHY from eeprom settings */
    msleep(15);
    if (hw->mac_type != e1000_ich8lan) {
    /* Configure activity LED after PHY reset */
    led_ctrl = E1000_READ_REG(hw, LEDCTL);
    led_ctrl &= IGP_ACTIVITY_LED_MASK;
    led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE);
    E1000_WRITE_REG(hw, LEDCTL, led_ctrl);
    }

    /* The NVM settings will configure LPLU in D3 for IGP2 and IGP3 PHYs */
    if (hw->phy_type == e1000_phy_igp) {
        /* disable lplu d3 during driver init */
        ret_val = e1000_set_d3_lplu_state(hw, false);
        if (ret_val) {
            DEBUGOUT("Error Disabling LPLU D3\n");
            return ret_val;
        }
    }

    /* disable lplu d0 during driver init */
    ret_val = e1000_set_d0_lplu_state(hw, false);
    if (ret_val) {
        DEBUGOUT("Error Disabling LPLU D0\n");
        return ret_val;
    }
    /* Configure mdi-mdix settings */
    ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, &phy_data);
    if (ret_val)
        return ret_val;

    if ((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
        hw->dsp_config_state = e1000_dsp_config_disabled;
        /* Force MDI for earlier revs of the IGP PHY */
        phy_data &= ~(IGP01E1000_PSCR_AUTO_MDIX | IGP01E1000_PSCR_FORCE_MDI_MDIX);
        hw->mdix = 1;

    } else {
        hw->dsp_config_state = e1000_dsp_config_enabled;
        phy_data &= ~IGP01E1000_PSCR_AUTO_MDIX;

        switch (hw->mdix) {
        case 1:
            phy_data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX;
            break;
        case 2:
            phy_data |= IGP01E1000_PSCR_FORCE_MDI_MDIX;
            break;
        case 0:
        default:
            phy_data |= IGP01E1000_PSCR_AUTO_MDIX;
            break;
        }
    }
    ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, phy_data);
    if (ret_val)
        return ret_val;

    /* set auto-master slave resolution settings */
    if (hw->autoneg) {
        e1000_ms_type phy_ms_setting = hw->master_slave;

        if (hw->ffe_config_state == e1000_ffe_config_active)
            hw->ffe_config_state = e1000_ffe_config_enabled;

        if (hw->dsp_config_state == e1000_dsp_config_activated)
            hw->dsp_config_state = e1000_dsp_config_enabled;

        /* when autonegotiation advertisment is only 1000Mbps then we
          * should disable SmartSpeed and enable Auto MasterSlave
          * resolution as hardware default. */
        if (hw->autoneg_advertised == ADVERTISE_1000_FULL) {
            /* Disable SmartSpeed */
            ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
                                         &phy_data);
            if (ret_val)
                return ret_val;
            phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
            ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
                                          phy_data);
            if (ret_val)
                return ret_val;
            /* Set auto Master/Slave resolution process */
            ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_data);
            if (ret_val)
                return ret_val;
            phy_data &= ~CR_1000T_MS_ENABLE;
            ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL, phy_data);
            if (ret_val)
                return ret_val;
        }

        ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_data);
        if (ret_val)
            return ret_val;

        /* load defaults for future use */
        hw->original_master_slave = (phy_data & CR_1000T_MS_ENABLE) ?
                                        ((phy_data & CR_1000T_MS_VALUE) ?
                                         e1000_ms_force_master :
                                         e1000_ms_force_slave) :
                                         e1000_ms_auto;

        switch (phy_ms_setting) {
        case e1000_ms_force_master:
            phy_data |= (CR_1000T_MS_ENABLE | CR_1000T_MS_VALUE);
            break;
        case e1000_ms_force_slave:
            phy_data |= CR_1000T_MS_ENABLE;
            phy_data &= ~(CR_1000T_MS_VALUE);
            break;
        case e1000_ms_auto:
            phy_data &= ~CR_1000T_MS_ENABLE;
            default:
            break;
        }
        ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL, phy_data);
        if (ret_val)
            return ret_val;
    }

    return E1000_SUCCESS;
}

/********************************************************************
* Copper link setup for e1000_phy_gg82563 series.
*
* hw - Struct containing variables accessed by shared code
*********************************************************************/
static s32
e1000_copper_link_ggp_setup(struct e1000_hw *hw)
{
    s32 ret_val;
    u16 phy_data;
    u32 reg_data;

    DEBUGFUNC("e1000_copper_link_ggp_setup");

    if (!hw->phy_reset_disable) {

        /* Enable CRS on TX for half-duplex operation. */
        ret_val = e1000_read_phy_reg(hw, GG82563_PHY_MAC_SPEC_CTRL,
                                     &phy_data);
        if (ret_val)
            return ret_val;

        phy_data |= GG82563_MSCR_ASSERT_CRS_ON_TX;
        /* Use 25MHz for both link down and 1000BASE-T for Tx clock */
        phy_data |= GG82563_MSCR_TX_CLK_1000MBPS_25MHZ;

        ret_val = e1000_write_phy_reg(hw, GG82563_PHY_MAC_SPEC_CTRL,
                                      phy_data);
        if (ret_val)
            return ret_val;

        /* Options:
         *   MDI/MDI-X = 0 (default)
         *   0 - Auto for all speeds
         *   1 - MDI mode
         *   2 - MDI-X mode
         *   3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes)
         */
        ret_val = e1000_read_phy_reg(hw, GG82563_PHY_SPEC_CTRL, &phy_data);
        if (ret_val)
            return ret_val;

        phy_data &= ~GG82563_PSCR_CROSSOVER_MODE_MASK;

        switch (hw->mdix) {
        case 1:
            phy_data |= GG82563_PSCR_CROSSOVER_MODE_MDI;
            break;
        case 2:
            phy_data |= GG82563_PSCR_CROSSOVER_MODE_MDIX;
            break;
        case 0:
        default:
            phy_data |= GG82563_PSCR_CROSSOVER_MODE_AUTO;
            break;
        }

        /* Options:
         *   disable_polarity_correction = 0 (default)
         *       Automatic Correction for Reversed Cable Polarity
         *   0 - Disabled
         *   1 - Enabled
         */
        phy_data &= ~GG82563_PSCR_POLARITY_REVERSAL_DISABLE;
        if (hw->disable_polarity_correction == 1)
            phy_data |= GG82563_PSCR_POLARITY_REVERSAL_DISABLE;
        ret_val = e1000_write_phy_reg(hw, GG82563_PHY_SPEC_CTRL, phy_data);

        if (ret_val)
            return ret_val;

        /* SW Reset the PHY so all changes take effect */
        ret_val = e1000_phy_reset(hw);
        if (ret_val) {
            DEBUGOUT("Error Resetting the PHY\n");
            return ret_val;
        }
    } /* phy_reset_disable */

    if (hw->mac_type == e1000_80003es2lan) {
        /* Bypass RX and TX FIFO's */
        ret_val = e1000_write_kmrn_reg(hw, E1000_KUMCTRLSTA_OFFSET_FIFO_CTRL,
                                       E1000_KUMCTRLSTA_FIFO_CTRL_RX_BYPASS |
                                       E1000_KUMCTRLSTA_FIFO_CTRL_TX_BYPASS);
        if (ret_val)
            return ret_val;

        ret_val = e1000_read_phy_reg(hw, GG82563_PHY_SPEC_CTRL_2, &phy_data);
        if (ret_val)
            return ret_val;

        phy_data &= ~GG82563_PSCR2_REVERSE_AUTO_NEG;
        ret_val = e1000_write_phy_reg(hw, GG82563_PHY_SPEC_CTRL_2, phy_data);

        if (ret_val)
            return ret_val;

        reg_data = E1000_READ_REG(hw, CTRL_EXT);
        reg_data &= ~(E1000_CTRL_EXT_LINK_MODE_MASK);
        E1000_WRITE_REG(hw, CTRL_EXT, reg_data);

        ret_val = e1000_read_phy_reg(hw, GG82563_PHY_PWR_MGMT_CTRL,
                                          &phy_data);
        if (ret_val)
            return ret_val;

        /* Do not init these registers when the HW is in IAMT mode, since the
         * firmware will have already initialized them.  We only initialize
         * them if the HW is not in IAMT mode.
         */
        if (!e1000_check_mng_mode(hw)) {
            /* Enable Electrical Idle on the PHY */
            phy_data |= GG82563_PMCR_ENABLE_ELECTRICAL_IDLE;
            ret_val = e1000_write_phy_reg(hw, GG82563_PHY_PWR_MGMT_CTRL,
                                          phy_data);
            if (ret_val)
                return ret_val;

            ret_val = e1000_read_phy_reg(hw, GG82563_PHY_KMRN_MODE_CTRL,
                                         &phy_data);
            if (ret_val)
                return ret_val;

            phy_data &= ~GG82563_KMCR_PASS_FALSE_CARRIER;
            ret_val = e1000_write_phy_reg(hw, GG82563_PHY_KMRN_MODE_CTRL,
                                          phy_data);

            if (ret_val)
                return ret_val;
        }

        /* Workaround: Disable padding in Kumeran interface in the MAC
         * and in the PHY to avoid CRC errors.
         */
        ret_val = e1000_read_phy_reg(hw, GG82563_PHY_INBAND_CTRL,
                                     &phy_data);
        if (ret_val)
            return ret_val;
        phy_data |= GG82563_ICR_DIS_PADDING;
        ret_val = e1000_write_phy_reg(hw, GG82563_PHY_INBAND_CTRL,
                                      phy_data);
        if (ret_val)
            return ret_val;
    }

    return E1000_SUCCESS;
}

/********************************************************************
* Copper link setup for e1000_phy_m88 series.
*
* hw - Struct containing variables accessed by shared code
*********************************************************************/
static s32
e1000_copper_link_mgp_setup(struct e1000_hw *hw)
{
    s32 ret_val;
    u16 phy_data;

    DEBUGFUNC("e1000_copper_link_mgp_setup");

    if (hw->phy_reset_disable)
        return E1000_SUCCESS;

    /* Enable CRS on TX. This must be set for half-duplex operation. */
    ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
    if (ret_val)
        return ret_val;

    phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;

    /* Options:
     *   MDI/MDI-X = 0 (default)
     *   0 - Auto for all speeds
     *   1 - MDI mode
     *   2 - MDI-X mode
     *   3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes)
     */
    phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;

    switch (hw->mdix) {
    case 1:
        phy_data |= M88E1000_PSCR_MDI_MANUAL_MODE;
        break;
    case 2:
        phy_data |= M88E1000_PSCR_MDIX_MANUAL_MODE;
        break;
    case 3:
        phy_data |= M88E1000_PSCR_AUTO_X_1000T;
        break;
    case 0:
    default:
        phy_data |= M88E1000_PSCR_AUTO_X_MODE;
        break;
    }

    /* Options:
     *   disable_polarity_correction = 0 (default)
     *       Automatic Correction for Reversed Cable Polarity
     *   0 - Disabled
     *   1 - Enabled
     */
    phy_data &= ~M88E1000_PSCR_POLARITY_REVERSAL;
    if (hw->disable_polarity_correction == 1)
        phy_data |= M88E1000_PSCR_POLARITY_REVERSAL;
    ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
    if (ret_val)
        return ret_val;

    if (hw->phy_revision < M88E1011_I_REV_4) {
        /* Force TX_CLK in the Extended PHY Specific Control Register
         * to 25MHz clock.
         */
        ret_val = e1000_read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data);
        if (ret_val)
            return ret_val;

        phy_data |= M88E1000_EPSCR_TX_CLK_25;

        if ((hw->phy_revision == E1000_REVISION_2) &&
            (hw->phy_id == M88E1111_I_PHY_ID)) {
            /* Vidalia Phy, set the downshift counter to 5x */
            phy_data &= ~(M88EC018_EPSCR_DOWNSHIFT_COUNTER_MASK);
            phy_data |= M88EC018_EPSCR_DOWNSHIFT_COUNTER_5X;
            ret_val = e1000_write_phy_reg(hw,
                                        M88E1000_EXT_PHY_SPEC_CTRL, phy_data);
            if (ret_val)
                return ret_val;
        } else {
            /* Configure Master and Slave downshift values */
            phy_data &= ~(M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK |
                              M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK);
            phy_data |= (M88E1000_EPSCR_MASTER_DOWNSHIFT_1X |
                             M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X);
            ret_val = e1000_write_phy_reg(hw,
                                        M88E1000_EXT_PHY_SPEC_CTRL, phy_data);
            if (ret_val)
               return ret_val;
        }
    }

    /* SW Reset the PHY so all changes take effect */
    ret_val = e1000_phy_reset(hw);
    if (ret_val) {
        DEBUGOUT("Error Resetting the PHY\n");
        return ret_val;
    }

   return E1000_SUCCESS;
}

/********************************************************************
* Setup auto-negotiation and flow control advertisements,
* and then perform auto-negotiation.
*
* hw - Struct containing variables accessed by shared code
*********************************************************************/
static s32
e1000_copper_link_autoneg(struct e1000_hw *hw)
{
    s32 ret_val;
    u16 phy_data;

    DEBUGFUNC("e1000_copper_link_autoneg");

    /* Perform some bounds checking on the hw->autoneg_advertised
     * parameter.  If this variable is zero, then set it to the default.
     */
    hw->autoneg_advertised &= AUTONEG_ADVERTISE_SPEED_DEFAULT;

    /* If autoneg_advertised is zero, we assume it was not defaulted
     * by the calling code so we set to advertise full capability.
     */
    if (hw->autoneg_advertised == 0)
        hw->autoneg_advertised = AUTONEG_ADVERTISE_SPEED_DEFAULT;

    /* IFE phy only supports 10/100 */
    if (hw->phy_type == e1000_phy_ife)
        hw->autoneg_advertised &= AUTONEG_ADVERTISE_10_100_ALL;

    DEBUGOUT("Reconfiguring auto-neg advertisement params\n");
    ret_val = e1000_phy_setup_autoneg(hw);
    if (ret_val) {
        DEBUGOUT("Error Setting up Auto-Negotiation\n");
        return ret_val;
    }
    DEBUGOUT("Restarting Auto-Neg\n");

    /* Restart auto-negotiation by setting the Auto Neg Enable bit and
     * the Auto Neg Restart bit in the PHY control register.
     */
    ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &phy_data);
    if (ret_val)
        return ret_val;

    phy_data |= (MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG);
    ret_val = e1000_write_phy_reg(hw, PHY_CTRL, phy_data);
    if (ret_val)
        return ret_val;

    /* Does the user want to wait for Auto-Neg to complete here, or
     * check at a later time (for example, callback routine).
     */
    if (hw->wait_autoneg_complete) {
        ret_val = e1000_wait_autoneg(hw);
        if (ret_val) {
            DEBUGOUT("Error while waiting for autoneg to complete\n");
            return ret_val;
        }
    }

    hw->get_link_status = true;

    return E1000_SUCCESS;
}

/******************************************************************************
* Config the MAC and the PHY after link is up.
*   1) Set up the MAC to the current PHY speed/duplex
*      if we are on 82543.  If we
*      are on newer silicon, we only need to configure
*      collision distance in the Transmit Control Register.
*   2) Set up flow control on the MAC to that established with
*      the link partner.
*   3) Config DSP to improve Gigabit link quality for some PHY revisions.
*
* hw - Struct containing variables accessed by shared code
******************************************************************************/
static s32
e1000_copper_link_postconfig(struct e1000_hw *hw)
{
    s32 ret_val;
    DEBUGFUNC("e1000_copper_link_postconfig");

    if (hw->mac_type >= e1000_82544) {
        e1000_config_collision_dist(hw);
    } else {
        ret_val = e1000_config_mac_to_phy(hw);
        if (ret_val) {
            DEBUGOUT("Error configuring MAC to PHY settings\n");
            return ret_val;
        }
    }
    ret_val = e1000_config_fc_after_link_up(hw);
    if (ret_val) {
        DEBUGOUT("Error Configuring Flow Control\n");
        return ret_val;
    }

    /* Config DSP to improve Giga link quality */
    if (hw->phy_type == e1000_phy_igp) {
        ret_val = e1000_config_dsp_after_link_change(hw, true);
        if (ret_val) {
            DEBUGOUT("Error Configuring DSP after link up\n");
            return ret_val;
        }
    }

    return E1000_SUCCESS;
}

/******************************************************************************
* Detects which PHY is present and setup the speed and duplex
*
* hw - Struct containing variables accessed by shared code
******************************************************************************/
static s32
e1000_setup_copper_link(struct e1000_hw *hw)
{
    s32 ret_val;
    u16 i;
    u16 phy_data;
    u16 reg_data;

    DEBUGFUNC("e1000_setup_copper_link");

    switch (hw->mac_type) {
    case e1000_80003es2lan:
    case e1000_ich8lan:
        /* Set the mac to wait the maximum time between each
         * iteration and increase the max iterations when
         * polling the phy; this fixes erroneous timeouts at 10Mbps. */
        ret_val = e1000_write_kmrn_reg(hw, GG82563_REG(0x34, 4), 0xFFFF);
        if (ret_val)
            return ret_val;
        ret_val = e1000_read_kmrn_reg(hw, GG82563_REG(0x34, 9), &reg_data);
        if (ret_val)
            return ret_val;
        reg_data |= 0x3F;
        ret_val = e1000_write_kmrn_reg(hw, GG82563_REG(0x34, 9), reg_data);
        if (ret_val)
            return ret_val;
    default:
        break;
    }

    /* Check if it is a valid PHY and set PHY mode if necessary. */
    ret_val = e1000_copper_link_preconfig(hw);
    if (ret_val)
        return ret_val;

    switch (hw->mac_type) {
    case e1000_80003es2lan:
        /* Kumeran registers are written-only */
        reg_data = E1000_KUMCTRLSTA_INB_CTRL_LINK_STATUS_TX_TIMEOUT_DEFAULT;
        reg_data |= E1000_KUMCTRLSTA_INB_CTRL_DIS_PADDING;
        ret_val = e1000_write_kmrn_reg(hw, E1000_KUMCTRLSTA_OFFSET_INB_CTRL,
                                       reg_data);
        if (ret_val)
            return ret_val;
        break;
    default:
        break;
    }

    if (hw->phy_type == e1000_phy_igp ||
        hw->phy_type == e1000_phy_igp_3 ||
        hw->phy_type == e1000_phy_igp_2) {
        ret_val = e1000_copper_link_igp_setup(hw);
        if (ret_val)
            return ret_val;
    } else if (hw->phy_type == e1000_phy_m88) {
        ret_val = e1000_copper_link_mgp_setup(hw);
        if (ret_val)
            return ret_val;
    } else if (hw->phy_type == e1000_phy_gg82563) {
        ret_val = e1000_copper_link_ggp_setup(hw);
        if (ret_val)
            return ret_val;
    }

    if (hw->autoneg) {
        /* Setup autoneg and flow control advertisement
          * and perform autonegotiation */
        ret_val = e1000_copper_link_autoneg(hw);
        if (ret_val)
            return ret_val;
    } else {
        /* PHY will be set to 10H, 10F, 100H,or 100F
          * depending on value from forced_speed_duplex. */
        DEBUGOUT("Forcing speed and duplex\n");
        ret_val = e1000_phy_force_speed_duplex(hw);
        if (ret_val) {
            DEBUGOUT("Error Forcing Speed and Duplex\n");
            return ret_val;
        }
    }

    /* Check link status. Wait up to 100 microseconds for link to become
     * valid.
     */
    for (i = 0; i < 10; i++) {
        ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
        if (ret_val)
            return ret_val;
        ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
        if (ret_val)
            return ret_val;

        if (phy_data & MII_SR_LINK_STATUS) {
            /* Config the MAC and PHY after link is up */
            ret_val = e1000_copper_link_postconfig(hw);
            if (ret_val)
                return ret_val;

            DEBUGOUT("Valid link established!!!\n");
            return E1000_SUCCESS;
        }
        udelay(10);
    }

    DEBUGOUT("Unable to establish link!!!\n");
    return E1000_SUCCESS;
}

/******************************************************************************
* Configure the MAC-to-PHY interface for 10/100Mbps
*
* hw - Struct containing variables accessed by shared code
******************************************************************************/
static s32
e1000_configure_kmrn_for_10_100(struct e1000_hw *hw, u16 duplex)
{
    s32 ret_val = E1000_SUCCESS;
    u32 tipg;
    u16 reg_data;

    DEBUGFUNC("e1000_configure_kmrn_for_10_100");

    reg_data = E1000_KUMCTRLSTA_HD_CTRL_10_100_DEFAULT;
    ret_val = e1000_write_kmrn_reg(hw, E1000_KUMCTRLSTA_OFFSET_HD_CTRL,
                                   reg_data);
    if (ret_val)
        return ret_val;

    /* Configure Transmit Inter-Packet Gap */
    tipg = E1000_READ_REG(hw, TIPG);
    tipg &= ~E1000_TIPG_IPGT_MASK;
    tipg |= DEFAULT_80003ES2LAN_TIPG_IPGT_10_100;
    E1000_WRITE_REG(hw, TIPG, tipg);

    ret_val = e1000_read_phy_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, &reg_data);

    if (ret_val)
        return ret_val;

    if (duplex == HALF_DUPLEX)
        reg_data |= GG82563_KMCR_PASS_FALSE_CARRIER;
    else
        reg_data &= ~GG82563_KMCR_PASS_FALSE_CARRIER;

    ret_val = e1000_write_phy_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, reg_data);

    return ret_val;
}

static s32
e1000_configure_kmrn_for_1000(struct e1000_hw *hw)
{
    s32 ret_val = E1000_SUCCESS;
    u16 reg_data;
    u32 tipg;

    DEBUGFUNC("e1000_configure_kmrn_for_1000");

    reg_data = E1000_KUMCTRLSTA_HD_CTRL_1000_DEFAULT;
    ret_val = e1000_write_kmrn_reg(hw, E1000_KUMCTRLSTA_OFFSET_HD_CTRL,
                                   reg_data);
    if (ret_val)
        return ret_val;

    /* Configure Transmit Inter-Packet Gap */
    tipg = E1000_READ_REG(hw, TIPG);
    tipg &= ~E1000_TIPG_IPGT_MASK;
    tipg |= DEFAULT_80003ES2LAN_TIPG_IPGT_1000;
    E1000_WRITE_REG(hw, TIPG, tipg);

    ret_val = e1000_read_phy_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, &reg_data);

    if (ret_val)
        return ret_val;

    reg_data &= ~GG82563_KMCR_PASS_FALSE_CARRIER;
    ret_val = e1000_write_phy_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, reg_data);

    return ret_val;
}

/******************************************************************************
* Configures PHY autoneg and flow control advertisement settings
*
* hw - Struct containing variables accessed by shared code
******************************************************************************/
s32
e1000_phy_setup_autoneg(struct e1000_hw *hw)
{
    s32 ret_val;
    u16 mii_autoneg_adv_reg;
    u16 mii_1000t_ctrl_reg;

    DEBUGFUNC("e1000_phy_setup_autoneg");

    /* Read the MII Auto-Neg Advertisement Register (Address 4). */
    ret_val = e1000_read_phy_reg(hw, PHY_AUTONEG_ADV, &mii_autoneg_adv_reg);
    if (ret_val)
        return ret_val;

    if (hw->phy_type != e1000_phy_ife) {
        /* Read the MII 1000Base-T Control Register (Address 9). */
        ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL, &mii_1000t_ctrl_reg);
        if (ret_val)
            return ret_val;
    } else
        mii_1000t_ctrl_reg=0;

    /* Need to parse both autoneg_advertised and fc and set up
     * the appropriate PHY registers.  First we will parse for
     * autoneg_advertised software override.  Since we can advertise
     * a plethora of combinations, we need to check each bit
     * individually.
     */

    /* First we clear all the 10/100 mb speed bits in the Auto-Neg
     * Advertisement Register (Address 4) and the 1000 mb speed bits in
     * the  1000Base-T Control Register (Address 9).
     */
    mii_autoneg_adv_reg &= ~REG4_SPEED_MASK;
    mii_1000t_ctrl_reg &= ~REG9_SPEED_MASK;

    DEBUGOUT1("autoneg_advertised %x\n", hw->autoneg_advertised);

    /* Do we want to advertise 10 Mb Half Duplex? */
    if (hw->autoneg_advertised & ADVERTISE_10_HALF) {
        DEBUGOUT("Advertise 10mb Half duplex\n");
        mii_autoneg_adv_reg |= NWAY_AR_10T_HD_CAPS;
    }

    /* Do we want to advertise 10 Mb Full Duplex? */
    if (hw->autoneg_advertised & ADVERTISE_10_FULL) {
        DEBUGOUT("Advertise 10mb Full duplex\n");
        mii_autoneg_adv_reg |= NWAY_AR_10T_FD_CAPS;
    }

    /* Do we want to advertise 100 Mb Half Duplex? */
    if (hw->autoneg_advertised & ADVERTISE_100_HALF) {
        DEBUGOUT("Advertise 100mb Half duplex\n");
        mii_autoneg_adv_reg |= NWAY_AR_100TX_HD_CAPS;
    }

    /* Do we want to advertise 100 Mb Full Duplex? */
    if (hw->autoneg_advertised & ADVERTISE_100_FULL) {
        DEBUGOUT("Advertise 100mb Full duplex\n");
        mii_autoneg_adv_reg |= NWAY_AR_100TX_FD_CAPS;
    }

    /* We do not allow the Phy to advertise 1000 Mb Half Duplex */
    if (hw->autoneg_advertised & ADVERTISE_1000_HALF) {
        DEBUGOUT("Advertise 1000mb Half duplex requested, request denied!\n");
    }

    /* Do we want to advertise 1000 Mb Full Duplex? */
    if (hw->autoneg_advertised & ADVERTISE_1000_FULL) {
        DEBUGOUT("Advertise 1000mb Full duplex\n");
        mii_1000t_ctrl_reg |= CR_1000T_FD_CAPS;
        if (hw->phy_type == e1000_phy_ife) {
            DEBUGOUT("e1000_phy_ife is a 10/100 PHY. Gigabit speed is not supported.\n");
        }
    }

    /* Check for a software override of the flow control settings, and
     * setup the PHY advertisement registers accordingly.  If
     * auto-negotiation is enabled, then software will have to set the
     * "PAUSE" bits to the correct value in the Auto-Negotiation
     * Advertisement Register (PHY_AUTONEG_ADV) and re-start auto-negotiation.
     *
     * The possible values of the "fc" parameter are:
     *      0:  Flow control is completely disabled
     *      1:  Rx flow control is enabled (we can receive pause frames
     *          but not send pause frames).
     *      2:  Tx flow control is enabled (we can send pause frames
     *          but we do not support receiving pause frames).
     *      3:  Both Rx and TX flow control (symmetric) are enabled.
     *  other:  No software override.  The flow control configuration
     *          in the EEPROM is used.
     */
    switch (hw->fc) {
    case E1000_FC_NONE: /* 0 */
        /* Flow control (RX & TX) is completely disabled by a
         * software over-ride.
         */
        mii_autoneg_adv_reg &= ~(NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
        break;
    case E1000_FC_RX_PAUSE: /* 1 */
        /* RX Flow control is enabled, and TX Flow control is
         * disabled, by a software over-ride.
         */
        /* Since there really isn't a way to advertise that we are
         * capable of RX Pause ONLY, we will advertise that we
         * support both symmetric and asymmetric RX PAUSE.  Later
         * (in e1000_config_fc_after_link_up) we will disable the
         *hw's ability to send PAUSE frames.
         */
        mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
        break;
    case E1000_FC_TX_PAUSE: /* 2 */
        /* TX Flow control is enabled, and RX Flow control is
         * disabled, by a software over-ride.
         */
        mii_autoneg_adv_reg |= NWAY_AR_ASM_DIR;
        mii_autoneg_adv_reg &= ~NWAY_AR_PAUSE;
        break;
    case E1000_FC_FULL: /* 3 */
        /* Flow control (both RX and TX) is enabled by a software
         * over-ride.
         */
        mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
        break;
    default:
        DEBUGOUT("Flow control param set incorrectly\n");
        return -E1000_ERR_CONFIG;
    }

    ret_val = e1000_write_phy_reg(hw, PHY_AUTONEG_ADV, mii_autoneg_adv_reg);
    if (ret_val)
        return ret_val;

    DEBUGOUT1("Auto-Neg Advertising %x\n", mii_autoneg_adv_reg);

    if (hw->phy_type != e1000_phy_ife) {
        ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL, mii_1000t_ctrl_reg);
        if (ret_val)
            return ret_val;
    }

    return E1000_SUCCESS;
}

/******************************************************************************
* Force PHY speed and duplex settings to hw->forced_speed_duplex
*
* hw - Struct containing variables accessed by shared code
******************************************************************************/
static s32
e1000_phy_force_speed_duplex(struct e1000_hw *hw)
{
    u32 ctrl;
    s32 ret_val;
    u16 mii_ctrl_reg;
    u16 mii_status_reg;
    u16 phy_data;
    u16 i;

    DEBUGFUNC("e1000_phy_force_speed_duplex");

    /* Turn off Flow control if we are forcing speed and duplex. */
    hw->fc = E1000_FC_NONE;

    DEBUGOUT1("hw->fc = %d\n", hw->fc);

    /* Read the Device Control Register. */
    ctrl = E1000_READ_REG(hw, CTRL);

    /* Set the bits to Force Speed and Duplex in the Device Ctrl Reg. */
    ctrl |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
    ctrl &= ~(DEVICE_SPEED_MASK);

    /* Clear the Auto Speed Detect Enable bit. */
    ctrl &= ~E1000_CTRL_ASDE;

    /* Read the MII Control Register. */
    ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &mii_ctrl_reg);
    if (ret_val)
        return ret_val;

    /* We need to disable autoneg in order to force link and duplex. */

    mii_ctrl_reg &= ~MII_CR_AUTO_NEG_EN;

    /* Are we forcing Full or Half Duplex? */
    if (hw->forced_speed_duplex == e1000_100_full ||
        hw->forced_speed_duplex == e1000_10_full) {
        /* We want to force full duplex so we SET the full duplex bits in the
         * Device and MII Control Registers.
         */
        ctrl |= E1000_CTRL_FD;
        mii_ctrl_reg |= MII_CR_FULL_DUPLEX;
        DEBUGOUT("Full Duplex\n");
    } else {
        /* We want to force half duplex so we CLEAR the full duplex bits in
         * the Device and MII Control Registers.
         */
        ctrl &= ~E1000_CTRL_FD;
        mii_ctrl_reg &= ~MII_CR_FULL_DUPLEX;
        DEBUGOUT("Half Duplex\n");
    }

    /* Are we forcing 100Mbps??? */
    if (hw->forced_speed_duplex == e1000_100_full ||
       hw->forced_speed_duplex == e1000_100_half) {
        /* Set the 100Mb bit and turn off the 1000Mb and 10Mb bits. */
        ctrl |= E1000_CTRL_SPD_100;
        mii_ctrl_reg |= MII_CR_SPEED_100;
        mii_ctrl_reg &= ~(MII_CR_SPEED_1000 | MII_CR_SPEED_10);
        DEBUGOUT("Forcing 100mb ");
    } else {
        /* Set the 10Mb bit and turn off the 1000Mb and 100Mb bits. */
        ctrl &= ~(E1000_CTRL_SPD_1000 | E1000_CTRL_SPD_100);
        mii_ctrl_reg |= MII_CR_SPEED_10;
        mii_ctrl_reg &= ~(MII_CR_SPEED_1000 | MII_CR_SPEED_100);
        DEBUGOUT("Forcing 10mb ");
    }

    e1000_config_collision_dist(hw);

    /* Write the configured values back to the Device Control Reg. */
    E1000_WRITE_REG(hw, CTRL, ctrl);

    if ((hw->phy_type == e1000_phy_m88) ||
        (hw->phy_type == e1000_phy_gg82563)) {
        ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
        if (ret_val)
            return ret_val;

        /* Clear Auto-Crossover to force MDI manually. M88E1000 requires MDI
         * forced whenever speed are duplex are forced.
         */
        phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
        ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
        if (ret_val)
            return ret_val;

        DEBUGOUT1("M88E1000 PSCR: %x \n", phy_data);

        /* Need to reset the PHY or these changes will be ignored */
        mii_ctrl_reg |= MII_CR_RESET;

    /* Disable MDI-X support for 10/100 */
    } else if (hw->phy_type == e1000_phy_ife) {
        ret_val = e1000_read_phy_reg(hw, IFE_PHY_MDIX_CONTROL, &phy_data);
        if (ret_val)
            return ret_val;

        phy_data &= ~IFE_PMC_AUTO_MDIX;
        phy_data &= ~IFE_PMC_FORCE_MDIX;

        ret_val = e1000_write_phy_reg(hw, IFE_PHY_MDIX_CONTROL, phy_data);
        if (ret_val)
            return ret_val;

    } else {
        /* Clear Auto-Crossover to force MDI manually.  IGP requires MDI
         * forced whenever speed or duplex are forced.
         */
        ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, &phy_data);
        if (ret_val)
            return ret_val;

        phy_data &= ~IGP01E1000_PSCR_AUTO_MDIX;
        phy_data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX;

        ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, phy_data);
        if (ret_val)
            return ret_val;
    }

    /* Write back the modified PHY MII control register. */
    ret_val = e1000_write_phy_reg(hw, PHY_CTRL, mii_ctrl_reg);
    if (ret_val)
        return ret_val;

    udelay(1);

    /* The wait_autoneg_complete flag may be a little misleading here.
     * Since we are forcing speed and duplex, Auto-Neg is not enabled.
     * But we do want to delay for a period while forcing only so we
     * don't generate false No Link messages.  So we will wait here
     * only if the user has set wait_autoneg_complete to 1, which is
     * the default.
     */
    if (hw->wait_autoneg_complete) {
        /* We will wait for autoneg to complete. */
        DEBUGOUT("Waiting for forced speed/duplex link.\n");
        mii_status_reg = 0;

        /* We will wait for autoneg to complete or 4.5 seconds to expire. */
        for (i = PHY_FORCE_TIME; i > 0; i--) {
            /* Read the MII Status Register and wait for Auto-Neg Complete bit
             * to be set.
             */
            ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
            if (ret_val)
                return ret_val;

            ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
            if (ret_val)
                return ret_val;

            if (mii_status_reg & MII_SR_LINK_STATUS) break;
            msleep(100);
        }
        if ((i == 0) &&
           ((hw->phy_type == e1000_phy_m88) ||
            (hw->phy_type == e1000_phy_gg82563))) {
            /* We didn't get link.  Reset the DSP and wait again for link. */
            ret_val = e1000_phy_reset_dsp(hw);
            if (ret_val) {
                DEBUGOUT("Error Resetting PHY DSP\n");
                return ret_val;
            }
        }
        /* This loop will early-out if the link condition has been met.  */
        for (i = PHY_FORCE_TIME; i > 0; i--) {
            if (mii_status_reg & MII_SR_LINK_STATUS) break;
            msleep(100);
            /* Read the MII Status Register and wait for Auto-Neg Complete bit
             * to be set.
             */
            ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
            if (ret_val)
                return ret_val;

            ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
            if (ret_val)
                return ret_val;
        }
    }

    if (hw->phy_type == e1000_phy_m88) {
        /* Because we reset the PHY above, we need to re-force TX_CLK in the
         * Extended PHY Specific Control Register to 25MHz clock.  This value
         * defaults back to a 2.5MHz clock when the PHY is reset.
         */
        ret_val = e1000_read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data);
        if (ret_val)
            return ret_val;

        phy_data |= M88E1000_EPSCR_TX_CLK_25;
        ret_val = e1000_write_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, phy_data);
        if (ret_val)
            return ret_val;

        /* In addition, because of the s/w reset above, we need to enable CRS on
         * TX.  This must be set for both full and half duplex operation.
         */
        ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
        if (ret_val)
            return ret_val;

        phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
        ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
        if (ret_val)
            return ret_val;

        if ((hw->mac_type == e1000_82544 || hw->mac_type == e1000_82543) &&
            (!hw->autoneg) && (hw->forced_speed_duplex == e1000_10_full ||
             hw->forced_speed_duplex == e1000_10_half)) {
            ret_val = e1000_polarity_reversal_workaround(hw);
            if (ret_val)
                return ret_val;
        }
    } else if (hw->phy_type == e1000_phy_gg82563) {
        /* The TX_CLK of the Extended PHY Specific Control Register defaults
         * to 2.5MHz on a reset.  We need to re-force it back to 25MHz, if
         * we're not in a forced 10/duplex configuration. */
        ret_val = e1000_read_phy_reg(hw, GG82563_PHY_MAC_SPEC_CTRL, &phy_data);
        if (ret_val)
            return ret_val;

        phy_data &= ~GG82563_MSCR_TX_CLK_MASK;
        if ((hw->forced_speed_duplex == e1000_10_full) ||
            (hw->forced_speed_duplex == e1000_10_half))
            phy_data |= GG82563_MSCR_TX_CLK_10MBPS_2_5MHZ;
        else
            phy_data |= GG82563_MSCR_TX_CLK_100MBPS_25MHZ;

        /* Also due to the reset, we need to enable CRS on Tx. */
        phy_data |= GG82563_MSCR_ASSERT_CRS_ON_TX;

        ret_val = e1000_write_phy_reg(hw, GG82563_PHY_MAC_SPEC_CTRL, phy_data);
        if (ret_val)
            return ret_val;
    }
    return E1000_SUCCESS;
}

/******************************************************************************
* Sets the collision distance in the Transmit Control register
*
* hw - Struct containing variables accessed by shared code
*
* Link should have been established previously. Reads the speed and duplex
* information from the Device Status register.
******************************************************************************/
void
e1000_config_collision_dist(struct e1000_hw *hw)
{
    u32 tctl, coll_dist;

    DEBUGFUNC("e1000_config_collision_dist");

    if (hw->mac_type < e1000_82543)
        coll_dist = E1000_COLLISION_DISTANCE_82542;
    else
        coll_dist = E1000_COLLISION_DISTANCE;

    tctl = E1000_READ_REG(hw, TCTL);

    tctl &= ~E1000_TCTL_COLD;
    tctl |= coll_dist << E1000_COLD_SHIFT;

    E1000_WRITE_REG(hw, TCTL, tctl);
    E1000_WRITE_FLUSH(hw);
}

/******************************************************************************
* Sets MAC speed and duplex settings to reflect the those in the PHY
*
* hw - Struct containing variables accessed by shared code
* mii_reg - data to write to the MII control register
*
* The contents of the PHY register containing the needed information need to
* be passed in.
******************************************************************************/
static s32
e1000_config_mac_to_phy(struct e1000_hw *hw)
{
    u32 ctrl;
    s32 ret_val;
    u16 phy_data;

    DEBUGFUNC("e1000_config_mac_to_phy");

    /* 82544 or newer MAC, Auto Speed Detection takes care of
    * MAC speed/duplex configuration.*/
    if (hw->mac_type >= e1000_82544)
        return E1000_SUCCESS;

    /* Read the Device Control Register and set the bits to Force Speed
     * and Duplex.
     */
    ctrl = E1000_READ_REG(hw, CTRL);
    ctrl |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
    ctrl &= ~(E1000_CTRL_SPD_SEL | E1000_CTRL_ILOS);

    /* Set up duplex in the Device Control and Transmit Control
     * registers depending on negotiated values.
     */
    ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data);
    if (ret_val)
        return ret_val;

    if (phy_data & M88E1000_PSSR_DPLX)
        ctrl |= E1000_CTRL_FD;
    else
        ctrl &= ~E1000_CTRL_FD;

    e1000_config_collision_dist(hw);

    /* Set up speed in the Device Control register depending on
     * negotiated values.
     */
    if ((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS)
        ctrl |= E1000_CTRL_SPD_1000;
    else if ((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_100MBS)
        ctrl |= E1000_CTRL_SPD_100;

    /* Write the configured values back to the Device Control Reg. */
    E1000_WRITE_REG(hw, CTRL, ctrl);
    return E1000_SUCCESS;
}

/******************************************************************************
 * Forces the MAC's flow control settings.
 *
 * hw - Struct containing variables accessed by shared code
 *
 * Sets the TFCE and RFCE bits in the device control register to reflect
 * the adapter settings. TFCE and RFCE need to be explicitly set by
 * software when a Copper PHY is used because autonegotiation is managed
 * by the PHY rather than the MAC. Software must also configure these
 * bits when link is forced on a fiber connection.
 *****************************************************************************/
s32
e1000_force_mac_fc(struct e1000_hw *hw)
{
    u32 ctrl;

    DEBUGFUNC("e1000_force_mac_fc");

    /* Get the current configuration of the Device Control Register */
    ctrl = E1000_READ_REG(hw, CTRL);

    /* Because we didn't get link via the internal auto-negotiation
     * mechanism (we either forced link or we got link via PHY
     * auto-neg), we have to manually enable/disable transmit an
     * receive flow control.
     *
     * The "Case" statement below enables/disable flow control
     * according to the "hw->fc" parameter.
     *
     * The possible values of the "fc" parameter are:
     *      0:  Flow control is completely disabled
     *      1:  Rx flow control is enabled (we can receive pause
     *          frames but not send pause frames).
     *      2:  Tx flow control is enabled (we can send pause frames
     *          frames but we do not receive pause frames).
     *      3:  Both Rx and TX flow control (symmetric) is enabled.
     *  other:  No other values should be possible at this point.
     */

    switch (hw->fc) {
    case E1000_FC_NONE:
        ctrl &= (~(E1000_CTRL_TFCE | E1000_CTRL_RFCE));
        break;
    case E1000_FC_RX_PAUSE:
        ctrl &= (~E1000_CTRL_TFCE);
        ctrl |= E1000_CTRL_RFCE;
        break;
    case E1000_FC_TX_PAUSE:
        ctrl &= (~E1000_CTRL_RFCE);
        ctrl |= E1000_CTRL_TFCE;
        break;
    case E1000_FC_FULL:
        ctrl |= (E1000_CTRL_TFCE | E1000_CTRL_RFCE);
        break;
    default:
        DEBUGOUT("Flow control param set incorrectly\n");
        return -E1000_ERR_CONFIG;
    }

    /* Disable TX Flow Control for 82542 (rev 2.0) */
    if (hw->mac_type == e1000_82542_rev2_0)
        ctrl &= (~E1000_CTRL_TFCE);

    E1000_WRITE_REG(hw, CTRL, ctrl);
    return E1000_SUCCESS;
}

/******************************************************************************
 * Configures flow control settings after link is established
 *
 * hw - Struct containing variables accessed by shared code
 *
 * Should be called immediately after a valid link has been established.
 * Forces MAC flow control settings if link was forced. When in MII/GMII mode
 * and autonegotiation is enabled, the MAC flow control settings will be set
 * based on the flow control negotiated by the PHY. In TBI mode, the TFCE
 * and RFCE bits will be automaticaly set to the negotiated flow control mode.
 *****************************************************************************/
static s32
e1000_config_fc_after_link_up(struct e1000_hw *hw)
{
    s32 ret_val;
    u16 mii_status_reg;
    u16 mii_nway_adv_reg;
    u16 mii_nway_lp_ability_reg;
    u16 speed;
    u16 duplex;

    DEBUGFUNC("e1000_config_fc_after_link_up");

    /* Check for the case where we have fiber media and auto-neg failed
     * so we had to force link.  In this case, we need to force the
     * configuration of the MAC to match the "fc" parameter.
     */
    if (((hw->media_type == e1000_media_type_fiber) && (hw->autoneg_failed)) ||
        ((hw->media_type == e1000_media_type_internal_serdes) &&
         (hw->autoneg_failed)) ||
        ((hw->media_type == e1000_media_type_copper) && (!hw->autoneg))) {
        ret_val = e1000_force_mac_fc(hw);
        if (ret_val) {
            DEBUGOUT("Error forcing flow control settings\n");
            return ret_val;
        }
    }

    /* Check for the case where we have copper media and auto-neg is
     * enabled.  In this case, we need to check and see if Auto-Neg
     * has completed, and if so, how the PHY and link partner has
     * flow control configured.
     */
    if ((hw->media_type == e1000_media_type_copper) && hw->autoneg) {
        /* Read the MII Status Register and check to see if AutoNeg
         * has completed.  We read this twice because this reg has
         * some "sticky" (latched) bits.
         */
        ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
        if (ret_val)
            return ret_val;
        ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
        if (ret_val)
            return ret_val;

        if (mii_status_reg & MII_SR_AUTONEG_COMPLETE) {
            /* The AutoNeg process has completed, so we now need to
             * read both the Auto Negotiation Advertisement Register
             * (Address 4) and the Auto_Negotiation Base Page Ability
             * Register (Address 5) to determine how flow control was
             * negotiated.
             */
            ret_val = e1000_read_phy_reg(hw, PHY_AUTONEG_ADV,
                                         &mii_nway_adv_reg);
            if (ret_val)
                return ret_val;
            ret_val = e1000_read_phy_reg(hw, PHY_LP_ABILITY,
                                         &mii_nway_lp_ability_reg);
            if (ret_val)
                return ret_val;

            /* Two bits in the Auto Negotiation Advertisement Register
             * (Address 4) and two bits in the Auto Negotiation Base
             * Page Ability Register (Address 5) determine flow control
             * for both the PHY and the link partner.  The following
             * table, taken out of the IEEE 802.3ab/D6.0 dated March 25,
             * 1999, describes these PAUSE resolution bits and how flow
             * control is determined based upon these settings.
             * NOTE:  DC = Don't Care
             *
             *   LOCAL DEVICE  |   LINK PARTNER
             * PAUSE | ASM_DIR | PAUSE | ASM_DIR | NIC Resolution
             *-------|---------|-------|---------|--------------------
             *   0   |    0    |  DC   |   DC    | E1000_FC_NONE
             *   0   |    1    |   0   |   DC    | E1000_FC_NONE
             *   0   |    1    |   1   |    0    | E1000_FC_NONE
             *   0   |    1    |   1   |    1    | E1000_FC_TX_PAUSE
             *   1   |    0    |   0   |   DC    | E1000_FC_NONE
             *   1   |   DC    |   1   |   DC    | E1000_FC_FULL
             *   1   |    1    |   0   |    0    | E1000_FC_NONE
             *   1   |    1    |   0   |    1    | E1000_FC_RX_PAUSE
             *
             */
            /* Are both PAUSE bits set to 1?  If so, this implies
             * Symmetric Flow Control is enabled at both ends.  The
             * ASM_DIR bits are irrelevant per the spec.
             *
             * For Symmetric Flow Control:
             *
             *   LOCAL DEVICE  |   LINK PARTNER
             * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
             *-------|---------|-------|---------|--------------------
             *   1   |   DC    |   1   |   DC    | E1000_FC_FULL
             *
             */
            if ((mii_nway_adv_reg & NWAY_AR_PAUSE) &&
                (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE)) {
                /* Now we need to check if the user selected RX ONLY
                 * of pause frames.  In this case, we had to advertise
                 * FULL flow control because we could not advertise RX
                 * ONLY. Hence, we must now check to see if we need to
                 * turn OFF  the TRANSMISSION of PAUSE frames.
                 */
                if (hw->original_fc == E1000_FC_FULL) {
                    hw->fc = E1000_FC_FULL;
                    DEBUGOUT("Flow Control = FULL.\n");
                } else {
                    hw->fc = E1000_FC_RX_PAUSE;
                    DEBUGOUT("Flow Control = RX PAUSE frames only.\n");
                }
            }
            /* For receiving PAUSE frames ONLY.
             *
             *   LOCAL DEVICE  |   LINK PARTNER
             * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
             *-------|---------|-------|---------|--------------------
             *   0   |    1    |   1   |    1    | E1000_FC_TX_PAUSE
             *
             */
            else if (!(mii_nway_adv_reg & NWAY_AR_PAUSE) &&
                     (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
                     (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
                     (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
                hw->fc = E1000_FC_TX_PAUSE;
                DEBUGOUT("Flow Control = TX PAUSE frames only.\n");
            }
            /* For transmitting PAUSE frames ONLY.
             *
             *   LOCAL DEVICE  |   LINK PARTNER
             * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
             *-------|---------|-------|---------|--------------------
             *   1   |    1    |   0   |    1    | E1000_FC_RX_PAUSE
             *
             */
            else if ((mii_nway_adv_reg & NWAY_AR_PAUSE) &&
                     (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
                     !(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
                     (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
                hw->fc = E1000_FC_RX_PAUSE;
                DEBUGOUT("Flow Control = RX PAUSE frames only.\n");
            }
            /* Per the IEEE spec, at this point flow control should be
             * disabled.  However, we want to consider that we could
             * be connected to a legacy switch that doesn't advertise
             * desired flow control, but can be forced on the link
             * partner.  So if we advertised no flow control, that is
             * what we will resolve to.  If we advertised some kind of
             * receive capability (Rx Pause Only or Full Flow Control)
             * and the link partner advertised none, we will configure
             * ourselves to enable Rx Flow Control only.  We can do
             * this safely for two reasons:  If the link partner really
             * didn't want flow control enabled, and we enable Rx, no
             * harm done since we won't be receiving any PAUSE frames
             * anyway.  If the intent on the link partner was to have
             * flow control enabled, then by us enabling RX only, we
             * can at least receive pause frames and process them.
             * This is a good idea because in most cases, since we are
             * predominantly a server NIC, more times than not we will
             * be asked to delay transmission of packets than asking
             * our link partner to pause transmission of frames.
             */
            else if ((hw->original_fc == E1000_FC_NONE ||
                      hw->original_fc == E1000_FC_TX_PAUSE) ||
                      hw->fc_strict_ieee) {
                hw->fc = E1000_FC_NONE;
                DEBUGOUT("Flow Control = NONE.\n");
            } else {
                hw->fc = E1000_FC_RX_PAUSE;
                DEBUGOUT("Flow Control = RX PAUSE frames only.\n");
            }

            /* Now we need to do one last check...  If we auto-
             * negotiated to HALF DUPLEX, flow control should not be
             * enabled per IEEE 802.3 spec.
             */
            ret_val = e1000_get_speed_and_duplex(hw, &speed, &duplex);
            if (ret_val) {
                DEBUGOUT("Error getting link speed and duplex\n");
                return ret_val;
            }

            if (duplex == HALF_DUPLEX)
                hw->fc = E1000_FC_NONE;

            /* Now we call a subroutine to actually force the MAC
             * controller to use the correct flow control settings.
             */
            ret_val = e1000_force_mac_fc(hw);
            if (ret_val) {
                DEBUGOUT("Error forcing flow control settings\n");
                return ret_val;
            }
        } else {
            DEBUGOUT("Copper PHY and Auto Neg has not completed.\n");
        }
    }
    return E1000_SUCCESS;
}

/******************************************************************************
 * Checks to see if the link status of the hardware has changed.
 *
 * hw - Struct containing variables accessed by shared code
 *
 * Called by any function that needs to check the link status of the adapter.
 *****************************************************************************/
s32
e1000_check_for_link(struct e1000_hw *hw)
{
    u32 rxcw = 0;
    u32 ctrl;
    u32 status;
    u32 rctl;
    u32 icr;
    u32 signal = 0;
    s32 ret_val;
    u16 phy_data;

    DEBUGFUNC("e1000_check_for_link");

    ctrl = E1000_READ_REG(hw, CTRL);
    status = E1000_READ_REG(hw, STATUS);

    /* On adapters with a MAC newer than 82544, SW Defineable pin 1 will be
     * set when the optics detect a signal. On older adapters, it will be
     * cleared when there is a signal.  This applies to fiber media only.
     */
    if ((hw->media_type == e1000_media_type_fiber) ||
        (hw->media_type == e1000_media_type_internal_serdes)) {
        rxcw = E1000_READ_REG(hw, RXCW);

        if (hw->media_type == e1000_media_type_fiber) {
            signal = (hw->mac_type > e1000_82544) ? E1000_CTRL_SWDPIN1 : 0;
            if (status & E1000_STATUS_LU)
                hw->get_link_status = false;
        }
    }

    /* If we have a copper PHY then we only want to go out to the PHY
     * registers to see if Auto-Neg has completed and/or if our link
     * status has changed.  The get_link_status flag will be set if we
     * receive a Link Status Change interrupt or we have Rx Sequence
     * Errors.
     */
    if ((hw->media_type == e1000_media_type_copper) && hw->get_link_status) {
        /* First we want to see if the MII Status Register reports
         * link.  If so, then we want to get the current speed/duplex
         * of the PHY.
         * Read the register twice since the link bit is sticky.
         */
        ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
        if (ret_val)
            return ret_val;
        ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
        if (ret_val)
            return ret_val;

        if (phy_data & MII_SR_LINK_STATUS) {
            hw->get_link_status = false;
            /* Check if there was DownShift, must be checked immediately after
             * link-up */
            e1000_check_downshift(hw);

            /* If we are on 82544 or 82543 silicon and speed/duplex
             * are forced to 10H or 10F, then we will implement the polarity
             * reversal workaround.  We disable interrupts first, and upon
             * returning, place the devices interrupt state to its previous
             * value except for the link status change interrupt which will
             * happen due to the execution of this workaround.
             */

            if ((hw->mac_type == e1000_82544 || hw->mac_type == e1000_82543) &&
                (!hw->autoneg) &&
                (hw->forced_speed_duplex == e1000_10_full ||
                 hw->forced_speed_duplex == e1000_10_half)) {
                E1000_WRITE_REG(hw, IMC, 0xffffffff);
                ret_val = e1000_polarity_reversal_workaround(hw);
                icr = E1000_READ_REG(hw, ICR);
                E1000_WRITE_REG(hw, ICS, (icr & ~E1000_ICS_LSC));
                E1000_WRITE_REG(hw, IMS, IMS_ENABLE_MASK);
            }

        } else {
            /* No link detected */
            e1000_config_dsp_after_link_change(hw, false);
            return 0;
        }

        /* If we are forcing speed/duplex, then we simply return since
         * we have already determined whether we have link or not.
         */
        if (!hw->autoneg) return -E1000_ERR_CONFIG;

        /* optimize the dsp settings for the igp phy */
        e1000_config_dsp_after_link_change(hw, true);

        /* We have a M88E1000 PHY and Auto-Neg is enabled.  If we
         * have Si on board that is 82544 or newer, Auto
         * Speed Detection takes care of MAC speed/duplex
         * configuration.  So we only need to configure Collision
         * Distance in the MAC.  Otherwise, we need to force
         * speed/duplex on the MAC to the current PHY speed/duplex
         * settings.
         */
        if (hw->mac_type >= e1000_82544)
            e1000_config_collision_dist(hw);
        else {
            ret_val = e1000_config_mac_to_phy(hw);
            if (ret_val) {
                DEBUGOUT("Error configuring MAC to PHY settings\n");
                return ret_val;
            }
        }

        /* Configure Flow Control now that Auto-Neg has completed. First, we
         * need to restore the desired flow control settings because we may
         * have had to re-autoneg with a different link partner.
         */
        ret_val = e1000_config_fc_after_link_up(hw);
        if (ret_val) {
            DEBUGOUT("Error configuring flow control\n");
            return ret_val;
        }

        /* At this point we know that we are on copper and we have
         * auto-negotiated link.  These are conditions for checking the link
         * partner capability register.  We use the link speed to determine if
         * TBI compatibility needs to be turned on or off.  If the link is not
         * at gigabit speed, then TBI compatibility is not needed.  If we are
         * at gigabit speed, we turn on TBI compatibility.
         */
        if (hw->tbi_compatibility_en) {
            u16 speed, duplex;
            ret_val = e1000_get_speed_and_duplex(hw, &speed, &duplex);
            if (ret_val) {
                DEBUGOUT("Error getting link speed and duplex\n");
                return ret_val;
            }
            if (speed != SPEED_1000) {
                /* If link speed is not set to gigabit speed, we do not need
                 * to enable TBI compatibility.
                 */
                if (hw->tbi_compatibility_on) {
                    /* If we previously were in the mode, turn it off. */
                    rctl = E1000_READ_REG(hw, RCTL);
                    rctl &= ~E1000_RCTL_SBP;
                    E1000_WRITE_REG(hw, RCTL, rctl);
                    hw->tbi_compatibility_on = false;
                }
            } else {
                /* If TBI compatibility is was previously off, turn it on. For
                 * compatibility with a TBI link partner, we will store bad
                 * packets. Some frames have an additional byte on the end and
                 * will look like CRC errors to to the hardware.
                 */
                if (!hw->tbi_compatibility_on) {
                    hw->tbi_compatibility_on = true;
                    rctl = E1000_READ_REG(hw, RCTL);
                    rctl |= E1000_RCTL_SBP;
                    E1000_WRITE_REG(hw, RCTL, rctl);
                }
            }
        }
    }
    /* If we don't have link (auto-negotiation failed or link partner cannot
     * auto-negotiate), the cable is plugged in (we have signal), and our
     * link partner is not trying to auto-negotiate with us (we are receiving
     * idles or data), we need to force link up. We also need to give
     * auto-negotiation time to complete, in case the cable was just plugged
     * in. The autoneg_failed flag does this.
     */
    else if ((((hw->media_type == e1000_media_type_fiber) &&
              ((ctrl & E1000_CTRL_SWDPIN1) == signal)) ||
              (hw->media_type == e1000_media_type_internal_serdes)) &&
              (!(status & E1000_STATUS_LU)) &&
              (!(rxcw & E1000_RXCW_C))) {
        if (hw->autoneg_failed == 0) {
            hw->autoneg_failed = 1;
            return 0;
        }
        DEBUGOUT("NOT RXing /C/, disable AutoNeg and force link.\n");

        /* Disable auto-negotiation in the TXCW register */
        E1000_WRITE_REG(hw, TXCW, (hw->txcw & ~E1000_TXCW_ANE));

        /* Force link-up and also force full-duplex. */
        ctrl = E1000_READ_REG(hw, CTRL);
        ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FD);
        E1000_WRITE_REG(hw, CTRL, ctrl);

        /* Configure Flow Control after forcing link up. */
        ret_val = e1000_config_fc_after_link_up(hw);
        if (ret_val) {
            DEBUGOUT("Error configuring flow control\n");
            return ret_val;
        }
    }
    /* If we are forcing link and we are receiving /C/ ordered sets, re-enable
     * auto-negotiation in the TXCW register and disable forced link in the
     * Device Control register in an attempt to auto-negotiate with our link
     * partner.
     */
    else if (((hw->media_type == e1000_media_type_fiber) ||
              (hw->media_type == e1000_media_type_internal_serdes)) &&
              (ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) {
        DEBUGOUT("RXing /C/, enable AutoNeg and stop forcing link.\n");
        E1000_WRITE_REG(hw, TXCW, hw->txcw);
        E1000_WRITE_REG(hw, CTRL, (ctrl & ~E1000_CTRL_SLU));

        hw->serdes_link_down = false;
    }
    /* If we force link for non-auto-negotiation switch, check link status
     * based on MAC synchronization for internal serdes media type.
     */
    else if ((hw->media_type == e1000_media_type_internal_serdes) &&
             !(E1000_TXCW_ANE & E1000_READ_REG(hw, TXCW))) {
        /* SYNCH bit and IV bit are sticky. */
        udelay(10);
        if (E1000_RXCW_SYNCH & E1000_READ_REG(hw, RXCW)) {
            if (!(rxcw & E1000_RXCW_IV)) {
                hw->serdes_link_down = false;
                DEBUGOUT("SERDES: Link is up.\n");
            }
        } else {
            hw->serdes_link_down = true;
            DEBUGOUT("SERDES: Link is down.\n");
        }
    }
    if ((hw->media_type == e1000_media_type_internal_serdes) &&
        (E1000_TXCW_ANE & E1000_READ_REG(hw, TXCW))) {
        hw->serdes_link_down = !(E1000_STATUS_LU & E1000_READ_REG(hw, STATUS));
    }
    return E1000_SUCCESS;
}

/******************************************************************************
 * Detects the current speed and duplex settings of the hardware.
 *
 * hw - Struct containing variables accessed by shared code
 * speed - Speed of the connection
 * duplex - Duplex setting of the connection
 *****************************************************************************/
s32
e1000_get_speed_and_duplex(struct e1000_hw *hw,
                           u16 *speed,
                           u16 *duplex)
{
    u32 status;
    s32 ret_val;
    u16 phy_data;

    DEBUGFUNC("e1000_get_speed_and_duplex");

    if (hw->mac_type >= e1000_82543) {
        status = E1000_READ_REG(hw, STATUS);
        if (status & E1000_STATUS_SPEED_1000) {
            *speed = SPEED_1000;
            DEBUGOUT("1000 Mbs, ");
        } else if (status & E1000_STATUS_SPEED_100) {
            *speed = SPEED_100;
            DEBUGOUT("100 Mbs, ");
        } else {
            *speed = SPEED_10;
            DEBUGOUT("10 Mbs, ");
        }

        if (status & E1000_STATUS_FD) {
            *duplex = FULL_DUPLEX;
            DEBUGOUT("Full Duplex\n");
        } else {
            *duplex = HALF_DUPLEX;
            DEBUGOUT(" Half Duplex\n");
        }
    } else {
        DEBUGOUT("1000 Mbs, Full Duplex\n");
        *speed = SPEED_1000;
        *duplex = FULL_DUPLEX;
    }

    /* IGP01 PHY may advertise full duplex operation after speed downgrade even
     * if it is operating at half duplex.  Here we set the duplex settings to
     * match the duplex in the link partner's capabilities.
     */
    if (hw->phy_type == e1000_phy_igp && hw->speed_downgraded) {
        ret_val = e1000_read_phy_reg(hw, PHY_AUTONEG_EXP, &phy_data);
        if (ret_val)
            return ret_val;

        if (!(phy_data & NWAY_ER_LP_NWAY_CAPS))
            *duplex = HALF_DUPLEX;
        else {
            ret_val = e1000_read_phy_reg(hw, PHY_LP_ABILITY, &phy_data);
            if (ret_val)
                return ret_val;
            if ((*speed == SPEED_100 && !(phy_data & NWAY_LPAR_100TX_FD_CAPS)) ||
               (*speed == SPEED_10 && !(phy_data & NWAY_LPAR_10T_FD_CAPS)))
                *duplex = HALF_DUPLEX;
        }
    }

    if ((hw->mac_type == e1000_80003es2lan) &&
        (hw->media_type == e1000_media_type_copper)) {
        if (*speed == SPEED_1000)
            ret_val = e1000_configure_kmrn_for_1000(hw);
        else
            ret_val = e1000_configure_kmrn_for_10_100(hw, *duplex);
        if (ret_val)
            return ret_val;
    }

    if ((hw->phy_type == e1000_phy_igp_3) && (*speed == SPEED_1000)) {
        ret_val = e1000_kumeran_lock_loss_workaround(hw);
        if (ret_val)
            return ret_val;
    }

    return E1000_SUCCESS;
}

/******************************************************************************
* Blocks until autoneg completes or times out (~4.5 seconds)
*
* hw - Struct containing variables accessed by shared code
******************************************************************************/
static s32
e1000_wait_autoneg(struct e1000_hw *hw)
{
    s32 ret_val;
    u16 i;
    u16 phy_data;

    DEBUGFUNC("e1000_wait_autoneg");
    DEBUGOUT("Waiting for Auto-Neg to complete.\n");

    /* We will wait for autoneg to complete or 4.5 seconds to expire. */
    for (i = PHY_AUTO_NEG_TIME; i > 0; i--) {
        /* Read the MII Status Register and wait for Auto-Neg
         * Complete bit to be set.
         */
        ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
        if (ret_val)
            return ret_val;
        ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
        if (ret_val)
            return ret_val;
        if (phy_data & MII_SR_AUTONEG_COMPLETE) {
            return E1000_SUCCESS;
        }
        msleep(100);
    }
    return E1000_SUCCESS;
}

/******************************************************************************
* Raises the Management Data Clock
*
* hw - Struct containing variables accessed by shared code
* ctrl - Device control register's current value
******************************************************************************/
static void
e1000_raise_mdi_clk(struct e1000_hw *hw,
                    u32 *ctrl)
{
    /* Raise the clock input to the Management Data Clock (by setting the MDC
     * bit), and then delay 10 microseconds.
     */
    E1000_WRITE_REG(hw, CTRL, (*ctrl | E1000_CTRL_MDC));
    E1000_WRITE_FLUSH(hw);
    udelay(10);
}

/******************************************************************************
* Lowers the Management Data Clock
*
* hw - Struct containing variables accessed by shared code
* ctrl - Device control register's current value
******************************************************************************/
static void
e1000_lower_mdi_clk(struct e1000_hw *hw,
                    u32 *ctrl)
{
    /* Lower the clock input to the Management Data Clock (by clearing the MDC
     * bit), and then delay 10 microseconds.
     */
    E1000_WRITE_REG(hw, CTRL, (*ctrl & ~E1000_CTRL_MDC));
    E1000_WRITE_FLUSH(hw);
    udelay(10);
}

/******************************************************************************
* Shifts data bits out to the PHY
*
* hw - Struct containing variables accessed by shared code
* data - Data to send out to the PHY
* count - Number of bits to shift out
*
* Bits are shifted out in MSB to LSB order.
******************************************************************************/
static void
e1000_shift_out_mdi_bits(struct e1000_hw *hw,
                         u32 data,
                         u16 count)
{
    u32 ctrl;
    u32 mask;

    /* We need to shift "count" number of bits out to the PHY. So, the value
     * in the "data" parameter will be shifted out to the PHY one bit at a
     * time. In order to do this, "data" must be broken down into bits.
     */
    mask = 0x01;
    mask <<= (count - 1);

    ctrl = E1000_READ_REG(hw, CTRL);

    /* Set MDIO_DIR and MDC_DIR direction bits to be used as output pins. */
    ctrl |= (E1000_CTRL_MDIO_DIR | E1000_CTRL_MDC_DIR);

    while (mask) {
        /* A "1" is shifted out to the PHY by setting the MDIO bit to "1" and
         * then raising and lowering the Management Data Clock. A "0" is
         * shifted out to the PHY by setting the MDIO bit to "0" and then
         * raising and lowering the clock.
         */
        if (data & mask)
            ctrl |= E1000_CTRL_MDIO;
        else
            ctrl &= ~E1000_CTRL_MDIO;

        E1000_WRITE_REG(hw, CTRL, ctrl);
        E1000_WRITE_FLUSH(hw);

        udelay(10);

        e1000_raise_mdi_clk(hw, &ctrl);
        e1000_lower_mdi_clk(hw, &ctrl);

        mask = mask >> 1;
    }
}

/******************************************************************************
* Shifts data bits in from the PHY
*
* hw - Struct containing variables accessed by shared code
*
* Bits are shifted in in MSB to LSB order.
******************************************************************************/
static u16
e1000_shift_in_mdi_bits(struct e1000_hw *hw)
{
    u32 ctrl;
    u16 data = 0;
    u8 i;

    /* In order to read a register from the PHY, we need to shift in a total
     * of 18 bits from the PHY. The first two bit (turnaround) times are used
     * to avoid contention on the MDIO pin when a read operation is performed.
     * These two bits are ignored by us and thrown away. Bits are "shifted in"
     * by raising the input to the Management Data Clock (setting the MDC bit),
     * and then reading the value of the MDIO bit.
     */
    ctrl = E1000_READ_REG(hw, CTRL);

    /* Clear MDIO_DIR (SWDPIO1) to indicate this bit is to be used as input. */
    ctrl &= ~E1000_CTRL_MDIO_DIR;
    ctrl &= ~E1000_CTRL_MDIO;

    E1000_WRITE_REG(hw, CTRL, ctrl);
    E1000_WRITE_FLUSH(hw);

    /* Raise and Lower the clock before reading in the data. This accounts for
     * the turnaround bits. The first clock occurred when we clocked out the
     * last bit of the Register Address.
     */
    e1000_raise_mdi_clk(hw, &ctrl);
    e1000_lower_mdi_clk(hw, &ctrl);

    for (data = 0, i = 0; i < 16; i++) {
        data = data << 1;
        e1000_raise_mdi_clk(hw, &ctrl);
        ctrl = E1000_READ_REG(hw, CTRL);
        /* Check to see if we shifted in a "1". */
        if (ctrl & E1000_CTRL_MDIO)
            data |= 1;
        e1000_lower_mdi_clk(hw, &ctrl);
    }

    e1000_raise_mdi_clk(hw, &ctrl);
    e1000_lower_mdi_clk(hw, &ctrl);

    return data;
}

static s32
e1000_swfw_sync_acquire(struct e1000_hw *hw, u16 mask)
{
    u32 swfw_sync = 0;
    u32 swmask = mask;
    u32 fwmask = mask << 16;
    s32 timeout = 200;

    DEBUGFUNC("e1000_swfw_sync_acquire");

    if (hw->swfwhw_semaphore_present)
        return e1000_get_software_flag(hw);

    if (!hw->swfw_sync_present)
        return e1000_get_hw_eeprom_semaphore(hw);

    while (timeout) {
            if (e1000_get_hw_eeprom_semaphore(hw))
                return -E1000_ERR_SWFW_SYNC;

            swfw_sync = E1000_READ_REG(hw, SW_FW_SYNC);
            if (!(swfw_sync & (fwmask | swmask))) {
                break;
            }

            /* firmware currently using resource (fwmask) */
            /* or other software thread currently using resource (swmask) */
            e1000_put_hw_eeprom_semaphore(hw);
            mdelay(5);
            timeout--;
    }

    if (!timeout) {
        DEBUGOUT("Driver can't access resource, SW_FW_SYNC timeout.\n");
        return -E1000_ERR_SWFW_SYNC;
    }

    swfw_sync |= swmask;
    E1000_WRITE_REG(hw, SW_FW_SYNC, swfw_sync);

    e1000_put_hw_eeprom_semaphore(hw);
    return E1000_SUCCESS;
}

static void
e1000_swfw_sync_release(struct e1000_hw *hw, u16 mask)
{
    u32 swfw_sync;
    u32 swmask = mask;

    DEBUGFUNC("e1000_swfw_sync_release");

    if (hw->swfwhw_semaphore_present) {
        e1000_release_software_flag(hw);
        return;
    }

    if (!hw->swfw_sync_present) {
        e1000_put_hw_eeprom_semaphore(hw);
        return;
    }

    /* if (e1000_get_hw_eeprom_semaphore(hw))
     *    return -E1000_ERR_SWFW_SYNC; */
    while (e1000_get_hw_eeprom_semaphore(hw) != E1000_SUCCESS);
        /* empty */

    swfw_sync = E1000_READ_REG(hw, SW_FW_SYNC);
    swfw_sync &= ~swmask;
    E1000_WRITE_REG(hw, SW_FW_SYNC, swfw_sync);

    e1000_put_hw_eeprom_semaphore(hw);
}

/*****************************************************************************
* Reads the value from a PHY register, if the value is on a specific non zero
* page, sets the page first.
* hw - Struct containing variables accessed by shared code
* reg_addr - address of the PHY register to read
******************************************************************************/
s32
e1000_read_phy_reg(struct e1000_hw *hw,
                   u32 reg_addr,
                   u16 *phy_data)
{
    u32 ret_val;
    u16 swfw;

    DEBUGFUNC("e1000_read_phy_reg");

    if ((hw->mac_type == e1000_80003es2lan) &&
        (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1)) {
        swfw = E1000_SWFW_PHY1_SM;
    } else {
        swfw = E1000_SWFW_PHY0_SM;
    }
    if (e1000_swfw_sync_acquire(hw, swfw))
        return -E1000_ERR_SWFW_SYNC;

    if ((hw->phy_type == e1000_phy_igp ||
        hw->phy_type == e1000_phy_igp_3 ||
        hw->phy_type == e1000_phy_igp_2) &&
       (reg_addr > MAX_PHY_MULTI_PAGE_REG)) {
        ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT,
                                         (u16)reg_addr);
        if (ret_val) {
            e1000_swfw_sync_release(hw, swfw);
            return ret_val;
        }
    } else if (hw->phy_type == e1000_phy_gg82563) {
        if (((reg_addr & MAX_PHY_REG_ADDRESS) > MAX_PHY_MULTI_PAGE_REG) ||
            (hw->mac_type == e1000_80003es2lan)) {
            /* Select Configuration Page */
            if ((reg_addr & MAX_PHY_REG_ADDRESS) < GG82563_MIN_ALT_REG) {
                ret_val = e1000_write_phy_reg_ex(hw, GG82563_PHY_PAGE_SELECT,
                          (u16)((u16)reg_addr >> GG82563_PAGE_SHIFT));
            } else {
                /* Use Alternative Page Select register to access
                 * registers 30 and 31
                 */
                ret_val = e1000_write_phy_reg_ex(hw,
                                                 GG82563_PHY_PAGE_SELECT_ALT,
                          (u16)((u16)reg_addr >> GG82563_PAGE_SHIFT));
            }

            if (ret_val) {
                e1000_swfw_sync_release(hw, swfw);
                return ret_val;
            }
        }
    }

    ret_val = e1000_read_phy_reg_ex(hw, MAX_PHY_REG_ADDRESS & reg_addr,
                                    phy_data);

    e1000_swfw_sync_release(hw, swfw);
    return ret_val;
}

static s32
e1000_read_phy_reg_ex(struct e1000_hw *hw, u32 reg_addr,
                      u16 *phy_data)
{
    u32 i;
    u32 mdic = 0;
    const u32 phy_addr = 1;

    DEBUGFUNC("e1000_read_phy_reg_ex");

    if (reg_addr > MAX_PHY_REG_ADDRESS) {
        DEBUGOUT1("PHY Address %d is out of range\n", reg_addr);
        return -E1000_ERR_PARAM;
    }

    if (hw->mac_type > e1000_82543) {
        /* Set up Op-code, Phy Address, and register address in the MDI
         * Control register.  The MAC will take care of interfacing with the
         * PHY to retrieve the desired data.
         */
        mdic = ((reg_addr << E1000_MDIC_REG_SHIFT) |
                (phy_addr << E1000_MDIC_PHY_SHIFT) |
                (E1000_MDIC_OP_READ));

        E1000_WRITE_REG(hw, MDIC, mdic);

        /* Poll the ready bit to see if the MDI read completed */
        for (i = 0; i < 64; i++) {
            udelay(50);
            mdic = E1000_READ_REG(hw, MDIC);
            if (mdic & E1000_MDIC_READY) break;
        }
        if (!(mdic & E1000_MDIC_READY)) {
            DEBUGOUT("MDI Read did not complete\n");
            return -E1000_ERR_PHY;
        }
        if (mdic & E1000_MDIC_ERROR) {
            DEBUGOUT("MDI Error\n");
            return -E1000_ERR_PHY;
        }
        *phy_data = (u16) mdic;
    } else {
        /* We must first send a preamble through the MDIO pin to signal the
         * beginning of an MII instruction.  This is done by sending 32
         * consecutive "1" bits.
         */
        e1000_shift_out_mdi_bits(hw, PHY_PREAMBLE, PHY_PREAMBLE_SIZE);

        /* Now combine the next few fields that are required for a read
         * operation.  We use this method instead of calling the
         * e1000_shift_out_mdi_bits routine five different times. The format of
         * a MII read instruction consists of a shift out of 14 bits and is
         * defined as follows:
         *    <Preamble><SOF><Op Code><Phy Addr><Reg Addr>
         * followed by a shift in of 18 bits.  This first two bits shifted in
         * are TurnAround bits used to avoid contention on the MDIO pin when a
         * READ operation is performed.  These two bits are thrown away
         * followed by a shift in of 16 bits which contains the desired data.
         */
        mdic = ((reg_addr) | (phy_addr << 5) |
                (PHY_OP_READ << 10) | (PHY_SOF << 12));

        e1000_shift_out_mdi_bits(hw, mdic, 14);

        /* Now that we've shifted out the read command to the MII, we need to
         * "shift in" the 16-bit value (18 total bits) of the requested PHY
         * register address.
         */
        *phy_data = e1000_shift_in_mdi_bits(hw);
    }
    return E1000_SUCCESS;
}

/******************************************************************************
* Writes a value to a PHY register
*
* hw - Struct containing variables accessed by shared code
* reg_addr - address of the PHY register to write
* data - data to write to the PHY
******************************************************************************/
s32
e1000_write_phy_reg(struct e1000_hw *hw, u32 reg_addr,
                    u16 phy_data)
{
    u32 ret_val;
    u16 swfw;

    DEBUGFUNC("e1000_write_phy_reg");

    if ((hw->mac_type == e1000_80003es2lan) &&
        (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1)) {
        swfw = E1000_SWFW_PHY1_SM;
    } else {
        swfw = E1000_SWFW_PHY0_SM;
    }
    if (e1000_swfw_sync_acquire(hw, swfw))
        return -E1000_ERR_SWFW_SYNC;

    if ((hw->phy_type == e1000_phy_igp ||
        hw->phy_type == e1000_phy_igp_3 ||
        hw->phy_type == e1000_phy_igp_2) &&
       (reg_addr > MAX_PHY_MULTI_PAGE_REG)) {
        ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT,
                                         (u16)reg_addr);
        if (ret_val) {
            e1000_swfw_sync_release(hw, swfw);
            return ret_val;
        }
    } else if (hw->phy_type == e1000_phy_gg82563) {
        if (((reg_addr & MAX_PHY_REG_ADDRESS) > MAX_PHY_MULTI_PAGE_REG) ||
            (hw->mac_type == e1000_80003es2lan)) {
            /* Select Configuration Page */
            if ((reg_addr & MAX_PHY_REG_ADDRESS) < GG82563_MIN_ALT_REG) {
                ret_val = e1000_write_phy_reg_ex(hw, GG82563_PHY_PAGE_SELECT,
                          (u16)((u16)reg_addr >> GG82563_PAGE_SHIFT));
            } else {
                /* Use Alternative Page Select register to access
                 * registers 30 and 31
                 */
                ret_val = e1000_write_phy_reg_ex(hw,
                                                 GG82563_PHY_PAGE_SELECT_ALT,
                          (u16)((u16)reg_addr >> GG82563_PAGE_SHIFT));
            }

            if (ret_val) {
                e1000_swfw_sync_release(hw, swfw);
                return ret_val;
            }
        }
    }

    ret_val = e1000_write_phy_reg_ex(hw, MAX_PHY_REG_ADDRESS & reg_addr,
                                     phy_data);

    e1000_swfw_sync_release(hw, swfw);
    return ret_val;
}

static s32
e1000_write_phy_reg_ex(struct e1000_hw *hw, u32 reg_addr,
                       u16 phy_data)
{
    u32 i;
    u32 mdic = 0;
    const u32 phy_addr = 1;

    DEBUGFUNC("e1000_write_phy_reg_ex");

    if (reg_addr > MAX_PHY_REG_ADDRESS) {
        DEBUGOUT1("PHY Address %d is out of range\n", reg_addr);
        return -E1000_ERR_PARAM;
    }

    if (hw->mac_type > e1000_82543) {
        /* Set up Op-code, Phy Address, register address, and data intended
         * for the PHY register in the MDI Control register.  The MAC will take
         * care of interfacing with the PHY to send the desired data.
         */
        mdic = (((u32) phy_data) |
                (reg_addr << E1000_MDIC_REG_SHIFT) |
                (phy_addr << E1000_MDIC_PHY_SHIFT) |
                (E1000_MDIC_OP_WRITE));

        E1000_WRITE_REG(hw, MDIC, mdic);

        /* Poll the ready bit to see if the MDI read completed */
        for (i = 0; i < 641; i++) {
            udelay(5);
            mdic = E1000_READ_REG(hw, MDIC);
            if (mdic & E1000_MDIC_READY) break;
        }
        if (!(mdic & E1000_MDIC_READY)) {
            DEBUGOUT("MDI Write did not complete\n");
            return -E1000_ERR_PHY;
        }
    } else {
        /* We'll need to use the SW defined pins to shift the write command
         * out to the PHY. We first send a preamble to the PHY to signal the
         * beginning of the MII instruction.  This is done by sending 32
         * consecutive "1" bits.
         */
        e1000_shift_out_mdi_bits(hw, PHY_PREAMBLE, PHY_PREAMBLE_SIZE);

        /* Now combine the remaining required fields that will indicate a
         * write operation. We use this method instead of calling the
         * e1000_shift_out_mdi_bits routine for each field in the command. The
         * format of a MII write instruction is as follows:
         * <Preamble><SOF><Op Code><Phy Addr><Reg Addr><Turnaround><Data>.
         */
        mdic = ((PHY_TURNAROUND) | (reg_addr << 2) | (phy_addr << 7) |
                (PHY_OP_WRITE << 12) | (PHY_SOF << 14));
        mdic <<= 16;
        mdic |= (u32) phy_data;

        e1000_shift_out_mdi_bits(hw, mdic, 32);
    }

    return E1000_SUCCESS;
}

static s32
e1000_read_kmrn_reg(struct e1000_hw *hw,
                    u32 reg_addr,
                    u16 *data)
{
    u32 reg_val;
    u16 swfw;
    DEBUGFUNC("e1000_read_kmrn_reg");

    if ((hw->mac_type == e1000_80003es2lan) &&
        (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1)) {
        swfw = E1000_SWFW_PHY1_SM;
    } else {
        swfw = E1000_SWFW_PHY0_SM;
    }
    if (e1000_swfw_sync_acquire(hw, swfw))
        return -E1000_ERR_SWFW_SYNC;

    /* Write register address */
    reg_val = ((reg_addr << E1000_KUMCTRLSTA_OFFSET_SHIFT) &
              E1000_KUMCTRLSTA_OFFSET) |
              E1000_KUMCTRLSTA_REN;
    E1000_WRITE_REG(hw, KUMCTRLSTA, reg_val);
    udelay(2);

    /* Read the data returned */
    reg_val = E1000_READ_REG(hw, KUMCTRLSTA);
    *data = (u16)reg_val;

    e1000_swfw_sync_release(hw, swfw);
    return E1000_SUCCESS;
}

static s32
e1000_write_kmrn_reg(struct e1000_hw *hw,
                     u32 reg_addr,
                     u16 data)
{
    u32 reg_val;
    u16 swfw;
    DEBUGFUNC("e1000_write_kmrn_reg");

    if ((hw->mac_type == e1000_80003es2lan) &&
        (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1)) {
        swfw = E1000_SWFW_PHY1_SM;
    } else {
        swfw = E1000_SWFW_PHY0_SM;
    }
    if (e1000_swfw_sync_acquire(hw, swfw))
        return -E1000_ERR_SWFW_SYNC;

    reg_val = ((reg_addr << E1000_KUMCTRLSTA_OFFSET_SHIFT) &
              E1000_KUMCTRLSTA_OFFSET) | data;
    E1000_WRITE_REG(hw, KUMCTRLSTA, reg_val);
    udelay(2);

    e1000_swfw_sync_release(hw, swfw);
    return E1000_SUCCESS;
}

/******************************************************************************
* Returns the PHY to the power-on reset state
*
* hw - Struct containing variables accessed by shared code
******************************************************************************/
s32
e1000_phy_hw_reset(struct e1000_hw *hw)
{
    u32 ctrl, ctrl_ext;
    u32 led_ctrl;
    s32 ret_val;
    u16 swfw;

    DEBUGFUNC("e1000_phy_hw_reset");

    /* In the case of the phy reset being blocked, it's not an error, we
     * simply return success without performing the reset. */
    ret_val = e1000_check_phy_reset_block(hw);
    if (ret_val)
        return E1000_SUCCESS;

    DEBUGOUT("Resetting Phy...\n");

    if (hw->mac_type > e1000_82543) {
        if ((hw->mac_type == e1000_80003es2lan) &&
            (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1)) {
            swfw = E1000_SWFW_PHY1_SM;
        } else {
            swfw = E1000_SWFW_PHY0_SM;
        }
        if (e1000_swfw_sync_acquire(hw, swfw)) {
            DEBUGOUT("Unable to acquire swfw sync\n");
            return -E1000_ERR_SWFW_SYNC;
        }
        /* Read the device control register and assert the E1000_CTRL_PHY_RST
         * bit. Then, take it out of reset.
         * For pre-e1000_82571 hardware, we delay for 10ms between the assert
         * and deassert.  For e1000_82571 hardware and later, we instead delay
         * for 50us between and 10ms after the deassertion.
         */
        ctrl = E1000_READ_REG(hw, CTRL);
        E1000_WRITE_REG(hw, CTRL, ctrl | E1000_CTRL_PHY_RST);
        E1000_WRITE_FLUSH(hw);

        if (hw->mac_type < e1000_82571)
            msleep(10);
        else
            udelay(100);

        E1000_WRITE_REG(hw, CTRL, ctrl);
        E1000_WRITE_FLUSH(hw);

        if (hw->mac_type >= e1000_82571)
            mdelay(10);

        e1000_swfw_sync_release(hw, swfw);
    } else {
        /* Read the Extended Device Control Register, assert the PHY_RESET_DIR
         * bit to put the PHY into reset. Then, take it out of reset.
         */
        ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
        ctrl_ext |= E1000_CTRL_EXT_SDP4_DIR;
        ctrl_ext &= ~E1000_CTRL_EXT_SDP4_DATA;
        E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
        E1000_WRITE_FLUSH(hw);
        msleep(10);
        ctrl_ext |= E1000_CTRL_EXT_SDP4_DATA;
        E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
        E1000_WRITE_FLUSH(hw);
    }
    udelay(150);

    if ((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
        /* Configure activity LED after PHY reset */
        led_ctrl = E1000_READ_REG(hw, LEDCTL);
        led_ctrl &= IGP_ACTIVITY_LED_MASK;
        led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE);
        E1000_WRITE_REG(hw, LEDCTL, led_ctrl);
    }

    /* Wait for FW to finish PHY configuration. */
    ret_val = e1000_get_phy_cfg_done(hw);
    if (ret_val != E1000_SUCCESS)
        return ret_val;
    e1000_release_software_semaphore(hw);

    if ((hw->mac_type == e1000_ich8lan) && (hw->phy_type == e1000_phy_igp_3))
        ret_val = e1000_init_lcd_from_nvm(hw);

    return ret_val;
}

/******************************************************************************
* Resets the PHY
*
* hw - Struct containing variables accessed by shared code
*
* Sets bit 15 of the MII Control register
******************************************************************************/
s32
e1000_phy_reset(struct e1000_hw *hw)
{
    s32 ret_val;
    u16 phy_data;

    DEBUGFUNC("e1000_phy_reset");

    /* In the case of the phy reset being blocked, it's not an error, we
     * simply return success without performing the reset. */
    ret_val = e1000_check_phy_reset_block(hw);
    if (ret_val)
        return E1000_SUCCESS;

    switch (hw->phy_type) {
    case e1000_phy_igp:
    case e1000_phy_igp_2:
    case e1000_phy_igp_3:
    case e1000_phy_ife:
        ret_val = e1000_phy_hw_reset(hw);
        if (ret_val)
            return ret_val;
        break;
    default:
        ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &phy_data);
        if (ret_val)
            return ret_val;

        phy_data |= MII_CR_RESET;
        ret_val = e1000_write_phy_reg(hw, PHY_CTRL, phy_data);
        if (ret_val)
            return ret_val;

        udelay(1);
        break;
    }

    if (hw->phy_type == e1000_phy_igp || hw->phy_type == e1000_phy_igp_2)
        e1000_phy_init_script(hw);

    return E1000_SUCCESS;
}

/******************************************************************************
* Work-around for 82566 power-down: on D3 entry-
* 1) disable gigabit link
* 2) write VR power-down enable
* 3) read it back
* if successful continue, else issue LCD reset and repeat
*
* hw - struct containing variables accessed by shared code
******************************************************************************/
void
e1000_phy_powerdown_workaround(struct e1000_hw *hw)
{
    s32 reg;
    u16 phy_data;
    s32 retry = 0;

    DEBUGFUNC("e1000_phy_powerdown_workaround");

    if (hw->phy_type != e1000_phy_igp_3)
        return;

    do {
        /* Disable link */
        reg = E1000_READ_REG(hw, PHY_CTRL);
        E1000_WRITE_REG(hw, PHY_CTRL, reg | E1000_PHY_CTRL_GBE_DISABLE |
                        E1000_PHY_CTRL_NOND0A_GBE_DISABLE);

        /* Write VR power-down enable - bits 9:8 should be 10b */
        e1000_read_phy_reg(hw, IGP3_VR_CTRL, &phy_data);
        phy_data |= (1 << 9);
        phy_data &= ~(1 << 8);
        e1000_write_phy_reg(hw, IGP3_VR_CTRL, phy_data);

        /* Read it back and test */
        e1000_read_phy_reg(hw, IGP3_VR_CTRL, &phy_data);
        if (((phy_data & IGP3_VR_CTRL_MODE_MASK) == IGP3_VR_CTRL_MODE_SHUT) || retry)
            break;

        /* Issue PHY reset and repeat at most one more time */
        reg = E1000_READ_REG(hw, CTRL);
        E1000_WRITE_REG(hw, CTRL, reg | E1000_CTRL_PHY_RST);
        retry++;
    } while (retry);

    return;

}

/******************************************************************************
* Work-around for 82566 Kumeran PCS lock loss:
* On link status change (i.e. PCI reset, speed change) and link is up and
* speed is gigabit-
* 0) if workaround is optionally disabled do nothing
* 1) wait 1ms for Kumeran link to come up
* 2) check Kumeran Diagnostic register PCS lock loss bit
* 3) if not set the link is locked (all is good), otherwise...
* 4) reset the PHY
* 5) repeat up to 10 times
* Note: this is only called for IGP3 copper when speed is 1gb.
*
* hw - struct containing variables accessed by shared code
******************************************************************************/
static s32
e1000_kumeran_lock_loss_workaround(struct e1000_hw *hw)
{
    s32 ret_val;
    s32 reg;
    s32 cnt;
    u16 phy_data;

    if (hw->kmrn_lock_loss_workaround_disabled)
        return E1000_SUCCESS;

    /* Make sure link is up before proceeding.  If not just return.
     * Attempting this while link is negotiating fouled up link
     * stability */
    ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
    ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);

    if (phy_data & MII_SR_LINK_STATUS) {
        for (cnt = 0; cnt < 10; cnt++) {
            /* read once to clear */
            ret_val = e1000_read_phy_reg(hw, IGP3_KMRN_DIAG, &phy_data);
            if (ret_val)
                return ret_val;
            /* and again to get new status */
            ret_val = e1000_read_phy_reg(hw, IGP3_KMRN_DIAG, &phy_data);
            if (ret_val)
                return ret_val;

            /* check for PCS lock */
            if (!(phy_data & IGP3_KMRN_DIAG_PCS_LOCK_LOSS))
                return E1000_SUCCESS;

            /* Issue PHY reset */
            e1000_phy_hw_reset(hw);
            mdelay(5);
        }
        /* Disable GigE link negotiation */
        reg = E1000_READ_REG(hw, PHY_CTRL);
        E1000_WRITE_REG(hw, PHY_CTRL, reg | E1000_PHY_CTRL_GBE_DISABLE |
                        E1000_PHY_CTRL_NOND0A_GBE_DISABLE);

        /* unable to acquire PCS lock */
        return E1000_ERR_PHY;
    }

    return E1000_SUCCESS;
}

/******************************************************************************
* Probes the expected PHY address for known PHY IDs
*
* hw - Struct containing variables accessed by shared code
******************************************************************************/
static s32
e1000_detect_gig_phy(struct e1000_hw *hw)
{
    s32 phy_init_status, ret_val;
    u16 phy_id_high, phy_id_low;
    bool match = false;

    DEBUGFUNC("e1000_detect_gig_phy");

    if (hw->phy_id != 0)
        return E1000_SUCCESS;

    /* The 82571 firmware may still be configuring the PHY.  In this
     * case, we cannot access the PHY until the configuration is done.  So
     * we explicitly set the PHY values. */
    if (hw->mac_type == e1000_82571 ||
        hw->mac_type == e1000_82572) {
        hw->phy_id = IGP01E1000_I_PHY_ID;
        hw->phy_type = e1000_phy_igp_2;
        return E1000_SUCCESS;
    }

    /* ESB-2 PHY reads require e1000_phy_gg82563 to be set because of a work-
     * around that forces PHY page 0 to be set or the reads fail.  The rest of
     * the code in this routine uses e1000_read_phy_reg to read the PHY ID.
     * So for ESB-2 we need to have this set so our reads won't fail.  If the
     * attached PHY is not a e1000_phy_gg82563, the routines below will figure
     * this out as well. */
    if (hw->mac_type == e1000_80003es2lan)
        hw->phy_type = e1000_phy_gg82563;

    /* Read the PHY ID Registers to identify which PHY is onboard. */
    ret_val = e1000_read_phy_reg(hw, PHY_ID1, &phy_id_high);
    if (ret_val)
        return ret_val;

    hw->phy_id = (u32) (phy_id_high << 16);
    udelay(20);
    ret_val = e1000_read_phy_reg(hw, PHY_ID2, &phy_id_low);
    if (ret_val)
        return ret_val;

    hw->phy_id |= (u32) (phy_id_low & PHY_REVISION_MASK);
    hw->phy_revision = (u32) phy_id_low & ~PHY_REVISION_MASK;

    switch (hw->mac_type) {
    case e1000_82543:
        if (hw->phy_id == M88E1000_E_PHY_ID) match = true;
        break;
    case e1000_82544:
        if (hw->phy_id == M88E1000_I_PHY_ID) match = true;
        break;
    case e1000_82540:
    case e1000_82545:
    case e1000_82545_rev_3:
    case e1000_82546:
    case e1000_82546_rev_3:
        if (hw->phy_id == M88E1011_I_PHY_ID) match = true;
        break;
    case e1000_82541:
    case e1000_82541_rev_2:
    case e1000_82547:
    case e1000_82547_rev_2:
        if (hw->phy_id == IGP01E1000_I_PHY_ID) match = true;
        break;
    case e1000_82573:
        if (hw->phy_id == M88E1111_I_PHY_ID) match = true;
        break;
    case e1000_80003es2lan:
        if (hw->phy_id == GG82563_E_PHY_ID) match = true;
        break;
    case e1000_ich8lan:
        if (hw->phy_id == IGP03E1000_E_PHY_ID) match = true;
        if (hw->phy_id == IFE_E_PHY_ID) match = true;
        if (hw->phy_id == IFE_PLUS_E_PHY_ID) match = true;
        if (hw->phy_id == IFE_C_E_PHY_ID) match = true;
        break;
    default:
        DEBUGOUT1("Invalid MAC type %d\n", hw->mac_type);
        return -E1000_ERR_CONFIG;
    }
    phy_init_status = e1000_set_phy_type(hw);

    if ((match) && (phy_init_status == E1000_SUCCESS)) {
        DEBUGOUT1("PHY ID 0x%X detected\n", hw->phy_id);
        return E1000_SUCCESS;
    }
    DEBUGOUT1("Invalid PHY ID 0x%X\n", hw->phy_id);
    return -E1000_ERR_PHY;
}

/******************************************************************************
* Resets the PHY's DSP
*
* hw - Struct containing variables accessed by shared code
******************************************************************************/
static s32
e1000_phy_reset_dsp(struct e1000_hw *hw)
{
    s32 ret_val;
    DEBUGFUNC("e1000_phy_reset_dsp");

    do {
        if (hw->phy_type != e1000_phy_gg82563) {
            ret_val = e1000_write_phy_reg(hw, 29, 0x001d);
            if (ret_val) break;
        }
        ret_val = e1000_write_phy_reg(hw, 30, 0x00c1);
        if (ret_val) break;
        ret_val = e1000_write_phy_reg(hw, 30, 0x0000);
        if (ret_val) break;
        ret_val = E1000_SUCCESS;
    } while (0);

    return ret_val;
}

/******************************************************************************
* Get PHY information from various PHY registers for igp PHY only.
*
* hw - Struct containing variables accessed by shared code
* phy_info - PHY information structure
******************************************************************************/
static s32
e1000_phy_igp_get_info(struct e1000_hw *hw,
                       struct e1000_phy_info *phy_info)
{
    s32 ret_val;
    u16 phy_data, min_length, max_length, average;
    e1000_rev_polarity polarity;

    DEBUGFUNC("e1000_phy_igp_get_info");

    /* The downshift status is checked only once, after link is established,
     * and it stored in the hw->speed_downgraded parameter. */
    phy_info->downshift = (e1000_downshift)hw->speed_downgraded;

    /* IGP01E1000 does not need to support it. */
    phy_info->extended_10bt_distance = e1000_10bt_ext_dist_enable_normal;

    /* IGP01E1000 always correct polarity reversal */
    phy_info->polarity_correction = e1000_polarity_reversal_enabled;

    /* Check polarity status */
    ret_val = e1000_check_polarity(hw, &polarity);
    if (ret_val)
        return ret_val;

    phy_info->cable_polarity = polarity;

    ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS, &phy_data);
    if (ret_val)
        return ret_val;

    phy_info->mdix_mode = (e1000_auto_x_mode)((phy_data & IGP01E1000_PSSR_MDIX) >>
                          IGP01E1000_PSSR_MDIX_SHIFT);

    if ((phy_data & IGP01E1000_PSSR_SPEED_MASK) ==
       IGP01E1000_PSSR_SPEED_1000MBPS) {
        /* Local/Remote Receiver Information are only valid at 1000 Mbps */
        ret_val = e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_data);
        if (ret_val)
            return ret_val;

        phy_info->local_rx = ((phy_data & SR_1000T_LOCAL_RX_STATUS) >>
                             SR_1000T_LOCAL_RX_STATUS_SHIFT) ?
                             e1000_1000t_rx_status_ok : e1000_1000t_rx_status_not_ok;
        phy_info->remote_rx = ((phy_data & SR_1000T_REMOTE_RX_STATUS) >>
                              SR_1000T_REMOTE_RX_STATUS_SHIFT) ?
                              e1000_1000t_rx_status_ok : e1000_1000t_rx_status_not_ok;

        /* Get cable length */
        ret_val = e1000_get_cable_length(hw, &min_length, &max_length);
        if (ret_val)
            return ret_val;

        /* Translate to old method */
        average = (max_length + min_length) / 2;

        if (average <= e1000_igp_cable_length_50)
            phy_info->cable_length = e1000_cable_length_50;
        else if (average <= e1000_igp_cable_length_80)
            phy_info->cable_length = e1000_cable_length_50_80;
        else if (average <= e1000_igp_cable_length_110)
            phy_info->cable_length = e1000_cable_length_80_110;
        else if (average <= e1000_igp_cable_length_140)
            phy_info->cable_length = e1000_cable_length_110_140;
        else
            phy_info->cable_length = e1000_cable_length_140;
    }

    return E1000_SUCCESS;
}

/******************************************************************************
* Get PHY information from various PHY registers for ife PHY only.
*
* hw - Struct containing variables accessed by shared code
* phy_info - PHY information structure
******************************************************************************/
static s32
e1000_phy_ife_get_info(struct e1000_hw *hw,
                       struct e1000_phy_info *phy_info)
{
    s32 ret_val;
    u16 phy_data;
    e1000_rev_polarity polarity;

    DEBUGFUNC("e1000_phy_ife_get_info");

    phy_info->downshift = (e1000_downshift)hw->speed_downgraded;
    phy_info->extended_10bt_distance = e1000_10bt_ext_dist_enable_normal;

    ret_val = e1000_read_phy_reg(hw, IFE_PHY_SPECIAL_CONTROL, &phy_data);
    if (ret_val)
        return ret_val;
    phy_info->polarity_correction =
                        ((phy_data & IFE_PSC_AUTO_POLARITY_DISABLE) >>
                        IFE_PSC_AUTO_POLARITY_DISABLE_SHIFT) ?
                        e1000_polarity_reversal_disabled : e1000_polarity_reversal_enabled;

    if (phy_info->polarity_correction == e1000_polarity_reversal_enabled) {
        ret_val = e1000_check_polarity(hw, &polarity);
        if (ret_val)
            return ret_val;
    } else {
        /* Polarity is forced. */
        polarity = ((phy_data & IFE_PSC_FORCE_POLARITY) >>
                     IFE_PSC_FORCE_POLARITY_SHIFT) ?
                     e1000_rev_polarity_reversed : e1000_rev_polarity_normal;
    }
    phy_info->cable_polarity = polarity;

    ret_val = e1000_read_phy_reg(hw, IFE_PHY_MDIX_CONTROL, &phy_data);
    if (ret_val)
        return ret_val;

    phy_info->mdix_mode = (e1000_auto_x_mode)
                     ((phy_data & (IFE_PMC_AUTO_MDIX | IFE_PMC_FORCE_MDIX)) >>
                     IFE_PMC_MDIX_MODE_SHIFT);

    return E1000_SUCCESS;
}

/******************************************************************************
* Get PHY information from various PHY registers fot m88 PHY only.
*
* hw - Struct containing variables accessed by shared code
* phy_info - PHY information structure
******************************************************************************/
static s32
e1000_phy_m88_get_info(struct e1000_hw *hw,
                       struct e1000_phy_info *phy_info)
{
    s32 ret_val;
    u16 phy_data;
    e1000_rev_polarity polarity;

    DEBUGFUNC("e1000_phy_m88_get_info");

    /* The downshift status is checked only once, after link is established,
     * and it stored in the hw->speed_downgraded parameter. */
    phy_info->downshift = (e1000_downshift)hw->speed_downgraded;

    ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
    if (ret_val)
        return ret_val;

    phy_info->extended_10bt_distance =
        ((phy_data & M88E1000_PSCR_10BT_EXT_DIST_ENABLE) >>
        M88E1000_PSCR_10BT_EXT_DIST_ENABLE_SHIFT) ?
        e1000_10bt_ext_dist_enable_lower : e1000_10bt_ext_dist_enable_normal;

    phy_info->polarity_correction =
        ((phy_data & M88E1000_PSCR_POLARITY_REVERSAL) >>
        M88E1000_PSCR_POLARITY_REVERSAL_SHIFT) ?
        e1000_polarity_reversal_disabled : e1000_polarity_reversal_enabled;

    /* Check polarity status */
    ret_val = e1000_check_polarity(hw, &polarity);
    if (ret_val)
        return ret_val;
    phy_info->cable_polarity = polarity;

    ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data);
    if (ret_val)
        return ret_val;

    phy_info->mdix_mode = (e1000_auto_x_mode)((phy_data & M88E1000_PSSR_MDIX) >>
                          M88E1000_PSSR_MDIX_SHIFT);

    if ((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS) {
        /* Cable Length Estimation and Local/Remote Receiver Information
         * are only valid at 1000 Mbps.
         */
        if (hw->phy_type != e1000_phy_gg82563) {
            phy_info->cable_length = (e1000_cable_length)((phy_data & M88E1000_PSSR_CABLE_LENGTH) >>
                                      M88E1000_PSSR_CABLE_LENGTH_SHIFT);
        } else {
            ret_val = e1000_read_phy_reg(hw, GG82563_PHY_DSP_DISTANCE,
                                         &phy_data);
            if (ret_val)
                return ret_val;

            phy_info->cable_length = (e1000_cable_length)(phy_data & GG82563_DSPD_CABLE_LENGTH);
        }

        ret_val = e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_data);
        if (ret_val)
            return ret_val;

        phy_info->local_rx = ((phy_data & SR_1000T_LOCAL_RX_STATUS) >>
                             SR_1000T_LOCAL_RX_STATUS_SHIFT) ?
                             e1000_1000t_rx_status_ok : e1000_1000t_rx_status_not_ok;
        phy_info->remote_rx = ((phy_data & SR_1000T_REMOTE_RX_STATUS) >>
                              SR_1000T_REMOTE_RX_STATUS_SHIFT) ?
                              e1000_1000t_rx_status_ok : e1000_1000t_rx_status_not_ok;

    }

    return E1000_SUCCESS;
}

/******************************************************************************
* Get PHY information from various PHY registers
*
* hw - Struct containing variables accessed by shared code
* phy_info - PHY information structure
******************************************************************************/
s32
e1000_phy_get_info(struct e1000_hw *hw,
                   struct e1000_phy_info *phy_info)
{
    s32 ret_val;
    u16 phy_data;

    DEBUGFUNC("e1000_phy_get_info");

    phy_info->cable_length = e1000_cable_length_undefined;
    phy_info->extended_10bt_distance = e1000_10bt_ext_dist_enable_undefined;
    phy_info->cable_polarity = e1000_rev_polarity_undefined;
    phy_info->downshift = e1000_downshift_undefined;
    phy_info->polarity_correction = e1000_polarity_reversal_undefined;
    phy_info->mdix_mode = e1000_auto_x_mode_undefined;
    phy_info->local_rx = e1000_1000t_rx_status_undefined;
    phy_info->remote_rx = e1000_1000t_rx_status_undefined;

    if (hw->media_type != e1000_media_type_copper) {
        DEBUGOUT("PHY info is only valid for copper media\n");
        return -E1000_ERR_CONFIG;
    }

    ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
    if (ret_val)
        return ret_val;

    ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
    if (ret_val)
        return ret_val;

    if ((phy_data & MII_SR_LINK_STATUS) != MII_SR_LINK_STATUS) {
        DEBUGOUT("PHY info is only valid if link is up\n");
        return -E1000_ERR_CONFIG;
    }

    if (hw->phy_type == e1000_phy_igp ||
        hw->phy_type == e1000_phy_igp_3 ||
        hw->phy_type == e1000_phy_igp_2)
        return e1000_phy_igp_get_info(hw, phy_info);
    else if (hw->phy_type == e1000_phy_ife)
        return e1000_phy_ife_get_info(hw, phy_info);
    else
        return e1000_phy_m88_get_info(hw, phy_info);
}

s32
e1000_validate_mdi_setting(struct e1000_hw *hw)
{
    DEBUGFUNC("e1000_validate_mdi_settings");

    if (!hw->autoneg && (hw->mdix == 0 || hw->mdix == 3)) {
        DEBUGOUT("Invalid MDI setting detected\n");
        hw->mdix = 1;
        return -E1000_ERR_CONFIG;
    }
    return E1000_SUCCESS;
}


/******************************************************************************
 * Sets up eeprom variables in the hw struct.  Must be called after mac_type
 * is configured.  Additionally, if this is ICH8, the flash controller GbE
 * registers must be mapped, or this will crash.
 *
 * hw - Struct containing variables accessed by shared code
 *****************************************************************************/
s32
e1000_init_eeprom_params(struct e1000_hw *hw)
{
    struct e1000_eeprom_info *eeprom = &hw->eeprom;
    u32 eecd = E1000_READ_REG(hw, EECD);
    s32 ret_val = E1000_SUCCESS;
    u16 eeprom_size;

    DEBUGFUNC("e1000_init_eeprom_params");

    switch (hw->mac_type) {
    case e1000_82542_rev2_0:
    case e1000_82542_rev2_1:
    case e1000_82543:
    case e1000_82544:
        eeprom->type = e1000_eeprom_microwire;
        eeprom->word_size = 64;
        eeprom->opcode_bits = 3;
        eeprom->address_bits = 6;
        eeprom->delay_usec = 50;
        eeprom->use_eerd = false;
        eeprom->use_eewr = false;
        break;
    case e1000_82540:
    case e1000_82545:
    case e1000_82545_rev_3:
    case e1000_82546:
    case e1000_82546_rev_3:
        eeprom->type = e1000_eeprom_microwire;
        eeprom->opcode_bits = 3;
        eeprom->delay_usec = 50;
        if (eecd & E1000_EECD_SIZE) {
            eeprom->word_size = 256;
            eeprom->address_bits = 8;
        } else {
            eeprom->word_size = 64;
            eeprom->address_bits = 6;
        }
        eeprom->use_eerd = false;
        eeprom->use_eewr = false;
        break;
    case e1000_82541:
    case e1000_82541_rev_2:
    case e1000_82547:
    case e1000_82547_rev_2:
        if (eecd & E1000_EECD_TYPE) {
            eeprom->type = e1000_eeprom_spi;
            eeprom->opcode_bits = 8;
            eeprom->delay_usec = 1;
            if (eecd & E1000_EECD_ADDR_BITS) {
                eeprom->page_size = 32;
                eeprom->address_bits = 16;
            } else {
                eeprom->page_size = 8;
                eeprom->address_bits = 8;
            }
        } else {
            eeprom->type = e1000_eeprom_microwire;
            eeprom->opcode_bits = 3;
            eeprom->delay_usec = 50;
            if (eecd & E1000_EECD_ADDR_BITS) {
                eeprom->word_size = 256;
                eeprom->address_bits = 8;
            } else {
                eeprom->word_size = 64;
                eeprom->address_bits = 6;
            }
        }
        eeprom->use_eerd = false;
        eeprom->use_eewr = false;
        break;
    case e1000_82571:
    case e1000_82572:
        eeprom->type = e1000_eeprom_spi;
        eeprom->opcode_bits = 8;
        eeprom->delay_usec = 1;
        if (eecd & E1000_EECD_ADDR_BITS) {
            eeprom->page_size = 32;
            eeprom->address_bits = 16;
        } else {
            eeprom->page_size = 8;
            eeprom->address_bits = 8;
        }
        eeprom->use_eerd = false;
        eeprom->use_eewr = false;
        break;
    case e1000_82573:
        eeprom->type = e1000_eeprom_spi;
        eeprom->opcode_bits = 8;
        eeprom->delay_usec = 1;
        if (eecd & E1000_EECD_ADDR_BITS) {
            eeprom->page_size = 32;
            eeprom->address_bits = 16;
        } else {
            eeprom->page_size = 8;
            eeprom->address_bits = 8;
        }
        eeprom->use_eerd = true;
        eeprom->use_eewr = true;
        if (!e1000_is_onboard_nvm_eeprom(hw)) {
            eeprom->type = e1000_eeprom_flash;
            eeprom->word_size = 2048;

            /* Ensure that the Autonomous FLASH update bit is cleared due to
             * Flash update issue on parts which use a FLASH for NVM. */
            eecd &= ~E1000_EECD_AUPDEN;
            E1000_WRITE_REG(hw, EECD, eecd);
        }
        break;
    case e1000_80003es2lan:
        eeprom->type = e1000_eeprom_spi;
        eeprom->opcode_bits = 8;
        eeprom->delay_usec = 1;
        if (eecd & E1000_EECD_ADDR_BITS) {
            eeprom->page_size = 32;
            eeprom->address_bits = 16;
        } else {
            eeprom->page_size = 8;
            eeprom->address_bits = 8;
        }
        eeprom->use_eerd = true;
        eeprom->use_eewr = false;
        break;
    case e1000_ich8lan:
        {
        s32  i = 0;
        u32 flash_size = E1000_READ_ICH_FLASH_REG(hw, ICH_FLASH_GFPREG);

        eeprom->type = e1000_eeprom_ich8;
        eeprom->use_eerd = false;
        eeprom->use_eewr = false;
        eeprom->word_size = E1000_SHADOW_RAM_WORDS;

        /* Zero the shadow RAM structure. But don't load it from NVM
         * so as to save time for driver init */
        if (hw->eeprom_shadow_ram != NULL) {
            for (i = 0; i < E1000_SHADOW_RAM_WORDS; i++) {
                hw->eeprom_shadow_ram[i].modified = false;
                hw->eeprom_shadow_ram[i].eeprom_word = 0xFFFF;
            }
        }

        hw->flash_base_addr = (flash_size & ICH_GFPREG_BASE_MASK) *
                              ICH_FLASH_SECTOR_SIZE;

        hw->flash_bank_size = ((flash_size >> 16) & ICH_GFPREG_BASE_MASK) + 1;
        hw->flash_bank_size -= (flash_size & ICH_GFPREG_BASE_MASK);

        hw->flash_bank_size *= ICH_FLASH_SECTOR_SIZE;

        hw->flash_bank_size /= 2 * sizeof(u16);

        break;
        }
    default:
        break;
    }

    if (eeprom->type == e1000_eeprom_spi) {
        /* eeprom_size will be an enum [0..8] that maps to eeprom sizes 128B to
         * 32KB (incremented by powers of 2).
         */
        if (hw->mac_type <= e1000_82547_rev_2) {
            /* Set to default value for initial eeprom read. */
            eeprom->word_size = 64;
            ret_val = e1000_read_eeprom(hw, EEPROM_CFG, 1, &eeprom_size);
            if (ret_val)
                return ret_val;
            eeprom_size = (eeprom_size & EEPROM_SIZE_MASK) >> EEPROM_SIZE_SHIFT;
            /* 256B eeprom size was not supported in earlier hardware, so we
             * bump eeprom_size up one to ensure that "1" (which maps to 256B)
             * is never the result used in the shifting logic below. */
            if (eeprom_size)
                eeprom_size++;
        } else {
            eeprom_size = (u16)((eecd & E1000_EECD_SIZE_EX_MASK) >>
                          E1000_EECD_SIZE_EX_SHIFT);
        }

        eeprom->word_size = 1 << (eeprom_size + EEPROM_WORD_SIZE_SHIFT);
    }
    return ret_val;
}

/******************************************************************************
 * Raises the EEPROM's clock input.
 *
 * hw - Struct containing variables accessed by shared code
 * eecd - EECD's current value
 *****************************************************************************/
static void
e1000_raise_ee_clk(struct e1000_hw *hw,
                   u32 *eecd)
{
    /* Raise the clock input to the EEPROM (by setting the SK bit), and then
     * wait <delay> microseconds.
     */
    *eecd = *eecd | E1000_EECD_SK;
    E1000_WRITE_REG(hw, EECD, *eecd);
    E1000_WRITE_FLUSH(hw);
    udelay(hw->eeprom.delay_usec);
}

/******************************************************************************
 * Lowers the EEPROM's clock input.
 *
 * hw - Struct containing variables accessed by shared code
 * eecd - EECD's current value
 *****************************************************************************/
static void
e1000_lower_ee_clk(struct e1000_hw *hw,
                   u32 *eecd)
{
    /* Lower the clock input to the EEPROM (by clearing the SK bit), and then
     * wait 50 microseconds.
     */
    *eecd = *eecd & ~E1000_EECD_SK;
    E1000_WRITE_REG(hw, EECD, *eecd);
    E1000_WRITE_FLUSH(hw);
    udelay(hw->eeprom.delay_usec);
}

/******************************************************************************
 * Shift data bits out to the EEPROM.
 *
 * hw - Struct containing variables accessed by shared code
 * data - data to send to the EEPROM
 * count - number of bits to shift out
 *****************************************************************************/
static void
e1000_shift_out_ee_bits(struct e1000_hw *hw,
                        u16 data,
                        u16 count)
{
    struct e1000_eeprom_info *eeprom = &hw->eeprom;
    u32 eecd;
    u32 mask;

    /* We need to shift "count" bits out to the EEPROM. So, value in the
     * "data" parameter will be shifted out to the EEPROM one bit at a time.
     * In order to do this, "data" must be broken down into bits.
     */
    mask = 0x01 << (count - 1);
    eecd = E1000_READ_REG(hw, EECD);
    if (eeprom->type == e1000_eeprom_microwire) {
        eecd &= ~E1000_EECD_DO;
    } else if (eeprom->type == e1000_eeprom_spi) {
        eecd |= E1000_EECD_DO;
    }
    do {
        /* A "1" is shifted out to the EEPROM by setting bit "DI" to a "1",
         * and then raising and then lowering the clock (the SK bit controls
         * the clock input to the EEPROM).  A "0" is shifted out to the EEPROM
         * by setting "DI" to "0" and then raising and then lowering the clock.
         */
        eecd &= ~E1000_EECD_DI;

        if (data & mask)
            eecd |= E1000_EECD_DI;

        E1000_WRITE_REG(hw, EECD, eecd);
        E1000_WRITE_FLUSH(hw);

        udelay(eeprom->delay_usec);

        e1000_raise_ee_clk(hw, &eecd);
        e1000_lower_ee_clk(hw, &eecd);

        mask = mask >> 1;

    } while (mask);

    /* We leave the "DI" bit set to "0" when we leave this routine. */
    eecd &= ~E1000_EECD_DI;
    E1000_WRITE_REG(hw, EECD, eecd);
}

/******************************************************************************
 * Shift data bits in from the EEPROM
 *
 * hw - Struct containing variables accessed by shared code
 *****************************************************************************/
static u16
e1000_shift_in_ee_bits(struct e1000_hw *hw,
                       u16 count)
{
    u32 eecd;
    u32 i;
    u16 data;

    /* In order to read a register from the EEPROM, we need to shift 'count'
     * bits in from the EEPROM. Bits are "shifted in" by raising the clock
     * input to the EEPROM (setting the SK bit), and then reading the value of
     * the "DO" bit.  During this "shifting in" process the "DI" bit should
     * always be clear.
     */

    eecd = E1000_READ_REG(hw, EECD);

    eecd &= ~(E1000_EECD_DO | E1000_EECD_DI);
    data = 0;

    for (i = 0; i < count; i++) {
        data = data << 1;
        e1000_raise_ee_clk(hw, &eecd);

        eecd = E1000_READ_REG(hw, EECD);

        eecd &= ~(E1000_EECD_DI);
        if (eecd & E1000_EECD_DO)
            data |= 1;

        e1000_lower_ee_clk(hw, &eecd);
    }

    return data;
}

/******************************************************************************
 * Prepares EEPROM for access
 *
 * hw - Struct containing variables accessed by shared code
 *
 * Lowers EEPROM clock. Clears input pin. Sets the chip select pin. This
 * function should be called before issuing a command to the EEPROM.
 *****************************************************************************/
static s32
e1000_acquire_eeprom(struct e1000_hw *hw)
{
    struct e1000_eeprom_info *eeprom = &hw->eeprom;
    u32 eecd, i=0;

    DEBUGFUNC("e1000_acquire_eeprom");

    if (e1000_swfw_sync_acquire(hw, E1000_SWFW_EEP_SM))
        return -E1000_ERR_SWFW_SYNC;
    eecd = E1000_READ_REG(hw, EECD);

    if (hw->mac_type != e1000_82573) {
        /* Request EEPROM Access */
        if (hw->mac_type > e1000_82544) {
            eecd |= E1000_EECD_REQ;
            E1000_WRITE_REG(hw, EECD, eecd);
            eecd = E1000_READ_REG(hw, EECD);
            while ((!(eecd & E1000_EECD_GNT)) &&
                  (i < E1000_EEPROM_GRANT_ATTEMPTS)) {
                i++;
                udelay(5);
                eecd = E1000_READ_REG(hw, EECD);
            }
            if (!(eecd & E1000_EECD_GNT)) {
                eecd &= ~E1000_EECD_REQ;
                E1000_WRITE_REG(hw, EECD, eecd);
                DEBUGOUT("Could not acquire EEPROM grant\n");
                e1000_swfw_sync_release(hw, E1000_SWFW_EEP_SM);
                return -E1000_ERR_EEPROM;
            }
        }
    }

    /* Setup EEPROM for Read/Write */

    if (eeprom->type == e1000_eeprom_microwire) {
        /* Clear SK and DI */
        eecd &= ~(E1000_EECD_DI | E1000_EECD_SK);
        E1000_WRITE_REG(hw, EECD, eecd);

        /* Set CS */
        eecd |= E1000_EECD_CS;
        E1000_WRITE_REG(hw, EECD, eecd);
    } else if (eeprom->type == e1000_eeprom_spi) {
        /* Clear SK and CS */
        eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
        E1000_WRITE_REG(hw, EECD, eecd);
        udelay(1);
    }

    return E1000_SUCCESS;
}

/******************************************************************************
 * Returns EEPROM to a "standby" state
 *
 * hw - Struct containing variables accessed by shared code
 *****************************************************************************/
static void
e1000_standby_eeprom(struct e1000_hw *hw)
{
    struct e1000_eeprom_info *eeprom = &hw->eeprom;
    u32 eecd;

    eecd = E1000_READ_REG(hw, EECD);

    if (eeprom->type == e1000_eeprom_microwire) {
        eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
        E1000_WRITE_REG(hw, EECD, eecd);
        E1000_WRITE_FLUSH(hw);
        udelay(eeprom->delay_usec);

        /* Clock high */
        eecd |= E1000_EECD_SK;
        E1000_WRITE_REG(hw, EECD, eecd);
        E1000_WRITE_FLUSH(hw);
        udelay(eeprom->delay_usec);

        /* Select EEPROM */
        eecd |= E1000_EECD_CS;
        E1000_WRITE_REG(hw, EECD, eecd);
        E1000_WRITE_FLUSH(hw);
        udelay(eeprom->delay_usec);

        /* Clock low */
        eecd &= ~E1000_EECD_SK;
        E1000_WRITE_REG(hw, EECD, eecd);
        E1000_WRITE_FLUSH(hw);
        udelay(eeprom->delay_usec);
    } else if (eeprom->type == e1000_eeprom_spi) {
        /* Toggle CS to flush commands */
        eecd |= E1000_EECD_CS;
        E1000_WRITE_REG(hw, EECD, eecd);
        E1000_WRITE_FLUSH(hw);
        udelay(eeprom->delay_usec);
        eecd &= ~E1000_EECD_CS;
        E1000_WRITE_REG(hw, EECD, eecd);
        E1000_WRITE_FLUSH(hw);
        udelay(eeprom->delay_usec);
    }
}

/******************************************************************************
 * Terminates a command by inverting the EEPROM's chip select pin
 *
 * hw - Struct containing variables accessed by shared code
 *****************************************************************************/
static void
e1000_release_eeprom(struct e1000_hw *hw)
{
    u32 eecd;

    DEBUGFUNC("e1000_release_eeprom");

    eecd = E1000_READ_REG(hw, EECD);

    if (hw->eeprom.type == e1000_eeprom_spi) {
        eecd |= E1000_EECD_CS;  /* Pull CS high */
        eecd &= ~E1000_EECD_SK; /* Lower SCK */

        E1000_WRITE_REG(hw, EECD, eecd);

        udelay(hw->eeprom.delay_usec);
    } else if (hw->eeprom.type == e1000_eeprom_microwire) {
        /* cleanup eeprom */

        /* CS on Microwire is active-high */
        eecd &= ~(E1000_EECD_CS | E1000_EECD_DI);

        E1000_WRITE_REG(hw, EECD, eecd);

        /* Rising edge of clock */
        eecd |= E1000_EECD_SK;
        E1000_WRITE_REG(hw, EECD, eecd);
        E1000_WRITE_FLUSH(hw);
        udelay(hw->eeprom.delay_usec);

        /* Falling edge of clock */
        eecd &= ~E1000_EECD_SK;
        E1000_WRITE_REG(hw, EECD, eecd);
        E1000_WRITE_FLUSH(hw);
        udelay(hw->eeprom.delay_usec);
    }

    /* Stop requesting EEPROM access */
    if (hw->mac_type > e1000_82544) {
        eecd &= ~E1000_EECD_REQ;
        E1000_WRITE_REG(hw, EECD, eecd);
    }

    e1000_swfw_sync_release(hw, E1000_SWFW_EEP_SM);
}

/******************************************************************************
 * Reads a 16 bit word from the EEPROM.
 *
 * hw - Struct containing variables accessed by shared code
 *****************************************************************************/
static s32
e1000_spi_eeprom_ready(struct e1000_hw *hw)
{
    u16 retry_count = 0;
    u8 spi_stat_reg;

    DEBUGFUNC("e1000_spi_eeprom_ready");

    /* Read "Status Register" repeatedly until the LSB is cleared.  The
     * EEPROM will signal that the command has been completed by clearing
     * bit 0 of the internal status register.  If it's not cleared within
     * 5 milliseconds, then error out.
     */
    retry_count = 0;
    do {
        e1000_shift_out_ee_bits(hw, EEPROM_RDSR_OPCODE_SPI,
                                hw->eeprom.opcode_bits);
        spi_stat_reg = (u8)e1000_shift_in_ee_bits(hw, 8);
        if (!(spi_stat_reg & EEPROM_STATUS_RDY_SPI))
            break;

        udelay(5);
        retry_count += 5;

        e1000_standby_eeprom(hw);
    } while (retry_count < EEPROM_MAX_RETRY_SPI);

    /* ATMEL SPI write time could vary from 0-20mSec on 3.3V devices (and
     * only 0-5mSec on 5V devices)
     */
    if (retry_count >= EEPROM_MAX_RETRY_SPI) {
        DEBUGOUT("SPI EEPROM Status error\n");
        return -E1000_ERR_EEPROM;
    }

    return E1000_SUCCESS;
}

/******************************************************************************
 * Reads a 16 bit word from the EEPROM.
 *
 * hw - Struct containing variables accessed by shared code
 * offset - offset of  word in the EEPROM to read
 * data - word read from the EEPROM
 * words - number of words to read
 *****************************************************************************/
s32
e1000_read_eeprom(struct e1000_hw *hw,
                  u16 offset,
                  u16 words,
                  u16 *data)
{
    struct e1000_eeprom_info *eeprom = &hw->eeprom;
    u32 i = 0;

    DEBUGFUNC("e1000_read_eeprom");

    /* If eeprom is not yet detected, do so now */
    if (eeprom->word_size == 0)
        e1000_init_eeprom_params(hw);

    /* A check for invalid values:  offset too large, too many words, and not
     * enough words.
     */
    if ((offset >= eeprom->word_size) || (words > eeprom->word_size - offset) ||
       (words == 0)) {
        DEBUGOUT2("\"words\" parameter out of bounds. Words = %d, size = %d\n", offset, eeprom->word_size);
        return -E1000_ERR_EEPROM;
    }

    /* EEPROM's that don't use EERD to read require us to bit-bang the SPI
     * directly. In this case, we need to acquire the EEPROM so that
     * FW or other port software does not interrupt.
     */
    if (e1000_is_onboard_nvm_eeprom(hw) && !hw->eeprom.use_eerd) {
        /* Prepare the EEPROM for bit-bang reading */
        if (e1000_acquire_eeprom(hw) != E1000_SUCCESS)
            return -E1000_ERR_EEPROM;
    }

    /* Eerd register EEPROM access requires no eeprom aquire/release */
    if (eeprom->use_eerd)
        return e1000_read_eeprom_eerd(hw, offset, words, data);

    /* ICH EEPROM access is done via the ICH flash controller */
    if (eeprom->type == e1000_eeprom_ich8)
        return e1000_read_eeprom_ich8(hw, offset, words, data);

    /* Set up the SPI or Microwire EEPROM for bit-bang reading.  We have
     * acquired the EEPROM at this point, so any returns should relase it */
    if (eeprom->type == e1000_eeprom_spi) {
        u16 word_in;
        u8 read_opcode = EEPROM_READ_OPCODE_SPI;

        if (e1000_spi_eeprom_ready(hw)) {
            e1000_release_eeprom(hw);
            return -E1000_ERR_EEPROM;
        }

        e1000_standby_eeprom(hw);

        /* Some SPI eeproms use the 8th address bit embedded in the opcode */
        if ((eeprom->address_bits == 8) && (offset >= 128))
            read_opcode |= EEPROM_A8_OPCODE_SPI;

        /* Send the READ command (opcode + addr)  */
        e1000_shift_out_ee_bits(hw, read_opcode, eeprom->opcode_bits);
        e1000_shift_out_ee_bits(hw, (u16)(offset*2), eeprom->address_bits);

        /* Read the data.  The address of the eeprom internally increments with
         * each byte (spi) being read, saving on the overhead of eeprom setup
         * and tear-down.  The address counter will roll over if reading beyond
         * the size of the eeprom, thus allowing the entire memory to be read
         * starting from any offset. */
        for (i = 0; i < words; i++) {
            word_in = e1000_shift_in_ee_bits(hw, 16);
            data[i] = (word_in >> 8) | (word_in << 8);
        }
    } else if (eeprom->type == e1000_eeprom_microwire) {
        for (i = 0; i < words; i++) {
            /* Send the READ command (opcode + addr)  */
            e1000_shift_out_ee_bits(hw, EEPROM_READ_OPCODE_MICROWIRE,
                                    eeprom->opcode_bits);
            e1000_shift_out_ee_bits(hw, (u16)(offset + i),
                                    eeprom->address_bits);

            /* Read the data.  For microwire, each word requires the overhead
             * of eeprom setup and tear-down. */
            data[i] = e1000_shift_in_ee_bits(hw, 16);
            e1000_standby_eeprom(hw);
        }
    }

    /* End this read operation */
    e1000_release_eeprom(hw);

    return E1000_SUCCESS;
}

/******************************************************************************
 * Reads a 16 bit word from the EEPROM using the EERD register.
 *
 * hw - Struct containing variables accessed by shared code
 * offset - offset of  word in the EEPROM to read
 * data - word read from the EEPROM
 * words - number of words to read
 *****************************************************************************/
static s32
e1000_read_eeprom_eerd(struct e1000_hw *hw,
                  u16 offset,
                  u16 words,
                  u16 *data)
{
    u32 i, eerd = 0;
    s32 error = 0;

    for (i = 0; i < words; i++) {
        eerd = ((offset+i) << E1000_EEPROM_RW_ADDR_SHIFT) +
                         E1000_EEPROM_RW_REG_START;

        E1000_WRITE_REG(hw, EERD, eerd);
        error = e1000_poll_eerd_eewr_done(hw, E1000_EEPROM_POLL_READ);

        if (error) {
            break;
        }
        data[i] = (E1000_READ_REG(hw, EERD) >> E1000_EEPROM_RW_REG_DATA);

    }

    return error;
}

/******************************************************************************
 * Writes a 16 bit word from the EEPROM using the EEWR register.
 *
 * hw - Struct containing variables accessed by shared code
 * offset - offset of  word in the EEPROM to read
 * data - word read from the EEPROM
 * words - number of words to read
 *****************************************************************************/
static s32
e1000_write_eeprom_eewr(struct e1000_hw *hw,
                   u16 offset,
                   u16 words,
                   u16 *data)
{
    u32    register_value = 0;
    u32    i              = 0;
    s32     error          = 0;

    if (e1000_swfw_sync_acquire(hw, E1000_SWFW_EEP_SM))
        return -E1000_ERR_SWFW_SYNC;

    for (i = 0; i < words; i++) {
        register_value = (data[i] << E1000_EEPROM_RW_REG_DATA) |
                         ((offset+i) << E1000_EEPROM_RW_ADDR_SHIFT) |
                         E1000_EEPROM_RW_REG_START;

        error = e1000_poll_eerd_eewr_done(hw, E1000_EEPROM_POLL_WRITE);
        if (error) {
            break;
        }

        E1000_WRITE_REG(hw, EEWR, register_value);

        error = e1000_poll_eerd_eewr_done(hw, E1000_EEPROM_POLL_WRITE);

        if (error) {
            break;
        }
    }

    e1000_swfw_sync_release(hw, E1000_SWFW_EEP_SM);
    return error;
}

/******************************************************************************
 * Polls the status bit (bit 1) of the EERD to determine when the read is done.
 *
 * hw - Struct containing variables accessed by shared code
 *****************************************************************************/
static s32
e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int eerd)
{
    u32 attempts = 100000;
    u32 i, reg = 0;
    s32 done = E1000_ERR_EEPROM;

    for (i = 0; i < attempts; i++) {
        if (eerd == E1000_EEPROM_POLL_READ)
            reg = E1000_READ_REG(hw, EERD);
        else
            reg = E1000_READ_REG(hw, EEWR);

        if (reg & E1000_EEPROM_RW_REG_DONE) {
            done = E1000_SUCCESS;
            break;
        }
        udelay(5);
    }

    return done;
}

/***************************************************************************
* Description:     Determines if the onboard NVM is FLASH or EEPROM.
*
* hw - Struct containing variables accessed by shared code
****************************************************************************/
static bool
e1000_is_onboard_nvm_eeprom(struct e1000_hw *hw)
{
    u32 eecd = 0;

    DEBUGFUNC("e1000_is_onboard_nvm_eeprom");

    if (hw->mac_type == e1000_ich8lan)
        return false;

    if (hw->mac_type == e1000_82573) {
        eecd = E1000_READ_REG(hw, EECD);

        /* Isolate bits 15 & 16 */
        eecd = ((eecd >> 15) & 0x03);

        /* If both bits are set, device is Flash type */
        if (eecd == 0x03) {
            return false;
        }
    }
    return true;
}

/******************************************************************************
 * Verifies that the EEPROM has a valid checksum
 *
 * hw - Struct containing variables accessed by shared code
 *
 * Reads the first 64 16 bit words of the EEPROM and sums the values read.
 * If the the sum of the 64 16 bit words is 0xBABA, the EEPROM's checksum is
 * valid.
 *****************************************************************************/
s32
e1000_validate_eeprom_checksum(struct e1000_hw *hw)
{
    u16 checksum = 0;
    u16 i, eeprom_data;

    DEBUGFUNC("e1000_validate_eeprom_checksum");

    if ((hw->mac_type == e1000_82573) && !e1000_is_onboard_nvm_eeprom(hw)) {
        /* Check bit 4 of word 10h.  If it is 0, firmware is done updating
         * 10h-12h.  Checksum may need to be fixed. */
        e1000_read_eeprom(hw, 0x10, 1, &eeprom_data);
        if ((eeprom_data & 0x10) == 0) {
            /* Read 0x23 and check bit 15.  This bit is a 1 when the checksum
             * has already been fixed.  If the checksum is still wrong and this
             * bit is a 1, we need to return bad checksum.  Otherwise, we need
             * to set this bit to a 1 and update the checksum. */
            e1000_read_eeprom(hw, 0x23, 1, &eeprom_data);
            if ((eeprom_data & 0x8000) == 0) {
                eeprom_data |= 0x8000;
                e1000_write_eeprom(hw, 0x23, 1, &eeprom_data);
                e1000_update_eeprom_checksum(hw);
            }
        }
    }

    if (hw->mac_type == e1000_ich8lan) {
        /* Drivers must allocate the shadow ram structure for the
         * EEPROM checksum to be updated.  Otherwise, this bit as well
         * as the checksum must both be set correctly for this
         * validation to pass.
         */
        e1000_read_eeprom(hw, 0x19, 1, &eeprom_data);
        if ((eeprom_data & 0x40) == 0) {
            eeprom_data |= 0x40;
            e1000_write_eeprom(hw, 0x19, 1, &eeprom_data);
            e1000_update_eeprom_checksum(hw);
        }
    }

    for (i = 0; i < (EEPROM_CHECKSUM_REG + 1); i++) {
        if (e1000_read_eeprom(hw, i, 1, &eeprom_data) < 0) {
            DEBUGOUT("EEPROM Read Error\n");
            return -E1000_ERR_EEPROM;
        }
        checksum += eeprom_data;
    }

    if (checksum == (u16) EEPROM_SUM)
        return E1000_SUCCESS;
    else {
        DEBUGOUT("EEPROM Checksum Invalid\n");
        return -E1000_ERR_EEPROM;
    }
}

/******************************************************************************
 * Calculates the EEPROM checksum and writes it to the EEPROM
 *
 * hw - Struct containing variables accessed by shared code
 *
 * Sums the first 63 16 bit words of the EEPROM. Subtracts the sum from 0xBABA.
 * Writes the difference to word offset 63 of the EEPROM.
 *****************************************************************************/
s32
e1000_update_eeprom_checksum(struct e1000_hw *hw)
{
    u32 ctrl_ext;
    u16 checksum = 0;
    u16 i, eeprom_data;

    DEBUGFUNC("e1000_update_eeprom_checksum");

    for (i = 0; i < EEPROM_CHECKSUM_REG; i++) {
        if (e1000_read_eeprom(hw, i, 1, &eeprom_data) < 0) {
            DEBUGOUT("EEPROM Read Error\n");
            return -E1000_ERR_EEPROM;
        }
        checksum += eeprom_data;
    }
    checksum = (u16) EEPROM_SUM - checksum;
    if (e1000_write_eeprom(hw, EEPROM_CHECKSUM_REG, 1, &checksum) < 0) {
        DEBUGOUT("EEPROM Write Error\n");
        return -E1000_ERR_EEPROM;
    } else if (hw->eeprom.type == e1000_eeprom_flash) {
        e1000_commit_shadow_ram(hw);
    } else if (hw->eeprom.type == e1000_eeprom_ich8) {
        e1000_commit_shadow_ram(hw);
        /* Reload the EEPROM, or else modifications will not appear
         * until after next adapter reset. */
        ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
        ctrl_ext |= E1000_CTRL_EXT_EE_RST;
        E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
        msleep(10);
    }
    return E1000_SUCCESS;
}

/******************************************************************************
 * Parent function for writing words to the different EEPROM types.
 *
 * hw - Struct containing variables accessed by shared code
 * offset - offset within the EEPROM to be written to
 * words - number of words to write
 * data - 16 bit word to be written to the EEPROM
 *
 * If e1000_update_eeprom_checksum is not called after this function, the
 * EEPROM will most likely contain an invalid checksum.
 *****************************************************************************/
s32
e1000_write_eeprom(struct e1000_hw *hw,
                   u16 offset,
                   u16 words,
                   u16 *data)
{
    struct e1000_eeprom_info *eeprom = &hw->eeprom;
    s32 status = 0;

    DEBUGFUNC("e1000_write_eeprom");

    /* If eeprom is not yet detected, do so now */
    if (eeprom->word_size == 0)
        e1000_init_eeprom_params(hw);

    /* A check for invalid values:  offset too large, too many words, and not
     * enough words.
     */
    if ((offset >= eeprom->word_size) || (words > eeprom->word_size - offset) ||
       (words == 0)) {
        DEBUGOUT("\"words\" parameter out of bounds\n");
        return -E1000_ERR_EEPROM;
    }

    /* 82573 writes only through eewr */
    if (eeprom->use_eewr)
        return e1000_write_eeprom_eewr(hw, offset, words, data);

    if (eeprom->type == e1000_eeprom_ich8)
        return e1000_write_eeprom_ich8(hw, offset, words, data);

    /* Prepare the EEPROM for writing  */
    if (e1000_acquire_eeprom(hw) != E1000_SUCCESS)
        return -E1000_ERR_EEPROM;

    if (eeprom->type == e1000_eeprom_microwire) {
        status = e1000_write_eeprom_microwire(hw, offset, words, data);
    } else {
        status = e1000_write_eeprom_spi(hw, offset, words, data);
        msleep(10);
    }

    /* Done with writing */
    e1000_release_eeprom(hw);

    return status;
}

/******************************************************************************
 * Writes a 16 bit word to a given offset in an SPI EEPROM.
 *
 * hw - Struct containing variables accessed by shared code
 * offset - offset within the EEPROM to be written to
 * words - number of words to write
 * data - pointer to array of 8 bit words to be written to the EEPROM
 *
 *****************************************************************************/
static s32
e1000_write_eeprom_spi(struct e1000_hw *hw,
                       u16 offset,
                       u16 words,
                       u16 *data)
{
    struct e1000_eeprom_info *eeprom = &hw->eeprom;
    u16 widx = 0;

    DEBUGFUNC("e1000_write_eeprom_spi");

    while (widx < words) {
        u8 write_opcode = EEPROM_WRITE_OPCODE_SPI;

        if (e1000_spi_eeprom_ready(hw)) return -E1000_ERR_EEPROM;

        e1000_standby_eeprom(hw);

        /*  Send the WRITE ENABLE command (8 bit opcode )  */
        e1000_shift_out_ee_bits(hw, EEPROM_WREN_OPCODE_SPI,
                                    eeprom->opcode_bits);

        e1000_standby_eeprom(hw);

        /* Some SPI eeproms use the 8th address bit embedded in the opcode */
        if ((eeprom->address_bits == 8) && (offset >= 128))
            write_opcode |= EEPROM_A8_OPCODE_SPI;

        /* Send the Write command (8-bit opcode + addr) */
        e1000_shift_out_ee_bits(hw, write_opcode, eeprom->opcode_bits);

        e1000_shift_out_ee_bits(hw, (u16)((offset + widx)*2),
                                eeprom->address_bits);

        /* Send the data */

        /* Loop to allow for up to whole page write (32 bytes) of eeprom */
        while (widx < words) {
            u16 word_out = data[widx];
            word_out = (word_out >> 8) | (word_out << 8);
            e1000_shift_out_ee_bits(hw, word_out, 16);
            widx++;

            /* Some larger eeprom sizes are capable of a 32-byte PAGE WRITE
             * operation, while the smaller eeproms are capable of an 8-byte
             * PAGE WRITE operation.  Break the inner loop to pass new address
             */
            if ((((offset + widx)*2) % eeprom->page_size) == 0) {
                e1000_standby_eeprom(hw);
                break;
            }
        }
    }

    return E1000_SUCCESS;
}

/******************************************************************************
 * Writes a 16 bit word to a given offset in a Microwire EEPROM.
 *
 * hw - Struct containing variables accessed by shared code
 * offset - offset within the EEPROM to be written to
 * words - number of words to write
 * data - pointer to array of 16 bit words to be written to the EEPROM
 *
 *****************************************************************************/
static s32
e1000_write_eeprom_microwire(struct e1000_hw *hw,
                             u16 offset,
                             u16 words,
                             u16 *data)
{
    struct e1000_eeprom_info *eeprom = &hw->eeprom;
    u32 eecd;
    u16 words_written = 0;
    u16 i = 0;

    DEBUGFUNC("e1000_write_eeprom_microwire");

    /* Send the write enable command to the EEPROM (3-bit opcode plus
     * 6/8-bit dummy address beginning with 11).  It's less work to include
     * the 11 of the dummy address as part of the opcode than it is to shift
     * it over the correct number of bits for the address.  This puts the
     * EEPROM into write/erase mode.
     */
    e1000_shift_out_ee_bits(hw, EEPROM_EWEN_OPCODE_MICROWIRE,
                            (u16)(eeprom->opcode_bits + 2));

    e1000_shift_out_ee_bits(hw, 0, (u16)(eeprom->address_bits - 2));

    /* Prepare the EEPROM */
    e1000_standby_eeprom(hw);

    while (words_written < words) {
        /* Send the Write command (3-bit opcode + addr) */
        e1000_shift_out_ee_bits(hw, EEPROM_WRITE_OPCODE_MICROWIRE,
                                eeprom->opcode_bits);

        e1000_shift_out_ee_bits(hw, (u16)(offset + words_written),
                                eeprom->address_bits);

        /* Send the data */
        e1000_shift_out_ee_bits(hw, data[words_written], 16);

        /* Toggle the CS line.  This in effect tells the EEPROM to execute
         * the previous command.
         */
        e1000_standby_eeprom(hw);

        /* Read DO repeatedly until it is high (equal to '1').  The EEPROM will
         * signal that the command has been completed by raising the DO signal.
         * If DO does not go high in 10 milliseconds, then error out.
         */
        for (i = 0; i < 200; i++) {
            eecd = E1000_READ_REG(hw, EECD);
            if (eecd & E1000_EECD_DO) break;
            udelay(50);
        }
        if (i == 200) {
            DEBUGOUT("EEPROM Write did not complete\n");
            return -E1000_ERR_EEPROM;
        }

        /* Recover from write */
        e1000_standby_eeprom(hw);

        words_written++;
    }

    /* Send the write disable command to the EEPROM (3-bit opcode plus
     * 6/8-bit dummy address beginning with 10).  It's less work to include
     * the 10 of the dummy address as part of the opcode than it is to shift
     * it over the correct number of bits for the address.  This takes the
     * EEPROM out of write/erase mode.
     */
    e1000_shift_out_ee_bits(hw, EEPROM_EWDS_OPCODE_MICROWIRE,
                            (u16)(eeprom->opcode_bits + 2));

    e1000_shift_out_ee_bits(hw, 0, (u16)(eeprom->address_bits - 2));

    return E1000_SUCCESS;
}

/******************************************************************************
 * Flushes the cached eeprom to NVM. This is done by saving the modified values
 * in the eeprom cache and the non modified values in the currently active bank
 * to the new bank.
 *
 * hw - Struct containing variables accessed by shared code
 * offset - offset of  word in the EEPROM to read
 * data - word read from the EEPROM
 * words - number of words to read
 *****************************************************************************/
static s32
e1000_commit_shadow_ram(struct e1000_hw *hw)
{
    u32 attempts = 100000;
    u32 eecd = 0;
    u32 flop = 0;
    u32 i = 0;
    s32 error = E1000_SUCCESS;
    u32 old_bank_offset = 0;
    u32 new_bank_offset = 0;
    u8 low_byte = 0;
    u8 high_byte = 0;
    bool sector_write_failed = false;

    if (hw->mac_type == e1000_82573) {
        /* The flop register will be used to determine if flash type is STM */
        flop = E1000_READ_REG(hw, FLOP);
        for (i=0; i < attempts; i++) {
            eecd = E1000_READ_REG(hw, EECD);
            if ((eecd & E1000_EECD_FLUPD) == 0) {
                break;
            }
            udelay(5);
        }

        if (i == attempts) {
            return -E1000_ERR_EEPROM;
        }

        /* If STM opcode located in bits 15:8 of flop, reset firmware */
        if ((flop & 0xFF00) == E1000_STM_OPCODE) {
            E1000_WRITE_REG(hw, HICR, E1000_HICR_FW_RESET);
        }

        /* Perform the flash update */
        E1000_WRITE_REG(hw, EECD, eecd | E1000_EECD_FLUPD);

        for (i=0; i < attempts; i++) {
            eecd = E1000_READ_REG(hw, EECD);
            if ((eecd & E1000_EECD_FLUPD) == 0) {
                break;
            }
            udelay(5);
        }

        if (i == attempts) {
            return -E1000_ERR_EEPROM;
        }
    }

    if (hw->mac_type == e1000_ich8lan && hw->eeprom_shadow_ram != NULL) {
        /* We're writing to the opposite bank so if we're on bank 1,
         * write to bank 0 etc.  We also need to erase the segment that
         * is going to be written */
        if (!(E1000_READ_REG(hw, EECD) & E1000_EECD_SEC1VAL)) {
            new_bank_offset = hw->flash_bank_size * 2;
            old_bank_offset = 0;
            e1000_erase_ich8_4k_segment(hw, 1);
        } else {
            old_bank_offset = hw->flash_bank_size * 2;
            new_bank_offset = 0;
            e1000_erase_ich8_4k_segment(hw, 0);
        }

        sector_write_failed = false;
        /* Loop for every byte in the shadow RAM,
         * which is in units of words. */
        for (i = 0; i < E1000_SHADOW_RAM_WORDS; i++) {
            /* Determine whether to write the value stored
             * in the other NVM bank or a modified value stored
             * in the shadow RAM */
            if (hw->eeprom_shadow_ram[i].modified) {
                low_byte = (u8)hw->eeprom_shadow_ram[i].eeprom_word;
                udelay(100);
                error = e1000_verify_write_ich8_byte(hw,
                            (i << 1) + new_bank_offset, low_byte);

                if (error != E1000_SUCCESS)
                    sector_write_failed = true;
                else {
                    high_byte =
                        (u8)(hw->eeprom_shadow_ram[i].eeprom_word >> 8);
                    udelay(100);
                }
            } else {
                e1000_read_ich8_byte(hw, (i << 1) + old_bank_offset,
                                     &low_byte);
                udelay(100);
                error = e1000_verify_write_ich8_byte(hw,
                            (i << 1) + new_bank_offset, low_byte);

                if (error != E1000_SUCCESS)
                    sector_write_failed = true;
                else {
                    e1000_read_ich8_byte(hw, (i << 1) + old_bank_offset + 1,
                                         &high_byte);
                    udelay(100);
                }
            }

            /* If the write of the low byte was successful, go ahead and
             * write the high byte while checking to make sure that if it
             * is the signature byte, then it is handled properly */
            if (!sector_write_failed) {
                /* If the word is 0x13, then make sure the signature bits
                 * (15:14) are 11b until the commit has completed.
                 * This will allow us to write 10b which indicates the
                 * signature is valid.  We want to do this after the write
                 * has completed so that we don't mark the segment valid
                 * while the write is still in progress */
                if (i == E1000_ICH_NVM_SIG_WORD)
                    high_byte = E1000_ICH_NVM_SIG_MASK | high_byte;

                error = e1000_verify_write_ich8_byte(hw,
                            (i << 1) + new_bank_offset + 1, high_byte);
                if (error != E1000_SUCCESS)
                    sector_write_failed = true;

            } else {
                /* If the write failed then break from the loop and
                 * return an error */
                break;
            }
        }

        /* Don't bother writing the segment valid bits if sector
         * programming failed. */
        if (!sector_write_failed) {
            /* Finally validate the new segment by setting bit 15:14
             * to 10b in word 0x13 , this can be done without an
             * erase as well since these bits are 11 to start with
             * and we need to change bit 14 to 0b */
            e1000_read_ich8_byte(hw,
                                 E1000_ICH_NVM_SIG_WORD * 2 + 1 + new_bank_offset,
                                 &high_byte);
            high_byte &= 0xBF;
            error = e1000_verify_write_ich8_byte(hw,
                        E1000_ICH_NVM_SIG_WORD * 2 + 1 + new_bank_offset, high_byte);
            /* And invalidate the previously valid segment by setting
             * its signature word (0x13) high_byte to 0b. This can be
             * done without an erase because flash erase sets all bits
             * to 1's. We can write 1's to 0's without an erase */
            if (error == E1000_SUCCESS) {
                error = e1000_verify_write_ich8_byte(hw,
                            E1000_ICH_NVM_SIG_WORD * 2 + 1 + old_bank_offset, 0);
            }

            /* Clear the now not used entry in the cache */
            for (i = 0; i < E1000_SHADOW_RAM_WORDS; i++) {
                hw->eeprom_shadow_ram[i].modified = false;
                hw->eeprom_shadow_ram[i].eeprom_word = 0xFFFF;
            }
        }
    }

    return error;
}

/******************************************************************************
 * Reads the adapter's MAC address from the EEPROM and inverts the LSB for the
 * second function of dual function devices
 *
 * hw - Struct containing variables accessed by shared code
 *****************************************************************************/
s32
e1000_read_mac_addr(struct e1000_hw * hw)
{
    u16 offset;
    u16 eeprom_data, i;

    DEBUGFUNC("e1000_read_mac_addr");

    for (i = 0; i < NODE_ADDRESS_SIZE; i += 2) {
        offset = i >> 1;
        if (e1000_read_eeprom(hw, offset, 1, &eeprom_data) < 0) {
            DEBUGOUT("EEPROM Read Error\n");
            return -E1000_ERR_EEPROM;
        }
        hw->perm_mac_addr[i] = (u8) (eeprom_data & 0x00FF);
        hw->perm_mac_addr[i+1] = (u8) (eeprom_data >> 8);
    }

    switch (hw->mac_type) {
    default:
        break;
    case e1000_82546:
    case e1000_82546_rev_3:
    case e1000_82571:
    case e1000_80003es2lan:
        if (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1)
            hw->perm_mac_addr[5] ^= 0x01;
        break;
    }

    for (i = 0; i < NODE_ADDRESS_SIZE; i++)
        hw->mac_addr[i] = hw->perm_mac_addr[i];
    return E1000_SUCCESS;
}

/******************************************************************************
 * Initializes receive address filters.
 *
 * hw - Struct containing variables accessed by shared code
 *
 * Places the MAC address in receive address register 0 and clears the rest
 * of the receive addresss registers. Clears the multicast table. Assumes
 * the receiver is in reset when the routine is called.
 *****************************************************************************/
static void
e1000_init_rx_addrs(struct e1000_hw *hw)
{
    u32 i;
    u32 rar_num;

    DEBUGFUNC("e1000_init_rx_addrs");

    /* Setup the receive address. */
    DEBUGOUT("Programming MAC Address into RAR[0]\n");

    e1000_rar_set(hw, hw->mac_addr, 0);

    rar_num = E1000_RAR_ENTRIES;

    /* Reserve a spot for the Locally Administered Address to work around
     * an 82571 issue in which a reset on one port will reload the MAC on
     * the other port. */
    if ((hw->mac_type == e1000_82571) && (hw->laa_is_present))
        rar_num -= 1;
    if (hw->mac_type == e1000_ich8lan)
        rar_num = E1000_RAR_ENTRIES_ICH8LAN;

    /* Zero out the other 15 receive addresses. */
    DEBUGOUT("Clearing RAR[1-15]\n");
    for (i = 1; i < rar_num; i++) {
        E1000_WRITE_REG_ARRAY(hw, RA, (i << 1), 0);
        E1000_WRITE_FLUSH(hw);
        E1000_WRITE_REG_ARRAY(hw, RA, ((i << 1) + 1), 0);
        E1000_WRITE_FLUSH(hw);
    }
}

/******************************************************************************
 * Hashes an address to determine its location in the multicast table
 *
 * hw - Struct containing variables accessed by shared code
 * mc_addr - the multicast address to hash
 *****************************************************************************/
u32
e1000_hash_mc_addr(struct e1000_hw *hw,
                   u8 *mc_addr)
{
    u32 hash_value = 0;

    /* The portion of the address that is used for the hash table is
     * determined by the mc_filter_type setting.
     */
    switch (hw->mc_filter_type) {
    /* [0] [1] [2] [3] [4] [5]
     * 01  AA  00  12  34  56
     * LSB                 MSB
     */
    case 0:
        if (hw->mac_type == e1000_ich8lan) {
            /* [47:38] i.e. 0x158 for above example address */
            hash_value = ((mc_addr[4] >> 6) | (((u16) mc_addr[5]) << 2));
        } else {
            /* [47:36] i.e. 0x563 for above example address */
            hash_value = ((mc_addr[4] >> 4) | (((u16) mc_addr[5]) << 4));
        }
        break;
    case 1:
        if (hw->mac_type == e1000_ich8lan) {
            /* [46:37] i.e. 0x2B1 for above example address */
            hash_value = ((mc_addr[4] >> 5) | (((u16) mc_addr[5]) << 3));
        } else {
            /* [46:35] i.e. 0xAC6 for above example address */
            hash_value = ((mc_addr[4] >> 3) | (((u16) mc_addr[5]) << 5));
        }
        break;
    case 2:
        if (hw->mac_type == e1000_ich8lan) {
            /*[45:36] i.e. 0x163 for above example address */
            hash_value = ((mc_addr[4] >> 4) | (((u16) mc_addr[5]) << 4));
        } else {
            /* [45:34] i.e. 0x5D8 for above example address */
            hash_value = ((mc_addr[4] >> 2) | (((u16) mc_addr[5]) << 6));
        }
        break;
    case 3:
        if (hw->mac_type == e1000_ich8lan) {
            /* [43:34] i.e. 0x18D for above example address */
            hash_value = ((mc_addr[4] >> 2) | (((u16) mc_addr[5]) << 6));
        } else {
            /* [43:32] i.e. 0x634 for above example address */
            hash_value = ((mc_addr[4]) | (((u16) mc_addr[5]) << 8));
        }
        break;
    }

    hash_value &= 0xFFF;
    if (hw->mac_type == e1000_ich8lan)
        hash_value &= 0x3FF;

    return hash_value;
}

/******************************************************************************
 * Sets the bit in the multicast table corresponding to the hash value.
 *
 * hw - Struct containing variables accessed by shared code
 * hash_value - Multicast address hash value
 *****************************************************************************/
void
e1000_mta_set(struct e1000_hw *hw,
              u32 hash_value)
{
    u32 hash_bit, hash_reg;
    u32 mta;
    u32 temp;

    /* The MTA is a register array of 128 32-bit registers.
     * It is treated like an array of 4096 bits.  We want to set
     * bit BitArray[hash_value]. So we figure out what register
     * the bit is in, read it, OR in the new bit, then write
     * back the new value.  The register is determined by the
     * upper 7 bits of the hash value and the bit within that
     * register are determined by the lower 5 bits of the value.
     */
    hash_reg = (hash_value >> 5) & 0x7F;
    if (hw->mac_type == e1000_ich8lan)
        hash_reg &= 0x1F;

    hash_bit = hash_value & 0x1F;

    mta = E1000_READ_REG_ARRAY(hw, MTA, hash_reg);

    mta |= (1 << hash_bit);

    /* If we are on an 82544 and we are trying to write an odd offset
     * in the MTA, save off the previous entry before writing and
     * restore the old value after writing.
     */
    if ((hw->mac_type == e1000_82544) && ((hash_reg & 0x1) == 1)) {
        temp = E1000_READ_REG_ARRAY(hw, MTA, (hash_reg - 1));
        E1000_WRITE_REG_ARRAY(hw, MTA, hash_reg, mta);
        E1000_WRITE_FLUSH(hw);
        E1000_WRITE_REG_ARRAY(hw, MTA, (hash_reg - 1), temp);
        E1000_WRITE_FLUSH(hw);
    } else {
        E1000_WRITE_REG_ARRAY(hw, MTA, hash_reg, mta);
        E1000_WRITE_FLUSH(hw);
    }
}

/******************************************************************************
 * Puts an ethernet address into a receive address register.
 *
 * hw - Struct containing variables accessed by shared code
 * addr - Address to put into receive address register
 * index - Receive address register to write
 *****************************************************************************/
void
e1000_rar_set(struct e1000_hw *hw,
              u8 *addr,
              u32 index)
{
    u32 rar_low, rar_high;

    /* HW expects these in little endian so we reverse the byte order
     * from network order (big endian) to little endian
     */
    rar_low = ((u32) addr[0] |
               ((u32) addr[1] << 8) |
               ((u32) addr[2] << 16) | ((u32) addr[3] << 24));
    rar_high = ((u32) addr[4] | ((u32) addr[5] << 8));

    /* Disable Rx and flush all Rx frames before enabling RSS to avoid Rx
     * unit hang.
     *
     * Description:
     * If there are any Rx frames queued up or otherwise present in the HW
     * before RSS is enabled, and then we enable RSS, the HW Rx unit will
     * hang.  To work around this issue, we have to disable receives and
     * flush out all Rx frames before we enable RSS. To do so, we modify we
     * redirect all Rx traffic to manageability and then reset the HW.
     * This flushes away Rx frames, and (since the redirections to
     * manageability persists across resets) keeps new ones from coming in
     * while we work.  Then, we clear the Address Valid AV bit for all MAC
     * addresses and undo the re-direction to manageability.
     * Now, frames are coming in again, but the MAC won't accept them, so
     * far so good.  We now proceed to initialize RSS (if necessary) and
     * configure the Rx unit.  Last, we re-enable the AV bits and continue
     * on our merry way.
     */
    switch (hw->mac_type) {
    case e1000_82571:
    case e1000_82572:
    case e1000_80003es2lan:
        if (hw->leave_av_bit_off)
            break;
    default:
        /* Indicate to hardware the Address is Valid. */
        rar_high |= E1000_RAH_AV;
        break;
    }

    E1000_WRITE_REG_ARRAY(hw, RA, (index << 1), rar_low);
    E1000_WRITE_FLUSH(hw);
    E1000_WRITE_REG_ARRAY(hw, RA, ((index << 1) + 1), rar_high);
    E1000_WRITE_FLUSH(hw);
}

/******************************************************************************
 * Writes a value to the specified offset in the VLAN filter table.
 *
 * hw - Struct containing variables accessed by shared code
 * offset - Offset in VLAN filer table to write
 * value - Value to write into VLAN filter table
 *****************************************************************************/
void
e1000_write_vfta(struct e1000_hw *hw,
                 u32 offset,
                 u32 value)
{
    u32 temp;

    if (hw->mac_type == e1000_ich8lan)
        return;

    if ((hw->mac_type == e1000_82544) && ((offset & 0x1) == 1)) {
        temp = E1000_READ_REG_ARRAY(hw, VFTA, (offset - 1));
        E1000_WRITE_REG_ARRAY(hw, VFTA, offset, value);
        E1000_WRITE_FLUSH(hw);
        E1000_WRITE_REG_ARRAY(hw, VFTA, (offset - 1), temp);
        E1000_WRITE_FLUSH(hw);
    } else {
        E1000_WRITE_REG_ARRAY(hw, VFTA, offset, value);
        E1000_WRITE_FLUSH(hw);
    }
}

/******************************************************************************
 * Clears the VLAN filer table
 *
 * hw - Struct containing variables accessed by shared code
 *****************************************************************************/
static void
e1000_clear_vfta(struct e1000_hw *hw)
{
    u32 offset;
    u32 vfta_value = 0;
    u32 vfta_offset = 0;
    u32 vfta_bit_in_reg = 0;

    if (hw->mac_type == e1000_ich8lan)
        return;

    if (hw->mac_type == e1000_82573) {
        if (hw->mng_cookie.vlan_id != 0) {
            /* The VFTA is a 4096b bit-field, each identifying a single VLAN
             * ID.  The following operations determine which 32b entry
             * (i.e. offset) into the array we want to set the VLAN ID
             * (i.e. bit) of the manageability unit. */
            vfta_offset = (hw->mng_cookie.vlan_id >>
                           E1000_VFTA_ENTRY_SHIFT) &
                          E1000_VFTA_ENTRY_MASK;
            vfta_bit_in_reg = 1 << (hw->mng_cookie.vlan_id &
                                    E1000_VFTA_ENTRY_BIT_SHIFT_MASK);
        }
    }
    for (offset = 0; offset < E1000_VLAN_FILTER_TBL_SIZE; offset++) {
        /* If the offset we want to clear is the same offset of the
         * manageability VLAN ID, then clear all bits except that of the
         * manageability unit */
        vfta_value = (offset == vfta_offset) ? vfta_bit_in_reg : 0;
        E1000_WRITE_REG_ARRAY(hw, VFTA, offset, vfta_value);
        E1000_WRITE_FLUSH(hw);
    }
}

static s32
e1000_id_led_init(struct e1000_hw * hw)
{
    u32 ledctl;
    const u32 ledctl_mask = 0x000000FF;
    const u32 ledctl_on = E1000_LEDCTL_MODE_LED_ON;
    const u32 ledctl_off = E1000_LEDCTL_MODE_LED_OFF;
    u16 eeprom_data, i, temp;
    const u16 led_mask = 0x0F;

    DEBUGFUNC("e1000_id_led_init");

    if (hw->mac_type < e1000_82540) {
        /* Nothing to do */
        return E1000_SUCCESS;
    }

    ledctl = E1000_READ_REG(hw, LEDCTL);
    hw->ledctl_default = ledctl;
    hw->ledctl_mode1 = hw->ledctl_default;
    hw->ledctl_mode2 = hw->ledctl_default;

    if (e1000_read_eeprom(hw, EEPROM_ID_LED_SETTINGS, 1, &eeprom_data) < 0) {
        DEBUGOUT("EEPROM Read Error\n");
        return -E1000_ERR_EEPROM;
    }

    if ((hw->mac_type == e1000_82573) &&
        (eeprom_data == ID_LED_RESERVED_82573))
        eeprom_data = ID_LED_DEFAULT_82573;
    else if ((eeprom_data == ID_LED_RESERVED_0000) ||
            (eeprom_data == ID_LED_RESERVED_FFFF)) {
        if (hw->mac_type == e1000_ich8lan)
            eeprom_data = ID_LED_DEFAULT_ICH8LAN;
        else
            eeprom_data = ID_LED_DEFAULT;
    }

    for (i = 0; i < 4; i++) {
        temp = (eeprom_data >> (i << 2)) & led_mask;
        switch (temp) {
        case ID_LED_ON1_DEF2:
        case ID_LED_ON1_ON2:
        case ID_LED_ON1_OFF2:
            hw->ledctl_mode1 &= ~(ledctl_mask << (i << 3));
            hw->ledctl_mode1 |= ledctl_on << (i << 3);
            break;
        case ID_LED_OFF1_DEF2:
        case ID_LED_OFF1_ON2:
        case ID_LED_OFF1_OFF2:
            hw->ledctl_mode1 &= ~(ledctl_mask << (i << 3));
            hw->ledctl_mode1 |= ledctl_off << (i << 3);
            break;
        default:
            /* Do nothing */
            break;
        }
        switch (temp) {
        case ID_LED_DEF1_ON2:
        case ID_LED_ON1_ON2:
        case ID_LED_OFF1_ON2:
            hw->ledctl_mode2 &= ~(ledctl_mask << (i << 3));
            hw->ledctl_mode2 |= ledctl_on << (i << 3);
            break;
        case ID_LED_DEF1_OFF2:
        case ID_LED_ON1_OFF2:
        case ID_LED_OFF1_OFF2:
            hw->ledctl_mode2 &= ~(ledctl_mask << (i << 3));
            hw->ledctl_mode2 |= ledctl_off << (i << 3);
            break;
        default:
            /* Do nothing */
            break;
        }
    }
    return E1000_SUCCESS;
}

/******************************************************************************
 * Prepares SW controlable LED for use and saves the current state of the LED.
 *
 * hw - Struct containing variables accessed by shared code
 *****************************************************************************/
s32
e1000_setup_led(struct e1000_hw *hw)
{
    u32 ledctl;
    s32 ret_val = E1000_SUCCESS;

    DEBUGFUNC("e1000_setup_led");

    switch (hw->mac_type) {
    case e1000_82542_rev2_0:
    case e1000_82542_rev2_1:
    case e1000_82543:
    case e1000_82544:
        /* No setup necessary */
        break;
    case e1000_82541:
    case e1000_82547:
    case e1000_82541_rev_2:
    case e1000_82547_rev_2:
        /* Turn off PHY Smart Power Down (if enabled) */
        ret_val = e1000_read_phy_reg(hw, IGP01E1000_GMII_FIFO,
                                     &hw->phy_spd_default);
        if (ret_val)
            return ret_val;
        ret_val = e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO,
                                      (u16)(hw->phy_spd_default &
                                      ~IGP01E1000_GMII_SPD));
        if (ret_val)
            return ret_val;
        /* Fall Through */
    default:
        if (hw->media_type == e1000_media_type_fiber) {
            ledctl = E1000_READ_REG(hw, LEDCTL);
            /* Save current LEDCTL settings */
            hw->ledctl_default = ledctl;
            /* Turn off LED0 */
            ledctl &= ~(E1000_LEDCTL_LED0_IVRT |
                        E1000_LEDCTL_LED0_BLINK |
                        E1000_LEDCTL_LED0_MODE_MASK);
            ledctl |= (E1000_LEDCTL_MODE_LED_OFF <<
                       E1000_LEDCTL_LED0_MODE_SHIFT);
            E1000_WRITE_REG(hw, LEDCTL, ledctl);
        } else if (hw->media_type == e1000_media_type_copper)
            E1000_WRITE_REG(hw, LEDCTL, hw->ledctl_mode1);
        break;
    }

    return E1000_SUCCESS;
}


/******************************************************************************
 * Used on 82571 and later Si that has LED blink bits.
 * Callers must use their own timer and should have already called
 * e1000_id_led_init()
 * Call e1000_cleanup led() to stop blinking
 *
 * hw - Struct containing variables accessed by shared code
 *****************************************************************************/
s32
e1000_blink_led_start(struct e1000_hw *hw)
{
    s16  i;
    u32 ledctl_blink = 0;

    DEBUGFUNC("e1000_id_led_blink_on");

    if (hw->mac_type < e1000_82571) {
        /* Nothing to do */
        return E1000_SUCCESS;
    }
    if (hw->media_type == e1000_media_type_fiber) {
        /* always blink LED0 for PCI-E fiber */
        ledctl_blink = E1000_LEDCTL_LED0_BLINK |
                     (E1000_LEDCTL_MODE_LED_ON << E1000_LEDCTL_LED0_MODE_SHIFT);
    } else {
        /* set the blink bit for each LED that's "on" (0x0E) in ledctl_mode2 */
        ledctl_blink = hw->ledctl_mode2;
        for (i=0; i < 4; i++)
            if (((hw->ledctl_mode2 >> (i * 8)) & 0xFF) ==
                E1000_LEDCTL_MODE_LED_ON)
                ledctl_blink |= (E1000_LEDCTL_LED0_BLINK << (i * 8));
    }

    E1000_WRITE_REG(hw, LEDCTL, ledctl_blink);

    return E1000_SUCCESS;
}

/******************************************************************************
 * Restores the saved state of the SW controlable LED.
 *
 * hw - Struct containing variables accessed by shared code
 *****************************************************************************/
s32
e1000_cleanup_led(struct e1000_hw *hw)
{
    s32 ret_val = E1000_SUCCESS;

    DEBUGFUNC("e1000_cleanup_led");

    switch (hw->mac_type) {
    case e1000_82542_rev2_0:
    case e1000_82542_rev2_1:
    case e1000_82543:
    case e1000_82544:
        /* No cleanup necessary */
        break;
    case e1000_82541:
    case e1000_82547:
    case e1000_82541_rev_2:
    case e1000_82547_rev_2:
        /* Turn on PHY Smart Power Down (if previously enabled) */
        ret_val = e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO,
                                      hw->phy_spd_default);
        if (ret_val)
            return ret_val;
        /* Fall Through */
    default:
        if (hw->phy_type == e1000_phy_ife) {
            e1000_write_phy_reg(hw, IFE_PHY_SPECIAL_CONTROL_LED, 0);
            break;
        }
        /* Restore LEDCTL settings */
        E1000_WRITE_REG(hw, LEDCTL, hw->ledctl_default);
        break;
    }

    return E1000_SUCCESS;
}

/******************************************************************************
 * Turns on the software controllable LED
 *
 * hw - Struct containing variables accessed by shared code
 *****************************************************************************/
s32
e1000_led_on(struct e1000_hw *hw)
{
    u32 ctrl = E1000_READ_REG(hw, CTRL);

    DEBUGFUNC("e1000_led_on");

    switch (hw->mac_type) {
    case e1000_82542_rev2_0:
    case e1000_82542_rev2_1:
    case e1000_82543:
        /* Set SW Defineable Pin 0 to turn on the LED */
        ctrl |= E1000_CTRL_SWDPIN0;
        ctrl |= E1000_CTRL_SWDPIO0;
        break;
    case e1000_82544:
        if (hw->media_type == e1000_media_type_fiber) {
            /* Set SW Defineable Pin 0 to turn on the LED */
            ctrl |= E1000_CTRL_SWDPIN0;
            ctrl |= E1000_CTRL_SWDPIO0;
        } else {
            /* Clear SW Defineable Pin 0 to turn on the LED */
            ctrl &= ~E1000_CTRL_SWDPIN0;
            ctrl |= E1000_CTRL_SWDPIO0;
        }
        break;
    default:
        if (hw->media_type == e1000_media_type_fiber) {
            /* Clear SW Defineable Pin 0 to turn on the LED */
            ctrl &= ~E1000_CTRL_SWDPIN0;
            ctrl |= E1000_CTRL_SWDPIO0;
        } else if (hw->phy_type == e1000_phy_ife) {
            e1000_write_phy_reg(hw, IFE_PHY_SPECIAL_CONTROL_LED,
                 (IFE_PSCL_PROBE_MODE | IFE_PSCL_PROBE_LEDS_ON));
        } else if (hw->media_type == e1000_media_type_copper) {
            E1000_WRITE_REG(hw, LEDCTL, hw->ledctl_mode2);
            return E1000_SUCCESS;
        }
        break;
    }

    E1000_WRITE_REG(hw, CTRL, ctrl);

    return E1000_SUCCESS;
}

/******************************************************************************
 * Turns off the software controllable LED
 *
 * hw - Struct containing variables accessed by shared code
 *****************************************************************************/
s32
e1000_led_off(struct e1000_hw *hw)
{
    u32 ctrl = E1000_READ_REG(hw, CTRL);

    DEBUGFUNC("e1000_led_off");

    switch (hw->mac_type) {
    case e1000_82542_rev2_0:
    case e1000_82542_rev2_1:
    case e1000_82543:
        /* Clear SW Defineable Pin 0 to turn off the LED */
        ctrl &= ~E1000_CTRL_SWDPIN0;
        ctrl |= E1000_CTRL_SWDPIO0;
        break;
    case e1000_82544:
        if (hw->media_type == e1000_media_type_fiber) {
            /* Clear SW Defineable Pin 0 to turn off the LED */
            ctrl &= ~E1000_CTRL_SWDPIN0;
            ctrl |= E1000_CTRL_SWDPIO0;
        } else {
            /* Set SW Defineable Pin 0 to turn off the LED */
            ctrl |= E1000_CTRL_SWDPIN0;
            ctrl |= E1000_CTRL_SWDPIO0;
        }
        break;
    default:
        if (hw->media_type == e1000_media_type_fiber) {
            /* Set SW Defineable Pin 0 to turn off the LED */
            ctrl |= E1000_CTRL_SWDPIN0;
            ctrl |= E1000_CTRL_SWDPIO0;
        } else if (hw->phy_type == e1000_phy_ife) {
            e1000_write_phy_reg(hw, IFE_PHY_SPECIAL_CONTROL_LED,
                 (IFE_PSCL_PROBE_MODE | IFE_PSCL_PROBE_LEDS_OFF));
        } else if (hw->media_type == e1000_media_type_copper) {
            E1000_WRITE_REG(hw, LEDCTL, hw->ledctl_mode1);
            return E1000_SUCCESS;
        }
        break;
    }

    E1000_WRITE_REG(hw, CTRL, ctrl);

    return E1000_SUCCESS;
}

/******************************************************************************
 * Clears all hardware statistics counters.
 *
 * hw - Struct containing variables accessed by shared code
 *****************************************************************************/
static void
e1000_clear_hw_cntrs(struct e1000_hw *hw)
{
    volatile u32 temp;

    temp = E1000_READ_REG(hw, CRCERRS);
    temp = E1000_READ_REG(hw, SYMERRS);
    temp = E1000_READ_REG(hw, MPC);
    temp = E1000_READ_REG(hw, SCC);
    temp = E1000_READ_REG(hw, ECOL);
    temp = E1000_READ_REG(hw, MCC);
    temp = E1000_READ_REG(hw, LATECOL);
    temp = E1000_READ_REG(hw, COLC);
    temp = E1000_READ_REG(hw, DC);
    temp = E1000_READ_REG(hw, SEC);
    temp = E1000_READ_REG(hw, RLEC);
    temp = E1000_READ_REG(hw, XONRXC);
    temp = E1000_READ_REG(hw, XONTXC);
    temp = E1000_READ_REG(hw, XOFFRXC);
    temp = E1000_READ_REG(hw, XOFFTXC);
    temp = E1000_READ_REG(hw, FCRUC);

    if (hw->mac_type != e1000_ich8lan) {
    temp = E1000_READ_REG(hw, PRC64);
    temp = E1000_READ_REG(hw, PRC127);
    temp = E1000_READ_REG(hw, PRC255);
    temp = E1000_READ_REG(hw, PRC511);
    temp = E1000_READ_REG(hw, PRC1023);
    temp = E1000_READ_REG(hw, PRC1522);
    }

    temp = E1000_READ_REG(hw, GPRC);
    temp = E1000_READ_REG(hw, BPRC);
    temp = E1000_READ_REG(hw, MPRC);
    temp = E1000_READ_REG(hw, GPTC);
    temp = E1000_READ_REG(hw, GORCL);
    temp = E1000_READ_REG(hw, GORCH);
    temp = E1000_READ_REG(hw, GOTCL);
    temp = E1000_READ_REG(hw, GOTCH);
    temp = E1000_READ_REG(hw, RNBC);
    temp = E1000_READ_REG(hw, RUC);
    temp = E1000_READ_REG(hw, RFC);
    temp = E1000_READ_REG(hw, ROC);
    temp = E1000_READ_REG(hw, RJC);
    temp = E1000_READ_REG(hw, TORL);
    temp = E1000_READ_REG(hw, TORH);
    temp = E1000_READ_REG(hw, TOTL);
    temp = E1000_READ_REG(hw, TOTH);
    temp = E1000_READ_REG(hw, TPR);
    temp = E1000_READ_REG(hw, TPT);

    if (hw->mac_type != e1000_ich8lan) {
    temp = E1000_READ_REG(hw, PTC64);
    temp = E1000_READ_REG(hw, PTC127);
    temp = E1000_READ_REG(hw, PTC255);
    temp = E1000_READ_REG(hw, PTC511);
    temp = E1000_READ_REG(hw, PTC1023);
    temp = E1000_READ_REG(hw, PTC1522);
    }

    temp = E1000_READ_REG(hw, MPTC);
    temp = E1000_READ_REG(hw, BPTC);

    if (hw->mac_type < e1000_82543) return;

    temp = E1000_READ_REG(hw, ALGNERRC);
    temp = E1000_READ_REG(hw, RXERRC);
    temp = E1000_READ_REG(hw, TNCRS);
    temp = E1000_READ_REG(hw, CEXTERR);
    temp = E1000_READ_REG(hw, TSCTC);
    temp = E1000_READ_REG(hw, TSCTFC);

    if (hw->mac_type <= e1000_82544) return;

    temp = E1000_READ_REG(hw, MGTPRC);
    temp = E1000_READ_REG(hw, MGTPDC);
    temp = E1000_READ_REG(hw, MGTPTC);

    if (hw->mac_type <= e1000_82547_rev_2) return;

    temp = E1000_READ_REG(hw, IAC);
    temp = E1000_READ_REG(hw, ICRXOC);

    if (hw->mac_type == e1000_ich8lan) return;

    temp = E1000_READ_REG(hw, ICRXPTC);
    temp = E1000_READ_REG(hw, ICRXATC);
    temp = E1000_READ_REG(hw, ICTXPTC);
    temp = E1000_READ_REG(hw, ICTXATC);
    temp = E1000_READ_REG(hw, ICTXQEC);
    temp = E1000_READ_REG(hw, ICTXQMTC);
    temp = E1000_READ_REG(hw, ICRXDMTC);
}

/******************************************************************************
 * Resets Adaptive IFS to its default state.
 *
 * hw - Struct containing variables accessed by shared code
 *
 * Call this after e1000_init_hw. You may override the IFS defaults by setting
 * hw->ifs_params_forced to true. However, you must initialize hw->
 * current_ifs_val, ifs_min_val, ifs_max_val, ifs_step_size, and ifs_ratio
 * before calling this function.
 *****************************************************************************/
void
e1000_reset_adaptive(struct e1000_hw *hw)
{
    DEBUGFUNC("e1000_reset_adaptive");

    if (hw->adaptive_ifs) {
        if (!hw->ifs_params_forced) {
            hw->current_ifs_val = 0;
            hw->ifs_min_val = IFS_MIN;
            hw->ifs_max_val = IFS_MAX;
            hw->ifs_step_size = IFS_STEP;
            hw->ifs_ratio = IFS_RATIO;
        }
        hw->in_ifs_mode = false;
        E1000_WRITE_REG(hw, AIT, 0);
    } else {
        DEBUGOUT("Not in Adaptive IFS mode!\n");
    }
}

/******************************************************************************
 * Called during the callback/watchdog routine to update IFS value based on
 * the ratio of transmits to collisions.
 *
 * hw - Struct containing variables accessed by shared code
 * tx_packets - Number of transmits since last callback
 * total_collisions - Number of collisions since last callback
 *****************************************************************************/
void
e1000_update_adaptive(struct e1000_hw *hw)
{
    DEBUGFUNC("e1000_update_adaptive");

    if (hw->adaptive_ifs) {
        if ((hw->collision_delta * hw->ifs_ratio) > hw->tx_packet_delta) {
            if (hw->tx_packet_delta > MIN_NUM_XMITS) {
                hw->in_ifs_mode = true;
                if (hw->current_ifs_val < hw->ifs_max_val) {
                    if (hw->current_ifs_val == 0)
                        hw->current_ifs_val = hw->ifs_min_val;
                    else
                        hw->current_ifs_val += hw->ifs_step_size;
                    E1000_WRITE_REG(hw, AIT, hw->current_ifs_val);
                }
            }
        } else {
            if (hw->in_ifs_mode && (hw->tx_packet_delta <= MIN_NUM_XMITS)) {
                hw->current_ifs_val = 0;
                hw->in_ifs_mode = false;
                E1000_WRITE_REG(hw, AIT, 0);
            }
        }
    } else {
        DEBUGOUT("Not in Adaptive IFS mode!\n");
    }
}

/******************************************************************************
 * Adjusts the statistic counters when a frame is accepted by TBI_ACCEPT
 *
 * hw - Struct containing variables accessed by shared code
 * frame_len - The length of the frame in question
 * mac_addr - The Ethernet destination address of the frame in question
 *****************************************************************************/
void
e1000_tbi_adjust_stats(struct e1000_hw *hw,
                       struct e1000_hw_stats *stats,
                       u32 frame_len,
                       u8 *mac_addr)
{
    u64 carry_bit;

    /* First adjust the frame length. */
    frame_len--;
    /* We need to adjust the statistics counters, since the hardware
     * counters overcount this packet as a CRC error and undercount
     * the packet as a good packet
     */
    /* This packet should not be counted as a CRC error.    */
    stats->crcerrs--;
    /* This packet does count as a Good Packet Received.    */
    stats->gprc++;

    /* Adjust the Good Octets received counters             */
    carry_bit = 0x80000000 & stats->gorcl;
    stats->gorcl += frame_len;
    /* If the high bit of Gorcl (the low 32 bits of the Good Octets
     * Received Count) was one before the addition,
     * AND it is zero after, then we lost the carry out,
     * need to add one to Gorch (Good Octets Received Count High).
     * This could be simplified if all environments supported
     * 64-bit integers.
     */
    if (carry_bit && ((stats->gorcl & 0x80000000) == 0))
        stats->gorch++;
    /* Is this a broadcast or multicast?  Check broadcast first,
     * since the test for a multicast frame will test positive on
     * a broadcast frame.
     */
    if ((mac_addr[0] == (u8) 0xff) && (mac_addr[1] == (u8) 0xff))
        /* Broadcast packet */
        stats->bprc++;
    else if (*mac_addr & 0x01)
        /* Multicast packet */
        stats->mprc++;

    if (frame_len == hw->max_frame_size) {
        /* In this case, the hardware has overcounted the number of
         * oversize frames.
         */
        if (stats->roc > 0)
            stats->roc--;
    }

    /* Adjust the bin counters when the extra byte put the frame in the
     * wrong bin. Remember that the frame_len was adjusted above.
     */
    if (frame_len == 64) {
        stats->prc64++;
        stats->prc127--;
    } else if (frame_len == 127) {
        stats->prc127++;
        stats->prc255--;
    } else if (frame_len == 255) {
        stats->prc255++;
        stats->prc511--;
    } else if (frame_len == 511) {
        stats->prc511++;
        stats->prc1023--;
    } else if (frame_len == 1023) {
        stats->prc1023++;
        stats->prc1522--;
    } else if (frame_len == 1522) {
        stats->prc1522++;
    }
}

/******************************************************************************
 * Gets the current PCI bus type, speed, and width of the hardware
 *
 * hw - Struct containing variables accessed by shared code
 *****************************************************************************/
void
e1000_get_bus_info(struct e1000_hw *hw)
{
    s32 ret_val;
    u16 pci_ex_link_status;
    u32 status;

    switch (hw->mac_type) {
    case e1000_82542_rev2_0:
    case e1000_82542_rev2_1:
        hw->bus_type = e1000_bus_type_pci;
        hw->bus_speed = e1000_bus_speed_unknown;
        hw->bus_width = e1000_bus_width_unknown;
        break;
    case e1000_82571:
    case e1000_82572:
    case e1000_82573:
    case e1000_80003es2lan:
        hw->bus_type = e1000_bus_type_pci_express;
        hw->bus_speed = e1000_bus_speed_2500;
        ret_val = e1000_read_pcie_cap_reg(hw,
                                      PCI_EX_LINK_STATUS,
                                      &pci_ex_link_status);
        if (ret_val)
            hw->bus_width = e1000_bus_width_unknown;
        else
            hw->bus_width = (pci_ex_link_status & PCI_EX_LINK_WIDTH_MASK) >>
                          PCI_EX_LINK_WIDTH_SHIFT;
        break;
    case e1000_ich8lan:
        hw->bus_type = e1000_bus_type_pci_express;
        hw->bus_speed = e1000_bus_speed_2500;
        hw->bus_width = e1000_bus_width_pciex_1;
        break;
    default:
        status = E1000_READ_REG(hw, STATUS);
        hw->bus_type = (status & E1000_STATUS_PCIX_MODE) ?
                       e1000_bus_type_pcix : e1000_bus_type_pci;

        if (hw->device_id == E1000_DEV_ID_82546EB_QUAD_COPPER) {
            hw->bus_speed = (hw->bus_type == e1000_bus_type_pci) ?
                            e1000_bus_speed_66 : e1000_bus_speed_120;
        } else if (hw->bus_type == e1000_bus_type_pci) {
            hw->bus_speed = (status & E1000_STATUS_PCI66) ?
                            e1000_bus_speed_66 : e1000_bus_speed_33;
        } else {
            switch (status & E1000_STATUS_PCIX_SPEED) {
            case E1000_STATUS_PCIX_SPEED_66:
                hw->bus_speed = e1000_bus_speed_66;
                break;
            case E1000_STATUS_PCIX_SPEED_100:
                hw->bus_speed = e1000_bus_speed_100;
                break;
            case E1000_STATUS_PCIX_SPEED_133:
                hw->bus_speed = e1000_bus_speed_133;
                break;
            default:
                hw->bus_speed = e1000_bus_speed_reserved;
                break;
            }
        }
        hw->bus_width = (status & E1000_STATUS_BUS64) ?
                        e1000_bus_width_64 : e1000_bus_width_32;
        break;
    }
}

/******************************************************************************
 * Writes a value to one of the devices registers using port I/O (as opposed to
 * memory mapped I/O). Only 82544 and newer devices support port I/O.
 *
 * hw - Struct containing variables accessed by shared code
 * offset - offset to write to
 * value - value to write
 *****************************************************************************/
static void
e1000_write_reg_io(struct e1000_hw *hw,
                   u32 offset,
                   u32 value)
{
    unsigned long io_addr = hw->io_base;
    unsigned long io_data = hw->io_base + 4;

    e1000_io_write(hw, io_addr, offset);
    e1000_io_write(hw, io_data, value);
}

/******************************************************************************
 * Estimates the cable length.
 *
 * hw - Struct containing variables accessed by shared code
 * min_length - The estimated minimum length
 * max_length - The estimated maximum length
 *
 * returns: - E1000_ERR_XXX
 *            E1000_SUCCESS
 *
 * This function always returns a ranged length (minimum & maximum).
 * So for M88 phy's, this function interprets the one value returned from the
 * register to the minimum and maximum range.
 * For IGP phy's, the function calculates the range by the AGC registers.
 *****************************************************************************/
static s32
e1000_get_cable_length(struct e1000_hw *hw,
                       u16 *min_length,
                       u16 *max_length)
{
    s32 ret_val;
    u16 agc_value = 0;
    u16 i, phy_data;
    u16 cable_length;

    DEBUGFUNC("e1000_get_cable_length");

    *min_length = *max_length = 0;

    /* Use old method for Phy older than IGP */
    if (hw->phy_type == e1000_phy_m88) {

        ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS,
                                     &phy_data);
        if (ret_val)
            return ret_val;
        cable_length = (phy_data & M88E1000_PSSR_CABLE_LENGTH) >>
                       M88E1000_PSSR_CABLE_LENGTH_SHIFT;

        /* Convert the enum value to ranged values */
        switch (cable_length) {
        case e1000_cable_length_50:
            *min_length = 0;
            *max_length = e1000_igp_cable_length_50;
            break;
        case e1000_cable_length_50_80:
            *min_length = e1000_igp_cable_length_50;
            *max_length = e1000_igp_cable_length_80;
            break;
        case e1000_cable_length_80_110:
            *min_length = e1000_igp_cable_length_80;
            *max_length = e1000_igp_cable_length_110;
            break;
        case e1000_cable_length_110_140:
            *min_length = e1000_igp_cable_length_110;
            *max_length = e1000_igp_cable_length_140;
            break;
        case e1000_cable_length_140:
            *min_length = e1000_igp_cable_length_140;
            *max_length = e1000_igp_cable_length_170;
            break;
        default:
            return -E1000_ERR_PHY;
            break;
        }
    } else if (hw->phy_type == e1000_phy_gg82563) {
        ret_val = e1000_read_phy_reg(hw, GG82563_PHY_DSP_DISTANCE,
                                     &phy_data);
        if (ret_val)
            return ret_val;
        cable_length = phy_data & GG82563_DSPD_CABLE_LENGTH;

        switch (cable_length) {
        case e1000_gg_cable_length_60:
            *min_length = 0;
            *max_length = e1000_igp_cable_length_60;
            break;
        case e1000_gg_cable_length_60_115:
            *min_length = e1000_igp_cable_length_60;
            *max_length = e1000_igp_cable_length_115;
            break;
        case e1000_gg_cable_length_115_150:
            *min_length = e1000_igp_cable_length_115;
            *max_length = e1000_igp_cable_length_150;
            break;
        case e1000_gg_cable_length_150:
            *min_length = e1000_igp_cable_length_150;
            *max_length = e1000_igp_cable_length_180;
            break;
        default:
            return -E1000_ERR_PHY;
            break;
        }
    } else if (hw->phy_type == e1000_phy_igp) { /* For IGP PHY */
        u16 cur_agc_value;
        u16 min_agc_value = IGP01E1000_AGC_LENGTH_TABLE_SIZE;
        u16 agc_reg_array[IGP01E1000_PHY_CHANNEL_NUM] =
                                                         {IGP01E1000_PHY_AGC_A,
                                                          IGP01E1000_PHY_AGC_B,
                                                          IGP01E1000_PHY_AGC_C,
                                                          IGP01E1000_PHY_AGC_D};
        /* Read the AGC registers for all channels */
        for (i = 0; i < IGP01E1000_PHY_CHANNEL_NUM; i++) {

            ret_val = e1000_read_phy_reg(hw, agc_reg_array[i], &phy_data);
            if (ret_val)
                return ret_val;

            cur_agc_value = phy_data >> IGP01E1000_AGC_LENGTH_SHIFT;

            /* Value bound check. */
            if ((cur_agc_value >= IGP01E1000_AGC_LENGTH_TABLE_SIZE - 1) ||
                (cur_agc_value == 0))
                return -E1000_ERR_PHY;

            agc_value += cur_agc_value;

            /* Update minimal AGC value. */
            if (min_agc_value > cur_agc_value)
                min_agc_value = cur_agc_value;
        }

        /* Remove the minimal AGC result for length < 50m */
        if (agc_value < IGP01E1000_PHY_CHANNEL_NUM * e1000_igp_cable_length_50) {
            agc_value -= min_agc_value;

            /* Get the average length of the remaining 3 channels */
            agc_value /= (IGP01E1000_PHY_CHANNEL_NUM - 1);
        } else {
            /* Get the average length of all the 4 channels. */
            agc_value /= IGP01E1000_PHY_CHANNEL_NUM;
        }

        /* Set the range of the calculated length. */
        *min_length = ((e1000_igp_cable_length_table[agc_value] -
                       IGP01E1000_AGC_RANGE) > 0) ?
                       (e1000_igp_cable_length_table[agc_value] -
                       IGP01E1000_AGC_RANGE) : 0;
        *max_length = e1000_igp_cable_length_table[agc_value] +
                      IGP01E1000_AGC_RANGE;
    } else if (hw->phy_type == e1000_phy_igp_2 ||
               hw->phy_type == e1000_phy_igp_3) {
        u16 cur_agc_index, max_agc_index = 0;
        u16 min_agc_index = IGP02E1000_AGC_LENGTH_TABLE_SIZE - 1;
        u16 agc_reg_array[IGP02E1000_PHY_CHANNEL_NUM] =
                                                         {IGP02E1000_PHY_AGC_A,
                                                          IGP02E1000_PHY_AGC_B,
                                                          IGP02E1000_PHY_AGC_C,
                                                          IGP02E1000_PHY_AGC_D};
        /* Read the AGC registers for all channels */
        for (i = 0; i < IGP02E1000_PHY_CHANNEL_NUM; i++) {
            ret_val = e1000_read_phy_reg(hw, agc_reg_array[i], &phy_data);
            if (ret_val)
                return ret_val;

            /* Getting bits 15:9, which represent the combination of course and
             * fine gain values.  The result is a number that can be put into
             * the lookup table to obtain the approximate cable length. */
            cur_agc_index = (phy_data >> IGP02E1000_AGC_LENGTH_SHIFT) &
                            IGP02E1000_AGC_LENGTH_MASK;

            /* Array index bound check. */
            if ((cur_agc_index >= IGP02E1000_AGC_LENGTH_TABLE_SIZE) ||
                (cur_agc_index == 0))
                return -E1000_ERR_PHY;

            /* Remove min & max AGC values from calculation. */
            if (e1000_igp_2_cable_length_table[min_agc_index] >
                e1000_igp_2_cable_length_table[cur_agc_index])
                min_agc_index = cur_agc_index;
            if (e1000_igp_2_cable_length_table[max_agc_index] <
                e1000_igp_2_cable_length_table[cur_agc_index])
                max_agc_index = cur_agc_index;

            agc_value += e1000_igp_2_cable_length_table[cur_agc_index];
        }

        agc_value -= (e1000_igp_2_cable_length_table[min_agc_index] +
                      e1000_igp_2_cable_length_table[max_agc_index]);
        agc_value /= (IGP02E1000_PHY_CHANNEL_NUM - 2);

        /* Calculate cable length with the error range of +/- 10 meters. */
        *min_length = ((agc_value - IGP02E1000_AGC_RANGE) > 0) ?
                       (agc_value - IGP02E1000_AGC_RANGE) : 0;
        *max_length = agc_value + IGP02E1000_AGC_RANGE;
    }

    return E1000_SUCCESS;
}

/******************************************************************************
 * Check the cable polarity
 *
 * hw - Struct containing variables accessed by shared code
 * polarity - output parameter : 0 - Polarity is not reversed
 *                               1 - Polarity is reversed.
 *
 * returns: - E1000_ERR_XXX
 *            E1000_SUCCESS
 *
 * For phy's older then IGP, this function simply reads the polarity bit in the
 * Phy Status register.  For IGP phy's, this bit is valid only if link speed is
 * 10 Mbps.  If the link speed is 100 Mbps there is no polarity so this bit will
 * return 0.  If the link speed is 1000 Mbps the polarity status is in the
 * IGP01E1000_PHY_PCS_INIT_REG.
 *****************************************************************************/
static s32
e1000_check_polarity(struct e1000_hw *hw,
                     e1000_rev_polarity *polarity)
{
    s32 ret_val;
    u16 phy_data;

    DEBUGFUNC("e1000_check_polarity");

    if ((hw->phy_type == e1000_phy_m88) ||
        (hw->phy_type == e1000_phy_gg82563)) {
        /* return the Polarity bit in the Status register. */
        ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS,
                                     &phy_data);
        if (ret_val)
            return ret_val;
        *polarity = ((phy_data & M88E1000_PSSR_REV_POLARITY) >>
                     M88E1000_PSSR_REV_POLARITY_SHIFT) ?
                     e1000_rev_polarity_reversed : e1000_rev_polarity_normal;

    } else if (hw->phy_type == e1000_phy_igp ||
              hw->phy_type == e1000_phy_igp_3 ||
              hw->phy_type == e1000_phy_igp_2) {
        /* Read the Status register to check the speed */
        ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS,
                                     &phy_data);
        if (ret_val)
            return ret_val;

        /* If speed is 1000 Mbps, must read the IGP01E1000_PHY_PCS_INIT_REG to
         * find the polarity status */
        if ((phy_data & IGP01E1000_PSSR_SPEED_MASK) ==
           IGP01E1000_PSSR_SPEED_1000MBPS) {

            /* Read the GIG initialization PCS register (0x00B4) */
            ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PCS_INIT_REG,
                                         &phy_data);
            if (ret_val)
                return ret_val;

            /* Check the polarity bits */
            *polarity = (phy_data & IGP01E1000_PHY_POLARITY_MASK) ?
                         e1000_rev_polarity_reversed : e1000_rev_polarity_normal;
        } else {
            /* For 10 Mbps, read the polarity bit in the status register. (for
             * 100 Mbps this bit is always 0) */
            *polarity = (phy_data & IGP01E1000_PSSR_POLARITY_REVERSED) ?
                         e1000_rev_polarity_reversed : e1000_rev_polarity_normal;
        }
    } else if (hw->phy_type == e1000_phy_ife) {
        ret_val = e1000_read_phy_reg(hw, IFE_PHY_EXTENDED_STATUS_CONTROL,
                                     &phy_data);
        if (ret_val)
            return ret_val;
        *polarity = ((phy_data & IFE_PESC_POLARITY_REVERSED) >>
                     IFE_PESC_POLARITY_REVERSED_SHIFT) ?
                     e1000_rev_polarity_reversed : e1000_rev_polarity_normal;
    }
    return E1000_SUCCESS;
}

/******************************************************************************
 * Check if Downshift occured
 *
 * hw - Struct containing variables accessed by shared code
 * downshift - output parameter : 0 - No Downshift ocured.
 *                                1 - Downshift ocured.
 *
 * returns: - E1000_ERR_XXX
 *            E1000_SUCCESS
 *
 * For phy's older then IGP, this function reads the Downshift bit in the Phy
 * Specific Status register.  For IGP phy's, it reads the Downgrade bit in the
 * Link Health register.  In IGP this bit is latched high, so the driver must
 * read it immediately after link is established.
 *****************************************************************************/
static s32
e1000_check_downshift(struct e1000_hw *hw)
{
    s32 ret_val;
    u16 phy_data;

    DEBUGFUNC("e1000_check_downshift");

    if (hw->phy_type == e1000_phy_igp ||
        hw->phy_type == e1000_phy_igp_3 ||
        hw->phy_type == e1000_phy_igp_2) {
        ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_LINK_HEALTH,
                                     &phy_data);
        if (ret_val)
            return ret_val;

        hw->speed_downgraded = (phy_data & IGP01E1000_PLHR_SS_DOWNGRADE) ? 1 : 0;
    } else if ((hw->phy_type == e1000_phy_m88) ||
               (hw->phy_type == e1000_phy_gg82563)) {
        ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS,
                                     &phy_data);
        if (ret_val)
            return ret_val;

        hw->speed_downgraded = (phy_data & M88E1000_PSSR_DOWNSHIFT) >>
                               M88E1000_PSSR_DOWNSHIFT_SHIFT;
    } else if (hw->phy_type == e1000_phy_ife) {
        /* e1000_phy_ife supports 10/100 speed only */
        hw->speed_downgraded = false;
    }

    return E1000_SUCCESS;
}

/*****************************************************************************
 *
 * 82541_rev_2 & 82547_rev_2 have the capability to configure the DSP when a
 * gigabit link is achieved to improve link quality.
 *
 * hw: Struct containing variables accessed by shared code
 *
 * returns: - E1000_ERR_PHY if fail to read/write the PHY
 *            E1000_SUCCESS at any other case.
 *
 ****************************************************************************/

static s32
e1000_config_dsp_after_link_change(struct e1000_hw *hw,
                                   bool link_up)
{
    s32 ret_val;
    u16 phy_data, phy_saved_data, speed, duplex, i;
    u16 dsp_reg_array[IGP01E1000_PHY_CHANNEL_NUM] =
                                        {IGP01E1000_PHY_AGC_PARAM_A,
                                        IGP01E1000_PHY_AGC_PARAM_B,
                                        IGP01E1000_PHY_AGC_PARAM_C,
                                        IGP01E1000_PHY_AGC_PARAM_D};
    u16 min_length, max_length;

    DEBUGFUNC("e1000_config_dsp_after_link_change");

    if (hw->phy_type != e1000_phy_igp)
        return E1000_SUCCESS;

    if (link_up) {
        ret_val = e1000_get_speed_and_duplex(hw, &speed, &duplex);
        if (ret_val) {
            DEBUGOUT("Error getting link speed and duplex\n");
            return ret_val;
        }

        if (speed == SPEED_1000) {

            ret_val = e1000_get_cable_length(hw, &min_length, &max_length);
            if (ret_val)
                return ret_val;

            if ((hw->dsp_config_state == e1000_dsp_config_enabled) &&
                min_length >= e1000_igp_cable_length_50) {

                for (i = 0; i < IGP01E1000_PHY_CHANNEL_NUM; i++) {
                    ret_val = e1000_read_phy_reg(hw, dsp_reg_array[i],
                                                 &phy_data);
                    if (ret_val)
                        return ret_val;

                    phy_data &= ~IGP01E1000_PHY_EDAC_MU_INDEX;

                    ret_val = e1000_write_phy_reg(hw, dsp_reg_array[i],
                                                  phy_data);
                    if (ret_val)
                        return ret_val;
                }
                hw->dsp_config_state = e1000_dsp_config_activated;
            }

            if ((hw->ffe_config_state == e1000_ffe_config_enabled) &&
               (min_length < e1000_igp_cable_length_50)) {

                u16 ffe_idle_err_timeout = FFE_IDLE_ERR_COUNT_TIMEOUT_20;
                u32 idle_errs = 0;

                /* clear previous idle error counts */
                ret_val = e1000_read_phy_reg(hw, PHY_1000T_STATUS,
                                             &phy_data);
                if (ret_val)
                    return ret_val;

                for (i = 0; i < ffe_idle_err_timeout; i++) {
                    udelay(1000);
                    ret_val = e1000_read_phy_reg(hw, PHY_1000T_STATUS,
                                                 &phy_data);
                    if (ret_val)
                        return ret_val;

                    idle_errs += (phy_data & SR_1000T_IDLE_ERROR_CNT);
                    if (idle_errs > SR_1000T_PHY_EXCESSIVE_IDLE_ERR_COUNT) {
                        hw->ffe_config_state = e1000_ffe_config_active;

                        ret_val = e1000_write_phy_reg(hw,
                                    IGP01E1000_PHY_DSP_FFE,
                                    IGP01E1000_PHY_DSP_FFE_CM_CP);
                        if (ret_val)
                            return ret_val;
                        break;
                    }

                    if (idle_errs)
                        ffe_idle_err_timeout = FFE_IDLE_ERR_COUNT_TIMEOUT_100;
                }
            }
        }
    } else {
        if (hw->dsp_config_state == e1000_dsp_config_activated) {
            /* Save off the current value of register 0x2F5B to be restored at
             * the end of the routines. */
            ret_val = e1000_read_phy_reg(hw, 0x2F5B, &phy_saved_data);

            if (ret_val)
                return ret_val;

            /* Disable the PHY transmitter */
            ret_val = e1000_write_phy_reg(hw, 0x2F5B, 0x0003);

            if (ret_val)
                return ret_val;

            mdelay(20);

            ret_val = e1000_write_phy_reg(hw, 0x0000,
                                          IGP01E1000_IEEE_FORCE_GIGA);
            if (ret_val)
                return ret_val;
            for (i = 0; i < IGP01E1000_PHY_CHANNEL_NUM; i++) {
                ret_val = e1000_read_phy_reg(hw, dsp_reg_array[i], &phy_data);
                if (ret_val)
                    return ret_val;

                phy_data &= ~IGP01E1000_PHY_EDAC_MU_INDEX;
                phy_data |=  IGP01E1000_PHY_EDAC_SIGN_EXT_9_BITS;

                ret_val = e1000_write_phy_reg(hw,dsp_reg_array[i], phy_data);
                if (ret_val)
                    return ret_val;
            }

            ret_val = e1000_write_phy_reg(hw, 0x0000,
                                          IGP01E1000_IEEE_RESTART_AUTONEG);
            if (ret_val)
                return ret_val;

            mdelay(20);

            /* Now enable the transmitter */
            ret_val = e1000_write_phy_reg(hw, 0x2F5B, phy_saved_data);

            if (ret_val)
                return ret_val;

            hw->dsp_config_state = e1000_dsp_config_enabled;
        }

        if (hw->ffe_config_state == e1000_ffe_config_active) {
            /* Save off the current value of register 0x2F5B to be restored at
             * the end of the routines. */
            ret_val = e1000_read_phy_reg(hw, 0x2F5B, &phy_saved_data);

            if (ret_val)
                return ret_val;

            /* Disable the PHY transmitter */
            ret_val = e1000_write_phy_reg(hw, 0x2F5B, 0x0003);

            if (ret_val)
                return ret_val;

            mdelay(20);

            ret_val = e1000_write_phy_reg(hw, 0x0000,
                                          IGP01E1000_IEEE_FORCE_GIGA);
            if (ret_val)
                return ret_val;
            ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_DSP_FFE,
                                          IGP01E1000_PHY_DSP_FFE_DEFAULT);
            if (ret_val)
                return ret_val;

            ret_val = e1000_write_phy_reg(hw, 0x0000,
                                          IGP01E1000_IEEE_RESTART_AUTONEG);
            if (ret_val)
                return ret_val;

            mdelay(20);

            /* Now enable the transmitter */
            ret_val = e1000_write_phy_reg(hw, 0x2F5B, phy_saved_data);

            if (ret_val)
                return ret_val;

            hw->ffe_config_state = e1000_ffe_config_enabled;
        }
    }
    return E1000_SUCCESS;
}

/*****************************************************************************
 * Set PHY to class A mode
 * Assumes the following operations will follow to enable the new class mode.
 *  1. Do a PHY soft reset
 *  2. Restart auto-negotiation or force link.
 *
 * hw - Struct containing variables accessed by shared code
 ****************************************************************************/
static s32
e1000_set_phy_mode(struct e1000_hw *hw)
{
    s32 ret_val;
    u16 eeprom_data;

    DEBUGFUNC("e1000_set_phy_mode");

    if ((hw->mac_type == e1000_82545_rev_3) &&
        (hw->media_type == e1000_media_type_copper)) {
        ret_val = e1000_read_eeprom(hw, EEPROM_PHY_CLASS_WORD, 1, &eeprom_data);
        if (ret_val) {
            return ret_val;
        }

        if ((eeprom_data != EEPROM_RESERVED_WORD) &&
            (eeprom_data & EEPROM_PHY_CLASS_A)) {
            ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x000B);
            if (ret_val)
                return ret_val;
            ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0x8104);
            if (ret_val)
                return ret_val;

            hw->phy_reset_disable = false;
        }
    }

    return E1000_SUCCESS;
}

/*****************************************************************************
 *
 * This function sets the lplu state according to the active flag.  When
 * activating lplu this function also disables smart speed and vise versa.
 * lplu will not be activated unless the device autonegotiation advertisment
 * meets standards of either 10 or 10/100 or 10/100/1000 at all duplexes.
 * hw: Struct containing variables accessed by shared code
 * active - true to enable lplu false to disable lplu.
 *
 * returns: - E1000_ERR_PHY if fail to read/write the PHY
 *            E1000_SUCCESS at any other case.
 *
 ****************************************************************************/

static s32
e1000_set_d3_lplu_state(struct e1000_hw *hw,
                        bool active)
{
    u32 phy_ctrl = 0;
    s32 ret_val;
    u16 phy_data;
    DEBUGFUNC("e1000_set_d3_lplu_state");

    if (hw->phy_type != e1000_phy_igp && hw->phy_type != e1000_phy_igp_2
        && hw->phy_type != e1000_phy_igp_3)
        return E1000_SUCCESS;

    /* During driver activity LPLU should not be used or it will attain link
     * from the lowest speeds starting from 10Mbps. The capability is used for
     * Dx transitions and states */
    if (hw->mac_type == e1000_82541_rev_2 || hw->mac_type == e1000_82547_rev_2) {
        ret_val = e1000_read_phy_reg(hw, IGP01E1000_GMII_FIFO, &phy_data);
        if (ret_val)
            return ret_val;
    } else if (hw->mac_type == e1000_ich8lan) {
        /* MAC writes into PHY register based on the state transition
         * and start auto-negotiation. SW driver can overwrite the settings
         * in CSR PHY power control E1000_PHY_CTRL register. */
        phy_ctrl = E1000_READ_REG(hw, PHY_CTRL);
    } else {
        ret_val = e1000_read_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, &phy_data);
        if (ret_val)
            return ret_val;
    }

    if (!active) {
        if (hw->mac_type == e1000_82541_rev_2 ||
            hw->mac_type == e1000_82547_rev_2) {
            phy_data &= ~IGP01E1000_GMII_FLEX_SPD;
            ret_val = e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO, phy_data);
            if (ret_val)
                return ret_val;
        } else {
            if (hw->mac_type == e1000_ich8lan) {
                phy_ctrl &= ~E1000_PHY_CTRL_NOND0A_LPLU;
                E1000_WRITE_REG(hw, PHY_CTRL, phy_ctrl);
            } else {
                phy_data &= ~IGP02E1000_PM_D3_LPLU;
                ret_val = e1000_write_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT,
                                              phy_data);
                if (ret_val)
                    return ret_val;
            }
        }

        /* LPLU and SmartSpeed are mutually exclusive.  LPLU is used during
         * Dx states where the power conservation is most important.  During
         * driver activity we should enable SmartSpeed, so performance is
         * maintained. */
        if (hw->smart_speed == e1000_smart_speed_on) {
            ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
                                         &phy_data);
            if (ret_val)
                return ret_val;

            phy_data |= IGP01E1000_PSCFR_SMART_SPEED;
            ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
                                          phy_data);
            if (ret_val)
                return ret_val;
        } else if (hw->smart_speed == e1000_smart_speed_off) {
            ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
                                         &phy_data);
            if (ret_val)
                return ret_val;

            phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
            ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
                                          phy_data);
            if (ret_val)
                return ret_val;
        }

    } else if ((hw->autoneg_advertised == AUTONEG_ADVERTISE_SPEED_DEFAULT) ||
               (hw->autoneg_advertised == AUTONEG_ADVERTISE_10_ALL ) ||
               (hw->autoneg_advertised == AUTONEG_ADVERTISE_10_100_ALL)) {

        if (hw->mac_type == e1000_82541_rev_2 ||
            hw->mac_type == e1000_82547_rev_2) {
            phy_data |= IGP01E1000_GMII_FLEX_SPD;
            ret_val = e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO, phy_data);
            if (ret_val)
                return ret_val;
        } else {
            if (hw->mac_type == e1000_ich8lan) {
                phy_ctrl |= E1000_PHY_CTRL_NOND0A_LPLU;
                E1000_WRITE_REG(hw, PHY_CTRL, phy_ctrl);
            } else {
                phy_data |= IGP02E1000_PM_D3_LPLU;
                ret_val = e1000_write_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT,
                                              phy_data);
                if (ret_val)
                    return ret_val;
            }
        }

        /* When LPLU is enabled we should disable SmartSpeed */
        ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, &phy_data);
        if (ret_val)
            return ret_val;

        phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
        ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, phy_data);
        if (ret_val)
            return ret_val;

    }
    return E1000_SUCCESS;
}

/*****************************************************************************
 *
 * This function sets the lplu d0 state according to the active flag.  When
 * activating lplu this function also disables smart speed and vise versa.
 * lplu will not be activated unless the device autonegotiation advertisment
 * meets standards of either 10 or 10/100 or 10/100/1000 at all duplexes.
 * hw: Struct containing variables accessed by shared code
 * active - true to enable lplu false to disable lplu.
 *
 * returns: - E1000_ERR_PHY if fail to read/write the PHY
 *            E1000_SUCCESS at any other case.
 *
 ****************************************************************************/

static s32
e1000_set_d0_lplu_state(struct e1000_hw *hw,
                        bool active)
{
    u32 phy_ctrl = 0;
    s32 ret_val;
    u16 phy_data;
    DEBUGFUNC("e1000_set_d0_lplu_state");

    if (hw->mac_type <= e1000_82547_rev_2)
        return E1000_SUCCESS;

    if (hw->mac_type == e1000_ich8lan) {
        phy_ctrl = E1000_READ_REG(hw, PHY_CTRL);
    } else {
        ret_val = e1000_read_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, &phy_data);
        if (ret_val)
            return ret_val;
    }

    if (!active) {
        if (hw->mac_type == e1000_ich8lan) {
            phy_ctrl &= ~E1000_PHY_CTRL_D0A_LPLU;
            E1000_WRITE_REG(hw, PHY_CTRL, phy_ctrl);
        } else {
            phy_data &= ~IGP02E1000_PM_D0_LPLU;
            ret_val = e1000_write_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, phy_data);
            if (ret_val)
                return ret_val;
        }

        /* LPLU and SmartSpeed are mutually exclusive.  LPLU is used during
         * Dx states where the power conservation is most important.  During
         * driver activity we should enable SmartSpeed, so performance is
         * maintained. */
        if (hw->smart_speed == e1000_smart_speed_on) {
            ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
                                         &phy_data);
            if (ret_val)
                return ret_val;

            phy_data |= IGP01E1000_PSCFR_SMART_SPEED;
            ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
                                          phy_data);
            if (ret_val)
                return ret_val;
        } else if (hw->smart_speed == e1000_smart_speed_off) {
            ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
                                         &phy_data);
            if (ret_val)
                return ret_val;

            phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
            ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
                                          phy_data);
            if (ret_val)
                return ret_val;
        }


    } else {

        if (hw->mac_type == e1000_ich8lan) {
            phy_ctrl |= E1000_PHY_CTRL_D0A_LPLU;
            E1000_WRITE_REG(hw, PHY_CTRL, phy_ctrl);
        } else {
            phy_data |= IGP02E1000_PM_D0_LPLU;
            ret_val = e1000_write_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, phy_data);
            if (ret_val)
                return ret_val;
        }

        /* When LPLU is enabled we should disable SmartSpeed */
        ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, &phy_data);
        if (ret_val)
            return ret_val;

        phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
        ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, phy_data);
        if (ret_val)
            return ret_val;

    }
    return E1000_SUCCESS;
}

/******************************************************************************
 * Change VCO speed register to improve Bit Error Rate performance of SERDES.
 *
 * hw - Struct containing variables accessed by shared code
 *****************************************************************************/
static s32
e1000_set_vco_speed(struct e1000_hw *hw)
{
    s32  ret_val;
    u16 default_page = 0;
    u16 phy_data;

    DEBUGFUNC("e1000_set_vco_speed");

    switch (hw->mac_type) {
    case e1000_82545_rev_3:
    case e1000_82546_rev_3:
       break;
    default:
        return E1000_SUCCESS;
    }

    /* Set PHY register 30, page 5, bit 8 to 0 */

    ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, &default_page);
    if (ret_val)
        return ret_val;

    ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0005);
    if (ret_val)
        return ret_val;

    ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, &phy_data);
    if (ret_val)
        return ret_val;

    phy_data &= ~M88E1000_PHY_VCO_REG_BIT8;
    ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, phy_data);
    if (ret_val)
        return ret_val;

    /* Set PHY register 30, page 4, bit 11 to 1 */

    ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0004);
    if (ret_val)
        return ret_val;

    ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, &phy_data);
    if (ret_val)
        return ret_val;

    phy_data |= M88E1000_PHY_VCO_REG_BIT11;
    ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, phy_data);
    if (ret_val)
        return ret_val;

    ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, default_page);
    if (ret_val)
        return ret_val;

    return E1000_SUCCESS;
}


/*****************************************************************************
 * This function reads the cookie from ARC ram.
 *
 * returns: - E1000_SUCCESS .
 ****************************************************************************/
static s32
e1000_host_if_read_cookie(struct e1000_hw * hw, u8 *buffer)
{
    u8 i;
    u32 offset = E1000_MNG_DHCP_COOKIE_OFFSET;
    u8 length = E1000_MNG_DHCP_COOKIE_LENGTH;

    length = (length >> 2);
    offset = (offset >> 2);

    for (i = 0; i < length; i++) {
        *((u32 *) buffer + i) =
            E1000_READ_REG_ARRAY_DWORD(hw, HOST_IF, offset + i);
    }
    return E1000_SUCCESS;
}


/*****************************************************************************
 * This function checks whether the HOST IF is enabled for command operaton
 * and also checks whether the previous command is completed.
 * It busy waits in case of previous command is not completed.
 *
 * returns: - E1000_ERR_HOST_INTERFACE_COMMAND in case if is not ready or
 *            timeout
 *          - E1000_SUCCESS for success.
 ****************************************************************************/
static s32
e1000_mng_enable_host_if(struct e1000_hw * hw)
{
    u32 hicr;
    u8 i;

    /* Check that the host interface is enabled. */
    hicr = E1000_READ_REG(hw, HICR);
    if ((hicr & E1000_HICR_EN) == 0) {
        DEBUGOUT("E1000_HOST_EN bit disabled.\n");
        return -E1000_ERR_HOST_INTERFACE_COMMAND;
    }
    /* check the previous command is completed */
    for (i = 0; i < E1000_MNG_DHCP_COMMAND_TIMEOUT; i++) {
        hicr = E1000_READ_REG(hw, HICR);
        if (!(hicr & E1000_HICR_C))
            break;
        mdelay(1);
    }

    if (i == E1000_MNG_DHCP_COMMAND_TIMEOUT) {
        DEBUGOUT("Previous command timeout failed .\n");
        return -E1000_ERR_HOST_INTERFACE_COMMAND;
    }
    return E1000_SUCCESS;
}

/*****************************************************************************
 * This function writes the buffer content at the offset given on the host if.
 * It also does alignment considerations to do the writes in most efficient way.
 * Also fills up the sum of the buffer in *buffer parameter.
 *
 * returns  - E1000_SUCCESS for success.
 ****************************************************************************/
static s32
e1000_mng_host_if_write(struct e1000_hw * hw, u8 *buffer,
                        u16 length, u16 offset, u8 *sum)
{
    u8 *tmp;
    u8 *bufptr = buffer;
    u32 data = 0;
    u16 remaining, i, j, prev_bytes;

    /* sum = only sum of the data and it is not checksum */

    if (length == 0 || offset + length > E1000_HI_MAX_MNG_DATA_LENGTH) {
        return -E1000_ERR_PARAM;
    }

    tmp = (u8 *)&data;
    prev_bytes = offset & 0x3;
    offset &= 0xFFFC;
    offset >>= 2;

    if (prev_bytes) {
        data = E1000_READ_REG_ARRAY_DWORD(hw, HOST_IF, offset);
        for (j = prev_bytes; j < sizeof(u32); j++) {
            *(tmp + j) = *bufptr++;
            *sum += *(tmp + j);
        }
        E1000_WRITE_REG_ARRAY_DWORD(hw, HOST_IF, offset, data);
        length -= j - prev_bytes;
        offset++;
    }

    remaining = length & 0x3;
    length -= remaining;

    /* Calculate length in DWORDs */
    length >>= 2;

    /* The device driver writes the relevant command block into the
     * ram area. */
    for (i = 0; i < length; i++) {
        for (j = 0; j < sizeof(u32); j++) {
            *(tmp + j) = *bufptr++;
            *sum += *(tmp + j);
        }

        E1000_WRITE_REG_ARRAY_DWORD(hw, HOST_IF, offset + i, data);
    }
    if (remaining) {
        for (j = 0; j < sizeof(u32); j++) {
            if (j < remaining)
                *(tmp + j) = *bufptr++;
            else
                *(tmp + j) = 0;

            *sum += *(tmp + j);
        }
        E1000_WRITE_REG_ARRAY_DWORD(hw, HOST_IF, offset + i, data);
    }

    return E1000_SUCCESS;
}


/*****************************************************************************
 * This function writes the command header after does the checksum calculation.
 *
 * returns  - E1000_SUCCESS for success.
 ****************************************************************************/
static s32
e1000_mng_write_cmd_header(struct e1000_hw * hw,
                           struct e1000_host_mng_command_header * hdr)
{
    u16 i;
    u8 sum;
    u8 *buffer;

    /* Write the whole command header structure which includes sum of
     * the buffer */

    u16 length = sizeof(struct e1000_host_mng_command_header);

    sum = hdr->checksum;
    hdr->checksum = 0;

    buffer = (u8 *) hdr;
    i = length;
    while (i--)
        sum += buffer[i];

    hdr->checksum = 0 - sum;

    length >>= 2;
    /* The device driver writes the relevant command block into the ram area. */
    for (i = 0; i < length; i++) {
        E1000_WRITE_REG_ARRAY_DWORD(hw, HOST_IF, i, *((u32 *) hdr + i));
        E1000_WRITE_FLUSH(hw);
    }

    return E1000_SUCCESS;
}


/*****************************************************************************
 * This function indicates to ARC that a new command is pending which completes
 * one write operation by the driver.
 *
 * returns  - E1000_SUCCESS for success.
 ****************************************************************************/
static s32
e1000_mng_write_commit(struct e1000_hw * hw)
{
    u32 hicr;

    hicr = E1000_READ_REG(hw, HICR);
    /* Setting this bit tells the ARC that a new command is pending. */
    E1000_WRITE_REG(hw, HICR, hicr | E1000_HICR_C);

    return E1000_SUCCESS;
}


/*****************************************************************************
 * This function checks the mode of the firmware.
 *
 * returns  - true when the mode is IAMT or false.
 ****************************************************************************/
bool
e1000_check_mng_mode(struct e1000_hw *hw)
{
    u32 fwsm;

    fwsm = E1000_READ_REG(hw, FWSM);

    if (hw->mac_type == e1000_ich8lan) {
        if ((fwsm & E1000_FWSM_MODE_MASK) ==
            (E1000_MNG_ICH_IAMT_MODE << E1000_FWSM_MODE_SHIFT))
            return true;
    } else if ((fwsm & E1000_FWSM_MODE_MASK) ==
               (E1000_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT))
        return true;

    return false;
}


/*****************************************************************************
 * This function writes the dhcp info .
 ****************************************************************************/
s32
e1000_mng_write_dhcp_info(struct e1000_hw * hw, u8 *buffer,
                          u16 length)
{
    s32 ret_val;
    struct e1000_host_mng_command_header hdr;

    hdr.command_id = E1000_MNG_DHCP_TX_PAYLOAD_CMD;
    hdr.command_length = length;
    hdr.reserved1 = 0;
    hdr.reserved2 = 0;
    hdr.checksum = 0;

    ret_val = e1000_mng_enable_host_if(hw);
    if (ret_val == E1000_SUCCESS) {
        ret_val = e1000_mng_host_if_write(hw, buffer, length, sizeof(hdr),
                                          &(hdr.checksum));
        if (ret_val == E1000_SUCCESS) {
            ret_val = e1000_mng_write_cmd_header(hw, &hdr);
            if (ret_val == E1000_SUCCESS)
                ret_val = e1000_mng_write_commit(hw);
        }
    }
    return ret_val;
}


/*****************************************************************************
 * This function calculates the checksum.
 *
 * returns  - checksum of buffer contents.
 ****************************************************************************/
static u8
e1000_calculate_mng_checksum(char *buffer, u32 length)
{
    u8 sum = 0;
    u32 i;

    if (!buffer)
        return 0;

    for (i=0; i < length; i++)
        sum += buffer[i];

    return (u8) (0 - sum);
}

/*****************************************************************************
 * This function checks whether tx pkt filtering needs to be enabled or not.
 *
 * returns  - true for packet filtering or false.
 ****************************************************************************/
bool
e1000_enable_tx_pkt_filtering(struct e1000_hw *hw)
{
    /* called in init as well as watchdog timer functions */

    s32 ret_val, checksum;
    bool tx_filter = false;
    struct e1000_host_mng_dhcp_cookie *hdr = &(hw->mng_cookie);
    u8 *buffer = (u8 *) &(hw->mng_cookie);

    if (e1000_check_mng_mode(hw)) {
        ret_val = e1000_mng_enable_host_if(hw);
        if (ret_val == E1000_SUCCESS) {
            ret_val = e1000_host_if_read_cookie(hw, buffer);
            if (ret_val == E1000_SUCCESS) {
                checksum = hdr->checksum;
                hdr->checksum = 0;
                if ((hdr->signature == E1000_IAMT_SIGNATURE) &&
                    checksum == e1000_calculate_mng_checksum((char *)buffer,
                                               E1000_MNG_DHCP_COOKIE_LENGTH)) {
                    if (hdr->status &
                        E1000_MNG_DHCP_COOKIE_STATUS_PARSING_SUPPORT)
                        tx_filter = true;
                } else
                    tx_filter = true;
            } else
                tx_filter = true;
        }
    }

    hw->tx_pkt_filtering = tx_filter;
    return tx_filter;
}

/******************************************************************************
 * Verifies the hardware needs to allow ARPs to be processed by the host
 *
 * hw - Struct containing variables accessed by shared code
 *
 * returns: - true/false
 *
 *****************************************************************************/
u32
e1000_enable_mng_pass_thru(struct e1000_hw *hw)
{
    u32 manc;
    u32 fwsm, factps;

    if (hw->asf_firmware_present) {
        manc = E1000_READ_REG(hw, MANC);

        if (!(manc & E1000_MANC_RCV_TCO_EN) ||
            !(manc & E1000_MANC_EN_MAC_ADDR_FILTER))
            return false;
        if (e1000_arc_subsystem_valid(hw)) {
            fwsm = E1000_READ_REG(hw, FWSM);
            factps = E1000_READ_REG(hw, FACTPS);

            if ((((fwsm & E1000_FWSM_MODE_MASK) >> E1000_FWSM_MODE_SHIFT) ==
                   e1000_mng_mode_pt) && !(factps & E1000_FACTPS_MNGCG))
                return true;
        } else
            if ((manc & E1000_MANC_SMBUS_EN) && !(manc & E1000_MANC_ASF_EN))
                return true;
    }
    return false;
}

static s32
e1000_polarity_reversal_workaround(struct e1000_hw *hw)
{
    s32 ret_val;
    u16 mii_status_reg;
    u16 i;

    /* Polarity reversal workaround for forced 10F/10H links. */

    /* Disable the transmitter on the PHY */

    ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0019);
    if (ret_val)
        return ret_val;
    ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xFFFF);
    if (ret_val)
        return ret_val;

    ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0000);
    if (ret_val)
        return ret_val;

    /* This loop will early-out if the NO link condition has been met. */
    for (i = PHY_FORCE_TIME; i > 0; i--) {
        /* Read the MII Status Register and wait for Link Status bit
         * to be clear.
         */

        ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
        if (ret_val)
            return ret_val;

        ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
        if (ret_val)
            return ret_val;

        if ((mii_status_reg & ~MII_SR_LINK_STATUS) == 0) break;
        mdelay(100);
    }

    /* Recommended delay time after link has been lost */
    mdelay(1000);

    /* Now we will re-enable th transmitter on the PHY */

    ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0019);
    if (ret_val)
        return ret_val;
    mdelay(50);
    ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xFFF0);
    if (ret_val)
        return ret_val;
    mdelay(50);
    ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xFF00);
    if (ret_val)
        return ret_val;
    mdelay(50);
    ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0x0000);
    if (ret_val)
        return ret_val;

    ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0000);
    if (ret_val)
        return ret_val;

    /* This loop will early-out if the link condition has been met. */
    for (i = PHY_FORCE_TIME; i > 0; i--) {
        /* Read the MII Status Register and wait for Link Status bit
         * to be set.
         */

        ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
        if (ret_val)
            return ret_val;

        ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
        if (ret_val)
            return ret_val;

        if (mii_status_reg & MII_SR_LINK_STATUS) break;
        mdelay(100);
    }
    return E1000_SUCCESS;
}

/***************************************************************************
 *
 * Disables PCI-Express master access.
 *
 * hw: Struct containing variables accessed by shared code
 *
 * returns: - none.
 *
 ***************************************************************************/
static void
e1000_set_pci_express_master_disable(struct e1000_hw *hw)
{
    u32 ctrl;

    DEBUGFUNC("e1000_set_pci_express_master_disable");

    if (hw->bus_type != e1000_bus_type_pci_express)
        return;

    ctrl = E1000_READ_REG(hw, CTRL);
    ctrl |= E1000_CTRL_GIO_MASTER_DISABLE;
    E1000_WRITE_REG(hw, CTRL, ctrl);
}

/*******************************************************************************
 *
 * Disables PCI-Express master access and verifies there are no pending requests
 *
 * hw: Struct containing variables accessed by shared code
 *
 * returns: - E1000_ERR_MASTER_REQUESTS_PENDING if master disable bit hasn't
 *            caused the master requests to be disabled.
 *            E1000_SUCCESS master requests disabled.
 *
 ******************************************************************************/
s32
e1000_disable_pciex_master(struct e1000_hw *hw)
{
    s32 timeout = MASTER_DISABLE_TIMEOUT;   /* 80ms */

    DEBUGFUNC("e1000_disable_pciex_master");

    if (hw->bus_type != e1000_bus_type_pci_express)
        return E1000_SUCCESS;

    e1000_set_pci_express_master_disable(hw);

    while (timeout) {
        if (!(E1000_READ_REG(hw, STATUS) & E1000_STATUS_GIO_MASTER_ENABLE))
            break;
        else
            udelay(100);
        timeout--;
    }

    if (!timeout) {
        DEBUGOUT("Master requests are pending.\n");
        return -E1000_ERR_MASTER_REQUESTS_PENDING;
    }

    return E1000_SUCCESS;
}

/*******************************************************************************
 *
 * Check for EEPROM Auto Read bit done.
 *
 * hw: Struct containing variables accessed by shared code
 *
 * returns: - E1000_ERR_RESET if fail to reset MAC
 *            E1000_SUCCESS at any other case.
 *
 ******************************************************************************/
static s32
e1000_get_auto_rd_done(struct e1000_hw *hw)
{
    s32 timeout = AUTO_READ_DONE_TIMEOUT;

    DEBUGFUNC("e1000_get_auto_rd_done");

    switch (hw->mac_type) {
    default:
        msleep(5);
        break;
    case e1000_82571:
    case e1000_82572:
    case e1000_82573:
    case e1000_80003es2lan:
    case e1000_ich8lan:
        while (timeout) {
            if (E1000_READ_REG(hw, EECD) & E1000_EECD_AUTO_RD)
                break;
            else msleep(1);
            timeout--;
        }

        if (!timeout) {
            DEBUGOUT("Auto read by HW from EEPROM has not completed.\n");
            return -E1000_ERR_RESET;
        }
        break;
    }

    /* PHY configuration from NVM just starts after EECD_AUTO_RD sets to high.
     * Need to wait for PHY configuration completion before accessing NVM
     * and PHY. */
    if (hw->mac_type == e1000_82573)
        msleep(25);

    return E1000_SUCCESS;
}

/***************************************************************************
 * Checks if the PHY configuration is done
 *
 * hw: Struct containing variables accessed by shared code
 *
 * returns: - E1000_ERR_RESET if fail to reset MAC
 *            E1000_SUCCESS at any other case.
 *
 ***************************************************************************/
static s32
e1000_get_phy_cfg_done(struct e1000_hw *hw)
{
    s32 timeout = PHY_CFG_TIMEOUT;
    u32 cfg_mask = E1000_EEPROM_CFG_DONE;

    DEBUGFUNC("e1000_get_phy_cfg_done");

    switch (hw->mac_type) {
    default:
        mdelay(10);
        break;
    case e1000_80003es2lan:
        /* Separate *_CFG_DONE_* bit for each port */
        if (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1)
            cfg_mask = E1000_EEPROM_CFG_DONE_PORT_1;
        /* Fall Through */
    case e1000_82571:
    case e1000_82572:
        while (timeout) {
            if (E1000_READ_REG(hw, EEMNGCTL) & cfg_mask)
                break;
            else
                msleep(1);
            timeout--;
        }
        if (!timeout) {
            DEBUGOUT("MNG configuration cycle has not completed.\n");
            return -E1000_ERR_RESET;
        }
        break;
    }

    return E1000_SUCCESS;
}

/***************************************************************************
 *
 * Using the combination of SMBI and SWESMBI semaphore bits when resetting
 * adapter or Eeprom access.
 *
 * hw: Struct containing variables accessed by shared code
 *
 * returns: - E1000_ERR_EEPROM if fail to access EEPROM.
 *            E1000_SUCCESS at any other case.
 *
 ***************************************************************************/
static s32
e1000_get_hw_eeprom_semaphore(struct e1000_hw *hw)
{
    s32 timeout;
    u32 swsm;

    DEBUGFUNC("e1000_get_hw_eeprom_semaphore");

    if (!hw->eeprom_semaphore_present)
        return E1000_SUCCESS;

    if (hw->mac_type == e1000_80003es2lan) {
        /* Get the SW semaphore. */
        if (e1000_get_software_semaphore(hw) != E1000_SUCCESS)
            return -E1000_ERR_EEPROM;
    }

    /* Get the FW semaphore. */
    timeout = hw->eeprom.word_size + 1;
    while (timeout) {
        swsm = E1000_READ_REG(hw, SWSM);
        swsm |= E1000_SWSM_SWESMBI;
        E1000_WRITE_REG(hw, SWSM, swsm);
        /* if we managed to set the bit we got the semaphore. */
        swsm = E1000_READ_REG(hw, SWSM);
        if (swsm & E1000_SWSM_SWESMBI)
            break;

        udelay(50);
        timeout--;
    }

    if (!timeout) {
        /* Release semaphores */
        e1000_put_hw_eeprom_semaphore(hw);
        DEBUGOUT("Driver can't access the Eeprom - SWESMBI bit is set.\n");
        return -E1000_ERR_EEPROM;
    }

    return E1000_SUCCESS;
}

/***************************************************************************
 * This function clears HW semaphore bits.
 *
 * hw: Struct containing variables accessed by shared code
 *
 * returns: - None.
 *
 ***************************************************************************/
static void
e1000_put_hw_eeprom_semaphore(struct e1000_hw *hw)
{
    u32 swsm;

    DEBUGFUNC("e1000_put_hw_eeprom_semaphore");

    if (!hw->eeprom_semaphore_present)
        return;

    swsm = E1000_READ_REG(hw, SWSM);
    if (hw->mac_type == e1000_80003es2lan) {
        /* Release both semaphores. */
        swsm &= ~(E1000_SWSM_SMBI | E1000_SWSM_SWESMBI);
    } else
        swsm &= ~(E1000_SWSM_SWESMBI);
    E1000_WRITE_REG(hw, SWSM, swsm);
}

/***************************************************************************
 *
 * Obtaining software semaphore bit (SMBI) before resetting PHY.
 *
 * hw: Struct containing variables accessed by shared code
 *
 * returns: - E1000_ERR_RESET if fail to obtain semaphore.
 *            E1000_SUCCESS at any other case.
 *
 ***************************************************************************/
static s32
e1000_get_software_semaphore(struct e1000_hw *hw)
{
    s32 timeout = hw->eeprom.word_size + 1;
    u32 swsm;

    DEBUGFUNC("e1000_get_software_semaphore");

    if (hw->mac_type != e1000_80003es2lan) {
        return E1000_SUCCESS;
    }

    while (timeout) {
        swsm = E1000_READ_REG(hw, SWSM);
        /* If SMBI bit cleared, it is now set and we hold the semaphore */
        if (!(swsm & E1000_SWSM_SMBI))
            break;
        mdelay(1);
        timeout--;
    }

    if (!timeout) {
        DEBUGOUT("Driver can't access device - SMBI bit is set.\n");
        return -E1000_ERR_RESET;
    }

    return E1000_SUCCESS;
}

/***************************************************************************
 *
 * Release semaphore bit (SMBI).
 *
 * hw: Struct containing variables accessed by shared code
 *
 ***************************************************************************/
static void
e1000_release_software_semaphore(struct e1000_hw *hw)
{
    u32 swsm;

    DEBUGFUNC("e1000_release_software_semaphore");

    if (hw->mac_type != e1000_80003es2lan) {
        return;
    }

    swsm = E1000_READ_REG(hw, SWSM);
    /* Release the SW semaphores.*/
    swsm &= ~E1000_SWSM_SMBI;
    E1000_WRITE_REG(hw, SWSM, swsm);
}

/******************************************************************************
 * Checks if PHY reset is blocked due to SOL/IDER session, for example.
 * Returning E1000_BLK_PHY_RESET isn't necessarily an error.  But it's up to
 * the caller to figure out how to deal with it.
 *
 * hw - Struct containing variables accessed by shared code
 *
 * returns: - E1000_BLK_PHY_RESET
 *            E1000_SUCCESS
 *
 *****************************************************************************/
s32
e1000_check_phy_reset_block(struct e1000_hw *hw)
{
    u32 manc = 0;
    u32 fwsm = 0;

    if (hw->mac_type == e1000_ich8lan) {
        fwsm = E1000_READ_REG(hw, FWSM);
        return (fwsm & E1000_FWSM_RSPCIPHY) ? E1000_SUCCESS
                                            : E1000_BLK_PHY_RESET;
    }

    if (hw->mac_type > e1000_82547_rev_2)
        manc = E1000_READ_REG(hw, MANC);
    return (manc & E1000_MANC_BLK_PHY_RST_ON_IDE) ?
        E1000_BLK_PHY_RESET : E1000_SUCCESS;
}

static u8
e1000_arc_subsystem_valid(struct e1000_hw *hw)
{
    u32 fwsm;

    /* On 8257x silicon, registers in the range of 0x8800 - 0x8FFC
     * may not be provided a DMA clock when no manageability features are
     * enabled.  We do not want to perform any reads/writes to these registers
     * if this is the case.  We read FWSM to determine the manageability mode.
     */
    switch (hw->mac_type) {
    case e1000_82571:
    case e1000_82572:
    case e1000_82573:
    case e1000_80003es2lan:
        fwsm = E1000_READ_REG(hw, FWSM);
        if ((fwsm & E1000_FWSM_MODE_MASK) != 0)
            return true;
        break;
    case e1000_ich8lan:
        return true;
    default:
        break;
    }
    return false;
}


/******************************************************************************
 * Configure PCI-Ex no-snoop
 *
 * hw - Struct containing variables accessed by shared code.
 * no_snoop - Bitmap of no-snoop events.
 *
 * returns: E1000_SUCCESS
 *
 *****************************************************************************/
static s32
e1000_set_pci_ex_no_snoop(struct e1000_hw *hw, u32 no_snoop)
{
    u32 gcr_reg = 0;

    DEBUGFUNC("e1000_set_pci_ex_no_snoop");

    if (hw->bus_type == e1000_bus_type_unknown)
        e1000_get_bus_info(hw);

    if (hw->bus_type != e1000_bus_type_pci_express)
        return E1000_SUCCESS;

    if (no_snoop) {
        gcr_reg = E1000_READ_REG(hw, GCR);
        gcr_reg &= ~(PCI_EX_NO_SNOOP_ALL);
        gcr_reg |= no_snoop;
        E1000_WRITE_REG(hw, GCR, gcr_reg);
    }
    if (hw->mac_type == e1000_ich8lan) {
        u32 ctrl_ext;

        E1000_WRITE_REG(hw, GCR, PCI_EX_82566_SNOOP_ALL);

        ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
        ctrl_ext |= E1000_CTRL_EXT_RO_DIS;
        E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
    }

    return E1000_SUCCESS;
}

/***************************************************************************
 *
 * Get software semaphore FLAG bit (SWFLAG).
 * SWFLAG is used to synchronize the access to all shared resource between
 * SW, FW and HW.
 *
 * hw: Struct containing variables accessed by shared code
 *
 ***************************************************************************/
static s32
e1000_get_software_flag(struct e1000_hw *hw)
{
    s32 timeout = PHY_CFG_TIMEOUT;
    u32 extcnf_ctrl;

    DEBUGFUNC("e1000_get_software_flag");

    if (hw->mac_type == e1000_ich8lan) {
        while (timeout) {
            extcnf_ctrl = E1000_READ_REG(hw, EXTCNF_CTRL);
            extcnf_ctrl |= E1000_EXTCNF_CTRL_SWFLAG;
            E1000_WRITE_REG(hw, EXTCNF_CTRL, extcnf_ctrl);

            extcnf_ctrl = E1000_READ_REG(hw, EXTCNF_CTRL);
            if (extcnf_ctrl & E1000_EXTCNF_CTRL_SWFLAG)
                break;
            mdelay(1);
            timeout--;
        }

        if (!timeout) {
            DEBUGOUT("FW or HW locks the resource too long.\n");
            return -E1000_ERR_CONFIG;
        }
    }

    return E1000_SUCCESS;
}

/***************************************************************************
 *
 * Release software semaphore FLAG bit (SWFLAG).
 * SWFLAG is used to synchronize the access to all shared resource between
 * SW, FW and HW.
 *
 * hw: Struct containing variables accessed by shared code
 *
 ***************************************************************************/
static void
e1000_release_software_flag(struct e1000_hw *hw)
{
    u32 extcnf_ctrl;

    DEBUGFUNC("e1000_release_software_flag");

    if (hw->mac_type == e1000_ich8lan) {
        extcnf_ctrl= E1000_READ_REG(hw, EXTCNF_CTRL);
        extcnf_ctrl &= ~E1000_EXTCNF_CTRL_SWFLAG;
        E1000_WRITE_REG(hw, EXTCNF_CTRL, extcnf_ctrl);
    }

    return;
}

/******************************************************************************
 * Reads a 16 bit word or words from the EEPROM using the ICH8's flash access
 * register.
 *
 * hw - Struct containing variables accessed by shared code
 * offset - offset of word in the EEPROM to read
 * data - word read from the EEPROM
 * words - number of words to read
 *****************************************************************************/
static s32
e1000_read_eeprom_ich8(struct e1000_hw *hw, u16 offset, u16 words,
                       u16 *data)
{
    s32  error = E1000_SUCCESS;
    u32 flash_bank = 0;
    u32 act_offset = 0;
    u32 bank_offset = 0;
    u16 word = 0;
    u16 i = 0;

    /* We need to know which is the valid flash bank.  In the event
     * that we didn't allocate eeprom_shadow_ram, we may not be
     * managing flash_bank.  So it cannot be trusted and needs
     * to be updated with each read.
     */
    /* Value of bit 22 corresponds to the flash bank we're on. */
    flash_bank = (E1000_READ_REG(hw, EECD) & E1000_EECD_SEC1VAL) ? 1 : 0;

    /* Adjust offset appropriately if we're on bank 1 - adjust for word size */
    bank_offset = flash_bank * (hw->flash_bank_size * 2);

    error = e1000_get_software_flag(hw);
    if (error != E1000_SUCCESS)
        return error;

    for (i = 0; i < words; i++) {
        if (hw->eeprom_shadow_ram != NULL &&
            hw->eeprom_shadow_ram[offset+i].modified) {
            data[i] = hw->eeprom_shadow_ram[offset+i].eeprom_word;
        } else {
            /* The NVM part needs a byte offset, hence * 2 */
            act_offset = bank_offset + ((offset + i) * 2);
            error = e1000_read_ich8_word(hw, act_offset, &word);
            if (error != E1000_SUCCESS)
                break;
            data[i] = word;
        }
    }

    e1000_release_software_flag(hw);

    return error;
}

/******************************************************************************
 * Writes a 16 bit word or words to the EEPROM using the ICH8's flash access
 * register.  Actually, writes are written to the shadow ram cache in the hw
 * structure hw->e1000_shadow_ram.  e1000_commit_shadow_ram flushes this to
 * the NVM, which occurs when the NVM checksum is updated.
 *
 * hw - Struct containing variables accessed by shared code
 * offset - offset of word in the EEPROM to write
 * words - number of words to write
 * data - words to write to the EEPROM
 *****************************************************************************/
static s32
e1000_write_eeprom_ich8(struct e1000_hw *hw, u16 offset, u16 words,
                        u16 *data)
{
    u32 i = 0;
    s32 error = E1000_SUCCESS;

    error = e1000_get_software_flag(hw);
    if (error != E1000_SUCCESS)
        return error;

    /* A driver can write to the NVM only if it has eeprom_shadow_ram
     * allocated.  Subsequent reads to the modified words are read from
     * this cached structure as well.  Writes will only go into this
     * cached structure unless it's followed by a call to
     * e1000_update_eeprom_checksum() where it will commit the changes
     * and clear the "modified" field.
     */
    if (hw->eeprom_shadow_ram != NULL) {
        for (i = 0; i < words; i++) {
            if ((offset + i) < E1000_SHADOW_RAM_WORDS) {
                hw->eeprom_shadow_ram[offset+i].modified = true;
                hw->eeprom_shadow_ram[offset+i].eeprom_word = data[i];
            } else {
                error = -E1000_ERR_EEPROM;
                break;
            }
        }
    } else {
        /* Drivers have the option to not allocate eeprom_shadow_ram as long
         * as they don't perform any NVM writes.  An attempt in doing so
         * will result in this error.
         */
        error = -E1000_ERR_EEPROM;
    }

    e1000_release_software_flag(hw);

    return error;
}

/******************************************************************************
 * This function does initial flash setup so that a new read/write/erase cycle
 * can be started.
 *
 * hw - The pointer to the hw structure
 ****************************************************************************/
static s32
e1000_ich8_cycle_init(struct e1000_hw *hw)
{
    union ich8_hws_flash_status hsfsts;
    s32 error = E1000_ERR_EEPROM;
    s32 i     = 0;

    DEBUGFUNC("e1000_ich8_cycle_init");

    hsfsts.regval = E1000_READ_ICH_FLASH_REG16(hw, ICH_FLASH_HSFSTS);

    /* May be check the Flash Des Valid bit in Hw status */
    if (hsfsts.hsf_status.fldesvalid == 0) {
        DEBUGOUT("Flash descriptor invalid.  SW Sequencing must be used.");
        return error;
    }

    /* Clear FCERR in Hw status by writing 1 */
    /* Clear DAEL in Hw status by writing a 1 */
    hsfsts.hsf_status.flcerr = 1;
    hsfsts.hsf_status.dael = 1;

    E1000_WRITE_ICH_FLASH_REG16(hw, ICH_FLASH_HSFSTS, hsfsts.regval);

    /* Either we should have a hardware SPI cycle in progress bit to check
     * against, in order to start a new cycle or FDONE bit should be changed
     * in the hardware so that it is 1 after harware reset, which can then be
     * used as an indication whether a cycle is in progress or has been
     * completed .. we should also have some software semaphore mechanism to
     * guard FDONE or the cycle in progress bit so that two threads access to
     * those bits can be sequentiallized or a way so that 2 threads dont
     * start the cycle at the same time */

    if (hsfsts.hsf_status.flcinprog == 0) {
        /* There is no cycle running at present, so we can start a cycle */
        /* Begin by setting Flash Cycle Done. */
        hsfsts.hsf_status.flcdone = 1;
        E1000_WRITE_ICH_FLASH_REG16(hw, ICH_FLASH_HSFSTS, hsfsts.regval);
        error = E1000_SUCCESS;
    } else {
        /* otherwise poll for sometime so the current cycle has a chance
         * to end before giving up. */
        for (i = 0; i < ICH_FLASH_COMMAND_TIMEOUT; i++) {
            hsfsts.regval = E1000_READ_ICH_FLASH_REG16(hw, ICH_FLASH_HSFSTS);
            if (hsfsts.hsf_status.flcinprog == 0) {
                error = E1000_SUCCESS;
                break;
            }
            udelay(1);
        }
        if (error == E1000_SUCCESS) {
            /* Successful in waiting for previous cycle to timeout,
             * now set the Flash Cycle Done. */
            hsfsts.hsf_status.flcdone = 1;
            E1000_WRITE_ICH_FLASH_REG16(hw, ICH_FLASH_HSFSTS, hsfsts.regval);
        } else {
            DEBUGOUT("Flash controller busy, cannot get access");
        }
    }
    return error;
}

/******************************************************************************
 * This function starts a flash cycle and waits for its completion
 *
 * hw - The pointer to the hw structure
 ****************************************************************************/
static s32
e1000_ich8_flash_cycle(struct e1000_hw *hw, u32 timeout)
{
    union ich8_hws_flash_ctrl hsflctl;
    union ich8_hws_flash_status hsfsts;
    s32 error = E1000_ERR_EEPROM;
    u32 i = 0;

    /* Start a cycle by writing 1 in Flash Cycle Go in Hw Flash Control */
    hsflctl.regval = E1000_READ_ICH_FLASH_REG16(hw, ICH_FLASH_HSFCTL);
    hsflctl.hsf_ctrl.flcgo = 1;
    E1000_WRITE_ICH_FLASH_REG16(hw, ICH_FLASH_HSFCTL, hsflctl.regval);

    /* wait till FDONE bit is set to 1 */
    do {
        hsfsts.regval = E1000_READ_ICH_FLASH_REG16(hw, ICH_FLASH_HSFSTS);
        if (hsfsts.hsf_status.flcdone == 1)
            break;
        udelay(1);
        i++;
    } while (i < timeout);
    if (hsfsts.hsf_status.flcdone == 1 && hsfsts.hsf_status.flcerr == 0) {
        error = E1000_SUCCESS;
    }
    return error;
}

/******************************************************************************
 * Reads a byte or word from the NVM using the ICH8 flash access registers.
 *
 * hw - The pointer to the hw structure
 * index - The index of the byte or word to read.
 * size - Size of data to read, 1=byte 2=word
 * data - Pointer to the word to store the value read.
 *****************************************************************************/
static s32
e1000_read_ich8_data(struct e1000_hw *hw, u32 index,
                     u32 size, u16* data)
{
    union ich8_hws_flash_status hsfsts;
    union ich8_hws_flash_ctrl hsflctl;
    u32 flash_linear_address;
    u32 flash_data = 0;
    s32 error = -E1000_ERR_EEPROM;
    s32 count = 0;

    DEBUGFUNC("e1000_read_ich8_data");

    if (size < 1  || size > 2 || data == NULL ||
        index > ICH_FLASH_LINEAR_ADDR_MASK)
        return error;

    flash_linear_address = (ICH_FLASH_LINEAR_ADDR_MASK & index) +
                           hw->flash_base_addr;

    do {
        udelay(1);
        /* Steps */
        error = e1000_ich8_cycle_init(hw);
        if (error != E1000_SUCCESS)
            break;

        hsflctl.regval = E1000_READ_ICH_FLASH_REG16(hw, ICH_FLASH_HSFCTL);
        /* 0b/1b corresponds to 1 or 2 byte size, respectively. */
        hsflctl.hsf_ctrl.fldbcount = size - 1;
        hsflctl.hsf_ctrl.flcycle = ICH_CYCLE_READ;
        E1000_WRITE_ICH_FLASH_REG16(hw, ICH_FLASH_HSFCTL, hsflctl.regval);

        /* Write the last 24 bits of index into Flash Linear address field in
         * Flash Address */
        /* TODO: TBD maybe check the index against the size of flash */

        E1000_WRITE_ICH_FLASH_REG(hw, ICH_FLASH_FADDR, flash_linear_address);

        error = e1000_ich8_flash_cycle(hw, ICH_FLASH_COMMAND_TIMEOUT);

        /* Check if FCERR is set to 1, if set to 1, clear it and try the whole
         * sequence a few more times, else read in (shift in) the Flash Data0,
         * the order is least significant byte first msb to lsb */
        if (error == E1000_SUCCESS) {
            flash_data = E1000_READ_ICH_FLASH_REG(hw, ICH_FLASH_FDATA0);
            if (size == 1) {
                *data = (u8)(flash_data & 0x000000FF);
            } else if (size == 2) {
                *data = (u16)(flash_data & 0x0000FFFF);
            }
            break;
        } else {
            /* If we've gotten here, then things are probably completely hosed,
             * but if the error condition is detected, it won't hurt to give
             * it another try...ICH_FLASH_CYCLE_REPEAT_COUNT times.
             */
            hsfsts.regval = E1000_READ_ICH_FLASH_REG16(hw, ICH_FLASH_HSFSTS);
            if (hsfsts.hsf_status.flcerr == 1) {
                /* Repeat for some time before giving up. */
                continue;
            } else if (hsfsts.hsf_status.flcdone == 0) {
                DEBUGOUT("Timeout error - flash cycle did not complete.");
                break;
            }
        }
    } while (count++ < ICH_FLASH_CYCLE_REPEAT_COUNT);

    return error;
}

/******************************************************************************
 * Writes One /two bytes to the NVM using the ICH8 flash access registers.
 *
 * hw - The pointer to the hw structure
 * index - The index of the byte/word to read.
 * size - Size of data to read, 1=byte 2=word
 * data - The byte(s) to write to the NVM.
 *****************************************************************************/
static s32
e1000_write_ich8_data(struct e1000_hw *hw, u32 index, u32 size,
                      u16 data)
{
    union ich8_hws_flash_status hsfsts;
    union ich8_hws_flash_ctrl hsflctl;
    u32 flash_linear_address;
    u32 flash_data = 0;
    s32 error = -E1000_ERR_EEPROM;
    s32 count = 0;

    DEBUGFUNC("e1000_write_ich8_data");

    if (size < 1  || size > 2 || data > size * 0xff ||
        index > ICH_FLASH_LINEAR_ADDR_MASK)
        return error;

    flash_linear_address = (ICH_FLASH_LINEAR_ADDR_MASK & index) +
                           hw->flash_base_addr;

    do {
        udelay(1);
        /* Steps */
        error = e1000_ich8_cycle_init(hw);
        if (error != E1000_SUCCESS)
            break;

        hsflctl.regval = E1000_READ_ICH_FLASH_REG16(hw, ICH_FLASH_HSFCTL);
        /* 0b/1b corresponds to 1 or 2 byte size, respectively. */
        hsflctl.hsf_ctrl.fldbcount = size -1;
        hsflctl.hsf_ctrl.flcycle = ICH_CYCLE_WRITE;
        E1000_WRITE_ICH_FLASH_REG16(hw, ICH_FLASH_HSFCTL, hsflctl.regval);

        /* Write the last 24 bits of index into Flash Linear address field in
         * Flash Address */
        E1000_WRITE_ICH_FLASH_REG(hw, ICH_FLASH_FADDR, flash_linear_address);

        if (size == 1)
            flash_data = (u32)data & 0x00FF;
        else
            flash_data = (u32)data;

        E1000_WRITE_ICH_FLASH_REG(hw, ICH_FLASH_FDATA0, flash_data);

        /* check if FCERR is set to 1 , if set to 1, clear it and try the whole
         * sequence a few more times else done */
        error = e1000_ich8_flash_cycle(hw, ICH_FLASH_COMMAND_TIMEOUT);
        if (error == E1000_SUCCESS) {
            break;
        } else {
            /* If we're here, then things are most likely completely hosed,
             * but if the error condition is detected, it won't hurt to give
             * it another try...ICH_FLASH_CYCLE_REPEAT_COUNT times.
             */
            hsfsts.regval = E1000_READ_ICH_FLASH_REG16(hw, ICH_FLASH_HSFSTS);
            if (hsfsts.hsf_status.flcerr == 1) {
                /* Repeat for some time before giving up. */
                continue;
            } else if (hsfsts.hsf_status.flcdone == 0) {
                DEBUGOUT("Timeout error - flash cycle did not complete.");
                break;
            }
        }
    } while (count++ < ICH_FLASH_CYCLE_REPEAT_COUNT);

    return error;
}

/******************************************************************************
 * Reads a single byte from the NVM using the ICH8 flash access registers.
 *
 * hw - pointer to e1000_hw structure
 * index - The index of the byte to read.
 * data - Pointer to a byte to store the value read.
 *****************************************************************************/
static s32
e1000_read_ich8_byte(struct e1000_hw *hw, u32 index, u8* data)
{
    s32 status = E1000_SUCCESS;
    u16 word = 0;

    status = e1000_read_ich8_data(hw, index, 1, &word);
    if (status == E1000_SUCCESS) {
        *data = (u8)word;
    }

    return status;
}

/******************************************************************************
 * Writes a single byte to the NVM using the ICH8 flash access registers.
 * Performs verification by reading back the value and then going through
 * a retry algorithm before giving up.
 *
 * hw - pointer to e1000_hw structure
 * index - The index of the byte to write.
 * byte - The byte to write to the NVM.
 *****************************************************************************/
static s32
e1000_verify_write_ich8_byte(struct e1000_hw *hw, u32 index, u8 byte)
{
    s32 error = E1000_SUCCESS;
    s32 program_retries = 0;

    DEBUGOUT2("Byte := %2.2X Offset := %d\n", byte, index);

    error = e1000_write_ich8_byte(hw, index, byte);

    if (error != E1000_SUCCESS) {
        for (program_retries = 0; program_retries < 100; program_retries++) {
            DEBUGOUT2("Retrying \t Byte := %2.2X Offset := %d\n", byte, index);
            error = e1000_write_ich8_byte(hw, index, byte);
            udelay(100);
            if (error == E1000_SUCCESS)
                break;
        }
    }

    if (program_retries == 100)
        error = E1000_ERR_EEPROM;

    return error;
}

/******************************************************************************
 * Writes a single byte to the NVM using the ICH8 flash access registers.
 *
 * hw - pointer to e1000_hw structure
 * index - The index of the byte to read.
 * data - The byte to write to the NVM.
 *****************************************************************************/
static s32
e1000_write_ich8_byte(struct e1000_hw *hw, u32 index, u8 data)
{
    s32 status = E1000_SUCCESS;
    u16 word = (u16)data;

    status = e1000_write_ich8_data(hw, index, 1, word);

    return status;
}

/******************************************************************************
 * Reads a word from the NVM using the ICH8 flash access registers.
 *
 * hw - pointer to e1000_hw structure
 * index - The starting byte index of the word to read.
 * data - Pointer to a word to store the value read.
 *****************************************************************************/
static s32
e1000_read_ich8_word(struct e1000_hw *hw, u32 index, u16 *data)
{
    s32 status = E1000_SUCCESS;
    status = e1000_read_ich8_data(hw, index, 2, data);
    return status;
}

/******************************************************************************
 * Erases the bank specified. Each bank may be a 4, 8 or 64k block. Banks are 0
 * based.
 *
 * hw - pointer to e1000_hw structure
 * bank - 0 for first bank, 1 for second bank
 *
 * Note that this function may actually erase as much as 8 or 64 KBytes.  The
 * amount of NVM used in each bank is a *minimum* of 4 KBytes, but in fact the
 * bank size may be 4, 8 or 64 KBytes
 *****************************************************************************/
static s32
e1000_erase_ich8_4k_segment(struct e1000_hw *hw, u32 bank)
{
    union ich8_hws_flash_status hsfsts;
    union ich8_hws_flash_ctrl hsflctl;
    u32 flash_linear_address;
    s32  count = 0;
    s32  error = E1000_ERR_EEPROM;
    s32  iteration;
    s32  sub_sector_size = 0;
    s32  bank_size;
    s32  j = 0;
    s32  error_flag = 0;

    hsfsts.regval = E1000_READ_ICH_FLASH_REG16(hw, ICH_FLASH_HSFSTS);

    /* Determine HW Sector size: Read BERASE bits of Hw flash Status register */
    /* 00: The Hw sector is 256 bytes, hence we need to erase 16
     *     consecutive sectors.  The start index for the nth Hw sector can be
     *     calculated as bank * 4096 + n * 256
     * 01: The Hw sector is 4K bytes, hence we need to erase 1 sector.
     *     The start index for the nth Hw sector can be calculated
     *     as bank * 4096
     * 10: The HW sector is 8K bytes
     * 11: The Hw sector size is 64K bytes */
    if (hsfsts.hsf_status.berasesz == 0x0) {
        /* Hw sector size 256 */
        sub_sector_size = ICH_FLASH_SEG_SIZE_256;
        bank_size = ICH_FLASH_SECTOR_SIZE;
        iteration = ICH_FLASH_SECTOR_SIZE / ICH_FLASH_SEG_SIZE_256;
    } else if (hsfsts.hsf_status.berasesz == 0x1) {
        bank_size = ICH_FLASH_SEG_SIZE_4K;
        iteration = 1;
    } else if (hsfsts.hsf_status.berasesz == 0x3) {
        bank_size = ICH_FLASH_SEG_SIZE_64K;
        iteration = 1;
    } else {
        return error;
    }

    for (j = 0; j < iteration ; j++) {
        do {
            count++;
            /* Steps */
            error = e1000_ich8_cycle_init(hw);
            if (error != E1000_SUCCESS) {
                error_flag = 1;
                break;
            }

            /* Write a value 11 (block Erase) in Flash Cycle field in Hw flash
             * Control */
            hsflctl.regval = E1000_READ_ICH_FLASH_REG16(hw, ICH_FLASH_HSFCTL);
            hsflctl.hsf_ctrl.flcycle = ICH_CYCLE_ERASE;
            E1000_WRITE_ICH_FLASH_REG16(hw, ICH_FLASH_HSFCTL, hsflctl.regval);

            /* Write the last 24 bits of an index within the block into Flash
             * Linear address field in Flash Address.  This probably needs to
             * be calculated here based off the on-chip erase sector size and
             * the software bank size (4, 8 or 64 KBytes) */
            flash_linear_address = bank * bank_size + j * sub_sector_size;
            flash_linear_address += hw->flash_base_addr;
            flash_linear_address &= ICH_FLASH_LINEAR_ADDR_MASK;

            E1000_WRITE_ICH_FLASH_REG(hw, ICH_FLASH_FADDR, flash_linear_address);

            error = e1000_ich8_flash_cycle(hw, ICH_FLASH_ERASE_TIMEOUT);
            /* Check if FCERR is set to 1.  If 1, clear it and try the whole
             * sequence a few more times else Done */
            if (error == E1000_SUCCESS) {
                break;
            } else {
                hsfsts.regval = E1000_READ_ICH_FLASH_REG16(hw, ICH_FLASH_HSFSTS);
                if (hsfsts.hsf_status.flcerr == 1) {
                    /* repeat for some time before giving up */
                    continue;
                } else if (hsfsts.hsf_status.flcdone == 0) {
                    error_flag = 1;
                    break;
                }
            }
        } while ((count < ICH_FLASH_CYCLE_REPEAT_COUNT) && !error_flag);
        if (error_flag == 1)
            break;
    }
    if (error_flag != 1)
        error = E1000_SUCCESS;
    return error;
}

static s32
e1000_init_lcd_from_nvm_config_region(struct e1000_hw *hw,
                                      u32 cnf_base_addr, u32 cnf_size)
{
    u32 ret_val = E1000_SUCCESS;
    u16 word_addr, reg_data, reg_addr;
    u16 i;

    /* cnf_base_addr is in DWORD */
    word_addr = (u16)(cnf_base_addr << 1);

    /* cnf_size is returned in size of dwords */
    for (i = 0; i < cnf_size; i++) {
        ret_val = e1000_read_eeprom(hw, (word_addr + i*2), 1, &reg_data);
        if (ret_val)
            return ret_val;

        ret_val = e1000_read_eeprom(hw, (word_addr + i*2 + 1), 1, &reg_addr);
        if (ret_val)
            return ret_val;

        ret_val = e1000_get_software_flag(hw);
        if (ret_val != E1000_SUCCESS)
            return ret_val;

        ret_val = e1000_write_phy_reg_ex(hw, (u32)reg_addr, reg_data);

        e1000_release_software_flag(hw);
    }

    return ret_val;
}


/******************************************************************************
 * This function initializes the PHY from the NVM on ICH8 platforms. This
 * is needed due to an issue where the NVM configuration is not properly
 * autoloaded after power transitions. Therefore, after each PHY reset, we
 * will load the configuration data out of the NVM manually.
 *
 * hw: Struct containing variables accessed by shared code
 *****************************************************************************/
static s32
e1000_init_lcd_from_nvm(struct e1000_hw *hw)
{
    u32 reg_data, cnf_base_addr, cnf_size, ret_val, loop;

    if (hw->phy_type != e1000_phy_igp_3)
          return E1000_SUCCESS;

    /* Check if SW needs configure the PHY */
    reg_data = E1000_READ_REG(hw, FEXTNVM);
    if (!(reg_data & FEXTNVM_SW_CONFIG))
        return E1000_SUCCESS;

    /* Wait for basic configuration completes before proceeding*/
    loop = 0;
    do {
        reg_data = E1000_READ_REG(hw, STATUS) & E1000_STATUS_LAN_INIT_DONE;
        udelay(100);
        loop++;
    } while ((!reg_data) && (loop < 50));

    /* Clear the Init Done bit for the next init event */
    reg_data = E1000_READ_REG(hw, STATUS);
    reg_data &= ~E1000_STATUS_LAN_INIT_DONE;
    E1000_WRITE_REG(hw, STATUS, reg_data);

    /* Make sure HW does not configure LCD from PHY extended configuration
       before SW configuration */
    reg_data = E1000_READ_REG(hw, EXTCNF_CTRL);
    if ((reg_data & E1000_EXTCNF_CTRL_LCD_WRITE_ENABLE) == 0x0000) {
        reg_data = E1000_READ_REG(hw, EXTCNF_SIZE);
        cnf_size = reg_data & E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH;
        cnf_size >>= 16;
        if (cnf_size) {
            reg_data = E1000_READ_REG(hw, EXTCNF_CTRL);
            cnf_base_addr = reg_data & E1000_EXTCNF_CTRL_EXT_CNF_POINTER;
            /* cnf_base_addr is in DWORD */
            cnf_base_addr >>= 16;

            /* Configure LCD from extended configuration region. */
            ret_val = e1000_init_lcd_from_nvm_config_region(hw, cnf_base_addr,
                                                            cnf_size);
            if (ret_val)
                return ret_val;
        }
    }

    return E1000_SUCCESS;
}



<|start_filename|>3rdpart/ethercat-1.5.2/tool/CommandRescan.cpp<|end_filename|>
/*****************************************************************************
 *
 *  $Id: CommandRescan.cpp,v bc2d4bf9cbe5 2012/09/06 18:22:24 fp $
 *
 *  Copyright (C) 2006-2009  <NAME>, Ingenieurgemeinschaft IgH
 *
 *  This file is part of the IgH EtherCAT Master.
 *
 *  The IgH EtherCAT Master is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License version 2, as
 *  published by the Free Software Foundation.
 *
 *  The IgH EtherCAT Master is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 *  Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with the IgH EtherCAT Master; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 *  vim: expandtab
 *
 ****************************************************************************/

#include <sstream>
#include <iomanip>
using namespace std;

#include "CommandRescan.h"
#include "MasterDevice.h"

/*****************************************************************************/

CommandRescan::CommandRescan():
    Command("rescan", "Rescan the bus.")
{
}

/*****************************************************************************/

string CommandRescan::helpString(const string &binaryBaseName) const
{
    stringstream str;

    str << binaryBaseName << " " << getName() << endl
        << endl
        << getBriefDescription() << endl
        << endl
        << "Command a bus rescan. Gathered slave information will be" << endl
        << "forgotten and slaves will be read in again." << endl
        << endl;

    return str.str();
}

/****************************************************************************/

void CommandRescan::execute(const StringVector &args)
{
	MasterIndexList masterIndices;

    if (args.size() != 0) {
        stringstream err;
        err << "'" << getName() << "' takes no arguments!";
        throwInvalidUsageException(err);
    }

	masterIndices = getMasterIndices();
    MasterIndexList::const_iterator mi;
    for (mi = masterIndices.begin();
            mi != masterIndices.end(); mi++) {
        MasterDevice m(*mi);
        m.open(MasterDevice::ReadWrite);
        m.rescan();
    }
}

/*****************************************************************************/


<|start_filename|>rootfs/buildroot-2017.11.1/package/perl-http-message/perl-http-message.mk<|end_filename|>
################################################################################
#
# perl-http-message
#
################################################################################

PERL_HTTP_MESSAGE_VERSION = 6.13
PERL_HTTP_MESSAGE_SOURCE = HTTP-Message-$(PERL_HTTP_MESSAGE_VERSION).tar.gz
PERL_HTTP_MESSAGE_SITE = $(BR2_CPAN_MIRROR)/authors/id/O/OA/OALDERS
PERL_HTTP_MESSAGE_DEPENDENCIES = perl-encode-locale perl-http-date perl-io-html perl-lwp-mediatypes perl-uri
PERL_HTTP_MESSAGE_LICENSE = Artistic or GPL-1.0+
PERL_HTTP_MESSAGE_LICENSE_FILES = LICENSE

$(eval $(perl-package))


<|start_filename|>3rdpart/ethercat-1.5.2/master/fsm_slave.h<|end_filename|>
/******************************************************************************
 *
 *  $Id: fsm_slave.h,v 9cdd7669dc0b 2013/01/10 16:36:41 fp $
 *
 *  Copyright (C) 2006-2012  <NAME>, Ingenieurgemeinschaft IgH
 *
 *  This file is part of the IgH EtherCAT Master.
 *
 *  The IgH EtherCAT Master is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License version 2, as
 *  published by the Free Software Foundation.
 *
 *  The IgH EtherCAT Master is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 *  Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with the IgH EtherCAT Master; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 *****************************************************************************/

/**
   \file
   EtherCAT slave request state machine.
*/

/*****************************************************************************/

#ifndef __EC_FSM_SLAVE_H__
#define __EC_FSM_SLAVE_H__

#include "globals.h"
#include "datagram.h"
#include "sdo_request.h"
#include "reg_request.h"
#include "fsm_coe.h"
#include "fsm_foe.h"
#include "fsm_soe.h"

/*****************************************************************************/

typedef struct ec_fsm_slave ec_fsm_slave_t; /**< \see ec_fsm_slave */

/** Finite state machine of an EtherCAT slave.
 */
struct ec_fsm_slave {
    ec_slave_t *slave; /**< slave the FSM runs on */
    struct list_head list; /**< Used for execution list. */

    void (*state)(ec_fsm_slave_t *, ec_datagram_t *); /**< State function. */
    ec_datagram_t *datagram; /**< Previous state datagram. */
    ec_sdo_request_t *sdo_request; /**< SDO request to process. */
    ec_reg_request_t *reg_request; /**< Register request to process. */
    ec_foe_request_t *foe_request; /**< FoE request to process. */
    off_t foe_index; /**< Index to FoE write request data. */
    ec_soe_request_t *soe_request; /**< SoE request to process. */

    ec_fsm_coe_t fsm_coe; /**< CoE state machine. */
    ec_fsm_foe_t fsm_foe; /**< FoE state machine. */
    ec_fsm_soe_t fsm_soe; /**< SoE state machine. */
};

/*****************************************************************************/

void ec_fsm_slave_init(ec_fsm_slave_t *, ec_slave_t *);
void ec_fsm_slave_clear(ec_fsm_slave_t *);

int ec_fsm_slave_exec(ec_fsm_slave_t *, ec_datagram_t *);
void ec_fsm_slave_set_ready(ec_fsm_slave_t *);
int ec_fsm_slave_is_ready(const ec_fsm_slave_t *);

/*****************************************************************************/


#endif // __EC_FSM_SLAVE_H__


<|start_filename|>apps/ecat-master/main/gui.h<|end_filename|>
/*
 * gui.h
 *
 *  Created on: Mar 16, 2018
 *      Author: morris
 */

#ifndef GUI_H_
#define GUI_H_

#include "lvgl/lvgl.h"

int gui_init(void);
void gui_stop(void);
void gui_user_work(void* arg);

#endif /* GUI_H_ */


<|start_filename|>3rdpart/tslib-1.15/src/ts_get_eventpath.c<|end_filename|>
/*
 *  tslib/src/ts_get_eventpath.c
 *
 *  Copyright (C) 2017 <NAME>
 *
 * SPDX-License-Identifier: LGPL-2.1
 */
#include "tslib-private.h"

char *ts_get_eventpath(struct tsdev *tsdev)
{
	return tsdev->eventpath;
}


<|start_filename|>3rdpart/tslib-1.15/tools/ts_uinput.c<|end_filename|>
/*
 * (C) 2017 Ginzinger electronic systems GmbH, A-4952 Weng im Innkreis
 *
 * <NAME> <<EMAIL>>  2016-09-14
 * <NAME> <<EMAIL>>  2015-09-30
 *
 * This file is part of tslib.
 *
 * ts_uinput is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * ts_uinput is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with ts_uinput.  If not, see <http://www.gnu.org/licenses/>.
 *
 * SPDX-License-Identifier: GPL-2.0+
 *
 *
 * ts_uinput daemon to generate (single- and multitouch) input events
 * taken from tslib multitouch samples. It's a userspace evdev driver
 * and thus Linux specific.
 */

#define _GNU_SOURCE
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <tslib.h>
#include <unistd.h>
#include <signal.h>
#include <syslog.h>
#include <dirent.h>
#ifdef __FreeBSD__
#include <dev/evdev/input.h>
#include <dev/evdev/uinput.h>
#include <sys/types.h>
#include <sys/fbio.h>
#else
#include <linux/input.h>
#include <linux/uinput.h>
#include <linux/fb.h>
#endif

#define RESET   "\033[0m"
#define RED     "\033[31m"
#define GREEN   "\033[32m"
#define BLUE    "\033[34m"

#define BITS_PER_BYTE           8
#define BITS_PER_LONG           (sizeof(long) * BITS_PER_BYTE)
#define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1)
#define OFF(x)  ((x)%BITS_PER_LONG)
#define BIT(x)  (1UL<<OFF(x))
#define LONG(x) ((x)/BITS_PER_LONG)
#define test_bit(bit, array)	((array[LONG(bit)] >> OFF(bit)) & 1)

#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
#define BIT_MASK(nr)            (1UL << ((nr) % BITS_PER_LONG))
#define BIT_WORD(nr)            ((nr) / BITS_PER_LONG)
#define BITS_TO_LONGS(nr)       DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long))

#define DEFAULT_UINPUT_NAME "ts_uinput"

#ifndef ABS_MT_SLOT /* < 2.6.36 kernel headers */
# define ABS_MT_SLOT             0x2f    /* MT slot being modified */
#endif
#ifndef ABS_MT_POSITION_X /* < 2.6.30 kernel headers */
# define ABS_MT_TOUCH_MAJOR      0x30    /* Major axis of touching ellipse */
# define ABS_MT_TOUCH_MINOR      0x31    /* Minor axis (omit if circular) */
# define ABS_MT_WIDTH_MAJOR      0x32    /* Major axis of approaching ellipse */
# define ABS_MT_WIDTH_MINOR      0x33    /* Minor axis (omit if circular) */
# define ABS_MT_ORIENTATION      0x34    /* Ellipse orientation */
# define ABS_MT_POSITION_X       0x35    /* Center X touch position */
# define ABS_MT_POSITION_Y       0x36    /* Center Y touch position */
# define ABS_MT_TOOL_TYPE        0x37    /* Type of touching device */
# define ABS_MT_BLOB_ID          0x38    /* Group a set of packets as a blob */
# define ABS_MT_TRACKING_ID      0x39    /* Unique ID of initiated contact */
#endif
#ifndef ABS_MT_PRESSURE /* < 2.6.33 kernel headers */
# define ABS_MT_PRESSURE         0x3a    /* Pressure on contact area */
#endif
#ifndef ABS_MT_DISTANCE /* < 2.6.38 kernel headers */
# define ABS_MT_DISTANCE         0x3b    /* Contact hover distance */
#endif
#ifndef ABS_MT_TOOL_X /* < 3.6 kernel headers */
# define ABS_MT_TOOL_X           0x3c    /* Center X tool position */
# define ABS_MT_TOOL_Y           0x3d    /* Center Y tool position */
#endif

#define SYS_INPUT_DIR "/sys/devices/virtual/input/"

#ifndef UINPUT_VERSION
#define UINPUT_VERSION	2
#endif

static char *defaultfbdevice = "/dev/fb0";

struct data_t {
	int fd_uinput;
	int fd_input;
	int fd_fb;
	char *uinput_name;
	char *input_name;
	char *fb_name;
	struct tsdev *ts;
	unsigned short verbose;
	unsigned short verbose_daemon;
	struct input_event *ev;
	struct ts_sample_mt **s_array;
	int slots;
	unsigned short uinput_version;
	short mt_type_a;
	unsigned short nofb;
};

static void help(void)
{
	struct ts_lib_version_data *ver = ts_libversion();

	printf("                 _       _ _ _\n");
	printf("                | |_ ___| (_) |__\n");
	printf("                | __/ __| | | '_ \\\n");
	printf("                | |_\\__ \\ | | |_) |\n");
	printf("                 \\__|___/_|_|_.__/\n\n");
	printf("tslib %s / libts ABI version %d (0x%06X)\n",
		ver->package_version, ver->version_num >> 16, ver->version_num);
	printf("\n");
	printf("Starts tslib instance listening to given event <device>, creates a virtual\n");
	printf("input event device with given <name> using 'uinput', then continually reads\n");
	printf("touch reports from tslib and replays them as touch events of protocol type B\n");
	printf("on the virtual device.\n");
	printf("\n");
	printf("Usage: ts_uinput [-v] [-d] [-i <device>] [-f <device>] [-n <name>] [-s <slots>]\n");
	printf("\n");
	printf("  -h, --help          this help text\n");
	printf("  -d, --daemonize     run in the background as a daemon\n");
	printf("  -v, --verbose       verbose output\n");
	printf("  -n, --name          set name of new input device  (default: " DEFAULT_UINPUT_NAME")\n");
	printf("  -i, --idev          touchscreen's input device\n");
	printf("  -f, --fbdev         touchscreen's framebuffer device\n");
	printf("  -s, --slots         override available concurrent touch contacts\n");
	printf("  -b, --nofb          read screen resolution from the input dev, not the framebuffer device.\n");
	printf("\n");
	printf("See the manpage for further details.\n");
}

#define MAX_CODES_PER_SLOT 20
static int send_touch_events(struct data_t *data, struct ts_sample_mt **s,
			     int nr, int max_slots)
{
	int i;
	int j;
	int c = 0;

	for (j = 0; j < nr; j++) {
		memset(data->ev,
		       0,
		       sizeof(struct input_event) * MAX_CODES_PER_SLOT * max_slots);

		for (i = 0; i < max_slots; i++) {
			if (!(s[j][i].valid & TSLIB_MT_VALID))
				continue;

			if (s[j][i].pen_down == 1) {
				data->ev[c].time = s[j][i].tv;
				data->ev[c].type = EV_KEY;
				data->ev[c].code = BTN_TOUCH;
				data->ev[c].value = s[j][i].pen_down;
				c++;
			}

			data->ev[c].time = s[j][i].tv;
			data->ev[c].type = EV_ABS;
			data->ev[c].code = ABS_MT_SLOT;
			data->ev[c].value = s[j][i].slot;
			c++;

			/*
			 * This simply supports legacy input events when only
			 * one finger is used.
			 * XXX We should track slot 0, and if it is gone
			 * we should use slot 1 and so on.
			 */
			if (i == 0) {
				data->ev[c].time = s[j][i].tv;
				data->ev[c].type = EV_ABS;
				data->ev[c].code = ABS_X;
				data->ev[c].value = s[j][i].x;
				c++;

				data->ev[c].time = s[j][i].tv;
				data->ev[c].type = EV_ABS;
				data->ev[c].code = ABS_Y;
				data->ev[c].value = s[j][i].y;
				c++;

				data->ev[c].time = s[j][i].tv;
				data->ev[c].type = EV_ABS;
				data->ev[c].code = ABS_PRESSURE;
				data->ev[c].value = s[j][i].pressure;
				c++;
			}

			data->ev[c].time = s[j][i].tv;
			data->ev[c].type = EV_ABS;
			data->ev[c].code = ABS_MT_POSITION_X;
			data->ev[c].value = s[j][i].x;
			c++;

			data->ev[c].time = s[j][i].tv;
			data->ev[c].type = EV_ABS;
			data->ev[c].code = ABS_MT_POSITION_Y;
			data->ev[c].value = s[j][i].y;
			c++;

			data->ev[c].time = s[j][i].tv;
			data->ev[c].type = EV_ABS;
			data->ev[c].code = ABS_MT_PRESSURE;
			data->ev[c].value = s[j][i].pressure;
			c++;

			data->ev[c].time = s[j][i].tv;
			data->ev[c].type = EV_ABS;
			data->ev[c].code = ABS_MT_TOUCH_MAJOR;
			data->ev[c].value = s[j][i].touch_major;
			c++;

			data->ev[c].time = s[j][i].tv;
			data->ev[c].type = EV_ABS;
			data->ev[c].code = ABS_MT_WIDTH_MAJOR;
			data->ev[c].value = s[j][i].width_major;
			c++;

			data->ev[c].time = s[j][i].tv;
			data->ev[c].type = EV_ABS;
			data->ev[c].code = ABS_MT_TOUCH_MINOR;
			data->ev[c].value = s[j][i].touch_minor;
			c++;

			data->ev[c].time = s[j][i].tv;
			data->ev[c].type = EV_ABS;
			data->ev[c].code = ABS_MT_WIDTH_MINOR;
			data->ev[c].value = s[j][i].width_minor;
			c++;

			data->ev[c].time = s[j][i].tv;
			data->ev[c].type = EV_ABS;
			data->ev[c].code = ABS_MT_TOOL_TYPE;
			data->ev[c].value = s[j][i].tool_type;
			c++;

			data->ev[c].time = s[j][i].tv;
			data->ev[c].type = EV_ABS;
			data->ev[c].code = ABS_MT_TOOL_X;
			data->ev[c].value = s[j][i].tool_x;
			c++;

			data->ev[c].time = s[j][i].tv;
			data->ev[c].type = EV_ABS;
			data->ev[c].code = ABS_MT_TOOL_Y;
			data->ev[c].value = s[j][i].tool_y;
			c++;

			data->ev[c].time = s[j][i].tv;
			data->ev[c].type = EV_ABS;
			data->ev[c].code = ABS_MT_ORIENTATION;
			data->ev[c].value = s[j][i].orientation;
			c++;

			data->ev[c].time = s[j][i].tv;
			data->ev[c].type = EV_ABS;
			data->ev[c].code = ABS_MT_DISTANCE;
			data->ev[c].value = s[j][i].distance;
			c++;

			data->ev[c].time = s[j][i].tv;
			data->ev[c].type = EV_ABS;
			data->ev[c].code = ABS_MT_BLOB_ID;
			data->ev[c].value = s[j][i].blob_id;
			c++;

			data->ev[c].time = s[j][i].tv;
			data->ev[c].type = EV_ABS;
			data->ev[c].code = ABS_MT_TRACKING_ID;
			data->ev[c].value = s[j][i].tracking_id;
			c++;

			if (data->mt_type_a == 1) {
				data->ev[c].time = s[j][i].tv;
				data->ev[c].type = EV_SYN;
				data->ev[c].code = SYN_MT_REPORT;
				data->ev[c].value = 0;
				c++;
			}

			if (s[j][i].pen_down == 0) {
				data->ev[c].time = s[j][i].tv;
				data->ev[c].type = EV_KEY;
				data->ev[c].code = BTN_TOUCH;
				data->ev[c].value = s[j][i].pen_down;
				c++;
			}

		}

		if (c > 0) {
			data->ev[c].time = s[j][i].tv;
			data->ev[c].type = EV_SYN;
			data->ev[c].code = SYN_REPORT;
			data->ev[c].value = 0;


			if (write(data->fd_uinput,
				  data->ev,
				  sizeof(struct input_event) * (c + 1)) < 0) {
				perror("write");
				return errno;
			}
		}

		c = 0;
	}

	return 0;
}

static int get_abs_max_fb(struct data_t *data, int *max_x, int *max_y)
{
	struct fb_var_screeninfo fbinfo;

	if (ioctl(data->fd_fb, FBIOGET_VSCREENINFO, &fbinfo) < 0) {
		perror("ioctl FBIOGET_VSCREENINFO");
		return errno;
	}

	*max_x = fbinfo.xres - 1;
	*max_y = fbinfo.yres - 1;

	return 0;
}

static int get_abs_max_input(struct data_t *data, int *max_x, int *max_y)
{
	long absbit[BITS_TO_LONGS(ABS_CNT)];
	struct input_absinfo absinfo;
	int abs_x_only;

	if (ioctl(data->fd_input, EVIOCGBIT(EV_ABS, sizeof(absbit)), absbit) < 0) {
		perror("ioctl EVIOCGBIT");
		return errno;
	}

	if (!(absbit[BIT_WORD(ABS_MT_POSITION_X)] & BIT_MASK(ABS_MT_POSITION_X)) ||
	    !(absbit[BIT_WORD(ABS_MT_POSITION_Y)] & BIT_MASK(ABS_MT_POSITION_Y))) {
		if (!(absbit[BIT_WORD(ABS_X)] & BIT_MASK(ABS_X)) ||
		    !(absbit[BIT_WORD(ABS_Y)] & BIT_MASK(ABS_Y))) {
			return errno;
		} else {
			abs_x_only = 1;
		}
	} else {
		abs_x_only = 0;
	}

	if (abs_x_only) {
		if (ioctl(data->fd_input, EVIOCGABS(ABS_X), &absinfo) < 0) {
			perror("ioctl EVIOCGABS");
			return errno;
		}
		*max_x = absinfo.maximum;

		if (ioctl(data->fd_input, EVIOCGABS(ABS_Y), &absinfo) < 0) {
			perror("ioctl EVIOCGABS");
			return errno;
		}
		*max_y = absinfo.maximum;
	} else {
		if (ioctl(data->fd_input, EVIOCGABS(ABS_MT_POSITION_X), &absinfo) < 0) {
			perror("ioctl EVIOCGABS");
			return errno;
		}
		*max_x = absinfo.maximum;

		if (ioctl(data->fd_input, EVIOCGABS(ABS_MT_POSITION_Y), &absinfo) < 0) {
			perror("ioctl EVIOCGABS");
			return errno;
		}
		*max_y = absinfo.maximum;
	}

	return 0;
}

static int setup_uinput(struct data_t *data, int *max_slots)
{
	struct uinput_user_dev uidev;
	unsigned long bit[EV_MAX][NBITS(KEY_MAX)];
	int i, j;
	struct input_absinfo absinfo;
	int max_x = 0;
	int max_y = 0;
	int ret;

	if (data->nofb)
		ret = get_abs_max_input(data, &max_x, &max_y);
	else
		ret = get_abs_max_fb(data, &max_x, &max_y);

	if (ret)
		return ret;

	data->fd_uinput = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
	if (data->fd_uinput == -1) {
		perror("open /dev/uinput");
		goto err;
	}

	if (ioctl(data->fd_uinput, UI_SET_EVBIT, EV_KEY) < 0 ||
	    ioctl(data->fd_uinput, UI_SET_EVBIT, EV_SYN) < 0 ||
	    ioctl(data->fd_uinput, UI_SET_KEYBIT, BTN_TOUCH) < 0 ||
	    ioctl(data->fd_uinput, UI_SET_EVBIT, EV_ABS) < 0) {
		perror("ioctl");
		goto err;
	}

	memset(&uidev, 0, sizeof(uidev));
	snprintf(uidev.name, UINPUT_MAX_NAME_SIZE, "%s", data->uinput_name);
	uidev.id.bustype = BUS_VIRTUAL;

	memset(bit, 0, sizeof(bit));

	/* get info on input device and copy setting over to uinput device */
	if (ioctl(data->fd_input, EVIOCGBIT(0, EV_MAX), bit[0]) < 0) {
		perror("ioctl EVIOCGBIT");
		goto err;
	}
	for (i = 0; i < EV_MAX; i++) {
		if (test_bit(i, bit[0])) {
			if (ioctl(data->fd_input,
				  EVIOCGBIT(i, KEY_MAX),
				  bit[i]) < 0) {
				perror("ioctl EVIOCGBIT");
				goto err;
			}

			for (j = 0; j < KEY_MAX; j++) {
				if (test_bit(j, bit[i])) {
					if (i == EV_ABS) {
						if (ioctl(data->fd_input,
							  EVIOCGABS(j),
							  &absinfo) < 0) {
							perror("ioctl EVIOCGABS");
							goto err;
						}

						if (ioctl(data->fd_uinput,
							  UI_SET_ABSBIT,
							  j) < 0) {
							perror("ioctl UI_SET_ABSBIT");
							goto err;
						}

						/*
						 * X and Y max/min are taken from the framebuffer device
						 * The rest comes from the input device.
						 */

						if (j == ABS_X) {
							uidev.absmin[ABS_X] = 0;
							uidev.absmax[ABS_X] = max_x;
						} else if (j == ABS_Y) {
							uidev.absmin[ABS_Y] = 0;
							uidev.absmax[ABS_Y] = max_y;
						} else if (j == ABS_MT_POSITION_X) {
							uidev.absmin[ABS_MT_POSITION_X] = 0;
							uidev.absmax[ABS_MT_POSITION_X] = max_x;
						} else if (j == ABS_MT_POSITION_Y) {
							uidev.absmin[ABS_MT_POSITION_Y] = 0;
							uidev.absmax[ABS_MT_POSITION_Y] = max_y;
						} else {
							uidev.absmin[j] = absinfo.minimum;
							uidev.absmax[j] = absinfo.maximum;
						}

						if (j == ABS_MT_SLOT)
							*max_slots = absinfo.maximum + 1 - absinfo.minimum;
					}
				}
			}
		}
	}

	if (write(data->fd_uinput, &uidev, sizeof(uidev)) == -1) {
		perror("write uinput_user_dev");
		goto err;
	}

	if (ioctl(data->fd_uinput, UI_DEV_CREATE) < 0) {
		perror("ioctl UI_DEV_CREATE");
		goto err;
	}

	return 0;

err:
	return errno;
}

static int process(struct data_t *data, struct ts_sample_mt **s_array,
		   int max_slots, int nr)
{
	int samples_read;
	int i, j;
	int ret;

	samples_read = ts_read_mt(data->ts, s_array, max_slots, nr);
	if (samples_read > 0) {
		ret = send_touch_events(data, s_array, samples_read, max_slots);
		if (ret)
			return ret;

		if (data->verbose) {
			for (j = 0; j < nr; j++) {
				printf(BLUE DEFAULT_UINPUT_NAME
				       ": sample %d:  x\ty\tslot\ttracking_id\n"
				       RESET, j);
				for (i = 0; i < max_slots; i++) {
					if (s_array[j][i].valid & TSLIB_MT_VALID) {
						printf(DEFAULT_UINPUT_NAME
						       ": \t%d\t%d\t%d\t%d\n",
						       s_array[j][i].x,
						       s_array[j][i].y,
						       s_array[j][i].slot,
						       s_array[j][i].tracking_id);
					}
				}
			}
		}
	} else if (samples_read < 0 && samples_read != -EAGAIN) {
		if (data->verbose)
			fprintf(stderr, RED DEFAULT_UINPUT_NAME
				": ts_read_mt failure.\n" RESET);

		return samples_read;
	}

	return 0;
}

#define TS_READ_WHOLE_SAMPLES 1

static void cleanup(struct data_t *data)
{
	int i;
	int ret;

	if (data->s_array) {
		for (i = 0; i < TS_READ_WHOLE_SAMPLES; i++) {
			if (data->s_array[i])
				free(data->s_array[i]);
		}
		free(data->s_array);
	}

	if (data->ev)
		free(data->ev);

	if (data->ts)
		ts_close(data->ts);

	if (data->fd_uinput > 0) {
		ret = ioctl(data->fd_uinput, UI_DEV_DESTROY);
		if (ret == -1)
			perror("ioctl UI_DEV_DESTROY");

		close(data->fd_uinput);
	}

	if (data->fd_input)
		close(data->fd_input);

	if (data->fd_fb)
		close(data->fd_fb);

	if (data->uinput_name)
		free(data->uinput_name);
}

/* directly from libevdev (LGPL) */
static int is_event_device(const struct dirent *dent)
{
	return strncmp("event", dent->d_name, 5) == 0;
}

/* directly from libevdev (LGPL) */
static char *fetch_device_node(const char *path)
{
	char *devnode = NULL;
	struct dirent **namelist;
	int ndev, i;

	ndev = scandir(path, &namelist, is_event_device, alphasort);
	if (ndev <= 0)
		return NULL;

	/* ndev should only ever be 1 */

	for (i = 0; i < ndev; i++) {
		if (!devnode && asprintf(&devnode, "/dev/input/%s", namelist[i]->d_name) == -1)
			devnode = NULL;
		free(namelist[i]);
	}

	free(namelist);

	return devnode;
}

int main(int argc, char **argv)
{
	struct data_t data = {
		.fd_uinput = 0,
		.fd_input = 0,
		.uinput_name = NULL,
		.input_name = NULL,
		.fb_name = NULL,
		.ts = NULL,
		.verbose = 0,
		.ev = NULL,
		.s_array = NULL,
		.slots = 1,
		.mt_type_a = 0,
		.verbose_daemon = 0,
		.nofb = 0,
	};
	int i, j;
	unsigned short run_daemon = 0;
	char *dev_input_name = NULL;
	int ret;
	struct ts_sample_mt *testsample;
	struct ts_sample_mt **testsample_p;

	while (1) {
		const struct option long_options[] = {
			{ "help",         no_argument,       NULL, 'h' },
			{ "name",         required_argument, NULL, 'n' },
			{ "verbose",      no_argument,       NULL, 'v' },
			{ "daemonize",    no_argument,       NULL, 'd' },
			{ "idev",         required_argument, NULL, 'i' },
			{ "fbdev",        required_argument, NULL, 'f' },
			{ "slots",        required_argument, NULL, 's' },
			{ "nofb",         no_argument,       NULL, 'b' },
		};

		int option_index = 0;
		int c = getopt_long(argc, argv, "dhn:f:i:vs:b", long_options,
				    &option_index);

		if (c == -1)
			break;

		errno = 0;
		switch (c) {
		case 'h':
			help();
			return 0;

		case 'n':
			data.uinput_name = optarg;
			break;

		case 'v':
			data.verbose = 1;
			break;

		case 'b':
			data.nofb = 1;
			break;

		case 'd':
			run_daemon = 1;
			break;

		case 'i':
			data.input_name = optarg;
			break;

		case 'f':
			data.fb_name = optarg;
			break;

		case 's':
			data.slots = atoi(optarg);
			break;

		default:
			help();
			return 0;
		}

		if (errno) {
			char str[9];

			sprintf(str, "option ?");
			str[7] = c & 0xff;
			perror(str);
		}
	}

	/* if we run as a daemon, we don't print all debug output. we print
	 * the input device node before returning.
	 */
	if (data.verbose && run_daemon) {
		data.verbose = 0;
		data.verbose_daemon = 1;
	}

	if (data.verbose) {
		printf(BLUE "\ntslib environment variables:" RESET "\n");
		printf("       TSLIB_TSDEVICE: '%s'\n", getenv("TSLIB_TSDEVICE"));
		printf("      TSLIB_PLUGINDIR: '%s'\n", getenv("TSLIB_PLUGINDIR"));
		printf("  TSLIB_CONSOLEDEVICE: '%s'\n", getenv("TSLIB_CONSOLEDEVICE"));
		printf("       TSLIB_FBDEVICE: '%s'\n", getenv("TSLIB_FBDEVICE"));
		printf("      TSLIB_CALIBFILE: '%s'\n", getenv("TSLIB_CALIBFILE"));
		printf("       TSLIB_CONFFILE: '%s'\n", getenv("TSLIB_CONFFILE"));
		printf("\n");
	}

	if (!data.uinput_name) {
		data.uinput_name = malloc(strlen(DEFAULT_UINPUT_NAME) + 1);
		if (!data.uinput_name)
			return errno;
		sprintf(data.uinput_name, DEFAULT_UINPUT_NAME);
	}

	if (!data.nofb) {
		if (!data.fb_name) {
			if (getenv("TSLIB_FBDEVICE"))
				data.fb_name = getenv("TSLIB_FBDEVICE");
			else
				data.fb_name = defaultfbdevice;
		}

		data.fd_fb = open(data.fb_name, O_RDWR);
		if (data.fd_fb == -1) {
			perror("open");
			goto out;
		}

		if (data.verbose)
			printf(DEFAULT_UINPUT_NAME ": using framebuffer device "
			       GREEN "%s" RESET "\n",
			       data.fb_name);
	}

	/* non-blocking for one read in order to verify reading and fail before forking */
	data.ts = ts_setup(data.input_name, 1);
	if (!data.ts) {
		perror("ts_setup");
		goto out;
	}

	testsample_p = calloc(1, sizeof(struct ts_sample_mt *));
	if (!testsample_p)
		goto out;
	testsample = calloc(1, sizeof(struct ts_sample_mt));
	if (!testsample) {
		free(testsample_p);
		goto out;
	}
	testsample_p[0] = testsample;

	ret = ts_read_mt(data.ts, testsample_p, 1, 1);
	if (ret < 0 && ret != -EAGAIN) {
		free(testsample);
		free(testsample_p);
		goto out;
	}

	ts_close(data.ts);
	free(testsample);
	free(testsample_p);

	/* blocking setup for production run */
	data.ts = ts_setup(data.input_name, 0);
	if (!data.ts) {
		perror("ts_setup");
		goto out;
	}

	dev_input_name = ts_get_eventpath(data.ts);
	if (!dev_input_name)
		goto out;

	data.fd_input = open(dev_input_name, O_RDWR);
	if (data.fd_input == -1) {
		perror("open");
		goto out;
	}

	if (data.verbose)
		printf(DEFAULT_UINPUT_NAME
		       ": using input device " GREEN "%s" RESET "\n",
		       dev_input_name);

	if (setup_uinput(&data, &data.slots)) {
		goto out;
	} else {
		if (data.verbose && data.slots == 1)
			printf(DEFAULT_UINPUT_NAME
			       ": We don't use a multitouch device\n");
		else if (data.verbose && data.slots > 1)
			printf(DEFAULT_UINPUT_NAME
			       ": We use a "
			       GREEN "multitouch" RESET
			       " device\n");
	}

	if (data.verbose) {
		printf(DEFAULT_UINPUT_NAME ": running uinput version %d\n", UINPUT_VERSION);
		#if UINPUT_VERSION >= 4
			char name[64];
			int ret = ioctl(data.fd_uinput,
					UI_GET_SYSNAME(sizeof(name)),
					name);
			if (ret >= 0) {
				char buf[sizeof(SYS_INPUT_DIR) + sizeof(name)] = SYS_INPUT_DIR;
				char *devnode;

				snprintf(&buf[strlen(SYS_INPUT_DIR)], sizeof(name), "%s", name);
				fprintf(stdout, "created %s\n", buf);
				devnode = fetch_device_node(buf);
				if (devnode)
					fprintf(stdout, "%s\n", devnode);
			}
		#else
			fprintf(stderr, DEFAULT_UINPUT_NAME
				": See the kernel log for the device number\n");
		#endif
	}

	data.ev = malloc(sizeof(struct input_event) * MAX_CODES_PER_SLOT * data.slots);
	if (!data.ev)
		goto out;

	data.s_array = calloc(TS_READ_WHOLE_SAMPLES,
			      sizeof(struct ts_sample_mt *));
	if (!data.s_array)
		goto out;

	for (i = 0; i < TS_READ_WHOLE_SAMPLES; i++) {
		data.s_array[i] = malloc(data.slots * sizeof(struct ts_sample_mt));
		if (!data.s_array[i]) {
			fprintf(stderr, DEFAULT_UINPUT_NAME
				": Error allocating memory\n");
			for (j = 0; j <= i; j++)
				free(data.s_array[j]);
			goto out;
		}
	}

	if (run_daemon) {
	#if UINPUT_VERSION >= 4
		char name[64];
		int ret = ioctl(data.fd_uinput,
				UI_GET_SYSNAME(sizeof(name)),
				name);
		if (ret >= 0) {
			if (data.verbose_daemon) {
				char buf[sizeof(SYS_INPUT_DIR) + sizeof(name)] = SYS_INPUT_DIR;
				char *devnode;

				snprintf(&buf[strlen(SYS_INPUT_DIR)], sizeof(name), "%s", name);
				devnode = fetch_device_node(buf);
				if (devnode)
					fprintf(stdout, "%s\n", devnode);
			} else {
				fprintf(stdout, "%s\n", name);
			}

			fflush(stdout);
		} else {
			perror("ioctl UI_GET_SYSNAME");
			goto out;
		}
	#else
		fprintf(stderr, DEFAULT_UINPUT_NAME
		": See the kernel log for the device number\n");
	#endif
		if (daemon(0, 0) == -1) {
			perror("error starting daemon");
			goto out;
		}
	}

	while (1) {
		if (process(&data, data.s_array, data.slots,
			    TS_READ_WHOLE_SAMPLES))
			goto out;
	}

out:
	if (dev_input_name)
		free(dev_input_name);

	cleanup(&data);

	return errno;
}


<|start_filename|>apps/ecat-master/main/ecat.h<|end_filename|>
/*
 * ecat.h
 *
 *  Created on: Mar 12, 2018
 *      Author: morris
 */

#ifndef ECAT_H_
#define ECAT_H_

#include <stdint.h>

/* 运行过程中测量分布式时钟的性能 */
#define MEASURE_TIMING

/* 周期性任务1秒钟运行100次 */
#define FREQUENCY 		100
/* 用实时时钟作为参考时钟 */
#define CLOCK_TO_USE 	CLOCK_REALTIME

/* 1s = 10^9ns */
#define NSEC_PER_SEC 	(1000000000L)
/* 周期时间换算为纳秒单位 */
#define PERIOD_NS 		(NSEC_PER_SEC / FREQUENCY)

/* 时间差(B-A)，结果换算成纳秒单位 */
#define DIFF_NS(A, B) 	(((B).tv_sec - (A).tv_sec) * NSEC_PER_SEC + (B).tv_nsec - (A).tv_nsec)
/* 将时间单位timespec转换为纳秒单位 */
#define TIMESPEC2NS(T) 	((uint64_t)(T).tv_sec * NSEC_PER_SEC + (T).tv_nsec)

/**
 * EtherCAT从站在总线上的位置
 */
#define XMC_Slave0Pos 0, 0 /* slave alias, slave position */
#define XMC_Slave1Pos 0, 1 /* slave alias, slave position */

/**
 * 从站厂商信息与产品信息
 */
#define Infineon_XMC4800 0x0000034E, 0x12345678 /* vendor ID, product code */

typedef struct ecat_user_struct {
	/* 控制从站LED的状态值 */
	unsigned int blink0;
	unsigned int blink1;
	/* 从站上传的传感器数据 */
	uint16_t sensor_temp0;
	uint16_t sensor_temp1;
} ecat_user;

int ecat_init(void (*work_callback)(void*));
void ecat_stop(void);

#endif /* ECAT_H_ */


<|start_filename|>rootfs/buildroot-2017.11.1/package/bluez5_utils/bluez5_utils.mk<|end_filename|>
################################################################################
#
# bluez5_utils
#
################################################################################

BLUEZ5_UTILS_VERSION = 5.47
BLUEZ5_UTILS_SOURCE = bluez-$(BLUEZ5_UTILS_VERSION).tar.xz
BLUEZ5_UTILS_SITE = $(BR2_KERNEL_MIRROR)/linux/bluetooth
BLUEZ5_UTILS_INSTALL_STAGING = YES
BLUEZ5_UTILS_DEPENDENCIES = dbus libglib2
BLUEZ5_UTILS_LICENSE = GPL-2.0+, LGPL-2.1+
BLUEZ5_UTILS_LICENSE_FILES = COPYING COPYING.LIB

BLUEZ5_UTILS_CONF_OPTS = \
	--enable-tools \
	--enable-library \
	--disable-cups

ifeq ($(BR2_PACKAGE_BLUEZ5_UTILS_OBEX),y)
BLUEZ5_UTILS_CONF_OPTS += --enable-obex
BLUEZ5_UTILS_DEPENDENCIES += libical
else
BLUEZ5_UTILS_CONF_OPTS += --disable-obex
endif

ifeq ($(BR2_PACKAGE_BLUEZ5_UTILS_CLIENT),y)
BLUEZ5_UTILS_CONF_OPTS += --enable-client
BLUEZ5_UTILS_DEPENDENCIES += readline
else
BLUEZ5_UTILS_CONF_OPTS += --disable-client
endif

# experimental plugins
ifeq ($(BR2_PACKAGE_BLUEZ5_UTILS_EXPERIMENTAL),y)
BLUEZ5_UTILS_CONF_OPTS += --enable-experimental
else
BLUEZ5_UTILS_CONF_OPTS += --disable-experimental
endif

# enable health plugin
ifeq ($(BR2_PACKAGE_BLUEZ5_PLUGINS_HEALTH),y)
BLUEZ5_UTILS_CONF_OPTS += --enable-health
else
BLUEZ5_UTILS_CONF_OPTS += --disable-health
endif

# enable midi profile
ifeq ($(BR2_PACKAGE_BLUEZ5_PLUGINS_MIDI),y)
BLUEZ5_UTILS_CONF_OPTS += --enable-midi
BLUEZ5_UTILS_DEPENDENCIES += alsa-lib
else
BLUEZ5_UTILS_CONF_OPTS += --disable-midi
endif

# enable nfc plugin
ifeq ($(BR2_PACKAGE_BLUEZ5_PLUGINS_NFC),y)
BLUEZ5_UTILS_CONF_OPTS += --enable-nfc
else
BLUEZ5_UTILS_CONF_OPTS += --disable-nfc
endif

# enable sap plugin
ifeq ($(BR2_PACKAGE_BLUEZ5_PLUGINS_SAP),y)
BLUEZ5_UTILS_CONF_OPTS += --enable-sap
else
BLUEZ5_UTILS_CONF_OPTS += --disable-sap
endif

# enable sixaxis plugin
ifeq ($(BR2_PACKAGE_BLUEZ5_PLUGINS_SIXAXIS),y)
BLUEZ5_UTILS_CONF_OPTS += --enable-sixaxis
else
BLUEZ5_UTILS_CONF_OPTS += --disable-sixaxis
endif

# install gatttool (For some reason upstream choose not to do it by default)
ifeq ($(BR2_PACKAGE_BLUEZ5_UTILS_DEPRECATED),y)
define BLUEZ5_UTILS_INSTALL_GATTTOOL
	$(INSTALL) -D -m 0755 $(@D)/attrib/gatttool $(TARGET_DIR)/usr/bin/gatttool
endef
BLUEZ5_UTILS_POST_INSTALL_TARGET_HOOKS += BLUEZ5_UTILS_INSTALL_GATTTOOL
# hciattach_bcm43xx defines default firmware path in `/etc/firmware`, but
# Broadcom firmware blobs are usually located in `/lib/firmware`.
BLUEZ5_UTILS_CONF_ENV += \
	CPPFLAGS='$(TARGET_CPPFLAGS) -DFIRMWARE_DIR=\"/lib/firmware\"'
BLUEZ5_UTILS_CONF_OPTS += --enable-deprecated
else
BLUEZ5_UTILS_CONF_OPTS += --disable-deprecated
endif

# enable test
ifeq ($(BR2_PACKAGE_BLUEZ5_UTILS_TEST),y)
BLUEZ5_UTILS_CONF_OPTS += --enable-test
else
BLUEZ5_UTILS_CONF_OPTS += --disable-test
endif

# use udev if available
ifeq ($(BR2_PACKAGE_HAS_UDEV),y)
BLUEZ5_UTILS_CONF_OPTS += --enable-udev
BLUEZ5_UTILS_DEPENDENCIES += udev
else
BLUEZ5_UTILS_CONF_OPTS += --disable-udev
endif

# integrate with systemd if available
ifeq ($(BR2_PACKAGE_SYSTEMD),y)
BLUEZ5_UTILS_CONF_OPTS += --enable-systemd
BLUEZ5_UTILS_DEPENDENCIES += systemd
else
BLUEZ5_UTILS_CONF_OPTS += --disable-systemd
endif

define BLUEZ5_UTILS_INSTALL_INIT_SYSTEMD
	mkdir -p $(TARGET_DIR)/etc/systemd/system/bluetooth.target.wants
	ln -fs ../../../../usr/lib/systemd/system/bluetooth.service \
		$(TARGET_DIR)/etc/systemd/system/bluetooth.target.wants/bluetooth.service
	ln -fs ../../../../usr/lib/systemd/system/bluetooth.service \
		$(TARGET_DIR)/etc/systemd/system/dbus-org.bluez.service
endef

$(eval $(autotools-package))


<|start_filename|>3rdpart/tslib-1.15/tests/testutils.c<|end_filename|>
/*
 *  tslib/src/testutils.c
 *
 *  Copyright (C) 2001 <NAME>.
 *
 * This file is placed under the GPL.  Please see the file
 * COPYING for more details.
 *
 * SPDX-License-Identifier: GPL-2.0+
 *
 *
 * Common functions for the test programs
 */

#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/time.h>
#include "tslib.h"
#include "fbutils.h"
#include "testutils.h"

/* [inactive] border fill text [active] border fill text */
static int button_palette[6] = {
	1, 4, 2,
	1, 5, 0
};

void button_draw(struct ts_button *button)
{
	int s = (button->flags & BUTTON_ACTIVE) ? 3 : 0;

	rect(button->x, button->y, button->x + button->w,
	     button->y + button->h, button_palette[s]);
	fillrect(button->x + 1, button->y + 1,
		 button->x + button->w - 2,
		 button->y + button->h - 2, button_palette[s + 1]);
	put_string_center(button->x + button->w / 2,
			  button->y + button->h / 2,
			  button->text, button_palette[s + 2]);
}

int button_handle(struct ts_button *button, int x, int y, unsigned int p)
{
	int inside = (x >= button->x) && (y >= button->y) &&
		     (x < button->x + button->w) &&
		     (y < button->y + button->h);

	if (p > 0) {
		if (inside) {
			if (!(button->flags & BUTTON_ACTIVE)) {
				button->flags |= BUTTON_ACTIVE;
				button_draw(button);
			}
		} else if (button->flags & BUTTON_ACTIVE) {
			button->flags &= ~BUTTON_ACTIVE;
			button_draw(button);
		}
	} else if (button->flags & BUTTON_ACTIVE) {
		button->flags &= ~BUTTON_ACTIVE;
		button_draw(button);
		return 1;
	}

	return 0;
}

static int sort_by_x(const void *a, const void *b)
{
	return (((struct ts_sample *)a)->x - ((struct ts_sample *)b)->x);
}

static int sort_by_y(const void *a, const void *b)
{
	return (((struct ts_sample *)a)->y - ((struct ts_sample *)b)->y);
}

/* Waits for the screen to be touched, averages x and y sample
 * coordinates until the end of contact
 */
void getxy(struct tsdev *ts, int *x, int *y)
{
#define MAX_SAMPLES 128
	struct ts_sample samp[MAX_SAMPLES];
	int index, middle;

	do {
		if (ts_read_raw(ts, &samp[0], 1) < 0) {
			perror("ts_read");
			close_framebuffer();
			exit(1);
		}
	} while (samp[0].pressure == 0);

	/* Now collect up to MAX_SAMPLES touches into the samp array. */
	index = 0;
	do {
		if (index < MAX_SAMPLES-1)
			index++;
		if (ts_read_raw(ts, &samp[index], 1) < 0) {
			perror("ts_read");
			close_framebuffer();
			exit(1);
		}
	} while (samp[index].pressure > 0);
	printf("Took %d samples...\n", index);

	/*
	 * At this point, we have samples in indices zero to (index-1)
	 * which means that we have (index) number of samples.  We want
	 * to calculate the median of the samples so that wild outliers
	 * don't skew the result.  First off, let's assume that arrays
	 * are one-based instead of zero-based.  If this were the case
	 * and index was odd, we would need sample number ((index+1)/2)
	 * of a sorted array; if index was even, we would need the
	 * average of sample number (index/2) and sample number
	 * ((index/2)+1).  To turn this into something useful for the
	 * real world, we just need to subtract one off of the sample
	 * numbers.  So for when index is odd, we need sample number
	 * (((index+1)/2)-1).  Due to integer division truncation, we
	 * can simplify this to just (index/2).  When index is even, we
	 * need the average of sample number ((index/2)-1) and sample
	 * number (index/2).  Calculate (index/2) now and we'll handle
	 * the even odd stuff after we sort.
	 */
	middle = index/2;
	if (x) {
		qsort(samp, index, sizeof(struct ts_sample), sort_by_x);
		if (index & 1)
			*x = samp[middle].x;
		else
			*x = (samp[middle-1].x + samp[middle].x) / 2;
	}
	if (y) {
		qsort(samp, index, sizeof(struct ts_sample), sort_by_y);
		if (index & 1)
			*y = samp[middle].y;
		else
			*y = (samp[middle-1].y + samp[middle].y) / 2;
	}
}

void ts_flush(struct tsdev *ts)
{
	/* Read all unread touchscreen data,
	 * so that we are sure that the next data that we read
	 * have been input after this flushing.
	 */

#define TS_BUFFER_MAX 32768
	static char buffer[TS_BUFFER_MAX];

	if (read(ts_fd(ts), buffer, TS_BUFFER_MAX) == -1)
		fprintf(stderr, "ts_flush read error\n");
}

void print_ascii_logo(void)
{
	printf("                 _       _ _ _\n");
	printf("                | |_ ___| (_) |__\n");
	printf("                | __/ __| | | '_ \\\n");
	printf("                | |_\\__ \\ | | |_) |\n");
	printf("                 \\__|___/_|_|_.__/\n\n");
}


<|start_filename|>rootfs/buildroot-2017.11.1/package/boinc/boinc.mk<|end_filename|>
################################################################################
#
# boinc
#
################################################################################

BOINC_VERSION_MAJOR = 7.8
BOINC_VERSION = $(BOINC_VERSION_MAJOR).3
# client_release can be used to build the Client and Manager but not the Server
# part. The Server currently has no versioning (see
# https://github.com/BOINC/boinc/pull/1798).
BOINC_SITE = \
	$(call github,BOINC,boinc,client_release/$(BOINC_VERSION_MAJOR)/$(BOINC_VERSION))
BOINC_LICENSE = LGPL-3.0+
BOINC_LICENSE_FILES = COPYING COPYING.LESSER
BOINC_DEPENDENCIES = host-pkgconf libcurl openssl
BOINC_AUTORECONF = YES
BOINC_CONF_OPTS = \
	--disable-apps \
	--disable-boinczip \
	--disable-manager \
	--disable-server \
	--enable-client \
	--enable-dynamic-client-linkage \
	--enable-libraries \
	--with-pkg-config=$(PKG_CONFIG_HOST_BINARY) \
	--with-libcurl=$(STAGING_DIR)/usr

ifeq ($(BR2_PACKAGE_FREETYPE),y)
BOINC_DEPENDENCIES += freetype
endif

ifeq ($(BR2_PACKAGE_LIBFCGI),y)
BOINC_DEPENDENCIES += libfcgi
BOINC_CONF_OPTS += --enable-fcgi
else
BOINC_CONF_OPTS += --disable-fcgi
endif

# Remove boinc-client because it is incompatible with buildroot
define BOINC_REMOVE_UNNEEDED_FILE
	$(RM) $(TARGET_DIR)/etc/init.d/boinc-client
endef

BOINC_POST_INSTALL_TARGET_HOOKS += BOINC_REMOVE_UNNEEDED_FILE

define BOINC_INSTALL_INIT_SYSV
	 $(INSTALL) -D -m 0755 package/boinc/S99boinc-client \
		$(TARGET_DIR)/etc/init.d/S99boinc-client
endef

define BOINC_INSTALL_INIT_SYSTEMD
	$(INSTALL) -D -m 644 package/boinc/boinc-client.service \
		$(TARGET_DIR)/usr/lib/systemd/system/boinc-client.service
	mkdir -p $(TARGET_DIR)/etc/systemd/system/multi-user.target.wants
	ln -sf ../../../../usr/lib/systemd/system/boinc-client.service \
		$(TARGET_DIR)/etc/systemd/system/multi-user.target.wants/boinc-client.service
endef

$(eval $(autotools-package))


<|start_filename|>3rdpart/ethercat-1.5.2/lib/Makefile<|end_filename|>
# Makefile.in generated by automake 1.11.1 from Makefile.am.
# lib/Makefile.  Generated from Makefile.in by configure.

# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
# Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.



#------------------------------------------------------------------------------
#
#  $Id: Makefile.am,v 4c2e37d2237c 2013/02/12 16:30:45 fp $
#
#  Copyright (C) 2006-2012  <NAME>, Ingenieurgemeinschaft IgH
#
#  This file is part of the IgH EtherCAT master userspace library.
#
#  The IgH EtherCAT master userspace library is free software; you can
#  redistribute it and/or modify it under the terms of the GNU Lesser General
#  Public License as published by the Free Software Foundation; version 2.1 of
#  the License.
#
#  The IgH EtherCAT master userspace library is distributed in the hope that
#  it will be useful, but WITHOUT ANY WARRANTY; without even the implied
#  warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU Lesser General Public License for more details.
#
#  You should have received a copy of the GNU Lesser General Public License
#  along with the IgH EtherCAT master userspace library. If not, see
#  <http://www.gnu.org/licenses/>.
#
#  ---
#
#  The license mentioned above concerns the source code only. Using the
#  EtherCAT technology and brand is only permitted in compliance with the
#  industrial property and similar rights of Beckhoff Automation GmbH.
#
#------------------------------------------------------------------------------



pkgdatadir = $(datadir)/ethercat
pkgincludedir = $(includedir)/ethercat
pkglibdir = $(libdir)/ethercat
pkglibexecdir = $(libexecdir)/ethercat
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = x86_64-unknown-linux-gnu
host_triplet = arm-unknown-linux-gnueabihf

#------------------------------------------------------------------------------
#am__append_1 = libethercat_rtdm.la
##am__append_2 = $(XENOMAI_RTDM_CFLAGS)
##am__append_3 = $(XENOMAI_RTDM_LDFLAGS)
##am__append_4 = $(RTAI_LXRT_CFLAGS)
##am__append_5 = $(RTAI_LXRT_LDFLAGS)
subdir = lib
DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
	$(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
	$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
	$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
	$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
	$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
    *) f=$$p;; \
  esac;
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
am__install_max = 40
am__nobase_strip_setup = \
  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
am__nobase_strip = \
  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
am__nobase_list = $(am__nobase_strip_setup); \
  for p in $$list; do echo "$$p $$p"; done | \
  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
    if (++n[$$2] == $(am__install_max)) \
      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
    END { for (dir in files) print dir, files[dir] }'
am__base_list = \
  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__installdirs = "$(DESTDIR)$(libdir)"
LTLIBRARIES = $(lib_LTLIBRARIES)
libethercat_la_LIBADD =
am_libethercat_la_OBJECTS = libethercat_la-common.lo \
	libethercat_la-domain.lo libethercat_la-master.lo \
	libethercat_la-reg_request.lo libethercat_la-sdo_request.lo \
	libethercat_la-slave_config.lo libethercat_la-voe_handler.lo
libethercat_la_OBJECTS = $(am_libethercat_la_OBJECTS)
libethercat_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(libethercat_la_CFLAGS) \
	$(CFLAGS) $(libethercat_la_LDFLAGS) $(LDFLAGS) -o $@
libethercat_rtdm_la_LIBADD =
am__libethercat_rtdm_la_SOURCES_DIST = common.c domain.c master.c \
	reg_request.c sdo_request.c slave_config.c voe_handler.c
am__objects_1 = libethercat_rtdm_la-common.lo \
	libethercat_rtdm_la-domain.lo libethercat_rtdm_la-master.lo \
	libethercat_rtdm_la-reg_request.lo \
	libethercat_rtdm_la-sdo_request.lo \
	libethercat_rtdm_la-slave_config.lo \
	libethercat_rtdm_la-voe_handler.lo
#am_libethercat_rtdm_la_OBJECTS = $(am__objects_1)
libethercat_rtdm_la_OBJECTS = $(am_libethercat_rtdm_la_OBJECTS)
libethercat_rtdm_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
	$(LIBTOOLFLAGS) --mode=link $(CCLD) \
	$(libethercat_rtdm_la_CFLAGS) $(CFLAGS) \
	$(libethercat_rtdm_la_LDFLAGS) $(LDFLAGS) -o $@
#am_libethercat_rtdm_la_rpath = -rpath $(libdir)
DEFAULT_INCLUDES = -I. -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/autoconf/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
	--mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
	--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
	$(LDFLAGS) -o $@
SOURCES = $(libethercat_la_SOURCES) $(libethercat_rtdm_la_SOURCES)
DIST_SOURCES = $(libethercat_la_SOURCES) \
	$(am__libethercat_rtdm_la_SOURCES_DIST)
HEADERS = $(noinst_HEADERS)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = ${SHELL} /home/morris/SUDA_V3S/3rdpart/ethercat-1.5.2/autoconf/missing --run aclocal-1.11
AMTAR = ${SHELL} /home/morris/SUDA_V3S/3rdpart/ethercat-1.5.2/autoconf/missing --run tar
AR = arm-linux-gnueabihf-ar
AUTOCONF = ${SHELL} /home/morris/SUDA_V3S/3rdpart/ethercat-1.5.2/autoconf/missing --run autoconf
AUTOHEADER = ${SHELL} /home/morris/SUDA_V3S/3rdpart/ethercat-1.5.2/autoconf/missing --run autoheader
AUTOMAKE = ${SHELL} /home/morris/SUDA_V3S/3rdpart/ethercat-1.5.2/autoconf/missing --run automake-1.11
AWK = gawk
CC = arm-linux-gnueabihf-gcc
CCDEPMODE = depmode=gcc3
CFLAGS = -g -O2
CPP = arm-linux-gnueabihf-gcc -E
CPPFLAGS = 
CXX = arm-linux-gnueabihf-g++
CXXCPP = arm-linux-gnueabihf-g++ -E
CXXDEPMODE = depmode=gcc3
CXXFLAGS = -g -O2
CYGPATH_W = echo
DEFS = -DHAVE_CONFIG_H
DEPDIR = .deps
DLLTOOL = false
DSYMUTIL = 
DUMPBIN = 
E1000E_LAYOUT_3_4 = 0
ECHO_C = 
ECHO_N = -n
ECHO_T = 
EGREP = /bin/grep -E
ENABLE_8139TOO = 0
ENABLE_DEBUG_IF = 0
ENABLE_E100 = 0
ENABLE_E1000 = 0
ENABLE_E1000E = 0
ENABLE_EOE = 1
ENABLE_GENERIC = 1
ENABLE_R8169 = 0
ENABLE_RTAI = 0
ENABLE_RTDM = 0
ENABLE_TTY = 0
ENABLE_XENOMAI = 0
EXEEXT = 
FGREP = /bin/grep -F
GREP = /bin/grep
INSTALL = /usr/bin/install -c
INSTALL_DATA = ${INSTALL} -m 644
INSTALL_MOD_DIR = ethercat
INSTALL_PROGRAM = ${INSTALL}
INSTALL_SCRIPT = ${INSTALL}
INSTALL_STRIP_PROGRAM = $(install_sh) -c -s
KERNEL_8139TOO = 4.13
KERNEL_E100 = 4.13
KERNEL_E1000 = 4.13
KERNEL_E1000E = 4.13
KERNEL_R8169 = 4.13
LD = arm-linux-gnueabihf-ld
LDFLAGS = 
LIBOBJS = 
LIBS = 
LIBTOOL = $(SHELL) $(top_builddir)/libtool
LINUX_SOURCE_DIR = /home/morris/SUDA_V3S/kernel/linux-zero-4.13.y/
LIPO = 
LN_S = ln -s
LTLIBOBJS = 
MAKEINFO = ${SHELL} /home/morris/SUDA_V3S/3rdpart/ethercat-1.5.2/autoconf/missing --run makeinfo
MANIFEST_TOOL = :
MKDIR_P = /bin/mkdir -p
NM = arm-linux-gnueabihf-nm
NMEDIT = 
OBJDUMP = arm-linux-gnueabihf-objdump
OBJEXT = o
OTOOL = 
OTOOL64 = 
PACKAGE = ethercat
PACKAGE_BUGREPORT = <EMAIL>
PACKAGE_NAME = ethercat
PACKAGE_STRING = ethercat 1.5.2
PACKAGE_TARNAME = ethercat
PACKAGE_URL = 
PACKAGE_VERSION = 1.5.2
PATH_SEPARATOR = :
RANLIB = arm-linux-gnueabihf-ranlib
RTAI_DIR = 
RTAI_LXRT_CFLAGS = 
RTAI_LXRT_LDFLAGS = 
SED = /bin/sed
SET_MAKE = 
SHELL = /bin/bash
STRIP = arm-linux-gnueabihf-strip
VERSION = 1.5.2
XENOMAI_DIR = 
XENOMAI_NATIVE_CFLAGS = 
XENOMAI_NATIVE_LDFLAGS = 
XENOMAI_POSIX_CFLAGS = 
XENOMAI_POSIX_LDFLAGS = 
XENOMAI_RTDM_CFLAGS = 
XENOMAI_RTDM_LDFLAGS = 
abs_builddir = /home/morris/SUDA_V3S/3rdpart/ethercat-1.5.2/lib
abs_srcdir = /home/morris/SUDA_V3S/3rdpart/ethercat-1.5.2/lib
abs_top_builddir = /home/morris/SUDA_V3S/3rdpart/ethercat-1.5.2
abs_top_srcdir = /home/morris/SUDA_V3S/3rdpart/ethercat-1.5.2
ac_ct_AR = 
ac_ct_CC = 
ac_ct_CXX = 
ac_ct_DUMPBIN = 
am__include = include
am__leading_dot = .
am__quote = 
am__tar = ${AMTAR} chof - "$$tardir"
am__untar = ${AMTAR} xf -
bindir = ${exec_prefix}/bin
build = x86_64-unknown-linux-gnu
build_alias = 
build_cpu = x86_64
build_os = linux-gnu
build_vendor = unknown
builddir = .
datadir = ${datarootdir}
datarootdir = ${prefix}/share
docdir = ${datarootdir}/doc/${PACKAGE_TARNAME}
dvidir = ${docdir}
exec_prefix = ${prefix}
host = arm-unknown-linux-gnueabihf
host_alias = arm-linux-gnueabihf
host_cpu = arm
host_os = linux-gnueabihf
host_vendor = unknown
htmldir = ${docdir}
includedir = ${prefix}/include
infodir = ${datarootdir}/info
install_sh = ${SHELL} /home/morris/SUDA_V3S/3rdpart/ethercat-1.5.2/autoconf/install-sh
libdir = ${exec_prefix}/lib
libexecdir = ${exec_prefix}/libexec
localedir = ${datarootdir}/locale
localstatedir = ${prefix}/var
mandir = ${datarootdir}/man
mkdir_p = /bin/mkdir -p
oldincludedir = /usr/include
pdfdir = ${docdir}
prefix = /home/morris/SUDA_V3S/rootfs/multistrap/rootfs/opt/ethercat
program_transform_name = s,x,x,
psdir = ${docdir}
sbindir = ${exec_prefix}/sbin
sharedstatedir = ${prefix}/com
srcdir = .
sysconfdir = ${prefix}/etc
target_alias = 
top_build_prefix = ../
top_builddir = ..
top_srcdir = ..
lib_LTLIBRARIES = libethercat.la $(am__append_1)

#------------------------------------------------------------------------------
libethercat_la_SOURCES = \
	common.c \
	domain.c \
	master.c \
	reg_request.c \
	sdo_request.c \
	slave_config.c \
	voe_handler.c

noinst_HEADERS = \
	domain.h \
	ioctl.h \
	master.h \
	reg_request.h \
	sdo_request.h \
	slave_config.h \
	voe_handler.h

libethercat_la_CFLAGS = -fno-strict-aliasing -Wall
libethercat_la_LDFLAGS = -version-info 1:0:0
#libethercat_rtdm_la_SOURCES = $(libethercat_la_SOURCES)
#libethercat_rtdm_la_CFLAGS =  \
#	$(libethercat_la_CFLAGS) -DUSE_RTDM \
#	$(am__append_2) $(am__append_4)
#libethercat_rtdm_la_LDFLAGS =  \
#	$(libethercat_la_LDFLAGS) $(am__append_3) \
#	$(am__append_5)
all: all-am

.SUFFIXES:
.SUFFIXES: .c .lo .o .obj
$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
	@for dep in $?; do \
	  case '$(am__configure_deps)' in \
	    *$$dep*) \
	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
	        && { if test -f $@; then exit 0; else break; fi; }; \
	      exit 1;; \
	  esac; \
	done; \
	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lib/Makefile'; \
	$(am__cd) $(top_srcdir) && \
	  $(AUTOMAKE) --gnu lib/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
	@case '$?' in \
	  *config.status*) \
	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
	  *) \
	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
	esac;

$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh

$(top_srcdir)/configure:  $(am__configure_deps)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
	@$(NORMAL_INSTALL)
	test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
	@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
	list2=; for p in $$list; do \
	  if test -f $$p; then \
	    list2="$$list2 $$p"; \
	  else :; fi; \
	done; \
	test -z "$$list2" || { \
	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
	}

uninstall-libLTLIBRARIES:
	@$(NORMAL_UNINSTALL)
	@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
	for p in $$list; do \
	  $(am__strip_dir) \
	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
	done

clean-libLTLIBRARIES:
	-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
	@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
	  dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
	  test "$$dir" != "$$p" || dir=.; \
	  echo "rm -f \"$${dir}/so_locations\""; \
	  rm -f "$${dir}/so_locations"; \
	done
libethercat.la: $(libethercat_la_OBJECTS) $(libethercat_la_DEPENDENCIES) 
	$(libethercat_la_LINK) -rpath $(libdir) $(libethercat_la_OBJECTS) $(libethercat_la_LIBADD) $(LIBS)
libethercat_rtdm.la: $(libethercat_rtdm_la_OBJECTS) $(libethercat_rtdm_la_DEPENDENCIES) 
	$(libethercat_rtdm_la_LINK) $(am_libethercat_rtdm_la_rpath) $(libethercat_rtdm_la_OBJECTS) $(libethercat_rtdm_la_LIBADD) $(LIBS)

mostlyclean-compile:
	-rm -f *.$(OBJEXT)

distclean-compile:
	-rm -f *.tab.c

include ./$(DEPDIR)/libethercat_la-common.Plo
include ./$(DEPDIR)/libethercat_la-domain.Plo
include ./$(DEPDIR)/libethercat_la-master.Plo
include ./$(DEPDIR)/libethercat_la-reg_request.Plo
include ./$(DEPDIR)/libethercat_la-sdo_request.Plo
include ./$(DEPDIR)/libethercat_la-slave_config.Plo
include ./$(DEPDIR)/libethercat_la-voe_handler.Plo
include ./$(DEPDIR)/libethercat_rtdm_la-common.Plo
include ./$(DEPDIR)/libethercat_rtdm_la-domain.Plo
include ./$(DEPDIR)/libethercat_rtdm_la-master.Plo
include ./$(DEPDIR)/libethercat_rtdm_la-reg_request.Plo
include ./$(DEPDIR)/libethercat_rtdm_la-sdo_request.Plo
include ./$(DEPDIR)/libethercat_rtdm_la-slave_config.Plo
include ./$(DEPDIR)/libethercat_rtdm_la-voe_handler.Plo

.c.o:
	$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
	$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
#	source='$<' object='$@' libtool=no \
#	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
#	$(COMPILE) -c $<

.c.obj:
	$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
	$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
#	source='$<' object='$@' libtool=no \
#	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
#	$(COMPILE) -c `$(CYGPATH_W) '$<'`

.c.lo:
	$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
	$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
#	source='$<' object='$@' libtool=yes \
#	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
#	$(LTCOMPILE) -c -o $@ $<

libethercat_la-common.lo: common.c
	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libethercat_la_CFLAGS) $(CFLAGS) -MT libethercat_la-common.lo -MD -MP -MF $(DEPDIR)/libethercat_la-common.Tpo -c -o libethercat_la-common.lo `test -f 'common.c' || echo '$(srcdir)/'`common.c
	$(am__mv) $(DEPDIR)/libethercat_la-common.Tpo $(DEPDIR)/libethercat_la-common.Plo
#	source='common.c' object='libethercat_la-common.lo' libtool=yes \
#	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
#	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libethercat_la_CFLAGS) $(CFLAGS) -c -o libethercat_la-common.lo `test -f 'common.c' || echo '$(srcdir)/'`common.c

libethercat_la-domain.lo: domain.c
	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libethercat_la_CFLAGS) $(CFLAGS) -MT libethercat_la-domain.lo -MD -MP -MF $(DEPDIR)/libethercat_la-domain.Tpo -c -o libethercat_la-domain.lo `test -f 'domain.c' || echo '$(srcdir)/'`domain.c
	$(am__mv) $(DEPDIR)/libethercat_la-domain.Tpo $(DEPDIR)/libethercat_la-domain.Plo
#	source='domain.c' object='libethercat_la-domain.lo' libtool=yes \
#	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
#	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libethercat_la_CFLAGS) $(CFLAGS) -c -o libethercat_la-domain.lo `test -f 'domain.c' || echo '$(srcdir)/'`domain.c

libethercat_la-master.lo: master.c
	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libethercat_la_CFLAGS) $(CFLAGS) -MT libethercat_la-master.lo -MD -MP -MF $(DEPDIR)/libethercat_la-master.Tpo -c -o libethercat_la-master.lo `test -f 'master.c' || echo '$(srcdir)/'`master.c
	$(am__mv) $(DEPDIR)/libethercat_la-master.Tpo $(DEPDIR)/libethercat_la-master.Plo
#	source='master.c' object='libethercat_la-master.lo' libtool=yes \
#	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
#	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libethercat_la_CFLAGS) $(CFLAGS) -c -o libethercat_la-master.lo `test -f 'master.c' || echo '$(srcdir)/'`master.c

libethercat_la-reg_request.lo: reg_request.c
	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libethercat_la_CFLAGS) $(CFLAGS) -MT libethercat_la-reg_request.lo -MD -MP -MF $(DEPDIR)/libethercat_la-reg_request.Tpo -c -o libethercat_la-reg_request.lo `test -f 'reg_request.c' || echo '$(srcdir)/'`reg_request.c
	$(am__mv) $(DEPDIR)/libethercat_la-reg_request.Tpo $(DEPDIR)/libethercat_la-reg_request.Plo
#	source='reg_request.c' object='libethercat_la-reg_request.lo' libtool=yes \
#	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
#	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libethercat_la_CFLAGS) $(CFLAGS) -c -o libethercat_la-reg_request.lo `test -f 'reg_request.c' || echo '$(srcdir)/'`reg_request.c

libethercat_la-sdo_request.lo: sdo_request.c
	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libethercat_la_CFLAGS) $(CFLAGS) -MT libethercat_la-sdo_request.lo -MD -MP -MF $(DEPDIR)/libethercat_la-sdo_request.Tpo -c -o libethercat_la-sdo_request.lo `test -f 'sdo_request.c' || echo '$(srcdir)/'`sdo_request.c
	$(am__mv) $(DEPDIR)/libethercat_la-sdo_request.Tpo $(DEPDIR)/libethercat_la-sdo_request.Plo
#	source='sdo_request.c' object='libethercat_la-sdo_request.lo' libtool=yes \
#	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
#	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libethercat_la_CFLAGS) $(CFLAGS) -c -o libethercat_la-sdo_request.lo `test -f 'sdo_request.c' || echo '$(srcdir)/'`sdo_request.c

libethercat_la-slave_config.lo: slave_config.c
	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libethercat_la_CFLAGS) $(CFLAGS) -MT libethercat_la-slave_config.lo -MD -MP -MF $(DEPDIR)/libethercat_la-slave_config.Tpo -c -o libethercat_la-slave_config.lo `test -f 'slave_config.c' || echo '$(srcdir)/'`slave_config.c
	$(am__mv) $(DEPDIR)/libethercat_la-slave_config.Tpo $(DEPDIR)/libethercat_la-slave_config.Plo
#	source='slave_config.c' object='libethercat_la-slave_config.lo' libtool=yes \
#	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
#	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libethercat_la_CFLAGS) $(CFLAGS) -c -o libethercat_la-slave_config.lo `test -f 'slave_config.c' || echo '$(srcdir)/'`slave_config.c

libethercat_la-voe_handler.lo: voe_handler.c
	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libethercat_la_CFLAGS) $(CFLAGS) -MT libethercat_la-voe_handler.lo -MD -MP -MF $(DEPDIR)/libethercat_la-voe_handler.Tpo -c -o libethercat_la-voe_handler.lo `test -f 'voe_handler.c' || echo '$(srcdir)/'`voe_handler.c
	$(am__mv) $(DEPDIR)/libethercat_la-voe_handler.Tpo $(DEPDIR)/libethercat_la-voe_handler.Plo
#	source='voe_handler.c' object='libethercat_la-voe_handler.lo' libtool=yes \
#	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
#	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libethercat_la_CFLAGS) $(CFLAGS) -c -o libethercat_la-voe_handler.lo `test -f 'voe_handler.c' || echo '$(srcdir)/'`voe_handler.c

libethercat_rtdm_la-common.lo: common.c
	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libethercat_rtdm_la_CFLAGS) $(CFLAGS) -MT libethercat_rtdm_la-common.lo -MD -MP -MF $(DEPDIR)/libethercat_rtdm_la-common.Tpo -c -o libethercat_rtdm_la-common.lo `test -f 'common.c' || echo '$(srcdir)/'`common.c
	$(am__mv) $(DEPDIR)/libethercat_rtdm_la-common.Tpo $(DEPDIR)/libethercat_rtdm_la-common.Plo
#	source='common.c' object='libethercat_rtdm_la-common.lo' libtool=yes \
#	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
#	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libethercat_rtdm_la_CFLAGS) $(CFLAGS) -c -o libethercat_rtdm_la-common.lo `test -f 'common.c' || echo '$(srcdir)/'`common.c

libethercat_rtdm_la-domain.lo: domain.c
	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libethercat_rtdm_la_CFLAGS) $(CFLAGS) -MT libethercat_rtdm_la-domain.lo -MD -MP -MF $(DEPDIR)/libethercat_rtdm_la-domain.Tpo -c -o libethercat_rtdm_la-domain.lo `test -f 'domain.c' || echo '$(srcdir)/'`domain.c
	$(am__mv) $(DEPDIR)/libethercat_rtdm_la-domain.Tpo $(DEPDIR)/libethercat_rtdm_la-domain.Plo
#	source='domain.c' object='libethercat_rtdm_la-domain.lo' libtool=yes \
#	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
#	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libethercat_rtdm_la_CFLAGS) $(CFLAGS) -c -o libethercat_rtdm_la-domain.lo `test -f 'domain.c' || echo '$(srcdir)/'`domain.c

libethercat_rtdm_la-master.lo: master.c
	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libethercat_rtdm_la_CFLAGS) $(CFLAGS) -MT libethercat_rtdm_la-master.lo -MD -MP -MF $(DEPDIR)/libethercat_rtdm_la-master.Tpo -c -o libethercat_rtdm_la-master.lo `test -f 'master.c' || echo '$(srcdir)/'`master.c
	$(am__mv) $(DEPDIR)/libethercat_rtdm_la-master.Tpo $(DEPDIR)/libethercat_rtdm_la-master.Plo
#	source='master.c' object='libethercat_rtdm_la-master.lo' libtool=yes \
#	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
#	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libethercat_rtdm_la_CFLAGS) $(CFLAGS) -c -o libethercat_rtdm_la-master.lo `test -f 'master.c' || echo '$(srcdir)/'`master.c

libethercat_rtdm_la-reg_request.lo: reg_request.c
	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libethercat_rtdm_la_CFLAGS) $(CFLAGS) -MT libethercat_rtdm_la-reg_request.lo -MD -MP -MF $(DEPDIR)/libethercat_rtdm_la-reg_request.Tpo -c -o libethercat_rtdm_la-reg_request.lo `test -f 'reg_request.c' || echo '$(srcdir)/'`reg_request.c
	$(am__mv) $(DEPDIR)/libethercat_rtdm_la-reg_request.Tpo $(DEPDIR)/libethercat_rtdm_la-reg_request.Plo
#	source='reg_request.c' object='libethercat_rtdm_la-reg_request.lo' libtool=yes \
#	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
#	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libethercat_rtdm_la_CFLAGS) $(CFLAGS) -c -o libethercat_rtdm_la-reg_request.lo `test -f 'reg_request.c' || echo '$(srcdir)/'`reg_request.c

libethercat_rtdm_la-sdo_request.lo: sdo_request.c
	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libethercat_rtdm_la_CFLAGS) $(CFLAGS) -MT libethercat_rtdm_la-sdo_request.lo -MD -MP -MF $(DEPDIR)/libethercat_rtdm_la-sdo_request.Tpo -c -o libethercat_rtdm_la-sdo_request.lo `test -f 'sdo_request.c' || echo '$(srcdir)/'`sdo_request.c
	$(am__mv) $(DEPDIR)/libethercat_rtdm_la-sdo_request.Tpo $(DEPDIR)/libethercat_rtdm_la-sdo_request.Plo
#	source='sdo_request.c' object='libethercat_rtdm_la-sdo_request.lo' libtool=yes \
#	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
#	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libethercat_rtdm_la_CFLAGS) $(CFLAGS) -c -o libethercat_rtdm_la-sdo_request.lo `test -f 'sdo_request.c' || echo '$(srcdir)/'`sdo_request.c

libethercat_rtdm_la-slave_config.lo: slave_config.c
	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libethercat_rtdm_la_CFLAGS) $(CFLAGS) -MT libethercat_rtdm_la-slave_config.lo -MD -MP -MF $(DEPDIR)/libethercat_rtdm_la-slave_config.Tpo -c -o libethercat_rtdm_la-slave_config.lo `test -f 'slave_config.c' || echo '$(srcdir)/'`slave_config.c
	$(am__mv) $(DEPDIR)/libethercat_rtdm_la-slave_config.Tpo $(DEPDIR)/libethercat_rtdm_la-slave_config.Plo
#	source='slave_config.c' object='libethercat_rtdm_la-slave_config.lo' libtool=yes \
#	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
#	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libethercat_rtdm_la_CFLAGS) $(CFLAGS) -c -o libethercat_rtdm_la-slave_config.lo `test -f 'slave_config.c' || echo '$(srcdir)/'`slave_config.c

libethercat_rtdm_la-voe_handler.lo: voe_handler.c
	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libethercat_rtdm_la_CFLAGS) $(CFLAGS) -MT libethercat_rtdm_la-voe_handler.lo -MD -MP -MF $(DEPDIR)/libethercat_rtdm_la-voe_handler.Tpo -c -o libethercat_rtdm_la-voe_handler.lo `test -f 'voe_handler.c' || echo '$(srcdir)/'`voe_handler.c
	$(am__mv) $(DEPDIR)/libethercat_rtdm_la-voe_handler.Tpo $(DEPDIR)/libethercat_rtdm_la-voe_handler.Plo
#	source='voe_handler.c' object='libethercat_rtdm_la-voe_handler.lo' libtool=yes \
#	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
#	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libethercat_rtdm_la_CFLAGS) $(CFLAGS) -c -o libethercat_rtdm_la-voe_handler.lo `test -f 'voe_handler.c' || echo '$(srcdir)/'`voe_handler.c

mostlyclean-libtool:
	-rm -f *.lo

clean-libtool:
	-rm -rf .libs _libs

ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
	unique=`for i in $$list; do \
	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
	  done | \
	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
	      END { if (nonempty) { for (i in files) print i; }; }'`; \
	mkid -fID $$unique
tags: TAGS

TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
		$(TAGS_FILES) $(LISP)
	set x; \
	here=`pwd`; \
	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
	unique=`for i in $$list; do \
	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
	  done | \
	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
	      END { if (nonempty) { for (i in files) print i; }; }'`; \
	shift; \
	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
	  test -n "$$unique" || unique=$$empty_fix; \
	  if test $$# -gt 0; then \
	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
	      "$$@" $$unique; \
	  else \
	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
	      $$unique; \
	  fi; \
	fi
ctags: CTAGS
CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
		$(TAGS_FILES) $(LISP)
	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
	unique=`for i in $$list; do \
	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
	  done | \
	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
	      END { if (nonempty) { for (i in files) print i; }; }'`; \
	test -z "$(CTAGS_ARGS)$$unique" \
	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
	     $$unique

GTAGS:
	here=`$(am__cd) $(top_builddir) && pwd` \
	  && $(am__cd) $(top_srcdir) \
	  && gtags -i $(GTAGS_ARGS) "$$here"

distclean-tags:
	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags

distdir: $(DISTFILES)
	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
	list='$(DISTFILES)'; \
	  dist_files=`for file in $$list; do echo $$file; done | \
	  sed -e "s|^$$srcdirstrip/||;t" \
	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
	case $$dist_files in \
	  */*) $(MKDIR_P) `echo "$$dist_files" | \
			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
			   sort -u` ;; \
	esac; \
	for file in $$dist_files; do \
	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
	  if test -d $$d/$$file; then \
	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
	    if test -d "$(distdir)/$$file"; then \
	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
	    fi; \
	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
	    fi; \
	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
	  else \
	    test -f "$(distdir)/$$file" \
	    || cp -p $$d/$$file "$(distdir)/$$file" \
	    || exit 1; \
	  fi; \
	done
check-am: all-am
check: check-am
all-am: Makefile $(LTLIBRARIES) $(HEADERS)
installdirs:
	for dir in "$(DESTDIR)$(libdir)"; do \
	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
	done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am

install-am: all-am
	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am

installcheck: installcheck-am
install-strip:
	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
	  `test -z '$(STRIP)' || \
	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:

clean-generic:

distclean-generic:
	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)

maintainer-clean-generic:
	@echo "This command is intended for maintainers to use"
	@echo "it deletes files that may require special tools to rebuild."
clean: clean-am

clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
	mostlyclean-am

distclean: distclean-am
	-rm -rf ./$(DEPDIR)
	-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
	distclean-tags

dvi: dvi-am

dvi-am:

html: html-am

html-am:

info: info-am

info-am:

install-data-am:

install-dvi: install-dvi-am

install-dvi-am:

install-exec-am: install-libLTLIBRARIES

install-html: install-html-am

install-html-am:

install-info: install-info-am

install-info-am:

install-man:

install-pdf: install-pdf-am

install-pdf-am:

install-ps: install-ps-am

install-ps-am:

installcheck-am:

maintainer-clean: maintainer-clean-am
	-rm -rf ./$(DEPDIR)
	-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic

mostlyclean: mostlyclean-am

mostlyclean-am: mostlyclean-compile mostlyclean-generic \
	mostlyclean-libtool

pdf: pdf-am

pdf-am:

ps: ps-am

ps-am:

uninstall-am: uninstall-libLTLIBRARIES

.MAKE: install-am install-strip

.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
	clean-libLTLIBRARIES clean-libtool ctags distclean \
	distclean-compile distclean-generic distclean-libtool \
	distclean-tags distdir dvi dvi-am html html-am info info-am \
	install install-am install-data install-data-am install-dvi \
	install-dvi-am install-exec install-exec-am install-html \
	install-html-am install-info install-info-am \
	install-libLTLIBRARIES install-man install-pdf install-pdf-am \
	install-ps install-ps-am install-strip installcheck \
	installcheck-am installdirs maintainer-clean \
	maintainer-clean-generic mostlyclean mostlyclean-compile \
	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
	tags uninstall uninstall-am uninstall-libLTLIBRARIES


#------------------------------------------------------------------------------

# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:


<|start_filename|>apps/ecat-master/main/indev_tslib.h<|end_filename|>
/*
 * indev_tslib.h
 *
 *  Created on: Mar 11, 2018
 *      Author: morris
 */

#ifndef INDEV_TSLIB_H_
#define INDEV_TSLIB_H_

#include "lvgl/lv_hal/lv_hal_indev.h"

int indev_init(void);
bool indev_ts_read(lv_indev_data_t *data);
void indev_stop(void);

#endif /* INDEV_TSLIB_H_ */


<|start_filename|>3rdpart/tslib-1.15/tests/fbutils.h<|end_filename|>
/*
 * fbutils.h
 *
 * Headers for utility routines for framebuffer interaction
 *
 * Copyright 2002 <NAME> and <NAME>
 *
 * This file is placed under the GPL.  Please see the
 * file COPYING for details.
 *
 * SPDX-License-Identifier: GPL-2.0+
 */

#ifndef _FBUTILS_H
#define _FBUTILS_H

#include <stdint.h>

/* This constant, being ORed with the color index tells the library
 * to draw in exclusive-or mode (that is, drawing the same second time
 * in the same place will remove the element leaving the background intact).
 */
#define XORMODE	0x80000000

extern uint32_t xres, yres;
extern int8_t rotation;

int open_framebuffer(void);
void close_framebuffer(void);
void setcolor(unsigned colidx, unsigned value);
void put_cross(int x, int y, unsigned colidx);
void put_string(int x, int y, char *s, unsigned colidx);
void put_string_center(int x, int y, char *s, unsigned colidx);
void pixel(int x, int y, unsigned colidx);
void line(int x1, int y1, int x2, int y2, unsigned colidx);
void rect(int x1, int y1, int x2, int y2, unsigned colidx);
void fillrect(int x1, int y1, int x2, int y2, unsigned colidx);

#endif /* _FBUTILS_H */


<|start_filename|>3rdpart/tslib-1.15/plugins/debounce.c<|end_filename|>
/*
 *  tslib/plugins/debounce.c
 *
 *  Copyright (C) 2017 <NAME> <<EMAIL>>
 *  Copyright (C) 2013 <NAME> <<EMAIL>>
 *
 * This file is placed under the LGPL.  Please see the file
 * COPYING for more details.
 *
 * SPDX-License-Identifier: LGPL-2.1
 *
 *
 * Problem: An intended single-tap by the user should be understood as
 * such. Be it because of the touch device's properties or an unintended
 * wrong input by the user, multiple input events that lead to a "tap"
 * could occur.
 *
 * Solution: For a specified time after stopping to touch, we drop input
 * samples.
 */

#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <limits.h>
#include <stdint.h>

#include "tslib.h"
#include "tslib-filter.h"

enum debounce_mode {
	DOWN,
	MOVE,
	UP
};

struct tslib_debounce {
	struct tslib_module_info	module;
	unsigned int			drop_threshold; /* ms */
	int64_t				last_release;
	int				last_pressure;
	int64_t				*last_release_mt;
	int				*last_pressure_mt;
	int32_t				current_max_slots;
	enum debounce_mode		*mode_mt;
};

static int debounce_read(struct tslib_module_info *info, struct ts_sample *samp, int nr)
{
	struct tslib_debounce *p = (struct tslib_debounce *)info;
	struct ts_sample *s;
	int ret;
	int num = 0;
	int i;
	int64_t now;
	long dt;
	int drop = 0;
	int left;
	__attribute__ ((unused)) enum debounce_mode mode;

	ret = info->next->ops->read(info->next, samp, nr);
	if (ret < 0)
		return ret;

	for (s = samp, i = 0; i < ret; i++, s++) {
		now = s->tv.tv_sec * 1e6 + s->tv.tv_usec;
		dt = (long)(now - p->last_release) / 1000; /* ms */
		mode = MOVE;

		drop = 0;

		if (!s->pressure) {
			mode = UP;
			p->last_release = now;
		} else if (!p->last_pressure) {
			mode = DOWN;
		}

		p->last_pressure = s->pressure;

		if (dt < p->drop_threshold)
			drop = 1;

#ifdef DEBUG
		fprintf(stderr, "\033[%smDEBOUNCE:\033[m  press=%u  x=%d  y=%d  dt=%ld%s\n",
				mode == DOWN ? "92" : mode == MOVE ? "32" : "93",
				s->pressure, s->x, s->y, dt,
				drop ? "  \033[31mdropped\033[m" : "");
#endif

		if (drop) {
			left = ret - num - 1;
			if (left > 0) {
				memmove(s, s + 1, left * sizeof(struct ts_sample));
				s--;
				continue;
			}
			break;
		}

		num++;
	}
	return num;
}

static int debounce_read_mt(struct tslib_module_info *info, struct ts_sample_mt **samp,
			    int max_slots, int nr_samples)
{
	struct tslib_debounce *p = (struct tslib_debounce *)info;
	int ret;
	int64_t now;
	long dt;
	int nr;
	int i;

	if (p->mode_mt == NULL || max_slots > p->current_max_slots) {
		if (p->mode_mt)
			free(p->mode_mt);

		p->mode_mt = calloc(max_slots, sizeof(unsigned int));
		if (!p->mode_mt)
			return -ENOMEM;

		p->current_max_slots = max_slots;
	}

	if (p->last_release_mt == NULL || max_slots > p->current_max_slots) {
		if (p->last_release_mt)
			free(p->last_release_mt);

		p->last_release_mt = calloc(max_slots, sizeof(int64_t));
		if (!p->last_release_mt)
			return -ENOMEM;

		p->current_max_slots = max_slots;
	}

	if (p->last_pressure_mt == NULL || max_slots > p->current_max_slots) {
		if (p->last_pressure_mt)
			free(p->last_pressure_mt);

		p->last_pressure_mt = calloc(max_slots, sizeof(int));
		if (!p->last_pressure_mt)
			return -ENOMEM;

		p->current_max_slots = max_slots;
	}

	if (!info->next->ops->read_mt)
		return -ENOSYS;

	ret = info->next->ops->read_mt(info->next, samp, max_slots, nr_samples);
	if (ret < 0)
		return ret;

#ifdef DEBUG
	printf("DEBOUNCE: read %d samples (mem: %d nr x %d slots)\n", ret, nr_samples, max_slots);
#endif

	for (nr = 0; nr < ret; nr++) {
		for (i = 0; i < max_slots; i++) {
			if (!(samp[nr][i].valid & TSLIB_MT_VALID))
				continue;

			now = samp[nr][i].tv.tv_sec * 1e6 + samp[nr][i].tv.tv_usec;
			dt = (long)(now - p->last_release_mt[i]) / 1000; /* ms */
			p->mode_mt[i] = MOVE;

			if (!samp[nr][i].pressure) {
				p->mode_mt[i] = UP;
				p->last_release_mt[i] = now;
			} else if (!p->last_pressure_mt[i]) {
				p->mode_mt[i] = DOWN;
			}

			p->last_pressure_mt[i] = samp[nr][i].pressure;

			if (dt < p->drop_threshold)
				samp[nr][i].valid = 0;

	#ifdef DEBUG
			fprintf(stderr, "\033[%smDEBOUNCE:\033[m (slot %d) P:%u X:%4d  Y:%4d  dt=%ld%s\n",
					p->mode_mt[i] == DOWN ? "92" : p->mode_mt[i] == MOVE ? "32" : "93",
					samp[nr][i].slot, samp[nr][i].pressure,
					samp[nr][i].x, samp[nr][i].y, dt,
					samp[nr][i].valid ? "" : "  \033[31mdropped\033[m");
	#endif
		}
	}

	return nr;
}

static int debounce_fini(struct tslib_module_info *info)
{
	struct tslib_debounce *p = (struct tslib_debounce *)info;

	if (p->last_release_mt)
		free(p->last_release_mt);

	if (p->last_pressure_mt)
		free(p->last_pressure_mt);

	free(info);

	return 0;
}

static const struct tslib_ops debounce_ops = {
	.read = debounce_read,
	.read_mt = debounce_read_mt,
	.fini = debounce_fini,
};

static int read_debounce_vars(struct tslib_module_info *inf, char *str, void *data)
{
	struct tslib_debounce *p = (struct tslib_debounce *)inf;
	unsigned long v;
	int err = errno;

	v = strtoul(str, NULL, 0);
	if (v == ULONG_MAX && errno == ERANGE)
		return -1;

	errno = err;
	switch ((int)(intptr_t)data) {
	case 0:
		p->drop_threshold = v;
		break;

	default:
		return -1;
	}
	return 0;
}


static const struct tslib_vars debounce_vars[] = {
	{ "drop_threshold", (void *)0, read_debounce_vars }, /* ms */
};

#define NR_VARS (sizeof(debounce_vars) / sizeof(debounce_vars[0]))

TSAPI struct tslib_module_info *debounce_mod_init(__attribute__ ((unused)) struct tsdev *dev,
						  const char *params)
{
	struct tslib_debounce *p;

	p = malloc(sizeof(struct tslib_debounce));
	if (p == NULL)
		return NULL;

	p->module.ops = &debounce_ops;
	p->drop_threshold = 0;
	p->last_release = 0ULL;
	p->last_pressure = 0;
	p->last_release_mt = NULL;
	p->last_pressure_mt = NULL;
	p->current_max_slots = 0;
	p->mode_mt = NULL;

	if (tslib_parse_vars(&p->module, debounce_vars, NR_VARS, params)) {
		free(p);
		return NULL;
	}

	return &p->module;
}

#ifndef TSLIB_STATIC_DEBOUNCE_MODULE
	TSLIB_MODULE_INIT(debounce_mod_init);
#endif


<|start_filename|>3rdpart/ethercat-1.5.2/master/sdo.c<|end_filename|>
/******************************************************************************
 *
 *  $Id: sdo.c,v bc2d4bf9cbe5 2012/09/06 18:22:24 fp $
 *
 *  Copyright (C) 2006-2008  <NAME>, Ingenieurgemeinschaft IgH
 *
 *  This file is part of the IgH EtherCAT Master.
 *
 *  The IgH EtherCAT Master is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License version 2, as
 *  published by the Free Software Foundation.
 *
 *  The IgH EtherCAT Master is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 *  Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with the IgH EtherCAT Master; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 *****************************************************************************/

/**
   \file
   CANopen SDO functions.
*/

/*****************************************************************************/

#include <linux/slab.h>

#include "master.h"

#include "sdo.h"

/*****************************************************************************/

/** Constructor.
 */
void ec_sdo_init(
        ec_sdo_t *sdo, /**< SDO. */
        ec_slave_t *slave, /**< Parent slave. */
        uint16_t index /**< SDO index. */
        )
{
    sdo->slave = slave;
    sdo->index = index;
    sdo->object_code = 0x00;
    sdo->name = NULL;
    sdo->max_subindex = 0;
    INIT_LIST_HEAD(&sdo->entries);
}

/*****************************************************************************/

/** SDO destructor.
 *
 * Clears and frees an SDO object.
 */
void ec_sdo_clear(
        ec_sdo_t *sdo /**< SDO. */
        )
{
    ec_sdo_entry_t *entry, *next;

    // free all entries
    list_for_each_entry_safe(entry, next, &sdo->entries, list) {
        list_del(&entry->list);
        ec_sdo_entry_clear(entry);
        kfree(entry);
    }

    if (sdo->name)
        kfree(sdo->name);
}

/*****************************************************************************/

/** Get an SDO entry from an SDO via its subindex.
 *
 * \retval >0 Pointer to the requested SDO entry.
 * \retval NULL SDO entry not found.
 */
ec_sdo_entry_t *ec_sdo_get_entry(
        ec_sdo_t *sdo, /**< SDO. */
        uint8_t subindex /**< Entry subindex. */
        )
{
    ec_sdo_entry_t *entry;

    list_for_each_entry(entry, &sdo->entries, list) {
        if (entry->subindex != subindex)
            continue;
        return entry;
    }

    return NULL;
}

/*****************************************************************************/

/** Get an SDO entry from an SDO via its subindex.
 *
 * const version.
 *
 * \retval >0 Pointer to the requested SDO entry.
 * \retval NULL SDO entry not found.
 */
const ec_sdo_entry_t *ec_sdo_get_entry_const(
        const ec_sdo_t *sdo, /**< SDO. */
        uint8_t subindex /**< Entry subindex. */
        )
{
    const ec_sdo_entry_t *entry;

    list_for_each_entry(entry, &sdo->entries, list) {
        if (entry->subindex != subindex)
            continue;
        return entry;
    }

    return NULL;
}

/*****************************************************************************/


<|start_filename|>apps/ecat-master/main/utils.c<|end_filename|>
/*
 * utils.c
 *
 *  Created on: Mar 11, 2018
 *      Author: morris
 */
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <pthread.h>
#include <unistd.h>
#include "utils.h"

static bool thread_running = true;
static uint8_t usage = 0;

/* 互斥锁 */
static pthread_mutex_t mutex;

void utils_stop(void) {
	pthread_mutex_lock(&mutex);
	thread_running = false;
	pthread_mutex_unlock(&mutex);
}

static void* handle_cpu_usage(void* arg) {
	FILE* fp = NULL;
	uint32_t cpu_user = 0, cpu_nice = 0, cpu_system = 0, cpu_idle = 0,
			cpu_iowait = 0, cpu_irq = 0, cpu_softirq = 0, cpu_stealstolen = 0,
			cpu_guest = 0;
	uint32_t all0 = 0, all1 = 0, idle0 = 0, idle1 = 0;
	int ret;
	pthread_mutex_lock(&mutex);
	while (thread_running) {
		pthread_mutex_unlock(&mutex);
		fp = fopen("/proc/stat", "r");
		if (!fp) {
			perror("fopen");
			goto file_err;
		}
		ret = fscanf(fp, "%*s%d%d%d%d%d%d%d%d%d", &cpu_user, &cpu_nice,
				&cpu_system, &cpu_idle, &cpu_iowait, &cpu_irq, &cpu_softirq,
				&cpu_stealstolen, &cpu_guest);
		fclose(fp);
		if (ret < 0) {
			perror("fscanf");
			goto file_err;
		}
		all1 = cpu_user + cpu_nice + cpu_system + cpu_idle + cpu_iowait
				+ cpu_irq + cpu_softirq + cpu_stealstolen + cpu_guest;
		idle1 = cpu_idle;
		pthread_mutex_lock(&mutex);
		/* CPU利用率的计算公式 */
		usage = (uint8_t) ((float) (all1 - all0 - (idle1 - idle0))
				/ (all1 - all0) * 100);
		pthread_mutex_unlock(&mutex);
		all0 = all1;
		idle0 = idle1;
		sleep(1);
		pthread_mutex_lock(&mutex);
	}
	pthread_mutex_unlock(&mutex);
file_err:
	/* 确保线程停止运行 */
	utils_stop();
	/* 释放互斥锁内存 */
	pthread_mutex_destroy(&mutex);
	pthread_exit(arg);
}

int utils_init(void) {
	int ret;
	pthread_t thread_hdl;
	pthread_attr_t attr;

	/* 初始化互斥锁 */
	pthread_mutex_init(&mutex, NULL);
	/* 设置线程的分离属性 */
	pthread_attr_init(&attr);
	ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
	if (ret) {
		perror("pthread_attr_setdetachstate");
		goto err;
	}
	/* 设置线程的绑定属性 */
	ret = pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
	if (ret) {
		perror("pthread_attr_setscope");
		goto err;
	}
	/* 创建线程 */
	ret = pthread_create(&thread_hdl, &attr, handle_cpu_usage, NULL);
	if (ret) {
		perror("pthread_create");
		goto err;
	}
	/* 释放线程属性对象 */
	pthread_attr_destroy(&attr);
	return 0;
err:
	/* 释放线程属性对象 */
	pthread_attr_destroy(&attr);
	/* 释放互斥锁对象 */
	pthread_mutex_destroy(&mutex);
	return ret;
}

int utils_cpu_usage(uint8_t* arg) {
	pthread_mutex_lock(&mutex);
	*arg = usage;
	pthread_mutex_unlock(&mutex);
	return 0;
}


<|start_filename|>3rdpart/ethercat-1.5.2/tool/CommandSiiRead.cpp<|end_filename|>
/*****************************************************************************
 *
 *  $Id: CommandSiiRead.cpp,v bc2d4bf9cbe5 2012/09/06 18:22:24 fp $
 *
 *  Copyright (C) 2006-2009  <NAME>, Ingenieurgemeinschaft IgH
 *
 *  This file is part of the IgH EtherCAT Master.
 *
 *  The IgH EtherCAT Master is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License version 2, as
 *  published by the Free Software Foundation.
 *
 *  The IgH EtherCAT Master is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 *  Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with the IgH EtherCAT Master; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 ****************************************************************************/

#include <iostream>
#include <iomanip>
using namespace std;

#include "CommandSiiRead.h"
#include "MasterDevice.h"

/*****************************************************************************/

CommandSiiRead::CommandSiiRead():
    Command("sii_read", "Output a slave's SII contents.")
{
}

/*****************************************************************************/

string CommandSiiRead::helpString(const string &binaryBaseName) const
{
    stringstream str;

    str << binaryBaseName << " " << getName() << " [OPTIONS]" << endl
        << endl
        << getBriefDescription() << endl
        << endl
        << "This command requires a single slave to be selected." << endl
        << endl
        << "Without the --verbose option, binary SII contents are" << endl
        << "output." << endl
        << endl
        << "With the --verbose option given, a textual representation" << endl
        << "of the data is output, that is separated by SII category" << endl
        << "names." << endl
        << endl
        << "Command-specific options:" << endl
        << "  --alias    -a <alias>" << endl
        << "  --position -p <pos>    Slave selection. See the help of" << endl
        << "                         the 'slaves' command." << endl
        << "  --verbose  -v          Output textual data with" << endl
        << "                         category names." << endl
        << endl
        << numericInfo();

    return str.str();
}

/****************************************************************************/

void CommandSiiRead::execute(const StringVector &args)
{
    SlaveList slaves;
    ec_ioctl_slave_t *slave;
    ec_ioctl_slave_sii_t data;
    unsigned int i;
    const uint16_t *categoryHeader;
    uint16_t categoryType, categorySize;
    stringstream err;

    if (args.size()) {
        err << "'" << getName() << "' takes no arguments!";
        throwInvalidUsageException(err);
    }

    MasterDevice m(getSingleMasterIndex());
    m.open(MasterDevice::Read);
    slaves = selectedSlaves(m);

    if (slaves.size() != 1) {
        throwSingleSlaveRequired(slaves.size());
    }
    slave = &slaves.front();
    data.slave_position = slave->position;

    if (!slave->sii_nwords)
        return;

    data.offset = 0;
    data.nwords = slave->sii_nwords;
    data.words = new uint16_t[data.nwords];

    try {
        m.readSii(&data);
    } catch (MasterDeviceException &e) {
        delete [] data.words;
        throw e;
    }

    if (getVerbosity() == Verbose) {
        cout << "SII Area:" << hex << setfill('0');
        for (i = 0; i < min(data.nwords, 0x0040U) * 2; i++) {
            if (i % BreakAfterBytes) {
                cout << " ";
            } else {
                cout << endl << "  ";
            }
            cout << setw(2) << (unsigned int) *((uint8_t *) data.words + i);
        }
        cout << endl;

        if (data.nwords > 0x0040U) {
            // cycle through categories
            categoryHeader = data.words + 0x0040U;
            categoryType = le16_to_cpup(categoryHeader);
            while (categoryType != 0xffff) {
                cout << "SII Category 0x" << hex
                    << setw(4) << categoryType
                    << " (" << getCategoryName(categoryType) << ")" << flush;

                if (categoryHeader + 1 > data.words + data.nwords) {
                    err << "SII data seem to be corrupted!";
                    throwCommandException(err);
                }
                categorySize = le16_to_cpup(categoryHeader + 1);
                cout << ", " << dec << categorySize << " words" << flush;

                if (categoryHeader + 2 + categorySize
                        > data.words + data.nwords) {
                    err << "SII data seem to be corrupted!";
                    throwCommandException(err);
                }

                cout << hex;
                for (i = 0; i < categorySize * 2U; i++) {
                    if (i % BreakAfterBytes) {
                        cout << " ";
                    } else {
                        cout << endl << "  ";
                    }
                    cout << setw(2) << (unsigned int)
                        *((uint8_t *) (categoryHeader + 2) + i);
                }
                cout << endl;

                if (categoryHeader + 2 + categorySize + 1
                        > data.words + data.nwords) {
                    err << "SII data seem to be corrupted!";
                    throwCommandException(err);
                }
                categoryHeader += 2 + categorySize;
                categoryType = le16_to_cpup(categoryHeader);
            }
        }
    } else {
        for (i = 0; i < data.nwords; i++) {
            uint16_t *w = data.words + i;
            cout << *(uint8_t *) w << *((uint8_t *) w + 1);
        }
    }

    delete [] data.words;
}

/****************************************************************************/

const CommandSiiRead::CategoryName CommandSiiRead::categoryNames[] = {
    {0x000a, "STRINGS"},
    {0x0014, "DataTypes"},
    {0x001e, "General"},
    {0x0028, "FMMU"},
    {0x0029, "SyncM"},
    {0x0032, "TXPDO"},
    {0x0033, "RXPDO"},
    {0x003c, "DC"},
    {}
};

/****************************************************************************/

const char *CommandSiiRead::getCategoryName(uint16_t type)
{
    const CategoryName *cn = categoryNames;

    while (cn->type) {
        if (cn->type == type) {
            return cn->name;
        }
        cn++;
    }

    return "unknown";
}

/*****************************************************************************/


<|start_filename|>3rdpart/ethercat-1.5.2/devices/e1000e/ich8lan-2.6.37-ethercat.c<|end_filename|>
/*******************************************************************************

  Intel PRO/1000 Linux driver
  Copyright(c) 1999 - 2010 Intel Corporation.

  This program is free software; you can redistribute it and/or modify it
  under the terms and conditions of the GNU General Public License,
  version 2, as published by the Free Software Foundation.

  This program is distributed in the hope it will be useful, but WITHOUT
  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  more details.

  You should have received a copy of the GNU General Public License along with
  this program; if not, write to the Free Software Foundation, Inc.,
  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.

  The full GNU General Public License is included in this distribution in
  the file called "COPYING".

  Contact Information:
  Linux NICS <<EMAIL>>
  e1000-devel Mailing List <<EMAIL>>
  Intel Corporation, 5200 N.E. El<NAME> Parkway, Hillsboro, OR 97124-6497

*******************************************************************************/

/*
 * 82562G 10/100 Network Connection
 * 82562G-2 10/100 Network Connection
 * 82562GT 10/100 Network Connection
 * 82562GT-2 10/100 Network Connection
 * 82562V 10/100 Network Connection
 * 82562V-2 10/100 Network Connection
 * 82566DC-2 Gigabit Network Connection
 * 82566DC Gigabit Network Connection
 * 82566DM-2 Gigabit Network Connection
 * 82566DM Gigabit Network Connection
 * 82566MC Gigabit Network Connection
 * 82566MM Gigabit Network Connection
 * 82567LM Gigabit Network Connection
 * 82567LF Gigabit Network Connection
 * 82567V Gigabit Network Connection
 * 82567LM-2 Gigabit Network Connection
 * 82567LF-2 Gigabit Network Connection
 * 82567V-2 Gigabit Network Connection
 * 82567LF-3 Gigabit Network Connection
 * 82567LM-3 Gigabit Network Connection
 * 82567LM-4 Gigabit Network Connection
 * 82577LM Gigabit Network Connection
 * 82577LC Gigabit Network Connection
 * 82578DM Gigabit Network Connection
 * 82578DC Gigabit Network Connection
 * 82579LM Gigabit Network Connection
 * 82579V Gigabit Network Connection
 */

#include "e1000-2.6.37-ethercat.h"

#define ICH_FLASH_GFPREG		0x0000
#define ICH_FLASH_HSFSTS		0x0004
#define ICH_FLASH_HSFCTL		0x0006
#define ICH_FLASH_FADDR			0x0008
#define ICH_FLASH_FDATA0		0x0010
#define ICH_FLASH_PR0			0x0074

#define ICH_FLASH_READ_COMMAND_TIMEOUT	500
#define ICH_FLASH_WRITE_COMMAND_TIMEOUT	500
#define ICH_FLASH_ERASE_COMMAND_TIMEOUT	3000000
#define ICH_FLASH_LINEAR_ADDR_MASK	0x00FFFFFF
#define ICH_FLASH_CYCLE_REPEAT_COUNT	10

#define ICH_CYCLE_READ			0
#define ICH_CYCLE_WRITE			2
#define ICH_CYCLE_ERASE			3

#define FLASH_GFPREG_BASE_MASK		0x1FFF
#define FLASH_SECTOR_ADDR_SHIFT		12

#define ICH_FLASH_SEG_SIZE_256		256
#define ICH_FLASH_SEG_SIZE_4K		4096
#define ICH_FLASH_SEG_SIZE_8K		8192
#define ICH_FLASH_SEG_SIZE_64K		65536


#define E1000_ICH_FWSM_RSPCIPHY	0x00000040 /* Reset PHY on PCI Reset */
/* FW established a valid mode */
#define E1000_ICH_FWSM_FW_VALID		0x00008000

#define E1000_ICH_MNG_IAMT_MODE		0x2

#define ID_LED_DEFAULT_ICH8LAN  ((ID_LED_DEF1_DEF2 << 12) | \
				 (ID_LED_DEF1_OFF2 <<  8) | \
				 (ID_LED_DEF1_ON2  <<  4) | \
				 (ID_LED_DEF1_DEF2))

#define E1000_ICH_NVM_SIG_WORD		0x13
#define E1000_ICH_NVM_SIG_MASK		0xC000
#define E1000_ICH_NVM_VALID_SIG_MASK    0xC0
#define E1000_ICH_NVM_SIG_VALUE         0x80

#define E1000_ICH8_LAN_INIT_TIMEOUT	1500

#define E1000_FEXTNVM_SW_CONFIG		1
#define E1000_FEXTNVM_SW_CONFIG_ICH8M (1 << 27) /* Bit redefined for ICH8M :/ */

#define E1000_FEXTNVM4_BEACON_DURATION_MASK    0x7
#define E1000_FEXTNVM4_BEACON_DURATION_8USEC   0x7
#define E1000_FEXTNVM4_BEACON_DURATION_16USEC  0x3

#define PCIE_ICH8_SNOOP_ALL		PCIE_NO_SNOOP_ALL

#define E1000_ICH_RAR_ENTRIES		7

#define PHY_PAGE_SHIFT 5
#define PHY_REG(page, reg) (((page) << PHY_PAGE_SHIFT) | \
			   ((reg) & MAX_PHY_REG_ADDRESS))
#define IGP3_KMRN_DIAG  PHY_REG(770, 19) /* KMRN Diagnostic */
#define IGP3_VR_CTRL    PHY_REG(776, 18) /* Voltage Regulator Control */

#define IGP3_KMRN_DIAG_PCS_LOCK_LOSS	0x0002
#define IGP3_VR_CTRL_DEV_POWERDOWN_MODE_MASK 0x0300
#define IGP3_VR_CTRL_MODE_SHUTDOWN	0x0200

#define HV_LED_CONFIG		PHY_REG(768, 30) /* LED Configuration */

#define SW_FLAG_TIMEOUT    1000 /* SW Semaphore flag timeout in milliseconds */

/* SMBus Address Phy Register */
#define HV_SMB_ADDR            PHY_REG(768, 26)
#define HV_SMB_ADDR_MASK       0x007F
#define HV_SMB_ADDR_PEC_EN     0x0200
#define HV_SMB_ADDR_VALID      0x0080

/* PHY Power Management Control */
#define HV_PM_CTRL		PHY_REG(770, 17)

/* PHY Low Power Idle Control */
#define I82579_LPI_CTRL			PHY_REG(772, 20)
#define I82579_LPI_CTRL_ENABLE_MASK	0x6000

/* Strapping Option Register - RO */
#define E1000_STRAP                     0x0000C
#define E1000_STRAP_SMBUS_ADDRESS_MASK  0x00FE0000
#define E1000_STRAP_SMBUS_ADDRESS_SHIFT 17

/* OEM Bits Phy Register */
#define HV_OEM_BITS            PHY_REG(768, 25)
#define HV_OEM_BITS_LPLU       0x0004 /* Low Power Link Up */
#define HV_OEM_BITS_GBE_DIS    0x0040 /* Gigabit Disable */
#define HV_OEM_BITS_RESTART_AN 0x0400 /* Restart Auto-negotiation */

#define E1000_NVM_K1_CONFIG 0x1B /* NVM K1 Config Word */
#define E1000_NVM_K1_ENABLE 0x1  /* NVM Enable K1 bit */

/* KMRN Mode Control */
#define HV_KMRN_MODE_CTRL      PHY_REG(769, 16)
#define HV_KMRN_MDIO_SLOW      0x0400

/* ICH GbE Flash Hardware Sequencing Flash Status Register bit breakdown */
/* Offset 04h HSFSTS */
union ich8_hws_flash_status {
	struct ich8_hsfsts {
		u16 flcdone    :1; /* bit 0 Flash Cycle Done */
		u16 flcerr     :1; /* bit 1 Flash Cycle Error */
		u16 dael       :1; /* bit 2 Direct Access error Log */
		u16 berasesz   :2; /* bit 4:3 Sector Erase Size */
		u16 flcinprog  :1; /* bit 5 flash cycle in Progress */
		u16 reserved1  :2; /* bit 13:6 Reserved */
		u16 reserved2  :6; /* bit 13:6 Reserved */
		u16 fldesvalid :1; /* bit 14 Flash Descriptor Valid */
		u16 flockdn    :1; /* bit 15 Flash Config Lock-Down */
	} hsf_status;
	u16 regval;
};

/* ICH GbE Flash Hardware Sequencing Flash control Register bit breakdown */
/* Offset 06h FLCTL */
union ich8_hws_flash_ctrl {
	struct ich8_hsflctl {
		u16 flcgo      :1;   /* 0 Flash Cycle Go */
		u16 flcycle    :2;   /* 2:1 Flash Cycle */
		u16 reserved   :5;   /* 7:3 Reserved  */
		u16 fldbcount  :2;   /* 9:8 Flash Data Byte Count */
		u16 flockdn    :6;   /* 15:10 Reserved */
	} hsf_ctrl;
	u16 regval;
};

/* ICH Flash Region Access Permissions */
union ich8_hws_flash_regacc {
	struct ich8_flracc {
		u32 grra      :8; /* 0:7 GbE region Read Access */
		u32 grwa      :8; /* 8:15 GbE region Write Access */
		u32 gmrag     :8; /* 23:16 GbE Master Read Access Grant */
		u32 gmwag     :8; /* 31:24 GbE Master Write Access Grant */
	} hsf_flregacc;
	u16 regval;
};

/* ICH Flash Protected Region */
union ich8_flash_protected_range {
	struct ich8_pr {
		u32 base:13;     /* 0:12 Protected Range Base */
		u32 reserved1:2; /* 13:14 Reserved */
		u32 rpe:1;       /* 15 Read Protection Enable */
		u32 limit:13;    /* 16:28 Protected Range Limit */
		u32 reserved2:2; /* 29:30 Reserved */
		u32 wpe:1;       /* 31 Write Protection Enable */
	} range;
	u32 regval;
};

static s32 e1000_setup_link_ich8lan(struct e1000_hw *hw);
static void e1000_clear_hw_cntrs_ich8lan(struct e1000_hw *hw);
static void e1000_initialize_hw_bits_ich8lan(struct e1000_hw *hw);
static s32 e1000_erase_flash_bank_ich8lan(struct e1000_hw *hw, u32 bank);
static s32 e1000_retry_write_flash_byte_ich8lan(struct e1000_hw *hw,
						u32 offset, u8 byte);
static s32 e1000_read_flash_byte_ich8lan(struct e1000_hw *hw, u32 offset,
					 u8 *data);
static s32 e1000_read_flash_word_ich8lan(struct e1000_hw *hw, u32 offset,
					 u16 *data);
static s32 e1000_read_flash_data_ich8lan(struct e1000_hw *hw, u32 offset,
					 u8 size, u16 *data);
static s32 e1000_setup_copper_link_ich8lan(struct e1000_hw *hw);
static s32 e1000_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw);
static s32 e1000_get_cfg_done_ich8lan(struct e1000_hw *hw);
static s32 e1000_cleanup_led_ich8lan(struct e1000_hw *hw);
static s32 e1000_led_on_ich8lan(struct e1000_hw *hw);
static s32 e1000_led_off_ich8lan(struct e1000_hw *hw);
static s32 e1000_id_led_init_pchlan(struct e1000_hw *hw);
static s32 e1000_setup_led_pchlan(struct e1000_hw *hw);
static s32 e1000_cleanup_led_pchlan(struct e1000_hw *hw);
static s32 e1000_led_on_pchlan(struct e1000_hw *hw);
static s32 e1000_led_off_pchlan(struct e1000_hw *hw);
static s32 e1000_set_lplu_state_pchlan(struct e1000_hw *hw, bool active);
static void e1000_power_down_phy_copper_ich8lan(struct e1000_hw *hw);
static void e1000_lan_init_done_ich8lan(struct e1000_hw *hw);
static s32  e1000_k1_gig_workaround_hv(struct e1000_hw *hw, bool link);
static s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw);
static bool e1000_check_mng_mode_ich8lan(struct e1000_hw *hw);
static bool e1000_check_mng_mode_pchlan(struct e1000_hw *hw);
static s32 e1000_k1_workaround_lv(struct e1000_hw *hw);
static void e1000_gate_hw_phy_config_ich8lan(struct e1000_hw *hw, bool gate);

static inline u16 __er16flash(struct e1000_hw *hw, unsigned long reg)
{
	return readw(hw->flash_address + reg);
}

static inline u32 __er32flash(struct e1000_hw *hw, unsigned long reg)
{
	return readl(hw->flash_address + reg);
}

static inline void __ew16flash(struct e1000_hw *hw, unsigned long reg, u16 val)
{
	writew(val, hw->flash_address + reg);
}

static inline void __ew32flash(struct e1000_hw *hw, unsigned long reg, u32 val)
{
	writel(val, hw->flash_address + reg);
}

#define er16flash(reg)		__er16flash(hw, (reg))
#define er32flash(reg)		__er32flash(hw, (reg))
#define ew16flash(reg,val)	__ew16flash(hw, (reg), (val))
#define ew32flash(reg,val)	__ew32flash(hw, (reg), (val))

/**
 *  e1000_init_phy_params_pchlan - Initialize PHY function pointers
 *  @hw: pointer to the HW structure
 *
 *  Initialize family-specific PHY parameters and function pointers.
 **/
static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw)
{
	struct e1000_phy_info *phy = &hw->phy;
	u32 ctrl, fwsm;
	s32 ret_val = 0;

	phy->addr                     = 1;
	phy->reset_delay_us           = 100;

	phy->ops.read_reg             = e1000_read_phy_reg_hv;
	phy->ops.read_reg_locked      = e1000_read_phy_reg_hv_locked;
	phy->ops.set_d0_lplu_state    = e1000_set_lplu_state_pchlan;
	phy->ops.set_d3_lplu_state    = e1000_set_lplu_state_pchlan;
	phy->ops.write_reg            = e1000_write_phy_reg_hv;
	phy->ops.write_reg_locked     = e1000_write_phy_reg_hv_locked;
	phy->ops.power_up             = e1000_power_up_phy_copper;
	phy->ops.power_down           = e1000_power_down_phy_copper_ich8lan;
	phy->autoneg_mask             = AUTONEG_ADVERTISE_SPEED_DEFAULT;

	/*
	 * The MAC-PHY interconnect may still be in SMBus mode
	 * after Sx->S0.  If the manageability engine (ME) is
	 * disabled, then toggle the LANPHYPC Value bit to force
	 * the interconnect to PCIe mode.
	 */
	fwsm = er32(FWSM);
	if (!(fwsm & E1000_ICH_FWSM_FW_VALID)) {
		ctrl = er32(CTRL);
		ctrl |=  E1000_CTRL_LANPHYPC_OVERRIDE;
		ctrl &= ~E1000_CTRL_LANPHYPC_VALUE;
		ew32(CTRL, ctrl);
		udelay(10);
		ctrl &= ~E1000_CTRL_LANPHYPC_OVERRIDE;
		ew32(CTRL, ctrl);
		msleep(50);

		/*
		 * Gate automatic PHY configuration by hardware on
		 * non-managed 82579
		 */
		if (hw->mac.type == e1000_pch2lan)
			e1000_gate_hw_phy_config_ich8lan(hw, true);
	}

	/*
	 * Reset the PHY before any acccess to it.  Doing so, ensures that
	 * the PHY is in a known good state before we read/write PHY registers.
	 * The generic reset is sufficient here, because we haven't determined
	 * the PHY type yet.
	 */
	ret_val = e1000e_phy_hw_reset_generic(hw);
	if (ret_val)
		goto out;

	/* Ungate automatic PHY configuration on non-managed 82579 */
	if ((hw->mac.type == e1000_pch2lan)  &&
	    !(fwsm & E1000_ICH_FWSM_FW_VALID)) {
		msleep(10);
		e1000_gate_hw_phy_config_ich8lan(hw, false);
	}

	phy->id = e1000_phy_unknown;
	switch (hw->mac.type) {
	default:
		ret_val = e1000e_get_phy_id(hw);
		if (ret_val)
			goto out;
		if ((phy->id != 0) && (phy->id != PHY_REVISION_MASK))
			break;
		/* fall-through */
	case e1000_pch2lan:
		/*
		 * In case the PHY needs to be in mdio slow mode,
		 * set slow mode and try to get the PHY id again.
		 */
		ret_val = e1000_set_mdio_slow_mode_hv(hw);
		if (ret_val)
			goto out;
		ret_val = e1000e_get_phy_id(hw);
		if (ret_val)
			goto out;
		break;
	}
	phy->type = e1000e_get_phy_type_from_id(phy->id);

	switch (phy->type) {
	case e1000_phy_82577:
	case e1000_phy_82579:
		phy->ops.check_polarity = e1000_check_polarity_82577;
		phy->ops.force_speed_duplex =
			e1000_phy_force_speed_duplex_82577;
		phy->ops.get_cable_length = e1000_get_cable_length_82577;
		phy->ops.get_info = e1000_get_phy_info_82577;
		phy->ops.commit = e1000e_phy_sw_reset;
		break;
	case e1000_phy_82578:
		phy->ops.check_polarity = e1000_check_polarity_m88;
		phy->ops.force_speed_duplex = e1000e_phy_force_speed_duplex_m88;
		phy->ops.get_cable_length = e1000e_get_cable_length_m88;
		phy->ops.get_info = e1000e_get_phy_info_m88;
		break;
	default:
		ret_val = -E1000_ERR_PHY;
		break;
	}

out:
	return ret_val;
}

/**
 *  e1000_init_phy_params_ich8lan - Initialize PHY function pointers
 *  @hw: pointer to the HW structure
 *
 *  Initialize family-specific PHY parameters and function pointers.
 **/
static s32 e1000_init_phy_params_ich8lan(struct e1000_hw *hw)
{
	struct e1000_phy_info *phy = &hw->phy;
	s32 ret_val;
	u16 i = 0;

	phy->addr			= 1;
	phy->reset_delay_us		= 100;

	phy->ops.power_up               = e1000_power_up_phy_copper;
	phy->ops.power_down             = e1000_power_down_phy_copper_ich8lan;

	/*
	 * We may need to do this twice - once for IGP and if that fails,
	 * we'll set BM func pointers and try again
	 */
	ret_val = e1000e_determine_phy_address(hw);
	if (ret_val) {
		phy->ops.write_reg = e1000e_write_phy_reg_bm;
		phy->ops.read_reg  = e1000e_read_phy_reg_bm;
		ret_val = e1000e_determine_phy_address(hw);
		if (ret_val) {
			e_dbg("Cannot determine PHY addr. Erroring out\n");
			return ret_val;
		}
	}

	phy->id = 0;
	while ((e1000_phy_unknown == e1000e_get_phy_type_from_id(phy->id)) &&
	       (i++ < 100)) {
		msleep(1);
		ret_val = e1000e_get_phy_id(hw);
		if (ret_val)
			return ret_val;
	}

	/* Verify phy id */
	switch (phy->id) {
	case IGP03E1000_E_PHY_ID:
		phy->type = e1000_phy_igp_3;
		phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT;
		phy->ops.read_reg_locked = e1000e_read_phy_reg_igp_locked;
		phy->ops.write_reg_locked = e1000e_write_phy_reg_igp_locked;
		phy->ops.get_info = e1000e_get_phy_info_igp;
		phy->ops.check_polarity = e1000_check_polarity_igp;
		phy->ops.force_speed_duplex = e1000e_phy_force_speed_duplex_igp;
		break;
	case IFE_E_PHY_ID:
	case IFE_PLUS_E_PHY_ID:
	case IFE_C_E_PHY_ID:
		phy->type = e1000_phy_ife;
		phy->autoneg_mask = E1000_ALL_NOT_GIG;
		phy->ops.get_info = e1000_get_phy_info_ife;
		phy->ops.check_polarity = e1000_check_polarity_ife;
		phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_ife;
		break;
	case BME1000_E_PHY_ID:
		phy->type = e1000_phy_bm;
		phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT;
		phy->ops.read_reg = e1000e_read_phy_reg_bm;
		phy->ops.write_reg = e1000e_write_phy_reg_bm;
		phy->ops.commit = e1000e_phy_sw_reset;
		phy->ops.get_info = e1000e_get_phy_info_m88;
		phy->ops.check_polarity = e1000_check_polarity_m88;
		phy->ops.force_speed_duplex = e1000e_phy_force_speed_duplex_m88;
		break;
	default:
		return -E1000_ERR_PHY;
		break;
	}

	return 0;
}

/**
 *  e1000_init_nvm_params_ich8lan - Initialize NVM function pointers
 *  @hw: pointer to the HW structure
 *
 *  Initialize family-specific NVM parameters and function
 *  pointers.
 **/
static s32 e1000_init_nvm_params_ich8lan(struct e1000_hw *hw)
{
	struct e1000_nvm_info *nvm = &hw->nvm;
	struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan;
	u32 gfpreg, sector_base_addr, sector_end_addr;
	u16 i;

	/* Can't read flash registers if the register set isn't mapped. */
	if (!hw->flash_address) {
		e_dbg("ERROR: Flash registers not mapped\n");
		return -E1000_ERR_CONFIG;
	}

	nvm->type = e1000_nvm_flash_sw;

	gfpreg = er32flash(ICH_FLASH_GFPREG);

	/*
	 * sector_X_addr is a "sector"-aligned address (4096 bytes)
	 * Add 1 to sector_end_addr since this sector is included in
	 * the overall size.
	 */
	sector_base_addr = gfpreg & FLASH_GFPREG_BASE_MASK;
	sector_end_addr = ((gfpreg >> 16) & FLASH_GFPREG_BASE_MASK) + 1;

	/* flash_base_addr is byte-aligned */
	nvm->flash_base_addr = sector_base_addr << FLASH_SECTOR_ADDR_SHIFT;

	/*
	 * find total size of the NVM, then cut in half since the total
	 * size represents two separate NVM banks.
	 */
	nvm->flash_bank_size = (sector_end_addr - sector_base_addr)
				<< FLASH_SECTOR_ADDR_SHIFT;
	nvm->flash_bank_size /= 2;
	/* Adjust to word count */
	nvm->flash_bank_size /= sizeof(u16);

	nvm->word_size = E1000_ICH8_SHADOW_RAM_WORDS;

	/* Clear shadow ram */
	for (i = 0; i < nvm->word_size; i++) {
		dev_spec->shadow_ram[i].modified = false;
		dev_spec->shadow_ram[i].value    = 0xFFFF;
	}

	return 0;
}

/**
 *  e1000_init_mac_params_ich8lan - Initialize MAC function pointers
 *  @hw: pointer to the HW structure
 *
 *  Initialize family-specific MAC parameters and function
 *  pointers.
 **/
static s32 e1000_init_mac_params_ich8lan(struct e1000_adapter *adapter)
{
	struct e1000_hw *hw = &adapter->hw;
	struct e1000_mac_info *mac = &hw->mac;

	/* Set media type function pointer */
	hw->phy.media_type = e1000_media_type_copper;

	/* Set mta register count */
	mac->mta_reg_count = 32;
	/* Set rar entry count */
	mac->rar_entry_count = E1000_ICH_RAR_ENTRIES;
	if (mac->type == e1000_ich8lan)
		mac->rar_entry_count--;
	/* FWSM register */
	mac->has_fwsm = true;
	/* ARC subsystem not supported */
	mac->arc_subsystem_valid = false;
	/* Adaptive IFS supported */
	mac->adaptive_ifs = true;

	/* LED operations */
	switch (mac->type) {
	case e1000_ich8lan:
	case e1000_ich9lan:
	case e1000_ich10lan:
		/* check management mode */
		mac->ops.check_mng_mode = e1000_check_mng_mode_ich8lan;
		/* ID LED init */
		mac->ops.id_led_init = e1000e_id_led_init;
		/* setup LED */
		mac->ops.setup_led = e1000e_setup_led_generic;
		/* cleanup LED */
		mac->ops.cleanup_led = e1000_cleanup_led_ich8lan;
		/* turn on/off LED */
		mac->ops.led_on = e1000_led_on_ich8lan;
		mac->ops.led_off = e1000_led_off_ich8lan;
		break;
	case e1000_pchlan:
	case e1000_pch2lan:
		/* check management mode */
		mac->ops.check_mng_mode = e1000_check_mng_mode_pchlan;
		/* ID LED init */
		mac->ops.id_led_init = e1000_id_led_init_pchlan;
		/* setup LED */
		mac->ops.setup_led = e1000_setup_led_pchlan;
		/* cleanup LED */
		mac->ops.cleanup_led = e1000_cleanup_led_pchlan;
		/* turn on/off LED */
		mac->ops.led_on = e1000_led_on_pchlan;
		mac->ops.led_off = e1000_led_off_pchlan;
		break;
	default:
		break;
	}

	/* Enable PCS Lock-loss workaround for ICH8 */
	if (mac->type == e1000_ich8lan)
		e1000e_set_kmrn_lock_loss_workaround_ich8lan(hw, true);

	/* Gate automatic PHY configuration by hardware on managed 82579 */
	if ((mac->type == e1000_pch2lan) &&
	    (er32(FWSM) & E1000_ICH_FWSM_FW_VALID))
		e1000_gate_hw_phy_config_ich8lan(hw, true);

	return 0;
}

/**
 *  e1000_set_eee_pchlan - Enable/disable EEE support
 *  @hw: pointer to the HW structure
 *
 *  Enable/disable EEE based on setting in dev_spec structure.  The bits in
 *  the LPI Control register will remain set only if/when link is up.
 **/
static s32 e1000_set_eee_pchlan(struct e1000_hw *hw)
{
	s32 ret_val = 0;
	u16 phy_reg;

	if (hw->phy.type != e1000_phy_82579)
		goto out;

	ret_val = e1e_rphy(hw, I82579_LPI_CTRL, &phy_reg);
	if (ret_val)
		goto out;

	if (hw->dev_spec.ich8lan.eee_disable)
		phy_reg &= ~I82579_LPI_CTRL_ENABLE_MASK;
	else
		phy_reg |= I82579_LPI_CTRL_ENABLE_MASK;

	ret_val = e1e_wphy(hw, I82579_LPI_CTRL, phy_reg);
out:
	return ret_val;
}

/**
 *  e1000_check_for_copper_link_ich8lan - Check for link (Copper)
 *  @hw: pointer to the HW structure
 *
 *  Checks to see of the link status of the hardware has changed.  If a
 *  change in link status has been detected, then we read the PHY registers
 *  to get the current speed/duplex if link exists.
 **/
static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
{
	struct e1000_mac_info *mac = &hw->mac;
	s32 ret_val;
	bool link;

	/*
	 * We only want to go out to the PHY registers to see if Auto-Neg
	 * has completed and/or if our link status has changed.  The
	 * get_link_status flag is set upon receiving a Link Status
	 * Change or Rx Sequence Error interrupt.
	 */
	if (!mac->get_link_status) {
		ret_val = 0;
		goto out;
	}

	/*
	 * First we want to see if the MII Status Register reports
	 * link.  If so, then we want to get the current speed/duplex
	 * of the PHY.
	 */
	ret_val = e1000e_phy_has_link_generic(hw, 1, 0, &link);
	if (ret_val)
		goto out;

	if (hw->mac.type == e1000_pchlan) {
		ret_val = e1000_k1_gig_workaround_hv(hw, link);
		if (ret_val)
			goto out;
	}

	if (!link)
		goto out; /* No link detected */

	mac->get_link_status = false;

	if (hw->phy.type == e1000_phy_82578) {
		ret_val = e1000_link_stall_workaround_hv(hw);
		if (ret_val)
			goto out;
	}

	if (hw->mac.type == e1000_pch2lan) {
		ret_val = e1000_k1_workaround_lv(hw);
		if (ret_val)
			goto out;
	}

	/*
	 * Check if there was DownShift, must be checked
	 * immediately after link-up
	 */
	e1000e_check_downshift(hw);

	/* Enable/Disable EEE after link up */
	ret_val = e1000_set_eee_pchlan(hw);
	if (ret_val)
		goto out;

	/*
	 * If we are forcing speed/duplex, then we simply return since
	 * we have already determined whether we have link or not.
	 */
	if (!mac->autoneg) {
		ret_val = -E1000_ERR_CONFIG;
		goto out;
	}

	/*
	 * Auto-Neg is enabled.  Auto Speed Detection takes care
	 * of MAC speed/duplex configuration.  So we only need to
	 * configure Collision Distance in the MAC.
	 */
	e1000e_config_collision_dist(hw);

	/*
	 * Configure Flow Control now that Auto-Neg has completed.
	 * First, we need to restore the desired flow control
	 * settings because we may have had to re-autoneg with a
	 * different link partner.
	 */
	ret_val = e1000e_config_fc_after_link_up(hw);
	if (ret_val)
		e_dbg("Error configuring flow control\n");

out:
	return ret_val;
}

static s32 e1000_get_variants_ich8lan(struct e1000_adapter *adapter)
{
	struct e1000_hw *hw = &adapter->hw;
	s32 rc;

	rc = e1000_init_mac_params_ich8lan(adapter);
	if (rc)
		return rc;

	rc = e1000_init_nvm_params_ich8lan(hw);
	if (rc)
		return rc;

	switch (hw->mac.type) {
	case e1000_ich8lan:
	case e1000_ich9lan:
	case e1000_ich10lan:
		rc = e1000_init_phy_params_ich8lan(hw);
		break;
	case e1000_pchlan:
	case e1000_pch2lan:
		rc = e1000_init_phy_params_pchlan(hw);
		break;
	default:
		break;
	}
	if (rc)
		return rc;

	if (adapter->hw.phy.type == e1000_phy_ife) {
		adapter->flags &= ~FLAG_HAS_JUMBO_FRAMES;
		adapter->max_hw_frame_size = ETH_FRAME_LEN + ETH_FCS_LEN;
	}

	if ((adapter->hw.mac.type == e1000_ich8lan) &&
	    (adapter->hw.phy.type == e1000_phy_igp_3))
		adapter->flags |= FLAG_LSC_GIG_SPEED_DROP;

	/* Disable EEE by default until IEEE802.3az spec is finalized */
	if (adapter->flags2 & FLAG2_HAS_EEE)
		adapter->hw.dev_spec.ich8lan.eee_disable = true;

	return 0;
}

static DEFINE_MUTEX(nvm_mutex);

/**
 *  e1000_acquire_nvm_ich8lan - Acquire NVM mutex
 *  @hw: pointer to the HW structure
 *
 *  Acquires the mutex for performing NVM operations.
 **/
static s32 e1000_acquire_nvm_ich8lan(struct e1000_hw *hw)
{
	mutex_lock(&nvm_mutex);

	return 0;
}

/**
 *  e1000_release_nvm_ich8lan - Release NVM mutex
 *  @hw: pointer to the HW structure
 *
 *  Releases the mutex used while performing NVM operations.
 **/
static void e1000_release_nvm_ich8lan(struct e1000_hw *hw)
{
	mutex_unlock(&nvm_mutex);
}

static DEFINE_MUTEX(swflag_mutex);

/**
 *  e1000_acquire_swflag_ich8lan - Acquire software control flag
 *  @hw: pointer to the HW structure
 *
 *  Acquires the software control flag for performing PHY and select
 *  MAC CSR accesses.
 **/
static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw)
{
	u32 extcnf_ctrl, timeout = PHY_CFG_TIMEOUT;
	s32 ret_val = 0;

	mutex_lock(&swflag_mutex);

	while (timeout) {
		extcnf_ctrl = er32(EXTCNF_CTRL);
		if (!(extcnf_ctrl & E1000_EXTCNF_CTRL_SWFLAG))
			break;

		mdelay(1);
		timeout--;
	}

	if (!timeout) {
		e_dbg("SW/FW/HW has locked the resource for too long.\n");
		ret_val = -E1000_ERR_CONFIG;
		goto out;
	}

	timeout = SW_FLAG_TIMEOUT;

	extcnf_ctrl |= E1000_EXTCNF_CTRL_SWFLAG;
	ew32(EXTCNF_CTRL, extcnf_ctrl);

	while (timeout) {
		extcnf_ctrl = er32(EXTCNF_CTRL);
		if (extcnf_ctrl & E1000_EXTCNF_CTRL_SWFLAG)
			break;

		mdelay(1);
		timeout--;
	}

	if (!timeout) {
		e_dbg("Failed to acquire the semaphore.\n");
		extcnf_ctrl &= ~E1000_EXTCNF_CTRL_SWFLAG;
		ew32(EXTCNF_CTRL, extcnf_ctrl);
		ret_val = -E1000_ERR_CONFIG;
		goto out;
	}

out:
	if (ret_val)
		mutex_unlock(&swflag_mutex);

	return ret_val;
}

/**
 *  e1000_release_swflag_ich8lan - Release software control flag
 *  @hw: pointer to the HW structure
 *
 *  Releases the software control flag for performing PHY and select
 *  MAC CSR accesses.
 **/
static void e1000_release_swflag_ich8lan(struct e1000_hw *hw)
{
	u32 extcnf_ctrl;

	extcnf_ctrl = er32(EXTCNF_CTRL);
	extcnf_ctrl &= ~E1000_EXTCNF_CTRL_SWFLAG;
	ew32(EXTCNF_CTRL, extcnf_ctrl);

	mutex_unlock(&swflag_mutex);
}

/**
 *  e1000_check_mng_mode_ich8lan - Checks management mode
 *  @hw: pointer to the HW structure
 *
 *  This checks if the adapter has any manageability enabled.
 *  This is a function pointer entry point only called by read/write
 *  routines for the PHY and NVM parts.
 **/
static bool e1000_check_mng_mode_ich8lan(struct e1000_hw *hw)
{
	u32 fwsm;

	fwsm = er32(FWSM);
	return (fwsm & E1000_ICH_FWSM_FW_VALID) &&
	       ((fwsm & E1000_FWSM_MODE_MASK) ==
		(E1000_ICH_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT));
}

/**
 *  e1000_check_mng_mode_pchlan - Checks management mode
 *  @hw: pointer to the HW structure
 *
 *  This checks if the adapter has iAMT enabled.
 *  This is a function pointer entry point only called by read/write
 *  routines for the PHY and NVM parts.
 **/
static bool e1000_check_mng_mode_pchlan(struct e1000_hw *hw)
{
	u32 fwsm;

	fwsm = er32(FWSM);
	return (fwsm & E1000_ICH_FWSM_FW_VALID) &&
	       (fwsm & (E1000_ICH_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT));
}

/**
 *  e1000_check_reset_block_ich8lan - Check if PHY reset is blocked
 *  @hw: pointer to the HW structure
 *
 *  Checks if firmware is blocking the reset of the PHY.
 *  This is a function pointer entry point only called by
 *  reset routines.
 **/
static s32 e1000_check_reset_block_ich8lan(struct e1000_hw *hw)
{
	u32 fwsm;

	fwsm = er32(FWSM);

	return (fwsm & E1000_ICH_FWSM_RSPCIPHY) ? 0 : E1000_BLK_PHY_RESET;
}

/**
 *  e1000_write_smbus_addr - Write SMBus address to PHY needed during Sx states
 *  @hw: pointer to the HW structure
 *
 *  Assumes semaphore already acquired.
 *
 **/
static s32 e1000_write_smbus_addr(struct e1000_hw *hw)
{
	u16 phy_data;
	u32 strap = er32(STRAP);
	s32 ret_val = 0;

	strap &= E1000_STRAP_SMBUS_ADDRESS_MASK;

	ret_val = e1000_read_phy_reg_hv_locked(hw, HV_SMB_ADDR, &phy_data);
	if (ret_val)
		goto out;

	phy_data &= ~HV_SMB_ADDR_MASK;
	phy_data |= (strap >> E1000_STRAP_SMBUS_ADDRESS_SHIFT);
	phy_data |= HV_SMB_ADDR_PEC_EN | HV_SMB_ADDR_VALID;
	ret_val = e1000_write_phy_reg_hv_locked(hw, HV_SMB_ADDR, phy_data);

out:
	return ret_val;
}

/**
 *  e1000_sw_lcd_config_ich8lan - SW-based LCD Configuration
 *  @hw:   pointer to the HW structure
 *
 *  SW should configure the LCD from the NVM extended configuration region
 *  as a workaround for certain parts.
 **/
static s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw)
{
	struct e1000_phy_info *phy = &hw->phy;
	u32 i, data, cnf_size, cnf_base_addr, sw_cfg_mask;
	s32 ret_val = 0;
	u16 word_addr, reg_data, reg_addr, phy_page = 0;

	/*
	 * Initialize the PHY from the NVM on ICH platforms.  This
	 * is needed due to an issue where the NVM configuration is
	 * not properly autoloaded after power transitions.
	 * Therefore, after each PHY reset, we will load the
	 * configuration data out of the NVM manually.
	 */
	switch (hw->mac.type) {
	case e1000_ich8lan:
		if (phy->type != e1000_phy_igp_3)
			return ret_val;

		if ((hw->adapter->pdev->device == E1000_DEV_ID_ICH8_IGP_AMT) ||
		    (hw->adapter->pdev->device == E1000_DEV_ID_ICH8_IGP_C)) {
			sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG;
			break;
		}
		/* Fall-thru */
	case e1000_pchlan:
	case e1000_pch2lan:
		sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG_ICH8M;
		break;
	default:
		return ret_val;
	}

	ret_val = hw->phy.ops.acquire(hw);
	if (ret_val)
		return ret_val;

	data = er32(FEXTNVM);
	if (!(data & sw_cfg_mask))
		goto out;

	/*
	 * Make sure HW does not configure LCD from PHY
	 * extended configuration before SW configuration
	 */
	data = er32(EXTCNF_CTRL);
	if (!(hw->mac.type == e1000_pch2lan)) {
		if (data & E1000_EXTCNF_CTRL_LCD_WRITE_ENABLE)
			goto out;
	}

	cnf_size = er32(EXTCNF_SIZE);
	cnf_size &= E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_MASK;
	cnf_size >>= E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_SHIFT;
	if (!cnf_size)
		goto out;

	cnf_base_addr = data & E1000_EXTCNF_CTRL_EXT_CNF_POINTER_MASK;
	cnf_base_addr >>= E1000_EXTCNF_CTRL_EXT_CNF_POINTER_SHIFT;

	if ((!(data & E1000_EXTCNF_CTRL_OEM_WRITE_ENABLE) &&
	    (hw->mac.type == e1000_pchlan)) ||
	     (hw->mac.type == e1000_pch2lan)) {
		/*
		 * HW configures the SMBus address and LEDs when the
		 * OEM and LCD Write Enable bits are set in the NVM.
		 * When both NVM bits are cleared, SW will configure
		 * them instead.
		 */
		ret_val = e1000_write_smbus_addr(hw);
		if (ret_val)
			goto out;

		data = er32(LEDCTL);
		ret_val = e1000_write_phy_reg_hv_locked(hw, HV_LED_CONFIG,
							(u16)data);
		if (ret_val)
			goto out;
	}

	/* Configure LCD from extended configuration region. */

	/* cnf_base_addr is in DWORD */
	word_addr = (u16)(cnf_base_addr << 1);

	for (i = 0; i < cnf_size; i++) {
		ret_val = e1000_read_nvm(hw, (word_addr + i * 2), 1,
					 &reg_data);
		if (ret_val)
			goto out;

		ret_val = e1000_read_nvm(hw, (word_addr + i * 2 + 1),
					 1, &reg_addr);
		if (ret_val)
			goto out;

		/* Save off the PHY page for future writes. */
		if (reg_addr == IGP01E1000_PHY_PAGE_SELECT) {
			phy_page = reg_data;
			continue;
		}

		reg_addr &= PHY_REG_MASK;
		reg_addr |= phy_page;

		ret_val = phy->ops.write_reg_locked(hw, (u32)reg_addr,
						    reg_data);
		if (ret_val)
			goto out;
	}

out:
	hw->phy.ops.release(hw);
	return ret_val;
}

/**
 *  e1000_k1_gig_workaround_hv - K1 Si workaround
 *  @hw:   pointer to the HW structure
 *  @link: link up bool flag
 *
 *  If K1 is enabled for 1Gbps, the MAC might stall when transitioning
 *  from a lower speed.  This workaround disables K1 whenever link is at 1Gig
 *  If link is down, the function will restore the default K1 setting located
 *  in the NVM.
 **/
static s32 e1000_k1_gig_workaround_hv(struct e1000_hw *hw, bool link)
{
	s32 ret_val = 0;
	u16 status_reg = 0;
	bool k1_enable = hw->dev_spec.ich8lan.nvm_k1_enabled;

	if (hw->mac.type != e1000_pchlan)
		goto out;

	/* Wrap the whole flow with the sw flag */
	ret_val = hw->phy.ops.acquire(hw);
	if (ret_val)
		goto out;

	/* Disable K1 when link is 1Gbps, otherwise use the NVM setting */
	if (link) {
		if (hw->phy.type == e1000_phy_82578) {
			ret_val = hw->phy.ops.read_reg_locked(hw, BM_CS_STATUS,
			                                          &status_reg);
			if (ret_val)
				goto release;

			status_reg &= BM_CS_STATUS_LINK_UP |
			              BM_CS_STATUS_RESOLVED |
			              BM_CS_STATUS_SPEED_MASK;

			if (status_reg == (BM_CS_STATUS_LINK_UP |
			                   BM_CS_STATUS_RESOLVED |
			                   BM_CS_STATUS_SPEED_1000))
				k1_enable = false;
		}

		if (hw->phy.type == e1000_phy_82577) {
			ret_val = hw->phy.ops.read_reg_locked(hw, HV_M_STATUS,
			                                          &status_reg);
			if (ret_val)
				goto release;

			status_reg &= HV_M_STATUS_LINK_UP |
			              HV_M_STATUS_AUTONEG_COMPLETE |
			              HV_M_STATUS_SPEED_MASK;

			if (status_reg == (HV_M_STATUS_LINK_UP |
			                   HV_M_STATUS_AUTONEG_COMPLETE |
			                   HV_M_STATUS_SPEED_1000))
				k1_enable = false;
		}

		/* Link stall fix for link up */
		ret_val = hw->phy.ops.write_reg_locked(hw, PHY_REG(770, 19),
		                                           0x0100);
		if (ret_val)
			goto release;

	} else {
		/* Link stall fix for link down */
		ret_val = hw->phy.ops.write_reg_locked(hw, PHY_REG(770, 19),
		                                           0x4100);
		if (ret_val)
			goto release;
	}

	ret_val = e1000_configure_k1_ich8lan(hw, k1_enable);

release:
	hw->phy.ops.release(hw);
out:
	return ret_val;
}

/**
 *  e1000_configure_k1_ich8lan - Configure K1 power state
 *  @hw: pointer to the HW structure
 *  @enable: K1 state to configure
 *
 *  Configure the K1 power state based on the provided parameter.
 *  Assumes semaphore already acquired.
 *
 *  Success returns 0, Failure returns -E1000_ERR_PHY (-2)
 **/
s32 e1000_configure_k1_ich8lan(struct e1000_hw *hw, bool k1_enable)
{
	s32 ret_val = 0;
	u32 ctrl_reg = 0;
	u32 ctrl_ext = 0;
	u32 reg = 0;
	u16 kmrn_reg = 0;

	ret_val = e1000e_read_kmrn_reg_locked(hw,
	                                     E1000_KMRNCTRLSTA_K1_CONFIG,
	                                     &kmrn_reg);
	if (ret_val)
		goto out;

	if (k1_enable)
		kmrn_reg |= E1000_KMRNCTRLSTA_K1_ENABLE;
	else
		kmrn_reg &= ~E1000_KMRNCTRLSTA_K1_ENABLE;

	ret_val = e1000e_write_kmrn_reg_locked(hw,
	                                      E1000_KMRNCTRLSTA_K1_CONFIG,
	                                      kmrn_reg);
	if (ret_val)
		goto out;

	udelay(20);
	ctrl_ext = er32(CTRL_EXT);
	ctrl_reg = er32(CTRL);

	reg = ctrl_reg & ~(E1000_CTRL_SPD_1000 | E1000_CTRL_SPD_100);
	reg |= E1000_CTRL_FRCSPD;
	ew32(CTRL, reg);

	ew32(CTRL_EXT, ctrl_ext | E1000_CTRL_EXT_SPD_BYPS);
	udelay(20);
	ew32(CTRL, ctrl_reg);
	ew32(CTRL_EXT, ctrl_ext);
	udelay(20);

out:
	return ret_val;
}

/**
 *  e1000_oem_bits_config_ich8lan - SW-based LCD Configuration
 *  @hw:       pointer to the HW structure
 *  @d0_state: boolean if entering d0 or d3 device state
 *
 *  SW will configure Gbe Disable and LPLU based on the NVM. The four bits are
 *  collectively called OEM bits.  The OEM Write Enable bit and SW Config bit
 *  in NVM determines whether HW should configure LPLU and Gbe Disable.
 **/
static s32 e1000_oem_bits_config_ich8lan(struct e1000_hw *hw, bool d0_state)
{
	s32 ret_val = 0;
	u32 mac_reg;
	u16 oem_reg;

	if ((hw->mac.type != e1000_pch2lan) && (hw->mac.type != e1000_pchlan))
		return ret_val;

	ret_val = hw->phy.ops.acquire(hw);
	if (ret_val)
		return ret_val;

	if (!(hw->mac.type == e1000_pch2lan)) {
		mac_reg = er32(EXTCNF_CTRL);
		if (mac_reg & E1000_EXTCNF_CTRL_OEM_WRITE_ENABLE)
			goto out;
	}

	mac_reg = er32(FEXTNVM);
	if (!(mac_reg & E1000_FEXTNVM_SW_CONFIG_ICH8M))
		goto out;

	mac_reg = er32(PHY_CTRL);

	ret_val = hw->phy.ops.read_reg_locked(hw, HV_OEM_BITS, &oem_reg);
	if (ret_val)
		goto out;

	oem_reg &= ~(HV_OEM_BITS_GBE_DIS | HV_OEM_BITS_LPLU);

	if (d0_state) {
		if (mac_reg & E1000_PHY_CTRL_GBE_DISABLE)
			oem_reg |= HV_OEM_BITS_GBE_DIS;

		if (mac_reg & E1000_PHY_CTRL_D0A_LPLU)
			oem_reg |= HV_OEM_BITS_LPLU;
	} else {
		if (mac_reg & E1000_PHY_CTRL_NOND0A_GBE_DISABLE)
			oem_reg |= HV_OEM_BITS_GBE_DIS;

		if (mac_reg & E1000_PHY_CTRL_NOND0A_LPLU)
			oem_reg |= HV_OEM_BITS_LPLU;
	}
	/* Restart auto-neg to activate the bits */
	if (!e1000_check_reset_block(hw))
		oem_reg |= HV_OEM_BITS_RESTART_AN;
	ret_val = hw->phy.ops.write_reg_locked(hw, HV_OEM_BITS, oem_reg);

out:
	hw->phy.ops.release(hw);

	return ret_val;
}


/**
 *  e1000_set_mdio_slow_mode_hv - Set slow MDIO access mode
 *  @hw:   pointer to the HW structure
 **/
static s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw)
{
	s32 ret_val;
	u16 data;

	ret_val = e1e_rphy(hw, HV_KMRN_MODE_CTRL, &data);
	if (ret_val)
		return ret_val;

	data |= HV_KMRN_MDIO_SLOW;

	ret_val = e1e_wphy(hw, HV_KMRN_MODE_CTRL, data);

	return ret_val;
}

/**
 *  e1000_hv_phy_workarounds_ich8lan - A series of Phy workarounds to be
 *  done after every PHY reset.
 **/
static s32 e1000_hv_phy_workarounds_ich8lan(struct e1000_hw *hw)
{
	s32 ret_val = 0;
	u16 phy_data;

	if (hw->mac.type != e1000_pchlan)
		return ret_val;

	/* Set MDIO slow mode before any other MDIO access */
	if (hw->phy.type == e1000_phy_82577) {
		ret_val = e1000_set_mdio_slow_mode_hv(hw);
		if (ret_val)
			goto out;
	}

	if (((hw->phy.type == e1000_phy_82577) &&
	     ((hw->phy.revision == 1) || (hw->phy.revision == 2))) ||
	    ((hw->phy.type == e1000_phy_82578) && (hw->phy.revision == 1))) {
		/* Disable generation of early preamble */
		ret_val = e1e_wphy(hw, PHY_REG(769, 25), 0x4431);
		if (ret_val)
			return ret_val;

		/* Preamble tuning for SSC */
		ret_val = e1e_wphy(hw, PHY_REG(770, 16), 0xA204);
		if (ret_val)
			return ret_val;
	}

	if (hw->phy.type == e1000_phy_82578) {
		/*
		 * Return registers to default by doing a soft reset then
		 * writing 0x3140 to the control register.
		 */
		if (hw->phy.revision < 2) {
			e1000e_phy_sw_reset(hw);
			ret_val = e1e_wphy(hw, PHY_CONTROL, 0x3140);
		}
	}

	/* Select page 0 */
	ret_val = hw->phy.ops.acquire(hw);
	if (ret_val)
		return ret_val;

	hw->phy.addr = 1;
	ret_val = e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, 0);
	hw->phy.ops.release(hw);
	if (ret_val)
		goto out;

	/*
	 * Configure the K1 Si workaround during phy reset assuming there is
	 * link so that it disables K1 if link is in 1Gbps.
	 */
	ret_val = e1000_k1_gig_workaround_hv(hw, true);
	if (ret_val)
		goto out;

	/* Workaround for link disconnects on a busy hub in half duplex */
	ret_val = hw->phy.ops.acquire(hw);
	if (ret_val)
		goto out;
	ret_val = hw->phy.ops.read_reg_locked(hw,
	                                      PHY_REG(BM_PORT_CTRL_PAGE, 17),
	                                      &phy_data);
	if (ret_val)
		goto release;
	ret_val = hw->phy.ops.write_reg_locked(hw,
	                                       PHY_REG(BM_PORT_CTRL_PAGE, 17),
	                                       phy_data & 0x00FF);
release:
	hw->phy.ops.release(hw);
out:
	return ret_val;
}

/**
 *  e1000_copy_rx_addrs_to_phy_ich8lan - Copy Rx addresses from MAC to PHY
 *  @hw:   pointer to the HW structure
 **/
void e1000_copy_rx_addrs_to_phy_ich8lan(struct e1000_hw *hw)
{
	u32 mac_reg;
	u16 i;

	/* Copy both RAL/H (rar_entry_count) and SHRAL/H (+4) to PHY */
	for (i = 0; i < (hw->mac.rar_entry_count + 4); i++) {
		mac_reg = er32(RAL(i));
		e1e_wphy(hw, BM_RAR_L(i), (u16)(mac_reg & 0xFFFF));
		e1e_wphy(hw, BM_RAR_M(i), (u16)((mac_reg >> 16) & 0xFFFF));
		mac_reg = er32(RAH(i));
		e1e_wphy(hw, BM_RAR_H(i), (u16)(mac_reg & 0xFFFF));
		e1e_wphy(hw, BM_RAR_CTRL(i), (u16)((mac_reg >> 16) & 0x8000));
	}
}

static u32 e1000_calc_rx_da_crc(u8 mac[])
{
	u32 poly = 0xEDB88320;	/* Polynomial for 802.3 CRC calculation */
	u32 i, j, mask, crc;

	crc = 0xffffffff;
	for (i = 0; i < 6; i++) {
		crc = crc ^ mac[i];
		for (j = 8; j > 0; j--) {
			mask = (crc & 1) * (-1);
			crc = (crc >> 1) ^ (poly & mask);
		}
	}
	return ~crc;
}

/**
 *  e1000_lv_jumbo_workaround_ich8lan - required for jumbo frame operation
 *  with 82579 PHY
 *  @hw: pointer to the HW structure
 *  @enable: flag to enable/disable workaround when enabling/disabling jumbos
 **/
s32 e1000_lv_jumbo_workaround_ich8lan(struct e1000_hw *hw, bool enable)
{
	s32 ret_val = 0;
	u16 phy_reg, data;
	u32 mac_reg;
	u16 i;

	if (hw->mac.type != e1000_pch2lan)
		goto out;

	/* disable Rx path while enabling/disabling workaround */
	e1e_rphy(hw, PHY_REG(769, 20), &phy_reg);
	ret_val = e1e_wphy(hw, PHY_REG(769, 20), phy_reg | (1 << 14));
	if (ret_val)
		goto out;

	if (enable) {
		/*
		 * Write Rx addresses (rar_entry_count for RAL/H, +4 for
		 * SHRAL/H) and initial CRC values to the MAC
		 */
		for (i = 0; i < (hw->mac.rar_entry_count + 4); i++) {
			u8 mac_addr[ETH_ALEN] = {0};
			u32 addr_high, addr_low;

			addr_high = er32(RAH(i));
			if (!(addr_high & E1000_RAH_AV))
				continue;
			addr_low = er32(RAL(i));
			mac_addr[0] = (addr_low & 0xFF);
			mac_addr[1] = ((addr_low >> 8) & 0xFF);
			mac_addr[2] = ((addr_low >> 16) & 0xFF);
			mac_addr[3] = ((addr_low >> 24) & 0xFF);
			mac_addr[4] = (addr_high & 0xFF);
			mac_addr[5] = ((addr_high >> 8) & 0xFF);

			ew32(PCH_RAICC(i),
					e1000_calc_rx_da_crc(mac_addr));
		}

		/* Write Rx addresses to the PHY */
		e1000_copy_rx_addrs_to_phy_ich8lan(hw);

		/* Enable jumbo frame workaround in the MAC */
		mac_reg = er32(FFLT_DBG);
		mac_reg &= ~(1 << 14);
		mac_reg |= (7 << 15);
		ew32(FFLT_DBG, mac_reg);

		mac_reg = er32(RCTL);
		mac_reg |= E1000_RCTL_SECRC;
		ew32(RCTL, mac_reg);

		ret_val = e1000e_read_kmrn_reg(hw,
						E1000_KMRNCTRLSTA_CTRL_OFFSET,
						&data);
		if (ret_val)
			goto out;
		ret_val = e1000e_write_kmrn_reg(hw,
						E1000_KMRNCTRLSTA_CTRL_OFFSET,
						data | (1 << 0));
		if (ret_val)
			goto out;
		ret_val = e1000e_read_kmrn_reg(hw,
						E1000_KMRNCTRLSTA_HD_CTRL,
						&data);
		if (ret_val)
			goto out;
		data &= ~(0xF << 8);
		data |= (0xB << 8);
		ret_val = e1000e_write_kmrn_reg(hw,
						E1000_KMRNCTRLSTA_HD_CTRL,
						data);
		if (ret_val)
			goto out;

		/* Enable jumbo frame workaround in the PHY */
		e1e_rphy(hw, PHY_REG(769, 23), &data);
		data &= ~(0x7F << 5);
		data |= (0x37 << 5);
		ret_val = e1e_wphy(hw, PHY_REG(769, 23), data);
		if (ret_val)
			goto out;
		e1e_rphy(hw, PHY_REG(769, 16), &data);
		data &= ~(1 << 13);
		ret_val = e1e_wphy(hw, PHY_REG(769, 16), data);
		if (ret_val)
			goto out;
		e1e_rphy(hw, PHY_REG(776, 20), &data);
		data &= ~(0x3FF << 2);
		data |= (0x1A << 2);
		ret_val = e1e_wphy(hw, PHY_REG(776, 20), data);
		if (ret_val)
			goto out;
		ret_val = e1e_wphy(hw, PHY_REG(776, 23), 0xFE00);
		if (ret_val)
			goto out;
		e1e_rphy(hw, HV_PM_CTRL, &data);
		ret_val = e1e_wphy(hw, HV_PM_CTRL, data | (1 << 10));
		if (ret_val)
			goto out;
	} else {
		/* Write MAC register values back to h/w defaults */
		mac_reg = er32(FFLT_DBG);
		mac_reg &= ~(0xF << 14);
		ew32(FFLT_DBG, mac_reg);

		mac_reg = er32(RCTL);
		mac_reg &= ~E1000_RCTL_SECRC;
		ew32(RCTL, mac_reg);

		ret_val = e1000e_read_kmrn_reg(hw,
						E1000_KMRNCTRLSTA_CTRL_OFFSET,
						&data);
		if (ret_val)
			goto out;
		ret_val = e1000e_write_kmrn_reg(hw,
						E1000_KMRNCTRLSTA_CTRL_OFFSET,
						data & ~(1 << 0));
		if (ret_val)
			goto out;
		ret_val = e1000e_read_kmrn_reg(hw,
						E1000_KMRNCTRLSTA_HD_CTRL,
						&data);
		if (ret_val)
			goto out;
		data &= ~(0xF << 8);
		data |= (0xB << 8);
		ret_val = e1000e_write_kmrn_reg(hw,
						E1000_KMRNCTRLSTA_HD_CTRL,
						data);
		if (ret_val)
			goto out;

		/* Write PHY register values back to h/w defaults */
		e1e_rphy(hw, PHY_REG(769, 23), &data);
		data &= ~(0x7F << 5);
		ret_val = e1e_wphy(hw, PHY_REG(769, 23), data);
		if (ret_val)
			goto out;
		e1e_rphy(hw, PHY_REG(769, 16), &data);
		data |= (1 << 13);
		ret_val = e1e_wphy(hw, PHY_REG(769, 16), data);
		if (ret_val)
			goto out;
		e1e_rphy(hw, PHY_REG(776, 20), &data);
		data &= ~(0x3FF << 2);
		data |= (0x8 << 2);
		ret_val = e1e_wphy(hw, PHY_REG(776, 20), data);
		if (ret_val)
			goto out;
		ret_val = e1e_wphy(hw, PHY_REG(776, 23), 0x7E00);
		if (ret_val)
			goto out;
		e1e_rphy(hw, HV_PM_CTRL, &data);
		ret_val = e1e_wphy(hw, HV_PM_CTRL, data & ~(1 << 10));
		if (ret_val)
			goto out;
	}

	/* re-enable Rx path after enabling/disabling workaround */
	ret_val = e1e_wphy(hw, PHY_REG(769, 20), phy_reg & ~(1 << 14));

out:
	return ret_val;
}

/**
 *  e1000_lv_phy_workarounds_ich8lan - A series of Phy workarounds to be
 *  done after every PHY reset.
 **/
static s32 e1000_lv_phy_workarounds_ich8lan(struct e1000_hw *hw)
{
	s32 ret_val = 0;

	if (hw->mac.type != e1000_pch2lan)
		goto out;

	/* Set MDIO slow mode before any other MDIO access */
	ret_val = e1000_set_mdio_slow_mode_hv(hw);

out:
	return ret_val;
}

/**
 *  e1000_k1_gig_workaround_lv - K1 Si workaround
 *  @hw:   pointer to the HW structure
 *
 *  Workaround to set the K1 beacon duration for 82579 parts
 **/
static s32 e1000_k1_workaround_lv(struct e1000_hw *hw)
{
	s32 ret_val = 0;
	u16 status_reg = 0;
	u32 mac_reg;

	if (hw->mac.type != e1000_pch2lan)
		goto out;

	/* Set K1 beacon duration based on 1Gbps speed or otherwise */
	ret_val = e1e_rphy(hw, HV_M_STATUS, &status_reg);
	if (ret_val)
		goto out;

	if ((status_reg & (HV_M_STATUS_LINK_UP | HV_M_STATUS_AUTONEG_COMPLETE))
	    == (HV_M_STATUS_LINK_UP | HV_M_STATUS_AUTONEG_COMPLETE)) {
		mac_reg = er32(FEXTNVM4);
		mac_reg &= ~E1000_FEXTNVM4_BEACON_DURATION_MASK;

		if (status_reg & HV_M_STATUS_SPEED_1000)
			mac_reg |= E1000_FEXTNVM4_BEACON_DURATION_8USEC;
		else
			mac_reg |= E1000_FEXTNVM4_BEACON_DURATION_16USEC;

		ew32(FEXTNVM4, mac_reg);
	}

out:
	return ret_val;
}

/**
 *  e1000_gate_hw_phy_config_ich8lan - disable PHY config via hardware
 *  @hw:   pointer to the HW structure
 *  @gate: boolean set to true to gate, false to ungate
 *
 *  Gate/ungate the automatic PHY configuration via hardware; perform
 *  the configuration via software instead.
 **/
static void e1000_gate_hw_phy_config_ich8lan(struct e1000_hw *hw, bool gate)
{
	u32 extcnf_ctrl;

	if (hw->mac.type != e1000_pch2lan)
		return;

	extcnf_ctrl = er32(EXTCNF_CTRL);

	if (gate)
		extcnf_ctrl |= E1000_EXTCNF_CTRL_GATE_PHY_CFG;
	else
		extcnf_ctrl &= ~E1000_EXTCNF_CTRL_GATE_PHY_CFG;

	ew32(EXTCNF_CTRL, extcnf_ctrl);
	return;
}

/**
 *  e1000_lan_init_done_ich8lan - Check for PHY config completion
 *  @hw: pointer to the HW structure
 *
 *  Check the appropriate indication the MAC has finished configuring the
 *  PHY after a software reset.
 **/
static void e1000_lan_init_done_ich8lan(struct e1000_hw *hw)
{
	u32 data, loop = E1000_ICH8_LAN_INIT_TIMEOUT;

	/* Wait for basic configuration completes before proceeding */
	do {
		data = er32(STATUS);
		data &= E1000_STATUS_LAN_INIT_DONE;
		udelay(100);
	} while ((!data) && --loop);

	/*
	 * If basic configuration is incomplete before the above loop
	 * count reaches 0, loading the configuration from NVM will
	 * leave the PHY in a bad state possibly resulting in no link.
	 */
	if (loop == 0)
		e_dbg("LAN_INIT_DONE not set, increase timeout\n");

	/* Clear the Init Done bit for the next init event */
	data = er32(STATUS);
	data &= ~E1000_STATUS_LAN_INIT_DONE;
	ew32(STATUS, data);
}

/**
 *  e1000_post_phy_reset_ich8lan - Perform steps required after a PHY reset
 *  @hw: pointer to the HW structure
 **/
static s32 e1000_post_phy_reset_ich8lan(struct e1000_hw *hw)
{
	s32 ret_val = 0;
	u16 reg;

	if (e1000_check_reset_block(hw))
		goto out;

	/* Allow time for h/w to get to quiescent state after reset */
	msleep(10);

	/* Perform any necessary post-reset workarounds */
	switch (hw->mac.type) {
	case e1000_pchlan:
		ret_val = e1000_hv_phy_workarounds_ich8lan(hw);
		if (ret_val)
			goto out;
		break;
	case e1000_pch2lan:
		ret_val = e1000_lv_phy_workarounds_ich8lan(hw);
		if (ret_val)
			goto out;
		break;
	default:
		break;
	}

	/* Dummy read to clear the phy wakeup bit after lcd reset */
	if (hw->mac.type >= e1000_pchlan)
		e1e_rphy(hw, BM_WUC, &reg);

	/* Configure the LCD with the extended configuration region in NVM */
	ret_val = e1000_sw_lcd_config_ich8lan(hw);
	if (ret_val)
		goto out;

	/* Configure the LCD with the OEM bits in NVM */
	ret_val = e1000_oem_bits_config_ich8lan(hw, true);

	/* Ungate automatic PHY configuration on non-managed 82579 */
	if ((hw->mac.type == e1000_pch2lan) &&
	    !(er32(FWSM) & E1000_ICH_FWSM_FW_VALID)) {
		msleep(10);
		e1000_gate_hw_phy_config_ich8lan(hw, false);
	}

out:
	return ret_val;
}

/**
 *  e1000_phy_hw_reset_ich8lan - Performs a PHY reset
 *  @hw: pointer to the HW structure
 *
 *  Resets the PHY
 *  This is a function pointer entry point called by drivers
 *  or other shared routines.
 **/
static s32 e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw)
{
	s32 ret_val = 0;

	/* Gate automatic PHY configuration by hardware on non-managed 82579 */
	if ((hw->mac.type == e1000_pch2lan) &&
	    !(er32(FWSM) & E1000_ICH_FWSM_FW_VALID))
		e1000_gate_hw_phy_config_ich8lan(hw, true);

	ret_val = e1000e_phy_hw_reset_generic(hw);
	if (ret_val)
		goto out;

	ret_val = e1000_post_phy_reset_ich8lan(hw);

out:
	return ret_val;
}

/**
 *  e1000_set_lplu_state_pchlan - Set Low Power Link Up state
 *  @hw: pointer to the HW structure
 *  @active: true to enable LPLU, false to disable
 *
 *  Sets the LPLU state according to the active flag.  For PCH, if OEM write
 *  bit are disabled in the NVM, writing the LPLU bits in the MAC will not set
 *  the phy speed. This function will manually set the LPLU bit and restart
 *  auto-neg as hw would do. D3 and D0 LPLU will call the same function
 *  since it configures the same bit.
 **/
static s32 e1000_set_lplu_state_pchlan(struct e1000_hw *hw, bool active)
{
	s32 ret_val = 0;
	u16 oem_reg;

	ret_val = e1e_rphy(hw, HV_OEM_BITS, &oem_reg);
	if (ret_val)
		goto out;

	if (active)
		oem_reg |= HV_OEM_BITS_LPLU;
	else
		oem_reg &= ~HV_OEM_BITS_LPLU;

	oem_reg |= HV_OEM_BITS_RESTART_AN;
	ret_val = e1e_wphy(hw, HV_OEM_BITS, oem_reg);

out:
	return ret_val;
}

/**
 *  e1000_set_d0_lplu_state_ich8lan - Set Low Power Linkup D0 state
 *  @hw: pointer to the HW structure
 *  @active: true to enable LPLU, false to disable
 *
 *  Sets the LPLU D0 state according to the active flag.  When
 *  activating LPLU this function also disables smart speed
 *  and vice versa.  LPLU will not be activated unless the
 *  device autonegotiation advertisement meets standards of
 *  either 10 or 10/100 or 10/100/1000 at all duplexes.
 *  This is a function pointer entry point only called by
 *  PHY setup routines.
 **/
static s32 e1000_set_d0_lplu_state_ich8lan(struct e1000_hw *hw, bool active)
{
	struct e1000_phy_info *phy = &hw->phy;
	u32 phy_ctrl;
	s32 ret_val = 0;
	u16 data;

	if (phy->type == e1000_phy_ife)
		return ret_val;

	phy_ctrl = er32(PHY_CTRL);

	if (active) {
		phy_ctrl |= E1000_PHY_CTRL_D0A_LPLU;
		ew32(PHY_CTRL, phy_ctrl);

		if (phy->type != e1000_phy_igp_3)
			return 0;

		/*
		 * Call gig speed drop workaround on LPLU before accessing
		 * any PHY registers
		 */
		if (hw->mac.type == e1000_ich8lan)
			e1000e_gig_downshift_workaround_ich8lan(hw);

		/* When LPLU is enabled, we should disable SmartSpeed */
		ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CONFIG, &data);
		data &= ~IGP01E1000_PSCFR_SMART_SPEED;
		ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG, data);
		if (ret_val)
			return ret_val;
	} else {
		phy_ctrl &= ~E1000_PHY_CTRL_D0A_LPLU;
		ew32(PHY_CTRL, phy_ctrl);

		if (phy->type != e1000_phy_igp_3)
			return 0;

		/*
		 * LPLU and SmartSpeed are mutually exclusive.  LPLU is used
		 * during Dx states where the power conservation is most
		 * important.  During driver activity we should enable
		 * SmartSpeed, so performance is maintained.
		 */
		if (phy->smart_speed == e1000_smart_speed_on) {
			ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CONFIG,
					   &data);
			if (ret_val)
				return ret_val;

			data |= IGP01E1000_PSCFR_SMART_SPEED;
			ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG,
					   data);
			if (ret_val)
				return ret_val;
		} else if (phy->smart_speed == e1000_smart_speed_off) {
			ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CONFIG,
					   &data);
			if (ret_val)
				return ret_val;

			data &= ~IGP01E1000_PSCFR_SMART_SPEED;
			ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG,
					   data);
			if (ret_val)
				return ret_val;
		}
	}

	return 0;
}

/**
 *  e1000_set_d3_lplu_state_ich8lan - Set Low Power Linkup D3 state
 *  @hw: pointer to the HW structure
 *  @active: true to enable LPLU, false to disable
 *
 *  Sets the LPLU D3 state according to the active flag.  When
 *  activating LPLU this function also disables smart speed
 *  and vice versa.  LPLU will not be activated unless the
 *  device autonegotiation advertisement meets standards of
 *  either 10 or 10/100 or 10/100/1000 at all duplexes.
 *  This is a function pointer entry point only called by
 *  PHY setup routines.
 **/
static s32 e1000_set_d3_lplu_state_ich8lan(struct e1000_hw *hw, bool active)
{
	struct e1000_phy_info *phy = &hw->phy;
	u32 phy_ctrl;
	s32 ret_val;
	u16 data;

	phy_ctrl = er32(PHY_CTRL);

	if (!active) {
		phy_ctrl &= ~E1000_PHY_CTRL_NOND0A_LPLU;
		ew32(PHY_CTRL, phy_ctrl);

		if (phy->type != e1000_phy_igp_3)
			return 0;

		/*
		 * LPLU and SmartSpeed are mutually exclusive.  LPLU is used
		 * during Dx states where the power conservation is most
		 * important.  During driver activity we should enable
		 * SmartSpeed, so performance is maintained.
		 */
		if (phy->smart_speed == e1000_smart_speed_on) {
			ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CONFIG,
					   &data);
			if (ret_val)
				return ret_val;

			data |= IGP01E1000_PSCFR_SMART_SPEED;
			ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG,
					   data);
			if (ret_val)
				return ret_val;
		} else if (phy->smart_speed == e1000_smart_speed_off) {
			ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CONFIG,
					   &data);
			if (ret_val)
				return ret_val;

			data &= ~IGP01E1000_PSCFR_SMART_SPEED;
			ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG,
					   data);
			if (ret_val)
				return ret_val;
		}
	} else if ((phy->autoneg_advertised == E1000_ALL_SPEED_DUPLEX) ||
		   (phy->autoneg_advertised == E1000_ALL_NOT_GIG) ||
		   (phy->autoneg_advertised == E1000_ALL_10_SPEED)) {
		phy_ctrl |= E1000_PHY_CTRL_NOND0A_LPLU;
		ew32(PHY_CTRL, phy_ctrl);

		if (phy->type != e1000_phy_igp_3)
			return 0;

		/*
		 * Call gig speed drop workaround on LPLU before accessing
		 * any PHY registers
		 */
		if (hw->mac.type == e1000_ich8lan)
			e1000e_gig_downshift_workaround_ich8lan(hw);

		/* When LPLU is enabled, we should disable SmartSpeed */
		ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CONFIG, &data);
		if (ret_val)
			return ret_val;

		data &= ~IGP01E1000_PSCFR_SMART_SPEED;
		ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG, data);
	}

	return 0;
}

/**
 *  e1000_valid_nvm_bank_detect_ich8lan - finds out the valid bank 0 or 1
 *  @hw: pointer to the HW structure
 *  @bank:  pointer to the variable that returns the active bank
 *
 *  Reads signature byte from the NVM using the flash access registers.
 *  Word 0x13 bits 15:14 = 10b indicate a valid signature for that bank.
 **/
static s32 e1000_valid_nvm_bank_detect_ich8lan(struct e1000_hw *hw, u32 *bank)
{
	u32 eecd;
	struct e1000_nvm_info *nvm = &hw->nvm;
	u32 bank1_offset = nvm->flash_bank_size * sizeof(u16);
	u32 act_offset = E1000_ICH_NVM_SIG_WORD * 2 + 1;
	u8 sig_byte = 0;
	s32 ret_val = 0;

	switch (hw->mac.type) {
	case e1000_ich8lan:
	case e1000_ich9lan:
		eecd = er32(EECD);
		if ((eecd & E1000_EECD_SEC1VAL_VALID_MASK) ==
		    E1000_EECD_SEC1VAL_VALID_MASK) {
			if (eecd & E1000_EECD_SEC1VAL)
				*bank = 1;
			else
				*bank = 0;

			return 0;
		}
		e_dbg("Unable to determine valid NVM bank via EEC - "
		       "reading flash signature\n");
		/* fall-thru */
	default:
		/* set bank to 0 in case flash read fails */
		*bank = 0;

		/* Check bank 0 */
		ret_val = e1000_read_flash_byte_ich8lan(hw, act_offset,
		                                        &sig_byte);
		if (ret_val)
			return ret_val;
		if ((sig_byte & E1000_ICH_NVM_VALID_SIG_MASK) ==
		    E1000_ICH_NVM_SIG_VALUE) {
			*bank = 0;
			return 0;
		}

		/* Check bank 1 */
		ret_val = e1000_read_flash_byte_ich8lan(hw, act_offset +
		                                        bank1_offset,
		                                        &sig_byte);
		if (ret_val)
			return ret_val;
		if ((sig_byte & E1000_ICH_NVM_VALID_SIG_MASK) ==
		    E1000_ICH_NVM_SIG_VALUE) {
			*bank = 1;
			return 0;
		}

		e_dbg("ERROR: No valid NVM bank present\n");
		return -E1000_ERR_NVM;
	}

	return 0;
}

/**
 *  e1000_read_nvm_ich8lan - Read word(s) from the NVM
 *  @hw: pointer to the HW structure
 *  @offset: The offset (in bytes) of the word(s) to read.
 *  @words: Size of data to read in words
 *  @data: Pointer to the word(s) to read at offset.
 *
 *  Reads a word(s) from the NVM using the flash access registers.
 **/
static s32 e1000_read_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words,
				  u16 *data)
{
	struct e1000_nvm_info *nvm = &hw->nvm;
	struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan;
	u32 act_offset;
	s32 ret_val = 0;
	u32 bank = 0;
	u16 i, word;

	if ((offset >= nvm->word_size) || (words > nvm->word_size - offset) ||
	    (words == 0)) {
		e_dbg("nvm parameter(s) out of bounds\n");
		ret_val = -E1000_ERR_NVM;
		goto out;
	}

	nvm->ops.acquire(hw);

	ret_val = e1000_valid_nvm_bank_detect_ich8lan(hw, &bank);
	if (ret_val) {
		e_dbg("Could not detect valid bank, assuming bank 0\n");
		bank = 0;
	}

	act_offset = (bank) ? nvm->flash_bank_size : 0;
	act_offset += offset;

	ret_val = 0;
	for (i = 0; i < words; i++) {
		if ((dev_spec->shadow_ram) &&
		    (dev_spec->shadow_ram[offset+i].modified)) {
			data[i] = dev_spec->shadow_ram[offset+i].value;
		} else {
			ret_val = e1000_read_flash_word_ich8lan(hw,
								act_offset + i,
								&word);
			if (ret_val)
				break;
			data[i] = word;
		}
	}

	nvm->ops.release(hw);

out:
	if (ret_val)
		e_dbg("NVM read error: %d\n", ret_val);

	return ret_val;
}

/**
 *  e1000_flash_cycle_init_ich8lan - Initialize flash
 *  @hw: pointer to the HW structure
 *
 *  This function does initial flash setup so that a new read/write/erase cycle
 *  can be started.
 **/
static s32 e1000_flash_cycle_init_ich8lan(struct e1000_hw *hw)
{
	union ich8_hws_flash_status hsfsts;
	s32 ret_val = -E1000_ERR_NVM;
	s32 i = 0;

	hsfsts.regval = er16flash(ICH_FLASH_HSFSTS);

	/* Check if the flash descriptor is valid */
	if (hsfsts.hsf_status.fldesvalid == 0) {
		e_dbg("Flash descriptor invalid.  "
			 "SW Sequencing must be used.\n");
		return -E1000_ERR_NVM;
	}

	/* Clear FCERR and DAEL in hw status by writing 1 */
	hsfsts.hsf_status.flcerr = 1;
	hsfsts.hsf_status.dael = 1;

	ew16flash(ICH_FLASH_HSFSTS, hsfsts.regval);

	/*
	 * Either we should have a hardware SPI cycle in progress
	 * bit to check against, in order to start a new cycle or
	 * FDONE bit should be changed in the hardware so that it
	 * is 1 after hardware reset, which can then be used as an
	 * indication whether a cycle is in progress or has been
	 * completed.
	 */

	if (hsfsts.hsf_status.flcinprog == 0) {
		/*
		 * There is no cycle running at present,
		 * so we can start a cycle.
		 * Begin by setting Flash Cycle Done.
		 */
		hsfsts.hsf_status.flcdone = 1;
		ew16flash(ICH_FLASH_HSFSTS, hsfsts.regval);
		ret_val = 0;
	} else {
		/*
		 * Otherwise poll for sometime so the current
		 * cycle has a chance to end before giving up.
		 */
		for (i = 0; i < ICH_FLASH_READ_COMMAND_TIMEOUT; i++) {
			hsfsts.regval = __er16flash(hw, ICH_FLASH_HSFSTS);
			if (hsfsts.hsf_status.flcinprog == 0) {
				ret_val = 0;
				break;
			}
			udelay(1);
		}
		if (ret_val == 0) {
			/*
			 * Successful in waiting for previous cycle to timeout,
			 * now set the Flash Cycle Done.
			 */
			hsfsts.hsf_status.flcdone = 1;
			ew16flash(ICH_FLASH_HSFSTS, hsfsts.regval);
		} else {
			e_dbg("Flash controller busy, cannot get access\n");
		}
	}

	return ret_val;
}

/**
 *  e1000_flash_cycle_ich8lan - Starts flash cycle (read/write/erase)
 *  @hw: pointer to the HW structure
 *  @timeout: maximum time to wait for completion
 *
 *  This function starts a flash cycle and waits for its completion.
 **/
static s32 e1000_flash_cycle_ich8lan(struct e1000_hw *hw, u32 timeout)
{
	union ich8_hws_flash_ctrl hsflctl;
	union ich8_hws_flash_status hsfsts;
	s32 ret_val = -E1000_ERR_NVM;
	u32 i = 0;

	/* Start a cycle by writing 1 in Flash Cycle Go in Hw Flash Control */
	hsflctl.regval = er16flash(ICH_FLASH_HSFCTL);
	hsflctl.hsf_ctrl.flcgo = 1;
	ew16flash(ICH_FLASH_HSFCTL, hsflctl.regval);

	/* wait till FDONE bit is set to 1 */
	do {
		hsfsts.regval = er16flash(ICH_FLASH_HSFSTS);
		if (hsfsts.hsf_status.flcdone == 1)
			break;
		udelay(1);
	} while (i++ < timeout);

	if (hsfsts.hsf_status.flcdone == 1 && hsfsts.hsf_status.flcerr == 0)
		return 0;

	return ret_val;
}

/**
 *  e1000_read_flash_word_ich8lan - Read word from flash
 *  @hw: pointer to the HW structure
 *  @offset: offset to data location
 *  @data: pointer to the location for storing the data
 *
 *  Reads the flash word at offset into data.  Offset is converted
 *  to bytes before read.
 **/
static s32 e1000_read_flash_word_ich8lan(struct e1000_hw *hw, u32 offset,
					 u16 *data)
{
	/* Must convert offset into bytes. */
	offset <<= 1;

	return e1000_read_flash_data_ich8lan(hw, offset, 2, data);
}

/**
 *  e1000_read_flash_byte_ich8lan - Read byte from flash
 *  @hw: pointer to the HW structure
 *  @offset: The offset of the byte to read.
 *  @data: Pointer to a byte to store the value read.
 *
 *  Reads a single byte from the NVM using the flash access registers.
 **/
static s32 e1000_read_flash_byte_ich8lan(struct e1000_hw *hw, u32 offset,
					 u8 *data)
{
	s32 ret_val;
	u16 word = 0;

	ret_val = e1000_read_flash_data_ich8lan(hw, offset, 1, &word);
	if (ret_val)
		return ret_val;

	*data = (u8)word;

	return 0;
}

/**
 *  e1000_read_flash_data_ich8lan - Read byte or word from NVM
 *  @hw: pointer to the HW structure
 *  @offset: The offset (in bytes) of the byte or word to read.
 *  @size: Size of data to read, 1=byte 2=word
 *  @data: Pointer to the word to store the value read.
 *
 *  Reads a byte or word from the NVM using the flash access registers.
 **/
static s32 e1000_read_flash_data_ich8lan(struct e1000_hw *hw, u32 offset,
					 u8 size, u16 *data)
{
	union ich8_hws_flash_status hsfsts;
	union ich8_hws_flash_ctrl hsflctl;
	u32 flash_linear_addr;
	u32 flash_data = 0;
	s32 ret_val = -E1000_ERR_NVM;
	u8 count = 0;

	if (size < 1  || size > 2 || offset > ICH_FLASH_LINEAR_ADDR_MASK)
		return -E1000_ERR_NVM;

	flash_linear_addr = (ICH_FLASH_LINEAR_ADDR_MASK & offset) +
			    hw->nvm.flash_base_addr;

	do {
		udelay(1);
		/* Steps */
		ret_val = e1000_flash_cycle_init_ich8lan(hw);
		if (ret_val != 0)
			break;

		hsflctl.regval = er16flash(ICH_FLASH_HSFCTL);
		/* 0b/1b corresponds to 1 or 2 byte size, respectively. */
		hsflctl.hsf_ctrl.fldbcount = size - 1;
		hsflctl.hsf_ctrl.flcycle = ICH_CYCLE_READ;
		ew16flash(ICH_FLASH_HSFCTL, hsflctl.regval);

		ew32flash(ICH_FLASH_FADDR, flash_linear_addr);

		ret_val = e1000_flash_cycle_ich8lan(hw,
						ICH_FLASH_READ_COMMAND_TIMEOUT);

		/*
		 * Check if FCERR is set to 1, if set to 1, clear it
		 * and try the whole sequence a few more times, else
		 * read in (shift in) the Flash Data0, the order is
		 * least significant byte first msb to lsb
		 */
		if (ret_val == 0) {
			flash_data = er32flash(ICH_FLASH_FDATA0);
			if (size == 1) {
				*data = (u8)(flash_data & 0x000000FF);
			} else if (size == 2) {
				*data = (u16)(flash_data & 0x0000FFFF);
			}
			break;
		} else {
			/*
			 * If we've gotten here, then things are probably
			 * completely hosed, but if the error condition is
			 * detected, it won't hurt to give it another try...
			 * ICH_FLASH_CYCLE_REPEAT_COUNT times.
			 */
			hsfsts.regval = er16flash(ICH_FLASH_HSFSTS);
			if (hsfsts.hsf_status.flcerr == 1) {
				/* Repeat for some time before giving up. */
				continue;
			} else if (hsfsts.hsf_status.flcdone == 0) {
				e_dbg("Timeout error - flash cycle "
					 "did not complete.\n");
				break;
			}
		}
	} while (count++ < ICH_FLASH_CYCLE_REPEAT_COUNT);

	return ret_val;
}

/**
 *  e1000_write_nvm_ich8lan - Write word(s) to the NVM
 *  @hw: pointer to the HW structure
 *  @offset: The offset (in bytes) of the word(s) to write.
 *  @words: Size of data to write in words
 *  @data: Pointer to the word(s) to write at offset.
 *
 *  Writes a byte or word to the NVM using the flash access registers.
 **/
static s32 e1000_write_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words,
				   u16 *data)
{
	struct e1000_nvm_info *nvm = &hw->nvm;
	struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan;
	u16 i;

	if ((offset >= nvm->word_size) || (words > nvm->word_size - offset) ||
	    (words == 0)) {
		e_dbg("nvm parameter(s) out of bounds\n");
		return -E1000_ERR_NVM;
	}

	nvm->ops.acquire(hw);

	for (i = 0; i < words; i++) {
		dev_spec->shadow_ram[offset+i].modified = true;
		dev_spec->shadow_ram[offset+i].value = data[i];
	}

	nvm->ops.release(hw);

	return 0;
}

/**
 *  e1000_update_nvm_checksum_ich8lan - Update the checksum for NVM
 *  @hw: pointer to the HW structure
 *
 *  The NVM checksum is updated by calling the generic update_nvm_checksum,
 *  which writes the checksum to the shadow ram.  The changes in the shadow
 *  ram are then committed to the EEPROM by processing each bank at a time
 *  checking for the modified bit and writing only the pending changes.
 *  After a successful commit, the shadow ram is cleared and is ready for
 *  future writes.
 **/
static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw)
{
	struct e1000_nvm_info *nvm = &hw->nvm;
	struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan;
	u32 i, act_offset, new_bank_offset, old_bank_offset, bank;
	s32 ret_val;
	u16 data;

	ret_val = e1000e_update_nvm_checksum_generic(hw);
	if (ret_val)
		goto out;

	if (nvm->type != e1000_nvm_flash_sw)
		goto out;

	nvm->ops.acquire(hw);

	/*
	 * We're writing to the opposite bank so if we're on bank 1,
	 * write to bank 0 etc.  We also need to erase the segment that
	 * is going to be written
	 */
	ret_val =  e1000_valid_nvm_bank_detect_ich8lan(hw, &bank);
	if (ret_val) {
		e_dbg("Could not detect valid bank, assuming bank 0\n");
		bank = 0;
	}

	if (bank == 0) {
		new_bank_offset = nvm->flash_bank_size;
		old_bank_offset = 0;
		ret_val = e1000_erase_flash_bank_ich8lan(hw, 1);
		if (ret_val)
			goto release;
	} else {
		old_bank_offset = nvm->flash_bank_size;
		new_bank_offset = 0;
		ret_val = e1000_erase_flash_bank_ich8lan(hw, 0);
		if (ret_val)
			goto release;
	}

	for (i = 0; i < E1000_ICH8_SHADOW_RAM_WORDS; i++) {
		/*
		 * Determine whether to write the value stored
		 * in the other NVM bank or a modified value stored
		 * in the shadow RAM
		 */
		if (dev_spec->shadow_ram[i].modified) {
			data = dev_spec->shadow_ram[i].value;
		} else {
			ret_val = e1000_read_flash_word_ich8lan(hw, i +
			                                        old_bank_offset,
			                                        &data);
			if (ret_val)
				break;
		}

		/*
		 * If the word is 0x13, then make sure the signature bits
		 * (15:14) are 11b until the commit has completed.
		 * This will allow us to write 10b which indicates the
		 * signature is valid.  We want to do this after the write
		 * has completed so that we don't mark the segment valid
		 * while the write is still in progress
		 */
		if (i == E1000_ICH_NVM_SIG_WORD)
			data |= E1000_ICH_NVM_SIG_MASK;

		/* Convert offset to bytes. */
		act_offset = (i + new_bank_offset) << 1;

		udelay(100);
		/* Write the bytes to the new bank. */
		ret_val = e1000_retry_write_flash_byte_ich8lan(hw,
							       act_offset,
							       (u8)data);
		if (ret_val)
			break;

		udelay(100);
		ret_val = e1000_retry_write_flash_byte_ich8lan(hw,
							  act_offset + 1,
							  (u8)(data >> 8));
		if (ret_val)
			break;
	}

	/*
	 * Don't bother writing the segment valid bits if sector
	 * programming failed.
	 */
	if (ret_val) {
		/* Possibly read-only, see e1000e_write_protect_nvm_ich8lan() */
		e_dbg("Flash commit failed.\n");
		goto release;
	}

	/*
	 * Finally validate the new segment by setting bit 15:14
	 * to 10b in word 0x13 , this can be done without an
	 * erase as well since these bits are 11 to start with
	 * and we need to change bit 14 to 0b
	 */
	act_offset = new_bank_offset + E1000_ICH_NVM_SIG_WORD;
	ret_val = e1000_read_flash_word_ich8lan(hw, act_offset, &data);
	if (ret_val)
		goto release;

	data &= 0xBFFF;
	ret_val = e1000_retry_write_flash_byte_ich8lan(hw,
						       act_offset * 2 + 1,
						       (u8)(data >> 8));
	if (ret_val)
		goto release;

	/*
	 * And invalidate the previously valid segment by setting
	 * its signature word (0x13) high_byte to 0b. This can be
	 * done without an erase because flash erase sets all bits
	 * to 1's. We can write 1's to 0's without an erase
	 */
	act_offset = (old_bank_offset + E1000_ICH_NVM_SIG_WORD) * 2 + 1;
	ret_val = e1000_retry_write_flash_byte_ich8lan(hw, act_offset, 0);
	if (ret_val)
		goto release;

	/* Great!  Everything worked, we can now clear the cached entries. */
	for (i = 0; i < E1000_ICH8_SHADOW_RAM_WORDS; i++) {
		dev_spec->shadow_ram[i].modified = false;
		dev_spec->shadow_ram[i].value = 0xFFFF;
	}

release:
	nvm->ops.release(hw);

	/*
	 * Reload the EEPROM, or else modifications will not appear
	 * until after the next adapter reset.
	 */
	if (!ret_val) {
		e1000e_reload_nvm(hw);
		msleep(10);
	}

out:
	if (ret_val)
		e_dbg("NVM update error: %d\n", ret_val);

	return ret_val;
}

/**
 *  e1000_validate_nvm_checksum_ich8lan - Validate EEPROM checksum
 *  @hw: pointer to the HW structure
 *
 *  Check to see if checksum needs to be fixed by reading bit 6 in word 0x19.
 *  If the bit is 0, that the EEPROM had been modified, but the checksum was not
 *  calculated, in which case we need to calculate the checksum and set bit 6.
 **/
static s32 e1000_validate_nvm_checksum_ich8lan(struct e1000_hw *hw)
{
	s32 ret_val;
	u16 data;

	/*
	 * Read 0x19 and check bit 6.  If this bit is 0, the checksum
	 * needs to be fixed.  This bit is an indication that the NVM
	 * was prepared by OEM software and did not calculate the
	 * checksum...a likely scenario.
	 */
	ret_val = e1000_read_nvm(hw, 0x19, 1, &data);
	if (ret_val)
		return ret_val;

	if ((data & 0x40) == 0) {
		data |= 0x40;
		ret_val = e1000_write_nvm(hw, 0x19, 1, &data);
		if (ret_val)
			return ret_val;
		ret_val = e1000e_update_nvm_checksum(hw);
		if (ret_val)
			return ret_val;
	}

	return e1000e_validate_nvm_checksum_generic(hw);
}

/**
 *  e1000e_write_protect_nvm_ich8lan - Make the NVM read-only
 *  @hw: pointer to the HW structure
 *
 *  To prevent malicious write/erase of the NVM, set it to be read-only
 *  so that the hardware ignores all write/erase cycles of the NVM via
 *  the flash control registers.  The shadow-ram copy of the NVM will
 *  still be updated, however any updates to this copy will not stick
 *  across driver reloads.
 **/
void e1000e_write_protect_nvm_ich8lan(struct e1000_hw *hw)
{
	struct e1000_nvm_info *nvm = &hw->nvm;
	union ich8_flash_protected_range pr0;
	union ich8_hws_flash_status hsfsts;
	u32 gfpreg;

	nvm->ops.acquire(hw);

	gfpreg = er32flash(ICH_FLASH_GFPREG);

	/* Write-protect GbE Sector of NVM */
	pr0.regval = er32flash(ICH_FLASH_PR0);
	pr0.range.base = gfpreg & FLASH_GFPREG_BASE_MASK;
	pr0.range.limit = ((gfpreg >> 16) & FLASH_GFPREG_BASE_MASK);
	pr0.range.wpe = true;
	ew32flash(ICH_FLASH_PR0, pr0.regval);

	/*
	 * Lock down a subset of GbE Flash Control Registers, e.g.
	 * PR0 to prevent the write-protection from being lifted.
	 * Once FLOCKDN is set, the registers protected by it cannot
	 * be written until FLOCKDN is cleared by a hardware reset.
	 */
	hsfsts.regval = er16flash(ICH_FLASH_HSFSTS);
	hsfsts.hsf_status.flockdn = true;
	ew32flash(ICH_FLASH_HSFSTS, hsfsts.regval);

	nvm->ops.release(hw);
}

/**
 *  e1000_write_flash_data_ich8lan - Writes bytes to the NVM
 *  @hw: pointer to the HW structure
 *  @offset: The offset (in bytes) of the byte/word to read.
 *  @size: Size of data to read, 1=byte 2=word
 *  @data: The byte(s) to write to the NVM.
 *
 *  Writes one/two bytes to the NVM using the flash access registers.
 **/
static s32 e1000_write_flash_data_ich8lan(struct e1000_hw *hw, u32 offset,
					  u8 size, u16 data)
{
	union ich8_hws_flash_status hsfsts;
	union ich8_hws_flash_ctrl hsflctl;
	u32 flash_linear_addr;
	u32 flash_data = 0;
	s32 ret_val;
	u8 count = 0;

	if (size < 1 || size > 2 || data > size * 0xff ||
	    offset > ICH_FLASH_LINEAR_ADDR_MASK)
		return -E1000_ERR_NVM;

	flash_linear_addr = (ICH_FLASH_LINEAR_ADDR_MASK & offset) +
			    hw->nvm.flash_base_addr;

	do {
		udelay(1);
		/* Steps */
		ret_val = e1000_flash_cycle_init_ich8lan(hw);
		if (ret_val)
			break;

		hsflctl.regval = er16flash(ICH_FLASH_HSFCTL);
		/* 0b/1b corresponds to 1 or 2 byte size, respectively. */
		hsflctl.hsf_ctrl.fldbcount = size -1;
		hsflctl.hsf_ctrl.flcycle = ICH_CYCLE_WRITE;
		ew16flash(ICH_FLASH_HSFCTL, hsflctl.regval);

		ew32flash(ICH_FLASH_FADDR, flash_linear_addr);

		if (size == 1)
			flash_data = (u32)data & 0x00FF;
		else
			flash_data = (u32)data;

		ew32flash(ICH_FLASH_FDATA0, flash_data);

		/*
		 * check if FCERR is set to 1 , if set to 1, clear it
		 * and try the whole sequence a few more times else done
		 */
		ret_val = e1000_flash_cycle_ich8lan(hw,
					       ICH_FLASH_WRITE_COMMAND_TIMEOUT);
		if (!ret_val)
			break;

		/*
		 * If we're here, then things are most likely
		 * completely hosed, but if the error condition
		 * is detected, it won't hurt to give it another
		 * try...ICH_FLASH_CYCLE_REPEAT_COUNT times.
		 */
		hsfsts.regval = er16flash(ICH_FLASH_HSFSTS);
		if (hsfsts.hsf_status.flcerr == 1)
			/* Repeat for some time before giving up. */
			continue;
		if (hsfsts.hsf_status.flcdone == 0) {
			e_dbg("Timeout error - flash cycle "
				 "did not complete.");
			break;
		}
	} while (count++ < ICH_FLASH_CYCLE_REPEAT_COUNT);

	return ret_val;
}

/**
 *  e1000_write_flash_byte_ich8lan - Write a single byte to NVM
 *  @hw: pointer to the HW structure
 *  @offset: The index of the byte to read.
 *  @data: The byte to write to the NVM.
 *
 *  Writes a single byte to the NVM using the flash access registers.
 **/
static s32 e1000_write_flash_byte_ich8lan(struct e1000_hw *hw, u32 offset,
					  u8 data)
{
	u16 word = (u16)data;

	return e1000_write_flash_data_ich8lan(hw, offset, 1, word);
}

/**
 *  e1000_retry_write_flash_byte_ich8lan - Writes a single byte to NVM
 *  @hw: pointer to the HW structure
 *  @offset: The offset of the byte to write.
 *  @byte: The byte to write to the NVM.
 *
 *  Writes a single byte to the NVM using the flash access registers.
 *  Goes through a retry algorithm before giving up.
 **/
static s32 e1000_retry_write_flash_byte_ich8lan(struct e1000_hw *hw,
						u32 offset, u8 byte)
{
	s32 ret_val;
	u16 program_retries;

	ret_val = e1000_write_flash_byte_ich8lan(hw, offset, byte);
	if (!ret_val)
		return ret_val;

	for (program_retries = 0; program_retries < 100; program_retries++) {
		e_dbg("Retrying Byte %2.2X at offset %u\n", byte, offset);
		udelay(100);
		ret_val = e1000_write_flash_byte_ich8lan(hw, offset, byte);
		if (!ret_val)
			break;
	}
	if (program_retries == 100)
		return -E1000_ERR_NVM;

	return 0;
}

/**
 *  e1000_erase_flash_bank_ich8lan - Erase a bank (4k) from NVM
 *  @hw: pointer to the HW structure
 *  @bank: 0 for first bank, 1 for second bank, etc.
 *
 *  Erases the bank specified. Each bank is a 4k block. Banks are 0 based.
 *  bank N is 4096 * N + flash_reg_addr.
 **/
static s32 e1000_erase_flash_bank_ich8lan(struct e1000_hw *hw, u32 bank)
{
	struct e1000_nvm_info *nvm = &hw->nvm;
	union ich8_hws_flash_status hsfsts;
	union ich8_hws_flash_ctrl hsflctl;
	u32 flash_linear_addr;
	/* bank size is in 16bit words - adjust to bytes */
	u32 flash_bank_size = nvm->flash_bank_size * 2;
	s32 ret_val;
	s32 count = 0;
	s32 j, iteration, sector_size;

	hsfsts.regval = er16flash(ICH_FLASH_HSFSTS);

	/*
	 * Determine HW Sector size: Read BERASE bits of hw flash status
	 * register
	 * 00: The Hw sector is 256 bytes, hence we need to erase 16
	 *     consecutive sectors.  The start index for the nth Hw sector
	 *     can be calculated as = bank * 4096 + n * 256
	 * 01: The Hw sector is 4K bytes, hence we need to erase 1 sector.
	 *     The start index for the nth Hw sector can be calculated
	 *     as = bank * 4096
	 * 10: The Hw sector is 8K bytes, nth sector = bank * 8192
	 *     (ich9 only, otherwise error condition)
	 * 11: The Hw sector is 64K bytes, nth sector = bank * 65536
	 */
	switch (hsfsts.hsf_status.berasesz) {
	case 0:
		/* Hw sector size 256 */
		sector_size = ICH_FLASH_SEG_SIZE_256;
		iteration = flash_bank_size / ICH_FLASH_SEG_SIZE_256;
		break;
	case 1:
		sector_size = ICH_FLASH_SEG_SIZE_4K;
		iteration = 1;
		break;
	case 2:
		sector_size = ICH_FLASH_SEG_SIZE_8K;
		iteration = 1;
		break;
	case 3:
		sector_size = ICH_FLASH_SEG_SIZE_64K;
		iteration = 1;
		break;
	default:
		return -E1000_ERR_NVM;
	}

	/* Start with the base address, then add the sector offset. */
	flash_linear_addr = hw->nvm.flash_base_addr;
	flash_linear_addr += (bank) ? flash_bank_size : 0;

	for (j = 0; j < iteration ; j++) {
		do {
			/* Steps */
			ret_val = e1000_flash_cycle_init_ich8lan(hw);
			if (ret_val)
				return ret_val;

			/*
			 * Write a value 11 (block Erase) in Flash
			 * Cycle field in hw flash control
			 */
			hsflctl.regval = er16flash(ICH_FLASH_HSFCTL);
			hsflctl.hsf_ctrl.flcycle = ICH_CYCLE_ERASE;
			ew16flash(ICH_FLASH_HSFCTL, hsflctl.regval);

			/*
			 * Write the last 24 bits of an index within the
			 * block into Flash Linear address field in Flash
			 * Address.
			 */
			flash_linear_addr += (j * sector_size);
			ew32flash(ICH_FLASH_FADDR, flash_linear_addr);

			ret_val = e1000_flash_cycle_ich8lan(hw,
					       ICH_FLASH_ERASE_COMMAND_TIMEOUT);
			if (ret_val == 0)
				break;

			/*
			 * Check if FCERR is set to 1.  If 1,
			 * clear it and try the whole sequence
			 * a few more times else Done
			 */
			hsfsts.regval = er16flash(ICH_FLASH_HSFSTS);
			if (hsfsts.hsf_status.flcerr == 1)
				/* repeat for some time before giving up */
				continue;
			else if (hsfsts.hsf_status.flcdone == 0)
				return ret_val;
		} while (++count < ICH_FLASH_CYCLE_REPEAT_COUNT);
	}

	return 0;
}

/**
 *  e1000_valid_led_default_ich8lan - Set the default LED settings
 *  @hw: pointer to the HW structure
 *  @data: Pointer to the LED settings
 *
 *  Reads the LED default settings from the NVM to data.  If the NVM LED
 *  settings is all 0's or F's, set the LED default to a valid LED default
 *  setting.
 **/
static s32 e1000_valid_led_default_ich8lan(struct e1000_hw *hw, u16 *data)
{
	s32 ret_val;

	ret_val = e1000_read_nvm(hw, NVM_ID_LED_SETTINGS, 1, data);
	if (ret_val) {
		e_dbg("NVM Read Error\n");
		return ret_val;
	}

	if (*data == ID_LED_RESERVED_0000 ||
	    *data == ID_LED_RESERVED_FFFF)
		*data = ID_LED_DEFAULT_ICH8LAN;

	return 0;
}

/**
 *  e1000_id_led_init_pchlan - store LED configurations
 *  @hw: pointer to the HW structure
 *
 *  PCH does not control LEDs via the LEDCTL register, rather it uses
 *  the PHY LED configuration register.
 *
 *  PCH also does not have an "always on" or "always off" mode which
 *  complicates the ID feature.  Instead of using the "on" mode to indicate
 *  in ledctl_mode2 the LEDs to use for ID (see e1000e_id_led_init()),
 *  use "link_up" mode.  The LEDs will still ID on request if there is no
 *  link based on logic in e1000_led_[on|off]_pchlan().
 **/
static s32 e1000_id_led_init_pchlan(struct e1000_hw *hw)
{
	struct e1000_mac_info *mac = &hw->mac;
	s32 ret_val;
	const u32 ledctl_on = E1000_LEDCTL_MODE_LINK_UP;
	const u32 ledctl_off = E1000_LEDCTL_MODE_LINK_UP | E1000_PHY_LED0_IVRT;
	u16 data, i, temp, shift;

	/* Get default ID LED modes */
	ret_val = hw->nvm.ops.valid_led_default(hw, &data);
	if (ret_val)
		goto out;

	mac->ledctl_default = er32(LEDCTL);
	mac->ledctl_mode1 = mac->ledctl_default;
	mac->ledctl_mode2 = mac->ledctl_default;

	for (i = 0; i < 4; i++) {
		temp = (data >> (i << 2)) & E1000_LEDCTL_LED0_MODE_MASK;
		shift = (i * 5);
		switch (temp) {
		case ID_LED_ON1_DEF2:
		case ID_LED_ON1_ON2:
		case ID_LED_ON1_OFF2:
			mac->ledctl_mode1 &= ~(E1000_PHY_LED0_MASK << shift);
			mac->ledctl_mode1 |= (ledctl_on << shift);
			break;
		case ID_LED_OFF1_DEF2:
		case ID_LED_OFF1_ON2:
		case ID_LED_OFF1_OFF2:
			mac->ledctl_mode1 &= ~(E1000_PHY_LED0_MASK << shift);
			mac->ledctl_mode1 |= (ledctl_off << shift);
			break;
		default:
			/* Do nothing */
			break;
		}
		switch (temp) {
		case ID_LED_DEF1_ON2:
		case ID_LED_ON1_ON2:
		case ID_LED_OFF1_ON2:
			mac->ledctl_mode2 &= ~(E1000_PHY_LED0_MASK << shift);
			mac->ledctl_mode2 |= (ledctl_on << shift);
			break;
		case ID_LED_DEF1_OFF2:
		case ID_LED_ON1_OFF2:
		case ID_LED_OFF1_OFF2:
			mac->ledctl_mode2 &= ~(E1000_PHY_LED0_MASK << shift);
			mac->ledctl_mode2 |= (ledctl_off << shift);
			break;
		default:
			/* Do nothing */
			break;
		}
	}

out:
	return ret_val;
}

/**
 *  e1000_get_bus_info_ich8lan - Get/Set the bus type and width
 *  @hw: pointer to the HW structure
 *
 *  ICH8 use the PCI Express bus, but does not contain a PCI Express Capability
 *  register, so the the bus width is hard coded.
 **/
static s32 e1000_get_bus_info_ich8lan(struct e1000_hw *hw)
{
	struct e1000_bus_info *bus = &hw->bus;
	s32 ret_val;

	ret_val = e1000e_get_bus_info_pcie(hw);

	/*
	 * ICH devices are "PCI Express"-ish.  They have
	 * a configuration space, but do not contain
	 * PCI Express Capability registers, so bus width
	 * must be hardcoded.
	 */
	if (bus->width == e1000_bus_width_unknown)
		bus->width = e1000_bus_width_pcie_x1;

	return ret_val;
}

/**
 *  e1000_reset_hw_ich8lan - Reset the hardware
 *  @hw: pointer to the HW structure
 *
 *  Does a full reset of the hardware which includes a reset of the PHY and
 *  MAC.
 **/
static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw)
{
	struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan;
	u16 reg;
	u32 ctrl, icr __attribute__ ((unused)), kab;
	s32 ret_val;

	/*
	 * Prevent the PCI-E bus from sticking if there is no TLP connection
	 * on the last TLP read/write transaction when MAC is reset.
	 */
	ret_val = e1000e_disable_pcie_master(hw);
	if (ret_val)
		e_dbg("PCI-E Master disable polling has failed.\n");

	e_dbg("Masking off all interrupts\n");
	ew32(IMC, 0xffffffff);

	/*
	 * Disable the Transmit and Receive units.  Then delay to allow
	 * any pending transactions to complete before we hit the MAC
	 * with the global reset.
	 */
	ew32(RCTL, 0);
	ew32(TCTL, E1000_TCTL_PSP);
	e1e_flush();

	msleep(10);

	/* Workaround for ICH8 bit corruption issue in FIFO memory */
	if (hw->mac.type == e1000_ich8lan) {
		/* Set Tx and Rx buffer allocation to 8k apiece. */
		ew32(PBA, E1000_PBA_8K);
		/* Set Packet Buffer Size to 16k. */
		ew32(PBS, E1000_PBS_16K);
	}

	if (hw->mac.type == e1000_pchlan) {
		/* Save the NVM K1 bit setting*/
		ret_val = e1000_read_nvm(hw, E1000_NVM_K1_CONFIG, 1, &reg);
		if (ret_val)
			return ret_val;

		if (reg & E1000_NVM_K1_ENABLE)
			dev_spec->nvm_k1_enabled = true;
		else
			dev_spec->nvm_k1_enabled = false;
	}

	ctrl = er32(CTRL);

	if (!e1000_check_reset_block(hw)) {
		/*
		 * Full-chip reset requires MAC and PHY reset at the same
		 * time to make sure the interface between MAC and the
		 * external PHY is reset.
		 */
		ctrl |= E1000_CTRL_PHY_RST;

		/*
		 * Gate automatic PHY configuration by hardware on
		 * non-managed 82579
		 */
		if ((hw->mac.type == e1000_pch2lan) &&
		    !(er32(FWSM) & E1000_ICH_FWSM_FW_VALID))
			e1000_gate_hw_phy_config_ich8lan(hw, true);
	}
	ret_val = e1000_acquire_swflag_ich8lan(hw);
	e_dbg("Issuing a global reset to ich8lan\n");
	ew32(CTRL, (ctrl | E1000_CTRL_RST));
	msleep(20);

	if (!ret_val)
		e1000_release_swflag_ich8lan(hw);

	if (ctrl & E1000_CTRL_PHY_RST) {
		ret_val = hw->phy.ops.get_cfg_done(hw);
		if (ret_val)
			goto out;

		ret_val = e1000_post_phy_reset_ich8lan(hw);
		if (ret_val)
			goto out;
	}

	/*
	 * For PCH, this write will make sure that any noise
	 * will be detected as a CRC error and be dropped rather than show up
	 * as a bad packet to the DMA engine.
	 */
	if (hw->mac.type == e1000_pchlan)
		ew32(CRC_OFFSET, 0x65656565);

	ew32(IMC, 0xffffffff);
	icr = er32(ICR);

	kab = er32(KABGTXD);
	kab |= E1000_KABGTXD_BGSQLBIAS;
	ew32(KABGTXD, kab);

out:
	return ret_val;
}

/**
 *  e1000_init_hw_ich8lan - Initialize the hardware
 *  @hw: pointer to the HW structure
 *
 *  Prepares the hardware for transmit and receive by doing the following:
 *   - initialize hardware bits
 *   - initialize LED identification
 *   - setup receive address registers
 *   - setup flow control
 *   - setup transmit descriptors
 *   - clear statistics
 **/
static s32 e1000_init_hw_ich8lan(struct e1000_hw *hw)
{
	struct e1000_mac_info *mac = &hw->mac;
	u32 ctrl_ext, txdctl, snoop;
	s32 ret_val;
	u16 i;

	e1000_initialize_hw_bits_ich8lan(hw);

	/* Initialize identification LED */
	ret_val = mac->ops.id_led_init(hw);
	if (ret_val)
		e_dbg("Error initializing identification LED\n");
		/* This is not fatal and we should not stop init due to this */

	/* Setup the receive address. */
	e1000e_init_rx_addrs(hw, mac->rar_entry_count);

	/* Zero out the Multicast HASH table */
	e_dbg("Zeroing the MTA\n");
	for (i = 0; i < mac->mta_reg_count; i++)
		E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0);

	/*
	 * The 82578 Rx buffer will stall if wakeup is enabled in host and
	 * the ME.  Reading the BM_WUC register will clear the host wakeup bit.
	 * Reset the phy after disabling host wakeup to reset the Rx buffer.
	 */
	if (hw->phy.type == e1000_phy_82578) {
		hw->phy.ops.read_reg(hw, BM_WUC, &i);
		ret_val = e1000_phy_hw_reset_ich8lan(hw);
		if (ret_val)
			return ret_val;
	}

	/* Setup link and flow control */
	ret_val = e1000_setup_link_ich8lan(hw);

	/* Set the transmit descriptor write-back policy for both queues */
	txdctl = er32(TXDCTL(0));
	txdctl = (txdctl & ~E1000_TXDCTL_WTHRESH) |
		 E1000_TXDCTL_FULL_TX_DESC_WB;
	txdctl = (txdctl & ~E1000_TXDCTL_PTHRESH) |
		 E1000_TXDCTL_MAX_TX_DESC_PREFETCH;
	ew32(TXDCTL(0), txdctl);
	txdctl = er32(TXDCTL(1));
	txdctl = (txdctl & ~E1000_TXDCTL_WTHRESH) |
		 E1000_TXDCTL_FULL_TX_DESC_WB;
	txdctl = (txdctl & ~E1000_TXDCTL_PTHRESH) |
		 E1000_TXDCTL_MAX_TX_DESC_PREFETCH;
	ew32(TXDCTL(1), txdctl);

	/*
	 * ICH8 has opposite polarity of no_snoop bits.
	 * By default, we should use snoop behavior.
	 */
	if (mac->type == e1000_ich8lan)
		snoop = PCIE_ICH8_SNOOP_ALL;
	else
		snoop = (u32) ~(PCIE_NO_SNOOP_ALL);
	e1000e_set_pcie_no_snoop(hw, snoop);

	ctrl_ext = er32(CTRL_EXT);
	ctrl_ext |= E1000_CTRL_EXT_RO_DIS;
	ew32(CTRL_EXT, ctrl_ext);

	/*
	 * Clear all of the statistics registers (clear on read).  It is
	 * important that we do this after we have tried to establish link
	 * because the symbol error count will increment wildly if there
	 * is no link.
	 */
	e1000_clear_hw_cntrs_ich8lan(hw);

	return 0;
}
/**
 *  e1000_initialize_hw_bits_ich8lan - Initialize required hardware bits
 *  @hw: pointer to the HW structure
 *
 *  Sets/Clears required hardware bits necessary for correctly setting up the
 *  hardware for transmit and receive.
 **/
static void e1000_initialize_hw_bits_ich8lan(struct e1000_hw *hw)
{
	u32 reg;

	/* Extended Device Control */
	reg = er32(CTRL_EXT);
	reg |= (1 << 22);
	/* Enable PHY low-power state when MAC is at D3 w/o WoL */
	if (hw->mac.type >= e1000_pchlan)
		reg |= E1000_CTRL_EXT_PHYPDEN;
	ew32(CTRL_EXT, reg);

	/* Transmit Descriptor Control 0 */
	reg = er32(TXDCTL(0));
	reg |= (1 << 22);
	ew32(TXDCTL(0), reg);

	/* Transmit Descriptor Control 1 */
	reg = er32(TXDCTL(1));
	reg |= (1 << 22);
	ew32(TXDCTL(1), reg);

	/* Transmit Arbitration Control 0 */
	reg = er32(TARC(0));
	if (hw->mac.type == e1000_ich8lan)
		reg |= (1 << 28) | (1 << 29);
	reg |= (1 << 23) | (1 << 24) | (1 << 26) | (1 << 27);
	ew32(TARC(0), reg);

	/* Transmit Arbitration Control 1 */
	reg = er32(TARC(1));
	if (er32(TCTL) & E1000_TCTL_MULR)
		reg &= ~(1 << 28);
	else
		reg |= (1 << 28);
	reg |= (1 << 24) | (1 << 26) | (1 << 30);
	ew32(TARC(1), reg);

	/* Device Status */
	if (hw->mac.type == e1000_ich8lan) {
		reg = er32(STATUS);
		reg &= ~(1 << 31);
		ew32(STATUS, reg);
	}

	/*
	 * work-around descriptor data corruption issue during nfs v2 udp
	 * traffic, just disable the nfs filtering capability
	 */
	reg = er32(RFCTL);
	reg |= (E1000_RFCTL_NFSW_DIS | E1000_RFCTL_NFSR_DIS);
	ew32(RFCTL, reg);
}

/**
 *  e1000_setup_link_ich8lan - Setup flow control and link settings
 *  @hw: pointer to the HW structure
 *
 *  Determines which flow control settings to use, then configures flow
 *  control.  Calls the appropriate media-specific link configuration
 *  function.  Assuming the adapter has a valid link partner, a valid link
 *  should be established.  Assumes the hardware has previously been reset
 *  and the transmitter and receiver are not enabled.
 **/
static s32 e1000_setup_link_ich8lan(struct e1000_hw *hw)
{
	s32 ret_val;

	if (e1000_check_reset_block(hw))
		return 0;

	/*
	 * ICH parts do not have a word in the NVM to determine
	 * the default flow control setting, so we explicitly
	 * set it to full.
	 */
	if (hw->fc.requested_mode == e1000_fc_default) {
		/* Workaround h/w hang when Tx flow control enabled */
		if (hw->mac.type == e1000_pchlan)
			hw->fc.requested_mode = e1000_fc_rx_pause;
		else
			hw->fc.requested_mode = e1000_fc_full;
	}

	/*
	 * Save off the requested flow control mode for use later.  Depending
	 * on the link partner's capabilities, we may or may not use this mode.
	 */
	hw->fc.current_mode = hw->fc.requested_mode;

	e_dbg("After fix-ups FlowControl is now = %x\n",
		hw->fc.current_mode);

	/* Continue to configure the copper link. */
	ret_val = e1000_setup_copper_link_ich8lan(hw);
	if (ret_val)
		return ret_val;

	ew32(FCTTV, hw->fc.pause_time);
	if ((hw->phy.type == e1000_phy_82578) ||
	    (hw->phy.type == e1000_phy_82579) ||
	    (hw->phy.type == e1000_phy_82577)) {
		ew32(FCRTV_PCH, hw->fc.refresh_time);

		ret_val = hw->phy.ops.write_reg(hw,
		                             PHY_REG(BM_PORT_CTRL_PAGE, 27),
		                             hw->fc.pause_time);
		if (ret_val)
			return ret_val;
	}

	return e1000e_set_fc_watermarks(hw);
}

/**
 *  e1000_setup_copper_link_ich8lan - Configure MAC/PHY interface
 *  @hw: pointer to the HW structure
 *
 *  Configures the kumeran interface to the PHY to wait the appropriate time
 *  when polling the PHY, then call the generic setup_copper_link to finish
 *  configuring the copper link.
 **/
static s32 e1000_setup_copper_link_ich8lan(struct e1000_hw *hw)
{
	u32 ctrl;
	s32 ret_val;
	u16 reg_data;

	ctrl = er32(CTRL);
	ctrl |= E1000_CTRL_SLU;
	ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
	ew32(CTRL, ctrl);

	/*
	 * Set the mac to wait the maximum time between each iteration
	 * and increase the max iterations when polling the phy;
	 * this fixes erroneous timeouts at 10Mbps.
	 */
	ret_val = e1000e_write_kmrn_reg(hw, E1000_KMRNCTRLSTA_TIMEOUTS, 0xFFFF);
	if (ret_val)
		return ret_val;
	ret_val = e1000e_read_kmrn_reg(hw, E1000_KMRNCTRLSTA_INBAND_PARAM,
	                               &reg_data);
	if (ret_val)
		return ret_val;
	reg_data |= 0x3F;
	ret_val = e1000e_write_kmrn_reg(hw, E1000_KMRNCTRLSTA_INBAND_PARAM,
	                                reg_data);
	if (ret_val)
		return ret_val;

	switch (hw->phy.type) {
	case e1000_phy_igp_3:
		ret_val = e1000e_copper_link_setup_igp(hw);
		if (ret_val)
			return ret_val;
		break;
	case e1000_phy_bm:
	case e1000_phy_82578:
		ret_val = e1000e_copper_link_setup_m88(hw);
		if (ret_val)
			return ret_val;
		break;
	case e1000_phy_82577:
	case e1000_phy_82579:
		ret_val = e1000_copper_link_setup_82577(hw);
		if (ret_val)
			return ret_val;
		break;
	case e1000_phy_ife:
		ret_val = hw->phy.ops.read_reg(hw, IFE_PHY_MDIX_CONTROL,
		                               &reg_data);
		if (ret_val)
			return ret_val;

		reg_data &= ~IFE_PMC_AUTO_MDIX;

		switch (hw->phy.mdix) {
		case 1:
			reg_data &= ~IFE_PMC_FORCE_MDIX;
			break;
		case 2:
			reg_data |= IFE_PMC_FORCE_MDIX;
			break;
		case 0:
		default:
			reg_data |= IFE_PMC_AUTO_MDIX;
			break;
		}
		ret_val = hw->phy.ops.write_reg(hw, IFE_PHY_MDIX_CONTROL,
		                                reg_data);
		if (ret_val)
			return ret_val;
		break;
	default:
		break;
	}
	return e1000e_setup_copper_link(hw);
}

/**
 *  e1000_get_link_up_info_ich8lan - Get current link speed and duplex
 *  @hw: pointer to the HW structure
 *  @speed: pointer to store current link speed
 *  @duplex: pointer to store the current link duplex
 *
 *  Calls the generic get_speed_and_duplex to retrieve the current link
 *  information and then calls the Kumeran lock loss workaround for links at
 *  gigabit speeds.
 **/
static s32 e1000_get_link_up_info_ich8lan(struct e1000_hw *hw, u16 *speed,
					  u16 *duplex)
{
	s32 ret_val;

	ret_val = e1000e_get_speed_and_duplex_copper(hw, speed, duplex);
	if (ret_val)
		return ret_val;

	if ((hw->mac.type == e1000_ich8lan) &&
	    (hw->phy.type == e1000_phy_igp_3) &&
	    (*speed == SPEED_1000)) {
		ret_val = e1000_kmrn_lock_loss_workaround_ich8lan(hw);
	}

	return ret_val;
}

/**
 *  e1000_kmrn_lock_loss_workaround_ich8lan - Kumeran workaround
 *  @hw: pointer to the HW structure
 *
 *  Work-around for 82566 Kumeran PCS lock loss:
 *  On link status change (i.e. PCI reset, speed change) and link is up and
 *  speed is gigabit-
 *    0) if workaround is optionally disabled do nothing
 *    1) wait 1ms for Kumeran link to come up
 *    2) check Kumeran Diagnostic register PCS lock loss bit
 *    3) if not set the link is locked (all is good), otherwise...
 *    4) reset the PHY
 *    5) repeat up to 10 times
 *  Note: this is only called for IGP3 copper when speed is 1gb.
 **/
static s32 e1000_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw)
{
	struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan;
	u32 phy_ctrl;
	s32 ret_val;
	u16 i, data;
	bool link;

	if (!dev_spec->kmrn_lock_loss_workaround_enabled)
		return 0;

	/*
	 * Make sure link is up before proceeding.  If not just return.
	 * Attempting this while link is negotiating fouled up link
	 * stability
	 */
	ret_val = e1000e_phy_has_link_generic(hw, 1, 0, &link);
	if (!link)
		return 0;

	for (i = 0; i < 10; i++) {
		/* read once to clear */
		ret_val = e1e_rphy(hw, IGP3_KMRN_DIAG, &data);
		if (ret_val)
			return ret_val;
		/* and again to get new status */
		ret_val = e1e_rphy(hw, IGP3_KMRN_DIAG, &data);
		if (ret_val)
			return ret_val;

		/* check for PCS lock */
		if (!(data & IGP3_KMRN_DIAG_PCS_LOCK_LOSS))
			return 0;

		/* Issue PHY reset */
		e1000_phy_hw_reset(hw);
		mdelay(5);
	}
	/* Disable GigE link negotiation */
	phy_ctrl = er32(PHY_CTRL);
	phy_ctrl |= (E1000_PHY_CTRL_GBE_DISABLE |
		     E1000_PHY_CTRL_NOND0A_GBE_DISABLE);
	ew32(PHY_CTRL, phy_ctrl);

	/*
	 * Call gig speed drop workaround on Gig disable before accessing
	 * any PHY registers
	 */
	e1000e_gig_downshift_workaround_ich8lan(hw);

	/* unable to acquire PCS lock */
	return -E1000_ERR_PHY;
}

/**
 *  e1000_set_kmrn_lock_loss_workaround_ich8lan - Set Kumeran workaround state
 *  @hw: pointer to the HW structure
 *  @state: boolean value used to set the current Kumeran workaround state
 *
 *  If ICH8, set the current Kumeran workaround state (enabled - true
 *  /disabled - false).
 **/
void e1000e_set_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw,
						 bool state)
{
	struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan;

	if (hw->mac.type != e1000_ich8lan) {
		e_dbg("Workaround applies to ICH8 only.\n");
		return;
	}

	dev_spec->kmrn_lock_loss_workaround_enabled = state;
}

/**
 *  e1000_ipg3_phy_powerdown_workaround_ich8lan - Power down workaround on D3
 *  @hw: pointer to the HW structure
 *
 *  Workaround for 82566 power-down on D3 entry:
 *    1) disable gigabit link
 *    2) write VR power-down enable
 *    3) read it back
 *  Continue if successful, else issue LCD reset and repeat
 **/
void e1000e_igp3_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw)
{
	u32 reg;
	u16 data;
	u8  retry = 0;

	if (hw->phy.type != e1000_phy_igp_3)
		return;

	/* Try the workaround twice (if needed) */
	do {
		/* Disable link */
		reg = er32(PHY_CTRL);
		reg |= (E1000_PHY_CTRL_GBE_DISABLE |
			E1000_PHY_CTRL_NOND0A_GBE_DISABLE);
		ew32(PHY_CTRL, reg);

		/*
		 * Call gig speed drop workaround on Gig disable before
		 * accessing any PHY registers
		 */
		if (hw->mac.type == e1000_ich8lan)
			e1000e_gig_downshift_workaround_ich8lan(hw);

		/* Write VR power-down enable */
		e1e_rphy(hw, IGP3_VR_CTRL, &data);
		data &= ~IGP3_VR_CTRL_DEV_POWERDOWN_MODE_MASK;
		e1e_wphy(hw, IGP3_VR_CTRL, data | IGP3_VR_CTRL_MODE_SHUTDOWN);

		/* Read it back and test */
		e1e_rphy(hw, IGP3_VR_CTRL, &data);
		data &= IGP3_VR_CTRL_DEV_POWERDOWN_MODE_MASK;
		if ((data == IGP3_VR_CTRL_MODE_SHUTDOWN) || retry)
			break;

		/* Issue PHY reset and repeat at most one more time */
		reg = er32(CTRL);
		ew32(CTRL, reg | E1000_CTRL_PHY_RST);
		retry++;
	} while (retry);
}

/**
 *  e1000e_gig_downshift_workaround_ich8lan - WoL from S5 stops working
 *  @hw: pointer to the HW structure
 *
 *  Steps to take when dropping from 1Gb/s (eg. link cable removal (LSC),
 *  LPLU, Gig disable, MDIC PHY reset):
 *    1) Set Kumeran Near-end loopback
 *    2) Clear Kumeran Near-end loopback
 *  Should only be called for ICH8[m] devices with IGP_3 Phy.
 **/
void e1000e_gig_downshift_workaround_ich8lan(struct e1000_hw *hw)
{
	s32 ret_val;
	u16 reg_data;

	if ((hw->mac.type != e1000_ich8lan) ||
	    (hw->phy.type != e1000_phy_igp_3))
		return;

	ret_val = e1000e_read_kmrn_reg(hw, E1000_KMRNCTRLSTA_DIAG_OFFSET,
				      &reg_data);
	if (ret_val)
		return;
	reg_data |= E1000_KMRNCTRLSTA_DIAG_NELPBK;
	ret_val = e1000e_write_kmrn_reg(hw, E1000_KMRNCTRLSTA_DIAG_OFFSET,
				       reg_data);
	if (ret_val)
		return;
	reg_data &= ~E1000_KMRNCTRLSTA_DIAG_NELPBK;
	ret_val = e1000e_write_kmrn_reg(hw, E1000_KMRNCTRLSTA_DIAG_OFFSET,
				       reg_data);
}

/**
 *  e1000e_disable_gig_wol_ich8lan - disable gig during WoL
 *  @hw: pointer to the HW structure
 *
 *  During S0 to Sx transition, it is possible the link remains at gig
 *  instead of negotiating to a lower speed.  Before going to Sx, set
 *  'LPLU Enabled' and 'Gig Disable' to force link speed negotiation
 *  to a lower speed.
 *
 *  Should only be called for applicable parts.
 **/
void e1000e_disable_gig_wol_ich8lan(struct e1000_hw *hw)
{
	u32 phy_ctrl;
	s32 ret_val;

	phy_ctrl = er32(PHY_CTRL);
	phy_ctrl |= E1000_PHY_CTRL_D0A_LPLU | E1000_PHY_CTRL_GBE_DISABLE;
	ew32(PHY_CTRL, phy_ctrl);

	if (hw->mac.type >= e1000_pchlan) {
		e1000_oem_bits_config_ich8lan(hw, true);
		ret_val = hw->phy.ops.acquire(hw);
		if (ret_val)
			return;
		e1000_write_smbus_addr(hw);
		hw->phy.ops.release(hw);
	}
}

/**
 *  e1000_cleanup_led_ich8lan - Restore the default LED operation
 *  @hw: pointer to the HW structure
 *
 *  Return the LED back to the default configuration.
 **/
static s32 e1000_cleanup_led_ich8lan(struct e1000_hw *hw)
{
	if (hw->phy.type == e1000_phy_ife)
		return e1e_wphy(hw, IFE_PHY_SPECIAL_CONTROL_LED, 0);

	ew32(LEDCTL, hw->mac.ledctl_default);
	return 0;
}

/**
 *  e1000_led_on_ich8lan - Turn LEDs on
 *  @hw: pointer to the HW structure
 *
 *  Turn on the LEDs.
 **/
static s32 e1000_led_on_ich8lan(struct e1000_hw *hw)
{
	if (hw->phy.type == e1000_phy_ife)
		return e1e_wphy(hw, IFE_PHY_SPECIAL_CONTROL_LED,
				(IFE_PSCL_PROBE_MODE | IFE_PSCL_PROBE_LEDS_ON));

	ew32(LEDCTL, hw->mac.ledctl_mode2);
	return 0;
}

/**
 *  e1000_led_off_ich8lan - Turn LEDs off
 *  @hw: pointer to the HW structure
 *
 *  Turn off the LEDs.
 **/
static s32 e1000_led_off_ich8lan(struct e1000_hw *hw)
{
	if (hw->phy.type == e1000_phy_ife)
		return e1e_wphy(hw, IFE_PHY_SPECIAL_CONTROL_LED,
			       (IFE_PSCL_PROBE_MODE | IFE_PSCL_PROBE_LEDS_OFF));

	ew32(LEDCTL, hw->mac.ledctl_mode1);
	return 0;
}

/**
 *  e1000_setup_led_pchlan - Configures SW controllable LED
 *  @hw: pointer to the HW structure
 *
 *  This prepares the SW controllable LED for use.
 **/
static s32 e1000_setup_led_pchlan(struct e1000_hw *hw)
{
	return hw->phy.ops.write_reg(hw, HV_LED_CONFIG,
					(u16)hw->mac.ledctl_mode1);
}

/**
 *  e1000_cleanup_led_pchlan - Restore the default LED operation
 *  @hw: pointer to the HW structure
 *
 *  Return the LED back to the default configuration.
 **/
static s32 e1000_cleanup_led_pchlan(struct e1000_hw *hw)
{
	return hw->phy.ops.write_reg(hw, HV_LED_CONFIG,
					(u16)hw->mac.ledctl_default);
}

/**
 *  e1000_led_on_pchlan - Turn LEDs on
 *  @hw: pointer to the HW structure
 *
 *  Turn on the LEDs.
 **/
static s32 e1000_led_on_pchlan(struct e1000_hw *hw)
{
	u16 data = (u16)hw->mac.ledctl_mode2;
	u32 i, led;

	/*
	 * If no link, then turn LED on by setting the invert bit
	 * for each LED that's mode is "link_up" in ledctl_mode2.
	 */
	if (!(er32(STATUS) & E1000_STATUS_LU)) {
		for (i = 0; i < 3; i++) {
			led = (data >> (i * 5)) & E1000_PHY_LED0_MASK;
			if ((led & E1000_PHY_LED0_MODE_MASK) !=
			    E1000_LEDCTL_MODE_LINK_UP)
				continue;
			if (led & E1000_PHY_LED0_IVRT)
				data &= ~(E1000_PHY_LED0_IVRT << (i * 5));
			else
				data |= (E1000_PHY_LED0_IVRT << (i * 5));
		}
	}

	return hw->phy.ops.write_reg(hw, HV_LED_CONFIG, data);
}

/**
 *  e1000_led_off_pchlan - Turn LEDs off
 *  @hw: pointer to the HW structure
 *
 *  Turn off the LEDs.
 **/
static s32 e1000_led_off_pchlan(struct e1000_hw *hw)
{
	u16 data = (u16)hw->mac.ledctl_mode1;
	u32 i, led;

	/*
	 * If no link, then turn LED off by clearing the invert bit
	 * for each LED that's mode is "link_up" in ledctl_mode1.
	 */
	if (!(er32(STATUS) & E1000_STATUS_LU)) {
		for (i = 0; i < 3; i++) {
			led = (data >> (i * 5)) & E1000_PHY_LED0_MASK;
			if ((led & E1000_PHY_LED0_MODE_MASK) !=
			    E1000_LEDCTL_MODE_LINK_UP)
				continue;
			if (led & E1000_PHY_LED0_IVRT)
				data &= ~(E1000_PHY_LED0_IVRT << (i * 5));
			else
				data |= (E1000_PHY_LED0_IVRT << (i * 5));
		}
	}

	return hw->phy.ops.write_reg(hw, HV_LED_CONFIG, data);
}

/**
 *  e1000_get_cfg_done_ich8lan - Read config done bit after Full or PHY reset
 *  @hw: pointer to the HW structure
 *
 *  Read appropriate register for the config done bit for completion status
 *  and configure the PHY through s/w for EEPROM-less parts.
 *
 *  NOTE: some silicon which is EEPROM-less will fail trying to read the
 *  config done bit, so only an error is logged and continues.  If we were
 *  to return with error, EEPROM-less silicon would not be able to be reset
 *  or change link.
 **/
static s32 e1000_get_cfg_done_ich8lan(struct e1000_hw *hw)
{
	s32 ret_val = 0;
	u32 bank = 0;
	u32 status;

	e1000e_get_cfg_done(hw);

	/* Wait for indication from h/w that it has completed basic config */
	if (hw->mac.type >= e1000_ich10lan) {
		e1000_lan_init_done_ich8lan(hw);
	} else {
		ret_val = e1000e_get_auto_rd_done(hw);
		if (ret_val) {
			/*
			 * When auto config read does not complete, do not
			 * return with an error. This can happen in situations
			 * where there is no eeprom and prevents getting link.
			 */
			e_dbg("Auto Read Done did not complete\n");
			ret_val = 0;
		}
	}

	/* Clear PHY Reset Asserted bit */
	status = er32(STATUS);
	if (status & E1000_STATUS_PHYRA)
		ew32(STATUS, status & ~E1000_STATUS_PHYRA);
	else
		e_dbg("PHY Reset Asserted not set - needs delay\n");

	/* If EEPROM is not marked present, init the IGP 3 PHY manually */
	if (hw->mac.type <= e1000_ich9lan) {
		if (((er32(EECD) & E1000_EECD_PRES) == 0) &&
		    (hw->phy.type == e1000_phy_igp_3)) {
			e1000e_phy_init_script_igp3(hw);
		}
	} else {
		if (e1000_valid_nvm_bank_detect_ich8lan(hw, &bank)) {
			/* Maybe we should do a basic PHY config */
			e_dbg("EEPROM not present\n");
			ret_val = -E1000_ERR_CONFIG;
		}
	}

	return ret_val;
}

/**
 * e1000_power_down_phy_copper_ich8lan - Remove link during PHY power down
 * @hw: pointer to the HW structure
 *
 * In the case of a PHY power down to save power, or to turn off link during a
 * driver unload, or wake on lan is not enabled, remove the link.
 **/
static void e1000_power_down_phy_copper_ich8lan(struct e1000_hw *hw)
{
	/* If the management interface is not enabled, then power down */
	if (!(hw->mac.ops.check_mng_mode(hw) ||
	      hw->phy.ops.check_reset_block(hw)))
		e1000_power_down_phy_copper(hw);
}

/**
 *  e1000_clear_hw_cntrs_ich8lan - Clear statistical counters
 *  @hw: pointer to the HW structure
 *
 *  Clears hardware counters specific to the silicon family and calls
 *  clear_hw_cntrs_generic to clear all general purpose counters.
 **/
static void e1000_clear_hw_cntrs_ich8lan(struct e1000_hw *hw)
{
	u16 phy_data;

	e1000e_clear_hw_cntrs_base(hw);

	er32(ALGNERRC);
	er32(RXERRC);
	er32(TNCRS);
	er32(CEXTERR);
	er32(TSCTC);
	er32(TSCTFC);

	er32(MGTPRC);
	er32(MGTPDC);
	er32(MGTPTC);

	er32(IAC);
	er32(ICRXOC);

	/* Clear PHY statistics registers */
	if ((hw->phy.type == e1000_phy_82578) ||
	    (hw->phy.type == e1000_phy_82579) ||
	    (hw->phy.type == e1000_phy_82577)) {
		hw->phy.ops.read_reg(hw, HV_SCC_UPPER, &phy_data);
		hw->phy.ops.read_reg(hw, HV_SCC_LOWER, &phy_data);
		hw->phy.ops.read_reg(hw, HV_ECOL_UPPER, &phy_data);
		hw->phy.ops.read_reg(hw, HV_ECOL_LOWER, &phy_data);
		hw->phy.ops.read_reg(hw, HV_MCC_UPPER, &phy_data);
		hw->phy.ops.read_reg(hw, HV_MCC_LOWER, &phy_data);
		hw->phy.ops.read_reg(hw, HV_LATECOL_UPPER, &phy_data);
		hw->phy.ops.read_reg(hw, HV_LATECOL_LOWER, &phy_data);
		hw->phy.ops.read_reg(hw, HV_COLC_UPPER, &phy_data);
		hw->phy.ops.read_reg(hw, HV_COLC_LOWER, &phy_data);
		hw->phy.ops.read_reg(hw, HV_DC_UPPER, &phy_data);
		hw->phy.ops.read_reg(hw, HV_DC_LOWER, &phy_data);
		hw->phy.ops.read_reg(hw, HV_TNCRS_UPPER, &phy_data);
		hw->phy.ops.read_reg(hw, HV_TNCRS_LOWER, &phy_data);
	}
}

static struct e1000_mac_operations ich8_mac_ops = {
	.id_led_init		= e1000e_id_led_init,
	/* check_mng_mode dependent on mac type */
	.check_for_link		= e1000_check_for_copper_link_ich8lan,
	/* cleanup_led dependent on mac type */
	.clear_hw_cntrs		= e1000_clear_hw_cntrs_ich8lan,
	.get_bus_info		= e1000_get_bus_info_ich8lan,
	.set_lan_id		= e1000_set_lan_id_single_port,
	.get_link_up_info	= e1000_get_link_up_info_ich8lan,
	/* led_on dependent on mac type */
	/* led_off dependent on mac type */
	.update_mc_addr_list	= e1000e_update_mc_addr_list_generic,
	.reset_hw		= e1000_reset_hw_ich8lan,
	.init_hw		= e1000_init_hw_ich8lan,
	.setup_link		= e1000_setup_link_ich8lan,
	.setup_physical_interface= e1000_setup_copper_link_ich8lan,
	/* id_led_init dependent on mac type */
};

static struct e1000_phy_operations ich8_phy_ops = {
	.acquire		= e1000_acquire_swflag_ich8lan,
	.check_reset_block	= e1000_check_reset_block_ich8lan,
	.commit			= NULL,
	.get_cfg_done		= e1000_get_cfg_done_ich8lan,
	.get_cable_length	= e1000e_get_cable_length_igp_2,
	.read_reg		= e1000e_read_phy_reg_igp,
	.release		= e1000_release_swflag_ich8lan,
	.reset			= e1000_phy_hw_reset_ich8lan,
	.set_d0_lplu_state	= e1000_set_d0_lplu_state_ich8lan,
	.set_d3_lplu_state	= e1000_set_d3_lplu_state_ich8lan,
	.write_reg		= e1000e_write_phy_reg_igp,
};

static struct e1000_nvm_operations ich8_nvm_ops = {
	.acquire		= e1000_acquire_nvm_ich8lan,
	.read		 	= e1000_read_nvm_ich8lan,
	.release		= e1000_release_nvm_ich8lan,
	.update			= e1000_update_nvm_checksum_ich8lan,
	.valid_led_default	= e1000_valid_led_default_ich8lan,
	.validate		= e1000_validate_nvm_checksum_ich8lan,
	.write			= e1000_write_nvm_ich8lan,
};

struct e1000_info e1000_ich8_info = {
	.mac			= e1000_ich8lan,
	.flags			= FLAG_HAS_WOL
				  | FLAG_IS_ICH
				  | FLAG_RX_CSUM_ENABLED
				  | FLAG_HAS_CTRLEXT_ON_LOAD
				  | FLAG_HAS_AMT
				  | FLAG_HAS_FLASH
				  | FLAG_APME_IN_WUC,
	.pba			= 8,
	.max_hw_frame_size	= ETH_FRAME_LEN + ETH_FCS_LEN,
	.get_variants		= e1000_get_variants_ich8lan,
	.mac_ops		= &ich8_mac_ops,
	.phy_ops		= &ich8_phy_ops,
	.nvm_ops		= &ich8_nvm_ops,
};

struct e1000_info e1000_ich9_info = {
	.mac			= e1000_ich9lan,
	.flags			= FLAG_HAS_JUMBO_FRAMES
				  | FLAG_IS_ICH
				  | FLAG_HAS_WOL
				  | FLAG_RX_CSUM_ENABLED
				  | FLAG_HAS_CTRLEXT_ON_LOAD
				  | FLAG_HAS_AMT
				  | FLAG_HAS_ERT
				  | FLAG_HAS_FLASH
				  | FLAG_APME_IN_WUC,
	.pba			= 10,
	.max_hw_frame_size	= DEFAULT_JUMBO,
	.get_variants		= e1000_get_variants_ich8lan,
	.mac_ops		= &ich8_mac_ops,
	.phy_ops		= &ich8_phy_ops,
	.nvm_ops		= &ich8_nvm_ops,
};

struct e1000_info e1000_ich10_info = {
	.mac			= e1000_ich10lan,
	.flags			= FLAG_HAS_JUMBO_FRAMES
				  | FLAG_IS_ICH
				  | FLAG_HAS_WOL
				  | FLAG_RX_CSUM_ENABLED
				  | FLAG_HAS_CTRLEXT_ON_LOAD
				  | FLAG_HAS_AMT
				  | FLAG_HAS_ERT
				  | FLAG_HAS_FLASH
				  | FLAG_APME_IN_WUC,
	.pba			= 10,
	.max_hw_frame_size	= DEFAULT_JUMBO,
	.get_variants		= e1000_get_variants_ich8lan,
	.mac_ops		= &ich8_mac_ops,
	.phy_ops		= &ich8_phy_ops,
	.nvm_ops		= &ich8_nvm_ops,
};

struct e1000_info e1000_pch_info = {
	.mac			= e1000_pchlan,
	.flags			= FLAG_IS_ICH
				  | FLAG_HAS_WOL
				  | FLAG_RX_CSUM_ENABLED
				  | FLAG_HAS_CTRLEXT_ON_LOAD
				  | FLAG_HAS_AMT
				  | FLAG_HAS_FLASH
				  | FLAG_HAS_JUMBO_FRAMES
				  | FLAG_DISABLE_FC_PAUSE_TIME /* errata */
				  | FLAG_APME_IN_WUC,
	.flags2			= FLAG2_HAS_PHY_STATS,
	.pba			= 26,
	.max_hw_frame_size	= 4096,
	.get_variants		= e1000_get_variants_ich8lan,
	.mac_ops		= &ich8_mac_ops,
	.phy_ops		= &ich8_phy_ops,
	.nvm_ops		= &ich8_nvm_ops,
};

struct e1000_info e1000_pch2_info = {
	.mac			= e1000_pch2lan,
	.flags			= FLAG_IS_ICH
				  | FLAG_HAS_WOL
				  | FLAG_RX_CSUM_ENABLED
				  | FLAG_HAS_CTRLEXT_ON_LOAD
				  | FLAG_HAS_AMT
				  | FLAG_HAS_FLASH
				  | FLAG_HAS_JUMBO_FRAMES
				  | FLAG_APME_IN_WUC,
	.flags2			= FLAG2_HAS_PHY_STATS
				  | FLAG2_HAS_EEE,
	.pba			= 26,
	.max_hw_frame_size	= DEFAULT_JUMBO,
	.get_variants		= e1000_get_variants_ich8lan,
	.mac_ops		= &ich8_mac_ops,
	.phy_ops		= &ich8_phy_ops,
	.nvm_ops		= &ich8_nvm_ops,
};


<|start_filename|>3rdpart/tslib-1.15/plugins/linear-h2200.c<|end_filename|>
/*
 *  tslib/plugins/linear-h2200.c
 *
 *  Copyright (C) 2004 <NAME>
 *
 * This file is placed under the LGPL.  Please see the file
 * COPYING for more details.
 *
 * SPDX-License-Identifier: LGPL-2.1
 *
 *
 * Linearly scale touchscreen values for HP iPAQ h22xx.
 */

#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>

#include <stdio.h>

#include "config.h"
#include "tslib.h"
#include "tslib-filter.h"

struct tslib_linear_h2200 {
	struct tslib_module_info module;
};

/*

  Thanks to <NAME> <<EMAIL>> for the formula!

  [u v] = [1  x  y  x*y  x2  y2] * P

  P = [ 14.0274374997464	-10.4143500663246
	0.963183808844262	0.123820939383483
       -0.0175631972840528	0.90783932803656
	3.01072646091237e-005	-0.00022066295637918
	1.78550793439434e-005	5.26174785439132e-006
	1.24328256232492e-006	0.000171150736110672]

  Using fixed point arithmetics as ARM processors don't have floating point
  capabilities. Otherwise, using floating point would cause time consuming
  kernel exceptions. With our input and output data, found that we could
  use a 12.20 format, provided we use extra intermediate shifts with very
  small numbers and products are done in a careful order that doesn't
  yield big intermediate products).

*/

#define M20(x, y) ((long)(((long long)x * (long long)y) >> 20))
#define M32(x, y) ((long)(((long long)x * (long long)y) >> 32))

static int
linear_h2200_read(struct tslib_module_info *info, struct ts_sample *samp,
		  int nr_samples)
{
	int ret;
	long x, y, new_x, new_y;

	ret = info->next->ops->read(info->next, samp, nr_samples);
	if (ret >= 0) {
		int nr;

		for (nr = 0; nr < ret; nr++, samp++) {

			x = ((long) samp->x) << 20;
			y = ((long) samp->y) << 20;

			/* Caution: constants have been multiplied by 2^20
			  (to save runtime). Some of them have been
			  multiplied by 2^32 when they were too small.
			  An extra >>12 is then needed.

			  Note: we never multiply x*y or y*y first
			  (intermediate result too big, could overflow),
			  we multiply by the constant first. Because of this,
			  we can't reuse x^2, y^2 and x*y
			*/

			new_x = 14708834 + M20(1009971, x) + M20(-18416, y) +
				M20(M32(129310, x), y) + M20(M32(76687, x), x) +
				M20(M32(5340, y), y);

			new_y = -10920238 + M20(129836, x) + M20(951939, y) +
				M20(M32(-947740, x), y) + M20(M32(22599, x), x) +
				M20(M32(735087, y), y);

			samp->x = (int) (new_x >> 20);
			samp->y = (int) (new_y >> 20);
		}
	}

	return ret;
}

static int linear_h2200_fini(struct tslib_module_info *info)
{
	free(info);
	return 0;
}

static const struct tslib_ops linear_h2200_ops = {
	.read	= linear_h2200_read,
	.fini	= linear_h2200_fini,
};

TSAPI struct tslib_module_info *linear_h2200_mod_init(__attribute__ ((unused)) struct tsdev *dev,
						      __attribute__ ((unused)) const char *params)
{

	struct tslib_linear_h2200 *lin;

	lin = malloc(sizeof(struct tslib_linear_h2200));
	if (lin == NULL)
		return NULL;

	lin->module.ops = &linear_h2200_ops;

	return &lin->module;
}

#ifndef TSLIB_STATIC_LINEAR_H2200_MODULE
	TSLIB_MODULE_INIT(linear_h2200_mod_init);
#endif


<|start_filename|>3rdpart/tslib-1.15/tests/fbutils-linux.c<|end_filename|>
/*
 * fbutils-linux.c
 *
 * Utility routines for framebuffer interaction
 *
 * Copyright 2002 <NAME> and <NAME>
 *
 * This file is placed under the GPL.  Please see the
 * file COPYING for details.
 *
 * SPDX-License-Identifier: GPL-2.0+
 */

#include "config.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/time.h>
#include <fcntl.h>

#include <linux/vt.h>
#include <linux/kd.h>
#include <linux/fb.h>

#include "font.h"
#include "fbutils.h"

union multiptr {
	uint8_t *p8;
	uint16_t *p16;
	uint32_t *p32;
};

static int32_t con_fd, last_vt = -1;
static struct fb_fix_screeninfo fix;
static struct fb_var_screeninfo var;
static unsigned char *fbuffer;
static unsigned char **line_addr;
static int32_t fb_fd;
static int32_t bytes_per_pixel;
static uint32_t transp_mask;
static uint32_t colormap[256];
uint32_t xres, yres;
int8_t rotation;

static char *defaultfbdevice = "/dev/fb0";
static char *defaultconsoledevice = "/dev/tty";
static char *fbdevice;
static char *consoledevice;

#define VTNAME_LEN 128

int open_framebuffer(void)
{
	struct vt_stat vts;
	char vtname[VTNAME_LEN];
	int32_t fd, nr;
	uint32_t y, addr;

	if ((fbdevice = getenv("TSLIB_FBDEVICE")) == NULL)
		fbdevice = defaultfbdevice;

	if ((consoledevice = getenv("TSLIB_CONSOLEDEVICE")) == NULL)
		consoledevice = defaultconsoledevice;

	if (strcmp(consoledevice, "none") != 0) {
		if (strlen(consoledevice) >= VTNAME_LEN)
			return -1;

		sprintf(vtname, "%s%d", consoledevice, 1);
		fd = open(vtname, O_WRONLY);
		if (fd < 0) {
			perror("open consoledevice");
			return -1;
		}

		if (ioctl(fd, VT_OPENQRY, &nr) < 0) {
			close(fd);
			perror("ioctl VT_OPENQRY");
			return -1;
		}
		close(fd);

		sprintf(vtname, "%s%d", consoledevice, nr);

		con_fd = open(vtname, O_RDWR | O_NDELAY);
		if (con_fd < 0) {
			perror("open tty");
			return -1;
		}

		if (ioctl(con_fd, VT_GETSTATE, &vts) == 0)
			last_vt = vts.v_active;

		if (ioctl(con_fd, VT_ACTIVATE, nr) < 0) {
			perror("VT_ACTIVATE");
			close(con_fd);
			return -1;
		}

#ifndef TSLIB_NO_VT_WAITACTIVE
		if (ioctl(con_fd, VT_WAITACTIVE, nr) < 0) {
			perror("VT_WAITACTIVE");
			close(con_fd);
			return -1;
		}
#endif

		if (ioctl(con_fd, KDSETMODE, KD_GRAPHICS) < 0) {
			perror("KDSETMODE");
			close(con_fd);
			return -1;
		}

	}

	fb_fd = open(fbdevice, O_RDWR);
	if (fb_fd == -1) {
		perror("open fbdevice");
		return -1;
	}

	if (ioctl(fb_fd, FBIOGET_FSCREENINFO, &fix) < 0) {
		perror("ioctl FBIOGET_FSCREENINFO");
		close(fb_fd);
		return -1;
	}

	if (ioctl(fb_fd, FBIOGET_VSCREENINFO, &var) < 0) {
		perror("ioctl FBIOGET_VSCREENINFO");
		close(fb_fd);
		return -1;
	}
	if (rotation & 1) {
		/* 1 or 3 */
		y = var.yres;
		yres = var.xres;
		xres = y;
	} else {
		/* 0 or 2 */
		xres = var.xres;
		yres = var.yres;
	}

	fbuffer = mmap(NULL,
		       fix.smem_len,
		       PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED,
		       fb_fd,
		       0);

	if (fbuffer == (unsigned char *)-1) {
		perror("mmap framebuffer");
		close(fb_fd);
		return -1;
	}
	memset(fbuffer, 0, fix.smem_len);

	bytes_per_pixel = (var.bits_per_pixel + 7) / 8;
	transp_mask = ((1 << var.transp.length) - 1) <<
		var.transp.offset; /* transp.length unlikely > 32 */
	line_addr = malloc(sizeof(*line_addr) * var.yres_virtual);
	addr = 0;
	for (y = 0; y < var.yres_virtual; y++, addr += fix.line_length)
		line_addr[y] = fbuffer + addr;

	return 0;
}

void close_framebuffer(void)
{
	memset(fbuffer, 0, fix.smem_len);
	munmap(fbuffer, fix.smem_len);
	close(fb_fd);

	if (strcmp(consoledevice, "none") != 0) {
		if (ioctl(con_fd, KDSETMODE, KD_TEXT) < 0)
			perror("KDSETMODE");

		if (last_vt >= 0)
			if (ioctl(con_fd, VT_ACTIVATE, last_vt))
				perror("VT_ACTIVATE");

		close(con_fd);
	}

	free(line_addr);

	xres = 0;
	yres = 0;
	rotation = 0;
}

void put_cross(int32_t x, int32_t y, uint32_t colidx)
{
	line(x - 10, y, x - 2, y, colidx);
	line(x + 2, y, x + 10, y, colidx);
	line(x, y - 10, x, y - 2, colidx);
	line(x, y + 2, x, y + 10, colidx);

#if 1
	line(x - 6, y - 9, x - 9, y - 9, colidx + 1);
	line(x - 9, y - 8, x - 9, y - 6, colidx + 1);
	line(x - 9, y + 6, x - 9, y + 9, colidx + 1);
	line(x - 8, y + 9, x - 6, y + 9, colidx + 1);
	line(x + 6, y + 9, x + 9, y + 9, colidx + 1);
	line(x + 9, y + 8, x + 9, y + 6, colidx + 1);
	line(x + 9, y - 6, x + 9, y - 9, colidx + 1);
	line(x + 8, y - 9, x + 6, y - 9, colidx + 1);
#else
	line(x - 7, y - 7, x - 4, y - 4, colidx + 1);
	line(x - 7, y + 7, x - 4, y + 4, colidx + 1);
	line(x + 4, y - 4, x + 7, y - 7, colidx + 1);
	line(x + 4, y + 4, x + 7, y + 7, colidx + 1);
#endif
}

static void put_char(int32_t x, int32_t y, int32_t c, int32_t colidx)
{
	int32_t i, j, bits;

	for (i = 0; i < font_vga_8x8.height; i++) {
		bits = font_vga_8x8.data[font_vga_8x8.height * c + i];
		for (j = 0; j < font_vga_8x8.width; j++, bits <<= 1)
			if (bits & 0x80)
				pixel(x + j, y + i, colidx);
	}
}

void put_string(int32_t x, int32_t y, char *s, uint32_t colidx)
{
	int32_t i;

	for (i = 0; *s; i++, x += font_vga_8x8.width, s++)
		put_char (x, y, *s, colidx);
}

void put_string_center(int32_t x, int32_t y, char *s, uint32_t colidx)
{
	size_t sl = strlen(s);

	put_string(x - (sl / 2) * font_vga_8x8.width,
		   y - font_vga_8x8.height / 2, s, colidx);
}

void setcolor(uint32_t colidx, uint32_t value)
{
	uint32_t res;
	uint16_t red, green, blue;
	struct fb_cmap cmap;

	if (colidx > 255) {
#ifdef DEBUG
		fprintf(stderr, "WARNING: color index = %u, must be <256\n",
			colidx);
#endif
		return;
	}

	switch (bytes_per_pixel) {
	default:
	case 1:
		res = colidx;
		red = (value >> 8) & 0xff00;
		green = value & 0xff00;
		blue = (value << 8) & 0xff00;
		cmap.start = colidx;
		cmap.len = 1;
		cmap.red = &red;
		cmap.green = &green;
		cmap.blue = &blue;
		cmap.transp = NULL;

		if (ioctl(fb_fd, FBIOPUTCMAP, &cmap) < 0)
			perror("ioctl FBIOPUTCMAP");
		break;
	case 2:
	case 3:
	case 4:
		red = (value >> 16) & 0xff;
		green = (value >> 8) & 0xff;
		blue = value & 0xff;
		res = ((red >> (8 - var.red.length)) << var.red.offset) |
		      ((green >> (8 - var.green.length)) << var.green.offset) |
		      ((blue >> (8 - var.blue.length)) << var.blue.offset);
	}
	colormap[colidx] = res;
}

static void __pixel_loc(int32_t x, int32_t y, union multiptr *loc)
{
	switch (rotation) {
	case 0:
	default:
		loc->p8 = line_addr[y] + x * bytes_per_pixel;
		break;
	case 1:
		loc->p8 = line_addr[x] + (yres - y - 1) * bytes_per_pixel;
		break;
	case 2:
		loc->p8 = line_addr[yres - y - 1] + (xres - x - 1) * bytes_per_pixel;
		break;
	case 3:
		loc->p8 = line_addr[xres - x - 1] + y * bytes_per_pixel;
		break;
	}
}

static inline void __setpixel(union multiptr loc, uint32_t xormode, uint32_t color)
{
	switch (bytes_per_pixel) {
	case 1:
	default:
		if (xormode)
			*loc.p8 ^= color;
		else
			*loc.p8 = color;
		*loc.p8 |= transp_mask;
		break;
	case 2:
		if (xormode)
			*loc.p16 ^= color;
		else
			*loc.p16 = color;
		*loc.p16 |= transp_mask;
		break;
	case 3:
		if (xormode) {
			*loc.p8++ ^= (color >> 16) & 0xff;
			*loc.p8++ ^= (color >> 8) & 0xff;
			*loc.p8 ^= color & 0xff;
		} else {
			*loc.p8++ = (color >> 16) & 0xff;
			*loc.p8++ = (color >> 8) & 0xff;
			*loc.p8 = color & 0xff;
		}
		*loc.p8 |= transp_mask;
		break;
	case 4:
		if (xormode)
			*loc.p32 ^= color;
		else
			*loc.p32 = color;
		*loc.p32 |= transp_mask;
		break;
	}
}

void pixel(int32_t x, int32_t y, uint32_t colidx)
{
	uint32_t xormode;
	union multiptr loc;

	if ((x < 0) || ((uint32_t)x >= xres) ||
	    (y < 0) || ((uint32_t)y >= yres))
		return;

	xormode = colidx & XORMODE;
	colidx &= ~XORMODE;

	if (colidx > 255) {
#ifdef DEBUG
		fprintf(stderr, "WARNING: color value = %u, must be <256\n",
			colidx);
#endif
		return;
	}

	__pixel_loc(x, y, &loc);
	__setpixel(loc, xormode, colormap[colidx]);
}

void line(int32_t x1, int32_t y1, int32_t x2, int32_t y2, uint32_t colidx)
{
	int32_t tmp;
	int32_t dx = x2 - x1;
	int32_t dy = y2 - y1;

	if (abs(dx) < abs(dy)) {
		if (y1 > y2) {
			tmp = x1; x1 = x2; x2 = tmp;
			tmp = y1; y1 = y2; y2 = tmp;
			dx = -dx; dy = -dy;
		}
		x1 <<= 16;
		/* dy is apriori >0 */
		dx = (dx << 16) / dy;
		while (y1 <= y2) {
			pixel(x1 >> 16, y1, colidx);
			x1 += dx;
			y1++;
		}
	} else {
		if (x1 > x2) {
			tmp = x1; x1 = x2; x2 = tmp;
			tmp = y1; y1 = y2; y2 = tmp;
			dx = -dx; dy = -dy;
		}
		y1 <<= 16;
		dy = dx ? (dy << 16) / dx : 0;
		while (x1 <= x2) {
			pixel(x1, y1 >> 16, colidx);
			y1 += dy;
			x1++;
		}
	}
}

void rect(int32_t x1, int32_t y1, int32_t x2, int32_t y2, uint32_t colidx)
{
	line(x1, y1, x2, y1, colidx);
	line(x2, y1+1, x2, y2-1, colidx);
	line(x2, y2, x1, y2, colidx);
	line(x1, y2-1, x1, y1+1, colidx);
}

void fillrect(int32_t x1, int32_t y1, int32_t x2, int32_t y2, uint32_t colidx)
{
	int32_t tmp;
	uint32_t xormode;
	union multiptr loc;

	/* Clipping and sanity checking */
	if (x1 > x2) { tmp = x1; x1 = x2; x2 = tmp; }
	if (y1 > y2) { tmp = y1; y1 = y2; y2 = tmp; }

	if (x1 < 0)
		x1 = 0;
	if ((uint32_t)x1 >= xres)
		x1 = xres - 1;

	if (x2 < 0)
		x2 = 0;
	if ((uint32_t)x2 >= xres)
		x2 = xres - 1;

	if (y1 < 0)
		y1 = 0;
	if ((uint32_t)y1 >= yres)
		y1 = yres - 1;

	if (y2 < 0)
		y2 = 0;
	if ((uint32_t)y2 >= yres)
		y2 = yres - 1;

	if ((x1 > x2) || (y1 > y2))
		return;

	xormode = colidx & XORMODE;
	colidx &= ~XORMODE;

	if (colidx > 255) {
#ifdef DEBUG
		fprintf(stderr, "WARNING: color value = %u, must be <256\n",
			colidx);
#endif
		return;
	}

	colidx = colormap[colidx];

	for (; y1 <= y2; y1++) {
		for (tmp = x1; tmp <= x2; tmp++) {
			__pixel_loc(tmp, y1, &loc);
			__setpixel(loc, xormode, colidx);
			loc.p8 += bytes_per_pixel;
		}
	}
}


<|start_filename|>3rdpart/ethercat-1.5.2/master/slave.h<|end_filename|>
/******************************************************************************
 *
 *  $Id: slave.h,v ec403cf308eb 2013/02/12 14:46:43 fp $
 *
 *  Copyright (C) 2006-2012  <NAME>, Ingenieurgemeinschaft IgH
 *
 *  This file is part of the IgH EtherCAT Master.
 *
 *  The IgH EtherCAT Master is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License version 2, as
 *  published by the Free Software Foundation.
 *
 *  The IgH EtherCAT Master is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 *  Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with the IgH EtherCAT Master; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 *****************************************************************************/

/**
   \file
   EtherCAT slave structure.
*/

/*****************************************************************************/

#ifndef __EC_SLAVE_H__
#define __EC_SLAVE_H__

#include <linux/list.h>
#include <linux/kobject.h>

#include "globals.h"
#include "datagram.h"
#include "pdo.h"
#include "sync.h"
#include "sdo.h"
#include "fsm_slave.h"

/*****************************************************************************/

/** Convenience macro for printing slave-specific information to syslog.
 *
 * This will print the message in \a fmt with a prefixed
 * "EtherCAT <INDEX>-<POSITION>: ", where INDEX is the master index and
 * POSITION is the slave's ring position.
 *
 * \param slave EtherCAT slave
 * \param fmt format string (like in printf())
 * \param args arguments (optional)
 */
#define EC_SLAVE_INFO(slave, fmt, args...) \
    printk(KERN_INFO "EtherCAT %u-%u: " fmt, slave->master->index, \
            slave->ring_position, ##args)

/** Convenience macro for printing slave-specific errors to syslog.
 *
 * This will print the message in \a fmt with a prefixed
 * "EtherCAT <INDEX>-<POSITION>: ", where INDEX is the master index and
 * POSITION is the slave's ring position.
 *
 * \param slave EtherCAT slave
 * \param fmt format string (like in printf())
 * \param args arguments (optional)
 */
#define EC_SLAVE_ERR(slave, fmt, args...) \
    printk(KERN_ERR "EtherCAT ERROR %u-%u: " fmt, slave->master->index, \
            slave->ring_position, ##args)

/** Convenience macro for printing slave-specific warnings to syslog.
 *
 * This will print the message in \a fmt with a prefixed
 * "EtherCAT <INDEX>-<POSITION>: ", where INDEX is the master index and
 * POSITION is the slave's ring position.
 *
 * \param slave EtherCAT slave
 * \param fmt format string (like in printf())
 * \param args arguments (optional)
 */
#define EC_SLAVE_WARN(slave, fmt, args...) \
    printk(KERN_WARNING "EtherCAT WARNING %u-%u: " fmt, \
            slave->master->index, slave->ring_position, ##args)

/** Convenience macro for printing slave-specific debug messages to syslog.
 *
 * This will print the message in \a fmt with a prefixed
 * "EtherCAT <INDEX>-<POSITION>: ", where INDEX is the master index and
 * POSITION is the slave's ring position.
 *
 * \param slave EtherCAT slave
 * \param level Debug level. Master's debug level must be >= \a level for
 * output.
 * \param fmt format string (like in printf())
 * \param args arguments (optional)
 */
#define EC_SLAVE_DBG(slave, level, fmt, args...) \
    do { \
        if (slave->master->debug_level >= level) { \
            printk(KERN_DEBUG "EtherCAT DEBUG %u-%u: " fmt, \
                    slave->master->index, slave->ring_position, ##args); \
        } \
    } while (0)

/*****************************************************************************/

/** Slave port.
 */
typedef struct {
    ec_slave_port_desc_t desc; /**< Port descriptors. */
    ec_slave_port_link_t link; /**< Port link status. */
    ec_slave_t *next_slave; /**< Connected slaves. */
    uint32_t receive_time; /**< Port receive times for delay
                                            measurement. */
    uint32_t delay_to_next_dc; /**< Delay to next slave with DC support behind
                                 this port [ns]. */
} ec_slave_port_t;

/*****************************************************************************/

/** Slave information interface data.
 */
typedef struct {
    // Non-category data
    uint16_t alias; /**< Configured station alias. */
    uint32_t vendor_id; /**< Vendor ID. */
    uint32_t product_code; /**< Vendor-specific product code. */
    uint32_t revision_number; /**< Revision number. */
    uint32_t serial_number; /**< Serial number. */
    uint16_t boot_rx_mailbox_offset; /**< Bootstrap receive mailbox address. */
    uint16_t boot_rx_mailbox_size; /**< Bootstrap receive mailbox size. */
    uint16_t boot_tx_mailbox_offset; /**< Bootstrap transmit mailbox address. */
    uint16_t boot_tx_mailbox_size; /**< Bootstrap transmit mailbox size. */
    uint16_t std_rx_mailbox_offset; /**< Standard receive mailbox address. */
    uint16_t std_rx_mailbox_size; /**< Standard receive mailbox size. */
    uint16_t std_tx_mailbox_offset; /**< Standard transmit mailbox address. */
    uint16_t std_tx_mailbox_size; /**< Standard transmit mailbox size. */
    uint16_t mailbox_protocols; /**< Supported mailbox protocols. */

    // Strings
    char **strings; /**< Strings in SII categories. */
    unsigned int string_count; /**< Number of SII strings. */

    // General
    unsigned int has_general; /**< General category present. */
    char *group; /**< Group name. */
    char *image; /**< Image name. */
    char *order; /**< Order number. */
    char *name; /**< Slave name. */
    uint8_t physical_layer[EC_MAX_PORTS]; /**< Port media. */
    ec_sii_coe_details_t coe_details; /**< CoE detail flags. */
    ec_sii_general_flags_t general_flags; /**< General flags. */
    int16_t current_on_ebus; /**< Power consumption in mA. */

    // SyncM
    ec_sync_t *syncs; /**< SYNC MANAGER categories. */
    unsigned int sync_count; /**< Number of sync managers. */

    // [RT]XPDO
    struct list_head pdos; /**< SII [RT]XPDO categories. */
} ec_sii_t;

/*****************************************************************************/

/** EtherCAT slave.
 */
struct ec_slave
{
    ec_master_t *master; /**< Master owning the slave. */
    ec_device_index_t device_index; /**< Index of device the slave responds
                                      on. */

    // addresses
    uint16_t ring_position; /**< Ring position. */
    uint16_t station_address; /**< Configured station address. */
    uint16_t effective_alias; /**< Effective alias address. */

    ec_slave_port_t ports[EC_MAX_PORTS]; /**< Ports. */

    // configuration
    ec_slave_config_t *config; /**< Current configuration. */
    ec_slave_state_t requested_state; /**< Requested application state. */
    ec_slave_state_t current_state; /**< Current application state. */
    unsigned int error_flag; /**< Stop processing after an error. */
    unsigned int force_config; /**< Force (re-)configuration. */
    uint16_t configured_rx_mailbox_offset; /**< Configured receive mailbox
                                             offset. */
    uint16_t configured_rx_mailbox_size; /**< Configured receive mailbox size.
                                          */
    uint16_t configured_tx_mailbox_offset; /**< Configured send mailbox
                                             offset. */
    uint16_t configured_tx_mailbox_size; /**< Configured send mailbox size. */

    // base data
    uint8_t base_type; /**< Slave type. */
    uint8_t base_revision; /**< Revision. */
    uint16_t base_build; /**< Build number. */
    uint8_t base_fmmu_count; /**< Number of supported FMMUs. */
    uint8_t base_sync_count; /**< Number of supported sync managers. */
    uint8_t base_fmmu_bit_operation; /**< FMMU bit operation is supported. */
    uint8_t base_dc_supported; /**< Distributed clocks are supported. */
    ec_slave_dc_range_t base_dc_range; /**< DC range. */
    uint8_t has_dc_system_time; /**< The slave supports the DC system time
                                  register. Otherwise it can only be used for
                                  delay measurement. */
    uint32_t transmission_delay; /**< DC system time transmission delay
                                   (offset from reference clock). */

    // SII
    uint16_t *sii_words; /**< Complete SII image. */
    size_t sii_nwords; /**< Size of the SII contents in words. */

    // Slave information interface
    ec_sii_t sii; /**< Extracted SII data. */

    struct list_head sdo_dictionary; /**< SDO dictionary list */
    uint8_t sdo_dictionary_fetched; /**< Dictionary has been fetched. */
    unsigned long jiffies_preop; /**< Time, the slave went to PREOP. */

    struct list_head sdo_requests; /**< SDO access requests. */
    struct list_head reg_requests; /**< Register access requests. */
    struct list_head foe_requests; /**< FoE write requests. */
    struct list_head soe_requests; /**< SoE write requests. */

    ec_fsm_slave_t fsm; /**< Slave state machine. */
};

/*****************************************************************************/

// slave construction/destruction
void ec_slave_init(ec_slave_t *, ec_master_t *, ec_device_index_t,
        uint16_t, uint16_t);
void ec_slave_clear(ec_slave_t *);

void ec_slave_clear_sync_managers(ec_slave_t *);

void ec_slave_request_state(ec_slave_t *, ec_slave_state_t);
void ec_slave_set_state(ec_slave_t *, ec_slave_state_t);

// SII categories
int ec_slave_fetch_sii_strings(ec_slave_t *, const uint8_t *, size_t);
int ec_slave_fetch_sii_general(ec_slave_t *, const uint8_t *, size_t);
int ec_slave_fetch_sii_syncs(ec_slave_t *, const uint8_t *, size_t);
int ec_slave_fetch_sii_pdos(ec_slave_t *, const uint8_t *, size_t,
        ec_direction_t);

// misc.
ec_sync_t *ec_slave_get_sync(ec_slave_t *, uint8_t);

void ec_slave_sdo_dict_info(const ec_slave_t *,
        unsigned int *, unsigned int *);
ec_sdo_t *ec_slave_get_sdo(ec_slave_t *, uint16_t);
const ec_sdo_t *ec_slave_get_sdo_const(const ec_slave_t *, uint16_t);
const ec_sdo_t *ec_slave_get_sdo_by_pos_const(const ec_slave_t *, uint16_t);
uint16_t ec_slave_sdo_count(const ec_slave_t *);
const ec_pdo_t *ec_slave_find_pdo(const ec_slave_t *, uint16_t);
void ec_slave_attach_pdo_names(ec_slave_t *);

void ec_slave_calc_port_delays(ec_slave_t *);
void ec_slave_calc_transmission_delays_rec(ec_slave_t *, uint32_t *);

/*****************************************************************************/

#endif


<|start_filename|>3rdpart/ethercat-1.5.2/master/fsm_soe.c<|end_filename|>
/******************************************************************************
 *
 *  $Id: fsm_soe.c,v 9cdd7669dc0b 2013/01/10 16:36:41 fp $
 *
 *  Copyright (C) 2006-2008  <NAME>, Ingenieurgemeinschaft IgH
 *
 *  This file is part of the IgH EtherCAT Master.
 *
 *  The IgH EtherCAT Master is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License version 2, as
 *  published by the Free Software Foundation.
 *
 *  The IgH EtherCAT Master is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 *  Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with the IgH EtherCAT Master; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 *****************************************************************************/

/**
   \file
   EtherCAT SoE state machines.
*/

/*****************************************************************************/

#include "globals.h"
#include "master.h"
#include "mailbox.h"
#include "fsm_soe.h"

/*****************************************************************************/

/** Mailbox type for SoE.
 */
#define EC_MBOX_TYPE_SOE 0x05

/** SoE operations
 */
enum ec_soe_opcodes {
    OPCODE_READ_REQUEST   = 0x01, /**< Read request. */
    OPCODE_READ_RESPONSE  = 0x02, /**< Read response. */
    OPCODE_WRITE_REQUEST  = 0x03, /**< Write request. */
    OPCODE_WRITE_RESPONSE = 0x04  /**< Write response. */
};

/** Size of all SoE headers.
 */
#define EC_SOE_SIZE 0x04

/** SoE response timeout [ms].
 */
#define EC_SOE_RESPONSE_TIMEOUT 1000

/*****************************************************************************/

void ec_fsm_soe_read_start(ec_fsm_soe_t *, ec_datagram_t *);
void ec_fsm_soe_read_request(ec_fsm_soe_t *, ec_datagram_t *);
void ec_fsm_soe_read_check(ec_fsm_soe_t *, ec_datagram_t *);
void ec_fsm_soe_read_response(ec_fsm_soe_t *, ec_datagram_t *);

void ec_fsm_soe_write_start(ec_fsm_soe_t *, ec_datagram_t *);
void ec_fsm_soe_write_request(ec_fsm_soe_t *, ec_datagram_t *);
void ec_fsm_soe_write_check(ec_fsm_soe_t *, ec_datagram_t *);
void ec_fsm_soe_write_response(ec_fsm_soe_t *, ec_datagram_t *);

void ec_fsm_soe_end(ec_fsm_soe_t *, ec_datagram_t *);
void ec_fsm_soe_error(ec_fsm_soe_t *, ec_datagram_t *);

/*****************************************************************************/

extern const ec_code_msg_t soe_error_codes[];

/*****************************************************************************/

/** Outputs an SoE error code.
*/
void ec_print_soe_error(const ec_slave_t *slave, uint16_t error_code)
{
    const ec_code_msg_t *error_msg;

    for (error_msg = soe_error_codes; error_msg->code; error_msg++) {
        if (error_msg->code == error_code) {
            EC_SLAVE_ERR(slave, "SoE error 0x%04X: \"%s\".\n",
                   error_msg->code, error_msg->message);
            return;
        }
    }

    EC_SLAVE_ERR(slave, "Unknown SoE error 0x%04X.\n", error_code);
}

/*****************************************************************************/

/** Constructor.
 */
void ec_fsm_soe_init(
        ec_fsm_soe_t *fsm /**< finite state machine */
        )
{
    fsm->state = NULL;
    fsm->datagram = NULL;
    fsm->fragment_size = 0;
}

/*****************************************************************************/

/** Destructor.
 */
void ec_fsm_soe_clear(
        ec_fsm_soe_t *fsm /**< finite state machine */
        )
{
}

/*****************************************************************************/

/** Starts to transfer an IDN to/from a slave.
 */
void ec_fsm_soe_transfer(
        ec_fsm_soe_t *fsm, /**< State machine. */
        ec_slave_t *slave, /**< EtherCAT slave. */
        ec_soe_request_t *request /**< SoE request. */
        )
{
    fsm->slave = slave;
    fsm->request = request;

    if (request->dir == EC_DIR_OUTPUT) {
        fsm->state = ec_fsm_soe_write_start;
    } else {
        fsm->state = ec_fsm_soe_read_start;
    }
}

/*****************************************************************************/

/** Executes the current state of the state machine.
 *
 * \return 1 if the datagram was used, else 0.
 */
int ec_fsm_soe_exec(
        ec_fsm_soe_t *fsm, /**< finite state machine */
        ec_datagram_t *datagram /**< Datagram to use. */
        )
{
    int datagram_used = 0;

    if (fsm->datagram &&
            (fsm->datagram->state == EC_DATAGRAM_INIT ||
             fsm->datagram->state == EC_DATAGRAM_QUEUED ||
             fsm->datagram->state == EC_DATAGRAM_SENT)) {
        // datagram not received yet
        return datagram_used;
    }

    fsm->state(fsm, datagram);

    datagram_used =
        fsm->state != ec_fsm_soe_end && fsm->state != ec_fsm_soe_error;

    if (datagram_used) {
        fsm->datagram = datagram;
    } else {
        fsm->datagram = NULL;
    }

    return datagram_used;
}

/*****************************************************************************/

/** Returns, if the state machine terminated with success.
 *
 * \return non-zero if successful.
 */
int ec_fsm_soe_success(const ec_fsm_soe_t *fsm /**< Finite state machine */)
{
    return fsm->state == ec_fsm_soe_end;
}

/*****************************************************************************/

/** Output information about a failed SoE transfer.
 */
void ec_fsm_soe_print_error(ec_fsm_soe_t *fsm /**< Finite state machine */)
{
    ec_soe_request_t *request = fsm->request;

    EC_SLAVE_ERR(fsm->slave, "");

    if (request->dir == EC_DIR_OUTPUT) {
        printk("Writing");
    } else {
        printk("Reading");
    }

    printk(" IDN 0x%04X failed.\n", request->idn);
}

/******************************************************************************
 * SoE read state machine
 *****************************************************************************/

/** Prepare a read operation.
 *
 * \return 0 on success, otherwise a negative error code.
 */
int ec_fsm_soe_prepare_read(
        ec_fsm_soe_t *fsm, /**< finite state machine */
        ec_datagram_t *datagram /**< Datagram to use. */
        )
{
    uint8_t *data;
    ec_slave_t *slave = fsm->slave;
    ec_master_t *master = slave->master;
    ec_soe_request_t *request = fsm->request;

    data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_SOE,
            EC_SOE_SIZE);
    if (IS_ERR(data)) {
        return PTR_ERR(data);
    }

    EC_WRITE_U8(data, OPCODE_READ_REQUEST | (request->drive_no & 0x07) << 5);
    EC_WRITE_U8(data + 1, 1 << 6); // request value
    EC_WRITE_U16(data + 2, request->idn);

    if (master->debug_level) {
        EC_SLAVE_DBG(slave, 0, "SCC read request:\n");
        ec_print_data(data, EC_SOE_SIZE);
    }

    fsm->request->jiffies_sent = jiffies;
    fsm->state = ec_fsm_soe_read_request;

    return 0;
}

/*****************************************************************************/

/** SoE state: READ START.
 */
void ec_fsm_soe_read_start(
        ec_fsm_soe_t *fsm, /**< finite state machine */
        ec_datagram_t *datagram /**< Datagram to use. */
        )
{
    ec_slave_t *slave = fsm->slave;
    ec_soe_request_t *request = fsm->request;

    EC_SLAVE_DBG(slave, 1, "Reading IDN 0x%04X of drive %u.\n", request->idn,
            request->drive_no);

    if (!(slave->sii.mailbox_protocols & EC_MBOX_SOE)) {
        EC_SLAVE_ERR(slave, "Slave does not support SoE!\n");
        fsm->state = ec_fsm_soe_error;
        ec_fsm_soe_print_error(fsm);
        return;
    }

    request->data_size = 0;
    fsm->retries = EC_FSM_RETRIES;

    if (ec_fsm_soe_prepare_read(fsm, datagram)) {
        fsm->state = ec_fsm_soe_error;
        ec_fsm_soe_print_error(fsm);
    }
}

/*****************************************************************************/

/** SoE state: READ REQUEST.
 */
void ec_fsm_soe_read_request(
        ec_fsm_soe_t *fsm, /**< finite state machine */
        ec_datagram_t *datagram /**< Datagram to use. */
        )
{
    ec_slave_t *slave = fsm->slave;
    unsigned long diff_ms;

    if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
        if (ec_fsm_soe_prepare_read(fsm, datagram)) {
            fsm->state = ec_fsm_soe_error;
            ec_fsm_soe_print_error(fsm);
        }
        return;
    }

    if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
        fsm->state = ec_fsm_soe_error;
        EC_SLAVE_ERR(slave, "Failed to receive SoE read request: ");
        ec_datagram_print_state(fsm->datagram);
        ec_fsm_soe_print_error(fsm);
        return;
    }

    diff_ms = (jiffies - fsm->request->jiffies_sent) * 1000 / HZ;

    if (fsm->datagram->working_counter != 1) {
        if (!fsm->datagram->working_counter) {
            if (diff_ms < EC_SOE_RESPONSE_TIMEOUT) {
                // no response; send request datagram again
                if (ec_fsm_soe_prepare_read(fsm, datagram)) {
                    fsm->state = ec_fsm_soe_error;
                    ec_fsm_soe_print_error(fsm);
                }
                return;
            }
        }
        fsm->state = ec_fsm_soe_error;
        EC_SLAVE_ERR(slave, "Reception of SoE read request"
                " failed after %lu ms: ", diff_ms);
        ec_datagram_print_wc_error(fsm->datagram);
        ec_fsm_soe_print_error(fsm);
        return;
    }

    fsm->jiffies_start = fsm->datagram->jiffies_sent;
    ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
    fsm->retries = EC_FSM_RETRIES;
    fsm->state = ec_fsm_soe_read_check;
}

/*****************************************************************************/

/** CoE state: READ CHECK.
 */
void ec_fsm_soe_read_check(
        ec_fsm_soe_t *fsm, /**< finite state machine */
        ec_datagram_t *datagram /**< Datagram to use. */
        )
{
    ec_slave_t *slave = fsm->slave;

    if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
        ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
        return;
    }

    if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
        fsm->state = ec_fsm_soe_error;
        EC_SLAVE_ERR(slave, "Failed to receive SoE mailbox check datagram: ");
        ec_datagram_print_state(fsm->datagram);
        ec_fsm_soe_print_error(fsm);
        return;
    }

    if (fsm->datagram->working_counter != 1) {
        fsm->state = ec_fsm_soe_error;
        EC_SLAVE_ERR(slave, "Reception of SoE mailbox check"
                " datagram failed: ");
        ec_datagram_print_wc_error(fsm->datagram);
        ec_fsm_soe_print_error(fsm);
        return;
    }

    if (!ec_slave_mbox_check(fsm->datagram)) {
        unsigned long diff_ms =
            (fsm->datagram->jiffies_received - fsm->jiffies_start) *
            1000 / HZ;
        if (diff_ms >= EC_SOE_RESPONSE_TIMEOUT) {
            fsm->state = ec_fsm_soe_error;
            EC_SLAVE_ERR(slave, "Timeout after %lu ms while waiting for"
                    " read response.\n", diff_ms);
            ec_fsm_soe_print_error(fsm);
            return;
        }

        ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
        fsm->retries = EC_FSM_RETRIES;
        return;
    }

    // Fetch response
    ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
    fsm->retries = EC_FSM_RETRIES;
    fsm->state = ec_fsm_soe_read_response;
}

/*****************************************************************************/

/** SoE state: READ RESPONSE.
 */
void ec_fsm_soe_read_response(
        ec_fsm_soe_t *fsm, /**< finite state machine */
        ec_datagram_t *datagram /**< Datagram to use. */
        )
{
    ec_slave_t *slave = fsm->slave;
    ec_master_t *master = slave->master;
    uint8_t *data, mbox_prot, header, opcode, incomplete, error_flag,
            value_included;
    size_t rec_size, data_size;
    ec_soe_request_t *req = fsm->request;

    if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
        ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
        return;
    }

    if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
        fsm->state = ec_fsm_soe_error;
        EC_SLAVE_ERR(slave, "Failed to receive SoE read response datagram: ");
        ec_datagram_print_state(fsm->datagram);
        ec_fsm_soe_print_error(fsm);
        return;
    }

    if (fsm->datagram->working_counter != 1) {
        fsm->state = ec_fsm_soe_error;
        EC_SLAVE_ERR(slave, "Reception of SoE read response failed: ");
        ec_datagram_print_wc_error(fsm->datagram);
        ec_fsm_soe_print_error(fsm);
        return;
    }

    data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
    if (IS_ERR(data)) {
        fsm->state = ec_fsm_soe_error;
        ec_fsm_soe_print_error(fsm);
        return;
    }

    if (master->debug_level) {
        EC_SLAVE_DBG(slave, 0, "SCC read response:\n");
        ec_print_data(data, rec_size);
    }

    if (mbox_prot != EC_MBOX_TYPE_SOE) {
        fsm->state = ec_fsm_soe_error;
        EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
                mbox_prot);
        ec_fsm_soe_print_error(fsm);
        return;
    }

    if (rec_size < EC_SOE_SIZE) {
        fsm->state = ec_fsm_soe_error;
        EC_SLAVE_ERR(slave, "Received currupted SoE read response"
                " (%zu bytes)!\n", rec_size);
        ec_print_data(data, rec_size);
        ec_fsm_soe_print_error(fsm);
        return;
    }

    header = EC_READ_U8(data);
    opcode = header & 0x7;
    incomplete = (header >> 3) & 1;
    error_flag = (header >> 4) & 1;

    if (opcode != OPCODE_READ_RESPONSE) {
        EC_SLAVE_ERR(slave, "Received no read response (opcode %x).\n",
                opcode);
        ec_print_data(data, rec_size);
        ec_fsm_soe_print_error(fsm);
        fsm->state = ec_fsm_soe_error;
        return;
    }

    if (error_flag) {
        req->error_code = EC_READ_U16(data + rec_size - 2);
        EC_SLAVE_ERR(slave, "Received error response:\n");
        ec_print_soe_error(slave, req->error_code);
        ec_fsm_soe_print_error(fsm);
        fsm->state = ec_fsm_soe_error;
        return;
    } else {
        req->error_code = 0x0000;
    }

    value_included = (EC_READ_U8(data + 1) >> 6) & 1;
    if (!value_included) {
        EC_SLAVE_ERR(slave, "No value included!\n");
        ec_fsm_soe_print_error(fsm);
        fsm->state = ec_fsm_soe_error;
        return;
    }

    data_size = rec_size - EC_SOE_SIZE;
    if (ec_soe_request_append_data(req,
                data + EC_SOE_SIZE, data_size)) {
        fsm->state = ec_fsm_soe_error;
        ec_fsm_soe_print_error(fsm);
        return;
    }

    if (incomplete) {
        EC_SLAVE_DBG(slave, 1, "SoE data incomplete. Waiting for fragment"
                " at offset %zu.\n", req->data_size);
        fsm->jiffies_start = fsm->datagram->jiffies_sent;
        ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
        fsm->retries = EC_FSM_RETRIES;
        fsm->state = ec_fsm_soe_read_check;
    } else {
        if (master->debug_level) {
            EC_SLAVE_DBG(slave, 0, "IDN data:\n");
            ec_print_data(req->data, req->data_size);
        }

        fsm->state = ec_fsm_soe_end; // success
    }
}

/******************************************************************************
 * SoE write state machine
 *****************************************************************************/

/** Write next fragment.
 */
void ec_fsm_soe_write_next_fragment(
        ec_fsm_soe_t *fsm, /**< finite state machine */
        ec_datagram_t *datagram /**< Datagram to use. */
        )
{
    ec_slave_t *slave = fsm->slave;
    ec_master_t *master = slave->master;
    ec_soe_request_t *req = fsm->request;
    uint8_t incomplete, *data;
    size_t header_size, max_fragment_size, remaining_size;
    uint16_t fragments_left;

    header_size = EC_MBOX_HEADER_SIZE + EC_SOE_SIZE;
    if (slave->configured_rx_mailbox_size <= header_size) {
        EC_SLAVE_ERR(slave, "Mailbox size (%u) too small for SoE write.\n",
                slave->configured_rx_mailbox_size);
        fsm->state = ec_fsm_soe_error;
        ec_fsm_soe_print_error(fsm);
        return;
    }

    remaining_size = req->data_size - fsm->offset;
    max_fragment_size = slave->configured_rx_mailbox_size - header_size;
    incomplete = remaining_size > max_fragment_size;
    fsm->fragment_size = incomplete ? max_fragment_size : remaining_size;
    fragments_left = remaining_size / fsm->fragment_size - 1;
    if (remaining_size % fsm->fragment_size) {
        fragments_left++;
    }

    data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_SOE,
            EC_SOE_SIZE + fsm->fragment_size);
    if (IS_ERR(data)) {
        fsm->state = ec_fsm_soe_error;
        ec_fsm_soe_print_error(fsm);
        return;
    }

    EC_WRITE_U8(data, OPCODE_WRITE_REQUEST | incomplete << 3 |
            (req->drive_no & 0x07) << 5);
    EC_WRITE_U8(data + 1, 1 << 6); // only value included
    EC_WRITE_U16(data + 2, incomplete ? fragments_left : req->idn);
    memcpy(data + 4, req->data + fsm->offset, fsm->fragment_size);

    if (master->debug_level) {
        EC_SLAVE_DBG(slave, 0, "SCC write request:\n");
        ec_print_data(data, EC_SOE_SIZE + fsm->fragment_size);
    }

    req->jiffies_sent = jiffies;
    fsm->state = ec_fsm_soe_write_request;
}

/*****************************************************************************/

/** SoE state: WRITE START.
 */
void ec_fsm_soe_write_start(
        ec_fsm_soe_t *fsm, /**< finite state machine */
        ec_datagram_t *datagram /**< Datagram to use. */
        )
{
    ec_slave_t *slave = fsm->slave;
    ec_soe_request_t *req = fsm->request;

    EC_SLAVE_DBG(slave, 1, "Writing IDN 0x%04X of drive %u (%zu byte).\n",
            req->idn, req->drive_no, req->data_size);

    if (!(slave->sii.mailbox_protocols & EC_MBOX_SOE)) {
        EC_SLAVE_ERR(slave, "Slave does not support SoE!\n");
        fsm->state = ec_fsm_soe_error;
        ec_fsm_soe_print_error(fsm);
        return;
    }

    fsm->offset = 0;
    fsm->retries = EC_FSM_RETRIES;
    ec_fsm_soe_write_next_fragment(fsm, datagram);
}

/*****************************************************************************/

/** SoE state: WRITE REQUEST.
 */
void ec_fsm_soe_write_request(
        ec_fsm_soe_t *fsm, /**< finite state machine */
        ec_datagram_t *datagram /**< Datagram to use. */
        )
{
    ec_slave_t *slave = fsm->slave;
    unsigned long diff_ms;

    if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
        ec_fsm_soe_write_next_fragment(fsm, datagram);
        return;
    }

    if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
        fsm->state = ec_fsm_soe_error;
        EC_SLAVE_ERR(slave, "Failed to receive SoE write request: ");
        ec_datagram_print_state(fsm->datagram);
        ec_fsm_soe_print_error(fsm);
        return;
    }

    diff_ms = (jiffies - fsm->request->jiffies_sent) * 1000 / HZ;

    if (fsm->datagram->working_counter != 1) {
        if (!fsm->datagram->working_counter) {
            if (diff_ms < EC_SOE_RESPONSE_TIMEOUT) {
                // no response; send request datagram again
                ec_fsm_soe_write_next_fragment(fsm, datagram);
                return;
            }
        }
        fsm->state = ec_fsm_soe_error;
        EC_SLAVE_ERR(slave, "Reception of SoE write request"
                " failed after %lu ms: ", diff_ms);
        ec_datagram_print_wc_error(fsm->datagram);
        ec_fsm_soe_print_error(fsm);
        return;
    }

    fsm->jiffies_start = fsm->datagram->jiffies_sent;

    ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
    fsm->retries = EC_FSM_RETRIES;
    fsm->state = ec_fsm_soe_write_check;
}

/*****************************************************************************/

/** CoE state: WRITE CHECK.
 */
void ec_fsm_soe_write_check(
        ec_fsm_soe_t *fsm, /**< finite state machine */
        ec_datagram_t *datagram /**< Datagram to use. */
        )
{
    ec_slave_t *slave = fsm->slave;

    if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
        ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
        return;
    }

    if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
        fsm->state = ec_fsm_soe_error;
        EC_SLAVE_ERR(slave, "Failed to receive SoE write request datagram: ");
        ec_datagram_print_state(fsm->datagram);
        ec_fsm_soe_print_error(fsm);
        return;
    }

    if (fsm->datagram->working_counter != 1) {
        fsm->state = ec_fsm_soe_error;
        EC_SLAVE_ERR(slave, "Reception of SoE write request datagram: ");
        ec_datagram_print_wc_error(fsm->datagram);
        ec_fsm_soe_print_error(fsm);
        return;
    }

    if (!ec_slave_mbox_check(fsm->datagram)) {
        unsigned long diff_ms =
            (datagram->jiffies_received - fsm->jiffies_start) * 1000 / HZ;
        if (diff_ms >= EC_SOE_RESPONSE_TIMEOUT) {
            fsm->state = ec_fsm_soe_error;
            EC_SLAVE_ERR(slave, "Timeout after %lu ms while waiting"
                    " for write response.\n", diff_ms);
            ec_fsm_soe_print_error(fsm);
            return;
        }

        ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
        fsm->retries = EC_FSM_RETRIES;
        return;
    }

    // Fetch response
    ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
    fsm->retries = EC_FSM_RETRIES;
    fsm->state = ec_fsm_soe_write_response;
}

/*****************************************************************************/

/** SoE state: WRITE RESPONSE.
 */
void ec_fsm_soe_write_response(
        ec_fsm_soe_t *fsm, /**< finite state machine */
        ec_datagram_t *datagram /**< Datagram to use. */
        )
{
    ec_slave_t *slave = fsm->slave;
    ec_master_t *master = slave->master;
    ec_soe_request_t *req = fsm->request;
    uint8_t *data, mbox_prot, opcode, error_flag;
    uint16_t idn;
    size_t rec_size;

    if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
        ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
        return; // FIXME: request again?
    }

    if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
        fsm->state = ec_fsm_soe_error;
        EC_SLAVE_ERR(slave, "Failed to receive SoE write"
                " response datagram: ");
        ec_datagram_print_state(fsm->datagram);
        ec_fsm_soe_print_error(fsm);
        return;
    }

    if (fsm->datagram->working_counter != 1) {
        fsm->state = ec_fsm_soe_error;
        EC_SLAVE_ERR(slave, "Reception of SoE write response failed: ");
        ec_datagram_print_wc_error(fsm->datagram);
        ec_fsm_soe_print_error(fsm);
        return;
    }

    data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
    if (IS_ERR(data)) {
        fsm->state = ec_fsm_soe_error;
        ec_fsm_soe_print_error(fsm);
        return;
    }

    if (master->debug_level) {
        EC_SLAVE_DBG(slave, 0, "SCC write response:\n");
        ec_print_data(data, rec_size);
    }

    if (mbox_prot != EC_MBOX_TYPE_SOE) {
        fsm->state = ec_fsm_soe_error;
        EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
                mbox_prot);
        ec_fsm_soe_print_error(fsm);
        return;
    }

    if (rec_size < EC_SOE_SIZE) {
        fsm->state = ec_fsm_soe_error;
        EC_SLAVE_ERR(slave, "Received corrupted SoE write response"
                " (%zu bytes)!\n", rec_size);
        ec_print_data(data, rec_size);
        ec_fsm_soe_print_error(fsm);
        return;
    }

    opcode = EC_READ_U8(data) & 0x7;
    if (opcode != OPCODE_WRITE_RESPONSE) {
        EC_SLAVE_ERR(slave, "Received no write response"
                " (opcode %x).\n", opcode);
        ec_print_data(data, rec_size);
        ec_fsm_soe_print_error(fsm);
        fsm->state = ec_fsm_soe_error;
        return;
    }

    idn = EC_READ_U16(data + 2);
    if (idn != req->idn) {
        EC_SLAVE_ERR(slave, "Received response for"
                " wrong IDN 0x%04x.\n", idn);
        ec_print_data(data, rec_size);
        ec_fsm_soe_print_error(fsm);
        fsm->state = ec_fsm_soe_error;
        return;
    }

    error_flag = (EC_READ_U8(data) >> 4) & 1;
    if (error_flag) {
        if (rec_size < EC_SOE_SIZE + 2) {
            EC_SLAVE_ERR(slave, "Received corrupted error response"
                    " - error flag set, but received size is %zu.\n",
                    rec_size);
        } else {
            req->error_code = EC_READ_U16(data + EC_SOE_SIZE);
            EC_SLAVE_ERR(slave, "Received error response:\n");
            ec_print_soe_error(slave, req->error_code);
        }
        ec_print_data(data, rec_size);
        ec_fsm_soe_print_error(fsm);
        fsm->state = ec_fsm_soe_error;
        return;
    } else {
        req->error_code = 0x0000;
    }

    fsm->offset += fsm->fragment_size;

    if (fsm->offset < req->data_size) {
        fsm->retries = EC_FSM_RETRIES;
        ec_fsm_soe_write_next_fragment(fsm, datagram);
    } else {
        fsm->state = ec_fsm_soe_end; // success
    }
}

/*****************************************************************************/

/** State: ERROR.
 */
void ec_fsm_soe_error(
        ec_fsm_soe_t *fsm, /**< finite state machine */
        ec_datagram_t *datagram /**< Datagram to use. */
        )
{
}

/*****************************************************************************/

/** State: END.
 */
void ec_fsm_soe_end(
        ec_fsm_soe_t *fsm, /**< finite state machine */
        ec_datagram_t *datagram /**< Datagram to use. */
        )
{
}

/*****************************************************************************/


<|start_filename|>3rdpart/tslib-1.15/plugins/variance.c<|end_filename|>
/*
 *  tslib/plugins/variance.c
 *
 *  Copyright (C) 2016 <NAME>
 *  Copyright (C) 2001 <NAME>.
 *
 * This file is placed under the LGPL.  Please see the file
 * COPYING for more details.
 *
 * SPDX-License-Identifier: LGPL-2.1
 *
 *
 * Variance filter for touchscreen values.
 *
 * Problem: some touchscreens are sampled very roughly, thus even if
 * you hold the pen still, the samples can differ, sometimes substantially.
 * The worst happens when electric noise during sampling causes the result
 * to be substantially different from the real pen position; this causes
 * the mouse cursor to suddenly "jump" and then return back.
 *
 * Solution: delay sampled data by one timeslot. If we see that the last
 * sample read differs too much, we mark it as "suspicious". If next sample
 * read is close to the sample before the "suspicious", the suspicious sample
 * is dropped, otherwise we consider that a quick pen movement is in progress
 * and pass through both the "suspicious" sample and the sample after it.
 */
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <stdint.h>

#include "config.h"
#include "tslib.h"
#include "tslib-filter.h"

struct tslib_variance {
	struct tslib_module_info module;
	int delta;
	struct ts_sample last;
	struct ts_sample noise;
	unsigned int flags;
	short last_pen_down;
#define VAR_PENDOWN		0x00000001
#define VAR_LASTVALID		0x00000002
#define VAR_NOISEVALID		0x00000004
#define VAR_SUBMITNOISE		0x00000008
	int slots;
	int nr;
	struct ts_sample_mt **cur_mt;
	struct ts_sample *samp;
};

static int sqr(int x)
{
	return x * x;
}

static int variance_read(struct tslib_module_info *info, struct ts_sample *samp,
			 int nr)
{
	struct tslib_variance *var = (struct tslib_variance *)info;
	struct ts_sample cur;
	int count = 0, dist;

	while (count < nr) {
		if (var->flags & VAR_SUBMITNOISE) {
			cur = var->noise;
			var->flags &= ~VAR_SUBMITNOISE;
		} else {
			if (info->next->ops->read(info->next, &cur, 1) < 1)
				return count;
		}

		if (cur.pressure == 0) {
			/* Flush the queue immediately when the pen is just
			 * released, otherwise the previous layer will
			 * get the pen up notification too late. This
			 * will happen if info->next->ops->read() blocks.
			 * Update var->last with the recent value on pen-
			 * release.
			 */
			var->last = cur;

			/* Reset the state machine on pen up events. */
			var->flags &= ~(VAR_PENDOWN | VAR_NOISEVALID |
					VAR_LASTVALID | VAR_SUBMITNOISE);
			goto acceptsample;
		} else {
			var->flags |= VAR_PENDOWN;
		}

		if (!(var->flags & VAR_LASTVALID)) {
			var->last = cur;
			var->flags |= VAR_LASTVALID;
			goto acceptsample;
		}

		if (var->flags & VAR_PENDOWN) {
			/* Compute distance between last sample and current */
			dist = sqr(cur.x - var->last.x) +
			       sqr(cur.y - var->last.y);

			if (dist > var->delta) {
				/* Do we suspect the previous sample was a
				 * noise?
				 */
				if (var->flags & VAR_NOISEVALID) {
					/* Two "noises": it's just a quick pen
					 * movement
					 */
					samp[count++] = var->last = var->noise;
					var->flags = (var->flags &
						      ~VAR_NOISEVALID) |
						      VAR_SUBMITNOISE;
				} else {
					var->flags |= VAR_NOISEVALID;
				}

				/* The pen jumped too far, maybe it's a noise */
				var->noise = cur;
				continue;
			} else {
				var->flags &= ~VAR_NOISEVALID;
			}
		}

acceptsample:
#ifdef DEBUG
		fprintf(stderr, "VARIANCE----------------> %d %d %d\n",
			var->last.x, var->last.y, var->last.pressure);
#endif
		samp[count++] = var->last;
		var->last = cur;
	}

	return count;
}

/* No multitouch support here! This behaves like the old variance_read() call.
 * Only slot 0 is read.
 */
static int variance_read_mt(struct tslib_module_info *info,
			    struct ts_sample_mt **samp_mt,
			    int max_slots, int nr)
{
	struct tslib_variance *var = (struct tslib_variance *)info;
	int count = 0, dist;
	int i, j;
	struct ts_sample cur;
	short pen_down = 1;
	int ret;

	if (!info->next->ops->read_mt)
		return -ENOSYS;

	if (var->samp == NULL) {
		var->samp = calloc(nr, sizeof(struct ts_sample));
		if (!var->samp)
			return -ENOMEM;
	} else {
		if (nr == var->nr)
			memset(var->samp, 0, nr * sizeof(struct ts_sample));
	}

	if (var->cur_mt == NULL || max_slots > var->slots || nr > var->nr) {
		printf("tslib: WARNING: no multitouch using VARIANCE filter\n");
		if (var->cur_mt) {
			for (i = 0; i < var->nr; i++) {
				if (var->cur_mt[i])
					free(var->cur_mt[i]);
			}
			free(var->cur_mt);
		}

		var->cur_mt = malloc(nr * sizeof(struct ts_sample_mt *));
		if (!var->cur_mt)
			return -ENOMEM;

		for (i = 0; i < nr; i++) {
			var->cur_mt[i] = malloc(max_slots * sizeof(struct ts_sample_mt));
			if (!var->cur_mt[i]) {
				for (j = 0; j <= i; j++)
					free(var->cur_mt[j]);

				free(var->cur_mt);
				free(var->samp);
				return -ENOMEM;
			}
		}

		var->slots = max_slots;
		var->nr = nr;
	}

	while (count < nr) {
		if (var->flags & VAR_SUBMITNOISE) {
			cur = var->noise;
			var->flags &= ~VAR_SUBMITNOISE;
		} else {
			ret = info->next->ops->read_mt(info->next, var->cur_mt,
						       max_slots, 1);
			if (ret < 0) {
				count = ret;
				goto out;
			} else if (ret == 0) {
				goto out;
			}

			for (i = 1; i < max_slots; i++) {
				if (var->cur_mt[0][i].valid & TSLIB_MT_VALID) {
				#ifdef DEBUG
					fprintf(stderr,
						"VARIANCE: MT data dropped.\n");
				#endif
					/* XXX Attention. You lose multitouch
					 * using ts_read_mt() with the variance
					 * filter
					 */
					var->cur_mt[0][i].valid = 0;
				}
			}
			if (!(var->cur_mt[0][0].valid & TSLIB_MT_VALID))
				continue;

			cur.x = var->cur_mt[0][0].x;
			cur.y = var->cur_mt[0][0].y;
			cur.pressure = var->cur_mt[0][0].pressure;
			cur.tv = var->cur_mt[0][0].tv;
		}

		if (cur.pressure == 0) {
			/* Flush the queue immediately when the pen is just
			 * released, otherwise the previous layer will
			 * get the pen up notification too late. This
			 * will happen if info->next->ops->read() blocks.
			 */
			var->last = cur;
			var->last_pen_down = pen_down;

			/* Reset the state machine on pen up events. */
			var->flags &= ~(VAR_PENDOWN | VAR_NOISEVALID |
					VAR_LASTVALID | VAR_SUBMITNOISE);
			goto acceptsample;
		} else {
			var->flags |= VAR_PENDOWN;
		}

		if (!(var->flags & VAR_LASTVALID)) {
			var->last = cur;
			var->last_pen_down = pen_down;
			var->flags |= VAR_LASTVALID;
			goto acceptsample;
		}

		if (var->flags & VAR_PENDOWN) {
			/* Compute the distance between last sample and
			 * current
			 */
			dist = sqr(cur.x - var->last.x) +
			       sqr(cur.y - var->last.y);

			if (dist > var->delta) {
				/* Do we suspect the previous sample was a
				 * noise?
				 */
				if (var->flags & VAR_NOISEVALID) {
					/* Two "noises": it's just a quick pen
					 * movement
					 */
					var->samp[count] = var->last = var->noise;
					samp_mt[count][0].x = var->samp[count].x;
					samp_mt[count][0].y = var->samp[count].y;
					samp_mt[count][0].pressure = var->samp[count].pressure;
					samp_mt[count][0].tv = var->samp[count].tv;
					samp_mt[count][0].valid |= TSLIB_MT_VALID;
					samp_mt[count][0].slot = var->cur_mt[0][0].slot;
					samp_mt[count][0].tracking_id = var->cur_mt[0][0].tracking_id;
					samp_mt[count][0].pen_down = pen_down;
					count++;
					var->flags = (var->flags &
						      ~VAR_NOISEVALID) |
						     VAR_SUBMITNOISE;
				} else {
					var->flags |= VAR_NOISEVALID;
				}

				/* The pen jumped too far, maybe it's a noise */
				var->noise = cur;
				continue;
			} else {
				var->flags &= ~VAR_NOISEVALID;
			}
		}

acceptsample:
#ifdef DEBUG
		fprintf(stderr, "VARIANCE----------------> %d %d %d\n",
			var->last.x, var->last.y, var->last.pressure);
#endif
		var->samp[count] = var->last;
		samp_mt[count][0].x = var->samp[count].x;
		samp_mt[count][0].y = var->samp[count].y;
		samp_mt[count][0].pressure = var->samp[count].pressure;
		samp_mt[count][0].tv = var->samp[count].tv;
		samp_mt[count][0].valid |= TSLIB_MT_VALID;
		samp_mt[count][0].slot = var->cur_mt[0][0].slot;
		samp_mt[count][0].tracking_id = var->cur_mt[0][0].tracking_id;
		samp_mt[count][0].pen_down = var->last_pen_down;
		count++;
		var->last = cur;
	}

out:
	return count;
}

static int variance_fini(struct tslib_module_info *info)
{
	struct tslib_variance *var = (struct tslib_variance *)info;
	int i;

	if (var->cur_mt) {
		for (i = 0; i < var->nr; i++) {
			if (var->cur_mt[i])
				free(var->cur_mt[i]);
		}
		free(var->cur_mt);
	}
	if (var->samp)
		free(var->samp);

	free(info);

	return 0;
}

static const struct tslib_ops variance_ops = {
	.read		= variance_read,
	.read_mt	= variance_read_mt,
	.fini		= variance_fini,
};

static int variance_limit(struct tslib_module_info *inf, char *str, void *data)
{
	struct tslib_variance *var = (struct tslib_variance *)inf;
	unsigned long v;
	int err = errno;

	v = strtoul(str, NULL, 0);

	if (v == ULONG_MAX && errno == ERANGE)
		return -1;

	errno = err;
	switch ((int)(intptr_t)data) {
	case 1:
		var->delta = v;
		break;

	default:
		return -1;
	}
	return 0;
}

static const struct tslib_vars variance_vars[] = {
	{ "delta",	(void *)1, variance_limit },
};

#define NR_VARS (sizeof(variance_vars) / sizeof(variance_vars[0]))

TSAPI struct tslib_module_info *variance_mod_init(__attribute__ ((unused)) struct tsdev *dev,
						  const char *params)
{
	struct tslib_variance *var;

	var = malloc(sizeof(struct tslib_variance));
	if (var == NULL)
		return NULL;

	var->module.ops = &variance_ops;

	var->delta = 30;
	var->flags = 0;
	var->last_pen_down = 1;
	var->slots = 0;
	var->cur_mt = NULL;
	var->nr = 0;
	var->samp = NULL;

	if (tslib_parse_vars(&var->module, variance_vars, NR_VARS, params)) {
		free(var);
		return NULL;
	}

	var->delta = sqr(var->delta);

	return &var->module;
}

#ifndef TSLIB_STATIC_VARIANCE_MODULE
	TSLIB_MODULE_INIT(variance_mod_init);
#endif


<|start_filename|>3rdpart/tslib-1.15/tests/ts_test_mt_sdl.c<|end_filename|>
/*
 * (C) 2017 <NAME> <<EMAIL>>
 *
 * This file is part of tslib.
 *
 * ts_calibrate is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * ts_calibrate is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this tool.  If not, see <http://www.gnu.org/licenses/>.
 *
 * SPDX-License-Identifier: GPL-2.0+
 */

#include <SDL2/SDL.h>

#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <errno.h>
#include <stdint.h>

#if defined (__FreeBSD__)

#include <dev/evdev/input.h>
#define TS_HAVE_EVDEV

#elif defined (__linux__)

#include <linux/input.h>
#define TS_HAVE_EVDEV

#endif

#ifdef TS_HAVE_EVDEV
#include <sys/ioctl.h>
#endif

#include <tslib.h>
#include "sdlutils.h"

static void help(void)
{
	struct ts_lib_version_data *ver = ts_libversion();

	print_ascii_logo();

	printf("tslib %s / libts ABI version %d (0x%06X)\n",
		ver->package_version, ver->version_num >> 16, ver->version_num);
	printf("\n");
	printf("Usage: ts_test_mt [-v] [-i <device>] [-j <slots>]\n");
	printf("\n");
	printf("        <device>       Override the input device to use\n");
	printf("        <slots>        Override the number of possible touch contacts\n");
	printf("                       Automatically detected only on Linux, but not\n");
	printf("                       for all devices\n");
	printf("\n");
}

int main(int argc, char **argv)
{
	struct tsdev *ts;
#ifdef TS_HAVE_EVDEV
	struct input_absinfo slot;
#endif
	int32_t user_slots = 0;
	int32_t max_slots = 1;
	const char *tsdevice = NULL;
	struct ts_sample_mt **samp_mt = NULL;
	short verbose = 0;
	int ret;
	int i;
	SDL_Window *sdlWindow;
	SDL_Renderer *sdlRenderer;
	SDL_Event ev;

	while (1) {
		const struct option long_options[] = {
			{ "help",         no_argument,       NULL, 'h' },
			{ "verbose",      no_argument,       NULL, 'v' },
			{ "idev",         required_argument, NULL, 'i' },
			{ "slots",        required_argument, NULL, 'j' },
		};

		int option_index = 0;
		int c = getopt_long(argc, argv, "hi:vj:", long_options, &option_index);

		errno = 0;
		if (c == -1)
			break;

		switch (c) {
		case 'h':
			help();
			return 0;

		case 'v':
			verbose = 1;
			break;

		case 'i':
			tsdevice = optarg;
			break;

		case 'j':
			user_slots = atoi(optarg);
			if (user_slots <= 0) {
				help();
				return 0;
			}
			break;
		default:
			help();
			return 0;
		}

		if (errno) {
			char str[9];

			sprintf(str, "option ?");
			str[7] = c & 0xff;
			perror(str);
		}
	}

	ts = ts_setup(tsdevice, 0);
	if (!ts) {
		perror("ts_setup");
		return errno;
	}

#ifdef TS_HAVE_EVDEV
	if (ioctl(ts_fd(ts), EVIOCGABS(ABS_MT_SLOT), &slot) < 0) {
		perror("ioctl EVIOGABS");
		ts_close(ts);
		return errno;
	}

	max_slots = slot.maximum + 1 - slot.minimum;
#endif
	if (user_slots > 0)
		max_slots = user_slots;

	samp_mt = malloc(sizeof(struct ts_sample_mt *));
	if (!samp_mt) {
		ts_close(ts);
		return -ENOMEM;
	}
	samp_mt[0] = calloc(max_slots, sizeof(struct ts_sample_mt));
	if (!samp_mt[0]) {
		free(samp_mt);
		ts_close(ts);
		return -ENOMEM;
	}

	SDL_SetMainReady();

	if (SDL_Init(SDL_INIT_VIDEO) < 0) {
		SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
			     "Couldn't initialize SDL: %s", SDL_GetError());
		goto out;
	}

	if (SDL_CreateWindowAndRenderer(0, 0,
					SDL_WINDOW_FULLSCREEN_DESKTOP,
					&sdlWindow, &sdlRenderer)) {
		SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
			     "Couldn't create window and renderer: %s",
			     SDL_GetError());
		goto out;
	}

	SDL_ShowCursor(SDL_DISABLE);
	SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");

	SDL_SetRenderDrawColor(sdlRenderer, 0, 0, 0, 255);
	SDL_RenderClear(sdlRenderer);

	while (1) {
		ret = ts_read_mt(ts, samp_mt, max_slots, 1);
		if (ret < 0) {
			SDL_Quit();
			goto out;
		}

		if (ret != 1)
			continue;

		SDL_SetRenderDrawColor(sdlRenderer, 0, 0, 0, 255);
		SDL_RenderClear(sdlRenderer);

		for (i = 0; i < max_slots; i++) {
			if (!(samp_mt[0][i].valid & TSLIB_MT_VALID))
				continue;

			draw_crosshair(sdlRenderer,
				       samp_mt[0][i].x, samp_mt[0][i].y);

			if (verbose) {
				printf("%ld.%06ld: (slot %d) %6d %6d %6d\n",
					samp_mt[0][i].tv.tv_sec,
					samp_mt[0][i].tv.tv_usec,
					samp_mt[0][i].slot,
					samp_mt[0][i].x,
					samp_mt[0][i].y,
					samp_mt[0][i].pressure);
			}
		}

		SDL_PollEvent(&ev);
		switch (ev.type) {
		case SDL_KEYDOWN:
		case SDL_QUIT:
			SDL_ShowCursor(SDL_ENABLE);
			SDL_DestroyWindow(sdlWindow);
			SDL_Quit();
			goto out;
		}

		SDL_RenderPresent(sdlRenderer);
	}
out:
	if (ts)
		ts_close(ts);

	if (samp_mt) {
		if (samp_mt[0])
			free(samp_mt[0]);

		free(samp_mt);
	}
	return 0;
}


<|start_filename|>3rdpart/ethercat-1.5.2/master/fsm_change.h<|end_filename|>
/******************************************************************************
 *
 *  $Id: fsm_change.h,v 11c0b2caa253 2009/02/24 12:51:39 fp $
 *
 *  Copyright (C) 2006-2008  <NAME>, Ingenieurgemeinschaft IgH
 *
 *  This file is part of the IgH EtherCAT Master.
 *
 *  The IgH EtherCAT Master is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License version 2, as
 *  published by the Free Software Foundation.
 *
 *  The IgH EtherCAT Master is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 *  Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with the IgH EtherCAT Master; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 *****************************************************************************/

/**
   \file
   EtherCAT state change FSM.
*/

/*****************************************************************************/

#ifndef __EC_FSM_CHANGE_H__
#define __EC_FSM_CHANGE_H__

#include "globals.h"
#include "datagram.h"
#include "slave.h"

/*****************************************************************************/

/**
   Mode of the change state machine.
*/

typedef enum {
    EC_FSM_CHANGE_MODE_FULL, /**< full state change */
    EC_FSM_CHANGE_MODE_ACK_ONLY /**< only state acknowledgement */
}
ec_fsm_change_mode_t;

/*****************************************************************************/

typedef struct ec_fsm_change ec_fsm_change_t; /**< \see ec_fsm_change */

/**
   EtherCAT state change FSM.
*/

struct ec_fsm_change
{
    ec_slave_t *slave; /**< slave the FSM runs on */
    ec_datagram_t *datagram; /**< datagram used in the state machine */
    unsigned int retries; /**< retries upon datagram timeout */

    void (*state)(ec_fsm_change_t *); /**< slave state change state function */
    ec_fsm_change_mode_t mode; /**< full state change, or ack only. */
    ec_slave_state_t requested_state; /**< input: state */
    ec_slave_state_t old_state; /**< prior slave state */
    unsigned long jiffies_start; /**< change timer */
    uint8_t take_time; /**< take sending timestamp */
    uint8_t spontaneous_change; /**< spontaneous state change detected */
};

/*****************************************************************************/

void ec_fsm_change_init(ec_fsm_change_t *, ec_datagram_t *);
void ec_fsm_change_clear(ec_fsm_change_t *);

void ec_fsm_change_start(ec_fsm_change_t *, ec_slave_t *, ec_slave_state_t);
void ec_fsm_change_ack(ec_fsm_change_t *, ec_slave_t *);

int ec_fsm_change_exec(ec_fsm_change_t *);
int ec_fsm_change_success(ec_fsm_change_t *);

/*****************************************************************************/

#endif


<|start_filename|>3rdpart/tslib-1.15/src/ts_open.c<|end_filename|>
/*
 *  tslib/src/ts_open.c
 *
 *  Copyright (C) 2001 <NAME>.
 *
 * This file is placed under the LGPL.  Please see the file
 * COPYING for more details.
 *
 * SPDX-License-Identifier: LGPL-2.1
 *
 *
 * Open a touchscreen device.
 */
#include "config.h"
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>

#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

#include "tslib-private.h"

#ifdef DEBUG
#include <stdio.h>
#endif

extern struct tslib_module_info __ts_raw;

#ifdef DEBUG
/* verify we use the correct OS specific code at runtime.
 * If we use it, test it here!
 */
static void print_host_os(void)
{
	struct ts_lib_version_data *version = ts_libversion();

	printf("tslib %s (library 0x%06X) on ",
	       version->package_version, version->version_num);

#if defined (__linux__)
	printf("Host OS: Linux");
#elif defined (__FreeBSD__)
	printf("Host OS: FreeBSD");
#elif defined (__OpenBSD__)
	printf("Host OS: OpenBSD");
#elif defined (__GNU__) && defined (__MACH__)
	printf("Host OS: Hurd");
#elif defined (__HAIKU__)
	printf("Host OS: Haiku");
#elif defined (__BEOS__)
	printf("Host OS: BeOS");
#elif defined (WIN32)
	printf("Host OS: Windows");
#elif defined (__APPLE__) && defined (__MACH__)
	printf("Host OS: Darwin");
#else
	printf("Host OS: unknown");
#endif
}
#endif /* DEBUG */

int (*ts_open_restricted)(const char *path, int flags, void *user_data) = NULL;

struct tsdev *ts_open(const char *name, int nonblock)
{
	struct tsdev *ts;
	int flags = O_RDWR;

#ifdef DEBUG
	print_host_os();
	printf(", trying to open %s\n", name);
#endif

	if (nonblock) {
	#ifndef WIN32
		flags |= O_NONBLOCK;
	#endif
	}

	ts = malloc(sizeof(struct tsdev));
	if (!ts)
		return NULL;

	memset(ts, 0, sizeof(struct tsdev));

	ts->eventpath = strdup(name);
	if (!ts->eventpath)
		goto free;

	if (ts_open_restricted) {
		ts->fd = ts_open_restricted(name, flags, NULL);
		if (ts->fd == -1)
			goto free;

		return ts;
	}

	ts->fd = open(name, flags);
	/*
	 * Try again in case file is simply not writable
	 * It will do for most drivers
	 */
	if (ts->fd == -1 && errno == EACCES) {
	#ifndef WIN32
		flags = nonblock ? (O_RDONLY | O_NONBLOCK) : O_RDONLY;
	#else
		flags = O_RDONLY;
	#endif
		ts->fd = open(name, flags);
	}
	if (ts->fd == -1)
		goto free;

	return ts;

free:
	if (ts->eventpath)
		free(ts->eventpath);

	free(ts);
	return NULL;
}


<|start_filename|>rootfs/buildroot-2017.11.1/package/kodi-inputstream-adaptive/kodi-inputstream-adaptive.mk<|end_filename|>
################################################################################
#
# kodi-inputstream-adaptive
#
################################################################################

# This cset is on the branch 'Krypton'
# When Kodi is updated, then this should be updated to the corresponding branch
KODI_INPUTSTREAM_ADAPTIVE_VERSION = f2904b547e940c724dce7412a26744c2698cab66
KODI_INPUTSTREAM_ADAPTIVE_SITE = $(call github,peak3d,inputstream.adaptive,$(KODI_INPUTSTREAM_ADAPTIVE_VERSION))
KODI_INPUTSTREAM_ADAPTIVE_LICENSE = GPL-2.0+
KODI_INPUTSTREAM_ADAPTIVE_LICENSE_FILES = src/main.cpp
KODI_INPUTSTREAM_ADAPTIVE_DEPENDENCIES = libplatform kodi-platform

$(eval $(cmake-package))


<|start_filename|>rootfs/buildroot-2017.11.1/package/python-pytablewriter/python-pytablewriter.mk<|end_filename|>
################################################################################
#
# python-pytablewriter
#
################################################################################

PYTHON_PYTABLEWRITER_VERSION = 0.24.0
PYTHON_PYTABLEWRITER_SOURCE = pytablewriter-$(PYTHON_PYTABLEWRITER_VERSION).tar.gz
PYTHON_PYTABLEWRITER_SITE = https://pypi.python.org/packages/65/b0/efafdd9e4d5b08069371530e46acde684ac7fb18bffa09b635e2af091d82
PYTHON_PYTABLEWRITER_SETUP_TYPE = setuptools
PYTHON_PYTABLEWRITER_LICENSE = MIT
PYTHON_PYTABLEWRITER_LICENSE_FILES = LICENSE

$(eval $(python-package))


<|start_filename|>3rdpart/ethercat-1.5.2/master/ioctl.h<|end_filename|>
/******************************************************************************
 *
 *  $Id: ioctl.h,v 5ef3197e5e1f 2013/02/05 15:45:34 fp $
 *
 *  Copyright (C) 2006-2012  <NAME>, Ingenieurgemeinschaft IgH
 *
 *  This file is part of the IgH EtherCAT Master.
 *
 *  The IgH EtherCAT Master is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License version 2, as
 *  published by the Free Software Foundation.
 *
 *  The IgH EtherCAT Master is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 *  Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with the IgH EtherCAT Master; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 *****************************************************************************/

/**
   \file
   EtherCAT master character device IOCTL commands.
*/

/*****************************************************************************/

#ifndef __EC_IOCTL_H__
#define __EC_IOCTL_H__

#include <linux/ioctl.h>

#include "globals.h"

/*****************************************************************************/

/** \cond */

#define EC_IOCTL_TYPE 0xa4

#define EC_IO(nr)           _IO(EC_IOCTL_TYPE, nr)
#define EC_IOR(nr, type)   _IOR(EC_IOCTL_TYPE, nr, type)
#define EC_IOW(nr, type)   _IOW(EC_IOCTL_TYPE, nr, type)
#define EC_IOWR(nr, type) _IOWR(EC_IOCTL_TYPE, nr, type)

/** EtherCAT master ioctl() version magic.
 *
 * Increment this when changing the ioctl interface!
 */
#define EC_IOCTL_VERSION_MAGIC 27

// Command-line tool
#define EC_IOCTL_MODULE                EC_IOR(0x00, ec_ioctl_module_t)
#define EC_IOCTL_MASTER                EC_IOR(0x01, ec_ioctl_master_t)
#define EC_IOCTL_SLAVE                EC_IOWR(0x02, ec_ioctl_slave_t)
#define EC_IOCTL_SLAVE_SYNC           EC_IOWR(0x03, ec_ioctl_slave_sync_t)
#define EC_IOCTL_SLAVE_SYNC_PDO       EC_IOWR(0x04, ec_ioctl_slave_sync_pdo_t)
#define EC_IOCTL_SLAVE_SYNC_PDO_ENTRY EC_IOWR(0x05, ec_ioctl_slave_sync_pdo_entry_t)
#define EC_IOCTL_DOMAIN               EC_IOWR(0x06, ec_ioctl_domain_t)
#define EC_IOCTL_DOMAIN_FMMU          EC_IOWR(0x07, ec_ioctl_domain_fmmu_t)
#define EC_IOCTL_DOMAIN_DATA          EC_IOWR(0x08, ec_ioctl_domain_data_t)
#define EC_IOCTL_MASTER_DEBUG           EC_IO(0x09)
#define EC_IOCTL_MASTER_RESCAN          EC_IO(0x0a)
#define EC_IOCTL_SLAVE_STATE           EC_IOW(0x0b, ec_ioctl_slave_state_t)
#define EC_IOCTL_SLAVE_SDO            EC_IOWR(0x0c, ec_ioctl_slave_sdo_t)
#define EC_IOCTL_SLAVE_SDO_ENTRY      EC_IOWR(0x0d, ec_ioctl_slave_sdo_entry_t)
#define EC_IOCTL_SLAVE_SDO_UPLOAD     EC_IOWR(0x0e, ec_ioctl_slave_sdo_upload_t)
#define EC_IOCTL_SLAVE_SDO_DOWNLOAD   EC_IOWR(0x0f, ec_ioctl_slave_sdo_download_t)
#define EC_IOCTL_SLAVE_SII_READ       EC_IOWR(0x10, ec_ioctl_slave_sii_t)
#define EC_IOCTL_SLAVE_SII_WRITE       EC_IOW(0x11, ec_ioctl_slave_sii_t)
#define EC_IOCTL_SLAVE_REG_READ       EC_IOWR(0x12, ec_ioctl_slave_reg_t)
#define EC_IOCTL_SLAVE_REG_WRITE       EC_IOW(0x13, ec_ioctl_slave_reg_t)
#define EC_IOCTL_SLAVE_FOE_READ       EC_IOWR(0x14, ec_ioctl_slave_foe_t)
#define EC_IOCTL_SLAVE_FOE_WRITE       EC_IOW(0x15, ec_ioctl_slave_foe_t)
#define EC_IOCTL_SLAVE_SOE_READ       EC_IOWR(0x16, ec_ioctl_slave_soe_read_t)
#define EC_IOCTL_SLAVE_SOE_WRITE      EC_IOWR(0x17, ec_ioctl_slave_soe_write_t)
#define EC_IOCTL_CONFIG               EC_IOWR(0x18, ec_ioctl_config_t)
#define EC_IOCTL_CONFIG_PDO           EC_IOWR(0x19, ec_ioctl_config_pdo_t)
#define EC_IOCTL_CONFIG_PDO_ENTRY     EC_IOWR(0x1a, ec_ioctl_config_pdo_entry_t)
#define EC_IOCTL_CONFIG_SDO           EC_IOWR(0x1b, ec_ioctl_config_sdo_t)
#define EC_IOCTL_CONFIG_IDN           EC_IOWR(0x1c, ec_ioctl_config_idn_t)
#ifdef EC_EOE
#define EC_IOCTL_EOE_HANDLER          EC_IOWR(0x1d, ec_ioctl_eoe_handler_t)
#endif

// Application interface
#define EC_IOCTL_REQUEST                EC_IO(0x1e)
#define EC_IOCTL_CREATE_DOMAIN          EC_IO(0x1f)
#define EC_IOCTL_CREATE_SLAVE_CONFIG  EC_IOWR(0x20, ec_ioctl_config_t)
#define EC_IOCTL_SELECT_REF_CLOCK      EC_IOW(0x21, uint32_t)
#define EC_IOCTL_ACTIVATE              EC_IOR(0x22, ec_ioctl_master_activate_t)
#define EC_IOCTL_DEACTIVATE             EC_IO(0x23)
#define EC_IOCTL_SEND                   EC_IO(0x24)
#define EC_IOCTL_RECEIVE                EC_IO(0x25)
#define EC_IOCTL_MASTER_STATE          EC_IOR(0x26, ec_master_state_t)
#define EC_IOCTL_MASTER_LINK_STATE    EC_IOWR(0x27, ec_ioctl_link_state_t)
#define EC_IOCTL_APP_TIME              EC_IOW(0x28, ec_ioctl_app_time_t)
#define EC_IOCTL_SYNC_REF               EC_IO(0x29)
#define EC_IOCTL_SYNC_SLAVES            EC_IO(0x2a)
#define EC_IOCTL_REF_CLOCK_TIME        EC_IOR(0x2b, uint32_t)
#define EC_IOCTL_SYNC_MON_QUEUE         EC_IO(0x2c)
#define EC_IOCTL_SYNC_MON_PROCESS      EC_IOR(0x2d, uint32_t)
#define EC_IOCTL_RESET                  EC_IO(0x2e)
#define EC_IOCTL_SC_SYNC               EC_IOW(0x2f, ec_ioctl_config_t)
#define EC_IOCTL_SC_WATCHDOG           EC_IOW(0x30, ec_ioctl_config_t)
#define EC_IOCTL_SC_ADD_PDO            EC_IOW(0x31, ec_ioctl_config_pdo_t)
#define EC_IOCTL_SC_CLEAR_PDOS         EC_IOW(0x32, ec_ioctl_config_pdo_t)
#define EC_IOCTL_SC_ADD_ENTRY          EC_IOW(0x33, ec_ioctl_add_pdo_entry_t)
#define EC_IOCTL_SC_CLEAR_ENTRIES      EC_IOW(0x34, ec_ioctl_config_pdo_t)
#define EC_IOCTL_SC_REG_PDO_ENTRY     EC_IOWR(0x35, ec_ioctl_reg_pdo_entry_t)
#define EC_IOCTL_SC_REG_PDO_POS       EC_IOWR(0x36, ec_ioctl_reg_pdo_pos_t)
#define EC_IOCTL_SC_DC                 EC_IOW(0x37, ec_ioctl_config_t)
#define EC_IOCTL_SC_SDO                EC_IOW(0x38, ec_ioctl_sc_sdo_t)
#define EC_IOCTL_SC_EMERG_SIZE         EC_IOW(0x39, ec_ioctl_sc_emerg_t)
#define EC_IOCTL_SC_EMERG_POP         EC_IOWR(0x3a, ec_ioctl_sc_emerg_t)
#define EC_IOCTL_SC_EMERG_CLEAR        EC_IOW(0x3b, ec_ioctl_sc_emerg_t)
#define EC_IOCTL_SC_EMERG_OVERRUNS    EC_IOWR(0x3c, ec_ioctl_sc_emerg_t)
#define EC_IOCTL_SC_SDO_REQUEST       EC_IOWR(0x3d, ec_ioctl_sdo_request_t)
#define EC_IOCTL_SC_REG_REQUEST       EC_IOWR(0x3e, ec_ioctl_reg_request_t)
#define EC_IOCTL_SC_VOE               EC_IOWR(0x3f, ec_ioctl_voe_t)
#define EC_IOCTL_SC_STATE             EC_IOWR(0x40, ec_ioctl_sc_state_t)
#define EC_IOCTL_SC_IDN                EC_IOW(0x41, ec_ioctl_sc_idn_t)
#define EC_IOCTL_DOMAIN_SIZE            EC_IO(0x42)
#define EC_IOCTL_DOMAIN_OFFSET          EC_IO(0x43)
#define EC_IOCTL_DOMAIN_PROCESS         EC_IO(0x44)
#define EC_IOCTL_DOMAIN_QUEUE           EC_IO(0x45)
#define EC_IOCTL_DOMAIN_STATE         EC_IOWR(0x46, ec_ioctl_domain_state_t)
#define EC_IOCTL_SDO_REQUEST_INDEX    EC_IOWR(0x47, ec_ioctl_sdo_request_t)
#define EC_IOCTL_SDO_REQUEST_TIMEOUT  EC_IOWR(0x48, ec_ioctl_sdo_request_t)
#define EC_IOCTL_SDO_REQUEST_STATE    EC_IOWR(0x49, ec_ioctl_sdo_request_t)
#define EC_IOCTL_SDO_REQUEST_READ     EC_IOWR(0x4a, ec_ioctl_sdo_request_t)
#define EC_IOCTL_SDO_REQUEST_WRITE    EC_IOWR(0x4b, ec_ioctl_sdo_request_t)
#define EC_IOCTL_SDO_REQUEST_DATA     EC_IOWR(0x4c, ec_ioctl_sdo_request_t)
#define EC_IOCTL_REG_REQUEST_DATA     EC_IOWR(0x4d, ec_ioctl_reg_request_t)
#define EC_IOCTL_REG_REQUEST_STATE    EC_IOWR(0x4e, ec_ioctl_reg_request_t)
#define EC_IOCTL_REG_REQUEST_WRITE    EC_IOWR(0x4f, ec_ioctl_reg_request_t)
#define EC_IOCTL_REG_REQUEST_READ     EC_IOWR(0x50, ec_ioctl_reg_request_t)
#define EC_IOCTL_VOE_SEND_HEADER       EC_IOW(0x51, ec_ioctl_voe_t)
#define EC_IOCTL_VOE_REC_HEADER       EC_IOWR(0x52, ec_ioctl_voe_t)
#define EC_IOCTL_VOE_READ              EC_IOW(0x53, ec_ioctl_voe_t)
#define EC_IOCTL_VOE_READ_NOSYNC       EC_IOW(0x54, ec_ioctl_voe_t)
#define EC_IOCTL_VOE_WRITE            EC_IOWR(0x55, ec_ioctl_voe_t)
#define EC_IOCTL_VOE_EXEC             EC_IOWR(0x56, ec_ioctl_voe_t)
#define EC_IOCTL_VOE_DATA             EC_IOWR(0x57, ec_ioctl_voe_t)
#define EC_IOCTL_SET_SEND_INTERVAL     EC_IOW(0x58, size_t)

/*****************************************************************************/

#define EC_IOCTL_STRING_SIZE 64

/*****************************************************************************/

typedef struct {
    uint32_t ioctl_version_magic;
    uint32_t master_count;
} ec_ioctl_module_t;

/*****************************************************************************/

typedef struct {
    uint32_t slave_count;
    uint32_t config_count;
    uint32_t domain_count;
#ifdef EC_EOE
    uint32_t eoe_handler_count;
#endif
    uint8_t phase;
    uint8_t active;
    uint8_t scan_busy;
    struct ec_ioctl_device {
        uint8_t address[6];
        uint8_t attached;
        uint8_t link_state;
        uint64_t tx_count;
        uint64_t rx_count;
        uint64_t tx_bytes;
        uint64_t rx_bytes;
        uint64_t tx_errors;
        int32_t tx_frame_rates[EC_RATE_COUNT];
        int32_t rx_frame_rates[EC_RATE_COUNT];
        int32_t tx_byte_rates[EC_RATE_COUNT];
        int32_t rx_byte_rates[EC_RATE_COUNT];
    } devices[EC_MAX_NUM_DEVICES];
    uint32_t num_devices;
    uint64_t tx_count;
    uint64_t rx_count;
    uint64_t tx_bytes;
    uint64_t rx_bytes;
    int32_t tx_frame_rates[EC_RATE_COUNT];
    int32_t rx_frame_rates[EC_RATE_COUNT];
    int32_t tx_byte_rates[EC_RATE_COUNT];
    int32_t rx_byte_rates[EC_RATE_COUNT];
    int32_t loss_rates[EC_RATE_COUNT];
    uint64_t app_time;
    uint16_t ref_clock;
} ec_ioctl_master_t;

/*****************************************************************************/

typedef struct {
    // input
    uint16_t position;

    // outputs
    unsigned int device_index;
    uint32_t vendor_id;
    uint32_t product_code;
    uint32_t revision_number;
    uint32_t serial_number;
    uint16_t alias;
    uint16_t boot_rx_mailbox_offset;
    uint16_t boot_rx_mailbox_size;
    uint16_t boot_tx_mailbox_offset;
    uint16_t boot_tx_mailbox_size;
    uint16_t std_rx_mailbox_offset;
    uint16_t std_rx_mailbox_size;
    uint16_t std_tx_mailbox_offset;
    uint16_t std_tx_mailbox_size;
    uint16_t mailbox_protocols;
    uint8_t has_general_category;
    ec_sii_coe_details_t coe_details;
    ec_sii_general_flags_t general_flags;
    int16_t current_on_ebus;
    struct {
        ec_slave_port_desc_t desc;
        ec_slave_port_link_t link;
        uint32_t receive_time;
        uint16_t next_slave;
        uint32_t delay_to_next_dc;
    } ports[EC_MAX_PORTS];
    uint8_t fmmu_bit;
    uint8_t dc_supported;
    ec_slave_dc_range_t dc_range;
    uint8_t has_dc_system_time;
    uint32_t transmission_delay;
    uint8_t al_state;
    uint8_t error_flag;
    uint8_t sync_count;
    uint16_t sdo_count;
    uint32_t sii_nwords;
    char group[EC_IOCTL_STRING_SIZE];
    char image[EC_IOCTL_STRING_SIZE];
    char order[EC_IOCTL_STRING_SIZE];
    char name[EC_IOCTL_STRING_SIZE];
} ec_ioctl_slave_t;

/*****************************************************************************/

typedef struct {
    // inputs
    uint16_t slave_position;
    uint32_t sync_index;

    // outputs
    uint16_t physical_start_address;
    uint16_t default_size;
    uint8_t control_register;
    uint8_t enable;
    uint8_t pdo_count;
} ec_ioctl_slave_sync_t;

/*****************************************************************************/

typedef struct {
    // inputs
    uint16_t slave_position;
    uint32_t sync_index;
    uint32_t pdo_pos;

    // outputs
    uint16_t index;
    uint8_t entry_count;
    int8_t name[EC_IOCTL_STRING_SIZE];
} ec_ioctl_slave_sync_pdo_t;

/*****************************************************************************/

typedef struct {
    // inputs
    uint16_t slave_position;
    uint32_t sync_index;
    uint32_t pdo_pos;
    uint32_t entry_pos;

    // outputs
    uint16_t index;
    uint8_t subindex;
    uint8_t bit_length;
    int8_t name[EC_IOCTL_STRING_SIZE];
} ec_ioctl_slave_sync_pdo_entry_t;

/*****************************************************************************/

typedef struct {
    // inputs
    uint32_t index;

    // outputs
    uint32_t data_size;
    uint32_t logical_base_address;
    uint16_t working_counter[EC_MAX_NUM_DEVICES];
    uint16_t expected_working_counter;
    uint32_t fmmu_count;
} ec_ioctl_domain_t;

/*****************************************************************************/

typedef struct {
    // inputs
    uint32_t domain_index;
    uint32_t fmmu_index;

    // outputs
    uint16_t slave_config_alias;
    uint16_t slave_config_position;
    uint8_t sync_index;
    ec_direction_t dir;
    uint32_t logical_address;
    uint32_t data_size;
} ec_ioctl_domain_fmmu_t;

/*****************************************************************************/

typedef struct {
    // inputs
    uint32_t domain_index;
    uint32_t data_size;
    uint8_t *target;
} ec_ioctl_domain_data_t;

/*****************************************************************************/

typedef struct {
    // inputs
    uint16_t slave_position;
    uint8_t al_state;
} ec_ioctl_slave_state_t;

/*****************************************************************************/

typedef struct {
    // inputs
    uint16_t slave_position;
    uint16_t sdo_position;

    // outputs
    uint16_t sdo_index;
    uint8_t max_subindex;
    int8_t name[EC_IOCTL_STRING_SIZE];
} ec_ioctl_slave_sdo_t;

/*****************************************************************************/

typedef struct {
    // inputs
    uint16_t slave_position;
    int sdo_spec; // positive: index, negative: list position
    uint8_t sdo_entry_subindex;

    // outputs
    uint16_t data_type;
    uint16_t bit_length;
    uint8_t read_access[EC_SDO_ENTRY_ACCESS_COUNT];
    uint8_t write_access[EC_SDO_ENTRY_ACCESS_COUNT];
    int8_t description[EC_IOCTL_STRING_SIZE];
} ec_ioctl_slave_sdo_entry_t;

/*****************************************************************************/

typedef struct {
    // inputs
    uint16_t slave_position;
    uint16_t sdo_index;
    uint8_t sdo_entry_subindex;
    size_t target_size;
    uint8_t *target;

    // outputs
    size_t data_size;
    uint32_t abort_code;
} ec_ioctl_slave_sdo_upload_t;

/*****************************************************************************/

typedef struct {
    // inputs
    uint16_t slave_position;
    uint16_t sdo_index;
    uint8_t sdo_entry_subindex;
    uint8_t complete_access;
    size_t data_size;
    uint8_t *data;

    // outputs
    uint32_t abort_code;
} ec_ioctl_slave_sdo_download_t;

/*****************************************************************************/

typedef struct {
    // inputs
    uint16_t slave_position;
    uint16_t offset;
    uint32_t nwords;
    uint16_t *words;
} ec_ioctl_slave_sii_t;

/*****************************************************************************/

typedef struct {
    // inputs
    uint16_t slave_position;
    uint16_t address;
    size_t size;
    uint8_t *data;
} ec_ioctl_slave_reg_t;

/*****************************************************************************/

typedef struct {
    // inputs
    uint16_t slave_position;
    uint16_t offset;
    size_t buffer_size;
    uint8_t *buffer;

    // outputs
    size_t data_size;
    uint32_t result;
    uint32_t error_code;
    char file_name[32];
} ec_ioctl_slave_foe_t;

/*****************************************************************************/

typedef struct {
    // inputs
    uint16_t slave_position;
    uint8_t drive_no;
    uint16_t idn;
    size_t mem_size;
    uint8_t *data;

    // outputs
    size_t data_size;
    uint16_t error_code;
} ec_ioctl_slave_soe_read_t;

/*****************************************************************************/

typedef struct {
    // inputs
    uint16_t slave_position;
    uint8_t drive_no;
    uint16_t idn;
    size_t data_size;
    uint8_t *data;

    // outputs
    uint16_t error_code;
} ec_ioctl_slave_soe_write_t;

/*****************************************************************************/

typedef struct {
    // inputs
    uint32_t config_index;

    // outputs
    uint16_t alias;
    uint16_t position;
    uint32_t vendor_id;
    uint32_t product_code;
    struct {
        ec_direction_t dir;
        ec_watchdog_mode_t watchdog_mode;
        uint32_t pdo_count;
        uint8_t config_this;
    } syncs[EC_MAX_SYNC_MANAGERS];
    uint16_t watchdog_divider;
    uint16_t watchdog_intervals;
    uint32_t sdo_count;
    uint32_t idn_count;
    int32_t slave_position;
    uint16_t dc_assign_activate;
    ec_sync_signal_t dc_sync[EC_SYNC_SIGNAL_COUNT];
} ec_ioctl_config_t;

/*****************************************************************************/

typedef struct {
    // inputs
    uint32_t config_index;
    uint8_t sync_index;
    uint16_t pdo_pos;

    // outputs
    uint16_t index;
    uint8_t entry_count;
    int8_t name[EC_IOCTL_STRING_SIZE];
} ec_ioctl_config_pdo_t;

/*****************************************************************************/

typedef struct {
    // inputs
    uint32_t config_index;
    uint8_t sync_index;
    uint16_t pdo_pos;
    uint8_t entry_pos;

    // outputs
    uint16_t index;
    uint8_t subindex;
    uint8_t bit_length;
    int8_t name[EC_IOCTL_STRING_SIZE];
} ec_ioctl_config_pdo_entry_t;

/*****************************************************************************/

/** Maximum size for displayed SDO data.
 * \todo Make this dynamic.
 */
#define EC_MAX_SDO_DATA_SIZE 1024

typedef struct {
    // inputs
    uint32_t config_index;
    uint32_t sdo_pos;

    // outputs
    uint16_t index;
    uint8_t subindex;
    size_t size;
    uint8_t data[EC_MAX_SDO_DATA_SIZE];
    uint8_t complete_access;
} ec_ioctl_config_sdo_t;

/*****************************************************************************/

/** Maximum size for displayed IDN data.
 * \todo Make this dynamic.
 */
#define EC_MAX_IDN_DATA_SIZE 1024

typedef struct {
    // inputs
    uint32_t config_index;
    uint32_t idn_pos;

    // outputs
    uint8_t drive_no;
    uint16_t idn;
    ec_al_state_t state;
    size_t size;
    uint8_t data[EC_MAX_IDN_DATA_SIZE];
} ec_ioctl_config_idn_t;

/*****************************************************************************/

#ifdef EC_EOE

typedef struct {
    // input
    uint16_t eoe_index;

    // outputs
    char name[EC_DATAGRAM_NAME_SIZE];
    uint16_t slave_position;
    uint8_t open;
    uint32_t rx_bytes;
    uint32_t rx_rate;
    uint32_t tx_bytes;
    uint32_t tx_rate;
    uint32_t tx_queued_frames;
    uint32_t tx_queue_size;
} ec_ioctl_eoe_handler_t;

#endif

/*****************************************************************************/

typedef struct {
    // outputs
    void *process_data;
    size_t process_data_size;
} ec_ioctl_master_activate_t;

/*****************************************************************************/

typedef struct {
    // inputs
    uint32_t config_index;
    uint16_t pdo_index;
    uint16_t entry_index;
    uint8_t entry_subindex;
    uint8_t entry_bit_length;
} ec_ioctl_add_pdo_entry_t;

/*****************************************************************************/

typedef struct {
    // inputs
    uint32_t config_index;
    uint16_t entry_index;
    uint8_t entry_subindex;
    uint32_t domain_index;

    // outputs
    unsigned int bit_position;
} ec_ioctl_reg_pdo_entry_t;

/*****************************************************************************/

typedef struct {
    // inputs
    uint32_t config_index;
    uint32_t sync_index;
    uint32_t pdo_pos;
    uint32_t entry_pos;
    uint32_t domain_index;

    // outputs
    unsigned int bit_position;
} ec_ioctl_reg_pdo_pos_t;

/*****************************************************************************/

typedef struct {
    // inputs
    uint32_t config_index;
    uint16_t index;
    uint8_t subindex;
    const uint8_t *data;
    size_t size;
    uint8_t complete_access;
} ec_ioctl_sc_sdo_t;

/*****************************************************************************/

typedef struct {
    // inputs
    uint32_t config_index;
    size_t size;
    uint8_t *target;

    // outputs
    int32_t overruns;
} ec_ioctl_sc_emerg_t;

/*****************************************************************************/

typedef struct {
    // inputs
    uint32_t config_index;

    // outputs
    ec_slave_config_state_t *state;
} ec_ioctl_sc_state_t;

/*****************************************************************************/

typedef struct {
    // inputs
    uint32_t config_index;
    uint8_t drive_no;
    uint16_t idn;
    ec_al_state_t al_state;
    const uint8_t *data;
    size_t size;
} ec_ioctl_sc_idn_t;

/*****************************************************************************/

typedef struct {
    // inputs
    uint32_t domain_index;

    // outputs
    ec_domain_state_t *state;
} ec_ioctl_domain_state_t;

/*****************************************************************************/

typedef struct {
    // inputs
    uint32_t config_index;

    // inputs/outputs
    uint32_t request_index;
    uint16_t sdo_index;
    uint8_t sdo_subindex;
    size_t size;
    uint8_t *data;
    uint32_t timeout;
    ec_request_state_t state;
} ec_ioctl_sdo_request_t;

/*****************************************************************************/

typedef struct {
    // inputs
    uint32_t config_index;
    size_t mem_size;

    // inputs/outputs
    uint32_t request_index;
    uint8_t *data;
    ec_request_state_t state;
    uint8_t new_data;
    uint16_t address;
    size_t transfer_size;
} ec_ioctl_reg_request_t;

/*****************************************************************************/

typedef struct {
    // inputs
    uint32_t config_index;

    // inputs/outputs
    uint32_t voe_index;
    uint32_t *vendor_id;
    uint16_t *vendor_type;
    size_t size;
    uint8_t *data;
    ec_request_state_t state;
} ec_ioctl_voe_t;

/*****************************************************************************/

typedef struct {
    // inputs
    uint32_t dev_idx;

    // outputs
    ec_master_link_state_t *state;
} ec_ioctl_link_state_t;

/*****************************************************************************/

typedef struct {
    // inputs
    uint64_t app_time;
} ec_ioctl_app_time_t;

/*****************************************************************************/

#ifdef __KERNEL__

/** Context data structure for file handles.
 */
typedef struct {
    unsigned int writable; /**< Device was opened with write permission. */
    unsigned int requested; /**< Master was requested via this file handle. */
    uint8_t *process_data; /**< Total process data area. */
    size_t process_data_size; /**< Size of the \a process_data. */
} ec_ioctl_context_t;

long ec_ioctl(ec_master_t *, ec_ioctl_context_t *, unsigned int,
        void __user *);

#ifdef EC_RTDM

long ec_ioctl_rtdm(ec_master_t *, ec_ioctl_context_t *, unsigned int,
        void __user *);
int ec_rtdm_mmap(ec_ioctl_context_t *, void **);

#endif

#endif

/*****************************************************************************/

/** \endcond */

#endif


<|start_filename|>apps/ecat-master/main/indev_tslib.c<|end_filename|>
/*
 * indev_tslib.c
 *
 *  Created on: Mar 11, 2018
 *      Author: morris
 */
#include <stdbool.h>
#include <stdlib.h>
#include <pthread.h>
#include <stdio.h>
#include "tslib.h"
#include "indev_tslib.h"

static bool thread_running = true;
static bool press_down = false;
static int16_t last_x = 0;
static int16_t last_y = 0;

/* 互斥锁 */
static pthread_mutex_t mutex;

void indev_stop(void) {
	pthread_mutex_lock(&mutex);
	thread_running = false;
	pthread_mutex_unlock(&mutex);
}

/* 线程：用来读取最新的触摸输入 */
static void *handle_input(void *arg) {
	struct ts_sample samp;
	int ret;
	struct tsdev *ts = (struct tsdev*) arg;
	pthread_mutex_lock(&mutex);
	while (thread_running) {
		pthread_mutex_unlock(&mutex);
		ret = ts_read_raw(ts, &samp, 1);
		if (ret < 0) {
			perror("ts_read_raw");
			goto read_err;
		}
		if (ret != 1) {
			pthread_mutex_lock(&mutex);
			continue;
		}
		pthread_mutex_lock(&mutex);
		press_down = samp.pressure ? true : false;
		if (press_down) {
			last_x = samp.x;
			last_y = samp.y;
		}
	}
	pthread_mutex_unlock(&mutex);
read_err:
	/* 确保线程停止运行 */
	indev_stop();
	/* 出错处理*/
	pthread_mutex_destroy(&mutex);
	ts_close(ts);
	pthread_exit(arg);
}

int indev_init(void) {
	int ret;
	pthread_t thread_hdl;
	pthread_attr_t attr;
	struct tsdev *ts;
	/* 初始化互斥锁 */
	pthread_mutex_init(&mutex, NULL);
	/* 初始化线程的属性 */
	pthread_attr_init(&attr);

	/* 打开并配置触摸屏设备 */
	ts = ts_setup(NULL, 0);
	if (!ts) {
		perror("ts_setup");
		ret = -1;
		goto ts_err;
	}
	/* 设置线程的分离属性 */
	ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
	if (ret) {
		perror("pthread_attr_setdetachstate");
		goto pthread_err;
	}
	/* 设置线程的绑定属性 */
	ret = pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
	if (ret) {
		perror("pthread_attr_setscope");
		goto pthread_err;
	}
	/* 创建线程 */
	ret = pthread_create(&thread_hdl, &attr, handle_input, (void*) ts);
	if (ret) {
		perror("pthread_create");
		goto pthread_err;
	}
	/* 释放线程属性对象 */
	pthread_attr_destroy(&attr);
	return 0;
pthread_err:
	ts_close(ts);
ts_err:
	pthread_attr_destroy(&attr);
	pthread_mutex_destroy(&mutex);
	return ret;
}

/* indev_ts_read在主线程中被调用 */
bool indev_ts_read(lv_indev_data_t *data) {
	pthread_mutex_lock(&mutex);
	data->point.x = last_x;
	data->point.y = last_y;
	data->state = press_down ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL;
	pthread_mutex_unlock(&mutex);
	return false;
}


<|start_filename|>kernel/modules/virtual_framebuffer/vfb_test.c<|end_filename|>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>

int main()
{
    int fd;
    int ret;
    char *start = NULL;
    int i;
    char buf[32]; //用户空间的内存

    fd = open("/dev/vfb0", O_RDWR);
    if (fd == -1)
    {
        goto fail;
    }

    /* 第一个参数是想要映射的起始地址，通常设为NULL，表示由内核来决定起始地址
    ** 第二个参数表示要映射的内存空间的大小
    ** 第三个参数表示映射后的空间是可读可写的
    ** 第四个参数表示该映射是多进程共享的 */
    start = mmap(NULL, 32, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if (start == MAP_FAILED)
    {
        goto fail;
    }
    /* 对映射后的内存进行操作 */
    for (i = 0; i < 26; i++)
    {
        *(start + i) = 'a' + i;
    }
    *(start + i) = '\0';

    if (lseek(fd, 3, SEEK_SET) == -1)
    {
        goto fail;
    }

    if (read(fd, buf, 10) == -1)
    {
        goto fail;
    }
    buf[10] = '\0';
    puts(buf);

    munmap(start, 32);

    exit(EXIT_SUCCESS);
fail:
    perror("mmap test");
    exit(EXIT_FAILURE);
}

<|start_filename|>3rdpart/ethercat-1.5.2/master/slave.c<|end_filename|>
/******************************************************************************
 *
 *  $Id: slave.c,v ec403cf308eb 2013/02/12 14:46:43 fp $
 *
 *  Copyright (C) 2006-2012  <NAME>, Ingenieurgemeinschaft IgH
 *
 *  This file is part of the IgH EtherCAT Master.
 *
 *  The IgH EtherCAT Master is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License version 2, as
 *  published by the Free Software Foundation.
 *
 *  The IgH EtherCAT Master is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 *  Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with the IgH EtherCAT Master; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 *****************************************************************************/

/**
   \file
   EtherCAT slave methods.
*/

/*****************************************************************************/

#include <linux/module.h>
#include <linux/delay.h>

#include "globals.h"
#include "datagram.h"
#include "master.h"
#include "slave_config.h"

#include "slave.h"

/*****************************************************************************/

extern const ec_code_msg_t al_status_messages[];

/*****************************************************************************/

char *ec_slave_sii_string(ec_slave_t *, unsigned int);

/*****************************************************************************/

/**
   Slave constructor.
   \return 0 in case of success, else < 0
*/

void ec_slave_init(
        ec_slave_t *slave, /**< EtherCAT slave */
        ec_master_t *master, /**< EtherCAT master */
        ec_device_index_t dev_idx, /**< Device index. */
        uint16_t ring_position, /**< ring position */
        uint16_t station_address /**< station address to configure */
        )
{
    unsigned int i;

    slave->master = master;
    slave->device_index = dev_idx;
    slave->ring_position = ring_position;
    slave->station_address = station_address;
    slave->effective_alias = 0x0000;

    slave->config = NULL;
    slave->requested_state = EC_SLAVE_STATE_PREOP;
    slave->current_state = EC_SLAVE_STATE_UNKNOWN;
    slave->error_flag = 0;
    slave->force_config = 0;
    slave->configured_rx_mailbox_offset = 0x0000;
    slave->configured_rx_mailbox_size = 0x0000;
    slave->configured_tx_mailbox_offset = 0x0000;
    slave->configured_tx_mailbox_size = 0x0000;

    slave->base_type = 0;
    slave->base_revision = 0;
    slave->base_build = 0;
    slave->base_fmmu_count = 0;
    slave->base_sync_count = 0;

    for (i = 0; i < EC_MAX_PORTS; i++) {
        slave->ports[i].desc = EC_PORT_NOT_IMPLEMENTED;

        slave->ports[i].link.link_up = 0;
        slave->ports[i].link.loop_closed = 0;
        slave->ports[i].link.signal_detected = 0;
        slave->sii.physical_layer[i] = 0xFF;

        slave->ports[i].receive_time = 0U;

        slave->ports[i].next_slave = NULL;
        slave->ports[i].delay_to_next_dc = 0U;
    }

    slave->base_fmmu_bit_operation = 0;
    slave->base_dc_supported = 0;
    slave->base_dc_range = EC_DC_32;
    slave->has_dc_system_time = 0;
    slave->transmission_delay = 0U;

    slave->sii_words = NULL;
    slave->sii_nwords = 0;

    slave->sii.alias = 0x0000;
    slave->sii.vendor_id = 0x00000000;
    slave->sii.product_code = 0x00000000;
    slave->sii.revision_number = 0x00000000;
    slave->sii.serial_number = 0x00000000;
    slave->sii.boot_rx_mailbox_offset = 0x0000;
    slave->sii.boot_rx_mailbox_size = 0x0000;
    slave->sii.boot_tx_mailbox_offset = 0x0000;
    slave->sii.boot_tx_mailbox_size = 0x0000;
    slave->sii.std_rx_mailbox_offset = 0x0000;
    slave->sii.std_rx_mailbox_size = 0x0000;
    slave->sii.std_tx_mailbox_offset = 0x0000;
    slave->sii.std_tx_mailbox_size = 0x0000;
    slave->sii.mailbox_protocols = 0;

    slave->sii.strings = NULL;
    slave->sii.string_count = 0;

    slave->sii.has_general = 0;
    slave->sii.group = NULL;
    slave->sii.image = NULL;
    slave->sii.order = NULL;
    slave->sii.name = NULL;
    memset(&slave->sii.coe_details, 0x00, sizeof(ec_sii_coe_details_t));
    memset(&slave->sii.general_flags, 0x00, sizeof(ec_sii_general_flags_t));
    slave->sii.current_on_ebus = 0;

    slave->sii.syncs = NULL;
    slave->sii.sync_count = 0;

    INIT_LIST_HEAD(&slave->sii.pdos);

    INIT_LIST_HEAD(&slave->sdo_dictionary);

    slave->sdo_dictionary_fetched = 0;
    slave->jiffies_preop = 0;

    INIT_LIST_HEAD(&slave->sdo_requests);
    INIT_LIST_HEAD(&slave->reg_requests);
    INIT_LIST_HEAD(&slave->foe_requests);
    INIT_LIST_HEAD(&slave->soe_requests);

    // create state machine object
    ec_fsm_slave_init(&slave->fsm, slave);
}

/*****************************************************************************/

/**
   Slave destructor.
   Clears and frees a slave object.
*/

void ec_slave_clear(ec_slave_t *slave /**< EtherCAT slave */)
{
    ec_sdo_t *sdo, *next_sdo;
    unsigned int i;
    ec_pdo_t *pdo, *next_pdo;

    // abort all pending requests

    while (!list_empty(&slave->sdo_requests)) {
        ec_sdo_request_t *request =
            list_entry(slave->sdo_requests.next, ec_sdo_request_t, list);
        list_del_init(&request->list); // dequeue
        EC_SLAVE_WARN(slave, "Discarding SDO request,"
                " slave about to be deleted.\n");
        request->state = EC_INT_REQUEST_FAILURE;
    }

    while (!list_empty(&slave->reg_requests)) {
        ec_reg_request_t *reg =
            list_entry(slave->reg_requests.next, ec_reg_request_t, list);
        list_del_init(&reg->list); // dequeue
        EC_SLAVE_WARN(slave, "Discarding register request,"
                " slave about to be deleted.\n");
        reg->state = EC_INT_REQUEST_FAILURE;
    }

    while (!list_empty(&slave->foe_requests)) {
        ec_foe_request_t *request =
            list_entry(slave->foe_requests.next, ec_foe_request_t, list);
        list_del_init(&request->list); // dequeue
        EC_SLAVE_WARN(slave, "Discarding FoE request,"
                " slave about to be deleted.\n");
        request->state = EC_INT_REQUEST_FAILURE;
    }

    while (!list_empty(&slave->soe_requests)) {
        ec_soe_request_t *request =
            list_entry(slave->soe_requests.next, ec_soe_request_t, list);
        list_del_init(&request->list); // dequeue
        EC_SLAVE_WARN(slave, "Discarding SoE request,"
                " slave about to be deleted.\n");
        request->state = EC_INT_REQUEST_FAILURE;
    }

    wake_up_all(&slave->master->request_queue);

    if (slave->config) {
        ec_slave_config_detach(slave->config);
    }

    // free all SDOs
    list_for_each_entry_safe(sdo, next_sdo, &slave->sdo_dictionary, list) {
        list_del(&sdo->list);
        ec_sdo_clear(sdo);
        kfree(sdo);
    }

    // free all strings
    if (slave->sii.strings) {
        for (i = 0; i < slave->sii.string_count; i++)
            kfree(slave->sii.strings[i]);
        kfree(slave->sii.strings);
    }

    // free all sync managers
    ec_slave_clear_sync_managers(slave);

    // free all SII PDOs
    list_for_each_entry_safe(pdo, next_pdo, &slave->sii.pdos, list) {
        list_del(&pdo->list);
        ec_pdo_clear(pdo);
        kfree(pdo);
    }

    if (slave->sii_words) {
        kfree(slave->sii_words);
    }

    ec_fsm_slave_clear(&slave->fsm);
}

/*****************************************************************************/

/** Clear the sync manager array.
 */
void ec_slave_clear_sync_managers(ec_slave_t *slave /**< EtherCAT slave. */)
{
    unsigned int i;

    if (slave->sii.syncs) {
        for (i = 0; i < slave->sii.sync_count; i++) {
            ec_sync_clear(&slave->sii.syncs[i]);
        }
        kfree(slave->sii.syncs);
        slave->sii.syncs = NULL;
    }
}

/*****************************************************************************/

/**
 * Sets the application state of a slave.
 */

void ec_slave_set_state(ec_slave_t *slave, /**< EtherCAT slave */
        ec_slave_state_t new_state /**< new application state */
        )
{
    if (new_state != slave->current_state) {
        if (slave->master->debug_level) {
            char old_state[EC_STATE_STRING_SIZE],
                cur_state[EC_STATE_STRING_SIZE];
            ec_state_string(slave->current_state, old_state, 0);
            ec_state_string(new_state, cur_state, 0);
            EC_SLAVE_DBG(slave, 0, "%s -> %s.\n", old_state, cur_state);
        }
        slave->current_state = new_state;
    }
}

/*****************************************************************************/

/**
 * Request a slave state and resets the error flag.
 */

void ec_slave_request_state(ec_slave_t *slave, /**< EtherCAT slave */
                            ec_slave_state_t state /**< new state */
                            )
{
    slave->requested_state = state;
    slave->error_flag = 0;
}

/*****************************************************************************/

/**
   Fetches data from a STRING category.
   \todo range checking
   \return 0 in case of success, else < 0
*/

int ec_slave_fetch_sii_strings(
        ec_slave_t *slave, /**< EtherCAT slave */
        const uint8_t *data, /**< category data */
        size_t data_size /**< number of bytes */
        )
{
    int i, err;
    size_t size;
    off_t offset;

    slave->sii.string_count = data[0];

    if (slave->sii.string_count) {
        if (!(slave->sii.strings =
                    kmalloc(sizeof(char *) * slave->sii.string_count,
                        GFP_KERNEL))) {
            EC_SLAVE_ERR(slave, "Failed to allocate string array memory.\n");
            err = -ENOMEM;
            goto out_zero;
        }

        offset = 1;
        for (i = 0; i < slave->sii.string_count; i++) {
            size = data[offset];
            // allocate memory for string structure and data at a single blow
            if (!(slave->sii.strings[i] =
                        kmalloc(sizeof(char) * size + 1, GFP_KERNEL))) {
                EC_SLAVE_ERR(slave, "Failed to allocate string memory.\n");
                err = -ENOMEM;
                goto out_free;
            }
            memcpy(slave->sii.strings[i], data + offset + 1, size);
            slave->sii.strings[i][size] = 0x00; // append binary zero
            offset += 1 + size;
        }
    }

    return 0;

out_free:
    for (i--; i >= 0; i--)
        kfree(slave->sii.strings[i]);
    kfree(slave->sii.strings);
    slave->sii.strings = NULL;
out_zero:
    slave->sii.string_count = 0;
    return err;
}

/*****************************************************************************/

/**
   Fetches data from a GENERAL category.
   \return 0 in case of success, else < 0
*/

int ec_slave_fetch_sii_general(
        ec_slave_t *slave, /**< EtherCAT slave */
        const uint8_t *data, /**< category data */
        size_t data_size /**< size in bytes */
        )
{
    unsigned int i;
    uint8_t flags;

    if (data_size != 32) {
        EC_SLAVE_ERR(slave, "Wrong size of general category (%zu/32).\n",
                data_size);
        return -EINVAL;
    }

    slave->sii.group = ec_slave_sii_string(slave, data[0]);
    slave->sii.image = ec_slave_sii_string(slave, data[1]);
    slave->sii.order = ec_slave_sii_string(slave, data[2]);
    slave->sii.name = ec_slave_sii_string(slave, data[3]);

    for (i = 0; i < 4; i++)
        slave->sii.physical_layer[i] =
            (data[4] & (0x03 << (i * 2))) >> (i * 2);

    // read CoE details
    flags = EC_READ_U8(data + 5);
    slave->sii.coe_details.enable_sdo =                 (flags >> 0) & 0x01;
    slave->sii.coe_details.enable_sdo_info =            (flags >> 1) & 0x01;
    slave->sii.coe_details.enable_pdo_assign =          (flags >> 2) & 0x01;
    slave->sii.coe_details.enable_pdo_configuration =   (flags >> 3) & 0x01;
    slave->sii.coe_details.enable_upload_at_startup =   (flags >> 4) & 0x01;
    slave->sii.coe_details.enable_sdo_complete_access = (flags >> 5) & 0x01;

    // read general flags
    flags = EC_READ_U8(data + 0x000B);
    slave->sii.general_flags.enable_safeop =  (flags >> 0) & 0x01;
    slave->sii.general_flags.enable_not_lrw = (flags >> 1) & 0x01;

    slave->sii.current_on_ebus = EC_READ_S16(data + 0x0C);
    slave->sii.has_general = 1;
    return 0;
}

/*****************************************************************************/

/** Fetches data from a SYNC MANAGER category.
 *
 * Appends the sync managers described in the category to the existing ones.
 *
 * \return 0 in case of success, else < 0
 */
int ec_slave_fetch_sii_syncs(
        ec_slave_t *slave, /**< EtherCAT slave. */
        const uint8_t *data, /**< Category data. */
        size_t data_size /**< Number of bytes. */
        )
{
    unsigned int i, count, total_count;
    ec_sync_t *sync;
    size_t memsize;
    ec_sync_t *syncs;
    uint8_t index;

    // one sync manager struct is 4 words long
    if (data_size % 8) {
        EC_SLAVE_ERR(slave, "Invalid SII sync manager category size %zu.\n",
                data_size);
        return -EINVAL;
    }

    count = data_size / 8;

    if (count) {
        total_count = count + slave->sii.sync_count;
        if (total_count > EC_MAX_SYNC_MANAGERS) {
            EC_SLAVE_ERR(slave, "Exceeded maximum number of"
                    " sync managers!\n");
            return -EOVERFLOW;
        }
        memsize = sizeof(ec_sync_t) * total_count;
        if (!(syncs = kmalloc(memsize, GFP_KERNEL))) {
            EC_SLAVE_ERR(slave, "Failed to allocate %zu bytes"
                    " for sync managers.\n", memsize);
            return -ENOMEM;
        }

        for (i = 0; i < slave->sii.sync_count; i++)
            ec_sync_init_copy(syncs + i, slave->sii.syncs + i);

        // initialize new sync managers
        for (i = 0; i < count; i++, data += 8) {
            index = i + slave->sii.sync_count;
            sync = &syncs[index];

            ec_sync_init(sync, slave);
            sync->physical_start_address = EC_READ_U16(data);
            sync->default_length = EC_READ_U16(data + 2);
            sync->control_register = EC_READ_U8(data + 4);
            sync->enable = EC_READ_U8(data + 6);
        }

        if (slave->sii.syncs)
            kfree(slave->sii.syncs);
        slave->sii.syncs = syncs;
        slave->sii.sync_count = total_count;
    }

    return 0;
}

/*****************************************************************************/

/**
   Fetches data from a [RT]xPDO category.
   \return 0 in case of success, else < 0
*/

int ec_slave_fetch_sii_pdos(
        ec_slave_t *slave, /**< EtherCAT slave */
        const uint8_t *data, /**< category data */
        size_t data_size, /**< number of bytes */
        ec_direction_t dir /**< PDO direction. */
        )
{
    int ret;
    ec_pdo_t *pdo;
    ec_pdo_entry_t *entry;
    unsigned int entry_count, i;

    while (data_size >= 8) {
        if (!(pdo = kmalloc(sizeof(ec_pdo_t), GFP_KERNEL))) {
            EC_SLAVE_ERR(slave, "Failed to allocate PDO memory.\n");
            return -ENOMEM;
        }

        ec_pdo_init(pdo);
        pdo->index = EC_READ_U16(data);
        entry_count = EC_READ_U8(data + 2);
        pdo->sync_index = EC_READ_U8(data + 3);
        ret = ec_pdo_set_name(pdo,
                ec_slave_sii_string(slave, EC_READ_U8(data + 5)));
        if (ret) {
            ec_pdo_clear(pdo);
            kfree(pdo);
            return ret;
        }
        list_add_tail(&pdo->list, &slave->sii.pdos);

        data_size -= 8;
        data += 8;

        for (i = 0; i < entry_count; i++) {
            if (!(entry = kmalloc(sizeof(ec_pdo_entry_t), GFP_KERNEL))) {
                EC_SLAVE_ERR(slave, "Failed to allocate PDO entry memory.\n");
                return -ENOMEM;
            }

            ec_pdo_entry_init(entry);
            entry->index = EC_READ_U16(data);
            entry->subindex = EC_READ_U8(data + 2);
            ret = ec_pdo_entry_set_name(entry,
                    ec_slave_sii_string(slave, EC_READ_U8(data + 3)));
            if (ret) {
                ec_pdo_entry_clear(entry);
                kfree(entry);
                return ret;
            }
            entry->bit_length = EC_READ_U8(data + 5);
            list_add_tail(&entry->list, &pdo->entries);

            data_size -= 8;
            data += 8;
        }

        // if sync manager index is positive, the PDO is mapped by default
        if (pdo->sync_index >= 0) {
            ec_sync_t *sync;

            if (!(sync = ec_slave_get_sync(slave, pdo->sync_index))) {
                EC_SLAVE_ERR(slave, "Invalid SM index %i for PDO 0x%04X.",
                        pdo->sync_index, pdo->index);
                return -ENOENT;
            }

            ret = ec_pdo_list_add_pdo_copy(&sync->pdos, pdo);
            if (ret)
                return ret;
        }
    }

    return 0;
}

/*****************************************************************************/

/**
   Searches the string list for an index.
   \return 0 in case of success, else < 0
*/

char *ec_slave_sii_string(
        ec_slave_t *slave, /**< EtherCAT slave */
        unsigned int index /**< string index */
        )
{
    if (!index--)
        return NULL;

    if (index >= slave->sii.string_count) {
        EC_SLAVE_DBG(slave, 1, "String %u not found.\n", index);
        return NULL;
    }

    return slave->sii.strings[index];
}

/*****************************************************************************/

/** Get the sync manager given an index.
 *
 * \return pointer to sync manager, or NULL.
 */
ec_sync_t *ec_slave_get_sync(
        ec_slave_t *slave, /**< EtherCAT slave. */
        uint8_t sync_index /**< Sync manager index. */
        )
{
    if (sync_index < slave->sii.sync_count) {
        return &slave->sii.syncs[sync_index];
    } else {
        return NULL;
    }
}

/*****************************************************************************/

/**
   Counts the total number of SDOs and entries in the dictionary.
*/

void ec_slave_sdo_dict_info(const ec_slave_t *slave, /**< EtherCAT slave */
                            unsigned int *sdo_count, /**< number of SDOs */
                            unsigned int *entry_count /**< total number of
                                                         entries */
                            )
{
    unsigned int sdos = 0, entries = 0;
    ec_sdo_t *sdo;
    ec_sdo_entry_t *entry;

    list_for_each_entry(sdo, &slave->sdo_dictionary, list) {
        sdos++;
        list_for_each_entry(entry, &sdo->entries, list) {
            entries++;
        }
    }

    *sdo_count = sdos;
    *entry_count = entries;
}

/*****************************************************************************/

/**
 * Get an SDO from the dictionary.
 * \returns The desired SDO, or NULL.
 */

ec_sdo_t *ec_slave_get_sdo(
        ec_slave_t *slave, /**< EtherCAT slave */
        uint16_t index /**< SDO index */
        )
{
    ec_sdo_t *sdo;

    list_for_each_entry(sdo, &slave->sdo_dictionary, list) {
        if (sdo->index != index)
            continue;
        return sdo;
    }

    return NULL;
}

/*****************************************************************************/

/**
 * Get an SDO from the dictionary.
 *
 * const version.
 *
 * \returns The desired SDO, or NULL.
 */

const ec_sdo_t *ec_slave_get_sdo_const(
        const ec_slave_t *slave, /**< EtherCAT slave */
        uint16_t index /**< SDO index */
        )
{
    const ec_sdo_t *sdo;

    list_for_each_entry(sdo, &slave->sdo_dictionary, list) {
        if (sdo->index != index)
            continue;
        return sdo;
    }

    return NULL;
}

/*****************************************************************************/

/** Get an SDO from the dictionary, given its position in the list.
 * \returns The desired SDO, or NULL.
 */

const ec_sdo_t *ec_slave_get_sdo_by_pos_const(
        const ec_slave_t *slave, /**< EtherCAT slave. */
        uint16_t sdo_position /**< SDO list position. */
        )
{
    const ec_sdo_t *sdo;

    list_for_each_entry(sdo, &slave->sdo_dictionary, list) {
        if (sdo_position--)
            continue;
        return sdo;
    }

    return NULL;
}

/*****************************************************************************/

/** Get the number of SDOs in the dictionary.
 * \returns SDO count.
 */

uint16_t ec_slave_sdo_count(
        const ec_slave_t *slave /**< EtherCAT slave. */
        )
{
    const ec_sdo_t *sdo;
    uint16_t count = 0;

    list_for_each_entry(sdo, &slave->sdo_dictionary, list) {
        count++;
    }

    return count;
}

/*****************************************************************************/

/** Finds a mapped PDO.
 * \returns The desired PDO object, or NULL.
 */
const ec_pdo_t *ec_slave_find_pdo(
        const ec_slave_t *slave, /**< Slave. */
        uint16_t index /**< PDO index to find. */
        )
{
    unsigned int i;
    const ec_sync_t *sync;
    const ec_pdo_t *pdo;

    for (i = 0; i < slave->sii.sync_count; i++) {
        sync = &slave->sii.syncs[i];

        if (!(pdo = ec_pdo_list_find_pdo_const(&sync->pdos, index)))
            continue;

        return pdo;
    }

    return NULL;
}

/*****************************************************************************/

/** Find name for a PDO and its entries.
 */
void ec_slave_find_names_for_pdo(
        ec_slave_t *slave,
        ec_pdo_t *pdo
        )
{
    const ec_sdo_t *sdo;
    ec_pdo_entry_t *pdo_entry;
    const ec_sdo_entry_t *sdo_entry;

    list_for_each_entry(sdo, &slave->sdo_dictionary, list) {
        if (sdo->index == pdo->index) {
            ec_pdo_set_name(pdo, sdo->name);
        } else {
            list_for_each_entry(pdo_entry, &pdo->entries, list) {
                if (sdo->index == pdo_entry->index) {
                    sdo_entry = ec_sdo_get_entry_const(
                            sdo, pdo_entry->subindex);
                    if (sdo_entry) {
                        ec_pdo_entry_set_name(pdo_entry,
                                sdo_entry->description);
                    }
                }
            }
        }
    }
}

/*****************************************************************************/

/** Attach PDO names.
 */
void ec_slave_attach_pdo_names(
        ec_slave_t *slave
        )
{
    unsigned int i;
    ec_sync_t *sync;
    ec_pdo_t *pdo;

    for (i = 0; i < slave->sii.sync_count; i++) {
        sync = slave->sii.syncs + i;
        list_for_each_entry(pdo, &sync->pdos.list, list) {
            ec_slave_find_names_for_pdo(slave, pdo);
        }
    }
}

/*****************************************************************************/

/** Returns the previous connected port of a given port.
 *
 * \return Port index.
 */
unsigned int ec_slave_get_previous_port(
        ec_slave_t *slave, /**< EtherCAT slave. */
        unsigned int port_index /**< Port index. */
        )
{
    static const unsigned int prev_table[EC_MAX_PORTS] = {
        2, 3, 1, 0
    };

    if (port_index >= EC_MAX_PORTS) {
        EC_SLAVE_WARN(slave, "%s(port_index=%u): Invalid port index!\n",
                __func__, port_index);
    }

    do {
        port_index = prev_table[port_index];
        if (slave->ports[port_index].next_slave) {
            return port_index;
        }
    } while (port_index);

    return 0;
}

/*****************************************************************************/

/** Returns the next connected port of a given port.
 *
 * \return Port index.
 */
unsigned int ec_slave_get_next_port(
        ec_slave_t *slave, /**< EtherCAT slave. */
        unsigned int port_index /**< Port index. */
        )
{
    static const unsigned int next_table[EC_MAX_PORTS] = {
        3, 2, 0, 1
    };

    if (port_index >= EC_MAX_PORTS) {
        EC_SLAVE_WARN(slave, "%s(port_index=%u): Invalid port index!\n",
                __func__, port_index);
    }

    do {
        port_index = next_table[port_index];
        if (slave->ports[port_index].next_slave) {
            return port_index;
        }
    } while (port_index);

    return 0;
}

/*****************************************************************************/

/** Calculates the sum of round-trip-times of connected ports 1-3.
 *
 * \return Round-trip-time in ns.
 */
uint32_t ec_slave_calc_rtt_sum(
        ec_slave_t *slave /**< EtherCAT slave. */
        )
{
    uint32_t rtt_sum = 0, rtt;
    unsigned int port_index = ec_slave_get_next_port(slave, 0);

    while (port_index != 0) {
        unsigned int prev_index =
            ec_slave_get_previous_port(slave, port_index);

        rtt = slave->ports[port_index].receive_time -
            slave->ports[prev_index].receive_time;
        rtt_sum += rtt;
        port_index = ec_slave_get_next_port(slave, port_index);
    }

    return rtt_sum;
}

/*****************************************************************************/

/** Finds the next slave supporting DC delay measurement.
 *
 * \return Next DC slave, or NULL.
 */
ec_slave_t *ec_slave_find_next_dc_slave(
        ec_slave_t *slave /**< EtherCAT slave. */
        )
{
    unsigned int port_index;
    ec_slave_t *dc_slave = NULL;

    if (slave->base_dc_supported) {
        dc_slave = slave;
    } else {
        port_index = ec_slave_get_next_port(slave, 0);

        while (port_index != 0) {
            ec_slave_t *next = slave->ports[port_index].next_slave;

            if (next) {
                dc_slave = ec_slave_find_next_dc_slave(next);

                if (dc_slave) {
                    break;
                }
            }
            port_index = ec_slave_get_next_port(slave, port_index);
        }
    }

    return dc_slave;
}

/*****************************************************************************/

/** Calculates the port transmission delays.
 */
void ec_slave_calc_port_delays(
        ec_slave_t *slave /**< EtherCAT slave. */
        )
{
    unsigned int port_index;
    ec_slave_t *next_slave, *next_dc;
    uint32_t rtt, next_rtt_sum;

    if (!slave->base_dc_supported)
        return;

    port_index = ec_slave_get_next_port(slave, 0);

    while (port_index != 0) {
        next_slave = slave->ports[port_index].next_slave;
        next_dc = ec_slave_find_next_dc_slave(next_slave);

        if (next_dc) {
            unsigned int prev_port =
                ec_slave_get_previous_port(slave, port_index);

            rtt = slave->ports[port_index].receive_time -
                slave->ports[prev_port].receive_time;
            next_rtt_sum = ec_slave_calc_rtt_sum(next_dc);

            slave->ports[port_index].delay_to_next_dc =
                (rtt - next_rtt_sum) / 2; // FIXME
            next_dc->ports[0].delay_to_next_dc =
                (rtt - next_rtt_sum) / 2;

#if 0
            EC_SLAVE_DBG(slave, 1, "delay %u:%u rtt=%u"
                    " next_rtt_sum=%u delay=%u\n",
                    slave->ring_position, port_index, rtt, next_rtt_sum,
                    slave->ports[port_index].delay_to_next_dc);
#endif
        }

        port_index = ec_slave_get_next_port(slave, port_index);
    }
}

/*****************************************************************************/

/** Recursively calculates transmission delays.
 */
void ec_slave_calc_transmission_delays_rec(
        ec_slave_t *slave, /**< Current slave. */
        uint32_t *delay /**< Sum of delays. */
        )
{
    unsigned int i;
    ec_slave_t *next_dc;

    EC_SLAVE_DBG(slave, 1, "%s(delay = %u ns)\n", __func__, *delay);

    slave->transmission_delay = *delay;

    i = ec_slave_get_next_port(slave, 0);

    while (i != 0) {
        ec_slave_port_t *port = &slave->ports[i];
        next_dc = ec_slave_find_next_dc_slave(port->next_slave);
        if (next_dc) {
            *delay = *delay + port->delay_to_next_dc;
#if 0
            EC_SLAVE_DBG(slave, 1, "%u:%u %u\n",
                    slave->ring_position, i, *delay);
#endif
            ec_slave_calc_transmission_delays_rec(next_dc, delay);
        }

        i = ec_slave_get_next_port(slave, i);
    }

    *delay = *delay + slave->ports[0].delay_to_next_dc;
}

/*****************************************************************************/


<|start_filename|>3rdpart/ethercat-1.5.2/examples/mini/mini.c<|end_filename|>
/******************************************************************************
 *
 *  $Id: mini.c,v bc2d4bf9cbe5 2012/09/06 18:22:24 fp $
 *
 *  Copyright (C) 2006-2008  <NAME>, Ingenieurgemeinschaft IgH
 *
 *  This file is part of the IgH EtherCAT Master.
 *
 *  The IgH EtherCAT Master is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License version 2, as
 *  published by the Free Software Foundation.
 *
 *  The IgH EtherCAT Master is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 *  Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with the IgH EtherCAT Master; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 *****************************************************************************/

#include <linux/version.h>
#include <linux/module.h>
#include <linux/timer.h>
#include <linux/interrupt.h>
#include <linux/err.h>

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 34)
#include <linux/slab.h>
#endif

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
#include <linux/semaphore.h>
#else
#include <asm/semaphore.h>
#endif

#include "../../include/ecrt.h" // EtherCAT realtime interface

/*****************************************************************************/

// Module parameters
#define FREQUENCY 100

// Optional features
#define CONFIGURE_PDOS  1
#define EL3152_ALT_PDOS 0
#define EXTERNAL_MEMORY 1
#define SDO_ACCESS      0
#define VOE_ACCESS      0

#define PFX "ec_mini: "

/*****************************************************************************/

// EtherCAT
static ec_master_t *master = NULL;
static ec_master_state_t master_state = {};
struct semaphore master_sem;

static ec_domain_t *domain1 = NULL;
static ec_domain_state_t domain1_state = {};

static ec_slave_config_t *sc_ana_in = NULL;
static ec_slave_config_state_t sc_ana_in_state = {};

// Timer
static struct timer_list timer;

/*****************************************************************************/

// process data
static uint8_t *domain1_pd; // process data memory

#define AnaInSlavePos  0, 2
#define AnaOutSlavePos 0, 1
#define DigOutSlavePos 0, 3

#define Beckhoff_EL2004 0x00000002, 0x07D43052
#define Beckhoff_EL3152 0x00000002, 0x0c503052
#define Beckhoff_EL4102 0x00000002, 0x10063052

// offsets for PDO entries
static unsigned int off_ana_in;
static unsigned int off_ana_out;
static unsigned int off_dig_out;

const static ec_pdo_entry_reg_t domain1_regs[] = {
#if EL3152_ALT_PDOS
    {AnaInSlavePos,  Beckhoff_EL3152, 0x6401, 1, &off_ana_in},
#else
    {AnaInSlavePos,  Beckhoff_EL3152, 0x3101, 2, &off_ana_in},
#endif
    {AnaOutSlavePos, Beckhoff_EL4102, 0x3001, 1, &off_ana_out},
    {DigOutSlavePos, Beckhoff_EL2004, 0x3001, 1, &off_dig_out},
    {}
};

static unsigned int counter = 0;
static unsigned int blink = 0;

/*****************************************************************************/

#if CONFIGURE_PDOS

// Analog in --------------------------

static ec_pdo_entry_info_t el3152_pdo_entries[] = {
    {0x3101, 1,  8}, // channel 1 status
    {0x3101, 2, 16}, // channel 1 value
    {0x3102, 1,  8}, // channel 2 status
    {0x3102, 2, 16}, // channel 2 value
    {0x6401, 1, 16}, // channel 1 value (alt.)
    {0x6401, 2, 16}  // channel 2 value (alt.)
};

#if EL3152_ALT_PDOS
static ec_pdo_info_t el3152_pdos[] = {
    {0x1A10, 2, el3152_pdo_entries + 4},
};

static ec_sync_info_t el3152_syncs[] = {
    {2, EC_DIR_OUTPUT},
    {3, EC_DIR_INPUT, 1, el3152_pdos},
    {0xff}
};
#else
static ec_pdo_info_t el3152_pdos[] = {
    {0x1A00, 2, el3152_pdo_entries},
    {0x1A01, 2, el3152_pdo_entries + 2}
};

static ec_sync_info_t el3152_syncs[] = {
    {2, EC_DIR_OUTPUT},
    {3, EC_DIR_INPUT, 1, el3152_pdos},
    {0xff}
};
#endif

// Analog out -------------------------

static ec_pdo_entry_info_t el4102_pdo_entries[] = {
    {0x3001, 1, 16}, // channel 1 value
    {0x3002, 1, 16}, // channel 2 value
};

static ec_pdo_info_t el4102_pdos[] = {
    {0x1600, 1, el4102_pdo_entries},
    {0x1601, 1, el4102_pdo_entries + 1}
};

static ec_sync_info_t el4102_syncs[] = {
    {2, EC_DIR_OUTPUT, 2, el4102_pdos},
    {3, EC_DIR_INPUT},
    {0xff}
};

// Digital out ------------------------

static ec_pdo_entry_info_t el2004_channels[] = {
    {0x3001, 1, 1}, // Value 1
    {0x3001, 2, 1}, // Value 2
    {0x3001, 3, 1}, // Value 3
    {0x3001, 4, 1}  // Value 4
};

static ec_pdo_info_t el2004_pdos[] = {
    {0x1600, 1, &el2004_channels[0]},
    {0x1601, 1, &el2004_channels[1]},
    {0x1602, 1, &el2004_channels[2]},
    {0x1603, 1, &el2004_channels[3]}
};

static ec_sync_info_t el2004_syncs[] = {
    {0, EC_DIR_OUTPUT, 4, el2004_pdos},
    {1, EC_DIR_INPUT},
    {0xff}
};
#endif

/*****************************************************************************/

#if SDO_ACCESS
static ec_sdo_request_t *sdo;
#endif

#if VOE_ACCESS
static ec_voe_handler_t *voe;
#endif

/*****************************************************************************/

void check_domain1_state(void)
{
    ec_domain_state_t ds;

    down(&master_sem);
    ecrt_domain_state(domain1, &ds);
    up(&master_sem);

    if (ds.working_counter != domain1_state.working_counter)
        printk(KERN_INFO PFX "Domain1: WC %u.\n", ds.working_counter);
    if (ds.wc_state != domain1_state.wc_state)
        printk(KERN_INFO PFX "Domain1: State %u.\n", ds.wc_state);

    domain1_state = ds;
}

/*****************************************************************************/

void check_master_state(void)
{
    ec_master_state_t ms;

    down(&master_sem);
    ecrt_master_state(master, &ms);
    up(&master_sem);

    if (ms.slaves_responding != master_state.slaves_responding)
        printk(KERN_INFO PFX "%u slave(s).\n", ms.slaves_responding);
    if (ms.al_states != master_state.al_states)
        printk(KERN_INFO PFX "AL states: 0x%02X.\n", ms.al_states);
    if (ms.link_up != master_state.link_up)
        printk(KERN_INFO PFX "Link is %s.\n", ms.link_up ? "up" : "down");

    master_state = ms;
}

/*****************************************************************************/

void check_slave_config_states(void)
{
    ec_slave_config_state_t s;

    down(&master_sem);
    ecrt_slave_config_state(sc_ana_in, &s);
    up(&master_sem);

    if (s.al_state != sc_ana_in_state.al_state)
        printk(KERN_INFO PFX "AnaIn: State 0x%02X.\n", s.al_state);
    if (s.online != sc_ana_in_state.online)
        printk(KERN_INFO PFX "AnaIn: %s.\n", s.online ? "online" : "offline");
    if (s.operational != sc_ana_in_state.operational)
        printk(KERN_INFO PFX "AnaIn: %soperational.\n",
                s.operational ? "" : "Not ");

    sc_ana_in_state = s;
}

/*****************************************************************************/

#if SDO_ACCESS
void read_sdo(void)
{
    switch (ecrt_sdo_request_state(sdo)) {
        case EC_REQUEST_UNUSED: // request was not used yet
            ecrt_sdo_request_read(sdo); // trigger first read
            break;
        case EC_REQUEST_BUSY:
            printk(KERN_INFO PFX "Still busy...\n");
            break;
        case EC_REQUEST_SUCCESS:
            printk(KERN_INFO PFX "SDO value: 0x%04X\n",
                    EC_READ_U16(ecrt_sdo_request_data(sdo)));
            ecrt_sdo_request_read(sdo); // trigger next read
            break;
        case EC_REQUEST_ERROR:
            printk(KERN_INFO PFX "Failed to read SDO!\n");
            ecrt_sdo_request_read(sdo); // retry reading
            break;
    }
}
#endif

/*****************************************************************************/

#if VOE_ACCESS
void read_voe(void)
{
    switch (ecrt_voe_handler_execute(voe)) {
        case EC_REQUEST_UNUSED:
            ecrt_voe_handler_read(voe); // trigger first read
            break;
        case EC_REQUEST_BUSY:
            printk(KERN_INFO PFX "VoE read still busy...\n");
            break;
        case EC_REQUEST_SUCCESS:
            printk(KERN_INFO PFX "VoE received.\n");
            // get data via ecrt_voe_handler_data(voe)
            ecrt_voe_handler_read(voe); // trigger next read
            break;
        case EC_REQUEST_ERROR:
            printk(KERN_INFO PFX "Failed to read VoE data!\n");
            ecrt_voe_handler_read(voe); // retry reading
            break;
    }
}
#endif

/*****************************************************************************/

void cyclic_task(unsigned long data)
{
    // receive process data
    down(&master_sem);
    ecrt_master_receive(master);
    ecrt_domain_process(domain1);
    up(&master_sem);

    // check process data state (optional)
    check_domain1_state();

    if (counter) {
        counter--;
    } else { // do this at 1 Hz
        counter = FREQUENCY;

        // calculate new process data
        blink = !blink;

        // check for master state (optional)
        check_master_state();

        // check for islave configuration state(s) (optional)
        check_slave_config_states();

#if SDO_ACCESS
        // read process data SDO
        read_sdo();
#endif

#if VOE_ACCESS
        read_voe();
#endif
    }

    // write process data
    EC_WRITE_U8(domain1_pd + off_dig_out, blink ? 0x06 : 0x09);

    // send process data
    down(&master_sem);
    ecrt_domain_queue(domain1);
    ecrt_master_send(master);
    up(&master_sem);

    // restart timer
    timer.expires += HZ / FREQUENCY;
    add_timer(&timer);
}

/*****************************************************************************/

void send_callback(void *cb_data)
{
    ec_master_t *m = (ec_master_t *) cb_data;
    down(&master_sem);
    ecrt_master_send_ext(m);
    up(&master_sem);
}

/*****************************************************************************/

void receive_callback(void *cb_data)
{
    ec_master_t *m = (ec_master_t *) cb_data;
    down(&master_sem);
    ecrt_master_receive(m);
    up(&master_sem);
}

/*****************************************************************************/

int __init init_mini_module(void)
{
    int ret = -1;
#if CONFIGURE_PDOS
    ec_slave_config_t *sc;
#endif
#if EXTERNAL_MEMORY
    unsigned int size;
#endif

    printk(KERN_INFO PFX "Starting...\n");

    master = ecrt_request_master(0);
    if (!master) {
        ret = -EBUSY;
        printk(KERN_ERR PFX "Requesting master 0 failed.\n");
        goto out_return;
    }

    sema_init(&master_sem, 1);
    ecrt_master_callbacks(master, send_callback, receive_callback, master);

    printk(KERN_INFO PFX "Registering domain...\n");
    if (!(domain1 = ecrt_master_create_domain(master))) {
        printk(KERN_ERR PFX "Domain creation failed!\n");
        goto out_release_master;
    }

    if (!(sc_ana_in = ecrt_master_slave_config(
                    master, AnaInSlavePos, Beckhoff_EL3152))) {
        printk(KERN_ERR PFX "Failed to get slave configuration.\n");
        goto out_release_master;
    }

#if CONFIGURE_PDOS
    printk(KERN_INFO PFX "Configuring PDOs...\n");
    if (ecrt_slave_config_pdos(sc_ana_in, EC_END, el3152_syncs)) {
        printk(KERN_ERR PFX "Failed to configure PDOs.\n");
        goto out_release_master;
    }

    if (!(sc = ecrt_master_slave_config(
                    master, AnaOutSlavePos, Beckhoff_EL4102))) {
        printk(KERN_ERR PFX "Failed to get slave configuration.\n");
        goto out_release_master;
    }

    if (ecrt_slave_config_pdos(sc, EC_END, el4102_syncs)) {
        printk(KERN_ERR PFX "Failed to configure PDOs.\n");
        goto out_release_master;
    }

    if (!(sc = ecrt_master_slave_config(
                    master, DigOutSlavePos, Beckhoff_EL2004))) {
        printk(KERN_ERR PFX "Failed to get slave configuration.\n");
        goto out_release_master;
    }

    if (ecrt_slave_config_pdos(sc, EC_END, el2004_syncs)) {
        printk(KERN_ERR PFX "Failed to configure PDOs.\n");
        goto out_release_master;
    }
#endif

#if SDO_ACCESS
    printk(KERN_INFO PFX "Creating SDO requests...\n");
    if (!(sdo = ecrt_slave_config_create_sdo_request(sc_ana_in, 0x3102, 2, 2))) {
        printk(KERN_ERR PFX "Failed to create SDO request.\n");
        goto out_release_master;
    }
    ecrt_sdo_request_timeout(sdo, 500); // ms
#endif

#if VOE_ACCESS
    printk(KERN_INFO PFX "Creating VoE handlers...\n");
    if (!(voe = ecrt_slave_config_create_voe_handler(sc_ana_in, 1000))) {
        printk(KERN_ERR PFX "Failed to create VoE handler.\n");
        goto out_release_master;
    }
#endif

    printk(KERN_INFO PFX "Registering PDO entries...\n");
    if (ecrt_domain_reg_pdo_entry_list(domain1, domain1_regs)) {
        printk(KERN_ERR PFX "PDO entry registration failed!\n");
        goto out_release_master;
    }

#if EXTERNAL_MEMORY
    if ((size = ecrt_domain_size(domain1))) {
        if (!(domain1_pd = (uint8_t *) kmalloc(size, GFP_KERNEL))) {
            printk(KERN_ERR PFX "Failed to allocate %u bytes of process data"
                    " memory!\n", size);
            goto out_release_master;
        }
        ecrt_domain_external_memory(domain1, domain1_pd);
    }
#endif

    printk(KERN_INFO PFX "Activating master...\n");
    if (ecrt_master_activate(master)) {
        printk(KERN_ERR PFX "Failed to activate master!\n");
#if EXTERNAL_MEMORY
        goto out_free_process_data;
#else
        goto out_release_master;
#endif
    }

#if !EXTERNAL_MEMORY
    // Get internal process data for domain
    domain1_pd = ecrt_domain_data(domain1);
#endif

    printk(KERN_INFO PFX "Starting cyclic sample thread.\n");
    init_timer(&timer);
    timer.function = cyclic_task;
    timer.expires = jiffies + 10;
    add_timer(&timer);

    printk(KERN_INFO PFX "Started.\n");
    return 0;

#if EXTERNAL_MEMORY
out_free_process_data:
    kfree(domain1_pd);
#endif
out_release_master:
    printk(KERN_ERR PFX "Releasing master...\n");
    ecrt_release_master(master);
out_return:
    printk(KERN_ERR PFX "Failed to load. Aborting.\n");
    return ret;
}

/*****************************************************************************/

void __exit cleanup_mini_module(void)
{
    printk(KERN_INFO PFX "Stopping...\n");

    del_timer_sync(&timer);

#if EXTERNAL_MEMORY
    kfree(domain1_pd);
#endif

    printk(KERN_INFO PFX "Releasing master...\n");
    ecrt_release_master(master);

    printk(KERN_INFO PFX "Unloading.\n");
}

/*****************************************************************************/

MODULE_LICENSE("GPL");
MODULE_AUTHOR("<NAME> <<EMAIL>>");
MODULE_DESCRIPTION("EtherCAT minimal test environment");

module_init(init_mini_module);
module_exit(cleanup_mini_module);

/*****************************************************************************/


<|start_filename|>3rdpart/tslib-1.15/tests/ts_calibrate_sdl.c<|end_filename|>
/*
 * (C) 2017 <NAME> <<EMAIL>>
 *
 * This file is part of tslib.
 *
 * ts_calibrate is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * ts_calibrate is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this tool.  If not, see <http://www.gnu.org/licenses/>.
 *
 * SPDX-License-Identifier: GPL-2.0+
 */

#include <SDL2/SDL.h>

#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <errno.h>
#include <stdint.h>
#include <unistd.h>
#include <fcntl.h>

#include <tslib.h>
#include "ts_calibrate.h"
#include "sdlutils.h"

static void help(void)
{
	struct ts_lib_version_data *ver = ts_libversion();

	print_ascii_logo();

	printf("tslib %s / libts ABI version %d (0x%06X)\n",
		ver->package_version, ver->version_num >> 16, ver->version_num);
	printf("\n");
	printf("Usage: ts_calibrate [-i <device>]\n");
	printf("\n");
	printf("        <device>       Override the input device to use\n");
	printf("\n");
}

static void get_sample(struct tsdev *ts, calibration *cal,
		       int index, int x, int y, char *name,
		       SDL_Renderer *r)
{
	static int last_x = -1, last_y;
	SDL_Event ev;

	if (last_x != -1) {

#define NR_STEPS 20
		int dx = ((x - last_x) << 16) / NR_STEPS;
		int dy = ((y - last_y) << 16) / NR_STEPS;
		int i;

		last_x <<= 16;
		last_y <<= 16;
		for (i = 0; i < NR_STEPS; i++) {
			SDL_SetRenderDrawColor(r, 0, 0, 0, 255);
			SDL_RenderClear(r);
			draw_crosshair(r, last_x >> 16, last_y >> 16);
			SDL_RenderPresent(r);

			last_x += dx;
			last_y += dy;
		}
	}

	SDL_SetRenderDrawColor(r, 0, 0, 0, 255);
	SDL_RenderClear(r);
	draw_crosshair(r, x, y);
	SDL_RenderPresent(r);

	getxy(ts, &cal->x[index], &cal->y[index]);

	SDL_SetRenderDrawColor(r, 0, 0, 0, 255);
	SDL_RenderClear(r);
	draw_crosshair(r, x, y);
	SDL_RenderPresent(r);

	last_x = cal->xfb[index] = x;
	last_y = cal->yfb[index] = y;

	printf("%s : X = %4d Y = %4d\n", name, cal->x[index], cal->y[index]);

	SDL_PollEvent(&ev);
	switch (ev.type) {
	case SDL_KEYDOWN:
	case SDL_QUIT:
		SDL_ShowCursor(SDL_ENABLE);
		SDL_Quit();
	}
}

static void clearbuf(struct tsdev *ts)
{
	int fd = ts_fd(ts);
	fd_set fdset;
	struct timeval tv;
	int nfds;
	struct ts_sample sample;

	while (1) {
		FD_ZERO(&fdset);
		FD_SET(fd, &fdset);

		tv.tv_sec = 0;
		tv.tv_usec = 0;

		nfds = select(fd + 1, &fdset, NULL, NULL, &tv);
		if (nfds == 0)
			break;

		if (ts_read_raw(ts, &sample, 1) < 0) {
			perror("ts_read");
			exit(1);
		}
	}
}

int main(int argc, char **argv)
{
	struct tsdev *ts;
	const char *tsdevice = NULL;
	int ret;
	int i;
	SDL_Window *sdlWindow;
	SDL_Renderer *sdlRenderer;
	calibration cal = {
		.x = { 0 },
		.y = { 0 },
	};
	int xres;
	int yres;
	char *calfile = NULL;
	int cal_fd;
	char cal_buffer[256];
	uint32_t len;
	SDL_DisplayMode currentDisplay;

	while (1) {
		const struct option long_options[] = {
			{ "help",         no_argument,       NULL, 'h' },
			{ "idev",         required_argument, NULL, 'i' },
		};

		int option_index = 0;
		int c = getopt_long(argc, argv, "hi:", long_options,
				    &option_index);

		errno = 0;
		if (c == -1)
			break;

		switch (c) {
		case 'h':
			help();
			return 0;

		case 'i':
			tsdevice = optarg;
			break;
		default:
			help();
			return 0;
		}

		if (errno) {
			char str[9];

			sprintf(str, "option ?");
			str[7] = c & 0xff;
			perror(str);
		}
	}

	ts = ts_setup(tsdevice, 0);
	if (!ts) {
		perror("ts_setup");
		return errno;
	}

	SDL_SetMainReady();

	if (SDL_Init(SDL_INIT_VIDEO) < 0) {
		SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
			     "Couldn't initialize SDL: %s", SDL_GetError());
		goto out;
	}

	if (SDL_CreateWindowAndRenderer(0, 0,
					SDL_WINDOW_FULLSCREEN_DESKTOP,
					&sdlWindow, &sdlRenderer)) {
		SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
			     "Couldn't create window and renderer: %s",
			     SDL_GetError());
		goto out;
	}

	SDL_ShowCursor(SDL_DISABLE);
	SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");

	SDL_SetRenderDrawColor(sdlRenderer, 0, 0, 0, 255);
	SDL_RenderClear(sdlRenderer);

	/* TODO add support for selecting the display */
	if (SDL_GetNumVideoDisplays() > 1) {
		SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
			     "More than one display found");
		goto out;
	}

	ret = SDL_GetCurrentDisplayMode(0, &currentDisplay);
	if (ret) {
		SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
			     "Could not get display mode for display #1: %s",
			     SDL_GetError());
		goto out;
	}

	xres = currentDisplay.w;
	yres = currentDisplay.h;

	printf("xres = %d, yres = %d\n", xres, yres);

	/* Clear the buffer */
	clearbuf(ts);

	get_sample(ts, &cal, 0, 50,        50,        "Top left", sdlRenderer);
	clearbuf(ts);
	get_sample(ts, &cal, 1, xres - 50, 50,        "Top right", sdlRenderer);
	clearbuf(ts);
	get_sample(ts, &cal, 2, xres - 50, yres - 50, "Bot right", sdlRenderer);
	clearbuf(ts);
	get_sample(ts, &cal, 3, 50,        yres - 50, "Bot left", sdlRenderer);
	clearbuf(ts);
	get_sample(ts, &cal, 4, xres / 2,  yres / 2,  "Center", sdlRenderer);

	if (perform_calibration (&cal)) {
		printf("Calibration constants: ");
		for (i = 0; i < 7; i++)
			printf("%d ", cal.a[i]);
		printf("\n");
		if ((calfile = getenv("TSLIB_CALIBFILE")) != NULL) {
			cal_fd = open(calfile, O_CREAT | O_TRUNC | O_RDWR,
				      S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
		} else {
			cal_fd = open(TS_POINTERCAL, O_CREAT | O_TRUNC | O_RDWR,
				      S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
		}
		if (cal_fd < 0) {
			perror("open");
			ts_close(ts);
			exit(1);
		}

		len = sprintf(cal_buffer, "%d %d %d %d %d %d %d %d %d",
			      cal.a[1], cal.a[2], cal.a[0],
			      cal.a[4], cal.a[5], cal.a[3], cal.a[6],
			      xres, yres);
		if (write(cal_fd, cal_buffer, len) == -1) {
			perror("write");
			ts_close(ts);
			exit(1);
		}
		close(cal_fd);
		i = 0;
	} else {
		printf("Calibration failed.\n");
		i = -1;
	}

out:
	if (ts)
		ts_close(ts);

	return 0;
}


<|start_filename|>3rdpart/ethercat-1.5.2/tool/Command.cpp<|end_filename|>
/*****************************************************************************
 *
 *  $Id: Command.cpp,v d461b1f07296 2012/11/30 19:15:31 fp $
 *
 *  Copyright (C) 2006-2009  <NAME>, Ingenieurgemeinschaft IgH
 *
 *  This file is part of the IgH EtherCAT Master.
 *
 *  The IgH EtherCAT Master is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License version 2, as
 *  published by the Free Software Foundation.
 *
 *  The IgH EtherCAT Master is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 *  Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with the IgH EtherCAT Master; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 *  vim: expandtab
 *
 ****************************************************************************/

#include <map>
using namespace std;

#include "Command.h"
#include "MasterDevice.h"
#include "NumberListParser.h"

/*****************************************************************************/

typedef map<uint16_t, ec_ioctl_config_t> AliasMap;
typedef map<uint16_t, AliasMap> ConfigMap;

/*****************************************************************************/

class MasterIndexParser:
    public NumberListParser
{
    protected:
        int getMax() {
            MasterDevice dev;
            dev.setIndex(0U);
            dev.open(MasterDevice::Read);
            return (int) dev.getMasterCount() - 1;
        };
};

/*****************************************************************************/

class SlaveAliasParser:
    public NumberListParser
{
    public:
        SlaveAliasParser(ec_ioctl_master_t &master, MasterDevice &dev):
            master(master), dev(dev) {}

    protected:
        int getMax() {
            unsigned int i;

            uint16_t maxAlias = 0;
            for (i = 0; i < master.slave_count; i++) {
                ec_ioctl_slave_t slave;
                dev.getSlave(&slave, i);
                if (slave.alias > maxAlias) {
                    maxAlias = slave.alias;
                }
            }
            return maxAlias ? maxAlias : -1;
        };

    private:
        ec_ioctl_master_t &master;
        MasterDevice &dev;
};

/*****************************************************************************/

class ConfigAliasParser:
    public NumberListParser
{
    public:
        ConfigAliasParser(unsigned int maxAlias):
            maxAlias(maxAlias) {}

    protected:
        int getMax() { return maxAlias; };

    private:
        unsigned int maxAlias;
};

/*****************************************************************************/

class PositionParser:
    public NumberListParser
{
    public:
        PositionParser(unsigned int count):
            count(count) {}

    protected:
        int getMax() {
            return count - 1;
        };

    private:
        const unsigned int count;
};

/*****************************************************************************/

class AliasPositionParser:
    public NumberListParser
{
    public:
        AliasPositionParser(const AliasMap &aliasMap):
            aliasMap(aliasMap) {}

    protected:
        int getMax() {
            AliasMap::const_iterator i;
            int maxPos = -1;

            for (i = aliasMap.begin(); i != aliasMap.end(); i++) {
                if (i->first > maxPos) {
                    maxPos = i->first;
                }
            }

            return maxPos;
        };

    private:
        const AliasMap &aliasMap;
};

/*****************************************************************************/

Command::Command(const string &name, const string &briefDesc):
    name(name),
    briefDesc(briefDesc),
    verbosity(Normal)
{
}

/*****************************************************************************/

Command::~Command()
{
}

/*****************************************************************************/

void Command::setMasters(const string &m)
{
    masters = m;
};

/*****************************************************************************/

void Command::setVerbosity(Verbosity v)
{
    verbosity = v;
};

/*****************************************************************************/

void Command::setAliases(const string &a)
{
    aliases = a;
};

/*****************************************************************************/

void Command::setPositions(const string &p)
{
    positions = p;
};

/*****************************************************************************/

void Command::setDomains(const string &d)
{
    domains = d;
};

/*****************************************************************************/

void Command::setDataType(const string &t)
{
    dataType = t;
};

/*****************************************************************************/

void Command::setForce(bool f)
{
    force = f;
};

/*****************************************************************************/

void Command::setOutputFile(const string &f)
{
    outputFile = f;
};

/*****************************************************************************/

void Command::setSkin(const string &s)
{
    skin = s;
};

/****************************************************************************/

bool Command::matchesSubstr(const string &cmd) const
{
    return name.substr(0, cmd.length()) == cmd;
}

/****************************************************************************/

bool Command::matchesAbbrev(const string &abb) const
{
    unsigned int i;
    size_t pos = 0;

    for (i = 0; i < abb.length(); i++) {
        pos = name.find(abb[i], pos);
        if (pos == string::npos)
            return false;
    }

    return true;
}

/*****************************************************************************/

string Command::numericInfo()
{
    stringstream str;

    str << "Numerical values can be specified either with decimal (no" << endl
        << "prefix), octal (prefix '0') or hexadecimal (prefix '0x') base."
        << endl;

    return str.str();
}

/*****************************************************************************/

void Command::throwInvalidUsageException(const stringstream &s) const
{
    throw InvalidUsageException(s);
}

/*****************************************************************************/

void Command::throwCommandException(const string &msg) const
{
    throw CommandException(msg);
}

/*****************************************************************************/

void Command::throwCommandException(const stringstream &s) const
{
    throw CommandException(s);
}

/*****************************************************************************/

void Command::throwSingleSlaveRequired(unsigned int size) const
{
    stringstream err;

    err << "The slave selection matches " << size << " slaves. '"
        << name << "' requires a single slave.";

    throwInvalidUsageException(err);
}

/*****************************************************************************/

Command::MasterIndexList Command::getMasterIndices() const
{
    MasterIndexList indices;

    try {
        MasterIndexParser p;
        indices = p.parse(masters.c_str());
    } catch (MasterDeviceException &e) {
        stringstream err;
        err << "Failed to obtain number of masters: " << e.what();
        throwCommandException(err);
    } catch (runtime_error &e) {
        stringstream err;
        err << "Invalid master argument '" << masters << "': " << e.what();
        throwInvalidUsageException(err);
    }

    return indices;
}

/*****************************************************************************/

unsigned int Command::getSingleMasterIndex() const
{
    MasterIndexList masterIndices = getMasterIndices();

    if (masterIndices.size() != 1) {
        stringstream err;
        err << getName() << " requires to select a single master!";
        throwInvalidUsageException(err);
    }

    return masterIndices.front();
}

/*****************************************************************************/

Command::SlaveList Command::selectedSlaves(MasterDevice &m)
{
    ec_ioctl_master_t master;
    unsigned int i;
    ec_ioctl_slave_t slave;
    SlaveList list;

    m.getMaster(&master);

    if (aliases == "-") { // no alias given
        PositionParser pp(master.slave_count);
        NumberListParser::List posList = pp.parse(positions.c_str());
        NumberListParser::List::const_iterator pi;

        for (pi = posList.begin(); pi != posList.end(); pi++) {
            if (*pi < master.slave_count) {
                m.getSlave(&slave, *pi);
                list.push_back(slave);
            }
        }
    } else { // aliases given
        SlaveAliasParser ap(master, m);
        NumberListParser::List aliasList = ap.parse(aliases.c_str());
        NumberListParser::List::const_iterator ai;

        for (ai = aliasList.begin(); ai != aliasList.end(); ai++) {

            // gather slaves with that alias (and following)
            uint16_t lastAlias = 0;
            vector<ec_ioctl_slave_t> aliasSlaves;

            for (i = 0; i < master.slave_count; i++) {
                m.getSlave(&slave, i);
                if (slave.alias) {
                    if (lastAlias && lastAlias == *ai && slave.alias != *ai) {
                        // ignore multiple ocurrences of the same alias to
                        // assure consistency for the position argument
                        break;
                    }
                    lastAlias = slave.alias;
                }
                if (lastAlias == *ai) {
                    aliasSlaves.push_back(slave);
                }
            }

            PositionParser pp(aliasSlaves.size());
            NumberListParser::List posList = pp.parse(positions.c_str());
            NumberListParser::List::const_iterator pi;

            for (pi = posList.begin(); pi != posList.end(); pi++) {
                if (*pi < aliasSlaves.size()) {
                    list.push_back(aliasSlaves[*pi]);
                }
            }
        }
    }

    return list;
}

/*****************************************************************************/

bool operator<(
        const ec_ioctl_config_t &a,
        const ec_ioctl_config_t &b
        )
{
    return a.alias < b.alias
        || (a.alias == b.alias && a.position < b.position);
}

/*****************************************************************************/

Command::ConfigList Command::selectedConfigs(MasterDevice &m)
{
    unsigned int i;
    ec_ioctl_master_t master;
    ec_ioctl_config_t config;
    ConfigList list;
    stringstream err;

    m.getMaster(&master);

    if (aliases == "-" && positions == "-") { // shortcut
        for (i = 0; i < master.config_count; i++) {
            m.getConfig(&config, i);
            list.push_back(config);
        }
    } else { // take the long way home...
        ConfigMap configs;
        uint16_t maxAlias = 0;

        // fill cascaded map structure with all configs
        for (i = 0; i < master.config_count; i++) {
            m.getConfig(&config, i);
            AliasMap &aliasMap = configs[config.alias];
            aliasMap[config.position] = config;
            if (config.alias > maxAlias) {
                maxAlias = config.alias;
            }
        }

        ConfigAliasParser ap(maxAlias);
        NumberListParser::List aliasList = ap.parse(aliases.c_str());
        NumberListParser::List::const_iterator ai;

        for (ai = aliasList.begin(); ai != aliasList.end(); ai++) {

            ConfigMap::iterator ci = configs.find(*ai);
            if (ci == configs.end()) {
                continue;
            }

            AliasMap &aliasMap = configs[*ai];
            AliasPositionParser pp(aliasMap);
            NumberListParser::List posList = pp.parse(positions.c_str());
            NumberListParser::List::const_iterator pi;

            for (pi = posList.begin(); pi != posList.end(); pi++) {
                AliasMap::const_iterator ci;

                ci = aliasMap.find(*pi);
                if (ci != aliasMap.end()) {
                    list.push_back(ci->second);
                }
            }
        }
    }

    list.sort();
    return list;
}

/****************************************************************************/

Command::DomainList Command::selectedDomains(MasterDevice &m,
        const ec_ioctl_master_t &io)
{
    DomainList list;

    PositionParser pp(io.domain_count);
    NumberListParser::List domList = pp.parse(domains.c_str());
    NumberListParser::List::const_iterator di;

    for (di = domList.begin(); di != domList.end(); di++) {
        if (*di < io.domain_count) {
            ec_ioctl_domain_t d;
            m.getDomain(&d, *di);
            list.push_back(d);
        }
    }

    return list;
}

/****************************************************************************/

string Command::alStateString(uint8_t state)
{
    string ret;

    switch (state & EC_SLAVE_STATE_MASK) {
        case 1: ret = "INIT"; break;
        case 2: ret = "PREOP"; break;
        case 3: ret = "BOOT"; break;
        case 4: ret = "SAFEOP"; break;
        case 8: ret = "OP"; break;
        default: ret = "???";
    }

    if (state & EC_SLAVE_STATE_ACK_ERR) {
        ret += "+ERROR";
    }

    return ret;
}

/****************************************************************************/


<|start_filename|>rootfs/buildroot-2017.11.1/package/python-dataproperty/python-dataproperty.mk<|end_filename|>
################################################################################
#
# python-dataproperty
#
################################################################################

PYTHON_DATAPROPERTY_VERSION = 0.25.6
PYTHON_DATAPROPERTY_SOURCE = DataProperty-$(PYTHON_DATAPROPERTY_VERSION).tar.gz
PYTHON_DATAPROPERTY_SITE = https://pypi.python.org/packages/bb/4b/d9a8d24aa27bd2827d70e68f1f389cdd824e5bea7541993fac8cb35100ed
PYTHON_DATAPROPERTY_SETUP_TYPE = setuptools
PYTHON_DATAPROPERTY_LICENSE = MIT
PYTHON_DATAPROPERTY_LICENSE_FILES = LICENSE

$(eval $(python-package))


<|start_filename|>3rdpart/ethercat-1.5.2/lib/domain.h<|end_filename|>
/******************************************************************************
 *
 *  $Id: domain.h,v bc2d4bf9cbe5 2012/09/06 18:22:24 fp $
 *
 *  Copyright (C) 2006-2009  <NAME>, Ingenieurgemeinschaft IgH
 *
 *  This file is part of the IgH EtherCAT master userspace library.
 *
 *  The IgH EtherCAT master userspace library is free software; you can
 *  redistribute it and/or modify it under the terms of the GNU Lesser General
 *  Public License as published by the Free Software Foundation; version 2.1
 *  of the License.
 *
 *  The IgH EtherCAT master userspace library is distributed in the hope that
 *  it will be useful, but WITHOUT ANY WARRANTY; without even the implied
 *  warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public License
 *  along with the IgH EtherCAT master userspace library. If not, see
 *  <http://www.gnu.org/licenses/>.
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 *****************************************************************************/

#include "include/ecrt.h"

/*****************************************************************************/

struct ec_domain {
    ec_domain_t *next;
    unsigned int index;
    ec_master_t *master;
    uint8_t *process_data;
};

/*****************************************************************************/

void ec_domain_clear(ec_domain_t *);

/*****************************************************************************/


<|start_filename|>3rdpart/ethercat-1.5.2/examples/rtai_rtdm_dc/main.c<|end_filename|>
/******************************************************************************
 *
 *  $Id: main.c,v c5c81a52fc30 2013/02/12 15:37:11 fp $
 *
 *  Copyright (C)      2011  IgH <NAME>
 *                     2012  <NAME> <<EMAIL>>
 *
 *  This file is part of the IgH EtherCAT master
 *
 *  The IgH EtherCAT Master is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License version 2, as
 *  published by the Free Software Foundation.
 *
 *  The IgH EtherCAT master is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
 *  Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with the IgH EtherCAT master. If not, see <http://www.gnu.org/licenses/>.
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 *****************************************************************************/

#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <signal.h>

#include <rtai_lxrt.h>
#include <rtdm/rtdm.h>

#include "ecrt.h"

#define rt_printf(X, Y)

#define NSEC_PER_SEC 1000000000

RT_TASK *task;

static unsigned int cycle_ns = 1000000; /* 1 ms */

static int run = 1;

/****************************************************************************/

// EtherCAT
static ec_master_t *master = NULL;
static ec_master_state_t master_state = {};

static ec_domain_t *domain1 = NULL;
static ec_domain_state_t domain1_state = {};

static uint8_t *domain1_pd = NULL;

static ec_slave_config_t *sc_dig_out_01 = NULL;

/****************************************************************************/

// EtherCAT distributed clock variables

#define DC_FILTER_CNT          1024
#define SYNC_MASTER_TO_REF        1

static uint64_t dc_start_time_ns = 0LL;
static uint64_t dc_time_ns = 0;
#if SYNC_MASTER_TO_REF
static uint8_t  dc_started = 0;
static int32_t  dc_diff_ns = 0;
static int32_t  prev_dc_diff_ns = 0;
static int64_t  dc_diff_total_ns = 0LL;
static int64_t  dc_delta_total_ns = 0LL;
static int      dc_filter_idx = 0;
static int64_t  dc_adjust_ns;
#endif
static int64_t  system_time_base = 0LL;
static uint64_t wakeup_time = 0LL;
static uint64_t overruns = 0LL;

/****************************************************************************/

// process data

#define BusCoupler01_Pos  0, 0
#define DigOutSlave01_Pos 0, 1

#define Beckhoff_EK1100 0x00000002, 0x044c2c52
#define Beckhoff_EL2004 0x00000002, 0x07d43052

// offsets for PDO entries
static unsigned int off_dig_out0 = 0;

// process data

const static ec_pdo_entry_reg_t domain1_regs[] = {
   {DigOutSlave01_Pos, Beckhoff_EL2004, 0x7000, 0x01, &off_dig_out0, NULL},
   {}
};

/****************************************************************************/

/* Slave 1, "EL2004"
 * Vendor ID:       0x00000002
 * Product code:    0x07d43052
 * Revision number: 0x00100000
 */

ec_pdo_entry_info_t slave_1_pdo_entries[] = {
   {0x7000, 0x01, 1}, /* Output */
   {0x7010, 0x01, 1}, /* Output */
   {0x7020, 0x01, 1}, /* Output */
   {0x7030, 0x01, 1}, /* Output */
};

ec_pdo_info_t slave_1_pdos[] = {
   {0x1600, 1, slave_1_pdo_entries + 0}, /* Channel 1 */
   {0x1601, 1, slave_1_pdo_entries + 1}, /* Channel 2 */
   {0x1602, 1, slave_1_pdo_entries + 2}, /* Channel 3 */
   {0x1603, 1, slave_1_pdo_entries + 3}, /* Channel 4 */
};

ec_sync_info_t slave_1_syncs[] = {
   {0, EC_DIR_OUTPUT, 4, slave_1_pdos + 0, EC_WD_ENABLE},
   {0xff}
};

/*****************************************************************************
 * Realtime task
 ****************************************************************************/

/** Get the time in ns for the current cpu, adjusted by system_time_base.
 *
 * \attention Rather than calling rt_get_time_ns() directly, all application
 * time calls should use this method instead.
 *
 * \ret The time in ns.
 */
uint64_t system_time_ns(void)
{
    RTIME time = rt_get_time_ns();

    if (system_time_base > time) {
        rt_printk("%s() error: system_time_base greater than"
                " system time (system_time_base: %lld, time: %llu\n",
                __func__, system_time_base, time);
        return time;
    }
    else {
        return time - system_time_base;
    }
}

/****************************************************************************/

/** Convert system time to RTAI time in counts (via the system_time_base).
 */
RTIME system2count(
        uint64_t time
        )
{
    RTIME ret;

    if ((system_time_base < 0) &&
            ((uint64_t) (-system_time_base) > time)) {
        rt_printk("%s() error: system_time_base less than"
                " system time (system_time_base: %lld, time: %llu\n",
                __func__, system_time_base, time);
        ret = time;
    }
    else {
        ret = time + system_time_base;
    }

    return nano2count(ret);
}

/*****************************************************************************/

/** Synchronise the distributed clocks
 */
void sync_distributed_clocks(void)
{
#if SYNC_MASTER_TO_REF
    uint32_t ref_time = 0;
    uint64_t prev_app_time = dc_time_ns;
#endif

    dc_time_ns = system_time_ns();

    // set master time in nano-seconds
    ecrt_master_application_time(master, dc_time_ns);

#if SYNC_MASTER_TO_REF
    // get reference clock time to synchronize master cycle
    ecrt_master_reference_clock_time(master, &ref_time);
    dc_diff_ns = (uint32_t) prev_app_time - ref_time;
#else
    // sync reference clock to master
    ecrt_master_sync_reference_clock(master);
#endif

    // call to sync slaves to ref slave
    ecrt_master_sync_slave_clocks(master);
}

/*****************************************************************************/

/** Return the sign of a number
 *
 * ie -1 for -ve value, 0 for 0, +1 for +ve value
 *
 * \retval the sign of the value
 */
#define sign(val) \
    ({ typeof (val) _val = (val); \
    ((_val > 0) - (_val < 0)); })

/*****************************************************************************/

/** Update the master time based on ref slaves time diff
 *
 * called after the ethercat frame is sent to avoid time jitter in
 * sync_distributed_clocks()
 */
void update_master_clock(void)
{
#if SYNC_MASTER_TO_REF
    // calc drift (via un-normalised time diff)
    int32_t delta = dc_diff_ns - prev_dc_diff_ns;
    prev_dc_diff_ns = dc_diff_ns;

    // normalise the time diff
    dc_diff_ns =
        ((dc_diff_ns + (cycle_ns / 2)) % cycle_ns) - (cycle_ns / 2);

    // only update if primary master
    if (dc_started) {

        // add to totals
        dc_diff_total_ns += dc_diff_ns;
        dc_delta_total_ns += delta;
        dc_filter_idx++;

        if (dc_filter_idx >= DC_FILTER_CNT) {
            // add rounded delta average
            dc_adjust_ns +=
                ((dc_delta_total_ns + (DC_FILTER_CNT / 2)) / DC_FILTER_CNT);

            // and add adjustment for general diff (to pull in drift)
            dc_adjust_ns += sign(dc_diff_total_ns / DC_FILTER_CNT);

            // limit crazy numbers (0.1% of std cycle time)
            if (dc_adjust_ns < -1000) {
                dc_adjust_ns = -1000;
            }
            if (dc_adjust_ns > 1000) {
                dc_adjust_ns =  1000;
            }

            // reset
            dc_diff_total_ns = 0LL;
            dc_delta_total_ns = 0LL;
            dc_filter_idx = 0;
        }

        // add cycles adjustment to time base (including a spot adjustment)
        system_time_base += dc_adjust_ns + sign(dc_diff_ns);
    }
    else {
        dc_started = (dc_diff_ns != 0);

        if (dc_started) {
            // output first diff
            rt_printk("First master diff: %d.\n", dc_diff_ns);

            // record the time of this initial cycle
            dc_start_time_ns = dc_time_ns;
        }
    }
#endif
}

/****************************************************************************/

void rt_check_domain_state(void)
{
    ec_domain_state_t ds = {};

    ecrt_domain_state(domain1, &ds);

    if (ds.working_counter != domain1_state.working_counter) {
        rt_printf("Domain1: WC %u.\n", ds.working_counter);
    }

    if (ds.wc_state != domain1_state.wc_state) {
        rt_printf("Domain1: State %u.\n", ds.wc_state);
    }

    domain1_state = ds;
}

/****************************************************************************/

void rt_check_master_state(void)
{
    ec_master_state_t ms;

    ecrt_master_state(master, &ms);

    if (ms.slaves_responding != master_state.slaves_responding) {
        rt_printf("%u slave(s).\n", ms.slaves_responding);
    }

    if (ms.al_states != master_state.al_states) {
        rt_printf("AL states: 0x%02X.\n", ms.al_states);
    }

    if (ms.link_up != master_state.link_up) {
        rt_printf("Link is %s.\n", ms.link_up ? "up" : "down");
    }

    master_state = ms;
}

/****************************************************************************/

/** Wait for the next period
 */
void wait_period(void)
{
    while (1)
    {
        RTIME wakeup_count = system2count(wakeup_time);
        RTIME current_count = rt_get_time();

        if ((wakeup_count < current_count)
                || (wakeup_count > current_count + (50 * cycle_ns))) {
            rt_printk("%s(): unexpected wake time!\n", __func__);
        }

        switch (rt_sleep_until(wakeup_count)) {
            case RTE_UNBLKD:
                rt_printk("rt_sleep_until(): RTE_UNBLKD\n");
                continue;

            case RTE_TMROVRN:
                rt_printk("rt_sleep_until(): RTE_TMROVRN\n");
                overruns++;

                if (overruns % 100 == 0) {
                    // in case wake time is broken ensure other processes get
                    // some time slice (and error messages can get displayed)
                    rt_sleep(cycle_ns / 100);
                }
                break;

            default:
                break;
        }

        // done if we got to here
        break;
    }

    // calc next wake time (in sys time)
    wakeup_time += cycle_ns;
}

/****************************************************************************/

void my_cyclic(void)
{
    int cycle_counter = 0;
    unsigned int blink = 0;

    // oneshot mode to allow adjustable wake time
    rt_set_oneshot_mode();

    // set first wake time in a few cycles
    wakeup_time = system_time_ns() + 10 * cycle_ns;

    // start the timer
    start_rt_timer(nano2count(cycle_ns));

    rt_make_hard_real_time();

    while (run) {
        // wait for next period (using adjustable system time)
        wait_period();

        cycle_counter++;

        if (!run) {
            break;
        }

        // receive EtherCAT
        ecrt_master_receive(master);
        ecrt_domain_process(domain1);

        rt_check_domain_state();

        if (!(cycle_counter % 1000)) {
            rt_check_master_state();
        }

        if (!(cycle_counter % 200)) {
            blink = !blink;
        }

        EC_WRITE_U8(domain1_pd + off_dig_out0, blink ? 0x00 : 0x0F);

        // queue process data
        ecrt_domain_queue(domain1);

        // sync distributed clock just before master_send to set
        // most accurate master clock time
        sync_distributed_clocks();

        // send EtherCAT data
        ecrt_master_send(master);

        // update the master clock
        // Note: called after ecrt_master_send() to reduce time
        // jitter in the sync_distributed_clocks() call
        update_master_clock();
    }

    rt_make_soft_real_time();
    stop_rt_timer();
}

/****************************************************************************
 * Signal handler
 ***************************************************************************/

void signal_handler(int sig)
{
    run = 0;
}

/****************************************************************************
 * Main function
 ***************************************************************************/

int main(int argc, char *argv[])
{
    ec_slave_config_t *sc_ek1100;
    int ret;

    signal(SIGTERM, signal_handler);
    signal(SIGINT, signal_handler);

    mlockall(MCL_CURRENT | MCL_FUTURE);

    printf("Requesting master...\n");
    master = ecrt_request_master(0);
    if (!master) {
        return -1;
    }

    domain1 = ecrt_master_create_domain(master);
    if (!domain1) {
        return -1;
    }

    printf("Creating slave configurations...\n");

    // Create configuration for bus coupler
    sc_ek1100 =
        ecrt_master_slave_config(master, BusCoupler01_Pos, Beckhoff_EK1100);
    if (!sc_ek1100) {
        return -1;
    }

    sc_dig_out_01 =
        ecrt_master_slave_config(master, DigOutSlave01_Pos, Beckhoff_EL2004);
    if (!sc_dig_out_01) {
        fprintf(stderr, "Failed to get slave configuration.\n");
        return -1;
    }

    if (ecrt_slave_config_pdos(sc_dig_out_01, EC_END, slave_1_syncs)) {
        fprintf(stderr, "Failed to configure PDOs.\n");
        return -1;
    }

    if (ecrt_domain_reg_pdo_entry_list(domain1, domain1_regs)) {
        fprintf(stderr, "PDO entry registration failed!\n");
        return -1;
    }

    /* Set the initial master time and select a slave to use as the DC
     * reference clock, otherwise pass NULL to auto select the first capable
     * slave. Note: This can be used whether the master or the ref slave will
     * be used as the systems master DC clock.
     */
    dc_start_time_ns = system_time_ns();
    dc_time_ns = dc_start_time_ns;

    /* Attention: The initial application time is also used for phase
     * calculation for the SYNC0/1 interrupts. Please be sure to call it at
     * the correct phase to the realtime cycle.
     */
    ecrt_master_application_time(master, dc_start_time_ns);

    ret = ecrt_master_select_reference_clock(master, sc_ek1100);
    if (ret < 0) {
        fprintf(stderr, "Failed to select reference clock: %s\n",
                strerror(-ret));
        return ret;
    }

    printf("Activating master...\n");
    if (ecrt_master_activate(master)) {
        return -1;
    }

    if (!(domain1_pd = ecrt_domain_data(domain1))) {
        fprintf(stderr, "Failed to get domain data pointer.\n");
        return -1;
    }

    /* Create cyclic RT-thread */
    struct sched_param param;
    param.sched_priority = sched_get_priority_max(SCHED_FIFO) - 1;
    if (sched_setscheduler(0, SCHED_FIFO, &param) == -1) {
        puts("ERROR IN SETTING THE SCHEDULER");
        perror("errno");
        return -1;
    }

    task = rt_task_init(nam2num("ec_rtai_rtdm_example"),
            0 /* priority */, 0 /* stack size */, 0 /* msg size */);

    my_cyclic();

    rt_task_delete(task);

    printf("End of Program\n");
    ecrt_release_master(master);

    return 0;
}

/****************************************************************************/


<|start_filename|>3rdpart/ethercat-1.5.2/master/globals.h<|end_filename|>
/******************************************************************************
 *
 *  $Id: globals.h,v d461b1f07296 2012/11/30 19:15:31 fp $
 *
 *  Copyright (C) 2006-2008  <NAME>, Ingenieurgemeinschaft IgH
 *
 *  This file is part of the IgH EtherCAT Master.
 *
 *  The IgH EtherCAT Master is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License version 2, as
 *  published by the Free Software Foundation.
 *
 *  The IgH EtherCAT Master is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 *  Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with the IgH EtherCAT Master; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 *****************************************************************************/

/** \file
 * Global definitions and macros.
 */

/*****************************************************************************/

#ifndef __EC_MASTER_GLOBALS_H__
#define __EC_MASTER_GLOBALS_H__

#include "../globals.h"
#include "../include/ecrt.h"

/******************************************************************************
 * EtherCAT master
 *****************************************************************************/

/** Datagram timeout in microseconds. */
#define EC_IO_TIMEOUT 500

/** SDO injection timeout in microseconds. */
#define EC_SDO_INJECTION_TIMEOUT 10000

/** Time to send a byte in nanoseconds.
 *
 * t_ns = 1 / (100 MBit/s / 8 bit/byte) = 80 ns/byte
 */
#define EC_BYTE_TRANSMISSION_TIME_NS 80

/** Number of state machine retries on datagram timeout. */
#define EC_FSM_RETRIES 3

/** Seconds to wait before fetching SDO dictionary
    after slave entered PREOP state. */
#define EC_WAIT_SDO_DICT 3

/** Minimum size of a buffer used with ec_state_string(). */
#define EC_STATE_STRING_SIZE 32

/** Maximum SII size in words, to avoid infinite reading. */
#define EC_MAX_SII_SIZE 4096

/** Number of statistic rate intervals to maintain. */
#define EC_RATE_COUNT 3

/******************************************************************************
 * EtherCAT protocol
 *****************************************************************************/

/** Size of an EtherCAT frame header. */
#define EC_FRAME_HEADER_SIZE 2

/** Size of an EtherCAT datagram header. */
#define EC_DATAGRAM_HEADER_SIZE 10

/** Size of an EtherCAT datagram footer. */
#define EC_DATAGRAM_FOOTER_SIZE 2

/** Size of the EtherCAT address field. */
#define EC_ADDR_LEN 4

/** Resulting maximum data size of a single datagram in a frame. */
#define EC_MAX_DATA_SIZE (ETH_DATA_LEN - EC_FRAME_HEADER_SIZE \
                          - EC_DATAGRAM_HEADER_SIZE - EC_DATAGRAM_FOOTER_SIZE)

/** Mailbox header size.  */
#define EC_MBOX_HEADER_SIZE 6

/** Word offset of first SII category. */
#define EC_FIRST_SII_CATEGORY_OFFSET 0x40

/** Size of a sync manager configuration page. */
#define EC_SYNC_PAGE_SIZE 8

/** Maximum number of FMMUs per slave. */
#define EC_MAX_FMMUS 16

/** Size of an FMMU configuration page. */
#define EC_FMMU_PAGE_SIZE 16

/** Number of DC sync signals. */
#define EC_SYNC_SIGNAL_COUNT 2

/** Size of the datagram description string.
 *
 * This is also used as the maximum lenth of EoE device names.
 **/
#define EC_DATAGRAM_NAME_SIZE 20

/** Slave state mask.
 *
 * Apply this mask to a slave state byte to get the slave state without
 * the error flag.
 */
#define EC_SLAVE_STATE_MASK 0x0F

/** State of an EtherCAT slave.
 */
typedef enum {
    EC_SLAVE_STATE_UNKNOWN = 0x00,
    /**< unknown state */
    EC_SLAVE_STATE_INIT = 0x01,
    /**< INIT state (no mailbox communication, no IO) */
    EC_SLAVE_STATE_PREOP = 0x02,
    /**< PREOP state (mailbox communication, no IO) */
    EC_SLAVE_STATE_BOOT = 0x03,
    /**< Bootstrap state (mailbox communication, firmware update) */
    EC_SLAVE_STATE_SAFEOP = 0x04,
    /**< SAFEOP (mailbox communication and input update) */
    EC_SLAVE_STATE_OP = 0x08,
    /**< OP (mailbox communication and input/output update) */
    EC_SLAVE_STATE_ACK_ERR = 0x10
    /**< Acknowledge/Error bit (no actual state) */
} ec_slave_state_t;

/** Supported mailbox protocols.
 */
enum {
    EC_MBOX_AOE = 0x01, /**< ADS over EtherCAT */
    EC_MBOX_EOE = 0x02, /**< Ethernet over EtherCAT */
    EC_MBOX_COE = 0x04, /**< CANopen over EtherCAT */
    EC_MBOX_FOE = 0x08, /**< File-Access over EtherCAT */
    EC_MBOX_SOE = 0x10, /**< Servo-Profile over EtherCAT */
    EC_MBOX_VOE = 0x20  /**< Vendor specific */
};

/** Slave information interface CANopen over EtherCAT details flags.
 */
typedef struct {
    uint8_t enable_sdo : 1; /**< Enable SDO access. */
    uint8_t enable_sdo_info : 1; /**< SDO information service available. */
    uint8_t enable_pdo_assign : 1; /**< PDO mapping configurable. */
    uint8_t enable_pdo_configuration : 1; /**< PDO configuration possible. */
    uint8_t enable_upload_at_startup : 1; /**< ?. */
    uint8_t enable_sdo_complete_access : 1; /**< Complete access possible. */
} ec_sii_coe_details_t;

/** Slave information interface general flags.
 */
typedef struct {
    uint8_t enable_safeop : 1; /**< ?. */
    uint8_t enable_not_lrw : 1; /**< Slave does not support LRW. */
} ec_sii_general_flags_t;

/** EtherCAT slave distributed clocks range.
 */
typedef enum {
    EC_DC_32, /**< 32 bit. */
    EC_DC_64 /*< 64 bit for system time, system time offset and
               port 0 receive time. */
} ec_slave_dc_range_t;

/** EtherCAT slave sync signal configuration.
 */
typedef struct {
    uint32_t cycle_time; /**< Cycle time [ns]. */
    int32_t shift_time; /**< Shift time [ns]. */
} ec_sync_signal_t;

/** Access states for SDO entries.
 *
 * The access rights are managed per AL state.
 */
enum {
    EC_SDO_ENTRY_ACCESS_PREOP, /**< Access rights in PREOP. */
    EC_SDO_ENTRY_ACCESS_SAFEOP, /**< Access rights in SAFEOP. */
    EC_SDO_ENTRY_ACCESS_OP, /**< Access rights in OP. */
    EC_SDO_ENTRY_ACCESS_COUNT /**< Number of states. */
};

/** Master devices.
 */
typedef enum {
    EC_DEVICE_MAIN, /**< Main device. */
    EC_DEVICE_BACKUP /**< Backup device */
} ec_device_index_t;

extern const char *ec_device_names[2]; // only main and backup!

/*****************************************************************************/

/** Convenience macro for printing EtherCAT-specific information to syslog.
 *
 * This will print the message in \a fmt with a prefixed "EtherCAT: ".
 *
 * \param fmt format string (like in printf())
 * \param args arguments (optional)
 */
#define EC_INFO(fmt, args...) \
    printk(KERN_INFO "EtherCAT: " fmt, ##args)

/** Convenience macro for printing EtherCAT-specific errors to syslog.
 *
 * This will print the message in \a fmt with a prefixed "EtherCAT ERROR: ".
 *
 * \param fmt format string (like in printf())
 * \param args arguments (optional)
 */
#define EC_ERR(fmt, args...) \
    printk(KERN_ERR "EtherCAT ERROR: " fmt, ##args)

/** Convenience macro for printing EtherCAT-specific warnings to syslog.
 *
 * This will print the message in \a fmt with a prefixed "EtherCAT WARNING: ".
 *
 * \param fmt format string (like in printf())
 * \param args arguments (optional)
 */
#define EC_WARN(fmt, args...) \
    printk(KERN_WARNING "EtherCAT WARNING: " fmt, ##args)

/** Convenience macro for printing EtherCAT debug messages to syslog.
 *
 * This will print the message in \a fmt with a prefixed "EtherCAT DEBUG: ".
 *
 * \param fmt format string (like in printf())
 * \param args arguments (optional)
 */
#define EC_DBG(fmt, args...) \
    printk(KERN_DEBUG "EtherCAT DEBUG: " fmt, ##args)

/*****************************************************************************/

/** Absolute value.
 */
#define EC_ABS(X) ((X) >= 0 ? (X) : -(X))

/*****************************************************************************/

extern char *ec_master_version_str;

/*****************************************************************************/

unsigned int ec_master_count(void);
void ec_print_data(const uint8_t *, size_t);
void ec_print_data_diff(const uint8_t *, const uint8_t *, size_t);
size_t ec_state_string(uint8_t, char *, uint8_t);
ssize_t ec_mac_print(const uint8_t *, char *);
int ec_mac_is_zero(const uint8_t *);

ec_master_t *ecrt_request_master_err(unsigned int);

/*****************************************************************************/

/** Code/Message pair.
 *
 * Some EtherCAT datagrams support reading a status code to display a certain
 * message. This type allows to map a code to a message string.
 */
typedef struct {
    uint32_t code; /**< Code. */
    const char *message; /**< Message belonging to \a code. */
} ec_code_msg_t;

/*****************************************************************************/

/** Generic request state.
 *
 * \attention If ever changing this, please be sure to adjust the \a
 * state_table in master/sdo_request.c.
 */
typedef enum {
    EC_INT_REQUEST_INIT,
    EC_INT_REQUEST_QUEUED,
    EC_INT_REQUEST_BUSY,
    EC_INT_REQUEST_SUCCESS,
    EC_INT_REQUEST_FAILURE
} ec_internal_request_state_t;

/*****************************************************************************/

extern const ec_request_state_t ec_request_state_translation_table[];

/*****************************************************************************/

/** Origin type.
 */
typedef enum {
    EC_ORIG_INTERNAL, /**< Internal. */
    EC_ORIG_EXTERNAL /**< External. */
} ec_origin_t;

/*****************************************************************************/

typedef struct ec_slave ec_slave_t; /**< \see ec_slave. */

/*****************************************************************************/

#endif


<|start_filename|>kernel/modules/virtual_serial/vser.c<|end_filename|>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>

#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/kfifo.h>

#include <linux/ioctl.h>
#include <linux/uaccess.h>

#include <linux/wait.h>
#include <linux/sched.h>
#include <linux/poll.h>

#include <linux/interrupt.h>
#include <linux/random.h>
#include <linux/delay.h>
#include <linux/ktime.h>
#include <linux/hrtimer.h>

#include "vser.h"

#define VSER_MAJOR 256
#define VSER_MINOR 0
#define VSER_DEV_CNT 1
#define VSER_DEV_NAME "vser"
#define VSRE_FIFO_SIZE 32

struct vser_dev
{
    struct cdev cdev;
    unsigned int baud;
    struct option opt;
    wait_queue_head_t rwqh;     /* 读 等待队列头 */
    struct fasync_struct *fapp; /* fasync_struct链表头 */
    struct hrtimer timer;       /* 高分辨率定时器对象 */
    atomic_t available;         /* 当前串口是否可用 */
    struct kfifo fifo;
};

static struct vser_dev *vsdev;
static int vser_fasync(int fd, struct file *filp, int on);

static int vser_open(struct inode *inode, struct file *filp)
{
    if (atomic_dec_and_test(&vsdev->available))
    {
        /* 首次被打开 */
        return 0;
    }
    else
    {
        /* 竞争失败的进程应该要将available的值加回来，否则以后串口将永远无法打开 */
        atomic_inc(&vsdev->available);
        return -EBUSY;
    }
}

static int vser_release(struct inode *inode, struct file *filp)
{
    /* 将节点从链表删除，这样进程不会再收到信号 */
    vser_fasync(-1, filp, 0);
    /* 使用完串口之后要把available加回来，使串口又可用 */
    atomic_inc(&vsdev->available);
    return 0;
}

static ssize_t vser_read(struct file *filp, char __user *buf, size_t count, loff_t *pos)
{
    int len;
    int ret;
    char rbuf[VSRE_FIFO_SIZE];
    /* 修正读取数据的大小 */
    len = count > sizeof(rbuf) ? sizeof(rbuf) : count;
    /* 使用等待队列中自带的自旋锁进行加锁操作，保护共享资源fifo */
    /* 在持有锁期间，不能调度调度器 */
    spin_lock(&vsdev->rwqh.lock);
    /* 判断fifo是否为空 */
    if (kfifo_is_empty(&vsdev->fifo))
    {
        /* 如果是以非阻塞的方式打开 */
        if (filp->f_flags & O_NONBLOCK)
        {
            spin_unlock(&vsdev->rwqh.lock);
            return -EAGAIN;
        }
        /* 如果是阻塞方式打开 */
        /* 进程睡眠，直到fifo不为空或者进程被信号唤醒 */
        /* wait_event_interruptible_locked会在进程休眠前自动释放自旋锁，醒来后又将重新获得自旋锁 */
        if (wait_event_interruptible_locked(vsdev->rwqh, !kfifo_is_empty(&vsdev->fifo)))
        {
            spin_unlock(&vsdev->rwqh.lock);
            /* 被信号唤醒 */
            return -ERESTARTSYS;
        }
    }
    /* 将内核FIFO中的数据取出，复制到临时缓冲区 */
    len = kfifo_out(&vsdev->fifo, rbuf, len);
    /* 释放自旋锁 */
    spin_unlock(&vsdev->rwqh.lock);

    ret = copy_to_user(buf, rbuf, len);

    return len - ret;
}

static ssize_t vser_write(struct file *filp, const char __user *buf, size_t count, loff_t *pos)
{
    int ret;
    int len;
    char *tbuf[VSRE_FIFO_SIZE];
    len = count > sizeof(tbuf) ? sizeof(tbuf) : count;
    ret = copy_from_user(tbuf, buf, len);
    return len - ret;
}

static long vser_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
    if (_IOC_TYPE(cmd) != VS_MAGIC)
    {
        return -ENOTTY; /* 参数不对 */
    }
    switch (cmd)
    {
    case VS_SET_BAUD: /* 设置波特率 */
        vsdev->baud = *(unsigned int *)arg;
        break;
    case VS_GET_BAUD:
        *(unsigned int *)arg = vsdev->baud;
        break;
    case VS_SET_FMT: /* 设置帧格式 */
        /* 返回未复制成功的字节数，该函数可能会使进程睡眠 */
        if (copy_from_user(&vsdev->opt, (struct option __user *)arg, sizeof(struct option)))
        {
            return -EFAULT;
        }
        break;
    case VS_GET_FMT:
        /* 返回未复制成功的字节数，该函数可能会使进程睡眠 */
        if (copy_to_user((struct option __user *)arg, &vsdev->opt, sizeof(struct option)))
        {
            return -EFAULT;
        }
        break;
    default:
        return -ENOTTY;
    }
    return 0;
}

static unsigned int vser_poll(struct file *filp, struct poll_table_struct *p)
{
    unsigned int mask = 0;

    /* 将系统调用中构造的等待队列节点加入到相应的等待队列中 */
    poll_wait(filp, &vsdev->rwqh, p);

    spin_lock(&vsdev->rwqh.lock);
    /* 根据资源的情况返回设置mask的值并返回 */
    if (!kfifo_is_empty(&vsdev->fifo))
    {
        mask |= POLLIN | POLLRDNORM;
    }
    spin_unlock(&vsdev->rwqh.lock);
    return mask;
}

static int vser_fasync(int fd, struct file *filp, int on)
{
    /* 调用fasync_helper来构造struct fasync_struct节点，并加入到链表 */
    return fasync_helper(fd, filp, on, &vsdev->fapp);
}

static enum hrtimer_restart vser_timer(struct hrtimer *timer)
{
    unsigned char data;

    get_random_bytes(&data, sizeof(data));
    data %= 26;
    data += 'A';
    spin_lock(&vsdev->rwqh.lock);
    if (!kfifo_is_full(&vsdev->fifo))
    {
        if (!kfifo_in(&vsdev->fifo, &data, sizeof(data)))
        {
            printk(KERN_ERR "vser: kfifo_in failure\n");
        }
    }
    if (!kfifo_is_empty(&vsdev->fifo))
    {
        spin_unlock(&vsdev->rwqh.lock);
        wake_up_interruptible(&vsdev->rwqh);
        kill_fasync(&vsdev->fapp, SIGIO, POLL_IN);
    }
    else
    {
        spin_unlock(&vsdev->rwqh.lock);
    }

    /* 重新设置定时值 */
    hrtimer_forward_now(timer, ktime_set(1, 1000));
    /* HRTIMER_RESTART表示要重新启动定时器 */
    return HRTIMER_RESTART;
}

static struct file_operations vser_ops = {
    .owner = THIS_MODULE,
    .open = vser_open,
    .release = vser_release,
    .read = vser_read,
    .write = vser_write,
    .unlocked_ioctl = vser_ioctl,
    .poll = vser_poll,
    .fasync = vser_fasync,
};

/* 模块初始化函数 */
static int __init vser_init(void)
{
    int ret;
    dev_t dev;

    dev = MKDEV(VSER_MAJOR, VSER_MINOR);
    /* 向内核注册设备号，静态方式 */
    ret = register_chrdev_region(dev, VSER_DEV_CNT, VSER_DEV_NAME);
    if (ret)
    {
        goto reg_err;
    }

    vsdev = kzalloc(sizeof(struct vser_dev), GFP_KERNEL);
    if (!vsdev)
    {
        ret = -ENOMEM;
        goto mem_err;
    }
    ret = kfifo_alloc(&vsdev->fifo, VSRE_FIFO_SIZE, GFP_KERNEL);
    if (ret)
    {
        goto fifo_err;
    }

    /* 初始化cdev对象，绑定ops */
    cdev_init(&vsdev->cdev, &vser_ops);
    vsdev->cdev.owner = THIS_MODULE;
    vsdev->baud = 115200;
    vsdev->opt.datab = 8;
    vsdev->opt.stopb = 1;
    vsdev->opt.parity = 0;
    /* 初始化等待队列头 */
    init_waitqueue_head(&vsdev->rwqh);
    /* 添加到内核中的cdev_map散列表中 */
    ret = cdev_add(&vsdev->cdev, dev, VSER_DEV_CNT);
    if (ret)
    {
        goto add_err;
    }
    /* 初始化定时器 */
    /* CLOCK_MONOTONIC时钟类型表示自系统开机以来的单调递增时间,HRTIMER_MODE_REL表示相对时间模式 */
    hrtimer_init(&vsdev->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
    vsdev->timer.function = vser_timer;
    /* 启动定时器 */
    hrtimer_start(&vsdev->timer, ktime_set(1, 1000), HRTIMER_MODE_REL);
    /* 将原子变量赋值为1 */
    atomic_set(&vsdev->available, 1);
    return 0;

add_err:
    kfifo_free(&vsdev->fifo);
fifo_err:
    kfree(vsdev);
mem_err:
    unregister_chrdev_region(dev, VSER_DEV_CNT);
reg_err:
    return ret;
}

/* 模块清理函数 */
static void __exit vser_exit(void)
{
    dev_t dev;

    /* 关闭定时器 */
    hrtimer_cancel(&vsdev->timer);
    dev = MKDEV(VSER_MAJOR, VSER_MINOR);
    cdev_del(&vsdev->cdev);
    unregister_chrdev_region(dev, VSER_DEV_CNT);
    kfifo_free(&vsdev->fifo);
    kfree(vsdev);
}

/* 为模块初始化函数和清理函数取别名 */
module_init(vser_init);
module_exit(vser_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("suda-morris <<EMAIL>>");
MODULE_DESCRIPTION("A simple module");
MODULE_ALIAS("virtual-serial");

<|start_filename|>3rdpart/tslib-1.15/src/ts_parse_vars.c<|end_filename|>
/*
 *  tslib/src/ts_parse_vars.c
 *
 *  Copyright (C) 2001 <NAME>.
 *
 * This file is placed under the LGPL.  Please see the file
 * COPYING for more details.
 *
 * SPDX-License-Identifier: LGPL-2.1
 *
 *
 * Parse modules' parameters and call their own parsing functions
 */
#include "config.h"

#ifdef HAVE_ALLOCA_H
#include <alloca.h>
#endif
#include <string.h>

#include "tslib-private.h"

#if !defined HAVE_STRSEP
#include "ts_strsep.h"
#endif

#define BUF_SIZE 1024

static char s_holder[BUF_SIZE];

int tslib_parse_vars(struct tslib_module_info *mod,
		     const struct tslib_vars *vars, int nr,
		     const char *str)
{
	char *s, *p;
	int ret = 0;

	if (!str)
		return 0;

	strncpy(s_holder, str, BUF_SIZE - 1);
	s_holder[BUF_SIZE - 1] = '\0';

	s = s_holder;
#if !defined HAVE_STRSEP
	while ((p = ts_strsep(&s, " \t")) != NULL && ret == 0) {
#else
	while ((p = strsep(&s, " \t")) != NULL && ret == 0) {
#endif
		const struct tslib_vars *v;
		char *eq;

		eq = strchr(p, '=');
		if (eq)
			*eq++ = '\0';

		for (v = vars; v < vars + nr; v++)
			if (strcasecmp(v->name, p) == 0) {
				ret = v->fn(mod, eq, v->data);
				break;
			}
	}

	return ret;
}


<|start_filename|>3rdpart/tslib-1.15/plugins/waveshare-raw.c<|end_filename|>
/*
 * tslib driver for WaveShare touchscreens
 * Copyright (C) 2015 <NAME>
 * inspiration from derekhe:
 * https://github.com/derekhe/wavesahre-7inch-touchscreen-driver
 *
 * This file is placed under the LGPL.  Please see the file COPYING for more
 * details.
 *
 * SPDX-License-Identifier: LGPL-2.1
 *
 *
 * Usage:
 *   module_raw waveshare vid_pid=<vendorID>:<productID> len=<raw_data_len>
 */

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <linux/hidraw.h>
#include <stdint.h>

#include "config.h"
#include "tslib-private.h"

struct tslib_input {
	struct tslib_module_info module;
	int vendor;
	int product;
	int len;
};

static int waveshare_read(struct tslib_module_info *inf, struct ts_sample *samp,
			  int nr)
{
	static short reopen = 1;
	struct stat devstat;
	struct hidraw_devinfo info;
	char name_buf[512];
	int cnt;
	short found = 0;
	struct tslib_input *i = (struct tslib_input *) inf;
	struct tsdev *ts = inf->dev;
	struct tsdev *ts_tmp;
	char *buf;
	int ret;

	if (reopen == 1) {
		reopen = 0;

		if (i->vendor > 0 && i->product > 0) {
#ifdef DEBUG
			fprintf(stderr,
				"waveshare: searching for device using hidraw...\n");
#endif
			for (cnt = 0; cnt < HIDRAW_MAX_DEVICES; cnt++) {
				snprintf(name_buf, sizeof(name_buf),
					 "/dev/hidraw%d", cnt);
#ifdef DEBUG
				fprintf(stderr,
					"waveshare: device: %s\n", name_buf);
#endif
				ret = stat(name_buf, &devstat);
				if (ret < 0)
					continue;

				ts_tmp = ts_open(name_buf, 0);
				if (!ts_tmp)
					continue;

#ifdef DEBUG
				fprintf(stderr, "  opened\n");
#endif
				ret = ioctl(ts_tmp->fd, HIDIOCGRAWINFO, &info);
				if (ret < 0) {
					ts_close(ts_tmp);
					continue;
				}

				info.vendor &= 0xFFFF;
				info.product &= 0xFFFF;
#ifdef DEBUG
				fprintf(stderr,
					"  vid=%04X, pid=%04X\n",
					info.vendor, info.product);
#endif

				if (i->vendor == info.vendor &&
				    i->product == info.product) {
					close(ts->fd);

					ts->fd = ts_tmp->fd;
					found = 1;
#ifdef DEBUG
					fprintf(stderr, "  correct device\n");
#endif
					ts_close(ts_tmp);
					break;
				}

				ts_close(ts_tmp);
			} /* for HIDRAW_MAX_DEVICES */

			if (found == 0)
				return -1;
		} /* vid/pid set */
	} /* reopen */

	buf = alloca(i->len * nr);

	ret = read(ts->fd, buf, i->len * nr);
	if (ret > 0) {
		while (ret >= (int) i->len) {
	/*
	  0000271: aa01 00e4 0139 bb01 01e0 0320 01e0 0320 01e0 0320 01e0 0320 cc  .....9..... ... ... ... .

	  "aa" is start of the command,
	  "01" means clicked, while
	  "00" means unclicked.
	  "00e4" and "0139" is the X,Y position (HEX).
	  "bb" is start of multi-touch,
	  and the following bytes are the position of each point.
	 */
			samp->pressure = buf[1] & 0xff;
			samp->x = ((buf[2] & 0xff) << 8) | (buf[3] & 0xff);
			samp->y = ((buf[4] & 0xff) << 8) | (buf[5] & 0xff);
			gettimeofday(&samp->tv, NULL);
		#ifdef DEBUG
			fprintf(stderr, "waveshare raw: %d %d %d\n",
				samp->x, samp->y, samp->pressure);
			fprintf(stderr, "%x %x %x %x %x %x\n",
				buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
		#endif
			samp++;
			buf += i->len;
			ret -= i->len;
		}
	} else {
		return -1;
	}

	return nr;
}

static const struct tslib_ops waveshare_ops = {
	.read = waveshare_read,
};

static int parse_vid_pid(struct tslib_module_info *inf, char *str, void *data)
{
	struct tslib_input *i = (struct tslib_input *)inf;

	if (strlen(str) < 9 || (int)(intptr_t) data != 1)
		return 0;   /* -1 */

	str[4] = str[9] = '\0';
	i->vendor = strtol(&str[0], NULL, 16);
	i->product = strtol(&str[5], NULL, 16);
#ifdef DEBUG
	fprintf(stderr, "waveshare vid:pid - %04X:%04X\n",
		i->vendor, i->product);
#endif /*DEBUG*/
	return 0;
}

static int parse_len(struct tslib_module_info *inf, char *str, void *data)
{
	struct tslib_input *i = (struct tslib_input *)inf;
	int v;
	int err = errno;

	v = atoi(str);

	if (v < 0)
		return -1;

	errno = err;
	switch ((int)(intptr_t) data) {
	case 1:
		i->len = v;
#ifdef DEBUG
		fprintf(stderr, "waveshare raw data len: %d bytes\n", i->len);
#endif
		break;
	default:
		return -1;
	}
	return 0;
}

static const struct tslib_vars raw_vars[] = {
	{ "vid_pid", (void *) 1, parse_vid_pid },
	{ "len", (void *) 1, parse_len },
};

#define NR_VARS (sizeof(raw_vars) / sizeof(raw_vars[0]))

TSAPI struct tslib_module_info *waveshare_mod_init(struct tsdev *dev,
						   const char *params)
{
	struct tslib_input *i;

	(void) dev;

	i = malloc(sizeof(struct tslib_input));
	if (i == NULL)
		return NULL;

	i->module.ops = &waveshare_ops;
	i->vendor = 0;
	i->product = 0;
	i->len = 25;

	if (tslib_parse_vars(&i->module, raw_vars, NR_VARS, params)) {
		free(i);
		return NULL;
	}

	return &(i->module);
}

#ifndef TSLIB_STATIC_WAVESHARE_MODULE
	TSLIB_MODULE_INIT(waveshare_mod_init);
#endif


<|start_filename|>3rdpart/tslib-1.15/src/ts_close.c<|end_filename|>
/*
 *  tslib/src/ts_close.c
 *
 *  Copyright (C) 2001 <NAME>.
 *
 * This file is placed under the LGPL.  Please see the file
 * COPYING for more details.
 *
 * SPDX-License-Identifier: LGPL-2.1
 *
 *
 * Close a touchscreen device.
 */
#include "config.h"
#include <stdlib.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_LIBDL
#include <dlfcn.h>
#endif

#include "tslib-private.h"

void (*ts_close_restricted)(int fd, void *user_data) = NULL;

int ts_close(struct tsdev *ts)
{
	void *handle;
	int ret = 0;
	struct tslib_module_info *info, *next;

	info = ts->list;
	while (info) {
		/* Save the "next" pointer now because info will be freed */
		next = info->next;

		handle = info->handle;

		if (info->ops->fini)
			info->ops->fini(info);
		else
			free(info);
	#ifdef HAVE_LIBDL
		if (handle)
			dlclose(handle);
	#endif

		info = next;
	}

	if (ts_close_restricted)
		ts_close_restricted(ts->fd, NULL);
	else
		ret = close(ts->fd);

	free(ts->eventpath);

	free(ts);

	return ret;
}


<|start_filename|>kernel/modules/devmodel/vbus.c<|end_filename|>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>

#include <linux/device.h>

/* 用于匹配驱动和设备 */
static int vbus_match(struct device *dev, struct device_driver *drv)
{
	/* 一般会考察设备和驱动的ID是否匹配 */
	return 1;
}
/* 定义了一个vbus对象，代表总线 */
static struct bus_type vbus = {
	.name = "vbus",
	.match = vbus_match,
};
/* 导出vbus对象，其余模块也能访问 */
EXPORT_SYMBOL(vbus);

static int __init vbus_init(void)
{
	/* 向内核注册总线 */
	return bus_register(&vbus);
}

static void __exit vbus_exit(void)
{
	/* 总线注销 */
	bus_unregister(&vbus);
}

module_init(vbus_init);
module_exit(vbus_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("suda-morris <<EMAIL>>");
MODULE_DESCRIPTION("A virtual bus");


<|start_filename|>rootfs/buildroot-2017.11.1/package/pango/pango.mk<|end_filename|>
################################################################################
#
# pango
#
################################################################################

PANGO_VERSION_MAJOR = 1.40
PANGO_VERSION = $(PANGO_VERSION_MAJOR).12
PANGO_SOURCE = pango-$(PANGO_VERSION).tar.xz
PANGO_SITE = http://ftp.gnome.org/pub/GNOME/sources/pango/$(PANGO_VERSION_MAJOR)
PANGO_AUTORECONF = YES
PANGO_INSTALL_STAGING = YES
PANGO_LICENSE = LGPL-2.0+
PANGO_LICENSE_FILES = COPYING

PANGO_CONF_OPTS = --enable-explicit-deps=no
HOST_PANGO_CONF_OPTS = --enable-explicit-deps=no

PANGO_DEPENDENCIES = \
	$(TARGET_NLS_DEPENDENCIES) \
	host-pkgconf \
	libglib2 \
	cairo \
	harfbuzz \
	fontconfig \
	freetype
HOST_PANGO_DEPENDENCIES = \
	host-pkgconf \
	host-libglib2 \
	host-cairo \
	host-harfbuzz \
	host-fontconfig \
	host-freetype

ifeq ($(BR2_PACKAGE_XORG7),y)
PANGO_CONF_OPTS += \
	--x-includes=$(STAGING_DIR)/usr/include/X11 \
	--x-libraries=$(STAGING_DIR)/usr/lib
PANGO_DEPENDENCIES += xlib_libX11
endif

ifeq ($(BR2_PACKAGE_XLIB_LIBXFT)$(BR2_PACKAGE_XLIB_LIBXRENDER),yy)
PANGO_DEPENDENCIES += xlib_libXft xlib_libXrender
PANGO_CONF_OPTS += --with-xft
endif

$(eval $(autotools-package))
$(eval $(host-autotools-package))


<|start_filename|>rootfs/buildroot-2017.11.1/package/setools/setools.mk<|end_filename|>
################################################################################
#
# setools
#
################################################################################

SETOOLS_VERSION = 4.1.1
SETOOLS_SITE = $(call github,TresysTechnology,setools,$(SETOOLS_VERSION))
SETOOLS_DEPENDENCIES = libselinux libsepol python-setuptools host-bison host-flex host-swig
SETOOLS_INSTALL_STAGING = YES
SETOOLS_LICENSE = GPL-2.0+, LGPL-2.1+
SETOOLS_LICENSE_FILES = COPYING COPYING.GPL COPYING.LGPL
SETOOLS_SETUP_TYPE = setuptools
HOST_SETOOLS_DEPENDENCIES = host-libselinux host-libsepol


ifeq ($(BR2_PACKAGE_PYTHON3),y)
SETOOLS_PYLIBVER = python$(PYTHON3_VERSION_MAJOR)
else
SETOOLS_PYLIBVER = python$(PYTHON_VERSION_MAJOR)
SETOOLS_DEPENDENCIES += python-enum34
endif

define SETOOLS_FIX_SETUP
	# By default, setup.py will look for libsepol.a in the host machines
	# /usr/lib directory. This needs to be changed to the staging directory.
	$(SED) "s@base_lib_dirs =.*@base_lib_dirs = ['$(STAGING_DIR)/usr/lib']@g" \
		$(@D)/setup.py
endef
SETOOLS_POST_PATCH_HOOKS += SETOOLS_FIX_SETUP

define HOST_SETOOLS_FIX_SETUP
	# By default, setup.py will look for libsepol.a in the host machines
	# /usr/lib directory. This needs to be changed to the host directory.
	$(SED) "s@base_lib_dirs =.*@base_lib_dirs = ['$(HOST_DIR)/lib']@g" \
		$(@D)/setup.py
endef
HOST_SETOOLS_POST_PATCH_HOOKS += HOST_SETOOLS_FIX_SETUP

# sedta and seinfoflow depend on python-networkx. This package is not
# available in buildroot.
define SETOOLS_REMOVE_BROKEN_SCRIPTS
	$(RM) $(TARGET_DIR)/usr/bin/sedta
	$(RM) $(TARGET_DIR)/usr/bin/seinfoflow
endef
SETOOLS_POST_INSTALL_TARGET_HOOKS += SETOOLS_REMOVE_BROKEN_SCRIPTS

# apol requires pyqt5. However, the setools installation
# process will install apol even if pyqt5 is missing.
# Remove these scripts from the target it pyqt5 is not selected.
ifeq ($(BR2_PACKAGE_PYTHON_PYQT5),)
define SETOOLS_REMOVE_QT_SCRIPTS
	$(RM) $(TARGET_DIR)/usr/bin/apol
	$(RM) -r $(TARGET_DIR)/lib/$(SETOOLS_PYLIBVER)/site-packages/setoolsgui/
endef
SETOOLS_POST_INSTALL_TARGET_HOOKS += SETOOLS_REMOVE_QT_SCRIPTS
endif

# sedta and seinfoflow depend on python-networkx. This package is not
# available in buildroot. pyqt5 is not a host-package, remove apol
# from the host directory as well.
define HOST_SETOOLS_REMOVE_BROKEN_SCRIPTS
	$(RM) $(HOST_DIR)/bin/sedta
	$(RM) $(HOST_DIR)/bin/seinfoflow
	$(RM) $(HOST_DIR)/bin/apol
endef
HOST_SETOOLS_POST_INSTALL_HOOKS += HOST_SETOOLS_REMOVE_BROKEN_SCRIPTS

$(eval $(python-package))
$(eval $(host-python-package))


<|start_filename|>3rdpart/ethercat-1.5.2/master/voe_handler.c<|end_filename|>
/******************************************************************************
 *
 *  $Id: voe_handler.c,v ec403cf308eb 2013/02/12 14:46:43 fp $
 *
 *  Copyright (C) 2006-2008  <NAME>, Ingenieurgemeinschaft IgH
 *
 *  This file is part of the IgH EtherCAT Master.
 *
 *  The IgH EtherCAT Master is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License version 2, as
 *  published by the Free Software Foundation.
 *
 *  The IgH EtherCAT Master is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 *  Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with the IgH EtherCAT Master; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 *****************************************************************************/

/** \file
 * Vendor specific over EtherCAT protocol handler functions.
 */

/*****************************************************************************/

#include <linux/module.h>

#include "master.h"
#include "slave_config.h"
#include "mailbox.h"
#include "voe_handler.h"

/** VoE mailbox type.
 */
#define EC_MBOX_TYPE_VOE 0x0f

/** VoE header size.
 */
#define EC_VOE_HEADER_SIZE 6

/** VoE response timeout in [ms].
 */
#define EC_VOE_RESPONSE_TIMEOUT 500

/*****************************************************************************/

void ec_voe_handler_state_write_start(ec_voe_handler_t *);
void ec_voe_handler_state_write_response(ec_voe_handler_t *);

void ec_voe_handler_state_read_start(ec_voe_handler_t *);
void ec_voe_handler_state_read_check(ec_voe_handler_t *);
void ec_voe_handler_state_read_response(ec_voe_handler_t *);

void ec_voe_handler_state_read_nosync_start(ec_voe_handler_t *);
void ec_voe_handler_state_read_nosync_response(ec_voe_handler_t *);

void ec_voe_handler_state_end(ec_voe_handler_t *);
void ec_voe_handler_state_error(ec_voe_handler_t *);

/*****************************************************************************/

/** VoE handler constructor.
 *
 * \return Return value of ec_datagram_prealloc().
 */
int ec_voe_handler_init(
        ec_voe_handler_t *voe, /**< VoE handler. */
        ec_slave_config_t *sc, /**< Parent slave configuration. */
        size_t size /**< Size of memory to reserve. */
        )
{
    voe->config = sc;
    voe->vendor_id = 0x00000000;
    voe->vendor_type = 0x0000;
    voe->data_size = 0;
    voe->dir = EC_DIR_INVALID;
    voe->state = ec_voe_handler_state_error;
    voe->request_state = EC_INT_REQUEST_INIT;

    ec_datagram_init(&voe->datagram);
    return ec_datagram_prealloc(&voe->datagram,
            size + EC_MBOX_HEADER_SIZE + EC_VOE_HEADER_SIZE);
}

/*****************************************************************************/

/** VoE handler destructor.
 */
void ec_voe_handler_clear(
        ec_voe_handler_t *voe /**< VoE handler. */
        )
{
    ec_datagram_clear(&voe->datagram);
}

/*****************************************************************************/

/** Get usable memory size.
 *
 * \return Memory size.
 */
size_t ec_voe_handler_mem_size(
        const ec_voe_handler_t *voe /**< VoE handler. */
        )
{
    if (voe->datagram.mem_size >= EC_MBOX_HEADER_SIZE + EC_VOE_HEADER_SIZE)
        return voe->datagram.mem_size -
            (EC_MBOX_HEADER_SIZE + EC_VOE_HEADER_SIZE);
    else
        return 0;
}

/*****************************************************************************
 * Application interface.
 ****************************************************************************/

void ecrt_voe_handler_send_header(ec_voe_handler_t *voe, uint32_t vendor_id,
        uint16_t vendor_type)
{
    voe->vendor_id = vendor_id;
    voe->vendor_type = vendor_type;
}

/*****************************************************************************/

void ecrt_voe_handler_received_header(const ec_voe_handler_t *voe,
        uint32_t *vendor_id, uint16_t *vendor_type)
{
    uint8_t *header = voe->datagram.data + EC_MBOX_HEADER_SIZE;

    if (vendor_id)
        *vendor_id = EC_READ_U32(header);
    if (vendor_type)
        *vendor_type = EC_READ_U16(header + 4);
}

/*****************************************************************************/

uint8_t *ecrt_voe_handler_data(ec_voe_handler_t *voe)
{
    return voe->datagram.data + EC_MBOX_HEADER_SIZE + EC_VOE_HEADER_SIZE;
}

/*****************************************************************************/

size_t ecrt_voe_handler_data_size(const ec_voe_handler_t *voe)
{
    return voe->data_size;
}

/*****************************************************************************/

void ecrt_voe_handler_read(ec_voe_handler_t *voe)
{
    voe->dir = EC_DIR_INPUT;
    voe->state = ec_voe_handler_state_read_start;
    voe->request_state = EC_INT_REQUEST_BUSY;
}

/*****************************************************************************/

void ecrt_voe_handler_read_nosync(ec_voe_handler_t *voe)
{
    voe->dir = EC_DIR_INPUT;
    voe->state = ec_voe_handler_state_read_nosync_start;
    voe->request_state = EC_INT_REQUEST_BUSY;
}

/*****************************************************************************/

void ecrt_voe_handler_write(ec_voe_handler_t *voe, size_t size)
{
    voe->dir = EC_DIR_OUTPUT;
    voe->data_size = size;
    voe->state = ec_voe_handler_state_write_start;
    voe->request_state = EC_INT_REQUEST_BUSY;
}

/*****************************************************************************/

ec_request_state_t ecrt_voe_handler_execute(ec_voe_handler_t *voe)
{
    if (voe->config->slave) { // FIXME locking?
        voe->state(voe);
        if (voe->request_state == EC_INT_REQUEST_BUSY) {
            ec_master_queue_datagram(voe->config->master, &voe->datagram);
        }
    } else {
        voe->state = ec_voe_handler_state_error;
        voe->request_state = EC_INT_REQUEST_FAILURE;
    }

    return ec_request_state_translation_table[voe->request_state];
}

/******************************************************************************
 * State functions.
 *****************************************************************************/

/** Start writing VoE data.
 */
void ec_voe_handler_state_write_start(ec_voe_handler_t *voe)
{
    ec_slave_t *slave = voe->config->slave;
    uint8_t *data;

    if (slave->master->debug_level) {
        EC_SLAVE_DBG(slave, 0, "Writing %zu bytes of VoE data.\n",
               voe->data_size);
        ec_print_data(ecrt_voe_handler_data(voe), voe->data_size);
    }

    if (!(slave->sii.mailbox_protocols & EC_MBOX_VOE)) {
        EC_SLAVE_ERR(slave, "Slave does not support VoE!\n");
        voe->state = ec_voe_handler_state_error;
        voe->request_state = EC_INT_REQUEST_FAILURE;
        return;
    }

    data = ec_slave_mbox_prepare_send(slave, &voe->datagram,
            EC_MBOX_TYPE_VOE, EC_VOE_HEADER_SIZE + voe->data_size);
    if (IS_ERR(data)) {
        voe->state = ec_voe_handler_state_error;
        voe->request_state = EC_INT_REQUEST_FAILURE;
        return;
    }

    EC_WRITE_U32(data,     voe->vendor_id);
    EC_WRITE_U16(data + 4, voe->vendor_type);
    /* data already in datagram */

    voe->retries = EC_FSM_RETRIES;
    voe->jiffies_start = jiffies;
    voe->state = ec_voe_handler_state_write_response;
}

/*****************************************************************************/

/** Wait for the mailbox response.
 */
void ec_voe_handler_state_write_response(ec_voe_handler_t *voe)
{
    ec_datagram_t *datagram = &voe->datagram;
    ec_slave_t *slave = voe->config->slave;

    if (datagram->state == EC_DATAGRAM_TIMED_OUT && voe->retries--)
        return;

    if (datagram->state != EC_DATAGRAM_RECEIVED) {
        voe->state = ec_voe_handler_state_error;
        voe->request_state = EC_INT_REQUEST_FAILURE;
        EC_SLAVE_ERR(slave, "Failed to receive VoE write request datagram: ");
        ec_datagram_print_state(datagram);
        return;
    }

    if (datagram->working_counter != 1) {
        if (!datagram->working_counter) {
            unsigned long diff_ms =
                (jiffies - voe->jiffies_start) * 1000 / HZ;
            if (diff_ms < EC_VOE_RESPONSE_TIMEOUT) {
                EC_SLAVE_DBG(slave, 1, "Slave did not respond to"
                        " VoE write request. Retrying after %lu ms...\n",
                        diff_ms);
                // no response; send request datagram again
                return;
            }
        }
        voe->state = ec_voe_handler_state_error;
        voe->request_state = EC_INT_REQUEST_FAILURE;
        EC_SLAVE_ERR(slave, "Reception of VoE write request failed: ");
        ec_datagram_print_wc_error(datagram);
        return;
    }

    EC_CONFIG_DBG(voe->config, 1, "VoE write request successful.\n");

    voe->request_state = EC_INT_REQUEST_SUCCESS;
    voe->state = ec_voe_handler_state_end;
}

/*****************************************************************************/

/** Start reading VoE data.
 */
void ec_voe_handler_state_read_start(ec_voe_handler_t *voe)
{
    ec_datagram_t *datagram = &voe->datagram;
    ec_slave_t *slave = voe->config->slave;

    EC_SLAVE_DBG(slave, 1, "Reading VoE data.\n");

    if (!(slave->sii.mailbox_protocols & EC_MBOX_VOE)) {
        EC_SLAVE_ERR(slave, "Slave does not support VoE!\n");
        voe->state = ec_voe_handler_state_error;
        voe->request_state = EC_INT_REQUEST_FAILURE;
        return;
    }

    ec_slave_mbox_prepare_check(slave, datagram); // can not fail.

    voe->jiffies_start = jiffies;
    voe->retries = EC_FSM_RETRIES;
    voe->state = ec_voe_handler_state_read_check;
}

/*****************************************************************************/

/** Check for new data in the mailbox.
 */
void ec_voe_handler_state_read_check(ec_voe_handler_t *voe)
{
    ec_datagram_t *datagram = &voe->datagram;
    ec_slave_t *slave = voe->config->slave;

    if (datagram->state == EC_DATAGRAM_TIMED_OUT && voe->retries--)
        return;

    if (datagram->state != EC_DATAGRAM_RECEIVED) {
        voe->state = ec_voe_handler_state_error;
        voe->request_state = EC_INT_REQUEST_FAILURE;
        EC_SLAVE_ERR(slave, "Failed to receive VoE mailbox check datagram: ");
        ec_datagram_print_state(datagram);
        return;
    }

    if (datagram->working_counter != 1) {
        voe->state = ec_voe_handler_state_error;
        voe->request_state = EC_INT_REQUEST_FAILURE;
        EC_SLAVE_ERR(slave, "Reception of VoE mailbox check"
                " datagram failed: ");
        ec_datagram_print_wc_error(datagram);
        return;
    }

    if (!ec_slave_mbox_check(datagram)) {
        unsigned long diff_ms =
            (datagram->jiffies_received - voe->jiffies_start) * 1000 / HZ;
        if (diff_ms >= EC_VOE_RESPONSE_TIMEOUT) {
            voe->state = ec_voe_handler_state_error;
            voe->request_state = EC_INT_REQUEST_FAILURE;
            EC_SLAVE_ERR(slave, "Timeout while waiting for VoE data.\n");
            return;
        }

        ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
        voe->retries = EC_FSM_RETRIES;
        return;
    }

    // Fetch response
    ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
    voe->retries = EC_FSM_RETRIES;
    voe->state = ec_voe_handler_state_read_response;
}

/*****************************************************************************/

/** Read the pending mailbox data.
 */
void ec_voe_handler_state_read_response(ec_voe_handler_t *voe)
{
    ec_datagram_t *datagram = &voe->datagram;
    ec_slave_t *slave = voe->config->slave;
    ec_master_t *master = voe->config->master;
    uint8_t *data, mbox_prot;
    size_t rec_size;

    if (datagram->state == EC_DATAGRAM_TIMED_OUT && voe->retries--)
        return;

    if (datagram->state != EC_DATAGRAM_RECEIVED) {
        voe->state = ec_voe_handler_state_error;
        voe->request_state = EC_INT_REQUEST_FAILURE;
        EC_SLAVE_ERR(slave, "Failed to receive VoE read datagram: ");
        ec_datagram_print_state(datagram);
        return;
    }

    if (datagram->working_counter != 1) {
        voe->state = ec_voe_handler_state_error;
        voe->request_state = EC_INT_REQUEST_FAILURE;
        EC_SLAVE_ERR(slave, "Reception of VoE read response failed: ");
        ec_datagram_print_wc_error(datagram);
        return;
    }

    data = ec_slave_mbox_fetch(slave, datagram, &mbox_prot, &rec_size);
    if (IS_ERR(data)) {
        voe->state = ec_voe_handler_state_error;
        voe->request_state = EC_INT_REQUEST_FAILURE;
        return;
    }

    if (mbox_prot != EC_MBOX_TYPE_VOE) {
        voe->state = ec_voe_handler_state_error;
        voe->request_state = EC_INT_REQUEST_FAILURE;
        EC_SLAVE_WARN(slave, "Received mailbox protocol 0x%02X"
                " as response.\n", mbox_prot);
        ec_print_data(data, rec_size);
        return;
    }

    if (rec_size < EC_VOE_HEADER_SIZE) {
        voe->state = ec_voe_handler_state_error;
        voe->request_state = EC_INT_REQUEST_FAILURE;
        EC_SLAVE_ERR(slave, "Received VoE header is"
                " incomplete (%zu bytes)!\n", rec_size);
        return;
    }

    if (master->debug_level) {
        EC_CONFIG_DBG(voe->config, 0, "VoE data:\n");
        ec_print_data(data, rec_size);
    }

    voe->data_size = rec_size - EC_VOE_HEADER_SIZE;
    voe->request_state = EC_INT_REQUEST_SUCCESS;
    voe->state = ec_voe_handler_state_end; // success
}

/*****************************************************************************/

/** Start reading VoE data without sending a sync message before.
 */
void ec_voe_handler_state_read_nosync_start(ec_voe_handler_t *voe)
{
    ec_datagram_t *datagram = &voe->datagram;
    ec_slave_t *slave = voe->config->slave;

    EC_SLAVE_DBG(slave, 1, "Reading VoE data.\n");

    if (!(slave->sii.mailbox_protocols & EC_MBOX_VOE)) {
        EC_SLAVE_ERR(slave, "Slave does not support VoE!\n");
        voe->state = ec_voe_handler_state_error;
        voe->request_state = EC_INT_REQUEST_FAILURE;
        return;
    }

    ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.

    voe->jiffies_start = jiffies;
    voe->retries = EC_FSM_RETRIES;
    voe->state = ec_voe_handler_state_read_nosync_response;
}

/*****************************************************************************/

/** Read the pending mailbox data without sending a sync message before. This
 *  might lead to an empty reponse from the client.
 */
void ec_voe_handler_state_read_nosync_response(ec_voe_handler_t *voe)
{
    ec_datagram_t *datagram = &voe->datagram;
    ec_slave_t *slave = voe->config->slave;
    ec_master_t *master = voe->config->master;
    uint8_t *data, mbox_prot;
    size_t rec_size;

    if (datagram->state == EC_DATAGRAM_TIMED_OUT && voe->retries--)
        return;

    if (datagram->state != EC_DATAGRAM_RECEIVED) {
        voe->state = ec_voe_handler_state_error;
        voe->request_state = EC_INT_REQUEST_FAILURE;
        EC_SLAVE_ERR(slave, "Failed to receive VoE read datagram: ");
        ec_datagram_print_state(datagram);
        return;
    }

    if (datagram->working_counter == 0) {
        voe->state = ec_voe_handler_state_error;
        voe->request_state = EC_INT_REQUEST_FAILURE;
        EC_SLAVE_DBG(slave, 1, "Slave did not send VoE data.\n");
        return;
    }

    if (datagram->working_counter != 1) {
        voe->state = ec_voe_handler_state_error;
        voe->request_state = EC_INT_REQUEST_FAILURE;
        EC_SLAVE_WARN(slave, "Reception of VoE read response failed: ");
        ec_datagram_print_wc_error(datagram);
        return;
    }

    if (!(data = ec_slave_mbox_fetch(slave, datagram,
                    &mbox_prot, &rec_size))) {
        voe->state = ec_voe_handler_state_error;
        voe->request_state = EC_INT_REQUEST_FAILURE;
        return;
    }

    if (mbox_prot != EC_MBOX_TYPE_VOE) {
        voe->state = ec_voe_handler_state_error;
        voe->request_state = EC_INT_REQUEST_FAILURE;
        EC_SLAVE_WARN(slave, "Received mailbox protocol 0x%02X"
                " as response.\n", mbox_prot);
        ec_print_data(data, rec_size);
        return;
    }

    if (rec_size < EC_VOE_HEADER_SIZE) {
        voe->state = ec_voe_handler_state_error;
        voe->request_state = EC_INT_REQUEST_FAILURE;
        EC_SLAVE_ERR(slave, "Received VoE header is"
                " incomplete (%zu bytes)!\n", rec_size);
        return;
    }

    if (master->debug_level) {
        EC_CONFIG_DBG(voe->config, 1, "VoE data:\n");
        ec_print_data(data, rec_size);
    }

    voe->data_size = rec_size - EC_VOE_HEADER_SIZE;
    voe->request_state = EC_INT_REQUEST_SUCCESS;
    voe->state = ec_voe_handler_state_end; // success
}

/*****************************************************************************/

/** Successful termination state function.
 */
void ec_voe_handler_state_end(ec_voe_handler_t *voe)
{
}

/*****************************************************************************/

/** Failure termination state function.
 */
void ec_voe_handler_state_error(ec_voe_handler_t *voe)
{
}

/*****************************************************************************/

/** \cond */

EXPORT_SYMBOL(ecrt_voe_handler_send_header);
EXPORT_SYMBOL(ecrt_voe_handler_received_header);
EXPORT_SYMBOL(ecrt_voe_handler_data);
EXPORT_SYMBOL(ecrt_voe_handler_data_size);
EXPORT_SYMBOL(ecrt_voe_handler_read);
EXPORT_SYMBOL(ecrt_voe_handler_write);
EXPORT_SYMBOL(ecrt_voe_handler_execute);

/** \endcond */

/*****************************************************************************/


<|start_filename|>3rdpart/ethercat-1.5.2/master/fsm_pdo_entry.h<|end_filename|>
/******************************************************************************
 *
 *  $Id: fsm_pdo_entry.h,v 9cdd7669dc0b 2013/01/10 16:36:41 fp $
 *
 *  Copyright (C) 2006-2008  <NAME>, Ingenieurgemeinschaft IgH
 *
 *  This file is part of the IgH EtherCAT Master.
 *
 *  The IgH EtherCAT Master is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License version 2, as
 *  published by the Free Software Foundation.
 *
 *  The IgH EtherCAT Master is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 *  Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with the IgH EtherCAT Master; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 *****************************************************************************/

/** \file
 * EtherCAT PDO entry configuration state machine structures.
 */

/*****************************************************************************/

#ifndef __EC_FSM_PDO_ENTRY_H__
#define __EC_FSM_PDO_ENTRY_H__

#include "globals.h"
#include "datagram.h"
#include "fsm_coe.h"

/*****************************************************************************/

/**
 * \see ec_fsm_pdo_entry
 */
typedef struct ec_fsm_pdo_entry ec_fsm_pdo_entry_t;

/** PDO configuration state machine.
 */
struct ec_fsm_pdo_entry
{
    void (*state)(ec_fsm_pdo_entry_t *, ec_datagram_t *); /**< state function
                                                           */
    ec_fsm_coe_t *fsm_coe; /**< CoE state machine to use */
    ec_sdo_request_t request; /**< SDO request. */

    ec_slave_t *slave; /**< Slave the FSM runs on. */
    ec_pdo_t *target_pdo; /**< PDO to read the mapping for. */
    const ec_pdo_t *source_pdo; /**< PDO with desired mapping. */
    const ec_pdo_t *cur_pdo; /**< PDO with current mapping (display only). */
    const ec_pdo_entry_t *entry; /**< Current entry. */
    unsigned int entry_count; /**< Number of entries. */
    unsigned int entry_pos; /**< Position in PDO mapping. */
};

/*****************************************************************************/

void ec_fsm_pdo_entry_init(ec_fsm_pdo_entry_t *, ec_fsm_coe_t *);
void ec_fsm_pdo_entry_clear(ec_fsm_pdo_entry_t *);

void ec_fsm_pdo_entry_start_reading(ec_fsm_pdo_entry_t *, ec_slave_t *,
        ec_pdo_t *);
void ec_fsm_pdo_entry_start_configuration(ec_fsm_pdo_entry_t *, ec_slave_t *,
        const ec_pdo_t *, const ec_pdo_t *);

int ec_fsm_pdo_entry_exec(ec_fsm_pdo_entry_t *, ec_datagram_t *);
int ec_fsm_pdo_entry_success(const ec_fsm_pdo_entry_t *);

/*****************************************************************************/

#endif


<|start_filename|>3rdpart/ethercat-1.5.2/tool/DataTypeHandler.cpp<|end_filename|>
/*****************************************************************************
 *
 *  $Id: DataTypeHandler.cpp,v bc2d4bf9cbe5 2012/09/06 18:22:24 fp $
 *
 *  Copyright (C) 2006-2009  <NAME>, Ingenieurgemeinschaft IgH
 *
 *  This file is part of the IgH EtherCAT Master.
 *
 *  The IgH EtherCAT Master is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License version 2, as
 *  published by the Free Software Foundation.
 *
 *  The IgH EtherCAT Master is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 *  Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with the IgH EtherCAT Master; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 ****************************************************************************/

#define DEBUG 0

#if DEBUG
#include <iostream>
#endif

#include <iomanip>
#include <sstream>
using namespace std;

#include "DataTypeHandler.h"

#include "ecrt.h"

/*****************************************************************************/

DataTypeHandler::DataTypeHandler()
{
}

/****************************************************************************/

const DataTypeHandler::DataType *DataTypeHandler::findDataType(
        const string &str
        )
{
    const DataType *d;

    for (d = dataTypes; d->name; d++)
        if (str == d->name)
            return d;

    return NULL; // FIXME exception
}

/****************************************************************************/

string DataTypeHandler::typeInfo()
{
	stringstream s;

	s
		<< "These are valid data types to use with" << endl
		<< "the --type option:" << endl
		<< "  bool," << endl
		<< "  int8, int16, int32, int64," << endl
		<< "  uint8, uint16, uint32, uint64," << endl
		<< "  float, double," << endl
		<< "  string, octet_string, unicode_string." << endl
        << "For sign-and-magnitude coding, use the following types:" << endl
        << "  sm8, sm16, sm32, sm64" << endl;
	return s.str();
}

/****************************************************************************/

const DataTypeHandler::DataType *DataTypeHandler::findDataType(uint16_t code)
{
    const DataType *d;

    for (d = dataTypes; d->name; d++)
        if (code == d->code)
            return d;

    return NULL;
}

/****************************************************************************/

size_t DataTypeHandler::interpretAsType(
        const DataType *type,
        const string &source,
        void *target,
        size_t targetSize
        )
{
    stringstream str;
    size_t dataSize = type->byteSize;

#if DEBUG
	cerr << __func__ << "(targetSize=" << targetSize << ")" << endl;
#endif

    str << source;
    str >> resetiosflags(ios::basefield); // guess base from prefix
    str.exceptions(ios::failbit);

#if DEBUG
	cerr << "code=" << type->code << endl;
#endif

    switch (type->code) {
        case 0x0001: // bool
            {
                int16_t val; // uint8_t is interpreted as char
                str >> val;
                if (val > 1 || val < 0)
                    throw ios::failure("Value out of range");
                *(uint8_t *) target = val;
                break;
            }
        case 0x0002: // int8
            {
                int16_t val; // uint8_t is interpreted as char
                str >> val;
                if (val > 127 || val < -128)
                    throw ios::failure("Value out of range");
                *(uint8_t *) target = val;
                break;
            }
        case 0x0003: // int16
            {
                int16_t val;
                str >> val;
                *(int16_t *) target = cpu_to_le16(val);
                break;
            }
        case 0x0004: // int32
            {
                int32_t val;
                str >> val;
                *(int32_t *) target = cpu_to_le32(val);
                break;
            }
        case 0x0005: // uint8
            {
                uint16_t val; // uint8_t is interpreted as char
                str >> val;
                if (val > 0xff)
                    throw ios::failure("Value out of range");
                *(uint8_t *) target = val;
                break;
            }
        case 0x0006: // uint16
            {
                uint16_t val;
                str >> val;
                *(uint16_t *) target = cpu_to_le16(val);
                break;
            }
        case 0x0007: // uint32
            {
                uint32_t val;
                str >> val;
                *(uint32_t *) target = cpu_to_le32(val);
                break;
            }
        case 0x0008: // float
            {
                float val;
                str >> val;
                *(uint32_t *) target =
					cpu_to_le32(*(uint32_t *) (void *) &val);
                break;
            }
        case 0x0009: // string
        case 0x000a: // octet_string
        case 0x000b: // unicode_string
            dataSize = str.str().size();
            if (dataSize > targetSize) {
                stringstream err;
                err << "String too large ("
                    << dataSize << " > " << targetSize << ")";
                throw SizeException(err.str());
            }
            str >> (char *) target;
            break;
        case 0x0011: // double
            {
                double val;
                str >> val;
                *(uint64_t *) target =
					cpu_to_le64(*(uint64_t *) (void *) &val);
                break;
            }
            break;
        case 0x0015: // int64
            {
                int64_t val;
                str >> val;
                *(int64_t *) target = cpu_to_le64(val);
                break;
            }
            break;
        case 0x001b: // uint64
            {
                uint64_t val;
                str >> val;
                *(uint64_t *) target = cpu_to_le64(val);
                break;
            }
            break;

        case 0x0010: // int24
        case 0x0012: // int40
        case 0x0013: // int48
        case 0x0014: // int56
        case 0x0016: // uint24
        case 0x0018: // uint40
        case 0x0019: // uint48
        case 0x001a: // uint56
            {
                stringstream err;
                err << "Non-native integer type " << type->name
					<< " is not yet implemented.";
                throw runtime_error(err.str());
            }

        case 0xfffb: // sm8
        case 0xfffc: // sm16
        case 0xfffd: // sm32
        case 0xfffe: // sm64
            {
                stringstream err;
                err << "Sign-and-magitude types not yet"
                    " implemented for input direction.";
                throw runtime_error(err.str());
            }

        default:
            {
                stringstream err;
                err << "Unknown data type 0x" << hex << type->code;
                throw runtime_error(err.str());
            }
    }

#if DEBUG
	printRawData(cerr, (const uint8_t *) target, dataSize);
#endif

    return dataSize;
}

/****************************************************************************/

void DataTypeHandler::outputData(
        ostream &o,
        const DataType *type,
        void *data,
        size_t dataSize
        )
{
    uint16_t typeCode;

    if (type) {
        if (type->byteSize && dataSize != type->byteSize) {
            stringstream err;
            err << "Data type mismatch. Expected " << type->name
                << " with " << type->byteSize << " byte, but got "
                << dataSize << " byte.";
            throw SizeException(err.str());
        }
        typeCode = type->code;
    } else {
        typeCode = 0xffff; // raw data
    }

    o << setfill('0');

    switch (typeCode) {
        case 0x0001: // bool
            {
                int val = (int) *(int8_t *) data;
                o << "0x" << hex << setw(2) << val
                    << " " << dec << val << endl;
            }
            break;
        case 0x0002: // int8
            {
                int val = (int) *(int8_t *) data;
                o << "0x" << hex << setw(2) << val
                    << " " << dec << val << endl;
            }
            break;
        case 0x0003: // int16
            {
                int16_t val = le16_to_cpup(data);
                o << "0x" << hex << setw(4) << val
                    << " " << dec << val << endl;
            }
            break;
        case 0x0004: // int32
            {
                int32_t val = le32_to_cpup(data);
                o << "0x" << hex << setw(8) << val
                    << " " << dec << val << endl;
            }
            break;
        case 0x0005: // uint8
            {
                unsigned int val = (unsigned int) *(uint8_t *) data;
                o << "0x" << hex << setw(2) << val
                    << " " << dec << val << endl;
            }
            break;
        case 0x0006: // uint16
            {
                uint16_t val = le16_to_cpup(data);
                o << "0x" << hex << setw(4) << val
                    << " " << dec << val << endl;
            }
            break;
        case 0x0007: // uint32
            {
                uint32_t val = le32_to_cpup(data);
                o << "0x" << hex << setw(8) << val
                    << " " << dec << val << endl;
            }
            break;
        case 0x0008: // float
            {
                uint32_t val = le32_to_cpup(data);
				float fval = *(float *) (void *) &val;
                o << fval << endl;
            }
            break;
        case 0x0009: // string
            o << string((const char *) data, dataSize) << endl;
            break;
        case 0x000a: // octet_string
            o << string((const char *) data, dataSize) << flush;
            break;
        case 0x000b: // unicode_string
			// FIXME encoding
            o << string((const char *) data, dataSize) << endl;
            break;
        case 0x0011: // double
            {
                uint64_t val = le64_to_cpup(data);
				double fval = *(double *) (void *) &val;
                o << fval << endl;
            }
            break;
        case 0x0015: // int64
            {
                int64_t val = le64_to_cpup(data);
                o << "0x" << hex << setw(16) << val
                    << " " << dec << val << endl;
            }
            break;
        case 0x001b: // uint64
            {
                uint64_t val = le64_to_cpup(data);
                o << "0x" << hex << setw(16) << val
                    << " " << dec << val << endl;
            }
            break;
        case 0xfffb: // sm8
            {
                int8_t val = *(uint8_t *) data;
                int8_t smval = val < 0 ? (val & 0x7f) * -1 : val;

                o << "0x" << hex << setw(2) << (int) val
                    << " " << dec << (int) smval << endl;
            }
            break;
        case 0xfffc: // sm16
            {
                int16_t val = le16_to_cpup(data);
                int16_t smval = val < 0 ? (val & 0x7fff) * -1 : val;

                o << "0x" << hex << setw(4) << val
                    << " " << dec << smval << endl;
            }
            break;
        case 0xfffd: // sm32
            {
                int32_t val = le32_to_cpup(data);
                int32_t smval = val < 0 ? (val & 0x7fffffffUL) * -1 : val;

                o << "0x" << hex << setw(8) << val
                    << " " << dec << smval << endl;
            }
            break;
        case 0xfffe: // sm64
            {
                int64_t val = le64_to_cpup(data);
                int64_t smval =
                    val < 0 ? (val & 0x7fffffffffffffffULL) * -1 : val;

                o << "0x" << hex << setw(16) << val
                    << " " << dec << smval << endl;
            }
            break;

        default:
            printRawData(o, (const uint8_t *) data, dataSize); // FIXME
            break;
    }
}

/****************************************************************************/

void DataTypeHandler::printRawData(
        ostream &o,
        const uint8_t *data,
        size_t size
        )
{
    o << hex << setfill('0');
    while (size--) {
        o << "0x" << setw(2) << (unsigned int) *data++;
        if (size)
            o << " ";
    }
    o << endl;
}

/****************************************************************************/

const DataTypeHandler::DataType DataTypeHandler::dataTypes[] = {
    {"bool",           0x0001, 1},
    {"int8",           0x0002, 1},
    {"int16",          0x0003, 2},
    {"int32",          0x0004, 4},
    {"uint8",          0x0005, 1},
    {"uint16",         0x0006, 2},
    {"uint32",         0x0007, 4},
    {"float",          0x0008, 4},
    {"string",         0x0009, 0}, // a. k. a. visible_string
    {"octet_string",   0x000a, 0},
    {"unicode_string", 0x000b, 0},
	// ... not implemented yet
    {"int24",          0x0010, 3},
    {"double",         0x0011, 8},
    {"int40",          0x0012, 5},
    {"int48",          0x0013, 6},
    {"int56",          0x0014, 7},
    {"int64",          0x0015, 8},
    {"uint24",         0x0016, 3},
	// reserved        0x0017
    {"uint40",         0x0018, 5},
    {"uint48",         0x0019, 6},
    {"uint56",         0x001a, 7},
    {"uint64",         0x001b, 8},
	// reserved        0x001c-0x001f
    {"sm8",            0xfffb, 1}, // sign-and-magnitude coding
    {"sm16",           0xfffc, 2}, // sign-and-magnitude coding
    {"sm32",           0xfffd, 4}, // sign-and-magnitude coding
    {"sm64",           0xfffe, 8}, // sign-and-magnitude coding
    {"raw",            0xffff, 0},
    {}
};

/*****************************************************************************/


<|start_filename|>3rdpart/ethercat-1.5.2/tool/CommandSlaves.h<|end_filename|>
/*****************************************************************************
 *
 *  $Id: CommandSlaves.h,v bc2d4bf9cbe5 2012/09/06 18:22:24 fp $
 *
 *  Copyright (C) 2006-2009  <NAME>, Ingenieurgemeinschaft IgH
 *
 *  This file is part of the IgH EtherCAT Master.
 *
 *  The IgH EtherCAT Master is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License version 2, as
 *  published by the Free Software Foundation.
 *
 *  The IgH EtherCAT Master is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 *  Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with the IgH EtherCAT Master; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 ****************************************************************************/

#ifndef __COMMANDSLAVES_H__
#define __COMMANDSLAVES_H__

#include "Command.h"

/****************************************************************************/

class CommandSlaves:
    public Command
{
    public:
        CommandSlaves();

        string helpString(const string &) const;
        void execute(const StringVector &);

    protected:
        struct Info {
            string pos;
            string alias;
            string relPos;
            string state;
            string flag;
            string name;
            unsigned int device;
        };

        void listSlaves(MasterDevice &, const SlaveList &, bool);
        void showSlaves(MasterDevice &, const SlaveList &);

        static bool slaveInList( const ec_ioctl_slave_t &, const SlaveList &);
};

/****************************************************************************/

#endif


<|start_filename|>rootfs/buildroot-2017.11.1/package/libpqxx/libpqxx.mk<|end_filename|>
################################################################################
#
# libpqxx
#
################################################################################

LIBPQXX_VERSION = 4.0.1
LIBPQXX_SITE = http://pqxx.org/download/software/libpqxx
LIBPQXX_INSTALL_STAGING = YES
LIBPQXX_DEPENDENCIES = postgresql
LIBPQXX_LICENSE = BSD-3-Clause
LIBPQXX_LICENSE_FILES = COPYING

# 0001-Fix-broken-sed-call-in-configure.ac.in.patch
LIBPQXX_AUTORECONF = YES

LIBPQXX_CONF_ENV += ac_cv_path_PG_CONFIG=$(STAGING_DIR)/usr/bin/pg_config

$(eval $(autotools-package))


<|start_filename|>3rdpart/tslib-1.15/tests/ts_calibrate.h<|end_filename|>
#ifndef _TSCALIBRATE_H
#define _TSCALIBRATE_H
/*
 *  tslib/tests/ts_calibrate.h
 *
 *  Copyright (C) 2001 <NAME>.
 *
 * This file is placed under the GPL.  Please see the file
 * COPYING for more details.
 *
 * SPDX-License-Identifier: GPL-2.0+
 *
 *
 * functions used for calibrating
 */
typedef struct {
	int x[5], xfb[5];
	int y[5], yfb[5];
	int a[7];
} calibration;

int perform_calibration(calibration *cal);

#endif /* _TSCALIBRATE_H */


<|start_filename|>3rdpart/tslib-1.15/tests/ts_verify.c<|end_filename|>
/*
 *  tslib/tests/ts_verify.c
 *
 *  Copyright (C) 2017 <NAME>
 *
 * This file is part of tslib.
 *
 * ts_verify is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * ts_verify is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with ts_verify.  If not, see <http://www.gnu.org/licenses/>.
 *
 * SPDX-License-Identifier: GPL-2.0+
 *
 *
 * This program includes random tests of tslib's API
 */
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/time.h>
#include <getopt.h>
#include <errno.h>
#include <unistd.h>

#if defined (__FreeBSD__)

#include <dev/evdev/input.h>
#define TS_HAVE_EVDEV

#elif defined (__linux__)

#include <linux/input.h>
#define TS_HAVE_EVDEV

#endif

#include "tslib.h"
#include "testutils.h"

#ifndef ABS_MT_SLOT /* < 2.6.36 kernel headers */
# define ABS_MT_SLOT             0x2f    /* MT slot being modified */
#endif


#define CONFFILE "ts_verify_ts.conf"

struct ts_verify {
	struct tsdev *ts;
	char *tsdevice;
	uint8_t verbose;
	FILE *tsconf;

	struct ts_sample_mt **samp_mt;
	struct ts_sample *samp_read;
	int32_t slots;
	uint8_t nr;
	uint16_t read_mt_run_count;
	uint16_t read_mt_fail_count;
	uint16_t read_run_count;
	uint16_t read_fail_count;
	uint16_t iteration;
	uint16_t nr_of_iterations;
};

static void usage(char **argv)
{
	struct ts_lib_version_data *ver = ts_libversion();

	printf("tslib %s\n", ver->package_version);
	printf("\n");
	printf("Usage: %s [--idev <device>] [--verbose]\n", argv[0]);
}

static int ts_verify_alloc_mt(struct ts_verify *data, int nr, int8_t nonblocking)
{
#ifdef TS_HAVE_EVDEV
	struct input_absinfo slot;
#endif
	int i, j;

	data->ts = ts_setup(data->tsdevice, nonblocking);
	if (!data->ts) {
		perror("ts_setup");
		return errno;
	}

#ifdef TS_HAVE_EVDEV
	if (ioctl(ts_fd(data->ts), EVIOCGABS(ABS_MT_SLOT), &slot) < 0) {
		perror("ioctl EVIOGABS");
		ts_close(data->ts);
		return errno;
	}

	data->slots = slot.maximum + 1 - slot.minimum;
#else
	data->slots = 11;
#endif

	data->samp_mt = malloc(nr * sizeof(struct ts_sample_mt *));
	if (!data->samp_mt) {
		ts_close(data->ts);
		return -ENOMEM;
	}
	for (i = 0; i < nr; i++) {
		data->samp_mt[i] = calloc(data->slots,
					  sizeof(struct ts_sample_mt));
		if (!data->samp_mt[i]) {
			for (j = 0; j < i; j++)
				free(data->samp_mt[j]);

			free(data->samp_mt);
			ts_close(data->ts);
			return -ENOMEM;
		}
	}

	return 0;
}

static void ts_verify_free_mt(struct ts_verify *data)
{
	int i;

	if (!data->samp_mt)
		return;

	for (i = 0; i < data->nr; i++) {
		if (data->samp_mt[i])
			free(data->samp_mt[i]);
	}
	ts_close(data->ts);
}

/* TEST ts_read_mt 1 */
static int ts_verify_read_mt_1(struct ts_verify *data, int nr,
				     int8_t nonblocking, int raw)
{
	int i, j;
	int ret;
	int count = 0;

	ret = ts_verify_alloc_mt(data, nr, nonblocking);
	if (ret < 0)
		return ret;

	/* blocking operation */
	if (nonblocking != 1) {
		if (raw == 0)
			ret = ts_read_mt(data->ts, data->samp_mt, data->slots, nr);
		else
			ret = ts_read_raw_mt(data->ts, data->samp_mt, data->slots, nr);
		if (ret < 0) {
			perror("ts_read_mt");
			ts_verify_free_mt(data);
			return ret;
		}

		for (j = 0; j < ret; j++) {
			for (i = 0; i < data->slots; i++) {
				if (!(data->samp_mt[j][i].valid & TSLIB_MT_VALID))
					continue;

				if (data->samp_mt[j][i].pressure > 255) {
					if (data->verbose)
						printf("pressure out of bounds\n");
				}
				/* TODO check xy bounds when fbdev and not raw*/
			}
		}
	/* non blocking operation */
	} else {
		while (1) {
			if (raw == 0)
				ret = ts_read_mt(data->ts, data->samp_mt, data->slots, nr);
			else
				ret = ts_read_raw_mt(data->ts, data->samp_mt, data->slots, nr);
			if (ret == -EAGAIN) {
				continue;
			} else if (ret < 0) {
				perror("ts_read_mt");
				ts_verify_free_mt(data);
				return ret;
			} else {
				count = count + ret;

				if (data->verbose)
					printf("got %d samples in 1 read\n", ret);
			}

			if (count >= nr) {
				ret = count;
				break;
			}
		}
	}

	ts_verify_free_mt(data);

	return ret;
}

static int ts_verify_read_1(struct ts_verify *data, int nr,
			    int nonblocking, int raw)
{
	int ret;

	if (!data->samp_read) {
		data->samp_read = calloc(nr, sizeof(struct ts_sample));
		if (!data->samp_read) {
			perror("calloc");
			return errno;
		}
	}

	data->ts = ts_setup(data->tsdevice, nonblocking);
	if (!data->ts) {
		free(data->samp_read);
		perror("ts_setup");
		return errno;
	}

	/* blocking */
	if (nonblocking != 1) {
		if (raw == 0)
			ret = ts_read(data->ts, data->samp_read, nr);
		else
			ret = ts_read_raw(data->ts, data->samp_read, nr);
	/*non blocking*/
	} else {
		while (1) {
			if (raw == 0)
				ret = ts_read(data->ts, data->samp_read, nr);
			else
				ret = ts_read_raw(data->ts, data->samp_read, nr);

	/* yeah that's lame but that's pretty much the only way it's used out there. it's deprecated anyways  */
			if (ret == nr)
				break;
		}
	}

	ts_close(data->ts);
	free(data->samp_read);
	data->samp_read = NULL;

	return ret;
}

static int ts_reconfig_1(struct ts_verify *data)
{
	int ret = 0;

	data->ts = ts_setup(data->tsdevice, 0);
	if (!data->ts) {
		perror("ts_setup");
		return errno;
	}

	ret = ts_reconfig(data->ts);
	if (data->verbose)
		printf("ts_reconfig ret: %d\n", ret);

	ts_close(data->ts);

	return ret;
}

static int ts_load_module_4_inv(struct ts_verify *data)
{
	int ret = 0;

	data->ts = ts_setup(data->tsdevice, 0);
	if (!data->ts) {
		perror("ts_setup");
		return errno;
	}

	ret = ts_load_module(data->ts, "asdf", "asdf");

	ts_close(data->ts);

	return ret;
}

static void run_tests(struct ts_verify *data)
{
	int32_t ret;

	printf("===================== test run %d =====================\n", data->iteration);

	/* ts_read() paramters(data, samples, nonblocking, raw) */
	ret = ts_verify_read_mt_1(data, 1, 0, 0);
	data->read_mt_run_count++;
	if (ret <= 1 && ret >= 0) {
		printf("TEST ts_read_mt (blocking) 1       ......   " GREEN "PASS" RESET "\n");
	} else {
		printf("TEST ts_read_mt (blocking) 1       ......   " RED "FAIL" RESET "\n");
		data->read_mt_fail_count++;
	}

	ret = ts_verify_read_mt_1(data, 5, 0, 0);
	data->read_mt_run_count++;
	if (ret <= 5 && ret > 1) { /* > 1 according to expected from filters */
		printf("TEST ts_read_mt (blocking) 5       ......   " GREEN "PASS" RESET "\n");
	} else {
		printf("TEST ts_read_mt (blocking) 5       ......   " RED "FAIL" RESET "\n");
		data->read_mt_fail_count++;
	}

	ret = ts_verify_read_mt_1(data, 1, 1, 0);
	data->read_mt_run_count++;
	if (ret <= 1 && ret >= 0) {
		printf("TEST ts_read_mt (nonblocking) 1    ......   " GREEN "PASS" RESET "\n");
	} else {
		printf("TEST ts_read_mt (nonblocking) 1    ......   " RED "FAIL" RESET "\n");
		data->read_mt_fail_count++;
	}

	ret = ts_verify_read_mt_1(data, 5, 1, 0);
	data->read_mt_run_count++;
	if (ret <= 5 && ret > 1) { /* > 1 */
		printf("TEST ts_read_mt (nonblocking) 5    ......   " GREEN "PASS" RESET "\n");
	} else {
		printf("TEST ts_read_mt (nonblocking) 5    ......   " RED "FAIL" RESET "\n");
		data->read_mt_fail_count++;
	}

	ret = ts_verify_read_1(data, 1, 0, 0);
	data->read_run_count++;
	if (ret <= 1 && ret >= 0) {
		printf("TEST ts_read    (blocking) 1       ......   " GREEN "PASS" RESET "\n");
	} else {
		printf("TEST ts_read    (blocking) 1       ......   " RED "FAIL" RESET "\n");
		data->read_fail_count++;
	}

	ret = ts_verify_read_1(data, 5, 0, 0);
	data->read_run_count++;
	if (ret <= 5 && ret > 1) { /* > 1 */
		printf("TEST ts_read    (blocking) 5       ......   " GREEN "PASS" RESET "\n");
	} else {
		printf("TEST ts_read    (blocking) 5       ......   " RED "FAIL" RESET "\n");
		data->read_fail_count++;
	}

	ret = ts_verify_read_1(data, 1, 1, 0);
	data->read_run_count++;
	if (ret <= 1 && ret >= 0) {
		printf("TEST ts_read    (nonblocking) 1    ......   " GREEN "PASS" RESET "\n");
	} else {
		printf("TEST ts_read    (nonblocking) 1    ......   " RED "FAIL" RESET "\n");
		data->read_fail_count++;
	}



	/* the same with the raw calls */
	ret = ts_verify_read_mt_1(data, 1, 0, 1);
	data->read_mt_run_count++;
	if (ret <= 1 && ret >= 0) {
		printf("TEST ts_read_raw_mt (blocking) 1   ......   " GREEN "PASS" RESET "\n");
	} else {
		printf("TEST ts_read_raw_mt (blocking) 1   ......   " RED "FAIL" RESET "\n");
		data->read_mt_fail_count++;
	}

	ret = ts_verify_read_mt_1(data, 5, 0, 1);
	data->read_mt_run_count++;
	if (ret <= 5 && ret > 1) { /* > 1 */
		printf("TEST ts_read_raw_mt (blocking) 5   ......   " GREEN "PASS" RESET "\n");
	} else {
		printf("TEST ts_read_raw_mt (blocking) 5   ......   " RED "FAIL" RESET "\n");
		data->read_mt_fail_count++;
	}

	ret = ts_verify_read_mt_1(data, 1, 1, 1);
	data->read_mt_run_count++;
	if (ret <= 1 && ret >= 0) {
		printf("TEST ts_read_raw_mt (nonblocking) 1......   " GREEN "PASS" RESET "\n");
	} else {
		printf("TEST ts_read_raw_mt (nonblocking) 1......   " RED "FAIL" RESET "\n");
		data->read_mt_fail_count++;
	}

	ret = ts_verify_read_mt_1(data, 5, 1, 1);
	data->read_mt_run_count++;
	if (ret <= 5 && ret > 1) { /* > 1 */
		printf("TEST ts_read_raw_mt (nonblocking) 5......   " GREEN "PASS" RESET "\n");
	} else {
		printf("TEST ts_read_raw_mt (nonblocking) 5......   " RED "FAIL" RESET "\n");
		data->read_mt_fail_count++;
	}

	ret = ts_verify_read_1(data, 1, 0, 1);
	data->read_run_count++;
	if (ret <= 1 && ret >= 0) {
		printf("TEST ts_read_raw(blocking) 1       ......   " GREEN "PASS" RESET "\n");
	} else {
		printf("TEST ts_read_raw(blocking) 1       ......   " RED "FAIL" RESET "\n");
		data->read_fail_count++;
	}

	ret = ts_verify_read_1(data, 5, 0, 1);
	data->read_run_count++;
	if (ret <= 5 && ret > 1) { /* > 1 */
		printf("TEST ts_read_raw(blocking) 5       ......   " GREEN "PASS" RESET "\n");
	} else {
		printf("TEST ts_read_raw(blocking) 5       ......   " RED "FAIL" RESET "\n");
		data->read_fail_count++;
	}

	ret = ts_verify_read_1(data, 1, 1, 1);
	data->read_run_count++;
	if (ret <= 1 && ret >= 0) {
		printf("TEST ts_read_raw(nonblocking) 1    ......   " GREEN "PASS" RESET "\n");
	}



	ret = ts_reconfig_1(data);
	if (ret == 0) {
		printf("TEST ts_reconfig (1)               ......   " GREEN "PASS" RESET "\n");
	} else {
		printf("TEST ts_reconfig (1)               ......   " RED "FAIL" RESET "\n");
	}

	ret = ts_load_module_4_inv(data);
	if (ret == 0) {
		printf("TEST ts_load_module (4)            ......   " RED "FAIL" RESET "\n");
	} else {
		printf("TEST ts_load_module (4)            ......   " GREEN "PASS" RESET "\n");
	}

	data->iteration++;
}

int main(int argc, char **argv)
{
	struct ts_verify data = {
		.ts = NULL,
		.tsdevice = NULL,
		.slots = 1,
		.samp_mt = NULL,
		.samp_read = NULL,
		.verbose = 0,
		.read_fail_count = 0,
		.read_mt_fail_count = 0,
		.read_run_count = 0,
		.read_mt_run_count = 0,
		.iteration = 0,
		.nr_of_iterations = 6,
		.tsconf = NULL,
	};
	struct ts_lib_version_data *ver = ts_libversion();

	while (1) {
		const struct option long_options[] = {
			{ "help",         no_argument,       NULL, 'h' },
			{ "idev",         required_argument, NULL, 'i' },
			{ "verbose",      no_argument,       NULL, 'v' },
		};

		int option_index = 0;
		int c = getopt_long(argc, argv, "hi:v", long_options,
				    &option_index);

		errno = 0;
		if (c == -1)
			break;

		switch (c) {
		case 'h':
			usage(argv);
			return 0;

		case 'i':
			data.tsdevice = optarg;
			break;

		case 'v':
			data.verbose = 1;
			break;

		default:
			usage(argv);
			return 0;
		}

		if (errno) {
			char str[9];
			sprintf(str, "option ?");
			str[7] = c & 0xff;
			perror(str);
		}
	}

	unlink(CONFFILE);
	data.tsconf = fopen(CONFFILE, "a+");
	fprintf(data.tsconf, "module_raw input\n");
	fclose(data.tsconf);

	if (setenv("TSLIB_CONFFILE", CONFFILE, 1) == -1)
		return errno;


	printf("                 _       _ _ _\n");
	printf("                | |_ ___| (_) |__\n");
	printf("                | __/ __| | | '_ \\\n");
	printf("                | |_\\__ \\ | | |_) |\n");
	printf("                 \\__|___/_|_|_.__/\n\n");
	printf("tslib %s / libts ABI version %d (0x%06X)\n",
		ver->package_version, ver->version_num >> 16, ver->version_num);

	run_tests(&data);

	data.tsconf = fopen(CONFFILE, "a+");
	fprintf(data.tsconf, "module skip nhead=1 ntail=1\n");
	fclose(data.tsconf);
	printf("======================================================\n");
	printf("skip\n");

	run_tests(&data);

	data.tsconf = fopen(CONFFILE, "a+");
	fprintf(data.tsconf, "module pthres pmin=20\n");
	fclose(data.tsconf);
	printf("======================================================\n");
	printf("skip -> pthres\n");

	run_tests(&data);

	data.tsconf = fopen(CONFFILE, "a+");
	fprintf(data.tsconf, "module debounce drop_threshold=40\n");
	fclose(data.tsconf);
	printf("======================================================\n");
	printf("skip -> pthres -> debounce\n");

	run_tests(&data);

	data.tsconf = fopen(CONFFILE, "a+");
	fprintf(data.tsconf, "module median depth=7\n");
	fclose(data.tsconf);
	printf("======================================================\n");
	printf("skip -> pthres -> debounce -> median\n");

	run_tests(&data);

	data.tsconf = fopen(CONFFILE, "a+");
	fprintf(data.tsconf, "module dejitter delta=100\n");
	fclose(data.tsconf);
	printf("======================================================\n");
	printf("skip -> pthres -> debounce -> median -> dejitter\n");

	run_tests(&data);

	data.tsconf = fopen(CONFFILE, "a+");
	fprintf(data.tsconf, "module lowpass\n");
	fclose(data.tsconf);
	printf("======================================================\n");
	printf("skip -> pthres -> debounce -> median -> dejitter -> lowpass\n");

	run_tests(&data);

	data.tsconf = fopen(CONFFILE, "a+");
	fprintf(data.tsconf, "module invert\n");
	fclose(data.tsconf);
	printf("======================================================\n");
	printf("skip -> pthres -> debounce -> median -> dejitter -> lowpass -> invert\n");

	run_tests(&data);

	data.tsconf = fopen(CONFFILE, "a+");
	fprintf(data.tsconf, "module linear\n");
	fclose(data.tsconf);
	printf("======================================================\n");
	printf("skip -> pthres -> debounce -> median -> dejitter -> lowpass -> invert -> linear\n");

	run_tests(&data);

	unlink(CONFFILE);

	printf("------------------------------------------------------\n");
	printf("summary of results:\n");
	printf("------------------------------------------------------\n");
	printf("read_mt FAILs: %3d of %3d\n", data.read_mt_fail_count, data.read_mt_run_count);
	printf("read    FAILs: %3d of %3d (WONTFIX)\n", data.read_fail_count, data.read_run_count);
	printf("------------------------------------------------------\n");

	return 0;
}


<|start_filename|>kernel/modules/platform/pltdev.c<|end_filename|>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>

#include <linux/platform_device.h>

static void pdev_release(struct device *dev)
{
}

/* 定义平台设备pdev0 */
struct platform_device pdev0 = {
	.name = "pdev",
	.id = 0,
	.num_resources = 0,
	.resource = NULL,
	.dev = {
		.release = pdev_release,
	},
};

/* 定义平台设备pdev1 */
struct platform_device pdev1 = {
	.name = "pdev",
	.id = 1,
	.num_resources = 0,
	.resource = NULL,
	.dev = {
		.release = pdev_release,
	},
};

static int __init pltdev_init(void)
{
	/* 注册平台设备 */
	platform_device_register(&pdev0);
	platform_device_register(&pdev1);

	return 0;
}

static void __exit pltdev_exit(void)
{
	/* 注销平台设备 */
	platform_device_unregister(&pdev1);
	platform_device_unregister(&pdev0);
}

module_init(pltdev_init);
module_exit(pltdev_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("suda-morris <<EMAIL>>");
MODULE_DESCRIPTION("register a platfom device");


<|start_filename|>3rdpart/tslib-1.15/plugins/lowpass.c<|end_filename|>
/*
 * tslib/plugins/lowpass.c
 *
 * Copyright 2017 <NAME> <<EMAIL>>
 * Courtesy of Openmoko, 2011
 *
 * This file is placed under the LGPL.  Please see the file
 * COPYING for more details.
 *
 * SPDX-License-Identifier: LGPL-2.1
 *
 *
 * Very stupid lowpass dejittering filter
 */
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <stdint.h>

#include "config.h"
#include "tslib.h"
#include "tslib-filter.h"

struct tslib_lowpass {
	struct tslib_module_info module;
	struct ts_sample last;
	struct ts_sample ideal;
	struct ts_sample_mt *last_mt;
	struct ts_sample_mt *ideal_mt;
	int slots;
	float factor;
	unsigned int flags;
	unsigned int *flags_mt;
	unsigned char threshold;
#define VAR_PENUP		0x00000001
};

static int lowpass_read(struct tslib_module_info *info, struct ts_sample *samp, int nr)
{
	struct tslib_lowpass *var = (struct tslib_lowpass *)info;
	struct ts_sample current;
	int count = 0;
	int delta;

	while (count < nr) {
		if (info->next->ops->read(info->next, &current, 1) < 1)
			return count;

		if (current.pressure == 0) {
			var->flags |= VAR_PENUP;
			samp[count++] = current;
		} else if (var->flags & VAR_PENUP) {
			var->flags &= ~VAR_PENUP;
			var->last = current;
			samp[count++] = current;
		} else {
			var->ideal = current;

			var->ideal.x = var->last.x;
			delta = current.x - var->last.x;
			if (delta <= var->threshold &&
					delta >= -var->threshold)
				delta = 0;
			delta *= var->factor;
			var->ideal.x += delta;

			var->ideal.y = var->last.y;
			delta = current.y - var->last.y;
			if (delta <= var->threshold &&
					delta >= -var->threshold)
				delta = 0;
			delta *= var->factor;
			var->ideal.y += delta;

			var->last = var->ideal;
			samp[count++] = var->ideal;
		}
	}
	return count;
}

static int lowpass_read_mt(struct tslib_module_info *info,
			   struct ts_sample_mt **samp,
			   int max_slots, int nr)
{
	struct tslib_lowpass *var = (struct tslib_lowpass *)info;
	int delta;
	int ret;
	int i, j;

	if (!info->next->ops->read_mt)
		return -ENOSYS;

	ret = info->next->ops->read_mt(info->next, samp, max_slots, nr);
	if (ret < 0)
		return ret;

#ifdef DEBUG
	if (ret == 0)
		fprintf(stderr, "LOWPASS: couldn't read data\n");

	printf("LOWPASS: read %d samples (mem: %d nr x %d slots)\n",
		ret, nr, max_slots);
#endif

	if (!var->last_mt || !var->ideal_mt || max_slots > var->slots) {
		if (var->last_mt)
			free(var->last_mt);

		if (var->ideal_mt)
			free(var->ideal_mt);

		if (var->flags_mt)
			free(var->flags_mt);

		var->last_mt = calloc(max_slots, sizeof(struct ts_sample_mt));
		if (!var->last_mt)
			return -ENOMEM;

		var->ideal_mt = calloc(max_slots, sizeof(struct ts_sample_mt));
		if (!var->ideal_mt)
			return -ENOMEM;

		var->flags_mt = calloc(max_slots, sizeof(int));
		if (!var->flags_mt)
			return -ENOMEM;

		var->slots = max_slots;
	}

	for (i = 0; i < ret; i++) {
		for (j = 0; j < max_slots; j++) {
			if (!(samp[i][j].valid & TSLIB_MT_VALID))
				continue;

			if (samp[i][j].pressure == 0) {
				var->flags_mt[j] |= VAR_PENUP;
				continue;
			} else if (var->flags_mt[j] & VAR_PENUP) {
				var->flags_mt[j] &= ~VAR_PENUP;
				var->last_mt[j] = samp[i][j];
				continue;
			} else {
				var->ideal_mt[j] = samp[i][j];

				var->ideal_mt[j].x = var->last_mt[j].x;
				delta = samp[i][j].x - var->last_mt[j].x;
				if (delta <= var->threshold &&
				    delta >= -var->threshold)
					delta = 0;

				delta *= var->factor;
				var->ideal_mt[j].x += delta;


				var->ideal_mt[j].y = var->last_mt[j].y;
				delta = samp[i][j].y - var->last_mt[j].y;
				if (delta <= var->threshold &&
				    delta >= -var->threshold)
					delta = 0;

				delta *= var->factor;
				var->ideal_mt[j].y += delta;


				var->last_mt[j] = var->ideal_mt[j];
				samp[i][j] = var->ideal_mt[j];
			}
		}
	}

	return ret;
}

static int lowpass_fini(struct tslib_module_info *info)
{
	struct tslib_lowpass *var = (struct tslib_lowpass *)info;

	if (var->last_mt)
		free(var->last_mt);

	if (var->ideal_mt)
		free(var->ideal_mt);

	if (var->flags_mt)
		free(var->flags_mt);

	free(info);

	return 0;
}

static const struct tslib_ops lowpass_ops = {
	.read		= lowpass_read,
	.read_mt	= lowpass_read_mt,
	.fini		= lowpass_fini,
};

static int lowpass_factor(struct tslib_module_info *inf, char *str, void *data)
{
	struct tslib_lowpass *var = (struct tslib_lowpass *)inf;
	long double v;
	int err = errno;

	v = strtod(str, NULL);

	if (v > 1 || v < 0)
		return -1;

	errno = err;
	switch ((int)(intptr_t)data) {
	case 1:
		var->factor = v;
#ifdef DEBUG
		printf("LOWPASS: factor is now %Lf\n", v);
#endif
		break;

	default:
		return -1;
	}
	return 0;
}

static int lowpass_threshold(struct tslib_module_info *inf, char *str,
			     void *data)
{
	struct tslib_lowpass *var = (struct tslib_lowpass *)inf;
	long result;
	int err = errno;

	result = strtol(str, NULL, 0);
	if (errno == ERANGE)
		return -1;

	errno = err;

	switch ((int)(intptr_t)data) {
	case 1:
		var->threshold = result;
#ifdef DEBUG
		printf("LOWPASS: threshold is now %ld\n", result);
#endif
		break;
	default:
		return -1;
	}
	return 0;
}

static const struct tslib_vars lowpass_vars[] = {
	{ "factor",	(void *)1, lowpass_factor },
	{ "threshold",  (void *)1, lowpass_threshold },
};

#define NR_VARS (sizeof(lowpass_vars) / sizeof(lowpass_vars[0]))

TSAPI struct tslib_module_info *lowpass_mod_init(__attribute__ ((unused)) struct tsdev *dev,
						 const char *params)
{
	struct tslib_lowpass *var;

	var = malloc(sizeof(struct tslib_lowpass));
	if (var == NULL)
		return NULL;

	memset(var, 0, sizeof(*var));
	var->module.ops = &lowpass_ops;

	var->factor = 0.4;
	var->threshold = 2;
	var->flags = VAR_PENUP;
	var->slots = 0;
	var->last_mt = NULL;
	var->ideal_mt = NULL;
	var->flags_mt = NULL;

	if (tslib_parse_vars(&var->module, lowpass_vars, NR_VARS, params)) {
		free(var);
		return NULL;
	}


	return &var->module;
}

#ifndef TSLIB_STATIC_LOWPASS_MODULE
	TSLIB_MODULE_INIT(lowpass_mod_init);
#endif


<|start_filename|>3rdpart/tslib-1.15/tests/sdlutils.h<|end_filename|>
/*
 * SPDX-License-Identifier: GPL-2.0+
 */
#ifndef _SDLUTILS_H
#define _SDLUTILS_H
void draw_line(SDL_Renderer *r, int32_t x1, int32_t y1, int32_t x2, int32_t y2);
void draw_crosshair(SDL_Renderer *r, int32_t x, int32_t y);
void getxy(struct tsdev *ts, int *x, int *y);
void print_ascii_logo(void);
#endif /* _SDLUTILS_H */


<|start_filename|>3rdpart/ethercat-1.5.2/devices/e1000e/defines-2.6.37-orig.h<|end_filename|>
/*******************************************************************************

  Intel PRO/1000 Linux driver
  Copyright(c) 1999 - 2010 Intel Corporation.

  This program is free software; you can redistribute it and/or modify it
  under the terms and conditions of the GNU General Public License,
  version 2, as published by the Free Software Foundation.

  This program is distributed in the hope it will be useful, but WITHOUT
  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  more details.

  You should have received a copy of the GNU General Public License along with
  this program; if not, write to the Free Software Foundation, Inc.,
  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.

  The full GNU General Public License is included in this distribution in
  the file called "COPYING".

  Contact Information:
  Linux NICS <<EMAIL>>
  e1000-devel Mailing List <<EMAIL>>
  Intel Corporation, 5200 N.E. <NAME>way, Hillsboro, OR 97124-6497

*******************************************************************************/

#ifndef _E1000_DEFINES_H_
#define _E1000_DEFINES_H_

#define E1000_TXD_POPTS_IXSM 0x01       /* Insert IP checksum */
#define E1000_TXD_POPTS_TXSM 0x02       /* Insert TCP/UDP checksum */
#define E1000_TXD_CMD_EOP    0x01000000 /* End of Packet */
#define E1000_TXD_CMD_IFCS   0x02000000 /* Insert FCS (Ethernet CRC) */
#define E1000_TXD_CMD_IC     0x04000000 /* Insert Checksum */
#define E1000_TXD_CMD_RS     0x08000000 /* Report Status */
#define E1000_TXD_CMD_RPS    0x10000000 /* Report Packet Sent */
#define E1000_TXD_CMD_DEXT   0x20000000 /* Descriptor extension (0 = legacy) */
#define E1000_TXD_CMD_VLE    0x40000000 /* Add VLAN tag */
#define E1000_TXD_CMD_IDE    0x80000000 /* Enable Tidv register */
#define E1000_TXD_STAT_DD    0x00000001 /* Descriptor Done */
#define E1000_TXD_STAT_EC    0x00000002 /* Excess Collisions */
#define E1000_TXD_STAT_LC    0x00000004 /* Late Collisions */
#define E1000_TXD_STAT_TU    0x00000008 /* Transmit underrun */
#define E1000_TXD_CMD_TCP    0x01000000 /* TCP packet */
#define E1000_TXD_CMD_IP     0x02000000 /* IP packet */
#define E1000_TXD_CMD_TSE    0x04000000 /* TCP Seg enable */
#define E1000_TXD_STAT_TC    0x00000004 /* Tx Underrun */

/* Number of Transmit and Receive Descriptors must be a multiple of 8 */
#define REQ_TX_DESCRIPTOR_MULTIPLE  8
#define REQ_RX_DESCRIPTOR_MULTIPLE  8

/* Definitions for power management and wakeup registers */
/* Wake Up Control */
#define E1000_WUC_APME       0x00000001 /* APM Enable */
#define E1000_WUC_PME_EN     0x00000002 /* PME Enable */
#define E1000_WUC_PHY_WAKE   0x00000100 /* if PHY supports wakeup */

/* Wake Up Filter Control */
#define E1000_WUFC_LNKC 0x00000001 /* Link Status Change Wakeup Enable */
#define E1000_WUFC_MAG  0x00000002 /* Magic Packet Wakeup Enable */
#define E1000_WUFC_EX   0x00000004 /* Directed Exact Wakeup Enable */
#define E1000_WUFC_MC   0x00000008 /* Directed Multicast Wakeup Enable */
#define E1000_WUFC_BC   0x00000010 /* Broadcast Wakeup Enable */
#define E1000_WUFC_ARP  0x00000020 /* ARP Request Packet Wakeup Enable */

/* Wake Up Status */
#define E1000_WUS_LNKC         E1000_WUFC_LNKC
#define E1000_WUS_MAG          E1000_WUFC_MAG
#define E1000_WUS_EX           E1000_WUFC_EX
#define E1000_WUS_MC           E1000_WUFC_MC
#define E1000_WUS_BC           E1000_WUFC_BC

/* Extended Device Control */
#define E1000_CTRL_EXT_SDP3_DATA 0x00000080 /* Value of SW Definable Pin 3 */
#define E1000_CTRL_EXT_EE_RST    0x00002000 /* Reinitialize from EEPROM */
#define E1000_CTRL_EXT_SPD_BYPS  0x00008000 /* Speed Select Bypass */
#define E1000_CTRL_EXT_RO_DIS    0x00020000 /* Relaxed Ordering disable */
#define E1000_CTRL_EXT_DMA_DYN_CLK_EN 0x00080000 /* DMA Dynamic Clock Gating */
#define E1000_CTRL_EXT_LINK_MODE_MASK 0x00C00000
#define E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES  0x00C00000
#define E1000_CTRL_EXT_EIAME          0x01000000
#define E1000_CTRL_EXT_DRV_LOAD       0x10000000 /* Driver loaded bit for FW */
#define E1000_CTRL_EXT_IAME           0x08000000 /* Interrupt acknowledge Auto-mask */
#define E1000_CTRL_EXT_INT_TIMER_CLR  0x20000000 /* Clear Interrupt timers after IMS clear */
#define E1000_CTRL_EXT_PBA_CLR        0x80000000 /* PBA Clear */
#define E1000_CTRL_EXT_PHYPDEN        0x00100000

/* Receive Descriptor bit definitions */
#define E1000_RXD_STAT_DD       0x01    /* Descriptor Done */
#define E1000_RXD_STAT_EOP      0x02    /* End of Packet */
#define E1000_RXD_STAT_IXSM     0x04    /* Ignore checksum */
#define E1000_RXD_STAT_VP       0x08    /* IEEE VLAN Packet */
#define E1000_RXD_STAT_UDPCS    0x10    /* UDP xsum calculated */
#define E1000_RXD_STAT_TCPCS    0x20    /* TCP xsum calculated */
#define E1000_RXD_ERR_CE        0x01    /* CRC Error */
#define E1000_RXD_ERR_SE        0x02    /* Symbol Error */
#define E1000_RXD_ERR_SEQ       0x04    /* Sequence Error */
#define E1000_RXD_ERR_CXE       0x10    /* Carrier Extension Error */
#define E1000_RXD_ERR_TCPE      0x20    /* TCP/UDP Checksum Error */
#define E1000_RXD_ERR_RXE       0x80    /* Rx Data Error */
#define E1000_RXD_SPC_VLAN_MASK 0x0FFF  /* VLAN ID is in lower 12 bits */

#define E1000_RXDEXT_STATERR_CE    0x01000000
#define E1000_RXDEXT_STATERR_SE    0x02000000
#define E1000_RXDEXT_STATERR_SEQ   0x04000000
#define E1000_RXDEXT_STATERR_CXE   0x10000000
#define E1000_RXDEXT_STATERR_RXE   0x80000000

/* mask to determine if packets should be dropped due to frame errors */
#define E1000_RXD_ERR_FRAME_ERR_MASK ( \
    E1000_RXD_ERR_CE  |                \
    E1000_RXD_ERR_SE  |                \
    E1000_RXD_ERR_SEQ |                \
    E1000_RXD_ERR_CXE |                \
    E1000_RXD_ERR_RXE)

/* Same mask, but for extended and packet split descriptors */
#define E1000_RXDEXT_ERR_FRAME_ERR_MASK ( \
    E1000_RXDEXT_STATERR_CE  |            \
    E1000_RXDEXT_STATERR_SE  |            \
    E1000_RXDEXT_STATERR_SEQ |            \
    E1000_RXDEXT_STATERR_CXE |            \
    E1000_RXDEXT_STATERR_RXE)

#define E1000_RXDPS_HDRSTAT_HDRSP              0x00008000

/* Management Control */
#define E1000_MANC_SMBUS_EN      0x00000001 /* SMBus Enabled - RO */
#define E1000_MANC_ASF_EN        0x00000002 /* ASF Enabled - RO */
#define E1000_MANC_ARP_EN        0x00002000 /* Enable ARP Request Filtering */
#define E1000_MANC_RCV_TCO_EN    0x00020000 /* Receive TCO Packets Enabled */
#define E1000_MANC_BLK_PHY_RST_ON_IDE   0x00040000 /* Block phy resets */
/* Enable MAC address filtering */
#define E1000_MANC_EN_MAC_ADDR_FILTER   0x00100000
/* Enable MNG packets to host memory */
#define E1000_MANC_EN_MNG2HOST   0x00200000

#define E1000_MANC2H_PORT_623    0x00000020 /* Port 0x26f */
#define E1000_MANC2H_PORT_664    0x00000040 /* Port 0x298 */
#define E1000_MDEF_PORT_623      0x00000800 /* Port 0x26f */
#define E1000_MDEF_PORT_664      0x00000400 /* Port 0x298 */

/* Receive Control */
#define E1000_RCTL_EN             0x00000002    /* enable */
#define E1000_RCTL_SBP            0x00000004    /* store bad packet */
#define E1000_RCTL_UPE            0x00000008    /* unicast promiscuous enable */
#define E1000_RCTL_MPE            0x00000010    /* multicast promiscuous enab */
#define E1000_RCTL_LPE            0x00000020    /* long packet enable */
#define E1000_RCTL_LBM_NO         0x00000000    /* no loopback mode */
#define E1000_RCTL_LBM_MAC        0x00000040    /* MAC loopback mode */
#define E1000_RCTL_LBM_TCVR       0x000000C0    /* tcvr loopback mode */
#define E1000_RCTL_DTYP_PS        0x00000400    /* Packet Split descriptor */
#define E1000_RCTL_RDMTS_HALF     0x00000000    /* Rx desc min threshold size */
#define E1000_RCTL_MO_SHIFT       12            /* multicast offset shift */
#define E1000_RCTL_MO_3           0x00003000    /* multicast offset 15:4 */
#define E1000_RCTL_BAM            0x00008000    /* broadcast enable */
/* these buffer sizes are valid if E1000_RCTL_BSEX is 0 */
#define E1000_RCTL_SZ_2048        0x00000000    /* Rx buffer size 2048 */
#define E1000_RCTL_SZ_1024        0x00010000    /* Rx buffer size 1024 */
#define E1000_RCTL_SZ_512         0x00020000    /* Rx buffer size 512 */
#define E1000_RCTL_SZ_256         0x00030000    /* Rx buffer size 256 */
/* these buffer sizes are valid if E1000_RCTL_BSEX is 1 */
#define E1000_RCTL_SZ_16384       0x00010000    /* Rx buffer size 16384 */
#define E1000_RCTL_SZ_8192        0x00020000    /* Rx buffer size 8192 */
#define E1000_RCTL_SZ_4096        0x00030000    /* Rx buffer size 4096 */
#define E1000_RCTL_VFE            0x00040000    /* vlan filter enable */
#define E1000_RCTL_CFIEN          0x00080000    /* canonical form enable */
#define E1000_RCTL_CFI            0x00100000    /* canonical form indicator */
#define E1000_RCTL_PMCF           0x00800000    /* pass MAC control frames */
#define E1000_RCTL_BSEX           0x02000000    /* Buffer size extension */
#define E1000_RCTL_SECRC          0x04000000    /* Strip Ethernet CRC */

/*
 * Use byte values for the following shift parameters
 * Usage:
 *     psrctl |= (((ROUNDUP(value0, 128) >> E1000_PSRCTL_BSIZE0_SHIFT) &
 *                  E1000_PSRCTL_BSIZE0_MASK) |
 *                ((ROUNDUP(value1, 1024) >> E1000_PSRCTL_BSIZE1_SHIFT) &
 *                  E1000_PSRCTL_BSIZE1_MASK) |
 *                ((ROUNDUP(value2, 1024) << E1000_PSRCTL_BSIZE2_SHIFT) &
 *                  E1000_PSRCTL_BSIZE2_MASK) |
 *                ((ROUNDUP(value3, 1024) << E1000_PSRCTL_BSIZE3_SHIFT) |;
 *                  E1000_PSRCTL_BSIZE3_MASK))
 * where value0 = [128..16256],  default=256
 *       value1 = [1024..64512], default=4096
 *       value2 = [0..64512],    default=4096
 *       value3 = [0..64512],    default=0
 */

#define E1000_PSRCTL_BSIZE0_MASK   0x0000007F
#define E1000_PSRCTL_BSIZE1_MASK   0x00003F00
#define E1000_PSRCTL_BSIZE2_MASK   0x003F0000
#define E1000_PSRCTL_BSIZE3_MASK   0x3F000000

#define E1000_PSRCTL_BSIZE0_SHIFT  7            /* Shift _right_ 7 */
#define E1000_PSRCTL_BSIZE1_SHIFT  2            /* Shift _right_ 2 */
#define E1000_PSRCTL_BSIZE2_SHIFT  6            /* Shift _left_ 6 */
#define E1000_PSRCTL_BSIZE3_SHIFT 14            /* Shift _left_ 14 */

/* SWFW_SYNC Definitions */
#define E1000_SWFW_EEP_SM   0x1
#define E1000_SWFW_PHY0_SM  0x2
#define E1000_SWFW_PHY1_SM  0x4
#define E1000_SWFW_CSR_SM   0x8

/* Device Control */
#define E1000_CTRL_FD       0x00000001  /* Full duplex.0=half; 1=full */
#define E1000_CTRL_GIO_MASTER_DISABLE 0x00000004 /*Blocks new Master requests */
#define E1000_CTRL_LRST     0x00000008  /* Link reset. 0=normal,1=reset */
#define E1000_CTRL_ASDE     0x00000020  /* Auto-speed detect enable */
#define E1000_CTRL_SLU      0x00000040  /* Set link up (Force Link) */
#define E1000_CTRL_ILOS     0x00000080  /* Invert Loss-Of Signal */
#define E1000_CTRL_SPD_SEL  0x00000300  /* Speed Select Mask */
#define E1000_CTRL_SPD_10   0x00000000  /* Force 10Mb */
#define E1000_CTRL_SPD_100  0x00000100  /* Force 100Mb */
#define E1000_CTRL_SPD_1000 0x00000200  /* Force 1Gb */
#define E1000_CTRL_FRCSPD   0x00000800  /* Force Speed */
#define E1000_CTRL_FRCDPX   0x00001000  /* Force Duplex */
#define E1000_CTRL_LANPHYPC_OVERRIDE 0x00010000 /* SW control of LANPHYPC */
#define E1000_CTRL_LANPHYPC_VALUE    0x00020000 /* SW value of LANPHYPC */
#define E1000_CTRL_SWDPIN0  0x00040000  /* SWDPIN 0 value */
#define E1000_CTRL_SWDPIN1  0x00080000  /* SWDPIN 1 value */
#define E1000_CTRL_SWDPIO0  0x00400000  /* SWDPIN 0 Input or output */
#define E1000_CTRL_RST      0x04000000  /* Global reset */
#define E1000_CTRL_RFCE     0x08000000  /* Receive Flow Control enable */
#define E1000_CTRL_TFCE     0x10000000  /* Transmit flow control enable */
#define E1000_CTRL_VME      0x40000000  /* IEEE VLAN mode enable */
#define E1000_CTRL_PHY_RST  0x80000000  /* PHY Reset */

/*
 * Bit definitions for the Management Data IO (MDIO) and Management Data
 * Clock (MDC) pins in the Device Control Register.
 */

/* Device Status */
#define E1000_STATUS_FD         0x00000001      /* Full duplex.0=half,1=full */
#define E1000_STATUS_LU         0x00000002      /* Link up.0=no,1=link */
#define E1000_STATUS_FUNC_MASK  0x0000000C      /* PCI Function Mask */
#define E1000_STATUS_FUNC_SHIFT 2
#define E1000_STATUS_FUNC_1     0x00000004      /* Function 1 */
#define E1000_STATUS_TXOFF      0x00000010      /* transmission paused */
#define E1000_STATUS_SPEED_10   0x00000000      /* Speed 10Mb/s */
#define E1000_STATUS_SPEED_100  0x00000040      /* Speed 100Mb/s */
#define E1000_STATUS_SPEED_1000 0x00000080      /* Speed 1000Mb/s */
#define E1000_STATUS_LAN_INIT_DONE 0x00000200   /* Lan Init Completion by NVM */
#define E1000_STATUS_PHYRA      0x00000400      /* PHY Reset Asserted */
#define E1000_STATUS_GIO_MASTER_ENABLE 0x00080000 /* Status of Master requests. */

/* Constants used to interpret the masked PCI-X bus speed. */

#define HALF_DUPLEX 1
#define FULL_DUPLEX 2


#define ADVERTISE_10_HALF                 0x0001
#define ADVERTISE_10_FULL                 0x0002
#define ADVERTISE_100_HALF                0x0004
#define ADVERTISE_100_FULL                0x0008
#define ADVERTISE_1000_HALF               0x0010 /* Not used, just FYI */
#define ADVERTISE_1000_FULL               0x0020

/* 1000/H is not supported, nor spec-compliant. */
#define E1000_ALL_SPEED_DUPLEX ( ADVERTISE_10_HALF |   ADVERTISE_10_FULL | \
				ADVERTISE_100_HALF |  ADVERTISE_100_FULL | \
						     ADVERTISE_1000_FULL)
#define E1000_ALL_NOT_GIG      ( ADVERTISE_10_HALF |   ADVERTISE_10_FULL | \
				ADVERTISE_100_HALF |  ADVERTISE_100_FULL)
#define E1000_ALL_100_SPEED    (ADVERTISE_100_HALF |  ADVERTISE_100_FULL)
#define E1000_ALL_10_SPEED      (ADVERTISE_10_HALF |   ADVERTISE_10_FULL)
#define E1000_ALL_HALF_DUPLEX   (ADVERTISE_10_HALF |  ADVERTISE_100_HALF)

#define AUTONEG_ADVERTISE_SPEED_DEFAULT   E1000_ALL_SPEED_DUPLEX

/* LED Control */
#define E1000_PHY_LED0_MODE_MASK          0x00000007
#define E1000_PHY_LED0_IVRT               0x00000008
#define E1000_PHY_LED0_MASK               0x0000001F

#define E1000_LEDCTL_LED0_MODE_MASK       0x0000000F
#define E1000_LEDCTL_LED0_MODE_SHIFT      0
#define E1000_LEDCTL_LED0_IVRT            0x00000040
#define E1000_LEDCTL_LED0_BLINK           0x00000080

#define E1000_LEDCTL_MODE_LINK_UP       0x2
#define E1000_LEDCTL_MODE_LED_ON        0xE
#define E1000_LEDCTL_MODE_LED_OFF       0xF

/* Transmit Descriptor bit definitions */
#define E1000_TXD_DTYP_D     0x00100000 /* Data Descriptor */
#define E1000_TXD_POPTS_IXSM 0x01       /* Insert IP checksum */
#define E1000_TXD_POPTS_TXSM 0x02       /* Insert TCP/UDP checksum */
#define E1000_TXD_CMD_EOP    0x01000000 /* End of Packet */
#define E1000_TXD_CMD_IFCS   0x02000000 /* Insert FCS (Ethernet CRC) */
#define E1000_TXD_CMD_IC     0x04000000 /* Insert Checksum */
#define E1000_TXD_CMD_RS     0x08000000 /* Report Status */
#define E1000_TXD_CMD_RPS    0x10000000 /* Report Packet Sent */
#define E1000_TXD_CMD_DEXT   0x20000000 /* Descriptor extension (0 = legacy) */
#define E1000_TXD_CMD_VLE    0x40000000 /* Add VLAN tag */
#define E1000_TXD_CMD_IDE    0x80000000 /* Enable Tidv register */
#define E1000_TXD_STAT_DD    0x00000001 /* Descriptor Done */
#define E1000_TXD_STAT_EC    0x00000002 /* Excess Collisions */
#define E1000_TXD_STAT_LC    0x00000004 /* Late Collisions */
#define E1000_TXD_STAT_TU    0x00000008 /* Transmit underrun */
#define E1000_TXD_CMD_TCP    0x01000000 /* TCP packet */
#define E1000_TXD_CMD_IP     0x02000000 /* IP packet */
#define E1000_TXD_CMD_TSE    0x04000000 /* TCP Seg enable */
#define E1000_TXD_STAT_TC    0x00000004 /* Tx Underrun */

/* Transmit Control */
#define E1000_TCTL_EN     0x00000002    /* enable Tx */
#define E1000_TCTL_PSP    0x00000008    /* pad short packets */
#define E1000_TCTL_CT     0x00000ff0    /* collision threshold */
#define E1000_TCTL_COLD   0x003ff000    /* collision distance */
#define E1000_TCTL_RTLC   0x01000000    /* Re-transmit on late collision */
#define E1000_TCTL_MULR   0x10000000    /* Multiple request support */

/* Transmit Arbitration Count */

/* SerDes Control */
#define E1000_SCTL_DISABLE_SERDES_LOOPBACK 0x0400

/* Receive Checksum Control */
#define E1000_RXCSUM_TUOFL     0x00000200   /* TCP / UDP checksum offload */
#define E1000_RXCSUM_IPPCSE    0x00001000   /* IP payload checksum enable */

/* Header split receive */
#define E1000_RFCTL_NFSW_DIS            0x00000040
#define E1000_RFCTL_NFSR_DIS            0x00000080
#define E1000_RFCTL_ACK_DIS             0x00001000
#define E1000_RFCTL_EXTEN               0x00008000
#define E1000_RFCTL_IPV6_EX_DIS         0x00010000
#define E1000_RFCTL_NEW_IPV6_EXT_DIS    0x00020000

/* Collision related configuration parameters */
#define E1000_COLLISION_THRESHOLD       15
#define E1000_CT_SHIFT                  4
#define E1000_COLLISION_DISTANCE        63
#define E1000_COLD_SHIFT                12

/* Default values for the transmit IPG register */
#define DEFAULT_82543_TIPG_IPGT_COPPER 8

#define E1000_TIPG_IPGT_MASK  0x000003FF

#define DEFAULT_82543_TIPG_IPGR1 8
#define E1000_TIPG_IPGR1_SHIFT  10

#define DEFAULT_82543_TIPG_IPGR2 6
#define DEFAULT_80003ES2LAN_TIPG_IPGR2 7
#define E1000_TIPG_IPGR2_SHIFT  20

#define MAX_JUMBO_FRAME_SIZE    0x3F00

/* Extended Configuration Control and Size */
#define E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP      0x00000020
#define E1000_EXTCNF_CTRL_LCD_WRITE_ENABLE       0x00000001
#define E1000_EXTCNF_CTRL_OEM_WRITE_ENABLE       0x00000008
#define E1000_EXTCNF_CTRL_SWFLAG                 0x00000020
#define E1000_EXTCNF_CTRL_GATE_PHY_CFG           0x00000080
#define E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_MASK   0x00FF0000
#define E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_SHIFT          16
#define E1000_EXTCNF_CTRL_EXT_CNF_POINTER_MASK   0x0FFF0000
#define E1000_EXTCNF_CTRL_EXT_CNF_POINTER_SHIFT          16

#define E1000_PHY_CTRL_D0A_LPLU           0x00000002
#define E1000_PHY_CTRL_NOND0A_LPLU        0x00000004
#define E1000_PHY_CTRL_NOND0A_GBE_DISABLE 0x00000008
#define E1000_PHY_CTRL_GBE_DISABLE        0x00000040

#define E1000_KABGTXD_BGSQLBIAS           0x00050000

/* PBA constants */
#define E1000_PBA_8K  0x0008    /* 8KB */
#define E1000_PBA_16K 0x0010    /* 16KB */

#define E1000_PBS_16K E1000_PBA_16K

#define IFS_MAX       80
#define IFS_MIN       40
#define IFS_RATIO     4
#define IFS_STEP      10
#define MIN_NUM_XMITS 1000

/* SW Semaphore Register */
#define E1000_SWSM_SMBI         0x00000001 /* Driver Semaphore bit */
#define E1000_SWSM_SWESMBI      0x00000002 /* FW Semaphore bit */
#define E1000_SWSM_DRV_LOAD     0x00000008 /* Driver Loaded Bit */

#define E1000_SWSM2_LOCK        0x00000002 /* Secondary driver semaphore bit */

/* Interrupt Cause Read */
#define E1000_ICR_TXDW          0x00000001 /* Transmit desc written back */
#define E1000_ICR_LSC           0x00000004 /* Link Status Change */
#define E1000_ICR_RXSEQ         0x00000008 /* Rx sequence error */
#define E1000_ICR_RXDMT0        0x00000010 /* Rx desc min. threshold (0) */
#define E1000_ICR_RXT0          0x00000080 /* Rx timer intr (ring 0) */
#define E1000_ICR_INT_ASSERTED  0x80000000 /* If this bit asserted, the driver should claim the interrupt */
#define E1000_ICR_RXQ0          0x00100000 /* Rx Queue 0 Interrupt */
#define E1000_ICR_RXQ1          0x00200000 /* Rx Queue 1 Interrupt */
#define E1000_ICR_TXQ0          0x00400000 /* Tx Queue 0 Interrupt */
#define E1000_ICR_TXQ1          0x00800000 /* Tx Queue 1 Interrupt */
#define E1000_ICR_OTHER         0x01000000 /* Other Interrupts */

/* PBA ECC Register */
#define E1000_PBA_ECC_COUNTER_MASK  0xFFF00000 /* ECC counter mask */
#define E1000_PBA_ECC_COUNTER_SHIFT 20         /* ECC counter shift value */
#define E1000_PBA_ECC_CORR_EN       0x00000001 /* ECC correction enable */
#define E1000_PBA_ECC_STAT_CLR      0x00000002 /* Clear ECC error counter */
#define E1000_PBA_ECC_INT_EN        0x00000004 /* Enable ICR bit 5 for ECC */

/*
 * This defines the bits that are set in the Interrupt Mask
 * Set/Read Register.  Each bit is documented below:
 *   o RXT0   = Receiver Timer Interrupt (ring 0)
 *   o TXDW   = Transmit Descriptor Written Back
 *   o RXDMT0 = Receive Descriptor Minimum Threshold hit (ring 0)
 *   o RXSEQ  = Receive Sequence Error
 *   o LSC    = Link Status Change
 */
#define IMS_ENABLE_MASK ( \
    E1000_IMS_RXT0   |    \
    E1000_IMS_TXDW   |    \
    E1000_IMS_RXDMT0 |    \
    E1000_IMS_RXSEQ  |    \
    E1000_IMS_LSC)

/* Interrupt Mask Set */
#define E1000_IMS_TXDW      E1000_ICR_TXDW      /* Transmit desc written back */
#define E1000_IMS_LSC       E1000_ICR_LSC       /* Link Status Change */
#define E1000_IMS_RXSEQ     E1000_ICR_RXSEQ     /* Rx sequence error */
#define E1000_IMS_RXDMT0    E1000_ICR_RXDMT0    /* Rx desc min. threshold */
#define E1000_IMS_RXT0      E1000_ICR_RXT0      /* Rx timer intr */
#define E1000_IMS_RXQ0      E1000_ICR_RXQ0      /* Rx Queue 0 Interrupt */
#define E1000_IMS_RXQ1      E1000_ICR_RXQ1      /* Rx Queue 1 Interrupt */
#define E1000_IMS_TXQ0      E1000_ICR_TXQ0      /* Tx Queue 0 Interrupt */
#define E1000_IMS_TXQ1      E1000_ICR_TXQ1      /* Tx Queue 1 Interrupt */
#define E1000_IMS_OTHER     E1000_ICR_OTHER     /* Other Interrupts */

/* Interrupt Cause Set */
#define E1000_ICS_LSC       E1000_ICR_LSC       /* Link Status Change */
#define E1000_ICS_RXSEQ     E1000_ICR_RXSEQ     /* Rx sequence error */
#define E1000_ICS_RXDMT0    E1000_ICR_RXDMT0    /* Rx desc min. threshold */

/* Transmit Descriptor Control */
#define E1000_TXDCTL_PTHRESH 0x0000003F /* TXDCTL Prefetch Threshold */
#define E1000_TXDCTL_HTHRESH 0x00003F00 /* TXDCTL Host Threshold */
#define E1000_TXDCTL_WTHRESH 0x003F0000 /* TXDCTL Writeback Threshold */
#define E1000_TXDCTL_GRAN    0x01000000 /* TXDCTL Granularity */
#define E1000_TXDCTL_FULL_TX_DESC_WB 0x01010000 /* GRAN=1, WTHRESH=1 */
#define E1000_TXDCTL_MAX_TX_DESC_PREFETCH 0x0100001F /* GRAN=1, PTHRESH=31 */
/* Enable the counting of desc. still to be processed. */
#define E1000_TXDCTL_COUNT_DESC 0x00400000

/* Flow Control Constants */
#define FLOW_CONTROL_ADDRESS_LOW  0x00C28001
#define FLOW_CONTROL_ADDRESS_HIGH 0x00000100
#define FLOW_CONTROL_TYPE         0x8808

/* 802.1q VLAN Packet Size */
#define E1000_VLAN_FILTER_TBL_SIZE 128  /* VLAN Filter Table (4096 bits) */

/* Receive Address */
/*
 * Number of high/low register pairs in the RAR. The RAR (Receive Address
 * Registers) holds the directed and multicast addresses that we monitor.
 * Technically, we have 16 spots.  However, we reserve one of these spots
 * (RAR[15]) for our directed address used by controllers with
 * manageability enabled, allowing us room for 15 multicast addresses.
 */
#define E1000_RAR_ENTRIES     15
#define E1000_RAH_AV  0x80000000        /* Receive descriptor valid */
#define E1000_RAL_MAC_ADDR_LEN 4
#define E1000_RAH_MAC_ADDR_LEN 2

/* Error Codes */
#define E1000_ERR_NVM      1
#define E1000_ERR_PHY      2
#define E1000_ERR_CONFIG   3
#define E1000_ERR_PARAM    4
#define E1000_ERR_MAC_INIT 5
#define E1000_ERR_PHY_TYPE 6
#define E1000_ERR_RESET   9
#define E1000_ERR_MASTER_REQUESTS_PENDING 10
#define E1000_ERR_HOST_INTERFACE_COMMAND 11
#define E1000_BLK_PHY_RESET   12
#define E1000_ERR_SWFW_SYNC 13
#define E1000_NOT_IMPLEMENTED 14

/* Loop limit on how long we wait for auto-negotiation to complete */
#define FIBER_LINK_UP_LIMIT               50
#define COPPER_LINK_UP_LIMIT              10
#define PHY_AUTO_NEG_LIMIT                45
#define PHY_FORCE_LIMIT                   20
/* Number of 100 microseconds we wait for PCI Express master disable */
#define MASTER_DISABLE_TIMEOUT      800
/* Number of milliseconds we wait for PHY configuration done after MAC reset */
#define PHY_CFG_TIMEOUT             100
/* Number of 2 milliseconds we wait for acquiring MDIO ownership. */
#define MDIO_OWNERSHIP_TIMEOUT      10
/* Number of milliseconds for NVM auto read done after MAC reset. */
#define AUTO_READ_DONE_TIMEOUT      10

/* Flow Control */
#define E1000_FCRTH_RTH  0x0000FFF8     /* Mask Bits[15:3] for RTH */
#define E1000_FCRTL_RTL  0x0000FFF8     /* Mask Bits[15:3] for RTL */
#define E1000_FCRTL_XONE 0x80000000     /* Enable XON frame transmission */

/* Transmit Configuration Word */
#define E1000_TXCW_FD         0x00000020        /* TXCW full duplex */
#define E1000_TXCW_PAUSE      0x00000080        /* TXCW sym pause request */
#define E1000_TXCW_ASM_DIR    0x00000100        /* TXCW astm pause direction */
#define E1000_TXCW_PAUSE_MASK 0x00000180        /* TXCW pause request mask */
#define E1000_TXCW_ANE        0x80000000        /* Auto-neg enable */

/* Receive Configuration Word */
#define E1000_RXCW_IV         0x08000000        /* Receive config invalid */
#define E1000_RXCW_C          0x20000000        /* Receive config */
#define E1000_RXCW_SYNCH      0x40000000        /* Receive config synch */

/* PCI Express Control */
#define E1000_GCR_RXD_NO_SNOOP          0x00000001
#define E1000_GCR_RXDSCW_NO_SNOOP       0x00000002
#define E1000_GCR_RXDSCR_NO_SNOOP       0x00000004
#define E1000_GCR_TXD_NO_SNOOP          0x00000008
#define E1000_GCR_TXDSCW_NO_SNOOP       0x00000010
#define E1000_GCR_TXDSCR_NO_SNOOP       0x00000020

#define PCIE_NO_SNOOP_ALL (E1000_GCR_RXD_NO_SNOOP         | \
			   E1000_GCR_RXDSCW_NO_SNOOP      | \
			   E1000_GCR_RXDSCR_NO_SNOOP      | \
			   E1000_GCR_TXD_NO_SNOOP         | \
			   E1000_GCR_TXDSCW_NO_SNOOP      | \
			   E1000_GCR_TXDSCR_NO_SNOOP)

/* PHY Control Register */
#define MII_CR_FULL_DUPLEX      0x0100  /* FDX =1, half duplex =0 */
#define MII_CR_RESTART_AUTO_NEG 0x0200  /* Restart auto negotiation */
#define MII_CR_POWER_DOWN       0x0800  /* Power down */
#define MII_CR_AUTO_NEG_EN      0x1000  /* Auto Neg Enable */
#define MII_CR_LOOPBACK         0x4000  /* 0 = normal, 1 = loopback */
#define MII_CR_RESET            0x8000  /* 0 = normal, 1 = PHY reset */
#define MII_CR_SPEED_1000       0x0040
#define MII_CR_SPEED_100        0x2000
#define MII_CR_SPEED_10         0x0000

/* PHY Status Register */
#define MII_SR_LINK_STATUS       0x0004 /* Link Status 1 = link */
#define MII_SR_AUTONEG_COMPLETE  0x0020 /* Auto Neg Complete */

/* Autoneg Advertisement Register */
#define NWAY_AR_10T_HD_CAPS      0x0020   /* 10T   Half Duplex Capable */
#define NWAY_AR_10T_FD_CAPS      0x0040   /* 10T   Full Duplex Capable */
#define NWAY_AR_100TX_HD_CAPS    0x0080   /* 100TX Half Duplex Capable */
#define NWAY_AR_100TX_FD_CAPS    0x0100   /* 100TX Full Duplex Capable */
#define NWAY_AR_PAUSE            0x0400   /* Pause operation desired */
#define NWAY_AR_ASM_DIR          0x0800   /* Asymmetric Pause Direction bit */

/* Link Partner Ability Register (Base Page) */
#define NWAY_LPAR_PAUSE          0x0400 /* LP Pause operation desired */
#define NWAY_LPAR_ASM_DIR        0x0800 /* LP Asymmetric Pause Direction bit */

/* Autoneg Expansion Register */
#define NWAY_ER_LP_NWAY_CAPS     0x0001 /* LP has Auto Neg Capability */

/* 1000BASE-T Control Register */
#define CR_1000T_HD_CAPS         0x0100 /* Advertise 1000T HD capability */
#define CR_1000T_FD_CAPS         0x0200 /* Advertise 1000T FD capability  */
					/* 0=DTE device */
#define CR_1000T_MS_VALUE        0x0800 /* 1=Configure PHY as Master */
					/* 0=Configure PHY as Slave */
#define CR_1000T_MS_ENABLE       0x1000 /* 1=Master/Slave manual config value */
					/* 0=Automatic Master/Slave config */

/* 1000BASE-T Status Register */
#define SR_1000T_REMOTE_RX_STATUS 0x1000 /* Remote receiver OK */
#define SR_1000T_LOCAL_RX_STATUS  0x2000 /* Local receiver OK */


/* PHY 1000 MII Register/Bit Definitions */
/* PHY Registers defined by IEEE */
#define PHY_CONTROL      0x00 /* Control Register */
#define PHY_STATUS       0x01 /* Status Register */
#define PHY_ID1          0x02 /* Phy Id Reg (word 1) */
#define PHY_ID2          0x03 /* Phy Id Reg (word 2) */
#define PHY_AUTONEG_ADV  0x04 /* Autoneg Advertisement */
#define PHY_LP_ABILITY   0x05 /* Link Partner Ability (Base Page) */
#define PHY_AUTONEG_EXP  0x06 /* Autoneg Expansion Reg */
#define PHY_1000T_CTRL   0x09 /* 1000Base-T Control Reg */
#define PHY_1000T_STATUS 0x0A /* 1000Base-T Status Reg */
#define PHY_EXT_STATUS   0x0F /* Extended Status Reg */

#define PHY_CONTROL_LB   0x4000 /* PHY Loopback bit */

/* NVM Control */
#define E1000_EECD_SK        0x00000001 /* NVM Clock */
#define E1000_EECD_CS        0x00000002 /* NVM Chip Select */
#define E1000_EECD_DI        0x00000004 /* NVM Data In */
#define E1000_EECD_DO        0x00000008 /* NVM Data Out */
#define E1000_EECD_REQ       0x00000040 /* NVM Access Request */
#define E1000_EECD_GNT       0x00000080 /* NVM Access Grant */
#define E1000_EECD_PRES      0x00000100 /* NVM Present */
#define E1000_EECD_SIZE      0x00000200 /* NVM Size (0=64 word 1=256 word) */
/* NVM Addressing bits based on type (0-small, 1-large) */
#define E1000_EECD_ADDR_BITS 0x00000400
#define E1000_NVM_GRANT_ATTEMPTS   1000 /* NVM # attempts to gain grant */
#define E1000_EECD_AUTO_RD          0x00000200  /* NVM Auto Read done */
#define E1000_EECD_SIZE_EX_MASK     0x00007800  /* NVM Size */
#define E1000_EECD_SIZE_EX_SHIFT     11
#define E1000_EECD_FLUPD     0x00080000 /* Update FLASH */
#define E1000_EECD_AUPDEN    0x00100000 /* Enable Autonomous FLASH update */
#define E1000_EECD_SEC1VAL   0x00400000 /* Sector One Valid */
#define E1000_EECD_SEC1VAL_VALID_MASK (E1000_EECD_AUTO_RD | E1000_EECD_PRES)

#define E1000_NVM_RW_REG_DATA   16   /* Offset to data in NVM read/write registers */
#define E1000_NVM_RW_REG_DONE   2    /* Offset to READ/WRITE done bit */
#define E1000_NVM_RW_REG_START  1    /* Start operation */
#define E1000_NVM_RW_ADDR_SHIFT 2    /* Shift to the address bits */
#define E1000_NVM_POLL_WRITE    1    /* Flag for polling for write complete */
#define E1000_NVM_POLL_READ     0    /* Flag for polling for read complete */
#define E1000_FLASH_UPDATES  2000

/* NVM Word Offsets */
#define NVM_COMPAT                 0x0003
#define NVM_ID_LED_SETTINGS        0x0004
#define NVM_INIT_CONTROL2_REG      0x000F
#define NVM_INIT_CONTROL3_PORT_B   0x0014
#define NVM_INIT_3GIO_3            0x001A
#define NVM_INIT_CONTROL3_PORT_A   0x0024
#define NVM_CFG                    0x0012
#define NVM_ALT_MAC_ADDR_PTR       0x0037
#define NVM_CHECKSUM_REG           0x003F

#define E1000_NVM_INIT_CTRL2_MNGM 0x6000 /* Manageability Operation Mode mask */

#define E1000_NVM_CFG_DONE_PORT_0  0x40000 /* MNG config cycle done */
#define E1000_NVM_CFG_DONE_PORT_1  0x80000 /* ...for second port */

/* Mask bits for fields in Word 0x0f of the NVM */
#define NVM_WORD0F_PAUSE_MASK       0x3000
#define NVM_WORD0F_PAUSE            0x1000
#define NVM_WORD0F_ASM_DIR          0x2000

/* Mask bits for fields in Word 0x1a of the NVM */
#define NVM_WORD1A_ASPM_MASK  0x000C

/* Mask bits for fields in Word 0x03 of the EEPROM */
#define NVM_COMPAT_LOM    0x0800

/* For checksumming, the sum of all words in the NVM should equal 0xBABA. */
#define NVM_SUM                    0xBABA

/* PBA (printed board assembly) number words */
#define NVM_PBA_OFFSET_0           8
#define NVM_PBA_OFFSET_1           9

#define NVM_WORD_SIZE_BASE_SHIFT   6

/* NVM Commands - SPI */
#define NVM_MAX_RETRY_SPI          5000 /* Max wait of 5ms, for RDY signal */
#define NVM_READ_OPCODE_SPI        0x03 /* NVM read opcode */
#define NVM_WRITE_OPCODE_SPI       0x02 /* NVM write opcode */
#define NVM_A8_OPCODE_SPI          0x08 /* opcode bit-3 = address bit-8 */
#define NVM_WREN_OPCODE_SPI        0x06 /* NVM set Write Enable latch */
#define NVM_RDSR_OPCODE_SPI        0x05 /* NVM read Status register */

/* SPI NVM Status Register */
#define NVM_STATUS_RDY_SPI         0x01

/* Word definitions for ID LED Settings */
#define ID_LED_RESERVED_0000 0x0000
#define ID_LED_RESERVED_FFFF 0xFFFF
#define ID_LED_DEFAULT       ((ID_LED_OFF1_ON2  << 12) | \
			      (ID_LED_OFF1_OFF2 <<  8) | \
			      (ID_LED_DEF1_DEF2 <<  4) | \
			      (ID_LED_DEF1_DEF2))
#define ID_LED_DEF1_DEF2     0x1
#define ID_LED_DEF1_ON2      0x2
#define ID_LED_DEF1_OFF2     0x3
#define ID_LED_ON1_DEF2      0x4
#define ID_LED_ON1_ON2       0x5
#define ID_LED_ON1_OFF2      0x6
#define ID_LED_OFF1_DEF2     0x7
#define ID_LED_OFF1_ON2      0x8
#define ID_LED_OFF1_OFF2     0x9

#define IGP_ACTIVITY_LED_MASK   0xFFFFF0FF
#define IGP_ACTIVITY_LED_ENABLE 0x0300
#define IGP_LED3_MODE           0x07000000

/* PCI/PCI-X/PCI-EX Config space */
#define PCI_HEADER_TYPE_REGISTER     0x0E
#define PCIE_LINK_STATUS             0x12

#define PCI_HEADER_TYPE_MULTIFUNC    0x80
#define PCIE_LINK_WIDTH_MASK         0x3F0
#define PCIE_LINK_WIDTH_SHIFT        4

#define PHY_REVISION_MASK      0xFFFFFFF0
#define MAX_PHY_REG_ADDRESS    0x1F  /* 5 bit address bus (0-0x1F) */
#define MAX_PHY_MULTI_PAGE_REG 0xF

/* Bit definitions for valid PHY IDs. */
/*
 * I = Integrated
 * E = External
 */
#define M88E1000_E_PHY_ID    0x01410C50
#define M88E1000_I_PHY_ID    0x01410C30
#define M88E1011_I_PHY_ID    0x01410C20
#define IGP01E1000_I_PHY_ID  0x02A80380
#define M88E1111_I_PHY_ID    0x01410CC0
#define GG82563_E_PHY_ID     0x01410CA0
#define IGP03E1000_E_PHY_ID  0x02A80390
#define IFE_E_PHY_ID         0x02A80330
#define IFE_PLUS_E_PHY_ID    0x02A80320
#define IFE_C_E_PHY_ID       0x02A80310
#define BME1000_E_PHY_ID     0x01410CB0
#define BME1000_E_PHY_ID_R2  0x01410CB1
#define I82577_E_PHY_ID      0x01540050
#define I82578_E_PHY_ID      0x004DD040
#define I82579_E_PHY_ID      0x01540090

/* M88E1000 Specific Registers */
#define M88E1000_PHY_SPEC_CTRL     0x10  /* PHY Specific Control Register */
#define M88E1000_PHY_SPEC_STATUS   0x11  /* PHY Specific Status Register */
#define M88E1000_EXT_PHY_SPEC_CTRL 0x14  /* Extended PHY Specific Control */

#define M88E1000_PHY_PAGE_SELECT   0x1D  /* Reg 29 for page number setting */
#define M88E1000_PHY_GEN_CONTROL   0x1E  /* Its meaning depends on reg 29 */

/* M88E1000 PHY Specific Control Register */
#define M88E1000_PSCR_POLARITY_REVERSAL 0x0002 /* 1=Polarity Reversal enabled */
#define M88E1000_PSCR_MDI_MANUAL_MODE  0x0000  /* MDI Crossover Mode bits 6:5 */
					       /* Manual MDI configuration */
#define M88E1000_PSCR_MDIX_MANUAL_MODE 0x0020  /* Manual MDIX configuration */
/* 1000BASE-T: Auto crossover, 100BASE-TX/10BASE-T: MDI Mode */
#define M88E1000_PSCR_AUTO_X_1000T     0x0040
/* Auto crossover enabled all speeds */
#define M88E1000_PSCR_AUTO_X_MODE      0x0060
/*
 * 1=Enable Extended 10BASE-T distance (Lower 10BASE-T Rx Threshold)
 * 0=Normal 10BASE-T Rx Threshold
 */
#define M88E1000_PSCR_ASSERT_CRS_ON_TX 0x0800 /* 1=Assert CRS on Transmit */

/* M88E1000 PHY Specific Status Register */
#define M88E1000_PSSR_REV_POLARITY       0x0002 /* 1=Polarity reversed */
#define M88E1000_PSSR_DOWNSHIFT          0x0020 /* 1=Downshifted */
#define M88E1000_PSSR_MDIX               0x0040 /* 1=MDIX; 0=MDI */
/* 0=<50M; 1=50-80M; 2=80-110M; 3=110-140M; 4=>140M */
#define M88E1000_PSSR_CABLE_LENGTH       0x0380
#define M88E1000_PSSR_SPEED              0xC000 /* Speed, bits 14:15 */
#define M88E1000_PSSR_1000MBS            0x8000 /* 10=1000Mbs */

#define M88E1000_PSSR_CABLE_LENGTH_SHIFT 7

/*
 * Number of times we will attempt to autonegotiate before downshifting if we
 * are the master
 */
#define M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK 0x0C00
#define M88E1000_EPSCR_MASTER_DOWNSHIFT_1X   0x0000
/*
 * Number of times we will attempt to autonegotiate before downshifting if we
 * are the slave
 */
#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK  0x0300
#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X    0x0100
#define M88E1000_EPSCR_TX_CLK_25      0x0070 /* 25  MHz TX_CLK */

/* M88EC018 Rev 2 specific DownShift settings */
#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_MASK  0x0E00
#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_5X    0x0800

#define I82578_EPSCR_DOWNSHIFT_ENABLE          0x0020
#define I82578_EPSCR_DOWNSHIFT_COUNTER_MASK    0x001C

/* BME1000 PHY Specific Control Register */
#define BME1000_PSCR_ENABLE_DOWNSHIFT   0x0800 /* 1 = enable downshift */


#define PHY_PAGE_SHIFT 5
#define PHY_REG(page, reg) (((page) << PHY_PAGE_SHIFT) | \
                           ((reg) & MAX_PHY_REG_ADDRESS))

/*
 * Bits...
 * 15-5: page
 * 4-0: register offset
 */
#define GG82563_PAGE_SHIFT        5
#define GG82563_REG(page, reg)    \
	(((page) << GG82563_PAGE_SHIFT) | ((reg) & MAX_PHY_REG_ADDRESS))
#define GG82563_MIN_ALT_REG       30

/* GG82563 Specific Registers */
#define GG82563_PHY_SPEC_CTRL           \
	GG82563_REG(0, 16) /* PHY Specific Control */
#define GG82563_PHY_PAGE_SELECT         \
	GG82563_REG(0, 22) /* Page Select */
#define GG82563_PHY_SPEC_CTRL_2         \
	GG82563_REG(0, 26) /* PHY Specific Control 2 */
#define GG82563_PHY_PAGE_SELECT_ALT     \
	GG82563_REG(0, 29) /* Alternate Page Select */

#define GG82563_PHY_MAC_SPEC_CTRL       \
	GG82563_REG(2, 21) /* MAC Specific Control Register */

#define GG82563_PHY_DSP_DISTANCE    \
	GG82563_REG(5, 26) /* DSP Distance */

/* Page 193 - Port Control Registers */
#define GG82563_PHY_KMRN_MODE_CTRL   \
	GG82563_REG(193, 16) /* Kumeran Mode Control */
#define GG82563_PHY_PWR_MGMT_CTRL       \
	GG82563_REG(193, 20) /* Power Management Control */

/* Page 194 - KMRN Registers */
#define GG82563_PHY_INBAND_CTRL         \
	GG82563_REG(194, 18) /* Inband Control */

/* MDI Control */
#define E1000_MDIC_REG_SHIFT 16
#define E1000_MDIC_PHY_SHIFT 21
#define E1000_MDIC_OP_WRITE  0x04000000
#define E1000_MDIC_OP_READ   0x08000000
#define E1000_MDIC_READY     0x10000000
#define E1000_MDIC_ERROR     0x40000000

/* SerDes Control */
#define E1000_GEN_POLL_TIMEOUT          640

#endif /* _E1000_DEFINES_H_ */


<|start_filename|>rootfs/buildroot-2017.11.1/package/vlc/vlc.mk<|end_filename|>
################################################################################
#
# vlc
#
################################################################################

VLC_VERSION = 2.2.8
VLC_SITE = https://get.videolan.org/vlc/$(VLC_VERSION)
VLC_SOURCE = vlc-$(VLC_VERSION).tar.xz
VLC_LICENSE = GPL-2.0+, LGPL-2.1+
VLC_LICENSE_FILES = COPYING COPYING.LIB
VLC_DEPENDENCIES = host-pkgconf
VLC_AUTORECONF = YES

# Install vlc libraries in staging.
VLC_INSTALL_STAGING = YES

# gcc bug internal compiler error: in merge_overlapping_regs, at
# regrename.c:304. This bug is fixed since gcc 6.
ifeq ($(BR2_microblaze):$(BR2_TOOLCHAIN_GCC_AT_LEAST_6),y:)
VLC_CONF_ENV += CFLAGS="$(TARGET_CFLAGS) -O0"
VLC_CONF_OPTS += --disable-optimizations
endif

# VLC defines two autoconf functions which are also defined by our own pkg.m4
# from pkgconf. Unfortunately, they are defined in a different way: VLC adds
# --enable- options, but pkg.m4 adds --with- options. To make sure we use
# VLC's definition, rename these two functions.
define VLC_OVERRIDE_PKG_M4
	$(SED) 's/PKG_WITH_MODULES/VLC_PKG_WITH_MODULES/g' \
		-e 's/PKG_HAVE_WITH_MODULES/VLC_PKG_HAVE_WITH_MODULES/g' \
		$(@D)/configure.ac $(@D)/m4/with_pkg.m4
endef
VLC_POST_PATCH_HOOKS += VLC_OVERRIDE_PKG_M4

VLC_CONF_OPTS += \
	--disable-gles1 \
	--disable-a52 \
	--disable-shout \
	--disable-twolame \
	--disable-dca \
	--disable-schroedinger \
	--disable-fluidsynth \
	--disable-zvbi \
	--disable-kate \
	--disable-caca \
	--disable-jack \
	--disable-samplerate \
	--disable-chromaprint \
	--disable-goom \
	--disable-projectm \
	--disable-vsxu \
	--disable-mtp \
	--disable-mmal-codec \
	--disable-mmal-vout \
	--disable-dvdnav \
	--disable-vpx \
	--disable-jpeg \
	--disable-x262 \
	--disable-x265 \
	--disable-mfx \
	--disable-vdpau \
	--disable-addonmanagermodules \
	--enable-run-as-root

# Uses __atomic_fetch_add_4
ifeq ($(BR2_TOOLCHAIN_HAS_LIBATOMIC),y)
VLC_CONF_ENV += LIBS="-latomic"
endif

# Building static and shared doesn't work, so force static off.
ifeq ($(BR2_STATIC_LIBS),)
VLC_CONF_OPTS += --disable-static
endif

ifeq ($(BR2_POWERPC_CPU_HAS_ALTIVEC),y)
VLC_CONF_OPTS += --enable-altivec
else
VLC_CONF_OPTS += --disable-altivec
endif

ifeq ($(BR2_X86_CPU_HAS_SSE),y)
VLC_CONF_OPTS += --enable-sse
else
VLC_CONF_OPTS += --disable-sse
endif

ifeq ($(BR2_PACKAGE_ALSA_LIB),y)
VLC_CONF_OPTS += --enable-alsa
VLC_DEPENDENCIES += alsa-lib
else
VLC_CONF_OPTS += --disable-alsa
endif

# bonjour support needs avahi-client, which needs avahi-daemon and dbus
ifeq ($(BR2_PACKAGE_AVAHI)$(BR2_PACKAGE_AVAHI_DAEMON)$(BR2_PACKAGE_DBUS),yyy)
VLC_CONF_OPTS += --enable-bonjour
VLC_DEPENDENCIES += avahi dbus
else
VLC_CONF_OPTS += --disable-bonjour
endif

ifeq ($(BR2_PACKAGE_DBUS),y)
VLC_CONF_OPTS += --enable-dbus
VLC_DEPENDENCIES += dbus
else
VLC_CONF_OPTS += --disable-dbus
endif

ifeq ($(BR2_PACKAGE_DIRECTFB),y)
VLC_CONF_OPTS += --enable-directfb
VLC_CONF_ENV += ac_cv_path_DIRECTFB_CONFIG=$(STAGING_DIR)/usr/bin/directfb-config
VLC_DEPENDENCIES += directfb
else
VLC_CONF_OPTS += --disable-directfb
endif

ifeq ($(BR2_PACKAGE_FAAD2),y)
VLC_CONF_OPTS += --enable-faad
VLC_DEPENDENCIES += faad2
else
VLC_CONF_OPTS += --disable-faad
endif

ifeq ($(BR2_PACKAGE_FFMPEG),y)
VLC_CONF_OPTS += --enable-avcodec
VLC_DEPENDENCIES += ffmpeg
else
VLC_CONF_OPTS += --disable-avcodec
endif

ifeq ($(BR2_PACKAGE_FFMPEG_POSTPROC),y)
VLC_CONF_OPTS += --enable-postproc
else
VLC_CONF_OPTS += --disable-postproc
endif

ifeq ($(BR2_PACKAGE_FFMPEG_SWSCALE),y)
VLC_CONF_OPTS += --enable-swscale
else
VLC_CONF_OPTS += --disable-swscale
endif

ifeq ($(BR2_PACKAGE_FLAC),y)
VLC_CONF_OPTS += --enable-flac
VLC_DEPENDENCIES += flac
else
VLC_CONF_OPTS += --disable-flac
endif

ifeq ($(BR2_PACKAGE_FREERDP),y)
VLC_DEPENDENCIES += freerdp
endif

ifeq ($(BR2_PACKAGE_HAS_LIBGL),y)
VLC_DEPENDENCIES += libgl
endif

ifeq ($(BR2_PACKAGE_HAS_LIBGLES),y)
VLC_CONF_OPTS += --enable-gles2
VLC_DEPENDENCIES += libgles
else
VLC_CONF_OPTS += --disable-gles2
endif

ifeq ($(BR2_PACKAGE_OPENCV)$(BR2_PACKAGE_OPENCV3),y)
VLC_CONF_OPTS += --enable-opencv
ifeq ($(BR2_PACKAGE_OPENCV),y)
VLC_DEPENDENCIES += opencv
else
VLC_DEPENDENCIES += opencv3
endif
else
VLC_CONF_OPTS += --disable-opencv
endif

ifeq ($(BR2_PACKAGE_OPUS),y)
VLC_CONF_OPTS += --enable-opus
VLC_DEPENDENCIES += libvorbis opus
else
VLC_CONF_OPTS += --disable-opus
endif

ifeq ($(BR2_PACKAGE_LIBASS),y)
VLC_CONF_OPTS += --enable-libass
VLC_DEPENDENCIES += libass
else
VLC_CONF_OPTS += --disable-libass
endif

ifeq ($(BR2_PACKAGE_LIBBLURAY),y)
VLC_CONF_OPTS += --enable-bluray
VLC_DEPENDENCIES += libbluray
else
VLC_CONF_OPTS += --disable-bluray
endif

ifeq ($(BR2_PACKAGE_LIBCDDB),y)
VLC_CONF_OPTS += --enable-libcddb
VLC_DEPENDENCIES += libcddb
else
VLC_CONF_OPTS += --disable-libcddb
endif

ifeq ($(BR2_PACKAGE_LIBDVBPSI),y)
VLC_CONF_OPTS += --enable-dvbpsi
VLC_DEPENDENCIES += libdvbpsi
else
VLC_CONF_OPTS += --disable-dvbpsi
endif

ifeq ($(BR2_PACKAGE_LIBGCRYPT),y)
VLC_CONF_OPTS += --enable-libgcrypt
VLC_DEPENDENCIES += libgcrypt
VLC_CONF_ENV += \
	GCRYPT_CONFIG="$(STAGING_DIR)/usr/bin/libgcrypt-config"
else
VLC_CONF_OPTS += --disable-libgcrypt
endif

ifeq ($(BR2_PACKAGE_LIBMAD),y)
VLC_CONF_OPTS += --enable-mad
VLC_DEPENDENCIES += libmad
else
VLC_CONF_OPTS += --disable-mad
endif

ifeq ($(BR2_PACKAGE_LIBMATROSKA),y)
VLC_CONF_OPTS += --enable-mkv
VLC_DEPENDENCIES += libmatroska
else
VLC_CONF_OPTS += --disable-mkv
endif

ifeq ($(BR2_PACKAGE_LIBMODPLUG),y)
VLC_CONF_OPTS += --enable-mod
VLC_DEPENDENCIES += libmodplug
else
VLC_CONF_OPTS += --disable-mod
endif

ifeq ($(BR2_PACKAGE_LIBMPEG2),y)
VLC_CONF_OPTS += --enable-libmpeg2
VLC_DEPENDENCIES += libmpeg2
else
VLC_CONF_OPTS += --disable-libmpeg2
endif

ifeq ($(BR2_PACKAGE_LIBPNG),y)
VLC_CONF_OPTS += --enable-png
VLC_DEPENDENCIES += libpng
else
VLC_CONF_OPTS += --disable-png
endif

ifeq ($(BR2_PACKAGE_LIBRSVG),y)
VLC_CONF_OPTS += --enable-svg --enable-svgdec
VLC_DEPENDENCIES += librsvg
else
VLC_CONF_OPTS += --disable-svg --disable-svgdec
endif

ifeq ($(BR2_PACKAGE_LIBSSH2),y)
VLC_CONF_OPTS += --enable-sftp
VLC_DEPENDENCIES += libssh2
else
VLC_CONF_OPTS += --disable-sftp
endif

ifeq ($(BR2_PACKAGE_LIBSIDPLAY2),y)
VLC_CONF_OPTS += --enable-sid
VLC_DEPENDENCIES += libsidplay2
else
VLC_CONF_OPTS += --disable-sid
endif

ifeq ($(BR2_PACKAGE_LIBTHEORA),y)
VLC_CONF_OPTS += --enable-theora
VLC_DEPENDENCIES += libtheora
else
VLC_CONF_OPTS += --disable-theora
endif

ifeq ($(BR2_PACKAGE_LIBUPNP),y)
VLC_CONF_OPTS += --enable-upnp
VLC_DEPENDENCIES += libupnp
else
VLC_CONF_OPTS += --disable-upnp
endif

ifeq ($(BR2_PACKAGE_LIBVNCSERVER),y)
VLC_CONF_OPTS += --enable-vnc
VLC_DEPENDENCIES += libvncserver
else
VLC_CONF_OPTS += --disable-vnc
endif

ifeq ($(BR2_PACKAGE_LIBVORBIS),y)
VLC_CONF_OPTS += --enable-vorbis
VLC_DEPENDENCIES += libvorbis
else
VLC_CONF_OPTS += --disable-vorbis
endif

ifeq ($(BR2_PACKAGE_LIBV4L),y)
VLC_CONF_OPTS += --enable-v4l2
VLC_DEPENDENCIES += libv4l
else
VLC_CONF_OPTS += --disable-v4l2
endif

ifeq ($(BR2_PACKAGE_LIBXCB),y)
VLC_CONF_OPTS += --enable-xcb
VLC_DEPENDENCIES += libxcb
else
VLC_CONF_OPTS += --disable-xcb
endif

ifeq ($(BR2_PACKAGE_LIBXML2),y)
VLC_CONF_OPTS += --enable-libxml2
VLC_DEPENDENCIES += libxml2
else
VLC_CONF_OPTS += --disable-libxml2
endif

ifeq ($(BR2_PACKAGE_LIVE555),y)
VLC_CONF_OPTS += --enable-live555
VLC_DEPENDENCIES += live555
VLC_CONF_ENV += \
	LIVE555_CFLAGS="\
		-I$(STAGING_DIR)/usr/include/BasicUsageEnvironment \
		-I$(STAGING_DIR)/usr/include/groupsock \
		-I$(STAGING_DIR)/usr/include/liveMedia \
		-I$(STAGING_DIR)/usr/include/UsageEnvironment \
		" \
	LIVE555_LIBS="-L$(STAGING_DIR)/usr/lib -lliveMedia"
else
VLC_CONF_OPTS += --disable-live555
endif

ifeq ($(BR2_PACKAGE_LUA),y)
VLC_CONF_OPTS += --enable-lua
VLC_DEPENDENCIES += lua host-lua
else
VLC_CONF_OPTS += --disable-lua
endif

ifeq ($(BR2_PACKAGE_MINIZIP),y)
VLC_DEPENDENCIES += minizip
endif

ifeq ($(BR2_PACKAGE_MUSEPACK),y)
VLC_CONF_OPTS += --enable-mpc
VLC_DEPENDENCIES += musepack
else
VLC_CONF_OPTS += --disable-mpc
endif

ifeq ($(BR2_PACKAGE_QT_GUI_MODULE),y)
VLC_CONF_OPTS += --enable-qt
VLC_CONF_ENV += \
	ac_cv_path_MOC=$(HOST_DIR)/bin/moc \
	ac_cv_path_RCC=$(HOST_DIR)/bin/rcc \
	ac_cv_path_UIC=$(HOST_DIR)/bin/uic
VLC_DEPENDENCIES += qt
else
VLC_CONF_OPTS += --disable-qt
endif

ifeq ($(BR2_PACKAGE_SDL_X11),y)
VLC_CONF_OPTS += --enable-sdl
VLC_DEPENDENCIES += sdl
else
VLC_CONF_OPTS += --disable-sdl
endif

ifeq ($(BR2_PACKAGE_SDL_IMAGE),y)
VLC_CONF_OPTS += --enable-sdl-image
VLC_DEPENDENCIES += sdl_image
else
VLC_CONF_OPTS += --disable-sdl-image
endif

ifeq ($(BR2_PACKAGE_SPEEX),y)
VLC_CONF_OPTS += --enable-speex
VLC_DEPENDENCIES += speex
else
VLC_CONF_OPTS += --disable-speex
endif

ifeq ($(BR2_PACKAGE_TAGLIB),y)
VLC_CONF_OPTS += --enable-taglib
VLC_DEPENDENCIES += taglib
else
VLC_CONF_OPTS += --disable-taglib
endif

ifeq ($(BR2_PACKAGE_TREMOR),y)
VLC_CONF_OPTS += --enable-tremor
VLC_DEPENDENCIES += tremor
else
VLC_CONF_OPTS += --disable-tremor
endif

ifeq ($(BR2_PACKAGE_HAS_UDEV),y)
VLC_CONF_OPTS += --enable-udev
VLC_DEPENDENCIES += udev
else
VLC_CONF_OPTS += --disable-udev
endif

ifeq ($(BR2_PACKAGE_XCB_UTIL_KEYSYMS),y)
VLC_CONF_OPTS += --enable-xcb
VLC_DEPENDENCIES += xcb-util-keysyms
else
VLC_CONF_OPTS += --disable-xcb
endif

ifeq ($(BR2_PACKAGE_XLIB_LIBX11),y)
VLC_CONF_OPTS += --with-x
VLC_DEPENDENCIES += xlib_libX11
else
VLC_CONF_OPTS += --without-x
endif

ifeq ($(BR2_PACKAGE_ZLIB),y)
VLC_DEPENDENCIES += zlib
endif

$(eval $(autotools-package))


<|start_filename|>3rdpart/tslib-1.15/src/ts_read_raw.c<|end_filename|>
/*
 *  tslib/src/ts_read_raw.c
 *
 *  Copyright (C) 2003 <NAME>.
 *
 * This file is placed under the LGPL.  Please see the file
 * COPYING for more details.
 *
 * SPDX-License-Identifier: LGPL-2.1
 *
 *
 * Read raw pressure, x, y, and timestamp from a touchscreen device.
 */
#include "config.h"

#include "tslib-private.h"

#ifdef DEBUG
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#endif

int ts_read_raw(struct tsdev *ts, struct ts_sample *samp, int nr)
{
#ifdef DEBUG
	int i;
#endif
	int result = ts->list_raw->ops->read(ts->list_raw, samp, nr);

#ifdef DEBUG
	for (i = 0; i < result; i++) {
		fprintf(stderr,
			"TS_READ_RAW----> x = %d, y = %d, pressure = %d\n",
			samp->x, samp->y, samp->pressure);

		samp++;
	}
#endif
	return result;
}

int ts_read_raw_mt(struct tsdev *ts, struct ts_sample_mt **samp, int slots,
		   int nr)
{
#ifdef DEBUG
	int i, j;
#endif

	int result = ts->list_raw->ops->read_mt(ts->list_raw, samp, slots, nr);
#ifdef DEBUG
	for (i = 0; i < result; i++) {
		for (j = 0; j < slots; j++) {
			if (!(samp[i][j].valid & TSLIB_MT_VALID))
				continue;

			ts_error("TS_READ_RAW_MT----> slot %d: x = %d, y = %d, pressure = %d\n",
				 samp[i][j].slot, samp[i][j].x, samp[i][j].y,
				 samp[i][j].pressure);
		}
	}
#endif
	return result;
}


<|start_filename|>3rdpart/ethercat-1.5.2/master/pdo.h<|end_filename|>
/******************************************************************************
 *
 *  $Id: pdo.h,v 2bf892fe8080 2010/02/23 14:49:12 fp $
 *
 *  Copyright (C) 2006-2008  <NAME>, Ingenieurgemeinschaft IgH
 *
 *  This file is part of the IgH EtherCAT Master.
 *
 *  The IgH EtherCAT Master is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License version 2, as
 *  published by the Free Software Foundation.
 *
 *  The IgH EtherCAT Master is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 *  Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with the IgH EtherCAT Master; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 *****************************************************************************/

/**
   \file
   EtherCAT Process data object structure.
*/

/*****************************************************************************/

#ifndef __EC_PDO_H__
#define __EC_PDO_H__

#include <linux/list.h>

#include "globals.h"
#include "pdo_entry.h"

/*****************************************************************************/

/** PDO description.
 */
typedef struct {
    struct list_head list; /**< List item. */
    uint16_t index; /**< PDO index. */
    int8_t sync_index; /**< Assigned sync manager. \todo remove? */
    char *name; /**< PDO name. */
    struct list_head entries; /**< List of PDO entries. */
} ec_pdo_t;

/*****************************************************************************/

void ec_pdo_init(ec_pdo_t *);
int ec_pdo_init_copy(ec_pdo_t *, const ec_pdo_t *);
void ec_pdo_clear(ec_pdo_t *);
void ec_pdo_clear_entries(ec_pdo_t *);
int ec_pdo_set_name(ec_pdo_t *, const char *);
ec_pdo_entry_t *ec_pdo_add_entry(ec_pdo_t *, uint16_t, uint8_t, uint8_t);
int ec_pdo_copy_entries(ec_pdo_t *, const ec_pdo_t *);
int ec_pdo_equal_entries(const ec_pdo_t *, const ec_pdo_t *);
unsigned int ec_pdo_entry_count(const ec_pdo_t *);
const ec_pdo_entry_t *ec_pdo_find_entry_by_pos_const(
        const ec_pdo_t *, unsigned int);

void ec_pdo_print_entries(const ec_pdo_t *);

/*****************************************************************************/

#endif


<|start_filename|>rootfs/buildroot-2017.11.1/package/libzip/libzip.mk<|end_filename|>
################################################################################
#
# libzip
#
################################################################################

LIBZIP_VERSION = 1.3.0
LIBZIP_SITE = http://www.nih.at/libzip
LIBZIP_SOURCE = libzip-$(LIBZIP_VERSION).tar.xz
LIBZIP_LICENSE = BSD-3-Clause
LIBZIP_LICENSE_FILES = LICENSE
LIBZIP_INSTALL_STAGING = YES
LIBZIP_DEPENDENCIES = zlib

ifeq ($(BR2_PACKAGE_BZIP2),y)
LIBZIP_CONF_OPTS += --with-bzip2
LIBZIP_DEPENDENCIES += bzip2
else
LIBZIP_CONF_OPTS += --without-bzip2
endif

$(eval $(autotools-package))


<|start_filename|>3rdpart/ethercat-1.5.2/master/fsm_slave_scan.c<|end_filename|>
/******************************************************************************
 *
 *  $Id: fsm_slave_scan.c,v 1e8d9fcb5100 2013/02/06 16:52:07 fp $
 *
 *  Copyright (C) 2006-2008  <NAME>, Ingenieurgemeinschaft IgH
 *
 *  This file is part of the IgH EtherCAT Master.
 *
 *  The IgH EtherCAT Master is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License version 2, as
 *  published by the Free Software Foundation.
 *
 *  The IgH EtherCAT Master is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 *  Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with the IgH EtherCAT Master; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 *****************************************************************************/

/**
   \file
   EtherCAT slave state machines.
*/

/*****************************************************************************/

#include "globals.h"
#include "master.h"
#include "mailbox.h"
#include "slave_config.h"

#include "fsm_slave_scan.h"

/*****************************************************************************/

void ec_fsm_slave_scan_state_start(ec_fsm_slave_scan_t *);
void ec_fsm_slave_scan_state_address(ec_fsm_slave_scan_t *);
void ec_fsm_slave_scan_state_state(ec_fsm_slave_scan_t *);
void ec_fsm_slave_scan_state_base(ec_fsm_slave_scan_t *);
void ec_fsm_slave_scan_state_dc_cap(ec_fsm_slave_scan_t *);
void ec_fsm_slave_scan_state_dc_times(ec_fsm_slave_scan_t *);
void ec_fsm_slave_scan_state_datalink(ec_fsm_slave_scan_t *);
#ifdef EC_SII_ASSIGN
void ec_fsm_slave_scan_state_assign_sii(ec_fsm_slave_scan_t *);
#endif
void ec_fsm_slave_scan_state_sii_size(ec_fsm_slave_scan_t *);
void ec_fsm_slave_scan_state_sii_data(ec_fsm_slave_scan_t *);
#ifdef EC_REGALIAS
void ec_fsm_slave_scan_state_regalias(ec_fsm_slave_scan_t *);
#endif
void ec_fsm_slave_scan_state_preop(ec_fsm_slave_scan_t *);
void ec_fsm_slave_scan_state_sync(ec_fsm_slave_scan_t *);
void ec_fsm_slave_scan_state_pdos(ec_fsm_slave_scan_t *);

void ec_fsm_slave_scan_state_end(ec_fsm_slave_scan_t *);
void ec_fsm_slave_scan_state_error(ec_fsm_slave_scan_t *);

void ec_fsm_slave_scan_enter_datalink(ec_fsm_slave_scan_t *);
#ifdef EC_REGALIAS
void ec_fsm_slave_scan_enter_regalias(ec_fsm_slave_scan_t *);
#endif
void ec_fsm_slave_scan_enter_preop(ec_fsm_slave_scan_t *);
void ec_fsm_slave_scan_enter_pdos(ec_fsm_slave_scan_t *);

/*****************************************************************************/

/** Constructor.
 */
void ec_fsm_slave_scan_init(
        ec_fsm_slave_scan_t *fsm, /**< Slave scanning state machine. */
        ec_datagram_t *datagram, /**< Datagram to use. */
        ec_fsm_slave_config_t *fsm_slave_config, /**< Slave configuration
                                                  state machine to use. */
        ec_fsm_pdo_t *fsm_pdo /**< PDO configuration machine to use. */
        )
{
    fsm->datagram = datagram;
    fsm->fsm_slave_config = fsm_slave_config;
    fsm->fsm_pdo = fsm_pdo;

    // init sub state machines
    ec_fsm_sii_init(&fsm->fsm_sii, fsm->datagram);
}

/*****************************************************************************/

/** Destructor.
 */
void ec_fsm_slave_scan_clear(ec_fsm_slave_scan_t *fsm /**< slave state machine */)
{
    // clear sub state machines
    ec_fsm_sii_clear(&fsm->fsm_sii);
}

/*****************************************************************************/

/**
 * Start slave scan state machine.
 */

void ec_fsm_slave_scan_start(
        ec_fsm_slave_scan_t *fsm, /**< slave state machine */
        ec_slave_t *slave /**< slave to configure */
        )
{
    fsm->slave = slave;
    fsm->state = ec_fsm_slave_scan_state_start;
}

/*****************************************************************************/

/**
   \return false, if state machine has terminated
*/

int ec_fsm_slave_scan_running(const ec_fsm_slave_scan_t *fsm /**< slave state machine */)
{
    return fsm->state != ec_fsm_slave_scan_state_end
        && fsm->state != ec_fsm_slave_scan_state_error;
}

/*****************************************************************************/

/**
   Executes the current state of the state machine.
   If the state machine's datagram is not sent or received yet, the execution
   of the state machine is delayed to the next cycle.
   \return false, if state machine has terminated
*/

int ec_fsm_slave_scan_exec(ec_fsm_slave_scan_t *fsm /**< slave state machine */)
{
    if (fsm->datagram->state == EC_DATAGRAM_SENT
        || fsm->datagram->state == EC_DATAGRAM_QUEUED) {
        // datagram was not sent or received yet.
        return ec_fsm_slave_scan_running(fsm);
    }

    fsm->state(fsm);
    return ec_fsm_slave_scan_running(fsm);
}

/*****************************************************************************/

/**
   \return true, if the state machine terminated gracefully
*/

int ec_fsm_slave_scan_success(const ec_fsm_slave_scan_t *fsm /**< slave state machine */)
{
    return fsm->state == ec_fsm_slave_scan_state_end;
}

/******************************************************************************
 *  slave scan state machine
 *****************************************************************************/

/**
   Slave scan state: START.
   First state of the slave state machine. Writes the station address to the
   slave, according to its ring position.
*/

void ec_fsm_slave_scan_state_start(ec_fsm_slave_scan_t *fsm /**< slave state machine */)
{
    // write station address
    ec_datagram_apwr(fsm->datagram, fsm->slave->ring_position, 0x0010, 2);
    EC_WRITE_U16(fsm->datagram->data, fsm->slave->station_address);
    fsm->retries = EC_FSM_RETRIES;
    fsm->state = ec_fsm_slave_scan_state_address;
}

/*****************************************************************************/

/**
   Slave scan state: ADDRESS.
*/

void ec_fsm_slave_scan_state_address(
        ec_fsm_slave_scan_t *fsm /**< slave state machine */
        )
{
    ec_datagram_t *datagram = fsm->datagram;

    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
        return;

    if (datagram->state != EC_DATAGRAM_RECEIVED) {
        fsm->state = ec_fsm_slave_scan_state_error;
        EC_SLAVE_ERR(fsm->slave,
                "Failed to receive station address datagram: ");
        ec_datagram_print_state(datagram);
        return;
    }

    if (datagram->working_counter != 1) {
        fsm->slave->error_flag = 1;
        fsm->state = ec_fsm_slave_scan_state_error;
        EC_SLAVE_ERR(fsm->slave, "Failed to write station address: ");
        ec_datagram_print_wc_error(datagram);
        return;
    }

    // Read AL state
    ec_datagram_fprd(datagram, fsm->slave->station_address, 0x0130, 2);
    ec_datagram_zero(datagram);
    fsm->retries = EC_FSM_RETRIES;
    fsm->state = ec_fsm_slave_scan_state_state;
}

/*****************************************************************************/

/**
   Slave scan state: STATE.
*/

void ec_fsm_slave_scan_state_state(
        ec_fsm_slave_scan_t *fsm /**< slave state machine */
        )
{
    ec_datagram_t *datagram = fsm->datagram;
    ec_slave_t *slave = fsm->slave;

    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
        return;

    if (datagram->state != EC_DATAGRAM_RECEIVED) {
        fsm->state = ec_fsm_slave_scan_state_error;
        EC_SLAVE_ERR(slave, "Failed to receive AL state datagram: ");
        ec_datagram_print_state(datagram);
        return;
    }

    if (datagram->working_counter != 1) {
        fsm->slave->error_flag = 1;
        fsm->state = ec_fsm_slave_scan_state_error;
        EC_SLAVE_ERR(slave, "Failed to read AL state: ");
        ec_datagram_print_wc_error(datagram);
        return;
    }

    slave->current_state = EC_READ_U8(datagram->data);
    if (slave->current_state & EC_SLAVE_STATE_ACK_ERR) {
        char state_str[EC_STATE_STRING_SIZE];
        ec_state_string(slave->current_state, state_str, 0);
        EC_SLAVE_WARN(slave, "Slave has state error bit set (%s)!\n",
                state_str);
    }

    // read base data
    ec_datagram_fprd(datagram, fsm->slave->station_address, 0x0000, 12);
    ec_datagram_zero(datagram);
    fsm->retries = EC_FSM_RETRIES;
    fsm->state = ec_fsm_slave_scan_state_base;
}

/*****************************************************************************/

/** Slave scan state: BASE.
 */
void ec_fsm_slave_scan_state_base(
        ec_fsm_slave_scan_t *fsm /**< slave state machine */
        )
{
    ec_datagram_t *datagram = fsm->datagram;
    ec_slave_t *slave = fsm->slave;
    u8 octet;
    int i;

    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
        return;

    if (datagram->state != EC_DATAGRAM_RECEIVED) {
        fsm->state = ec_fsm_slave_scan_state_error;
        EC_SLAVE_ERR(slave, "Failed to receive base data datagram: ");
        ec_datagram_print_state(datagram);
        return;
    }

    if (datagram->working_counter != 1) {
        fsm->slave->error_flag = 1;
        fsm->state = ec_fsm_slave_scan_state_error;
        EC_SLAVE_ERR(slave, "Failed to read base data: ");
        ec_datagram_print_wc_error(datagram);
        return;
    }

    slave->base_type       = EC_READ_U8 (datagram->data);
    slave->base_revision   = EC_READ_U8 (datagram->data + 1);
    slave->base_build      = EC_READ_U16(datagram->data + 2);

    slave->base_fmmu_count = EC_READ_U8 (datagram->data + 4);
    if (slave->base_fmmu_count > EC_MAX_FMMUS) {
        EC_SLAVE_WARN(slave, "Slave has more FMMUs (%u) than the master can"
                " handle (%u).\n", slave->base_fmmu_count, EC_MAX_FMMUS);
        slave->base_fmmu_count = EC_MAX_FMMUS;
    }

    slave->base_sync_count = EC_READ_U8(datagram->data + 5);
    if (slave->base_sync_count > EC_MAX_SYNC_MANAGERS) {
        EC_SLAVE_WARN(slave, "Slave provides more sync managers (%u)"
                " than the master can handle (%u).\n",
                slave->base_sync_count, EC_MAX_SYNC_MANAGERS);
        slave->base_sync_count = EC_MAX_SYNC_MANAGERS;
    }

    octet = EC_READ_U8(datagram->data + 7);
    for (i = 0; i < EC_MAX_PORTS; i++) {
        slave->ports[i].desc = (octet >> (2 * i)) & 0x03;
    }

    octet = EC_READ_U8(datagram->data + 8);
    slave->base_fmmu_bit_operation = octet & 0x01;
    slave->base_dc_supported = (octet >> 2) & 0x01;
    slave->base_dc_range = ((octet >> 3) & 0x01) ? EC_DC_64 : EC_DC_32;

    if (slave->base_dc_supported) {
        // read DC capabilities
        ec_datagram_fprd(datagram, slave->station_address, 0x0910,
                slave->base_dc_range == EC_DC_64 ? 8 : 4);
        ec_datagram_zero(datagram);
        fsm->retries = EC_FSM_RETRIES;
        fsm->state = ec_fsm_slave_scan_state_dc_cap;
    } else {
        ec_fsm_slave_scan_enter_datalink(fsm);
    }
}

/*****************************************************************************/

/**
   Slave scan state: DC CAPABILITIES.
*/

void ec_fsm_slave_scan_state_dc_cap(
        ec_fsm_slave_scan_t *fsm /**< slave state machine */
        )
{
    ec_datagram_t *datagram = fsm->datagram;
    ec_slave_t *slave = fsm->slave;

    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
        return;

    if (datagram->state != EC_DATAGRAM_RECEIVED) {
        fsm->state = ec_fsm_slave_scan_state_error;
        EC_SLAVE_ERR(slave, "Failed to receive system time datagram: ");
        ec_datagram_print_state(datagram);
        return;
    }

    if (datagram->working_counter == 1) {
        slave->has_dc_system_time = 1;
        EC_SLAVE_DBG(slave, 1, "Slave has the System Time register.\n");
    } else if (datagram->working_counter == 0) {
        EC_SLAVE_DBG(slave, 1, "Slave has no System Time register; delay "
                "measurement only.\n");
    } else {
        fsm->slave->error_flag = 1;
        fsm->state = ec_fsm_slave_scan_state_error;
        EC_SLAVE_ERR(slave, "Failed to determine, if system time register is "
                "supported: ");
        ec_datagram_print_wc_error(datagram);
        return;
    }

    // read DC port receive times
    ec_datagram_fprd(datagram, slave->station_address, 0x0900, 16);
    ec_datagram_zero(datagram);
    fsm->retries = EC_FSM_RETRIES;
    fsm->state = ec_fsm_slave_scan_state_dc_times;
}

/*****************************************************************************/

/**
   Slave scan state: DC TIMES.
*/

void ec_fsm_slave_scan_state_dc_times(
        ec_fsm_slave_scan_t *fsm /**< slave state machine */
        )
{
    ec_datagram_t *datagram = fsm->datagram;
    ec_slave_t *slave = fsm->slave;
    int i;

    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
        return;

    if (datagram->state != EC_DATAGRAM_RECEIVED) {
        fsm->state = ec_fsm_slave_scan_state_error;
        EC_SLAVE_ERR(slave, "Failed to receive system time datagram: ");
        ec_datagram_print_state(datagram);
        return;
    }

    if (datagram->working_counter != 1) {
        fsm->slave->error_flag = 1;
        fsm->state = ec_fsm_slave_scan_state_error;
        EC_SLAVE_ERR(slave, "Failed to get DC receive times: ");
        ec_datagram_print_wc_error(datagram);
        return;
    }

    for (i = 0; i < EC_MAX_PORTS; i++) {
        slave->ports[i].receive_time = EC_READ_U32(datagram->data + 4 * i);
    }

    ec_fsm_slave_scan_enter_datalink(fsm);
}

/*****************************************************************************/

/**
   Slave scan entry function: DATALINK.
*/

void ec_fsm_slave_scan_enter_datalink(
        ec_fsm_slave_scan_t *fsm /**< slave state machine */
        )
{
    ec_datagram_t *datagram = fsm->datagram;
    ec_slave_t *slave = fsm->slave;

    // read data link status
    ec_datagram_fprd(datagram, slave->station_address, 0x0110, 2);
    ec_datagram_zero(datagram);
    fsm->retries = EC_FSM_RETRIES;
    fsm->state = ec_fsm_slave_scan_state_datalink;
}

/*****************************************************************************/

/** Enter slave scan state SII_SIZE.
 */
void ec_fsm_slave_scan_enter_sii_size(
        ec_fsm_slave_scan_t *fsm /**< slave state machine */
        )
{
    // Start fetching SII size

    fsm->sii_offset = EC_FIRST_SII_CATEGORY_OFFSET; // first category header
    ec_fsm_sii_read(&fsm->fsm_sii, fsm->slave, fsm->sii_offset,
            EC_FSM_SII_USE_CONFIGURED_ADDRESS);
    fsm->state = ec_fsm_slave_scan_state_sii_size;
    fsm->state(fsm); // execute state immediately
}

/*****************************************************************************/

#ifdef EC_SII_ASSIGN

/** Enter slave scan state ASSIGN_SII.
 */
void ec_fsm_slave_scan_enter_assign_sii(
        ec_fsm_slave_scan_t *fsm /**< slave state machine */
        )
{
    ec_datagram_t *datagram = fsm->datagram;
    ec_slave_t *slave = fsm->slave;

    EC_SLAVE_DBG(slave, 1, "Assigning SII access to EtherCAT.\n");

    // assign SII to ECAT
    ec_datagram_fpwr(datagram, slave->station_address, 0x0500, 1);
    EC_WRITE_U8(datagram->data, 0x00); // EtherCAT
    fsm->retries = EC_FSM_RETRIES;
    fsm->state = ec_fsm_slave_scan_state_assign_sii;
}

#endif

/*****************************************************************************/

/**
   Slave scan state: DATALINK.
*/

void ec_fsm_slave_scan_state_datalink(
        ec_fsm_slave_scan_t *fsm /**< slave state machine */
        )
{
    ec_datagram_t *datagram = fsm->datagram;
    ec_slave_t *slave = fsm->slave;
    uint16_t dl_status;
    unsigned int i;

    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
        return;

    if (datagram->state != EC_DATAGRAM_RECEIVED) {
        fsm->state = ec_fsm_slave_scan_state_error;
        EC_SLAVE_ERR(slave, "Failed to receive DL status datagram: ");
        ec_datagram_print_state(datagram);
        return;
    }

    if (datagram->working_counter != 1) {
        fsm->slave->error_flag = 1;
        fsm->state = ec_fsm_slave_scan_state_error;
        EC_SLAVE_ERR(slave, "Failed to read DL status: ");
        ec_datagram_print_wc_error(datagram);
        return;
    }

    dl_status = EC_READ_U16(datagram->data);
    for (i = 0; i < EC_MAX_PORTS; i++) {
        slave->ports[i].link.link_up =
            dl_status & (1 << (4 + i)) ? 1 : 0;
        slave->ports[i].link.loop_closed =
            dl_status & (1 << (8 + i * 2)) ? 1 : 0;
        slave->ports[i].link.signal_detected =
            dl_status & (1 << (9 + i * 2)) ? 1 : 0;
    }

#ifdef EC_SII_ASSIGN
    ec_fsm_slave_scan_enter_assign_sii(fsm);
#else
    ec_fsm_slave_scan_enter_sii_size(fsm);
#endif
}

/*****************************************************************************/

#ifdef EC_SII_ASSIGN

/**
   Slave scan state: ASSIGN_SII.
*/

void ec_fsm_slave_scan_state_assign_sii(
        ec_fsm_slave_scan_t *fsm /**< slave state machine */
        )
{
    ec_datagram_t *datagram = fsm->datagram;
    ec_slave_t *slave = fsm->slave;

    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
        return;
    }

    if (datagram->state != EC_DATAGRAM_RECEIVED) {
        EC_SLAVE_WARN(slave, "Failed to receive SII assignment datagram: ");
        ec_datagram_print_state(datagram);
        // Try to go on, probably assignment is correct
        goto continue_with_sii_size;
    }

    if (datagram->working_counter != 1) {
        EC_SLAVE_WARN(slave, "Failed to assign SII to EtherCAT: ");
        ec_datagram_print_wc_error(datagram);
        // Try to go on, probably assignment is correct
    }

continue_with_sii_size:
    ec_fsm_slave_scan_enter_sii_size(fsm);
}

#endif

/*****************************************************************************/

/**
   Slave scan state: SII SIZE.
*/

void ec_fsm_slave_scan_state_sii_size(
        ec_fsm_slave_scan_t *fsm /**< slave state machine */
        )
{
    ec_slave_t *slave = fsm->slave;
    uint16_t cat_type, cat_size;

    if (ec_fsm_sii_exec(&fsm->fsm_sii))
        return;

    if (!ec_fsm_sii_success(&fsm->fsm_sii)) {
        fsm->slave->error_flag = 1;
        fsm->state = ec_fsm_slave_scan_state_error;
        EC_SLAVE_ERR(slave, "Failed to determine SII content size:"
                " Reading word offset 0x%04x failed. Assuming %u words.\n",
                fsm->sii_offset, EC_FIRST_SII_CATEGORY_OFFSET);
        slave->sii_nwords = EC_FIRST_SII_CATEGORY_OFFSET;
        goto alloc_sii;
    }

    cat_type = EC_READ_U16(fsm->fsm_sii.value);
    cat_size = EC_READ_U16(fsm->fsm_sii.value + 2);

    if (cat_type != 0xFFFF) { // not the last category
        off_t next_offset = 2UL + fsm->sii_offset + cat_size;
        if (next_offset >= EC_MAX_SII_SIZE) {
            EC_SLAVE_WARN(slave, "SII size exceeds %u words"
                    " (0xffff limiter missing?).\n", EC_MAX_SII_SIZE);
            // cut off category data...
            slave->sii_nwords = EC_FIRST_SII_CATEGORY_OFFSET;
            goto alloc_sii;
        }
        fsm->sii_offset = next_offset;
        ec_fsm_sii_read(&fsm->fsm_sii, slave, fsm->sii_offset,
                        EC_FSM_SII_USE_CONFIGURED_ADDRESS);
        ec_fsm_sii_exec(&fsm->fsm_sii); // execute state immediately
        return;
    }

    slave->sii_nwords = fsm->sii_offset + 1;

alloc_sii:
    if (slave->sii_words) {
        EC_SLAVE_WARN(slave, "Freeing old SII data...\n");
        kfree(slave->sii_words);
    }

    if (!(slave->sii_words =
                (uint16_t *) kmalloc(slave->sii_nwords * 2, GFP_KERNEL))) {
        EC_SLAVE_ERR(slave, "Failed to allocate %zu words of SII data.\n",
               slave->sii_nwords);
        slave->sii_nwords = 0;
        slave->error_flag = 1;
        fsm->state = ec_fsm_slave_scan_state_error;
        return;
    }

    // Start fetching SII contents

    fsm->state = ec_fsm_slave_scan_state_sii_data;
    fsm->sii_offset = 0x0000;
    ec_fsm_sii_read(&fsm->fsm_sii, slave, fsm->sii_offset,
            EC_FSM_SII_USE_CONFIGURED_ADDRESS);
    ec_fsm_sii_exec(&fsm->fsm_sii); // execute state immediately
}

/*****************************************************************************/

/**
   Slave scan state: SII DATA.
*/

void ec_fsm_slave_scan_state_sii_data(ec_fsm_slave_scan_t *fsm /**< slave state machine */)
{
    ec_slave_t *slave = fsm->slave;
    uint16_t *cat_word, cat_type, cat_size;

    if (ec_fsm_sii_exec(&fsm->fsm_sii)) return;

    if (!ec_fsm_sii_success(&fsm->fsm_sii)) {
        fsm->slave->error_flag = 1;
        fsm->state = ec_fsm_slave_scan_state_error;
        EC_SLAVE_ERR(slave, "Failed to fetch SII contents.\n");
        return;
    }

    // 2 words fetched

    if (fsm->sii_offset + 2 <= slave->sii_nwords) { // 2 words fit
        memcpy(slave->sii_words + fsm->sii_offset, fsm->fsm_sii.value, 4);
    } else { // copy the last word
        memcpy(slave->sii_words + fsm->sii_offset, fsm->fsm_sii.value, 2);
    }

    if (fsm->sii_offset + 2 < slave->sii_nwords) {
        // fetch the next 2 words
        fsm->sii_offset += 2;
        ec_fsm_sii_read(&fsm->fsm_sii, slave, fsm->sii_offset,
                        EC_FSM_SII_USE_CONFIGURED_ADDRESS);
        ec_fsm_sii_exec(&fsm->fsm_sii); // execute state immediately
        return;
    }

    // Evaluate SII contents

    ec_slave_clear_sync_managers(slave);

    slave->sii.alias =
        EC_READ_U16(slave->sii_words + 0x0004);
    slave->effective_alias = slave->sii.alias;
    slave->sii.vendor_id =
        EC_READ_U32(slave->sii_words + 0x0008);
    slave->sii.product_code =
        EC_READ_U32(slave->sii_words + 0x000A);
    slave->sii.revision_number =
        EC_READ_U32(slave->sii_words + 0x000C);
    slave->sii.serial_number =
        EC_READ_U32(slave->sii_words + 0x000E);
    slave->sii.boot_rx_mailbox_offset =
        EC_READ_U16(slave->sii_words + 0x0014);
    slave->sii.boot_rx_mailbox_size =
        EC_READ_U16(slave->sii_words + 0x0015);
    slave->sii.boot_tx_mailbox_offset =
        EC_READ_U16(slave->sii_words + 0x0016);
    slave->sii.boot_tx_mailbox_size =
        EC_READ_U16(slave->sii_words + 0x0017);
    slave->sii.std_rx_mailbox_offset =
        EC_READ_U16(slave->sii_words + 0x0018);
    slave->sii.std_rx_mailbox_size =
        EC_READ_U16(slave->sii_words + 0x0019);
    slave->sii.std_tx_mailbox_offset =
        EC_READ_U16(slave->sii_words + 0x001A);
    slave->sii.std_tx_mailbox_size =
        EC_READ_U16(slave->sii_words + 0x001B);
    slave->sii.mailbox_protocols =
        EC_READ_U16(slave->sii_words + 0x001C);

    if (slave->sii_nwords == EC_FIRST_SII_CATEGORY_OFFSET) {
        // sii does not contain category data
        fsm->state = ec_fsm_slave_scan_state_end;
        return;
    }

    if (slave->sii_nwords < EC_FIRST_SII_CATEGORY_OFFSET + 1) {
        EC_SLAVE_ERR(slave, "Unexpected end of SII data:"
                " First category header missing.\n");
        goto end;
    }

    // evaluate category data
    cat_word = slave->sii_words + EC_FIRST_SII_CATEGORY_OFFSET;
    while (EC_READ_U16(cat_word) != 0xFFFF) {

        // type and size words must fit
        if (cat_word + 2 - slave->sii_words > slave->sii_nwords) {
            EC_SLAVE_ERR(slave, "Unexpected end of SII data:"
                    " Category header incomplete.\n");
            goto end;
        }

        cat_type = EC_READ_U16(cat_word) & 0x7FFF;
        cat_size = EC_READ_U16(cat_word + 1);
        cat_word += 2;

        if (cat_word + cat_size - slave->sii_words > slave->sii_nwords) {
            EC_SLAVE_WARN(slave, "Unexpected end of SII data:"
                    " Category data incomplete.\n");
            goto end;
        }

        switch (cat_type) {
            case 0x000A:
                if (ec_slave_fetch_sii_strings(slave, (uint8_t *) cat_word,
                            cat_size * 2))
                    goto end;
                break;
            case 0x001E:
                if (ec_slave_fetch_sii_general(slave, (uint8_t *) cat_word,
                            cat_size * 2))
                    goto end;
                break;
            case 0x0028:
                break;
            case 0x0029:
                if (ec_slave_fetch_sii_syncs(slave, (uint8_t *) cat_word,
                            cat_size * 2))
                    goto end;
                break;
            case 0x0032:
                if (ec_slave_fetch_sii_pdos( slave, (uint8_t *) cat_word,
                            cat_size * 2, EC_DIR_INPUT)) // TxPDO
                    goto end;
                break;
            case 0x0033:
                if (ec_slave_fetch_sii_pdos( slave, (uint8_t *) cat_word,
                            cat_size * 2, EC_DIR_OUTPUT)) // RxPDO
                    goto end;
                break;
            default:
                EC_SLAVE_DBG(slave, 1, "Unknown category type 0x%04X.\n",
                        cat_type);
        }

        cat_word += cat_size;
        if (cat_word - slave->sii_words >= slave->sii_nwords) {
            EC_SLAVE_WARN(slave, "Unexpected end of SII data:"
                    " Next category header missing.\n");
            goto end;
        }
    }

#ifdef EC_REGALIAS
    ec_fsm_slave_scan_enter_regalias(fsm);
#else
    if (slave->sii.mailbox_protocols & EC_MBOX_COE) {
        ec_fsm_slave_scan_enter_preop(fsm);
    } else {
        fsm->state = ec_fsm_slave_scan_state_end;
    }
#endif
    return;

end:
    EC_SLAVE_ERR(slave, "Failed to analyze category data.\n");
    fsm->slave->error_flag = 1;
    fsm->state = ec_fsm_slave_scan_state_error;
}

/*****************************************************************************/

#ifdef EC_REGALIAS

/** Slave scan entry function: REGALIAS.
 */
void ec_fsm_slave_scan_enter_regalias(
        ec_fsm_slave_scan_t *fsm /**< slave state machine */
        )
{
    ec_datagram_t *datagram = fsm->datagram;
    ec_slave_t *slave = fsm->slave;

    // read alias from register
    EC_SLAVE_DBG(slave, 1, "Reading alias from register.\n");
    ec_datagram_fprd(datagram, slave->station_address, 0x0012, 2);
    ec_datagram_zero(datagram);
    fsm->retries = EC_FSM_RETRIES;
    fsm->state = ec_fsm_slave_scan_state_regalias;
}

/*****************************************************************************/

/** Slave scan state: REGALIAS.
 */
void ec_fsm_slave_scan_state_regalias(
        ec_fsm_slave_scan_t *fsm /**< slave state machine */
        )
{
    ec_datagram_t *datagram = fsm->datagram;
    ec_slave_t *slave = fsm->slave;

    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
        return;

    if (datagram->state != EC_DATAGRAM_RECEIVED) {
        fsm->state = ec_fsm_slave_scan_state_error;
        EC_SLAVE_ERR(slave, "Failed to receive register alias datagram: ");
        ec_datagram_print_state(datagram);
        return;
    }

    if (datagram->working_counter != 1) {
        EC_SLAVE_DBG(slave, 1, "Failed to read register alias.\n");
    } else {
        slave->effective_alias = EC_READ_U16(datagram->data);
        EC_SLAVE_DBG(slave, 1, "Read alias %u from register.\n",
                slave->effective_alias);
    }

    if (slave->sii.mailbox_protocols & EC_MBOX_COE) {
        ec_fsm_slave_scan_enter_preop(fsm);
    } else {
        fsm->state = ec_fsm_slave_scan_state_end;
    }
}

#endif // defined EC_REGALIAS

/*****************************************************************************/

/** Enter slave scan state PREOP.
 */
void ec_fsm_slave_scan_enter_preop(
        ec_fsm_slave_scan_t *fsm /**< slave state machine */
        )
{
    ec_slave_t *slave = fsm->slave;
    uint8_t current_state = slave->current_state & EC_SLAVE_STATE_MASK;

    if (current_state != EC_SLAVE_STATE_PREOP
            && current_state != EC_SLAVE_STATE_SAFEOP
            && current_state != EC_SLAVE_STATE_OP) {
        if (slave->master->debug_level) {
            char str[EC_STATE_STRING_SIZE];
            ec_state_string(current_state, str, 0);
            EC_SLAVE_DBG(slave, 0, "Slave is not in the state"
                    " to do mailbox com (%s), setting to PREOP.\n", str);
        }

        fsm->state = ec_fsm_slave_scan_state_preop;
        ec_slave_request_state(slave, EC_SLAVE_STATE_PREOP);
        ec_fsm_slave_config_start(fsm->fsm_slave_config, slave);
        ec_fsm_slave_config_exec(fsm->fsm_slave_config);
    } else {
        EC_SLAVE_DBG(slave, 1, "Reading mailbox"
                " sync manager configuration.\n");

        /* Scan current sync manager configuration to get configured mailbox
         * sizes. */
        ec_datagram_fprd(fsm->datagram, slave->station_address, 0x0800,
                EC_SYNC_PAGE_SIZE * 2);
        fsm->retries = EC_FSM_RETRIES;
        fsm->state = ec_fsm_slave_scan_state_sync;
    }
}

/*****************************************************************************/

/** Slave scan state: PREOP.
 */
void ec_fsm_slave_scan_state_preop(
        ec_fsm_slave_scan_t *fsm /**< slave state machine */
        )
{
    if (ec_fsm_slave_config_exec(fsm->fsm_slave_config))
        return;

    if (!ec_fsm_slave_config_success(fsm->fsm_slave_config)) {
        fsm->state = ec_fsm_slave_scan_state_error;
        return;
    }

    ec_fsm_slave_scan_enter_pdos(fsm);
}

/*****************************************************************************/

/** Slave scan state: SYNC.
 */
void ec_fsm_slave_scan_state_sync(
        ec_fsm_slave_scan_t *fsm /**< slave state machine */
        )
{
    ec_datagram_t *datagram = fsm->datagram;
    ec_slave_t *slave = fsm->slave;

    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
        return;

    if (datagram->state != EC_DATAGRAM_RECEIVED) {
        fsm->state = ec_fsm_slave_scan_state_error;
        EC_SLAVE_ERR(slave, "Failed to receive sync manager"
                " configuration datagram: ");
        ec_datagram_print_state(datagram);
        return;
    }

    if (datagram->working_counter != 1) {
        fsm->slave->error_flag = 1;
        fsm->state = ec_fsm_slave_scan_state_error;
        EC_SLAVE_ERR(slave, "Failed to read DL status: ");
        ec_datagram_print_wc_error(datagram);
        return;
    }

    slave->configured_rx_mailbox_offset = EC_READ_U16(datagram->data);
    slave->configured_rx_mailbox_size = EC_READ_U16(datagram->data + 2);
    slave->configured_tx_mailbox_offset = EC_READ_U16(datagram->data + 8);
    slave->configured_tx_mailbox_size = EC_READ_U16(datagram->data + 10);

    EC_SLAVE_DBG(slave, 1, "Mailbox configuration:\n");
    EC_SLAVE_DBG(slave, 1, " RX offset=0x%04x size=%u\n",
            slave->configured_rx_mailbox_offset,
            slave->configured_rx_mailbox_size);
    EC_SLAVE_DBG(slave, 1, " TX offset=0x%04x size=%u\n",
            slave->configured_tx_mailbox_offset,
            slave->configured_tx_mailbox_size);

    ec_fsm_slave_scan_enter_pdos(fsm);
}

/*****************************************************************************/

/** Enter slave scan state PDOS.
 */
void ec_fsm_slave_scan_enter_pdos(
        ec_fsm_slave_scan_t *fsm /**< slave state machine */
        )
{
    ec_slave_t *slave = fsm->slave;

    EC_SLAVE_DBG(slave, 1, "Scanning PDO assignment and mapping.\n");
    fsm->state = ec_fsm_slave_scan_state_pdos;
    ec_fsm_pdo_start_reading(fsm->fsm_pdo, slave);
    ec_fsm_pdo_exec(fsm->fsm_pdo, fsm->datagram); // execute immediately
}

/*****************************************************************************/

/** Slave scan state: PDOS.
 */
void ec_fsm_slave_scan_state_pdos(
        ec_fsm_slave_scan_t *fsm /**< slave state machine */
        )
{
    if (ec_fsm_pdo_exec(fsm->fsm_pdo, fsm->datagram)) {
        return;
    }

    if (!ec_fsm_pdo_success(fsm->fsm_pdo)) {
        fsm->state = ec_fsm_slave_scan_state_error;
        return;
    }

    // reading PDO configuration finished
    fsm->state = ec_fsm_slave_scan_state_end;
}

/******************************************************************************
 * Common state functions
 *****************************************************************************/

/** State: ERROR.
 */
void ec_fsm_slave_scan_state_error(
        ec_fsm_slave_scan_t *fsm /**< slave state machine */
        )
{
}

/*****************************************************************************/

/** State: END.
 */
void ec_fsm_slave_scan_state_end(
        ec_fsm_slave_scan_t *fsm /**< slave state machine */
        )
{
}

/*****************************************************************************/


<|start_filename|>3rdpart/ethercat-1.5.2/master/fsm_change.c<|end_filename|>
/******************************************************************************
 *
 *  $Id: fsm_change.c,v fdb85a806585 2012/09/06 16:28:57 fp $
 *
 *  Copyright (C) 2006-2008  <NAME>, Ingenieurgemeinschaft IgH
 *
 *  This file is part of the IgH EtherCAT Master.
 *
 *  The IgH EtherCAT Master is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License version 2, as
 *  published by the Free Software Foundation.
 *
 *  The IgH EtherCAT Master is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 *  Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with the IgH EtherCAT Master; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 *****************************************************************************/

/**
   \file
   EtherCAT state change FSM.
*/

/*****************************************************************************/

#include "globals.h"
#include "master.h"
#include "fsm_change.h"

/*****************************************************************************/

/** Timeout while waiting for AL state change [s].
 */
#define EC_AL_STATE_CHANGE_TIMEOUT 5

/*****************************************************************************/

void ec_fsm_change_state_start(ec_fsm_change_t *);
void ec_fsm_change_state_check(ec_fsm_change_t *);
void ec_fsm_change_state_status(ec_fsm_change_t *);
void ec_fsm_change_state_start_code(ec_fsm_change_t *);
void ec_fsm_change_state_code(ec_fsm_change_t *);
void ec_fsm_change_state_ack(ec_fsm_change_t *);
void ec_fsm_change_state_check_ack(ec_fsm_change_t *);
void ec_fsm_change_state_end(ec_fsm_change_t *);
void ec_fsm_change_state_error(ec_fsm_change_t *);

/*****************************************************************************/

/**
   Constructor.
*/

void ec_fsm_change_init(ec_fsm_change_t *fsm, /**< finite state machine */
                        ec_datagram_t *datagram /**< datagram */
                        )
{
    fsm->state = NULL;
    fsm->datagram = datagram;
    fsm->spontaneous_change = 0;
}

/*****************************************************************************/

/**
   Destructor.
*/

void ec_fsm_change_clear(ec_fsm_change_t *fsm /**< finite state machine */)
{
}

/*****************************************************************************/

/**
   Starts the change state machine.
*/

void ec_fsm_change_start(ec_fsm_change_t *fsm, /**< finite state machine */
                         ec_slave_t *slave, /**< EtherCAT slave */
                         ec_slave_state_t state /**< requested state */
                         )
{
    fsm->mode = EC_FSM_CHANGE_MODE_FULL;
    fsm->slave = slave;
    fsm->requested_state = state;
    fsm->state = ec_fsm_change_state_start;
}

/*****************************************************************************/

/**
   Starts the change state machine to only acknowlegde a slave's state.
*/

void ec_fsm_change_ack(ec_fsm_change_t *fsm, /**< finite state machine */
                       ec_slave_t *slave /**< EtherCAT slave */
                       )
{
    fsm->mode = EC_FSM_CHANGE_MODE_ACK_ONLY;
    fsm->slave = slave;
    fsm->requested_state = EC_SLAVE_STATE_UNKNOWN;
    fsm->state = ec_fsm_change_state_start_code;
}

/*****************************************************************************/

/**
   Executes the current state of the state machine.
   \return false, if the state machine has terminated
*/

int ec_fsm_change_exec(ec_fsm_change_t *fsm /**< finite state machine */)
{
    fsm->state(fsm);

    return fsm->state != ec_fsm_change_state_end
        && fsm->state != ec_fsm_change_state_error;
}

/*****************************************************************************/

/**
   Returns, if the state machine terminated with success.
   \return non-zero if successful.
*/

int ec_fsm_change_success(ec_fsm_change_t *fsm /**< Finite state machine */)
{
    return fsm->state == ec_fsm_change_state_end;
}

/******************************************************************************
 *  state change state machine
 *****************************************************************************/

/**
   Change state: START.
*/

void ec_fsm_change_state_start(ec_fsm_change_t *fsm
                               /**< finite state machine */)
{
    ec_datagram_t *datagram = fsm->datagram;
    ec_slave_t *slave = fsm->slave;

    fsm->take_time = 1;
    fsm->old_state = fsm->slave->current_state;

    // write new state to slave
    ec_datagram_fpwr(datagram, slave->station_address, 0x0120, 2);
    EC_WRITE_U16(datagram->data, fsm->requested_state);
    fsm->retries = EC_FSM_RETRIES;
    fsm->state = ec_fsm_change_state_check;
}

/*****************************************************************************/

/**
   Change state: CHECK.
*/

void ec_fsm_change_state_check(ec_fsm_change_t *fsm
                               /**< finite state machine */)
{
    ec_datagram_t *datagram = fsm->datagram;
    ec_slave_t *slave = fsm->slave;

    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
        return;

    if (datagram->state != EC_DATAGRAM_RECEIVED) {
        fsm->state = ec_fsm_change_state_error;
        EC_SLAVE_ERR(slave, "Failed to receive state datagram: ");
        ec_datagram_print_state(datagram);
        return;
    }

    if (fsm->take_time) {
        fsm->take_time = 0;
        fsm->jiffies_start = datagram->jiffies_sent;
    }

    if (datagram->working_counter == 0) {
        if (datagram->jiffies_received - fsm->jiffies_start >= 3 * HZ) {
            char state_str[EC_STATE_STRING_SIZE];
            ec_state_string(fsm->requested_state, state_str, 0);
            fsm->state = ec_fsm_change_state_error;
            EC_SLAVE_ERR(slave, "Failed to set state %s: ", state_str);
            ec_datagram_print_wc_error(datagram);
            return;
        }

        // repeat writing new state to slave
        ec_datagram_fpwr(datagram, slave->station_address, 0x0120, 2);
        EC_WRITE_U16(datagram->data, fsm->requested_state);
        fsm->retries = EC_FSM_RETRIES;
        return;
    }

    if (unlikely(datagram->working_counter > 1)) {
        char state_str[EC_STATE_STRING_SIZE];
        ec_state_string(fsm->requested_state, state_str, 0);
        fsm->state = ec_fsm_change_state_error;
        EC_SLAVE_ERR(slave, "Failed to set state %s: ", state_str);
        ec_datagram_print_wc_error(datagram);
        return;
    }

    fsm->take_time = 1;

    // read AL status from slave
    ec_datagram_fprd(datagram, slave->station_address, 0x0130, 2);
    ec_datagram_zero(datagram);
    fsm->retries = EC_FSM_RETRIES;
    fsm->spontaneous_change = 0;
    fsm->state = ec_fsm_change_state_status;
}

/*****************************************************************************/

/**
   Change state: STATUS.
*/

void ec_fsm_change_state_status(ec_fsm_change_t *fsm
                                /**< finite state machine */)
{
    ec_datagram_t *datagram = fsm->datagram;
    ec_slave_t *slave = fsm->slave;

    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
        return;

    if (datagram->state != EC_DATAGRAM_RECEIVED) {
        fsm->state = ec_fsm_change_state_error;
        EC_SLAVE_ERR(slave, "Failed to receive state checking datagram: ");
        ec_datagram_print_state(datagram);
        return;
    }

    if (datagram->working_counter != 1) {
        char req_state[EC_STATE_STRING_SIZE];
        ec_state_string(fsm->requested_state, req_state, 0);
        fsm->state = ec_fsm_change_state_error;
        EC_SLAVE_ERR(slave, "Failed to check state %s: ", req_state);
        ec_datagram_print_wc_error(datagram);
        return;
    }

    if (fsm->take_time) {
        fsm->take_time = 0;
        fsm->jiffies_start = datagram->jiffies_sent;
    }

    slave->current_state = EC_READ_U8(datagram->data);

    if (slave->current_state == fsm->requested_state) {
        // state has been set successfully
        fsm->state = ec_fsm_change_state_end;
        return;
    }

    if (slave->current_state != fsm->old_state) { // state changed
        char req_state[EC_STATE_STRING_SIZE], cur_state[EC_STATE_STRING_SIZE];

        ec_state_string(slave->current_state, cur_state, 0);

        if ((slave->current_state & 0x0F) != (fsm->old_state & 0x0F)) {
            // Slave spontaneously changed its state just before the new state
            // was written. Accept current state as old state and wait for
            // state change
            fsm->spontaneous_change = 1;
            fsm->old_state = slave->current_state;
            EC_SLAVE_WARN(slave, "Changed to %s in the meantime.\n",
                    cur_state);
            goto check_again;
        }

        // state change error

        slave->error_flag = 1;
        ec_state_string(fsm->requested_state, req_state, 0);

        EC_SLAVE_ERR(slave, "Failed to set %s state, slave refused state"
                " change (%s).\n", req_state, cur_state);

        ec_fsm_change_state_start_code(fsm);
        return;
    }

    // still old state

    if (datagram->jiffies_received - fsm->jiffies_start >=
            EC_AL_STATE_CHANGE_TIMEOUT * HZ) {
        // timeout while checking
        char state_str[EC_STATE_STRING_SIZE];
        ec_state_string(fsm->requested_state, state_str, 0);
        fsm->state = ec_fsm_change_state_error;
        EC_SLAVE_ERR(slave, "Timeout while setting state %s.\n", state_str);
        return;
    }

 check_again:
    // no timeout yet. check again
    ec_datagram_fprd(datagram, slave->station_address, 0x0130, 2);
    ec_datagram_zero(datagram);
    fsm->retries = EC_FSM_RETRIES;
}

/*****************************************************************************/

/** Enter reading AL status code.
 */
void ec_fsm_change_state_start_code(
        ec_fsm_change_t *fsm /**< finite state machine */
        )
{
    ec_slave_t *slave = fsm->slave;
    ec_datagram_t *datagram = fsm->datagram;

    // fetch AL status error code
    ec_datagram_fprd(datagram, slave->station_address, 0x0134, 2);
    ec_datagram_zero(datagram);
    fsm->retries = EC_FSM_RETRIES;
    fsm->state = ec_fsm_change_state_code;
}

/*****************************************************************************/

/**
   Application layer status messages.
*/

const ec_code_msg_t al_status_messages[] = {
    {0x0000, "No error"},
    {0x0001, "Unspecified error"},
    {0x0002, "No Memory"},
    {0x0011, "Invalid requested state change"},
    {0x0012, "Unknown requested state"},
    {0x0013, "Bootstrap not supported"},
    {0x0014, "No valid firmware"},
    {0x0015, "Invalid mailbox configuration"},
    {0x0016, "Invalid mailbox configuration"},
    {0x0017, "Invalid sync manager configuration"},
    {0x0018, "No valid inputs available"},
    {0x0019, "No valid outputs"},
    {0x001A, "Synchronization error"},
    {0x001B, "Sync manager watchdog"},
    {0x001C, "Invalid sync manager types"},
    {0x001D, "Invalid output configuration"},
    {0x001E, "Invalid input configuration"},
    {0x001F, "Invalid watchdog configuration"},
    {0x0020, "Slave needs cold start"},
    {0x0021, "Slave needs INIT"},
    {0x0022, "Slave needs PREOP"},
    {0x0023, "Slave needs SAFEOP"},
    {0x0024, "Invalid Input Mapping"},
    {0x0025, "Invalid Output Mapping"},
    {0x0026, "Inconsistent Settings"},
    {0x0027, "Freerun not supported"},
    {0x0028, "Synchronization not supported"},
    {0x0029, "Freerun needs 3 Buffer Mode"},
    {0x002A, "Background Watchdog"},
    {0x002B, "No Valid Inputs and Outputs"},
    {0x002C, "Fatal Sync Error"},
    {0x002D, "No Sync Error"},
    {0x0030, "Invalid DC SYNCH configuration"},
    {0x0031, "Invalid DC latch configuration"},
    {0x0032, "PLL error"},
    {0x0033, "DC Sync IO Error"},
    {0x0034, "DC Sync Timeout Error"},
    {0x0035, "DC Invalid Sync Cycle Time"},
    {0x0036, "DC Sync0 Cycle Time"},
    {0x0037, "DC Sync1 Cycle Time"},
    {0x0041, "MBX_AOE"},
    {0x0042, "MBX_EOE"},
    {0x0043, "MBX_COE"},
    {0x0044, "MBX_FOE"},
    {0x0045, "MBX_SOE"},
    {0x004F, "MBX_VOE"},
    {0x0050, "EEPROM No Access"},
    {0x0051, "EEPROM Error"},
    {0x0060, "Slave Restarted Locally"},
    {0xffff}
};


/*****************************************************************************/

/**
   Change state: CODE.
*/

void ec_fsm_change_state_code(ec_fsm_change_t *fsm
                              /**< finite state machine */)
{
    ec_datagram_t *datagram = fsm->datagram;
    uint32_t code;
    const ec_code_msg_t *al_msg;

    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
        return;

    if (datagram->state != EC_DATAGRAM_RECEIVED) {
        fsm->state = ec_fsm_change_state_error;
        EC_SLAVE_ERR(fsm->slave, "Failed to receive"
                " AL status code datagram: ");
        ec_datagram_print_state(datagram);
        return;
    }

    if (datagram->working_counter != 1) {
        EC_SLAVE_WARN(fsm->slave, "Reception of AL status code"
                " datagram failed: ");
        ec_datagram_print_wc_error(datagram);
    } else {
        code = EC_READ_U16(datagram->data);
        for (al_msg = al_status_messages; al_msg->code != 0xffff; al_msg++) {
            if (al_msg->code != code) {
                continue;
            }

            EC_SLAVE_ERR(fsm->slave, "AL status message 0x%04X: \"%s\".\n",
                    al_msg->code, al_msg->message);
            break;
        }
        if (al_msg->code == 0xffff) { /* not found in our list. */
            EC_SLAVE_ERR(fsm->slave, "Unknown AL status code 0x%04X.\n",
                    code);
        }
    }

    // acknowledge "old" slave state
    ec_datagram_fpwr(datagram, fsm->slave->station_address, 0x0120, 2);
    EC_WRITE_U16(datagram->data, fsm->slave->current_state);
    fsm->retries = EC_FSM_RETRIES;
    fsm->state = ec_fsm_change_state_ack;
}

/*****************************************************************************/

/**
   Change state: ACK.
*/

void ec_fsm_change_state_ack(ec_fsm_change_t *fsm /**< finite state machine */)
{
    ec_datagram_t *datagram = fsm->datagram;
    ec_slave_t *slave = fsm->slave;

    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
        return;

    if (datagram->state != EC_DATAGRAM_RECEIVED) {
        fsm->state = ec_fsm_change_state_error;
        EC_SLAVE_ERR(slave, "Failed to receive state ack datagram: ");
        ec_datagram_print_state(datagram);
        return;
    }

    if (datagram->working_counter != 1) {
        fsm->state = ec_fsm_change_state_error;
        EC_SLAVE_ERR(slave, "Reception of state ack datagram failed: ");
        ec_datagram_print_wc_error(datagram);
        return;
    }

    fsm->take_time = 1;

    // read new AL status
    ec_datagram_fprd(datagram, slave->station_address, 0x0130, 2);
    ec_datagram_zero(datagram);
    fsm->retries = EC_FSM_RETRIES;
    fsm->state = ec_fsm_change_state_check_ack;
}

/*****************************************************************************/

/**
   Change state: CHECK ACK.
*/

void ec_fsm_change_state_check_ack(ec_fsm_change_t *fsm
                                   /**< finite state machine */)
{
    ec_datagram_t *datagram = fsm->datagram;
    ec_slave_t *slave = fsm->slave;

    if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
        return;

    if (datagram->state != EC_DATAGRAM_RECEIVED) {
        fsm->state = ec_fsm_change_state_error;
        EC_SLAVE_ERR(slave, "Failed to receive state ack check datagram: ");
        ec_datagram_print_state(datagram);
        return;
    }

    if (datagram->working_counter != 1) {
        fsm->state = ec_fsm_change_state_error;
        EC_SLAVE_ERR(slave, "Reception of state ack check datagram failed: ");
        ec_datagram_print_wc_error(datagram);
        return;
    }

    if (fsm->take_time) {
        fsm->take_time = 0;
        fsm->jiffies_start = datagram->jiffies_sent;
    }

    slave->current_state = EC_READ_U8(datagram->data);

    if (!(slave->current_state & EC_SLAVE_STATE_ACK_ERR)) {
        char state_str[EC_STATE_STRING_SIZE];
        ec_state_string(slave->current_state, state_str, 0);
        if (fsm->mode == EC_FSM_CHANGE_MODE_FULL) {
            fsm->state = ec_fsm_change_state_error;
        }
        else { // EC_FSM_CHANGE_MODE_ACK_ONLY
            fsm->state = ec_fsm_change_state_end;
        }
        EC_SLAVE_INFO(slave, "Acknowledged state %s.\n", state_str);
        return;
    }

    if (datagram->jiffies_received - fsm->jiffies_start >=
            EC_AL_STATE_CHANGE_TIMEOUT * HZ) {
        // timeout while checking
        char state_str[EC_STATE_STRING_SIZE];
        ec_state_string(slave->current_state, state_str, 0);
        fsm->state = ec_fsm_change_state_error;
        EC_SLAVE_ERR(slave, "Timeout while acknowledging state %s.\n",
                state_str);
        return;
    }

    // reread new AL status
    ec_datagram_fprd(datagram, slave->station_address, 0x0130, 2);
    ec_datagram_zero(datagram);
    fsm->retries = EC_FSM_RETRIES;
}

/*****************************************************************************/

/**
   State: ERROR.
*/

void ec_fsm_change_state_error(ec_fsm_change_t *fsm
                               /**< finite state machine */)
{
}

/*****************************************************************************/

/**
   State: END.
*/

void ec_fsm_change_state_end(ec_fsm_change_t *fsm
                             /**< finite state machine */)
{
}

/*****************************************************************************/


<|start_filename|>kernel/modules/raw_led/led.c<|end_filename|>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>

#include <linux/fs.h>
#include <linux/cdev.h>

#include <linux/ioctl.h>
#include <linux/uaccess.h>
#include <linux/slab.h>

#include <linux/io.h>
#include <linux/ioport.h>

#include "led.h"

#define LED_MAJOR 255
#define LED_MINOR 0
#define LED_DEV_CNT 1
#define LED_DEV_NAME "led"

/* SFR寄存器基地址 */
#define GPIO_BASE (0x01C20800)
#define GPG_BASE (GPIO_BASE + 0x24 * 6)

struct led_dev
{
    struct cdev cdev;
    atomic_t available;
    unsigned int __iomem *pgcfg; /* SFR映射后的虚拟地址 */
    unsigned int __iomem *pgdata;
};

static struct led_dev *led;

static int led_open(struct inode *inode, struct file *filp)
{
    if (atomic_dec_and_test(&led->available))
    {
        return 0;
    }
    else
    {
        atomic_inc(&led->available);
        return -EBUSY;
    }
}

static int led_release(struct inode *inode, struct file *filp)
{
    /* 熄灭LED */
    writel(readl(led->pgdata) & ~(0x7 << 0), led->pgdata);
    atomic_inc(&led->available);
    return 0;
}

static long led_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
    if (_IOC_TYPE(cmd) != LED_MAGIC)
    {
        return -ENOTTY;
    }
    switch (cmd)
    {
    case LED_ON:
        switch (arg)
        {
        case LED_RED:
            writel(readl(led->pgdata) | (0x1 << 0), led->pgdata);
            break;
        case LED_GREEN:
            writel(readl(led->pgdata) | (0x1 << 1), led->pgdata);
            break;
        case LED_BLUE:
            writel(readl(led->pgdata) | (0x1 << 2), led->pgdata);
            break;
        default:
            return -ENOTTY;
        }
        break;
    case LED_OFF:
        switch (arg)
        {
        case LED_RED:
            writel(readl(led->pgdata) & ~(0x1 << 0), led->pgdata);
            break;
        case LED_GREEN:
            writel(readl(led->pgdata) & ~(0x1 << 1), led->pgdata);
            break;
        case LED_BLUE:
            writel(readl(led->pgdata) & ~(0x1 << 2), led->pgdata);
            break;
        default:
            return -ENOTTY;
        }
        break;
    default:
        return -ENOTTY;
    }
    return 0;
}

static struct file_operations led_ops = {
    .owner = THIS_MODULE,
    .open = led_open,
    .release = led_release,
    .unlocked_ioctl = led_ioctl,
};

/* 模块初始化函数 */
static int __init led_init(void)
{
    int ret;
    dev_t dev;

    dev = MKDEV(LED_MAJOR, LED_MINOR);
    ret = register_chrdev_region(dev, LED_DEV_CNT, LED_DEV_NAME);
    if (ret)
    {
        goto reg_err;
    }

    led = kzalloc(sizeof(struct led_dev), GFP_KERNEL);
    if (!led)
    {
        ret = -ENOMEM;
        goto mem_err;
    }

    /* 初始化cdev对象，绑定ops */
    cdev_init(&led->cdev, &led_ops);
    led->cdev.owner = THIS_MODULE;

    /* 添加到内核中的cdev_map散列表中 */
    ret = cdev_add(&led->cdev, dev, LED_DEV_CNT);
    if (ret)
    {
        goto add_err;
    }

    atomic_set(&led->available, 1);

    /* SFR映射操作 */
    led->pgcfg = ioremap(GPG_BASE, 36);
    if (led->pgcfg)
    {
        ret = -EBUSY;
        goto map_err;
    }
    led->pgdata = led->pgcfg + 4;

    /* 初始化PG0，PG1，PG2为输出模式 */
    writel((readl(led->pgcfg) & ~(0x777 << 0)) | (0x111 << 0), led->pgcfg);
    /* 熄灭LED */
    writel(readl(led->pgdata) & ~(0x7 << 0), led->pgdata);
    return 0;

map_err:
    cdev_del(&led->cdev);
add_err:
    kfree(led);
mem_err:
    unregister_chrdev_region(dev, LED_DEV_CNT);
reg_err:
    return ret;
}

/* 模块清理函数 */
static void __exit led_exit(void)
{
    dev_t dev;

    dev = MKDEV(LED_MAJOR, LED_MINOR);
    /* 解除IO内存映射 */
    iounmap(led->pgcfg);

    cdev_del(&led->cdev);
    kfree(led);
    unregister_chrdev_region(dev, LED_DEV_CNT);
}

/* 为模块初始化函数和清理函数取别名 */
module_init(led_init);
module_exit(led_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("suda-morris <<EMAIL>>");
MODULE_DESCRIPTION("A simple module");
MODULE_ALIAS("raw-led");

<|start_filename|>rootfs/buildroot-2017.11.1/package/openpowerlink/openpowerlink.mk<|end_filename|>
################################################################################
#
# openpowerlink
#
################################################################################

OPENPOWERLINK_VERSION = V2.6.1
OPENPOWERLINK_SITE = http://downloads.sourceforge.net/project/openpowerlink/openPOWERLINK/$(OPENPOWERLINK_VERSION)
OPENPOWERLINK_SOURCE = openPOWERLINK_$(OPENPOWERLINK_VERSION).tar.gz
OPENPOWERLINK_LICENSE = BSD-2-Clause, GPL-2.0
OPENPOWERLINK_LICENSE_FILES = license.md

OPENPOWERLINK_INSTALL_STAGING = YES

# The archive has no leading component.
OPENPOWERLINK_STRIP_COMPONENTS = 0

OPENPOWERLINK_MN_ONOFF = $(if $(BR2_PACKAGE_OPENPOWERLINK_MN),ON,OFF)
OPENPOWERLINK_CN_ONOFF = $(if $(BR2_PACKAGE_OPENPOWERLINK_CN),ON,OFF)

#### OPLK LIBRARY ####

# Always build a oplk stack
# Disable library with simulation interface
# Disable zynq/FPGA (PCIe) interface
OPENPOWERLINK_CONF_OPTS += -DCFG_OPLK_LIB=ON \
	-DCFG_COMPILE_LIB_MN_SIM=OFF \
	-DCFG_COMPILE_LIB_CN_SIM=OFF \
	-DCFG_COMPILE_LIB_MNAPP_ZYNQINTF=OFF

# All option are ON by default
ifeq ($(BR2_PACKAGE_OPENPOWERLINK_STACK_MONOLITHIC_USER_STACK_LIB),y)
OPENPOWERLINK_DEPENDENCIES += libpcap
OPENPOWERLINK_CONF_OPTS += \
	-DCFG_COMPILE_LIB_MN=$(OPENPOWERLINK_MN_ONOFF) \
	-DCFG_COMPILE_LIB_MNAPP_USERINTF=OFF \
	-DCFG_COMPILE_LIB_MNAPP_KERNELINTF=OFF \
	-DCFG_COMPILE_LIB_MNAPP_PCIEINTF=OFF \
	-DCFG_COMPILE_LIB_MNDRV_PCAP=OFF \
	-DCFG_COMPILE_LIB_CN=$(OPENPOWERLINK_CN_ONOFF) \
	-DCFG_COMPILE_LIB_CNAPP_USERINTF=OFF \
	-DCFG_COMPILE_LIB_CNAPP_KERNELINTF=OFF \
	-DCFG_COMPILE_LIB_CNDRV_PCAP=OFF \
	-DPCAP_CONFIG="$(STAGING_DIR)/usr/bin/pcap-config"
else ifeq ($(BR2_PACKAGE_OPENPOWERLINK_STACK_USERSPACE_DAEMON_LIB),y)
OPENPOWERLINK_DEPENDENCIES += libpcap
OPENPOWERLINK_CONF_OPTS += \
	-DCFG_COMPILE_LIB_MN=OFF \
	-DCFG_COMPILE_LIB_MNAPP_USERINTF=$(OPENPOWERLINK_MN_ONOFF) \
	-DCFG_COMPILE_LIB_MNAPP_KERNELINTF=OFF \
	-DCFG_COMPILE_LIB_MNAPP_PCIEINTF=OFF \
	-DCFG_COMPILE_LIB_MNDRV_PCAP=$(OPENPOWERLINK_MN_ONOFF) \
	-DCFG_COMPILE_LIB_CN=OFF \
	-DCFG_COMPILE_LIB_CNAPP_USERINTF=$(OPENPOWERLINK_CN_ONOFF) \
	-DCFG_COMPILE_LIB_CNAPP_KERNELINTF=OFF \
	-DCFG_COMPILE_LIB_CNDRV_PCAP=$(OPENPOWERLINK_CN_ONOFF) \
	-DPCAP_CONFIG="$(STAGING_DIR)/usr/bin/pcap-config"
else ifeq ($(BR2_PACKAGE_OPENPOWERLINK_STACK_KERNEL_STACK_LIB),y)
OPENPOWERLINK_CONF_OPTS += \
	-DCFG_COMPILE_LIB_MN=OFF \
	-DCFG_COMPILE_LIB_MNAPP_USERINTF=OFF \
	-DCFG_COMPILE_LIB_MNAPP_KERNELINTF=$(OPENPOWERLINK_MN_ONOFF) \
	-DCFG_COMPILE_LIB_MNAPP_PCIEINTF=OFF \
	-DCFG_COMPILE_LIB_MNDRV_PCAP=OFF \
	-DCFG_COMPILE_LIB_CN=OFF \
	-DCFG_COMPILE_LIB_CNAPP_USERINTF=OFF \
	-DCFG_COMPILE_LIB_CNAPP_KERNELINTF=$(OPENPOWERLINK_CN_ONOFF) \
	-DCFG_COMPILE_LIB_CNDRV_PCAP=OFF
else ifeq ($(BR2_PACKAGE_OPENPOWERLINK_STACK_KERNEL_PCIE_STACK_LIB),y)
OPENPOWERLINK_CONF_OPTS += \
	-DCFG_COMPILE_LIB_MN=OFF \
	-DCFG_COMPILE_LIB_MNAPP_USERINTF=OFF \
	-DCFG_COMPILE_LIB_MNAPP_KERNELINTF=OFF \
	-DCFG_COMPILE_LIB_MNAPP_PCIEINTF=$(OPENPOWERLINK_MN_ONOFF) \
	-DCFG_COMPILE_LIB_MNDRV_PCAP=OFF \
	-DCFG_COMPILE_LIB_CN=OFF \
	-DCFG_COMPILE_LIB_CNAPP_USERINTF=OFF \
	-DCFG_COMPILE_LIB_CNAPP_KERNELINTF=OFF \
	-DCFG_COMPILE_LIB_CNDRV_PCAP=OFF
endif

OPENPOWERLINK_CONF_OPTS += \
	-DCFG_COMPILE_SHARED_LIBRARY=$(if $(BR2_STATIC_LIBS),OFF,ON)

#### OPLK KERNEL DRIVERS ####

ifeq ($(BR2_PACKAGE_OPENPOWERLINK_STACK_KERNEL_STACK_LIB)$(BR2_PACKAGE_OPENPOWERLINK_KERNEL_PCIE_DRIVER),y)
OPENPOWERLINK_DEPENDENCIES += linux

OPENPOWERLINK_CONF_OPTS += \
	-DCFG_KERNEL_DIR="$(LINUX_DIR)" \
	-DCMAKE_SYSTEM_VERSION="$(LINUX_VERSION)" \
	-DCFG_OPLK_MN="$(OPENPOWERLINK_MN_ONOFF)" \
	-DMAKE_KERNEL_ARCH="$(KERNEL_ARCH)" \
	-DMAKE_KERNEL_CROSS_COMPILE="$(CCACHE) $(TARGET_CROSS)"
endif

ifeq ($(BR2_PACKAGE_OPENPOWERLINK_STACK_KERNEL_STACK_LIB),y)
OPENPOWERLINK_CONF_OPTS += -DCFG_KERNEL_DRIVERS=ON \
	-DCFG_POWERLINK_EDRV_82573=$(if $(BR2_PACKAGE_OPENPOWERLINK_KERNEL_DRIVER_82573),ON,OFF) \
	-DCFG_POWERLINK_EDRV_8255X=$(if $(BR2_PACKAGE_OPENPOWERLINK_KERNEL_DRIVER_8255x),ON,OFF) \
	-DCFG_POWERLINK_EDRV_I210=$(if $(BR2_PACKAGE_OPENPOWERLINK_KERNEL_DRIVER_I210),ON,OFF) \
	-DCFG_POWERLINK_EDRV_8111=$(if $(BR2_PACKAGE_OPENPOWERLINK_KERNEL_DRIVER_RTL8111),ON,OFF) \
	-DCFG_POWERLINK_EDRV_8139=$(if $(BR2_PACKAGE_OPENPOWERLINK_KERNEL_DRIVER_RTL8139),ON,OFF)
else
OPENPOWERLINK_CONF_OPTS += -DCFG_KERNEL_DRIVERS=OFF
endif

ifeq ($(BR2_PACKAGE_OPENPOWERLINK_KERNEL_PCIE_DRIVER),y)
OPENPOWERLINK_CONF_OPTS += -DCFG_KERNEL_PCIE_DRIVERS=ON
else
OPENPOWERLINK_CONF_OPTS += -DCFG_KERNEL_PCIE_DRIVERS=OFF
endif

#### OPLK PCAP DAEMON ####

ifeq ($(BR2_PACKAGE_OPENPOWERLINK_STACK_USERSPACE_DAEMON_LIB),y)
OPENPOWERLINK_CONF_OPTS += \
	-DCFG_PCAP_DAEMON=ON \
	-DCFG_OPLK_MN=$(OPENPOWERLINK_MN_ONOFF)
endif

#### OPLK DEMO APPS ####

# See apps/common/cmake/configure-linux.cmake for available options list.
ifeq ($(BR2_PACKAGE_OPENPOWERLINK_STACK_MONOLITHIC_USER_STACK_LIB),y)
OPENPOWERLINK_CONF_OPTS += \
	-DCFG_BUILD_KERNEL_STACK="Link to Application"
else ifeq ($(BR2_PACKAGE_OPENPOWERLINK_STACK_USERSPACE_DAEMON_LIB),y)
OPENPOWERLINK_CONF_OPTS += \
	-DCFG_BUILD_KERNEL_STACK="Linux Userspace Daemon"
else ifeq ($(BR2_PACKAGE_OPENPOWERLINK_STACK_KERNEL_STACK_LIB),y)
OPENPOWERLINK_CONF_OPTS += \
	-DCFG_BUILD_KERNEL_STACK="Linux Kernel Module"
else ifeq ($(BR2_PACKAGE_OPENPOWERLINK_STACK_KERNEL_PCIE_STACK_LIB),y)
OPENPOWERLINK_CONF_OPTS += \
	-DCFG_BUILD_KERNEL_STACK="Kernel stack on PCIe card"
endif

ifeq ($(BR2_PACKAGE_OPENPOWERLINK_DEMO_MN_CONSOLE),y)
OPENPOWERLINK_CONF_OPTS += -DCFG_DEMO_MN_CONSOLE=ON \
	-DCFG_DEMO_MN_CONSOLE_USE_SYNCTHREAD=ON
else
OPENPOWERLINK_CONF_OPTS += -DCFG_DEMO_MN_CONSOLE=OFF
endif

ifeq ($(BR2_PACKAGE_OPENPOWERLINK_DEMO_CN_CONSOLE),y)
OPENPOWERLINK_CONF_OPTS += -DCFG_DEMO_CN_CONSOLE=ON
else
OPENPOWERLINK_CONF_OPTS += -DCFG_DEMO_CN_CONSOLE=OFF
endif

$(eval $(cmake-package))


<|start_filename|>3rdpart/ethercat-1.5.2/master/fsm_coe.h<|end_filename|>
/******************************************************************************
 *
 *  $Id: fsm_coe.h,v 9cdd7669dc0b 2013/01/10 16:36:41 fp $
 *
 *  Copyright (C) 2006-2008  <NAME>, Ingenieurgemeinschaft IgH
 *
 *  This file is part of the IgH EtherCAT Master.
 *
 *  The IgH EtherCAT Master is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License version 2, as
 *  published by the Free Software Foundation.
 *
 *  The IgH EtherCAT Master is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 *  Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with the IgH EtherCAT Master; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 *****************************************************************************/

/**
   \file
   EtherCAT CoE state machines.
*/

/*****************************************************************************/

#ifndef __EC_FSM_COE_H__
#define __EC_FSM_COE_H__

#include "globals.h"
#include "datagram.h"
#include "slave.h"
#include "sdo.h"
#include "sdo_request.h"

/*****************************************************************************/

typedef struct ec_fsm_coe ec_fsm_coe_t; /**< \see ec_fsm_coe */

/** Finite state machines for the CANopen over EtherCAT protocol.
 */
struct ec_fsm_coe {
    ec_slave_t *slave; /**< slave the FSM runs on */
    unsigned int retries; /**< retries upon datagram timeout */

    void (*state)(ec_fsm_coe_t *, ec_datagram_t *); /**< CoE state function */
    ec_datagram_t *datagram; /**< Datagram used in last step. */
    unsigned long jiffies_start; /**< CoE timestamp. */
    ec_sdo_t *sdo; /**< current SDO */
    uint8_t subindex; /**< current subindex */
    ec_sdo_request_t *request; /**< SDO request */
    uint32_t complete_size; /**< Used when segmenting. */
    uint8_t toggle; /**< toggle bit for segment commands */
    uint32_t offset; /**< Data offset during segmented download. */
    uint32_t remaining; /**< Remaining bytes during segmented download. */
    size_t segment_size; /**< Current segment size. */
};

/*****************************************************************************/

void ec_fsm_coe_init(ec_fsm_coe_t *);
void ec_fsm_coe_clear(ec_fsm_coe_t *);

void ec_fsm_coe_dictionary(ec_fsm_coe_t *, ec_slave_t *);
void ec_fsm_coe_transfer(ec_fsm_coe_t *, ec_slave_t *, ec_sdo_request_t *);

int ec_fsm_coe_exec(ec_fsm_coe_t *, ec_datagram_t *);
int ec_fsm_coe_success(const ec_fsm_coe_t *);

/*****************************************************************************/

#endif


<|start_filename|>3rdpart/tslib-1.15/plugins/collie-raw.c<|end_filename|>
/*
 * SPDX-License-Identifier: LGPL-2.1
 */
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>

#include "config.h"
#include "tslib-private.h"

struct collie_ts_event { /* Used in the Sharp Zaurus SL-5000d and SL-5500 */
	long y;
	long x;
	long pressure;
	long long millisecs;
};

static int collie_read(struct tslib_module_info *inf, struct ts_sample *samp, int nr)
{
	struct tsdev *ts = inf->dev;
	struct collie_ts_event *collie_evt;
	int ret;
	int nr_read;

	collie_evt = alloca(sizeof(*collie_evt) * nr);
	ret = read(ts->fd, collie_evt, sizeof(*collie_evt) * nr);
	if (ret > 0) {
		nr_read = ret / sizeof(*collie_evt);
		while (ret >= (int)sizeof(*collie_evt)) {
			samp->x = collie_evt->x;
			samp->y = collie_evt->y;
			samp->pressure = collie_evt->pressure;
#ifdef DEBUG
	fprintf(stderr, "RAW---------------------------> %d %d %d\n",
		samp->x, samp->y, samp->pressure);
#endif /*DEBUG*/
			samp->tv.tv_usec = (collie_evt->millisecs % 1000) * 1000;
			samp->tv.tv_sec = collie_evt->millisecs / 1000;
			samp++;
			collie_evt++;
			ret -= sizeof(*collie_evt);
		}
	} else {
		return -1;
	}

	ret = nr_read;
	return ret;
}

static const struct tslib_ops collie_ops = {
	.read	= collie_read,
};

TSAPI struct tslib_module_info *collie_mod_init(__attribute__ ((unused)) struct tsdev *dev,
						__attribute__ ((unused)) const char *params)
{
	struct tslib_module_info *m;

	m = malloc(sizeof(struct tslib_module_info));
	if (m == NULL)
		return NULL;

	m->ops = &collie_ops;
	return m;
}

#ifndef TSLIB_STATIC_COLLIE_MODULE
	TSLIB_MODULE_INIT(collie_mod_init);
#endif


<|start_filename|>3rdpart/ethercat-1.5.2/tool/CommandVersion.cpp<|end_filename|>
/*****************************************************************************
 *
 *  $Id: CommandVersion.cpp,v 4f682084c643 2010/10/25 08:12:26 fp $
 *
 *  Copyright (C) 2006-2009  <NAME>, Ingenieurgemeinschaft IgH
 *
 *  This file is part of the IgH EtherCAT Master.
 *
 *  The IgH EtherCAT Master is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License version 2, as
 *  published by the Free Software Foundation.
 *
 *  The IgH EtherCAT Master is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 *  Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with the IgH EtherCAT Master; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 ****************************************************************************/

#include <iostream>
using namespace std;

#include "CommandVersion.h"

/*****************************************************************************/

CommandVersion::CommandVersion():
    Command("version", "Show version information.")
{
}

/****************************************************************************/

string CommandVersion::helpString(const string &binaryBaseName) const
{
    stringstream str;

    str << binaryBaseName << " " << getName() << " [OPTIONS]" << endl
        << endl
        << getBriefDescription() << endl;

    return str.str();
}

/****************************************************************************/

void CommandVersion::execute(const StringVector &args)
{
    if (args.size()) {
        stringstream err;
        err << "'" << getName() << "' takes no arguments!";
        throwInvalidUsageException(err);
    }

    cout << "IgH EtherCAT master " << EC_MASTER_VERSION << endl;
}

/*****************************************************************************/


<|start_filename|>3rdpart/ethercat-1.5.2/tool/CommandPdos.cpp<|end_filename|>
/*****************************************************************************
 *
 *  $Id: CommandPdos.cpp,v 960cc1bb6b4a 2012/10/24 16:21:52 fp $
 *
 *  Copyright (C) 2006-2009  <NAME>, Ingenieurgemeinschaft IgH
 *
 *  This file is part of the IgH EtherCAT Master.
 *
 *  The IgH EtherCAT Master is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License version 2, as
 *  published by the Free Software Foundation.
 *
 *  The IgH EtherCAT Master is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 *  Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with the IgH EtherCAT Master; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 ****************************************************************************/

#include <iostream>
#include <iomanip>
#include <cstring>
using namespace std;

#include "CommandPdos.h"
#include "MasterDevice.h"

/*****************************************************************************/

CommandPdos::CommandPdos():
    Command("pdos", "List Sync managers, PDO assignment and mapping.")
{
}

/*****************************************************************************/

string CommandPdos::helpString(const string &binaryBaseName) const
{
    stringstream str;

    str << binaryBaseName << " " << getName() << " [OPTIONS]" << endl
        << endl
        << getBriefDescription() << endl
        << endl
        << "For the default skin (see --skin option) the information" << endl
        << "is displayed in three layers, which are" << endl
        << "indented accordingly:" << endl
        << endl
        << "1) Sync managers - Contains the sync manager information" << endl
        << "   from the SII: Index, physical start address, default" << endl
        << "   size, control register and enable word. Example:" << endl
        << endl
        << "   SM3: PhysAddr 0x1100, DefaultSize 0, ControlRegister 0x20, "
        << "Enable 1" << endl
        << endl
        << "2) Assigned PDOs - PDO direction, hexadecimal index and" << endl
        << "   the PDO name, if avaliable. Note that a 'Tx' and 'Rx'" << endl
        << "   are seen from the slave's point of view. Example:" << endl
        << endl
        << "   TxPDO 0x1a00 \"Channel1\"" << endl
        << endl
        << "3) Mapped PDO entries - PDO entry index and subindex (both" << endl
        << "   hexadecimal), the length in bit and the description, if" << endl
        << "   available. Example:" << endl
        << endl
        << "   PDO entry 0x3101:01, 8 bit, \"Status\"" << endl
        << endl
        << "Note, that the displayed PDO assignment and PDO mapping" << endl
        << "information can either originate from the SII or from the" << endl
        << "CoE communication area." << endl
        << endl
        << "The \"etherlab\" skin outputs a template configuration" << endl
        << "for EtherLab's generic EtherCAT slave block." << endl
        << endl
        << "Command-specific options:" << endl
        << "  --alias    -a <alias>" << endl
        << "  --position -p <pos>    Slave selection. See the help of" << endl
        << "                         the 'slaves' command." << endl
        << "  --skin     -s <skin>   Choose output skin. Possible values are"
        << endl
        << "                         \"default\" and \"etherlab\"." << endl
        << endl
        << numericInfo();

    return str.str();
}

/****************************************************************************/

void CommandPdos::execute(const StringVector &args)
{
	MasterIndexList masterIndices;
    SlaveList slaves;
    SlaveList::const_iterator si;
    bool showHeader, multiMaster;

    if (args.size()) {
        stringstream err;
        err << "'" << getName() << "' takes no arguments!";
        throwInvalidUsageException(err);
    }

    if (getSkin().empty() || getSkin() == "default") {
        masterIndices = getMasterIndices();
        multiMaster = masterIndices.size() > 1;
        MasterIndexList::const_iterator mi;
        for (mi = masterIndices.begin();
                mi != masterIndices.end(); mi++) {
            MasterDevice m(*mi);
            m.open(MasterDevice::Read);
            slaves = selectedSlaves(m);
            showHeader = multiMaster || slaves.size() > 1;

            for (si = slaves.begin(); si != slaves.end(); si++) {
                listSlavePdos(m, *si, showHeader);
            }
        }
    }
    else if (getSkin() == "etherlab") {
        masterIndices = getMasterIndices();
        MasterIndexList::const_iterator mi;
        for (mi = masterIndices.begin();
                mi != masterIndices.end(); mi++) {
            MasterDevice m(*mi);
            m.open(MasterDevice::Read);
            slaves = selectedSlaves(m);

            for (si = slaves.begin(); si != slaves.end(); si++) {
                etherlabConfig(m, *si);
            }
        }
    }
    else {
        stringstream err;
        err << "Invalid skin '" << getSkin() << "'!";
        throwInvalidUsageException(err);
    }
}

/****************************************************************************/

void CommandPdos::listSlavePdos(
        MasterDevice &m,
        const ec_ioctl_slave_t &slave,
        bool showHeader
        )
{
    ec_ioctl_slave_sync_t sync;
    ec_ioctl_slave_sync_pdo_t pdo;
    ec_ioctl_slave_sync_pdo_entry_t entry;
    unsigned int i, j, k;

    if (showHeader && slave.sync_count)
        cout << "=== Master " << m.getIndex()
            << ", Slave " << slave.position << " ===" << endl;

    for (i = 0; i < slave.sync_count; i++) {
        m.getSync(&sync, slave.position, i);

        cout << "SM" << i << ":"
            << " PhysAddr 0x"
            << hex << setfill('0')
            << setw(4) << sync.physical_start_address
            << ", DefaultSize "
            << dec << setfill(' ') << setw(4) << sync.default_size
            << ", ControlRegister 0x"
            << hex << setfill('0') << setw(2)
            << (unsigned int) sync.control_register
            << ", Enable " << dec << (unsigned int) sync.enable
            << endl;

        for (j = 0; j < sync.pdo_count; j++) {
            m.getPdo(&pdo, slave.position, i, j);

            cout << "  " << (sync.control_register & 0x04 ? "R" : "T")
                << "xPDO 0x"
                << hex << setfill('0')
                << setw(4) << pdo.index
                << " \"" << pdo.name << "\"" << endl;

            if (getVerbosity() == Quiet)
                continue;

            for (k = 0; k < pdo.entry_count; k++) {
                m.getPdoEntry(&entry, slave.position, i, j, k);

                cout << "    PDO entry 0x"
                    << hex << setfill('0')
                    << setw(4) << entry.index
                    << ":" << setw(2) << (unsigned int) entry.subindex
                    << ", " << dec << setfill(' ')
                    << setw(2) << (unsigned int) entry.bit_length
                    << " bit, \"" << entry.name << "\"" << endl;
            }
        }
    }
}

/****************************************************************************/

void CommandPdos::etherlabConfig(
        MasterDevice &m,
        const ec_ioctl_slave_t &slave
        )
{
    ec_ioctl_slave_sync_t sync;
    ec_ioctl_slave_sync_pdo_t pdo;
    ec_ioctl_slave_sync_pdo_entry_t entry;
    unsigned int i, j, k;

    cout << "%" << endl
        << "% Master " << m.getIndex() << ", Slave " << slave.position;
    if (strlen(slave.order)) {
        cout << ", \"" << slave.order << "\"";
    }
    cout << endl
        << "%" << endl
        << "function rv = slave" << slave.position << "()" << endl << endl;

    cout << "% Slave configuration" << endl << endl;

    cout << "rv.SlaveConfig.vendor = " << slave.vendor_id << ";" << endl
        << "rv.SlaveConfig.product = hex2dec('"
        << hex << setfill('0') << setw(8) << slave.product_code << "');"
        << endl
        << "rv.SlaveConfig.description = '" << slave.order << "';" << endl
        << "rv.SlaveConfig.sm = { ..." << endl;

    /* slave configuration */
    for (i = 0; i < slave.sync_count; i++) {
        m.getSync(&sync, slave.position, i);

        cout << "    {" << dec << i << ", "
            << (sync.control_register & 0x04 ? 0 : 1) << ", {" << endl;

        for (j = 0; j < sync.pdo_count; j++) {
            m.getPdo(&pdo, slave.position, i, j);

            cout << "        {hex2dec('" <<
                hex << setfill('0') << setw(4) << pdo.index << "'), ["
                << endl;

            for (k = 0; k < pdo.entry_count; k++) {
                m.getPdoEntry(&entry, slave.position, i, j, k);

                cout << "            hex2dec('"
                    << hex << setfill('0') << setw(4) << entry.index
                    << "'), hex2dec('"
                    << setw(2) << (unsigned int) entry.subindex
                    << "'), " << dec << setfill(' ') << setw(3)
                    << (unsigned int) entry.bit_length
                    << "; ..." << endl;
            }

            cout << "            ]}, ..." << endl;
        }
        cout << "        }}, ..." << endl;
    }

    cout << "    };" << endl << endl;

    cout << "% Port configuration" << endl << endl;

    unsigned int input = 1, output = 1;
    for (i = 0; i < slave.sync_count; i++) {
        m.getSync(&sync, slave.position, i);

        for (j = 0; j < sync.pdo_count; j++) {
            m.getPdo(&pdo, slave.position, i, j);

            for (k = 0; k < pdo.entry_count; k++) {
                m.getPdoEntry(&entry, slave.position, i, j, k);

                if (!entry.index) {
                    continue;
                }

                string dir;
                unsigned int port;

                if (sync.control_register & 0x04) {
                    dir = "input";
                    port = input++;
                }
                else {
                    dir = "output";
                    port = output++;
                }

                stringstream var;
                var << "rv.PortConfig." << dir << "(" << dec << port
                    << ")";

                cout << var.str() << ".pdo = ["
                    << i << ", " << j << ", " << k << ", 0];" << endl;
                cout << var.str() << ".pdo_data_type = "
                    << 1000 + (unsigned int) entry.bit_length
                    << ";" << endl << endl;
            }
        }
    }

    cout << "end" << endl;
}

/*****************************************************************************/


<|start_filename|>kernel/modules/devmodel/vdrv.c<|end_filename|>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>

#include <linux/device.h>

/* 引用了vbus模块导出的符号vbus */
extern struct bus_type vbus;

/* 定义了vdrv对象，代表驱动 */
static struct device_driver vdrv = {
	.name = "vdrv",
	.bus = &vbus, //指明该驱动所属的总线，这样该驱动就会被注册在vbus总线下
};

static int __init vdrv_init(void)
{
	/* 注册驱动 */
	return driver_register(&vdrv);
}

static void __exit vdrv_exit(void)
{
	/* 注销驱动 */
	driver_unregister(&vdrv);
}

module_init(vdrv_init);
module_exit(vdrv_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("suda-morris <<EMAIL>>");
MODULE_DESCRIPTION("A virtual device driver");


<|start_filename|>3rdpart/tslib-1.15/plugins/skip.c<|end_filename|>
/*
 *  tslib/plugins/skip.c
 *
 * (C) 2017 <NAME> <<EMAIL>> (read_mt())
 * (C) 2008 by Openmoko, Inc.
 * Author: <NAME>
 *
 * This file is placed under the LGPL.  Please see the file
 * COPYING for more details.
 *
 * SPDX-License-Identifier: LGPL-2.1
 *
 *
 * Skip filter for touchscreen values.
 *
 * Problem: With some drivers the first and the last sample is reliable.
 *
 * Solution:
 *
 *  - Skip N points after pressure != 0
 *  - Skip M points before pressure == 0
 *  - Ignore a click if it has less than N + M + 1 points
 *
 * Parameters:
 *
 *  - nhead (means N)
 *  - ntail (means M)
 */

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <stdint.h>

#include "config.h"
#include "tslib.h"
#include "tslib-filter.h"

struct tslib_skip {
	struct tslib_module_info module;

	int nhead;
	int N;
	int *N_mt;

	int ntail;
	int M;
	int *M_mt;
	struct ts_sample *buf;
	struct ts_sample_mt **buf_mt;
	struct ts_sample_mt **cur_mt;
	int slots;
	int sent;
	int *sent_mt;
};

static void reset_skip(struct tslib_skip *s)
{
	s->N = 0;
	s->M = 0;
	s->sent = 0;
}

static void reset_skip_mt(struct tslib_skip *s, int slot)
{
	s->N_mt[slot] = 0;
	s->M_mt[slot] = 0;
	s->sent_mt[slot] = 0;
}

static int skip_read(struct tslib_module_info *info, struct ts_sample *samp,
		     int nr)
{
	struct tslib_skip *skip = (struct tslib_skip *)info;
	int nread = 0;

	while (nread < nr) {
		struct ts_sample cur;

		if (info->next->ops->read(info->next, &cur, 1) < 1)
			return nread;

		/* skip the first N samples */
		if (skip->N < skip->nhead) {
			skip->N++;
			if (cur.pressure == 0)
				reset_skip(skip);
			continue;
		}

		/* We didn't send DOWN -- Ignore UP */
		if (cur.pressure == 0 && skip->sent == 0) {
			reset_skip(skip);
			continue;
		}

		/* Just accept the sample if ntail is zero */
		if (skip->ntail == 0) {
			samp[nread++] = cur;
			skip->sent = 1;
			if (cur.pressure == 0)
				reset_skip(skip);
			continue;
		}

		/* ntail > 0,  Queue current point if we need to */
		if (skip->sent == 0 && skip->M < skip->ntail) {
			skip->buf[skip->M++] = cur;
			continue;
		}

		/* queue full, accept one, queue one */

		if (skip->M >= skip->ntail)
			skip->M = 0;

		if (cur.pressure == 0)
			skip->buf[skip->M].pressure = 0;

		samp[nread++] = skip->buf[skip->M];

#ifdef DEBUG
		fprintf(stderr, "SKIP---> (X:%d Y:%d) pressure:%d\n",
			skip->buf[skip->M].x, skip->buf[skip->M].y,
			skip->buf[skip->M].pressure);
#endif

		if (cur.pressure == 0) {
			reset_skip(skip);
		} else {
			skip->buf[skip->M++] = cur;
			skip->sent = 1;
		}
	}
	return nread;
}

static int skip_read_mt(struct tslib_module_info *info,
			struct ts_sample_mt **samp, int max_slots, int nr)
{
	struct tslib_skip *skip = (struct tslib_skip *)info;
	int nread = 0;
	int i, j;
	int ret = 0;
	int count = 0;
	int count_current = 0;

	if (skip->cur_mt == NULL || max_slots > skip->slots) {
		if (skip->cur_mt) {
			if (skip->cur_mt[0])
				free(skip->cur_mt[0]);

			free(skip->cur_mt);
		}

		skip->cur_mt = malloc(sizeof(struct ts_sample_mt *));
		if (!skip->cur_mt)
			return -ENOMEM;

		skip->cur_mt[0] = calloc(max_slots,
					 sizeof(struct ts_sample_mt));
		if (!skip->cur_mt[0]) {
			if (skip->cur_mt)
				free(skip->cur_mt);

			return -ENOMEM;
		}

		skip->slots = max_slots;
	}
	memset(skip->cur_mt[0], 0, max_slots * sizeof(struct ts_sample_mt));

	if (skip->slots < max_slots || skip->buf_mt == NULL) {
		if (skip->buf_mt) {
			for (i = 0; i < skip->ntail; i++) {
				if (skip->buf_mt[i])
					free(skip->buf_mt[i]);
			}
			free(skip->buf_mt);
		}

		skip->buf_mt = malloc(skip->ntail *
				      sizeof(struct ts_sample_mt *));
		if (!skip->buf_mt) {
			free(skip->cur_mt[0]);
			free(skip->cur_mt);
			return -ENOMEM;
		}

		for (i = 0; i < skip->ntail; i++) {
			skip->buf_mt[i] = calloc(max_slots,
						 sizeof(struct ts_sample_mt));
			if (!skip->buf_mt[i]) {
				for (j = 0; j < i; j++)
					free(skip->buf_mt[j]);
				free(skip->buf_mt);
				free(skip->cur_mt[0]);
				free(skip->cur_mt);
				return -ENOMEM;
			}
		}

		skip->N_mt = calloc(max_slots, sizeof(int));
		if (!skip->N_mt) {
			for (i = 0; i < skip->ntail; i++)
				free(skip->buf_mt[i]);
			free(skip->buf_mt);
			free(skip->cur_mt[0]);
			free(skip->cur_mt);
			return -ENOMEM;
		}

		skip->M_mt = calloc(max_slots, sizeof(int));
		if (!skip->M_mt) {
			free(skip->N_mt);
			for (i = 0; i < skip->ntail; i++)
				free(skip->buf_mt[i]);
			free(skip->buf_mt);
			free(skip->cur_mt[0]);
			free(skip->cur_mt);
			return -ENOMEM;
		}

		skip->sent_mt = calloc(max_slots, sizeof(int));
		if (!skip->sent_mt) {
			free(skip->N_mt);
			free(skip->M_mt);
			for (i = 0; i < skip->ntail; i++)
				free(skip->buf_mt[i]);
			free(skip->buf_mt);
			free(skip->cur_mt[0]);
			free(skip->cur_mt);
			return -ENOMEM;
		}

		skip->slots = max_slots;
	}

	if (!info->next->ops->read_mt)
		return -ENOSYS;

	ret = info->next->ops->read_mt(info->next, samp, max_slots, nr);
	if (ret < 0)
		return ret;

#ifdef DEBUG
	printf("SKIP: read %d samples (%d slots)\n",
	       ret, max_slots);
#endif
	while (nread < ret) {
		count_current = 0;
		memcpy(skip->cur_mt[0], samp[count],
		       max_slots * sizeof(struct ts_sample_mt));
		for (i = 0; i < max_slots; i++) {
			if (!(skip->cur_mt[0][i].valid & TSLIB_MT_VALID))
				continue;

			/* skip the first N samples */
			if (skip->N_mt[i] < skip->nhead) {
			#ifdef DEBUG
				printf("SKIP: (slot %d) skip %d of %d samples\n",
				       i, skip->N_mt[i] + 1, skip->nhead);
			#endif
				skip->N_mt[i]++;
				if (skip->cur_mt[0][i].pressure == 0) {
					reset_skip_mt(skip, i);
				}

				skip->cur_mt[0][i].valid = 0;
				samp[count][i].valid = 0;
				continue;
			}

			/* We didn't send DOWN -- Ignore UP */
			if (skip->cur_mt[0][i].pressure == 0 &&
			    skip->sent_mt[i] == 0) {
			#ifdef DEBUG
				fprintf(stderr, "SKIP: (Slot %d) ignore up\n", i);
			#endif
				reset_skip_mt(skip, i);
				continue;
			}

			/* Just accept the sample if ntail is zero */
			if (skip->ntail == 0) {

				if (skip->sent_mt[i] == 0) {
					skip->cur_mt[0][i].pen_down = 1;
					skip->cur_mt[0][i].valid |= TSLIB_MT_VALID;
				}

				memcpy(&samp[count][i], &skip->cur_mt[0][i],
				       sizeof(struct ts_sample_mt));

				if (count_current == 0) {
					nread++;
				}
				count_current++;

				skip->sent_mt[i] = 1;
				if (skip->cur_mt[0][i].pressure == 0)
					reset_skip_mt(skip, i);
			#ifdef DEBUG
				fprintf(stderr,
					"SKIP: ntail 0 - sample accepted\n");
			#endif
				continue;
			}

			/* ntail > 0,  Queue current point if we need to */
			if (skip->sent_mt[i] == 0 && skip->M_mt[i] < skip->ntail) {
				skip->cur_mt[0][i].pen_down = 1;
				skip->cur_mt[0][i].valid |= TSLIB_MT_VALID;
				samp[count][i].valid = 0;

			#ifdef DEBUG
				fprintf(stderr,
					"SKIP: queue one sample to %d\n",
					skip->M_mt[i]);
			#endif
				memcpy(&skip->buf_mt[skip->M_mt[i]][i],
				       &skip->cur_mt[0][i],
				       sizeof(struct ts_sample_mt));
				skip->M_mt[i]++;
				continue;
			}
			/* queue full, accept one, queue one */
			if (skip->M_mt[i] >= skip->ntail)
				skip->M_mt[i] = 0;


			if (skip->cur_mt[0][i].pressure == 0) {
				skip->buf_mt[skip->M_mt[i]][i].pressure = 0;
				skip->buf_mt[skip->M_mt[i]][i].pen_down = 0;
				skip->buf_mt[skip->M_mt[i]][i].tracking_id = -1;
				skip->buf_mt[skip->M_mt[i]][i].valid |= TSLIB_MT_VALID;
			}

			memcpy(&samp[count][i], &skip->buf_mt[skip->M_mt[i]][i],
			       sizeof(struct ts_sample_mt));

	#ifdef DEBUG
			fprintf(stderr,
				"SKIP: (Slot %d) X:%4d Y:%4d pressure:%d btn_touch:%d\n",
				skip->buf_mt[skip->M_mt[i]][i].slot,
				skip->buf_mt[skip->M_mt[i]][i].x,
				skip->buf_mt[skip->M_mt[i]][i].y,
				skip->buf_mt[skip->M_mt[i]][i].pressure,
				skip->buf_mt[skip->M_mt[i]][i].pen_down);

	#endif
			if (count_current == 0) {
				nread++;
			}
			count_current++;

			if (skip->cur_mt[0][i].pressure == 0) {
				reset_skip_mt(skip, i);
			} else {
				memcpy(&skip->buf_mt[skip->M_mt[i]][i],
				       &skip->cur_mt[0][i],
				       sizeof(struct ts_sample_mt));


			#ifdef DEBUG
				fprintf(stderr,
					"SKIP: accept and queue one sample (slot %d) to %d\n", i, skip->M_mt[i]);
			#endif
				skip->sent_mt[i] = 1;
				skip->M_mt[i]++;
			}

		}
		count++;
		if (count == ret)
			break;


	}

	return nread;
}

static int skip_fini(struct tslib_module_info *info)
{
	struct tslib_skip *skip = (struct tslib_skip *)info;
	int i;

	if (skip->N_mt)
		free(skip->N_mt);

	if (skip->M_mt)
		free(skip->M_mt);

	if (skip->sent_mt)
		free(skip->sent_mt);

	if (skip->buf)
		free(skip->buf);

	if (skip->buf_mt) {
		for (i = 0; i < skip->ntail; i++) {
			if (skip->buf_mt[i])
				free(skip->buf_mt[i]);
		}
		free(skip->buf_mt);
	}

	if (skip->buf_mt)

	if (skip->cur_mt && skip->cur_mt[0])
		free(skip->cur_mt[0]);

	if (skip->cur_mt)
		free(skip->cur_mt);

	free(info);

	return 0;
}

static const struct tslib_ops skip_ops = {
	.read		= skip_read,
	.read_mt	= skip_read_mt,
	.fini		= skip_fini,
};

static int skip_opt(struct tslib_module_info *inf, char *str, void *data)
{
	struct tslib_skip *skip = (struct tslib_skip *)inf;
	unsigned long v;
	int err = errno;

	v = strtoul(str, NULL, 0);

	if (v == ULONG_MAX && errno == ERANGE)
		return -1;

	errno = err;

	switch ((int)(intptr_t)data) {
	case 1:
		skip->nhead = v;
		break;

	case 2:
		skip->ntail = v;
		break;

	default:
		return -1;
	}
	return 0;
}

static const struct tslib_vars skip_vars[] = {
	{ "nhead",      (void *)1, skip_opt },
	{ "ntail",      (void *)2, skip_opt },
};

#define NR_VARS (sizeof(skip_vars) / sizeof(skip_vars[0]))

TSAPI struct tslib_module_info *skip_mod_init(__attribute__ ((unused)) struct tsdev *dev,
					      const char *params)
{
	struct tslib_skip *skip;

	skip = malloc(sizeof(struct tslib_skip));
	if (skip == NULL)
		return NULL;

	memset(skip, 0, sizeof(struct tslib_skip));
	skip->module.ops = &skip_ops;

	skip->nhead = 1; /* by default remove the first */
	skip->ntail = 1; /* by default remove the last */
	skip->buf = NULL;
	skip->buf_mt = NULL;
	skip->cur_mt = NULL;
	skip->slots = 0;
	skip->N_mt = NULL;
	skip->M_mt = NULL;
	skip->sent_mt = NULL;

	reset_skip(skip);

	if (tslib_parse_vars(&skip->module, skip_vars, NR_VARS, params)) {
		free(skip);
		return NULL;
	}

	if (skip->ntail &&
	    !(skip->buf = malloc(sizeof(struct ts_sample) * skip->ntail))) {
		free(skip);
		return NULL;
	}

	return &skip->module;
}

#ifndef TSLIB_STATIC_SKIP_MODULE
	TSLIB_MODULE_INIT(skip_mod_init);
#endif


<|start_filename|>3rdpart/ethercat-1.5.2/master/sdo_request.h<|end_filename|>
/******************************************************************************
 *
 *  $Id: sdo_request.h,v fa52128477f6 2012/10/04 08:07:52 fp $
 *
 *  Copyright (C) 2006-2008  <NAME>, Ingenieurgemeinschaft IgH
 *
 *  This file is part of the IgH EtherCAT Master.
 *
 *  The IgH EtherCAT Master is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License version 2, as
 *  published by the Free Software Foundation.
 *
 *  The IgH EtherCAT Master is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 *  Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with the IgH EtherCAT Master; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 *****************************************************************************/

/**
   \file
   EtherCAT CANopen SDO request structure.
*/

/*****************************************************************************/

#ifndef __EC_SDO_REQUEST_H__
#define __EC_SDO_REQUEST_H__

#include <linux/list.h>

#include "globals.h"

/*****************************************************************************/

/** CANopen SDO request.
 */
struct ec_sdo_request {
    struct list_head list; /**< List item. */
    uint16_t index; /**< SDO index. */
    uint8_t subindex; /**< SDO subindex. */
    uint8_t *data; /**< Pointer to SDO data. */
    size_t mem_size; /**< Size of SDO data memory. */
    size_t data_size; /**< Size of SDO data. */
    uint8_t complete_access; /**< SDO shall be transferred completely. */
    uint32_t issue_timeout; /**< Maximum time in ms, the processing of the
                              request may take. */
    uint32_t response_timeout; /**< Maximum time in ms, the transfer is
                                 retried, if the slave does not respond. */
    ec_direction_t dir; /**< Direction. EC_DIR_OUTPUT means downloading to
                          the slave, EC_DIR_INPUT means uploading from the
                          slave. */
    ec_internal_request_state_t state; /**< SDO request state. */
    unsigned long jiffies_start; /**< Jiffies, when the request was issued. */
    unsigned long jiffies_sent; /**< Jiffies, when the upload/download
                                     request was sent. */
    int errno; /**< Error number. */
    uint32_t abort_code; /**< SDO request abort code. Zero on success. */
};

/*****************************************************************************/

void ec_sdo_request_init(ec_sdo_request_t *);
void ec_sdo_request_clear(ec_sdo_request_t *);

int ec_sdo_request_copy(ec_sdo_request_t *, const ec_sdo_request_t *);
int ec_sdo_request_alloc(ec_sdo_request_t *, size_t);
int ec_sdo_request_copy_data(ec_sdo_request_t *, const uint8_t *, size_t);
int ec_sdo_request_timed_out(const ec_sdo_request_t *);

/*****************************************************************************/

#endif


<|start_filename|>3rdpart/ethercat-1.5.2/examples/xenomai_posix/Makefile<|end_filename|>
# Makefile.in generated by automake 1.11.1 from Makefile.am.
# examples/xenomai_posix/Makefile.  Generated from Makefile.in by configure.

# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
# Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.



#------------------------------------------------------------------------------
#
#  $Id$
#
#  Copyright (C) 2006-2012  <NAME>, Ingenieurgemeinschaft IgH
#
#  This file is part of the IgH EtherCAT Master.
#
#  The IgH EtherCAT Master is free software; you can redistribute it and/or
#  modify it under the terms of the GNU General Public License version 2, as
#  published by the Free Software Foundation.
#
#  The IgH EtherCAT Master is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
#  Public License for more details.
#
#  You should have received a copy of the GNU General Public License along with
#  the IgH EtherCAT Master; if not, write to the Free Software Foundation,
#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
#
#  ---
#
#  The license mentioned above concerns the source code only. Using the
#  EtherCAT technology and brand is only permitted in compliance with the
#  industrial property and similar rights of Beckhoff Automation GmbH.
#
#------------------------------------------------------------------------------


pkgdatadir = $(datadir)/ethercat
pkgincludedir = $(includedir)/ethercat
pkglibdir = $(libdir)/ethercat
pkglibexecdir = $(libexecdir)/ethercat
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = x86_64-unknown-linux-gnu
host_triplet = arm-unknown-linux-gnueabihf
noinst_PROGRAMS = ec_xenomai_posix_example$(EXEEXT)
subdir = examples/xenomai_posix
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
	$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
	$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
	$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
	$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
PROGRAMS = $(noinst_PROGRAMS)
am_ec_xenomai_posix_example_OBJECTS =  \
	ec_xenomai_posix_example-main.$(OBJEXT)
ec_xenomai_posix_example_OBJECTS =  \
	$(am_ec_xenomai_posix_example_OBJECTS)
ec_xenomai_posix_example_LDADD = $(LDADD)
ec_xenomai_posix_example_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
	$(LIBTOOLFLAGS) --mode=link $(CCLD) \
	$(ec_xenomai_posix_example_CFLAGS) $(CFLAGS) \
	$(ec_xenomai_posix_example_LDFLAGS) $(LDFLAGS) -o $@
DEFAULT_INCLUDES = -I. -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/autoconf/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
	--mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
	--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
	$(LDFLAGS) -o $@
SOURCES = $(ec_xenomai_posix_example_SOURCES)
DIST_SOURCES = $(ec_xenomai_posix_example_SOURCES)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = ${SHELL} /home/morris/SUDA_V3S/3rdpart/ethercat-1.5.2/autoconf/missing --run aclocal-1.11
AMTAR = ${SHELL} /home/morris/SUDA_V3S/3rdpart/ethercat-1.5.2/autoconf/missing --run tar
AR = arm-linux-gnueabihf-ar
AUTOCONF = ${SHELL} /home/morris/SUDA_V3S/3rdpart/ethercat-1.5.2/autoconf/missing --run autoconf
AUTOHEADER = ${SHELL} /home/morris/SUDA_V3S/3rdpart/ethercat-1.5.2/autoconf/missing --run autoheader
AUTOMAKE = ${SHELL} /home/morris/SUDA_V3S/3rdpart/ethercat-1.5.2/autoconf/missing --run automake-1.11
AWK = gawk
CC = arm-linux-gnueabihf-gcc
CCDEPMODE = depmode=gcc3
CFLAGS = -g -O2
CPP = arm-linux-gnueabihf-gcc -E
CPPFLAGS = 
CXX = arm-linux-gnueabihf-g++
CXXCPP = arm-linux-gnueabihf-g++ -E
CXXDEPMODE = depmode=gcc3
CXXFLAGS = -g -O2
CYGPATH_W = echo
DEFS = -DHAVE_CONFIG_H
DEPDIR = .deps
DLLTOOL = false
DSYMUTIL = 
DUMPBIN = 
E1000E_LAYOUT_3_4 = 0
ECHO_C = 
ECHO_N = -n
ECHO_T = 
EGREP = /bin/grep -E
ENABLE_8139TOO = 0
ENABLE_DEBUG_IF = 0
ENABLE_E100 = 0
ENABLE_E1000 = 0
ENABLE_E1000E = 0
ENABLE_EOE = 1
ENABLE_GENERIC = 1
ENABLE_R8169 = 0
ENABLE_RTAI = 0
ENABLE_RTDM = 0
ENABLE_TTY = 0
ENABLE_XENOMAI = 0
EXEEXT = 
FGREP = /bin/grep -F
GREP = /bin/grep
INSTALL = /usr/bin/install -c
INSTALL_DATA = ${INSTALL} -m 644
INSTALL_MOD_DIR = ethercat
INSTALL_PROGRAM = ${INSTALL}
INSTALL_SCRIPT = ${INSTALL}
INSTALL_STRIP_PROGRAM = $(install_sh) -c -s
KERNEL_8139TOO = 4.13
KERNEL_E100 = 4.13
KERNEL_E1000 = 4.13
KERNEL_E1000E = 4.13
KERNEL_R8169 = 4.13
LD = arm-linux-gnueabihf-ld
LDFLAGS = 
LIBOBJS = 
LIBS = 
LIBTOOL = $(SHELL) $(top_builddir)/libtool
LINUX_SOURCE_DIR = /home/morris/SUDA_V3S/kernel/linux-zero-4.13.y/
LIPO = 
LN_S = ln -s
LTLIBOBJS = 
MAKEINFO = ${SHELL} /home/morris/SUDA_V3S/3rdpart/ethercat-1.5.2/autoconf/missing --run makeinfo
MANIFEST_TOOL = :
MKDIR_P = /bin/mkdir -p
NM = arm-linux-gnueabihf-nm
NMEDIT = 
OBJDUMP = arm-linux-gnueabihf-objdump
OBJEXT = o
OTOOL = 
OTOOL64 = 
PACKAGE = ethercat
PACKAGE_BUGREPORT = <EMAIL>
PACKAGE_NAME = ethercat
PACKAGE_STRING = ethercat 1.5.2
PACKAGE_TARNAME = ethercat
PACKAGE_URL = 
PACKAGE_VERSION = 1.5.2
PATH_SEPARATOR = :
RANLIB = arm-linux-gnueabihf-ranlib
RTAI_DIR = 
RTAI_LXRT_CFLAGS = 
RTAI_LXRT_LDFLAGS = 
SED = /bin/sed
SET_MAKE = 
SHELL = /bin/bash
STRIP = arm-linux-gnueabihf-strip
VERSION = 1.5.2
XENOMAI_DIR = 
XENOMAI_NATIVE_CFLAGS = 
XENOMAI_NATIVE_LDFLAGS = 
XENOMAI_POSIX_CFLAGS = 
XENOMAI_POSIX_LDFLAGS = 
XENOMAI_RTDM_CFLAGS = 
XENOMAI_RTDM_LDFLAGS = 
abs_builddir = /home/morris/SUDA_V3S/3rdpart/ethercat-1.5.2/examples/xenomai_posix
abs_srcdir = /home/morris/SUDA_V3S/3rdpart/ethercat-1.5.2/examples/xenomai_posix
abs_top_builddir = /home/morris/SUDA_V3S/3rdpart/ethercat-1.5.2
abs_top_srcdir = /home/morris/SUDA_V3S/3rdpart/ethercat-1.5.2
ac_ct_AR = 
ac_ct_CC = 
ac_ct_CXX = 
ac_ct_DUMPBIN = 
am__include = include
am__leading_dot = .
am__quote = 
am__tar = ${AMTAR} chof - "$$tardir"
am__untar = ${AMTAR} xf -
bindir = ${exec_prefix}/bin
build = x86_64-unknown-linux-gnu
build_alias = 
build_cpu = x86_64
build_os = linux-gnu
build_vendor = unknown
builddir = .
datadir = ${datarootdir}
datarootdir = ${prefix}/share
docdir = ${datarootdir}/doc/${PACKAGE_TARNAME}
dvidir = ${docdir}
exec_prefix = ${prefix}
host = arm-unknown-linux-gnueabihf
host_alias = arm-linux-gnueabihf
host_cpu = arm
host_os = linux-gnueabihf
host_vendor = unknown
htmldir = ${docdir}
includedir = ${prefix}/include
infodir = ${datarootdir}/info
install_sh = ${SHELL} /home/morris/SUDA_V3S/3rdpart/ethercat-1.5.2/autoconf/install-sh
libdir = ${exec_prefix}/lib
libexecdir = ${exec_prefix}/libexec
localedir = ${datarootdir}/locale
localstatedir = ${prefix}/var
mandir = ${datarootdir}/man
mkdir_p = /bin/mkdir -p
oldincludedir = /usr/include
pdfdir = ${docdir}
prefix = /home/morris/SUDA_V3S/rootfs/multistrap/rootfs/opt/ethercat
program_transform_name = s,x,x,
psdir = ${docdir}
sbindir = ${exec_prefix}/sbin
sharedstatedir = ${prefix}/com
srcdir = .
sysconfdir = ${prefix}/etc
target_alias = 
top_build_prefix = ../../
top_builddir = ../..
top_srcdir = ../..
ec_xenomai_posix_example_SOURCES = main.c
ec_xenomai_posix_example_CFLAGS = \
	-Wall \
	-I$(top_srcdir)/include \
	$(XENOMAI_POSIX_CFLAGS) \
	$(XENOMAI_RTDM_CFLAGS)

ec_xenomai_posix_example_LDFLAGS = \
	-L$(top_builddir)/lib/.libs -lethercat_rtdm \
	$(XENOMAI_POSIX_LDFLAGS) \
	$(XENOMAI_RTDM_LDFLAGS)

all: all-am

.SUFFIXES:
.SUFFIXES: .c .lo .o .obj
$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
	@for dep in $?; do \
	  case '$(am__configure_deps)' in \
	    *$$dep*) \
	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
	        && { if test -f $@; then exit 0; else break; fi; }; \
	      exit 1;; \
	  esac; \
	done; \
	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu examples/xenomai_posix/Makefile'; \
	$(am__cd) $(top_srcdir) && \
	  $(AUTOMAKE) --gnu examples/xenomai_posix/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
	@case '$?' in \
	  *config.status*) \
	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
	  *) \
	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
	esac;

$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh

$(top_srcdir)/configure:  $(am__configure_deps)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):

clean-noinstPROGRAMS:
	@list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \
	echo " rm -f" $$list; \
	rm -f $$list || exit $$?; \
	test -n "$(EXEEXT)" || exit 0; \
	list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
	echo " rm -f" $$list; \
	rm -f $$list
ec_xenomai_posix_example$(EXEEXT): $(ec_xenomai_posix_example_OBJECTS) $(ec_xenomai_posix_example_DEPENDENCIES) 
	@rm -f ec_xenomai_posix_example$(EXEEXT)
	$(ec_xenomai_posix_example_LINK) $(ec_xenomai_posix_example_OBJECTS) $(ec_xenomai_posix_example_LDADD) $(LIBS)

mostlyclean-compile:
	-rm -f *.$(OBJEXT)

distclean-compile:
	-rm -f *.tab.c

include ./$(DEPDIR)/ec_xenomai_posix_example-main.Po

.c.o:
	$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
	$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
#	source='$<' object='$@' libtool=no \
#	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
#	$(COMPILE) -c $<

.c.obj:
	$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
	$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
#	source='$<' object='$@' libtool=no \
#	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
#	$(COMPILE) -c `$(CYGPATH_W) '$<'`

.c.lo:
	$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
	$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
#	source='$<' object='$@' libtool=yes \
#	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
#	$(LTCOMPILE) -c -o $@ $<

ec_xenomai_posix_example-main.o: main.c
	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ec_xenomai_posix_example_CFLAGS) $(CFLAGS) -MT ec_xenomai_posix_example-main.o -MD -MP -MF $(DEPDIR)/ec_xenomai_posix_example-main.Tpo -c -o ec_xenomai_posix_example-main.o `test -f 'main.c' || echo '$(srcdir)/'`main.c
	$(am__mv) $(DEPDIR)/ec_xenomai_posix_example-main.Tpo $(DEPDIR)/ec_xenomai_posix_example-main.Po
#	source='main.c' object='ec_xenomai_posix_example-main.o' libtool=no \
#	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
#	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ec_xenomai_posix_example_CFLAGS) $(CFLAGS) -c -o ec_xenomai_posix_example-main.o `test -f 'main.c' || echo '$(srcdir)/'`main.c

ec_xenomai_posix_example-main.obj: main.c
	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ec_xenomai_posix_example_CFLAGS) $(CFLAGS) -MT ec_xenomai_posix_example-main.obj -MD -MP -MF $(DEPDIR)/ec_xenomai_posix_example-main.Tpo -c -o ec_xenomai_posix_example-main.obj `if test -f 'main.c'; then $(CYGPATH_W) 'main.c'; else $(CYGPATH_W) '$(srcdir)/main.c'; fi`
	$(am__mv) $(DEPDIR)/ec_xenomai_posix_example-main.Tpo $(DEPDIR)/ec_xenomai_posix_example-main.Po
#	source='main.c' object='ec_xenomai_posix_example-main.obj' libtool=no \
#	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
#	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ec_xenomai_posix_example_CFLAGS) $(CFLAGS) -c -o ec_xenomai_posix_example-main.obj `if test -f 'main.c'; then $(CYGPATH_W) 'main.c'; else $(CYGPATH_W) '$(srcdir)/main.c'; fi`

mostlyclean-libtool:
	-rm -f *.lo

clean-libtool:
	-rm -rf .libs _libs

ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
	unique=`for i in $$list; do \
	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
	  done | \
	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
	      END { if (nonempty) { for (i in files) print i; }; }'`; \
	mkid -fID $$unique
tags: TAGS

TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
		$(TAGS_FILES) $(LISP)
	set x; \
	here=`pwd`; \
	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
	unique=`for i in $$list; do \
	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
	  done | \
	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
	      END { if (nonempty) { for (i in files) print i; }; }'`; \
	shift; \
	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
	  test -n "$$unique" || unique=$$empty_fix; \
	  if test $$# -gt 0; then \
	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
	      "$$@" $$unique; \
	  else \
	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
	      $$unique; \
	  fi; \
	fi
ctags: CTAGS
CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
		$(TAGS_FILES) $(LISP)
	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
	unique=`for i in $$list; do \
	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
	  done | \
	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
	      END { if (nonempty) { for (i in files) print i; }; }'`; \
	test -z "$(CTAGS_ARGS)$$unique" \
	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
	     $$unique

GTAGS:
	here=`$(am__cd) $(top_builddir) && pwd` \
	  && $(am__cd) $(top_srcdir) \
	  && gtags -i $(GTAGS_ARGS) "$$here"

distclean-tags:
	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags

distdir: $(DISTFILES)
	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
	list='$(DISTFILES)'; \
	  dist_files=`for file in $$list; do echo $$file; done | \
	  sed -e "s|^$$srcdirstrip/||;t" \
	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
	case $$dist_files in \
	  */*) $(MKDIR_P) `echo "$$dist_files" | \
			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
			   sort -u` ;; \
	esac; \
	for file in $$dist_files; do \
	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
	  if test -d $$d/$$file; then \
	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
	    if test -d "$(distdir)/$$file"; then \
	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
	    fi; \
	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
	    fi; \
	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
	  else \
	    test -f "$(distdir)/$$file" \
	    || cp -p $$d/$$file "$(distdir)/$$file" \
	    || exit 1; \
	  fi; \
	done
check-am: all-am
check: check-am
all-am: Makefile $(PROGRAMS)
installdirs:
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am

install-am: all-am
	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am

installcheck: installcheck-am
install-strip:
	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
	  `test -z '$(STRIP)' || \
	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:

clean-generic:

distclean-generic:
	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)

maintainer-clean-generic:
	@echo "This command is intended for maintainers to use"
	@echo "it deletes files that may require special tools to rebuild."
clean: clean-am

clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \
	mostlyclean-am

distclean: distclean-am
	-rm -rf ./$(DEPDIR)
	-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
	distclean-tags

dvi: dvi-am

dvi-am:

html: html-am

html-am:

info: info-am

info-am:

install-data-am:

install-dvi: install-dvi-am

install-dvi-am:

install-exec-am:

install-html: install-html-am

install-html-am:

install-info: install-info-am

install-info-am:

install-man:

install-pdf: install-pdf-am

install-pdf-am:

install-ps: install-ps-am

install-ps-am:

installcheck-am:

maintainer-clean: maintainer-clean-am
	-rm -rf ./$(DEPDIR)
	-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic

mostlyclean: mostlyclean-am

mostlyclean-am: mostlyclean-compile mostlyclean-generic \
	mostlyclean-libtool

pdf: pdf-am

pdf-am:

ps: ps-am

ps-am:

uninstall-am:

.MAKE: install-am install-strip

.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
	clean-libtool clean-noinstPROGRAMS ctags distclean \
	distclean-compile distclean-generic distclean-libtool \
	distclean-tags distdir dvi dvi-am html html-am info info-am \
	install install-am install-data install-data-am install-dvi \
	install-dvi-am install-exec install-exec-am install-html \
	install-html-am install-info install-info-am install-man \
	install-pdf install-pdf-am install-ps install-ps-am \
	install-strip installcheck installcheck-am installdirs \
	maintainer-clean maintainer-clean-generic mostlyclean \
	mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
	pdf pdf-am ps ps-am tags uninstall uninstall-am


#------------------------------------------------------------------------------

# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:


<|start_filename|>3rdpart/ethercat-1.5.2/tool/CommandStates.cpp<|end_filename|>
/*****************************************************************************
 *
 *  $Id: CommandStates.cpp,v bc2d4bf9cbe5 2012/09/06 18:22:24 fp $
 *
 *  Copyright (C) 2006-2009  <NAME>, Ingenieurgemeinschaft IgH
 *
 *  This file is part of the IgH EtherCAT Master.
 *
 *  The IgH EtherCAT Master is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License version 2, as
 *  published by the Free Software Foundation.
 *
 *  The IgH EtherCAT Master is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 *  Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with the IgH EtherCAT Master; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 ****************************************************************************/

#include <iostream>
#include <algorithm>
using namespace std;

#include "CommandStates.h"
#include "MasterDevice.h"

/*****************************************************************************/

CommandStates::CommandStates():
    Command("states", "Request application-layer states.")
{
}

/*****************************************************************************/

string CommandStates::helpString(const string &binaryBaseName) const
{
    stringstream str;

    str << binaryBaseName << " " << getName() << " [OPTIONS] <STATE>" << endl
        << endl
        << getBriefDescription() << endl
        << endl
        << "Arguments:" << endl
        << "  STATE can be 'INIT', 'PREOP', 'BOOT', 'SAFEOP', or 'OP'." << endl
        << endl
        << "Command-specific options:" << endl
        << "  --alias    -a <alias>" << endl
        << "  --position -p <pos>    Slave selection. See the help of" << endl
        << "                         the 'slaves' command." << endl
        << endl
        << numericInfo();

    return str.str();
}

/****************************************************************************/

void CommandStates::execute(const StringVector &args)
{
	MasterIndexList masterIndices;
    SlaveList slaves;
    SlaveList::const_iterator si;
    stringstream err;
    string stateStr;
    uint8_t state = 0x00;

    if (args.size() != 1) {
        err << "'" << getName() << "' takes exactly one argument!";
        throwInvalidUsageException(err);
    }

    stateStr = args[0];
    transform(stateStr.begin(), stateStr.end(),
            stateStr.begin(), (int (*) (int)) std::toupper);

    if (stateStr == "INIT") {
        state = 0x01;
    } else if (stateStr == "PREOP") {
        state = 0x02;
    } else if (stateStr == "BOOT") {
        state = 0x03;
    } else if (stateStr == "SAFEOP") {
        state = 0x04;
    } else if (stateStr == "OP") {
        state = 0x08;
    } else {
        err << "Invalid state '" << args[0] << "'!";
        throwInvalidUsageException(err);
    }

	masterIndices = getMasterIndices();
    MasterIndexList::const_iterator mi;
    for (mi = masterIndices.begin();
            mi != masterIndices.end(); mi++) {
        MasterDevice m(*mi);
        m.open(MasterDevice::ReadWrite);
        slaves = selectedSlaves(m);

        for (si = slaves.begin(); si != slaves.end(); si++) {
            m.requestState(si->position, state);
        }
    }
}

/*****************************************************************************/


<|start_filename|>3rdpart/ethercat-1.5.2/include/ectty.h<|end_filename|>
/******************************************************************************
 *
 *  $Id: ectty.h,v bc2d4bf9cbe5 2012/09/06 18:22:24 fp $
 *
 *  Copyright (C) 2006-2008  <NAME>, Ingenieurgemeinschaft IgH
 *
 *  This file is part of the IgH EtherCAT master userspace library.
 *
 *  The IgH EtherCAT master userspace library is free software; you can
 *  redistribute it and/or modify it under the terms of the GNU Lesser General
 *  Public License as published by the Free Software Foundation; version 2.1
 *  of the License.
 *
 *  The IgH EtherCAT master userspace library is distributed in the hope that
 *  it will be useful, but WITHOUT ANY WARRANTY; without even the implied
 *  warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public License
 *  along with the IgH EtherCAT master userspace library. If not, see
 *  <http://www.gnu.org/licenses/>.
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 *****************************************************************************/

/** \file
 *
 * EtherCAT virtual TTY interface.
 *
 * \defgroup TTYInterface EtherCAT Virtual TTY Interface
 *
 * @{
 */

/*****************************************************************************/

#ifndef __ECTTY_H__
#define __ECTTY_H__

#include <linux/termios.h>

/******************************************************************************
 * Data types
 *****************************************************************************/

struct ec_tty;
typedef struct ec_tty ec_tty_t; /**< \see ec_tty */

/** Operations on the virtual TTY interface.
 */
typedef struct {
    int (*cflag_changed)(void *, tcflag_t); /**< Called when the serial
                                              * settings shall be changed. The
                                              * \a cflag argument contains the
                                              * new settings. */
} ec_tty_operations_t;

/******************************************************************************
 * Global functions
 *****************************************************************************/

/** Create a virtual TTY interface.
 *
 * \param ops Set of callbacks.
 * \param cb_data Arbitrary data, that is passed to any callback.
 *
 * \return Pointer to the interface object, otherwise an ERR_PTR value.
 */
ec_tty_t *ectty_create(
        const ec_tty_operations_t *ops,
        void *cb_data
        );

/******************************************************************************
 * TTY interface methods
 *****************************************************************************/

/** Releases a virtual TTY interface.
 */
void ectty_free(
        ec_tty_t *tty /**< TTY interface. */
        );

/** Reads data to send from the TTY interface.
 *
 * If there are data to send, they are copied into the \a buffer. At maximum,
 * \a size bytes are copied. The actual number of bytes copied is returned.
 *
 * \return Number of bytes copied.
 */
unsigned int ectty_tx_data(
        ec_tty_t *tty, /**< TTY interface. */
        uint8_t *buffer, /**< Buffer for data to transmit. */
        size_t size /**< Available space in \a buffer. */
        );

/** Pushes received data to the TTY interface.
 */
void ectty_rx_data(
        ec_tty_t *tty, /**< TTY interface. */
        const uint8_t *buffer, /**< Buffer with received data. */
        size_t size /**< Number of bytes in \a buffer. */
        );

/*****************************************************************************/

/** @} */

#endif


<|start_filename|>3rdpart/ethercat-1.5.2/master/foe.h<|end_filename|>
/******************************************************************************
 *
 *  $Id: foe.h,v 6d9865c37b6f 2013/02/12 16:15:09 fp $
 *
 *  Copyright (C) 2006-2008  <NAME>, Ingenieurgemeinschaft IgH
 *
 *  This file is part of the IgH EtherCAT Master.
 *
 *  The IgH EtherCAT Master is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License version 2, as
 *  published by the Free Software Foundation.
 *
 *  The IgH EtherCAT Master is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 *  Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with the IgH EtherCAT Master; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 *****************************************************************************/

/** \file
 * FoE defines.
 */

#ifndef __FOE_H__
#define __FOE_H__

/*****************************************************************************/

/** FoE error enumeration type.
 */
typedef enum {
    FOE_BUSY               = 0, /**< Busy. */
    FOE_READY              = 1, /**< Ready. */
    FOE_IDLE               = 2, /**< Idle. */
    FOE_WC_ERROR           = 3, /**< Working counter error. */
    FOE_RECEIVE_ERROR      = 4, /**< Receive error. */
    FOE_PROT_ERROR         = 5, /**< Protocol error. */
    FOE_NODATA_ERROR       = 6, /**< No data error. */
    FOE_PACKETNO_ERROR     = 7, /**< Packet number error. */
    FOE_OPCODE_ERROR       = 8, /**< OpCode error. */
    FOE_TIMEOUT_ERROR      = 9, /**< Timeout error. */
    FOE_SEND_RX_DATA_ERROR = 10, /**< Error sending received data. */
    FOE_RX_DATA_ACK_ERROR  = 11, /**< Error acknowledging received data. */
    FOE_ACK_ERROR          = 12, /**< Acknowledge error. */
    FOE_MBOX_FETCH_ERROR   = 13, /**< Error fetching data from mailbox. */
    FOE_READ_NODATA_ERROR  = 14, /**< No data while reading. */
    FOE_MBOX_PROT_ERROR    = 15, /**< Mailbox protocol error. */
} ec_foe_error_t;

/*****************************************************************************/

#endif


<|start_filename|>3rdpart/tslib-1.15/tests/ts_test.c<|end_filename|>
/*
 *  tslib/src/ts_test.c
 *
 *  Copyright (C) 2001 <NAME>.
 *
 * This file is placed under the GPL.  Please see the file
 * COPYING for more details.
 *
 * SPDX-License-Identifier: GPL-2.0+
 *
 *
 * Basic test program for touchscreen library.
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <getopt.h>
#include <errno.h>

#include "tslib.h"
#include "fbutils.h"
#include "testutils.h"

static int palette[] = {
	0x000000, 0xffe080, 0xffffff, 0xe0c0a0, 0x304050, 0x80b8c0
};
#define NR_COLORS (sizeof (palette) / sizeof (palette [0]))

#define NR_BUTTONS 3
static struct ts_button buttons[NR_BUTTONS];

static void sig(int sig)
{
	close_framebuffer();
	fflush(stderr);
	printf("signal %d caught\n", sig);
	fflush(stdout);
	exit(1);
}

static void refresh_screen(void)
{
	int i;

	fillrect(0, 0, xres - 1, yres - 1, 0);
	put_string_center(xres / 2, yres / 4, "Touchscreen test program", 1);
	put_string_center(xres / 2, yres / 4 + 20,
			  "Touch screen to move crosshair", 2);

	for (i = 0; i < NR_BUTTONS; i++)
		button_draw(&buttons[i]);
}

static void help(void)
{
	struct ts_lib_version_data *ver = ts_libversion();

	print_ascii_logo();

	printf("tslib %s / libts ABI version %d (0x%06X)\n",
		ver->package_version, ver->version_num >> 16, ver->version_num);
	printf("\n");
	printf("Usage: ts_test [-r <rotate_value>]\n");
	printf("\n");
	printf("        <rotate_value> 0 ... no rotation; 0 degree (default)\n");
	printf("                       1 ... clockwise orientation; 90 degrees\n");
	printf("                       2 ... upside down orientation; 180 degrees\n");
	printf("                       3 ... counterclockwise orientation; 270 degrees\n");
	printf("\n");
	printf("Example (Linux): ts_test -r $(cat /sys/class/graphics/fbcon/rotate)\n");
	printf("\n");
}

int main(int argc, char **argv)
{
	struct tsdev *ts;
	int x, y;
	unsigned int i;
	unsigned int mode = 0;
	int quit_pressed = 0;

	signal(SIGSEGV, sig);
	signal(SIGINT, sig);
	signal(SIGTERM, sig);

	while (1) {
		const struct option long_options[] = {
			{ "help",         no_argument,       NULL, 'h' },
			{ "rotate",       required_argument, NULL, 'r' },
		};

		int option_index = 0;
		int c = getopt_long(argc, argv, "hr:", long_options, &option_index);

		errno = 0;
		if (c == -1)
			break;

		switch (c) {
		case 'h':
			help();
			return 0;

		case 'r':
			/* extern in fbutils.h */
			rotation = atoi(optarg);
			if (rotation < 0 || rotation > 3) {
				help();
				return 0;
			}
			break;

		default:
			help();
			return 0;
		}

		if (errno) {
			char str[9];

			sprintf(str, "option ?");
			str[7] = c & 0xff;
			perror(str);
		}
	}

	ts = ts_setup(NULL, 0);
	if (!ts) {
		perror("ts_open");
		exit(1);
	}

	if (open_framebuffer()) {
		close_framebuffer();
		ts_close(ts);
		exit(1);
	}

	x = xres / 2;
	y = yres / 2;

	for (i = 0; i < NR_COLORS; i++)
		setcolor(i, palette[i]);

	/* Initialize buttons */
	memset(&buttons, 0, sizeof(buttons));
	buttons[0].w = buttons[1].w = buttons[2].w = xres / 4;
	buttons[0].h = buttons[1].h = buttons[2].h = 20;
	buttons[0].x = 0;
	buttons[1].x = (3 * xres) / 8;
	buttons[2].x = (3 * xres) / 4;
	buttons[0].y = buttons[1].y = buttons[2].y = 10;
	buttons[0].text = "Drag";
	buttons[1].text = "Draw";
	buttons[2].text = "Quit";

	refresh_screen();

	while (1) {
		struct ts_sample samp;
		int ret;

		/* Show the cross */
		if ((mode & 15) != 1)
			put_cross(x, y, 2 | XORMODE);

		ret = ts_read(ts, &samp, 1);

		/* Hide it */
		if ((mode & 15) != 1)
			put_cross(x, y, 2 | XORMODE);

		if (ret < 0) {
			perror("ts_read");
			close_framebuffer();
			ts_close(ts);
			exit(1);
		}

		if (ret != 1)
			continue;

		for (i = 0; i < NR_BUTTONS; i++)
			if (button_handle(&buttons[i], samp.x, samp.y, samp.pressure))
				switch (i) {
				case 0:
					mode = 0;
					refresh_screen();
					break;
				case 1:
					mode = 1;
					refresh_screen();
					break;
				case 2:
					quit_pressed = 1;
				}

		printf("%ld.%06ld: %6d %6d %6d\n", samp.tv.tv_sec, samp.tv.tv_usec,
			samp.x, samp.y, samp.pressure);

		if (samp.pressure > 0) {
			if (mode == 0x80000001)
				line(x, y, samp.x, samp.y, 2);
			x = samp.x;
			y = samp.y;
			mode |= 0x80000000;
		} else
			mode &= ~0x80000000;
		if (quit_pressed)
			break;
	}
	fillrect(0, 0, xres - 1, yres - 1, 0);
	close_framebuffer();
	ts_close(ts);

	return 0;
}


<|start_filename|>3rdpart/tslib-1.15/src/ts_option.c<|end_filename|>
/*
 *  tslib/src/ts_option.c
 *
 *  Copyright (C) 2005 <NAME> <<EMAIL>>
 *
 * This file is placed under the LGPL.  Please see the file
 * COPYING for more details.
 *
 * SPDX-License-Identifier: LGPL-2.1
 *
 *
 * Interface for setting parameters for the core library
 */
#include "config.h"
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "tslib-private.h"

int ts_option(struct tsdev *ts, enum ts_param param, ...)
{
	int ret;
	va_list ap;

	va_start(ap, param);
	ret = 0;

	switch (param) {
	case TS_SCREEN_RES:
		ts->res_x = va_arg(ap, unsigned int);
		ts->res_y = va_arg(ap, unsigned int);
		break;
	case TS_SCREEN_ROT:
		ts->rotation = va_arg(ap, int);
		break;
	}
	va_end(ap);

	return ret;
}



<|start_filename|>3rdpart/tslib-1.15/tests/ts_calibrate.c<|end_filename|>
/*
 *  tslib/tests/ts_calibrate.c
 *
 *  Copyright (C) 2001 <NAME>.
 *
 * This file is placed under the GPL.  Please see the file
 * COPYING for more details.
 *
 * SPDX-License-Identifier: GPL-2.0+
 *
 *
 * Graphical touchscreen calibration tool. This writes the configuration
 * file used by tslib's "linear" filter plugin module to transform the
 * touch samples according to the calibration.
 */
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <getopt.h>
#include <errno.h>

#include "tslib.h"

#include "fbutils.h"
#include "testutils.h"
#include "ts_calibrate.h"

static int palette[] = {
	0x000000, 0xffe080, 0xffffff, 0xe0c0a0
};
#define NR_COLORS (sizeof(palette) / sizeof(palette[0]))

static void sig(int sig)
{
	close_framebuffer();
	fflush(stderr);
	printf("signal %d caught\n", sig);
	fflush(stdout);
	exit(1);
}

static void get_sample(struct tsdev *ts, calibration *cal,
		       int index, int x, int y, char *name)
{
	static int last_x = -1, last_y;

	if (last_x != -1) {
#define NR_STEPS 10
		int dx = ((x - last_x) << 16) / NR_STEPS;
		int dy = ((y - last_y) << 16) / NR_STEPS;
		int i;

		last_x <<= 16;
		last_y <<= 16;
		for (i = 0; i < NR_STEPS; i++) {
			put_cross(last_x >> 16, last_y >> 16, 2 | XORMODE);
			usleep(1000);
			put_cross(last_x >> 16, last_y >> 16, 2 | XORMODE);
			last_x += dx;
			last_y += dy;
		}
	}

	put_cross(x, y, 2 | XORMODE);
	getxy(ts, &cal->x[index], &cal->y[index]);
	put_cross(x, y, 2 | XORMODE);

	last_x = cal->xfb[index] = x;
	last_y = cal->yfb[index] = y;

	printf("%s : X = %4d Y = %4d\n", name, cal->x[index], cal->y[index]);
}

static void clearbuf(struct tsdev *ts)
{
	int fd = ts_fd(ts);
	fd_set fdset;
	struct timeval tv;
	int nfds;
	struct ts_sample sample;

	while (1) {
		FD_ZERO(&fdset);
		FD_SET(fd, &fdset);

		tv.tv_sec = 0;
		tv.tv_usec = 0;

		nfds = select(fd + 1, &fdset, NULL, NULL, &tv);
		if (nfds == 0)
			break;

		if (ts_read_raw(ts, &sample, 1) < 0) {
			perror("ts_read_raw");
			exit(1);
		}
	}
}

static void help(void)
{
	struct ts_lib_version_data *ver = ts_libversion();

	print_ascii_logo();

	printf("tslib %s / libts ABI version %d (0x%06X)\n",
		ver->package_version, ver->version_num >> 16, ver->version_num);
	printf("\n");
	printf("Usage: ts_calibrate [-r <rotate_value>]\n");
	printf("\n");
	printf("        <rotate_value> 0 ... no rotation; 0 degree (default)\n");
	printf("                       1 ... clockwise orientation; 90 degrees\n");
	printf("                       2 ... upside down orientation; 180 degrees\n");
	printf("                       3 ... counterclockwise orientation; 270 degrees\n");
	printf("\n");
	printf("Example (Linux): ts_calibrate -r $(cat /sys/class/graphics/fbcon/rotate)\n");
	printf("\n");
}

int main(int argc, char **argv)
{
	struct tsdev *ts;
	calibration cal = {
		.x = { 0 },
		.y = { 0 },
	};
	int cal_fd;
	char cal_buffer[256];
	char *calfile = NULL;
	unsigned int i, len;

	signal(SIGSEGV, sig);
	signal(SIGINT, sig);
	signal(SIGTERM, sig);

	while (1) {
		const struct option long_options[] = {
			{ "help",         no_argument,       NULL, 'h' },
			{ "rotate",       required_argument, NULL, 'r' },
		};

		int option_index = 0;
		int c = getopt_long(argc, argv, "hr:", long_options, &option_index);

		errno = 0;
		if (c == -1)
			break;

		switch (c) {
		case 'h':
			help();
			return 0;

		case 'r':
			/* extern in fbutils.h */
			rotation = atoi(optarg);
			if (rotation < 0 || rotation > 3) {
				help();
				return 0;
			}
			break;

		default:
			help();
			return 0;
		}

		if (errno) {
			char str[9];
			sprintf(str, "option ?");
			str[7] = c & 0xff;
			perror(str);
		}
	}

	ts = ts_setup(NULL, 0);
	if (!ts) {
		perror("ts_setup");
		exit(1);
	}

	if (open_framebuffer()) {
		close_framebuffer();
		ts_close(ts);
		exit(1);
	}

	for (i = 0; i < NR_COLORS; i++)
		setcolor(i, palette[i]);

	put_string_center(xres / 2, yres / 4,
			  "Touchscreen calibration utility", 1);
	put_string_center(xres / 2, yres / 4 + 20,
			  "Touch crosshair to calibrate", 2);

	printf("xres = %d, yres = %d\n", xres, yres);

	/* Clear the buffer */
	clearbuf(ts);

	get_sample(ts, &cal, 0, 50,        50,        "Top left");
	clearbuf(ts);
	get_sample(ts, &cal, 1, xres - 50, 50,        "Top right");
	clearbuf(ts);
	get_sample(ts, &cal, 2, xres - 50, yres - 50, "Bot right");
	clearbuf(ts);
	get_sample(ts, &cal, 3, 50,        yres - 50, "Bot left");
	clearbuf(ts);
	get_sample(ts, &cal, 4, xres / 2,  yres / 2,  "Center");

	if (perform_calibration (&cal)) {
		printf("Calibration constants: ");
		for (i = 0; i < 7; i++)
			printf("%d ", cal.a[i]);
		printf("\n");
		if ((calfile = getenv("TSLIB_CALIBFILE")) != NULL) {
			cal_fd = open(calfile, O_CREAT | O_TRUNC | O_RDWR,
				      S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
		} else {
			cal_fd = open(TS_POINTERCAL, O_CREAT | O_TRUNC | O_RDWR,
				      S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
		}
		if (cal_fd < 0) {
			perror("open");
			close_framebuffer();
			ts_close(ts);
			exit(1);
		}

		len = sprintf(cal_buffer, "%d %d %d %d %d %d %d %d %d",
			      cal.a[1], cal.a[2], cal.a[0],
			      cal.a[4], cal.a[5], cal.a[3], cal.a[6],
			      xres, yres);
		if (write(cal_fd, cal_buffer, len) == -1) {
			perror("write");
			close_framebuffer();
			ts_close(ts);
			exit(1);
		}
		close(cal_fd);
		i = 0;
	} else {
		printf("Calibration failed.\n");
		i = -1;
	}

	fillrect(0, 0, xres - 1, yres - 1, 0);
	close_framebuffer();
	ts_close(ts);
	return i;
}


<|start_filename|>3rdpart/ethercat-1.5.2/lib/sdo_request.c<|end_filename|>
/******************************************************************************
 *
 *  $Id: sdo_request.c,v 9640948881fd 2012/12/06 12:53:09 fp $
 *
 *  Copyright (C) 2006-2012  <NAME>, Ingenieurgemeinschaft IgH
 *
 *  This file is part of the IgH EtherCAT master userspace library.
 *
 *  The IgH EtherCAT master userspace library is free software; you can
 *  redistribute it and/or modify it under the terms of the GNU Lesser General
 *  Public License as published by the Free Software Foundation; version 2.1
 *  of the License.
 *
 *  The IgH EtherCAT master userspace library is distributed in the hope that
 *  it will be useful, but WITHOUT ANY WARRANTY; without even the implied
 *  warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public License
 *  along with the IgH EtherCAT master userspace library. If not, see
 *  <http://www.gnu.org/licenses/>.
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 *****************************************************************************/

/** \file
 * Canopen over EtherCAT SDO request functions.
 */

/*****************************************************************************/

#include <stdio.h>
#include <string.h>

#include "ioctl.h"
#include "sdo_request.h"
#include "slave_config.h"
#include "master.h"

/*****************************************************************************/

void ec_sdo_request_clear(ec_sdo_request_t *req)
{
    if (req->data) {
        free(req->data);
    }
}

/*****************************************************************************
 * Application interface.
 ****************************************************************************/

void ecrt_sdo_request_index(ec_sdo_request_t *req, uint16_t index,
        uint8_t subindex)
{
    ec_ioctl_sdo_request_t data;
    int ret;

    data.config_index = req->config->index;
    data.request_index = req->index;
    data.sdo_index = index;
    data.sdo_subindex = subindex;

    ret = ioctl(req->config->master->fd, EC_IOCTL_SDO_REQUEST_INDEX, &data);
    if (EC_IOCTL_IS_ERROR(ret)) {
        fprintf(stderr, "Failed to set SDO request index/subindex: %s\n",
                strerror(EC_IOCTL_ERRNO(ret)));
    }
}

/*****************************************************************************/

void ecrt_sdo_request_timeout(ec_sdo_request_t *req, uint32_t timeout)
{
    ec_ioctl_sdo_request_t data;
    int ret;

    data.config_index = req->config->index;
    data.request_index = req->index;
    data.timeout = timeout;

    ret = ioctl(req->config->master->fd, EC_IOCTL_SDO_REQUEST_TIMEOUT, &data);
    if (EC_IOCTL_IS_ERROR(ret)) {
        fprintf(stderr, "Failed to set SDO request timeout: %s\n",
                strerror(EC_IOCTL_ERRNO(ret)));
    }
}

/*****************************************************************************/

uint8_t *ecrt_sdo_request_data(ec_sdo_request_t *req)
{
    return req->data;
}

/*****************************************************************************/

size_t ecrt_sdo_request_data_size(const ec_sdo_request_t *req)
{
    return req->data_size;
}

/*****************************************************************************/

ec_request_state_t ecrt_sdo_request_state(ec_sdo_request_t *req)
{
    ec_ioctl_sdo_request_t data;
    int ret;

    data.config_index = req->config->index;
    data.request_index = req->index;

    ret = ioctl(req->config->master->fd, EC_IOCTL_SDO_REQUEST_STATE, &data);
    if (EC_IOCTL_IS_ERROR(ret)) {
        fprintf(stderr, "Failed to get SDO request state: %s\n",
                strerror(EC_IOCTL_ERRNO(ret)));
        return EC_REQUEST_ERROR;
    }

    if (data.size) { // new data waiting to be copied
        if (req->mem_size < data.size) {
            fprintf(stderr, "Received %zu bytes do not fit info SDO data"
                    " memory (%zu bytes)!\n", data.size, req->mem_size);
            return EC_REQUEST_ERROR;
        }

        data.data = req->data;

        ret = ioctl(req->config->master->fd,
                EC_IOCTL_SDO_REQUEST_DATA, &data);
        if (EC_IOCTL_IS_ERROR(ret)) {
            fprintf(stderr, "Failed to get SDO data: %s\n",
                    strerror(EC_IOCTL_ERRNO(ret)));
            return EC_REQUEST_ERROR;
        }
        req->data_size = data.size;
    }

    return data.state;
}

/*****************************************************************************/

void ecrt_sdo_request_read(ec_sdo_request_t *req)
{
    ec_ioctl_sdo_request_t data;
    int ret;

    data.config_index = req->config->index;
    data.request_index = req->index;

    ret = ioctl(req->config->master->fd, EC_IOCTL_SDO_REQUEST_READ, &data);
    if (EC_IOCTL_IS_ERROR(ret)) {
        fprintf(stderr, "Failed to command an SDO read operation : %s\n",
                strerror(EC_IOCTL_ERRNO(ret)));
    }
}

/*****************************************************************************/

void ecrt_sdo_request_write(ec_sdo_request_t *req)
{
    ec_ioctl_sdo_request_t data;
    int ret;

    data.config_index = req->config->index;
    data.request_index = req->index;
    data.data = req->data;
    data.size = req->data_size;

    ret = ioctl(req->config->master->fd, EC_IOCTL_SDO_REQUEST_WRITE, &data);
    if (EC_IOCTL_IS_ERROR(ret)) {
        fprintf(stderr, "Failed to command an SDO write operation : %s\n",
                strerror(EC_IOCTL_ERRNO(ret)));
    }
}

/*****************************************************************************/


<|start_filename|>apps/ecat-master/main/main.c<|end_filename|>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <stdbool.h>
#include <time.h>
#include "gui.h"
#include "utils.h"
#include "ecat.h"

static bool app_running = true;

/* 进程的信号处理函数 */
static void signal_handler(int sig) {
	switch (sig) {
	case SIGINT:
		app_running = false;
		break;
	default:
		break;
	}
}

int main(void) {
	/* 注册信号处理函数 */
	signal(SIGINT, signal_handler);

	/* 初始化GUI组件 */
	gui_init();
	/* 初始化工具线程，计算CPU使用率 */
	utils_init();
	/* 初始化ethercat主站，注册回调函数 */
	ecat_init(gui_user_work);

	while (app_running) {
		sleep(1);
	}
	ecat_stop();
	utils_stop();
	gui_stop();
	printf("ByeBye\r\n");
	return 0;
}



<|start_filename|>apps/ecat-master/main/utils.h<|end_filename|>
/*
 * utils.h
 *
 *  Created on: Mar 11, 2018
 *      Author: morris
 */

#ifndef UTILS_H_
#define UTILS_H_

#include <stdint.h>

int utils_init(void);
int utils_cpu_usage(uint8_t* arg);
void utils_stop(void);

#endif /* UTILS_H_ */


<|start_filename|>3rdpart/ethercat-1.5.2/config.h<|end_filename|>
/* config.h.  Generated from config.h.in by configure.  */
/* config.h.in.  Generated from configure.ac by autoheader.  */

/* Debug interfaces enabled */
/* #undef EC_DEBUG_IF */

/* Debug ring enabled */
/* #undef EC_DEBUG_RING */

/* EoE support enabled */
#define EC_EOE 1

/* Use CPU timestamp counter */
/* #undef EC_HAVE_CYCLES */

/* Use vendor id / product code wildcards */
/* #undef EC_IDENT_WILDCARDS */

/* Max. number of Ethernet devices per master */
#define EC_MAX_NUM_DEVICES 1

/* Read alias adresses from register */
/* #undef EC_REGALIAS */

/* RTDM interface enabled */
/* #undef EC_RTDM */

/* Assign SII to PDI */
/* #undef EC_SII_ASSIGN */

/* Use hrtimer for scheduling */
/* #undef EC_USE_HRTIMER */

/* Define to 1 if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H 1

/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1

/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1

/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1

/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1

/* Define to 1 if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1

/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1

/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1

/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1

/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1

/* Define to the sub-directory in which libtool stores uninstalled libraries.
   */
#define LT_OBJDIR ".libs/"

/* Define to 1 if your C compiler doesn't accept -c and -o together. */
/* #undef NO_MINUS_C_MINUS_O */

/* Name of package */
#define PACKAGE "ethercat"

/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "<EMAIL>"

/* Define to the full name of this package. */
#define PACKAGE_NAME "ethercat"

/* Define to the full name and version of this package. */
#define PACKAGE_STRING "ethercat 1.5.2"

/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "ethercat"

/* Define to the home page for this package. */
#define PACKAGE_URL ""

/* Define to the version of this package. */
#define PACKAGE_VERSION "1.5.2"

/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1

/* Version number of package */
#define VERSION "1.5.2"


<|start_filename|>3rdpart/ethercat-1.5.2/lib/domain.c<|end_filename|>
/******************************************************************************
 *
 *  $Id: domain.c,v 5ef9d5b14879 2013/02/05 14:24:45 fp $
 *
 *  Copyright (C) 2006-2012  <NAME>, Ingenieurgemeinschaft IgH
 *
 *  This file is part of the IgH EtherCAT master userspace library.
 *
 *  The IgH EtherCAT master userspace library is free software; you can
 *  redistribute it and/or modify it under the terms of the GNU Lesser General
 *  Public License as published by the Free Software Foundation; version 2.1
 *  of the License.
 *
 *  The IgH EtherCAT master userspace library is distributed in the hope that
 *  it will be useful, but WITHOUT ANY WARRANTY; without even the implied
 *  warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public License
 *  along with the IgH EtherCAT master userspace library. If not, see
 *  <http://www.gnu.org/licenses/>.
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 *****************************************************************************/

/**
   \file
   EtherCAT domain methods.
*/

/*****************************************************************************/

#include <stdio.h>
#include <string.h>
#include <errno.h> /* ENOENT */

#include "ioctl.h"
#include "domain.h"
#include "master.h"

/*****************************************************************************/

void ec_domain_clear(ec_domain_t *domain)
{
    // nothing to do
}

/*****************************************************************************/

int ecrt_domain_reg_pdo_entry_list(ec_domain_t *domain,
        const ec_pdo_entry_reg_t *regs)
{
    const ec_pdo_entry_reg_t *reg;
    ec_slave_config_t *sc;
    int ret;

    for (reg = regs; reg->index; reg++) {
        if (!(sc = ecrt_master_slave_config(domain->master, reg->alias,
                        reg->position, reg->vendor_id, reg->product_code)))
            return -ENOENT;

        if ((ret = ecrt_slave_config_reg_pdo_entry(sc, reg->index,
                        reg->subindex, domain, reg->bit_position)) < 0)
            return ret;

        *reg->offset = ret;
    }

    return 0;
}

/*****************************************************************************/

size_t ecrt_domain_size(const ec_domain_t *domain)
{
    int ret;

    ret = ioctl(domain->master->fd, EC_IOCTL_DOMAIN_SIZE, domain->index);
    if (EC_IOCTL_IS_ERROR(ret)) {
        fprintf(stderr, "Failed to get domain size: %s\n",
                strerror(EC_IOCTL_ERRNO(ret)));
    }

    return ret;
}

/*****************************************************************************/

uint8_t *ecrt_domain_data(ec_domain_t *domain)
{
    if (!domain->process_data) {
        int offset = 0;

        offset = ioctl(domain->master->fd, EC_IOCTL_DOMAIN_OFFSET,
                domain->index);
        if (EC_IOCTL_IS_ERROR(offset)) {
            fprintf(stderr, "Failed to get domain offset: %s\n",
                    strerror(EC_IOCTL_ERRNO(offset)));
            return NULL;
        }

        domain->process_data = domain->master->process_data + offset;
    }

    return domain->process_data;
}

/*****************************************************************************/

void ecrt_domain_process(ec_domain_t *domain)
{
    int ret;

    ret = ioctl(domain->master->fd, EC_IOCTL_DOMAIN_PROCESS, domain->index);
    if (EC_IOCTL_IS_ERROR(ret)) {
        fprintf(stderr, "Failed to process domain: %s\n",
                strerror(EC_IOCTL_ERRNO(ret)));
    }
}

/*****************************************************************************/

void ecrt_domain_queue(ec_domain_t *domain)
{
    int ret;

    ret = ioctl(domain->master->fd, EC_IOCTL_DOMAIN_QUEUE, domain->index);
    if (EC_IOCTL_IS_ERROR(ret)) {
        fprintf(stderr, "Failed to queue domain: %s\n",
                strerror(EC_IOCTL_ERRNO(ret)));
    }
}

/*****************************************************************************/

void ecrt_domain_state(const ec_domain_t *domain, ec_domain_state_t *state)
{
    ec_ioctl_domain_state_t data;
    int ret;

    data.domain_index = domain->index;
    data.state = state;

    ret = ioctl(domain->master->fd, EC_IOCTL_DOMAIN_STATE, &data);
    if (EC_IOCTL_IS_ERROR(ret)) {
        fprintf(stderr, "Failed to get domain state: %s\n",
                strerror(EC_IOCTL_ERRNO(ret)));
    }
}

/*****************************************************************************/


<|start_filename|>3rdpart/ethercat-1.5.2/devices/e1000/e1000_osdep-2.6.13-orig.h<|end_filename|>
/*******************************************************************************

  
  Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
  
  This program is free software; you can redistribute it and/or modify it 
  under the terms of the GNU General Public License as published by the Free 
  Software Foundation; either version 2 of the License, or (at your option) 
  any later version.
  
  This program is distributed in the hope that it will be useful, but WITHOUT 
  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for 
  more details.
  
  You should have received a copy of the GNU General Public License along with
  this program; if not, write to the Free Software Foundation, Inc., 59 
  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  
  The full GNU General Public License is included in this distribution in the
  file called LICENSE.
  
  Contact Information:
  Linux NICS <<EMAIL>>
  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497

*******************************************************************************/


/* glue for the OS independent part of e1000
 * includes register access macros
 */

#ifndef _E1000_OSDEP_H_
#define _E1000_OSDEP_H_

#include <linux/types.h>
#include <linux/pci.h>
#include <linux/delay.h>
#include <asm/io.h>
#include <linux/interrupt.h>
#include <linux/sched.h>

#ifndef msec_delay
#define msec_delay(x)	do { if(in_interrupt()) { \
				/* Don't mdelay in interrupt context! */ \
	                	BUG(); \
			} else { \
				msleep(x); \
			} } while(0)

/* Some workarounds require millisecond delays and are run during interrupt
 * context.  Most notably, when establishing link, the phy may need tweaking
 * but cannot process phy register reads/writes faster than millisecond
 * intervals...and we establish link due to a "link status change" interrupt.
 */
#define msec_delay_irq(x) mdelay(x)
#endif

#define PCI_COMMAND_REGISTER   PCI_COMMAND
#define CMD_MEM_WRT_INVALIDATE PCI_COMMAND_INVALIDATE

typedef enum {
#undef FALSE
    FALSE = 0,
#undef TRUE
    TRUE = 1
} boolean_t;

#define MSGOUT(S, A, B)	printk(KERN_DEBUG S "\n", A, B)

#ifdef DBG
#define DEBUGOUT(S)		printk(KERN_DEBUG S "\n")
#define DEBUGOUT1(S, A...)	printk(KERN_DEBUG S "\n", A)
#else
#define DEBUGOUT(S)
#define DEBUGOUT1(S, A...)
#endif

#define DEBUGFUNC(F) DEBUGOUT(F)
#define DEBUGOUT2 DEBUGOUT1
#define DEBUGOUT3 DEBUGOUT2
#define DEBUGOUT7 DEBUGOUT3


#define E1000_WRITE_REG(a, reg, value) ( \
    writel((value), ((a)->hw_addr + \
        (((a)->mac_type >= e1000_82543) ? E1000_##reg : E1000_82542_##reg))))

#define E1000_READ_REG(a, reg) ( \
    readl((a)->hw_addr + \
        (((a)->mac_type >= e1000_82543) ? E1000_##reg : E1000_82542_##reg)))

#define E1000_WRITE_REG_ARRAY(a, reg, offset, value) ( \
    writel((value), ((a)->hw_addr + \
        (((a)->mac_type >= e1000_82543) ? E1000_##reg : E1000_82542_##reg) + \
        ((offset) << 2))))

#define E1000_READ_REG_ARRAY(a, reg, offset) ( \
    readl((a)->hw_addr + \
        (((a)->mac_type >= e1000_82543) ? E1000_##reg : E1000_82542_##reg) + \
        ((offset) << 2)))

#define E1000_READ_REG_ARRAY_DWORD E1000_READ_REG_ARRAY
#define E1000_WRITE_REG_ARRAY_DWORD E1000_WRITE_REG_ARRAY

#define E1000_WRITE_REG_ARRAY_WORD(a, reg, offset, value) ( \
    writew((value), ((a)->hw_addr + \
        (((a)->mac_type >= e1000_82543) ? E1000_##reg : E1000_82542_##reg) + \
        ((offset) << 1))))

#define E1000_READ_REG_ARRAY_WORD(a, reg, offset) ( \
    readw((a)->hw_addr + \
        (((a)->mac_type >= e1000_82543) ? E1000_##reg : E1000_82542_##reg) + \
        ((offset) << 1)))

#define E1000_WRITE_REG_ARRAY_BYTE(a, reg, offset, value) ( \
    writeb((value), ((a)->hw_addr + \
        (((a)->mac_type >= e1000_82543) ? E1000_##reg : E1000_82542_##reg) + \
        (offset))))

#define E1000_READ_REG_ARRAY_BYTE(a, reg, offset) ( \
    readb((a)->hw_addr + \
        (((a)->mac_type >= e1000_82543) ? E1000_##reg : E1000_82542_##reg) + \
        (offset)))

#define E1000_WRITE_FLUSH(a) E1000_READ_REG(a, STATUS)

#endif /* _E1000_OSDEP_H_ */


<|start_filename|>3rdpart/ethercat-1.5.2/examples/user/main.c<|end_filename|>
/*****************************************************************************
 *
 *  $Id: main.c,v 6a6dec6fc806 2012/09/19 17:46:58 fp $
 *
 *  Copyright (C) 2007-2009  <NAME>, Ingenieurgemeinschaft IgH
 *
 *  This file is part of the IgH EtherCAT Master.
 *
 *  The IgH EtherCAT Master is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License version 2, as
 *  published by the Free Software Foundation.
 *
 *  The IgH EtherCAT Master is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 *  Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with the IgH EtherCAT Master; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 ****************************************************************************/

#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <sys/resource.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

/****************************************************************************/

#include "ecrt.h"

/****************************************************************************/

// Application parameters
#define FREQUENCY 100
#define PRIORITY 1

// Optional features
#define CONFIGURE_PDOS  1
#define SDO_ACCESS      0

/****************************************************************************/

// EtherCAT
static ec_master_t *master = NULL;
static ec_master_state_t master_state = {};

static ec_domain_t *domain1 = NULL;
static ec_domain_state_t domain1_state = {};

static ec_slave_config_t *sc_ana_in = NULL;
static ec_slave_config_state_t sc_ana_in_state = {};

// Timer
static unsigned int sig_alarms = 0;
static unsigned int user_alarms = 0;

/****************************************************************************/

// process data
static uint8_t *domain1_pd = NULL;

#define BusCouplerPos  0, 0
#define DigOutSlavePos 0, 2
#define AnaInSlavePos  0, 3
#define AnaOutSlavePos 0, 4

#define Beckhoff_EK1100 0x00000002, 0x044c2c52
#define Beckhoff_EL2004 0x00000002, 0x07d43052
#define Beckhoff_EL2032 0x00000002, 0x07f03052
#define Beckhoff_EL3152 0x00000002, 0x0c503052
#define Beckhoff_EL3102 0x00000002, 0x0c1e3052
#define Beckhoff_EL4102 0x00000002, 0x10063052

// offsets for PDO entries
static unsigned int off_ana_in_status;
static unsigned int off_ana_in_value;
static unsigned int off_ana_out;
static unsigned int off_dig_out;

const static ec_pdo_entry_reg_t domain1_regs[] = {
    {AnaInSlavePos,  Beckhoff_EL3102, 0x3101, 1, &off_ana_in_status},
    {AnaInSlavePos,  Beckhoff_EL3102, 0x3101, 2, &off_ana_in_value},
    {AnaOutSlavePos, Beckhoff_EL4102, 0x3001, 1, &off_ana_out},
    {DigOutSlavePos, Beckhoff_EL2032, 0x3001, 1, &off_dig_out},
    {}
};

static unsigned int counter = 0;
static unsigned int blink = 0;

/*****************************************************************************/

#if CONFIGURE_PDOS

// Analog in --------------------------

static ec_pdo_entry_info_t el3102_pdo_entries[] = {
    {0x3101, 1,  8}, // channel 1 status
    {0x3101, 2, 16}, // channel 1 value
    {0x3102, 1,  8}, // channel 2 status
    {0x3102, 2, 16}, // channel 2 value
    {0x6401, 1, 16}, // channel 1 value (alt.)
    {0x6401, 2, 16}  // channel 2 value (alt.)
};

static ec_pdo_info_t el3102_pdos[] = {
    {0x1A00, 2, el3102_pdo_entries},
    {0x1A01, 2, el3102_pdo_entries + 2}
};

static ec_sync_info_t el3102_syncs[] = {
    {2, EC_DIR_OUTPUT},
    {3, EC_DIR_INPUT, 2, el3102_pdos},
    {0xff}
};

// Analog out -------------------------

static ec_pdo_entry_info_t el4102_pdo_entries[] = {
    {0x3001, 1, 16}, // channel 1 value
    {0x3002, 1, 16}, // channel 2 value
};

static ec_pdo_info_t el4102_pdos[] = {
    {0x1600, 1, el4102_pdo_entries},
    {0x1601, 1, el4102_pdo_entries + 1}
};

static ec_sync_info_t el4102_syncs[] = {
    {2, EC_DIR_OUTPUT, 2, el4102_pdos},
    {3, EC_DIR_INPUT},
    {0xff}
};

// Digital out ------------------------

static ec_pdo_entry_info_t el2004_channels[] = {
    {0x3001, 1, 1}, // Value 1
    {0x3001, 2, 1}, // Value 2
    {0x3001, 3, 1}, // Value 3
    {0x3001, 4, 1}  // Value 4
};

static ec_pdo_info_t el2004_pdos[] = {
    {0x1600, 1, &el2004_channels[0]},
    {0x1601, 1, &el2004_channels[1]},
    {0x1602, 1, &el2004_channels[2]},
    {0x1603, 1, &el2004_channels[3]}
};

static ec_sync_info_t el2004_syncs[] = {
    {0, EC_DIR_OUTPUT, 4, el2004_pdos},
    {1, EC_DIR_INPUT},
    {0xff}
};
#endif

/*****************************************************************************/

#if SDO_ACCESS
static ec_sdo_request_t *sdo;
#endif

/*****************************************************************************/

void check_domain1_state(void)
{
    ec_domain_state_t ds;

    ecrt_domain_state(domain1, &ds);

    if (ds.working_counter != domain1_state.working_counter)
        printf("Domain1: WC %u.\n", ds.working_counter);
    if (ds.wc_state != domain1_state.wc_state)
        printf("Domain1: State %u.\n", ds.wc_state);

    domain1_state = ds;
}

/*****************************************************************************/

void check_master_state(void)
{
    ec_master_state_t ms;

    ecrt_master_state(master, &ms);

    if (ms.slaves_responding != master_state.slaves_responding)
        printf("%u slave(s).\n", ms.slaves_responding);
    if (ms.al_states != master_state.al_states)
        printf("AL states: 0x%02X.\n", ms.al_states);
    if (ms.link_up != master_state.link_up)
        printf("Link is %s.\n", ms.link_up ? "up" : "down");

    master_state = ms;
}

/*****************************************************************************/

void check_slave_config_states(void)
{
    ec_slave_config_state_t s;

    ecrt_slave_config_state(sc_ana_in, &s);

    if (s.al_state != sc_ana_in_state.al_state)
        printf("AnaIn: State 0x%02X.\n", s.al_state);
    if (s.online != sc_ana_in_state.online)
        printf("AnaIn: %s.\n", s.online ? "online" : "offline");
    if (s.operational != sc_ana_in_state.operational)
        printf("AnaIn: %soperational.\n",
                s.operational ? "" : "Not ");

    sc_ana_in_state = s;
}

/*****************************************************************************/

#if SDO_ACCESS
void read_sdo(void)
{
    switch (ecrt_sdo_request_state(sdo)) {
        case EC_REQUEST_UNUSED: // request was not used yet
            ecrt_sdo_request_read(sdo); // trigger first read
            break;
        case EC_REQUEST_BUSY:
            fprintf(stderr, "Still busy...\n");
            break;
        case EC_REQUEST_SUCCESS:
            fprintf(stderr, "SDO value: 0x%04X\n",
                    EC_READ_U16(ecrt_sdo_request_data(sdo)));
            ecrt_sdo_request_read(sdo); // trigger next read
            break;
        case EC_REQUEST_ERROR:
            fprintf(stderr, "Failed to read SDO!\n");
            ecrt_sdo_request_read(sdo); // retry reading
            break;
    }
}
#endif

/****************************************************************************/

void cyclic_task()
{
    // receive process data
    ecrt_master_receive(master);
    ecrt_domain_process(domain1);

    // check process data state (optional)
    check_domain1_state();

    if (counter) {
        counter--;
    } else { // do this at 1 Hz
        counter = FREQUENCY;

        // calculate new process data
        blink = !blink;

        // check for master state (optional)
        check_master_state();

        // check for islave configuration state(s) (optional)
        check_slave_config_states();

#if SDO_ACCESS
        // read process data SDO
        read_sdo();
#endif

    }

#if 0
    // read process data
    printf("AnaIn: state %u value %u\n",
            EC_READ_U8(domain1_pd + off_ana_in_status),
            EC_READ_U16(domain1_pd + off_ana_in_value));
#endif

#if 1
    // write process data
    EC_WRITE_U8(domain1_pd + off_dig_out, blink ? 0x06 : 0x09);
#endif

    // send process data
    ecrt_domain_queue(domain1);
    ecrt_master_send(master);
}

/****************************************************************************/

void signal_handler(int signum) {
    switch (signum) {
        case SIGALRM:
            sig_alarms++;
            break;
    }
}

/****************************************************************************/

int main(int argc, char **argv)
{
    ec_slave_config_t *sc;
    struct sigaction sa;
    struct itimerval tv;

    master = ecrt_request_master(0);
    if (!master)
        return -1;

    domain1 = ecrt_master_create_domain(master);
    if (!domain1)
        return -1;

    if (!(sc_ana_in = ecrt_master_slave_config(
                    master, AnaInSlavePos, Beckhoff_EL3102))) {
        fprintf(stderr, "Failed to get slave configuration.\n");
        return -1;
    }

#if SDO_ACCESS
    fprintf(stderr, "Creating SDO requests...\n");
    if (!(sdo = ecrt_slave_config_create_sdo_request(sc_ana_in, 0x3102, 2, 2))) {
        fprintf(stderr, "Failed to create SDO request.\n");
        return -1;
    }
    ecrt_sdo_request_timeout(sdo, 500); // ms
#endif

#if CONFIGURE_PDOS
    printf("Configuring PDOs...\n");
    if (ecrt_slave_config_pdos(sc_ana_in, EC_END, el3102_syncs)) {
        fprintf(stderr, "Failed to configure PDOs.\n");
        return -1;
    }

    if (!(sc = ecrt_master_slave_config(
                    master, AnaOutSlavePos, Beckhoff_EL4102))) {
        fprintf(stderr, "Failed to get slave configuration.\n");
        return -1;
    }

    if (ecrt_slave_config_pdos(sc, EC_END, el4102_syncs)) {
        fprintf(stderr, "Failed to configure PDOs.\n");
        return -1;
    }

    if (!(sc = ecrt_master_slave_config(
                    master, DigOutSlavePos, Beckhoff_EL2032))) {
        fprintf(stderr, "Failed to get slave configuration.\n");
        return -1;
    }

    if (ecrt_slave_config_pdos(sc, EC_END, el2004_syncs)) {
        fprintf(stderr, "Failed to configure PDOs.\n");
        return -1;
    }
#endif

    // Create configuration for bus coupler
    sc = ecrt_master_slave_config(master, BusCouplerPos, Beckhoff_EK1100);
    if (!sc)
        return -1;

    if (ecrt_domain_reg_pdo_entry_list(domain1, domain1_regs)) {
        fprintf(stderr, "PDO entry registration failed!\n");
        return -1;
    }

    printf("Activating master...\n");
    if (ecrt_master_activate(master))
        return -1;

    if (!(domain1_pd = ecrt_domain_data(domain1))) {
        return -1;
    }

#if PRIORITY
    pid_t pid = getpid();
    if (setpriority(PRIO_PROCESS, pid, -19))
        fprintf(stderr, "Warning: Failed to set priority: %s\n",
                strerror(errno));
#endif

    sa.sa_handler = signal_handler;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = 0;
    if (sigaction(SIGALRM, &sa, 0)) {
        fprintf(stderr, "Failed to install signal handler!\n");
        return -1;
    }

    printf("Starting timer...\n");
    tv.it_interval.tv_sec = 0;
    tv.it_interval.tv_usec = 1000000 / FREQUENCY;
    tv.it_value.tv_sec = 0;
    tv.it_value.tv_usec = 1000;
    if (setitimer(ITIMER_REAL, &tv, NULL)) {
        fprintf(stderr, "Failed to start timer: %s\n", strerror(errno));
        return 1;
    }

    printf("Started.\n");
    while (1) {
        pause();

#if 0
        struct timeval t;
        gettimeofday(&t, NULL);
        printf("%u.%06u\n", t.tv_sec, t.tv_usec);
#endif

        while (sig_alarms != user_alarms) {
            cyclic_task();
            user_alarms++;
        }
    }

    return 0;
}

/****************************************************************************/


<|start_filename|>rootfs/buildroot-2017.11.1/package/dhcp/dhcp.mk<|end_filename|>
################################################################################
#
# dhcp
#
################################################################################

DHCP_VERSION = 4.3.6
DHCP_SITE = http://ftp.isc.org/isc/dhcp/$(DHCP_VERSION)
DHCP_INSTALL_STAGING = YES
DHCP_LICENSE = ISC
DHCP_LICENSE_FILES = LICENSE
DHCP_CONF_ENV = \
	CPPFLAGS='-D_PATH_DHCPD_CONF=\"/etc/dhcp/dhcpd.conf\" \
		-D_PATH_DHCLIENT_CONF=\"/etc/dhcp/dhclient.conf\"'
DHCP_CONF_OPTS = \
	--with-randomdev=/dev/random \
	--with-srv-lease-file=/var/lib/dhcp/dhcpd.leases \
	--with-srv6-lease-file=/var/lib/dhcp/dhcpd6.leases \
	--with-cli-lease-file=/var/lib/dhcp/dhclient.leases \
	--with-cli6-lease-file=/var/lib/dhcp/dhclient6.leases \
	--with-srv-pid-file=/var/run/dhcpd.pid \
	--with-srv6-pid-file=/var/run/dhcpd6.pid \
	--with-cli-pid-file=/var/run/dhclient.pid \
	--with-cli6-pid-file=/var/run/dhclient6.pid \
	--with-relay-pid-file=/var/run/dhcrelay.pid \
	--with-relay6-pid-file=/var/run/dhcrelay6.pid

# The source for the bind libraries used by dhcp are embedded in the dhcp source
# as a tar-ball. Extract the bind source to allow any patches to be applied
# during the patch phase.
define DHCP_EXTRACT_BIND
	cd $(@D)/bind; tar -xvf bind.tar.gz
endef
DHCP_POST_EXTRACT_HOOKS += DHCP_EXTRACT_BIND

# The patchset requires configure et.al. to be regenerated.
DHCP_AUTORECONF = YES

# bind does not support parallel builds.
DHCP_MAKE = $(MAKE1)

# bind configure is called via dhcp make instead of dhcp configure. The make env
# needs extra values for bind configure.
DHCP_MAKE_ENV = \
	$(TARGET_CONFIGURE_OPTS) \
	BUILD_CC="$(HOSTCC)" \
	BUILD_CFLAGS="$(HOST_CFLAGS)" \
	BUILD_CPPFLAGS="$(HOST_CPPFLAGS)" \
	BUILD_LDFLAGS="$(HOST_LDFLAGS)"

ifeq ($(BR2_PACKAGE_DHCP_SERVER_DELAYED_ACK),y)
DHCP_CONF_OPTS += --enable-delayed-ack
endif

ifeq ($(BR2_PACKAGE_DHCP_SERVER),y)
define DHCP_INSTALL_SERVER
	mkdir -p $(TARGET_DIR)/var/lib
	(cd $(TARGET_DIR)/var/lib; ln -snf /tmp dhcp)
	$(INSTALL) -m 0755 -D $(@D)/server/dhcpd $(TARGET_DIR)/usr/sbin/dhcpd
	$(INSTALL) -m 0644 -D package/dhcp/dhcpd.conf \
		$(TARGET_DIR)/etc/dhcp/dhcpd.conf
endef
endif

ifeq ($(BR2_PACKAGE_DHCP_RELAY),y)
define DHCP_INSTALL_RELAY
	mkdir -p $(TARGET_DIR)/var/lib
	(cd $(TARGET_DIR)/var/lib; ln -snf /tmp dhcp)
	$(INSTALL) -m 0755 -D $(DHCP_DIR)/relay/dhcrelay \
		$(TARGET_DIR)/usr/sbin/dhcrelay
endef
endif

ifeq ($(BR2_PACKAGE_DHCP_CLIENT),y)
define DHCP_INSTALL_CLIENT
	mkdir -p $(TARGET_DIR)/var/lib
	(cd $(TARGET_DIR)/var/lib; ln -snf /tmp dhcp)
	$(INSTALL) -m 0755 -D $(DHCP_DIR)/client/dhclient \
		$(TARGET_DIR)/sbin/dhclient
	$(INSTALL) -m 0644 -D package/dhcp/dhclient.conf \
		$(TARGET_DIR)/etc/dhcp/dhclient.conf
	$(INSTALL) -m 0755 -D package/dhcp/dhclient-script \
		$(TARGET_DIR)/sbin/dhclient-script
endef
endif

# Options don't matter, scripts won't start if binaries aren't there
define DHCP_INSTALL_INIT_SYSV
	$(INSTALL) -m 0755 -D package/dhcp/S80dhcp-server \
		$(TARGET_DIR)/etc/init.d/S80dhcp-server
	$(INSTALL) -m 0755 -D package/dhcp/S80dhcp-relay \
		$(TARGET_DIR)/etc/init.d/S80dhcp-relay
endef

ifeq ($(BR2_PACKAGE_DHCP_SERVER),y)
define DHCP_INSTALL_INIT_SYSTEMD
	$(INSTALL) -D -m 644 package/dhcp/dhcpd.service \
		$(TARGET_DIR)/usr/lib/systemd/system/dhcpd.service

	mkdir -p $(TARGET_DIR)/etc/systemd/system/multi-user.target.wants

	ln -sf ../../../../usr/lib/systemd/system/dhcpd.service \
		$(TARGET_DIR)/etc/systemd/system/multi-user.target.wants/dhcpd.service

	mkdir -p $(TARGET_DIR)/usr/lib/tmpfiles.d
	echo "d /var/lib/dhcp 0755 - - - -" > \
		$(TARGET_DIR)/usr/lib/tmpfiles.d/dhcpd.conf
	echo "f /var/lib/dhcp/dhcpd.leases - - - - -" >> \
		$(TARGET_DIR)/usr/lib/tmpfiles.d/dhcpd.conf
endef
endif

define DHCP_INSTALL_TARGET_CMDS
	$(DHCP_INSTALL_RELAY)
	$(DHCP_INSTALL_SERVER)
	$(DHCP_INSTALL_CLIENT)
endef

$(eval $(autotools-package))


<|start_filename|>3rdpart/tslib-1.15/tests/ts_print_raw.c<|end_filename|>
/*
 *  tslib/tests/ts_print_raw.c
 *
 *  Derived from tslib/src/ts_test.c by <NAME>
 *  Just prints touchscreen events -- does not paint them on framebuffer
 *
 * This file is placed under the GPL.  Please see the file
 * COPYING for more details.
 *
 * SPDX-License-Identifier: GPL-2.0+
 *
 *
 * Basic test program for touchscreen library.
 */
#include <stdio.h>
#include <stdlib.h>

#include "tslib.h"


int main(void)
{
	struct tsdev *ts;

	ts = ts_setup(NULL, 0);
	if (!ts) {
		perror("ts_setup");
		exit(1);
	}

	while (1) {
		struct ts_sample samp;
		int ret;

		ret = ts_read_raw(ts, &samp, 1);

		if (ret < 0) {
			perror("ts_read_raw");
			ts_close(ts);
			exit(1);
		}

		if (ret != 1)
			continue;

		printf("%ld.%06ld: %6d %6d %6d\n", samp.tv.tv_sec, samp.tv.tv_usec, samp.x, samp.y, samp.pressure);

	}

	ts_close(ts);
}


<|start_filename|>3rdpart/ethercat-1.5.2/master/fsm_slave_config.h<|end_filename|>
/******************************************************************************
 *
 *  $Id: fsm_slave_config.h,v 06b53ebfa0c3 2012/12/06 13:06:10 fp $
 *
 *  Copyright (C) 2006-2008  <NAME>, Ingenieurgemeinschaft IgH
 *
 *  This file is part of the IgH EtherCAT Master.
 *
 *  The IgH EtherCAT Master is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License version 2, as
 *  published by the Free Software Foundation.
 *
 *  The IgH EtherCAT Master is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 *  Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with the IgH EtherCAT Master; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 *****************************************************************************/

/**
   \file
   EtherCAT slave configuration state machine.
*/

/*****************************************************************************/

#ifndef __EC_FSM_SLAVE_CONFIG_H__
#define __EC_FSM_SLAVE_CONFIG_H__

#include "globals.h"
#include "slave.h"
#include "datagram.h"
#include "fsm_change.h"
#include "fsm_coe.h"
#include "fsm_pdo.h"

/*****************************************************************************/

/** \see ec_fsm_slave_config */
typedef struct ec_fsm_slave_config ec_fsm_slave_config_t;

/** Finite state machine to configure an EtherCAT slave.
 */
struct ec_fsm_slave_config
{
    ec_datagram_t *datagram; /**< Datagram used in the state machine. */
    ec_fsm_change_t *fsm_change; /**< State change state machine. */
    ec_fsm_coe_t *fsm_coe; /**< CoE state machine. */
    ec_fsm_soe_t *fsm_soe; /**< SoE state machine. */
    ec_fsm_pdo_t *fsm_pdo; /**< PDO configuration state machine. */

    ec_slave_t *slave; /**< Slave the FSM runs on. */
    void (*state)(ec_fsm_slave_config_t *); /**< State function. */
    unsigned int retries; /**< Retries on datagram timeout. */
    ec_sdo_request_t *request; /**< SDO request for SDO configuration. */
    ec_sdo_request_t request_copy; /**< Copied SDO request. */
    ec_soe_request_t *soe_request; /**< SDO request for SDO configuration. */
    ec_soe_request_t soe_request_copy; /**< Copied SDO request. */
    unsigned long jiffies_start; /**< For timeout calculations. */
    unsigned int take_time; /**< Store jiffies after datagram reception. */
};

/*****************************************************************************/

void ec_fsm_slave_config_init(ec_fsm_slave_config_t *, ec_datagram_t *,
        ec_fsm_change_t *, ec_fsm_coe_t *, ec_fsm_soe_t *, ec_fsm_pdo_t *);
void ec_fsm_slave_config_clear(ec_fsm_slave_config_t *);

void ec_fsm_slave_config_start(ec_fsm_slave_config_t *, ec_slave_t *);

int ec_fsm_slave_config_exec(ec_fsm_slave_config_t *);
int ec_fsm_slave_config_success(const ec_fsm_slave_config_t *);

/*****************************************************************************/

#endif


<|start_filename|>3rdpart/ethercat-1.5.2/master/sdo_entry.c<|end_filename|>
/******************************************************************************
 *
 *  $Id: sdo_entry.c,v cb2188d111f3 2009/04/08 08:13:33 fp $
 *
 *  Copyright (C) 2006-2008  <NAME>, Ingenieurgemeinschaft IgH
 *
 *  This file is part of the IgH EtherCAT Master.
 *
 *  The IgH EtherCAT Master is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License version 2, as
 *  published by the Free Software Foundation.
 *
 *  The IgH EtherCAT Master is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 *  Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with the IgH EtherCAT Master; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 *****************************************************************************/

/**
   \file
   CANopen over EtherCAT SDO entry functions.
*/

/*****************************************************************************/

#include <linux/slab.h>

#include "sdo_entry.h"

/*****************************************************************************/

/** Constructor.
 */
void ec_sdo_entry_init(
        ec_sdo_entry_t *entry, /**< SDO entry. */
        ec_sdo_t *sdo, /**< Parent SDO. */
        uint8_t subindex /**< Subindex. */
        )
{
    entry->sdo = sdo;
    entry->subindex = subindex;
    entry->data_type = 0x0000;
    entry->bit_length = 0;
    entry->read_access[EC_SDO_ENTRY_ACCESS_PREOP] = 0;
    entry->read_access[EC_SDO_ENTRY_ACCESS_SAFEOP] = 0;
    entry->read_access[EC_SDO_ENTRY_ACCESS_OP] = 0;
    entry->write_access[EC_SDO_ENTRY_ACCESS_PREOP] = 0;
    entry->write_access[EC_SDO_ENTRY_ACCESS_SAFEOP] = 0;
    entry->write_access[EC_SDO_ENTRY_ACCESS_OP] = 0;
    entry->description = NULL;
}

/*****************************************************************************/

/** Destructor.
 */
void ec_sdo_entry_clear(
        ec_sdo_entry_t *entry /**< SDO entry. */
        )
{

    if (entry->description)
        kfree(entry->description);
}

/*****************************************************************************/


<|start_filename|>3rdpart/ethercat-1.5.2/tool/CommandFoeRead.cpp<|end_filename|>
/*****************************************************************************
 *
 *  $Id: CommandFoeRead.cpp,v 4f682084c643 2010/10/25 08:12:26 fp $
 *
 *  Copyright (C) 2006-2009  <NAME>, Ingenieurgemeinschaft IgH
 *
 *  This file is part of the IgH EtherCAT Master.
 *
 *  The IgH EtherCAT Master is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License version 2, as
 *  published by the Free Software Foundation.
 *
 *  The IgH EtherCAT Master is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 *  Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with the IgH EtherCAT Master; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 ****************************************************************************/

#include <string.h>

#include <iostream>
#include <iomanip>
using namespace std;

#include "CommandFoeRead.h"
#include "foe.h"
#include "MasterDevice.h"

/*****************************************************************************/

CommandFoeRead::CommandFoeRead():
    FoeCommand("foe_read", "Read a file from a slave via FoE.")
{
}

/*****************************************************************************/

string CommandFoeRead::helpString(const string &binaryBaseName) const
{
    stringstream str;

    str << binaryBaseName << " " << getName()
        << " [OPTIONS] <SOURCEFILE>" << endl
        << endl
        << getBriefDescription() << endl
        << endl
        << "This command requires a single slave to be selected." << endl
        << endl
        << "Arguments:" << endl
        << "  SOURCEFILE is the name of the source file on the slave." << endl
        << endl
        << "Command-specific options:" << endl
        << "  --output-file -o <file>   Local target filename. If" << endl
        << "                            '-' (default), data are" << endl
        << "                            printed to stdout." << endl
        << "  --alias       -a <alias>  " << endl
        << "  --position    -p <pos>    Slave selection. See the help" << endl
        << "                            of the 'slaves' command." << endl
        << endl
        << numericInfo();

    return str.str();
}

/****************************************************************************/

void CommandFoeRead::execute(const StringVector &args)
{
    SlaveList slaves;
    ec_ioctl_slave_t *slave;
    ec_ioctl_slave_foe_t data;
    unsigned int i;
    stringstream err;

    if (args.size() != 1) {
        err << "'" << getName() << "' takes exactly one argument!";
        throwInvalidUsageException(err);
    }

    MasterDevice m(getSingleMasterIndex());
    m.open(MasterDevice::Read);
    slaves = selectedSlaves(m);

    if (slaves.size() != 1) {
        throwSingleSlaveRequired(slaves.size());
    }
    slave = &slaves.front();
    data.slave_position = slave->position;

    /* FIXME: No good idea to have a fixed buffer size.
     * Read in chunks and fill a buffer instead.
     */
    data.offset = 0;
    data.buffer_size = 0x8800;
    data.buffer = new uint8_t[data.buffer_size];

    strncpy(data.file_name, args[0].c_str(), sizeof(data.file_name));

    try {
        m.readFoe(&data);
    } catch (MasterDeviceException &e) {
        delete [] data.buffer;
        if (data.result) {
            if (data.result == FOE_OPCODE_ERROR) {
                err << "FoE read aborted with error code 0x"
                    << setw(8) << setfill('0') << hex << data.error_code
                    << ": " << errorText(data.error_code);
            } else {
                err << "Failed to write via FoE: "
                    << resultText(data.result);
            }
            throwCommandException(err);
        } else {
            throw e;
        }
    }

    // TODO --output-file
    for (i = 0; i < data.data_size; i++) {
        uint8_t *w = data.buffer + i;
        cout << *(uint8_t *) w ;
    }

    delete [] data.buffer;
}

/*****************************************************************************/


<|start_filename|>3rdpart/ethercat-1.5.2/devices/e1000/e1000_param-2.6.24-ethercat.c<|end_filename|>
/*******************************************************************************

  Intel PRO/1000 Linux driver
  Copyright(c) 1999 - 2006 Intel Corporation.

  This program is free software; you can redistribute it and/or modify it
  under the terms and conditions of the GNU General Public License,
  version 2, as published by the Free Software Foundation.

  This program is distributed in the hope it will be useful, but WITHOUT
  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  more details.

  You should have received a copy of the GNU General Public License along with
  this program; if not, write to the Free Software Foundation, Inc.,
  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.

  The full GNU General Public License is included in this distribution in
  the file called "COPYING".

  Contact Information:
  Linux NICS <<EMAIL>>
  e1000-devel Mailing List <<EMAIL>>
  Intel Corporation, 5200 N.E. <NAME>way, Hillsboro, OR 97124-6497

*******************************************************************************/

#include "e1000-2.6.24-ethercat.h"

/* This is the only thing that needs to be changed to adjust the
 * maximum number of ports that the driver can manage.
 */

#define E1000_MAX_NIC 32

#define OPTION_UNSET   -1
#define OPTION_DISABLED 0
#define OPTION_ENABLED  1

/* All parameters are treated the same, as an integer array of values.
 * This macro just reduces the need to repeat the same declaration code
 * over and over (plus this helps to avoid typo bugs).
 */

#define E1000_PARAM_INIT { [0 ... E1000_MAX_NIC] = OPTION_UNSET }
#define E1000_PARAM(X, desc) \
	static int __devinitdata X[E1000_MAX_NIC+1] = E1000_PARAM_INIT; \
	static unsigned int num_##X; \
	module_param_array_named(X, X, int, &num_##X, 0); \
	MODULE_PARM_DESC(X, desc);

/* Transmit Descriptor Count
 *
 * Valid Range: 80-256 for 82542 and 82543 gigabit ethernet controllers
 * Valid Range: 80-4096 for 82544 and newer
 *
 * Default Value: 256
 */
E1000_PARAM(TxDescriptors, "Number of transmit descriptors");

/* Receive Descriptor Count
 *
 * Valid Range: 80-256 for 82542 and 82543 gigabit ethernet controllers
 * Valid Range: 80-4096 for 82544 and newer
 *
 * Default Value: 256
 */
E1000_PARAM(RxDescriptors, "Number of receive descriptors");

/* User Specified Speed Override
 *
 * Valid Range: 0, 10, 100, 1000
 *  - 0    - auto-negotiate at all supported speeds
 *  - 10   - only link at 10 Mbps
 *  - 100  - only link at 100 Mbps
 *  - 1000 - only link at 1000 Mbps
 *
 * Default Value: 0
 */
E1000_PARAM(Speed, "Speed setting");

/* User Specified Duplex Override
 *
 * Valid Range: 0-2
 *  - 0 - auto-negotiate for duplex
 *  - 1 - only link at half duplex
 *  - 2 - only link at full duplex
 *
 * Default Value: 0
 */
E1000_PARAM(Duplex, "Duplex setting");

/* Auto-negotiation Advertisement Override
 *
 * Valid Range: 0x01-0x0F, 0x20-0x2F (copper); 0x20 (fiber)
 *
 * The AutoNeg value is a bit mask describing which speed and duplex
 * combinations should be advertised during auto-negotiation.
 * The supported speed and duplex modes are listed below
 *
 * Bit           7     6     5      4      3     2     1      0
 * Speed (Mbps)  N/A   N/A   1000   N/A    100   100   10     10
 * Duplex                    Full          Full  Half  Full   Half
 *
 * Default Value: 0x2F (copper); 0x20 (fiber)
 */
E1000_PARAM(AutoNeg, "Advertised auto-negotiation setting");
#define AUTONEG_ADV_DEFAULT  0x2F
#define AUTONEG_ADV_MASK     0x2F

/* User Specified Flow Control Override
 *
 * Valid Range: 0-3
 *  - 0 - No Flow Control
 *  - 1 - Rx only, respond to PAUSE frames but do not generate them
 *  - 2 - Tx only, generate PAUSE frames but ignore them on receive
 *  - 3 - Full Flow Control Support
 *
 * Default Value: Read flow control settings from the EEPROM
 */
E1000_PARAM(FlowControl, "Flow Control setting");
#define FLOW_CONTROL_DEFAULT FLOW_CONTROL_FULL

/* XsumRX - Receive Checksum Offload Enable/Disable
 *
 * Valid Range: 0, 1
 *  - 0 - disables all checksum offload
 *  - 1 - enables receive IP/TCP/UDP checksum offload
 *        on 82543 and newer -based NICs
 *
 * Default Value: 1
 */
E1000_PARAM(XsumRX, "Disable or enable Receive Checksum offload");

/* Transmit Interrupt Delay in units of 1.024 microseconds
 *  Tx interrupt delay needs to typically be set to something non zero
 *
 * Valid Range: 0-65535
 */
E1000_PARAM(TxIntDelay, "Transmit Interrupt Delay");
#define DEFAULT_TIDV                   8
#define MAX_TXDELAY               0xFFFF
#define MIN_TXDELAY                    0

/* Transmit Absolute Interrupt Delay in units of 1.024 microseconds
 *
 * Valid Range: 0-65535
 */
E1000_PARAM(TxAbsIntDelay, "Transmit Absolute Interrupt Delay");
#define DEFAULT_TADV                  32
#define MAX_TXABSDELAY            0xFFFF
#define MIN_TXABSDELAY                 0

/* Receive Interrupt Delay in units of 1.024 microseconds
 *   hardware will likely hang if you set this to anything but zero.
 *
 * Valid Range: 0-65535
 */
E1000_PARAM(RxIntDelay, "Receive Interrupt Delay");
#define DEFAULT_RDTR                   0
#define MAX_RXDELAY               0xFFFF
#define MIN_RXDELAY                    0

/* Receive Absolute Interrupt Delay in units of 1.024 microseconds
 *
 * Valid Range: 0-65535
 */
E1000_PARAM(RxAbsIntDelay, "Receive Absolute Interrupt Delay");
#define DEFAULT_RADV                   8
#define MAX_RXABSDELAY            0xFFFF
#define MIN_RXABSDELAY                 0

/* Interrupt Throttle Rate (interrupts/sec)
 *
 * Valid Range: 100-100000 (0=off, 1=dynamic, 3=dynamic conservative)
 */
E1000_PARAM(InterruptThrottleRate, "Interrupt Throttling Rate");
#define DEFAULT_ITR                    3
#define MAX_ITR                   100000
#define MIN_ITR                      100

/* Enable Smart Power Down of the PHY
 *
 * Valid Range: 0, 1
 *
 * Default Value: 0 (disabled)
 */
E1000_PARAM(SmartPowerDownEnable, "Enable PHY smart power down");

/* Enable Kumeran Lock Loss workaround
 *
 * Valid Range: 0, 1
 *
 * Default Value: 1 (enabled)
 */
E1000_PARAM(KumeranLockLoss, "Enable Kumeran lock loss workaround");

struct e1000_option {
	enum { enable_option, range_option, list_option } type;
	const char *name;
	const char *err;
	int def;
	union {
		struct { /* range_option info */
			int min;
			int max;
		} r;
		struct { /* list_option info */
			int nr;
			struct e1000_opt_list { int i; char *str; } *p;
		} l;
	} arg;
};

static int __devinit
e1000_validate_option(unsigned int *value,
		      const struct e1000_option *opt,
		      struct e1000_adapter *adapter)
{
	if (*value == OPTION_UNSET) {
		*value = opt->def;
		return 0;
	}

	switch (opt->type) {
	case enable_option:
		switch (*value) {
		case OPTION_ENABLED:
			DPRINTK(PROBE, INFO, "%s Enabled\n", opt->name);
			return 0;
		case OPTION_DISABLED:
			DPRINTK(PROBE, INFO, "%s Disabled\n", opt->name);
			return 0;
		}
		break;
	case range_option:
		if (*value >= opt->arg.r.min && *value <= opt->arg.r.max) {
			DPRINTK(PROBE, INFO,
					"%s set to %i\n", opt->name, *value);
			return 0;
		}
		break;
	case list_option: {
		int i;
		struct e1000_opt_list *ent;

		for (i = 0; i < opt->arg.l.nr; i++) {
			ent = &opt->arg.l.p[i];
			if (*value == ent->i) {
				if (ent->str[0] != '\0')
					DPRINTK(PROBE, INFO, "%s\n", ent->str);
				return 0;
			}
		}
	}
		break;
	default:
		BUG();
	}

	DPRINTK(PROBE, INFO, "Invalid %s value specified (%i) %s\n",
	       opt->name, *value, opt->err);
	*value = opt->def;
	return -1;
}

static void e1000_check_fiber_options(struct e1000_adapter *adapter);
static void e1000_check_copper_options(struct e1000_adapter *adapter);

/**
 * e1000_check_options - Range Checking for Command Line Parameters
 * @adapter: board private structure
 *
 * This routine checks all command line parameters for valid user
 * input.  If an invalid value is given, or if no user specified
 * value exists, a default value is used.  The final value is stored
 * in a variable in the adapter structure.
 **/

void __devinit
e1000_check_options(struct e1000_adapter *adapter)
{
	int bd = adapter->bd_number;
	if (bd >= E1000_MAX_NIC) {
		DPRINTK(PROBE, NOTICE,
		       "Warning: no configuration for board #%i\n", bd);
		DPRINTK(PROBE, NOTICE, "Using defaults for all values\n");
	}

	{ /* Transmit Descriptor Count */
		struct e1000_option opt = {
			.type = range_option,
			.name = "Transmit Descriptors",
			.err  = "using default of "
				__MODULE_STRING(E1000_DEFAULT_TXD),
			.def  = E1000_DEFAULT_TXD,
			.arg  = { .r = { .min = E1000_MIN_TXD }}
		};
		struct e1000_tx_ring *tx_ring = adapter->tx_ring;
		int i;
		e1000_mac_type mac_type = adapter->hw.mac_type;
		opt.arg.r.max = mac_type < e1000_82544 ?
			E1000_MAX_TXD : E1000_MAX_82544_TXD;

		if (num_TxDescriptors > bd) {
			tx_ring->count = TxDescriptors[bd];
			e1000_validate_option(&tx_ring->count, &opt, adapter);
			tx_ring->count = ALIGN(tx_ring->count,
						REQ_TX_DESCRIPTOR_MULTIPLE);
		} else {
			tx_ring->count = opt.def;
		}
		for (i = 0; i < adapter->num_tx_queues; i++)
			tx_ring[i].count = tx_ring->count;
	}
	{ /* Receive Descriptor Count */
		struct e1000_option opt = {
			.type = range_option,
			.name = "Receive Descriptors",
			.err  = "using default of "
				__MODULE_STRING(E1000_DEFAULT_RXD),
			.def  = E1000_DEFAULT_RXD,
			.arg  = { .r = { .min = E1000_MIN_RXD }}
		};
		struct e1000_rx_ring *rx_ring = adapter->rx_ring;
		int i;
		e1000_mac_type mac_type = adapter->hw.mac_type;
		opt.arg.r.max = mac_type < e1000_82544 ? E1000_MAX_RXD :
			E1000_MAX_82544_RXD;

		if (num_RxDescriptors > bd) {
			rx_ring->count = RxDescriptors[bd];
			e1000_validate_option(&rx_ring->count, &opt, adapter);
			rx_ring->count = ALIGN(rx_ring->count,
						REQ_RX_DESCRIPTOR_MULTIPLE);
		} else {
			rx_ring->count = opt.def;
		}
		for (i = 0; i < adapter->num_rx_queues; i++)
			rx_ring[i].count = rx_ring->count;
	}
	{ /* Checksum Offload Enable/Disable */
		struct e1000_option opt = {
			.type = enable_option,
			.name = "Checksum Offload",
			.err  = "defaulting to Enabled",
			.def  = OPTION_ENABLED
		};

		if (num_XsumRX > bd) {
			unsigned int rx_csum = XsumRX[bd];
			e1000_validate_option(&rx_csum, &opt, adapter);
			adapter->rx_csum = rx_csum;
		} else {
			adapter->rx_csum = opt.def;
		}
	}
	{ /* Flow Control */

		struct e1000_opt_list fc_list[] =
			{{ E1000_FC_NONE,    "Flow Control Disabled" },
			 { E1000_FC_RX_PAUSE,"Flow Control Receive Only" },
			 { E1000_FC_TX_PAUSE,"Flow Control Transmit Only" },
			 { E1000_FC_FULL,    "Flow Control Enabled" },
			 { E1000_FC_DEFAULT, "Flow Control Hardware Default" }};

		struct e1000_option opt = {
			.type = list_option,
			.name = "Flow Control",
			.err  = "reading default settings from EEPROM",
			.def  = E1000_FC_DEFAULT,
			.arg  = { .l = { .nr = ARRAY_SIZE(fc_list),
					 .p = fc_list }}
		};

		if (num_FlowControl > bd) {
			unsigned int fc = FlowControl[bd];
			e1000_validate_option(&fc, &opt, adapter);
			adapter->hw.fc = adapter->hw.original_fc = fc;
		} else {
			adapter->hw.fc = adapter->hw.original_fc = opt.def;
		}
	}
	{ /* Transmit Interrupt Delay */
		struct e1000_option opt = {
			.type = range_option,
			.name = "Transmit Interrupt Delay",
			.err  = "using default of " __MODULE_STRING(DEFAULT_TIDV),
			.def  = DEFAULT_TIDV,
			.arg  = { .r = { .min = MIN_TXDELAY,
					 .max = MAX_TXDELAY }}
		};

		if (num_TxIntDelay > bd) {
			adapter->tx_int_delay = TxIntDelay[bd];
			e1000_validate_option(&adapter->tx_int_delay, &opt,
			                      adapter);
		} else {
			adapter->tx_int_delay = opt.def;
		}
	}
	{ /* Transmit Absolute Interrupt Delay */
		struct e1000_option opt = {
			.type = range_option,
			.name = "Transmit Absolute Interrupt Delay",
			.err  = "using default of " __MODULE_STRING(DEFAULT_TADV),
			.def  = DEFAULT_TADV,
			.arg  = { .r = { .min = MIN_TXABSDELAY,
					 .max = MAX_TXABSDELAY }}
		};

		if (num_TxAbsIntDelay > bd) {
			adapter->tx_abs_int_delay = TxAbsIntDelay[bd];
			e1000_validate_option(&adapter->tx_abs_int_delay, &opt,
			                      adapter);
		} else {
			adapter->tx_abs_int_delay = opt.def;
		}
	}
	{ /* Receive Interrupt Delay */
		struct e1000_option opt = {
			.type = range_option,
			.name = "Receive Interrupt Delay",
			.err  = "using default of " __MODULE_STRING(DEFAULT_RDTR),
			.def  = DEFAULT_RDTR,
			.arg  = { .r = { .min = MIN_RXDELAY,
					 .max = MAX_RXDELAY }}
		};

		if (num_RxIntDelay > bd) {
			adapter->rx_int_delay = RxIntDelay[bd];
			e1000_validate_option(&adapter->rx_int_delay, &opt,
			                      adapter);
		} else {
			adapter->rx_int_delay = opt.def;
		}
	}
	{ /* Receive Absolute Interrupt Delay */
		struct e1000_option opt = {
			.type = range_option,
			.name = "Receive Absolute Interrupt Delay",
			.err  = "using default of " __MODULE_STRING(DEFAULT_RADV),
			.def  = DEFAULT_RADV,
			.arg  = { .r = { .min = MIN_RXABSDELAY,
					 .max = MAX_RXABSDELAY }}
		};

		if (num_RxAbsIntDelay > bd) {
			adapter->rx_abs_int_delay = RxAbsIntDelay[bd];
			e1000_validate_option(&adapter->rx_abs_int_delay, &opt,
			                      adapter);
		} else {
			adapter->rx_abs_int_delay = opt.def;
		}
	}
	{ /* Interrupt Throttling Rate */
		struct e1000_option opt = {
			.type = range_option,
			.name = "Interrupt Throttling Rate (ints/sec)",
			.err  = "using default of " __MODULE_STRING(DEFAULT_ITR),
			.def  = DEFAULT_ITR,
			.arg  = { .r = { .min = MIN_ITR,
					 .max = MAX_ITR }}
		};

		if (num_InterruptThrottleRate > bd) {
			adapter->itr = InterruptThrottleRate[bd];
			switch (adapter->itr) {
			case 0:
				DPRINTK(PROBE, INFO, "%s turned off\n",
				        opt.name);
				break;
			case 1:
				DPRINTK(PROBE, INFO, "%s set to dynamic mode\n",
					opt.name);
				adapter->itr_setting = adapter->itr;
				adapter->itr = 20000;
				break;
			case 3:
				DPRINTK(PROBE, INFO,
				        "%s set to dynamic conservative mode\n",
					opt.name);
				adapter->itr_setting = adapter->itr;
				adapter->itr = 20000;
				break;
			default:
				e1000_validate_option(&adapter->itr, &opt,
				        adapter);
				/* save the setting, because the dynamic bits change itr */
				/* clear the lower two bits because they are
				 * used as control */
				adapter->itr_setting = adapter->itr & ~3;
				break;
			}
		} else {
			adapter->itr_setting = opt.def;
			adapter->itr = 20000;
		}
	}
	{ /* Smart Power Down */
		struct e1000_option opt = {
			.type = enable_option,
			.name = "PHY Smart Power Down",
			.err  = "defaulting to Disabled",
			.def  = OPTION_DISABLED
		};

		if (num_SmartPowerDownEnable > bd) {
			unsigned int spd = SmartPowerDownEnable[bd];
			e1000_validate_option(&spd, &opt, adapter);
			adapter->smart_power_down = spd;
		} else {
			adapter->smart_power_down = opt.def;
		}
	}
	{ /* Kumeran Lock Loss Workaround */
		struct e1000_option opt = {
			.type = enable_option,
			.name = "Kumeran Lock Loss Workaround",
			.err  = "defaulting to Enabled",
			.def  = OPTION_ENABLED
		};

		if (num_KumeranLockLoss > bd) {
			unsigned int kmrn_lock_loss = KumeranLockLoss[bd];
			e1000_validate_option(&kmrn_lock_loss, &opt, adapter);
			adapter->hw.kmrn_lock_loss_workaround_disabled = !kmrn_lock_loss;
		} else {
			adapter->hw.kmrn_lock_loss_workaround_disabled = !opt.def;
		}
	}

	switch (adapter->hw.media_type) {
	case e1000_media_type_fiber:
	case e1000_media_type_internal_serdes:
		e1000_check_fiber_options(adapter);
		break;
	case e1000_media_type_copper:
		e1000_check_copper_options(adapter);
		break;
	default:
		BUG();
	}
}

/**
 * e1000_check_fiber_options - Range Checking for Link Options, Fiber Version
 * @adapter: board private structure
 *
 * Handles speed and duplex options on fiber adapters
 **/

static void __devinit
e1000_check_fiber_options(struct e1000_adapter *adapter)
{
	int bd = adapter->bd_number;
	if (num_Speed > bd) {
		DPRINTK(PROBE, INFO, "Speed not valid for fiber adapters, "
		       "parameter ignored\n");
	}

	if (num_Duplex > bd) {
		DPRINTK(PROBE, INFO, "Duplex not valid for fiber adapters, "
		       "parameter ignored\n");
	}

	if ((num_AutoNeg > bd) && (AutoNeg[bd] != 0x20)) {
		DPRINTK(PROBE, INFO, "AutoNeg other than 1000/Full is "
				 "not valid for fiber adapters, "
				 "parameter ignored\n");
	}
}

/**
 * e1000_check_copper_options - Range Checking for Link Options, Copper Version
 * @adapter: board private structure
 *
 * Handles speed and duplex options on copper adapters
 **/

static void __devinit
e1000_check_copper_options(struct e1000_adapter *adapter)
{
	unsigned int speed, dplx, an;
	int bd = adapter->bd_number;

	{ /* Speed */
		struct e1000_opt_list speed_list[] = {{          0, "" },
						      {   SPEED_10, "" },
						      {  SPEED_100, "" },
						      { SPEED_1000, "" }};

		struct e1000_option opt = {
			.type = list_option,
			.name = "Speed",
			.err  = "parameter ignored",
			.def  = 0,
			.arg  = { .l = { .nr = ARRAY_SIZE(speed_list),
					 .p = speed_list }}
		};

		if (num_Speed > bd) {
			speed = Speed[bd];
			e1000_validate_option(&speed, &opt, adapter);
		} else {
			speed = opt.def;
		}
	}
	{ /* Duplex */
		struct e1000_opt_list dplx_list[] = {{           0, "" },
						     { HALF_DUPLEX, "" },
						     { FULL_DUPLEX, "" }};

		struct e1000_option opt = {
			.type = list_option,
			.name = "Duplex",
			.err  = "parameter ignored",
			.def  = 0,
			.arg  = { .l = { .nr = ARRAY_SIZE(dplx_list),
					 .p = dplx_list }}
		};

		if (e1000_check_phy_reset_block(&adapter->hw)) {
			DPRINTK(PROBE, INFO,
				"Link active due to SoL/IDER Session. "
			        "Speed/Duplex/AutoNeg parameter ignored.\n");
			return;
		}
		if (num_Duplex > bd) {
			dplx = Duplex[bd];
			e1000_validate_option(&dplx, &opt, adapter);
		} else {
			dplx = opt.def;
		}
	}

	if ((num_AutoNeg > bd) && (speed != 0 || dplx != 0)) {
		DPRINTK(PROBE, INFO,
		       "AutoNeg specified along with Speed or Duplex, "
		       "parameter ignored\n");
		adapter->hw.autoneg_advertised = AUTONEG_ADV_DEFAULT;
	} else { /* Autoneg */
		struct e1000_opt_list an_list[] =
			#define AA "AutoNeg advertising "
			{{ 0x01, AA "10/HD" },
			 { 0x02, AA "10/FD" },
			 { 0x03, AA "10/FD, 10/HD" },
			 { 0x04, AA "100/HD" },
			 { 0x05, AA "100/HD, 10/HD" },
			 { 0x06, AA "100/HD, 10/FD" },
			 { 0x07, AA "100/HD, 10/FD, 10/HD" },
			 { 0x08, AA "100/FD" },
			 { 0x09, AA "100/FD, 10/HD" },
			 { 0x0a, AA "100/FD, 10/FD" },
			 { 0x0b, AA "100/FD, 10/FD, 10/HD" },
			 { 0x0c, AA "100/FD, 100/HD" },
			 { 0x0d, AA "100/FD, 100/HD, 10/HD" },
			 { 0x0e, AA "100/FD, 100/HD, 10/FD" },
			 { 0x0f, AA "100/FD, 100/HD, 10/FD, 10/HD" },
			 { 0x20, AA "1000/FD" },
			 { 0x21, AA "1000/FD, 10/HD" },
			 { 0x22, AA "1000/FD, 10/FD" },
			 { 0x23, AA "1000/FD, 10/FD, 10/HD" },
			 { 0x24, AA "1000/FD, 100/HD" },
			 { 0x25, AA "1000/FD, 100/HD, 10/HD" },
			 { 0x26, AA "1000/FD, 100/HD, 10/FD" },
			 { 0x27, AA "1000/FD, 100/HD, 10/FD, 10/HD" },
			 { 0x28, AA "1000/FD, 100/FD" },
			 { 0x29, AA "1000/FD, 100/FD, 10/HD" },
			 { 0x2a, AA "1000/FD, 100/FD, 10/FD" },
			 { 0x2b, AA "1000/FD, 100/FD, 10/FD, 10/HD" },
			 { 0x2c, AA "1000/FD, 100/FD, 100/HD" },
			 { 0x2d, AA "1000/FD, 100/FD, 100/HD, 10/HD" },
			 { 0x2e, AA "1000/FD, 100/FD, 100/HD, 10/FD" },
			 { 0x2f, AA "1000/FD, 100/FD, 100/HD, 10/FD, 10/HD" }};

		struct e1000_option opt = {
			.type = list_option,
			.name = "AutoNeg",
			.err  = "parameter ignored",
			.def  = AUTONEG_ADV_DEFAULT,
			.arg  = { .l = { .nr = ARRAY_SIZE(an_list),
					 .p = an_list }}
		};

		if (num_AutoNeg > bd) {
			an = AutoNeg[bd];
			e1000_validate_option(&an, &opt, adapter);
		} else {
			an = opt.def;
		}
		adapter->hw.autoneg_advertised = an;
	}

	switch (speed + dplx) {
	case 0:
		adapter->hw.autoneg = adapter->fc_autoneg = 1;
		if ((num_Speed > bd) && (speed != 0 || dplx != 0))
			DPRINTK(PROBE, INFO,
			       "Speed and duplex autonegotiation enabled\n");
		break;
	case HALF_DUPLEX:
		DPRINTK(PROBE, INFO, "Half Duplex specified without Speed\n");
		DPRINTK(PROBE, INFO, "Using Autonegotiation at "
			"Half Duplex only\n");
		adapter->hw.autoneg = adapter->fc_autoneg = 1;
		adapter->hw.autoneg_advertised = ADVERTISE_10_HALF |
		                                 ADVERTISE_100_HALF;
		break;
	case FULL_DUPLEX:
		DPRINTK(PROBE, INFO, "Full Duplex specified without Speed\n");
		DPRINTK(PROBE, INFO, "Using Autonegotiation at "
			"Full Duplex only\n");
		adapter->hw.autoneg = adapter->fc_autoneg = 1;
		adapter->hw.autoneg_advertised = ADVERTISE_10_FULL |
		                                 ADVERTISE_100_FULL |
		                                 ADVERTISE_1000_FULL;
		break;
	case SPEED_10:
		DPRINTK(PROBE, INFO, "10 Mbps Speed specified "
			"without Duplex\n");
		DPRINTK(PROBE, INFO, "Using Autonegotiation at 10 Mbps only\n");
		adapter->hw.autoneg = adapter->fc_autoneg = 1;
		adapter->hw.autoneg_advertised = ADVERTISE_10_HALF |
		                                 ADVERTISE_10_FULL;
		break;
	case SPEED_10 + HALF_DUPLEX:
		DPRINTK(PROBE, INFO, "Forcing to 10 Mbps Half Duplex\n");
		adapter->hw.autoneg = adapter->fc_autoneg = 0;
		adapter->hw.forced_speed_duplex = e1000_10_half;
		adapter->hw.autoneg_advertised = 0;
		break;
	case SPEED_10 + FULL_DUPLEX:
		DPRINTK(PROBE, INFO, "Forcing to 10 Mbps Full Duplex\n");
		adapter->hw.autoneg = adapter->fc_autoneg = 0;
		adapter->hw.forced_speed_duplex = e1000_10_full;
		adapter->hw.autoneg_advertised = 0;
		break;
	case SPEED_100:
		DPRINTK(PROBE, INFO, "100 Mbps Speed specified "
			"without Duplex\n");
		DPRINTK(PROBE, INFO, "Using Autonegotiation at "
			"100 Mbps only\n");
		adapter->hw.autoneg = adapter->fc_autoneg = 1;
		adapter->hw.autoneg_advertised = ADVERTISE_100_HALF |
		                                 ADVERTISE_100_FULL;
		break;
	case SPEED_100 + HALF_DUPLEX:
		DPRINTK(PROBE, INFO, "Forcing to 100 Mbps Half Duplex\n");
		adapter->hw.autoneg = adapter->fc_autoneg = 0;
		adapter->hw.forced_speed_duplex = e1000_100_half;
		adapter->hw.autoneg_advertised = 0;
		break;
	case SPEED_100 + FULL_DUPLEX:
		DPRINTK(PROBE, INFO, "Forcing to 100 Mbps Full Duplex\n");
		adapter->hw.autoneg = adapter->fc_autoneg = 0;
		adapter->hw.forced_speed_duplex = e1000_100_full;
		adapter->hw.autoneg_advertised = 0;
		break;
	case SPEED_1000:
		DPRINTK(PROBE, INFO, "1000 Mbps Speed specified without "
			"Duplex\n");
		goto full_duplex_only;
	case SPEED_1000 + HALF_DUPLEX:
		DPRINTK(PROBE, INFO,
			"Half Duplex is not supported at 1000 Mbps\n");
		/* fall through */
	case SPEED_1000 + FULL_DUPLEX:
full_duplex_only:
		DPRINTK(PROBE, INFO,
		       "Using Autonegotiation at 1000 Mbps Full Duplex only\n");
		adapter->hw.autoneg = adapter->fc_autoneg = 1;
		adapter->hw.autoneg_advertised = ADVERTISE_1000_FULL;
		break;
	default:
		BUG();
	}

	/* Speed, AutoNeg and MDI/MDI-X must all play nice */
	if (e1000_validate_mdi_setting(&(adapter->hw)) < 0) {
		DPRINTK(PROBE, INFO,
			"Speed, AutoNeg and MDI-X specifications are "
			"incompatible. Setting MDI-X to a compatible value.\n");
	}
}



<|start_filename|>3rdpart/ethercat-1.5.2/examples/rtai_rtdm/main.c<|end_filename|>
/******************************************************************************
 *
 *  $Id$
 *
 *  Copyright (C)      2011  IgH <NAME>
 *                     2012  <NAME> <<EMAIL>>
 *
 *  This file is part of the IgH EtherCAT master
 *
 *  The IgH EtherCAT Master is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License version 2, as
 *  published by the Free Software Foundation.
 *
 *  The IgH EtherCAT master is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
 *  Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with the IgH EtherCAT master. If not, see <http://www.gnu.org/licenses/>.
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 *****************************************************************************/

#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <signal.h>

#include <rtai_lxrt.h>
#include <rtdm/rtdm.h>

#include "ecrt.h"

#define rt_printf(X, Y)

#define NSEC_PER_SEC 1000000000

RT_TASK *task;

const static unsigned int cycle_us = 1000; /* 1 ms */

static int run = 1;

/****************************************************************************/

// EtherCAT
static ec_master_t *master = NULL;
static ec_master_state_t master_state = {};

static ec_domain_t *domain1 = NULL;
static ec_domain_state_t domain1_state = {};

static uint8_t *domain1_pd = NULL;

static ec_slave_config_t *sc_dig_out_01 = NULL;

/****************************************************************************/

// process data

#define BusCoupler01_Pos  0, 0
#define DigOutSlave01_Pos 0, 1

#define Beckhoff_EK1100 0x00000002, 0x044c2c52
#define Beckhoff_EL2004 0x00000002, 0x07d43052

// offsets for PDO entries
static unsigned int off_dig_out0 = 0;

// process data

const static ec_pdo_entry_reg_t domain1_regs[] = {
   {DigOutSlave01_Pos, Beckhoff_EL2004, 0x7000, 0x01, &off_dig_out0, NULL},
   {}
};

/****************************************************************************/

/* Slave 1, "EL2004"
 * Vendor ID:       0x00000002
 * Product code:    0x07d43052
 * Revision number: 0x00100000
 */

ec_pdo_entry_info_t slave_1_pdo_entries[] = {
   {0x7000, 0x01, 1}, /* Output */
   {0x7010, 0x01, 1}, /* Output */
   {0x7020, 0x01, 1}, /* Output */
   {0x7030, 0x01, 1}, /* Output */
};

ec_pdo_info_t slave_1_pdos[] = {
   {0x1600, 1, slave_1_pdo_entries + 0}, /* Channel 1 */
   {0x1601, 1, slave_1_pdo_entries + 1}, /* Channel 2 */
   {0x1602, 1, slave_1_pdo_entries + 2}, /* Channel 3 */
   {0x1603, 1, slave_1_pdo_entries + 3}, /* Channel 4 */
};

ec_sync_info_t slave_1_syncs[] = {
   {0, EC_DIR_OUTPUT, 4, slave_1_pdos + 0, EC_WD_ENABLE},
   {0xff}
};

/*****************************************************************************
 * Realtime task
 ****************************************************************************/

void rt_check_domain_state(void)
{
    ec_domain_state_t ds = {};

    ecrt_domain_state(domain1, &ds);

    if (ds.working_counter != domain1_state.working_counter) {
        rt_printf("Domain1: WC %u.\n", ds.working_counter);
    }

    if (ds.wc_state != domain1_state.wc_state) {
        rt_printf("Domain1: State %u.\n", ds.wc_state);
    }

    domain1_state = ds;
}

/****************************************************************************/

void rt_check_master_state(void)
{
    ec_master_state_t ms;

    ecrt_master_state(master, &ms);

    if (ms.slaves_responding != master_state.slaves_responding) {
        rt_printf("%u slave(s).\n", ms.slaves_responding);
    }

    if (ms.al_states != master_state.al_states) {
        rt_printf("AL states: 0x%02X.\n", ms.al_states);
    }

    if (ms.link_up != master_state.link_up) {
        rt_printf("Link is %s.\n", ms.link_up ? "up" : "down");
    }

    master_state = ms;
}

/****************************************************************************/

void my_cyclic(void)
{
    int cycle_counter = 0;
    int period;
    unsigned int blink = 0;

    rt_set_periodic_mode();
    period = (int) nano2count((RTIME) cycle_us * 1000);
    start_rt_timer(period);
    rt_make_hard_real_time();
    rt_task_make_periodic(task, rt_get_time() + 10 * period, period);

    while (run) {
        rt_task_wait_period();

        cycle_counter++;

        // receive EtherCAT
        ecrt_master_receive(master);
        ecrt_domain_process(domain1);

        rt_check_domain_state();

        if (!(cycle_counter % 1000)) {
            rt_check_master_state();
        }

        if (!(cycle_counter % 200)) {
            blink = !blink;
        }

        EC_WRITE_U8(domain1_pd + off_dig_out0, blink ? 0x00 : 0x0F);

        // send process data
        ecrt_domain_queue(domain1);
        ecrt_master_send(master);
    }

    rt_make_soft_real_time();
    stop_rt_timer();
}

/****************************************************************************
 * Signal handler
 ***************************************************************************/

void signal_handler(int sig)
{
    run = 0;
}

/****************************************************************************
 * Main function
 ***************************************************************************/

int main(int argc, char *argv[])
{
    ec_slave_config_t *sc;

    signal(SIGTERM, signal_handler);
    signal(SIGINT, signal_handler);

    mlockall(MCL_CURRENT | MCL_FUTURE);

    printf("Requesting master...\n");
    master = ecrt_request_master(0);
    if (!master) {
        return -1;
    }

    domain1 = ecrt_master_create_domain(master);
    if (!domain1) {
        return -1;
    }

    printf("Creating slave configurations...\n");

    // Create configuration for bus coupler
    sc = ecrt_master_slave_config(master, BusCoupler01_Pos, Beckhoff_EK1100);
    if (!sc) {
        return -1;
    }

    sc_dig_out_01 =
        ecrt_master_slave_config(master, DigOutSlave01_Pos, Beckhoff_EL2004);
    if (!sc_dig_out_01) {
        fprintf(stderr, "Failed to get slave configuration.\n");
        return -1;
    }

    if (ecrt_slave_config_pdos(sc_dig_out_01, EC_END, slave_1_syncs)) {
        fprintf(stderr, "Failed to configure PDOs.\n");
        return -1;
    }

    if (ecrt_domain_reg_pdo_entry_list(domain1, domain1_regs)) {
        fprintf(stderr, "PDO entry registration failed!\n");
        return -1;
    }

    printf("Activating master...\n");
    if (ecrt_master_activate(master)) {
        return -1;
    }

    if (!(domain1_pd = ecrt_domain_data(domain1))) {
        fprintf(stderr, "Failed to get domain data pointer.\n");
        return -1;
    }

    /* Create cyclic RT-thread */
    struct sched_param param;
    param.sched_priority = sched_get_priority_max(SCHED_FIFO) - 1;
    if (sched_setscheduler(0, SCHED_FIFO, &param) == -1) {
        puts("ERROR IN SETTING THE SCHEDULER");
        perror("errno");
        return -1;
    }

    task = rt_task_init(nam2num("ec_rtai_rtdm_example"),
            0 /* priority */, 0 /* stack size */, 0 /* msg size */);

    my_cyclic();

    rt_task_delete(task);

    printf("End of Program\n");
    ecrt_release_master(master);

    return 0;
}

/****************************************************************************/


<|start_filename|>3rdpart/ethercat-1.5.2/master/fsm_slave_scan.h<|end_filename|>
/******************************************************************************
 *
 *  $Id: fsm_slave_scan.h,v 11c0b2caa253 2009/02/24 12:51:39 fp $
 *
 *  Copyright (C) 2006-2008  <NAME>, Ingenieurgemeinschaft IgH
 *
 *  This file is part of the IgH EtherCAT Master.
 *
 *  The IgH EtherCAT Master is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License version 2, as
 *  published by the Free Software Foundation.
 *
 *  The IgH EtherCAT Master is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 *  Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with the IgH EtherCAT Master; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 *****************************************************************************/

/**
   \file
   EtherCAT slave scanning state machine.
*/

/*****************************************************************************/

#ifndef __EC_FSM_SLAVE_SCAN_H__
#define __EC_FSM_SLAVE_SCAN_H__

#include "globals.h"
#include "datagram.h"
#include "slave.h"
#include "fsm_sii.h"
#include "fsm_change.h"
#include "fsm_coe.h"
#include "fsm_pdo.h"

/*****************************************************************************/

/** \see ec_fsm_slave_scan */
typedef struct ec_fsm_slave_scan ec_fsm_slave_scan_t;

/** Finite state machine for scanning an EtherCAT slave.
 */
struct ec_fsm_slave_scan
{
    ec_slave_t *slave; /**< Slave the FSM runs on. */
    ec_datagram_t *datagram; /**< Datagram used in the state machine. */
    ec_fsm_slave_config_t *fsm_slave_config; /**< Slave configuration state
                                               machine to use. */
    ec_fsm_pdo_t *fsm_pdo; /**< PDO configuration state machine to use. */
    unsigned int retries; /**< Retries on datagram timeout. */

    void (*state)(ec_fsm_slave_scan_t *); /**< State function. */
    uint16_t sii_offset; /**< SII offset in words. */

    ec_fsm_sii_t fsm_sii; /**< SII state machine. */
};

/*****************************************************************************/

void ec_fsm_slave_scan_init(ec_fsm_slave_scan_t *, ec_datagram_t *,
        ec_fsm_slave_config_t *, ec_fsm_pdo_t *);
void ec_fsm_slave_scan_clear(ec_fsm_slave_scan_t *);

void ec_fsm_slave_scan_start(ec_fsm_slave_scan_t *, ec_slave_t *);

int ec_fsm_slave_scan_exec(ec_fsm_slave_scan_t *);
int ec_fsm_slave_scan_success(const ec_fsm_slave_scan_t *);

/*****************************************************************************/

#endif


<|start_filename|>3rdpart/tslib-1.15/src/ts_setup.c<|end_filename|>
/*
 *  tslib/src/ts_setup.c
 *
 *  Copyright (C) 2017 <NAME>
 *
 * This file is placed under the LGPL.  Please see the file
 * COPYING for more details.
 *
 * SPDX-License-Identifier: LGPL-2.1
 *
 *
 * Find, open and configure a touchscreen device.
 */

#include "tslib.h"
#include "tslib-private.h"
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>

#if defined (__linux__)
#include <dirent.h>
#include <stdio.h>
#include <string.h>
#include <linux/input.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

#define DEV_INPUT_EVENT "/dev/input"
#define EVENT_DEV_NAME "event"

#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
#define BIT(nr)                 (1UL << (nr))
#define BIT_MASK(nr)            (1UL << ((nr) % BITS_PER_LONG))
#define BIT_WORD(nr)            ((nr) / BITS_PER_LONG)
#define BITS_PER_BYTE           8
#define BITS_PER_LONG           (sizeof(long) * BITS_PER_BYTE)
#define BITS_TO_LONGS(nr)       DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long))

static int is_event_device(const struct dirent *dir)
{
	return strncmp(EVENT_DEV_NAME, dir->d_name, 5) == 0;
}

static char *scan_devices(void)
{
	struct dirent **namelist;
	int i, ndev;
	char *filename = NULL;
	int have_touchscreen = 0;
	long propbit[BITS_TO_LONGS(INPUT_PROP_MAX)] = {0};

#ifdef DEBUG
	printf("scanning for devices in %s\n", DEV_INPUT_EVENT);
#endif

	ndev = scandir(DEV_INPUT_EVENT, &namelist, is_event_device, alphasort);
	if (ndev <= 0)
		return NULL;

	for (i = 0; i < ndev; i++) {
		char fname[64];
		int fd = -1;

		snprintf(fname, sizeof(fname),
			 "%s/%s", DEV_INPUT_EVENT, namelist[i]->d_name);
		fd = open(fname, O_RDONLY);
		if (fd < 0)
			continue;

		if ((ioctl(fd, EVIOCGPROP(sizeof(propbit)), propbit) < 0) ||
			!(propbit[BIT_WORD(INPUT_PROP_DIRECT)] &
				  BIT_MASK(INPUT_PROP_DIRECT))) {
			continue;
		} else {
			have_touchscreen = 1;
		}

		close(fd);
		free(namelist[i]);

		if (have_touchscreen) {
			filename = malloc(strlen(DEV_INPUT_EVENT) +
					  strlen(EVENT_DEV_NAME) +
					  3);
			if (!filename)
				return NULL;

			sprintf(filename, "%s/%s%d",
				DEV_INPUT_EVENT, EVENT_DEV_NAME,
				i);
		}

		return filename;
	}

	return NULL;
}

#endif /* __linux__ */

static const char * const ts_name_default[] = {
		"/dev/input/ts",
		"/dev/input/touchscreen",
		"/dev/touchscreen/ucb1x00",
		NULL
};

struct tsdev *ts_setup(const char *dev_name, int nonblock)
{
	const char * const *defname;
	struct tsdev *ts = NULL;
#if defined (__linux__)
	char *fname = NULL;
#endif /* __linux__ */

	dev_name = dev_name ? dev_name : getenv("TSLIB_TSDEVICE");

	if (dev_name != NULL) {
		ts = ts_open(dev_name, nonblock);
	} else {
		defname = &ts_name_default[0];
		while (*defname != NULL) {
			ts = ts_open(*defname, nonblock);
			if (ts != NULL)
				break;

			++defname;
		}
	}

#if defined (__linux__)
	if (!ts) {
		fname = scan_devices();
		if (!fname)
			return NULL;

		ts = ts_open(fname, nonblock);
		free(fname);
	}
#endif /* __linux__ */

	/* if detected try to configure it */
	if (ts && ts_config(ts) != 0) {
		ts_error("ts_config: %s\n", strerror(errno));
		ts_close(ts);
		return NULL;
	}

	return ts;
}


<|start_filename|>3rdpart/tslib-1.15/plugins/cy8mrln.h<|end_filename|>
/*
 * Copyright (C) 2008-2009 Palm, Inc
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2 of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * SPDX-License-Identifier: GPL-2.0
 */

#ifndef __CY8MRLN_H
#define __CY8MRLN_H

#ifdef __KERNEL__
#include <linux/spi/spi.h>
#include <linux/ioctl.h>
#include <linux/types.h>
#endif /* __KERNEL */


/* IOCTLs */
#define CY8MRLN_IOCTL_GET_SCANRATE	_IOR('c', 0x01, int)
#define CY8MRLN_IOCTL_GET_SLEEPMODE	_IOR('c', 0x02, int)
#define CY8MRLN_IOCTL_GET_XFER_OPTION	_IOR('c', 0x03, int)
#define CY8MRLN_IOCTL_GET_SPI_MODE	_IOR('c', 0x04, int)
#define CY8MRLN_IOCTL_GET_SPI_CLOCK	_IOR('c', 0x05, int)
#define CY8MRLN_IOCTL_GET_READ_OPTION	_IOR('c', 0x06, int)
#define CY8MRLN_IOCTL_GET_VERBOSE_MODE	_IOR('c', 0x07, int)

#define CY8MRLN_IOCTL_SET_SCANRATE	_IOW('c', 0x08, int)
#define CY8MRLN_IOCTL_SET_SLEEPMODE	_IOW('c', 0x09, int)
#define CY8MRLN_IOCTL_SET_XFER_OPTION	_IOW('c', 0x0a, int)
#define CY8MRLN_IOCTL_SET_SPI_MODE	_IOW('c', 0x0b, char)
#define CY8MRLN_IOCTL_SET_SPI_CLOCK	_IOW('c', 0x0c, int)
#define CY8MRLN_IOCTL_SET_READ_OPTION	_IOW('c', 0x0d, int)
#define CY8MRLN_IOCTL_SET_VERBOSE_MODE	_IOW('c', 0x0e, int)
#define CY8MRLN_IOCTL_SET_BYTES		_IOW('c', 0x0f, int)
#define CY8MRLN_IOCTL_GET_NUM_DATA_BYTES	_IOR('c', 0x10, int)
#define CY8MRLN_IOCTL_SET_NUM_DATA_BYTES	_IOW('c', 0x11, int)
#define CY8MRLN_IOCTL_GET_QUERY_DATA	_IOR('c', 0x12, unsigned short)
#define CY8MRLN_IOCTL_SET_VECTORS	_IOW('c', 0x13, int)
#define CY8MRLN_IOCTL_SET_PROG_PHASE	_IOW('c', 0x14, int)
#define CY8MRLN_IOCTL_SET_FW_DATA	_IOW('c', 0x15, int)
#define CY8MRLN_IOCTL_GET_TIMESTAMP_MODE _IOR('c', 0x16, int)
#define CY8MRLN_IOCTL_SET_TIMESTAMP_MODE _IOW('c', 0x17, int)
/* rpswtest */
// The following two ioctls are deprecated
// #define CY8MRLN_IOCTL_GET_CALIBRATION_MODE      _IOR('c', 0x18, int)
// #define CY8MRLN_IOCTL_SET_CALIBRATION_MODE      _IOW('c', 0x19, int)
#define CY8MRLN_IOCTL_GET_INTERLEAVED_SCAN_MODE _IOR('c', 0x1a, int)
#define CY8MRLN_IOCTL_SET_INTERLEAVED_SCAN_MODE _IOW('c', 0x1b, int)

/* Wake-On-Touch or WOT */
//#define CY8MRLN_IOCTL_SET_WOT_MODE		_IOW('c', 0x1c, int)
#define CY8MRLN_IOCTL_SET_WOT_THRESHOLD		_IOW('c', 0x1d, int)
#define CY8MRLN_IOCTL_GET_WOT_THRESHOLD		_IOR('c', 0x1e, int)
//#define CY8MRLN_IOCTL_SET_WOT_PRESCALER	_IOW('c', 0x1f, int)
//#define CY8MRLN_IOCTL_GET_WOT_PRESCALER	_IOR('c', 0x20, int)

/*
 * The WOT SCAN Rate the rate at which the PSoC will
 * wake up from sleep and perform a WOT scan
 */
#define CY8MRLN_IOCTL_GET_IDAC_TABLE		_IOR('c', 0x21, unsigned char[154])
#define CY8MRLN_IOCTL_SET_WOT_SCANRATE		_IOW('c', 0x22, int)
#define CY8MRLN_IOCTL_GET_WOT_SCANRATE		_IOR('c', 0x23, int)
#define CY8MRLN_IOCTL_START_WOT_SCAN		_IOW('c', 0x24, int)
#define CY8MRLN_IOCTL_GET_WOT_BASELINE_LO	_IOR('c', 0x25, int)
#define CY8MRLN_IOCTL_GET_WOT_BASELINE_HI	_IOR('c', 0x26, int)
#define CY8MRLN_IOCTL_SET_WOT_BASELINE_LO	_IOW('c', 0x27, int)
#define CY8MRLN_IOCTL_SET_WOT_BASELINE_HI	_IOW('c', 0x28, int)
#define CY8MRLN_IOCTL_GET_FPC_INFO			_IOR('c', 0x29, unsigned char)
#define CY8MRLN_IOCTL_ENTER_WOT_RAW_DATA	_IOR('c', 0x30, int)
#define CY8MRLN_IOCTL_EXIT_WOT_RAW_DATA		_IOR('c', 0x31, int)


/*CY8MRLN_IOCTL_START_WOT_SCAN_FORCED:
 * Combines CY8MRLN_IOCTL_START_WOT_SCAN and CY8MRLN_IOCTL_SET_WOT_THRESHOLD
 * in one IOCTLs.  I.E. the wot threshold is sent together with wot start request.
 * This IOCTLE will ejects/force PSoC out of WOT mode so that the WOT sensitivity
 * specified in the IOCTL parameter will be used.
 */
#define CY8MRLN_IOCTL_START_WOT_SCAN_FORCED	_IOW('c', 0x32, int)

/*
*  Used for forcing calibration of the IDAC outside of flashing and also storing that calibration
*/
#define CY8MRLN_IOCTL_IDAC_CALIBRATE			_IOW('c', 0x33, int)
#define CY8MRLN_IOCTL_IDAC_CALIBRATION_STORE	_IOW('c', 0x34, int)

/*
*   Causes the PSoC to calibrate its internal low speed oscillator
*/
#define CY8MRLN_IOCTL_ILO_CALIBRATE		_IOW('c', 0x35, int)
#define CY8MRLN_IOCTL_EXIT_WOT_SCAN		_IOR('c', 0x36, int)

/* WOT Sensitivity/Threshold ranges */
#define WOT_THRESHOLD_MIN 10
#define WOT_THRESHOLD_MAX 73

/* WOT Scan Rate Index */
enum{
	WOT_SCANRATE_512HZ = 0,
	WOT_SCANRATE_256HZ,
	WOT_SCANRATE_171HZ,
	WOT_SCANRATE_128HZ
};

/* WOT MIN & MAX configuraton value for scan rate
 * NB: min. value is max freq and
 *     max. value is min freq.
 */
#define WOT_SCANRATE_MAX	WOT_SCANRATE_128HZ
#define WOT_SCANRATE_MIN	WOT_SCANRATE_512HZ

/* debug */


/* PSoC Power State */
enum {
	CY8MRLN_OFF_STATE = 0,
	CY8MRLN_SLEEP_STATE,
	CY8MRLN_ON_STATE
};

/* Scan/Version SPI data xfer method. */
enum {
	CY8MRLN_TWO_INT_THREE_SETUP_BYTES = 0,
	CY8MRLN_TWO_INT_TWO_SETUP_BYTES,
	CY8MRLN_ONE_INT_THREE_SETUP_BYTES,
	CY8MRLN_ONE_INT_TWO_SETUP_BYTES,
	CY8MRLN_ONE_INT_ZERO_SETUP_BYTES
};

/* DMA vs. PIO. */
enum {
	CY8MRLN_PIO_XFER_OPTION = 0,
	CY8MRLN_DMA_XFER_OPTION
};

enum {
	SCAN_AT_256HZ = 0,
	SCAN_AT_170HZ,
	SCAN_AT_128HZ,
	SCAN_AT_102HZ
};

#define CY8MRLN_DEFALUT_NUM_DATA_BYTES		(7 * 11 * 2 + 4)

/* PSoC Programming Vector Structure. */
typedef struct cy8mrln_vector {
	unsigned int id;
	unsigned int bits;
	unsigned int bytes;
	unsigned char *data;
} cy8mrln_vector_t;

/* PSoC Hex FW file line structure. */
typedef struct cy8mrln_fw_data {
	unsigned int index;
	unsigned int bytes;
	unsigned int addr;
	unsigned int type;
	unsigned int checksum;
	unsigned char *blk;
} cy8mrln_fw_data_t;

struct cy8mrln_platform_data {
	int xres_gpio;		/* not used. */
	int enable_gpio;
	int scl_gpio;		/* Programming mode clk */
	int mosi_gpio;		/* Used for SDA line mirroring in programming */
	int sda_gpio;		/* Programming mode data */
	int flip_x;		/* Flip the X coordinate? */
	int flip_y;		/* Flip the Y coordinate? */
	/* Function pointer that switches between the programming
	 * mode and the normal functional mode.
	 */
	int (*switch_mode)(int flag);
};

/* SPI stuff. */
#define SPI_READ_BIT			0x80
#define CY8MRLN_DATA_REG_START		0x00
#define CY8MRLN_CONTROL_REG		0x00

/* Command definitions. */
#define CY8MRLN_WAKE_UP				0x00
#define CY8MRLN_GO_ACTIVE			0x00
#define CY8MRLN_SCAN_START			0x01
#define CY8MRLN_SLEEP				0x02
#define CY8MRLN_QUERY				0x04
#define CY8MRLN_STORE_IDAC_CALIBRATION		0x08
#define CY8MRLN_CALIBRATE_IDAC			0x0A
#define CY8MRLN_AUTO_SCAN			0x0B
#define CY8MRLN_CALIBRATE_ILO			0x0C
#define CY8MRLN_BASELINE_ADJUST			0x0D
#define CY8MRLN_WOT_RAW_DATA			0x0F
#define CY8MRLN_CMD_INVALID			0xFF


enum {
		WOT_DBG_OFF = 0,	//0 OFF
		WOT_DBG_ON_PENDING,	//1 ON_P
		WOT_DBG_ON,		//2 ON
		WOT_DBG_OFF_PENDING 	//3 OFF_P
};

/* 11_0A is the latest version. The 08_0c is the initial
 * version of FW that actually doesn't support QUERY
 * command.
 */
#define VERSION_11_0A                   0x110a
#define VERSION_08_0C                   0x080c

/* PSoC Programming Vectors. These vectors are defined
 * by Cypress and reside in user space updater application.
 */
enum {
	INIT1 = 0,
	INIT2,
	INIT3_5V,
	INIT3_3V,
	ID_SETUP,
	TARGET_ID,
	READ_ID,
	ERASE_ALL,
	SET_BANK_NUMBER,
	SET_BANK_NUMBER_END,
	WRITE_BYTE_START,
	WRITE_BYTE_END,
	SET_BLOCK_NUMBER,
	SET_BLOCK_NUMBER_END,
	PROGRAM_BLOCK,
	VERIFY_SETUP,
	READ_BYTE,
	SECURITY,
	CHECKSUM,
	READ_CHECKSUM,
	WAIT_AND_POLL_END,
	NUM_VECTORS
};


/* Different phases of programming the PSoC. */
enum {
	NORM_OP = 0,
	INIT_VECTORS,
	INIT_TARGET,
	VERIFY_ID,
	PROGRAM,
	VERIFY,
	SECURE,
	VERIFY_CHECKSUM,
	EXIT_PROG
};

/* Different types of Cypress Hex FW data. */
enum {
	FW_START = 0,
	FW_END = 255,
	SECURITY_OFFSET = 256,
	SECURITY_DATA = 257,
	CHECKSUM_OFFSET = 258,
	CHECKSUM_DATA = 259,
	END_OF_FILE = 260,
	NUM_FW_LINES = 261
};

#define NUM_TP_DRV_STATUS_REG_BYTES 1
#define DRV_STATUS_MASK__BUF_OVERFLOW 		0x80

#define TP_DRV_STATUS_REG__FRAME_TYPE_MASK	0x60
#define FRAME_TYPE_MASK__NORMAL_SCAN		0x00
#define FRAME_TYPE_MASK__WOT_ENTRY_SCAN 	0x20
#define FRAME_TYPE_MASK__WOT_EXIT_SCAN 		0x40

/* Cypress PSoC Attributes. */

// ****************************************************************************
// ************* USER ATTENTION REQUIRED: TARGET SUPPLY VOLTAGE ***************
// ****************************************************************************
// This directive causes the proper Initialization vector #3 to be sent
// to the Target, based on what the Target Vdd programming voltage will
// be. Either 5V (if #define enabled) or 3.3V (if #define disabled).
//#define TARGET_VOLTAGE_IS_5V


// ****************************************************************************
// **************** USER ATTENTION REQUIRED: PROGRAMMING MODE *****************
// ****************************************************************************
// This directive selects whether code that uses reset programming mode or code
// that uses power cycle programming is use. Reset programming mode uses the
// external reset pin (XRES) to enter programming mode. Power cycle programming
// mode uses the power-on reset to enter programming mode.
// Applying signals to various pins on the target device must be done in a
// deliberate order when using power cycle mode. Otherwise, high signals to GPIO
// pins on the target will power the PSoC through the protection diodes.
//#define RESET_MODE

// ****************************************************************************
// ****************** USER ATTENTION REQUIRED: TARGET PSOC ********************
// ****************************************************************************
// The directives below enable support for various PSoC devices. The root part
// number to be programmed should be un-commented so that its value becomes
// defined.  All other devices should be commented out.
// Select one device to be supported below:

// **** CY8C21x23 devices ****
//#define CY8C21123
//#define CY8C21223
//#define CY8C21323
//#define CY8C21002

// **** CY8C21x34 devices ****
//#define CY8C21234
//#define CY8C21334
//#define CY8C21434
//#define CY8C21534
//#define CY8C21634
//#define CY8C21001

// **** CY8C24x23A devices ****
//#define CY8C24123A
//#define CY8C24223A
//#define CY8C24423A
//#define CY8C24000A

// **** CY8C24x94 devices ****
//#define CY8C24794
#define CY8C24894
//#define CY8C24994
//#define CY8C24094

// **** CY8C27x34 devices ****
//#define CY8C27143
//#define CY8C27243
//#define CY8C27443
//#define CY8C27543
//#define CY8C27643
//#define CY8C27002

// **** CY8C29x66 devices ****
//#define CY8C29466
//#define CY8C29566
//#define CY8C29666
//#define CY8C29866
//#define CY8C29002

//-----------------------------------------------------------------------------
// This section sets the Family that has been selected. These are used to
// simplify other conditional compilation blocks.
//-----------------------------------------------------------------------------
#ifdef CY8C21123
    #define CY8C21x23
#endif
#ifdef CY8C21223
    #define CY8C21x23
#endif
#ifdef CY8C21323
    #define CY8C21x23
#endif
#ifdef CY8C21002
    #define CY8C21x23
#endif
#ifdef CY8C21234
    #define CY8C21x34
#endif
#ifdef CY8C21334
    #define CY8C21x34
#endif
#ifdef CY8C21434
    #define CY8C21x34
#endif
#ifdef CY8C21534
    #define CY8C21x34
#endif
#ifdef CY8C21634
    #define CY8C21x34
#endif
#ifdef CY8C21001
    #define CY8C21x34
#endif
#ifdef CY8C24123A
    #define CY8C24x23A
#endif
#ifdef CY8C24223A
    #define CY8C24x23A
#endif
#ifdef CY8C24423A
    #define CY8C24x23A
#endif
#ifdef CY8C24000A
    #define CY8C24x23A
#endif
#ifdef CY8C24794
    #define CY8C24x94
#endif
#ifdef CY8C24894
    #define CY8C24x94
#endif
#ifdef CY8C24994
    #define CY8C24x94
#endif
#ifdef CY8C24094
    #define CY8C24x94
#endif
#ifdef CY8C27143
    #define CY8C27x43
#endif
#ifdef CY8C27243
    #define CY8C27x43
#endif
#ifdef CY8C27443
    #define CY8C27x43
#endif
#ifdef CY8C27543
    #define CY8C27x43
#endif
#ifdef CY8C27643
    #define CY8C27x43
#endif
#ifdef CY8C27002
    #define CY8C27x43
#endif
#ifdef CY8C29466
    #define CY8C29x66
#endif
#ifdef CY8C29566
    #define CY8C29x66
#endif
#ifdef CY8C29666
    #define CY8C29x66
#endif
#ifdef CY8C29866
    #define CY8C29x66
#endif
#ifdef CY8C29002
    #define CY8C29x66
#endif
//-----------------------------------------------------------------------------
// The directives below are used to define various sets of vectors that differ
// for more than one set of PSoC parts.
//-----------------------------------------------------------------------------
// **** Select a Checksum Setup Vector ****
#ifdef CY8C21x23
    #define CHECKSUM_SETUP_21_27
#endif
#ifdef CY8C21x34
    #define CHECKSUM_SETUP_21_27
#endif
#ifdef CY8C24x23A
    #define CHECKSUM_SETUP_24_24A
#endif
#ifdef CY8C24x94
    #define CHECKSUM_SETUP_24_29
#endif
#ifdef CY8C27x43
    #define CHECKSUM_SETUP_21_27
#endif
#ifdef CY8C29x66
    #define CHECKSUM_SETUP_24_29
#endif

// **** Select a Program Block Vector ****
#ifdef CY8C21x23
    #define PROGRAM_BLOCK_21_24_29
#endif
#ifdef CY8C21x34
    #define PROGRAM_BLOCK_21_24_29
#endif
#ifdef CY8C24x23A
    #define PROGRAM_BLOCK_21_24_29
#endif
#ifdef CY8C24x94
    #define PROGRAM_BLOCK_21_24_29
#endif
#ifdef CY8C27x43
    #define PROGRAM_BLOCK_27
#endif
#ifdef CY8C29x66
    #define PROGRAM_BLOCK_21_24_29
#endif

//-----------------------------------------------------------------------------
// The directives below are used to control switching banks if the device is
// has multiple banks of Flash.
//-----------------------------------------------------------------------------
// **** Select a Checksum Setup Vector ****
#ifdef CY8C24x94
    #define MULTI_BANK
#endif
#ifdef CY8C29x66
    #define MULTI_BANK
#endif

/* Block-Verify Uses 64-Bytes of RAM */
#define TARGET_DATABUFF_LEN    64

/* The number of Flash blocks in each part is defined here. This is used in
 * main programming loop when programming and verifying the blocks.
 */
#ifdef CY8C21x23
    #define NUM_BANKS                     1
    #define BLOCKS_PER_BANK              64
    #define SECURITY_BYTES_PER_BANK      64
#endif
#ifdef CY8C21x34
    #define NUM_BANKS                     1
    #define BLOCKS_PER_BANK             128
    #define SECURITY_BYTES_PER_BANK      64
#endif
#ifdef CY8C24x23A
    #define NUM_BANKS                     1
    #define BLOCKS_PER_BANK              64
    #define SECURITY_BYTES_PER_BANK      64
#endif
#ifdef CY8C24x94
    #define NUM_BANKS                     2
    #define BLOCKS_PER_BANK             128
    #define SECURITY_BYTES_PER_BANK      32
#endif
#ifdef CY8C27x43
    #define NUM_BANKS                     1
    #define BLOCKS_PER_BANK             256
    #define SECURITY_BYTES_PER_BANK      64
#endif
#ifdef CY8C29x66
    #define NUM_BANKS                     4
    #define BLOCKS_PER_BANK             128
    #define SECURITY_BYTES_PER_BANK      32
#endif


/* In system programming error code. */
#define PASS		(0)
#define HILOW_ERROR	(-1)
#define SI_ID_ERROR	(-2)
#define VERIFY_ERROR	(-3)
#define CHECKSUM_ERROR	(-4)


/* TRANSITION_TIMEOUT is a loop counter for a 100msec timeout when waiting for
 * a high-to-low transition. Each pass through the loop takes approximately 15
 * usec. 100 msec is about 6740 loops.
 */
#define TRANSITION_TIMEOUT    	6740

/* XRES_DELAY is the time duration for which XRES is asserted. This defines
 * a 63 usec delay.
 * The minimum Xres time (from the device datasheet) is 10 usec.
 */
#define XRES_CLK_DELAY   	63

/* POWER_CYCLE_DELAY is the time required when power is cycled to the target
 * device to create a power reset after programming has been completed. The
 * actual time of this delay will vary from system to system depending on the
 * bypass capacitor size.  A delay of 1000 usec is used here.
 */
#define POWER_CYCLE_DELAY	1000

#endif //__CY8MRLN_H


<|start_filename|>3rdpart/ethercat-1.5.2/tool/DataTypeHandler.h<|end_filename|>
/*****************************************************************************
 *
 *  $Id: DataTypeHandler.h,v 489ea0becd74 2010/03/11 13:29:43 fp $
 *
 *  Copyright (C) 2006-2009  <NAME>, Ingenieurgemeinschaft IgH
 *
 *  This file is part of the IgH EtherCAT Master.
 *
 *  The IgH EtherCAT Master is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License version 2, as
 *  published by the Free Software Foundation.
 *
 *  The IgH EtherCAT Master is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 *  Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with the IgH EtherCAT Master; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 ****************************************************************************/

#ifndef __DATATYPEHANDLER_H__
#define __DATATYPEHANDLER_H__

/****************************************************************************/

#include <stdint.h>
#include <string>
#include <stdexcept>
#include <ostream>

/****************************************************************************/

class DataTypeHandler
{
    public:
        DataTypeHandler();

    protected:
        struct DataType {
            const char *name;
            uint16_t code;
            size_t byteSize;
        };

		static std::string typeInfo();

        static const DataType *findDataType(const std::string &);
        static const DataType *findDataType(uint16_t);
        static size_t interpretAsType(const DataType *, const std::string &,
                void *, size_t);

        class SizeException:
            public std::runtime_error
        {
            public:
                SizeException(const std::string &msg):
                    runtime_error(msg) {}
        };

        static void outputData(std::ostream &, const DataType *,
                void *, size_t);
        static void printRawData(ostream &, const uint8_t *, size_t);

    private:
        static const DataType dataTypes[];
};

/****************************************************************************/

#endif


<|start_filename|>3rdpart/ethercat-1.5.2/master/slave_config.h<|end_filename|>
/******************************************************************************
 *
 *  $Id: slave_config.h,v ec403cf308eb 2013/02/12 14:46:43 fp $
 *
 *  Copyright (C) 2006-2012  <NAME>, Ingenieurgemeinschaft IgH
 *
 *  This file is part of the IgH EtherCAT Master.
 *
 *  The IgH EtherCAT Master is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License version 2, as
 *  published by the Free Software Foundation.
 *
 *  The IgH EtherCAT Master is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 *  Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with the IgH EtherCAT Master; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 *****************************************************************************/

/**
   \file
   EtherCAT slave configuration structure.
*/

/*****************************************************************************/

#ifndef __EC_SLAVE_CONFIG_H__
#define __EC_SLAVE_CONFIG_H__

#include <linux/list.h>

#include "globals.h"
#include "slave.h"
#include "sync_config.h"
#include "fmmu_config.h"
#include "coe_emerg_ring.h"

/*****************************************************************************/

/** Convenience macro for printing configuration-specific information to
 * syslog.
 *
 * This will print the message in \a fmt with a prefixed
 * "EtherCAT <INDEX> <ALIAS>:<POSITION>: ", where INDEX is the master index
 * and ALIAS and POSITION identify the configuration.
 *
 * \param sc EtherCAT slave configuration
 * \param fmt format string (like in printf())
 * \param args arguments (optional)
 */
#define EC_CONFIG_INFO(sc, fmt, args...) \
    printk(KERN_INFO "EtherCAT %u %u:%u: " fmt, sc->master->index, \
            sc->alias, sc->position, ##args)

/** Convenience macro for printing configuration-specific errors to syslog.
 *
 * This will print the message in \a fmt with a prefixed
 * "EtherCAT <INDEX> <ALIAS>:<POSITION>: ", where INDEX is the master index
 * and ALIAS and POSITION identify the configuration.
 *
 * \param sc EtherCAT slave configuration
 * \param fmt format string (like in printf())
 * \param args arguments (optional)
 */
#define EC_CONFIG_ERR(sc, fmt, args...) \
    printk(KERN_ERR "EtherCAT ERROR %u %u:%u: " fmt, sc->master->index, \
            sc->alias, sc->position, ##args)

/** Convenience macro for printing configuration-specific warnings to syslog.
 *
 * This will print the message in \a fmt with a prefixed
 * "EtherCAT <INDEX> <ALIAS>:<POSITION>: ", where INDEX is the master index
 * and ALIAS and POSITION identify the configuration.
 *
 * \param sc EtherCAT slave configuration
 * \param fmt format string (like in printf())
 * \param args arguments (optional)
 */
#define EC_CONFIG_WARN(sc, fmt, args...) \
    printk(KERN_WARNING "EtherCAT WARNING %u %u:%u: " fmt, \
            sc->master->index, sc->alias, sc->position, ##args)

/** Convenience macro for printing configuration-specific debug messages to
 * syslog.
 *
 * This will print the message in \a fmt with a prefixed
 * "EtherCAT <INDEX> <ALIAS>:<POSITION>: ", where INDEX is the master index
 * and ALIAS and POSITION identify the configuration.
 *
 * \param sc EtherCAT slave configuration
 * \param level Debug level. Master's debug level must be >= \a level for
 * output.
 * \param fmt format string (like in printf())
 * \param args arguments (optional)
 */
#define EC_CONFIG_DBG(sc, level, fmt, args...) \
    do { \
        if (sc->master->debug_level >= level) { \
            printk(KERN_DEBUG "EtherCAT DEBUG %u %u:%u: " fmt, \
                    sc->master->index, sc->alias, sc->position, ##args); \
        } \
    } while (0)

/*****************************************************************************/

/** EtherCAT slave configuration.
 */
struct ec_slave_config {
    struct list_head list; /**< List item. */
    ec_master_t *master; /**< Master owning the slave configuration. */

    uint16_t alias; /**< Slave alias. */
    uint16_t position; /**< Index after alias. If alias is zero, this is the
                         ring position. */
    uint32_t vendor_id; /**< Slave vendor ID. */
    uint32_t product_code; /**< Slave product code. */

    uint16_t watchdog_divider; /**< Watchdog divider as a number of 40ns
                                 intervals (see spec. reg. 0x0400). */
    uint16_t watchdog_intervals; /**< Process data watchdog intervals (see
                                   spec. reg. 0x0420). */

    ec_slave_t *slave; /**< Slave pointer. This is \a NULL, if the slave is
                         offline. */

    ec_sync_config_t sync_configs[EC_MAX_SYNC_MANAGERS]; /**< Sync manager
                                                   configurations. */
    ec_fmmu_config_t fmmu_configs[EC_MAX_FMMUS]; /**< FMMU configurations. */
    uint8_t used_fmmus; /**< Number of FMMUs used. */
    uint16_t dc_assign_activate; /**< Vendor-specific AssignActivate word. */
    ec_sync_signal_t dc_sync[EC_SYNC_SIGNAL_COUNT]; /**< DC sync signals. */

    struct list_head sdo_configs; /**< List of SDO configurations. */
    struct list_head sdo_requests; /**< List of SDO requests. */
    struct list_head voe_handlers; /**< List of VoE handlers. */
    struct list_head reg_requests; /**< List of register requests. */
    struct list_head soe_configs; /**< List of SoE configurations. */

    ec_coe_emerg_ring_t emerg_ring; /**< CoE emergency ring buffer. */
};

/*****************************************************************************/

void ec_slave_config_init(ec_slave_config_t *, ec_master_t *, uint16_t,
        uint16_t, uint32_t, uint32_t);
void ec_slave_config_clear(ec_slave_config_t *);

int ec_slave_config_attach(ec_slave_config_t *);
void ec_slave_config_detach(ec_slave_config_t *);

void ec_slave_config_load_default_sync_config(ec_slave_config_t *);

unsigned int ec_slave_config_sdo_count(const ec_slave_config_t *);
const ec_sdo_request_t *ec_slave_config_get_sdo_by_pos_const(
        const ec_slave_config_t *, unsigned int);
unsigned int ec_slave_config_idn_count(const ec_slave_config_t *);
const ec_soe_request_t *ec_slave_config_get_idn_by_pos_const(
        const ec_slave_config_t *, unsigned int);
ec_sdo_request_t *ec_slave_config_find_sdo_request(ec_slave_config_t *,
        unsigned int);
ec_reg_request_t *ec_slave_config_find_reg_request(ec_slave_config_t *,
        unsigned int);
ec_voe_handler_t *ec_slave_config_find_voe_handler(ec_slave_config_t *,
        unsigned int);

ec_sdo_request_t *ecrt_slave_config_create_sdo_request_err(
        ec_slave_config_t *, uint16_t, uint8_t, size_t);
ec_voe_handler_t *ecrt_slave_config_create_voe_handler_err(
        ec_slave_config_t *, size_t);
ec_reg_request_t *ecrt_slave_config_create_reg_request_err(
        ec_slave_config_t *, size_t);

/*****************************************************************************/

#endif


<|start_filename|>rootfs/buildroot-2017.11.1/package/pdbg/pdbg.mk<|end_filename|>
################################################################################
#
# pdbg
#
################################################################################

PDBG_VERSION = 527fe54e1c95e031efd3db008c3f4e096cb3ea58
PDBG_SITE = $(call github,open-power,pdbg,$(PDBG_VERSION))
PDBG_LICENSE = Apache-2.0
PDBG_LICENSE_FILES = COPYING
PDBG_AUTORECONF = YES
PDBG_DEPENDENCIES = host-dtc

PDBG_MAKE_OPTS = "GIT_SHA1=\"$(PDBG_VERSION)\""

define PDBG_PATCH_M4
	mkdir -p $(@D)/m4
endef
PDBG_POST_PATCH_HOOKS += PDBG_PATCH_M4

$(eval $(autotools-package))


<|start_filename|>3rdpart/ethercat-1.5.2/master/fsm_soe.h<|end_filename|>
/******************************************************************************
 *
 *  $Id: fsm_soe.h,v 9cdd7669dc0b 2013/01/10 16:36:41 fp $
 *
 *  Copyright (C) 2006-2008  <NAME>, Ingenieurgemeinschaft IgH
 *
 *  This file is part of the IgH EtherCAT Master.
 *
 *  The IgH EtherCAT Master is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License version 2, as
 *  published by the Free Software Foundation.
 *
 *  The IgH EtherCAT Master is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 *  Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with the IgH EtherCAT Master; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 *****************************************************************************/

/**
   \file
   EtherCAT CoE state machines.
*/

/*****************************************************************************/

#ifndef __EC_FSM_SOE_H__
#define __EC_FSM_SOE_H__

#include "globals.h"
#include "datagram.h"
#include "slave.h"
#include "soe_request.h"

/*****************************************************************************/

typedef struct ec_fsm_soe ec_fsm_soe_t; /**< \see ec_fsm_soe */

/** Finite state machines for the Sercos over EtherCAT protocol.
 */
struct ec_fsm_soe {
    ec_slave_t *slave; /**< slave the FSM runs on */
    unsigned int retries; /**< retries upon datagram timeout */

    void (*state)(ec_fsm_soe_t *, ec_datagram_t *); /**< CoE state function */
    ec_datagram_t *datagram; /**< Datagram used in the previous step. */
    unsigned long jiffies_start; /**< Timestamp. */
    ec_soe_request_t *request; /**< SoE request */
    off_t offset; /**< IDN data offset during fragmented write. */
    size_t fragment_size; /**< Size of the current fragment. */
};

/*****************************************************************************/

void ec_fsm_soe_init(ec_fsm_soe_t *);
void ec_fsm_soe_clear(ec_fsm_soe_t *);

void ec_fsm_soe_transfer(ec_fsm_soe_t *, ec_slave_t *, ec_soe_request_t *);

int ec_fsm_soe_exec(ec_fsm_soe_t *, ec_datagram_t *);
int ec_fsm_soe_success(const ec_fsm_soe_t *);

/*****************************************************************************/

#endif


<|start_filename|>3rdpart/ethercat-1.5.2/lib/ioctl.h<|end_filename|>
/******************************************************************************
 *
 *  $Id: common.c,v 572948e8b2ed 2012/07/09 08:29:15 fp $
 *
 *  Copyright (C) 2006-2012  <NAME>, Ingenieurgemeinschaft IgH
 *
 *  This file is part of the IgH EtherCAT master userspace library.
 *
 *  The IgH EtherCAT master userspace library is free software; you can
 *  redistribute it and/or modify it under the terms of the GNU Lesser General
 *  Public License as published by the Free Software Foundation; version 2.1
 *  of the License.
 *
 *  The IgH EtherCAT master userspace library is distributed in the hope that
 *  it will be useful, but WITHOUT ANY WARRANTY; without even the implied
 *  warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public License
 *  along with the IgH EtherCAT master userspace library. If not, see
 *  <http://www.gnu.org/licenses/>.
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 *****************************************************************************/

#ifndef __EC_LIB_IOCTL_H__
#define __EC_LIB_IOCTL_H__

/*****************************************************************************/

#ifdef USE_RTDM
#include <rtdm/rtdm.h>
#else
#include <sys/ioctl.h>
#endif

/*****************************************************************************/

#include "master/ioctl.h"

/*****************************************************************************/

#ifdef USE_RTDM

#define ioctl rt_dev_ioctl

/* rt_dev_ioctl() returns negative error code */
#define EC_IOCTL_IS_ERROR(X) ((X) < 0)
#define EC_IOCTL_ERRNO(X) (-(X))

#else

#define ioctl ioctl

/* libc's ioctl() always returns -1 on error and sets errno */
#define EC_IOCTL_IS_ERROR(X) ((X) == -1)
#define EC_IOCTL_ERRNO(X) (errno)

#include <errno.h>

#endif

/*****************************************************************************/

#endif /* __EC_LIB_IOCTL_H__ */

/*****************************************************************************/



<|start_filename|>3rdpart/tslib-1.15/tests/ts_finddev.c<|end_filename|>
/*
 *  tslib/src/ts_finddev.c
 *
 *  Derived from tslib/src/ts_test.c by <NAME>
 *
 * This file is placed under the GPL.  Please see the file
 * COPYING for more details.
 *
 * SPDX-License-Identifier: GPL-2.0+
 */
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/time.h>
#include <unistd.h>

#include "tslib.h"

static void usage(char **argv)
{
	struct ts_lib_version_data *ver = ts_libversion();

	printf("                 _       _ _ _\n");
	printf("                | |_ ___| (_) |__\n");
	printf("                | __/ __| | | '_ \\\n");
	printf("                | |_\\__ \\ | | |_) |\n");
	printf("                 \\__|___/_|_|_.__/\n\n");
	printf("tslib %s / libts ABI version %d (0x%06X)\n",
		ver->package_version, ver->version_num >> 16, ver->version_num);
	printf("\n");
	printf("Usage: %s device_name wait_for_sec\n", argv[0]);
	printf("\tdevice_name  - tdevice to probe, example /dev/input/event0\n");
	printf("\twait_for_sec - wait seconds for touch event, if 0 - don't wait!\n");
	printf("\tReturn codes:\n");
	printf("\t  0          - timeout expired without receiving event.\n");
	printf("\t               But this maybe is TouchScreen.\n");
	printf("\t -1          - this is NOT TouchScreen device!\n");
	printf("\t  1          - this is TouchScreen for shure!\n");
	exit(-1);
}

static void alarm_handler(int sig)
{
	/* time is expired */
	printf("signal %d caught\n", sig);

	exit(0);
}

int main(int argc, char **argv)
{
	struct tsdev *ts;
	struct ts_sample samp;
	char *tsdevice = NULL;
	int waitsec;
	int ret;

	if (argc != 3)
		usage(argv);

	tsdevice = argv[1];
	waitsec = atoi(argv[2]);
	if (waitsec < 0)
		usage(argv);

	ts = ts_setup(tsdevice, 0);
	if (!ts)
		return -1;

	if (!waitsec)
		return 0;

	printf("Probe device %s, Please Touch Screen Anywhere in %i seconds! ...\n",
	       tsdevice, waitsec);
	signal(SIGALRM, alarm_handler);
	alarm(waitsec);
	ret = ts_read_raw(ts, &samp, 1);
	ts_close(ts);
	if (ret)
		return 1;

	return -1;
}


<|start_filename|>3rdpart/ethercat-1.5.2/tool/NumberListParser.cpp<|end_filename|>
/*****************************************************************************
 *
 *  $Id: NumberListParser.cpp,v ee4782738e30 2011/01/04 07:36:41 fp $
 *
 *  Copyright (C) 2006-2009  <NAME>, Ingenieurgemeinschaft IgH
 *
 *  This file is part of the IgH EtherCAT Master.
 *
 *  The IgH EtherCAT Master is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License version 2, as
 *  published by the Free Software Foundation.
 *
 *  The IgH EtherCAT Master is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 *  Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with the IgH EtherCAT Master; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 ****************************************************************************/

#include <cstring>
#include <sstream>
#include <stdexcept>
using namespace std;

#include "NumberListParser.h"

/*****************************************************************************/

NumberListParser::NumberListParser():
    max(0U),
    hasMax(false)
{
}

/*****************************************************************************/

NumberListParser::~NumberListParser()
{
}

/*****************************************************************************/

NumberListParser::List NumberListParser::parse(const char *data)
{
    List ret;
    unsigned int i = 0, size = strlen(data), firstNum = 0U, secondNum = 0U;
    typedef enum {
        SectionStart,
        FirstNumber,
        Range,
        SecondNumber,
        Finished
    } State;
    State state = SectionStart;

    while (state != Finished) {
        switch (state) {
            case SectionStart:
                if (i >= size) {
                    state = Finished;
                } else if (isNumeric(data[i])) {
                    firstNum = parseNumber(data, &i, size);
                    state = FirstNumber;
                } else if (data[i] == '-') {
                    firstNum = 0U;
                    i++;
                    state = Range;
                } else if (data[i] == ',') {
                    i++;
                } else {
                    stringstream err;
                    err << "Invalid character " << data[i]
                        << " at position " << i << "in state "
                        << state << "." << endl;
                    throw runtime_error(err.str());
                }
                break;

            case FirstNumber:
                if (i >= size) {
                    ret.push_back(firstNum);
                    state = Finished;
                } else if (data[i] == '-') {
                    i++;
                    state = Range;
                } else if (data[i] == ',') {
                    i++;
                    ret.push_back(firstNum);
                    state = SectionStart;
                } else {
                    stringstream err;
                    err << "Invalid character " << data[i]
                        << " at position " << i << "in state "
                        << state << "." << endl;
                    throw runtime_error(err.str());
                }
                break;

            case Range:
                if (i >= size) {
                    int max = maximum();
                    // only increasing ranges if second number omitted
                    if (max >= 0 && firstNum <= (unsigned int) max) {
                        List r = range(firstNum, max);
                        ret.splice(ret.end(), r);
                    }
                    state = Finished;
                } else if (isNumeric(data[i])) {
                    secondNum = parseNumber(data, &i, size);
                    state = SecondNumber;
                } else if (data[i] == ',') {
                    int max = maximum();
                    i++;
                    if (max >= 0) {
                        List r = range(firstNum, max);
                        ret.splice(ret.end(), r);
                    }
                    state = SectionStart;
                } else {
                    stringstream err;
                    err << "Invalid character " << data[i]
                        << " at position " << i << "in state "
                        << state << "." << endl;
                    throw runtime_error(err.str());
                }
                break;

            case SecondNumber:
                if (i >= size) {
                    List r = range(firstNum, secondNum);
                    ret.splice(ret.end(), r);
                    state = Finished;
                } else if (data[i] == ',') {
                    i++;
                    List r = range(firstNum, secondNum);
                    ret.splice(ret.end(), r);
                    state = SectionStart;
                } else {
                    stringstream err;
                    err << "Invalid character " << data[i]
                        << " at position " << i << "in state "
                        << state << "." << endl;
                    throw runtime_error(err.str());
                }
                break;

            default:
                {
                    stringstream err;
                    err << "Invalid state " << state << ".";
                    throw runtime_error(err.str());
                }
        }
    }

    return ret;
}

/*****************************************************************************/

int NumberListParser::maximum()
{
    if (!hasMax) {
        max = getMax();
    }

    return max;
}

/*****************************************************************************/

bool NumberListParser::isNumeric(char c)
{
    return c >= '0' && c <= '9';
}

/*****************************************************************************/

unsigned int NumberListParser::parseNumber(
        const char *data,
        unsigned int *i,
        unsigned int size
        )
{
    unsigned int numSize = 0U, ret;

    while (*i + numSize < size && isNumeric(data[*i + numSize])) {
        numSize++;
    }

    if (numSize) {
        stringstream str;
        str << string(data + *i, numSize);
        str >> ret;
    } else {
        throw runtime_error("EOF");
    }

    *i = *i + numSize;
    return ret;
}

/****************************************************************************/

NumberListParser::List NumberListParser::range(
        unsigned int i,
        unsigned int j
        )
{
    List ret;

    if (i <= j) {
        for (; i <= j; i++) {
            ret.push_back(i);
        }
    } else {
        for (; j <= i; j++) {
            ret.push_front(j);
        }
    }

    return ret;
}

/****************************************************************************/


<|start_filename|>3rdpart/ethercat-1.5.2/devices/e1000e/e1000-2.6.33-orig.h<|end_filename|>
/*******************************************************************************

  Intel PRO/1000 Linux driver
  Copyright(c) 1999 - 2009 Intel Corporation.

  This program is free software; you can redistribute it and/or modify it
  under the terms and conditions of the GNU General Public License,
  version 2, as published by the Free Software Foundation.

  This program is distributed in the hope it will be useful, but WITHOUT
  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  more details.

  You should have received a copy of the GNU General Public License along with
  this program; if not, write to the Free Software Foundation, Inc.,
  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.

  The full GNU General Public License is included in this distribution in
  the file called "COPYING".

  Contact Information:
  Linux NICS <<EMAIL>>
  e1000-devel Mailing List <<EMAIL>>
  Intel Corporation, 5200 N.E. <NAME>way, Hillsboro, OR 97124-6497

*******************************************************************************/

/* Linux PRO/1000 Ethernet Driver main header file */

#ifndef _E1000_H_
#define _E1000_H_

#include <linux/types.h>
#include <linux/timer.h>
#include <linux/workqueue.h>
#include <linux/io.h>
#include <linux/netdevice.h>
#include <linux/pci.h>

#include "hw.h"

struct e1000_info;

#define e_printk(level, adapter, format, arg...) \
	printk(level "%s: %s: " format, pci_name(adapter->pdev), \
	       adapter->netdev->name, ## arg)

#ifdef DEBUG
#define e_dbg(format, arg...) \
	e_printk(KERN_DEBUG , hw->adapter, format, ## arg)
#else
#define e_dbg(format, arg...) do { (void)(hw); } while (0)
#endif

#define e_err(format, arg...) \
	e_printk(KERN_ERR, adapter, format, ## arg)
#define e_info(format, arg...) \
	e_printk(KERN_INFO, adapter, format, ## arg)
#define e_warn(format, arg...) \
	e_printk(KERN_WARNING, adapter, format, ## arg)
#define e_notice(format, arg...) \
	e_printk(KERN_NOTICE, adapter, format, ## arg)


/* Interrupt modes, as used by the IntMode parameter */
#define E1000E_INT_MODE_LEGACY		0
#define E1000E_INT_MODE_MSI		1
#define E1000E_INT_MODE_MSIX		2

/* Tx/Rx descriptor defines */
#define E1000_DEFAULT_TXD		256
#define E1000_MAX_TXD			4096
#define E1000_MIN_TXD			64

#define E1000_DEFAULT_RXD		256
#define E1000_MAX_RXD			4096
#define E1000_MIN_RXD			64

#define E1000_MIN_ITR_USECS		10 /* 100000 irq/sec */
#define E1000_MAX_ITR_USECS		10000 /* 100    irq/sec */

/* Early Receive defines */
#define E1000_ERT_2048			0x100

#define E1000_FC_PAUSE_TIME		0x0680 /* 858 usec */

/* How many Tx Descriptors do we need to call netif_wake_queue ? */
/* How many Rx Buffers do we bundle into one write to the hardware ? */
#define E1000_RX_BUFFER_WRITE		16 /* Must be power of 2 */

#define AUTO_ALL_MODES			0
#define E1000_EEPROM_APME		0x0400

#define E1000_MNG_VLAN_NONE		(-1)

/* Number of packet split data buffers (not including the header buffer) */
#define PS_PAGE_BUFFERS			(MAX_PS_BUFFERS - 1)

#define DEFAULT_JUMBO			9234

/* BM/HV Specific Registers */
#define BM_PORT_CTRL_PAGE                 769

#define PHY_UPPER_SHIFT                   21
#define BM_PHY_REG(page, reg) \
	(((reg) & MAX_PHY_REG_ADDRESS) |\
	 (((page) & 0xFFFF) << PHY_PAGE_SHIFT) |\
	 (((reg) & ~MAX_PHY_REG_ADDRESS) << (PHY_UPPER_SHIFT - PHY_PAGE_SHIFT)))

/* PHY Wakeup Registers and defines */
#define BM_RCTL         PHY_REG(BM_WUC_PAGE, 0)
#define BM_WUC          PHY_REG(BM_WUC_PAGE, 1)
#define BM_WUFC         PHY_REG(BM_WUC_PAGE, 2)
#define BM_WUS          PHY_REG(BM_WUC_PAGE, 3)
#define BM_RAR_L(_i)    (BM_PHY_REG(BM_WUC_PAGE, 16 + ((_i) << 2)))
#define BM_RAR_M(_i)    (BM_PHY_REG(BM_WUC_PAGE, 17 + ((_i) << 2)))
#define BM_RAR_H(_i)    (BM_PHY_REG(BM_WUC_PAGE, 18 + ((_i) << 2)))
#define BM_RAR_CTRL(_i) (BM_PHY_REG(BM_WUC_PAGE, 19 + ((_i) << 2)))
#define BM_MTA(_i)      (BM_PHY_REG(BM_WUC_PAGE, 128 + ((_i) << 1)))

#define BM_RCTL_UPE           0x0001          /* Unicast Promiscuous Mode */
#define BM_RCTL_MPE           0x0002          /* Multicast Promiscuous Mode */
#define BM_RCTL_MO_SHIFT      3               /* Multicast Offset Shift */
#define BM_RCTL_MO_MASK       (3 << 3)        /* Multicast Offset Mask */
#define BM_RCTL_BAM           0x0020          /* Broadcast Accept Mode */
#define BM_RCTL_PMCF          0x0040          /* Pass MAC Control Frames */
#define BM_RCTL_RFCE          0x0080          /* Rx Flow Control Enable */

#define HV_SCC_UPPER		PHY_REG(778, 16) /* Single Collision Count */
#define HV_SCC_LOWER		PHY_REG(778, 17)
#define HV_ECOL_UPPER		PHY_REG(778, 18) /* Excessive Collision Count */
#define HV_ECOL_LOWER		PHY_REG(778, 19)
#define HV_MCC_UPPER		PHY_REG(778, 20) /* Multiple Collision Count */
#define HV_MCC_LOWER		PHY_REG(778, 21)
#define HV_LATECOL_UPPER	PHY_REG(778, 23) /* Late Collision Count */
#define HV_LATECOL_LOWER	PHY_REG(778, 24)
#define HV_COLC_UPPER		PHY_REG(778, 25) /* Collision Count */
#define HV_COLC_LOWER		PHY_REG(778, 26)
#define HV_DC_UPPER		PHY_REG(778, 27) /* Defer Count */
#define HV_DC_LOWER		PHY_REG(778, 28)
#define HV_TNCRS_UPPER		PHY_REG(778, 29) /* Transmit with no CRS */
#define HV_TNCRS_LOWER		PHY_REG(778, 30)

#define E1000_FCRTV_PCH     0x05F40 /* PCH Flow Control Refresh Timer Value */

/* BM PHY Copper Specific Status */
#define BM_CS_STATUS                      17
#define BM_CS_STATUS_LINK_UP              0x0400
#define BM_CS_STATUS_RESOLVED             0x0800
#define BM_CS_STATUS_SPEED_MASK           0xC000
#define BM_CS_STATUS_SPEED_1000           0x8000

/* 82577 Mobile Phy Status Register */
#define HV_M_STATUS                       26
#define HV_M_STATUS_AUTONEG_COMPLETE      0x1000
#define HV_M_STATUS_SPEED_MASK            0x0300
#define HV_M_STATUS_SPEED_1000            0x0200
#define HV_M_STATUS_LINK_UP               0x0040

enum e1000_boards {
	board_82571,
	board_82572,
	board_82573,
	board_82574,
	board_82583,
	board_80003es2lan,
	board_ich8lan,
	board_ich9lan,
	board_ich10lan,
	board_pchlan,
};

struct e1000_queue_stats {
	u64 packets;
	u64 bytes;
};

struct e1000_ps_page {
	struct page *page;
	u64 dma; /* must be u64 - written to hw */
};

/*
 * wrappers around a pointer to a socket buffer,
 * so a DMA handle can be stored along with the buffer
 */
struct e1000_buffer {
	dma_addr_t dma;
	struct sk_buff *skb;
	union {
		/* Tx */
		struct {
			unsigned long time_stamp;
			u16 length;
			u16 next_to_watch;
			u16 mapped_as_page;
		};
		/* Rx */
		struct {
			/* arrays of page information for packet split */
			struct e1000_ps_page *ps_pages;
			struct page *page;
		};
	};
};

struct e1000_ring {
	void *desc;			/* pointer to ring memory  */
	dma_addr_t dma;			/* phys address of ring    */
	unsigned int size;		/* length of ring in bytes */
	unsigned int count;		/* number of desc. in ring */

	u16 next_to_use;
	u16 next_to_clean;

	u16 head;
	u16 tail;

	/* array of buffer information structs */
	struct e1000_buffer *buffer_info;

	char name[IFNAMSIZ + 5];
	u32 ims_val;
	u32 itr_val;
	u16 itr_register;
	int set_itr;

	struct sk_buff *rx_skb_top;

	struct e1000_queue_stats stats;
};

/* PHY register snapshot values */
struct e1000_phy_regs {
	u16 bmcr;		/* basic mode control register    */
	u16 bmsr;		/* basic mode status register     */
	u16 advertise;		/* auto-negotiation advertisement */
	u16 lpa;		/* link partner ability register  */
	u16 expansion;		/* auto-negotiation expansion reg */
	u16 ctrl1000;		/* 1000BASE-T control register    */
	u16 stat1000;		/* 1000BASE-T status register     */
	u16 estatus;		/* extended status register       */
};

/* board specific private data structure */
struct e1000_adapter {
	struct timer_list watchdog_timer;
	struct timer_list phy_info_timer;
	struct timer_list blink_timer;

	struct work_struct reset_task;
	struct work_struct watchdog_task;

	const struct e1000_info *ei;

	struct vlan_group *vlgrp;
	u32 bd_number;
	u32 rx_buffer_len;
	u16 mng_vlan_id;
	u16 link_speed;
	u16 link_duplex;
	u16 eeprom_vers;

	/* track device up/down/testing state */
	unsigned long state;

	/* Interrupt Throttle Rate */
	u32 itr;
	u32 itr_setting;
	u16 tx_itr;
	u16 rx_itr;

	/*
	 * Tx
	 */
	struct e1000_ring *tx_ring /* One per active queue */
						____cacheline_aligned_in_smp;

	struct napi_struct napi;

	unsigned long tx_queue_len;
	unsigned int restart_queue;
	u32 txd_cmd;

	bool detect_tx_hung;
	u8 tx_timeout_factor;

	u32 tx_int_delay;
	u32 tx_abs_int_delay;

	unsigned int total_tx_bytes;
	unsigned int total_tx_packets;
	unsigned int total_rx_bytes;
	unsigned int total_rx_packets;

	/* Tx stats */
	u64 tpt_old;
	u64 colc_old;
	u32 gotc;
	u64 gotc_old;
	u32 tx_timeout_count;
	u32 tx_fifo_head;
	u32 tx_head_addr;
	u32 tx_fifo_size;
	u32 tx_dma_failed;

	/*
	 * Rx
	 */
	bool (*clean_rx) (struct e1000_adapter *adapter,
			  int *work_done, int work_to_do)
						____cacheline_aligned_in_smp;
	void (*alloc_rx_buf) (struct e1000_adapter *adapter,
			      int cleaned_count);
	struct e1000_ring *rx_ring;

	u32 rx_int_delay;
	u32 rx_abs_int_delay;

	/* Rx stats */
	u64 hw_csum_err;
	u64 hw_csum_good;
	u64 rx_hdr_split;
	u32 gorc;
	u64 gorc_old;
	u32 alloc_rx_buff_failed;
	u32 rx_dma_failed;

	unsigned int rx_ps_pages;
	u16 rx_ps_bsize0;
	u32 max_frame_size;
	u32 min_frame_size;

	/* OS defined structs */
	struct net_device *netdev;
	struct pci_dev *pdev;

	/* structs defined in e1000_hw.h */
	struct e1000_hw hw;

	struct e1000_hw_stats stats;
	struct e1000_phy_info phy_info;
	struct e1000_phy_stats phy_stats;

	/* Snapshot of PHY registers */
	struct e1000_phy_regs phy_regs;

	struct e1000_ring test_tx_ring;
	struct e1000_ring test_rx_ring;
	u32 test_icr;

	u32 msg_enable;
	struct msix_entry *msix_entries;
	int int_mode;
	u32 eiac_mask;

	u32 eeprom_wol;
	u32 wol;
	u32 pba;
	u32 max_hw_frame_size;

	bool fc_autoneg;

	unsigned long led_status;

	unsigned int flags;
	unsigned int flags2;
	struct work_struct downshift_task;
	struct work_struct update_phy_task;
	struct work_struct led_blink_task;
	struct work_struct print_hang_task;
};

struct e1000_info {
	enum e1000_mac_type	mac;
	unsigned int		flags;
	unsigned int            flags2;
	u32			pba;
	u32			max_hw_frame_size;
	s32			(*get_variants)(struct e1000_adapter *);
	struct e1000_mac_operations *mac_ops;
	struct e1000_phy_operations *phy_ops;
	struct e1000_nvm_operations *nvm_ops;
};

/* hardware capability, feature, and workaround flags */
#define FLAG_HAS_AMT                      (1 << 0)
#define FLAG_HAS_FLASH                    (1 << 1)
#define FLAG_HAS_HW_VLAN_FILTER           (1 << 2)
#define FLAG_HAS_WOL                      (1 << 3)
#define FLAG_HAS_ERT                      (1 << 4)
#define FLAG_HAS_CTRLEXT_ON_LOAD          (1 << 5)
#define FLAG_HAS_SWSM_ON_LOAD             (1 << 6)
#define FLAG_HAS_JUMBO_FRAMES             (1 << 7)
#define FLAG_READ_ONLY_NVM                (1 << 8)
#define FLAG_IS_ICH                       (1 << 9)
#define FLAG_HAS_MSIX                     (1 << 10)
#define FLAG_HAS_SMART_POWER_DOWN         (1 << 11)
#define FLAG_IS_QUAD_PORT_A               (1 << 12)
#define FLAG_IS_QUAD_PORT                 (1 << 13)
#define FLAG_TIPG_MEDIUM_FOR_80003ESLAN   (1 << 14)
#define FLAG_APME_IN_WUC                  (1 << 15)
#define FLAG_APME_IN_CTRL3                (1 << 16)
#define FLAG_APME_CHECK_PORT_B            (1 << 17)
#define FLAG_DISABLE_FC_PAUSE_TIME        (1 << 18)
#define FLAG_NO_WAKE_UCAST                (1 << 19)
#define FLAG_MNG_PT_ENABLED               (1 << 20)
#define FLAG_RESET_OVERWRITES_LAA         (1 << 21)
#define FLAG_TARC_SPEED_MODE_BIT          (1 << 22)
#define FLAG_TARC_SET_BIT_ZERO            (1 << 23)
#define FLAG_RX_NEEDS_RESTART             (1 << 24)
#define FLAG_LSC_GIG_SPEED_DROP           (1 << 25)
#define FLAG_SMART_POWER_DOWN             (1 << 26)
#define FLAG_MSI_ENABLED                  (1 << 27)
#define FLAG_RX_CSUM_ENABLED              (1 << 28)
#define FLAG_TSO_FORCE                    (1 << 29)
#define FLAG_RX_RESTART_NOW               (1 << 30)
#define FLAG_MSI_TEST_FAILED              (1 << 31)

/* CRC Stripping defines */
#define FLAG2_CRC_STRIPPING               (1 << 0)
#define FLAG2_HAS_PHY_WAKEUP              (1 << 1)
#define FLAG2_IS_DISCARDING               (1 << 2)

#define E1000_RX_DESC_PS(R, i)	    \
	(&(((union e1000_rx_desc_packet_split *)((R).desc))[i]))
#define E1000_GET_DESC(R, i, type)	(&(((struct type *)((R).desc))[i]))
#define E1000_RX_DESC(R, i)		E1000_GET_DESC(R, i, e1000_rx_desc)
#define E1000_TX_DESC(R, i)		E1000_GET_DESC(R, i, e1000_tx_desc)
#define E1000_CONTEXT_DESC(R, i)	E1000_GET_DESC(R, i, e1000_context_desc)

enum e1000_state_t {
	__E1000_TESTING,
	__E1000_RESETTING,
	__E1000_DOWN
};

enum latency_range {
	lowest_latency = 0,
	low_latency = 1,
	bulk_latency = 2,
	latency_invalid = 255
};

extern char e1000e_driver_name[];
extern const char e1000e_driver_version[];

extern void e1000e_check_options(struct e1000_adapter *adapter);
extern void e1000e_set_ethtool_ops(struct net_device *netdev);

extern int e1000e_up(struct e1000_adapter *adapter);
extern void e1000e_down(struct e1000_adapter *adapter);
extern void e1000e_reinit_locked(struct e1000_adapter *adapter);
extern void e1000e_reset(struct e1000_adapter *adapter);
extern void e1000e_power_up_phy(struct e1000_adapter *adapter);
extern int e1000e_setup_rx_resources(struct e1000_adapter *adapter);
extern int e1000e_setup_tx_resources(struct e1000_adapter *adapter);
extern void e1000e_free_rx_resources(struct e1000_adapter *adapter);
extern void e1000e_free_tx_resources(struct e1000_adapter *adapter);
extern void e1000e_update_stats(struct e1000_adapter *adapter);
extern bool e1000_has_link(struct e1000_adapter *adapter);
extern void e1000e_set_interrupt_capability(struct e1000_adapter *adapter);
extern void e1000e_reset_interrupt_capability(struct e1000_adapter *adapter);

extern unsigned int copybreak;

extern char *e1000e_get_hw_dev_name(struct e1000_hw *hw);

extern struct e1000_info e1000_82571_info;
extern struct e1000_info e1000_82572_info;
extern struct e1000_info e1000_82573_info;
extern struct e1000_info e1000_82574_info;
extern struct e1000_info e1000_82583_info;
extern struct e1000_info e1000_ich8_info;
extern struct e1000_info e1000_ich9_info;
extern struct e1000_info e1000_ich10_info;
extern struct e1000_info e1000_pch_info;
extern struct e1000_info e1000_es2_info;

extern s32 e1000e_read_pba_num(struct e1000_hw *hw, u32 *pba_num);

extern s32  e1000e_commit_phy(struct e1000_hw *hw);

extern bool e1000e_enable_mng_pass_thru(struct e1000_hw *hw);

extern bool e1000e_get_laa_state_82571(struct e1000_hw *hw);
extern void e1000e_set_laa_state_82571(struct e1000_hw *hw, bool state);

extern void e1000e_write_protect_nvm_ich8lan(struct e1000_hw *hw);
extern void e1000e_set_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw,
						 bool state);
extern void e1000e_igp3_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw);
extern void e1000e_gig_downshift_workaround_ich8lan(struct e1000_hw *hw);
extern void e1000e_disable_gig_wol_ich8lan(struct e1000_hw *hw);
extern s32 e1000_configure_k1_ich8lan(struct e1000_hw *hw, bool k1_enable);

extern s32 e1000e_check_for_copper_link(struct e1000_hw *hw);
extern s32 e1000e_check_for_fiber_link(struct e1000_hw *hw);
extern s32 e1000e_check_for_serdes_link(struct e1000_hw *hw);
extern s32 e1000e_setup_led_generic(struct e1000_hw *hw);
extern s32 e1000e_cleanup_led_generic(struct e1000_hw *hw);
extern s32 e1000e_led_on_generic(struct e1000_hw *hw);
extern s32 e1000e_led_off_generic(struct e1000_hw *hw);
extern s32 e1000e_get_bus_info_pcie(struct e1000_hw *hw);
extern s32 e1000e_get_speed_and_duplex_copper(struct e1000_hw *hw, u16 *speed, u16 *duplex);
extern s32 e1000e_get_speed_and_duplex_fiber_serdes(struct e1000_hw *hw, u16 *speed, u16 *duplex);
extern s32 e1000e_disable_pcie_master(struct e1000_hw *hw);
extern s32 e1000e_get_auto_rd_done(struct e1000_hw *hw);
extern s32 e1000e_id_led_init(struct e1000_hw *hw);
extern void e1000e_clear_hw_cntrs_base(struct e1000_hw *hw);
extern s32 e1000e_setup_fiber_serdes_link(struct e1000_hw *hw);
extern s32 e1000e_copper_link_setup_m88(struct e1000_hw *hw);
extern s32 e1000e_copper_link_setup_igp(struct e1000_hw *hw);
extern s32 e1000e_setup_link(struct e1000_hw *hw);
extern void e1000_clear_vfta_generic(struct e1000_hw *hw);
extern void e1000e_init_rx_addrs(struct e1000_hw *hw, u16 rar_count);
extern void e1000e_update_mc_addr_list_generic(struct e1000_hw *hw,
					       u8 *mc_addr_list,
					       u32 mc_addr_count,
					       u32 rar_used_count,
					       u32 rar_count);
extern void e1000e_rar_set(struct e1000_hw *hw, u8 *addr, u32 index);
extern s32 e1000e_set_fc_watermarks(struct e1000_hw *hw);
extern void e1000e_set_pcie_no_snoop(struct e1000_hw *hw, u32 no_snoop);
extern s32 e1000e_get_hw_semaphore(struct e1000_hw *hw);
extern s32 e1000e_valid_led_default(struct e1000_hw *hw, u16 *data);
extern void e1000e_config_collision_dist(struct e1000_hw *hw);
extern s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw);
extern s32 e1000e_force_mac_fc(struct e1000_hw *hw);
extern s32 e1000e_blink_led(struct e1000_hw *hw);
extern void e1000_write_vfta_generic(struct e1000_hw *hw, u32 offset, u32 value);
extern void e1000e_reset_adaptive(struct e1000_hw *hw);
extern void e1000e_update_adaptive(struct e1000_hw *hw);

extern s32 e1000e_setup_copper_link(struct e1000_hw *hw);
extern s32 e1000e_get_phy_id(struct e1000_hw *hw);
extern void e1000e_put_hw_semaphore(struct e1000_hw *hw);
extern s32 e1000e_check_reset_block_generic(struct e1000_hw *hw);
extern s32 e1000e_phy_force_speed_duplex_igp(struct e1000_hw *hw);
extern s32 e1000e_get_cable_length_igp_2(struct e1000_hw *hw);
extern s32 e1000e_get_phy_info_igp(struct e1000_hw *hw);
extern s32 e1000e_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data);
extern s32 e1000e_read_phy_reg_igp_locked(struct e1000_hw *hw, u32 offset,
                                          u16 *data);
extern s32 e1000e_phy_hw_reset_generic(struct e1000_hw *hw);
extern s32 e1000e_set_d3_lplu_state(struct e1000_hw *hw, bool active);
extern s32 e1000e_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data);
extern s32 e1000e_write_phy_reg_igp_locked(struct e1000_hw *hw, u32 offset,
                                           u16 data);
extern s32 e1000e_phy_sw_reset(struct e1000_hw *hw);
extern s32 e1000e_phy_force_speed_duplex_m88(struct e1000_hw *hw);
extern s32 e1000e_get_cfg_done(struct e1000_hw *hw);
extern s32 e1000e_get_cable_length_m88(struct e1000_hw *hw);
extern s32 e1000e_get_phy_info_m88(struct e1000_hw *hw);
extern s32 e1000e_read_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 *data);
extern s32 e1000e_write_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 data);
extern s32 e1000e_phy_init_script_igp3(struct e1000_hw *hw);
extern enum e1000_phy_type e1000e_get_phy_type_from_id(u32 phy_id);
extern s32 e1000e_determine_phy_address(struct e1000_hw *hw);
extern s32 e1000e_write_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 data);
extern s32 e1000e_read_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data);
extern s32 e1000e_read_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 *data);
extern s32 e1000e_write_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 data);
extern void e1000e_phy_force_speed_duplex_setup(struct e1000_hw *hw, u16 *phy_ctrl);
extern s32 e1000e_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data);
extern s32 e1000e_write_kmrn_reg_locked(struct e1000_hw *hw, u32 offset,
                                        u16 data);
extern s32 e1000e_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data);
extern s32 e1000e_read_kmrn_reg_locked(struct e1000_hw *hw, u32 offset,
                                       u16 *data);
extern s32 e1000e_phy_has_link_generic(struct e1000_hw *hw, u32 iterations,
			       u32 usec_interval, bool *success);
extern s32 e1000e_phy_reset_dsp(struct e1000_hw *hw);
extern void e1000_power_up_phy_copper(struct e1000_hw *hw);
extern void e1000_power_down_phy_copper(struct e1000_hw *hw);
extern s32 e1000e_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data);
extern s32 e1000e_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data);
extern s32 e1000e_check_downshift(struct e1000_hw *hw);
extern s32 e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data);
extern s32 e1000_read_phy_reg_hv_locked(struct e1000_hw *hw, u32 offset,
                                        u16 *data);
extern s32 e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data);
extern s32 e1000_write_phy_reg_hv_locked(struct e1000_hw *hw, u32 offset,
                                         u16 data);
extern s32 e1000_link_stall_workaround_hv(struct e1000_hw *hw);
extern s32 e1000_copper_link_setup_82577(struct e1000_hw *hw);
extern s32 e1000_check_polarity_82577(struct e1000_hw *hw);
extern s32 e1000_get_phy_info_82577(struct e1000_hw *hw);
extern s32 e1000_phy_force_speed_duplex_82577(struct e1000_hw *hw);
extern s32 e1000_get_cable_length_82577(struct e1000_hw *hw);

extern s32 e1000_check_polarity_m88(struct e1000_hw *hw);
extern s32 e1000_get_phy_info_ife(struct e1000_hw *hw);
extern s32 e1000_check_polarity_ife(struct e1000_hw *hw);
extern s32 e1000_phy_force_speed_duplex_ife(struct e1000_hw *hw);
extern s32 e1000_check_polarity_igp(struct e1000_hw *hw);

static inline s32 e1000_phy_hw_reset(struct e1000_hw *hw)
{
	return hw->phy.ops.reset(hw);
}

static inline s32 e1000_check_reset_block(struct e1000_hw *hw)
{
	return hw->phy.ops.check_reset_block(hw);
}

static inline s32 e1e_rphy(struct e1000_hw *hw, u32 offset, u16 *data)
{
	return hw->phy.ops.read_reg(hw, offset, data);
}

static inline s32 e1e_wphy(struct e1000_hw *hw, u32 offset, u16 data)
{
	return hw->phy.ops.write_reg(hw, offset, data);
}

static inline s32 e1000_get_cable_length(struct e1000_hw *hw)
{
	return hw->phy.ops.get_cable_length(hw);
}

extern s32 e1000e_acquire_nvm(struct e1000_hw *hw);
extern s32 e1000e_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data);
extern s32 e1000e_update_nvm_checksum_generic(struct e1000_hw *hw);
extern s32 e1000e_poll_eerd_eewr_done(struct e1000_hw *hw, int ee_reg);
extern s32 e1000e_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data);
extern s32 e1000e_validate_nvm_checksum_generic(struct e1000_hw *hw);
extern void e1000e_release_nvm(struct e1000_hw *hw);
extern void e1000e_reload_nvm(struct e1000_hw *hw);
extern s32 e1000e_read_mac_addr(struct e1000_hw *hw);

static inline s32 e1000_validate_nvm_checksum(struct e1000_hw *hw)
{
	return hw->nvm.ops.validate(hw);
}

static inline s32 e1000e_update_nvm_checksum(struct e1000_hw *hw)
{
	return hw->nvm.ops.update(hw);
}

static inline s32 e1000_read_nvm(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
{
	return hw->nvm.ops.read(hw, offset, words, data);
}

static inline s32 e1000_write_nvm(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
{
	return hw->nvm.ops.write(hw, offset, words, data);
}

static inline s32 e1000_get_phy_info(struct e1000_hw *hw)
{
	return hw->phy.ops.get_info(hw);
}

static inline s32 e1000e_check_mng_mode(struct e1000_hw *hw)
{
	return hw->mac.ops.check_mng_mode(hw);
}

extern bool e1000e_check_mng_mode_generic(struct e1000_hw *hw);
extern bool e1000e_enable_tx_pkt_filtering(struct e1000_hw *hw);
extern s32 e1000e_mng_write_dhcp_info(struct e1000_hw *hw, u8 *buffer, u16 length);

static inline u32 __er32(struct e1000_hw *hw, unsigned long reg)
{
	return readl(hw->hw_addr + reg);
}

static inline void __ew32(struct e1000_hw *hw, unsigned long reg, u32 val)
{
	writel(val, hw->hw_addr + reg);
}

#endif /* _E1000_H_ */


<|start_filename|>3rdpart/tslib-1.15/tests/ts_test_mt.c<|end_filename|>
/*
 *  tslib/src/ts_test_mt.c
 *
 *  Copyright (C) 2016 <NAME>
 *
 * This file is part of tslib.
 *
 * ts_test_mt is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * ts_test_mt is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with ts_test_mt.  If not, see <http://www.gnu.org/licenses/>.
 *
 * SPDX-License-Identifier: GPL-2.0+
 *
 *
 * Basic multitouch test program for the libts library.
 */
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <getopt.h>

#if defined (__FreeBSD__)

#include <dev/evdev/input.h>
#define TS_HAVE_EVDEV

#elif defined (__linux__)

#include <linux/input.h>
#define TS_HAVE_EVDEV

#endif

#ifdef TS_HAVE_EVDEV
#include <sys/ioctl.h>
#endif

#include "tslib.h"
#include "fbutils.h"
#include "testutils.h"

#ifndef ABS_MT_SLOT /* < 2.6.36 kernel headers */
# define ABS_MT_SLOT             0x2f    /* MT slot being modified */
#endif

static int palette[] = {
	0x000000, 0xffe080, 0xffffff, 0xe0c0a0, 0x304050, 0x80b8c0
};
#define NR_COLORS (int)(sizeof (palette) / sizeof (palette[0]))

#define NR_BUTTONS 3
static struct ts_button buttons[NR_BUTTONS];

static void sig(int sig)
{
	close_framebuffer();
	fflush(stderr);
	printf("signal %d caught\n", sig);
	fflush(stdout);
	exit(1);
}

static void refresh_screen(void)
{
	int i;

	fillrect(0, 0, xres - 1, yres - 1, 0);
	put_string_center(xres / 2, yres / 4, "Multitouch test program", 1);
	put_string_center(xres / 2, yres / 4 + 20,
			  "Touch screen to move crosshairs", 2);

	for (i = 0; i < NR_BUTTONS; i++)
		button_draw(&buttons[i]);
}

static void help(void)
{
	struct ts_lib_version_data *ver = ts_libversion();

	print_ascii_logo();

	printf("tslib %s / libts ABI version %d (0x%06X)\n",
		ver->package_version, ver->version_num >> 16, ver->version_num);
	printf("\n");
	printf("Usage: ts_test_mt [-v] [-i <device>] [-j <slots>] [-r <rotate_value>]\n");
	printf("\n");
	printf("        <device>       Override the input device to use\n");
	printf("        <slots>        Override the number of possible touch contacts\n");
	printf("                       Automatically detected only on Linux, but not\n");
	printf("                       for all devices\n");
	printf("        <rotate_value> 0 ... no rotation; 0 degree (default)\n");
	printf("                       1 ... clockwise orientation; 90 degrees\n");
	printf("                       2 ... upside down orientation; 180 degrees\n");
	printf("                       3 ... counterclockwise orientation; 270 degrees\n");
	printf("\n");
	printf("Example (Linux): ts_test_mt -r $(cat /sys/class/graphics/fbcon/rotate)\n");
	printf("\n");
}

void print_slot_info(char *slot_info, size_t len, int32_t max_slots,
		     int32_t user_slots)
{
	snprintf(slot_info, len,
		 "%d touch contacts supported (%s)",
		 max_slots, user_slots ? "user" : "driver");
	put_string(2, yres - 14, slot_info, 2);
}

#define CROSS_VISIBLE 0x00001000
#define CROSS_SHOW 0x00000008
#define DRAWING 0x80000000

int main(int argc, char **argv)
{
	struct tsdev *ts;
	int *x = NULL;
	int *y = NULL;
	int i, j;
	unsigned int mode = 0;
	unsigned int *mode_mt = NULL;
	int quit_pressed = 0;
#ifdef TS_HAVE_EVDEV
	struct input_absinfo slot;
#endif
	int32_t user_slots = 0;
	int32_t max_slots = 1;
	struct ts_sample_mt **samp_mt = NULL;
	short verbose = 0;

	const char *tsdevice = NULL;
	char slot_info[64];

	signal(SIGSEGV, sig);
	signal(SIGINT, sig);
	signal(SIGTERM, sig);

	while (1) {
		const struct option long_options[] = {
			{ "help",         no_argument,       NULL, 'h' },
			{ "verbose",      no_argument,       NULL, 'v' },
			{ "idev",         required_argument, NULL, 'i' },
			{ "slots",        required_argument, NULL, 'j' },
			{ "rotate",       required_argument, NULL, 'r' },
		};

		int option_index = 0;
		int c = getopt_long(argc, argv, "hi:vj:r:", long_options, &option_index);

		errno = 0;
		if (c == -1)
			break;

		switch (c) {
		case 'h':
			help();
			return 0;

		case 'v':
			verbose = 1;
			break;

		case 'i':
			tsdevice = optarg;
			break;

		case 'j':
			user_slots = atoi(optarg);
			if (user_slots <= 0) {
				help();
				return 0;
			}
			break;

		case 'r':
			/* extern in fbutils.h */
			rotation = atoi(optarg);
			if (rotation < 0 || rotation > 3) {
				help();
				return 0;
			}
			break;

		default:
			help();
			return 0;
		}

		if (errno) {
			char str[9];

			sprintf(str, "option ?");
			str[7] = c & 0xff;
			perror(str);
		}
	}

	ts = ts_setup(tsdevice, 0);
	if (!ts) {
		perror("ts_setup");
		return errno;
	}
	if (verbose && tsdevice)
		printf("ts_test_mt: using input device " GREEN "%s" RESET "\n", tsdevice);
#ifdef TS_HAVE_EVDEV
	if (ioctl(ts_fd(ts), EVIOCGABS(ABS_MT_SLOT), &slot) < 0) {
		perror("ioctl EVIOGABS");
		ts_close(ts);
		return errno;
	}

	max_slots = slot.maximum + 1 - slot.minimum;
#endif
	if (user_slots > 0)
		max_slots = user_slots;

	samp_mt = malloc(sizeof(struct ts_sample_mt *));
	if (!samp_mt) {
		ts_close(ts);
		return -ENOMEM;
	}
	samp_mt[0] = calloc(max_slots, sizeof(struct ts_sample_mt));
	if (!samp_mt[0]) {
		free(samp_mt);
		ts_close(ts);
		return -ENOMEM;
	}

	if (open_framebuffer()) {
		close_framebuffer();
		free(samp_mt[0]);
		free(samp_mt);
		ts_close(ts);
		exit(1);
	}

	x = calloc(max_slots, sizeof(int));
	if (!x)
		goto out;

	y = calloc(max_slots, sizeof(int));
	if (!y)
		goto out;

	mode_mt = calloc(max_slots, sizeof(unsigned int));
	if (!mode_mt)
		goto out;

	for (i = 0; i < max_slots; i++) {
		x[i] = xres / 2;
		y[i] = yres / 2;
	}

	for (i = 0; i < NR_COLORS; i++)
		setcolor(i, palette[i]);

	/* Initialize buttons */
	memset(&buttons, 0, sizeof(buttons));
	buttons[0].w = buttons[1].w = buttons[2].w = xres / 4;
	buttons[0].h = buttons[1].h = buttons[2].h = 20;
	buttons[0].x = 0;
	buttons[1].x = (3 * xres) / 8;
	buttons[2].x = (3 * xres) / 4;
	buttons[0].y = buttons[1].y = buttons[2].y = 10;
	buttons[0].text = "Drag";
	buttons[1].text = "Draw";
	buttons[2].text = "Quit";

	refresh_screen();
	print_slot_info(slot_info, sizeof(slot_info), max_slots, user_slots);

	while (1) {
		int ret;

		/* Show the cross */
		for (j = 0; j < max_slots; j++) {
			if ((mode & 15) != 1) { /* not in draw mode */
				/* Hide slots > 0 if released */
				if (j > 0 && !(mode_mt[j] & CROSS_SHOW))
					continue;

				if (!(mode_mt[j] & CROSS_VISIBLE))
					put_cross(x[j], y[j], 2 | XORMODE);

				mode_mt[j] |= CROSS_VISIBLE;
			}
		}

		ret = ts_read_mt(ts, samp_mt, max_slots, 1);

		/* Hide it */
		for (j = 0; j < max_slots; j++) {
			if ((mode & 15) != 1) { /* not in draw mode */
				if (j > 0 && !(mode_mt[j] & CROSS_SHOW) &&
				    !(mode_mt[j] & CROSS_VISIBLE))
					continue;

				put_cross(x[j], y[j], 2 | XORMODE);

				mode_mt[j] &= ~CROSS_VISIBLE;
			}
		}

		if (ret < 0) {
			perror("ts_read_mt");
			close_framebuffer();
			free(samp_mt);
			ts_close(ts);
			exit(1);
		}

		if (ret != 1)
			continue;

		for (j = 0; j < max_slots; j++) {
			if (!(samp_mt[0][j].valid & TSLIB_MT_VALID))
				continue;

			for (i = 0; i < NR_BUTTONS; i++) {
				if (button_handle(&buttons[i],
						  samp_mt[0][j].x,
						  samp_mt[0][j].y,
						  samp_mt[0][j].pressure)) {
					switch (i) {
					case 0:
						mode = 0x0;
						refresh_screen();
						print_slot_info(slot_info,
								sizeof(slot_info),
								max_slots,
								user_slots);
						break;
					case 1:
						mode = 0x1;
						refresh_screen();
						print_slot_info(slot_info,
								sizeof(slot_info),
								max_slots,
								user_slots);
						break;
					case 2:
						quit_pressed = 1;
					}
				}
			}

			if (verbose) {
				printf(YELLOW "%ld.%06ld:" RESET " (slot %d) %6d %6d %6d\n",
					samp_mt[0][j].tv.tv_sec,
					samp_mt[0][j].tv.tv_usec,
					samp_mt[0][j].slot,
					samp_mt[0][j].x,
					samp_mt[0][j].y,
					samp_mt[0][j].pressure);
			}

			if (samp_mt[0][j].pressure > 0) {
				if (mode & DRAWING && mode & 0x1) { /* draw mode while drawing */
					if (mode_mt[j] & DRAWING) /* slot while drawing */
						line(x[j], y[j], samp_mt[0][j].x, samp_mt[0][j].y, 2);
				}
				x[j] = samp_mt[0][j].x;
				y[j] = samp_mt[0][j].y;
				mode |= DRAWING;
				mode_mt[j] |= DRAWING;
				mode_mt[j] |= CROSS_SHOW;
			} else {
				mode &= ~DRAWING;
				mode_mt[j] &= ~DRAWING;
				mode_mt[j] &= ~CROSS_SHOW; /* hide the cross */
			}
			if (quit_pressed)
				goto out;
		}
	}

out:
	fillrect(0, 0, xres - 1, yres - 1, 0);
	close_framebuffer();

	if (ts)
		ts_close(ts);

	if (samp_mt) {
		if (samp_mt[0])
			free(samp_mt[0]);

		free(samp_mt);
	}

	if (x)
		free(x);

	if (y)
		free(y);

	if (mode_mt)
		free(mode_mt);

	return 0;
}


<|start_filename|>3rdpart/ethercat-1.5.2/tool/Command.h<|end_filename|>
/*****************************************************************************
 *
 *  $Id: Command.h,v d461b1f07296 2012/11/30 19:15:31 fp $
 *
 *  Copyright (C) 2006-2009  <NAME>, Ingenieurgemeinschaft IgH
 *
 *  This file is part of the IgH EtherCAT Master.
 *
 *  The IgH EtherCAT Master is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License version 2, as
 *  published by the Free Software Foundation.
 *
 *  The IgH EtherCAT Master is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 *  Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with the IgH EtherCAT Master; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 ****************************************************************************/

#ifndef __COMMAND_H__
#define __COMMAND_H__

#include <stdexcept>
#include <vector>
#include <list>
#include <sstream>
using namespace std;

#include "../master/ioctl.h"

class MasterDevice;

/****************************************************************************/

class InvalidUsageException:
    public runtime_error
{
    friend class Command;

    protected:
        /** Constructor with stringstream parameter. */
        InvalidUsageException(
                const stringstream &s /**< Message. */
                ): runtime_error(s.str()) {}
};

/****************************************************************************/

class CommandException:
    public runtime_error
{
    friend class Command;

    protected:
        /** Constructor with char * parameter. */
        CommandException(
                const string &msg /**< Message. */
                ): runtime_error(msg) {}

        /** Constructor with stringstream parameter. */
        CommandException(
                const stringstream &s /**< Message. */
                ): runtime_error(s.str()) {}
};

/****************************************************************************/

class Command
{
    public:
        Command(const string &, const string &);
        virtual ~Command();

        const string &getName() const;
        const string &getBriefDescription() const;

        typedef list<unsigned int> MasterIndexList;
        void setMasters(const string &);
        MasterIndexList getMasterIndices() const;
		unsigned int getSingleMasterIndex() const;

        enum Verbosity {
            Quiet,
            Normal,
            Verbose
        };
        void setVerbosity(Verbosity);
        Verbosity getVerbosity() const;

        void setAliases(const string &);
        void setPositions(const string &);

        void setDomains(const string &);
        typedef list<unsigned int> DomainIndexList;
        DomainIndexList getDomainIndices() const;

        void setDataType(const string &);
        const string &getDataType() const;

        void setForce(bool);
        bool getForce() const;

        void setOutputFile(const string &);
        const string &getOutputFile() const;

        void setSkin(const string &);
        const string &getSkin() const;

        bool matchesSubstr(const string &) const;
        bool matchesAbbrev(const string &) const;

        virtual string helpString(const string &) const = 0;

        typedef vector<string> StringVector;
        virtual void execute(const StringVector &) = 0;

        static string numericInfo();

    protected:
        enum {BreakAfterBytes = 16};

        void throwInvalidUsageException(const stringstream &) const;
        void throwCommandException(const string &) const;
        void throwCommandException(const stringstream &) const;
        void throwSingleSlaveRequired(unsigned int) const;

        typedef list<ec_ioctl_slave_t> SlaveList;
        SlaveList selectedSlaves(MasterDevice &);
        typedef list<ec_ioctl_config_t> ConfigList;
        ConfigList selectedConfigs(MasterDevice &);
        typedef list<ec_ioctl_domain_t> DomainList;
        DomainList selectedDomains(MasterDevice &, const ec_ioctl_master_t &);

        static string alStateString(uint8_t);

    private:
        string name;
        string briefDesc;
        string masters;
        Verbosity verbosity;
        string aliases;
        string positions;
        string domains;
        string dataType;
        bool force;
        string outputFile;
        string skin;

        Command();
};

/****************************************************************************/

inline const string &Command::getName() const
{
    return name;
}

/****************************************************************************/

inline const string &Command::getBriefDescription() const
{
    return briefDesc;
}

/****************************************************************************/

inline Command::Verbosity Command::getVerbosity() const
{
    return verbosity;
}

/****************************************************************************/

inline const string &Command::getDataType() const
{
    return dataType;
}

/****************************************************************************/

inline bool Command::getForce() const
{
    return force;
}

/****************************************************************************/

inline const string &Command::getOutputFile() const
{
    return outputFile;
}

/****************************************************************************/

inline const string &Command::getSkin() const
{
    return skin;
}

/****************************************************************************/

#endif


<|start_filename|>3rdpart/tslib-1.15/plugins/median.c<|end_filename|>
/*
 *  tslib/plugins/median.c
 *
 *  Copyright (C) 2016 <NAME> <<EMAIL>>
 *  Copyright (C) 2009 <NAME>
 *  Author <NAME>
 *
 * This file is placed under the LGPL.  Please see the file
 * COPYING for more details.
 *
 * SPDX-License-Identifier: LGPL-2.1
 *
 *
 * Median filter incomming data. For some theory, see
 * https://en.wikipedia.org/wiki/Median_filter
 */

#include <errno.h>
#include <stdio.h>
#include <limits.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>

#include "config.h"
#include "tslib.h"
#include "tslib-filter.h"

#define MEDIAN_DEPTH_MAX 128

#define PREPARESAMPLE(array, context, member) { \
	int count = context->size; \
	while (count--) { \
		array[count] = context->delay[count].member; \
	} \
}

#define PREPARESAMPLE_MT(array, context, member, slot) { \
	int count = context->size; \
	while (count--) { \
		array[count] = context->delay_mt[slot][count].member; \
	} \
}

struct median_context {
	struct tslib_module_info	module;
	int				size;
	struct ts_sample		*delay;
	struct ts_sample_mt		**delay_mt;
	int				withsamples;
	int				*withsamples_mt;
	int				slots;
	unsigned int			depth;
	int32_t				*sorted;
	uint32_t			*usorted;
};

static int comp_int(const void *n1, const void *n2)
{
	int *i1 = (int *) n1;
	int *i2 = (int *) n2;

	return  *i1 < *i2 ? -1 : 1;
}

static int comp_uint(const void *n1, const void *n2)
{
	unsigned int *i1 = (unsigned int *) n1;
	unsigned int *i2 = (unsigned int *) n2;

	return  *i1 < *i2 ? -1 : 1;
}

static void printsamples(__attribute__ ((unused)) char *prefix,
			 __attribute__ ((unused)) int *samples,
			 __attribute__ ((unused)) size_t count)
{
#ifdef DEBUG
	size_t j;

	printf("%s Using %d samples ", prefix, (int) count);
	for (j = 0; j < count; j++)
		printf(" %d", samples[j]);

	printf("\n");
#endif
}

static void printsamples_mt(__attribute__ ((unused)) char *prefix,
			    __attribute__ ((unused)) int *samples,
			    __attribute__ ((unused)) size_t count,
			    __attribute__ ((unused)) int slot)
{
#ifdef DEBUG
	size_t j;

	printf("%s (slot %d) Using %d samples ", prefix, slot, (int) count);
	for (j = 0; j < count; j++)
		printf(" %d", samples[j]);

	printf("\n");
#endif
}

static void printsample(__attribute__ ((unused)) char *prefix,
			__attribute__ ((unused)) struct ts_sample *s)
{
#ifdef DEBUG
	printf("%s using Point at (%d,%d) with pressure %u\n",
	       prefix, s->x, s->y, s->pressure);
#endif
}

static void printsample_mt(__attribute__ ((unused)) char *prefix,
			   __attribute__ ((unused)) struct ts_sample_mt *s)
{
#ifdef DEBUG
	printf("%s (slot %d) using Point at (%d,%d) with pressure %u\n",
	       prefix, s->slot, s->x, s->y, s->pressure);
#endif
}

static int median_read(struct tslib_module_info *inf, struct ts_sample *samp,
		       int nr)
{
	struct median_context *c = (struct median_context *)inf;
	int ret;

	ret = inf->next->ops->read(inf->next, samp, nr);
	if (ret > 0) {
		int i;
		struct ts_sample *s;

		for (s = samp, i = 0; i < ret; i++, s++) {
			unsigned int cpress;

			cpress = s->pressure;

			memmove(&c->delay[0],
				&c->delay[1],
				(c->size - 1) * sizeof(c->delay[0]));
			c->delay[c->size - 1] = *s;

			PREPARESAMPLE(c->sorted, c, x);
			printsamples("MEDIAN: X Before", c->sorted, c->size);
			qsort(&c->sorted[0], c->size,
			      sizeof(c->sorted[0]),
			      comp_int);
			s->x = c->sorted[c->size / 2];
			printsamples("MEDIAN: X After ", c->sorted, c->size);

			PREPARESAMPLE(c->sorted, c, y);
			printsamples("MEDIAN: Y Before", c->sorted, c->size);
			qsort(&c->sorted[0], c->size,
			      sizeof(c->sorted[0]),
			      comp_int);
			s->y = c->sorted[c->size / 2];
			printsamples("MEDIAN: Y After ", c->sorted, c->size);

			PREPARESAMPLE(c->usorted, c, pressure);
			printsamples("MEDIAN: Pressure Before",
				     (int *)c->usorted, c->size);
			qsort(&c->usorted[0], c->size,
			      sizeof(c->usorted[0]),
			      comp_uint);
			s->pressure = c->usorted[c->size / 2];
			printsamples("MEDIAN: Pressure After ",
				     (int *)c->usorted, c->size);

			printsample("", s);

			if ((cpress == 0)  && (c->withsamples != 0)) {
				/* We have penup. Flush the line we now must
				 * wait for c->size / 2 samples untill we get
				 * valid data again
				 */
				memset(c->delay,
				       0,
				       sizeof(struct ts_sample) * c->size);
				c->withsamples = 0;
			#ifdef DEBUG
				printf("MEDIAN: Pen Up\n");
			#endif
				s->pressure = cpress;
			} else if ((cpress != 0) && (c->withsamples == 0)) {
				/* We have pen down */
				c->withsamples = 1;
			#ifdef DEBUG
				printf("MEDIAN: Pen Down\n");
			#endif
			}
		}
	}

	return ret;
}

static int median_read_mt(struct tslib_module_info *inf,
			  struct ts_sample_mt **samp, int max_slots, int nr)
{
	struct median_context *c = (struct median_context *)inf;
	int ret;
	int i, j;

	if (!inf->next->ops->read_mt)
		return -ENOSYS;

	ret = inf->next->ops->read_mt(inf->next, samp, max_slots, nr);
	if (ret < 0)
		return ret;

#ifdef DEBUG
	if (ret == 0)
		fprintf(stderr, "MEDIAN: couldn't read data\n");

	printf("MEDIAN:   read %d samples (mem: %d nr x %d slots)\n",
	       ret, nr, max_slots);
#endif

	if (c->delay_mt == NULL || max_slots > c->slots) {
		if (c->delay_mt) {
			for (i = 0; i < c->slots; i++) {
				if (c->delay_mt[i])
					free(c->delay_mt[i]);
			}
			free(c->delay_mt);
		}

		c->delay_mt = malloc(max_slots * sizeof(struct ts_sample_mt *));
		if (!c->delay_mt)
			return -ENOMEM;

		for (i = 0; i < max_slots; i++) {
			c->delay_mt[i] = calloc(c->size,
						sizeof(struct ts_sample_mt));
			if (!c->delay_mt[i]) {
				for (j = 0; j < i; j++) {
					if (c->delay_mt[j])
						free(c->delay_mt[j]);
				}
				if (c->delay_mt)
					free(c->delay_mt);

				return -ENOMEM;
			}
		}

		c->slots = max_slots;
	}

	if (c->withsamples_mt == NULL || max_slots > c->slots) {
		if (c->withsamples_mt)
			free(c->withsamples_mt);

		c->withsamples_mt = calloc(max_slots, sizeof(int));
		if (!c->withsamples_mt)
			return -ENOMEM;
	}

	for (i = 0; i < ret; i++) {
		for (j = 0; j < max_slots; j++) {
			unsigned int cpress = 0;

			if (!(samp[i][j].valid & TSLIB_MT_VALID))
				continue;

			memset(c->sorted, 0, c->size * sizeof(int32_t));
			memset(c->usorted, 0, c->size * sizeof(uint32_t));

			cpress = samp[i][j].pressure;

			memmove(&c->delay_mt[j][0],
				&c->delay_mt[j][1],
				(c->size - 1) * sizeof(c->delay_mt[j][0]));
			c->delay_mt[j][c->size - 1] = samp[i][j];

			PREPARESAMPLE_MT(c->sorted, c, x, j);
			printsamples_mt("MEDIAN: X Before", c->sorted, c->size, j);
			qsort(&c->sorted[0], c->size, sizeof(c->sorted[0]), comp_int);
			samp[i][j].x = c->sorted[c->size / 2];
			printsamples_mt("MEDIAN: X After ", c->sorted, c->size, j);

			PREPARESAMPLE_MT(c->sorted, c, y, j);
			printsamples_mt("MEDIAN: Y Before", c->sorted, c->size, j);
			qsort(&c->sorted[0], c->size, sizeof(c->sorted[0]), comp_int);
			samp[i][j].y = c->sorted[c->size / 2];
			printsamples_mt("MEDIAN: Y After ", c->sorted, c->size, j);

			PREPARESAMPLE_MT(c->usorted, c, pressure, j);
			printsamples_mt("MEDIAN: Pressure Before",
					(int *)c->usorted, c->size, j);
			qsort(&c->usorted[0], c->size, sizeof(c->usorted[0]),
			      comp_uint);
			samp[i][j].pressure = c->usorted[c->size / 2];
			printsamples_mt("MEDIAN: Pressure After ",
					(int *)c->usorted, c->size, j);

			printsample_mt("MEDIAN: ", &samp[i][j]);

			if ((cpress == 0) && (c->withsamples_mt[j] != 0)) {
				/* We have penup. Flush the line we now must
				 * wait for c->size / 2 samples untill we get
				 * valid data again
				 */
				memset(c->delay_mt[j],
				       0,
				       sizeof(struct ts_sample_mt) * c->size);

				c->withsamples_mt[j] = 0;
			#ifdef DEBUG
				printf("MEDIAN: Pen Up\n");
			#endif
				samp[i][j].pressure = cpress;
			} else if ((cpress != 0) &&
				   (c->withsamples_mt[j] == 0)) {
				/* We have pen down */
				c->withsamples_mt[j] = 1;
			#ifdef DEBUG
				printf("MEDIAN: Pen Down\n");
			#endif
			}

			if (cpress != 0 && c->withsamples_mt[j] <= c->size / 2) {
				samp[i][j].valid = 0;
				c->withsamples_mt[j]++;
			}
		}
	}

	return ret;
}

static int median_fini(struct tslib_module_info *inf)
{
	struct median_context *c = (struct median_context *) inf;
	int i;

	free(c->delay);

	for (i = 0; i < c->slots; i++) {
		if (c->delay_mt[i])
			free(c->delay_mt[i]);
	}

	if (c->delay_mt)
		free(c->delay_mt);

	if (c->withsamples_mt)
		free(c->withsamples_mt);

	free(c->sorted);
	free(c->usorted);

	free(inf);

	return 0;
}

static const struct tslib_ops median_ops = {
	.read		= median_read,
	.read_mt	= median_read_mt,
	.fini		= median_fini,
};

static int median_depth(struct tslib_module_info *inf, char *str,
			__attribute__ ((unused)) void *data)
{
	struct median_context *m = (struct median_context *)inf;
	unsigned long v;
	int err = errno;
	unsigned int max = MEDIAN_DEPTH_MAX;

	v = strtoul(str, NULL, 0);

	if (v >= max) {
		fprintf(stderr, "MEDIAN: depth exceeds maximum of %d\n", max);
		return -1;
	}

	errno = err;
	m->delay = malloc(sizeof(struct ts_sample) * v);
	m->size = v;

	m->sorted = calloc(m->size, sizeof(int32_t));
	if (!m->sorted)
		return -1;

	m->usorted = calloc(m->size, sizeof(uint32_t));
	if (!m->usorted)
		return -1;

	return 0;
}

static const struct tslib_vars median_vars[] = {
	{ "depth", (void *)1, median_depth },
};

#define NR_VARS (sizeof(median_vars) / sizeof(median_vars[0]))

TSAPI struct tslib_module_info *median_mod_init(__attribute__ ((unused)) struct tsdev *dev,
						const char *params)
{
	struct median_context *c;

	c = malloc(sizeof(struct median_context));
	if (c == NULL)
		return NULL;

	memset(c, 0, sizeof(struct median_context));
	c->module.ops = &median_ops;

	c->withsamples_mt = NULL;
	c->delay_mt = NULL;
	c->slots = 0;
	c->sorted = NULL;
	c->usorted = NULL;

	if (tslib_parse_vars(&c->module, median_vars, NR_VARS, params)) {
		free(c);
		return NULL;
	}

	if (c->delay == NULL) {
		c->delay = malloc(sizeof(struct ts_sample) * 3);
		c->size = 3;
		printf("Using default size of 3\n");
	}

	return &(c->module);
}

#ifndef TSLIB_STATIC_MEDIAN_MODULE
	TSLIB_MODULE_INIT(median_mod_init);
#endif


<|start_filename|>3rdpart/ethercat-1.5.2/master/fsm_coe.c<|end_filename|>
/******************************************************************************
 *
 *  $Id: fsm_coe.c,v ec403cf308eb 2013/02/12 14:46:43 fp $
 *
 *  Copyright (C) 2006-2008  <NAME>, Ingenieurgemeinschaft IgH
 *
 *  This file is part of the IgH EtherCAT Master.
 *
 *  The IgH EtherCAT Master is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License version 2, as
 *  published by the Free Software Foundation.
 *
 *  The IgH EtherCAT Master is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 *  Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with the IgH EtherCAT Master; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 *****************************************************************************/

/** \file
 * EtherCAT CoE state machines.
 */

/*****************************************************************************/

#include "globals.h"
#include "master.h"
#include "mailbox.h"
#include "fsm_coe.h"
#include "slave_config.h"

/*****************************************************************************/

/** Maximum time in ms to wait for responses when reading out the dictionary.
 */
#define EC_FSM_COE_DICT_TIMEOUT 1000

/** CoE download request header size.
 */
#define EC_COE_DOWN_REQ_HEADER_SIZE 10

/** CoE download segment request header size.
 */
#define EC_COE_DOWN_SEG_REQ_HEADER_SIZE 3

/** Minimum size of download segment.
 */
#define EC_COE_DOWN_SEG_MIN_DATA_SIZE 7

/** Enable debug output for CoE retries.
 */
#define DEBUG_RETRIES 0

/** Enable warning output if transfers take too long.
 */
#define DEBUG_LONG 0

/*****************************************************************************/

void ec_fsm_coe_dict_start(ec_fsm_coe_t *, ec_datagram_t *);
void ec_fsm_coe_dict_request(ec_fsm_coe_t *, ec_datagram_t *);
void ec_fsm_coe_dict_check(ec_fsm_coe_t *, ec_datagram_t *);
void ec_fsm_coe_dict_response(ec_fsm_coe_t *, ec_datagram_t *);
void ec_fsm_coe_dict_desc_request(ec_fsm_coe_t *, ec_datagram_t *);
void ec_fsm_coe_dict_desc_check(ec_fsm_coe_t *, ec_datagram_t *);
void ec_fsm_coe_dict_desc_response(ec_fsm_coe_t *, ec_datagram_t *);
void ec_fsm_coe_dict_entry_request(ec_fsm_coe_t *, ec_datagram_t *);
void ec_fsm_coe_dict_entry_check(ec_fsm_coe_t *, ec_datagram_t *);
void ec_fsm_coe_dict_entry_response(ec_fsm_coe_t *, ec_datagram_t *);

void ec_fsm_coe_down_start(ec_fsm_coe_t *, ec_datagram_t *);
void ec_fsm_coe_down_request(ec_fsm_coe_t *, ec_datagram_t *);
void ec_fsm_coe_down_check(ec_fsm_coe_t *, ec_datagram_t *);
void ec_fsm_coe_down_response(ec_fsm_coe_t *, ec_datagram_t *);
void ec_fsm_coe_down_seg_check(ec_fsm_coe_t *, ec_datagram_t *);
void ec_fsm_coe_down_seg_response(ec_fsm_coe_t *, ec_datagram_t *);

void ec_fsm_coe_up_start(ec_fsm_coe_t *, ec_datagram_t *);
void ec_fsm_coe_up_request(ec_fsm_coe_t *, ec_datagram_t *);
void ec_fsm_coe_up_check(ec_fsm_coe_t *, ec_datagram_t *);
void ec_fsm_coe_up_response(ec_fsm_coe_t *, ec_datagram_t *);
void ec_fsm_coe_up_seg_request(ec_fsm_coe_t *, ec_datagram_t *);
void ec_fsm_coe_up_seg_check(ec_fsm_coe_t *, ec_datagram_t *);
void ec_fsm_coe_up_seg_response(ec_fsm_coe_t *, ec_datagram_t *);

void ec_fsm_coe_end(ec_fsm_coe_t *, ec_datagram_t *);
void ec_fsm_coe_error(ec_fsm_coe_t *, ec_datagram_t *);

/*****************************************************************************/

/** SDO abort messages.
 *
 * The "abort SDO transfer request" supplies an abort code, which can be
 * translated to clear text. This table does the mapping of the codes and
 * messages.
 */
const ec_code_msg_t sdo_abort_messages[] = {
    {0x05030000, "Toggle bit not changed"},
    {0x05040000, "SDO protocol timeout"},
    {0x05040001, "Client/Server command specifier not valid or unknown"},
    {0x05040005, "Out of memory"},
    {0x06010000, "Unsupported access to an object"},
    {0x06010001, "Attempt to read a write-only object"},
    {0x06010002, "Attempt to write a read-only object"},
    {0x06020000, "This object does not exist in the object directory"},
    {0x06040041, "The object cannot be mapped into the PDO"},
    {0x06040042, "The number and length of the objects to be mapped would"
     " exceed the PDO length"},
    {0x06040043, "General parameter incompatibility reason"},
    {0x06040047, "Gerneral internal incompatibility in device"},
    {0x06060000, "Access failure due to a hardware error"},
    {0x06070010, "Data type does not match, length of service parameter does"
     " not match"},
    {0x06070012, "Data type does not match, length of service parameter too"
     " high"},
    {0x06070013, "Data type does not match, length of service parameter too"
     " low"},
    {0x06090011, "Subindex does not exist"},
    {0x06090030, "Value range of parameter exceeded"},
    {0x06090031, "Value of parameter written too high"},
    {0x06090032, "Value of parameter written too low"},
    {0x06090036, "Maximum value is less than minimum value"},
    {0x08000000, "General error"},
    {0x08000020, "Data cannot be transferred or stored to the application"},
    {0x08000021, "Data cannot be transferred or stored to the application"
     " because of local control"},
    {0x08000022, "Data cannot be transferred or stored to the application"
     " because of the present device state"},
    {0x08000023, "Object dictionary dynamic generation fails or no object"
     " dictionary is present"},
    {}
};

/*****************************************************************************/

/** Outputs an SDO abort message.
 */
void ec_canopen_abort_msg(
        const ec_slave_t *slave, /**< Slave. */
        uint32_t abort_code /**< Abort code to search for. */
        )
{
    const ec_code_msg_t *abort_msg;

    for (abort_msg = sdo_abort_messages; abort_msg->code; abort_msg++) {
        if (abort_msg->code == abort_code) {
            EC_SLAVE_ERR(slave, "SDO abort message 0x%08X: \"%s\".\n",
                   abort_msg->code, abort_msg->message);
            return;
        }
    }

    EC_SLAVE_ERR(slave, "Unknown SDO abort code 0x%08X.\n", abort_code);
}

/*****************************************************************************/

/** Constructor.
 */
void ec_fsm_coe_init(
        ec_fsm_coe_t *fsm /**< Finite state machine */
        )
{
    fsm->state = NULL;
    fsm->datagram = NULL;
}

/*****************************************************************************/

/** Destructor.
 */
void ec_fsm_coe_clear(
        ec_fsm_coe_t *fsm /**< Finite state machine */
        )
{
}

/*****************************************************************************/

/** Starts reading a slaves' SDO dictionary.
 */
void ec_fsm_coe_dictionary(
        ec_fsm_coe_t *fsm, /**< Finite state machine */
        ec_slave_t *slave /**< EtherCAT slave */
        )
{
    fsm->slave = slave;
    fsm->state = ec_fsm_coe_dict_start;
}

/*****************************************************************************/

/** Starts to transfer an SDO to/from a slave.
 */
void ec_fsm_coe_transfer(
        ec_fsm_coe_t *fsm, /**< State machine. */
        ec_slave_t *slave, /**< EtherCAT slave. */
        ec_sdo_request_t *request /**< SDO request. */
        )
{
    fsm->slave = slave;
    fsm->request = request;

    if (request->dir == EC_DIR_OUTPUT) {
        fsm->state = ec_fsm_coe_down_start;
    }
    else {
        fsm->state = ec_fsm_coe_up_start;
    }
}

/*****************************************************************************/

/** Executes the current state of the state machine.
 *
 * \return 1 if the datagram was used, else 0.
 */
int ec_fsm_coe_exec(
        ec_fsm_coe_t *fsm, /**< Finite state machine. */
        ec_datagram_t *datagram /**< Datagram to use. */
        )
{
    int datagram_used = 0;

    if (fsm->datagram &&
            (fsm->datagram->state == EC_DATAGRAM_INIT ||
             fsm->datagram->state == EC_DATAGRAM_QUEUED ||
             fsm->datagram->state == EC_DATAGRAM_SENT)) {
        // datagram not received yet
        return datagram_used;
    }

    fsm->state(fsm, datagram);

    datagram_used =
        fsm->state != ec_fsm_coe_end && fsm->state != ec_fsm_coe_error;

    if (datagram_used) {
        fsm->datagram = datagram;
    } else {
        fsm->datagram = NULL;
    }

    return datagram_used;
}

/*****************************************************************************/

/** Returns, if the state machine terminated with success.
 * \return non-zero if successful.
 */
int ec_fsm_coe_success(
        const ec_fsm_coe_t *fsm /**< Finite state machine */
        )
{
    return fsm->state == ec_fsm_coe_end;
}

/*****************************************************************************/

/** Check if the received data are a CoE emergency request.
 *
 * If the check is positive, the emergency request is output.
 *
 * \return The data were an emergency request.
 */
int ec_fsm_coe_check_emergency(
        ec_fsm_coe_t *fsm, /**< Finite state machine */
        const uint8_t *data, /**< CoE mailbox data. */
        size_t size /**< CoE mailbox data size. */
        )
{
    if (size < 2 || ((EC_READ_U16(data) >> 12) & 0x0F) != 0x01)
        return 0;

    if (size < 10) {
        EC_SLAVE_WARN(fsm->slave, "Received incomplete CoE Emergency"
                " request:\n");
        ec_print_data(data, size);
        return 1;
    }

    {
        ec_slave_config_t *sc = fsm->slave->config;
        if (sc) {
            ec_coe_emerg_ring_push(&sc->emerg_ring, data + 2);
        }
    }

    EC_SLAVE_WARN(fsm->slave, "CoE Emergency Request received:\n"
            "Error code 0x%04X, Error register 0x%02X, data:\n",
            EC_READ_U16(data + 2), EC_READ_U8(data + 4));
    ec_print_data(data + 5, 5);
    return 1;
}

/******************************************************************************
 *  CoE dictionary state machine
 *****************************************************************************/

/** Prepare a dictionary request.
 *
 * \return Zero on success, otherwise a negative error code.
 */
int ec_fsm_coe_prepare_dict(
        ec_fsm_coe_t *fsm, /**< Finite state machine. */
        ec_datagram_t *datagram /**< Datagram to use. */
        )
{
    ec_slave_t *slave = fsm->slave;
    uint8_t *data = ec_slave_mbox_prepare_send(slave, datagram, 0x03, 8);
    if (IS_ERR(data)) {
        return PTR_ERR(data);
    }

    EC_WRITE_U16(data, 0x8 << 12); // SDO information
    EC_WRITE_U8 (data + 2, 0x01); // Get OD List Request
    EC_WRITE_U8 (data + 3, 0x00);
    EC_WRITE_U16(data + 4, 0x0000);
    EC_WRITE_U16(data + 6, 0x0001); // deliver all SDOs!

    fsm->state = ec_fsm_coe_dict_request;
    return 0;
}

/*****************************************************************************/

/** CoE state: DICT START.
 */
void ec_fsm_coe_dict_start(
        ec_fsm_coe_t *fsm, /**< Finite state machine. */
        ec_datagram_t *datagram /**< Datagram to use. */
        )
{
    ec_slave_t *slave = fsm->slave;

    if (!(slave->sii.mailbox_protocols & EC_MBOX_COE)) {
        EC_SLAVE_ERR(slave, "Slave does not support CoE!\n");
        fsm->state = ec_fsm_coe_error;
        return;
    }

    if (slave->sii.has_general && !slave->sii.coe_details.enable_sdo_info) {
        EC_SLAVE_ERR(slave, "Slave does not support"
                " SDO information service!\n");
        fsm->state = ec_fsm_coe_error;
        return;
    }

    fsm->retries = EC_FSM_RETRIES;

    if (ec_fsm_coe_prepare_dict(fsm, datagram)) {
        fsm->state = ec_fsm_coe_error;
    }
}

/*****************************************************************************/

/** CoE state: DICT REQUEST.
 * \todo Timeout behavior
 */
void ec_fsm_coe_dict_request(
        ec_fsm_coe_t *fsm, /**< Finite state machine. */
        ec_datagram_t *datagram /**< Datagram to use. */
        )
{
    ec_slave_t *slave = fsm->slave;

    if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
        if (ec_fsm_coe_prepare_dict(fsm, datagram)) {
            fsm->state = ec_fsm_coe_error;
        }
        return;
    }

    if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
        fsm->state = ec_fsm_coe_error;
        EC_SLAVE_ERR(slave, "Failed to receive CoE dictionary"
                " request datagram: ");
        ec_datagram_print_state(fsm->datagram);
        return;
    }

    if (fsm->datagram->working_counter != 1) {
        fsm->state = ec_fsm_coe_error;
        EC_SLAVE_ERR(slave, "Reception of CoE dictionary request failed: ");
        ec_datagram_print_wc_error(fsm->datagram);
        return;
    }

    fsm->jiffies_start = fsm->datagram->jiffies_sent;

    ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
    fsm->retries = EC_FSM_RETRIES;
    fsm->state = ec_fsm_coe_dict_check;
}

/*****************************************************************************/

/** CoE state: DICT CHECK.
 */
void ec_fsm_coe_dict_check(
        ec_fsm_coe_t *fsm, /**< Finite state machine. */
        ec_datagram_t *datagram /**< Datagram to use. */
        )
{
    ec_slave_t *slave = fsm->slave;

    if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
        ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
        return;
    }

    if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
        fsm->state = ec_fsm_coe_error;
        EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check datagram: ");
        ec_datagram_print_state(fsm->datagram);
        return;
    }

    if (fsm->datagram->working_counter != 1) {
        fsm->state = ec_fsm_coe_error;
        EC_SLAVE_ERR(slave,"Reception of CoE mailbox check"
                " datagram failed: ");
        ec_datagram_print_wc_error(fsm->datagram);
        return;
    }

    if (!ec_slave_mbox_check(fsm->datagram)) {
        unsigned long diff_ms =
            (fsm->datagram->jiffies_received - fsm->jiffies_start) *
            1000 / HZ;
        if (diff_ms >= EC_FSM_COE_DICT_TIMEOUT) {
            fsm->state = ec_fsm_coe_error;
            EC_SLAVE_ERR(slave, "Timeout while waiting for"
                    " SDO dictionary list response.\n");
            return;
        }

        ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
        fsm->retries = EC_FSM_RETRIES;
        return;
    }

    // Fetch response
    ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
    fsm->retries = EC_FSM_RETRIES;
    fsm->state = ec_fsm_coe_dict_response;
}

/*****************************************************************************/

/** Prepare an object description request.
 *
 * \return Zero on success, otherwise a negative error code.
 */
int ec_fsm_coe_dict_prepare_desc(
        ec_fsm_coe_t *fsm, /**< Finite state machine. */
        ec_datagram_t *datagram /**< Datagram to use. */
        )
{
    ec_slave_t *slave = fsm->slave;
    u8 *data = ec_slave_mbox_prepare_send(slave, datagram, 0x03, 8);
    if (IS_ERR(data)) {
        return PTR_ERR(data);
    }

    EC_WRITE_U16(data, 0x8 << 12); // SDO information
    EC_WRITE_U8 (data + 2, 0x03); // Get object description request
    EC_WRITE_U8 (data + 3, 0x00);
    EC_WRITE_U16(data + 4, 0x0000);
    EC_WRITE_U16(data + 6, fsm->sdo->index); // SDO index

    fsm->state = ec_fsm_coe_dict_desc_request;
    return 0;
}

/*****************************************************************************/

/**
   CoE state: DICT RESPONSE.
   \todo Timeout behavior
*/

void ec_fsm_coe_dict_response(
        ec_fsm_coe_t *fsm, /**< Finite state machine. */
        ec_datagram_t *datagram /**< Datagram to use. */
        )
{
    ec_slave_t *slave = fsm->slave;
    uint8_t *data, mbox_prot;
    size_t rec_size;
    unsigned int sdo_count, i;
    uint16_t sdo_index, fragments_left;
    ec_sdo_t *sdo;
    bool first_segment;
    size_t index_list_offset;

    if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
        ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
        return;
    }

    if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
        fsm->state = ec_fsm_coe_error;
        EC_SLAVE_ERR(slave, "Failed to receive CoE dictionary"
                " response datagram: ");
        ec_datagram_print_state(fsm->datagram);
        return;
    }

    if (fsm->datagram->working_counter != 1) {
        fsm->state = ec_fsm_coe_error;
        EC_SLAVE_ERR(slave, "Reception of CoE dictionary response failed: ");
        ec_datagram_print_wc_error(fsm->datagram);
        return;
    }

    data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
    if (IS_ERR(data)) {
        fsm->state = ec_fsm_coe_error;
        return;
    }

    if (mbox_prot != 0x03) { // CoE
        EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
                mbox_prot);
        fsm->state = ec_fsm_coe_error;
        return;
    }

    if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
        // check for CoE response again
        ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
        fsm->retries = EC_FSM_RETRIES;
        fsm->state = ec_fsm_coe_dict_check;
        return;
    }

    if (rec_size < 3) {
        EC_SLAVE_ERR(slave, "Received corrupted SDO dictionary response"
                " (size %zu).\n", rec_size);
        fsm->state = ec_fsm_coe_error;
        return;
    }

    if (EC_READ_U16(data) >> 12 == 0x8 && // SDO information
        (EC_READ_U8(data + 2) & 0x7F) == 0x07) { // error response
        EC_SLAVE_ERR(slave, "SDO information error response!\n");
        if (rec_size < 10) {
            EC_SLAVE_ERR(slave, "Incomplete SDO information"
                    " error response:\n");
            ec_print_data(data, rec_size);
        } else {
            ec_canopen_abort_msg(slave, EC_READ_U32(data + 6));
        }
        fsm->state = ec_fsm_coe_error;
        return;
    }

    if (EC_READ_U16(data) >> 12 != 0x8 || // SDO information
        (EC_READ_U8 (data + 2) & 0x7F) != 0x02) { // Get OD List response
        if (fsm->slave->master->debug_level) {
            EC_SLAVE_DBG(slave, 1, "Invalid SDO list response!"
                    " Retrying...\n");
            ec_print_data(data, rec_size);
        }
        ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
        fsm->retries = EC_FSM_RETRIES;
        fsm->state = ec_fsm_coe_dict_check;
        return;
    }

    first_segment = list_empty(&slave->sdo_dictionary) ? true : false;
    index_list_offset = first_segment ? 8 : 6;

    if (rec_size < index_list_offset || rec_size % 2) {
        EC_SLAVE_ERR(slave, "Invalid data size %zu!\n", rec_size);
        ec_print_data(data, rec_size);
        fsm->state = ec_fsm_coe_error;
        return;
    }

    sdo_count = (rec_size - index_list_offset) / 2;

    for (i = 0; i < sdo_count; i++) {
        sdo_index = EC_READ_U16(data + index_list_offset + i * 2);
        if (!sdo_index) {
            EC_SLAVE_DBG(slave, 1, "SDO dictionary contains index 0x0000.\n");
            continue;
        }

        if (!(sdo = (ec_sdo_t *) kmalloc(sizeof(ec_sdo_t), GFP_KERNEL))) {
            EC_SLAVE_ERR(slave, "Failed to allocate memory for SDO!\n");
            fsm->state = ec_fsm_coe_error;
            return;
        }

        ec_sdo_init(sdo, slave, sdo_index);
        list_add_tail(&sdo->list, &slave->sdo_dictionary);
    }

    fragments_left = EC_READ_U16(data + 4);
    if (fragments_left) {
        EC_SLAVE_DBG(slave, 1, "SDO list fragments left: %u\n",
                fragments_left);
    }

    if (EC_READ_U8(data + 2) & 0x80 || fragments_left) {
        // more messages waiting. check again.
        fsm->jiffies_start = fsm->datagram->jiffies_sent;
        ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
        fsm->retries = EC_FSM_RETRIES;
        fsm->state = ec_fsm_coe_dict_check;
        return;
    }

    if (list_empty(&slave->sdo_dictionary)) {
        // no SDOs in dictionary. finished.
        fsm->state = ec_fsm_coe_end; // success
        return;
    }

    // fetch SDO descriptions
    fsm->sdo = list_entry(slave->sdo_dictionary.next, ec_sdo_t, list);

    fsm->retries = EC_FSM_RETRIES;
    if (ec_fsm_coe_dict_prepare_desc(fsm, datagram)) {
        fsm->state = ec_fsm_coe_error;
    }
}

/*****************************************************************************/

/**
   CoE state: DICT DESC REQUEST.
   \todo Timeout behavior
*/

void ec_fsm_coe_dict_desc_request(
        ec_fsm_coe_t *fsm, /**< Finite state machine. */
        ec_datagram_t *datagram /**< Datagram to use. */
        )
{
    ec_slave_t *slave = fsm->slave;

    if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
        if (ec_fsm_coe_dict_prepare_desc(fsm, datagram)) {
            fsm->state = ec_fsm_coe_error;
        }
        return;
    }

    if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
        fsm->state = ec_fsm_coe_error;
        EC_SLAVE_ERR(slave, "Failed to receive CoE SDO"
                " description request datagram: ");
        ec_datagram_print_state(fsm->datagram);
        return;
    }

    if (fsm->datagram->working_counter != 1) {
        fsm->state = ec_fsm_coe_error;
        EC_SLAVE_ERR(slave, "Reception of CoE SDO description"
                " request failed: ");
        ec_datagram_print_wc_error(fsm->datagram);
        return;
    }

    fsm->jiffies_start = fsm->datagram->jiffies_sent;

    ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
    fsm->retries = EC_FSM_RETRIES;
    fsm->state = ec_fsm_coe_dict_desc_check;
}

/*****************************************************************************/

/**
   CoE state: DICT DESC CHECK.
*/

void ec_fsm_coe_dict_desc_check(
        ec_fsm_coe_t *fsm, /**< Finite state machine. */
        ec_datagram_t *datagram /**< Datagram to use. */
        )
{
    ec_slave_t *slave = fsm->slave;

    if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
        ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
        return;
    }

    if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
        fsm->state = ec_fsm_coe_error;
        EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check datagram: ");
        ec_datagram_print_state(fsm->datagram);
        return;
    }

    if (fsm->datagram->working_counter != 1) {
        fsm->state = ec_fsm_coe_error;
        EC_SLAVE_ERR(slave, "Reception of CoE mailbox check"
                " datagram failed: ");
        ec_datagram_print_wc_error(fsm->datagram);
        return;
    }

    if (!ec_slave_mbox_check(fsm->datagram)) {
        unsigned long diff_ms =
            (fsm->datagram->jiffies_received - fsm->jiffies_start) *
            1000 / HZ;
        if (diff_ms >= EC_FSM_COE_DICT_TIMEOUT) {
            fsm->state = ec_fsm_coe_error;
            EC_SLAVE_ERR(slave, "Timeout while waiting for"
                    " SDO 0x%04x object description response.\n",
                    fsm->sdo->index);
            return;
        }

        ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
        fsm->retries = EC_FSM_RETRIES;
        return;
    }

    // Fetch response
    ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
    fsm->retries = EC_FSM_RETRIES;
    fsm->state = ec_fsm_coe_dict_desc_response;
}

/*****************************************************************************/

/** Prepare an entry description request.
 *
 * \return Zero on success, otherwise a negative error code.
 */
int ec_fsm_coe_dict_prepare_entry(
        ec_fsm_coe_t *fsm, /**< Finite state machine */
        ec_datagram_t *datagram /**< Datagram to use. */
        )
{
    ec_slave_t *slave = fsm->slave;
    u8 *data = ec_slave_mbox_prepare_send(slave, datagram, 0x03, 10);
    if (IS_ERR(data)) {
        return PTR_ERR(data);
    }

    EC_WRITE_U16(data, 0x8 << 12); // SDO information
    EC_WRITE_U8 (data + 2, 0x05); // Get entry description request
    EC_WRITE_U8 (data + 3, 0x00);
    EC_WRITE_U16(data + 4, 0x0000);
    EC_WRITE_U16(data + 6, fsm->sdo->index); // SDO index
    EC_WRITE_U8 (data + 8, fsm->subindex); // SDO subindex
    EC_WRITE_U8 (data + 9, 0x01); // value info (access rights only)

    fsm->state = ec_fsm_coe_dict_entry_request;
    return 0;
}

/*****************************************************************************/

/**
   CoE state: DICT DESC RESPONSE.
   \todo Timeout behavior
*/

void ec_fsm_coe_dict_desc_response(
        ec_fsm_coe_t *fsm, /**< Finite state machine */
        ec_datagram_t *datagram /**< Datagram to use. */
        )
{
    ec_slave_t *slave = fsm->slave;
    ec_sdo_t *sdo = fsm->sdo;
    uint8_t *data, mbox_prot;
    size_t rec_size, name_size;

    if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
        ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
        return;
    }

    if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
        fsm->state = ec_fsm_coe_error;
        EC_SLAVE_ERR(slave, "Failed to receive CoE SDO description"
                " response datagram: ");
        ec_datagram_print_state(fsm->datagram);
        return;
    }

    if (fsm->datagram->working_counter != 1) {
        fsm->state = ec_fsm_coe_error;
        EC_SLAVE_ERR(slave, "Reception of CoE SDO description"
                " response failed: ");
        ec_datagram_print_wc_error(fsm->datagram);
        return;
    }

    data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
    if (IS_ERR(data)) {
        fsm->state = ec_fsm_coe_error;
        return;
    }

    if (mbox_prot != 0x03) { // CoE
        EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
                mbox_prot);
        fsm->state = ec_fsm_coe_error;
        return;
    }

    if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
        // check for CoE response again
        ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
        fsm->retries = EC_FSM_RETRIES;
        fsm->state = ec_fsm_coe_dict_desc_check;
        return;
    }

    if (rec_size < 3) {
        EC_SLAVE_ERR(slave, "Received corrupted SDO description response"
                " (size %zu).\n", rec_size);
        fsm->state = ec_fsm_coe_error;
        return;
    }

    if (EC_READ_U16(data) >> 12 == 0x8 && // SDO information
        (EC_READ_U8 (data + 2) & 0x7F) == 0x07) { // error response
        EC_SLAVE_ERR(slave, "SDO information error response while"
                " fetching SDO 0x%04X!\n", sdo->index);
        ec_canopen_abort_msg(slave, EC_READ_U32(data + 6));
        fsm->state = ec_fsm_coe_error;
        return;
    }

    if (rec_size < 8) {
        EC_SLAVE_ERR(slave, "Received corrupted SDO"
                " description response (size %zu).\n", rec_size);
        fsm->state = ec_fsm_coe_error;
        return;
    }

    if (EC_READ_U16(data) >> 12 != 0x8 || // SDO information
        (EC_READ_U8 (data + 2) & 0x7F) != 0x04 || // Object desc. response
        EC_READ_U16(data + 6) != sdo->index) { // SDO index
        if (fsm->slave->master->debug_level) {
            EC_SLAVE_DBG(slave, 1, "Invalid object description response while"
                    " fetching SDO 0x%04X!\n", sdo->index);
            ec_print_data(data, rec_size);
        }
        // check for CoE response again
        ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
        fsm->retries = EC_FSM_RETRIES;
        fsm->state = ec_fsm_coe_dict_desc_check;
        return;
    }

    if (rec_size < 12) {
        EC_SLAVE_ERR(slave, "Invalid data size!\n");
        ec_print_data(data, rec_size);
        fsm->state = ec_fsm_coe_error;
        return;
    }

    sdo->max_subindex = EC_READ_U8(data + 10);
    sdo->object_code = EC_READ_U8(data + 11);

    name_size = rec_size - 12;
    if (name_size) {
        if (!(sdo->name = kmalloc(name_size + 1, GFP_KERNEL))) {
            EC_SLAVE_ERR(slave, "Failed to allocate SDO name!\n");
            fsm->state = ec_fsm_coe_error;
            return;
        }

        memcpy(sdo->name, data + 12, name_size);
        sdo->name[name_size] = 0;
    }

    if (EC_READ_U8(data + 2) & 0x80) {
        EC_SLAVE_ERR(slave, "Fragment follows (not implemented)!\n");
        fsm->state = ec_fsm_coe_error;
        return;
    }

    // start fetching entries

    fsm->subindex = 0;
    fsm->retries = EC_FSM_RETRIES;

    if (ec_fsm_coe_dict_prepare_entry(fsm, datagram)) {
        fsm->state = ec_fsm_coe_error;
    }
}

/*****************************************************************************/

/**
   CoE state: DICT ENTRY REQUEST.
   \todo Timeout behavior
*/

void ec_fsm_coe_dict_entry_request(
        ec_fsm_coe_t *fsm, /**< Finite state machine. */
        ec_datagram_t *datagram /**< Datagram to use. */
        )
{
    ec_slave_t *slave = fsm->slave;

    if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
        if (ec_fsm_coe_dict_prepare_entry(fsm, datagram)) {
            fsm->state = ec_fsm_coe_error;
        }
        return;
    }

    if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
        fsm->state = ec_fsm_coe_error;
        EC_SLAVE_ERR(slave, "Failed to receive CoE SDO entry"
                " request datagram: ");
        ec_datagram_print_state(fsm->datagram);
        return;
    }

    if (fsm->datagram->working_counter != 1) {
        fsm->state = ec_fsm_coe_error;
        EC_SLAVE_ERR(slave, "Reception of CoE SDO entry request failed: ");
        ec_datagram_print_wc_error(fsm->datagram);
        return;
    }

    fsm->jiffies_start = fsm->datagram->jiffies_sent;

    ec_slave_mbox_prepare_check(slave, datagram); // can not fail
    fsm->retries = EC_FSM_RETRIES;
    fsm->state = ec_fsm_coe_dict_entry_check;
}

/*****************************************************************************/

/**
   CoE state: DICT ENTRY CHECK.
*/

void ec_fsm_coe_dict_entry_check(
        ec_fsm_coe_t *fsm, /**< Finite state machine. */
        ec_datagram_t *datagram /**< Datagram to use. */
        )
{
    ec_slave_t *slave = fsm->slave;

    if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
        ec_slave_mbox_prepare_check(slave, datagram); // can not fail
        return;
    }

    if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
        fsm->state = ec_fsm_coe_error;
        EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check datagram: ");
        ec_datagram_print_state(fsm->datagram);
        return;
    }

    if (fsm->datagram->working_counter != 1) {
        fsm->state = ec_fsm_coe_error;
        EC_SLAVE_ERR(slave, "Reception of CoE mailbox check"
                " datagram failed: ");
        ec_datagram_print_wc_error(fsm->datagram);
        return;
    }

    if (!ec_slave_mbox_check(fsm->datagram)) {
        unsigned long diff_ms =
            (fsm->datagram->jiffies_received - fsm->jiffies_start) *
            1000 / HZ;
        if (diff_ms >= EC_FSM_COE_DICT_TIMEOUT) {
            fsm->state = ec_fsm_coe_error;
            EC_SLAVE_ERR(slave, "Timeout while waiting for"
                    " SDO entry 0x%04x:%x description response.\n",
                    fsm->sdo->index, fsm->subindex);
            return;
        }

        ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
        fsm->retries = EC_FSM_RETRIES;
        return;
    }

    // Fetch response
    ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
    fsm->retries = EC_FSM_RETRIES;
    fsm->state = ec_fsm_coe_dict_entry_response;
}

/*****************************************************************************/

/**
   CoE state: DICT ENTRY RESPONSE.
   \todo Timeout behavior
*/

void ec_fsm_coe_dict_entry_response(
        ec_fsm_coe_t *fsm, /**< Finite state machine. */
        ec_datagram_t *datagram /**< Datagram to use. */
        )
{
    ec_slave_t *slave = fsm->slave;
    ec_sdo_t *sdo = fsm->sdo;
    uint8_t *data, mbox_prot;
    size_t rec_size, data_size;
    ec_sdo_entry_t *entry;
    u16 word;

    if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
        ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
        return;
    }

    if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
        fsm->state = ec_fsm_coe_error;
        EC_SLAVE_ERR(slave, "Failed to receive CoE SDO"
                " description response datagram: ");
        ec_datagram_print_state(fsm->datagram);
        return;
    }

    if (fsm->datagram->working_counter != 1) {
        fsm->state = ec_fsm_coe_error;
        EC_SLAVE_ERR(slave, "Reception of CoE SDO description"
                " response failed: ");
        ec_datagram_print_wc_error(fsm->datagram);
        return;
    }

    data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
    if (IS_ERR(data)) {
        fsm->state = ec_fsm_coe_error;
        return;
    }

    if (mbox_prot != 0x03) { // CoE
        EC_SLAVE_ERR(slave, "Received mailbox protocol"
                " 0x%02X as response.\n", mbox_prot);
        fsm->state = ec_fsm_coe_error;
        return;
    }

    if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
        // check for CoE response again
        ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
        fsm->retries = EC_FSM_RETRIES;
        fsm->state = ec_fsm_coe_dict_entry_check;
        return;
    }

    if (rec_size < 3) {
        EC_SLAVE_ERR(slave, "Received corrupted SDO entry"
                " description response (size %zu).\n", rec_size);
        fsm->state = ec_fsm_coe_error;
        return;
    }

    if (EC_READ_U16(data) >> 12 == 0x8 && // SDO information
        (EC_READ_U8 (data + 2) & 0x7F) == 0x07) { // error response
        EC_SLAVE_WARN(slave, "SDO information error response while"
               " fetching SDO entry 0x%04X:%02X!\n",
               sdo->index, fsm->subindex);
        ec_canopen_abort_msg(slave, EC_READ_U32(data + 6));

        /* There may be gaps in the subindices, so try to continue with next
         * subindex. */

    } else {

        if (rec_size < 9) {
            EC_SLAVE_ERR(slave, "Received corrupted SDO entry"
                    " description response (size %zu).\n", rec_size);
            fsm->state = ec_fsm_coe_error;
            return;
        }

        if (EC_READ_U16(data) >> 12 != 0x8 || // SDO information
            (EC_READ_U8(data + 2) & 0x7F) != 0x06 || // Entry desc. response
            EC_READ_U16(data + 6) != sdo->index || // SDO index
            EC_READ_U8(data + 8) != fsm->subindex) { // SDO subindex
            if (fsm->slave->master->debug_level) {
                EC_SLAVE_DBG(slave, 1, "Invalid entry description response"
                        " while fetching SDO entry 0x%04X:%02X!\n",
                        sdo->index, fsm->subindex);
                ec_print_data(data, rec_size);
            }
            // check for CoE response again
            ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
            fsm->retries = EC_FSM_RETRIES;
            fsm->state = ec_fsm_coe_dict_entry_check;
            return;
        }

        if (rec_size < 16) {
            EC_SLAVE_ERR(slave, "Invalid data size %zu!\n", rec_size);
            ec_print_data(data, rec_size);
            fsm->state = ec_fsm_coe_error;
            return;
        }

        data_size = rec_size - 16;

        if (!(entry = (ec_sdo_entry_t *)
              kmalloc(sizeof(ec_sdo_entry_t), GFP_KERNEL))) {
            EC_SLAVE_ERR(slave, "Failed to allocate entry!\n");
            fsm->state = ec_fsm_coe_error;
            return;
        }

        ec_sdo_entry_init(entry, sdo, fsm->subindex);
        entry->data_type = EC_READ_U16(data + 10);
        entry->bit_length = EC_READ_U16(data + 12);

        // read access rights
        word = EC_READ_U16(data + 14);
        entry->read_access[EC_SDO_ENTRY_ACCESS_PREOP] = word & 0x0001;
        entry->read_access[EC_SDO_ENTRY_ACCESS_SAFEOP] =
            (word >> 1)  & 0x0001;
        entry->read_access[EC_SDO_ENTRY_ACCESS_OP] = (word >> 2)  & 0x0001;
        entry->write_access[EC_SDO_ENTRY_ACCESS_PREOP] = (word >> 3) & 0x0001;
        entry->write_access[EC_SDO_ENTRY_ACCESS_SAFEOP] =
            (word >> 4)  & 0x0001;
        entry->write_access[EC_SDO_ENTRY_ACCESS_OP] = (word >> 5)  & 0x0001;

        if (data_size) {
            uint8_t *desc;
            if (!(desc = kmalloc(data_size + 1, GFP_KERNEL))) {
                EC_SLAVE_ERR(slave, "Failed to allocate SDO entry name!\n");
                fsm->state = ec_fsm_coe_error;
                return;
            }
            memcpy(desc, data + 16, data_size);
            desc[data_size] = 0;
            entry->description = desc;
        }

        list_add_tail(&entry->list, &sdo->entries);
    }

    if (fsm->subindex < sdo->max_subindex) {

        fsm->subindex++;
        fsm->retries = EC_FSM_RETRIES;

        if (ec_fsm_coe_dict_prepare_entry(fsm, datagram)) {
            fsm->state = ec_fsm_coe_error;
        }

        return;
    }

    // another SDO description to fetch?
    if (fsm->sdo->list.next != &slave->sdo_dictionary) {

        fsm->sdo = list_entry(fsm->sdo->list.next, ec_sdo_t, list);
        fsm->retries = EC_FSM_RETRIES;

        if (ec_fsm_coe_dict_prepare_desc(fsm, datagram)) {
            fsm->state = ec_fsm_coe_error;
        }

        return;
    }

    fsm->state = ec_fsm_coe_end;
}

/******************************************************************************
 *  CoE state machine
 *****************************************************************************/

/** Prepare a donwnload request.
 *
 * \return Zero on success, otherwise a negative error code.
 */
int ec_fsm_coe_prepare_down_start(
        ec_fsm_coe_t *fsm, /**< Finite state machine. */
        ec_datagram_t *datagram /**< Datagram to use. */
        )
{
    u8 *data;
    ec_slave_t *slave = fsm->slave;
    ec_sdo_request_t *request = fsm->request;
    uint8_t data_set_size;

    if (request->data_size <= 4) { // use expedited transfer type
        data = ec_slave_mbox_prepare_send(slave, datagram, 0x03,
                EC_COE_DOWN_REQ_HEADER_SIZE);
        if (IS_ERR(data)) {
            request->errno = PTR_ERR(data);
            return PTR_ERR(data);
        }

        fsm->remaining = 0;

        data_set_size = 4 - request->data_size;

        EC_WRITE_U16(data, 0x2 << 12); // SDO request
        EC_WRITE_U8 (data + 2, (0x3 // size specified, expedited
                    | data_set_size << 2
                    | ((request->complete_access ? 1 : 0) << 4)
                    | 0x1 << 5)); // Download request
        EC_WRITE_U16(data + 3, request->index);
        EC_WRITE_U8 (data + 5,
                request->complete_access ? 0x00 : request->subindex);
        memcpy(data + 6, request->data, request->data_size);
        memset(data + 6 + request->data_size, 0x00, 4 - request->data_size);

        if (slave->master->debug_level) {
            EC_SLAVE_DBG(slave, 1, "Expedited download request:\n");
            ec_print_data(data, EC_COE_DOWN_REQ_HEADER_SIZE);
        }
    }
    else { // request->data_size > 4, use normal transfer type
        size_t data_size,
               max_data_size =
                   slave->configured_rx_mailbox_size - EC_MBOX_HEADER_SIZE,
               required_data_size =
                   EC_COE_DOWN_REQ_HEADER_SIZE + request->data_size;

        if (max_data_size < required_data_size) {
            // segmenting needed
            data_size = max_data_size;
        } else {
            data_size = required_data_size;
        }

        data = ec_slave_mbox_prepare_send(slave, datagram, 0x03,
                data_size);
        if (IS_ERR(data)) {
            request->errno = PTR_ERR(data);
            return PTR_ERR(data);
        }

        fsm->offset = 0;
        fsm->remaining = request->data_size;

        EC_WRITE_U16(data, 0x2 << 12); // SDO request
        EC_WRITE_U8(data + 2,
                0x1 // size indicator, normal
                | ((request->complete_access ? 1 : 0) << 4)
                | 0x1 << 5); // Download request
        EC_WRITE_U16(data + 3, request->index);
        EC_WRITE_U8 (data + 5,
                request->complete_access ? 0x00 : request->subindex);
        EC_WRITE_U32(data + 6, request->data_size);

        if (data_size > EC_COE_DOWN_REQ_HEADER_SIZE) {
            size_t segment_size = data_size - EC_COE_DOWN_REQ_HEADER_SIZE;
            memcpy(data + EC_COE_DOWN_REQ_HEADER_SIZE,
                    request->data, segment_size);
            fsm->offset += segment_size;
            fsm->remaining -= segment_size;
        }

        if (slave->master->debug_level) {
            EC_SLAVE_DBG(slave, 1, "Normal download request:\n");
            ec_print_data(data, data_size);
        }
    }

    fsm->state = ec_fsm_coe_down_request;
    return 0;
}

/****************************************************************************/

/** CoE state: DOWN START.
 */
void ec_fsm_coe_down_start(
        ec_fsm_coe_t *fsm, /**< Finite state machine. */
        ec_datagram_t *datagram /**< Datagram to use. */
        )
{
    ec_slave_t *slave = fsm->slave;
    ec_sdo_request_t *request = fsm->request;

    if (fsm->slave->master->debug_level) {
        char subidxstr[10];
        if (request->complete_access) {
            subidxstr[0] = 0x00;
        } else {
            sprintf(subidxstr, ":%02X", request->subindex);
        }
        EC_SLAVE_DBG(slave, 1, "Downloading SDO 0x%04X%s.\n",
                request->index, subidxstr);
        ec_print_data(request->data, request->data_size);
    }

    if (!(slave->sii.mailbox_protocols & EC_MBOX_COE)) {
        EC_SLAVE_ERR(slave, "Slave does not support CoE!\n");
        request->errno = EPROTONOSUPPORT;
        fsm->state = ec_fsm_coe_error;
        return;
    }

    if (slave->configured_rx_mailbox_size <
            EC_MBOX_HEADER_SIZE + EC_COE_DOWN_REQ_HEADER_SIZE) {
        EC_SLAVE_ERR(slave, "Mailbox too small!\n");
        request->errno = EOVERFLOW;
        fsm->state = ec_fsm_coe_error;
        return;
    }


    fsm->request->jiffies_sent = jiffies;
    fsm->retries = EC_FSM_RETRIES;

    if (ec_fsm_coe_prepare_down_start(fsm, datagram)) {
        fsm->state = ec_fsm_coe_error;
    }
}

/*****************************************************************************/

/**
   CoE state: DOWN REQUEST.
   \todo Timeout behavior
*/

void ec_fsm_coe_down_request(
        ec_fsm_coe_t *fsm, /**< Finite state machine. */
        ec_datagram_t *datagram /**< Datagram to use. */
        )
{
    ec_slave_t *slave = fsm->slave;
    unsigned long diff_ms;

    if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
        if (ec_fsm_coe_prepare_down_start(fsm, datagram)) {
            fsm->state = ec_fsm_coe_error;
        }
        return;
    }

    if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
        fsm->request->errno = EIO;
        fsm->state = ec_fsm_coe_error;
        EC_SLAVE_ERR(slave, "Failed to receive CoE download"
                " request datagram: ");
        ec_datagram_print_state(fsm->datagram);
        return;
    }

    diff_ms = (jiffies - fsm->request->jiffies_sent) * 1000 / HZ;

    if (fsm->datagram->working_counter != 1) {
        if (!fsm->datagram->working_counter) {
            if (diff_ms < fsm->request->response_timeout) {
#if DEBUG_RETRIES
                EC_SLAVE_DBG(slave, 1, "Slave did not respond to SDO"
                        " download request. Retrying after %lu ms...\n",
                        diff_ms);
#endif
                // no response; send request datagram again
                if (ec_fsm_coe_prepare_down_start(fsm, datagram)) {
                    fsm->state = ec_fsm_coe_error;
                }
                return;
            }
        }
        fsm->request->errno = EIO;
        fsm->state = ec_fsm_coe_error;
        EC_SLAVE_ERR(slave, "Reception of CoE download request"
                " for SDO 0x%04x:%x failed with timeout after %lu ms: ",
                fsm->request->index, fsm->request->subindex, diff_ms);
        ec_datagram_print_wc_error(fsm->datagram);
        return;
    }

#if DEBUG_LONG
    if (diff_ms > 200) {
        EC_SLAVE_WARN(slave, "SDO 0x%04x:%x download took %lu ms.\n",
                fsm->request->index, fsm->request->subindex, diff_ms);
    }
#endif

    fsm->jiffies_start = fsm->datagram->jiffies_sent;

    ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
    fsm->retries = EC_FSM_RETRIES;
    fsm->state = ec_fsm_coe_down_check;
}

/*****************************************************************************/

/** CoE state: DOWN CHECK.
 */
void ec_fsm_coe_down_check(
        ec_fsm_coe_t *fsm, /**< Finite state machine. */
        ec_datagram_t *datagram /**< Datagram to use. */
        )
{
    ec_slave_t *slave = fsm->slave;

    if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
        ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
        return;
    }

    if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
        fsm->request->errno = EIO;
        fsm->state = ec_fsm_coe_error;
        EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check"
                " datagram: ");
        ec_datagram_print_state(fsm->datagram);
        return;
    }

    if (fsm->datagram->working_counter != 1) {
        fsm->request->errno = EIO;
        fsm->state = ec_fsm_coe_error;
        EC_SLAVE_ERR(slave, "Reception of CoE mailbox check"
                " datagram failed: ");
        ec_datagram_print_wc_error(fsm->datagram);
        return;
    }

    if (!ec_slave_mbox_check(fsm->datagram)) {
        unsigned long diff_ms =
            (fsm->datagram->jiffies_received - fsm->jiffies_start) *
            1000 / HZ;
        if (diff_ms >= fsm->request->response_timeout) {
            fsm->request->errno = EIO;
            fsm->state = ec_fsm_coe_error;
            EC_SLAVE_ERR(slave, "Timeout after %lu ms while waiting"
                    " for SDO 0x%04x:%x download response.\n", diff_ms,
                    fsm->request->index, fsm->request->subindex);
            return;
        }

        ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
        fsm->retries = EC_FSM_RETRIES;
        return;
    }

    // Fetch response
    ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
    fsm->retries = EC_FSM_RETRIES;
    fsm->state = ec_fsm_coe_down_response;
}

/*****************************************************************************/

/** Prepare a download segment request.
 */
void ec_fsm_coe_down_prepare_segment_request(
        ec_fsm_coe_t *fsm, /**< Finite state machine. */
        ec_datagram_t *datagram /**< Datagram to use. */
        )
{
    ec_slave_t *slave = fsm->slave;
    ec_sdo_request_t *request = fsm->request;
    size_t max_segment_size =
        slave->configured_rx_mailbox_size
        - EC_MBOX_HEADER_SIZE
        - EC_COE_DOWN_SEG_REQ_HEADER_SIZE;
    size_t data_size;
    uint8_t last_segment, seg_data_size, *data;

    if (fsm->remaining > max_segment_size) {
        fsm->segment_size = max_segment_size;
        last_segment = 0;
    } else {
        fsm->segment_size = fsm->remaining;
        last_segment = 1;
    }

    if (fsm->segment_size > EC_COE_DOWN_SEG_MIN_DATA_SIZE) {
        seg_data_size = 0x00;
        data_size = EC_COE_DOWN_SEG_REQ_HEADER_SIZE + fsm->segment_size;
    } else {
        seg_data_size = EC_COE_DOWN_SEG_MIN_DATA_SIZE - fsm->segment_size;
        data_size = EC_COE_DOWN_SEG_REQ_HEADER_SIZE
            + EC_COE_DOWN_SEG_MIN_DATA_SIZE;
    }

    data = ec_slave_mbox_prepare_send(slave, datagram, 0x03,
            data_size);
    if (IS_ERR(data)) {
        request->errno = PTR_ERR(data);
        fsm->state = ec_fsm_coe_error;
        return;
    }

    EC_WRITE_U16(data, 0x2 << 12); // SDO request
    EC_WRITE_U8(data + 2, (last_segment ? 1 : 0)
            | (seg_data_size << 1)
            | (fsm->toggle << 4)
            | (0x00 << 5)); // Download segment request
    memcpy(data + EC_COE_DOWN_SEG_REQ_HEADER_SIZE,
            request->data + fsm->offset, fsm->segment_size);
    if (fsm->segment_size < EC_COE_DOWN_SEG_MIN_DATA_SIZE) {
        memset(data + EC_COE_DOWN_SEG_REQ_HEADER_SIZE + fsm->segment_size,
                0x00, EC_COE_DOWN_SEG_MIN_DATA_SIZE - fsm->segment_size);
    }

    if (slave->master->debug_level) {
        EC_SLAVE_DBG(slave, 1, "Download segment request:\n");
        ec_print_data(data, data_size);
    }

    fsm->state = ec_fsm_coe_down_seg_check;
}

/*****************************************************************************/

/**
   CoE state: DOWN RESPONSE.
   \todo Timeout behavior
*/

void ec_fsm_coe_down_response(
        ec_fsm_coe_t *fsm, /**< Finite state machine. */
        ec_datagram_t *datagram /**< Datagram to use. */
        )
{
    ec_slave_t *slave = fsm->slave;
    uint8_t *data, mbox_prot;
    size_t rec_size;
    ec_sdo_request_t *request = fsm->request;

    if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
        ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
        return;
    }

    if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
        request->errno = EIO;
        fsm->state = ec_fsm_coe_error;
        EC_SLAVE_ERR(slave, "Failed to receive CoE download"
                " response datagram: ");
        ec_datagram_print_state(fsm->datagram);
        return;
    }

    if (fsm->datagram->working_counter != 1) {
        request->errno = EIO;
        fsm->state = ec_fsm_coe_error;
        EC_SLAVE_ERR(slave, "Reception of CoE download response failed: ");
        ec_datagram_print_wc_error(fsm->datagram);
        return;
    }

    data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
    if (IS_ERR(data)) {
        request->errno = PTR_ERR(data);
        fsm->state = ec_fsm_coe_error;
        return;
    }

    if (mbox_prot != 0x03) { // CoE
        request->errno = EIO;
        fsm->state = ec_fsm_coe_error;
        EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
                mbox_prot);
        return;
    }

    if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
        // check for CoE response again
        ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
        fsm->retries = EC_FSM_RETRIES;
        fsm->state = ec_fsm_coe_down_check;
        return;
    }

    if (slave->master->debug_level) {
        EC_SLAVE_DBG(slave, 1, "Download response:\n");
        ec_print_data(data, rec_size);
    }

    if (rec_size < 6) {
        request->errno = EIO;
        fsm->state = ec_fsm_coe_error;
        EC_SLAVE_ERR(slave, "Received data are too small (%zu bytes):\n",
                rec_size);
        ec_print_data(data, rec_size);
        return;
    }

    if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request
        EC_READ_U8 (data + 2) >> 5 == 0x4) { // abort SDO transfer request
        char subidxstr[10];
        request->errno = EIO;
        fsm->state = ec_fsm_coe_error;
        if (request->complete_access) {
            subidxstr[0] = 0x00;
        } else {
            sprintf(subidxstr, ":%02X", request->subindex);
        }
        EC_SLAVE_ERR(slave, "SDO download 0x%04X%s (%zu bytes) aborted.\n",
                request->index, subidxstr, request->data_size);
        if (rec_size < 10) {
            EC_SLAVE_ERR(slave, "Incomplete abort command:\n");
            ec_print_data(data, rec_size);
        } else {
            fsm->request->abort_code = EC_READ_U32(data + 6);
            ec_canopen_abort_msg(slave, fsm->request->abort_code);
        }
        return;
    }

    if (EC_READ_U16(data) >> 12 != 0x3 || // SDO response
        EC_READ_U8 (data + 2) >> 5 != 0x3 || // Download response
        EC_READ_U16(data + 3) != request->index || // index
        EC_READ_U8 (data + 5) != request->subindex) { // subindex
        if (slave->master->debug_level) {
            EC_SLAVE_DBG(slave, 1, "Invalid SDO download response!"
                    " Retrying...\n");
            ec_print_data(data, rec_size);
        }
        // check for CoE response again
        ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
        fsm->retries = EC_FSM_RETRIES;
        fsm->state = ec_fsm_coe_down_check;
        return;
    }

    if (fsm->remaining) { // more segments to download
        fsm->toggle = 0;
        ec_fsm_coe_down_prepare_segment_request(fsm, datagram);
    } else {
        fsm->state = ec_fsm_coe_end; // success
    }
}

/*****************************************************************************/

/**
   CoE state: DOWN SEG CHECK.
*/

void ec_fsm_coe_down_seg_check(
        ec_fsm_coe_t *fsm, /**< Finite state machine. */
        ec_datagram_t *datagram /**< Datagram to use. */
        )
{
    ec_slave_t *slave = fsm->slave;

    if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
        return;

    if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
        fsm->request->errno = EIO;
        fsm->state = ec_fsm_coe_error;
        EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check datagram: ");
        ec_datagram_print_state(fsm->datagram);
        return;
    }

    if (fsm->datagram->working_counter != 1) {
        fsm->request->errno = EIO;
        fsm->state = ec_fsm_coe_error;
        EC_SLAVE_ERR(slave, "Reception of CoE mailbox segment check"
                " datagram failed: ");
        ec_datagram_print_wc_error(fsm->datagram);
        return;
    }

    if (!ec_slave_mbox_check(fsm->datagram)) {
        unsigned long diff_ms =
            (fsm->datagram->jiffies_received - fsm->jiffies_start) *
            1000 / HZ;
        if (diff_ms >= fsm->request->response_timeout) {
            fsm->request->errno = EIO;
            fsm->state = ec_fsm_coe_error;
            EC_SLAVE_ERR(slave, "Timeout while waiting for SDO download"
                    " segment response.\n");
            return;
        }

        ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
        fsm->retries = EC_FSM_RETRIES;
        return;
    }

    // Fetch response
    ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
    fsm->retries = EC_FSM_RETRIES;
    fsm->state = ec_fsm_coe_down_seg_response;
}

/*****************************************************************************/

/**
   CoE state: DOWN SEG RESPONSE.
   \todo Timeout behavior
*/

void ec_fsm_coe_down_seg_response(
        ec_fsm_coe_t *fsm, /**< Finite state machine */
        ec_datagram_t *datagram /**< Datagram to use. */
        )
{
    ec_slave_t *slave = fsm->slave;
    uint8_t *data, mbox_prot;
    size_t rec_size;
    ec_sdo_request_t *request = fsm->request;

    if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
        ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
        return;
    }

    if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
        request->errno = EIO;
        fsm->state = ec_fsm_coe_error;
        EC_SLAVE_ERR(slave, "Failed to receive CoE download response"
                " datagram: ");
        ec_datagram_print_state(fsm->datagram);
        return;
    }

    if (fsm->datagram->working_counter != 1) {
        request->errno = EIO;
        fsm->state = ec_fsm_coe_error;
        EC_SLAVE_ERR(slave, "Reception of CoE download response failed: ");
        ec_datagram_print_wc_error(fsm->datagram);
        return;
    }

    data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
    if (IS_ERR(data)) {
        request->errno = PTR_ERR(data);
        fsm->state = ec_fsm_coe_error;
        return;
    }

    if (mbox_prot != 0x03) { // CoE
        request->errno = EIO;
        fsm->state = ec_fsm_coe_error;
        EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
                mbox_prot);
        return;
    }

    if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
        // check for CoE response again
        ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
        fsm->retries = EC_FSM_RETRIES;
        fsm->state = ec_fsm_coe_down_check;
        return;
    }

    if (slave->master->debug_level) {
        EC_SLAVE_DBG(slave, 1, "Download response:\n");
        ec_print_data(data, rec_size);
    }

    if (rec_size < 6) {
        request->errno = EIO;
        fsm->state = ec_fsm_coe_error;
        EC_SLAVE_ERR(slave, "Received data are too small (%zu bytes):\n",
                rec_size);
        ec_print_data(data, rec_size);
        return;
    }

    if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request
        EC_READ_U8 (data + 2) >> 5 == 0x4) { // abort SDO transfer request
        char subidxstr[10];
        request->errno = EIO;
        fsm->state = ec_fsm_coe_error;
        if (request->complete_access) {
            subidxstr[0] = 0x00;
        } else {
            sprintf(subidxstr, ":%02X", request->subindex);
        }
        EC_SLAVE_ERR(slave, "SDO download 0x%04X%s (%zu bytes) aborted.\n",
                request->index, subidxstr, request->data_size);
        if (rec_size < 10) {
            EC_SLAVE_ERR(slave, "Incomplete abort command:\n");
            ec_print_data(data, rec_size);
        } else {
            fsm->request->abort_code = EC_READ_U32(data + 6);
            ec_canopen_abort_msg(slave, fsm->request->abort_code);
        }
        return;
    }

    if (EC_READ_U16(data) >> 12 != 0x3 ||
            ((EC_READ_U8(data + 2) >> 5) != 0x01)) { // segment response
        if (slave->master->debug_level) {
            EC_SLAVE_DBG(slave, 1, "Invalid SDO download response!"
                    " Retrying...\n");
            ec_print_data(data, rec_size);
        }
        // check for CoE response again
        ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
        fsm->retries = EC_FSM_RETRIES;
        fsm->state = ec_fsm_coe_down_seg_check;
        return;
    }

    if (((EC_READ_U8(data + 2) >> 4) & 0x01) != fsm->toggle) {
        EC_SLAVE_ERR(slave, "Invalid toggle received during"
                " segmented download:\n");
        ec_print_data(data, rec_size);
        request->errno = EIO;
        fsm->state = ec_fsm_coe_error;
        return;
    }

    fsm->offset += fsm->segment_size;
    fsm->remaining -= fsm->segment_size;

    if (fsm->remaining) { // more segments to download
        fsm->toggle = !fsm->toggle;
        ec_fsm_coe_down_prepare_segment_request(fsm, datagram);
    } else {
        fsm->state = ec_fsm_coe_end; // success
    }
}

/*****************************************************************************/

/** Prepare an upload request.
 *
 * \return Zero on success, otherwise a negative error code.
 */
int ec_fsm_coe_prepare_up(
        ec_fsm_coe_t *fsm, /**< Finite state machine. */
        ec_datagram_t *datagram /**< Datagram to use. */
        )
{
    ec_slave_t *slave = fsm->slave;
    ec_sdo_request_t *request = fsm->request;
    ec_master_t *master = slave->master;

    u8 *data = ec_slave_mbox_prepare_send(slave, datagram, 0x03, 10);
    if (IS_ERR(data)) {
        request->errno = PTR_ERR(data);
        return PTR_ERR(data);
    }

    EC_WRITE_U16(data, 0x2 << 12); // SDO request
    EC_WRITE_U8 (data + 2, 0x2 << 5); // initiate upload request
    EC_WRITE_U16(data + 3, request->index);
    EC_WRITE_U8 (data + 5, request->subindex);
    memset(data + 6, 0x00, 4);

    if (master->debug_level) {
        EC_SLAVE_DBG(slave, 1, "Upload request:\n");
        ec_print_data(data, 10);
    }

    fsm->state = ec_fsm_coe_up_request;
    return 0;
}

/*****************************************************************************/

/**
   CoE state: UP START.
*/

void ec_fsm_coe_up_start(
        ec_fsm_coe_t *fsm, /**< Finite state machine. */
        ec_datagram_t *datagram /**< Datagram to use. */
        )
{
    ec_slave_t *slave = fsm->slave;
    ec_sdo_request_t *request = fsm->request;

    EC_SLAVE_DBG(slave, 1, "Uploading SDO 0x%04X:%02X.\n",
            request->index, request->subindex);

    if (!(slave->sii.mailbox_protocols & EC_MBOX_COE)) {
        EC_SLAVE_ERR(slave, "Slave does not support CoE!\n");
        request->errno = EPROTONOSUPPORT;
        fsm->state = ec_fsm_coe_error;
        return;
    }

    fsm->retries = EC_FSM_RETRIES;
    fsm->request->jiffies_sent = jiffies;

    if (ec_fsm_coe_prepare_up(fsm, datagram)) {
        fsm->state = ec_fsm_coe_error;
    }
}

/*****************************************************************************/
/**
   CoE state: UP REQUEST.
   \todo Timeout behavior
*/

void ec_fsm_coe_up_request(
        ec_fsm_coe_t *fsm, /**< Finite state machine. */
        ec_datagram_t *datagram /**< Datagram to use. */
        )
{
    ec_slave_t *slave = fsm->slave;
    unsigned long diff_ms;

    if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
        if (ec_fsm_coe_prepare_up(fsm, datagram)) {
            fsm->state = ec_fsm_coe_error;
        }
        return;
    }

    if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
        fsm->request->errno = EIO;
        fsm->state = ec_fsm_coe_error;
        EC_SLAVE_ERR(slave, "Failed to receive CoE upload request: ");
        ec_datagram_print_state(fsm->datagram);
        return;
    }

    diff_ms = (jiffies - fsm->request->jiffies_sent) * 1000 / HZ;

    if (fsm->datagram->working_counter != 1) {
        if (!fsm->datagram->working_counter) {
            if (diff_ms < fsm->request->response_timeout) {
#if DEBUG_RETRIES
                EC_SLAVE_DBG(slave, 1, "Slave did not respond to"
                        " SDO upload request. Retrying after %lu ms...\n",
                        diff_ms);
#endif
                // no response; send request datagram again
                if (ec_fsm_coe_prepare_up(fsm, datagram)) {
                    fsm->state = ec_fsm_coe_error;
                }
                return;
            }
        }
        fsm->request->errno = EIO;
        fsm->state = ec_fsm_coe_error;
        EC_SLAVE_ERR(slave, "Reception of CoE upload request for"
                " SDO 0x%04x:%x failed with timeout after %lu ms: ",
                fsm->request->index, fsm->request->subindex, diff_ms);
        ec_datagram_print_wc_error(fsm->datagram);
        return;
    }

#if DEBUG_LONG
    if (diff_ms > 200) {
        EC_SLAVE_WARN(slave, "SDO 0x%04x:%x upload took %lu ms.\n",
                fsm->request->index, fsm->request->subindex, diff_ms);
    }
#endif

    fsm->jiffies_start = fsm->datagram->jiffies_sent;

    ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
    fsm->retries = EC_FSM_RETRIES;
    fsm->state = ec_fsm_coe_up_check;
}

/*****************************************************************************/

/**
   CoE state: UP CHECK.
*/

void ec_fsm_coe_up_check(
        ec_fsm_coe_t *fsm, /**< Finite state machine. */
        ec_datagram_t *datagram /**< Datagram to use. */
        )
{
    ec_slave_t *slave = fsm->slave;

    if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
        ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
        return;
    }

    if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
        fsm->request->errno = EIO;
        fsm->state = ec_fsm_coe_error;
        EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check datagram: ");
        ec_datagram_print_state(fsm->datagram);
        return;
    }

    if (fsm->datagram->working_counter != 1) {
        fsm->request->errno = EIO;
        fsm->state = ec_fsm_coe_error;
        EC_SLAVE_ERR(slave, "Reception of CoE mailbox check"
                " datagram failed: ");
        ec_datagram_print_wc_error(fsm->datagram);
        return;
    }

    if (!ec_slave_mbox_check(fsm->datagram)) {
        unsigned long diff_ms =
            (fsm->datagram->jiffies_received - fsm->jiffies_start) *
            1000 / HZ;
        if (diff_ms >= fsm->request->response_timeout) {
            fsm->request->errno = EIO;
            fsm->state = ec_fsm_coe_error;
            EC_SLAVE_ERR(slave, "Timeout after %lu ms while waiting for"
                    " SDO 0x%04x:%x upload response.\n", diff_ms,
                    fsm->request->index, fsm->request->subindex);
            return;
        }

        ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
        fsm->retries = EC_FSM_RETRIES;
        return;
    }

    // Fetch response
    ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
    fsm->retries = EC_FSM_RETRIES;
    fsm->state = ec_fsm_coe_up_response;
}

/*****************************************************************************/

/** Prepare an SDO upload segment request.
 */
void ec_fsm_coe_up_prepare_segment_request(
        ec_fsm_coe_t *fsm, /**< Finite state machine */
        ec_datagram_t *datagram /**< Datagram to use. */
        )
{
    uint8_t *data =
        ec_slave_mbox_prepare_send(fsm->slave, datagram, 0x03, 10);
    if (IS_ERR(data)) {
        fsm->request->errno = PTR_ERR(data);
        fsm->state = ec_fsm_coe_error;
        return;
    }

    EC_WRITE_U16(data, 0x2 << 12); // SDO request
    EC_WRITE_U8 (data + 2, (fsm->toggle << 4 // toggle
                | 0x3 << 5)); // upload segment request
    memset(data + 3, 0x00, 7);

    if (fsm->slave->master->debug_level) {
        EC_SLAVE_DBG(fsm->slave, 1, "Upload segment request:\n");
        ec_print_data(data, 10);
    }
}

/*****************************************************************************/

/**
   CoE state: UP RESPONSE.
   \todo Timeout behavior
*/

void ec_fsm_coe_up_response(
        ec_fsm_coe_t *fsm, /**< Finite state machine. */
        ec_datagram_t *datagram /**< Datagram to use. */
        )
{
    ec_slave_t *slave = fsm->slave;
    ec_master_t *master = slave->master;
    uint16_t rec_index;
    uint8_t *data, mbox_prot, rec_subindex;
    size_t rec_size, data_size;
    ec_sdo_request_t *request = fsm->request;
    unsigned int expedited, size_specified;
    int ret;

    if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
        ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
        return;
    }

    if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
        request->errno = EIO;
        fsm->state = ec_fsm_coe_error;
        EC_SLAVE_ERR(slave, "Failed to receive CoE upload response"
                " datagram: ");
        ec_datagram_print_state(fsm->datagram);
        return;
    }

    if (fsm->datagram->working_counter != 1) {
        request->errno = EIO;
        fsm->state = ec_fsm_coe_error;
        EC_SLAVE_ERR(slave, "Reception of CoE upload response failed: ");
        ec_datagram_print_wc_error(fsm->datagram);
        return;
    }

    data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
    if (IS_ERR(data)) {
        request->errno = PTR_ERR(data);
        fsm->state = ec_fsm_coe_error;
        return;
    }

    if (master->debug_level) {
        EC_SLAVE_DBG(slave, 1, "Upload response:\n");
        ec_print_data(data, rec_size);
    }

    if (mbox_prot != 0x03) { // CoE
        request->errno = EIO;
        fsm->state = ec_fsm_coe_error;
        EC_SLAVE_WARN(slave, "Received mailbox protocol 0x%02X"
                " as response.\n", mbox_prot);
        return;
    }

    if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
        // check for CoE response again
        ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
        fsm->retries = EC_FSM_RETRIES;
        fsm->state = ec_fsm_coe_up_check;
        return;
    }

    if (rec_size < 6) {
        request->errno = EIO;
        fsm->state = ec_fsm_coe_error;
        EC_SLAVE_ERR(slave, "Received currupted SDO upload response"
                " (%zu bytes)!\n", rec_size);
        ec_print_data(data, rec_size);
        return;
    }

    if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request
            EC_READ_U8(data + 2) >> 5 == 0x4) { // abort SDO transfer request
        EC_SLAVE_ERR(slave, "SDO upload 0x%04X:%02X aborted.\n",
               request->index, request->subindex);
        if (rec_size >= 10) {
            request->abort_code = EC_READ_U32(data + 6);
            ec_canopen_abort_msg(slave, request->abort_code);
        } else {
            EC_SLAVE_ERR(slave, "No abort message.\n");
        }
        request->errno = EIO;
        fsm->state = ec_fsm_coe_error;
        return;
    }

    if (EC_READ_U16(data) >> 12 != 0x3 || // SDO response
            EC_READ_U8(data + 2) >> 5 != 0x2) { // upload response
        EC_SLAVE_ERR(slave, "Received unknown response while"
                " uploading SDO 0x%04X:%02X.\n",
                request->index, request->subindex);
        ec_print_data(data, rec_size);
        request->errno = EIO;
        fsm->state = ec_fsm_coe_error;
        return;
    }

    rec_index = EC_READ_U16(data + 3);
    rec_subindex = EC_READ_U8(data + 5);

    if (rec_index != request->index || rec_subindex != request->subindex) {
        EC_SLAVE_ERR(slave, "Received upload response for wrong SDO"
                " (0x%04X:%02X, requested: 0x%04X:%02X).\n",
                rec_index, rec_subindex, request->index, request->subindex);
        ec_print_data(data, rec_size);

        // check for CoE response again
        ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
        fsm->retries = EC_FSM_RETRIES;
        fsm->state = ec_fsm_coe_up_check;
        return;
    }

    // normal or expedited?
    expedited = EC_READ_U8(data + 2) & 0x02;

    if (expedited) {
        size_specified = EC_READ_U8(data + 2) & 0x01;
        if (size_specified) {
            fsm->complete_size = 4 - ((EC_READ_U8(data + 2) & 0x0C) >> 2);
        } else {
            fsm->complete_size = 4;
        }

        if (rec_size < 6 + fsm->complete_size) {
            request->errno = EIO;
            fsm->state = ec_fsm_coe_error;
            EC_SLAVE_ERR(slave, "Received corrupted SDO expedited upload"
                    " response (only %zu bytes)!\n", rec_size);
            ec_print_data(data, rec_size);
            return;
        }

        ret = ec_sdo_request_copy_data(request, data + 6, fsm->complete_size);
        if (ret) {
            request->errno = -ret;
            fsm->state = ec_fsm_coe_error;
            return;
        }
    } else { // normal
        if (rec_size < 10) {
            request->errno = EIO;
            fsm->state = ec_fsm_coe_error;
            EC_SLAVE_ERR(slave, "Received currupted SDO normal upload"
                    " response (only %zu bytes)!\n", rec_size);
            ec_print_data(data, rec_size);
            return;
        }

        data_size = rec_size - 10;
        fsm->complete_size = EC_READ_U32(data + 6);

        if (!fsm->complete_size) {
            request->errno = EIO;
            fsm->state = ec_fsm_coe_error;
            EC_SLAVE_ERR(slave, "No complete size supplied!\n");
            ec_print_data(data, rec_size);
            return;
        }

        ret = ec_sdo_request_alloc(request, fsm->complete_size);
        if (ret) {
            request->errno = -ret;
            fsm->state = ec_fsm_coe_error;
            return;
        }

        ret = ec_sdo_request_copy_data(request, data + 10, data_size);
        if (ret) {
            request->errno = -ret;
            fsm->state = ec_fsm_coe_error;
            return;
        }

        fsm->toggle = 0;

        if (data_size < fsm->complete_size) {
            EC_SLAVE_DBG(slave, 1, "SDO data incomplete (%zu / %u)."
                    " Segmenting...\n", data_size, fsm->complete_size);
            ec_fsm_coe_up_prepare_segment_request(fsm, datagram);
            fsm->retries = EC_FSM_RETRIES;
            fsm->state = ec_fsm_coe_up_seg_request;
            return;
        }
    }

    if (master->debug_level) {
        EC_SLAVE_DBG(slave, 1, "Uploaded data:\n");
        ec_print_data(request->data, request->data_size);
    }

    fsm->state = ec_fsm_coe_end; // success
}

/*****************************************************************************/

/**
   CoE state: UP REQUEST.
   \todo Timeout behavior
*/

void ec_fsm_coe_up_seg_request(
        ec_fsm_coe_t *fsm, /**< Finite state machine. */
        ec_datagram_t *datagram /**< Datagram to use. */
        )
{
    ec_slave_t *slave = fsm->slave;

    if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
        ec_fsm_coe_up_prepare_segment_request(fsm, datagram);
        return;
    }

    if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
        fsm->request->errno = EIO;
        fsm->state = ec_fsm_coe_error;
        EC_SLAVE_ERR(slave, "Failed to receive CoE upload segment"
                " request datagram: ");
        ec_datagram_print_state(fsm->datagram);
        return;
    }

    if (fsm->datagram->working_counter != 1) {
        fsm->request->errno = EIO;
        fsm->state = ec_fsm_coe_error;
        EC_SLAVE_ERR(slave, "Reception of CoE upload segment"
                " request failed: ");
        ec_datagram_print_wc_error(fsm->datagram);
        return;
    }

    fsm->jiffies_start = fsm->datagram->jiffies_sent;

    ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
    fsm->retries = EC_FSM_RETRIES;
    fsm->state = ec_fsm_coe_up_seg_check;
}

/*****************************************************************************/

/**
   CoE state: UP CHECK.
*/

void ec_fsm_coe_up_seg_check(
        ec_fsm_coe_t *fsm, /**< Finite state machine. */
        ec_datagram_t *datagram /**< Datagram to use. */
        )
{
    ec_slave_t *slave = fsm->slave;

    if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
        ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
        return;
    }

    if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
        fsm->request->errno = EIO;
        fsm->state = ec_fsm_coe_error;
        EC_SLAVE_ERR(slave, "Failed to receive CoE mailbox check"
                " datagram: ");
        ec_datagram_print_state(fsm->datagram);
        return;
    }

    if (fsm->datagram->working_counter != 1) {
        fsm->request->errno = EIO;
        fsm->state = ec_fsm_coe_error;
        EC_SLAVE_ERR(slave, "Reception of CoE mailbox check datagram"
                " failed: ");
        ec_datagram_print_wc_error(fsm->datagram);
        return;
    }

    if (!ec_slave_mbox_check(fsm->datagram)) {
        unsigned long diff_ms =
            (fsm->datagram->jiffies_received - fsm->jiffies_start) *
            1000 / HZ;
        if (diff_ms >= fsm->request->response_timeout) {
            fsm->request->errno = EIO;
            fsm->state = ec_fsm_coe_error;
            EC_SLAVE_ERR(slave, "Timeout while waiting for SDO upload"
                    " segment response.\n");
            return;
        }

        ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
        fsm->retries = EC_FSM_RETRIES;
        return;
    }

    // Fetch response
    ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
    fsm->retries = EC_FSM_RETRIES;
    fsm->state = ec_fsm_coe_up_seg_response;
}

/*****************************************************************************/

/**
   CoE state: UP RESPONSE.
   \todo Timeout behavior
*/

void ec_fsm_coe_up_seg_response(
        ec_fsm_coe_t *fsm, /**< Finite state machine. */
        ec_datagram_t *datagram /**< Datagram to use. */
        )
{
    ec_slave_t *slave = fsm->slave;
    ec_master_t *master = slave->master;
    uint8_t *data, mbox_prot;
    size_t rec_size, data_size;
    ec_sdo_request_t *request = fsm->request;
    unsigned int last_segment;

    if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
        ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.
        return;
    }

    if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
        request->errno = EIO;
        fsm->state = ec_fsm_coe_error;
        EC_SLAVE_ERR(slave, "Failed to receive CoE upload segment"
                " response datagram: ");
        ec_datagram_print_state(fsm->datagram);
        return;
    }

    if (fsm->datagram->working_counter != 1) {
        request->errno = EIO;
        fsm->state = ec_fsm_coe_error;
        EC_SLAVE_ERR(slave, "Reception of CoE upload segment"
                " response failed: ");
        ec_datagram_print_wc_error(fsm->datagram);
        return;
    }

    data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
    if (IS_ERR(data)) {
        request->errno = PTR_ERR(data);
        fsm->state = ec_fsm_coe_error;
        return;
    }

    if (master->debug_level) {
        EC_SLAVE_DBG(slave, 1, "Upload segment response:\n");
        ec_print_data(data, rec_size);
    }

    if (mbox_prot != 0x03) { // CoE
        EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
                mbox_prot);
        request->errno = EIO;
        fsm->state = ec_fsm_coe_error;
        return;
    }

    if (ec_fsm_coe_check_emergency(fsm, data, rec_size)) {
        // check for CoE response again
        ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
        fsm->retries = EC_FSM_RETRIES;
        fsm->state = ec_fsm_coe_up_seg_check;
        return;
    }

    if (rec_size < 10) {
        EC_SLAVE_ERR(slave, "Received currupted SDO upload"
                " segment response!\n");
        ec_print_data(data, rec_size);
        request->errno = EIO;
        fsm->state = ec_fsm_coe_error;
        return;
    }

    if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request
            EC_READ_U8 (data + 2) >> 5 == 0x4) { // abort SDO transfer request
        EC_SLAVE_ERR(slave, "SDO upload 0x%04X:%02X aborted.\n",
               request->index, request->subindex);
        request->abort_code = EC_READ_U32(data + 6);
        ec_canopen_abort_msg(slave, request->abort_code);
        request->errno = EIO;
        fsm->state = ec_fsm_coe_error;
        return;
    }

    if (EC_READ_U16(data) >> 12 != 0x3 || // SDO response
        EC_READ_U8 (data + 2) >> 5 != 0x0) { // upload segment response
        if (fsm->slave->master->debug_level) {
            EC_SLAVE_DBG(slave, 1, "Invalid SDO upload segment response!\n");
            ec_print_data(data, rec_size);
        }
        // check for CoE response again
        ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
        fsm->retries = EC_FSM_RETRIES;
        fsm->state = ec_fsm_coe_up_seg_check;
        return;
    }

    data_size = rec_size - 3; /* Header of segment upload is smaller than
                                 normal upload */
    if (rec_size == 10) {
        uint8_t seg_size = (EC_READ_U8(data + 2) & 0xE) >> 1;
        data_size -= seg_size;
    }

    if (request->data_size + data_size > fsm->complete_size) {
        EC_SLAVE_ERR(slave, "SDO upload 0x%04X:%02X failed: Fragment"
                " exceeding complete size!\n",
                request->index, request->subindex);
        request->errno = EOVERFLOW;
        fsm->state = ec_fsm_coe_error;
        return;
    }

    memcpy(request->data + request->data_size, data + 3, data_size);
    request->data_size += data_size;

    last_segment = EC_READ_U8(data + 2) & 0x01;
    if (!last_segment) {
        fsm->toggle = !fsm->toggle;
        ec_fsm_coe_up_prepare_segment_request(fsm, datagram);
        fsm->retries = EC_FSM_RETRIES;
        fsm->state = ec_fsm_coe_up_seg_request;
        return;
    }

    if (request->data_size != fsm->complete_size) {
        EC_SLAVE_WARN(slave, "SDO upload 0x%04X:%02X: Assembled data"
                " size (%zu) does not match complete size (%u)!\n",
                request->index, request->subindex,
                request->data_size, fsm->complete_size);
    }

    if (master->debug_level) {
        EC_SLAVE_DBG(slave, 1, "Uploaded data:\n");
        ec_print_data(request->data, request->data_size);
    }

    fsm->state = ec_fsm_coe_end; // success
}

/*****************************************************************************/

/**
   State: ERROR.
*/

void ec_fsm_coe_error(
        ec_fsm_coe_t *fsm, /**< Finite state machine. */
        ec_datagram_t *datagram /**< Datagram to use. */
        )
{
}

/*****************************************************************************/

/**
   State: END.
*/

void ec_fsm_coe_end(
        ec_fsm_coe_t *fsm, /**< Finite state machine. */
        ec_datagram_t *datagram /**< Datagram to use. */
        )
{
}

/*****************************************************************************/


<|start_filename|>rootfs/buildroot-2017.11.1/package/audit/audit.mk<|end_filename|>
################################################################################
#
# audit
#
################################################################################

AUDIT_VERSION = 2.7.8
AUDIT_SITE = http://people.redhat.com/sgrubb/audit
AUDIT_LICENSE = GPL-2.0+ (programs), LGPL-2.1+ (libraries)
AUDIT_LICENSE_FILES = COPYING COPYING.LIB

AUDIT_INSTALL_STAGING = YES

AUDIT_CONF_OPTS = --without-python --without-python3 --disable-zos-remote

ifeq ($(BR2_PACKAGE_LIBCAP_NG),y)
AUDIT_DEPENDENCIES += libcap-ng
AUDIT_CONF_OPTS += --with-libcap-ng=yes
else
AUDIT_CONF_OPTS += --with-libcap-ng=no
endif

# For i386, x86-64 and PowerPC, the system call tables are
# unconditionally included. However, for ARM(eb) and AArch64, then
# need to be explicitly enabled.

ifeq ($(BR2_arm)$(BR2_armeb),y)
AUDIT_CONF_OPTS += --with-arm
endif
ifeq ($(BR2_aarch64),y)
AUDIT_CONF_OPTS += --with-aarch64
endif

ifeq ($(BR2_INIT_SYSTEMD),y)
AUDIT_CONF_OPTS += --enable-systemd
else
AUDIT_CONF_OPTS += --disable-systemd
endif

define AUDIT_INSTALL_INIT_SYSV
	$(INSTALL) -D -m 755 package/audit/S01auditd $(TARGET_DIR)/etc/init.d/S01auditd
endef

define AUDIT_INSTALL_INIT_SYSTEMD
	mkdir -p $(TARGET_DIR)/etc/systemd/system/multi-user.target.wants
	ln -fs ../../../../usr/lib/systemd/system/auditd.service \
		$(TARGET_DIR)/etc/systemd/system/multi-user.target.wants/auditd.service

	$(INSTALL) -D -m 644 package/audit/audit_tmpfiles.conf \
		$(TARGET_DIR)/usr/lib/tmpfiles.d/audit.conf
endef

define AUDIT_INSTALL_CLEANUP
	$(RM) -rf $(TARGET_DIR)/etc/rc.d
	$(RM) -rf $(TARGET_DIR)/etc/sysconfig
endef
AUDIT_POST_INSTALL_TARGET_HOOKS += AUDIT_INSTALL_CLEANUP

HOST_AUDIT_CONF_OPTS = \
	--without-python \
	--without-python3 \
	--disable-zos-remote \
	--without-libcap-ng

$(eval $(autotools-package))
$(eval $(host-autotools-package))


<|start_filename|>kernel/modules/platform/pltdrv.c<|end_filename|>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>

#include <linux/platform_device.h>

static int pdrv_suspend(struct device *dev)
{
	printk("pdev: suspend\n");
	return 0;
}

static int pdrv_resume(struct device *dev)
{
	printk("pdev: resume\n");
	return 0;
}

/* 电源管理函数的集合 */
static const struct dev_pm_ops pdrv_pm_ops = {
	.suspend = pdrv_suspend,
	.resume  = pdrv_resume,
};

static int pdrv_probe(struct platform_device *pdev)
{
	return 0;
}

static int pdrv_remove(struct platform_device *pdev)
{
	return 0;
}

/* 定义一个平台驱动 */
struct platform_driver pdrv = {
	.driver = {
		.name    = "pdev",//名字需要和待绑定的平台设备一致，这样才能匹配成功
		.owner   = THIS_MODULE,
		.pm      = &pdrv_pm_ops,
	},
	.probe   = pdrv_probe,
	.remove  = pdrv_remove,
};

static int __init pltdrv_init(void)
{
	/* 注册平台驱动 */
	platform_driver_register(&pdrv);
	return 0;
}

static void __exit pltdrv_exit(void)
{
	/* 注销平台驱动 */
	platform_driver_unregister(&pdrv);
}

module_init(pltdrv_init);
module_exit(pltdrv_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("suda-morris <<EMAIL>>");
MODULE_DESCRIPTION("A simple platform driver");
MODULE_ALIAS("platform:pdev");


<|start_filename|>kernel/modules/raw_led/led.h<|end_filename|>
#pragma once

#define LED_MAGIC 'l'

#define LED_ON      _IOW(LED_MAGIC,0,unsigned int)
#define LED_OFF     _IOW(LED_MAGIC,1,unsigned int)

#define LED_RED     0
#define LED_GREEN   1
#define LED_BLUE    2


<|start_filename|>3rdpart/tslib-1.15/plugins/dejitter.c<|end_filename|>
/*
 *  tslib/plugins/dejitter.c
 *
 *  Copyright (C) 2016 <NAME> <<EMAIL>>
 *  Copyright (C) 2001 <NAME>.
 *
 * This file is placed under the LGPL.  Please see the file
 * COPYING for more details.
 *
 * SPDX-License-Identifier: LGPL-2.1
 *
 *
 * Problem: some touchscreens read the X/Y values from ADC with a
 * great level of noise in their lowest bits. This produces "jitter"
 * in touchscreen output, e.g. even if we hold the stylus still,
 * we get a great deal of X/Y coordinate pairs that are close enough
 * but not equal. Also if we try to draw a straight line in a painter
 * program, we'll get a line full of spikes.
 *
 * Solution: we apply a smoothing filter on the last several values
 * thus excluding spikes from output. If we detect a substantial change
 * in coordinates, we reset the backlog of pen positions, thus avoiding
 * smoothing coordinates that are not supposed to be smoothed. This
 * supposes all noise has been filtered by the lower-level filter,
 * e.g. by the "variance" module.
 */
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <stdint.h>

#include <stdio.h>

#include "config.h"
#include "tslib.h"
#include "tslib-filter.h"

/**
 * This filter works as follows: we keep track of latest N samples,
 * and average them with certain weights. The oldest samples have the
 * least weight and the most recent samples have the most weight.
 * This helps remove the jitter and at the same time doesn't influence
 * responsivity because for each input sample we generate one output
 * sample; pen movement becomes just somehow more smooth.
 */

#define NR_SAMPHISTLEN	4

/* To keep things simple (avoiding division) we ensure that
 * SUM(weight) = power-of-two. Also we must know how to approximate
 * measurements when we have less than NR_SAMPHISTLEN samples.
 */
static const unsigned char weight[NR_SAMPHISTLEN - 1][NR_SAMPHISTLEN + 1] = {
	/* The last element is pow2(SUM(0..3)) */
	{ 5, 3, 0, 0, 3 },	/* When we have 2 samples ... */
	{ 8, 5, 3, 0, 4 },	/* When we have 3 samples ... */
	{ 6, 4, 3, 3, 4 },	/* When we have 4 samples ... */
};

struct ts_hist {
	int x;
	int y;
	unsigned int p;
};

struct tslib_dejitter {
	struct tslib_module_info module;
	int delta;
	int nr;
	int head;
	struct ts_hist hist[NR_SAMPHISTLEN];
	int *nr_mt;
	int *head_mt;
	struct ts_hist **hist_mt;
	int slots;
};

static int sqr(int x)
{
	return x * x;
}

static void average(struct tslib_dejitter *djt, struct ts_sample *samp)
{
	const unsigned char *w;
	int sn = djt->head;
	int i, x = 0, y = 0;
	unsigned int p = 0;

	w = weight[djt->nr - 2];

	for (i = 0; i < djt->nr; i++) {
		x += djt->hist[sn].x * w[i];
		y += djt->hist[sn].y * w[i];
		p += djt->hist[sn].p * w[i];
		sn = (sn - 1) & (NR_SAMPHISTLEN - 1);
	}

	samp->x = x >> w[NR_SAMPHISTLEN];
	samp->y = y >> w[NR_SAMPHISTLEN];
	samp->pressure = p >> w[NR_SAMPHISTLEN];
#ifdef DEBUG
	fprintf(stderr, "DEJITTER----------------> %d %d %d\n",
		samp->x, samp->y, samp->pressure);
#endif
}

static int dejitter_read(struct tslib_module_info *info, struct ts_sample *samp,
			 int nr)
{
	struct tslib_dejitter *djt = (struct tslib_dejitter *)info;
	struct ts_sample *s;
	int count = 0, ret;

	ret = info->next->ops->read(info->next, samp, nr);
	for (s = samp; ret > 0; s++, ret--) {
		if (s->pressure == 0) {
			/*
			 * Pen was released. Reset the state and
			 * forget all history events.
			 */
			djt->nr = 0;
			samp[count++] = *s;
			continue;
		}

		/* If the pen moves too fast, reset the backlog. */
		if (djt->nr) {
			int prev = (djt->head - 1) & (NR_SAMPHISTLEN - 1);

			if (sqr(s->x - djt->hist[prev].x) +
			    sqr(s->y - djt->hist[prev].y) > djt->delta) {
#ifdef DEBUG
				fprintf(stderr,
					"DEJITTER: pen movement exceeds threshold\n");
#endif
				djt->nr = 0;
			}
		}

		djt->hist[djt->head].x = s->x;
		djt->hist[djt->head].y = s->y;
		djt->hist[djt->head].p = s->pressure;
		if (djt->nr < NR_SAMPHISTLEN)
			djt->nr++;

		/* We'll pass through the very first sample since
		 * we can't average it (no history yet).
		 */
		if (djt->nr == 1)
			samp[count] = *s;
		else {
			average(djt, samp + count);
			samp[count].tv = s->tv;
		}
		count++;

		djt->head = (djt->head + 1) & (NR_SAMPHISTLEN - 1);
	}

	return count;
}

static void average_mt(struct tslib_dejitter *djt, struct ts_sample_mt **samp, int nr, int slot)
{
	const unsigned char *w;
	int sn = djt->head_mt[slot];
	int i, x = 0, y = 0;
	unsigned int p = 0;

	w = weight[djt->nr_mt[slot] - 2];

	for (i = 0; i < djt->nr_mt[slot]; i++) {
		x += djt->hist_mt[slot][sn].x * w[i];
		y += djt->hist_mt[slot][sn].y * w[i];
		p += djt->hist_mt[slot][sn].p * w[i];
		sn = (sn - 1) & (NR_SAMPHISTLEN - 1);
	}

	samp[nr][slot].x = x >> w[NR_SAMPHISTLEN];
	samp[nr][slot].y = y >> w[NR_SAMPHISTLEN];
	samp[nr][slot].pressure = p >> w[NR_SAMPHISTLEN];
#ifdef DEBUG
	fprintf(stderr, "DEJITTER----------------> %d %d %d\n",
		samp[nr][slot].x, samp[nr][slot].y,
		samp[nr][slot].pressure);
#endif
}

static int dejitter_read_mt(struct tslib_module_info *info,
			    struct ts_sample_mt **samp, int max_slots, int nr)
{
	struct tslib_dejitter *djt = (struct tslib_dejitter *)info;
	int ret;
	int i, j;

	if (!info->next->ops->read_mt)
		return -ENOSYS;

	ret = info->next->ops->read_mt(info->next, samp, max_slots, nr);
	if (ret < 0)
		return ret;

#ifdef DEBUG
	printf("DEJITTER: read %d samples (mem: %d nr x %d slots)\n",
	       ret, nr, max_slots);
#endif

	if (djt->hist_mt == NULL || max_slots > djt->slots) {
		if (djt->hist_mt) {
			for (i = 0; i < djt->slots; i++) {
				if (djt->hist_mt[i])
					free(djt->hist_mt[i]);
			}
			free(djt->hist_mt);
			djt->hist_mt = NULL;
		}

		djt->hist_mt = malloc(max_slots * sizeof(struct ts_hist *));
		if (!djt->hist_mt)
			return -ENOMEM;

		for (i = 0; i < max_slots; i++) {
			djt->hist_mt[i] = calloc(NR_SAMPHISTLEN, sizeof(struct ts_hist));
			if (&djt->hist[i] == NULL) {
				for (j = 0; j < i; j++)
					if (&djt->hist[j])
						free(&djt->hist[j]);

				if (djt->hist_mt)
					free(djt->hist_mt);

				return -ENOMEM;
			}
		}
		djt->slots = max_slots;
	}

	if (djt->nr_mt == NULL || max_slots > djt->slots) {
		if (djt->nr_mt)
			free(djt->nr_mt);

		djt->nr_mt = calloc(max_slots, sizeof(int));
		if (!djt->nr_mt)
			return -ENOMEM;
	}

	if (djt->head_mt == NULL || max_slots > djt->slots) {
		if (djt->head_mt)
			free(djt->head_mt);

		djt->head_mt = calloc(max_slots, sizeof(int));
		if (!djt->head_mt)
			return -ENOMEM;
	}

	for (j = 0; j < ret; j++) {
		for (i = 0; i < max_slots; i++) {
			if (!(samp[j][i].valid & TSLIB_MT_VALID))
				continue;

			if (samp[j][i].pressure == 0) {
				/*
				 * Pen was released. Reset the state and
				 * forget all history events.
				 */
				djt->nr_mt[i] = 0;
				continue;
			}

			/* If the pen moves too fast, reset the backlog. */
			if (djt->nr_mt[i]) {
				int prev = (djt->head_mt[i] - 1) & (NR_SAMPHISTLEN - 1);
				if (sqr(samp[j][i].x - djt->hist_mt[i][prev].x) +
				    sqr(samp[j][i].y - djt->hist_mt[i][prev].y) > djt->delta) {
	#ifdef DEBUG
					fprintf(stderr,
						"DEJITTER: pen movement exceeds threshold\n");
	#endif
					djt->nr_mt[i] = 0;
				}
			}

			djt->hist_mt[i][djt->head_mt[i]].x = samp[j][i].x;
			djt->hist_mt[i][djt->head_mt[i]].y = samp[j][i].y;
			djt->hist_mt[i][djt->head_mt[i]].p = samp[j][i].pressure;
			if (djt->nr_mt[i] < NR_SAMPHISTLEN)
				djt->nr_mt[i]++;

			/* We'll pass through the very first sample since
			 * we can't average it (no history yet).
			 */
			if (djt->nr_mt[i] > 1)
				average_mt(djt, samp, j, i);

			djt->head_mt[i] = (djt->head_mt[i] + 1) & (NR_SAMPHISTLEN - 1);
		}
	}

	return j;
}

static int dejitter_fini(struct tslib_module_info *info)
{
	struct tslib_dejitter *djt = (struct tslib_dejitter *)info;
	int i;

	for (i = 0; i < djt->slots; i++) {
		if (djt->hist_mt[i])
			free(djt->hist_mt[i]);
	}

	if (djt->hist_mt)
		free(djt->hist_mt);

	if (djt->nr_mt)
		free(djt->nr_mt);

	if (djt->head_mt)
		free(djt->head_mt);

	free(info);

	return 0;
}

static const struct tslib_ops dejitter_ops = {
	.read		= dejitter_read,
	.read_mt	= dejitter_read_mt,
	.fini		= dejitter_fini,
};

static int dejitter_limit(struct tslib_module_info *inf, char *str, void *data)
{
	struct tslib_dejitter *djt = (struct tslib_dejitter *)inf;
	unsigned long v;
	int err = errno;

	v = strtoul(str, NULL, 0);

	if (v == ULONG_MAX && errno == ERANGE)
		return -1;

	errno = err;
	switch ((int)(intptr_t)data) {
	case 1:
		djt->delta = v;
		break;

	default:
		return -1;
	}
	return 0;
}

static const struct tslib_vars dejitter_vars[] = {
	{ "delta",	(void *)1, dejitter_limit },
};

#define NR_VARS (sizeof(dejitter_vars) / sizeof(dejitter_vars[0]))

TSAPI struct tslib_module_info *dejitter_mod_init(__attribute__ ((unused)) struct tsdev *dev,
						  const char *params)
{
	struct tslib_dejitter *djt;

	djt = malloc(sizeof(struct tslib_dejitter));
	if (djt == NULL)
		return NULL;

	memset(djt, 0, sizeof(struct tslib_dejitter));
	djt->module.ops = &dejitter_ops;

	djt->delta = 100;
	djt->head = 0;
	djt->hist_mt = NULL;
	djt->nr_mt = NULL;
	djt->head_mt = NULL;
	djt->slots = 0;

	if (tslib_parse_vars(&djt->module, dejitter_vars, NR_VARS, params)) {
		free(djt);
		return NULL;
	}
	djt->delta = sqr(djt->delta);

	return &djt->module;
}

#ifndef TSLIB_STATIC_DEJITTER_MODULE
	TSLIB_MODULE_INIT(dejitter_mod_init);
#endif


<|start_filename|>rootfs/buildroot-2017.11.1/package/lua-resty-http/lua-resty-http.mk<|end_filename|>
################################################################################
#
# lua-resty-http
#
################################################################################

LUA_RESTY_HTTP_VERSION = 0.11-0
LUA_RESTY_HTTP_SUBDIR = lua-resty-http
LUA_RESTY_HTTP_LICENSE = BSD-2-Clause
LUA_RESTY_HTTP_LICENSE_FILES = $(LUA_RESTY_HTTP_SUBDIR)/LICENSE

$(eval $(luarocks-package))


<|start_filename|>3rdpart/ethercat-1.5.2/master/datagram_pair.h<|end_filename|>
/******************************************************************************
 *
 *  $Id: datagram_pair.h,v ec403cf308eb 2013/02/12 14:46:43 fp $
 *
 *  Copyright (C) 2006-2012  <NAME>, Ingenieurgemeinschaft IgH
 *
 *  This file is part of the IgH EtherCAT Master.
 *
 *  The IgH EtherCAT Master is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License version 2, as
 *  published by the Free Software Foundation.
 *
 *  The IgH EtherCAT Master is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 *  Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with the IgH EtherCAT Master; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 *****************************************************************************/

/**
   \file
   EtherCAT datagram pair structure.
*/

/*****************************************************************************/

#ifndef __EC_DATAGRAM_PAIR_H__
#define __EC_DATAGRAM_PAIR_H__

#include <linux/list.h>

#include "globals.h"
#include "datagram.h"

/*****************************************************************************/

/** Domain datagram pair.
 */
typedef struct {
    struct list_head list; /**< List header. */
    ec_domain_t *domain; /**< Parent domain. */
    ec_datagram_t datagrams[EC_MAX_NUM_DEVICES]; /**< Datagrams.  */
#if EC_MAX_NUM_DEVICES > 1
    uint8_t *send_buffer;
#endif
    unsigned int expected_working_counter; /**< Expectord working conter. */
} ec_datagram_pair_t;

/*****************************************************************************/

int ec_datagram_pair_init(ec_datagram_pair_t *, ec_domain_t *, uint32_t,
        uint8_t *, size_t, const unsigned int []);
void ec_datagram_pair_clear(ec_datagram_pair_t *);

uint16_t ec_datagram_pair_process(ec_datagram_pair_t *, uint16_t[]);

/*****************************************************************************/

#endif


<|start_filename|>3rdpart/tslib-1.15/tests/sdlutils.c<|end_filename|>
/*
 * (C) 2017 <NAME> <<EMAIL>>
 *
 * This file is part of tslib.
 *
 * ts_calibrate is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * ts_calibrate is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this tool.  If not, see <http://www.gnu.org/licenses/>.
 *
 * SPDX-License-Identifier: GPL-2.0+
 */

#include <SDL2/SDL.h>

#include <stdint.h>

#include <tslib.h>

void draw_line(SDL_Renderer *r, int32_t x1, int32_t y1, int32_t x2, int32_t y2)
{
	int32_t tmp;
	int32_t dx = x2 - x1;
	int32_t dy = y2 - y1;

	if (abs(dx) < abs(dy)) {
		if (y1 > y2) {
			tmp = x1;
			x1 = x2;
			x2 = tmp;

			tmp = y1;
			y1 = y2;
			y2 = tmp;

			dx = -dx;
			dy = -dy;
		}

		x1 <<= 16;

		dx = (dx << 16) / dy;
		while (y1 <= y2) {
			SDL_RenderDrawPoint(r, x1 >> 16, y1);
			y1 += dx;
			y1++;
		}
	} else {
		if (x1 > x2) {
			tmp = x1;
			x1 = x2;
			x2 = tmp;

			tmp = y1;
			y1 = y2;
			y2 = tmp;

			dx = -dx;
			dy = -dy;
		}

		y1 <<= 16;

		dy = dx ? (dy << 16) : 0;
		while (x1 <= x2) {
			SDL_RenderDrawPoint(r, x1, y1 >> 16);
			y1 += dy;
			x1++;
		}
	}
}

void draw_crosshair(SDL_Renderer *r, int32_t x, int32_t y)
{
	SDL_SetRenderDrawColor(r, 255, 255, 255, 255);
	draw_line(r, x - 10, y, x - 2, y);
	draw_line(r, x + 2, y, x + 10, y);
	draw_line(r, x, y - 10, x, y - 2);
	draw_line(r, x, y + 2, x, y + 10);

	SDL_SetRenderDrawColor(r, 0xff, 0xe0, 0x80, 255);
	draw_line(r, x - 6, y - 9, x - 9, y - 9);
	draw_line(r, x - 9, y - 8, x - 9, y - 6);
	draw_line(r, x - 9, y + 6, x - 9, y + 9);
	draw_line(r, x - 8, y + 9, x - 6, y + 9);
	draw_line(r, x + 6, y + 9, x + 9, y + 9);
	draw_line(r, x + 9, y + 8, x + 9, y + 6);
	draw_line(r, x + 9, y - 6, x + 9, y - 9);
	draw_line(r, x + 8, y - 9, x + 6, y - 9);
}

static int sort_by_x(const void *a, const void *b)
{
	return (((struct ts_sample *)a)->x - ((struct ts_sample *)b)->x);
}

static int sort_by_y(const void *a, const void *b)
{
	return (((struct ts_sample *)a)->y - ((struct ts_sample *)b)->y);
}

void getxy(struct tsdev *ts, int *x, int *y)
{
#define MAX_SAMPLES 128
	struct ts_sample samp[MAX_SAMPLES];
	int index, middle;

	do {
		if (ts_read_raw(ts, &samp[0], 1) < 0) {
			perror("ts_read");
			SDL_Quit();
		}
	} while (samp[0].pressure == 0);

	/* Now collect up to MAX_SAMPLES touches into the samp array. */
	index = 0;
	do {
		if (index < MAX_SAMPLES-1)
			index++;
		if (ts_read_raw(ts, &samp[index], 1) < 0) {
			perror("ts_read");
			SDL_Quit();
		}
	} while (samp[index].pressure > 0);
	printf("Took %d samples...\n", index);

	/*
	 * At this point, we have samples in indices zero to (index-1)
	 * which means that we have (index) number of samples.  We want
	 * to calculate the median of the samples so that wild outliers
	 * don't skew the result.  First off, let's assume that arrays
	 * are one-based instead of zero-based.  If this were the case
	 * and index was odd, we would need sample number ((index+1)/2)
	 * of a sorted array; if index was even, we would need the
	 * average of sample number (index/2) and sample number
	 * ((index/2)+1).  To turn this into something useful for the
	 * real world, we just need to subtract one off of the sample
	 * numbers.  So for when index is odd, we need sample number
	 * (((index+1)/2)-1).  Due to integer division truncation, we
	 * can simplify this to just (index/2).  When index is even, we
	 * need the average of sample number ((index/2)-1) and sample
	 * number (index/2).  Calculate (index/2) now and we'll handle
	 * the even odd stuff after we sort.
	 */
	middle = index/2;
	if (x) {
		qsort(samp, index, sizeof(struct ts_sample), sort_by_x);
		if (index & 1)
			*x = samp[middle].x;
		else
			*x = (samp[middle-1].x + samp[middle].x) / 2;
	}
	if (y) {
		qsort(samp, index, sizeof(struct ts_sample), sort_by_y);
		if (index & 1)
			*y = samp[middle].y;
		else
			*y = (samp[middle-1].y + samp[middle].y) / 2;
	}
}

void print_ascii_logo(void)
{
	printf("                 _       _ _ _\n");
	printf("                | |_ ___| (_) |__\n");
	printf("                | __/ __| | | '_ \\\n");
	printf("                | |_\\__ \\ | | |_) |\n");
	printf("                 \\__|___/_|_|_.__/\n\n");
}


<|start_filename|>rootfs/buildroot-2017.11.1/boot/arm-trusted-firmware/arm-trusted-firmware.mk<|end_filename|>
################################################################################
#
# arm-trusted-firmware
#
################################################################################

ARM_TRUSTED_FIRMWARE_VERSION = $(call qstrip,$(BR2_TARGET_ARM_TRUSTED_FIRMWARE_VERSION))
ARM_TRUSTED_FIRMWARE_LICENSE = BSD-3-Clause
ARM_TRUSTED_FIRMWARE_LICENSE_FILES = license.rst

ARM_TRUSTED_FIRMWARE_DEPENDENCIES += uboot

ifeq ($(ARM_TRUSTED_FIRMWARE_VERSION),custom)
# Handle custom ATF tarballs as specified by the configuration
ARM_TRUSTED_FIRMWARE_TARBALL = $(call qstrip,$(BR2_TARGET_ARM_TRUSTED_FIRMWARE_CUSTOM_TARBALL_LOCATION))
ARM_TRUSTED_FIRMWARE_SITE = $(patsubst %/,%,$(dir $(ARM_TRUSTED_FIRMWARE_TARBALL)))
ARM_TRUSTED_FIRMWARE_SOURCE = $(notdir $(ARM_TRUSTED_FIRMWARE_TARBALL))
BR_NO_CHECK_HASH_FOR += $(ARM_TRUSTED_FIRMWARE_SOURCE)
else ifeq ($(BR2_TARGET_ARM_TRUSTED_FIRMWARE_CUSTOM_GIT),y)
ARM_TRUSTED_FIRMWARE_SITE = $(call qstrip,$(BR2_TARGET_ARM_TRUSTED_FIRMWARE_CUSTOM_REPO_URL))
ARM_TRUSTED_FIRMWARE_SITE_METHOD = git
BR_NO_CHECK_HASH_FOR += $(ARM_TRUSTED_FIRMWARE_SOURCE)
else
ARM_TRUSTED_FIRMWARE_SITE = $(call github,ARM-software,arm-trusted-firmware,$(ARM_TRUSTED_FIRMWARE_VERSION))
endif

ARM_TRUSTED_FIRMWARE_INSTALL_IMAGES = YES

ARM_TRUSTED_FIRMWARE_PLATFORM = $(call qstrip,$(BR2_TARGET_ARM_TRUSTED_FIRMWARE_PLATFORM))

ARM_TRUSTED_FIRMWARE_MAKE_OPTS += \
	CROSS_COMPILE="$(TARGET_CROSS)" \
	BL33=$(BINARIES_DIR)/u-boot.bin \
	$(call qstrip,$(BR2_TARGET_ARM_TRUSTED_FIRMWARE_ADDITIONAL_VARIABLES)) \
	PLAT=$(ARM_TRUSTED_FIRMWARE_PLATFORM)

ifeq ($(BR2_TARGET_VEXPRESS_FIRMWARE),y)
ARM_TRUSTED_FIRMWARE_MAKE_OPTS += SCP_BL2=$(BINARIES_DIR)/scp-fw.bin
ARM_TRUSTED_FIRMWARE_DEPENDENCIES += vexpress-firmware
endif

define ARM_TRUSTED_FIRMWARE_BUILD_CMDS
	$(TARGET_CONFIGURE_OPTS) \
		$(MAKE) -C $(@D) $(ARM_TRUSTED_FIRMWARE_MAKE_OPTS) \
			all fip
endef

define ARM_TRUSTED_FIRMWARE_INSTALL_IMAGES_CMDS
	cp -dpf $(@D)/build/$(ARM_TRUSTED_FIRMWARE_PLATFORM)/release/*.bin $(BINARIES_DIR)/
endef

# Configuration check
ifeq ($(BR2_TARGET_ARM_TRUSTED_FIRMWARE)$(BR_BUILDING),yy)

ifeq ($(ARM_TRUSTED_FIRMWARE_VERSION),custom)
ifeq ($(call qstrip,$(BR2_TARGET_ARM_TRUSTED_FIRMWARE_CUSTOM_TARBALL_LOCATION))),)
$(error No tarball location specified. Please check BR2_TARGET_ARM_TRUSTED_FIRMWARE_CUSTOM_TARBALL_LOCATION))
endif
endif

ifeq ($(BR2_TARGET_ARM_TRUSTED_FIRMWARE_CUSTOM_GIT),y)
ifeq ($(call qstrip,$(BR2_TARGET_ARM_TRUSTED_FIRMWARE_CUSTOM_REPO_URL)),)
$(error No repository specified. Please check BR2_TARGET_ARM_TRUSTED_FIRMWARE_CUSTOM_REPO_URL)
endif
endif

endif

$(eval $(generic-package))


<|start_filename|>rootfs/buildroot-2017.11.1/package/dash/dash.mk<|end_filename|>
################################################################################
#
# dash
#
################################################################################

DASH_VERSION = 0.5.9.1
DASH_SITE = http://gondor.apana.org.au/~herbert/dash/files
DASH_LICENSE = BSD-3-Clause, GPL-2.0+ (mksignames.c)
DASH_LICENSE_FILES = COPYING

define DASH_INSTALL_TARGET_CMDS
	$(INSTALL) -m 0755 $(@D)/src/dash $(TARGET_DIR)/bin/dash
endef

$(eval $(autotools-package))


<|start_filename|>kernel/modules/raw_led/led_test.c<|end_filename|>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>

#include "led.h"

int main()
{
    int fd;
    int ret;
    int num = LED_RED;

    fd = open("/dev/led", O_RDWR);
    if (fd == -1)
    {
        goto fail;
    }

    while (1)
    {
        ret = ioctl(fd, LED_ON, num);
        if (ret == -1)
        {
            goto fail;
        }
        usleep(500000);
        ret = ioctl(fd, LED_OFF, num);
        if (ret == -1)
        {
            goto fail;
        }
        usleep(500000);

        num = (num + 1) % 3;
    }
    exit(EXIT_SUCCESS);
fail:
    perror("led test");
    exit(EXIT_FAILURE);
}

<|start_filename|>3rdpart/tslib-1.15/plugins/arctic2-raw.c<|end_filename|>
/*
 * SPDX-License-Identifier: LGPL-2.1
 */
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>

#include "config.h"
#include "tslib-private.h"

struct arctic2_ts_event { /* Used in the IBM Arctic II */
	signed short pressure;
	signed int x;
	signed int y;
	int millisecs;
	int flags;
};

static int arctic2_read(struct tslib_module_info *inf, struct ts_sample *samp, int nr)
{
	struct tsdev *ts = inf->dev;
	struct arctic2_ts_event *arctic2_evt;
	int ret;
	int nr_read;

	arctic2_evt = alloca(sizeof(*arctic2_evt) * nr);
	ret = read(ts->fd, arctic2_evt, sizeof(*arctic2_evt) * nr);
	if (ret > 0) {
		nr_read = ret / sizeof(*arctic2_evt);
		while (ret >= (int)sizeof(*arctic2_evt)) {
			samp->x = (short)arctic2_evt->x;
			samp->y = (short)arctic2_evt->y;
			samp->pressure = arctic2_evt->pressure;
#ifdef DEBUG
	fprintf(stderr, "RAW---------------------------> %d %d %d\n",
		samp->x, samp->y, samp->pressure);
#endif /*DEBUG*/
			gettimeofday(&samp->tv, NULL);
			samp++;
			arctic2_evt++;
			ret -= sizeof(*arctic2_evt);
		}
	} else {
		return -1;
	}

	ret = nr_read;
	return ret;
}

static const struct tslib_ops arctic2_ops = {
	.read	= arctic2_read,
};

TSAPI struct tslib_module_info *arctic2_mod_init(__attribute__ ((unused)) struct tsdev *dev,
						 __attribute__ ((unused)) const char *params)
{
	struct tslib_module_info *m;

	m = malloc(sizeof(struct tslib_module_info));
	if (m == NULL)
		return NULL;

	m->ops = &arctic2_ops;
	return m;
}

#ifndef TSLIB_STATIC_ARCTIC2_MODULE
	TSLIB_MODULE_INIT(arctic2_mod_init);
#endif


<|start_filename|>rootfs/buildroot-2017.11.1/package/network-manager/network-manager.mk<|end_filename|>
################################################################################
#
# network-manager
#
################################################################################

NETWORK_MANAGER_VERSION_MAJOR = 1.8
NETWORK_MANAGER_VERSION = $(NETWORK_MANAGER_VERSION_MAJOR).4
NETWORK_MANAGER_SOURCE = NetworkManager-$(NETWORK_MANAGER_VERSION).tar.xz
NETWORK_MANAGER_SITE = http://ftp.gnome.org/pub/GNOME/sources/NetworkManager/$(NETWORK_MANAGER_VERSION_MAJOR)
NETWORK_MANAGER_INSTALL_STAGING = YES
NETWORK_MANAGER_DEPENDENCIES = host-pkgconf udev dbus-glib libnl gnutls \
	libgcrypt wireless_tools util-linux host-intltool readline libndp libgudev
NETWORK_MANAGER_LICENSE = GPL-2.0+ (app), LGPL-2.0+ (libnm-util)
NETWORK_MANAGER_LICENSE_FILES = COPYING libnm-util/COPYING

NETWORK_MANAGER_CONF_ENV = \
	ac_cv_path_LIBGCRYPT_CONFIG=$(STAGING_DIR)/usr/bin/libgcrypt-config \
	ac_cv_file__etc_fedora_release=no \
	ac_cv_file__etc_mandriva_release=no \
	ac_cv_file__etc_debian_version=no \
	ac_cv_file__etc_redhat_release=no \
	ac_cv_file__etc_SuSE_release=no

NETWORK_MANAGER_CONF_OPTS = \
	--disable-tests \
	--disable-qt \
	--disable-more-warnings \
	--without-docs \
	--with-crypto=gnutls \
	--with-iptables=/usr/sbin/iptables \
	--disable-ifupdown \
	--disable-ifnet

ifeq ($(BR2_PACKAGE_OFONO),y)
NETWORK_MANAGER_DEPENDENCIES += ofono
NETWORK_MANAGER_CONF_OPTS += --with-ofono
else
NETWORK_MANAGER_CONF_OPTS += --without-ofono
endif

ifeq ($(BR2_PACKAGE_LIBCURL),y)
NETWORK_MANAGER_DEPENDENCIES += libcurl
NETWORK_MANAGER_CONF_OPTS += --enable-concheck
else
NETWORK_MANAGER_CONF_OPTS += --disable-concheck
endif

ifeq ($(BR2_PACKAGE_NETWORK_MANAGER_TUI),y)
NETWORK_MANAGER_DEPENDENCIES += newt
NETWORK_MANAGER_CONF_OPTS += --with-nmtui=yes
else
NETWORK_MANAGER_CONF_OPTS += --with-nmtui=no
endif

ifeq ($(BR2_PACKAGE_NETWORK_MANAGER_PPPD),y)
NETWORK_MANAGER_DEPENDENCIES += pppd
NETWORK_MANAGER_CONF_OPTS += --enable-ppp
else
NETWORK_MANAGER_CONF_OPTS += --disable-ppp
endif

ifeq ($(BR2_PACKAGE_NETWORK_MANAGER_MODEM_MANAGER),y)
NETWORK_MANAGER_DEPENDENCIES += modem-manager
NETWORK_MANAGER_CONF_OPTS += --with-modem-manager-1
else
NETWORK_MANAGER_CONF_OPTS += --without-modem-manager-1
endif

ifeq ($(BR2_PACKAGE_DHCP_CLIENT),y)
NETWORK_MANAGER_CONF_OPTS += --with-dhclient=/sbin/dhclient
endif

ifeq ($(BR2_PACKAGE_DHCPCD),y)
NETWORK_MANAGER_CONF_OPTS += --with-dhcpcd=/sbin/dhcpcd
endif

# uClibc by default doesn't have backtrace support, so don't use it
ifeq ($(BR2_TOOLCHAIN_USES_UCLIBC),y)
NETWORK_MANAGER_CONF_OPTS += --disable-crashtrace
endif

define NETWORK_MANAGER_INSTALL_INIT_SYSV
	$(INSTALL) -m 0755 -D package/network-manager/S45network-manager $(TARGET_DIR)/etc/init.d/S45network-manager
endef

define NETWORK_MANAGER_INSTALL_INIT_SYSTEMD
	mkdir -p $(TARGET_DIR)/etc/systemd/system/multi-user.target.wants

	ln -sf /usr/lib/systemd/system/NetworkManager.service \
		$(TARGET_DIR)/etc/systemd/system/dbus-org.freedesktop.NetworkManager.service

	ln -sf /usr/lib/systemd/system/NetworkManager.service \
		$(TARGET_DIR)/etc/systemd/system/multi-user.target.wants/NetworkManager.service

	ln -sf /usr/lib/systemd/system/NetworkManager-dispatcher.service \
		$(TARGET_DIR)/etc/systemd/system/dbus-org.freedesktop.nm-dispatcher.service
endef

$(eval $(autotools-package))


<|start_filename|>3rdpart/ethercat-1.5.2/include/ecrt.h<|end_filename|>
/******************************************************************************
 *
 *  $Id: ecrt.h,v 6d9865c37b6f 2013/02/12 16:15:09 fp $
 *
 *  Copyright (C) 2006-2012  <NAME>, Ingenieurgemeinschaft IgH
 *
 *  This file is part of the IgH EtherCAT master userspace library.
 *
 *  The IgH EtherCAT master userspace library is free software; you can
 *  redistribute it and/or modify it under the terms of the GNU Lesser General
 *  Public License as published by the Free Software Foundation; version 2.1
 *  of the License.
 *
 *  The IgH EtherCAT master userspace library is distributed in the hope that
 *  it will be useful, but WITHOUT ANY WARRANTY; without even the implied
 *  warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public License
 *  along with the IgH EtherCAT master userspace library. If not, see
 *  <http://www.gnu.org/licenses/>.
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 *****************************************************************************/

/** \file
 *
 * EtherCAT master application interface.
 *
 * \defgroup ApplicationInterface EtherCAT Application Interface
 *
 * EtherCAT interface for realtime applications. This interface is designed
 * for realtime modules that want to use EtherCAT. There are functions to
 * request a master, to map process data, to communicate with slaves via CoE
 * and to configure and activate the bus.
 *
 * Changes in version 1.5.2:
 *
 * - Added redundancy_active flag to ec_domain_state_t.
 * - Added ecrt_master_link_state() method and ec_master_link_state_t to query
 *   the state of a redundant link.
 * - Added the EC_HAVE_REDUNDANCY define, to check, if the interface contains
 *   redundancy features.
 * - Added ecrt_sdo_request_index() to change SDO index and subindex after
 *   handler creation.
 * - Added interface for retrieving CoE emergency messages, i. e.
 *   ecrt_slave_config_emerg_size(), ecrt_slave_config_emerg_pop(),
 *   ecrt_slave_config_emerg_clear(), ecrt_slave_config_emerg_overruns() and
 *   the defines EC_HAVE_EMERGENCY and EC_COE_EMERGENCY_MSG_SIZE.
 * - Added interface for direct EtherCAT register access: Added data type
 *   ec_reg_request_t and methods ecrt_slave_config_create_reg_request(),
 *   ecrt_reg_request_data(), ecrt_reg_request_state(),
 *   ecrt_reg_request_write(), ecrt_reg_request_read() and the feature flag
 *   EC_HAVE_REG_ACCESS.
 * - Added method to select the reference clock,
 *   ecrt_master_select_reference_clock() and the feature flag
 *   EC_HAVE_SELECT_REF_CLOCK to check, if the method is available.
 * - Added method to get the reference clock time,
 *   ecrt_master_reference_clock_time() and the feature flag
 *   EC_HAVE_REF_CLOCK_TIME to have the possibility to synchronize the master
 *   clock to the reference clock.
 * - Changed the data types of the shift times in ecrt_slave_config_dc() to
 *   int32_t to correctly display negative shift times.
 * - Added ecrt_slave_config_reg_pdo_entry_pos() and the feature flag
 *   EC_HAVE_REG_BY_POS for registering PDO entries with non-unique indices
 *   via their positions in the mapping.
 *
 * Changes in version 1.5:
 *
 * - Added the distributed clocks feature and the respective method
 *   ecrt_slave_config_dc() to configure a slave for cyclic operation, and
 *   ecrt_master_application_time(), ecrt_master_sync_reference_clock() and
 *   ecrt_master_sync_slave_clocks() for offset and drift compensation. The
 *   EC_TIMEVAL2NANO() macro can be used for epoch time conversion, while the
 *   ecrt_master_sync_monitor_queue() and ecrt_master_sync_monitor_process()
 *   methods can be used to monitor the synchrony.
 * - Improved the callback mechanism. ecrt_master_callbacks() now takes two
 *   callback functions for sending and receiving datagrams.
 *   ecrt_master_send_ext() is used to execute the sending of non-application
 *   datagrams.
 * - Added watchdog configuration (method ecrt_slave_config_watchdog(),
 *   #ec_watchdog_mode_t, \a watchdog_mode parameter in ec_sync_info_t and
 *   ecrt_slave_config_sync_manager()).
 * - Added ecrt_slave_config_complete_sdo() method to download an SDO during
 *   configuration via CompleteAccess.
 * - Added ecrt_master_deactivate() to remove the bus configuration.
 * - Added ecrt_open_master() and ecrt_master_reserve() separation for
 *   userspace.
 * - Added bus information interface (methods ecrt_master(),
 *   ecrt_master_get_slave(), ecrt_master_get_sync_manager(),
 *   ecrt_master_get_pdo() and ecrt_master_get_pdo_entry()) to get information
 *   about the currently connected slaves and the PDO entries provided.
 * - Added ecrt_master_sdo_download(), ecrt_master_sdo_download_complete() and
 *   ecrt_master_sdo_upload() methods to let an application transfer SDOs
 *   before activating the master.
 * - Changed the meaning of the negative return values of
 *   ecrt_slave_config_reg_pdo_entry() and ecrt_slave_config_sdo*().
 * - Implemented the Vendor-specific over EtherCAT mailbox protocol. See
 *   ecrt_slave_config_create_voe_handler().
 * - Renamed ec_sdo_request_state_t to #ec_request_state_t, because it is also
 *   used by VoE handlers.
 * - Removed 'const' from argument of ecrt_sdo_request_state(), because the
 *   userspace library has to modify object internals.
 * - Added 64-bit data access macros.
 * - Added ecrt_slave_config_idn() method for storing SoE IDN configurations,
 *   and ecrt_master_read_idn() and ecrt_master_write_idn() to read/write IDNs
 *   ad-hoc via the user-space library.
 * - Added ecrt_master_reset() to initiate retrying to configure slaves.
 *
 * @{
 */

/*****************************************************************************/

#ifndef __ECRT_H__
#define __ECRT_H__

#ifdef __KERNEL__
#include <asm/byteorder.h>
#include <linux/types.h>
#include <linux/time.h>
#else
#include <stdlib.h> // for size_t
#include <stdint.h>
#include <sys/time.h> // for struct timeval
#endif

/******************************************************************************
 * Global definitions
 *****************************************************************************/

/** EtherCAT realtime interface major version number.
 */
#define ECRT_VER_MAJOR 1

/** EtherCAT realtime interface minor version number.
 */
#define ECRT_VER_MINOR 5

/** EtherCAT realtime interface version word generator.
 */
#define ECRT_VERSION(a, b) (((a) << 8) + (b))

/** EtherCAT realtime interface version word.
 */
#define ECRT_VERSION_MAGIC ECRT_VERSION(ECRT_VER_MAJOR, ECRT_VER_MINOR)

/******************************************************************************
 * Feature flags
 *****************************************************************************/

/** Defined, if the redundancy features are available.
 *
 * I. e. if the \a redundancy_active flag in ec_domain_state_t and the
 * ecrt_master_link_state() method are available.
 */
#define EC_HAVE_REDUNDANCY

/** Defined, if the CoE emergency ring feature is available.
 *
 * I. e. if the ecrt_slave_config_emerg_*() methods are available.
 */
#define EC_HAVE_EMERGENCY

/** Defined, if the register access interface is available.
 *
 * I. e. if the methods ecrt_slave_config_create_reg_request(),
 * ecrt_reg_request_data(), ecrt_reg_request_state(), ecrt_reg_request_write()
 * and ecrt_reg_request_read() are available.
 */
#define EC_HAVE_REG_ACCESS

/** Defined if the method ecrt_master_select_reference_clock() is available.
 */
#define EC_HAVE_SELECT_REF_CLOCK

/** Defined if the method ecrt_master_reference_clock_time() is available.
 */
#define EC_HAVE_REF_CLOCK_TIME

/** Defined if the method ecrt_slave_config_reg_pdo_entry_pos() is available.
 */
#define EC_HAVE_REG_BY_POS

/*****************************************************************************/

/** End of list marker.
 *
 * This can be used with ecrt_slave_config_pdos().
 */
#define EC_END ~0U

/** Maximum number of sync managers per slave.
 */
#define EC_MAX_SYNC_MANAGERS 16

/** Maximum string length.
 *
 * Used in ec_slave_info_t.
 */
#define EC_MAX_STRING_LENGTH 64

/** Maximum number of slave ports. */
#define EC_MAX_PORTS 4

/** Timeval to nanoseconds conversion.
 *
 * This macro converts a Unix epoch time to EtherCAT DC time.
 *
 * \see void ecrt_master_application_time()
 *
 * \param TV struct timeval containing epoch time.
 */
#define EC_TIMEVAL2NANO(TV) \
    (((TV).tv_sec - 946684800ULL) * 1000000000ULL + (TV).tv_usec * 1000ULL)

/** Size of a CoE emergency message in byte.
 *
 * \see ecrt_slave_config_emerg_pop().
 */
#define EC_COE_EMERGENCY_MSG_SIZE 8

/******************************************************************************
 * Data types
 *****************************************************************************/

struct ec_master;
typedef struct ec_master ec_master_t; /**< \see ec_master */

struct ec_slave_config;
typedef struct ec_slave_config ec_slave_config_t; /**< \see ec_slave_config */

struct ec_domain;
typedef struct ec_domain ec_domain_t; /**< \see ec_domain */

struct ec_sdo_request;
typedef struct ec_sdo_request ec_sdo_request_t; /**< \see ec_sdo_request. */

struct ec_voe_handler;
typedef struct ec_voe_handler ec_voe_handler_t; /**< \see ec_voe_handler. */

struct ec_reg_request;
typedef struct ec_reg_request ec_reg_request_t; /**< \see ec_sdo_request. */

/*****************************************************************************/

/** Master state.
 *
 * This is used for the output parameter of ecrt_master_state().
 *
 * \see ecrt_master_state().
 */
typedef struct {
    unsigned int slaves_responding; /**< Sum of responding slaves on all
                                      Ethernet devices. */
    unsigned int al_states : 4; /**< Application-layer states of all slaves.
                                  The states are coded in the lower 4 bits.
                                  If a bit is set, it means that at least one
                                  slave in the bus is in the corresponding
                                  state:
                                  - Bit 0: \a INIT
                                  - Bit 1: \a PREOP
                                  - Bit 2: \a SAFEOP
                                  - Bit 3: \a OP */
    unsigned int link_up : 1; /**< \a true, if at least one Ethernet link is
                                up. */
} ec_master_state_t;

/*****************************************************************************/

/** Redundant link state.
 *
 * This is used for the output parameter of ecrt_master_link_state().
 *
 * \see ecrt_master_link_state().
 */
typedef struct {
    unsigned int slaves_responding; /**< Sum of responding slaves on the given
                                      link. */
    unsigned int al_states : 4; /**< Application-layer states of the slaves on
                                  the given link.  The states are coded in the
                                  lower 4 bits.  If a bit is set, it means
                                  that at least one slave in the bus is in the
                                  corresponding state:
                                  - Bit 0: \a INIT
                                  - Bit 1: \a PREOP
                                  - Bit 2: \a SAFEOP
                                  - Bit 3: \a OP */
    unsigned int link_up : 1; /**< \a true, if the given Ethernet link is up.
                               */
} ec_master_link_state_t;

/*****************************************************************************/

/** Slave configuration state.
 *
 * This is used as an output parameter of ecrt_slave_config_state().
 *
 * \see ecrt_slave_config_state().
 */
typedef struct  {
    unsigned int online : 1; /**< The slave is online. */
    unsigned int operational : 1; /**< The slave was brought into \a OP state
                                    using the specified configuration. */
    unsigned int al_state : 4; /**< The application-layer state of the slave.
                                 - 1: \a INIT
                                 - 2: \a PREOP
                                 - 4: \a SAFEOP
                                 - 8: \a OP

                                 Note that each state is coded in a different
                                 bit! */
} ec_slave_config_state_t;

/*****************************************************************************/

/** Master information.
 *
 * This is used as an output parameter of ecrt_master().
 *
 * \see ecrt_master().
 */
typedef struct {
   unsigned int slave_count; /**< Number of slaves in the bus. */
   unsigned int link_up : 1; /**< \a true, if the network link is up. */
   uint8_t scan_busy; /**< \a true, while the master is scanning the bus */
   uint64_t app_time; /**< Application time. */
} ec_master_info_t;

/*****************************************************************************/

/** EtherCAT slave port descriptor.
 */
typedef enum {
    EC_PORT_NOT_IMPLEMENTED, /**< Port is not implemented. */
    EC_PORT_NOT_CONFIGURED, /**< Port is not configured. */
    EC_PORT_EBUS, /**< Port is an E-Bus. */
    EC_PORT_MII /**< Port is a MII. */
} ec_slave_port_desc_t;

/*****************************************************************************/

/** EtherCAT slave port information.
 */
typedef struct {
    uint8_t link_up; /**< Link detected. */
    uint8_t loop_closed; /**< Loop closed. */
    uint8_t signal_detected; /**< Detected signal on RX port. */
} ec_slave_port_link_t;

/*****************************************************************************/

/** Slave information.
 *
 * This is used as an output parameter of ecrt_master_get_slave().
 *
 * \see ecrt_master_get_slave().
 */
typedef struct {
    uint16_t position; /**< Offset of the slave in the ring. */
    uint32_t vendor_id; /**< Vendor-ID stored on the slave. */
    uint32_t product_code; /**< Product-Code stored on the slave. */
    uint32_t revision_number; /**< Revision-Number stored on the slave. */
    uint32_t serial_number; /**< Serial-Number stored on the slave. */
    uint16_t alias; /**< The slaves alias if not equal to 0. */
    int16_t current_on_ebus; /**< Used current in mA. */
    struct {
        ec_slave_port_desc_t desc; /**< Physical port type. */
        ec_slave_port_link_t link; /**< Port link state. */
        uint32_t receive_time; /**< Receive time on DC transmission delay
                                 measurement. */
        uint16_t next_slave; /**< Ring position of next DC slave on that
                               port.  */
        uint32_t delay_to_next_dc; /**< Delay [ns] to next DC slave. */
    } ports[EC_MAX_PORTS]; /**< Port information. */
    uint8_t al_state; /**< Current state of the slave. */
    uint8_t error_flag; /**< Error flag for that slave. */
    uint8_t sync_count; /**< Number of sync managers. */
    uint16_t sdo_count; /**< Number of SDOs. */
    char name[EC_MAX_STRING_LENGTH]; /**< Name of the slave. */
} ec_slave_info_t;

/*****************************************************************************/

/** Domain working counter interpretation.
 *
 * This is used in ec_domain_state_t.
 */
typedef enum {
    EC_WC_ZERO = 0,   /**< No registered process data were exchanged. */
    EC_WC_INCOMPLETE, /**< Some of the registered process data were
                        exchanged. */
    EC_WC_COMPLETE    /**< All registered process data were exchanged. */
} ec_wc_state_t;

/*****************************************************************************/

/** Domain state.
 *
 * This is used for the output parameter of ecrt_domain_state().
 */
typedef struct {
    unsigned int working_counter; /**< Value of the last working counter. */
    ec_wc_state_t wc_state; /**< Working counter interpretation. */
    unsigned int redundancy_active; /**< Redundant link is in use. */
} ec_domain_state_t;

/*****************************************************************************/

/** Direction type for PDO assignment functions.
 */
typedef enum {
    EC_DIR_INVALID, /**< Invalid direction. Do not use this value. */
    EC_DIR_OUTPUT, /**< Values written by the master. */
    EC_DIR_INPUT, /**< Values read by the master. */
    EC_DIR_COUNT /**< Number of directions. For internal use only. */
} ec_direction_t;

/*****************************************************************************/

/** Watchdog mode for sync manager configuration.
 *
 * Used to specify, if a sync manager's watchdog is to be enabled.
 */
typedef enum {
    EC_WD_DEFAULT, /**< Use the default setting of the sync manager. */
    EC_WD_ENABLE, /**< Enable the watchdog. */
    EC_WD_DISABLE, /**< Disable the watchdog. */
} ec_watchdog_mode_t;

/*****************************************************************************/

/** PDO entry configuration information.
 *
 * This is the data type of the \a entries field in ec_pdo_info_t.
 *
 * \see ecrt_slave_config_pdos().
 */
typedef struct {
    uint16_t index; /**< PDO entry index. */
    uint8_t subindex; /**< PDO entry subindex. */
    uint8_t bit_length; /**< Size of the PDO entry in bit. */
} ec_pdo_entry_info_t;

/*****************************************************************************/

/** PDO configuration information.
 *
 * This is the data type of the \a pdos field in ec_sync_info_t.
 *
 * \see ecrt_slave_config_pdos().
 */
typedef struct {
    uint16_t index; /**< PDO index. */
    unsigned int n_entries; /**< Number of PDO entries in \a entries to map.
                              Zero means, that the default mapping shall be
                              used (this can only be done if the slave is
                              present at bus configuration time). */
    ec_pdo_entry_info_t *entries; /**< Array of PDO entries to map. Can either
                                    be \a NULL, or must contain at
                                    least \a n_entries values. */
} ec_pdo_info_t;

/*****************************************************************************/

/** Sync manager configuration information.
 *
 * This can be use to configure multiple sync managers including the PDO
 * assignment and PDO mapping. It is used as an input parameter type in
 * ecrt_slave_config_pdos().
 */
typedef struct {
    uint8_t index; /**< Sync manager index. Must be less
                     than #EC_MAX_SYNC_MANAGERS for a valid sync manager,
                     but can also be \a 0xff to mark the end of the list. */
    ec_direction_t dir; /**< Sync manager direction. */
    unsigned int n_pdos; /**< Number of PDOs in \a pdos. */
    ec_pdo_info_t *pdos; /**< Array with PDOs to assign. This must contain
                            at least \a n_pdos PDOs. */
    ec_watchdog_mode_t watchdog_mode; /**< Watchdog mode. */
} ec_sync_info_t;

/*****************************************************************************/

/** List record type for PDO entry mass-registration.
 *
 * This type is used for the array parameter of the
 * ecrt_domain_reg_pdo_entry_list()
 */
typedef struct {
    uint16_t alias; /**< Slave alias address. */
    uint16_t position; /**< Slave position. */
    uint32_t vendor_id; /**< Slave vendor ID. */
    uint32_t product_code; /**< Slave product code. */
    uint16_t index; /**< PDO entry index. */
    uint8_t subindex; /**< PDO entry subindex. */
    unsigned int *offset; /**< Pointer to a variable to store the PDO entry's
                       (byte-)offset in the process data. */
    unsigned int *bit_position; /**< Pointer to a variable to store a bit
                                  position (0-7) within the \a offset. Can be
                                  NULL, in which case an error is raised if the
                                  PDO entry does not byte-align. */
} ec_pdo_entry_reg_t;

/*****************************************************************************/

/** Request state.
 *
 * This is used as return type for ecrt_sdo_request_state() and
 * ecrt_voe_handler_state().
 */
typedef enum {
    EC_REQUEST_UNUSED, /**< Not requested. */
    EC_REQUEST_BUSY, /**< Request is being processed. */
    EC_REQUEST_SUCCESS, /**< Request was processed successfully. */
    EC_REQUEST_ERROR, /**< Request processing failed. */
} ec_request_state_t;

/*****************************************************************************/

/** Application-layer state.
 */
typedef enum {
    EC_AL_STATE_INIT = 1, /**< Init. */
    EC_AL_STATE_PREOP = 2, /**< Pre-operational. */
    EC_AL_STATE_SAFEOP = 4, /**< Safe-operational. */
    EC_AL_STATE_OP = 8, /**< Operational. */
} ec_al_state_t;

/******************************************************************************
 * Global functions
 *****************************************************************************/

#ifdef __cplusplus
extern "C" {
#endif

/** Returns the version magic of the realtime interface.
 *
 * \return Value of ECRT_VERSION_MAGIC() at EtherCAT master compile time.
 */
unsigned int ecrt_version_magic(void);

/** Requests an EtherCAT master for realtime operation.
 *
 * Before an application can access an EtherCAT master, it has to reserve one
 * for exclusive use.
 *
 * In userspace, this is a convenience function for ecrt_open_master() and
 * ecrt_master_reserve().
 *
 * This function has to be the first function an application has to call to
 * use EtherCAT. The function takes the index of the master as its argument.
 * The first master has index 0, the n-th master has index n - 1. The number
 * of masters has to be specified when loading the master module.
 *
 * \return Pointer to the reserved master, otherwise \a NULL.
 */
ec_master_t *ecrt_request_master(
        unsigned int master_index /**< Index of the master to request. */
        );

#ifndef __KERNEL__

/** Opens an EtherCAT master for userspace access.
 *
 * This function has to be the first function an application has to call to
 * use EtherCAT. The function takes the index of the master as its argument.
 * The first master has index 0, the n-th master has index n - 1. The number
 * of masters has to be specified when loading the master module.
 *
 * For convenience, the function ecrt_request_master() can be used.
 *
 * \return Pointer to the opened master, otherwise \a NULL.
 */
ec_master_t *ecrt_open_master(
        unsigned int master_index /**< Index of the master to request. */
        );

#endif // #ifndef __KERNEL__

/** Releases a requested EtherCAT master.
 *
 * After use, a master it has to be released to make it available for other
 * applications.
 *
 * This method frees all created data structures. It should not be called in
 * realtime context.
 *
 * If the master was activated, ecrt_master_deactivate() is called internally.
 */
void ecrt_release_master(
        ec_master_t *master /**< EtherCAT master */
        );

/******************************************************************************
 * Master methods
 *****************************************************************************/

#ifndef __KERNEL__

/** Reserves an EtherCAT master for realtime operation.
 *
 * Before an application can use PDO/domain registration functions or SDO
 * request functions on the master, it has to reserve one for exclusive use.
 *
 * \return 0 in case of success, else < 0
 */
int ecrt_master_reserve(
        ec_master_t *master /**< EtherCAT master */
        );

#endif // #ifndef __KERNEL__

#ifdef __KERNEL__

/** Sets the locking callbacks.
 *
 * For concurrent master access, i. e. if other instances than the application
 * want to send and receive datagrams on the bus, the application has to
 * provide a callback mechanism. This method takes two function pointers as
 * its parameters. Asynchronous master access (like EoE processing) is only
 * possible if the callbacks have been set.
 *
 * The task of the send callback (\a send_cb) is to decide, if the bus is
 * currently accessible and whether or not to call the ecrt_master_send_ext()
 * method.
 *
 * The task of the receive callback (\a receive_cb) is to decide, if a call to
 * ecrt_master_receive() is allowed and to execute it respectively.
 *
 * \attention This method has to be called before ecrt_master_activate().
 */
void ecrt_master_callbacks(
        ec_master_t *master, /**< EtherCAT master */
        void (*send_cb)(void *), /**< Datagram sending callback. */
        void (*receive_cb)(void *), /**< Receive callback. */
        void *cb_data /**< Arbitrary pointer passed to the callback functions.
                       */
        );

#endif /* __KERNEL__ */

/** Creates a new process data domain.
 *
 * For process data exchange, at least one process data domain is needed.
 * This method creates a new process data domain and returns a pointer to the
 * new domain object. This object can be used for registering PDOs and
 * exchanging them in cyclic operation.
 *
 * This method allocates memory and should be called in non-realtime context
 * before ecrt_master_activate().
 *
 * \return Pointer to the new domain on success, else NULL.
 */
ec_domain_t *ecrt_master_create_domain(
        ec_master_t *master /**< EtherCAT master. */
        );

/** Obtains a slave configuration.
 *
 * Creates a slave configuration object for the given \a alias and \a position
 * tuple and returns it. If a configuration with the same \a alias and \a
 * position already exists, it will be re-used. In the latter case, the given
 * vendor ID and product code are compared to the stored ones. On mismatch, an
 * error message is raised and the function returns \a NULL.
 *
 * Slaves are addressed with the \a alias and \a position parameters.
 * - If \a alias is zero, \a position is interpreted as the desired slave's
 *   ring position.
 * - If \a alias is non-zero, it matches a slave with the given alias. In this
 *   case, \a position is interpreted as ring offset, starting from the
 *   aliased slave, so a position of zero means the aliased slave itself and a
 *   positive value matches the n-th slave behind the aliased one.
 *
 * If the slave with the given address is found during the bus configuration,
 * its vendor ID and product code are matched against the given value. On
 * mismatch, the slave is not configured and an error message is raised.
 *
 * If different slave configurations are pointing to the same slave during bus
 * configuration, a warning is raised and only the first configuration is
 * applied.
 *
 * This method allocates memory and should be called in non-realtime context
 * before ecrt_master_activate().
 *
 * \retval >0 Pointer to the slave configuration structure.
 * \retval NULL in the error case.
 */
ec_slave_config_t *ecrt_master_slave_config(
        ec_master_t *master, /**< EtherCAT master */
        uint16_t alias, /**< Slave alias. */
        uint16_t position, /**< Slave position. */
        uint32_t vendor_id, /**< Expected vendor ID. */
        uint32_t product_code /**< Expected product code. */
        );

/** Selects the reference clock for distributed clocks.
 *
 * If this method is not called for a certain master, or if the slave
 * configuration pointer is NULL, then the first slave with DC functionality
 * will provide the reference clock.
 *
 * \return 0 on success, otherwise negative error code.
 */
int ecrt_master_select_reference_clock(
        ec_master_t *master, /**< EtherCAT master. */
        ec_slave_config_t *sc /**< Slave config of the slave to use as the
                               * reference slave (or NULL). */
        );

/** Obtains master information.
 *
 * No memory is allocated on the heap in
 * this function.
 *
 * \attention The pointer to this structure must point to a valid variable.
 *
 * \return 0 in case of success, else < 0
 */
int ecrt_master(
        ec_master_t *master, /**< EtherCAT master */
        ec_master_info_t *master_info /**< Structure that will output the
                                        information */
        );

/** Obtains slave information.
 *
 * Tries to find the slave with the given ring position. The obtained
 * information is stored in a structure. No memory is allocated on the heap in
 * this function.
 *
 * \attention The pointer to this structure must point to a valid variable.
 *
 * \return 0 in case of success, else < 0
 */
int ecrt_master_get_slave(
        ec_master_t *master, /**< EtherCAT master */
        uint16_t slave_position, /**< Slave position. */
        ec_slave_info_t *slave_info /**< Structure that will output the
                                      information */
        );

#ifndef __KERNEL__

/** Returns the proposed configuration of a slave's sync manager.
 *
 * Fills a given ec_sync_info_t structure with the attributes of a sync
 * manager. The \a pdos field of the return value is left empty. Use
 * ecrt_master_get_pdo() to get the PDO information.
 *
 * \return zero on success, else non-zero
 */
int ecrt_master_get_sync_manager(
        ec_master_t *master, /**< EtherCAT master. */
        uint16_t slave_position, /**< Slave position. */
        uint8_t sync_index, /**< Sync manager index. Must be less
                                than #EC_MAX_SYNC_MANAGERS. */
        ec_sync_info_t *sync /**< Pointer to output structure. */
        );

/** Returns information about a currently assigned PDO.
 *
 * Fills a given ec_pdo_info_t structure with the attributes of a currently
 * assigned PDO of the given sync manager. The \a entries field of the return
 * value is left empty. Use ecrt_master_get_pdo_entry() to get the PDO
 * entry information.
 *
 * \retval zero on success, else non-zero
 */
int ecrt_master_get_pdo(
        ec_master_t *master, /**< EtherCAT master. */
        uint16_t slave_position, /**< Slave position. */
        uint8_t sync_index, /**< Sync manager index. Must be less
                                 than #EC_MAX_SYNC_MANAGERS. */
        uint16_t pos, /**< Zero-based PDO position. */
        ec_pdo_info_t *pdo /**< Pointer to output structure. */
        );

/** Returns information about a currently mapped PDO entry.
 *
 * Fills a given ec_pdo_entry_info_t structure with the attributes of a
 * currently mapped PDO entry of the given PDO.
 *
 * \retval zero on success, else non-zero
 */
int ecrt_master_get_pdo_entry(
        ec_master_t *master, /**< EtherCAT master. */
        uint16_t slave_position, /**< Slave position. */
        uint8_t sync_index, /**< Sync manager index. Must be less
                                 than #EC_MAX_SYNC_MANAGERS. */
        uint16_t pdo_pos, /**< Zero-based PDO position. */
        uint16_t entry_pos, /**< Zero-based PDO entry position. */
        ec_pdo_entry_info_t *entry /**< Pointer to output structure. */
        );

#endif /* #ifndef __KERNEL__ */

/** Executes an SDO download request to write data to a slave.
 *
 * This request is processed by the master state machine. This method blocks,
 * until the request has been processed and may not be called in realtime
 * context.
 *
 * \retval  0 Success.
 * \retval <0 Error code.
 */
int ecrt_master_sdo_download(
        ec_master_t *master, /**< EtherCAT master. */
        uint16_t slave_position, /**< Slave position. */
        uint16_t index, /**< Index of the SDO. */
        uint8_t subindex, /**< Subindex of the SDO. */
        uint8_t *data, /**< Data buffer to download. */
        size_t data_size, /**< Size of the data buffer. */
        uint32_t *abort_code /**< Abort code of the SDO download. */
        );

/** Executes an SDO download request to write data to a slave via complete
 * access.
 *
 * This request is processed by the master state machine. This method blocks,
 * until the request has been processed and may not be called in realtime
 * context.
 *
 * \retval  0 Success.
 * \retval <0 Error code.
 */
int ecrt_master_sdo_download_complete(
        ec_master_t *master, /**< EtherCAT master. */
        uint16_t slave_position, /**< Slave position. */
        uint16_t index, /**< Index of the SDO. */
        uint8_t *data, /**< Data buffer to download. */
        size_t data_size, /**< Size of the data buffer. */
        uint32_t *abort_code /**< Abort code of the SDO download. */
        );

/** Executes an SDO upload request to read data from a slave.
 *
 * This request is processed by the master state machine. This method blocks,
 * until the request has been processed and may not be called in realtime
 * context.
 *
 * \retval  0 Success.
 * \retval <0 Error code.
 */
int ecrt_master_sdo_upload(
        ec_master_t *master, /**< EtherCAT master. */
        uint16_t slave_position, /**< Slave position. */
        uint16_t index, /**< Index of the SDO. */
        uint8_t subindex, /**< Subindex of the SDO. */
        uint8_t *target, /**< Target buffer for the upload. */
        size_t target_size, /**< Size of the target buffer. */
        size_t *result_size, /**< Uploaded data size. */
        uint32_t *abort_code /**< Abort code of the SDO upload. */
        );

/** Executes an SoE write request.
 *
 * Starts writing an IDN and blocks until the request was processed, or an
 * error occurred.
 *
 * \retval  0 Success.
 * \retval <0 Error code.
 */
int ecrt_master_write_idn(
        ec_master_t *master, /**< EtherCAT master. */
        uint16_t slave_position, /**< Slave position. */
        uint8_t drive_no, /**< Drive number. */
        uint16_t idn, /**< SoE IDN (see ecrt_slave_config_idn()). */
        uint8_t *data, /**< Pointer to data to write. */
        size_t data_size, /**< Size of data to write. */
        uint16_t *error_code /**< Pointer to variable, where an SoE error code
                               can be stored. */
        );

/** Executes an SoE read request.
 *
 * Starts reading an IDN and blocks until the request was processed, or an
 * error occurred.
 *
 * \retval  0 Success.
 * \retval <0 Error code.
 */
int ecrt_master_read_idn(
        ec_master_t *master, /**< EtherCAT master. */
        uint16_t slave_position, /**< Slave position. */
        uint8_t drive_no, /**< Drive number. */
        uint16_t idn, /**< SoE IDN (see ecrt_slave_config_idn()). */
        uint8_t *target, /**< Pointer to memory where the read data can be
                           stored. */
        size_t target_size, /**< Size of the memory \a target points to. */
        size_t *result_size, /**< Actual size of the received data. */
        uint16_t *error_code /**< Pointer to variable, where an SoE error code
                               can be stored. */
        );

/** Finishes the configuration phase and prepares for cyclic operation.
 *
 * This function tells the master that the configuration phase is finished and
 * the realtime operation will begin. The function allocates internal memory
 * for the domains and calculates the logical FMMU addresses for domain
 * members. It tells the master state machine that the bus configuration is
 * now to be applied.
 *
 * \attention After this function has been called, the realtime application is
 * in charge of cyclically calling ecrt_master_send() and
 * ecrt_master_receive() to ensure bus communication. Before calling this
 * function, the master thread is responsible for that, so these functions may
 * not be called! The method itself allocates memory and should not be called
 * in realtime context.
 *
 * \return 0 in case of success, else < 0
 */
int ecrt_master_activate(
        ec_master_t *master /**< EtherCAT master. */
        );

/** Deactivates the master.
 *
 * Removes the bus configuration. All objects created by
 * ecrt_master_create_domain(), ecrt_master_slave_config(), ecrt_domain_data()
 * ecrt_slave_config_create_sdo_request() and
 * ecrt_slave_config_create_voe_handler() are freed, so pointers to them
 * become invalid.
 *
 * This method should not be called in realtime context.
 */
void ecrt_master_deactivate(
        ec_master_t *master /**< EtherCAT master. */
        );

/** Set interval between calls to ecrt_master_send().
 *
 * This information helps the master to decide, how much data can be appended
 * to a frame by the master state machine. When the master is configured with
 * --enable-hrtimers, this is used to calculate the scheduling of the master
 * thread.
 *
 * \retval 0 on success.
 * \retval <0 Error code.
 */
int ecrt_master_set_send_interval(
        ec_master_t *master, /**< EtherCAT master. */
        size_t send_interval /**< Send interval in us */
        );

/** Sends all datagrams in the queue.
 *
 * This method takes all datagrams, that have been queued for transmission,
 * puts them into frames, and passes them to the Ethernet device for sending.
 *
 * Has to be called cyclically by the application after ecrt_master_activate()
 * has returned.
 */
void ecrt_master_send(
        ec_master_t *master /**< EtherCAT master. */
        );

/** Fetches received frames from the hardware and processes the datagrams.
 *
 * Queries the network device for received frames by calling the interrupt
 * service routine. Extracts received datagrams and dispatches the results to
 * the datagram objects in the queue. Received datagrams, and the ones that
 * timed out, will be marked, and dequeued.
 *
 * Has to be called cyclically by the realtime application after
 * ecrt_master_activate() has returned.
 */
void ecrt_master_receive(
        ec_master_t *master /**< EtherCAT master. */
        );

/** Sends non-application datagrams.
 *
 * This method has to be called in the send callback function passed via
 * ecrt_master_callbacks() to allow the sending of non-application datagrams.
 */
void ecrt_master_send_ext(
        ec_master_t *master /**< EtherCAT master. */
        );

/** Reads the current master state.
 *
 * Stores the master state information in the given \a state structure.
 *
 * This method returns a global state. For the link-specific states in a
 * redundant bus topology, use the ecrt_master_link_state() method.
 */
void ecrt_master_state(
        const ec_master_t *master, /**< EtherCAT master. */
        ec_master_state_t *state /**< Structure to store the information. */
        );

/** Reads the current state of a redundant link.
 *
 * Stores the link state information in the given \a state structure.
 *
 * \return Zero on success, otherwise negative error code.
 */
int ecrt_master_link_state(
        const ec_master_t *master, /**< EtherCAT master. */
        unsigned int dev_idx, /**< Index of the device (0 = main device, 1 =
                                first backup device, ...). */
        ec_master_link_state_t *state /**< Structure to store the information.
                                       */
        );

/** Sets the application time.
 *
 * The master has to know the application's time when operating slaves with
 * distributed clocks. The time is not incremented by the master itself, so
 * this method has to be called cyclically.
 *
 * \attention The first call of this method is used to calculate the phase
 * delay for the slaves' SYNC0/1 interrupts. Either the method has to be
 * called during the realtime cycle *only*, or the first time submitted must
 * be in-phase with the realtime cycle. Otherwise synchronisation problems can
 * occur.
 *
 * The time is used when setting the slaves' <tt>System Time Offset</tt> and
 * <tt>Cyclic Operation Start Time</tt> registers and when synchronizing the
 * DC reference clock to the application time via
 * ecrt_master_sync_reference_clock().
 *
 * The time is defined as nanoseconds from 2000-01-01 00:00. Converting an
 * epoch time can be done with the EC_TIMEVAL2NANO() macro.
 */
void ecrt_master_application_time(
        ec_master_t *master, /**< EtherCAT master. */
        uint64_t app_time /**< Application time. */
        );

/** Queues the DC reference clock drift compensation datagram for sending.
 *
 * The reference clock will by synchronized to the application time provided
 * by the last call off ecrt_master_application_time().
 */
void ecrt_master_sync_reference_clock(
        ec_master_t *master /**< EtherCAT master. */
        );

/** Queues the DC clock drift compensation datagram for sending.
 *
 * All slave clocks synchronized to the reference clock.
 */
void ecrt_master_sync_slave_clocks(
        ec_master_t *master /**< EtherCAT master. */
        );

/** Get the lower 32 bit of the reference clock system time.
 *
 * This method can be used to synchronize the master to the reference clock.
 *
 * The reference clock system time is queried via the
 * ecrt_master_sync_slave_clocks() method, that reads the system time of the
 * reference clock and writes it to the slave clocks (so be sure to call it
 * cyclically to get valid data).
 *
 * \attention The returned time is the system time of the reference clock
 * minus the transmission delay of the reference clock.
 *
 * \retval 0 success, system time was written into \a time.
 * \retval -ENXIO No reference clock found.
 * \retval -EIO Slave synchronization datagram was not received.
 */
int ecrt_master_reference_clock_time(
        ec_master_t *master, /**< EtherCAT master. */
        uint32_t *time /**< Pointer to store the queried system time. */
        );

/** Queues the DC synchrony monitoring datagram for sending.
 *
 * The datagram broadcast-reads all "System time difference" registers (\a
 * 0x092c) to get an upper estimation of the DC synchrony. The result can be
 * checked with the ecrt_master_sync_monitor_process() method.
 */
void ecrt_master_sync_monitor_queue(
        ec_master_t *master /**< EtherCAT master. */
        );

/** Processes the DC synchrony monitoring datagram.
 *
 * If the sync monitoring datagram was sent before with
 * ecrt_master_sync_monitor_queue(), the result can be queried with this
 * method.
 *
 * \return Upper estimation of the maximum time difference in ns.
 */
uint32_t ecrt_master_sync_monitor_process(
        ec_master_t *master /**< EtherCAT master. */
        );

/** Retry configuring slaves.
 *
 * Via this method, the application can tell the master to bring all slaves to
 * OP state. In general, this is not necessary, because it is automatically
 * done by the master. But with special slaves, that can be reconfigured by
 * the vendor during runtime, it can be useful.
 */
void ecrt_master_reset(
        ec_master_t *master /**< EtherCAT master. */
        );

/******************************************************************************
 * Slave configuration methods
 *****************************************************************************/

/** Configure a sync manager.
 *
 * Sets the direction of a sync manager. This overrides the direction bits
 * from the default control register from SII.
 *
 * This method has to be called in non-realtime context before
 * ecrt_master_activate().
 *
 * \return zero on success, else non-zero
 */
int ecrt_slave_config_sync_manager(
        ec_slave_config_t *sc, /**< Slave configuration. */
        uint8_t sync_index, /**< Sync manager index. Must be less
                              than #EC_MAX_SYNC_MANAGERS. */
        ec_direction_t direction, /**< Input/Output. */
        ec_watchdog_mode_t watchdog_mode /** Watchdog mode. */
        );

/** Configure a slave's watchdog times.
 *
 * This method has to be called in non-realtime context before
 * ecrt_master_activate().
 */
void ecrt_slave_config_watchdog(
        ec_slave_config_t *sc, /**< Slave configuration. */
        uint16_t watchdog_divider, /**< Number of 40 ns intervals. Used as a
                                     base unit for all slave watchdogs. If set
                                     to zero, the value is not written, so the
                                     default is used. */
        uint16_t watchdog_intervals /**< Number of base intervals for process
                                      data watchdog. If set to zero, the value
                                      is not written, so the default is used.
                                     */
        );

/** Add a PDO to a sync manager's PDO assignment.
 *
 * This method has to be called in non-realtime context before
 * ecrt_master_activate().
 *
 * \see ecrt_slave_config_pdos()
 * \return zero on success, else non-zero
 */
int ecrt_slave_config_pdo_assign_add(
        ec_slave_config_t *sc, /**< Slave configuration. */
        uint8_t sync_index, /**< Sync manager index. Must be less
                              than #EC_MAX_SYNC_MANAGERS. */
        uint16_t index /**< Index of the PDO to assign. */
        );

/** Clear a sync manager's PDO assignment.
 *
 * This can be called before assigning PDOs via
 * ecrt_slave_config_pdo_assign_add(), to clear the default assignment of a
 * sync manager.
 *
 * This method has to be called in non-realtime context before
 * ecrt_master_activate().
 *
 * \see ecrt_slave_config_pdos()
 */
void ecrt_slave_config_pdo_assign_clear(
        ec_slave_config_t *sc, /**< Slave configuration. */
        uint8_t sync_index /**< Sync manager index. Must be less
                              than #EC_MAX_SYNC_MANAGERS. */
        );

/** Add a PDO entry to the given PDO's mapping.
 *
 * This method has to be called in non-realtime context before
 * ecrt_master_activate().
 *
 * \see ecrt_slave_config_pdos()
 * \return zero on success, else non-zero
 */
int ecrt_slave_config_pdo_mapping_add(
        ec_slave_config_t *sc, /**< Slave configuration. */
        uint16_t pdo_index, /**< Index of the PDO. */
        uint16_t entry_index, /**< Index of the PDO entry to add to the PDO's
                                mapping. */
        uint8_t entry_subindex, /**< Subindex of the PDO entry to add to the
                                  PDO's mapping. */
        uint8_t entry_bit_length /**< Size of the PDO entry in bit. */
        );

/** Clear the mapping of a given PDO.
 *
 * This can be called before mapping PDO entries via
 * ecrt_slave_config_pdo_mapping_add(), to clear the default mapping.
 *
 * This method has to be called in non-realtime context before
 * ecrt_master_activate().
 *
 * \see ecrt_slave_config_pdos()
 */
void ecrt_slave_config_pdo_mapping_clear(
        ec_slave_config_t *sc, /**< Slave configuration. */
        uint16_t pdo_index /**< Index of the PDO. */
        );

/** Specify a complete PDO configuration.
 *
 * This function is a convenience wrapper for the functions
 * ecrt_slave_config_sync_manager(), ecrt_slave_config_pdo_assign_clear(),
 * ecrt_slave_config_pdo_assign_add(), ecrt_slave_config_pdo_mapping_clear()
 * and ecrt_slave_config_pdo_mapping_add(), that are better suitable for
 * automatic code generation.
 *
 * The following example shows, how to specify a complete configuration,
 * including the PDO mappings. With this information, the master is able to
 * reserve the complete process data, even if the slave is not present at
 * configuration time:
 *
 * \code
 * ec_pdo_entry_info_t el3162_channel1[] = {
 *     {0x3101, 1,  8}, // status
 *     {0x3101, 2, 16}  // value
 * };
 *
 * ec_pdo_entry_info_t el3162_channel2[] = {
 *     {0x3102, 1,  8}, // status
 *     {0x3102, 2, 16}  // value
 * };
 *
 * ec_pdo_info_t el3162_pdos[] = {
 *     {0x1A00, 2, el3162_channel1},
 *     {0x1A01, 2, el3162_channel2}
 * };
 *
 * ec_sync_info_t el3162_syncs[] = {
 *     {2, EC_DIR_OUTPUT},
 *     {3, EC_DIR_INPUT, 2, el3162_pdos},
 *     {0xff}
 * };
 *
 * if (ecrt_slave_config_pdos(sc_ana_in, EC_END, el3162_syncs)) {
 *     // handle error
 * }
 * \endcode
 *
 * The next example shows, how to configure the PDO assignment only. The
 * entries for each assigned PDO are taken from the PDO's default mapping.
 * Please note, that PDO entry registration will fail, if the PDO
 * configuration is left empty and the slave is offline.
 *
 * \code
 * ec_pdo_info_t pdos[] = {
 *     {0x1600}, // Channel 1
 *     {0x1601}  // Channel 2
 * };
 *
 * ec_sync_info_t syncs[] = {
 *     {3, EC_DIR_INPUT, 2, pdos},
 * };
 *
 * if (ecrt_slave_config_pdos(slave_config_ana_in, 1, syncs)) {
 *     // handle error
 * }
 * \endcode
 *
 * Processing of \a syncs will stop, if
 * - the number of processed items reaches \a n_syncs, or
 * - the \a index member of an ec_sync_info_t item is 0xff. In this case,
 *   \a n_syncs should set to a number greater than the number of list items;
 *   using EC_END is recommended.
 *
 * This method has to be called in non-realtime context before
 * ecrt_master_activate().
 *
 * \return zero on success, else non-zero
 */
int ecrt_slave_config_pdos(
        ec_slave_config_t *sc, /**< Slave configuration. */
        unsigned int n_syncs, /**< Number of sync manager configurations in
                                \a syncs. */
        const ec_sync_info_t syncs[] /**< Array of sync manager
                                       configurations. */
        );

/** Registers a PDO entry for process data exchange in a domain.
 *
 * Searches the assigned PDOs for the given PDO entry. An error is raised, if
 * the given entry is not mapped. Otherwise, the corresponding sync manager
 * and FMMU configurations are provided for slave configuration and the
 * respective sync manager's assigned PDOs are appended to the given domain,
 * if not already done. The offset of the requested PDO entry's data inside
 * the domain's process data is returned. Optionally, the PDO entry bit
 * position (0-7) can be retrieved via the \a bit_position output parameter.
 * This pointer may be \a NULL, in this case an error is raised if the PDO
 * entry does not byte-align.
 *
 * This method has to be called in non-realtime context before
 * ecrt_master_activate().
 *
 * \retval >=0 Success: Offset of the PDO entry's process data.
 * \retval  <0 Error code.
 */
int ecrt_slave_config_reg_pdo_entry(
        ec_slave_config_t *sc, /**< Slave configuration. */
        uint16_t entry_index, /**< Index of the PDO entry to register. */
        uint8_t entry_subindex, /**< Subindex of the PDO entry to register. */
        ec_domain_t *domain, /**< Domain. */
        unsigned int *bit_position /**< Optional address if bit addressing
                                 is desired */
        );

/** Registers a PDO entry using its position.
 *
 * Similar to ecrt_slave_config_reg_pdo_entry(), but not using PDO indices but
 * offsets in the PDO mapping, because PDO entry indices may not be unique
 * inside a slave's PDO mapping. An error is raised, if
 * one of the given positions is out of range.
 *
 * This method has to be called in non-realtime context before
 * ecrt_master_activate().
 *
 * \retval >=0 Success: Offset of the PDO entry's process data.
 * \retval  <0 Error code.
 */
int ecrt_slave_config_reg_pdo_entry_pos(
        ec_slave_config_t *sc, /**< Slave configuration. */
        uint8_t sync_index, /**< Sync manager index. */
        unsigned int pdo_pos, /**< Position of the PDO inside the SM. */
        unsigned int entry_pos, /**< Position of the entry inside the PDO. */
        ec_domain_t *domain, /**< Domain. */
        unsigned int *bit_position /**< Optional address if bit addressing
                                 is desired */
        );

/** Configure distributed clocks.
 *
 * Sets the AssignActivate word and the cycle and shift times for the sync
 * signals.
 *
 * The AssignActivate word is vendor-specific and can be taken from the XML
 * device description file (Device -> Dc -> AssignActivate). Set this to zero,
 * if the slave shall be operated without distributed clocks (default).
 *
 * This method has to be called in non-realtime context before
 * ecrt_master_activate().
 *
 * \attention The \a sync1_shift time is ignored.
 */
void ecrt_slave_config_dc(
        ec_slave_config_t *sc, /**< Slave configuration. */
        uint16_t assign_activate, /**< AssignActivate word. */
        uint32_t sync0_cycle, /**< SYNC0 cycle time [ns]. */
        int32_t sync0_shift, /**< SYNC0 shift time [ns]. */
        uint32_t sync1_cycle, /**< SYNC1 cycle time [ns]. */
        int32_t sync1_shift /**< SYNC1 shift time [ns]. */
        );

/** Add an SDO configuration.
 *
 * An SDO configuration is stored in the slave configuration object and is
 * downloaded to the slave whenever the slave is being configured by the
 * master. This usually happens once on master activation, but can be repeated
 * subsequently, for example after the slave's power supply failed.
 *
 * \attention The SDOs for PDO assignment (\p 0x1C10 - \p 0x1C2F) and PDO
 * mapping (\p 0x1600 - \p 0x17FF and \p 0x1A00 - \p 0x1BFF) should not be
 * configured with this function, because they are part of the slave
 * configuration done by the master. Please use ecrt_slave_config_pdos() and
 * friends instead.
 *
 * This is the generic function for adding an SDO configuration. Please note
 * that the this function does not do any endianness correction. If
 * datatype-specific functions are needed (that automatically correct the
 * endianness), have a look at ecrt_slave_config_sdo8(),
 * ecrt_slave_config_sdo16() and ecrt_slave_config_sdo32().
 *
 * This method has to be called in non-realtime context before
 * ecrt_master_activate().
 *
 * \retval  0 Success.
 * \retval <0 Error code.
 */
int ecrt_slave_config_sdo(
        ec_slave_config_t *sc, /**< Slave configuration. */
        uint16_t index, /**< Index of the SDO to configure. */
        uint8_t subindex, /**< Subindex of the SDO to configure. */
        const uint8_t *data, /**< Pointer to the data. */
        size_t size /**< Size of the \a data. */
        );

/** Add a configuration value for an 8-bit SDO.
 *
 * This method has to be called in non-realtime context before
 * ecrt_master_activate().
 *
 * \see ecrt_slave_config_sdo().
 *
 * \retval  0 Success.
 * \retval <0 Error code.
 */
int ecrt_slave_config_sdo8(
        ec_slave_config_t *sc, /**< Slave configuration */
        uint16_t sdo_index, /**< Index of the SDO to configure. */
        uint8_t sdo_subindex, /**< Subindex of the SDO to configure. */
        uint8_t value /**< Value to set. */
        );

/** Add a configuration value for a 16-bit SDO.
 *
 * This method has to be called in non-realtime context before
 * ecrt_master_activate().
 *
 * \see ecrt_slave_config_sdo().
 *
 * \retval  0 Success.
 * \retval <0 Error code.
 */
int ecrt_slave_config_sdo16(
        ec_slave_config_t *sc, /**< Slave configuration */
        uint16_t sdo_index, /**< Index of the SDO to configure. */
        uint8_t sdo_subindex, /**< Subindex of the SDO to configure. */
        uint16_t value /**< Value to set. */
        );

/** Add a configuration value for a 32-bit SDO.
 *
 * This method has to be called in non-realtime context before
 * ecrt_master_activate().
 *
 * \see ecrt_slave_config_sdo().
 *
 * \retval  0 Success.
 * \retval <0 Error code.
 */
int ecrt_slave_config_sdo32(
        ec_slave_config_t *sc, /**< Slave configuration */
        uint16_t sdo_index, /**< Index of the SDO to configure. */
        uint8_t sdo_subindex, /**< Subindex of the SDO to configure. */
        uint32_t value /**< Value to set. */
        );

/** Add configuration data for a complete SDO.
 *
 * The SDO data are transferred via CompleteAccess. Data for the first
 * subindex (0) have to be included.
 *
 * This method has to be called in non-realtime context before
 * ecrt_master_activate().
 *
 * \see ecrt_slave_config_sdo().
 *
 * \retval  0 Success.
 * \retval <0 Error code.
 */
int ecrt_slave_config_complete_sdo(
        ec_slave_config_t *sc, /**< Slave configuration. */
        uint16_t index, /**< Index of the SDO to configure. */
        const uint8_t *data, /**< Pointer to the data. */
        size_t size /**< Size of the \a data. */
        );

/** Set the size of the CoE emergency ring buffer.
 *
 * The initial size is zero, so all messages will be dropped. This method can
 * be called even after master activation, but it will clear the ring buffer!
 *
 * This method has to be called in non-realtime context before
 * ecrt_master_activate().
 *
 * \return 0 on success, or negative error code.
 */
int ecrt_slave_config_emerg_size(
        ec_slave_config_t *sc, /**< Slave configuration. */
        size_t elements /**< Number of records of the CoE emergency ring. */
        );

/** Read and remove one record from the CoE emergency ring buffer.
 *
 * A record consists of 8 bytes:
 *
 * Byte 0-1: Error code (little endian)
 * Byte   2: Error register
 * Byte 3-7: Data
 *
 * \return 0 on success (record popped), or negative error code (i. e.
 * -ENOENT, if ring is empty).
 */
int ecrt_slave_config_emerg_pop(
        ec_slave_config_t *sc, /**< Slave configuration. */
        uint8_t *target /**< Pointer to target memory (at least
                          EC_COE_EMERGENCY_MSG_SIZE bytes). */
        );

/** Clears CoE emergency ring buffer and the overrun counter.
 *
 * \return 0 on success, or negative error code.
 */
int ecrt_slave_config_emerg_clear(
        ec_slave_config_t *sc /**< Slave configuration. */
        );

/** Read the number of CoE emergency overruns.
 *
 * The overrun counter will be incremented when a CoE emergency message could
 * not be stored in the ring buffer and had to be dropped. Call
 * ecrt_slave_config_emerg_clear() to reset the counter.
 *
 * \return Number of overruns since last clear, or negative error code.
 */
int ecrt_slave_config_emerg_overruns(
        ec_slave_config_t *sc /**< Slave configuration. */
        );

/** Create an SDO request to exchange SDOs during realtime operation.
 *
 * The created SDO request object is freed automatically when the master is
 * released.
 *
 * This method has to be called in non-realtime context before
 * ecrt_master_activate().
 *
 * \return New SDO request, or NULL on error.
 */
ec_sdo_request_t *ecrt_slave_config_create_sdo_request(
        ec_slave_config_t *sc, /**< Slave configuration. */
        uint16_t index, /**< SDO index. */
        uint8_t subindex, /**< SDO subindex. */
        size_t size /**< Data size to reserve. */
        );

/** Create an VoE handler to exchange vendor-specific data during realtime
 * operation.
 *
 * The number of VoE handlers per slave configuration is not limited, but
 * usually it is enough to create one for sending and one for receiving, if
 * both can be done simultaneously.
 *
 * The created VoE handler object is freed automatically when the master is
 * released.
 *
 * This method has to be called in non-realtime context before
 * ecrt_master_activate().
 *
 * \return New VoE handler, or NULL on error.
 */
ec_voe_handler_t *ecrt_slave_config_create_voe_handler(
        ec_slave_config_t *sc, /**< Slave configuration. */
        size_t size /**< Data size to reserve. */
        );

/** Create a register request to exchange EtherCAT register contents during
 * realtime operation.
 *
 * This interface should not be used to take over master functionality,
 * instead it is intended for debugging and monitoring reasons.
 *
 * The created register request object is freed automatically when the master
 * is released.
 *
 * This method has to be called in non-realtime context before
 * ecrt_master_activate().
 *
 * \return New register request, or NULL on error.
 */
ec_reg_request_t *ecrt_slave_config_create_reg_request(
        ec_slave_config_t *sc, /**< Slave configuration. */
        size_t size /**< Data size to reserve. */
        );

/** Outputs the state of the slave configuration.
 *
 * Stores the state information in the given \a state structure. The state
 * information is updated by the master state machine, so it may take a few
 * cycles, until it changes.
 *
 * \attention If the state of process data exchange shall be monitored in
 * realtime, ecrt_domain_state() should be used.
 */
void ecrt_slave_config_state(
        const ec_slave_config_t *sc, /**< Slave configuration */
        ec_slave_config_state_t *state /**< State object to write to. */
        );

/** Add an SoE IDN configuration.
 *
 * A configuration for a Sercos-over-EtherCAT IDN is stored in the slave
 * configuration object and is written to the slave whenever the slave is
 * being configured by the master. This usually happens once on master
 * activation, but can be repeated subsequently, for example after the slave's
 * power supply failed.
 *
 * The \a idn parameter can be separated into several sections:
 *  - Bit 15: Standard data (0) or Product data (1)
 *  - Bit 14 - 12: Parameter set (0 - 7)
 *  - Bit 11 - 0: Data block number (0 - 4095)
 *
 * Please note that the this function does not do any endianness correction.
 * Multi-byte data have to be passed in EtherCAT endianness (little-endian).
 *
 * This method has to be called in non-realtime context before
 * ecrt_master_activate().
 *
 * \retval  0 Success.
 * \retval <0 Error code.
 */
int ecrt_slave_config_idn(
        ec_slave_config_t *sc, /**< Slave configuration. */
        uint8_t drive_no, /**< Drive number. */
        uint16_t idn, /**< SoE IDN. */
        ec_al_state_t state, /**< AL state in which to write the IDN (PREOP or
                               SAFEOP). */
        const uint8_t *data, /**< Pointer to the data. */
        size_t size /**< Size of the \a data. */
        );

/******************************************************************************
 * Domain methods
 *****************************************************************************/

/** Registers a bunch of PDO entries for a domain.
 *
 * This method has to be called in non-realtime context before
 * ecrt_master_activate().
 *
 * \see ecrt_slave_config_reg_pdo_entry()
 *
 * \attention The registration array has to be terminated with an empty
 *            structure, or one with the \a index field set to zero!
 * \return 0 on success, else non-zero.
 */
int ecrt_domain_reg_pdo_entry_list(
        ec_domain_t *domain, /**< Domain. */
        const ec_pdo_entry_reg_t *pdo_entry_regs /**< Array of PDO
                                                   registrations. */
        );

/** Returns the current size of the domain's process data.
 *
 * \return Size of the process data image, or a negative error code.
 */
size_t ecrt_domain_size(
        const ec_domain_t *domain /**< Domain. */
        );

#ifdef __KERNEL__

/** Provide external memory to store the domain's process data.
 *
 * Call this after all PDO entries have been registered and before activating
 * the master.
 *
 * The size of the allocated memory must be at least ecrt_domain_size(), after
 * all PDO entries have been registered.
 *
 * This method has to be called in non-realtime context before
 * ecrt_master_activate().
 *
 */
void ecrt_domain_external_memory(
        ec_domain_t *domain, /**< Domain. */
        uint8_t *memory /**< Address of the memory to store the process
                          data in. */
        );

#endif /* __KERNEL__ */

/** Returns the domain's process data.
 *
 * - In kernel context: If external memory was provided with
 * ecrt_domain_external_memory(), the returned pointer will contain the
 * address of that memory. Otherwise it will point to the internally allocated
 * memory. In the latter case, this method may not be called before
 * ecrt_master_activate().
 *
 * - In userspace context: This method has to be called after
 * ecrt_master_activate() to get the mapped domain process data memory.
 *
 * \return Pointer to the process data memory.
 */
uint8_t *ecrt_domain_data(
        ec_domain_t *domain /**< Domain. */
        );

/** Determines the states of the domain's datagrams.
 *
 * Evaluates the working counters of the received datagrams and outputs
 * statistics, if necessary. This must be called after ecrt_master_receive()
 * is expected to receive the domain datagrams in order to make
 * ecrt_domain_state() return the result of the last process data exchange.
 */
void ecrt_domain_process(
        ec_domain_t *domain /**< Domain. */
        );

/** (Re-)queues all domain datagrams in the master's datagram queue.
 *
 * Call this function to mark the domain's datagrams for exchanging at the
 * next call of ecrt_master_send().
 */
void ecrt_domain_queue(
        ec_domain_t *domain /**< Domain. */
        );

/** Reads the state of a domain.
 *
 * Stores the domain state in the given \a state structure.
 *
 * Using this method, the process data exchange can be monitored in realtime.
 */
void ecrt_domain_state(
        const ec_domain_t *domain, /**< Domain. */
        ec_domain_state_t *state /**< Pointer to a state object to store the
                                   information. */
        );

/*****************************************************************************
 * SDO request methods.
 ****************************************************************************/

/** Set the SDO index and subindex.
 *
 * \attention If the SDO index and/or subindex is changed while
 * ecrt_sdo_request_state() returns EC_REQUEST_BUSY, this may lead to
 * unexpected results.
 */
void ecrt_sdo_request_index(
        ec_sdo_request_t *req, /**< SDO request. */
        uint16_t index, /**< SDO index. */
        uint8_t subindex /**< SDO subindex. */
        );

/** Set the timeout for an SDO request.
 *
 * If the request cannot be processed in the specified time, if will be marked
 * as failed.
 *
 * The timeout is permanently stored in the request object and is valid until
 * the next call of this method.
 */
void ecrt_sdo_request_timeout(
        ec_sdo_request_t *req, /**< SDO request. */
        uint32_t timeout /**< Timeout in milliseconds. Zero means no
                           timeout. */
        );

/** Access to the SDO request's data.
 *
 * This function returns a pointer to the request's internal SDO data memory.
 *
 * - After a read operation was successful, integer data can be evaluated using
 *   the EC_READ_*() macros as usual. Example:
 *   \code
 *   uint16_t value = EC_READ_U16(ecrt_sdo_request_data(sdo)));
 *   \endcode
 * - If a write operation shall be triggered, the data have to be written to
 *   the internal memory. Use the EC_WRITE_*() macros, if you are writing
 *   integer data. Be sure, that the data fit into the memory. The memory size
 *   is a parameter of ecrt_slave_config_create_sdo_request().
 *   \code
 *   EC_WRITE_U16(ecrt_sdo_request_data(sdo), 0xFFFF);
 *   \endcode
 *
 * \attention The return value can be invalid during a read operation, because
 * the internal SDO data memory could be re-allocated if the read SDO data do
 * not fit inside.
 *
 * \return Pointer to the internal SDO data memory.
 */
uint8_t *ecrt_sdo_request_data(
        ec_sdo_request_t *req /**< SDO request. */
        );

/** Returns the current SDO data size.
 *
 * When the SDO request is created, the data size is set to the size of the
 * reserved memory. After a read operation the size is set to the size of the
 * read data. The size is not modified in any other situation.
 *
 * \return SDO data size in bytes.
 */
size_t ecrt_sdo_request_data_size(
        const ec_sdo_request_t *req /**< SDO request. */
        );

/** Get the current state of the SDO request.
 *
 * \return Request state.
 */
#ifdef __KERNEL__
ec_request_state_t ecrt_sdo_request_state(
        const ec_sdo_request_t *req /**< SDO request. */
    );
#else
ec_request_state_t ecrt_sdo_request_state(
        ec_sdo_request_t *req /**< SDO request. */
    );
#endif

/** Schedule an SDO write operation.
 *
 * \attention This method may not be called while ecrt_sdo_request_state()
 * returns EC_REQUEST_BUSY.
 */
void ecrt_sdo_request_write(
        ec_sdo_request_t *req /**< SDO request. */
        );

/** Schedule an SDO read operation.
 *
 * \attention This method may not be called while ecrt_sdo_request_state()
 * returns EC_REQUEST_BUSY.
 *
 * \attention After calling this function, the return value of
 * ecrt_sdo_request_data() must be considered as invalid while
 * ecrt_sdo_request_state() returns EC_REQUEST_BUSY.
 */
void ecrt_sdo_request_read(
        ec_sdo_request_t *req /**< SDO request. */
        );

/*****************************************************************************
 * VoE handler methods.
 ****************************************************************************/

/** Sets the VoE header for future send operations.
 *
 * A VoE message shall contain a 4-byte vendor ID, followed by a 2-byte vendor
 * type at as header. These numbers can be set with this function. The values
 * are valid and will be used for future send operations until the next call
 * of this method.
 */
void ecrt_voe_handler_send_header(
        ec_voe_handler_t *voe, /**< VoE handler. */
        uint32_t vendor_id, /**< Vendor ID. */
        uint16_t vendor_type /**< Vendor-specific type. */
        );

/** Reads the header data of a received VoE message.
 *
 * This method can be used to get the received VoE header information after a
 * read operation has succeeded.
 *
 * The header information is stored at the memory given by the pointer
 * parameters.
 */
void ecrt_voe_handler_received_header(
        const ec_voe_handler_t *voe, /**< VoE handler. */
        uint32_t *vendor_id, /**< Vendor ID. */
        uint16_t *vendor_type /**< Vendor-specific type. */
        );

/** Access to the VoE handler's data.
 *
 * This function returns a pointer to the VoE handler's internal memory, that
 * points to the actual VoE data right after the VoE header (see
 * ecrt_voe_handler_send_header()).
 *
 * - After a read operation was successful, the memory contains the received
 *   data. The size of the received data can be determined via
 *   ecrt_voe_handler_data_size().
 * - Before a write operation is triggered, the data have to be written to the
 *   internal memory. Be sure, that the data fit into the memory. The reserved
 *   memory size is a parameter of ecrt_slave_config_create_voe_handler().
 *
 * \attention The returned pointer is not necessarily persistent: After a read
 * operation, the internal memory may have been reallocated. This can be
 * avoided by reserving enough memory via the \a size parameter of
 * ecrt_slave_config_create_voe_handler().
 *
 * \return Pointer to the internal memory.
 */
uint8_t *ecrt_voe_handler_data(
        ec_voe_handler_t *voe /**< VoE handler. */
        );

/** Returns the current data size.
 *
 * The data size is the size of the VoE data without the header (see
 * ecrt_voe_handler_send_header()).
 *
 * When the VoE handler is created, the data size is set to the size of the
 * reserved memory. At a write operation, the data size is set to the number
 * of bytes to write. After a read operation the size is set to the size of
 * the read data. The size is not modified in any other situation.
 *
 * \return Data size in bytes.
 */
size_t ecrt_voe_handler_data_size(
        const ec_voe_handler_t *voe /**< VoE handler. */
        );

/** Start a VoE write operation.
 *
 * After this function has been called, the ecrt_voe_handler_execute() method
 * must be called in every bus cycle as long as it returns EC_REQUEST_BUSY. No
 * other operation may be started while the handler is busy.
 */
void ecrt_voe_handler_write(
        ec_voe_handler_t *voe, /**< VoE handler. */
        size_t size /**< Number of bytes to write (without the VoE header). */
        );

/** Start a VoE read operation.
 *
 * After this function has been called, the ecrt_voe_handler_execute() method
 * must be called in every bus cycle as long as it returns EC_REQUEST_BUSY. No
 * other operation may be started while the handler is busy.
 *
 * The state machine queries the slave's send mailbox for new data to be send
 * to the master. If no data appear within the EC_VOE_RESPONSE_TIMEOUT
 * (defined in master/voe_handler.c), the operation fails.
 *
 * On success, the size of the read data can be determined via
 * ecrt_voe_handler_data_size(), while the VoE header of the received data
 * can be retrieved with ecrt_voe_handler_received_header().
 */
void ecrt_voe_handler_read(
        ec_voe_handler_t *voe /**< VoE handler. */
        );

/** Start a VoE read operation without querying the sync manager status.
 *
 * After this function has been called, the ecrt_voe_handler_execute() method
 * must be called in every bus cycle as long as it returns EC_REQUEST_BUSY. No
 * other operation may be started while the handler is busy.
 *
 * The state machine queries the slave by sending an empty mailbox. The slave
 * fills its data to the master in this mailbox. If no data appear within the
 * EC_VOE_RESPONSE_TIMEOUT (defined in master/voe_handler.c), the operation
 * fails.
 *
 * On success, the size of the read data can be determined via
 * ecrt_voe_handler_data_size(), while the VoE header of the received data
 * can be retrieved with ecrt_voe_handler_received_header().
 */
void ecrt_voe_handler_read_nosync(
        ec_voe_handler_t *voe /**< VoE handler. */
        );

/** Execute the handler.
 *
 * This method executes the VoE handler. It has to be called in every bus
 * cycle as long as it returns EC_REQUEST_BUSY.
 *
 * \return Handler state.
 */
ec_request_state_t ecrt_voe_handler_execute(
    ec_voe_handler_t *voe /**< VoE handler. */
    );

/*****************************************************************************
 * Register request methods.
 ****************************************************************************/

/** Access to the register request's data.
 *
 * This function returns a pointer to the request's internal memory.
 *
 * - After a read operation was successful, integer data can be evaluated
 *   using the EC_READ_*() macros as usual. Example:
 *   \code
 *   uint16_t value = EC_READ_U16(ecrt_reg_request_data(reg_request)));
 *   \endcode
 * - If a write operation shall be triggered, the data have to be written to
 *   the internal memory. Use the EC_WRITE_*() macros, if you are writing
 *   integer data. Be sure, that the data fit into the memory. The memory size
 *   is a parameter of ecrt_slave_config_create_reg_request().
 *   \code
 *   EC_WRITE_U16(ecrt_reg_request_data(reg_request), 0xFFFF);
 *   \endcode
 *
 * \return Pointer to the internal memory.
 */
uint8_t *ecrt_reg_request_data(
        ec_reg_request_t *req /**< Register request. */
        );

/** Get the current state of the register request.
 *
 * \return Request state.
 */
#ifdef __KERNEL__
ec_request_state_t ecrt_reg_request_state(
        const ec_reg_request_t *req /**< Register request. */
    );
#else
ec_request_state_t ecrt_reg_request_state(
        ec_reg_request_t *req /**< Register request. */
    );
#endif

/** Schedule an register write operation.
 *
 * \attention This method may not be called while ecrt_reg_request_state()
 * returns EC_REQUEST_BUSY.
 *
 * \attention The \a size parameter is truncated to the size given at request
 * creation.
 */
void ecrt_reg_request_write(
        ec_reg_request_t *req, /**< Register request. */
        uint16_t address, /**< Register address. */
        size_t size /**< Size to write. */
        );

/** Schedule a register read operation.
 *
 * \attention This method may not be called while ecrt_reg_request_state()
 * returns EC_REQUEST_BUSY.
 *
 * \attention The \a size parameter is truncated to the size given at request
 * creation.
 */
void ecrt_reg_request_read(
        ec_reg_request_t *req, /**< Register request. */
        uint16_t address, /**< Register address. */
        size_t size /**< Size to write. */
        );

/*****************************************************************************/

#ifdef __cplusplus
}
#endif

/******************************************************************************
 * Bitwise read/write macros
 *****************************************************************************/

/** Read a certain bit of an EtherCAT data byte.
 *
 * \param DATA EtherCAT data pointer
 * \param POS bit position
 */
#define EC_READ_BIT(DATA, POS) ((*((uint8_t *) (DATA)) >> (POS)) & 0x01)

/** Write a certain bit of an EtherCAT data byte.
 *
 * \param DATA EtherCAT data pointer
 * \param POS bit position
 * \param VAL new bit value
 */
#define EC_WRITE_BIT(DATA, POS, VAL) \
    do { \
        if (VAL) *((uint8_t *) (DATA)) |=  (1 << (POS)); \
        else     *((uint8_t *) (DATA)) &= ~(1 << (POS)); \
    } while (0)

/******************************************************************************
 * Byte-swapping functions for user space
 *****************************************************************************/

#ifndef __KERNEL__

#if __BYTE_ORDER == __LITTLE_ENDIAN

#define le16_to_cpu(x) x
#define le32_to_cpu(x) x
#define le64_to_cpu(x) x

#define cpu_to_le16(x) x
#define cpu_to_le32(x) x
#define cpu_to_le64(x) x

#elif __BYTE_ORDER == __BIG_ENDIAN

#define swap16(x) \
        ((uint16_t)( \
        (((uint16_t)(x) & 0x00ffU) << 8) | \
        (((uint16_t)(x) & 0xff00U) >> 8) ))
#define swap32(x) \
        ((uint32_t)( \
        (((uint32_t)(x) & 0x000000ffUL) << 24) | \
        (((uint32_t)(x) & 0x0000ff00UL) <<  8) | \
        (((uint32_t)(x) & 0x00ff0000UL) >>  8) | \
        (((uint32_t)(x) & 0xff000000UL) >> 24) ))
#define swap64(x) \
        ((uint64_t)( \
        (((uint64_t)(x) & 0x00000000000000ffULL) << 56) | \
        (((uint64_t)(x) & 0x000000000000ff00ULL) << 40) | \
        (((uint64_t)(x) & 0x0000000000ff0000ULL) << 24) | \
        (((uint64_t)(x) & 0x00000000ff000000ULL) <<  8) | \
        (((uint64_t)(x) & 0x000000ff00000000ULL) >>  8) | \
        (((uint64_t)(x) & 0x0000ff0000000000ULL) >> 24) | \
        (((uint64_t)(x) & 0x00ff000000000000ULL) >> 40) | \
        (((uint64_t)(x) & 0xff00000000000000ULL) >> 56) ))

#define le16_to_cpu(x) swap16(x)
#define le32_to_cpu(x) swap32(x)
#define le64_to_cpu(x) swap64(x)

#define cpu_to_le16(x) swap16(x)
#define cpu_to_le32(x) swap32(x)
#define cpu_to_le64(x) swap64(x)

#endif

#define le16_to_cpup(x) le16_to_cpu(*((uint16_t *)(x)))
#define le32_to_cpup(x) le32_to_cpu(*((uint32_t *)(x)))
#define le64_to_cpup(x) le64_to_cpu(*((uint64_t *)(x)))

#endif /* ifndef __KERNEL__ */

/******************************************************************************
 * Read macros
 *****************************************************************************/

/** Read an 8-bit unsigned value from EtherCAT data.
 *
 * \return EtherCAT data value
 */
#define EC_READ_U8(DATA) \
    ((uint8_t) *((uint8_t *) (DATA)))

/** Read an 8-bit signed value from EtherCAT data.
 *
 * \param DATA EtherCAT data pointer
 * \return EtherCAT data value
 */
#define EC_READ_S8(DATA) \
     ((int8_t) *((uint8_t *) (DATA)))

/** Read a 16-bit unsigned value from EtherCAT data.
 *
 * \param DATA EtherCAT data pointer
 * \return EtherCAT data value
 */
#define EC_READ_U16(DATA) \
     ((uint16_t) le16_to_cpup((void *) (DATA)))

/** Read a 16-bit signed value from EtherCAT data.
 *
 * \param DATA EtherCAT data pointer
 * \return EtherCAT data value
 */
#define EC_READ_S16(DATA) \
     ((int16_t) le16_to_cpup((void *) (DATA)))

/** Read a 32-bit unsigned value from EtherCAT data.
 *
 * \param DATA EtherCAT data pointer
 * \return EtherCAT data value
 */
#define EC_READ_U32(DATA) \
     ((uint32_t) le32_to_cpup((void *) (DATA)))

/** Read a 32-bit signed value from EtherCAT data.
 *
 * \param DATA EtherCAT data pointer
 * \return EtherCAT data value
 */
#define EC_READ_S32(DATA) \
     ((int32_t) le32_to_cpup((void *) (DATA)))

/** Read a 64-bit unsigned value from EtherCAT data.
 *
 * \param DATA EtherCAT data pointer
 * \return EtherCAT data value
 */
#define EC_READ_U64(DATA) \
     ((uint64_t) le64_to_cpup((void *) (DATA)))

/** Read a 64-bit signed value from EtherCAT data.
 *
 * \param DATA EtherCAT data pointer
 * \return EtherCAT data value
 */
#define EC_READ_S64(DATA) \
     ((int64_t) le64_to_cpup((void *) (DATA)))

/******************************************************************************
 * Write macros
 *****************************************************************************/

/** Write an 8-bit unsigned value to EtherCAT data.
 *
 * \param DATA EtherCAT data pointer
 * \param VAL new value
 */
#define EC_WRITE_U8(DATA, VAL) \
    do { \
        *((uint8_t *)(DATA)) = ((uint8_t) (VAL)); \
    } while (0)

/** Write an 8-bit signed value to EtherCAT data.
 *
 * \param DATA EtherCAT data pointer
 * \param VAL new value
 */
#define EC_WRITE_S8(DATA, VAL) EC_WRITE_U8(DATA, VAL)

/** Write a 16-bit unsigned value to EtherCAT data.
 *
 * \param DATA EtherCAT data pointer
 * \param VAL new value
 */
#define EC_WRITE_U16(DATA, VAL) \
    do { \
        *((uint16_t *) (DATA)) = cpu_to_le16((uint16_t) (VAL)); \
    } while (0)

/** Write a 16-bit signed value to EtherCAT data.
 *
 * \param DATA EtherCAT data pointer
 * \param VAL new value
 */
#define EC_WRITE_S16(DATA, VAL) EC_WRITE_U16(DATA, VAL)

/** Write a 32-bit unsigned value to EtherCAT data.
 *
 * \param DATA EtherCAT data pointer
 * \param VAL new value
 */
#define EC_WRITE_U32(DATA, VAL) \
    do { \
        *((uint32_t *) (DATA)) = cpu_to_le32((uint32_t) (VAL)); \
    } while (0)

/** Write a 32-bit signed value to EtherCAT data.
 *
 * \param DATA EtherCAT data pointer
 * \param VAL new value
 */
#define EC_WRITE_S32(DATA, VAL) EC_WRITE_U32(DATA, VAL)

/** Write a 64-bit unsigned value to EtherCAT data.
 *
 * \param DATA EtherCAT data pointer
 * \param VAL new value
 */
#define EC_WRITE_U64(DATA, VAL) \
    do { \
        *((uint64_t *) (DATA)) = cpu_to_le64((uint64_t) (VAL)); \
    } while (0)

/** Write a 64-bit signed value to EtherCAT data.
 *
 * \param DATA EtherCAT data pointer
 * \param VAL new value
 */
#define EC_WRITE_S64(DATA, VAL) EC_WRITE_U64(DATA, VAL)

/*****************************************************************************/

/** @} */

#endif


<|start_filename|>3rdpart/tslib-1.15/src/ts_strsep.h<|end_filename|>
/*
 *  tslib/src/ts_strsep.h
 *
 * This file is placed under the LGPL.  Please see the file
 * COPYING for more details.
 *
 * SPDX-License-Identifier: LGPL-2.1
 */
#include <stddef.h>
#include <string.h>
#include <stdio.h>

char *ts_strsep(char **stringp, const char *delim);


<|start_filename|>3rdpart/tslib-1.15/plugins/input-raw.c<|end_filename|>
/*
 *  tslib/plugins/input-raw.c
 *
 *  Additions for the Linux multitouch API:
 *  Copyright (C) 2016 <NAME> <<EMAIL>>
 *
 *  Rewritten for the Linux input device API:
 *  Copyright (C) 2002 <NAME>
 *
 *  Original version:
 *  Copyright (C) 2001 <NAME>.
 *
 * This file is placed under the LGPL.  Please see the file
 * COPYING for more details.
 *
 * SPDX-License-Identifier: LGPL-2.1
 *
 *
 * Read raw pressure, x, y, and timestamp from a touchscreen device.
 */
#include "config.h"

#include <errno.h>
#include <stdio.h>
#include <limits.h>
#include <string.h>
#include <stdint.h>

#include <stdlib.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif

#include <sys/time.h>
#include <sys/types.h>

#ifdef __FreeBSD__
# include <dev/evdev/input.h>
#else
# include <linux/input.h>
#endif

#ifndef EV_SYN /* 2.4 kernel headers */
# define EV_SYN 0x00
#endif
#ifndef EV_CNT
# define EV_CNT (EV_MAX+1)
#endif
#ifndef ABS_CNT /* < 2.6.24 kernel headers */
# define ABS_CNT (ABS_MAX+1)
#endif
#ifndef KEY_CNT
# define KEY_CNT (KEY_MAX+1)
#endif
#ifndef SYN_MT_REPORT /* < 2.6.30 kernel headers */
# define SYN_MT_REPORT 2
#endif
#ifndef SYN_DROPPED /* < 2.6.39 kernel headers */
# define SYN_DROPPED 3
#endif
#ifndef SYN_MAX /* < 3.12 kernel headers */
# define SYN_MAX 0xf
#endif
#ifndef SYN_CNT
# define SYN_CNT (SYN_MAX+1)
#endif

#ifndef ABS_MT_SLOT /* < 2.6.36 kernel headers */
# define ABS_MT_SLOT             0x2f    /* MT slot being modified */
#endif
#ifndef ABS_MT_POSITION_X /* < 2.6.30 kernel headers */
# define ABS_MT_TOUCH_MAJOR      0x30    /* Major axis of touching ellipse */
# define ABS_MT_TOUCH_MINOR      0x31    /* Minor axis (omit if circular) */
# define ABS_MT_WIDTH_MAJOR      0x32    /* Major axis of approaching ellipse */
# define ABS_MT_WIDTH_MINOR      0x33    /* Minor axis (omit if circular) */
# define ABS_MT_ORIENTATION      0x34    /* Ellipse orientation */
# define ABS_MT_POSITION_X       0x35    /* Center X touch position */
# define ABS_MT_POSITION_Y       0x36    /* Center Y touch position */
# define ABS_MT_TOOL_TYPE        0x37    /* Type of touching device */
# define ABS_MT_BLOB_ID          0x38    /* Group a set of packets as a blob */
# define ABS_MT_TRACKING_ID      0x39    /* Unique ID of initiated contact */
#endif
#ifndef ABS_MT_PRESSURE /* < 2.6.33 kernel headers */
# define ABS_MT_PRESSURE         0x3a    /* Pressure on contact area */
#endif
#ifndef ABS_MT_DISTANCE /* < 2.6.38 kernel headers */
# define ABS_MT_DISTANCE         0x3b    /* Contact hover distance */
#endif
#ifndef ABS_MT_TOOL_X /* < 3.6 kernel headers */
# define ABS_MT_TOOL_X           0x3c    /* Center X tool position */
# define ABS_MT_TOOL_Y           0x3d    /* Center Y tool position */
#endif

#include "tslib-private.h"

#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
#define BIT(nr)                 (1UL << (nr))
#define BIT_MASK(nr)            (1UL << ((nr) % BITS_PER_LONG))
#define BIT_WORD(nr)            ((nr) / BITS_PER_LONG)
#define BITS_PER_BYTE           8
#define BITS_PER_LONG           (sizeof(long) * BITS_PER_BYTE)
#define BITS_TO_LONGS(nr)       DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long))

#define GRAB_EVENTS_WANTED	1
#define GRAB_EVENTS_ACTIVE	2

#define NUM_EVENTS_READ 1 /* internal. independent from the user call */

struct tslib_input {
	struct tslib_module_info module;

	int	current_x;
	int	current_y;
	int	current_p;

	int8_t	using_syn;
	int8_t	grab_events;

	struct input_event ev[NUM_EVENTS_READ];
	struct ts_sample_mt **buf;

	int	slot;
	int	max_slots;
	int	nr;
	int	pen_down;
	int	last_fd;
	int8_t	mt;
	int8_t	no_pressure;
	int8_t	type_a;
	int32_t *last_pressure;

	uint16_t	special_device; /* broken device we work around, see below */
};

#ifndef BUS_USB
#define BUS_USB 0x03
#endif

/* List of VIDs we use special cases for */
#define USB_VID_EGALAX 0x0EEF

/* List of actual devices we enumerate. For the device selection,
 * see get_special_device()
 */
#define EGALAX_VERSION_210 2

static int get_special_device(struct tslib_input *i)
{
	struct input_id id;
	struct tsdev *ts = i->module.dev;

	if ((ioctl(ts->fd, EVIOCGID, &id) < 0)) {
		fprintf(stderr, "tslib: warning, can't read device id\n");
		return -1;
	}

#ifdef DEBUG
	printf("tslib input device: vendor 0x%X product 0x%X version 0x%X on bus 0x%X\n",
	       id.vendor, id.product, id.version, id.bustype);
#endif

	/* only special usb devices so far, see the list above.
	 * so if not usb, we are done. */
	if (id.bustype != BUS_USB)
		return 0;

	switch (id.vendor) {
	case USB_VID_EGALAX:
		switch (id.product) {
		case 0x0001:
		/* taken from galax-raw. is this correct? */
		case 0x7200:
		case 0x7201:
			/* please note that any workarounds that don't
			 * apply to only a specific VERSION of one product,
			 * but to the product ID, should *really* be handled
			 * in the kernel! They have quirks over there.
			 */
			switch (id.version) {
			case 0x0210:
				i->special_device = EGALAX_VERSION_210;
				break;
			default:
				break;
			}
			break;
		default:
			break;
		}
		break;
	default:
		break;
	}

	return 0;
}

static void set_pressure(struct tslib_input *i)
{
	int j, k;

	i->current_p = 255;

	if (i->buf) {
		for (j = 0; j < i->nr; j++) {
			for (k = 0; k < i->max_slots; k++)
				i->buf[j][k].pressure = 255;
		}
	}
}

static int check_fd(struct tslib_input *i)
{
	struct tsdev *ts = i->module.dev;
	int version;
	long evbit[BITS_TO_LONGS(EV_CNT)];
	long absbit[BITS_TO_LONGS(ABS_CNT)];
	long keybit[BITS_TO_LONGS(KEY_CNT)];
	long synbit[BITS_TO_LONGS(SYN_CNT)];

	if (ioctl(ts->fd, EVIOCGVERSION, &version) < 0) {
		fprintf(stderr,
			"tslib: Selected device is not a Linux input event device\n");
		return -1;
	}

	/* support version EV_VERSION 0x010000 and 0x010001
	 * this check causes more troubles than it solves here
	 */
	if (version < EV_VERSION)
		fprintf(stderr,
			"tslib: Warning: Selected device uses a different version of the event protocol than tslib was compiled for\n");

	if ((ioctl(ts->fd, EVIOCGBIT(0, sizeof(evbit)), evbit) < 0) ||
		!(evbit[BIT_WORD(EV_ABS)] & BIT_MASK(EV_ABS))) {
		fprintf(stderr,
			"tslib: Selected device is not a touchscreen (must support ABS event type)\n");
		return -1;
	}

	if ((ioctl(ts->fd, EVIOCGBIT(EV_ABS, sizeof(absbit)), absbit)) < 0 ||
	    !(absbit[BIT_WORD(ABS_X)] & BIT_MASK(ABS_X)) ||
	    !(absbit[BIT_WORD(ABS_Y)] & BIT_MASK(ABS_Y))) {
		if (!(absbit[BIT_WORD(ABS_MT_POSITION_X)] & BIT_MASK(ABS_MT_POSITION_X)) ||
		    !(absbit[BIT_WORD(ABS_MT_POSITION_Y)] & BIT_MASK(ABS_MT_POSITION_Y))) {
			fprintf(stderr,
				"tslib: Selected device is not a touchscreen (must support ABS_X/Y or ABS_MT_POSITION_X/Y events)\n");
			return -1;
		}
	}

	/* Remember whether we have a multitouch device. We need to know for ABS_X,
	 * ABS_Y and ABS_PRESSURE data.
	 */
	if ((absbit[BIT_WORD(ABS_MT_POSITION_X)] & BIT_MASK(ABS_MT_POSITION_X)) &&
	    (absbit[BIT_WORD(ABS_MT_POSITION_Y)] & BIT_MASK(ABS_MT_POSITION_Y)))
		i->mt = 1;

	if (evbit[BIT_WORD(EV_KEY)] & BIT_MASK(EV_KEY)) {
		if (ioctl(ts->fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), keybit) < 0) {
			fprintf(stderr, "tslib: ioctl EVIOCGBIT error)\n");
			return -1;
		}

		/* for multitouch type B, tracking id is enough for pen down/up. type A
		 * has pen down/up through the list of (empty) SYN_MT_REPORT
		 * only for singletouch we need BTN_TOUCH or BTN_LEFT
		 */
		if (!(keybit[BIT_WORD(BTN_TOUCH)] & BIT_MASK(BTN_TOUCH) ||
		      keybit[BIT_WORD(BTN_LEFT)] & BIT_MASK(BTN_LEFT)) && !i->mt) {
			fprintf(stderr,
				"tslib: Selected device is not a touchscreen (missing BTN_TOUCH or BTN_LEFT)\n");
			return -1;
		}
	}

	if (evbit[BIT_WORD(EV_SYN)] & BIT_MASK(EV_SYN))
		i->using_syn = 1;

	/* read device info and set special device nr */
	get_special_device(i);

	/* Since some touchscreens (eg. infrared) physically can't measure pressure,
	 * the input system doesn't report it on those. Tslib relies on pressure, thus
	 * we set it to constant 255. It's still controlled by BTN_TOUCH/BTN_LEFT -
	 * when not touched, the pressure is forced to 0.
	 */
	if (!(absbit[BIT_WORD(ABS_PRESSURE)] & BIT_MASK(ABS_PRESSURE)))
		i->no_pressure = 1;

	if (i->mt) {
		if (!(absbit[BIT_WORD(ABS_MT_PRESSURE)] & BIT_MASK(ABS_MT_PRESSURE)))
			i->no_pressure = 1;
		else
			i->no_pressure = 0;
	}

	if ((ioctl(ts->fd, EVIOCGBIT(EV_SYN, sizeof(synbit)), synbit)) == -1)
		fprintf(stderr, "tslib: ioctl error\n");

	/* remember whether we have a multitouch type A device */
	if (i->mt && synbit[BIT_WORD(SYN_MT_REPORT)] & BIT_MASK(SYN_MT_REPORT) &&
	    !(absbit[BIT_WORD(ABS_MT_SLOT)] & BIT_MASK(ABS_MT_SLOT)) &&
	    !(absbit[BIT_WORD(ABS_MT_TRACKING_ID)] & BIT_MASK(ABS_MT_TRACKING_ID))) {
		i->type_a = 1;
	#ifdef DEBUG
		printf("tslib: We have a multitouch type A device\n");
	#endif
	}

	if (i->grab_events == GRAB_EVENTS_WANTED) {
		if (ioctl(ts->fd, EVIOCGRAB, (void *)1)) {
			fprintf(stderr,
				"tslib: Unable to grab selected input device\n");
			return -1;
		}
		i->grab_events = GRAB_EVENTS_ACTIVE;
	}

	if (i->mt && !i->using_syn) {
		fprintf(stderr,
			"tslib: Unsupported multitouch device (missing EV_SYN)\n");
		return -1;
	}

	return ts->fd;
}

static int ts_input_read(struct tslib_module_info *inf,
			 struct ts_sample *samp, int nr)
{
	struct tslib_input *i = (struct tslib_input *)inf;
	struct tsdev *ts = inf->dev;
	struct input_event ev;
	int ret = nr;
	int total = 0;
	int pen_up = 0;

	if (ts->fd != i->last_fd)
		i->last_fd = check_fd(i);

	if (i->last_fd == -1)
		return -ENODEV;

	if (i->no_pressure)
		set_pressure(i);

	if (i->using_syn) {
		while (total < nr) {
			ret = read(ts->fd, &ev, sizeof(struct input_event));
			if (ret < (int)sizeof(struct input_event)) {
				total = -1;
				break;
			}

			switch (ev.type) {
			case EV_KEY:
				switch (ev.code) {
				case BTN_TOUCH:
				case BTN_LEFT:
					if (ev.value == 0)
						pen_up = 1;
					break;
				}
				break;
			case EV_SYN:
				if (ev.code == SYN_REPORT) {
					/* Fill out a new complete event */
					if (pen_up) {
						samp->x = 0;
						samp->y = 0;
						samp->pressure = 0;
						pen_up = 0;
					} else {
						samp->x = i->current_x;
						samp->y = i->current_y;
						samp->pressure = i->current_p;
					}
					samp->tv = ev.time;
			#ifdef DEBUG
				fprintf(stderr,
					"RAW---------------------> %d %d %d %ld.%ld\n",
					samp->x, samp->y, samp->pressure,
					(long)samp->tv.tv_sec,
					(long)samp->tv.tv_usec);
			#endif /* DEBUG */
					samp++;
					total++;
				} else if (ev.code == SYN_MT_REPORT) {
					if (!i->type_a)
						break;

					if (i->type_a == 1) { /* no data: pen-up */
						pen_up = 1;

					} else {
						i->type_a = 1;
					}
			#ifdef DEBUG
				} else if (ev.code == SYN_DROPPED) {
					fprintf(stderr,
						"INPUT-RAW: SYN_DROPPED\n");
			#endif
				}
				break;
			case EV_ABS:
				if (i->special_device == EGALAX_VERSION_210) {
					switch (ev.code) {
					case ABS_X:
						i->current_x = ev.value;
						break;
					case ABS_Y:
						i->current_y = ev.value;
						break;
					case ABS_PRESSURE:
						i->current_p = ev.value;
						break;
					case ABS_MT_DISTANCE:
						if (ev.value > 0)
							i->current_p = 0;
						else
							i->current_p = 255;
						break;
					}
				} else {
					switch (ev.code) {
					case ABS_X:
						i->current_x = ev.value;
						break;
					case ABS_Y:
						i->current_y = ev.value;
						break;
					case ABS_MT_POSITION_X:
						i->current_x = ev.value;
						i->type_a++;
						break;
					case ABS_MT_POSITION_Y:
						i->current_y = ev.value;
						i->type_a++;
						break;
					case ABS_PRESSURE:
						i->current_p = ev.value;
						break;
					case ABS_MT_PRESSURE:
						i->current_p = ev.value;
						break;
					case ABS_MT_TRACKING_ID:
						if (ev.value == -1)
							i->current_p = 0;
						break;
					}
				}
				break;
			}
		}
		ret = total;
	} else {
		unsigned char *p = (unsigned char *) &ev;
		int len = sizeof(struct input_event);

		while (total < nr) {
			ret = read(ts->fd, p, len);
			if (ret == -1) {
				if (errno == EINTR)
					continue;

				break;
			}

			if (ret < (int)sizeof(struct input_event)) {
				/* short read
				 * restart read to get the rest of the event
				 */
				p += ret;
				len -= ret;
				continue;
			}
			/* successful read of a whole event */

			if (ev.type == EV_ABS) {
				switch (ev.code) {
				case ABS_X:
					if (ev.value != 0) {
						samp->x = i->current_x = ev.value;
						samp->y = i->current_y;
						samp->pressure = i->current_p;
					} else {
						fprintf(stderr,
							"tslib: dropped x = 0\n");
						continue;
					}
					break;
				case ABS_Y:
					if (ev.value != 0) {
						samp->x = i->current_x;
						samp->y = i->current_y = ev.value;
						samp->pressure = i->current_p;
					} else {
						fprintf(stderr,
							"tslib: dropped y = 0\n");
						continue;
					}
					break;
				case ABS_PRESSURE:
					samp->x = i->current_x;
					samp->y = i->current_y;
					samp->pressure = i->current_p = ev.value;
					break;
				}
				samp->tv = ev.time;
	#ifdef DEBUG
				fprintf(stderr,
					"RAW---------------------------> %d %d %d\n",
					samp->x, samp->y, samp->pressure);
	#endif /* DEBUG */
				samp++;
				total++;
			} else if (ev.type == EV_KEY) {
				switch (ev.code) {
				case BTN_TOUCH:
				case BTN_LEFT:
					if (ev.value == 0) {
						/* pen up */
						samp->x = 0;
						samp->y = 0;
						samp->pressure = 0;
						samp->tv = ev.time;
						samp++;
						total++;
					}
					break;
				}
			} else {
				fprintf(stderr,
					"tslib: Unknown event type %d\n",
					ev.type);
			}
			p = (unsigned char *) &ev;
		}
		ret = total;
	}

	return ret;
}

static int ts_input_read_mt(struct tslib_module_info *inf,
			    struct ts_sample_mt **samp, int max_slots, int nr)
{
	struct tslib_input *i = (struct tslib_input *)inf;
	struct tsdev *ts = inf->dev;
	int ret = nr;
	int total = 0;
	unsigned int it;
	int rd;
	int j, k;
	uint8_t pen_up = 0;
	static int32_t next_trackid;

	if (ts->fd != i->last_fd)
		i->last_fd = check_fd(i);

	if (i->last_fd == -1)
		return -ENODEV;

	if (i->buf == NULL || i->max_slots < max_slots || i->nr < nr) {
		if (i->buf) {
			for (j = 0; j < i->nr; j++) {
				if (i->buf[j])
					free(i->buf[j]);
			}
			free(i->buf);
		}

		i->buf = malloc(nr * sizeof(struct ts_sample_mt *));
		if (!i->buf)
			return -ENOMEM;

		for (j = 0; j < nr; j++) {
			i->buf[j] = calloc(max_slots,
					   sizeof(struct ts_sample_mt));
			if (!i->buf[j])
				return -ENOMEM;
		}

		i->max_slots = max_slots;
		i->nr = nr;

		if (i->type_a) {
			i->last_pressure = calloc(max_slots, sizeof(int32_t));
			if (!i->last_pressure) {
				for (j = 0; j < nr; j++)
					free(i->buf[j]);

				return -ENOMEM;
			}
		}
	}

	if (i->no_pressure)
		set_pressure(i);

	for (j = 0; j < nr; j++) {
		for (k = 0; k < max_slots; k++) {
			i->buf[j][k].valid = 0;
			i->buf[j][k].pen_down = -1;
		}
	}

	while (total < nr) {
		memset(i->ev, 0, sizeof(i->ev));
		rd = read(ts->fd,
			  i->ev,
			  sizeof(struct input_event) * NUM_EVENTS_READ);
		if (rd == -1) {
			if (total == 0) {
				if (errno > 0)
					return errno * -1;
				else
					return errno;
			} else {
				return total;
			}
		} else if (rd < (int) sizeof(struct input_event)) {
			if (total == 0)
				return -1;
			else
				return total;
		}

		for (it = 0; it < rd / sizeof(struct input_event); it++) {
		#ifdef DEBUG
			printf("INPUT-RAW: read type %d  code %3d  value %4d  time %ld.%ld\n",
			       i->ev[it].type, i->ev[it].code,
			       i->ev[it].value, (long)i->ev[it].time.tv_sec,
			       (long)i->ev[it].time.tv_usec);
		#endif
			switch (i->ev[it].type) {
			case EV_KEY:
				switch (i->ev[it].code) {
				case BTN_TOUCH:
					i->buf[total][i->slot].pen_down = i->ev[it].value;
					i->buf[total][i->slot].tv = i->ev[it].time;
					i->buf[total][i->slot].valid |= TSLIB_MT_VALID;
					if (i->ev[it].value == 0)
						pen_up = 1;

					break;
				}
				break;
			case EV_SYN:
				switch (i->ev[it].code) {
				case SYN_REPORT:
					if (pen_up && i->no_pressure) {
						for (k = 0; k < max_slots; k++) {
							i->buf[total][k].pressure = 0;
						}
					}

					if (pen_up)
						pen_up = 0;

					for (j = 0; j < nr; j++) {
						for (k = 0; k < max_slots; k++) {
							/* generate tracking id if not available */
							if (i->type_a) {
								if (i->buf[j][k].pressure == 0) {
									i->buf[j][k].tracking_id = -1;
									i->last_pressure[k] = 0;
								} else {
									if (i->last_pressure[k] == 0)
										next_trackid++;

									i->buf[j][k].tracking_id = next_trackid;
								}
							}

							memcpy(&samp[j][k],
								&i->buf[j][k],
								sizeof(struct ts_sample_mt));
						}
					}

					if (i->type_a)
						i->slot = 0;

					total++;
					break;
				case SYN_MT_REPORT:
					if (!i->type_a)
						break;

					if (i->buf[total][i->slot].valid < 1) {
						i->buf[total][i->slot].pressure = 0;
						if (i->slot == 0) {
							pen_up = 1;
							break;
						}

					} else if (i->slot < (max_slots - 1)) {
						i->slot++;
						i->buf[total][i->slot].slot = i->slot;
					}

					break;
			#ifdef DEBUG
				case SYN_DROPPED:
					fprintf(stderr,
						"INPUT-RAW: SYN_DROPPED\n");
					break;
			#endif
				}
				break;
			case EV_ABS:
				switch (i->ev[it].code) {
				case ABS_X:
					/* in case we didn't already get data for this
					 * slot, we go ahead and act as if this would be
					 * ABS_MT_POSITION_X
					 */
					if (i->mt && i->buf[total][i->slot].valid & TSLIB_MT_VALID)
						break;
				case ABS_MT_POSITION_X:
					i->buf[total][i->slot].x = i->ev[it].value;
					i->buf[total][i->slot].tv = i->ev[it].time;
					i->buf[total][i->slot].valid |= TSLIB_MT_VALID;
					break;
				case ABS_Y:
					if (i->mt && i->buf[total][i->slot].valid & TSLIB_MT_VALID)
						break;
				case ABS_MT_POSITION_Y:
					i->buf[total][i->slot].y = i->ev[it].value;
					i->buf[total][i->slot].tv = i->ev[it].time;
					i->buf[total][i->slot].valid |= TSLIB_MT_VALID;
					break;
				case ABS_PRESSURE:
					if (i->mt && i->buf[total][i->slot].valid & TSLIB_MT_VALID)
						break;
				case ABS_MT_PRESSURE:
					i->buf[total][i->slot].pressure = i->ev[it].value;
					i->buf[total][i->slot].tv = i->ev[it].time;
					i->buf[total][i->slot].valid |= TSLIB_MT_VALID;
					break;
				case ABS_MT_TOOL_X:
					i->buf[total][i->slot].tool_x = i->ev[it].value;
					i->buf[total][i->slot].tv = i->ev[it].time;
					i->buf[total][i->slot].valid |= TSLIB_MT_VALID;
					/* for future use
					 * i->buf[total][i->slot].valid |= TSLIB_MT_VALID_TOOL;
					 */
					break;
				case ABS_MT_TOOL_Y:
					i->buf[total][i->slot].tool_y = i->ev[it].value;
					i->buf[total][i->slot].tv = i->ev[it].time;
					i->buf[total][i->slot].valid |= TSLIB_MT_VALID;
					/* for future use
					 * i->buf[total][i->slot].valid |= TSLIB_MT_VALID_TOOL;
					 */
					break;
				case ABS_MT_TOOL_TYPE:
					i->buf[total][i->slot].tool_type = i->ev[it].value;
					i->buf[total][i->slot].tv = i->ev[it].time;
					i->buf[total][i->slot].valid |= TSLIB_MT_VALID;
					/* for future use
					 * i->buf[total][i->slot].valid |= TSLIB_MT_VALID_TOOL;
					 */
					break;
				case ABS_MT_ORIENTATION:
					i->buf[total][i->slot].orientation = i->ev[it].value;
					i->buf[total][i->slot].tv = i->ev[it].time;
					i->buf[total][i->slot].valid |= TSLIB_MT_VALID;
					break;
				case ABS_MT_DISTANCE:
					i->buf[total][i->slot].distance = i->ev[it].value;
					i->buf[total][i->slot].tv = i->ev[it].time;
					i->buf[total][i->slot].valid |= TSLIB_MT_VALID;

					if (i->special_device == EGALAX_VERSION_210) {
						if (i->ev[it].value > 0)
							i->buf[total][i->slot].pressure = 0;
						else
							i->buf[total][i->slot].pressure = 255;
					}

					break;
				case ABS_MT_BLOB_ID:
					i->buf[total][i->slot].blob_id = i->ev[it].value;
					i->buf[total][i->slot].tv = i->ev[it].time;
					i->buf[total][i->slot].valid |= TSLIB_MT_VALID;
					break;
				case ABS_MT_TOUCH_MAJOR:
					i->buf[total][i->slot].touch_major = i->ev[it].value;
					i->buf[total][i->slot].tv = i->ev[it].time;
					i->buf[total][i->slot].valid |= TSLIB_MT_VALID;
					break;
				case ABS_MT_WIDTH_MAJOR:
					i->buf[total][i->slot].width_major = i->ev[it].value;
					i->buf[total][i->slot].tv = i->ev[it].time;
					i->buf[total][i->slot].valid |= TSLIB_MT_VALID;
					break;
				case ABS_MT_TOUCH_MINOR:
					i->buf[total][i->slot].touch_minor = i->ev[it].value;
					i->buf[total][i->slot].tv = i->ev[it].time;
					i->buf[total][i->slot].valid |= TSLIB_MT_VALID;
					break;
				case ABS_MT_WIDTH_MINOR:
					i->buf[total][i->slot].width_minor = i->ev[it].value;
					i->buf[total][i->slot].tv = i->ev[it].time;
					i->buf[total][i->slot].valid |= TSLIB_MT_VALID;
					break;
				case ABS_MT_TRACKING_ID:
					i->buf[total][i->slot].tracking_id = i->ev[it].value;
					i->buf[total][i->slot].tv = i->ev[it].time;
					i->buf[total][i->slot].valid |= TSLIB_MT_VALID;
					if (i->ev[it].value == -1)
						i->buf[total][i->slot].pressure = 0;
					break;
				case ABS_MT_SLOT:
					if (i->ev[it].value < 0 || i->ev[it].value >= max_slots) {
						fprintf(stderr, "tslib: warning: slot out of range. data corrupted!\n");
						i->slot = max_slots - 1;
					} else {
						i->slot = i->ev[it].value;
						i->buf[total][i->slot].slot = i->ev[it].value;
						i->buf[total][i->slot].valid |= TSLIB_MT_VALID;
					}
					break;
				}
				break;
			}
			if (total == ret)
				break;
		} /* just NUM_EVENTS_READ. it's simply 1 */
	}

	return total;
}

static int ts_input_fini(struct tslib_module_info *inf)
{
	struct tslib_input *i = (struct tslib_input *)inf;
	struct tsdev *ts = inf->dev;
	int j;

	if (i->grab_events == GRAB_EVENTS_ACTIVE) {
		if (ioctl(ts->fd, EVIOCGRAB, (void *)0))
			fprintf(stderr, "tslib: Unable to un-grab selected input device\n");
	}

	for (j = 0; j < i->nr; j++) {
		if (i->buf[j])
			free(i->buf[j]);
	}
	if (i->buf)
		free(i->buf);

	if (i->last_pressure)
		free(i->last_pressure);

	free(inf);

	return 0;
}

static const struct tslib_ops __ts_input_ops = {
	.read		= ts_input_read,
	.read_mt	= ts_input_read_mt,
	.fini		= ts_input_fini,
};

static int parse_raw_grab(struct tslib_module_info *inf, char *str, void *data)
{
	struct tslib_input *i = (struct tslib_input *)inf;
	unsigned long v;
	int err = errno;

	v = strtoul(str, NULL, 0);

	if (v == ULONG_MAX && errno == ERANGE)
		return -1;

	errno = err;
	switch ((int)(intptr_t)data) {
	case 1:
		if (v)
			i->grab_events = GRAB_EVENTS_WANTED;
		break;
	default:
		return -1;
	}
	return 0;
}

static const struct tslib_vars raw_vars[] = {
	{ "grab_events", (void *)1, parse_raw_grab },
};

#define NR_VARS (sizeof(raw_vars) / sizeof(raw_vars[0]))

TSAPI struct tslib_module_info *input_mod_init(__attribute__ ((unused)) struct tsdev *dev,
					       const char *params)
{
	struct tslib_input *i;

	i = malloc(sizeof(struct tslib_input));
	if (i == NULL)
		return NULL;

	i->module.ops = &__ts_input_ops;
	i->current_x = 0;
	i->current_y = 0;
	i->current_p = 0;
	i->using_syn = 0;
	i->grab_events = 0;
	i->slot = 0;
	i->pen_down = 0;
	i->buf = NULL;
	i->max_slots = 0;
	i->nr = 0;
	i->mt = 0;
	i->no_pressure = 0;
	i->last_fd = -2;
	i->type_a = 0;
	i->special_device = 0;
	i->last_pressure = NULL;

	if (tslib_parse_vars(&i->module, raw_vars, NR_VARS, params)) {
		free(i);
		return NULL;
	}

	return &(i->module);
}

#ifndef TSLIB_STATIC_INPUT_MODULE
	TSLIB_MODULE_INIT(input_mod_init);
#endif


<|start_filename|>3rdpart/ethercat-1.5.2/master/fsm_foe.c<|end_filename|>
/******************************************************************************
 *
 *  $Id: fsm_foe.c,v ec403cf308eb 2013/02/12 14:46:43 fp $
 *
 *  Copyright (C) 2008  <NAME>, imc Messsysteme GmbH
 *
 *  This file is part of the IgH EtherCAT Master.
 *
 *  The IgH EtherCAT Master is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License version 2, as
 *  published by the Free Software Foundation.
 *
 *  The IgH EtherCAT Master is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 *  Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with the IgH EtherCAT Master; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 *****************************************************************************/

/**
   \file
   EtherCAT FoE state machines.
*/

/*****************************************************************************/

#include "globals.h"
#include "master.h"
#include "mailbox.h"
#include "fsm_foe.h"
#include "foe.h"

/*****************************************************************************/

/** Maximum time in ms to wait for responses when reading out the dictionary.
 */
#define EC_FSM_FOE_TIMEOUT 3000

/** Mailbox type FoE.
 */
#define EC_MBOX_TYPE_FILEACCESS 0x04

/** Size of the FoE header.
 */
#define EC_FOE_HEADER_SIZE 6
// uint8_t  OpCode
// uint8_t  reserved
// uint32_t PacketNo, Password, ErrorCode

//#define DEBUG_FOE

/*****************************************************************************/

/** FoE OpCodes.
 */
enum {
    EC_FOE_OPCODE_RRQ  = 1, /**< Read request. */
    EC_FOE_OPCODE_WRQ  = 2, /**< Write request. */
    EC_FOE_OPCODE_DATA = 3, /**< Data. */
    EC_FOE_OPCODE_ACK  = 4, /**< Acknowledge. */
    EC_FOE_OPCODE_ERR  = 5, /**< Error. */
    EC_FOE_OPCODE_BUSY = 6  /**< Busy. */
} ec_foe_opcode_t;

/*****************************************************************************/

int ec_foe_prepare_data_send(ec_fsm_foe_t *, ec_datagram_t *);
int ec_foe_prepare_wrq_send(ec_fsm_foe_t *, ec_datagram_t *);
int ec_foe_prepare_rrq_send(ec_fsm_foe_t *, ec_datagram_t *);
int ec_foe_prepare_send_ack(ec_fsm_foe_t *, ec_datagram_t *);

void ec_foe_set_tx_error(ec_fsm_foe_t *, uint32_t);
void ec_foe_set_rx_error(ec_fsm_foe_t *, uint32_t);

void ec_fsm_foe_end(ec_fsm_foe_t *, ec_datagram_t *);
void ec_fsm_foe_error(ec_fsm_foe_t *, ec_datagram_t *);

void ec_fsm_foe_state_wrq_sent(ec_fsm_foe_t *, ec_datagram_t *);
void ec_fsm_foe_state_rrq_sent(ec_fsm_foe_t *, ec_datagram_t *);

void ec_fsm_foe_state_ack_check(ec_fsm_foe_t *, ec_datagram_t *);
void ec_fsm_foe_state_ack_read(ec_fsm_foe_t *, ec_datagram_t *);

void ec_fsm_foe_state_data_sent(ec_fsm_foe_t *, ec_datagram_t *);

void ec_fsm_foe_state_data_check(ec_fsm_foe_t *, ec_datagram_t *);
void ec_fsm_foe_state_data_read(ec_fsm_foe_t *, ec_datagram_t *);
void ec_fsm_foe_state_sent_ack(ec_fsm_foe_t *, ec_datagram_t *);

void ec_fsm_foe_write_start(ec_fsm_foe_t *, ec_datagram_t *);
void ec_fsm_foe_read_start(ec_fsm_foe_t *, ec_datagram_t *);

/*****************************************************************************/

/** Constructor.
 */
void ec_fsm_foe_init(
        ec_fsm_foe_t *fsm /**< finite state machine */
        )
{
    fsm->state = NULL;
    fsm->datagram = NULL;
}

/*****************************************************************************/

/** Destructor.
 */
void ec_fsm_foe_clear(ec_fsm_foe_t *fsm /**< finite state machine */)
{
}

/*****************************************************************************/

/** Executes the current state of the state machine.
 *
 * \return 1, if the datagram was used, else 0.
 */
int ec_fsm_foe_exec(
        ec_fsm_foe_t *fsm, /**< finite state machine */
        ec_datagram_t *datagram /**< Datagram to use. */
        )
{
    int datagram_used = 0;

    if (fsm->datagram &&
            (fsm->datagram->state == EC_DATAGRAM_INIT ||
             fsm->datagram->state == EC_DATAGRAM_QUEUED ||
             fsm->datagram->state == EC_DATAGRAM_SENT)) {
        // datagram not received yet
        return datagram_used;
    }

    fsm->state(fsm, datagram);

    datagram_used =
        fsm->state != ec_fsm_foe_end && fsm->state != ec_fsm_foe_error;

    if (datagram_used) {
        fsm->datagram = datagram;
    } else {
        fsm->datagram = NULL;
    }

    return datagram_used;
}

/*****************************************************************************/

/** Returns, if the state machine terminated with success.
 * \return non-zero if successful.
 */
int ec_fsm_foe_success(const ec_fsm_foe_t *fsm /**< Finite state machine */)
{
    return fsm->state == ec_fsm_foe_end;
}

/*****************************************************************************/

/** Prepares an FoE transfer.
 */
void ec_fsm_foe_transfer(
        ec_fsm_foe_t *fsm, /**< State machine. */
        ec_slave_t *slave, /**< EtherCAT slave. */
        ec_foe_request_t *request /**< Sdo request. */
        )
{
    fsm->slave = slave;
    fsm->request = request;

    if (request->dir == EC_DIR_OUTPUT) {
        fsm->tx_buffer = fsm->request->buffer;
        fsm->tx_buffer_size = fsm->request->data_size;
        fsm->tx_buffer_offset = 0;

        fsm->tx_filename = fsm->request->file_name;
        fsm->tx_filename_len = strlen(fsm->tx_filename);

        fsm->state = ec_fsm_foe_write_start;
    }
    else {
        fsm->rx_buffer = fsm->request->buffer;
        fsm->rx_buffer_size = fsm->request->buffer_size;

        fsm->rx_filename = fsm->request->file_name;
        fsm->rx_filename_len = strlen(fsm->rx_filename);

        fsm->state = ec_fsm_foe_read_start;
    }
}

/*****************************************************************************/

/** State: ERROR.
 */
void ec_fsm_foe_error(
        ec_fsm_foe_t *fsm, /**< finite state machine */
        ec_datagram_t *datagram /**< Datagram to use. */
        )
{
#ifdef DEBUG_FOE
    printk("ec_fsm_foe_error()\n");
#endif
}

/*****************************************************************************/

/** State: END.
 */
void ec_fsm_foe_end(
        ec_fsm_foe_t *fsm, /**< finite state machine */
        ec_datagram_t *datagram /**< Datagram to use. */
        )
{
#ifdef DEBUG_FOE
    printk("ec_fsm_foe_end\n");
#endif
}

/*****************************************************************************/

/** Sends a file or the next fragment.
 *
 * \return Zero on success, otherwise a negative error code.
 */
int ec_foe_prepare_data_send(
        ec_fsm_foe_t *fsm, /**< Finite state machine. */
        ec_datagram_t *datagram /**< Datagram to use. */
        )
{
    size_t remaining_size, current_size;
    uint8_t *data;

    remaining_size = fsm->tx_buffer_size - fsm->tx_buffer_offset;

    if (remaining_size < fsm->slave->configured_tx_mailbox_size
            - EC_MBOX_HEADER_SIZE - EC_FOE_HEADER_SIZE) {
        current_size = remaining_size;
        fsm->tx_last_packet = 1;
    } else {
        current_size = fsm->slave->configured_tx_mailbox_size
            - EC_MBOX_HEADER_SIZE - EC_FOE_HEADER_SIZE;
    }

    data = ec_slave_mbox_prepare_send(fsm->slave,
            datagram, EC_MBOX_TYPE_FILEACCESS,
            current_size + EC_FOE_HEADER_SIZE);
    if (IS_ERR(data)) {
        return -1;
    }

    EC_WRITE_U16(data, EC_FOE_OPCODE_DATA);    // OpCode = DataBlock req.
    EC_WRITE_U32(data + 2, fsm->tx_packet_no); // PacketNo, Password

    memcpy(data + EC_FOE_HEADER_SIZE,
            fsm->tx_buffer + fsm->tx_buffer_offset, current_size);
    fsm->tx_current_size = current_size;

    return 0;
}

/*****************************************************************************/

/** Prepare a write request (WRQ) with filename
 *
 * \return Zero on success, otherwise a negative error code.
 */
int ec_foe_prepare_wrq_send(
        ec_fsm_foe_t *fsm, /**< Finite state machine. */
        ec_datagram_t *datagram /**< Datagram to use. */
        )
{
    size_t current_size;
    uint8_t *data;

    fsm->tx_buffer_offset = 0;
    fsm->tx_current_size = 0;
    fsm->tx_packet_no = 0;
    fsm->tx_last_packet = 0;

    current_size = fsm->tx_filename_len;

    data = ec_slave_mbox_prepare_send(fsm->slave, datagram,
            EC_MBOX_TYPE_FILEACCESS, current_size + EC_FOE_HEADER_SIZE);
    if (IS_ERR(data)) {
        return -1;
    }

    EC_WRITE_U16( data, EC_FOE_OPCODE_WRQ); // fsm write request
    EC_WRITE_U32( data + 2, fsm->tx_packet_no );

    memcpy(data + EC_FOE_HEADER_SIZE, fsm->tx_filename, current_size);

    return 0;
}

/*****************************************************************************/

/** Initializes the FoE write state machine.
 */
void ec_fsm_foe_write_start(
        ec_fsm_foe_t *fsm, /**< finite state machine */
        ec_datagram_t *datagram /**< Datagram to use. */
        )
{
    ec_slave_t *slave = fsm->slave;

    fsm->tx_buffer_offset = 0;
    fsm->tx_current_size = 0;
    fsm->tx_packet_no = 0;
    fsm->tx_last_packet = 0;

#ifdef DEBUG_FOE
    printk("ec_fsm_foe_write_start()\n");
#endif

    if (!(slave->sii.mailbox_protocols & EC_MBOX_FOE)) {
        ec_foe_set_tx_error(fsm, FOE_MBOX_PROT_ERROR);
        EC_SLAVE_ERR(slave, "Slave does not support FoE!\n");
        return;
    }

    if (ec_foe_prepare_wrq_send(fsm, datagram)) {
        ec_foe_set_tx_error(fsm, FOE_PROT_ERROR);
        return;
    }

    fsm->state = ec_fsm_foe_state_wrq_sent;
}

/*****************************************************************************/

/** Check for acknowledge.
 */
void ec_fsm_foe_state_ack_check(
        ec_fsm_foe_t *fsm, /**< FoE statemachine. */
        ec_datagram_t *datagram /**< Datagram to use. */
        )
{
    ec_slave_t *slave = fsm->slave;

#ifdef DEBUG_FOE
    printk("ec_fsm_foe_ack_check()\n");
#endif

    if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
        ec_foe_set_rx_error(fsm, FOE_RECEIVE_ERROR);
        EC_SLAVE_ERR(slave, "Failed to receive FoE mailbox check datagram: ");
        ec_datagram_print_state(fsm->datagram);
        return;
    }

    if (fsm->datagram->working_counter != 1) {
        ec_foe_set_rx_error(fsm, FOE_WC_ERROR);
        EC_SLAVE_ERR(slave, "Reception of FoE mailbox check datagram"
                " failed: ");
        ec_datagram_print_wc_error(fsm->datagram);
        return;
    }

    if (!ec_slave_mbox_check(fsm->datagram)) {
        // slave did not put anything in the mailbox yet
        unsigned long diff_ms =
            (datagram->jiffies_received - fsm->jiffies_start) * 1000 / HZ;
        if (diff_ms >= EC_FSM_FOE_TIMEOUT) {
            ec_foe_set_tx_error(fsm, FOE_TIMEOUT_ERROR);
            EC_SLAVE_ERR(slave, "Timeout while waiting for ack response.\n");
            return;
        }

        ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
        fsm->retries = EC_FSM_RETRIES;
        return;
    }

    // Fetch response
    ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.

    fsm->retries = EC_FSM_RETRIES;
    fsm->state = ec_fsm_foe_state_ack_read;
}

/*****************************************************************************/

/** Acknowledge a read operation.
 */
void ec_fsm_foe_state_ack_read(
        ec_fsm_foe_t *fsm, /**< FoE statemachine. */
        ec_datagram_t *datagram /**< Datagram to use. */
        )
{
    ec_slave_t *slave = fsm->slave;
    uint8_t *data, mbox_prot;
    uint8_t opCode;
    size_t rec_size;

#ifdef DEBUG_FOE
    printk("ec_fsm_foe_ack_read()\n");
#endif

    if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
        ec_foe_set_rx_error(fsm, FOE_RECEIVE_ERROR);
        EC_SLAVE_ERR(slave, "Failed to receive FoE ack response datagram: ");
        ec_datagram_print_state(fsm->datagram);
        return;
    }

    if (fsm->datagram->working_counter != 1) {
        ec_foe_set_rx_error(fsm, FOE_WC_ERROR);
        EC_SLAVE_ERR(slave, "Reception of FoE ack response failed: ");
        ec_datagram_print_wc_error(fsm->datagram);
        return;
    }

    data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
    if (IS_ERR(data)) {
        ec_foe_set_tx_error(fsm, FOE_PROT_ERROR);
        return;
    }

    if (mbox_prot != EC_MBOX_TYPE_FILEACCESS) { // FoE
        ec_foe_set_tx_error(fsm, FOE_MBOX_PROT_ERROR);
        EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
                mbox_prot);
        return;
    }

    opCode = EC_READ_U8(data);

    if (opCode == EC_FOE_OPCODE_BUSY) {
        // slave not ready
        if (ec_foe_prepare_data_send(fsm, datagram)) {
            ec_foe_set_tx_error(fsm, FOE_PROT_ERROR);
            EC_SLAVE_ERR(slave, "Slave is busy.\n");
            return;
        }
        fsm->state = ec_fsm_foe_state_data_sent;
        return;
    }

    if (opCode == EC_FOE_OPCODE_ACK) {
        fsm->tx_packet_no++;
        fsm->tx_buffer_offset += fsm->tx_current_size;

        if (fsm->tx_last_packet) {
            fsm->state = ec_fsm_foe_end;
            return;
        }

        if (ec_foe_prepare_data_send(fsm, datagram)) {
            ec_foe_set_tx_error(fsm, FOE_PROT_ERROR);
            return;
        }
        fsm->state = ec_fsm_foe_state_data_sent;
        return;
    }
    ec_foe_set_tx_error(fsm, FOE_ACK_ERROR);
}

/*****************************************************************************/

/** State: WRQ SENT.
 *
 * Checks is the previous transmit datagram succeded and sends the next
 * fragment, if necessary.
 */
void ec_fsm_foe_state_wrq_sent(
        ec_fsm_foe_t *fsm, /**< FoE statemachine. */
        ec_datagram_t *datagram /**< Datagram to use. */
        )
{
    ec_slave_t *slave = fsm->slave;

#ifdef DEBUG_FOE
    printk("ec_foe_state_sent_wrq()\n");
#endif

    if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
        ec_foe_set_rx_error(fsm, FOE_RECEIVE_ERROR);
        EC_SLAVE_ERR(slave, "Failed to send FoE WRQ: ");
        ec_datagram_print_state(fsm->datagram);
        return;
    }

    if (fsm->datagram->working_counter != 1) {
        // slave did not put anything in the mailbox yet
        ec_foe_set_rx_error(fsm, FOE_WC_ERROR);
        EC_SLAVE_ERR(slave, "Reception of FoE WRQ failed: ");
        ec_datagram_print_wc_error(fsm->datagram);
        return;
    }

    fsm->jiffies_start = fsm->datagram->jiffies_sent;

    ec_slave_mbox_prepare_check(slave, datagram); // can not fail.

    fsm->retries = EC_FSM_RETRIES;
    fsm->state = ec_fsm_foe_state_ack_check;
}

/*****************************************************************************/

/** State: WRQ SENT.
 *
 * Checks is the previous transmit datagram succeded and sends the next
 * fragment, if necessary.
 */
void ec_fsm_foe_state_data_sent(
        ec_fsm_foe_t *fsm, /**< Foe statemachine. */
        ec_datagram_t *datagram /**< Datagram to use. */
        )
{
    ec_slave_t *slave = fsm->slave;

#ifdef DEBUG_FOE
    printk("ec_fsm_foe_state_data_sent()\n");
#endif

    if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
        ec_foe_set_tx_error(fsm, FOE_RECEIVE_ERROR);
        EC_SLAVE_ERR(slave, "Failed to receive FoE ack response datagram: ");
        ec_datagram_print_state(fsm->datagram);
        return;
    }

    if (fsm->datagram->working_counter != 1) {
        ec_foe_set_tx_error(fsm, FOE_WC_ERROR);
        EC_SLAVE_ERR(slave, "Reception of FoE data send failed: ");
        ec_datagram_print_wc_error(fsm->datagram);
        return;
    }

    ec_slave_mbox_prepare_check(slave, datagram);
    fsm->jiffies_start = jiffies;
    fsm->retries = EC_FSM_RETRIES;
    fsm->state = ec_fsm_foe_state_ack_check;
}

/*****************************************************************************/

/** Prepare a read request (RRQ) with filename
 *
 * \return Zero on success, otherwise a negative error code.
 */
int ec_foe_prepare_rrq_send(
        ec_fsm_foe_t *fsm, /**< Finite state machine. */
        ec_datagram_t *datagram /**< Datagram to use. */
        )
{
    size_t current_size;
    uint8_t *data;

    current_size = fsm->rx_filename_len;

    data = ec_slave_mbox_prepare_send(fsm->slave, datagram,
            EC_MBOX_TYPE_FILEACCESS, current_size + EC_FOE_HEADER_SIZE);
    if (IS_ERR(data)) {
        return -1;
    }

    EC_WRITE_U16(data, EC_FOE_OPCODE_RRQ); // fsm read request
    EC_WRITE_U32(data + 2, 0x00000000); // no passwd
    memcpy(data + EC_FOE_HEADER_SIZE, fsm->rx_filename, current_size);

    if (fsm->slave->master->debug_level) {
        EC_SLAVE_DBG(fsm->slave, 1, "FoE Read Request:\n");
        ec_print_data(data, current_size + EC_FOE_HEADER_SIZE);
    }

    return 0;
}

/*****************************************************************************/

/** Prepare to send an acknowledge.
 *
 * \return Zero on success, otherwise a negative error code.
 */
int ec_foe_prepare_send_ack(
        ec_fsm_foe_t *fsm, /**< FoE statemachine. */
        ec_datagram_t *datagram /**< Datagram to use. */
        )
{
    uint8_t *data;

    data = ec_slave_mbox_prepare_send(fsm->slave, datagram,
            EC_MBOX_TYPE_FILEACCESS, EC_FOE_HEADER_SIZE);
    if (IS_ERR(data)) {
        return -1;
    }

    EC_WRITE_U16(data, EC_FOE_OPCODE_ACK);
    EC_WRITE_U32(data + 2, fsm->rx_expected_packet_no);

    return 0;
}

/*****************************************************************************/

/** State: RRQ SENT.
 *
 * Checks is the previous transmit datagram succeeded and sends the next
 * fragment, if necessary.
 */
void ec_fsm_foe_state_rrq_sent(
        ec_fsm_foe_t *fsm, /**< FoE statemachine. */
        ec_datagram_t *datagram /**< Datagram to use. */
        )
{
    ec_slave_t *slave = fsm->slave;

#ifdef DEBUG_FOE
    printk("ec_foe_state_rrq_sent()\n");
#endif

    if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
        ec_foe_set_rx_error(fsm, FOE_RECEIVE_ERROR);
        EC_SLAVE_ERR(slave, "Failed to send FoE RRQ: ");
        ec_datagram_print_state(fsm->datagram);
        return;
    }

    if (fsm->datagram->working_counter != 1) {
        // slave did not put anything in the mailbox yet
        ec_foe_set_rx_error(fsm, FOE_WC_ERROR);
        EC_SLAVE_ERR(slave, "Reception of FoE RRQ failed: ");
        ec_datagram_print_wc_error(fsm->datagram);
        return;
    }

    fsm->jiffies_start = fsm->datagram->jiffies_sent;

    ec_slave_mbox_prepare_check(slave, datagram); // can not fail.

    fsm->retries = EC_FSM_RETRIES;
    fsm->state = ec_fsm_foe_state_data_check;
}

/*****************************************************************************/

/** Starting state for read operations.
 */
void ec_fsm_foe_read_start(
        ec_fsm_foe_t *fsm, /**< FoE statemachine. */
        ec_datagram_t *datagram /**< Datagram to use. */
        )
{
    ec_slave_t *slave = fsm->slave;

    fsm->rx_buffer_offset = 0;
    fsm->rx_expected_packet_no = 1;
    fsm->rx_last_packet = 0;

#ifdef DEBUG_FOE
    printk("ec_fsm_foe_read_start()\n");
#endif

    if (!(slave->sii.mailbox_protocols & EC_MBOX_FOE)) {
        ec_foe_set_tx_error(fsm, FOE_MBOX_PROT_ERROR);
        EC_SLAVE_ERR(slave, "Slave does not support FoE!\n");
        return;
    }

    if (ec_foe_prepare_rrq_send(fsm, datagram)) {
        ec_foe_set_rx_error(fsm, FOE_PROT_ERROR);
        return;
    }

    fsm->state = ec_fsm_foe_state_rrq_sent;
}

/*****************************************************************************/

/** Check for data.
 */
void ec_fsm_foe_state_data_check(
        ec_fsm_foe_t *fsm, /**< FoE statemachine. */
        ec_datagram_t *datagram /**< Datagram to use. */
        )
{
    ec_slave_t *slave = fsm->slave;

#ifdef DEBUG_FOE
    printk("ec_fsm_foe_state_data_check()\n");
#endif

    if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
        ec_foe_set_rx_error(fsm, FOE_RECEIVE_ERROR);
        EC_SLAVE_ERR(slave, "Failed to send FoE DATA READ: ");
        ec_datagram_print_state(fsm->datagram);
        return;
    }

    if (fsm->datagram->working_counter != 1) {
        ec_foe_set_rx_error(fsm, FOE_WC_ERROR);
        EC_SLAVE_ERR(slave, "Reception of FoE DATA READ: ");
        ec_datagram_print_wc_error(fsm->datagram);
        return;
    }

    if (!ec_slave_mbox_check(fsm->datagram)) {
        unsigned long diff_ms =
            (fsm->datagram->jiffies_received - fsm->jiffies_start) *
            1000 / HZ;
        if (diff_ms >= EC_FSM_FOE_TIMEOUT) {
            ec_foe_set_tx_error(fsm, FOE_TIMEOUT_ERROR);
            EC_SLAVE_ERR(slave, "Timeout while waiting for ack response.\n");
            return;
        }

        ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
        fsm->retries = EC_FSM_RETRIES;
        return;
    }

    // Fetch response
    ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail.

    fsm->retries = EC_FSM_RETRIES;
    fsm->state = ec_fsm_foe_state_data_read;

}

/*****************************************************************************/

/** Start reading data.
 */
void ec_fsm_foe_state_data_read(
        ec_fsm_foe_t *fsm, /**< FoE statemachine. */
        ec_datagram_t *datagram /**< Datagram to use. */
        )
{
    size_t rec_size;
    uint8_t *data, opCode, packet_no, mbox_prot;

    ec_slave_t *slave = fsm->slave;

#ifdef DEBUG_FOE
    printk("ec_fsm_foe_state_data_read()\n");
#endif

    if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
        ec_foe_set_rx_error(fsm, FOE_RECEIVE_ERROR);
        EC_SLAVE_ERR(slave, "Failed to receive FoE DATA READ datagram: ");
        ec_datagram_print_state(fsm->datagram);
        return;
    }

    if (fsm->datagram->working_counter != 1) {
        ec_foe_set_rx_error(fsm, FOE_WC_ERROR);
        EC_SLAVE_ERR(slave, "Reception of FoE DATA READ failed: ");
        ec_datagram_print_wc_error(fsm->datagram);
        return;
    }

    data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
    if (IS_ERR(data)) {
        ec_foe_set_rx_error(fsm, FOE_MBOX_FETCH_ERROR);
        return;
    }

    if (mbox_prot != EC_MBOX_TYPE_FILEACCESS) { // FoE
        EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
                mbox_prot);
        ec_foe_set_rx_error(fsm, FOE_PROT_ERROR);
        return;
    }

    opCode = EC_READ_U8(data);

    if (opCode == EC_FOE_OPCODE_BUSY) {
        if (ec_foe_prepare_send_ack(fsm, datagram)) {
            ec_foe_set_rx_error(fsm, FOE_PROT_ERROR);
        }
        return;
    }

    if (opCode == EC_FOE_OPCODE_ERR) {
        fsm->request->error_code = EC_READ_U32(data + 2);
        EC_SLAVE_ERR(slave, "Received FoE Error Request (code 0x%08x).\n",
                fsm->request->error_code);
        if (rec_size > 6) {
            uint8_t text[256];
            strncpy(text, data + 6, min(rec_size - 6, sizeof(text)));
            EC_SLAVE_ERR(slave, "FoE Error Text: %s\n", text);
        }
        ec_foe_set_rx_error(fsm, FOE_OPCODE_ERROR);
        return;
    }

    if (opCode != EC_FOE_OPCODE_DATA) {
        EC_SLAVE_ERR(slave, "Received OPCODE %x, expected %x.\n",
                opCode, EC_FOE_OPCODE_DATA);
        fsm->request->error_code = 0x00000000;
        ec_foe_set_rx_error(fsm, FOE_OPCODE_ERROR);
        return;
    }

    packet_no = EC_READ_U16(data + 2);
    if (packet_no != fsm->rx_expected_packet_no) {
        EC_SLAVE_ERR(slave, "Received unexpected packet number.\n");
        ec_foe_set_rx_error(fsm, FOE_PACKETNO_ERROR);
        return;
    }

    rec_size -= EC_FOE_HEADER_SIZE;

    if (fsm->rx_buffer_size >= fsm->rx_buffer_offset + rec_size) {
        memcpy(fsm->rx_buffer + fsm->rx_buffer_offset,
                data + EC_FOE_HEADER_SIZE, rec_size);
        fsm->rx_buffer_offset += rec_size;
    }

    fsm->rx_last_packet =
        (rec_size + EC_MBOX_HEADER_SIZE + EC_FOE_HEADER_SIZE
         != slave->configured_rx_mailbox_size);

    if (fsm->rx_last_packet ||
            (slave->configured_rx_mailbox_size - EC_MBOX_HEADER_SIZE
             - EC_FOE_HEADER_SIZE + fsm->rx_buffer_offset)
            <= fsm->rx_buffer_size) {
        // either it was the last packet or a new packet will fit into the
        // delivered buffer
#ifdef DEBUG_FOE
        printk ("last_packet=true\n");
#endif
        if (ec_foe_prepare_send_ack(fsm, datagram)) {
            ec_foe_set_rx_error(fsm, FOE_RX_DATA_ACK_ERROR);
            return;
        }

        fsm->state = ec_fsm_foe_state_sent_ack;
    }
    else {
        // no more data fits into the delivered buffer
        // ... wait for new read request
        printk ("ERROR: data doesn't fit in receive buffer\n");
        printk ("       rx_buffer_size  = %d\n", fsm->rx_buffer_size);
        printk ("       rx_buffer_offset= %d\n", fsm->rx_buffer_offset);
        printk ("       rec_size        = %zd\n", rec_size);
        printk ("       rx_mailbox_size = %d\n",
                slave->configured_rx_mailbox_size);
        printk ("       rx_last_packet  = %d\n", fsm->rx_last_packet);
        fsm->request->result = FOE_READY;
    }
}

/*****************************************************************************/

/** Sent an acknowledge.
 */
void ec_fsm_foe_state_sent_ack(
        ec_fsm_foe_t *fsm, /**< FoE statemachine. */
        ec_datagram_t *datagram /**< Datagram to use. */
        )
{
    ec_slave_t *slave = fsm->slave;

#ifdef DEBUG_FOE
    printk("ec_foe_state_sent_ack()\n");
#endif

    if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
        ec_foe_set_rx_error(fsm, FOE_RECEIVE_ERROR);
        EC_SLAVE_ERR(slave, "Failed to send FoE ACK: ");
        ec_datagram_print_state(fsm->datagram);
        return;
    }

    if (fsm->datagram->working_counter != 1) {
        // slave did not put anything into the mailbox yet
        ec_foe_set_rx_error(fsm, FOE_WC_ERROR);
        EC_SLAVE_ERR(slave, "Reception of FoE ACK failed: ");
        ec_datagram_print_wc_error(fsm->datagram);
        return;
    }

    fsm->jiffies_start = fsm->datagram->jiffies_sent;

    ec_slave_mbox_prepare_check(slave, datagram); // can not fail.

    if (fsm->rx_last_packet) {
        fsm->rx_expected_packet_no = 0;
        fsm->request->data_size = fsm->rx_buffer_offset;
        fsm->state = ec_fsm_foe_end;
    }
    else {
        fsm->rx_expected_packet_no++;
        fsm->retries = EC_FSM_RETRIES;
        fsm->state = ec_fsm_foe_state_data_check;
    }
}

/*****************************************************************************/

/** Set an error code and go to the send error state.
 */
void ec_foe_set_tx_error(
        ec_fsm_foe_t *fsm, /**< FoE statemachine. */
        uint32_t errorcode /**< FoE error code. */
        )
{
    fsm->request->result = errorcode;
    fsm->state = ec_fsm_foe_error;
}

/*****************************************************************************/

/** Set an error code and go to the receive error state.
 */
void ec_foe_set_rx_error(
        ec_fsm_foe_t *fsm, /**< FoE statemachine. */
        uint32_t errorcode /**< FoE error code. */
        )
{
    fsm->request->result = errorcode;
    fsm->state = ec_fsm_foe_error;
}

/*****************************************************************************/


<|start_filename|>3rdpart/tslib-1.15/plugins/dmc_dus3000-raw.c<|end_filename|>
/*
 * Copyright 2017 <NAME> <<EMAIL>>
 *
 * SPDX-License-Identifier: LGPL-2.1
 */

/*
 * DMC projected capacitive touch screen - DUS Series (tested with DUS3000)
 *
 * - UART and winxp mode only
 * - module linear and running ts_calibrate once is required
 *   (on-board calibration is not triggered)
 *
 * From the Software Spec, Copyright 2014 DMC Co., Ltd.:
 *
 * UART Interface
 * ---------------------
 * Baud rate	57600
 * Data bit	8bits
 * Parity	None
 * Stop bit	1bit
 * Flow control	None
 *
 * Transmission of the coordinate data will start once the host computer sends
 * instruction for starting via coordinate output control command.
 *
 * Report ID is 0x01, and mouse format (SW: 0x00=up, 0x01=down) will be placed after it.
 * 0		1		2		3		4		5
 * Report ID	SW		X (lower byte)	X (upper)	Y (lower)	Y (upper)
 *
 *
 * TODO There is a USB and multitouch mode too. Support that in Linux' usbtouchscreen.
 */
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <inttypes.h>
#include <errno.h>
#include <termios.h>

#include "config.h"
#include "tslib-private.h"

typedef enum {
	tr_id_none       = 0x00,
	tr_id_cal_offset = 0x01,
	tr_id_vers_info  = 0x04,
	tr_id_firmw_info = 0x06,
	tr_id_adj_offset = 0x17
} TTouchResponseIDs;

typedef enum {
	tm_version_info,
	tm_detailed_firmw_info,
	tm_setup_winxp,
	tm_coordinates_on,
	tm_coordinates_off,
	tm_adjust_offset,
	tm_calibrate_offset,
	tm_NumberOfTouchMessages
} TTouchMessages;

typedef enum {
	AdjustOffset = 0,
	CalibrateOffset,
	Coordinates
} TState;

struct tslib_dus3000 {
	struct tslib_module_info module;

	TState state;
	ssize_t rxPosition;
	uint8_t rxBuffer[0x110]; // messages with length field have 3 bytes + (contents of length field)
	                         // bytes (so max 255) + one null byte we add for strings; round that up
};

static void dus3000_init_data(struct tslib_dus3000 *d)
{
	d->state = Coordinates;
	d->rxPosition = 0;
}

struct Command {
	uint8_t length;
	uint8_t data[5];
};

static int send_command(int fd, TTouchMessages id)
{
	static const struct Command commands[tm_NumberOfTouchMessages] = {
		{ 5, { 0x02, 0x4C, 0x02, 0x04, 0x00 } }, // tm_version_info
		{ 5, { 0x02, 0x4C, 0x02, 0x06, 0x00 } }, // tm_detailed_firmw_info
		{ 5, { 0x02, 0x4C, 0x02, 0x80, 0x04 } }, // tm_setup_winxp
		{ 5, { 0x02, 0x4C, 0x02, 0x81, 0x01 } }, // tm_coordinates_on
		{ 5, { 0x02, 0x4C, 0x02, 0x81, 0x00 } }, // tm_coordinates_off
		{ 4, { 0x02, 0x4C, 0x01, 0x17, 0x00 } }, // tm_adjust_offset
		{ 4, { 0x02, 0x4C, 0x01, 0x01, 0x00 } }  // tm_calibrate_offset
	};
	const ssize_t length = commands[id].length;
	// writing synchronously to an fd opened in async mode is slightly dubious, but
	// we can reasonably expect that such small amounts of data are buffered on the
	// sending (our) side.
	return write(fd, commands[id].data, length) == length;
}

static void dus3000_init_device(struct tslib_dus3000 *d, struct tsdev *dev)
{
	const int fd = dev->fd;

	struct termios tty;
	tcgetattr(fd, &tty);
	tty.c_iflag = IGNBRK | IGNPAR;
	tty.c_oflag = 0;
	tty.c_lflag = 0;
	tty.c_line = 0;
	tty.c_cc[VTIME] = 0;
	tty.c_cc[VMIN] = 1;
	tty.c_cflag = CS8 | CREAD | CLOCAL | HUPCL;
	cfsetispeed (&tty, B57600);
	cfsetospeed (&tty, B57600);
	tcsetattr(fd, TCSAFLUSH, &tty);

	// Using XP mode because that's the easiest way to get single-touch without filtering
	// which finger(s) to accept.
	send_command(fd, tm_setup_winxp);

	switch (d->state) {
	case AdjustOffset:
		send_command(fd, tm_adjust_offset);
		break;
	case CalibrateOffset:
		send_command(fd, tm_calibrate_offset);
		break;
	case Coordinates:
		send_command(fd, tm_coordinates_on);
		break;
	}
}

static int read_to_pos(int fd, struct tslib_dus3000 *d, ssize_t pos)
{
	ssize_t toRead = pos - d->rxPosition;
	if (toRead <= 0) {
		return 1;
	}
	ssize_t r = read(fd, &d->rxBuffer[d->rxPosition], toRead);
	if (r >= 0) {
		d->rxPosition += r;
		return 1;
	} else {
		return 0;
	}
}

static int dus3000_read(struct tslib_module_info *m, struct ts_sample *samples, int maxSamples)
{
	struct tslib_dus3000 *const d = (struct tslib_dus3000 *)m;
	const int fd = m->dev->fd;
	int i = 0;

	for (i = 0; i < maxSamples; ) {
		// - Read until we have at least four bytes, which is <= minimum reply length and also
		//   sufficient to determine the final length of all kinds of replies
		// then... code:
		if (!read_to_pos(fd, d, 4)) {
			break;
		}

		if (d->rxPosition >= 4) {
			if (d->rxBuffer[0] == 0x01) {
				if (!read_to_pos(fd, d, 6)) {
					break;
				}
				// read finger up / down and coordinates
				samples[i].pressure = d->rxBuffer[1] ? 255 : 0;
				samples[i].x = ((int)d->rxBuffer[2]) | (((int)d->rxBuffer[3]) << 8);
				samples[i].y = ((int)d->rxBuffer[4]) | (((int)d->rxBuffer[5]) << 8);
				i++;
				d->rxPosition = 0; // message complete

			} else if (d->rxBuffer[0] == 0x02 && d->rxBuffer[1] == 0x4c) {

				const ssize_t fullRequiredLength = 3 + d->rxBuffer[2];
				if (!read_to_pos(fd, d, fullRequiredLength)) {
					break;
				}
				d->rxPosition = 0; // message complete

				switch (d->rxBuffer[3]) {
				case tr_id_vers_info: // "acquisition of version information" response
					// get rest of message. length is stored in m_RxBuf[2]
#ifdef DEBUG
					d->rxBuffer[fullRequiredLength] = '\0';
					fprintf(stderr, "Version information: %s\n", d->rxBuffer + 3);
#endif
					break;

				case tr_id_firmw_info: // "firmware detailed information" response
#ifdef DEBUG
					d->rxBuffer[fullRequiredLength] = '\0';
					fprintf(stderr, "Firmware information: %s\n", d->rxBuffer);
#endif
					break;

				case tr_id_adj_offset: // "adjust offset" response
					if (d->state == AdjustOffset && d->rxBuffer[4] != 0) {
#ifdef DEBUG
						fprintf(stderr, "Adjust offset succeeded!\n");
#endif
					} else {
						// abort calibration if command transmission failed
						continue;
					}
					if (!send_command(fd, tm_calibrate_offset)) {
						fprintf(stderr,
							"Calibrate offset command transmission failed!\n");
						continue;
					}
					d->state = CalibrateOffset;
					break;

				case tr_id_cal_offset: // "calibrate offset" response
					if (d->state == CalibrateOffset && d->rxBuffer[4] != 0) {
#ifdef DEBUG
						fprintf(stderr, "Calibrate offset succeeded!\n");
#endif
					} else {
						// abort calibration if command transmission failed
						fprintf(stderr, "Calibrate offset failed!\n");
						continue;
					}
					// calibration done, restart coordinate transmission
					if (!send_command(fd, tm_coordinates_on)) {
						fprintf(stderr,
							"Enable coordinates command transmission failed!\n");
						continue;
					}
					d->state = Coordinates;
#ifdef DEBUG
					fprintf(stderr, "Calibration finished!\n");
#endif
					break;

				} // switch
			} else {
				fprintf(stderr,
					"DUS3000: unknown response 0x %02x %02x %02x %02x - resynchronizing!\n",
					d->rxBuffer[0], d->rxBuffer[1], d->rxBuffer[2], d->rxBuffer[3]);

				// stop coordinate transmission, flush buffers, and re-enable
				send_command(fd, tm_coordinates_off);
				usleep (50000); // let all pending data arrive in our buffer
				tcflush(fd, TCIOFLUSH); // clear buffers
				d->rxPosition = 0;
				d->state = Coordinates;
				send_command(fd, tm_coordinates_on);

			}
		}
	}

	return i;
}

static int dus3000_fini(struct tslib_module_info *inf)
{
	free(inf);

	return 0;
}

static const struct tslib_ops dus3000_ops = {
	.read	= dus3000_read,
	.fini	= dus3000_fini,
};

TSAPI struct tslib_module_info *dmc_dus3000_mod_init(struct tsdev *dev,
			    __attribute__ ((unused)) const char *params)
{
	struct tslib_dus3000 *d = calloc(1, sizeof(struct tslib_dus3000));
	if (d == NULL)
		return NULL;

	dus3000_init_data(d);
	dus3000_init_device(d, dev);

	d->module.ops = &dus3000_ops;
	return &(d->module);
}

#ifndef TSLIB_STATIC_DMC_DUS3000_MODULE
	TSLIB_MODULE_INIT(dmc_dus3000_mod_init);
#endif


<|start_filename|>3rdpart/tslib-1.15/src/ts_config.c<|end_filename|>
/*
 *  tslib/src/ts_config.c
 *
 *  Copyright (C) 2001 <NAME>.
 *
 * This file is placed under the LGPL.  Please see the file
 * COPYING for more details.
 *
 * SPDX-License-Identifier: LGPL-2.1
 *
 *
 * Read the configuration and load the appropriate drivers.
 */
#include "config.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

#ifdef HAVE_LIBDL
#include <dlfcn.h>
#endif

#include <errno.h>

#if !defined(HAVE_STRSEP)
#include "ts_strsep.h"
#endif

#include "tslib-private.h"

/* Maximum line size is BUF_SIZE - 2
 * -1 for fgets and -1 to test end of line
 */
#define BUF_SIZE 512

/* Discard any empty tokens
 * Note: strsep modifies p (see man strsep)
 */
static void discard_null_tokens(char **p, char **tokPtr)
{
	while (*p != NULL && **tokPtr == '\0') {
	#if !defined HAVE_STRSEP
		*tokPtr = ts_strsep(p, "\t");
	#else
		*tokPtr = strsep(p, " \t");
	#endif
	}
}

int ts_config(struct tsdev *ts)
{
	char buf[BUF_SIZE], *p;
	FILE *f;
	int line = 0;
	int ret = 0;
	short strdup_allocated = 0;

	char *conffile;

	if ((conffile = getenv("TSLIB_CONFFILE")) == NULL) {
		conffile = strdup(TS_CONF);
		if (conffile) {
			strdup_allocated = 1;
		} else {
			ts_error("Couldn't find tslib config file: %s\n",
				 strerror(errno));
			return -1;
		}
	}

	f = fopen(conffile, "r");
	if (!f) {
		if (strdup_allocated)
			free(conffile);

		ts_error("Couldn't open tslib config file: %s\n",
			 strerror(errno));
		return -1;
	}

	buf[BUF_SIZE - 2] = '\0';
	while ((p = fgets(buf, BUF_SIZE, f)) != NULL) {
		char *e;
		char *tok;
		char *module_name;

		line++;

		/* Chomp */
		e = strchr(p, '\n');
		if (e)
			*e = '\0';

		/* Did we read a whole line? */
		if (buf[BUF_SIZE - 2] != '\0') {
			ts_error("%s: line %d too long\n", conffile, line);
			break;
		}

	#if !defined HAVE_STRSEP
		tok = ts_strsep(&p, " \t");
	#else
		tok = strsep(&p, " \t");
	#endif
		discard_null_tokens(&p, &tok);

		/* Ignore comments or blank lines.
		 * Note: strsep modifies p (see man strsep)
		 */
		if (p == NULL || *tok == '#')
			continue;

		/* Search for the option. */
		if (strcasecmp(tok, "module") == 0) {
		#if !defined HAVE_STRSEP
			module_name = ts_strsep(&p, " \t");
		#else
			module_name = strsep(&p, " \t");
		#endif
			discard_null_tokens(&p, &module_name);
			ret = ts_load_module(ts, module_name, p);
		} else if (strcasecmp(tok, "module_raw") == 0) {
		#if !defined HAVE_STRSEP
			module_name = ts_strsep(&p, " \t");
		#else
			module_name = strsep(&p, " \t");
		#endif
			discard_null_tokens(&p, &module_name);
			ret = ts_load_module_raw(ts, module_name, p);
		} else {
			ts_error("%s: Unrecognised option %s:%d:%s\n",
				 conffile, line, tok);
			break;
		}
		if (ret != 0) {
			ts_error("Couldnt load module %s\n", module_name);
			break;
		}
	}

	if (ts->list_raw == NULL) {
		ts_error("No raw modules loaded.\n");
		ret = -1;
	}

	fclose(f);

	if (strdup_allocated)
		free(conffile);

	return ret;
}

int ts_reconfig(struct tsdev *ts)
{
	void *handle;
	int ret;
	struct tslib_module_info *info, *next;
	int fd;

	info = ts->list;
	while (info) {
		/* Save the "next" pointer now because info will be freed */
		next = info->next;

		handle = info->handle;

		if (info->ops->fini)
			info->ops->fini(info);
	#ifdef HAVE_LIBDL
		if (handle)
			dlclose(handle);
	#endif

		info = next;
	}

	fd = ts->fd;	/* save temp */
	memset(ts, 0, sizeof(struct tsdev));
	ts->fd = fd;

	ret = ts_config(ts);
	return ret;
}


<|start_filename|>3rdpart/tslib-1.15/plugins/iir.c<|end_filename|>
/*
 *  tslib/plugins/iir.c
 *
 *  Copyright (C) 2017 <NAME>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * SPDX-License-Identifier: LGPL-2.1
 *
 *
 * Similar to dejitter, this is a smoothing filter to remove low-level noise.
 * See https://en.wikipedia.org/wiki/Infinite_impulse_response for some theory.
 * There is a trade-off between noise removal (smoothing) and responsiveness:
 * The parameters N and D specify the level of smoothing in the form of a
 * fraction (N/D).
 *
 * The discrete formula we use is found at http://dlbeer.co.nz/articles/tsf.html
 */
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <stdint.h>

#include <stdio.h>

#include "config.h"
#include "tslib.h"
#include "tslib-filter.h"

struct tslib_iir {
	struct tslib_module_info module;
	uint32_t D;
	uint32_t N;
	int32_t slots;
	uint32_t nr;
	int32_t s;
	int32_t t;
	uint8_t last_active; /* for finding pen-down */

	int32_t *s_mt;
	int32_t *t_mt;
	uint8_t *last_active_mt; /* for finding pen-down */
};

static void iir_filter(struct tslib_module_info *info, int32_t *new,
		       int32_t *save)
{
	struct tslib_iir *iir = (struct tslib_iir *)info;

	*save = (iir->N * *save + (iir->D - iir->N) * *new + iir->D / 2) / iir->D;
}

/* legacy read interface */
static int iir_read(struct tslib_module_info *info, struct ts_sample *samp,
		    int nr)
{
	struct tslib_iir *iir = (struct tslib_iir *)info;
	int32_t ret;
	int32_t i;

	ret = info->next->ops->read(info->next, samp, nr);
	if (ret < 0)
		return ret;

	for (i = 0; i < ret; i++, samp++) {
		if (samp->pressure == 0) { /* reset */
			iir->s = samp->x;
			iir->t = samp->y;
			iir->last_active = 0;
			continue;
		} else if (iir->last_active == 0) {
			iir->s = samp->x;
			iir->t = samp->y;
			iir->last_active = 1;
			continue;
		}

		iir_filter(info, &samp->x, &iir->s);
	#ifdef DEBUG
		printf("IIR: X: %d -> %d\n", samp->x, iir->s);
	#endif
		samp->x = iir->s;

		iir_filter(info, &samp->y, &iir->t);
	#ifdef DEBUG
		printf("IIR: Y: %d -> %d\n", samp->y, iir->t);
	#endif
		samp->y = iir->t;
	}

	return ret;
}

static int iir_read_mt(struct tslib_module_info *info,
		       struct ts_sample_mt **samp, int max_slots, int nr)
{
	struct tslib_iir *iir = (struct tslib_iir *)info;
	int32_t ret;
	int32_t i, j;

	if (!iir->s_mt || max_slots > iir->slots) {
		if (iir->s_mt)
			free(iir->s_mt);

		if (iir->t_mt)
			free(iir->t_mt);

		if (iir->last_active_mt)
			free(iir->last_active_mt);

		iir->s_mt = calloc(max_slots, sizeof(int32_t));
		if (!iir->s_mt)
			return -ENOMEM;

		iir->t_mt = calloc(max_slots, sizeof(int32_t));
		if (!iir->t_mt)
			return -ENOMEM;

		iir->last_active_mt = calloc(max_slots, sizeof(uint8_t));
		if (!iir->last_active_mt)
			return -ENOMEM;

		iir->slots = max_slots;
	}

	if (!info->next->ops->read_mt)
		return -ENOSYS;

	ret = info->next->ops->read_mt(info->next, samp, max_slots, nr);
	if (ret < 0)
		return ret;

	for (i = 0; i < ret; i++) {
		for (j = 0; j < max_slots; j++) {
			if (!(samp[i][j].valid & TSLIB_MT_VALID))
				continue;
			/* reset */
			if (samp[i][j].pressure == 0) { /* pen-up */
				iir->s_mt[j] = samp[i][j].x;
				iir->t_mt[j] = samp[i][j].y;
				iir->last_active_mt[j] = 0;
				continue;
			} else if (iir->last_active_mt[j] == 0) { /* pen-down */
				iir->s_mt[j] = samp[i][j].x;
				iir->t_mt[j] = samp[i][j].y;
				iir->last_active_mt[j] = 1;
				continue;
			}

			iir_filter(info, &samp[i][j].x, &iir->s_mt[j]);
		#ifdef DEBUG
			printf("IIR: (slot %d) X: %d -> %d\n",
			       j, samp[i][j].x, iir->s_mt[j]);
		#endif
			samp[i][j].x = iir->s_mt[j];

			iir_filter(info, &samp[i][j].y, &iir->t_mt[j]);
		#ifdef DEBUG
			printf("IIR: (slot %d) Y: %d -> %d\n",
			       j, samp[i][j].y, iir->t_mt[j]);
		#endif
			samp[i][j].y = iir->t_mt[j];
		}
	}

	return ret;
}

static int iir_fini(struct tslib_module_info *info)
{
	struct tslib_iir *iir = (struct tslib_iir *)info;

	if (iir->s_mt)
		free(iir->s_mt);

	if (iir->t_mt)
		free(iir->t_mt);

	if (iir->last_active_mt)
		free(iir->last_active_mt);

	free(info);

	return 0;
}

static const struct tslib_ops iir_ops = {
	.read		= iir_read,
	.read_mt	= iir_read_mt,
	.fini		= iir_fini,
};

static int iir_opt(struct tslib_module_info *inf, char *str, void *data)
{
	struct tslib_iir *iir = (struct tslib_iir *)inf;
	unsigned long v;
	int32_t err = errno;

	v = strtoul(str, NULL, 0);

	if (v == ULONG_MAX && errno == ERANGE)
		return -1;

	errno = err;
	switch ((int)(intptr_t)data) {
	case 1:
		iir->N = v;
		break;

	case 2:
		iir->D = v;
		if (iir->D == 0) {
			printf("IIR: avoid division by zero: D=1 set\n");
			iir->D = 1;
		}
		break;

	default:
		return -1;
	}


	return 0;
}

static const struct tslib_vars iir_vars[] = {
	{ "N",	(void *)1, iir_opt },
	{ "D",	(void *)2, iir_opt },
};

#define NR_VARS (sizeof(iir_vars) / sizeof(iir_vars[0]))

TSAPI struct tslib_module_info *iir_mod_init(__attribute__ ((unused)) struct tsdev *dev,
					     const char *params)
{
	struct tslib_iir *iir;

	iir = malloc(sizeof(struct tslib_iir));
	if (iir == NULL)
		return NULL;

	memset(iir, 0, sizeof(struct tslib_iir));
	iir->module.ops = &iir_ops;

	iir->N = 0;
	iir->D = 0;
	iir->slots = 0;
	iir->nr = 0;
	iir->s = 0;
	iir->t = 0;
	iir->s_mt = NULL;
	iir->t_mt = NULL;
	iir->last_active = 0;

	if (tslib_parse_vars(&iir->module, iir_vars, NR_VARS, params)) {
		free(iir);
		return NULL;
	}

	return &iir->module;
}

#ifndef TSLIB_STATIC_IIR_MODULE
	TSLIB_MODULE_INIT(iir_mod_init);
#endif


<|start_filename|>3rdpart/tslib-1.15/src/ts_strsep.c<|end_filename|>
/*
 *  tslib/src/ts_strsep.c
 *
 * This file is placed under the LGPL.  Please see the file
 * COPYING for more details.
 *
 * SPDX-License-Identifier: LGPL-2.1
 */
#include "ts_strsep.h"

char *ts_strsep(char **stringp, const char *delim)
{
	char *start = *stringp;
	char *p;

	p = (start) ? strpbrk(start, delim) : NULL;

	if (!p) {
		*stringp = NULL;
	} else {
		*p = '\0';
		*stringp = p + 1;
	}

	return start;
}


<|start_filename|>3rdpart/ethercat-1.5.2/examples/rtai/rtai_sample.c<|end_filename|>
/******************************************************************************
 *
 *  RTAI sample for the IgH EtherCAT master.
 *
 *  $Id: rtai_sample.c,v bc2d4bf9cbe5 2012/09/06 18:22:24 fp $
 *
 *  Copyright (C) 2006-2008  <NAME>, Ingenieurgemeinschaft IgH
 *
 *  This file is part of the IgH EtherCAT Master.
 *
 *  The IgH EtherCAT Master is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License version 2, as
 *  published by the Free Software Foundation.
 *
 *  The IgH EtherCAT Master is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 *  Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with the IgH EtherCAT Master; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 *****************************************************************************/

// Linux
#include <linux/module.h>
#include <linux/err.h>

// RTAI
#include <rtai_sched.h>
#include <rtai_sem.h>

// EtherCAT
#include "../../include/ecrt.h"

/*****************************************************************************/

// Module parameters

#define FREQUENCY 2000 // task frequency in Hz
#define INHIBIT_TIME 20

#define TIMERTICKS (1000000000 / FREQUENCY)

// Optional features (comment to disable)
#define CONFIGURE_PDOS

#define PFX "ec_rtai_sample: "

/*****************************************************************************/

// EtherCAT
static ec_master_t *master = NULL;
static ec_master_state_t master_state = {};

static ec_domain_t *domain1 = NULL;
static ec_domain_state_t domain1_state = {};

static ec_slave_config_t *sc_ana_in = NULL;
static ec_slave_config_state_t sc_ana_in_state = {};

// RTAI
static RT_TASK task;
static SEM master_sem;
static cycles_t t_last_cycle = 0, t_critical;

/*****************************************************************************/

// process data
static uint8_t *domain1_pd; // process data memory

#define AnaInSlavePos  0, 3
#define DigOutSlavePos 0, 2

#define Beckhoff_EL2004 0x00000002, 0x07D43052
#define Beckhoff_EL3162 0x00000002, 0x0C5A3052

static unsigned int off_ana_in; // offsets for PDO entries
static unsigned int off_dig_out;

const static ec_pdo_entry_reg_t domain1_regs[] = {
    {AnaInSlavePos,  Beckhoff_EL3162, 0x3101, 2, &off_ana_in},
    {DigOutSlavePos, Beckhoff_EL2004, 0x3001, 1, &off_dig_out},
    {}
};

static unsigned int counter = 0;
static unsigned int blink = 0;

/*****************************************************************************/

#ifdef CONFIGURE_PDOS
static ec_pdo_entry_info_t el3162_channel1[] = {
    {0x3101, 1,  8}, // status
    {0x3101, 2, 16}  // value
};

static ec_pdo_entry_info_t el3162_channel2[] = {
    {0x3102, 1,  8}, // status
    {0x3102, 2, 16}  // value
};

static ec_pdo_info_t el3162_pdos[] = {
    {0x1A00, 2, el3162_channel1},
    {0x1A01, 2, el3162_channel2}
};

static ec_sync_info_t el3162_syncs[] = {
    {2, EC_DIR_OUTPUT},
    {3, EC_DIR_INPUT, 2, el3162_pdos},
    {0xff}
};

static ec_pdo_entry_info_t el2004_channels[] = {
    {0x3001, 1, 1}, // Value 1
    {0x3001, 2, 1}, // Value 2
    {0x3001, 3, 1}, // Value 3
    {0x3001, 4, 1}  // Value 4
};

static ec_pdo_info_t el2004_pdos[] = {
    {0x1600, 1, &el2004_channels[0]},
    {0x1601, 1, &el2004_channels[1]},
    {0x1602, 1, &el2004_channels[2]},
    {0x1603, 1, &el2004_channels[3]}
};

static ec_sync_info_t el2004_syncs[] = {
    {0, EC_DIR_OUTPUT, 4, el2004_pdos},
    {1, EC_DIR_INPUT},
    {0xff}
};
#endif

/*****************************************************************************/

void check_domain1_state(void)
{
    ec_domain_state_t ds;

    rt_sem_wait(&master_sem);
    ecrt_domain_state(domain1, &ds);
    rt_sem_signal(&master_sem);

    if (ds.working_counter != domain1_state.working_counter)
        printk(KERN_INFO PFX "Domain1: WC %u.\n", ds.working_counter);
    if (ds.wc_state != domain1_state.wc_state)
        printk(KERN_INFO PFX "Domain1: State %u.\n", ds.wc_state);

    domain1_state = ds;
}

/*****************************************************************************/

void check_master_state(void)
{
    ec_master_state_t ms;

    rt_sem_wait(&master_sem);
    ecrt_master_state(master, &ms);
    rt_sem_signal(&master_sem);

    if (ms.slaves_responding != master_state.slaves_responding)
        printk(KERN_INFO PFX "%u slave(s).\n", ms.slaves_responding);
    if (ms.al_states != master_state.al_states)
        printk(KERN_INFO PFX "AL states: 0x%02X.\n", ms.al_states);
    if (ms.link_up != master_state.link_up)
        printk(KERN_INFO PFX "Link is %s.\n", ms.link_up ? "up" : "down");

    master_state = ms;
}

/*****************************************************************************/

void check_slave_config_states(void)
{
    ec_slave_config_state_t s;

    rt_sem_wait(&master_sem);
    ecrt_slave_config_state(sc_ana_in, &s);
    rt_sem_signal(&master_sem);

    if (s.al_state != sc_ana_in_state.al_state)
        printk(KERN_INFO PFX "AnaIn: State 0x%02X.\n", s.al_state);
    if (s.online != sc_ana_in_state.online)
        printk(KERN_INFO PFX "AnaIn: %s.\n", s.online ? "online" : "offline");
    if (s.operational != sc_ana_in_state.operational)
        printk(KERN_INFO PFX "AnaIn: %soperational.\n",
                s.operational ? "" : "Not ");

    sc_ana_in_state = s;
}

/*****************************************************************************/

void run(long data)
{
    while (1) {
        t_last_cycle = get_cycles();

        // receive process data
        rt_sem_wait(&master_sem);
        ecrt_master_receive(master);
        ecrt_domain_process(domain1);
        rt_sem_signal(&master_sem);

        // check process data state (optional)
        check_domain1_state();

        if (counter) {
            counter--;
        } else { // do this at 1 Hz
            counter = FREQUENCY;

            // calculate new process data
            blink = !blink;

            // check for master state (optional)
            check_master_state();

            // check for islave configuration state(s) (optional)
            check_slave_config_states();
        }

        // write process data
        EC_WRITE_U8(domain1_pd + off_dig_out, blink ? 0x06 : 0x09);

        rt_sem_wait(&master_sem);
        ecrt_domain_queue(domain1);
        ecrt_master_send(master);
        rt_sem_signal(&master_sem);

        rt_task_wait_period();
    }
}

/*****************************************************************************/

void send_callback(void *cb_data)
{
    ec_master_t *m = (ec_master_t *) cb_data;

    // too close to the next real time cycle: deny access...
    if (get_cycles() - t_last_cycle <= t_critical) {
        rt_sem_wait(&master_sem);
        ecrt_master_send_ext(m);
        rt_sem_signal(&master_sem);
    }
}

/*****************************************************************************/

void receive_callback(void *cb_data)
{
    ec_master_t *m = (ec_master_t *) cb_data;

    // too close to the next real time cycle: deny access...
    if (get_cycles() - t_last_cycle <= t_critical) {
        rt_sem_wait(&master_sem);
        ecrt_master_receive(m);
        rt_sem_signal(&master_sem);
    }
}

/*****************************************************************************/

int __init init_mod(void)
{
    int ret = -1;
    RTIME tick_period, requested_ticks, now;
#ifdef CONFIGURE_PDOS
    ec_slave_config_t *sc;
#endif

    printk(KERN_INFO PFX "Starting...\n");

    rt_sem_init(&master_sem, 1);

    t_critical = cpu_khz * 1000 / FREQUENCY - cpu_khz * INHIBIT_TIME / 1000;

    master = ecrt_request_master(0);
    if (!master) {
        ret = -EBUSY;
        printk(KERN_ERR PFX "Requesting master 0 failed!\n");
        goto out_return;
    }

    ecrt_master_callbacks(master, send_callback, receive_callback, master);

    printk(KERN_INFO PFX "Registering domain...\n");
    if (!(domain1 = ecrt_master_create_domain(master))) {
        printk(KERN_ERR PFX "Domain creation failed!\n");
        goto out_release_master;
    }

    if (!(sc_ana_in = ecrt_master_slave_config(
                    master, AnaInSlavePos, Beckhoff_EL3162))) {
        printk(KERN_ERR PFX "Failed to get slave configuration.\n");
        goto out_release_master;
    }

#ifdef CONFIGURE_PDOS
    printk(KERN_INFO PFX "Configuring PDOs...\n");
    if (ecrt_slave_config_pdos(sc_ana_in, EC_END, el3162_syncs)) {
        printk(KERN_ERR PFX "Failed to configure PDOs.\n");
        goto out_release_master;
    }

    if (!(sc = ecrt_master_slave_config(master, DigOutSlavePos, Beckhoff_EL2004))) {
        printk(KERN_ERR PFX "Failed to get slave configuration.\n");
        goto out_release_master;
    }

    if (ecrt_slave_config_pdos(sc, EC_END, el2004_syncs)) {
        printk(KERN_ERR PFX "Failed to configure PDOs.\n");
        goto out_release_master;
    }
#endif

    printk(KERN_INFO PFX "Registering PDO entries...\n");
    if (ecrt_domain_reg_pdo_entry_list(domain1, domain1_regs)) {
        printk(KERN_ERR PFX "PDO entry registration failed!\n");
        goto out_release_master;
    }

    printk(KERN_INFO PFX "Activating master...\n");
    if (ecrt_master_activate(master)) {
        printk(KERN_ERR PFX "Failed to activate master!\n");
        goto out_release_master;
    }

    // Get internal process data for domain
    domain1_pd = ecrt_domain_data(domain1);

    printk(KERN_INFO PFX "Starting cyclic sample thread...\n");
    requested_ticks = nano2count(TIMERTICKS);
    tick_period = start_rt_timer(requested_ticks);
    printk(KERN_INFO PFX "RT timer started with %i/%i ticks.\n",
           (int) tick_period, (int) requested_ticks);

    if (rt_task_init(&task, run, 0, 2000, 0, 1, NULL)) {
        printk(KERN_ERR PFX "Failed to init RTAI task!\n");
        goto out_stop_timer;
    }

    now = rt_get_time();
    if (rt_task_make_periodic(&task, now + tick_period, tick_period)) {
        printk(KERN_ERR PFX "Failed to run RTAI task!\n");
        goto out_stop_task;
    }

    printk(KERN_INFO PFX "Initialized.\n");
    return 0;

 out_stop_task:
    rt_task_delete(&task);
 out_stop_timer:
    stop_rt_timer();
 out_release_master:
    printk(KERN_ERR PFX "Releasing master...\n");
    ecrt_release_master(master);
 out_return:
    rt_sem_delete(&master_sem);
    printk(KERN_ERR PFX "Failed to load. Aborting.\n");
    return ret;
}

/*****************************************************************************/

void __exit cleanup_mod(void)
{
    printk(KERN_INFO PFX "Stopping...\n");

    rt_task_delete(&task);
    stop_rt_timer();
    ecrt_release_master(master);
    rt_sem_delete(&master_sem);

    printk(KERN_INFO PFX "Unloading.\n");
}

/*****************************************************************************/

MODULE_LICENSE("GPL");
MODULE_AUTHOR("<NAME> <<EMAIL>>");
MODULE_DESCRIPTION("EtherCAT RTAI sample module");

module_init(init_mod);
module_exit(cleanup_mod);

/*****************************************************************************/


<|start_filename|>3rdpart/ethercat-1.5.2/examples/dc_user/main.c<|end_filename|>
/*****************************************************************************
 *
 *  $Id: main.c,v bc2d4bf9cbe5 2012/09/06 18:22:24 fp $
 *
 *  Copyright (C) 2007-2009  <NAME>, Ingenieurgemeinschaft IgH
 *
 *  This file is part of the IgH EtherCAT Master.
 *
 *  The IgH EtherCAT Master is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License version 2, as
 *  published by the Free Software Foundation.
 *
 *  The IgH EtherCAT Master is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 *  Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with the IgH EtherCAT Master; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 ****************************************************************************/

#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <sys/resource.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <time.h>
#include <sys/mman.h>
#include <malloc.h>

/****************************************************************************/

#include "ecrt.h"

/****************************************************************************/

// Application parameters
#define FREQUENCY 1000
#define CLOCK_TO_USE CLOCK_REALTIME
#define MEASURE_TIMING

/****************************************************************************/

#define NSEC_PER_SEC (1000000000L)
#define PERIOD_NS (NSEC_PER_SEC / FREQUENCY)

#define DIFF_NS(A, B) (((B).tv_sec - (A).tv_sec) * NSEC_PER_SEC + \
	(B).tv_nsec - (A).tv_nsec)

#define TIMESPEC2NS(T) ((uint64_t) (T).tv_sec * NSEC_PER_SEC + (T).tv_nsec)

/****************************************************************************/

// EtherCAT
static ec_master_t *master = NULL;
static ec_master_state_t master_state = {};

static ec_domain_t *domain1 = NULL;
static ec_domain_state_t domain1_state = {};

/****************************************************************************/

// process data
static uint8_t *domain1_pd = NULL;

#define BusCouplerPos    0, 0
#define DigOutSlavePos   0, 1
#define CounterSlavePos  0, 2

#define Beckhoff_EK1100 0x00000002, 0x044c2c52
#define Beckhoff_EL2008 0x00000002, 0x07d83052
#define IDS_Counter     0x000012ad, 0x05de3052

// offsets for PDO entries
static int off_dig_out;
static int off_counter_in;
static int off_counter_out;

static unsigned int counter = 0;
static unsigned int blink = 0;
static unsigned int sync_ref_counter = 0;
const struct timespec cycletime = {0, PERIOD_NS};

/*****************************************************************************/

struct timespec timespec_add(struct timespec time1, struct timespec time2)
{
	struct timespec result;

	if ((time1.tv_nsec + time2.tv_nsec) >= NSEC_PER_SEC) {
		result.tv_sec = time1.tv_sec + time2.tv_sec + 1;
		result.tv_nsec = time1.tv_nsec + time2.tv_nsec - NSEC_PER_SEC;
	} else {
		result.tv_sec = time1.tv_sec + time2.tv_sec;
		result.tv_nsec = time1.tv_nsec + time2.tv_nsec;
	}

	return result;
}

/*****************************************************************************/

void check_domain1_state(void)
{
    ec_domain_state_t ds;

    ecrt_domain_state(domain1, &ds);

    if (ds.working_counter != domain1_state.working_counter)
        printf("Domain1: WC %u.\n", ds.working_counter);
    if (ds.wc_state != domain1_state.wc_state)
        printf("Domain1: State %u.\n", ds.wc_state);

    domain1_state = ds;
}

/*****************************************************************************/

void check_master_state(void)
{
    ec_master_state_t ms;

    ecrt_master_state(master, &ms);

	if (ms.slaves_responding != master_state.slaves_responding)
        printf("%u slave(s).\n", ms.slaves_responding);
    if (ms.al_states != master_state.al_states)
        printf("AL states: 0x%02X.\n", ms.al_states);
    if (ms.link_up != master_state.link_up)
        printf("Link is %s.\n", ms.link_up ? "up" : "down");

    master_state = ms;
}

/****************************************************************************/

void cyclic_task()
{
    struct timespec wakeupTime, time;
#ifdef MEASURE_TIMING
    struct timespec startTime, endTime, lastStartTime = {};
    uint32_t period_ns = 0, exec_ns = 0, latency_ns = 0,
             latency_min_ns = 0, latency_max_ns = 0,
             period_min_ns = 0, period_max_ns = 0,
             exec_min_ns = 0, exec_max_ns = 0;
#endif

    // get current time
    clock_gettime(CLOCK_TO_USE, &wakeupTime);

	while(1) {
		wakeupTime = timespec_add(wakeupTime, cycletime);
        clock_nanosleep(CLOCK_TO_USE, TIMER_ABSTIME, &wakeupTime, NULL);

#ifdef MEASURE_TIMING
        clock_gettime(CLOCK_TO_USE, &startTime);
        latency_ns = DIFF_NS(wakeupTime, startTime);
        period_ns = DIFF_NS(lastStartTime, startTime);
        exec_ns = DIFF_NS(lastStartTime, endTime);
        lastStartTime = startTime;

        if (latency_ns > latency_max_ns) {
            latency_max_ns = latency_ns;
        }
        if (latency_ns < latency_min_ns) {
            latency_min_ns = latency_ns;
        }
        if (period_ns > period_max_ns) {
            period_max_ns = period_ns;
        }
        if (period_ns < period_min_ns) {
            period_min_ns = period_ns;
        }
        if (exec_ns > exec_max_ns) {
            exec_max_ns = exec_ns;
        }
        if (exec_ns < exec_min_ns) {
            exec_min_ns = exec_ns;
        }
#endif

		// receive process data
		ecrt_master_receive(master);
		ecrt_domain_process(domain1);

		// check process data state (optional)
		check_domain1_state();

		if (counter) {
			counter--;
		} else { // do this at 1 Hz
			counter = FREQUENCY;

			// check for master state (optional)
			check_master_state();

#ifdef MEASURE_TIMING
            // output timing stats
            printf("period     %10u ... %10u\n",
                    period_min_ns, period_max_ns);
            printf("exec       %10u ... %10u\n",
                    exec_min_ns, exec_max_ns);
            printf("latency    %10u ... %10u\n",
                    latency_min_ns, latency_max_ns);
            period_max_ns = 0;
            period_min_ns = 0xffffffff;
            exec_max_ns = 0;
            exec_min_ns = 0xffffffff;
            latency_max_ns = 0;
            latency_min_ns = 0xffffffff;
#endif

			// calculate new process data
			blink = !blink;
		}

		// write process data
		EC_WRITE_U8(domain1_pd + off_dig_out, blink ? 0x66 : 0x99);
		EC_WRITE_U8(domain1_pd + off_counter_out, blink ? 0x00 : 0x02);

		// write application time to master
		clock_gettime(CLOCK_TO_USE, &time);
		ecrt_master_application_time(master, TIMESPEC2NS(time));

		if (sync_ref_counter) {
			sync_ref_counter--;
		} else {
			sync_ref_counter = 1; // sync every cycle
			ecrt_master_sync_reference_clock(master);
		}
		ecrt_master_sync_slave_clocks(master);

		// send process data
		ecrt_domain_queue(domain1);
		ecrt_master_send(master);

#ifdef MEASURE_TIMING
        clock_gettime(CLOCK_TO_USE, &endTime);
#endif
	}
}

/****************************************************************************/

int main(int argc, char **argv)
{
    ec_slave_config_t *sc;

	if (mlockall(MCL_CURRENT | MCL_FUTURE) == -1) {
		perror("mlockall failed");
		return -1;
	}

    master = ecrt_request_master(0);
    if (!master)
        return -1;

    domain1 = ecrt_master_create_domain(master);
    if (!domain1)
        return -1;

    // Create configuration for bus coupler
    sc = ecrt_master_slave_config(master, BusCouplerPos, Beckhoff_EK1100);
    if (!sc)
        return -1;

    if (!(sc = ecrt_master_slave_config(master,
                    DigOutSlavePos, Beckhoff_EL2008))) {
        fprintf(stderr, "Failed to get slave configuration.\n");
        return -1;
    }

    off_dig_out = ecrt_slave_config_reg_pdo_entry(sc,
            0x7000, 1, domain1, NULL);
    if (off_dig_out < 0)
        return -1;

	if (!(sc = ecrt_master_slave_config(master,
					CounterSlavePos, IDS_Counter))) {
        fprintf(stderr, "Failed to get slave configuration.\n");
        return -1;
	}

	off_counter_in = ecrt_slave_config_reg_pdo_entry(sc,
			0x6020, 0x11, domain1, NULL);
	if (off_counter_in < 0)
        return -1;

	off_counter_out = ecrt_slave_config_reg_pdo_entry(sc,
			0x7020, 1, domain1, NULL);
	if (off_counter_out < 0)
        return -1;

    // configure SYNC signals for this slave
	ecrt_slave_config_dc(sc, 0x0700, PERIOD_NS, 4400000, 0, 0);

    printf("Activating master...\n");
    if (ecrt_master_activate(master))
        return -1;

    if (!(domain1_pd = ecrt_domain_data(domain1))) {
        return -1;
    }

    pid_t pid = getpid();
    if (setpriority(PRIO_PROCESS, pid, -19))
        fprintf(stderr, "Warning: Failed to set priority: %s\n",
                strerror(errno));

	printf("Starting cyclic function.\n");
    cyclic_task();

    return 0;
}

/****************************************************************************/


<|start_filename|>3rdpart/tslib-1.15/plugins/plugins.h<|end_filename|>
/*
 * SPDX-License-Identifier: LGPL-2.1
 */
#define TSLIB_DECLARE_MODULE(name) \
	TSAPI struct tslib_module_info *name##_mod_init(struct tsdev *dev, const char *params)

TSLIB_DECLARE_MODULE(linear);
TSLIB_DECLARE_MODULE(dejitter);
TSLIB_DECLARE_MODULE(linear_h2200);
TSLIB_DECLARE_MODULE(variance);
TSLIB_DECLARE_MODULE(median);
TSLIB_DECLARE_MODULE(pthres);
TSLIB_DECLARE_MODULE(debounce);
TSLIB_DECLARE_MODULE(skip);
TSLIB_DECLARE_MODULE(invert);
TSLIB_DECLARE_MODULE(iir);
TSLIB_DECLARE_MODULE(lowpass);

TSLIB_DECLARE_MODULE(arctic2);
TSLIB_DECLARE_MODULE(collie);
TSLIB_DECLARE_MODULE(corgi);
TSLIB_DECLARE_MODULE(cy8mrln_palmpre);
TSLIB_DECLARE_MODULE(dmc);
TSLIB_DECLARE_MODULE(dmc_dus3000);
TSLIB_DECLARE_MODULE(galax);
TSLIB_DECLARE_MODULE(h3600);
TSLIB_DECLARE_MODULE(input);
TSLIB_DECLARE_MODULE(mk712);
TSLIB_DECLARE_MODULE(tatung);
TSLIB_DECLARE_MODULE(touchkit);
TSLIB_DECLARE_MODULE(ucb1x00);
TSLIB_DECLARE_MODULE(waveshare);


<|start_filename|>3rdpart/tslib-1.15/tests/ts_calibrate_common.c<|end_filename|>
/*
 *  tslib/tests/ts_calibrate_common.c
 *
 *  Copyright (C) 2001 <NAME>.
 *
 * This file is placed under the GPL.  Please see the file
 * COPYING for more details.
 *
 * SPDX-License-Identifier: GPL-2.0+
 *
 *
 * common functions for calibration
 */
#include <stdio.h>
#include "ts_calibrate.h"

int perform_calibration(calibration *cal)
{
	int j;
	float n, x, y, x2, y2, xy, z, zx, zy;
	float det, a, b, c, e, f, i;
	float scaling = 65536.0;

	/* Get sums for matrix */
	n = x = y = x2 = y2 = xy = 0;
	for (j = 0; j < 5; j++) {
		n += 1.0;
		x += (float)cal->x[j];
		y += (float)cal->y[j];
		x2 += (float)(cal->x[j]*cal->x[j]);
		y2 += (float)(cal->y[j]*cal->y[j]);
		xy += (float)(cal->x[j]*cal->y[j]);
	}

	/* Get determinant of matrix -- check if determinant is too small */
	det = n*(x2*y2 - xy*xy) + x*(xy*y - x*y2) + y*(x*xy - y*x2);
	if (det < 0.1 && det > -0.1) {
		printf("ts_calibrate: determinant is too small -- %f\n", det);
		return 0;
	}

	/* Get elements of inverse matrix */
	a = (x2*y2 - xy*xy)/det;
	b = (xy*y - x*y2)/det;
	c = (x*xy - y*x2)/det;
	e = (n*y2 - y*y)/det;
	f = (x*y - n*xy)/det;
	i = (n*x2 - x*x)/det;

	/* Get sums for x calibration */
	z = zx = zy = 0;
	for (j = 0; j < 5; j++) {
		z += (float)cal->xfb[j];
		zx += (float)(cal->xfb[j]*cal->x[j]);
		zy += (float)(cal->xfb[j]*cal->y[j]);
	}

	/* Now multiply out to get the calibration for framebuffer x coord */
	cal->a[0] = (int)((a*z + b*zx + c*zy)*(scaling));
	cal->a[1] = (int)((b*z + e*zx + f*zy)*(scaling));
	cal->a[2] = (int)((c*z + f*zx + i*zy)*(scaling));

	printf("%f %f %f\n", (a*z + b*zx + c*zy),
			     (b*z + e*zx + f*zy),
			     (c*z + f*zx + i*zy));

	/* Get sums for y calibration */
	z = zx = zy = 0;
	for (j = 0; j < 5; j++) {
		z += (float)cal->yfb[j];
		zx += (float)(cal->yfb[j]*cal->x[j]);
		zy += (float)(cal->yfb[j]*cal->y[j]);
	}

	/* Now multiply out to get the calibration for framebuffer y coord */
	cal->a[3] = (int)((a*z + b*zx + c*zy)*(scaling));
	cal->a[4] = (int)((b*z + e*zx + f*zy)*(scaling));
	cal->a[5] = (int)((c*z + f*zx + i*zy)*(scaling));

	printf("%f %f %f\n", (a*z + b*zx + c*zy),
			     (b*z + e*zx + f*zy),
			     (c*z + f*zx + i*zy));

	/* If we got here, we're OK, so assign scaling to a[6] and return */
	cal->a[6] = (int)scaling;

	return 1;
}


<|start_filename|>3rdpart/tslib-1.15/src/ts_version.c<|end_filename|>
/*
 *  tslib/src/ts_version.c
 *
 *  Copyright (C) 2017 <NAME>
 *
 * This file is placed under the LGPL.  Please see the file
 * COPYING for more details.
 *
 * SPDX-License-Identifier: LGPL-2.1
 *
 *
 * This file contains libts version information only. Check the README.md
 * file for details.
 */
#include <stdlib.h>
#include "config.h"
#include "tslib.h"

static struct ts_lib_version_data version_data = {
	PACKAGE_VERSION,
	0x000000,	/* version_num calculated below */
	0		/* features */
	| TSLIB_VERSION_MT
	| TSLIB_VERSION_OPEN_RESTRICTED
	,
};

/* This function returns a pointer to a static copy of the version info
 * struct.
 */
struct ts_lib_version_data *ts_libversion(void)
{
	static short initialized;
	int major = 0;
	int minor = 0;
	int patch = 0;

	if (initialized)
		return &version_data;

#ifdef LIBTS_VERSION_CURRENT
	major = LIBTS_VERSION_CURRENT - LIBTS_VERSION_AGE;
	minor = LIBTS_VERSION_AGE;
	patch = LIBTS_VERSION_REVISION;

	version_data.version_num |= major << 16;
	version_data.version_num |= minor << 8;
	version_data.version_num |= patch << 0;
#endif

	initialized = 1;

	return &version_data;
}


<|start_filename|>3rdpart/ethercat-1.5.2/master/doxygen.c<|end_filename|>
/******************************************************************************
 *
 *  $Id: doxygen.c,v 6d9865c37b6f 2013/02/12 16:15:09 fp $
 *
 *  Copyright (C) 2006-2008  <NAME>, Ingenieurgemeinschaft IgH
 *
 *  This file is part of the IgH EtherCAT Master.
 *
 *  The IgH EtherCAT Master is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License version 2, as
 *  published by the Free Software Foundation.
 *
 *  The IgH EtherCAT Master is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 *  Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with the IgH EtherCAT Master; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 *****************************************************************************/

// This file only contains the doxygen mainpage.

/** \file
 * Doxygen mainpage only.
 */

/*****************************************************************************/

/**
   \mainpage

   \section sec_general General information

   This HTML contains the complete code documentation.

   The API documentations are in the <a href="modules.html">modules
   section</a>.

   For information how to build and install, see the INSTALL file in the source
   root.

   \section sec_contact Contact

   \verbatim
   <NAME> <<EMAIL>>
   Ingenieurgemeinschaft IgH
   Heinz-Baecker-Str. 34
   D-45356 Essen
   http://igh-essen.com
   \endverbatim

   \section sec_license License

   \verbatim
   Copyright (C) 2006-2013  <NAME>, Ingenieurgemeinschaft IgH

   This file is part of the IgH EtherCAT Master.

   The IgH EtherCAT Master is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public License version 2, as
   published by the Free Software Foundation.

   The IgH EtherCAT Master is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
   Public License for more details.

   You should have received a copy of the GNU General Public License along
   with the IgH EtherCAT Master; if not, write to the Free Software
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

   ---

   The license mentioned above concerns the source code only. Using the
   EtherCAT technology and brand is only permitted in compliance with the
   industrial property and similar rights of Beckhoff Automation GmbH.
   \endverbatim
*/

/*****************************************************************************/


<|start_filename|>3rdpart/ethercat-1.5.2/master/fsm_master.h<|end_filename|>
/******************************************************************************
 *
 *  $Id: fsm_master.h,v 06b53ebfa0c3 2012/12/06 13:06:10 fp $
 *
 *  Copyright (C) 2006-2012  <NAME>, Ingenieurgemeinschaft IgH
 *
 *  This file is part of the IgH EtherCAT Master.
 *
 *  The IgH EtherCAT Master is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License version 2, as
 *  published by the Free Software Foundation.
 *
 *  The IgH EtherCAT Master is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 *  Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with the IgH EtherCAT Master; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 *****************************************************************************/

/**
   \file
   EtherCAT master state machine.
*/

/*****************************************************************************/

#ifndef __EC_FSM_MASTER_H__
#define __EC_FSM_MASTER_H__

#include "globals.h"
#include "datagram.h"
#include "foe_request.h"
#include "sdo_request.h"
#include "soe_request.h"
#include "fsm_slave_config.h"
#include "fsm_slave_scan.h"
#include "fsm_pdo.h"

/*****************************************************************************/

/** SII write request.
 */
typedef struct {
    struct list_head list; /**< List head. */
    ec_slave_t *slave; /**< EtherCAT slave. */
    uint16_t offset; /**< SII word offset. */
    size_t nwords; /**< Number of words. */
    const uint16_t *words; /**< Pointer to the data words. */
    ec_internal_request_state_t state; /**< State of the request. */
} ec_sii_write_request_t;

/*****************************************************************************/

typedef struct ec_fsm_master ec_fsm_master_t; /**< \see ec_fsm_master */

/** Finite state machine of an EtherCAT master.
 */
struct ec_fsm_master {
    ec_master_t *master; /**< master the FSM runs on */
    ec_datagram_t *datagram; /**< datagram used in the state machine */
    unsigned int retries; /**< retries on datagram timeout. */

    void (*state)(ec_fsm_master_t *); /**< master state function */
    ec_device_index_t dev_idx; /**< Current device index (for scanning etc.).
                                */
    int idle; /**< state machine is in idle phase */
    unsigned long scan_jiffies; /**< beginning of slave scanning */
    uint8_t link_state[EC_MAX_NUM_DEVICES]; /**< Last link state for every
                                              device. */
    unsigned int slaves_responding[EC_MAX_NUM_DEVICES]; /**< Number of
                                                          responding slaves
                                                          for every device. */
    unsigned int rescan_required; /**< A bus rescan is required. */
    ec_slave_state_t slave_states[EC_MAX_NUM_DEVICES]; /**< AL states of
                                                         responding slaves for
                                                         every device. */
    ec_slave_t *slave; /**< current slave */
    ec_sii_write_request_t *sii_request; /**< SII write request */
    off_t sii_index; /**< index to SII write request data */
    ec_sdo_request_t *sdo_request; /**< SDO request to process. */

    ec_fsm_coe_t fsm_coe; /**< CoE state machine */
    ec_fsm_soe_t fsm_soe; /**< SoE state machine */
    ec_fsm_pdo_t fsm_pdo; /**< PDO configuration state machine. */
    ec_fsm_change_t fsm_change; /**< State change state machine */
    ec_fsm_slave_config_t fsm_slave_config; /**< slave state machine */
    ec_fsm_slave_scan_t fsm_slave_scan; /**< slave state machine */
    ec_fsm_sii_t fsm_sii; /**< SII state machine */
};

/*****************************************************************************/

void ec_fsm_master_init(ec_fsm_master_t *, ec_master_t *, ec_datagram_t *);
void ec_fsm_master_clear(ec_fsm_master_t *);

void ec_fsm_master_reset(ec_fsm_master_t *);

int ec_fsm_master_exec(ec_fsm_master_t *);
int ec_fsm_master_idle(const ec_fsm_master_t *);

/*****************************************************************************/

#endif


<|start_filename|>3rdpart/tslib-1.15/src/ts_load_module.c<|end_filename|>
/*
 *  tslib/src/ts_load_module.c
 *
 *  Copyright (C) 2001 <NAME>.
 *
 * This file is placed under the LGPL.  Please see the file
 * COPYING for more details.
 *
 * SPDX-License-Identifier: LGPL-2.1
 *
 *
 * Share and static plugin-modules loading functions
 */
#include "config.h"

#ifdef HAVE_ALLOCA_H
#include <alloca.h>
#endif

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#ifdef HAVE_LIBDL
#include <dlfcn.h>
#endif

#include "tslib-private.h"

#include "../plugins/plugins.h"

struct tslib_module_desc {
	const char *name;
	tslib_module_init mod_init;
};

static const struct tslib_module_desc tslib_modules[] = {
	/* sort alphabetically */
#ifdef TSLIB_STATIC_ARCTIC2_MODULE
	{ "arctic2", arctic2_mod_init },
#endif
#ifdef TSLIB_STATIC_COLLIE_MODULE
	{ "collie", collie_mod_init },
#endif
#ifdef TSLIB_STATIC_CORGI_MODULE
	{ "corgi", corgi_mod_init },
#endif
#ifdef TSLIB_STATIC_CY8MRLN_PALMPRE_MODULE
	{ "cy8mrln_palmpre", cy8mrln_palmpre_mod_init },
#endif
#ifdef TSLIB_STATIC_DEBOUNCE_MODULE
	{ "debounce", debounce_mod_init },
#endif
#ifdef TSLIB_STATIC_DEJITTER_MODULE
	{ "dejitter", dejitter_mod_init },
#endif
#ifdef TSLIB_STATIC_DMC_MODULE
	{ "dmc", dmc_mod_init },
#endif
#ifdef TSLIB_STATIC_DMC_DUS3000_MODULE
	{ "dmc_dus3000", dmc_dus3000_mod_init },
#endif
#ifdef TSLIB_STATIC_GALAX_MODULE
	{ "galax", galax_mod_init },
#endif
#ifdef TSLIB_STATIC_H3600_MODULE
	{ "h3600", h3600_mod_init },
#endif
#ifdef TSLIB_STATIC_IIR_MODULE
	{ "iir", iir_mod_init },
#endif
#ifdef TSLIB_STATIC_INPUT_MODULE
	{ "input", input_mod_init },
#endif
#ifdef TSLIB_STATIC_INVERT_MODULE
	{ "invert", invert_mod_init },
#endif
#ifdef TSLIB_STATIC_LINEAR_MODULE
	{ "linear", linear_mod_init },
#endif
#ifdef TSLIB_STATIC_LINEAR_H2200_MODULE
	{ "linear_h2200", linear_h2200_mod_init },
#endif
#ifdef TSLIB_STATIC_LOWPASS_MODULE
	{ "lowpass", lowpass_mod_init },
#endif
#ifdef TSLIB_STATIC_MEDIAN_MODULE
	{ "median", median_mod_init },
#endif
#ifdef TSLIB_STATIC_MK712_MODULE
	{ "mk712", mk712_mod_init },
#endif
#ifdef TSLIB_STATIC_PTHRES_MODULE
	{ "pthres", pthres_mod_init },
#endif
#ifdef TSLIB_STATIC_SKIP_MODULE
	{ "skip", skip_mod_init },
#endif
#ifdef TSLIB_STATIC_TATUNG_MODULE
	{ "tatung", tatung_mod_init },
#endif
#ifdef TSLIB_STATIC_TOUCHKIT_MODULE
	{ "touchkit", touchkit_mod_init },
#endif
#ifdef TSLIB_STATIC_UCB1X00_MODULE
	{ "ucb1x00", ucb1x00_mod_init },
#endif
#ifdef TSLIB_STATIC_VARIANCE_MODULE
	{ "variance", variance_mod_init },
#endif
#ifdef TSLIB_STATIC_WAVESHARE_MODULE
	{ "waveshare", waveshare_mod_init },
#endif
};

#define countof(arr) (sizeof(arr) / sizeof((arr)[0]))

static int cmp_name(const void *va, const void *vb)
{
	struct tslib_module_desc *a = (struct tslib_module_desc *)va;
	struct tslib_module_desc *b = (struct tslib_module_desc *)vb;

	return strcmp(a->name, b->name);
}

static struct tslib_module_info *__ts_load_module_static(struct tsdev *ts,
							 const char *module,
							 const char *params)
{
	struct tslib_module_info *info = NULL;
	struct tslib_module_desc *result;
	struct tslib_module_desc key;

	key.name = module;
	result = bsearch(&key, tslib_modules, countof(tslib_modules),
			 sizeof(struct tslib_module_desc), cmp_name);
	if (!result)
		return NULL;

	info = result->mod_init(ts, params);
#ifdef DEBUG
	fprintf(stderr, "static module %s init %s\n", module,
		info ? "succeeded" : "failed");
#endif

	if (info)
		info->handle = NULL;

	return info;
}

#define PLUGIN_DIR_LEN 1024

#ifdef HAVE_LIBDL
static struct tslib_module_info *__ts_load_module_shared(struct tsdev *ts,
							 const char *module,
							 const char *params)
{
	tslib_module_init *init;
	struct tslib_module_info *info;
	char fn[PLUGIN_DIR_LEN];
	void *handle;
	char *plugin_directory = getenv("TSLIB_PLUGINDIR");

	if (!plugin_directory)
		plugin_directory = PLUGIN_DIR;

	if (strlen(plugin_directory) >= PLUGIN_DIR_LEN) {
#ifdef DEBUG
		ts_error("%s dlopen() failed: path too long\n", fn);
#endif
		return NULL;
	}

	snprintf(fn, sizeof(fn), "%s/%s.so", plugin_directory, module);

	handle = dlopen(fn, RTLD_NOW);
	if (!handle) {
#ifdef DEBUG
		ts_error("%s dlopen() failed: %s\n", fn, dlerror());
#endif
		return NULL;
	}

	init = dlsym(handle, "mod_init");
	if (!init || !(*init)) {
#ifdef DEBUG
		ts_error("%s dlsym() failed: %s\n", fn, dlerror());
#endif
		dlclose(handle);
		return NULL;
	}

	info = (*init)(ts, params);
	if (!info) {
#ifdef DEBUG
		ts_error("Can't init %s\n", fn);
#endif
		dlclose(handle);
		return NULL;
	}

	info->handle = handle;

	return info;
}
#endif /* HAVE_LIBDL */

static int __ts_load_module(struct tsdev *ts, const char *module,
			    const char *params, int raw)
{
	struct tslib_module_info *info;
	void *handle;
	int ret;

#ifdef DEBUG
	if (params)
		printf("Loading module %s (%s)\n", module, params);
	else
		printf("Loading module %s\n", module);
#endif

	info = __ts_load_module_static(ts, module, params);
#ifdef HAVE_LIBDL
	if (!info)
		info = __ts_load_module_shared(ts, module, params);
#endif
	if (!info)
		return -1;

	if (raw)
		ret = __ts_attach_raw(ts, info);
	else
		ret = __ts_attach(ts, info);

	if (ret) {
#ifdef DEBUG
		ts_error("Can't attach %s\n", module);
#endif
		handle = info->handle;

		if (info->ops->fini)
			info->ops->fini(info);

#ifdef HAVE_LIBDL
		if (handle)
			dlclose(handle);
#endif
	}

	return ret;
}

int ts_load_module(struct tsdev *ts, const char *module, const char *params)
{
	return __ts_load_module(ts, module, params, 0);
}

int ts_load_module_raw(struct tsdev *ts, const char *module, const char *params)
{
	return __ts_load_module(ts, module, params, 1);
}


<|start_filename|>3rdpart/tslib-1.15/src/Makefile<|end_filename|>
# Makefile.in generated by automake 1.15 from Makefile.am.
# src/Makefile.  Generated from Makefile.in by configure.

# Copyright (C) 1994-2014 Free Software Foundation, Inc.

# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.



#
#  tslib/src/Makefile.am
#
#  Copyright (C) 2001 <NAME>.
#
# This file is placed under the LGPL.  Please see the file
# COPYING for more details.
#
#



am__is_gnu_make = { \
  if test -z '$(MAKELEVEL)'; then \
    false; \
  elif test -n '$(MAKE_HOST)'; then \
    true; \
  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
    true; \
  else \
    false; \
  fi; \
}
am__make_running_with_option = \
  case $${target_option-} in \
      ?) ;; \
      *) echo "am__make_running_with_option: internal error: invalid" \
              "target option '$${target_option-}' specified" >&2; \
         exit 1;; \
  esac; \
  has_opt=no; \
  sane_makeflags=$$MAKEFLAGS; \
  if $(am__is_gnu_make); then \
    sane_makeflags=$$MFLAGS; \
  else \
    case $$MAKEFLAGS in \
      *\\[\ \	]*) \
        bs=\\; \
        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
    esac; \
  fi; \
  skip_next=no; \
  strip_trailopt () \
  { \
    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
  }; \
  for flg in $$sane_makeflags; do \
    test $$skip_next = yes && { skip_next=no; continue; }; \
    case $$flg in \
      *=*|--*) continue;; \
        -*I) strip_trailopt 'I'; skip_next=yes;; \
      -*I?*) strip_trailopt 'I';; \
        -*O) strip_trailopt 'O'; skip_next=yes;; \
      -*O?*) strip_trailopt 'O';; \
        -*l) strip_trailopt 'l'; skip_next=yes;; \
      -*l?*) strip_trailopt 'l';; \
      -[dEDm]) skip_next=yes;; \
      -[JT]) skip_next=yes;; \
    esac; \
    case $$flg in \
      *$$target_option*) has_opt=yes; break;; \
    esac; \
  done; \
  test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/tslib
pkgincludedir = $(includedir)/tslib
pkglibdir = $(libdir)/tslib
pkglibexecdir = $(libexecdir)/tslib
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = x86_64-pc-linux-gnu
host_triplet = arm-unknown-linux-gnueabihf
am__append_1 = ts_strsep.c ts_strsep.h

##################
# filter modules #
##################
#am__append_2 = $(top_srcdir)/plugins/debounce.c
#am__append_3 = $(top_srcdir)/plugins/dejitter.c
#am__append_4 = $(top_srcdir)/plugins/iir.c
#am__append_5 = $(top_srcdir)/plugins/linear.c
#am__append_6 = $(top_srcdir)/plugins/linear-h2200.c
#am__append_7 = $(top_srcdir)/plugins/median.c
#am__append_8 = $(top_srcdir)/plugins/pthres.c
#am__append_9 = $(top_srcdir)/plugins/skip.c
#am__append_10 = $(top_srcdir)/plugins/variance.c
#am__append_11 = $(top_srcdir)/plugins/invert.c
#am__append_12 = $(top_srcdir)/plugins/lowpass.c

###############
# raw modules #
###############
#am__append_13 = $(top_srcdir)/plugins/input-raw.c
#am__append_14 = $(top_srcdir)/plugins/ucb1x00-raw.c
#am__append_15 = $(top_srcdir)/plugins/corgi-raw.c
#am__append_16 = $(top_srcdir)/plugins/collie-raw.c
#am__append_17 = $(top_srcdir)/plugins/h3600-raw.c
#am__append_18 = $(top_srcdir)/plugins/mk712-raw.c
#am__append_19 = $(top_srcdir)/plugins/arctic2-raw.c
#am__append_20 = $(top_srcdir)/plugins/tatung-raw.c
#am__append_21 = $(top_srcdir)/plugins/dmc-raw.c
#am__append_22 = $(top_srcdir)/plugins/touchkit-raw.c
#am__append_23 = $(top_srcdir)/plugins/waveshare-raw.c
#am__append_24 = $(top_srcdir)/plugins/dmc_dus3000-raw.c
#am__append_25 = $(top_srcdir)/plugins/galax-raw.c
#am__append_26 = $(top_srcdir)/plugins/cy8mrln.h \
#	$(top_srcdir)/plugins/cy8mrln-palmpre.c
#am__append_27 = -no-undefined
subdir = src
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/internal/libtool.m4 \
	$(top_srcdir)/m4/internal/ltoptions.m4 \
	$(top_srcdir)/m4/internal/ltsugar.m4 \
	$(top_srcdir)/m4/internal/ltversion.m4 \
	$(top_srcdir)/m4/internal/lt~obsolete.m4 \
	$(top_srcdir)/m4/internal/tslib_modules.m4 \
	$(top_srcdir)/m4/internal/visibility.m4 \
	$(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
	$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(include_HEADERS) \
	$(noinst_HEADERS) $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
    *) f=$$p;; \
  esac;
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
am__install_max = 40
am__nobase_strip_setup = \
  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
am__nobase_strip = \
  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
am__nobase_list = $(am__nobase_strip_setup); \
  for p in $$list; do echo "$$p $$p"; done | \
  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
    if (++n[$$2] == $(am__install_max)) \
      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
    END { for (dir in files) print dir, files[dir] }'
am__base_list = \
  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__uninstall_files_from_dir = { \
  test -z "$$files" \
    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
         $(am__cd) "$$dir" && rm -f $$files; }; \
  }
am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)"
LTLIBRARIES = $(lib_LTLIBRARIES)
libts_la_LIBADD =
am__libts_la_SOURCES_DIST = ts_attach.c ts_close.c ts_config.c \
	ts_error.c ts_fd.c ts_load_module.c ts_open.c ts_parse_vars.c \
	ts_read.c ts_read_raw.c ts_option.c ts_setup.c \
	$(srcdir)/../plugins/plugins.h ts_version.c ts_get_eventpath.c \
	ts_strsep.c ts_strsep.h $(top_srcdir)/plugins/debounce.c \
	$(top_srcdir)/plugins/dejitter.c $(top_srcdir)/plugins/iir.c \
	$(top_srcdir)/plugins/linear.c \
	$(top_srcdir)/plugins/linear-h2200.c \
	$(top_srcdir)/plugins/median.c $(top_srcdir)/plugins/pthres.c \
	$(top_srcdir)/plugins/skip.c $(top_srcdir)/plugins/variance.c \
	$(top_srcdir)/plugins/invert.c $(top_srcdir)/plugins/lowpass.c \
	$(top_srcdir)/plugins/input-raw.c \
	$(top_srcdir)/plugins/ucb1x00-raw.c \
	$(top_srcdir)/plugins/corgi-raw.c \
	$(top_srcdir)/plugins/collie-raw.c \
	$(top_srcdir)/plugins/h3600-raw.c \
	$(top_srcdir)/plugins/mk712-raw.c \
	$(top_srcdir)/plugins/arctic2-raw.c \
	$(top_srcdir)/plugins/tatung-raw.c \
	$(top_srcdir)/plugins/dmc-raw.c \
	$(top_srcdir)/plugins/touchkit-raw.c \
	$(top_srcdir)/plugins/waveshare-raw.c \
	$(top_srcdir)/plugins/dmc_dus3000-raw.c \
	$(top_srcdir)/plugins/galax-raw.c \
	$(top_srcdir)/plugins/cy8mrln.h \
	$(top_srcdir)/plugins/cy8mrln-palmpre.c
am__objects_1 = ts_strsep.lo
am__dirstamp = $(am__leading_dot)dirstamp
#am__objects_2 = $(top_srcdir)/plugins/debounce.lo
#am__objects_3 = $(top_srcdir)/plugins/dejitter.lo
#am__objects_4 =  \
#	$(top_srcdir)/plugins/iir.lo
#am__objects_5 = $(top_srcdir)/plugins/linear.lo
#am__objects_6 = $(top_srcdir)/plugins/linear-h2200.lo
#am__objects_7 = $(top_srcdir)/plugins/median.lo
#am__objects_8 = $(top_srcdir)/plugins/pthres.lo
#am__objects_9 =  \
#	$(top_srcdir)/plugins/skip.lo
#am__objects_10 = $(top_srcdir)/plugins/variance.lo
#am__objects_11 = $(top_srcdir)/plugins/invert.lo
#am__objects_12 = $(top_srcdir)/plugins/lowpass.lo
#am__objects_13 = $(top_srcdir)/plugins/input-raw.lo
#am__objects_14 = $(top_srcdir)/plugins/ucb1x00-raw.lo
#am__objects_15 = $(top_srcdir)/plugins/corgi-raw.lo
#am__objects_16 = $(top_srcdir)/plugins/collie-raw.lo
#am__objects_17 = $(top_srcdir)/plugins/h3600-raw.lo
#am__objects_18 = $(top_srcdir)/plugins/mk712-raw.lo
#am__objects_19 = $(top_srcdir)/plugins/arctic2-raw.lo
#am__objects_20 = $(top_srcdir)/plugins/tatung-raw.lo
#am__objects_21 = $(top_srcdir)/plugins/dmc-raw.lo
#am__objects_22 = $(top_srcdir)/plugins/touchkit-raw.lo
#am__objects_23 = $(top_srcdir)/plugins/waveshare-raw.lo
#am__objects_24 = $(top_srcdir)/plugins/dmc_dus3000-raw.lo
#am__objects_25 = $(top_srcdir)/plugins/galax-raw.lo
#am__objects_26 = $(top_srcdir)/plugins/cy8mrln-palmpre.lo
am_libts_la_OBJECTS = ts_attach.lo ts_close.lo ts_config.lo \
	ts_error.lo ts_fd.lo ts_load_module.lo ts_open.lo \
	ts_parse_vars.lo ts_read.lo ts_read_raw.lo ts_option.lo \
	ts_setup.lo ts_version.lo ts_get_eventpath.lo $(am__objects_1) \
	$(am__objects_2) $(am__objects_3) $(am__objects_4) \
	$(am__objects_5) $(am__objects_6) $(am__objects_7) \
	$(am__objects_8) $(am__objects_9) $(am__objects_10) \
	$(am__objects_11) $(am__objects_12) $(am__objects_13) \
	$(am__objects_14) $(am__objects_15) $(am__objects_16) \
	$(am__objects_17) $(am__objects_18) $(am__objects_19) \
	$(am__objects_20) $(am__objects_21) $(am__objects_22) \
	$(am__objects_23) $(am__objects_24) $(am__objects_25) \
	$(am__objects_26)
libts_la_OBJECTS = $(am_libts_la_OBJECTS)
AM_V_lt = $(am__v_lt_$(V))
am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
am__v_lt_0 = --silent
am__v_lt_1 = 
libts_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
	$(libts_la_LDFLAGS) $(LDFLAGS) -o $@
AM_V_P = $(am__v_P_$(V))
am__v_P_ = $(am__v_P_$(AM_DEFAULT_VERBOSITY))
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_$(V))
am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
am__v_GEN_0 = @echo "  GEN     " $@;
am__v_GEN_1 = 
AM_V_at = $(am__v_at_$(V))
am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
am__v_at_0 = @
am__v_at_1 = 
DEFAULT_INCLUDES = -I. -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
	$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
	$(AM_CFLAGS) $(CFLAGS)
AM_V_CC = $(am__v_CC_$(V))
am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY))
am__v_CC_0 = @echo "  CC      " $@;
am__v_CC_1 = 
CCLD = $(CC)
LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
	$(AM_LDFLAGS) $(LDFLAGS) -o $@
AM_V_CCLD = $(am__v_CCLD_$(V))
am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY))
am__v_CCLD_0 = @echo "  CCLD    " $@;
am__v_CCLD_1 = 
SOURCES = $(libts_la_SOURCES)
DIST_SOURCES = $(am__libts_la_SOURCES_DIST)
am__can_run_installinfo = \
  case $$AM_UPDATE_INFO_DIR in \
    n|no|NO) false;; \
    *) (install-info --version) >/dev/null 2>&1;; \
  esac
HEADERS = $(include_HEADERS) $(noinst_HEADERS)
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
# Read a list of newline-separated strings from the standard input,
# and print each of them once, without duplicates.  Input order is
# *not* preserved.
am__uniquify_input = $(AWK) '\
  BEGIN { nonempty = 0; } \
  { items[$$0] = 1; nonempty = 1; } \
  END { if (nonempty) { for (i in items) print i; }; } \
'
# Make sure the list of sources is unique.  This is necessary because,
# e.g., the same source file might be shared among _SOURCES variables
# for different programs/libraries.
am__define_uniq_tagged_files = \
  list='$(am__tagged_files)'; \
  unique=`for i in $$list; do \
    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
  done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = ${SHELL} /home/morris/SUDA_V3S/3rdpart/tslib-1.15/missing aclocal-1.15
ALLOCA = 
AMTAR = $${TAR-tar}
AM_DEFAULT_VERBOSITY = 0
AR = arm-linux-gnueabihf-ar
AUTOCONF = ${SHELL} /home/morris/SUDA_V3S/3rdpart/tslib-1.15/missing autoconf
AUTOHEADER = ${SHELL} /home/morris/SUDA_V3S/3rdpart/tslib-1.15/missing autoheader
AUTOMAKE = ${SHELL} /home/morris/SUDA_V3S/3rdpart/tslib-1.15/missing automake-1.15
AWK = gawk
CC = /home/morris/SUDA_V3S/toolchains/gcc-linaro-6.4.1-2017.11-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc
CCDEPMODE = depmode=none
CFLAGS = -DGCC_HASCLASSVISIBILITY -O2 -Wall -W -fPIC
CPP = /home/morris/SUDA_V3S/toolchains/gcc-linaro-6.4.1-2017.11-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc -E
CPPFLAGS = 
CYGPATH_W = echo
DEBUGFLAGS = 
DEFS = -DHAVE_CONFIG_H
DEPDIR = .deps
DLLTOOL = false
DSYMUTIL = 
DUMPBIN = 
ECHO_C = 
ECHO_N = -n
ECHO_T = 
EGREP = /bin/grep -E
EXEEXT = 
FGREP = /bin/grep -F
GREP = /bin/grep
INSTALL = /usr/bin/install -c
INSTALL_DATA = ${INSTALL} -m 644
INSTALL_PROGRAM = ${INSTALL}
INSTALL_SCRIPT = ${INSTALL}
INSTALL_STRIP_PROGRAM = $(install_sh) -c -s
LD = /home/morris/SUDA_V3S/toolchains/gcc-linaro-6.4.1-2017.11-x86_64_arm-linux-gnueabihf/arm-linux-gnueabihf/bin/ld
LDFLAGS = 
LIBFLAGS = -DTSLIB_INTERNAL
LIBOBJS =  ${LIBOBJDIR}lstat$U.o ${LIBOBJDIR}stat$U.o
LIBS = -ldl 
LIBTOOL = $(SHELL) $(top_builddir)/libtool
LIBTS_VERSION_AGE = $LT_AGE
LIBTS_VERSION_CURRENT = $LT_CURRENT
LIBTS_VERSION_REVISION = $LT_REVISION
LIPO = 
LN_S = ln -s
LTLIBOBJS =  ${LIBOBJDIR}lstat$U.lo ${LIBOBJDIR}stat$U.lo
LT_AGE = 9
LT_CURRENT = 9
LT_REVISION = 0
LT_SYS_LIBRARY_PATH = 
MAKEINFO = ${SHELL} /home/morris/SUDA_V3S/3rdpart/tslib-1.15/missing makeinfo
MANIFEST_TOOL = :
MKDIR_P = /bin/mkdir -p
NM = /home/morris/SUDA_V3S/toolchains/gcc-linaro-6.4.1-2017.11-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-nm -B
NMEDIT = 
OBJDUMP = arm-linux-gnueabihf-objdump
OBJEXT = o
OTOOL = 
OTOOL64 = 
PACKAGE = tslib
PACKAGE_BUGREPORT = <EMAIL>
PACKAGE_DESCRIPTION = Touchscreen Access Library
PACKAGE_NAME = tslib
PACKAGE_STRING = tslib 1.15
PACKAGE_TARNAME = tslib
PACKAGE_URL = http://tslib.org
PACKAGE_VERSION = 1.15
PATH_SEPARATOR = :
PLUGIN_DIR = ${libdir}/ts
RANLIB = arm-linux-gnueabihf-ranlib
SED = /bin/sed
SET_MAKE = 
SHELL = /bin/bash
STRIP = arm-linux-gnueabihf-strip
TS_CONF = ${sysconfdir}/ts.conf
TS_POINTERCAL = ${sysconfdir}/pointercal
VERSION = 1.15
VIS_CFLAGS = -fvisibility=hidden
abs_builddir = /home/morris/SUDA_V3S/3rdpart/tslib-1.15/src
abs_srcdir = /home/morris/SUDA_V3S/3rdpart/tslib-1.15/src
abs_top_builddir = /home/morris/SUDA_V3S/3rdpart/tslib-1.15
abs_top_srcdir = /home/morris/SUDA_V3S/3rdpart/tslib-1.15
ac_ct_AR = 
ac_ct_CC = 
ac_ct_DUMPBIN = 
am__include = include
am__leading_dot = .
am__quote = 
am__tar = $${TAR-tar} chof - "$$tardir"
am__untar = $${TAR-tar} xf -
bindir = ${exec_prefix}/bin
build = x86_64-pc-linux-gnu
build_alias = 
build_cpu = x86_64
build_os = linux-gnu
build_vendor = pc
builddir = .
datadir = ${datarootdir}
datarootdir = ${prefix}/share
docdir = ${datarootdir}/doc/${PACKAGE_TARNAME}
dvidir = ${docdir}
exec_prefix = ${prefix}
host = arm-unknown-linux-gnueabihf
host_alias = arm-linux-gnueabihf
host_cpu = arm
host_os = linux-gnueabihf
host_vendor = unknown
htmldir = ${docdir}
includedir = ${prefix}/include
infodir = ${datarootdir}/info
install_sh = ${SHELL} /home/morris/SUDA_V3S/3rdpart/tslib-1.15/install-sh
libdir = ${exec_prefix}/lib
libexecdir = ${exec_prefix}/libexec
localedir = ${datarootdir}/locale
localstatedir = ${prefix}/var
mandir = ${datarootdir}/man
mkdir_p = $(MKDIR_P)
oldincludedir = /usr/include
pdfdir = ${docdir}
prefix = /home/morris/SUDA_V3S/3rdpart/tslib-1.15/out
program_transform_name = s,x,x,
psdir = ${docdir}
runstatedir = ${localstatedir}/run
sbindir = ${exec_prefix}/sbin
sharedstatedir = ${prefix}/com
srcdir = .
sysconfdir = ${prefix}/etc
target_alias = 
top_build_prefix = ../
top_builddir = ..
top_srcdir = ..
AM_CFLAGS = -DPLUGIN_DIR=\"${libdir}/ts\" -DTS_CONF=\"${sysconfdir}/ts.conf\" -DTS_POINTERCAL=\"${sysconfdir}/pointercal\" \
		   $(DEBUGFLAGS) $(LIBFLAGS) $(VIS_CFLAGS)

noinst_HEADERS = tslib-private.h tslib-filter.h
include_HEADERS = tslib.h
lib_LTLIBRARIES = libts.la
libts_la_SOURCES = ts_attach.c ts_close.c ts_config.c ts_error.c \
	ts_fd.c ts_load_module.c ts_open.c ts_parse_vars.c ts_read.c \
	ts_read_raw.c ts_option.c ts_setup.c \
	$(srcdir)/../plugins/plugins.h ts_version.c ts_get_eventpath.c \
	$(am__append_1) $(am__append_2) $(am__append_3) \
	$(am__append_4) $(am__append_5) $(am__append_6) \
	$(am__append_7) $(am__append_8) $(am__append_9) \
	$(am__append_10) $(am__append_11) $(am__append_12) \
	$(am__append_13) $(am__append_14) $(am__append_15) \
	$(am__append_16) $(am__append_17) $(am__append_18) \
	$(am__append_19) $(am__append_20) $(am__append_21) \
	$(am__append_22) $(am__append_23) $(am__append_24) \
	$(am__append_25) $(am__append_26)
libts_la_LDFLAGS = -version-info \
	$(LT_CURRENT):$(LT_REVISION):$(LT_AGE) -export-dynamic \
	$(am__append_27)
all: all-am

.SUFFIXES:
.SUFFIXES: .c .lo .o .obj
$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
	@for dep in $?; do \
	  case '$(am__configure_deps)' in \
	    *$$dep*) \
	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
	        && { if test -f $@; then exit 0; else break; fi; }; \
	      exit 1;; \
	  esac; \
	done; \
	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \
	$(am__cd) $(top_srcdir) && \
	  $(AUTOMAKE) --gnu src/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
	@case '$?' in \
	  *config.status*) \
	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
	  *) \
	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
	esac;

$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh

$(top_srcdir)/configure:  $(am__configure_deps)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):

install-libLTLIBRARIES: $(lib_LTLIBRARIES)
	@$(NORMAL_INSTALL)
	@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
	list2=; for p in $$list; do \
	  if test -f $$p; then \
	    list2="$$list2 $$p"; \
	  else :; fi; \
	done; \
	test -z "$$list2" || { \
	  echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \
	  $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \
	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
	}

uninstall-libLTLIBRARIES:
	@$(NORMAL_UNINSTALL)
	@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
	for p in $$list; do \
	  $(am__strip_dir) \
	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
	done

clean-libLTLIBRARIES:
	-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
	@list='$(lib_LTLIBRARIES)'; \
	locs=`for p in $$list; do echo $$p; done | \
	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
	      sort -u`; \
	test -z "$$locs" || { \
	  echo rm -f $${locs}; \
	  rm -f $${locs}; \
	}
$(top_srcdir)/plugins/$(am__dirstamp):
	@$(MKDIR_P) $(top_srcdir)/plugins
	@: > $(top_srcdir)/plugins/$(am__dirstamp)
$(top_srcdir)/plugins/$(DEPDIR)/$(am__dirstamp):
	@$(MKDIR_P) $(top_srcdir)/plugins/$(DEPDIR)
	@: > $(top_srcdir)/plugins/$(DEPDIR)/$(am__dirstamp)
$(top_srcdir)/plugins/debounce.lo:  \
	$(top_srcdir)/plugins/$(am__dirstamp) \
	$(top_srcdir)/plugins/$(DEPDIR)/$(am__dirstamp)
$(top_srcdir)/plugins/dejitter.lo:  \
	$(top_srcdir)/plugins/$(am__dirstamp) \
	$(top_srcdir)/plugins/$(DEPDIR)/$(am__dirstamp)
$(top_srcdir)/plugins/iir.lo: $(top_srcdir)/plugins/$(am__dirstamp) \
	$(top_srcdir)/plugins/$(DEPDIR)/$(am__dirstamp)
$(top_srcdir)/plugins/linear.lo:  \
	$(top_srcdir)/plugins/$(am__dirstamp) \
	$(top_srcdir)/plugins/$(DEPDIR)/$(am__dirstamp)
$(top_srcdir)/plugins/linear-h2200.lo:  \
	$(top_srcdir)/plugins/$(am__dirstamp) \
	$(top_srcdir)/plugins/$(DEPDIR)/$(am__dirstamp)
$(top_srcdir)/plugins/median.lo:  \
	$(top_srcdir)/plugins/$(am__dirstamp) \
	$(top_srcdir)/plugins/$(DEPDIR)/$(am__dirstamp)
$(top_srcdir)/plugins/pthres.lo:  \
	$(top_srcdir)/plugins/$(am__dirstamp) \
	$(top_srcdir)/plugins/$(DEPDIR)/$(am__dirstamp)
$(top_srcdir)/plugins/skip.lo: $(top_srcdir)/plugins/$(am__dirstamp) \
	$(top_srcdir)/plugins/$(DEPDIR)/$(am__dirstamp)
$(top_srcdir)/plugins/variance.lo:  \
	$(top_srcdir)/plugins/$(am__dirstamp) \
	$(top_srcdir)/plugins/$(DEPDIR)/$(am__dirstamp)
$(top_srcdir)/plugins/invert.lo:  \
	$(top_srcdir)/plugins/$(am__dirstamp) \
	$(top_srcdir)/plugins/$(DEPDIR)/$(am__dirstamp)
$(top_srcdir)/plugins/lowpass.lo:  \
	$(top_srcdir)/plugins/$(am__dirstamp) \
	$(top_srcdir)/plugins/$(DEPDIR)/$(am__dirstamp)
$(top_srcdir)/plugins/input-raw.lo:  \
	$(top_srcdir)/plugins/$(am__dirstamp) \
	$(top_srcdir)/plugins/$(DEPDIR)/$(am__dirstamp)
$(top_srcdir)/plugins/ucb1x00-raw.lo:  \
	$(top_srcdir)/plugins/$(am__dirstamp) \
	$(top_srcdir)/plugins/$(DEPDIR)/$(am__dirstamp)
$(top_srcdir)/plugins/corgi-raw.lo:  \
	$(top_srcdir)/plugins/$(am__dirstamp) \
	$(top_srcdir)/plugins/$(DEPDIR)/$(am__dirstamp)
$(top_srcdir)/plugins/collie-raw.lo:  \
	$(top_srcdir)/plugins/$(am__dirstamp) \
	$(top_srcdir)/plugins/$(DEPDIR)/$(am__dirstamp)
$(top_srcdir)/plugins/h3600-raw.lo:  \
	$(top_srcdir)/plugins/$(am__dirstamp) \
	$(top_srcdir)/plugins/$(DEPDIR)/$(am__dirstamp)
$(top_srcdir)/plugins/mk712-raw.lo:  \
	$(top_srcdir)/plugins/$(am__dirstamp) \
	$(top_srcdir)/plugins/$(DEPDIR)/$(am__dirstamp)
$(top_srcdir)/plugins/arctic2-raw.lo:  \
	$(top_srcdir)/plugins/$(am__dirstamp) \
	$(top_srcdir)/plugins/$(DEPDIR)/$(am__dirstamp)
$(top_srcdir)/plugins/tatung-raw.lo:  \
	$(top_srcdir)/plugins/$(am__dirstamp) \
	$(top_srcdir)/plugins/$(DEPDIR)/$(am__dirstamp)
$(top_srcdir)/plugins/dmc-raw.lo:  \
	$(top_srcdir)/plugins/$(am__dirstamp) \
	$(top_srcdir)/plugins/$(DEPDIR)/$(am__dirstamp)
$(top_srcdir)/plugins/touchkit-raw.lo:  \
	$(top_srcdir)/plugins/$(am__dirstamp) \
	$(top_srcdir)/plugins/$(DEPDIR)/$(am__dirstamp)
$(top_srcdir)/plugins/waveshare-raw.lo:  \
	$(top_srcdir)/plugins/$(am__dirstamp) \
	$(top_srcdir)/plugins/$(DEPDIR)/$(am__dirstamp)
$(top_srcdir)/plugins/dmc_dus3000-raw.lo:  \
	$(top_srcdir)/plugins/$(am__dirstamp) \
	$(top_srcdir)/plugins/$(DEPDIR)/$(am__dirstamp)
$(top_srcdir)/plugins/galax-raw.lo:  \
	$(top_srcdir)/plugins/$(am__dirstamp) \
	$(top_srcdir)/plugins/$(DEPDIR)/$(am__dirstamp)
$(top_srcdir)/plugins/cy8mrln-palmpre.lo:  \
	$(top_srcdir)/plugins/$(am__dirstamp) \
	$(top_srcdir)/plugins/$(DEPDIR)/$(am__dirstamp)

libts.la: $(libts_la_OBJECTS) $(libts_la_DEPENDENCIES) $(EXTRA_libts_la_DEPENDENCIES) 
	$(AM_V_CCLD)$(libts_la_LINK) -rpath $(libdir) $(libts_la_OBJECTS) $(libts_la_LIBADD) $(LIBS)

mostlyclean-compile:
	-rm -f *.$(OBJEXT)
	-rm -f $(top_srcdir)/plugins/*.$(OBJEXT)
	-rm -f $(top_srcdir)/plugins/*.lo

distclean-compile:
	-rm -f *.tab.c

#include $(top_srcdir)/plugins/$(DEPDIR)/arctic2-raw.Plo
#include $(top_srcdir)/plugins/$(DEPDIR)/collie-raw.Plo
#include $(top_srcdir)/plugins/$(DEPDIR)/corgi-raw.Plo
#include $(top_srcdir)/plugins/$(DEPDIR)/cy8mrln-palmpre.Plo
#include $(top_srcdir)/plugins/$(DEPDIR)/debounce.Plo
#include $(top_srcdir)/plugins/$(DEPDIR)/dejitter.Plo
#include $(top_srcdir)/plugins/$(DEPDIR)/dmc-raw.Plo
#include $(top_srcdir)/plugins/$(DEPDIR)/dmc_dus3000-raw.Plo
#include $(top_srcdir)/plugins/$(DEPDIR)/galax-raw.Plo
#include $(top_srcdir)/plugins/$(DEPDIR)/h3600-raw.Plo
#include $(top_srcdir)/plugins/$(DEPDIR)/iir.Plo
#include $(top_srcdir)/plugins/$(DEPDIR)/input-raw.Plo
#include $(top_srcdir)/plugins/$(DEPDIR)/invert.Plo
#include $(top_srcdir)/plugins/$(DEPDIR)/linear-h2200.Plo
#include $(top_srcdir)/plugins/$(DEPDIR)/linear.Plo
#include $(top_srcdir)/plugins/$(DEPDIR)/lowpass.Plo
#include $(top_srcdir)/plugins/$(DEPDIR)/median.Plo
#include $(top_srcdir)/plugins/$(DEPDIR)/mk712-raw.Plo
#include $(top_srcdir)/plugins/$(DEPDIR)/pthres.Plo
#include $(top_srcdir)/plugins/$(DEPDIR)/skip.Plo
#include $(top_srcdir)/plugins/$(DEPDIR)/tatung-raw.Plo
#include $(top_srcdir)/plugins/$(DEPDIR)/touchkit-raw.Plo
#include $(top_srcdir)/plugins/$(DEPDIR)/ucb1x00-raw.Plo
#include $(top_srcdir)/plugins/$(DEPDIR)/variance.Plo
#include $(top_srcdir)/plugins/$(DEPDIR)/waveshare-raw.Plo
#include ./$(DEPDIR)/ts_attach.Plo
#include ./$(DEPDIR)/ts_close.Plo
#include ./$(DEPDIR)/ts_config.Plo
#include ./$(DEPDIR)/ts_error.Plo
#include ./$(DEPDIR)/ts_fd.Plo
#include ./$(DEPDIR)/ts_get_eventpath.Plo
#include ./$(DEPDIR)/ts_load_module.Plo
#include ./$(DEPDIR)/ts_open.Plo
#include ./$(DEPDIR)/ts_option.Plo
#include ./$(DEPDIR)/ts_parse_vars.Plo
#include ./$(DEPDIR)/ts_read.Plo
#include ./$(DEPDIR)/ts_read_raw.Plo
#include ./$(DEPDIR)/ts_setup.Plo
#include ./$(DEPDIR)/ts_strsep.Plo
#include ./$(DEPDIR)/ts_version.Plo

.c.o:
#	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
#	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
#	$(am__mv) $$depbase.Tpo $$depbase.Po
#	$(AM_V_CC)source='$<' object='$@' libtool=no 
#	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) 
	$(AM_V_CC)$(COMPILE) -c -o $@ $<

.c.obj:
#	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
#	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
#	$(am__mv) $$depbase.Tpo $$depbase.Po
#	$(AM_V_CC)source='$<' object='$@' libtool=no 
#	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) 
	$(AM_V_CC)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`

.c.lo:
#	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
#	$(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
#	$(am__mv) $$depbase.Tpo $$depbase.Plo
#	$(AM_V_CC)source='$<' object='$@' libtool=yes 
#	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) 
	$(AM_V_CC)$(LTCOMPILE) -c -o $@ $<

mostlyclean-libtool:
	-rm -f *.lo

clean-libtool:
	-rm -rf $(top_srcdir)/plugins/.libs $(top_srcdir)/plugins/_libs
	-rm -rf .libs _libs
install-includeHEADERS: $(include_HEADERS)
	@$(NORMAL_INSTALL)
	@list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \
	if test -n "$$list"; then \
	  echo " $(MKDIR_P) '$(DESTDIR)$(includedir)'"; \
	  $(MKDIR_P) "$(DESTDIR)$(includedir)" || exit 1; \
	fi; \
	for p in $$list; do \
	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
	  echo "$$d$$p"; \
	done | $(am__base_list) | \
	while read files; do \
	  echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includedir)'"; \
	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(includedir)" || exit $$?; \
	done

uninstall-includeHEADERS:
	@$(NORMAL_UNINSTALL)
	@list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \
	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
	dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir)

ID: $(am__tagged_files)
	$(am__define_uniq_tagged_files); mkid -fID $$unique
tags: tags-am
TAGS: tags

tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
	set x; \
	here=`pwd`; \
	$(am__define_uniq_tagged_files); \
	shift; \
	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
	  test -n "$$unique" || unique=$$empty_fix; \
	  if test $$# -gt 0; then \
	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
	      "$$@" $$unique; \
	  else \
	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
	      $$unique; \
	  fi; \
	fi
ctags: ctags-am

CTAGS: ctags
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
	$(am__define_uniq_tagged_files); \
	test -z "$(CTAGS_ARGS)$$unique" \
	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
	     $$unique

GTAGS:
	here=`$(am__cd) $(top_builddir) && pwd` \
	  && $(am__cd) $(top_srcdir) \
	  && gtags -i $(GTAGS_ARGS) "$$here"
cscopelist: cscopelist-am

cscopelist-am: $(am__tagged_files)
	list='$(am__tagged_files)'; \
	case "$(srcdir)" in \
	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
	  *) sdir=$(subdir)/$(srcdir) ;; \
	esac; \
	for i in $$list; do \
	  if test -f "$$i"; then \
	    echo "$(subdir)/$$i"; \
	  else \
	    echo "$$sdir/$$i"; \
	  fi; \
	done >> $(top_builddir)/cscope.files

distclean-tags:
	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags

distdir: $(DISTFILES)
	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
	list='$(DISTFILES)'; \
	  dist_files=`for file in $$list; do echo $$file; done | \
	  sed -e "s|^$$srcdirstrip/||;t" \
	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
	case $$dist_files in \
	  */*) $(MKDIR_P) `echo "$$dist_files" | \
			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
			   sort -u` ;; \
	esac; \
	for file in $$dist_files; do \
	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
	  if test -d $$d/$$file; then \
	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
	    if test -d "$(distdir)/$$file"; then \
	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
	    fi; \
	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
	    fi; \
	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
	  else \
	    test -f "$(distdir)/$$file" \
	    || cp -p $$d/$$file "$(distdir)/$$file" \
	    || exit 1; \
	  fi; \
	done
check-am: all-am
check: check-am
all-am: Makefile $(LTLIBRARIES) $(HEADERS)
installdirs:
	for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)"; do \
	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
	done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am

install-am: all-am
	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am

installcheck: installcheck-am
install-strip:
	if test -z '$(STRIP)'; then \
	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
	      install; \
	else \
	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
	fi
mostlyclean-generic:

clean-generic:

distclean-generic:
	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
	-test -z "$(top_srcdir)/plugins/$(DEPDIR)/$(am__dirstamp)" || rm -f $(top_srcdir)/plugins/$(DEPDIR)/$(am__dirstamp)
	-test -z "$(top_srcdir)/plugins/$(am__dirstamp)" || rm -f $(top_srcdir)/plugins/$(am__dirstamp)

maintainer-clean-generic:
	@echo "This command is intended for maintainers to use"
	@echo "it deletes files that may require special tools to rebuild."
clean: clean-am

clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
	mostlyclean-am

distclean: distclean-am
	-rm -rf $(top_srcdir)/plugins/$(DEPDIR) ./$(DEPDIR)
	-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
	distclean-tags

dvi: dvi-am

dvi-am:

html: html-am

html-am:

info: info-am

info-am:

install-data-am: install-includeHEADERS

install-dvi: install-dvi-am

install-dvi-am:

install-exec-am: install-libLTLIBRARIES

install-html: install-html-am

install-html-am:

install-info: install-info-am

install-info-am:

install-man:

install-pdf: install-pdf-am

install-pdf-am:

install-ps: install-ps-am

install-ps-am:

installcheck-am:

maintainer-clean: maintainer-clean-am
	-rm -rf $(top_srcdir)/plugins/$(DEPDIR) ./$(DEPDIR)
	-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic

mostlyclean: mostlyclean-am

mostlyclean-am: mostlyclean-compile mostlyclean-generic \
	mostlyclean-libtool

pdf: pdf-am

pdf-am:

ps: ps-am

ps-am:

uninstall-am: uninstall-includeHEADERS uninstall-libLTLIBRARIES

.MAKE: install-am install-strip

.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
	clean-libLTLIBRARIES clean-libtool cscopelist-am ctags \
	ctags-am distclean distclean-compile distclean-generic \
	distclean-libtool distclean-tags distdir dvi dvi-am html \
	html-am info info-am install install-am install-data \
	install-data-am install-dvi install-dvi-am install-exec \
	install-exec-am install-html install-html-am \
	install-includeHEADERS install-info install-info-am \
	install-libLTLIBRARIES install-man install-pdf install-pdf-am \
	install-ps install-ps-am install-strip installcheck \
	installcheck-am installdirs maintainer-clean \
	maintainer-clean-generic mostlyclean mostlyclean-compile \
	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
	tags tags-am uninstall uninstall-am uninstall-includeHEADERS \
	uninstall-libLTLIBRARIES

.PRECIOUS: Makefile


# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:


<|start_filename|>3rdpart/ethercat-1.5.2/master/sdo.h<|end_filename|>
/******************************************************************************
 *
 *  $Id: sdo.h,v 11c0b2caa253 2009/02/24 12:51:39 fp $
 *
 *  Copyright (C) 2006-2008  <NAME>, Ingenieurgemeinschaft IgH
 *
 *  This file is part of the IgH EtherCAT Master.
 *
 *  The IgH EtherCAT Master is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License version 2, as
 *  published by the Free Software Foundation.
 *
 *  The IgH EtherCAT Master is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 *  Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with the IgH EtherCAT Master; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 *****************************************************************************/

/**
   \file
   EtherCAT CANopen SDO structure.
*/

/*****************************************************************************/

#ifndef __EC_SDO_H__
#define __EC_SDO_H__

#include <linux/list.h>

#include "globals.h"
#include "sdo_entry.h"

/*****************************************************************************/

/** CANopen SDO.
 */
struct ec_sdo {
    struct list_head list; /**< List item. */
    ec_slave_t *slave; /**< Parent slave. */
    uint16_t index; /**< SDO index. */
    uint8_t object_code; /**< Object code. */
    char *name; /**< SDO name. */
    uint8_t max_subindex; /**< Maximum subindex. */
    struct list_head entries; /**< List of entries. */
};

/*****************************************************************************/

void ec_sdo_init(ec_sdo_t *, ec_slave_t *, uint16_t);
void ec_sdo_clear(ec_sdo_t *);

ec_sdo_entry_t *ec_sdo_get_entry(ec_sdo_t *, uint8_t);
const ec_sdo_entry_t *ec_sdo_get_entry_const(const ec_sdo_t *, uint8_t);

/*****************************************************************************/

#endif


<|start_filename|>3rdpart/tslib-1.15/plugins/linear.c<|end_filename|>
/*
 *  tslib/plugins/linear.c
 *
 *  Copyright (C) 2016 <NAME> <<EMAIL>>
 *  Copyright (C) 2005 <NAME> <<EMAIL>>
 *  Copyright (C) 2001 <NAME>.
 *
 * This file is placed under the LGPL.  Please see the file
 * COPYING for more details.
 *
 * SPDX-License-Identifier: LGPL-2.1
 *
 *
 * Linearly scale touchscreen values
 */
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>

#include "config.h"
#include "tslib-private.h"
#include "tslib-filter.h"

struct tslib_linear {
	struct tslib_module_info module;
	int	swap_xy;

	/* Linear scaling and offset parameters for pressure */
	int	p_offset;
	int	p_mult;
	int	p_div;

	/* Linear scaling and offset parameters for x,y (can include rotation) */
	int	a[7];

	/* Screen resolution at the time when calibration was performed */
	unsigned int cal_res_x;
	unsigned int cal_res_y;
};

static int linear_read(struct tslib_module_info *info, struct ts_sample *samp,
		       int nr_samples)
{
	struct tslib_linear *lin = (struct tslib_linear *)info;
	int ret;
	int xtemp, ytemp;

	ret = info->next->ops->read(info->next, samp, nr_samples);
	if (ret >= 0) {
		int nr;

		for (nr = 0; nr < ret; nr++, samp++) {
		#ifdef DEBUG
			fprintf(stderr,
				"BEFORE CALIB--------------------> %d %d %d\n",
				samp->x, samp->y, samp->pressure);
		#endif /* DEBUG */
			xtemp = samp->x; ytemp = samp->y;
			samp->x =	(lin->a[2] +
					lin->a[0]*xtemp +
					lin->a[1]*ytemp) / lin->a[6];
			samp->y =	(lin->a[5] +
					lin->a[3]*xtemp +
					lin->a[4]*ytemp) / lin->a[6];
			if (info->dev->res_x && lin->cal_res_x)
				samp->x = samp->x * info->dev->res_x
					  / lin->cal_res_x;
			if (info->dev->res_y && lin->cal_res_y)
				samp->y = samp->y * info->dev->res_y
					  / lin->cal_res_y;

			samp->pressure = ((samp->pressure + lin->p_offset)
					  * lin->p_mult) / lin->p_div;
			if (lin->swap_xy) {
				int tmp = samp->x;

				samp->x = samp->y;
				samp->y = tmp;
			}
		}
	}

	return ret;
}

static int linear_read_mt(struct tslib_module_info *info,
			  struct ts_sample_mt **samp,
			  int max_slots, int nr_samples)
{
	struct tslib_linear *lin = (struct tslib_linear *)info;
	int ret;
	int xtemp, ytemp;
	int i;
	int nr;

	if (!info->next->ops->read_mt)
		return -ENOSYS;

	ret = info->next->ops->read_mt(info->next, samp, max_slots, nr_samples);
	if (ret < 0)
		return ret;

	for (nr = 0; nr < ret; nr++) {
	#ifdef DEBUG
		printf("LINEAR:   read %d samples (mem: %d nr x %d slots)\n",
		       ret, nr_samples, max_slots);
		fprintf(stderr, "BEFORE CALIB:\n");
	#endif /*DEBUG*/
		for (i = 0; i < max_slots; i++) {
			if (!(samp[nr][i].valid & TSLIB_MT_VALID))
				continue;

		#ifdef DEBUG
			fprintf(stderr, "          (slot %d) X:%4d Y:%4d P:%d\n",
				i, samp[nr][i].x, samp[nr][i].y,
				samp[nr][i].pressure);
		#endif /*DEBUG*/
			xtemp = samp[nr][i].x;
			ytemp = samp[nr][i].y;
			samp[nr][i].x =	(lin->a[2] +
					lin->a[0]*xtemp +
					lin->a[1]*ytemp) / lin->a[6];
			samp[nr][i].y =	(lin->a[5] +
					lin->a[3]*xtemp +
					lin->a[4]*ytemp) / lin->a[6];
			if (info->dev->res_x && lin->cal_res_x)
				samp[nr][i].x = samp[nr][i].x *
						info->dev->res_x /
						lin->cal_res_x;
			if (info->dev->res_y && lin->cal_res_y)
				samp[nr][i].y = samp[nr][i].y *
						info->dev->res_y /
						lin->cal_res_y;

			samp[nr][i].pressure = ((samp[nr][i].pressure +
						 lin->p_offset) *
						 lin->p_mult) /
						 lin->p_div;
			if (lin->swap_xy) {
				int tmp = samp[nr][i].x;

				samp[nr][i].x = samp[nr][i].y;
				samp[nr][i].y = tmp;
			}
		}
	}

	return ret;
}

static int linear_fini(struct tslib_module_info *info)
{
	free(info);
	return 0;
}

static const struct tslib_ops linear_ops = {
	.read		= linear_read,
	.read_mt	= linear_read_mt,
	.fini		= linear_fini,
};

static int linear_xyswap(struct tslib_module_info *inf,
			 __attribute__ ((unused)) char *str,
			 __attribute__ ((unused)) void *data)
{
	struct tslib_linear *lin = (struct tslib_linear *)inf;

	lin->swap_xy = 1;
	return 0;
}

static int linear_p_offset(struct tslib_module_info *inf, char *str,
			   __attribute__ ((unused)) void *data)
{
	struct tslib_linear *lin = (struct tslib_linear *)inf;

	unsigned long offset = strtoul(str, NULL, 0);

	if (offset == ULONG_MAX && errno == ERANGE)
		return -1;

	lin->p_offset = offset;
	return 0;
}

static int linear_p_mult(struct tslib_module_info *inf, char *str,
			 __attribute__ ((unused)) void *data)
{
	struct tslib_linear *lin = (struct tslib_linear *)inf;
	unsigned long mult = strtoul(str, NULL, 0);

	if (mult == ULONG_MAX && errno == ERANGE)
		return -1;

	lin->p_mult = mult;
	return 0;
}

static int linear_p_div(struct tslib_module_info *inf, char *str,
			__attribute__ ((unused)) void *data)
{
	struct tslib_linear *lin = (struct tslib_linear *)inf;
	unsigned long div = strtoul(str, NULL, 0);

	if (div == ULONG_MAX && errno == ERANGE)
		return -1;

	lin->p_div = div;
	return 0;
}

static const struct tslib_vars linear_vars[] = {
	{ "xyswap",	(void *)1, linear_xyswap },
	{ "pressure_offset", NULL, linear_p_offset},
	{ "pressure_mul", NULL, linear_p_mult},
	{ "pressure_div", NULL, linear_p_div},
};

#define NR_VARS (sizeof(linear_vars) / sizeof(linear_vars[0]))

TSAPI struct tslib_module_info *linear_mod_init(__attribute__ ((unused)) struct tsdev *dev,
						const char *params)
{

	struct tslib_linear *lin;
	struct stat sbuf;
	FILE *pcal_fd;
	int index;
	char *calfile;

	lin = malloc(sizeof(struct tslib_linear));
	if (lin == NULL)
		return NULL;

	lin->module.ops = &linear_ops;

	/* Use default values that leave ts numbers unchanged after transform */
	lin->a[0] = 1;
	lin->a[1] = 0;
	lin->a[2] = 0;
	lin->a[3] = 0;
	lin->a[4] = 1;
	lin->a[5] = 0;
	lin->a[6] = 1;
	lin->p_offset = 0;
	lin->p_mult   = 1;
	lin->p_div    = 1;
	lin->swap_xy  = 0;

	/*
	 * Check calibration file
	 */
	if ((calfile = getenv("TSLIB_CALIBFILE")) == NULL)
		calfile = TS_POINTERCAL;

	if (stat(calfile, &sbuf) == 0) {
		pcal_fd = fopen(calfile, "r");
		if (!pcal_fd) {
			free(lin);
			perror("fopen");
			return NULL;
		}

		for (index = 0; index < 7; index++)
			if (fscanf(pcal_fd, "%d", &lin->a[index]) != 1)
				break;

		if (!fscanf(pcal_fd, "%d %d", &lin->cal_res_x, &lin->cal_res_y))
			fprintf(stderr,
				"LINEAR: Couldn't read resolution values\n");

#ifdef DEBUG
		printf("Linear calibration constants: ");
		for (index = 0; index < 7; index++)
			printf("%d ", lin->a[index]);
		printf("\n");
#endif /*DEBUG*/
		fclose(pcal_fd);
	}

	/*
	 * Parse the parameters.
	 */
	if (tslib_parse_vars(&lin->module, linear_vars, NR_VARS, params)) {
		free(lin);
		return NULL;
	}

	return &lin->module;
}

#ifndef TSLIB_STATIC_LINEAR_MODULE
	TSLIB_MODULE_INIT(linear_mod_init);
#endif


<|start_filename|>3rdpart/ethercat-1.5.2/tool/CommandCStruct.cpp<|end_filename|>
/*****************************************************************************
 *
 *  $Id: CommandCStruct.cpp,v bc2d4bf9cbe5 2012/09/06 18:22:24 fp $
 *
 *  Copyright (C) 2006-2009  <NAME>, Ingenieurgemeinschaft IgH
 *
 *  This file is part of the IgH EtherCAT Master.
 *
 *  The IgH EtherCAT Master is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License version 2, as
 *  published by the Free Software Foundation.
 *
 *  The IgH EtherCAT Master is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 *  Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with the IgH EtherCAT Master; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 *  vim: expandtab
 *
 ****************************************************************************/

#include <iostream>
#include <iomanip>
#include <string.h>
using namespace std;

#include "CommandCStruct.h"
#include "MasterDevice.h"

/*****************************************************************************/

CommandCStruct::CommandCStruct():
    Command("cstruct", "Generate slave PDO information in C language.")
{
}

/*****************************************************************************/

string CommandCStruct::helpString(const string &binaryBaseName) const
{
    stringstream str;

    str << binaryBaseName << " " << getName() << " [OPTIONS]" << endl
        << endl
        << getBriefDescription() << endl
        << endl
        << "The output C code can be used directly with the" << endl
        << "ecrt_slave_config_pdos() function of the application" << endl
        << "interface." << endl
        << endl
        << "Command-specific options:" << endl
        << "  --alias    -a <alias>" << endl
        << "  --position -p <pos>    Slave selection. See the help of" << endl
        << "                         the 'slaves' command." << endl
        << endl
        << numericInfo();

    return str.str();
}

/****************************************************************************/

void CommandCStruct::execute(const StringVector &args)
{
    MasterIndexList masterIndices;
    SlaveList slaves;
    SlaveList::const_iterator si;

    if (args.size()) {
        stringstream err;
        err << "'" << getName() << "' takes no arguments!";
        throwInvalidUsageException(err);
    }

    masterIndices = getMasterIndices();
    MasterIndexList::const_iterator mi;
    for (mi = masterIndices.begin();
            mi != masterIndices.end(); mi++) {
        MasterDevice m(*mi);
        m.open(MasterDevice::Read);
        slaves = selectedSlaves(m);

        for (si = slaves.begin(); si != slaves.end(); si++) {
            generateSlaveCStruct(m, *si);
        }
    }
}

/****************************************************************************/

void CommandCStruct::generateSlaveCStruct(
        MasterDevice &m,
        const ec_ioctl_slave_t &slave
        )
{
    ec_ioctl_slave_sync_t sync;
    ec_ioctl_slave_sync_pdo_t pdo;
    ec_ioctl_slave_sync_pdo_entry_t entry;
    unsigned int i, j, k, pdo_pos = 0, entry_pos = 0;
    stringstream id, syncs, pdos, entries;

    if (!slave.sync_count)
        return;

    id << "slave_" << dec << slave.position << "_";

    for (i = 0; i < slave.sync_count; i++) {
        m.getSync(&sync, slave.position, i);

        syncs << "    {" << dec << sync.sync_index
            << ", " << (EC_READ_BIT(&sync.control_register, 2) ?
                    "EC_DIR_OUTPUT" : "EC_DIR_INPUT")
            << ", " << dec << (unsigned int) sync.pdo_count
            << ", ";
        if (sync.pdo_count) {
            syncs << id.str() << "pdos + " << dec << pdo_pos;
        } else {
            syncs << "NULL";
        }
        syncs << ", " << (EC_READ_BIT(&sync.control_register, 6) ?
                "EC_WD_ENABLE" : "EC_WD_DISABLE")
            << "},";
        syncs << endl;
        pdo_pos += sync.pdo_count;

        for (j = 0; j < sync.pdo_count; j++) {
            m.getPdo(&pdo, slave.position, i, j);

            pdos << "    {0x" << hex << setfill('0')
                << setw(4) << pdo.index
                << ", " << dec << (unsigned int) pdo.entry_count
                << ", ";
                if (pdo.entry_count) {
                    pdos << id.str() << "pdo_entries + " << dec << entry_pos;
                } else {
                    pdos << "NULL";
                }
            pdos << "},";
            if (strlen((const char *) pdo.name)) {
                pdos << " /* " << pdo.name << " */";
            }
            pdos << endl;
            entry_pos += pdo.entry_count;

            for (k = 0; k < pdo.entry_count; k++) {
                m.getPdoEntry(&entry, slave.position, i, j, k);

                entries << "    {0x" << hex << setfill('0')
                    << setw(4) << entry.index
                    << ", 0x" << setw(2) << (unsigned int) entry.subindex
                    << ", " << dec << (unsigned int) entry.bit_length
                    << "},";
                if (strlen((const char *) entry.name)) {
                    entries << " /* " << entry.name << " */";
                }
                entries << endl;
            }
        }
    }

    cout
        << "/* Master " << m.getIndex() << ", Slave " << slave.position;
    if (strlen(slave.order)) {
        cout << ", \"" << slave.order << "\"";
    }

    cout << endl
        << " * Vendor ID:       0x" << hex << setfill('0')
        << setw(8) << slave.vendor_id << endl
        << " * Product code:    0x" << hex << setfill('0')
        << setw(8) << slave.product_code << endl
        << " * Revision number: 0x" << hex << setfill('0')
        << setw(8) << slave.revision_number << endl
        << " */" << endl
        << endl;

    if (entry_pos) {
        cout << "ec_pdo_entry_info_t " << id.str()
            << "pdo_entries[] = {" << endl
            << entries.str()
            << "};" << endl
            << endl;
    }

    if (pdo_pos) {
        cout << "ec_pdo_info_t " << id.str() << "pdos[] = {" << endl
            << pdos.str()
            << "};" << endl
            << endl;
    }

    cout << "ec_sync_info_t " << id.str() << "syncs[] = {" << endl
        << syncs.str()
        << "    {0xff}" << endl
        << "};" << endl
        << endl;
}

/*****************************************************************************/


<|start_filename|>kernel/modules/virtual_framebuffer/Makefile<|end_filename|>
ifeq ($(KERNELRELEASE),)

ifeq ($(ARCH),arm)
KERNELDIR ?= /home/morris/SUDA_V3S/kernel/linux-zero-4.13.y
ROOTFSDIR ?= /home/morris/SUDA_V3S/rootfs/multistrap/rootfs
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
endif

PWD ?= $(shell pwd)

modules:
	$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
modules_install:
	$(MAKE) -C $(KERNELDIR) M=$(PWD) INSTALL_MOD_PATH=$(ROOTFSDIR) modules_install
clean:
	rm -rf *.o *.ko .*.cmd *.mod.* modules.order Module.symvers .tmp_versions 

else

obj-m := vfb.o

endif

<|start_filename|>3rdpart/tslib-1.15/plugins/h3600-raw.c<|end_filename|>
/*
 * SPDX-License-Identifier: LGPL-2.1
 */
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>

#include "config.h"
#include "tslib-private.h"

struct h3600_ts_event { /* Used in the Compaq IPAQ */
	unsigned short pressure;
	unsigned short x;
	unsigned short y;
	unsigned short pad;
};

static int h3600_read(struct tslib_module_info *inf, struct ts_sample *samp,
		      int nr)
{
	struct tsdev *ts = inf->dev;
	struct h3600_ts_event *h3600_evt;
	int ret;
	int nr_read;

	h3600_evt = alloca(sizeof(*h3600_evt) * nr);
	ret = read(ts->fd, h3600_evt, sizeof(*h3600_evt) * nr);
	if (ret > 0) {
		nr_read = ret / sizeof(*h3600_evt);
		while (ret >= (int)sizeof(*h3600_evt)) {
			samp->x = h3600_evt->x;
			samp->y = h3600_evt->y;
			samp->pressure = h3600_evt->pressure;
#ifdef DEBUG
	fprintf(stderr, "RAW---------------------------> %d %d %d\n",
		samp->x, samp->y, samp->pressure);
#endif /*DEBUG*/
			gettimeofday(&samp->tv, NULL);
			samp++;
			h3600_evt++;
			ret -= sizeof(*h3600_evt);
		}
	} else {
		return -1;
	}

	ret = nr_read;
	return ret;
}

static const struct tslib_ops h3600_ops = {
	.read	= h3600_read,
};

TSAPI struct tslib_module_info *h3600_mod_init(__attribute__ ((unused)) struct tsdev *dev,
					       __attribute__ ((unused)) const char *params)
{
	struct tslib_module_info *m;

	m = malloc(sizeof(struct tslib_module_info));
	if (m == NULL)
		return NULL;

	m->ops = &h3600_ops;
	return m;
}

#ifndef TSLIB_STATIC_H3600_MODULE
	TSLIB_MODULE_INIT(h3600_mod_init);
#endif


<|start_filename|>kernel/modules/virtual_serial/vser_test.c<|end_filename|>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <poll.h>
#include <signal.h>

#include "vser.h"

int fd;

static void sigio_handler(int signum, siginfo_t *siginfo, void *act)
{
    int ret;
    char buf[32];
    if (signum == SIGIO)
    {
        /* si_band记录着资源是可读还是可写 */
        if (siginfo->si_band & POLLIN)
        {
            printf("FIFO is not empty\n");
            ret = read(fd, buf, sizeof(buf));
            if (ret != -1)
            {
                buf[ret] = '\0';
                puts(buf);
            }
        }
        if (siginfo->si_band & POLLOUT)
        {
            printf("FIFO is not full\n");
        }
    }
}

int main()
{
    int ret;
    int flag;

    struct sigaction newact, oldact;

    /* sigaction比signal更高级，主要是信号阻塞和提供信号信息这两方面 */
    /* 设置信号处理函数中要屏蔽的信号，防止嵌套 */
    sigemptyset(&newact.sa_mask);
    sigaddset(&newact.sa_mask, SIGIO);
    /* 注册信号函数 */
    newact.sa_flags = SA_SIGINFO;
    newact.sa_sigaction = sigio_handler;
    if (sigaction(SIGIO, &newact, &oldact) == -1)
    {
        goto fail;
    }

    fd = open("/dev/vser0", O_RDWR | O_NONBLOCK);
    if (fd == -1)
    {
        goto fail;
    }
    /* 设置文件属主，从而驱动可以根据file结构来找到对应的进程 */
    if (fcntl(fd, F_SETOWN, getpid()) == -1)
    {
        goto fail;
    }
    /* F_SETSIG不是POSIX标准，需要在编译时候加上-D_GNU_SOURCE */
    /* 当设备资源可用时，向进程发送SIGIO信号 */
    if (fcntl(fd, F_SETSIG, SIGIO) == -1)
    {
        goto fail;
    }
    /* 使能异步通知机制 */
    flag = fcntl(fd, F_GETFL);
    if (flag == -1)
    {
        goto fail;
    }
    /* 会触发调用驱动中的fasync接口函数 */
    if (fcntl(fd, F_SETFL, flag | FASYNC) == -1)
    {
        goto fail;
    }

    while (1)
    {
        sleep(1);
    }
    exit(EXIT_SUCCESS);
fail:
    perror("fasync test");
    exit(EXIT_FAILURE);
}

<|start_filename|>3rdpart/ethercat-1.5.2/master/datagram.c<|end_filename|>
/******************************************************************************
 *
 *  $Id: datagram.c,v ec403cf308eb 2013/02/12 14:46:43 fp $
 *
 *  Copyright (C) 2006-2008  <NAME>, Ingenieurgemeinschaft IgH
 *
 *  This file is part of the IgH EtherCAT Master.
 *
 *  The IgH EtherCAT Master is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License version 2, as
 *  published by the Free Software Foundation.
 *
 *  The IgH EtherCAT Master is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 *  Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with the IgH EtherCAT Master; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 *****************************************************************************/

/**
   \file
   Methods of an EtherCAT datagram.
*/

/*****************************************************************************/

#include <linux/slab.h>

#include "datagram.h"
#include "master.h"

/*****************************************************************************/

/** \cond */

#define EC_FUNC_HEADER \
    ret = ec_datagram_prealloc(datagram, data_size); \
    if (unlikely(ret)) \
        return ret; \
    datagram->index = 0; \
    datagram->working_counter = 0; \
    datagram->state = EC_DATAGRAM_INIT;

#define EC_FUNC_FOOTER \
    datagram->data_size = data_size; \
    return 0;

/** \endcond */

/*****************************************************************************/

/** Array of datagram type strings used in ec_datagram_type_string().
 *
 * \attention This is indexed by ec_datagram_type_t.
 */
static const char *type_strings[] = {
    "?",
    "APRD",
    "APWR",
    "APRW",
    "FPRD",
    "FPWR",
    "FPRW",
    "BRD",
    "BWR",
    "BRW",
    "LRD",
    "LWR",
    "LRW",
    "ARMW",
    "FRMW"
};

/*****************************************************************************/

/** Constructor.
 */
void ec_datagram_init(ec_datagram_t *datagram /**< EtherCAT datagram. */)
{
    INIT_LIST_HEAD(&datagram->queue); // mark as unqueued
    datagram->device_index = EC_DEVICE_MAIN;
    datagram->type = EC_DATAGRAM_NONE;
    memset(datagram->address, 0x00, EC_ADDR_LEN);
    datagram->data = NULL;
    datagram->data_origin = EC_ORIG_INTERNAL;
    datagram->mem_size = 0;
    datagram->data_size = 0;
    datagram->index = 0x00;
    datagram->working_counter = 0x0000;
    datagram->state = EC_DATAGRAM_INIT;
#ifdef EC_HAVE_CYCLES
    datagram->cycles_sent = 0;
#endif
    datagram->jiffies_sent = 0;
#ifdef EC_HAVE_CYCLES
    datagram->cycles_received = 0;
#endif
    datagram->jiffies_received = 0;
    datagram->skip_count = 0;
    datagram->stats_output_jiffies = 0;
    memset(datagram->name, 0x00, EC_DATAGRAM_NAME_SIZE);
}

/*****************************************************************************/

/** Destructor.
 */
void ec_datagram_clear(ec_datagram_t *datagram /**< EtherCAT datagram. */)
{
    ec_datagram_unqueue(datagram);

    if (datagram->data_origin == EC_ORIG_INTERNAL && datagram->data) {
        kfree(datagram->data);
        datagram->data = NULL;
    }
}

/*****************************************************************************/

/** Unqueue datagram.
 */
void ec_datagram_unqueue(ec_datagram_t *datagram /**< EtherCAT datagram. */)
{
    if (!list_empty(&datagram->queue)) {
        list_del_init(&datagram->queue);
    }
}

/*****************************************************************************/

/** Allocates internal payload memory.
 *
 * If the allocated memory is already larger than requested, nothing ist done.
 *
 * \attention If external payload memory has been provided, no range checking
 *            is done!
 *
 * \return 0 in case of success, otherwise \a -ENOMEM.
 */
int ec_datagram_prealloc(
        ec_datagram_t *datagram, /**< EtherCAT datagram. */
        size_t size /**< New payload size in bytes. */
        )
{
    if (datagram->data_origin == EC_ORIG_EXTERNAL
            || size <= datagram->mem_size)
        return 0;

    if (datagram->data) {
        kfree(datagram->data);
        datagram->data = NULL;
        datagram->mem_size = 0;
    }

    if (!(datagram->data = kmalloc(size, GFP_KERNEL))) {
        EC_ERR("Failed to allocate %zu bytes of datagram memory!\n", size);
        return -ENOMEM;
    }

    datagram->mem_size = size;
    return 0;
}

/*****************************************************************************/

/** Fills the datagram payload memory with zeros.
 */
void ec_datagram_zero(ec_datagram_t *datagram /**< EtherCAT datagram. */)
{
    memset(datagram->data, 0x00, datagram->data_size);
}

/*****************************************************************************/

/** Initializes an EtherCAT APRD datagram.
 *
 * \return Return value of ec_datagram_prealloc().
 */
int ec_datagram_aprd(
        ec_datagram_t *datagram, /**< EtherCAT datagram. */
        uint16_t ring_position, /**< Auto-increment address. */
        uint16_t mem_address, /**< Physical memory address. */
        size_t data_size /**< Number of bytes to read. */
        )
{
    int ret;
    EC_FUNC_HEADER;
    datagram->type = EC_DATAGRAM_APRD;
    EC_WRITE_S16(datagram->address, (int16_t) ring_position * (-1));
    EC_WRITE_U16(datagram->address + 2, mem_address);
    EC_FUNC_FOOTER;
}

/*****************************************************************************/

/** Initializes an EtherCAT APWR datagram.
 *
 * \return Return value of ec_datagram_prealloc().
 */
int ec_datagram_apwr(
        ec_datagram_t *datagram, /**< EtherCAT datagram. */
        uint16_t ring_position, /**< Auto-increment address. */
        uint16_t mem_address, /**< Physical memory address. */
        size_t data_size /**< Number of bytes to write. */
        )
{
    int ret;
    EC_FUNC_HEADER;
    datagram->type = EC_DATAGRAM_APWR;
    EC_WRITE_S16(datagram->address, (int16_t) ring_position * (-1));
    EC_WRITE_U16(datagram->address + 2, mem_address);
    EC_FUNC_FOOTER;
}

/*****************************************************************************/

/** Initializes an EtherCAT APRW datagram.
 *
 * \return Return value of ec_datagram_prealloc().
 */
int ec_datagram_aprw(
        ec_datagram_t *datagram, /**< EtherCAT datagram. */
        uint16_t ring_position, /**< Auto-increment address. */
        uint16_t mem_address, /**< Physical memory address. */
        size_t data_size /**< Number of bytes to write. */
        )
{
    int ret;
    EC_FUNC_HEADER;
    datagram->type = EC_DATAGRAM_APRW;
    EC_WRITE_S16(datagram->address, (int16_t) ring_position * (-1));
    EC_WRITE_U16(datagram->address + 2, mem_address);
    EC_FUNC_FOOTER;
}

/*****************************************************************************/

/** Initializes an EtherCAT ARMW datagram.
 *
 * \return Return value of ec_datagram_prealloc().
 */
int ec_datagram_armw(
        ec_datagram_t *datagram, /**< EtherCAT datagram. */
        uint16_t ring_position, /**< Auto-increment address. */
        uint16_t mem_address, /**< Physical memory address. */
        size_t data_size /**< Number of bytes to read. */
        )
{
    int ret;
    EC_FUNC_HEADER;
    datagram->type = EC_DATAGRAM_ARMW;
    EC_WRITE_S16(datagram->address, (int16_t) ring_position * (-1));
    EC_WRITE_U16(datagram->address + 2, mem_address);
    EC_FUNC_FOOTER;
}

/*****************************************************************************/

/** Initializes an EtherCAT FPRD datagram.
 *
 * \return Return value of ec_datagram_prealloc().
 */
int ec_datagram_fprd(
        ec_datagram_t *datagram, /**< EtherCAT datagram. */
        uint16_t configured_address, /**< Configured station address. */
        uint16_t mem_address, /**< Physical memory address. */
        size_t data_size /**< Number of bytes to read. */
        )
{
    int ret;

    if (unlikely(configured_address == 0x0000))
        EC_WARN("Using configured station address 0x0000!\n");

    EC_FUNC_HEADER;
    datagram->type = EC_DATAGRAM_FPRD;
    EC_WRITE_U16(datagram->address, configured_address);
    EC_WRITE_U16(datagram->address + 2, mem_address);
    EC_FUNC_FOOTER;
}

/*****************************************************************************/

/** Initializes an EtherCAT FPWR datagram.
 *
 * \return Return value of ec_datagram_prealloc().
 */
int ec_datagram_fpwr(
        ec_datagram_t *datagram, /**< EtherCAT datagram. */
        uint16_t configured_address, /**< Configured station address. */
        uint16_t mem_address, /**< Physical memory address. */
        size_t data_size /**< Number of bytes to write. */
        )
{
    int ret;

    if (unlikely(configured_address == 0x0000))
        EC_WARN("Using configured station address 0x0000!\n");

    EC_FUNC_HEADER;
    datagram->type = EC_DATAGRAM_FPWR;
    EC_WRITE_U16(datagram->address, configured_address);
    EC_WRITE_U16(datagram->address + 2, mem_address);
    EC_FUNC_FOOTER;
}

/*****************************************************************************/

/** Initializes an EtherCAT FPRW datagram.
 *
 * \return Return value of ec_datagram_prealloc().
 */
int ec_datagram_fprw(
        ec_datagram_t *datagram, /**< EtherCAT datagram. */
        uint16_t configured_address, /**< Configured station address. */
        uint16_t mem_address, /**< Physical memory address. */
        size_t data_size /**< Number of bytes to write. */
        )
{
    int ret;

    if (unlikely(configured_address == 0x0000))
        EC_WARN("Using configured station address 0x0000!\n");

    EC_FUNC_HEADER;
    datagram->type = EC_DATAGRAM_FPRW;
    EC_WRITE_U16(datagram->address, configured_address);
    EC_WRITE_U16(datagram->address + 2, mem_address);
    EC_FUNC_FOOTER;
}

/*****************************************************************************/

/** Initializes an EtherCAT FRMW datagram.
 *
 * \return Return value of ec_datagram_prealloc().
 */
int ec_datagram_frmw(
        ec_datagram_t *datagram, /**< EtherCAT datagram. */
        uint16_t configured_address, /**< Configured station address. */
        uint16_t mem_address, /**< Physical memory address. */
        size_t data_size /**< Number of bytes to write. */
        )
{
    int ret;

    if (unlikely(configured_address == 0x0000))
        EC_WARN("Using configured station address 0x0000!\n");

    EC_FUNC_HEADER;
    datagram->type = EC_DATAGRAM_FRMW;
    EC_WRITE_U16(datagram->address, configured_address);
    EC_WRITE_U16(datagram->address + 2, mem_address);
    EC_FUNC_FOOTER;
}

/*****************************************************************************/

/** Initializes an EtherCAT BRD datagram.
 *
 * \return Return value of ec_datagram_prealloc().
 */
int ec_datagram_brd(
        ec_datagram_t *datagram, /**< EtherCAT datagram. */
        uint16_t mem_address, /**< Physical memory address. */
        size_t data_size /**< Number of bytes to read. */
        )
{
    int ret;
    EC_FUNC_HEADER;
    datagram->type = EC_DATAGRAM_BRD;
    EC_WRITE_U16(datagram->address, 0x0000);
    EC_WRITE_U16(datagram->address + 2, mem_address);
    EC_FUNC_FOOTER;
}

/*****************************************************************************/

/** Initializes an EtherCAT BWR datagram.
 *
 * \return Return value of ec_datagram_prealloc().
 */
int ec_datagram_bwr(
        ec_datagram_t *datagram, /**< EtherCAT datagram. */
        uint16_t mem_address, /**< Physical memory address. */
        size_t data_size /**< Number of bytes to write. */
        )
{
    int ret;
    EC_FUNC_HEADER;
    datagram->type = EC_DATAGRAM_BWR;
    EC_WRITE_U16(datagram->address, 0x0000);
    EC_WRITE_U16(datagram->address + 2, mem_address);
    EC_FUNC_FOOTER;
}

/*****************************************************************************/

/** Initializes an EtherCAT BRW datagram.
 *
 * \return Return value of ec_datagram_prealloc().
 */
int ec_datagram_brw(
        ec_datagram_t *datagram, /**< EtherCAT datagram. */
        uint16_t mem_address, /**< Physical memory address. */
        size_t data_size /**< Number of bytes to write. */
        )
{
    int ret;
    EC_FUNC_HEADER;
    datagram->type = EC_DATAGRAM_BRW;
    EC_WRITE_U16(datagram->address, 0x0000);
    EC_WRITE_U16(datagram->address + 2, mem_address);
    EC_FUNC_FOOTER;
}

/*****************************************************************************/

/** Initializes an EtherCAT LRD datagram.
 *
 * \return Return value of ec_datagram_prealloc().
 */
int ec_datagram_lrd(
        ec_datagram_t *datagram, /**< EtherCAT datagram. */
        uint32_t offset, /**< Logical address. */
        size_t data_size /**< Number of bytes to read/write. */
        )
{
    int ret;
    EC_FUNC_HEADER;
    datagram->type = EC_DATAGRAM_LRD;
    EC_WRITE_U32(datagram->address, offset);
    EC_FUNC_FOOTER;
}

/*****************************************************************************/

/** Initializes an EtherCAT LWR datagram.
 *
 * \return Return value of ec_datagram_prealloc().
 */
int ec_datagram_lwr(
        ec_datagram_t *datagram, /**< EtherCAT datagram. */
        uint32_t offset, /**< Logical address. */
        size_t data_size /**< Number of bytes to read/write. */
        )
{
    int ret;
    EC_FUNC_HEADER;
    datagram->type = EC_DATAGRAM_LWR;
    EC_WRITE_U32(datagram->address, offset);
    EC_FUNC_FOOTER;
}

/*****************************************************************************/

/** Initializes an EtherCAT LRW datagram.
 *
 * \return Return value of ec_datagram_prealloc().
 */
int ec_datagram_lrw(
        ec_datagram_t *datagram, /**< EtherCAT datagram. */
        uint32_t offset, /**< Logical address. */
        size_t data_size /**< Number of bytes to read/write. */
        )
{
    int ret;
    EC_FUNC_HEADER;
    datagram->type = EC_DATAGRAM_LRW;
    EC_WRITE_U32(datagram->address, offset);
    EC_FUNC_FOOTER;
}

/*****************************************************************************/

/** Initializes an EtherCAT LRD datagram with external memory.
 *
 * \attention It is assumed, that the external memory is at least \a data_size
 *            bytes large.
 *
 * \return Return value of ec_datagram_prealloc().
 */
int ec_datagram_lrd_ext(
        ec_datagram_t *datagram, /**< EtherCAT datagram. */
        uint32_t offset, /**< Logical address. */
        size_t data_size, /**< Number of bytes to read/write. */
        uint8_t *external_memory /**< Pointer to the memory to use. */
        )
{
    int ret;
    datagram->data = external_memory;
    datagram->data_origin = EC_ORIG_EXTERNAL;
    EC_FUNC_HEADER;
    datagram->type = EC_DATAGRAM_LRD;
    EC_WRITE_U32(datagram->address, offset);
    EC_FUNC_FOOTER;
}

/*****************************************************************************/

/** Initializes an EtherCAT LWR datagram with external memory.
 *
 * \attention It is assumed, that the external memory is at least \a data_size
 *            bytes large.
 *
 * \return Return value of ec_datagram_prealloc().
 */
int ec_datagram_lwr_ext(
        ec_datagram_t *datagram, /**< EtherCAT datagram. */
        uint32_t offset, /**< Logical address. */
        size_t data_size, /**< Number of bytes to read/write. */
        uint8_t *external_memory /**< Pointer to the memory to use. */
        )
{
    int ret;
    datagram->data = external_memory;
    datagram->data_origin = EC_ORIG_EXTERNAL;
    EC_FUNC_HEADER;
    datagram->type = EC_DATAGRAM_LWR;
    EC_WRITE_U32(datagram->address, offset);
    EC_FUNC_FOOTER;
}

/*****************************************************************************/

/** Initializes an EtherCAT LRW datagram with external memory.
 *
 * \attention It is assumed, that the external memory is at least \a data_size
 *            bytes large.
 *
 * \return Return value of ec_datagram_prealloc().
 */
int ec_datagram_lrw_ext(
        ec_datagram_t *datagram, /**< EtherCAT datagram. */
        uint32_t offset, /**< Logical address. */
        size_t data_size, /**< Number of bytes to read/write. */
        uint8_t *external_memory /**< Pointer to the memory to use. */
        )
{
    int ret;
    datagram->data = external_memory;
    datagram->data_origin = EC_ORIG_EXTERNAL;
    EC_FUNC_HEADER;
    datagram->type = EC_DATAGRAM_LRW;
    EC_WRITE_U32(datagram->address, offset);
    EC_FUNC_FOOTER;
}

/*****************************************************************************/

/** Prints the state of a datagram.
 *
 * Outputs a text message.
 */
void ec_datagram_print_state(
        const ec_datagram_t *datagram /**< EtherCAT datagram */
        )
{
    printk("Datagram ");
    switch (datagram->state) {
        case EC_DATAGRAM_INIT:
            printk("initialized");
            break;
        case EC_DATAGRAM_QUEUED:
            printk("queued");
            break;
        case EC_DATAGRAM_SENT:
            printk("sent");
            break;
        case EC_DATAGRAM_RECEIVED:
            printk("received");
            break;
        case EC_DATAGRAM_TIMED_OUT:
            printk("timed out");
            break;
        case EC_DATAGRAM_ERROR:
            printk("error");
            break;
        default:
            printk("???");
    }

    printk(".\n");
}

/*****************************************************************************/

/** Evaluates the working counter of a single-cast datagram.
 *
 * Outputs an error message.
 */
void ec_datagram_print_wc_error(
        const ec_datagram_t *datagram /**< EtherCAT datagram */
        )
{
    if (datagram->working_counter == 0)
        printk("No response.");
    else if (datagram->working_counter > 1)
        printk("%u slaves responded!", datagram->working_counter);
    else
        printk("Success.");
    printk("\n");
}

/*****************************************************************************/

/** Outputs datagram statistics at most every second.
 */
void ec_datagram_output_stats(
        ec_datagram_t *datagram
        )
{
    if (jiffies - datagram->stats_output_jiffies > HZ) {
        datagram->stats_output_jiffies = jiffies;

        if (unlikely(datagram->skip_count)) {
            EC_WARN("Datagram %p (%s) was SKIPPED %u time%s.\n",
                    datagram, datagram->name,
                    datagram->skip_count,
                    datagram->skip_count == 1 ? "" : "s");
            datagram->skip_count = 0;
        }
    }
}

/*****************************************************************************/

/** Returns a string describing the datagram type.
 *
 * \return Pointer on a static memory containing the requested string.
 */
const char *ec_datagram_type_string(
        const ec_datagram_t *datagram /**< EtherCAT datagram. */
        )
{
    return type_strings[datagram->type];
}

/*****************************************************************************/


<|start_filename|>3rdpart/ethercat-1.5.2/master/ethernet.c<|end_filename|>
/******************************************************************************
 *
 *  $Id: ethernet.c,v ec403cf308eb 2013/02/12 14:46:43 fp $
 *
 *  Copyright (C) 2006-2008  <NAME>, Ingenieurgemeinschaft IgH
 *
 *  This file is part of the IgH EtherCAT Master.
 *
 *  The IgH EtherCAT Master is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License version 2, as
 *  published by the Free Software Foundation.
 *
 *  The IgH EtherCAT Master is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 *  Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with the IgH EtherCAT Master; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 *****************************************************************************/

/**
   \file
   Ethernet over EtherCAT (EoE).
*/

/*****************************************************************************/

#include <linux/version.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>

#include "globals.h"
#include "master.h"
#include "slave.h"
#include "mailbox.h"
#include "ethernet.h"

/*****************************************************************************/

/** Defines the debug level of EoE processing.
 *
 * 0 = No debug messages.
 * 1 = Output warnings.
 * 2 = Output actions.
 * 3 = Output actions and frame data.
 */
#define EOE_DEBUG_LEVEL 1

/** Size of the EoE tx queue.
 */
#define EC_EOE_TX_QUEUE_SIZE 100

/** Number of tries.
 */
#define EC_EOE_TRIES 100

/*****************************************************************************/

void ec_eoe_flush(ec_eoe_t *);

// state functions
void ec_eoe_state_rx_start(ec_eoe_t *);
void ec_eoe_state_rx_check(ec_eoe_t *);
void ec_eoe_state_rx_fetch(ec_eoe_t *);
void ec_eoe_state_tx_start(ec_eoe_t *);
void ec_eoe_state_tx_sent(ec_eoe_t *);

// net_device functions
int ec_eoedev_open(struct net_device *);
int ec_eoedev_stop(struct net_device *);
int ec_eoedev_tx(struct sk_buff *, struct net_device *);
struct net_device_stats *ec_eoedev_stats(struct net_device *);

/*****************************************************************************/

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)
/** Device operations for EoE interfaces.
 */
static const struct net_device_ops ec_eoedev_ops = {
    .ndo_open = ec_eoedev_open,
    .ndo_stop = ec_eoedev_stop,
    .ndo_start_xmit = ec_eoedev_tx,
    .ndo_get_stats = ec_eoedev_stats,
};
#endif

/*****************************************************************************/

/** EoE constructor.
 *
 * Initializes the EoE handler, creates a net_device and registers it.
 *
 * \return Zero on success, otherwise a negative error code.
 */
int ec_eoe_init(
        ec_eoe_t *eoe, /**< EoE handler */
        ec_slave_t *slave /**< EtherCAT slave */
        )
{
    ec_eoe_t **priv;
    int i, ret = 0;
    char name[EC_DATAGRAM_NAME_SIZE];

    eoe->slave = slave;

    ec_datagram_init(&eoe->datagram);
    eoe->queue_datagram = 0;
    eoe->state = ec_eoe_state_rx_start;
    eoe->opened = 0;
    eoe->rx_skb = NULL;
    eoe->rx_expected_fragment = 0;
    INIT_LIST_HEAD(&eoe->tx_queue);
    eoe->tx_frame = NULL;
    eoe->tx_queue_active = 0;
    eoe->tx_queue_size = EC_EOE_TX_QUEUE_SIZE;
    eoe->tx_queued_frames = 0;

    sema_init(&eoe->tx_queue_sem, 1);
    eoe->tx_frame_number = 0xFF;
    memset(&eoe->stats, 0, sizeof(struct net_device_stats));

    eoe->rx_counter = 0;
    eoe->tx_counter = 0;
    eoe->rx_rate = 0;
    eoe->tx_rate = 0;
    eoe->rate_jiffies = 0;
    eoe->rx_idle = 1;
    eoe->tx_idle = 1;

    /* device name eoe<MASTER>[as]<SLAVE>, because networking scripts don't
     * like hyphens etc. in interface names. */
    if (slave->effective_alias) {
        snprintf(name, EC_DATAGRAM_NAME_SIZE,
                "eoe%ua%u", slave->master->index, slave->effective_alias);
    } else {
        snprintf(name, EC_DATAGRAM_NAME_SIZE,
                "eoe%us%u", slave->master->index, slave->ring_position);
    }

    snprintf(eoe->datagram.name, EC_DATAGRAM_NAME_SIZE, name);

    if (!(eoe->dev = alloc_netdev(sizeof(ec_eoe_t *), name, NET_NAME_UNKNOWN, ether_setup))) {
        EC_SLAVE_ERR(slave, "Unable to allocate net_device %s"
                " for EoE handler!\n", name);
        ret = -ENODEV;
        goto out_return;
    }

    // initialize net_device
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)
    eoe->dev->netdev_ops = &ec_eoedev_ops;
#else
    eoe->dev->open = ec_eoedev_open;
    eoe->dev->stop = ec_eoedev_stop;
    eoe->dev->hard_start_xmit = ec_eoedev_tx;
    eoe->dev->get_stats = ec_eoedev_stats;
#endif

    for (i = 0; i < ETH_ALEN; i++)
        eoe->dev->dev_addr[i] = i | (i << 4);

    // initialize private data
    priv = netdev_priv(eoe->dev);
    *priv = eoe;

    // Usually setting the MTU appropriately makes the upper layers
    // do the frame fragmenting. In some cases this doesn't work
    // so the MTU is left on the Ethernet standard value and fragmenting
    // is done "manually".
#if 0
    eoe->dev->mtu = slave->configured_rx_mailbox_size - ETH_HLEN - 10;
#endif

    // connect the net_device to the kernel
    ret = register_netdev(eoe->dev);
    if (ret) {
        EC_SLAVE_ERR(slave, "Unable to register net_device:"
                " error %i\n", ret);
        goto out_free;
    }

    // make the last address octet unique
    eoe->dev->dev_addr[ETH_ALEN - 1] = (uint8_t) eoe->dev->ifindex;
    return 0;

 out_free:
    free_netdev(eoe->dev);
    eoe->dev = NULL;
 out_return:
    return ret;
}

/*****************************************************************************/

/** EoE destructor.
 *
 * Unregisteres the net_device and frees allocated memory.
 */
void ec_eoe_clear(ec_eoe_t *eoe /**< EoE handler */)
{
    unregister_netdev(eoe->dev); // possibly calls close callback

    // empty transmit queue
    ec_eoe_flush(eoe);

    if (eoe->tx_frame) {
        dev_kfree_skb(eoe->tx_frame->skb);
        kfree(eoe->tx_frame);
    }

    if (eoe->rx_skb)
        dev_kfree_skb(eoe->rx_skb);

    free_netdev(eoe->dev);

    ec_datagram_clear(&eoe->datagram);
}

/*****************************************************************************/

/** Empties the transmit queue.
 */
void ec_eoe_flush(ec_eoe_t *eoe /**< EoE handler */)
{
    ec_eoe_frame_t *frame, *next;

    down(&eoe->tx_queue_sem);

    list_for_each_entry_safe(frame, next, &eoe->tx_queue, queue) {
        list_del(&frame->queue);
        dev_kfree_skb(frame->skb);
        kfree(frame);
    }
    eoe->tx_queued_frames = 0;

    up(&eoe->tx_queue_sem);
}

/*****************************************************************************/

/** Sends a frame or the next fragment.
 *
 * \return Zero on success, otherwise a negative error code.
 */
int ec_eoe_send(ec_eoe_t *eoe /**< EoE handler */)
{
    size_t remaining_size, current_size, complete_offset;
    unsigned int last_fragment;
    uint8_t *data;
#if EOE_DEBUG_LEVEL >= 3
    unsigned int i;
#endif

    remaining_size = eoe->tx_frame->skb->len - eoe->tx_offset;

    if (remaining_size <= eoe->slave->configured_tx_mailbox_size - 10) {
        current_size = remaining_size;
        last_fragment = 1;
    } else {
        current_size = ((eoe->slave->configured_tx_mailbox_size - 10) / 32) * 32;
        last_fragment = 0;
    }

    if (eoe->tx_fragment_number) {
        complete_offset = eoe->tx_offset / 32;
    }
    else {
        // complete size in 32 bit blocks, rounded up.
        complete_offset = remaining_size / 32 + 1;
    }

#if EOE_DEBUG_LEVEL >= 2
    EC_SLAVE_DBG(slave, 0, "EoE %s TX sending fragment %u%s"
            " with %u octets (%u). %u frames queued.\n",
            eoe->dev->name, eoe->tx_fragment_number,
            last_fragment ? "" : "+", current_size, complete_offset,
            eoe->tx_queued_frames);
#endif

#if EOE_DEBUG_LEVEL >= 3
    EC_SLAVE_DBG(master, 0, "");
    for (i = 0; i < current_size; i++) {
        printk("%02X ", eoe->tx_frame->skb->data[eoe->tx_offset + i]);
        if ((i + 1) % 16 == 0) {
            printk("\n");
            EC_SLAVE_DBG(master, 0, "");
        }
    }
    printk("\n");
#endif

    data = ec_slave_mbox_prepare_send(eoe->slave, &eoe->datagram,
            0x02, current_size + 4);
    if (IS_ERR(data))
        return PTR_ERR(data);

    EC_WRITE_U8 (data,     0x00); // eoe fragment req.
    EC_WRITE_U8 (data + 1, last_fragment);
    EC_WRITE_U16(data + 2, ((eoe->tx_fragment_number & 0x3F) |
                            (complete_offset & 0x3F) << 6 |
                            (eoe->tx_frame_number & 0x0F) << 12));

    memcpy(data + 4, eoe->tx_frame->skb->data + eoe->tx_offset, current_size);
    eoe->queue_datagram = 1;

    eoe->tx_offset += current_size;
    eoe->tx_fragment_number++;
    return 0;
}

/*****************************************************************************/

/** Runs the EoE state machine.
 */
void ec_eoe_run(ec_eoe_t *eoe /**< EoE handler */)
{
    if (!eoe->opened)
        return;

    // if the datagram was not sent, or is not yet received, skip this cycle
    if (eoe->queue_datagram || eoe->datagram.state == EC_DATAGRAM_SENT)
        return;

    // call state function
    eoe->state(eoe);

    // update statistics
    if (jiffies - eoe->rate_jiffies > HZ) {
        eoe->rx_rate = eoe->rx_counter;
        eoe->tx_rate = eoe->tx_counter;
        eoe->rx_counter = 0;
        eoe->tx_counter = 0;
        eoe->rate_jiffies = jiffies;
    }

    ec_datagram_output_stats(&eoe->datagram);
}

/*****************************************************************************/

/** Queues the datagram, if necessary.
 */
void ec_eoe_queue(ec_eoe_t *eoe /**< EoE handler */)
{
   if (eoe->queue_datagram) {
       ec_master_queue_datagram_ext(eoe->slave->master, &eoe->datagram);
       eoe->queue_datagram = 0;
   }
}

/*****************************************************************************/

/** Returns the state of the device.
 *
 * \return 1 if the device is "up", 0 if it is "down"
 */
int ec_eoe_is_open(const ec_eoe_t *eoe /**< EoE handler */)
{
    return eoe->opened;
}

/*****************************************************************************/

/** Returns the idle state.
 *
 * \retval 1 The device is idle.
 * \retval 0 The device is busy.
 */
int ec_eoe_is_idle(const ec_eoe_t *eoe /**< EoE handler */)
{
    return eoe->rx_idle && eoe->tx_idle;
}

/******************************************************************************
 *  STATE PROCESSING FUNCTIONS
 *****************************************************************************/

/** State: RX_START.
 *
 * Starts a new receiving sequence by queueing a datagram that checks the
 * slave's mailbox for a new EoE datagram.
 *
 * \todo Use both devices.
 */
void ec_eoe_state_rx_start(ec_eoe_t *eoe /**< EoE handler */)
{
    if (eoe->slave->error_flag ||
            !eoe->slave->master->devices[EC_DEVICE_MAIN].link_state) {
        eoe->rx_idle = 1;
        eoe->tx_idle = 1;
        return;
    }

    ec_slave_mbox_prepare_check(eoe->slave, &eoe->datagram);
    eoe->queue_datagram = 1;
    eoe->state = ec_eoe_state_rx_check;
}

/*****************************************************************************/

/** State: RX_CHECK.
 *
 * Processes the checking datagram sent in RX_START and issues a receive
 * datagram, if new data is available.
 */
void ec_eoe_state_rx_check(ec_eoe_t *eoe /**< EoE handler */)
{
    if (eoe->datagram.state != EC_DATAGRAM_RECEIVED) {
        eoe->stats.rx_errors++;
#if EOE_DEBUG_LEVEL >= 1
        EC_SLAVE_WARN(eoe->slave, "Failed to receive mbox"
                " check datagram for %s.\n", eoe->dev->name);
#endif
        eoe->state = ec_eoe_state_tx_start;
        return;
    }

    if (!ec_slave_mbox_check(&eoe->datagram)) {
        eoe->rx_idle = 1;
        eoe->state = ec_eoe_state_tx_start;
        return;
    }

    eoe->rx_idle = 0;
    ec_slave_mbox_prepare_fetch(eoe->slave, &eoe->datagram);
    eoe->queue_datagram = 1;
    eoe->state = ec_eoe_state_rx_fetch;
}

/*****************************************************************************/

/** State: RX_FETCH.
 *
 * Checks if the requested data of RX_CHECK was received and processes the EoE
 * datagram.
 */
void ec_eoe_state_rx_fetch(ec_eoe_t *eoe /**< EoE handler */)
{
    size_t rec_size, data_size;
    uint8_t *data, frame_type, last_fragment, time_appended, mbox_prot;
    uint8_t fragment_offset, fragment_number;
#if EOE_DEBUG_LEVEL >= 2
    uint8_t frame_number;
#endif
    off_t offset;
#if EOE_DEBUG_LEVEL >= 3
    unsigned int i;
#endif

    if (eoe->datagram.state != EC_DATAGRAM_RECEIVED) {
        eoe->stats.rx_errors++;
#if EOE_DEBUG_LEVEL >= 1
        EC_SLAVE_WARN(eoe->slave, "Failed to receive mbox"
                " fetch datagram for %s.\n", eoe->dev->name);
#endif
        eoe->state = ec_eoe_state_tx_start;
        return;
    }

    data = ec_slave_mbox_fetch(eoe->slave, &eoe->datagram,
            &mbox_prot, &rec_size);
    if (IS_ERR(data)) {
        eoe->stats.rx_errors++;
#if EOE_DEBUG_LEVEL >= 1
        EC_SLAVE_WARN(eoe->slave, "Invalid mailbox response for %s.\n",
                eoe->dev->name);
#endif
        eoe->state = ec_eoe_state_tx_start;
        return;
    }

    if (mbox_prot != 0x02) { // EoE FIXME mailbox handler necessary
        eoe->stats.rx_errors++;
#if EOE_DEBUG_LEVEL >= 1
        EC_SLAVE_WARN(eoe->slave, "Other mailbox protocol response for %s.\n",
                eoe->dev->name);
#endif
        eoe->state = ec_eoe_state_tx_start;
        return;
    }

    frame_type = EC_READ_U16(data) & 0x000F;

    if (frame_type != 0x00) {
#if EOE_DEBUG_LEVEL >= 1
        EC_SLAVE_WARN(eoe->slave, "%s: Other frame received."
                " Dropping.\n", eoe->dev->name);
#endif
        eoe->stats.rx_dropped++;
        eoe->state = ec_eoe_state_tx_start;
        return;
    }

    // EoE Fragment Request received

    last_fragment = (EC_READ_U16(data) >> 8) & 0x0001;
    time_appended = (EC_READ_U16(data) >> 9) & 0x0001;
    fragment_number = EC_READ_U16(data + 2) & 0x003F;
    fragment_offset = (EC_READ_U16(data + 2) >> 6) & 0x003F;
#if EOE_DEBUG_LEVEL >= 2
    frame_number = (EC_READ_U16(data + 2) >> 12) & 0x000F;
#endif

#if EOE_DEBUG_LEVEL >= 2
    EC_SLAVE_DBG(eoe->slave, 0, "EoE %s RX fragment %u%s, offset %u,"
            " frame %u%s, %u octets\n", eoe->dev->name, fragment_number,
           last_fragment ? "" : "+", fragment_offset, frame_number,
           time_appended ? ", + timestamp" : "",
           time_appended ? rec_size - 8 : rec_size - 4);
#endif

#if EOE_DEBUG_LEVEL >= 3
    EC_SLAVE_DBG(eoe->slave, 0, "");
    for (i = 0; i < rec_size - 4; i++) {
        printk("%02X ", data[i + 4]);
        if ((i + 1) % 16 == 0) {
            printk("\n");
            EC_SLAVE_DBG(eoe->slave, 0, "");
        }
    }
    printk("\n");
#endif

    data_size = time_appended ? rec_size - 8 : rec_size - 4;

    if (!fragment_number) {
        if (eoe->rx_skb) {
            EC_SLAVE_WARN(eoe->slave, "EoE RX freeing old socket buffer.\n");
            dev_kfree_skb(eoe->rx_skb);
        }

        // new socket buffer
        if (!(eoe->rx_skb = dev_alloc_skb(fragment_offset * 32))) {
            if (printk_ratelimit())
                EC_SLAVE_WARN(eoe->slave, "EoE RX low on mem,"
                        " frame dropped.\n");
            eoe->stats.rx_dropped++;
            eoe->state = ec_eoe_state_tx_start;
            return;
        }

        eoe->rx_skb_offset = 0;
        eoe->rx_skb_size = fragment_offset * 32;
        eoe->rx_expected_fragment = 0;
    }
    else {
        if (!eoe->rx_skb) {
            eoe->stats.rx_dropped++;
            eoe->state = ec_eoe_state_tx_start;
            return;
        }

        offset = fragment_offset * 32;
        if (offset != eoe->rx_skb_offset ||
            offset + data_size > eoe->rx_skb_size ||
            fragment_number != eoe->rx_expected_fragment) {
            dev_kfree_skb(eoe->rx_skb);
            eoe->rx_skb = NULL;
            eoe->stats.rx_errors++;
#if EOE_DEBUG_LEVEL >= 1
            EC_SLAVE_WARN(eoe->slave, "Fragmenting error at %s.\n",
                    eoe->dev->name);
#endif
            eoe->state = ec_eoe_state_tx_start;
            return;
        }
    }

    // copy fragment into socket buffer
    memcpy(skb_put(eoe->rx_skb, data_size), data + 4, data_size);
    eoe->rx_skb_offset += data_size;

    if (last_fragment) {
        // update statistics
        eoe->stats.rx_packets++;
        eoe->stats.rx_bytes += eoe->rx_skb->len;
        eoe->rx_counter += eoe->rx_skb->len;

#if EOE_DEBUG_LEVEL >= 2
        EC_SLAVE_DBG(eoe->slave, 0, "EoE %s RX frame completed"
                " with %u octets.\n", eoe->dev->name, eoe->rx_skb->len);
#endif

        // pass socket buffer to network stack
        eoe->rx_skb->dev = eoe->dev;
        eoe->rx_skb->protocol = eth_type_trans(eoe->rx_skb, eoe->dev);
        eoe->rx_skb->ip_summed = CHECKSUM_UNNECESSARY;
        if (netif_rx(eoe->rx_skb)) {
            EC_SLAVE_WARN(eoe->slave, "EoE RX netif_rx failed.\n");
        }
        eoe->rx_skb = NULL;

        eoe->state = ec_eoe_state_tx_start;
    }
    else {
        eoe->rx_expected_fragment++;
#if EOE_DEBUG_LEVEL >= 2
        EC_SLAVE_DBG(eoe->slave, 0, "EoE %s RX expecting fragment %u\n",
               eoe->dev->name, eoe->rx_expected_fragment);
#endif
        eoe->state = ec_eoe_state_rx_start;
    }
}

/*****************************************************************************/

/** State: TX START.
 *
 * Starts a new transmit sequence. If no data is available, a new receive
 * sequence is started instead.
 *
 * \todo Use both devices.
 */
void ec_eoe_state_tx_start(ec_eoe_t *eoe /**< EoE handler */)
{
#if EOE_DEBUG_LEVEL >= 2
    unsigned int wakeup = 0;
#endif

    if (eoe->slave->error_flag ||
            !eoe->slave->master->devices[EC_DEVICE_MAIN].link_state) {
        eoe->rx_idle = 1;
        eoe->tx_idle = 1;
        return;
    }

    down(&eoe->tx_queue_sem);

    if (!eoe->tx_queued_frames || list_empty(&eoe->tx_queue)) {
        up(&eoe->tx_queue_sem);
        eoe->tx_idle = 1;
        // no data available.
        // start a new receive immediately.
        ec_eoe_state_rx_start(eoe);
        return;
    }

    // take the first frame out of the queue
    eoe->tx_frame = list_entry(eoe->tx_queue.next, ec_eoe_frame_t, queue);
    list_del(&eoe->tx_frame->queue);
    if (!eoe->tx_queue_active &&
        eoe->tx_queued_frames == eoe->tx_queue_size / 2) {
        netif_wake_queue(eoe->dev);
        eoe->tx_queue_active = 1;
#if EOE_DEBUG_LEVEL >= 2
        wakeup = 1;
#endif
    }

    eoe->tx_queued_frames--;
    up(&eoe->tx_queue_sem);

    eoe->tx_idle = 0;

    eoe->tx_frame_number++;
    eoe->tx_frame_number %= 16;
    eoe->tx_fragment_number = 0;
    eoe->tx_offset = 0;

    if (ec_eoe_send(eoe)) {
        dev_kfree_skb(eoe->tx_frame->skb);
        kfree(eoe->tx_frame);
        eoe->tx_frame = NULL;
        eoe->stats.tx_errors++;
        eoe->state = ec_eoe_state_rx_start;
#if EOE_DEBUG_LEVEL >= 1
        EC_SLAVE_WARN(eoe->slave, "Send error at %s.\n", eoe->dev->name);
#endif
        return;
    }

#if EOE_DEBUG_LEVEL >= 2
    if (wakeup)
        EC_SLAVE_DBG(eoe->slave, 0, "EoE %s waking up TX queue...\n",
                eoe->dev->name);
#endif

    eoe->tries = EC_EOE_TRIES;
    eoe->state = ec_eoe_state_tx_sent;
}

/*****************************************************************************/

/** State: TX SENT.
 *
 * Checks is the previous transmit datagram succeded and sends the next
 * fragment, if necessary.
 */
void ec_eoe_state_tx_sent(ec_eoe_t *eoe /**< EoE handler */)
{
    if (eoe->datagram.state != EC_DATAGRAM_RECEIVED) {
        if (eoe->tries) {
            eoe->tries--; // try again
            eoe->queue_datagram = 1;
        } else {
            eoe->stats.tx_errors++;
#if EOE_DEBUG_LEVEL >= 1
            EC_SLAVE_WARN(eoe->slave, "Failed to receive send"
                    " datagram for %s after %u tries.\n",
                    eoe->dev->name, EC_EOE_TRIES);
#endif
            eoe->state = ec_eoe_state_rx_start;
        }
        return;
    }

    if (eoe->datagram.working_counter != 1) {
        if (eoe->tries) {
            eoe->tries--; // try again
            eoe->queue_datagram = 1;
        } else {
            eoe->stats.tx_errors++;
#if EOE_DEBUG_LEVEL >= 1
            EC_SLAVE_WARN(eoe->slave, "No sending response"
                    " for %s after %u tries.\n",
                    eoe->dev->name, EC_EOE_TRIES);
#endif
            eoe->state = ec_eoe_state_rx_start;
        }
        return;
    }

    // frame completely sent
    if (eoe->tx_offset >= eoe->tx_frame->skb->len) {
        eoe->stats.tx_packets++;
        eoe->stats.tx_bytes += eoe->tx_frame->skb->len;
        eoe->tx_counter += eoe->tx_frame->skb->len;
        dev_kfree_skb(eoe->tx_frame->skb);
        kfree(eoe->tx_frame);
        eoe->tx_frame = NULL;
        eoe->state = ec_eoe_state_rx_start;
    }
    else { // send next fragment
        if (ec_eoe_send(eoe)) {
            dev_kfree_skb(eoe->tx_frame->skb);
            kfree(eoe->tx_frame);
            eoe->tx_frame = NULL;
            eoe->stats.tx_errors++;
#if EOE_DEBUG_LEVEL >= 1
            EC_SLAVE_WARN(eoe->slave, "Send error at %s.\n", eoe->dev->name);
#endif
            eoe->state = ec_eoe_state_rx_start;
        }
    }
}

/******************************************************************************
 *  NET_DEVICE functions
 *****************************************************************************/

/** Opens the virtual network device.
 *
 * \return Always zero (success).
 */
int ec_eoedev_open(struct net_device *dev /**< EoE net_device */)
{
    ec_eoe_t *eoe = *((ec_eoe_t **) netdev_priv(dev));
    ec_eoe_flush(eoe);
    eoe->opened = 1;
    eoe->rx_idle = 0;
    eoe->tx_idle = 0;
    netif_start_queue(dev);
    eoe->tx_queue_active = 1;
#if EOE_DEBUG_LEVEL >= 2
    EC_SLAVE_DBG(eoe->slave, 0, "%s opened.\n", dev->name);
#endif
    ec_slave_request_state(eoe->slave, EC_SLAVE_STATE_OP);
    return 0;
}

/*****************************************************************************/

/** Stops the virtual network device.
 *
 * \return Always zero (success).
 */
int ec_eoedev_stop(struct net_device *dev /**< EoE net_device */)
{
    ec_eoe_t *eoe = *((ec_eoe_t **) netdev_priv(dev));
    netif_stop_queue(dev);
    eoe->rx_idle = 1;
    eoe->tx_idle = 1;
    eoe->tx_queue_active = 0;
    eoe->opened = 0;
    ec_eoe_flush(eoe);
#if EOE_DEBUG_LEVEL >= 2
    EC_SLAVE_DBG(eoe->slave, 0, "%s stopped.\n", dev->name);
#endif
    ec_slave_request_state(eoe->slave, EC_SLAVE_STATE_PREOP);
    return 0;
}

/*****************************************************************************/

/** Transmits data via the virtual network device.
 *
 * \return Zero on success, non-zero on failure.
 */
int ec_eoedev_tx(struct sk_buff *skb, /**< transmit socket buffer */
                 struct net_device *dev /**< EoE net_device */
                )
{
    ec_eoe_t *eoe = *((ec_eoe_t **) netdev_priv(dev));
    ec_eoe_frame_t *frame;

#if 0
    if (skb->len > eoe->slave->configured_tx_mailbox_size - 10) {
        EC_SLAVE_WARN(eoe->slave, "EoE TX frame (%u octets)"
                " exceeds MTU. dropping.\n", skb->len);
        dev_kfree_skb(skb);
        eoe->stats.tx_dropped++;
        return 0;
    }
#endif

    if (!(frame =
          (ec_eoe_frame_t *) kmalloc(sizeof(ec_eoe_frame_t), GFP_ATOMIC))) {
        if (printk_ratelimit())
            EC_SLAVE_WARN(eoe->slave, "EoE TX: low on mem. frame dropped.\n");
        return 1;
    }

    frame->skb = skb;

    down(&eoe->tx_queue_sem);
    list_add_tail(&frame->queue, &eoe->tx_queue);
    eoe->tx_queued_frames++;
    if (eoe->tx_queued_frames == eoe->tx_queue_size) {
        netif_stop_queue(dev);
        eoe->tx_queue_active = 0;
    }
    up(&eoe->tx_queue_sem);

#if EOE_DEBUG_LEVEL >= 2
    EC_SLAVE_DBG(eoe->slave, 0, "EoE %s TX queued frame"
            " with %u octets (%u frames queued).\n",
            eoe->dev->name, skb->len, eoe->tx_queued_frames);
    if (!eoe->tx_queue_active)
        EC_SLAVE_WARN(eoe->slave, "EoE TX queue is now full.\n");
#endif

    return 0;
}

/*****************************************************************************/

/** Gets statistics about the virtual network device.
 *
 * \return Statistics.
 */
struct net_device_stats *ec_eoedev_stats(
        struct net_device *dev /**< EoE net_device */
        )
{
    ec_eoe_t *eoe = *((ec_eoe_t **) netdev_priv(dev));
    return &eoe->stats;
}

/*****************************************************************************/


<|start_filename|>3rdpart/ethercat-1.5.2/tool/CommandMaster.cpp<|end_filename|>
/*****************************************************************************
 *
 *  $Id: CommandMaster.cpp,v d461b1f07296 2012/11/30 19:15:31 fp $
 *
 *  Copyright (C) 2006-2009  <NAME>, Ingenieurgemeinschaft IgH
 *
 *  This file is part of the IgH EtherCAT Master.
 *
 *  The IgH EtherCAT Master is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License version 2, as
 *  published by the Free Software Foundation.
 *
 *  The IgH EtherCAT Master is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 *  Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with the IgH EtherCAT Master; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 ****************************************************************************/

#include <iostream>
#include <iomanip>
using namespace std;

#include "CommandMaster.h"
#include "MasterDevice.h"

#define MAX_TIME_STR_SIZE 50

/*****************************************************************************/

CommandMaster::CommandMaster():
    Command("master", "Show master and Ethernet device information.")
{
}

/****************************************************************************/

string CommandMaster::helpString(const string &binaryBaseName) const
{
    stringstream str;

    str << binaryBaseName << " " << getName() << " [OPTIONS]" << endl
        << endl
        << getBriefDescription() << endl
        << endl
        << "Command-specific options:" << endl
        << "  --master -m <indices>  Master indices. A comma-separated" << endl
        << "                         list with ranges is supported." << endl
        << "                         Example: 1,4,5,7-9. Default: - (all)."
        << endl << endl
        << numericInfo();

    return str.str();
}

/****************************************************************************/

void CommandMaster::execute(const StringVector &args)
{
	MasterIndexList masterIndices;
    ec_ioctl_master_t data;
    stringstream err;
    unsigned int dev_idx, j;
    time_t epoch;
    char time_str[MAX_TIME_STR_SIZE + 1];
    size_t time_str_size;

    if (args.size()) {
        err << "'" << getName() << "' takes no arguments!";
        throwInvalidUsageException(err);
    }

	masterIndices = getMasterIndices();
    MasterIndexList::const_iterator mi;
    for (mi = masterIndices.begin();
            mi != masterIndices.end(); mi++) {
        MasterDevice m(*mi);
        m.open(MasterDevice::Read);
        m.getMaster(&data);

        cout
            << "Master" << m.getIndex() << endl
            << "  Phase: ";

        switch (data.phase) {
            case 0:  cout << "Waiting for device(s)..."; break;
            case 1:  cout << "Idle"; break;
            case 2:  cout << "Operation"; break;
            default: cout << "???";
        }

        cout << endl
            << "  Active: " << (data.active ? "yes" : "no") << endl
            << "  Slaves: " << data.slave_count << endl
            << "  Ethernet devices:" << endl;

        for (dev_idx = EC_DEVICE_MAIN; dev_idx < data.num_devices;
                dev_idx++) {
            cout << "    " << (dev_idx == EC_DEVICE_MAIN ? "Main" : "Backup")
                << ": ";
            cout << hex << setfill('0')
                << setw(2) << (unsigned int) data.devices[dev_idx].address[0]
                << ":"
                << setw(2) << (unsigned int) data.devices[dev_idx].address[1]
                << ":"
                << setw(2) << (unsigned int) data.devices[dev_idx].address[2]
                << ":"
                << setw(2) << (unsigned int) data.devices[dev_idx].address[3]
                << ":"
                << setw(2) << (unsigned int) data.devices[dev_idx].address[4]
                << ":"
                << setw(2) << (unsigned int) data.devices[dev_idx].address[5]
                << " ("
                << (data.devices[dev_idx].attached ?
                        "attached" : "waiting...")
                << ")" << endl << dec
                << "      Link: "
                << (data.devices[dev_idx].link_state ? "UP" : "DOWN") << endl
                << "      Tx frames:   "
                << data.devices[dev_idx].tx_count << endl
                << "      Tx bytes:    "
                << data.devices[dev_idx].tx_bytes << endl
                << "      Rx frames:   "
                << data.devices[dev_idx].rx_count << endl
                << "      Rx bytes:    "
                << data.devices[dev_idx].rx_bytes << endl
                << "      Tx errors:   "
                << data.devices[dev_idx].tx_errors << endl
                << "      Tx frame rate [1/s]: "
                << setfill(' ') << setprecision(0) << fixed;
            for (j = 0; j < EC_RATE_COUNT; j++) {
                cout << setw(ColWidth)
                    << data.devices[dev_idx].tx_frame_rates[j] / 1000.0;
                if (j < EC_RATE_COUNT - 1) {
                    cout << " ";
                }
            }
            cout << endl
                << "      Tx rate [KByte/s]:   "
                << setprecision(1) << fixed;
            for (j = 0; j < EC_RATE_COUNT; j++) {
                cout << setw(ColWidth)
                    << data.devices[dev_idx].tx_byte_rates[j] / 1024.0;
                if (j < EC_RATE_COUNT - 1) {
                    cout << " ";
                }
            }
            cout << endl
                << "      Rx frame rate [1/s]: "
                << setfill(' ') << setprecision(0) << fixed;
            for (j = 0; j < EC_RATE_COUNT; j++) {
                cout << setw(ColWidth)
                    << data.devices[dev_idx].rx_frame_rates[j] / 1000.0;
                if (j < EC_RATE_COUNT - 1) {
                    cout << " ";
                }
            }
            cout << endl
                << "      Rx rate [KByte/s]:   "
                << setprecision(1) << fixed;
            for (j = 0; j < EC_RATE_COUNT; j++) {
                cout << setw(ColWidth)
                    << data.devices[dev_idx].rx_byte_rates[j] / 1024.0;
                if (j < EC_RATE_COUNT - 1) {
                    cout << " ";
                }
            }
            cout << setprecision(0) << endl;
        }
        unsigned int lost = data.tx_count - data.rx_count;
        if (lost == 1) {
            // allow one frame travelling
            lost = 0;
        }
        cout << "    Common:" << endl
            << "      Tx frames:   "
            << data.tx_count << endl
            << "      Tx bytes:    "
            << data.tx_bytes << endl
            << "      Rx frames:   "
            << data.rx_count << endl
            << "      Rx bytes:    "
            << data.rx_bytes << endl
            << "      Lost frames: " << lost << endl
            << "      Tx frame rate [1/s]: "
            << setfill(' ') << setprecision(0) << fixed;
        for (j = 0; j < EC_RATE_COUNT; j++) {
            cout << setw(ColWidth)
                << data.tx_frame_rates[j] / 1000.0;
            if (j < EC_RATE_COUNT - 1) {
                cout << " ";
            }
        }
        cout << endl
            << "      Tx rate [KByte/s]:   "
            << setprecision(1) << fixed;
        for (j = 0; j < EC_RATE_COUNT; j++) {
            cout << setw(ColWidth)
                << data.tx_byte_rates[j] / 1024.0;
            if (j < EC_RATE_COUNT - 1) {
                cout << " ";
            }
        }
        cout << endl
            << "      Rx frame rate [1/s]: "
            << setfill(' ') << setprecision(0) << fixed;
        for (j = 0; j < EC_RATE_COUNT; j++) {
            cout << setw(ColWidth)
                << data.rx_frame_rates[j] / 1000.0;
            if (j < EC_RATE_COUNT - 1) {
                cout << " ";
            }
        }
        cout << endl
            << "      Rx rate [KByte/s]:   "
            << setprecision(1) << fixed;
        for (j = 0; j < EC_RATE_COUNT; j++) {
            cout << setw(ColWidth)
                << data.rx_byte_rates[j] / 1024.0;
            if (j < EC_RATE_COUNT - 1) {
                cout << " ";
            }
        }
        cout << endl
            << "      Loss rate [1/s]:     "
            << setprecision(0) << fixed;
        for (j = 0; j < EC_RATE_COUNT; j++) {
            cout << setw(ColWidth)
                << data.loss_rates[j] / 1000.0;
            if (j < EC_RATE_COUNT - 1) {
                cout << " ";
            }
        }
        cout << endl
            << "      Frame loss [%]:      "
            << setprecision(1) << fixed;
        for (j = 0; j < EC_RATE_COUNT; j++) {
            double perc = 0.0;
            if (data.tx_frame_rates[j]) {
                perc = 100.0 * data.loss_rates[j] / data.tx_frame_rates[j];
            }
            cout << setw(ColWidth) << perc;
            if (j < EC_RATE_COUNT - 1) {
                cout << " ";
            }
        }
        cout << setprecision(0) << endl;

        cout << "  Distributed clocks:" << endl
            << "    Reference clock: ";
        if (data.ref_clock != 0xffff) {
            cout << "Slave " << dec << data.ref_clock;
        } else {
            cout << "None";
        }
        cout << endl
            << "    Application time: " << data.app_time << endl
            << "                      ";

        epoch = data.app_time / 1000000000 + 946684800ULL;
        time_str_size = strftime(time_str, MAX_TIME_STR_SIZE,
                "%Y-%m-%d %H:%M:%S", gmtime(&epoch));
        cout << string(time_str, time_str_size) << "."
            << setfill('0') << setw(9) << data.app_time % 1000000000 << endl;
    }
}

/*****************************************************************************/


<|start_filename|>3rdpart/ethercat-1.5.2/tool/SoeCommand.cpp<|end_filename|>
/*****************************************************************************
 *
 *  $Id: SoeCommand.cpp,v 23c638a81fe7 2010/10/24 06:43:44 fp $
 *
 *  Copyright (C) 2006-2009  <NAME>, Ingenieurgemeinschaft IgH
 *
 *  This file is part of the IgH EtherCAT Master.
 *
 *  The IgH EtherCAT Master is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License version 2, as
 *  published by the Free Software Foundation.
 *
 *  The IgH EtherCAT Master is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 *  Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with the IgH EtherCAT Master; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 ****************************************************************************/

#include <iomanip>
using namespace std;

#include "SoeCommand.h"

extern const ec_code_msg_t soe_error_codes[];

/*****************************************************************************/

uint16_t SoeCommand::parseIdn(const string &str)
{
    uint16_t idn = 0x0000;
    stringstream s, err;

    if (!str.length()) {
        err << "Zero-size string not allowed!";
        throw runtime_error(err.str());
    }

    if (str[0] == 'S' || str[0] == 'P') {
        unsigned int num;
        unsigned char c;

        s << str;

        s >> c;
        if (c == 'P') {
            idn |= 0x8000;
        }

        s >> c;
        if (s.fail() || c != '-') {
             err << "'-' expected!";
             throw runtime_error(err.str());
        }

        s >> num;
        if (s.fail() || num > 7) {
            err << "Invalid parameter set number!";
            throw runtime_error(err.str());
        }
        idn |= num << 12;

        s >> c;
        if (s.fail() || c != '-') {
             err << "'-' expected!";
             throw runtime_error(err.str());
        }

        s >> num;
        if (s.fail() || num > 4095) {
            err << "Invalid data block number!";
            throw runtime_error(err.str());
        }
        idn |= num;

        s.peek();
        if (!s.eof()) {
            err << "Additional input!";
            throw runtime_error(err.str());
        }
    } else {
        s << str;
        s >> resetiosflags(ios::basefield) >> idn;
        if (s.fail()) {
            err << "Invalid number!";
            throw runtime_error(err.str());
        }
    }

    return idn;
}

/*****************************************************************************/

string SoeCommand::outputIdn(uint16_t idn)
{
    stringstream str;

    str << ((idn & 0x8000) ? 'P' : 'S')
        << "-" << ((idn >> 12) & 0x07)
        << "-" << setfill('0') << setw(4) << (idn & 0x0fff);

    return str.str();
}

/*****************************************************************************/

/** Outputs an SoE error code.
*/
std::string SoeCommand::errorMsg(uint16_t code)
{
    const ec_code_msg_t *error_msg;
	stringstream str;

	str << "0x" << hex << setfill('0') << setw(4) << code << ": ";

    for (error_msg = soe_error_codes; error_msg->code; error_msg++) {
        if (error_msg->code == code) {
			str << error_msg->message;
			return str.str();
        }
    }

	str << "(Unknown)";
	return str.str();
}

/****************************************************************************/


<|start_filename|>3rdpart/ethercat-1.5.2/master/rtdm.c<|end_filename|>
/*****************************************************************************
 *
 *  $Id: rtdm.c,v 6d9865c37b6f 2013/02/12 16:15:09 fp $
 *
 *  Copyright (C) 2009-2010  Moehwald GmbH <NAME>
 *                     2011  IgH <NAME>
 *                     2012  <NAME> <<EMAIL>>
 *
 *  This file is part of the IgH EtherCAT master.
 *
 *  The IgH EtherCAT master is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License as published
 *  by the Free Software Foundation; version 2 of the License.
 *
 *  The IgH EtherCAT master is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
 *  Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with the IgH EtherCAT master. If not, see <http://www.gnu.org/licenses/>.
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 ****************************************************************************/

/** \file
 * RTDM interface.
 */

#include <linux/module.h>
#include <linux/slab.h>
#include <linux/mman.h>

#include <rtdm/rtdm_driver.h>

#include "master.h"
#include "ioctl.h"
#include "rtdm.h"

/** Set to 1 to enable device operations debugging.
 */
#define DEBUG 0

/****************************************************************************/

/** Context structure for an open RTDM file handle.
 */
typedef struct {
    rtdm_user_info_t *user_info; /**< RTDM user data. */
    ec_ioctl_context_t ioctl_ctx; /**< Context structure. */
} ec_rtdm_context_t;

/****************************************************************************/

int ec_rtdm_open(struct rtdm_dev_context *, rtdm_user_info_t *, int);
int ec_rtdm_close(struct rtdm_dev_context *, rtdm_user_info_t *);
int ec_rtdm_ioctl(struct rtdm_dev_context *, rtdm_user_info_t *,
        unsigned int, void __user *);

/****************************************************************************/

/** Initialize an RTDM device.
 *
 * \return Zero on success, otherwise a negative error code.
 */
int ec_rtdm_dev_init(
        ec_rtdm_dev_t *rtdm_dev, /**< EtherCAT RTDM device. */
        ec_master_t *master /**< EtherCAT master. */
        )
{
    int ret;

    rtdm_dev->master = master;

    rtdm_dev->dev = kzalloc(sizeof(struct rtdm_device), GFP_KERNEL);
    if (!rtdm_dev->dev) {
        EC_MASTER_ERR(master, "Failed to reserve memory for RTDM device.\n");
        return -ENOMEM;
    }

    rtdm_dev->dev->struct_version = RTDM_DEVICE_STRUCT_VER;
    rtdm_dev->dev->device_flags = RTDM_NAMED_DEVICE;
    rtdm_dev->dev->context_size = sizeof(ec_rtdm_context_t);
    snprintf(rtdm_dev->dev->device_name, RTDM_MAX_DEVNAME_LEN,
            "EtherCAT%u", master->index);
    rtdm_dev->dev->open_nrt = ec_rtdm_open;
    rtdm_dev->dev->ops.close_nrt = ec_rtdm_close;
    rtdm_dev->dev->ops.ioctl_rt = ec_rtdm_ioctl;
    rtdm_dev->dev->ops.ioctl_nrt = ec_rtdm_ioctl;
    rtdm_dev->dev->device_class = RTDM_CLASS_EXPERIMENTAL;
    rtdm_dev->dev->device_sub_class = 222;
    rtdm_dev->dev->driver_name = "EtherCAT";
    rtdm_dev->dev->driver_version = RTDM_DRIVER_VER(1, 0, 2);
    rtdm_dev->dev->peripheral_name = rtdm_dev->dev->device_name;
    rtdm_dev->dev->provider_name = "EtherLab Community";
    rtdm_dev->dev->proc_name = rtdm_dev->dev->device_name;
    rtdm_dev->dev->device_data = rtdm_dev; /* pointer to parent */

    EC_MASTER_INFO(master, "Registering RTDM device %s.\n",
            rtdm_dev->dev->driver_name);
    ret = rtdm_dev_register(rtdm_dev->dev);
    if (ret) {
        EC_MASTER_ERR(master, "Initialization of RTDM interface failed"
                " (return value %i).\n", ret);
        kfree(rtdm_dev->dev);
    }

    return ret;
}

/****************************************************************************/

/** Clear an RTDM device.
 */
void ec_rtdm_dev_clear(
        ec_rtdm_dev_t *rtdm_dev /**< EtherCAT RTDM device. */
        )
{
    int ret;

    EC_MASTER_INFO(rtdm_dev->master, "Unregistering RTDM device %s.\n",
            rtdm_dev->dev->driver_name);
    ret = rtdm_dev_unregister(rtdm_dev->dev, 1000 /* poll delay [ms] */);
    if (ret < 0) {
        EC_MASTER_WARN(rtdm_dev->master,
                "Failed to unregister RTDM device (code %i).\n", ret);
    }

    kfree(rtdm_dev->dev);
}

/****************************************************************************/

/** Driver open.
 *
 * \return Always zero (success).
 */
int ec_rtdm_open(
        struct rtdm_dev_context *context, /**< Context. */
        rtdm_user_info_t *user_info, /**< User data. */
        int oflags /**< Open flags. */
        )
{
    ec_rtdm_context_t *ctx = (ec_rtdm_context_t *) context->dev_private;
#if DEBUG
    ec_rtdm_dev_t *rtdm_dev = (ec_rtdm_dev_t *) context->device->device_data;
#endif

    ctx->user_info = user_info;
    ctx->ioctl_ctx.writable = oflags & O_WRONLY || oflags & O_RDWR;
    ctx->ioctl_ctx.requested = 0;
    ctx->ioctl_ctx.process_data = NULL;
    ctx->ioctl_ctx.process_data_size = 0;

#if DEBUG
    EC_MASTER_INFO(rtdm_dev->master, "RTDM device %s opened.\n",
            context->device->device_name);
#endif
    return 0;
}

/****************************************************************************/

/** Driver close.
 *
 * \return Always zero (success).
 */
int ec_rtdm_close(
        struct rtdm_dev_context *context, /**< Context. */
        rtdm_user_info_t *user_info /**< User data. */
        )
{
    ec_rtdm_context_t *ctx = (ec_rtdm_context_t *) context->dev_private;
    ec_rtdm_dev_t *rtdm_dev = (ec_rtdm_dev_t *) context->device->device_data;

    if (ctx->ioctl_ctx.requested) {
        ecrt_release_master(rtdm_dev->master);
	}

#if DEBUG
    EC_MASTER_INFO(rtdm_dev->master, "RTDM device %s closed.\n",
            context->device->device_name);
#endif
    return 0;
}

/****************************************************************************/

/** Driver ioctl.
 *
 * \return ioctl() return code.
 */
int ec_rtdm_ioctl(
        struct rtdm_dev_context *context, /**< Context. */
        rtdm_user_info_t *user_info, /**< User data. */
        unsigned int request, /**< Request. */
        void __user *arg /**< Argument. */
        )
{
    ec_rtdm_context_t *ctx = (ec_rtdm_context_t *) context->dev_private;
    ec_rtdm_dev_t *rtdm_dev = (ec_rtdm_dev_t *) context->device->device_data;

#if DEBUG
    EC_MASTER_INFO(rtdm_dev->master, "ioctl(request = %u, ctl = %02x)"
            " on RTDM device %s.\n", request, _IOC_NR(request),
            context->device->device_name);
#endif
    return ec_ioctl_rtdm(rtdm_dev->master, &ctx->ioctl_ctx, request, arg);
}

/****************************************************************************/

/** Memory-map process data to user space.
 *
 * \return Zero on success, otherwise a negative error code.
 */
int ec_rtdm_mmap(
        ec_ioctl_context_t *ioctl_ctx, /**< Context. */
        void **user_address /**< Userspace address. */
        )
{
    ec_rtdm_context_t *ctx =
        container_of(ioctl_ctx, ec_rtdm_context_t, ioctl_ctx);
    int ret;

    ret = rtdm_mmap_to_user(ctx->user_info,
            ioctl_ctx->process_data, ioctl_ctx->process_data_size,
            PROT_READ | PROT_WRITE,
            user_address,
            NULL, NULL);
    if (ret < 0) {
        return ret;
    }

    return 0;
}

/****************************************************************************/


<|start_filename|>3rdpart/ethercat-1.5.2/examples/xenomai/main.c<|end_filename|>
/******************************************************************************
 *
 *  $Id: main.c,v 3bdd7a747fae 2012/09/20 13:28:25 fp $
 *
 *  Copyright (C) 2009-2010  Moehwald GmbH <NAME>
 *                     2011  IgH <NAME>
 *                     2012  <NAME> <<EMAIL>>
 *
 *  This file is part of the IgH EtherCAT master
 *
 *  The IgH EtherCAT Master is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License version 2, as
 *  published by the Free Software Foundation.
 *
 *  The IgH EtherCAT master is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
 *  Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with the IgH EtherCAT master. If not, see <http://www.gnu.org/licenses/>.
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 *****************************************************************************/

#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <sys/resource.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/mman.h>
#include <rtdm/rtdm.h>
#include <native/task.h>
#include <native/sem.h>
#include <native/mutex.h>
#include <native/timer.h>
#include <rtdk.h>
#include <pthread.h>

#include "ecrt.h"

RT_TASK my_task;

static int run = 1;

/****************************************************************************/

// EtherCAT
static ec_master_t *master = NULL;
static ec_master_state_t master_state = {};

static ec_domain_t *domain1 = NULL;
static ec_domain_state_t domain1_state = {};

static uint8_t *domain1_pd = NULL;

static ec_slave_config_t *sc_dig_out_01 = NULL;

/****************************************************************************/

// process data

#define BusCoupler01_Pos  0, 0
#define DigOutSlave01_Pos 0, 1

#define Beckhoff_EK1100 0x00000002, 0x044c2c52
#define Beckhoff_EL2004 0x00000002, 0x07d43052

// offsets for PDO entries
static unsigned int off_dig_out0 = 0;

// process data

const static ec_pdo_entry_reg_t domain1_regs[] = {
   {DigOutSlave01_Pos, Beckhoff_EL2004, 0x7000, 0x01, &off_dig_out0, NULL},
   {}
};

/****************************************************************************/

/* Slave 1, "EL2004"
 * Vendor ID:       0x00000002
 * Product code:    0x07d43052
 * Revision number: 0x00100000
 */

ec_pdo_entry_info_t slave_1_pdo_entries[] = {
   {0x7000, 0x01, 1}, /* Output */
   {0x7010, 0x01, 1}, /* Output */
   {0x7020, 0x01, 1}, /* Output */
   {0x7030, 0x01, 1}, /* Output */
};

ec_pdo_info_t slave_1_pdos[] = {
   {0x1600, 1, slave_1_pdo_entries + 0}, /* Channel 1 */
   {0x1601, 1, slave_1_pdo_entries + 1}, /* Channel 2 */
   {0x1602, 1, slave_1_pdo_entries + 2}, /* Channel 3 */
   {0x1603, 1, slave_1_pdo_entries + 3}, /* Channel 4 */
};

ec_sync_info_t slave_1_syncs[] = {
   {0, EC_DIR_OUTPUT, 4, slave_1_pdos + 0, EC_WD_ENABLE},
   {0xff}
};

/*****************************************************************************
 * Realtime task
 ****************************************************************************/

void rt_check_domain_state(void)
{
    ec_domain_state_t ds = {};

	ecrt_domain_state(domain1, &ds);

    if (ds.working_counter != domain1_state.working_counter) {
        rt_printf("Domain1: WC %u.\n", ds.working_counter);
    }

    if (ds.wc_state != domain1_state.wc_state) {
        rt_printf("Domain1: State %u.\n", ds.wc_state);
    }

    domain1_state = ds;
}

/****************************************************************************/

void rt_check_master_state(void)
{
    ec_master_state_t ms;

	ecrt_master_state(master, &ms);

    if (ms.slaves_responding != master_state.slaves_responding) {
        rt_printf("%u slave(s).\n", ms.slaves_responding);
    }

    if (ms.al_states != master_state.al_states) {
        rt_printf("AL states: 0x%02X.\n", ms.al_states);
    }

    if (ms.link_up != master_state.link_up) {
        rt_printf("Link is %s.\n", ms.link_up ? "up" : "down");
    }

    master_state = ms;
}

/****************************************************************************/

void my_task_proc(void *arg)
{
	int cycle_counter = 0;
    unsigned int blink = 0;

	rt_task_set_periodic(NULL, TM_NOW, 1000000); // ns

	while (run) {
		rt_task_wait_period(NULL);

		cycle_counter++;

		// receive EtherCAT frames
		ecrt_master_receive(master);
		ecrt_domain_process(domain1);

		rt_check_domain_state();

		if (!(cycle_counter % 1000)) {
			rt_check_master_state();
		}

		if (!(cycle_counter % 200)) {
			blink = !blink;
		}

		EC_WRITE_U8(domain1_pd + off_dig_out0, blink ? 0x0 : 0x0F);

		// send process data
		ecrt_domain_queue(domain1);
		ecrt_master_send(master);
	}
}

/****************************************************************************
 * Signal handler
 ***************************************************************************/

void signal_handler(int sig)
{
    run = 0;
}

/****************************************************************************
 * Main function
 ***************************************************************************/

int main(int argc, char *argv[])
{
    ec_slave_config_t *sc;
    int ret;

    /* Perform auto-init of rt_print buffers if the task doesn't do so */
    rt_print_auto_init(1);

    signal(SIGTERM, signal_handler);
    signal(SIGINT, signal_handler);

    mlockall(MCL_CURRENT | MCL_FUTURE);

    printf("Requesting master...\n");
    master = ecrt_request_master(0);
    if (!master) {
        return -1;
    }

    domain1 = ecrt_master_create_domain(master);
    if (!domain1) {
        return -1;
    }

    printf("Creating slave configurations...\n");

    // Create configuration for bus coupler
    sc = ecrt_master_slave_config(master, BusCoupler01_Pos, Beckhoff_EK1100);
    if (!sc) {
        return -1;
    }

    sc_dig_out_01 =
        ecrt_master_slave_config(master, DigOutSlave01_Pos, Beckhoff_EL2004);
    if (!sc_dig_out_01) {
        fprintf(stderr, "Failed to get slave configuration.\n");
        return -1;
    }

    if (ecrt_slave_config_pdos(sc_dig_out_01, EC_END, slave_1_syncs)) {
        fprintf(stderr, "Failed to configure PDOs.\n");
        return -1;
    }

    if (ecrt_domain_reg_pdo_entry_list(domain1, domain1_regs)) {
        fprintf(stderr, "PDO entry registration failed!\n");
        return -1;
    }

    printf("Activating master...\n");
    if (ecrt_master_activate(master)) {
        return -1;
    }

    if (!(domain1_pd = ecrt_domain_data(domain1))) {
        fprintf(stderr, "Failed to get domain data pointer.\n");
        return -1;
    }

    ret = rt_task_create(&my_task, "my_task", 0, 80, T_FPU);
    if (ret < 0) {
        fprintf(stderr, "Failed to create task: %s\n", strerror(-ret));
        return -1;
    }

    printf("Starting my_task...\n");
    ret = rt_task_start(&my_task, &my_task_proc, NULL);
    if (ret < 0) {
        fprintf(stderr, "Failed to start task: %s\n", strerror(-ret));
        return -1;
    }

	while (run) {
		sched_yield();
	}

    printf("Deleting realtime task...\n");
    rt_task_delete(&my_task);

    printf("End of Program\n");
    ecrt_release_master(master);

    return 0;
}

/****************************************************************************/


<|start_filename|>3rdpart/tslib-1.15/tests/ts_print_mt.c<|end_filename|>
/*
 *  tslib/tests/ts_print_mt.c
 *
 *  Copyright (C) 2017 <NAME>
 *
 * This file is part of tslib.
 *
 * ts_print_mt is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * ts_print_mt is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with ts_print_mt.  If not, see <http://www.gnu.org/licenses/>.
 *
 * SPDX-License-Identifier: GPL-2.0+
 *
 *
 * Just prints touchscreen events -- does not paint them on framebuffer
 */
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/time.h>
#include <getopt.h>
#include <errno.h>
#include <unistd.h>

#if defined (__FreeBSD__)

#include <dev/evdev/input.h>
#define TS_HAVE_EVDEV

#elif defined (__linux__)

#include <linux/input.h>
#define TS_HAVE_EVDEV

#endif

#ifdef TS_HAVE_EVDEV
#include <sys/ioctl.h>
#endif

#include "tslib.h"
#include "testutils.h"

#ifndef ABS_MT_SLOT /* < 2.6.36 kernel headers */
# define ABS_MT_SLOT             0x2f    /* MT slot being modified */
#endif

static void usage(char **argv)
{
	struct ts_lib_version_data *ver = ts_libversion();

	printf("                 _       _ _ _\n");
	printf("                | |_ ___| (_) |__\n");
	printf("                | __/ __| | | '_ \\\n");
	printf("                | |_\\__ \\ | | |_) |\n");
	printf("                 \\__|___/_|_|_.__/\n\n");
	printf("tslib %s / libts ABI version %d (0x%06X)\n",
		ver->package_version, ver->version_num >> 16, ver->version_num);
	printf("\n");
	printf("Usage: %s [--raw] [--non-blocking] [-s samples] [-i <device>] [-j <slots>]\n", argv[0]);
}

static int errfn(const char *fmt, va_list ap)
{
	return vfprintf(stderr, fmt, ap);
}

static int openfn(const char *path, int flags,
		  void *user_data __attribute__((unused)))
{
	return open(path, flags);
}

int main(int argc, char **argv)
{
	struct tsdev *ts;
	char *tsdevice = NULL;
	struct ts_sample_mt **samp_mt = NULL;
#ifdef TS_HAVE_EVDEV
	struct input_absinfo slot;
#endif
	int32_t user_slots = 0;
	int32_t max_slots = 1;
	int ret, i, j;
	int read_samples = 1;
	short non_blocking = 0;
	short raw = 0;
	struct ts_lib_version_data *ver = ts_libversion();

#ifndef TSLIB_VERSION_MT /* < 1.10 */
	printf("You are running an old version of tslib. Please upgrade.\n");
#endif

	while (1) {
		const struct option long_options[] = {
			{ "help",         no_argument,       NULL, 'h' },
			{ "idev",         required_argument, NULL, 'i' },
			{ "samples",      required_argument, NULL, 's' },
			{ "non-blocking", no_argument,       NULL, 'n' },
			{ "raw",          no_argument,       NULL, 'r' },
			{ "slots",        required_argument, NULL, 'j' },
		};

		int option_index = 0;
		int c = getopt_long(argc, argv, "hi:s:nrj:", long_options, &option_index);

		errno = 0;
		if (c == -1)
			break;

		switch (c) {
		case 'h':
			usage(argv);
			return 0;

		case 'i':
			tsdevice = optarg;
			break;

		case 'n':
			non_blocking = 1;
			break;

		case 'r':
			raw = 1;
			break;

		case 's':
			read_samples = atoi(optarg);
			if (read_samples <= 0) {
				usage(argv);
				return 0;
			}
			break;

		case 'j':
			user_slots = atoi(optarg);
			if (user_slots <= 0) {
				usage(argv);
				return 0;
			}
			break;

		default:
			usage(argv);
			return 0;
		}

		if (errno) {
			char str[9];

			sprintf(str, "option ?");
			str[7] = c & 0xff;
			perror(str);
		}
	}

	ts_error_fn = errfn;

#ifdef TSLIB_VERSION_OPEN_RESTRICTED
	if (ver->features & TSLIB_VERSION_OPEN_RESTRICTED)
		ts_open_restricted = openfn;
#endif

	if (non_blocking)
		ts = ts_setup(tsdevice, 1);
	else
		ts = ts_setup(tsdevice, 0);

	if (!ts) {
		perror("ts_setup");
		return errno;
	}

	printf("libts %06X opened device %s\n",
	       ver->version_num, ts_get_eventpath(ts));

#ifdef TS_HAVE_EVDEV
	if (ioctl(ts_fd(ts), EVIOCGABS(ABS_MT_SLOT), &slot) < 0) {
		perror("ioctl EVIOGABS");
		ts_close(ts);
		return errno;
	}

	max_slots = slot.maximum + 1 - slot.minimum;
#endif
	if (user_slots > 0)
		max_slots = user_slots;

	samp_mt = malloc(read_samples * sizeof(struct ts_sample_mt *));
	if (!samp_mt) {
		ts_close(ts);
		return -ENOMEM;
	}
	for (i = 0; i < read_samples; i++) {
		samp_mt[i] = calloc(max_slots, sizeof(struct ts_sample_mt));
		if (!samp_mt[i]) {
			free(samp_mt);
			ts_close(ts);
			return -ENOMEM;
		}
	}

	while (1) {
		if (raw)
			ret = ts_read_raw_mt(ts, samp_mt, max_slots, read_samples);
		else
			ret = ts_read_mt(ts, samp_mt, max_slots, read_samples);

		if (ret < 0) {
			if (non_blocking) {
				printf("ts_print_mt: read returns %d\n", ret);
				continue;
			}

			perror("ts_read_mt");
			ts_close(ts);
			exit(1);
		}

		for (j = 0; j < ret; j++) {
			for (i = 0; i < max_slots; i++) {
				if (!(samp_mt[j][i].valid & TSLIB_MT_VALID))
					continue;

				printf(YELLOW "sample %d - %ld.%06ld -" RESET " (slot %d) %6d %6d %6d\n",
				       j,
				       samp_mt[j][i].tv.tv_sec,
				       samp_mt[j][i].tv.tv_usec,
				       samp_mt[j][i].slot,
				       samp_mt[j][i].x,
				       samp_mt[j][i].y,
				       samp_mt[j][i].pressure);
			}
		}
	}

	ts_close(ts);
}


<|start_filename|>3rdpart/ethercat-1.5.2/examples/tty/serial.c<|end_filename|>
/******************************************************************************
 *
 *  $Id: serial.c,v bc2d4bf9cbe5 2012/09/06 18:22:24 fp $
 *
 *  Copyright (C) 2006-2008  <NAME>, Ingenieurgemeinschaft IgH
 *
 *  This file is part of the IgH EtherCAT Master.
 *
 *  The IgH EtherCAT Master is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License version 2, as
 *  published by the Free Software Foundation.
 *
 *  The IgH EtherCAT Master is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 *  Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with the IgH EtherCAT Master; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  ---
 *
 *  The license mentioned above concerns the source code only. Using the
 *  EtherCAT technology and brand is only permitted in compliance with the
 *  industrial property and similar rights of Beckhoff Automation GmbH.
 *
 *****************************************************************************/

#include <linux/module.h>
#include <linux/err.h>
#include <linux/termios.h>
#include <linux/slab.h>

#include "../../include/ecrt.h" // EtherCAT realtime interface
#include "../../include/ectty.h" // EtherCAT TTY interface

/*****************************************************************************/

// Optional features
#define PFX "ec_tty_example: "

#define DEBUG 0

/*****************************************************************************/

#define VendorIdBeckhoff 0x00000002
#define ProductCodeBeckhoffEL6002 0x17723052

#define VendorIdIds 0x000012ad
#define ProductCodeIdsCSI71A 0x17723052

/*****************************************************************************/

typedef enum {
    SER_REQUEST_INIT,
    SER_WAIT_FOR_INIT_RESPONSE,
    SER_READY,
    SER_SET_RTSCTS,
    SER_SET_BAUD_RATE,
    SER_SET_DATA_FRAME,
} el60xx_port_state;

#define EL6002_PORT_NAME_SIZE 16

typedef struct {
    ec_tty_t *tty;
    char name[EL6002_PORT_NAME_SIZE];

    size_t max_tx_data_size;
    size_t max_rx_data_size;

    u8 *tx_data;
    u8 tx_data_size;

    el60xx_port_state state;

    u8 tx_request_toggle;
    u8 tx_accepted_toggle;

    u8 rx_request_toggle;
    u8 rx_accepted_toggle;

    u16 control;

    u32 off_ctrl;
    u32 off_tx;
    u32 off_status;
    u32 off_rx;

    ec_sdo_request_t *rtscts_sdo;
    u8 requested_rtscts;
    u8 current_rtscts;

    ec_sdo_request_t *baud_sdo;
    u8 requested_baud_rate;
    u8 current_baud_rate;

    ec_sdo_request_t *frame_sdo;
    u8 requested_data_frame;
    u8 current_data_frame;

    unsigned int config_error;

} el60xx_port_t;

#define EL6002_PORTS 2

typedef struct {
    struct list_head list;
    ec_slave_config_t *sc;
    el60xx_port_t port[EL6002_PORTS];
} el6002_t;

LIST_HEAD(handlers);

/*****************************************************************************/

/* Beckhoff EL6002
 * Vendor ID:       0x00000002
 * Product code:    0x17723052
 * Revision number: 0x00100000
 */

ec_pdo_entry_info_t el6002_pdo_entries[] = {
   {0x7001, 0x01, 16}, /* Ctrl */
   {0x7000, 0x11, 8}, /* Data Out 0 */
   {0x7000, 0x12, 8}, /* Data Out 1 */
   {0x7000, 0x13, 8}, /* Data Out 2 */
   {0x7000, 0x14, 8}, /* Data Out 3 */
   {0x7000, 0x15, 8}, /* Data Out 4 */
   {0x7000, 0x16, 8}, /* Data Out 5 */
   {0x7000, 0x17, 8}, /* Data Out 6 */
   {0x7000, 0x18, 8}, /* Data Out 7 */
   {0x7000, 0x19, 8}, /* Data Out 8 */
   {0x7000, 0x1a, 8}, /* Data Out 9 */
   {0x7000, 0x1b, 8}, /* Data Out 10 */
   {0x7000, 0x1c, 8}, /* Data Out 11 */
   {0x7000, 0x1d, 8}, /* Data Out 12 */
   {0x7000, 0x1e, 8}, /* Data Out 13 */
   {0x7000, 0x1f, 8}, /* Data Out 14 */
   {0x7000, 0x20, 8}, /* Data Out 15 */
   {0x7000, 0x21, 8}, /* Data Out 16 */
   {0x7000, 0x22, 8}, /* Data Out 17 */
   {0x7000, 0x23, 8}, /* Data Out 18 */
   {0x7000, 0x24, 8}, /* Data Out 19 */
   {0x7000, 0x25, 8}, /* Data Out 20 */
   {0x7000, 0x26, 8}, /* Data Out 21 */
   {0x7011, 0x01, 16}, /* Ctrl */
   {0x7010, 0x11, 8}, /* Data Out 0 */
   {0x7010, 0x12, 8}, /* Data Out 1 */
   {0x7010, 0x13, 8}, /* Data Out 2 */
   {0x7010, 0x14, 8}, /* Data Out 3 */
   {0x7010, 0x15, 8}, /* Data Out 4 */
   {0x7010, 0x16, 8}, /* Data Out 5 */
   {0x7010, 0x17, 8}, /* Data Out 6 */
   {0x7010, 0x18, 8}, /* Data Out 7 */
   {0x7010, 0x19, 8}, /* Data Out 8 */
   {0x7010, 0x1a, 8}, /* Data Out 9 */
   {0x7010, 0x1b, 8}, /* Data Out 10 */
   {0x7010, 0x1c, 8}, /* Data Out 11 */
   {0x7010, 0x1d, 8}, /* Data Out 12 */
   {0x7010, 0x1e, 8}, /* Data Out 13 */
   {0x7010, 0x1f, 8}, /* Data Out 14 */
   {0x7010, 0x20, 8}, /* Data Out 15 */
   {0x7010, 0x21, 8}, /* Data Out 16 */
   {0x7010, 0x22, 8}, /* Data Out 17 */
   {0x7010, 0x23, 8}, /* Data Out 18 */
   {0x7010, 0x24, 8}, /* Data Out 19 */
   {0x7010, 0x25, 8}, /* Data Out 20 */
   {0x7010, 0x26, 8}, /* Data Out 21 */
   {0x6001, 0x01, 16}, /* Status */
   {0x6000, 0x11, 8}, /* Data In 0 */
   {0x6000, 0x12, 8}, /* Data In 1 */
   {0x6000, 0x13, 8}, /* Data In 2 */
   {0x6000, 0x14, 8}, /* Data In 3 */
   {0x6000, 0x15, 8}, /* Data In 4 */
   {0x6000, 0x16, 8}, /* Data In 5 */
   {0x6000, 0x17, 8}, /* Data In 6 */
   {0x6000, 0x18, 8}, /* Data In 7 */
   {0x6000, 0x19, 8}, /* Data In 8 */
   {0x6000, 0x1a, 8}, /* Data In 9 */
   {0x6000, 0x1b, 8}, /* Data In 10 */
   {0x6000, 0x1c, 8}, /* Data In 11 */
   {0x6000, 0x1d, 8}, /* Data In 12 */
   {0x6000, 0x1e, 8}, /* Data In 13 */
   {0x6000, 0x1f, 8}, /* Data In 14 */
   {0x6000, 0x20, 8}, /* Data In 15 */
   {0x6000, 0x21, 8}, /* Data In 16 */
   {0x6000, 0x22, 8}, /* Data In 17 */
   {0x6000, 0x23, 8}, /* Data In 18 */
   {0x6000, 0x24, 8}, /* Data In 19 */
   {0x6000, 0x25, 8}, /* Data In 20 */
   {0x6000, 0x26, 8}, /* Data In 21 */
   {0x6011, 0x01, 16}, /* Status */
   {0x6010, 0x11, 8}, /* Data In 0 */
   {0x6010, 0x12, 8}, /* Data In 1 */
   {0x6010, 0x13, 8}, /* Data In 2 */
   {0x6010, 0x14, 8}, /* Data In 3 */
   {0x6010, 0x15, 8}, /* Data In 4 */
   {0x6010, 0x16, 8}, /* Data In 5 */
   {0x6010, 0x17, 8}, /* Data In 6 */
   {0x6010, 0x18, 8}, /* Data In 7 */
   {0x6010, 0x19, 8}, /* Data In 8 */
   {0x6010, 0x1a, 8}, /* Data In 9 */
   {0x6010, 0x1b, 8}, /* Data In 10 */
   {0x6010, 0x1c, 8}, /* Data In 11 */
   {0x6010, 0x1d, 8}, /* Data In 12 */
   {0x6010, 0x1e, 8}, /* Data In 13 */
   {0x6010, 0x1f, 8}, /* Data In 14 */
   {0x6010, 0x20, 8}, /* Data In 15 */
   {0x6010, 0x21, 8}, /* Data In 16 */
   {0x6010, 0x22, 8}, /* Data In 17 */
   {0x6010, 0x23, 8}, /* Data In 18 */
   {0x6010, 0x24, 8}, /* Data In 19 */
   {0x6010, 0x25, 8}, /* Data In 20 */
   {0x6010, 0x26, 8}, /* Data In 21 */
};

ec_pdo_info_t el6002_pdos[] = {
   {0x1604, 23, el6002_pdo_entries + 0}, /* COM RxPDO-Map Outputs Ch.1 */
   {0x1605, 23, el6002_pdo_entries + 23}, /* COM RxPDO-Map Outputs Ch.2 */
   {0x1a04, 23, el6002_pdo_entries + 46}, /* COM TxPDO-Map Inputs Ch.1 */
   {0x1a05, 23, el6002_pdo_entries + 69}, /* COM TxPDO-Map Inputs Ch.2 */
};

ec_sync_info_t el6002_syncs[] = {
   {0, EC_DIR_OUTPUT, 0, NULL, EC_WD_DISABLE},
   {1, EC_DIR_INPUT, 0, NULL, EC_WD_DISABLE},
   {2, EC_DIR_OUTPUT, 2, el6002_pdos + 0, EC_WD_DISABLE},
   {3, EC_DIR_INPUT, 2, el6002_pdos + 2, EC_WD_DISABLE},
   {0xff}
};

typedef enum {
    PAR_NONE,
    PAR_ODD,
    PAR_EVEN
} parity_t;

typedef struct {
    u8 value;
    unsigned int data_bits;
    parity_t parity;
    unsigned int stop_bits;
} el600x_data_frame_t;

/** EL600x supported values for data frame SDO.
 */
el600x_data_frame_t el600x_data_frame[] = {
    {0x01, 7, PAR_EVEN, 1},
    {0x09, 7, PAR_EVEN, 2},
    {0x02, 7, PAR_ODD,  1},
    {0x0a, 7, PAR_ODD,  2},
    {0x03, 8, PAR_NONE, 1},
    {0x0b, 8, PAR_NONE, 2},
    {0x04, 8, PAR_EVEN, 1},
    {0x0c, 8, PAR_EVEN, 2},
    {0x05, 8, PAR_ODD,  1},
    {0x0d, 8, PAR_ODD,  2},
};

typedef struct {
    u8 value;
    unsigned int baud;
    tcflag_t cbaud;
} el600x_baud_rate_t;

/** EL600x supported values for baud rate SDO.
 */
el600x_baud_rate_t el600x_baud_rate[] = {
    {1,   300,    B300},
    {2,   600,    B600},
    {3,   1200,   B1200},
    {4,   2400,   B2400},
    {5,   4800,   B4800},
    {6,   9600,   B9600},
    {7,   19200,  B19200},
    {8,   38400,  B38400},
    {9,   57600,  B57600},
    {10,  115200, B115200}
};

/****************************************************************************/

int el60xx_cflag_changed(void *data, tcflag_t cflag)
{
    el60xx_port_t *port = (el60xx_port_t *) data;
    unsigned int data_bits, stop_bits;
    tcflag_t cbaud, rtscts;
    parity_t par;
    unsigned int i;
    el600x_baud_rate_t *b_to_use = NULL;
    el600x_data_frame_t *df_to_use = NULL;

#if DEBUG
    printk(KERN_INFO PFX "%s(%s, cflag=%x).\n", __func__, port->name, cflag);
#endif

    rtscts = cflag & CRTSCTS;
    printk(KERN_INFO PFX "%s: Requested RTS/CTS: %s.\n",
            port->name, rtscts ? "yes" : "no");

    cbaud = cflag & CBAUD;

    for (i = 0; i < sizeof(el600x_baud_rate) / sizeof(el600x_baud_rate_t);
            i++) {
        el600x_baud_rate_t *b = el600x_baud_rate + i;
        if (b->cbaud == cbaud) {
            b_to_use = b;
            break;
        }
    }

    if (b_to_use) {
        printk(KERN_INFO PFX "%s: Requested baud rate: %u.\n",
                port->name, b_to_use->baud);
    } else {
        printk(KERN_ERR PFX "Error: %s does not support"
                " baud rate index %x.\n", port->name, cbaud);
        return -EINVAL;
    }

    switch (cflag & CSIZE) {
        case CS5:
            data_bits = 5;
            break;
        case CS6:
            data_bits = 6;
            break;
        case CS7:
            data_bits = 7;
            break;
        case CS8:
            data_bits = 8;
            break;
        default: /* CS5 or CS6 */
            data_bits = 0;
    }

    if (cflag & PARENB) {
        par = (cflag & PARODD) ? PAR_ODD : PAR_EVEN;
    } else {
        par = PAR_NONE;
    }

    stop_bits = (cflag & CSTOPB) ? 2 : 1;

    printk(KERN_INFO PFX "%s: Requested Data frame: %u%c%u.\n",
            port->name, data_bits,
            (par == PAR_NONE ? 'N' : (par == PAR_ODD ? 'O' : 'E')),
            stop_bits);

    for (i = 0; i < sizeof(el600x_data_frame) / sizeof(el600x_data_frame_t);
            i++) {
        el600x_data_frame_t *df = el600x_data_frame + i;
        if (df->data_bits == data_bits &&
                df->parity == par &&
                df->stop_bits == stop_bits) {
            df_to_use = df;
            break;
        }
    }

    if (!df_to_use) {
        printk(KERN_ERR PFX "Error: %s does not support data frame type.\n",
                port->name);
        return -EINVAL;
    }

    port->requested_rtscts = rtscts != 0;
    port->requested_baud_rate = b_to_use->value;
    port->requested_data_frame = df_to_use->value;
    port->config_error = 0;
    return 0;
}

/****************************************************************************/

static ec_tty_operations_t el60xx_tty_ops = {
    .cflag_changed = el60xx_cflag_changed,
};

/****************************************************************************/

int el60xx_port_init(el60xx_port_t *port, ec_slave_config_t *sc,
        ec_domain_t *domain, unsigned int slot_offset, const char *name)
{
    int ret = 0;

    strncpy(port->name, name, EL6002_PORT_NAME_SIZE);

    port->tty = ectty_create(&el60xx_tty_ops, port);
    if (IS_ERR(port->tty)) {
        printk(KERN_ERR PFX "Failed to create tty for %s.\n",
                port->name);
        ret = PTR_ERR(port->tty);
        goto out_return;
    }

    port->max_tx_data_size = 22;
    port->max_rx_data_size = 22;
    port->tx_data = NULL;
    port->tx_data_size = 0;
    port->state = SER_REQUEST_INIT;
    port->tx_request_toggle = 0;
    port->rx_accepted_toggle = 0;
    port->control = 0x0000;
    port->off_ctrl = 0;
    port->off_tx = 0;
    port->off_status = 0;
    port->off_rx = 0;
    port->requested_rtscts = 0x00; // no hardware handshake
    port->current_rtscts = 0xff;
    port->requested_baud_rate = 6; // 9600
    port->current_baud_rate = 0;
    port->requested_data_frame = 0x03; // 8N1
    port->current_data_frame = 0x00;
    port->config_error = 0;

    if (!(port->rtscts_sdo = ecrt_slave_config_create_sdo_request(sc,
                    0x8000 + slot_offset, 0x01, 1))) {
        printk(KERN_ERR PFX "Failed to create SDO request for %s.\n",
                port->name);
        ret = -ENOMEM;
        goto out_free_tty;
    }

    if (!(port->baud_sdo = ecrt_slave_config_create_sdo_request(sc,
                    0x8000 + slot_offset, 0x11, 1))) {
        printk(KERN_ERR PFX "Failed to create SDO request for %s.\n",
                port->name);
        ret = -ENOMEM;
        goto out_free_tty;
    }

    if (!(port->frame_sdo = ecrt_slave_config_create_sdo_request(sc,
                    0x8000 + slot_offset, 0x15, 1))) {
        printk(KERN_ERR PFX "Failed to create SDO request for %s\n",
                port->name);
        ret = -ENOMEM;
        goto out_free_tty;
    }

    ret = ecrt_slave_config_reg_pdo_entry(
            sc, 0x7001 + slot_offset, 0x01, domain, NULL);
    if (ret < 0) {
        printk(KERN_ERR PFX "Failed to register PDO entry of %s\n",
                port->name);
        goto out_free_tty;
    }
    port->off_ctrl = ret;

    ret = ecrt_slave_config_reg_pdo_entry(
            sc, 0x7000 + slot_offset, 0x11, domain, NULL);
    if (ret < 0) {
        printk(KERN_ERR PFX "Failed to register PDO entry of %s.\n",
                port->name);
        goto out_free_tty;
    }
    port->off_tx = ret;

    ret = ecrt_slave_config_reg_pdo_entry(
            sc, 0x6001 + slot_offset, 0x01, domain, NULL);
    if (ret < 0) {
        printk(KERN_ERR PFX "Failed to register PDO entry of %s.\n",
                port->name);
        goto out_free_tty;
    }
    port->off_status = ret;

    ret = ecrt_slave_config_reg_pdo_entry(
            sc, 0x6000 + slot_offset, 0x11, domain, NULL);
    if (ret < 0) {
        printk(KERN_ERR PFX "Failed to register PDO entry of %s.\n",
                port->name);
        goto out_free_tty;
    }
    port->off_rx = ret;

    if (port->max_tx_data_size > 0) {
        port->tx_data = kmalloc(port->max_tx_data_size, GFP_KERNEL);
        if (port->tx_data == NULL) {
            printk(KERN_ERR PFX "Failed to allocate %u bytes of TX"
                    " memory for %s.\n", port->max_tx_data_size, port->name);
            ret = -ENOMEM;
            goto out_free_tty;
        }
    }

    return 0;

out_free_tty:
    ectty_free(port->tty);
out_return:
    return ret;
}

/****************************************************************************/

void el60xx_port_clear(el60xx_port_t *port)
{
    ectty_free(port->tty);
    if (port->tx_data) {
        kfree(port->tx_data);
    }
}

/****************************************************************************/

void el60xx_port_run(el60xx_port_t *port, u8 *pd)
{
    u16 status = EC_READ_U16(pd + port->off_status);
    u8 *rx_data = pd + port->off_rx;
    uint8_t tx_accepted_toggle, rx_request_toggle;

    switch (port->state) {
        case SER_READY:

            /* Check, if hardware handshaking has to be configured. */
            if (!port->config_error &&
                    port->requested_rtscts != port->current_rtscts) {
                EC_WRITE_U8(ecrt_sdo_request_data(port->rtscts_sdo),
                        port->requested_rtscts);
                ecrt_sdo_request_write(port->rtscts_sdo);
                port->state = SER_SET_RTSCTS;
                break;
            }

            /* Check, if the baud rate has to be configured. */
            if (!port->config_error &&
                    port->requested_baud_rate != port->current_baud_rate) {
                EC_WRITE_U8(ecrt_sdo_request_data(port->baud_sdo),
                        port->requested_baud_rate);
                ecrt_sdo_request_write(port->baud_sdo);
                port->state = SER_SET_BAUD_RATE;
                break;
            }

            /* Check, if the data frame has to be configured. */
            if (!port->config_error &&
                    port->requested_data_frame != port->current_data_frame) {
                EC_WRITE_U8(ecrt_sdo_request_data(port->frame_sdo),
                        port->requested_data_frame);
                ecrt_sdo_request_write(port->frame_sdo);
                port->state = SER_SET_DATA_FRAME;
                break;
            }

            /* Send data */

            tx_accepted_toggle = status & 0x0001;
            if (tx_accepted_toggle != port->tx_accepted_toggle) { // ready
                port->tx_data_size =
                    ectty_tx_data(port->tty, port->tx_data, port->max_tx_data_size);
                if (port->tx_data_size) {
#if DEBUG
                    printk(KERN_INFO PFX "%s: Sending %u bytes.\n",
                            port->name, port->tx_data_size);
#endif
                    port->tx_request_toggle = !port->tx_request_toggle;
                    port->tx_accepted_toggle = tx_accepted_toggle;
                }
            }

            /* Receive data */

            rx_request_toggle = status & 0x0002;
            if (rx_request_toggle != port->rx_request_toggle) {
                uint8_t rx_data_size = status >> 8;
                port->rx_request_toggle = rx_request_toggle;
#if DEBUG
                printk(KERN_INFO PFX "%s: Received %u bytes.\n",
                        port->name, rx_data_size);
#endif
                ectty_rx_data(port->tty, rx_data, rx_data_size);
                port->rx_accepted_toggle = !port->rx_accepted_toggle;
            }

            port->control =
                port->tx_request_toggle |
                port->rx_accepted_toggle << 1 |
                port->tx_data_size << 8;
            break;

        case SER_REQUEST_INIT:
            if (status & (1 << 2)) {
                port->control = 0x0000;
                port->state = SER_WAIT_FOR_INIT_RESPONSE;
            } else {
                port->control = 1 << 2; // CW.2, request initialization
            }
            break;

        case SER_WAIT_FOR_INIT_RESPONSE:
            if (!(status & (1 << 2))) {
                printk(KERN_INFO PFX "%s: Init successful.\n", port->name);
                port->tx_accepted_toggle = 1;
                port->control = 0x0000;
                port->state = SER_READY;
            }
            break;

        case SER_SET_RTSCTS:
            switch (ecrt_sdo_request_state(port->rtscts_sdo)) {
                case EC_REQUEST_SUCCESS:
                    printk(KERN_INFO PFX "%s: Accepted RTS/CTS.\n",
                            port->name);
                    port->current_rtscts = port->requested_rtscts;
                    port->state = SER_REQUEST_INIT;
                    break;
                case EC_REQUEST_ERROR:
                    printk(KERN_ERR PFX "Failed to set RTS/CTS on %s!\n",
                            port->name);
                    port->state = SER_REQUEST_INIT;
                    port->config_error = 1;
                    break;
                default:
                    break;
            }
            break;

        case SER_SET_BAUD_RATE:
            switch (ecrt_sdo_request_state(port->baud_sdo)) {
                case EC_REQUEST_SUCCESS:
                    printk(KERN_INFO PFX "%s: Accepted baud rate.\n",
                            port->name);
                    port->current_baud_rate = port->requested_baud_rate;
                    port->state = SER_REQUEST_INIT;
                    break;
                case EC_REQUEST_ERROR:
                    printk(KERN_ERR PFX "Failed to set baud rate on %s!\n",
                            port->name);
                    port->state = SER_REQUEST_INIT;
                    port->config_error = 1;
                    break;
                default:
                    break;
            }
            break;

        case SER_SET_DATA_FRAME:
            switch (ecrt_sdo_request_state(port->frame_sdo)) {
                case EC_REQUEST_SUCCESS:
                    printk(KERN_INFO PFX "%s: Accepted data frame.\n",
                            port->name);
                    port->current_data_frame = port->requested_data_frame;
                    port->state = SER_REQUEST_INIT;
                    break;
                case EC_REQUEST_ERROR:
                    printk(KERN_ERR PFX "Failed to set data frame on %s!\n",
                            port->name);
                    port->state = SER_REQUEST_INIT;
                    port->config_error = 1;
                    break;
                default:
                    break;
            }
            break;
    }

    EC_WRITE_U16(pd + port->off_ctrl, port->control);
    memcpy(pd + port->off_tx, port->tx_data, port->tx_data_size);
}

/****************************************************************************/

int el6002_init(el6002_t *el6002, ec_master_t *master, u16 position,
        ec_domain_t *domain, u32 vendor, u32 product)
{
    int ret = 0, i;

    if (!(el6002->sc = ecrt_master_slave_config(
                    master, 0, position, vendor, product))) {
        printk(KERN_ERR PFX "EL6002(%u): Failed to create"
                " slave configuration.\n", position);
        ret = -EBUSY;
        goto out_return;
    }

    if (ecrt_slave_config_pdos(el6002->sc, EC_END, el6002_syncs)) {
        printk(KERN_ERR PFX "EL6002(%u): Failed to configure PDOs.\n",
                position);
        ret = -ENOMEM;
        goto out_return;
    }

    for (i = 0; i < EL6002_PORTS; i++) {
        char name[EL6002_PORT_NAME_SIZE];
        snprintf(name, EL6002_PORT_NAME_SIZE, "EL6002(%u) X%u",
                position, i + 1);
        if (el60xx_port_init(el6002->port + i, el6002->sc, domain, i * 0x10,
                    name)) {
            printk(KERN_ERR PFX "EL6002(%u): Failed to init port X%u.\n",
                    position, i);
            goto out_ports;
        }
    }

    return 0;

out_ports:
    for (i--; i >= 0; i--) {
        el60xx_port_clear(el6002->port + i);
    }
out_return:
    return ret;
}

/****************************************************************************/

void el6002_clear(el6002_t *el6002)
{
    int i;

    for (i = 0; i < EL6002_PORTS; i++) {
        el60xx_port_clear(el6002->port + i);
    }
}

/****************************************************************************/

void el6002_run(el6002_t *el6002, u8 *pd)
{
    int i;

    for (i = 0; i < EL6002_PORTS; i++) {
        el60xx_port_run(el6002->port + i, pd);
    }
}

/*****************************************************************************/

void run_serial_devices(u8 *pd)
{
    el6002_t *el6002;

    list_for_each_entry(el6002, &handlers, list) {
        el6002_run(el6002, pd);
    }
}

/*****************************************************************************/

int create_el6002_handler(ec_master_t *master, ec_domain_t *domain,
        u16 position, u32 vendor, u32 product)
{
    el6002_t *el6002;
    int ret;

    printk(KERN_INFO PFX "Creating handler for EL6002 at position %u\n",
            position);

    el6002 = kmalloc(sizeof(*el6002), GFP_KERNEL);
    if (!el6002) {
        printk(KERN_ERR PFX "Failed to allocate serial device object.\n");
        return -ENOMEM;
    }

    ret = el6002_init(el6002, master, position, domain, vendor, product);
    if (ret) {
        kfree(el6002);
        return ret;
    }

    list_add_tail(&el6002->list, &handlers);
    return 0;
}

/*****************************************************************************/

int create_serial_devices(ec_master_t *master, ec_domain_t *domain)
{
    int i, ret;
    ec_master_info_t master_info;
    ec_slave_info_t slave_info;
    el6002_t *ser, *next;

    printk(KERN_INFO PFX "Registering serial devices...\n");

    ret = ecrt_master(master, &master_info);
    if (ret) {
        printk(KERN_ERR PFX "Failed to obtain master information.\n");
        goto out_return;
    }

    for (i = 0; i < master_info.slave_count; i++) {
        ret = ecrt_master_get_slave(master, i, &slave_info);
        if (ret) {
            printk(KERN_ERR PFX "Failed to obtain slave information.\n");
            goto out_free_handlers;
        }

        if (slave_info.vendor_id == VendorIdBeckhoff
                && slave_info.product_code == ProductCodeBeckhoffEL6002) {
            if (create_el6002_handler(master, domain, i,
                    slave_info.vendor_id, slave_info.product_code)) {
                goto out_free_handlers;
            }
        }

        if (slave_info.vendor_id == VendorIdIds
                && slave_info.product_code == ProductCodeIdsCSI71A) {
            if (create_el6002_handler(master, domain, i,
                    slave_info.vendor_id, slave_info.product_code)) {
                goto out_free_handlers;
            }
        }
    }

    printk(KERN_INFO PFX "Finished registering serial devices.\n");
    return 0;

out_free_handlers:
    list_for_each_entry_safe(ser, next, &handlers, list) {
        list_del(&ser->list);
        el6002_clear(ser);
        kfree(ser);
    }
out_return:
    return ret;
}

/*****************************************************************************/

void free_serial_devices(void)
{
    el6002_t *ser, *next;

    printk(KERN_INFO PFX "Cleaning up serial devices...\n");

    list_for_each_entry_safe(ser, next, &handlers, list) {
        list_del(&ser->list);
        el6002_clear(ser);
        kfree(ser);
    }

    printk(KERN_INFO PFX "Finished cleaning up serial devices.\n");
}

/*****************************************************************************/


<|start_filename|>apps/ecat-master/main/ecat.c<|end_filename|>
/*
 * ecat.c
 *
 *  Created on: Mar 12, 2018
 *      Author: morris
 */
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <unistd.h>
#include <time.h>
#include <pthread.h>
#include <sys/mman.h>
#include <sys/resource.h>
#include "ecat.h"
#include "ecrt.h"

static bool thread_running = true;
/* 互斥锁 */
static pthread_mutex_t mutex;

/* master对象，管理从站，域,IO */
static ec_master_t *master = NULL;
/* master对象的状态 */
static ec_master_state_t master_state = { };

/* 域，管理一组从站的过程数据 */
static ec_domain_t *domain = NULL;
/* 域的状态 */
static ec_domain_state_t domain_state = { };
/* 指向某个域的过程数据 */
static uint8_t *domain_pd = NULL;

static void (*user_work)(void*) = NULL;

/* 过程数据对象中的具体数据的偏移地址 */
static unsigned int off_sensors_in0;
static unsigned int off_leds_out0;
static unsigned int off_sensors_in1;
static unsigned int off_leds_out1;

/* 本地的秒计数器 */
static unsigned int counter = 0;

/* 计数器,用于同步到参考时钟 */
static unsigned int sync_ref_counter = 0;

/* 周期时间 */
const struct timespec cycletime = { 0, PERIOD_NS };

/* 用户数据 */
static ecat_user user_data = { .blink0 = 0, .blink1 = 0, .sensor_temp0 = 0,
		.sensor_temp1 = 0 };

/* 过程数据对象的配置信息，具体到每一条目，可以通过在主站使用命令查看：ethercat cstruct */
/* Master 0, Slave 0
 * Vendor ID:       0x0000034e
 * Product code:    0x12345678
 * Revision number: 0x00000001
 */
static ec_pdo_entry_info_t xmc_pdo_entries[] = {
/* {条目主索引, 条目子索引, 条目大小：单位bit} */
{ 0x7000, 0x01, 1 }, /* LED1 */
{ 0x7000, 0x02, 1 }, /* LED2 */
{ 0x7000, 0x03, 1 }, /* LED3 */
{ 0x7000, 0x04, 1 }, /* LED4 */
{ 0x7000, 0x05, 1 }, /* LED5 */
{ 0x7000, 0x06, 1 }, /* LED6 */
{ 0x7000, 0x07, 1 }, /* LED7 */
{ 0x7000, 0x08, 1 }, /* LED8 */
{ 0x6000, 0x01, 16 }, /* Sensor1 */
};

/* 过程数据对象的配置信息，可以通过在主站使用命令查看：ethercat pdos */
static ec_pdo_info_t xmc_pdos[] = {
/* 过程数据对象的索引, 条目数量, 条目数组 */
{ 0x1600, 8, xmc_pdo_entries + 0 }, /* 代表LED过程数据的映射 */
{ 0x1a00, 1, xmc_pdo_entries + 8 }, /* 代表传感器过程数据的映射 */
};

/* 同步管理单元的配置信息 */
static ec_sync_info_t xmc_syncs[] = {
/* 索引号, 方向, PDO数量, PDO数组, 看门狗模式 */
{ 0, EC_DIR_OUTPUT, 0, NULL, EC_WD_DISABLE }, { 1, EC_DIR_INPUT, 0, NULL,
		EC_WD_DISABLE }, { 2, EC_DIR_OUTPUT, 1, xmc_pdos + 0, EC_WD_ENABLE }, {
		3, EC_DIR_INPUT, 1, xmc_pdos + 1, EC_WD_DISABLE }, { 0xff } };

/* 高精度时间相加函数 */
static inline struct timespec timespec_add(struct timespec time1,
		struct timespec time2) {
	struct timespec result;

	if ((time1.tv_nsec + time2.tv_nsec) >= NSEC_PER_SEC) {
		result.tv_sec = time1.tv_sec + time2.tv_sec + 1;
		result.tv_nsec = time1.tv_nsec + time2.tv_nsec - NSEC_PER_SEC;
	} else {
		result.tv_sec = time1.tv_sec + time2.tv_sec;
		result.tv_nsec = time1.tv_nsec + time2.tv_nsec;
	}

	return result;
}

/* 检查域的状态 */
static void check_domain_state(void) {
	ec_domain_state_t ds;

	/* 读取域的状态，能够实时监控到过程数据的交换 */
	ecrt_domain_state(domain, &ds);
	/* 工作计数器是否有改变 */
	if (ds.working_counter != domain_state.working_counter) {
		printf("domain: WC->%u\n", ds.working_counter);
	}
	/* 解释当前的工作状态 */
	if (ds.wc_state != domain_state.wc_state) {
		printf("domain: State->%u\n", ds.wc_state);
	}
	/* 更新状态值 */
	domain_state = ds;
}

/* 检查master对象的状态 */
static void check_master_state(void) {
	ec_master_state_t ms;
	/* 获取当前master的状态 */
	ecrt_master_state(master, &ms);
	/* 检查从站数量是否有变化 */
	if (ms.slaves_responding != master_state.slaves_responding) {
		printf("master: %u slave(s)\n", ms.slaves_responding);
	}
	/* 应用层协议状态 */
	if (ms.al_states != master_state.al_states) {
		printf("master: AL states->%s\n",
				ms.al_states & 0x8 ? "OP" : ms.al_states & 0x4 ? "SAFEOP" :
				ms.al_states & 0x2 ? "PREOP" : "INIT");
	}
	/* 检查是否至少有一个链路已经起来 */
	if (ms.link_up != master_state.link_up) {
		printf("master: Link is %s\n", ms.link_up ? "up" : "down");
	}
	/* 更新状态值 */
	master_state = ms;
}

static void* cyclic_task(void* arg) {
	struct timespec wakeupTime, time;
#ifdef MEASURE_TIMING
	struct timespec startTime, endTime, lastStartTime = { };
	uint32_t period_ns = 0, exec_ns = 0, latency_ns = 0, latency_min_ns = 0,
			latency_max_ns = 0, period_min_ns = 0, period_max_ns = 0,
			exec_min_ns = 0, exec_max_ns = 0;
#endif

	/* 获取当前时间 */
	clock_gettime(CLOCK_TO_USE, &wakeupTime);
	pthread_mutex_lock(&mutex);
	while (thread_running) {
		pthread_mutex_unlock(&mutex);
		/* 更新理论上的唤醒时间 */
		wakeupTime = timespec_add(wakeupTime, cycletime);
		/* 高精度睡眠函数 */
		clock_nanosleep(CLOCK_TO_USE, TIMER_ABSTIME, &wakeupTime, NULL);

#ifdef MEASURE_TIMING
		/* 更新实际的唤醒时间 */
		clock_gettime(CLOCK_TO_USE, &startTime);
		/* latency_ns=startTime-wakeupTime */
		latency_ns = DIFF_NS(wakeupTime, startTime);
		/* period_ns=startTime-lastStartTime */
		period_ns = DIFF_NS(lastStartTime, startTime);
		/* exec_ns=endTime-lastStartTime */
		exec_ns = DIFF_NS(lastStartTime, endTime);
		/* 更新lastStartTime */
		lastStartTime = startTime;

		if (latency_ns > latency_max_ns) {
			latency_max_ns = latency_ns;
		}
		if (latency_ns < latency_min_ns) {
			latency_min_ns = latency_ns;
		}
		if (period_ns > period_max_ns) {
			period_max_ns = period_ns;
		}
		if (period_ns < period_min_ns) {
			period_min_ns = period_ns;
		}
		if (exec_ns > exec_max_ns) {
			exec_max_ns = exec_ns;
		}
		if (exec_ns < exec_min_ns) {
			exec_min_ns = exec_ns;
		}
#endif

		/* 从硬件获取数据帧 */
		ecrt_master_receive(master);
		/* 处理接收到的数据帧，解析工作计数器，域的工作状态  */
		ecrt_domain_process(domain);
		/* 检查当前域的工作状态 */
		check_domain_state();
		if (counter) {
			counter--;
		} else {
			/* 下面的任务一秒钟做10次 */
			counter = FREQUENCY / 10;
			/* 检查master的状态 */
			check_master_state();

#ifdef MEASURE_TIMING
			/* 打印时间测量结果 */
			printf("period %*u ... %*u\n", 8, period_min_ns, 10, period_max_ns);
			printf("exec %*u ... %*u\n", 10, exec_min_ns, 10, exec_max_ns);
			printf("latency %*u ... %*u\n", 7, latency_min_ns, 10,
					latency_max_ns);
			period_max_ns = 0;
			period_min_ns = 0xffffffff;
			exec_max_ns = 0;
			exec_min_ns = 0xffffffff;
			latency_max_ns = 0;
			latency_min_ns = 0xffffffff;
#endif
			/* 读取输入的过程数据 */
			user_data.sensor_temp0 = EC_READ_U16(domain_pd + off_sensors_in0);
			user_data.sensor_temp1 = EC_READ_U16(domain_pd + off_sensors_in1);
			user_work((void*) &user_data);
			/* 输出过程数据 */
			EC_WRITE_U8(domain_pd + off_leds_out0, user_data.blink0);
			EC_WRITE_U8(domain_pd + off_leds_out1, user_data.blink1);
		}

		clock_gettime(CLOCK_TO_USE, &time);
		/* 设置应用程序的时间(DC需要) */
		ecrt_master_application_time(master, TIMESPEC2NS(time));

		if (sync_ref_counter) {
			sync_ref_counter--;
		} else {
			/* 每两个周期同步一次 */
			sync_ref_counter = 1;
			/* 提交DC参考时钟偏移补偿报文(即修正DC参考用的时钟),这里的参考时钟同步于本地实时时钟 */
			ecrt_master_sync_reference_clock(master);
		}
		/* 提交DC时钟偏移补偿报文，DC时钟同步于DC参考时钟 */
		ecrt_master_sync_slave_clocks(master);

		/* 标记域中需要发送的数据包 */
		ecrt_domain_queue(domain);
		/* 发送数据包 */
		ecrt_master_send(master);

#ifdef MEASURE_TIMING
		clock_gettime(CLOCK_TO_USE, &endTime);
#endif
		pthread_mutex_lock(&mutex);
	}
	pthread_mutex_unlock(&mutex);
	/* 释放互斥锁内存 */
	pthread_mutex_destroy(&mutex);
	pthread_exit(arg);
}

int ecat_init(void (*work_callback)(void*)) {
	int ret;
	pthread_t thread_hdl;
	pthread_attr_t attr;
	/* 保存回调函数 */
	user_work = work_callback;

	/* 将进程使用的部分或者全部的地址空间锁定在物理内存中，防止其被交换到swap空间 */
	if (mlockall(MCL_CURRENT | MCL_FUTURE) == -1) {
		perror("mlockall failed");
		ret = -1;
		goto mlock_err;
	}
	/* 申请一个master对象 */
	master = ecrt_request_master(0);
	if (!master) {
		perror("ecrt_request_master failed");
		ret = -1;
		goto request_master_err;
	}
	/* 申请一个域来管理过程数据 */
	domain = ecrt_master_create_domain(master);
	if (!domain) {
		perror("create_domain failed");
		ret = -1;
		goto ecat_err;
	}
	printf("Configuring PDOs...\n");
	/* 获取指定从站的配置信息 */
	ec_slave_config_t* sc_xmc = ecrt_master_slave_config(master, XMC_Slave0Pos,
	Infineon_XMC4800);
	if (!sc_xmc) {
		perror("get slave configuration failed");
		ret = -1;
		goto ecat_err;
	}
	/* 初始化一个完整的PDO配置 */
	if (ecrt_slave_config_pdos(sc_xmc, EC_END, xmc_syncs)) {
		perror("config pdos failed");
		ret = -1;
		goto ecat_err;
	}
	/* 向域中注册PDO条目，这样才能实现过程数据的交换 */
	off_leds_out0 = ecrt_slave_config_reg_pdo_entry(sc_xmc, 0x7000, 1, domain,
	NULL);
	if (off_leds_out0 < 0) {
		perror("reg_pdo_entry_err failed");
		ret = -1;
		goto ecat_err;
	}
	off_sensors_in0 = ecrt_slave_config_reg_pdo_entry(sc_xmc, 0x6000, 1, domain,
	NULL);
	if (off_sensors_in0 < 0) {
		perror("reg_pdo_entry_err failed");
		ret = -1;
		goto ecat_err;
	}
	/* 配置分步式时钟，查阅从站描述文件Device->Dc->AssignActivate */
	ecrt_slave_config_dc(sc_xmc, 0x300, PERIOD_NS, 0, 0, 0);

	/* 获取指定从站的配置信息 */
	sc_xmc = ecrt_master_slave_config(master, XMC_Slave1Pos, Infineon_XMC4800);
	if (!sc_xmc) {
		perror("get slave configuration failed");
		ret = -1;
		goto ecat_err;
	}
	/* 初始化一个完整的PDO配置 */
	if (ecrt_slave_config_pdos(sc_xmc, EC_END, xmc_syncs)) {
		perror("config pdos failed");
		ret = -1;
		goto ecat_err;
	}
	/* 向域中注册PDO条目，这样才能实现过程数据的交换 */
	off_leds_out1 = ecrt_slave_config_reg_pdo_entry(sc_xmc, 0x7000, 1, domain,
	NULL);
	if (off_leds_out1 < 0) {
		perror("reg_pdo_entry_err failed");
		ret = -1;
		goto ecat_err;
	}
	off_sensors_in1 = ecrt_slave_config_reg_pdo_entry(sc_xmc, 0x6000, 1, domain,
	NULL);
	if (off_sensors_in1 < 0) {
		perror("reg_pdo_entry_err failed");
		ret = -1;
		goto ecat_err;
	}
	/* 配置分步式时钟，查阅从站描述文件Device->Dc->AssignActivate */
	ecrt_slave_config_dc(sc_xmc, 0x300, PERIOD_NS, 0, 0, 0);

	printf("Activating master...\n");
	/* 激活主站 */
	if (ecrt_master_activate(master)) {
		perror("master_activate failed");
		ret = -1;
		goto ecat_err;
	}
	/* 获取过程数据的映射地址 */
	if (!(domain_pd = ecrt_domain_data(domain))) {
		perror("get mapped domain data failed");
		ret = -1;
		goto ecat_err;
	}
	/* 设置本进程的优先执行权 */
	pid_t pid = getpid();
	if (setpriority(PRIO_PROCESS, pid, -19)) {
		perror("Failed to set priority");
	}

	/* 初始化互斥锁 */
	pthread_mutex_init(&mutex, NULL);
	/* 设置线程的分离属性 */
	pthread_attr_init(&attr);
	ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
	if (ret) {
		perror("pthread_attr_setdetachstate");
		goto err;
	}
	/* 设置线程的绑定属性 */
	ret = pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
	if (ret) {
		perror("pthread_attr_setscope");
		goto err;
	}
	/* 创建线程 */
	ret = pthread_create(&thread_hdl, &attr, cyclic_task, NULL);
	if (ret) {
		perror("pthread_create");
		goto err;
	}
	/* 释放线程属性对象 */
	pthread_attr_destroy(&attr);
	return 0;
	err:
	/* 释放线程属性对象 */
	pthread_attr_destroy(&attr);
	/* 释放互斥锁对象 */
	pthread_mutex_destroy(&mutex);
	ecat_err:
	/* 释放master对象 */
	ecrt_release_master(master);
	request_master_err:
	/* 解除对物理内存的锁定 */
	munlockall();
	mlock_err:
	/* 返回错误代码 */
	return ret;
}

void ecat_stop(void) {
	pthread_mutex_lock(&mutex);
	thread_running = false;
	pthread_mutex_unlock(&mutex);
}


<|start_filename|>rootfs/buildroot-2017.11.1/package/zstd/zstd.mk<|end_filename|>
################################################################################
#
# zstd
#
################################################################################

ZSTD_VERSION = v1.3.2
ZSTD_SITE = $(call github,facebook,zstd,$(ZSTD_VERSION))
ZSTD_LICENSE = BSD-3-Clause, GPL-2.0
ZSTD_LICENSE_FILES = LICENSE COPYING

ifeq ($(BR2_TOOLCHAIN_HAS_THREADS),y)
ZSTD_OPTS += HAVE_THREAD=1
else
ZSTD_OPTS += HAVE_THREAD=0
endif

ifeq ($(BR2_PACKAGE_ZLIB),y)
ZSTD_DEPENDENCIES += zlib
ZSTD_OPTS += HAVE_ZLIB=1
else
ZSTD_OPTS += HAVE_ZLIB=0
endif

ifeq ($(BR2_PACKAGE_XZ),y)
ZSTD_DEPENDENCIES += xz
ZSTD_OPTS += HAVE_LZMA=1
else
ZSTD_OPTS += HAVE_LZMA=0
endif

ifeq ($(BR2_PACKAGE_LZ4),y)
ZSTD_DEPENDENCIES += lz4
ZSTD_OPTS += HAVE_LZ4=1
else
ZSTD_OPTS += HAVE_LZ4=0
endif

define ZSTD_BUILD_CMDS
	$(TARGET_MAKE_ENV) $(TARGET_CONFIGURE_OPTS) $(MAKE) $(ZSTD_OPTS) \
		-C $(@D) zstd
endef

define ZSTD_INSTALL_TARGET_CMDS
	$(TARGET_MAKE_ENV) $(TARGET_CONFIGURE_OPTS) $(MAKE) $(ZSTD_OPTS) \
		DESTDIR=$(TARGET_DIR) PREFIX=/usr -C $(@D)/programs install
endef

$(eval $(generic-package))


<|start_filename|>rootfs/buildroot-2017.11.1/package/imx-usb-loader/imx-usb-loader.mk<|end_filename|>
################################################################################
#
# imx-usb-loader
#
################################################################################

IMX_USB_LOADER_VERSION = f04f225ebc1c38e81eb24745333c8622deda6b49
IMX_USB_LOADER_SITE = $(call github,boundarydevices,imx_usb_loader,$(IMX_USB_LOADER_VERSION))
IMX_USB_LOADER_LICENSE = LGPL-2.1+
IMX_USB_LOADER_LICENSE_FILES = COPYING
HOST_IMX_USB_LOADER_DEPENDENCIES = host-libusb host-pkgconf

define HOST_IMX_USB_LOADER_BUILD_CMDS
	$(HOST_CONFIGURE_OPTS) $(MAKE) -C $(@D)
endef

define HOST_IMX_USB_LOADER_INSTALL_CMDS
	$(HOST_CONFIGURE_OPTS) $(MAKE) -C $(@D) prefix=$(HOST_DIR) install
endef

$(eval $(host-generic-package))
