/*
 * Freescale UUT driver
 *
 * Copyright 2008-2013 Freescale Semiconductor, Inc.
 * Copyright 2008-2009 Embedded Alley Solutions, Inc All Rights Reserved.
 */

/*
 * The code contained herein is licensed under the GNU General Public
 * License. You may obtain a copy of the GNU General Public License
 * Version 2 or later at the following locations:
 *
 * http://www.opensource.org/licenses/gpl-license.html
 * http://www.gnu.org/copyleft/gpl.html
 */

#ifndef __FSL_UPDATER_H
#define __FSL_UPDATER_H

//#include <linux/miscdevice.h>
#include <linux/list.h>
//#include <linux/vmalloc.h>
//#include <linux/ioctl.h>
//#include <mach/hardware.h>

static int utp_init(struct fsg_dev *fsg);
static void utp_exit(struct fsg_dev *fsg);

static struct utp_user_data *utp_user_data_alloc(size_t align, size_t size);
static void utp_user_data_free(struct utp_user_data *uud);
static int utp_get_sense(struct fsg_common *common);
static int utp_do_read(struct fsg_common *common, void *data, size_t size);
static int utp_do_write(struct fsg_common *common, void *data, size_t size);
static inline void utp_set_sense(struct fsg_common *fsg, u16 code, u64 reply);
static int utp_handle_message(struct fsg_common *common,
			      u8 *cdb_data,
			      int default_reply);
static struct utp_user_data 
*utp_interpret_message(struct utp_user_data *uud2r);

#define UTP_REPLY_PASS		0
#define UTP_REPLY_EXIT		0x8001
#define UTP_REPLY_BUSY		0x8002
#define UTP_REPLY_SIZE		0x8003
#define UTP_SENSE_KEY		9

#define UTP_MINOR		222
/* MISC_DYNAMIC_MINOR would be better, but... */

#define UTP_COMMAND_SIZE	80

#define UTP_SS_EXIT(fsg, r) 	utp_set_sense(fsg, UTP_REPLY_EXIT, (u64)r)
#define UTP_SS_PASS(fsg)	utp_set_sense(fsg, UTP_REPLY_PASS, 0)
#define UTP_SS_BUSY(fsg, r)	utp_set_sense(fsg, UTP_REPLY_BUSY, (u64)r)
#define UTP_SS_SIZE(fsg, r)	utp_set_sense(fsg, UTP_REPLY_SIZE, (u64)r)

#define	UTP_IOCTL_BASE	'U'
#define	UTP_GET_CPU_ID	_IOR(UTP_IOCTL_BASE, 0, int)
/* the structure of utp message which is mapped to 16-byte SCSI CBW's CDB */
#pragma pack(1)
struct utp_msg {
	u8  f0;
	u8  utp_msg_type;
	u32 utp_msg_tag;
	union {
		struct {
			u32 param_lsb;
			u32 param_msb;
		};
		u64 param;
	};
};

enum utp_msg_type {
	UTP_POLL = 0,
	UTP_EXEC,
	UTP_GET,
	UTP_PUT,
};

static struct utp_context {
	u32 sd, sdinfo, sdinfo_h;			/* sense data */
	int processed;
	u8 *buffer;
	u32 counter;
	u64 utp_version;
} utp_context;

#define UTP_FLAG_COMMAND	0x00000001
#define UTP_FLAG_DATA		0x00000002
#define UTP_FLAG_STATUS		0x00000004
#define UTP_FLAG_REPORT_BUSY	0x10000000
struct utp_message {
	u32 	flags;
	size_t 	size;
	union {
		struct {
			u64 payload;
			char command[1];
		};
		struct {
			size_t bufsize;
			u8 data[1];
		};
		u32 status;
	};
};

struct utp_user_data {
	struct  utp_message	data;
};
#pragma pack()

static inline struct utp_context *UTP_CTX(struct fsg_dev *fsg)
{
	return (struct utp_context *)fsg->utp;
}

#endif /* __FSL_UPDATER_H */

