aboutsummaryrefslogtreecommitdiffstats
path: root/Documentation/parport.txt
blob: 93a7ceef398d3841c95cb7e0fe17709511892f08 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
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
86
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
The `parport' code provides parallel-port support under Linux.  This
includes the ability to share one port between multiple device
drivers.

You can pass parameters to the parport code to override its automatic
detection of your hardware.  This is particularly useful if you want
to use IRQs, since in general these can't be autoprobed successfully.
By default IRQs are not used even if they _can_ be probed.  This is
because there are a lot of people using the same IRQ for their
parallel port and a sound card or network card.

The parport code is split into two parts: generic (which deals with
port-sharing) and architecture-dependent (which deals with actually
using the port).


Parport as modules
==================

If you load the parport code as a module, say

	# insmod parport

to load the generic parport code.  You then must load the
architecture-dependent code with (for example):

	# insmod parport_pc io=0x3bc,0x378,0x278 irq=none,7,auto

to tell the parport code that you want three PC-style ports, one at
0x3bc with no IRQ, one at 0x378 using IRQ 7, and one at 0x278 with an
auto-detected IRQ.  Currently, PC-style (parport_pc), Sun `bpp',
Amiga, Atari, and MFC3 hardware is supported.

PCI parallel I/O card support comes from parport_pc.  Base I/O
addresses should not be specified for supported PCI cards since they
are automatically detected.


KMod
----

If you use kmod, you will find it useful to edit /etc/modprobe.conf.
Here is an example of the lines that need to be added:

	alias parport_lowlevel parport_pc
	options parport_pc io=0x378,0x278 irq=7,auto

KMod will then automatically load parport_pc (with the options
"io=0x378,0x278 irq=7,auto") whenever a parallel port device driver
(such as lp) is loaded.

Note that these are example lines only!  You shouldn't in general need
to specify any options to parport_pc in order to be able to use a
parallel port.


Parport probe [optional]
-------------

In 2.2 kernels there was a module called parport_probe, which was used
for collecting IEEE 1284 device ID information.  This has now been
enhanced and now lives with the IEEE 1284 support.  When a parallel
port is detected, the devices that are connected to it are analysed,
and information is logged like this:

	parport0: Printer, BJC-210 (Canon)

The probe information is available from files in /proc/sys/dev/parport/.


Parport linked into the kernel statically
=========================================

If you compile the parport code into the kernel, then you can use
kernel boot parameters to get the same effect.  Add something like the
following to your LILO command line:

	parport=0x3bc parport=0x378,7 parport=0x278,auto,nofifo

You can have many `parport=...' statements, one for each port you want
to add.  Adding `parport=0' to the kernel command-line will disable
parport support entirely.  Adding `parport=auto' to the kernel
command-line will make parport use any IRQ lines or DMA channels that
it auto-detects.


Files in /proc
==============

If you have configured the /proc filesystem into your kernel, you will
see a new directory entry: /proc/sys/dev/parport.  In there will be a
directory entry for each parallel port for which parport is
configured.  In each of those directories are a collection of files
describing that parallel port.

The /proc/sys/dev/parport directory tree looks like:

parport
|-- default
|   |-- spintime
|   `-- timeslice
|-- parport0
|   |-- autoprobe
|   |-- autoprobe0
|   |-- autoprobe1
|   |-- autoprobe2
|   |-- autoprobe3
|   |-- devices
|   |   |-- active
|   |   `-- lp
|   |       `-- timeslice
|   |-- base-addr
|   |-- irq
|   |-- dma
|   |-- modes
|   `-- spintime
`-- parport1
    |-- autoprobe
    |-- autoprobe0
    |-- autoprobe1
    |-- autoprobe2
    |-- autoprobe3
    |-- devices
    |   |-- active
    |   `-- ppa
    |       `-- timeslice
    |-- base-addr
    |-- irq
    |-- dma
    |-- modes
    `-- spintime


File:		Contents:

devices/active	A list of the device drivers using that port.  A "+"
		will appear by the name of the device currently using
		the port (it might not appear against any).  The
		string "none" means that there are no device drivers
		using that port.

base-addr	Parallel port's base address, or addresses if the port
		has more than one in which case they are separated
		with tabs.  These values might not have any sensible
		meaning for some ports.

irq		Parallel port's IRQ, or -1 if none is being used.

dma		Parallel port's DMA channel, or -1 if none is being
		used.

modes		Parallel port's hardware modes, comma-separated,
		meaning:

		PCSPP		PC-style SPP registers are available.
		TRISTATE	Port is bidirectional.
		COMPAT		Hardware acceleration for printers is
				available and will be used.
		EPP		Hardware acceleration for EPP protocol
				is available and will be used.
		ECP		Hardware acceleration for ECP protocol
				is available and will be used.
		DMA		DMA is available and will be used.

		Note that the current implementation will only take
		advantage of COMPAT and ECP modes if it has an IRQ
		line to use.

autoprobe	Any IEEE-1284 device ID information that has been
		acquired from the (non-IEEE 1284.3) device.

autoprobe[0-3]	IEEE 1284 device ID information retrieved from
		daisy-chain devices that conform to IEEE 1284.3.

spintime	The number of microseconds to busy-loop while waiting
		for the peripheral to respond.  You might find thatan>
	ands	r4, r4, r1, lsr #3		@ find maximum number on the way size
	clz	r5, r4				@ find bit position of way size increment
	ldr	r7, =0x7fff
	ands	r7, r7, r1, lsr #13		@ extract max number of the index size
loop2:
	mov	r9, r4				@ create working copy of max way size
loop3:
	orr	r11, r10, r9, lsl r5		@ factor way and cache number into r11
	orr	r11, r11, r7, lsl r2		@ factor index number into r11
	mcr	p15, 0, r11, c7, c14, 2		@ clean & invalidate by set/way
	subs	r9, r9, #1			@ decrement the way
	bge	loop3
	subs	r7, r7, #1			@ decrement the index
	bge	loop2
skip:
	add	r10, r10, #2			@ increment cache number
	cmp	r3, r10
	bgt	loop1
finished:
	mov	r10, #0				@ swith back to cache level 0
	mcr	p15, 2, r10, c0, c0, 0		@ select current cache level in cssr
	isb
	mov	pc, lr

/*
 *	v7_flush_cache_all()
 *
 *	Flush the entire cache system.
 *  The data cache flush is now achieved using atomic clean / invalidates
 *  working outwards from L1 cache. This is done using Set/Way based cache
 *  maintainance instructions.
 *  The instruction cache can still be invalidated back to the point of
 *  unification in a single instruction.
 *
 */
ENTRY(v7_flush_kern_cache_all)
	stmfd	sp!, {r4-r5, r7, r9-r11, lr}
	bl	v7_flush_dcache_all
	mov	r0, #0
	mcr	p15, 0, r0, c7, c5, 0		@ I+BTB cache invalidate
	ldmfd	sp!, {r4-r5, r7, r9-r11, lr}
	mov	pc, lr

/*
 *	v7_flush_cache_all()
 *
 *	Flush all TLB entries in a particular address space
 *
 *	- mm    - mm_struct describing address space
 */
ENTRY(v7_flush_user_cache_all)
	/*FALLTHROUGH*/

/*
 *	v7_flush_cache_range(start, end, flags)
 *
 *	Flush a range of TLB entries in the specified address space.
 *
 *	- start - start address (may not be aligned)
 *	- end   - end address (exclusive, may not be aligned)
 *	- flags	- vm_area_struct flags describing address space
 *
 *	It is assumed that:
 *	- we have a VIPT cache.
 */
ENTRY(v7_flush_user_cache_range)
	mov	pc, lr

/*
 *	v7_coherent_kern_range(start,end)
 *
 *	Ensure that the I and D caches are coherent within specified
 *	region.  This is typically used when code has been written to
 *	a memory region, and will be executed.
 *
 *	- start   - virtual start address of region
 *	- end     - virtual end address of region
 *
 *	It is assumed that:
 *	- the Icache does not read data from the write buffer
 */
ENTRY(v7_coherent_kern_range)
	/* FALLTHROUGH */

/*
 *	v7_coherent_user_range(start,end)
 *
 *	Ensure that the I and D caches are coherent within specified
 *	region.  This is typically used when code has been written to
 *	a memory region, and will be executed.
 *
 *	- start   - virtual start address of region
 *	- end     - virtual end address of region
 *
 *	It is assumed that:
 *	- the Icache does not read data from the write buffer
 */
ENTRY(v7_coherent_user_range)
	dcache_line_size r2, r3
	sub	r3, r2, #1
	bic	r0, r0, r3
1:	mcr	p15, 0, r0, c7, c11, 1		@ clean D line to the point of unification
	dsb
	mcr	p15, 0, r0, c7, c5, 1		@ invalidate I line
	add	r0, r0, r2
	cmp	r0, r1
	blo	1b
	mov	r0, #0
	mcr	p15, 0, r0, c7, c5, 6		@ invalidate BTB
	dsb
	isb
	mov	pc, lr

/*
 *	v7_flush_kern_dcache_page(kaddr)
 *
 *	Ensure that the data held in the page kaddr is written back
 *	to the page in question.
 *
 *	- kaddr   - kernel address (guaranteed to be page aligned)
 */
ENTRY(v7_flush_kern_dcache_page)
	dcache_line_size r2, r3
	add	r1, r0, #PAGE_SZ
1:
	mcr	p15, 0, r0, c7, c14, 1		@ clean & invalidate D line / unified line
	add	r0, r0, r2
	cmp	r0, r1
	blo	1b
	dsb
	mov	pc, lr

/*
 *	v7_dma_inv_range(start,end)
 *
 *	Invalidate the data cache within the specified region; we will
 *	be performing a DMA operation in this region and we want to
 *	purge old data in the cache.
 *
 *	- start   - virtual start address of region
 *	- end     - virtual end address of region
 */
ENTRY(v7_dma_inv_range)
	dcache_line_size r2, r3
	sub	r3, r2, #1
	tst	r0, r3
	bic	r0, r0, r3
	mcrne	p15, 0, r0, c7, c14, 1		@ clean & invalidate D / U line

	tst	r1, r3
	bic	r1, r1, r3
	mcrne	p15, 0, r1, c7, c14, 1		@ clean & invalidate D / U line
1:
	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D / U line
	add	r0, r0, r2
	cmp	r0, r1
	blo	1b
	dsb
	mov	pc, lr

/*
 *	v7_dma_clean_range(start,end)
 *	- start   - virtual start address of region
 *	- end     - virtual end address of region
 */
ENTRY(v7_dma_clean_range)
	dcache_line_size r2, r3
	sub	r3, r2, #1
	bic	r0, r0, r3
1:
	mcr	p15, 0, r0, c7, c10, 1		@ clean D / U line
	add	r0, r0, r2
	cmp	r0, r1
	blo	1b
	dsb
	mov	pc, lr

/*
 *	v7_dma_flush_range(start,end)
 *	- start   - virtual start address of region
 *	- end     - virtual end address of region
 */
ENTRY(v7_dma_flush_range)
	dcache_line_size r2, r3
	sub	r3, r2, #1
	bic	r0, r0, r3
1:
	mcr	p15, 0, r0, c7, c14, 1		@ clean & invalidate D / U line
	add	r0, r0, r2
	cmp	r0, r1
	blo	1b
	dsb
	mov	pc, lr

	__INITDATA

	.type	v7_cache_fns, #object
ENTRY(v7_cache_fns)
	.long	v7_flush_kern_cache_all
	.long	v7_flush_user_cache_all
	.long	v7_flush_user_cache_range
	.long	v7_coherent_kern_range
	.long	v7_coherent_user_range
	.long	v7_flush_kern_dcache_page
	.long	v7_dma_inv_range
	.long	v7_dma_clean_range
	.long	v7_dma_flush_range
	.size	v7_cache_fns, . - v7_cache_fns