Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 /* floppy.h: Sparc specific parts of the Floppy driver.
0003  *
0004  * Copyright (C) 1996, 2007, 2008 David S. Miller (davem@davemloft.net)
0005  * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
0006  *
0007  * Ultra/PCI support added: Sep 1997  Eddie C. Dost  (ecd@skynet.be)
0008  */
0009 
0010 #ifndef __ASM_SPARC64_FLOPPY_H
0011 #define __ASM_SPARC64_FLOPPY_H
0012 
0013 #include <linux/of.h>
0014 #include <linux/of_device.h>
0015 #include <linux/dma-mapping.h>
0016 
0017 #include <asm/auxio.h>
0018 
0019 /*
0020  * Define this to enable exchanging drive 0 and 1 if only drive 1 is
0021  * probed on PCI machines.
0022  */
0023 #undef PCI_FDC_SWAP_DRIVES
0024 
0025 
0026 /* References:
0027  * 1) Netbsd Sun floppy driver.
0028  * 2) NCR 82077 controller manual
0029  * 3) Intel 82077 controller manual
0030  */
0031 struct sun_flpy_controller {
0032     volatile unsigned char status1_82077; /* Auxiliary Status reg. 1 */
0033     volatile unsigned char status2_82077; /* Auxiliary Status reg. 2 */
0034     volatile unsigned char dor_82077;     /* Digital Output reg. */
0035     volatile unsigned char tapectl_82077; /* Tape Control reg */
0036     volatile unsigned char status_82077;  /* Main Status Register. */
0037 #define drs_82077              status_82077   /* Digital Rate Select reg. */
0038     volatile unsigned char data_82077;    /* Data fifo. */
0039     volatile unsigned char ___unused;
0040     volatile unsigned char dir_82077;     /* Digital Input reg. */
0041 #define dcr_82077              dir_82077      /* Config Control reg. */
0042 };
0043 
0044 /* You'll only ever find one controller on an Ultra anyways. */
0045 static struct sun_flpy_controller *sun_fdc = (struct sun_flpy_controller *)-1;
0046 unsigned long fdc_status;
0047 static struct platform_device *floppy_op = NULL;
0048 
0049 struct sun_floppy_ops {
0050     unsigned char   (*fd_inb) (unsigned long port, unsigned int reg);
0051     void        (*fd_outb) (unsigned char value, unsigned long base,
0052                     unsigned int reg);
0053     void        (*fd_enable_dma) (void);
0054     void        (*fd_disable_dma) (void);
0055     void        (*fd_set_dma_mode) (int);
0056     void        (*fd_set_dma_addr) (char *);
0057     void        (*fd_set_dma_count) (int);
0058     unsigned int    (*get_dma_residue) (void);
0059     int     (*fd_request_irq) (void);
0060     void        (*fd_free_irq) (void);
0061     int     (*fd_eject) (int);
0062 };
0063 
0064 static struct sun_floppy_ops sun_fdops;
0065 
0066 #define fd_inb(base, reg)         sun_fdops.fd_inb(base, reg)
0067 #define fd_outb(value, base, reg) sun_fdops.fd_outb(value, base, reg)
0068 #define fd_enable_dma()           sun_fdops.fd_enable_dma()
0069 #define fd_disable_dma()          sun_fdops.fd_disable_dma()
0070 #define fd_request_dma()          (0) /* nothing... */
0071 #define fd_free_dma()             /* nothing... */
0072 #define fd_clear_dma_ff()         /* nothing... */
0073 #define fd_set_dma_mode(mode)     sun_fdops.fd_set_dma_mode(mode)
0074 #define fd_set_dma_addr(addr)     sun_fdops.fd_set_dma_addr(addr)
0075 #define fd_set_dma_count(count)   sun_fdops.fd_set_dma_count(count)
0076 #define get_dma_residue(x)        sun_fdops.get_dma_residue()
0077 #define fd_request_irq()          sun_fdops.fd_request_irq()
0078 #define fd_free_irq()             sun_fdops.fd_free_irq()
0079 #define fd_eject(drive)           sun_fdops.fd_eject(drive)
0080 
0081 /* Super paranoid... */
0082 #undef HAVE_DISABLE_HLT
0083 
0084 static int sun_floppy_types[2] = { 0, 0 };
0085 
0086 /* Here is where we catch the floppy driver trying to initialize,
0087  * therefore this is where we call the PROM device tree probing
0088  * routine etc. on the Sparc.
0089  */
0090 #define FLOPPY0_TYPE        sun_floppy_init()
0091 #define FLOPPY1_TYPE        sun_floppy_types[1]
0092 
0093 #define FDC1            ((unsigned long)sun_fdc)
0094 
0095 #define N_FDC    1
0096 #define N_DRIVE  8
0097 
0098 /* No 64k boundary crossing problems on the Sparc. */
0099 #define CROSS_64KB(a,s) (0)
0100 
0101 static unsigned char sun_82077_fd_inb(unsigned long base, unsigned int reg)
0102 {
0103     udelay(5);
0104     switch (reg) {
0105     default:
0106         printk("floppy: Asked to read unknown port %x\n", reg);
0107         panic("floppy: Port bolixed.");
0108     case FD_STATUS:
0109         return sbus_readb(&sun_fdc->status_82077) & ~STATUS_DMA;
0110     case FD_DATA:
0111         return sbus_readb(&sun_fdc->data_82077);
0112     case FD_DIR:
0113         /* XXX: Is DCL on 0x80 in sun4m? */
0114         return sbus_readb(&sun_fdc->dir_82077);
0115     }
0116     panic("sun_82072_fd_inb: How did I get here?");
0117 }
0118 
0119 static void sun_82077_fd_outb(unsigned char value, unsigned long base,
0120                   unsigned int reg)
0121 {
0122     udelay(5);
0123     switch (reg) {
0124     default:
0125         printk("floppy: Asked to write to unknown port %x\n", reg);
0126         panic("floppy: Port bolixed.");
0127     case FD_DOR:
0128         /* Happily, the 82077 has a real DOR register. */
0129         sbus_writeb(value, &sun_fdc->dor_82077);
0130         break;
0131     case FD_DATA:
0132         sbus_writeb(value, &sun_fdc->data_82077);
0133         break;
0134     case FD_DCR:
0135         sbus_writeb(value, &sun_fdc->dcr_82077);
0136         break;
0137     case FD_DSR:
0138         sbus_writeb(value, &sun_fdc->status_82077);
0139         break;
0140     }
0141     return;
0142 }
0143 
0144 /* For pseudo-dma (Sun floppy drives have no real DMA available to
0145  * them so we must eat the data fifo bytes directly ourselves) we have
0146  * three state variables.  doing_pdma tells our inline low-level
0147  * assembly floppy interrupt entry point whether it should sit and eat
0148  * bytes from the fifo or just transfer control up to the higher level
0149  * floppy interrupt c-code.  I tried very hard but I could not get the
0150  * pseudo-dma to work in c-code without getting many overruns and
0151  * underruns.  If non-zero, doing_pdma encodes the direction of
0152  * the transfer for debugging.  1=read 2=write
0153  */
0154 unsigned char *pdma_vaddr;
0155 unsigned long pdma_size;
0156 volatile int doing_pdma = 0;
0157 
0158 /* This is software state */
0159 char *pdma_base = NULL;
0160 unsigned long pdma_areasize;
0161 
0162 /* Common routines to all controller types on the Sparc. */
0163 static void sun_fd_disable_dma(void)
0164 {
0165     doing_pdma = 0;
0166     pdma_base = NULL;
0167 }
0168 
0169 static void sun_fd_set_dma_mode(int mode)
0170 {
0171     switch(mode) {
0172     case DMA_MODE_READ:
0173         doing_pdma = 1;
0174         break;
0175     case DMA_MODE_WRITE:
0176         doing_pdma = 2;
0177         break;
0178     default:
0179         printk("Unknown dma mode %d\n", mode);
0180         panic("floppy: Giving up...");
0181     }
0182 }
0183 
0184 static void sun_fd_set_dma_addr(char *buffer)
0185 {
0186     pdma_vaddr = buffer;
0187 }
0188 
0189 static void sun_fd_set_dma_count(int length)
0190 {
0191     pdma_size = length;
0192 }
0193 
0194 static void sun_fd_enable_dma(void)
0195 {
0196     pdma_base = pdma_vaddr;
0197     pdma_areasize = pdma_size;
0198 }
0199 
0200 irqreturn_t sparc_floppy_irq(int irq, void *dev_cookie)
0201 {
0202     if (likely(doing_pdma)) {
0203         void __iomem *stat = (void __iomem *) fdc_status;
0204         unsigned char *vaddr = pdma_vaddr;
0205         unsigned long size = pdma_size;
0206         u8 val;
0207 
0208         while (size) {
0209             val = readb(stat);
0210             if (unlikely(!(val & 0x80))) {
0211                 pdma_vaddr = vaddr;
0212                 pdma_size = size;
0213                 return IRQ_HANDLED;
0214             }
0215             if (unlikely(!(val & 0x20))) {
0216                 pdma_vaddr = vaddr;
0217                 pdma_size = size;
0218                 doing_pdma = 0;
0219                 goto main_interrupt;
0220             }
0221             if (val & 0x40) {
0222                 /* read */
0223                 *vaddr++ = readb(stat + 1);
0224             } else {
0225                 unsigned char data = *vaddr++;
0226 
0227                 /* write */
0228                 writeb(data, stat + 1);
0229             }
0230             size--;
0231         }
0232 
0233         pdma_vaddr = vaddr;
0234         pdma_size = size;
0235 
0236         /* Send Terminal Count pulse to floppy controller. */
0237         val = readb(auxio_register);
0238         val |= AUXIO_AUX1_FTCNT;
0239         writeb(val, auxio_register);
0240         val &= ~AUXIO_AUX1_FTCNT;
0241         writeb(val, auxio_register);
0242 
0243         doing_pdma = 0;
0244     }
0245 
0246 main_interrupt:
0247     return floppy_interrupt(irq, dev_cookie);
0248 }
0249 
0250 static int sun_fd_request_irq(void)
0251 {
0252     static int once = 0;
0253     int error;
0254 
0255     if(!once) {
0256         once = 1;
0257 
0258         error = request_irq(FLOPPY_IRQ, sparc_floppy_irq,
0259                     0, "floppy", NULL);
0260 
0261         return ((error == 0) ? 0 : -1);
0262     }
0263     return 0;
0264 }
0265 
0266 static void sun_fd_free_irq(void)
0267 {
0268 }
0269 
0270 static unsigned int sun_get_dma_residue(void)
0271 {
0272     /* XXX This isn't really correct. XXX */
0273     return 0;
0274 }
0275 
0276 static int sun_fd_eject(int drive)
0277 {
0278     set_dor(0x00, 0xff, 0x90);
0279     udelay(500);
0280     set_dor(0x00, 0x6f, 0x00);
0281     udelay(500);
0282     return 0;
0283 }
0284 
0285 #include <asm/ebus_dma.h>
0286 #include <asm/ns87303.h>
0287 
0288 static struct ebus_dma_info sun_pci_fd_ebus_dma;
0289 static struct device *sun_floppy_dev;
0290 static int sun_pci_broken_drive = -1;
0291 
0292 struct sun_pci_dma_op {
0293     unsigned int    addr;
0294     int     len;
0295     int     direction;
0296     char        *buf;
0297 };
0298 static struct sun_pci_dma_op sun_pci_dma_current = { -1U, 0, 0, NULL};
0299 static struct sun_pci_dma_op sun_pci_dma_pending = { -1U, 0, 0, NULL};
0300 
0301 irqreturn_t floppy_interrupt(int irq, void *dev_id);
0302 
0303 static unsigned char sun_pci_fd_inb(unsigned long base, unsigned int reg)
0304 {
0305     udelay(5);
0306     return inb(base + reg);
0307 }
0308 
0309 static void sun_pci_fd_outb(unsigned char val, unsigned long base,
0310                 unsigned int reg)
0311 {
0312     udelay(5);
0313     outb(val, base + reg);
0314 }
0315 
0316 static void sun_pci_fd_broken_outb(unsigned char val, unsigned long base,
0317                    unsigned int reg)
0318 {
0319     udelay(5);
0320     /*
0321      * XXX: Due to SUN's broken floppy connector on AX and AXi
0322      *      we need to turn on MOTOR_0 also, if the floppy is
0323      *      jumpered to DS1 (like most PC floppies are). I hope
0324      *      this does not hurt correct hardware like the AXmp.
0325      *      (Eddie, Sep 12 1998).
0326      */
0327     if (reg == FD_DOR) {
0328         if (((val & 0x03) == sun_pci_broken_drive) && (val & 0x20)) {
0329             val |= 0x10;
0330         }
0331     }
0332     outb(val, base + reg);
0333 }
0334 
0335 #ifdef PCI_FDC_SWAP_DRIVES
0336 static void sun_pci_fd_lde_broken_outb(unsigned char val, unsigned long base,
0337                        unsigned int reg)
0338 {
0339     udelay(5);
0340     /*
0341      * XXX: Due to SUN's broken floppy connector on AX and AXi
0342      *      we need to turn on MOTOR_0 also, if the floppy is
0343      *      jumpered to DS1 (like most PC floppies are). I hope
0344      *      this does not hurt correct hardware like the AXmp.
0345      *      (Eddie, Sep 12 1998).
0346      */
0347     if (reg == FD_DOR) {
0348         if (((val & 0x03) == sun_pci_broken_drive) && (val & 0x10)) {
0349             val &= ~(0x03);
0350             val |= 0x21;
0351         }
0352     }
0353     outb(val, base + reg);
0354 }
0355 #endif /* PCI_FDC_SWAP_DRIVES */
0356 
0357 static void sun_pci_fd_enable_dma(void)
0358 {
0359     BUG_ON((NULL == sun_pci_dma_pending.buf)    ||
0360         (0    == sun_pci_dma_pending.len)   ||
0361         (0    == sun_pci_dma_pending.direction));
0362 
0363     sun_pci_dma_current.buf = sun_pci_dma_pending.buf;
0364     sun_pci_dma_current.len = sun_pci_dma_pending.len;
0365     sun_pci_dma_current.direction = sun_pci_dma_pending.direction;
0366 
0367     sun_pci_dma_pending.buf  = NULL;
0368     sun_pci_dma_pending.len  = 0;
0369     sun_pci_dma_pending.direction = 0;
0370     sun_pci_dma_pending.addr = -1U;
0371 
0372     sun_pci_dma_current.addr =
0373         dma_map_single(sun_floppy_dev,
0374                    sun_pci_dma_current.buf,
0375                    sun_pci_dma_current.len,
0376                    sun_pci_dma_current.direction);
0377 
0378     ebus_dma_enable(&sun_pci_fd_ebus_dma, 1);
0379 
0380     if (ebus_dma_request(&sun_pci_fd_ebus_dma,
0381                  sun_pci_dma_current.addr,
0382                  sun_pci_dma_current.len))
0383         BUG();
0384 }
0385 
0386 static void sun_pci_fd_disable_dma(void)
0387 {
0388     ebus_dma_enable(&sun_pci_fd_ebus_dma, 0);
0389     if (sun_pci_dma_current.addr != -1U)
0390         dma_unmap_single(sun_floppy_dev,
0391                  sun_pci_dma_current.addr,
0392                  sun_pci_dma_current.len,
0393                  sun_pci_dma_current.direction);
0394     sun_pci_dma_current.addr = -1U;
0395 }
0396 
0397 static void sun_pci_fd_set_dma_mode(int mode)
0398 {
0399     if (mode == DMA_MODE_WRITE)
0400         sun_pci_dma_pending.direction = DMA_TO_DEVICE;
0401     else
0402         sun_pci_dma_pending.direction = DMA_FROM_DEVICE;
0403 
0404     ebus_dma_prepare(&sun_pci_fd_ebus_dma, mode != DMA_MODE_WRITE);
0405 }
0406 
0407 static void sun_pci_fd_set_dma_count(int length)
0408 {
0409     sun_pci_dma_pending.len = length;
0410 }
0411 
0412 static void sun_pci_fd_set_dma_addr(char *buffer)
0413 {
0414     sun_pci_dma_pending.buf = buffer;
0415 }
0416 
0417 static unsigned int sun_pci_get_dma_residue(void)
0418 {
0419     return ebus_dma_residue(&sun_pci_fd_ebus_dma);
0420 }
0421 
0422 static int sun_pci_fd_request_irq(void)
0423 {
0424     return ebus_dma_irq_enable(&sun_pci_fd_ebus_dma, 1);
0425 }
0426 
0427 static void sun_pci_fd_free_irq(void)
0428 {
0429     ebus_dma_irq_enable(&sun_pci_fd_ebus_dma, 0);
0430 }
0431 
0432 static int sun_pci_fd_eject(int drive)
0433 {
0434     return -EINVAL;
0435 }
0436 
0437 void sun_pci_fd_dma_callback(struct ebus_dma_info *p, int event, void *cookie)
0438 {
0439     floppy_interrupt(0, NULL);
0440 }
0441 
0442 /*
0443  * Floppy probing, we'd like to use /dev/fd0 for a single Floppy on PCI,
0444  * even if this is configured using DS1, thus looks like /dev/fd1 with
0445  * the cabling used in Ultras.
0446  */
0447 #define DOR (port + 2)
0448 #define MSR (port + 4)
0449 #define FIFO    (port + 5)
0450 
0451 static void sun_pci_fd_out_byte(unsigned long port, unsigned char val,
0452                     unsigned long reg)
0453 {
0454     unsigned char status;
0455     int timeout = 1000;
0456 
0457     while (!((status = inb(MSR)) & 0x80) && --timeout)
0458         udelay(100);
0459     outb(val, reg);
0460 }
0461 
0462 static unsigned char sun_pci_fd_sensei(unsigned long port)
0463 {
0464     unsigned char result[2] = { 0x70, 0x00 };
0465     unsigned char status;
0466     int i = 0;
0467 
0468     sun_pci_fd_out_byte(port, 0x08, FIFO);
0469     do {
0470         int timeout = 1000;
0471 
0472         while (!((status = inb(MSR)) & 0x80) && --timeout)
0473             udelay(100);
0474 
0475         if (!timeout)
0476             break;
0477 
0478         if ((status & 0xf0) == 0xd0)
0479             result[i++] = inb(FIFO);
0480         else
0481             break;
0482     } while (i < 2);
0483 
0484     return result[0];
0485 }
0486 
0487 static void sun_pci_fd_reset(unsigned long port)
0488 {
0489     unsigned char mask = 0x00;
0490     unsigned char status;
0491     int timeout = 10000;
0492 
0493     outb(0x80, MSR);
0494     do {
0495         status = sun_pci_fd_sensei(port);
0496         if ((status & 0xc0) == 0xc0)
0497             mask |= 1 << (status & 0x03);
0498         else
0499             udelay(100);
0500     } while ((mask != 0x0f) && --timeout);
0501 }
0502 
0503 static int sun_pci_fd_test_drive(unsigned long port, int drive)
0504 {
0505     unsigned char status, data;
0506     int timeout = 1000;
0507     int ready;
0508 
0509     sun_pci_fd_reset(port);
0510 
0511     data = (0x10 << drive) | 0x0c | drive;
0512     sun_pci_fd_out_byte(port, data, DOR);
0513 
0514     sun_pci_fd_out_byte(port, 0x07, FIFO);
0515     sun_pci_fd_out_byte(port, drive & 0x03, FIFO);
0516 
0517     do {
0518         udelay(100);
0519         status = sun_pci_fd_sensei(port);
0520     } while (((status & 0xc0) == 0x80) && --timeout);
0521 
0522     if (!timeout)
0523         ready = 0;
0524     else
0525         ready = (status & 0x10) ? 0 : 1;
0526 
0527     sun_pci_fd_reset(port);
0528     return ready;
0529 }
0530 #undef FIFO
0531 #undef MSR
0532 #undef DOR
0533 
0534 static int __init ebus_fdthree_p(struct device_node *dp)
0535 {
0536     if (of_node_name_eq(dp, "fdthree"))
0537         return 1;
0538     if (of_node_name_eq(dp, "floppy")) {
0539         const char *compat;
0540 
0541         compat = of_get_property(dp, "compatible", NULL);
0542         if (compat && !strcmp(compat, "fdthree"))
0543             return 1;
0544     }
0545     return 0;
0546 }
0547 
0548 static unsigned long __init sun_floppy_init(void)
0549 {
0550     static int initialized = 0;
0551     struct device_node *dp;
0552     struct platform_device *op;
0553     const char *prop;
0554     char state[128];
0555 
0556     if (initialized)
0557         return sun_floppy_types[0];
0558     initialized = 1;
0559 
0560     op = NULL;
0561 
0562     for_each_node_by_name(dp, "SUNW,fdtwo") {
0563         if (!of_node_name_eq(dp->parent, "sbus"))
0564             continue;
0565         op = of_find_device_by_node(dp);
0566         if (op)
0567             break;
0568     }
0569     if (op) {
0570         floppy_op = op;
0571         FLOPPY_IRQ = op->archdata.irqs[0];
0572     } else {
0573         struct device_node *ebus_dp;
0574         void __iomem *auxio_reg;
0575         const char *state_prop;
0576         unsigned long config;
0577 
0578         dp = NULL;
0579         for_each_node_by_name(ebus_dp, "ebus") {
0580             for (dp = ebus_dp->child; dp; dp = dp->sibling) {
0581                 if (ebus_fdthree_p(dp))
0582                     goto found_fdthree;
0583             }
0584         }
0585     found_fdthree:
0586         if (!dp)
0587             return 0;
0588 
0589         op = of_find_device_by_node(dp);
0590         if (!op)
0591             return 0;
0592 
0593         state_prop = of_get_property(op->dev.of_node, "status", NULL);
0594         if (state_prop && !strncmp(state_prop, "disabled", 8))
0595             return 0;
0596 
0597         FLOPPY_IRQ = op->archdata.irqs[0];
0598 
0599         /* Make sure the high density bit is set, some systems
0600          * (most notably Ultra5/Ultra10) come up with it clear.
0601          */
0602         auxio_reg = (void __iomem *) op->resource[2].start;
0603         writel(readl(auxio_reg)|0x2, auxio_reg);
0604 
0605         sun_floppy_dev = &op->dev;
0606 
0607         spin_lock_init(&sun_pci_fd_ebus_dma.lock);
0608 
0609         /* XXX ioremap */
0610         sun_pci_fd_ebus_dma.regs = (void __iomem *)
0611             op->resource[1].start;
0612         if (!sun_pci_fd_ebus_dma.regs)
0613             return 0;
0614 
0615         sun_pci_fd_ebus_dma.flags = (EBUS_DMA_FLAG_USE_EBDMA_HANDLER |
0616                          EBUS_DMA_FLAG_TCI_DISABLE);
0617         sun_pci_fd_ebus_dma.callback = sun_pci_fd_dma_callback;
0618         sun_pci_fd_ebus_dma.client_cookie = NULL;
0619         sun_pci_fd_ebus_dma.irq = FLOPPY_IRQ;
0620         strcpy(sun_pci_fd_ebus_dma.name, "floppy");
0621         if (ebus_dma_register(&sun_pci_fd_ebus_dma))
0622             return 0;
0623 
0624         /* XXX ioremap */
0625         sun_fdc = (struct sun_flpy_controller *) op->resource[0].start;
0626 
0627         sun_fdops.fd_inb = sun_pci_fd_inb;
0628         sun_fdops.fd_outb = sun_pci_fd_outb;
0629 
0630         can_use_virtual_dma = use_virtual_dma = 0;
0631         sun_fdops.fd_enable_dma = sun_pci_fd_enable_dma;
0632         sun_fdops.fd_disable_dma = sun_pci_fd_disable_dma;
0633         sun_fdops.fd_set_dma_mode = sun_pci_fd_set_dma_mode;
0634         sun_fdops.fd_set_dma_addr = sun_pci_fd_set_dma_addr;
0635         sun_fdops.fd_set_dma_count = sun_pci_fd_set_dma_count;
0636         sun_fdops.get_dma_residue = sun_pci_get_dma_residue;
0637 
0638         sun_fdops.fd_request_irq = sun_pci_fd_request_irq;
0639         sun_fdops.fd_free_irq = sun_pci_fd_free_irq;
0640 
0641         sun_fdops.fd_eject = sun_pci_fd_eject;
0642 
0643         fdc_status = (unsigned long) &sun_fdc->status_82077;
0644 
0645         /*
0646          * XXX: Find out on which machines this is really needed.
0647          */
0648         if (1) {
0649             sun_pci_broken_drive = 1;
0650             sun_fdops.fd_outb = sun_pci_fd_broken_outb;
0651         }
0652 
0653         allowed_drive_mask = 0;
0654         if (sun_pci_fd_test_drive((unsigned long)sun_fdc, 0))
0655             sun_floppy_types[0] = 4;
0656         if (sun_pci_fd_test_drive((unsigned long)sun_fdc, 1))
0657             sun_floppy_types[1] = 4;
0658 
0659         /*
0660          * Find NS87303 SuperIO config registers (through ecpp).
0661          */
0662         config = 0;
0663         for (dp = ebus_dp->child; dp; dp = dp->sibling) {
0664             if (of_node_name_eq(dp, "ecpp")) {
0665                 struct platform_device *ecpp_op;
0666 
0667                 ecpp_op = of_find_device_by_node(dp);
0668                 if (ecpp_op)
0669                     config = ecpp_op->resource[1].start;
0670                 goto config_done;
0671             }
0672         }
0673     config_done:
0674 
0675         /*
0676          * Sanity check, is this really the NS87303?
0677          */
0678         switch (config & 0x3ff) {
0679         case 0x02e:
0680         case 0x15c:
0681         case 0x26e:
0682         case 0x398:
0683             break;
0684         default:
0685             config = 0;
0686         }
0687 
0688         if (!config)
0689             return sun_floppy_types[0];
0690 
0691         /* Enable PC-AT mode. */
0692         ns87303_modify(config, ASC, 0, 0xc0);
0693 
0694 #ifdef PCI_FDC_SWAP_DRIVES
0695         /*
0696          * If only Floppy 1 is present, swap drives.
0697          */
0698         if (!sun_floppy_types[0] && sun_floppy_types[1]) {
0699             /*
0700              * Set the drive exchange bit in FCR on NS87303,
0701              * make sure other bits are sane before doing so.
0702              */
0703             ns87303_modify(config, FER, FER_EDM, 0);
0704             ns87303_modify(config, ASC, ASC_DRV2_SEL, 0);
0705             ns87303_modify(config, FCR, 0, FCR_LDE);
0706 
0707             config = sun_floppy_types[0];
0708             sun_floppy_types[0] = sun_floppy_types[1];
0709             sun_floppy_types[1] = config;
0710 
0711             if (sun_pci_broken_drive != -1) {
0712                 sun_pci_broken_drive = 1 - sun_pci_broken_drive;
0713                 sun_fdops.fd_outb = sun_pci_fd_lde_broken_outb;
0714             }
0715         }
0716 #endif /* PCI_FDC_SWAP_DRIVES */
0717 
0718         return sun_floppy_types[0];
0719     }
0720     prop = of_get_property(op->dev.of_node, "status", NULL);
0721     if (prop && !strncmp(state, "disabled", 8))
0722         return 0;
0723 
0724     /*
0725      * We cannot do of_ioremap here: it does request_region,
0726      * which the generic floppy driver tries to do once again.
0727      * But we must use the sdev resource values as they have
0728      * had parent ranges applied.
0729      */
0730     sun_fdc = (struct sun_flpy_controller *)
0731         (op->resource[0].start +
0732          ((op->resource[0].flags & 0x1ffUL) << 32UL));
0733 
0734     /* Last minute sanity check... */
0735     if (sbus_readb(&sun_fdc->status1_82077) == 0xff) {
0736         sun_fdc = (struct sun_flpy_controller *)-1;
0737         return 0;
0738     }
0739 
0740         sun_fdops.fd_inb = sun_82077_fd_inb;
0741         sun_fdops.fd_outb = sun_82077_fd_outb;
0742 
0743     can_use_virtual_dma = use_virtual_dma = 1;
0744     sun_fdops.fd_enable_dma = sun_fd_enable_dma;
0745     sun_fdops.fd_disable_dma = sun_fd_disable_dma;
0746     sun_fdops.fd_set_dma_mode = sun_fd_set_dma_mode;
0747     sun_fdops.fd_set_dma_addr = sun_fd_set_dma_addr;
0748     sun_fdops.fd_set_dma_count = sun_fd_set_dma_count;
0749     sun_fdops.get_dma_residue = sun_get_dma_residue;
0750 
0751     sun_fdops.fd_request_irq = sun_fd_request_irq;
0752     sun_fdops.fd_free_irq = sun_fd_free_irq;
0753 
0754     sun_fdops.fd_eject = sun_fd_eject;
0755 
0756         fdc_status = (unsigned long) &sun_fdc->status_82077;
0757 
0758     /* Success... */
0759     allowed_drive_mask = 0x01;
0760     sun_floppy_types[0] = 4;
0761     sun_floppy_types[1] = 0;
0762 
0763     return sun_floppy_types[0];
0764 }
0765 
0766 #define EXTRA_FLOPPY_PARAMS
0767 
0768 static DEFINE_SPINLOCK(dma_spin_lock);
0769 
0770 #define claim_dma_lock() \
0771 ({  unsigned long flags; \
0772     spin_lock_irqsave(&dma_spin_lock, flags); \
0773     flags; \
0774 })
0775 
0776 #define release_dma_lock(__flags) \
0777     spin_unlock_irqrestore(&dma_spin_lock, __flags);
0778 
0779 #endif /* !(__ASM_SPARC64_FLOPPY_H) */