/*
 * 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, bit, bits[8];

	par = 0;
	for (j = 0; j < 8; j++)
		bits[j] = 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);

	US_DEBUGP("alauda_get_media_status: 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;
	}

	US_DEBUGP("alauda_init_media: 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) {
		US_DEBUGP("alauda_init_media: 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;

	US_DEBUGP("alauda_init_media: 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;
	US_DEBUGP("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)) {
		US_DEBUGP("alauda_check_media: 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) {
		US_DEBUGP("alauda_check_media: 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;

	US_DEBUGP("alauda_check_status2: %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;
	}

	US_DEBUGP("alauda_read_map: 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;
		US_DEBUGP("alauda_read_map: 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) {
			US_DEBUGP("alauda_read_map: 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) {
			US_DEBUGP("alauda_read_map: 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];

	US_DEBUGP("alauda_erase_block: 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;

	US_DEBUGP("alauda_erase_block: 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)
	};

	US_DEBUGP("alauda_read_block: 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)
	};

	US_DEBUGP("alauda_write_block: 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)) {
			US_DEBUGP("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)) {
			US_DEBUGP("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;
	US_DEBUGP("alauda_write_lba: 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) {
			US_DEBUGP("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 */
			US_DEBUGP("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 {
			US_DEBUGP("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) {
			US_DEBUGP("alauda_write_data: 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) {
		US_DEBUGP("init_alauda: Gah! Can't allocate storage for"
			"alauda info struct!\n");
		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) {
		US_DEBUGP("alauda_transport: 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) {
		US_DEBUGP("alauda_transport: 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]);

		US_DEBUGP("alauda_transport: 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]);

		US_DEBUGP("alauda_transport: WRITE_10: page %d pagect %d\n",
			  page, pages);

		return alauda_write_data(us, page, pages);
	}

	if (srb->cmnd[0] == REQUEST_SENSE) {
		US_DEBUGP("alauda_transport: 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;
	}

	US_DEBUGP("alauda_transport: 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);
