1 /* $Id: fd.c,v 1.1 1998/01/16 04:17:47 sakamoto 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 "stand.h" 37 38 /*---------------------------------------------------------------------------* 39 * Floppy Disk Controller Define * 40 *---------------------------------------------------------------------------*/ 41 /* Floppy Disk Controller Registers */ 42 int FDC_PORT[] = { /* fdc base I/O port */ 43 0x3f0, /* primary */ 44 }; 45 #define FDC_DOR(x) (FDC_PORT[x] + 0x2) /* motor drive control bits */ 46 #define FDC_STATUS(x) (FDC_PORT[x] + 0x4) /* fdc main status register */ 47 #define FDC_DATA(x) (FDC_PORT[x] + 0x5) /* fdc data register */ 48 #define FDC_RATE(x) (FDC_PORT[x] + 0x7) /* transfer rate register */ 49 50 #define FDC_IRQ 6 51 #define FD_DMA_CHAN 2 52 53 /* fdc main status register */ 54 #define RQM 0x80 /* the host can transfer data if set */ 55 #define DIO 0x40 /* direction of data transfer. write required if set */ 56 #define NON_DMA 0x20 /* fdc have date for transfer in non dma mode */ 57 #define CMD_BUSY 0x10 /* command busy if set */ 58 59 /* fdc result status */ 60 #define ST0_IC_MASK 0xc0 /* interrupt code 00:normal terminate */ 61 #define ST1_EN 0x80 /* end of cylinder */ 62 63 /* fdc digtal output register */ 64 #define DOR_DMAEN 0x08 /* DRQ, nDACK, TC and FINTR output enable */ 65 #define DOR_RESET 0x04 /* fdc software reset */ 66 67 /* fdc command */ 68 #define CMD_RECALIBRATE 0x07 /* recalibrate */ 69 #define CMD_SENSE_INT 0x08 /* sense interrupt status */ 70 #define CMD_DRV_SENSE 0x04 /* sense drive status */ 71 #define CMD_SEEK 0x0f /* seek */ 72 #define CMD_FORMAT 0x4d /* format */ 73 #define CMD_READ 0x46 /* read e6 */ 74 #define CMD_WRITE 0xc5 /* write */ 75 #define CMD_VERIFY 0xf6 /* verify */ 76 #define CMD_READID 0x4a /* readID */ 77 #define CMD_SPECIFY 0x03 /* specify */ 78 #define CMD_CONFIG 0x13 /* config */ 79 #define CMD_VERSION 0x10 /* version */ 80 81 /* command specify value */ 82 #define SPECIFY1 ((0x0d<<4)|0x0f) 83 #define SPECIFY2 ((0x01<<1)|0) /* DMA MODE */ 84 85 /* fdc result */ 86 #define STATUS_MAX 16 /* result status max number */ 87 #define RESULT_VERSION 0x90 /* enhanced controller */ 88 #define RESULT_SEEK 0x20 /* seek & recalibrate complete flag on status0 */ 89 90 /*---------------------------------------------------------------------------* 91 * Floppy Disk Type Define * 92 *---------------------------------------------------------------------------*/ 93 struct fdd_type { 94 int seccount; /* sector per track */ 95 int secsize; /* byte per sector (uPD765 paramater) */ 96 int datalen; /* data length */ 97 int gap; /* gap */ 98 int gaplen; /* gap length */ 99 int cylinder; /* track per media */ 100 int maxseccount; /* media max sector count */ 101 int step; /* seek step */ 102 int rate; /* drive rate (250 or 500kbps) */ 103 int heads; /* heads */ 104 int f_gap; /* format gap */ 105 int mselect; /* drive mode select */ 106 char *type_name; /* media type name */ 107 }; 108 typedef struct fdd_type FDDTYPE; 109 110 #define FDTYPE_MAX 5 111 FDDTYPE fdd_types[FDTYPE_MAX] = { 112 { 18,2,0xff,0x1b,0x54,80,2880,1,0,2,0x6c,0,"2HQ" }, /* 2HD (PC/AT) */ 113 { 8,3,0xff,0x35,0x74,77,1232,1,0,2,0x54,1,"2HD" }, /* 2HD (98) */ 114 { 15,2,0xff,0x1b,0x54,80,2400,1,0,2,0x54,1,"2HC" }, /* 2HC */ 115 { 9,2,0xff,0x23,0x50,80,1440,1,2,2,0x50,1,"2DD9" },/* 2DD 9 sector */ 116 { 8,2,0xff,0x3a,0x50,80,1280,1,2,2,0x50,1,"2DD8" },/* 2DD 8 sector */ 117 }; 118 119 int fdsectors[] = {128, 256, 512, 1024, 2048, 4096}; 120 #define SECTOR_MAX 4096 121 #define FDBLK (fdsectors[un->un_type->secsize]) 122 123 #define START_CYL 0 124 #define START_SECTOR 1 125 126 #define DELAY(x) delay(100000 * x) /* about 100ms */ 127 #define INT_TIMEOUT 3000000 128 129 /*---------------------------------------------------------------------------* 130 * FDC Device Driver Define * 131 *---------------------------------------------------------------------------*/ 132 #define CTLR_MAX 1 133 #define UNIT_MAX 2 134 135 struct fd_unit { 136 int ctlr; 137 int unit; 138 int part; 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 fdc_out(int, int); 166 int fdc_in(int, unsigned char *); 167 int fdc_intr_wait(); 168 int fd_check(FD_UNIT *); 169 void motor_on(int, int); 170 void motor_off(int, int); 171 void fdReset(int); 172 void fdRecalibrate(int, int); 173 void fdSpecify(int); 174 void fdDriveStatus(int, int, int, int *); 175 int fdSeek(int, int, int); 176 int fdSenseInt(int, int *); 177 int fdReadWrite(FD_UNIT *, int, int, int, int, u_char *); 178 179 /*===========================================================================* 180 * fdinit * 181 *===========================================================================*/ 182 fdinit(un) 183 FD_UNIT *un; 184 { 185 int i; 186 int ctlr = un->ctlr; 187 unsigned char result; 188 189 #if 0 190 irq_init(); 191 #endif 0 192 fdReset(ctlr); 193 194 if (fdc_out(ctlr, CMD_VERSION) != SUCCESS) { /* version check */ 195 printf ("fdc%d:fatal error: CMD_VERSION cmd fail\n",ctlr); 196 return (FAIL); 197 } 198 if (fdc_in(ctlr, &result) != SUCCESS) { 199 printf ("fdc%d:fatal error: CMD_VERSION exec fail\n",ctlr); 200 return (FAIL); 201 } 202 if (result != (unsigned char)RESULT_VERSION) { 203 printf ("fdc%d:fatal error: unknown version fdc\n",ctlr); 204 return (FAIL); 205 } 206 207 un->un_flags = INT_ALIVE; 208 return (SUCCESS); 209 } 210 211 /*===========================================================================* 212 * fdopen * 213 *===========================================================================*/ 214 fdopen(f, ctlr, unit, part) 215 struct open_file *f; 216 int ctlr, unit, part; 217 { 218 FD_UNIT *un; 219 int *stat = un->stat; 220 221 if (ctlr >= CTLR_MAX) 222 return (ENXIO); 223 if (unit >= UNIT_MAX) 224 return (ENXIO); 225 un = &fd_unit[ctlr][unit]; 226 227 if (!(un->un_flags & INT_ALIVE)) { 228 if (fdinit(un) != SUCCESS) 229 return (ENXIO); 230 } 231 232 motor_on(ctlr, unit); 233 234 fdRecalibrate(ctlr, unit); 235 fdSenseInt(ctlr, stat); 236 if (stat[1] != START_CYL) { 237 printf("fdc%d: unit:%d recalibrate failed. status:0x%x cyl:%d\n", 238 ctlr, unit, stat[0], stat[1]); 239 motor_off(ctlr, unit); 240 return (EIO); 241 } 242 243 if (fd_check(un) != SUCCESS) /* research disk type */ 244 return (EIO); 245 246 f->f_devdata = (void *)un; 247 return (SUCCESS); 248 } 249 250 /*===========================================================================* 251 * fdclose * 252 *===========================================================================*/ 253 fdclose(f) 254 struct open_file *f; 255 { 256 FD_UNIT *un = f->f_devdata; 257 258 fdRecalibrate(un->ctlr, un->unit); 259 fdSenseInt(un->ctlr, un->stat); 260 motor_off(un->ctlr, un->unit); 261 un->un_flags = 0; 262 return (SUCCESS); 263 } 264 265 /*===========================================================================* 266 * fdioctl * 267 *===========================================================================*/ 268 fdioctl(f, cmd, arg) 269 struct open_file *f; 270 u_long cmd; 271 void *arg; 272 { 273 FD_UNIT *un = f->f_devdata; 274 int *stat = un->stat; 275 276 switch(cmd) { 277 default: 278 return (EIO); 279 } 280 281 return (SUCCESS); 282 } 283 284 /*===========================================================================* 285 * fdstrategy * 286 *===========================================================================*/ 287 fdstrategy(devdata, func, blk, size, buf, rsize) 288 void *devdata; /* device uniq data */ 289 int func; /* function (read or write) */ 290 daddr_t blk; /* block number */ 291 size_t size; /* request size in bytes */ 292 void *buf; /* buffer */ 293 size_t *rsize; /* bytes transferred */ 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 char *cbuf = (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(un) 353 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(ctlr, cmd) 399 int ctlr; /* controller no */ 400 int cmd; /* cmd */ 401 { 402 volatile int status; 403 int time_out; 404 405 time_out = TIMEOUT; 406 while (((status = inb(FDC_STATUS(ctlr))) & (RQM | DIO)) 407 != (RQM | 0) && time_out-- > 0); 408 if (time_out <= 0) { 409 printf("fdc_out: timeout status = 0x%x\n", status); 410 return (FAIL); 411 } 412 413 outb(FDC_DATA(ctlr), cmd); 414 415 return (SUCCESS); 416 } 417 418 /*===========================================================================* 419 * fdc_in * 420 *===========================================================================*/ 421 int 422 fdc_in(ctlr, data) 423 int ctlr; /* controller no */ 424 unsigned char *data; 425 { 426 volatile int status; 427 int time_out; 428 429 time_out = TIMEOUT; 430 while ((status = inb(FDC_STATUS(ctlr)) & (RQM | DIO)) 431 != (RQM | DIO) && time_out-- > 0) { 432 if (status == RQM) { 433 printf("fdc_in:error:ready for output\n"); 434 return (FAIL); 435 } 436 } 437 438 if (time_out <= 0) { 439 printf("fdc_in:input ready timeout\n"); 440 return (FAIL); 441 } 442 443 if (data) *data = (unsigned char)inb(FDC_DATA(ctlr)); 444 445 return (SUCCESS); 446 } 447 448 /*===========================================================================* 449 * fdc_intr_wait * 450 *===========================================================================*/ 451 int 452 fdc_intr_wait() 453 { 454 return (irq_polling(FDC_IRQ, INT_TIMEOUT)); /* wait interrupt */ 455 } 456 457 /*===========================================================================* 458 * fdc command function * 459 *===========================================================================*/ 460 void 461 motor_on(ctlr, unit) 462 int ctlr; 463 int unit; 464 { 465 outb(FDC_DOR(ctlr), DOR_RESET | DOR_DMAEN | unit 466 | (1 << (unit + 4))); /* reset & unit motor on */ 467 DELAY(1); /* wait 100msec */ 468 } 469 470 void 471 motor_off(ctlr, unit) 472 int ctlr; 473 int unit; 474 { 475 outb(FDC_DOR(ctlr), DOR_RESET); /* reset & motor off */ 476 if (fdc_intr_wait() == FAIL) /* wait interrupt */ 477 printf("fdc: motor off failed.\n"); 478 } 479 480 void 481 fdReset(ctlr) 482 { 483 outb(FDC_DOR(ctlr), 0); /* fdc reset */ 484 DELAY(3); 485 outb(FDC_DOR(ctlr), DOR_RESET); 486 DELAY(8); 487 } 488 489 void 490 fdRecalibrate(ctlr, unit) 491 int ctlr; 492 int unit; 493 { 494 int ret_val = 0; 495 496 fdc_out(ctlr, CMD_RECALIBRATE); 497 fdc_out(ctlr, unit); 498 499 if (fdc_intr_wait() == FAIL) /* wait interrupt */ 500 printf("fdc: recalibrate Timeout\n"); 501 } 502 503 void 504 fdSpecify(ctlr) 505 int ctlr; 506 { 507 fdc_out(ctlr, CMD_SPECIFY); 508 fdc_out(ctlr, SPECIFY1); 509 fdc_out(ctlr, SPECIFY2); 510 } 511 512 void 513 fdDriveStatus(ctlr, unit, head, stat) 514 int ctlr; 515 register int unit, head; 516 register int *stat; 517 { 518 unsigned char result; 519 520 fdc_out(ctlr, CMD_DRV_SENSE); 521 fdc_out(ctlr, (head << 2) | unit); 522 fdc_in(ctlr, &result); 523 *stat = (int)(result & 0xff); 524 } 525 526 int 527 fdSeek(ctlr, unit, cyl) 528 int ctlr; 529 int unit; 530 int cyl; 531 { 532 int ret_val = 0; 533 534 fdc_out(ctlr, CMD_SEEK); 535 fdc_out(ctlr, unit); 536 fdc_out(ctlr, cyl); 537 538 if (fdc_intr_wait() == FAIL) { /* wait interrupt */ 539 printf("fdc: fdSeek Timeout\n"); 540 ret_val = FAIL; 541 } 542 543 return(ret_val); 544 } 545 546 int 547 fdSenseInt(ctlr, stat) 548 int ctlr; 549 int *stat; 550 { 551 unsigned char result; 552 553 fdc_out(ctlr, CMD_SENSE_INT); 554 555 fdc_in(ctlr, &result); 556 *stat++ = (int)(result & 0xff); 557 fdc_in(ctlr, &result); 558 *stat++ = (int)(result & 0xff); 559 560 return(0); 561 } 562 563 int 564 fdReadWrite(un, func, cyl, head, sec, adrs) 565 FD_UNIT *un; 566 int func; 567 int cyl; 568 int head; 569 int sec; 570 u_char *adrs; 571 { 572 int i; 573 int ctlr = un->ctlr; 574 int unit = un->unit; 575 int *stat = un->stat; 576 int read_bytes; 577 unsigned char result; 578 579 #if 0 580 printf("%s:", (func == F_READ ? "READ" : "WRITE")); 581 printf("cyl = %d", cyl); 582 printf("head = %d", head); 583 printf("sec = %d", sec); 584 printf("secsize = %d", un->un_type->secsize); 585 printf("seccount = %d", un->un_type->seccount); 586 printf("gap = %d", un->un_type->gap); 587 printf("datalen = %d\n", un->un_type->datalen); 588 #endif 589 590 dma_setup(adrs, FDBLK, func, FD_DMA_CHAN); 591 fdc_out(ctlr, (func == F_READ ? CMD_READ : CMD_WRITE)); 592 fdc_out(ctlr, (head<<2) | unit); 593 fdc_out(ctlr, cyl); /* cyl */ 594 fdc_out(ctlr, head); /* head */ 595 fdc_out(ctlr, sec); /* sec */ 596 fdc_out(ctlr, un->un_type->secsize); /* secsize */ 597 fdc_out(ctlr, un->un_type->seccount); /* EOT (end of track) */ 598 fdc_out(ctlr, un->un_type->gap); /* GAP3 */ 599 fdc_out(ctlr, un->un_type->datalen); /* DTL (data length) */ 600 601 if (fdc_intr_wait() == FAIL) { /* wait interrupt */ 602 printf("fdc: DMA transfer Timeout\n"); 603 return (FAIL); 604 } 605 606 for (i = 0; i < 7; i++) { 607 fdc_in(ctlr, &result); 608 stat[i] = (int)(result & 0xff); 609 } 610 if (stat[0] & ST0_IC_MASK) { /* not normal terminate */ 611 if ((stat[1] & ~ST1_EN) || stat[2]) 612 goto bad; 613 } 614 if (!dma_finished(FD_DMA_CHAN)) { 615 printf("DMA not finished\n"); 616 goto bad; 617 } 618 return (SUCCESS); 619 620 bad: 621 printf(" func: %s\n", (func == F_READ ? "F_READ" : "F_WRITE")); 622 printf(" st0 = 0x%x\n", stat[0]); 623 printf(" st1 = 0x%x\n", stat[1]); 624 printf(" st2 = 0x%x\n", stat[2]); 625 printf(" c = 0x%x\n", stat[3]); 626 printf(" h = 0x%x\n", stat[4]); 627 printf(" r = 0x%x\n", stat[5]); 628 printf(" n = 0x%x\n", stat[6]); 629 return (FAIL); 630 } 631 632 /*----------------------------------------------------------------------- 633 * Interrupt Controller Operation Functions 634 *----------------------------------------------------------------------- 635 */ 636 637 /* 8259A interrupt controller register */ 638 #define INT_CTL0 0x20 639 #define INT_CTL1 0x21 640 #define INT2_CTL0 0xA0 641 #define INT2_CTL1 0xA1 642 643 #define CASCADE_IRQ 2 644 645 #define ICW1_AT 0x11 /* edge triggered, cascade, need ICW4 */ 646 #define ICW4_AT 0x01 /* not SFNM, not buffered, normal EOI, 8086 */ 647 #define OCW3_PL 0x0e /* polling mode */ 648 #define OCW2_CLEAR 0x20 /* interrupt clear */ 649 650 /* 651 * IRC programing sequence 652 * 653 * after reset 654 * 1. ICW1 (write port:INT_CTL0 data:bit4=1) 655 * 2. ICW2 (write port:INT_CTL1) 656 * 3. ICW3 (write port:INT_CTL1) 657 * 4. ICW4 (write port:INT_CTL1) 658 * 659 * after ICW 660 * OCW1 (write port:INT_CTL1) 661 * OCW2 (write port:INT_CTL0 data:bit3=0,bit4=0) 662 * OCW3 (write port:INT_CTL0 data:bit3=1,bit4=0) 663 * 664 * IMR (read port:INT_CTL1) 665 * IRR (read port:INT_CTL0) OCW3(bit1=1,bit0=0) 666 * ISR (read port:INT_CTL0) OCW3(bit1=1,bit0=1) 667 * PL (read port:INT_CTL0) OCW3(bit2=1,bit1=1) 668 */ 669 670 unsigned int INT_MASK; 671 unsigned int INT2_MASK; 672 673 /*===========================================================================* 674 * irq initialize * 675 *===========================================================================*/ 676 irq_init() 677 { 678 outb(INT_CTL0, ICW1_AT); /* ICW1 */ 679 outb(INT_CTL1, 0); /* ICW2 for master */ 680 outb(INT_CTL1, (1 << CASCADE_IRQ)); /* ICW3 tells slaves */ 681 outb(INT_CTL1, ICW4_AT); /* ICW4 */ 682 683 outb(INT_CTL1, (INT_MASK = ~(1 << CASCADE_IRQ))); 684 /* IRQ mask(exclusive of cascade) */ 685 686 outb(INT2_CTL0, ICW1_AT); /* ICW1 */ 687 outb(INT2_CTL1, 8); /* ICW2 for slave */ 688 outb(INT2_CTL1, CASCADE_IRQ); /* ICW3 is slave nr */ 689 outb(INT2_CTL1, ICW4_AT); /* ICW4 */ 690 691 outb(INT2_CTL1, (INT2_MASK = ~0)); /* IRQ 8-15 mask */ 692 } 693 694 /*===========================================================================* 695 * irq polling check * 696 *===========================================================================*/ 697 irq_polling(irq_no, timeout) 698 int irq_no; 699 int timeout; 700 { 701 int irc_no; 702 int data; 703 int ret; 704 705 if (irq_no > 8) irc_no = 1; 706 else irc_no = 0; 707 708 outb(irc_no ? INT2_CTL1 : INT_CTL1, ~(1 << (irq_no >> (irc_no * 3)))); 709 710 while(--timeout > 0) { 711 outb(irc_no ? INT2_CTL0 : INT_CTL0, OCW3_PL); 712 /* set polling mode */ 713 data = inb(irc_no ? INT2_CTL0 : INT_CTL0); 714 if (data & 0x80) { /* if interrupt request */ 715 if ((irq_no >> (irc_no * 3)) == (data & 0x7)) { 716 ret = SUCCESS; 717 break; 718 } 719 } 720 } 721 if (!timeout) ret = FAIL; 722 723 if (irc_no) { /* interrupt clear */ 724 outb(INT2_CTL0, OCW2_CLEAR | (irq_no >> 3)); 725 outb(INT_CTL0, OCW2_CLEAR | CASCADE_IRQ); 726 } else { 727 outb(INT_CTL0, OCW2_CLEAR | irq_no); 728 } 729 730 outb(INT_CTL1, INT_MASK); 731 outb(INT2_CTL1, INT2_MASK); 732 733 return (ret); 734 } 735 736 /*---------------------------------------------------------------------------* 737 * DMA Controller Define * 738 *---------------------------------------------------------------------------*/ 739 /* DMA Controller Registers */ 740 #define DMA_ADDR 0x004 /* port for low 16 bits of DMA address */ 741 #define DMA_LTOP 0x081 /* port for top low 8bit DMA addr(ch2) */ 742 #define DMA_HTOP 0x481 /* port for top high 8bit DMA addr(ch2) */ 743 #define DMA_COUNT 0x005 /* port for DMA count (count = bytes - 1) */ 744 #define DMA_DEVCON 0x008 /* DMA device control register */ 745 #define DMA_SR 0x008 /* DMA status register */ 746 #define DMA_RESET 0x00D /* DMA software reset register */ 747 #define DMA_FLIPFLOP 0x00C /* DMA byte pointer flip-flop */ 748 #define DMA_MODE 0x00B /* DMA mode port */ 749 #define DMA_INIT 0x00A /* DMA init port */ 750 751 #define DMA_RESET_VAL 0x06 752 /* DMA channel commands. */ 753 #define DMA_READ 0x46 /* DMA read opcode */ 754 #define DMA_WRITE 0x4A /* DMA write opcode */ 755 756 /*===========================================================================* 757 * dma_setup * 758 *===========================================================================*/ 759 int 760 dma_setup(buf, size, func, chan) 761 unsigned char *buf; 762 int size; 763 int func; 764 int chan; 765 { 766 unsigned long pbuf = local_to_PCI((unsigned long)buf); 767 768 #if 0 769 outb(DMA_RESET, 0); 770 DELAY(1); 771 outb(DMA_DEVCON, 0x00); 772 outb(DMA_INIT, DMA_RESET_VAL); /* reset the dma controller */ 773 #endif 774 outb(DMA_MODE, func == F_READ ? DMA_READ : DMA_WRITE); 775 outb(DMA_FLIPFLOP, 0); /* write anything to reset it */ 776 777 outb(DMA_ADDR, (int)pbuf >> 0); 778 outb(DMA_ADDR, (int)pbuf >> 8); 779 outb(DMA_LTOP, (int)pbuf >> 16); 780 outb(DMA_HTOP, (int)pbuf >> 24); 781 782 outb(DMA_COUNT, (size - 1) >> 0); 783 outb(DMA_COUNT, (size - 1) >> 8); 784 outb(DMA_INIT, chan); /* some sort of enable */ 785 } 786 787 int 788 dma_finished(chan) 789 int chan; 790 { 791 return ((inb(DMA_SR) & 0x0f) == (1 << chan)); 792 } 793