#ifndef _SMARTMEDIA_H_
#define _SMARTMEDIA_H_

#include "usb.h"

extern unsigned char nand_parity[256];
extern void nand_compute_ecc(unsigned char *data, unsigned char *ecc);
extern void nand_store_ecc  (unsigned char *data, unsigned char *ecc);
extern int  nand_compare_ecc(unsigned char *data, unsigned char *ecc);

struct sm_card_info {
	unsigned long	capacity;	/* Size of card in bytes */
	int		pagesize;	/* Size of page in bytes */
	int		pageshift;	/* log2 of pagesize */
	int		blocksize;	/* Size of block in pages */
	int		blockshift;	/* log2 of blocksize */
	int		blockmask;	/* 2^blockshift - 1 */
	int		*lba_to_pba;	/* logical to physical map */
	int		*pba_to_lba;	/* physical to logical map */
	int		lbact;		/* number of available pages */
	int		flags;
#define	SMARTMEDIA_WP	1		/* write protected */
};

struct sm_ops {
	int (*sm_get_wp)(struct us_data *us);
	int (*sm_read_deviceID)(struct us_data *us, unsigned char *id4);
	int (*sm_read_map)(struct us_data *us);
	int (*sm_read_data)(struct us_data *us,
			    unsigned long address, unsigned int sectorct,
			    unsigned char *buf, int use_sg);
	int (*sm_write_lba)(struct us_data *us, unsigned int lba,
			     unsigned int page, unsigned int pagect,
			     unsigned char *buf);
	int (*sm_test_unit_ready)(struct us_data *us,
				  Scsi_Cmnd *srb, int cmdlen);
	int (*sm_request_sense)(struct us_data *us,
				Scsi_Cmnd *srb, int cmdlen);
};


extern int smartmedia_raw;

extern int
smartmedia_transport(Scsi_Cmnd *srb, struct us_data *us, struct sm_ops *sm);

extern int
smartmedia_allocate_map(struct sm_card_info *info);

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

#endif
