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