openwrt/target/linux/adm5120/files/drivers/block/rb1xx/ata.h

144 lines
3.6 KiB
C

/* CF-mips driver
This is a block driver for the direct (mmaped) interface to the CF-slot,
found in Routerboard.com's RB532 board
See SDK provided from routerboard.com.
Module adapted By P.Christeas <p_christeas@yahoo.com>, 2005-6.
Cleaned up and adapted to platform_device by Felix Fietkau <nbd@openwrt.org>
This work is redistributed under the terms of the GNU General Public License.
*/
#ifndef __CFMIPS_ATA_H__
#define __CFMIPS_ATA_H__
#include <linux/interrupt.h>
#define CFG_DC_DEV1 (void*)0xb8010010
#define CFG_DC_DEVBASE 0x0
#define CFG_DC_DEVMASK 0x4
#define CFG_DC_DEVC 0x8
#define CFG_DC_DEVTC 0xC
#define CFDEV_BUF_SIZE 0x1000
#define ATA_CIS_OFFSET 0x200
#define ATA_REG_OFFSET 0x800
#define ATA_DBUF_OFFSET 0xC00
#define ATA_REG_FEAT 0x1
#define ATA_REG_SC 0x2
#define ATA_REG_SN 0x3
#define ATA_REG_CL 0x4
#define ATA_REG_CH 0x5
#define ATA_REG_DH 0x6
#define ATA_REG_DH_BASE 0xa0
#define ATA_REG_DH_LBA 0x40
#define ATA_REG_DH_DRV 0x10
#define ATA_REG_CMD 0x7
#define ATA_REG_ST 0x7
#define ATA_REG_ST_BUSY 0x80
#define ATA_REG_ST_RDY 0x40
#define ATA_REG_ST_DWF 0x20
#define ATA_REG_ST_DSC 0x10
#define ATA_REG_ST_DRQ 0x08
#define ATA_REG_ST_CORR 0x04
#define ATA_REG_ST_ERR 0x01
#define ATA_REG_ERR 0xd
#define ATA_REG_DC 0xe
#define ATA_REG_DC_IEN 0x02
#define ATA_REG_DC_SRST 0x04
#define ATA_CMD_READ_SECTORS 0x20
#define ATA_CMD_WRITE_SECTORS 0x30
#define ATA_CMD_EXEC_DRIVE_DIAG 0x90
#define ATA_CMD_READ_MULTIPLE 0xC4
#define ATA_CMD_WRITE_MULTIPLE 0xC5
#define ATA_CMD_SET_MULTIPLE 0xC6
#define ATA_CMD_IDENTIFY_DRIVE 0xEC
#define ATA_CMD_SET_FEATURES 0xEF
#define ATA_FEATURE_ENABLE_APM 0x05
#define ATA_FEATURE_DISABLE_APM 0x85
#define ATA_APM_DISABLED 0x00
#define ATA_APM_MIN_POWER 0x01
#define ATA_APM_WITH_STANDBY 0x7f
#define ATA_APM_WITHOUT_STANDBY 0x80
#define ATA_APM_MAX_PERFORMANCE 0xfe
#define CF_SECT_SIZE 0x200
/* That is the ratio CF_SECT_SIZE/512 (the kernel sector size) */
#define CF_KERNEL_MUL 1
#define ATA_MAX_SECT_PER_CMD 0x100
#define CF_TRANS_FAILED 0
#define CF_TRANS_OK 1
#define CF_TRANS_IN_PROGRESS 2
enum trans_state {
TS_IDLE = 0,
TS_AFTER_RESET,
TS_READY,
TS_CMD,
TS_TRANS
};
//
// #if DEBUG
// static unsigned long busy_time;
// #endif
/** Struct to hold the cfdev
Actually, all the data here only has one instance. However, for
reasons of programming conformity, it is passed around as a pointer
*/
struct cf_mips_dev {
void *base; /* base address for I/O */
void *baddr; /* remapped address */
int pin; /* gpio pin */
int irq; /* gpio irq */
unsigned head;
unsigned cyl;
unsigned spt;
unsigned sectors;
unsigned short block_size;
unsigned dtype ; // ATA or CF
struct request_queue *queue;
struct gendisk *gd;
/* Transaction state */
enum trans_state tstate;
char *tbuf;
unsigned long tbuf_size;
sector_t tsect_start;
unsigned tsector_count;
unsigned tsectors_left;
int tread;
unsigned tcmd;
int async_mode;
unsigned long irq_enable_time;
struct request *active_req; /* A request is being carried out. Is that different from tstate? */
int users;
struct timer_list to_timer;
struct tasklet_struct tasklet;
/** This lock ensures that the requests to this device are all done
atomically. Transfers can run in parallel, requests are all queued
one-by-one */
spinlock_t lock;
};
int cf_do_transfer(struct cf_mips_dev* dev,sector_t sector, unsigned long nsect,
char* buffer, int is_write);
int cf_init(struct cf_mips_dev* dev);
void cf_cleanup(struct cf_mips_dev* dev);
void cf_async_trans_done(struct cf_mips_dev* dev, int result);
// void *cf_get_next_buf(unsigned long *buf_size);
#endif