/*
 * Driver for Alauda-based card readers
 *
 * Current development and maintenance by:
 *   (c) 2005 Daniel Drake <dsd@gentoo.org>
 *
 * The 'Alauda' is a chip manufacturered by RATOC for OEM use.
 *
 * Alauda implements a vendor-specific command set to access two media reader
 * ports (XD, SmartMedia). This driver converts SCSI commands to the commands
 * which are accepted by these devices.
 *
 * The driver was developed through reverse-engineering, with the help of the
 * sddr09 driver which has many similarities, and with some help from the
 * (very old) vendor-supplied GPL sma03 driver.
 *
 * For protocol info, see http://alauda.sourceforge.net
 *
 * 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, write to the Free Software Foundation, Inc.,
 * 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <linux/module.h>
#include <linux/slab.h>

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

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

MODULE_DESCRIPTION("Driver for Alauda-based card readers");
MODULE_AUTHOR("Daniel Drake <dsd@gentoo.org>");
MODULE_LICENSE("GPL");

/*
 * Status bytes
 */
#define ALAUDA_STATUS_ERROR		0x01
#define ALAUDA_STATUS_READY		0x40

/*
 * Control opcodes (for request field)
 */
#define ALAUDA_GET_XD_MEDIA_STATUS	0x08
#define ALAUDA_GET_SM_MEDIA_STATUS	0x98
#define ALAUDA_ACK_XD_MEDIA_CHANGE	0x0a
#define ALAUDA_ACK_SM_MEDIA_CHANGE	0x9a
#define ALAUDA_GET_XD_MEDIA_SIG		0x86
#define ALAUDA_GET_SM_MEDIA_SIG		0x96

/*
 * Bulk command identity (byte 0)
 */
#define ALAUDA_BULK_CMD			0x40

/*
 * Bulk opcodes (byte 1)
 */
#define ALAUDA_BULK_GET_REDU_DATA	0x85
#define ALAUDA_BULK_READ_BLOCK		0x94
#define ALAUDA_BULK_ERASE_BLOCK		0xa3
#define ALAUDA_BULK_WRITE_BLOCK		0xb4
#define ALAUDA_BULK_GET_STATUS2		0xb7
#define ALAUDA_BULK_RESET_MEDIA		0xe0

/*
 * Port to operate on (byte 8)
 */
#define ALAUDA_PORT_XD			0x00
#define ALAUDA_PORT_SM			0x01

/*
 * LBA and PBA are unsigned ints. Special values.
 */
#define UNDEF    0xffff
#define SPARE    0xfffe
#define UNUSABLE 0xfffd

struct alauda_media_info {
	unsigned long capacity;		/* total media size in bytes */
	unsigned int pagesize;		/* page size in bytes */
	unsigned int blocksize;		/* number of pages per block */
	unsigned int uzonesize;		/* number of usable blocks per zone */
	unsigned int zonesize;		/* number of blocks per zone */
	unsigned int blockmask;		/* mask to get page from address */

	unsigned char pageshift;
	unsigned char blockshift;
	unsigned char zoneshift;

	u16 **lba_to_pba;		/* logical to physical block map */
	u16 **pba_to_lba;		/* physical to logical block map */
};

struct alauda_info {
	struct alauda_media_info port[2];
	int wr_ep;			/* endpoint to write data out of */

	unsigned char sense_key;
	unsigned long sense_asc;	/* additional sense code */
	unsigned long sense_ascq;	/* additional sense code qualifier */
};

#define short_pack(lsb,msb) ( ((u16)(lsb)) | ( ((u16)(msb))<<8 ) )
#define LSB_of(s) ((s)&0xFF)
#define MSB_of(s) ((s)>>8)

#define MEDIA_PORT(us) us->srb->device->lun
#define MEDIA_INFO(us) ((struct alauda_info *)us->extra)->port[MEDIA_PORT(us)]

#define PBA_LO(pba) ((pba & 0xF) << 5)
#define PBA_HI(pba) (pba >> 3)
#define PBA_ZONE(pba) (pba >> 11)

static int init_alauda(struct us_data *us);


/*
 * The table of devices
 */
#define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
		    vendorName, productName, useProtocol, useTransport, \
		    initFunction, flags) \
{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \
  .driver_info = (flags) }

static struct usb_device_id alauda_usb_ids[] = {
#	include "unusual_alauda.h"
	{ }		/* Terminating entry */
};
MODULE_DEVICE_TABLE(usb, alauda_usb_ids);

#undef UNUSUAL_DEV

/*
 * The flags table
 */
#define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \
		    vendor_name, product_name, use_protocol, use_transport, \
		    init_function, Flags) \
{ \
	.vendorName = vendor_name,	\
	.productName = product_name,	\
	.useProtocol = use_protocol,	\
	.useTransport = use_transport,	\
	.initFunction = init_function,	\
}

static struct us_unusual_dev alauda_unusual_dev_list[] = {
#	include "unusual_alauda.h"
	{ }		/* Terminating entry */
};

#undef UNUSUAL_DEV


/*
 * Media handling
 */

struct alauda_card_info {
	unsigned char id;		/* id byte */
	unsigned char chipshift;	/* 1<<cs bytes total capacity */
	unsigned char pageshift;	/* 1<<ps bytes in a page */
	unsigned char blockshift;	/* 1<<bs pages per block */
	unsigned char zoneshift;	/* 1<<zs blocks per zone */
};

static struct alauda_card_info alauda_card_ids[] = {
	/* NAND flash */
	{ 0x6e, 20, 8, 4, 8},	/* 1 MB */
	{ 0xe8, 20, 8, 4, 8},	/* 1 MB */
	{ 0xec, 20, 8, 4, 8},	/* 1 MB */
	{ 0x64, 21, 8, 4, 9}, 	/* 2 MB */
	{ 0xea, 21, 8, 4, 9},	/* 2 MB */
	{ 0x6b, 22, 9, 4, 9},	/* 4 MB */
	{ 0xe3, 22, 9, 4, 9},	/* 4 MB */
	{ 0xe5, 22, 9, 4, 9},	/* 4 MB */
	{ 0xe6, 23, 9, 4, 10},	/* 8 MB */
	{ 0x73, 24, 9, 5, 10},	/* 16 MB */
	{ 0x75, 25, 9, 5, 10},	/* 32 MB */
	{ 0x76, 26, 9, 5, 10},	/* 64 MB */
	{ 0x79, 27, 9, 5, 10},	/* 128 MB */
	{ 0x71, 28, 9, 5, 10},	/* 256 MB */

	/* MASK ROM */
	{ 0x5d, 21, 9, 4, 8},	/* 2 MB */
	{ 0xd5, 22, 9, 4, 9},	/* 4 MB */
	{ 0xd6, 23, 9, 4, 10},	/* 8 MB */
	{ 0x57, 24, 9, 4, 11},	/* 16 MB */
	{ 0x58, 25, 9, 4, 12},	/* 32 MB */
	{ 0,}
};

static struct alauda_card_info *alauda_card_find_id(unsigned char id) {
	int i;

	for (i = 0; alauda_card_ids[i].id != 0; i++)
		if (alauda_card_ids[i].id == id)
			return &(alauda_card_ids[i]);
	return NULL;
}

/*
 * ECC computation.
 */

static unsigned char parity[256];
static unsigned char ecc2[256];

static void nand_init_ecc(void) {
	int i, j, a;

	parity[0] = 0;
	for (i = 1; i < 256; i++)
		parity[i] = (parity[i&(i-1)] ^ 1);

	for (i = 0; i < 256; i++) {
		a = 0;
		for (j = 0; j < 8; j++) {
			if (i & (1<<j)) {
				if ((j & 1) == 0)
					a ^= 0x04;
				if ((j & 2) == 0)
					a ^= 0x10;
				if ((j & 4) == 0)
					a ^= 0x40;
			}
		}
		ecc2[i] = ~(a ^ (a<<1) ^ (parity[i] ? 0xa8 : 0));
	}
}

/* compute 3-byte ecc on 256 bytes */
static void nand_compute_ecc(unsigned char *data, unsigned char *ecc) {
	int i, j, a;
	unsigned char par = 0, bit, bits[8] = {0};

	/* collect 16 checksum bits */
	for (i = 0; i < 256; i++) {
		par ^= data[i];
		bit = parity[data[i]];
		for (j = 0; j < 8; j++)
			if ((i & (1<<j)) == 0)
				bits[j] ^= bit;
	}

	/* put 4+4+4 = 12 bits in the ecc */
	a = (bits[3] << 6) + (bits[2] << 4) + (bits[1] << 2) + bits[0];
	ecc[0] = ~(a ^ (a<<1) ^ (parity[par] ? 0xaa : 0));

	a = (bits[7] << 6) + (bits[6] << 4) + (bits[5] << 2) + bits[4];
	ecc[1] = ~(a ^ (a<<1) ^ (parity[par] ? 0xaa : 0));

	ecc[2] = ecc2[par];
}

static int nand_compare_ecc(unsigned char *data, unsigned char *ecc) {
	return (data[0] == ecc[0] && data[1] == ecc[1] && data[2] == ecc[2]);
}

static void nand_store_ecc(unsigned char *data, unsigned char *ecc) {
	memcpy(data, ecc, 3);
}

/*
 * Alauda driver
 */

/*
 * Forget our PBA <---> LBA mappings for a particular port
 */
static void alauda_free_maps (struct alauda_media_info *media_info)
{
	unsigned int shift = media_info->zoneshift
		+ media_info->blockshift + media_info->pageshift;
	unsigned int num_zones = media_info->capacity >> shift;
	unsigned int i;

	if (media_info->lba_to_pba != NULL)
		for (i = 0; i < num_zones; i++) {
			kfree(media_info->lba_to_pba[i]);
			media_info->lba_to_pba[i] = NULL;
		}

	if (media_info->pba_to_lba != NULL)
		for (i = 0; i < num_zones; i++) {
			kfree(media_info->pba_to_lba[i]);
			media_info->pba_to_lba[i] = NULL;
		}
}

/*
 * Returns 2 bytes of status data
 * The first byte describes media status, and second byte describes door status
 */
static int alauda_get_media_status(struct us_data *us, unsigned char *data)
{
	int rc;
	unsigned char command;

	if (MEDIA_PORT(us) == ALAUDA_PORT_XD)
		command = ALAUDA_GET_XD_MEDIA_STATUS;
	else
		command = ALAUDA_GET_SM_MEDIA_STATUS;

	rc = usb_stor_ctrl_transfer(us, us->recv_ctrl_pipe,
		command, 0xc0, 0, 1, data, 2);

	usb_stor_dbg(us, "Media status %02X %02X\n", data[0], data[1]);

	return rc;
}

/*
 * Clears the "media was changed" bit so that we know when it changes again
 * in the future.
 */
static int alauda_ack_media(struct us_data *us)
{
	unsigned char command;

	if (MEDIA_PORT(us) == ALAUDA_PORT_XD)
		command = ALAUDA_ACK_XD_MEDIA_CHANGE;
	else
		command = ALAUDA_ACK_SM_MEDIA_CHANGE;

	return usb_stor_ctrl_transfer(us, us->send_ctrl_pipe,
		command, 0x40, 0, 1, NULL, 0);
}

/*
 * Retrieves a 4-byte media signature, which indicates manufacturer, capacity,
 * and some other details.
 */
static int alauda_get_media_signature(struct us_data *us, unsigned char *data)
{
	unsigned char command;

	if (MEDIA_PORT(us) == ALAUDA_PORT_XD)
		command = ALAUDA_GET_XD_MEDIA_SIG;
	else
		command = ALAUDA_GET_SM_MEDIA_SIG;

	return usb_stor_ctrl_transfer(us, us->recv_ctrl_pipe,
		command, 0xc0, 0, 0, data, 4);
}

/*
 * Resets the media status (but not the whole device?)
 */
static int alauda_reset_media(struct us_data *us)
{
	unsigned char *command = us->iobuf;

	memset(command, 0, 9);
	command[0] = ALAUDA_BULK_CMD;
	command[1] = ALAUDA_BULK_RESET_MEDIA;
	command[8] = MEDIA_PORT(us);

	return usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe,
		command, 9, NULL);
}

/*
 * Examines the media and deduces capacity, etc.
 */
static int alauda_init_media(struct us_data *us)
{
	unsigned char *data = us->iobuf;
	int ready = 0;
	struct alauda_card_info *media_info;
	unsigned int num_zones;

	while (ready == 0) {
		msleep(20);

		if (alauda_get_media_status(us, data) != USB_STOR_XFER_GOOD)
			return USB_STOR_TRANSPORT_ERROR;

		if (data[0] & 0x10)
			ready = 1;
	}

	usb_stor_dbg(us, "We are ready for action!\n");

	if (alauda_ack_media(us) != USB_STOR_XFER_GOOD)
		return USB_STOR_TRANSPORT_ERROR;

	msleep(10);

	if (alauda_get_media_status(us, data) != USB_STOR_XFER_GOOD)
		return USB_STOR_TRANSPORT_ERROR;

	if (data[0] != 0x14) {
		usb_stor_dbg(us, "Media not ready after ack\n");
		return USB_STOR_TRANSPORT_ERROR;
	}

	if (alauda_get_media_signature(us, data) != USB_STOR_XFER_GOOD)
		return USB_STOR_TRANSPORT_ERROR;

	usb_stor_dbg(us, "Media signature: %02X %02X %02X %02X\n",
		     data[0], data[1], data[2], data[3]);
	media_info = alauda_card_find_id(data[1]);
	if (media_info == NULL) {
		printk(KERN_WARNING
			"alauda_init_media: Unrecognised media signature: "
			"%02X %02X %02X %02X\n",
			data[0], data[1], data[2], data[3]);
		return USB_STOR_TRANSPORT_ERROR;
	}

	MEDIA_INFO(us).capacity = 1 << media_info->chipshift;
	usb_stor_dbg(us, "Found media with capacity: %ldMB\n",
		     MEDIA_INFO(us).capacity >> 20);

	MEDIA_INFO(us).pageshift = media_info->pageshift;
	MEDIA_INFO(us).blockshift = media_info->blockshift;
	MEDIA_INFO(us).zoneshift = media_info->zoneshift;

	MEDIA_INFO(us).pagesize = 1 << media_info->pageshift;
	MEDIA_INFO(us).blocksize = 1 << media_info->blockshift;
	MEDIA_INFO(us).zonesize = 1 << media_info->zoneshift;

	MEDIA_INFO(us).uzonesize = ((1 << media_info->zoneshift) / 128) * 125;
	MEDIA_INFO(us).blockmask = MEDIA_INFO(us).blocksize - 1;

	num_zones = MEDIA_INFO(us).capacity >> (MEDIA_INFO(us).zoneshift
		+ MEDIA_INFO(us).blockshift + MEDIA_INFO(us).pageshift);
	MEDIA_INFO(us).pba_to_lba = kcalloc(num_zones, sizeof(u16*), GFP_NOIO);
	MEDIA_INFO(us).lba_to_pba = kcalloc(num_zones, sizeof(u16*), GFP_NOIO);

	if (alauda_reset_media(us) != USB_STOR_XFER_GOOD)
		return USB_STOR_TRANSPORT_ERROR;

	return USB_STOR_TRANSPORT_GOOD;
}

/*
 * Examines the media status and does the right thing when the media has gone,
 * appeared, or changed.
 */
static int alauda_check_media(struct us_data *us)
{
	struct alauda_info *info = (struct alauda_info *) us->extra;
	unsigned char status[2];
	int rc;

	rc = alauda_get_media_status(us, status);

	/* Check for no media or door open */
	if ((status[0] & 0x80) || ((status[0] & 0x1F) == 0x10)
		|| ((status[1] & 0x01) == 0)) {
		usb_stor_dbg(us, "No media, or door open\n");
		alauda_free_maps(&MEDIA_INFO(us));
		info->sense_key = 0x02;
		info->sense_asc = 0x3A;
		info->sense_ascq = 0x00;
		return USB_STOR_TRANSPORT_FAILED;
	}

	/* Check for media change */
	if (status[0] & 0x08) {
		usb_stor_dbg(us, "Media change detected\n");
		alauda_free_maps(&MEDIA_INFO(us));
		alauda_init_media(us);

		info->sense_key = UNIT_ATTENTION;
		info->sense_asc = 0x28;
		info->sense_ascq = 0x00;
		return USB_STOR_TRANSPORT_FAILED;
	}

	return USB_STOR_TRANSPORT_GOOD;
}

/*
 * Checks the status from the 2nd status register
 * Returns 3 bytes of status data, only the first is known
 */
static int alauda_check_status2(struct us_data *us)
{
	int rc;
	unsigned char command[] = {
		ALAUDA_BULK_CMD, ALAUDA_BULK_GET_STATUS2,
		0, 0, 0, 0, 3, 0, MEDIA_PORT(us)
	};
	unsigned char data[3];

	rc = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe,
		command, 9, NULL);
	if (rc != USB_STOR_XFER_GOOD)
		return rc;

	rc = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
		data, 3, NULL);
	if (rc != USB_STOR_XFER_GOOD)
		return rc;

	usb_stor_dbg(us, "%02X %02X %02X\n", data[0], data[1], data[2]);
	if (data[0] & ALAUDA_STATUS_ERROR)
		return USB_STOR_XFER_ERROR;

	return USB_STOR_XFER_GOOD;
}

/*
 * Gets the redundancy data for the first page of a PBA
 * Returns 16 bytes.
 */
static int alauda_get_redu_data(struct us_data *us, u16 pba, unsigned char *data)
{
	int rc;
	unsigned char command[] = {
		ALAUDA_BULK_CMD, ALAUDA_BULK_GET_REDU_DATA,
		PBA_HI(pba), PBA_ZONE(pba), 0, PBA_LO(pba), 0, 0, MEDIA_PORT(us)
	};

	rc = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe,
		command, 9, NULL);
	if (rc != USB_STOR_XFER_GOOD)
		return rc;

	return usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
		data, 16, NULL);
}

/*
 * Finds the first unused PBA in a zone
 * Returns the absolute PBA of an unused PBA, or 0 if none found.
 */
static u16 alauda_find_unused_pba(struct alauda_media_info *info,
	unsigned int zone)
{
	u16 *pba_to_lba = info->pba_to_lba[zone];
	unsigned int i;

	for (i = 0; i < info->zonesize; i++)
		if (pba_to_lba[i] == UNDEF)
			return (zone << info->zoneshift) + i;

	return 0;
}

/*
 * Reads the redundancy data for all PBA's in a zone
 * Produces lba <--> pba mappings
 */
static int alauda_read_map(struct us_data *us, unsigned int zone)
{
	unsigned char *data = us->iobuf;
	int result;
	int i, j;
	unsigned int zonesize = MEDIA_INFO(us).zonesize;
	unsigned int uzonesize = MEDIA_INFO(us).uzonesize;
	unsigned int lba_offset, lba_real, blocknum;
	unsigned int zone_base_lba = zone * uzonesize;
	unsigned int zone_base_pba = zone * zonesize;
	u16 *lba_to_pba = kcalloc(zonesize, sizeof(u16), GFP_NOIO);
	u16 *pba_to_lba = kcalloc(zonesize, sizeof(u16), GFP_NOIO);
	if (lba_to_pba == NULL || pba_to_lba == NULL) {
		result = USB_STOR_TRANSPORT_ERROR;
		goto error;
	}

	usb_stor_dbg(us, "Mapping blocks for zone %d\n", zone);

	/* 1024 PBA's per zone */
	for (i = 0; i < zonesize; i++)
		lba_to_pba[i] = pba_to_lba[i] = UNDEF;

	for (i = 0; i < zonesize; i++) {
		blocknum = zone_base_pba + i;

		result = alauda_get_redu_data(us, blocknum, data);
		if (result != USB_STOR_XFER_GOOD) {
			result = USB_STOR_TRANSPORT_ERROR;
			goto error;
		}

		/* special PBAs have control field 0^16 */
		for (j = 0; j < 16; j++)
			if (data[j] != 0)
				goto nonz;
		pba_to_lba[i] = UNUSABLE;
		usb_stor_dbg(us, "PBA %d has no logical mapping\n", blocknum);
		continue;

	nonz:
		/* unwritten PBAs have control field FF^16 */
		for (j = 0; j < 16; j++)
			if (data[j] != 0xff)
				goto nonff;
		continue;

	nonff:
		/* normal PBAs start with six FFs */
		if (j < 6) {
			usb_stor_dbg(us, "PBA %d has no logical mapping: reserved area = %02X%02X%02X%02X data status %02X block status %02X\n",
				     blocknum,
				     data[0], data[1], data[2], data[3],
				     data[4], data[5]);
			pba_to_lba[i] = UNUSABLE;
			continue;
		}

		if ((data[6] >> 4) != 0x01) {
			usb_stor_dbg(us, "PBA %d has invalid address field %02X%02X/%02X%02X\n",
				     blocknum, data[6], data[7],
				     data[11], data[12]);
			pba_to_lba[i] = UNUSABLE;
			continue;
		}

		/* check even parity */
		if (parity[data[6] ^ data[7]]) {
			printk(KERN_WARNING
			       "alauda_read_map: Bad parity in LBA for block %d"
			       " (%02X %02X)\n", i, data[6], data[7]);
			pba_to_lba[i] = UNUSABLE;
			continue;
		}

		lba_offset = short_pack(data[7], data[6]);
		lba_offset = (lba_offset & 0x07FF) >> 1;
		lba_real = lba_offset + zone_base_lba;

		/*
		 * Every 1024 physical blocks ("zone"), the LBA numbers
		 * go back to zero, but are within a higher block of LBA's.
		 * Also, there is a maximum of 1000 LBA's per zone.
		 * In other words, in PBA 1024-2047 you will find LBA 0-999
		 * which are really LBA 1000-1999. This allows for 24 bad
		 * or special physical blocks per zone.
		 */

		if (lba_offset >= uzonesize) {
			printk(KERN_WARNING
			       "alauda_read_map: Bad low LBA %d for block %d\n",
			       lba_real, blocknum);
			continue;
		}

		if (lba_to_pba[lba_offset] != UNDEF) {
			printk(KERN_WARNING
			       "alauda_read_map: "
			       "LBA %d seen for PBA %d and %d\n",
			       lba_real, lba_to_pba[lba_offset], blocknum);
			continue;
		}

		pba_to_lba[i] = lba_real;
		lba_to_pba[lba_offset] = blocknum;
		continue;
	}

	MEDIA_INFO(us).lba_to_pba[zone] = lba_to_pba;
	MEDIA_INFO(us).pba_to_lba[zone] = pba_to_lba;
	result = 0;
	goto out;

error:
	kfree(lba_to_pba);
	kfree(pba_to_lba);
out:
	return result;
}

/*
 * Checks to see whether we have already mapped a certain zone
 * If we haven't, the map is generated
 */
static void alauda_ensure_map_for_zone(struct us_data *us, unsigned int zone)
{
	if (MEDIA_INFO(us).lba_to_pba[zone] == NULL
		|| MEDIA_INFO(us).pba_to_lba[zone] == NULL)
		alauda_read_map(us, zone);
}

/*
 * Erases an entire block
 */
static int alauda_erase_block(struct us_data *us, u16 pba)
{
	int rc;
	unsigned char command[] = {
		ALAUDA_BULK_CMD, ALAUDA_BULK_ERASE_BLOCK, PBA_HI(pba),
		PBA_ZONE(pba), 0, PBA_LO(pba), 0x02, 0, MEDIA_PORT(us)
	};
	unsigned char buf[2];

	usb_stor_dbg(us, "Erasing PBA %d\n", pba);

	rc = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe,
		command, 9, NULL);
	if (rc != USB_STOR_XFER_GOOD)
		return rc;

	rc = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
		buf, 2, NULL);
	if (rc != USB_STOR_XFER_GOOD)
		return rc;

	usb_stor_dbg(us, "Erase result: %02X %02X\n", buf[0], buf[1]);
	return rc;
}

/*
 * Reads data from a certain offset page inside a PBA, including interleaved
 * redundancy data. Returns (pagesize+64)*pages bytes in data.
 */
static int alauda_read_block_raw(struct us_data *us, u16 pba,
		unsigned int page, unsigned int pages, unsigned char *data)
{
	int rc;
	unsigned char command[] = {
		ALAUDA_BULK_CMD, ALAUDA_BULK_READ_BLOCK, PBA_HI(pba),
		PBA_ZONE(pba), 0, PBA_LO(pba) + page, pages, 0, MEDIA_PORT(us)
	};

	usb_stor_dbg(us, "pba %d page %d count %d\n", pba, page, pages);

	rc = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe,
		command, 9, NULL);
	if (rc != USB_STOR_XFER_GOOD)
		return rc;

	return usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
		data, (MEDIA_INFO(us).pagesize + 64) * pages, NULL);
}

/*
 * Reads data from a certain offset page inside a PBA, excluding redundancy
 * data. Returns pagesize*pages bytes in data. Note that data must be big enough
 * to hold (pagesize+64)*pages bytes of data, but you can ignore those 'extra'
 * trailing bytes outside this function.
 */
static int alauda_read_block(struct us_data *us, u16 pba,
		unsigned int page, unsigned int pages, unsigned char *data)
{
	int i, rc;
	unsigned int pagesize = MEDIA_INFO(us).pagesize;

	rc = alauda_read_block_raw(us, pba, page, pages, data);
	if (rc != USB_STOR_XFER_GOOD)
		return rc;

	/* Cut out the redundancy data */
	for (i = 0; i < pages; i++) {
		int dest_offset = i * pagesize;
		int src_offset = i * (pagesize + 64);
		memmove(data + dest_offset, data + src_offset, pagesize);
	}

	return rc;
}

/*
 * Writes an entire block of data and checks status after write.
 * Redundancy data must be already included in data. Data should be
 * (pagesize+64)*blocksize bytes in length.
 */
static int alauda_write_block(struct us_data *us, u16 pba, unsigned char *data)
{
	int rc;
	struct alauda_info *info = (struct alauda_info *) us->extra;
	unsigned char command[] = {
		ALAUDA_BULK_CMD, ALAUDA_BULK_WRITE_BLOCK, PBA_HI(pba),
		PBA_ZONE(pba), 0, PBA_LO(pba), 32, 0, MEDIA_PORT(us)
	};

	usb_stor_dbg(us, "pba %d\n", pba);

	rc = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe,
		command, 9, NULL);
	if (rc != USB_STOR_XFER_GOOD)
		return rc;

	rc = usb_stor_bulk_transfer_buf(us, info->wr_ep, data,
		(MEDIA_INFO(us).pagesize + 64) * MEDIA_INFO(us).blocksize,
		NULL);
	if (rc != USB_STOR_XFER_GOOD)
		return rc;

	return alauda_check_status2(us);
}

/*
 * Write some data to a specific LBA.
 */
static int alauda_write_lba(struct us_data *us, u16 lba,
		 unsigned int page, unsigned int pages,
		 unsigned char *ptr, unsigned char *blockbuffer)
{
	u16 pba, lbap, new_pba;
	unsigned char *bptr, *cptr, *xptr;
	unsigned char ecc[3];
	int i, result;
	unsigned int uzonesize = MEDIA_INFO(us).uzonesize;
	unsigned int zonesize = MEDIA_INFO(us).zonesize;
	unsigned int pagesize = MEDIA_INFO(us).pagesize;
	unsigned int blocksize = MEDIA_INFO(us).blocksize;
	unsigned int lba_offset = lba % uzonesize;
	unsigned int new_pba_offset;
	unsigned int zone = lba / uzonesize;

	alauda_ensure_map_for_zone(us, zone);

	pba = MEDIA_INFO(us).lba_to_pba[zone][lba_offset];
	if (pba == 1) {
		/* Maybe it is impossible to write to PBA 1.
		   Fake success, but don't do anything. */
		printk(KERN_WARNING
		       "alauda_write_lba: avoid writing to pba 1\n");
		return USB_STOR_TRANSPORT_GOOD;
	}

	new_pba = alauda_find_unused_pba(&MEDIA_INFO(us), zone);
	if (!new_pba) {
		printk(KERN_WARNING
		       "alauda_write_lba: Out of unused blocks\n");
		return USB_STOR_TRANSPORT_ERROR;
	}

	/* read old contents */
	if (pba != UNDEF) {
		result = alauda_read_block_raw(us, pba, 0,
			blocksize, blockbuffer);
		if (result != USB_STOR_XFER_GOOD)
			return result;
	} else {
		memset(blockbuffer, 0, blocksize * (pagesize + 64));
	}

	lbap = (lba_offset << 1) | 0x1000;
	if (parity[MSB_of(lbap) ^ LSB_of(lbap)])
		lbap ^= 1;

	/* check old contents and fill lba */
	for (i = 0; i < blocksize; i++) {
		bptr = blockbuffer + (i * (pagesize + 64));
		cptr = bptr + pagesize;
		nand_compute_ecc(bptr, ecc);
		if (!nand_compare_ecc(cptr+13, ecc)) {
			usb_stor_dbg(us, "Warning: bad ecc in page %d- of pba %d\n",
				     i, pba);
			nand_store_ecc(cptr+13, ecc);
		}
		nand_compute_ecc(bptr + (pagesize / 2), ecc);
		if (!nand_compare_ecc(cptr+8, ecc)) {
			usb_stor_dbg(us, "Warning: bad ecc in page %d+ of pba %d\n",
				     i, pba);
			nand_store_ecc(cptr+8, ecc);
		}
		cptr[6] = cptr[11] = MSB_of(lbap);
		cptr[7] = cptr[12] = LSB_of(lbap);
	}

	/* copy in new stuff and compute ECC */
	xptr = ptr;
	for (i = page; i < page+pages; i++) {
		bptr = blockbuffer + (i * (pagesize + 64));
		cptr = bptr + pagesize;
		memcpy(bptr, xptr, pagesize);
		xptr += pagesize;
		nand_compute_ecc(bptr, ecc);
		nand_store_ecc(cptr+13, ecc);
		nand_compute_ecc(bptr + (pagesize / 2), ecc);
		nand_store_ecc(cptr+8, ecc);
	}

	result = alauda_write_block(us, new_pba, blockbuffer);
	if (result != USB_STOR_XFER_GOOD)
		return result;

	new_pba_offset = new_pba - (zone * zonesize);
	MEDIA_INFO(us).pba_to_lba[zone][new_pba_offset] = lba;
	MEDIA_INFO(us).lba_to_pba[zone][lba_offset] = new_pba;
	usb_stor_dbg(us, "Remapped LBA %d to PBA %d\n", lba, new_pba);

	if (pba != UNDEF) {
		unsigned int pba_offset = pba - (zone * zonesize);
		result = alauda_erase_block(us, pba);
		if (result != USB_STOR_XFER_GOOD)
			return result;
		MEDIA_INFO(us).pba_to_lba[zone][pba_offset] = UNDEF;
	}

	return USB_STOR_TRANSPORT_GOOD;
}

/*
 * Read data from a specific sector address
 */
static int alauda_read_data(struct us_data *us, unsigned long address,
		unsigned int sectors)
{
	unsigned char *buffer;
	u16 lba, max_lba;
	unsigned int page, len, offset;
	unsigned int blockshift = MEDIA_INFO(us).blockshift;
	unsigned int pageshift = MEDIA_INFO(us).pageshift;
	unsigned int blocksize = MEDIA_INFO(us).blocksize;
	unsigned int pagesize = MEDIA_INFO(us).pagesize;
	unsigned int uzonesize = MEDIA_INFO(us).uzonesize;
	struct scatterlist *sg;
	int result;

	/*
	 * Since we only read in one block at a time, we have to create
	 * a bounce buffer and move the data a piece at a time between the
	 * bounce buffer and the actual transfer buffer.
	 * We make this buffer big enough to hold temporary redundancy data,
	 * which we use when reading the data blocks.
	 */

	len = min(sectors, blocksize) * (pagesize + 64);
	buffer = kmalloc(len, GFP_NOIO);
	if (buffer == NULL) {
		printk(KERN_WARNING "alauda_read_data: Out of memory\n");
		return USB_STOR_TRANSPORT_ERROR;
	}

	/* Figure out the initial LBA and page */
	lba = address >> blockshift;
	page = (address & MEDIA_INFO(us).blockmask);
	max_lba = MEDIA_INFO(us).capacity >> (blockshift + pageshift);

	result = USB_STOR_TRANSPORT_GOOD;
	offset = 0;
	sg = NULL;

	while (sectors > 0) {
		unsigned int zone = lba / uzonesize; /* integer division */
		unsigned int lba_offset = lba - (zone * uzonesize);
		unsigned int pages;
		u16 pba;
		alauda_ensure_map_for_zone(us, zone);

		/* Not overflowing capacity? */
		if (lba >= max_lba) {
			usb_stor_dbg(us, "Error: Requested lba %u exceeds maximum %u\n",
				     lba, max_lba);
			result = USB_STOR_TRANSPORT_ERROR;
			break;
		}

		/* Find number of pages we can read in this block */
		pages = min(sectors, blocksize - page);
		len = pages << pageshift;

		/* Find where this lba lives on disk */
		pba = MEDIA_INFO(us).lba_to_pba[zone][lba_offset];

		if (pba == UNDEF) {	/* this lba was never written */
			usb_stor_dbg(us, "Read %d zero pages (LBA %d) page %d\n",
				     pages, lba, page);

			/* This is not really an error. It just means
			   that the block has never been written.
			   Instead of returning USB_STOR_TRANSPORT_ERROR
			   it is better to return all zero data. */

			memset(buffer, 0, len);
		} else {
			usb_stor_dbg(us, "Read %d pages, from PBA %d (LBA %d) page %d\n",
				     pages, pba, lba, page);

			result = alauda_read_block(us, pba, page, pages, buffer);
			if (result != USB_STOR_TRANSPORT_GOOD)
				break;
		}

		/* Store the data in the transfer buffer */
		usb_stor_access_xfer_buf(buffer, len, us->srb,
				&sg, &offset, TO_XFER_BUF);

		page = 0;
		lba++;
		sectors -= pages;
	}

	kfree(buffer);
	return result;
}

/*
 * Write data to a specific sector address
 */
static int alauda_write_data(struct us_data *us, unsigned long address,
		unsigned int sectors)
{
	unsigned char *buffer, *blockbuffer;
	unsigned int page, len, offset;
	unsigned int blockshift = MEDIA_INFO(us).blockshift;
	unsigned int pageshift = MEDIA_INFO(us).pageshift;
	unsigned int blocksize = MEDIA_INFO(us).blocksize;
	unsigned int pagesize = MEDIA_INFO(us).pagesize;
	struct scatterlist *sg;
	u16 lba, max_lba;
	int result;

	/*
	 * Since we don't write the user data directly to the device,
	 * we have to create a bounce buffer and move the data a piece
	 * at a time between the bounce buffer and the actual transfer buffer.
	 */

	len = min(sectors, blocksize) * pagesize;
	buffer = kmalloc(len, GFP_NOIO);
	if (buffer == NULL) {
		printk(KERN_WARNING "alauda_write_data: Out of memory\n");
		return USB_STOR_TRANSPORT_ERROR;
	}

	/*
	 * We also need a temporary block buffer, where we read in the old data,
	 * overwrite parts with the new data, and manipulate the redundancy data
	 */
	blockbuffer = kmalloc((pagesize + 64) * blocksize, GFP_NOIO);
	if (blockbuffer == NULL) {
		printk(KERN_WARNING "alauda_write_data: Out of memory\n");
		kfree(buffer);
		return USB_STOR_TRANSPORT_ERROR;
	}

	/* Figure out the initial LBA and page */
	lba = address >> blockshift;
	page = (address & MEDIA_INFO(us).blockmask);
	max_lba = MEDIA_INFO(us).capacity >> (pageshift + blockshift);

	result = USB_STOR_TRANSPORT_GOOD;
	offset = 0;
	sg = NULL;

	while (sectors > 0) {
		/* Write as many sectors as possible in this block */
		unsigned int pages = min(sectors, blocksize - page);
		len = pages << pageshift;

		/* Not overflowing capacity? */
		if (lba >= max_lba) {
			usb_stor_dbg(us, "Requested lba %u exceeds maximum %u\n",
				     lba, max_lba);
			result = USB_STOR_TRANSPORT_ERROR;
			break;
		}

		/* Get the data from the transfer buffer */
		usb_stor_access_xfer_buf(buffer, len, us->srb,
				&sg, &offset, FROM_XFER_BUF);

		result = alauda_write_lba(us, lba, page, pages, buffer,
			blockbuffer);
		if (result != USB_STOR_TRANSPORT_GOOD)
			break;

		page = 0;
		lba++;
		sectors -= pages;
	}

	kfree(buffer);
	kfree(blockbuffer);
	return result;
}

/*
 * Our interface with the rest of the world
 */

static void alauda_info_destructor(void *extra)
{
	struct alauda_info *info = (struct alauda_info *) extra;
	int port;

	if (!info)
		return;

	for (port = 0; port < 2; port++) {
		struct alauda_media_info *media_info = &info->port[port];

		alauda_free_maps(media_info);
		kfree(media_info->lba_to_pba);
		kfree(media_info->pba_to_lba);
	}
}

/*
 * Initialize alauda_info struct and find the data-write endpoint
 */
static int init_alauda(struct us_data *us)
{
	struct alauda_info *info;
	struct usb_host_interface *altsetting = us->pusb_intf->cur_altsetting;
	nand_init_ecc();

	us->extra = kzalloc(sizeof(struct alauda_info), GFP_NOIO);
	if (!us->extra)
		return USB_STOR_TRANSPORT_ERROR;

	info = (struct alauda_info *) us->extra;
	us->extra_destructor = alauda_info_destructor;

	info->wr_ep = usb_sndbulkpipe(us->pusb_dev,
		altsetting->endpoint[0].desc.bEndpointAddress
		& USB_ENDPOINT_NUMBER_MASK);

	return USB_STOR_TRANSPORT_GOOD;
}

static int alauda_transport(struct scsi_cmnd *srb, struct us_data *us)
{
	int rc;
	struct alauda_info *info = (struct alauda_info *) us->extra;
	unsigned char *ptr = us->iobuf;
	static unsigned char inquiry_response[36] = {
		0x00, 0x80, 0x00, 0x01, 0x1F, 0x00, 0x00, 0x00
	};

	if (srb->cmnd[0] == INQUIRY) {
		usb_stor_dbg(us, "INQUIRY - Returning bogus response\n");
		memcpy(ptr, inquiry_response, sizeof(inquiry_response));
		fill_inquiry_response(us, ptr, 36);
		return USB_STOR_TRANSPORT_GOOD;
	}

	if (srb->cmnd[0] == TEST_UNIT_READY) {
		usb_stor_dbg(us, "TEST_UNIT_READY\n");
		return alauda_check_media(us);
	}

	if (srb->cmnd[0] == READ_CAPACITY) {
		unsigned int num_zones;
		unsigned long capacity;

		rc = alauda_check_media(us);
		if (rc != USB_STOR_TRANSPORT_GOOD)
			return rc;

		num_zones = MEDIA_INFO(us).capacity >> (MEDIA_INFO(us).zoneshift
			+ MEDIA_INFO(us).blockshift + MEDIA_INFO(us).pageshift);

		capacity = num_zones * MEDIA_INFO(us).uzonesize
			* MEDIA_INFO(us).blocksize;

		/* Report capacity and page size */
		((__be32 *) ptr)[0] = cpu_to_be32(capacity - 1);
		((__be32 *) ptr)[1] = cpu_to_be32(512);

		usb_stor_set_xfer_buf(ptr, 8, srb);
		return USB_STOR_TRANSPORT_GOOD;
	}

	if (srb->cmnd[0] == READ_10) {
		unsigned int page, pages;

		rc = alauda_check_media(us);
		if (rc != USB_STOR_TRANSPORT_GOOD)
			return rc;

		page = short_pack(srb->cmnd[3], srb->cmnd[2]);
		page <<= 16;
		page |= short_pack(srb->cmnd[5], srb->cmnd[4]);
		pages = short_pack(srb->cmnd[8], srb->cmnd[7]);

		usb_stor_dbg(us, "READ_10: page %d pagect %d\n", page, pages);

		return alauda_read_data(us, page, pages);
	}

	if (srb->cmnd[0] == WRITE_10) {
		unsigned int page, pages;

		rc = alauda_check_media(us);
		if (rc != USB_STOR_TRANSPORT_GOOD)
			return rc;

		page = short_pack(srb->cmnd[3], srb->cmnd[2]);
		page <<= 16;
		page |= short_pack(srb->cmnd[5], srb->cmnd[4]);
		pages = short_pack(srb->cmnd[8], srb->cmnd[7]);

		usb_stor_dbg(us, "WRITE_10: page %d pagect %d\n", page, pages);

		return alauda_write_data(us, page, pages);
	}

	if (srb->cmnd[0] == REQUEST_SENSE) {
		usb_stor_dbg(us, "REQUEST_SENSE\n");

		memset(ptr, 0, 18);
		ptr[0] = 0xF0;
		ptr[2] = info->sense_key;
		ptr[7] = 11;
		ptr[12] = info->sense_asc;
		ptr[13] = info->sense_ascq;
		usb_stor_set_xfer_buf(ptr, 18, srb);

		return USB_STOR_TRANSPORT_GOOD;
	}

	if (srb->cmnd[0] == ALLOW_MEDIUM_REMOVAL) {
		/* sure.  whatever.  not like we can stop the user from popping
		   the media out of the device (no locking doors, etc) */
		return USB_STOR_TRANSPORT_GOOD;
	}

	usb_stor_dbg(us, "Gah! Unknown command: %d (0x%x)\n",
		     srb->cmnd[0], srb->cmnd[0]);
	info->sense_key = 0x05;
	info->sense_asc = 0x20;
	info->sense_ascq = 0x00;
	return USB_STOR_TRANSPORT_FAILED;
}

static int alauda_probe(struct usb_interface *intf,
			 const struct usb_device_id *id)
{
	struct us_data *us;
	int result;

	result = usb_stor_probe1(&us, intf, id,
			(id - alauda_usb_ids) + alauda_unusual_dev_list);
	if (result)
		return result;

	us->transport_name  = "Alauda Control/Bulk";
	us->transport = alauda_transport;
	us->transport_reset = usb_stor_Bulk_reset;
	us->max_lun = 1;

	result = usb_stor_probe2(us);
	return result;
}

static struct usb_driver alauda_driver = {
	.name =		"ums-alauda",
	.probe =	alauda_probe,
	.disconnect =	usb_stor_disconnect,
	.suspend =	usb_stor_suspend,
	.resume =	usb_stor_resume,
	.reset_resume =	usb_stor_reset_resume,
	.pre_reset =	usb_stor_pre_reset,
	.post_reset =	usb_stor_post_reset,
	.id_table =	alauda_usb_ids,
	.soft_unbind =	1,
	.no_dynamic_id = 1,
};

module_usb_driver(alauda_driver);
