1/* floppy.h: Sparc specific parts of the Floppy driver. 2 * 3 * Copyright (C) 1996, 2007, 2008 David S. Miller (davem@davemloft.net) 4 * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) 5 * 6 * Ultra/PCI support added: Sep 1997 Eddie C. Dost (ecd@skynet.be) 7 */ 8 9#ifndef __ASM_SPARC64_FLOPPY_H 10#define __ASM_SPARC64_FLOPPY_H 11 12#include <linux/of.h> 13#include <linux/of_device.h> 14#include <linux/dma-mapping.h> 15 16#include <asm/auxio.h> 17 18/* 19 * Define this to enable exchanging drive 0 and 1 if only drive 1 is 20 * probed on PCI machines. 21 */ 22#undef PCI_FDC_SWAP_DRIVES 23 24 25/* References: 26 * 1) Netbsd Sun floppy driver. 27 * 2) NCR 82077 controller manual 28 * 3) Intel 82077 controller manual 29 */ 30struct sun_flpy_controller { 31 volatile unsigned char status1_82077; /* Auxiliary Status reg. 1 */ 32 volatile unsigned char status2_82077; /* Auxiliary Status reg. 2 */ 33 volatile unsigned char dor_82077; /* Digital Output reg. */ 34 volatile unsigned char tapectl_82077; /* Tape Control reg */ 35 volatile unsigned char status_82077; /* Main Status Register. */ 36#define drs_82077 status_82077 /* Digital Rate Select reg. */ 37 volatile unsigned char data_82077; /* Data fifo. */ 38 volatile unsigned char ___unused; 39 volatile unsigned char dir_82077; /* Digital Input reg. */ 40#define dcr_82077 dir_82077 /* Config Control reg. */ 41}; 42 43/* You'll only ever find one controller on an Ultra anyways. */ 44static struct sun_flpy_controller *sun_fdc = (struct sun_flpy_controller *)-1; 45unsigned long fdc_status; 46static struct platform_device *floppy_op = NULL; 47 48struct sun_floppy_ops { 49 unsigned char (*fd_inb) (unsigned long port); 50 void (*fd_outb) (unsigned char value, unsigned long port); 51 void (*fd_enable_dma) (void); 52 void (*fd_disable_dma) (void); 53 void (*fd_set_dma_mode) (int); 54 void (*fd_set_dma_addr) (char *); 55 void (*fd_set_dma_count) (int); 56 unsigned int (*get_dma_residue) (void); 57 int (*fd_request_irq) (void); 58 void (*fd_free_irq) (void); 59 int (*fd_eject) (int); 60}; 61 62static struct sun_floppy_ops sun_fdops; 63 64#define fd_inb(port) sun_fdops.fd_inb(port) 65#define fd_outb(value,port) sun_fdops.fd_outb(value,port) 66#define fd_enable_dma() sun_fdops.fd_enable_dma() 67#define fd_disable_dma() sun_fdops.fd_disable_dma() 68#define fd_request_dma() (0) /* nothing... */ 69#define fd_free_dma() /* nothing... */ 70#define fd_clear_dma_ff() /* nothing... */ 71#define fd_set_dma_mode(mode) sun_fdops.fd_set_dma_mode(mode) 72#define fd_set_dma_addr(addr) sun_fdops.fd_set_dma_addr(addr) 73#define fd_set_dma_count(count) sun_fdops.fd_set_dma_count(count) 74#define get_dma_residue(x) sun_fdops.get_dma_residue() 75#define fd_cacheflush(addr, size) /* nothing... */ 76#define fd_request_irq() sun_fdops.fd_request_irq() 77#define fd_free_irq() sun_fdops.fd_free_irq() 78#define fd_eject(drive) sun_fdops.fd_eject(drive) 79 80/* Super paranoid... */ 81#undef HAVE_DISABLE_HLT 82 83static int sun_floppy_types[2] = { 0, 0 }; 84 85/* Here is where we catch the floppy driver trying to initialize, 86 * therefore this is where we call the PROM device tree probing 87 * routine etc. on the Sparc. 88 */ 89#define FLOPPY0_TYPE sun_floppy_init() 90#define FLOPPY1_TYPE sun_floppy_types[1] 91 92#define FDC1 ((unsigned long)sun_fdc) 93 94#define N_FDC 1 95#define N_DRIVE 8 96 97/* No 64k boundary crossing problems on the Sparc. */ 98#define CROSS_64KB(a,s) (0) 99 100static unsigned char sun_82077_fd_inb(unsigned long port) 101{ 102 udelay(5); 103 switch(port & 7) { 104 default: 105 printk("floppy: Asked to read unknown port %lx\n", port); 106 panic("floppy: Port bolixed."); 107 case 4: /* FD_STATUS */ 108 return sbus_readb(&sun_fdc->status_82077) & ~STATUS_DMA; 109 case 5: /* FD_DATA */ 110 return sbus_readb(&sun_fdc->data_82077); 111 case 7: /* FD_DIR */ 112 return sbus_readb(&sun_fdc->dir_82077); 113 }; 114 panic("sun_82072_fd_inb: How did I get here?"); 115} 116 117static void sun_82077_fd_outb(unsigned char value, unsigned long port) 118{ 119 udelay(5); 120 switch(port & 7) { 121 default: 122 printk("floppy: Asked to write to unknown port %lx\n", port); 123 panic("floppy: Port bolixed."); 124 case 2: /* FD_DOR */ 125 /* Happily, the 82077 has a real DOR register. */ 126 sbus_writeb(value, &sun_fdc->dor_82077); 127 break; 128 case 5: /* FD_DATA */ 129 sbus_writeb(value, &sun_fdc->data_82077); 130 break; 131 case 7: /* FD_DCR */ 132 sbus_writeb(value, &sun_fdc->dcr_82077); 133 break; 134 case 4: /* FD_STATUS */ 135 sbus_writeb(value, &sun_fdc->status_82077); 136 break; 137 }; 138 return; 139} 140 141/* For pseudo-dma (Sun floppy drives have no real DMA available to 142 * them so we must eat the data fifo bytes directly ourselves) we have 143 * three state variables. doing_pdma tells our inline low-level 144 * assembly floppy interrupt entry point whether it should sit and eat 145 * bytes from the fifo or just transfer control up to the higher level 146 * floppy interrupt c-code. I tried very hard but I could not get the 147 * pseudo-dma to work in c-code without getting many overruns and 148 * underruns. If non-zero, doing_pdma encodes the direction of 149 * the transfer for debugging. 1=read 2=write 150 */ 151unsigned char *pdma_vaddr; 152unsigned long pdma_size; 153volatile int doing_pdma = 0; 154 155/* This is software state */ 156char *pdma_base = NULL; 157unsigned long pdma_areasize; 158 159/* Common routines to all controller types on the Sparc. */ 160static void sun_fd_disable_dma(void) 161{ 162 doing_pdma = 0; 163 if (pdma_base) { 164 mmu_unlockarea(pdma_base, pdma_areasize); 165 pdma_base = NULL; 166 } 167} 168 169static void sun_fd_set_dma_mode(int mode) 170{ 171 switch(mode) { 172 case DMA_MODE_READ: 173 doing_pdma = 1; 174 break; 175 case DMA_MODE_WRITE: 176 doing_pdma = 2; 177 break; 178 default: 179 printk("Unknown dma mode %d\n", mode); 180 panic("floppy: Giving up..."); 181 } 182} 183 184static void sun_fd_set_dma_addr(char *buffer) 185{ 186 pdma_vaddr = buffer; 187} 188 189static void sun_fd_set_dma_count(int length) 190{ 191 pdma_size = length; 192} 193 194static void sun_fd_enable_dma(void) 195{ 196 pdma_vaddr = mmu_lockarea(pdma_vaddr, pdma_size); 197 pdma_base = pdma_vaddr; 198 pdma_areasize = pdma_size; 199} 200 201irqreturn_t sparc_floppy_irq(int irq, void *dev_cookie) 202{ 203 if (likely(doing_pdma)) { 204 void __iomem *stat = (void __iomem *) fdc_status; 205 unsigned char *vaddr = pdma_vaddr; 206 unsigned long size = pdma_size; 207 u8 val; 208 209 while (size) { 210 val = readb(stat); 211 if (unlikely(!(val & 0x80))) { 212 pdma_vaddr = vaddr; 213 pdma_size = size; 214 return IRQ_HANDLED; 215 } 216 if (unlikely(!(val & 0x20))) { 217 pdma_vaddr = vaddr; 218 pdma_size = size; 219 doing_pdma = 0; 220 goto main_interrupt; 221 } 222 if (val & 0x40) { 223 /* read */ 224 *vaddr++ = readb(stat + 1); 225 } else { 226 unsigned char data = *vaddr++; 227 228 /* write */ 229 writeb(data, stat + 1); 230 } 231 size--; 232 } 233 234 pdma_vaddr = vaddr; 235 pdma_size = size; 236 237 /* Send Terminal Count pulse to floppy controller. */ 238 val = readb(auxio_register); 239 val |= AUXIO_AUX1_FTCNT; 240 writeb(val, auxio_register); 241 val &= ~AUXIO_AUX1_FTCNT; 242 writeb(val, auxio_register); 243 244 doing_pdma = 0; 245 } 246 247main_interrupt: 248 return floppy_interrupt(irq, dev_cookie); 249} 250 251static int sun_fd_request_irq(void) 252{ 253 static int once = 0; 254 int error; 255 256 if(!once) { 257 once = 1; 258 259 error = request_irq(FLOPPY_IRQ, sparc_floppy_irq, 260 IRQF_DISABLED, "floppy", NULL); 261 262 return ((error == 0) ? 0 : -1); 263 } 264 return 0; 265} 266 267static void sun_fd_free_irq(void) 268{ 269} 270 271static unsigned int sun_get_dma_residue(void) 272{ 273 return 0; 274} 275 276static int sun_fd_eject(int drive) 277{ 278 set_dor(0x00, 0xff, 0x90); 279 udelay(500); 280 set_dor(0x00, 0x6f, 0x00); 281 udelay(500); 282 return 0; 283} 284 285#include <asm/ebus_dma.h> 286#include <asm/ns87303.h> 287 288static struct ebus_dma_info sun_pci_fd_ebus_dma; 289static struct device *sun_floppy_dev; 290static int sun_pci_broken_drive = -1; 291 292struct sun_pci_dma_op { 293 unsigned int addr; 294 int len; 295 int direction; 296 char *buf; 297}; 298static struct sun_pci_dma_op sun_pci_dma_current = { -1U, 0, 0, NULL}; 299static struct sun_pci_dma_op sun_pci_dma_pending = { -1U, 0, 0, NULL}; 300 301extern irqreturn_t floppy_interrupt(int irq, void *dev_id); 302 303static unsigned char sun_pci_fd_inb(unsigned long port) 304{ 305 udelay(5); 306 return inb(port); 307} 308 309static void sun_pci_fd_outb(unsigned char val, unsigned long port) 310{ 311 udelay(5); 312 outb(val, port); 313} 314 315static void sun_pci_fd_broken_outb(unsigned char val, unsigned long port) 316{ 317 udelay(5); 318 if (port == ((unsigned long)sun_fdc) + 2) { 319 if (((val & 0x03) == sun_pci_broken_drive) && (val & 0x20)) { 320 val |= 0x10; 321 } 322 } 323 outb(val, port); 324} 325 326#ifdef PCI_FDC_SWAP_DRIVES 327static void sun_pci_fd_lde_broken_outb(unsigned char val, unsigned long port) 328{ 329 udelay(5); 330 if (port == ((unsigned long)sun_fdc) + 2) { 331 if (((val & 0x03) == sun_pci_broken_drive) && (val & 0x10)) { 332 val &= ~(0x03); 333 val |= 0x21; 334 } 335 } 336 outb(val, port); 337} 338#endif /* PCI_FDC_SWAP_DRIVES */ 339 340static void sun_pci_fd_enable_dma(void) 341{ 342 BUG_ON((NULL == sun_pci_dma_pending.buf) || 343 (0 == sun_pci_dma_pending.len) || 344 (0 == sun_pci_dma_pending.direction)); 345 346 sun_pci_dma_current.buf = sun_pci_dma_pending.buf; 347 sun_pci_dma_current.len = sun_pci_dma_pending.len; 348 sun_pci_dma_current.direction = sun_pci_dma_pending.direction; 349 350 sun_pci_dma_pending.buf = NULL; 351 sun_pci_dma_pending.len = 0; 352 sun_pci_dma_pending.direction = 0; 353 sun_pci_dma_pending.addr = -1U; 354 355 sun_pci_dma_current.addr = 356 dma_map_single(sun_floppy_dev, 357 sun_pci_dma_current.buf, 358 sun_pci_dma_current.len, 359 sun_pci_dma_current.direction); 360 361 ebus_dma_enable(&sun_pci_fd_ebus_dma, 1); 362 363 if (ebus_dma_request(&sun_pci_fd_ebus_dma, 364 sun_pci_dma_current.addr, 365 sun_pci_dma_current.len)) 366 BUG(); 367} 368 369static void sun_pci_fd_disable_dma(void) 370{ 371 ebus_dma_enable(&sun_pci_fd_ebus_dma, 0); 372 if (sun_pci_dma_current.addr != -1U) 373 dma_unmap_single(sun_floppy_dev, 374 sun_pci_dma_current.addr, 375 sun_pci_dma_current.len, 376 sun_pci_dma_current.direction); 377 sun_pci_dma_current.addr = -1U; 378} 379 380static void sun_pci_fd_set_dma_mode(int mode) 381{ 382 if (mode == DMA_MODE_WRITE) 383 sun_pci_dma_pending.direction = DMA_TO_DEVICE; 384 else 385 sun_pci_dma_pending.direction = DMA_FROM_DEVICE; 386 387 ebus_dma_prepare(&sun_pci_fd_ebus_dma, mode != DMA_MODE_WRITE); 388} 389 390static void sun_pci_fd_set_dma_count(int length) 391{ 392 sun_pci_dma_pending.len = length; 393} 394 395static void sun_pci_fd_set_dma_addr(char *buffer) 396{ 397 sun_pci_dma_pending.buf = buffer; 398} 399 400static unsigned int sun_pci_get_dma_residue(void) 401{ 402 return ebus_dma_residue(&sun_pci_fd_ebus_dma); 403} 404 405static int sun_pci_fd_request_irq(void) 406{ 407 return ebus_dma_irq_enable(&sun_pci_fd_ebus_dma, 1); 408} 409 410static void sun_pci_fd_free_irq(void) 411{ 412 ebus_dma_irq_enable(&sun_pci_fd_ebus_dma, 0); 413} 414 415static int sun_pci_fd_eject(int drive) 416{ 417 return -EINVAL; 418} 419 420void sun_pci_fd_dma_callback(struct ebus_dma_info *p, int event, void *cookie) 421{ 422 floppy_interrupt(0, NULL); 423} 424 425/* 426 * Floppy probing, we'd like to use /dev/fd0 for a single Floppy on PCI, 427 * even if this is configured using DS1, thus looks like /dev/fd1 with 428 * the cabling used in Ultras. 429 */ 430#define DOR (port + 2) 431#define MSR (port + 4) 432#define FIFO (port + 5) 433 434static void sun_pci_fd_out_byte(unsigned long port, unsigned char val, 435 unsigned long reg) 436{ 437 unsigned char status; 438 int timeout = 1000; 439 440 while (!((status = inb(MSR)) & 0x80) && --timeout) 441 udelay(100); 442 outb(val, reg); 443} 444 445static unsigned char sun_pci_fd_sensei(unsigned long port) 446{ 447 unsigned char result[2] = { 0x70, 0x00 }; 448 unsigned char status; 449 int i = 0; 450 451 sun_pci_fd_out_byte(port, 0x08, FIFO); 452 do { 453 int timeout = 1000; 454 455 while (!((status = inb(MSR)) & 0x80) && --timeout) 456 udelay(100); 457 458 if (!timeout) 459 break; 460 461 if ((status & 0xf0) == 0xd0) 462 result[i++] = inb(FIFO); 463 else 464 break; 465 } while (i < 2); 466 467 return result[0]; 468} 469 470static void sun_pci_fd_reset(unsigned long port) 471{ 472 unsigned char mask = 0x00; 473 unsigned char status; 474 int timeout = 10000; 475 476 outb(0x80, MSR); 477 do { 478 status = sun_pci_fd_sensei(port); 479 if ((status & 0xc0) == 0xc0) 480 mask |= 1 << (status & 0x03); 481 else 482 udelay(100); 483 } while ((mask != 0x0f) && --timeout); 484} 485 486static int sun_pci_fd_test_drive(unsigned long port, int drive) 487{ 488 unsigned char status, data; 489 int timeout = 1000; 490 int ready; 491 492 sun_pci_fd_reset(port); 493 494 data = (0x10 << drive) | 0x0c | drive; 495 sun_pci_fd_out_byte(port, data, DOR); 496 497 sun_pci_fd_out_byte(port, 0x07, FIFO); 498 sun_pci_fd_out_byte(port, drive & 0x03, FIFO); 499 500 do { 501 udelay(100); 502 status = sun_pci_fd_sensei(port); 503 } while (((status & 0xc0) == 0x80) && --timeout); 504 505 if (!timeout) 506 ready = 0; 507 else 508 ready = (status & 0x10) ? 0 : 1; 509 510 sun_pci_fd_reset(port); 511 return ready; 512} 513#undef FIFO 514#undef MSR 515#undef DOR 516 517static int __init ebus_fdthree_p(struct device_node *dp) 518{ 519 if (!strcmp(dp->name, "fdthree")) 520 return 1; 521 if (!strcmp(dp->name, "floppy")) { 522 const char *compat; 523 524 compat = of_get_property(dp, "compatible", NULL); 525 if (compat && !strcmp(compat, "fdthree")) 526 return 1; 527 } 528 return 0; 529} 530 531static unsigned long __init sun_floppy_init(void) 532{ 533 static int initialized = 0; 534 struct device_node *dp; 535 struct platform_device *op; 536 const char *prop; 537 char state[128]; 538 539 if (initialized) 540 return sun_floppy_types[0]; 541 initialized = 1; 542 543 op = NULL; 544 545 for_each_node_by_name(dp, "SUNW,fdtwo") { 546 if (strcmp(dp->parent->name, "sbus")) 547 continue; 548 op = of_find_device_by_node(dp); 549 if (op) 550 break; 551 } 552 if (op) { 553 floppy_op = op; 554 FLOPPY_IRQ = op->archdata.irqs[0]; 555 } else { 556 struct device_node *ebus_dp; 557 void __iomem *auxio_reg; 558 const char *state_prop; 559 unsigned long config; 560 561 dp = NULL; 562 for_each_node_by_name(ebus_dp, "ebus") { 563 for (dp = ebus_dp->child; dp; dp = dp->sibling) { 564 if (ebus_fdthree_p(dp)) 565 goto found_fdthree; 566 } 567 } 568 found_fdthree: 569 if (!dp) 570 return 0; 571 572 op = of_find_device_by_node(dp); 573 if (!op) 574 return 0; 575 576 state_prop = of_get_property(op->dev.of_node, "status", NULL); 577 if (state_prop && !strncmp(state_prop, "disabled", 8)) 578 return 0; 579 580 FLOPPY_IRQ = op->archdata.irqs[0]; 581 582 /* Make sure the high density bit is set, some systems 583 * (most notably Ultra5/Ultra10) come up with it clear. 584 */ 585 auxio_reg = (void __iomem *) op->resource[2].start; 586 writel(readl(auxio_reg)|0x2, auxio_reg); 587 588 sun_floppy_dev = &op->dev; 589 590 spin_lock_init(&sun_pci_fd_ebus_dma.lock); 591 592 sun_pci_fd_ebus_dma.regs = (void __iomem *) 593 op->resource[1].start; 594 if (!sun_pci_fd_ebus_dma.regs) 595 return 0; 596 597 sun_pci_fd_ebus_dma.flags = (EBUS_DMA_FLAG_USE_EBDMA_HANDLER | 598 EBUS_DMA_FLAG_TCI_DISABLE); 599 sun_pci_fd_ebus_dma.callback = sun_pci_fd_dma_callback; 600 sun_pci_fd_ebus_dma.client_cookie = NULL; 601 sun_pci_fd_ebus_dma.irq = FLOPPY_IRQ; 602 strcpy(sun_pci_fd_ebus_dma.name, "floppy"); 603 if (ebus_dma_register(&sun_pci_fd_ebus_dma)) 604 return 0; 605 606 sun_fdc = (struct sun_flpy_controller *) op->resource[0].start; 607 608 sun_fdops.fd_inb = sun_pci_fd_inb; 609 sun_fdops.fd_outb = sun_pci_fd_outb; 610 611 can_use_virtual_dma = use_virtual_dma = 0; 612 sun_fdops.fd_enable_dma = sun_pci_fd_enable_dma; 613 sun_fdops.fd_disable_dma = sun_pci_fd_disable_dma; 614 sun_fdops.fd_set_dma_mode = sun_pci_fd_set_dma_mode; 615 sun_fdops.fd_set_dma_addr = sun_pci_fd_set_dma_addr; 616 sun_fdops.fd_set_dma_count = sun_pci_fd_set_dma_count; 617 sun_fdops.get_dma_residue = sun_pci_get_dma_residue; 618 619 sun_fdops.fd_request_irq = sun_pci_fd_request_irq; 620 sun_fdops.fd_free_irq = sun_pci_fd_free_irq; 621 622 sun_fdops.fd_eject = sun_pci_fd_eject; 623 624 fdc_status = (unsigned long) &sun_fdc->status_82077; 625 626 if (1) { 627 sun_pci_broken_drive = 1; 628 sun_fdops.fd_outb = sun_pci_fd_broken_outb; 629 } 630 631 allowed_drive_mask = 0; 632 if (sun_pci_fd_test_drive((unsigned long)sun_fdc, 0)) 633 sun_floppy_types[0] = 4; 634 if (sun_pci_fd_test_drive((unsigned long)sun_fdc, 1)) 635 sun_floppy_types[1] = 4; 636 637 /* 638 * Find NS87303 SuperIO config registers (through ecpp). 639 */ 640 config = 0; 641 for (dp = ebus_dp->child; dp; dp = dp->sibling) { 642 if (!strcmp(dp->name, "ecpp")) { 643 struct platform_device *ecpp_op; 644 645 ecpp_op = of_find_device_by_node(dp); 646 if (ecpp_op) 647 config = ecpp_op->resource[1].start; 648 goto config_done; 649 } 650 } 651 config_done: 652 653 /* 654 * Sanity check, is this really the NS87303? 655 */ 656 switch (config & 0x3ff) { 657 case 0x02e: 658 case 0x15c: 659 case 0x26e: 660 case 0x398: 661 break; 662 default: 663 config = 0; 664 } 665 666 if (!config) 667 return sun_floppy_types[0]; 668 669 /* Enable PC-AT mode. */ 670 ns87303_modify(config, ASC, 0, 0xc0); 671 672#ifdef PCI_FDC_SWAP_DRIVES 673 /* 674 * If only Floppy 1 is present, swap drives. 675 */ 676 if (!sun_floppy_types[0] && sun_floppy_types[1]) { 677 /* 678 * Set the drive exchange bit in FCR on NS87303, 679 * make sure other bits are sane before doing so. 680 */ 681 ns87303_modify(config, FER, FER_EDM, 0); 682 ns87303_modify(config, ASC, ASC_DRV2_SEL, 0); 683 ns87303_modify(config, FCR, 0, FCR_LDE); 684 685 config = sun_floppy_types[0]; 686 sun_floppy_types[0] = sun_floppy_types[1]; 687 sun_floppy_types[1] = config; 688 689 if (sun_pci_broken_drive != -1) { 690 sun_pci_broken_drive = 1 - sun_pci_broken_drive; 691 sun_fdops.fd_outb = sun_pci_fd_lde_broken_outb; 692 } 693 } 694#endif /* PCI_FDC_SWAP_DRIVES */ 695 696 return sun_floppy_types[0]; 697 } 698 prop = of_get_property(op->dev.of_node, "status", NULL); 699 if (prop && !strncmp(state, "disabled", 8)) 700 return 0; 701 702 /* 703 * We cannot do of_ioremap here: it does request_region, 704 * which the generic floppy driver tries to do once again. 705 * But we must use the sdev resource values as they have 706 * had parent ranges applied. 707 */ 708 sun_fdc = (struct sun_flpy_controller *) 709 (op->resource[0].start + 710 ((op->resource[0].flags & 0x1ffUL) << 32UL)); 711 712 /* Last minute sanity check... */ 713 if (sbus_readb(&sun_fdc->status1_82077) == 0xff) { 714 sun_fdc = (struct sun_flpy_controller *)-1; 715 return 0; 716 } 717 718 sun_fdops.fd_inb = sun_82077_fd_inb; 719 sun_fdops.fd_outb = sun_82077_fd_outb; 720 721 can_use_virtual_dma = use_virtual_dma = 1; 722 sun_fdops.fd_enable_dma = sun_fd_enable_dma; 723 sun_fdops.fd_disable_dma = sun_fd_disable_dma; 724 sun_fdops.fd_set_dma_mode = sun_fd_set_dma_mode; 725 sun_fdops.fd_set_dma_addr = sun_fd_set_dma_addr; 726 sun_fdops.fd_set_dma_count = sun_fd_set_dma_count; 727 sun_fdops.get_dma_residue = sun_get_dma_residue; 728 729 sun_fdops.fd_request_irq = sun_fd_request_irq; 730 sun_fdops.fd_free_irq = sun_fd_free_irq; 731 732 sun_fdops.fd_eject = sun_fd_eject; 733 734 fdc_status = (unsigned long) &sun_fdc->status_82077; 735 736 /* Success... */ 737 allowed_drive_mask = 0x01; 738 sun_floppy_types[0] = 4; 739 sun_floppy_types[1] = 0; 740 741 return sun_floppy_types[0]; 742} 743 744#define EXTRA_FLOPPY_PARAMS 745 746static DEFINE_SPINLOCK(dma_spin_lock); 747 748#define claim_dma_lock() \ 749({ unsigned long flags; \ 750 spin_lock_irqsave(&dma_spin_lock, flags); \ 751 flags; \ 752}) 753 754#define release_dma_lock(__flags) \ 755 spin_unlock_irqrestore(&dma_spin_lock, __flags); 756 757#endif /* !(__ASM_SPARC64_FLOPPY_H) */ 758