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