Home | History | Annotate | Line # | Download | only in boot
fd.c revision 1.9
      1  1.9    cegger /*	$NetBSD: fd.c,v 1.9 2009/03/18 10:22:27 cegger Exp $	*/
      2  1.1  sakamoto 
      3  1.1  sakamoto /*-
      4  1.5    keihan  * 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.6  junyoung #include <lib/libsa/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.8  kiyohara int fdinit(FD_UNIT *);
    167  1.8  kiyohara int fdopen(struct open_file *, int, int, int);
    168  1.8  kiyohara int fdclose(struct open_file *);
    169  1.8  kiyohara int fdioctl(struct open_file *, u_long, void *);
    170  1.8  kiyohara int fdstrategy(void *, int, daddr_t, size_t, void *, size_t *);
    171  1.8  kiyohara int fdc_out(int, int);
    172  1.8  kiyohara int fdc_in(int, u_char *);
    173  1.8  kiyohara int fdc_intr_wait(void);
    174  1.8  kiyohara int fd_check(FD_UNIT *);
    175  1.8  kiyohara void motor_on(int, int);
    176  1.8  kiyohara void motor_off(int, int);
    177  1.8  kiyohara void fdReset(int);
    178  1.8  kiyohara void fdRecalibrate(int, int);
    179  1.8  kiyohara void fdSpecify(int);
    180  1.8  kiyohara void fdDriveStatus(int, int, int, int *);
    181  1.8  kiyohara int fdSeek(int, int, int);
    182  1.8  kiyohara int fdSenseInt(int, int *);
    183  1.8  kiyohara int fdReadWrite(FD_UNIT *, int, int, int, int, u_char *);
    184  1.8  kiyohara void irq_init(void);
    185  1.8  kiyohara int irq_polling(int, int);
    186  1.8  kiyohara void dma_setup(u_char *, int, int, int);
    187  1.8  kiyohara int dma_finished(int);
    188  1.1  sakamoto 
    189  1.1  sakamoto /*===========================================================================*
    190  1.1  sakamoto  *				   fdinit				     *
    191  1.1  sakamoto  *===========================================================================*/
    192  1.3  sakamoto int
    193  1.8  kiyohara fdinit(FD_UNIT *un)
    194  1.1  sakamoto {
    195  1.1  sakamoto 	int ctlr = un->ctlr;
    196  1.3  sakamoto 	u_char result;
    197  1.1  sakamoto 
    198  1.1  sakamoto #if 0
    199  1.1  sakamoto 	irq_init();
    200  1.4    simonb #endif
    201  1.1  sakamoto 	fdReset(ctlr);
    202  1.3  sakamoto 
    203  1.1  sakamoto 	if (fdc_out(ctlr, CMD_VERSION) != SUCCESS) {  /* version check */
    204  1.3  sakamoto 		printf ("fdc%d:fatal error: CMD_VERSION cmd fail\n", ctlr);
    205  1.1  sakamoto 		return (FAIL);
    206  1.1  sakamoto 	}
    207  1.1  sakamoto 	if (fdc_in(ctlr, &result) != SUCCESS) {
    208  1.3  sakamoto 		printf ("fdc%d:fatal error: CMD_VERSION exec fail\n", ctlr);
    209  1.1  sakamoto 		return (FAIL);
    210  1.1  sakamoto 	}
    211  1.3  sakamoto 	if (result != (u_char)RESULT_VERSION) {
    212  1.3  sakamoto 		printf ("fdc%d:fatal error: unknown version fdc\n", ctlr);
    213  1.1  sakamoto 		return (FAIL);
    214  1.1  sakamoto 	}
    215  1.1  sakamoto 
    216  1.1  sakamoto 	un->un_flags = INT_ALIVE;
    217  1.1  sakamoto 	return (SUCCESS);
    218  1.1  sakamoto }
    219  1.1  sakamoto 
    220  1.1  sakamoto /*===========================================================================*
    221  1.1  sakamoto  *				   fdopen				     *
    222  1.1  sakamoto  *===========================================================================*/
    223  1.3  sakamoto int
    224  1.8  kiyohara fdopen(struct open_file *f, int ctlr, int unit, int part)
    225  1.1  sakamoto {
    226  1.1  sakamoto 	FD_UNIT	*un;
    227  1.8  kiyohara 	int *stat;
    228  1.1  sakamoto 
    229  1.1  sakamoto 	if (ctlr >= CTLR_MAX)
    230  1.1  sakamoto 		return (ENXIO);
    231  1.1  sakamoto 	if (unit >= UNIT_MAX)
    232  1.1  sakamoto 		return (ENXIO);
    233  1.1  sakamoto 	un = &fd_unit[ctlr][unit];
    234  1.8  kiyohara 	stat = un->stat;
    235  1.1  sakamoto 
    236  1.1  sakamoto 	if (!(un->un_flags & INT_ALIVE)) {
    237  1.1  sakamoto 		if (fdinit(un) != SUCCESS)
    238  1.1  sakamoto 			return (ENXIO);
    239  1.1  sakamoto 	}
    240  1.1  sakamoto 
    241  1.1  sakamoto 	motor_on(ctlr, unit);
    242  1.1  sakamoto 
    243  1.1  sakamoto 	fdRecalibrate(ctlr, unit);
    244  1.1  sakamoto 	fdSenseInt(ctlr, stat);
    245  1.1  sakamoto 	if (stat[1] != START_CYL) {
    246  1.1  sakamoto 		printf("fdc%d: unit:%d recalibrate failed. status:0x%x cyl:%d\n",
    247  1.1  sakamoto 			ctlr, unit, stat[0], stat[1]);
    248  1.1  sakamoto 		motor_off(ctlr, unit);
    249  1.1  sakamoto 		return (EIO);
    250  1.1  sakamoto 	}
    251  1.1  sakamoto 
    252  1.1  sakamoto 	if (fd_check(un) != SUCCESS)	/* research disk type */
    253  1.1  sakamoto 		return (EIO);
    254  1.1  sakamoto 
    255  1.1  sakamoto 	f->f_devdata = (void *)un;
    256  1.1  sakamoto 	return (SUCCESS);
    257  1.1  sakamoto }
    258  1.1  sakamoto 
    259  1.1  sakamoto /*===========================================================================*
    260  1.1  sakamoto  *				   fdclose				     *
    261  1.1  sakamoto  *===========================================================================*/
    262  1.3  sakamoto int
    263  1.8  kiyohara fdclose(struct open_file *f)
    264  1.1  sakamoto {
    265  1.1  sakamoto 	FD_UNIT *un = f->f_devdata;
    266  1.1  sakamoto 
    267  1.1  sakamoto 	fdRecalibrate(un->ctlr, un->unit);
    268  1.1  sakamoto 	fdSenseInt(un->ctlr, un->stat);
    269  1.1  sakamoto 	motor_off(un->ctlr, un->unit);
    270  1.1  sakamoto 	un->un_flags = 0;
    271  1.1  sakamoto 	return (SUCCESS);
    272  1.1  sakamoto }
    273  1.1  sakamoto 
    274  1.1  sakamoto /*===========================================================================*
    275  1.1  sakamoto  *				   fdioctl				     *
    276  1.1  sakamoto  *===========================================================================*/
    277  1.3  sakamoto int
    278  1.8  kiyohara fdioctl(struct open_file *f, u_long cmd, void *arg)
    279  1.1  sakamoto {
    280  1.8  kiyohara 
    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.8  kiyohara fdstrategy(void *devdata, int func, daddr_t blk, size_t size, void *buf,
    294  1.8  kiyohara 	   size_t *rsize)
    295  1.1  sakamoto {
    296  1.1  sakamoto 	int sectrac, cyl, head, sec;
    297  1.1  sakamoto 	FD_UNIT *un = devdata;
    298  1.1  sakamoto 	int ctlr = un->ctlr;
    299  1.1  sakamoto 	int unit = un->unit;
    300  1.1  sakamoto 	int *stat = un->stat;
    301  1.1  sakamoto 	long nblock, blknum;
    302  1.1  sakamoto 	int fd_skip = 0;
    303  1.8  kiyohara 	u_char *cbuf = (u_char *)buf;
    304  1.1  sakamoto 
    305  1.3  sakamoto 	if (un->un_flags & INT_BUSY) {
    306  1.1  sakamoto 		return (ENXIO);
    307  1.1  sakamoto 	}
    308  1.1  sakamoto 	fdDriveStatus(ctlr, unit, 0, stat);
    309  1.1  sakamoto 
    310  1.1  sakamoto 	nblock = un->un_type->maxseccount;
    311  1.1  sakamoto 	sectrac = un->un_type->seccount;	/* sector per track */
    312  1.1  sakamoto 	*rsize = 0;
    313  1.1  sakamoto 
    314  1.1  sakamoto 	while (fd_skip < size) {
    315  1.1  sakamoto 		blknum = (u_long)blk * DEV_BSIZE/FDBLK + fd_skip/FDBLK;
    316  1.1  sakamoto 		cyl = blknum / (sectrac * 2);
    317  1.1  sakamoto 		fdSeek(ctlr, unit, cyl);
    318  1.1  sakamoto 		fdSenseInt(ctlr, stat);
    319  1.1  sakamoto 		if (!(stat[0] & RESULT_SEEK)) {
    320  1.1  sakamoto 			printf("fdc%d: unit:%d seek failed."
    321  1.1  sakamoto 				"status:0x%x cyl:%d pcyl:%d\n",
    322  1.1  sakamoto 				ctlr, unit, stat[0], cyl, stat[1]);
    323  1.1  sakamoto 			goto bad;
    324  1.1  sakamoto 		}
    325  1.1  sakamoto 
    326  1.1  sakamoto 		sec = blknum % (sectrac * 2);
    327  1.1  sakamoto 		head = sec / sectrac;
    328  1.1  sakamoto 		sec = sec % sectrac + 1;
    329  1.1  sakamoto 
    330  1.1  sakamoto 		if (fdReadWrite(un, func, cyl, head, sec, cbuf) == FAIL) {
    331  1.1  sakamoto 			printf("fdc%d: unit%d fdReadWrite error [%s]\n",
    332  1.1  sakamoto 			    ctlr, unit, (func==F_READ?"READ":"WRITE"));
    333  1.1  sakamoto 			goto bad;
    334  1.1  sakamoto 		}
    335  1.1  sakamoto 
    336  1.1  sakamoto 		*rsize += FDBLK;
    337  1.1  sakamoto 		cbuf += FDBLK;
    338  1.1  sakamoto 		fd_skip += FDBLK;
    339  1.1  sakamoto 	}
    340  1.1  sakamoto 	return (SUCCESS);
    341  1.1  sakamoto 
    342  1.1  sakamoto bad:
    343  1.3  sakamoto 	return (FAIL);
    344  1.1  sakamoto }
    345  1.1  sakamoto 
    346  1.1  sakamoto /*===========================================================================*
    347  1.1  sakamoto  *				   fd_check				     *
    348  1.1  sakamoto  *===========================================================================*/
    349  1.1  sakamoto /*
    350  1.1  sakamoto  *	this function is Check floppy disk Type
    351  1.1  sakamoto  */
    352  1.1  sakamoto int
    353  1.8  kiyohara fd_check(FD_UNIT *un)
    354  1.1  sakamoto {
    355  1.1  sakamoto 	int ctlr = un->ctlr;
    356  1.1  sakamoto 	int unit = un->unit;
    357  1.1  sakamoto 	int *stat = un->stat;
    358  1.1  sakamoto 	int type;
    359  1.1  sakamoto 	static u_char sec_buff[SECTOR_MAX];
    360  1.1  sakamoto 
    361  1.1  sakamoto 	un->un_type = (FDDTYPE *)FAIL;
    362  1.1  sakamoto 	for (type = 0; type < FDTYPE_MAX; type++) {
    363  1.1  sakamoto 		un->un_type = &fdd_types[type];
    364  1.1  sakamoto 
    365  1.1  sakamoto 		/* try read start sector */
    366  1.1  sakamoto 		outb(FDC_RATE(ctlr), un->un_type->rate);   /* rate set */
    367  1.1  sakamoto 		fdSpecify(ctlr);
    368  1.1  sakamoto 		fdSeek(ctlr, unit, START_CYL);
    369  1.1  sakamoto 		fdSenseInt(ctlr, stat);
    370  1.1  sakamoto 		if (!(stat[0] & RESULT_SEEK) || stat[1] != START_CYL) {
    371  1.1  sakamoto 			printf("fdc%d: unit:%d seek failed. status:0x%x\n",
    372  1.1  sakamoto 				ctlr, unit, stat[0]);
    373  1.1  sakamoto 			goto bad;
    374  1.1  sakamoto 		}
    375  1.1  sakamoto 		if (fdReadWrite(un, F_READ,
    376  1.1  sakamoto 		    START_CYL, 0, START_SECTOR, sec_buff) == FAIL) {
    377  1.1  sakamoto 			continue;	/* bad disk type */
    378  1.1  sakamoto 		}
    379  1.1  sakamoto 		break;
    380  1.1  sakamoto 	}
    381  1.1  sakamoto 	if (un->un_type == (FDDTYPE *)FAIL) {
    382  1.1  sakamoto 		printf("fdc%d: unit:%d check disk type failed.\n",
    383  1.1  sakamoto 		ctlr, unit);
    384  1.1  sakamoto 		goto bad;
    385  1.1  sakamoto 	}
    386  1.1  sakamoto 	return (SUCCESS);
    387  1.1  sakamoto bad:
    388  1.1  sakamoto 	return (FAIL);
    389  1.1  sakamoto }
    390  1.1  sakamoto 
    391  1.1  sakamoto /*
    392  1.1  sakamoto  * for FDC routines.
    393  1.1  sakamoto  */
    394  1.1  sakamoto /*===========================================================================*
    395  1.1  sakamoto  *				fdc_out					     *
    396  1.1  sakamoto  *===========================================================================*/
    397  1.1  sakamoto int
    398  1.8  kiyohara fdc_out(int ctlr, int cmd)
    399  1.1  sakamoto {
    400  1.1  sakamoto 	volatile int status;
    401  1.1  sakamoto 	int time_out;
    402  1.1  sakamoto 
    403  1.1  sakamoto 	time_out = TIMEOUT;
    404  1.1  sakamoto 	while (((status = inb(FDC_STATUS(ctlr))) & (RQM | DIO))
    405  1.1  sakamoto 		!= (RQM | 0) && time_out-- > 0);
    406  1.1  sakamoto 	if (time_out <= 0) {
    407  1.3  sakamoto 		printf("fdc_out: timeout  status = 0x%x\n", status);
    408  1.1  sakamoto 		return (FAIL);
    409  1.1  sakamoto 	}
    410  1.1  sakamoto 
    411  1.1  sakamoto 	outb(FDC_DATA(ctlr), cmd);
    412  1.1  sakamoto 
    413  1.1  sakamoto 	return (SUCCESS);
    414  1.1  sakamoto }
    415  1.1  sakamoto 
    416  1.1  sakamoto /*===========================================================================*
    417  1.1  sakamoto  *				fdc_in					     *
    418  1.1  sakamoto  *===========================================================================*/
    419  1.1  sakamoto int
    420  1.8  kiyohara fdc_in(int ctlr, u_char *data)
    421  1.1  sakamoto {
    422  1.1  sakamoto 	volatile int status;
    423  1.1  sakamoto 	int time_out;
    424  1.1  sakamoto 
    425  1.1  sakamoto 	time_out = TIMEOUT;
    426  1.1  sakamoto 	while ((status = inb(FDC_STATUS(ctlr)) & (RQM | DIO))
    427  1.1  sakamoto 	    != (RQM | DIO) && time_out-- > 0) {
    428  1.1  sakamoto 		if (status == RQM) {
    429  1.1  sakamoto 			printf("fdc_in:error:ready for output\n");
    430  1.1  sakamoto 			return (FAIL);
    431  1.1  sakamoto 		}
    432  1.1  sakamoto 	}
    433  1.1  sakamoto 
    434  1.1  sakamoto 	if (time_out <= 0) {
    435  1.1  sakamoto 		printf("fdc_in:input ready timeout\n");
    436  1.1  sakamoto 		return (FAIL);
    437  1.1  sakamoto 	}
    438  1.1  sakamoto 
    439  1.3  sakamoto 	if (data) *data = (u_char)inb(FDC_DATA(ctlr));
    440  1.1  sakamoto 
    441  1.1  sakamoto 	return (SUCCESS);
    442  1.1  sakamoto }
    443  1.1  sakamoto 
    444  1.1  sakamoto /*===========================================================================*
    445  1.1  sakamoto  *                              fdc_intr_wait                                *
    446  1.1  sakamoto  *===========================================================================*/
    447  1.1  sakamoto int
    448  1.9    cegger fdc_intr_wait(void)
    449  1.1  sakamoto {
    450  1.8  kiyohara 
    451  1.3  sakamoto 	return (irq_polling(FDC_IRQ, INT_TIMEOUT));	/* wait interrupt */
    452  1.1  sakamoto }
    453  1.1  sakamoto 
    454  1.1  sakamoto /*===========================================================================*
    455  1.1  sakamoto  *		   	     fdc command function	 	    	     *
    456  1.1  sakamoto  *===========================================================================*/
    457  1.1  sakamoto void
    458  1.8  kiyohara motor_on(int ctlr, int unit)
    459  1.1  sakamoto {
    460  1.8  kiyohara 
    461  1.1  sakamoto 	outb(FDC_DOR(ctlr), DOR_RESET | DOR_DMAEN | unit
    462  1.1  sakamoto 		| (1 << (unit + 4)));	/* reset & unit motor on */
    463  1.1  sakamoto 	DELAY(1);		/* wait 100msec */
    464  1.1  sakamoto }
    465  1.1  sakamoto 
    466  1.1  sakamoto void
    467  1.8  kiyohara motor_off(int ctlr, int unit)
    468  1.1  sakamoto {
    469  1.8  kiyohara 
    470  1.8  kiyohara 	outb(FDC_DOR(ctlr), DOR_RESET);		/* reset & motor off */
    471  1.3  sakamoto 	if (fdc_intr_wait() == FAIL)		/* wait interrupt */
    472  1.1  sakamoto 		printf("fdc: motor off failed.\n");
    473  1.1  sakamoto }
    474  1.1  sakamoto 
    475  1.1  sakamoto void
    476  1.8  kiyohara fdReset(int ctlr)
    477  1.1  sakamoto {
    478  1.8  kiyohara 
    479  1.1  sakamoto 	outb(FDC_DOR(ctlr), 0); /* fdc reset */
    480  1.1  sakamoto 	DELAY(3);
    481  1.1  sakamoto 	outb(FDC_DOR(ctlr), DOR_RESET);
    482  1.1  sakamoto 	DELAY(8);
    483  1.1  sakamoto }
    484  1.1  sakamoto 
    485  1.1  sakamoto void
    486  1.8  kiyohara fdRecalibrate(int ctlr, int unit)
    487  1.1  sakamoto {
    488  1.8  kiyohara 
    489  1.1  sakamoto 	fdc_out(ctlr, CMD_RECALIBRATE);
    490  1.1  sakamoto 	fdc_out(ctlr, unit);
    491  1.1  sakamoto 
    492  1.1  sakamoto 	if (fdc_intr_wait() == FAIL)   /* wait interrupt */
    493  1.1  sakamoto 		printf("fdc: recalibrate Timeout\n");
    494  1.1  sakamoto }
    495  1.1  sakamoto 
    496  1.1  sakamoto void
    497  1.8  kiyohara fdSpecify(int ctlr)
    498  1.1  sakamoto {
    499  1.8  kiyohara 
    500  1.1  sakamoto 	fdc_out(ctlr, CMD_SPECIFY);
    501  1.1  sakamoto 	fdc_out(ctlr, SPECIFY1);
    502  1.1  sakamoto 	fdc_out(ctlr, SPECIFY2);
    503  1.1  sakamoto }
    504  1.1  sakamoto 
    505  1.1  sakamoto void
    506  1.8  kiyohara fdDriveStatus(int ctlr, register int unit, register int head,
    507  1.8  kiyohara 	      register int *stat)
    508  1.1  sakamoto {
    509  1.3  sakamoto 	u_char result;
    510  1.1  sakamoto 
    511  1.1  sakamoto 	fdc_out(ctlr, CMD_DRV_SENSE);
    512  1.1  sakamoto 	fdc_out(ctlr, (head << 2) | unit);
    513  1.1  sakamoto 	fdc_in(ctlr, &result);
    514  1.1  sakamoto 	*stat = (int)(result & 0xff);
    515  1.1  sakamoto }
    516  1.1  sakamoto 
    517  1.1  sakamoto int
    518  1.8  kiyohara fdSeek(int ctlr, int unit, int cyl)
    519  1.1  sakamoto {
    520  1.1  sakamoto 	int ret_val = 0;
    521  1.1  sakamoto 
    522  1.1  sakamoto 	fdc_out(ctlr, CMD_SEEK);
    523  1.1  sakamoto 	fdc_out(ctlr, unit);
    524  1.1  sakamoto 	fdc_out(ctlr, cyl);
    525  1.1  sakamoto 
    526  1.3  sakamoto         if (fdc_intr_wait() == FAIL) {		/* wait interrupt */
    527  1.1  sakamoto 		printf("fdc: fdSeek Timeout\n");
    528  1.1  sakamoto 		ret_val = FAIL;
    529  1.1  sakamoto 	}
    530  1.1  sakamoto 
    531  1.1  sakamoto 	return(ret_val);
    532  1.1  sakamoto }
    533  1.1  sakamoto 
    534  1.1  sakamoto int
    535  1.8  kiyohara fdSenseInt(int ctlr, int *stat)
    536  1.1  sakamoto {
    537  1.3  sakamoto 	u_char result;
    538  1.1  sakamoto 
    539  1.1  sakamoto 	fdc_out(ctlr, CMD_SENSE_INT);
    540  1.1  sakamoto 
    541  1.1  sakamoto 	fdc_in(ctlr, &result);
    542  1.1  sakamoto 	*stat++ = (int)(result & 0xff);
    543  1.1  sakamoto 	fdc_in(ctlr, &result);
    544  1.1  sakamoto 	*stat++ = (int)(result & 0xff);
    545  1.1  sakamoto 
    546  1.3  sakamoto 	return (0);
    547  1.1  sakamoto }
    548  1.1  sakamoto 
    549  1.1  sakamoto int
    550  1.8  kiyohara fdReadWrite(FD_UNIT *un, int func, int cyl, int head, int sec, u_char *adrs)
    551  1.1  sakamoto {
    552  1.1  sakamoto 	int i;
    553  1.1  sakamoto 	int ctlr = un->ctlr;
    554  1.1  sakamoto 	int unit = un->unit;
    555  1.1  sakamoto 	int *stat = un->stat;
    556  1.3  sakamoto 	u_char result;
    557  1.1  sakamoto 
    558  1.1  sakamoto #if 0
    559  1.1  sakamoto printf("%s:", (func == F_READ ? "READ" : "WRITE"));
    560  1.1  sakamoto printf("cyl = %d", cyl);
    561  1.1  sakamoto printf("head = %d", head);
    562  1.1  sakamoto printf("sec = %d", sec);
    563  1.1  sakamoto printf("secsize = %d", un->un_type->secsize);
    564  1.1  sakamoto printf("seccount = %d", un->un_type->seccount);
    565  1.1  sakamoto printf("gap = %d", un->un_type->gap);
    566  1.1  sakamoto printf("datalen = %d\n", un->un_type->datalen);
    567  1.1  sakamoto #endif
    568  1.1  sakamoto 
    569  1.1  sakamoto 	dma_setup(adrs, FDBLK, func, FD_DMA_CHAN);
    570  1.1  sakamoto 	fdc_out(ctlr, (func == F_READ ? CMD_READ : CMD_WRITE));
    571  1.1  sakamoto 	fdc_out(ctlr, (head<<2) | unit);
    572  1.1  sakamoto 	fdc_out(ctlr, cyl);			/* cyl */
    573  1.1  sakamoto 	fdc_out(ctlr, head);			/* head */
    574  1.1  sakamoto 	fdc_out(ctlr, sec);			/* sec */
    575  1.1  sakamoto 	fdc_out(ctlr, un->un_type->secsize);	/* secsize */
    576  1.1  sakamoto 	fdc_out(ctlr, un->un_type->seccount);	/* EOT (end of track) */
    577  1.1  sakamoto 	fdc_out(ctlr, un->un_type->gap);	/* GAP3 */
    578  1.1  sakamoto 	fdc_out(ctlr, un->un_type->datalen);	/* DTL (data length) */
    579  1.1  sakamoto 
    580  1.1  sakamoto 	if (fdc_intr_wait() == FAIL) {  /* wait interrupt */
    581  1.1  sakamoto 		printf("fdc: DMA transfer Timeout\n");
    582  1.1  sakamoto 		return (FAIL);
    583  1.1  sakamoto 	}
    584  1.1  sakamoto 
    585  1.1  sakamoto 	for (i = 0; i < 7; i++) {
    586  1.1  sakamoto 		fdc_in(ctlr, &result);
    587  1.1  sakamoto 		stat[i] = (int)(result & 0xff);
    588  1.1  sakamoto 	}
    589  1.1  sakamoto 	if (stat[0] & ST0_IC_MASK) {	/* not normal terminate */
    590  1.1  sakamoto 		if ((stat[1] & ~ST1_EN) || stat[2])
    591  1.1  sakamoto 		goto bad;
    592  1.1  sakamoto 	}
    593  1.1  sakamoto 	if (!dma_finished(FD_DMA_CHAN)) {
    594  1.1  sakamoto 		printf("DMA not finished\n");
    595  1.1  sakamoto 		goto bad;
    596  1.1  sakamoto 	}
    597  1.1  sakamoto 	return (SUCCESS);
    598  1.1  sakamoto 
    599  1.1  sakamoto bad:
    600  1.1  sakamoto 	printf("       func: %s\n", (func == F_READ ? "F_READ" : "F_WRITE"));
    601  1.1  sakamoto 	printf("	st0 = 0x%x\n", stat[0]);
    602  1.1  sakamoto 	printf("	st1 = 0x%x\n", stat[1]);
    603  1.1  sakamoto 	printf("	st2 = 0x%x\n", stat[2]);
    604  1.1  sakamoto 	printf("	  c = 0x%x\n", stat[3]);
    605  1.1  sakamoto 	printf("	  h = 0x%x\n", stat[4]);
    606  1.1  sakamoto 	printf("	  r = 0x%x\n", stat[5]);
    607  1.1  sakamoto 	printf("	  n = 0x%x\n", stat[6]);
    608  1.1  sakamoto 	return (FAIL);
    609  1.1  sakamoto }
    610  1.1  sakamoto 
    611  1.1  sakamoto /*-----------------------------------------------------------------------
    612  1.1  sakamoto  * Interrupt Controller Operation Functions
    613  1.1  sakamoto  *-----------------------------------------------------------------------
    614  1.1  sakamoto  */
    615  1.1  sakamoto 
    616  1.1  sakamoto /* 8259A interrupt controller register */
    617  1.3  sakamoto #define	INT_CTL0	0x20
    618  1.3  sakamoto #define	INT_CTL1	0x21
    619  1.3  sakamoto #define	INT2_CTL0	0xA0
    620  1.3  sakamoto #define	INT2_CTL1	0xA1
    621  1.1  sakamoto 
    622  1.1  sakamoto #define	CASCADE_IRQ	2
    623  1.1  sakamoto 
    624  1.3  sakamoto #define	ICW1_AT		0x11    /* edge triggered, cascade, need ICW4 */
    625  1.3  sakamoto #define	ICW4_AT		0x01    /* not SFNM, not buffered, normal EOI, 8086 */
    626  1.1  sakamoto #define	OCW3_PL		0x0e	/* polling mode */
    627  1.1  sakamoto #define	OCW2_CLEAR	0x20	/* interrupt clear */
    628  1.1  sakamoto 
    629  1.1  sakamoto /*
    630  1.3  sakamoto  * IRC programing sequence
    631  1.1  sakamoto  *
    632  1.1  sakamoto  * after reset
    633  1.1  sakamoto  * 1.	ICW1 (write port:INT_CTL0 data:bit4=1)
    634  1.1  sakamoto  * 2.	ICW2 (write port:INT_CTL1)
    635  1.1  sakamoto  * 3.	ICW3 (write port:INT_CTL1)
    636  1.1  sakamoto  * 4.	ICW4 (write port:INT_CTL1)
    637  1.3  sakamoto  *
    638  1.1  sakamoto  * after ICW
    639  1.1  sakamoto  *	OCW1 (write port:INT_CTL1)
    640  1.1  sakamoto  *	OCW2 (write port:INT_CTL0 data:bit3=0,bit4=0)
    641  1.1  sakamoto  *	OCW3 (write port:INT_CTL0 data:bit3=1,bit4=0)
    642  1.1  sakamoto  *
    643  1.1  sakamoto  *	IMR  (read port:INT_CTL1)
    644  1.1  sakamoto  *	IRR  (read port:INT_CTL0)	OCW3(bit1=1,bit0=0)
    645  1.1  sakamoto  *	ISR  (read port:INT_CTL0)	OCW3(bit1=1,bit0=1)
    646  1.1  sakamoto  *	PL   (read port:INT_CTL0)	OCW3(bit2=1,bit1=1)
    647  1.1  sakamoto  */
    648  1.1  sakamoto 
    649  1.3  sakamoto u_int INT_MASK;
    650  1.3  sakamoto u_int INT2_MASK;
    651  1.1  sakamoto 
    652  1.1  sakamoto /*===========================================================================*
    653  1.1  sakamoto  *                             irq initialize                                *
    654  1.1  sakamoto  *===========================================================================*/
    655  1.3  sakamoto void
    656  1.9    cegger irq_init(void)
    657  1.1  sakamoto {
    658  1.1  sakamoto 	outb(INT_CTL0, ICW1_AT);		/* ICW1 */
    659  1.1  sakamoto 	outb(INT_CTL1, 0);			/* ICW2 for master */
    660  1.1  sakamoto 	outb(INT_CTL1, (1 << CASCADE_IRQ));	/* ICW3 tells slaves */
    661  1.1  sakamoto 	outb(INT_CTL1, ICW4_AT);		/* ICW4 */
    662  1.1  sakamoto 
    663  1.1  sakamoto 	outb(INT_CTL1, (INT_MASK = ~(1 << CASCADE_IRQ)));
    664  1.1  sakamoto 				/* IRQ mask(exclusive of cascade) */
    665  1.1  sakamoto 
    666  1.1  sakamoto 	outb(INT2_CTL0, ICW1_AT);		/* ICW1 */
    667  1.1  sakamoto 	outb(INT2_CTL1, 8); 			/* ICW2 for slave */
    668  1.1  sakamoto 	outb(INT2_CTL1, CASCADE_IRQ);		/* ICW3 is slave nr */
    669  1.1  sakamoto 	outb(INT2_CTL1, ICW4_AT);		/* ICW4 */
    670  1.1  sakamoto 
    671  1.1  sakamoto 	outb(INT2_CTL1, (INT2_MASK = ~0));	/* IRQ 8-15 mask */
    672  1.1  sakamoto }
    673  1.1  sakamoto 
    674  1.1  sakamoto /*===========================================================================*
    675  1.1  sakamoto  *                           irq polling check                               *
    676  1.1  sakamoto  *===========================================================================*/
    677  1.3  sakamoto int
    678  1.8  kiyohara irq_polling(int irq_no, int timeout)
    679  1.1  sakamoto {
    680  1.1  sakamoto 	int	irc_no;
    681  1.1  sakamoto 	int	data;
    682  1.1  sakamoto 	int	ret;
    683  1.1  sakamoto 
    684  1.1  sakamoto 	if (irq_no > 8) irc_no = 1;
    685  1.1  sakamoto 		else irc_no = 0;
    686  1.1  sakamoto 
    687  1.1  sakamoto 	outb(irc_no ? INT2_CTL1 : INT_CTL1, ~(1 << (irq_no >> (irc_no * 3))));
    688  1.1  sakamoto 
    689  1.3  sakamoto 	while (--timeout > 0) {
    690  1.1  sakamoto 		outb(irc_no ? INT2_CTL0 : INT_CTL0, OCW3_PL);
    691  1.1  sakamoto 						/* set polling mode */
    692  1.1  sakamoto 		data = inb(irc_no ? INT2_CTL0 : INT_CTL0);
    693  1.1  sakamoto 		if (data & 0x80) {	/* if interrupt request */
    694  1.1  sakamoto 			if ((irq_no >> (irc_no * 3)) == (data & 0x7)) {
    695  1.1  sakamoto 				ret = SUCCESS;
    696  1.1  sakamoto 				break;
    697  1.1  sakamoto 			}
    698  1.1  sakamoto 		}
    699  1.1  sakamoto 	}
    700  1.1  sakamoto 	if (!timeout) ret = FAIL;
    701  1.1  sakamoto 
    702  1.1  sakamoto 	if (irc_no) {				/* interrupt clear */
    703  1.1  sakamoto 		outb(INT2_CTL0, OCW2_CLEAR | (irq_no >> 3));
    704  1.1  sakamoto 		outb(INT_CTL0, OCW2_CLEAR | CASCADE_IRQ);
    705  1.1  sakamoto 	} else {
    706  1.1  sakamoto 		outb(INT_CTL0, OCW2_CLEAR | irq_no);
    707  1.1  sakamoto 	}
    708  1.1  sakamoto 
    709  1.1  sakamoto 	outb(INT_CTL1, INT_MASK);
    710  1.1  sakamoto 	outb(INT2_CTL1, INT2_MASK);
    711  1.1  sakamoto 
    712  1.1  sakamoto 	return (ret);
    713  1.1  sakamoto }
    714  1.1  sakamoto 
    715  1.1  sakamoto /*---------------------------------------------------------------------------*
    716  1.1  sakamoto  *			DMA Controller Define			 	     *
    717  1.1  sakamoto  *---------------------------------------------------------------------------*/
    718  1.1  sakamoto /* DMA Controller Registers */
    719  1.3  sakamoto #define	DMA_ADDR	0x004    /* port for low 16 bits of DMA address */
    720  1.3  sakamoto #define	DMA_LTOP	0x081    /* port for top low 8bit DMA addr(ch2) */
    721  1.3  sakamoto #define	DMA_HTOP	0x481    /* port for top high 8bit DMA addr(ch2) */
    722  1.3  sakamoto #define	DMA_COUNT	0x005    /* port for DMA count (count =  bytes - 1) */
    723  1.1  sakamoto #define	DMA_DEVCON	0x008    /* DMA device control register */
    724  1.1  sakamoto #define	DMA_SR		0x008    /* DMA status register */
    725  1.1  sakamoto #define	DMA_RESET	0x00D    /* DMA software reset register */
    726  1.3  sakamoto #define	DMA_FLIPFLOP	0x00C    /* DMA byte pointer flip-flop */
    727  1.3  sakamoto #define	DMA_MODE	0x00B    /* DMA mode port */
    728  1.3  sakamoto #define	DMA_INIT	0x00A    /* DMA init port */
    729  1.1  sakamoto 
    730  1.3  sakamoto #define	DMA_RESET_VAL	0x06
    731  1.1  sakamoto /* DMA channel commands. */
    732  1.3  sakamoto #define	DMA_READ	0x46    /* DMA read opcode */
    733  1.3  sakamoto #define	DMA_WRITE	0x4A    /* DMA write opcode */
    734  1.1  sakamoto 
    735  1.1  sakamoto /*===========================================================================*
    736  1.1  sakamoto  *				dma_setup				     *
    737  1.1  sakamoto  *===========================================================================*/
    738  1.3  sakamoto void
    739  1.8  kiyohara dma_setup(u_char *buf, int size, int func, int chan)
    740  1.1  sakamoto {
    741  1.3  sakamoto 	u_long pbuf = local_to_PCI((u_long)buf);
    742  1.1  sakamoto 
    743  1.1  sakamoto #if 0
    744  1.1  sakamoto 	outb(DMA_RESET, 0);
    745  1.1  sakamoto 	DELAY(1);
    746  1.1  sakamoto 	outb(DMA_DEVCON, 0x00);
    747  1.3  sakamoto 	outb(DMA_INIT, DMA_RESET_VAL);	/* reset the dma controller */
    748  1.1  sakamoto #endif
    749  1.1  sakamoto 	outb(DMA_MODE, func == F_READ ? DMA_READ : DMA_WRITE);
    750  1.3  sakamoto 	outb(DMA_FLIPFLOP, 0);		/* write anything to reset it */
    751  1.1  sakamoto 
    752  1.1  sakamoto 	outb(DMA_ADDR, (int)pbuf >>  0);
    753  1.1  sakamoto 	outb(DMA_ADDR, (int)pbuf >>  8);
    754  1.1  sakamoto 	outb(DMA_LTOP, (int)pbuf >> 16);
    755  1.1  sakamoto 	outb(DMA_HTOP, (int)pbuf >> 24);
    756  1.1  sakamoto 
    757  1.1  sakamoto 	outb(DMA_COUNT, (size - 1) >> 0);
    758  1.1  sakamoto 	outb(DMA_COUNT, (size - 1) >> 8);
    759  1.3  sakamoto 	outb(DMA_INIT, chan);		/* some sort of enable */
    760  1.1  sakamoto }
    761  1.1  sakamoto 
    762  1.1  sakamoto int
    763  1.8  kiyohara dma_finished(int chan)
    764  1.1  sakamoto {
    765  1.8  kiyohara 
    766  1.1  sakamoto 	return ((inb(DMA_SR) & 0x0f) == (1 << chan));
    767  1.1  sakamoto }
    768