/* IBM_PROLOG_BEGIN_TAG */ /* This is an automatically generated prolog. */ /* */ /* bos720 src/bos/usr/samples/fd/fd_local.h 1.1 */ /* */ /* Licensed Materials - Property of IBM */ /* */ /* COPYRIGHT International Business Machines Corp. 1988,1993 */ /* All Rights Reserved */ /* */ /* US Government Users Restricted Rights - Use, duplication or */ /* disclosure restricted by GSA ADP Schedule Contract with IBM Corp. */ /* */ /* IBM_PROLOG_END_TAG */ /* @(#)67 1.1 src/bos/usr/samples/fd/fd_local.h, fdsamp, bos720 10/12/93 14:36:13 */ #ifndef _H_FD_LOCAL #define _H_FD_LOCAL /* * COMPONENT_NAME: FDSAMP (Diskette Device Driver) * * FUNCTIONS: None * * ORIGINS: 27 * * * (C) COPYRIGHT International Business Machines Corp. 1988,1993 * All Rights Reserved * Licensed Materials - Property of IBM * US Government Users Restricted Rights - Use, duplication or * disclosure restricted by GSA ADP Schedule Contract with IBM Corp. */ /* NOTICE TO USERS OF THE SOURCE CODE EXAMPLES THE SOURCE CODE EXAMPLES PROVIDED BY IBM ARE ONLY INTENDED TO ASSIST IN THE DEVELOPMENT OF A WORKING SOFTWARE PROGRAM. THE SOURCE CODE EXAMPLES DO NOT FUNCTION AS WRITTEN: ADDITIONAL CODE IS REQUIRED. IN ADDITION, THE SOURCE CODE EXAMPLES MAY NOT COMPILE AND/OR BIND SUCCESSFULLY AS WRITTEN. INTERNATIONAL BUSINESS MACHINES CORPORATION PROVIDES THE SOURCE CODE EXAMPLES, BOTH INDIVIDUALLY AND AS ONE OR MORE GROUPS, "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOURCE CODE EXAMPLES, BOTH INDIVIDUALLY AND AS ONE OR MORE GROUPS, IS WITH YOU. SHOULD ANY PART OF THE SOURCE CODE EXAMPLES PROVE DEFECTIVE, YOU (AND NOT IBM OR AN AUTHORIZED RISC System/6000* WORKSTATION DEALER) ASSUME THE ENTIRE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. IBM does not warrant that the contents of the source code examples, whether individually or as one or more groups, will meet your requirements or that the source code examples are error-free. IBM may make improvements and/or changes in the source code examples at any time. Changes may be made periodically to the information in the source code examples; these changes may be reported, for the sample device drivers included herein, in new editions of the examples. References in the source code examples to IBM products, programs, or services do not imply that IBM intends to make these available in all countries in which IBM operates. Any reference to an IBM licensed program in the source code examples is not intended to state or imply that only IBM's licensed program may be used. Any functionally equivalent program may be used. * RISC System/6000 is a trademark of International Business Machines Corporation. */ /* * Defines for constants */ #define FDMAXDRIVES 2 /* maximum number of drives allowed */ #define FDMAX_SIMPLE_RETRIES1 3 /* maximum # of times to just retry the command initially */ #define FDMAX_COMPLEX_RETRIES 5 /* maximum # of times to retry the command after doing a reset */ #define FDMAX_SIMPLE_RETRIES2 6 /* maximum # of times to just retry the command after complex retry */ #define FDMAX_LOOP_TIME 50000000 /* # of nanoseconds before timeout */ #define FDDISK_CHANGE 0x80 /* value that indicates the door has been opened */ #define FDMT 0x80 /* multi-track r/w (0x00 off, 0x80 on) */ #define FDMFM 0x40 /* MFM data encoding scheme (0x00 off, 0x40 on) */ #define FDDMA 0x00 /* DMA mode (0x0 on, 0x1 off) */ #define FDNORMAL 0xc0 /* mask for determining if a command completed normally */ #define FDREAD_MASK 0xC0 /* mask indicating a read operation */ #define FDWRITE_MASK 0x80 /* mask indicating a write operation */ #define FDRFM_MASK 0x80 /* mask indicating controller ready */ #define FDINVALID_MASK 0x80 /* mask indicating invalid command */ #define FDINT_MASK 0x02 /* mask indicating a diskette interrupt */ #define FDTYPEMASK 0x3f /* mask to delete the drive number */ #define FDSIZEMASK 0xdf /* mask to delete the diskette diameter flag */ #define FDCONTROLMASK 0x0c /* master DMA and interrupt enable, controller not reset */ #define FDRESETMASK 0x08 /* enable DMA and interrupts, controller reset */ #define FDNOINTRESETMASK 0x00 /* disable DMA and interrupts, controller reset */ #define FDDISABLEMASK 0x04 /* disable DMA and interrupts, controller not reset */ #define FDDRIVE_0_MASK 0x10 /* mask to enable drive 0 */ #define FDNO_DRIVE 0xff /* used to indicate no drive running */ #define FDSUCCESS 0 /* return code for successful subroutine completion */ #define FDFAILURE -1 /* return code for unsuccessful subroutine completion */ #define FDENABLEREG 0x00400002 #define FDARBREG 0x00400004 /* * Diskette Controller Register Offsets */ #define FDDRIVE_CONTROL_REG 0 /* write only */ #define FDMAIN_STATUS_REG 2 /* read only */ #define FDDISKETTE_DATA_REG 3 /* read/write */ #define FDDATA_RATE_REG 5 /* write only */ #define FDDISK_CHANGED_REG 5 /* read only */ /* * Diskette interrupt handler states */ #define FD_NO_STATE 0 #define FD_TYPE1_WAKEUP 1 #define FD_TYPE2_WAKEUP 2 #define FD_FORMAT 3 #define FD_SPEED 4 #define FD_SETTLE 5 #define FD_RW 6 #define FD_INITIAL_INTERRUPT 7 #define FD_IO_RESET 8 /* * Diskette interrupt handler sub-states */ #define FD_SPEED_READ1 1 #define FD_SPEED_READ2 2 #define FD_SETTLE_READ1 3 #define FD_SETTLE_SEEK 4 #define FD_SETTLE_WRITE 5 #define FD_SETTLE_READ2 6 #define FD_RW_SEEK1 7 #define FD_RW_RECAL1 8 #define FD_RW_RECAL2 9 #define FD_RW_RECAL3 10 #define FD_RW_SEEK2 11 #define FD_RW_DRCHK_RECAL 12 #define FD_RW_DRCHK_SEEK 13 #define FD_RW_SUB 14 #define FD_RW_RESET 15 /* * Diskette timer sub-states */ #define FD_SETTLE_TIMER 32 #define FD_RW_DELAY_TIMER 33 /* * Macros for writing and reading data to and from the diskette controller */ #define FDWRITE(offset, data) BUSIO_PUTC((caddr_t)(offset), data) #define FDREAD(offset) BUSIO_GETC((caddr_t)(offset)) /* * Structure for storing the physical address of data. */ struct phys_add { uchar cylinder; uchar head; uchar sector; uint transfer_length; /* length (in bytes) of the current transfer */ }; /* * Structure to store the result phase data from a diskette controller * operation before storing the data in the floppy structure. */ struct result_bytes { uchar total_bytes; /* number of bytes in this result */ union { struct { union { uchar status0; /* all reads, write, format track, sense int */ uchar status3; /* sense drive status */ uchar value; /* set track */ } byte0; union { uchar status1; /* all reads, write, format track */ uchar present_track; /* sense interrupt */ } byte1; uchar status2; /* all reads, write, format track */ uchar track; /* all reads, write, format track */ uchar head; /* all reads, write, format track */ uchar sector; /* all reads, write, format track */ uchar sector_size; /* all reads, write, format track */ } names; uchar result_array[7]; } un1; }; /* * Structure to build a command phase in before sending it to the * diskette controller. */ struct command_bytes { uchar total_bytes; /* number of bytes in this command */ union { struct { uchar command1; /* all commands, identifies command */ #define FDREAD_DATA 0x06 #define FDREAD_ID 0x0a #define FDFORMAT_TRACK 0x0d #define FDWRITE_DATA 0x05 #define FDSEEK 0x0f #define FDRECALIBRATE 0x07 #define FDSENSE_INTERRUPT 0x08 #define FDSENSE_DRIVE_STATUS 0x04 #define FDSPECIFY 0x03 /* * The following commands do not use the controller data register. */ #define FDDISABLE_CONTROLLER 0xaf #define FDENABLE_CONTROLLER 0xbf #define FDDRIVE_SELECT 0xcf #define FDSET_DATA_RATE 0xdf #define FDSOFT_RESET 0xef #define FDHARD_RESET 0xff uchar command2; /* all commands */ union { uchar track; /* read data, write data, seek */ uchar sector_size; /* format track */ uchar motor_time; /* specify */ } byte2; union { uchar head; /* read data, write data */ uchar sectors_per_track;/* format track */ } byte3; union { uchar sector; /* read data, write data */ uchar gap_length; /* format track */ } byte4; union { uchar sector_size; /* read data, write data */ uchar data_pattern; /* format track */ } byte5; uchar eot_sector; /* read data, write data */ uchar gap_length; /* read data, write data */ uchar data_length; /* read data, write data */ } cmds; uchar command_array[9]; } un1; }; /* * The following is the structure that is used to pass information * between the different parts of the device driver. */ struct floppy { dev_t device_number; /* save off the 'devno' for later use */ uchar initialized; /* is diskette drive initialized? */ uchar drive_state; /* current state of the drive */ #define FDOPEN 1 #define FDOPENING 2 #define FDCLOSED 4 #define FDCLOSING 8 uchar first_move; /* is this the first move of the drive heads after opening? */ uchar drive_type; /* type of diskette drive, uses same defines as fdinfo structure. */ uchar diskette_type; /* type of diskette in the drive */ #define FDUNKNOWN 0 uchar sector_size; /* encoded number of bytes in a sector */ uchar tracks_per_cylinder; /* number of tracks per cylinder */ uchar step_size; /* 1 or 2 depending on drive/diskette combination */ uchar data_rate; /* data rate setting for diskette type */ uchar head_load; /* head load time for diskette type */ uchar head_unload; /* head unload time for diskette type */ uchar step_rate; /* step rate for diskette type */ uchar step_rate_time; /* step rate for diskette type (in milliseconds) */ uchar gap; /* inter-sector gap length */ uchar format_gap; /* format inter-sector gap length */ uchar retry_flag; /* 0 = disabled, anything else = enabled */ uchar fill_byte; /* fill byte for formmating */ uchar cylinder_id; /* cylinder number for SEEK ioctls */ uchar head_id; /* head number for READ_ID ioctls */ uchar head_settle_time; /* head settle time (milliseconds) */ uchar data_length; /* data length controller parameter */ uchar last_error1; /* last error type that failed retries (status register 1 value) */ uchar last_error2; /* last error type that failed retries (status register 2 value) */ uchar motor_off_time; /* inactive time before motor turned off (seconds) */ ushort format_size; /* size of format buffer */ ushort sectors_per_track; /* number of sectors per track */ ushort sectors_per_cylinder; /* number of sectors per cylinder */ ushort cylinders_per_disk; /* number of cylinders on the disk */ ushort bytes_per_sector; /* raw sector size */ ushort number_of_blocks; /* total number of blocks on the disk */ ushort motor_start; /* motor start time (in milliseconds) */ ushort motor_ticks; /* motor start time (in timer ticks) */ ushort start_block; /* starting block # for read or write */ int dma_flags; /* flags passed to the DMA services */ uint total_bcount; /* total number of bytes transfered so far */ uint modified_bcount; /* modified byte count for transfers */ uint simple_count1; /* first simple retry count for the i/o operation */ uint complex_count; /* complex retry count for the i/o operation */ uint simple_count2; /* second simple retry count for the i/o operation */ uint buf_offset; /* the offset in the data buffer for this io */ uint motor_speed; /* motor speed (rpm) */ uint motor_speed_time; /* motor speed (microseconds) */ ulong settle_delay; /* delay used during settle test (nanoseconds) */ ulong rcount_bytes; /* the next four variables keep */ ulong rcount_megabytes; /* track of the number of bytes */ ulong wcount_bytes; /* transfered since the drive was */ ulong wcount_megabytes; /* last configured */ struct buf *headptr; /* pointer to first queued buffer header */ struct buf *tailptr; /* pointer to last queued buffer header */ struct xmem xmem; /* cross memory descriptor */ struct phys_add start; /* starting address for read/write for the requested block */ struct phys_add current;/* current starting address for the io this is used to keep track of where an intermediate io operation started during large read or write requests */ char resource_name[8]; /* name for error logging */ }; /* * Diskette error logging structure. */ struct fd_err_rec { struct err_rec0 header; struct fd_status data; }; /* * Structure used for passing parameters to pio_assist routines. */ struct pio_parms { volatile uchar data; /* data byte */ char read; /* is this a read? */ ulong reg; /* i/o register offset */ caddr_t bus_val; /* bus id value */ }; /* * structure to keep config parameters around to reset to if needed. */ struct fdconfig_parameters { uchar head_settle; uchar step_rate; ushort motor_start; ushort type; }; /* * Structure describing controller (global) status. */ struct adapter_structure { uchar adapter_dead; /* has a fatal error occurred? */ uchar adapter_busy; /* is the interrupt handler busy? */ uchar active_drive; /* valid values are 0 or 1 */ uchar motor_on; /* which drive motor is on? */ uchar data_rate; /* encoded data rate in use */ uchar int_class; /* diskette interrupt class */ uchar slot_num; /* diskette adapter slot number */ uchar initialized; /* are adapter structures initialized? */ uchar pinned; /* is the adapter structure pinned? */ uchar int_init; /* is the interrupt handler defined? */ uchar dma_init; /* is the dma channel defined? */ uchar reset_needed; /* a reset is needed */ uchar d_comp_needed; /* is a d_complete needed? */ uchar first_open; /* is this the first open after config? */ ushort bus_type; /* type of i/o bus */ ushort state; /* interrupt state */ ushort sub_state; /* interrupt sub-state */ int sleep_anchor; /* event word for waiting on interrupts */ int adapter_sleep_anchor; /* event word for adapter lock */ int dma_level; /* DMA arbitration level */ int bus_int_level; /* diskette bus interrupt level */ int dma_id; /* DMA channel id */ int error_value; /* error value set at interrupt level */ uint adapter_id; /* adapter type id (used by RAS) */ ulong bus_id; /* io bus id */ ulong actual_delay; /* actual time delayed for settle ioctl */ ulong fudge_factor; /* compensation value for settle ioctl */ ulong io_address; /* start of diskette io addresses */ ulong data_reg_excess; /* number of times data register delay exceeded 50 microseconds */ char *format_buffer; /* pointer to buffer with format info */ char *speed_buffer; /* pointer to buffer for speed and settle ioctls */ struct intr *fdhandler; /* pointer to interrupt handler structure */ struct trb *fdstart_timer; /* timer structure for interrupt level delays */ struct trb *fdsettle_timer; /* timer structure for head settle test */ struct fd_err_rec *fderrptr; /* pointer to error log structure */ struct xmem xdp; /* xmem descriptor for speed and settle ioctls */ struct timestruc_t start_time; struct timestruc_t end_time; struct watchdog inttimer; /* interrupt watchdog timer structure */ struct watchdog mottimer; /* motor watchdog timer structure */ struct command_bytes command; /* last command executed */ struct result_bytes results; /* results of the last executed command */ struct floppy *drive_list[FDMAXDRIVES]; /* list of pointers to device structures */ struct fdconfig_parameters *fdconfparms[FDMAXDRIVES]; }; /* * Top half device driver entry points. */ #ifndef _NO_PROTO int fd_config( dev_t devno, int cmd, register struct uio *uiop ); int fd_open( dev_t devno, ulong devflag ); int fd_close( dev_t devno ); int fd_read( dev_t devno, register struct uio *uiop ); int fd_write( dev_t devno, register struct uio *uiop ); int fd_ioctl( dev_t devno, int op, register long arg, ulong devflag ); #else int fd_config(); int fd_open(); int fd_close(); int fd_read(); int fd_write(); int fd_ioctl(); #endif /* * Additional top half internal device driver routines. */ #ifndef _NO_PROTO int fddoor_check(); int fdtype(); int nodev(); int fdconfig_vpd( register struct floppy *fdp, register struct fd_vpd *vpdptr, uchar drive_number ); int fdconfig_reset( register struct pio_parms *piop ); int fdconfig_soft_reset( register struct pio_parms *piop ); int fdconfig_specify( register struct floppy *fdp, register struct pio_parms *piop ); int fdconfig_motor_start( register struct floppy *fdp, register struct pio_parms *piop, uchar drive_number ); int fdconfig_motor_stop( register struct pio_parms *piop ); int fdconfig_recalibrate( register struct floppy *fdp, register struct pio_parms *piop, uchar drive_number ); int fdconfig_sense_interrupt( register struct floppy *fdp, register struct pio_parms *piop ); int fdconfig_seek( register struct floppy *fdp, register struct pio_parms *piop, uchar drive_number ); void fd_qvpd_exit( register struct fd_vpd *vpdptr, register struct iovec *localuio_iovec ); #else int fddoor_check(); int fdtype(); int nodev(); int fdconfig_vpd(); int fdconfig_reset(); int fdconfig_soft_reset(); int fdconfig_specify(); int fdconfig_motor_start(); int fdconfig_motor_stop(); int fdconfig_recalibrate(); int fdconfig_sense_interrupt(); int fdconfig_seek(); void fd_qvpd_exit(); #endif /* * Bottom half device driver entry points. */ #ifndef _NO_PROTO int fd_strategy( register struct buf *bp ); int fd_intr(); #else int fd_strategy(); int fd_intr(); #endif /* * Additional bottom half internal device driver routines. */ #ifndef _NO_PROTO uchar fdread_change_line(); uchar fdread_main_status(); int fdload_floppy( int value, register struct floppy *fdp ); int fdrw_exit( register struct floppy *fdp, int errno_value ); int fdio_exit( register struct floppy *fdp, int errno_value ); int fdiocformat( long arg ); void fdformat_track(); int fddata_reg_pio( caddr_t parms ); int fdcfg_data_pio( caddr_t parms ); int fdlock_adapter( int drive_number ); void fdunlock_adapter( int drive_number ); int fddata_reg_pio_recovery( caddr_t parms, int action ); int fdcfg_data_pio_recovery( caddr_t parms, int action ); int fdcntl_reg_pio( caddr_t parms ); int fdcfg_cntl_pio( caddr_t parms ); int fdcntl_reg_pio_recovery( caddr_t parms, int action ); int fdcfg_cntl_pio_recovery( caddr_t parms, int action ); void fdmotor_start(); void fdreset_check(); void fdio( register struct buf *bp ); void fdsettle_timer_handler( register struct trb *settle_timer ); void fdlog_error( register struct floppy *fdp, uchar value ); void fdtimeout( register struct trb *fdstart_timer_ptr ); void fdwatchdog( register struct watchdog *timer ); void fdmotor_timer( register struct watchdog *timer ); int fdiocrecal(); void fdrecalibrate(); int fdiocseek(); void fdseek(); int fdiocspeed(); int fdiocsettle( long arg ); void fdrw(); void fdrw_ioctl(); int fdiocreset(); void fdreset(); void fdset_data_rate(); void fdselect_drive(); void fdenable_controller(); void fddisable_controller(); void fdsoft_reset(); void fdsense_interrupt(); void fdsense_drive_status(); void fdspecify(); void fdreadid(); void fdassign_error( register struct floppy *fdp ); int fdexecute_int_cmd( void (*func)() ); int fdqueue_check( register struct floppy *fdp, int drive_number ); #else int fdlock_adapter(); void fdunlock_adapter(); uchar fdread_change_line(); uchar fdread_main_status(); int fdiocformat(); void fdformat_track(); int fdload_floppy(); int fdrw_exit(); int fdio_exit(); int fddata_reg_pio(); int fdcfg_data_pio(); int fddata_reg_pio_recovery(); int fdcfg_data_pio_recovery(); int fdcntl_reg_pio(); int fdcfg_cntl_pio(); int fdcntl_reg_pio_recovery(); int fdcfg_cntl_pio_recovery(); void fdmotor_start(); void fdreset_check(); void fdio(); void fdsettle_timer_handler(); void fdlog_error(); void fdtimeout(); void fdwatchdog(); void fdmotor_timer(); int fdiocrecal(); void fdrecalibrate(); int fdiocseek(); void fdseek(); int fdiocspeed(); int fdiocsettle(); int fdiocreset(); void fdreset(); void fdset_data_rate(); void fdselect_drive(); void fdenable_controller(); void fddisable_controller(); void fdsoft_reset(); void fdsense_interrupt(); void fdsense_drive_status(); void fdspecify(); void fdreadid(); void fdrw(); void fdrw_ioctl(); void fdassign_error(); int fdexecute_int_cmd(); int fdqueue_check(); #endif #endif /* ! _H_FD_LOCAL */