/*
 * Copyright (C) 2018 Synaptics Incorporated. 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 version 2 as
 * published by the Free Software Foundation.
 *
 * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND
 * SYNAPTICS EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES,
 * INCLUDING ANY IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE, AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY
 * INTELLECTUAL PROPERTY RIGHTS. IN NO EVENT SHALL SYNAPTICS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, PUNITIVE, OR
 * CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION WITH THE USE
 * OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED AND
 * BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF
 * COMPETENT JURISDICTION DOES NOT PERMIT THE DISCLAIMER OF DIRECT
 * DAMAGES OR ANY OTHER DAMAGES, SYNAPTICS' TOTAL CUMULATIVE LIABILITY
 * TO ANY PARTY SHALL NOT EXCEED ONE HUNDRED U.S. DOLLARS.
 */
#include "diag_common.h"
#include "diag_misc.h"
#include "Galois_memmap.h"
#include "soc.h"
#include "diag_gic.h"
#include "diag_cpu.h"
#include "diag_misc.h"
#include "global.h"
#include "usb_memmap.h"
#include "usb_typedefs.h"
#include "usb_mass_ufi.h"
#include "core.h"

static struct usb_mass_data usb_stor = {0};
static int g_udev_bulk_in_epnum = 1; // Mass Storage EP assignment
static int g_udev_bulk_out_epnum = 2; // Mass Storage EP assignment
static char *gp_mass_cdb_buff = (char *)USB_MASS_BULK_CDB_BASE;
static char *gp_mass_csw_buff = (char *)USB_MASS_BULK_CSW_BASE;
static char *gp_mass_data_buff = (char *)USB_MASS_BULK_DATA_BASE;
static int g_mass_lun = 0; // LUN for MASS Storage
static int g_mass_tag = 0;
static int g_mass_last_lba = 0; //Mass Storage last lba
static int g_usb_init = 0; //Indicate if usb is initialized in mass storage
int g_mass_blen = 512; // Mass Storage block len
int g_mass_blocking = 0;
int g_mass_storage_timeout = 0; // 1000 = 1 second, 0: no timeout
unsigned int g_usbTrCompleteCount = 0;
int g_usb_mass_isr_state = MASS_WAIT_NEW_CMD;
int g_usb_mass_data_dir;
int g_usb_mass_data_len;
char *g_usb_mass_data;

static void mymemcpy(char *d, char *s, int count)
{
	while(count){
		*d++ = *s++;
		count--;
	}
}

static unsigned int usb_mass_getmaxlun(int *maxlun)
{
    struct usb_mass_data *us = &usb_stor;
    int len;
    int ret;
    unsigned char *result = USB_memalloc(1);
    len = urb_control(us->pusb_dev,
                  usb_rcvctrlpipe(us->pusb_dev, 0),
                  US_BBB_GET_MAX_LUN,
                  USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
                  0, us->ifnum,
                  result, sizeof(char),
                  USB_CNTL_TIMEOUT * 5);
    dbg_printf(PRN_RES,"Get Max LUN -> len = %d, result = %d\n", len, (int) *result);

	g_mass_tag = 1; // Start Mass Storage CDW tag to 1
    if (len > 0)  {
        *maxlun = *result;
        ret = 0;
    }else {
        *maxlun = 0;
        ret = -EINVAL;
    }

    USB_memfree(result);
    return ret;
}

static int usb_mass_data_queue()
{
	int res;
	unsigned long pipe_bulk_in, pipe_bulk_out;

	if (g_usb_mass_data_dir == USB_DIR_IN){
		pipe_bulk_in = usb_rcvbulkpipe(pdev_usb, g_udev_bulk_in_epnum);
		res = que_blk_msg(pdev_usb, pipe_bulk_in, g_usb_mass_data, g_usb_mass_data_len);
	}
	else{
		pipe_bulk_out = usb_sndbulkpipe(pdev_usb, g_udev_bulk_out_epnum);
		res = que_blk_msg(pdev_usb, pipe_bulk_out, g_usb_mass_data, g_usb_mass_data_len);
	}

	RETURN_ON_ERROR(res)
	return 0;
}

static int usb_mass_status_queue()
{
	unsigned long pipe_bulk_in;
	int res;

	pipe_bulk_in = usb_rcvbulkpipe(pdev_usb, g_udev_bulk_in_epnum);
	res = que_blk_msg(pdev_usb, pipe_bulk_in, gp_mass_csw_buff, CSW_SIZE);

	RETURN_ON_ERROR(res)

	return 0;
}

void usb_mass_callback()
{

	switch(g_usb_mass_isr_state){
		case MASS_WAIT_CMD_DONE:
		//Queue Data
			dbg_disp("DATA PHASE\n");
			usb_mass_data_queue();
			g_usb_mass_isr_state = MASS_WAIT_DATA_DONE;
			break;
		case MASS_WAIT_DATA_DONE:
		//Queue Status
			dbg_disp("STATUS PHASE\n");
			usb_mass_status_queue();
			g_usb_mass_isr_state = MASS_WAIT_STATUS_DONE;
			break;
		case MASS_WAIT_STATUS_DONE:
			dbg_disp("COMPLETE PHASE\n");
			g_usbTrCompleteCount++; // Let MI know.
			g_usb_mass_isr_state = MASS_WAIT_NEW_CMD;
			break;
	}
}


static int usb_mass_generic_queue(char *cdb, char *data, int data_len, int dir)
{
	unsigned long pipe_bulk_out;
	int res;

	// Build pipe
	pipe_bulk_out = usb_sndbulkpipe(pdev_usb, g_udev_bulk_out_epnum);

	g_usb_mass_data_dir = dir;
	g_usb_mass_data_len = data_len;
	g_usb_mass_data = data;

	mymemcpy(gp_mass_cdb_buff, cdb, CBW_SIZE);
	dbg_dump_buffer((unsigned char *)gp_mass_cdb_buff,31);

	g_usb_mass_isr_state = data_len ? MASS_WAIT_CMD_DONE:MASS_WAIT_DATA_DONE;

	dbg_disp("COMMAND PHASE\n");
	res = que_blk_msg(pdev_usb, pipe_bulk_out, gp_mass_cdb_buff, CBW_SIZE);
	RETURN_ON_ERROR(res)

	return 0;
}

static int usbmass_generic(char *cdb, char *data, int data_len, int dir)
{
	unsigned long pipe_bulk_in, pipe_bulk_out;
	int res;

	if (g_mass_blocking)
	{
		// Build pipe
		pipe_bulk_in = usb_rcvbulkpipe(pdev_usb, g_udev_bulk_in_epnum);
		pipe_bulk_out = usb_sndbulkpipe(pdev_usb, g_udev_bulk_out_epnum);

		//Command Phase
		mymemcpy(gp_mass_cdb_buff, cdb, CBW_SIZE);
		dbg_out("CDB[");dbg_outdw((unsigned long)gp_mass_cdb_buff);dbg_out("]");
		dbg_dump_buffer((unsigned char *)gp_mass_cdb_buff,31);
		res = snd_blk_msg(pdev_usb, pipe_bulk_out, gp_mass_cdb_buff, CBW_SIZE);
		RETURN_ON_ERROR(res)

		//Data Phase if data_len>0
		if (data_len){
			if (dir == USB_DIR_IN){
				res = snd_blk_msg(pdev_usb, pipe_bulk_in, data, data_len);
				RETURN_ON_ERROR(res)
				dbg_out("POST DATA IN[");dbg_outdw((unsigned long)data);dbg_out("]");
				dbg_dump_buffer((unsigned char *)data,min(data_len,8));
				if (data_len>=16){
					dbg_out("POST DATA IN[");dbg_outdw((unsigned long)(data+data_len-8));dbg_out("]");
					dbg_dump_buffer((unsigned char *)(data+data_len-8),8);
				}
			}
			else{
				dbg_out("DATA_OUT["); dbg_outdw((unsigned long)data); dbg_out(",");dbg_outdw((unsigned int)data_len);
				dbg_dump_buffer((unsigned char *)data,min(data_len,16));
				res = snd_blk_msg(pdev_usb, pipe_bulk_out, data, data_len);
				RETURN_ON_ERROR(res)
			}
		}


		//Status phase
		res = snd_blk_msg(pdev_usb, pipe_bulk_in, gp_mass_csw_buff, CSW_SIZE);
		RETURN_ON_ERROR(res)
		dbg_out("POST CSW[");dbg_outdw((unsigned long)gp_mass_csw_buff); dbg_out("]");
		dbg_dump_buffer((unsigned char*)gp_mass_csw_buff,CSW_SIZE);
	}
	else{
		unsigned int tr_compl_count_pre = g_usbTrCompleteCount;
		int timeout=g_mass_storage_timeout;

		usb_mass_generic_queue( cdb, data, data_len, dir);

		while(g_usbTrCompleteCount==tr_compl_count_pre){
			// To Do. Implement some kind of Time out here in case of error.
			dbg_printf(PRN_INFO,".");
			mdelay(1);
			if ((!timeout) && g_mass_storage_timeout ){
				dbg_printf(PRN_RES,"ERR: Mass Storage Timeout!\n");
				return 1;
			}
			if (g_mass_storage_timeout)
				timeout--;
		}
	}
	return 0;
}

int usb_mass_ufi_generic
(
/* [IN] command object allocated by application*/
uint_8                     opcode,
uint_8                     lun,
uint_32                    lbaddr,
uint_32                    blen,

uint_8                     cbwflags,

uchar_ptr                  buf,
uint_32                    buf_len
)
{ /* Body */
	//int status = USB_OK;
	CBW_STRUCT *cbw_ptr = (CBW_STRUCT *)gp_mass_cdb_buff;
	UFI_CBWCB_EXTENDED  *ufi_ptr = (UFI_CBWCB_EXTENDED *)cbw_ptr->CBWCB;

	memset(gp_mass_cdb_buff, 0, CBW_SIZE);

	/* Construct UFI command buffer */
	ufi_ptr->BUFIOPCODE = opcode;
	ufi_ptr->BUFILUN = lun;
	utou32swap(ufi_ptr->BUFILOGICALBLOCKADDRESS, lbaddr);
	utou32swap(ufi_ptr->BLENGTH, blen);

	/* Construct CBW fields (sig and tag will be filled up by class driver)*/
	utou32(cbw_ptr->DCBWDATALENGTH, buf_len);
	cbw_ptr->BMCBWFLAGS = cbwflags;
	transfer_low_nibble(g_mass_lun, cbw_ptr->BCBWCBLUN);
	transfer_low_nibble(sizeof(UFI_CBWCB_EXTENDED),
		cbw_ptr->BCBWCBLENGTH);
	utou32(cbw_ptr->DCBWSIGNATURE, CBW_SIGNATURE);
	utou32(cbw_ptr->DCBWTAG, g_mass_tag++); // increment mass storage command tag here

	return usbmass_generic((char*) cbw_ptr, (char *) buf, buf_len, cbwflags);

} /* Endbody */

void usb_mass_parse_capacity(char *b, int *last , int *len)
{
	unsigned long last_lba, blk_len;

	last_lba = (((unsigned long)b[0]) << 24) |
		(((unsigned long)b[1]) << 16) |
		(((unsigned long)b[2]) << 8) |
		(((unsigned long)b[3]) & 0x0FF);
	blk_len = (((unsigned long)b[4]) << 24) |
		(((unsigned long)b[5]) << 16) |
		(((unsigned long)b[6]) << 8) |
		(((unsigned long)b[7]) & 0x0FF);

	*last = last_lba;
	*len = blk_len;

	dbg_printf(PRN_RES,"USB MASS STORAGE INFO: LAST_LBA=0x%08lX BLK_LEN=%d bytes\n", last_lba, blk_len);
}

int usb_mass_probe(void)
{
    struct usb_interface *iface;
    int i;
    struct usb_endpoint_descriptor *ep_desc;
    //unsigned int flags = 0;
    struct usb_device *dev = pdev_usb;
    struct usb_mass_data *ss = &usb_stor;
    unsigned int ifnum = 0;

    /* let's examine the device now */
    iface = &dev->config.if_desc[ifnum];

    if (dev->descriptor.bDeviceClass != 0 ||
            iface->desc.bInterfaceClass != USB_CLASS_MASS_STORAGE ||
            iface->desc.bInterfaceSubClass < US_SC_MIN ||
            iface->desc.bInterfaceSubClass > US_SC_MAX) {
        debug("Not mass storage\n");
        /* if it's not a mass storage, we go no further */
        return 0;
    }

    memset(ss, 0, sizeof(struct usb_mass_data));

    /* At this point, we know we've got a live one */
    debug("\n\nUSB Mass Storage device detected\n");

    /* Initialize the us_data structure with some useful info */
    ss->ifnum = ifnum;
    ss->pusb_dev = dev;

    /*
     * We are expecting a minimum of 2 endpoints - in and out (bulk).
     * An optional interrupt is OK (necessary for CBI protocol).
     * We will ignore any others.
     */
    for (i = 0; i < iface->desc.bNumEndpoints; i++) {
        ep_desc = &iface->ep_desc[i];
        /* is it an BULK endpoint? */
        if ((ep_desc->bmAttributes &
             USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK) {
            if (ep_desc->bEndpointAddress & USB_DIR_IN)
                ss->ep_in = ep_desc->bEndpointAddress &
                        USB_ENDPOINT_NUMBER_MASK;
            else
                ss->ep_out =
                    ep_desc->bEndpointAddress &
                    USB_ENDPOINT_NUMBER_MASK;
        }

        /* is it an interrupt endpoint? */
        if ((ep_desc->bmAttributes &
             USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT) {
            ss->ep_int = ep_desc->bEndpointAddress &
                        USB_ENDPOINT_NUMBER_MASK;
            ss->irqinterval = ep_desc->bInterval;
        }
    }
    debug("Endpoints In %d Out %d Int %d\n",
          ss->ep_in, ss->ep_out, ss->ep_int);
    g_udev_bulk_in_epnum = ss->ep_in;
    g_udev_bulk_out_epnum = ss->ep_out;

    return set_interface(dev, iface->desc.bInterfaceNumber, 0);
}

int usb_mass_start()
{
	int res;
	static int mass_started = 0;

	if (!mass_started){
		mass_started = 1;
		// Dynamically allocate
		gp_mass_cdb_buff = USB_memalloc(64);
		gp_mass_csw_buff = USB_memalloc(64);
		gp_mass_data_buff = USB_memalloc(USB_MASS_BULK_DATA_SIZE);	//2MB
	}

	dbg_printf(PRN_RES,"\t--SET_INTERFACE..");
    res = usb_mass_probe();
	RETURN_ON_ERROR(res);
	dbg_printf(PRN_RES,"OK\n");

	dbg_printf(PRN_RES,"\t--GET_LUN..");
	res = usb_mass_getmaxlun(&g_mass_lun);
	RETURN_ON_ERROR(res);
	dbg_printf(PRN_RES,"got:%d .. OK\n",g_mass_lun);

	//	TEST UNIT READY
	dbg_printf(PRN_RES,"\t--TEST_UNIT_READY..");
	res = usb_mass_ufi_test_unit_ready();
	RETURN_ON_ERROR(res);
	dbg_printf(PRN_RES,"OK\n");
	USB_MASS_SENSE

	// READ CAPACITY to get last_lba and blk_len, before we do any READ /WRITE block based.
	dbg_printf(PRN_RES,"\t--READ_CAPACITY..");
	res = usb_mass_ufi_read_capacity((uchar_ptr)gp_mass_data_buff, sizeof(MASS_STORAGE_READ_CAPACITY_CMD_STRUCT_INFO));
	RETURN_ON_ERROR(res);
	dbg_printf(PRN_RES,"OK\n");
	//now parse the result to extract important mass storage information.
	usb_mass_parse_capacity(gp_mass_data_buff, &g_mass_last_lba, &g_mass_blen);
	USB_MASS_SENSE

	//	READ10
	memset(gp_mass_data_buff,0,g_mass_blen); // SET read buffer to 0
	dbg_printf(PRN_RES,"\t--READ10..");
	res = usb_mass_ufi_read_10( 8, (uchar_ptr) gp_mass_data_buff, g_mass_blen , 1);
	RETURN_ON_ERROR(res);
	dbg_printf(PRN_RES,"OK\n");

	//	WRITE10
	dbg_printf(PRN_RES,"\t--WRITE10..");
#if PLATFORM == VELOCE	//we don't use File System in mass storage
	// Initialize input buffer.
	{ int i;
	unsigned char *pb= (uchar_ptr)gp_mass_data_buff;
	for(i=0;i<g_mass_blen;i++) *pb++=i&0x0ff;
	}

	res = usb_mass_ufi_write_10(8, (uchar_ptr)gp_mass_data_buff, g_mass_blen, 1);
	RETURN_ON_ERROR(res);
	dbg_printf(PRN_RES,"OK\n");
#else
	dbg_printf(PRN_RES,"SKIPPED\n");
#endif

	//	INQUIRY
	dbg_printf(PRN_RES,"\t--INQUIRY..");
	res = usb_mass_ufi_inquiry((uchar_ptr)gp_mass_data_buff, sizeof(INQUIRY_DATA_FORMAT));
	RETURN_ON_ERROR(res);
	dbg_printf(PRN_RES,"OK\n");

	//	PREVENT ALLOW MEDIUM REMOVAL
	dbg_printf(PRN_RES,"\t--PREVENT MEDIUM REMOVAL..");
	res = usb_mass_ufi_prevent_allow_medium_removal(1); //prevent
	RETURN_ON_ERROR(res);
	dbg_printf(PRN_RES,"OK\n");
	g_usb_init = 1;

	return 0;
}

int usb_storage_init()
{
	int res;

	if (g_usb_init)
		return 0;
	res = usb_mass_start();
	RETURN_ON_ERROR(res);

	return 0;
}

int usb_storage_read(unsigned char *buff,int lba, int blk_count)
{
	int res;
	int bc,n;

	res = usb_storage_init();
	RETURN_ON_ERROR(res);

	bc = 0;
	while(bc < blk_count){
		n = min(256,(blk_count-bc));
		res = usb_mass_ufi_read_10( lba+bc, (uchar_ptr)buff+bc*g_mass_blen, n* g_mass_blen, n);
	RETURN_ON_ERROR(res);
		bc += n;
	}

	return 0;
}

int usb_storage_write(unsigned char *buff, int lba, int blk_count)
{
	int res;
	int bc,n;

		bc = 0;
	res = usb_storage_init();
	RETURN_ON_ERROR(res);

	while(bc < blk_count){
		n = min(256,(blk_count-bc));
		res = usb_mass_ufi_write_10(lba+bc, (uchar_ptr)buff+bc*g_mass_blen, n* g_mass_blen, n);
	RETURN_ON_ERROR(res);
		bc+= n;
	}

	return 0;
}
