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