linux/drivers/usb/storage/alauda.c

// SPDX-License-Identifier: GPL-2.0+
/*
 * Driver for Alauda-based card readers
 *
 * Current development and maintenance by:
 *   (c) 2005 Daniel Drake <[email protected]>
 *
 * 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
 */

#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"
#include "scsiglue.h"

#define DRV_NAME

MODULE_DESCRIPTION();
MODULE_AUTHOR();
MODULE_LICENSE();
MODULE_IMPORT_NS();

/*
 * Status bytes
 */
#define ALAUDA_STATUS_ERROR
#define ALAUDA_STATUS_READY

/*
 * Control opcodes (for request field)
 */
#define ALAUDA_GET_XD_MEDIA_STATUS
#define ALAUDA_GET_SM_MEDIA_STATUS
#define ALAUDA_ACK_XD_MEDIA_CHANGE
#define ALAUDA_ACK_SM_MEDIA_CHANGE
#define ALAUDA_GET_XD_MEDIA_SIG
#define ALAUDA_GET_SM_MEDIA_SIG

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

/*
 * Bulk opcodes (byte 1)
 */
#define ALAUDA_BULK_GET_REDU_DATA
#define ALAUDA_BULK_READ_BLOCK
#define ALAUDA_BULK_ERASE_BLOCK
#define ALAUDA_BULK_WRITE_BLOCK
#define ALAUDA_BULK_GET_STATUS2
#define ALAUDA_BULK_RESET_MEDIA

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

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

struct alauda_media_info {};

struct alauda_info {};

#define short_pack(lsb,msb)
#define LSB_of(s)
#define MSB_of(s)

#define MEDIA_PORT(us)
#define MEDIA_INFO(us)

#define PBA_LO(pba)
#define PBA_HI(pba)
#define PBA_ZONE(pba)

static int init_alauda(struct us_data *us);


/*
 * The table of devices
 */
#define UNUSUAL_DEV

static struct usb_device_id alauda_usb_ids[] =;
MODULE_DEVICE_TABLE(usb, alauda_usb_ids);

#undef UNUSUAL_DEV

/*
 * The flags table
 */
#define UNUSUAL_DEV

static struct us_unusual_dev alauda_unusual_dev_list[] =;

#undef UNUSUAL_DEV


/*
 * Media handling
 */

struct alauda_card_info {};

static struct alauda_card_info alauda_card_ids[] =;

static struct alauda_card_info *alauda_card_find_id(unsigned char id)
{}

/*
 * ECC computation.
 */

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

static void nand_init_ecc(void)
{}

/* compute 3-byte ecc on 256 bytes */
static void nand_compute_ecc(unsigned char *data, unsigned char *ecc)
{}

static int nand_compare_ecc(unsigned char *data, unsigned char *ecc)
{}

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

/*
 * Alauda driver
 */

/*
 * Forget our PBA <---> LBA mappings for a particular port
 */
static void alauda_free_maps (struct alauda_media_info *media_info)
{}

/*
 * 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)
{}

/*
 * 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)
{}

/*
 * 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)
{}

/*
 * Resets the media status (but not the whole device?)
 */
static int alauda_reset_media(struct us_data *us)
{}

/*
 * Examines the media and deduces capacity, etc.
 */
static int alauda_init_media(struct us_data *us)
{}

/*
 * 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)
{}

/*
 * 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)
{}

/*
 * 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)
{}

/*
 * 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)
{}

/*
 * 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)
{}

/*
 * 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)
{}

/*
 * Erases an entire block
 */
static int alauda_erase_block(struct us_data *us, u16 pba)
{}

/*
 * 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)
{}

/*
 * 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)
{}

/*
 * 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)
{}

/*
 * 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)
{}

/*
 * Read data from a specific sector address
 */
static int alauda_read_data(struct us_data *us, unsigned long address,
		unsigned int sectors)
{}

/*
 * Write data to a specific sector address
 */
static int alauda_write_data(struct us_data *us, unsigned long address,
		unsigned int sectors)
{}

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

static void alauda_info_destructor(void *extra)
{}

/*
 * Initialize alauda_info struct and find the data-write endpoint
 */
static int init_alauda(struct us_data *us)
{}

static int alauda_transport(struct scsi_cmnd *srb, struct us_data *us)
{}

static struct scsi_host_template alauda_host_template;

static int alauda_probe(struct usb_interface *intf,
			 const struct usb_device_id *id)
{}

static struct usb_driver alauda_driver =;

module_usb_stor_driver(alauda_driver, alauda_host_template, DRV_NAME);