1/* 2 * Copyright 2003-2008, Haiku. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Fran��ois Revol <revol@free.fr> 7 */ 8 9#ifndef _FLOPPY_H 10#define _FLOPPY_H 11 12#include <Drivers.h> 13#include <ISA.h> 14#include <KernelExport.h> 15 16// TODO: switch to native lock. 17#ifdef __HAIKU__ 18#include <lock.h> 19typedef recursive_lock lock; 20#define new_lock recursive_lock_init 21#define free_lock recursive_lock_destroy 22#define LOCK(l) recursive_lock_lock(&l); 23#define UNLOCK(l) recursive_lock_unlock(&l); 24#else 25#ifndef _IMPEXP_KERNEL 26#define _IMPEXP_KERNEL 27#endif 28#include "lock.h" 29#endif 30 31#define FLO "floppy: " 32#if defined(DEBUG) && DEBUG > 0 33# define TRACE(x...) dprintf(FLO x) 34#else 35# define TRACE(x...) 36#endif 37 38#define MOTOR_TIMEOUT 5000000 // 5 seconds 39#define MOTOR_SPINUP_DELAY 500000 // 500 msecs 40#define FLOPPY_CMD_TIMEOUT 500000 // .5s 41#define MAX_DRIVES_PER_CTRL 2 42#define CYL_BUFFER_SIZE (5*B_PAGE_SIZE) 43 44/*** those belong to ISA.h ***/ 45#define B_DMA_MODE_DEMAND 0x00 // modeByte bits for various dma modes 46#define B_DMA_MODE_BLOCK 0x80 47#define B_DMA_MODE_SINGLE 0x40 48 49#define B_DMA_MODE_MEMR 0x08 // modeByte memory read or write 50#define B_DMA_MODE_MEMW 0x04 51/*** !ISA.h ***/ 52 53typedef enum { 54 FLOP_NO_MEDIA, 55 FLOP_MEDIA_CHANGED, 56 FLOP_MEDIA_UNREADABLE, 57 FLOP_MEDIA_FORMAT_FOUND, 58 FLOP_WORKING 59} floppy_status; 60 61#define CMD_MODE 0x01 62#define CMD_SETTRK 0x21 //21 63#define CMD_READTRK 0x02 64#define CMD_SPECIFY 0x03 65#define CMD_SENSED 0x04 66#define CMD_WRITED 0x05 67#define CMD_READD 0x06 68#define CMD_RECAL 0x07 69#define CMD_SENSEI 0x08 70#define CMD_WRITEDD 0x09 71#define CMD_READID 0x0A 72#define CMD_READDD 0x0C 73#define CMD_FORMAT 0x0D 74#define CMD_DUMPREG 0x0E 75#define CMD_SEEK 0x0F 76#define CMD_RELSEEK 0x8F //8F 77#define CMD_VERSION 0x10 78#define CMD_SCANE 0x11 79#define CMD_PERPEND 0x12 80#define CMD_CONFIG 0x13 81#define CMD_LOCK 0x14 82#define CMD_VERIFY 0x16 83#define CMD_SCANLE 0x19 84#define CMD_SCANHE 0x1D 85 86#define CMD_RESET 0xF0 87#define CMD_SWITCH_MASK 0x1F 88 89typedef struct floppy_geometry { 90 int gap; 91 int numsectors; 92 int data_rate; 93 int format_gap; 94 int side2_offset; 95 device_geometry g; 96 int flags; 97 const char *name; 98} floppy_geometry; 99 100extern const floppy_geometry supported_geometries[]; 101 102#define FL_MFM 0x0001 /* MFM recording */ 103#define FL_2STEP 0x0002 /* 2 steps between cylinders */ 104#define FL_PERP 0x0004 /* perpendicular recording */ 105 106#define FDC_500KBPS 0x00 /* 500KBPS MFM drive transfer rate */ 107#define FDC_300KBPS 0x01 /* 300KBPS MFM drive transfer rate */ 108#define FDC_250KBPS 0x02 /* 250KBPS MFM drive transfer rate */ 109#define FDC_1MBPS 0x03 /* 1MPBS MFM drive transfer rate */ 110 111#define FDC_MAX_CYLINDER 85 112 113typedef struct floppy { 114 const floppy_geometry *geometry; 115 device_geometry bgeom; 116 uint32 iobase; /* controller address */ 117 uint32 irq; 118 int32 dma; 119 int drive_num; /* number of this drive */ 120 int current; /* currently selected drive */ 121 floppy_status status; 122 sem_id completion; 123 uint16 pending_cmd; 124 uint8 result[8]; /* status of the last finished command */ 125 126 lock ben; 127 spinlock slock; 128 isa_module_info *isa; 129 130 uint8 data_rate; /* FDC_*BPS */ 131 uint32 motor_timeout; 132 133 area_id buffer_area; 134 uint8 *buffer; 135 long buffer_index; /* index at which to put/get the next byte in the buffer */ 136 long avail; /* valid bytes in the buffer */ 137 int track; /* the track currently in the cylinder buffer */ 138 139 struct floppy *master; /* the 'controller' */ 140 struct floppy *next; /* next floppy for same controller */ 141} floppy_t; 142 143typedef struct { 144 uint8 id; 145 uint8 drive; 146 uint8 cylinder; 147 uint8 head; 148 uint8 sector; 149 uint8 sector_size; 150 uint8 track_length; 151 uint8 gap3_length; 152 uint8 data_length; 153} floppy_command; 154 155typedef struct { 156 uint8 st0; 157 uint8 st1; 158 uint8 st2; 159 uint8 cylinder; 160 uint8 head; 161 uint8 sector; 162 uint8 sector_size; 163} floppy_result; 164 165typedef enum { 166 STATUS_A = 0, 167 STATUS_B = 1, 168 DIGITAL_OUT = 2, 169 TAPE_DRIVE = 3, 170 MAIN_STATUS = 4, 171 DATA_RATE_SELECT = 4, 172 DATA = 5, 173 /* RESERVED = 6, */ 174 DIGITAL_IN = 7, 175 CONFIG_CONTROL = 7 176} floppy_reg_selector; 177 178#define FDC_SR0_IC 0xc0 179#define FDC_SR0_SE 0x20 180#define FDC_SR0_EC 0x10 181#define FDC_SR0_HS 0x04 182#define FDC_SR0_DS 0x03 183 184/* low level */ 185extern void write_reg(floppy_t *flp, floppy_reg_selector selector, uint8 data); 186extern uint8 read_reg(floppy_t *flp, floppy_reg_selector selector); 187 188/* init */ 189 /* initialize the controller */ 190extern void reset_controller(floppy_t *master); 191 /* returns a bitmap of the present drives */ 192extern int count_floppies(floppy_t *master); 193 /* seek to track 0 and detect drive presence */ 194extern int recalibrate_drive(floppy_t *flp); 195/* debug */ 196 /* issue dumpreg command */ 197extern void floppy_dump_reg(floppy_t *flp); 198 199/* drive handling */ 200extern void drive_select(floppy_t *flp); 201extern void drive_deselect(floppy_t *flp); 202extern void turn_on_motor(floppy_t *flp); 203extern void turn_off_motor(floppy_t *flp); 204 205/* transactions */ 206extern void wait_for_rqm(floppy_t *flp); 207extern bool can_read_result(floppy_t *flp); 208 /* send a command and schedule for irq */ 209extern int send_command(floppy_t *flp, const uint8 *data, int len); 210extern int wait_til_ready(floppy_t *flp); 211 /* called by irq handler */ 212extern int read_result(floppy_t *flp, uint8 *data, int len); 213 /* wait for the irq to occur */ 214extern int wait_result(floppy_t *flp); 215 216extern int32 flo_intr(void *arg); 217 218 /* read sectors to internal flp->master->buffer */ 219extern ssize_t pio_read_sectors(floppy_t *flp, int lba, int num_sectors); 220 /* write sectors from internal flp->master->buffer */ 221extern ssize_t pio_write_sectors(floppy_t *flp, int lba, int num_sectors); 222 /* read a track to internal flp->master->buffer */ 223extern ssize_t pio_read_track(floppy_t *flp, int lba); 224 225/* high level */ 226 /* query the media type and fill the geometry information */ 227extern status_t query_media(floppy_t *flp, bool forceupdate); 228 229extern ssize_t read_sectors(floppy_t *flp, int lba, int num_sectors); 230 231#endif /* _FLOPPY_H */ 232