// SPDX-License-Identifier: GPL-2.0
#include <scsi/scsi.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h>
#include <linux/usb.h>
#include <linux/module.h>
#include <linux/slab.h>

#include "usb.h"
#include "transport.h"
#include "protocol.h"
#include "scsiglue.h"
#include "sierra_ms.h"
#include "debug.h"

#define SWIMS_USB_REQUEST_SetSwocMode	0x0B
#define SWIMS_USB_REQUEST_GetSwocInfo	0x0A
#define SWIMS_USB_INDEX_SetMode		0x0000
#define SWIMS_SET_MODE_Modem		0x0001

#define TRU_NORMAL 			0x01
#define TRU_FORCE_MS 			0x02
#define TRU_FORCE_MODEM 		0x03

static unsigned int swi_tru_install = 1;
module_param(swi_tru_install, uint, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(swi_tru_install, "TRU-Install mode (1=Full Logic (def),"
		 " 2=Force CD-Rom, 3=Force Modem)");

struct swoc_info {
	__u8 rev;
	__u8 reserved[8];
	__u16 LinuxSKU;
	__u16 LinuxVer;
	__u8 reserved2[47];
} __attribute__((__packed__));

static bool containsFullLinuxPackage(struct swoc_info *swocInfo)
{
	if ((swocInfo->LinuxSKU >= 0x2100 && swocInfo->LinuxSKU <= 0x2FFF) ||
	   (swocInfo->LinuxSKU >= 0x7100 && swocInfo->LinuxSKU <= 0x7FFF))
		return true;
	else
		return false;
}

static int sierra_set_ms_mode(struct usb_device *udev, __u16 eSWocMode)
{
	int result;
	dev_dbg(&udev->dev, "SWIMS: %s", "DEVICE MODE SWITCH\n");
	result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
			SWIMS_USB_REQUEST_SetSwocMode,	/* __u8 request      */
			USB_TYPE_VENDOR | USB_DIR_OUT,	/* __u8 request type */
			eSWocMode,			/* __u16 value       */
			0x0000,				/* __u16 index       */
			NULL,				/* void *data        */
			0,				/* __u16 size 	     */
			USB_CTRL_SET_TIMEOUT);		/* int timeout       */
	return result;
}


static int sierra_get_swoc_info(struct usb_device *udev,
				struct swoc_info *swocInfo)
{
	int result;

	dev_dbg(&udev->dev, "SWIMS: Attempting to get TRU-Install info\n");

	result = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
			SWIMS_USB_REQUEST_GetSwocInfo,	/* __u8 request      */
			USB_TYPE_VENDOR | USB_DIR_IN,	/* __u8 request type */
			0,				/* __u16 value       */
			0,				/* __u16 index       */
			(void *) swocInfo,		/* void *data        */
			sizeof(struct swoc_info),	/* __u16 size 	     */
			USB_CTRL_SET_TIMEOUT);		/* int timeout 	     */

	swocInfo->LinuxSKU = le16_to_cpu(swocInfo->LinuxSKU);
	swocInfo->LinuxVer = le16_to_cpu(swocInfo->LinuxVer);
	return result;
}

static void debug_swoc(const struct device *dev, struct swoc_info *swocInfo)
{
	dev_dbg(dev, "SWIMS: SWoC Rev: %02d\n", swocInfo->rev);
	dev_dbg(dev, "SWIMS: Linux SKU: %04X\n", swocInfo->LinuxSKU);
	dev_dbg(dev, "SWIMS: Linux Version: %04X\n", swocInfo->LinuxVer);
}


static ssize_t truinst_show(struct device *dev, struct device_attribute *attr,
			char *buf)
{
	struct swoc_info *swocInfo;
	struct usb_interface *intf = to_usb_interface(dev);
	struct usb_device *udev = interface_to_usbdev(intf);
	int result;
	if (swi_tru_install == TRU_FORCE_MS) {
		result = sysfs_emit(buf, "Forced Mass Storage\n");
	} else {
		swocInfo = kmalloc(sizeof(struct swoc_info), GFP_KERNEL);
		if (!swocInfo) {
			sysfs_emit(buf, "Error\n");
			return -ENOMEM;
		}
		result = sierra_get_swoc_info(udev, swocInfo);
		if (result < 0) {
			dev_dbg(dev, "SWIMS: failed SWoC query\n");
			kfree(swocInfo);
			sysfs_emit(buf, "Error\n");
			return -EIO;
		}
		debug_swoc(dev, swocInfo);
		result = sysfs_emit(buf,
				    "REV=%02d SKU=%04X VER=%04X\n",
				    swocInfo->rev,
				    swocInfo->LinuxSKU,
				    swocInfo->LinuxVer);
		kfree(swocInfo);
	}
	return result;
}
static DEVICE_ATTR_RO(truinst);

int sierra_ms_init(struct us_data *us)
{
	int result, retries;
	struct swoc_info *swocInfo;
	struct usb_device *udev;

	udev = us->pusb_dev;

	/* Force Modem mode */
	if (swi_tru_install == TRU_FORCE_MODEM) {
		usb_stor_dbg(us, "SWIMS: Forcing Modem Mode\n");
		result = sierra_set_ms_mode(udev, SWIMS_SET_MODE_Modem);
		if (result < 0)
			usb_stor_dbg(us, "SWIMS: Failed to switch to modem mode\n");
		return -EIO;
	}
	/* Force Mass Storage mode (keep CD-Rom) */
	else if (swi_tru_install == TRU_FORCE_MS) {
		usb_stor_dbg(us, "SWIMS: Forcing Mass Storage Mode\n");
		goto complete;
	}
	/* Normal TRU-Install Logic */
	else {
		usb_stor_dbg(us, "SWIMS: Normal SWoC Logic\n");

		swocInfo = kmalloc(sizeof(struct swoc_info),
				GFP_KERNEL);
		if (!swocInfo)
			return -ENOMEM;

		retries = 3;
		do {
			retries--;
			result = sierra_get_swoc_info(udev, swocInfo);
			if (result < 0) {
				usb_stor_dbg(us, "SWIMS: Failed SWoC query\n");
				schedule_timeout_uninterruptible(2*HZ);
			}
		} while (retries && result < 0);

		if (result < 0) {
			usb_stor_dbg(us, "SWIMS: Completely failed SWoC query\n");
			kfree(swocInfo);
			return -EIO;
		}

		debug_swoc(&us->pusb_dev->dev, swocInfo);

		/*
		 * If there is not Linux software on the TRU-Install device
		 * then switch to modem mode
		 */
		if (!containsFullLinuxPackage(swocInfo)) {
			usb_stor_dbg(us, "SWIMS: Switching to Modem Mode\n");
			result = sierra_set_ms_mode(udev,
				SWIMS_SET_MODE_Modem);
			if (result < 0)
				usb_stor_dbg(us, "SWIMS: Failed to switch modem\n");
			kfree(swocInfo);
			return -EIO;
		}
		kfree(swocInfo);
	}
complete:
	return device_create_file(&us->pusb_intf->dev, &dev_attr_truinst);
}

