Blame view

include/asm-powerpc/floppy.h 5 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
8
9
  /*
   * Architecture specific parts of the Floppy driver
   *
   * This file is subject to the terms and conditions of the GNU General Public
   * License.  See the file "COPYING" in the main directory of this archive
   * for more details.
   *
   * Copyright (C) 1995
   */
c55377ee7   Paul Mackerras   powerpc: Move a b...
10
11
  #ifndef __ASM_POWERPC_FLOPPY_H
  #define __ASM_POWERPC_FLOPPY_H
88ced0314   Arnd Bergmann   [PATCH] powerpc: ...
12
  #ifdef __KERNEL__
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
13

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
14
  #include <asm/machdep.h>
c55377ee7   Paul Mackerras   powerpc: Move a b...
15
16
  #define fd_inb(port)		inb_p(port)
  #define fd_outb(value,port)	outb_p(value,port)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
17
18
  
  #define fd_enable_dma()         enable_dma(FLOPPY_DMA)
9ea8b7c96   Pavel Fedin   [POWERPC] Virtual...
19
20
  #define fd_disable_dma()	 fd_ops->_disable_dma(FLOPPY_DMA)
  #define fd_free_dma()           fd_ops->_free_dma(FLOPPY_DMA)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
21
  #define fd_clear_dma_ff()       clear_dma_ff(FLOPPY_DMA)
c55377ee7   Paul Mackerras   powerpc: Move a b...
22
23
  #define fd_set_dma_mode(mode)   set_dma_mode(FLOPPY_DMA, mode)
  #define fd_set_dma_count(count) set_dma_count(FLOPPY_DMA, count)
9ea8b7c96   Pavel Fedin   [POWERPC] Virtual...
24
  #define fd_get_dma_residue()    fd_ops->_get_dma_residue(FLOPPY_DMA)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
25
26
27
  #define fd_enable_irq()         enable_irq(FLOPPY_IRQ)
  #define fd_disable_irq()        disable_irq(FLOPPY_IRQ)
  #define fd_cacheflush(addr,size) /* nothing */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
28
  #define fd_free_irq()           free_irq(FLOPPY_IRQ, NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
29
  #include <linux/pci.h>
b239cbe95   Stephen Rothwell   [PATCH] powerpc: ...
30
  #include <asm/ppc-pci.h>	/* for ppc64_isabridge_dev */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
31

9ea8b7c96   Pavel Fedin   [POWERPC] Virtual...
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
  #define fd_dma_setup(addr,size,mode,io) fd_ops->_dma_setup(addr,size,mode,io)
  
  static int fd_request_dma(void);
  
  struct fd_dma_ops {
  	void (*_disable_dma)(unsigned int dmanr);
  	void (*_free_dma)(unsigned int dmanr);
  	int (*_get_dma_residue)(unsigned int dummy);
  	int (*_dma_setup)(char *addr, unsigned long size, int mode, int io);
  };
  
  static int virtual_dma_count;
  static int virtual_dma_residue;
  static char *virtual_dma_addr;
  static int virtual_dma_mode;
  static int doing_vdma;
  static struct fd_dma_ops *fd_ops;
  
  static irqreturn_t floppy_hardint(int irq, void *dev_id)
  {
  	unsigned char st;
  	int lcount;
  	char *lptr;
  
  	if (!doing_vdma)
  		return floppy_interrupt(irq, dev_id);
  
  
  	st = 1;
  	for (lcount=virtual_dma_count, lptr=virtual_dma_addr;
  	     lcount; lcount--, lptr++) {
  		st=inb(virtual_dma_port+4) & 0xa0 ;
  		if (st != 0xa0)
  			break;
  		if (virtual_dma_mode)
  			outb_p(*lptr, virtual_dma_port+5);
  		else
  			*lptr = inb_p(virtual_dma_port+5);
  	}
  	virtual_dma_count = lcount;
  	virtual_dma_addr = lptr;
  	st = inb(virtual_dma_port+4);
  
  	if (st == 0x20)
  		return IRQ_HANDLED;
  	if (!(st & 0x20)) {
  		virtual_dma_residue += virtual_dma_count;
  		virtual_dma_count=0;
  		doing_vdma = 0;
  		floppy_interrupt(irq, dev_id);
  		return IRQ_HANDLED;
  	}
  	return IRQ_HANDLED;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
86

9ea8b7c96   Pavel Fedin   [POWERPC] Virtual...
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
  static void vdma_disable_dma(unsigned int dummy)
  {
  	doing_vdma = 0;
  	virtual_dma_residue += virtual_dma_count;
  	virtual_dma_count=0;
  }
  
  static void vdma_nop(unsigned int dummy)
  {
  }
  
  
  static int vdma_get_dma_residue(unsigned int dummy)
  {
  	return virtual_dma_count + virtual_dma_residue;
  }
  
  
  static int fd_request_irq(void)
  {
  	if (can_use_virtual_dma)
  		return request_irq(FLOPPY_IRQ, floppy_hardint,
  				   IRQF_DISABLED, "floppy", NULL);
  	else
  		return request_irq(FLOPPY_IRQ, floppy_interrupt,
  				   IRQF_DISABLED, "floppy", NULL);
  }
  
  static int vdma_dma_setup(char *addr, unsigned long size, int mode, int io)
  {
  	doing_vdma = 1;
  	virtual_dma_port = io;
  	virtual_dma_mode = (mode  == DMA_MODE_WRITE);
  	virtual_dma_addr = addr;
  	virtual_dma_count = size;
  	virtual_dma_residue = 0;
  	return 0;
  }
  
  static int hard_dma_setup(char *addr, unsigned long size, int mode, int io)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
127
128
129
130
131
132
  {
  	static unsigned long prev_size;
  	static dma_addr_t bus_addr = 0;
  	static char *prev_addr;
  	static int prev_dir;
  	int dir;
9ea8b7c96   Pavel Fedin   [POWERPC] Virtual...
133
  	doing_vdma = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
134
135
136
137
138
  	dir = (mode == DMA_MODE_READ) ? PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE;
  
  	if (bus_addr 
  	    && (addr != prev_addr || size != prev_size || dir != prev_dir)) {
  		/* different from last time -- unmap prev */
b239cbe95   Stephen Rothwell   [PATCH] powerpc: ...
139
  		pci_unmap_single(ppc64_isabridge_dev, bus_addr, prev_size, prev_dir);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
140
141
  		bus_addr = 0;
  	}
c55377ee7   Paul Mackerras   powerpc: Move a b...
142
  	if (!bus_addr)	/* need to map it */
b239cbe95   Stephen Rothwell   [PATCH] powerpc: ...
143
  		bus_addr = pci_map_single(ppc64_isabridge_dev, addr, size, dir);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
  
  	/* remember this one as prev */
  	prev_addr = addr;
  	prev_size = size;
  	prev_dir = dir;
  
  	fd_clear_dma_ff();
  	fd_cacheflush(addr, size);
  	fd_set_dma_mode(mode);
  	set_dma_addr(FLOPPY_DMA, bus_addr);
  	fd_set_dma_count(size);
  	virtual_dma_port = io;
  	fd_enable_dma();
  
  	return 0;
  }
9ea8b7c96   Pavel Fedin   [POWERPC] Virtual...
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
  static struct fd_dma_ops real_dma_ops =
  {
  	._disable_dma = disable_dma,
  	._free_dma = free_dma,
  	._get_dma_residue = get_dma_residue,
  	._dma_setup = hard_dma_setup
  };
  
  static struct fd_dma_ops virt_dma_ops =
  {
  	._disable_dma = vdma_disable_dma,
  	._free_dma = vdma_nop,
  	._get_dma_residue = vdma_get_dma_residue,
  	._dma_setup = vdma_dma_setup
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
175

1be9ab056   Al Viro   [PATCH] ANSIfy po...
176
  static int fd_request_dma(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
177
  {
9ea8b7c96   Pavel Fedin   [POWERPC] Virtual...
178
179
180
181
182
183
184
185
  	if (can_use_virtual_dma & 1) {
  		fd_ops = &virt_dma_ops;
  		return 0;
  	}
  	else {
  		fd_ops = &real_dma_ops;
  		return request_dma(FLOPPY_DMA, "floppy");
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
  }
  
  static int FDC1 = 0x3f0;
  static int FDC2 = -1;
  
  /*
   * Again, the CMOS information not available
   */
  #define FLOPPY0_TYPE 6
  #define FLOPPY1_TYPE 0
  
  #define N_FDC 2			/* Don't change this! */
  #define N_DRIVE 8
  
  #define FLOPPY_MOTOR_MASK 0xf0
  
  /*
   * The PowerPC has no problems with floppy DMA crossing 64k borders.
   */
  #define CROSS_64KB(a,s)	(0)
  
  #define EXTRA_FLOPPY_PARAMS
88ced0314   Arnd Bergmann   [PATCH] powerpc: ...
208
  #endif /* __KERNEL__ */
c55377ee7   Paul Mackerras   powerpc: Move a b...
209
  #endif /* __ASM_POWERPC_FLOPPY_H */