/* 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 */
		kfree(info->lba_to_pba);
		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;
	}

	kfree(info->lba_to_pba);
	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) {
		kfree(info->lba_to_pba);
		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;

	kfree(info->lba_to_pba);
	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?
}

