home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / src / linux-headers-2.6.17-6 / include / asm-sparc64 / floppy.h < prev    next >
Encoding:
C/C++ Source or Header  |  2006-08-11  |  20.1 KB  |  811 lines

  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.  */
  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. static int FLOPPY_MOTOR_MASK = 0x10;
  88.  
  89. /* Super paranoid... */
  90. #undef HAVE_DISABLE_HLT
  91.  
  92. static 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.  
  109. static 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.  
  127. static 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.  */
  161. unsigned char *pdma_vaddr;
  162. unsigned long pdma_size;
  163. volatile int doing_pdma = 0;
  164.  
  165. /* This is software state */
  166. char *pdma_base = NULL;
  167. unsigned long pdma_areasize;
  168.  
  169. /* Common routines to all controller types on the Sparc. */
  170. static 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.  
  179. static 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.  
  194. static void sun_fd_set_dma_addr(char *buffer)
  195. {
  196.     pdma_vaddr = buffer;
  197. }
  198.  
  199. static void sun_fd_set_dma_count(int length)
  200. {
  201.     pdma_size = length;
  202. }
  203.  
  204. static 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.  
  211. extern irqreturn_t sparc_floppy_irq(int, void *, struct pt_regs *);
  212.  
  213. static int sun_fd_request_irq(void)
  214. {
  215.     static int once = 0;
  216.     int error;
  217.  
  218.     if(!once) {
  219.         once = 1;
  220.  
  221.         error = request_irq(FLOPPY_IRQ, sparc_floppy_irq, 
  222.                     SA_INTERRUPT, "floppy", NULL);
  223.  
  224.         return ((error == 0) ? 0 : -1);
  225.     }
  226.     return 0;
  227. }
  228.  
  229. static void sun_fd_free_irq(void)
  230. {
  231. }
  232.  
  233. static unsigned int sun_get_dma_residue(void)
  234. {
  235.     /* XXX This isn't really correct. XXX */
  236.     return 0;
  237. }
  238.  
  239. static int sun_fd_eject(int drive)
  240. {
  241.     set_dor(0x00, 0xff, 0x90);
  242.     udelay(500);
  243.     set_dor(0x00, 0x6f, 0x00);
  244.     udelay(500);
  245.     return 0;
  246. }
  247.  
  248. #ifdef CONFIG_PCI
  249. #include <asm/ebus.h>
  250. #include <asm/isa.h>
  251. #include <asm/ns87303.h>
  252.  
  253. static struct ebus_dma_info sun_pci_fd_ebus_dma;
  254. static struct pci_dev *sun_pci_ebus_dev;
  255. static int sun_pci_broken_drive = -1;
  256.  
  257. struct sun_pci_dma_op {
  258.     unsigned int     addr;
  259.     int        len;
  260.     int        direction;
  261.     char        *buf;
  262. };
  263. static struct sun_pci_dma_op sun_pci_dma_current = { -1U, 0, 0, NULL};
  264. static struct sun_pci_dma_op sun_pci_dma_pending = { -1U, 0, 0, NULL};
  265.  
  266. extern irqreturn_t floppy_interrupt(int irq, void *dev_id, struct pt_regs *regs);
  267.  
  268. static unsigned char sun_pci_fd_inb(unsigned long port)
  269. {
  270.     udelay(5);
  271.     return inb(port);
  272. }
  273.  
  274. static void sun_pci_fd_outb(unsigned char val, unsigned long port)
  275. {
  276.     udelay(5);
  277.     outb(val, port);
  278. }
  279.  
  280. static void sun_pci_fd_broken_outb(unsigned char val, unsigned long port)
  281. {
  282.     udelay(5);
  283.     /*
  284.      * XXX: Due to SUN's broken floppy connector on AX and AXi
  285.      *      we need to turn on MOTOR_0 also, if the floppy is
  286.      *      jumpered to DS1 (like most PC floppies are). I hope
  287.      *      this does not hurt correct hardware like the AXmp.
  288.      *      (Eddie, Sep 12 1998).
  289.      */
  290.     if (port == ((unsigned long)sun_fdc) + 2) {
  291.         if (((val & 0x03) == sun_pci_broken_drive) && (val & 0x20)) {
  292.             val |= 0x10;
  293.         }
  294.     }
  295.     outb(val, port);
  296. }
  297.  
  298. #ifdef PCI_FDC_SWAP_DRIVES
  299. static void sun_pci_fd_lde_broken_outb(unsigned char val, unsigned long port)
  300. {
  301.     udelay(5);
  302.     /*
  303.      * XXX: Due to SUN's broken floppy connector on AX and AXi
  304.      *      we need to turn on MOTOR_0 also, if the floppy is
  305.      *      jumpered to DS1 (like most PC floppies are). I hope
  306.      *      this does not hurt correct hardware like the AXmp.
  307.      *      (Eddie, Sep 12 1998).
  308.      */
  309.     if (port == ((unsigned long)sun_fdc) + 2) {
  310.         if (((val & 0x03) == sun_pci_broken_drive) && (val & 0x10)) {
  311.             val &= ~(0x03);
  312.             val |= 0x21;
  313.         }
  314.     }
  315.     outb(val, port);
  316. }
  317. #endif /* PCI_FDC_SWAP_DRIVES */
  318.  
  319. static void sun_pci_fd_enable_dma(void)
  320. {
  321.     BUG_ON((NULL == sun_pci_dma_pending.buf)     ||
  322.         (0      == sun_pci_dma_pending.len)     ||
  323.         (0      == sun_pci_dma_pending.direction));
  324.  
  325.     sun_pci_dma_current.buf = sun_pci_dma_pending.buf;
  326.     sun_pci_dma_current.len = sun_pci_dma_pending.len;
  327.     sun_pci_dma_current.direction = sun_pci_dma_pending.direction;
  328.  
  329.     sun_pci_dma_pending.buf  = NULL;
  330.     sun_pci_dma_pending.len  = 0;
  331.     sun_pci_dma_pending.direction = 0;
  332.     sun_pci_dma_pending.addr = -1U;
  333.  
  334.     sun_pci_dma_current.addr = 
  335.         pci_map_single(sun_pci_ebus_dev,
  336.                    sun_pci_dma_current.buf,
  337.                    sun_pci_dma_current.len,
  338.                    sun_pci_dma_current.direction);
  339.  
  340.     ebus_dma_enable(&sun_pci_fd_ebus_dma, 1);
  341.  
  342.     if (ebus_dma_request(&sun_pci_fd_ebus_dma,
  343.                  sun_pci_dma_current.addr,
  344.                  sun_pci_dma_current.len))
  345.         BUG();
  346. }
  347.  
  348. static void sun_pci_fd_disable_dma(void)
  349. {
  350.     ebus_dma_enable(&sun_pci_fd_ebus_dma, 0);
  351.     if (sun_pci_dma_current.addr != -1U)
  352.         pci_unmap_single(sun_pci_ebus_dev,
  353.                  sun_pci_dma_current.addr,
  354.                  sun_pci_dma_current.len,
  355.                  sun_pci_dma_current.direction);
  356.     sun_pci_dma_current.addr = -1U;
  357. }
  358.  
  359. static void sun_pci_fd_set_dma_mode(int mode)
  360. {
  361.     if (mode == DMA_MODE_WRITE)
  362.         sun_pci_dma_pending.direction = PCI_DMA_TODEVICE;
  363.     else
  364.         sun_pci_dma_pending.direction = PCI_DMA_FROMDEVICE;
  365.  
  366.     ebus_dma_prepare(&sun_pci_fd_ebus_dma, mode != DMA_MODE_WRITE);
  367. }
  368.  
  369. static void sun_pci_fd_set_dma_count(int length)
  370. {
  371.     sun_pci_dma_pending.len = length;
  372. }
  373.  
  374. static void sun_pci_fd_set_dma_addr(char *buffer)
  375. {
  376.     sun_pci_dma_pending.buf = buffer;
  377. }
  378.  
  379. static unsigned int sun_pci_get_dma_residue(void)
  380. {
  381.     return ebus_dma_residue(&sun_pci_fd_ebus_dma);
  382. }
  383.  
  384. static int sun_pci_fd_request_irq(void)
  385. {
  386.     return ebus_dma_irq_enable(&sun_pci_fd_ebus_dma, 1);
  387. }
  388.  
  389. static void sun_pci_fd_free_irq(void)
  390. {
  391.     ebus_dma_irq_enable(&sun_pci_fd_ebus_dma, 0);
  392. }
  393.  
  394. static int sun_pci_fd_eject(int drive)
  395. {
  396.     return -EINVAL;
  397. }
  398.  
  399. void sun_pci_fd_dma_callback(struct ebus_dma_info *p, int event, void *cookie)
  400. {
  401.     floppy_interrupt(0, NULL, NULL);
  402. }
  403.  
  404. /*
  405.  * Floppy probing, we'd like to use /dev/fd0 for a single Floppy on PCI,
  406.  * even if this is configured using DS1, thus looks like /dev/fd1 with
  407.  * the cabling used in Ultras.
  408.  */
  409. #define DOR    (port + 2)
  410. #define MSR    (port + 4)
  411. #define FIFO    (port + 5)
  412.  
  413. static void sun_pci_fd_out_byte(unsigned long port, unsigned char val,
  414.                     unsigned long reg)
  415. {
  416.     unsigned char status;
  417.     int timeout = 1000;
  418.  
  419.     while (!((status = inb(MSR)) & 0x80) && --timeout)
  420.         udelay(100);
  421.     outb(val, reg);
  422. }
  423.  
  424. static unsigned char sun_pci_fd_sensei(unsigned long port)
  425. {
  426.     unsigned char result[2] = { 0x70, 0x00 };
  427.     unsigned char status;
  428.     int i = 0;
  429.  
  430.     sun_pci_fd_out_byte(port, 0x08, FIFO);
  431.     do {
  432.         int timeout = 1000;
  433.  
  434.         while (!((status = inb(MSR)) & 0x80) && --timeout)
  435.             udelay(100);
  436.  
  437.         if (!timeout)
  438.             break;
  439.  
  440.         if ((status & 0xf0) == 0xd0)
  441.             result[i++] = inb(FIFO);
  442.         else
  443.             break;
  444.     } while (i < 2);
  445.  
  446.     return result[0];
  447. }
  448.  
  449. static void sun_pci_fd_reset(unsigned long port)
  450. {
  451.     unsigned char mask = 0x00;
  452.     unsigned char status;
  453.     int timeout = 10000;
  454.  
  455.     outb(0x80, MSR);
  456.     do {
  457.         status = sun_pci_fd_sensei(port);
  458.         if ((status & 0xc0) == 0xc0)
  459.             mask |= 1 << (status & 0x03);
  460.         else
  461.             udelay(100);
  462.     } while ((mask != 0x0f) && --timeout);
  463. }
  464.  
  465. static int sun_pci_fd_test_drive(unsigned long port, int drive)
  466. {
  467.     unsigned char status, data;
  468.     int timeout = 1000;
  469.     int ready;
  470.  
  471.     sun_pci_fd_reset(port);
  472.  
  473.     data = (0x10 << drive) | 0x0c | drive;
  474.     sun_pci_fd_out_byte(port, data, DOR);
  475.  
  476.     sun_pci_fd_out_byte(port, 0x07, FIFO);
  477.     sun_pci_fd_out_byte(port, drive & 0x03, FIFO);
  478.  
  479.     do {
  480.         udelay(100);
  481.         status = sun_pci_fd_sensei(port);
  482.     } while (((status & 0xc0) == 0x80) && --timeout);
  483.  
  484.     if (!timeout)
  485.         ready = 0;
  486.     else
  487.         ready = (status & 0x10) ? 0 : 1;
  488.  
  489.     sun_pci_fd_reset(port);
  490.     return ready;
  491. }
  492. #undef FIFO
  493. #undef MSR
  494. #undef DOR
  495.  
  496. #endif /* CONFIG_PCI */
  497.  
  498. #ifdef CONFIG_PCI
  499. static int __init ebus_fdthree_p(struct linux_ebus_device *edev)
  500. {
  501.     if (!strcmp(edev->prom_name, "fdthree"))
  502.         return 1;
  503.     if (!strcmp(edev->prom_name, "floppy")) {
  504.         char compat[16];
  505.         prom_getstring(edev->prom_node,
  506.                    "compatible",
  507.                    compat, sizeof(compat));
  508.         compat[15] = '\0';
  509.         if (!strcmp(compat, "fdthree"))
  510.             return 1;
  511.     }
  512.     return 0;
  513. }
  514. #endif
  515.  
  516. #ifdef CONFIG_PCI
  517. #undef ISA_FLOPPY_WORKS
  518.  
  519. #ifdef ISA_FLOPPY_WORKS
  520. static unsigned long __init isa_floppy_init(void)
  521. {
  522.     struct sparc_isa_bridge *isa_br;
  523.     struct sparc_isa_device *isa_dev = NULL;
  524.  
  525.     for_each_isa(isa_br) {
  526.         for_each_isadev(isa_dev, isa_br) {
  527.             if (!strcmp(isa_dev->prom_name, "dma")) {
  528.                 struct sparc_isa_device *child =
  529.                     isa_dev->child;
  530.  
  531.                 while (child) {
  532.                     if (!strcmp(child->prom_name,
  533.                             "floppy")) {
  534.                         isa_dev = child;
  535.                         goto isa_done;
  536.                     }
  537.                     child = child->next;
  538.                 }
  539.             }
  540.         }
  541.     }
  542. isa_done:
  543.     if (!isa_dev)
  544.         return 0;
  545.  
  546.     /* We could use DMA on devices behind the ISA bridge, but...
  547.      *
  548.      * There is a slight problem.  Normally on x86 kit the x86 processor
  549.      * delays I/O port instructions when the ISA bus "dma in progress"
  550.      * signal is active.  Well, sparc64 systems do not monitor this
  551.      * signal thus we would need to block all I/O port accesses in software
  552.      * when a dma transfer is active for some device.
  553.      */
  554.  
  555.     sun_fdc = (struct sun_flpy_controller *)isa_dev->resource.start;
  556.     FLOPPY_IRQ = isa_dev->irq;
  557.  
  558.     sun_fdops.fd_inb = sun_pci_fd_inb;
  559.     sun_fdops.fd_outb = sun_pci_fd_outb;
  560.  
  561.     can_use_virtual_dma = use_virtual_dma = 1;
  562.     sun_fdops.fd_enable_dma = sun_fd_enable_dma;
  563.     sun_fdops.fd_disable_dma = sun_fd_disable_dma;
  564.     sun_fdops.fd_set_dma_mode = sun_fd_set_dma_mode;
  565.     sun_fdops.fd_set_dma_addr = sun_fd_set_dma_addr;
  566.     sun_fdops.fd_set_dma_count = sun_fd_set_dma_count;
  567.     sun_fdops.get_dma_residue = sun_get_dma_residue;
  568.  
  569.     sun_fdops.fd_request_irq = sun_fd_request_irq;
  570.     sun_fdops.fd_free_irq = sun_fd_free_irq;
  571.  
  572.     /* Floppy eject is manual.   Actually, could determine this
  573.      * via presence of 'manual' property in OBP node.
  574.      */
  575.     sun_fdops.fd_eject = sun_pci_fd_eject;
  576.  
  577.         fdc_status = (unsigned long) &sun_fdc->status_82077;
  578.     FLOPPY_MOTOR_MASK = 0xf0;
  579.  
  580.     allowed_drive_mask = 0;
  581.     sun_floppy_types[0] = 0;
  582.     sun_floppy_types[1] = 4;
  583.  
  584.     sun_pci_broken_drive = 1;
  585.     sun_fdops.fd_outb = sun_pci_fd_broken_outb;
  586.  
  587.     return sun_floppy_types[0];
  588. }
  589. #endif /* ISA_FLOPPY_WORKS */
  590.  
  591. #endif
  592.  
  593. static unsigned long __init sun_floppy_init(void)
  594. {
  595.     char state[128];
  596.     struct sbus_bus *bus;
  597.     struct sbus_dev *sdev = NULL;
  598.     static int initialized = 0;
  599.  
  600.     if (initialized)
  601.         return sun_floppy_types[0];
  602.     initialized = 1;
  603.  
  604.     for_all_sbusdev (sdev, bus) {
  605.         if (!strcmp(sdev->prom_name, "SUNW,fdtwo")) 
  606.             break;
  607.     }
  608.     if(sdev) {
  609.         floppy_sdev = sdev;
  610.         FLOPPY_IRQ = sdev->irqs[0];
  611.     } else {
  612. #ifdef CONFIG_PCI
  613.         struct linux_ebus *ebus;
  614.         struct linux_ebus_device *edev = NULL;
  615.         unsigned long config = 0;
  616.         void __iomem *auxio_reg;
  617.  
  618.         for_each_ebus(ebus) {
  619.             for_each_ebusdev(edev, ebus) {
  620.                 if (ebus_fdthree_p(edev))
  621.                     goto ebus_done;
  622.             }
  623.         }
  624.     ebus_done:
  625.         if (!edev) {
  626. #ifdef ISA_FLOPPY_WORKS
  627.             return isa_floppy_init();
  628. #else
  629.             return 0;
  630. #endif
  631.         }
  632.  
  633.         prom_getproperty(edev->prom_node, "status",
  634.                  state, sizeof(state));
  635.         if (!strncmp(state, "disabled", 8))
  636.             return 0;
  637.             
  638.         FLOPPY_IRQ = edev->irqs[0];
  639.  
  640.         /* Make sure the high density bit is set, some systems
  641.          * (most notably Ultra5/Ultra10) come up with it clear.
  642.          */
  643.         auxio_reg = (void __iomem *) edev->resource[2].start;
  644.         writel(readl(auxio_reg)|0x2, auxio_reg);
  645.  
  646.         sun_pci_ebus_dev = ebus->self;
  647.  
  648.         spin_lock_init(&sun_pci_fd_ebus_dma.lock);
  649.  
  650.         /* XXX ioremap */
  651.         sun_pci_fd_ebus_dma.regs = (void __iomem *)
  652.             edev->resource[1].start;
  653.         if (!sun_pci_fd_ebus_dma.regs)
  654.             return 0;
  655.  
  656.         sun_pci_fd_ebus_dma.flags = (EBUS_DMA_FLAG_USE_EBDMA_HANDLER |
  657.                          EBUS_DMA_FLAG_TCI_DISABLE);
  658.         sun_pci_fd_ebus_dma.callback = sun_pci_fd_dma_callback;
  659.         sun_pci_fd_ebus_dma.client_cookie = NULL;
  660.         sun_pci_fd_ebus_dma.irq = FLOPPY_IRQ;
  661.         strcpy(sun_pci_fd_ebus_dma.name, "floppy");
  662.         if (ebus_dma_register(&sun_pci_fd_ebus_dma))
  663.             return 0;
  664.  
  665.         /* XXX ioremap */
  666.         sun_fdc = (struct sun_flpy_controller *)edev->resource[0].start;
  667.  
  668.         sun_fdops.fd_inb = sun_pci_fd_inb;
  669.         sun_fdops.fd_outb = sun_pci_fd_outb;
  670.  
  671.         can_use_virtual_dma = use_virtual_dma = 0;
  672.         sun_fdops.fd_enable_dma = sun_pci_fd_enable_dma;
  673.         sun_fdops.fd_disable_dma = sun_pci_fd_disable_dma;
  674.         sun_fdops.fd_set_dma_mode = sun_pci_fd_set_dma_mode;
  675.         sun_fdops.fd_set_dma_addr = sun_pci_fd_set_dma_addr;
  676.         sun_fdops.fd_set_dma_count = sun_pci_fd_set_dma_count;
  677.         sun_fdops.get_dma_residue = sun_pci_get_dma_residue;
  678.  
  679.         sun_fdops.fd_request_irq = sun_pci_fd_request_irq;
  680.         sun_fdops.fd_free_irq = sun_pci_fd_free_irq;
  681.  
  682.         sun_fdops.fd_eject = sun_pci_fd_eject;
  683.  
  684.             fdc_status = (unsigned long) &sun_fdc->status_82077;
  685.         FLOPPY_MOTOR_MASK = 0xf0;
  686.  
  687.         /*
  688.          * XXX: Find out on which machines this is really needed.
  689.          */
  690.         if (1) {
  691.             sun_pci_broken_drive = 1;
  692.             sun_fdops.fd_outb = sun_pci_fd_broken_outb;
  693.         }
  694.  
  695.         allowed_drive_mask = 0;
  696.         if (sun_pci_fd_test_drive((unsigned long)sun_fdc, 0))
  697.             sun_floppy_types[0] = 4;
  698.         if (sun_pci_fd_test_drive((unsigned long)sun_fdc, 1))
  699.             sun_floppy_types[1] = 4;
  700.  
  701.         /*
  702.          * Find NS87303 SuperIO config registers (through ecpp).
  703.          */
  704.         for_each_ebus(ebus) {
  705.             for_each_ebusdev(edev, ebus) {
  706.                 if (!strcmp(edev->prom_name, "ecpp")) {
  707.                     config = edev->resource[1].start;
  708.                     goto config_done;
  709.                 }
  710.             }
  711.         }
  712.     config_done:
  713.  
  714.         /*
  715.          * Sanity check, is this really the NS87303?
  716.          */
  717.         switch (config & 0x3ff) {
  718.         case 0x02e:
  719.         case 0x15c:
  720.         case 0x26e:
  721.         case 0x398:
  722.             break;
  723.         default:
  724.             config = 0;
  725.         }
  726.  
  727.         if (!config)
  728.             return sun_floppy_types[0];
  729.  
  730.         /* Enable PC-AT mode. */
  731.         ns87303_modify(config, ASC, 0, 0xc0);
  732.  
  733. #ifdef PCI_FDC_SWAP_DRIVES
  734.         /*
  735.          * If only Floppy 1 is present, swap drives.
  736.          */
  737.         if (!sun_floppy_types[0] && sun_floppy_types[1]) {
  738.             /*
  739.              * Set the drive exchange bit in FCR on NS87303,
  740.              * make sure other bits are sane before doing so.
  741.              */
  742.             ns87303_modify(config, FER, FER_EDM, 0);
  743.             ns87303_modify(config, ASC, ASC_DRV2_SEL, 0);
  744.             ns87303_modify(config, FCR, 0, FCR_LDE);
  745.  
  746.             config = sun_floppy_types[0];
  747.             sun_floppy_types[0] = sun_floppy_types[1];
  748.             sun_floppy_types[1] = config;
  749.  
  750.             if (sun_pci_broken_drive != -1) {
  751.                 sun_pci_broken_drive = 1 - sun_pci_broken_drive;
  752.                 sun_fdops.fd_outb = sun_pci_fd_lde_broken_outb;
  753.             }
  754.         }
  755. #endif /* PCI_FDC_SWAP_DRIVES */
  756.  
  757.         return sun_floppy_types[0];
  758. #else
  759.         return 0;
  760. #endif
  761.     }
  762.     prom_getproperty(sdev->prom_node, "status", state, sizeof(state));
  763.     if(!strncmp(state, "disabled", 8))
  764.         return 0;
  765.  
  766.     /*
  767.      * We cannot do sbus_ioremap here: it does request_region,
  768.      * which the generic floppy driver tries to do once again.
  769.      * But we must use the sdev resource values as they have
  770.      * had parent ranges applied.
  771.      */
  772.     sun_fdc = (struct sun_flpy_controller *)
  773.         (sdev->resource[0].start +
  774.          ((sdev->resource[0].flags & 0x1ffUL) << 32UL));
  775.  
  776.     /* Last minute sanity check... */
  777.     if(sbus_readb(&sun_fdc->status1_82077) == 0xff) {
  778.         sun_fdc = (struct sun_flpy_controller *)-1;
  779.         return 0;
  780.     }
  781.  
  782.         sun_fdops.fd_inb = sun_82077_fd_inb;
  783.         sun_fdops.fd_outb = sun_82077_fd_outb;
  784.  
  785.     can_use_virtual_dma = use_virtual_dma = 1;
  786.     sun_fdops.fd_enable_dma = sun_fd_enable_dma;
  787.     sun_fdops.fd_disable_dma = sun_fd_disable_dma;
  788.     sun_fdops.fd_set_dma_mode = sun_fd_set_dma_mode;
  789.     sun_fdops.fd_set_dma_addr = sun_fd_set_dma_addr;
  790.     sun_fdops.fd_set_dma_count = sun_fd_set_dma_count;
  791.     sun_fdops.get_dma_residue = sun_get_dma_residue;
  792.  
  793.     sun_fdops.fd_request_irq = sun_fd_request_irq;
  794.     sun_fdops.fd_free_irq = sun_fd_free_irq;
  795.  
  796.     sun_fdops.fd_eject = sun_fd_eject;
  797.  
  798.         fdc_status = (unsigned long) &sun_fdc->status_82077;
  799.  
  800.     /* Success... */
  801.     allowed_drive_mask = 0x01;
  802.     sun_floppy_types[0] = 4;
  803.     sun_floppy_types[1] = 0;
  804.  
  805.     return sun_floppy_types[0];
  806. }
  807.  
  808. #define EXTRA_FLOPPY_PARAMS
  809.  
  810. #endif /* !(__ASM_SPARC64_FLOPPY_H) */
  811.