Home | History | Annotate | Line # | Download | only in dev
fd.c revision 1.2
      1  1.1  chopps /*
      2  1.1  chopps  * Copyright (c) 1994 Brad Pepers
      3  1.1  chopps  * All rights reserved.
      4  1.1  chopps  *
      5  1.1  chopps  * This code is derived from software contributed to Berkeley by
      6  1.1  chopps  * Brad Pepers.
      7  1.1  chopps  *
      8  1.1  chopps  * Redistribution and use in source and binary forms, with or without
      9  1.1  chopps  * modification, are permitted provided that the following conditions
     10  1.1  chopps  * are met:
     11  1.1  chopps  * 1. Redistributions of source code must retain the above copyright
     12  1.1  chopps  *    notice, this list of conditions and the following disclaimer.
     13  1.1  chopps  * 2. Redistributions in binary form must reproduce the above copyright
     14  1.1  chopps  *    notice, this list of conditions and the following disclaimer in the
     15  1.1  chopps  *    documentation and/or other materials provided with the distribution.
     16  1.1  chopps  * 3. All advertising materials mentioning features or use of this software
     17  1.1  chopps  *    must display the following acknowledgement:
     18  1.1  chopps  *	This product includes software developed by the University of
     19  1.1  chopps  *	California, Berkeley and its contributors.
     20  1.1  chopps  * 4. Neither the name of the University nor the names of its contributors
     21  1.1  chopps  *    may be used to endorse or promote products derived from this software
     22  1.1  chopps  *    without specific prior written permission.
     23  1.1  chopps  *
     24  1.1  chopps  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     25  1.1  chopps  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     26  1.1  chopps  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     27  1.1  chopps  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     28  1.1  chopps  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     29  1.1  chopps  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     30  1.1  chopps  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     31  1.1  chopps  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     32  1.1  chopps  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     33  1.1  chopps  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     34  1.1  chopps  * SUCH DAMAGE.
     35  1.1  chopps  *
     36  1.1  chopps  */
     37  1.1  chopps 
     38  1.1  chopps /*
     39  1.1  chopps  * floppy interface
     40  1.1  chopps  */
     41  1.1  chopps 
     42  1.1  chopps #include "fd.h"
     43  1.1  chopps #if NFD > 0
     44  1.1  chopps 
     45  1.1  chopps #include <sys/param.h>
     46  1.1  chopps #include <sys/systm.h>
     47  1.1  chopps #include <sys/buf.h>
     48  1.1  chopps #include <sys/dkstat.h>
     49  1.1  chopps #include <sys/disklabel.h>
     50  1.1  chopps #include <sys/malloc.h>
     51  1.1  chopps #include <sys/proc.h>
     52  1.1  chopps #include <sys/reboot.h>
     53  1.1  chopps #include <sys/file.h>
     54  1.1  chopps #include <sys/ioctl.h>
     55  1.1  chopps 
     56  1.1  chopps #include <amiga/dev/device.h>
     57  1.1  chopps #include <amiga/amiga/cia.h>
     58  1.1  chopps #include <amiga/amiga/custom.h>
     59  1.1  chopps 
     60  1.1  chopps #define UNIT(x)		(minor(x) & 3)
     61  1.1  chopps #define	b_cylin		b_resid
     62  1.1  chopps #define FDBLK 512
     63  1.1  chopps #define MAX_SECTS 22
     64  1.1  chopps #define IMMED_WRITE 0
     65  1.1  chopps 
     66  1.1  chopps int fdattach();
     67  1.1  chopps struct	driver fddriver = {
     68  1.1  chopps 	fdattach, "fd",
     69  1.1  chopps };
     70  1.1  chopps 
     71  1.1  chopps /* defines */
     72  1.1  chopps #define MFM_SYNC	0x4489
     73  1.1  chopps #define DSKLEN_DMAEN    (1<<15)
     74  1.1  chopps #define DSKLEN_WRITE    (1<<14)
     75  1.1  chopps 
     76  1.1  chopps /* drive type values */
     77  1.1  chopps #define FD_NONE		0x00000000
     78  1.1  chopps #define FD_DD_3		0xffffffff	/* double-density 3.5" (880K) */
     79  1.1  chopps #define FD_HD_3		0x55555555	/* high-density 3.5" (1760K) */
     80  1.1  chopps 
     81  1.1  chopps struct fd_type {
     82  1.1  chopps 	int id;
     83  1.1  chopps 	char *name;
     84  1.1  chopps 	int tracks;
     85  1.1  chopps 	int heads;
     86  1.1  chopps 	int read_size;
     87  1.1  chopps 	int write_size;
     88  1.1  chopps 	int sect_mult;
     89  1.1  chopps 	int precomp1;
     90  1.1  chopps 	int precomp2;
     91  1.1  chopps 	int step_delay;
     92  1.1  chopps 	int side_time;
     93  1.1  chopps 	int settle_time;
     94  1.1  chopps };
     95  1.1  chopps 
     96  1.1  chopps struct fd_type drive_types[] = {
     97  1.1  chopps /*	    id       name      tr he  rdsz   wrsz  sm pc1  pc2 sd  st st  */
     98  1.1  chopps 	{ FD_DD_3, "DD 3.5", 80, 2, 14716, 13630, 1, 80, 161, 3, 18, 1 },
     99  1.1  chopps 	{ FD_HD_3, "HD 3.5", 80, 2, 29432, 27260, 2, 80, 161, 3, 18, 1 },
    100  1.1  chopps 	{ FD_NONE, "No Drive", 0, }
    101  1.1  chopps };
    102  1.1  chopps int num_dr_types = sizeof(drive_types) / sizeof(drive_types[0]);
    103  1.1  chopps 
    104  1.1  chopps /*
    105  1.1  chopps  * Per drive structure.
    106  1.1  chopps  * N per controller (presently 4) (DRVS_PER_CTLR)
    107  1.1  chopps  */
    108  1.1  chopps #define DRVS_PER_CTLR 4
    109  1.1  chopps struct fd_data {
    110  1.1  chopps 	int fdu;		/* This unit number */
    111  1.1  chopps 	struct buf head;	/* Head of buf chain      */
    112  1.1  chopps 	struct buf rhead;	/* Raw head of buf chain  */
    113  1.1  chopps 	int type;		/* Drive type */
    114  1.1  chopps 	struct fd_type *ft;	/* Pointer to type descriptor */
    115  1.1  chopps 	int flags;
    116  1.1  chopps #define	FDF_OPEN	0x01	/* it's open		*/
    117  1.1  chopps 	int skip;
    118  1.1  chopps 	int sects;		/* number of sectors in a track */
    119  1.1  chopps 	int size;		/* size of disk in sectors */
    120  1.1  chopps 	int side;		/* current side disk is on */
    121  1.1  chopps 	int dir;		/* current direction of stepping */
    122  1.1  chopps 	int cyl;		/* current cylinder disk is on */
    123  1.1  chopps 	int buf_track;
    124  1.1  chopps 	int buf_dirty;
    125  1.1  chopps 	char *buf_data;
    126  1.1  chopps 	char *buf_labels;
    127  1.1  chopps 	int write_cnt;
    128  1.1  chopps };
    129  1.1  chopps 
    130  1.1  chopps /*
    131  1.1  chopps  * Per controller structure.
    132  1.1  chopps  */
    133  1.1  chopps struct fdc_data
    134  1.1  chopps {
    135  1.1  chopps 	int fdcu;		/* our unit number */
    136  1.1  chopps 	struct fd_data *fd;	/* drive we are currently doing work for */
    137  1.1  chopps 	int motor_fdu;	/* drive that has its motor on */
    138  1.1  chopps 	int state;
    139  1.1  chopps 	int saved;
    140  1.1  chopps 	int retry;
    141  1.1  chopps 	struct fd_data fd_data[DRVS_PER_CTLR];
    142  1.1  chopps };
    143  1.1  chopps struct fdc_data fdc_data[NFD];
    144  1.1  chopps 
    145  1.1  chopps /*
    146  1.1  chopps  * Throughout this file the following conventions will be used:
    147  1.1  chopps  *
    148  1.1  chopps  * fd is a pointer to the fd_data struct for the drive in question
    149  1.1  chopps  * fdc is a pointer to the fdc_data struct for the controller
    150  1.1  chopps  * fdu is the floppy drive unit number
    151  1.1  chopps  * fdcu is the floppy controller unit number
    152  1.1  chopps  * fdsu is the floppy drive unit number on that controller. (sub-unit)
    153  1.1  chopps  */
    154  1.1  chopps typedef int	fdu_t;
    155  1.1  chopps typedef int	fdcu_t;
    156  1.1  chopps typedef int	fdsu_t;
    157  1.1  chopps typedef	struct fd_data *fd_p;
    158  1.1  chopps typedef struct fdc_data *fdc_p;
    159  1.1  chopps 
    160  1.1  chopps /*
    161  1.1  chopps  * protos.
    162  1.1  chopps  */
    163  1.1  chopps static int delay __P((int));
    164  1.1  chopps void encode __P((u_long, u_long *, u_long *));
    165  1.1  chopps void fd_step __P((void));
    166  1.1  chopps void fd_seek __P((fd_p, int));
    167  1.1  chopps void correct __P((u_long *));
    168  1.1  chopps void fd_probe __P((fd_p));
    169  1.1  chopps void fd_turnon __P((fdc_p, fdu_t));
    170  1.1  chopps void fd_turnoff __P((fdc_p));
    171  1.1  chopps void track_read __P((fdc_p, fd_p, int));
    172  1.1  chopps void fd_timeout __P((fdc_p));
    173  1.1  chopps void fd_motor_to __P((fdcu_t));
    174  1.1  chopps void fd_motor_on __P((fdc_p, fdu_t));
    175  1.1  chopps void track_write __P((fdc_p, fd_p));
    176  1.1  chopps void amiga_write __P((fd_p));
    177  1.1  chopps void fd_calibrate __P((fd_p));
    178  1.1  chopps void encode_block __P((u_long *, u_char *, int, u_long *));
    179  1.1  chopps void fd_select_dir __P((fd_p, int));
    180  1.1  chopps void fd_pseudointr __P((fdc_p));
    181  1.1  chopps void fd_select_side __P((fd_p, int));
    182  1.1  chopps 
    183  1.1  chopps u_long scan_sync __P((u_long, u_long, int));
    184  1.1  chopps u_long encode_long __P((u_long, u_long *));
    185  1.1  chopps u_long loop_read_id __P((int));
    186  1.1  chopps u_long get_drive_id __P((int));
    187  1.1  chopps 
    188  1.1  chopps int fdstate __P((fdc_p));
    189  1.1  chopps int retrier __P((fdc_p));
    190  1.1  chopps int amiga_read __P((fd_p));
    191  1.1  chopps int get_drive_type __P((u_long));
    192  1.1  chopps 
    193  1.1  chopps /* device routines */
    194  1.1  chopps int Fdopen __P((dev_t, int));
    195  1.1  chopps int fdsize __P((dev_t));
    196  1.1  chopps int fdioctl __P((dev_t, int, caddr_t, int, struct proc *));
    197  1.1  chopps int fdclose __P((dev_t, int));
    198  1.1  chopps int fdattach __P((struct amiga_device *));
    199  1.1  chopps 
    200  1.1  chopps void fdintr __P((fdcu_t));
    201  1.1  chopps void fdstart __P((fdc_p));
    202  1.1  chopps void fdstrategy __P((struct buf *bp));
    203  1.1  chopps 
    204  1.1  chopps #define DEVIDLE		0
    205  1.1  chopps #define FINDWORK	1
    206  1.1  chopps #define	DOSEEK		2
    207  1.1  chopps #define DO_IO	 	3
    208  1.1  chopps #define	DONE_IO		4
    209  1.1  chopps #define	WAIT_READ	5
    210  1.1  chopps #define	WAIT_WRITE	6
    211  1.1  chopps #define DELAY_WRITE	7
    212  1.1  chopps #define RECALCOMPLETE	8
    213  1.1  chopps #define	STARTRECAL	9
    214  1.1  chopps #define	RESETCTLR	10
    215  1.1  chopps #define	SEEKWAIT	11
    216  1.1  chopps #define	RECALWAIT	12
    217  1.1  chopps #define	MOTORWAIT	13
    218  1.1  chopps 
    219  1.1  chopps #undef DEBUG
    220  1.1  chopps 
    221  1.1  chopps #ifdef DEBUG
    222  1.1  chopps 
    223  1.1  chopps char *fdstates[] =
    224  1.1  chopps {
    225  1.1  chopps "DEVIDLE",
    226  1.1  chopps "FINDWORK",
    227  1.1  chopps "DOSEEK",
    228  1.1  chopps "DO_IO",
    229  1.1  chopps "DONE_IO",
    230  1.1  chopps "WAIT_READ",
    231  1.1  chopps "WAIT_WRITE",
    232  1.1  chopps "DELAY_WRITE",
    233  1.1  chopps "RECALCOMPLETE",
    234  1.1  chopps "STARTRECAL",
    235  1.1  chopps "RESETCTLR",
    236  1.1  chopps "SEEKWAIT",
    237  1.1  chopps "RECALWAIT",
    238  1.1  chopps "MOTORWAIT",
    239  1.1  chopps };
    240  1.1  chopps 
    241  1.1  chopps #define TRACE0(arg) if (fd_debug == 1) printf(arg)
    242  1.1  chopps #define TRACE1(arg1,arg2) if (fd_debug == 1) printf(arg1,arg2)
    243  1.1  chopps 
    244  1.1  chopps #else	/* !DEBUG */
    245  1.1  chopps 
    246  1.1  chopps #define TRACE0(arg)
    247  1.1  chopps #define TRACE1(arg1,arg2)
    248  1.1  chopps 
    249  1.1  chopps #endif	/* !DEBUG */
    250  1.1  chopps 
    251  1.1  chopps extern int hz;
    252  1.1  chopps 
    253  1.1  chopps unsigned char *raw_buf = NULL;
    254  1.1  chopps #ifdef DEBUG
    255  1.1  chopps int fd_debug = 1;
    256  1.1  chopps #else
    257  1.1  chopps int fd_debug = 0;
    258  1.1  chopps #endif
    259  1.1  chopps 
    260  1.1  chopps /*
    261  1.1  chopps  * Floppy Support Routines
    262  1.1  chopps  */
    263  1.1  chopps #define MOTOR_ON		(ciab.prb &= ~CIAB_PRB_MTR)
    264  1.1  chopps #define MOTOR_OFF		(ciab.prb |= CIAB_PRB_MTR)
    265  1.1  chopps #define SELECT(mask)		(ciab.prb &= ~mask)
    266  1.1  chopps #define DESELECT(mask)		(ciab.prb |= mask)
    267  1.1  chopps #define SELMASK(drive)		(1 << (3 + (drive & 3)))
    268  1.1  chopps 
    269  1.1  chopps /*
    270  1.1  chopps  * Delay for a number of milliseconds
    271  1.1  chopps  *	- tried ciab.tod but seems to miss values and screw up
    272  1.1  chopps  *	- stupid busy loop for now
    273  1.1  chopps  */
    274  1.1  chopps static int
    275  1.1  chopps delay(delay_ms)
    276  1.1  chopps 	int delay_ms;
    277  1.1  chopps {
    278  1.1  chopps 	long cnt, inner;
    279  1.1  chopps 	int val;
    280  1.1  chopps 
    281  1.1  chopps 	for (cnt = 0; cnt < delay_ms; cnt++)
    282  1.1  chopps 		for (inner = 0; inner < 500; inner++)
    283  1.1  chopps 			val += inner * cnt;
    284  1.1  chopps 	return(val);
    285  1.1  chopps }
    286  1.1  chopps 
    287  1.1  chopps /*
    288  1.1  chopps  * motor control stuff
    289  1.1  chopps  */
    290  1.1  chopps void
    291  1.1  chopps fd_motor_to(fdcu)
    292  1.1  chopps 	fdcu_t fdcu;
    293  1.1  chopps {
    294  1.1  chopps 	printf("timeout starting motor\n");	/* XXXX */
    295  1.1  chopps 	fdc_data[fdcu].motor_fdu = -2;
    296  1.1  chopps }
    297  1.1  chopps 
    298  1.1  chopps void
    299  1.1  chopps fd_motor_on(fdc, fdu)
    300  1.1  chopps 	fdc_p fdc;
    301  1.1  chopps 	fdu_t fdu;
    302  1.1  chopps {
    303  1.1  chopps 	int i;
    304  1.1  chopps 	int cnt;		/* XXXX not used? */
    305  1.1  chopps 
    306  1.1  chopps 	cnt = 0;		/* XXXX not used? */
    307  1.1  chopps 
    308  1.1  chopps 	/* deselect all drives */
    309  1.1  chopps 	for (i = 0; i < DRVS_PER_CTLR; i++)
    310  1.1  chopps 		DESELECT(SELMASK(i));
    311  1.1  chopps 
    312  1.1  chopps 	/* turn on the unit's motor */
    313  1.1  chopps 	MOTOR_ON;
    314  1.1  chopps 	SELECT(SELMASK(fdu));
    315  1.1  chopps 
    316  1.1  chopps 	timeout((timeout_t)fd_motor_to, (caddr_t)fdc->fdcu, hz);
    317  1.1  chopps 	while (ciaa.pra & CIAA_PRA_RDY)
    318  1.1  chopps 		;
    319  1.1  chopps 	untimeout((timeout_t)fd_motor_to, (caddr_t)fdc->fdcu);
    320  1.1  chopps 	fdc->motor_fdu = fdu;
    321  1.1  chopps }
    322  1.1  chopps 
    323  1.1  chopps void
    324  1.1  chopps fd_turnoff(fdc)
    325  1.1  chopps 	fdc_p fdc;
    326  1.1  chopps {
    327  1.1  chopps 	int i;
    328  1.1  chopps 
    329  1.1  chopps 	if (fdc->motor_fdu != -1) {
    330  1.1  chopps 		/* deselect all drives */
    331  1.1  chopps 		for (i = 0; i < DRVS_PER_CTLR; i++)
    332  1.1  chopps 			DESELECT(SELMASK(i));
    333  1.1  chopps 
    334  1.1  chopps 		/* turn off the unit's motor */
    335  1.1  chopps 		MOTOR_OFF;
    336  1.1  chopps 		SELECT(SELMASK(fdc->motor_fdu));
    337  1.1  chopps 		MOTOR_ON;
    338  1.1  chopps 		DESELECT(SELMASK(fdc->motor_fdu));
    339  1.1  chopps 	}
    340  1.1  chopps 
    341  1.1  chopps 	fdc->motor_fdu = -1;
    342  1.1  chopps }
    343  1.1  chopps 
    344  1.1  chopps void
    345  1.1  chopps fd_turnon(fdc, fdu)
    346  1.1  chopps 	fdc_p fdc;
    347  1.1  chopps 	fdu_t fdu;
    348  1.1  chopps {
    349  1.1  chopps 	if (fdc->motor_fdu == fdu)
    350  1.1  chopps 		return;
    351  1.1  chopps 
    352  1.1  chopps 	fd_turnoff(fdc);
    353  1.1  chopps 	fd_motor_on(fdc, fdu);
    354  1.1  chopps }
    355  1.1  chopps 
    356  1.1  chopps /*
    357  1.1  chopps  * Step the drive once in its current direction
    358  1.1  chopps  */
    359  1.1  chopps void
    360  1.1  chopps fd_step()
    361  1.1  chopps {
    362  1.1  chopps 	ciab.prb &= ~CIAB_PRB_STEP;
    363  1.1  chopps 	ciab.prb |= CIAB_PRB_STEP;
    364  1.1  chopps }
    365  1.1  chopps 
    366  1.1  chopps /*
    367  1.1  chopps  * Select the side to use for a particular drive.
    368  1.1  chopps  * The drive must have been calibrated at some point before this.
    369  1.1  chopps  * The drive must also be active and the motor must be running.
    370  1.1  chopps  */
    371  1.1  chopps void
    372  1.1  chopps fd_select_side(fd, side)
    373  1.1  chopps 	fd_p fd;
    374  1.1  chopps 	int side;
    375  1.1  chopps {
    376  1.1  chopps 	if (fd->side == side)
    377  1.1  chopps 		return;
    378  1.1  chopps 
    379  1.1  chopps 	/* select the requested side */
    380  1.1  chopps 	if (side == 0)
    381  1.1  chopps 		ciab.prb &= ~CIAB_PRB_SIDE;
    382  1.1  chopps 	else
    383  1.1  chopps 		ciab.prb |= CIAB_PRB_SIDE;
    384  1.1  chopps 	delay(fd->ft->side_time);
    385  1.1  chopps 	fd->side = side;
    386  1.1  chopps }
    387  1.1  chopps 
    388  1.1  chopps /*
    389  1.1  chopps  * Select the direction to use for the current particular drive.
    390  1.1  chopps  */
    391  1.1  chopps void
    392  1.1  chopps fd_select_dir(fd, dir)
    393  1.1  chopps 	fd_p fd;
    394  1.1  chopps 	int dir;
    395  1.1  chopps {
    396  1.1  chopps 	if (fd->dir == dir)
    397  1.1  chopps 		return;
    398  1.1  chopps 
    399  1.1  chopps 	/* select the requested direction */
    400  1.1  chopps 	if (dir == 0)
    401  1.1  chopps 		ciab.prb &= ~CIAB_PRB_DIR;
    402  1.1  chopps 	else
    403  1.1  chopps 		ciab.prb |= CIAB_PRB_DIR;
    404  1.1  chopps 	delay(fd->ft->settle_time);
    405  1.1  chopps 	fd->dir = dir;
    406  1.1  chopps }
    407  1.1  chopps 
    408  1.1  chopps /*
    409  1.1  chopps  * Seek the drive to track 0.
    410  1.1  chopps  * The drive must be active and the motor must be running.
    411  1.1  chopps  * Returns standard floppy error code. /* XXXX doesn't return anything
    412  1.1  chopps  */
    413  1.1  chopps void
    414  1.1  chopps fd_calibrate(fd)
    415  1.1  chopps 	fd_p fd;
    416  1.1  chopps {
    417  1.1  chopps 	fd_select_dir(fd, 1);
    418  1.1  chopps 
    419  1.1  chopps 	/* loop until we hit track 0 */
    420  1.1  chopps 	while (ciaa.pra & CIAA_PRA_TK0) {
    421  1.1  chopps 		fd_step();
    422  1.1  chopps 		delay(4);
    423  1.1  chopps 	}
    424  1.1  chopps 
    425  1.1  chopps 	/* set known values */
    426  1.1  chopps 	fd->cyl = 0;
    427  1.1  chopps }
    428  1.1  chopps 
    429  1.1  chopps /*
    430  1.1  chopps  * Seek the drive to the requested track.
    431  1.1  chopps  * The drive must be active and the motor must be running.
    432  1.1  chopps  */
    433  1.1  chopps void
    434  1.1  chopps fd_seek(fd, track)
    435  1.1  chopps 	fd_p fd;
    436  1.1  chopps 	int track;
    437  1.1  chopps {
    438  1.1  chopps 	int cyl, side;
    439  1.1  chopps 	int dir, cnt;
    440  1.1  chopps 	int delay_time;
    441  1.1  chopps 
    442  1.1  chopps 	cyl = track >> 1;
    443  1.1  chopps 	side = (track % 2) ^ 1;
    444  1.1  chopps 
    445  1.1  chopps 	if (fd->cyl == -1)
    446  1.1  chopps 		fd_calibrate(fd);
    447  1.1  chopps 
    448  1.1  chopps 	fd_select_side(fd, side);
    449  1.1  chopps 
    450  1.1  chopps 	if (cyl < fd->cyl) {
    451  1.1  chopps 		dir = 1;
    452  1.1  chopps 		cnt = fd->cyl - cyl;
    453  1.1  chopps 	} else {
    454  1.1  chopps 		dir = 0;
    455  1.1  chopps 		cnt = cyl - fd->cyl;
    456  1.1  chopps 	}
    457  1.1  chopps 
    458  1.1  chopps 	fd_select_dir(fd, dir);
    459  1.1  chopps 
    460  1.1  chopps 	if (cnt) {
    461  1.1  chopps 		while (cnt) {
    462  1.1  chopps 			delay_time = fd->ft->step_delay;
    463  1.1  chopps 			if (dir != fd->dir)
    464  1.1  chopps 				delay_time += fd->ft->settle_time;
    465  1.1  chopps 			fd_step();
    466  1.1  chopps 			delay(delay_time);
    467  1.1  chopps 			--cnt;
    468  1.1  chopps 		}
    469  1.1  chopps 		delay(fd->ft->settle_time);
    470  1.1  chopps 	}
    471  1.1  chopps 
    472  1.1  chopps 	fd->cyl = cyl;
    473  1.1  chopps }
    474  1.1  chopps 
    475  1.1  chopps void
    476  1.1  chopps encode(data, dest, csum)
    477  1.1  chopps 	u_long data;
    478  1.1  chopps 	u_long *dest, *csum;
    479  1.1  chopps {
    480  1.1  chopps 	u_long data2;
    481  1.1  chopps 
    482  1.1  chopps 	data &= 0x55555555;
    483  1.1  chopps 	data2 = data ^ 0x55555555;
    484  1.1  chopps 	data |= ((data2 >> 1) | 0x80000000) & (data2 << 1);
    485  1.1  chopps 
    486  1.1  chopps 	if (*(dest - 1) & 0x00000001)
    487  1.1  chopps 		data &= 0x7FFFFFFF;
    488  1.1  chopps 
    489  1.1  chopps 	*csum ^= data;
    490  1.1  chopps 	*dest = data;
    491  1.1  chopps }
    492  1.1  chopps 
    493  1.1  chopps u_long
    494  1.1  chopps encode_long(data, dest)
    495  1.1  chopps 	u_long data;
    496  1.1  chopps 	u_long *dest;
    497  1.1  chopps {
    498  1.1  chopps 	u_long csum;
    499  1.1  chopps 
    500  1.1  chopps 	csum = 0;
    501  1.1  chopps 
    502  1.1  chopps 	encode(data >> 1, dest, &csum);
    503  1.1  chopps 	encode(data, dest + 1, &csum);
    504  1.1  chopps 
    505  1.1  chopps 	return(csum & 0x55555555);
    506  1.1  chopps }
    507  1.1  chopps 
    508  1.1  chopps void
    509  1.1  chopps encode_block(dest, from, len, csum)
    510  1.1  chopps 	u_long *dest, *csum;
    511  1.1  chopps 	u_char *from;
    512  1.1  chopps 	int len;
    513  1.1  chopps {
    514  1.1  chopps 	int cnt, to_cnt = 0;
    515  1.1  chopps 	u_long data, *src;
    516  1.1  chopps 
    517  1.1  chopps 	to_cnt = 0;
    518  1.1  chopps 	src = (u_long *)from;
    519  1.1  chopps 
    520  1.1  chopps 	/* odd bits */
    521  1.1  chopps 	for (cnt = 0; cnt < len / 4; cnt++) {
    522  1.1  chopps 		data = src[cnt] >> 1;
    523  1.1  chopps 		encode(data, dest + to_cnt++, csum);
    524  1.1  chopps 	}
    525  1.1  chopps 
    526  1.1  chopps 	/* even bits */
    527  1.1  chopps 	for (cnt = 0; cnt < len / 4; cnt++) {
    528  1.1  chopps 		data = src[cnt];
    529  1.1  chopps 		encode(data, dest + to_cnt++, csum);
    530  1.1  chopps 	}
    531  1.1  chopps 
    532  1.1  chopps 	*csum &= 0x55555555;
    533  1.1  chopps }
    534  1.1  chopps 
    535  1.1  chopps void
    536  1.1  chopps correct(raw)
    537  1.1  chopps 	u_long *raw;
    538  1.1  chopps {
    539  1.1  chopps 	u_char data, *ptr;
    540  1.1  chopps 
    541  1.1  chopps 	ptr = (u_char *)raw;
    542  1.1  chopps 
    543  1.1  chopps 	data = *ptr;
    544  1.1  chopps 	if (*(ptr - 1) & 0x01) {	/* XXXX will choke on old GVP's */
    545  1.1  chopps 		*ptr = data & 0x7f;
    546  1.1  chopps 		return;
    547  1.1  chopps 	}
    548  1.1  chopps 
    549  1.1  chopps 	if (data & 0x40)
    550  1.1  chopps 		return;
    551  1.1  chopps 
    552  1.1  chopps 	*ptr |= 0x80;
    553  1.1  chopps }
    554  1.1  chopps 
    555  1.1  chopps /*
    556  1.1  chopps  * amiga_write converts track/labels data to raw track data
    557  1.1  chopps  */
    558  1.1  chopps void
    559  1.1  chopps amiga_write(fd)
    560  1.1  chopps 	fd_p fd;
    561  1.1  chopps {
    562  1.1  chopps 	u_long *raw, csum, format;
    563  1.1  chopps 	u_char *data, *labels;
    564  1.1  chopps 	int cnt, track;
    565  1.1  chopps 
    566  1.1  chopps 	raw = (u_long *)raw_buf;	/* XXXX never used while intr? */
    567  1.1  chopps 					/* XXXX never waits after here? */
    568  1.1  chopps 	data = fd->buf_data;
    569  1.1  chopps 	labels = fd->buf_labels;
    570  1.1  chopps 	track = fd->buf_track;
    571  1.1  chopps 
    572  1.1  chopps 	/* gap space */
    573  1.1  chopps 	for (cnt = 0; cnt < 414; cnt++)
    574  1.1  chopps 		*raw++ = 0xaaaaaaaa;
    575  1.1  chopps 
    576  1.1  chopps 	/* sectors */
    577  1.1  chopps 	for (cnt = 0; cnt < 11; cnt++) {
    578  1.1  chopps 		*raw = 0xaaaaaaaa;
    579  1.1  chopps 		correct(raw);
    580  1.1  chopps 		++raw;
    581  1.1  chopps 
    582  1.1  chopps 		*raw++ = 0x44894489;
    583  1.1  chopps 
    584  1.1  chopps 		format = 0xff000000 | (track << 16) | (cnt << 8) | (11 - cnt);
    585  1.1  chopps 		csum = encode_long(format,raw);
    586  1.1  chopps 		raw += 2;
    587  1.1  chopps 
    588  1.1  chopps 		encode_block(raw, labels + cnt * 16, 16, &csum);
    589  1.1  chopps 		raw += 8;
    590  1.1  chopps 		csum = encode_long(csum, raw);
    591  1.1  chopps 		raw += 2;
    592  1.1  chopps 
    593  1.1  chopps 		csum = 0;
    594  1.1  chopps 		encode_block(raw+2, data + cnt * 512, 512, &csum);
    595  1.1  chopps 		csum = encode_long(csum, raw);
    596  1.1  chopps 		raw += 256 + 2;
    597  1.1  chopps 	}
    598  1.1  chopps }
    599  1.1  chopps 
    600  1.1  chopps #define get_word(raw) (*(u_short *)(raw))
    601  1.1  chopps #define get_long(raw) (*(u_long *)(raw))
    602  1.1  chopps 
    603  1.1  chopps #define decode_long(raw) \
    604  1.1  chopps     (((get_long(raw) & 0x55555555) << 1) | \
    605  1.1  chopps     (get_long((raw)+4) & 0x55555555))
    606  1.1  chopps 
    607  1.1  chopps #define MFM_NOSYNC	1
    608  1.1  chopps #define MFM_HEADER	2
    609  1.1  chopps #define MFM_DATA	3
    610  1.1  chopps #define MFM_TRACK	4
    611  1.1  chopps 
    612  1.1  chopps /*
    613  1.1  chopps  * scan_sync - looks for the next start of sector marked by a sync. When
    614  1.1  chopps  *	sector = 10, can't be certain of a starting sync.
    615  1.1  chopps  */
    616  1.1  chopps u_long
    617  1.1  chopps scan_sync(raw, end, sect)
    618  1.1  chopps 	u_long raw, end;
    619  1.1  chopps 	int sect;
    620  1.1  chopps {
    621  1.1  chopps 	u_short data;
    622  1.1  chopps 
    623  1.1  chopps 	if (sect != 10) {
    624  1.1  chopps 		while (raw < end) {
    625  1.1  chopps 			data = get_word(raw);
    626  1.1  chopps 			if (data == 0x4489)
    627  1.1  chopps 				break;
    628  1.1  chopps 			raw += 2;
    629  1.1  chopps 		}
    630  1.1  chopps 		if (raw > end)
    631  1.1  chopps 			return(0);
    632  1.1  chopps 	}
    633  1.1  chopps 
    634  1.1  chopps 	while (raw < end) {
    635  1.1  chopps 		data = get_word(raw);
    636  1.1  chopps 		if (data != 0x4489)
    637  1.1  chopps 			break;
    638  1.1  chopps 		raw += 2;
    639  1.1  chopps 	}
    640  1.1  chopps 	if (raw > end)
    641  1.1  chopps 		return(0);
    642  1.1  chopps 	return(raw);
    643  1.1  chopps }
    644  1.1  chopps 
    645  1.1  chopps /*
    646  1.1  chopps  * amiga_read reads a raw track of data into a track buffer
    647  1.1  chopps  */
    648  1.1  chopps int
    649  1.1  chopps amiga_read(fd)
    650  1.1  chopps 	fd_p fd;
    651  1.1  chopps {
    652  1.1  chopps 	u_char *track_data, *label_data;
    653  1.1  chopps 	u_long raw, end, val1, val2, csum, data_csum;
    654  1.1  chopps 	u_long *data, *labels;
    655  1.1  chopps 	int scnt, cnt, format, tnum, sect, snext;
    656  1.1  chopps 
    657  1.1  chopps 	track_data = fd->buf_data;
    658  1.1  chopps 	label_data = fd->buf_labels;
    659  1.1  chopps 	raw = (u_long)raw_buf;		/* XXXX see above about glb */
    660  1.1  chopps 
    661  1.1  chopps 	end = raw + fd->ft->read_size;
    662  1.1  chopps 
    663  1.1  chopps 	for (scnt = fd->sects-1; scnt >= 0; scnt--) {
    664  1.1  chopps 		if ((raw = scan_sync(raw, end, scnt)) == 0) {
    665  1.1  chopps 			/* XXXX */
    666  1.1  chopps 			printf("can't find sync for sector %d\n", scnt);
    667  1.1  chopps 			return(1);
    668  1.1  chopps 		}
    669  1.1  chopps 
    670  1.1  chopps 		val1 = decode_long(raw);
    671  1.1  chopps 
    672  1.1  chopps 		format = (val1 >> 24) & 0xFF;
    673  1.1  chopps 		tnum   = (val1 >> 16) & 0xFF;
    674  1.1  chopps 		sect   = (val1 >>  8) & 0xFF;
    675  1.1  chopps 		snext  = (val1)       & 0xFF;
    676  1.1  chopps 
    677  1.1  chopps 		labels = (u_long *)(label_data + (sect << 4));
    678  1.1  chopps 
    679  1.1  chopps 		csum = 0;
    680  1.1  chopps 		val1 = get_long(raw);
    681  1.1  chopps 		raw += 4;
    682  1.1  chopps 		csum ^= val1;
    683  1.1  chopps 		val1 = get_long(raw);
    684  1.1  chopps 		raw += 4;
    685  1.1  chopps 		csum ^= val1;
    686  1.1  chopps 
    687  1.1  chopps 		for (cnt = 0; cnt < 4; cnt++) {
    688  1.1  chopps 			val1 = get_long(raw+16);
    689  1.1  chopps 			csum ^= val1;
    690  1.1  chopps 			val1 &= 0x55555555;
    691  1.1  chopps 			val2 = get_long(raw);
    692  1.1  chopps 			raw += 4;
    693  1.1  chopps 			csum ^= val2;
    694  1.1  chopps 			val2 &= 0x55555555;
    695  1.1  chopps 			val2 = val2 << 1;
    696  1.1  chopps 			val1 |= val2;
    697  1.1  chopps 			*labels++ = val1;
    698  1.1  chopps 		}
    699  1.1  chopps 
    700  1.1  chopps 		csum &= 0x55555555;
    701  1.1  chopps 		raw += 16;
    702  1.1  chopps 		val1 = decode_long(raw);
    703  1.1  chopps 		raw += 8;
    704  1.1  chopps 		if (val1 != csum) {
    705  1.1  chopps 			/* XXXX */
    706  1.1  chopps 			printf("MFM_HEADER %d: %08x,%08x\n", scnt,
    707  1.1  chopps 			    val1, csum);
    708  1.1  chopps 			return(MFM_HEADER);
    709  1.1  chopps 		}
    710  1.1  chopps 
    711  1.1  chopps 		/* verify track */
    712  1.1  chopps 		if (tnum != fd->buf_track) {
    713  1.1  chopps 			/* XXXX */
    714  1.1  chopps 			printf("MFM_TRACK %d: %d, %d\n", scnt, tnum,
    715  1.1  chopps 			    fd->buf_track);
    716  1.1  chopps 			return(MFM_TRACK);
    717  1.1  chopps 		}
    718  1.1  chopps 
    719  1.1  chopps 		data_csum = decode_long(raw);
    720  1.1  chopps 		raw += 8;
    721  1.1  chopps 		data = (u_long *)(track_data + (sect << 9));
    722  1.1  chopps 
    723  1.1  chopps 		csum = 0;
    724  1.1  chopps 		for (cnt = 0; cnt < 128; cnt++) {
    725  1.1  chopps 			val1 = get_long(raw + 512);
    726  1.1  chopps 			csum ^= val1;
    727  1.1  chopps 			val1 &= 0x55555555;
    728  1.1  chopps 			val2 = get_long(raw);
    729  1.1  chopps 			raw += 4;
    730  1.1  chopps 			csum ^= val2;
    731  1.1  chopps 			val2 &= 0x55555555;
    732  1.1  chopps 			val2 = val2 << 1;
    733  1.1  chopps 			val1 |= val2;
    734  1.1  chopps 			*data++ = val1;
    735  1.1  chopps 		}
    736  1.1  chopps 
    737  1.1  chopps 		csum &= 0x55555555;
    738  1.1  chopps 		raw += 512;
    739  1.1  chopps 
    740  1.1  chopps 		if (data_csum != csum) {
    741  1.1  chopps 			printf(
    742  1.1  chopps 			    "MFM_DATA: f=%d t=%d s=%d sn=%d sc=%d %ld, %ld\n",
    743  1.1  chopps 			    format, tnum, sect, snext, scnt, data_csum, csum);
    744  1.1  chopps 			return(MFM_DATA);
    745  1.1  chopps 		}
    746  1.1  chopps 	}
    747  1.1  chopps 	return(0);
    748  1.1  chopps }
    749  1.1  chopps 
    750  1.1  chopps /*
    751  1.1  chopps  * Return unit ID number of given disk
    752  1.1  chopps  * XXXX This function doesn't return anything.
    753  1.1  chopps  */
    754  1.1  chopps u_long
    755  1.1  chopps loop_read_id(unit)
    756  1.1  chopps 	int unit;
    757  1.1  chopps {
    758  1.1  chopps 	u_long id;
    759  1.1  chopps 	int i;
    760  1.1  chopps 
    761  1.1  chopps 	id = 0;
    762  1.1  chopps 
    763  1.1  chopps 	/* loop and read disk ID */
    764  1.1  chopps 	for (i = 0; i < 32; i++) {
    765  1.1  chopps 		SELECT(SELMASK(unit));
    766  1.1  chopps 
    767  1.1  chopps 		/* read and store value of DSKRDY */
    768  1.1  chopps 		id <<= 1;		/* XXXX 0 << 1? */
    769  1.1  chopps 		id |= (ciaa.pra & CIAA_PRA_RDY) ? 0 : 1;
    770  1.1  chopps 
    771  1.1  chopps 		DESELECT(SELMASK(unit));
    772  1.1  chopps 	}
    773  1.1  chopps }
    774  1.1  chopps 
    775  1.1  chopps u_long
    776  1.1  chopps get_drive_id(unit)
    777  1.1  chopps 	int unit;
    778  1.1  chopps {
    779  1.1  chopps 	int i, t;
    780  1.1  chopps 	u_long id;
    781  1.1  chopps 	u_char mask1, mask2;
    782  1.1  chopps 	volatile u_char *a_ptr;
    783  1.1  chopps 	volatile u_char *b_ptr;
    784  1.1  chopps 
    785  1.1  chopps 	id = 0;
    786  1.1  chopps 	a_ptr = &ciaa.pra;
    787  1.1  chopps 	b_ptr = &ciab.prb;
    788  1.1  chopps 	mask1 = ~(1 << (3 + unit));
    789  1.1  chopps 	mask2 = 1 << (3 + unit);
    790  1.1  chopps 
    791  1.1  chopps 	*b_ptr &= ~CIAB_PRB_MTR;
    792  1.1  chopps 	*b_ptr &= mask1;
    793  1.1  chopps 	*b_ptr |= mask2;
    794  1.1  chopps 	*b_ptr |= CIAB_PRB_MTR;
    795  1.1  chopps 	*b_ptr &= mask1;
    796  1.1  chopps 	*b_ptr |= mask2;
    797  1.1  chopps 
    798  1.1  chopps 	for (i = 0; i < 32; i++) {
    799  1.1  chopps 		*b_ptr &= mask1;
    800  1.1  chopps 		t = (*a_ptr) & CIAA_PRA_RDY;
    801  1.1  chopps 		id = (id << 1) | (t ? 0 : 1);
    802  1.1  chopps 		*b_ptr |= mask2;
    803  1.1  chopps 	}
    804  1.2  chopps 
    805  1.2  chopps 	/* all amigas have internal drives at 0. */
    806  1.2  chopps 	if (unit == 0 && id == FD_NONE)
    807  1.2  chopps 		return(FD_DD_3);
    808  1.1  chopps 	return(id);
    809  1.1  chopps #if 0
    810  1.1  chopps   /* set up for ID */
    811  1.1  chopps   MOTOR_ON;
    812  1.1  chopps   SELECT(SELMASK(unit));
    813  1.1  chopps   DESELECT(SELMASK(unit));
    814  1.1  chopps   MOTOR_OFF;
    815  1.1  chopps   SELECT(SELMASK(unit));
    816  1.1  chopps   DESELECT(SELMASK(unit));
    817  1.1  chopps 
    818  1.1  chopps   return loop_read_id(unit); /* XXXX gotta fix loop_read_id() if use */
    819  1.1  chopps #endif
    820  1.1  chopps }
    821  1.1  chopps 
    822  1.1  chopps int
    823  1.1  chopps get_drive_type(u_long id)
    824  1.1  chopps {
    825  1.1  chopps 	int type;
    826  1.1  chopps 
    827  1.1  chopps 	for (type = 0; type < num_dr_types; type++)
    828  1.1  chopps 		if (drive_types[type].id == id)
    829  1.1  chopps 			return(type);
    830  1.1  chopps 	return(-1);
    831  1.1  chopps }
    832  1.1  chopps 
    833  1.1  chopps void
    834  1.1  chopps fd_probe(fd)
    835  1.1  chopps 	fd_p fd;
    836  1.1  chopps {
    837  1.1  chopps 	u_long id;
    838  1.1  chopps 	int type, data;
    839  1.1  chopps 
    840  1.1  chopps 	fd->ft = NULL;
    841  1.1  chopps 
    842  1.1  chopps 	id = get_drive_id(fd->fdu);
    843  1.1  chopps 	type = get_drive_type(id);
    844  1.1  chopps 
    845  1.1  chopps 	if (type == -1) {
    846  1.1  chopps 		/* XXXX */
    847  1.1  chopps 		printf("fd_probe: unsupported drive type %08x found\n", id);
    848  1.1  chopps 		return;
    849  1.1  chopps 	}
    850  1.1  chopps 
    851  1.1  chopps 	fd->type = type;
    852  1.1  chopps 	fd->ft = &drive_types[type];
    853  1.1  chopps 	if (fd->ft->tracks == 0) {
    854  1.1  chopps 		/* XXXX */
    855  1.1  chopps 		printf("no drive type %d\n", type);
    856  1.1  chopps 	}
    857  1.1  chopps 	fd->side = -1;
    858  1.1  chopps 	fd->dir = -1;
    859  1.1  chopps 	fd->cyl = -1;
    860  1.1  chopps 
    861  1.1  chopps 	fd->sects = 11 * drive_types[type].sect_mult;
    862  1.1  chopps 	fd->size = fd->sects *
    863  1.1  chopps 	    drive_types[type].tracks *
    864  1.1  chopps 	    drive_types[type].heads;
    865  1.1  chopps 	fd->flags = 0;
    866  1.1  chopps }
    867  1.1  chopps 
    868  1.1  chopps void
    869  1.1  chopps track_read(fdc, fd, track)
    870  1.1  chopps 	fdc_p fdc;
    871  1.1  chopps 	fd_p fd;
    872  1.1  chopps 	int track;
    873  1.1  chopps {
    874  1.1  chopps 	u_long len;
    875  1.1  chopps 
    876  1.1  chopps 	fd->buf_track = track;
    877  1.1  chopps 	fdc->state = WAIT_READ;
    878  1.1  chopps 	timeout((timeout_t)fd_timeout, (caddr_t)fdc, 2 * hz);
    879  1.1  chopps 
    880  1.1  chopps 	fd_seek(fd, track);
    881  1.1  chopps 
    882  1.1  chopps 	len = fd->ft->read_size >> 1;
    883  1.1  chopps 
    884  1.1  chopps 	/* setup adkcon bits correctly */
    885  1.1  chopps 	custom.adkcon = ADKF_MSBSYNC;
    886  1.1  chopps 	custom.adkcon = ADKF_SETCLR | ADKF_WORDSYNC | ADKF_FAST;
    887  1.1  chopps 
    888  1.1  chopps 	custom.dsksync = MFM_SYNC;
    889  1.1  chopps 
    890  1.1  chopps 	custom.dsklen = 0;
    891  1.1  chopps 	delay(fd->ft->side_time);
    892  1.1  chopps 
    893  1.1  chopps 	custom.dskpt = (u_char *)kvtop(raw_buf);
    894  1.1  chopps 	custom.dsklen = len | DSKLEN_DMAEN;
    895  1.1  chopps 	custom.dsklen = len | DSKLEN_DMAEN;
    896  1.1  chopps }
    897  1.1  chopps 
    898  1.1  chopps void
    899  1.1  chopps track_write(fdc, fd)
    900  1.1  chopps 	fdc_p fdc;
    901  1.1  chopps 	fd_p fd;
    902  1.1  chopps {
    903  1.1  chopps 	int track;
    904  1.1  chopps 	u_long len;
    905  1.1  chopps 	u_short adk;
    906  1.1  chopps 
    907  1.1  chopps 	amiga_write(fd);
    908  1.1  chopps 
    909  1.1  chopps 	track = fd->buf_track;
    910  1.1  chopps 	fd->write_cnt += 1;
    911  1.1  chopps 
    912  1.1  chopps 	fdc->saved = fdc->state;
    913  1.1  chopps 	fdc->state = WAIT_WRITE;
    914  1.1  chopps 	timeout((timeout_t)fd_timeout, (caddr_t)fdc, 2 * hz);
    915  1.1  chopps 
    916  1.1  chopps 	fd_seek(fd, track);
    917  1.1  chopps 
    918  1.1  chopps 	len = fd->ft->write_size >> 1;
    919  1.1  chopps 
    920  1.1  chopps 	if ((ciaa.pra & CIAA_PRA_WPRO) == 0)
    921  1.1  chopps 		return;
    922  1.1  chopps 
    923  1.1  chopps 	/* clear adkcon bits */
    924  1.1  chopps 	custom.adkcon = ADKF_PRECOMP1 | ADKF_PRECOMP0 | ADKF_WORDSYNC |
    925  1.1  chopps 	    ADKF_MSBSYNC;
    926  1.1  chopps 
    927  1.1  chopps 	/* set appropriate adkcon bits */
    928  1.1  chopps 	adk = ADKF_SETCLR | ADKF_FAST;
    929  1.1  chopps 	if (track >= fd->ft->precomp2)
    930  1.1  chopps 		adk |= ADKF_PRECOMP1;
    931  1.1  chopps 	else if (track >= fd->ft->precomp1)
    932  1.1  chopps 		adk |= ADKF_PRECOMP0;
    933  1.1  chopps 	custom.adkcon = adk;
    934  1.1  chopps 
    935  1.1  chopps 	custom.dsklen = DSKLEN_WRITE;
    936  1.1  chopps 	delay(fd->ft->side_time);
    937  1.1  chopps 
    938  1.1  chopps 	custom.dskpt = (u_char *)kvtop(raw_buf);	/* XXXX again raw */
    939  1.1  chopps 	custom.dsklen = len | DSKLEN_DMAEN | DSKLEN_WRITE;
    940  1.1  chopps 	custom.dsklen = len | DSKLEN_DMAEN | DSKLEN_WRITE;
    941  1.1  chopps }
    942  1.1  chopps 
    943  1.1  chopps /*
    944  1.1  chopps  * Floppy Device Code
    945  1.1  chopps  */
    946  1.1  chopps int
    947  1.1  chopps fdattach(ad)
    948  1.1  chopps 	struct amiga_device *ad;
    949  1.1  chopps {
    950  1.1  chopps 	int fdcu = 0;
    951  1.1  chopps 	fdc_p fdc = fdc_data + fdcu;
    952  1.1  chopps 	int i;
    953  1.1  chopps 	unsigned long id;
    954  1.1  chopps 	int type;
    955  1.1  chopps 
    956  1.1  chopps 	fdc->fdcu = fdcu;
    957  1.1  chopps 	fdc->state = FINDWORK;
    958  1.1  chopps 	fdc->fd = NULL;
    959  1.1  chopps 	fdc->motor_fdu = -1;
    960  1.1  chopps 
    961  1.1  chopps 	for (i = 0; i < DRVS_PER_CTLR; i++) {
    962  1.1  chopps 		fdc->fd_data[i].fdu = i;
    963  1.1  chopps 		fdc->fd_data[i].flags = 0;
    964  1.1  chopps 
    965  1.1  chopps 		fdc->fd_data[i].buf_track = -1;
    966  1.1  chopps 		fdc->fd_data[i].buf_dirty = 0;
    967  1.1  chopps 		fdc->fd_data[i].buf_data =
    968  1.1  chopps 		    malloc(MAX_SECTS * 512, M_DEVBUF, 0);
    969  1.1  chopps 		fdc->fd_data[i].buf_labels =
    970  1.1  chopps 		    malloc(MAX_SECTS * 16, M_DEVBUF, 0);
    971  1.1  chopps 
    972  1.1  chopps 		if (fdc->fd_data[i].buf_data == NULL ||
    973  1.1  chopps 		    fdc->fd_data[i].buf_labels == NULL) {
    974  1.1  chopps 			printf("Cannot alloc buffer memory for fd device\n");
    975  1.1  chopps 			return(0);
    976  1.1  chopps 		}
    977  1.1  chopps 
    978  1.1  chopps 		id = get_drive_id(i);
    979  1.1  chopps 		type = get_drive_type(id);
    980  1.1  chopps 
    981  1.1  chopps 		if (type != -1 && drive_types[type].tracks != 0) {
    982  1.1  chopps 			printf("floppy drive %d: %s\n", i,
    983  1.1  chopps 			    drive_types[type].name);
    984  1.1  chopps 		}
    985  1.1  chopps 	}
    986  1.1  chopps 
    987  1.1  chopps 	raw_buf = (char *)alloc_chipmem(30000);
    988  1.1  chopps 	if (raw_buf == NULL) {
    989  1.1  chopps 		printf("Cannot alloc chipmem for fd device\n");
    990  1.1  chopps 		return 0;
    991  1.1  chopps 	}
    992  1.1  chopps 
    993  1.1  chopps 	/* enable disk DMA */
    994  1.1  chopps 	custom.dmacon = DMAF_SETCLR | DMAF_DISK;
    995  1.1  chopps 
    996  1.1  chopps 	/* enable interrupts for IRQ_DSKBLK */
    997  1.1  chopps 	ciaa.icr = CIA_ICR_IR_SC | CIA_ICR_FLG;
    998  1.1  chopps 	custom.intena = INTF_SETCLR | INTF_SOFTINT;
    999  1.1  chopps 
   1000  1.1  chopps 	/* enable disk block interrupts */
   1001  1.1  chopps 	custom.intena = INTF_SETCLR | INTF_DSKBLK;
   1002  1.1  chopps 
   1003  1.1  chopps 	return(1);
   1004  1.1  chopps }
   1005  1.1  chopps 
   1006  1.1  chopps int
   1007  1.1  chopps Fdopen(dev, flags)
   1008  1.1  chopps 	dev_t dev;
   1009  1.1  chopps 	int flags;
   1010  1.1  chopps {
   1011  1.1  chopps 	fdcu_t fdcu;
   1012  1.1  chopps 	fdc_p fdc;
   1013  1.1  chopps 	fdu_t fdu;
   1014  1.1  chopps 	fd_p fd;
   1015  1.1  chopps 
   1016  1.1  chopps 	fdcu = 0;
   1017  1.1  chopps 	fdc = fdc_data + fdcu;
   1018  1.1  chopps 	fdu = UNIT(dev);
   1019  1.1  chopps 	fd = fdc->fd_data + fdu;
   1020  1.1  chopps 
   1021  1.1  chopps 	/* check bounds */
   1022  1.1  chopps 	if (fdu >= DRVS_PER_CTLR)
   1023  1.1  chopps 		return(ENXIO);
   1024  1.1  chopps 
   1025  1.1  chopps 	fd_probe(fd);
   1026  1.1  chopps 	if (fd->ft == NULL || fd->ft->tracks == 0)
   1027  1.1  chopps 		return(ENXIO);
   1028  1.1  chopps 
   1029  1.1  chopps 	fd->flags |= FDF_OPEN;
   1030  1.1  chopps 	fd->write_cnt = 0;
   1031  1.1  chopps 
   1032  1.1  chopps 	return(0);
   1033  1.1  chopps }
   1034  1.1  chopps 
   1035  1.1  chopps int
   1036  1.1  chopps fdclose(dev, flags)
   1037  1.1  chopps 	dev_t dev;
   1038  1.1  chopps 	int flags;
   1039  1.1  chopps {
   1040  1.1  chopps 	struct buf *dp,*bp;
   1041  1.1  chopps 	fdcu_t fdcu;
   1042  1.1  chopps 	fdc_p fdc;
   1043  1.1  chopps 	fdu_t fdu;
   1044  1.1  chopps 	fd_p fd;
   1045  1.1  chopps 
   1046  1.1  chopps 	fdcu = 0;
   1047  1.1  chopps 	fdc = fdc_data + fdcu;
   1048  1.1  chopps 	fdu = UNIT(dev);
   1049  1.1  chopps 	fd = fdc->fd_data + fdu;
   1050  1.1  chopps 
   1051  1.1  chopps 
   1052  1.1  chopps 	/* wait until activity is done for this drive */
   1053  1.1  chopps 	/* XXXX ACK! sleep.. */
   1054  1.1  chopps 	do {
   1055  1.1  chopps 		dp = &(fd->head);
   1056  1.1  chopps 		bp = dp->b_actf;
   1057  1.1  chopps 	} while (bp);
   1058  1.1  chopps 
   1059  1.1  chopps 	/* XXXX */
   1060  1.1  chopps 	printf("wrote %d tracks (%d)\n", fd->write_cnt, fd->buf_dirty);
   1061  1.1  chopps 
   1062  1.1  chopps 	fd->buf_track = -1;
   1063  1.1  chopps 	fd->buf_dirty = 0;
   1064  1.1  chopps 	fd->flags &= ~FDF_OPEN;
   1065  1.1  chopps 
   1066  1.1  chopps 	return(0);
   1067  1.1  chopps }
   1068  1.1  chopps 
   1069  1.1  chopps int
   1070  1.1  chopps fdioctl(dev, cmd, data, flag, p)
   1071  1.1  chopps 	dev_t dev;
   1072  1.1  chopps 	int cmd, flag;
   1073  1.1  chopps 	caddr_t data;
   1074  1.1  chopps 	struct proc *p;
   1075  1.1  chopps {
   1076  1.1  chopps 	struct disklabel *fd_label;
   1077  1.1  chopps 	fdcu_t fdcu;
   1078  1.1  chopps 	fdc_p fdc;
   1079  1.1  chopps 	fdu_t fdu;
   1080  1.1  chopps 	fd_p fd;
   1081  1.1  chopps 	int error;
   1082  1.1  chopps 
   1083  1.1  chopps 	fdcu = 0;
   1084  1.1  chopps 	fdc = fdc_data + fdcu;
   1085  1.1  chopps 	fdu = UNIT(dev);
   1086  1.1  chopps 	fd = fdc->fd_data + fdu;
   1087  1.1  chopps 	error = 0;
   1088  1.1  chopps 
   1089  1.1  chopps 	if (cmd != DIOCGDINFO)
   1090  1.1  chopps 		return (EINVAL);
   1091  1.1  chopps 
   1092  1.1  chopps 	fd_label = (struct disklabel *)data;
   1093  1.1  chopps 
   1094  1.1  chopps 	bzero(fd_label, sizeof(fd_label));
   1095  1.1  chopps 	fd_label->d_magic = DISKMAGIC;
   1096  1.1  chopps 	fd_label->d_type = DTYPE_FLOPPY;
   1097  1.1  chopps 	strncpy(fd_label->d_typename, "fd", sizeof(fd_label->d_typename) - 1);
   1098  1.1  chopps 	strcpy(fd_label->d_packname, "some pack");
   1099  1.1  chopps 
   1100  1.1  chopps 	fd_label->d_secsize = 512;
   1101  1.1  chopps 	fd_label->d_nsectors = 11;
   1102  1.1  chopps 	fd_label->d_ntracks = 2;
   1103  1.1  chopps 	fd_label->d_ncylinders = 80;
   1104  1.1  chopps 	fd_label->d_secpercyl = fd_label->d_nsectors * fd_label->d_ntracks;
   1105  1.1  chopps 	fd_label->d_secperunit= fd_label->d_ncylinders * fd_label->d_secpercyl;
   1106  1.1  chopps 
   1107  1.1  chopps 	fd_label->d_magic2 = DISKMAGIC;
   1108  1.1  chopps 	fd_label->d_partitions[0].p_offset = 0;
   1109  1.1  chopps 	fd_label->d_partitions[0].p_size = fd_label->d_secperunit;
   1110  1.1  chopps 	fd_label->d_partitions[0].p_fstype = FS_UNUSED;
   1111  1.1  chopps 	fd_label->d_npartitions = 1;
   1112  1.1  chopps 
   1113  1.1  chopps 	fd_label->d_checksum = 0;
   1114  1.1  chopps 	fd_label->d_checksum = dkcksum(fd_label);
   1115  1.1  chopps 
   1116  1.1  chopps 	return(0);
   1117  1.1  chopps }
   1118  1.1  chopps 
   1119  1.1  chopps int
   1120  1.1  chopps fdsize(dev)
   1121  1.1  chopps 	dev_t dev;
   1122  1.1  chopps {
   1123  1.1  chopps 	/* check UNIT? */
   1124  1.1  chopps 	return((fdc_data + 0)->fd_data[UNIT(dev)].size);
   1125  1.1  chopps }
   1126  1.1  chopps 
   1127  1.1  chopps void
   1128  1.1  chopps fdstrategy(bp)
   1129  1.1  chopps 	struct buf *bp;
   1130  1.1  chopps {
   1131  1.1  chopps 	fdcu_t fdcu;
   1132  1.1  chopps 	fdc_p fdc;
   1133  1.1  chopps 	fdu_t fdu;
   1134  1.1  chopps 	fd_p fd;
   1135  1.1  chopps 	long nblocks, blknum;
   1136  1.1  chopps 	struct buf *dp;
   1137  1.1  chopps 	int s;
   1138  1.1  chopps 
   1139  1.1  chopps 	fdcu = 0;
   1140  1.1  chopps 	fdc = fdc_data + fdcu;
   1141  1.1  chopps 	fdu = UNIT(bp->b_dev);
   1142  1.1  chopps 	fd = fdc->fd_data + fdu;
   1143  1.1  chopps 
   1144  1.1  chopps 	if (bp->b_blkno < 0) {
   1145  1.1  chopps 		/* XXXX */
   1146  1.1  chopps 		printf("fdstrat error: fdu = %d, blkno = %d, bcount = %d\n",
   1147  1.1  chopps 		    fdu, bp->b_blkno, bp->b_bcount);
   1148  1.1  chopps 		bp->b_error = EINVAL;
   1149  1.1  chopps 		bp->b_flags |= B_ERROR;
   1150  1.1  chopps 		biodone(bp);
   1151  1.1  chopps 		return;
   1152  1.1  chopps 	}
   1153  1.1  chopps 
   1154  1.1  chopps 	/*
   1155  1.1  chopps 	 * Set up block calculations.
   1156  1.1  chopps 	 */
   1157  1.1  chopps 	blknum = (unsigned long) bp->b_blkno * DEV_BSIZE / FDBLK;
   1158  1.1  chopps 	nblocks = fd->sects * fd->ft->tracks * fd->ft->heads;
   1159  1.1  chopps 	if (blknum + (bp->b_bcount / FDBLK) > nblocks) {
   1160  1.1  chopps 		/* XXXX */
   1161  1.1  chopps 		printf("at end of disk\n");
   1162  1.1  chopps 		bp->b_error = ENOSPC;
   1163  1.1  chopps 		bp->b_flags |= B_ERROR;
   1164  1.1  chopps 		biodone(bp);
   1165  1.1  chopps 		return;
   1166  1.1  chopps 	}
   1167  1.1  chopps 
   1168  1.1  chopps 	bp->b_cylin = blknum;	/* set here for disksort */
   1169  1.1  chopps 	dp = &(fd->head);
   1170  1.1  chopps 
   1171  1.1  chopps 	s = splbio();
   1172  1.1  chopps 	disksort(dp, bp);
   1173  1.1  chopps 	untimeout((timeout_t)fd_turnoff, (caddr_t)fdc); /* a good idea */
   1174  1.1  chopps 	fdstart(fdc);
   1175  1.1  chopps 	splx(s);
   1176  1.1  chopps }
   1177  1.1  chopps 
   1178  1.1  chopps /*
   1179  1.1  chopps  * We have just queued something.. if the controller is not busy
   1180  1.1  chopps  * then simulate the case where it has just finished a command
   1181  1.1  chopps  * So that it (the interrupt routine) looks on the queue for more
   1182  1.1  chopps  * work to do and picks up what we just added.
   1183  1.1  chopps  * If the controller is already busy, we need do nothing, as it
   1184  1.1  chopps  * will pick up our work when the present work completes
   1185  1.1  chopps  */
   1186  1.1  chopps void
   1187  1.1  chopps fdstart(fdc)
   1188  1.1  chopps 	fdc_p fdc;
   1189  1.1  chopps {
   1190  1.1  chopps 	int s;
   1191  1.1  chopps 
   1192  1.1  chopps 	s = splbio();
   1193  1.1  chopps 	if (fdc->state == FINDWORK)
   1194  1.1  chopps 		fdintr(fdc->fdcu);
   1195  1.1  chopps 	splx(s);
   1196  1.1  chopps }
   1197  1.1  chopps 
   1198  1.1  chopps /*
   1199  1.1  chopps  * just ensure it has the right spl
   1200  1.1  chopps  */
   1201  1.1  chopps void
   1202  1.1  chopps fd_pseudointr(fdc)
   1203  1.1  chopps 	fdc_p fdc;
   1204  1.1  chopps {
   1205  1.1  chopps 	int s;
   1206  1.1  chopps 
   1207  1.1  chopps 	s = splbio();
   1208  1.1  chopps 	fdintr(fdc->fdcu);
   1209  1.1  chopps 	splx(s);
   1210  1.1  chopps }
   1211  1.1  chopps 
   1212  1.1  chopps void
   1213  1.1  chopps fd_timeout(fdc)
   1214  1.1  chopps 	fdc_p fdc;
   1215  1.1  chopps {
   1216  1.1  chopps 	struct buf *dp,*bp;
   1217  1.1  chopps 	fd_p fd;
   1218  1.1  chopps 
   1219  1.1  chopps 	fd = fdc->fd;
   1220  1.1  chopps 	dp = &fd->head;
   1221  1.1  chopps 	bp = dp->b_actf;
   1222  1.1  chopps 
   1223  1.1  chopps 	/* XXXX */
   1224  1.1  chopps 	printf("fd%d: Operation timeout\n", fd->fdu);
   1225  1.1  chopps 	if (bp) {
   1226  1.1  chopps 		retrier(fdc);
   1227  1.1  chopps 		fdc->state = DONE_IO;
   1228  1.1  chopps 		if (fdc->retry < 6)
   1229  1.1  chopps 			fdc->retry = 6;
   1230  1.1  chopps 	} else {
   1231  1.1  chopps 		fdc->fd = NULL;
   1232  1.1  chopps 		fdc->state = FINDWORK;
   1233  1.1  chopps 	}
   1234  1.1  chopps 
   1235  1.1  chopps 	fd_pseudointr(fdc);
   1236  1.1  chopps }
   1237  1.1  chopps 
   1238  1.1  chopps /*
   1239  1.1  chopps  * keep calling the state machine until it returns a 0
   1240  1.1  chopps  * ALWAYS called at SPLBIO
   1241  1.1  chopps  */
   1242  1.1  chopps void
   1243  1.1  chopps fdintr(fdcu)
   1244  1.1  chopps 	fdcu_t fdcu;
   1245  1.1  chopps {
   1246  1.1  chopps 	fdc_p fdc;
   1247  1.1  chopps 
   1248  1.1  chopps 	fdc = fdc_data + fdcu;
   1249  1.1  chopps 	while (fdstate(fdc))
   1250  1.1  chopps 		;
   1251  1.1  chopps }
   1252  1.1  chopps 
   1253  1.1  chopps /*
   1254  1.1  chopps  * The controller state machine.
   1255  1.1  chopps  * if it returns a non zero value, it should be called again immediatly
   1256  1.1  chopps  */
   1257  1.1  chopps int
   1258  1.1  chopps fdstate(fdc)
   1259  1.1  chopps 	fdc_p fdc;
   1260  1.1  chopps {
   1261  1.1  chopps 	struct buf *dp,*bp;
   1262  1.1  chopps 	int track, read, sec, i;
   1263  1.1  chopps 	u_long blknum;
   1264  1.1  chopps 	fd_p fd;
   1265  1.1  chopps 
   1266  1.1  chopps 	fd = fdc->fd;
   1267  1.1  chopps 
   1268  1.1  chopps 	if (fd == NULL) {
   1269  1.1  chopps 		/* search for a unit do work with */
   1270  1.1  chopps 		for (i = 0; i < DRVS_PER_CTLR; i++) {
   1271  1.1  chopps 			fd = fdc->fd_data + i;
   1272  1.1  chopps 			dp = &(fd->head);
   1273  1.1  chopps 			bp = dp->b_actf;
   1274  1.1  chopps 			if (bp) {
   1275  1.1  chopps 				fdc->fd = fd;
   1276  1.1  chopps 				break;
   1277  1.1  chopps 			}
   1278  1.1  chopps 		}
   1279  1.1  chopps 
   1280  1.1  chopps 		if (fdc->fd)
   1281  1.1  chopps 			return(1);
   1282  1.1  chopps 
   1283  1.1  chopps 		fdc->state = FINDWORK;
   1284  1.1  chopps 		TRACE1("[fdc%d IDLE]\n", fdc->fdcu);
   1285  1.1  chopps 		return(0);
   1286  1.1  chopps 	}
   1287  1.1  chopps 
   1288  1.1  chopps 	dp = &(fd->head);
   1289  1.1  chopps 	bp = dp->b_actf;
   1290  1.1  chopps 
   1291  1.1  chopps 	blknum = (u_long)bp->b_blkno * DEV_BSIZE / FDBLK + fd->skip / FDBLK;
   1292  1.1  chopps 	track = blknum / fd->sects;
   1293  1.1  chopps 	sec = blknum % fd->sects;
   1294  1.1  chopps 
   1295  1.1  chopps 	read = bp->b_flags & B_READ;
   1296  1.1  chopps 	TRACE1("fd%d", fd->fdu);
   1297  1.1  chopps 	TRACE1("[%s]", fdstates[fdc->state]);
   1298  1.1  chopps 	TRACE1("(0x%x) ", fd->flags);
   1299  1.1  chopps 	TRACE1("%d\n", fd->buf_track);
   1300  1.1  chopps 
   1301  1.1  chopps 	untimeout((timeout_t)fd_turnoff, (caddr_t)fdc);
   1302  1.1  chopps 	timeout((timeout_t)fd_turnoff, (caddr_t)fdc, 4 * hz);
   1303  1.1  chopps 
   1304  1.1  chopps 	switch (fdc->state) {
   1305  1.1  chopps 	case FINDWORK:
   1306  1.1  chopps 		if (!bp) {
   1307  1.1  chopps 			if (fd->buf_dirty) {
   1308  1.1  chopps 				track_write(fdc, fd);
   1309  1.1  chopps 				return(0);
   1310  1.1  chopps 			}
   1311  1.1  chopps 			fdc->fd = NULL;
   1312  1.1  chopps 			return(1);
   1313  1.1  chopps 		}
   1314  1.1  chopps 
   1315  1.1  chopps 		fdc->state = DOSEEK;
   1316  1.1  chopps 		fdc->retry = 0;
   1317  1.1  chopps 		fd->skip = 0;
   1318  1.1  chopps 		return(1);
   1319  1.1  chopps 	case DOSEEK:
   1320  1.1  chopps 		fd_turnon(fdc, fd->fdu);
   1321  1.1  chopps 
   1322  1.1  chopps 		/*
   1323  1.1  chopps 		 * If not started, error starting it
   1324  1.1  chopps 		 */
   1325  1.1  chopps 		if (fdc->motor_fdu != fd->fdu) {
   1326  1.1  chopps 			/* XXXX */
   1327  1.1  chopps 			printf("motor not on!\n");
   1328  1.1  chopps 		}
   1329  1.1  chopps 
   1330  1.1  chopps 		/*
   1331  1.1  chopps 		 * If track not in buffer, read it in
   1332  1.1  chopps 		 */
   1333  1.1  chopps 		if (fd->buf_track != track) {
   1334  1.1  chopps 			TRACE1("do track %d\n", track);
   1335  1.1  chopps 
   1336  1.1  chopps 			if (fd->buf_dirty)
   1337  1.1  chopps 				track_write(fdc, fd);
   1338  1.1  chopps 			else
   1339  1.1  chopps 				track_read(fdc, fd, track);
   1340  1.1  chopps 			return(0);
   1341  1.1  chopps 		}
   1342  1.1  chopps 
   1343  1.1  chopps 		fdc->state = DO_IO;
   1344  1.1  chopps 		return(1);
   1345  1.1  chopps 	case DO_IO:
   1346  1.1  chopps 		if (read)
   1347  1.1  chopps 			bcopy(&fd->buf_data[sec * FDBLK],
   1348  1.1  chopps 			    bp->b_un.b_addr + fd->skip, FDBLK);
   1349  1.1  chopps 		else {
   1350  1.1  chopps 			bcopy(bp->b_un.b_addr + fd->skip,
   1351  1.1  chopps 			    &fd->buf_data[sec * FDBLK], FDBLK);
   1352  1.1  chopps 			fd->buf_dirty = 1;
   1353  1.1  chopps 			if (IMMED_WRITE) {
   1354  1.1  chopps 				fdc->state = DONE_IO;
   1355  1.1  chopps 				track_write(fdc, fd);
   1356  1.1  chopps 				return(0);
   1357  1.1  chopps 			}
   1358  1.1  chopps 		}
   1359  1.1  chopps 	case DONE_IO:
   1360  1.1  chopps 		fd->skip += FDBLK;
   1361  1.1  chopps 		if (fd->skip < bp->b_bcount)
   1362  1.1  chopps 			fdc->state = DOSEEK;
   1363  1.1  chopps 		else {
   1364  1.1  chopps 			fd->skip = 0;
   1365  1.1  chopps 			bp->b_resid = 0;
   1366  1.1  chopps 			dp->b_actf = bp->b_actf;
   1367  1.1  chopps 			biodone(bp);
   1368  1.1  chopps 			fdc->state = FINDWORK;
   1369  1.1  chopps 		}
   1370  1.1  chopps 		return(1);
   1371  1.1  chopps 	case WAIT_READ:
   1372  1.1  chopps 		untimeout((timeout_t)fd_timeout, (caddr_t)fdc);
   1373  1.1  chopps 		custom.dsklen = 0;
   1374  1.1  chopps 		amiga_read(fd);
   1375  1.1  chopps 		fdc->state = DO_IO;
   1376  1.1  chopps 		return(1);
   1377  1.1  chopps 	case WAIT_WRITE:
   1378  1.1  chopps 		untimeout((timeout_t)fd_timeout, (caddr_t)fdc);
   1379  1.1  chopps 		custom.dsklen = 0;
   1380  1.1  chopps 		fdc->state = fdc->saved;
   1381  1.1  chopps 		fd->buf_dirty = 0;
   1382  1.1  chopps 		return(1);
   1383  1.1  chopps 	default:
   1384  1.1  chopps 		/* XXXX */
   1385  1.1  chopps 		printf("Unexpected FD int->%d\n", fdc->state);
   1386  1.1  chopps 		return 0;
   1387  1.1  chopps 	}
   1388  1.1  chopps 
   1389  1.1  chopps 	/* Come back immediatly to new state */
   1390  1.1  chopps 	return(1);
   1391  1.1  chopps }
   1392  1.1  chopps 
   1393  1.1  chopps int
   1394  1.1  chopps retrier(fdc)
   1395  1.1  chopps 	fdc_p fdc;
   1396  1.1  chopps {
   1397  1.1  chopps 	struct buf *dp,*bp;
   1398  1.1  chopps 	fd_p fd;
   1399  1.1  chopps 
   1400  1.1  chopps 	fd = fdc->fd;
   1401  1.1  chopps 	dp = &(fd->head);
   1402  1.1  chopps 	bp = dp->b_actf;
   1403  1.1  chopps 
   1404  1.1  chopps #if 0
   1405  1.1  chopps 	switch(fdc->retry) {
   1406  1.1  chopps 	case 0:
   1407  1.1  chopps 	case 1:
   1408  1.1  chopps 	case 2:
   1409  1.1  chopps 		fdc->state = SEEKCOMPLETE;
   1410  1.1  chopps 		break;
   1411  1.1  chopps 	case 3:
   1412  1.1  chopps 	case 4:
   1413  1.1  chopps 	case 5:
   1414  1.1  chopps 		fdc->state = STARTRECAL;
   1415  1.1  chopps 		break;
   1416  1.1  chopps 	case 6:
   1417  1.1  chopps 		fdc->state = RESETCTLR;
   1418  1.1  chopps 		break;
   1419  1.1  chopps 	case 7:
   1420  1.1  chopps 		break;
   1421  1.1  chopps 	default:
   1422  1.1  chopps #endif
   1423  1.1  chopps 	/* XXXX */
   1424  1.1  chopps 	printf("fd%d: hard error\n", fd->fdu);
   1425  1.1  chopps 
   1426  1.1  chopps 	bp->b_flags |= B_ERROR;
   1427  1.1  chopps 	bp->b_error = EIO;
   1428  1.1  chopps 	bp->b_resid = bp->b_bcount - fd->skip;
   1429  1.1  chopps 	dp->b_actf = bp->b_actf;
   1430  1.1  chopps 	fd->skip = 0;
   1431  1.1  chopps 	biodone(bp);
   1432  1.1  chopps 	fdc->state = FINDWORK;
   1433  1.1  chopps 	return(1);
   1434  1.1  chopps #if 0
   1435  1.1  chopps 	fdc->retry++;
   1436  1.1  chopps 	return(1);
   1437  1.1  chopps #endif
   1438  1.1  chopps }
   1439  1.1  chopps 
   1440  1.1  chopps #endif
   1441