/* 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"

#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_rts51x_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 = kzalloc(cmnd->buf_len, GFP_KERNEL);
		if (!buf)
			TRACE_RET(chip, STATUS_NOMEM);

		retval = ext_rts51x_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_rts51x_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;
}

long rts51x_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
	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
