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