cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

floppy_64.h (19392B)


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