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