617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan/*
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * Use is subject to license terms.
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan */
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan/*
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * Part of Intel(R) Manageability Engine Interface Linux driver
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan *
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * Copyright (c) 2003 - 2008 Intel Corp.
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * All rights reserved.
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan *
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * Redistribution and use in source and binary forms, with or without
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * modification, are permitted provided that the following conditions
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * are met:
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * 1. Redistributions of source code must retain the above copyright
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * notice, this list of conditions, and the following disclaimer,
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * without modification.
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * 2. Redistributions in binary form must reproduce at minimum a disclaimer
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * substantially similar to the "NO WARRANTY" disclaimer below
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * ("Disclaimer") and any redistribution must be conditioned upon
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * including a substantially similar Disclaimer requirement for further
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * binary redistribution.
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * 3. Neither the names of the above-listed copyright holders nor the names
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * of any contributors may be used to endorse or promote products derived
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * from this software without specific prior written permission.
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan *
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * Alternatively, this software may be distributed under the terms of the
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * GNU General Public License ("GPL") version 2 as published by the Free
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * Software Foundation.
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan *
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * NO WARRANTY
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * POSSIBILITY OF SUCH DAMAGES.
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan *
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan */
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan#include <sys/types.h>
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan#include <sys/note.h>
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan#include <sys/cmn_err.h>
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan#include <sys/conf.h>
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan#include <sys/ddi.h>
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan#include <sys/ddi_impldefs.h>
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan#include <sys/devops.h>
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan#include <sys/instance.h>
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan#include <sys/modctl.h>
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan#include <sys/open.h>
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan#include <sys/stat.h>
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan#include <sys/sunddi.h>
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan#include <sys/sunndi.h>
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan#include <sys/systm.h>
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan#include <sys/mkdev.h>
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan#include <sys/list.h>
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan#include "heci_data_structures.h"
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan#include "heci.h"
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan#include "heci_interface.h"
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan#include "version.h"
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Loganstatic inline int heci_fe_same_id(struct heci_file_private *fe1,
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan struct heci_file_private *fe2);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan/*
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * heci_ioctl_get_version - the get driver version IOCTL function
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan *
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * @dev: Device object for our driver
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * @if_num: minor number
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * @*u_msg: pointer to user data struct in user space
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * @k_msg: data in kernel on the stack
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * @file_ext: private data of the file object
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan *
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * @return 0 on success, <0 on failure.
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan */
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Loganint
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Loganheci_ioctl_get_version(struct iamt_heci_device *dev, int if_num,
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan struct heci_message_data *u_msg,
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan struct heci_message_data k_msg,
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan struct heci_file_private *file_ext, int mode)
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan{
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan int rets = 0;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan struct heci_driver_version *version;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan struct heci_message_data res_msg;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if ((if_num < HECI_MINOR_NUMBER) || (!dev) ||
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan (!file_ext))
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan return (-ENODEV);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if (k_msg.size < (sizeof (struct heci_driver_version) - 2)) {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan DBG("user buffer less than heci_driver_version.\n");
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan return (-EMSGSIZE);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan }
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan res_msg.data = kmem_zalloc(sizeof (struct heci_driver_version),
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan KM_SLEEP);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if (!res_msg.data) {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan DBG("failed allocation response buffer size = %d.\n",
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan (int)sizeof (struct heci_driver_version));
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan return (-ENOMEM);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan }
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan version = (struct heci_driver_version *)res_msg.data;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan version->major = MAJOR_VERSION;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan version->minor = MINOR_VERSION;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan version->hotfix = QUICK_FIX_NUMBER;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan version->build = VER_BUILD;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan res_msg.size = sizeof (struct heci_driver_version);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if (k_msg.size < sizeof (struct heci_driver_version))
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan res_msg.size -= 2;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan rets = file_ext->status;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan /* now copy the data to user space */
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if (ddi_copyout(res_msg.data, k_msg.data, res_msg.size, mode)) {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan rets = -EFAULT;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan goto end;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan }
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if (ddi_copyout(&res_msg.size, &u_msg->size, sizeof (uint32_t), mode)) {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan rets = -EFAULT;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan goto end;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan }
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Loganend:
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan kmem_free(res_msg.data, sizeof (struct heci_driver_version));
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan return (rets);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan}
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan/*
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * heci_ioctl_connect_client - the connect to fw client IOCTL function
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan *
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * @dev: Device object for our driver
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * @if_num: minor number
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * @*u_msg: pointer to user data struct in user space
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * @k_msg: data in kernel on the stack
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * @file_ext: private data of the file object
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan *
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * @return 0 on success, <0 on failure.
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan */
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Loganint
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Loganheci_ioctl_connect_client(struct iamt_heci_device *dev, int if_num,
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan struct heci_message_data *u_msg,
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan struct heci_message_data k_msg,
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan struct heci_file *file, int mode)
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan{
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan int rets = 0;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan struct heci_message_data req_msg, res_msg;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan struct heci_cb_private *priv_cb = NULL;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan struct heci_client *client;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan struct heci_file_private *file_ext;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan struct heci_file_private *file_pos = NULL;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan struct heci_file_private *file_next = NULL;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan long timeout = 15; /* 15 second */
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan uint8_t i;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan int err = 0;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if ((if_num < HECI_MINOR_NUMBER) || (!dev) || (!file))
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan return (-ENODEV);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan file_ext = file->private_data;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if (!file_ext)
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan return (-ENODEV);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if (k_msg.size != sizeof (struct guid)) {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan DBG("user buffer size is not equal to size of struct "
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan "guid(16).\n");
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan return (-EMSGSIZE);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan }
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if (!k_msg.data)
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan return (-EIO);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan req_msg.data = kmem_zalloc(sizeof (struct guid), KM_SLEEP);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan res_msg.data = kmem_zalloc(sizeof (struct heci_client), KM_SLEEP);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if (!res_msg.data) {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan DBG("failed allocation response buffer size = %d.\n",
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan (int)sizeof (struct heci_client));
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan kmem_free(req_msg.data, sizeof (struct guid));
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan return (-ENOMEM);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan }
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if (!req_msg.data) {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan DBG("failed allocation request buffer size = %d.\n",
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan (int)sizeof (struct guid));
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if (res_msg.data) {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan kmem_free(res_msg.data, sizeof (struct heci_client));
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan res_msg.data = NULL;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan goto fail;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan }
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Loganfail:
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan return (-ENOMEM);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan }
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan req_msg.size = sizeof (struct guid);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan res_msg.size = sizeof (struct heci_client);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan /*
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * copy the message to kernel space -
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * use a pointer already copied into kernel space
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan */
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if (ddi_copyin(k_msg.data, req_msg.data, k_msg.size, mode)) {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan rets = -EFAULT;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan goto end;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan }
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan /* buffered ioctl cb */
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan priv_cb = kmem_zalloc(sizeof (struct heci_cb_private), KM_SLEEP);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if (!priv_cb) {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan rets = -ENOMEM;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan goto end;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan }
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan LIST_INIT_HEAD(&priv_cb->cb_list);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan priv_cb->response_buffer.data = res_msg.data;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan priv_cb->response_buffer.size = res_msg.size;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan priv_cb->request_buffer.data = req_msg.data;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan priv_cb->request_buffer.size = req_msg.size;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan priv_cb->major_file_operations = HECI_IOCTL;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan mutex_enter(&dev->device_lock);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if (dev->heci_state != HECI_ENABLED) {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan rets = -ENODEV;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan mutex_exit(&dev->device_lock);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan goto end;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan }
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if ((file_ext->state != HECI_FILE_INITIALIZING) &&
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan (file_ext->state != HECI_FILE_DISCONNECTED)) {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan rets = -EBUSY;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan mutex_exit(&dev->device_lock);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan goto end;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan }
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan DBG("req_msg.data:%x", *(uint32_t *)(void *)req_msg.data);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan /* find ME client we're trying to connect to */
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan for (i = 0; i < dev->num_heci_me_clients; i++) {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan DBG("guid:%x, me_client_id:%d\n",
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan dev->me_clients[i].props.protocol_name.data1,
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan dev->me_clients[i].client_id);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if (memcmp((struct guid *)req_msg.data,
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan &dev->me_clients[i].props.protocol_name,
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan sizeof (struct guid)) == 0) {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if (dev->me_clients[i].props.fixed_address == 0) {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan file_ext->me_client_id =
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan dev->me_clients[i].client_id;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan file_ext->state = HECI_FILE_CONNECTING;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan }
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan break;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan }
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan }
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan /*
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * if we're connecting to PTHI client so we will use the exist
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * connection
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan */
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if (memcmp((struct guid *)req_msg.data, &heci_pthi_guid,
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan sizeof (struct guid)) == 0) {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if (dev->iamthif_file_ext.state != HECI_FILE_CONNECTED) {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan rets = -ENODEV;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan mutex_exit(&dev->device_lock);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan goto end;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan }
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan dev->heci_host_clients[file_ext->host_client_id / 8] &=
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan ~(1 << (file_ext->host_client_id % 8));
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan list_for_each_entry_safe(file_pos,
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan file_next, &dev->file_list, link,
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan struct heci_file_private) {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if (heci_fe_same_id(file_ext, file_pos)) {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan DBG("remove file private data node host"
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan " client = %d, ME client = %d.\n",
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan file_pos->host_client_id,
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan file_pos->me_client_id);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan list_del(&file_pos->link);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan }
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan }
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan DBG("free file private data memory.\n");
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan kmem_free(file_ext, sizeof (struct heci_file_private));
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan file_ext = NULL;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan file->private_data = &dev->iamthif_file_ext;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan client = (struct heci_client *)res_msg.data;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan client->max_message_length =
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan dev->me_clients[i].props.max_msg_length;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan client->protocol_version =
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan dev->me_clients[i].props.protocol_version;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan rets = dev->iamthif_file_ext.status;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan mutex_exit(&dev->device_lock);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan /* now copy the data to user space */
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if (ddi_copyout(res_msg.data, k_msg.data, res_msg.size, mode)) {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan cmn_err(CE_WARN, "ddi_copyout error on res_msg.data");
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan rets = -EFAULT;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan goto end;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan }
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if (ddi_copyout(&res_msg.size, &u_msg->size,
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan sizeof (uint32_t), mode)) {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan cmn_err(CE_WARN, "ddi_copyout error on res_msg.size");
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan rets = -EFAULT;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan goto end;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan }
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan goto end;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan }
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan mutex_enter(&file_ext->file_lock);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if (file_ext->state != HECI_FILE_CONNECTING) {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan rets = -ENODEV;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan mutex_exit(&file_ext->file_lock);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan mutex_exit(&dev->device_lock);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan goto end;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan }
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan mutex_exit(&file_ext->file_lock);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan /* prepare the output buffer */
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan client = (struct heci_client *)res_msg.data;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan client->max_message_length = dev->me_clients[i].props.max_msg_length;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan client->protocol_version = dev->me_clients[i].props.protocol_version;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if (dev->host_buffer_is_empty &&
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan !other_client_is_connecting(dev, file_ext)) {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan dev->host_buffer_is_empty = 0;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if (!heci_connect(dev, file_ext)) {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan rets = -ENODEV;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan mutex_exit(&dev->device_lock);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan goto end;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan } else {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan file_ext->timer_count = HECI_CONNECT_TIMEOUT;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan priv_cb->file_private = file_ext;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan list_add_tail(&priv_cb->cb_list,
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan &dev->ctrl_rd_list.heci_cb.
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan cb_list);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan }
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan } else {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan priv_cb->file_private = file_ext;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan DBG("add connect cb to control write list.\n");
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan list_add_tail(&priv_cb->cb_list,
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan &dev->ctrl_wr_list.heci_cb.cb_list);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan }
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan err = 0;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan while (err != -1 && HECI_FILE_CONNECTED != file_ext->state &&
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan HECI_FILE_DISCONNECTED != file_ext->state) {
d3d50737e566cade9a08d73d2af95105ac7cd960Rafael Vanoni err = cv_reltimedwait(&dev->wait_recvd_msg,
d3d50737e566cade9a08d73d2af95105ac7cd960Rafael Vanoni &dev->device_lock, timeout * HZ, TR_CLOCK_TICK);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan }
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan mutex_exit(&dev->device_lock);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if (HECI_FILE_CONNECTED == file_ext->state) {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan DBG("successfully connected to FW client."
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan " me_client_id:%d, host_client_id:%d\n",
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan file_ext->me_client_id,
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan file_ext->host_client_id);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan rets = file_ext->status;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan /* now copy the data to user space */
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if (ddi_copyout(res_msg.data, k_msg.data, res_msg.size, mode)) {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan rets = -EFAULT;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan goto end;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan }
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if (ddi_copyout(&res_msg.size, &u_msg->size,
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan sizeof (uint32_t), mode)) {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan rets = -EFAULT;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan goto end;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan }
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan goto end;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan } else {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan DBG("failed to connect to FW client.file_ext->state = %d,"
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan " me_client_id:%d, host_client_id:%d\n",
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan file_ext->state, file_ext->me_client_id,
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan file_ext->host_client_id);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if (!err) {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan DBG("wait_event_interruptible_timeout failed on client"
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan " connect message fw response message.\n");
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan }
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan rets = -EFAULT;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan goto remove_list;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan }
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Loganremove_list:
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if (priv_cb) {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan mutex_enter(&dev->device_lock);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan heci_flush_list(&dev->ctrl_rd_list, file_ext);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan heci_flush_list(&dev->ctrl_wr_list, file_ext);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan mutex_exit(&dev->device_lock);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan }
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Loganend:
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan DBG("free connect cb memory.");
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan kmem_free(req_msg.data, sizeof (struct guid));
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan req_msg.data = NULL;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan kmem_free(res_msg.data, sizeof (struct heci_client));
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan res_msg.data = NULL;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if (priv_cb) {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan kmem_free(priv_cb, sizeof (struct heci_cb_private));
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan priv_cb = NULL;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan }
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan return (rets);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan}
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan/*
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * heci_ioctl_wd - the wd IOCTL function
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan *
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * @dev: Device object for our driver
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * @if_num: minor number
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * @k_msg: data in kernel on the stack
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * @file_ext: private data of the file object
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan *
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * @return 0 on success, <0 on failure.
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan */
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Loganint
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Loganheci_ioctl_wd(struct iamt_heci_device *dev, int if_num,
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan struct heci_message_data k_msg,
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan struct heci_file_private *file_ext, int mode)
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan{
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan int rets = 0;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan struct heci_message_data req_msg; /* in kernel on the stack */
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if (if_num < HECI_MINOR_NUMBER)
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan return (-ENODEV);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan mutex_enter(&file_ext->file_lock);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if (k_msg.size != HECI_WATCHDOG_DATA_SIZE) {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan DBG("user buffer has invalid size.\n");
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan mutex_exit(&file_ext->file_lock);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan return (-EMSGSIZE);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan }
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan mutex_exit(&file_ext->file_lock);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan req_msg.data = kmem_zalloc(HECI_WATCHDOG_DATA_SIZE, KM_SLEEP);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if (!req_msg.data) {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan DBG("failed allocation request buffer size = %d.\n",
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan HECI_WATCHDOG_DATA_SIZE);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan return (-ENOMEM);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan }
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan req_msg.size = HECI_WATCHDOG_DATA_SIZE;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan /*
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * copy the message to kernel space - use a pointer already
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * copied into kernel space
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan */
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if (ddi_copyin(k_msg.data, req_msg.data, k_msg.size, mode)) {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan rets = -EFAULT;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan goto end;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan }
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan mutex_enter(&dev->device_lock);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if (dev->heci_state != HECI_ENABLED) {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan rets = -ENODEV;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan mutex_exit(&dev->device_lock);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan goto end;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan }
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if (dev->wd_file_ext.state != HECI_FILE_CONNECTED) {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan rets = -ENODEV;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan mutex_exit(&dev->device_lock);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan goto end;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan }
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if (!dev->asf_mode) {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan rets = -EIO;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan mutex_exit(&dev->device_lock);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan goto end;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan }
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan (void) memcpy(&dev->wd_data[HECI_WD_PARAMS_SIZE], req_msg.data,
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan HECI_WATCHDOG_DATA_SIZE);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan dev->wd_timeout = (req_msg.data[1] << 8) + req_msg.data[0];
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan dev->wd_pending = 0;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan dev->wd_due_counter = 1; /* next timer */
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if (dev->wd_timeout == 0) {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan (void) memcpy(dev->wd_data, &stop_wd_params,
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan HECI_WD_PARAMS_SIZE);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan } else {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan (void) memcpy(dev->wd_data, &start_wd_params,
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan HECI_WD_PARAMS_SIZE);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan dev->wd_timer = timeout(heci_wd_timer, dev, 1);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan }
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan mutex_exit(&dev->device_lock);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Loganend:
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan kmem_free(req_msg.data, HECI_WATCHDOG_DATA_SIZE);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan return (rets);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan}
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan/*
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * heci_ioctl_bypass_wd - the bypass_wd IOCTL function
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan *
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * @dev: Device object for our driver
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * @if_num: minor number
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * @k_msg: data in kernel on the stack
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * @file_ext: private data of the file object
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan *
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * @return 0 on success, <0 on failure.
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan */
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Loganint
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Loganheci_ioctl_bypass_wd(struct iamt_heci_device *dev, int if_num,
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan struct heci_message_data k_msg,
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan struct heci_file_private *file_ext, int mode)
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan{
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan uint8_t flag = 0;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan int rets = 0;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if (if_num < HECI_MINOR_NUMBER)
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan return (-ENODEV);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan mutex_enter(&file_ext->file_lock);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if (k_msg.size < 1) {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan DBG("user buffer less than HECI_WATCHDOG_DATA_SIZE.\n");
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan mutex_exit(&file_ext->file_lock);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan return (-EMSGSIZE);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan }
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan mutex_exit(&file_ext->file_lock);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if (ddi_copyin(k_msg.data, &flag, 1, mode)) {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan rets = -EFAULT;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan goto end;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan }
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan mutex_enter(&dev->device_lock);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan flag = flag ? (1) : (0);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan dev->wd_bypass = flag;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan mutex_exit(&dev->device_lock);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Loganend:
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan return (rets);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan}
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan/*
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * find_pthi_read_list_entry - finds a PTHIlist entry for current file
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan *
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * @dev: Device object for our driver
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * @file: pointer to file object
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan *
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * @return returned a list entry on success, NULL on failure.
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan */
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Loganstruct heci_cb_private *
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Loganfind_pthi_read_list_entry(
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan struct iamt_heci_device *dev,
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan struct heci_file *file)
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan{
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan struct heci_file_private *file_ext_temp;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan struct heci_cb_private *priv_cb_pos = NULL;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan struct heci_cb_private *priv_cb_next = NULL;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if ((dev->pthi_read_complete_list.status == 0) &&
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan !list_empty(&dev->pthi_read_complete_list.heci_cb.cb_list)) {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan list_for_each_entry_safe(priv_cb_pos, priv_cb_next,
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan &dev->pthi_read_complete_list.heci_cb.cb_list, cb_list,
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan struct heci_cb_private) {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan file_ext_temp = (struct heci_file_private *)
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan priv_cb_pos->file_private;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if ((file_ext_temp != NULL) &&
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan (file_ext_temp == &dev->iamthif_file_ext) &&
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan (priv_cb_pos->file_object == file))
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan return (priv_cb_pos);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan }
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan }
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan return (NULL);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan}
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan/*
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * pthi_read - read data from pthi client
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan *
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * @dev: Device object for our driver
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * @if_num: minor number
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * @file: pointer to file object
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * @*ubuf: pointer to user data in user space
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * @length: data length to read
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * @offset: data read offset
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan *
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * @return
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * returned data length on success,
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * zero if no data to read,
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * negative on failure.
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan */
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Loganint
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Loganpthi_read(struct iamt_heci_device *dev, int if_num, struct heci_file *file,
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan struct uio *uio_p)
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan{
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan int rets = 0;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan struct heci_cb_private *priv_cb = NULL;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan struct heci_file_private *file_ext = file->private_data;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan uint8_t i;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan unsigned long currtime = ddi_get_time();
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if ((if_num < HECI_MINOR_NUMBER) || (!dev))
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan return (-ENODEV);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if ((file_ext == NULL) || (file_ext != &dev->iamthif_file_ext))
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan return (-ENODEV);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan mutex_enter(&dev->device_lock);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan for (i = 0; i < dev->num_heci_me_clients; i++) {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if (dev->me_clients[i].client_id ==
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan dev->iamthif_file_ext.me_client_id)
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan break;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan }
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan ASSERT(dev->me_clients[i].client_id == file_ext->me_client_id);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if ((i == dev->num_heci_me_clients) ||
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan (dev->me_clients[i].client_id !=
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan dev->iamthif_file_ext.me_client_id)) {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan DBG("PTHI client not found.\n");
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan mutex_exit(&dev->device_lock);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan return (-ENODEV);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan }
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan priv_cb = find_pthi_read_list_entry(dev, file);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if (!priv_cb) {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan mutex_exit(&dev->device_lock);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan return (0); /* No more data to read */
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan } else {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if (priv_cb &&
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan (currtime - priv_cb->read_time > IAMTHIF_READ_TIMER)) {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan /* 15 sec for the message has expired */
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan list_del(&priv_cb->cb_list);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan mutex_exit(&dev->device_lock);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan rets = -ETIMEDOUT;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan goto free;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan }
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan /* if the whole message will fit remove it from the list */
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if ((priv_cb->information >= UIO_OFFSET(uio_p)) &&
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan (UIO_LENGTH(uio_p) >=
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan (priv_cb->information - UIO_OFFSET(uio_p)))) {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan list_del(&priv_cb->cb_list);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan } else if ((priv_cb->information > 0) &&
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan (priv_cb->information <= UIO_OFFSET(uio_p))) {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan /* end of the message has been reached */
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan list_del(&priv_cb->cb_list);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan rets = 0;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan mutex_exit(&dev->device_lock);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan goto free;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan }
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan /*
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * else means that not full buffer will be read and do not
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * remove message from deletion list
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan */
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan }
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan DBG("pthi priv_cb->response_buffer size - %d\n",
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan priv_cb->response_buffer.size);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan DBG("pthi priv_cb->information - %lu\n",
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan priv_cb->information);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan mutex_exit(&dev->device_lock);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan rets = uiomove(priv_cb->response_buffer.data,
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan min(uio_p->uio_resid, priv_cb->information),
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan UIO_READ, uio_p);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Loganfree:
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan DBG("free pthi cb memory.\n");
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan kmem_free(priv_cb->request_buffer.data, priv_cb->request_buffer.size);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan kmem_free(priv_cb->response_buffer.data, priv_cb->response_buffer.size);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan kmem_free(priv_cb, sizeof (struct heci_cb_private));
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan return (rets);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan}
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan/*
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * heci_start_read - the start read client message function.
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan *
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * @dev: Device object for our driver
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * @if_num: minor number
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * @file_ext: private data of the file object
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan *
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * @return 0 on success, <0 on failure.
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan */
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Loganint
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Loganheci_start_read(struct iamt_heci_device *dev, int if_num,
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan struct heci_file_private *file_ext)
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan{
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan int rets = 0;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan uint8_t i;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan struct heci_cb_private *priv_cb = NULL;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if ((if_num < HECI_MINOR_NUMBER) || (!dev) || (!file_ext)) {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan DBG("received wrong function input param.\n");
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan return (-ENODEV);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan }
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if (file_ext->state != HECI_FILE_CONNECTED)
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan return (-ENODEV);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan mutex_enter(&dev->device_lock);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if (dev->heci_state != HECI_ENABLED) {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan mutex_exit(&dev->device_lock);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan return (-ENODEV);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan }
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan mutex_exit(&dev->device_lock);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan DBG("check if read is pending.\n");
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if ((file_ext->read_pending) || (file_ext->read_cb != NULL)) {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan DBG("read is pending.\n");
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan return (-EBUSY);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan }
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan priv_cb = kmem_zalloc(sizeof (struct heci_cb_private), KM_SLEEP);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if (!priv_cb)
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan return (-ENOMEM);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan DBG("allocation call back success\n"
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan "host client = %d, ME client = %d\n",
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan file_ext->host_client_id, file_ext->me_client_id);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan mutex_enter(&dev->device_lock);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan for (i = 0; i < dev->num_heci_me_clients; i++) {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if (dev->me_clients[i].client_id == file_ext->me_client_id)
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan break;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan }
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan ASSERT(dev->me_clients[i].client_id == file_ext->me_client_id);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if (i == dev->num_heci_me_clients) {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan rets = -ENODEV;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan goto unlock;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan }
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan priv_cb->response_buffer.size = dev->me_clients[i].props.max_msg_length;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan mutex_exit(&dev->device_lock);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan priv_cb->response_buffer.data =
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan kmem_zalloc(priv_cb->response_buffer.size, KM_SLEEP);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if (!priv_cb->response_buffer.data) {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan rets = -ENOMEM;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan goto fail;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan }
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan DBG("allocation call back data success.\n");
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan priv_cb->major_file_operations = HECI_READ;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan /* make sure information is zero before we start */
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan priv_cb->information = 0;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan priv_cb->file_private = (void *)file_ext;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan file_ext->read_cb = priv_cb;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan mutex_enter(&dev->device_lock);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if (dev->host_buffer_is_empty) {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan dev->host_buffer_is_empty = 0;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if (!heci_send_flow_control(dev, file_ext)) {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan rets = -ENODEV;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan goto unlock;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan } else {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan list_add_tail(&priv_cb->cb_list,
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan &dev->read_list.heci_cb.cb_list);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan }
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan } else {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan list_add_tail(&priv_cb->cb_list,
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan &dev->ctrl_wr_list.heci_cb.cb_list);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan }
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan mutex_exit(&dev->device_lock);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan return (rets);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Loganunlock:
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan mutex_exit(&dev->device_lock);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Loganfail:
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan heci_free_cb_private(priv_cb);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan return (rets);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan}
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan/*
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * pthi_write: write iamthif data to pthi client
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan *
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * @dev: Device object for our driver
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * @priv_cb: heci call back struct
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan *
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * @return 0 on success, <0 on failure.
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan */
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Loganint
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Loganpthi_write(struct iamt_heci_device *dev,
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan struct heci_cb_private *priv_cb)
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan{
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan int rets = 0;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan struct heci_msg_hdr heci_hdr;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if ((!dev) || (!priv_cb))
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan return (-ENODEV);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan DBG("write data to pthi client.\n");
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan dev->iamthif_state = HECI_IAMTHIF_WRITING;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan dev->iamthif_current_cb = priv_cb;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan dev->iamthif_file_object = priv_cb->file_object;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan dev->iamthif_canceled = 0;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan dev->iamthif_ioctl = 1;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan dev->iamthif_msg_buf_size = priv_cb->request_buffer.size;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan (void) memcpy(dev->iamthif_msg_buf, priv_cb->request_buffer.data,
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan priv_cb->request_buffer.size);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if (flow_ctrl_creds(dev, &dev->iamthif_file_ext) &&
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan dev->host_buffer_is_empty) {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan dev->host_buffer_is_empty = 0;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if (priv_cb->request_buffer.size >
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan (((dev->host_hw_state & H_CBD) >> 24) *
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan sizeof (uint32_t)) - sizeof (struct heci_msg_hdr)) {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan heci_hdr.length =
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan (((dev->host_hw_state & H_CBD) >> 24) *
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan sizeof (uint32_t)) - sizeof (struct heci_msg_hdr);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan heci_hdr.msg_complete = 0;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan } else {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan heci_hdr.length = priv_cb->request_buffer.size;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan heci_hdr.msg_complete = 1;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan }
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan heci_hdr.host_addr = dev->iamthif_file_ext.host_client_id;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan heci_hdr.me_addr = dev->iamthif_file_ext.me_client_id;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan heci_hdr.reserved = 0;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan dev->iamthif_msg_buf_index += heci_hdr.length;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if (!heci_write_message(dev, &heci_hdr,
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan (unsigned char *)(dev->iamthif_msg_buf),
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan heci_hdr.length))
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan return (-ENODEV);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if (heci_hdr.msg_complete) {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan flow_ctrl_reduce(dev, &dev->iamthif_file_ext);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan dev->iamthif_flow_control_pending = 1;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan dev->iamthif_state = HECI_IAMTHIF_FLOW_CONTROL;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan DBG("add pthi cb to write waiting list\n");
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan dev->iamthif_current_cb = priv_cb;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan dev->iamthif_file_object = priv_cb->file_object;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan list_add_tail(&priv_cb->cb_list,
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan &dev->write_waiting_list.heci_cb.cb_list);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan } else {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan DBG("message does not complete, "
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan "so add pthi cb to write list.\n");
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan list_add_tail(&priv_cb->cb_list,
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan &dev->write_list.heci_cb.cb_list);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan }
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan } else {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if (!(dev->host_buffer_is_empty))
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan DBG("host buffer is not empty");
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan DBG("No flow control credentials, "
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan "so add iamthif cb to write list.\n");
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan list_add_tail(&priv_cb->cb_list,
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan &dev->write_list.heci_cb.cb_list);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan }
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan return (rets);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan}
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan/*
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * iamthif_ioctl_send_msg - send cmd data to pthi client
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan *
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * @dev: Device object for our driver
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan *
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * @return 0 on success, <0 on failure.
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan */
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Loganvoid
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Loganrun_next_iamthif_cmd(struct iamt_heci_device *dev)
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan{
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan struct heci_file_private *file_ext_tmp;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan struct heci_cb_private *priv_cb_pos = NULL;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan struct heci_cb_private *priv_cb_next = NULL;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan int status = 0;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if (!dev)
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan return;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan dev->iamthif_msg_buf_size = 0;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan dev->iamthif_msg_buf_index = 0;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan dev->iamthif_canceled = 0;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan dev->iamthif_ioctl = 1;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan dev->iamthif_state = HECI_IAMTHIF_IDLE;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan dev->iamthif_timer = 0;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan dev->iamthif_file_object = NULL;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if (dev->pthi_cmd_list.status == 0 &&
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan !list_empty(&dev->pthi_cmd_list.heci_cb.cb_list)) {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan DBG("complete pthi cmd_list cb.\n");
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan list_for_each_entry_safe(priv_cb_pos, priv_cb_next,
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan &dev->pthi_cmd_list.heci_cb.cb_list, cb_list,
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan struct heci_cb_private) {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan list_del(&priv_cb_pos->cb_list);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan file_ext_tmp = (struct heci_file_private *)
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan priv_cb_pos->file_private;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if ((file_ext_tmp != NULL) &&
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan (file_ext_tmp == &dev->iamthif_file_ext)) {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan status = pthi_write(dev, priv_cb_pos);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if (status != 0) {
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan DBG("pthi write failed status = %d\n",
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan status);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan return;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan }
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan break;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan }
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan }
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan }
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan}
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan/*
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * heci_free_cb_private - free heci_cb_private related memory
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan *
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * @priv_cb: heci callback struct
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan */
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Loganvoid
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Loganheci_free_cb_private(struct heci_cb_private *priv_cb)
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan{
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan if (priv_cb == NULL)
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan return;
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan kmem_free(priv_cb->request_buffer.data, priv_cb->request_buffer.size);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan kmem_free(priv_cb->response_buffer.data, priv_cb->response_buffer.size);
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan kmem_free(priv_cb, sizeof (struct heci_cb_private));
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan}
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan/*
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * heci_fe_same_id - tell if file private data have same id
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan *
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * @fe1: private data of 1. file object
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * @fe2: private data of 2. file object
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan *
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan * @return !=0 - if ids are the same, 0 - if differ.
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan */
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Loganstatic inline int heci_fe_same_id(struct heci_file_private *fe1,
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan struct heci_file_private *fe2)
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan{
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan return ((fe1->host_client_id == fe2->host_client_id) &&
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan (fe1->me_client_id == fe2->me_client_id));
617e2443dfc17fe44fd44c0675d6aad2ffc9df42Mark Logan}