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 */ 30 struct 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. */ 44 static struct sun_flpy_controller *sun_fdc = (struct sun_flpy_controller *)-1; 45 unsigned long fdc_status; 46 static struct platform_device *floppy_op = NULL; 47 48 struct 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 62 static 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 83 static 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 100 static 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 /* XXX: Is DCL on 0x80 in sun4m? */ 113 return sbus_readb(&sun_fdc->dir_82077); 114 } 115 panic("sun_82072_fd_inb: How did I get here?"); 116 } 117 118 static void sun_82077_fd_outb(unsigned char value, unsigned long port) 119 { 120 udelay(5); 121 switch(port & 7) { 122 default: 123 printk("floppy: Asked to write to unknown port %lx\n", port); 124 panic("floppy: Port bolixed."); 125 case 2: /* FD_DOR */ 126 /* Happily, the 82077 has a real DOR register. */ 127 sbus_writeb(value, &sun_fdc->dor_82077); 128 break; 129 case 5: /* FD_DATA */ 130 sbus_writeb(value, &sun_fdc->data_82077); 131 break; 132 case 7: /* FD_DCR */ 133 sbus_writeb(value, &sun_fdc->dcr_82077); 134 break; 135 case 4: /* FD_STATUS */ 136 sbus_writeb(value, &sun_fdc->status_82077); 137 break; 138 } 139 return; 140 } 141 142 /* For pseudo-dma (Sun floppy drives have no real DMA available to 143 * them so we must eat the data fifo bytes directly ourselves) we have 144 * three state variables. doing_pdma tells our inline low-level 145 * assembly floppy interrupt entry point whether it should sit and eat 146 * bytes from the fifo or just transfer control up to the higher level 147 * floppy interrupt c-code. I tried very hard but I could not get the 148 * pseudo-dma to work in c-code without getting many overruns and 149 * underruns. If non-zero, doing_pdma encodes the direction of 150 * the transfer for debugging. 1=read 2=write 151 */ 152 unsigned char *pdma_vaddr; 153 unsigned long pdma_size; 154 volatile int doing_pdma = 0; 155 156 /* This is software state */ 157 char *pdma_base = NULL; 158 unsigned long pdma_areasize; 159 160 /* Common routines to all controller types on the Sparc. */ 161 static void sun_fd_disable_dma(void) 162 { 163 doing_pdma = 0; 164 if (pdma_base) { 165 mmu_unlockarea(pdma_base, pdma_areasize); 166 pdma_base = NULL; 167 } 168 } 169 170 static void sun_fd_set_dma_mode(int mode) 171 { 172 switch(mode) { 173 case DMA_MODE_READ: 174 doing_pdma = 1; 175 break; 176 case DMA_MODE_WRITE: 177 doing_pdma = 2; 178 break; 179 default: 180 printk("Unknown dma mode %d\n", mode); 181 panic("floppy: Giving up..."); 182 } 183 } 184 185 static void sun_fd_set_dma_addr(char *buffer) 186 { 187 pdma_vaddr = buffer; 188 } 189 190 static void sun_fd_set_dma_count(int length) 191 { 192 pdma_size = length; 193 } 194 195 static void sun_fd_enable_dma(void) 196 { 197 pdma_vaddr = mmu_lockarea(pdma_vaddr, pdma_size); 198 pdma_base = pdma_vaddr; 199 pdma_areasize = pdma_size; 200 } 201 202 irqreturn_t sparc_floppy_irq(int irq, void *dev_cookie) 203 { 204 if (likely(doing_pdma)) { 205 void __iomem *stat = (void __iomem *) fdc_status; 206 unsigned char *vaddr = pdma_vaddr; 207 unsigned long size = pdma_size; 208 u8 val; 209 210 while (size) { 211 val = readb(stat); 212 if (unlikely(!(val & 0x80))) { 213 pdma_vaddr = vaddr; 214 pdma_size = size; 215 return IRQ_HANDLED; 216 } 217 if (unlikely(!(val & 0x20))) { 218 pdma_vaddr = vaddr; 219 pdma_size = size; 220 doing_pdma = 0; 221 goto main_interrupt; 222 } 223 if (val & 0x40) { 224 /* read */ 225 *vaddr++ = readb(stat + 1); 226 } else { 227 unsigned char data = *vaddr++; 228 229 /* write */ 230 writeb(data, stat + 1); 231 } 232 size--; 233 } 234 235 pdma_vaddr = vaddr; 236 pdma_size = size; 237 238 /* Send Terminal Count pulse to floppy controller. */ 239 val = readb(auxio_register); 240 val |= AUXIO_AUX1_FTCNT; 241 writeb(val, auxio_register); 242 val &= ~AUXIO_AUX1_FTCNT; 243 writeb(val, auxio_register); 244 245 doing_pdma = 0; 246 } 247 248 main_interrupt: 249 return floppy_interrupt(irq, dev_cookie); 250 } 251 252 static int sun_fd_request_irq(void) 253 { 254 static int once = 0; 255 int error; 256 257 if(!once) { 258 once = 1; 259 260 error = request_irq(FLOPPY_IRQ, sparc_floppy_irq, 261 IRQF_DISABLED, "floppy", NULL); 262 263 return ((error == 0) ? 0 : -1); 264 } 265 return 0; 266 } 267 268 static void sun_fd_free_irq(void) 269 { 270 } 271 272 static unsigned int sun_get_dma_residue(void) 273 { 274 /* XXX This isn't really correct. XXX */ 275 return 0; 276 } 277 278 static int sun_fd_eject(int drive) 279 { 280 set_dor(0x00, 0xff, 0x90); 281 udelay(500); 282 set_dor(0x00, 0x6f, 0x00); 283 udelay(500); 284 return 0; 285 } 286 287 #include <asm/ebus_dma.h> 288 #include <asm/ns87303.h> 289 290 static struct ebus_dma_info sun_pci_fd_ebus_dma; 291 static struct device *sun_floppy_dev; 292 static int sun_pci_broken_drive = -1; 293 294 struct sun_pci_dma_op { 295 unsigned int addr; 296 int len; 297 int direction; 298 char *buf; 299 }; 300 static struct sun_pci_dma_op sun_pci_dma_current = { -1U, 0, 0, NULL}; 301 static struct sun_pci_dma_op sun_pci_dma_pending = { -1U, 0, 0, NULL}; 302 303 extern irqreturn_t floppy_interrupt(int irq, void *dev_id); 304 305 static unsigned char sun_pci_fd_inb(unsigned long port) 306 { 307 udelay(5); 308 return inb(port); 309 } 310 311 static void sun_pci_fd_outb(unsigned char val, unsigned long port) 312 { 313 udelay(5); 314 outb(val, port); 315 } 316 317 static void sun_pci_fd_broken_outb(unsigned char val, unsigned long port) 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 (port == ((unsigned long)sun_fdc) + 2) { 328 if (((val & 0x03) == sun_pci_broken_drive) && (val & 0x20)) { 329 val |= 0x10; 330 } 331 } 332 outb(val, port); 333 } 334 335 #ifdef PCI_FDC_SWAP_DRIVES 336 static void sun_pci_fd_lde_broken_outb(unsigned char val, unsigned long port) 337 { 338 udelay(5); 339 /* 340 * XXX: Due to SUN's broken floppy connector on AX and AXi 341 * we need to turn on MOTOR_0 also, if the floppy is 342 * jumpered to DS1 (like most PC floppies are). I hope 343 * this does not hurt correct hardware like the AXmp. 344 * (Eddie, Sep 12 1998). 345 */ 346 if (port == ((unsigned long)sun_fdc) + 2) { 347 if (((val & 0x03) == sun_pci_broken_drive) && (val & 0x10)) { 348 val &= ~(0x03); 349 val |= 0x21; 350 } 351 } 352 outb(val, port); 353 } 354 #endif /* PCI_FDC_SWAP_DRIVES */ 355 356 static void sun_pci_fd_enable_dma(void) 357 { 358 BUG_ON((NULL == sun_pci_dma_pending.buf) || 359 (0 == sun_pci_dma_pending.len) || 360 (0 == sun_pci_dma_pending.direction)); 361 362 sun_pci_dma_current.buf = sun_pci_dma_pending.buf; 363 sun_pci_dma_current.len = sun_pci_dma_pending.len; 364 sun_pci_dma_current.direction = sun_pci_dma_pending.direction; 365 366 sun_pci_dma_pending.buf = NULL; 367 sun_pci_dma_pending.len = 0; 368 sun_pci_dma_pending.direction = 0; 369 sun_pci_dma_pending.addr = -1U; 370 371 sun_pci_dma_current.addr = 372 dma_map_single(sun_floppy_dev, 373 sun_pci_dma_current.buf, 374 sun_pci_dma_current.len, 375 sun_pci_dma_current.direction); 376 377 ebus_dma_enable(&sun_pci_fd_ebus_dma, 1); 378 379 if (ebus_dma_request(&sun_pci_fd_ebus_dma, 380 sun_pci_dma_current.addr, 381 sun_pci_dma_current.len)) 382 BUG(); 383 } 384 385 static void sun_pci_fd_disable_dma(void) 386 { 387 ebus_dma_enable(&sun_pci_fd_ebus_dma, 0); 388 if (sun_pci_dma_current.addr != -1U) 389 dma_unmap_single(sun_floppy_dev, 390 sun_pci_dma_current.addr, 391 sun_pci_dma_current.len, 392 sun_pci_dma_current.direction); 393 sun_pci_dma_current.addr = -1U; 394 } 395 396 static void sun_pci_fd_set_dma_mode(int mode) 397 { 398 if (mode == DMA_MODE_WRITE) 399 sun_pci_dma_pending.direction = DMA_TO_DEVICE; 400 else 401 sun_pci_dma_pending.direction = DMA_FROM_DEVICE; 402 403 ebus_dma_prepare(&sun_pci_fd_ebus_dma, mode != DMA_MODE_WRITE); 404 } 405 406 static void sun_pci_fd_set_dma_count(int length) 407 { 408 sun_pci_dma_pending.len = length; 409 } 410 411 static void sun_pci_fd_set_dma_addr(char *buffer) 412 { 413 sun_pci_dma_pending.buf = buffer; 414 } 415 416 static unsigned int sun_pci_get_dma_residue(void) 417 { 418 return ebus_dma_residue(&sun_pci_fd_ebus_dma); 419 } 420 421 static int sun_pci_fd_request_irq(void) 422 { 423 return ebus_dma_irq_enable(&sun_pci_fd_ebus_dma, 1); 424 } 425 426 static void sun_pci_fd_free_irq(void) 427 { 428 ebus_dma_irq_enable(&sun_pci_fd_ebus_dma, 0); 429 } 430 431 static int sun_pci_fd_eject(int drive) 432 { 433 return -EINVAL; 434 } 435 436 void sun_pci_fd_dma_callback(struct ebus_dma_info *p, int event, void *cookie) 437 { 438 floppy_interrupt(0, NULL); 439 } 440 441 /* 442 * Floppy probing, we'd like to use /dev/fd0 for a single Floppy on PCI, 443 * even if this is configured using DS1, thus looks like /dev/fd1 with 444 * the cabling used in Ultras. 445 */ 446 #define DOR (port + 2) 447 #define MSR (port + 4) 448 #define FIFO (port + 5) 449 450 static void sun_pci_fd_out_byte(unsigned long port, unsigned char val, 451 unsigned long reg) 452 { 453 unsigned char status; 454 int timeout = 1000; 455 456 while (!((status = inb(MSR)) & 0x80) && --timeout) 457 udelay(100); 458 outb(val, reg); 459 } 460 461 static unsigned char sun_pci_fd_sensei(unsigned long port) 462 { 463 unsigned char result[2] = { 0x70, 0x00 }; 464 unsigned char status; 465 int i = 0; 466 467 sun_pci_fd_out_byte(port, 0x08, FIFO); 468 do { 469 int timeout = 1000; 470 471 while (!((status = inb(MSR)) & 0x80) && --timeout) 472 udelay(100); 473 474 if (!timeout) 475 break; 476 477 if ((status & 0xf0) == 0xd0) 478 result[i++] = inb(FIFO); 479 else 480 break; 481 } while (i < 2); 482 483 return result[0]; 484 } 485 486 static void sun_pci_fd_reset(unsigned long port) 487 { 488 unsigned char mask = 0x00; 489 unsigned char status; 490 int timeout = 10000; 491 492 outb(0x80, MSR); 493 do { 494 status = sun_pci_fd_sensei(port); 495 if ((status & 0xc0) == 0xc0) 496 mask |= 1 << (status & 0x03); 497 else 498 udelay(100); 499 } while ((mask != 0x0f) && --timeout); 500 } 501 502 static int sun_pci_fd_test_drive(unsigned long port, int drive) 503 { 504 unsigned char status, data; 505 int timeout = 1000; 506 int ready; 507 508 sun_pci_fd_reset(port); 509 510 data = (0x10 << drive) | 0x0c | drive; 511 sun_pci_fd_out_byte(port, data, DOR); 512 513 sun_pci_fd_out_byte(port, 0x07, FIFO); 514 sun_pci_fd_out_byte(port, drive & 0x03, FIFO); 515 516 do { 517 udelay(100); 518 status = sun_pci_fd_sensei(port); 519 } while (((status & 0xc0) == 0x80) && --timeout); 520 521 if (!timeout) 522 ready = 0; 523 else 524 ready = (status & 0x10) ? 0 : 1; 525 526 sun_pci_fd_reset(port); 527 return ready; 528 } 529 #undef FIFO 530 #undef MSR 531 #undef DOR 532 533 static int __init ebus_fdthree_p(struct device_node *dp) 534 { 535 if (!strcmp(dp->name, "fdthree")) 536 return 1; 537 if (!strcmp(dp->name, "floppy")) { 538 const char *compat; 539 540 compat = of_get_property(dp, "compatible", NULL); 541 if (compat && !strcmp(compat, "fdthree")) 542 return 1; 543 } 544 return 0; 545 } 546 547 static unsigned long __init sun_floppy_init(void) 548 { 549 static int initialized = 0; 550 struct device_node *dp; 551 struct platform_device *op; 552 const char *prop; 553 char state[128]; 554 555 if (initialized) 556 return sun_floppy_types[0]; 557 initialized = 1; 558 559 op = NULL; 560 561 for_each_node_by_name(dp, "SUNW,fdtwo") { 562 if (strcmp(dp->parent->name, "sbus")) 563 continue; 564 op = of_find_device_by_node(dp); 565 if (op) 566 break; 567 } 568 if (op) { 569 floppy_op = op; 570 FLOPPY_IRQ = op->archdata.irqs[0]; 571 } else { 572 struct device_node *ebus_dp; 573 void __iomem *auxio_reg; 574 const char *state_prop; 575 unsigned long config; 576 577 dp = NULL; 578 for_each_node_by_name(ebus_dp, "ebus") { 579 for (dp = ebus_dp->child; dp; dp = dp->sibling) { 580 if (ebus_fdthree_p(dp)) 581 goto found_fdthree; 582 } 583 } 584 found_fdthree: 585 if (!dp) 586 return 0; 587 588 op = of_find_device_by_node(dp); 589 if (!op) 590 return 0; 591 592 state_prop = of_get_property(op->dev.of_node, "status", NULL); 593 if (state_prop && !strncmp(state_prop, "disabled", 8)) 594 return 0; 595 596 FLOPPY_IRQ = op->archdata.irqs[0]; 597 598 /* Make sure the high density bit is set, some systems 599 * (most notably Ultra5/Ultra10) come up with it clear. 600 */ 601 auxio_reg = (void __iomem *) op->resource[2].start; 602 writel(readl(auxio_reg)|0x2, auxio_reg); 603 604 sun_floppy_dev = &op->dev; 605 606 spin_lock_init(&sun_pci_fd_ebus_dma.lock); 607 608 /* XXX ioremap */ 609 sun_pci_fd_ebus_dma.regs = (void __iomem *) 610 op->resource[1].start; 611 if (!sun_pci_fd_ebus_dma.regs) 612 return 0; 613 614 sun_pci_fd_ebus_dma.flags = (EBUS_DMA_FLAG_USE_EBDMA_HANDLER | 615 EBUS_DMA_FLAG_TCI_DISABLE); 616 sun_pci_fd_ebus_dma.callback = sun_pci_fd_dma_callback; 617 sun_pci_fd_ebus_dma.client_cookie = NULL; 618 sun_pci_fd_ebus_dma.irq = FLOPPY_IRQ; 619 strcpy(sun_pci_fd_ebus_dma.name, "floppy"); 620 if (ebus_dma_register(&sun_pci_fd_ebus_dma)) 621 return 0; 622 623 /* XXX ioremap */ 624 sun_fdc = (struct sun_flpy_controller *) op->resource[0].start; 625 626 sun_fdops.fd_inb = sun_pci_fd_inb; 627 sun_fdops.fd_outb = sun_pci_fd_outb; 628 629 can_use_virtual_dma = use_virtual_dma = 0; 630 sun_fdops.fd_enable_dma = sun_pci_fd_enable_dma; 631 sun_fdops.fd_disable_dma = sun_pci_fd_disable_dma; 632 sun_fdops.fd_set_dma_mode = sun_pci_fd_set_dma_mode; 633 sun_fdops.fd_set_dma_addr = sun_pci_fd_set_dma_addr; 634 sun_fdops.fd_set_dma_count = sun_pci_fd_set_dma_count; 635 sun_fdops.get_dma_residue = sun_pci_get_dma_residue; 636 637 sun_fdops.fd_request_irq = sun_pci_fd_request_irq; 638 sun_fdops.fd_free_irq = sun_pci_fd_free_irq; 639 640 sun_fdops.fd_eject = sun_pci_fd_eject; 641 642 fdc_status = (unsigned long) &sun_fdc->status_82077; 643 644 /* 645 * XXX: Find out on which machines this is really needed. 646 */ 647 if (1) { 648 sun_pci_broken_drive = 1; 649 sun_fdops.fd_outb = sun_pci_fd_broken_outb; 650 } 651 652 allowed_drive_mask = 0; 653 if (sun_pci_fd_test_drive((unsigned long)sun_fdc, 0)) 654 sun_floppy_types[0] = 4; 655 if (sun_pci_fd_test_drive((unsigned long)sun_fdc, 1)) 656 sun_floppy_types[1] = 4; 657 658 /* 659 * Find NS87303 SuperIO config registers (through ecpp). 660 */ 661 config = 0; 662 for (dp = ebus_dp->child; dp; dp = dp->sibling) { 663 if (!strcmp(dp->name, "ecpp")) { 664 struct platform_device *ecpp_op; 665 666 ecpp_op = of_find_device_by_node(dp); 667 if (ecpp_op) 668 config = ecpp_op->resource[1].start; 669 goto config_done; 670 } 671 } 672 config_done: 673 674 /* 675 * Sanity check, is this really the NS87303? 676 */ 677 switch (config & 0x3ff) { 678 case 0x02e: 679 case 0x15c: 680 case 0x26e: 681 case 0x398: 682 break; 683 default: 684 config = 0; 685 } 686 687 if (!config) 688 return sun_floppy_types[0]; 689 690 /* Enable PC-AT mode. */ 691 ns87303_modify(config, ASC, 0, 0xc0); 692 693 #ifdef PCI_FDC_SWAP_DRIVES 694 /* 695 * If only Floppy 1 is present, swap drives. 696 */ 697 if (!sun_floppy_types[0] && sun_floppy_types[1]) { 698 /* 699 * Set the drive exchange bit in FCR on NS87303, 700 * make sure other bits are sane before doing so. 701 */ 702 ns87303_modify(config, FER, FER_EDM, 0); 703 ns87303_modify(config, ASC, ASC_DRV2_SEL, 0); 704 ns87303_modify(config, FCR, 0, FCR_LDE); 705 706 config = sun_floppy_types[0]; 707 sun_floppy_types[0] = sun_floppy_types[1]; 708 sun_floppy_types[1] = config; 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