/* Driver for SanDisk SDDR-55 SmartMedia reader
 *
 * $Id:$
 *
 * SDDR55 driver v0.1:
 *
 * First release
 *
 * Current development and maintenance by:
 *   (c) 2002 Simon Munton
 *
 * 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/jiffies.h>
#include <linux/errno.h>
#include <linux/slab.h>

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

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


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

#define set_sense_info(sk, asc, ascq)	\
    do {				\
	info->sense_data[2] = sk;	\
	info->sense_data[12] = asc;	\
	info->sense_data[13] = ascq;	\
	} while (0)


struct sddr55_card_info {
	unsigned long	capacity;	/* Size of card in bytes */
	int		max_log_blks;	/* maximum number of logical blocks */
	int		pageshift;	/* log2 of pagesize */
	int		smallpageshift;	/* 1 if pagesize == 256 */
	int		blocksize;	/* Size of block in pages */
	int		blockshift;	/* log2 of blocksize */
	int		blockmask;	/* 2^blockshift - 1 */
	int		read_only;	/* non zero if card is write protected */
	int		force_read_only;	/* non zero if we find a map error*/
	int		*lba_to_pba;	/* logical to physical map */
	int		*pba_to_lba;	/* physical to logical map */
	int		fatal_error;	/* set if we detect something nasty */
	unsigned long 	last_access;	/* number of jiffies since we last talked to device */
	unsigned char   sense_data[18];
};


#define NOT_ALLOCATED		0xffffffff
#define BAD_BLOCK		0xffff
#define CIS_BLOCK		0x400
#define UNUSED_BLOCK		0x3ff

static int
sddr55_bulk_transport(struct us_data *us, int direction,
		      unsigned char *data, unsigned int len) {
	struct sddr55_card_info *info = (struct sddr55_card_info *)us->extra;
	unsigned int pipe = (direction == DMA_FROM_DEVICE) ?
			us->recv_bulk_pipe : us->send_bulk_pipe;

	if (!len)
		return USB_STOR_XFER_GOOD;
	info->last_access = jiffies;
	return usb_stor_bulk_transfer_buf(us, pipe, data, len, NULL);
}

/* check if card inserted, if there is, update read_only status
 * return non zero if no card
 */

static int sddr55_status(struct us_data *us)
{
	int result;
	unsigned char *command = us->iobuf;
	unsigned char *status = us->iobuf;
	struct sddr55_card_info *info = (struct sddr55_card_info *)us->extra;

	/* send command */
	memset(command, 0, 8);
	command[5] = 0xB0;
	command[7] = 0x80;
	result = sddr55_bulk_transport(us,
		DMA_TO_DEVICE, command, 8);

	US_DEBUGP("Result for send_command in status %d\n",
		result);

	if (result != USB_STOR_XFER_GOOD) {
		set_sense_info (4, 0, 0);	/* hardware error */
		return USB_STOR_TRANSPORT_ERROR;
	}

	result = sddr55_bulk_transport(us,
		DMA_FROM_DEVICE, status,	4);

	/* expect to get short transfer if no card fitted */
	if (result == USB_STOR_XFER_SHORT || result == USB_STOR_XFER_STALLED) {
		/* had a short transfer, no card inserted, free map memory */
		if (info->lba_to_pba)
			kfree(info->lba_to_pba);
		if (info->pba_to_lba)
			kfree(info->pba_to_lba);
		info->lba_to_pba = NULL;
		info->pba_to_lba = NULL;

		info->fatal_error = 0;
		info->force_read_only = 0;

		set_sense_info (2, 0x3a, 0);	/* not ready, medium not present */
		return USB_STOR_TRANSPORT_FAILED;
	}

	if (result != USB_STOR_XFER_GOOD) {
		set_sense_info (4, 0, 0);	/* hardware error */
		return USB_STOR_TRANSPORT_FAILED;
	}
	
	/* check write protect status */
	info->read_only = (status[0] & 0x20);

	/* now read status */
	result = sddr55_bulk_transport(us,
		DMA_FROM_DEVICE, status,	2);

	if (result != USB_STOR_XFER_GOOD) {
		set_sense_info (4, 0, 0);	/* hardware error */
	}

	return (result == USB_STOR_XFER_GOOD ?
			USB_STOR_TRANSPORT_GOOD : USB_STOR_TRANSPORT_FAILED);
}


static int sddr55_read_data(struct us_data *us,
		unsigned int lba,
		unsigned int page,
		unsigned short sectors) {

	int result = USB_STOR_TRANSPORT_GOOD;
	unsigned char *command = us->iobuf;
	unsigned char *status = us->iobuf;
	struct sddr55_card_info *info = (struct sddr55_card_info *)us->extra;
	unsigned char *buffer;

	unsigned int pba;
	unsigned long address;

	unsigned short pages;
	unsigned int len, index, offset;

	// 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.

	len = min((unsigned int) sectors, (unsigned int) info->blocksize >>
			info->smallpageshift) * PAGESIZE;
	buffer = kmalloc(len, GFP_NOIO);
	if (buffer == NULL)
		return USB_STOR_TRANSPORT_ERROR; /* out of memory */
	index = offset = 0;

	while (sectors>0) {

		/* have we got to end? */
		if (lba >= info->max_log_blks)
			break;

		pba = info->lba_to_pba[lba];

		// Read as many sectors as possible in this block

		pages = min((unsigned int) sectors << info->smallpageshift,
				info->blocksize - page);
		len = pages << info->pageshift;

		US_DEBUGP("Read %02X pages, from PBA %04X"
			" (LBA %04X) page %02X\n",
			pages, pba, lba, page);

		if (pba == NOT_ALLOCATED) {
			/* no pba for this lba, fill with zeroes */
			memset (buffer, 0, len);
		} else {

			address = (pba << info->blockshift) + page;

			command[0] = 0;
			command[1] = LSB_of(address>>16);
			command[2] = LSB_of(address>>8);
			command[3] = LSB_of(address);

			command[4] = 0;
			command[5] = 0xB0;
			command[6] = LSB_of(pages << (1 - info->smallpageshift));
			command[7] = 0x85;

			/* send command */
			result = sddr55_bulk_transport(us,
				DMA_TO_DEVICE, command, 8);

			US_DEBUGP("Result for send_command in read_data %d\n",
				result);

			if (result != USB_STOR_XFER_GOOD) {
				result = USB_STOR_TRANSPORT_ERROR;
				goto leave;
			}

			/* read data */
			result = sddr55_bulk_transport(us,
				DMA_FROM_DEVICE, buffer, len);

			if (result != USB_STOR_XFER_GOOD) {
				result = USB_STOR_TRANSPORT_ERROR;
				goto leave;
			}

			/* now read status */
			result = sddr55_bulk_transport(us,
				DMA_FROM_DEVICE, status, 2);

			if (result != USB_STOR_XFER_GOOD) {
				result = USB_STOR_TRANSPORT_ERROR;
				goto leave;
			}

			/* check status for error */
			if (status[0] == 0xff && status[1] == 0x4) {
				set_sense_info (3, 0x11, 0);
				result = USB_STOR_TRANSPORT_FAILED;
				goto leave;
			}
		}

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

		page = 0;
		lba++;
		sectors -= pages >> info->smallpageshift;
	}

	result = USB_STOR_TRANSPORT_GOOD;

leave:
	kfree(buffer);

	return result;
}

static int sddr55_write_data(struct us_data *us,
		unsigned int lba,
		unsigned int page,
		unsigned short sectors) {

	int result = USB_STOR_TRANSPORT_GOOD;
	unsigned char *command = us->iobuf;
	unsigned char *status = us->iobuf;
	struct sddr55_card_info *info = (struct sddr55_card_info *)us->extra;
	unsigned char *buffer;

	unsigned int pba;
	unsigned int new_pba;
	unsigned long address;

	unsigned short pages;
	int i;
	unsigned int len, index, offset;

	/* check if we are allowed to write */
	if (info->read_only || info->force_read_only) {
		set_sense_info (7, 0x27, 0);	/* read only */
		return USB_STOR_TRANSPORT_FAILED;
	}

	// Since we only write 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.

	len = min((unsigned int) sectors, (unsigned int) info->blocksize >>
			info->smallpageshift) * PAGESIZE;
	buffer = kmalloc(len, GFP_NOIO);
	if (buffer == NULL)
		return USB_STOR_TRANSPORT_ERROR;
	index = offset = 0;

	while (sectors > 0) {

		/* have we got to end? */
		if (lba >= info->max_log_blks)
			break;

		pba = info->lba_to_pba[lba];

		// Write as many sectors as possible in this block

		pages = min((unsigned int) sectors << info->smallpageshift,
				info->blocksize - page);
		len = pages << info->pageshift;

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

		US_DEBUGP("Write %02X pages, to PBA %04X"
			" (LBA %04X) page %02X\n",
			pages, pba, lba, page);
			
		command[4] = 0;

		if (pba == NOT_ALLOCATED) {
			/* no pba allocated for this lba, find a free pba to use */

			int max_pba = (info->max_log_blks / 250 ) * 256;
			int found_count = 0;
			int found_pba = -1;

			/* set pba to first block in zone lba is in */
			pba = (lba / 1000) * 1024;

			US_DEBUGP("No PBA for LBA %04X\n",lba);

			if (max_pba > 1024)
				max_pba = 1024;

			/*
			 * Scan through the map looking for an unused block
			 * leave 16 unused blocks at start (or as many as
			 * possible) since the sddr55 seems to reuse a used
			 * block when it shouldn't if we don't leave space.
			 */
			for (i = 0; i < max_pba; i++, pba++) {
				if (info->pba_to_lba[pba] == UNUSED_BLOCK) {
					found_pba = pba;
					if (found_count++ > 16)
						break;
				}
			}

			pba = found_pba;

			if (pba == -1) {
				/* oh dear */
				US_DEBUGP("Couldn't find unallocated block\n");

				set_sense_info (3, 0x31, 0);	/* medium error */
				result = USB_STOR_TRANSPORT_FAILED;
				goto leave;
			}

			US_DEBUGP("Allocating PBA %04X for LBA %04X\n", pba, lba);

			/* set writing to unallocated block flag */
			command[4] = 0x40;
		}

		address = (pba << info->blockshift) + page;

		command[1] = LSB_of(address>>16);
		command[2] = LSB_of(address>>8); 
		command[3] = LSB_of(address);

		/* set the lba into the command, modulo 1000 */
		command[0] = LSB_of(lba % 1000);
		command[6] = MSB_of(lba % 1000);

		command[4] |= LSB_of(pages >> info->smallpageshift);
		command[5] = 0xB0;
		command[7] = 0x86;

		/* send command */
		result = sddr55_bulk_transport(us,
			DMA_TO_DEVICE, command, 8);

		if (result != USB_STOR_XFER_GOOD) {
			US_DEBUGP("Result for send_command in write_data %d\n",
			result);

			/* set_sense_info is superfluous here? */
			set_sense_info (3, 0x3, 0);/* peripheral write error */
			result = USB_STOR_TRANSPORT_FAILED;
			goto leave;
		}

		/* send the data */
		result = sddr55_bulk_transport(us,
			DMA_TO_DEVICE, buffer, len);

		if (result != USB_STOR_XFER_GOOD) {
			US_DEBUGP("Result for send_data in write_data %d\n",
				  result);

			/* set_sense_info is superfluous here? */
			set_sense_info (3, 0x3, 0);/* peripheral write error */
			result = USB_STOR_TRANSPORT_FAILED;
			goto leave;
		}

		/* now read status */
		result = sddr55_bulk_transport(us, DMA_FROM_DEVICE, status, 6);

		if (result != USB_STOR_XFER_GOOD) {
			US_DEBUGP("Result for get_status in write_data %d\n",
				  result);

			/* set_sense_info is superfluous here? */
			set_sense_info (3, 0x3, 0);/* peripheral write error */
			result = USB_STOR_TRANSPORT_FAILED;
			goto leave;
		}

		new_pba = (status[3] + (status[4] << 8) + (status[5] << 16))
						  >> info->blockshift;

		/* check status for error */
		if (status[0] == 0xff && status[1] == 0x4) {
			info->pba_to_lba[new_pba] = BAD_BLOCK;

			set_sense_info (3, 0x0c, 0);
			result = USB_STOR_TRANSPORT_FAILED;
			goto leave;
		}

		US_DEBUGP("Updating maps for LBA %04X: old PBA %04X, new PBA %04X\n",
			lba, pba, new_pba);

		/* update the lba<->pba maps, note new_pba might be the same as pba */
		info->lba_to_pba[lba] = new_pba;
		info->pba_to_lba[pba] = UNUSED_BLOCK;

		/* check that new_pba wasn't already being used */
		if (info->pba_to_lba[new_pba] != UNUSED_BLOCK) {
			printk(KERN_ERR "sddr55 error: new PBA %04X already in use for LBA %04X\n",
				new_pba, info->pba_to_lba[new_pba]);
			info->fatal_error = 1;
			set_sense_info (3, 0x31, 0);
			result = USB_STOR_TRANSPORT_FAILED;
			goto leave;
		}

		/* update the pba<->lba maps for new_pba */
		info->pba_to_lba[new_pba] = lba % 1000;

		page = 0;
		lba++;
		sectors -= pages >> info->smallpageshift;
	}
	result = USB_STOR_TRANSPORT_GOOD;

 leave:
	kfree(buffer);
	return result;
}

static int sddr55_read_deviceID(struct us_data *us,
		unsigned char *manufacturerID,
		unsigned char *deviceID) {

	int result;
	unsigned char *command = us->iobuf;
	unsigned char *content = us->iobuf;

	memset(command, 0, 8);
	command[5] = 0xB0;
	command[7] = 0x84;
	result = sddr55_bulk_transport(us, DMA_TO_DEVICE, command, 8);

	US_DEBUGP("Result of send_control for device ID is %d\n",
		result);

	if (result != USB_STOR_XFER_GOOD)
		return USB_STOR_TRANSPORT_ERROR;

	result = sddr55_bulk_transport(us,
		DMA_FROM_DEVICE, content, 4);

	if (result != USB_STOR_XFER_GOOD)
		return USB_STOR_TRANSPORT_ERROR;

	*manufacturerID = content[0];
	*deviceID = content[1];

	if (content[0] != 0xff)	{
    		result = sddr55_bulk_transport(us,
			DMA_FROM_DEVICE, content, 2);
	}

	return USB_STOR_TRANSPORT_GOOD;
}


int sddr55_reset(struct us_data *us) {
	return 0;
}


static unsigned long sddr55_get_capacity(struct us_data *us) {

	unsigned char manufacturerID;
	unsigned char deviceID;
	int result;
	struct sddr55_card_info *info = (struct sddr55_card_info *)us->extra;

	US_DEBUGP("Reading capacity...\n");

	result = sddr55_read_deviceID(us,
		&manufacturerID,
		&deviceID);

	US_DEBUGP("Result of read_deviceID is %d\n",
		result);

	if (result != USB_STOR_XFER_GOOD)
		return 0;

	US_DEBUGP("Device ID = %02X\n", deviceID);
	US_DEBUGP("Manuf  ID = %02X\n", manufacturerID);

	info->pageshift = 9;
	info->smallpageshift = 0;
	info->blocksize = 16;
	info->blockshift = 4;
	info->blockmask = 15;

	switch (deviceID) {

	case 0x6e: // 1MB
	case 0xe8:
	case 0xec:
		info->pageshift = 8;
		info->smallpageshift = 1;
		return 0x00100000;

	case 0xea: // 2MB
	case 0x64:
		info->pageshift = 8;
		info->smallpageshift = 1;
	case 0x5d: // 5d is a ROM card with pagesize 512.
		return 0x00200000;

	case 0xe3: // 4MB
	case 0xe5:
	case 0x6b:
	case 0xd5:
		return 0x00400000;

	case 0xe6: // 8MB
	case 0xd6:
		return 0x00800000;

	case 0x73: // 16MB
		info->blocksize = 32;
		info->blockshift = 5;
		info->blockmask = 31;
		return 0x01000000;

	case 0x75: // 32MB
		info->blocksize = 32;
		info->blockshift = 5;
		info->blockmask = 31;
		return 0x02000000;

	case 0x76: // 64MB
		info->blocksize = 32;
		info->blockshift = 5;
		info->blockmask = 31;
		return 0x04000000;

	case 0x79: // 128MB
		info->blocksize = 32;
		info->blockshift = 5;
		info->blockmask = 31;
		return 0x08000000;

	default: // unknown
		return 0;

	}
}

static int sddr55_read_map(struct us_data *us) {

	struct sddr55_card_info *info = (struct sddr55_card_info *)(us->extra);
	int numblocks;
	unsigned char *buffer;
	unsigned char *command = us->iobuf;
	int i;
	unsigned short lba;
	unsigned short max_lba;
	int result;

	if (!info->capacity)
		return -1;

	numblocks = info->capacity >> (info->blockshift + info->pageshift);
	
	buffer = kmalloc( numblocks * 2, GFP_NOIO );
	
	if (!buffer)
		return -1;

	memset(command, 0, 8);
	command[5] = 0xB0;
	command[6] = numblocks * 2 / 256;
	command[7] = 0x8A;

	result = sddr55_bulk_transport(us, DMA_TO_DEVICE, command, 8);

	if ( result != USB_STOR_XFER_GOOD) {
		kfree (buffer);
		return -1;
	}

	result = sddr55_bulk_transport(us, DMA_FROM_DEVICE, buffer, numblocks * 2);

	if ( result != USB_STOR_XFER_GOOD) {
		kfree (buffer);
		return -1;
	}

	result = sddr55_bulk_transport(us, DMA_FROM_DEVICE, command, 2);

	if ( result != USB_STOR_XFER_GOOD) {
		kfree (buffer);
		return -1;
	}

	if (info->lba_to_pba)
		kfree(info->lba_to_pba);
	if (info->pba_to_lba)
		kfree(info->pba_to_lba);
	info->lba_to_pba = kmalloc(numblocks*sizeof(int), GFP_NOIO);
	info->pba_to_lba = kmalloc(numblocks*sizeof(int), GFP_NOIO);

	if (info->lba_to_pba == NULL || info->pba_to_lba == NULL) {
		if (info->lba_to_pba != NULL)
			kfree(info->lba_to_pba);
		if (info->pba_to_lba != NULL)
			kfree(info->pba_to_lba);
		info->lba_to_pba = NULL;
		info->pba_to_lba = NULL;
		kfree(buffer);
		return -1;
	}

	memset(info->lba_to_pba, 0xff, numblocks*sizeof(int));
	memset(info->pba_to_lba, 0xff, numblocks*sizeof(int));

	/* set maximum lba */
	max_lba = info->max_log_blks;
	if (max_lba > 1000)
		max_lba = 1000;

	// Each block is 64 bytes of control data, so block i is located in
	// scatterlist block i*64/128k = i*(2^6)*(2^-17) = i*(2^-11)

	for (i=0; i<numblocks; i++) {
		int zone = i / 1024;

		lba = short_pack(buffer[i * 2], buffer[i * 2 + 1]);

			/* 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. Yes, this wastes 24
			 * physical blocks per zone. Go figure. 
			 * These devices can have blocks go bad, so there
			 * are 24 spare blocks to use when blocks do go bad.
			 */

			/* SDDR55 returns 0xffff for a bad block, and 0x400 for the 
			 * CIS block. (Is this true for cards 8MB or less??)
			 * Record these in the physical to logical map
			 */ 

		info->pba_to_lba[i] = lba;

		if (lba >= max_lba) {
			continue;
		}
		
		if (info->lba_to_pba[lba + zone * 1000] != NOT_ALLOCATED &&
		    !info->force_read_only) {
			printk("sddr55: map inconsistency at LBA %04X\n", lba + zone * 1000);
			info->force_read_only = 1;
		}

		if (lba<0x10 || (lba>=0x3E0 && lba<0x3EF))
			US_DEBUGP("LBA %04X <-> PBA %04X\n", lba, i);

		info->lba_to_pba[lba + zone * 1000] = i;
	}

	kfree(buffer);
	return 0;
}


static void sddr55_card_info_destructor(void *extra) {
	struct sddr55_card_info *info = (struct sddr55_card_info *)extra;

	if (!extra)
		return;

	if (info->lba_to_pba)
		kfree(info->lba_to_pba);
	if (info->pba_to_lba)
		kfree(info->pba_to_lba);
}


/*
 * Transport for the Sandisk SDDR-55
 */
int sddr55_transport(struct scsi_cmnd *srb, struct us_data *us)
{
	int result;
	static unsigned char inquiry_response[8] = {
		0x00, 0x80, 0x00, 0x02, 0x1F, 0x00, 0x00, 0x00
	};
 	// write-protected for now, no block descriptor support
	static unsigned char mode_page_01[20] = {
		0x0, 0x12, 0x00, 0x80, 0x0, 0x0, 0x0, 0x0,
		0x01, 0x0A,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
	};
	unsigned char *ptr = us->iobuf;
	unsigned long capacity;
	unsigned int lba;
	unsigned int pba;
	unsigned int page;
	unsigned short pages;
	struct sddr55_card_info *info;

	if (!us->extra) {
		us->extra = kmalloc(
			sizeof(struct sddr55_card_info), GFP_NOIO);
		if (!us->extra)
			return USB_STOR_TRANSPORT_ERROR;
		memset(us->extra, 0, sizeof(struct sddr55_card_info));
		us->extra_destructor = sddr55_card_info_destructor;
	}

	info = (struct sddr55_card_info *)(us->extra);

	if (srb->cmnd[0] == REQUEST_SENSE) {
		US_DEBUGP("SDDR55: request sense %02x/%02x/%02x\n", info->sense_data[2], info->sense_data[12], info->sense_data[13]);

		memcpy (ptr, info->sense_data, sizeof info->sense_data);
		ptr[0] = 0x70;
		ptr[7] = 11;
		usb_stor_set_xfer_buf (ptr, sizeof info->sense_data, srb);
		memset (info->sense_data, 0, sizeof info->sense_data);

		return USB_STOR_TRANSPORT_GOOD;
	}

	memset (info->sense_data, 0, sizeof info->sense_data);

	/* Dummy up a response for INQUIRY since SDDR55 doesn't
	   respond to INQUIRY commands */

	if (srb->cmnd[0] == INQUIRY) {
		memcpy(ptr, inquiry_response, 8);
		fill_inquiry_response(us, ptr, 36);
		return USB_STOR_TRANSPORT_GOOD;
	}

	/* only check card status if the map isn't allocated, ie no card seen yet
	 * or if it's been over half a second since we last accessed it
	 */
	if (info->lba_to_pba == NULL || time_after(jiffies, info->last_access + HZ/2)) {

		/* check to see if a card is fitted */
		result = sddr55_status (us);
		if (result) {
			result = sddr55_status (us);
			if (!result) {
			set_sense_info (6, 0x28, 0);	/* new media, set unit attention, not ready to ready */
			}
			return USB_STOR_TRANSPORT_FAILED;
		}
	}

	/* if we detected a problem with the map when writing,
	   don't allow any more access */
	if (info->fatal_error) {

		set_sense_info (3, 0x31, 0);
		return USB_STOR_TRANSPORT_FAILED;
	}

	if (srb->cmnd[0] == READ_CAPACITY) {

		capacity = sddr55_get_capacity(us);

		if (!capacity) {
			set_sense_info (3, 0x30, 0); /* incompatible medium */
			return USB_STOR_TRANSPORT_FAILED;
		}

		info->capacity = capacity;

		/* figure out the maximum logical block number, allowing for
		 * the fact that only 250 out of every 256 are used */
		info->max_log_blks = ((info->capacity >> (info->pageshift + info->blockshift)) / 256) * 250;

		/* Last page in the card, adjust as we only use 250 out of
		 * every 256 pages */
		capacity = (capacity / 256) * 250;

		capacity /= PAGESIZE;
		capacity--;

		((__be32 *) ptr)[0] = cpu_to_be32(capacity);
		((__be32 *) ptr)[1] = cpu_to_be32(PAGESIZE);
		usb_stor_set_xfer_buf(ptr, 8, srb);

		sddr55_read_map(us);

		return USB_STOR_TRANSPORT_GOOD;
	}

	if (srb->cmnd[0] == MODE_SENSE_10) {

		memcpy(ptr, mode_page_01, sizeof mode_page_01);
		ptr[3] = (info->read_only || info->force_read_only) ? 0x80 : 0;
		usb_stor_set_xfer_buf(ptr, sizeof(mode_page_01), srb);

		if ( (srb->cmnd[2] & 0x3F) == 0x01 ) {
			US_DEBUGP(
			  "SDDR55: Dummy up request for mode page 1\n");
			return USB_STOR_TRANSPORT_GOOD;

		} else if ( (srb->cmnd[2] & 0x3F) == 0x3F ) {
			US_DEBUGP(
			  "SDDR55: Dummy up request for all mode pages\n");
			return USB_STOR_TRANSPORT_GOOD;
		}

		set_sense_info (5, 0x24, 0);	/* invalid field in command */
		return USB_STOR_TRANSPORT_FAILED;
	}

	if (srb->cmnd[0] == ALLOW_MEDIUM_REMOVAL) {

		US_DEBUGP(
		  "SDDR55: %s medium removal. Not that I can do"
		  " anything about it...\n",
		  (srb->cmnd[4]&0x03) ? "Prevent" : "Allow");

		return USB_STOR_TRANSPORT_GOOD;

	}

	if (srb->cmnd[0] == READ_10 || srb->cmnd[0] == WRITE_10) {

		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]);

		page <<= info->smallpageshift;

		// convert page to block and page-within-block

		lba = page >> info->blockshift;
		page = page & info->blockmask;

		// locate physical block corresponding to logical block

		if (lba >= info->max_log_blks) {

			US_DEBUGP("Error: Requested LBA %04X exceeds maximum "
			  "block %04X\n", lba, info->max_log_blks-1);

			set_sense_info (5, 0x24, 0);	/* invalid field in command */

			return USB_STOR_TRANSPORT_FAILED;
		}

		pba = info->lba_to_pba[lba];

		if (srb->cmnd[0] == WRITE_10) {
			US_DEBUGP("WRITE_10: write block %04X (LBA %04X) page %01X"
				" pages %d\n",
				pba, lba, page, pages);

			return sddr55_write_data(us, lba, page, pages);
		} else {
			US_DEBUGP("READ_10: read block %04X (LBA %04X) page %01X"
				" pages %d\n",
				pba, lba, page, pages);

			return sddr55_read_data(us, lba, page, pages);
		}
	}


	if (srb->cmnd[0] == TEST_UNIT_READY) {
		return USB_STOR_TRANSPORT_GOOD;
	}

	if (srb->cmnd[0] == START_STOP) {
		return USB_STOR_TRANSPORT_GOOD;
	}

	set_sense_info (5, 0x20, 0);	/* illegal command */

	return USB_STOR_TRANSPORT_FAILED; // FIXME: sense buffer?
}

