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