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