aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/paride
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/block/paride
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'drivers/block/paride')
-rw-r--r--drivers/block/paride/Kconfig305
-rw-r--r--drivers/block/paride/Makefile28
-rw-r--r--drivers/block/paride/Transition-notes128
-rw-r--r--drivers/block/paride/aten.c162
-rw-r--r--drivers/block/paride/bpck.c477
-rw-r--r--drivers/block/paride/bpck6.c282
-rw-r--r--drivers/block/paride/comm.c218
-rw-r--r--drivers/block/paride/dstr.c233
-rw-r--r--drivers/block/paride/epat.c340
-rw-r--r--drivers/block/paride/epia.c316
-rw-r--r--drivers/block/paride/fit2.c151
-rw-r--r--drivers/block/paride/fit3.c211
-rw-r--r--drivers/block/paride/friq.c276
-rw-r--r--drivers/block/paride/frpw.c313
-rw-r--r--drivers/block/paride/jumbo70
-rw-r--r--drivers/block/paride/kbic.c297
-rw-r--r--drivers/block/paride/ktti.c128
-rw-r--r--drivers/block/paride/mkd30
-rw-r--r--drivers/block/paride/on20.c153
-rw-r--r--drivers/block/paride/on26.c319
-rw-r--r--drivers/block/paride/paride.c467
-rw-r--r--drivers/block/paride/paride.h170
-rw-r--r--drivers/block/paride/pcd.c971
-rw-r--r--drivers/block/paride/pd.c950
-rw-r--r--drivers/block/paride/pf.c982
-rw-r--r--drivers/block/paride/pg.c723
-rw-r--r--drivers/block/paride/ppc6lnx.c726
-rw-r--r--drivers/block/paride/pseudo.h102
-rw-r--r--drivers/block/paride/pt.c1024
29 files changed, 10552 insertions, 0 deletions
diff --git a/drivers/block/paride/Kconfig b/drivers/block/paride/Kconfig
new file mode 100644
index 000000000000..17ff40561257
--- /dev/null
+++ b/drivers/block/paride/Kconfig
@@ -0,0 +1,305 @@
1#
2# PARIDE configuration
3#
4# PARIDE doesn't need PARPORT, but if PARPORT is configured as a module,
5# PARIDE must also be a module. The bogus CONFIG_PARIDE_PARPORT option
6# controls the choices given to the user ...
7config PARIDE_PARPORT
8 tristate
9 depends on PARIDE!=n
10 default m if PARPORT=m
11 default y if PARPORT!=m
12
13comment "Parallel IDE high-level drivers"
14 depends on PARIDE
15
16config PARIDE_PD
17 tristate "Parallel port IDE disks"
18 depends on PARIDE
19 help
20 This option enables the high-level driver for IDE-type disk devices
21 connected through a parallel port. If you chose to build PARIDE
22 support into your kernel, you may answer Y here to build in the
23 parallel port IDE driver, otherwise you should answer M to build
24 it as a loadable module. The module will be called pd. You
25 must also have at least one parallel port protocol driver in your
26 system. Among the devices supported by this driver are the SyQuest
27 EZ-135, EZ-230 and SparQ drives, the Avatar Shark and the backpack
28 hard drives from MicroSolutions.
29
30config PARIDE_PCD
31 tristate "Parallel port ATAPI CD-ROMs"
32 depends on PARIDE
33 ---help---
34 This option enables the high-level driver for ATAPI CD-ROM devices
35 connected through a parallel port. If you chose to build PARIDE
36 support into your kernel, you may answer Y here to build in the
37 parallel port ATAPI CD-ROM driver, otherwise you should answer M to
38 build it as a loadable module. The module will be called pcd. You
39 must also have at least one parallel port protocol driver in your
40 system. Among the devices supported by this driver are the
41 MicroSolutions backpack CD-ROM drives and the Freecom Power CD. If
42 you have such a CD-ROM drive, you should also say Y or M to "ISO
43 9660 CD-ROM file system support" below, because that's the file
44 system used on CD-ROMs.
45
46config PARIDE_PF
47 tristate "Parallel port ATAPI disks"
48 depends on PARIDE
49 help
50 This option enables the high-level driver for ATAPI disk devices
51 connected through a parallel port. If you chose to build PARIDE
52 support into your kernel, you may answer Y here to build in the
53 parallel port ATAPI disk driver, otherwise you should answer M
54 to build it as a loadable module. The module will be called pf.
55 You must also have at least one parallel port protocol driver in
56 your system. Among the devices supported by this driver are the
57 MicroSolutions backpack PD/CD drive and the Imation Superdisk
58 LS-120 drive.
59
60config PARIDE_PT
61 tristate "Parallel port ATAPI tapes"
62 depends on PARIDE
63 help
64 This option enables the high-level driver for ATAPI tape devices
65 connected through a parallel port. If you chose to build PARIDE
66 support into your kernel, you may answer Y here to build in the
67 parallel port ATAPI disk driver, otherwise you should answer M
68 to build it as a loadable module. The module will be called pt.
69 You must also have at least one parallel port protocol driver in
70 your system. Among the devices supported by this driver is the
71 parallel port version of the HP 5GB drive.
72
73config PARIDE_PG
74 tristate "Parallel port generic ATAPI devices"
75 depends on PARIDE
76 ---help---
77 This option enables a special high-level driver for generic ATAPI
78 devices connected through a parallel port. The driver allows user
79 programs, such as cdrtools, to send ATAPI commands directly to a
80 device.
81
82 If you chose to build PARIDE support into your kernel, you may
83 answer Y here to build in the parallel port generic ATAPI driver,
84 otherwise you should answer M to build it as a loadable module. The
85 module will be called pg.
86
87 You must also have at least one parallel port protocol driver in
88 your system.
89
90 This driver implements an API loosely related to the generic SCSI
91 driver. See <file:include/linux/pg.h>. for details.
92
93 You can obtain the most recent version of cdrtools from
94 <ftp://ftp.berlios.de/pub/cdrecord/>. Versions 1.6.1a3 and
95 later fully support this driver.
96
97comment "Parallel IDE protocol modules"
98 depends on PARIDE
99
100config PARIDE_ATEN
101 tristate "ATEN EH-100 protocol"
102 depends on PARIDE
103 help
104 This option enables support for the ATEN EH-100 parallel port IDE
105 protocol. This protocol is used in some inexpensive low performance
106 parallel port kits made in Hong Kong. If you chose to build PARIDE
107 support into your kernel, you may answer Y here to build in the
108 protocol driver, otherwise you should answer M to build it as a
109 loadable module. The module will be called aten. You must also
110 have a high-level driver for the type of device that you want to
111 support.
112
113config PARIDE_BPCK
114 tristate "MicroSolutions backpack (Series 5) protocol"
115 depends on PARIDE
116 ---help---
117 This option enables support for the Micro Solutions BACKPACK
118 parallel port Series 5 IDE protocol. (Most BACKPACK drives made
119 before 1999 were Series 5) Series 5 drives will NOT always have the
120 Series noted on the bottom of the drive. Series 6 drivers will.
121
122 In other words, if your BACKPACK drive doesn't say "Series 6" on the
123 bottom, enable this option.
124
125 If you chose to build PARIDE support into your kernel, you may
126 answer Y here to build in the protocol driver, otherwise you should
127 answer M to build it as a loadable module. The module will be
128 called bpck. You must also have a high-level driver for the type
129 of device that you want to support.
130
131config PARIDE_BPCK6
132 tristate "MicroSolutions backpack (Series 6) protocol"
133 depends on PARIDE && !64BIT
134 ---help---
135 This option enables support for the Micro Solutions BACKPACK
136 parallel port Series 6 IDE protocol. (Most BACKPACK drives made
137 after 1999 were Series 6) Series 6 drives will have the Series noted
138 on the bottom of the drive. Series 5 drivers don't always have it
139 noted.
140
141 In other words, if your BACKPACK drive says "Series 6" on the
142 bottom, enable this option.
143
144 If you chose to build PARIDE support into your kernel, you may
145 answer Y here to build in the protocol driver, otherwise you should
146 answer M to build it as a loadable module. The module will be
147 called bpck6. You must also have a high-level driver for the type
148 of device that you want to support.
149
150config PARIDE_COMM
151 tristate "DataStor Commuter protocol"
152 depends on PARIDE
153 help
154 This option enables support for the Commuter parallel port IDE
155 protocol from DataStor. If you chose to build PARIDE support
156 into your kernel, you may answer Y here to build in the protocol
157 driver, otherwise you should answer M to build it as a loadable
158 module. The module will be called comm. You must also have
159 a high-level driver for the type of device that you want to support.
160
161config PARIDE_DSTR
162 tristate "DataStor EP-2000 protocol"
163 depends on PARIDE
164 help
165 This option enables support for the EP-2000 parallel port IDE
166 protocol from DataStor. If you chose to build PARIDE support
167 into your kernel, you may answer Y here to build in the protocol
168 driver, otherwise you should answer M to build it as a loadable
169 module. The module will be called dstr. You must also have
170 a high-level driver for the type of device that you want to support.
171
172config PARIDE_FIT2
173 tristate "FIT TD-2000 protocol"
174 depends on PARIDE
175 help
176 This option enables support for the TD-2000 parallel port IDE
177 protocol from Fidelity International Technology. This is a simple
178 (low speed) adapter that is used in some portable hard drives. If
179 you chose to build PARIDE support into your kernel, you may answer Y
180 here to build in the protocol driver, otherwise you should answer M
181 to build it as a loadable module. The module will be called ktti.
182 You must also have a high-level driver for the type of device that
183 you want to support.
184
185config PARIDE_FIT3
186 tristate "FIT TD-3000 protocol"
187 depends on PARIDE
188 help
189 This option enables support for the TD-3000 parallel port IDE
190 protocol from Fidelity International Technology. This protocol is
191 used in newer models of their portable disk, CD-ROM and PD/CD
192 devices. If you chose to build PARIDE support into your kernel, you
193 may answer Y here to build in the protocol driver, otherwise you
194 should answer M to build it as a loadable module. The module will be
195 called fit3. You must also have a high-level driver for the type
196 of device that you want to support.
197
198config PARIDE_EPAT
199 tristate "Shuttle EPAT/EPEZ protocol"
200 depends on PARIDE
201 help
202 This option enables support for the EPAT parallel port IDE protocol.
203 EPAT is a parallel port IDE adapter manufactured by Shuttle
204 Technology and widely used in devices from major vendors such as
205 Hewlett-Packard, SyQuest, Imation and Avatar. If you chose to build
206 PARIDE support into your kernel, you may answer Y here to build in
207 the protocol driver, otherwise you should answer M to build it as a
208 loadable module. The module will be called epat. You must also
209 have a high-level driver for the type of device that you want to
210 support.
211
212config PARIDE_EPATC8
213 bool "Support c7/c8 chips (EXPERIMENTAL)"
214 depends on PARIDE_EPAT && EXPERIMENTAL
215 help
216 This option enables support for the newer Shuttle EP1284 (aka c7 and
217 c8) chip. You need this if you are using any recent Imation SuperDisk
218 (LS-120) drive.
219
220config PARIDE_EPIA
221 tristate "Shuttle EPIA protocol"
222 depends on PARIDE
223 help
224 This option enables support for the (obsolete) EPIA parallel port
225 IDE protocol from Shuttle Technology. This adapter can still be
226 found in some no-name kits. If you chose to build PARIDE support
227 into your kernel, you may answer Y here to build in the protocol
228 driver, otherwise you should answer M to build it as a loadable
229 module. The module will be called epia. You must also have a
230 high-level driver for the type of device that you want to support.
231
232config PARIDE_FRIQ
233 tristate "Freecom IQ ASIC-2 protocol"
234 depends on PARIDE
235 help
236 This option enables support for version 2 of the Freecom IQ parallel
237 port IDE adapter. This adapter is used by the Maxell Superdisk
238 drive. If you chose to build PARIDE support into your kernel, you
239 may answer Y here to build in the protocol driver, otherwise you
240 should answer M to build it as a loadable module. The module will be
241 called friq. You must also have a high-level driver for the type
242 of device that you want to support.
243
244config PARIDE_FRPW
245 tristate "FreeCom power protocol"
246 depends on PARIDE
247 help
248 This option enables support for the Freecom power parallel port IDE
249 protocol. If you chose to build PARIDE support into your kernel, you
250 may answer Y here to build in the protocol driver, otherwise you
251 should answer M to build it as a loadable module. The module will be
252 called frpw. You must also have a high-level driver for the type
253 of device that you want to support.
254
255config PARIDE_KBIC
256 tristate "KingByte KBIC-951A/971A protocols"
257 depends on PARIDE
258 help
259 This option enables support for the KBIC-951A and KBIC-971A parallel
260 port IDE protocols from KingByte Information Corp. KingByte's
261 adapters appear in many no-name portable disk and CD-ROM products,
262 especially in Europe. If you chose to build PARIDE support into your
263 kernel, you may answer Y here to build in the protocol driver,
264 otherwise you should answer M to build it as a loadable module. The
265 module will be called kbic. You must also have a high-level driver
266 for the type of device that you want to support.
267
268config PARIDE_KTTI
269 tristate "KT PHd protocol"
270 depends on PARIDE
271 help
272 This option enables support for the "PHd" parallel port IDE protocol
273 from KT Technology. This is a simple (low speed) adapter that is
274 used in some 2.5" portable hard drives. If you chose to build PARIDE
275 support into your kernel, you may answer Y here to build in the
276 protocol driver, otherwise you should answer M to build it as a
277 loadable module. The module will be called ktti. You must also
278 have a high-level driver for the type of device that you want to
279 support.
280
281config PARIDE_ON20
282 tristate "OnSpec 90c20 protocol"
283 depends on PARIDE
284 help
285 This option enables support for the (obsolete) 90c20 parallel port
286 IDE protocol from OnSpec (often marketed under the ValuStore brand
287 name). If you chose to build PARIDE support into your kernel, you
288 may answer Y here to build in the protocol driver, otherwise you
289 should answer M to build it as a loadable module. The module will
290 be called on20. You must also have a high-level driver for the
291 type of device that you want to support.
292
293config PARIDE_ON26
294 tristate "OnSpec 90c26 protocol"
295 depends on PARIDE
296 help
297 This option enables support for the 90c26 parallel port IDE protocol
298 from OnSpec Electronics (often marketed under the ValuStore brand
299 name). If you chose to build PARIDE support into your kernel, you
300 may answer Y here to build in the protocol driver, otherwise you
301 should answer M to build it as a loadable module. The module will be
302 called on26. You must also have a high-level driver for the type
303 of device that you want to support.
304
305#
diff --git a/drivers/block/paride/Makefile b/drivers/block/paride/Makefile
new file mode 100644
index 000000000000..a539e004bb7a
--- /dev/null
+++ b/drivers/block/paride/Makefile
@@ -0,0 +1,28 @@
1#
2# Makefile for Parallel port IDE device drivers.
3#
4# 7 October 2000, Bartlomiej Zolnierkiewicz <bkz@linux-ide.org>
5# Rewritten to use lists instead of if-statements.
6#
7
8obj-$(CONFIG_PARIDE) += paride.o
9obj-$(CONFIG_PARIDE_ATEN) += aten.o
10obj-$(CONFIG_PARIDE_BPCK) += bpck.o
11obj-$(CONFIG_PARIDE_COMM) += comm.o
12obj-$(CONFIG_PARIDE_DSTR) += dstr.o
13obj-$(CONFIG_PARIDE_KBIC) += kbic.o
14obj-$(CONFIG_PARIDE_EPAT) += epat.o
15obj-$(CONFIG_PARIDE_EPIA) += epia.o
16obj-$(CONFIG_PARIDE_FRPW) += frpw.o
17obj-$(CONFIG_PARIDE_FRIQ) += friq.o
18obj-$(CONFIG_PARIDE_FIT2) += fit2.o
19obj-$(CONFIG_PARIDE_FIT3) += fit3.o
20obj-$(CONFIG_PARIDE_ON20) += on20.o
21obj-$(CONFIG_PARIDE_ON26) += on26.o
22obj-$(CONFIG_PARIDE_KTTI) += ktti.o
23obj-$(CONFIG_PARIDE_BPCK6) += bpck6.o
24obj-$(CONFIG_PARIDE_PD) += pd.o
25obj-$(CONFIG_PARIDE_PCD) += pcd.o
26obj-$(CONFIG_PARIDE_PF) += pf.o
27obj-$(CONFIG_PARIDE_PT) += pt.o
28obj-$(CONFIG_PARIDE_PG) += pg.o
diff --git a/drivers/block/paride/Transition-notes b/drivers/block/paride/Transition-notes
new file mode 100644
index 000000000000..70374907c020
--- /dev/null
+++ b/drivers/block/paride/Transition-notes
@@ -0,0 +1,128 @@
1Lemma 1:
2 If ps_tq is scheduled, ps_tq_active is 1. ps_tq_int() can be called
3 only when ps_tq_active is 1.
4Proof: All assignments to ps_tq_active and all scheduling of ps_tq happen
5 under ps_spinlock. There are three places where that can happen:
6 one in ps_set_intr() (A) and two in ps_tq_int() (B and C).
7 Consider the sequnce of these events. A can not be preceded by
8 anything except B, since it is under if (!ps_tq_active) under
9 ps_spinlock. C is always preceded by B, since we can't reach it
10 other than through B and we don't drop ps_spinlock between them.
11 IOW, the sequence is A?(BA|BC|B)*. OTOH, number of B can not exceed
12 the sum of numbers of A and C, since each call of ps_tq_int() is
13 the result of ps_tq execution. Therefore, the sequence starts with
14 A and each B is preceded by either A or C. Moments when we enter
15 ps_tq_int() are sandwiched between {A,C} and B in that sequence,
16 since at any time number of B can not exceed the number of these
17 moments which, in turn, can not exceed the number of A and C.
18 In other words, the sequence of events is (A or C set ps_tq_active to
19 1 and schedule ps_tq, ps_tq is executed, ps_tq_int() is entered,
20 B resets ps_tq_active)*.
21
22
23consider the following area:
24 * in do_pd_request1(): to calls of pi_do_claimed() and return in
25 case when pd_req is NULL.
26 * in next_request(): to call of do_pd_request1()
27 * in do_pd_read(): to call of ps_set_intr()
28 * in do_pd_read_start(): to calls of pi_do_claimed(), next_request()
29and ps_set_intr()
30 * in do_pd_read_drq(): to calls of pi_do_claimed() and next_request()
31 * in do_pd_write(): to call of ps_set_intr()
32 * in do_pd_write_start(): to calls of pi_do_claimed(), next_request()
33and ps_set_intr()
34 * in do_pd_write_done(): to calls of pi_do_claimed() and next_request()
35 * in ps_set_intr(): to check for ps_tq_active and to scheduling
36 ps_tq if ps_tq_active was 0.
37 * in ps_tq_int(): from the moment when we get ps_spinlock() to the
38 return, call of con() or scheduling ps_tq.
39 * in pi_schedule_claimed() when called from pi_do_claimed() called from
40 pd.c, everything until returning 1 or setting or setting ->claim_cont
41 on the path that returns 0
42 * in pi_do_claimed() when called from pd.c, everything until the call
43 of pi_do_claimed() plus the everything until the call of cont() if
44 pi_do_claimed() has returned 1.
45 * in pi_wake_up() called for PIA that belongs to pd.c, everything from
46 the moment when pi_spinlock has been acquired.
47
48Lemma 2:
49 1) at any time at most one thread of execution can be in that area or
50 be preempted there.
51 2) When there is such a thread, pd_busy is set or pd_lock is held by
52 that thread.
53 3) When there is such a thread, ps_tq_active is 0 or ps_spinlock is
54 held by that thread.
55 4) When there is such a thread, all PIA belonging to pd.c have NULL
56 ->claim_cont or pi_spinlock is held by thread in question.
57
58Proof: consider the first moment when the above is not true.
59
60(1) can become not true if some thread enters that area while another is there.
61 a) do_pd_request1() can be called from next_request() or do_pd_request()
62 In the first case the thread was already in the area. In the second,
63 the thread was holding pd_lock and found pd_busy not set, which would
64 mean that (2) was already not true.
65 b) ps_set_intr() and pi_schedule_claimed() can be called only from the
66 area.
67 c) pi_do_claimed() is called by pd.c only from the area.
68 d) ps_tq_int() can enter the area only when the thread is holding
69 ps_spinlock and ps_tq_active is 1 (due to Lemma 1). It means that
70 (3) was already not true.
71 e) do_pd_{read,write}* could be called only from the area. The only
72 case that needs consideration is call from pi_wake_up() and there
73 we would have to be called for the PIA that got ->claimed_cont
74 from pd.c. That could happen only if pi_do_claimed() had been
75 called from pd.c for that PIA, which happens only for PIA belonging
76 to pd.c.
77 f) pi_wake_up() can enter the area only when the thread is holding
78 pi_spinlock and ->claimed_cont is non-NULL for PIA belonging to
79 pd.c. It means that (4) was already not true.
80
81(2) can become not true only when pd_lock is released by the thread in question.
82 Indeed, pd_busy is reset only in the area and thread that resets
83 it is holding pd_lock. The only place within the area where we
84 release pd_lock is in pd_next_buf() (called from within the area).
85 But that code does not reset pd_busy, so pd_busy would have to be
86 0 when pd_next_buf() had acquired pd_lock. If it become 0 while
87 we were acquiring the lock, (1) would be already false, since
88 the thread that had reset it would be in the area simulateously.
89 If it was 0 before we tried to acquire pd_lock, (2) would be
90 already false.
91
92For similar reasons, (3) can become not true only when ps_spinlock is released
93by the thread in question. However, all such places within the area are right
94after resetting ps_tq_active to 0.
95
96(4) is done the same way - all places where we release pi_spinlock within
97the area are either after resetting ->claimed_cont to NULL while holding
98pi_spinlock, or after not tocuhing ->claimed_cont since acquiring pi_spinlock
99also in the area. The only place where ->claimed_cont is made non-NULL is
100in the area, under pi_spinlock and we do not release it until after leaving
101the area.
102
103QED.
104
105
106Corollary 1: ps_tq_active can be killed. Indeed, the only place where we
107check its value is in ps_set_intr() and if it had been non-zero at that
108point, we would have violated either (2.1) (if it was set while ps_set_intr()
109was acquiring ps_spinlock) or (2.3) (if it was set when we started to
110acquire ps_spinlock).
111
112Corollary 2: ps_spinlock can be killed. Indeed, Lemma 1 and Lemma 2 show
113that the only possible contention is between scheduling ps_tq followed by
114immediate release of spinlock and beginning of execution of ps_tq on
115another CPU.
116
117Corollary 3: assignment to pd_busy in do_pd_read_start() and do_pd_write_start()
118can be killed. Indeed, we are not holding pd_lock and thus pd_busy is already
1191 here.
120
121Corollary 4: in ps_tq_int() uses of con can be replaced with uses of
122ps_continuation, since the latter is changed only from the area.
123We don't need to reset it to NULL, since we are guaranteed that there
124will be a call of ps_set_intr() before we look at ps_continuation again.
125We can remove the check for ps_continuation being NULL for the same
126reason - the value is guaranteed to be set by the last ps_set_intr() and
127we never pass it NULL. Assignements in the beginning of ps_set_intr()
128can be taken to callers as long as they remain within the area.
diff --git a/drivers/block/paride/aten.c b/drivers/block/paride/aten.c
new file mode 100644
index 000000000000..c4d696d43dc1
--- /dev/null
+++ b/drivers/block/paride/aten.c
@@ -0,0 +1,162 @@
1/*
2 aten.c (c) 1997-8 Grant R. Guenther <grant@torque.net>
3 Under the terms of the GNU General Public License.
4
5 aten.c is a low-level protocol driver for the ATEN EH-100
6 parallel port adapter. The EH-100 supports 4-bit and 8-bit
7 modes only. There is also an EH-132 which supports EPP mode
8 transfers. The EH-132 is not yet supported.
9
10*/
11
12/* Changes:
13
14 1.01 GRG 1998.05.05 init_proto, release_proto
15
16*/
17
18#define ATEN_VERSION "1.01"
19
20#include <linux/module.h>
21#include <linux/init.h>
22#include <linux/delay.h>
23#include <linux/kernel.h>
24#include <linux/wait.h>
25#include <linux/types.h>
26#include <asm/io.h>
27
28#include "paride.h"
29
30#define j44(a,b) ((((a>>4)&0x0f)|(b&0xf0))^0x88)
31
32/* cont = 0 - access the IDE register file
33 cont = 1 - access the IDE command set
34*/
35
36static int cont_map[2] = { 0x08, 0x20 };
37
38static void aten_write_regr( PIA *pi, int cont, int regr, int val)
39
40{ int r;
41
42 r = regr + cont_map[cont] + 0x80;
43
44 w0(r); w2(0xe); w2(6); w0(val); w2(7); w2(6); w2(0xc);
45}
46
47static int aten_read_regr( PIA *pi, int cont, int regr )
48
49{ int a, b, r;
50
51 r = regr + cont_map[cont] + 0x40;
52
53 switch (pi->mode) {
54
55 case 0: w0(r); w2(0xe); w2(6);
56 w2(7); w2(6); w2(0);
57 a = r1(); w0(0x10); b = r1(); w2(0xc);
58 return j44(a,b);
59
60 case 1: r |= 0x10;
61 w0(r); w2(0xe); w2(6); w0(0xff);
62 w2(0x27); w2(0x26); w2(0x20);
63 a = r0();
64 w2(0x26); w2(0xc);
65 return a;
66 }
67 return -1;
68}
69
70static void aten_read_block( PIA *pi, char * buf, int count )
71
72{ int k, a, b, c, d;
73
74 switch (pi->mode) {
75
76 case 0: w0(0x48); w2(0xe); w2(6);
77 for (k=0;k<count/2;k++) {
78 w2(7); w2(6); w2(2);
79 a = r1(); w0(0x58); b = r1();
80 w2(0); d = r1(); w0(0x48); c = r1();
81 buf[2*k] = j44(c,d);
82 buf[2*k+1] = j44(a,b);
83 }
84 w2(0xc);
85 break;
86
87 case 1: w0(0x58); w2(0xe); w2(6);
88 for (k=0;k<count/2;k++) {
89 w2(0x27); w2(0x26); w2(0x22);
90 a = r0(); w2(0x20); b = r0();
91 buf[2*k] = b; buf[2*k+1] = a;
92 }
93 w2(0x26); w2(0xc);
94 break;
95 }
96}
97
98static void aten_write_block( PIA *pi, char * buf, int count )
99
100{ int k;
101
102 w0(0x88); w2(0xe); w2(6);
103 for (k=0;k<count/2;k++) {
104 w0(buf[2*k+1]); w2(0xe); w2(6);
105 w0(buf[2*k]); w2(7); w2(6);
106 }
107 w2(0xc);
108}
109
110static void aten_connect ( PIA *pi )
111
112{ pi->saved_r0 = r0();
113 pi->saved_r2 = r2();
114 w2(0xc);
115}
116
117static void aten_disconnect ( PIA *pi )
118
119{ w0(pi->saved_r0);
120 w2(pi->saved_r2);
121}
122
123static void aten_log_adapter( PIA *pi, char * scratch, int verbose )
124
125{ char *mode_string[2] = {"4-bit","8-bit"};
126
127 printk("%s: aten %s, ATEN EH-100 at 0x%x, ",
128 pi->device,ATEN_VERSION,pi->port);
129 printk("mode %d (%s), delay %d\n",pi->mode,
130 mode_string[pi->mode],pi->delay);
131
132}
133
134static struct pi_protocol aten = {
135 .owner = THIS_MODULE,
136 .name = "aten",
137 .max_mode = 2,
138 .epp_first = 2,
139 .default_delay = 1,
140 .max_units = 1,
141 .write_regr = aten_write_regr,
142 .read_regr = aten_read_regr,
143 .write_block = aten_write_block,
144 .read_block = aten_read_block,
145 .connect = aten_connect,
146 .disconnect = aten_disconnect,
147 .log_adapter = aten_log_adapter,
148};
149
150static int __init aten_init(void)
151{
152 return pi_register(&aten)-1;
153}
154
155static void __exit aten_exit(void)
156{
157 pi_unregister( &aten );
158}
159
160MODULE_LICENSE("GPL");
161module_init(aten_init)
162module_exit(aten_exit)
diff --git a/drivers/block/paride/bpck.c b/drivers/block/paride/bpck.c
new file mode 100644
index 000000000000..d462ff6b139d
--- /dev/null
+++ b/drivers/block/paride/bpck.c
@@ -0,0 +1,477 @@
1/*
2 bpck.c (c) 1996-8 Grant R. Guenther <grant@torque.net>
3 Under the terms of the GNU General Public License.
4
5 bpck.c is a low-level protocol driver for the MicroSolutions
6 "backpack" parallel port IDE adapter.
7
8*/
9
10/* Changes:
11
12 1.01 GRG 1998.05.05 init_proto, release_proto, pi->delay
13 1.02 GRG 1998.08.15 default pi->delay returned to 4
14
15*/
16
17#define BPCK_VERSION "1.02"
18
19#include <linux/module.h>
20#include <linux/init.h>
21#include <linux/delay.h>
22#include <linux/kernel.h>
23#include <linux/types.h>
24#include <linux/wait.h>
25#include <asm/io.h>
26
27#include "paride.h"
28
29#undef r2
30#undef w2
31
32#define PC pi->private
33#define r2() (PC=(in_p(2) & 0xff))
34#define w2(byte) {out_p(2,byte); PC = byte;}
35#define t2(pat) {PC ^= pat; out_p(2,PC);}
36#define e2() {PC &= 0xfe; out_p(2,PC);}
37#define o2() {PC |= 1; out_p(2,PC);}
38
39#define j44(l,h) (((l>>3)&0x7)|((l>>4)&0x8)|((h<<1)&0x70)|(h&0x80))
40
41/* cont = 0 - access the IDE register file
42 cont = 1 - access the IDE command set
43 cont = 2 - use internal bpck register addressing
44*/
45
46static int cont_map[3] = { 0x40, 0x48, 0 };
47
48static int bpck_read_regr( PIA *pi, int cont, int regr )
49
50{ int r, l, h;
51
52 r = regr + cont_map[cont];
53
54 switch (pi->mode) {
55
56 case 0: w0(r & 0xf); w0(r); t2(2); t2(4);
57 l = r1();
58 t2(4);
59 h = r1();
60 return j44(l,h);
61
62 case 1: w0(r & 0xf); w0(r); t2(2);
63 e2(); t2(0x20);
64 t2(4); h = r0();
65 t2(1); t2(0x20);
66 return h;
67
68 case 2:
69 case 3:
70 case 4: w0(r); w2(9); w2(0); w2(0x20);
71 h = r4();
72 w2(0);
73 return h;
74
75 }
76 return -1;
77}
78
79static void bpck_write_regr( PIA *pi, int cont, int regr, int val )
80
81{ int r;
82
83 r = regr + cont_map[cont];
84
85 switch (pi->mode) {
86
87 case 0:
88 case 1: w0(r);
89 t2(2);
90 w0(val);
91 o2(); t2(4); t2(1);
92 break;
93
94 case 2:
95 case 3:
96 case 4: w0(r); w2(9); w2(0);
97 w0(val); w2(1); w2(3); w2(0);
98 break;
99
100 }
101}
102
103/* These macros access the bpck registers in native addressing */
104
105#define WR(r,v) bpck_write_regr(pi,2,r,v)
106#define RR(r) (bpck_read_regr(pi,2,r))
107
108static void bpck_write_block( PIA *pi, char * buf, int count )
109
110{ int i;
111
112 switch (pi->mode) {
113
114 case 0: WR(4,0x40);
115 w0(0x40); t2(2); t2(1);
116 for (i=0;i<count;i++) { w0(buf[i]); t2(4); }
117 WR(4,0);
118 break;
119
120 case 1: WR(4,0x50);
121 w0(0x40); t2(2); t2(1);
122 for (i=0;i<count;i++) { w0(buf[i]); t2(4); }
123 WR(4,0x10);
124 break;
125
126 case 2: WR(4,0x48);
127 w0(0x40); w2(9); w2(0); w2(1);
128 for (i=0;i<count;i++) w4(buf[i]);
129 w2(0);
130 WR(4,8);
131 break;
132
133 case 3: WR(4,0x48);
134 w0(0x40); w2(9); w2(0); w2(1);
135 for (i=0;i<count/2;i++) w4w(((u16 *)buf)[i]);
136 w2(0);
137 WR(4,8);
138 break;
139
140 case 4: WR(4,0x48);
141 w0(0x40); w2(9); w2(0); w2(1);
142 for (i=0;i<count/4;i++) w4l(((u32 *)buf)[i]);
143 w2(0);
144 WR(4,8);
145 break;
146 }
147}
148
149static void bpck_read_block( PIA *pi, char * buf, int count )
150
151{ int i, l, h;
152
153 switch (pi->mode) {
154
155 case 0: WR(4,0x40);
156 w0(0x40); t2(2);
157 for (i=0;i<count;i++) {
158 t2(4); l = r1();
159 t2(4); h = r1();
160 buf[i] = j44(l,h);
161 }
162 WR(4,0);
163 break;
164
165 case 1: WR(4,0x50);
166 w0(0x40); t2(2); t2(0x20);
167 for(i=0;i<count;i++) { t2(4); buf[i] = r0(); }
168 t2(1); t2(0x20);
169 WR(4,0x10);
170 break;
171
172 case 2: WR(4,0x48);
173 w0(0x40); w2(9); w2(0); w2(0x20);
174 for (i=0;i<count;i++) buf[i] = r4();
175 w2(0);
176 WR(4,8);
177 break;
178
179 case 3: WR(4,0x48);
180 w0(0x40); w2(9); w2(0); w2(0x20);
181 for (i=0;i<count/2;i++) ((u16 *)buf)[i] = r4w();
182 w2(0);
183 WR(4,8);
184 break;
185
186 case 4: WR(4,0x48);
187 w0(0x40); w2(9); w2(0); w2(0x20);
188 for (i=0;i<count/4;i++) ((u32 *)buf)[i] = r4l();
189 w2(0);
190 WR(4,8);
191 break;
192
193 }
194}
195
196static int bpck_probe_unit ( PIA *pi )
197
198{ int o1, o0, f7, id;
199 int t, s;
200
201 id = pi->unit;
202 s = 0;
203 w2(4); w2(0xe); r2(); t2(2);
204 o1 = r1()&0xf8;
205 o0 = r0();
206 w0(255-id); w2(4); w0(id);
207 t2(8); t2(8); t2(8);
208 t2(2); t = r1()&0xf8;
209 f7 = ((id % 8) == 7);
210 if ((f7) || (t != o1)) { t2(2); s = r1()&0xf8; }
211 if ((t == o1) && ((!f7) || (s == o1))) {
212 w2(0x4c); w0(o0);
213 return 0;
214 }
215 t2(8); w0(0); t2(2); w2(0x4c); w0(o0);
216 return 1;
217}
218
219static void bpck_connect ( PIA *pi )
220
221{ pi->saved_r0 = r0();
222 w0(0xff-pi->unit); w2(4); w0(pi->unit);
223 t2(8); t2(8); t2(8);
224 t2(2); t2(2);
225
226 switch (pi->mode) {
227
228 case 0: t2(8); WR(4,0);
229 break;
230
231 case 1: t2(8); WR(4,0x10);
232 break;
233
234 case 2:
235 case 3:
236 case 4: w2(0); WR(4,8);
237 break;
238
239 }
240
241 WR(5,8);
242
243 if (pi->devtype == PI_PCD) {
244 WR(0x46,0x10); /* fiddle with ESS logic ??? */
245 WR(0x4c,0x38);
246 WR(0x4d,0x88);
247 WR(0x46,0xa0);
248 WR(0x41,0);
249 WR(0x4e,8);
250 }
251}
252
253static void bpck_disconnect ( PIA *pi )
254
255{ w0(0);
256 if (pi->mode >= 2) { w2(9); w2(0); } else t2(2);
257 w2(0x4c); w0(pi->saved_r0);
258}
259
260static void bpck_force_spp ( PIA *pi )
261
262/* This fakes the EPP protocol to turn off EPP ... */
263
264{ pi->saved_r0 = r0();
265 w0(0xff-pi->unit); w2(4); w0(pi->unit);
266 t2(8); t2(8); t2(8);
267 t2(2); t2(2);
268
269 w2(0);
270 w0(4); w2(9); w2(0);
271 w0(0); w2(1); w2(3); w2(0);
272 w0(0); w2(9); w2(0);
273 w2(0x4c); w0(pi->saved_r0);
274}
275
276#define TEST_LEN 16
277
278static int bpck_test_proto( PIA *pi, char * scratch, int verbose )
279
280{ int i, e, l, h, om;
281 char buf[TEST_LEN];
282
283 bpck_force_spp(pi);
284
285 switch (pi->mode) {
286
287 case 0: bpck_connect(pi);
288 WR(0x13,0x7f);
289 w0(0x13); t2(2);
290 for(i=0;i<TEST_LEN;i++) {
291 t2(4); l = r1();
292 t2(4); h = r1();
293 buf[i] = j44(l,h);
294 }
295 bpck_disconnect(pi);
296 break;
297
298 case 1: bpck_connect(pi);
299 WR(0x13,0x7f);
300 w0(0x13); t2(2); t2(0x20);
301 for(i=0;i<TEST_LEN;i++) { t2(4); buf[i] = r0(); }
302 t2(1); t2(0x20);
303 bpck_disconnect(pi);
304 break;
305
306 case 2:
307 case 3:
308 case 4: om = pi->mode;
309 pi->mode = 0;
310 bpck_connect(pi);
311 WR(7,3);
312 WR(4,8);
313 bpck_disconnect(pi);
314
315 pi->mode = om;
316 bpck_connect(pi);
317 w0(0x13); w2(9); w2(1); w0(0); w2(3); w2(0); w2(0xe0);
318
319 switch (pi->mode) {
320 case 2: for (i=0;i<TEST_LEN;i++) buf[i] = r4();
321 break;
322 case 3: for (i=0;i<TEST_LEN/2;i++) ((u16 *)buf)[i] = r4w();
323 break;
324 case 4: for (i=0;i<TEST_LEN/4;i++) ((u32 *)buf)[i] = r4l();
325 break;
326 }
327
328 w2(0);
329 WR(7,0);
330 bpck_disconnect(pi);
331
332 break;
333
334 }
335
336 if (verbose) {
337 printk("%s: bpck: 0x%x unit %d mode %d: ",
338 pi->device,pi->port,pi->unit,pi->mode);
339 for (i=0;i<TEST_LEN;i++) printk("%3d",buf[i]);
340 printk("\n");
341 }
342
343 e = 0;
344 for (i=0;i<TEST_LEN;i++) if (buf[i] != (i+1)) e++;
345 return e;
346}
347
348static void bpck_read_eeprom ( PIA *pi, char * buf )
349
350{ int i,j,k,n,p,v,f, om, od;
351
352 bpck_force_spp(pi);
353
354 om = pi->mode; od = pi->delay;
355 pi->mode = 0; pi->delay = 6;
356
357 bpck_connect(pi);
358
359 n = 0;
360 WR(4,0);
361 for (i=0;i<64;i++) {
362 WR(6,8);
363 WR(6,0xc);
364 p = 0x100;
365 for (k=0;k<9;k++) {
366 f = (((i + 0x180) & p) != 0) * 2;
367 WR(6,f+0xc);
368 WR(6,f+0xd);
369 WR(6,f+0xc);
370 p = (p >> 1);
371 }
372 for (j=0;j<2;j++) {
373 v = 0;
374 for (k=0;k<8;k++) {
375 WR(6,0xc);
376 WR(6,0xd);
377 WR(6,0xc);
378 f = RR(0);
379 v = 2*v + (f == 0x84);
380 }
381 buf[2*i+1-j] = v;
382 }
383 }
384 WR(6,8);
385 WR(6,0);
386 WR(5,8);
387
388 bpck_disconnect(pi);
389
390 if (om >= 2) {
391 bpck_connect(pi);
392 WR(7,3);
393 WR(4,8);
394 bpck_disconnect(pi);
395 }
396
397 pi->mode = om; pi->delay = od;
398}
399
400static int bpck_test_port ( PIA *pi ) /* check for 8-bit port */
401
402{ int i, r, m;
403
404 w2(0x2c); i = r0(); w0(255-i); r = r0(); w0(i);
405 m = -1;
406 if (r == i) m = 2;
407 if (r == (255-i)) m = 0;
408
409 w2(0xc); i = r0(); w0(255-i); r = r0(); w0(i);
410 if (r != (255-i)) m = -1;
411
412 if (m == 0) { w2(6); w2(0xc); r = r0(); w0(0xaa); w0(r); w0(0xaa); }
413 if (m == 2) { w2(0x26); w2(0xc); }
414
415 if (m == -1) return 0;
416 return 5;
417}
418
419static void bpck_log_adapter( PIA *pi, char * scratch, int verbose )
420
421{ char *mode_string[5] = { "4-bit","8-bit","EPP-8",
422 "EPP-16","EPP-32" };
423
424#ifdef DUMP_EEPROM
425 int i;
426#endif
427
428 bpck_read_eeprom(pi,scratch);
429
430#ifdef DUMP_EEPROM
431 if (verbose) {
432 for(i=0;i<128;i++)
433 if ((scratch[i] < ' ') || (scratch[i] > '~'))
434 scratch[i] = '.';
435 printk("%s: bpck EEPROM: %64.64s\n",pi->device,scratch);
436 printk("%s: %64.64s\n",pi->device,&scratch[64]);
437 }
438#endif
439
440 printk("%s: bpck %s, backpack %8.8s unit %d",
441 pi->device,BPCK_VERSION,&scratch[110],pi->unit);
442 printk(" at 0x%x, mode %d (%s), delay %d\n",pi->port,
443 pi->mode,mode_string[pi->mode],pi->delay);
444}
445
446static struct pi_protocol bpck = {
447 .owner = THIS_MODULE,
448 .name = "bpck",
449 .max_mode = 5,
450 .epp_first = 2,
451 .default_delay = 4,
452 .max_units = 255,
453 .write_regr = bpck_write_regr,
454 .read_regr = bpck_read_regr,
455 .write_block = bpck_write_block,
456 .read_block = bpck_read_block,
457 .connect = bpck_connect,
458 .disconnect = bpck_disconnect,
459 .test_port = bpck_test_port,
460 .probe_unit = bpck_probe_unit,
461 .test_proto = bpck_test_proto,
462 .log_adapter = bpck_log_adapter,
463};
464
465static int __init bpck_init(void)
466{
467 return pi_register(&bpck)-1;
468}
469
470static void __exit bpck_exit(void)
471{
472 pi_unregister(&bpck);
473}
474
475MODULE_LICENSE("GPL");
476module_init(bpck_init)
477module_exit(bpck_exit)
diff --git a/drivers/block/paride/bpck6.c b/drivers/block/paride/bpck6.c
new file mode 100644
index 000000000000..08d858ad64db
--- /dev/null
+++ b/drivers/block/paride/bpck6.c
@@ -0,0 +1,282 @@
1/*
2 backpack.c (c) 2001 Micro Solutions Inc.
3 Released under the terms of the GNU General Public license
4
5 backpack.c is a low-level protocol driver for the Micro Solutions
6 "BACKPACK" parallel port IDE adapter
7 (Works on Series 6 drives)
8
9 Written by: Ken Hahn (linux-dev@micro-solutions.com)
10 Clive Turvey (linux-dev@micro-solutions.com)
11
12*/
13
14/*
15 This is Ken's linux wrapper for the PPC library
16 Version 1.0.0 is the backpack driver for which source is not available
17 Version 2.0.0 is the first to have source released
18 Version 2.0.1 is the "Cox-ified" source code
19 Version 2.0.2 - fixed version string usage, and made ppc functions static
20*/
21
22
23/* PARAMETERS */
24static int verbose; /* set this to 1 to see debugging messages and whatnot */
25
26#define BACKPACK_VERSION "2.0.2"
27
28#include <linux/module.h>
29#include <linux/init.h>
30#include <linux/kernel.h>
31#include <linux/slab.h>
32#include <linux/types.h>
33#include <asm/io.h>
34
35#if defined(CONFIG_PARPORT_MODULE)||defined(CONFIG_PARPORT)
36#include <linux/parport.h>
37#endif
38
39#include "ppc6lnx.c"
40#include "paride.h"
41
42
43
44#define PPCSTRUCT(pi) ((Interface *)(pi->private))
45
46/****************************************************************/
47/*
48 ATAPI CDROM DRIVE REGISTERS
49*/
50#define ATAPI_DATA 0 /* data port */
51#define ATAPI_ERROR 1 /* error register (read) */
52#define ATAPI_FEATURES 1 /* feature register (write) */
53#define ATAPI_INT_REASON 2 /* interrupt reason register */
54#define ATAPI_COUNT_LOW 4 /* byte count register (low) */
55#define ATAPI_COUNT_HIGH 5 /* byte count register (high) */
56#define ATAPI_DRIVE_SEL 6 /* drive select register */
57#define ATAPI_STATUS 7 /* status port (read) */
58#define ATAPI_COMMAND 7 /* command port (write) */
59#define ATAPI_ALT_STATUS 0x0e /* alternate status reg (read) */
60#define ATAPI_DEVICE_CONTROL 0x0e /* device control (write) */
61/****************************************************************/
62
63static int bpck6_read_regr(PIA *pi, int cont, int reg)
64{
65 unsigned int out;
66
67 /* check for bad settings */
68 if (reg<0 || reg>7 || cont<0 || cont>2)
69 {
70 return(-1);
71 }
72 out=ppc6_rd_port(PPCSTRUCT(pi),cont?reg|8:reg);
73 return(out);
74}
75
76static void bpck6_write_regr(PIA *pi, int cont, int reg, int val)
77{
78 /* check for bad settings */
79 if (reg>=0 && reg<=7 && cont>=0 && cont<=1)
80 {
81 ppc6_wr_port(PPCSTRUCT(pi),cont?reg|8:reg,(u8)val);
82 }
83}
84
85static void bpck6_write_block( PIA *pi, char * buf, int len )
86{
87 ppc6_wr_port16_blk(PPCSTRUCT(pi),ATAPI_DATA,buf,(u32)len>>1);
88}
89
90static void bpck6_read_block( PIA *pi, char * buf, int len )
91{
92 ppc6_rd_port16_blk(PPCSTRUCT(pi),ATAPI_DATA,buf,(u32)len>>1);
93}
94
95static void bpck6_connect ( PIA *pi )
96{
97 if(verbose)
98 {
99 printk(KERN_DEBUG "connect\n");
100 }
101
102 if(pi->mode >=2)
103 {
104 PPCSTRUCT(pi)->mode=4+pi->mode-2;
105 }
106 else if(pi->mode==1)
107 {
108 PPCSTRUCT(pi)->mode=3;
109 }
110 else
111 {
112 PPCSTRUCT(pi)->mode=1;
113 }
114
115 ppc6_open(PPCSTRUCT(pi));
116 ppc6_wr_extout(PPCSTRUCT(pi),0x3);
117}
118
119static void bpck6_disconnect ( PIA *pi )
120{
121 if(verbose)
122 {
123 printk("disconnect\n");
124 }
125 ppc6_wr_extout(PPCSTRUCT(pi),0x0);
126 ppc6_close(PPCSTRUCT(pi));
127}
128
129static int bpck6_test_port ( PIA *pi ) /* check for 8-bit port */
130{
131 if(verbose)
132 {
133 printk(KERN_DEBUG "PARPORT indicates modes=%x for lp=0x%lx\n",
134 ((struct pardevice*)(pi->pardev))->port->modes,
135 ((struct pardevice *)(pi->pardev))->port->base);
136 }
137
138 /*copy over duplicate stuff.. initialize state info*/
139 PPCSTRUCT(pi)->ppc_id=pi->unit;
140 PPCSTRUCT(pi)->lpt_addr=pi->port;
141
142#ifdef CONFIG_PARPORT_PC_MODULE
143#define CONFIG_PARPORT_PC
144#endif
145
146#ifdef CONFIG_PARPORT_PC
147 /* look at the parport device to see if what modes we can use */
148 if(((struct pardevice *)(pi->pardev))->port->modes &
149 (PARPORT_MODE_EPP)
150 )
151 {
152 return 5; /* Can do EPP*/
153 }
154 else if(((struct pardevice *)(pi->pardev))->port->modes &
155 (PARPORT_MODE_TRISTATE)
156 )
157 {
158 return 2;
159 }
160 else /*Just flat SPP*/
161 {
162 return 1;
163 }
164#else
165 /* there is no way of knowing what kind of port we have
166 default to the highest mode possible */
167 return 5;
168#endif
169}
170
171static int bpck6_probe_unit ( PIA *pi )
172{
173 int out;
174
175 if(verbose)
176 {
177 printk(KERN_DEBUG "PROBE UNIT %x on port:%x\n",pi->unit,pi->port);
178 }
179
180 /*SET PPC UNIT NUMBER*/
181 PPCSTRUCT(pi)->ppc_id=pi->unit;
182
183 /*LOWER DOWN TO UNIDIRECTIONAL*/
184 PPCSTRUCT(pi)->mode=1;
185
186 out=ppc6_open(PPCSTRUCT(pi));
187
188 if(verbose)
189 {
190 printk(KERN_DEBUG "ppc_open returned %2x\n",out);
191 }
192
193 if(out)
194 {
195 ppc6_close(PPCSTRUCT(pi));
196 if(verbose)
197 {
198 printk(KERN_DEBUG "leaving probe\n");
199 }
200 return(1);
201 }
202 else
203 {
204 if(verbose)
205 {
206 printk(KERN_DEBUG "Failed open\n");
207 }
208 return(0);
209 }
210}
211
212static void bpck6_log_adapter( PIA *pi, char * scratch, int verbose )
213{
214 char *mode_string[5]=
215 {"4-bit","8-bit","EPP-8","EPP-16","EPP-32"};
216
217 printk("%s: BACKPACK Protocol Driver V"BACKPACK_VERSION"\n",pi->device);
218 printk("%s: Copyright 2001 by Micro Solutions, Inc., DeKalb IL.\n",pi->device);
219 printk("%s: BACKPACK %s, Micro Solutions BACKPACK Drive at 0x%x\n",
220 pi->device,BACKPACK_VERSION,pi->port);
221 printk("%s: Unit: %d Mode:%d (%s) Delay %d\n",pi->device,
222 pi->unit,pi->mode,mode_string[pi->mode],pi->delay);
223}
224
225static int bpck6_init_proto(PIA *pi)
226{
227 Interface *p = kmalloc(sizeof(Interface), GFP_KERNEL);
228
229 if (p) {
230 memset(p, 0, sizeof(Interface));
231 pi->private = (unsigned long)p;
232 return 0;
233 }
234
235 printk(KERN_ERR "%s: ERROR COULDN'T ALLOCATE MEMORY\n", pi->device);
236 return -1;
237}
238
239static void bpck6_release_proto(PIA *pi)
240{
241 kfree((void *)(pi->private));
242}
243
244static struct pi_protocol bpck6 = {
245 .owner = THIS_MODULE,
246 .name = "bpck6",
247 .max_mode = 5,
248 .epp_first = 2, /* 2-5 use epp (need 8 ports) */
249 .max_units = 255,
250 .write_regr = bpck6_write_regr,
251 .read_regr = bpck6_read_regr,
252 .write_block = bpck6_write_block,
253 .read_block = bpck6_read_block,
254 .connect = bpck6_connect,
255 .disconnect = bpck6_disconnect,
256 .test_port = bpck6_test_port,
257 .probe_unit = bpck6_probe_unit,
258 .log_adapter = bpck6_log_adapter,
259 .init_proto = bpck6_init_proto,
260 .release_proto = bpck6_release_proto,
261};
262
263static int __init bpck6_init(void)
264{
265 printk(KERN_INFO "bpck6: BACKPACK Protocol Driver V"BACKPACK_VERSION"\n");
266 printk(KERN_INFO "bpck6: Copyright 2001 by Micro Solutions, Inc., DeKalb IL. USA\n");
267 if(verbose)
268 printk(KERN_DEBUG "bpck6: verbose debug enabled.\n");
269 return pi_register(&bpck6) - 1;
270}
271
272static void __exit bpck6_exit(void)
273{
274 pi_unregister(&bpck6);
275}
276
277MODULE_LICENSE("GPL");
278MODULE_AUTHOR("Micro Solutions Inc.");
279MODULE_DESCRIPTION("BACKPACK Protocol module, compatible with PARIDE");
280module_param(verbose, bool, 0644);
281module_init(bpck6_init)
282module_exit(bpck6_exit)
diff --git a/drivers/block/paride/comm.c b/drivers/block/paride/comm.c
new file mode 100644
index 000000000000..d842956edf76
--- /dev/null
+++ b/drivers/block/paride/comm.c
@@ -0,0 +1,218 @@
1/*
2 comm.c (c) 1997-8 Grant R. Guenther <grant@torque.net>
3 Under the terms of the GNU General Public License.
4
5 comm.c is a low-level protocol driver for some older models
6 of the DataStor "Commuter" parallel to IDE adapter. Some of
7 the parallel port devices marketed by Arista currently
8 use this adapter.
9*/
10
11/* Changes:
12
13 1.01 GRG 1998.05.05 init_proto, release_proto
14
15*/
16
17#define COMM_VERSION "1.01"
18
19#include <linux/module.h>
20#include <linux/init.h>
21#include <linux/delay.h>
22#include <linux/kernel.h>
23#include <linux/types.h>
24#include <linux/wait.h>
25#include <asm/io.h>
26
27#include "paride.h"
28
29/* mode codes: 0 nybble reads, 8-bit writes
30 1 8-bit reads and writes
31 2 8-bit EPP mode
32*/
33
34#define j44(a,b) (((a>>3)&0x0f)|((b<<1)&0xf0))
35
36#define P1 w2(5);w2(0xd);w2(0xd);w2(5);w2(4);
37#define P2 w2(5);w2(7);w2(7);w2(5);w2(4);
38
39/* cont = 0 - access the IDE register file
40 cont = 1 - access the IDE command set
41*/
42
43static int cont_map[2] = { 0x08, 0x10 };
44
45static int comm_read_regr( PIA *pi, int cont, int regr )
46
47{ int l, h, r;
48
49 r = regr + cont_map[cont];
50
51 switch (pi->mode) {
52
53 case 0: w0(r); P1; w0(0);
54 w2(6); l = r1(); w0(0x80); h = r1(); w2(4);
55 return j44(l,h);
56
57 case 1: w0(r+0x20); P1;
58 w0(0); w2(0x26); h = r0(); w2(4);
59 return h;
60
61 case 2:
62 case 3:
63 case 4: w3(r+0x20); r1();
64 w2(0x24); h = r4(); w2(4);
65 return h;
66
67 }
68 return -1;
69}
70
71static void comm_write_regr( PIA *pi, int cont, int regr, int val )
72
73{ int r;
74
75 r = regr + cont_map[cont];
76
77 switch (pi->mode) {
78
79 case 0:
80 case 1: w0(r); P1; w0(val); P2;
81 break;
82
83 case 2:
84 case 3:
85 case 4: w3(r); r1(); w4(val);
86 break;
87 }
88}
89
90static void comm_connect ( PIA *pi )
91
92{ pi->saved_r0 = r0();
93 pi->saved_r2 = r2();
94 w2(4); w0(0xff); w2(6);
95 w2(4); w0(0xaa); w2(6);
96 w2(4); w0(0x00); w2(6);
97 w2(4); w0(0x87); w2(6);
98 w2(4); w0(0xe0); w2(0xc); w2(0xc); w2(4);
99}
100
101static void comm_disconnect ( PIA *pi )
102
103{ w2(0); w2(0); w2(0); w2(4);
104 w0(pi->saved_r0);
105 w2(pi->saved_r2);
106}
107
108static void comm_read_block( PIA *pi, char * buf, int count )
109
110{ int i, l, h;
111
112 switch (pi->mode) {
113
114 case 0: w0(0x48); P1;
115 for(i=0;i<count;i++) {
116 w0(0); w2(6); l = r1();
117 w0(0x80); h = r1(); w2(4);
118 buf[i] = j44(l,h);
119 }
120 break;
121
122 case 1: w0(0x68); P1; w0(0);
123 for(i=0;i<count;i++) {
124 w2(0x26); buf[i] = r0(); w2(0x24);
125 }
126 w2(4);
127 break;
128
129 case 2: w3(0x68); r1(); w2(0x24);
130 for (i=0;i<count;i++) buf[i] = r4();
131 w2(4);
132 break;
133
134 case 3: w3(0x68); r1(); w2(0x24);
135 for (i=0;i<count/2;i++) ((u16 *)buf)[i] = r4w();
136 w2(4);
137 break;
138
139 case 4: w3(0x68); r1(); w2(0x24);
140 for (i=0;i<count/4;i++) ((u32 *)buf)[i] = r4l();
141 w2(4);
142 break;
143
144 }
145}
146
147/* NB: Watch out for the byte swapped writes ! */
148
149static void comm_write_block( PIA *pi, char * buf, int count )
150
151{ int k;
152
153 switch (pi->mode) {
154
155 case 0:
156 case 1: w0(0x68); P1;
157 for (k=0;k<count;k++) {
158 w2(5); w0(buf[k^1]); w2(7);
159 }
160 w2(5); w2(4);
161 break;
162
163 case 2: w3(0x48); r1();
164 for (k=0;k<count;k++) w4(buf[k^1]);
165 break;
166
167 case 3: w3(0x48); r1();
168 for (k=0;k<count/2;k++) w4w(pi_swab16(buf,k));
169 break;
170
171 case 4: w3(0x48); r1();
172 for (k=0;k<count/4;k++) w4l(pi_swab32(buf,k));
173 break;
174
175
176 }
177}
178
179static void comm_log_adapter( PIA *pi, char * scratch, int verbose )
180
181{ char *mode_string[5] = {"4-bit","8-bit","EPP-8","EPP-16","EPP-32"};
182
183 printk("%s: comm %s, DataStor Commuter at 0x%x, ",
184 pi->device,COMM_VERSION,pi->port);
185 printk("mode %d (%s), delay %d\n",pi->mode,
186 mode_string[pi->mode],pi->delay);
187
188}
189
190static struct pi_protocol comm = {
191 .owner = THIS_MODULE,
192 .name = "comm",
193 .max_mode = 5,
194 .epp_first = 2,
195 .default_delay = 1,
196 .max_units = 1,
197 .write_regr = comm_write_regr,
198 .read_regr = comm_read_regr,
199 .write_block = comm_write_block,
200 .read_block = comm_read_block,
201 .connect = comm_connect,
202 .disconnect = comm_disconnect,
203 .log_adapter = comm_log_adapter,
204};
205
206static int __init comm_init(void)
207{
208 return pi_register(&comm)-1;
209}
210
211static void __exit comm_exit(void)
212{
213 pi_unregister(&comm);
214}
215
216MODULE_LICENSE("GPL");
217module_init(comm_init)
218module_exit(comm_exit)
diff --git a/drivers/block/paride/dstr.c b/drivers/block/paride/dstr.c
new file mode 100644
index 000000000000..04d53bf58e8c
--- /dev/null
+++ b/drivers/block/paride/dstr.c
@@ -0,0 +1,233 @@
1/*
2 dstr.c (c) 1997-8 Grant R. Guenther <grant@torque.net>
3 Under the terms of the GNU General Public License.
4
5 dstr.c is a low-level protocol driver for the
6 DataStor EP2000 parallel to IDE adapter chip.
7
8*/
9
10/* Changes:
11
12 1.01 GRG 1998.05.06 init_proto, release_proto
13
14*/
15
16#define DSTR_VERSION "1.01"
17
18#include <linux/module.h>
19#include <linux/init.h>
20#include <linux/delay.h>
21#include <linux/kernel.h>
22#include <linux/types.h>
23#include <linux/wait.h>
24#include <asm/io.h>
25
26#include "paride.h"
27
28/* mode codes: 0 nybble reads, 8-bit writes
29 1 8-bit reads and writes
30 2 8-bit EPP mode
31 3 EPP-16
32 4 EPP-32
33*/
34
35#define j44(a,b) (((a>>3)&0x07)|((~a>>4)&0x08)|((b<<1)&0x70)|((~b)&0x80))
36
37#define P1 w2(5);w2(0xd);w2(5);w2(4);
38#define P2 w2(5);w2(7);w2(5);w2(4);
39#define P3 w2(6);w2(4);w2(6);w2(4);
40
41/* cont = 0 - access the IDE register file
42 cont = 1 - access the IDE command set
43*/
44
45static int cont_map[2] = { 0x20, 0x40 };
46
47static int dstr_read_regr( PIA *pi, int cont, int regr )
48
49{ int a, b, r;
50
51 r = regr + cont_map[cont];
52
53 w0(0x81); P1;
54 if (pi->mode) { w0(0x11); } else { w0(1); }
55 P2; w0(r); P1;
56
57 switch (pi->mode) {
58
59 case 0: w2(6); a = r1(); w2(4); w2(6); b = r1(); w2(4);
60 return j44(a,b);
61
62 case 1: w0(0); w2(0x26); a = r0(); w2(4);
63 return a;
64
65 case 2:
66 case 3:
67 case 4: w2(0x24); a = r4(); w2(4);
68 return a;
69
70 }
71 return -1;
72}
73
74static void dstr_write_regr( PIA *pi, int cont, int regr, int val )
75
76{ int r;
77
78 r = regr + cont_map[cont];
79
80 w0(0x81); P1;
81 if (pi->mode >= 2) { w0(0x11); } else { w0(1); }
82 P2; w0(r); P1;
83
84 switch (pi->mode) {
85
86 case 0:
87 case 1: w0(val); w2(5); w2(7); w2(5); w2(4);
88 break;
89
90 case 2:
91 case 3:
92 case 4: w4(val);
93 break;
94 }
95}
96
97#define CCP(x) w0(0xff);w2(0xc);w2(4);\
98 w0(0xaa);w0(0x55);w0(0);w0(0xff);w0(0x87);w0(0x78);\
99 w0(x);w2(5);w2(4);
100
101static void dstr_connect ( PIA *pi )
102
103{ pi->saved_r0 = r0();
104 pi->saved_r2 = r2();
105 w2(4); CCP(0xe0); w0(0xff);
106}
107
108static void dstr_disconnect ( PIA *pi )
109
110{ CCP(0x30);
111 w0(pi->saved_r0);
112 w2(pi->saved_r2);
113}
114
115static void dstr_read_block( PIA *pi, char * buf, int count )
116
117{ int k, a, b;
118
119 w0(0x81); P1;
120 if (pi->mode) { w0(0x19); } else { w0(9); }
121 P2; w0(0x82); P1; P3; w0(0x20); P1;
122
123 switch (pi->mode) {
124
125 case 0: for (k=0;k<count;k++) {
126 w2(6); a = r1(); w2(4);
127 w2(6); b = r1(); w2(4);
128 buf[k] = j44(a,b);
129 }
130 break;
131
132 case 1: w0(0);
133 for (k=0;k<count;k++) {
134 w2(0x26); buf[k] = r0(); w2(0x24);
135 }
136 w2(4);
137 break;
138
139 case 2: w2(0x24);
140 for (k=0;k<count;k++) buf[k] = r4();
141 w2(4);
142 break;
143
144 case 3: w2(0x24);
145 for (k=0;k<count/2;k++) ((u16 *)buf)[k] = r4w();
146 w2(4);
147 break;
148
149 case 4: w2(0x24);
150 for (k=0;k<count/4;k++) ((u32 *)buf)[k] = r4l();
151 w2(4);
152 break;
153
154 }
155}
156
157static void dstr_write_block( PIA *pi, char * buf, int count )
158
159{ int k;
160
161 w0(0x81); P1;
162 if (pi->mode) { w0(0x19); } else { w0(9); }
163 P2; w0(0x82); P1; P3; w0(0x20); P1;
164
165 switch (pi->mode) {
166
167 case 0:
168 case 1: for (k=0;k<count;k++) {
169 w2(5); w0(buf[k]); w2(7);
170 }
171 w2(5); w2(4);
172 break;
173
174 case 2: w2(0xc5);
175 for (k=0;k<count;k++) w4(buf[k]);
176 w2(0xc4);
177 break;
178
179 case 3: w2(0xc5);
180 for (k=0;k<count/2;k++) w4w(((u16 *)buf)[k]);
181 w2(0xc4);
182 break;
183
184 case 4: w2(0xc5);
185 for (k=0;k<count/4;k++) w4l(((u32 *)buf)[k]);
186 w2(0xc4);
187 break;
188
189 }
190}
191
192
193static void dstr_log_adapter( PIA *pi, char * scratch, int verbose )
194
195{ char *mode_string[5] = {"4-bit","8-bit","EPP-8",
196 "EPP-16","EPP-32"};
197
198 printk("%s: dstr %s, DataStor EP2000 at 0x%x, ",
199 pi->device,DSTR_VERSION,pi->port);
200 printk("mode %d (%s), delay %d\n",pi->mode,
201 mode_string[pi->mode],pi->delay);
202
203}
204
205static struct pi_protocol dstr = {
206 .owner = THIS_MODULE,
207 .name = "dstr",
208 .max_mode = 5,
209 .epp_first = 2,
210 .default_delay = 1,
211 .max_units = 1,
212 .write_regr = dstr_write_regr,
213 .read_regr = dstr_read_regr,
214 .write_block = dstr_write_block,
215 .read_block = dstr_read_block,
216 .connect = dstr_connect,
217 .disconnect = dstr_disconnect,
218 .log_adapter = dstr_log_adapter,
219};
220
221static int __init dstr_init(void)
222{
223 return pi_register(&dstr)-1;
224}
225
226static void __exit dstr_exit(void)
227{
228 pi_unregister(&dstr);
229}
230
231MODULE_LICENSE("GPL");
232module_init(dstr_init)
233module_exit(dstr_exit)
diff --git a/drivers/block/paride/epat.c b/drivers/block/paride/epat.c
new file mode 100644
index 000000000000..55d1c0a1fb90
--- /dev/null
+++ b/drivers/block/paride/epat.c
@@ -0,0 +1,340 @@
1/*
2 epat.c (c) 1997-8 Grant R. Guenther <grant@torque.net>
3 Under the terms of the GNU General Public License.
4
5 This is the low level protocol driver for the EPAT parallel
6 to IDE adapter from Shuttle Technologies. This adapter is
7 used in many popular parallel port disk products such as the
8 SyQuest EZ drives, the Avatar Shark and the Imation SuperDisk.
9
10*/
11
12/* Changes:
13
14 1.01 GRG 1998.05.06 init_proto, release_proto
15 1.02 Joshua b. Jore CPP(renamed), epat_connect, epat_disconnect
16
17*/
18
19#define EPAT_VERSION "1.02"
20
21#include <linux/module.h>
22#include <linux/init.h>
23#include <linux/delay.h>
24#include <linux/kernel.h>
25#include <linux/types.h>
26#include <linux/wait.h>
27#include <asm/io.h>
28
29#include "paride.h"
30
31#define j44(a,b) (((a>>4)&0x0f)+(b&0xf0))
32#define j53(a,b) (((a>>3)&0x1f)+((b<<4)&0xe0))
33
34static int epatc8;
35
36module_param(epatc8, int, 0);
37MODULE_PARM_DESC(epatc8, "support for the Shuttle EP1284 chip, "
38 "used in any recent Imation SuperDisk (LS-120) drive.");
39
40/* cont = 0 IDE register file
41 cont = 1 IDE control registers
42 cont = 2 internal EPAT registers
43*/
44
45static int cont_map[3] = { 0x18, 0x10, 0 };
46
47static void epat_write_regr( PIA *pi, int cont, int regr, int val)
48
49{ int r;
50
51 r = regr + cont_map[cont];
52
53 switch (pi->mode) {
54
55 case 0:
56 case 1:
57 case 2: w0(0x60+r); w2(1); w0(val); w2(4);
58 break;
59
60 case 3:
61 case 4:
62 case 5: w3(0x40+r); w4(val);
63 break;
64
65 }
66}
67
68static int epat_read_regr( PIA *pi, int cont, int regr )
69
70{ int a, b, r;
71
72 r = regr + cont_map[cont];
73
74 switch (pi->mode) {
75
76 case 0: w0(r); w2(1); w2(3);
77 a = r1(); w2(4); b = r1();
78 return j44(a,b);
79
80 case 1: w0(0x40+r); w2(1); w2(4);
81 a = r1(); b = r2(); w0(0xff);
82 return j53(a,b);
83
84 case 2: w0(0x20+r); w2(1); w2(0x25);
85 a = r0(); w2(4);
86 return a;
87
88 case 3:
89 case 4:
90 case 5: w3(r); w2(0x24); a = r4(); w2(4);
91 return a;
92
93 }
94 return -1; /* never gets here */
95}
96
97static void epat_read_block( PIA *pi, char * buf, int count )
98
99{ int k, ph, a, b;
100
101 switch (pi->mode) {
102
103 case 0: w0(7); w2(1); w2(3); w0(0xff);
104 ph = 0;
105 for(k=0;k<count;k++) {
106 if (k == count-1) w0(0xfd);
107 w2(6+ph); a = r1();
108 if (a & 8) b = a;
109 else { w2(4+ph); b = r1(); }
110 buf[k] = j44(a,b);
111 ph = 1 - ph;
112 }
113 w0(0); w2(4);
114 break;
115
116 case 1: w0(0x47); w2(1); w2(5); w0(0xff);
117 ph = 0;
118 for(k=0;k<count;k++) {
119 if (k == count-1) w0(0xfd);
120 w2(4+ph);
121 a = r1(); b = r2();
122 buf[k] = j53(a,b);
123 ph = 1 - ph;
124 }
125 w0(0); w2(4);
126 break;
127
128 case 2: w0(0x27); w2(1); w2(0x25); w0(0);
129 ph = 0;
130 for(k=0;k<count-1;k++) {
131 w2(0x24+ph);
132 buf[k] = r0();
133 ph = 1 - ph;
134 }
135 w2(0x26); w2(0x27); buf[count-1] = r0();
136 w2(0x25); w2(4);
137 break;
138
139 case 3: w3(0x80); w2(0x24);
140 for(k=0;k<count-1;k++) buf[k] = r4();
141 w2(4); w3(0xa0); w2(0x24); buf[count-1] = r4();
142 w2(4);
143 break;
144
145 case 4: w3(0x80); w2(0x24);
146 for(k=0;k<(count/2)-1;k++) ((u16 *)buf)[k] = r4w();
147 buf[count-2] = r4();
148 w2(4); w3(0xa0); w2(0x24); buf[count-1] = r4();
149 w2(4);
150 break;
151
152 case 5: w3(0x80); w2(0x24);
153 for(k=0;k<(count/4)-1;k++) ((u32 *)buf)[k] = r4l();
154 for(k=count-4;k<count-1;k++) buf[k] = r4();
155 w2(4); w3(0xa0); w2(0x24); buf[count-1] = r4();
156 w2(4);
157 break;
158
159 }
160}
161
162static void epat_write_block( PIA *pi, char * buf, int count )
163
164{ int ph, k;
165
166 switch (pi->mode) {
167
168 case 0:
169 case 1:
170 case 2: w0(0x67); w2(1); w2(5);
171 ph = 0;
172 for(k=0;k<count;k++) {
173 w0(buf[k]);
174 w2(4+ph);
175 ph = 1 - ph;
176 }
177 w2(7); w2(4);
178 break;
179
180 case 3: w3(0xc0);
181 for(k=0;k<count;k++) w4(buf[k]);
182 w2(4);
183 break;
184
185 case 4: w3(0xc0);
186 for(k=0;k<(count/2);k++) w4w(((u16 *)buf)[k]);
187 w2(4);
188 break;
189
190 case 5: w3(0xc0);
191 for(k=0;k<(count/4);k++) w4l(((u32 *)buf)[k]);
192 w2(4);
193 break;
194
195 }
196}
197
198/* these macros access the EPAT registers in native addressing */
199
200#define WR(r,v) epat_write_regr(pi,2,r,v)
201#define RR(r) (epat_read_regr(pi,2,r))
202
203/* and these access the IDE task file */
204
205#define WRi(r,v) epat_write_regr(pi,0,r,v)
206#define RRi(r) (epat_read_regr(pi,0,r))
207
208/* FIXME: the CPP stuff should be fixed to handle multiple EPATs on a chain */
209
210#define CPP(x) w2(4);w0(0x22);w0(0xaa);w0(0x55);w0(0);w0(0xff);\
211 w0(0x87);w0(0x78);w0(x);w2(4);w2(5);w2(4);w0(0xff);
212
213static void epat_connect ( PIA *pi )
214
215{ pi->saved_r0 = r0();
216 pi->saved_r2 = r2();
217
218 /* Initialize the chip */
219 CPP(0);
220
221 if (epatc8) {
222 CPP(0x40);CPP(0xe0);
223 w0(0);w2(1);w2(4);
224 WR(0x8,0x12);WR(0xc,0x14);WR(0x12,0x10);
225 WR(0xe,0xf);WR(0xf,4);
226 /* WR(0xe,0xa);WR(0xf,4); */
227 WR(0xe,0xd);WR(0xf,0);
228 /* CPP(0x30); */
229 }
230
231 /* Connect to the chip */
232 CPP(0xe0);
233 w0(0);w2(1);w2(4); /* Idle into SPP */
234 if (pi->mode >= 3) {
235 w0(0);w2(1);w2(4);w2(0xc);
236 /* Request EPP */
237 w0(0x40);w2(6);w2(7);w2(4);w2(0xc);w2(4);
238 }
239
240 if (!epatc8) {
241 WR(8,0x10); WR(0xc,0x14); WR(0xa,0x38); WR(0x12,0x10);
242 }
243}
244
245static void epat_disconnect (PIA *pi)
246{ CPP(0x30);
247 w0(pi->saved_r0);
248 w2(pi->saved_r2);
249}
250
251static int epat_test_proto( PIA *pi, char * scratch, int verbose )
252
253{ int k, j, f, cc;
254 int e[2] = {0,0};
255
256 epat_connect(pi);
257 cc = RR(0xd);
258 epat_disconnect(pi);
259
260 epat_connect(pi);
261 for (j=0;j<2;j++) {
262 WRi(6,0xa0+j*0x10);
263 for (k=0;k<256;k++) {
264 WRi(2,k^0xaa);
265 WRi(3,k^0x55);
266 if (RRi(2) != (k^0xaa)) e[j]++;
267 }
268 }
269 epat_disconnect(pi);
270
271 f = 0;
272 epat_connect(pi);
273 WR(0x13,1); WR(0x13,0); WR(0xa,0x11);
274 epat_read_block(pi,scratch,512);
275
276 for (k=0;k<256;k++) {
277 if ((scratch[2*k] & 0xff) != k) f++;
278 if ((scratch[2*k+1] & 0xff) != (0xff-k)) f++;
279 }
280 epat_disconnect(pi);
281
282 if (verbose) {
283 printk("%s: epat: port 0x%x, mode %d, ccr %x, test=(%d,%d,%d)\n",
284 pi->device,pi->port,pi->mode,cc,e[0],e[1],f);
285 }
286
287 return (e[0] && e[1]) || f;
288}
289
290static void epat_log_adapter( PIA *pi, char * scratch, int verbose )
291
292{ int ver;
293 char *mode_string[6] =
294 {"4-bit","5/3","8-bit","EPP-8","EPP-16","EPP-32"};
295
296 epat_connect(pi);
297 WR(0xa,0x38); /* read the version code */
298 ver = RR(0xb);
299 epat_disconnect(pi);
300
301 printk("%s: epat %s, Shuttle EPAT chip %x at 0x%x, ",
302 pi->device,EPAT_VERSION,ver,pi->port);
303 printk("mode %d (%s), delay %d\n",pi->mode,
304 mode_string[pi->mode],pi->delay);
305
306}
307
308static struct pi_protocol epat = {
309 .owner = THIS_MODULE,
310 .name = "epat",
311 .max_mode = 6,
312 .epp_first = 3,
313 .default_delay = 1,
314 .max_units = 1,
315 .write_regr = epat_write_regr,
316 .read_regr = epat_read_regr,
317 .write_block = epat_write_block,
318 .read_block = epat_read_block,
319 .connect = epat_connect,
320 .disconnect = epat_disconnect,
321 .test_proto = epat_test_proto,
322 .log_adapter = epat_log_adapter,
323};
324
325static int __init epat_init(void)
326{
327#ifdef CONFIG_PARIDE_EPATC8
328 epatc8 = 1;
329#endif
330 return pi_register(&epat)-1;
331}
332
333static void __exit epat_exit(void)
334{
335 pi_unregister(&epat);
336}
337
338MODULE_LICENSE("GPL");
339module_init(epat_init)
340module_exit(epat_exit)
diff --git a/drivers/block/paride/epia.c b/drivers/block/paride/epia.c
new file mode 100644
index 000000000000..0f2e0c292d82
--- /dev/null
+++ b/drivers/block/paride/epia.c
@@ -0,0 +1,316 @@
1/*
2 epia.c (c) 1997-8 Grant R. Guenther <grant@torque.net>
3 Under the terms of the GNU General Public License.
4
5 epia.c is a low-level protocol driver for Shuttle Technologies
6 EPIA parallel to IDE adapter chip. This device is now obsolete
7 and has been replaced with the EPAT chip, which is supported
8 by epat.c, however, some devices based on EPIA are still
9 available.
10
11*/
12
13/* Changes:
14
15 1.01 GRG 1998.05.06 init_proto, release_proto
16 1.02 GRG 1998.06.17 support older versions of EPIA
17
18*/
19
20#define EPIA_VERSION "1.02"
21
22#include <linux/module.h>
23#include <linux/init.h>
24#include <linux/delay.h>
25#include <linux/kernel.h>
26#include <linux/types.h>
27#include <linux/wait.h>
28#include <asm/io.h>
29
30#include "paride.h"
31
32/* mode codes: 0 nybble reads on port 1, 8-bit writes
33 1 5/3 reads on ports 1 & 2, 8-bit writes
34 2 8-bit reads and writes
35 3 8-bit EPP mode
36 4 16-bit EPP
37 5 32-bit EPP
38*/
39
40#define j44(a,b) (((a>>4)&0x0f)+(b&0xf0))
41#define j53(a,b) (((a>>3)&0x1f)+((b<<4)&0xe0))
42
43/* cont = 0 IDE register file
44 cont = 1 IDE control registers
45*/
46
47static int cont_map[2] = { 0, 0x80 };
48
49static int epia_read_regr( PIA *pi, int cont, int regr )
50
51{ int a, b, r;
52
53 regr += cont_map[cont];
54
55 switch (pi->mode) {
56
57 case 0: r = regr^0x39;
58 w0(r); w2(1); w2(3); w0(r);
59 a = r1(); w2(1); b = r1(); w2(4);
60 return j44(a,b);
61
62 case 1: r = regr^0x31;
63 w0(r); w2(1); w0(r&0x37);
64 w2(3); w2(5); w0(r|0xf0);
65 a = r1(); b = r2(); w2(4);
66 return j53(a,b);
67
68 case 2: r = regr^0x29;
69 w0(r); w2(1); w2(0X21); w2(0x23);
70 a = r0(); w2(4);
71 return a;
72
73 case 3:
74 case 4:
75 case 5: w3(regr); w2(0x24); a = r4(); w2(4);
76 return a;
77
78 }
79 return -1;
80}
81
82static void epia_write_regr( PIA *pi, int cont, int regr, int val)
83
84{ int r;
85
86 regr += cont_map[cont];
87
88 switch (pi->mode) {
89
90 case 0:
91 case 1:
92 case 2: r = regr^0x19;
93 w0(r); w2(1); w0(val); w2(3); w2(4);
94 break;
95
96 case 3:
97 case 4:
98 case 5: r = regr^0x40;
99 w3(r); w4(val); w2(4);
100 break;
101 }
102}
103
104#define WR(r,v) epia_write_regr(pi,0,r,v)
105#define RR(r) (epia_read_regr(pi,0,r))
106
107/* The use of register 0x84 is entirely unclear - it seems to control
108 some EPP counters ... currently we know about 3 different block
109 sizes: the standard 512 byte reads and writes, 12 byte writes and
110 2048 byte reads (the last two being used in the CDrom drivers.
111*/
112
113static void epia_connect ( PIA *pi )
114
115{ pi->saved_r0 = r0();
116 pi->saved_r2 = r2();
117
118 w2(4); w0(0xa0); w0(0x50); w0(0xc0); w0(0x30); w0(0xa0); w0(0);
119 w2(1); w2(4);
120 if (pi->mode >= 3) {
121 w0(0xa); w2(1); w2(4); w0(0x82); w2(4); w2(0xc); w2(4);
122 w2(0x24); w2(0x26); w2(4);
123 }
124 WR(0x86,8);
125}
126
127static void epia_disconnect ( PIA *pi )
128
129{ /* WR(0x84,0x10); */
130 w0(pi->saved_r0);
131 w2(1); w2(4);
132 w0(pi->saved_r0);
133 w2(pi->saved_r2);
134}
135
136static void epia_read_block( PIA *pi, char * buf, int count )
137
138{ int k, ph, a, b;
139
140 switch (pi->mode) {
141
142 case 0: w0(0x81); w2(1); w2(3); w0(0xc1);
143 ph = 1;
144 for (k=0;k<count;k++) {
145 w2(2+ph); a = r1();
146 w2(4+ph); b = r1();
147 buf[k] = j44(a,b);
148 ph = 1 - ph;
149 }
150 w0(0); w2(4);
151 break;
152
153 case 1: w0(0x91); w2(1); w0(0x10); w2(3);
154 w0(0x51); w2(5); w0(0xd1);
155 ph = 1;
156 for (k=0;k<count;k++) {
157 w2(4+ph);
158 a = r1(); b = r2();
159 buf[k] = j53(a,b);
160 ph = 1 - ph;
161 }
162 w0(0); w2(4);
163 break;
164
165 case 2: w0(0x89); w2(1); w2(0x23); w2(0x21);
166 ph = 1;
167 for (k=0;k<count;k++) {
168 w2(0x24+ph);
169 buf[k] = r0();
170 ph = 1 - ph;
171 }
172 w2(6); w2(4);
173 break;
174
175 case 3: if (count > 512) WR(0x84,3);
176 w3(0); w2(0x24);
177 for (k=0;k<count;k++) buf[k] = r4();
178 w2(4); WR(0x84,0);
179 break;
180
181 case 4: if (count > 512) WR(0x84,3);
182 w3(0); w2(0x24);
183 for (k=0;k<count/2;k++) ((u16 *)buf)[k] = r4w();
184 w2(4); WR(0x84,0);
185 break;
186
187 case 5: if (count > 512) WR(0x84,3);
188 w3(0); w2(0x24);
189 for (k=0;k<count/4;k++) ((u32 *)buf)[k] = r4l();
190 w2(4); WR(0x84,0);
191 break;
192
193 }
194}
195
196static void epia_write_block( PIA *pi, char * buf, int count )
197
198{ int ph, k, last, d;
199
200 switch (pi->mode) {
201
202 case 0:
203 case 1:
204 case 2: w0(0xa1); w2(1); w2(3); w2(1); w2(5);
205 ph = 0; last = 0x8000;
206 for (k=0;k<count;k++) {
207 d = buf[k];
208 if (d != last) { last = d; w0(d); }
209 w2(4+ph);
210 ph = 1 - ph;
211 }
212 w2(7); w2(4);
213 break;
214
215 case 3: if (count < 512) WR(0x84,1);
216 w3(0x40);
217 for (k=0;k<count;k++) w4(buf[k]);
218 if (count < 512) WR(0x84,0);
219 break;
220
221 case 4: if (count < 512) WR(0x84,1);
222 w3(0x40);
223 for (k=0;k<count/2;k++) w4w(((u16 *)buf)[k]);
224 if (count < 512) WR(0x84,0);
225 break;
226
227 case 5: if (count < 512) WR(0x84,1);
228 w3(0x40);
229 for (k=0;k<count/4;k++) w4l(((u32 *)buf)[k]);
230 if (count < 512) WR(0x84,0);
231 break;
232
233 }
234
235}
236
237static int epia_test_proto( PIA *pi, char * scratch, int verbose )
238
239{ int j, k, f;
240 int e[2] = {0,0};
241
242 epia_connect(pi);
243 for (j=0;j<2;j++) {
244 WR(6,0xa0+j*0x10);
245 for (k=0;k<256;k++) {
246 WR(2,k^0xaa);
247 WR(3,k^0x55);
248 if (RR(2) != (k^0xaa)) e[j]++;
249 }
250 WR(2,1); WR(3,1);
251 }
252 epia_disconnect(pi);
253
254 f = 0;
255 epia_connect(pi);
256 WR(0x84,8);
257 epia_read_block(pi,scratch,512);
258 for (k=0;k<256;k++) {
259 if ((scratch[2*k] & 0xff) != ((k+1) & 0xff)) f++;
260 if ((scratch[2*k+1] & 0xff) != ((-2-k) & 0xff)) f++;
261 }
262 WR(0x84,0);
263 epia_disconnect(pi);
264
265 if (verbose) {
266 printk("%s: epia: port 0x%x, mode %d, test=(%d,%d,%d)\n",
267 pi->device,pi->port,pi->mode,e[0],e[1],f);
268 }
269
270 return (e[0] && e[1]) || f;
271
272}
273
274
275static void epia_log_adapter( PIA *pi, char * scratch, int verbose )
276
277{ char *mode_string[6] = {"4-bit","5/3","8-bit",
278 "EPP-8","EPP-16","EPP-32"};
279
280 printk("%s: epia %s, Shuttle EPIA at 0x%x, ",
281 pi->device,EPIA_VERSION,pi->port);
282 printk("mode %d (%s), delay %d\n",pi->mode,
283 mode_string[pi->mode],pi->delay);
284
285}
286
287static struct pi_protocol epia = {
288 .owner = THIS_MODULE,
289 .name = "epia",
290 .max_mode = 6,
291 .epp_first = 3,
292 .default_delay = 1,
293 .max_units = 1,
294 .write_regr = epia_write_regr,
295 .read_regr = epia_read_regr,
296 .write_block = epia_write_block,
297 .read_block = epia_read_block,
298 .connect = epia_connect,
299 .disconnect = epia_disconnect,
300 .test_proto = epia_test_proto,
301 .log_adapter = epia_log_adapter,
302};
303
304static int __init epia_init(void)
305{
306 return pi_register(&epia)-1;
307}
308
309static void __exit epia_exit(void)
310{
311 pi_unregister(&epia);
312}
313
314MODULE_LICENSE("GPL");
315module_init(epia_init)
316module_exit(epia_exit)
diff --git a/drivers/block/paride/fit2.c b/drivers/block/paride/fit2.c
new file mode 100644
index 000000000000..e0f0691d8bc2
--- /dev/null
+++ b/drivers/block/paride/fit2.c
@@ -0,0 +1,151 @@
1/*
2 fit2.c (c) 1998 Grant R. Guenther <grant@torque.net>
3 Under the terms of the GNU General Public License.
4
5 fit2.c is a low-level protocol driver for the older version
6 of the Fidelity International Technology parallel port adapter.
7 This adapter is used in their TransDisk 2000 and older TransDisk
8 3000 portable hard-drives. As far as I can tell, this device
9 supports 4-bit mode _only_.
10
11 Newer models of the FIT products use an enhanced protocol.
12 The "fit3" protocol module should support current drives.
13
14*/
15
16#define FIT2_VERSION "1.0"
17
18#include <linux/module.h>
19#include <linux/init.h>
20#include <linux/delay.h>
21#include <linux/kernel.h>
22#include <linux/types.h>
23#include <linux/wait.h>
24#include <asm/io.h>
25
26#include "paride.h"
27
28#define j44(a,b) (((a>>4)&0x0f)|(b&0xf0))
29
30/* cont = 0 - access the IDE register file
31 cont = 1 - access the IDE command set
32
33NB: The FIT adapter does not appear to use the control registers.
34So, we map ALT_STATUS to STATUS and NO-OP writes to the device
35control register - this means that IDE reset will not work on these
36devices.
37
38*/
39
40static void fit2_write_regr( PIA *pi, int cont, int regr, int val)
41
42{ if (cont == 1) return;
43 w2(0xc); w0(regr); w2(4); w0(val); w2(5); w0(0); w2(4);
44}
45
46static int fit2_read_regr( PIA *pi, int cont, int regr )
47
48{ int a, b, r;
49
50 if (cont) {
51 if (regr != 6) return 0xff;
52 r = 7;
53 } else r = regr + 0x10;
54
55 w2(0xc); w0(r); w2(4); w2(5);
56 w0(0); a = r1();
57 w0(1); b = r1();
58 w2(4);
59
60 return j44(a,b);
61
62}
63
64static void fit2_read_block( PIA *pi, char * buf, int count )
65
66{ int k, a, b, c, d;
67
68 w2(0xc); w0(0x10);
69
70 for (k=0;k<count/4;k++) {
71
72 w2(4); w2(5);
73 w0(0); a = r1(); w0(1); b = r1();
74 w0(3); c = r1(); w0(2); d = r1();
75 buf[4*k+0] = j44(a,b);
76 buf[4*k+1] = j44(d,c);
77
78 w2(4); w2(5);
79 a = r1(); w0(3); b = r1();
80 w0(1); c = r1(); w0(0); d = r1();
81 buf[4*k+2] = j44(d,c);
82 buf[4*k+3] = j44(a,b);
83
84 }
85
86 w2(4);
87
88}
89
90static void fit2_write_block( PIA *pi, char * buf, int count )
91
92{ int k;
93
94
95 w2(0xc); w0(0);
96 for (k=0;k<count/2;k++) {
97 w2(4); w0(buf[2*k]);
98 w2(5); w0(buf[2*k+1]);
99 }
100 w2(4);
101}
102
103static void fit2_connect ( PIA *pi )
104
105{ pi->saved_r0 = r0();
106 pi->saved_r2 = r2();
107 w2(0xcc);
108}
109
110static void fit2_disconnect ( PIA *pi )
111
112{ w0(pi->saved_r0);
113 w2(pi->saved_r2);
114}
115
116static void fit2_log_adapter( PIA *pi, char * scratch, int verbose )
117
118{ printk("%s: fit2 %s, FIT 2000 adapter at 0x%x, delay %d\n",
119 pi->device,FIT2_VERSION,pi->port,pi->delay);
120
121}
122
123static struct pi_protocol fit2 = {
124 .owner = THIS_MODULE,
125 .name = "fit2",
126 .max_mode = 1,
127 .epp_first = 2,
128 .default_delay = 1,
129 .max_units = 1,
130 .write_regr = fit2_write_regr,
131 .read_regr = fit2_read_regr,
132 .write_block = fit2_write_block,
133 .read_block = fit2_read_block,
134 .connect = fit2_connect,
135 .disconnect = fit2_disconnect,
136 .log_adapter = fit2_log_adapter,
137};
138
139static int __init fit2_init(void)
140{
141 return pi_register(&fit2)-1;
142}
143
144static void __exit fit2_exit(void)
145{
146 pi_unregister(&fit2);
147}
148
149MODULE_LICENSE("GPL");
150module_init(fit2_init)
151module_exit(fit2_exit)
diff --git a/drivers/block/paride/fit3.c b/drivers/block/paride/fit3.c
new file mode 100644
index 000000000000..15400e7bc666
--- /dev/null
+++ b/drivers/block/paride/fit3.c
@@ -0,0 +1,211 @@
1/*
2 fit3.c (c) 1998 Grant R. Guenther <grant@torque.net>
3 Under the terms of the GNU General Public License.
4
5 fit3.c is a low-level protocol driver for newer models
6 of the Fidelity International Technology parallel port adapter.
7 This adapter is used in their TransDisk 3000 portable
8 hard-drives, as well as CD-ROM, PD-CD and other devices.
9
10 The TD-2000 and certain older devices use a different protocol.
11 Try the fit2 protocol module with them.
12
13 NB: The FIT adapters do not appear to support the control
14 registers. So, we map ALT_STATUS to STATUS and NO-OP writes
15 to the device control register - this means that IDE reset
16 will not work on these devices.
17
18*/
19
20#define FIT3_VERSION "1.0"
21
22#include <linux/module.h>
23#include <linux/init.h>
24#include <linux/delay.h>
25#include <linux/kernel.h>
26#include <linux/types.h>
27#include <linux/wait.h>
28#include <asm/io.h>
29
30#include "paride.h"
31
32#define j44(a,b) (((a>>3)&0x0f)|((b<<1)&0xf0))
33
34#define w7(byte) {out_p(7,byte);}
35#define r7() (in_p(7) & 0xff)
36
37/* cont = 0 - access the IDE register file
38 cont = 1 - access the IDE command set
39
40*/
41
42static void fit3_write_regr( PIA *pi, int cont, int regr, int val)
43
44{ if (cont == 1) return;
45
46 switch (pi->mode) {
47
48 case 0:
49 case 1: w2(0xc); w0(regr); w2(0x8); w2(0xc);
50 w0(val); w2(0xd);
51 w0(0); w2(0xc);
52 break;
53
54 case 2: w2(0xc); w0(regr); w2(0x8); w2(0xc);
55 w4(val); w4(0);
56 w2(0xc);
57 break;
58
59 }
60}
61
62static int fit3_read_regr( PIA *pi, int cont, int regr )
63
64{ int a, b;
65
66 if (cont) {
67 if (regr != 6) return 0xff;
68 regr = 7;
69 }
70
71 switch (pi->mode) {
72
73 case 0: w2(0xc); w0(regr + 0x10); w2(0x8); w2(0xc);
74 w2(0xd); a = r1();
75 w2(0xf); b = r1();
76 w2(0xc);
77 return j44(a,b);
78
79 case 1: w2(0xc); w0(regr + 0x90); w2(0x8); w2(0xc);
80 w2(0xec); w2(0xee); w2(0xef); a = r0();
81 w2(0xc);
82 return a;
83
84 case 2: w2(0xc); w0(regr + 0x90); w2(0x8); w2(0xc);
85 w2(0xec);
86 a = r4(); b = r4();
87 w2(0xc);
88 return a;
89
90 }
91 return -1;
92
93}
94
95static void fit3_read_block( PIA *pi, char * buf, int count )
96
97{ int k, a, b, c, d;
98
99 switch (pi->mode) {
100
101 case 0: w2(0xc); w0(0x10); w2(0x8); w2(0xc);
102 for (k=0;k<count/2;k++) {
103 w2(0xd); a = r1();
104 w2(0xf); b = r1();
105 w2(0xc); c = r1();
106 w2(0xe); d = r1();
107 buf[2*k ] = j44(a,b);
108 buf[2*k+1] = j44(c,d);
109 }
110 w2(0xc);
111 break;
112
113 case 1: w2(0xc); w0(0x90); w2(0x8); w2(0xc);
114 w2(0xec); w2(0xee);
115 for (k=0;k<count/2;k++) {
116 w2(0xef); a = r0();
117 w2(0xee); b = r0();
118 buf[2*k ] = a;
119 buf[2*k+1] = b;
120 }
121 w2(0xec);
122 w2(0xc);
123 break;
124
125 case 2: w2(0xc); w0(0x90); w2(0x8); w2(0xc);
126 w2(0xec);
127 for (k=0;k<count;k++) buf[k] = r4();
128 w2(0xc);
129 break;
130
131 }
132}
133
134static void fit3_write_block( PIA *pi, char * buf, int count )
135
136{ int k;
137
138 switch (pi->mode) {
139
140 case 0:
141 case 1: w2(0xc); w0(0); w2(0x8); w2(0xc);
142 for (k=0;k<count/2;k++) {
143 w0(buf[2*k ]); w2(0xd);
144 w0(buf[2*k+1]); w2(0xc);
145 }
146 break;
147
148 case 2: w2(0xc); w0(0); w2(0x8); w2(0xc);
149 for (k=0;k<count;k++) w4(buf[k]);
150 w2(0xc);
151 break;
152 }
153}
154
155static void fit3_connect ( PIA *pi )
156
157{ pi->saved_r0 = r0();
158 pi->saved_r2 = r2();
159 w2(0xc); w0(0); w2(0xa);
160 if (pi->mode == 2) {
161 w2(0xc); w0(0x9); w2(0x8); w2(0xc);
162 }
163}
164
165static void fit3_disconnect ( PIA *pi )
166
167{ w2(0xc); w0(0xa); w2(0x8); w2(0xc);
168 w0(pi->saved_r0);
169 w2(pi->saved_r2);
170}
171
172static void fit3_log_adapter( PIA *pi, char * scratch, int verbose )
173
174{ char *mode_string[3] = {"4-bit","8-bit","EPP"};
175
176 printk("%s: fit3 %s, FIT 3000 adapter at 0x%x, "
177 "mode %d (%s), delay %d\n",
178 pi->device,FIT3_VERSION,pi->port,
179 pi->mode,mode_string[pi->mode],pi->delay);
180
181}
182
183static struct pi_protocol fit3 = {
184 .owner = THIS_MODULE,
185 .name = "fit3",
186 .max_mode = 3,
187 .epp_first = 2,
188 .default_delay = 1,
189 .max_units = 1,
190 .write_regr = fit3_write_regr,
191 .read_regr = fit3_read_regr,
192 .write_block = fit3_write_block,
193 .read_block = fit3_read_block,
194 .connect = fit3_connect,
195 .disconnect = fit3_disconnect,
196 .log_adapter = fit3_log_adapter,
197};
198
199static int __init fit3_init(void)
200{
201 return pi_register(&fit3)-1;
202}
203
204static void __exit fit3_exit(void)
205{
206 pi_unregister(&fit3);
207}
208
209MODULE_LICENSE("GPL");
210module_init(fit3_init)
211module_exit(fit3_exit)
diff --git a/drivers/block/paride/friq.c b/drivers/block/paride/friq.c
new file mode 100644
index 000000000000..5ea2904d2815
--- /dev/null
+++ b/drivers/block/paride/friq.c
@@ -0,0 +1,276 @@
1/*
2 friq.c (c) 1998 Grant R. Guenther <grant@torque.net>
3 Under the terms of the GNU General Public License
4
5 friq.c is a low-level protocol driver for the Freecom "IQ"
6 parallel port IDE adapter. Early versions of this adapter
7 use the 'frpw' protocol.
8
9 Freecom uses this adapter in a battery powered external
10 CD-ROM drive. It is also used in LS-120 drives by
11 Maxell and Panasonic, and other devices.
12
13 The battery powered drive requires software support to
14 control the power to the drive. This module enables the
15 drive power when the high level driver (pcd) is loaded
16 and disables it when the module is unloaded. Note, if
17 the friq module is built in to the kernel, the power
18 will never be switched off, so other means should be
19 used to conserve battery power.
20
21*/
22
23/* Changes:
24
25 1.01 GRG 1998.12.20 Added support for soft power switch
26*/
27
28#define FRIQ_VERSION "1.01"
29
30#include <linux/module.h>
31#include <linux/init.h>
32#include <linux/delay.h>
33#include <linux/kernel.h>
34#include <linux/types.h>
35#include <linux/wait.h>
36#include <asm/io.h>
37
38#include "paride.h"
39
40#define CMD(x) w2(4);w0(0xff);w0(0xff);w0(0x73);w0(0x73);\
41 w0(0xc9);w0(0xc9);w0(0x26);w0(0x26);w0(x);w0(x);
42
43#define j44(l,h) (((l>>4)&0x0f)|(h&0xf0))
44
45/* cont = 0 - access the IDE register file
46 cont = 1 - access the IDE command set
47*/
48
49static int cont_map[2] = { 0x08, 0x10 };
50
51static int friq_read_regr( PIA *pi, int cont, int regr )
52
53{ int h,l,r;
54
55 r = regr + cont_map[cont];
56
57 CMD(r);
58 w2(6); l = r1();
59 w2(4); h = r1();
60 w2(4);
61
62 return j44(l,h);
63
64}
65
66static void friq_write_regr( PIA *pi, int cont, int regr, int val)
67
68{ int r;
69
70 r = regr + cont_map[cont];
71
72 CMD(r);
73 w0(val);
74 w2(5);w2(7);w2(5);w2(4);
75}
76
77static void friq_read_block_int( PIA *pi, char * buf, int count, int regr )
78
79{ int h, l, k, ph;
80
81 switch(pi->mode) {
82
83 case 0: CMD(regr);
84 for (k=0;k<count;k++) {
85 w2(6); l = r1();
86 w2(4); h = r1();
87 buf[k] = j44(l,h);
88 }
89 w2(4);
90 break;
91
92 case 1: ph = 2;
93 CMD(regr+0xc0);
94 w0(0xff);
95 for (k=0;k<count;k++) {
96 w2(0xa4 + ph);
97 buf[k] = r0();
98 ph = 2 - ph;
99 }
100 w2(0xac); w2(0xa4); w2(4);
101 break;
102
103 case 2: CMD(regr+0x80);
104 for (k=0;k<count-2;k++) buf[k] = r4();
105 w2(0xac); w2(0xa4);
106 buf[count-2] = r4();
107 buf[count-1] = r4();
108 w2(4);
109 break;
110
111 case 3: CMD(regr+0x80);
112 for (k=0;k<(count/2)-1;k++) ((u16 *)buf)[k] = r4w();
113 w2(0xac); w2(0xa4);
114 buf[count-2] = r4();
115 buf[count-1] = r4();
116 w2(4);
117 break;
118
119 case 4: CMD(regr+0x80);
120 for (k=0;k<(count/4)-1;k++) ((u32 *)buf)[k] = r4l();
121 buf[count-4] = r4();
122 buf[count-3] = r4();
123 w2(0xac); w2(0xa4);
124 buf[count-2] = r4();
125 buf[count-1] = r4();
126 w2(4);
127 break;
128
129 }
130}
131
132static void friq_read_block( PIA *pi, char * buf, int count)
133
134{ friq_read_block_int(pi,buf,count,0x08);
135}
136
137static void friq_write_block( PIA *pi, char * buf, int count )
138
139{ int k;
140
141 switch(pi->mode) {
142
143 case 0:
144 case 1: CMD(8); w2(5);
145 for (k=0;k<count;k++) {
146 w0(buf[k]);
147 w2(7);w2(5);
148 }
149 w2(4);
150 break;
151
152 case 2: CMD(0xc8); w2(5);
153 for (k=0;k<count;k++) w4(buf[k]);
154 w2(4);
155 break;
156
157 case 3: CMD(0xc8); w2(5);
158 for (k=0;k<count/2;k++) w4w(((u16 *)buf)[k]);
159 w2(4);
160 break;
161
162 case 4: CMD(0xc8); w2(5);
163 for (k=0;k<count/4;k++) w4l(((u32 *)buf)[k]);
164 w2(4);
165 break;
166 }
167}
168
169static void friq_connect ( PIA *pi )
170
171{ pi->saved_r0 = r0();
172 pi->saved_r2 = r2();
173 w2(4);
174}
175
176static void friq_disconnect ( PIA *pi )
177
178{ CMD(0x20);
179 w0(pi->saved_r0);
180 w2(pi->saved_r2);
181}
182
183static int friq_test_proto( PIA *pi, char * scratch, int verbose )
184
185{ int j, k, r;
186 int e[2] = {0,0};
187
188 pi->saved_r0 = r0();
189 w0(0xff); udelay(20); CMD(0x3d); /* turn the power on */
190 udelay(500);
191 w0(pi->saved_r0);
192
193 friq_connect(pi);
194 for (j=0;j<2;j++) {
195 friq_write_regr(pi,0,6,0xa0+j*0x10);
196 for (k=0;k<256;k++) {
197 friq_write_regr(pi,0,2,k^0xaa);
198 friq_write_regr(pi,0,3,k^0x55);
199 if (friq_read_regr(pi,0,2) != (k^0xaa)) e[j]++;
200 }
201 }
202 friq_disconnect(pi);
203
204 friq_connect(pi);
205 friq_read_block_int(pi,scratch,512,0x10);
206 r = 0;
207 for (k=0;k<128;k++) if (scratch[k] != k) r++;
208 friq_disconnect(pi);
209
210 if (verbose) {
211 printk("%s: friq: port 0x%x, mode %d, test=(%d,%d,%d)\n",
212 pi->device,pi->port,pi->mode,e[0],e[1],r);
213 }
214
215 return (r || (e[0] && e[1]));
216}
217
218
219static void friq_log_adapter( PIA *pi, char * scratch, int verbose )
220
221{ char *mode_string[6] = {"4-bit","8-bit",
222 "EPP-8","EPP-16","EPP-32"};
223
224 printk("%s: friq %s, Freecom IQ ASIC-2 adapter at 0x%x, ", pi->device,
225 FRIQ_VERSION,pi->port);
226 printk("mode %d (%s), delay %d\n",pi->mode,
227 mode_string[pi->mode],pi->delay);
228
229 pi->private = 1;
230 friq_connect(pi);
231 CMD(0x9e); /* disable sleep timer */
232 friq_disconnect(pi);
233
234}
235
236static void friq_release_proto( PIA *pi)
237{
238 if (pi->private) { /* turn off the power */
239 friq_connect(pi);
240 CMD(0x1d); CMD(0x1e);
241 friq_disconnect(pi);
242 pi->private = 0;
243 }
244}
245
246static struct pi_protocol friq = {
247 .owner = THIS_MODULE,
248 .name = "friq",
249 .max_mode = 5,
250 .epp_first = 2,
251 .default_delay = 1,
252 .max_units = 1,
253 .write_regr = friq_write_regr,
254 .read_regr = friq_read_regr,
255 .write_block = friq_write_block,
256 .read_block = friq_read_block,
257 .connect = friq_connect,
258 .disconnect = friq_disconnect,
259 .test_proto = friq_test_proto,
260 .log_adapter = friq_log_adapter,
261 .release_proto = friq_release_proto,
262};
263
264static int __init friq_init(void)
265{
266 return pi_register(&friq)-1;
267}
268
269static void __exit friq_exit(void)
270{
271 pi_unregister(&friq);
272}
273
274MODULE_LICENSE("GPL");
275module_init(friq_init)
276module_exit(friq_exit)
diff --git a/drivers/block/paride/frpw.c b/drivers/block/paride/frpw.c
new file mode 100644
index 000000000000..56b3824b1538
--- /dev/null
+++ b/drivers/block/paride/frpw.c
@@ -0,0 +1,313 @@
1/*
2 frpw.c (c) 1996-8 Grant R. Guenther <grant@torque.net>
3 Under the terms of the GNU General Public License
4
5 frpw.c is a low-level protocol driver for the Freecom "Power"
6 parallel port IDE adapter.
7
8 Some applications of this adapter may require a "printer" reset
9 prior to loading the driver. This can be done by loading and
10 unloading the "lp" driver, or it can be done by this driver
11 if you define FRPW_HARD_RESET. The latter is not recommended
12 as it may upset devices on other ports.
13
14*/
15
16/* Changes:
17
18 1.01 GRG 1998.05.06 init_proto, release_proto
19 fix chip detect
20 added EPP-16 and EPP-32
21 1.02 GRG 1998.09.23 added hard reset to initialisation process
22 1.03 GRG 1998.12.14 made hard reset conditional
23
24*/
25
26#define FRPW_VERSION "1.03"
27
28#include <linux/module.h>
29#include <linux/init.h>
30#include <linux/delay.h>
31#include <linux/kernel.h>
32#include <linux/types.h>
33#include <linux/wait.h>
34#include <asm/io.h>
35
36#include "paride.h"
37
38#define cec4 w2(0xc);w2(0xe);w2(0xe);w2(0xc);w2(4);w2(4);w2(4);
39#define j44(l,h) (((l>>4)&0x0f)|(h&0xf0))
40
41/* cont = 0 - access the IDE register file
42 cont = 1 - access the IDE command set
43*/
44
45static int cont_map[2] = { 0x08, 0x10 };
46
47static int frpw_read_regr( PIA *pi, int cont, int regr )
48
49{ int h,l,r;
50
51 r = regr + cont_map[cont];
52
53 w2(4);
54 w0(r); cec4;
55 w2(6); l = r1();
56 w2(4); h = r1();
57 w2(4);
58
59 return j44(l,h);
60
61}
62
63static void frpw_write_regr( PIA *pi, int cont, int regr, int val)
64
65{ int r;
66
67 r = regr + cont_map[cont];
68
69 w2(4); w0(r); cec4;
70 w0(val);
71 w2(5);w2(7);w2(5);w2(4);
72}
73
74static void frpw_read_block_int( PIA *pi, char * buf, int count, int regr )
75
76{ int h, l, k, ph;
77
78 switch(pi->mode) {
79
80 case 0: w2(4); w0(regr); cec4;
81 for (k=0;k<count;k++) {
82 w2(6); l = r1();
83 w2(4); h = r1();
84 buf[k] = j44(l,h);
85 }
86 w2(4);
87 break;
88
89 case 1: ph = 2;
90 w2(4); w0(regr + 0xc0); cec4;
91 w0(0xff);
92 for (k=0;k<count;k++) {
93 w2(0xa4 + ph);
94 buf[k] = r0();
95 ph = 2 - ph;
96 }
97 w2(0xac); w2(0xa4); w2(4);
98 break;
99
100 case 2: w2(4); w0(regr + 0x80); cec4;
101 for (k=0;k<count;k++) buf[k] = r4();
102 w2(0xac); w2(0xa4);
103 w2(4);
104 break;
105
106 case 3: w2(4); w0(regr + 0x80); cec4;
107 for (k=0;k<count-2;k++) buf[k] = r4();
108 w2(0xac); w2(0xa4);
109 buf[count-2] = r4();
110 buf[count-1] = r4();
111 w2(4);
112 break;
113
114 case 4: w2(4); w0(regr + 0x80); cec4;
115 for (k=0;k<(count/2)-1;k++) ((u16 *)buf)[k] = r4w();
116 w2(0xac); w2(0xa4);
117 buf[count-2] = r4();
118 buf[count-1] = r4();
119 w2(4);
120 break;
121
122 case 5: w2(4); w0(regr + 0x80); cec4;
123 for (k=0;k<(count/4)-1;k++) ((u32 *)buf)[k] = r4l();
124 buf[count-4] = r4();
125 buf[count-3] = r4();
126 w2(0xac); w2(0xa4);
127 buf[count-2] = r4();
128 buf[count-1] = r4();
129 w2(4);
130 break;
131
132 }
133}
134
135static void frpw_read_block( PIA *pi, char * buf, int count)
136
137{ frpw_read_block_int(pi,buf,count,0x08);
138}
139
140static void frpw_write_block( PIA *pi, char * buf, int count )
141
142{ int k;
143
144 switch(pi->mode) {
145
146 case 0:
147 case 1:
148 case 2: w2(4); w0(8); cec4; w2(5);
149 for (k=0;k<count;k++) {
150 w0(buf[k]);
151 w2(7);w2(5);
152 }
153 w2(4);
154 break;
155
156 case 3: w2(4); w0(0xc8); cec4; w2(5);
157 for (k=0;k<count;k++) w4(buf[k]);
158 w2(4);
159 break;
160
161 case 4: w2(4); w0(0xc8); cec4; w2(5);
162 for (k=0;k<count/2;k++) w4w(((u16 *)buf)[k]);
163 w2(4);
164 break;
165
166 case 5: w2(4); w0(0xc8); cec4; w2(5);
167 for (k=0;k<count/4;k++) w4l(((u32 *)buf)[k]);
168 w2(4);
169 break;
170 }
171}
172
173static void frpw_connect ( PIA *pi )
174
175{ pi->saved_r0 = r0();
176 pi->saved_r2 = r2();
177 w2(4);
178}
179
180static void frpw_disconnect ( PIA *pi )
181
182{ w2(4); w0(0x20); cec4;
183 w0(pi->saved_r0);
184 w2(pi->saved_r2);
185}
186
187/* Stub logic to see if PNP string is available - used to distinguish
188 between the Xilinx and ASIC implementations of the Freecom adapter.
189*/
190
191static int frpw_test_pnp ( PIA *pi )
192
193/* returns chip_type: 0 = Xilinx, 1 = ASIC */
194
195{ int olddelay, a, b;
196
197#ifdef FRPW_HARD_RESET
198 w0(0); w2(8); udelay(50); w2(0xc); /* parallel bus reset */
199 mdelay(1500);
200#endif
201
202 olddelay = pi->delay;
203 pi->delay = 10;
204
205 pi->saved_r0 = r0();
206 pi->saved_r2 = r2();
207
208 w2(4); w0(4); w2(6); w2(7);
209 a = r1() & 0xff; w2(4); b = r1() & 0xff;
210 w2(0xc); w2(0xe); w2(4);
211
212 pi->delay = olddelay;
213 w0(pi->saved_r0);
214 w2(pi->saved_r2);
215
216 return ((~a&0x40) && (b&0x40));
217}
218
219/* We use the pi->private to remember the result of the PNP test.
220 To make this work, private = port*2 + chip. Yes, I know it's
221 a hack :-(
222*/
223
224static int frpw_test_proto( PIA *pi, char * scratch, int verbose )
225
226{ int j, k, r;
227 int e[2] = {0,0};
228
229 if ((pi->private>>1) != pi->port)
230 pi->private = frpw_test_pnp(pi) + 2*pi->port;
231
232 if (((pi->private%2) == 0) && (pi->mode > 2)) {
233 if (verbose)
234 printk("%s: frpw: Xilinx does not support mode %d\n",
235 pi->device, pi->mode);
236 return 1;
237 }
238
239 if (((pi->private%2) == 1) && (pi->mode == 2)) {
240 if (verbose)
241 printk("%s: frpw: ASIC does not support mode 2\n",
242 pi->device);
243 return 1;
244 }
245
246 frpw_connect(pi);
247 for (j=0;j<2;j++) {
248 frpw_write_regr(pi,0,6,0xa0+j*0x10);
249 for (k=0;k<256;k++) {
250 frpw_write_regr(pi,0,2,k^0xaa);
251 frpw_write_regr(pi,0,3,k^0x55);
252 if (frpw_read_regr(pi,0,2) != (k^0xaa)) e[j]++;
253 }
254 }
255 frpw_disconnect(pi);
256
257 frpw_connect(pi);
258 frpw_read_block_int(pi,scratch,512,0x10);
259 r = 0;
260 for (k=0;k<128;k++) if (scratch[k] != k) r++;
261 frpw_disconnect(pi);
262
263 if (verbose) {
264 printk("%s: frpw: port 0x%x, chip %ld, mode %d, test=(%d,%d,%d)\n",
265 pi->device,pi->port,(pi->private%2),pi->mode,e[0],e[1],r);
266 }
267
268 return (r || (e[0] && e[1]));
269}
270
271
272static void frpw_log_adapter( PIA *pi, char * scratch, int verbose )
273
274{ char *mode_string[6] = {"4-bit","8-bit","EPP",
275 "EPP-8","EPP-16","EPP-32"};
276
277 printk("%s: frpw %s, Freecom (%s) adapter at 0x%x, ", pi->device,
278 FRPW_VERSION,((pi->private%2) == 0)?"Xilinx":"ASIC",pi->port);
279 printk("mode %d (%s), delay %d\n",pi->mode,
280 mode_string[pi->mode],pi->delay);
281
282}
283
284static struct pi_protocol frpw = {
285 .owner = THIS_MODULE,
286 .name = "frpw",
287 .max_mode = 6,
288 .epp_first = 2,
289 .default_delay = 2,
290 .max_units = 1,
291 .write_regr = frpw_write_regr,
292 .read_regr = frpw_read_regr,
293 .write_block = frpw_write_block,
294 .read_block = frpw_read_block,
295 .connect = frpw_connect,
296 .disconnect = frpw_disconnect,
297 .test_proto = frpw_test_proto,
298 .log_adapter = frpw_log_adapter,
299};
300
301static int __init frpw_init(void)
302{
303 return pi_register(&frpw)-1;
304}
305
306static void __exit frpw_exit(void)
307{
308 pi_unregister(&frpw);
309}
310
311MODULE_LICENSE("GPL");
312module_init(frpw_init)
313module_exit(frpw_exit)
diff --git a/drivers/block/paride/jumbo b/drivers/block/paride/jumbo
new file mode 100644
index 000000000000..e793b9cb7e72
--- /dev/null
+++ b/drivers/block/paride/jumbo
@@ -0,0 +1,70 @@
1#!/bin/sh
2#
3# This script can be used to build "jumbo" modules that contain the
4# base PARIDE support, one protocol module and one high-level driver.
5#
6echo -n "High level driver [pcd] : "
7read X
8HLD=${X:-pcd}
9#
10echo -n "Protocol module [bpck] : "
11read X
12PROTO=${X:-bpck}
13#
14echo -n "Use MODVERSIONS [y] ? "
15read X
16UMODV=${X:-y}
17#
18echo -n "For SMP kernel [n] ? "
19read X
20USMP=${X:-n}
21#
22echo -n "Support PARPORT [n] ? "
23read X
24UPARP=${X:-n}
25#
26echo
27#
28case $USMP in
29 y* | Y* ) FSMP="-DCONFIG_SMP"
30 ;;
31 *) FSMP=""
32 ;;
33esac
34#
35MODI="-include ../../../include/linux/modversions.h"
36#
37case $UMODV in
38 y* | Y* ) FMODV="-DMODVERSIONS $MODI"
39 ;;
40 *) FMODV=""
41 ;;
42esac
43#
44case $UPARP in
45 y* | Y* ) FPARP="-DCONFIG_PARPORT"
46 ;;
47 *) FPARP=""
48 ;;
49esac
50#
51TARG=$HLD-$PROTO.o
52FPROTO=-DCONFIG_PARIDE_`echo "$PROTO" | tr [a-z] [A-Z]`
53FK="-D__KERNEL__ -I ../../../include"
54FLCH=-D_LINUX_CONFIG_H
55#
56echo cc $FK $FSMP $FLCH $FPARP $FPROTO $FMODV -Wall -O2 -o Jb.o -c paride.c
57cc $FK $FSMP $FLCH $FPARP $FPROTO $FMODV -Wall -O2 -o Jb.o -c paride.c
58#
59echo cc $FK $FSMP $FMODV -Wall -O2 -o Jp.o -c $PROTO.c
60cc $FK $FSMP $FMODV -Wall -O2 -o Jp.o -c $PROTO.c
61#
62echo cc $FK $FSMP $FMODV -DMODULE -DPARIDE_JUMBO -Wall -O2 -o Jd.o -c $HLD.c
63cc $FK $FSMP $FMODV -DMODULE -DPARIDE_JUMBO -Wall -O2 -o Jd.o -c $HLD.c
64#
65echo ld -r -o $TARG Jp.o Jb.o Jd.o
66ld -r -o $TARG Jp.o Jb.o Jd.o
67#
68#
69rm Jp.o Jb.o Jd.o
70#
diff --git a/drivers/block/paride/kbic.c b/drivers/block/paride/kbic.c
new file mode 100644
index 000000000000..d983bcea76fe
--- /dev/null
+++ b/drivers/block/paride/kbic.c
@@ -0,0 +1,297 @@
1/*
2 kbic.c (c) 1997-8 Grant R. Guenther <grant@torque.net>
3 Under the terms of the GNU General Public License.
4
5 This is a low-level driver for the KBIC-951A and KBIC-971A
6 parallel to IDE adapter chips from KingByte Information Systems.
7
8 The chips are almost identical, however, the wakeup code
9 required for the 971A interferes with the correct operation of
10 the 951A, so this driver registers itself twice, once for
11 each chip.
12
13*/
14
15/* Changes:
16
17 1.01 GRG 1998.05.06 init_proto, release_proto
18
19*/
20
21#define KBIC_VERSION "1.01"
22
23#include <linux/module.h>
24#include <linux/init.h>
25#include <linux/delay.h>
26#include <linux/kernel.h>
27#include <linux/types.h>
28#include <linux/wait.h>
29#include <asm/io.h>
30
31#include "paride.h"
32
33#define r12w() (delay_p,inw(pi->port+1)&0xffff)
34
35#define j44(a,b) ((((a>>4)&0x0f)|(b&0xf0))^0x88)
36#define j53(w) (((w>>3)&0x1f)|((w>>4)&0xe0))
37
38
39/* cont = 0 - access the IDE register file
40 cont = 1 - access the IDE command set
41*/
42
43static int cont_map[2] = { 0x80, 0x40 };
44
45static int kbic_read_regr( PIA *pi, int cont, int regr )
46
47{ int a, b, s;
48
49 s = cont_map[cont];
50
51 switch (pi->mode) {
52
53 case 0: w0(regr|0x18|s); w2(4); w2(6); w2(4); w2(1); w0(8);
54 a = r1(); w0(0x28); b = r1(); w2(4);
55 return j44(a,b);
56
57 case 1: w0(regr|0x38|s); w2(4); w2(6); w2(4); w2(5); w0(8);
58 a = r12w(); w2(4);
59 return j53(a);
60
61 case 2: w0(regr|0x08|s); w2(4); w2(6); w2(4); w2(0xa5); w2(0xa1);
62 a = r0(); w2(4);
63 return a;
64
65 case 3:
66 case 4:
67 case 5: w0(0x20|s); w2(4); w2(6); w2(4); w3(regr);
68 a = r4(); b = r4(); w2(4); w2(0); w2(4);
69 return a;
70
71 }
72 return -1;
73}
74
75static void kbic_write_regr( PIA *pi, int cont, int regr, int val)
76
77{ int s;
78
79 s = cont_map[cont];
80
81 switch (pi->mode) {
82
83 case 0:
84 case 1:
85 case 2: w0(regr|0x10|s); w2(4); w2(6); w2(4);
86 w0(val); w2(5); w2(4);
87 break;
88
89 case 3:
90 case 4:
91 case 5: w0(0x20|s); w2(4); w2(6); w2(4); w3(regr);
92 w4(val); w4(val);
93 w2(4); w2(0); w2(4);
94 break;
95
96 }
97}
98
99static void k951_connect ( PIA *pi )
100
101{ pi->saved_r0 = r0();
102 pi->saved_r2 = r2();
103 w2(4);
104}
105
106static void k951_disconnect ( PIA *pi )
107
108{ w0(pi->saved_r0);
109 w2(pi->saved_r2);
110}
111
112#define CCP(x) w2(0xc4);w0(0xaa);w0(0x55);w0(0);w0(0xff);w0(0x87);\
113 w0(0x78);w0(x);w2(0xc5);w2(0xc4);w0(0xff);
114
115static void k971_connect ( PIA *pi )
116
117{ pi->saved_r0 = r0();
118 pi->saved_r2 = r2();
119 CCP(0x20);
120 w2(4);
121}
122
123static void k971_disconnect ( PIA *pi )
124
125{ CCP(0x30);
126 w0(pi->saved_r0);
127 w2(pi->saved_r2);
128}
129
130/* counts must be congruent to 0 MOD 4, but all known applications
131 have this property.
132*/
133
134static void kbic_read_block( PIA *pi, char * buf, int count )
135
136{ int k, a, b;
137
138 switch (pi->mode) {
139
140 case 0: w0(0x98); w2(4); w2(6); w2(4);
141 for (k=0;k<count/2;k++) {
142 w2(1); w0(8); a = r1();
143 w0(0x28); b = r1();
144 buf[2*k] = j44(a,b);
145 w2(5); b = r1();
146 w0(8); a = r1();
147 buf[2*k+1] = j44(a,b);
148 w2(4);
149 }
150 break;
151
152 case 1: w0(0xb8); w2(4); w2(6); w2(4);
153 for (k=0;k<count/4;k++) {
154 w0(0xb8);
155 w2(4); w2(5);
156 w0(8); buf[4*k] = j53(r12w());
157 w0(0xb8); buf[4*k+1] = j53(r12w());
158 w2(4); w2(5);
159 buf[4*k+3] = j53(r12w());
160 w0(8); buf[4*k+2] = j53(r12w());
161 }
162 w2(4);
163 break;
164
165 case 2: w0(0x88); w2(4); w2(6); w2(4);
166 for (k=0;k<count/2;k++) {
167 w2(0xa0); w2(0xa1); buf[2*k] = r0();
168 w2(0xa5); buf[2*k+1] = r0();
169 }
170 w2(4);
171 break;
172
173 case 3: w0(0xa0); w2(4); w2(6); w2(4); w3(0);
174 for (k=0;k<count;k++) buf[k] = r4();
175 w2(4); w2(0); w2(4);
176 break;
177
178 case 4: w0(0xa0); w2(4); w2(6); w2(4); w3(0);
179 for (k=0;k<count/2;k++) ((u16 *)buf)[k] = r4w();
180 w2(4); w2(0); w2(4);
181 break;
182
183 case 5: w0(0xa0); w2(4); w2(6); w2(4); w3(0);
184 for (k=0;k<count/4;k++) ((u32 *)buf)[k] = r4l();
185 w2(4); w2(0); w2(4);
186 break;
187
188
189 }
190}
191
192static void kbic_write_block( PIA *pi, char * buf, int count )
193
194{ int k;
195
196 switch (pi->mode) {
197
198 case 0:
199 case 1:
200 case 2: w0(0x90); w2(4); w2(6); w2(4);
201 for(k=0;k<count/2;k++) {
202 w0(buf[2*k+1]); w2(0); w2(4);
203 w0(buf[2*k]); w2(5); w2(4);
204 }
205 break;
206
207 case 3: w0(0xa0); w2(4); w2(6); w2(4); w3(0);
208 for(k=0;k<count/2;k++) {
209 w4(buf[2*k+1]);
210 w4(buf[2*k]);
211 }
212 w2(4); w2(0); w2(4);
213 break;
214
215 case 4: w0(0xa0); w2(4); w2(6); w2(4); w3(0);
216 for(k=0;k<count/2;k++) w4w(pi_swab16(buf,k));
217 w2(4); w2(0); w2(4);
218 break;
219
220 case 5: w0(0xa0); w2(4); w2(6); w2(4); w3(0);
221 for(k=0;k<count/4;k++) w4l(pi_swab32(buf,k));
222 w2(4); w2(0); w2(4);
223 break;
224
225 }
226
227}
228
229static void kbic_log_adapter( PIA *pi, char * scratch,
230 int verbose, char * chip )
231
232{ char *mode_string[6] = {"4-bit","5/3","8-bit",
233 "EPP-8","EPP_16","EPP-32"};
234
235 printk("%s: kbic %s, KingByte %s at 0x%x, ",
236 pi->device,KBIC_VERSION,chip,pi->port);
237 printk("mode %d (%s), delay %d\n",pi->mode,
238 mode_string[pi->mode],pi->delay);
239
240}
241
242static void k951_log_adapter( PIA *pi, char * scratch, int verbose )
243
244{ kbic_log_adapter(pi,scratch,verbose,"KBIC-951A");
245}
246
247static void k971_log_adapter( PIA *pi, char * scratch, int verbose )
248
249{ kbic_log_adapter(pi,scratch,verbose,"KBIC-971A");
250}
251
252static struct pi_protocol k951 = {
253 .owner = THIS_MODULE,
254 .name = "k951",
255 .max_mode = 6,
256 .epp_first = 3,
257 .default_delay = 1,
258 .max_units = 1,
259 .write_regr = kbic_write_regr,
260 .read_regr = kbic_read_regr,
261 .write_block = kbic_write_block,
262 .read_block = kbic_read_block,
263 .connect = k951_connect,
264 .disconnect = k951_disconnect,
265 .log_adapter = k951_log_adapter,
266};
267
268static struct pi_protocol k971 = {
269 .owner = THIS_MODULE,
270 .name = "k971",
271 .max_mode = 6,
272 .epp_first = 3,
273 .default_delay = 1,
274 .max_units = 1,
275 .write_regr = kbic_write_regr,
276 .read_regr = kbic_read_regr,
277 .write_block = kbic_write_block,
278 .read_block = kbic_read_block,
279 .connect = k971_connect,
280 .disconnect = k971_disconnect,
281 .log_adapter = k971_log_adapter,
282};
283
284static int __init kbic_init(void)
285{
286 return (pi_register(&k951)||pi_register(&k971))-1;
287}
288
289static void __exit kbic_exit(void)
290{
291 pi_unregister(&k951);
292 pi_unregister(&k971);
293}
294
295MODULE_LICENSE("GPL");
296module_init(kbic_init)
297module_exit(kbic_exit)
diff --git a/drivers/block/paride/ktti.c b/drivers/block/paride/ktti.c
new file mode 100644
index 000000000000..6c7edbfba9a0
--- /dev/null
+++ b/drivers/block/paride/ktti.c
@@ -0,0 +1,128 @@
1/*
2 ktti.c (c) 1998 Grant R. Guenther <grant@torque.net>
3 Under the terms of the GNU General Public License.
4
5 ktti.c is a low-level protocol driver for the KT Technology
6 parallel port adapter. This adapter is used in the "PHd"
7 portable hard-drives. As far as I can tell, this device
8 supports 4-bit mode _only_.
9
10*/
11
12#define KTTI_VERSION "1.0"
13
14#include <linux/module.h>
15#include <linux/init.h>
16#include <linux/delay.h>
17#include <linux/kernel.h>
18#include <linux/types.h>
19#include <linux/wait.h>
20#include <asm/io.h>
21
22#include "paride.h"
23
24#define j44(a,b) (((a>>4)&0x0f)|(b&0xf0))
25
26/* cont = 0 - access the IDE register file
27 cont = 1 - access the IDE command set
28*/
29
30static int cont_map[2] = { 0x10, 0x08 };
31
32static void ktti_write_regr( PIA *pi, int cont, int regr, int val)
33
34{ int r;
35
36 r = regr + cont_map[cont];
37
38 w0(r); w2(0xb); w2(0xa); w2(3); w2(6);
39 w0(val); w2(3); w0(0); w2(6); w2(0xb);
40}
41
42static int ktti_read_regr( PIA *pi, int cont, int regr )
43
44{ int a, b, r;
45
46 r = regr + cont_map[cont];
47
48 w0(r); w2(0xb); w2(0xa); w2(9); w2(0xc); w2(9);
49 a = r1(); w2(0xc); b = r1(); w2(9); w2(0xc); w2(9);
50 return j44(a,b);
51
52}
53
54static void ktti_read_block( PIA *pi, char * buf, int count )
55
56{ int k, a, b;
57
58 for (k=0;k<count/2;k++) {
59 w0(0x10); w2(0xb); w2(0xa); w2(9); w2(0xc); w2(9);
60 a = r1(); w2(0xc); b = r1(); w2(9);
61 buf[2*k] = j44(a,b);
62 a = r1(); w2(0xc); b = r1(); w2(9);
63 buf[2*k+1] = j44(a,b);
64 }
65}
66
67static void ktti_write_block( PIA *pi, char * buf, int count )
68
69{ int k;
70
71 for (k=0;k<count/2;k++) {
72 w0(0x10); w2(0xb); w2(0xa); w2(3); w2(6);
73 w0(buf[2*k]); w2(3);
74 w0(buf[2*k+1]); w2(6);
75 w2(0xb);
76 }
77}
78
79static void ktti_connect ( PIA *pi )
80
81{ pi->saved_r0 = r0();
82 pi->saved_r2 = r2();
83 w2(0xb); w2(0xa); w0(0); w2(3); w2(6);
84}
85
86static void ktti_disconnect ( PIA *pi )
87
88{ w2(0xb); w2(0xa); w0(0xa0); w2(3); w2(4);
89 w0(pi->saved_r0);
90 w2(pi->saved_r2);
91}
92
93static void ktti_log_adapter( PIA *pi, char * scratch, int verbose )
94
95{ printk("%s: ktti %s, KT adapter at 0x%x, delay %d\n",
96 pi->device,KTTI_VERSION,pi->port,pi->delay);
97
98}
99
100static struct pi_protocol ktti = {
101 .owner = THIS_MODULE,
102 .name = "ktti",
103 .max_mode = 1,
104 .epp_first = 2,
105 .default_delay = 1,
106 .max_units = 1,
107 .write_regr = ktti_write_regr,
108 .read_regr = ktti_read_regr,
109 .write_block = ktti_write_block,
110 .read_block = ktti_read_block,
111 .connect = ktti_connect,
112 .disconnect = ktti_disconnect,
113 .log_adapter = ktti_log_adapter,
114};
115
116static int __init ktti_init(void)
117{
118 return pi_register(&ktti)-1;
119}
120
121static void __exit ktti_exit(void)
122{
123 pi_unregister(&ktti);
124}
125
126MODULE_LICENSE("GPL");
127module_init(ktti_init)
128module_exit(ktti_exit)
diff --git a/drivers/block/paride/mkd b/drivers/block/paride/mkd
new file mode 100644
index 000000000000..971f099b40aa
--- /dev/null
+++ b/drivers/block/paride/mkd
@@ -0,0 +1,30 @@
1#!/bin/bash
2#
3# mkd -- a script to create the device special files for the PARIDE subsystem
4#
5# block devices: pd (45), pcd (46), pf (47)
6# character devices: pt (96), pg (97)
7#
8function mkdev {
9 mknod $1 $2 $3 $4 ; chmod 0660 $1 ; chown root:disk $1
10}
11#
12function pd {
13 D=$( printf \\$( printf "x%03x" $[ $1 + 97 ] ) )
14 mkdev pd$D b 45 $[ $1 * 16 ]
15 for P in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
16 do mkdev pd$D$P b 45 $[ $1 * 16 + $P ]
17 done
18}
19#
20cd /dev
21#
22for u in 0 1 2 3 ; do pd $u ; done
23for u in 0 1 2 3 ; do mkdev pcd$u b 46 $u ; done
24for u in 0 1 2 3 ; do mkdev pf$u b 47 $u ; done
25for u in 0 1 2 3 ; do mkdev pt$u c 96 $u ; done
26for u in 0 1 2 3 ; do mkdev npt$u c 96 $[ $u + 128 ] ; done
27for u in 0 1 2 3 ; do mkdev pg$u c 97 $u ; done
28#
29# end of mkd
30
diff --git a/drivers/block/paride/on20.c b/drivers/block/paride/on20.c
new file mode 100644
index 000000000000..9f8e01096809
--- /dev/null
+++ b/drivers/block/paride/on20.c
@@ -0,0 +1,153 @@
1/*
2 on20.c (c) 1996-8 Grant R. Guenther <grant@torque.net>
3 Under the terms of the GNU General Public License.
4
5 on20.c is a low-level protocol driver for the
6 Onspec 90c20 parallel to IDE adapter.
7*/
8
9/* Changes:
10
11 1.01 GRG 1998.05.06 init_proto, release_proto
12
13*/
14
15#define ON20_VERSION "1.01"
16
17#include <linux/module.h>
18#include <linux/init.h>
19#include <linux/delay.h>
20#include <linux/kernel.h>
21#include <linux/types.h>
22#include <linux/wait.h>
23#include <asm/io.h>
24
25#include "paride.h"
26
27#define op(f) w2(4);w0(f);w2(5);w2(0xd);w2(5);w2(0xd);w2(5);w2(4);
28#define vl(v) w2(4);w0(v);w2(5);w2(7);w2(5);w2(4);
29
30#define j44(a,b) (((a>>4)&0x0f)|(b&0xf0))
31
32/* cont = 0 - access the IDE register file
33 cont = 1 - access the IDE command set
34*/
35
36static int on20_read_regr( PIA *pi, int cont, int regr )
37
38{ int h,l, r ;
39
40 r = (regr<<2) + 1 + cont;
41
42 op(1); vl(r); op(0);
43
44 switch (pi->mode) {
45
46 case 0: w2(4); w2(6); l = r1();
47 w2(4); w2(6); h = r1();
48 w2(4); w2(6); w2(4); w2(6); w2(4);
49 return j44(l,h);
50
51 case 1: w2(4); w2(0x26); r = r0();
52 w2(4); w2(0x26); w2(4);
53 return r;
54
55 }
56 return -1;
57}
58
59static void on20_write_regr( PIA *pi, int cont, int regr, int val )
60
61{ int r;
62
63 r = (regr<<2) + 1 + cont;
64
65 op(1); vl(r);
66 op(0); vl(val);
67 op(0); vl(val);
68}
69
70static void on20_connect ( PIA *pi)
71
72{ pi->saved_r0 = r0();
73 pi->saved_r2 = r2();
74
75 w2(4);w0(0);w2(0xc);w2(4);w2(6);w2(4);w2(6);w2(4);
76 if (pi->mode) { op(2); vl(8); op(2); vl(9); }
77 else { op(2); vl(0); op(2); vl(8); }
78}
79
80static void on20_disconnect ( PIA *pi )
81
82{ w2(4);w0(7);w2(4);w2(0xc);w2(4);
83 w0(pi->saved_r0);
84 w2(pi->saved_r2);
85}
86
87static void on20_read_block( PIA *pi, char * buf, int count )
88
89{ int k, l, h;
90
91 op(1); vl(1); op(0);
92
93 for (k=0;k<count;k++)
94 if (pi->mode) {
95 w2(4); w2(0x26); buf[k] = r0();
96 } else {
97 w2(6); l = r1(); w2(4);
98 w2(6); h = r1(); w2(4);
99 buf[k] = j44(l,h);
100 }
101 w2(4);
102}
103
104static void on20_write_block( PIA *pi, char * buf, int count )
105
106{ int k;
107
108 op(1); vl(1); op(0);
109
110 for (k=0;k<count;k++) { w2(5); w0(buf[k]); w2(7); }
111 w2(4);
112}
113
114static void on20_log_adapter( PIA *pi, char * scratch, int verbose )
115
116{ char *mode_string[2] = {"4-bit","8-bit"};
117
118 printk("%s: on20 %s, OnSpec 90c20 at 0x%x, ",
119 pi->device,ON20_VERSION,pi->port);
120 printk("mode %d (%s), delay %d\n",pi->mode,
121 mode_string[pi->mode],pi->delay);
122
123}
124
125static struct pi_protocol on20 = {
126 .owner = THIS_MODULE,
127 .name = "on20",
128 .max_mode = 2,
129 .epp_first = 2,
130 .default_delay = 1,
131 .max_units = 1,
132 .write_regr = on20_write_regr,
133 .read_regr = on20_read_regr,
134 .write_block = on20_write_block,
135 .read_block = on20_read_block,
136 .connect = on20_connect,
137 .disconnect = on20_disconnect,
138 .log_adapter = on20_log_adapter,
139};
140
141static int __init on20_init(void)
142{
143 return pi_register(&on20)-1;
144}
145
146static void __exit on20_exit(void)
147{
148 pi_unregister(&on20);
149}
150
151MODULE_LICENSE("GPL");
152module_init(on20_init)
153module_exit(on20_exit)
diff --git a/drivers/block/paride/on26.c b/drivers/block/paride/on26.c
new file mode 100644
index 000000000000..9f837d9a3639
--- /dev/null
+++ b/drivers/block/paride/on26.c
@@ -0,0 +1,319 @@
1/*
2 on26.c (c) 1997-8 Grant R. Guenther <grant@torque.net>
3 Under the terms of the GNU General Public License.
4
5 on26.c is a low-level protocol driver for the
6 OnSpec 90c26 parallel to IDE adapter chip.
7
8*/
9
10/* Changes:
11
12 1.01 GRG 1998.05.06 init_proto, release_proto
13 1.02 GRG 1998.09.23 updates for the -E rev chip
14 1.03 GRG 1998.12.14 fix for slave drives
15 1.04 GRG 1998.12.20 yet another bug fix
16
17*/
18
19#define ON26_VERSION "1.04"
20
21#include <linux/module.h>
22#include <linux/init.h>
23#include <linux/delay.h>
24#include <linux/kernel.h>
25#include <linux/types.h>
26#include <linux/wait.h>
27#include <asm/io.h>
28
29#include "paride.h"
30
31/* mode codes: 0 nybble reads, 8-bit writes
32 1 8-bit reads and writes
33 2 8-bit EPP mode
34 3 EPP-16
35 4 EPP-32
36*/
37
38#define j44(a,b) (((a>>4)&0x0f)|(b&0xf0))
39
40#define P1 w2(5);w2(0xd);w2(5);w2(0xd);w2(5);w2(4);
41#define P2 w2(5);w2(7);w2(5);w2(4);
42
43/* cont = 0 - access the IDE register file
44 cont = 1 - access the IDE command set
45*/
46
47static int on26_read_regr( PIA *pi, int cont, int regr )
48
49{ int a, b, r;
50
51 r = (regr<<2) + 1 + cont;
52
53 switch (pi->mode) {
54
55 case 0: w0(1); P1; w0(r); P2; w0(0); P1;
56 w2(6); a = r1(); w2(4);
57 w2(6); b = r1(); w2(4);
58 w2(6); w2(4); w2(6); w2(4);
59 return j44(a,b);
60
61 case 1: w0(1); P1; w0(r); P2; w0(0); P1;
62 w2(0x26); a = r0(); w2(4); w2(0x26); w2(4);
63 return a;
64
65 case 2:
66 case 3:
67 case 4: w3(1); w3(1); w2(5); w4(r); w2(4);
68 w3(0); w3(0); w2(0x24); a = r4(); w2(4);
69 w2(0x24); r4(); w2(4);
70 return a;
71
72 }
73 return -1;
74}
75
76static void on26_write_regr( PIA *pi, int cont, int regr, int val )
77
78{ int r;
79
80 r = (regr<<2) + 1 + cont;
81
82 switch (pi->mode) {
83
84 case 0:
85 case 1: w0(1); P1; w0(r); P2; w0(0); P1;
86 w0(val); P2; w0(val); P2;
87 break;
88
89 case 2:
90 case 3:
91 case 4: w3(1); w3(1); w2(5); w4(r); w2(4);
92 w3(0); w3(0);
93 w2(5); w4(val); w2(4);
94 w2(5); w4(val); w2(4);
95 break;
96 }
97}
98
99#define CCP(x) w0(0xfe);w0(0xaa);w0(0x55);w0(0);w0(0xff);\
100 w0(0x87);w0(0x78);w0(x);w2(4);w2(5);w2(4);w0(0xff);
101
102static void on26_connect ( PIA *pi )
103
104{ int x;
105
106 pi->saved_r0 = r0();
107 pi->saved_r2 = r2();
108
109 CCP(0x20);
110 x = 8; if (pi->mode) x = 9;
111
112 w0(2); P1; w0(8); P2;
113 w0(2); P1; w0(x); P2;
114}
115
116static void on26_disconnect ( PIA *pi )
117
118{ if (pi->mode >= 2) { w3(4); w3(4); w3(4); w3(4); }
119 else { w0(4); P1; w0(4); P1; }
120 CCP(0x30);
121 w0(pi->saved_r0);
122 w2(pi->saved_r2);
123}
124
125#define RESET_WAIT 200
126
127static int on26_test_port( PIA *pi) /* hard reset */
128
129{ int i, m, d, x=0, y=0;
130
131 pi->saved_r0 = r0();
132 pi->saved_r2 = r2();
133
134 d = pi->delay;
135 m = pi->mode;
136 pi->delay = 5;
137 pi->mode = 0;
138
139 w2(0xc);
140
141 CCP(0x30); CCP(0);
142
143 w0(0xfe);w0(0xaa);w0(0x55);w0(0);w0(0xff);
144 i = ((r1() & 0xf0) << 4); w0(0x87);
145 i |= (r1() & 0xf0); w0(0x78);
146 w0(0x20);w2(4);w2(5);
147 i |= ((r1() & 0xf0) >> 4);
148 w2(4);w0(0xff);
149
150 if (i == 0xb5f) {
151
152 w0(2); P1; w0(0); P2;
153 w0(3); P1; w0(0); P2;
154 w0(2); P1; w0(8); P2; udelay(100);
155 w0(2); P1; w0(0xa); P2; udelay(100);
156 w0(2); P1; w0(8); P2; udelay(1000);
157
158 on26_write_regr(pi,0,6,0xa0);
159
160 for (i=0;i<RESET_WAIT;i++) {
161 on26_write_regr(pi,0,6,0xa0);
162 x = on26_read_regr(pi,0,7);
163 on26_write_regr(pi,0,6,0xb0);
164 y = on26_read_regr(pi,0,7);
165 if (!((x&0x80)||(y&0x80))) break;
166 mdelay(100);
167 }
168
169 if (i == RESET_WAIT)
170 printk("on26: Device reset failed (%x,%x)\n",x,y);
171
172 w0(4); P1; w0(4); P1;
173 }
174
175 CCP(0x30);
176
177 pi->delay = d;
178 pi->mode = m;
179 w0(pi->saved_r0);
180 w2(pi->saved_r2);
181
182 return 5;
183}
184
185
186static void on26_read_block( PIA *pi, char * buf, int count )
187
188{ int k, a, b;
189
190 switch (pi->mode) {
191
192 case 0: w0(1); P1; w0(1); P2; w0(2); P1; w0(0x18); P2; w0(0); P1;
193 udelay(10);
194 for (k=0;k<count;k++) {
195 w2(6); a = r1();
196 w2(4); b = r1();
197 buf[k] = j44(a,b);
198 }
199 w0(2); P1; w0(8); P2;
200 break;
201
202 case 1: w0(1); P1; w0(1); P2; w0(2); P1; w0(0x19); P2; w0(0); P1;
203 udelay(10);
204 for (k=0;k<count/2;k++) {
205 w2(0x26); buf[2*k] = r0();
206 w2(0x24); buf[2*k+1] = r0();
207 }
208 w0(2); P1; w0(9); P2;
209 break;
210
211 case 2: w3(1); w3(1); w2(5); w4(1); w2(4);
212 w3(0); w3(0); w2(0x24);
213 udelay(10);
214 for (k=0;k<count;k++) buf[k] = r4();
215 w2(4);
216 break;
217
218 case 3: w3(1); w3(1); w2(5); w4(1); w2(4);
219 w3(0); w3(0); w2(0x24);
220 udelay(10);
221 for (k=0;k<count/2;k++) ((u16 *)buf)[k] = r4w();
222 w2(4);
223 break;
224
225 case 4: w3(1); w3(1); w2(5); w4(1); w2(4);
226 w3(0); w3(0); w2(0x24);
227 udelay(10);
228 for (k=0;k<count/4;k++) ((u32 *)buf)[k] = r4l();
229 w2(4);
230 break;
231
232 }
233}
234
235static void on26_write_block( PIA *pi, char * buf, int count )
236
237{ int k;
238
239 switch (pi->mode) {
240
241 case 0:
242 case 1: w0(1); P1; w0(1); P2;
243 w0(2); P1; w0(0x18+pi->mode); P2; w0(0); P1;
244 udelay(10);
245 for (k=0;k<count/2;k++) {
246 w2(5); w0(buf[2*k]);
247 w2(7); w0(buf[2*k+1]);
248 }
249 w2(5); w2(4);
250 w0(2); P1; w0(8+pi->mode); P2;
251 break;
252
253 case 2: w3(1); w3(1); w2(5); w4(1); w2(4);
254 w3(0); w3(0); w2(0xc5);
255 udelay(10);
256 for (k=0;k<count;k++) w4(buf[k]);
257 w2(0xc4);
258 break;
259
260 case 3: w3(1); w3(1); w2(5); w4(1); w2(4);
261 w3(0); w3(0); w2(0xc5);
262 udelay(10);
263 for (k=0;k<count/2;k++) w4w(((u16 *)buf)[k]);
264 w2(0xc4);
265 break;
266
267 case 4: w3(1); w3(1); w2(5); w4(1); w2(4);
268 w3(0); w3(0); w2(0xc5);
269 udelay(10);
270 for (k=0;k<count/4;k++) w4l(((u32 *)buf)[k]);
271 w2(0xc4);
272 break;
273
274 }
275
276}
277
278static void on26_log_adapter( PIA *pi, char * scratch, int verbose )
279
280{ char *mode_string[5] = {"4-bit","8-bit","EPP-8",
281 "EPP-16","EPP-32"};
282
283 printk("%s: on26 %s, OnSpec 90c26 at 0x%x, ",
284 pi->device,ON26_VERSION,pi->port);
285 printk("mode %d (%s), delay %d\n",pi->mode,
286 mode_string[pi->mode],pi->delay);
287
288}
289
290static struct pi_protocol on26 = {
291 .owner = THIS_MODULE,
292 .name = "on26",
293 .max_mode = 5,
294 .epp_first = 2,
295 .default_delay = 1,
296 .max_units = 1,
297 .write_regr = on26_write_regr,
298 .read_regr = on26_read_regr,
299 .write_block = on26_write_block,
300 .read_block = on26_read_block,
301 .connect = on26_connect,
302 .disconnect = on26_disconnect,
303 .test_port = on26_test_port,
304 .log_adapter = on26_log_adapter,
305};
306
307static int __init on26_init(void)
308{
309 return pi_register(&on26)-1;
310}
311
312static void __exit on26_exit(void)
313{
314 pi_unregister(&on26);
315}
316
317MODULE_LICENSE("GPL");
318module_init(on26_init)
319module_exit(on26_exit)
diff --git a/drivers/block/paride/paride.c b/drivers/block/paride/paride.c
new file mode 100644
index 000000000000..1fef136c0e41
--- /dev/null
+++ b/drivers/block/paride/paride.c
@@ -0,0 +1,467 @@
1/*
2 paride.c (c) 1997-8 Grant R. Guenther <grant@torque.net>
3 Under the terms of the GNU General Public License.
4
5 This is the base module for the family of device drivers
6 that support parallel port IDE devices.
7
8*/
9
10/* Changes:
11
12 1.01 GRG 1998.05.03 Use spinlocks
13 1.02 GRG 1998.05.05 init_proto, release_proto, ktti
14 1.03 GRG 1998.08.15 eliminate compiler warning
15 1.04 GRG 1998.11.28 added support for FRIQ
16 1.05 TMW 2000.06.06 use parport_find_number instead of
17 parport_enumerate
18 1.06 TMW 2001.03.26 more sane parport-or-not resource management
19*/
20
21#define PI_VERSION "1.06"
22
23#include <linux/module.h>
24#include <linux/config.h>
25#include <linux/kmod.h>
26#include <linux/types.h>
27#include <linux/kernel.h>
28#include <linux/ioport.h>
29#include <linux/string.h>
30#include <linux/spinlock.h>
31#include <linux/wait.h>
32
33#ifdef CONFIG_PARPORT_MODULE
34#define CONFIG_PARPORT
35#endif
36
37#ifdef CONFIG_PARPORT
38#include <linux/parport.h>
39#endif
40
41#include "paride.h"
42
43MODULE_LICENSE("GPL");
44
45#define MAX_PROTOS 32
46
47static struct pi_protocol *protocols[MAX_PROTOS];
48
49static DEFINE_SPINLOCK(pi_spinlock);
50
51void pi_write_regr(PIA * pi, int cont, int regr, int val)
52{
53 pi->proto->write_regr(pi, cont, regr, val);
54}
55
56EXPORT_SYMBOL(pi_write_regr);
57
58int pi_read_regr(PIA * pi, int cont, int regr)
59{
60 return pi->proto->read_regr(pi, cont, regr);
61}
62
63EXPORT_SYMBOL(pi_read_regr);
64
65void pi_write_block(PIA * pi, char *buf, int count)
66{
67 pi->proto->write_block(pi, buf, count);
68}
69
70EXPORT_SYMBOL(pi_write_block);
71
72void pi_read_block(PIA * pi, char *buf, int count)
73{
74 pi->proto->read_block(pi, buf, count);
75}
76
77EXPORT_SYMBOL(pi_read_block);
78
79#ifdef CONFIG_PARPORT
80
81static void pi_wake_up(void *p)
82{
83 PIA *pi = (PIA *) p;
84 unsigned long flags;
85 void (*cont) (void) = NULL;
86
87 spin_lock_irqsave(&pi_spinlock, flags);
88
89 if (pi->claim_cont && !parport_claim(pi->pardev)) {
90 cont = pi->claim_cont;
91 pi->claim_cont = NULL;
92 pi->claimed = 1;
93 }
94
95 spin_unlock_irqrestore(&pi_spinlock, flags);
96
97 wake_up(&(pi->parq));
98
99 if (cont)
100 cont();
101}
102
103#endif
104
105int pi_schedule_claimed(PIA * pi, void (*cont) (void))
106{
107#ifdef CONFIG_PARPORT
108 unsigned long flags;
109
110 spin_lock_irqsave(&pi_spinlock, flags);
111 if (pi->pardev && parport_claim(pi->pardev)) {
112 pi->claim_cont = cont;
113 spin_unlock_irqrestore(&pi_spinlock, flags);
114 return 0;
115 }
116 pi->claimed = 1;
117 spin_unlock_irqrestore(&pi_spinlock, flags);
118#endif
119 return 1;
120}
121EXPORT_SYMBOL(pi_schedule_claimed);
122
123void pi_do_claimed(PIA * pi, void (*cont) (void))
124{
125 if (pi_schedule_claimed(pi, cont))
126 cont();
127}
128
129EXPORT_SYMBOL(pi_do_claimed);
130
131static void pi_claim(PIA * pi)
132{
133 if (pi->claimed)
134 return;
135 pi->claimed = 1;
136#ifdef CONFIG_PARPORT
137 if (pi->pardev)
138 wait_event(pi->parq,
139 !parport_claim((struct pardevice *) pi->pardev));
140#endif
141}
142
143static void pi_unclaim(PIA * pi)
144{
145 pi->claimed = 0;
146#ifdef CONFIG_PARPORT
147 if (pi->pardev)
148 parport_release((struct pardevice *) (pi->pardev));
149#endif
150}
151
152void pi_connect(PIA * pi)
153{
154 pi_claim(pi);
155 pi->proto->connect(pi);
156}
157
158EXPORT_SYMBOL(pi_connect);
159
160void pi_disconnect(PIA * pi)
161{
162 pi->proto->disconnect(pi);
163 pi_unclaim(pi);
164}
165
166EXPORT_SYMBOL(pi_disconnect);
167
168static void pi_unregister_parport(PIA * pi)
169{
170#ifdef CONFIG_PARPORT
171 if (pi->pardev) {
172 parport_unregister_device((struct pardevice *) (pi->pardev));
173 pi->pardev = NULL;
174 }
175#endif
176}
177
178void pi_release(PIA * pi)
179{
180 pi_unregister_parport(pi);
181#ifndef CONFIG_PARPORT
182 if (pi->reserved)
183 release_region(pi->port, pi->reserved);
184#endif /* !CONFIG_PARPORT */
185 if (pi->proto->release_proto)
186 pi->proto->release_proto(pi);
187 module_put(pi->proto->owner);
188}
189
190EXPORT_SYMBOL(pi_release);
191
192static int default_test_proto(PIA * pi, char *scratch, int verbose)
193{
194 int j, k;
195 int e[2] = { 0, 0 };
196
197 pi->proto->connect(pi);
198
199 for (j = 0; j < 2; j++) {
200 pi_write_regr(pi, 0, 6, 0xa0 + j * 0x10);
201 for (k = 0; k < 256; k++) {
202 pi_write_regr(pi, 0, 2, k ^ 0xaa);
203 pi_write_regr(pi, 0, 3, k ^ 0x55);
204 if (pi_read_regr(pi, 0, 2) != (k ^ 0xaa))
205 e[j]++;
206 }
207 }
208 pi->proto->disconnect(pi);
209
210 if (verbose)
211 printk("%s: %s: port 0x%x, mode %d, test=(%d,%d)\n",
212 pi->device, pi->proto->name, pi->port,
213 pi->mode, e[0], e[1]);
214
215 return (e[0] && e[1]); /* not here if both > 0 */
216}
217
218static int pi_test_proto(PIA * pi, char *scratch, int verbose)
219{
220 int res;
221
222 pi_claim(pi);
223 if (pi->proto->test_proto)
224 res = pi->proto->test_proto(pi, scratch, verbose);
225 else
226 res = default_test_proto(pi, scratch, verbose);
227 pi_unclaim(pi);
228
229 return res;
230}
231
232int pi_register(PIP * pr)
233{
234 int k;
235
236 for (k = 0; k < MAX_PROTOS; k++)
237 if (protocols[k] && !strcmp(pr->name, protocols[k]->name)) {
238 printk("paride: %s protocol already registered\n",
239 pr->name);
240 return 0;
241 }
242 k = 0;
243 while ((k < MAX_PROTOS) && (protocols[k]))
244 k++;
245 if (k == MAX_PROTOS) {
246 printk("paride: protocol table full\n");
247 return 0;
248 }
249 protocols[k] = pr;
250 pr->index = k;
251 printk("paride: %s registered as protocol %d\n", pr->name, k);
252 return 1;
253}
254
255EXPORT_SYMBOL(pi_register);
256
257void pi_unregister(PIP * pr)
258{
259 if (!pr)
260 return;
261 if (protocols[pr->index] != pr) {
262 printk("paride: %s not registered\n", pr->name);
263 return;
264 }
265 protocols[pr->index] = NULL;
266}
267
268EXPORT_SYMBOL(pi_unregister);
269
270static int pi_register_parport(PIA * pi, int verbose)
271{
272#ifdef CONFIG_PARPORT
273
274 struct parport *port;
275
276 port = parport_find_base(pi->port);
277 if (!port)
278 return 0;
279
280 pi->pardev = parport_register_device(port,
281 pi->device, NULL,
282 pi_wake_up, NULL, 0, (void *) pi);
283 parport_put_port(port);
284 if (!pi->pardev)
285 return 0;
286
287 init_waitqueue_head(&pi->parq);
288
289 if (verbose)
290 printk("%s: 0x%x is %s\n", pi->device, pi->port, port->name);
291
292 pi->parname = (char *) port->name;
293#endif
294
295 return 1;
296}
297
298static int pi_probe_mode(PIA * pi, int max, char *scratch, int verbose)
299{
300 int best, range;
301
302 if (pi->mode != -1) {
303 if (pi->mode >= max)
304 return 0;
305 range = 3;
306 if (pi->mode >= pi->proto->epp_first)
307 range = 8;
308 if ((range == 8) && (pi->port % 8))
309 return 0;
310 pi->reserved = range;
311 return (!pi_test_proto(pi, scratch, verbose));
312 }
313 best = -1;
314 for (pi->mode = 0; pi->mode < max; pi->mode++) {
315 range = 3;
316 if (pi->mode >= pi->proto->epp_first)
317 range = 8;
318 if ((range == 8) && (pi->port % 8))
319 break;
320 pi->reserved = range;
321 if (!pi_test_proto(pi, scratch, verbose))
322 best = pi->mode;
323 }
324 pi->mode = best;
325 return (best > -1);
326}
327
328static int pi_probe_unit(PIA * pi, int unit, char *scratch, int verbose)
329{
330 int max, s, e;
331
332 s = unit;
333 e = s + 1;
334
335 if (s == -1) {
336 s = 0;
337 e = pi->proto->max_units;
338 }
339
340 if (!pi_register_parport(pi, verbose))
341 return 0;
342
343 if (pi->proto->test_port) {
344 pi_claim(pi);
345 max = pi->proto->test_port(pi);
346 pi_unclaim(pi);
347 } else
348 max = pi->proto->max_mode;
349
350 if (pi->proto->probe_unit) {
351 pi_claim(pi);
352 for (pi->unit = s; pi->unit < e; pi->unit++)
353 if (pi->proto->probe_unit(pi)) {
354 pi_unclaim(pi);
355 if (pi_probe_mode(pi, max, scratch, verbose))
356 return 1;
357 pi_unregister_parport(pi);
358 return 0;
359 }
360 pi_unclaim(pi);
361 pi_unregister_parport(pi);
362 return 0;
363 }
364
365 if (!pi_probe_mode(pi, max, scratch, verbose)) {
366 pi_unregister_parport(pi);
367 return 0;
368 }
369 return 1;
370
371}
372
373int pi_init(PIA * pi, int autoprobe, int port, int mode,
374 int unit, int protocol, int delay, char *scratch,
375 int devtype, int verbose, char *device)
376{
377 int p, k, s, e;
378 int lpts[7] = { 0x3bc, 0x378, 0x278, 0x268, 0x27c, 0x26c, 0 };
379
380 s = protocol;
381 e = s + 1;
382
383 if (!protocols[0])
384 request_module("paride_protocol");
385
386 if (autoprobe) {
387 s = 0;
388 e = MAX_PROTOS;
389 } else if ((s < 0) || (s >= MAX_PROTOS) || (port <= 0) ||
390 (!protocols[s]) || (unit < 0) ||
391 (unit >= protocols[s]->max_units)) {
392 printk("%s: Invalid parameters\n", device);
393 return 0;
394 }
395
396 for (p = s; p < e; p++) {
397 struct pi_protocol *proto = protocols[p];
398 if (!proto)
399 continue;
400 /* still racy */
401 if (!try_module_get(proto->owner))
402 continue;
403 pi->proto = proto;
404 pi->private = 0;
405 if (proto->init_proto && proto->init_proto(pi) < 0) {
406 pi->proto = NULL;
407 module_put(proto->owner);
408 continue;
409 }
410 if (delay == -1)
411 pi->delay = pi->proto->default_delay;
412 else
413 pi->delay = delay;
414 pi->devtype = devtype;
415 pi->device = device;
416
417 pi->parname = NULL;
418 pi->pardev = NULL;
419 init_waitqueue_head(&pi->parq);
420 pi->claimed = 0;
421 pi->claim_cont = NULL;
422
423 pi->mode = mode;
424 if (port != -1) {
425 pi->port = port;
426 if (pi_probe_unit(pi, unit, scratch, verbose))
427 break;
428 pi->port = 0;
429 } else {
430 k = 0;
431 while ((pi->port = lpts[k++]))
432 if (pi_probe_unit
433 (pi, unit, scratch, verbose))
434 break;
435 if (pi->port)
436 break;
437 }
438 if (pi->proto->release_proto)
439 pi->proto->release_proto(pi);
440 module_put(proto->owner);
441 }
442
443 if (!pi->port) {
444 if (autoprobe)
445 printk("%s: Autoprobe failed\n", device);
446 else
447 printk("%s: Adapter not found\n", device);
448 return 0;
449 }
450#ifndef CONFIG_PARPORT
451 if (!request_region(pi->port, pi->reserved, pi->device)) {
452 printk(KERN_WARNING "paride: Unable to request region 0x%x\n",
453 pi->port);
454 return 0;
455 }
456#endif /* !CONFIG_PARPORT */
457
458 if (pi->parname)
459 printk("%s: Sharing %s at 0x%x\n", pi->device,
460 pi->parname, pi->port);
461
462 pi->proto->log_adapter(pi, scratch, verbose);
463
464 return 1;
465}
466
467EXPORT_SYMBOL(pi_init);
diff --git a/drivers/block/paride/paride.h b/drivers/block/paride/paride.h
new file mode 100644
index 000000000000..c6d98ef09e48
--- /dev/null
+++ b/drivers/block/paride/paride.h
@@ -0,0 +1,170 @@
1#ifndef __DRIVERS_PARIDE_H__
2#define __DRIVERS_PARIDE_H__
3
4/*
5 paride.h (c) 1997-8 Grant R. Guenther <grant@torque.net>
6 Under the terms of the GPL.
7
8 This file defines the interface between the high-level parallel
9 IDE device drivers (pd, pf, pcd, pt) and the adapter chips.
10
11*/
12
13/* Changes:
14
15 1.01 GRG 1998.05.05 init_proto, release_proto
16*/
17
18#define PARIDE_H_VERSION "1.01"
19
20/* Some adapters need to know what kind of device they are in
21
22 Values for devtype:
23*/
24
25#define PI_PD 0 /* IDE disk */
26#define PI_PCD 1 /* ATAPI CDrom */
27#define PI_PF 2 /* ATAPI disk */
28#define PI_PT 3 /* ATAPI tape */
29#define PI_PG 4 /* ATAPI generic */
30
31/* The paride module contains no state, instead the drivers allocate
32 a pi_adapter data structure and pass it to paride in every operation.
33
34*/
35
36struct pi_adapter {
37
38 struct pi_protocol *proto; /* adapter protocol */
39 int port; /* base address of parallel port */
40 int mode; /* transfer mode in use */
41 int delay; /* adapter delay setting */
42 int devtype; /* device type: PI_PD etc. */
43 char *device; /* name of driver */
44 int unit; /* unit number for chained adapters */
45 int saved_r0; /* saved port state */
46 int saved_r2; /* saved port state */
47 int reserved; /* number of ports reserved */
48 unsigned long private; /* for protocol module */
49
50 wait_queue_head_t parq; /* semaphore for parport sharing */
51 void *pardev; /* pointer to pardevice */
52 char *parname; /* parport name */
53 int claimed; /* parport has already been claimed */
54 void (*claim_cont)(void); /* continuation for parport wait */
55};
56
57typedef struct pi_adapter PIA;
58
59/* functions exported by paride to the high level drivers */
60
61extern int pi_init(PIA *pi,
62 int autoprobe, /* 1 to autoprobe */
63 int port, /* base port address */
64 int mode, /* -1 for autoprobe */
65 int unit, /* unit number, if supported */
66 int protocol, /* protocol to use */
67 int delay, /* -1 to use adapter specific default */
68 char * scratch, /* address of 512 byte buffer */
69 int devtype, /* device type: PI_PD, PI_PCD, etc ... */
70 int verbose, /* log verbose data while probing */
71 char *device /* name of the driver */
72 ); /* returns 0 on failure, 1 on success */
73
74extern void pi_release(PIA *pi);
75
76/* registers are addressed as (cont,regr)
77
78 cont: 0 for command register file, 1 for control register(s)
79 regr: 0-7 for register number.
80
81*/
82
83extern void pi_write_regr(PIA *pi, int cont, int regr, int val);
84
85extern int pi_read_regr(PIA *pi, int cont, int regr);
86
87extern void pi_write_block(PIA *pi, char * buf, int count);
88
89extern void pi_read_block(PIA *pi, char * buf, int count);
90
91extern void pi_connect(PIA *pi);
92
93extern void pi_disconnect(PIA *pi);
94
95extern void pi_do_claimed(PIA *pi, void (*cont)(void));
96extern int pi_schedule_claimed(PIA *pi, void (*cont)(void));
97
98/* macros and functions exported to the protocol modules */
99
100#define delay_p (pi->delay?udelay(pi->delay):(void)0)
101#define out_p(offs,byte) outb(byte,pi->port+offs); delay_p;
102#define in_p(offs) (delay_p,inb(pi->port+offs))
103
104#define w0(byte) {out_p(0,byte);}
105#define r0() (in_p(0) & 0xff)
106#define w1(byte) {out_p(1,byte);}
107#define r1() (in_p(1) & 0xff)
108#define w2(byte) {out_p(2,byte);}
109#define r2() (in_p(2) & 0xff)
110#define w3(byte) {out_p(3,byte);}
111#define w4(byte) {out_p(4,byte);}
112#define r4() (in_p(4) & 0xff)
113#define w4w(data) {outw(data,pi->port+4); delay_p;}
114#define w4l(data) {outl(data,pi->port+4); delay_p;}
115#define r4w() (delay_p,inw(pi->port+4)&0xffff)
116#define r4l() (delay_p,inl(pi->port+4)&0xffffffff)
117
118static inline u16 pi_swab16( char *b, int k)
119
120{ union { u16 u; char t[2]; } r;
121
122 r.t[0]=b[2*k+1]; r.t[1]=b[2*k];
123 return r.u;
124}
125
126static inline u32 pi_swab32( char *b, int k)
127
128{ union { u32 u; char f[4]; } r;
129
130 r.f[0]=b[4*k+1]; r.f[1]=b[4*k];
131 r.f[2]=b[4*k+3]; r.f[3]=b[4*k+2];
132 return r.u;
133}
134
135struct pi_protocol {
136
137 char name[8]; /* name for this protocol */
138 int index; /* index into protocol table */
139
140 int max_mode; /* max mode number */
141 int epp_first; /* modes >= this use 8 ports */
142
143 int default_delay; /* delay parameter if not specified */
144 int max_units; /* max chained units probed for */
145
146 void (*write_regr)(PIA *,int,int,int);
147 int (*read_regr)(PIA *,int,int);
148 void (*write_block)(PIA *,char *,int);
149 void (*read_block)(PIA *,char *,int);
150
151 void (*connect)(PIA *);
152 void (*disconnect)(PIA *);
153
154 int (*test_port)(PIA *);
155 int (*probe_unit)(PIA *);
156 int (*test_proto)(PIA *,char *,int);
157 void (*log_adapter)(PIA *,char *,int);
158
159 int (*init_proto)(PIA *);
160 void (*release_proto)(PIA *);
161 struct module *owner;
162};
163
164typedef struct pi_protocol PIP;
165
166extern int pi_register( PIP * );
167extern void pi_unregister ( PIP * );
168
169#endif /* __DRIVERS_PARIDE_H__ */
170/* end of paride.h */
diff --git a/drivers/block/paride/pcd.c b/drivers/block/paride/pcd.c
new file mode 100644
index 000000000000..7289f67e9568
--- /dev/null
+++ b/drivers/block/paride/pcd.c
@@ -0,0 +1,971 @@
1/*
2 pcd.c (c) 1997-8 Grant R. Guenther <grant@torque.net>
3 Under the terms of the GNU General Public License.
4
5 This is a high-level driver for parallel port ATAPI CD-ROM
6 drives based on chips supported by the paride module.
7
8 By default, the driver will autoprobe for a single parallel
9 port ATAPI CD-ROM drive, but if their individual parameters are
10 specified, the driver can handle up to 4 drives.
11
12 The behaviour of the pcd driver can be altered by setting
13 some parameters from the insmod command line. The following
14 parameters are adjustable:
15
16 drive0 These four arguments can be arrays of
17 drive1 1-6 integers as follows:
18 drive2
19 drive3 <prt>,<pro>,<uni>,<mod>,<slv>,<dly>
20
21 Where,
22
23 <prt> is the base of the parallel port address for
24 the corresponding drive. (required)
25
26 <pro> is the protocol number for the adapter that
27 supports this drive. These numbers are
28 logged by 'paride' when the protocol modules
29 are initialised. (0 if not given)
30
31 <uni> for those adapters that support chained
32 devices, this is the unit selector for the
33 chain of devices on the given port. It should
34 be zero for devices that don't support chaining.
35 (0 if not given)
36
37 <mod> this can be -1 to choose the best mode, or one
38 of the mode numbers supported by the adapter.
39 (-1 if not given)
40
41 <slv> ATAPI CD-ROMs can be jumpered to master or slave.
42 Set this to 0 to choose the master drive, 1 to
43 choose the slave, -1 (the default) to choose the
44 first drive found.
45
46 <dly> some parallel ports require the driver to
47 go more slowly. -1 sets a default value that
48 should work with the chosen protocol. Otherwise,
49 set this to a small integer, the larger it is
50 the slower the port i/o. In some cases, setting
51 this to zero will speed up the device. (default -1)
52
53 major You may use this parameter to overide the
54 default major number (46) that this driver
55 will use. Be sure to change the device
56 name as well.
57
58 name This parameter is a character string that
59 contains the name the kernel will use for this
60 device (in /proc output, for instance).
61 (default "pcd")
62
63 verbose This parameter controls the amount of logging
64 that the driver will do. Set it to 0 for
65 normal operation, 1 to see autoprobe progress
66 messages, or 2 to see additional debugging
67 output. (default 0)
68
69 nice This parameter controls the driver's use of
70 idle CPU time, at the expense of some speed.
71
72 If this driver is built into the kernel, you can use kernel
73 the following command line parameters, with the same values
74 as the corresponding module parameters listed above:
75
76 pcd.drive0
77 pcd.drive1
78 pcd.drive2
79 pcd.drive3
80 pcd.nice
81
82 In addition, you can use the parameter pcd.disable to disable
83 the driver entirely.
84
85*/
86
87/* Changes:
88
89 1.01 GRG 1998.01.24 Added test unit ready support
90 1.02 GRG 1998.05.06 Changes to pcd_completion, ready_wait,
91 and loosen interpretation of ATAPI
92 standard for clearing error status.
93 Use spinlocks. Eliminate sti().
94 1.03 GRG 1998.06.16 Eliminated an Ugh
95 1.04 GRG 1998.08.15 Added extra debugging, improvements to
96 pcd_completion, use HZ in loop timing
97 1.05 GRG 1998.08.16 Conformed to "Uniform CD-ROM" standard
98 1.06 GRG 1998.08.19 Added audio ioctl support
99 1.07 GRG 1998.09.24 Increased reset timeout, added jumbo support
100
101*/
102
103#define PCD_VERSION "1.07"
104#define PCD_MAJOR 46
105#define PCD_NAME "pcd"
106#define PCD_UNITS 4
107
108/* Here are things one can override from the insmod command.
109 Most are autoprobed by paride unless set here. Verbose is off
110 by default.
111
112*/
113
114static int verbose = 0;
115static int major = PCD_MAJOR;
116static char *name = PCD_NAME;
117static int nice = 0;
118static int disable = 0;
119
120static int drive0[6] = { 0, 0, 0, -1, -1, -1 };
121static int drive1[6] = { 0, 0, 0, -1, -1, -1 };
122static int drive2[6] = { 0, 0, 0, -1, -1, -1 };
123static int drive3[6] = { 0, 0, 0, -1, -1, -1 };
124
125static int (*drives[4])[6] = {&drive0, &drive1, &drive2, &drive3};
126static int pcd_drive_count;
127
128enum {D_PRT, D_PRO, D_UNI, D_MOD, D_SLV, D_DLY};
129
130/* end of parameters */
131
132#include <linux/module.h>
133#include <linux/init.h>
134#include <linux/errno.h>
135#include <linux/fs.h>
136#include <linux/kernel.h>
137#include <linux/delay.h>
138#include <linux/cdrom.h>
139#include <linux/spinlock.h>
140#include <linux/blkdev.h>
141#include <asm/uaccess.h>
142
143static spinlock_t pcd_lock;
144
145module_param(verbose, bool, 0644);
146module_param(major, int, 0);
147module_param(name, charp, 0);
148module_param(nice, int, 0);
149module_param_array(drive0, int, NULL, 0);
150module_param_array(drive1, int, NULL, 0);
151module_param_array(drive2, int, NULL, 0);
152module_param_array(drive3, int, NULL, 0);
153
154#include "paride.h"
155#include "pseudo.h"
156
157#define PCD_RETRIES 5
158#define PCD_TMO 800 /* timeout in jiffies */
159#define PCD_DELAY 50 /* spin delay in uS */
160#define PCD_READY_TMO 20 /* in seconds */
161#define PCD_RESET_TMO 100 /* in tenths of a second */
162
163#define PCD_SPIN (1000000*PCD_TMO)/(HZ*PCD_DELAY)
164
165#define IDE_ERR 0x01
166#define IDE_DRQ 0x08
167#define IDE_READY 0x40
168#define IDE_BUSY 0x80
169
170static int pcd_open(struct cdrom_device_info *cdi, int purpose);
171static void pcd_release(struct cdrom_device_info *cdi);
172static int pcd_drive_status(struct cdrom_device_info *cdi, int slot_nr);
173static int pcd_media_changed(struct cdrom_device_info *cdi, int slot_nr);
174static int pcd_tray_move(struct cdrom_device_info *cdi, int position);
175static int pcd_lock_door(struct cdrom_device_info *cdi, int lock);
176static int pcd_drive_reset(struct cdrom_device_info *cdi);
177static int pcd_get_mcn(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn);
178static int pcd_audio_ioctl(struct cdrom_device_info *cdi,
179 unsigned int cmd, void *arg);
180static int pcd_packet(struct cdrom_device_info *cdi,
181 struct packet_command *cgc);
182
183static int pcd_detect(void);
184static void pcd_probe_capabilities(void);
185static void do_pcd_read_drq(void);
186static void do_pcd_request(request_queue_t * q);
187static void do_pcd_read(void);
188
189struct pcd_unit {
190 struct pi_adapter pia; /* interface to paride layer */
191 struct pi_adapter *pi;
192 int drive; /* master/slave */
193 int last_sense; /* result of last request sense */
194 int changed; /* media change seen */
195 int present; /* does this unit exist ? */
196 char *name; /* pcd0, pcd1, etc */
197 struct cdrom_device_info info; /* uniform cdrom interface */
198 struct gendisk *disk;
199};
200
201static struct pcd_unit pcd[PCD_UNITS];
202
203static char pcd_scratch[64];
204static char pcd_buffer[2048]; /* raw block buffer */
205static int pcd_bufblk = -1; /* block in buffer, in CD units,
206 -1 for nothing there. See also
207 pd_unit.
208 */
209
210/* the variables below are used mainly in the I/O request engine, which
211 processes only one request at a time.
212*/
213
214static struct pcd_unit *pcd_current; /* current request's drive */
215static struct request *pcd_req;
216static int pcd_retries; /* retries on current request */
217static int pcd_busy; /* request being processed ? */
218static int pcd_sector; /* address of next requested sector */
219static int pcd_count; /* number of blocks still to do */
220static char *pcd_buf; /* buffer for request in progress */
221
222static int pcd_warned; /* Have we logged a phase warning ? */
223
224/* kernel glue structures */
225
226static int pcd_block_open(struct inode *inode, struct file *file)
227{
228 struct pcd_unit *cd = inode->i_bdev->bd_disk->private_data;
229 return cdrom_open(&cd->info, inode, file);
230}
231
232static int pcd_block_release(struct inode *inode, struct file *file)
233{
234 struct pcd_unit *cd = inode->i_bdev->bd_disk->private_data;
235 return cdrom_release(&cd->info, file);
236}
237
238static int pcd_block_ioctl(struct inode *inode, struct file *file,
239 unsigned cmd, unsigned long arg)
240{
241 struct pcd_unit *cd = inode->i_bdev->bd_disk->private_data;
242 return cdrom_ioctl(file, &cd->info, inode, cmd, arg);
243}
244
245static int pcd_block_media_changed(struct gendisk *disk)
246{
247 struct pcd_unit *cd = disk->private_data;
248 return cdrom_media_changed(&cd->info);
249}
250
251static struct block_device_operations pcd_bdops = {
252 .owner = THIS_MODULE,
253 .open = pcd_block_open,
254 .release = pcd_block_release,
255 .ioctl = pcd_block_ioctl,
256 .media_changed = pcd_block_media_changed,
257};
258
259static struct cdrom_device_ops pcd_dops = {
260 .open = pcd_open,
261 .release = pcd_release,
262 .drive_status = pcd_drive_status,
263 .media_changed = pcd_media_changed,
264 .tray_move = pcd_tray_move,
265 .lock_door = pcd_lock_door,
266 .get_mcn = pcd_get_mcn,
267 .reset = pcd_drive_reset,
268 .audio_ioctl = pcd_audio_ioctl,
269 .generic_packet = pcd_packet,
270 .capability = CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK |
271 CDC_MCN | CDC_MEDIA_CHANGED | CDC_RESET |
272 CDC_PLAY_AUDIO | CDC_GENERIC_PACKET | CDC_CD_R |
273 CDC_CD_RW,
274};
275
276static void pcd_init_units(void)
277{
278 struct pcd_unit *cd;
279 int unit;
280
281 pcd_drive_count = 0;
282 for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) {
283 struct gendisk *disk = alloc_disk(1);
284 if (!disk)
285 continue;
286 cd->disk = disk;
287 cd->pi = &cd->pia;
288 cd->present = 0;
289 cd->last_sense = 0;
290 cd->changed = 1;
291 cd->drive = (*drives[unit])[D_SLV];
292 if ((*drives[unit])[D_PRT])
293 pcd_drive_count++;
294
295 cd->name = &cd->info.name[0];
296 snprintf(cd->name, sizeof(cd->info.name), "%s%d", name, unit);
297 cd->info.ops = &pcd_dops;
298 cd->info.handle = cd;
299 cd->info.speed = 0;
300 cd->info.capacity = 1;
301 cd->info.mask = 0;
302 disk->major = major;
303 disk->first_minor = unit;
304 strcpy(disk->disk_name, cd->name); /* umm... */
305 disk->fops = &pcd_bdops;
306 }
307}
308
309static int pcd_open(struct cdrom_device_info *cdi, int purpose)
310{
311 struct pcd_unit *cd = cdi->handle;
312 if (!cd->present)
313 return -ENODEV;
314 return 0;
315}
316
317static void pcd_release(struct cdrom_device_info *cdi)
318{
319}
320
321static inline int status_reg(struct pcd_unit *cd)
322{
323 return pi_read_regr(cd->pi, 1, 6);
324}
325
326static inline int read_reg(struct pcd_unit *cd, int reg)
327{
328 return pi_read_regr(cd->pi, 0, reg);
329}
330
331static inline void write_reg(struct pcd_unit *cd, int reg, int val)
332{
333 pi_write_regr(cd->pi, 0, reg, val);
334}
335
336static int pcd_wait(struct pcd_unit *cd, int go, int stop, char *fun, char *msg)
337{
338 int j, r, e, s, p;
339
340 j = 0;
341 while ((((r = status_reg(cd)) & go) || (stop && (!(r & stop))))
342 && (j++ < PCD_SPIN))
343 udelay(PCD_DELAY);
344
345 if ((r & (IDE_ERR & stop)) || (j >= PCD_SPIN)) {
346 s = read_reg(cd, 7);
347 e = read_reg(cd, 1);
348 p = read_reg(cd, 2);
349 if (j >= PCD_SPIN)
350 e |= 0x100;
351 if (fun)
352 printk("%s: %s %s: alt=0x%x stat=0x%x err=0x%x"
353 " loop=%d phase=%d\n",
354 cd->name, fun, msg, r, s, e, j, p);
355 return (s << 8) + r;
356 }
357 return 0;
358}
359
360static int pcd_command(struct pcd_unit *cd, char *cmd, int dlen, char *fun)
361{
362 pi_connect(cd->pi);
363
364 write_reg(cd, 6, 0xa0 + 0x10 * cd->drive);
365
366 if (pcd_wait(cd, IDE_BUSY | IDE_DRQ, 0, fun, "before command")) {
367 pi_disconnect(cd->pi);
368 return -1;
369 }
370
371 write_reg(cd, 4, dlen % 256);
372 write_reg(cd, 5, dlen / 256);
373 write_reg(cd, 7, 0xa0); /* ATAPI packet command */
374
375 if (pcd_wait(cd, IDE_BUSY, IDE_DRQ, fun, "command DRQ")) {
376 pi_disconnect(cd->pi);
377 return -1;
378 }
379
380 if (read_reg(cd, 2) != 1) {
381 printk("%s: %s: command phase error\n", cd->name, fun);
382 pi_disconnect(cd->pi);
383 return -1;
384 }
385
386 pi_write_block(cd->pi, cmd, 12);
387
388 return 0;
389}
390
391static int pcd_completion(struct pcd_unit *cd, char *buf, char *fun)
392{
393 int r, d, p, n, k, j;
394
395 r = -1;
396 k = 0;
397 j = 0;
398
399 if (!pcd_wait(cd, IDE_BUSY, IDE_DRQ | IDE_READY | IDE_ERR,
400 fun, "completion")) {
401 r = 0;
402 while (read_reg(cd, 7) & IDE_DRQ) {
403 d = read_reg(cd, 4) + 256 * read_reg(cd, 5);
404 n = (d + 3) & 0xfffc;
405 p = read_reg(cd, 2) & 3;
406
407 if ((p == 2) && (n > 0) && (j == 0)) {
408 pi_read_block(cd->pi, buf, n);
409 if (verbose > 1)
410 printk("%s: %s: Read %d bytes\n",
411 cd->name, fun, n);
412 r = 0;
413 j++;
414 } else {
415 if (verbose > 1)
416 printk
417 ("%s: %s: Unexpected phase %d, d=%d, k=%d\n",
418 cd->name, fun, p, d, k);
419 if ((verbose < 2) && !pcd_warned) {
420 pcd_warned = 1;
421 printk
422 ("%s: WARNING: ATAPI phase errors\n",
423 cd->name);
424 }
425 mdelay(1);
426 }
427 if (k++ > PCD_TMO) {
428 printk("%s: Stuck DRQ\n", cd->name);
429 break;
430 }
431 if (pcd_wait
432 (cd, IDE_BUSY, IDE_DRQ | IDE_READY | IDE_ERR, fun,
433 "completion")) {
434 r = -1;
435 break;
436 }
437 }
438 }
439
440 pi_disconnect(cd->pi);
441
442 return r;
443}
444
445static void pcd_req_sense(struct pcd_unit *cd, char *fun)
446{
447 char rs_cmd[12] = { 0x03, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0 };
448 char buf[16];
449 int r, c;
450
451 r = pcd_command(cd, rs_cmd, 16, "Request sense");
452 mdelay(1);
453 if (!r)
454 pcd_completion(cd, buf, "Request sense");
455
456 cd->last_sense = -1;
457 c = 2;
458 if (!r) {
459 if (fun)
460 printk("%s: %s: Sense key: %x, ASC: %x, ASQ: %x\n",
461 cd->name, fun, buf[2] & 0xf, buf[12], buf[13]);
462 c = buf[2] & 0xf;
463 cd->last_sense =
464 c | ((buf[12] & 0xff) << 8) | ((buf[13] & 0xff) << 16);
465 }
466 if ((c == 2) || (c == 6))
467 cd->changed = 1;
468}
469
470static int pcd_atapi(struct pcd_unit *cd, char *cmd, int dlen, char *buf, char *fun)
471{
472 int r;
473
474 r = pcd_command(cd, cmd, dlen, fun);
475 mdelay(1);
476 if (!r)
477 r = pcd_completion(cd, buf, fun);
478 if (r)
479 pcd_req_sense(cd, fun);
480
481 return r;
482}
483
484static int pcd_packet(struct cdrom_device_info *cdi, struct packet_command *cgc)
485{
486 return pcd_atapi(cdi->handle, cgc->cmd, cgc->buflen, cgc->buffer,
487 "generic packet");
488}
489
490#define DBMSG(msg) ((verbose>1)?(msg):NULL)
491
492static int pcd_media_changed(struct cdrom_device_info *cdi, int slot_nr)
493{
494 struct pcd_unit *cd = cdi->handle;
495 int res = cd->changed;
496 if (res)
497 cd->changed = 0;
498 return res;
499}
500
501static int pcd_lock_door(struct cdrom_device_info *cdi, int lock)
502{
503 char un_cmd[12] = { 0x1e, 0, 0, 0, lock, 0, 0, 0, 0, 0, 0, 0 };
504
505 return pcd_atapi(cdi->handle, un_cmd, 0, pcd_scratch,
506 lock ? "lock door" : "unlock door");
507}
508
509static int pcd_tray_move(struct cdrom_device_info *cdi, int position)
510{
511 char ej_cmd[12] = { 0x1b, 0, 0, 0, 3 - position, 0, 0, 0, 0, 0, 0, 0 };
512
513 return pcd_atapi(cdi->handle, ej_cmd, 0, pcd_scratch,
514 position ? "eject" : "close tray");
515}
516
517static void pcd_sleep(int cs)
518{
519 current->state = TASK_INTERRUPTIBLE;
520 schedule_timeout(cs);
521}
522
523static int pcd_reset(struct pcd_unit *cd)
524{
525 int i, k, flg;
526 int expect[5] = { 1, 1, 1, 0x14, 0xeb };
527
528 pi_connect(cd->pi);
529 write_reg(cd, 6, 0xa0 + 0x10 * cd->drive);
530 write_reg(cd, 7, 8);
531
532 pcd_sleep(20 * HZ / 1000); /* delay a bit */
533
534 k = 0;
535 while ((k++ < PCD_RESET_TMO) && (status_reg(cd) & IDE_BUSY))
536 pcd_sleep(HZ / 10);
537
538 flg = 1;
539 for (i = 0; i < 5; i++)
540 flg &= (read_reg(cd, i + 1) == expect[i]);
541
542 if (verbose) {
543 printk("%s: Reset (%d) signature = ", cd->name, k);
544 for (i = 0; i < 5; i++)
545 printk("%3x", read_reg(cd, i + 1));
546 if (!flg)
547 printk(" (incorrect)");
548 printk("\n");
549 }
550
551 pi_disconnect(cd->pi);
552 return flg - 1;
553}
554
555static int pcd_drive_reset(struct cdrom_device_info *cdi)
556{
557 return pcd_reset(cdi->handle);
558}
559
560static int pcd_ready_wait(struct pcd_unit *cd, int tmo)
561{
562 char tr_cmd[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
563 int k, p;
564
565 k = 0;
566 while (k < tmo) {
567 cd->last_sense = 0;
568 pcd_atapi(cd, tr_cmd, 0, NULL, DBMSG("test unit ready"));
569 p = cd->last_sense;
570 if (!p)
571 return 0;
572 if (!(((p & 0xffff) == 0x0402) || ((p & 0xff) == 6)))
573 return p;
574 k++;
575 pcd_sleep(HZ);
576 }
577 return 0x000020; /* timeout */
578}
579
580static int pcd_drive_status(struct cdrom_device_info *cdi, int slot_nr)
581{
582 char rc_cmd[12] = { 0x25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
583 struct pcd_unit *cd = cdi->handle;
584
585 if (pcd_ready_wait(cd, PCD_READY_TMO))
586 return CDS_DRIVE_NOT_READY;
587 if (pcd_atapi(cd, rc_cmd, 8, pcd_scratch, DBMSG("check media")))
588 return CDS_NO_DISC;
589 return CDS_DISC_OK;
590}
591
592static int pcd_identify(struct pcd_unit *cd, char *id)
593{
594 int k, s;
595 char id_cmd[12] = { 0x12, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0 };
596
597 pcd_bufblk = -1;
598
599 s = pcd_atapi(cd, id_cmd, 36, pcd_buffer, "identify");
600
601 if (s)
602 return -1;
603 if ((pcd_buffer[0] & 0x1f) != 5) {
604 if (verbose)
605 printk("%s: %s is not a CD-ROM\n",
606 cd->name, cd->drive ? "Slave" : "Master");
607 return -1;
608 }
609 memcpy(id, pcd_buffer + 16, 16);
610 id[16] = 0;
611 k = 16;
612 while ((k >= 0) && (id[k] <= 0x20)) {
613 id[k] = 0;
614 k--;
615 }
616
617 printk("%s: %s: %s\n", cd->name, cd->drive ? "Slave" : "Master", id);
618
619 return 0;
620}
621
622/*
623 * returns 0, with id set if drive is detected
624 * -1, if drive detection failed
625 */
626static int pcd_probe(struct pcd_unit *cd, int ms, char *id)
627{
628 if (ms == -1) {
629 for (cd->drive = 0; cd->drive <= 1; cd->drive++)
630 if (!pcd_reset(cd) && !pcd_identify(cd, id))
631 return 0;
632 } else {
633 cd->drive = ms;
634 if (!pcd_reset(cd) && !pcd_identify(cd, id))
635 return 0;
636 }
637 return -1;
638}
639
640static void pcd_probe_capabilities(void)
641{
642 int unit, r;
643 char buffer[32];
644 char cmd[12] = { 0x5a, 1 << 3, 0x2a, 0, 0, 0, 0, 18, 0, 0, 0, 0 };
645 struct pcd_unit *cd;
646
647 for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) {
648 if (!cd->present)
649 continue;
650 r = pcd_atapi(cd, cmd, 18, buffer, "mode sense capabilities");
651 if (r)
652 continue;
653 /* we should now have the cap page */
654 if ((buffer[11] & 1) == 0)
655 cd->info.mask |= CDC_CD_R;
656 if ((buffer[11] & 2) == 0)
657 cd->info.mask |= CDC_CD_RW;
658 if ((buffer[12] & 1) == 0)
659 cd->info.mask |= CDC_PLAY_AUDIO;
660 if ((buffer[14] & 1) == 0)
661 cd->info.mask |= CDC_LOCK;
662 if ((buffer[14] & 8) == 0)
663 cd->info.mask |= CDC_OPEN_TRAY;
664 if ((buffer[14] >> 6) == 0)
665 cd->info.mask |= CDC_CLOSE_TRAY;
666 }
667}
668
669static int pcd_detect(void)
670{
671 char id[18];
672 int k, unit;
673 struct pcd_unit *cd;
674
675 printk("%s: %s version %s, major %d, nice %d\n",
676 name, name, PCD_VERSION, major, nice);
677
678 k = 0;
679 if (pcd_drive_count == 0) { /* nothing spec'd - so autoprobe for 1 */
680 cd = pcd;
681 if (pi_init(cd->pi, 1, -1, -1, -1, -1, -1, pcd_buffer,
682 PI_PCD, verbose, cd->name)) {
683 if (!pcd_probe(cd, -1, id) && cd->disk) {
684 cd->present = 1;
685 k++;
686 } else
687 pi_release(cd->pi);
688 }
689 } else {
690 for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) {
691 int *conf = *drives[unit];
692 if (!conf[D_PRT])
693 continue;
694 if (!pi_init(cd->pi, 0, conf[D_PRT], conf[D_MOD],
695 conf[D_UNI], conf[D_PRO], conf[D_DLY],
696 pcd_buffer, PI_PCD, verbose, cd->name))
697 continue;
698 if (!pcd_probe(cd, conf[D_SLV], id) && cd->disk) {
699 cd->present = 1;
700 k++;
701 } else
702 pi_release(cd->pi);
703 }
704 }
705 if (k)
706 return 0;
707
708 printk("%s: No CD-ROM drive found\n", name);
709 for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++)
710 put_disk(cd->disk);
711 return -1;
712}
713
714/* I/O request processing */
715static struct request_queue *pcd_queue;
716
717static void do_pcd_request(request_queue_t * q)
718{
719 if (pcd_busy)
720 return;
721 while (1) {
722 pcd_req = elv_next_request(q);
723 if (!pcd_req)
724 return;
725
726 if (rq_data_dir(pcd_req) == READ) {
727 struct pcd_unit *cd = pcd_req->rq_disk->private_data;
728 if (cd != pcd_current)
729 pcd_bufblk = -1;
730 pcd_current = cd;
731 pcd_sector = pcd_req->sector;
732 pcd_count = pcd_req->current_nr_sectors;
733 pcd_buf = pcd_req->buffer;
734 pcd_busy = 1;
735 ps_set_intr(do_pcd_read, NULL, 0, nice);
736 return;
737 } else
738 end_request(pcd_req, 0);
739 }
740}
741
742static inline void next_request(int success)
743{
744 unsigned long saved_flags;
745
746 spin_lock_irqsave(&pcd_lock, saved_flags);
747 end_request(pcd_req, success);
748 pcd_busy = 0;
749 do_pcd_request(pcd_queue);
750 spin_unlock_irqrestore(&pcd_lock, saved_flags);
751}
752
753static int pcd_ready(void)
754{
755 return (((status_reg(pcd_current) & (IDE_BUSY | IDE_DRQ)) == IDE_DRQ));
756}
757
758static void pcd_transfer(void)
759{
760
761 while (pcd_count && (pcd_sector / 4 == pcd_bufblk)) {
762 int o = (pcd_sector % 4) * 512;
763 memcpy(pcd_buf, pcd_buffer + o, 512);
764 pcd_count--;
765 pcd_buf += 512;
766 pcd_sector++;
767 }
768}
769
770static void pcd_start(void)
771{
772 int b, i;
773 char rd_cmd[12] = { 0xa8, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 };
774
775 pcd_bufblk = pcd_sector / 4;
776 b = pcd_bufblk;
777 for (i = 0; i < 4; i++) {
778 rd_cmd[5 - i] = b & 0xff;
779 b = b >> 8;
780 }
781
782 if (pcd_command(pcd_current, rd_cmd, 2048, "read block")) {
783 pcd_bufblk = -1;
784 next_request(0);
785 return;
786 }
787
788 mdelay(1);
789
790 ps_set_intr(do_pcd_read_drq, pcd_ready, PCD_TMO, nice);
791}
792
793static void do_pcd_read(void)
794{
795 pcd_busy = 1;
796 pcd_retries = 0;
797 pcd_transfer();
798 if (!pcd_count) {
799 next_request(1);
800 return;
801 }
802
803 pi_do_claimed(pcd_current->pi, pcd_start);
804}
805
806static void do_pcd_read_drq(void)
807{
808 unsigned long saved_flags;
809
810 if (pcd_completion(pcd_current, pcd_buffer, "read block")) {
811 if (pcd_retries < PCD_RETRIES) {
812 mdelay(1);
813 pcd_retries++;
814 pi_do_claimed(pcd_current->pi, pcd_start);
815 return;
816 }
817 pcd_bufblk = -1;
818 next_request(0);
819 return;
820 }
821
822 do_pcd_read();
823 spin_lock_irqsave(&pcd_lock, saved_flags);
824 do_pcd_request(pcd_queue);
825 spin_unlock_irqrestore(&pcd_lock, saved_flags);
826}
827
828/* the audio_ioctl stuff is adapted from sr_ioctl.c */
829
830static int pcd_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd, void *arg)
831{
832 struct pcd_unit *cd = cdi->handle;
833
834 switch (cmd) {
835
836 case CDROMREADTOCHDR:
837
838 {
839 char cmd[12] =
840 { GPCMD_READ_TOC_PMA_ATIP, 0, 0, 0, 0, 0, 0, 0, 12,
841 0, 0, 0 };
842 struct cdrom_tochdr *tochdr =
843 (struct cdrom_tochdr *) arg;
844 char buffer[32];
845 int r;
846
847 r = pcd_atapi(cd, cmd, 12, buffer, "read toc header");
848
849 tochdr->cdth_trk0 = buffer[2];
850 tochdr->cdth_trk1 = buffer[3];
851
852 return r ? -EIO : 0;
853 }
854
855 case CDROMREADTOCENTRY:
856
857 {
858 char cmd[12] =
859 { GPCMD_READ_TOC_PMA_ATIP, 0, 0, 0, 0, 0, 0, 0, 12,
860 0, 0, 0 };
861
862 struct cdrom_tocentry *tocentry =
863 (struct cdrom_tocentry *) arg;
864 unsigned char buffer[32];
865 int r;
866
867 cmd[1] =
868 (tocentry->cdte_format == CDROM_MSF ? 0x02 : 0);
869 cmd[6] = tocentry->cdte_track;
870
871 r = pcd_atapi(cd, cmd, 12, buffer, "read toc entry");
872
873 tocentry->cdte_ctrl = buffer[5] & 0xf;
874 tocentry->cdte_adr = buffer[5] >> 4;
875 tocentry->cdte_datamode =
876 (tocentry->cdte_ctrl & 0x04) ? 1 : 0;
877 if (tocentry->cdte_format == CDROM_MSF) {
878 tocentry->cdte_addr.msf.minute = buffer[9];
879 tocentry->cdte_addr.msf.second = buffer[10];
880 tocentry->cdte_addr.msf.frame = buffer[11];
881 } else
882 tocentry->cdte_addr.lba =
883 (((((buffer[8] << 8) + buffer[9]) << 8)
884 + buffer[10]) << 8) + buffer[11];
885
886 return r ? -EIO : 0;
887 }
888
889 default:
890
891 return -ENOSYS;
892 }
893}
894
895static int pcd_get_mcn(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn)
896{
897 char cmd[12] =
898 { GPCMD_READ_SUBCHANNEL, 0, 0x40, 2, 0, 0, 0, 0, 24, 0, 0, 0 };
899 char buffer[32];
900
901 if (pcd_atapi(cdi->handle, cmd, 24, buffer, "get mcn"))
902 return -EIO;
903
904 memcpy(mcn->medium_catalog_number, buffer + 9, 13);
905 mcn->medium_catalog_number[13] = 0;
906
907 return 0;
908}
909
910static int __init pcd_init(void)
911{
912 struct pcd_unit *cd;
913 int unit;
914
915 if (disable)
916 return -1;
917
918 pcd_init_units();
919
920 if (pcd_detect())
921 return -1;
922
923 /* get the atapi capabilities page */
924 pcd_probe_capabilities();
925
926 if (register_blkdev(major, name)) {
927 for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++)
928 put_disk(cd->disk);
929 return -1;
930 }
931
932 pcd_queue = blk_init_queue(do_pcd_request, &pcd_lock);
933 if (!pcd_queue) {
934 unregister_blkdev(major, name);
935 for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++)
936 put_disk(cd->disk);
937 return -1;
938 }
939
940 for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) {
941 if (cd->present) {
942 register_cdrom(&cd->info);
943 cd->disk->private_data = cd;
944 cd->disk->queue = pcd_queue;
945 add_disk(cd->disk);
946 }
947 }
948
949 return 0;
950}
951
952static void __exit pcd_exit(void)
953{
954 struct pcd_unit *cd;
955 int unit;
956
957 for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) {
958 if (cd->present) {
959 del_gendisk(cd->disk);
960 pi_release(cd->pi);
961 unregister_cdrom(&cd->info);
962 }
963 put_disk(cd->disk);
964 }
965 blk_cleanup_queue(pcd_queue);
966 unregister_blkdev(major, name);
967}
968
969MODULE_LICENSE("GPL");
970module_init(pcd_init)
971module_exit(pcd_exit)
diff --git a/drivers/block/paride/pd.c b/drivers/block/paride/pd.c
new file mode 100644
index 000000000000..202a5a74ad37
--- /dev/null
+++ b/drivers/block/paride/pd.c
@@ -0,0 +1,950 @@
1/*
2 pd.c (c) 1997-8 Grant R. Guenther <grant@torque.net>
3 Under the terms of the GNU General Public License.
4
5 This is the high-level driver for parallel port IDE hard
6 drives based on chips supported by the paride module.
7
8 By default, the driver will autoprobe for a single parallel
9 port IDE drive, but if their individual parameters are
10 specified, the driver can handle up to 4 drives.
11
12 The behaviour of the pd driver can be altered by setting
13 some parameters from the insmod command line. The following
14 parameters are adjustable:
15
16 drive0 These four arguments can be arrays of
17 drive1 1-8 integers as follows:
18 drive2
19 drive3 <prt>,<pro>,<uni>,<mod>,<geo>,<sby>,<dly>,<slv>
20
21 Where,
22
23 <prt> is the base of the parallel port address for
24 the corresponding drive. (required)
25
26 <pro> is the protocol number for the adapter that
27 supports this drive. These numbers are
28 logged by 'paride' when the protocol modules
29 are initialised. (0 if not given)
30
31 <uni> for those adapters that support chained
32 devices, this is the unit selector for the
33 chain of devices on the given port. It should
34 be zero for devices that don't support chaining.
35 (0 if not given)
36
37 <mod> this can be -1 to choose the best mode, or one
38 of the mode numbers supported by the adapter.
39 (-1 if not given)
40
41 <geo> this defaults to 0 to indicate that the driver
42 should use the CHS geometry provided by the drive
43 itself. If set to 1, the driver will provide
44 a logical geometry with 64 heads and 32 sectors
45 per track, to be consistent with most SCSI
46 drivers. (0 if not given)
47
48 <sby> set this to zero to disable the power saving
49 standby mode, if needed. (1 if not given)
50
51 <dly> some parallel ports require the driver to
52 go more slowly. -1 sets a default value that
53 should work with the chosen protocol. Otherwise,
54 set this to a small integer, the larger it is
55 the slower the port i/o. In some cases, setting
56 this to zero will speed up the device. (default -1)
57
58 <slv> IDE disks can be jumpered to master or slave.
59 Set this to 0 to choose the master drive, 1 to
60 choose the slave, -1 (the default) to choose the
61 first drive found.
62
63
64 major You may use this parameter to overide the
65 default major number (45) that this driver
66 will use. Be sure to change the device
67 name as well.
68
69 name This parameter is a character string that
70 contains the name the kernel will use for this
71 device (in /proc output, for instance).
72 (default "pd")
73
74 cluster The driver will attempt to aggregate requests
75 for adjacent blocks into larger multi-block
76 clusters. The maximum cluster size (in 512
77 byte sectors) is set with this parameter.
78 (default 64)
79
80 verbose This parameter controls the amount of logging
81 that the driver will do. Set it to 0 for
82 normal operation, 1 to see autoprobe progress
83 messages, or 2 to see additional debugging
84 output. (default 0)
85
86 nice This parameter controls the driver's use of
87 idle CPU time, at the expense of some speed.
88
89 If this driver is built into the kernel, you can use kernel
90 the following command line parameters, with the same values
91 as the corresponding module parameters listed above:
92
93 pd.drive0
94 pd.drive1
95 pd.drive2
96 pd.drive3
97 pd.cluster
98 pd.nice
99
100 In addition, you can use the parameter pd.disable to disable
101 the driver entirely.
102
103*/
104
105/* Changes:
106
107 1.01 GRG 1997.01.24 Restored pd_reset()
108 Added eject ioctl
109 1.02 GRG 1998.05.06 SMP spinlock changes,
110 Added slave support
111 1.03 GRG 1998.06.16 Eliminate an Ugh.
112 1.04 GRG 1998.08.15 Extra debugging, use HZ in loop timing
113 1.05 GRG 1998.09.24 Added jumbo support
114
115*/
116
117#define PD_VERSION "1.05"
118#define PD_MAJOR 45
119#define PD_NAME "pd"
120#define PD_UNITS 4
121
122/* Here are things one can override from the insmod command.
123 Most are autoprobed by paride unless set here. Verbose is off
124 by default.
125
126*/
127
128static int verbose = 0;
129static int major = PD_MAJOR;
130static char *name = PD_NAME;
131static int cluster = 64;
132static int nice = 0;
133static int disable = 0;
134
135static int drive0[8] = { 0, 0, 0, -1, 0, 1, -1, -1 };
136static int drive1[8] = { 0, 0, 0, -1, 0, 1, -1, -1 };
137static int drive2[8] = { 0, 0, 0, -1, 0, 1, -1, -1 };
138static int drive3[8] = { 0, 0, 0, -1, 0, 1, -1, -1 };
139
140static int (*drives[4])[8] = {&drive0, &drive1, &drive2, &drive3};
141
142enum {D_PRT, D_PRO, D_UNI, D_MOD, D_GEO, D_SBY, D_DLY, D_SLV};
143
144/* end of parameters */
145
146#include <linux/init.h>
147#include <linux/module.h>
148#include <linux/fs.h>
149#include <linux/delay.h>
150#include <linux/hdreg.h>
151#include <linux/cdrom.h> /* for the eject ioctl */
152#include <linux/blkdev.h>
153#include <linux/blkpg.h>
154#include <asm/uaccess.h>
155#include <linux/sched.h>
156#include <linux/workqueue.h>
157
158static DEFINE_SPINLOCK(pd_lock);
159
160module_param(verbose, bool, 0);
161module_param(major, int, 0);
162module_param(name, charp, 0);
163module_param(cluster, int, 0);
164module_param(nice, int, 0);
165module_param_array(drive0, int, NULL, 0);
166module_param_array(drive1, int, NULL, 0);
167module_param_array(drive2, int, NULL, 0);
168module_param_array(drive3, int, NULL, 0);
169
170#include "paride.h"
171
172#define PD_BITS 4
173
174/* numbers for "SCSI" geometry */
175
176#define PD_LOG_HEADS 64
177#define PD_LOG_SECTS 32
178
179#define PD_ID_OFF 54
180#define PD_ID_LEN 14
181
182#define PD_MAX_RETRIES 5
183#define PD_TMO 800 /* interrupt timeout in jiffies */
184#define PD_SPIN_DEL 50 /* spin delay in micro-seconds */
185
186#define PD_SPIN (1000000*PD_TMO)/(HZ*PD_SPIN_DEL)
187
188#define STAT_ERR 0x00001
189#define STAT_INDEX 0x00002
190#define STAT_ECC 0x00004
191#define STAT_DRQ 0x00008
192#define STAT_SEEK 0x00010
193#define STAT_WRERR 0x00020
194#define STAT_READY 0x00040
195#define STAT_BUSY 0x00080
196
197#define ERR_AMNF 0x00100
198#define ERR_TK0NF 0x00200
199#define ERR_ABRT 0x00400
200#define ERR_MCR 0x00800
201#define ERR_IDNF 0x01000
202#define ERR_MC 0x02000
203#define ERR_UNC 0x04000
204#define ERR_TMO 0x10000
205
206#define IDE_READ 0x20
207#define IDE_WRITE 0x30
208#define IDE_READ_VRFY 0x40
209#define IDE_INIT_DEV_PARMS 0x91
210#define IDE_STANDBY 0x96
211#define IDE_ACKCHANGE 0xdb
212#define IDE_DOORLOCK 0xde
213#define IDE_DOORUNLOCK 0xdf
214#define IDE_IDENTIFY 0xec
215#define IDE_EJECT 0xed
216
217#define PD_NAMELEN 8
218
219struct pd_unit {
220 struct pi_adapter pia; /* interface to paride layer */
221 struct pi_adapter *pi;
222 int access; /* count of active opens ... */
223 int capacity; /* Size of this volume in sectors */
224 int heads; /* physical geometry */
225 int sectors;
226 int cylinders;
227 int can_lba;
228 int drive; /* master=0 slave=1 */
229 int changed; /* Have we seen a disk change ? */
230 int removable; /* removable media device ? */
231 int standby;
232 int alt_geom;
233 char name[PD_NAMELEN]; /* pda, pdb, etc ... */
234 struct gendisk *gd;
235};
236
237static struct pd_unit pd[PD_UNITS];
238
239static char pd_scratch[512]; /* scratch block buffer */
240
241static char *pd_errs[17] = { "ERR", "INDEX", "ECC", "DRQ", "SEEK", "WRERR",
242 "READY", "BUSY", "AMNF", "TK0NF", "ABRT", "MCR",
243 "IDNF", "MC", "UNC", "???", "TMO"
244};
245
246static inline int status_reg(struct pd_unit *disk)
247{
248 return pi_read_regr(disk->pi, 1, 6);
249}
250
251static inline int read_reg(struct pd_unit *disk, int reg)
252{
253 return pi_read_regr(disk->pi, 0, reg);
254}
255
256static inline void write_status(struct pd_unit *disk, int val)
257{
258 pi_write_regr(disk->pi, 1, 6, val);
259}
260
261static inline void write_reg(struct pd_unit *disk, int reg, int val)
262{
263 pi_write_regr(disk->pi, 0, reg, val);
264}
265
266static inline u8 DRIVE(struct pd_unit *disk)
267{
268 return 0xa0+0x10*disk->drive;
269}
270
271/* ide command interface */
272
273static void pd_print_error(struct pd_unit *disk, char *msg, int status)
274{
275 int i;
276
277 printk("%s: %s: status = 0x%x =", disk->name, msg, status);
278 for (i = 0; i < 18; i++)
279 if (status & (1 << i))
280 printk(" %s", pd_errs[i]);
281 printk("\n");
282}
283
284static void pd_reset(struct pd_unit *disk)
285{ /* called only for MASTER drive */
286 write_status(disk, 4);
287 udelay(50);
288 write_status(disk, 0);
289 udelay(250);
290}
291
292#define DBMSG(msg) ((verbose>1)?(msg):NULL)
293
294static int pd_wait_for(struct pd_unit *disk, int w, char *msg)
295{ /* polled wait */
296 int k, r, e;
297
298 k = 0;
299 while (k < PD_SPIN) {
300 r = status_reg(disk);
301 k++;
302 if (((r & w) == w) && !(r & STAT_BUSY))
303 break;
304 udelay(PD_SPIN_DEL);
305 }
306 e = (read_reg(disk, 1) << 8) + read_reg(disk, 7);
307 if (k >= PD_SPIN)
308 e |= ERR_TMO;
309 if ((e & (STAT_ERR | ERR_TMO)) && (msg != NULL))
310 pd_print_error(disk, msg, e);
311 return e;
312}
313
314static void pd_send_command(struct pd_unit *disk, int n, int s, int h, int c0, int c1, int func)
315{
316 write_reg(disk, 6, DRIVE(disk) + h);
317 write_reg(disk, 1, 0); /* the IDE task file */
318 write_reg(disk, 2, n);
319 write_reg(disk, 3, s);
320 write_reg(disk, 4, c0);
321 write_reg(disk, 5, c1);
322 write_reg(disk, 7, func);
323
324 udelay(1);
325}
326
327static void pd_ide_command(struct pd_unit *disk, int func, int block, int count)
328{
329 int c1, c0, h, s;
330
331 if (disk->can_lba) {
332 s = block & 255;
333 c0 = (block >>= 8) & 255;
334 c1 = (block >>= 8) & 255;
335 h = ((block >>= 8) & 15) + 0x40;
336 } else {
337 s = (block % disk->sectors) + 1;
338 h = (block /= disk->sectors) % disk->heads;
339 c0 = (block /= disk->heads) % 256;
340 c1 = (block >>= 8);
341 }
342 pd_send_command(disk, count, s, h, c0, c1, func);
343}
344
345/* The i/o request engine */
346
347enum action {Fail = 0, Ok = 1, Hold, Wait};
348
349static struct request *pd_req; /* current request */
350static enum action (*phase)(void);
351
352static void run_fsm(void);
353
354static void ps_tq_int( void *data);
355
356static DECLARE_WORK(fsm_tq, ps_tq_int, NULL);
357
358static void schedule_fsm(void)
359{
360 if (!nice)
361 schedule_work(&fsm_tq);
362 else
363 schedule_delayed_work(&fsm_tq, nice-1);
364}
365
366static void ps_tq_int(void *data)
367{
368 run_fsm();
369}
370
371static enum action do_pd_io_start(void);
372static enum action pd_special(void);
373static enum action do_pd_read_start(void);
374static enum action do_pd_write_start(void);
375static enum action do_pd_read_drq(void);
376static enum action do_pd_write_done(void);
377
378static struct request_queue *pd_queue;
379static int pd_claimed;
380
381static struct pd_unit *pd_current; /* current request's drive */
382static PIA *pi_current; /* current request's PIA */
383
384static void run_fsm(void)
385{
386 while (1) {
387 enum action res;
388 unsigned long saved_flags;
389 int stop = 0;
390
391 if (!phase) {
392 pd_current = pd_req->rq_disk->private_data;
393 pi_current = pd_current->pi;
394 phase = do_pd_io_start;
395 }
396
397 switch (pd_claimed) {
398 case 0:
399 pd_claimed = 1;
400 if (!pi_schedule_claimed(pi_current, run_fsm))
401 return;
402 case 1:
403 pd_claimed = 2;
404 pi_current->proto->connect(pi_current);
405 }
406
407 switch(res = phase()) {
408 case Ok: case Fail:
409 pi_disconnect(pi_current);
410 pd_claimed = 0;
411 phase = NULL;
412 spin_lock_irqsave(&pd_lock, saved_flags);
413 end_request(pd_req, res);
414 pd_req = elv_next_request(pd_queue);
415 if (!pd_req)
416 stop = 1;
417 spin_unlock_irqrestore(&pd_lock, saved_flags);
418 if (stop)
419 return;
420 case Hold:
421 schedule_fsm();
422 return;
423 case Wait:
424 pi_disconnect(pi_current);
425 pd_claimed = 0;
426 }
427 }
428}
429
430static int pd_retries = 0; /* i/o error retry count */
431static int pd_block; /* address of next requested block */
432static int pd_count; /* number of blocks still to do */
433static int pd_run; /* sectors in current cluster */
434static int pd_cmd; /* current command READ/WRITE */
435static char *pd_buf; /* buffer for request in progress */
436
437static enum action do_pd_io_start(void)
438{
439 if (pd_req->flags & REQ_SPECIAL) {
440 phase = pd_special;
441 return pd_special();
442 }
443
444 pd_cmd = rq_data_dir(pd_req);
445 if (pd_cmd == READ || pd_cmd == WRITE) {
446 pd_block = pd_req->sector;
447 pd_count = pd_req->current_nr_sectors;
448 if (pd_block + pd_count > get_capacity(pd_req->rq_disk))
449 return Fail;
450 pd_run = pd_req->nr_sectors;
451 pd_buf = pd_req->buffer;
452 pd_retries = 0;
453 if (pd_cmd == READ)
454 return do_pd_read_start();
455 else
456 return do_pd_write_start();
457 }
458 return Fail;
459}
460
461static enum action pd_special(void)
462{
463 enum action (*func)(struct pd_unit *) = pd_req->special;
464 return func(pd_current);
465}
466
467static int pd_next_buf(void)
468{
469 unsigned long saved_flags;
470
471 pd_count--;
472 pd_run--;
473 pd_buf += 512;
474 pd_block++;
475 if (!pd_run)
476 return 1;
477 if (pd_count)
478 return 0;
479 spin_lock_irqsave(&pd_lock, saved_flags);
480 end_request(pd_req, 1);
481 pd_count = pd_req->current_nr_sectors;
482 pd_buf = pd_req->buffer;
483 spin_unlock_irqrestore(&pd_lock, saved_flags);
484 return 0;
485}
486
487static unsigned long pd_timeout;
488
489static enum action do_pd_read_start(void)
490{
491 if (pd_wait_for(pd_current, STAT_READY, "do_pd_read") & STAT_ERR) {
492 if (pd_retries < PD_MAX_RETRIES) {
493 pd_retries++;
494 return Wait;
495 }
496 return Fail;
497 }
498 pd_ide_command(pd_current, IDE_READ, pd_block, pd_run);
499 phase = do_pd_read_drq;
500 pd_timeout = jiffies + PD_TMO;
501 return Hold;
502}
503
504static enum action do_pd_write_start(void)
505{
506 if (pd_wait_for(pd_current, STAT_READY, "do_pd_write") & STAT_ERR) {
507 if (pd_retries < PD_MAX_RETRIES) {
508 pd_retries++;
509 return Wait;
510 }
511 return Fail;
512 }
513 pd_ide_command(pd_current, IDE_WRITE, pd_block, pd_run);
514 while (1) {
515 if (pd_wait_for(pd_current, STAT_DRQ, "do_pd_write_drq") & STAT_ERR) {
516 if (pd_retries < PD_MAX_RETRIES) {
517 pd_retries++;
518 return Wait;
519 }
520 return Fail;
521 }
522 pi_write_block(pd_current->pi, pd_buf, 512);
523 if (pd_next_buf())
524 break;
525 }
526 phase = do_pd_write_done;
527 pd_timeout = jiffies + PD_TMO;
528 return Hold;
529}
530
531static inline int pd_ready(void)
532{
533 return !(status_reg(pd_current) & STAT_BUSY);
534}
535
536static enum action do_pd_read_drq(void)
537{
538 if (!pd_ready() && !time_after_eq(jiffies, pd_timeout))
539 return Hold;
540
541 while (1) {
542 if (pd_wait_for(pd_current, STAT_DRQ, "do_pd_read_drq") & STAT_ERR) {
543 if (pd_retries < PD_MAX_RETRIES) {
544 pd_retries++;
545 phase = do_pd_read_start;
546 return Wait;
547 }
548 return Fail;
549 }
550 pi_read_block(pd_current->pi, pd_buf, 512);
551 if (pd_next_buf())
552 break;
553 }
554 return Ok;
555}
556
557static enum action do_pd_write_done(void)
558{
559 if (!pd_ready() && !time_after_eq(jiffies, pd_timeout))
560 return Hold;
561
562 if (pd_wait_for(pd_current, STAT_READY, "do_pd_write_done") & STAT_ERR) {
563 if (pd_retries < PD_MAX_RETRIES) {
564 pd_retries++;
565 phase = do_pd_write_start;
566 return Wait;
567 }
568 return Fail;
569 }
570 return Ok;
571}
572
573/* special io requests */
574
575/* According to the ATA standard, the default CHS geometry should be
576 available following a reset. Some Western Digital drives come up
577 in a mode where only LBA addresses are accepted until the device
578 parameters are initialised.
579*/
580
581static void pd_init_dev_parms(struct pd_unit *disk)
582{
583 pd_wait_for(disk, 0, DBMSG("before init_dev_parms"));
584 pd_send_command(disk, disk->sectors, 0, disk->heads - 1, 0, 0,
585 IDE_INIT_DEV_PARMS);
586 udelay(300);
587 pd_wait_for(disk, 0, "Initialise device parameters");
588}
589
590static enum action pd_door_lock(struct pd_unit *disk)
591{
592 if (!(pd_wait_for(disk, STAT_READY, "Lock") & STAT_ERR)) {
593 pd_send_command(disk, 1, 0, 0, 0, 0, IDE_DOORLOCK);
594 pd_wait_for(disk, STAT_READY, "Lock done");
595 }
596 return Ok;
597}
598
599static enum action pd_door_unlock(struct pd_unit *disk)
600{
601 if (!(pd_wait_for(disk, STAT_READY, "Lock") & STAT_ERR)) {
602 pd_send_command(disk, 1, 0, 0, 0, 0, IDE_DOORUNLOCK);
603 pd_wait_for(disk, STAT_READY, "Lock done");
604 }
605 return Ok;
606}
607
608static enum action pd_eject(struct pd_unit *disk)
609{
610 pd_wait_for(disk, 0, DBMSG("before unlock on eject"));
611 pd_send_command(disk, 1, 0, 0, 0, 0, IDE_DOORUNLOCK);
612 pd_wait_for(disk, 0, DBMSG("after unlock on eject"));
613 pd_wait_for(disk, 0, DBMSG("before eject"));
614 pd_send_command(disk, 0, 0, 0, 0, 0, IDE_EJECT);
615 pd_wait_for(disk, 0, DBMSG("after eject"));
616 return Ok;
617}
618
619static enum action pd_media_check(struct pd_unit *disk)
620{
621 int r = pd_wait_for(disk, STAT_READY, DBMSG("before media_check"));
622 if (!(r & STAT_ERR)) {
623 pd_send_command(disk, 1, 1, 0, 0, 0, IDE_READ_VRFY);
624 r = pd_wait_for(disk, STAT_READY, DBMSG("RDY after READ_VRFY"));
625 } else
626 disk->changed = 1; /* say changed if other error */
627 if (r & ERR_MC) {
628 disk->changed = 1;
629 pd_send_command(disk, 1, 0, 0, 0, 0, IDE_ACKCHANGE);
630 pd_wait_for(disk, STAT_READY, DBMSG("RDY after ACKCHANGE"));
631 pd_send_command(disk, 1, 1, 0, 0, 0, IDE_READ_VRFY);
632 r = pd_wait_for(disk, STAT_READY, DBMSG("RDY after VRFY"));
633 }
634 return Ok;
635}
636
637static void pd_standby_off(struct pd_unit *disk)
638{
639 pd_wait_for(disk, 0, DBMSG("before STANDBY"));
640 pd_send_command(disk, 0, 0, 0, 0, 0, IDE_STANDBY);
641 pd_wait_for(disk, 0, DBMSG("after STANDBY"));
642}
643
644static enum action pd_identify(struct pd_unit *disk)
645{
646 int j;
647 char id[PD_ID_LEN + 1];
648
649/* WARNING: here there may be dragons. reset() applies to both drives,
650 but we call it only on probing the MASTER. This should allow most
651 common configurations to work, but be warned that a reset can clear
652 settings on the SLAVE drive.
653*/
654
655 if (disk->drive == 0)
656 pd_reset(disk);
657
658 write_reg(disk, 6, DRIVE(disk));
659 pd_wait_for(disk, 0, DBMSG("before IDENT"));
660 pd_send_command(disk, 1, 0, 0, 0, 0, IDE_IDENTIFY);
661
662 if (pd_wait_for(disk, STAT_DRQ, DBMSG("IDENT DRQ")) & STAT_ERR)
663 return Fail;
664 pi_read_block(disk->pi, pd_scratch, 512);
665 disk->can_lba = pd_scratch[99] & 2;
666 disk->sectors = le16_to_cpu(*(u16 *) (pd_scratch + 12));
667 disk->heads = le16_to_cpu(*(u16 *) (pd_scratch + 6));
668 disk->cylinders = le16_to_cpu(*(u16 *) (pd_scratch + 2));
669 if (disk->can_lba)
670 disk->capacity = le32_to_cpu(*(u32 *) (pd_scratch + 120));
671 else
672 disk->capacity = disk->sectors * disk->heads * disk->cylinders;
673
674 for (j = 0; j < PD_ID_LEN; j++)
675 id[j ^ 1] = pd_scratch[j + PD_ID_OFF];
676 j = PD_ID_LEN - 1;
677 while ((j >= 0) && (id[j] <= 0x20))
678 j--;
679 j++;
680 id[j] = 0;
681
682 disk->removable = pd_scratch[0] & 0x80;
683
684 printk("%s: %s, %s, %d blocks [%dM], (%d/%d/%d), %s media\n",
685 disk->name, id,
686 disk->drive ? "slave" : "master",
687 disk->capacity, disk->capacity / 2048,
688 disk->cylinders, disk->heads, disk->sectors,
689 disk->removable ? "removable" : "fixed");
690
691 if (disk->capacity)
692 pd_init_dev_parms(disk);
693 if (!disk->standby)
694 pd_standby_off(disk);
695
696 return Ok;
697}
698
699/* end of io request engine */
700
701static void do_pd_request(request_queue_t * q)
702{
703 if (pd_req)
704 return;
705 pd_req = elv_next_request(q);
706 if (!pd_req)
707 return;
708
709 schedule_fsm();
710}
711
712static int pd_special_command(struct pd_unit *disk,
713 enum action (*func)(struct pd_unit *disk))
714{
715 DECLARE_COMPLETION(wait);
716 struct request rq;
717 int err = 0;
718
719 memset(&rq, 0, sizeof(rq));
720 rq.errors = 0;
721 rq.rq_status = RQ_ACTIVE;
722 rq.rq_disk = disk->gd;
723 rq.ref_count = 1;
724 rq.waiting = &wait;
725 rq.end_io = blk_end_sync_rq;
726 blk_insert_request(disk->gd->queue, &rq, 0, func, 0);
727 wait_for_completion(&wait);
728 rq.waiting = NULL;
729 if (rq.errors)
730 err = -EIO;
731 blk_put_request(&rq);
732 return err;
733}
734
735/* kernel glue structures */
736
737static int pd_open(struct inode *inode, struct file *file)
738{
739 struct pd_unit *disk = inode->i_bdev->bd_disk->private_data;
740
741 disk->access++;
742
743 if (disk->removable) {
744 pd_special_command(disk, pd_media_check);
745 pd_special_command(disk, pd_door_lock);
746 }
747 return 0;
748}
749
750static int pd_ioctl(struct inode *inode, struct file *file,
751 unsigned int cmd, unsigned long arg)
752{
753 struct pd_unit *disk = inode->i_bdev->bd_disk->private_data;
754 struct hd_geometry __user *geo = (struct hd_geometry __user *) arg;
755 struct hd_geometry g;
756
757 switch (cmd) {
758 case CDROMEJECT:
759 if (disk->access == 1)
760 pd_special_command(disk, pd_eject);
761 return 0;
762 case HDIO_GETGEO:
763 if (disk->alt_geom) {
764 g.heads = PD_LOG_HEADS;
765 g.sectors = PD_LOG_SECTS;
766 g.cylinders = disk->capacity / (g.heads * g.sectors);
767 } else {
768 g.heads = disk->heads;
769 g.sectors = disk->sectors;
770 g.cylinders = disk->cylinders;
771 }
772 g.start = get_start_sect(inode->i_bdev);
773 if (copy_to_user(geo, &g, sizeof(struct hd_geometry)))
774 return -EFAULT;
775 return 0;
776 default:
777 return -EINVAL;
778 }
779}
780
781static int pd_release(struct inode *inode, struct file *file)
782{
783 struct pd_unit *disk = inode->i_bdev->bd_disk->private_data;
784
785 if (!--disk->access && disk->removable)
786 pd_special_command(disk, pd_door_unlock);
787
788 return 0;
789}
790
791static int pd_check_media(struct gendisk *p)
792{
793 struct pd_unit *disk = p->private_data;
794 int r;
795 if (!disk->removable)
796 return 0;
797 pd_special_command(disk, pd_media_check);
798 r = disk->changed;
799 disk->changed = 0;
800 return r;
801}
802
803static int pd_revalidate(struct gendisk *p)
804{
805 struct pd_unit *disk = p->private_data;
806 if (pd_special_command(disk, pd_identify) == 0)
807 set_capacity(p, disk->capacity);
808 else
809 set_capacity(p, 0);
810 return 0;
811}
812
813static struct block_device_operations pd_fops = {
814 .owner = THIS_MODULE,
815 .open = pd_open,
816 .release = pd_release,
817 .ioctl = pd_ioctl,
818 .media_changed = pd_check_media,
819 .revalidate_disk= pd_revalidate
820};
821
822/* probing */
823
824static void pd_probe_drive(struct pd_unit *disk)
825{
826 struct gendisk *p = alloc_disk(1 << PD_BITS);
827 if (!p)
828 return;
829 strcpy(p->disk_name, disk->name);
830 p->fops = &pd_fops;
831 p->major = major;
832 p->first_minor = (disk - pd) << PD_BITS;
833 disk->gd = p;
834 p->private_data = disk;
835 p->queue = pd_queue;
836
837 if (disk->drive == -1) {
838 for (disk->drive = 0; disk->drive <= 1; disk->drive++)
839 if (pd_special_command(disk, pd_identify) == 0)
840 return;
841 } else if (pd_special_command(disk, pd_identify) == 0)
842 return;
843 disk->gd = NULL;
844 put_disk(p);
845}
846
847static int pd_detect(void)
848{
849 int found = 0, unit, pd_drive_count = 0;
850 struct pd_unit *disk;
851
852 for (unit = 0; unit < PD_UNITS; unit++) {
853 int *parm = *drives[unit];
854 struct pd_unit *disk = pd + unit;
855 disk->pi = &disk->pia;
856 disk->access = 0;
857 disk->changed = 1;
858 disk->capacity = 0;
859 disk->drive = parm[D_SLV];
860 snprintf(disk->name, PD_NAMELEN, "%s%c", name, 'a'+unit);
861 disk->alt_geom = parm[D_GEO];
862 disk->standby = parm[D_SBY];
863 if (parm[D_PRT])
864 pd_drive_count++;
865 }
866
867 if (pd_drive_count == 0) { /* nothing spec'd - so autoprobe for 1 */
868 disk = pd;
869 if (pi_init(disk->pi, 1, -1, -1, -1, -1, -1, pd_scratch,
870 PI_PD, verbose, disk->name)) {
871 pd_probe_drive(disk);
872 if (!disk->gd)
873 pi_release(disk->pi);
874 }
875
876 } else {
877 for (unit = 0, disk = pd; unit < PD_UNITS; unit++, disk++) {
878 int *parm = *drives[unit];
879 if (!parm[D_PRT])
880 continue;
881 if (pi_init(disk->pi, 0, parm[D_PRT], parm[D_MOD],
882 parm[D_UNI], parm[D_PRO], parm[D_DLY],
883 pd_scratch, PI_PD, verbose, disk->name)) {
884 pd_probe_drive(disk);
885 if (!disk->gd)
886 pi_release(disk->pi);
887 }
888 }
889 }
890 for (unit = 0, disk = pd; unit < PD_UNITS; unit++, disk++) {
891 if (disk->gd) {
892 set_capacity(disk->gd, disk->capacity);
893 add_disk(disk->gd);
894 found = 1;
895 }
896 }
897 if (!found)
898 printk("%s: no valid drive found\n", name);
899 return found;
900}
901
902static int __init pd_init(void)
903{
904 if (disable)
905 goto out1;
906
907 pd_queue = blk_init_queue(do_pd_request, &pd_lock);
908 if (!pd_queue)
909 goto out1;
910
911 blk_queue_max_sectors(pd_queue, cluster);
912
913 if (register_blkdev(major, name))
914 goto out2;
915
916 printk("%s: %s version %s, major %d, cluster %d, nice %d\n",
917 name, name, PD_VERSION, major, cluster, nice);
918 if (!pd_detect())
919 goto out3;
920
921 return 0;
922
923out3:
924 unregister_blkdev(major, name);
925out2:
926 blk_cleanup_queue(pd_queue);
927out1:
928 return -ENODEV;
929}
930
931static void __exit pd_exit(void)
932{
933 struct pd_unit *disk;
934 int unit;
935 unregister_blkdev(major, name);
936 for (unit = 0, disk = pd; unit < PD_UNITS; unit++, disk++) {
937 struct gendisk *p = disk->gd;
938 if (p) {
939 disk->gd = NULL;
940 del_gendisk(p);
941 put_disk(p);
942 pi_release(disk->pi);
943 }
944 }
945 blk_cleanup_queue(pd_queue);
946}
947
948MODULE_LICENSE("GPL");
949module_init(pd_init)
950module_exit(pd_exit)
diff --git a/drivers/block/paride/pf.c b/drivers/block/paride/pf.c
new file mode 100644
index 000000000000..060b1f2a91dd
--- /dev/null
+++ b/drivers/block/paride/pf.c
@@ -0,0 +1,982 @@
1/*
2 pf.c (c) 1997-8 Grant R. Guenther <grant@torque.net>
3 Under the terms of the GNU General Public License.
4
5 This is the high-level driver for parallel port ATAPI disk
6 drives based on chips supported by the paride module.
7
8 By default, the driver will autoprobe for a single parallel
9 port ATAPI disk drive, but if their individual parameters are
10 specified, the driver can handle up to 4 drives.
11
12 The behaviour of the pf driver can be altered by setting
13 some parameters from the insmod command line. The following
14 parameters are adjustable:
15
16 drive0 These four arguments can be arrays of
17 drive1 1-7 integers as follows:
18 drive2
19 drive3 <prt>,<pro>,<uni>,<mod>,<slv>,<lun>,<dly>
20
21 Where,
22
23 <prt> is the base of the parallel port address for
24 the corresponding drive. (required)
25
26 <pro> is the protocol number for the adapter that
27 supports this drive. These numbers are
28 logged by 'paride' when the protocol modules
29 are initialised. (0 if not given)
30
31 <uni> for those adapters that support chained
32 devices, this is the unit selector for the
33 chain of devices on the given port. It should
34 be zero for devices that don't support chaining.
35 (0 if not given)
36
37 <mod> this can be -1 to choose the best mode, or one
38 of the mode numbers supported by the adapter.
39 (-1 if not given)
40
41 <slv> ATAPI CDroms can be jumpered to master or slave.
42 Set this to 0 to choose the master drive, 1 to
43 choose the slave, -1 (the default) to choose the
44 first drive found.
45
46 <lun> Some ATAPI devices support multiple LUNs.
47 One example is the ATAPI PD/CD drive from
48 Matshita/Panasonic. This device has a
49 CD drive on LUN 0 and a PD drive on LUN 1.
50 By default, the driver will search for the
51 first LUN with a supported device. Set
52 this parameter to force it to use a specific
53 LUN. (default -1)
54
55 <dly> some parallel ports require the driver to
56 go more slowly. -1 sets a default value that
57 should work with the chosen protocol. Otherwise,
58 set this to a small integer, the larger it is
59 the slower the port i/o. In some cases, setting
60 this to zero will speed up the device. (default -1)
61
62 major You may use this parameter to overide the
63 default major number (47) that this driver
64 will use. Be sure to change the device
65 name as well.
66
67 name This parameter is a character string that
68 contains the name the kernel will use for this
69 device (in /proc output, for instance).
70 (default "pf").
71
72 cluster The driver will attempt to aggregate requests
73 for adjacent blocks into larger multi-block
74 clusters. The maximum cluster size (in 512
75 byte sectors) is set with this parameter.
76 (default 64)
77
78 verbose This parameter controls the amount of logging
79 that the driver will do. Set it to 0 for
80 normal operation, 1 to see autoprobe progress
81 messages, or 2 to see additional debugging
82 output. (default 0)
83
84 nice This parameter controls the driver's use of
85 idle CPU time, at the expense of some speed.
86
87 If this driver is built into the kernel, you can use the
88 following command line parameters, with the same values
89 as the corresponding module parameters listed above:
90
91 pf.drive0
92 pf.drive1
93 pf.drive2
94 pf.drive3
95 pf.cluster
96 pf.nice
97
98 In addition, you can use the parameter pf.disable to disable
99 the driver entirely.
100
101*/
102
103/* Changes:
104
105 1.01 GRG 1998.05.03 Changes for SMP. Eliminate sti().
106 Fix for drives that don't clear STAT_ERR
107 until after next CDB delivered.
108 Small change in pf_completion to round
109 up transfer size.
110 1.02 GRG 1998.06.16 Eliminated an Ugh
111 1.03 GRG 1998.08.16 Use HZ in loop timings, extra debugging
112 1.04 GRG 1998.09.24 Added jumbo support
113
114*/
115
116#define PF_VERSION "1.04"
117#define PF_MAJOR 47
118#define PF_NAME "pf"
119#define PF_UNITS 4
120
121/* Here are things one can override from the insmod command.
122 Most are autoprobed by paride unless set here. Verbose is off
123 by default.
124
125*/
126
127static int verbose = 0;
128static int major = PF_MAJOR;
129static char *name = PF_NAME;
130static int cluster = 64;
131static int nice = 0;
132static int disable = 0;
133
134static int drive0[7] = { 0, 0, 0, -1, -1, -1, -1 };
135static int drive1[7] = { 0, 0, 0, -1, -1, -1, -1 };
136static int drive2[7] = { 0, 0, 0, -1, -1, -1, -1 };
137static int drive3[7] = { 0, 0, 0, -1, -1, -1, -1 };
138
139static int (*drives[4])[7] = {&drive0, &drive1, &drive2, &drive3};
140static int pf_drive_count;
141
142enum {D_PRT, D_PRO, D_UNI, D_MOD, D_SLV, D_LUN, D_DLY};
143
144/* end of parameters */
145
146#include <linux/module.h>
147#include <linux/init.h>
148#include <linux/fs.h>
149#include <linux/delay.h>
150#include <linux/hdreg.h>
151#include <linux/cdrom.h>
152#include <linux/spinlock.h>
153#include <linux/blkdev.h>
154#include <linux/blkpg.h>
155#include <asm/uaccess.h>
156
157static spinlock_t pf_spin_lock;
158
159module_param(verbose, bool, 0644);
160module_param(major, int, 0);
161module_param(name, charp, 0);
162module_param(cluster, int, 0);
163module_param(nice, int, 0);
164module_param_array(drive0, int, NULL, 0);
165module_param_array(drive1, int, NULL, 0);
166module_param_array(drive2, int, NULL, 0);
167module_param_array(drive3, int, NULL, 0);
168
169#include "paride.h"
170#include "pseudo.h"
171
172/* constants for faking geometry numbers */
173
174#define PF_FD_MAX 8192 /* use FD geometry under this size */
175#define PF_FD_HDS 2
176#define PF_FD_SPT 18
177#define PF_HD_HDS 64
178#define PF_HD_SPT 32
179
180#define PF_MAX_RETRIES 5
181#define PF_TMO 800 /* interrupt timeout in jiffies */
182#define PF_SPIN_DEL 50 /* spin delay in micro-seconds */
183
184#define PF_SPIN (1000000*PF_TMO)/(HZ*PF_SPIN_DEL)
185
186#define STAT_ERR 0x00001
187#define STAT_INDEX 0x00002
188#define STAT_ECC 0x00004
189#define STAT_DRQ 0x00008
190#define STAT_SEEK 0x00010
191#define STAT_WRERR 0x00020
192#define STAT_READY 0x00040
193#define STAT_BUSY 0x00080
194
195#define ATAPI_REQ_SENSE 0x03
196#define ATAPI_LOCK 0x1e
197#define ATAPI_DOOR 0x1b
198#define ATAPI_MODE_SENSE 0x5a
199#define ATAPI_CAPACITY 0x25
200#define ATAPI_IDENTIFY 0x12
201#define ATAPI_READ_10 0x28
202#define ATAPI_WRITE_10 0x2a
203
204static int pf_open(struct inode *inode, struct file *file);
205static void do_pf_request(request_queue_t * q);
206static int pf_ioctl(struct inode *inode, struct file *file,
207 unsigned int cmd, unsigned long arg);
208
209static int pf_release(struct inode *inode, struct file *file);
210
211static int pf_detect(void);
212static void do_pf_read(void);
213static void do_pf_read_start(void);
214static void do_pf_write(void);
215static void do_pf_write_start(void);
216static void do_pf_read_drq(void);
217static void do_pf_write_done(void);
218
219#define PF_NM 0
220#define PF_RO 1
221#define PF_RW 2
222
223#define PF_NAMELEN 8
224
225struct pf_unit {
226 struct pi_adapter pia; /* interface to paride layer */
227 struct pi_adapter *pi;
228 int removable; /* removable media device ? */
229 int media_status; /* media present ? WP ? */
230 int drive; /* drive */
231 int lun;
232 int access; /* count of active opens ... */
233 int present; /* device present ? */
234 char name[PF_NAMELEN]; /* pf0, pf1, ... */
235 struct gendisk *disk;
236};
237
238static struct pf_unit units[PF_UNITS];
239
240static int pf_identify(struct pf_unit *pf);
241static void pf_lock(struct pf_unit *pf, int func);
242static void pf_eject(struct pf_unit *pf);
243static int pf_check_media(struct gendisk *disk);
244
245static char pf_scratch[512]; /* scratch block buffer */
246
247/* the variables below are used mainly in the I/O request engine, which
248 processes only one request at a time.
249*/
250
251static int pf_retries = 0; /* i/o error retry count */
252static int pf_busy = 0; /* request being processed ? */
253static struct request *pf_req; /* current request */
254static int pf_block; /* address of next requested block */
255static int pf_count; /* number of blocks still to do */
256static int pf_run; /* sectors in current cluster */
257static int pf_cmd; /* current command READ/WRITE */
258static struct pf_unit *pf_current;/* unit of current request */
259static int pf_mask; /* stopper for pseudo-int */
260static char *pf_buf; /* buffer for request in progress */
261
262/* kernel glue structures */
263
264static struct block_device_operations pf_fops = {
265 .owner = THIS_MODULE,
266 .open = pf_open,
267 .release = pf_release,
268 .ioctl = pf_ioctl,
269 .media_changed = pf_check_media,
270};
271
272static void __init pf_init_units(void)
273{
274 struct pf_unit *pf;
275 int unit;
276
277 pf_drive_count = 0;
278 for (unit = 0, pf = units; unit < PF_UNITS; unit++, pf++) {
279 struct gendisk *disk = alloc_disk(1);
280 if (!disk)
281 continue;
282 pf->disk = disk;
283 pf->pi = &pf->pia;
284 pf->media_status = PF_NM;
285 pf->drive = (*drives[unit])[D_SLV];
286 pf->lun = (*drives[unit])[D_LUN];
287 snprintf(pf->name, PF_NAMELEN, "%s%d", name, unit);
288 disk->major = major;
289 disk->first_minor = unit;
290 strcpy(disk->disk_name, pf->name);
291 disk->fops = &pf_fops;
292 if (!(*drives[unit])[D_PRT])
293 pf_drive_count++;
294 }
295}
296
297static int pf_open(struct inode *inode, struct file *file)
298{
299 struct pf_unit *pf = inode->i_bdev->bd_disk->private_data;
300
301 pf_identify(pf);
302
303 if (pf->media_status == PF_NM)
304 return -ENODEV;
305
306 if ((pf->media_status == PF_RO) && (file->f_mode & 2))
307 return -EROFS;
308
309 pf->access++;
310 if (pf->removable)
311 pf_lock(pf, 1);
312
313 return 0;
314}
315
316static int pf_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
317{
318 struct pf_unit *pf = inode->i_bdev->bd_disk->private_data;
319 struct hd_geometry __user *geo = (struct hd_geometry __user *) arg;
320 struct hd_geometry g;
321 sector_t capacity;
322
323 if (cmd == CDROMEJECT) {
324 if (pf->access == 1) {
325 pf_eject(pf);
326 return 0;
327 }
328 return -EBUSY;
329 }
330 if (cmd != HDIO_GETGEO)
331 return -EINVAL;
332 capacity = get_capacity(pf->disk);
333 if (capacity < PF_FD_MAX) {
334 g.cylinders = sector_div(capacity, PF_FD_HDS * PF_FD_SPT);
335 g.heads = PF_FD_HDS;
336 g.sectors = PF_FD_SPT;
337 } else {
338 g.cylinders = sector_div(capacity, PF_HD_HDS * PF_HD_SPT);
339 g.heads = PF_HD_HDS;
340 g.sectors = PF_HD_SPT;
341 }
342 if (copy_to_user(geo, &g, sizeof(g)))
343 return -EFAULT;
344 return 0;
345}
346
347static int pf_release(struct inode *inode, struct file *file)
348{
349 struct pf_unit *pf = inode->i_bdev->bd_disk->private_data;
350
351 if (pf->access <= 0)
352 return -EINVAL;
353
354 pf->access--;
355
356 if (!pf->access && pf->removable)
357 pf_lock(pf, 0);
358
359 return 0;
360
361}
362
363static int pf_check_media(struct gendisk *disk)
364{
365 return 1;
366}
367
368static inline int status_reg(struct pf_unit *pf)
369{
370 return pi_read_regr(pf->pi, 1, 6);
371}
372
373static inline int read_reg(struct pf_unit *pf, int reg)
374{
375 return pi_read_regr(pf->pi, 0, reg);
376}
377
378static inline void write_reg(struct pf_unit *pf, int reg, int val)
379{
380 pi_write_regr(pf->pi, 0, reg, val);
381}
382
383static int pf_wait(struct pf_unit *pf, int go, int stop, char *fun, char *msg)
384{
385 int j, r, e, s, p;
386
387 j = 0;
388 while ((((r = status_reg(pf)) & go) || (stop && (!(r & stop))))
389 && (j++ < PF_SPIN))
390 udelay(PF_SPIN_DEL);
391
392 if ((r & (STAT_ERR & stop)) || (j >= PF_SPIN)) {
393 s = read_reg(pf, 7);
394 e = read_reg(pf, 1);
395 p = read_reg(pf, 2);
396 if (j >= PF_SPIN)
397 e |= 0x100;
398 if (fun)
399 printk("%s: %s %s: alt=0x%x stat=0x%x err=0x%x"
400 " loop=%d phase=%d\n",
401 pf->name, fun, msg, r, s, e, j, p);
402 return (e << 8) + s;
403 }
404 return 0;
405}
406
407static int pf_command(struct pf_unit *pf, char *cmd, int dlen, char *fun)
408{
409 pi_connect(pf->pi);
410
411 write_reg(pf, 6, 0xa0+0x10*pf->drive);
412
413 if (pf_wait(pf, STAT_BUSY | STAT_DRQ, 0, fun, "before command")) {
414 pi_disconnect(pf->pi);
415 return -1;
416 }
417
418 write_reg(pf, 4, dlen % 256);
419 write_reg(pf, 5, dlen / 256);
420 write_reg(pf, 7, 0xa0); /* ATAPI packet command */
421
422 if (pf_wait(pf, STAT_BUSY, STAT_DRQ, fun, "command DRQ")) {
423 pi_disconnect(pf->pi);
424 return -1;
425 }
426
427 if (read_reg(pf, 2) != 1) {
428 printk("%s: %s: command phase error\n", pf->name, fun);
429 pi_disconnect(pf->pi);
430 return -1;
431 }
432
433 pi_write_block(pf->pi, cmd, 12);
434
435 return 0;
436}
437
438static int pf_completion(struct pf_unit *pf, char *buf, char *fun)
439{
440 int r, s, n;
441
442 r = pf_wait(pf, STAT_BUSY, STAT_DRQ | STAT_READY | STAT_ERR,
443 fun, "completion");
444
445 if ((read_reg(pf, 2) & 2) && (read_reg(pf, 7) & STAT_DRQ)) {
446 n = (((read_reg(pf, 4) + 256 * read_reg(pf, 5)) +
447 3) & 0xfffc);
448 pi_read_block(pf->pi, buf, n);
449 }
450
451 s = pf_wait(pf, STAT_BUSY, STAT_READY | STAT_ERR, fun, "data done");
452
453 pi_disconnect(pf->pi);
454
455 return (r ? r : s);
456}
457
458static void pf_req_sense(struct pf_unit *pf, int quiet)
459{
460 char rs_cmd[12] =
461 { ATAPI_REQ_SENSE, pf->lun << 5, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0 };
462 char buf[16];
463 int r;
464
465 r = pf_command(pf, rs_cmd, 16, "Request sense");
466 mdelay(1);
467 if (!r)
468 pf_completion(pf, buf, "Request sense");
469
470 if ((!r) && (!quiet))
471 printk("%s: Sense key: %x, ASC: %x, ASQ: %x\n",
472 pf->name, buf[2] & 0xf, buf[12], buf[13]);
473}
474
475static int pf_atapi(struct pf_unit *pf, char *cmd, int dlen, char *buf, char *fun)
476{
477 int r;
478
479 r = pf_command(pf, cmd, dlen, fun);
480 mdelay(1);
481 if (!r)
482 r = pf_completion(pf, buf, fun);
483 if (r)
484 pf_req_sense(pf, !fun);
485
486 return r;
487}
488
489#define DBMSG(msg) ((verbose>1)?(msg):NULL)
490
491static void pf_lock(struct pf_unit *pf, int func)
492{
493 char lo_cmd[12] = { ATAPI_LOCK, pf->lun << 5, 0, 0, func, 0, 0, 0, 0, 0, 0, 0 };
494
495 pf_atapi(pf, lo_cmd, 0, pf_scratch, func ? "unlock" : "lock");
496}
497
498static void pf_eject(struct pf_unit *pf)
499{
500 char ej_cmd[12] = { ATAPI_DOOR, pf->lun << 5, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0 };
501
502 pf_lock(pf, 0);
503 pf_atapi(pf, ej_cmd, 0, pf_scratch, "eject");
504}
505
506#define PF_RESET_TMO 30 /* in tenths of a second */
507
508static void pf_sleep(int cs)
509{
510 current->state = TASK_INTERRUPTIBLE;
511 schedule_timeout(cs);
512}
513
514/* the ATAPI standard actually specifies the contents of all 7 registers
515 after a reset, but the specification is ambiguous concerning the last
516 two bytes, and different drives interpret the standard differently.
517 */
518
519static int pf_reset(struct pf_unit *pf)
520{
521 int i, k, flg;
522 int expect[5] = { 1, 1, 1, 0x14, 0xeb };
523
524 pi_connect(pf->pi);
525 write_reg(pf, 6, 0xa0+0x10*pf->drive);
526 write_reg(pf, 7, 8);
527
528 pf_sleep(20 * HZ / 1000);
529
530 k = 0;
531 while ((k++ < PF_RESET_TMO) && (status_reg(pf) & STAT_BUSY))
532 pf_sleep(HZ / 10);
533
534 flg = 1;
535 for (i = 0; i < 5; i++)
536 flg &= (read_reg(pf, i + 1) == expect[i]);
537
538 if (verbose) {
539 printk("%s: Reset (%d) signature = ", pf->name, k);
540 for (i = 0; i < 5; i++)
541 printk("%3x", read_reg(pf, i + 1));
542 if (!flg)
543 printk(" (incorrect)");
544 printk("\n");
545 }
546
547 pi_disconnect(pf->pi);
548 return flg - 1;
549}
550
551static void pf_mode_sense(struct pf_unit *pf)
552{
553 char ms_cmd[12] =
554 { ATAPI_MODE_SENSE, pf->lun << 5, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0 };
555 char buf[8];
556
557 pf_atapi(pf, ms_cmd, 8, buf, DBMSG("mode sense"));
558 pf->media_status = PF_RW;
559 if (buf[3] & 0x80)
560 pf->media_status = PF_RO;
561}
562
563static void xs(char *buf, char *targ, int offs, int len)
564{
565 int j, k, l;
566
567 j = 0;
568 l = 0;
569 for (k = 0; k < len; k++)
570 if ((buf[k + offs] != 0x20) || (buf[k + offs] != l))
571 l = targ[j++] = buf[k + offs];
572 if (l == 0x20)
573 j--;
574 targ[j] = 0;
575}
576
577static int xl(char *buf, int offs)
578{
579 int v, k;
580
581 v = 0;
582 for (k = 0; k < 4; k++)
583 v = v * 256 + (buf[k + offs] & 0xff);
584 return v;
585}
586
587static void pf_get_capacity(struct pf_unit *pf)
588{
589 char rc_cmd[12] = { ATAPI_CAPACITY, pf->lun << 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
590 char buf[8];
591 int bs;
592
593 if (pf_atapi(pf, rc_cmd, 8, buf, DBMSG("get capacity"))) {
594 pf->media_status = PF_NM;
595 return;
596 }
597 set_capacity(pf->disk, xl(buf, 0) + 1);
598 bs = xl(buf, 4);
599 if (bs != 512) {
600 set_capacity(pf->disk, 0);
601 if (verbose)
602 printk("%s: Drive %d, LUN %d,"
603 " unsupported block size %d\n",
604 pf->name, pf->drive, pf->lun, bs);
605 }
606}
607
608static int pf_identify(struct pf_unit *pf)
609{
610 int dt, s;
611 char *ms[2] = { "master", "slave" };
612 char mf[10], id[18];
613 char id_cmd[12] =
614 { ATAPI_IDENTIFY, pf->lun << 5, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0 };
615 char buf[36];
616
617 s = pf_atapi(pf, id_cmd, 36, buf, "identify");
618 if (s)
619 return -1;
620
621 dt = buf[0] & 0x1f;
622 if ((dt != 0) && (dt != 7)) {
623 if (verbose)
624 printk("%s: Drive %d, LUN %d, unsupported type %d\n",
625 pf->name, pf->drive, pf->lun, dt);
626 return -1;
627 }
628
629 xs(buf, mf, 8, 8);
630 xs(buf, id, 16, 16);
631
632 pf->removable = (buf[1] & 0x80);
633
634 pf_mode_sense(pf);
635 pf_mode_sense(pf);
636 pf_mode_sense(pf);
637
638 pf_get_capacity(pf);
639
640 printk("%s: %s %s, %s LUN %d, type %d",
641 pf->name, mf, id, ms[pf->drive], pf->lun, dt);
642 if (pf->removable)
643 printk(", removable");
644 if (pf->media_status == PF_NM)
645 printk(", no media\n");
646 else {
647 if (pf->media_status == PF_RO)
648 printk(", RO");
649 printk(", %llu blocks\n",
650 (unsigned long long)get_capacity(pf->disk));
651 }
652 return 0;
653}
654
655/* returns 0, with id set if drive is detected
656 -1, if drive detection failed
657*/
658static int pf_probe(struct pf_unit *pf)
659{
660 if (pf->drive == -1) {
661 for (pf->drive = 0; pf->drive <= 1; pf->drive++)
662 if (!pf_reset(pf)) {
663 if (pf->lun != -1)
664 return pf_identify(pf);
665 else
666 for (pf->lun = 0; pf->lun < 8; pf->lun++)
667 if (!pf_identify(pf))
668 return 0;
669 }
670 } else {
671 if (pf_reset(pf))
672 return -1;
673 if (pf->lun != -1)
674 return pf_identify(pf);
675 for (pf->lun = 0; pf->lun < 8; pf->lun++)
676 if (!pf_identify(pf))
677 return 0;
678 }
679 return -1;
680}
681
682static int pf_detect(void)
683{
684 struct pf_unit *pf = units;
685 int k, unit;
686
687 printk("%s: %s version %s, major %d, cluster %d, nice %d\n",
688 name, name, PF_VERSION, major, cluster, nice);
689
690 k = 0;
691 if (pf_drive_count == 0) {
692 if (pi_init(pf->pi, 1, -1, -1, -1, -1, -1, pf_scratch, PI_PF,
693 verbose, pf->name)) {
694 if (!pf_probe(pf) && pf->disk) {
695 pf->present = 1;
696 k++;
697 } else
698 pi_release(pf->pi);
699 }
700
701 } else
702 for (unit = 0; unit < PF_UNITS; unit++, pf++) {
703 int *conf = *drives[unit];
704 if (!conf[D_PRT])
705 continue;
706 if (pi_init(pf->pi, 0, conf[D_PRT], conf[D_MOD],
707 conf[D_UNI], conf[D_PRO], conf[D_DLY],
708 pf_scratch, PI_PF, verbose, pf->name)) {
709 if (!pf_probe(pf) && pf->disk) {
710 pf->present = 1;
711 k++;
712 } else
713 pi_release(pf->pi);
714 }
715 }
716 if (k)
717 return 0;
718
719 printk("%s: No ATAPI disk detected\n", name);
720 for (pf = units, unit = 0; unit < PF_UNITS; pf++, unit++)
721 put_disk(pf->disk);
722 return -1;
723}
724
725/* The i/o request engine */
726
727static int pf_start(struct pf_unit *pf, int cmd, int b, int c)
728{
729 int i;
730 char io_cmd[12] = { cmd, pf->lun << 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
731
732 for (i = 0; i < 4; i++) {
733 io_cmd[5 - i] = b & 0xff;
734 b = b >> 8;
735 }
736
737 io_cmd[8] = c & 0xff;
738 io_cmd[7] = (c >> 8) & 0xff;
739
740 i = pf_command(pf, io_cmd, c * 512, "start i/o");
741
742 mdelay(1);
743
744 return i;
745}
746
747static int pf_ready(void)
748{
749 return (((status_reg(pf_current) & (STAT_BUSY | pf_mask)) == pf_mask));
750}
751
752static struct request_queue *pf_queue;
753
754static void do_pf_request(request_queue_t * q)
755{
756 if (pf_busy)
757 return;
758repeat:
759 pf_req = elv_next_request(q);
760 if (!pf_req)
761 return;
762
763 pf_current = pf_req->rq_disk->private_data;
764 pf_block = pf_req->sector;
765 pf_run = pf_req->nr_sectors;
766 pf_count = pf_req->current_nr_sectors;
767
768 if (pf_block + pf_count > get_capacity(pf_req->rq_disk)) {
769 end_request(pf_req, 0);
770 goto repeat;
771 }
772
773 pf_cmd = rq_data_dir(pf_req);
774 pf_buf = pf_req->buffer;
775 pf_retries = 0;
776
777 pf_busy = 1;
778 if (pf_cmd == READ)
779 pi_do_claimed(pf_current->pi, do_pf_read);
780 else if (pf_cmd == WRITE)
781 pi_do_claimed(pf_current->pi, do_pf_write);
782 else {
783 pf_busy = 0;
784 end_request(pf_req, 0);
785 goto repeat;
786 }
787}
788
789static int pf_next_buf(void)
790{
791 unsigned long saved_flags;
792
793 pf_count--;
794 pf_run--;
795 pf_buf += 512;
796 pf_block++;
797 if (!pf_run)
798 return 0;
799 if (!pf_count)
800 return 1;
801 spin_lock_irqsave(&pf_spin_lock, saved_flags);
802 end_request(pf_req, 1);
803 pf_count = pf_req->current_nr_sectors;
804 pf_buf = pf_req->buffer;
805 spin_unlock_irqrestore(&pf_spin_lock, saved_flags);
806 return 1;
807}
808
809static inline void next_request(int success)
810{
811 unsigned long saved_flags;
812
813 spin_lock_irqsave(&pf_spin_lock, saved_flags);
814 end_request(pf_req, success);
815 pf_busy = 0;
816 do_pf_request(pf_queue);
817 spin_unlock_irqrestore(&pf_spin_lock, saved_flags);
818}
819
820/* detach from the calling context - in case the spinlock is held */
821static void do_pf_read(void)
822{
823 ps_set_intr(do_pf_read_start, NULL, 0, nice);
824}
825
826static void do_pf_read_start(void)
827{
828 pf_busy = 1;
829
830 if (pf_start(pf_current, ATAPI_READ_10, pf_block, pf_run)) {
831 pi_disconnect(pf_current->pi);
832 if (pf_retries < PF_MAX_RETRIES) {
833 pf_retries++;
834 pi_do_claimed(pf_current->pi, do_pf_read_start);
835 return;
836 }
837 next_request(0);
838 return;
839 }
840 pf_mask = STAT_DRQ;
841 ps_set_intr(do_pf_read_drq, pf_ready, PF_TMO, nice);
842}
843
844static void do_pf_read_drq(void)
845{
846 while (1) {
847 if (pf_wait(pf_current, STAT_BUSY, STAT_DRQ | STAT_ERR,
848 "read block", "completion") & STAT_ERR) {
849 pi_disconnect(pf_current->pi);
850 if (pf_retries < PF_MAX_RETRIES) {
851 pf_req_sense(pf_current, 0);
852 pf_retries++;
853 pi_do_claimed(pf_current->pi, do_pf_read_start);
854 return;
855 }
856 next_request(0);
857 return;
858 }
859 pi_read_block(pf_current->pi, pf_buf, 512);
860 if (pf_next_buf())
861 break;
862 }
863 pi_disconnect(pf_current->pi);
864 next_request(1);
865}
866
867static void do_pf_write(void)
868{
869 ps_set_intr(do_pf_write_start, NULL, 0, nice);
870}
871
872static void do_pf_write_start(void)
873{
874 pf_busy = 1;
875
876 if (pf_start(pf_current, ATAPI_WRITE_10, pf_block, pf_run)) {
877 pi_disconnect(pf_current->pi);
878 if (pf_retries < PF_MAX_RETRIES) {
879 pf_retries++;
880 pi_do_claimed(pf_current->pi, do_pf_write_start);
881 return;
882 }
883 next_request(0);
884 return;
885 }
886
887 while (1) {
888 if (pf_wait(pf_current, STAT_BUSY, STAT_DRQ | STAT_ERR,
889 "write block", "data wait") & STAT_ERR) {
890 pi_disconnect(pf_current->pi);
891 if (pf_retries < PF_MAX_RETRIES) {
892 pf_retries++;
893 pi_do_claimed(pf_current->pi, do_pf_write_start);
894 return;
895 }
896 next_request(0);
897 return;
898 }
899 pi_write_block(pf_current->pi, pf_buf, 512);
900 if (pf_next_buf())
901 break;
902 }
903 pf_mask = 0;
904 ps_set_intr(do_pf_write_done, pf_ready, PF_TMO, nice);
905}
906
907static void do_pf_write_done(void)
908{
909 if (pf_wait(pf_current, STAT_BUSY, 0, "write block", "done") & STAT_ERR) {
910 pi_disconnect(pf_current->pi);
911 if (pf_retries < PF_MAX_RETRIES) {
912 pf_retries++;
913 pi_do_claimed(pf_current->pi, do_pf_write_start);
914 return;
915 }
916 next_request(0);
917 return;
918 }
919 pi_disconnect(pf_current->pi);
920 next_request(1);
921}
922
923static int __init pf_init(void)
924{ /* preliminary initialisation */
925 struct pf_unit *pf;
926 int unit;
927
928 if (disable)
929 return -1;
930
931 pf_init_units();
932
933 if (pf_detect())
934 return -1;
935 pf_busy = 0;
936
937 if (register_blkdev(major, name)) {
938 for (pf = units, unit = 0; unit < PF_UNITS; pf++, unit++)
939 put_disk(pf->disk);
940 return -1;
941 }
942 pf_queue = blk_init_queue(do_pf_request, &pf_spin_lock);
943 if (!pf_queue) {
944 unregister_blkdev(major, name);
945 for (pf = units, unit = 0; unit < PF_UNITS; pf++, unit++)
946 put_disk(pf->disk);
947 return -1;
948 }
949
950 blk_queue_max_phys_segments(pf_queue, cluster);
951 blk_queue_max_hw_segments(pf_queue, cluster);
952
953 for (pf = units, unit = 0; unit < PF_UNITS; pf++, unit++) {
954 struct gendisk *disk = pf->disk;
955
956 if (!pf->present)
957 continue;
958 disk->private_data = pf;
959 disk->queue = pf_queue;
960 add_disk(disk);
961 }
962 return 0;
963}
964
965static void __exit pf_exit(void)
966{
967 struct pf_unit *pf;
968 int unit;
969 unregister_blkdev(major, name);
970 for (pf = units, unit = 0; unit < PF_UNITS; pf++, unit++) {
971 if (!pf->present)
972 continue;
973 del_gendisk(pf->disk);
974 put_disk(pf->disk);
975 pi_release(pf->pi);
976 }
977 blk_cleanup_queue(pf_queue);
978}
979
980MODULE_LICENSE("GPL");
981module_init(pf_init)
982module_exit(pf_exit)
diff --git a/drivers/block/paride/pg.c b/drivers/block/paride/pg.c
new file mode 100644
index 000000000000..dbeb107bb971
--- /dev/null
+++ b/drivers/block/paride/pg.c
@@ -0,0 +1,723 @@
1/*
2 pg.c (c) 1998 Grant R. Guenther <grant@torque.net>
3 Under the terms of the GNU General Public License.
4
5 The pg driver provides a simple character device interface for
6 sending ATAPI commands to a device. With the exception of the
7 ATAPI reset operation, all operations are performed by a pair
8 of read and write operations to the appropriate /dev/pgN device.
9 A write operation delivers a command and any outbound data in
10 a single buffer. Normally, the write will succeed unless the
11 device is offline or malfunctioning, or there is already another
12 command pending. If the write succeeds, it should be followed
13 immediately by a read operation, to obtain any returned data and
14 status information. A read will fail if there is no operation
15 in progress.
16
17 As a special case, the device can be reset with a write operation,
18 and in this case, no following read is expected, or permitted.
19
20 There are no ioctl() operations. Any single operation
21 may transfer at most PG_MAX_DATA bytes. Note that the driver must
22 copy the data through an internal buffer. In keeping with all
23 current ATAPI devices, command packets are assumed to be exactly
24 12 bytes in length.
25
26 To permit future changes to this interface, the headers in the
27 read and write buffers contain a single character "magic" flag.
28 Currently this flag must be the character "P".
29
30 By default, the driver will autoprobe for a single parallel
31 port ATAPI device, but if their individual parameters are
32 specified, the driver can handle up to 4 devices.
33
34 To use this device, you must have the following device
35 special files defined:
36
37 /dev/pg0 c 97 0
38 /dev/pg1 c 97 1
39 /dev/pg2 c 97 2
40 /dev/pg3 c 97 3
41
42 (You'll need to change the 97 to something else if you use
43 the 'major' parameter to install the driver on a different
44 major number.)
45
46 The behaviour of the pg driver can be altered by setting
47 some parameters from the insmod command line. The following
48 parameters are adjustable:
49
50 drive0 These four arguments can be arrays of
51 drive1 1-6 integers as follows:
52 drive2
53 drive3 <prt>,<pro>,<uni>,<mod>,<slv>,<dly>
54
55 Where,
56
57 <prt> is the base of the parallel port address for
58 the corresponding drive. (required)
59
60 <pro> is the protocol number for the adapter that
61 supports this drive. These numbers are
62 logged by 'paride' when the protocol modules
63 are initialised. (0 if not given)
64
65 <uni> for those adapters that support chained
66 devices, this is the unit selector for the
67 chain of devices on the given port. It should
68 be zero for devices that don't support chaining.
69 (0 if not given)
70
71 <mod> this can be -1 to choose the best mode, or one
72 of the mode numbers supported by the adapter.
73 (-1 if not given)
74
75 <slv> ATAPI devices can be jumpered to master or slave.
76 Set this to 0 to choose the master drive, 1 to
77 choose the slave, -1 (the default) to choose the
78 first drive found.
79
80 <dly> some parallel ports require the driver to
81 go more slowly. -1 sets a default value that
82 should work with the chosen protocol. Otherwise,
83 set this to a small integer, the larger it is
84 the slower the port i/o. In some cases, setting
85 this to zero will speed up the device. (default -1)
86
87 major You may use this parameter to overide the
88 default major number (97) that this driver
89 will use. Be sure to change the device
90 name as well.
91
92 name This parameter is a character string that
93 contains the name the kernel will use for this
94 device (in /proc output, for instance).
95 (default "pg").
96
97 verbose This parameter controls the amount of logging
98 that is done by the driver. Set it to 0 for
99 quiet operation, to 1 to enable progress
100 messages while the driver probes for devices,
101 or to 2 for full debug logging. (default 0)
102
103 If this driver is built into the kernel, you can use
104 the following command line parameters, with the same values
105 as the corresponding module parameters listed above:
106
107 pg.drive0
108 pg.drive1
109 pg.drive2
110 pg.drive3
111
112 In addition, you can use the parameter pg.disable to disable
113 the driver entirely.
114
115*/
116
117/* Changes:
118
119 1.01 GRG 1998.06.16 Bug fixes
120 1.02 GRG 1998.09.24 Added jumbo support
121
122*/
123
124#define PG_VERSION "1.02"
125#define PG_MAJOR 97
126#define PG_NAME "pg"
127#define PG_UNITS 4
128
129#ifndef PI_PG
130#define PI_PG 4
131#endif
132
133/* Here are things one can override from the insmod command.
134 Most are autoprobed by paride unless set here. Verbose is 0
135 by default.
136
137*/
138
139static int verbose = 0;
140static int major = PG_MAJOR;
141static char *name = PG_NAME;
142static int disable = 0;
143
144static int drive0[6] = { 0, 0, 0, -1, -1, -1 };
145static int drive1[6] = { 0, 0, 0, -1, -1, -1 };
146static int drive2[6] = { 0, 0, 0, -1, -1, -1 };
147static int drive3[6] = { 0, 0, 0, -1, -1, -1 };
148
149static int (*drives[4])[6] = {&drive0, &drive1, &drive2, &drive3};
150static int pg_drive_count;
151
152enum {D_PRT, D_PRO, D_UNI, D_MOD, D_SLV, D_DLY};
153
154/* end of parameters */
155
156#include <linux/module.h>
157#include <linux/init.h>
158#include <linux/fs.h>
159#include <linux/devfs_fs_kernel.h>
160#include <linux/delay.h>
161#include <linux/slab.h>
162#include <linux/mtio.h>
163#include <linux/pg.h>
164#include <linux/device.h>
165
166#include <asm/uaccess.h>
167
168module_param(verbose, bool, 0644);
169module_param(major, int, 0);
170module_param(name, charp, 0);
171module_param_array(drive0, int, NULL, 0);
172module_param_array(drive1, int, NULL, 0);
173module_param_array(drive2, int, NULL, 0);
174module_param_array(drive3, int, NULL, 0);
175
176#include "paride.h"
177
178#define PG_SPIN_DEL 50 /* spin delay in micro-seconds */
179#define PG_SPIN 200
180#define PG_TMO HZ
181#define PG_RESET_TMO 10*HZ
182
183#define STAT_ERR 0x01
184#define STAT_INDEX 0x02
185#define STAT_ECC 0x04
186#define STAT_DRQ 0x08
187#define STAT_SEEK 0x10
188#define STAT_WRERR 0x20
189#define STAT_READY 0x40
190#define STAT_BUSY 0x80
191
192#define ATAPI_IDENTIFY 0x12
193
194static int pg_open(struct inode *inode, struct file *file);
195static int pg_release(struct inode *inode, struct file *file);
196static ssize_t pg_read(struct file *filp, char __user *buf,
197 size_t count, loff_t * ppos);
198static ssize_t pg_write(struct file *filp, const char __user *buf,
199 size_t count, loff_t * ppos);
200static int pg_detect(void);
201
202#define PG_NAMELEN 8
203
204struct pg {
205 struct pi_adapter pia; /* interface to paride layer */
206 struct pi_adapter *pi;
207 int busy; /* write done, read expected */
208 int start; /* jiffies at command start */
209 int dlen; /* transfer size requested */
210 unsigned long timeout; /* timeout requested */
211 int status; /* last sense key */
212 int drive; /* drive */
213 unsigned long access; /* count of active opens ... */
214 int present; /* device present ? */
215 char *bufptr;
216 char name[PG_NAMELEN]; /* pg0, pg1, ... */
217};
218
219static struct pg devices[PG_UNITS];
220
221static int pg_identify(struct pg *dev, int log);
222
223static char pg_scratch[512]; /* scratch block buffer */
224
225static struct class_simple *pg_class;
226
227/* kernel glue structures */
228
229static struct file_operations pg_fops = {
230 .owner = THIS_MODULE,
231 .read = pg_read,
232 .write = pg_write,
233 .open = pg_open,
234 .release = pg_release,
235};
236
237static void pg_init_units(void)
238{
239 int unit;
240
241 pg_drive_count = 0;
242 for (unit = 0; unit < PG_UNITS; unit++) {
243 int *parm = *drives[unit];
244 struct pg *dev = &devices[unit];
245 dev->pi = &dev->pia;
246 clear_bit(0, &dev->access);
247 dev->busy = 0;
248 dev->present = 0;
249 dev->bufptr = NULL;
250 dev->drive = parm[D_SLV];
251 snprintf(dev->name, PG_NAMELEN, "%s%c", name, 'a'+unit);
252 if (parm[D_PRT])
253 pg_drive_count++;
254 }
255}
256
257static inline int status_reg(struct pg *dev)
258{
259 return pi_read_regr(dev->pi, 1, 6);
260}
261
262static inline int read_reg(struct pg *dev, int reg)
263{
264 return pi_read_regr(dev->pi, 0, reg);
265}
266
267static inline void write_reg(struct pg *dev, int reg, int val)
268{
269 pi_write_regr(dev->pi, 0, reg, val);
270}
271
272static inline u8 DRIVE(struct pg *dev)
273{
274 return 0xa0+0x10*dev->drive;
275}
276
277static void pg_sleep(int cs)
278{
279 current->state = TASK_INTERRUPTIBLE;
280 schedule_timeout(cs);
281}
282
283static int pg_wait(struct pg *dev, int go, int stop, unsigned long tmo, char *msg)
284{
285 int j, r, e, s, p, to;
286
287 dev->status = 0;
288
289 j = 0;
290 while ((((r = status_reg(dev)) & go) || (stop && (!(r & stop))))
291 && time_before(jiffies, tmo)) {
292 if (j++ < PG_SPIN)
293 udelay(PG_SPIN_DEL);
294 else
295 pg_sleep(1);
296 }
297
298 to = time_after_eq(jiffies, tmo);
299
300 if ((r & (STAT_ERR & stop)) || to) {
301 s = read_reg(dev, 7);
302 e = read_reg(dev, 1);
303 p = read_reg(dev, 2);
304 if (verbose > 1)
305 printk("%s: %s: stat=0x%x err=0x%x phase=%d%s\n",
306 dev->name, msg, s, e, p, to ? " timeout" : "");
307 if (to)
308 e |= 0x100;
309 dev->status = (e >> 4) & 0xff;
310 return -1;
311 }
312 return 0;
313}
314
315static int pg_command(struct pg *dev, char *cmd, int dlen, unsigned long tmo)
316{
317 int k;
318
319 pi_connect(dev->pi);
320
321 write_reg(dev, 6, DRIVE(dev));
322
323 if (pg_wait(dev, STAT_BUSY | STAT_DRQ, 0, tmo, "before command"))
324 goto fail;
325
326 write_reg(dev, 4, dlen % 256);
327 write_reg(dev, 5, dlen / 256);
328 write_reg(dev, 7, 0xa0); /* ATAPI packet command */
329
330 if (pg_wait(dev, STAT_BUSY, STAT_DRQ, tmo, "command DRQ"))
331 goto fail;
332
333 if (read_reg(dev, 2) != 1) {
334 printk("%s: command phase error\n", dev->name);
335 goto fail;
336 }
337
338 pi_write_block(dev->pi, cmd, 12);
339
340 if (verbose > 1) {
341 printk("%s: Command sent, dlen=%d packet= ", dev->name, dlen);
342 for (k = 0; k < 12; k++)
343 printk("%02x ", cmd[k] & 0xff);
344 printk("\n");
345 }
346 return 0;
347fail:
348 pi_disconnect(dev->pi);
349 return -1;
350}
351
352static int pg_completion(struct pg *dev, char *buf, unsigned long tmo)
353{
354 int r, d, n, p;
355
356 r = pg_wait(dev, STAT_BUSY, STAT_DRQ | STAT_READY | STAT_ERR,
357 tmo, "completion");
358
359 dev->dlen = 0;
360
361 while (read_reg(dev, 7) & STAT_DRQ) {
362 d = (read_reg(dev, 4) + 256 * read_reg(dev, 5));
363 n = ((d + 3) & 0xfffc);
364 p = read_reg(dev, 2) & 3;
365 if (p == 0)
366 pi_write_block(dev->pi, buf, n);
367 if (p == 2)
368 pi_read_block(dev->pi, buf, n);
369 if (verbose > 1)
370 printk("%s: %s %d bytes\n", dev->name,
371 p ? "Read" : "Write", n);
372 dev->dlen += (1 - p) * d;
373 buf += d;
374 r = pg_wait(dev, STAT_BUSY, STAT_DRQ | STAT_READY | STAT_ERR,
375 tmo, "completion");
376 }
377
378 pi_disconnect(dev->pi);
379
380 return r;
381}
382
383static int pg_reset(struct pg *dev)
384{
385 int i, k, err;
386 int expect[5] = { 1, 1, 1, 0x14, 0xeb };
387 int got[5];
388
389 pi_connect(dev->pi);
390 write_reg(dev, 6, DRIVE(dev));
391 write_reg(dev, 7, 8);
392
393 pg_sleep(20 * HZ / 1000);
394
395 k = 0;
396 while ((k++ < PG_RESET_TMO) && (status_reg(dev) & STAT_BUSY))
397 pg_sleep(1);
398
399 for (i = 0; i < 5; i++)
400 got[i] = read_reg(dev, i + 1);
401
402 err = memcmp(expect, got, sizeof(got)) ? -1 : 0;
403
404 if (verbose) {
405 printk("%s: Reset (%d) signature = ", dev->name, k);
406 for (i = 0; i < 5; i++)
407 printk("%3x", got[i]);
408 if (err)
409 printk(" (incorrect)");
410 printk("\n");
411 }
412
413 pi_disconnect(dev->pi);
414 return err;
415}
416
417static void xs(char *buf, char *targ, int len)
418{
419 char l = '\0';
420 int k;
421
422 for (k = 0; k < len; k++) {
423 char c = *buf++;
424 if (c != ' ' || c != l)
425 l = *targ++ = c;
426 }
427 if (l == ' ')
428 targ--;
429 *targ = '\0';
430}
431
432static int pg_identify(struct pg *dev, int log)
433{
434 int s;
435 char *ms[2] = { "master", "slave" };
436 char mf[10], id[18];
437 char id_cmd[12] = { ATAPI_IDENTIFY, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0 };
438 char buf[36];
439
440 s = pg_command(dev, id_cmd, 36, jiffies + PG_TMO);
441 if (s)
442 return -1;
443 s = pg_completion(dev, buf, jiffies + PG_TMO);
444 if (s)
445 return -1;
446
447 if (log) {
448 xs(buf + 8, mf, 8);
449 xs(buf + 16, id, 16);
450 printk("%s: %s %s, %s\n", dev->name, mf, id, ms[dev->drive]);
451 }
452
453 return 0;
454}
455
456/*
457 * returns 0, with id set if drive is detected
458 * -1, if drive detection failed
459 */
460static int pg_probe(struct pg *dev)
461{
462 if (dev->drive == -1) {
463 for (dev->drive = 0; dev->drive <= 1; dev->drive++)
464 if (!pg_reset(dev))
465 return pg_identify(dev, 1);
466 } else {
467 if (!pg_reset(dev))
468 return pg_identify(dev, 1);
469 }
470 return -1;
471}
472
473static int pg_detect(void)
474{
475 struct pg *dev = &devices[0];
476 int k, unit;
477
478 printk("%s: %s version %s, major %d\n", name, name, PG_VERSION, major);
479
480 k = 0;
481 if (pg_drive_count == 0) {
482 if (pi_init(dev->pi, 1, -1, -1, -1, -1, -1, pg_scratch,
483 PI_PG, verbose, dev->name)) {
484 if (!pg_probe(dev)) {
485 dev->present = 1;
486 k++;
487 } else
488 pi_release(dev->pi);
489 }
490
491 } else
492 for (unit = 0; unit < PG_UNITS; unit++, dev++) {
493 int *parm = *drives[unit];
494 if (!parm[D_PRT])
495 continue;
496 if (pi_init(dev->pi, 0, parm[D_PRT], parm[D_MOD],
497 parm[D_UNI], parm[D_PRO], parm[D_DLY],
498 pg_scratch, PI_PG, verbose, dev->name)) {
499 if (!pg_probe(dev)) {
500 dev->present = 1;
501 k++;
502 } else
503 pi_release(dev->pi);
504 }
505 }
506
507 if (k)
508 return 0;
509
510 printk("%s: No ATAPI device detected\n", name);
511 return -1;
512}
513
514static int pg_open(struct inode *inode, struct file *file)
515{
516 int unit = iminor(inode) & 0x7f;
517 struct pg *dev = &devices[unit];
518
519 if ((unit >= PG_UNITS) || (!dev->present))
520 return -ENODEV;
521
522 if (test_and_set_bit(0, &dev->access))
523 return -EBUSY;
524
525 if (dev->busy) {
526 pg_reset(dev);
527 dev->busy = 0;
528 }
529
530 pg_identify(dev, (verbose > 1));
531
532 dev->bufptr = kmalloc(PG_MAX_DATA, GFP_KERNEL);
533 if (dev->bufptr == NULL) {
534 clear_bit(0, &dev->access);
535 printk("%s: buffer allocation failed\n", dev->name);
536 return -ENOMEM;
537 }
538
539 file->private_data = dev;
540
541 return 0;
542}
543
544static int pg_release(struct inode *inode, struct file *file)
545{
546 struct pg *dev = file->private_data;
547
548 kfree(dev->bufptr);
549 dev->bufptr = NULL;
550 clear_bit(0, &dev->access);
551
552 return 0;
553}
554
555static ssize_t pg_write(struct file *filp, const char __user *buf, size_t count, loff_t *ppos)
556{
557 struct pg *dev = filp->private_data;
558 struct pg_write_hdr hdr;
559 int hs = sizeof (hdr);
560
561 if (dev->busy)
562 return -EBUSY;
563 if (count < hs)
564 return -EINVAL;
565
566 if (copy_from_user(&hdr, buf, hs))
567 return -EFAULT;
568
569 if (hdr.magic != PG_MAGIC)
570 return -EINVAL;
571 if (hdr.dlen > PG_MAX_DATA)
572 return -EINVAL;
573 if ((count - hs) > PG_MAX_DATA)
574 return -EINVAL;
575
576 if (hdr.func == PG_RESET) {
577 if (count != hs)
578 return -EINVAL;
579 if (pg_reset(dev))
580 return -EIO;
581 return count;
582 }
583
584 if (hdr.func != PG_COMMAND)
585 return -EINVAL;
586
587 dev->start = jiffies;
588 dev->timeout = hdr.timeout * HZ + HZ / 2 + jiffies;
589
590 if (pg_command(dev, hdr.packet, hdr.dlen, jiffies + PG_TMO)) {
591 if (dev->status & 0x10)
592 return -ETIME;
593 return -EIO;
594 }
595
596 dev->busy = 1;
597
598 if (copy_from_user(dev->bufptr, buf + hs, count - hs))
599 return -EFAULT;
600 return count;
601}
602
603static ssize_t pg_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos)
604{
605 struct pg *dev = filp->private_data;
606 struct pg_read_hdr hdr;
607 int hs = sizeof (hdr);
608 int copy;
609
610 if (!dev->busy)
611 return -EINVAL;
612 if (count < hs)
613 return -EINVAL;
614
615 dev->busy = 0;
616
617 if (pg_completion(dev, dev->bufptr, dev->timeout))
618 if (dev->status & 0x10)
619 return -ETIME;
620
621 hdr.magic = PG_MAGIC;
622 hdr.dlen = dev->dlen;
623 copy = 0;
624
625 if (hdr.dlen < 0) {
626 hdr.dlen = -1 * hdr.dlen;
627 copy = hdr.dlen;
628 if (copy > (count - hs))
629 copy = count - hs;
630 }
631
632 hdr.duration = (jiffies - dev->start + HZ / 2) / HZ;
633 hdr.scsi = dev->status & 0x0f;
634
635 if (copy_to_user(buf, &hdr, hs))
636 return -EFAULT;
637 if (copy > 0)
638 if (copy_to_user(buf + hs, dev->bufptr, copy))
639 return -EFAULT;
640 return copy + hs;
641}
642
643static int __init pg_init(void)
644{
645 int unit, err = 0;
646
647 if (disable){
648 err = -1;
649 goto out;
650 }
651
652 pg_init_units();
653
654 if (pg_detect()) {
655 err = -1;
656 goto out;
657 }
658
659 if (register_chrdev(major, name, &pg_fops)) {
660 printk("pg_init: unable to get major number %d\n", major);
661 for (unit = 0; unit < PG_UNITS; unit++) {
662 struct pg *dev = &devices[unit];
663 if (dev->present)
664 pi_release(dev->pi);
665 }
666 err = -1;
667 goto out;
668 }
669 pg_class = class_simple_create(THIS_MODULE, "pg");
670 if (IS_ERR(pg_class)) {
671 err = PTR_ERR(pg_class);
672 goto out_chrdev;
673 }
674 devfs_mk_dir("pg");
675 for (unit = 0; unit < PG_UNITS; unit++) {
676 struct pg *dev = &devices[unit];
677 if (dev->present) {
678 class_simple_device_add(pg_class, MKDEV(major, unit),
679 NULL, "pg%u", unit);
680 err = devfs_mk_cdev(MKDEV(major, unit),
681 S_IFCHR | S_IRUSR | S_IWUSR, "pg/%u",
682 unit);
683 if (err)
684 goto out_class;
685 }
686 }
687 err = 0;
688 goto out;
689
690out_class:
691 class_simple_device_remove(MKDEV(major, unit));
692 class_simple_destroy(pg_class);
693out_chrdev:
694 unregister_chrdev(major, "pg");
695out:
696 return err;
697}
698
699static void __exit pg_exit(void)
700{
701 int unit;
702
703 for (unit = 0; unit < PG_UNITS; unit++) {
704 struct pg *dev = &devices[unit];
705 if (dev->present) {
706 class_simple_device_remove(MKDEV(major, unit));
707 devfs_remove("pg/%u", unit);
708 }
709 }
710 class_simple_destroy(pg_class);
711 devfs_remove("pg");
712 unregister_chrdev(major, name);
713
714 for (unit = 0; unit < PG_UNITS; unit++) {
715 struct pg *dev = &devices[unit];
716 if (dev->present)
717 pi_release(dev->pi);
718 }
719}
720
721MODULE_LICENSE("GPL");
722module_init(pg_init)
723module_exit(pg_exit)
diff --git a/drivers/block/paride/ppc6lnx.c b/drivers/block/paride/ppc6lnx.c
new file mode 100644
index 000000000000..5e5521d3b1dd
--- /dev/null
+++ b/drivers/block/paride/ppc6lnx.c
@@ -0,0 +1,726 @@
1/*
2 ppc6lnx.c (c) 2001 Micro Solutions Inc.
3 Released under the terms of the GNU General Public license
4
5 ppc6lnx.c is a par of the protocol driver for the Micro Solutions
6 "BACKPACK" parallel port IDE adapter
7 (Works on Series 6 drives)
8
9*/
10
11//***************************************************************************
12
13// PPC 6 Code in C sanitized for LINUX
14// Original x86 ASM by Ron, Converted to C by Clive
15
16//***************************************************************************
17
18
19#define port_stb 1
20#define port_afd 2
21#define cmd_stb port_afd
22#define port_init 4
23#define data_stb port_init
24#define port_sel 8
25#define port_int 16
26#define port_dir 0x20
27
28#define ECR_EPP 0x80
29#define ECR_BI 0x20
30
31//***************************************************************************
32
33// 60772 Commands
34
35#define ACCESS_REG 0x00
36#define ACCESS_PORT 0x40
37
38#define ACCESS_READ 0x00
39#define ACCESS_WRITE 0x20
40
41// 60772 Command Prefix
42
43#define CMD_PREFIX_SET 0xe0 // Special command that modifies the next command's operation
44#define CMD_PREFIX_RESET 0xc0 // Resets current cmd modifier reg bits
45 #define PREFIX_IO16 0x01 // perform 16-bit wide I/O
46 #define PREFIX_FASTWR 0x04 // enable PPC mode fast-write
47 #define PREFIX_BLK 0x08 // enable block transfer mode
48
49// 60772 Registers
50
51#define REG_STATUS 0x00 // status register
52 #define STATUS_IRQA 0x01 // Peripheral IRQA line
53 #define STATUS_EEPROM_DO 0x40 // Serial EEPROM data bit
54#define REG_VERSION 0x01 // PPC version register (read)
55#define REG_HWCFG 0x02 // Hardware Config register
56#define REG_RAMSIZE 0x03 // Size of RAM Buffer
57 #define RAMSIZE_128K 0x02
58#define REG_EEPROM 0x06 // EEPROM control register
59 #define EEPROM_SK 0x01 // eeprom SK bit
60 #define EEPROM_DI 0x02 // eeprom DI bit
61 #define EEPROM_CS 0x04 // eeprom CS bit
62 #define EEPROM_EN 0x08 // eeprom output enable
63#define REG_BLKSIZE 0x08 // Block transfer len (24 bit)
64
65//***************************************************************************
66
67typedef struct ppc_storage {
68 u16 lpt_addr; // LPT base address
69 u8 ppc_id;
70 u8 mode; // operating mode
71 // 0 = PPC Uni SW
72 // 1 = PPC Uni FW
73 // 2 = PPC Bi SW
74 // 3 = PPC Bi FW
75 // 4 = EPP Byte
76 // 5 = EPP Word
77 // 6 = EPP Dword
78 u8 ppc_flags;
79 u8 org_data; // original LPT data port contents
80 u8 org_ctrl; // original LPT control port contents
81 u8 cur_ctrl; // current control port contents
82} Interface;
83
84//***************************************************************************
85
86// ppc_flags
87
88#define fifo_wait 0x10
89
90//***************************************************************************
91
92// DONT CHANGE THESE LEST YOU BREAK EVERYTHING - BIT FIELD DEPENDENCIES
93
94#define PPCMODE_UNI_SW 0
95#define PPCMODE_UNI_FW 1
96#define PPCMODE_BI_SW 2
97#define PPCMODE_BI_FW 3
98#define PPCMODE_EPP_BYTE 4
99#define PPCMODE_EPP_WORD 5
100#define PPCMODE_EPP_DWORD 6
101
102//***************************************************************************
103
104static int ppc6_select(Interface *ppc);
105static void ppc6_deselect(Interface *ppc);
106static void ppc6_send_cmd(Interface *ppc, u8 cmd);
107static void ppc6_wr_data_byte(Interface *ppc, u8 data);
108static u8 ppc6_rd_data_byte(Interface *ppc);
109static u8 ppc6_rd_port(Interface *ppc, u8 port);
110static void ppc6_wr_port(Interface *ppc, u8 port, u8 data);
111static void ppc6_rd_data_blk(Interface *ppc, u8 *data, long count);
112static void ppc6_wait_for_fifo(Interface *ppc);
113static void ppc6_wr_data_blk(Interface *ppc, u8 *data, long count);
114static void ppc6_rd_port16_blk(Interface *ppc, u8 port, u8 *data, long length);
115static void ppc6_wr_port16_blk(Interface *ppc, u8 port, u8 *data, long length);
116static void ppc6_wr_extout(Interface *ppc, u8 regdata);
117static int ppc6_open(Interface *ppc);
118static void ppc6_close(Interface *ppc);
119
120//***************************************************************************
121
122static int ppc6_select(Interface *ppc)
123{
124 u8 i, j, k;
125
126 i = inb(ppc->lpt_addr + 1);
127
128 if (i & 1)
129 outb(i, ppc->lpt_addr + 1);
130
131 ppc->org_data = inb(ppc->lpt_addr);
132
133 ppc->org_ctrl = inb(ppc->lpt_addr + 2) & 0x5F; // readback ctrl
134
135 ppc->cur_ctrl = ppc->org_ctrl;
136
137 ppc->cur_ctrl |= port_sel;
138
139 outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
140
141 if (ppc->org_data == 'b')
142 outb('x', ppc->lpt_addr);
143
144 outb('b', ppc->lpt_addr);
145 outb('p', ppc->lpt_addr);
146 outb(ppc->ppc_id, ppc->lpt_addr);
147 outb(~ppc->ppc_id,ppc->lpt_addr);
148
149 ppc->cur_ctrl &= ~port_sel;
150
151 outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
152
153 ppc->cur_ctrl = (ppc->cur_ctrl & port_int) | port_init;
154
155 outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
156
157 i = ppc->mode & 0x0C;
158
159 if (i == 0)
160 i = (ppc->mode & 2) | 1;
161
162 outb(i, ppc->lpt_addr);
163
164 ppc->cur_ctrl |= port_sel;
165
166 outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
167
168 // DELAY
169
170 ppc->cur_ctrl |= port_afd;
171
172 outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
173
174 j = ((i & 0x08) << 4) | ((i & 0x07) << 3);
175
176 k = inb(ppc->lpt_addr + 1) & 0xB8;
177
178 if (j == k)
179 {
180 ppc->cur_ctrl &= ~port_afd;
181
182 outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
183
184 k = (inb(ppc->lpt_addr + 1) & 0xB8) ^ 0xB8;
185
186 if (j == k)
187 {
188 if (i & 4) // EPP
189 ppc->cur_ctrl &= ~(port_sel | port_init);
190 else // PPC/ECP
191 ppc->cur_ctrl &= ~port_sel;
192
193 outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
194
195 return(1);
196 }
197 }
198
199 outb(ppc->org_ctrl, ppc->lpt_addr + 2);
200
201 outb(ppc->org_data, ppc->lpt_addr);
202
203 return(0); // FAIL
204}
205
206//***************************************************************************
207
208static void ppc6_deselect(Interface *ppc)
209{
210 if (ppc->mode & 4) // EPP
211 ppc->cur_ctrl |= port_init;
212 else // PPC/ECP
213 ppc->cur_ctrl |= port_sel;
214
215 outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
216
217 outb(ppc->org_data, ppc->lpt_addr);
218
219 outb((ppc->org_ctrl | port_sel), ppc->lpt_addr + 2);
220
221 outb(ppc->org_ctrl, ppc->lpt_addr + 2);
222}
223
224//***************************************************************************
225
226static void ppc6_send_cmd(Interface *ppc, u8 cmd)
227{
228 switch(ppc->mode)
229 {
230 case PPCMODE_UNI_SW :
231 case PPCMODE_UNI_FW :
232 case PPCMODE_BI_SW :
233 case PPCMODE_BI_FW :
234 {
235 outb(cmd, ppc->lpt_addr);
236
237 ppc->cur_ctrl ^= cmd_stb;
238
239 outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
240
241 break;
242 }
243
244 case PPCMODE_EPP_BYTE :
245 case PPCMODE_EPP_WORD :
246 case PPCMODE_EPP_DWORD :
247 {
248 outb(cmd, ppc->lpt_addr + 3);
249
250 break;
251 }
252 }
253}
254
255//***************************************************************************
256
257static void ppc6_wr_data_byte(Interface *ppc, u8 data)
258{
259 switch(ppc->mode)
260 {
261 case PPCMODE_UNI_SW :
262 case PPCMODE_UNI_FW :
263 case PPCMODE_BI_SW :
264 case PPCMODE_BI_FW :
265 {
266 outb(data, ppc->lpt_addr);
267
268 ppc->cur_ctrl ^= data_stb;
269
270 outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
271
272 break;
273 }
274
275 case PPCMODE_EPP_BYTE :
276 case PPCMODE_EPP_WORD :
277 case PPCMODE_EPP_DWORD :
278 {
279 outb(data, ppc->lpt_addr + 4);
280
281 break;
282 }
283 }
284}
285
286//***************************************************************************
287
288static u8 ppc6_rd_data_byte(Interface *ppc)
289{
290 u8 data = 0;
291
292 switch(ppc->mode)
293 {
294 case PPCMODE_UNI_SW :
295 case PPCMODE_UNI_FW :
296 {
297 ppc->cur_ctrl = (ppc->cur_ctrl & ~port_stb) ^ data_stb;
298
299 outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
300
301 // DELAY
302
303 data = inb(ppc->lpt_addr + 1);
304
305 data = ((data & 0x80) >> 1) | ((data & 0x38) >> 3);
306
307 ppc->cur_ctrl |= port_stb;
308
309 outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
310
311 // DELAY
312
313 data |= inb(ppc->lpt_addr + 1) & 0xB8;
314
315 break;
316 }
317
318 case PPCMODE_BI_SW :
319 case PPCMODE_BI_FW :
320 {
321 ppc->cur_ctrl |= port_dir;
322
323 outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
324
325 ppc->cur_ctrl = (ppc->cur_ctrl | port_stb) ^ data_stb;
326
327 outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
328
329 data = inb(ppc->lpt_addr);
330
331 ppc->cur_ctrl &= ~port_stb;
332
333 outb(ppc->cur_ctrl,ppc->lpt_addr + 2);
334
335 ppc->cur_ctrl &= ~port_dir;
336
337 outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
338
339 break;
340 }
341
342 case PPCMODE_EPP_BYTE :
343 case PPCMODE_EPP_WORD :
344 case PPCMODE_EPP_DWORD :
345 {
346 outb((ppc->cur_ctrl | port_dir),ppc->lpt_addr + 2);
347
348 data = inb(ppc->lpt_addr + 4);
349
350 outb(ppc->cur_ctrl,ppc->lpt_addr + 2);
351
352 break;
353 }
354 }
355
356 return(data);
357}
358
359//***************************************************************************
360
361static u8 ppc6_rd_port(Interface *ppc, u8 port)
362{
363 ppc6_send_cmd(ppc,(u8)(port | ACCESS_PORT | ACCESS_READ));
364
365 return(ppc6_rd_data_byte(ppc));
366}
367
368//***************************************************************************
369
370static void ppc6_wr_port(Interface *ppc, u8 port, u8 data)
371{
372 ppc6_send_cmd(ppc,(u8)(port | ACCESS_PORT | ACCESS_WRITE));
373
374 ppc6_wr_data_byte(ppc, data);
375}
376
377//***************************************************************************
378
379static void ppc6_rd_data_blk(Interface *ppc, u8 *data, long count)
380{
381 switch(ppc->mode)
382 {
383 case PPCMODE_UNI_SW :
384 case PPCMODE_UNI_FW :
385 {
386 while(count)
387 {
388 u8 d;
389
390 ppc->cur_ctrl = (ppc->cur_ctrl & ~port_stb) ^ data_stb;
391
392 outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
393
394 // DELAY
395
396 d = inb(ppc->lpt_addr + 1);
397
398 d = ((d & 0x80) >> 1) | ((d & 0x38) >> 3);
399
400 ppc->cur_ctrl |= port_stb;
401
402 outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
403
404 // DELAY
405
406 d |= inb(ppc->lpt_addr + 1) & 0xB8;
407
408 *data++ = d;
409 count--;
410 }
411
412 break;
413 }
414
415 case PPCMODE_BI_SW :
416 case PPCMODE_BI_FW :
417 {
418 ppc->cur_ctrl |= port_dir;
419
420 outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
421
422 ppc->cur_ctrl |= port_stb;
423
424 while(count)
425 {
426 ppc->cur_ctrl ^= data_stb;
427
428 outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
429
430 *data++ = inb(ppc->lpt_addr);
431 count--;
432 }
433
434 ppc->cur_ctrl &= ~port_stb;
435
436 outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
437
438 ppc->cur_ctrl &= ~port_dir;
439
440 outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
441
442 break;
443 }
444
445 case PPCMODE_EPP_BYTE :
446 {
447 outb((ppc->cur_ctrl | port_dir), ppc->lpt_addr + 2);
448
449 // DELAY
450
451 while(count)
452 {
453 *data++ = inb(ppc->lpt_addr + 4);
454 count--;
455 }
456
457 outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
458
459 break;
460 }
461
462 case PPCMODE_EPP_WORD :
463 {
464 outb((ppc->cur_ctrl | port_dir), ppc->lpt_addr + 2);
465
466 // DELAY
467
468 while(count > 1)
469 {
470 *((u16 *)data) = inw(ppc->lpt_addr + 4);
471 data += 2;
472 count -= 2;
473 }
474
475 while(count)
476 {
477 *data++ = inb(ppc->lpt_addr + 4);
478 count--;
479 }
480
481 outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
482
483 break;
484 }
485
486 case PPCMODE_EPP_DWORD :
487 {
488 outb((ppc->cur_ctrl | port_dir),ppc->lpt_addr + 2);
489
490 // DELAY
491
492 while(count > 3)
493 {
494 *((u32 *)data) = inl(ppc->lpt_addr + 4);
495 data += 4;
496 count -= 4;
497 }
498
499 while(count)
500 {
501 *data++ = inb(ppc->lpt_addr + 4);
502 count--;
503 }
504
505 outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
506
507 break;
508 }
509 }
510
511}
512
513//***************************************************************************
514
515static void ppc6_wait_for_fifo(Interface *ppc)
516{
517 int i;
518
519 if (ppc->ppc_flags & fifo_wait)
520 {
521 for(i=0; i<20; i++)
522 inb(ppc->lpt_addr + 1);
523 }
524}
525
526//***************************************************************************
527
528static void ppc6_wr_data_blk(Interface *ppc, u8 *data, long count)
529{
530 switch(ppc->mode)
531 {
532 case PPCMODE_UNI_SW :
533 case PPCMODE_BI_SW :
534 {
535 while(count--)
536 {
537 outb(*data++, ppc->lpt_addr);
538
539 ppc->cur_ctrl ^= data_stb;
540
541 outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
542 }
543
544 break;
545 }
546
547 case PPCMODE_UNI_FW :
548 case PPCMODE_BI_FW :
549 {
550 u8 this, last;
551
552 ppc6_send_cmd(ppc,(CMD_PREFIX_SET | PREFIX_FASTWR));
553
554 ppc->cur_ctrl |= port_stb;
555
556 outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
557
558 last = *data;
559
560 outb(last, ppc->lpt_addr);
561
562 while(count)
563 {
564 this = *data++;
565 count--;
566
567 if (this == last)
568 {
569 ppc->cur_ctrl ^= data_stb;
570
571 outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
572 }
573 else
574 {
575 outb(this, ppc->lpt_addr);
576
577 last = this;
578 }
579 }
580
581 ppc->cur_ctrl &= ~port_stb;
582
583 outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
584
585 ppc6_send_cmd(ppc,(CMD_PREFIX_RESET | PREFIX_FASTWR));
586
587 break;
588 }
589
590 case PPCMODE_EPP_BYTE :
591 {
592 while(count)
593 {
594 outb(*data++,ppc->lpt_addr + 4);
595 count--;
596 }
597
598 ppc6_wait_for_fifo(ppc);
599
600 break;
601 }
602
603 case PPCMODE_EPP_WORD :
604 {
605 while(count > 1)
606 {
607 outw(*((u16 *)data),ppc->lpt_addr + 4);
608 data += 2;
609 count -= 2;
610 }
611
612 while(count)
613 {
614 outb(*data++,ppc->lpt_addr + 4);
615 count--;
616 }
617
618 ppc6_wait_for_fifo(ppc);
619
620 break;
621 }
622
623 case PPCMODE_EPP_DWORD :
624 {
625 while(count > 3)
626 {
627 outl(*((u32 *)data),ppc->lpt_addr + 4);
628 data += 4;
629 count -= 4;
630 }
631
632 while(count)
633 {
634 outb(*data++,ppc->lpt_addr + 4);
635 count--;
636 }
637
638 ppc6_wait_for_fifo(ppc);
639
640 break;
641 }
642 }
643}
644
645//***************************************************************************
646
647static void ppc6_rd_port16_blk(Interface *ppc, u8 port, u8 *data, long length)
648{
649 length = length << 1;
650
651 ppc6_send_cmd(ppc, (REG_BLKSIZE | ACCESS_REG | ACCESS_WRITE));
652 ppc6_wr_data_byte(ppc,(u8)length);
653 ppc6_wr_data_byte(ppc,(u8)(length >> 8));
654 ppc6_wr_data_byte(ppc,0);
655
656 ppc6_send_cmd(ppc, (CMD_PREFIX_SET | PREFIX_IO16 | PREFIX_BLK));
657
658 ppc6_send_cmd(ppc, (u8)(port | ACCESS_PORT | ACCESS_READ));
659
660 ppc6_rd_data_blk(ppc, data, length);
661
662 ppc6_send_cmd(ppc, (CMD_PREFIX_RESET | PREFIX_IO16 | PREFIX_BLK));
663}
664
665//***************************************************************************
666
667static void ppc6_wr_port16_blk(Interface *ppc, u8 port, u8 *data, long length)
668{
669 length = length << 1;
670
671 ppc6_send_cmd(ppc, (REG_BLKSIZE | ACCESS_REG | ACCESS_WRITE));
672 ppc6_wr_data_byte(ppc,(u8)length);
673 ppc6_wr_data_byte(ppc,(u8)(length >> 8));
674 ppc6_wr_data_byte(ppc,0);
675
676 ppc6_send_cmd(ppc, (CMD_PREFIX_SET | PREFIX_IO16 | PREFIX_BLK));
677
678 ppc6_send_cmd(ppc, (u8)(port | ACCESS_PORT | ACCESS_WRITE));
679
680 ppc6_wr_data_blk(ppc, data, length);
681
682 ppc6_send_cmd(ppc, (CMD_PREFIX_RESET | PREFIX_IO16 | PREFIX_BLK));
683}
684
685//***************************************************************************
686
687static void ppc6_wr_extout(Interface *ppc, u8 regdata)
688{
689 ppc6_send_cmd(ppc,(REG_VERSION | ACCESS_REG | ACCESS_WRITE));
690
691 ppc6_wr_data_byte(ppc, (u8)((regdata & 0x03) << 6));
692}
693
694//***************************************************************************
695
696static int ppc6_open(Interface *ppc)
697{
698 int ret;
699
700 ret = ppc6_select(ppc);
701
702 if (ret == 0)
703 return(ret);
704
705 ppc->ppc_flags &= ~fifo_wait;
706
707 ppc6_send_cmd(ppc, (ACCESS_REG | ACCESS_WRITE | REG_RAMSIZE));
708 ppc6_wr_data_byte(ppc, RAMSIZE_128K);
709
710 ppc6_send_cmd(ppc, (ACCESS_REG | ACCESS_READ | REG_VERSION));
711
712 if ((ppc6_rd_data_byte(ppc) & 0x3F) == 0x0C)
713 ppc->ppc_flags |= fifo_wait;
714
715 return(ret);
716}
717
718//***************************************************************************
719
720static void ppc6_close(Interface *ppc)
721{
722 ppc6_deselect(ppc);
723}
724
725//***************************************************************************
726
diff --git a/drivers/block/paride/pseudo.h b/drivers/block/paride/pseudo.h
new file mode 100644
index 000000000000..932342d7a8eb
--- /dev/null
+++ b/drivers/block/paride/pseudo.h
@@ -0,0 +1,102 @@
1/*
2 pseudo.h (c) 1997-8 Grant R. Guenther <grant@torque.net>
3 Under the terms of the GNU General Public License.
4
5 This is the "pseudo-interrupt" logic for parallel port drivers.
6
7 This module is #included into each driver. It makes one
8 function available:
9
10 ps_set_intr( void (*continuation)(void),
11 int (*ready)(void),
12 int timeout,
13 int nice )
14
15 Which will arrange for ready() to be evaluated frequently and
16 when either it returns true, or timeout jiffies have passed,
17 continuation() will be invoked.
18
19 If nice is 1, the test will done approximately once a
20 jiffy. If nice is 0, the test will also be done whenever
21 the scheduler runs (by adding it to a task queue). If
22 nice is greater than 1, the test will be done once every
23 (nice-1) jiffies.
24
25*/
26
27/* Changes:
28
29 1.01 1998.05.03 Switched from cli()/sti() to spinlocks
30 1.02 1998.12.14 Added support for nice > 1
31*/
32
33#define PS_VERSION "1.02"
34
35#include <linux/sched.h>
36#include <linux/workqueue.h>
37
38static void ps_tq_int( void *data);
39
40static void (* ps_continuation)(void);
41static int (* ps_ready)(void);
42static unsigned long ps_timeout;
43static int ps_tq_active = 0;
44static int ps_nice = 0;
45
46static DEFINE_SPINLOCK(ps_spinlock __attribute__((unused)));
47
48static DECLARE_WORK(ps_tq, ps_tq_int, NULL);
49
50static void ps_set_intr(void (*continuation)(void),
51 int (*ready)(void),
52 int timeout, int nice)
53{
54 unsigned long flags;
55
56 spin_lock_irqsave(&ps_spinlock,flags);
57
58 ps_continuation = continuation;
59 ps_ready = ready;
60 ps_timeout = jiffies + timeout;
61 ps_nice = nice;
62
63 if (!ps_tq_active) {
64 ps_tq_active = 1;
65 if (!ps_nice)
66 schedule_work(&ps_tq);
67 else
68 schedule_delayed_work(&ps_tq, ps_nice-1);
69 }
70 spin_unlock_irqrestore(&ps_spinlock,flags);
71}
72
73static void ps_tq_int(void *data)
74{
75 void (*con)(void);
76 unsigned long flags;
77
78 spin_lock_irqsave(&ps_spinlock,flags);
79
80 con = ps_continuation;
81 ps_tq_active = 0;
82
83 if (!con) {
84 spin_unlock_irqrestore(&ps_spinlock,flags);
85 return;
86 }
87 if (!ps_ready || ps_ready() || time_after_eq(jiffies, ps_timeout)) {
88 ps_continuation = NULL;
89 spin_unlock_irqrestore(&ps_spinlock,flags);
90 con();
91 return;
92 }
93 ps_tq_active = 1;
94 if (!ps_nice)
95 schedule_work(&ps_tq);
96 else
97 schedule_delayed_work(&ps_tq, ps_nice-1);
98 spin_unlock_irqrestore(&ps_spinlock,flags);
99}
100
101/* end of pseudo.h */
102
diff --git a/drivers/block/paride/pt.c b/drivers/block/paride/pt.c
new file mode 100644
index 000000000000..8fbd6922fe0d
--- /dev/null
+++ b/drivers/block/paride/pt.c
@@ -0,0 +1,1024 @@
1/*
2 pt.c (c) 1998 Grant R. Guenther <grant@torque.net>
3 Under the terms of the GNU General Public License.
4
5 This is the high-level driver for parallel port ATAPI tape
6 drives based on chips supported by the paride module.
7
8 The driver implements both rewinding and non-rewinding
9 devices, filemarks, and the rewind ioctl. It allocates
10 a small internal "bounce buffer" for each open device, but
11 otherwise expects buffering and blocking to be done at the
12 user level. As with most block-structured tapes, short
13 writes are padded to full tape blocks, so reading back a file
14 may return more data than was actually written.
15
16 By default, the driver will autoprobe for a single parallel
17 port ATAPI tape drive, but if their individual parameters are
18 specified, the driver can handle up to 4 drives.
19
20 The rewinding devices are named /dev/pt0, /dev/pt1, ...
21 while the non-rewinding devices are /dev/npt0, /dev/npt1, etc.
22
23 The behaviour of the pt driver can be altered by setting
24 some parameters from the insmod command line. The following
25 parameters are adjustable:
26
27 drive0 These four arguments can be arrays of
28 drive1 1-6 integers as follows:
29 drive2
30 drive3 <prt>,<pro>,<uni>,<mod>,<slv>,<dly>
31
32 Where,
33
34 <prt> is the base of the parallel port address for
35 the corresponding drive. (required)
36
37 <pro> is the protocol number for the adapter that
38 supports this drive. These numbers are
39 logged by 'paride' when the protocol modules
40 are initialised. (0 if not given)
41
42 <uni> for those adapters that support chained
43 devices, this is the unit selector for the
44 chain of devices on the given port. It should
45 be zero for devices that don't support chaining.
46 (0 if not given)
47
48 <mod> this can be -1 to choose the best mode, or one
49 of the mode numbers supported by the adapter.
50 (-1 if not given)
51
52 <slv> ATAPI devices can be jumpered to master or slave.
53 Set this to 0 to choose the master drive, 1 to
54 choose the slave, -1 (the default) to choose the
55 first drive found.
56
57 <dly> some parallel ports require the driver to
58 go more slowly. -1 sets a default value that
59 should work with the chosen protocol. Otherwise,
60 set this to a small integer, the larger it is
61 the slower the port i/o. In some cases, setting
62 this to zero will speed up the device. (default -1)
63
64 major You may use this parameter to overide the
65 default major number (96) that this driver
66 will use. Be sure to change the device
67 name as well.
68
69 name This parameter is a character string that
70 contains the name the kernel will use for this
71 device (in /proc output, for instance).
72 (default "pt").
73
74 verbose This parameter controls the amount of logging
75 that the driver will do. Set it to 0 for
76 normal operation, 1 to see autoprobe progress
77 messages, or 2 to see additional debugging
78 output. (default 0)
79
80 If this driver is built into the kernel, you can use
81 the following command line parameters, with the same values
82 as the corresponding module parameters listed above:
83
84 pt.drive0
85 pt.drive1
86 pt.drive2
87 pt.drive3
88
89 In addition, you can use the parameter pt.disable to disable
90 the driver entirely.
91
92*/
93
94/* Changes:
95
96 1.01 GRG 1998.05.06 Round up transfer size, fix ready_wait,
97 loosed interpretation of ATAPI standard
98 for clearing error status.
99 Eliminate sti();
100 1.02 GRG 1998.06.16 Eliminate an Ugh.
101 1.03 GRG 1998.08.15 Adjusted PT_TMO, use HZ in loop timing,
102 extra debugging
103 1.04 GRG 1998.09.24 Repair minor coding error, added jumbo support
104
105*/
106
107#define PT_VERSION "1.04"
108#define PT_MAJOR 96
109#define PT_NAME "pt"
110#define PT_UNITS 4
111
112/* Here are things one can override from the insmod command.
113 Most are autoprobed by paride unless set here. Verbose is on
114 by default.
115
116*/
117
118static int verbose = 0;
119static int major = PT_MAJOR;
120static char *name = PT_NAME;
121static int disable = 0;
122
123static int drive0[6] = { 0, 0, 0, -1, -1, -1 };
124static int drive1[6] = { 0, 0, 0, -1, -1, -1 };
125static int drive2[6] = { 0, 0, 0, -1, -1, -1 };
126static int drive3[6] = { 0, 0, 0, -1, -1, -1 };
127
128static int (*drives[4])[6] = {&drive0, &drive1, &drive2, &drive3};
129
130#define D_PRT 0
131#define D_PRO 1
132#define D_UNI 2
133#define D_MOD 3
134#define D_SLV 4
135#define D_DLY 5
136
137#define DU (*drives[unit])
138
139/* end of parameters */
140
141#include <linux/module.h>
142#include <linux/init.h>
143#include <linux/fs.h>
144#include <linux/devfs_fs_kernel.h>
145#include <linux/delay.h>
146#include <linux/slab.h>
147#include <linux/mtio.h>
148#include <linux/device.h>
149
150#include <asm/uaccess.h>
151
152module_param(verbose, bool, 0);
153module_param(major, int, 0);
154module_param(name, charp, 0);
155module_param_array(drive0, int, NULL, 0);
156module_param_array(drive1, int, NULL, 0);
157module_param_array(drive2, int, NULL, 0);
158module_param_array(drive3, int, NULL, 0);
159
160#include "paride.h"
161
162#define PT_MAX_RETRIES 5
163#define PT_TMO 3000 /* interrupt timeout in jiffies */
164#define PT_SPIN_DEL 50 /* spin delay in micro-seconds */
165#define PT_RESET_TMO 30 /* 30 seconds */
166#define PT_READY_TMO 60 /* 60 seconds */
167#define PT_REWIND_TMO 1200 /* 20 minutes */
168
169#define PT_SPIN ((1000000/(HZ*PT_SPIN_DEL))*PT_TMO)
170
171#define STAT_ERR 0x00001
172#define STAT_INDEX 0x00002
173#define STAT_ECC 0x00004
174#define STAT_DRQ 0x00008
175#define STAT_SEEK 0x00010
176#define STAT_WRERR 0x00020
177#define STAT_READY 0x00040
178#define STAT_BUSY 0x00080
179#define STAT_SENSE 0x1f000
180
181#define ATAPI_TEST_READY 0x00
182#define ATAPI_REWIND 0x01
183#define ATAPI_REQ_SENSE 0x03
184#define ATAPI_READ_6 0x08
185#define ATAPI_WRITE_6 0x0a
186#define ATAPI_WFM 0x10
187#define ATAPI_IDENTIFY 0x12
188#define ATAPI_MODE_SENSE 0x1a
189#define ATAPI_LOG_SENSE 0x4d
190
191static int pt_open(struct inode *inode, struct file *file);
192static int pt_ioctl(struct inode *inode, struct file *file,
193 unsigned int cmd, unsigned long arg);
194static int pt_release(struct inode *inode, struct file *file);
195static ssize_t pt_read(struct file *filp, char __user *buf,
196 size_t count, loff_t * ppos);
197static ssize_t pt_write(struct file *filp, const char __user *buf,
198 size_t count, loff_t * ppos);
199static int pt_detect(void);
200
201/* bits in tape->flags */
202
203#define PT_MEDIA 1
204#define PT_WRITE_OK 2
205#define PT_REWIND 4
206#define PT_WRITING 8
207#define PT_READING 16
208#define PT_EOF 32
209
210#define PT_NAMELEN 8
211#define PT_BUFSIZE 16384
212
213struct pt_unit {
214 struct pi_adapter pia; /* interface to paride layer */
215 struct pi_adapter *pi;
216 int flags; /* various state flags */
217 int last_sense; /* result of last request sense */
218 int drive; /* drive */
219 atomic_t available; /* 1 if access is available 0 otherwise */
220 int bs; /* block size */
221 int capacity; /* Size of tape in KB */
222 int present; /* device present ? */
223 char *bufptr;
224 char name[PT_NAMELEN]; /* pf0, pf1, ... */
225};
226
227static int pt_identify(struct pt_unit *tape);
228
229static struct pt_unit pt[PT_UNITS];
230
231static char pt_scratch[512]; /* scratch block buffer */
232
233/* kernel glue structures */
234
235static struct file_operations pt_fops = {
236 .owner = THIS_MODULE,
237 .read = pt_read,
238 .write = pt_write,
239 .ioctl = pt_ioctl,
240 .open = pt_open,
241 .release = pt_release,
242};
243
244/* sysfs class support */
245static struct class_simple *pt_class;
246
247static inline int status_reg(struct pi_adapter *pi)
248{
249 return pi_read_regr(pi, 1, 6);
250}
251
252static inline int read_reg(struct pi_adapter *pi, int reg)
253{
254 return pi_read_regr(pi, 0, reg);
255}
256
257static inline void write_reg(struct pi_adapter *pi, int reg, int val)
258{
259 pi_write_regr(pi, 0, reg, val);
260}
261
262static inline u8 DRIVE(struct pt_unit *tape)
263{
264 return 0xa0+0x10*tape->drive;
265}
266
267static int pt_wait(struct pt_unit *tape, int go, int stop, char *fun, char *msg)
268{
269 int j, r, e, s, p;
270 struct pi_adapter *pi = tape->pi;
271
272 j = 0;
273 while ((((r = status_reg(pi)) & go) || (stop && (!(r & stop))))
274 && (j++ < PT_SPIN))
275 udelay(PT_SPIN_DEL);
276
277 if ((r & (STAT_ERR & stop)) || (j >= PT_SPIN)) {
278 s = read_reg(pi, 7);
279 e = read_reg(pi, 1);
280 p = read_reg(pi, 2);
281 if (j >= PT_SPIN)
282 e |= 0x100;
283 if (fun)
284 printk("%s: %s %s: alt=0x%x stat=0x%x err=0x%x"
285 " loop=%d phase=%d\n",
286 tape->name, fun, msg, r, s, e, j, p);
287 return (e << 8) + s;
288 }
289 return 0;
290}
291
292static int pt_command(struct pt_unit *tape, char *cmd, int dlen, char *fun)
293{
294 struct pi_adapter *pi = tape->pi;
295 pi_connect(pi);
296
297 write_reg(pi, 6, DRIVE(tape));
298
299 if (pt_wait(tape, STAT_BUSY | STAT_DRQ, 0, fun, "before command")) {
300 pi_disconnect(pi);
301 return -1;
302 }
303
304 write_reg(pi, 4, dlen % 256);
305 write_reg(pi, 5, dlen / 256);
306 write_reg(pi, 7, 0xa0); /* ATAPI packet command */
307
308 if (pt_wait(tape, STAT_BUSY, STAT_DRQ, fun, "command DRQ")) {
309 pi_disconnect(pi);
310 return -1;
311 }
312
313 if (read_reg(pi, 2) != 1) {
314 printk("%s: %s: command phase error\n", tape->name, fun);
315 pi_disconnect(pi);
316 return -1;
317 }
318
319 pi_write_block(pi, cmd, 12);
320
321 return 0;
322}
323
324static int pt_completion(struct pt_unit *tape, char *buf, char *fun)
325{
326 struct pi_adapter *pi = tape->pi;
327 int r, s, n, p;
328
329 r = pt_wait(tape, STAT_BUSY, STAT_DRQ | STAT_READY | STAT_ERR,
330 fun, "completion");
331
332 if (read_reg(pi, 7) & STAT_DRQ) {
333 n = (((read_reg(pi, 4) + 256 * read_reg(pi, 5)) +
334 3) & 0xfffc);
335 p = read_reg(pi, 2) & 3;
336 if (p == 0)
337 pi_write_block(pi, buf, n);
338 if (p == 2)
339 pi_read_block(pi, buf, n);
340 }
341
342 s = pt_wait(tape, STAT_BUSY, STAT_READY | STAT_ERR, fun, "data done");
343
344 pi_disconnect(pi);
345
346 return (r ? r : s);
347}
348
349static void pt_req_sense(struct pt_unit *tape, int quiet)
350{
351 char rs_cmd[12] = { ATAPI_REQ_SENSE, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0 };
352 char buf[16];
353 int r;
354
355 r = pt_command(tape, rs_cmd, 16, "Request sense");
356 mdelay(1);
357 if (!r)
358 pt_completion(tape, buf, "Request sense");
359
360 tape->last_sense = -1;
361 if (!r) {
362 if (!quiet)
363 printk("%s: Sense key: %x, ASC: %x, ASQ: %x\n",
364 tape->name, buf[2] & 0xf, buf[12], buf[13]);
365 tape->last_sense = (buf[2] & 0xf) | ((buf[12] & 0xff) << 8)
366 | ((buf[13] & 0xff) << 16);
367 }
368}
369
370static int pt_atapi(struct pt_unit *tape, char *cmd, int dlen, char *buf, char *fun)
371{
372 int r;
373
374 r = pt_command(tape, cmd, dlen, fun);
375 mdelay(1);
376 if (!r)
377 r = pt_completion(tape, buf, fun);
378 if (r)
379 pt_req_sense(tape, !fun);
380
381 return r;
382}
383
384static void pt_sleep(int cs)
385{
386 current->state = TASK_INTERRUPTIBLE;
387 schedule_timeout(cs);
388}
389
390static int pt_poll_dsc(struct pt_unit *tape, int pause, int tmo, char *msg)
391{
392 struct pi_adapter *pi = tape->pi;
393 int k, e, s;
394
395 k = 0;
396 e = 0;
397 s = 0;
398 while (k < tmo) {
399 pt_sleep(pause);
400 k++;
401 pi_connect(pi);
402 write_reg(pi, 6, DRIVE(tape));
403 s = read_reg(pi, 7);
404 e = read_reg(pi, 1);
405 pi_disconnect(pi);
406 if (s & (STAT_ERR | STAT_SEEK))
407 break;
408 }
409 if ((k >= tmo) || (s & STAT_ERR)) {
410 if (k >= tmo)
411 printk("%s: %s DSC timeout\n", tape->name, msg);
412 else
413 printk("%s: %s stat=0x%x err=0x%x\n", tape->name, msg, s,
414 e);
415 pt_req_sense(tape, 0);
416 return 0;
417 }
418 return 1;
419}
420
421static void pt_media_access_cmd(struct pt_unit *tape, int tmo, char *cmd, char *fun)
422{
423 if (pt_command(tape, cmd, 0, fun)) {
424 pt_req_sense(tape, 0);
425 return;
426 }
427 pi_disconnect(tape->pi);
428 pt_poll_dsc(tape, HZ, tmo, fun);
429}
430
431static void pt_rewind(struct pt_unit *tape)
432{
433 char rw_cmd[12] = { ATAPI_REWIND, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
434
435 pt_media_access_cmd(tape, PT_REWIND_TMO, rw_cmd, "rewind");
436}
437
438static void pt_write_fm(struct pt_unit *tape)
439{
440 char wm_cmd[12] = { ATAPI_WFM, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 };
441
442 pt_media_access_cmd(tape, PT_TMO, wm_cmd, "write filemark");
443}
444
445#define DBMSG(msg) ((verbose>1)?(msg):NULL)
446
447static int pt_reset(struct pt_unit *tape)
448{
449 struct pi_adapter *pi = tape->pi;
450 int i, k, flg;
451 int expect[5] = { 1, 1, 1, 0x14, 0xeb };
452
453 pi_connect(pi);
454 write_reg(pi, 6, DRIVE(tape));
455 write_reg(pi, 7, 8);
456
457 pt_sleep(20 * HZ / 1000);
458
459 k = 0;
460 while ((k++ < PT_RESET_TMO) && (status_reg(pi) & STAT_BUSY))
461 pt_sleep(HZ / 10);
462
463 flg = 1;
464 for (i = 0; i < 5; i++)
465 flg &= (read_reg(pi, i + 1) == expect[i]);
466
467 if (verbose) {
468 printk("%s: Reset (%d) signature = ", tape->name, k);
469 for (i = 0; i < 5; i++)
470 printk("%3x", read_reg(pi, i + 1));
471 if (!flg)
472 printk(" (incorrect)");
473 printk("\n");
474 }
475
476 pi_disconnect(pi);
477 return flg - 1;
478}
479
480static int pt_ready_wait(struct pt_unit *tape, int tmo)
481{
482 char tr_cmd[12] = { ATAPI_TEST_READY, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
483 int k, p;
484
485 k = 0;
486 while (k < tmo) {
487 tape->last_sense = 0;
488 pt_atapi(tape, tr_cmd, 0, NULL, DBMSG("test unit ready"));
489 p = tape->last_sense;
490 if (!p)
491 return 0;
492 if (!(((p & 0xffff) == 0x0402) || ((p & 0xff) == 6)))
493 return p;
494 k++;
495 pt_sleep(HZ);
496 }
497 return 0x000020; /* timeout */
498}
499
500static void xs(char *buf, char *targ, int offs, int len)
501{
502 int j, k, l;
503
504 j = 0;
505 l = 0;
506 for (k = 0; k < len; k++)
507 if ((buf[k + offs] != 0x20) || (buf[k + offs] != l))
508 l = targ[j++] = buf[k + offs];
509 if (l == 0x20)
510 j--;
511 targ[j] = 0;
512}
513
514static int xn(char *buf, int offs, int size)
515{
516 int v, k;
517
518 v = 0;
519 for (k = 0; k < size; k++)
520 v = v * 256 + (buf[k + offs] & 0xff);
521 return v;
522}
523
524static int pt_identify(struct pt_unit *tape)
525{
526 int dt, s;
527 char *ms[2] = { "master", "slave" };
528 char mf[10], id[18];
529 char id_cmd[12] = { ATAPI_IDENTIFY, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0 };
530 char ms_cmd[12] =
531 { ATAPI_MODE_SENSE, 0, 0x2a, 0, 36, 0, 0, 0, 0, 0, 0, 0 };
532 char ls_cmd[12] =
533 { ATAPI_LOG_SENSE, 0, 0x71, 0, 0, 0, 0, 0, 36, 0, 0, 0 };
534 char buf[36];
535
536 s = pt_atapi(tape, id_cmd, 36, buf, "identify");
537 if (s)
538 return -1;
539
540 dt = buf[0] & 0x1f;
541 if (dt != 1) {
542 if (verbose)
543 printk("%s: Drive %d, unsupported type %d\n",
544 tape->name, tape->drive, dt);
545 return -1;
546 }
547
548 xs(buf, mf, 8, 8);
549 xs(buf, id, 16, 16);
550
551 tape->flags = 0;
552 tape->capacity = 0;
553 tape->bs = 0;
554
555 if (!pt_ready_wait(tape, PT_READY_TMO))
556 tape->flags |= PT_MEDIA;
557
558 if (!pt_atapi(tape, ms_cmd, 36, buf, "mode sense")) {
559 if (!(buf[2] & 0x80))
560 tape->flags |= PT_WRITE_OK;
561 tape->bs = xn(buf, 10, 2);
562 }
563
564 if (!pt_atapi(tape, ls_cmd, 36, buf, "log sense"))
565 tape->capacity = xn(buf, 24, 4);
566
567 printk("%s: %s %s, %s", tape->name, mf, id, ms[tape->drive]);
568 if (!(tape->flags & PT_MEDIA))
569 printk(", no media\n");
570 else {
571 if (!(tape->flags & PT_WRITE_OK))
572 printk(", RO");
573 printk(", blocksize %d, %d MB\n", tape->bs, tape->capacity / 1024);
574 }
575
576 return 0;
577}
578
579
580/*
581 * returns 0, with id set if drive is detected
582 * -1, if drive detection failed
583 */
584static int pt_probe(struct pt_unit *tape)
585{
586 if (tape->drive == -1) {
587 for (tape->drive = 0; tape->drive <= 1; tape->drive++)
588 if (!pt_reset(tape))
589 return pt_identify(tape);
590 } else {
591 if (!pt_reset(tape))
592 return pt_identify(tape);
593 }
594 return -1;
595}
596
597static int pt_detect(void)
598{
599 struct pt_unit *tape;
600 int specified = 0, found = 0;
601 int unit;
602
603 printk("%s: %s version %s, major %d\n", name, name, PT_VERSION, major);
604
605 specified = 0;
606 for (unit = 0; unit < PT_UNITS; unit++) {
607 struct pt_unit *tape = &pt[unit];
608 tape->pi = &tape->pia;
609 atomic_set(&tape->available, 1);
610 tape->flags = 0;
611 tape->last_sense = 0;
612 tape->present = 0;
613 tape->bufptr = NULL;
614 tape->drive = DU[D_SLV];
615 snprintf(tape->name, PT_NAMELEN, "%s%d", name, unit);
616 if (!DU[D_PRT])
617 continue;
618 specified++;
619 if (pi_init(tape->pi, 0, DU[D_PRT], DU[D_MOD], DU[D_UNI],
620 DU[D_PRO], DU[D_DLY], pt_scratch, PI_PT,
621 verbose, tape->name)) {
622 if (!pt_probe(tape)) {
623 tape->present = 1;
624 found++;
625 } else
626 pi_release(tape->pi);
627 }
628 }
629 if (specified == 0) {
630 tape = pt;
631 if (pi_init(tape->pi, 1, -1, -1, -1, -1, -1, pt_scratch,
632 PI_PT, verbose, tape->name)) {
633 if (!pt_probe(tape)) {
634 tape->present = 1;
635 found++;
636 } else
637 pi_release(tape->pi);
638 }
639
640 }
641 if (found)
642 return 0;
643
644 printk("%s: No ATAPI tape drive detected\n", name);
645 return -1;
646}
647
648static int pt_open(struct inode *inode, struct file *file)
649{
650 int unit = iminor(inode) & 0x7F;
651 struct pt_unit *tape = pt + unit;
652 int err;
653
654 if (unit >= PT_UNITS || (!tape->present))
655 return -ENODEV;
656
657 err = -EBUSY;
658 if (!atomic_dec_and_test(&tape->available))
659 goto out;
660
661 pt_identify(tape);
662
663 err = -ENODEV;
664 if (!tape->flags & PT_MEDIA)
665 goto out;
666
667 err = -EROFS;
668 if ((!tape->flags & PT_WRITE_OK) && (file->f_mode & 2))
669 goto out;
670
671 if (!(iminor(inode) & 128))
672 tape->flags |= PT_REWIND;
673
674 err = -ENOMEM;
675 tape->bufptr = kmalloc(PT_BUFSIZE, GFP_KERNEL);
676 if (tape->bufptr == NULL) {
677 printk("%s: buffer allocation failed\n", tape->name);
678 goto out;
679 }
680
681 file->private_data = tape;
682 return 0;
683
684out:
685 atomic_inc(&tape->available);
686 return err;
687}
688
689static int pt_ioctl(struct inode *inode, struct file *file,
690 unsigned int cmd, unsigned long arg)
691{
692 struct pt_unit *tape = file->private_data;
693 struct mtop __user *p = (void __user *)arg;
694 struct mtop mtop;
695
696 switch (cmd) {
697 case MTIOCTOP:
698 if (copy_from_user(&mtop, p, sizeof(struct mtop)))
699 return -EFAULT;
700
701 switch (mtop.mt_op) {
702
703 case MTREW:
704 pt_rewind(tape);
705 return 0;
706
707 case MTWEOF:
708 pt_write_fm(tape);
709 return 0;
710
711 default:
712 printk("%s: Unimplemented mt_op %d\n", tape->name,
713 mtop.mt_op);
714 return -EINVAL;
715 }
716
717 default:
718 printk("%s: Unimplemented ioctl 0x%x\n", tape->name, cmd);
719 return -EINVAL;
720
721 }
722}
723
724static int
725pt_release(struct inode *inode, struct file *file)
726{
727 struct pt_unit *tape = file->private_data;
728
729 if (atomic_read(&tape->available) > 1)
730 return -EINVAL;
731
732 if (tape->flags & PT_WRITING)
733 pt_write_fm(tape);
734
735 if (tape->flags & PT_REWIND)
736 pt_rewind(tape);
737
738 kfree(tape->bufptr);
739 tape->bufptr = NULL;
740
741 atomic_inc(&tape->available);
742
743 return 0;
744
745}
746
747static ssize_t pt_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos)
748{
749 struct pt_unit *tape = filp->private_data;
750 struct pi_adapter *pi = tape->pi;
751 char rd_cmd[12] = { ATAPI_READ_6, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
752 int k, n, r, p, s, t, b;
753
754 if (!(tape->flags & (PT_READING | PT_WRITING))) {
755 tape->flags |= PT_READING;
756 if (pt_atapi(tape, rd_cmd, 0, NULL, "start read-ahead"))
757 return -EIO;
758 } else if (tape->flags & PT_WRITING)
759 return -EIO;
760
761 if (tape->flags & PT_EOF)
762 return 0;
763
764 t = 0;
765
766 while (count > 0) {
767
768 if (!pt_poll_dsc(tape, HZ / 100, PT_TMO, "read"))
769 return -EIO;
770
771 n = count;
772 if (n > 32768)
773 n = 32768; /* max per command */
774 b = (n - 1 + tape->bs) / tape->bs;
775 n = b * tape->bs; /* rounded up to even block */
776
777 rd_cmd[4] = b;
778
779 r = pt_command(tape, rd_cmd, n, "read");
780
781 mdelay(1);
782
783 if (r) {
784 pt_req_sense(tape, 0);
785 return -EIO;
786 }
787
788 while (1) {
789
790 r = pt_wait(tape, STAT_BUSY,
791 STAT_DRQ | STAT_ERR | STAT_READY,
792 DBMSG("read DRQ"), "");
793
794 if (r & STAT_SENSE) {
795 pi_disconnect(pi);
796 pt_req_sense(tape, 0);
797 return -EIO;
798 }
799
800 if (r)
801 tape->flags |= PT_EOF;
802
803 s = read_reg(pi, 7);
804
805 if (!(s & STAT_DRQ))
806 break;
807
808 n = (read_reg(pi, 4) + 256 * read_reg(pi, 5));
809 p = (read_reg(pi, 2) & 3);
810 if (p != 2) {
811 pi_disconnect(pi);
812 printk("%s: Phase error on read: %d\n", tape->name,
813 p);
814 return -EIO;
815 }
816
817 while (n > 0) {
818 k = n;
819 if (k > PT_BUFSIZE)
820 k = PT_BUFSIZE;
821 pi_read_block(pi, tape->bufptr, k);
822 n -= k;
823 b = k;
824 if (b > count)
825 b = count;
826 if (copy_to_user(buf + t, tape->bufptr, b)) {
827 pi_disconnect(pi);
828 return -EFAULT;
829 }
830 t += b;
831 count -= b;
832 }
833
834 }
835 pi_disconnect(pi);
836 if (tape->flags & PT_EOF)
837 break;
838 }
839
840 return t;
841
842}
843
844static ssize_t pt_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos)
845{
846 struct pt_unit *tape = filp->private_data;
847 struct pi_adapter *pi = tape->pi;
848 char wr_cmd[12] = { ATAPI_WRITE_6, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
849 int k, n, r, p, s, t, b;
850
851 if (!(tape->flags & PT_WRITE_OK))
852 return -EROFS;
853
854 if (!(tape->flags & (PT_READING | PT_WRITING))) {
855 tape->flags |= PT_WRITING;
856 if (pt_atapi
857 (tape, wr_cmd, 0, NULL, "start buffer-available mode"))
858 return -EIO;
859 } else if (tape->flags & PT_READING)
860 return -EIO;
861
862 if (tape->flags & PT_EOF)
863 return -ENOSPC;
864
865 t = 0;
866
867 while (count > 0) {
868
869 if (!pt_poll_dsc(tape, HZ / 100, PT_TMO, "write"))
870 return -EIO;
871
872 n = count;
873 if (n > 32768)
874 n = 32768; /* max per command */
875 b = (n - 1 + tape->bs) / tape->bs;
876 n = b * tape->bs; /* rounded up to even block */
877
878 wr_cmd[4] = b;
879
880 r = pt_command(tape, wr_cmd, n, "write");
881
882 mdelay(1);
883
884 if (r) { /* error delivering command only */
885 pt_req_sense(tape, 0);
886 return -EIO;
887 }
888
889 while (1) {
890
891 r = pt_wait(tape, STAT_BUSY,
892 STAT_DRQ | STAT_ERR | STAT_READY,
893 DBMSG("write DRQ"), NULL);
894
895 if (r & STAT_SENSE) {
896 pi_disconnect(pi);
897 pt_req_sense(tape, 0);
898 return -EIO;
899 }
900
901 if (r)
902 tape->flags |= PT_EOF;
903
904 s = read_reg(pi, 7);
905
906 if (!(s & STAT_DRQ))
907 break;
908
909 n = (read_reg(pi, 4) + 256 * read_reg(pi, 5));
910 p = (read_reg(pi, 2) & 3);
911 if (p != 0) {
912 pi_disconnect(pi);
913 printk("%s: Phase error on write: %d \n",
914 tape->name, p);
915 return -EIO;
916 }
917
918 while (n > 0) {
919 k = n;
920 if (k > PT_BUFSIZE)
921 k = PT_BUFSIZE;
922 b = k;
923 if (b > count)
924 b = count;
925 if (copy_from_user(tape->bufptr, buf + t, b)) {
926 pi_disconnect(pi);
927 return -EFAULT;
928 }
929 pi_write_block(pi, tape->bufptr, k);
930 t += b;
931 count -= b;
932 n -= k;
933 }
934
935 }
936 pi_disconnect(pi);
937 if (tape->flags & PT_EOF)
938 break;
939 }
940
941 return t;
942}
943
944static int __init pt_init(void)
945{
946 int unit, err = 0;
947
948 if (disable) {
949 err = -1;
950 goto out;
951 }
952
953 if (pt_detect()) {
954 err = -1;
955 goto out;
956 }
957
958 if (register_chrdev(major, name, &pt_fops)) {
959 printk("pt_init: unable to get major number %d\n", major);
960 for (unit = 0; unit < PT_UNITS; unit++)
961 if (pt[unit].present)
962 pi_release(pt[unit].pi);
963 err = -1;
964 goto out;
965 }
966 pt_class = class_simple_create(THIS_MODULE, "pt");
967 if (IS_ERR(pt_class)) {
968 err = PTR_ERR(pt_class);
969 goto out_chrdev;
970 }
971
972 devfs_mk_dir("pt");
973 for (unit = 0; unit < PT_UNITS; unit++)
974 if (pt[unit].present) {
975 class_simple_device_add(pt_class, MKDEV(major, unit),
976 NULL, "pt%d", unit);
977 err = devfs_mk_cdev(MKDEV(major, unit),
978 S_IFCHR | S_IRUSR | S_IWUSR,
979 "pt/%d", unit);
980 if (err) {
981 class_simple_device_remove(MKDEV(major, unit));
982 goto out_class;
983 }
984 class_simple_device_add(pt_class, MKDEV(major, unit + 128),
985 NULL, "pt%dn", unit);
986 err = devfs_mk_cdev(MKDEV(major, unit + 128),
987 S_IFCHR | S_IRUSR | S_IWUSR,
988 "pt/%dn", unit);
989 if (err) {
990 class_simple_device_remove(MKDEV(major, unit + 128));
991 goto out_class;
992 }
993 }
994 goto out;
995
996out_class:
997 class_simple_destroy(pt_class);
998out_chrdev:
999 unregister_chrdev(major, "pt");
1000out:
1001 return err;
1002}
1003
1004static void __exit pt_exit(void)
1005{
1006 int unit;
1007 for (unit = 0; unit < PT_UNITS; unit++)
1008 if (pt[unit].present) {
1009 class_simple_device_remove(MKDEV(major, unit));
1010 devfs_remove("pt/%d", unit);
1011 class_simple_device_remove(MKDEV(major, unit + 128));
1012 devfs_remove("pt/%dn", unit);
1013 }
1014 class_simple_destroy(pt_class);
1015 devfs_remove("pt");
1016 unregister_chrdev(major, name);
1017 for (unit = 0; unit < PT_UNITS; unit++)
1018 if (pt[unit].present)
1019 pi_release(pt[unit].pi);
1020}
1021
1022MODULE_LICENSE("GPL");
1023module_init(pt_init)
1024module_exit(pt_exit)