/* Driver for Realtek RTS51xx USB card reader
 *
 * Copyright(c) 2009 Realtek Semiconductor Corp. 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 as published by the
 * Free Software Foundation; either version 2, or (at your option) any
 * later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, see <http://www.gnu.org/licenses/>.
 *
 * Author:
 *   wwang (wei_wang@realsil.com.cn)
 *   No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
 * Maintainer:
 *   Edwin Rong (edwin_rong@realsil.com.cn)
 *   No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
 */

#include "rts51x.h"

#ifdef SUPPORT_FILE_OP

#include <linux/types.h>
#include <linux/stat.h>
#include <linux/kref.h>
#include <linux/slab.h>

#include "rts51x_chip.h"
#include "rts51x_card.h"
#include "rts51x_fop.h"
#include "sd_cprm.h"
#include "rts51x.h"

#define RTS5139_IOC_MAGIC		0x39

#define RTS5139_IOC_SD_DIRECT		_IOWR(RTS5139_IOC_MAGIC, 0xA0, int)
#define RTS5139_IOC_SD_GET_RSP		_IOWR(RTS5139_IOC_MAGIC, 0xA1, int)

static int rts51x_sd_direct_cmnd(struct rts51x_chip *chip,
				 struct sd_direct_cmnd *cmnd)
{
	int retval;
	u8 dir, cmd12, standby, acmd, cmd_idx, rsp_code;
	u8 *buf;
	u32 arg, len;

	dir = (cmnd->cmnd[0] >> 3) & 0x03;
	cmd12 = (cmnd->cmnd[0] >> 2) & 0x01;
	standby = (cmnd->cmnd[0] >> 1) & 0x01;
	acmd = cmnd->cmnd[0] & 0x01;
	cmd_idx = cmnd->cmnd[1];
	arg = ((u32) (cmnd->cmnd[2]) << 24) | ((u32) (cmnd->cmnd[3]) << 16) |
	    ((u32) (cmnd->cmnd[4]) << 8) | cmnd->cmnd[5];
	len =
	    ((u32) (cmnd->cmnd[6]) << 16) | ((u32) (cmnd->cmnd[7]) << 8) |
	    cmnd->cmnd[8];
	rsp_code = cmnd->cmnd[9];

	if (dir) {
		if (!cmnd->buf || (cmnd->buf_len < len))
			TRACE_RET(chip, STATUS_FAIL);
	}

	switch (dir) {
	case 0:
		/* No data */
		retval = ext_sd_execute_no_data(chip, chip->card2lun[SD_CARD],
						cmd_idx, standby, acmd,
						rsp_code, arg);
		if (retval != TRANSPORT_GOOD)
			TRACE_RET(chip, STATUS_FAIL);
		break;

	case 1:
		/* Read from card */
		buf = kmalloc(cmnd->buf_len, GFP_KERNEL);
		if (!buf)
			TRACE_RET(chip, STATUS_NOMEM);

		retval = ext_sd_execute_read_data(chip, chip->card2lun[SD_CARD],
						  cmd_idx, cmd12, standby, acmd,
						  rsp_code, arg, len, buf,
						  cmnd->buf_len, 0);
		if (retval != TRANSPORT_GOOD) {
			kfree(buf);
			TRACE_RET(chip, STATUS_FAIL);
		}

		retval =
		    copy_to_user((void *)cmnd->buf, (void *)buf, cmnd->buf_len);
		if (retval) {
			kfree(buf);
			TRACE_RET(chip, STATUS_NOMEM);
		}

		kfree(buf);
		break;

	case 2:
		/* Write to card */
		buf = kmalloc(cmnd->buf_len, GFP_KERNEL);
		if (!buf)
			TRACE_RET(chip, STATUS_NOMEM);

		retval =
		    copy_from_user((void *)buf, (void *)cmnd->buf,
				   cmnd->buf_len);
		if (retval) {
			kfree(buf);
			TRACE_RET(chip, STATUS_NOMEM);
		}

		retval =
		    ext_sd_execute_write_data(chip, chip->card2lun[SD_CARD],
					      cmd_idx, cmd12, standby, acmd,
					      rsp_code, arg, len, buf,
					      cmnd->buf_len, 0);
		if (retval != TRANSPORT_GOOD) {
			kfree(buf);
			TRACE_RET(chip, STATUS_FAIL);
		}

		kfree(buf);

		break;

	default:
		TRACE_RET(chip, STATUS_FAIL);
	}

	return STATUS_SUCCESS;
}

static int rts51x_sd_get_rsp(struct rts51x_chip *chip, struct sd_rsp *rsp)
{
	struct sd_info *sd_card = &(chip->sd_card);
	int count = 0, retval;

	if (sd_card->pre_cmd_err) {
		sd_card->pre_cmd_err = 0;
		TRACE_RET(chip, STATUS_FAIL);
	}

	if (sd_card->last_rsp_type == SD_RSP_TYPE_R0)
		TRACE_RET(chip, STATUS_FAIL);
	else if (sd_card->last_rsp_type == SD_RSP_TYPE_R2)
		count = (rsp->rsp_len < 17) ? rsp->rsp_len : 17;
	else
		count = (rsp->rsp_len < 6) ? rsp->rsp_len : 6;

	retval = copy_to_user((void *)rsp->rsp, (void *)sd_card->rsp, count);
	if (retval)
		TRACE_RET(chip, STATUS_NOMEM);

	RTS51X_DEBUGP("Response length: %d\n", count);
	RTS51X_DEBUGP("Response: 0x%x 0x%x 0x%x 0x%x\n",
		       sd_card->rsp[0], sd_card->rsp[1], sd_card->rsp[2],
		       sd_card->rsp[3]);

	return STATUS_SUCCESS;
}

int rts51x_open(struct inode *inode, struct file *filp)
{
	struct rts51x_chip *chip;
	struct usb_interface *interface;
	int subminor;
	int retval = 0;

	subminor = iminor(inode);

	interface = usb_find_interface(&rts51x_driver, subminor);
	if (!interface) {
		RTS51X_DEBUGP("%s - error, can't find device for minor %d\n",
			       __func__, subminor);
		retval = -ENODEV;
		goto exit;
	}

	chip = (struct rts51x_chip *)usb_get_intfdata(interface);
	if (!chip) {
		RTS51X_DEBUGP("Can't find chip\n");
		retval = -ENODEV;
		goto exit;
	}

	/* Increase our reference to the host */
	scsi_host_get(rts51x_to_host(chip));

	/* lock the device pointers */
	mutex_lock(&(chip->usb->dev_mutex));

	/* save our object in the file's private structure */
	filp->private_data = chip;

	/* unlock the device pointers */
	mutex_unlock(&chip->usb->dev_mutex);

exit:
	return retval;
}

int rts51x_release(struct inode *inode, struct file *filp)
{
	struct rts51x_chip *chip;

	chip = (struct rts51x_chip *)filp->private_data;
	if (chip == NULL)
		return -ENODEV;

	/* Drop our reference to the host; the SCSI core will free it
	 * (and "chip" along with it) when the refcount becomes 0. */
	scsi_host_put(rts51x_to_host(chip));

	return 0;
}

ssize_t rts51x_read(struct file *filp, char __user *buf, size_t count,
		    loff_t *f_pos)
{
	return 0;
}

ssize_t rts51x_write(struct file *filp, const char __user *buf, size_t count,
		     loff_t *f_pos)
{
	return 0;
}

#if 0 /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36) */
int rts51x_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
		 unsigned long arg)
#else
long rts51x_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
#endif
{
	struct rts51x_chip *chip;
	struct sd_direct_cmnd cmnd;
	struct sd_rsp rsp;
	int retval = 0;

	chip = (struct rts51x_chip *)filp->private_data;
	if (chip == NULL)
		return -ENODEV;

	/* lock the device pointers */
	mutex_lock(&(chip->usb->dev_mutex));

	switch (cmd) {
	case RTS5139_IOC_SD_DIRECT:
		retval =
		    copy_from_user((void *)&cmnd, (void *)arg,
				   sizeof(struct sd_direct_cmnd));
		if (retval) {
			retval = -ENOMEM;
			TRACE_GOTO(chip, exit);
		}
		retval = rts51x_sd_direct_cmnd(chip, &cmnd);
		if (retval != STATUS_SUCCESS) {
			retval = -EIO;
			TRACE_GOTO(chip, exit);
		}
		break;

	case RTS5139_IOC_SD_GET_RSP:
		retval =
		    copy_from_user((void *)&rsp, (void *)arg,
				   sizeof(struct sd_rsp));
		if (retval) {
			retval = -ENOMEM;
			TRACE_GOTO(chip, exit);
		}
		retval = rts51x_sd_get_rsp(chip, &rsp);
		if (retval != STATUS_SUCCESS) {
			retval = -EIO;
			TRACE_GOTO(chip, exit);
		}
		break;

	default:
		break;
	}

exit:
	/* unlock the device pointers */
	mutex_unlock(&chip->usb->dev_mutex);

	return retval;
}

#endif
