#include <linux/sched.h>
#include <linux/errno.h>
#include <linux/slab.h>

#include <scsi/scsi.h>
#include <scsi/scsi_eh.h>
#include <scsi/scsi_device.h>

#include "usb.h"
#include "scsiglue.h"
#include "transport.h"
#include "smil.h"

int SM_SCSI_Test_Unit_Ready(struct us_data *us, struct scsi_cmnd *srb);
int SM_SCSI_Inquiry(struct us_data *us, struct scsi_cmnd *srb);
int SM_SCSI_Mode_Sense(struct us_data *us, struct scsi_cmnd *srb);
int SM_SCSI_Start_Stop(struct us_data *us, struct scsi_cmnd *srb);
int SM_SCSI_Read_Capacity(struct us_data *us, struct scsi_cmnd *srb);
int SM_SCSI_Read(struct us_data *us, struct scsi_cmnd *srb);
int SM_SCSI_Write(struct us_data *us, struct scsi_cmnd *srb);

extern PBYTE                SMHostAddr;
extern DWORD                ErrXDCode;

/* ----- SM_SCSIIrp() -------------------------------------------------- */
int SM_SCSIIrp(struct us_data *us, struct scsi_cmnd *srb)
{
	int    result;

	us->SrbStatus = SS_SUCCESS;
	switch (srb->cmnd[0]) {
	case TEST_UNIT_READY:
		result = SM_SCSI_Test_Unit_Ready(us, srb);
		break;		/* 0x00 */
	case INQUIRY:
		result = SM_SCSI_Inquiry(us, srb);
		break;		/* 0x12 */
	case MODE_SENSE:
		result = SM_SCSI_Mode_Sense(us, srb);
		break;		/* 0x1A */
	case READ_CAPACITY:
		result = SM_SCSI_Read_Capacity(us, srb);
		break;		/* 0x25 */
	case READ_10:
		result = SM_SCSI_Read(us, srb);
		break;		/* 0x28 */
	case WRITE_10:
		result = SM_SCSI_Write(us, srb);
		break;		/* 0x2A */

	default:
			us->SrbStatus = SS_ILLEGAL_REQUEST;
			result = USB_STOR_TRANSPORT_FAILED;
			break;
	}
	return result;
}

/* ----- SM_SCSI_Test_Unit_Ready() ------------------------------------- */
int SM_SCSI_Test_Unit_Ready(struct us_data *us, struct scsi_cmnd *srb)
{
	if (us->SM_Status.Insert && us->SM_Status.Ready)
		return USB_STOR_TRANSPORT_GOOD;
	else {
		ENE_SMInit(us);
		return USB_STOR_TRANSPORT_GOOD;
	}

	return USB_STOR_TRANSPORT_GOOD;
}

/* ----- SM_SCSI_Inquiry() --------------------------------------------- */
int SM_SCSI_Inquiry(struct us_data *us, struct scsi_cmnd *srb)
{
	BYTE data_ptr[36] = {0x00, 0x80, 0x02, 0x00, 0x1F, 0x00, 0x00, 0x00,
				 0x55, 0x53, 0x42, 0x32, 0x2E, 0x30, 0x20,
				 0x20, 0x43, 0x61, 0x72, 0x64, 0x52, 0x65,
				 0x61, 0x64, 0x65, 0x72, 0x20, 0x20, 0x20,
				 0x20, 0x20, 0x20, 0x30, 0x31, 0x30, 0x30};

	usb_stor_set_xfer_buf(us, data_ptr, 36, srb, TO_XFER_BUF);
	return USB_STOR_TRANSPORT_GOOD;
}


/* ----- SM_SCSI_Mode_Sense() ------------------------------------------ */
int SM_SCSI_Mode_Sense(struct us_data *us, struct scsi_cmnd *srb)
{
	BYTE	mediaNoWP[12] = {0x0b, 0x00, 0x00, 0x08, 0x00, 0x00,
				0x71, 0xc0, 0x00, 0x00, 0x02, 0x00};
	BYTE	mediaWP[12]   = {0x0b, 0x00, 0x80, 0x08, 0x00, 0x00,
				0x71, 0xc0, 0x00, 0x00, 0x02, 0x00};

	if (us->SM_Status.WtP)
		usb_stor_set_xfer_buf(us, mediaWP, 12, srb, TO_XFER_BUF);
	else
		usb_stor_set_xfer_buf(us, mediaNoWP, 12, srb, TO_XFER_BUF);


	return USB_STOR_TRANSPORT_GOOD;
}

/* ----- SM_SCSI_Read_Capacity() --------------------------------------- */
int SM_SCSI_Read_Capacity(struct us_data *us, struct scsi_cmnd *srb)
{
	unsigned int offset = 0;
	struct scatterlist *sg = NULL;
	DWORD   bl_num;
	WORD    bl_len;
	BYTE    buf[8];

	dev_dbg(&us->pusb_dev->dev, "SM_SCSI_Read_Capacity\n");

	bl_len = 0x200;
	bl_num = Ssfdc.MaxLogBlocks * Ssfdc.MaxSectors * Ssfdc.MaxZones - 1;

	us->bl_num = bl_num;
	dev_dbg(&us->pusb_dev->dev, "bl_len = %x\n", bl_len);
	dev_dbg(&us->pusb_dev->dev, "bl_num = %x\n", bl_num);

	buf[0] = (bl_num >> 24) & 0xff;
	buf[1] = (bl_num >> 16) & 0xff;
	buf[2] = (bl_num >> 8) & 0xff;
	buf[3] = (bl_num >> 0) & 0xff;
	buf[4] = (bl_len >> 24) & 0xff;
	buf[5] = (bl_len >> 16) & 0xff;
	buf[6] = (bl_len >> 8) & 0xff;
	buf[7] = (bl_len >> 0) & 0xff;

	usb_stor_access_xfer_buf(us, buf, 8, srb, &sg, &offset, TO_XFER_BUF);

	return USB_STOR_TRANSPORT_GOOD;
}

/* ----- SM_SCSI_Read() -------------------------------------------------- */
int SM_SCSI_Read(struct us_data *us, struct scsi_cmnd *srb)
{
	int result = 0;
	PBYTE	Cdb = srb->cmnd;
	DWORD bn  =  ((Cdb[2] << 24) & 0xff000000) |
			((Cdb[3] << 16) & 0x00ff0000) |
			((Cdb[4] << 8) & 0x0000ff00) |
			((Cdb[5] << 0) & 0x000000ff);
	WORD  blen = ((Cdb[7] << 8) & 0xff00)     | ((Cdb[8] << 0) & 0x00ff);
	DWORD	blenByte = blen * 0x200;
	void	*buf;


	if (bn > us->bl_num)
		return USB_STOR_TRANSPORT_ERROR;

	buf = kmalloc(blenByte, GFP_KERNEL);
	if (buf == NULL)
		return USB_STOR_TRANSPORT_ERROR;
	result = Media_D_ReadSector(us, bn, blen, buf);
	usb_stor_set_xfer_buf(us, buf, blenByte, srb, TO_XFER_BUF);
	kfree(buf);

	if (!result)
		return USB_STOR_TRANSPORT_GOOD;
	else
		return USB_STOR_TRANSPORT_ERROR;

	return USB_STOR_TRANSPORT_GOOD;
}

/* ----- SM_SCSI_Write() -------------------------------------------------- */
int SM_SCSI_Write(struct us_data *us, struct scsi_cmnd *srb)
{
	int result = 0;
	PBYTE	Cdb = srb->cmnd;
	DWORD bn  =  ((Cdb[2] << 24) & 0xff000000) |
			((Cdb[3] << 16) & 0x00ff0000) |
			((Cdb[4] << 8) & 0x0000ff00) |
			((Cdb[5] << 0) & 0x000000ff);
	WORD  blen = ((Cdb[7] << 8) & 0xff00)     | ((Cdb[8] << 0) & 0x00ff);
	DWORD	blenByte = blen * 0x200;
	void	*buf;


	if (bn > us->bl_num)
		return USB_STOR_TRANSPORT_ERROR;

	buf = kmalloc(blenByte, GFP_KERNEL);
	if (buf == NULL)
		return USB_STOR_TRANSPORT_ERROR;
	usb_stor_set_xfer_buf(us, buf, blenByte, srb, FROM_XFER_BUF);
	result = Media_D_CopySector(us, bn, blen, buf);
	kfree(buf);

	if (!result)
		return USB_STOR_TRANSPORT_GOOD;
	else
		return USB_STOR_TRANSPORT_ERROR;

	return USB_STOR_TRANSPORT_GOOD;
}

