minix/drivers/at_wini/at_wini.h
David van Moolenbroek b4d909d415 Split block/character protocols and libdriver
This patch separates the character and block driver communication
protocols. The old character protocol remains the same, but a new
block protocol is introduced. The libdriver library is replaced by
two new libraries: libchardriver and libblockdriver. Their exposed
API, and drivers that use them, have been updated accordingly.
Together, libbdev and libblockdriver now completely abstract away
the message format used by the block protocol. As the memory driver
is both a character and a block device driver, it now implements its
own message loop.

The most important semantic change made to the block protocol is that
it is no longer possible to return both partial results and an error
for a single transfer. This simplifies the interaction between the
caller and the driver, as the I/O vector no longer needs to be copied
back. Also, drivers are now no longer supposed to decide based on the
layout of the I/O vector when a transfer should be cut short. Put
simply, transfers are now supposed to either succeed completely, or
result in an error.

After this patch, the state of the various pieces is as follows:
- block protocol: stable
- libbdev API: stable for synchronous communication
- libblockdriver API: needs slight revision (the drvlib/partition API
  in particular; the threading API will also change shortly)
- character protocol: needs cleanup
- libchardriver API: needs cleanup accordingly
- driver restarts: largely unsupported until endpoint changes are
  reintroduced

As a side effect, this patch eliminates several bugs, hacks, and gcc
-Wall and -W warnings all over the place. It probably introduces a
few new ones, too.

Update warning: this patch changes the protocol between MFS and disk
drivers, so in order to use old/new images, the MFS from the ramdisk
must be used to mount all file systems.
2011-11-23 14:06:37 +01:00

225 lines
10 KiB
C

#include <minix/drivers.h>
#include <minix/blockdriver.h>
#include <minix/drvlib.h>
#define VERBOSE 0 /* display identify messages during boot */
#define ENABLE_ATAPI 1 /* add ATAPI cd-rom support to driver */
#define ATAPI_DEBUG 0 /* To debug ATAPI code. */
/* I/O Ports used by winchester disk controllers. */
/* Read and write registers */
#define REG_CMD_BASE0 0x1F0 /* command base register of controller 0 */
#define REG_CMD_BASE1 0x170 /* command base register of controller 1 */
#define REG_CTL_BASE0 0x3F6 /* control base register of controller 0 */
#define REG_CTL_BASE1 0x376 /* control base register of controller 1 */
#define PCI_CTL_OFF 2 /* Offset of control registers from BAR2 */
#define PCI_DMA_2ND_OFF 8 /* Offset of DMA registers from BAR4 for
* secondary channel
*/
#define REG_DATA 0 /* data register (offset from the base reg.) */
#define REG_PRECOMP 1 /* start of write precompensation */
#define REG_COUNT 2 /* sectors to transfer */
#define REG_SECTOR 3 /* sector number */
#define REG_CYL_LO 4 /* low byte of cylinder number */
#define REG_CYL_HI 5 /* high byte of cylinder number */
#define REG_LDH 6 /* lba, drive and head */
#define LDH_DEFAULT 0xA0 /* ECC enable, 512 bytes per sector */
#define LDH_LBA 0x40 /* Use LBA addressing */
#define LDH_DEV 0x10 /* Drive 1 iff set */
#define ldh_init(drive) (LDH_DEFAULT | ((drive) << 4))
/* Read only registers */
#define REG_STATUS 7 /* status */
#define STATUS_BSY 0x80 /* controller busy */
#define STATUS_RDY 0x40 /* drive ready */
#define STATUS_WF 0x20 /* write fault */
#define STATUS_SC 0x10 /* seek complete (obsolete) */
#define STATUS_DRQ 0x08 /* data transfer request */
#define STATUS_CRD 0x04 /* corrected data */
#define STATUS_IDX 0x02 /* index pulse */
#define STATUS_ERR 0x01 /* error */
#define STATUS_ADMBSY 0x100 /* administratively busy (software) */
#define REG_ERROR 1 /* error code */
#define ERROR_BB 0x80 /* bad block */
#define ERROR_ECC 0x40 /* bad ecc bytes */
#define ERROR_ID 0x10 /* id not found */
#define ERROR_AC 0x04 /* aborted command */
#define ERROR_TK 0x02 /* track zero error */
#define ERROR_DM 0x01 /* no data address mark */
/* Write only registers */
#define REG_COMMAND 7 /* command */
#define CMD_IDLE 0x00 /* for w_command: drive idle */
#define CMD_RECALIBRATE 0x10 /* recalibrate drive */
#define CMD_READ 0x20 /* read data */
#define CMD_READ_EXT 0x24 /* read data (LBA48 addressed) */
#define CMD_READ_DMA_EXT 0x25 /* read data using DMA (w/ LBA48) */
#define CMD_WRITE 0x30 /* write data */
#define CMD_WRITE_EXT 0x34 /* write data (LBA48 addressed) */
#define CMD_WRITE_DMA_EXT 0x35 /* write data using DMA (w/ LBA48) */
#define CMD_READVERIFY 0x40 /* read verify */
#define CMD_FORMAT 0x50 /* format track */
#define CMD_SEEK 0x70 /* seek cylinder */
#define CMD_DIAG 0x90 /* execute device diagnostics */
#define CMD_SPECIFY 0x91 /* specify parameters */
#define CMD_READ_DMA 0xC8 /* read data using DMA */
#define CMD_WRITE_DMA 0xCA /* write data using DMA */
#define CMD_FLUSH_CACHE 0xE7 /* flush the write cache */
#define ATA_IDENTIFY 0xEC /* identify drive */
/* #define REG_CTL 0x206 */ /* control register */
#define REG_CTL 0 /* control register */
#define CTL_NORETRY 0x80 /* disable access retry */
#define CTL_NOECC 0x40 /* disable ecc retry */
#define CTL_EIGHTHEADS 0x08 /* more than eight heads */
#define CTL_RESET 0x04 /* reset controller */
#define CTL_INTDISABLE 0x02 /* disable interrupts */
#define REG_CTL_ALTSTAT 0 /* alternate status register */
/* Identify words */
#define ID_GENERAL 0x00 /* General configuration information */
#define ID_GEN_NOT_ATA 0x8000 /* Not an ATA device */
#define ID_CAPABILITIES 0x31 /* Capabilities (49)*/
#define ID_CAP_LBA 0x0200 /* LBA supported */
#define ID_CAP_DMA 0x0100 /* DMA supported */
#define ID_FIELD_VALIDITY 0x35 /* Field Validity (53) */
#define ID_FV_88 0x04 /* Word 88 is valid (UDMA) */
#define ID_MULTIWORD_DMA 0x3f /* Multiword DMA (63) */
#define ID_MWDMA_2_SEL 0x0400 /* Mode 2 is selected */
#define ID_MWDMA_1_SEL 0x0200 /* Mode 1 is selected */
#define ID_MWDMA_0_SEL 0x0100 /* Mode 0 is selected */
#define ID_MWDMA_2_SUP 0x0004 /* Mode 2 is supported */
#define ID_MWDMA_1_SUP 0x0002 /* Mode 1 is supported */
#define ID_MWDMA_0_SUP 0x0001 /* Mode 0 is supported */
#define ID_CSS 0x53 /* Command Sets Supported (83) */
#define ID_CSS_LBA48 0x0400
#define ID_ULTRA_DMA 0x58 /* Ultra DMA (88) */
#define ID_UDMA_5_SEL 0x2000 /* Mode 5 is selected */
#define ID_UDMA_4_SEL 0x1000 /* Mode 4 is selected */
#define ID_UDMA_3_SEL 0x0800 /* Mode 3 is selected */
#define ID_UDMA_2_SEL 0x0400 /* Mode 2 is selected */
#define ID_UDMA_1_SEL 0x0200 /* Mode 1 is selected */
#define ID_UDMA_0_SEL 0x0100 /* Mode 0 is selected */
#define ID_UDMA_5_SUP 0x0020 /* Mode 5 is supported */
#define ID_UDMA_4_SUP 0x0010 /* Mode 4 is supported */
#define ID_UDMA_3_SUP 0x0008 /* Mode 3 is supported */
#define ID_UDMA_2_SUP 0x0004 /* Mode 2 is supported */
#define ID_UDMA_1_SUP 0x0002 /* Mode 1 is supported */
#define ID_UDMA_0_SUP 0x0001 /* Mode 0 is supported */
/* DMA registers */
#define DMA_COMMAND 0 /* Command register */
#define DMA_CMD_WRITE 0x08 /* PCI bus master writes */
#define DMA_CMD_START 0x01 /* Start Bus Master */
#define DMA_STATUS 2 /* Status register */
#define DMA_ST_D1_DMACAP 0x40 /* Drive 1 is DMA capable */
#define DMA_ST_D0_DMACAP 0x20 /* Drive 0 is DMA capable */
#define DMA_ST_INT 0x04 /* Interrupt */
#define DMA_ST_ERROR 0x02 /* Error */
#define DMA_ST_BM_ACTIVE 0x01 /* Bus Master IDE Active */
#define DMA_PRDTP 4 /* PRD Table Pointer */
/* Check for the presence of LBA48 only on drives that are 'big'. */
#define LBA48_CHECK_SIZE 0x0f000000
#define LBA_MAX_SIZE 0x0fffffff /* Highest sector size for
* regular LBA.
*/
#if ENABLE_ATAPI
#define ERROR_SENSE 0xF0 /* sense key mask */
#define SENSE_NONE 0x00 /* no sense key */
#define SENSE_RECERR 0x10 /* recovered error */
#define SENSE_NOTRDY 0x20 /* not ready */
#define SENSE_MEDERR 0x30 /* medium error */
#define SENSE_HRDERR 0x40 /* hardware error */
#define SENSE_ILRQST 0x50 /* illegal request */
#define SENSE_UATTN 0x60 /* unit attention */
#define SENSE_DPROT 0x70 /* data protect */
#define SENSE_ABRT 0xb0 /* aborted command */
#define SENSE_MISCOM 0xe0 /* miscompare */
#define ERROR_MCR 0x08 /* media change requested */
#define ERROR_ABRT 0x04 /* aborted command */
#define ERROR_EOM 0x02 /* end of media detected */
#define ERROR_ILI 0x01 /* illegal length indication */
#define REG_FEAT 1 /* features */
#define FEAT_OVERLAP 0x02 /* overlap */
#define FEAT_DMA 0x01 /* dma */
#define REG_IRR 2 /* interrupt reason register */
#define IRR_REL 0x04 /* release */
#define IRR_IO 0x02 /* direction for xfer */
#define IRR_COD 0x01 /* command or data */
#define REG_SAMTAG 3
#define REG_CNT_LO 4 /* low byte of cylinder number */
#define REG_CNT_HI 5 /* high byte of cylinder number */
#define REG_DRIVE 6 /* drive select */
#endif
#define REG_STATUS 7 /* status */
#define STATUS_BSY 0x80 /* controller busy */
#define STATUS_DRDY 0x40 /* drive ready */
#define STATUS_DMADF 0x20 /* dma ready/drive fault */
#define STATUS_SRVCDSC 0x10 /* service or dsc */
#define STATUS_DRQ 0x08 /* data transfer request */
#define STATUS_CORR 0x04 /* correctable error occurred */
#define STATUS_CHECK 0x01 /* check error */
#if ENABLE_ATAPI
#define ATAPI_PACKETCMD 0xA0 /* packet command */
#define ATAPI_IDENTIFY 0xA1 /* identify drive */
#define SCSI_READ10 0x28 /* read from disk */
#define SCSI_SENSE 0x03 /* sense request */
#endif /* ATAPI */
/* Interrupt request lines. */
#define NO_IRQ 0 /* no IRQ set yet */
#define ATAPI_PACKETSIZE 12
#define SENSE_PACKETSIZE 18
/* Error codes */
#define ERR (-1) /* general error */
#define ERR_BAD_SECTOR (-2) /* block marked bad detected */
/* Some controllers don't interrupt, the clock will wake us up. */
#define WAKEUP_SECS 32 /* drive may be out for 31 seconds max */
#define WAKEUP_TICKS (WAKEUP_SECS*system_hz)
/* Miscellaneous. */
#define MAX_DRIVES 8
#define COMPAT_DRIVES 4
#if _WORD_SIZE > 2
#define MAX_SECS 256 /* controller can transfer this many sectors */
#else
#define MAX_SECS 127 /* but not to a 16 bit process */
#endif
#define MAX_ERRORS 4 /* how often to try rd/wt before quitting */
#define NR_MINORS (MAX_DRIVES * DEV_PER_DRIVE)
#define SUB_PER_DRIVE (NR_PARTITIONS * NR_PARTITIONS)
#define NR_SUBDEVS (MAX_DRIVES * SUB_PER_DRIVE)
#define DELAY_USECS 1000 /* controller timeout in microseconds */
#define DELAY_TICKS 1 /* controller timeout in ticks */
#define DEF_TIMEOUT_USECS 5000000L /* controller timeout in microseconds */
#define RECOVERY_USECS 500000 /* controller recovery time in microseconds */
#define RECOVERY_TICKS 30 /* controller recovery time in ticks */
#define INITIALIZED 0x01 /* drive is initialized */
#define DEAF 0x02 /* controller must be reset */
#define SMART 0x04 /* drive supports ATA commands */
#if ENABLE_ATAPI
#define ATAPI 0x08 /* it is an ATAPI device */
#else
#define ATAPI 0 /* don't bother with ATAPI; optimise out */
#endif
#define IDENTIFIED 0x10 /* w_identify done successfully */
#define IGNORING 0x20 /* w_identify failed once */
#define NO_DMA_VAR "ata_no_dma"
/* BIOS parameter table layout. */
#define bp_cylinders(t) (t[0] | (t[1] << 8))
#define bp_heads(t) (t[2])
#define bp_precomp(t) (t[5] | (t[6] << 8))
#define bp_sectors(t) (t[14])