Home | History | Annotate | Line # | Download | only in boot
fd.c revision 1.3
      1  1.3  sakamoto /*	$NetBSD: fd.c,v 1.3 1999/06/28 01:20:44 sakamoto Exp $	*/
      2  1.1  sakamoto 
      3  1.1  sakamoto /*-
      4  1.1  sakamoto  * Copyright (C) 1997-1998 Kazuki Sakamoto (sakamoto (at) netbsd.org)
      5  1.1  sakamoto  * All rights reserved.
      6  1.1  sakamoto  *
      7  1.1  sakamoto  * Floppy Disk Drive standalone device driver
      8  1.1  sakamoto  *
      9  1.1  sakamoto  * Redistribution and use in source and binary forms, with or without
     10  1.1  sakamoto  * modification, are permitted provided that the following conditions
     11  1.1  sakamoto  * are met:
     12  1.1  sakamoto  * 1. Redistributions of source code must retain the above copyright
     13  1.1  sakamoto  *    notice, this list of conditions and the following disclaimer.
     14  1.1  sakamoto  * 2. Redistributions in binary form must reproduce the above copyright
     15  1.1  sakamoto  *    notice, this list of conditions and the following disclaimer in the
     16  1.1  sakamoto  *    documentation and/or other materials provided with the distribution.
     17  1.1  sakamoto  * 3. All advertising materials mentioning features or use of this software
     18  1.1  sakamoto  *    must display the following acknowledgement:
     19  1.1  sakamoto  *      This product includes software developed by Kazuki Sakamoto.
     20  1.1  sakamoto  * 4. The name of the author may not be used to endorse or promote products
     21  1.1  sakamoto  *    derived from this software without specific prior written permission.
     22  1.1  sakamoto  *
     23  1.1  sakamoto  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     24  1.1  sakamoto  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     25  1.1  sakamoto  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     26  1.1  sakamoto  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     27  1.1  sakamoto  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     28  1.1  sakamoto  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     29  1.1  sakamoto  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     30  1.1  sakamoto  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     31  1.1  sakamoto  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     32  1.1  sakamoto  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     33  1.1  sakamoto  */
     34  1.1  sakamoto 
     35  1.1  sakamoto #include <sys/param.h>
     36  1.3  sakamoto #include <stand.h>
     37  1.3  sakamoto #include "boot.h"
     38  1.1  sakamoto 
     39  1.1  sakamoto /*---------------------------------------------------------------------------*
     40  1.1  sakamoto  *			Floppy Disk Controller Define			     *
     41  1.1  sakamoto  *---------------------------------------------------------------------------*/
     42  1.3  sakamoto /* Floppy Disk Controller Registers */
     43  1.1  sakamoto int FDC_PORT[] = {				/* fdc base I/O port */
     44  1.1  sakamoto 		0x3f0, /* primary */
     45  1.1  sakamoto 		};
     46  1.3  sakamoto #define	FDC_DOR(x)	(FDC_PORT[x] + 0x2)	/* motor drive control bits */
     47  1.3  sakamoto #define	FDC_STATUS(x)	(FDC_PORT[x] + 0x4)	/* fdc main status register */
     48  1.3  sakamoto #define	FDC_DATA(x)	(FDC_PORT[x] + 0x5)	/* fdc data register */
     49  1.3  sakamoto #define	FDC_RATE(x)	(FDC_PORT[x] + 0x7)	/* transfer rate register */
     50  1.1  sakamoto 
     51  1.1  sakamoto #define	FDC_IRQ		6
     52  1.1  sakamoto #define	FD_DMA_CHAN	2
     53  1.1  sakamoto 
     54  1.1  sakamoto /* fdc main status register */
     55  1.1  sakamoto #define	RQM	  0x80	/* the host can transfer data if set */
     56  1.1  sakamoto #define	DIO	  0x40	/* direction of data transfer. write required if set */
     57  1.3  sakamoto #define	NON_DMA   0x20  /* fdc have date for transfer in non dma mode */
     58  1.1  sakamoto #define	CMD_BUSY  0x10	/* command busy if set */
     59  1.1  sakamoto 
     60  1.1  sakamoto /* fdc result status */
     61  1.1  sakamoto #define	ST0_IC_MASK	0xc0	/* interrupt code  00:normal terminate */
     62  1.1  sakamoto #define	ST1_EN		0x80	/* end of cylinder */
     63  1.1  sakamoto 
     64  1.1  sakamoto /* fdc digtal output register */
     65  1.1  sakamoto #define	DOR_DMAEN	0x08	/* DRQ, nDACK, TC and FINTR output enable */
     66  1.1  sakamoto #define	DOR_RESET	0x04	/* fdc software reset */
     67  1.1  sakamoto 
     68  1.1  sakamoto /* fdc command */
     69  1.1  sakamoto #define	CMD_RECALIBRATE	0x07	/* recalibrate */
     70  1.1  sakamoto #define	CMD_SENSE_INT	0x08	/* sense interrupt status */
     71  1.1  sakamoto #define	CMD_DRV_SENSE	0x04	/* sense drive status */
     72  1.1  sakamoto #define	CMD_SEEK	0x0f	/* seek */
     73  1.1  sakamoto #define	CMD_FORMAT	0x4d	/* format */
     74  1.1  sakamoto #define	CMD_READ	0x46	/* read e6 */
     75  1.1  sakamoto #define	CMD_WRITE	0xc5	/* write */
     76  1.1  sakamoto #define	CMD_VERIFY	0xf6	/* verify */
     77  1.1  sakamoto #define	CMD_READID	0x4a	/* readID */
     78  1.1  sakamoto #define	CMD_SPECIFY	0x03	/* specify */
     79  1.1  sakamoto #define	CMD_CONFIG	0x13	/* config */
     80  1.1  sakamoto #define	CMD_VERSION	0x10	/* version */
     81  1.1  sakamoto 
     82  1.1  sakamoto /* command specify value */
     83  1.1  sakamoto #define	SPECIFY1	((0x0d<<4)|0x0f)
     84  1.1  sakamoto #define	SPECIFY2	((0x01<<1)|0)	/* DMA MODE */
     85  1.1  sakamoto 
     86  1.1  sakamoto /* fdc result */
     87  1.1  sakamoto #define	STATUS_MAX	16	/* result status max number */
     88  1.3  sakamoto #define	RESULT_VERSION	0x90	/* enhanced controller */
     89  1.1  sakamoto #define	RESULT_SEEK	0x20	/* seek & recalibrate complete flag on status0 */
     90  1.1  sakamoto 
     91  1.1  sakamoto /*---------------------------------------------------------------------------*
     92  1.1  sakamoto  *			     Floppy Disk Type Define	 		     *
     93  1.1  sakamoto  *---------------------------------------------------------------------------*/
     94  1.1  sakamoto struct	fdd_type {
     95  1.1  sakamoto 	int	seccount;	/* sector per track */
     96  1.1  sakamoto 	int	secsize;	/* byte per sector (uPD765 paramater) */
     97  1.1  sakamoto 	int	datalen;	/* data length */
     98  1.1  sakamoto 	int	gap;		/* gap */
     99  1.1  sakamoto 	int	gaplen;		/* gap length */
    100  1.1  sakamoto 	int	cylinder;	/* track per media */
    101  1.1  sakamoto 	int	maxseccount;	/* media max sector count */
    102  1.1  sakamoto 	int	step;		/* seek step */
    103  1.1  sakamoto 	int	rate;		/* drive rate (250 or 500kbps) */
    104  1.1  sakamoto 	int	heads;		/* heads */
    105  1.1  sakamoto 	int	f_gap;		/* format gap */
    106  1.1  sakamoto 	int	mselect;	/* drive mode select */
    107  1.1  sakamoto 	char	*type_name;	/* media type name */
    108  1.1  sakamoto };
    109  1.1  sakamoto typedef struct	fdd_type FDDTYPE;
    110  1.1  sakamoto 
    111  1.3  sakamoto #define	FDTYPE_MAX	5
    112  1.1  sakamoto FDDTYPE fdd_types[FDTYPE_MAX] = {
    113  1.1  sakamoto 	{ 18,2,0xff,0x1b,0x54,80,2880,1,0,2,0x6c,0,"2HQ" }, /* 2HD (PC/AT) */
    114  1.1  sakamoto 	{  8,3,0xff,0x35,0x74,77,1232,1,0,2,0x54,1,"2HD" }, /* 2HD (98) */
    115  1.1  sakamoto 	{ 15,2,0xff,0x1b,0x54,80,2400,1,0,2,0x54,1,"2HC" }, /* 2HC */
    116  1.1  sakamoto 	{  9,2,0xff,0x23,0x50,80,1440,1,2,2,0x50,1,"2DD9" },/* 2DD 9 sector */
    117  1.1  sakamoto 	{  8,2,0xff,0x3a,0x50,80,1280,1,2,2,0x50,1,"2DD8" },/* 2DD 8 sector */
    118  1.1  sakamoto };
    119  1.1  sakamoto 
    120  1.1  sakamoto int	fdsectors[] = {128, 256, 512, 1024, 2048, 4096};
    121  1.1  sakamoto #define	SECTOR_MAX	4096
    122  1.1  sakamoto #define	FDBLK	(fdsectors[un->un_type->secsize])
    123  1.1  sakamoto 
    124  1.1  sakamoto #define	START_CYL	0
    125  1.1  sakamoto #define	START_SECTOR	1
    126  1.1  sakamoto 
    127  1.1  sakamoto #define	DELAY(x)	delay(100000 * x)		/* about 100ms */
    128  1.3  sakamoto #define	INT_TIMEOUT	3000000
    129  1.1  sakamoto 
    130  1.1  sakamoto /*---------------------------------------------------------------------------*
    131  1.1  sakamoto  *			FDC Device Driver Define			     *
    132  1.1  sakamoto  *---------------------------------------------------------------------------*/
    133  1.1  sakamoto #define	CTLR_MAX	1
    134  1.1  sakamoto #define	UNIT_MAX	2
    135  1.1  sakamoto 
    136  1.1  sakamoto struct	fd_unit {
    137  1.1  sakamoto 	int	ctlr;
    138  1.1  sakamoto 	int	unit;
    139  1.1  sakamoto 	int	part;
    140  1.1  sakamoto 	u_int	un_flags;		/* unit status flag */
    141  1.1  sakamoto 	int	stat[STATUS_MAX];	/* result code */
    142  1.1  sakamoto 	FDDTYPE	*un_type;		/* floppy type (pointer) */
    143  1.1  sakamoto };
    144  1.1  sakamoto typedef	struct fd_unit FD_UNIT;
    145  1.1  sakamoto FD_UNIT	fd_unit[CTLR_MAX][UNIT_MAX];
    146  1.1  sakamoto 
    147  1.3  sakamoto /*
    148  1.1  sakamoto  *	un_flags flags
    149  1.1  sakamoto  */
    150  1.3  sakamoto #define	INT_ALIVE	0x00000001	/* Device is Alive and Available */
    151  1.3  sakamoto #define	INT_READY	0x00000002	/* Device is Ready */
    152  1.3  sakamoto #define	INT_BUSY	0x00000004	/* Device is busy */
    153  1.1  sakamoto 
    154  1.1  sakamoto /*---------------------------------------------------------------------------*
    155  1.1  sakamoto  *				Misc define				     *
    156  1.1  sakamoto  *---------------------------------------------------------------------------*/
    157  1.1  sakamoto #define	TIMEOUT		10000000
    158  1.1  sakamoto #define	ND_TIMEOUT	10000000
    159  1.1  sakamoto 
    160  1.3  sakamoto #define	SUCCESS		0
    161  1.3  sakamoto #define	FAIL		-1
    162  1.1  sakamoto 
    163  1.1  sakamoto /*
    164  1.1  sakamoto  *	function declaration
    165  1.1  sakamoto  */
    166  1.3  sakamoto int fdc_out __P((int, int));
    167  1.3  sakamoto int fdc_in __P((int, u_char *));
    168  1.3  sakamoto int fdc_intr_wait __P((void));
    169  1.3  sakamoto int fd_check __P((FD_UNIT *));
    170  1.3  sakamoto void motor_on __P((int, int));
    171  1.3  sakamoto void motor_off __P((int, int));
    172  1.3  sakamoto void fdReset __P((int));
    173  1.3  sakamoto void fdRecalibrate __P((int, int));
    174  1.3  sakamoto void fdSpecify __P((int));
    175  1.3  sakamoto void fdDriveStatus __P((int, int, int, int *));
    176  1.3  sakamoto int fdSeek __P((int, int, int));
    177  1.3  sakamoto int fdSenseInt __P((int, int *));
    178  1.3  sakamoto int fdReadWrite __P((FD_UNIT *, int, int, int, int, u_char *));
    179  1.3  sakamoto void irq_init __P((void));
    180  1.3  sakamoto int irq_polling __P((int, int));
    181  1.3  sakamoto void dma_setup __P((u_char *, int, int, int));
    182  1.3  sakamoto int dma_finished __P((int));
    183  1.1  sakamoto 
    184  1.1  sakamoto /*===========================================================================*
    185  1.1  sakamoto  *				   fdinit				     *
    186  1.1  sakamoto  *===========================================================================*/
    187  1.3  sakamoto int
    188  1.1  sakamoto fdinit(un)
    189  1.1  sakamoto 	FD_UNIT	*un;
    190  1.1  sakamoto {
    191  1.1  sakamoto 	int ctlr = un->ctlr;
    192  1.3  sakamoto 	u_char result;
    193  1.1  sakamoto 
    194  1.1  sakamoto #if 0
    195  1.1  sakamoto 	irq_init();
    196  1.1  sakamoto #endif 0
    197  1.1  sakamoto 	fdReset(ctlr);
    198  1.3  sakamoto 
    199  1.1  sakamoto 	if (fdc_out(ctlr, CMD_VERSION) != SUCCESS) {  /* version check */
    200  1.3  sakamoto 		printf ("fdc%d:fatal error: CMD_VERSION cmd fail\n", ctlr);
    201  1.1  sakamoto 		return (FAIL);
    202  1.1  sakamoto 	}
    203  1.1  sakamoto 	if (fdc_in(ctlr, &result) != SUCCESS) {
    204  1.3  sakamoto 		printf ("fdc%d:fatal error: CMD_VERSION exec fail\n", ctlr);
    205  1.1  sakamoto 		return (FAIL);
    206  1.1  sakamoto 	}
    207  1.3  sakamoto 	if (result != (u_char)RESULT_VERSION) {
    208  1.3  sakamoto 		printf ("fdc%d:fatal error: unknown version fdc\n", ctlr);
    209  1.1  sakamoto 		return (FAIL);
    210  1.1  sakamoto 	}
    211  1.1  sakamoto 
    212  1.1  sakamoto 	un->un_flags = INT_ALIVE;
    213  1.1  sakamoto 	return (SUCCESS);
    214  1.1  sakamoto }
    215  1.1  sakamoto 
    216  1.1  sakamoto /*===========================================================================*
    217  1.1  sakamoto  *				   fdopen				     *
    218  1.1  sakamoto  *===========================================================================*/
    219  1.3  sakamoto int
    220  1.1  sakamoto fdopen(f, ctlr, unit, part)
    221  1.1  sakamoto 	struct open_file *f;
    222  1.1  sakamoto 	int ctlr, unit, part;
    223  1.1  sakamoto {
    224  1.1  sakamoto 	FD_UNIT	*un;
    225  1.1  sakamoto 	int *stat = un->stat;
    226  1.1  sakamoto 
    227  1.1  sakamoto 	if (ctlr >= CTLR_MAX)
    228  1.1  sakamoto 		return (ENXIO);
    229  1.1  sakamoto 	if (unit >= UNIT_MAX)
    230  1.1  sakamoto 		return (ENXIO);
    231  1.1  sakamoto 	un = &fd_unit[ctlr][unit];
    232  1.1  sakamoto 
    233  1.1  sakamoto 	if (!(un->un_flags & INT_ALIVE)) {
    234  1.1  sakamoto 		if (fdinit(un) != SUCCESS)
    235  1.1  sakamoto 			return (ENXIO);
    236  1.1  sakamoto 	}
    237  1.1  sakamoto 
    238  1.1  sakamoto 	motor_on(ctlr, unit);
    239  1.1  sakamoto 
    240  1.1  sakamoto 	fdRecalibrate(ctlr, unit);
    241  1.1  sakamoto 	fdSenseInt(ctlr, stat);
    242  1.1  sakamoto 	if (stat[1] != START_CYL) {
    243  1.1  sakamoto 		printf("fdc%d: unit:%d recalibrate failed. status:0x%x cyl:%d\n",
    244  1.1  sakamoto 			ctlr, unit, stat[0], stat[1]);
    245  1.1  sakamoto 		motor_off(ctlr, unit);
    246  1.1  sakamoto 		return (EIO);
    247  1.1  sakamoto 	}
    248  1.1  sakamoto 
    249  1.1  sakamoto 	if (fd_check(un) != SUCCESS)	/* research disk type */
    250  1.1  sakamoto 		return (EIO);
    251  1.1  sakamoto 
    252  1.1  sakamoto 	f->f_devdata = (void *)un;
    253  1.1  sakamoto 	return (SUCCESS);
    254  1.1  sakamoto }
    255  1.1  sakamoto 
    256  1.1  sakamoto /*===========================================================================*
    257  1.1  sakamoto  *				   fdclose				     *
    258  1.1  sakamoto  *===========================================================================*/
    259  1.3  sakamoto int
    260  1.1  sakamoto fdclose(f)
    261  1.1  sakamoto 	struct open_file *f;
    262  1.1  sakamoto {
    263  1.1  sakamoto 	FD_UNIT *un = f->f_devdata;
    264  1.1  sakamoto 
    265  1.1  sakamoto 	fdRecalibrate(un->ctlr, un->unit);
    266  1.1  sakamoto 	fdSenseInt(un->ctlr, un->stat);
    267  1.1  sakamoto 	motor_off(un->ctlr, un->unit);
    268  1.1  sakamoto 	un->un_flags = 0;
    269  1.1  sakamoto 	return (SUCCESS);
    270  1.1  sakamoto }
    271  1.1  sakamoto 
    272  1.1  sakamoto /*===========================================================================*
    273  1.1  sakamoto  *				   fdioctl				     *
    274  1.1  sakamoto  *===========================================================================*/
    275  1.3  sakamoto int
    276  1.1  sakamoto fdioctl(f, cmd, arg)
    277  1.1  sakamoto 	struct open_file *f;
    278  1.1  sakamoto 	u_long cmd;
    279  1.1  sakamoto 	void *arg;
    280  1.1  sakamoto {
    281  1.3  sakamoto 	switch (cmd) {
    282  1.1  sakamoto 	default:
    283  1.1  sakamoto 		return (EIO);
    284  1.1  sakamoto 	}
    285  1.1  sakamoto 
    286  1.1  sakamoto 	return (SUCCESS);
    287  1.1  sakamoto }
    288  1.1  sakamoto 
    289  1.1  sakamoto /*===========================================================================*
    290  1.1  sakamoto  *				   fdstrategy				     *
    291  1.1  sakamoto  *===========================================================================*/
    292  1.3  sakamoto int
    293  1.1  sakamoto fdstrategy(devdata, func, blk, size, buf, rsize)
    294  1.1  sakamoto 	void *devdata;	/* device uniq data */
    295  1.1  sakamoto 	int func;	/* function (read or write) */
    296  1.1  sakamoto 	daddr_t blk;	/* block number */
    297  1.1  sakamoto 	size_t size;	/* request size in bytes */
    298  1.1  sakamoto 	void *buf;	/* buffer */
    299  1.1  sakamoto 	size_t *rsize;	/* bytes transferred */
    300  1.1  sakamoto {
    301  1.1  sakamoto 	int sectrac, cyl, head, sec;
    302  1.1  sakamoto 	FD_UNIT *un = devdata;
    303  1.1  sakamoto 	int ctlr = un->ctlr;
    304  1.1  sakamoto 	int unit = un->unit;
    305  1.1  sakamoto 	int *stat = un->stat;
    306  1.1  sakamoto 	long nblock, blknum;
    307  1.1  sakamoto 	int fd_skip = 0;
    308  1.1  sakamoto 	char *cbuf = (char *)buf;
    309  1.1  sakamoto 
    310  1.3  sakamoto 	if (un->un_flags & INT_BUSY) {
    311  1.1  sakamoto 		return (ENXIO);
    312  1.1  sakamoto 	}
    313  1.1  sakamoto 	fdDriveStatus(ctlr, unit, 0, stat);
    314  1.1  sakamoto 
    315  1.1  sakamoto 	nblock = un->un_type->maxseccount;
    316  1.1  sakamoto 	sectrac = un->un_type->seccount;	/* sector per track */
    317  1.1  sakamoto 	*rsize = 0;
    318  1.1  sakamoto 
    319  1.1  sakamoto 	while (fd_skip < size) {
    320  1.1  sakamoto 		blknum = (u_long)blk * DEV_BSIZE/FDBLK + fd_skip/FDBLK;
    321  1.1  sakamoto 		cyl = blknum / (sectrac * 2);
    322  1.1  sakamoto 		fdSeek(ctlr, unit, cyl);
    323  1.1  sakamoto 		fdSenseInt(ctlr, stat);
    324  1.1  sakamoto 		if (!(stat[0] & RESULT_SEEK)) {
    325  1.1  sakamoto 			printf("fdc%d: unit:%d seek failed."
    326  1.1  sakamoto 				"status:0x%x cyl:%d pcyl:%d\n",
    327  1.1  sakamoto 				ctlr, unit, stat[0], cyl, stat[1]);
    328  1.1  sakamoto 			goto bad;
    329  1.1  sakamoto 		}
    330  1.1  sakamoto 
    331  1.1  sakamoto 		sec = blknum % (sectrac * 2);
    332  1.1  sakamoto 		head = sec / sectrac;
    333  1.1  sakamoto 		sec = sec % sectrac + 1;
    334  1.1  sakamoto 
    335  1.1  sakamoto 		if (fdReadWrite(un, func, cyl, head, sec, cbuf) == FAIL) {
    336  1.1  sakamoto 			printf("fdc%d: unit%d fdReadWrite error [%s]\n",
    337  1.1  sakamoto 			    ctlr, unit, (func==F_READ?"READ":"WRITE"));
    338  1.1  sakamoto 			goto bad;
    339  1.1  sakamoto 		}
    340  1.1  sakamoto 
    341  1.1  sakamoto 		*rsize += FDBLK;
    342  1.1  sakamoto 		cbuf += FDBLK;
    343  1.1  sakamoto 		fd_skip += FDBLK;
    344  1.1  sakamoto 	}
    345  1.1  sakamoto 	return (SUCCESS);
    346  1.1  sakamoto 
    347  1.1  sakamoto bad:
    348  1.3  sakamoto 	return (FAIL);
    349  1.1  sakamoto }
    350  1.1  sakamoto 
    351  1.1  sakamoto /*===========================================================================*
    352  1.1  sakamoto  *				   fd_check				     *
    353  1.1  sakamoto  *===========================================================================*/
    354  1.1  sakamoto /*
    355  1.1  sakamoto  *	this function is Check floppy disk Type
    356  1.1  sakamoto  */
    357  1.1  sakamoto int
    358  1.1  sakamoto fd_check(un)
    359  1.1  sakamoto 	FD_UNIT	*un;
    360  1.1  sakamoto {
    361  1.1  sakamoto 	int ctlr = un->ctlr;
    362  1.1  sakamoto 	int unit = un->unit;
    363  1.1  sakamoto 	int *stat = un->stat;
    364  1.1  sakamoto 	int type;
    365  1.1  sakamoto 	static u_char sec_buff[SECTOR_MAX];
    366  1.1  sakamoto 
    367  1.1  sakamoto 	un->un_type = (FDDTYPE *)FAIL;
    368  1.1  sakamoto 	for (type = 0; type < FDTYPE_MAX; type++) {
    369  1.1  sakamoto 		un->un_type = &fdd_types[type];
    370  1.1  sakamoto 
    371  1.1  sakamoto 		/* try read start sector */
    372  1.1  sakamoto 		outb(FDC_RATE(ctlr), un->un_type->rate);   /* rate set */
    373  1.1  sakamoto 		fdSpecify(ctlr);
    374  1.1  sakamoto 		fdSeek(ctlr, unit, START_CYL);
    375  1.1  sakamoto 		fdSenseInt(ctlr, stat);
    376  1.1  sakamoto 		if (!(stat[0] & RESULT_SEEK) || stat[1] != START_CYL) {
    377  1.1  sakamoto 			printf("fdc%d: unit:%d seek failed. status:0x%x\n",
    378  1.1  sakamoto 				ctlr, unit, stat[0]);
    379  1.1  sakamoto 			goto bad;
    380  1.1  sakamoto 		}
    381  1.1  sakamoto 		if (fdReadWrite(un, F_READ,
    382  1.1  sakamoto 		    START_CYL, 0, START_SECTOR, sec_buff) == FAIL) {
    383  1.1  sakamoto 			continue;	/* bad disk type */
    384  1.1  sakamoto 		}
    385  1.1  sakamoto 		break;
    386  1.1  sakamoto 	}
    387  1.1  sakamoto 	if (un->un_type == (FDDTYPE *)FAIL) {
    388  1.1  sakamoto 		printf("fdc%d: unit:%d check disk type failed.\n",
    389  1.1  sakamoto 		ctlr, unit);
    390  1.1  sakamoto 		goto bad;
    391  1.1  sakamoto 	}
    392  1.1  sakamoto 	return (SUCCESS);
    393  1.1  sakamoto bad:
    394  1.1  sakamoto 	return (FAIL);
    395  1.1  sakamoto }
    396  1.1  sakamoto 
    397  1.1  sakamoto /*
    398  1.1  sakamoto  * for FDC routines.
    399  1.1  sakamoto  */
    400  1.1  sakamoto /*===========================================================================*
    401  1.1  sakamoto  *				fdc_out					     *
    402  1.1  sakamoto  *===========================================================================*/
    403  1.1  sakamoto int
    404  1.1  sakamoto fdc_out(ctlr, cmd)
    405  1.1  sakamoto 	int ctlr;	/* controller no */
    406  1.1  sakamoto 	int cmd;	/* cmd */
    407  1.1  sakamoto {
    408  1.1  sakamoto 	volatile int status;
    409  1.1  sakamoto 	int time_out;
    410  1.1  sakamoto 
    411  1.1  sakamoto 	time_out = TIMEOUT;
    412  1.1  sakamoto 	while (((status = inb(FDC_STATUS(ctlr))) & (RQM | DIO))
    413  1.1  sakamoto 		!= (RQM | 0) && time_out-- > 0);
    414  1.1  sakamoto 	if (time_out <= 0) {
    415  1.3  sakamoto 		printf("fdc_out: timeout  status = 0x%x\n", status);
    416  1.1  sakamoto 		return (FAIL);
    417  1.1  sakamoto 	}
    418  1.1  sakamoto 
    419  1.1  sakamoto 	outb(FDC_DATA(ctlr), cmd);
    420  1.1  sakamoto 
    421  1.1  sakamoto 	return (SUCCESS);
    422  1.1  sakamoto }
    423  1.1  sakamoto 
    424  1.1  sakamoto /*===========================================================================*
    425  1.1  sakamoto  *				fdc_in					     *
    426  1.1  sakamoto  *===========================================================================*/
    427  1.1  sakamoto int
    428  1.1  sakamoto fdc_in(ctlr, data)
    429  1.1  sakamoto 	int ctlr;	/* controller no */
    430  1.3  sakamoto 	u_char *data;
    431  1.1  sakamoto {
    432  1.1  sakamoto 	volatile int status;
    433  1.1  sakamoto 	int time_out;
    434  1.1  sakamoto 
    435  1.1  sakamoto 	time_out = TIMEOUT;
    436  1.1  sakamoto 	while ((status = inb(FDC_STATUS(ctlr)) & (RQM | DIO))
    437  1.1  sakamoto 	    != (RQM | DIO) && time_out-- > 0) {
    438  1.1  sakamoto 		if (status == RQM) {
    439  1.1  sakamoto 			printf("fdc_in:error:ready for output\n");
    440  1.1  sakamoto 			return (FAIL);
    441  1.1  sakamoto 		}
    442  1.1  sakamoto 	}
    443  1.1  sakamoto 
    444  1.1  sakamoto 	if (time_out <= 0) {
    445  1.1  sakamoto 		printf("fdc_in:input ready timeout\n");
    446  1.1  sakamoto 		return (FAIL);
    447  1.1  sakamoto 	}
    448  1.1  sakamoto 
    449  1.3  sakamoto 	if (data) *data = (u_char)inb(FDC_DATA(ctlr));
    450  1.1  sakamoto 
    451  1.1  sakamoto 	return (SUCCESS);
    452  1.1  sakamoto }
    453  1.1  sakamoto 
    454  1.1  sakamoto /*===========================================================================*
    455  1.1  sakamoto  *                              fdc_intr_wait                                *
    456  1.1  sakamoto  *===========================================================================*/
    457  1.1  sakamoto int
    458  1.1  sakamoto fdc_intr_wait()
    459  1.1  sakamoto {
    460  1.3  sakamoto 	return (irq_polling(FDC_IRQ, INT_TIMEOUT));	/* wait interrupt */
    461  1.1  sakamoto }
    462  1.1  sakamoto 
    463  1.1  sakamoto /*===========================================================================*
    464  1.1  sakamoto  *		   	     fdc command function	 	    	     *
    465  1.1  sakamoto  *===========================================================================*/
    466  1.1  sakamoto void
    467  1.1  sakamoto motor_on(ctlr, unit)
    468  1.1  sakamoto 	int ctlr;
    469  1.1  sakamoto 	int unit;
    470  1.1  sakamoto {
    471  1.1  sakamoto 	outb(FDC_DOR(ctlr), DOR_RESET | DOR_DMAEN | unit
    472  1.1  sakamoto 		| (1 << (unit + 4)));	/* reset & unit motor on */
    473  1.1  sakamoto 	DELAY(1);		/* wait 100msec */
    474  1.1  sakamoto }
    475  1.1  sakamoto 
    476  1.1  sakamoto void
    477  1.1  sakamoto motor_off(ctlr, unit)
    478  1.1  sakamoto 	int ctlr;
    479  1.1  sakamoto 	int unit;
    480  1.1  sakamoto {
    481  1.3  sakamoto         outb(FDC_DOR(ctlr), DOR_RESET);		/* reset & motor off */
    482  1.3  sakamoto 	if (fdc_intr_wait() == FAIL)		/* wait interrupt */
    483  1.1  sakamoto 		printf("fdc: motor off failed.\n");
    484  1.1  sakamoto }
    485  1.1  sakamoto 
    486  1.1  sakamoto void
    487  1.1  sakamoto fdReset(ctlr)
    488  1.1  sakamoto {
    489  1.1  sakamoto 	outb(FDC_DOR(ctlr), 0); /* fdc reset */
    490  1.1  sakamoto 	DELAY(3);
    491  1.1  sakamoto 	outb(FDC_DOR(ctlr), DOR_RESET);
    492  1.1  sakamoto 	DELAY(8);
    493  1.1  sakamoto }
    494  1.1  sakamoto 
    495  1.1  sakamoto void
    496  1.1  sakamoto fdRecalibrate(ctlr, unit)
    497  1.1  sakamoto 	int ctlr;
    498  1.1  sakamoto 	int unit;
    499  1.1  sakamoto {
    500  1.1  sakamoto 	fdc_out(ctlr, CMD_RECALIBRATE);
    501  1.1  sakamoto 	fdc_out(ctlr, unit);
    502  1.1  sakamoto 
    503  1.1  sakamoto 	if (fdc_intr_wait() == FAIL)   /* wait interrupt */
    504  1.1  sakamoto 		printf("fdc: recalibrate Timeout\n");
    505  1.1  sakamoto }
    506  1.1  sakamoto 
    507  1.1  sakamoto void
    508  1.1  sakamoto fdSpecify(ctlr)
    509  1.1  sakamoto 	int	ctlr;
    510  1.1  sakamoto {
    511  1.1  sakamoto 	fdc_out(ctlr, CMD_SPECIFY);
    512  1.1  sakamoto 	fdc_out(ctlr, SPECIFY1);
    513  1.1  sakamoto 	fdc_out(ctlr, SPECIFY2);
    514  1.1  sakamoto }
    515  1.1  sakamoto 
    516  1.1  sakamoto void
    517  1.1  sakamoto fdDriveStatus(ctlr, unit, head, stat)
    518  1.1  sakamoto 	int	ctlr;
    519  1.1  sakamoto 	register int	unit, head;
    520  1.1  sakamoto 	register int	*stat;
    521  1.1  sakamoto {
    522  1.3  sakamoto 	u_char result;
    523  1.1  sakamoto 
    524  1.1  sakamoto 	fdc_out(ctlr, CMD_DRV_SENSE);
    525  1.1  sakamoto 	fdc_out(ctlr, (head << 2) | unit);
    526  1.1  sakamoto 	fdc_in(ctlr, &result);
    527  1.1  sakamoto 	*stat = (int)(result & 0xff);
    528  1.1  sakamoto }
    529  1.1  sakamoto 
    530  1.1  sakamoto int
    531  1.1  sakamoto fdSeek(ctlr, unit, cyl)
    532  1.1  sakamoto 	int ctlr;
    533  1.1  sakamoto 	int unit;
    534  1.1  sakamoto 	int cyl;
    535  1.1  sakamoto {
    536  1.1  sakamoto 	int ret_val = 0;
    537  1.1  sakamoto 
    538  1.1  sakamoto 	fdc_out(ctlr, CMD_SEEK);
    539  1.1  sakamoto 	fdc_out(ctlr, unit);
    540  1.1  sakamoto 	fdc_out(ctlr, cyl);
    541  1.1  sakamoto 
    542  1.3  sakamoto         if (fdc_intr_wait() == FAIL) {		/* wait interrupt */
    543  1.1  sakamoto 		printf("fdc: fdSeek Timeout\n");
    544  1.1  sakamoto 		ret_val = FAIL;
    545  1.1  sakamoto 	}
    546  1.1  sakamoto 
    547  1.1  sakamoto 	return(ret_val);
    548  1.1  sakamoto }
    549  1.1  sakamoto 
    550  1.1  sakamoto int
    551  1.1  sakamoto fdSenseInt(ctlr, stat)
    552  1.1  sakamoto 	int ctlr;
    553  1.1  sakamoto 	int *stat;
    554  1.1  sakamoto {
    555  1.3  sakamoto 	u_char result;
    556  1.1  sakamoto 
    557  1.1  sakamoto 	fdc_out(ctlr, CMD_SENSE_INT);
    558  1.1  sakamoto 
    559  1.1  sakamoto 	fdc_in(ctlr, &result);
    560  1.1  sakamoto 	*stat++ = (int)(result & 0xff);
    561  1.1  sakamoto 	fdc_in(ctlr, &result);
    562  1.1  sakamoto 	*stat++ = (int)(result & 0xff);
    563  1.1  sakamoto 
    564  1.3  sakamoto 	return (0);
    565  1.1  sakamoto }
    566  1.1  sakamoto 
    567  1.1  sakamoto int
    568  1.1  sakamoto fdReadWrite(un, func, cyl, head, sec, adrs)
    569  1.1  sakamoto 	FD_UNIT	*un;
    570  1.1  sakamoto 	int func;
    571  1.1  sakamoto 	int cyl;
    572  1.1  sakamoto 	int head;
    573  1.1  sakamoto 	int sec;
    574  1.1  sakamoto 	u_char *adrs;
    575  1.1  sakamoto {
    576  1.1  sakamoto 	int i;
    577  1.1  sakamoto 	int ctlr = un->ctlr;
    578  1.1  sakamoto 	int unit = un->unit;
    579  1.1  sakamoto 	int *stat = un->stat;
    580  1.3  sakamoto 	u_char result;
    581  1.1  sakamoto 
    582  1.1  sakamoto #if 0
    583  1.1  sakamoto printf("%s:", (func == F_READ ? "READ" : "WRITE"));
    584  1.1  sakamoto printf("cyl = %d", cyl);
    585  1.1  sakamoto printf("head = %d", head);
    586  1.1  sakamoto printf("sec = %d", sec);
    587  1.1  sakamoto printf("secsize = %d", un->un_type->secsize);
    588  1.1  sakamoto printf("seccount = %d", un->un_type->seccount);
    589  1.1  sakamoto printf("gap = %d", un->un_type->gap);
    590  1.1  sakamoto printf("datalen = %d\n", un->un_type->datalen);
    591  1.1  sakamoto #endif
    592  1.1  sakamoto 
    593  1.1  sakamoto 	dma_setup(adrs, FDBLK, func, FD_DMA_CHAN);
    594  1.1  sakamoto 	fdc_out(ctlr, (func == F_READ ? CMD_READ : CMD_WRITE));
    595  1.1  sakamoto 	fdc_out(ctlr, (head<<2) | unit);
    596  1.1  sakamoto 	fdc_out(ctlr, cyl);			/* cyl */
    597  1.1  sakamoto 	fdc_out(ctlr, head);			/* head */
    598  1.1  sakamoto 	fdc_out(ctlr, sec);			/* sec */
    599  1.1  sakamoto 	fdc_out(ctlr, un->un_type->secsize);	/* secsize */
    600  1.1  sakamoto 	fdc_out(ctlr, un->un_type->seccount);	/* EOT (end of track) */
    601  1.1  sakamoto 	fdc_out(ctlr, un->un_type->gap);	/* GAP3 */
    602  1.1  sakamoto 	fdc_out(ctlr, un->un_type->datalen);	/* DTL (data length) */
    603  1.1  sakamoto 
    604  1.1  sakamoto 	if (fdc_intr_wait() == FAIL) {  /* wait interrupt */
    605  1.1  sakamoto 		printf("fdc: DMA transfer Timeout\n");
    606  1.1  sakamoto 		return (FAIL);
    607  1.1  sakamoto 	}
    608  1.1  sakamoto 
    609  1.1  sakamoto 	for (i = 0; i < 7; i++) {
    610  1.1  sakamoto 		fdc_in(ctlr, &result);
    611  1.1  sakamoto 		stat[i] = (int)(result & 0xff);
    612  1.1  sakamoto 	}
    613  1.1  sakamoto 	if (stat[0] & ST0_IC_MASK) {	/* not normal terminate */
    614  1.1  sakamoto 		if ((stat[1] & ~ST1_EN) || stat[2])
    615  1.1  sakamoto 		goto bad;
    616  1.1  sakamoto 	}
    617  1.1  sakamoto 	if (!dma_finished(FD_DMA_CHAN)) {
    618  1.1  sakamoto 		printf("DMA not finished\n");
    619  1.1  sakamoto 		goto bad;
    620  1.1  sakamoto 	}
    621  1.1  sakamoto 	return (SUCCESS);
    622  1.1  sakamoto 
    623  1.1  sakamoto bad:
    624  1.1  sakamoto 	printf("       func: %s\n", (func == F_READ ? "F_READ" : "F_WRITE"));
    625  1.1  sakamoto 	printf("	st0 = 0x%x\n", stat[0]);
    626  1.1  sakamoto 	printf("	st1 = 0x%x\n", stat[1]);
    627  1.1  sakamoto 	printf("	st2 = 0x%x\n", stat[2]);
    628  1.1  sakamoto 	printf("	  c = 0x%x\n", stat[3]);
    629  1.1  sakamoto 	printf("	  h = 0x%x\n", stat[4]);
    630  1.1  sakamoto 	printf("	  r = 0x%x\n", stat[5]);
    631  1.1  sakamoto 	printf("	  n = 0x%x\n", stat[6]);
    632  1.1  sakamoto 	return (FAIL);
    633  1.1  sakamoto }
    634  1.1  sakamoto 
    635  1.1  sakamoto /*-----------------------------------------------------------------------
    636  1.1  sakamoto  * Interrupt Controller Operation Functions
    637  1.1  sakamoto  *-----------------------------------------------------------------------
    638  1.1  sakamoto  */
    639  1.1  sakamoto 
    640  1.1  sakamoto /* 8259A interrupt controller register */
    641  1.3  sakamoto #define	INT_CTL0	0x20
    642  1.3  sakamoto #define	INT_CTL1	0x21
    643  1.3  sakamoto #define	INT2_CTL0	0xA0
    644  1.3  sakamoto #define	INT2_CTL1	0xA1
    645  1.1  sakamoto 
    646  1.1  sakamoto #define	CASCADE_IRQ	2
    647  1.1  sakamoto 
    648  1.3  sakamoto #define	ICW1_AT		0x11    /* edge triggered, cascade, need ICW4 */
    649  1.3  sakamoto #define	ICW4_AT		0x01    /* not SFNM, not buffered, normal EOI, 8086 */
    650  1.1  sakamoto #define	OCW3_PL		0x0e	/* polling mode */
    651  1.1  sakamoto #define	OCW2_CLEAR	0x20	/* interrupt clear */
    652  1.1  sakamoto 
    653  1.1  sakamoto /*
    654  1.3  sakamoto  * IRC programing sequence
    655  1.1  sakamoto  *
    656  1.1  sakamoto  * after reset
    657  1.1  sakamoto  * 1.	ICW1 (write port:INT_CTL0 data:bit4=1)
    658  1.1  sakamoto  * 2.	ICW2 (write port:INT_CTL1)
    659  1.1  sakamoto  * 3.	ICW3 (write port:INT_CTL1)
    660  1.1  sakamoto  * 4.	ICW4 (write port:INT_CTL1)
    661  1.3  sakamoto  *
    662  1.1  sakamoto  * after ICW
    663  1.1  sakamoto  *	OCW1 (write port:INT_CTL1)
    664  1.1  sakamoto  *	OCW2 (write port:INT_CTL0 data:bit3=0,bit4=0)
    665  1.1  sakamoto  *	OCW3 (write port:INT_CTL0 data:bit3=1,bit4=0)
    666  1.1  sakamoto  *
    667  1.1  sakamoto  *	IMR  (read port:INT_CTL1)
    668  1.1  sakamoto  *	IRR  (read port:INT_CTL0)	OCW3(bit1=1,bit0=0)
    669  1.1  sakamoto  *	ISR  (read port:INT_CTL0)	OCW3(bit1=1,bit0=1)
    670  1.1  sakamoto  *	PL   (read port:INT_CTL0)	OCW3(bit2=1,bit1=1)
    671  1.1  sakamoto  */
    672  1.1  sakamoto 
    673  1.3  sakamoto u_int INT_MASK;
    674  1.3  sakamoto u_int INT2_MASK;
    675  1.1  sakamoto 
    676  1.1  sakamoto /*===========================================================================*
    677  1.1  sakamoto  *                             irq initialize                                *
    678  1.1  sakamoto  *===========================================================================*/
    679  1.3  sakamoto void
    680  1.1  sakamoto irq_init()
    681  1.1  sakamoto {
    682  1.1  sakamoto 	outb(INT_CTL0, ICW1_AT);		/* ICW1 */
    683  1.1  sakamoto 	outb(INT_CTL1, 0);			/* ICW2 for master */
    684  1.1  sakamoto 	outb(INT_CTL1, (1 << CASCADE_IRQ));	/* ICW3 tells slaves */
    685  1.1  sakamoto 	outb(INT_CTL1, ICW4_AT);		/* ICW4 */
    686  1.1  sakamoto 
    687  1.1  sakamoto 	outb(INT_CTL1, (INT_MASK = ~(1 << CASCADE_IRQ)));
    688  1.1  sakamoto 				/* IRQ mask(exclusive of cascade) */
    689  1.1  sakamoto 
    690  1.1  sakamoto 	outb(INT2_CTL0, ICW1_AT);		/* ICW1 */
    691  1.1  sakamoto 	outb(INT2_CTL1, 8); 			/* ICW2 for slave */
    692  1.1  sakamoto 	outb(INT2_CTL1, CASCADE_IRQ);		/* ICW3 is slave nr */
    693  1.1  sakamoto 	outb(INT2_CTL1, ICW4_AT);		/* ICW4 */
    694  1.1  sakamoto 
    695  1.1  sakamoto 	outb(INT2_CTL1, (INT2_MASK = ~0));	/* IRQ 8-15 mask */
    696  1.1  sakamoto }
    697  1.1  sakamoto 
    698  1.1  sakamoto /*===========================================================================*
    699  1.1  sakamoto  *                           irq polling check                               *
    700  1.1  sakamoto  *===========================================================================*/
    701  1.3  sakamoto int
    702  1.1  sakamoto irq_polling(irq_no, timeout)
    703  1.1  sakamoto 	int	irq_no;
    704  1.1  sakamoto 	int	timeout;
    705  1.1  sakamoto {
    706  1.1  sakamoto 	int	irc_no;
    707  1.1  sakamoto 	int	data;
    708  1.1  sakamoto 	int	ret;
    709  1.1  sakamoto 
    710  1.1  sakamoto 	if (irq_no > 8) irc_no = 1;
    711  1.1  sakamoto 		else irc_no = 0;
    712  1.1  sakamoto 
    713  1.1  sakamoto 	outb(irc_no ? INT2_CTL1 : INT_CTL1, ~(1 << (irq_no >> (irc_no * 3))));
    714  1.1  sakamoto 
    715  1.3  sakamoto 	while (--timeout > 0) {
    716  1.1  sakamoto 		outb(irc_no ? INT2_CTL0 : INT_CTL0, OCW3_PL);
    717  1.1  sakamoto 						/* set polling mode */
    718  1.1  sakamoto 		data = inb(irc_no ? INT2_CTL0 : INT_CTL0);
    719  1.1  sakamoto 		if (data & 0x80) {	/* if interrupt request */
    720  1.1  sakamoto 			if ((irq_no >> (irc_no * 3)) == (data & 0x7)) {
    721  1.1  sakamoto 				ret = SUCCESS;
    722  1.1  sakamoto 				break;
    723  1.1  sakamoto 			}
    724  1.1  sakamoto 		}
    725  1.1  sakamoto 	}
    726  1.1  sakamoto 	if (!timeout) ret = FAIL;
    727  1.1  sakamoto 
    728  1.1  sakamoto 	if (irc_no) {				/* interrupt clear */
    729  1.1  sakamoto 		outb(INT2_CTL0, OCW2_CLEAR | (irq_no >> 3));
    730  1.1  sakamoto 		outb(INT_CTL0, OCW2_CLEAR | CASCADE_IRQ);
    731  1.1  sakamoto 	} else {
    732  1.1  sakamoto 		outb(INT_CTL0, OCW2_CLEAR | irq_no);
    733  1.1  sakamoto 	}
    734  1.1  sakamoto 
    735  1.1  sakamoto 	outb(INT_CTL1, INT_MASK);
    736  1.1  sakamoto 	outb(INT2_CTL1, INT2_MASK);
    737  1.1  sakamoto 
    738  1.1  sakamoto 	return (ret);
    739  1.1  sakamoto }
    740  1.1  sakamoto 
    741  1.1  sakamoto /*---------------------------------------------------------------------------*
    742  1.1  sakamoto  *			DMA Controller Define			 	     *
    743  1.1  sakamoto  *---------------------------------------------------------------------------*/
    744  1.1  sakamoto /* DMA Controller Registers */
    745  1.3  sakamoto #define	DMA_ADDR	0x004    /* port for low 16 bits of DMA address */
    746  1.3  sakamoto #define	DMA_LTOP	0x081    /* port for top low 8bit DMA addr(ch2) */
    747  1.3  sakamoto #define	DMA_HTOP	0x481    /* port for top high 8bit DMA addr(ch2) */
    748  1.3  sakamoto #define	DMA_COUNT	0x005    /* port for DMA count (count =  bytes - 1) */
    749  1.1  sakamoto #define	DMA_DEVCON	0x008    /* DMA device control register */
    750  1.1  sakamoto #define	DMA_SR		0x008    /* DMA status register */
    751  1.1  sakamoto #define	DMA_RESET	0x00D    /* DMA software reset register */
    752  1.3  sakamoto #define	DMA_FLIPFLOP	0x00C    /* DMA byte pointer flip-flop */
    753  1.3  sakamoto #define	DMA_MODE	0x00B    /* DMA mode port */
    754  1.3  sakamoto #define	DMA_INIT	0x00A    /* DMA init port */
    755  1.1  sakamoto 
    756  1.3  sakamoto #define	DMA_RESET_VAL	0x06
    757  1.1  sakamoto /* DMA channel commands. */
    758  1.3  sakamoto #define	DMA_READ	0x46    /* DMA read opcode */
    759  1.3  sakamoto #define	DMA_WRITE	0x4A    /* DMA write opcode */
    760  1.1  sakamoto 
    761  1.1  sakamoto /*===========================================================================*
    762  1.1  sakamoto  *				dma_setup				     *
    763  1.1  sakamoto  *===========================================================================*/
    764  1.3  sakamoto void
    765  1.1  sakamoto dma_setup(buf, size, func, chan)
    766  1.3  sakamoto 	u_char *buf;
    767  1.1  sakamoto 	int size;
    768  1.1  sakamoto 	int func;
    769  1.1  sakamoto 	int chan;
    770  1.1  sakamoto {
    771  1.3  sakamoto 	u_long pbuf = local_to_PCI((u_long)buf);
    772  1.1  sakamoto 
    773  1.1  sakamoto #if 0
    774  1.1  sakamoto 	outb(DMA_RESET, 0);
    775  1.1  sakamoto 	DELAY(1);
    776  1.1  sakamoto 	outb(DMA_DEVCON, 0x00);
    777  1.3  sakamoto 	outb(DMA_INIT, DMA_RESET_VAL);	/* reset the dma controller */
    778  1.1  sakamoto #endif
    779  1.1  sakamoto 	outb(DMA_MODE, func == F_READ ? DMA_READ : DMA_WRITE);
    780  1.3  sakamoto 	outb(DMA_FLIPFLOP, 0);		/* write anything to reset it */
    781  1.1  sakamoto 
    782  1.1  sakamoto 	outb(DMA_ADDR, (int)pbuf >>  0);
    783  1.1  sakamoto 	outb(DMA_ADDR, (int)pbuf >>  8);
    784  1.1  sakamoto 	outb(DMA_LTOP, (int)pbuf >> 16);
    785  1.1  sakamoto 	outb(DMA_HTOP, (int)pbuf >> 24);
    786  1.1  sakamoto 
    787  1.1  sakamoto 	outb(DMA_COUNT, (size - 1) >> 0);
    788  1.1  sakamoto 	outb(DMA_COUNT, (size - 1) >> 8);
    789  1.3  sakamoto 	outb(DMA_INIT, chan);		/* some sort of enable */
    790  1.1  sakamoto }
    791  1.1  sakamoto 
    792  1.1  sakamoto int
    793  1.1  sakamoto dma_finished(chan)
    794  1.1  sakamoto 	int chan;
    795  1.1  sakamoto {
    796  1.1  sakamoto 	return ((inb(DMA_SR) & 0x0f) == (1 << chan));
    797  1.1  sakamoto }
    798