aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/cdrom
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/cdrom
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/cdrom')
-rw-r--r--drivers/cdrom/Kconfig213
-rw-r--r--drivers/cdrom/Makefile23
-rw-r--r--drivers/cdrom/aztcd.c2494
-rw-r--r--drivers/cdrom/aztcd.h162
-rw-r--r--drivers/cdrom/cdrom.c3397
-rw-r--r--drivers/cdrom/cdu31a.c3248
-rw-r--r--drivers/cdrom/cdu31a.h411
-rw-r--r--drivers/cdrom/cm206.c1626
-rw-r--r--drivers/cdrom/cm206.h171
-rw-r--r--drivers/cdrom/gscd.c1031
-rw-r--r--drivers/cdrom/gscd.h108
-rw-r--r--drivers/cdrom/isp16.c374
-rw-r--r--drivers/cdrom/isp16.h72
-rw-r--r--drivers/cdrom/mcdx.c1952
-rw-r--r--drivers/cdrom/mcdx.h185
-rw-r--r--drivers/cdrom/optcd.c2106
-rw-r--r--drivers/cdrom/optcd.h52
-rw-r--r--drivers/cdrom/sbpcd.c5978
-rw-r--r--drivers/cdrom/sbpcd.h839
-rw-r--r--drivers/cdrom/sjcd.c1817
-rw-r--r--drivers/cdrom/sjcd.h181
-rw-r--r--drivers/cdrom/sonycd535.c1692
-rw-r--r--drivers/cdrom/sonycd535.h183
-rw-r--r--drivers/cdrom/viocd.c809
24 files changed, 29124 insertions, 0 deletions
diff --git a/drivers/cdrom/Kconfig b/drivers/cdrom/Kconfig
new file mode 100644
index 000000000000..ff5652d40619
--- /dev/null
+++ b/drivers/cdrom/Kconfig
@@ -0,0 +1,213 @@
1#
2# CDROM driver configuration
3#
4
5menu "Old CD-ROM drivers (not SCSI, not IDE)"
6 depends on ISA
7
8config CD_NO_IDESCSI
9 bool "Support non-SCSI/IDE/ATAPI CDROM drives"
10 ---help---
11 If you have a CD-ROM drive that is neither SCSI nor IDE/ATAPI, say Y
12 here, otherwise N. Read the CD-ROM-HOWTO, available from
13 <http://www.tldp.org/docs.html#howto>.
14
15 Note that the answer to this question doesn't directly affect the
16 kernel: saying N will just cause the configurator to skip all
17 the questions about these CD-ROM drives. If you are unsure what you
18 have, say Y and find out whether you have one of the following
19 drives.
20
21 For each of these drivers, a <file:Documentation/cdrom/{driver_name}>
22 exists. Especially in cases where you do not know exactly which kind
23 of drive you have you should read there. Most of these drivers use a
24 file drivers/cdrom/{driver_name}.h where you can define your
25 interface parameters and switch some internal goodies.
26
27 To compile these CD-ROM drivers as a module, choose M instead of Y.
28
29 If you want to use any of these CD-ROM drivers, you also have to
30 answer Y or M to "ISO 9660 CD-ROM file system support" below (this
31 answer will get "defaulted" for you if you enable any of the Linux
32 CD-ROM drivers).
33
34config AZTCD
35 tristate "Aztech/Orchid/Okano/Wearnes/TXC/CyDROM CDROM support"
36 depends on CD_NO_IDESCSI
37 ---help---
38 This is your driver if you have an Aztech CDA268-01A, Orchid
39 CD-3110, Okano or Wearnes CDD110, Conrad TXC, or CyCD-ROM CR520 or
40 CR540 CD-ROM drive. This driver -- just like all these CD-ROM
41 drivers -- is NOT for CD-ROM drives with IDE/ATAPI interfaces, such
42 as Aztech CDA269-031SE. Please read the file
43 <file:Documentation/cdrom/aztcd>.
44
45 If you say Y here, you should also say Y or M to "ISO 9660 CD-ROM
46 file system support" below, because that's the file system used on
47 CD-ROMs.
48
49 To compile this driver as a module, choose M here: the
50 module will be called aztcd.
51
52config GSCD
53 tristate "Goldstar R420 CDROM support"
54 depends on CD_NO_IDESCSI
55 ---help---
56 If this is your CD-ROM drive, say Y here. As described in the file
57 <file:Documentation/cdrom/gscd>, you might have to change a setting
58 in the file <file:drivers/cdrom/gscd.h> before compiling the
59 kernel. Please read the file <file:Documentation/cdrom/gscd>.
60
61 If you say Y here, you should also say Y or M to "ISO 9660 CD-ROM
62 file system support" below, because that's the file system used on
63 CD-ROMs.
64
65 To compile this driver as a module, choose M here: the
66 module will be called gscd.
67
68config SBPCD
69 tristate "Matsushita/Panasonic/Creative, Longshine, TEAC CDROM support"
70 depends on CD_NO_IDESCSI && BROKEN_ON_SMP
71 ---help---
72 This driver supports most of the drives which use the Panasonic or
73 Sound Blaster interface. Please read the file
74 <file:Documentation/cdrom/sbpcd>.
75
76 The Matsushita CR-521, CR-522, CR-523, CR-562, CR-563 drives
77 (sometimes labeled "Creative"), the Creative Labs CD200, the
78 Longshine LCS-7260, the "IBM External ISA CD-ROM" (in fact a CR-56x
79 model), the TEAC CD-55A fall under this category. Some other
80 "electrically compatible" drives (Vertos, Genoa, some Funai models)
81 are currently not supported; for the Sanyo H94A drive currently a
82 separate driver (asked later) is responsible. Most drives have a
83 uniquely shaped faceplate, with a caddyless motorized drawer, but
84 without external brand markings. The older CR-52x drives have a
85 caddy and manual loading/eject, but still no external markings. The
86 driver is able to do an extended auto-probing for interface
87 addresses and drive types; this can help to find facts in cases you
88 are not sure, but can consume some time during the boot process if
89 none of the supported drives gets found. Once your drive got found,
90 you should enter the reported parameters into
91 <file:drivers/cdrom/sbpcd.h> and set "DISTRIBUTION 0" there.
92
93 This driver can support up to four CD-ROM controller cards, and each
94 card can support up to four CD-ROM drives; if you say Y here, you
95 will be asked how many controller cards you have. If compiled as a
96 module, only one controller card (but with up to four drives) is
97 usable.
98
99 If you say Y here, you should also say Y or M to "ISO 9660 CD-ROM
100 file system support" below, because that's the file system used on
101 CD-ROMs.
102
103 To compile this driver as a module, choose M here: the
104 module will be called sbpcd.
105
106config MCDX
107 tristate "Mitsumi CDROM support"
108 depends on CD_NO_IDESCSI
109 ---help---
110 Use this driver if you want to be able to use your Mitsumi LU-005,
111 FX-001 or FX-001D CD-ROM drive.
112
113 Please read the file <file:Documentation/cdrom/mcdx>.
114
115 If you say Y here, you should also say Y or M to "ISO 9660 CD-ROM
116 file system support" below, because that's the file system used on
117 CD-ROMs.
118
119 To compile this driver as a module, choose M here: the
120 module will be called mcdx.
121
122config OPTCD
123 tristate "Optics Storage DOLPHIN 8000AT CDROM support"
124 depends on CD_NO_IDESCSI
125 ---help---
126 This is the driver for the 'DOLPHIN' drive with a 34-pin Sony
127 compatible interface. It also works with the Lasermate CR328A. If
128 you have one of those, say Y. This driver does not work for the
129 Optics Storage 8001 drive; use the IDE-ATAPI CD-ROM driver for that
130 one. Please read the file <file:Documentation/cdrom/optcd>.
131
132 If you say Y here, you should also say Y or M to "ISO 9660 CD-ROM
133 file system support" below, because that's the file system used on
134 CD-ROMs.
135
136 To compile this driver as a module, choose M here: the
137 module will be called optcd.
138
139config CM206
140 tristate "Philips/LMS CM206 CDROM support"
141 depends on CD_NO_IDESCSI && BROKEN_ON_SMP
142 ---help---
143 If you have a Philips/LMS CD-ROM drive cm206 in combination with a
144 cm260 host adapter card, say Y here. Please also read the file
145 <file:Documentation/cdrom/cm206>.
146
147 If you say Y here, you should also say Y or M to "ISO 9660 CD-ROM
148 file system support" below, because that's the file system used on
149 CD-ROMs.
150
151 To compile this driver as a module, choose M here: the
152 module will be called cm206.
153
154config SJCD
155 tristate "Sanyo CDR-H94A CDROM support"
156 depends on CD_NO_IDESCSI
157 help
158 If this is your CD-ROM drive, say Y here and read the file
159 <file:Documentation/cdrom/sjcd>. You should then also say Y or M to
160 "ISO 9660 CD-ROM file system support" below, because that's the
161 file system used on CD-ROMs.
162
163 To compile this driver as a module, choose M here: the
164 module will be called sjcd.
165
166config ISP16_CDI
167 tristate "ISP16/MAD16/Mozart soft configurable cdrom interface support"
168 depends on CD_NO_IDESCSI
169 ---help---
170 These are sound cards with built-in cdrom interfaces using the OPTi
171 82C928 or 82C929 chips. Say Y here to have them detected and
172 possibly configured at boot time. In addition, You'll have to say Y
173 to a driver for the particular cdrom drive you have attached to the
174 card. Read <file:Documentation/cdrom/isp16> for details.
175
176 To compile this driver as a module, choose M here: the
177 module will be called isp16.
178
179config CDU31A
180 tristate "Sony CDU31A/CDU33A CDROM support"
181 depends on CD_NO_IDESCSI && BROKEN_ON_SMP
182 ---help---
183 These CD-ROM drives have a spring-pop-out caddyless drawer, and a
184 rectangular green LED centered beneath it. NOTE: these CD-ROM
185 drives will not be auto detected by the kernel at boot time; you
186 have to provide the interface address as an option to the kernel at
187 boot time as described in <file:Documentation/cdrom/cdu31a> or fill
188 in your parameters into <file:drivers/cdrom/cdu31a.c>. Try "man
189 bootparam" or see the documentation of your boot loader (lilo or
190 loadlin) about how to pass options to the kernel.
191
192 If you say Y here, you should also say Y or M to "ISO 9660 CD-ROM
193 file system support" below, because that's the file system used on
194 CD-ROMs.
195
196 To compile this driver as a module, choose M here: the
197 module will be called cdu31a.
198
199config CDU535
200 tristate "Sony CDU535 CDROM support"
201 depends on CD_NO_IDESCSI
202 ---help---
203 This is the driver for the older Sony CDU-535 and CDU-531 CD-ROM
204 drives. Please read the file <file:Documentation/cdrom/sonycd535>.
205
206 If you say Y here, you should also say Y or M to "ISO 9660 CD-ROM
207 file system support" below, because that's the file system used on
208 CD-ROMs.
209
210 To compile this driver as a module, choose M here: the
211 module will be called sonycd535.
212
213endmenu
diff --git a/drivers/cdrom/Makefile b/drivers/cdrom/Makefile
new file mode 100644
index 000000000000..d1d1e5a4be73
--- /dev/null
+++ b/drivers/cdrom/Makefile
@@ -0,0 +1,23 @@
1# Makefile for the kernel cdrom device drivers.
2#
3# 30 Jan 1998, Michael Elizabeth Chastain, <mailto:mec@shout.net>
4# Rewritten to use lists instead of if-statements.
5
6# Each configuration option enables a list of files.
7
8obj-$(CONFIG_BLK_DEV_IDECD) += cdrom.o
9obj-$(CONFIG_BLK_DEV_SR) += cdrom.o
10obj-$(CONFIG_PARIDE_PCD) += cdrom.o
11obj-$(CONFIG_CDROM_PKTCDVD) += cdrom.o
12
13obj-$(CONFIG_AZTCD) += aztcd.o
14obj-$(CONFIG_CDU31A) += cdu31a.o cdrom.o
15obj-$(CONFIG_CM206) += cm206.o cdrom.o
16obj-$(CONFIG_GSCD) += gscd.o
17obj-$(CONFIG_ISP16_CDI) += isp16.o
18obj-$(CONFIG_MCDX) += mcdx.o cdrom.o
19obj-$(CONFIG_OPTCD) += optcd.o
20obj-$(CONFIG_SBPCD) += sbpcd.o cdrom.o
21obj-$(CONFIG_SJCD) += sjcd.o
22obj-$(CONFIG_CDU535) += sonycd535.o
23obj-$(CONFIG_VIOCD) += viocd.o cdrom.o
diff --git a/drivers/cdrom/aztcd.c b/drivers/cdrom/aztcd.c
new file mode 100644
index 000000000000..43bf1e5dc38a
--- /dev/null
+++ b/drivers/cdrom/aztcd.c
@@ -0,0 +1,2494 @@
1#define AZT_VERSION "2.60"
2
3/* $Id: aztcd.c,v 2.60 1997/11/29 09:51:19 root Exp root $
4 linux/drivers/block/aztcd.c - Aztech CD268 CDROM driver
5
6 Copyright (C) 1994-98 Werner Zimmermann(Werner.Zimmermann@fht-esslingen.de)
7
8 based on Mitsumi CDROM driver by Martin Hariss and preworks by
9 Eberhard Moenkeberg; contains contributions by Joe Nardone and Robby
10 Schirmer.
11
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2, or (at your option)
15 any later version.
16
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25
26 HISTORY
27 V0.0 Adaption to Aztech CD268-01A Version 1.3
28 Version is PRE_ALPHA, unresolved points:
29 1. I use busy wait instead of timer wait in STEN_LOW,DTEN_LOW
30 thus driver causes CPU overhead and is very slow
31 2. could not find a way to stop the drive, when it is
32 in data read mode, therefore I had to set
33 msf.end.min/sec/frame to 0:0:1 (in azt_poll); so only one
34 frame can be read in sequence, this is also the reason for
35 3. getting 'timeout in state 4' messages, but nevertheless
36 it works
37 W.Zimmermann, Oct. 31, 1994
38 V0.1 Version is ALPHA, problems #2 and #3 resolved.
39 W.Zimmermann, Nov. 3, 1994
40 V0.2 Modification to some comments, debugging aids for partial test
41 with Borland C under DOS eliminated. Timer interrupt wait
42 STEN_LOW_WAIT additionally to busy wait for STEN_LOW implemented;
43 use it only for the 'slow' commands (ACMD_GET_Q_CHANNEL, ACMD_
44 SEEK_TO_LEAD_IN), all other commands are so 'fast', that busy
45 waiting seems better to me than interrupt rescheduling.
46 Besides that, when used in the wrong place, STEN_LOW_WAIT causes
47 kernel panic.
48 In function aztPlay command ACMD_PLAY_AUDIO added, should make
49 audio functions work. The Aztech drive needs different commands
50 to read data tracks and play audio tracks.
51 W.Zimmermann, Nov. 8, 1994
52 V0.3 Recognition of missing drive during boot up improved (speeded up).
53 W.Zimmermann, Nov. 13, 1994
54 V0.35 Rewrote the control mechanism in azt_poll (formerly mcd_poll)
55 including removal of all 'goto' commands. :-);
56 J. Nardone, Nov. 14, 1994
57 V0.4 Renamed variables and constants to 'azt' instead of 'mcd'; had
58 to make some "compatibility" defines in azt.h; please note,
59 that the source file was renamed to azt.c, the include file to
60 azt.h
61 Speeded up drive recognition during init (will be a little bit
62 slower than before if no drive is installed!); suggested by
63 Robby Schirmer.
64 read_count declared volatile and set to AZT_BUF_SIZ to make
65 drive faster (now 300kB/sec, was 60kB/sec before, measured
66 by 'time dd if=/dev/cdrom of=/dev/null bs=2048 count=4096';
67 different AZT_BUF_SIZes were test, above 16 no further im-
68 provement seems to be possible; suggested by E.Moenkeberg.
69 W.Zimmermann, Nov. 18, 1994
70 V0.42 Included getAztStatus command in GetQChannelInfo() to allow
71 reading Q-channel info on audio disks, if drive is stopped,
72 and some other bug fixes in the audio stuff, suggested by
73 Robby Schirmer.
74 Added more ioctls (reading data in mode 1 and mode 2).
75 Completely removed the old azt_poll() routine.
76 Detection of ORCHID CDS-3110 in aztcd_init implemented.
77 Additional debugging aids (see the readme file).
78 W.Zimmermann, Dec. 9, 1994
79 V0.50 Autodetection of drives implemented.
80 W.Zimmermann, Dec. 12, 1994
81 V0.52 Prepared for including in the standard kernel, renamed most
82 variables to contain 'azt', included autoconf.h
83 W.Zimmermann, Dec. 16, 1994
84 V0.6 Version for being included in the standard Linux kernel.
85 Renamed source and header file to aztcd.c and aztcd.h
86 W.Zimmermann, Dec. 24, 1994
87 V0.7 Changed VERIFY_READ to VERIFY_WRITE in aztcd_ioctl, case
88 CDROMREADMODE1 and CDROMREADMODE2; bug fix in the ioctl,
89 which causes kernel crashes when playing audio, changed
90 include-files (config.h instead of autoconf.h, removed
91 delay.h)
92 W.Zimmermann, Jan. 8, 1995
93 V0.72 Some more modifications for adaption to the standard kernel.
94 W.Zimmermann, Jan. 16, 1995
95 V0.80 aztcd is now part of the standard kernel since version 1.1.83.
96 Modified the SET_TIMER and CLEAR_TIMER macros to comply with
97 the new timer scheme.
98 W.Zimmermann, Jan. 21, 1995
99 V0.90 Included CDROMVOLCTRL, but with my Aztech drive I can only turn
100 the channels on and off. If it works better with your drive,
101 please mail me. Also implemented ACMD_CLOSE for CDROMSTART.
102 W.Zimmermann, Jan. 24, 1995
103 V1.00 Implemented close and lock tray commands. Patches supplied by
104 Frank Racis
105 Added support for loadable MODULEs, so aztcd can now also be
106 loaded by insmod and removed by rmmod during run time
107 Werner Zimmermann, Mar. 24, 95
108 V1.10 Implemented soundcard configuration for Orchid CDS-3110 drives
109 connected to Soundwave32 cards. Release for LST 2.1.
110 (still experimental)
111 Werner Zimmermann, May 8, 95
112 V1.20 Implemented limited support for DOSEMU0.60's cdrom.c. Now it works, but
113 sometimes DOSEMU may hang for 30 seconds or so. A fully functional ver-
114 sion needs an update of Dosemu0.60's cdrom.c, which will come with the
115 next revision of Dosemu.
116 Also Soundwave32 support now works.
117 Werner Zimmermann, May 22, 95
118 V1.30 Auto-eject feature. Inspired by Franc Racis (racis@psu.edu)
119 Werner Zimmermann, July 4, 95
120 V1.40 Started multisession support. Implementation copied from mcdx.c
121 by Heiko Schlittermann. Not tested yet.
122 Werner Zimmermann, July 15, 95
123 V1.50 Implementation of ioctl CDROMRESET, continued multisession, began
124 XA, but still untested. Heavy modifications to drive status de-
125 tection.
126 Werner Zimmermann, July 25, 95
127 V1.60 XA support now should work. Speeded up drive recognition in cases,
128 where no drive is installed.
129 Werner Zimmermann, August 8, 1995
130 V1.70 Multisession support now is completed, but there is still not
131 enough testing done. If you can test it, please contact me. For
132 details please read Documentation/cdrom/aztcd
133 Werner Zimmermann, August 19, 1995
134 V1.80 Modification to suit the new kernel boot procedure introduced
135 with kernel 1.3.33. Will definitely not work with older kernels.
136 Programming done by Linus himself.
137 Werner Zimmermann, October 11, 1995
138 V1.90 Support for Conrad TXC drives, thank's to Jochen Kunz and Olaf Kaluza.
139 Werner Zimmermann, October 21, 1995
140 V2.00 Changed #include "blk.h" to <linux/blk.h> as the directory
141 structure was changed. README.aztcd is now /usr/src/docu-
142 mentation/cdrom/aztcd
143 Werner Zimmermann, November 10, 95
144 V2.10 Started to modify azt_poll to prevent reading beyond end of
145 tracks.
146 Werner Zimmermann, December 3, 95
147 V2.20 Changed some comments
148 Werner Zimmermann, April 1, 96
149 V2.30 Implemented support for CyCDROM CR520, CR940, Code for CR520
150 delivered by H.Berger with preworks by E.Moenkeberg.
151 Werner Zimmermann, April 29, 96
152 V2.40 Reorganized the placement of functions in the source code file
153 to reflect the layered approach; did not actually change code
154 Werner Zimmermann, May 1, 96
155 V2.50 Heiko Eissfeldt suggested to remove some VERIFY_READs in
156 aztcd_ioctl; check_aztcd_media_change modified
157 Werner Zimmermann, May 16, 96
158 V2.60 Implemented Auto-Probing; made changes for kernel's 2.1.xx blocksize
159 Adaption to linux kernel > 2.1.0
160 Werner Zimmermann, Nov 29, 97
161
162 November 1999 -- Make kernel-parameter implementation work with 2.3.x
163 Removed init_module & cleanup_module in favor of
164 module_init & module_exit.
165 Torben Mathiasen <tmm@image.dk>
166*/
167
168#include <linux/blkdev.h>
169#include "aztcd.h"
170
171#include <linux/module.h>
172#include <linux/errno.h>
173#include <linux/sched.h>
174#include <linux/mm.h>
175#include <linux/timer.h>
176#include <linux/fs.h>
177#include <linux/kernel.h>
178#include <linux/cdrom.h>
179#include <linux/ioport.h>
180#include <linux/string.h>
181#include <linux/major.h>
182
183#include <linux/init.h>
184
185#include <asm/system.h>
186#include <asm/io.h>
187
188#include <asm/uaccess.h>
189
190/*###########################################################################
191 Defines
192 ###########################################################################
193*/
194
195#define MAJOR_NR AZTECH_CDROM_MAJOR
196#define QUEUE (azt_queue)
197#define CURRENT elv_next_request(azt_queue)
198#define SET_TIMER(func, jifs) delay_timer.expires = jiffies + (jifs); \
199 delay_timer.function = (void *) (func); \
200 add_timer(&delay_timer);
201
202#define CLEAR_TIMER del_timer(&delay_timer);
203
204#define RETURNM(message,value) {printk("aztcd: Warning: %s failed\n",message);\
205 return value;}
206#define RETURN(message) {printk("aztcd: Warning: %s failed\n",message);\
207 return;}
208
209/* Macros to switch the IDE-interface to the slave device and back to the master*/
210#define SWITCH_IDE_SLAVE outb_p(0xa0,azt_port+6); \
211 outb_p(0x10,azt_port+6); \
212 outb_p(0x00,azt_port+7); \
213 outb_p(0x10,azt_port+6);
214#define SWITCH_IDE_MASTER outb_p(0xa0,azt_port+6);
215
216
217#if 0
218#define AZT_TEST
219#define AZT_TEST1 /* <int-..> */
220#define AZT_TEST2 /* do_aztcd_request */
221#define AZT_TEST3 /* AZT_S_state */
222#define AZT_TEST4 /* QUICK_LOOP-counter */
223#define AZT_TEST5 /* port(1) state */
224#define AZT_DEBUG
225#define AZT_DEBUG_MULTISESSION
226#endif
227
228static struct request_queue *azt_queue;
229
230static int current_valid(void)
231{
232 return CURRENT &&
233 CURRENT->cmd == READ &&
234 CURRENT->sector != -1;
235}
236
237#define AFL_STATUSorDATA (AFL_STATUS | AFL_DATA)
238#define AZT_BUF_SIZ 16
239
240#define READ_TIMEOUT 3000
241
242#define azt_port aztcd /*needed for the modutils */
243
244/*##########################################################################
245 Type Definitions
246 ##########################################################################
247*/
248enum azt_state_e { AZT_S_IDLE, /* 0 */
249 AZT_S_START, /* 1 */
250 AZT_S_MODE, /* 2 */
251 AZT_S_READ, /* 3 */
252 AZT_S_DATA, /* 4 */
253 AZT_S_STOP, /* 5 */
254 AZT_S_STOPPING /* 6 */
255};
256enum azt_read_modes { AZT_MODE_0, /*read mode for audio disks, not supported by Aztech firmware */
257 AZT_MODE_1, /*read mode for normal CD-ROMs */
258 AZT_MODE_2 /*read mode for XA CD-ROMs */
259};
260
261/*##########################################################################
262 Global Variables
263 ##########################################################################
264*/
265static int aztPresent = 0;
266
267static volatile int azt_transfer_is_active = 0;
268
269static char azt_buf[CD_FRAMESIZE_RAW * AZT_BUF_SIZ]; /*buffer for block size conversion */
270#if AZT_PRIVATE_IOCTLS
271static char buf[CD_FRAMESIZE_RAW]; /*separate buffer for the ioctls */
272#endif
273
274static volatile int azt_buf_bn[AZT_BUF_SIZ], azt_next_bn;
275static volatile int azt_buf_in, azt_buf_out = -1;
276static volatile int azt_error = 0;
277static int azt_open_count = 0;
278static volatile enum azt_state_e azt_state = AZT_S_IDLE;
279#ifdef AZT_TEST3
280static volatile enum azt_state_e azt_state_old = AZT_S_STOP;
281static volatile int azt_st_old = 0;
282#endif
283static volatile enum azt_read_modes azt_read_mode = AZT_MODE_1;
284
285static int azt_mode = -1;
286static volatile int azt_read_count = 1;
287
288static int azt_port = AZT_BASE_ADDR;
289
290module_param(azt_port, int, 0);
291
292static int azt_port_auto[16] = AZT_BASE_AUTO;
293
294static char azt_cont = 0;
295static char azt_init_end = 0;
296static char azt_auto_eject = AZT_AUTO_EJECT;
297
298static int AztTimeout, AztTries;
299static DECLARE_WAIT_QUEUE_HEAD(azt_waitq);
300static struct timer_list delay_timer = TIMER_INITIALIZER(NULL, 0, 0);
301
302static struct azt_DiskInfo DiskInfo;
303static struct azt_Toc Toc[MAX_TRACKS];
304static struct azt_Play_msf azt_Play;
305
306static int aztAudioStatus = CDROM_AUDIO_NO_STATUS;
307static char aztDiskChanged = 1;
308static char aztTocUpToDate = 0;
309
310static unsigned char aztIndatum;
311static unsigned long aztTimeOutCount;
312static int aztCmd = 0;
313
314static DEFINE_SPINLOCK(aztSpin);
315
316/*###########################################################################
317 Function Prototypes
318 ###########################################################################
319*/
320/* CDROM Drive Low Level I/O Functions */
321static void aztStatTimer(void);
322
323/* CDROM Drive Command Functions */
324static int aztGetDiskInfo(void);
325#if AZT_MULTISESSION
326static int aztGetMultiDiskInfo(void);
327#endif
328static int aztGetToc(int multi);
329
330/* Kernel Interface Functions */
331static int check_aztcd_media_change(struct gendisk *disk);
332static int aztcd_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
333 unsigned long arg);
334static int aztcd_open(struct inode *ip, struct file *fp);
335static int aztcd_release(struct inode *inode, struct file *file);
336
337static struct block_device_operations azt_fops = {
338 .owner = THIS_MODULE,
339 .open = aztcd_open,
340 .release = aztcd_release,
341 .ioctl = aztcd_ioctl,
342 .media_changed = check_aztcd_media_change,
343};
344
345/* Aztcd State Machine: Controls Drive Operating State */
346static void azt_poll(void);
347
348/* Miscellaneous support functions */
349static void azt_hsg2msf(long hsg, struct msf *msf);
350static long azt_msf2hsg(struct msf *mp);
351static void azt_bin2bcd(unsigned char *p);
352static int azt_bcd2bin(unsigned char bcd);
353
354/*##########################################################################
355 CDROM Drive Low Level I/O Functions
356 ##########################################################################
357*/
358/* Macros for the drive hardware interface handshake, these macros use
359 busy waiting */
360/* Wait for OP_OK = drive answers with AFL_OP_OK after receiving a command*/
361# define OP_OK op_ok()
362static void op_ok(void)
363{
364 aztTimeOutCount = 0;
365 do {
366 aztIndatum = inb(DATA_PORT);
367 aztTimeOutCount++;
368 if (aztTimeOutCount >= AZT_TIMEOUT) {
369 printk("aztcd: Error Wait OP_OK\n");
370 break;
371 }
372 } while (aztIndatum != AFL_OP_OK);
373}
374
375/* Wait for PA_OK = drive answers with AFL_PA_OK after receiving parameters*/
376#if 0
377# define PA_OK pa_ok()
378static void pa_ok(void)
379{
380 aztTimeOutCount = 0;
381 do {
382 aztIndatum = inb(DATA_PORT);
383 aztTimeOutCount++;
384 if (aztTimeOutCount >= AZT_TIMEOUT) {
385 printk("aztcd: Error Wait PA_OK\n");
386 break;
387 }
388 } while (aztIndatum != AFL_PA_OK);
389}
390#endif
391
392/* Wait for STEN=Low = handshake signal 'AFL_.._OK available or command executed*/
393# define STEN_LOW sten_low()
394static void sten_low(void)
395{
396 aztTimeOutCount = 0;
397 do {
398 aztIndatum = inb(STATUS_PORT);
399 aztTimeOutCount++;
400 if (aztTimeOutCount >= AZT_TIMEOUT) {
401 if (azt_init_end)
402 printk
403 ("aztcd: Error Wait STEN_LOW commands:%x\n",
404 aztCmd);
405 break;
406 }
407 } while (aztIndatum & AFL_STATUS);
408}
409
410/* Wait for DTEN=Low = handshake signal 'Data available'*/
411# define DTEN_LOW dten_low()
412static void dten_low(void)
413{
414 aztTimeOutCount = 0;
415 do {
416 aztIndatum = inb(STATUS_PORT);
417 aztTimeOutCount++;
418 if (aztTimeOutCount >= AZT_TIMEOUT) {
419 printk("aztcd: Error Wait DTEN_OK\n");
420 break;
421 }
422 } while (aztIndatum & AFL_DATA);
423}
424
425/*
426 * Macro for timer wait on STEN=Low, should only be used for 'slow' commands;
427 * may cause kernel panic when used in the wrong place
428*/
429#define STEN_LOW_WAIT statusAzt()
430static void statusAzt(void)
431{
432 AztTimeout = AZT_STATUS_DELAY;
433 SET_TIMER(aztStatTimer, HZ / 100);
434 sleep_on(&azt_waitq);
435 if (AztTimeout <= 0)
436 printk("aztcd: Error Wait STEN_LOW_WAIT command:%x\n",
437 aztCmd);
438 return;
439}
440
441static void aztStatTimer(void)
442{
443 if (!(inb(STATUS_PORT) & AFL_STATUS)) {
444 wake_up(&azt_waitq);
445 return;
446 }
447 AztTimeout--;
448 if (AztTimeout <= 0) {
449 wake_up(&azt_waitq);
450 printk("aztcd: Error aztStatTimer: Timeout\n");
451 return;
452 }
453 SET_TIMER(aztStatTimer, HZ / 100);
454}
455
456/*##########################################################################
457 CDROM Drive Command Functions
458 ##########################################################################
459*/
460/*
461 * Send a single command, return -1 on error, else 0
462*/
463static int aztSendCmd(int cmd)
464{
465 unsigned char data;
466 int retry;
467
468#ifdef AZT_DEBUG
469 printk("aztcd: Executing command %x\n", cmd);
470#endif
471
472 if ((azt_port == 0x1f0) || (azt_port == 0x170))
473 SWITCH_IDE_SLAVE; /*switch IDE interface to slave configuration */
474
475 aztCmd = cmd;
476 outb(POLLED, MODE_PORT);
477 do {
478 if (inb(STATUS_PORT) & AFL_STATUS)
479 break;
480 inb(DATA_PORT); /* if status left from last command, read and */
481 } while (1); /* discard it */
482 do {
483 if (inb(STATUS_PORT) & AFL_DATA)
484 break;
485 inb(DATA_PORT); /* if data left from last command, read and */
486 } while (1); /* discard it */
487 for (retry = 0; retry < AZT_RETRY_ATTEMPTS; retry++) {
488 outb((unsigned char) cmd, CMD_PORT);
489 STEN_LOW;
490 data = inb(DATA_PORT);
491 if (data == AFL_OP_OK) {
492 return 0;
493 } /*OP_OK? */
494 if (data == AFL_OP_ERR) {
495 STEN_LOW;
496 data = inb(DATA_PORT);
497 printk
498 ("### Error 1 aztcd: aztSendCmd %x Error Code %x\n",
499 cmd, data);
500 }
501 }
502 if (retry >= AZT_RETRY_ATTEMPTS) {
503 printk("### Error 2 aztcd: aztSendCmd %x \n", cmd);
504 azt_error = 0xA5;
505 }
506 RETURNM("aztSendCmd", -1);
507}
508
509/*
510 * Send a play or read command to the drive, return -1 on error, else 0
511*/
512static int sendAztCmd(int cmd, struct azt_Play_msf *params)
513{
514 unsigned char data;
515 int retry;
516
517#ifdef AZT_DEBUG
518 printk("aztcd: play start=%02x:%02x:%02x end=%02x:%02x:%02x\n",
519 params->start.min, params->start.sec, params->start.frame,
520 params->end.min, params->end.sec, params->end.frame);
521#endif
522 for (retry = 0; retry < AZT_RETRY_ATTEMPTS; retry++) {
523 aztSendCmd(cmd);
524 outb(params->start.min, CMD_PORT);
525 outb(params->start.sec, CMD_PORT);
526 outb(params->start.frame, CMD_PORT);
527 outb(params->end.min, CMD_PORT);
528 outb(params->end.sec, CMD_PORT);
529 outb(params->end.frame, CMD_PORT);
530 STEN_LOW;
531 data = inb(DATA_PORT);
532 if (data == AFL_PA_OK) {
533 return 0;
534 } /*PA_OK ? */
535 if (data == AFL_PA_ERR) {
536 STEN_LOW;
537 data = inb(DATA_PORT);
538 printk
539 ("### Error 1 aztcd: sendAztCmd %x Error Code %x\n",
540 cmd, data);
541 }
542 }
543 if (retry >= AZT_RETRY_ATTEMPTS) {
544 printk("### Error 2 aztcd: sendAztCmd %x\n ", cmd);
545 azt_error = 0xA5;
546 }
547 RETURNM("sendAztCmd", -1);
548}
549
550/*
551 * Send a seek command to the drive, return -1 on error, else 0
552*/
553static int aztSeek(struct azt_Play_msf *params)
554{
555 unsigned char data;
556 int retry;
557
558#ifdef AZT_DEBUG
559 printk("aztcd: aztSeek %02x:%02x:%02x\n",
560 params->start.min, params->start.sec, params->start.frame);
561#endif
562 for (retry = 0; retry < AZT_RETRY_ATTEMPTS; retry++) {
563 aztSendCmd(ACMD_SEEK);
564 outb(params->start.min, CMD_PORT);
565 outb(params->start.sec, CMD_PORT);
566 outb(params->start.frame, CMD_PORT);
567 STEN_LOW;
568 data = inb(DATA_PORT);
569 if (data == AFL_PA_OK) {
570 return 0;
571 } /*PA_OK ? */
572 if (data == AFL_PA_ERR) {
573 STEN_LOW;
574 data = inb(DATA_PORT);
575 printk("### Error 1 aztcd: aztSeek\n");
576 }
577 }
578 if (retry >= AZT_RETRY_ATTEMPTS) {
579 printk("### Error 2 aztcd: aztSeek\n ");
580 azt_error = 0xA5;
581 }
582 RETURNM("aztSeek", -1);
583}
584
585/* Send a Set Disk Type command
586 does not seem to work with Aztech drives, behavior is completely indepen-
587 dent on which mode is set ???
588*/
589static int aztSetDiskType(int type)
590{
591 unsigned char data;
592 int retry;
593
594#ifdef AZT_DEBUG
595 printk("aztcd: set disk type command: type= %i\n", type);
596#endif
597 for (retry = 0; retry < AZT_RETRY_ATTEMPTS; retry++) {
598 aztSendCmd(ACMD_SET_DISK_TYPE);
599 outb(type, CMD_PORT);
600 STEN_LOW;
601 data = inb(DATA_PORT);
602 if (data == AFL_PA_OK) { /*PA_OK ? */
603 azt_read_mode = type;
604 return 0;
605 }
606 if (data == AFL_PA_ERR) {
607 STEN_LOW;
608 data = inb(DATA_PORT);
609 printk
610 ("### Error 1 aztcd: aztSetDiskType %x Error Code %x\n",
611 type, data);
612 }
613 }
614 if (retry >= AZT_RETRY_ATTEMPTS) {
615 printk("### Error 2 aztcd: aztSetDiskType %x\n ", type);
616 azt_error = 0xA5;
617 }
618 RETURNM("aztSetDiskType", -1);
619}
620
621
622/* used in azt_poll to poll the status, expects another program to issue a
623 * ACMD_GET_STATUS directly before
624 */
625static int aztStatus(void)
626{
627 int st;
628/* int i;
629
630 i = inb(STATUS_PORT) & AFL_STATUS; is STEN=0? ???
631 if (!i)
632*/ STEN_LOW;
633 if (aztTimeOutCount < AZT_TIMEOUT) {
634 st = inb(DATA_PORT) & 0xFF;
635 return st;
636 } else
637 RETURNM("aztStatus", -1);
638}
639
640/*
641 * Get the drive status
642 */
643static int getAztStatus(void)
644{
645 int st;
646
647 if (aztSendCmd(ACMD_GET_STATUS))
648 RETURNM("getAztStatus 1", -1);
649 STEN_LOW;
650 st = inb(DATA_PORT) & 0xFF;
651#ifdef AZT_DEBUG
652 printk("aztcd: Status = %x\n", st);
653#endif
654 if ((st == 0xFF) || (st & AST_CMD_CHECK)) {
655 printk
656 ("aztcd: AST_CMD_CHECK error or no status available\n");
657 return -1;
658 }
659
660 if (((st & AST_MODE_BITS) != AST_BUSY)
661 && (aztAudioStatus == CDROM_AUDIO_PLAY))
662 /* XXX might be an error? look at q-channel? */
663 aztAudioStatus = CDROM_AUDIO_COMPLETED;
664
665 if ((st & AST_DSK_CHG) || (st & AST_NOT_READY)) {
666 aztDiskChanged = 1;
667 aztTocUpToDate = 0;
668 aztAudioStatus = CDROM_AUDIO_NO_STATUS;
669 }
670 return st;
671}
672
673
674/*
675 * Send a 'Play' command and get the status. Use only from the top half.
676 */
677static int aztPlay(struct azt_Play_msf *arg)
678{
679 if (sendAztCmd(ACMD_PLAY_AUDIO, arg) < 0)
680 RETURNM("aztPlay", -1);
681 return 0;
682}
683
684/*
685 * Subroutines to automatically close the door (tray) and
686 * lock it closed when the cd is mounted. Leave the tray
687 * locking as an option
688 */
689static void aztCloseDoor(void)
690{
691 aztSendCmd(ACMD_CLOSE);
692 STEN_LOW;
693 return;
694}
695
696static void aztLockDoor(void)
697{
698#if AZT_ALLOW_TRAY_LOCK
699 aztSendCmd(ACMD_LOCK);
700 STEN_LOW;
701#endif
702 return;
703}
704
705static void aztUnlockDoor(void)
706{
707#if AZT_ALLOW_TRAY_LOCK
708 aztSendCmd(ACMD_UNLOCK);
709 STEN_LOW;
710#endif
711 return;
712}
713
714/*
715 * Read a value from the drive. Should return quickly, so a busy wait
716 * is used to avoid excessive rescheduling. The read command itself must
717 * be issued with aztSendCmd() directly before
718 */
719static int aztGetValue(unsigned char *result)
720{
721 int s;
722
723 STEN_LOW;
724 if (aztTimeOutCount >= AZT_TIMEOUT) {
725 printk("aztcd: aztGetValue timeout\n");
726 return -1;
727 }
728 s = inb(DATA_PORT) & 0xFF;
729 *result = (unsigned char) s;
730 return 0;
731}
732
733/*
734 * Read the current Q-channel info. Also used for reading the
735 * table of contents.
736 */
737static int aztGetQChannelInfo(struct azt_Toc *qp)
738{
739 unsigned char notUsed;
740 int st;
741
742#ifdef AZT_DEBUG
743 printk("aztcd: starting aztGetQChannelInfo Time:%li\n", jiffies);
744#endif
745 if ((st = getAztStatus()) == -1)
746 RETURNM("aztGetQChannelInfo 1", -1);
747 if (aztSendCmd(ACMD_GET_Q_CHANNEL))
748 RETURNM("aztGetQChannelInfo 2", -1);
749 /*STEN_LOW_WAIT; ??? Dosemu0.60's cdrom.c does not like STEN_LOW_WAIT here */
750 if (aztGetValue(&notUsed))
751 RETURNM("aztGetQChannelInfo 3", -1); /*??? Nullbyte einlesen */
752 if ((st & AST_MODE_BITS) == AST_INITIAL) {
753 qp->ctrl_addr = 0; /* when audio stop ACMD_GET_Q_CHANNEL returns */
754 qp->track = 0; /* only one byte with Aztech drives */
755 qp->pointIndex = 0;
756 qp->trackTime.min = 0;
757 qp->trackTime.sec = 0;
758 qp->trackTime.frame = 0;
759 qp->diskTime.min = 0;
760 qp->diskTime.sec = 0;
761 qp->diskTime.frame = 0;
762 return 0;
763 } else {
764 if (aztGetValue(&qp->ctrl_addr) < 0)
765 RETURNM("aztGetQChannelInfo 4", -1);
766 if (aztGetValue(&qp->track) < 0)
767 RETURNM("aztGetQChannelInfo 4", -1);
768 if (aztGetValue(&qp->pointIndex) < 0)
769 RETURNM("aztGetQChannelInfo 4", -1);
770 if (aztGetValue(&qp->trackTime.min) < 0)
771 RETURNM("aztGetQChannelInfo 4", -1);
772 if (aztGetValue(&qp->trackTime.sec) < 0)
773 RETURNM("aztGetQChannelInfo 4", -1);
774 if (aztGetValue(&qp->trackTime.frame) < 0)
775 RETURNM("aztGetQChannelInfo 4", -1);
776 if (aztGetValue(&notUsed) < 0)
777 RETURNM("aztGetQChannelInfo 4", -1);
778 if (aztGetValue(&qp->diskTime.min) < 0)
779 RETURNM("aztGetQChannelInfo 4", -1);
780 if (aztGetValue(&qp->diskTime.sec) < 0)
781 RETURNM("aztGetQChannelInfo 4", -1);
782 if (aztGetValue(&qp->diskTime.frame) < 0)
783 RETURNM("aztGetQChannelInfo 4", -1);
784 }
785#ifdef AZT_DEBUG
786 printk("aztcd: exiting aztGetQChannelInfo Time:%li\n", jiffies);
787#endif
788 return 0;
789}
790
791/*
792 * Read the table of contents (TOC) and TOC header if necessary
793 */
794static int aztUpdateToc(void)
795{
796 int st;
797
798#ifdef AZT_DEBUG
799 printk("aztcd: starting aztUpdateToc Time:%li\n", jiffies);
800#endif
801 if (aztTocUpToDate)
802 return 0;
803
804 if (aztGetDiskInfo() < 0)
805 return -EIO;
806
807 if (aztGetToc(0) < 0)
808 return -EIO;
809
810 /*audio disk detection
811 with my Aztech drive there is no audio status bit, so I use the copy
812 protection bit of the first track. If this track is copy protected
813 (copy bit = 0), I assume, it's an audio disk. Strange, but works ??? */
814 if (!(Toc[DiskInfo.first].ctrl_addr & 0x40))
815 DiskInfo.audio = 1;
816 else
817 DiskInfo.audio = 0;
818
819 /* XA detection */
820 if (!DiskInfo.audio) {
821 azt_Play.start.min = 0; /*XA detection only seems to work */
822 azt_Play.start.sec = 2; /*when we play a track */
823 azt_Play.start.frame = 0;
824 azt_Play.end.min = 0;
825 azt_Play.end.sec = 0;
826 azt_Play.end.frame = 1;
827 if (sendAztCmd(ACMD_PLAY_READ, &azt_Play))
828 return -1;
829 DTEN_LOW;
830 for (st = 0; st < CD_FRAMESIZE; st++)
831 inb(DATA_PORT);
832 }
833 DiskInfo.xa = getAztStatus() & AST_MODE;
834 if (DiskInfo.xa) {
835 printk
836 ("aztcd: XA support experimental - mail results to Werner.Zimmermann@fht-esslingen.de\n");
837 }
838
839 /*multisession detection
840 support for multisession CDs is done automatically with Aztech drives,
841 we don't have to take care about TOC redirection; if we want the isofs
842 to take care about redirection, we have to set AZT_MULTISESSION to 1 */
843 DiskInfo.multi = 0;
844#if AZT_MULTISESSION
845 if (DiskInfo.xa) {
846 aztGetMultiDiskInfo(); /*here Disk.Info.multi is set */
847 }
848#endif
849 if (DiskInfo.multi) {
850 DiskInfo.lastSession.min = Toc[DiskInfo.next].diskTime.min;
851 DiskInfo.lastSession.sec = Toc[DiskInfo.next].diskTime.sec;
852 DiskInfo.lastSession.frame =
853 Toc[DiskInfo.next].diskTime.frame;
854 printk("aztcd: Multisession support experimental\n");
855 } else {
856 DiskInfo.lastSession.min =
857 Toc[DiskInfo.first].diskTime.min;
858 DiskInfo.lastSession.sec =
859 Toc[DiskInfo.first].diskTime.sec;
860 DiskInfo.lastSession.frame =
861 Toc[DiskInfo.first].diskTime.frame;
862 }
863
864 aztTocUpToDate = 1;
865#ifdef AZT_DEBUG
866 printk("aztcd: exiting aztUpdateToc Time:%li\n", jiffies);
867#endif
868 return 0;
869}
870
871
872/* Read the table of contents header, i.e. no. of tracks and start of first
873 * track
874 */
875static int aztGetDiskInfo(void)
876{
877 int limit;
878 unsigned char test;
879 struct azt_Toc qInfo;
880
881#ifdef AZT_DEBUG
882 printk("aztcd: starting aztGetDiskInfo Time:%li\n", jiffies);
883#endif
884 if (aztSendCmd(ACMD_SEEK_TO_LEADIN))
885 RETURNM("aztGetDiskInfo 1", -1);
886 STEN_LOW_WAIT;
887 test = 0;
888 for (limit = 300; limit > 0; limit--) {
889 if (aztGetQChannelInfo(&qInfo) < 0)
890 RETURNM("aztGetDiskInfo 2", -1);
891 if (qInfo.pointIndex == 0xA0) { /*Number of FirstTrack */
892 DiskInfo.first = qInfo.diskTime.min;
893 DiskInfo.first = azt_bcd2bin(DiskInfo.first);
894 test = test | 0x01;
895 }
896 if (qInfo.pointIndex == 0xA1) { /*Number of LastTrack */
897 DiskInfo.last = qInfo.diskTime.min;
898 DiskInfo.last = azt_bcd2bin(DiskInfo.last);
899 test = test | 0x02;
900 }
901 if (qInfo.pointIndex == 0xA2) { /*DiskLength */
902 DiskInfo.diskLength.min = qInfo.diskTime.min;
903 DiskInfo.diskLength.sec = qInfo.diskTime.sec;
904 DiskInfo.diskLength.frame = qInfo.diskTime.frame;
905 test = test | 0x04;
906 }
907 if ((qInfo.pointIndex == DiskInfo.first) && (test & 0x01)) { /*StartTime of First Track */
908 DiskInfo.firstTrack.min = qInfo.diskTime.min;
909 DiskInfo.firstTrack.sec = qInfo.diskTime.sec;
910 DiskInfo.firstTrack.frame = qInfo.diskTime.frame;
911 test = test | 0x08;
912 }
913 if (test == 0x0F)
914 break;
915 }
916#ifdef AZT_DEBUG
917 printk("aztcd: exiting aztGetDiskInfo Time:%li\n", jiffies);
918 printk
919 ("Disk Info: first %d last %d length %02X:%02X.%02X dez first %02X:%02X.%02X dez\n",
920 DiskInfo.first, DiskInfo.last, DiskInfo.diskLength.min,
921 DiskInfo.diskLength.sec, DiskInfo.diskLength.frame,
922 DiskInfo.firstTrack.min, DiskInfo.firstTrack.sec,
923 DiskInfo.firstTrack.frame);
924#endif
925 if (test != 0x0F)
926 return -1;
927 return 0;
928}
929
930#if AZT_MULTISESSION
931/*
932 * Get Multisession Disk Info
933 */
934static int aztGetMultiDiskInfo(void)
935{
936 int limit, k = 5;
937 unsigned char test;
938 struct azt_Toc qInfo;
939
940#ifdef AZT_DEBUG
941 printk("aztcd: starting aztGetMultiDiskInfo\n");
942#endif
943
944 do {
945 azt_Play.start.min = Toc[DiskInfo.last + 1].diskTime.min;
946 azt_Play.start.sec = Toc[DiskInfo.last + 1].diskTime.sec;
947 azt_Play.start.frame =
948 Toc[DiskInfo.last + 1].diskTime.frame;
949 test = 0;
950
951 for (limit = 30; limit > 0; limit--) { /*Seek for LeadIn of next session */
952 if (aztSeek(&azt_Play))
953 RETURNM("aztGetMultiDiskInfo 1", -1);
954 if (aztGetQChannelInfo(&qInfo) < 0)
955 RETURNM("aztGetMultiDiskInfo 2", -1);
956 if ((qInfo.track == 0) && (qInfo.pointIndex))
957 break; /*LeadIn found */
958 if ((azt_Play.start.sec += 10) > 59) {
959 azt_Play.start.sec = 0;
960 azt_Play.start.min++;
961 }
962 }
963 if (!limit)
964 break; /*Check, if a leadin track was found, if not we're
965 at the end of the disk */
966#ifdef AZT_DEBUG_MULTISESSION
967 printk("leadin found track %d pointIndex %x limit %d\n",
968 qInfo.track, qInfo.pointIndex, limit);
969#endif
970 for (limit = 300; limit > 0; limit--) {
971 if (++azt_Play.start.frame > 74) {
972 azt_Play.start.frame = 0;
973 if (azt_Play.start.sec > 59) {
974 azt_Play.start.sec = 0;
975 azt_Play.start.min++;
976 }
977 }
978 if (aztSeek(&azt_Play))
979 RETURNM("aztGetMultiDiskInfo 3", -1);
980 if (aztGetQChannelInfo(&qInfo) < 0)
981 RETURNM("aztGetMultiDiskInfo 4", -1);
982 if (qInfo.pointIndex == 0xA0) { /*Number of NextTrack */
983 DiskInfo.next = qInfo.diskTime.min;
984 DiskInfo.next = azt_bcd2bin(DiskInfo.next);
985 test = test | 0x01;
986 }
987 if (qInfo.pointIndex == 0xA1) { /*Number of LastTrack */
988 DiskInfo.last = qInfo.diskTime.min;
989 DiskInfo.last = azt_bcd2bin(DiskInfo.last);
990 test = test | 0x02;
991 }
992 if (qInfo.pointIndex == 0xA2) { /*DiskLength */
993 DiskInfo.diskLength.min =
994 qInfo.diskTime.min;
995 DiskInfo.diskLength.sec =
996 qInfo.diskTime.sec;
997 DiskInfo.diskLength.frame =
998 qInfo.diskTime.frame;
999 test = test | 0x04;
1000 }
1001 if ((qInfo.pointIndex == DiskInfo.next) && (test & 0x01)) { /*StartTime of Next Track */
1002 DiskInfo.nextSession.min =
1003 qInfo.diskTime.min;
1004 DiskInfo.nextSession.sec =
1005 qInfo.diskTime.sec;
1006 DiskInfo.nextSession.frame =
1007 qInfo.diskTime.frame;
1008 test = test | 0x08;
1009 }
1010 if (test == 0x0F)
1011 break;
1012 }
1013#ifdef AZT_DEBUG_MULTISESSION
1014 printk
1015 ("MultiDisk Info: first %d next %d last %d length %02x:%02x.%02x dez first %02x:%02x.%02x dez next %02x:%02x.%02x dez\n",
1016 DiskInfo.first, DiskInfo.next, DiskInfo.last,
1017 DiskInfo.diskLength.min, DiskInfo.diskLength.sec,
1018 DiskInfo.diskLength.frame, DiskInfo.firstTrack.min,
1019 DiskInfo.firstTrack.sec, DiskInfo.firstTrack.frame,
1020 DiskInfo.nextSession.min, DiskInfo.nextSession.sec,
1021 DiskInfo.nextSession.frame);
1022#endif
1023 if (test != 0x0F)
1024 break;
1025 else
1026 DiskInfo.multi = 1; /*found TOC of more than one session */
1027 aztGetToc(1);
1028 } while (--k);
1029
1030#ifdef AZT_DEBUG
1031 printk("aztcd: exiting aztGetMultiDiskInfo Time:%li\n", jiffies);
1032#endif
1033 return 0;
1034}
1035#endif
1036
1037/*
1038 * Read the table of contents (TOC)
1039 */
1040static int aztGetToc(int multi)
1041{
1042 int i, px;
1043 int limit;
1044 struct azt_Toc qInfo;
1045
1046#ifdef AZT_DEBUG
1047 printk("aztcd: starting aztGetToc Time:%li\n", jiffies);
1048#endif
1049 if (!multi) {
1050 for (i = 0; i < MAX_TRACKS; i++)
1051 Toc[i].pointIndex = 0;
1052 i = DiskInfo.last + 3;
1053 } else {
1054 for (i = DiskInfo.next; i < MAX_TRACKS; i++)
1055 Toc[i].pointIndex = 0;
1056 i = DiskInfo.last + 4 - DiskInfo.next;
1057 }
1058
1059/*Is there a good reason to stop motor before TOC read?
1060 if (aztSendCmd(ACMD_STOP)) RETURNM("aztGetToc 1",-1);
1061 STEN_LOW_WAIT;
1062*/
1063
1064 if (!multi) {
1065 azt_mode = 0x05;
1066 if (aztSendCmd(ACMD_SEEK_TO_LEADIN))
1067 RETURNM("aztGetToc 2", -1);
1068 STEN_LOW_WAIT;
1069 }
1070 for (limit = 300; limit > 0; limit--) {
1071 if (multi) {
1072 if (++azt_Play.start.sec > 59) {
1073 azt_Play.start.sec = 0;
1074 azt_Play.start.min++;
1075 }
1076 if (aztSeek(&azt_Play))
1077 RETURNM("aztGetToc 3", -1);
1078 }
1079 if (aztGetQChannelInfo(&qInfo) < 0)
1080 break;
1081
1082 px = azt_bcd2bin(qInfo.pointIndex);
1083
1084 if (px > 0 && px < MAX_TRACKS && qInfo.track == 0)
1085 if (Toc[px].pointIndex == 0) {
1086 Toc[px] = qInfo;
1087 i--;
1088 }
1089
1090 if (i <= 0)
1091 break;
1092 }
1093
1094 Toc[DiskInfo.last + 1].diskTime = DiskInfo.diskLength;
1095 Toc[DiskInfo.last].trackTime = DiskInfo.diskLength;
1096
1097#ifdef AZT_DEBUG_MULTISESSION
1098 printk("aztcd: exiting aztGetToc\n");
1099 for (i = 1; i <= DiskInfo.last + 1; i++)
1100 printk
1101 ("i = %2d ctl-adr = %02X track %2d px %02X %02X:%02X.%02X dez %02X:%02X.%02X dez\n",
1102 i, Toc[i].ctrl_addr, Toc[i].track, Toc[i].pointIndex,
1103 Toc[i].trackTime.min, Toc[i].trackTime.sec,
1104 Toc[i].trackTime.frame, Toc[i].diskTime.min,
1105 Toc[i].diskTime.sec, Toc[i].diskTime.frame);
1106 for (i = 100; i < 103; i++)
1107 printk
1108 ("i = %2d ctl-adr = %02X track %2d px %02X %02X:%02X.%02X dez %02X:%02X.%02X dez\n",
1109 i, Toc[i].ctrl_addr, Toc[i].track, Toc[i].pointIndex,
1110 Toc[i].trackTime.min, Toc[i].trackTime.sec,
1111 Toc[i].trackTime.frame, Toc[i].diskTime.min,
1112 Toc[i].diskTime.sec, Toc[i].diskTime.frame);
1113#endif
1114
1115 return limit > 0 ? 0 : -1;
1116}
1117
1118
1119/*##########################################################################
1120 Kernel Interface Functions
1121 ##########################################################################
1122*/
1123
1124#ifndef MODULE
1125static int __init aztcd_setup(char *str)
1126{
1127 int ints[4];
1128
1129 (void) get_options(str, ARRAY_SIZE(ints), ints);
1130
1131 if (ints[0] > 0)
1132 azt_port = ints[1];
1133 if (ints[1] > 1)
1134 azt_cont = ints[2];
1135 return 1;
1136}
1137
1138__setup("aztcd=", aztcd_setup);
1139
1140#endif /* !MODULE */
1141
1142/*
1143 * Checking if the media has been changed
1144*/
1145static int check_aztcd_media_change(struct gendisk *disk)
1146{
1147 if (aztDiskChanged) { /* disk changed */
1148 aztDiskChanged = 0;
1149 return 1;
1150 } else
1151 return 0; /* no change */
1152}
1153
1154/*
1155 * Kernel IO-controls
1156*/
1157static int aztcd_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
1158 unsigned long arg)
1159{
1160 int i;
1161 struct azt_Toc qInfo;
1162 struct cdrom_ti ti;
1163 struct cdrom_tochdr tocHdr;
1164 struct cdrom_msf msf;
1165 struct cdrom_tocentry entry;
1166 struct azt_Toc *tocPtr;
1167 struct cdrom_subchnl subchnl;
1168 struct cdrom_volctrl volctrl;
1169 void __user *argp = (void __user *)arg;
1170
1171#ifdef AZT_DEBUG
1172 printk("aztcd: starting aztcd_ioctl - Command:%x Time: %li\n",
1173 cmd, jiffies);
1174 printk("aztcd Status %x\n", getAztStatus());
1175#endif
1176 if (!ip)
1177 RETURNM("aztcd_ioctl 1", -EINVAL);
1178 if (getAztStatus() < 0)
1179 RETURNM("aztcd_ioctl 2", -EIO);
1180 if ((!aztTocUpToDate) || (aztDiskChanged)) {
1181 if ((i = aztUpdateToc()) < 0)
1182 RETURNM("aztcd_ioctl 3", i); /* error reading TOC */
1183 }
1184
1185 switch (cmd) {
1186 case CDROMSTART: /* Spin up the drive. Don't know, what to do,
1187 at least close the tray */
1188#if AZT_PRIVATE_IOCTLS
1189 if (aztSendCmd(ACMD_CLOSE))
1190 RETURNM("aztcd_ioctl 4", -1);
1191 STEN_LOW_WAIT;
1192#endif
1193 break;
1194 case CDROMSTOP: /* Spin down the drive */
1195 if (aztSendCmd(ACMD_STOP))
1196 RETURNM("aztcd_ioctl 5", -1);
1197 STEN_LOW_WAIT;
1198 /* should we do anything if it fails? */
1199 aztAudioStatus = CDROM_AUDIO_NO_STATUS;
1200 break;
1201 case CDROMPAUSE: /* Pause the drive */
1202 if (aztAudioStatus != CDROM_AUDIO_PLAY)
1203 return -EINVAL;
1204
1205 if (aztGetQChannelInfo(&qInfo) < 0) { /* didn't get q channel info */
1206 aztAudioStatus = CDROM_AUDIO_NO_STATUS;
1207 RETURNM("aztcd_ioctl 7", 0);
1208 }
1209 azt_Play.start = qInfo.diskTime; /* remember restart point */
1210
1211 if (aztSendCmd(ACMD_PAUSE))
1212 RETURNM("aztcd_ioctl 8", -1);
1213 STEN_LOW_WAIT;
1214 aztAudioStatus = CDROM_AUDIO_PAUSED;
1215 break;
1216 case CDROMRESUME: /* Play it again, Sam */
1217 if (aztAudioStatus != CDROM_AUDIO_PAUSED)
1218 return -EINVAL;
1219 /* restart the drive at the saved position. */
1220 i = aztPlay(&azt_Play);
1221 if (i < 0) {
1222 aztAudioStatus = CDROM_AUDIO_ERROR;
1223 return -EIO;
1224 }
1225 aztAudioStatus = CDROM_AUDIO_PLAY;
1226 break;
1227 case CDROMMULTISESSION: /*multisession support -- experimental */
1228 {
1229 struct cdrom_multisession ms;
1230#ifdef AZT_DEBUG
1231 printk("aztcd ioctl MULTISESSION\n");
1232#endif
1233 if (copy_from_user(&ms, argp,
1234 sizeof(struct cdrom_multisession)))
1235 return -EFAULT;
1236 if (ms.addr_format == CDROM_MSF) {
1237 ms.addr.msf.minute =
1238 azt_bcd2bin(DiskInfo.lastSession.min);
1239 ms.addr.msf.second =
1240 azt_bcd2bin(DiskInfo.lastSession.sec);
1241 ms.addr.msf.frame =
1242 azt_bcd2bin(DiskInfo.lastSession.
1243 frame);
1244 } else if (ms.addr_format == CDROM_LBA)
1245 ms.addr.lba =
1246 azt_msf2hsg(&DiskInfo.lastSession);
1247 else
1248 return -EINVAL;
1249 ms.xa_flag = DiskInfo.xa;
1250 if (copy_to_user(argp, &ms,
1251 sizeof(struct cdrom_multisession)))
1252 return -EFAULT;
1253#ifdef AZT_DEBUG
1254 if (ms.addr_format == CDROM_MSF)
1255 printk
1256 ("aztcd multisession xa:%d, msf:%02x:%02x.%02x [%02x:%02x.%02x])\n",
1257 ms.xa_flag, ms.addr.msf.minute,
1258 ms.addr.msf.second, ms.addr.msf.frame,
1259 DiskInfo.lastSession.min,
1260 DiskInfo.lastSession.sec,
1261 DiskInfo.lastSession.frame);
1262 else
1263 printk
1264 ("aztcd multisession %d, lba:0x%08x [%02x:%02x.%02x])\n",
1265 ms.xa_flag, ms.addr.lba,
1266 DiskInfo.lastSession.min,
1267 DiskInfo.lastSession.sec,
1268 DiskInfo.lastSession.frame);
1269#endif
1270 return 0;
1271 }
1272 case CDROMPLAYTRKIND: /* Play a track. This currently ignores index. */
1273 if (copy_from_user(&ti, argp, sizeof ti))
1274 return -EFAULT;
1275 if (ti.cdti_trk0 < DiskInfo.first
1276 || ti.cdti_trk0 > DiskInfo.last
1277 || ti.cdti_trk1 < ti.cdti_trk0) {
1278 return -EINVAL;
1279 }
1280 if (ti.cdti_trk1 > DiskInfo.last)
1281 ti.cdti_trk1 = DiskInfo.last;
1282 azt_Play.start = Toc[ti.cdti_trk0].diskTime;
1283 azt_Play.end = Toc[ti.cdti_trk1 + 1].diskTime;
1284#ifdef AZT_DEBUG
1285 printk("aztcd play: %02x:%02x.%02x to %02x:%02x.%02x\n",
1286 azt_Play.start.min, azt_Play.start.sec,
1287 azt_Play.start.frame, azt_Play.end.min,
1288 azt_Play.end.sec, azt_Play.end.frame);
1289#endif
1290 i = aztPlay(&azt_Play);
1291 if (i < 0) {
1292 aztAudioStatus = CDROM_AUDIO_ERROR;
1293 return -EIO;
1294 }
1295 aztAudioStatus = CDROM_AUDIO_PLAY;
1296 break;
1297 case CDROMPLAYMSF: /* Play starting at the given MSF address. */
1298/* if (aztAudioStatus == CDROM_AUDIO_PLAY)
1299 { if (aztSendCmd(ACMD_STOP)) RETURNM("aztcd_ioctl 9",-1);
1300 STEN_LOW;
1301 aztAudioStatus = CDROM_AUDIO_NO_STATUS;
1302 }
1303*/
1304 if (copy_from_user(&msf, argp, sizeof msf))
1305 return -EFAULT;
1306 /* convert to bcd */
1307 azt_bin2bcd(&msf.cdmsf_min0);
1308 azt_bin2bcd(&msf.cdmsf_sec0);
1309 azt_bin2bcd(&msf.cdmsf_frame0);
1310 azt_bin2bcd(&msf.cdmsf_min1);
1311 azt_bin2bcd(&msf.cdmsf_sec1);
1312 azt_bin2bcd(&msf.cdmsf_frame1);
1313 azt_Play.start.min = msf.cdmsf_min0;
1314 azt_Play.start.sec = msf.cdmsf_sec0;
1315 azt_Play.start.frame = msf.cdmsf_frame0;
1316 azt_Play.end.min = msf.cdmsf_min1;
1317 azt_Play.end.sec = msf.cdmsf_sec1;
1318 azt_Play.end.frame = msf.cdmsf_frame1;
1319#ifdef AZT_DEBUG
1320 printk("aztcd play: %02x:%02x.%02x to %02x:%02x.%02x\n",
1321 azt_Play.start.min, azt_Play.start.sec,
1322 azt_Play.start.frame, azt_Play.end.min,
1323 azt_Play.end.sec, azt_Play.end.frame);
1324#endif
1325 i = aztPlay(&azt_Play);
1326 if (i < 0) {
1327 aztAudioStatus = CDROM_AUDIO_ERROR;
1328 return -EIO;
1329 }
1330 aztAudioStatus = CDROM_AUDIO_PLAY;
1331 break;
1332
1333 case CDROMREADTOCHDR: /* Read the table of contents header */
1334 tocHdr.cdth_trk0 = DiskInfo.first;
1335 tocHdr.cdth_trk1 = DiskInfo.last;
1336 if (copy_to_user(argp, &tocHdr, sizeof tocHdr))
1337 return -EFAULT;
1338 break;
1339 case CDROMREADTOCENTRY: /* Read an entry in the table of contents */
1340 if (copy_from_user(&entry, argp, sizeof entry))
1341 return -EFAULT;
1342 if ((!aztTocUpToDate) || aztDiskChanged)
1343 aztUpdateToc();
1344 if (entry.cdte_track == CDROM_LEADOUT)
1345 tocPtr = &Toc[DiskInfo.last + 1];
1346 else if (entry.cdte_track > DiskInfo.last
1347 || entry.cdte_track < DiskInfo.first) {
1348 return -EINVAL;
1349 } else
1350 tocPtr = &Toc[entry.cdte_track];
1351 entry.cdte_adr = tocPtr->ctrl_addr;
1352 entry.cdte_ctrl = tocPtr->ctrl_addr >> 4;
1353 if (entry.cdte_format == CDROM_LBA)
1354 entry.cdte_addr.lba =
1355 azt_msf2hsg(&tocPtr->diskTime);
1356 else if (entry.cdte_format == CDROM_MSF) {
1357 entry.cdte_addr.msf.minute =
1358 azt_bcd2bin(tocPtr->diskTime.min);
1359 entry.cdte_addr.msf.second =
1360 azt_bcd2bin(tocPtr->diskTime.sec);
1361 entry.cdte_addr.msf.frame =
1362 azt_bcd2bin(tocPtr->diskTime.frame);
1363 } else {
1364 return -EINVAL;
1365 }
1366 if (copy_to_user(argp, &entry, sizeof entry))
1367 return -EFAULT;
1368 break;
1369 case CDROMSUBCHNL: /* Get subchannel info */
1370 if (copy_from_user
1371 (&subchnl, argp, sizeof(struct cdrom_subchnl)))
1372 return -EFAULT;
1373 if (aztGetQChannelInfo(&qInfo) < 0) {
1374#ifdef AZT_DEBUG
1375 printk
1376 ("aztcd: exiting aztcd_ioctl - Error 3 - Command:%x\n",
1377 cmd);
1378#endif
1379 return -EIO;
1380 }
1381 subchnl.cdsc_audiostatus = aztAudioStatus;
1382 subchnl.cdsc_adr = qInfo.ctrl_addr;
1383 subchnl.cdsc_ctrl = qInfo.ctrl_addr >> 4;
1384 subchnl.cdsc_trk = azt_bcd2bin(qInfo.track);
1385 subchnl.cdsc_ind = azt_bcd2bin(qInfo.pointIndex);
1386 if (subchnl.cdsc_format == CDROM_LBA) {
1387 subchnl.cdsc_absaddr.lba =
1388 azt_msf2hsg(&qInfo.diskTime);
1389 subchnl.cdsc_reladdr.lba =
1390 azt_msf2hsg(&qInfo.trackTime);
1391 } else { /*default */
1392 subchnl.cdsc_format = CDROM_MSF;
1393 subchnl.cdsc_absaddr.msf.minute =
1394 azt_bcd2bin(qInfo.diskTime.min);
1395 subchnl.cdsc_absaddr.msf.second =
1396 azt_bcd2bin(qInfo.diskTime.sec);
1397 subchnl.cdsc_absaddr.msf.frame =
1398 azt_bcd2bin(qInfo.diskTime.frame);
1399 subchnl.cdsc_reladdr.msf.minute =
1400 azt_bcd2bin(qInfo.trackTime.min);
1401 subchnl.cdsc_reladdr.msf.second =
1402 azt_bcd2bin(qInfo.trackTime.sec);
1403 subchnl.cdsc_reladdr.msf.frame =
1404 azt_bcd2bin(qInfo.trackTime.frame);
1405 }
1406 if (copy_to_user(argp, &subchnl, sizeof(struct cdrom_subchnl)))
1407 return -EFAULT;
1408 break;
1409 case CDROMVOLCTRL: /* Volume control
1410 * With my Aztech CD268-01A volume control does not work, I can only
1411 turn the channels on (any value !=0) or off (value==0). Maybe it
1412 works better with your drive */
1413 if (copy_from_user(&volctrl, argp, sizeof(volctrl)))
1414 return -EFAULT;
1415 azt_Play.start.min = 0x21;
1416 azt_Play.start.sec = 0x84;
1417 azt_Play.start.frame = volctrl.channel0;
1418 azt_Play.end.min = volctrl.channel1;
1419 azt_Play.end.sec = volctrl.channel2;
1420 azt_Play.end.frame = volctrl.channel3;
1421 sendAztCmd(ACMD_SET_VOLUME, &azt_Play);
1422 STEN_LOW_WAIT;
1423 break;
1424 case CDROMEJECT:
1425 aztUnlockDoor(); /* Assume user knows what they're doing */
1426 /* all drives can at least stop! */
1427 if (aztAudioStatus == CDROM_AUDIO_PLAY) {
1428 if (aztSendCmd(ACMD_STOP))
1429 RETURNM("azt_ioctl 10", -1);
1430 STEN_LOW_WAIT;
1431 }
1432 if (aztSendCmd(ACMD_EJECT))
1433 RETURNM("azt_ioctl 11", -1);
1434 STEN_LOW_WAIT;
1435 aztAudioStatus = CDROM_AUDIO_NO_STATUS;
1436 break;
1437 case CDROMEJECT_SW:
1438 azt_auto_eject = (char) arg;
1439 break;
1440 case CDROMRESET:
1441 outb(ACMD_SOFT_RESET, CMD_PORT); /*send reset */
1442 STEN_LOW;
1443 if (inb(DATA_PORT) != AFL_OP_OK) { /*OP_OK? */
1444 printk
1445 ("aztcd: AZTECH CD-ROM drive does not respond\n");
1446 }
1447 break;
1448/*Take care, the following code is not compatible with other CD-ROM drivers,
1449 use it at your own risk with cdplay.c. Set AZT_PRIVATE_IOCTLS to 0 in aztcd.h,
1450 if you do not want to use it!
1451*/
1452#if AZT_PRIVATE_IOCTLS
1453 case CDROMREADCOOKED: /*read data in mode 1 (2048 Bytes) */
1454 case CDROMREADRAW: /*read data in mode 2 (2336 Bytes) */
1455 {
1456 if (copy_from_user(&msf, argp, sizeof msf))
1457 return -EFAULT;
1458 /* convert to bcd */
1459 azt_bin2bcd(&msf.cdmsf_min0);
1460 azt_bin2bcd(&msf.cdmsf_sec0);
1461 azt_bin2bcd(&msf.cdmsf_frame0);
1462 msf.cdmsf_min1 = 0;
1463 msf.cdmsf_sec1 = 0;
1464 msf.cdmsf_frame1 = 1; /*read only one frame */
1465 azt_Play.start.min = msf.cdmsf_min0;
1466 azt_Play.start.sec = msf.cdmsf_sec0;
1467 azt_Play.start.frame = msf.cdmsf_frame0;
1468 azt_Play.end.min = msf.cdmsf_min1;
1469 azt_Play.end.sec = msf.cdmsf_sec1;
1470 azt_Play.end.frame = msf.cdmsf_frame1;
1471 if (cmd == CDROMREADRAW) {
1472 if (DiskInfo.xa) {
1473 return -1; /*XA Disks can't be read raw */
1474 } else {
1475 if (sendAztCmd(ACMD_PLAY_READ_RAW, &azt_Play))
1476 return -1;
1477 DTEN_LOW;
1478 insb(DATA_PORT, buf, CD_FRAMESIZE_RAW);
1479 if (copy_to_user(argp, &buf, CD_FRAMESIZE_RAW))
1480 return -EFAULT;
1481 }
1482 } else
1483 /*CDROMREADCOOKED*/ {
1484 if (sendAztCmd(ACMD_PLAY_READ, &azt_Play))
1485 return -1;
1486 DTEN_LOW;
1487 insb(DATA_PORT, buf, CD_FRAMESIZE);
1488 if (copy_to_user(argp, &buf, CD_FRAMESIZE))
1489 return -EFAULT;
1490 }
1491 }
1492 break;
1493 case CDROMSEEK: /*seek msf address */
1494 if (copy_from_user(&msf, argp, sizeof msf))
1495 return -EFAULT;
1496 /* convert to bcd */
1497 azt_bin2bcd(&msf.cdmsf_min0);
1498 azt_bin2bcd(&msf.cdmsf_sec0);
1499 azt_bin2bcd(&msf.cdmsf_frame0);
1500 azt_Play.start.min = msf.cdmsf_min0;
1501 azt_Play.start.sec = msf.cdmsf_sec0;
1502 azt_Play.start.frame = msf.cdmsf_frame0;
1503 if (aztSeek(&azt_Play))
1504 return -1;
1505 break;
1506#endif /*end of incompatible code */
1507 case CDROMREADMODE1: /*set read data in mode 1 */
1508 return aztSetDiskType(AZT_MODE_1);
1509 case CDROMREADMODE2: /*set read data in mode 2 */
1510 return aztSetDiskType(AZT_MODE_2);
1511 default:
1512 return -EINVAL;
1513 }
1514#ifdef AZT_DEBUG
1515 printk("aztcd: exiting aztcd_ioctl Command:%x Time:%li\n", cmd,
1516 jiffies);
1517#endif
1518 return 0;
1519}
1520
1521/*
1522 * Take care of the different block sizes between cdrom and Linux.
1523 * When Linux gets variable block sizes this will probably go away.
1524 */
1525static void azt_transfer(void)
1526{
1527#ifdef AZT_TEST
1528 printk("aztcd: executing azt_transfer Time:%li\n", jiffies);
1529#endif
1530 if (!current_valid())
1531 return;
1532
1533 while (CURRENT->nr_sectors) {
1534 int bn = CURRENT->sector / 4;
1535 int i;
1536 for (i = 0; i < AZT_BUF_SIZ && azt_buf_bn[i] != bn; ++i);
1537 if (i < AZT_BUF_SIZ) {
1538 int offs = (i * 4 + (CURRENT->sector & 3)) * 512;
1539 int nr_sectors = 4 - (CURRENT->sector & 3);
1540 if (azt_buf_out != i) {
1541 azt_buf_out = i;
1542 if (azt_buf_bn[i] != bn) {
1543 azt_buf_out = -1;
1544 continue;
1545 }
1546 }
1547 if (nr_sectors > CURRENT->nr_sectors)
1548 nr_sectors = CURRENT->nr_sectors;
1549 memcpy(CURRENT->buffer, azt_buf + offs,
1550 nr_sectors * 512);
1551 CURRENT->nr_sectors -= nr_sectors;
1552 CURRENT->sector += nr_sectors;
1553 CURRENT->buffer += nr_sectors * 512;
1554 } else {
1555 azt_buf_out = -1;
1556 break;
1557 }
1558 }
1559}
1560
1561static void do_aztcd_request(request_queue_t * q)
1562{
1563#ifdef AZT_TEST
1564 printk(" do_aztcd_request(%ld+%ld) Time:%li\n", CURRENT->sector,
1565 CURRENT->nr_sectors, jiffies);
1566#endif
1567 if (DiskInfo.audio) {
1568 printk("aztcd: Error, tried to mount an Audio CD\n");
1569 end_request(CURRENT, 0);
1570 return;
1571 }
1572 azt_transfer_is_active = 1;
1573 while (current_valid()) {
1574 azt_transfer();
1575 if (CURRENT->nr_sectors == 0) {
1576 end_request(CURRENT, 1);
1577 } else {
1578 azt_buf_out = -1; /* Want to read a block not in buffer */
1579 if (azt_state == AZT_S_IDLE) {
1580 if ((!aztTocUpToDate) || aztDiskChanged) {
1581 if (aztUpdateToc() < 0) {
1582 while (current_valid())
1583 end_request(CURRENT, 0);
1584 break;
1585 }
1586 }
1587 azt_state = AZT_S_START;
1588 AztTries = 5;
1589 SET_TIMER(azt_poll, HZ / 100);
1590 }
1591 break;
1592 }
1593 }
1594 azt_transfer_is_active = 0;
1595#ifdef AZT_TEST2
1596 printk
1597 ("azt_next_bn:%x azt_buf_in:%x azt_buf_out:%x azt_buf_bn:%x\n",
1598 azt_next_bn, azt_buf_in, azt_buf_out, azt_buf_bn[azt_buf_in]);
1599 printk(" do_aztcd_request ends Time:%li\n", jiffies);
1600#endif
1601}
1602
1603
1604static void azt_invalidate_buffers(void)
1605{
1606 int i;
1607
1608#ifdef AZT_DEBUG
1609 printk("aztcd: executing azt_invalidate_buffers\n");
1610#endif
1611 for (i = 0; i < AZT_BUF_SIZ; ++i)
1612 azt_buf_bn[i] = -1;
1613 azt_buf_out = -1;
1614}
1615
1616/*
1617 * Open the device special file. Check that a disk is in.
1618 */
1619static int aztcd_open(struct inode *ip, struct file *fp)
1620{
1621 int st;
1622
1623#ifdef AZT_DEBUG
1624 printk("aztcd: starting aztcd_open\n");
1625#endif
1626
1627 if (aztPresent == 0)
1628 return -ENXIO; /* no hardware */
1629
1630 if (!azt_open_count && azt_state == AZT_S_IDLE) {
1631 azt_invalidate_buffers();
1632
1633 st = getAztStatus(); /* check drive status */
1634 if (st == -1)
1635 goto err_out; /* drive doesn't respond */
1636
1637 if (st & AST_DOOR_OPEN) { /* close door, then get the status again. */
1638 printk("aztcd: Door Open?\n");
1639 aztCloseDoor();
1640 st = getAztStatus();
1641 }
1642
1643 if ((st & AST_NOT_READY) || (st & AST_DSK_CHG)) { /*no disk in drive or changed */
1644 printk
1645 ("aztcd: Disk Changed or No Disk in Drive?\n");
1646 aztTocUpToDate = 0;
1647 }
1648 if (aztUpdateToc())
1649 goto err_out;
1650
1651 }
1652 ++azt_open_count;
1653 aztLockDoor();
1654
1655#ifdef AZT_DEBUG
1656 printk("aztcd: exiting aztcd_open\n");
1657#endif
1658 return 0;
1659
1660 err_out:
1661 return -EIO;
1662}
1663
1664
1665/*
1666 * On close, we flush all azt blocks from the buffer cache.
1667 */
1668static int aztcd_release(struct inode *inode, struct file *file)
1669{
1670#ifdef AZT_DEBUG
1671 printk("aztcd: executing aztcd_release\n");
1672 printk("inode: %p, device: %s file: %p\n", inode,
1673 inode->i_bdev->bd_disk->disk_name, file);
1674#endif
1675 if (!--azt_open_count) {
1676 azt_invalidate_buffers();
1677 aztUnlockDoor();
1678 if (azt_auto_eject)
1679 aztSendCmd(ACMD_EJECT);
1680 CLEAR_TIMER;
1681 }
1682 return 0;
1683}
1684
1685static struct gendisk *azt_disk;
1686
1687/*
1688 * Test for presence of drive and initialize it. Called at boot time.
1689 */
1690
1691static int __init aztcd_init(void)
1692{
1693 long int count, max_count;
1694 unsigned char result[50];
1695 int st;
1696 void* status = NULL;
1697 int i = 0;
1698 int ret = 0;
1699
1700 if (azt_port == 0) {
1701 printk(KERN_INFO "aztcd: no Aztech CD-ROM Initialization");
1702 return -EIO;
1703 }
1704
1705 printk(KERN_INFO "aztcd: AZTECH, ORCHID, OKANO, WEARNES, TXC, CyDROM "
1706 "CD-ROM Driver\n");
1707 printk(KERN_INFO "aztcd: (C) 1994-98 W.Zimmermann\n");
1708 if (azt_port == -1) {
1709 printk
1710 ("aztcd: DriverVersion=%s For IDE/ATAPI-drives use ide-cd.c\n",
1711 AZT_VERSION);
1712 } else
1713 printk
1714 ("aztcd: DriverVersion=%s BaseAddress=0x%x For IDE/ATAPI-drives use ide-cd.c\n",
1715 AZT_VERSION, azt_port);
1716 printk(KERN_INFO "aztcd: If you have problems, read /usr/src/linux/"
1717 "Documentation/cdrom/aztcd\n");
1718
1719
1720#ifdef AZT_SW32 /*CDROM connected to Soundwave32 card */
1721 if ((0xFF00 & inw(AZT_SW32_ID_REG)) != 0x4500) {
1722 printk
1723 ("aztcd: no Soundwave32 card detected at base:%x init:%x config:%x id:%x\n",
1724 AZT_SW32_BASE_ADDR, AZT_SW32_INIT,
1725 AZT_SW32_CONFIG_REG, AZT_SW32_ID_REG);
1726 return -EIO;
1727 } else {
1728 printk(KERN_INFO
1729 "aztcd: Soundwave32 card detected at %x Version %x\n",
1730 AZT_SW32_BASE_ADDR, inw(AZT_SW32_ID_REG));
1731 outw(AZT_SW32_INIT, AZT_SW32_CONFIG_REG);
1732 for (count = 0; count < 10000; count++); /*delay a bit */
1733 }
1734#endif
1735
1736 /* check for presence of drive */
1737
1738 if (azt_port == -1) { /* autoprobing for proprietary interface */
1739 for (i = 0; (azt_port_auto[i] != 0) && (i < 16); i++) {
1740 azt_port = azt_port_auto[i];
1741 printk(KERN_INFO "aztcd: Autoprobing BaseAddress=0x%x"
1742 "\n", azt_port);
1743 /*proprietary interfaces need 4 bytes */
1744 if (!request_region(azt_port, 4, "aztcd")) {
1745 continue;
1746 }
1747 outb(POLLED, MODE_PORT);
1748 inb(CMD_PORT);
1749 inb(CMD_PORT);
1750 outb(ACMD_GET_VERSION, CMD_PORT); /*Try to get version info */
1751
1752 aztTimeOutCount = 0;
1753 do {
1754 aztIndatum = inb(STATUS_PORT);
1755 aztTimeOutCount++;
1756 if (aztTimeOutCount >= AZT_FAST_TIMEOUT)
1757 break;
1758 } while (aztIndatum & AFL_STATUS);
1759 if (inb(DATA_PORT) == AFL_OP_OK) { /* OK drive found */
1760 break;
1761 }
1762 else { /* Drive not found on this port - try next one */
1763 release_region(azt_port, 4);
1764 }
1765 }
1766 if ((azt_port_auto[i] == 0) || (i == 16)) {
1767 printk(KERN_INFO "aztcd: no AZTECH CD-ROM drive found\n");
1768 return -EIO;
1769 }
1770 } else { /* no autoprobing */
1771 if ((azt_port == 0x1f0) || (azt_port == 0x170))
1772 status = request_region(azt_port, 8, "aztcd"); /*IDE-interfaces need 8 bytes */
1773 else
1774 status = request_region(azt_port, 4, "aztcd"); /*proprietary interfaces need 4 bytes */
1775 if (!status) {
1776 printk(KERN_WARNING "aztcd: conflict, I/O port (%X) "
1777 "already used\n", azt_port);
1778 return -EIO;
1779 }
1780
1781 if ((azt_port == 0x1f0) || (azt_port == 0x170))
1782 SWITCH_IDE_SLAVE; /*switch IDE interface to slave configuration */
1783
1784 outb(POLLED, MODE_PORT);
1785 inb(CMD_PORT);
1786 inb(CMD_PORT);
1787 outb(ACMD_GET_VERSION, CMD_PORT); /*Try to get version info */
1788
1789 aztTimeOutCount = 0;
1790 do {
1791 aztIndatum = inb(STATUS_PORT);
1792 aztTimeOutCount++;
1793 if (aztTimeOutCount >= AZT_FAST_TIMEOUT)
1794 break;
1795 } while (aztIndatum & AFL_STATUS);
1796
1797 if (inb(DATA_PORT) != AFL_OP_OK) { /*OP_OK? If not, reset and try again */
1798#ifndef MODULE
1799 if (azt_cont != 0x79) {
1800 printk(KERN_WARNING "aztcd: no AZTECH CD-ROM "
1801 "drive found-Try boot parameter aztcd="
1802 "<BaseAddress>,0x79\n");
1803 ret = -EIO;
1804 goto err_out;
1805 }
1806#else
1807 if (0) {
1808 }
1809#endif
1810 else {
1811 printk(KERN_INFO "aztcd: drive reset - "
1812 "please wait\n");
1813 for (count = 0; count < 50; count++) {
1814 inb(STATUS_PORT); /*removing all data from earlier tries */
1815 inb(DATA_PORT);
1816 }
1817 outb(POLLED, MODE_PORT);
1818 inb(CMD_PORT);
1819 inb(CMD_PORT);
1820 getAztStatus(); /*trap errors */
1821 outb(ACMD_SOFT_RESET, CMD_PORT); /*send reset */
1822 STEN_LOW;
1823 if (inb(DATA_PORT) != AFL_OP_OK) { /*OP_OK? */
1824 printk(KERN_WARNING "aztcd: no AZTECH "
1825 "CD-ROM drive found\n");
1826 ret = -EIO;
1827 goto err_out;
1828 }
1829
1830 for (count = 0; count < AZT_TIMEOUT;
1831 count++)
1832 barrier(); /* Stop gcc 2.96 being smart */
1833 /* use udelay(), damnit -- AV */
1834
1835 if ((st = getAztStatus()) == -1) {
1836 printk(KERN_WARNING "aztcd: Drive Status"
1837 " Error Status=%x\n", st);
1838 ret = -EIO;
1839 goto err_out;
1840 }
1841#ifdef AZT_DEBUG
1842 printk(KERN_DEBUG "aztcd: Status = %x\n", st);
1843#endif
1844 outb(POLLED, MODE_PORT);
1845 inb(CMD_PORT);
1846 inb(CMD_PORT);
1847 outb(ACMD_GET_VERSION, CMD_PORT); /*GetVersion */
1848 STEN_LOW;
1849 OP_OK;
1850 }
1851 }
1852 }
1853
1854 azt_init_end = 1;
1855 STEN_LOW;
1856 result[0] = inb(DATA_PORT); /*reading in a null byte??? */
1857 for (count = 1; count < 50; count++) { /*Reading version string */
1858 aztTimeOutCount = 0; /*here we must implement STEN_LOW differently */
1859 do {
1860 aztIndatum = inb(STATUS_PORT); /*because we want to exit by timeout */
1861 aztTimeOutCount++;
1862 if (aztTimeOutCount >= AZT_FAST_TIMEOUT)
1863 break;
1864 } while (aztIndatum & AFL_STATUS);
1865 if (aztTimeOutCount >= AZT_FAST_TIMEOUT)
1866 break; /*all chars read? */
1867 result[count] = inb(DATA_PORT);
1868 }
1869 if (count > 30)
1870 max_count = 30; /*print max.30 chars of the version string */
1871 else
1872 max_count = count;
1873 printk(KERN_INFO "aztcd: FirmwareVersion=");
1874 for (count = 1; count < max_count; count++)
1875 printk("%c", result[count]);
1876 printk("<<>> ");
1877
1878 if ((result[1] == 'A') && (result[2] == 'Z') && (result[3] == 'T')) {
1879 printk("AZTECH drive detected\n");
1880 /*AZTECH*/}
1881 else if ((result[2] == 'C') && (result[3] == 'D')
1882 && (result[4] == 'D')) {
1883 printk("ORCHID or WEARNES drive detected\n"); /*ORCHID or WEARNES */
1884 } else if ((result[1] == 0x03) && (result[2] == '5')) {
1885 printk("TXC or CyCDROM drive detected\n"); /*Conrad TXC, CyCDROM */
1886 } else { /*OTHERS or none */
1887 printk("\nunknown drive or firmware version detected\n");
1888 printk
1889 ("aztcd may not run stable, if you want to try anyhow,\n");
1890 printk("boot with: aztcd=<BaseAddress>,0x79\n");
1891 if ((azt_cont != 0x79)) {
1892 printk("aztcd: FirmwareVersion=");
1893 for (count = 1; count < 5; count++)
1894 printk("%c", result[count]);
1895 printk("<<>> ");
1896 printk("Aborted\n");
1897 ret = -EIO;
1898 goto err_out;
1899 }
1900 }
1901 azt_disk = alloc_disk(1);
1902 if (!azt_disk)
1903 goto err_out;
1904
1905 if (register_blkdev(MAJOR_NR, "aztcd")) {
1906 ret = -EIO;
1907 goto err_out2;
1908 }
1909
1910 azt_queue = blk_init_queue(do_aztcd_request, &aztSpin);
1911 if (!azt_queue) {
1912 ret = -ENOMEM;
1913 goto err_out3;
1914 }
1915
1916 blk_queue_hardsect_size(azt_queue, 2048);
1917 azt_disk->major = MAJOR_NR;
1918 azt_disk->first_minor = 0;
1919 azt_disk->fops = &azt_fops;
1920 sprintf(azt_disk->disk_name, "aztcd");
1921 sprintf(azt_disk->devfs_name, "aztcd");
1922 azt_disk->queue = azt_queue;
1923 add_disk(azt_disk);
1924 azt_invalidate_buffers();
1925 aztPresent = 1;
1926 aztCloseDoor();
1927 return 0;
1928err_out3:
1929 unregister_blkdev(MAJOR_NR, "aztcd");
1930err_out2:
1931 put_disk(azt_disk);
1932err_out:
1933 if ((azt_port == 0x1f0) || (azt_port == 0x170)) {
1934 SWITCH_IDE_MASTER;
1935 release_region(azt_port, 8); /*IDE-interface */
1936 } else
1937 release_region(azt_port, 4); /*proprietary interface */
1938 return ret;
1939
1940}
1941
1942static void __exit aztcd_exit(void)
1943{
1944 del_gendisk(azt_disk);
1945 put_disk(azt_disk);
1946 if ((unregister_blkdev(MAJOR_NR, "aztcd") == -EINVAL)) {
1947 printk("What's that: can't unregister aztcd\n");
1948 return;
1949 }
1950 blk_cleanup_queue(azt_queue);
1951 if ((azt_port == 0x1f0) || (azt_port == 0x170)) {
1952 SWITCH_IDE_MASTER;
1953 release_region(azt_port, 8); /*IDE-interface */
1954 } else
1955 release_region(azt_port, 4); /*proprietary interface */
1956 printk(KERN_INFO "aztcd module released.\n");
1957}
1958
1959module_init(aztcd_init);
1960module_exit(aztcd_exit);
1961
1962/*##########################################################################
1963 Aztcd State Machine: Controls Drive Operating State
1964 ##########################################################################
1965*/
1966static void azt_poll(void)
1967{
1968 int st = 0;
1969 int loop_ctl = 1;
1970 int skip = 0;
1971
1972 if (azt_error) {
1973 if (aztSendCmd(ACMD_GET_ERROR))
1974 RETURN("azt_poll 1");
1975 STEN_LOW;
1976 azt_error = inb(DATA_PORT) & 0xFF;
1977 printk("aztcd: I/O error 0x%02x\n", azt_error);
1978 azt_invalidate_buffers();
1979#ifdef WARN_IF_READ_FAILURE
1980 if (AztTries == 5)
1981 printk
1982 ("aztcd: Read of Block %d Failed - Maybe Audio Disk?\n",
1983 azt_next_bn);
1984#endif
1985 if (!AztTries--) {
1986 printk
1987 ("aztcd: Read of Block %d Failed, Maybe Audio Disk? Giving up\n",
1988 azt_next_bn);
1989 if (azt_transfer_is_active) {
1990 AztTries = 0;
1991 loop_ctl = 0;
1992 }
1993 if (current_valid())
1994 end_request(CURRENT, 0);
1995 AztTries = 5;
1996 }
1997 azt_error = 0;
1998 azt_state = AZT_S_STOP;
1999 }
2000
2001 while (loop_ctl) {
2002 loop_ctl = 0; /* each case must flip this back to 1 if we want
2003 to come back up here */
2004 switch (azt_state) {
2005
2006 case AZT_S_IDLE:
2007#ifdef AZT_TEST3
2008 if (azt_state != azt_state_old) {
2009 azt_state_old = azt_state;
2010 printk("AZT_S_IDLE\n");
2011 }
2012#endif
2013 return;
2014
2015 case AZT_S_START:
2016#ifdef AZT_TEST3
2017 if (azt_state != azt_state_old) {
2018 azt_state_old = azt_state;
2019 printk("AZT_S_START\n");
2020 }
2021#endif
2022 if (aztSendCmd(ACMD_GET_STATUS))
2023 RETURN("azt_poll 2"); /*result will be checked by aztStatus() */
2024 azt_state =
2025 azt_mode == 1 ? AZT_S_READ : AZT_S_MODE;
2026 AztTimeout = 3000;
2027 break;
2028
2029 case AZT_S_MODE:
2030#ifdef AZT_TEST3
2031 if (azt_state != azt_state_old) {
2032 azt_state_old = azt_state;
2033 printk("AZT_S_MODE\n");
2034 }
2035#endif
2036 if (!skip) {
2037 if ((st = aztStatus()) != -1) {
2038 if ((st & AST_DSK_CHG)
2039 || (st & AST_NOT_READY)) {
2040 aztDiskChanged = 1;
2041 aztTocUpToDate = 0;
2042 azt_invalidate_buffers();
2043 end_request(CURRENT, 0);
2044 printk
2045 ("aztcd: Disk Changed or Not Ready 1 - Unmount Disk!\n");
2046 }
2047 } else
2048 break;
2049 }
2050 skip = 0;
2051
2052 if ((st & AST_DOOR_OPEN) || (st & AST_NOT_READY)) {
2053 aztDiskChanged = 1;
2054 aztTocUpToDate = 0;
2055 printk
2056 ("aztcd: Disk Changed or Not Ready 2 - Unmount Disk!\n");
2057 end_request(CURRENT, 0);
2058 printk((st & AST_DOOR_OPEN) ?
2059 "aztcd: door open\n" :
2060 "aztcd: disk removed\n");
2061 if (azt_transfer_is_active) {
2062 azt_state = AZT_S_START;
2063 loop_ctl = 1; /* goto immediately */
2064 break;
2065 }
2066 azt_state = AZT_S_IDLE;
2067 while (current_valid())
2068 end_request(CURRENT, 0);
2069 return;
2070 }
2071
2072/* if (aztSendCmd(ACMD_SET_MODE)) RETURN("azt_poll 3");
2073 outb(0x01, DATA_PORT);
2074 PA_OK;
2075 STEN_LOW;
2076*/
2077 if (aztSendCmd(ACMD_GET_STATUS))
2078 RETURN("azt_poll 4");
2079 STEN_LOW;
2080 azt_mode = 1;
2081 azt_state = AZT_S_READ;
2082 AztTimeout = 3000;
2083
2084 break;
2085
2086
2087 case AZT_S_READ:
2088#ifdef AZT_TEST3
2089 if (azt_state != azt_state_old) {
2090 azt_state_old = azt_state;
2091 printk("AZT_S_READ\n");
2092 }
2093#endif
2094 if (!skip) {
2095 if ((st = aztStatus()) != -1) {
2096 if ((st & AST_DSK_CHG)
2097 || (st & AST_NOT_READY)) {
2098 aztDiskChanged = 1;
2099 aztTocUpToDate = 0;
2100 azt_invalidate_buffers();
2101 printk
2102 ("aztcd: Disk Changed or Not Ready 3 - Unmount Disk!\n");
2103 end_request(CURRENT, 0);
2104 }
2105 } else
2106 break;
2107 }
2108
2109 skip = 0;
2110 if ((st & AST_DOOR_OPEN) || (st & AST_NOT_READY)) {
2111 aztDiskChanged = 1;
2112 aztTocUpToDate = 0;
2113 printk((st & AST_DOOR_OPEN) ?
2114 "aztcd: door open\n" :
2115 "aztcd: disk removed\n");
2116 if (azt_transfer_is_active) {
2117 azt_state = AZT_S_START;
2118 loop_ctl = 1;
2119 break;
2120 }
2121 azt_state = AZT_S_IDLE;
2122 while (current_valid())
2123 end_request(CURRENT, 0);
2124 return;
2125 }
2126
2127 if (current_valid()) {
2128 struct azt_Play_msf msf;
2129 int i;
2130 azt_next_bn = CURRENT->sector / 4;
2131 azt_hsg2msf(azt_next_bn, &msf.start);
2132 i = 0;
2133 /* find out in which track we are */
2134 while (azt_msf2hsg(&msf.start) >
2135 azt_msf2hsg(&Toc[++i].trackTime)) {
2136 };
2137 if (azt_msf2hsg(&msf.start) <
2138 azt_msf2hsg(&Toc[i].trackTime) -
2139 AZT_BUF_SIZ) {
2140 azt_read_count = AZT_BUF_SIZ; /*fast, because we read ahead */
2141 /*azt_read_count=CURRENT->nr_sectors; slow, no read ahead */
2142 } else /* don't read beyond end of track */
2143#if AZT_MULTISESSION
2144 {
2145 azt_read_count =
2146 (azt_msf2hsg(&Toc[i].trackTime)
2147 / 4) * 4 -
2148 azt_msf2hsg(&msf.start);
2149 if (azt_read_count < 0)
2150 azt_read_count = 0;
2151 if (azt_read_count > AZT_BUF_SIZ)
2152 azt_read_count =
2153 AZT_BUF_SIZ;
2154 printk
2155 ("aztcd: warning - trying to read beyond end of track\n");
2156/* printk("%i %i %li %li\n",i,azt_read_count,azt_msf2hsg(&msf.start),azt_msf2hsg(&Toc[i].trackTime));
2157*/ }
2158#else
2159 {
2160 azt_read_count = AZT_BUF_SIZ;
2161 }
2162#endif
2163 msf.end.min = 0;
2164 msf.end.sec = 0;
2165 msf.end.frame = azt_read_count; /*Mitsumi here reads 0xffffff sectors */
2166#ifdef AZT_TEST3
2167 printk
2168 ("---reading msf-address %x:%x:%x %x:%x:%x\n",
2169 msf.start.min, msf.start.sec,
2170 msf.start.frame, msf.end.min,
2171 msf.end.sec, msf.end.frame);
2172 printk
2173 ("azt_next_bn:%x azt_buf_in:%x azt_buf_out:%x azt_buf_bn:%x\n",
2174 azt_next_bn, azt_buf_in, azt_buf_out,
2175 azt_buf_bn[azt_buf_in]);
2176#endif
2177 if (azt_read_mode == AZT_MODE_2) {
2178 sendAztCmd(ACMD_PLAY_READ_RAW, &msf); /*XA disks in raw mode */
2179 } else {
2180 sendAztCmd(ACMD_PLAY_READ, &msf); /*others in cooked mode */
2181 }
2182 azt_state = AZT_S_DATA;
2183 AztTimeout = READ_TIMEOUT;
2184 } else {
2185 azt_state = AZT_S_STOP;
2186 loop_ctl = 1;
2187 break;
2188 }
2189
2190 break;
2191
2192
2193 case AZT_S_DATA:
2194#ifdef AZT_TEST3
2195 if (azt_state != azt_state_old) {
2196 azt_state_old = azt_state;
2197 printk("AZT_S_DATA\n");
2198 }
2199#endif
2200
2201 st = inb(STATUS_PORT) & AFL_STATUSorDATA;
2202
2203 switch (st) {
2204
2205 case AFL_DATA:
2206#ifdef AZT_TEST3
2207 if (st != azt_st_old) {
2208 azt_st_old = st;
2209 printk("---AFL_DATA st:%x\n", st);
2210 }
2211#endif
2212 if (!AztTries--) {
2213 printk
2214 ("aztcd: Read of Block %d Failed, Maybe Audio Disk ? Giving up\n",
2215 azt_next_bn);
2216 if (azt_transfer_is_active) {
2217 AztTries = 0;
2218 break;
2219 }
2220 if (current_valid())
2221 end_request(CURRENT, 0);
2222 AztTries = 5;
2223 }
2224 azt_state = AZT_S_START;
2225 AztTimeout = READ_TIMEOUT;
2226 loop_ctl = 1;
2227 break;
2228
2229 case AFL_STATUSorDATA:
2230#ifdef AZT_TEST3
2231 if (st != azt_st_old) {
2232 azt_st_old = st;
2233 printk
2234 ("---AFL_STATUSorDATA st:%x\n",
2235 st);
2236 }
2237#endif
2238 break;
2239
2240 default:
2241#ifdef AZT_TEST3
2242 if (st != azt_st_old) {
2243 azt_st_old = st;
2244 printk("---default: st:%x\n", st);
2245 }
2246#endif
2247 AztTries = 5;
2248 if (!current_valid() && azt_buf_in == azt_buf_out) {
2249 azt_state = AZT_S_STOP;
2250 loop_ctl = 1;
2251 break;
2252 }
2253 if (azt_read_count <= 0)
2254 printk
2255 ("aztcd: warning - try to read 0 frames\n");
2256 while (azt_read_count) { /*??? fast read ahead loop */
2257 azt_buf_bn[azt_buf_in] = -1;
2258 DTEN_LOW; /*??? unsolved problem, very
2259 seldom we get timeouts
2260 here, don't now the real
2261 reason. With my drive this
2262 sometimes also happens with
2263 Aztech's original driver under
2264 DOS. Is it a hardware bug?
2265 I tried to recover from such
2266 situations here. Zimmermann */
2267 if (aztTimeOutCount >= AZT_TIMEOUT) {
2268 printk
2269 ("read_count:%d CURRENT->nr_sectors:%ld azt_buf_in:%d\n",
2270 azt_read_count,
2271 CURRENT->nr_sectors,
2272 azt_buf_in);
2273 printk
2274 ("azt_transfer_is_active:%x\n",
2275 azt_transfer_is_active);
2276 azt_read_count = 0;
2277 azt_state = AZT_S_STOP;
2278 loop_ctl = 1;
2279 end_request(CURRENT, 1); /*should we have here (1) or (0)? */
2280 } else {
2281 if (azt_read_mode ==
2282 AZT_MODE_2) {
2283 insb(DATA_PORT,
2284 azt_buf +
2285 CD_FRAMESIZE_RAW
2286 * azt_buf_in,
2287 CD_FRAMESIZE_RAW);
2288 } else {
2289 insb(DATA_PORT,
2290 azt_buf +
2291 CD_FRAMESIZE *
2292 azt_buf_in,
2293 CD_FRAMESIZE);
2294 }
2295 azt_read_count--;
2296#ifdef AZT_TEST3
2297 printk
2298 ("AZT_S_DATA; ---I've read data- read_count: %d\n",
2299 azt_read_count);
2300 printk
2301 ("azt_next_bn:%d azt_buf_in:%d azt_buf_out:%d azt_buf_bn:%d\n",
2302 azt_next_bn,
2303 azt_buf_in,
2304 azt_buf_out,
2305 azt_buf_bn
2306 [azt_buf_in]);
2307#endif
2308 azt_buf_bn[azt_buf_in] =
2309 azt_next_bn++;
2310 if (azt_buf_out == -1)
2311 azt_buf_out =
2312 azt_buf_in;
2313 azt_buf_in =
2314 azt_buf_in + 1 ==
2315 AZT_BUF_SIZ ? 0 :
2316 azt_buf_in + 1;
2317 }
2318 }
2319 if (!azt_transfer_is_active) {
2320 while (current_valid()) {
2321 azt_transfer();
2322 if (CURRENT->nr_sectors ==
2323 0)
2324 end_request(CURRENT, 1);
2325 else
2326 break;
2327 }
2328 }
2329
2330 if (current_valid()
2331 && (CURRENT->sector / 4 < azt_next_bn
2332 || CURRENT->sector / 4 >
2333 azt_next_bn + AZT_BUF_SIZ)) {
2334 azt_state = AZT_S_STOP;
2335 loop_ctl = 1;
2336 break;
2337 }
2338 AztTimeout = READ_TIMEOUT;
2339 if (azt_read_count == 0) {
2340 azt_state = AZT_S_STOP;
2341 loop_ctl = 1;
2342 break;
2343 }
2344 break;
2345 }
2346 break;
2347
2348
2349 case AZT_S_STOP:
2350#ifdef AZT_TEST3
2351 if (azt_state != azt_state_old) {
2352 azt_state_old = azt_state;
2353 printk("AZT_S_STOP\n");
2354 }
2355#endif
2356 if (azt_read_count != 0)
2357 printk("aztcd: discard data=%x frames\n",
2358 azt_read_count);
2359 while (azt_read_count != 0) {
2360 int i;
2361 if (!(inb(STATUS_PORT) & AFL_DATA)) {
2362 if (azt_read_mode == AZT_MODE_2)
2363 for (i = 0;
2364 i < CD_FRAMESIZE_RAW;
2365 i++)
2366 inb(DATA_PORT);
2367 else
2368 for (i = 0;
2369 i < CD_FRAMESIZE; i++)
2370 inb(DATA_PORT);
2371 }
2372 azt_read_count--;
2373 }
2374 if (aztSendCmd(ACMD_GET_STATUS))
2375 RETURN("azt_poll 5");
2376 azt_state = AZT_S_STOPPING;
2377 AztTimeout = 1000;
2378 break;
2379
2380 case AZT_S_STOPPING:
2381#ifdef AZT_TEST3
2382 if (azt_state != azt_state_old) {
2383 azt_state_old = azt_state;
2384 printk("AZT_S_STOPPING\n");
2385 }
2386#endif
2387
2388 if ((st = aztStatus()) == -1 && AztTimeout)
2389 break;
2390
2391 if ((st != -1)
2392 && ((st & AST_DSK_CHG)
2393 || (st & AST_NOT_READY))) {
2394 aztDiskChanged = 1;
2395 aztTocUpToDate = 0;
2396 azt_invalidate_buffers();
2397 printk
2398 ("aztcd: Disk Changed or Not Ready 4 - Unmount Disk!\n");
2399 end_request(CURRENT, 0);
2400 }
2401
2402#ifdef AZT_TEST3
2403 printk("CURRENT_VALID %d azt_mode %d\n",
2404 current_valid(), azt_mode);
2405#endif
2406
2407 if (current_valid()) {
2408 if (st != -1) {
2409 if (azt_mode == 1) {
2410 azt_state = AZT_S_READ;
2411 loop_ctl = 1;
2412 skip = 1;
2413 break;
2414 } else {
2415 azt_state = AZT_S_MODE;
2416 loop_ctl = 1;
2417 skip = 1;
2418 break;
2419 }
2420 } else {
2421 azt_state = AZT_S_START;
2422 AztTimeout = 1;
2423 }
2424 } else {
2425 azt_state = AZT_S_IDLE;
2426 return;
2427 }
2428 break;
2429
2430 default:
2431 printk("aztcd: invalid state %d\n", azt_state);
2432 return;
2433 } /* case */
2434 } /* while */
2435
2436
2437 if (!AztTimeout--) {
2438 printk("aztcd: timeout in state %d\n", azt_state);
2439 azt_state = AZT_S_STOP;
2440 if (aztSendCmd(ACMD_STOP))
2441 RETURN("azt_poll 6");
2442 STEN_LOW_WAIT;
2443 };
2444
2445 SET_TIMER(azt_poll, HZ / 100);
2446}
2447
2448
2449/*###########################################################################
2450 * Miscellaneous support functions
2451 ###########################################################################
2452*/
2453static void azt_hsg2msf(long hsg, struct msf *msf)
2454{
2455 hsg += 150;
2456 msf->min = hsg / 4500;
2457 hsg %= 4500;
2458 msf->sec = hsg / 75;
2459 msf->frame = hsg % 75;
2460#ifdef AZT_DEBUG
2461 if (msf->min >= 70)
2462 printk("aztcd: Error hsg2msf address Minutes\n");
2463 if (msf->sec >= 60)
2464 printk("aztcd: Error hsg2msf address Seconds\n");
2465 if (msf->frame >= 75)
2466 printk("aztcd: Error hsg2msf address Frames\n");
2467#endif
2468 azt_bin2bcd(&msf->min); /* convert to BCD */
2469 azt_bin2bcd(&msf->sec);
2470 azt_bin2bcd(&msf->frame);
2471}
2472
2473static long azt_msf2hsg(struct msf *mp)
2474{
2475 return azt_bcd2bin(mp->frame) + azt_bcd2bin(mp->sec) * 75
2476 + azt_bcd2bin(mp->min) * 4500 - CD_MSF_OFFSET;
2477}
2478
2479static void azt_bin2bcd(unsigned char *p)
2480{
2481 int u, t;
2482
2483 u = *p % 10;
2484 t = *p / 10;
2485 *p = u | (t << 4);
2486}
2487
2488static int azt_bcd2bin(unsigned char bcd)
2489{
2490 return (bcd >> 4) * 10 + (bcd & 0xF);
2491}
2492
2493MODULE_LICENSE("GPL");
2494MODULE_ALIAS_BLOCKDEV_MAJOR(AZTECH_CDROM_MAJOR);
diff --git a/drivers/cdrom/aztcd.h b/drivers/cdrom/aztcd.h
new file mode 100644
index 000000000000..057501e31628
--- /dev/null
+++ b/drivers/cdrom/aztcd.h
@@ -0,0 +1,162 @@
1/* $Id: aztcd.h,v 2.60 1997/11/29 09:51:22 root Exp root $
2 *
3 * Definitions for a AztechCD268 CD-ROM interface
4 * Copyright (C) 1994-98 Werner Zimmermann
5 *
6 * based on Mitsumi CDROM driver by Martin Harriss
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 * History: W.Zimmermann adaption to Aztech CD268-01A Version 1.3
23 * October 1994 Email: Werner.Zimmermann@fht-esslingen.de
24 */
25
26/* *** change this to set the I/O port address of your CD-ROM drive,
27 set to '-1', if you want autoprobing */
28#define AZT_BASE_ADDR -1
29
30/* list of autoprobing addresses (not more than 15), last value must be 0x000
31 Note: Autoprobing is only enabled, if AZT_BASE_ADDR is set to '-1' ! */
32#define AZT_BASE_AUTO { 0x320, 0x300, 0x310, 0x330, 0x000 }
33
34/* Uncomment this, if your CDROM is connected to a Soundwave32-soundcard
35 and configure AZT_BASE_ADDR and AZT_SW32_BASE_ADDR */
36/*#define AZT_SW32 1
37*/
38
39#ifdef AZT_SW32
40#define AZT_SW32_BASE_ADDR 0x220 /*I/O port base address of your soundcard*/
41#endif
42
43/* Set this to 1, if you want your tray to be locked, set to 0 to prevent tray
44 from locking */
45#define AZT_ALLOW_TRAY_LOCK 1
46
47/*Set this to 1 to allow auto-eject when unmounting a disk, set to 0, if you
48 don't want the auto-eject feature*/
49#define AZT_AUTO_EJECT 0
50
51/*Set this to 1, if you want to use incompatible ioctls for reading in raw and
52 cooked mode */
53#define AZT_PRIVATE_IOCTLS 1
54
55/*Set this to 1, if you want multisession support by the ISO fs. Even if you set
56 this value to '0' you can use multisession CDs. In that case the drive's firm-
57 ware will do the appropriate redirection automatically. The CD will then look
58 like a single session CD (but nevertheless all data may be read). Please read
59 chapter '5.1 Multisession support' in README.aztcd for details. Normally it's
60 uncritical to leave this setting untouched */
61#define AZT_MULTISESSION 1
62
63/*Uncomment this, if you are using a linux kernel version prior to 2.1.0 */
64/*#define AZT_KERNEL_PRIOR_2_1 */
65
66/*---------------------------------------------------------------------------*/
67/*-----nothing to be configured for normal applications below this line------*/
68
69
70/* Increase this if you get lots of timeouts; if you get kernel panic, replace
71 STEN_LOW_WAIT by STEN_LOW in the source code */
72#define AZT_STATUS_DELAY 400 /*for timer wait, STEN_LOW_WAIT*/
73#define AZT_TIMEOUT 8000000 /*for busy wait STEN_LOW, DTEN_LOW*/
74#define AZT_FAST_TIMEOUT 10000 /*for reading the version string*/
75
76/* number of times to retry a command before giving up */
77#define AZT_RETRY_ATTEMPTS 3
78
79/* port access macros */
80#define CMD_PORT azt_port
81#define DATA_PORT azt_port
82#define STATUS_PORT azt_port+1
83#define MODE_PORT azt_port+2
84#ifdef AZT_SW32
85 #define AZT_SW32_INIT (unsigned int) (0xFF00 & (AZT_BASE_ADDR*16))
86 #define AZT_SW32_CONFIG_REG AZT_SW32_BASE_ADDR+0x16 /*Soundwave32 Config. Register*/
87 #define AZT_SW32_ID_REG AZT_SW32_BASE_ADDR+0x04 /*Soundwave32 ID Version Register*/
88#endif
89
90/* status bits */
91#define AST_CMD_CHECK 0x80 /* 1 = command error */
92#define AST_DOOR_OPEN 0x40 /* 1 = door is open */
93#define AST_NOT_READY 0x20 /* 1 = no disk in the drive */
94#define AST_DSK_CHG 0x02 /* 1 = disk removed or changed */
95#define AST_MODE 0x01 /* 0=MODE1, 1=MODE2 */
96#define AST_MODE_BITS 0x1C /* Mode Bits */
97#define AST_INITIAL 0x0C /* initial, only valid ... */
98#define AST_BUSY 0x04 /* now playing, only valid
99 in combination with mode
100 bits */
101/* flag bits */
102#define AFL_DATA 0x02 /* data available if low */
103#define AFL_STATUS 0x04 /* status available if low */
104#define AFL_OP_OK 0x01 /* OP_OK command correct*/
105#define AFL_PA_OK 0x02 /* PA_OK parameter correct*/
106#define AFL_OP_ERR 0x05 /* error in command*/
107#define AFL_PA_ERR 0x06 /* error in parameters*/
108#define POLLED 0x04 /* polled mode */
109
110/* commands */
111#define ACMD_SOFT_RESET 0x10 /* reset drive */
112#define ACMD_PLAY_READ 0x20 /* read data track in cooked mode */
113#define ACMD_PLAY_READ_RAW 0x21 /* reading in raw mode*/
114#define ACMD_SEEK 0x30 /* seek msf address*/
115#define ACMD_SEEK_TO_LEADIN 0x31 /* seek to leadin track*/
116#define ACMD_GET_ERROR 0x40 /* get error code */
117#define ACMD_GET_STATUS 0x41 /* get status */
118#define ACMD_GET_Q_CHANNEL 0x50 /* read info from q channel */
119#define ACMD_EJECT 0x60 /* eject/open tray */
120#define ACMD_CLOSE 0x61 /* close tray */
121#define ACMD_LOCK 0x71 /* lock tray closed */
122#define ACMD_UNLOCK 0x72 /* unlock tray */
123#define ACMD_PAUSE 0x80 /* pause */
124#define ACMD_STOP 0x81 /* stop play */
125#define ACMD_PLAY_AUDIO 0x90 /* play audio track */
126#define ACMD_SET_VOLUME 0x93 /* set audio level */
127#define ACMD_GET_VERSION 0xA0 /* get firmware version */
128#define ACMD_SET_DISK_TYPE 0xA1 /* set disk data mode */
129
130#define MAX_TRACKS 104
131
132struct msf {
133 unsigned char min;
134 unsigned char sec;
135 unsigned char frame;
136};
137
138struct azt_Play_msf {
139 struct msf start;
140 struct msf end;
141};
142
143struct azt_DiskInfo {
144 unsigned char first;
145 unsigned char next;
146 unsigned char last;
147 struct msf diskLength;
148 struct msf firstTrack;
149 unsigned char multi;
150 struct msf nextSession;
151 struct msf lastSession;
152 unsigned char xa;
153 unsigned char audio;
154};
155
156struct azt_Toc {
157 unsigned char ctrl_addr;
158 unsigned char track;
159 unsigned char pointIndex;
160 struct msf trackTime;
161 struct msf diskTime;
162};
diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c
new file mode 100644
index 000000000000..9deca49c71f0
--- /dev/null
+++ b/drivers/cdrom/cdrom.c
@@ -0,0 +1,3397 @@
1/* linux/drivers/cdrom/cdrom.c.
2 Copyright (c) 1996, 1997 David A. van Leeuwen.
3 Copyright (c) 1997, 1998 Erik Andersen <andersee@debian.org>
4 Copyright (c) 1998, 1999 Jens Axboe <axboe@image.dk>
5
6 May be copied or modified under the terms of the GNU General Public
7 License. See linux/COPYING for more information.
8
9 Uniform CD-ROM driver for Linux.
10 See Documentation/cdrom/cdrom-standard.tex for usage information.
11
12 The routines in the file provide a uniform interface between the
13 software that uses CD-ROMs and the various low-level drivers that
14 actually talk to the hardware. Suggestions are welcome.
15 Patches that work are more welcome though. ;-)
16
17 To Do List:
18 ----------------------------------
19
20 -- Modify sysctl/proc interface. I plan on having one directory per
21 drive, with entries for outputing general drive information, and sysctl
22 based tunable parameters such as whether the tray should auto-close for
23 that drive. Suggestions (or patches) for this welcome!
24
25
26 Revision History
27 ----------------------------------
28 1.00 Date Unknown -- David van Leeuwen <david@tm.tno.nl>
29 -- Initial version by David A. van Leeuwen. I don't have a detailed
30 changelog for the 1.x series, David?
31
322.00 Dec 2, 1997 -- Erik Andersen <andersee@debian.org>
33 -- New maintainer! As David A. van Leeuwen has been too busy to activly
34 maintain and improve this driver, I am now carrying on the torch. If
35 you have a problem with this driver, please feel free to contact me.
36
37 -- Added (rudimentary) sysctl interface. I realize this is really weak
38 right now, and is _very_ badly implemented. It will be improved...
39
40 -- Modified CDROM_DISC_STATUS so that it is now incorporated into
41 the Uniform CD-ROM driver via the cdrom_count_tracks function.
42 The cdrom_count_tracks function helps resolve some of the false
43 assumptions of the CDROM_DISC_STATUS ioctl, and is also used to check
44 for the correct media type when mounting or playing audio from a CD.
45
46 -- Remove the calls to verify_area and only use the copy_from_user and
47 copy_to_user stuff, since these calls now provide their own memory
48 checking with the 2.1.x kernels.
49
50 -- Major update to return codes so that errors from low-level drivers
51 are passed on through (thanks to Gerd Knorr for pointing out this
52 problem).
53
54 -- Made it so if a function isn't implemented in a low-level driver,
55 ENOSYS is now returned instead of EINVAL.
56
57 -- Simplified some complex logic so that the source code is easier to read.
58
59 -- Other stuff I probably forgot to mention (lots of changes).
60
612.01 to 2.11 Dec 1997-Jan 1998
62 -- TO-DO! Write changelogs for 2.01 to 2.12.
63
642.12 Jan 24, 1998 -- Erik Andersen <andersee@debian.org>
65 -- Fixed a bug in the IOCTL_IN and IOCTL_OUT macros. It turns out that
66 copy_*_user does not return EFAULT on error, but instead returns the number
67 of bytes not copied. I was returning whatever non-zero stuff came back from
68 the copy_*_user functions directly, which would result in strange errors.
69
702.13 July 17, 1998 -- Erik Andersen <andersee@debian.org>
71 -- Fixed a bug in CDROM_SELECT_SPEED where you couldn't lower the speed
72 of the drive. Thanks to Tobias Ringstr|m <tori@prosolvia.se> for pointing
73 this out and providing a simple fix.
74 -- Fixed the procfs-unload-module bug with the fill_inode procfs callback.
75 thanks to Andrea Arcangeli
76 -- Fixed it so that the /proc entry now also shows up when cdrom is
77 compiled into the kernel. Before it only worked when loaded as a module.
78
79 2.14 August 17, 1998 -- Erik Andersen <andersee@debian.org>
80 -- Fixed a bug in cdrom_media_changed and handling of reporting that
81 the media had changed for devices that _don't_ implement media_changed.
82 Thanks to Grant R. Guenther <grant@torque.net> for spotting this bug.
83 -- Made a few things more pedanticly correct.
84
852.50 Oct 19, 1998 - Jens Axboe <axboe@image.dk>
86 -- New maintainers! Erik was too busy to continue the work on the driver,
87 so now Chris Zwilling <chris@cloudnet.com> and Jens Axboe <axboe@image.dk>
88 will do their best to follow in his footsteps
89
90 2.51 Dec 20, 1998 - Jens Axboe <axboe@image.dk>
91 -- Check if drive is capable of doing what we ask before blindly changing
92 cdi->options in various ioctl.
93 -- Added version to proc entry.
94
95 2.52 Jan 16, 1999 - Jens Axboe <axboe@image.dk>
96 -- Fixed an error in open_for_data where we would sometimes not return
97 the correct error value. Thanks Huba Gaspar <huba@softcell.hu>.
98 -- Fixed module usage count - usage was based on /proc/sys/dev
99 instead of /proc/sys/dev/cdrom. This could lead to an oops when other
100 modules had entries in dev. Feb 02 - real bug was in sysctl.c where
101 dev would be removed even though it was used. cdrom.c just illuminated
102 that bug.
103
104 2.53 Feb 22, 1999 - Jens Axboe <axboe@image.dk>
105 -- Fixup of several ioctl calls, in particular CDROM_SET_OPTIONS has
106 been "rewritten" because capabilities and options aren't in sync. They
107 should be...
108 -- Added CDROM_LOCKDOOR ioctl. Locks the door and keeps it that way.
109 -- Added CDROM_RESET ioctl.
110 -- Added CDROM_DEBUG ioctl. Enable debug messages on-the-fly.
111 -- Added CDROM_GET_CAPABILITY ioctl. This relieves userspace programs
112 from parsing /proc/sys/dev/cdrom/info.
113
114 2.54 Mar 15, 1999 - Jens Axboe <axboe@image.dk>
115 -- Check capability mask from low level driver when counting tracks as
116 per suggestion from Corey J. Scotts <cstotts@blue.weeg.uiowa.edu>.
117
118 2.55 Apr 25, 1999 - Jens Axboe <axboe@image.dk>
119 -- autoclose was mistakenly checked against CDC_OPEN_TRAY instead of
120 CDC_CLOSE_TRAY.
121 -- proc info didn't mask against capabilities mask.
122
123 3.00 Aug 5, 1999 - Jens Axboe <axboe@image.dk>
124 -- Unified audio ioctl handling across CD-ROM drivers. A lot of the
125 code was duplicated before. Drives that support the generic packet
126 interface are now being fed packets from here instead.
127 -- First attempt at adding support for MMC2 commands - for DVD and
128 CD-R(W) drives. Only the DVD parts are in now - the interface used is
129 the same as for the audio ioctls.
130 -- ioctl cleanups. if a drive couldn't play audio, it didn't get
131 a change to perform device specific ioctls as well.
132 -- Defined CDROM_CAN(CDC_XXX) for checking the capabilities.
133 -- Put in sysctl files for autoclose, autoeject, check_media, debug,
134 and lock.
135 -- /proc/sys/dev/cdrom/info has been updated to also contain info about
136 CD-Rx and DVD capabilities.
137 -- Now default to checking media type.
138 -- CDROM_SEND_PACKET ioctl added. The infrastructure was in place for
139 doing this anyway, with the generic_packet addition.
140
141 3.01 Aug 6, 1999 - Jens Axboe <axboe@image.dk>
142 -- Fix up the sysctl handling so that the option flags get set
143 correctly.
144 -- Fix up ioctl handling so the device specific ones actually get
145 called :).
146
147 3.02 Aug 8, 1999 - Jens Axboe <axboe@image.dk>
148 -- Fixed volume control on SCSI drives (or others with longer audio
149 page).
150 -- Fixed a couple of DVD minors. Thanks to Andrew T. Veliath
151 <andrewtv@usa.net> for telling me and for having defined the various
152 DVD structures and ioctls in the first place! He designed the original
153 DVD patches for ide-cd and while I rearranged and unified them, the
154 interface is still the same.
155
156 3.03 Sep 1, 1999 - Jens Axboe <axboe@image.dk>
157 -- Moved the rest of the audio ioctls from the CD-ROM drivers here. Only
158 CDROMREADTOCENTRY and CDROMREADTOCHDR are left.
159 -- Moved the CDROMREADxxx ioctls in here.
160 -- Defined the cdrom_get_last_written and cdrom_get_next_block as ioctls
161 and exported functions.
162 -- Erik Andersen <andersen@xmission.com> modified all SCMD_ commands
163 to now read GPCMD_ for the new generic packet interface. All low level
164 drivers are updated as well.
165 -- Various other cleanups.
166
167 3.04 Sep 12, 1999 - Jens Axboe <axboe@image.dk>
168 -- Fixed a couple of possible memory leaks (if an operation failed and
169 we didn't free the buffer before returning the error).
170 -- Integrated Uniform CD Changer handling from Richard Sharman
171 <rsharman@pobox.com>.
172 -- Defined CD_DVD and CD_CHANGER log levels.
173 -- Fixed the CDROMREADxxx ioctls.
174 -- CDROMPLAYTRKIND uses the GPCMD_PLAY_AUDIO_MSF command - too few
175 drives supported it. We lose the index part, however.
176 -- Small modifications to accommodate opens of /dev/hdc1, required
177 for ide-cd to handle multisession discs.
178 -- Export cdrom_mode_sense and cdrom_mode_select.
179 -- init_cdrom_command() for setting up a cgc command.
180
181 3.05 Oct 24, 1999 - Jens Axboe <axboe@image.dk>
182 -- Changed the interface for CDROM_SEND_PACKET. Before it was virtually
183 impossible to send the drive data in a sensible way.
184 -- Lowered stack usage in mmc_ioctl(), dvd_read_disckey(), and
185 dvd_read_manufact.
186 -- Added setup of write mode for packet writing.
187 -- Fixed CDDA ripping with cdda2wav - accept much larger requests of
188 number of frames and split the reads in blocks of 8.
189
190 3.06 Dec 13, 1999 - Jens Axboe <axboe@image.dk>
191 -- Added support for changing the region of DVD drives.
192 -- Added sense data to generic command.
193
194 3.07 Feb 2, 2000 - Jens Axboe <axboe@suse.de>
195 -- Do same "read header length" trick in cdrom_get_disc_info() as
196 we do in cdrom_get_track_info() -- some drive don't obey specs and
197 fail if they can't supply the full Mt Fuji size table.
198 -- Deleted stuff related to setting up write modes. It has a different
199 home now.
200 -- Clear header length in mode_select unconditionally.
201 -- Removed the register_disk() that was added, not needed here.
202
203 3.08 May 1, 2000 - Jens Axboe <axboe@suse.de>
204 -- Fix direction flag in setup_send_key and setup_report_key. This
205 gave some SCSI adapters problems.
206 -- Always return -EROFS for write opens
207 -- Convert to module_init/module_exit style init and remove some
208 of the #ifdef MODULE stuff
209 -- Fix several dvd errors - DVD_LU_SEND_ASF should pass agid,
210 DVD_HOST_SEND_RPC_STATE did not set buffer size in cdb, and
211 dvd_do_auth passed uninitialized data to drive because init_cdrom_command
212 did not clear a 0 sized buffer.
213
214 3.09 May 12, 2000 - Jens Axboe <axboe@suse.de>
215 -- Fix Video-CD on SCSI drives that don't support READ_CD command. In
216 that case switch block size and issue plain READ_10 again, then switch
217 back.
218
219 3.10 Jun 10, 2000 - Jens Axboe <axboe@suse.de>
220 -- Fix volume control on CD's - old SCSI-II drives now use their own
221 code, as doing MODE6 stuff in here is really not my intention.
222 -- Use READ_DISC_INFO for more reliable end-of-disc.
223
224 3.11 Jun 12, 2000 - Jens Axboe <axboe@suse.de>
225 -- Fix bug in getting rpc phase 2 region info.
226 -- Reinstate "correct" CDROMPLAYTRKIND
227
228 3.12 Oct 18, 2000 - Jens Axboe <axboe@suse.de>
229 -- Use quiet bit on packet commands not known to work
230
231 3.20 Dec 17, 2003 - Jens Axboe <axboe@suse.de>
232 -- Various fixes and lots of cleanups not listed :-)
233 -- Locking fixes
234 -- Mt Rainier support
235 -- DVD-RAM write open fixes
236
237 Nov 5 2001, Aug 8 2002. Modified by Andy Polyakov
238 <appro@fy.chalmers.se> to support MMC-3 compliant DVD+RW units.
239
240 Modified by Nigel Kukard <nkukard@lbsd.net> - support DVD+RW
241 2.4.x patch by Andy Polyakov <appro@fy.chalmers.se>
242
243-------------------------------------------------------------------------*/
244
245#define REVISION "Revision: 3.20"
246#define VERSION "Id: cdrom.c 3.20 2003/12/17"
247
248/* I use an error-log mask to give fine grain control over the type of
249 messages dumped to the system logs. The available masks include: */
250#define CD_NOTHING 0x0
251#define CD_WARNING 0x1
252#define CD_REG_UNREG 0x2
253#define CD_DO_IOCTL 0x4
254#define CD_OPEN 0x8
255#define CD_CLOSE 0x10
256#define CD_COUNT_TRACKS 0x20
257#define CD_CHANGER 0x40
258#define CD_DVD 0x80
259
260/* Define this to remove _all_ the debugging messages */
261/* #define ERRLOGMASK CD_NOTHING */
262#define ERRLOGMASK CD_WARNING
263/* #define ERRLOGMASK (CD_WARNING|CD_OPEN|CD_COUNT_TRACKS|CD_CLOSE) */
264/* #define ERRLOGMASK (CD_WARNING|CD_REG_UNREG|CD_DO_IOCTL|CD_OPEN|CD_CLOSE|CD_COUNT_TRACKS) */
265
266#include <linux/config.h>
267#include <linux/module.h>
268#include <linux/fs.h>
269#include <linux/buffer_head.h>
270#include <linux/major.h>
271#include <linux/types.h>
272#include <linux/errno.h>
273#include <linux/kernel.h>
274#include <linux/mm.h>
275#include <linux/slab.h>
276#include <linux/cdrom.h>
277#include <linux/sysctl.h>
278#include <linux/proc_fs.h>
279#include <linux/blkpg.h>
280#include <linux/init.h>
281#include <linux/fcntl.h>
282#include <linux/blkdev.h>
283#include <linux/times.h>
284
285#include <asm/uaccess.h>
286
287/* used to tell the module to turn on full debugging messages */
288static int debug;
289/* used to keep tray locked at all times */
290static int keeplocked;
291/* default compatibility mode */
292static int autoclose=1;
293static int autoeject;
294static int lockdoor = 1;
295/* will we ever get to use this... sigh. */
296static int check_media_type;
297/* automatically restart mrw format */
298static int mrw_format_restart = 1;
299module_param(debug, bool, 0);
300module_param(autoclose, bool, 0);
301module_param(autoeject, bool, 0);
302module_param(lockdoor, bool, 0);
303module_param(check_media_type, bool, 0);
304module_param(mrw_format_restart, bool, 0);
305
306static DEFINE_SPINLOCK(cdrom_lock);
307
308static const char *mrw_format_status[] = {
309 "not mrw",
310 "bgformat inactive",
311 "bgformat active",
312 "mrw complete",
313};
314
315static const char *mrw_address_space[] = { "DMA", "GAA" };
316
317#if (ERRLOGMASK!=CD_NOTHING)
318#define cdinfo(type, fmt, args...) \
319 if ((ERRLOGMASK & type) || debug==1 ) \
320 printk(KERN_INFO "cdrom: " fmt, ## args)
321#else
322#define cdinfo(type, fmt, args...)
323#endif
324
325/* These are used to simplify getting data in from and back to user land */
326#define IOCTL_IN(arg, type, in) \
327 if (copy_from_user(&(in), (type __user *) (arg), sizeof (in))) \
328 return -EFAULT;
329
330#define IOCTL_OUT(arg, type, out) \
331 if (copy_to_user((type __user *) (arg), &(out), sizeof (out))) \
332 return -EFAULT;
333
334/* The (cdo->capability & ~cdi->mask & CDC_XXX) construct was used in
335 a lot of places. This macro makes the code more clear. */
336#define CDROM_CAN(type) (cdi->ops->capability & ~cdi->mask & (type))
337
338/* used in the audio ioctls */
339#define CHECKAUDIO if ((ret=check_for_audio_disc(cdi, cdo))) return ret
340
341/* Not-exported routines. */
342static int open_for_data(struct cdrom_device_info * cdi);
343static int check_for_audio_disc(struct cdrom_device_info * cdi,
344 struct cdrom_device_ops * cdo);
345static void sanitize_format(union cdrom_addr *addr,
346 u_char * curr, u_char requested);
347static int mmc_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
348 unsigned long arg);
349
350int cdrom_get_last_written(struct cdrom_device_info *, long *);
351static int cdrom_get_next_writable(struct cdrom_device_info *, long *);
352static void cdrom_count_tracks(struct cdrom_device_info *, tracktype*);
353
354static int cdrom_mrw_exit(struct cdrom_device_info *cdi);
355
356static int cdrom_get_disc_info(struct cdrom_device_info *cdi, disc_information *di);
357
358#ifdef CONFIG_SYSCTL
359static void cdrom_sysctl_register(void);
360#endif /* CONFIG_SYSCTL */
361static struct cdrom_device_info *topCdromPtr;
362
363static int cdrom_dummy_generic_packet(struct cdrom_device_info *cdi,
364 struct packet_command *cgc)
365{
366 if (cgc->sense) {
367 cgc->sense->sense_key = 0x05;
368 cgc->sense->asc = 0x20;
369 cgc->sense->ascq = 0x00;
370 }
371
372 cgc->stat = -EIO;
373 return -EIO;
374}
375
376/* This macro makes sure we don't have to check on cdrom_device_ops
377 * existence in the run-time routines below. Change_capability is a
378 * hack to have the capability flags defined const, while we can still
379 * change it here without gcc complaining at every line.
380 */
381#define ENSURE(call, bits) if (cdo->call == NULL) *change_capability &= ~(bits)
382
383int register_cdrom(struct cdrom_device_info *cdi)
384{
385 static char banner_printed;
386 struct cdrom_device_ops *cdo = cdi->ops;
387 int *change_capability = (int *)&cdo->capability; /* hack */
388
389 cdinfo(CD_OPEN, "entering register_cdrom\n");
390
391 if (cdo->open == NULL || cdo->release == NULL)
392 return -2;
393 if (!banner_printed) {
394 printk(KERN_INFO "Uniform CD-ROM driver " REVISION "\n");
395 banner_printed = 1;
396#ifdef CONFIG_SYSCTL
397 cdrom_sysctl_register();
398#endif /* CONFIG_SYSCTL */
399 }
400
401 ENSURE(drive_status, CDC_DRIVE_STATUS );
402 ENSURE(media_changed, CDC_MEDIA_CHANGED);
403 ENSURE(tray_move, CDC_CLOSE_TRAY | CDC_OPEN_TRAY);
404 ENSURE(lock_door, CDC_LOCK);
405 ENSURE(select_speed, CDC_SELECT_SPEED);
406 ENSURE(get_last_session, CDC_MULTI_SESSION);
407 ENSURE(get_mcn, CDC_MCN);
408 ENSURE(reset, CDC_RESET);
409 ENSURE(audio_ioctl, CDC_PLAY_AUDIO);
410 ENSURE(dev_ioctl, CDC_IOCTLS);
411 ENSURE(generic_packet, CDC_GENERIC_PACKET);
412 cdi->mc_flags = 0;
413 cdo->n_minors = 0;
414 cdi->options = CDO_USE_FFLAGS;
415
416 if (autoclose==1 && CDROM_CAN(CDC_CLOSE_TRAY))
417 cdi->options |= (int) CDO_AUTO_CLOSE;
418 if (autoeject==1 && CDROM_CAN(CDC_OPEN_TRAY))
419 cdi->options |= (int) CDO_AUTO_EJECT;
420 if (lockdoor==1)
421 cdi->options |= (int) CDO_LOCK;
422 if (check_media_type==1)
423 cdi->options |= (int) CDO_CHECK_TYPE;
424
425 if (CDROM_CAN(CDC_MRW_W))
426 cdi->exit = cdrom_mrw_exit;
427
428 if (cdi->disk)
429 cdi->cdda_method = CDDA_BPC_FULL;
430 else
431 cdi->cdda_method = CDDA_OLD;
432
433 if (!cdo->generic_packet)
434 cdo->generic_packet = cdrom_dummy_generic_packet;
435
436 cdinfo(CD_REG_UNREG, "drive \"/dev/%s\" registered\n", cdi->name);
437 spin_lock(&cdrom_lock);
438 cdi->next = topCdromPtr;
439 topCdromPtr = cdi;
440 spin_unlock(&cdrom_lock);
441 return 0;
442}
443#undef ENSURE
444
445int unregister_cdrom(struct cdrom_device_info *unreg)
446{
447 struct cdrom_device_info *cdi, *prev;
448 cdinfo(CD_OPEN, "entering unregister_cdrom\n");
449
450 prev = NULL;
451 spin_lock(&cdrom_lock);
452 cdi = topCdromPtr;
453 while (cdi && cdi != unreg) {
454 prev = cdi;
455 cdi = cdi->next;
456 }
457
458 if (cdi == NULL) {
459 spin_unlock(&cdrom_lock);
460 return -2;
461 }
462 if (prev)
463 prev->next = cdi->next;
464 else
465 topCdromPtr = cdi->next;
466
467 spin_unlock(&cdrom_lock);
468
469 if (cdi->exit)
470 cdi->exit(cdi);
471
472 cdi->ops->n_minors--;
473 cdinfo(CD_REG_UNREG, "drive \"/dev/%s\" unregistered\n", cdi->name);
474 return 0;
475}
476
477int cdrom_get_media_event(struct cdrom_device_info *cdi,
478 struct media_event_desc *med)
479{
480 struct packet_command cgc;
481 unsigned char buffer[8];
482 struct event_header *eh = (struct event_header *) buffer;
483
484 init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ);
485 cgc.cmd[0] = GPCMD_GET_EVENT_STATUS_NOTIFICATION;
486 cgc.cmd[1] = 1; /* IMMED */
487 cgc.cmd[4] = 1 << 4; /* media event */
488 cgc.cmd[8] = sizeof(buffer);
489 cgc.quiet = 1;
490
491 if (cdi->ops->generic_packet(cdi, &cgc))
492 return 1;
493
494 if (be16_to_cpu(eh->data_len) < sizeof(*med))
495 return 1;
496
497 if (eh->nea || eh->notification_class != 0x4)
498 return 1;
499
500 memcpy(med, &buffer[sizeof(*eh)], sizeof(*med));
501 return 0;
502}
503
504/*
505 * the first prototypes used 0x2c as the page code for the mrw mode page,
506 * subsequently this was changed to 0x03. probe the one used by this drive
507 */
508static int cdrom_mrw_probe_pc(struct cdrom_device_info *cdi)
509{
510 struct packet_command cgc;
511 char buffer[16];
512
513 init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ);
514
515 cgc.timeout = HZ;
516 cgc.quiet = 1;
517
518 if (!cdrom_mode_sense(cdi, &cgc, MRW_MODE_PC, 0)) {
519 cdi->mrw_mode_page = MRW_MODE_PC;
520 return 0;
521 } else if (!cdrom_mode_sense(cdi, &cgc, MRW_MODE_PC_PRE1, 0)) {
522 cdi->mrw_mode_page = MRW_MODE_PC_PRE1;
523 return 0;
524 }
525
526 return 1;
527}
528
529static int cdrom_is_mrw(struct cdrom_device_info *cdi, int *write)
530{
531 struct packet_command cgc;
532 struct mrw_feature_desc *mfd;
533 unsigned char buffer[16];
534 int ret;
535
536 *write = 0;
537
538 init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ);
539
540 cgc.cmd[0] = GPCMD_GET_CONFIGURATION;
541 cgc.cmd[3] = CDF_MRW;
542 cgc.cmd[8] = sizeof(buffer);
543 cgc.quiet = 1;
544
545 if ((ret = cdi->ops->generic_packet(cdi, &cgc)))
546 return ret;
547
548 mfd = (struct mrw_feature_desc *)&buffer[sizeof(struct feature_header)];
549 if (be16_to_cpu(mfd->feature_code) != CDF_MRW)
550 return 1;
551 *write = mfd->write;
552
553 if ((ret = cdrom_mrw_probe_pc(cdi))) {
554 *write = 0;
555 return ret;
556 }
557
558 return 0;
559}
560
561static int cdrom_mrw_bgformat(struct cdrom_device_info *cdi, int cont)
562{
563 struct packet_command cgc;
564 unsigned char buffer[12];
565 int ret;
566
567 printk(KERN_INFO "cdrom: %sstarting format\n", cont ? "Re" : "");
568
569 /*
570 * FmtData bit set (bit 4), format type is 1
571 */
572 init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_WRITE);
573 cgc.cmd[0] = GPCMD_FORMAT_UNIT;
574 cgc.cmd[1] = (1 << 4) | 1;
575
576 cgc.timeout = 5 * 60 * HZ;
577
578 /*
579 * 4 byte format list header, 8 byte format list descriptor
580 */
581 buffer[1] = 1 << 1;
582 buffer[3] = 8;
583
584 /*
585 * nr_blocks field
586 */
587 buffer[4] = 0xff;
588 buffer[5] = 0xff;
589 buffer[6] = 0xff;
590 buffer[7] = 0xff;
591
592 buffer[8] = 0x24 << 2;
593 buffer[11] = cont;
594
595 ret = cdi->ops->generic_packet(cdi, &cgc);
596 if (ret)
597 printk(KERN_INFO "cdrom: bgformat failed\n");
598
599 return ret;
600}
601
602static int cdrom_mrw_bgformat_susp(struct cdrom_device_info *cdi, int immed)
603{
604 struct packet_command cgc;
605
606 init_cdrom_command(&cgc, NULL, 0, CGC_DATA_NONE);
607 cgc.cmd[0] = GPCMD_CLOSE_TRACK;
608
609 /*
610 * Session = 1, Track = 0
611 */
612 cgc.cmd[1] = !!immed;
613 cgc.cmd[2] = 1 << 1;
614
615 cgc.timeout = 5 * 60 * HZ;
616
617 return cdi->ops->generic_packet(cdi, &cgc);
618}
619
620static int cdrom_flush_cache(struct cdrom_device_info *cdi)
621{
622 struct packet_command cgc;
623
624 init_cdrom_command(&cgc, NULL, 0, CGC_DATA_NONE);
625 cgc.cmd[0] = GPCMD_FLUSH_CACHE;
626
627 cgc.timeout = 5 * 60 * HZ;
628
629 return cdi->ops->generic_packet(cdi, &cgc);
630}
631
632static int cdrom_mrw_exit(struct cdrom_device_info *cdi)
633{
634 disc_information di;
635 int ret;
636
637 ret = cdrom_get_disc_info(cdi, &di);
638 if (ret < 0 || ret < (int)offsetof(typeof(di),disc_type))
639 return 1;
640
641 ret = 0;
642 if (di.mrw_status == CDM_MRW_BGFORMAT_ACTIVE) {
643 printk(KERN_INFO "cdrom: issuing MRW back ground "
644 "format suspend\n");
645 ret = cdrom_mrw_bgformat_susp(cdi, 0);
646 }
647
648 if (!ret)
649 ret = cdrom_flush_cache(cdi);
650
651 return ret;
652}
653
654static int cdrom_mrw_set_lba_space(struct cdrom_device_info *cdi, int space)
655{
656 struct packet_command cgc;
657 struct mode_page_header *mph;
658 char buffer[16];
659 int ret, offset, size;
660
661 init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ);
662
663 cgc.buffer = buffer;
664 cgc.buflen = sizeof(buffer);
665
666 if ((ret = cdrom_mode_sense(cdi, &cgc, cdi->mrw_mode_page, 0)))
667 return ret;
668
669 mph = (struct mode_page_header *) buffer;
670 offset = be16_to_cpu(mph->desc_length);
671 size = be16_to_cpu(mph->mode_data_length) + 2;
672
673 buffer[offset + 3] = space;
674 cgc.buflen = size;
675
676 if ((ret = cdrom_mode_select(cdi, &cgc)))
677 return ret;
678
679 printk(KERN_INFO "cdrom: %s: mrw address space %s selected\n", cdi->name, mrw_address_space[space]);
680 return 0;
681}
682
683static int cdrom_get_random_writable(struct cdrom_device_info *cdi,
684 struct rwrt_feature_desc *rfd)
685{
686 struct packet_command cgc;
687 char buffer[24];
688 int ret;
689
690 init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ);
691
692 cgc.cmd[0] = GPCMD_GET_CONFIGURATION; /* often 0x46 */
693 cgc.cmd[3] = CDF_RWRT; /* often 0x0020 */
694 cgc.cmd[8] = sizeof(buffer); /* often 0x18 */
695 cgc.quiet = 1;
696
697 if ((ret = cdi->ops->generic_packet(cdi, &cgc)))
698 return ret;
699
700 memcpy(rfd, &buffer[sizeof(struct feature_header)], sizeof (*rfd));
701 return 0;
702}
703
704static int cdrom_has_defect_mgt(struct cdrom_device_info *cdi)
705{
706 struct packet_command cgc;
707 char buffer[16];
708 __u16 *feature_code;
709 int ret;
710
711 init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ);
712
713 cgc.cmd[0] = GPCMD_GET_CONFIGURATION;
714 cgc.cmd[3] = CDF_HWDM;
715 cgc.cmd[8] = sizeof(buffer);
716 cgc.quiet = 1;
717
718 if ((ret = cdi->ops->generic_packet(cdi, &cgc)))
719 return ret;
720
721 feature_code = (__u16 *) &buffer[sizeof(struct feature_header)];
722 if (be16_to_cpu(*feature_code) == CDF_HWDM)
723 return 0;
724
725 return 1;
726}
727
728
729static int cdrom_is_random_writable(struct cdrom_device_info *cdi, int *write)
730{
731 struct rwrt_feature_desc rfd;
732 int ret;
733
734 *write = 0;
735
736 if ((ret = cdrom_get_random_writable(cdi, &rfd)))
737 return ret;
738
739 if (CDF_RWRT == be16_to_cpu(rfd.feature_code))
740 *write = 1;
741
742 return 0;
743}
744
745static int cdrom_media_erasable(struct cdrom_device_info *cdi)
746{
747 disc_information di;
748 int ret;
749
750 ret = cdrom_get_disc_info(cdi, &di);
751 if (ret < 0 || ret < offsetof(typeof(di), n_first_track))
752 return -1;
753
754 return di.erasable;
755}
756
757/*
758 * FIXME: check RO bit
759 */
760static int cdrom_dvdram_open_write(struct cdrom_device_info *cdi)
761{
762 int ret = cdrom_media_erasable(cdi);
763
764 /*
765 * allow writable open if media info read worked and media is
766 * erasable, _or_ if it fails since not all drives support it
767 */
768 if (!ret)
769 return 1;
770
771 return 0;
772}
773
774static int cdrom_mrw_open_write(struct cdrom_device_info *cdi)
775{
776 disc_information di;
777 int ret;
778
779 /*
780 * always reset to DMA lba space on open
781 */
782 if (cdrom_mrw_set_lba_space(cdi, MRW_LBA_DMA)) {
783 printk(KERN_ERR "cdrom: failed setting lba address space\n");
784 return 1;
785 }
786
787 ret = cdrom_get_disc_info(cdi, &di);
788 if (ret < 0 || ret < offsetof(typeof(di),disc_type))
789 return 1;
790
791 if (!di.erasable)
792 return 1;
793
794 /*
795 * mrw_status
796 * 0 - not MRW formatted
797 * 1 - MRW bgformat started, but not running or complete
798 * 2 - MRW bgformat in progress
799 * 3 - MRW formatting complete
800 */
801 ret = 0;
802 printk(KERN_INFO "cdrom open: mrw_status '%s'\n",
803 mrw_format_status[di.mrw_status]);
804 if (!di.mrw_status)
805 ret = 1;
806 else if (di.mrw_status == CDM_MRW_BGFORMAT_INACTIVE &&
807 mrw_format_restart)
808 ret = cdrom_mrw_bgformat(cdi, 1);
809
810 return ret;
811}
812
813static int mo_open_write(struct cdrom_device_info *cdi)
814{
815 struct packet_command cgc;
816 char buffer[255];
817 int ret;
818
819 init_cdrom_command(&cgc, &buffer, 4, CGC_DATA_READ);
820 cgc.quiet = 1;
821
822 /*
823 * obtain write protect information as per
824 * drivers/scsi/sd.c:sd_read_write_protect_flag
825 */
826
827 ret = cdrom_mode_sense(cdi, &cgc, GPMODE_ALL_PAGES, 0);
828 if (ret)
829 ret = cdrom_mode_sense(cdi, &cgc, GPMODE_VENDOR_PAGE, 0);
830 if (ret) {
831 cgc.buflen = 255;
832 ret = cdrom_mode_sense(cdi, &cgc, GPMODE_ALL_PAGES, 0);
833 }
834
835 /* drive gave us no info, let the user go ahead */
836 if (ret)
837 return 0;
838
839 return buffer[3] & 0x80;
840}
841
842static int cdrom_ram_open_write(struct cdrom_device_info *cdi)
843{
844 struct rwrt_feature_desc rfd;
845 int ret;
846
847 if ((ret = cdrom_has_defect_mgt(cdi)))
848 return ret;
849
850 if ((ret = cdrom_get_random_writable(cdi, &rfd)))
851 return ret;
852 else if (CDF_RWRT == be16_to_cpu(rfd.feature_code))
853 ret = !rfd.curr;
854
855 cdinfo(CD_OPEN, "can open for random write\n");
856 return ret;
857}
858
859static void cdrom_mmc3_profile(struct cdrom_device_info *cdi)
860{
861 struct packet_command cgc;
862 char buffer[32];
863 int ret, mmc3_profile;
864
865 init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ);
866
867 cgc.cmd[0] = GPCMD_GET_CONFIGURATION;
868 cgc.cmd[1] = 0;
869 cgc.cmd[2] = cgc.cmd[3] = 0; /* Starting Feature Number */
870 cgc.cmd[8] = sizeof(buffer); /* Allocation Length */
871 cgc.quiet = 1;
872
873 if ((ret = cdi->ops->generic_packet(cdi, &cgc)))
874 mmc3_profile = 0xffff;
875 else
876 mmc3_profile = (buffer[6] << 8) | buffer[7];
877
878 cdi->mmc3_profile = mmc3_profile;
879}
880
881static int cdrom_is_dvd_rw(struct cdrom_device_info *cdi)
882{
883 switch (cdi->mmc3_profile) {
884 case 0x12: /* DVD-RAM */
885 case 0x1A: /* DVD+RW */
886 return 0;
887 default:
888 return 1;
889 }
890}
891
892/*
893 * returns 0 for ok to open write, non-0 to disallow
894 */
895static int cdrom_open_write(struct cdrom_device_info *cdi)
896{
897 int mrw, mrw_write, ram_write;
898 int ret = 1;
899
900 mrw = 0;
901 if (!cdrom_is_mrw(cdi, &mrw_write))
902 mrw = 1;
903
904 if (CDROM_CAN(CDC_MO_DRIVE))
905 ram_write = 1;
906 else
907 (void) cdrom_is_random_writable(cdi, &ram_write);
908
909 if (mrw)
910 cdi->mask &= ~CDC_MRW;
911 else
912 cdi->mask |= CDC_MRW;
913
914 if (mrw_write)
915 cdi->mask &= ~CDC_MRW_W;
916 else
917 cdi->mask |= CDC_MRW_W;
918
919 if (ram_write)
920 cdi->mask &= ~CDC_RAM;
921 else
922 cdi->mask |= CDC_RAM;
923
924 if (CDROM_CAN(CDC_MRW_W))
925 ret = cdrom_mrw_open_write(cdi);
926 else if (CDROM_CAN(CDC_DVD_RAM))
927 ret = cdrom_dvdram_open_write(cdi);
928 else if (CDROM_CAN(CDC_RAM) &&
929 !CDROM_CAN(CDC_CD_R|CDC_CD_RW|CDC_DVD|CDC_DVD_R|CDC_MRW|CDC_MO_DRIVE))
930 ret = cdrom_ram_open_write(cdi);
931 else if (CDROM_CAN(CDC_MO_DRIVE))
932 ret = mo_open_write(cdi);
933 else if (!cdrom_is_dvd_rw(cdi))
934 ret = 0;
935
936 return ret;
937}
938
939static void cdrom_dvd_rw_close_write(struct cdrom_device_info *cdi)
940{
941 struct packet_command cgc;
942
943 if (cdi->mmc3_profile != 0x1a) {
944 cdinfo(CD_CLOSE, "%s: No DVD+RW\n", cdi->name);
945 return;
946 }
947
948 if (!cdi->media_written) {
949 cdinfo(CD_CLOSE, "%s: DVD+RW media clean\n", cdi->name);
950 return;
951 }
952
953 printk(KERN_INFO "cdrom: %s: dirty DVD+RW media, \"finalizing\"\n",
954 cdi->name);
955
956 init_cdrom_command(&cgc, NULL, 0, CGC_DATA_NONE);
957 cgc.cmd[0] = GPCMD_FLUSH_CACHE;
958 cgc.timeout = 30*HZ;
959 cdi->ops->generic_packet(cdi, &cgc);
960
961 init_cdrom_command(&cgc, NULL, 0, CGC_DATA_NONE);
962 cgc.cmd[0] = GPCMD_CLOSE_TRACK;
963 cgc.timeout = 3000*HZ;
964 cgc.quiet = 1;
965 cdi->ops->generic_packet(cdi, &cgc);
966
967 init_cdrom_command(&cgc, NULL, 0, CGC_DATA_NONE);
968 cgc.cmd[0] = GPCMD_CLOSE_TRACK;
969 cgc.cmd[2] = 2; /* Close session */
970 cgc.quiet = 1;
971 cgc.timeout = 3000*HZ;
972 cdi->ops->generic_packet(cdi, &cgc);
973
974 cdi->media_written = 0;
975}
976
977static int cdrom_close_write(struct cdrom_device_info *cdi)
978{
979#if 0
980 return cdrom_flush_cache(cdi);
981#else
982 return 0;
983#endif
984}
985
986/* We use the open-option O_NONBLOCK to indicate that the
987 * purpose of opening is only for subsequent ioctl() calls; no device
988 * integrity checks are performed.
989 *
990 * We hope that all cd-player programs will adopt this convention. It
991 * is in their own interest: device control becomes a lot easier
992 * this way.
993 */
994int cdrom_open(struct cdrom_device_info *cdi, struct inode *ip, struct file *fp)
995{
996 int ret;
997
998 cdinfo(CD_OPEN, "entering cdrom_open\n");
999
1000 /* if this was a O_NONBLOCK open and we should honor the flags,
1001 * do a quick open without drive/disc integrity checks. */
1002 cdi->use_count++;
1003 if ((fp->f_flags & O_NONBLOCK) && (cdi->options & CDO_USE_FFLAGS)) {
1004 ret = cdi->ops->open(cdi, 1);
1005 } else {
1006 ret = open_for_data(cdi);
1007 if (ret)
1008 goto err;
1009 cdrom_mmc3_profile(cdi);
1010 if (fp->f_mode & FMODE_WRITE) {
1011 ret = -EROFS;
1012 if (cdrom_open_write(cdi))
1013 goto err;
1014 if (!CDROM_CAN(CDC_RAM))
1015 goto err;
1016 ret = 0;
1017 cdi->media_written = 0;
1018 }
1019 }
1020
1021 if (ret)
1022 goto err;
1023
1024 cdinfo(CD_OPEN, "Use count for \"/dev/%s\" now %d\n",
1025 cdi->name, cdi->use_count);
1026 /* Do this on open. Don't wait for mount, because they might
1027 not be mounting, but opening with O_NONBLOCK */
1028 check_disk_change(ip->i_bdev);
1029 return 0;
1030err:
1031 cdi->use_count--;
1032 return ret;
1033}
1034
1035static
1036int open_for_data(struct cdrom_device_info * cdi)
1037{
1038 int ret;
1039 struct cdrom_device_ops *cdo = cdi->ops;
1040 tracktype tracks;
1041 cdinfo(CD_OPEN, "entering open_for_data\n");
1042 /* Check if the driver can report drive status. If it can, we
1043 can do clever things. If it can't, well, we at least tried! */
1044 if (cdo->drive_status != NULL) {
1045 ret = cdo->drive_status(cdi, CDSL_CURRENT);
1046 cdinfo(CD_OPEN, "drive_status=%d\n", ret);
1047 if (ret == CDS_TRAY_OPEN) {
1048 cdinfo(CD_OPEN, "the tray is open...\n");
1049 /* can/may i close it? */
1050 if (CDROM_CAN(CDC_CLOSE_TRAY) &&
1051 cdi->options & CDO_AUTO_CLOSE) {
1052 cdinfo(CD_OPEN, "trying to close the tray.\n");
1053 ret=cdo->tray_move(cdi,0);
1054 if (ret) {
1055 cdinfo(CD_OPEN, "bummer. tried to close the tray but failed.\n");
1056 /* Ignore the error from the low
1057 level driver. We don't care why it
1058 couldn't close the tray. We only care
1059 that there is no disc in the drive,
1060 since that is the _REAL_ problem here.*/
1061 ret=-ENOMEDIUM;
1062 goto clean_up_and_return;
1063 }
1064 } else {
1065 cdinfo(CD_OPEN, "bummer. this drive can't close the tray.\n");
1066 ret=-ENOMEDIUM;
1067 goto clean_up_and_return;
1068 }
1069 /* Ok, the door should be closed now.. Check again */
1070 ret = cdo->drive_status(cdi, CDSL_CURRENT);
1071 if ((ret == CDS_NO_DISC) || (ret==CDS_TRAY_OPEN)) {
1072 cdinfo(CD_OPEN, "bummer. the tray is still not closed.\n");
1073 cdinfo(CD_OPEN, "tray might not contain a medium.\n");
1074 ret=-ENOMEDIUM;
1075 goto clean_up_and_return;
1076 }
1077 cdinfo(CD_OPEN, "the tray is now closed.\n");
1078 }
1079 /* the door should be closed now, check for the disc */
1080 ret = cdo->drive_status(cdi, CDSL_CURRENT);
1081 if (ret!=CDS_DISC_OK) {
1082 ret = -ENOMEDIUM;
1083 goto clean_up_and_return;
1084 }
1085 }
1086 cdrom_count_tracks(cdi, &tracks);
1087 if (tracks.error == CDS_NO_DISC) {
1088 cdinfo(CD_OPEN, "bummer. no disc.\n");
1089 ret=-ENOMEDIUM;
1090 goto clean_up_and_return;
1091 }
1092 /* CD-Players which don't use O_NONBLOCK, workman
1093 * for example, need bit CDO_CHECK_TYPE cleared! */
1094 if (tracks.data==0) {
1095 if (cdi->options & CDO_CHECK_TYPE) {
1096 /* give people a warning shot, now that CDO_CHECK_TYPE
1097 is the default case! */
1098 cdinfo(CD_OPEN, "bummer. wrong media type.\n");
1099 cdinfo(CD_WARNING, "pid %d must open device O_NONBLOCK!\n",
1100 (unsigned int)current->pid);
1101 ret=-EMEDIUMTYPE;
1102 goto clean_up_and_return;
1103 }
1104 else {
1105 cdinfo(CD_OPEN, "wrong media type, but CDO_CHECK_TYPE not set.\n");
1106 }
1107 }
1108
1109 cdinfo(CD_OPEN, "all seems well, opening the device.\n");
1110
1111 /* all seems well, we can open the device */
1112 ret = cdo->open(cdi, 0); /* open for data */
1113 cdinfo(CD_OPEN, "opening the device gave me %d.\n", ret);
1114 /* After all this careful checking, we shouldn't have problems
1115 opening the device, but we don't want the device locked if
1116 this somehow fails... */
1117 if (ret) {
1118 cdinfo(CD_OPEN, "open device failed.\n");
1119 goto clean_up_and_return;
1120 }
1121 if (CDROM_CAN(CDC_LOCK) && (cdi->options & CDO_LOCK)) {
1122 cdo->lock_door(cdi, 1);
1123 cdinfo(CD_OPEN, "door locked.\n");
1124 }
1125 cdinfo(CD_OPEN, "device opened successfully.\n");
1126 return ret;
1127
1128 /* Something failed. Try to unlock the drive, because some drivers
1129 (notably ide-cd) lock the drive after every command. This produced
1130 a nasty bug where after mount failed, the drive would remain locked!
1131 This ensures that the drive gets unlocked after a mount fails. This
1132 is a goto to avoid bloating the driver with redundant code. */
1133clean_up_and_return:
1134 cdinfo(CD_WARNING, "open failed.\n");
1135 if (CDROM_CAN(CDC_LOCK) && cdi->options & CDO_LOCK) {
1136 cdo->lock_door(cdi, 0);
1137 cdinfo(CD_OPEN, "door unlocked.\n");
1138 }
1139 return ret;
1140}
1141
1142/* This code is similar to that in open_for_data. The routine is called
1143 whenever an audio play operation is requested.
1144*/
1145int check_for_audio_disc(struct cdrom_device_info * cdi,
1146 struct cdrom_device_ops * cdo)
1147{
1148 int ret;
1149 tracktype tracks;
1150 cdinfo(CD_OPEN, "entering check_for_audio_disc\n");
1151 if (!(cdi->options & CDO_CHECK_TYPE))
1152 return 0;
1153 if (cdo->drive_status != NULL) {
1154 ret = cdo->drive_status(cdi, CDSL_CURRENT);
1155 cdinfo(CD_OPEN, "drive_status=%d\n", ret);
1156 if (ret == CDS_TRAY_OPEN) {
1157 cdinfo(CD_OPEN, "the tray is open...\n");
1158 /* can/may i close it? */
1159 if (CDROM_CAN(CDC_CLOSE_TRAY) &&
1160 cdi->options & CDO_AUTO_CLOSE) {
1161 cdinfo(CD_OPEN, "trying to close the tray.\n");
1162 ret=cdo->tray_move(cdi,0);
1163 if (ret) {
1164 cdinfo(CD_OPEN, "bummer. tried to close tray but failed.\n");
1165 /* Ignore the error from the low
1166 level driver. We don't care why it
1167 couldn't close the tray. We only care
1168 that there is no disc in the drive,
1169 since that is the _REAL_ problem here.*/
1170 return -ENOMEDIUM;
1171 }
1172 } else {
1173 cdinfo(CD_OPEN, "bummer. this driver can't close the tray.\n");
1174 return -ENOMEDIUM;
1175 }
1176 /* Ok, the door should be closed now.. Check again */
1177 ret = cdo->drive_status(cdi, CDSL_CURRENT);
1178 if ((ret == CDS_NO_DISC) || (ret==CDS_TRAY_OPEN)) {
1179 cdinfo(CD_OPEN, "bummer. the tray is still not closed.\n");
1180 return -ENOMEDIUM;
1181 }
1182 if (ret!=CDS_DISC_OK) {
1183 cdinfo(CD_OPEN, "bummer. disc isn't ready.\n");
1184 return -EIO;
1185 }
1186 cdinfo(CD_OPEN, "the tray is now closed.\n");
1187 }
1188 }
1189 cdrom_count_tracks(cdi, &tracks);
1190 if (tracks.error)
1191 return(tracks.error);
1192
1193 if (tracks.audio==0)
1194 return -EMEDIUMTYPE;
1195
1196 return 0;
1197}
1198
1199/* Admittedly, the logic below could be performed in a nicer way. */
1200int cdrom_release(struct cdrom_device_info *cdi, struct file *fp)
1201{
1202 struct cdrom_device_ops *cdo = cdi->ops;
1203 int opened_for_data;
1204
1205 cdinfo(CD_CLOSE, "entering cdrom_release\n");
1206
1207 if (cdi->use_count > 0)
1208 cdi->use_count--;
1209 if (cdi->use_count == 0)
1210 cdinfo(CD_CLOSE, "Use count for \"/dev/%s\" now zero\n", cdi->name);
1211 if (cdi->use_count == 0)
1212 cdrom_dvd_rw_close_write(cdi);
1213 if (cdi->use_count == 0 &&
1214 (cdo->capability & CDC_LOCK) && !keeplocked) {
1215 cdinfo(CD_CLOSE, "Unlocking door!\n");
1216 cdo->lock_door(cdi, 0);
1217 }
1218 opened_for_data = !(cdi->options & CDO_USE_FFLAGS) ||
1219 !(fp && fp->f_flags & O_NONBLOCK);
1220
1221 /*
1222 * flush cache on last write release
1223 */
1224 if (CDROM_CAN(CDC_RAM) && !cdi->use_count && cdi->for_data)
1225 cdrom_close_write(cdi);
1226
1227 cdo->release(cdi);
1228 if (cdi->use_count == 0) { /* last process that closes dev*/
1229 if (opened_for_data &&
1230 cdi->options & CDO_AUTO_EJECT && CDROM_CAN(CDC_OPEN_TRAY))
1231 cdo->tray_move(cdi, 1);
1232 }
1233 return 0;
1234}
1235
1236static int cdrom_read_mech_status(struct cdrom_device_info *cdi,
1237 struct cdrom_changer_info *buf)
1238{
1239 struct packet_command cgc;
1240 struct cdrom_device_ops *cdo = cdi->ops;
1241 int length;
1242
1243 /*
1244 * Sanyo changer isn't spec compliant (doesn't use regular change
1245 * LOAD_UNLOAD command, and it doesn't implement the mech status
1246 * command below
1247 */
1248 if (cdi->sanyo_slot) {
1249 buf->hdr.nslots = 3;
1250 buf->hdr.curslot = cdi->sanyo_slot == 3 ? 0 : cdi->sanyo_slot;
1251 for (length = 0; length < 3; length++) {
1252 buf->slots[length].disc_present = 1;
1253 buf->slots[length].change = 0;
1254 }
1255 return 0;
1256 }
1257
1258 length = sizeof(struct cdrom_mechstat_header) +
1259 cdi->capacity * sizeof(struct cdrom_slot);
1260
1261 init_cdrom_command(&cgc, buf, length, CGC_DATA_READ);
1262 cgc.cmd[0] = GPCMD_MECHANISM_STATUS;
1263 cgc.cmd[8] = (length >> 8) & 0xff;
1264 cgc.cmd[9] = length & 0xff;
1265 return cdo->generic_packet(cdi, &cgc);
1266}
1267
1268static int cdrom_slot_status(struct cdrom_device_info *cdi, int slot)
1269{
1270 struct cdrom_changer_info *info;
1271 int ret;
1272
1273 cdinfo(CD_CHANGER, "entering cdrom_slot_status()\n");
1274 if (cdi->sanyo_slot)
1275 return CDS_NO_INFO;
1276
1277 info = kmalloc(sizeof(*info), GFP_KERNEL);
1278 if (!info)
1279 return -ENOMEM;
1280
1281 if ((ret = cdrom_read_mech_status(cdi, info)))
1282 goto out_free;
1283
1284 if (info->slots[slot].disc_present)
1285 ret = CDS_DISC_OK;
1286 else
1287 ret = CDS_NO_DISC;
1288
1289out_free:
1290 kfree(info);
1291 return ret;
1292}
1293
1294/* Return the number of slots for an ATAPI/SCSI cdrom,
1295 * return 1 if not a changer.
1296 */
1297int cdrom_number_of_slots(struct cdrom_device_info *cdi)
1298{
1299 int status;
1300 int nslots = 1;
1301 struct cdrom_changer_info *info;
1302
1303 cdinfo(CD_CHANGER, "entering cdrom_number_of_slots()\n");
1304 /* cdrom_read_mech_status requires a valid value for capacity: */
1305 cdi->capacity = 0;
1306
1307 info = kmalloc(sizeof(*info), GFP_KERNEL);
1308 if (!info)
1309 return -ENOMEM;
1310
1311 if ((status = cdrom_read_mech_status(cdi, info)) == 0)
1312 nslots = info->hdr.nslots;
1313
1314 kfree(info);
1315 return nslots;
1316}
1317
1318
1319/* If SLOT < 0, unload the current slot. Otherwise, try to load SLOT. */
1320static int cdrom_load_unload(struct cdrom_device_info *cdi, int slot)
1321{
1322 struct packet_command cgc;
1323
1324 cdinfo(CD_CHANGER, "entering cdrom_load_unload()\n");
1325 if (cdi->sanyo_slot && slot < 0)
1326 return 0;
1327
1328 init_cdrom_command(&cgc, NULL, 0, CGC_DATA_NONE);
1329 cgc.cmd[0] = GPCMD_LOAD_UNLOAD;
1330 cgc.cmd[4] = 2 + (slot >= 0);
1331 cgc.cmd[8] = slot;
1332 cgc.timeout = 60 * HZ;
1333
1334 /* The Sanyo 3 CD changer uses byte 7 of the
1335 GPCMD_TEST_UNIT_READY to command to switch CDs instead of
1336 using the GPCMD_LOAD_UNLOAD opcode. */
1337 if (cdi->sanyo_slot && -1 < slot) {
1338 cgc.cmd[0] = GPCMD_TEST_UNIT_READY;
1339 cgc.cmd[7] = slot;
1340 cgc.cmd[4] = cgc.cmd[8] = 0;
1341 cdi->sanyo_slot = slot ? slot : 3;
1342 }
1343
1344 return cdi->ops->generic_packet(cdi, &cgc);
1345}
1346
1347static int cdrom_select_disc(struct cdrom_device_info *cdi, int slot)
1348{
1349 struct cdrom_changer_info *info;
1350 int curslot;
1351 int ret;
1352
1353 cdinfo(CD_CHANGER, "entering cdrom_select_disc()\n");
1354 if (!CDROM_CAN(CDC_SELECT_DISC))
1355 return -EDRIVE_CANT_DO_THIS;
1356
1357 (void) cdi->ops->media_changed(cdi, slot);
1358
1359 if (slot == CDSL_NONE) {
1360 /* set media changed bits, on both queues */
1361 cdi->mc_flags = 0x3;
1362 return cdrom_load_unload(cdi, -1);
1363 }
1364
1365 info = kmalloc(sizeof(*info), GFP_KERNEL);
1366 if (!info)
1367 return -ENOMEM;
1368
1369 if ((ret = cdrom_read_mech_status(cdi, info))) {
1370 kfree(info);
1371 return ret;
1372 }
1373
1374 curslot = info->hdr.curslot;
1375 kfree(info);
1376
1377 if (cdi->use_count > 1 || keeplocked) {
1378 if (slot == CDSL_CURRENT) {
1379 return curslot;
1380 } else {
1381 return -EBUSY;
1382 }
1383 }
1384
1385 /* Specifying CDSL_CURRENT will attempt to load the currnet slot,
1386 which is useful if it had been previously unloaded.
1387 Whether it can or not, it returns the current slot.
1388 Similarly, if slot happens to be the current one, we still
1389 try and load it. */
1390 if (slot == CDSL_CURRENT)
1391 slot = curslot;
1392
1393 /* set media changed bits on both queues */
1394 cdi->mc_flags = 0x3;
1395 if ((ret = cdrom_load_unload(cdi, slot)))
1396 return ret;
1397
1398 return slot;
1399}
1400
1401/* We want to make media_changed accessible to the user through an
1402 * ioctl. The main problem now is that we must double-buffer the
1403 * low-level implementation, to assure that the VFS and the user both
1404 * see a medium change once.
1405 */
1406
1407static
1408int media_changed(struct cdrom_device_info *cdi, int queue)
1409{
1410 unsigned int mask = (1 << (queue & 1));
1411 int ret = !!(cdi->mc_flags & mask);
1412
1413 if (!CDROM_CAN(CDC_MEDIA_CHANGED))
1414 return ret;
1415 /* changed since last call? */
1416 if (cdi->ops->media_changed(cdi, CDSL_CURRENT)) {
1417 cdi->mc_flags = 0x3; /* set bit on both queues */
1418 ret |= 1;
1419 cdi->media_written = 0;
1420 }
1421 cdi->mc_flags &= ~mask; /* clear bit */
1422 return ret;
1423}
1424
1425int cdrom_media_changed(struct cdrom_device_info *cdi)
1426{
1427 /* This talks to the VFS, which doesn't like errors - just 1 or 0.
1428 * Returning "0" is always safe (media hasn't been changed). Do that
1429 * if the low-level cdrom driver dosn't support media changed. */
1430 if (cdi == NULL || cdi->ops->media_changed == NULL)
1431 return 0;
1432 if (!CDROM_CAN(CDC_MEDIA_CHANGED))
1433 return 0;
1434 return media_changed(cdi, 0);
1435}
1436
1437/* badly broken, I know. Is due for a fixup anytime. */
1438static void cdrom_count_tracks(struct cdrom_device_info *cdi, tracktype* tracks)
1439{
1440 struct cdrom_tochdr header;
1441 struct cdrom_tocentry entry;
1442 int ret, i;
1443 tracks->data=0;
1444 tracks->audio=0;
1445 tracks->cdi=0;
1446 tracks->xa=0;
1447 tracks->error=0;
1448 cdinfo(CD_COUNT_TRACKS, "entering cdrom_count_tracks\n");
1449 if (!CDROM_CAN(CDC_PLAY_AUDIO)) {
1450 tracks->error=CDS_NO_INFO;
1451 return;
1452 }
1453 /* Grab the TOC header so we can see how many tracks there are */
1454 if ((ret = cdi->ops->audio_ioctl(cdi, CDROMREADTOCHDR, &header))) {
1455 if (ret == -ENOMEDIUM)
1456 tracks->error = CDS_NO_DISC;
1457 else
1458 tracks->error = CDS_NO_INFO;
1459 return;
1460 }
1461 /* check what type of tracks are on this disc */
1462 entry.cdte_format = CDROM_MSF;
1463 for (i = header.cdth_trk0; i <= header.cdth_trk1; i++) {
1464 entry.cdte_track = i;
1465 if (cdi->ops->audio_ioctl(cdi, CDROMREADTOCENTRY, &entry)) {
1466 tracks->error=CDS_NO_INFO;
1467 return;
1468 }
1469 if (entry.cdte_ctrl & CDROM_DATA_TRACK) {
1470 if (entry.cdte_format == 0x10)
1471 tracks->cdi++;
1472 else if (entry.cdte_format == 0x20)
1473 tracks->xa++;
1474 else
1475 tracks->data++;
1476 } else
1477 tracks->audio++;
1478 cdinfo(CD_COUNT_TRACKS, "track %d: format=%d, ctrl=%d\n",
1479 i, entry.cdte_format, entry.cdte_ctrl);
1480 }
1481 cdinfo(CD_COUNT_TRACKS, "disc has %d tracks: %d=audio %d=data %d=Cd-I %d=XA\n",
1482 header.cdth_trk1, tracks->audio, tracks->data,
1483 tracks->cdi, tracks->xa);
1484}
1485
1486/* Requests to the low-level drivers will /always/ be done in the
1487 following format convention:
1488
1489 CDROM_LBA: all data-related requests.
1490 CDROM_MSF: all audio-related requests.
1491
1492 However, a low-level implementation is allowed to refuse this
1493 request, and return information in its own favorite format.
1494
1495 It doesn't make sense /at all/ to ask for a play_audio in LBA
1496 format, or ask for multi-session info in MSF format. However, for
1497 backward compatibility these format requests will be satisfied, but
1498 the requests to the low-level drivers will be sanitized in the more
1499 meaningful format indicated above.
1500 */
1501
1502static
1503void sanitize_format(union cdrom_addr *addr,
1504 u_char * curr, u_char requested)
1505{
1506 if (*curr == requested)
1507 return; /* nothing to be done! */
1508 if (requested == CDROM_LBA) {
1509 addr->lba = (int) addr->msf.frame +
1510 75 * (addr->msf.second - 2 + 60 * addr->msf.minute);
1511 } else { /* CDROM_MSF */
1512 int lba = addr->lba;
1513 addr->msf.frame = lba % 75;
1514 lba /= 75;
1515 lba += 2;
1516 addr->msf.second = lba % 60;
1517 addr->msf.minute = lba / 60;
1518 }
1519 *curr = requested;
1520}
1521
1522void init_cdrom_command(struct packet_command *cgc, void *buf, int len,
1523 int type)
1524{
1525 memset(cgc, 0, sizeof(struct packet_command));
1526 if (buf)
1527 memset(buf, 0, len);
1528 cgc->buffer = (char *) buf;
1529 cgc->buflen = len;
1530 cgc->data_direction = type;
1531 cgc->timeout = 5*HZ;
1532}
1533
1534/* DVD handling */
1535
1536#define copy_key(dest,src) memcpy((dest), (src), sizeof(dvd_key))
1537#define copy_chal(dest,src) memcpy((dest), (src), sizeof(dvd_challenge))
1538
1539static void setup_report_key(struct packet_command *cgc, unsigned agid, unsigned type)
1540{
1541 cgc->cmd[0] = GPCMD_REPORT_KEY;
1542 cgc->cmd[10] = type | (agid << 6);
1543 switch (type) {
1544 case 0: case 8: case 5: {
1545 cgc->buflen = 8;
1546 break;
1547 }
1548 case 1: {
1549 cgc->buflen = 16;
1550 break;
1551 }
1552 case 2: case 4: {
1553 cgc->buflen = 12;
1554 break;
1555 }
1556 }
1557 cgc->cmd[9] = cgc->buflen;
1558 cgc->data_direction = CGC_DATA_READ;
1559}
1560
1561static void setup_send_key(struct packet_command *cgc, unsigned agid, unsigned type)
1562{
1563 cgc->cmd[0] = GPCMD_SEND_KEY;
1564 cgc->cmd[10] = type | (agid << 6);
1565 switch (type) {
1566 case 1: {
1567 cgc->buflen = 16;
1568 break;
1569 }
1570 case 3: {
1571 cgc->buflen = 12;
1572 break;
1573 }
1574 case 6: {
1575 cgc->buflen = 8;
1576 break;
1577 }
1578 }
1579 cgc->cmd[9] = cgc->buflen;
1580 cgc->data_direction = CGC_DATA_WRITE;
1581}
1582
1583static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai)
1584{
1585 int ret;
1586 u_char buf[20];
1587 struct packet_command cgc;
1588 struct cdrom_device_ops *cdo = cdi->ops;
1589 rpc_state_t rpc_state;
1590
1591 memset(buf, 0, sizeof(buf));
1592 init_cdrom_command(&cgc, buf, 0, CGC_DATA_READ);
1593
1594 switch (ai->type) {
1595 /* LU data send */
1596 case DVD_LU_SEND_AGID:
1597 cdinfo(CD_DVD, "entering DVD_LU_SEND_AGID\n");
1598 cgc.quiet = 1;
1599 setup_report_key(&cgc, ai->lsa.agid, 0);
1600
1601 if ((ret = cdo->generic_packet(cdi, &cgc)))
1602 return ret;
1603
1604 ai->lsa.agid = buf[7] >> 6;
1605 /* Returning data, let host change state */
1606 break;
1607
1608 case DVD_LU_SEND_KEY1:
1609 cdinfo(CD_DVD, "entering DVD_LU_SEND_KEY1\n");
1610 setup_report_key(&cgc, ai->lsk.agid, 2);
1611
1612 if ((ret = cdo->generic_packet(cdi, &cgc)))
1613 return ret;
1614
1615 copy_key(ai->lsk.key, &buf[4]);
1616 /* Returning data, let host change state */
1617 break;
1618
1619 case DVD_LU_SEND_CHALLENGE:
1620 cdinfo(CD_DVD, "entering DVD_LU_SEND_CHALLENGE\n");
1621 setup_report_key(&cgc, ai->lsc.agid, 1);
1622
1623 if ((ret = cdo->generic_packet(cdi, &cgc)))
1624 return ret;
1625
1626 copy_chal(ai->lsc.chal, &buf[4]);
1627 /* Returning data, let host change state */
1628 break;
1629
1630 /* Post-auth key */
1631 case DVD_LU_SEND_TITLE_KEY:
1632 cdinfo(CD_DVD, "entering DVD_LU_SEND_TITLE_KEY\n");
1633 cgc.quiet = 1;
1634 setup_report_key(&cgc, ai->lstk.agid, 4);
1635 cgc.cmd[5] = ai->lstk.lba;
1636 cgc.cmd[4] = ai->lstk.lba >> 8;
1637 cgc.cmd[3] = ai->lstk.lba >> 16;
1638 cgc.cmd[2] = ai->lstk.lba >> 24;
1639
1640 if ((ret = cdo->generic_packet(cdi, &cgc)))
1641 return ret;
1642
1643 ai->lstk.cpm = (buf[4] >> 7) & 1;
1644 ai->lstk.cp_sec = (buf[4] >> 6) & 1;
1645 ai->lstk.cgms = (buf[4] >> 4) & 3;
1646 copy_key(ai->lstk.title_key, &buf[5]);
1647 /* Returning data, let host change state */
1648 break;
1649
1650 case DVD_LU_SEND_ASF:
1651 cdinfo(CD_DVD, "entering DVD_LU_SEND_ASF\n");
1652 setup_report_key(&cgc, ai->lsasf.agid, 5);
1653
1654 if ((ret = cdo->generic_packet(cdi, &cgc)))
1655 return ret;
1656
1657 ai->lsasf.asf = buf[7] & 1;
1658 break;
1659
1660 /* LU data receive (LU changes state) */
1661 case DVD_HOST_SEND_CHALLENGE:
1662 cdinfo(CD_DVD, "entering DVD_HOST_SEND_CHALLENGE\n");
1663 setup_send_key(&cgc, ai->hsc.agid, 1);
1664 buf[1] = 0xe;
1665 copy_chal(&buf[4], ai->hsc.chal);
1666
1667 if ((ret = cdo->generic_packet(cdi, &cgc)))
1668 return ret;
1669
1670 ai->type = DVD_LU_SEND_KEY1;
1671 break;
1672
1673 case DVD_HOST_SEND_KEY2:
1674 cdinfo(CD_DVD, "entering DVD_HOST_SEND_KEY2\n");
1675 setup_send_key(&cgc, ai->hsk.agid, 3);
1676 buf[1] = 0xa;
1677 copy_key(&buf[4], ai->hsk.key);
1678
1679 if ((ret = cdo->generic_packet(cdi, &cgc))) {
1680 ai->type = DVD_AUTH_FAILURE;
1681 return ret;
1682 }
1683 ai->type = DVD_AUTH_ESTABLISHED;
1684 break;
1685
1686 /* Misc */
1687 case DVD_INVALIDATE_AGID:
1688 cgc.quiet = 1;
1689 cdinfo(CD_DVD, "entering DVD_INVALIDATE_AGID\n");
1690 setup_report_key(&cgc, ai->lsa.agid, 0x3f);
1691 if ((ret = cdo->generic_packet(cdi, &cgc)))
1692 return ret;
1693 break;
1694
1695 /* Get region settings */
1696 case DVD_LU_SEND_RPC_STATE:
1697 cdinfo(CD_DVD, "entering DVD_LU_SEND_RPC_STATE\n");
1698 setup_report_key(&cgc, 0, 8);
1699 memset(&rpc_state, 0, sizeof(rpc_state_t));
1700 cgc.buffer = (char *) &rpc_state;
1701
1702 if ((ret = cdo->generic_packet(cdi, &cgc)))
1703 return ret;
1704
1705 ai->lrpcs.type = rpc_state.type_code;
1706 ai->lrpcs.vra = rpc_state.vra;
1707 ai->lrpcs.ucca = rpc_state.ucca;
1708 ai->lrpcs.region_mask = rpc_state.region_mask;
1709 ai->lrpcs.rpc_scheme = rpc_state.rpc_scheme;
1710 break;
1711
1712 /* Set region settings */
1713 case DVD_HOST_SEND_RPC_STATE:
1714 cdinfo(CD_DVD, "entering DVD_HOST_SEND_RPC_STATE\n");
1715 setup_send_key(&cgc, 0, 6);
1716 buf[1] = 6;
1717 buf[4] = ai->hrpcs.pdrc;
1718
1719 if ((ret = cdo->generic_packet(cdi, &cgc)))
1720 return ret;
1721 break;
1722
1723 default:
1724 cdinfo(CD_WARNING, "Invalid DVD key ioctl (%d)\n", ai->type);
1725 return -ENOTTY;
1726 }
1727
1728 return 0;
1729}
1730
1731static int dvd_read_physical(struct cdrom_device_info *cdi, dvd_struct *s)
1732{
1733 unsigned char buf[21], *base;
1734 struct dvd_layer *layer;
1735 struct packet_command cgc;
1736 struct cdrom_device_ops *cdo = cdi->ops;
1737 int ret, layer_num = s->physical.layer_num;
1738
1739 if (layer_num >= DVD_LAYERS)
1740 return -EINVAL;
1741
1742 init_cdrom_command(&cgc, buf, sizeof(buf), CGC_DATA_READ);
1743 cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE;
1744 cgc.cmd[6] = layer_num;
1745 cgc.cmd[7] = s->type;
1746 cgc.cmd[9] = cgc.buflen & 0xff;
1747
1748 /*
1749 * refrain from reporting errors on non-existing layers (mainly)
1750 */
1751 cgc.quiet = 1;
1752
1753 if ((ret = cdo->generic_packet(cdi, &cgc)))
1754 return ret;
1755
1756 base = &buf[4];
1757 layer = &s->physical.layer[layer_num];
1758
1759 /*
1760 * place the data... really ugly, but at least we won't have to
1761 * worry about endianess in userspace.
1762 */
1763 memset(layer, 0, sizeof(*layer));
1764 layer->book_version = base[0] & 0xf;
1765 layer->book_type = base[0] >> 4;
1766 layer->min_rate = base[1] & 0xf;
1767 layer->disc_size = base[1] >> 4;
1768 layer->layer_type = base[2] & 0xf;
1769 layer->track_path = (base[2] >> 4) & 1;
1770 layer->nlayers = (base[2] >> 5) & 3;
1771 layer->track_density = base[3] & 0xf;
1772 layer->linear_density = base[3] >> 4;
1773 layer->start_sector = base[5] << 16 | base[6] << 8 | base[7];
1774 layer->end_sector = base[9] << 16 | base[10] << 8 | base[11];
1775 layer->end_sector_l0 = base[13] << 16 | base[14] << 8 | base[15];
1776 layer->bca = base[16] >> 7;
1777
1778 return 0;
1779}
1780
1781static int dvd_read_copyright(struct cdrom_device_info *cdi, dvd_struct *s)
1782{
1783 int ret;
1784 u_char buf[8];
1785 struct packet_command cgc;
1786 struct cdrom_device_ops *cdo = cdi->ops;
1787
1788 init_cdrom_command(&cgc, buf, sizeof(buf), CGC_DATA_READ);
1789 cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE;
1790 cgc.cmd[6] = s->copyright.layer_num;
1791 cgc.cmd[7] = s->type;
1792 cgc.cmd[8] = cgc.buflen >> 8;
1793 cgc.cmd[9] = cgc.buflen & 0xff;
1794
1795 if ((ret = cdo->generic_packet(cdi, &cgc)))
1796 return ret;
1797
1798 s->copyright.cpst = buf[4];
1799 s->copyright.rmi = buf[5];
1800
1801 return 0;
1802}
1803
1804static int dvd_read_disckey(struct cdrom_device_info *cdi, dvd_struct *s)
1805{
1806 int ret, size;
1807 u_char *buf;
1808 struct packet_command cgc;
1809 struct cdrom_device_ops *cdo = cdi->ops;
1810
1811 size = sizeof(s->disckey.value) + 4;
1812
1813 if ((buf = (u_char *) kmalloc(size, GFP_KERNEL)) == NULL)
1814 return -ENOMEM;
1815
1816 init_cdrom_command(&cgc, buf, size, CGC_DATA_READ);
1817 cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE;
1818 cgc.cmd[7] = s->type;
1819 cgc.cmd[8] = size >> 8;
1820 cgc.cmd[9] = size & 0xff;
1821 cgc.cmd[10] = s->disckey.agid << 6;
1822
1823 if (!(ret = cdo->generic_packet(cdi, &cgc)))
1824 memcpy(s->disckey.value, &buf[4], sizeof(s->disckey.value));
1825
1826 kfree(buf);
1827 return ret;
1828}
1829
1830static int dvd_read_bca(struct cdrom_device_info *cdi, dvd_struct *s)
1831{
1832 int ret;
1833 u_char buf[4 + 188];
1834 struct packet_command cgc;
1835 struct cdrom_device_ops *cdo = cdi->ops;
1836
1837 init_cdrom_command(&cgc, buf, sizeof(buf), CGC_DATA_READ);
1838 cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE;
1839 cgc.cmd[7] = s->type;
1840 cgc.cmd[9] = cgc.buflen = 0xff;
1841
1842 if ((ret = cdo->generic_packet(cdi, &cgc)))
1843 return ret;
1844
1845 s->bca.len = buf[0] << 8 | buf[1];
1846 if (s->bca.len < 12 || s->bca.len > 188) {
1847 cdinfo(CD_WARNING, "Received invalid BCA length (%d)\n", s->bca.len);
1848 return -EIO;
1849 }
1850 memcpy(s->bca.value, &buf[4], s->bca.len);
1851
1852 return 0;
1853}
1854
1855static int dvd_read_manufact(struct cdrom_device_info *cdi, dvd_struct *s)
1856{
1857 int ret = 0, size;
1858 u_char *buf;
1859 struct packet_command cgc;
1860 struct cdrom_device_ops *cdo = cdi->ops;
1861
1862 size = sizeof(s->manufact.value) + 4;
1863
1864 if ((buf = (u_char *) kmalloc(size, GFP_KERNEL)) == NULL)
1865 return -ENOMEM;
1866
1867 init_cdrom_command(&cgc, buf, size, CGC_DATA_READ);
1868 cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE;
1869 cgc.cmd[7] = s->type;
1870 cgc.cmd[8] = size >> 8;
1871 cgc.cmd[9] = size & 0xff;
1872
1873 if ((ret = cdo->generic_packet(cdi, &cgc))) {
1874 kfree(buf);
1875 return ret;
1876 }
1877
1878 s->manufact.len = buf[0] << 8 | buf[1];
1879 if (s->manufact.len < 0 || s->manufact.len > 2048) {
1880 cdinfo(CD_WARNING, "Received invalid manufacture info length"
1881 " (%d)\n", s->manufact.len);
1882 ret = -EIO;
1883 } else {
1884 memcpy(s->manufact.value, &buf[4], s->manufact.len);
1885 }
1886
1887 kfree(buf);
1888 return ret;
1889}
1890
1891static int dvd_read_struct(struct cdrom_device_info *cdi, dvd_struct *s)
1892{
1893 switch (s->type) {
1894 case DVD_STRUCT_PHYSICAL:
1895 return dvd_read_physical(cdi, s);
1896
1897 case DVD_STRUCT_COPYRIGHT:
1898 return dvd_read_copyright(cdi, s);
1899
1900 case DVD_STRUCT_DISCKEY:
1901 return dvd_read_disckey(cdi, s);
1902
1903 case DVD_STRUCT_BCA:
1904 return dvd_read_bca(cdi, s);
1905
1906 case DVD_STRUCT_MANUFACT:
1907 return dvd_read_manufact(cdi, s);
1908
1909 default:
1910 cdinfo(CD_WARNING, ": Invalid DVD structure read requested (%d)\n",
1911 s->type);
1912 return -EINVAL;
1913 }
1914}
1915
1916int cdrom_mode_sense(struct cdrom_device_info *cdi,
1917 struct packet_command *cgc,
1918 int page_code, int page_control)
1919{
1920 struct cdrom_device_ops *cdo = cdi->ops;
1921
1922 memset(cgc->cmd, 0, sizeof(cgc->cmd));
1923
1924 cgc->cmd[0] = GPCMD_MODE_SENSE_10;
1925 cgc->cmd[2] = page_code | (page_control << 6);
1926 cgc->cmd[7] = cgc->buflen >> 8;
1927 cgc->cmd[8] = cgc->buflen & 0xff;
1928 cgc->data_direction = CGC_DATA_READ;
1929 return cdo->generic_packet(cdi, cgc);
1930}
1931
1932int cdrom_mode_select(struct cdrom_device_info *cdi,
1933 struct packet_command *cgc)
1934{
1935 struct cdrom_device_ops *cdo = cdi->ops;
1936
1937 memset(cgc->cmd, 0, sizeof(cgc->cmd));
1938 memset(cgc->buffer, 0, 2);
1939 cgc->cmd[0] = GPCMD_MODE_SELECT_10;
1940 cgc->cmd[1] = 0x10; /* PF */
1941 cgc->cmd[7] = cgc->buflen >> 8;
1942 cgc->cmd[8] = cgc->buflen & 0xff;
1943 cgc->data_direction = CGC_DATA_WRITE;
1944 return cdo->generic_packet(cdi, cgc);
1945}
1946
1947static int cdrom_read_subchannel(struct cdrom_device_info *cdi,
1948 struct cdrom_subchnl *subchnl, int mcn)
1949{
1950 struct cdrom_device_ops *cdo = cdi->ops;
1951 struct packet_command cgc;
1952 char buffer[32];
1953 int ret;
1954
1955 init_cdrom_command(&cgc, buffer, 16, CGC_DATA_READ);
1956 cgc.cmd[0] = GPCMD_READ_SUBCHANNEL;
1957 cgc.cmd[1] = 2; /* MSF addressing */
1958 cgc.cmd[2] = 0x40; /* request subQ data */
1959 cgc.cmd[3] = mcn ? 2 : 1;
1960 cgc.cmd[8] = 16;
1961
1962 if ((ret = cdo->generic_packet(cdi, &cgc)))
1963 return ret;
1964
1965 subchnl->cdsc_audiostatus = cgc.buffer[1];
1966 subchnl->cdsc_format = CDROM_MSF;
1967 subchnl->cdsc_ctrl = cgc.buffer[5] & 0xf;
1968 subchnl->cdsc_trk = cgc.buffer[6];
1969 subchnl->cdsc_ind = cgc.buffer[7];
1970
1971 subchnl->cdsc_reladdr.msf.minute = cgc.buffer[13];
1972 subchnl->cdsc_reladdr.msf.second = cgc.buffer[14];
1973 subchnl->cdsc_reladdr.msf.frame = cgc.buffer[15];
1974 subchnl->cdsc_absaddr.msf.minute = cgc.buffer[9];
1975 subchnl->cdsc_absaddr.msf.second = cgc.buffer[10];
1976 subchnl->cdsc_absaddr.msf.frame = cgc.buffer[11];
1977
1978 return 0;
1979}
1980
1981/*
1982 * Specific READ_10 interface
1983 */
1984static int cdrom_read_cd(struct cdrom_device_info *cdi,
1985 struct packet_command *cgc, int lba,
1986 int blocksize, int nblocks)
1987{
1988 struct cdrom_device_ops *cdo = cdi->ops;
1989
1990 memset(&cgc->cmd, 0, sizeof(cgc->cmd));
1991 cgc->cmd[0] = GPCMD_READ_10;
1992 cgc->cmd[2] = (lba >> 24) & 0xff;
1993 cgc->cmd[3] = (lba >> 16) & 0xff;
1994 cgc->cmd[4] = (lba >> 8) & 0xff;
1995 cgc->cmd[5] = lba & 0xff;
1996 cgc->cmd[6] = (nblocks >> 16) & 0xff;
1997 cgc->cmd[7] = (nblocks >> 8) & 0xff;
1998 cgc->cmd[8] = nblocks & 0xff;
1999 cgc->buflen = blocksize * nblocks;
2000 return cdo->generic_packet(cdi, cgc);
2001}
2002
2003/* very generic interface for reading the various types of blocks */
2004static int cdrom_read_block(struct cdrom_device_info *cdi,
2005 struct packet_command *cgc,
2006 int lba, int nblocks, int format, int blksize)
2007{
2008 struct cdrom_device_ops *cdo = cdi->ops;
2009
2010 memset(&cgc->cmd, 0, sizeof(cgc->cmd));
2011 cgc->cmd[0] = GPCMD_READ_CD;
2012 /* expected sector size - cdda,mode1,etc. */
2013 cgc->cmd[1] = format << 2;
2014 /* starting address */
2015 cgc->cmd[2] = (lba >> 24) & 0xff;
2016 cgc->cmd[3] = (lba >> 16) & 0xff;
2017 cgc->cmd[4] = (lba >> 8) & 0xff;
2018 cgc->cmd[5] = lba & 0xff;
2019 /* number of blocks */
2020 cgc->cmd[6] = (nblocks >> 16) & 0xff;
2021 cgc->cmd[7] = (nblocks >> 8) & 0xff;
2022 cgc->cmd[8] = nblocks & 0xff;
2023 cgc->buflen = blksize * nblocks;
2024
2025 /* set the header info returned */
2026 switch (blksize) {
2027 case CD_FRAMESIZE_RAW0 : cgc->cmd[9] = 0x58; break;
2028 case CD_FRAMESIZE_RAW1 : cgc->cmd[9] = 0x78; break;
2029 case CD_FRAMESIZE_RAW : cgc->cmd[9] = 0xf8; break;
2030 default : cgc->cmd[9] = 0x10;
2031 }
2032
2033 return cdo->generic_packet(cdi, cgc);
2034}
2035
2036static int cdrom_read_cdda_old(struct cdrom_device_info *cdi, __u8 __user *ubuf,
2037 int lba, int nframes)
2038{
2039 struct packet_command cgc;
2040 int ret = 0;
2041 int nr;
2042
2043 cdi->last_sense = 0;
2044
2045 memset(&cgc, 0, sizeof(cgc));
2046
2047 /*
2048 * start with will ra.nframes size, back down if alloc fails
2049 */
2050 nr = nframes;
2051 do {
2052 cgc.buffer = kmalloc(CD_FRAMESIZE_RAW * nr, GFP_KERNEL);
2053 if (cgc.buffer)
2054 break;
2055
2056 nr >>= 1;
2057 } while (nr);
2058
2059 if (!nr)
2060 return -ENOMEM;
2061
2062 if (!access_ok(VERIFY_WRITE, ubuf, nframes * CD_FRAMESIZE_RAW)) {
2063 ret = -EFAULT;
2064 goto out;
2065 }
2066
2067 cgc.data_direction = CGC_DATA_READ;
2068 while (nframes > 0) {
2069 if (nr > nframes)
2070 nr = nframes;
2071
2072 ret = cdrom_read_block(cdi, &cgc, lba, nr, 1, CD_FRAMESIZE_RAW);
2073 if (ret)
2074 break;
2075 if (__copy_to_user(ubuf, cgc.buffer, CD_FRAMESIZE_RAW * nr)) {
2076 ret = -EFAULT;
2077 break;
2078 }
2079 ubuf += CD_FRAMESIZE_RAW * nr;
2080 nframes -= nr;
2081 lba += nr;
2082 }
2083out:
2084 kfree(cgc.buffer);
2085 return ret;
2086}
2087
2088static int cdrom_read_cdda_bpc(struct cdrom_device_info *cdi, __u8 __user *ubuf,
2089 int lba, int nframes)
2090{
2091 request_queue_t *q = cdi->disk->queue;
2092 struct request *rq;
2093 struct bio *bio;
2094 unsigned int len;
2095 int nr, ret = 0;
2096
2097 if (!q)
2098 return -ENXIO;
2099
2100 cdi->last_sense = 0;
2101
2102 while (nframes) {
2103 nr = nframes;
2104 if (cdi->cdda_method == CDDA_BPC_SINGLE)
2105 nr = 1;
2106 if (nr * CD_FRAMESIZE_RAW > (q->max_sectors << 9))
2107 nr = (q->max_sectors << 9) / CD_FRAMESIZE_RAW;
2108
2109 len = nr * CD_FRAMESIZE_RAW;
2110
2111 rq = blk_rq_map_user(q, READ, ubuf, len);
2112 if (IS_ERR(rq))
2113 return PTR_ERR(rq);
2114
2115 memset(rq->cmd, 0, sizeof(rq->cmd));
2116 rq->cmd[0] = GPCMD_READ_CD;
2117 rq->cmd[1] = 1 << 2;
2118 rq->cmd[2] = (lba >> 24) & 0xff;
2119 rq->cmd[3] = (lba >> 16) & 0xff;
2120 rq->cmd[4] = (lba >> 8) & 0xff;
2121 rq->cmd[5] = lba & 0xff;
2122 rq->cmd[6] = (nr >> 16) & 0xff;
2123 rq->cmd[7] = (nr >> 8) & 0xff;
2124 rq->cmd[8] = nr & 0xff;
2125 rq->cmd[9] = 0xf8;
2126
2127 rq->cmd_len = 12;
2128 rq->flags |= REQ_BLOCK_PC;
2129 rq->timeout = 60 * HZ;
2130 bio = rq->bio;
2131
2132 if (rq->bio)
2133 blk_queue_bounce(q, &rq->bio);
2134
2135 if (blk_execute_rq(q, cdi->disk, rq)) {
2136 struct request_sense *s = rq->sense;
2137 ret = -EIO;
2138 cdi->last_sense = s->sense_key;
2139 }
2140
2141 if (blk_rq_unmap_user(rq, bio, len))
2142 ret = -EFAULT;
2143
2144 if (ret)
2145 break;
2146
2147 nframes -= nr;
2148 lba += nr;
2149 ubuf += len;
2150 }
2151
2152 return ret;
2153}
2154
2155static int cdrom_read_cdda(struct cdrom_device_info *cdi, __u8 __user *ubuf,
2156 int lba, int nframes)
2157{
2158 int ret;
2159
2160 if (cdi->cdda_method == CDDA_OLD)
2161 return cdrom_read_cdda_old(cdi, ubuf, lba, nframes);
2162
2163retry:
2164 /*
2165 * for anything else than success and io error, we need to retry
2166 */
2167 ret = cdrom_read_cdda_bpc(cdi, ubuf, lba, nframes);
2168 if (!ret || ret != -EIO)
2169 return ret;
2170
2171 /*
2172 * I've seen drives get sense 4/8/3 udma crc errors on multi
2173 * frame dma, so drop to single frame dma if we need to
2174 */
2175 if (cdi->cdda_method == CDDA_BPC_FULL && nframes > 1) {
2176 printk("cdrom: dropping to single frame dma\n");
2177 cdi->cdda_method = CDDA_BPC_SINGLE;
2178 goto retry;
2179 }
2180
2181 /*
2182 * so we have an io error of some sort with multi frame dma. if the
2183 * condition wasn't a hardware error
2184 * problems, not for any error
2185 */
2186 if (cdi->last_sense != 0x04 && cdi->last_sense != 0x0b)
2187 return ret;
2188
2189 printk("cdrom: dropping to old style cdda (sense=%x)\n", cdi->last_sense);
2190 cdi->cdda_method = CDDA_OLD;
2191 return cdrom_read_cdda_old(cdi, ubuf, lba, nframes);
2192}
2193
2194/* Just about every imaginable ioctl is supported in the Uniform layer
2195 * these days. ATAPI / SCSI specific code now mainly resides in
2196 * mmc_ioct().
2197 */
2198int cdrom_ioctl(struct file * file, struct cdrom_device_info *cdi,
2199 struct inode *ip, unsigned int cmd, unsigned long arg)
2200{
2201 struct cdrom_device_ops *cdo = cdi->ops;
2202 int ret;
2203
2204 /* Try the generic SCSI command ioctl's first.. */
2205 ret = scsi_cmd_ioctl(file, ip->i_bdev->bd_disk, cmd, (void __user *)arg);
2206 if (ret != -ENOTTY)
2207 return ret;
2208
2209 /* the first few commands do not deal with audio drive_info, but
2210 only with routines in cdrom device operations. */
2211 switch (cmd) {
2212 case CDROMMULTISESSION: {
2213 struct cdrom_multisession ms_info;
2214 u_char requested_format;
2215 cdinfo(CD_DO_IOCTL, "entering CDROMMULTISESSION\n");
2216 if (!(cdo->capability & CDC_MULTI_SESSION))
2217 return -ENOSYS;
2218 IOCTL_IN(arg, struct cdrom_multisession, ms_info);
2219 requested_format = ms_info.addr_format;
2220 if (!((requested_format == CDROM_MSF) ||
2221 (requested_format == CDROM_LBA)))
2222 return -EINVAL;
2223 ms_info.addr_format = CDROM_LBA;
2224 if ((ret=cdo->get_last_session(cdi, &ms_info)))
2225 return ret;
2226 sanitize_format(&ms_info.addr, &ms_info.addr_format,
2227 requested_format);
2228 IOCTL_OUT(arg, struct cdrom_multisession, ms_info);
2229 cdinfo(CD_DO_IOCTL, "CDROMMULTISESSION successful\n");
2230 return 0;
2231 }
2232
2233 case CDROMEJECT: {
2234 cdinfo(CD_DO_IOCTL, "entering CDROMEJECT\n");
2235 if (!CDROM_CAN(CDC_OPEN_TRAY))
2236 return -ENOSYS;
2237 if (cdi->use_count != 1 || keeplocked)
2238 return -EBUSY;
2239 if (CDROM_CAN(CDC_LOCK))
2240 if ((ret=cdo->lock_door(cdi, 0)))
2241 return ret;
2242
2243 return cdo->tray_move(cdi, 1);
2244 }
2245
2246 case CDROMCLOSETRAY: {
2247 cdinfo(CD_DO_IOCTL, "entering CDROMCLOSETRAY\n");
2248 if (!CDROM_CAN(CDC_CLOSE_TRAY))
2249 return -ENOSYS;
2250 return cdo->tray_move(cdi, 0);
2251 }
2252
2253 case CDROMEJECT_SW: {
2254 cdinfo(CD_DO_IOCTL, "entering CDROMEJECT_SW\n");
2255 if (!CDROM_CAN(CDC_OPEN_TRAY))
2256 return -ENOSYS;
2257 if (keeplocked)
2258 return -EBUSY;
2259 cdi->options &= ~(CDO_AUTO_CLOSE | CDO_AUTO_EJECT);
2260 if (arg)
2261 cdi->options |= CDO_AUTO_CLOSE | CDO_AUTO_EJECT;
2262 return 0;
2263 }
2264
2265 case CDROM_MEDIA_CHANGED: {
2266 struct cdrom_changer_info *info;
2267 int changed;
2268
2269 cdinfo(CD_DO_IOCTL, "entering CDROM_MEDIA_CHANGED\n");
2270 if (!CDROM_CAN(CDC_MEDIA_CHANGED))
2271 return -ENOSYS;
2272
2273 /* cannot select disc or select current disc */
2274 if (!CDROM_CAN(CDC_SELECT_DISC) || arg == CDSL_CURRENT)
2275 return media_changed(cdi, 1);
2276
2277 if ((unsigned int)arg >= cdi->capacity)
2278 return -EINVAL;
2279
2280 info = kmalloc(sizeof(*info), GFP_KERNEL);
2281 if (!info)
2282 return -ENOMEM;
2283
2284 if ((ret = cdrom_read_mech_status(cdi, info))) {
2285 kfree(info);
2286 return ret;
2287 }
2288
2289 changed = info->slots[arg].change;
2290 kfree(info);
2291 return changed;
2292 }
2293
2294 case CDROM_SET_OPTIONS: {
2295 cdinfo(CD_DO_IOCTL, "entering CDROM_SET_OPTIONS\n");
2296 /* options need to be in sync with capability. too late for
2297 that, so we have to check each one separately... */
2298 switch (arg) {
2299 case CDO_USE_FFLAGS:
2300 case CDO_CHECK_TYPE:
2301 break;
2302 case CDO_LOCK:
2303 if (!CDROM_CAN(CDC_LOCK))
2304 return -ENOSYS;
2305 break;
2306 case 0:
2307 return cdi->options;
2308 /* default is basically CDO_[AUTO_CLOSE|AUTO_EJECT] */
2309 default:
2310 if (!CDROM_CAN(arg))
2311 return -ENOSYS;
2312 }
2313 cdi->options |= (int) arg;
2314 return cdi->options;
2315 }
2316
2317 case CDROM_CLEAR_OPTIONS: {
2318 cdinfo(CD_DO_IOCTL, "entering CDROM_CLEAR_OPTIONS\n");
2319 cdi->options &= ~(int) arg;
2320 return cdi->options;
2321 }
2322
2323 case CDROM_SELECT_SPEED: {
2324 cdinfo(CD_DO_IOCTL, "entering CDROM_SELECT_SPEED\n");
2325 if (!CDROM_CAN(CDC_SELECT_SPEED))
2326 return -ENOSYS;
2327 return cdo->select_speed(cdi, arg);
2328 }
2329
2330 case CDROM_SELECT_DISC: {
2331 cdinfo(CD_DO_IOCTL, "entering CDROM_SELECT_DISC\n");
2332 if (!CDROM_CAN(CDC_SELECT_DISC))
2333 return -ENOSYS;
2334
2335 if ((arg != CDSL_CURRENT) && (arg != CDSL_NONE))
2336 if ((int)arg >= cdi->capacity)
2337 return -EINVAL;
2338
2339 /* cdo->select_disc is a hook to allow a driver-specific
2340 * way of seleting disc. However, since there is no
2341 * equiv hook for cdrom_slot_status this may not
2342 * actually be useful...
2343 */
2344 if (cdo->select_disc != NULL)
2345 return cdo->select_disc(cdi, arg);
2346
2347 /* no driver specific select_disc(), call our own */
2348 cdinfo(CD_CHANGER, "Using generic cdrom_select_disc()\n");
2349 return cdrom_select_disc(cdi, arg);
2350 }
2351
2352 case CDROMRESET: {
2353 if (!capable(CAP_SYS_ADMIN))
2354 return -EACCES;
2355 cdinfo(CD_DO_IOCTL, "entering CDROM_RESET\n");
2356 if (!CDROM_CAN(CDC_RESET))
2357 return -ENOSYS;
2358 invalidate_bdev(ip->i_bdev, 0);
2359 return cdo->reset(cdi);
2360 }
2361
2362 case CDROM_LOCKDOOR: {
2363 cdinfo(CD_DO_IOCTL, "%socking door.\n", arg ? "L" : "Unl");
2364 if (!CDROM_CAN(CDC_LOCK))
2365 return -EDRIVE_CANT_DO_THIS;
2366 keeplocked = arg ? 1 : 0;
2367 /* don't unlock the door on multiple opens,but allow root
2368 * to do so */
2369 if ((cdi->use_count != 1) && !arg && !capable(CAP_SYS_ADMIN))
2370 return -EBUSY;
2371 return cdo->lock_door(cdi, arg);
2372 }
2373
2374 case CDROM_DEBUG: {
2375 if (!capable(CAP_SYS_ADMIN))
2376 return -EACCES;
2377 cdinfo(CD_DO_IOCTL, "%sabling debug.\n", arg ? "En" : "Dis");
2378 debug = arg ? 1 : 0;
2379 return debug;
2380 }
2381
2382 case CDROM_GET_CAPABILITY: {
2383 cdinfo(CD_DO_IOCTL, "entering CDROM_GET_CAPABILITY\n");
2384 return (cdo->capability & ~cdi->mask);
2385 }
2386
2387/* The following function is implemented, although very few audio
2388 * discs give Universal Product Code information, which should just be
2389 * the Medium Catalog Number on the box. Note, that the way the code
2390 * is written on the CD is /not/ uniform across all discs!
2391 */
2392 case CDROM_GET_MCN: {
2393 struct cdrom_mcn mcn;
2394 cdinfo(CD_DO_IOCTL, "entering CDROM_GET_MCN\n");
2395 if (!(cdo->capability & CDC_MCN))
2396 return -ENOSYS;
2397 if ((ret=cdo->get_mcn(cdi, &mcn)))
2398 return ret;
2399 IOCTL_OUT(arg, struct cdrom_mcn, mcn);
2400 cdinfo(CD_DO_IOCTL, "CDROM_GET_MCN successful\n");
2401 return 0;
2402 }
2403
2404 case CDROM_DRIVE_STATUS: {
2405 cdinfo(CD_DO_IOCTL, "entering CDROM_DRIVE_STATUS\n");
2406 if (!(cdo->capability & CDC_DRIVE_STATUS))
2407 return -ENOSYS;
2408 if (!CDROM_CAN(CDC_SELECT_DISC))
2409 return cdo->drive_status(cdi, CDSL_CURRENT);
2410 if ((arg == CDSL_CURRENT) || (arg == CDSL_NONE))
2411 return cdo->drive_status(cdi, CDSL_CURRENT);
2412 if (((int)arg >= cdi->capacity))
2413 return -EINVAL;
2414 return cdrom_slot_status(cdi, arg);
2415 }
2416
2417 /* Ok, this is where problems start. The current interface for the
2418 CDROM_DISC_STATUS ioctl is flawed. It makes the false assumption
2419 that CDs are all CDS_DATA_1 or all CDS_AUDIO, etc. Unfortunatly,
2420 while this is often the case, it is also very common for CDs to
2421 have some tracks with data, and some tracks with audio. Just
2422 because I feel like it, I declare the following to be the best
2423 way to cope. If the CD has ANY data tracks on it, it will be
2424 returned as a data CD. If it has any XA tracks, I will return
2425 it as that. Now I could simplify this interface by combining these
2426 returns with the above, but this more clearly demonstrates
2427 the problem with the current interface. Too bad this wasn't
2428 designed to use bitmasks... -Erik
2429
2430 Well, now we have the option CDS_MIXED: a mixed-type CD.
2431 User level programmers might feel the ioctl is not very useful.
2432 ---david
2433 */
2434 case CDROM_DISC_STATUS: {
2435 tracktype tracks;
2436 cdinfo(CD_DO_IOCTL, "entering CDROM_DISC_STATUS\n");
2437 cdrom_count_tracks(cdi, &tracks);
2438 if (tracks.error)
2439 return(tracks.error);
2440
2441 /* Policy mode on */
2442 if (tracks.audio > 0) {
2443 if (tracks.data==0 && tracks.cdi==0 && tracks.xa==0)
2444 return CDS_AUDIO;
2445 else
2446 return CDS_MIXED;
2447 }
2448 if (tracks.cdi > 0) return CDS_XA_2_2;
2449 if (tracks.xa > 0) return CDS_XA_2_1;
2450 if (tracks.data > 0) return CDS_DATA_1;
2451 /* Policy mode off */
2452
2453 cdinfo(CD_WARNING,"This disc doesn't have any tracks I recognize!\n");
2454 return CDS_NO_INFO;
2455 }
2456
2457 case CDROM_CHANGER_NSLOTS: {
2458 cdinfo(CD_DO_IOCTL, "entering CDROM_CHANGER_NSLOTS\n");
2459 return cdi->capacity;
2460 }
2461 }
2462
2463 /* use the ioctls that are implemented through the generic_packet()
2464 interface. this may look at bit funny, but if -ENOTTY is
2465 returned that particular ioctl is not implemented and we
2466 let it go through the device specific ones. */
2467 if (CDROM_CAN(CDC_GENERIC_PACKET)) {
2468 ret = mmc_ioctl(cdi, cmd, arg);
2469 if (ret != -ENOTTY) {
2470 return ret;
2471 }
2472 }
2473
2474 /* note: most of the cdinfo() calls are commented out here,
2475 because they fill up the sys log when CD players poll
2476 the drive. */
2477 switch (cmd) {
2478 case CDROMSUBCHNL: {
2479 struct cdrom_subchnl q;
2480 u_char requested, back;
2481 if (!CDROM_CAN(CDC_PLAY_AUDIO))
2482 return -ENOSYS;
2483 /* cdinfo(CD_DO_IOCTL,"entering CDROMSUBCHNL\n");*/
2484 IOCTL_IN(arg, struct cdrom_subchnl, q);
2485 requested = q.cdsc_format;
2486 if (!((requested == CDROM_MSF) ||
2487 (requested == CDROM_LBA)))
2488 return -EINVAL;
2489 q.cdsc_format = CDROM_MSF;
2490 if ((ret=cdo->audio_ioctl(cdi, cmd, &q)))
2491 return ret;
2492 back = q.cdsc_format; /* local copy */
2493 sanitize_format(&q.cdsc_absaddr, &back, requested);
2494 sanitize_format(&q.cdsc_reladdr, &q.cdsc_format, requested);
2495 IOCTL_OUT(arg, struct cdrom_subchnl, q);
2496 /* cdinfo(CD_DO_IOCTL, "CDROMSUBCHNL successful\n"); */
2497 return 0;
2498 }
2499 case CDROMREADTOCHDR: {
2500 struct cdrom_tochdr header;
2501 if (!CDROM_CAN(CDC_PLAY_AUDIO))
2502 return -ENOSYS;
2503 /* cdinfo(CD_DO_IOCTL, "entering CDROMREADTOCHDR\n"); */
2504 IOCTL_IN(arg, struct cdrom_tochdr, header);
2505 if ((ret=cdo->audio_ioctl(cdi, cmd, &header)))
2506 return ret;
2507 IOCTL_OUT(arg, struct cdrom_tochdr, header);
2508 /* cdinfo(CD_DO_IOCTL, "CDROMREADTOCHDR successful\n"); */
2509 return 0;
2510 }
2511 case CDROMREADTOCENTRY: {
2512 struct cdrom_tocentry entry;
2513 u_char requested_format;
2514 if (!CDROM_CAN(CDC_PLAY_AUDIO))
2515 return -ENOSYS;
2516 /* cdinfo(CD_DO_IOCTL, "entering CDROMREADTOCENTRY\n"); */
2517 IOCTL_IN(arg, struct cdrom_tocentry, entry);
2518 requested_format = entry.cdte_format;
2519 if (!((requested_format == CDROM_MSF) ||
2520 (requested_format == CDROM_LBA)))
2521 return -EINVAL;
2522 /* make interface to low-level uniform */
2523 entry.cdte_format = CDROM_MSF;
2524 if ((ret=cdo->audio_ioctl(cdi, cmd, &entry)))
2525 return ret;
2526 sanitize_format(&entry.cdte_addr,
2527 &entry.cdte_format, requested_format);
2528 IOCTL_OUT(arg, struct cdrom_tocentry, entry);
2529 /* cdinfo(CD_DO_IOCTL, "CDROMREADTOCENTRY successful\n"); */
2530 return 0;
2531 }
2532 case CDROMPLAYMSF: {
2533 struct cdrom_msf msf;
2534 if (!CDROM_CAN(CDC_PLAY_AUDIO))
2535 return -ENOSYS;
2536 cdinfo(CD_DO_IOCTL, "entering CDROMPLAYMSF\n");
2537 IOCTL_IN(arg, struct cdrom_msf, msf);
2538 return cdo->audio_ioctl(cdi, cmd, &msf);
2539 }
2540 case CDROMPLAYTRKIND: {
2541 struct cdrom_ti ti;
2542 if (!CDROM_CAN(CDC_PLAY_AUDIO))
2543 return -ENOSYS;
2544 cdinfo(CD_DO_IOCTL, "entering CDROMPLAYTRKIND\n");
2545 IOCTL_IN(arg, struct cdrom_ti, ti);
2546 CHECKAUDIO;
2547 return cdo->audio_ioctl(cdi, cmd, &ti);
2548 }
2549 case CDROMVOLCTRL: {
2550 struct cdrom_volctrl volume;
2551 if (!CDROM_CAN(CDC_PLAY_AUDIO))
2552 return -ENOSYS;
2553 cdinfo(CD_DO_IOCTL, "entering CDROMVOLCTRL\n");
2554 IOCTL_IN(arg, struct cdrom_volctrl, volume);
2555 return cdo->audio_ioctl(cdi, cmd, &volume);
2556 }
2557 case CDROMVOLREAD: {
2558 struct cdrom_volctrl volume;
2559 if (!CDROM_CAN(CDC_PLAY_AUDIO))
2560 return -ENOSYS;
2561 cdinfo(CD_DO_IOCTL, "entering CDROMVOLREAD\n");
2562 if ((ret=cdo->audio_ioctl(cdi, cmd, &volume)))
2563 return ret;
2564 IOCTL_OUT(arg, struct cdrom_volctrl, volume);
2565 return 0;
2566 }
2567 case CDROMSTART:
2568 case CDROMSTOP:
2569 case CDROMPAUSE:
2570 case CDROMRESUME: {
2571 if (!CDROM_CAN(CDC_PLAY_AUDIO))
2572 return -ENOSYS;
2573 cdinfo(CD_DO_IOCTL, "doing audio ioctl (start/stop/pause/resume)\n");
2574 CHECKAUDIO;
2575 return cdo->audio_ioctl(cdi, cmd, NULL);
2576 }
2577 } /* switch */
2578
2579 /* do the device specific ioctls */
2580 if (CDROM_CAN(CDC_IOCTLS))
2581 return cdo->dev_ioctl(cdi, cmd, arg);
2582
2583 return -ENOSYS;
2584}
2585
2586static inline
2587int msf_to_lba(char m, char s, char f)
2588{
2589 return (((m * CD_SECS) + s) * CD_FRAMES + f) - CD_MSF_OFFSET;
2590}
2591
2592/*
2593 * Required when we need to use READ_10 to issue other than 2048 block
2594 * reads
2595 */
2596static int cdrom_switch_blocksize(struct cdrom_device_info *cdi, int size)
2597{
2598 struct cdrom_device_ops *cdo = cdi->ops;
2599 struct packet_command cgc;
2600 struct modesel_head mh;
2601
2602 memset(&mh, 0, sizeof(mh));
2603 mh.block_desc_length = 0x08;
2604 mh.block_length_med = (size >> 8) & 0xff;
2605 mh.block_length_lo = size & 0xff;
2606
2607 memset(&cgc, 0, sizeof(cgc));
2608 cgc.cmd[0] = 0x15;
2609 cgc.cmd[1] = 1 << 4;
2610 cgc.cmd[4] = 12;
2611 cgc.buflen = sizeof(mh);
2612 cgc.buffer = (char *) &mh;
2613 cgc.data_direction = CGC_DATA_WRITE;
2614 mh.block_desc_length = 0x08;
2615 mh.block_length_med = (size >> 8) & 0xff;
2616 mh.block_length_lo = size & 0xff;
2617
2618 return cdo->generic_packet(cdi, &cgc);
2619}
2620
2621static int mmc_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
2622 unsigned long arg)
2623{
2624 struct cdrom_device_ops *cdo = cdi->ops;
2625 struct packet_command cgc;
2626 struct request_sense sense;
2627 unsigned char buffer[32];
2628 int ret = 0;
2629
2630 memset(&cgc, 0, sizeof(cgc));
2631
2632 /* build a unified command and queue it through
2633 cdo->generic_packet() */
2634 switch (cmd) {
2635 case CDROMREADRAW:
2636 case CDROMREADMODE1:
2637 case CDROMREADMODE2: {
2638 struct cdrom_msf msf;
2639 int blocksize = 0, format = 0, lba;
2640
2641 switch (cmd) {
2642 case CDROMREADRAW:
2643 blocksize = CD_FRAMESIZE_RAW;
2644 break;
2645 case CDROMREADMODE1:
2646 blocksize = CD_FRAMESIZE;
2647 format = 2;
2648 break;
2649 case CDROMREADMODE2:
2650 blocksize = CD_FRAMESIZE_RAW0;
2651 break;
2652 }
2653 IOCTL_IN(arg, struct cdrom_msf, msf);
2654 lba = msf_to_lba(msf.cdmsf_min0,msf.cdmsf_sec0,msf.cdmsf_frame0);
2655 /* FIXME: we need upper bound checking, too!! */
2656 if (lba < 0)
2657 return -EINVAL;
2658 cgc.buffer = (char *) kmalloc(blocksize, GFP_KERNEL);
2659 if (cgc.buffer == NULL)
2660 return -ENOMEM;
2661 memset(&sense, 0, sizeof(sense));
2662 cgc.sense = &sense;
2663 cgc.data_direction = CGC_DATA_READ;
2664 ret = cdrom_read_block(cdi, &cgc, lba, 1, format, blocksize);
2665 if (ret && sense.sense_key==0x05 && sense.asc==0x20 && sense.ascq==0x00) {
2666 /*
2667 * SCSI-II devices are not required to support
2668 * READ_CD, so let's try switching block size
2669 */
2670 /* FIXME: switch back again... */
2671 if ((ret = cdrom_switch_blocksize(cdi, blocksize))) {
2672 kfree(cgc.buffer);
2673 return ret;
2674 }
2675 cgc.sense = NULL;
2676 ret = cdrom_read_cd(cdi, &cgc, lba, blocksize, 1);
2677 ret |= cdrom_switch_blocksize(cdi, blocksize);
2678 }
2679 if (!ret && copy_to_user((char __user *)arg, cgc.buffer, blocksize))
2680 ret = -EFAULT;
2681 kfree(cgc.buffer);
2682 return ret;
2683 }
2684 case CDROMREADAUDIO: {
2685 struct cdrom_read_audio ra;
2686 int lba;
2687
2688 IOCTL_IN(arg, struct cdrom_read_audio, ra);
2689
2690 if (ra.addr_format == CDROM_MSF)
2691 lba = msf_to_lba(ra.addr.msf.minute,
2692 ra.addr.msf.second,
2693 ra.addr.msf.frame);
2694 else if (ra.addr_format == CDROM_LBA)
2695 lba = ra.addr.lba;
2696 else
2697 return -EINVAL;
2698
2699 /* FIXME: we need upper bound checking, too!! */
2700 if (lba < 0 || ra.nframes <= 0 || ra.nframes > CD_FRAMES)
2701 return -EINVAL;
2702
2703 return cdrom_read_cdda(cdi, ra.buf, lba, ra.nframes);
2704 }
2705 case CDROMSUBCHNL: {
2706 struct cdrom_subchnl q;
2707 u_char requested, back;
2708 IOCTL_IN(arg, struct cdrom_subchnl, q);
2709 requested = q.cdsc_format;
2710 if (!((requested == CDROM_MSF) ||
2711 (requested == CDROM_LBA)))
2712 return -EINVAL;
2713 q.cdsc_format = CDROM_MSF;
2714 if ((ret = cdrom_read_subchannel(cdi, &q, 0)))
2715 return ret;
2716 back = q.cdsc_format; /* local copy */
2717 sanitize_format(&q.cdsc_absaddr, &back, requested);
2718 sanitize_format(&q.cdsc_reladdr, &q.cdsc_format, requested);
2719 IOCTL_OUT(arg, struct cdrom_subchnl, q);
2720 /* cdinfo(CD_DO_IOCTL, "CDROMSUBCHNL successful\n"); */
2721 return 0;
2722 }
2723 case CDROMPLAYMSF: {
2724 struct cdrom_msf msf;
2725 cdinfo(CD_DO_IOCTL, "entering CDROMPLAYMSF\n");
2726 IOCTL_IN(arg, struct cdrom_msf, msf);
2727 cgc.cmd[0] = GPCMD_PLAY_AUDIO_MSF;
2728 cgc.cmd[3] = msf.cdmsf_min0;
2729 cgc.cmd[4] = msf.cdmsf_sec0;
2730 cgc.cmd[5] = msf.cdmsf_frame0;
2731 cgc.cmd[6] = msf.cdmsf_min1;
2732 cgc.cmd[7] = msf.cdmsf_sec1;
2733 cgc.cmd[8] = msf.cdmsf_frame1;
2734 cgc.data_direction = CGC_DATA_NONE;
2735 return cdo->generic_packet(cdi, &cgc);
2736 }
2737 case CDROMPLAYBLK: {
2738 struct cdrom_blk blk;
2739 cdinfo(CD_DO_IOCTL, "entering CDROMPLAYBLK\n");
2740 IOCTL_IN(arg, struct cdrom_blk, blk);
2741 cgc.cmd[0] = GPCMD_PLAY_AUDIO_10;
2742 cgc.cmd[2] = (blk.from >> 24) & 0xff;
2743 cgc.cmd[3] = (blk.from >> 16) & 0xff;
2744 cgc.cmd[4] = (blk.from >> 8) & 0xff;
2745 cgc.cmd[5] = blk.from & 0xff;
2746 cgc.cmd[7] = (blk.len >> 8) & 0xff;
2747 cgc.cmd[8] = blk.len & 0xff;
2748 cgc.data_direction = CGC_DATA_NONE;
2749 return cdo->generic_packet(cdi, &cgc);
2750 }
2751 case CDROMVOLCTRL:
2752 case CDROMVOLREAD: {
2753 struct cdrom_volctrl volctrl;
2754 char mask[sizeof(buffer)];
2755 unsigned short offset;
2756
2757 cdinfo(CD_DO_IOCTL, "entering CDROMVOLUME\n");
2758
2759 IOCTL_IN(arg, struct cdrom_volctrl, volctrl);
2760
2761 cgc.buffer = buffer;
2762 cgc.buflen = 24;
2763 if ((ret = cdrom_mode_sense(cdi, &cgc, GPMODE_AUDIO_CTL_PAGE, 0)))
2764 return ret;
2765
2766 /* originally the code depended on buffer[1] to determine
2767 how much data is available for transfer. buffer[1] is
2768 unfortunately ambigious and the only reliable way seem
2769 to be to simply skip over the block descriptor... */
2770 offset = 8 + be16_to_cpu(*(unsigned short *)(buffer+6));
2771
2772 if (offset + 16 > sizeof(buffer))
2773 return -E2BIG;
2774
2775 if (offset + 16 > cgc.buflen) {
2776 cgc.buflen = offset+16;
2777 ret = cdrom_mode_sense(cdi, &cgc,
2778 GPMODE_AUDIO_CTL_PAGE, 0);
2779 if (ret)
2780 return ret;
2781 }
2782
2783 /* sanity check */
2784 if ((buffer[offset] & 0x3f) != GPMODE_AUDIO_CTL_PAGE ||
2785 buffer[offset+1] < 14)
2786 return -EINVAL;
2787
2788 /* now we have the current volume settings. if it was only
2789 a CDROMVOLREAD, return these values */
2790 if (cmd == CDROMVOLREAD) {
2791 volctrl.channel0 = buffer[offset+9];
2792 volctrl.channel1 = buffer[offset+11];
2793 volctrl.channel2 = buffer[offset+13];
2794 volctrl.channel3 = buffer[offset+15];
2795 IOCTL_OUT(arg, struct cdrom_volctrl, volctrl);
2796 return 0;
2797 }
2798
2799 /* get the volume mask */
2800 cgc.buffer = mask;
2801 if ((ret = cdrom_mode_sense(cdi, &cgc,
2802 GPMODE_AUDIO_CTL_PAGE, 1)))
2803 return ret;
2804
2805 buffer[offset+9] = volctrl.channel0 & mask[offset+9];
2806 buffer[offset+11] = volctrl.channel1 & mask[offset+11];
2807 buffer[offset+13] = volctrl.channel2 & mask[offset+13];
2808 buffer[offset+15] = volctrl.channel3 & mask[offset+15];
2809
2810 /* set volume */
2811 cgc.buffer = buffer + offset - 8;
2812 memset(cgc.buffer, 0, 8);
2813 return cdrom_mode_select(cdi, &cgc);
2814 }
2815
2816 case CDROMSTART:
2817 case CDROMSTOP: {
2818 cdinfo(CD_DO_IOCTL, "entering CDROMSTART/CDROMSTOP\n");
2819 cgc.cmd[0] = GPCMD_START_STOP_UNIT;
2820 cgc.cmd[1] = 1;
2821 cgc.cmd[4] = (cmd == CDROMSTART) ? 1 : 0;
2822 cgc.data_direction = CGC_DATA_NONE;
2823 return cdo->generic_packet(cdi, &cgc);
2824 }
2825
2826 case CDROMPAUSE:
2827 case CDROMRESUME: {
2828 cdinfo(CD_DO_IOCTL, "entering CDROMPAUSE/CDROMRESUME\n");
2829 cgc.cmd[0] = GPCMD_PAUSE_RESUME;
2830 cgc.cmd[8] = (cmd == CDROMRESUME) ? 1 : 0;
2831 cgc.data_direction = CGC_DATA_NONE;
2832 return cdo->generic_packet(cdi, &cgc);
2833 }
2834
2835 case DVD_READ_STRUCT: {
2836 dvd_struct *s;
2837 int size = sizeof(dvd_struct);
2838 if (!CDROM_CAN(CDC_DVD))
2839 return -ENOSYS;
2840 if ((s = (dvd_struct *) kmalloc(size, GFP_KERNEL)) == NULL)
2841 return -ENOMEM;
2842 cdinfo(CD_DO_IOCTL, "entering DVD_READ_STRUCT\n");
2843 if (copy_from_user(s, (dvd_struct __user *)arg, size)) {
2844 kfree(s);
2845 return -EFAULT;
2846 }
2847 if ((ret = dvd_read_struct(cdi, s))) {
2848 kfree(s);
2849 return ret;
2850 }
2851 if (copy_to_user((dvd_struct __user *)arg, s, size))
2852 ret = -EFAULT;
2853 kfree(s);
2854 return ret;
2855 }
2856
2857 case DVD_AUTH: {
2858 dvd_authinfo ai;
2859 if (!CDROM_CAN(CDC_DVD))
2860 return -ENOSYS;
2861 cdinfo(CD_DO_IOCTL, "entering DVD_AUTH\n");
2862 IOCTL_IN(arg, dvd_authinfo, ai);
2863 if ((ret = dvd_do_auth (cdi, &ai)))
2864 return ret;
2865 IOCTL_OUT(arg, dvd_authinfo, ai);
2866 return 0;
2867 }
2868
2869 case CDROM_NEXT_WRITABLE: {
2870 long next = 0;
2871 cdinfo(CD_DO_IOCTL, "entering CDROM_NEXT_WRITABLE\n");
2872 if ((ret = cdrom_get_next_writable(cdi, &next)))
2873 return ret;
2874 IOCTL_OUT(arg, long, next);
2875 return 0;
2876 }
2877 case CDROM_LAST_WRITTEN: {
2878 long last = 0;
2879 cdinfo(CD_DO_IOCTL, "entering CDROM_LAST_WRITTEN\n");
2880 if ((ret = cdrom_get_last_written(cdi, &last)))
2881 return ret;
2882 IOCTL_OUT(arg, long, last);
2883 return 0;
2884 }
2885 } /* switch */
2886
2887 return -ENOTTY;
2888}
2889
2890static int cdrom_get_track_info(struct cdrom_device_info *cdi, __u16 track, __u8 type,
2891 track_information *ti)
2892{
2893 struct cdrom_device_ops *cdo = cdi->ops;
2894 struct packet_command cgc;
2895 int ret, buflen;
2896
2897 init_cdrom_command(&cgc, ti, 8, CGC_DATA_READ);
2898 cgc.cmd[0] = GPCMD_READ_TRACK_RZONE_INFO;
2899 cgc.cmd[1] = type & 3;
2900 cgc.cmd[4] = (track & 0xff00) >> 8;
2901 cgc.cmd[5] = track & 0xff;
2902 cgc.cmd[8] = 8;
2903 cgc.quiet = 1;
2904
2905 if ((ret = cdo->generic_packet(cdi, &cgc)))
2906 return ret;
2907
2908 buflen = be16_to_cpu(ti->track_information_length) +
2909 sizeof(ti->track_information_length);
2910
2911 if (buflen > sizeof(track_information))
2912 buflen = sizeof(track_information);
2913
2914 cgc.cmd[8] = cgc.buflen = buflen;
2915 if ((ret = cdo->generic_packet(cdi, &cgc)))
2916 return ret;
2917
2918 /* return actual fill size */
2919 return buflen;
2920}
2921
2922/* requires CD R/RW */
2923static int cdrom_get_disc_info(struct cdrom_device_info *cdi, disc_information *di)
2924{
2925 struct cdrom_device_ops *cdo = cdi->ops;
2926 struct packet_command cgc;
2927 int ret, buflen;
2928
2929 /* set up command and get the disc info */
2930 init_cdrom_command(&cgc, di, sizeof(*di), CGC_DATA_READ);
2931 cgc.cmd[0] = GPCMD_READ_DISC_INFO;
2932 cgc.cmd[8] = cgc.buflen = 2;
2933 cgc.quiet = 1;
2934
2935 if ((ret = cdo->generic_packet(cdi, &cgc)))
2936 return ret;
2937
2938 /* not all drives have the same disc_info length, so requeue
2939 * packet with the length the drive tells us it can supply
2940 */
2941 buflen = be16_to_cpu(di->disc_information_length) +
2942 sizeof(di->disc_information_length);
2943
2944 if (buflen > sizeof(disc_information))
2945 buflen = sizeof(disc_information);
2946
2947 cgc.cmd[8] = cgc.buflen = buflen;
2948 if ((ret = cdo->generic_packet(cdi, &cgc)))
2949 return ret;
2950
2951 /* return actual fill size */
2952 return buflen;
2953}
2954
2955/* return the last written block on the CD-R media. this is for the udf
2956 file system. */
2957int cdrom_get_last_written(struct cdrom_device_info *cdi, long *last_written)
2958{
2959 struct cdrom_tocentry toc;
2960 disc_information di;
2961 track_information ti;
2962 __u32 last_track;
2963 int ret = -1, ti_size;
2964
2965 if (!CDROM_CAN(CDC_GENERIC_PACKET))
2966 goto use_toc;
2967
2968 ret = cdrom_get_disc_info(cdi, &di);
2969 if (ret < (int)(offsetof(typeof(di), last_track_lsb)
2970 + sizeof(di.last_track_lsb)))
2971 goto use_toc;
2972
2973 /* if unit didn't return msb, it's zeroed by cdrom_get_disc_info */
2974 last_track = (di.last_track_msb << 8) | di.last_track_lsb;
2975 ti_size = cdrom_get_track_info(cdi, last_track, 1, &ti);
2976 if (ti_size < (int)offsetof(typeof(ti), track_start))
2977 goto use_toc;
2978
2979 /* if this track is blank, try the previous. */
2980 if (ti.blank) {
2981 if (last_track==1)
2982 goto use_toc;
2983 last_track--;
2984 ti_size = cdrom_get_track_info(cdi, last_track, 1, &ti);
2985 }
2986
2987 if (ti_size < (int)(offsetof(typeof(ti), track_size)
2988 + sizeof(ti.track_size)))
2989 goto use_toc;
2990
2991 /* if last recorded field is valid, return it. */
2992 if (ti.lra_v && ti_size >= (int)(offsetof(typeof(ti), last_rec_address)
2993 + sizeof(ti.last_rec_address))) {
2994 *last_written = be32_to_cpu(ti.last_rec_address);
2995 } else {
2996 /* make it up instead */
2997 *last_written = be32_to_cpu(ti.track_start) +
2998 be32_to_cpu(ti.track_size);
2999 if (ti.free_blocks)
3000 *last_written -= (be32_to_cpu(ti.free_blocks) + 7);
3001 }
3002 return 0;
3003
3004 /* this is where we end up if the drive either can't do a
3005 GPCMD_READ_DISC_INFO or GPCMD_READ_TRACK_RZONE_INFO or if
3006 it doesn't give enough information or fails. then we return
3007 the toc contents. */
3008use_toc:
3009 toc.cdte_format = CDROM_MSF;
3010 toc.cdte_track = CDROM_LEADOUT;
3011 if ((ret = cdi->ops->audio_ioctl(cdi, CDROMREADTOCENTRY, &toc)))
3012 return ret;
3013 sanitize_format(&toc.cdte_addr, &toc.cdte_format, CDROM_LBA);
3014 *last_written = toc.cdte_addr.lba;
3015 return 0;
3016}
3017
3018/* return the next writable block. also for udf file system. */
3019static int cdrom_get_next_writable(struct cdrom_device_info *cdi, long *next_writable)
3020{
3021 disc_information di;
3022 track_information ti;
3023 __u16 last_track;
3024 int ret, ti_size;
3025
3026 if (!CDROM_CAN(CDC_GENERIC_PACKET))
3027 goto use_last_written;
3028
3029 ret = cdrom_get_disc_info(cdi, &di);
3030 if (ret < 0 || ret < offsetof(typeof(di), last_track_lsb)
3031 + sizeof(di.last_track_lsb))
3032 goto use_last_written;
3033
3034 /* if unit didn't return msb, it's zeroed by cdrom_get_disc_info */
3035 last_track = (di.last_track_msb << 8) | di.last_track_lsb;
3036 ti_size = cdrom_get_track_info(cdi, last_track, 1, &ti);
3037 if (ti_size < 0 || ti_size < offsetof(typeof(ti), track_start))
3038 goto use_last_written;
3039
3040 /* if this track is blank, try the previous. */
3041 if (ti.blank) {
3042 if (last_track == 1)
3043 goto use_last_written;
3044 last_track--;
3045 ti_size = cdrom_get_track_info(cdi, last_track, 1, &ti);
3046 if (ti_size < 0)
3047 goto use_last_written;
3048 }
3049
3050 /* if next recordable address field is valid, use it. */
3051 if (ti.nwa_v && ti_size >= offsetof(typeof(ti), next_writable)
3052 + sizeof(ti.next_writable)) {
3053 *next_writable = be32_to_cpu(ti.next_writable);
3054 return 0;
3055 }
3056
3057use_last_written:
3058 if ((ret = cdrom_get_last_written(cdi, next_writable))) {
3059 *next_writable = 0;
3060 return ret;
3061 } else {
3062 *next_writable += 7;
3063 return 0;
3064 }
3065}
3066
3067EXPORT_SYMBOL(cdrom_get_last_written);
3068EXPORT_SYMBOL(register_cdrom);
3069EXPORT_SYMBOL(unregister_cdrom);
3070EXPORT_SYMBOL(cdrom_open);
3071EXPORT_SYMBOL(cdrom_release);
3072EXPORT_SYMBOL(cdrom_ioctl);
3073EXPORT_SYMBOL(cdrom_media_changed);
3074EXPORT_SYMBOL(cdrom_number_of_slots);
3075EXPORT_SYMBOL(cdrom_mode_select);
3076EXPORT_SYMBOL(cdrom_mode_sense);
3077EXPORT_SYMBOL(init_cdrom_command);
3078EXPORT_SYMBOL(cdrom_get_media_event);
3079
3080#ifdef CONFIG_SYSCTL
3081
3082#define CDROM_STR_SIZE 1000
3083
3084static struct cdrom_sysctl_settings {
3085 char info[CDROM_STR_SIZE]; /* general info */
3086 int autoclose; /* close tray upon mount, etc */
3087 int autoeject; /* eject on umount */
3088 int debug; /* turn on debugging messages */
3089 int lock; /* lock the door on device open */
3090 int check; /* check media type */
3091} cdrom_sysctl_settings;
3092
3093static int cdrom_sysctl_info(ctl_table *ctl, int write, struct file * filp,
3094 void __user *buffer, size_t *lenp, loff_t *ppos)
3095{
3096 int pos;
3097 struct cdrom_device_info *cdi;
3098 char *info = cdrom_sysctl_settings.info;
3099
3100 if (!*lenp || (*ppos && !write)) {
3101 *lenp = 0;
3102 return 0;
3103 }
3104
3105 pos = sprintf(info, "CD-ROM information, " VERSION "\n");
3106
3107 pos += sprintf(info+pos, "\ndrive name:\t");
3108 for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
3109 pos += sprintf(info+pos, "\t%s", cdi->name);
3110
3111 pos += sprintf(info+pos, "\ndrive speed:\t");
3112 for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
3113 pos += sprintf(info+pos, "\t%d", cdi->speed);
3114
3115 pos += sprintf(info+pos, "\ndrive # of slots:");
3116 for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
3117 pos += sprintf(info+pos, "\t%d", cdi->capacity);
3118
3119 pos += sprintf(info+pos, "\nCan close tray:\t");
3120 for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
3121 pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_CLOSE_TRAY) != 0);
3122
3123 pos += sprintf(info+pos, "\nCan open tray:\t");
3124 for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
3125 pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_OPEN_TRAY) != 0);
3126
3127 pos += sprintf(info+pos, "\nCan lock tray:\t");
3128 for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
3129 pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_LOCK) != 0);
3130
3131 pos += sprintf(info+pos, "\nCan change speed:");
3132 for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
3133 pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_SELECT_SPEED) != 0);
3134
3135 pos += sprintf(info+pos, "\nCan select disk:");
3136 for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
3137 pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_SELECT_DISC) != 0);
3138
3139 pos += sprintf(info+pos, "\nCan read multisession:");
3140 for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
3141 pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_MULTI_SESSION) != 0);
3142
3143 pos += sprintf(info+pos, "\nCan read MCN:\t");
3144 for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
3145 pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_MCN) != 0);
3146
3147 pos += sprintf(info+pos, "\nReports media changed:");
3148 for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
3149 pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_MEDIA_CHANGED) != 0);
3150
3151 pos += sprintf(info+pos, "\nCan play audio:\t");
3152 for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
3153 pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_PLAY_AUDIO) != 0);
3154
3155 pos += sprintf(info+pos, "\nCan write CD-R:\t");
3156 for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
3157 pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_CD_R) != 0);
3158
3159 pos += sprintf(info+pos, "\nCan write CD-RW:");
3160 for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
3161 pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_CD_RW) != 0);
3162
3163 pos += sprintf(info+pos, "\nCan read DVD:\t");
3164 for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
3165 pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_DVD) != 0);
3166
3167 pos += sprintf(info+pos, "\nCan write DVD-R:");
3168 for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
3169 pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_DVD_R) != 0);
3170
3171 pos += sprintf(info+pos, "\nCan write DVD-RAM:");
3172 for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
3173 pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_DVD_RAM) != 0);
3174
3175 pos += sprintf(info+pos, "\nCan read MRW:\t");
3176 for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
3177 pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_MRW) != 0);
3178
3179 pos += sprintf(info+pos, "\nCan write MRW:\t");
3180 for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
3181 pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_MRW_W) != 0);
3182
3183 pos += sprintf(info+pos, "\nCan write RAM:\t");
3184 for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
3185 pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_RAM) != 0);
3186
3187 strcpy(info+pos,"\n\n");
3188
3189 return proc_dostring(ctl, write, filp, buffer, lenp, ppos);
3190}
3191
3192/* Unfortunately, per device settings are not implemented through
3193 procfs/sysctl yet. When they are, this will naturally disappear. For now
3194 just update all drives. Later this will become the template on which
3195 new registered drives will be based. */
3196static void cdrom_update_settings(void)
3197{
3198 struct cdrom_device_info *cdi;
3199
3200 for (cdi = topCdromPtr; cdi != NULL; cdi = cdi->next) {
3201 if (autoclose && CDROM_CAN(CDC_CLOSE_TRAY))
3202 cdi->options |= CDO_AUTO_CLOSE;
3203 else if (!autoclose)
3204 cdi->options &= ~CDO_AUTO_CLOSE;
3205 if (autoeject && CDROM_CAN(CDC_OPEN_TRAY))
3206 cdi->options |= CDO_AUTO_EJECT;
3207 else if (!autoeject)
3208 cdi->options &= ~CDO_AUTO_EJECT;
3209 if (lockdoor && CDROM_CAN(CDC_LOCK))
3210 cdi->options |= CDO_LOCK;
3211 else if (!lockdoor)
3212 cdi->options &= ~CDO_LOCK;
3213 if (check_media_type)
3214 cdi->options |= CDO_CHECK_TYPE;
3215 else
3216 cdi->options &= ~CDO_CHECK_TYPE;
3217 }
3218}
3219
3220static int cdrom_sysctl_handler(ctl_table *ctl, int write, struct file * filp,
3221 void __user *buffer, size_t *lenp, loff_t *ppos)
3222{
3223 int *valp = ctl->data;
3224 int val = *valp;
3225 int ret;
3226
3227 ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos);
3228
3229 if (write && *valp != val) {
3230
3231 /* we only care for 1 or 0. */
3232 if (*valp)
3233 *valp = 1;
3234 else
3235 *valp = 0;
3236
3237 switch (ctl->ctl_name) {
3238 case DEV_CDROM_AUTOCLOSE: {
3239 if (valp == &cdrom_sysctl_settings.autoclose)
3240 autoclose = cdrom_sysctl_settings.autoclose;
3241 break;
3242 }
3243 case DEV_CDROM_AUTOEJECT: {
3244 if (valp == &cdrom_sysctl_settings.autoeject)
3245 autoeject = cdrom_sysctl_settings.autoeject;
3246 break;
3247 }
3248 case DEV_CDROM_DEBUG: {
3249 if (valp == &cdrom_sysctl_settings.debug)
3250 debug = cdrom_sysctl_settings.debug;
3251 break;
3252 }
3253 case DEV_CDROM_LOCK: {
3254 if (valp == &cdrom_sysctl_settings.lock)
3255 lockdoor = cdrom_sysctl_settings.lock;
3256 break;
3257 }
3258 case DEV_CDROM_CHECK_MEDIA: {
3259 if (valp == &cdrom_sysctl_settings.check)
3260 check_media_type = cdrom_sysctl_settings.check;
3261 break;
3262 }
3263 }
3264 /* update the option flags according to the changes. we
3265 don't have per device options through sysctl yet,
3266 but we will have and then this will disappear. */
3267 cdrom_update_settings();
3268 }
3269
3270 return ret;
3271}
3272
3273/* Place files in /proc/sys/dev/cdrom */
3274static ctl_table cdrom_table[] = {
3275 {
3276 .ctl_name = DEV_CDROM_INFO,
3277 .procname = "info",
3278 .data = &cdrom_sysctl_settings.info,
3279 .maxlen = CDROM_STR_SIZE,
3280 .mode = 0444,
3281 .proc_handler = &cdrom_sysctl_info,
3282 },
3283 {
3284 .ctl_name = DEV_CDROM_AUTOCLOSE,
3285 .procname = "autoclose",
3286 .data = &cdrom_sysctl_settings.autoclose,
3287 .maxlen = sizeof(int),
3288 .mode = 0644,
3289 .proc_handler = &cdrom_sysctl_handler,
3290 },
3291 {
3292 .ctl_name = DEV_CDROM_AUTOEJECT,
3293 .procname = "autoeject",
3294 .data = &cdrom_sysctl_settings.autoeject,
3295 .maxlen = sizeof(int),
3296 .mode = 0644,
3297 .proc_handler = &cdrom_sysctl_handler,
3298 },
3299 {
3300 .ctl_name = DEV_CDROM_DEBUG,
3301 .procname = "debug",
3302 .data = &cdrom_sysctl_settings.debug,
3303 .maxlen = sizeof(int),
3304 .mode = 0644,
3305 .proc_handler = &cdrom_sysctl_handler,
3306 },
3307 {
3308 .ctl_name = DEV_CDROM_LOCK,
3309 .procname = "lock",
3310 .data = &cdrom_sysctl_settings.lock,
3311 .maxlen = sizeof(int),
3312 .mode = 0644,
3313 .proc_handler = &cdrom_sysctl_handler,
3314 },
3315 {
3316 .ctl_name = DEV_CDROM_CHECK_MEDIA,
3317 .procname = "check_media",
3318 .data = &cdrom_sysctl_settings.check,
3319 .maxlen = sizeof(int),
3320 .mode = 0644,
3321 .proc_handler = &cdrom_sysctl_handler
3322 },
3323 { .ctl_name = 0 }
3324};
3325
3326static ctl_table cdrom_cdrom_table[] = {
3327 {
3328 .ctl_name = DEV_CDROM,
3329 .procname = "cdrom",
3330 .maxlen = 0,
3331 .mode = 0555,
3332 .child = cdrom_table,
3333 },
3334 { .ctl_name = 0 }
3335};
3336
3337/* Make sure that /proc/sys/dev is there */
3338static ctl_table cdrom_root_table[] = {
3339 {
3340 .ctl_name = CTL_DEV,
3341 .procname = "dev",
3342 .maxlen = 0,
3343 .mode = 0555,
3344 .child = cdrom_cdrom_table,
3345 },
3346 { .ctl_name = 0 }
3347};
3348static struct ctl_table_header *cdrom_sysctl_header;
3349
3350static void cdrom_sysctl_register(void)
3351{
3352 static int initialized;
3353
3354 if (initialized == 1)
3355 return;
3356
3357 cdrom_sysctl_header = register_sysctl_table(cdrom_root_table, 1);
3358 if (cdrom_root_table->ctl_name && cdrom_root_table->child->de)
3359 cdrom_root_table->child->de->owner = THIS_MODULE;
3360
3361 /* set the defaults */
3362 cdrom_sysctl_settings.autoclose = autoclose;
3363 cdrom_sysctl_settings.autoeject = autoeject;
3364 cdrom_sysctl_settings.debug = debug;
3365 cdrom_sysctl_settings.lock = lockdoor;
3366 cdrom_sysctl_settings.check = check_media_type;
3367
3368 initialized = 1;
3369}
3370
3371static void cdrom_sysctl_unregister(void)
3372{
3373 if (cdrom_sysctl_header)
3374 unregister_sysctl_table(cdrom_sysctl_header);
3375}
3376
3377#endif /* CONFIG_SYSCTL */
3378
3379static int __init cdrom_init(void)
3380{
3381#ifdef CONFIG_SYSCTL
3382 cdrom_sysctl_register();
3383#endif
3384 return 0;
3385}
3386
3387static void __exit cdrom_exit(void)
3388{
3389 printk(KERN_INFO "Uniform CD-ROM driver unloaded\n");
3390#ifdef CONFIG_SYSCTL
3391 cdrom_sysctl_unregister();
3392#endif
3393}
3394
3395module_init(cdrom_init);
3396module_exit(cdrom_exit);
3397MODULE_LICENSE("GPL");
diff --git a/drivers/cdrom/cdu31a.c b/drivers/cdrom/cdu31a.c
new file mode 100644
index 000000000000..647a71b12a2a
--- /dev/null
+++ b/drivers/cdrom/cdu31a.c
@@ -0,0 +1,3248 @@
1/*
2* Sony CDU-31A CDROM interface device driver.
3*
4* Corey Minyard (minyard@wf-rch.cirr.com)
5*
6* Colossians 3:17
7*
8* See Documentation/cdrom/cdu31a for additional details about this driver.
9*
10* The Sony interface device driver handles Sony interface CDROM
11* drives and provides a complete block-level interface as well as an
12* ioctl() interface compatible with the Sun (as specified in
13* include/linux/cdrom.h). With this interface, CDROMs can be
14* accessed and standard audio CDs can be played back normally.
15*
16* WARNING - All autoprobes have been removed from the driver.
17* You MUST configure the CDU31A via a LILO config
18* at boot time or in lilo.conf. I have the
19* following in my lilo.conf:
20*
21* append="cdu31a=0x1f88,0,PAS"
22*
23* The first number is the I/O base address of the
24* card. The second is the interrupt (0 means none).
25 * The third should be "PAS" if on a Pro-Audio
26 * spectrum, or nothing if on something else.
27 *
28 * This interface is (unfortunately) a polled interface. This is
29 * because most Sony interfaces are set up with DMA and interrupts
30 * disables. Some (like mine) do not even have the capability to
31 * handle interrupts or DMA. For this reason you will see a lot of
32 * the following:
33 *
34 * retry_count = jiffies+ SONY_JIFFIES_TIMEOUT;
35 * while (time_before(jiffies, retry_count) && (! <some condition to wait for))
36 * {
37 * while (handle_sony_cd_attention())
38 * ;
39 *
40 * sony_sleep();
41 * }
42 * if (the condition not met)
43 * {
44 * return an error;
45 * }
46 *
47 * This ugly hack waits for something to happen, sleeping a little
48 * between every try. it also handles attentions, which are
49 * asynchronous events from the drive informing the driver that a disk
50 * has been inserted, removed, etc.
51 *
52 * NEWS FLASH - The driver now supports interrupts but they are
53 * turned off by default. Use of interrupts is highly encouraged, it
54 * cuts CPU usage down to a reasonable level. I had DMA in for a while
55 * but PC DMA is just too slow. Better to just insb() it.
56 *
57 * One thing about these drives: They talk in MSF (Minute Second Frame) format.
58 * There are 75 frames a second, 60 seconds a minute, and up to 75 minutes on a
59 * disk. The funny thing is that these are sent to the drive in BCD, but the
60 * interface wants to see them in decimal. A lot of conversion goes on.
61 *
62 * DRIVER SPECIAL FEATURES
63 * -----------------------
64 *
65 * This section describes features beyond the normal audio and CD-ROM
66 * functions of the drive.
67 *
68 * XA compatibility
69 *
70 * The driver should support XA disks for both the CDU31A and CDU33A.
71 * It does this transparently, the using program doesn't need to set it.
72 *
73 * Multi-Session
74 *
75 * A multi-session disk looks just like a normal disk to the user.
76 * Just mount one normally, and all the data should be there.
77 * A special thanks to Koen for help with this!
78 *
79 * Raw sector I/O
80 *
81 * Using the CDROMREADAUDIO it is possible to read raw audio and data
82 * tracks. Both operations return 2352 bytes per sector. On the data
83 * tracks, the first 12 bytes is not returned by the drive and the value
84 * of that data is indeterminate.
85 *
86 *
87 * Copyright (C) 1993 Corey Minyard
88 *
89 * This program is free software; you can redistribute it and/or modify
90 * it under the terms of the GNU General Public License as published by
91 * the Free Software Foundation; either version 2 of the License, or
92 * (at your option) any later version.
93 *
94 * This program is distributed in the hope that it will be useful,
95 * but WITHOUT ANY WARRANTY; without even the implied warranty of
96 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
97 * GNU General Public License for more details.
98 *
99 * You should have received a copy of the GNU General Public License
100 * along with this program; if not, write to the Free Software
101 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
102 *
103 * TODO:
104 * CDs with form1 and form2 sectors cause problems
105 * with current read-ahead strategy.
106 *
107 * Credits:
108 * Heiko Eissfeldt <heiko@colossus.escape.de>
109 * For finding abug in the return of the track numbers.
110 * TOC processing redone for proper multisession support.
111 *
112 *
113 * It probably a little late to be adding a history, but I guess I
114 * will start.
115 *
116 * 10/24/95 - Added support for disabling the eject button when the
117 * drive is open. Note that there is a small problem
118 * still here, if the eject button is pushed while the
119 * drive light is flashing, the drive will return a bad
120 * status and be reset. It recovers, though.
121 *
122 * 03/07/97 - Fixed a problem with timers.
123 *
124 *
125 * 18 Spetember 1997 -- Ported to Uniform CD-ROM driver by
126 * Heiko Eissfeldt <heiko@colossus.escape.de> with additional
127 * changes by Erik Andersen <andersee@debian.org>
128 *
129 * 24 January 1998 -- Removed the scd_disc_status() function, which was now
130 * just dead code left over from the port.
131 * Erik Andersen <andersee@debian.org>
132 *
133 * 16 July 1998 -- Drive donated to Erik Andersen by John Kodis
134 * <kodis@jagunet.com>. Work begun on fixing driver to
135 * work under 2.1.X. Added temporary extra printks
136 * which seem to slow it down enough to work.
137 *
138 * 9 November 1999 -- Make kernel-parameter implementation work with 2.3.x
139 * Removed init_module & cleanup_module in favor of
140 * module_init & module_exit.
141 * Torben Mathiasen <tmm@image.dk>
142 *
143 * 22 October 2004 -- Make the driver work in 2.6.X
144 * Added workaround to fix hard lockups on eject
145 * Fixed door locking problem after mounting empty drive
146 * Set double-speed drives to double speed by default
147 * Removed all readahead things - not needed anymore
148 * Ondrej Zary <rainbow@rainbow-software.org>
149*/
150
151#define DEBUG 1
152
153#include <linux/major.h>
154#include <linux/module.h>
155#include <linux/errno.h>
156#include <linux/signal.h>
157#include <linux/sched.h>
158#include <linux/timer.h>
159#include <linux/fs.h>
160#include <linux/kernel.h>
161#include <linux/hdreg.h>
162#include <linux/genhd.h>
163#include <linux/ioport.h>
164#include <linux/devfs_fs_kernel.h>
165#include <linux/string.h>
166#include <linux/slab.h>
167#include <linux/init.h>
168#include <linux/interrupt.h>
169#include <linux/cdrom.h>
170
171#include <asm/system.h>
172#include <asm/io.h>
173#include <asm/uaccess.h>
174#include <asm/dma.h>
175
176#include "cdu31a.h"
177
178#define MAJOR_NR CDU31A_CDROM_MAJOR
179#include <linux/blkdev.h>
180
181#define CDU31A_MAX_CONSECUTIVE_ATTENTIONS 10
182
183#define PFX "CDU31A: "
184
185/*
186** Edit the following data to change interrupts, DMA channels, etc.
187** Default is polled and no DMA. DMA is not recommended for double-speed
188** drives.
189*/
190static struct {
191 unsigned short base; /* I/O Base Address */
192 short int_num; /* Interrupt Number (-1 means scan for it,
193 0 means don't use) */
194} cdu31a_addresses[] __initdata = {
195 {0}
196};
197
198static int handle_sony_cd_attention(void);
199static int read_subcode(void);
200static void sony_get_toc(void);
201static int scd_spinup(void);
202/*static int scd_open(struct inode *inode, struct file *filp);*/
203static int scd_open(struct cdrom_device_info *, int);
204static void do_sony_cd_cmd(unsigned char cmd,
205 unsigned char *params,
206 unsigned int num_params,
207 unsigned char *result_buffer,
208 unsigned int *result_size);
209static void size_to_buf(unsigned int size, unsigned char *buf);
210
211/* Parameters for the read-ahead. */
212static unsigned int sony_next_block; /* Next 512 byte block offset */
213static unsigned int sony_blocks_left = 0; /* Number of 512 byte blocks left
214 in the current read command. */
215
216
217/* The base I/O address of the Sony Interface. This is a variable (not a
218 #define) so it can be easily changed via some future ioctl() */
219static unsigned int cdu31a_port = 0;
220module_param(cdu31a_port, uint, 0);
221
222/*
223 * The following are I/O addresses of the various registers for the drive. The
224 * comment for the base address also applies here.
225 */
226static volatile unsigned short sony_cd_cmd_reg;
227static volatile unsigned short sony_cd_param_reg;
228static volatile unsigned short sony_cd_write_reg;
229static volatile unsigned short sony_cd_control_reg;
230static volatile unsigned short sony_cd_status_reg;
231static volatile unsigned short sony_cd_result_reg;
232static volatile unsigned short sony_cd_read_reg;
233static volatile unsigned short sony_cd_fifost_reg;
234
235static struct request_queue *cdu31a_queue;
236static DEFINE_SPINLOCK(cdu31a_lock); /* queue lock */
237
238static int sony_spun_up = 0; /* Has the drive been spun up? */
239
240static int sony_speed = 0; /* Last wanted speed */
241
242static int sony_xa_mode = 0; /* Is an XA disk in the drive
243 and the drive a CDU31A? */
244
245static int sony_raw_data_mode = 1; /* 1 if data tracks, 0 if audio.
246 For raw data reads. */
247
248static unsigned int sony_usage = 0; /* How many processes have the
249 drive open. */
250
251static int sony_pas_init = 0; /* Initialize the Pro-Audio
252 Spectrum card? */
253
254static struct s_sony_session_toc single_toc; /* Holds the
255 table of
256 contents. */
257
258static struct s_all_sessions_toc sony_toc; /* entries gathered from all
259 sessions */
260
261static int sony_toc_read = 0; /* Has the TOC been read for
262 the drive? */
263
264static struct s_sony_subcode last_sony_subcode; /* Points to the last
265 subcode address read */
266
267static DECLARE_MUTEX(sony_sem); /* Semaphore for drive hardware access */
268
269static int is_double_speed = 0; /* does the drive support double speed ? */
270
271static int is_auto_eject = 1; /* Door has been locked? 1=No/0=Yes */
272
273/*
274 * The audio status uses the values from read subchannel data as specified
275 * in include/linux/cdrom.h.
276 */
277static volatile int sony_audio_status = CDROM_AUDIO_NO_STATUS;
278
279/*
280 * The following are a hack for pausing and resuming audio play. The drive
281 * does not work as I would expect it, if you stop it then start it again,
282 * the drive seeks back to the beginning and starts over. This holds the
283 * position during a pause so a resume can restart it. It uses the
284 * audio status variable above to tell if it is paused.
285 */
286static unsigned volatile char cur_pos_msf[3] = { 0, 0, 0 };
287static unsigned volatile char final_pos_msf[3] = { 0, 0, 0 };
288
289/* What IRQ is the drive using? 0 if none. */
290static int cdu31a_irq = 0;
291module_param(cdu31a_irq, int, 0);
292
293/* The interrupt handler will wake this queue up when it gets an
294 interrupts. */
295DECLARE_WAIT_QUEUE_HEAD(cdu31a_irq_wait);
296static int irq_flag = 0;
297
298static int curr_control_reg = 0; /* Current value of the control register */
299
300/* A disk changed variable. When a disk change is detected, it will
301 all be set to TRUE. As the upper layers ask for disk_changed status
302 it will be cleared. */
303static char disk_changed;
304
305/* This was readahead_buffer once... Now it's used only for audio reads */
306static char audio_buffer[CD_FRAMESIZE_RAW];
307
308/* Used to time a short period to abort an operation after the
309 drive has been idle for a while. This keeps the light on
310 the drive from flashing for very long. */
311static struct timer_list cdu31a_abort_timer;
312
313/* Marks if the timeout has started an abort read. This is used
314 on entry to the drive to tell the code to read out the status
315 from the abort read. */
316static int abort_read_started = 0;
317
318/*
319 * Uniform cdrom interface function
320 * report back, if disc has changed from time of last request.
321 */
322static int scd_media_changed(struct cdrom_device_info *cdi, int disc_nr)
323{
324 int retval;
325
326 retval = disk_changed;
327 disk_changed = 0;
328
329 return retval;
330}
331
332/*
333 * Uniform cdrom interface function
334 * report back, if drive is ready
335 */
336static int scd_drive_status(struct cdrom_device_info *cdi, int slot_nr)
337{
338 if (CDSL_CURRENT != slot_nr)
339 /* we have no changer support */
340 return -EINVAL;
341 if (sony_spun_up)
342 return CDS_DISC_OK;
343 if (down_interruptible(&sony_sem))
344 return -ERESTARTSYS;
345 if (scd_spinup() == 0)
346 sony_spun_up = 1;
347 up(&sony_sem);
348 return sony_spun_up ? CDS_DISC_OK : CDS_DRIVE_NOT_READY;
349}
350
351static inline void enable_interrupts(void)
352{
353 curr_control_reg |= (SONY_ATTN_INT_EN_BIT
354 | SONY_RES_RDY_INT_EN_BIT
355 | SONY_DATA_RDY_INT_EN_BIT);
356 outb(curr_control_reg, sony_cd_control_reg);
357}
358
359static inline void disable_interrupts(void)
360{
361 curr_control_reg &= ~(SONY_ATTN_INT_EN_BIT
362 | SONY_RES_RDY_INT_EN_BIT
363 | SONY_DATA_RDY_INT_EN_BIT);
364 outb(curr_control_reg, sony_cd_control_reg);
365}
366
367/*
368 * Wait a little while (used for polling the drive). If in initialization,
369 * setting a timeout doesn't work, so just loop for a while.
370 */
371static inline void sony_sleep(void)
372{
373 if (cdu31a_irq <= 0) {
374 yield();
375 } else { /* Interrupt driven */
376 DEFINE_WAIT(w);
377 int first = 1;
378
379 while (1) {
380 prepare_to_wait(&cdu31a_irq_wait, &w,
381 TASK_INTERRUPTIBLE);
382 if (first) {
383 enable_interrupts();
384 first = 0;
385 }
386
387 if (irq_flag != 0)
388 break;
389 if (!signal_pending(current)) {
390 schedule();
391 continue;
392 } else
393 disable_interrupts();
394 break;
395 }
396 finish_wait(&cdu31a_irq_wait, &w);
397 irq_flag = 0;
398 }
399}
400
401
402/*
403 * The following are convenience routine to read various status and set
404 * various conditions in the drive.
405 */
406static inline int is_attention(void)
407{
408 return (inb(sony_cd_status_reg) & SONY_ATTN_BIT) != 0;
409}
410
411static inline int is_busy(void)
412{
413 return (inb(sony_cd_status_reg) & SONY_BUSY_BIT) != 0;
414}
415
416static inline int is_data_ready(void)
417{
418 return (inb(sony_cd_status_reg) & SONY_DATA_RDY_BIT) != 0;
419}
420
421static inline int is_data_requested(void)
422{
423 return (inb(sony_cd_status_reg) & SONY_DATA_REQUEST_BIT) != 0;
424}
425
426static inline int is_result_ready(void)
427{
428 return (inb(sony_cd_status_reg) & SONY_RES_RDY_BIT) != 0;
429}
430
431static inline int is_param_write_rdy(void)
432{
433 return (inb(sony_cd_fifost_reg) & SONY_PARAM_WRITE_RDY_BIT) != 0;
434}
435
436static inline int is_result_reg_not_empty(void)
437{
438 return (inb(sony_cd_fifost_reg) & SONY_RES_REG_NOT_EMP_BIT) != 0;
439}
440
441static inline void reset_drive(void)
442{
443 curr_control_reg = 0;
444 sony_toc_read = 0;
445 outb(SONY_DRIVE_RESET_BIT, sony_cd_control_reg);
446}
447
448/*
449 * Uniform cdrom interface function
450 * reset drive and return when it is ready
451 */
452static int scd_reset(struct cdrom_device_info *cdi)
453{
454 unsigned long retry_count;
455
456 if (down_interruptible(&sony_sem))
457 return -ERESTARTSYS;
458 reset_drive();
459
460 retry_count = jiffies + SONY_RESET_TIMEOUT;
461 while (time_before(jiffies, retry_count) && (!is_attention())) {
462 sony_sleep();
463 }
464
465 up(&sony_sem);
466 return 0;
467}
468
469static inline void clear_attention(void)
470{
471 outb(curr_control_reg | SONY_ATTN_CLR_BIT, sony_cd_control_reg);
472}
473
474static inline void clear_result_ready(void)
475{
476 outb(curr_control_reg | SONY_RES_RDY_CLR_BIT, sony_cd_control_reg);
477}
478
479static inline void clear_data_ready(void)
480{
481 outb(curr_control_reg | SONY_DATA_RDY_CLR_BIT,
482 sony_cd_control_reg);
483}
484
485static inline void clear_param_reg(void)
486{
487 outb(curr_control_reg | SONY_PARAM_CLR_BIT, sony_cd_control_reg);
488}
489
490static inline unsigned char read_status_register(void)
491{
492 return inb(sony_cd_status_reg);
493}
494
495static inline unsigned char read_result_register(void)
496{
497 return inb(sony_cd_result_reg);
498}
499
500static inline unsigned char read_data_register(void)
501{
502 return inb(sony_cd_read_reg);
503}
504
505static inline void write_param(unsigned char param)
506{
507 outb(param, sony_cd_param_reg);
508}
509
510static inline void write_cmd(unsigned char cmd)
511{
512 outb(curr_control_reg | SONY_RES_RDY_INT_EN_BIT,
513 sony_cd_control_reg);
514 outb(cmd, sony_cd_cmd_reg);
515}
516
517static irqreturn_t cdu31a_interrupt(int irq, void *dev_id, struct pt_regs *regs)
518{
519 unsigned char val;
520
521 if (abort_read_started) {
522 /* We might be waiting for an abort to finish. Don't
523 disable interrupts yet, though, because we handle
524 this one here. */
525 /* Clear out the result registers. */
526 while (is_result_reg_not_empty()) {
527 val = read_result_register();
528 }
529 clear_data_ready();
530 clear_result_ready();
531
532 /* Clear out the data */
533 while (is_data_requested()) {
534 val = read_data_register();
535 }
536 abort_read_started = 0;
537
538 /* If something was waiting, wake it up now. */
539 if (waitqueue_active(&cdu31a_irq_wait)) {
540 disable_interrupts();
541 irq_flag = 1;
542 wake_up_interruptible(&cdu31a_irq_wait);
543 }
544 } else if (waitqueue_active(&cdu31a_irq_wait)) {
545 disable_interrupts();
546 irq_flag = 1;
547 wake_up_interruptible(&cdu31a_irq_wait);
548 } else {
549 disable_interrupts();
550 printk(KERN_NOTICE PFX
551 "Got an interrupt but nothing was waiting\n");
552 }
553 return IRQ_HANDLED;
554}
555
556/*
557 * give more verbose error messages
558 */
559static unsigned char *translate_error(unsigned char err_code)
560{
561 static unsigned char errbuf[80];
562
563 switch (err_code) {
564 case 0x10: return "illegal command ";
565 case 0x11: return "illegal parameter ";
566
567 case 0x20: return "not loaded ";
568 case 0x21: return "no disc ";
569 case 0x22: return "not spinning ";
570 case 0x23: return "spinning ";
571 case 0x25: return "spindle servo ";
572 case 0x26: return "focus servo ";
573 case 0x29: return "eject mechanism ";
574 case 0x2a: return "audio playing ";
575 case 0x2c: return "emergency eject ";
576
577 case 0x30: return "focus ";
578 case 0x31: return "frame sync ";
579 case 0x32: return "subcode address ";
580 case 0x33: return "block sync ";
581 case 0x34: return "header address ";
582
583 case 0x40: return "illegal track read ";
584 case 0x41: return "mode 0 read ";
585 case 0x42: return "illegal mode read ";
586 case 0x43: return "illegal block size read ";
587 case 0x44: return "mode read ";
588 case 0x45: return "form read ";
589 case 0x46: return "leadout read ";
590 case 0x47: return "buffer overrun ";
591
592 case 0x53: return "unrecoverable CIRC ";
593 case 0x57: return "unrecoverable LECC ";
594
595 case 0x60: return "no TOC ";
596 case 0x61: return "invalid subcode data ";
597 case 0x63: return "focus on TOC read ";
598 case 0x64: return "frame sync on TOC read ";
599 case 0x65: return "TOC data ";
600
601 case 0x70: return "hardware failure ";
602 case 0x91: return "leadin ";
603 case 0x92: return "leadout ";
604 case 0x93: return "data track ";
605 }
606 sprintf(errbuf, "unknown 0x%02x ", err_code);
607 return errbuf;
608}
609
610/*
611 * Set the drive parameters so the drive will auto-spin-up when a
612 * disk is inserted.
613 */
614static void set_drive_params(int want_doublespeed)
615{
616 unsigned char res_reg[12];
617 unsigned int res_size;
618 unsigned char params[3];
619
620
621 params[0] = SONY_SD_AUTO_SPIN_DOWN_TIME;
622 params[1] = 0x00; /* Never spin down the drive. */
623 do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
624 params, 2, res_reg, &res_size);
625 if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20)) {
626 printk(KERN_NOTICE PFX
627 "Unable to set spin-down time: 0x%2.2x\n", res_reg[1]);
628 }
629
630 params[0] = SONY_SD_MECH_CONTROL;
631 params[1] = SONY_AUTO_SPIN_UP_BIT; /* Set auto spin up */
632
633 if (is_auto_eject)
634 params[1] |= SONY_AUTO_EJECT_BIT;
635
636 if (is_double_speed && want_doublespeed) {
637 params[1] |= SONY_DOUBLE_SPEED_BIT; /* Set the drive to double speed if
638 possible */
639 }
640 do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
641 params, 2, res_reg, &res_size);
642 if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20)) {
643 printk(KERN_NOTICE PFX "Unable to set mechanical "
644 "parameters: 0x%2.2x\n", res_reg[1]);
645 }
646}
647
648/*
649 * Uniform cdrom interface function
650 * select reading speed for data access
651 */
652static int scd_select_speed(struct cdrom_device_info *cdi, int speed)
653{
654 if (speed == 0)
655 sony_speed = 1;
656 else
657 sony_speed = speed - 1;
658
659 if (down_interruptible(&sony_sem))
660 return -ERESTARTSYS;
661 set_drive_params(sony_speed);
662 up(&sony_sem);
663 return 0;
664}
665
666/*
667 * Uniform cdrom interface function
668 * lock or unlock eject button
669 */
670static int scd_lock_door(struct cdrom_device_info *cdi, int lock)
671{
672 if (lock == 0) {
673 is_auto_eject = 1;
674 } else {
675 is_auto_eject = 0;
676 }
677 if (down_interruptible(&sony_sem))
678 return -ERESTARTSYS;
679 set_drive_params(sony_speed);
680 up(&sony_sem);
681 return 0;
682}
683
684/*
685 * This code will reset the drive and attempt to restore sane parameters.
686 */
687static void restart_on_error(void)
688{
689 unsigned char res_reg[12];
690 unsigned int res_size;
691 unsigned long retry_count;
692
693
694 printk(KERN_NOTICE PFX "Resetting drive on error\n");
695 reset_drive();
696 retry_count = jiffies + SONY_RESET_TIMEOUT;
697 while (time_before(jiffies, retry_count) && (!is_attention())) {
698 sony_sleep();
699 }
700 set_drive_params(sony_speed);
701 do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, &res_size);
702 if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20)) {
703 printk(KERN_NOTICE PFX "Unable to spin up drive: 0x%2.2x\n",
704 res_reg[1]);
705 }
706
707 msleep(2000);
708
709 sony_get_toc();
710}
711
712/*
713 * This routine writes data to the parameter register. Since this should
714 * happen fairly fast, it is polled with no OS waits between.
715 */
716static int write_params(unsigned char *params, int num_params)
717{
718 unsigned int retry_count;
719
720
721 retry_count = SONY_READY_RETRIES;
722 while ((retry_count > 0) && (!is_param_write_rdy())) {
723 retry_count--;
724 }
725 if (!is_param_write_rdy()) {
726 return -EIO;
727 }
728
729 while (num_params > 0) {
730 write_param(*params);
731 params++;
732 num_params--;
733 }
734
735 return 0;
736}
737
738
739/*
740 * The following reads data from the command result register. It is a
741 * fairly complex routine, all status info flows back through this
742 * interface. The algorithm is stolen directly from the flowcharts in
743 * the drive manual.
744 */
745static void
746get_result(unsigned char *result_buffer, unsigned int *result_size)
747{
748 unsigned char a, b;
749 int i;
750 unsigned long retry_count;
751
752
753 while (handle_sony_cd_attention());
754 /* Wait for the result data to be ready */
755 retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
756 while (time_before(jiffies, retry_count)
757 && (is_busy() || (!(is_result_ready())))) {
758 sony_sleep();
759
760 while (handle_sony_cd_attention());
761 }
762 if (is_busy() || (!(is_result_ready()))) {
763 pr_debug(PFX "timeout out %d\n", __LINE__);
764 result_buffer[0] = 0x20;
765 result_buffer[1] = SONY_TIMEOUT_OP_ERR;
766 *result_size = 2;
767 return;
768 }
769
770 /*
771 * Get the first two bytes. This determines what else needs
772 * to be done.
773 */
774 clear_result_ready();
775 a = read_result_register();
776 *result_buffer = a;
777 result_buffer++;
778
779 /* Check for block error status result. */
780 if ((a & 0xf0) == 0x50) {
781 *result_size = 1;
782 return;
783 }
784
785 b = read_result_register();
786 *result_buffer = b;
787 result_buffer++;
788 *result_size = 2;
789
790 /*
791 * 0x20 means an error occurred. Byte 2 will have the error code.
792 * Otherwise, the command succeeded, byte 2 will have the count of
793 * how many more status bytes are coming.
794 *
795 * The result register can be read 10 bytes at a time, a wait for
796 * result ready to be asserted must be done between every 10 bytes.
797 */
798 if ((a & 0xf0) != 0x20) {
799 if (b > 8) {
800 for (i = 0; i < 8; i++) {
801 *result_buffer = read_result_register();
802 result_buffer++;
803 (*result_size)++;
804 }
805 b = b - 8;
806
807 while (b > 10) {
808 retry_count = SONY_READY_RETRIES;
809 while ((retry_count > 0)
810 && (!is_result_ready())) {
811 retry_count--;
812 }
813 if (!is_result_ready()) {
814 pr_debug(PFX "timeout out %d\n",
815 __LINE__);
816 result_buffer[0] = 0x20;
817 result_buffer[1] =
818 SONY_TIMEOUT_OP_ERR;
819 *result_size = 2;
820 return;
821 }
822
823 clear_result_ready();
824
825 for (i = 0; i < 10; i++) {
826 *result_buffer =
827 read_result_register();
828 result_buffer++;
829 (*result_size)++;
830 }
831 b = b - 10;
832 }
833
834 if (b > 0) {
835 retry_count = SONY_READY_RETRIES;
836 while ((retry_count > 0)
837 && (!is_result_ready())) {
838 retry_count--;
839 }
840 if (!is_result_ready()) {
841 pr_debug(PFX "timeout out %d\n",
842 __LINE__);
843 result_buffer[0] = 0x20;
844 result_buffer[1] =
845 SONY_TIMEOUT_OP_ERR;
846 *result_size = 2;
847 return;
848 }
849 }
850 }
851
852 while (b > 0) {
853 *result_buffer = read_result_register();
854 result_buffer++;
855 (*result_size)++;
856 b--;
857 }
858 }
859}
860
861/*
862 * Do a command that does not involve data transfer. This routine must
863 * be re-entrant from the same task to support being called from the
864 * data operation code when an error occurs.
865 */
866static void
867do_sony_cd_cmd(unsigned char cmd,
868 unsigned char *params,
869 unsigned int num_params,
870 unsigned char *result_buffer, unsigned int *result_size)
871{
872 unsigned long retry_count;
873 int num_retries = 0;
874
875retry_cd_operation:
876
877 while (handle_sony_cd_attention());
878
879 retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
880 while (time_before(jiffies, retry_count) && (is_busy())) {
881 sony_sleep();
882
883 while (handle_sony_cd_attention());
884 }
885 if (is_busy()) {
886 pr_debug(PFX "timeout out %d\n", __LINE__);
887 result_buffer[0] = 0x20;
888 result_buffer[1] = SONY_TIMEOUT_OP_ERR;
889 *result_size = 2;
890 } else {
891 clear_result_ready();
892 clear_param_reg();
893
894 write_params(params, num_params);
895 write_cmd(cmd);
896
897 get_result(result_buffer, result_size);
898 }
899
900 if (((result_buffer[0] & 0xf0) == 0x20)
901 && (num_retries < MAX_CDU31A_RETRIES)) {
902 num_retries++;
903 msleep(100);
904 goto retry_cd_operation;
905 }
906}
907
908
909/*
910 * Handle an attention from the drive. This will return 1 if it found one
911 * or 0 if not (if one is found, the caller might want to call again).
912 *
913 * This routine counts the number of consecutive times it is called
914 * (since this is always called from a while loop until it returns
915 * a 0), and returns a 0 if it happens too many times. This will help
916 * prevent a lockup.
917 */
918static int handle_sony_cd_attention(void)
919{
920 unsigned char atten_code;
921 static int num_consecutive_attentions = 0;
922 volatile int val;
923
924
925#if 0
926 pr_debug(PFX "Entering %s\n", __FUNCTION__);
927#endif
928 if (is_attention()) {
929 if (num_consecutive_attentions >
930 CDU31A_MAX_CONSECUTIVE_ATTENTIONS) {
931 printk(KERN_NOTICE PFX "Too many consecutive "
932 "attentions: %d\n", num_consecutive_attentions);
933 num_consecutive_attentions = 0;
934 pr_debug(PFX "Leaving %s at %d\n", __FUNCTION__,
935 __LINE__);
936 return 0;
937 }
938
939 clear_attention();
940 atten_code = read_result_register();
941
942 switch (atten_code) {
943 /* Someone changed the CD. Mark it as changed */
944 case SONY_MECH_LOADED_ATTN:
945 disk_changed = 1;
946 sony_toc_read = 0;
947 sony_audio_status = CDROM_AUDIO_NO_STATUS;
948 sony_blocks_left = 0;
949 break;
950
951 case SONY_SPIN_DOWN_COMPLETE_ATTN:
952 /* Mark the disk as spun down. */
953 sony_spun_up = 0;
954 break;
955
956 case SONY_AUDIO_PLAY_DONE_ATTN:
957 sony_audio_status = CDROM_AUDIO_COMPLETED;
958 read_subcode();
959 break;
960
961 case SONY_EJECT_PUSHED_ATTN:
962 if (is_auto_eject) {
963 sony_audio_status = CDROM_AUDIO_INVALID;
964 }
965 break;
966
967 case SONY_LEAD_IN_ERR_ATTN:
968 case SONY_LEAD_OUT_ERR_ATTN:
969 case SONY_DATA_TRACK_ERR_ATTN:
970 case SONY_AUDIO_PLAYBACK_ERR_ATTN:
971 sony_audio_status = CDROM_AUDIO_ERROR;
972 break;
973 }
974
975 num_consecutive_attentions++;
976 pr_debug(PFX "Leaving %s at %d\n", __FUNCTION__, __LINE__);
977 return 1;
978 } else if (abort_read_started) {
979 while (is_result_reg_not_empty()) {
980 val = read_result_register();
981 }
982 clear_data_ready();
983 clear_result_ready();
984 /* Clear out the data */
985 while (is_data_requested()) {
986 val = read_data_register();
987 }
988 abort_read_started = 0;
989 pr_debug(PFX "Leaving %s at %d\n", __FUNCTION__, __LINE__);
990 return 1;
991 }
992
993 num_consecutive_attentions = 0;
994#if 0
995 pr_debug(PFX "Leaving %s at %d\n", __FUNCTION__, __LINE__);
996#endif
997 return 0;
998}
999
1000
1001/* Convert from an integer 0-99 to BCD */
1002static inline unsigned int int_to_bcd(unsigned int val)
1003{
1004 int retval;
1005
1006
1007 retval = (val / 10) << 4;
1008 retval = retval | val % 10;
1009 return retval;
1010}
1011
1012
1013/* Convert from BCD to an integer from 0-99 */
1014static unsigned int bcd_to_int(unsigned int bcd)
1015{
1016 return (((bcd >> 4) & 0x0f) * 10) + (bcd & 0x0f);
1017}
1018
1019
1020/*
1021 * Convert a logical sector value (like the OS would want to use for
1022 * a block device) to an MSF format.
1023 */
1024static void log_to_msf(unsigned int log, unsigned char *msf)
1025{
1026 log = log + LOG_START_OFFSET;
1027 msf[0] = int_to_bcd(log / 4500);
1028 log = log % 4500;
1029 msf[1] = int_to_bcd(log / 75);
1030 msf[2] = int_to_bcd(log % 75);
1031}
1032
1033
1034/*
1035 * Convert an MSF format to a logical sector.
1036 */
1037static unsigned int msf_to_log(unsigned char *msf)
1038{
1039 unsigned int log;
1040
1041
1042 log = msf[2];
1043 log += msf[1] * 75;
1044 log += msf[0] * 4500;
1045 log = log - LOG_START_OFFSET;
1046
1047 return log;
1048}
1049
1050
1051/*
1052 * Take in integer size value and put it into a buffer like
1053 * the drive would want to see a number-of-sector value.
1054 */
1055static void size_to_buf(unsigned int size, unsigned char *buf)
1056{
1057 buf[0] = size / 65536;
1058 size = size % 65536;
1059 buf[1] = size / 256;
1060 buf[2] = size % 256;
1061}
1062
1063/* Starts a read operation. Returns 0 on success and 1 on failure.
1064 The read operation used here allows multiple sequential sectors
1065 to be read and status returned for each sector. The driver will
1066 read the output one at a time as the requests come and abort the
1067 operation if the requested sector is not the next one from the
1068 drive. */
1069static int
1070start_request(unsigned int sector, unsigned int nsect)
1071{
1072 unsigned char params[6];
1073 unsigned long retry_count;
1074
1075
1076 pr_debug(PFX "Entering %s\n", __FUNCTION__);
1077 log_to_msf(sector, params);
1078 size_to_buf(nsect, &params[3]);
1079
1080 /*
1081 * Clear any outstanding attentions and wait for the drive to
1082 * complete any pending operations.
1083 */
1084 while (handle_sony_cd_attention());
1085
1086 retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
1087 while (time_before(jiffies, retry_count) && (is_busy())) {
1088 sony_sleep();
1089
1090 while (handle_sony_cd_attention());
1091 }
1092
1093 if (is_busy()) {
1094 printk(KERN_NOTICE PFX "Timeout while waiting "
1095 "to issue command\n");
1096 pr_debug(PFX "Leaving %s at %d\n", __FUNCTION__, __LINE__);
1097 return 1;
1098 } else {
1099 /* Issue the command */
1100 clear_result_ready();
1101 clear_param_reg();
1102
1103 write_params(params, 6);
1104 write_cmd(SONY_READ_BLKERR_STAT_CMD);
1105
1106 sony_blocks_left = nsect * 4;
1107 sony_next_block = sector * 4;
1108 pr_debug(PFX "Leaving %s at %d\n", __FUNCTION__, __LINE__);
1109 return 0;
1110 }
1111 pr_debug(PFX "Leaving %s at %d\n", __FUNCTION__, __LINE__);
1112}
1113
1114/* Abort a pending read operation. Clear all the drive status variables. */
1115static void abort_read(void)
1116{
1117 unsigned char result_reg[2];
1118 int result_size;
1119 volatile int val;
1120
1121
1122 do_sony_cd_cmd(SONY_ABORT_CMD, NULL, 0, result_reg, &result_size);
1123 if ((result_reg[0] & 0xf0) == 0x20) {
1124 printk(KERN_ERR PFX "Aborting read, %s error\n",
1125 translate_error(result_reg[1]));
1126 }
1127
1128 while (is_result_reg_not_empty()) {
1129 val = read_result_register();
1130 }
1131 clear_data_ready();
1132 clear_result_ready();
1133 /* Clear out the data */
1134 while (is_data_requested()) {
1135 val = read_data_register();
1136 }
1137
1138 sony_blocks_left = 0;
1139}
1140
1141/* Called when the timer times out. This will abort the
1142 pending read operation. */
1143static void handle_abort_timeout(unsigned long data)
1144{
1145 pr_debug(PFX "Entering %s\n", __FUNCTION__);
1146 /* If it is in use, ignore it. */
1147 if (down_trylock(&sony_sem) == 0) {
1148 /* We can't use abort_read(), because it will sleep
1149 or schedule in the timer interrupt. Just start
1150 the operation, finish it on the next access to
1151 the drive. */
1152 clear_result_ready();
1153 clear_param_reg();
1154 write_cmd(SONY_ABORT_CMD);
1155
1156 sony_blocks_left = 0;
1157 abort_read_started = 1;
1158 up(&sony_sem);
1159 }
1160 pr_debug(PFX "Leaving %s\n", __FUNCTION__);
1161}
1162
1163/* Actually get one sector of data from the drive. */
1164static void
1165input_data_sector(char *buffer)
1166{
1167 pr_debug(PFX "Entering %s\n", __FUNCTION__);
1168
1169 /* If an XA disk on a CDU31A, skip the first 12 bytes of data from
1170 the disk. The real data is after that. We can use audio_buffer. */
1171 if (sony_xa_mode)
1172 insb(sony_cd_read_reg, audio_buffer, CD_XA_HEAD);
1173
1174 clear_data_ready();
1175
1176 insb(sony_cd_read_reg, buffer, 2048);
1177
1178 /* If an XA disk, we have to clear out the rest of the unused
1179 error correction data. We can use audio_buffer for that. */
1180 if (sony_xa_mode)
1181 insb(sony_cd_read_reg, audio_buffer, CD_XA_TAIL);
1182
1183 pr_debug(PFX "Leaving %s\n", __FUNCTION__);
1184}
1185
1186/* read data from the drive. Note the nsect must be <= 4. */
1187static void
1188read_data_block(char *buffer,
1189 unsigned int block,
1190 unsigned int nblocks,
1191 unsigned char res_reg[], int *res_size)
1192{
1193 unsigned long retry_count;
1194
1195 pr_debug(PFX "Entering %s\n", __FUNCTION__);
1196
1197 res_reg[0] = 0;
1198 res_reg[1] = 0;
1199 *res_size = 0;
1200
1201 /* Wait for the drive to tell us we have something */
1202 retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
1203 while (time_before(jiffies, retry_count) && !(is_data_ready())) {
1204 while (handle_sony_cd_attention());
1205
1206 sony_sleep();
1207 }
1208 if (!(is_data_ready())) {
1209 if (is_result_ready()) {
1210 get_result(res_reg, res_size);
1211 if ((res_reg[0] & 0xf0) != 0x20) {
1212 printk(KERN_NOTICE PFX "Got result that should"
1213 " have been error: %d\n", res_reg[0]);
1214 res_reg[0] = 0x20;
1215 res_reg[1] = SONY_BAD_DATA_ERR;
1216 *res_size = 2;
1217 }
1218 abort_read();
1219 } else {
1220 pr_debug(PFX "timeout out %d\n", __LINE__);
1221 res_reg[0] = 0x20;
1222 res_reg[1] = SONY_TIMEOUT_OP_ERR;
1223 *res_size = 2;
1224 abort_read();
1225 }
1226 } else {
1227 input_data_sector(buffer);
1228 sony_blocks_left -= nblocks;
1229 sony_next_block += nblocks;
1230
1231 /* Wait for the status from the drive. */
1232 retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
1233 while (time_before(jiffies, retry_count)
1234 && !(is_result_ready())) {
1235 while (handle_sony_cd_attention());
1236
1237 sony_sleep();
1238 }
1239
1240 if (!is_result_ready()) {
1241 pr_debug(PFX "timeout out %d\n", __LINE__);
1242 res_reg[0] = 0x20;
1243 res_reg[1] = SONY_TIMEOUT_OP_ERR;
1244 *res_size = 2;
1245 abort_read();
1246 } else {
1247 get_result(res_reg, res_size);
1248
1249 /* If we got a buffer status, handle that. */
1250 if ((res_reg[0] & 0xf0) == 0x50) {
1251
1252 if ((res_reg[0] ==
1253 SONY_NO_CIRC_ERR_BLK_STAT)
1254 || (res_reg[0] ==
1255 SONY_NO_LECC_ERR_BLK_STAT)
1256 || (res_reg[0] ==
1257 SONY_RECOV_LECC_ERR_BLK_STAT)) {
1258 /* nothing here */
1259 } else {
1260 printk(KERN_ERR PFX "Data block "
1261 "error: 0x%x\n", res_reg[0]);
1262 res_reg[0] = 0x20;
1263 res_reg[1] = SONY_BAD_DATA_ERR;
1264 *res_size = 2;
1265 }
1266
1267 /* Final transfer is done for read command, get final result. */
1268 if (sony_blocks_left == 0) {
1269 get_result(res_reg, res_size);
1270 }
1271 } else if ((res_reg[0] & 0xf0) != 0x20) {
1272 /* The drive gave me bad status, I don't know what to do.
1273 Reset the driver and return an error. */
1274 printk(KERN_ERR PFX "Invalid block "
1275 "status: 0x%x\n", res_reg[0]);
1276 restart_on_error();
1277 res_reg[0] = 0x20;
1278 res_reg[1] = SONY_BAD_DATA_ERR;
1279 *res_size = 2;
1280 }
1281 }
1282 }
1283 pr_debug(PFX "Leaving %s at %d\n", __FUNCTION__, __LINE__);
1284}
1285
1286
1287/*
1288 * The OS calls this to perform a read or write operation to the drive.
1289 * Write obviously fail. Reads to a read ahead of sony_buffer_size
1290 * bytes to help speed operations. This especially helps since the OS
1291 * uses 1024 byte blocks and the drive uses 2048 byte blocks. Since most
1292 * data access on a CD is done sequentially, this saves a lot of operations.
1293 */
1294static void do_cdu31a_request(request_queue_t * q)
1295{
1296 struct request *req;
1297 int block, nblock, num_retries;
1298 unsigned char res_reg[12];
1299 unsigned int res_size;
1300
1301 pr_debug(PFX "Entering %s\n", __FUNCTION__);
1302
1303 spin_unlock_irq(q->queue_lock);
1304 if (down_interruptible(&sony_sem)) {
1305 spin_lock_irq(q->queue_lock);
1306 return;
1307 }
1308
1309 /* Get drive status before doing anything. */
1310 while (handle_sony_cd_attention());
1311
1312 /* Make sure we have a valid TOC. */
1313 sony_get_toc();
1314
1315
1316 /* Make sure the timer is cancelled. */
1317 del_timer(&cdu31a_abort_timer);
1318
1319 while (1) {
1320 /*
1321 * The beginning here is stolen from the hard disk driver. I hope
1322 * it's right.
1323 */
1324 req = elv_next_request(q);
1325 if (!req)
1326 goto end_do_cdu31a_request;
1327
1328 if (!sony_spun_up)
1329 scd_spinup();
1330
1331 block = req->sector;
1332 nblock = req->nr_sectors;
1333 pr_debug(PFX "request at block %d, length %d blocks\n",
1334 block, nblock);
1335 if (!sony_toc_read) {
1336 printk(KERN_NOTICE PFX "TOC not read\n");
1337 end_request(req, 0);
1338 continue;
1339 }
1340
1341 /* WTF??? */
1342 if (!(req->flags & REQ_CMD))
1343 continue;
1344 if (rq_data_dir(req) == WRITE) {
1345 end_request(req, 0);
1346 continue;
1347 }
1348
1349 /*
1350 * If the block address is invalid or the request goes beyond the end of
1351 * the media, return an error.
1352 */
1353 if (((block + nblock) / 4) >= sony_toc.lead_out_start_lba) {
1354 printk(KERN_NOTICE PFX "Request past end of media\n");
1355 end_request(req, 0);
1356 continue;
1357 }
1358
1359 if (nblock > 4)
1360 nblock = 4;
1361 num_retries = 0;
1362
1363 try_read_again:
1364 while (handle_sony_cd_attention());
1365
1366 if (!sony_toc_read) {
1367 printk(KERN_NOTICE PFX "TOC not read\n");
1368 end_request(req, 0);
1369 continue;
1370 }
1371
1372 /* If no data is left to be read from the drive, start the
1373 next request. */
1374 if (sony_blocks_left == 0) {
1375 if (start_request(block / 4, nblock / 4)) {
1376 end_request(req, 0);
1377 continue;
1378 }
1379 }
1380 /* If the requested block is not the next one waiting in
1381 the driver, abort the current operation and start a
1382 new one. */
1383 else if (block != sony_next_block) {
1384 pr_debug(PFX "Read for block %d, expected %d\n",
1385 block, sony_next_block);
1386 abort_read();
1387 if (!sony_toc_read) {
1388 printk(KERN_NOTICE PFX "TOC not read\n");
1389 end_request(req, 0);
1390 continue;
1391 }
1392 if (start_request(block / 4, nblock / 4)) {
1393 printk(KERN_NOTICE PFX "start request failed\n");
1394 end_request(req, 0);
1395 continue;
1396 }
1397 }
1398
1399 read_data_block(req->buffer, block, nblock, res_reg, &res_size);
1400
1401 if (res_reg[0] != 0x20) {
1402 if (!end_that_request_first(req, 1, nblock)) {
1403 spin_lock_irq(q->queue_lock);
1404 blkdev_dequeue_request(req);
1405 end_that_request_last(req);
1406 spin_unlock_irq(q->queue_lock);
1407 }
1408 continue;
1409 }
1410
1411 if (num_retries > MAX_CDU31A_RETRIES) {
1412 end_request(req, 0);
1413 continue;
1414 }
1415
1416 num_retries++;
1417 if (res_reg[1] == SONY_NOT_SPIN_ERR) {
1418 do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg,
1419 &res_size);
1420 } else {
1421 printk(KERN_NOTICE PFX "%s error for block %d, nblock %d\n",
1422 translate_error(res_reg[1]), block, nblock);
1423 }
1424 goto try_read_again;
1425 }
1426 end_do_cdu31a_request:
1427#if 0
1428 /* After finished, cancel any pending operations. */
1429 abort_read();
1430#else
1431 /* Start a timer to time out after a while to disable
1432 the read. */
1433 cdu31a_abort_timer.expires = jiffies + 2 * HZ; /* Wait 2 seconds */
1434 add_timer(&cdu31a_abort_timer);
1435#endif
1436
1437 up(&sony_sem);
1438 spin_lock_irq(q->queue_lock);
1439 pr_debug(PFX "Leaving %s at %d\n", __FUNCTION__, __LINE__);
1440}
1441
1442
1443/*
1444 * Read the table of contents from the drive and set up TOC if
1445 * successful.
1446 */
1447static void sony_get_toc(void)
1448{
1449 unsigned char res_reg[2];
1450 unsigned int res_size;
1451 unsigned char parms[1];
1452 int session;
1453 int num_spin_ups;
1454 int totaltracks = 0;
1455 int mint = 99;
1456 int maxt = 0;
1457
1458 pr_debug(PFX "Entering %s\n", __FUNCTION__);
1459
1460 num_spin_ups = 0;
1461 if (!sony_toc_read) {
1462 respinup_on_gettoc:
1463 /* Ignore the result, since it might error if spinning already. */
1464 do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg,
1465 &res_size);
1466
1467 do_sony_cd_cmd(SONY_READ_TOC_CMD, NULL, 0, res_reg,
1468 &res_size);
1469
1470 /* The drive sometimes returns error 0. I don't know why, but ignore
1471 it. It seems to mean the drive has already done the operation. */
1472 if ((res_size < 2)
1473 || ((res_reg[0] != 0) && (res_reg[1] != 0))) {
1474 /* If the drive is already playing, it's ok. */
1475 if ((res_reg[1] == SONY_AUDIO_PLAYING_ERR)
1476 || (res_reg[1] == 0)) {
1477 goto gettoc_drive_spinning;
1478 }
1479
1480 /* If the drive says it is not spun up (even though we just did it!)
1481 then retry the operation at least a few times. */
1482 if ((res_reg[1] == SONY_NOT_SPIN_ERR)
1483 && (num_spin_ups < MAX_CDU31A_RETRIES)) {
1484 num_spin_ups++;
1485 goto respinup_on_gettoc;
1486 }
1487
1488 printk("cdu31a: Error reading TOC: %x %s\n",
1489 res_reg[0], translate_error(res_reg[1]));
1490 return;
1491 }
1492
1493 gettoc_drive_spinning:
1494
1495 /* The idea here is we keep asking for sessions until the command
1496 fails. Then we know what the last valid session on the disk is.
1497 No need to check session 0, since session 0 is the same as session
1498 1; the command returns different information if you give it 0.
1499 */
1500#if DEBUG
1501 memset(&sony_toc, 0x0e, sizeof(sony_toc));
1502 memset(&single_toc, 0x0f, sizeof(single_toc));
1503#endif
1504 session = 1;
1505 while (1) {
1506/* This seems to slow things down enough to make it work. This
1507 * appears to be a problem in do_sony_cd_cmd. This printk seems
1508 * to address the symptoms... -Erik */
1509 pr_debug(PFX "Trying session %d\n", session);
1510 parms[0] = session;
1511 do_sony_cd_cmd(SONY_READ_TOC_SPEC_CMD,
1512 parms, 1, res_reg, &res_size);
1513
1514 pr_debug(PFX "%2.2x %2.2x\n", res_reg[0], res_reg[1]);
1515
1516 if ((res_size < 2)
1517 || ((res_reg[0] & 0xf0) == 0x20)) {
1518 /* An error reading the TOC, this must be past the last session. */
1519 if (session == 1)
1520 printk
1521 ("Yikes! Couldn't read any sessions!");
1522 break;
1523 }
1524 pr_debug(PFX "Reading session %d\n", session);
1525
1526 parms[0] = session;
1527 do_sony_cd_cmd(SONY_REQ_TOC_DATA_SPEC_CMD,
1528 parms,
1529 1,
1530 (unsigned char *) &single_toc,
1531 &res_size);
1532 if ((res_size < 2)
1533 || ((single_toc.exec_status[0] & 0xf0) ==
1534 0x20)) {
1535 printk(KERN_ERR PFX "Error reading "
1536 "session %d: %x %s\n",
1537 session, single_toc.exec_status[0],
1538 translate_error(single_toc.
1539 exec_status[1]));
1540 /* An error reading the TOC. Return without sony_toc_read
1541 set. */
1542 return;
1543 }
1544 pr_debug(PFX "add0 %01x, con0 %01x, poi0 %02x, "
1545 "1st trk %d, dsktyp %x, dum0 %x\n",
1546 single_toc.address0, single_toc.control0,
1547 single_toc.point0,
1548 bcd_to_int(single_toc.first_track_num),
1549 single_toc.disk_type, single_toc.dummy0);
1550 pr_debug(PFX "add1 %01x, con1 %01x, poi1 %02x, "
1551 "lst trk %d, dummy1 %x, dum2 %x\n",
1552 single_toc.address1, single_toc.control1,
1553 single_toc.point1,
1554 bcd_to_int(single_toc.last_track_num),
1555 single_toc.dummy1, single_toc.dummy2);
1556 pr_debug(PFX "add2 %01x, con2 %01x, poi2 %02x "
1557 "leadout start min %d, sec %d, frame %d\n",
1558 single_toc.address2, single_toc.control2,
1559 single_toc.point2,
1560 bcd_to_int(single_toc.lead_out_start_msf[0]),
1561 bcd_to_int(single_toc.lead_out_start_msf[1]),
1562 bcd_to_int(single_toc.lead_out_start_msf[2]));
1563 if (res_size > 18 && single_toc.pointb0 > 0xaf)
1564 pr_debug(PFX "addb0 %01x, conb0 %01x, poib0 %02x, nextsession min %d, sec %d, frame %d\n"
1565 "#mode5_ptrs %02d, max_start_outer_leadout_msf min %d, sec %d, frame %d\n",
1566 single_toc.addressb0,
1567 single_toc.controlb0,
1568 single_toc.pointb0,
1569 bcd_to_int(single_toc.
1570 next_poss_prog_area_msf
1571 [0]),
1572 bcd_to_int(single_toc.
1573 next_poss_prog_area_msf
1574 [1]),
1575 bcd_to_int(single_toc.
1576 next_poss_prog_area_msf
1577 [2]),
1578 single_toc.num_mode_5_pointers,
1579 bcd_to_int(single_toc.
1580 max_start_outer_leadout_msf
1581 [0]),
1582 bcd_to_int(single_toc.
1583 max_start_outer_leadout_msf
1584 [1]),
1585 bcd_to_int(single_toc.
1586 max_start_outer_leadout_msf
1587 [2]));
1588 if (res_size > 27 && single_toc.pointb1 > 0xaf)
1589 pr_debug(PFX "addb1 %01x, conb1 %01x, poib1 %02x, %x %x %x %x #skipint_ptrs %d, #skiptrkassign %d %x\n",
1590 single_toc.addressb1,
1591 single_toc.controlb1,
1592 single_toc.pointb1,
1593 single_toc.dummyb0_1[0],
1594 single_toc.dummyb0_1[1],
1595 single_toc.dummyb0_1[2],
1596 single_toc.dummyb0_1[3],
1597 single_toc.num_skip_interval_pointers,
1598 single_toc.num_skip_track_assignments,
1599 single_toc.dummyb0_2);
1600 if (res_size > 36 && single_toc.pointb2 > 0xaf)
1601 pr_debug(PFX "addb2 %01x, conb2 %01x, poib2 %02x, %02x %02x %02x %02x %02x %02x %02x\n",
1602 single_toc.addressb2,
1603 single_toc.controlb2,
1604 single_toc.pointb2,
1605 single_toc.tracksb2[0],
1606 single_toc.tracksb2[1],
1607 single_toc.tracksb2[2],
1608 single_toc.tracksb2[3],
1609 single_toc.tracksb2[4],
1610 single_toc.tracksb2[5],
1611 single_toc.tracksb2[6]);
1612 if (res_size > 45 && single_toc.pointb3 > 0xaf)
1613 pr_debug(PFX "addb3 %01x, conb3 %01x, poib3 %02x, %02x %02x %02x %02x %02x %02x %02x\n",
1614 single_toc.addressb3,
1615 single_toc.controlb3,
1616 single_toc.pointb3,
1617 single_toc.tracksb3[0],
1618 single_toc.tracksb3[1],
1619 single_toc.tracksb3[2],
1620 single_toc.tracksb3[3],
1621 single_toc.tracksb3[4],
1622 single_toc.tracksb3[5],
1623 single_toc.tracksb3[6]);
1624 if (res_size > 54 && single_toc.pointb4 > 0xaf)
1625 pr_debug(PFX "addb4 %01x, conb4 %01x, poib4 %02x, %02x %02x %02x %02x %02x %02x %02x\n",
1626 single_toc.addressb4,
1627 single_toc.controlb4,
1628 single_toc.pointb4,
1629 single_toc.tracksb4[0],
1630 single_toc.tracksb4[1],
1631 single_toc.tracksb4[2],
1632 single_toc.tracksb4[3],
1633 single_toc.tracksb4[4],
1634 single_toc.tracksb4[5],
1635 single_toc.tracksb4[6]);
1636 if (res_size > 63 && single_toc.pointc0 > 0xaf)
1637 pr_debug(PFX "addc0 %01x, conc0 %01x, poic0 %02x, %02x %02x %02x %02x %02x %02x %02x\n",
1638 single_toc.addressc0,
1639 single_toc.controlc0,
1640 single_toc.pointc0,
1641 single_toc.dummyc0[0],
1642 single_toc.dummyc0[1],
1643 single_toc.dummyc0[2],
1644 single_toc.dummyc0[3],
1645 single_toc.dummyc0[4],
1646 single_toc.dummyc0[5],
1647 single_toc.dummyc0[6]);
1648#undef DEBUG
1649#define DEBUG 0
1650
1651 sony_toc.lead_out_start_msf[0] =
1652 bcd_to_int(single_toc.lead_out_start_msf[0]);
1653 sony_toc.lead_out_start_msf[1] =
1654 bcd_to_int(single_toc.lead_out_start_msf[1]);
1655 sony_toc.lead_out_start_msf[2] =
1656 bcd_to_int(single_toc.lead_out_start_msf[2]);
1657 sony_toc.lead_out_start_lba =
1658 single_toc.lead_out_start_lba =
1659 msf_to_log(sony_toc.lead_out_start_msf);
1660
1661 /* For points that do not exist, move the data over them
1662 to the right location. */
1663 if (single_toc.pointb0 != 0xb0) {
1664 memmove(((char *) &single_toc) + 27,
1665 ((char *) &single_toc) + 18,
1666 res_size - 18);
1667 res_size += 9;
1668 } else if (res_size > 18) {
1669 sony_toc.lead_out_start_msf[0] =
1670 bcd_to_int(single_toc.
1671 max_start_outer_leadout_msf
1672 [0]);
1673 sony_toc.lead_out_start_msf[1] =
1674 bcd_to_int(single_toc.
1675 max_start_outer_leadout_msf
1676 [1]);
1677 sony_toc.lead_out_start_msf[2] =
1678 bcd_to_int(single_toc.
1679 max_start_outer_leadout_msf
1680 [2]);
1681 sony_toc.lead_out_start_lba =
1682 msf_to_log(sony_toc.
1683 lead_out_start_msf);
1684 }
1685 if (single_toc.pointb1 != 0xb1) {
1686 memmove(((char *) &single_toc) + 36,
1687 ((char *) &single_toc) + 27,
1688 res_size - 27);
1689 res_size += 9;
1690 }
1691 if (single_toc.pointb2 != 0xb2) {
1692 memmove(((char *) &single_toc) + 45,
1693 ((char *) &single_toc) + 36,
1694 res_size - 36);
1695 res_size += 9;
1696 }
1697 if (single_toc.pointb3 != 0xb3) {
1698 memmove(((char *) &single_toc) + 54,
1699 ((char *) &single_toc) + 45,
1700 res_size - 45);
1701 res_size += 9;
1702 }
1703 if (single_toc.pointb4 != 0xb4) {
1704 memmove(((char *) &single_toc) + 63,
1705 ((char *) &single_toc) + 54,
1706 res_size - 54);
1707 res_size += 9;
1708 }
1709 if (single_toc.pointc0 != 0xc0) {
1710 memmove(((char *) &single_toc) + 72,
1711 ((char *) &single_toc) + 63,
1712 res_size - 63);
1713 res_size += 9;
1714 }
1715#if DEBUG
1716 printk(PRINT_INFO PFX "start track lba %u, "
1717 "leadout start lba %u\n",
1718 single_toc.start_track_lba,
1719 single_toc.lead_out_start_lba);
1720 {
1721 int i;
1722 for (i = 0;
1723 i <
1724 1 +
1725 bcd_to_int(single_toc.last_track_num)
1726 -
1727 bcd_to_int(single_toc.
1728 first_track_num); i++) {
1729 printk(KERN_INFO PFX "trk %02d: add 0x%01x, con 0x%01x, track %02d, start min %02d, sec %02d, frame %02d\n",
1730 i,
1731 single_toc.tracks[i].address,
1732 single_toc.tracks[i].control,
1733 bcd_to_int(single_toc.
1734 tracks[i].track),
1735 bcd_to_int(single_toc.
1736 tracks[i].
1737 track_start_msf
1738 [0]),
1739 bcd_to_int(single_toc.
1740 tracks[i].
1741 track_start_msf
1742 [1]),
1743 bcd_to_int(single_toc.
1744 tracks[i].
1745 track_start_msf
1746 [2]));
1747 if (mint >
1748 bcd_to_int(single_toc.
1749 tracks[i].track))
1750 mint =
1751 bcd_to_int(single_toc.
1752 tracks[i].
1753 track);
1754 if (maxt <
1755 bcd_to_int(single_toc.
1756 tracks[i].track))
1757 maxt =
1758 bcd_to_int(single_toc.
1759 tracks[i].
1760 track);
1761 }
1762 printk(KERN_INFO PFX "min track number %d, "
1763 "max track number %d\n",
1764 mint, maxt);
1765 }
1766#endif
1767
1768 /* prepare a special table of contents for a CD-I disc. They don't have one. */
1769 if (single_toc.disk_type == 0x10 &&
1770 single_toc.first_track_num == 2 &&
1771 single_toc.last_track_num == 2 /* CD-I */ ) {
1772 sony_toc.tracks[totaltracks].address = 1;
1773 sony_toc.tracks[totaltracks].control = 4; /* force data tracks */
1774 sony_toc.tracks[totaltracks].track = 1;
1775 sony_toc.tracks[totaltracks].
1776 track_start_msf[0] = 0;
1777 sony_toc.tracks[totaltracks].
1778 track_start_msf[1] = 2;
1779 sony_toc.tracks[totaltracks].
1780 track_start_msf[2] = 0;
1781 mint = maxt = 1;
1782 totaltracks++;
1783 } else
1784 /* gather track entries from this session */
1785 {
1786 int i;
1787 for (i = 0;
1788 i <
1789 1 +
1790 bcd_to_int(single_toc.last_track_num)
1791 -
1792 bcd_to_int(single_toc.
1793 first_track_num);
1794 i++, totaltracks++) {
1795 sony_toc.tracks[totaltracks].
1796 address =
1797 single_toc.tracks[i].address;
1798 sony_toc.tracks[totaltracks].
1799 control =
1800 single_toc.tracks[i].control;
1801 sony_toc.tracks[totaltracks].
1802 track =
1803 bcd_to_int(single_toc.
1804 tracks[i].track);
1805 sony_toc.tracks[totaltracks].
1806 track_start_msf[0] =
1807 bcd_to_int(single_toc.
1808 tracks[i].
1809 track_start_msf[0]);
1810 sony_toc.tracks[totaltracks].
1811 track_start_msf[1] =
1812 bcd_to_int(single_toc.
1813 tracks[i].
1814 track_start_msf[1]);
1815 sony_toc.tracks[totaltracks].
1816 track_start_msf[2] =
1817 bcd_to_int(single_toc.
1818 tracks[i].
1819 track_start_msf[2]);
1820 if (i == 0)
1821 single_toc.
1822 start_track_lba =
1823 msf_to_log(sony_toc.
1824 tracks
1825 [totaltracks].
1826 track_start_msf);
1827 if (mint >
1828 sony_toc.tracks[totaltracks].
1829 track)
1830 mint =
1831 sony_toc.
1832 tracks[totaltracks].
1833 track;
1834 if (maxt <
1835 sony_toc.tracks[totaltracks].
1836 track)
1837 maxt =
1838 sony_toc.
1839 tracks[totaltracks].
1840 track;
1841 }
1842 }
1843 sony_toc.first_track_num = mint;
1844 sony_toc.last_track_num = maxt;
1845 /* Disk type of last session wins. For example:
1846 CD-Extra has disk type 0 for the first session, so
1847 a dumb HiFi CD player thinks it is a plain audio CD.
1848 We are interested in the disk type of the last session,
1849 which is 0x20 (XA) for CD-Extra, so we can access the
1850 data track ... */
1851 sony_toc.disk_type = single_toc.disk_type;
1852 sony_toc.sessions = session;
1853
1854 /* don't believe everything :-) */
1855 if (session == 1)
1856 single_toc.start_track_lba = 0;
1857 sony_toc.start_track_lba =
1858 single_toc.start_track_lba;
1859
1860 if (session > 1 && single_toc.pointb0 == 0xb0 &&
1861 sony_toc.lead_out_start_lba ==
1862 single_toc.lead_out_start_lba) {
1863 break;
1864 }
1865
1866 /* Let's not get carried away... */
1867 if (session > 40) {
1868 printk(KERN_NOTICE PFX "too many sessions: "
1869 "%d\n", session);
1870 break;
1871 }
1872 session++;
1873 }
1874 sony_toc.track_entries = totaltracks;
1875 /* add one entry for the LAST track with track number CDROM_LEADOUT */
1876 sony_toc.tracks[totaltracks].address = single_toc.address2;
1877 sony_toc.tracks[totaltracks].control = single_toc.control2;
1878 sony_toc.tracks[totaltracks].track = CDROM_LEADOUT;
1879 sony_toc.tracks[totaltracks].track_start_msf[0] =
1880 sony_toc.lead_out_start_msf[0];
1881 sony_toc.tracks[totaltracks].track_start_msf[1] =
1882 sony_toc.lead_out_start_msf[1];
1883 sony_toc.tracks[totaltracks].track_start_msf[2] =
1884 sony_toc.lead_out_start_msf[2];
1885
1886 sony_toc_read = 1;
1887
1888 pr_debug(PFX "Disk session %d, start track: %d, "
1889 "stop track: %d\n",
1890 session, single_toc.start_track_lba,
1891 single_toc.lead_out_start_lba);
1892 }
1893 pr_debug(PFX "Leaving %s\n", __FUNCTION__);
1894}
1895
1896
1897/*
1898 * Uniform cdrom interface function
1899 * return multisession offset and sector information
1900 */
1901static int scd_get_last_session(struct cdrom_device_info *cdi,
1902 struct cdrom_multisession *ms_info)
1903{
1904 if (ms_info == NULL)
1905 return 1;
1906
1907 if (!sony_toc_read) {
1908 if (down_interruptible(&sony_sem))
1909 return -ERESTARTSYS;
1910 sony_get_toc();
1911 up(&sony_sem);
1912 }
1913
1914 ms_info->addr_format = CDROM_LBA;
1915 ms_info->addr.lba = sony_toc.start_track_lba;
1916 ms_info->xa_flag = sony_toc.disk_type == SONY_XA_DISK_TYPE ||
1917 sony_toc.disk_type == 0x10 /* CDI */ ;
1918
1919 return 0;
1920}
1921
1922/*
1923 * Search for a specific track in the table of contents.
1924 */
1925static int find_track(int track)
1926{
1927 int i;
1928
1929 for (i = 0; i <= sony_toc.track_entries; i++) {
1930 if (sony_toc.tracks[i].track == track) {
1931 return i;
1932 }
1933 }
1934
1935 return -1;
1936}
1937
1938
1939/*
1940 * Read the subcode and put it in last_sony_subcode for future use.
1941 */
1942static int read_subcode(void)
1943{
1944 unsigned int res_size;
1945
1946
1947 do_sony_cd_cmd(SONY_REQ_SUBCODE_ADDRESS_CMD,
1948 NULL,
1949 0, (unsigned char *) &last_sony_subcode, &res_size);
1950 if ((res_size < 2)
1951 || ((last_sony_subcode.exec_status[0] & 0xf0) == 0x20)) {
1952 printk(KERN_ERR PFX "Sony CDROM error %s (read_subcode)\n",
1953 translate_error(last_sony_subcode.exec_status[1]));
1954 return -EIO;
1955 }
1956
1957 last_sony_subcode.track_num =
1958 bcd_to_int(last_sony_subcode.track_num);
1959 last_sony_subcode.index_num =
1960 bcd_to_int(last_sony_subcode.index_num);
1961 last_sony_subcode.abs_msf[0] =
1962 bcd_to_int(last_sony_subcode.abs_msf[0]);
1963 last_sony_subcode.abs_msf[1] =
1964 bcd_to_int(last_sony_subcode.abs_msf[1]);
1965 last_sony_subcode.abs_msf[2] =
1966 bcd_to_int(last_sony_subcode.abs_msf[2]);
1967
1968 last_sony_subcode.rel_msf[0] =
1969 bcd_to_int(last_sony_subcode.rel_msf[0]);
1970 last_sony_subcode.rel_msf[1] =
1971 bcd_to_int(last_sony_subcode.rel_msf[1]);
1972 last_sony_subcode.rel_msf[2] =
1973 bcd_to_int(last_sony_subcode.rel_msf[2]);
1974 return 0;
1975}
1976
1977/*
1978 * Uniform cdrom interface function
1979 * return the media catalog number found on some older audio cds
1980 */
1981static int
1982scd_get_mcn(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn)
1983{
1984 unsigned char resbuffer[2 + 14];
1985 unsigned char *mcnp = mcn->medium_catalog_number;
1986 unsigned char *resp = resbuffer + 3;
1987 unsigned int res_size;
1988
1989 memset(mcn->medium_catalog_number, 0, 14);
1990 if (down_interruptible(&sony_sem))
1991 return -ERESTARTSYS;
1992 do_sony_cd_cmd(SONY_REQ_UPC_EAN_CMD,
1993 NULL, 0, resbuffer, &res_size);
1994 up(&sony_sem);
1995 if ((res_size < 2) || ((resbuffer[0] & 0xf0) == 0x20));
1996 else {
1997 /* packed bcd to single ASCII digits */
1998 *mcnp++ = (*resp >> 4) + '0';
1999 *mcnp++ = (*resp++ & 0x0f) + '0';
2000 *mcnp++ = (*resp >> 4) + '0';
2001 *mcnp++ = (*resp++ & 0x0f) + '0';
2002 *mcnp++ = (*resp >> 4) + '0';
2003 *mcnp++ = (*resp++ & 0x0f) + '0';
2004 *mcnp++ = (*resp >> 4) + '0';
2005 *mcnp++ = (*resp++ & 0x0f) + '0';
2006 *mcnp++ = (*resp >> 4) + '0';
2007 *mcnp++ = (*resp++ & 0x0f) + '0';
2008 *mcnp++ = (*resp >> 4) + '0';
2009 *mcnp++ = (*resp++ & 0x0f) + '0';
2010 *mcnp++ = (*resp >> 4) + '0';
2011 }
2012 *mcnp = '\0';
2013 return 0;
2014}
2015
2016
2017/*
2018 * Get the subchannel info like the CDROMSUBCHNL command wants to see it. If
2019 * the drive is playing, the subchannel needs to be read (since it would be
2020 * changing). If the drive is paused or completed, the subcode information has
2021 * already been stored, just use that. The ioctl call wants things in decimal
2022 * (not BCD), so all the conversions are done.
2023 */
2024static int sony_get_subchnl_info(struct cdrom_subchnl *schi)
2025{
2026 /* Get attention stuff */
2027 while (handle_sony_cd_attention());
2028
2029 sony_get_toc();
2030 if (!sony_toc_read) {
2031 return -EIO;
2032 }
2033
2034 switch (sony_audio_status) {
2035 case CDROM_AUDIO_NO_STATUS:
2036 case CDROM_AUDIO_PLAY:
2037 if (read_subcode() < 0) {
2038 return -EIO;
2039 }
2040 break;
2041
2042 case CDROM_AUDIO_PAUSED:
2043 case CDROM_AUDIO_COMPLETED:
2044 break;
2045
2046#if 0
2047 case CDROM_AUDIO_NO_STATUS:
2048 schi->cdsc_audiostatus = sony_audio_status;
2049 return 0;
2050 break;
2051#endif
2052 case CDROM_AUDIO_INVALID:
2053 case CDROM_AUDIO_ERROR:
2054 default:
2055 return -EIO;
2056 }
2057
2058 schi->cdsc_audiostatus = sony_audio_status;
2059 schi->cdsc_adr = last_sony_subcode.address;
2060 schi->cdsc_ctrl = last_sony_subcode.control;
2061 schi->cdsc_trk = last_sony_subcode.track_num;
2062 schi->cdsc_ind = last_sony_subcode.index_num;
2063 if (schi->cdsc_format == CDROM_MSF) {
2064 schi->cdsc_absaddr.msf.minute =
2065 last_sony_subcode.abs_msf[0];
2066 schi->cdsc_absaddr.msf.second =
2067 last_sony_subcode.abs_msf[1];
2068 schi->cdsc_absaddr.msf.frame =
2069 last_sony_subcode.abs_msf[2];
2070
2071 schi->cdsc_reladdr.msf.minute =
2072 last_sony_subcode.rel_msf[0];
2073 schi->cdsc_reladdr.msf.second =
2074 last_sony_subcode.rel_msf[1];
2075 schi->cdsc_reladdr.msf.frame =
2076 last_sony_subcode.rel_msf[2];
2077 } else if (schi->cdsc_format == CDROM_LBA) {
2078 schi->cdsc_absaddr.lba =
2079 msf_to_log(last_sony_subcode.abs_msf);
2080 schi->cdsc_reladdr.lba =
2081 msf_to_log(last_sony_subcode.rel_msf);
2082 }
2083
2084 return 0;
2085}
2086
2087/* Get audio data from the drive. This is fairly complex because I
2088 am looking for status and data at the same time, but if I get status
2089 then I just look for data. I need to get the status immediately so
2090 the switch from audio to data tracks will happen quickly. */
2091static void
2092read_audio_data(char *buffer, unsigned char res_reg[], int *res_size)
2093{
2094 unsigned long retry_count;
2095 int result_read;
2096
2097
2098 res_reg[0] = 0;
2099 res_reg[1] = 0;
2100 *res_size = 0;
2101 result_read = 0;
2102
2103 /* Wait for the drive to tell us we have something */
2104 retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
2105 continue_read_audio_wait:
2106 while (time_before(jiffies, retry_count) && !(is_data_ready())
2107 && !(is_result_ready() || result_read)) {
2108 while (handle_sony_cd_attention());
2109
2110 sony_sleep();
2111 }
2112 if (!(is_data_ready())) {
2113 if (is_result_ready() && !result_read) {
2114 get_result(res_reg, res_size);
2115
2116 /* Read block status and continue waiting for data. */
2117 if ((res_reg[0] & 0xf0) == 0x50) {
2118 result_read = 1;
2119 goto continue_read_audio_wait;
2120 }
2121 /* Invalid data from the drive. Shut down the operation. */
2122 else if ((res_reg[0] & 0xf0) != 0x20) {
2123 printk(KERN_WARNING PFX "Got result that "
2124 "should have been error: %d\n",
2125 res_reg[0]);
2126 res_reg[0] = 0x20;
2127 res_reg[1] = SONY_BAD_DATA_ERR;
2128 *res_size = 2;
2129 }
2130 abort_read();
2131 } else {
2132 pr_debug(PFX "timeout out %d\n", __LINE__);
2133 res_reg[0] = 0x20;
2134 res_reg[1] = SONY_TIMEOUT_OP_ERR;
2135 *res_size = 2;
2136 abort_read();
2137 }
2138 } else {
2139 clear_data_ready();
2140
2141 /* If data block, then get 2340 bytes offset by 12. */
2142 if (sony_raw_data_mode) {
2143 insb(sony_cd_read_reg, buffer + CD_XA_HEAD,
2144 CD_FRAMESIZE_RAW1);
2145 } else {
2146 /* Audio gets the whole 2352 bytes. */
2147 insb(sony_cd_read_reg, buffer, CD_FRAMESIZE_RAW);
2148 }
2149
2150 /* If I haven't already gotten the result, get it now. */
2151 if (!result_read) {
2152 /* Wait for the drive to tell us we have something */
2153 retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
2154 while (time_before(jiffies, retry_count)
2155 && !(is_result_ready())) {
2156 while (handle_sony_cd_attention());
2157
2158 sony_sleep();
2159 }
2160
2161 if (!is_result_ready()) {
2162 pr_debug(PFX "timeout out %d\n", __LINE__);
2163 res_reg[0] = 0x20;
2164 res_reg[1] = SONY_TIMEOUT_OP_ERR;
2165 *res_size = 2;
2166 abort_read();
2167 return;
2168 } else {
2169 get_result(res_reg, res_size);
2170 }
2171 }
2172
2173 if ((res_reg[0] & 0xf0) == 0x50) {
2174 if ((res_reg[0] == SONY_NO_CIRC_ERR_BLK_STAT)
2175 || (res_reg[0] == SONY_NO_LECC_ERR_BLK_STAT)
2176 || (res_reg[0] == SONY_RECOV_LECC_ERR_BLK_STAT)
2177 || (res_reg[0] == SONY_NO_ERR_DETECTION_STAT)) {
2178 /* Ok, nothing to do. */
2179 } else {
2180 printk(KERN_ERR PFX "Data block error: 0x%x\n",
2181 res_reg[0]);
2182 res_reg[0] = 0x20;
2183 res_reg[1] = SONY_BAD_DATA_ERR;
2184 *res_size = 2;
2185 }
2186 } else if ((res_reg[0] & 0xf0) != 0x20) {
2187 /* The drive gave me bad status, I don't know what to do.
2188 Reset the driver and return an error. */
2189 printk(KERN_NOTICE PFX "Invalid block status: 0x%x\n",
2190 res_reg[0]);
2191 restart_on_error();
2192 res_reg[0] = 0x20;
2193 res_reg[1] = SONY_BAD_DATA_ERR;
2194 *res_size = 2;
2195 }
2196 }
2197}
2198
2199/* Perform a raw data read. This will automatically detect the
2200 track type and read the proper data (audio or data). */
2201static int read_audio(struct cdrom_read_audio *ra)
2202{
2203 int retval;
2204 unsigned char params[2];
2205 unsigned char res_reg[12];
2206 unsigned int res_size;
2207 unsigned int cframe;
2208
2209 if (down_interruptible(&sony_sem))
2210 return -ERESTARTSYS;
2211 if (!sony_spun_up)
2212 scd_spinup();
2213
2214 /* Set the drive to do raw operations. */
2215 params[0] = SONY_SD_DECODE_PARAM;
2216 params[1] = 0x06 | sony_raw_data_mode;
2217 do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
2218 params, 2, res_reg, &res_size);
2219 if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20)) {
2220 printk(KERN_ERR PFX "Unable to set decode params: 0x%2.2x\n",
2221 res_reg[1]);
2222 retval = -EIO;
2223 goto out_up;
2224 }
2225
2226 /* From here down, we have to goto exit_read_audio instead of returning
2227 because the drive parameters have to be set back to data before
2228 return. */
2229
2230 retval = 0;
2231 if (start_request(ra->addr.lba, ra->nframes)) {
2232 retval = -EIO;
2233 goto exit_read_audio;
2234 }
2235
2236 /* For every requested frame. */
2237 cframe = 0;
2238 while (cframe < ra->nframes) {
2239 read_audio_data(audio_buffer, res_reg, &res_size);
2240 if ((res_reg[0] & 0xf0) == 0x20) {
2241 if (res_reg[1] == SONY_BAD_DATA_ERR) {
2242 printk(KERN_ERR PFX "Data error on audio "
2243 "sector %d\n",
2244 ra->addr.lba + cframe);
2245 } else if (res_reg[1] == SONY_ILL_TRACK_R_ERR) {
2246 /* Illegal track type, change track types and start over. */
2247 sony_raw_data_mode =
2248 (sony_raw_data_mode) ? 0 : 1;
2249
2250 /* Set the drive mode. */
2251 params[0] = SONY_SD_DECODE_PARAM;
2252 params[1] = 0x06 | sony_raw_data_mode;
2253 do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
2254 params,
2255 2, res_reg, &res_size);
2256 if ((res_size < 2)
2257 || ((res_reg[0] & 0xf0) == 0x20)) {
2258 printk(KERN_ERR PFX "Unable to set "
2259 "decode params: 0x%2.2x\n",
2260 res_reg[1]);
2261 retval = -EIO;
2262 goto exit_read_audio;
2263 }
2264
2265 /* Restart the request on the current frame. */
2266 if (start_request
2267 (ra->addr.lba + cframe,
2268 ra->nframes - cframe)) {
2269 retval = -EIO;
2270 goto exit_read_audio;
2271 }
2272
2273 /* Don't go back to the top because don't want to get into
2274 and infinite loop. A lot of code gets duplicated, but
2275 that's no big deal, I don't guess. */
2276 read_audio_data(audio_buffer, res_reg,
2277 &res_size);
2278 if ((res_reg[0] & 0xf0) == 0x20) {
2279 if (res_reg[1] ==
2280 SONY_BAD_DATA_ERR) {
2281 printk(KERN_ERR PFX "Data error"
2282 " on audio sector %d\n",
2283 ra->addr.lba +
2284 cframe);
2285 } else {
2286 printk(KERN_ERR PFX "Error reading audio data on sector %d: %s\n",
2287 ra->addr.lba + cframe,
2288 translate_error
2289 (res_reg[1]));
2290 retval = -EIO;
2291 goto exit_read_audio;
2292 }
2293 } else if (copy_to_user(ra->buf +
2294 (CD_FRAMESIZE_RAW
2295 * cframe),
2296 audio_buffer,
2297 CD_FRAMESIZE_RAW)) {
2298 retval = -EFAULT;
2299 goto exit_read_audio;
2300 }
2301 } else {
2302 printk(KERN_ERR PFX "Error reading audio "
2303 "data on sector %d: %s\n",
2304 ra->addr.lba + cframe,
2305 translate_error(res_reg[1]));
2306 retval = -EIO;
2307 goto exit_read_audio;
2308 }
2309 } else if (copy_to_user(ra->buf + (CD_FRAMESIZE_RAW * cframe),
2310 (char *)audio_buffer,
2311 CD_FRAMESIZE_RAW)) {
2312 retval = -EFAULT;
2313 goto exit_read_audio;
2314 }
2315
2316 cframe++;
2317 }
2318
2319 get_result(res_reg, &res_size);
2320 if ((res_reg[0] & 0xf0) == 0x20) {
2321 printk(KERN_ERR PFX "Error return from audio read: %s\n",
2322 translate_error(res_reg[1]));
2323 retval = -EIO;
2324 goto exit_read_audio;
2325 }
2326
2327 exit_read_audio:
2328
2329 /* Set the drive mode back to the proper one for the disk. */
2330 params[0] = SONY_SD_DECODE_PARAM;
2331 if (!sony_xa_mode) {
2332 params[1] = 0x0f;
2333 } else {
2334 params[1] = 0x07;
2335 }
2336 do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
2337 params, 2, res_reg, &res_size);
2338 if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20)) {
2339 printk(KERN_ERR PFX "Unable to reset decode params: 0x%2.2x\n",
2340 res_reg[1]);
2341 retval = -EIO;
2342 }
2343
2344 out_up:
2345 up(&sony_sem);
2346
2347 return retval;
2348}
2349
2350static int
2351do_sony_cd_cmd_chk(const char *name,
2352 unsigned char cmd,
2353 unsigned char *params,
2354 unsigned int num_params,
2355 unsigned char *result_buffer, unsigned int *result_size)
2356{
2357 do_sony_cd_cmd(cmd, params, num_params, result_buffer,
2358 result_size);
2359 if ((*result_size < 2) || ((result_buffer[0] & 0xf0) == 0x20)) {
2360 printk(KERN_ERR PFX "Error %s (CDROM%s)\n",
2361 translate_error(result_buffer[1]), name);
2362 return -EIO;
2363 }
2364 return 0;
2365}
2366
2367/*
2368 * Uniform cdrom interface function
2369 * open the tray
2370 */
2371static int scd_tray_move(struct cdrom_device_info *cdi, int position)
2372{
2373 int retval;
2374
2375 if (down_interruptible(&sony_sem))
2376 return -ERESTARTSYS;
2377 if (position == 1 /* open tray */ ) {
2378 unsigned char res_reg[12];
2379 unsigned int res_size;
2380
2381 do_sony_cd_cmd(SONY_AUDIO_STOP_CMD, NULL, 0, res_reg,
2382 &res_size);
2383 do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0, res_reg,
2384 &res_size);
2385
2386 sony_audio_status = CDROM_AUDIO_INVALID;
2387 retval = do_sony_cd_cmd_chk("EJECT", SONY_EJECT_CMD, NULL, 0,
2388 res_reg, &res_size);
2389 } else {
2390 if (0 == scd_spinup())
2391 sony_spun_up = 1;
2392 retval = 0;
2393 }
2394 up(&sony_sem);
2395 return retval;
2396}
2397
2398/*
2399 * The big ugly ioctl handler.
2400 */
2401static int scd_audio_ioctl(struct cdrom_device_info *cdi,
2402 unsigned int cmd, void *arg)
2403{
2404 unsigned char res_reg[12];
2405 unsigned int res_size;
2406 unsigned char params[7];
2407 int i, retval;
2408
2409 if (down_interruptible(&sony_sem))
2410 return -ERESTARTSYS;
2411 switch (cmd) {
2412 case CDROMSTART: /* Spin up the drive */
2413 retval = do_sony_cd_cmd_chk("START", SONY_SPIN_UP_CMD, NULL,
2414 0, res_reg, &res_size);
2415 break;
2416
2417 case CDROMSTOP: /* Spin down the drive */
2418 do_sony_cd_cmd(SONY_AUDIO_STOP_CMD, NULL, 0, res_reg,
2419 &res_size);
2420
2421 /*
2422 * Spin the drive down, ignoring the error if the disk was
2423 * already not spinning.
2424 */
2425 sony_audio_status = CDROM_AUDIO_NO_STATUS;
2426 retval = do_sony_cd_cmd_chk("STOP", SONY_SPIN_DOWN_CMD, NULL,
2427 0, res_reg, &res_size);
2428 break;
2429
2430 case CDROMPAUSE: /* Pause the drive */
2431 if (do_sony_cd_cmd_chk
2432 ("PAUSE", SONY_AUDIO_STOP_CMD, NULL, 0, res_reg,
2433 &res_size)) {
2434 retval = -EIO;
2435 break;
2436 }
2437 /* Get the current position and save it for resuming */
2438 if (read_subcode() < 0) {
2439 retval = -EIO;
2440 break;
2441 }
2442 cur_pos_msf[0] = last_sony_subcode.abs_msf[0];
2443 cur_pos_msf[1] = last_sony_subcode.abs_msf[1];
2444 cur_pos_msf[2] = last_sony_subcode.abs_msf[2];
2445 sony_audio_status = CDROM_AUDIO_PAUSED;
2446 retval = 0;
2447 break;
2448
2449 case CDROMRESUME: /* Start the drive after being paused */
2450 if (sony_audio_status != CDROM_AUDIO_PAUSED) {
2451 retval = -EINVAL;
2452 break;
2453 }
2454
2455 do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg,
2456 &res_size);
2457
2458 /* Start the drive at the saved position. */
2459 params[1] = int_to_bcd(cur_pos_msf[0]);
2460 params[2] = int_to_bcd(cur_pos_msf[1]);
2461 params[3] = int_to_bcd(cur_pos_msf[2]);
2462 params[4] = int_to_bcd(final_pos_msf[0]);
2463 params[5] = int_to_bcd(final_pos_msf[1]);
2464 params[6] = int_to_bcd(final_pos_msf[2]);
2465 params[0] = 0x03;
2466 if (do_sony_cd_cmd_chk
2467 ("RESUME", SONY_AUDIO_PLAYBACK_CMD, params, 7, res_reg,
2468 &res_size) < 0) {
2469 retval = -EIO;
2470 break;
2471 }
2472 sony_audio_status = CDROM_AUDIO_PLAY;
2473 retval = 0;
2474 break;
2475
2476 case CDROMPLAYMSF: /* Play starting at the given MSF address. */
2477 do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg,
2478 &res_size);
2479
2480 /* The parameters are given in int, must be converted */
2481 for (i = 1; i < 7; i++) {
2482 params[i] =
2483 int_to_bcd(((unsigned char *) arg)[i - 1]);
2484 }
2485 params[0] = 0x03;
2486 if (do_sony_cd_cmd_chk
2487 ("PLAYMSF", SONY_AUDIO_PLAYBACK_CMD, params, 7,
2488 res_reg, &res_size) < 0) {
2489 retval = -EIO;
2490 break;
2491 }
2492
2493 /* Save the final position for pauses and resumes */
2494 final_pos_msf[0] = bcd_to_int(params[4]);
2495 final_pos_msf[1] = bcd_to_int(params[5]);
2496 final_pos_msf[2] = bcd_to_int(params[6]);
2497 sony_audio_status = CDROM_AUDIO_PLAY;
2498 retval = 0;
2499 break;
2500
2501 case CDROMREADTOCHDR: /* Read the table of contents header */
2502 {
2503 struct cdrom_tochdr *hdr;
2504
2505 sony_get_toc();
2506 if (!sony_toc_read) {
2507 retval = -EIO;
2508 break;
2509 }
2510
2511 hdr = (struct cdrom_tochdr *) arg;
2512 hdr->cdth_trk0 = sony_toc.first_track_num;
2513 hdr->cdth_trk1 = sony_toc.last_track_num;
2514 }
2515 retval = 0;
2516 break;
2517
2518 case CDROMREADTOCENTRY: /* Read a given table of contents entry */
2519 {
2520 struct cdrom_tocentry *entry;
2521 int track_idx;
2522 unsigned char *msf_val = NULL;
2523
2524 sony_get_toc();
2525 if (!sony_toc_read) {
2526 retval = -EIO;
2527 break;
2528 }
2529
2530 entry = (struct cdrom_tocentry *) arg;
2531
2532 track_idx = find_track(entry->cdte_track);
2533 if (track_idx < 0) {
2534 retval = -EINVAL;
2535 break;
2536 }
2537
2538 entry->cdte_adr =
2539 sony_toc.tracks[track_idx].address;
2540 entry->cdte_ctrl =
2541 sony_toc.tracks[track_idx].control;
2542 msf_val =
2543 sony_toc.tracks[track_idx].track_start_msf;
2544
2545 /* Logical buffer address or MSF format requested? */
2546 if (entry->cdte_format == CDROM_LBA) {
2547 entry->cdte_addr.lba = msf_to_log(msf_val);
2548 } else if (entry->cdte_format == CDROM_MSF) {
2549 entry->cdte_addr.msf.minute = *msf_val;
2550 entry->cdte_addr.msf.second =
2551 *(msf_val + 1);
2552 entry->cdte_addr.msf.frame =
2553 *(msf_val + 2);
2554 }
2555 }
2556 retval = 0;
2557 break;
2558
2559 case CDROMPLAYTRKIND: /* Play a track. This currently ignores index. */
2560 {
2561 struct cdrom_ti *ti = (struct cdrom_ti *) arg;
2562 int track_idx;
2563
2564 sony_get_toc();
2565 if (!sony_toc_read) {
2566 retval = -EIO;
2567 break;
2568 }
2569
2570 if ((ti->cdti_trk0 < sony_toc.first_track_num)
2571 || (ti->cdti_trk0 > sony_toc.last_track_num)
2572 || (ti->cdti_trk1 < ti->cdti_trk0)) {
2573 retval = -EINVAL;
2574 break;
2575 }
2576
2577 track_idx = find_track(ti->cdti_trk0);
2578 if (track_idx < 0) {
2579 retval = -EINVAL;
2580 break;
2581 }
2582 params[1] =
2583 int_to_bcd(sony_toc.tracks[track_idx].
2584 track_start_msf[0]);
2585 params[2] =
2586 int_to_bcd(sony_toc.tracks[track_idx].
2587 track_start_msf[1]);
2588 params[3] =
2589 int_to_bcd(sony_toc.tracks[track_idx].
2590 track_start_msf[2]);
2591
2592 /*
2593 * If we want to stop after the last track, use the lead-out
2594 * MSF to do that.
2595 */
2596 if (ti->cdti_trk1 >= sony_toc.last_track_num) {
2597 track_idx = find_track(CDROM_LEADOUT);
2598 } else {
2599 track_idx = find_track(ti->cdti_trk1 + 1);
2600 }
2601 if (track_idx < 0) {
2602 retval = -EINVAL;
2603 break;
2604 }
2605 params[4] =
2606 int_to_bcd(sony_toc.tracks[track_idx].
2607 track_start_msf[0]);
2608 params[5] =
2609 int_to_bcd(sony_toc.tracks[track_idx].
2610 track_start_msf[1]);
2611 params[6] =
2612 int_to_bcd(sony_toc.tracks[track_idx].
2613 track_start_msf[2]);
2614 params[0] = 0x03;
2615
2616 do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg,
2617 &res_size);
2618
2619 do_sony_cd_cmd(SONY_AUDIO_PLAYBACK_CMD, params, 7,
2620 res_reg, &res_size);
2621
2622 if ((res_size < 2)
2623 || ((res_reg[0] & 0xf0) == 0x20)) {
2624 printk(KERN_ERR PFX
2625 "Params: %x %x %x %x %x %x %x\n",
2626 params[0], params[1], params[2],
2627 params[3], params[4], params[5],
2628 params[6]);
2629 printk(KERN_ERR PFX
2630 "Error %s (CDROMPLAYTRKIND)\n",
2631 translate_error(res_reg[1]));
2632 retval = -EIO;
2633 break;
2634 }
2635
2636 /* Save the final position for pauses and resumes */
2637 final_pos_msf[0] = bcd_to_int(params[4]);
2638 final_pos_msf[1] = bcd_to_int(params[5]);
2639 final_pos_msf[2] = bcd_to_int(params[6]);
2640 sony_audio_status = CDROM_AUDIO_PLAY;
2641 retval = 0;
2642 break;
2643 }
2644
2645 case CDROMVOLCTRL: /* Volume control. What volume does this change, anyway? */
2646 {
2647 struct cdrom_volctrl *volctrl =
2648 (struct cdrom_volctrl *) arg;
2649
2650 params[0] = SONY_SD_AUDIO_VOLUME;
2651 params[1] = volctrl->channel0;
2652 params[2] = volctrl->channel1;
2653 retval = do_sony_cd_cmd_chk("VOLCTRL",
2654 SONY_SET_DRIVE_PARAM_CMD,
2655 params, 3, res_reg,
2656 &res_size);
2657 break;
2658 }
2659 case CDROMSUBCHNL: /* Get subchannel info */
2660 retval = sony_get_subchnl_info((struct cdrom_subchnl *) arg);
2661 break;
2662
2663 default:
2664 retval = -EINVAL;
2665 break;
2666 }
2667 up(&sony_sem);
2668 return retval;
2669}
2670
2671static int scd_dev_ioctl(struct cdrom_device_info *cdi,
2672 unsigned int cmd, unsigned long arg)
2673{
2674 void __user *argp = (void __user *)arg;
2675 int retval;
2676
2677 if (down_interruptible(&sony_sem))
2678 return -ERESTARTSYS;
2679 switch (cmd) {
2680 case CDROMREADAUDIO: /* Read 2352 byte audio tracks and 2340 byte
2681 raw data tracks. */
2682 {
2683 struct cdrom_read_audio ra;
2684
2685
2686 sony_get_toc();
2687 if (!sony_toc_read) {
2688 retval = -EIO;
2689 break;
2690 }
2691
2692 if (copy_from_user(&ra, argp, sizeof(ra))) {
2693 retval = -EFAULT;
2694 break;
2695 }
2696
2697 if (ra.nframes == 0) {
2698 retval = 0;
2699 break;
2700 }
2701
2702 if (!access_ok(VERIFY_WRITE, ra.buf,
2703 CD_FRAMESIZE_RAW * ra.nframes))
2704 return -EFAULT;
2705
2706 if (ra.addr_format == CDROM_LBA) {
2707 if ((ra.addr.lba >=
2708 sony_toc.lead_out_start_lba)
2709 || (ra.addr.lba + ra.nframes >=
2710 sony_toc.lead_out_start_lba)) {
2711 retval = -EINVAL;
2712 break;
2713 }
2714 } else if (ra.addr_format == CDROM_MSF) {
2715 if ((ra.addr.msf.minute >= 75)
2716 || (ra.addr.msf.second >= 60)
2717 || (ra.addr.msf.frame >= 75)) {
2718 retval = -EINVAL;
2719 break;
2720 }
2721
2722 ra.addr.lba = ((ra.addr.msf.minute * 4500)
2723 + (ra.addr.msf.second * 75)
2724 + ra.addr.msf.frame);
2725 if ((ra.addr.lba >=
2726 sony_toc.lead_out_start_lba)
2727 || (ra.addr.lba + ra.nframes >=
2728 sony_toc.lead_out_start_lba)) {
2729 retval = -EINVAL;
2730 break;
2731 }
2732
2733 /* I know, this can go negative on an unsigned. However,
2734 the first thing done to the data is to add this value,
2735 so this should compensate and allow direct msf access. */
2736 ra.addr.lba -= LOG_START_OFFSET;
2737 } else {
2738 retval = -EINVAL;
2739 break;
2740 }
2741
2742 retval = read_audio(&ra);
2743 break;
2744 }
2745 retval = 0;
2746 break;
2747
2748 default:
2749 retval = -EINVAL;
2750 }
2751 up(&sony_sem);
2752 return retval;
2753}
2754
2755static int scd_spinup(void)
2756{
2757 unsigned char res_reg[12];
2758 unsigned int res_size;
2759 int num_spin_ups;
2760
2761 num_spin_ups = 0;
2762
2763 respinup_on_open:
2764 do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, &res_size);
2765
2766 /* The drive sometimes returns error 0. I don't know why, but ignore
2767 it. It seems to mean the drive has already done the operation. */
2768 if ((res_size < 2) || ((res_reg[0] != 0) && (res_reg[1] != 0))) {
2769 printk(KERN_ERR PFX "%s error (scd_open, spin up)\n",
2770 translate_error(res_reg[1]));
2771 return 1;
2772 }
2773
2774 do_sony_cd_cmd(SONY_READ_TOC_CMD, NULL, 0, res_reg, &res_size);
2775
2776 /* The drive sometimes returns error 0. I don't know why, but ignore
2777 it. It seems to mean the drive has already done the operation. */
2778 if ((res_size < 2) || ((res_reg[0] != 0) && (res_reg[1] != 0))) {
2779 /* If the drive is already playing, it's ok. */
2780 if ((res_reg[1] == SONY_AUDIO_PLAYING_ERR)
2781 || (res_reg[1] == 0)) {
2782 return 0;
2783 }
2784
2785 /* If the drive says it is not spun up (even though we just did it!)
2786 then retry the operation at least a few times. */
2787 if ((res_reg[1] == SONY_NOT_SPIN_ERR)
2788 && (num_spin_ups < MAX_CDU31A_RETRIES)) {
2789 num_spin_ups++;
2790 goto respinup_on_open;
2791 }
2792
2793 printk(KERN_ERR PFX "Error %s (scd_open, read toc)\n",
2794 translate_error(res_reg[1]));
2795 do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0, res_reg,
2796 &res_size);
2797 return 1;
2798 }
2799 return 0;
2800}
2801
2802/*
2803 * Open the drive for operations. Spin the drive up and read the table of
2804 * contents if these have not already been done.
2805 */
2806static int scd_open(struct cdrom_device_info *cdi, int purpose)
2807{
2808 unsigned char res_reg[12];
2809 unsigned int res_size;
2810 unsigned char params[2];
2811
2812 if (purpose == 1) {
2813 /* Open for IOCTLs only - no media check */
2814 sony_usage++;
2815 return 0;
2816 }
2817
2818 if (sony_usage == 0) {
2819 if (scd_spinup() != 0)
2820 return -EIO;
2821 sony_get_toc();
2822 if (!sony_toc_read) {
2823 do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0,
2824 res_reg, &res_size);
2825 return -EIO;
2826 }
2827
2828 /* For XA on the CDU31A only, we have to do special reads.
2829 The CDU33A handles XA automagically. */
2830 /* if ( (sony_toc.disk_type == SONY_XA_DISK_TYPE) */
2831 if ((sony_toc.disk_type != 0x00)
2832 && (!is_double_speed)) {
2833 params[0] = SONY_SD_DECODE_PARAM;
2834 params[1] = 0x07;
2835 do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
2836 params, 2, res_reg, &res_size);
2837 if ((res_size < 2)
2838 || ((res_reg[0] & 0xf0) == 0x20)) {
2839 printk(KERN_WARNING PFX "Unable to set "
2840 "XA params: 0x%2.2x\n", res_reg[1]);
2841 }
2842 sony_xa_mode = 1;
2843 }
2844 /* A non-XA disk. Set the parms back if necessary. */
2845 else if (sony_xa_mode) {
2846 params[0] = SONY_SD_DECODE_PARAM;
2847 params[1] = 0x0f;
2848 do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
2849 params, 2, res_reg, &res_size);
2850 if ((res_size < 2)
2851 || ((res_reg[0] & 0xf0) == 0x20)) {
2852 printk(KERN_WARNING PFX "Unable to reset "
2853 "XA params: 0x%2.2x\n", res_reg[1]);
2854 }
2855 sony_xa_mode = 0;
2856 }
2857
2858 sony_spun_up = 1;
2859 }
2860
2861 sony_usage++;
2862
2863 return 0;
2864}
2865
2866
2867/*
2868 * Close the drive. Spin it down if no task is using it. The spin
2869 * down will fail if playing audio, so audio play is OK.
2870 */
2871static void scd_release(struct cdrom_device_info *cdi)
2872{
2873 if (sony_usage == 1) {
2874 unsigned char res_reg[12];
2875 unsigned int res_size;
2876
2877 do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0, res_reg,
2878 &res_size);
2879
2880 sony_spun_up = 0;
2881 }
2882 sony_usage--;
2883}
2884
2885static struct cdrom_device_ops scd_dops = {
2886 .open = scd_open,
2887 .release = scd_release,
2888 .drive_status = scd_drive_status,
2889 .media_changed = scd_media_changed,
2890 .tray_move = scd_tray_move,
2891 .lock_door = scd_lock_door,
2892 .select_speed = scd_select_speed,
2893 .get_last_session = scd_get_last_session,
2894 .get_mcn = scd_get_mcn,
2895 .reset = scd_reset,
2896 .audio_ioctl = scd_audio_ioctl,
2897 .dev_ioctl = scd_dev_ioctl,
2898 .capability = CDC_OPEN_TRAY | CDC_CLOSE_TRAY | CDC_LOCK |
2899 CDC_SELECT_SPEED | CDC_MULTI_SESSION |
2900 CDC_MCN | CDC_MEDIA_CHANGED | CDC_PLAY_AUDIO |
2901 CDC_RESET | CDC_IOCTLS | CDC_DRIVE_STATUS,
2902 .n_minors = 1,
2903};
2904
2905static struct cdrom_device_info scd_info = {
2906 .ops = &scd_dops,
2907 .speed = 2,
2908 .capacity = 1,
2909 .name = "cdu31a"
2910};
2911
2912static int scd_block_open(struct inode *inode, struct file *file)
2913{
2914 return cdrom_open(&scd_info, inode, file);
2915}
2916
2917static int scd_block_release(struct inode *inode, struct file *file)
2918{
2919 return cdrom_release(&scd_info, file);
2920}
2921
2922static int scd_block_ioctl(struct inode *inode, struct file *file,
2923 unsigned cmd, unsigned long arg)
2924{
2925 int retval;
2926
2927 /* The eject and close commands should be handled by Uniform CD-ROM
2928 * driver - but I always got hard lockup instead of eject
2929 * until I put this here.
2930 */
2931 switch (cmd) {
2932 case CDROMEJECT:
2933 scd_lock_door(&scd_info, 0);
2934 retval = scd_tray_move(&scd_info, 1);
2935 break;
2936 case CDROMCLOSETRAY:
2937 retval = scd_tray_move(&scd_info, 0);
2938 break;
2939 default:
2940 retval = cdrom_ioctl(file, &scd_info, inode, cmd, arg);
2941 }
2942 return retval;
2943}
2944
2945static int scd_block_media_changed(struct gendisk *disk)
2946{
2947 return cdrom_media_changed(&scd_info);
2948}
2949
2950struct block_device_operations scd_bdops =
2951{
2952 .owner = THIS_MODULE,
2953 .open = scd_block_open,
2954 .release = scd_block_release,
2955 .ioctl = scd_block_ioctl,
2956 .media_changed = scd_block_media_changed,
2957};
2958
2959static struct gendisk *scd_gendisk;
2960
2961/* The different types of disc loading mechanisms supported */
2962static char *load_mech[] __initdata =
2963 { "caddy", "tray", "pop-up", "unknown" };
2964
2965static int __init
2966get_drive_configuration(unsigned short base_io,
2967 unsigned char res_reg[], unsigned int *res_size)
2968{
2969 unsigned long retry_count;
2970
2971
2972 if (!request_region(base_io, 4, "cdu31a"))
2973 return 0;
2974
2975 /* Set the base address */
2976 cdu31a_port = base_io;
2977
2978 /* Set up all the register locations */
2979 sony_cd_cmd_reg = cdu31a_port + SONY_CMD_REG_OFFSET;
2980 sony_cd_param_reg = cdu31a_port + SONY_PARAM_REG_OFFSET;
2981 sony_cd_write_reg = cdu31a_port + SONY_WRITE_REG_OFFSET;
2982 sony_cd_control_reg = cdu31a_port + SONY_CONTROL_REG_OFFSET;
2983 sony_cd_status_reg = cdu31a_port + SONY_STATUS_REG_OFFSET;
2984 sony_cd_result_reg = cdu31a_port + SONY_RESULT_REG_OFFSET;
2985 sony_cd_read_reg = cdu31a_port + SONY_READ_REG_OFFSET;
2986 sony_cd_fifost_reg = cdu31a_port + SONY_FIFOST_REG_OFFSET;
2987
2988 /*
2989 * Check to see if anything exists at the status register location.
2990 * I don't know if this is a good way to check, but it seems to work
2991 * ok for me.
2992 */
2993 if (read_status_register() != 0xff) {
2994 /*
2995 * Reset the drive and wait for attention from it (to say it's reset).
2996 * If you don't wait, the next operation will probably fail.
2997 */
2998 reset_drive();
2999 retry_count = jiffies + SONY_RESET_TIMEOUT;
3000 while (time_before(jiffies, retry_count)
3001 && (!is_attention())) {
3002 sony_sleep();
3003 }
3004
3005#if 0
3006 /* If attention is never seen probably not a CDU31a present */
3007 if (!is_attention()) {
3008 res_reg[0] = 0x20;
3009 goto out_err;
3010 }
3011#endif
3012
3013 /*
3014 * Get the drive configuration.
3015 */
3016 do_sony_cd_cmd(SONY_REQ_DRIVE_CONFIG_CMD,
3017 NULL,
3018 0, (unsigned char *) res_reg, res_size);
3019 if (*res_size <= 2 || (res_reg[0] & 0xf0) != 0)
3020 goto out_err;
3021 return 1;
3022 }
3023
3024 /* Return an error */
3025 res_reg[0] = 0x20;
3026out_err:
3027 release_region(cdu31a_port, 4);
3028 cdu31a_port = 0;
3029 return 0;
3030}
3031
3032#ifndef MODULE
3033/*
3034 * Set up base I/O and interrupts, called from main.c.
3035 */
3036
3037static int __init cdu31a_setup(char *strings)
3038{
3039 int ints[4];
3040
3041 (void) get_options(strings, ARRAY_SIZE(ints), ints);
3042
3043 if (ints[0] > 0) {
3044 cdu31a_port = ints[1];
3045 }
3046 if (ints[0] > 1) {
3047 cdu31a_irq = ints[2];
3048 }
3049 if ((strings != NULL) && (*strings != '\0')) {
3050 if (strcmp(strings, "PAS") == 0) {
3051 sony_pas_init = 1;
3052 } else {
3053 printk(KERN_NOTICE PFX "Unknown interface type: %s\n",
3054 strings);
3055 }
3056 }
3057
3058 return 1;
3059}
3060
3061__setup("cdu31a=", cdu31a_setup);
3062
3063#endif
3064
3065/*
3066 * Initialize the driver.
3067 */
3068int __init cdu31a_init(void)
3069{
3070 struct s_sony_drive_config drive_config;
3071 struct gendisk *disk;
3072 int deficiency = 0;
3073 unsigned int res_size;
3074 char msg[255];
3075 char buf[40];
3076 int i;
3077 int tmp_irq;
3078
3079 /*
3080 * According to Alex Freed (freed@europa.orion.adobe.com), this is
3081 * required for the Fusion CD-16 package. If the sound driver is
3082 * loaded, it should work fine, but just in case...
3083 *
3084 * The following turn on the CD-ROM interface for a Fusion CD-16.
3085 */
3086 if (sony_pas_init) {
3087 outb(0xbc, 0x9a01);
3088 outb(0xe2, 0x9a01);
3089 }
3090
3091 /* Setting the base I/O address to 0xffff will disable it. */
3092 if (cdu31a_port == 0xffff)
3093 goto errout3;
3094
3095 if (cdu31a_port != 0) {
3096 /* Need IRQ 0 because we can't sleep here. */
3097 tmp_irq = cdu31a_irq;
3098 cdu31a_irq = 0;
3099 if (!get_drive_configuration(cdu31a_port,
3100 drive_config.exec_status,
3101 &res_size))
3102 goto errout3;
3103 cdu31a_irq = tmp_irq;
3104 } else {
3105 cdu31a_irq = 0;
3106 for (i = 0; cdu31a_addresses[i].base; i++) {
3107 if (get_drive_configuration(cdu31a_addresses[i].base,
3108 drive_config.exec_status,
3109 &res_size)) {
3110 cdu31a_irq = cdu31a_addresses[i].int_num;
3111 break;
3112 }
3113 }
3114 if (!cdu31a_port)
3115 goto errout3;
3116 }
3117
3118 if (register_blkdev(MAJOR_NR, "cdu31a"))
3119 goto errout2;
3120
3121 disk = alloc_disk(1);
3122 if (!disk)
3123 goto errout1;
3124 disk->major = MAJOR_NR;
3125 disk->first_minor = 0;
3126 sprintf(disk->disk_name, "cdu31a");
3127 disk->fops = &scd_bdops;
3128 disk->flags = GENHD_FL_CD;
3129
3130 if (SONY_HWC_DOUBLE_SPEED(drive_config))
3131 is_double_speed = 1;
3132
3133 tmp_irq = cdu31a_irq; /* Need IRQ 0 because we can't sleep here. */
3134 cdu31a_irq = 0;
3135
3136 sony_speed = is_double_speed; /* Set 2X drives to 2X by default */
3137 set_drive_params(sony_speed);
3138
3139 cdu31a_irq = tmp_irq;
3140
3141 if (cdu31a_irq > 0) {
3142 if (request_irq
3143 (cdu31a_irq, cdu31a_interrupt, SA_INTERRUPT,
3144 "cdu31a", NULL)) {
3145 printk(KERN_WARNING PFX "Unable to grab IRQ%d for "
3146 "the CDU31A driver\n", cdu31a_irq);
3147 cdu31a_irq = 0;
3148 }
3149 }
3150
3151 sprintf(msg, "Sony I/F CDROM : %8.8s %16.16s %8.8s\n",
3152 drive_config.vendor_id,
3153 drive_config.product_id,
3154 drive_config.product_rev_level);
3155 sprintf(buf, " Capabilities: %s",
3156 load_mech[SONY_HWC_GET_LOAD_MECH(drive_config)]);
3157 strcat(msg, buf);
3158 if (SONY_HWC_AUDIO_PLAYBACK(drive_config))
3159 strcat(msg, ", audio");
3160 else
3161 deficiency |= CDC_PLAY_AUDIO;
3162 if (SONY_HWC_EJECT(drive_config))
3163 strcat(msg, ", eject");
3164 else
3165 deficiency |= CDC_OPEN_TRAY;
3166 if (SONY_HWC_LED_SUPPORT(drive_config))
3167 strcat(msg, ", LED");
3168 if (SONY_HWC_ELECTRIC_VOLUME(drive_config))
3169 strcat(msg, ", elec. Vol");
3170 if (SONY_HWC_ELECTRIC_VOLUME_CTL(drive_config))
3171 strcat(msg, ", sep. Vol");
3172 if (is_double_speed)
3173 strcat(msg, ", double speed");
3174 else
3175 deficiency |= CDC_SELECT_SPEED;
3176 if (cdu31a_irq > 0) {
3177 sprintf(buf, ", irq %d", cdu31a_irq);
3178 strcat(msg, buf);
3179 }
3180 strcat(msg, "\n");
3181 printk(KERN_INFO PFX "%s",msg);
3182
3183 cdu31a_queue = blk_init_queue(do_cdu31a_request, &cdu31a_lock);
3184 if (!cdu31a_queue)
3185 goto errout0;
3186 blk_queue_hardsect_size(cdu31a_queue, 2048);
3187
3188 init_timer(&cdu31a_abort_timer);
3189 cdu31a_abort_timer.function = handle_abort_timeout;
3190
3191 scd_info.mask = deficiency;
3192 scd_gendisk = disk;
3193 if (register_cdrom(&scd_info))
3194 goto err;
3195 disk->queue = cdu31a_queue;
3196 add_disk(disk);
3197
3198 disk_changed = 1;
3199 return 0;
3200
3201err:
3202 blk_cleanup_queue(cdu31a_queue);
3203errout0:
3204 if (cdu31a_irq)
3205 free_irq(cdu31a_irq, NULL);
3206 printk(KERN_ERR PFX "Unable to register with Uniform cdrom driver\n");
3207 put_disk(disk);
3208errout1:
3209 if (unregister_blkdev(MAJOR_NR, "cdu31a")) {
3210 printk(KERN_WARNING PFX "Can't unregister block device\n");
3211 }
3212errout2:
3213 release_region(cdu31a_port, 4);
3214errout3:
3215 return -EIO;
3216}
3217
3218
3219void __exit cdu31a_exit(void)
3220{
3221 del_gendisk(scd_gendisk);
3222 put_disk(scd_gendisk);
3223 if (unregister_cdrom(&scd_info)) {
3224 printk(KERN_WARNING PFX "Can't unregister from Uniform "
3225 "cdrom driver\n");
3226 return;
3227 }
3228 if ((unregister_blkdev(MAJOR_NR, "cdu31a") == -EINVAL)) {
3229 printk(KERN_WARNING PFX "Can't unregister\n");
3230 return;
3231 }
3232
3233 blk_cleanup_queue(cdu31a_queue);
3234
3235 if (cdu31a_irq > 0)
3236 free_irq(cdu31a_irq, NULL);
3237
3238 release_region(cdu31a_port, 4);
3239 printk(KERN_INFO PFX "module released.\n");
3240}
3241
3242#ifdef MODULE
3243module_init(cdu31a_init);
3244#endif
3245module_exit(cdu31a_exit);
3246
3247MODULE_LICENSE("GPL");
3248MODULE_ALIAS_BLOCKDEV_MAJOR(CDU31A_CDROM_MAJOR);
diff --git a/drivers/cdrom/cdu31a.h b/drivers/cdrom/cdu31a.h
new file mode 100644
index 000000000000..61d4768c412e
--- /dev/null
+++ b/drivers/cdrom/cdu31a.h
@@ -0,0 +1,411 @@
1/*
2 * Definitions for a Sony interface CDROM drive.
3 *
4 * Corey Minyard (minyard@wf-rch.cirr.com)
5 *
6 * Copyright (C) 1993 Corey Minyard
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 */
23
24/*
25 * General defines.
26 */
27#define SONY_XA_DISK_TYPE 0x20
28
29/*
30 * Offsets (from the base address) and bits for the various write registers
31 * of the drive.
32 */
33#define SONY_CMD_REG_OFFSET 0
34#define SONY_PARAM_REG_OFFSET 1
35#define SONY_WRITE_REG_OFFSET 2
36#define SONY_CONTROL_REG_OFFSET 3
37# define SONY_ATTN_CLR_BIT 0x01
38# define SONY_RES_RDY_CLR_BIT 0x02
39# define SONY_DATA_RDY_CLR_BIT 0x04
40# define SONY_ATTN_INT_EN_BIT 0x08
41# define SONY_RES_RDY_INT_EN_BIT 0x10
42# define SONY_DATA_RDY_INT_EN_BIT 0x20
43# define SONY_PARAM_CLR_BIT 0x40
44# define SONY_DRIVE_RESET_BIT 0x80
45
46/*
47 * Offsets (from the base address) and bits for the various read registers
48 * of the drive.
49 */
50#define SONY_STATUS_REG_OFFSET 0
51# define SONY_ATTN_BIT 0x01
52# define SONY_RES_RDY_BIT 0x02
53# define SONY_DATA_RDY_BIT 0x04
54# define SONY_ATTN_INT_ST_BIT 0x08
55# define SONY_RES_RDY_INT_ST_BIT 0x10
56# define SONY_DATA_RDY_INT_ST_BIT 0x20
57# define SONY_DATA_REQUEST_BIT 0x40
58# define SONY_BUSY_BIT 0x80
59#define SONY_RESULT_REG_OFFSET 1
60#define SONY_READ_REG_OFFSET 2
61#define SONY_FIFOST_REG_OFFSET 3
62# define SONY_PARAM_WRITE_RDY_BIT 0x01
63# define SONY_PARAM_REG_EMPTY_BIT 0x02
64# define SONY_RES_REG_NOT_EMP_BIT 0x04
65# define SONY_RES_REG_FULL_BIT 0x08
66
67#define LOG_START_OFFSET 150 /* Offset of first logical sector */
68
69#define SONY_DETECT_TIMEOUT (8*HZ/10) /* Maximum amount of time
70 that drive detection code
71 will wait for response
72 from drive (in 1/100th's
73 of seconds). */
74
75#define SONY_JIFFIES_TIMEOUT (10*HZ) /* Maximum number of times the
76 drive will wait/try for an
77 operation */
78#define SONY_RESET_TIMEOUT HZ /* Maximum number of times the
79 drive will wait/try a reset
80 operation */
81#define SONY_READY_RETRIES 20000 /* How many times to retry a
82 spin waiting for a register
83 to come ready */
84
85#define MAX_CDU31A_RETRIES 3 /* How many times to retry an
86 operation */
87
88/* Commands to request or set drive control parameters and disc information */
89#define SONY_REQ_DRIVE_CONFIG_CMD 0x00 /* Returns s_sony_drive_config */
90#define SONY_REQ_DRIVE_MODE_CMD 0x01
91#define SONY_REQ_DRIVE_PARAM_CMD 0x02
92#define SONY_REQ_MECH_STATUS_CMD 0x03
93#define SONY_REQ_AUDIO_STATUS_CMD 0x04
94#define SONY_SET_DRIVE_PARAM_CMD 0x10
95#define SONY_REQ_TOC_DATA_CMD 0x20 /* Returns s_sony_toc */
96#define SONY_REQ_SUBCODE_ADDRESS_CMD 0x21 /* Returns s_sony_subcode */
97#define SONY_REQ_UPC_EAN_CMD 0x22
98#define SONY_REQ_ISRC_CMD 0x23
99#define SONY_REQ_TOC_DATA_SPEC_CMD 0x24 /* Returns s_sony_session_toc */
100
101/* Commands to request information from the drive */
102#define SONY_READ_TOC_CMD 0x30 /* let the drive firmware grab the TOC */
103#define SONY_SEEK_CMD 0x31
104#define SONY_READ_CMD 0x32
105#define SONY_READ_BLKERR_STAT_CMD 0x34
106#define SONY_ABORT_CMD 0x35
107#define SONY_READ_TOC_SPEC_CMD 0x36
108
109/* Commands to control audio */
110#define SONY_AUDIO_PLAYBACK_CMD 0x40
111#define SONY_AUDIO_STOP_CMD 0x41
112#define SONY_AUDIO_SCAN_CMD 0x42
113
114/* Miscellaneous control commands */
115#define SONY_EJECT_CMD 0x50
116#define SONY_SPIN_UP_CMD 0x51
117#define SONY_SPIN_DOWN_CMD 0x52
118
119/* Diagnostic commands */
120#define SONY_WRITE_BUFFER_CMD 0x60
121#define SONY_READ_BUFFER_CMD 0x61
122#define SONY_DIAGNOSTICS_CMD 0x62
123
124
125/*
126 * The following are command parameters for the set drive parameter command
127 */
128#define SONY_SD_DECODE_PARAM 0x00
129#define SONY_SD_INTERFACE_PARAM 0x01
130#define SONY_SD_BUFFERING_PARAM 0x02
131#define SONY_SD_AUDIO_PARAM 0x03
132#define SONY_SD_AUDIO_VOLUME 0x04
133#define SONY_SD_MECH_CONTROL 0x05
134#define SONY_SD_AUTO_SPIN_DOWN_TIME 0x06
135
136/*
137 * The following are parameter bits for the mechanical control command
138 */
139#define SONY_AUTO_SPIN_UP_BIT 0x01
140#define SONY_AUTO_EJECT_BIT 0x02
141#define SONY_DOUBLE_SPEED_BIT 0x04
142
143/*
144 * The following extract information from the drive configuration about
145 * the drive itself.
146 */
147#define SONY_HWC_GET_LOAD_MECH(c) (c.hw_config[0] & 0x03)
148#define SONY_HWC_EJECT(c) (c.hw_config[0] & 0x04)
149#define SONY_HWC_LED_SUPPORT(c) (c.hw_config[0] & 0x08)
150#define SONY_HWC_DOUBLE_SPEED(c) (c.hw_config[0] & 0x10)
151#define SONY_HWC_GET_BUF_MEM_SIZE(c) ((c.hw_config[0] & 0xc0) >> 6)
152#define SONY_HWC_AUDIO_PLAYBACK(c) (c.hw_config[1] & 0x01)
153#define SONY_HWC_ELECTRIC_VOLUME(c) (c.hw_config[1] & 0x02)
154#define SONY_HWC_ELECTRIC_VOLUME_CTL(c) (c.hw_config[1] & 0x04)
155
156#define SONY_HWC_CADDY_LOAD_MECH 0x00
157#define SONY_HWC_TRAY_LOAD_MECH 0x01
158#define SONY_HWC_POPUP_LOAD_MECH 0x02
159#define SONY_HWC_UNKWN_LOAD_MECH 0x03
160
161#define SONY_HWC_8KB_BUFFER 0x00
162#define SONY_HWC_32KB_BUFFER 0x01
163#define SONY_HWC_64KB_BUFFER 0x02
164#define SONY_HWC_UNKWN_BUFFER 0x03
165
166/*
167 * This is the complete status returned from the drive configuration request
168 * command.
169 */
170struct s_sony_drive_config
171{
172 unsigned char exec_status[2];
173 char vendor_id[8];
174 char product_id[16];
175 char product_rev_level[8];
176 unsigned char hw_config[2];
177};
178
179/* The following is returned from the request subcode address command */
180struct s_sony_subcode
181{
182 unsigned char exec_status[2];
183 unsigned char address :4;
184 unsigned char control :4;
185 unsigned char track_num;
186 unsigned char index_num;
187 unsigned char rel_msf[3];
188 unsigned char reserved1;
189 unsigned char abs_msf[3];
190};
191
192#define MAX_TRACKS 100 /* The maximum tracks a disk may have. */
193/*
194 * The following is returned from the request TOC (Table Of Contents) command.
195 * (last_track_num-first_track_num+1) values are valid in tracks.
196 */
197struct s_sony_toc
198{
199 unsigned char exec_status[2];
200 unsigned char address0 :4;
201 unsigned char control0 :4;
202 unsigned char point0;
203 unsigned char first_track_num;
204 unsigned char disk_type;
205 unsigned char dummy0;
206 unsigned char address1 :4;
207 unsigned char control1 :4;
208 unsigned char point1;
209 unsigned char last_track_num;
210 unsigned char dummy1;
211 unsigned char dummy2;
212 unsigned char address2 :4;
213 unsigned char control2 :4;
214 unsigned char point2;
215 unsigned char lead_out_start_msf[3];
216 struct
217 {
218 unsigned char address :4;
219 unsigned char control :4;
220 unsigned char track;
221 unsigned char track_start_msf[3];
222 } tracks[MAX_TRACKS];
223
224 unsigned int lead_out_start_lba;
225};
226
227struct s_sony_session_toc
228{
229 unsigned char exec_status[2];
230 unsigned char session_number;
231 unsigned char address0 :4;
232 unsigned char control0 :4;
233 unsigned char point0;
234 unsigned char first_track_num;
235 unsigned char disk_type;
236 unsigned char dummy0;
237 unsigned char address1 :4;
238 unsigned char control1 :4;
239 unsigned char point1;
240 unsigned char last_track_num;
241 unsigned char dummy1;
242 unsigned char dummy2;
243 unsigned char address2 :4;
244 unsigned char control2 :4;
245 unsigned char point2;
246 unsigned char lead_out_start_msf[3];
247 unsigned char addressb0 :4;
248 unsigned char controlb0 :4;
249 unsigned char pointb0;
250 unsigned char next_poss_prog_area_msf[3];
251 unsigned char num_mode_5_pointers;
252 unsigned char max_start_outer_leadout_msf[3];
253 unsigned char addressb1 :4;
254 unsigned char controlb1 :4;
255 unsigned char pointb1;
256 unsigned char dummyb0_1[4];
257 unsigned char num_skip_interval_pointers;
258 unsigned char num_skip_track_assignments;
259 unsigned char dummyb0_2;
260 unsigned char addressb2 :4;
261 unsigned char controlb2 :4;
262 unsigned char pointb2;
263 unsigned char tracksb2[7];
264 unsigned char addressb3 :4;
265 unsigned char controlb3 :4;
266 unsigned char pointb3;
267 unsigned char tracksb3[7];
268 unsigned char addressb4 :4;
269 unsigned char controlb4 :4;
270 unsigned char pointb4;
271 unsigned char tracksb4[7];
272 unsigned char addressc0 :4;
273 unsigned char controlc0 :4;
274 unsigned char pointc0;
275 unsigned char dummyc0[7];
276 struct
277 {
278 unsigned char address :4;
279 unsigned char control :4;
280 unsigned char track;
281 unsigned char track_start_msf[3];
282 } tracks[MAX_TRACKS];
283
284 unsigned int start_track_lba;
285 unsigned int lead_out_start_lba;
286 unsigned int mint;
287 unsigned int maxt;
288};
289
290struct s_all_sessions_toc
291{
292 unsigned char sessions;
293 unsigned int track_entries;
294 unsigned char first_track_num;
295 unsigned char last_track_num;
296 unsigned char disk_type;
297 unsigned char lead_out_start_msf[3];
298 struct
299 {
300 unsigned char address :4;
301 unsigned char control :4;
302 unsigned char track;
303 unsigned char track_start_msf[3];
304 } tracks[MAX_TRACKS];
305
306 unsigned int start_track_lba;
307 unsigned int lead_out_start_lba;
308};
309
310
311/*
312 * The following are errors returned from the drive.
313 */
314
315/* Command error group */
316#define SONY_ILL_CMD_ERR 0x10
317#define SONY_ILL_PARAM_ERR 0x11
318
319/* Mechanism group */
320#define SONY_NOT_LOAD_ERR 0x20
321#define SONY_NO_DISK_ERR 0x21
322#define SONY_NOT_SPIN_ERR 0x22
323#define SONY_SPIN_ERR 0x23
324#define SONY_SPINDLE_SERVO_ERR 0x25
325#define SONY_FOCUS_SERVO_ERR 0x26
326#define SONY_EJECT_MECH_ERR 0x29
327#define SONY_AUDIO_PLAYING_ERR 0x2a
328#define SONY_EMERGENCY_EJECT_ERR 0x2c
329
330/* Seek error group */
331#define SONY_FOCUS_ERR 0x30
332#define SONY_FRAME_SYNC_ERR 0x31
333#define SONY_SUBCODE_ADDR_ERR 0x32
334#define SONY_BLOCK_SYNC_ERR 0x33
335#define SONY_HEADER_ADDR_ERR 0x34
336
337/* Read error group */
338#define SONY_ILL_TRACK_R_ERR 0x40
339#define SONY_MODE_0_R_ERR 0x41
340#define SONY_ILL_MODE_R_ERR 0x42
341#define SONY_ILL_BLOCK_SIZE_R_ERR 0x43
342#define SONY_MODE_R_ERR 0x44
343#define SONY_FORM_R_ERR 0x45
344#define SONY_LEAD_OUT_R_ERR 0x46
345#define SONY_BUFFER_OVERRUN_R_ERR 0x47
346
347/* Data error group */
348#define SONY_UNREC_CIRC_ERR 0x53
349#define SONY_UNREC_LECC_ERR 0x57
350
351/* Subcode error group */
352#define SONY_NO_TOC_ERR 0x60
353#define SONY_SUBCODE_DATA_NVAL_ERR 0x61
354#define SONY_FOCUS_ON_TOC_READ_ERR 0x63
355#define SONY_FRAME_SYNC_ON_TOC_READ_ERR 0x64
356#define SONY_TOC_DATA_ERR 0x65
357
358/* Hardware failure group */
359#define SONY_HW_FAILURE_ERR 0x70
360#define SONY_LEAD_IN_A_ERR 0x91
361#define SONY_LEAD_OUT_A_ERR 0x92
362#define SONY_DATA_TRACK_A_ERR 0x93
363
364/*
365 * The following are returned from the Read With Block Error Status command.
366 * They are not errors but information (Errors from the 0x5x group above may
367 * also be returned
368 */
369#define SONY_NO_CIRC_ERR_BLK_STAT 0x50
370#define SONY_NO_LECC_ERR_BLK_STAT 0x54
371#define SONY_RECOV_LECC_ERR_BLK_STAT 0x55
372#define SONY_NO_ERR_DETECTION_STAT 0x59
373
374/*
375 * The following is not an error returned by the drive, but by the code
376 * that talks to the drive. It is returned because of a timeout.
377 */
378#define SONY_TIMEOUT_OP_ERR 0x01
379#define SONY_SIGNAL_OP_ERR 0x02
380#define SONY_BAD_DATA_ERR 0x03
381
382
383/*
384 * The following are attention code for asynchronous events from the drive.
385 */
386
387/* Standard attention group */
388#define SONY_EMER_EJECT_ATTN 0x2c
389#define SONY_HW_FAILURE_ATTN 0x70
390#define SONY_MECH_LOADED_ATTN 0x80
391#define SONY_EJECT_PUSHED_ATTN 0x81
392
393/* Audio attention group */
394#define SONY_AUDIO_PLAY_DONE_ATTN 0x90
395#define SONY_LEAD_IN_ERR_ATTN 0x91
396#define SONY_LEAD_OUT_ERR_ATTN 0x92
397#define SONY_DATA_TRACK_ERR_ATTN 0x93
398#define SONY_AUDIO_PLAYBACK_ERR_ATTN 0x94
399
400/* Auto spin up group */
401#define SONY_SPIN_UP_COMPLETE_ATTN 0x24
402#define SONY_SPINDLE_SERVO_ERR_ATTN 0x25
403#define SONY_FOCUS_SERVO_ERR_ATTN 0x26
404#define SONY_TOC_READ_DONE_ATTN 0x62
405#define SONY_FOCUS_ON_TOC_READ_ERR_ATTN 0x63
406#define SONY_SYNC_ON_TOC_READ_ERR_ATTN 0x65
407
408/* Auto eject group */
409#define SONY_SPIN_DOWN_COMPLETE_ATTN 0x27
410#define SONY_EJECT_COMPLETE_ATTN 0x28
411#define SONY_EJECT_MECH_ERR_ATTN 0x29
diff --git a/drivers/cdrom/cm206.c b/drivers/cdrom/cm206.c
new file mode 100644
index 000000000000..da80b14335a5
--- /dev/null
+++ b/drivers/cdrom/cm206.c
@@ -0,0 +1,1626 @@
1/* cm206.c. A linux-driver for the cm206 cdrom player with cm260 adapter card.
2 Copyright (c) 1995--1997 David A. van Leeuwen.
3 $Id: cm206.c,v 1.5 1997/12/26 11:02:51 david Exp $
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18
19History:
20 Started 25 jan 1994. Waiting for documentation...
21 22 feb 1995: 0.1a first reasonably safe polling driver.
22 Two major bugs, one in read_sector and one in
23 do_cm206_request, happened to cancel!
24 25 feb 1995: 0.2a first reasonable interrupt driven version of above.
25 uart writes are still done in polling mode.
26 25 feb 1995: 0.21a writes also in interrupt mode, still some
27 small bugs to be found... Larger buffer.
28 2 mrt 1995: 0.22 Bug found (cd-> nowhere, interrupt was called in
29 initialization), read_ahead of 16. Timeouts implemented.
30 unclear if they do something...
31 7 mrt 1995: 0.23 Start of background read-ahead.
32 18 mrt 1995: 0.24 Working background read-ahead. (still problems)
33 26 mrt 1995: 0.25 Multi-session ioctl added (kernel v1.2).
34 Statistics implemented, though separate stats206.h.
35 Accessible trough ioctl 0x1000 (just a number).
36 Hard to choose between v1.2 development and 1.1.75.
37 Bottom-half doesn't work with 1.2...
38 0.25a: fixed... typo. Still problems...
39 1 apr 1995: 0.26 Module support added. Most bugs found. Use kernel 1.2.n.
40 5 apr 1995: 0.27 Auto-probe for the adapter card base address.
41 Auto-probe for the adaptor card irq line.
42 7 apr 1995: 0.28 Added lilo setup support for base address and irq.
43 Use major number 32 (not in this source), officially
44 assigned to this driver.
45 9 apr 1995: 0.29 Added very limited audio support. Toc_header, stop, pause,
46 resume, eject. Play_track ignores track info, because we can't
47 read a table-of-contents entry. Toc_entry is implemented
48 as a `placebo' function: always returns start of disc.
49 3 may 1995: 0.30 Audio support completed. The get_toc_entry function
50 is implemented as a binary search.
51 15 may 1995: 0.31 More work on audio stuff. Workman is not easy to
52 satisfy; changed binary search into linear search.
53 Auto-probe for base address somewhat relaxed.
54 1 jun 1995: 0.32 Removed probe_irq_on/off for module version.
55 10 jun 1995: 0.33 Workman still behaves funny, but you should be
56 able to eject and substitute another disc.
57
58 An adaptation of 0.33 is included in linux-1.3.7 by Eberhard Moenkeberg
59
60 18 jul 1995: 0.34 Patch by Heiko Eissfeldt included, mainly considering
61 verify_area's in the ioctls. Some bugs introduced by
62 EM considering the base port and irq fixed.
63
64 18 dec 1995: 0.35 Add some code for error checking... no luck...
65
66 We jump to reach our goal: version 1.0 in the next stable linux kernel.
67
68 19 mar 1996: 0.95 Different implementation of CDROM_GET_UPC, on
69 request of Thomas Quinot.
70 25 mar 1996: 0.96 Interpretation of opening with O_WRONLY or O_RDWR:
71 open only for ioctl operation, e.g., for operation of
72 tray etc.
73 4 apr 1996: 0.97 First implementation of layer between VFS and cdrom
74 driver, a generic interface. Much of the functionality
75 of cm206_open() and cm206_ioctl() is transferred to a
76 new file cdrom.c and its header ucdrom.h.
77
78 Upgrade to Linux kernel 1.3.78.
79
80 11 apr 1996 0.98 Upgrade to Linux kernel 1.3.85
81 More code moved to cdrom.c
82
83 0.99 Some more small changes to decrease number
84 of oopses at module load;
85
86 27 jul 1996 0.100 Many hours of debugging, kernel change from 1.2.13
87 to 2.0.7 seems to have introduced some weird behavior
88 in (interruptible_)sleep_on(&cd->data): the process
89 seems to be woken without any explicit wake_up in my own
90 code. Patch to try 100x in case such untriggered wake_up's
91 occur.
92
93 28 jul 1996 0.101 Rewriting of the code that receives the command echo,
94 using a fifo to store echoed bytes.
95
96 Branch from 0.99:
97
98 0.99.1.0 Update to kernel release 2.0.10 dev_t -> kdev_t
99 (emoenke) various typos found by others. extra
100 module-load oops protection.
101
102 0.99.1.1 Initialization constant cdrom_dops.speed
103 changed from float (2.0) to int (2); Cli()-sti() pair
104 around cm260_reset() in module initialization code.
105
106 0.99.1.2 Changes literally as proposed by Scott Snyder
107 <snyder@d0sgif.fnal.gov> for the 2.1 kernel line, which
108 have to do mainly with the poor minor support i had. The
109 major new concept is to change a cdrom driver's
110 operations struct from the capabilities struct. This
111 reflects the fact that there is one major for a driver,
112 whilst there can be many minors whith completely
113 different capabilities.
114
115 0.99.1.3 More changes for operations/info separation.
116
117 0.99.1.4 Added speed selection (someone had to do this
118 first).
119
120 23 jan 1997 0.99.1.5 MODULE_PARMS call added.
121
122 23 jan 1997 0.100.1.2--0.100.1.5 following similar lines as
123 0.99.1.1--0.99.1.5. I get too many complaints about the
124 drive making read errors. What't wrong with the 2.0+
125 kernel line? Why get i (and othe cm206 owners) weird
126 results? Why were things good in the good old 1.1--1.2
127 era? Why don't i throw away the drive?
128
129 2 feb 1997 0.102 Added `volatile' to values in cm206_struct. Seems to
130 reduce many of the problems. Rewrote polling routines
131 to use fixed delays between polls.
132 0.103 Changed printk behavior.
133 0.104 Added a 0.100 -> 0.100.1.1 change
134
13511 feb 1997 0.105 Allow auto_probe during module load, disable
136 with module option "auto_probe=0". Moved some debugging
137 statements to lower priority. Implemented select_speed()
138 function.
139
14013 feb 1997 1.0 Final version for 2.0 kernel line.
141
142 All following changes will be for the 2.1 kernel line.
143
14415 feb 1997 1.1 Keep up with kernel 2.1.26, merge in changes from
145 cdrom.c 0.100.1.1--1.0. Add some more MODULE_PARMS.
146
14714 sep 1997 1.2 Upgrade to Linux 2.1.55. Added blksize_size[], patch
148 sent by James Bottomley <James.Bottomley@columbiasc.ncr.com>.
149
15021 dec 1997 1.4 Upgrade to Linux 2.1.72.
151
15224 jan 1998 Removed the cm206_disc_status() function, as it was now dead
153 code. The Uniform CDROM driver now provides this functionality.
154
1559 Nov. 1999 Make kernel-parameter implementation work with 2.3.x
156 Removed init_module & cleanup_module in favor of
157 module_init & module_exit.
158 Torben Mathiasen <tmm@image.dk>
159 *
160 * Parts of the code are based upon lmscd.c written by Kai Petzke,
161 * sbpcd.c written by Eberhard Moenkeberg, and mcd.c by Martin
162 * Harriss, but any off-the-shelf dynamic programming algorithm won't
163 * be able to find them.
164 *
165 * The cm206 drive interface and the cm260 adapter card seem to be
166 * sufficiently different from their cm205/cm250 counterparts
167 * in order to write a complete new driver.
168 *
169 * I call all routines connected to the Linux kernel something
170 * with `cm206' in it, as this stuff is too series-dependent.
171 *
172 * Currently, my limited knowledge is based on:
173 * - The Linux Kernel Hacker's guide, v. 0.5, by Michael K. Johnson
174 * - Linux Kernel Programmierung, by Michael Beck and others
175 * - Philips/LMS cm206 and cm226 product specification
176 * - Philips/LMS cm260 product specification
177 *
178 * David van Leeuwen, david@tm.tno.nl. */
179#define REVISION "$Revision: 1.5 $"
180
181#include <linux/module.h>
182
183#include <linux/errno.h> /* These include what we really need */
184#include <linux/delay.h>
185#include <linux/string.h>
186#include <linux/sched.h>
187#include <linux/interrupt.h>
188#include <linux/timer.h>
189#include <linux/cdrom.h>
190#include <linux/devfs_fs_kernel.h>
191#include <linux/ioport.h>
192#include <linux/mm.h>
193#include <linux/slab.h>
194#include <linux/init.h>
195
196/* #include <linux/ucdrom.h> */
197
198#include <asm/io.h>
199
200#define MAJOR_NR CM206_CDROM_MAJOR
201
202#include <linux/blkdev.h>
203
204#undef DEBUG
205#define STATISTICS /* record times and frequencies of events */
206#define AUTO_PROBE_MODULE
207#define USE_INSW
208
209#include "cm206.h"
210
211/* This variable defines whether or not to probe for adapter base port
212 address and interrupt request. It can be overridden by the boot
213 parameter `auto'.
214*/
215static int auto_probe = 1; /* Yes, why not? */
216
217static int cm206_base = CM206_BASE;
218static int cm206_irq = CM206_IRQ;
219#ifdef MODULE
220static int cm206[2] = { 0, 0 }; /* for compatible `insmod' parameter passing */
221#endif
222
223MODULE_PARM(cm206_base, "i"); /* base */
224MODULE_PARM(cm206_irq, "i"); /* irq */
225MODULE_PARM(cm206, "1-2i"); /* base,irq or irq,base */
226MODULE_PARM(auto_probe, "i"); /* auto probe base and irq */
227MODULE_LICENSE("GPL");
228
229#define POLLOOP 100 /* milliseconds */
230#define READ_AHEAD 1 /* defines private buffer, waste! */
231#define BACK_AHEAD 1 /* defines adapter-read ahead */
232#define DATA_TIMEOUT (3*HZ) /* measured in jiffies (10 ms) */
233#define UART_TIMEOUT (5*HZ/100)
234#define DSB_TIMEOUT (7*HZ) /* time for the slowest command to finish */
235#define UR_SIZE 4 /* uart receive buffer fifo size */
236
237#define LINUX_BLOCK_SIZE 512 /* WHERE is this defined? */
238#define RAW_SECTOR_SIZE 2352 /* ok, is also defined in cdrom.h */
239#define ISO_SECTOR_SIZE 2048
240#define BLOCKS_ISO (ISO_SECTOR_SIZE/LINUX_BLOCK_SIZE) /* 4 */
241#define CD_SYNC_HEAD 16 /* CD_SYNC + CD_HEAD */
242
243#ifdef STATISTICS /* keep track of errors in counters */
244#define stats(i) { ++cd->stats[st_ ## i]; \
245 cd->last_stat[st_ ## i] = cd->stat_counter++; \
246 }
247#else
248#define stats(i) (void) 0;
249#endif
250
251#define Debug(a) {printk (KERN_DEBUG); printk a;}
252#ifdef DEBUG
253#define debug(a) Debug(a)
254#else
255#define debug(a) (void) 0;
256#endif
257
258typedef unsigned char uch; /* 8-bits */
259typedef unsigned short ush; /* 16-bits */
260
261struct toc_struct { /* private copy of Table of Contents */
262 uch track, fsm[3], q0;
263};
264
265struct cm206_struct {
266 volatile ush intr_ds; /* data status read on last interrupt */
267 volatile ush intr_ls; /* uart line status read on last interrupt */
268 volatile uch ur[UR_SIZE]; /* uart receive buffer fifo */
269 volatile uch ur_w, ur_r; /* write/read buffer index */
270 volatile uch dsb, cc; /* drive status byte and condition (error) code */
271 int command; /* command to be written to the uart */
272 int openfiles;
273 ush sector[READ_AHEAD * RAW_SECTOR_SIZE / 2]; /* buffered cd-sector */
274 int sector_first, sector_last; /* range of these sectors */
275 wait_queue_head_t uart; /* wait queues for interrupt */
276 wait_queue_head_t data;
277 struct timer_list timer; /* time-out */
278 char timed_out;
279 signed char max_sectors; /* number of sectors that fit in adapter mem */
280 char wait_back; /* we're waiting for a background-read */
281 char background; /* is a read going on in the background? */
282 int adapter_first; /* if so, that's the starting sector */
283 int adapter_last;
284 char fifo_overflowed;
285 uch disc_status[7]; /* result of get_disc_status command */
286#ifdef STATISTICS
287 int stats[NR_STATS];
288 int last_stat[NR_STATS]; /* `time' at which stat was stat */
289 int stat_counter;
290#endif
291 struct toc_struct toc[101]; /* The whole table of contents + lead-out */
292 uch q[10]; /* Last read q-channel info */
293 uch audio_status[5]; /* last read position on pause */
294 uch media_changed; /* record if media changed */
295};
296
297#define DISC_STATUS cd->disc_status[0]
298#define FIRST_TRACK cd->disc_status[1]
299#define LAST_TRACK cd->disc_status[2]
300#define PAUSED cd->audio_status[0] /* misuse this memory byte! */
301#define PLAY_TO cd->toc[0] /* toc[0] records end-time in play */
302
303static struct cm206_struct *cd; /* the main memory structure */
304static struct request_queue *cm206_queue;
305static DEFINE_SPINLOCK(cm206_lock);
306
307/* First, we define some polling functions. These are actually
308 only being used in the initialization. */
309
310void send_command_polled(int command)
311{
312 int loop = POLLOOP;
313 while (!(inw(r_line_status) & ls_transmitter_buffer_empty)
314 && loop > 0) {
315 mdelay(1); /* one millisec delay */
316 --loop;
317 }
318 outw(command, r_uart_transmit);
319}
320
321uch receive_echo_polled(void)
322{
323 int loop = POLLOOP;
324 while (!(inw(r_line_status) & ls_receive_buffer_full) && loop > 0) {
325 mdelay(1);
326 --loop;
327 }
328 return ((uch) inw(r_uart_receive));
329}
330
331uch send_receive_polled(int command)
332{
333 send_command_polled(command);
334 return receive_echo_polled();
335}
336
337inline void clear_ur(void)
338{
339 if (cd->ur_r != cd->ur_w) {
340 debug(("Deleting bytes from fifo:"));
341 for (; cd->ur_r != cd->ur_w;
342 cd->ur_r++, cd->ur_r %= UR_SIZE)
343 debug((" 0x%x", cd->ur[cd->ur_r]));
344 debug(("\n"));
345 }
346}
347
348static struct tasklet_struct cm206_tasklet;
349
350/* The interrupt handler. When the cm260 generates an interrupt, very
351 much care has to be taken in reading out the registers in the right
352 order; in case of a receive_buffer_full interrupt, first the
353 uart_receive must be read, and then the line status again to
354 de-assert the interrupt line. It took me a couple of hours to find
355 this out:-(
356
357 The function reset_cm206 appears to cause an interrupt, because
358 pulling up the INIT line clears both the uart-write-buffer /and/
359 the uart-write-buffer-empty mask. We call this a `lost interrupt,'
360 as there seems so reason for this to happen.
361*/
362
363static irqreturn_t cm206_interrupt(int sig, void *dev_id, struct pt_regs *regs)
364{
365 volatile ush fool;
366 cd->intr_ds = inw(r_data_status); /* resets data_ready, data_error,
367 crc_error, sync_error, toc_ready
368 interrupts */
369 cd->intr_ls = inw(r_line_status); /* resets overrun bit */
370 debug(("Intr, 0x%x 0x%x, %d\n", cd->intr_ds, cd->intr_ls,
371 cd->background));
372 if (cd->intr_ls & ls_attention)
373 stats(attention);
374 /* receive buffer full? */
375 if (cd->intr_ls & ls_receive_buffer_full) {
376 cd->ur[cd->ur_w] = inb(r_uart_receive); /* get order right! */
377 cd->intr_ls = inw(r_line_status); /* resets rbf interrupt */
378 debug(("receiving #%d: 0x%x\n", cd->ur_w,
379 cd->ur[cd->ur_w]));
380 cd->ur_w++;
381 cd->ur_w %= UR_SIZE;
382 if (cd->ur_w == cd->ur_r)
383 debug(("cd->ur overflow!\n"));
384 if (waitqueue_active(&cd->uart) && cd->background < 2) {
385 del_timer(&cd->timer);
386 wake_up_interruptible(&cd->uart);
387 }
388 }
389 /* data ready in fifo? */
390 else if (cd->intr_ds & ds_data_ready) {
391 if (cd->background)
392 ++cd->adapter_last;
393 if (waitqueue_active(&cd->data)
394 && (cd->wait_back || !cd->background)) {
395 del_timer(&cd->timer);
396 wake_up_interruptible(&cd->data);
397 }
398 stats(data_ready);
399 }
400 /* ready to issue a write command? */
401 else if (cd->command && cd->intr_ls & ls_transmitter_buffer_empty) {
402 outw(dc_normal | (inw(r_data_status) & 0x7f),
403 r_data_control);
404 outw(cd->command, r_uart_transmit);
405 cd->command = 0;
406 if (!cd->background)
407 wake_up_interruptible(&cd->uart);
408 }
409 /* now treat errors (at least, identify them for debugging) */
410 else if (cd->intr_ds & ds_fifo_overflow) {
411 debug(("Fifo overflow at sectors 0x%x\n",
412 cd->sector_first));
413 fool = inw(r_fifo_output_buffer); /* de-assert the interrupt */
414 cd->fifo_overflowed = 1; /* signal one word less should be read */
415 stats(fifo_overflow);
416 } else if (cd->intr_ds & ds_data_error) {
417 debug(("Data error at sector 0x%x\n", cd->sector_first));
418 stats(data_error);
419 } else if (cd->intr_ds & ds_crc_error) {
420 debug(("CRC error at sector 0x%x\n", cd->sector_first));
421 stats(crc_error);
422 } else if (cd->intr_ds & ds_sync_error) {
423 debug(("Sync at sector 0x%x\n", cd->sector_first));
424 stats(sync_error);
425 } else if (cd->intr_ds & ds_toc_ready) {
426 /* do something appropriate */
427 }
428 /* couldn't see why this interrupt, maybe due to init */
429 else {
430 outw(dc_normal | READ_AHEAD, r_data_control);
431 stats(lost_intr);
432 }
433 if (cd->background
434 && (cd->adapter_last - cd->adapter_first == cd->max_sectors
435 || cd->fifo_overflowed))
436 tasklet_schedule(&cm206_tasklet); /* issue a stop read command */
437 stats(interrupt);
438 return IRQ_HANDLED;
439}
440
441/* we have put the address of the wait queue in who */
442void cm206_timeout(unsigned long who)
443{
444 cd->timed_out = 1;
445 debug(("Timing out\n"));
446 wake_up_interruptible((wait_queue_head_t *) who);
447}
448
449/* This function returns 1 if a timeout occurred, 0 if an interrupt
450 happened */
451int sleep_or_timeout(wait_queue_head_t * wait, int timeout)
452{
453 cd->timed_out = 0;
454 init_timer(&cd->timer);
455 cd->timer.data = (unsigned long) wait;
456 cd->timer.expires = jiffies + timeout;
457 add_timer(&cd->timer);
458 debug(("going to sleep\n"));
459 interruptible_sleep_on(wait);
460 del_timer(&cd->timer);
461 if (cd->timed_out) {
462 cd->timed_out = 0;
463 return 1;
464 } else
465 return 0;
466}
467
468void cm206_delay(int nr_jiffies)
469{
470 DECLARE_WAIT_QUEUE_HEAD(wait);
471 sleep_or_timeout(&wait, nr_jiffies);
472}
473
474void send_command(int command)
475{
476 debug(("Sending 0x%x\n", command));
477 if (!(inw(r_line_status) & ls_transmitter_buffer_empty)) {
478 cd->command = command;
479 cli(); /* don't interrupt before sleep */
480 outw(dc_mask_sync_error | dc_no_stop_on_error |
481 (inw(r_data_status) & 0x7f), r_data_control);
482 /* interrupt routine sends command */
483 if (sleep_or_timeout(&cd->uart, UART_TIMEOUT)) {
484 debug(("Time out on write-buffer\n"));
485 stats(write_timeout);
486 outw(command, r_uart_transmit);
487 }
488 debug(("Write commmand delayed\n"));
489 } else
490 outw(command, r_uart_transmit);
491}
492
493uch receive_byte(int timeout)
494{
495 uch ret;
496 cli();
497 debug(("cli\n"));
498 ret = cd->ur[cd->ur_r];
499 if (cd->ur_r != cd->ur_w) {
500 sti();
501 debug(("returning #%d: 0x%x\n", cd->ur_r,
502 cd->ur[cd->ur_r]));
503 cd->ur_r++;
504 cd->ur_r %= UR_SIZE;
505 return ret;
506 } else if (sleep_or_timeout(&cd->uart, timeout)) { /* does sti() */
507 debug(("Time out on receive-buffer\n"));
508#ifdef STATISTICS
509 if (timeout == UART_TIMEOUT)
510 stats(receive_timeout) /* no `;'! */
511 else
512 stats(dsb_timeout);
513#endif
514 return 0xda;
515 }
516 ret = cd->ur[cd->ur_r];
517 debug(("slept; returning #%d: 0x%x\n", cd->ur_r,
518 cd->ur[cd->ur_r]));
519 cd->ur_r++;
520 cd->ur_r %= UR_SIZE;
521 return ret;
522}
523
524inline uch receive_echo(void)
525{
526 return receive_byte(UART_TIMEOUT);
527}
528
529inline uch send_receive(int command)
530{
531 send_command(command);
532 return receive_echo();
533}
534
535inline uch wait_dsb(void)
536{
537 return receive_byte(DSB_TIMEOUT);
538}
539
540int type_0_command(int command, int expect_dsb)
541{
542 int e;
543 clear_ur();
544 if (command != (e = send_receive(command))) {
545 debug(("command 0x%x echoed as 0x%x\n", command, e));
546 stats(echo);
547 return -1;
548 }
549 if (expect_dsb) {
550 cd->dsb = wait_dsb(); /* wait for command to finish */
551 }
552 return 0;
553}
554
555int type_1_command(int command, int bytes, uch * status)
556{ /* returns info */
557 int i;
558 if (type_0_command(command, 0))
559 return -1;
560 for (i = 0; i < bytes; i++)
561 status[i] = send_receive(c_gimme);
562 return 0;
563}
564
565/* This function resets the adapter card. We'd better not do this too
566 * often, because it tends to generate `lost interrupts.' */
567void reset_cm260(void)
568{
569 outw(dc_normal | dc_initialize | READ_AHEAD, r_data_control);
570 udelay(10); /* 3.3 mu sec minimum */
571 outw(dc_normal | READ_AHEAD, r_data_control);
572}
573
574/* fsm: frame-sec-min from linear address; one of many */
575void fsm(int lba, uch * fsm)
576{
577 fsm[0] = lba % 75;
578 lba /= 75;
579 lba += 2;
580 fsm[1] = lba % 60;
581 fsm[2] = lba / 60;
582}
583
584inline int fsm2lba(uch * fsm)
585{
586 return fsm[0] + 75 * (fsm[1] - 2 + 60 * fsm[2]);
587}
588
589inline int f_s_m2lba(uch f, uch s, uch m)
590{
591 return f + 75 * (s - 2 + 60 * m);
592}
593
594int start_read(int start)
595{
596 uch read_sector[4] = { c_read_data, };
597 int i, e;
598
599 fsm(start, &read_sector[1]);
600 clear_ur();
601 for (i = 0; i < 4; i++)
602 if (read_sector[i] != (e = send_receive(read_sector[i]))) {
603 debug(("read_sector: %x echoes %x\n",
604 read_sector[i], e));
605 stats(echo);
606 if (e == 0xff) { /* this seems to happen often */
607 e = receive_echo();
608 debug(("Second try %x\n", e));
609 if (e != read_sector[i])
610 return -1;
611 }
612 }
613 return 0;
614}
615
616int stop_read(void)
617{
618 int e;
619 type_0_command(c_stop, 0);
620 if ((e = receive_echo()) != 0xff) {
621 debug(("c_stop didn't send 0xff, but 0x%x\n", e));
622 stats(stop_0xff);
623 return -1;
624 }
625 return 0;
626}
627
628/* This function starts to read sectors in adapter memory, the
629 interrupt routine should stop the read. In fact, the bottom_half
630 routine takes care of this. Set a flag `background' in the cd
631 struct to indicate the process. */
632
633int read_background(int start, int reading)
634{
635 if (cd->background)
636 return -1; /* can't do twice */
637 outw(dc_normal | BACK_AHEAD, r_data_control);
638 if (!reading && start_read(start))
639 return -2;
640 cd->adapter_first = cd->adapter_last = start;
641 cd->background = 1; /* flag a read is going on */
642 return 0;
643}
644
645#ifdef USE_INSW
646#define transport_data insw
647#else
648/* this routine implements insw(,,). There was a time i had the
649 impression that there would be any difference in error-behaviour. */
650void transport_data(int port, ush * dest, int count)
651{
652 int i;
653 ush *d;
654 for (i = 0, d = dest; i < count; i++, d++)
655 *d = inw(port);
656}
657#endif
658
659
660#define MAX_TRIES 100
661int read_sector(int start)
662{
663 int tries = 0;
664 if (cd->background) {
665 cd->background = 0;
666 cd->adapter_last = -1; /* invalidate adapter memory */
667 stop_read();
668 }
669 cd->fifo_overflowed = 0;
670 reset_cm260(); /* empty fifo etc. */
671 if (start_read(start))
672 return -1;
673 do {
674 if (sleep_or_timeout(&cd->data, DATA_TIMEOUT)) {
675 debug(("Read timed out sector 0x%x\n", start));
676 stats(read_timeout);
677 stop_read();
678 return -3;
679 }
680 tries++;
681 } while (cd->intr_ds & ds_fifo_empty && tries < MAX_TRIES);
682 if (tries > 1)
683 debug(("Took me some tries\n"))
684 else
685 if (tries == MAX_TRIES)
686 debug(("MAX_TRIES tries for read sector\n"));
687 transport_data(r_fifo_output_buffer, cd->sector,
688 READ_AHEAD * RAW_SECTOR_SIZE / 2);
689 if (read_background(start + READ_AHEAD, 1))
690 stats(read_background);
691 cd->sector_first = start;
692 cd->sector_last = start + READ_AHEAD;
693 stats(read_restarted);
694 return 0;
695}
696
697/* The function of bottom-half is to send a stop command to the drive
698 This isn't easy because the routine is not `owned' by any process;
699 we can't go to sleep! The variable cd->background gives the status:
700 0 no read pending
701 1 a read is pending
702 2 c_stop waits for write_buffer_empty
703 3 c_stop waits for receive_buffer_full: echo
704 4 c_stop waits for receive_buffer_full: 0xff
705*/
706
707static void cm206_tasklet_func(unsigned long ignore)
708{
709 debug(("bh: %d\n", cd->background));
710 switch (cd->background) {
711 case 1:
712 stats(bh);
713 if (!(cd->intr_ls & ls_transmitter_buffer_empty)) {
714 cd->command = c_stop;
715 outw(dc_mask_sync_error | dc_no_stop_on_error |
716 (inw(r_data_status) & 0x7f), r_data_control);
717 cd->background = 2;
718 break; /* we'd better not time-out here! */
719 } else
720 outw(c_stop, r_uart_transmit);
721 /* fall into case 2: */
722 case 2:
723 /* the write has been satisfied by interrupt routine */
724 cd->background = 3;
725 break;
726 case 3:
727 if (cd->ur_r != cd->ur_w) {
728 if (cd->ur[cd->ur_r] != c_stop) {
729 debug(("cm206_bh: c_stop echoed 0x%x\n",
730 cd->ur[cd->ur_r]));
731 stats(echo);
732 }
733 cd->ur_r++;
734 cd->ur_r %= UR_SIZE;
735 }
736 cd->background++;
737 break;
738 case 4:
739 if (cd->ur_r != cd->ur_w) {
740 if (cd->ur[cd->ur_r] != 0xff) {
741 debug(("cm206_bh: c_stop reacted with 0x%x\n", cd->ur[cd->ur_r]));
742 stats(stop_0xff);
743 }
744 cd->ur_r++;
745 cd->ur_r %= UR_SIZE;
746 }
747 cd->background = 0;
748 }
749}
750
751static DECLARE_TASKLET(cm206_tasklet, cm206_tasklet_func, 0);
752
753/* This command clears the dsb_possible_media_change flag, so we must
754 * retain it.
755 */
756void get_drive_status(void)
757{
758 uch status[2];
759 type_1_command(c_drive_status, 2, status); /* this might be done faster */
760 cd->dsb = status[0];
761 cd->cc = status[1];
762 cd->media_changed |=
763 !!(cd->dsb & (dsb_possible_media_change |
764 dsb_drive_not_ready | dsb_tray_not_closed));
765}
766
767void get_disc_status(void)
768{
769 if (type_1_command(c_disc_status, 7, cd->disc_status)) {
770 debug(("get_disc_status: error\n"));
771 }
772}
773
774/* The new open. The real opening strategy is defined in cdrom.c. */
775
776static int cm206_open(struct cdrom_device_info *cdi, int purpose)
777{
778 if (!cd->openfiles) { /* reset only first time */
779 cd->background = 0;
780 reset_cm260();
781 cd->adapter_last = -1; /* invalidate adapter memory */
782 cd->sector_last = -1;
783 }
784 ++cd->openfiles;
785 stats(open);
786 return 0;
787}
788
789static void cm206_release(struct cdrom_device_info *cdi)
790{
791 if (cd->openfiles == 1) {
792 if (cd->background) {
793 cd->background = 0;
794 stop_read();
795 }
796 cd->sector_last = -1; /* Make our internal buffer invalid */
797 FIRST_TRACK = 0; /* No valid disc status */
798 }
799 --cd->openfiles;
800}
801
802/* Empty buffer empties $sectors$ sectors of the adapter card buffer,
803 * and then reads a sector in kernel memory. */
804void empty_buffer(int sectors)
805{
806 while (sectors >= 0) {
807 transport_data(r_fifo_output_buffer,
808 cd->sector + cd->fifo_overflowed,
809 RAW_SECTOR_SIZE / 2 - cd->fifo_overflowed);
810 --sectors;
811 ++cd->adapter_first; /* update the current adapter sector */
812 cd->fifo_overflowed = 0; /* reset overflow bit */
813 stats(sector_transferred);
814 }
815 cd->sector_first = cd->adapter_first - 1;
816 cd->sector_last = cd->adapter_first; /* update the buffer sector */
817}
818
819/* try_adapter. This function determines if the requested sector is
820 in adapter memory, or will appear there soon. Returns 0 upon
821 success */
822int try_adapter(int sector)
823{
824 if (cd->adapter_first <= sector && sector < cd->adapter_last) {
825 /* sector is in adapter memory */
826 empty_buffer(sector - cd->adapter_first);
827 return 0;
828 } else if (cd->background == 1 && cd->adapter_first <= sector
829 && sector < cd->adapter_first + cd->max_sectors) {
830 /* a read is going on, we can wait for it */
831 cd->wait_back = 1;
832 while (sector >= cd->adapter_last) {
833 if (sleep_or_timeout(&cd->data, DATA_TIMEOUT)) {
834 debug(("Timed out during background wait: %d %d %d %d\n", sector, cd->adapter_last, cd->adapter_first, cd->background));
835 stats(back_read_timeout);
836 cd->wait_back = 0;
837 return -1;
838 }
839 }
840 cd->wait_back = 0;
841 empty_buffer(sector - cd->adapter_first);
842 return 0;
843 } else
844 return -2;
845}
846
847/* This is not a very smart implementation. We could optimize for
848 consecutive block numbers. I'm not convinced this would really
849 bring down the processor load. */
850static void do_cm206_request(request_queue_t * q)
851{
852 long int i, cd_sec_no;
853 int quarter, error;
854 uch *source, *dest;
855 struct request *req;
856
857 while (1) { /* repeat until all requests have been satisfied */
858 req = elv_next_request(q);
859 if (!req)
860 return;
861
862 if (req->cmd != READ) {
863 debug(("Non-read command %d on cdrom\n", req->cmd));
864 end_request(req, 0);
865 continue;
866 }
867 spin_unlock_irq(q->queue_lock);
868 error = 0;
869 for (i = 0; i < req->nr_sectors; i++) {
870 int e1, e2;
871 cd_sec_no = (req->sector + i) / BLOCKS_ISO; /* 4 times 512 bytes */
872 quarter = (req->sector + i) % BLOCKS_ISO;
873 dest = req->buffer + i * LINUX_BLOCK_SIZE;
874 /* is already in buffer memory? */
875 if (cd->sector_first <= cd_sec_no
876 && cd_sec_no < cd->sector_last) {
877 source =
878 ((uch *) cd->sector) + 16 +
879 quarter * LINUX_BLOCK_SIZE +
880 (cd_sec_no -
881 cd->sector_first) * RAW_SECTOR_SIZE;
882 memcpy(dest, source, LINUX_BLOCK_SIZE);
883 } else if (!(e1 = try_adapter(cd_sec_no)) ||
884 !(e2 = read_sector(cd_sec_no))) {
885 source =
886 ((uch *) cd->sector) + 16 +
887 quarter * LINUX_BLOCK_SIZE;
888 memcpy(dest, source, LINUX_BLOCK_SIZE);
889 } else {
890 error = 1;
891 debug(("cm206_request: %d %d\n", e1, e2));
892 }
893 }
894 spin_lock_irq(q->queue_lock);
895 end_request(req, !error);
896 }
897}
898
899/* Audio support. I've tried very hard, but the cm206 drive doesn't
900 seem to have a get_toc (table-of-contents) function, while i'm
901 pretty sure it must read the toc upon disc insertion. Therefore
902 this function has been implemented through a binary search
903 strategy. All track starts that happen to be found are stored in
904 cd->toc[], for future use.
905
906 I've spent a whole day on a bug that only shows under Workman---
907 I don't get it. Tried everything, nothing works. If workman asks
908 for track# 0xaa, it'll get the wrong time back. Any other program
909 receives the correct value. I'm stymied.
910*/
911
912/* seek seeks to address lba. It does wait to arrive there. */
913void seek(int lba)
914{
915 int i;
916 uch seek_command[4] = { c_seek, };
917
918 fsm(lba, &seek_command[1]);
919 for (i = 0; i < 4; i++)
920 type_0_command(seek_command[i], 0);
921 cd->dsb = wait_dsb();
922}
923
924uch bcdbin(unsigned char bcd)
925{ /* stolen from mcd.c! */
926 return (bcd >> 4) * 10 + (bcd & 0xf);
927}
928
929inline uch normalize_track(uch track)
930{
931 if (track < 1)
932 return 1;
933 if (track > LAST_TRACK)
934 return LAST_TRACK + 1;
935 return track;
936}
937
938/* This function does a binary search for track start. It records all
939 * tracks seen in the process. Input $track$ must be between 1 and
940 * #-of-tracks+1. Note that the start of the disc must be in toc[1].fsm.
941 */
942int get_toc_lba(uch track)
943{
944 int max = 74 * 60 * 75 - 150, min = fsm2lba(cd->toc[1].fsm);
945 int i, lba, l, old_lba = 0;
946 uch *q = cd->q;
947 uch ct; /* current track */
948 int binary = 0;
949 const int skip = 3 * 60 * 75; /* 3 minutes */
950
951 for (i = track; i > 0; i--)
952 if (cd->toc[i].track) {
953 min = fsm2lba(cd->toc[i].fsm);
954 break;
955 }
956 lba = min + skip;
957 do {
958 seek(lba);
959 type_1_command(c_read_current_q, 10, q);
960 ct = normalize_track(q[1]);
961 if (!cd->toc[ct].track) {
962 l = q[9] - bcdbin(q[5]) + 75 * (q[8] -
963 bcdbin(q[4]) - 2 +
964 60 * (q[7] -
965 bcdbin(q
966 [3])));
967 cd->toc[ct].track = q[1]; /* lead out still 0xaa */
968 fsm(l, cd->toc[ct].fsm);
969 cd->toc[ct].q0 = q[0]; /* contains adr and ctrl info */
970 if (ct == track)
971 return l;
972 }
973 old_lba = lba;
974 if (binary) {
975 if (ct < track)
976 min = lba;
977 else
978 max = lba;
979 lba = (min + max) / 2;
980 } else {
981 if (ct < track)
982 lba += skip;
983 else {
984 binary = 1;
985 max = lba;
986 min = lba - skip;
987 lba = (min + max) / 2;
988 }
989 }
990 } while (lba != old_lba);
991 return lba;
992}
993
994void update_toc_entry(uch track)
995{
996 track = normalize_track(track);
997 if (!cd->toc[track].track)
998 get_toc_lba(track);
999}
1000
1001/* return 0 upon success */
1002int read_toc_header(struct cdrom_tochdr *hp)
1003{
1004 if (!FIRST_TRACK)
1005 get_disc_status();
1006 if (hp) {
1007 int i;
1008 hp->cdth_trk0 = FIRST_TRACK;
1009 hp->cdth_trk1 = LAST_TRACK;
1010 /* fill in first track position */
1011 for (i = 0; i < 3; i++)
1012 cd->toc[1].fsm[i] = cd->disc_status[3 + i];
1013 update_toc_entry(LAST_TRACK + 1); /* find most entries */
1014 return 0;
1015 }
1016 return -1;
1017}
1018
1019void play_from_to_msf(struct cdrom_msf *msfp)
1020{
1021 uch play_command[] = { c_play,
1022 msfp->cdmsf_frame0, msfp->cdmsf_sec0, msfp->cdmsf_min0,
1023 msfp->cdmsf_frame1, msfp->cdmsf_sec1, msfp->cdmsf_min1, 2,
1024 2
1025 };
1026 int i;
1027 for (i = 0; i < 9; i++)
1028 type_0_command(play_command[i], 0);
1029 for (i = 0; i < 3; i++)
1030 PLAY_TO.fsm[i] = play_command[i + 4];
1031 PLAY_TO.track = 0; /* say no track end */
1032 cd->dsb = wait_dsb();
1033}
1034
1035void play_from_to_track(int from, int to)
1036{
1037 uch play_command[8] = { c_play, };
1038 int i;
1039
1040 if (from == 0) { /* continue paused play */
1041 for (i = 0; i < 3; i++) {
1042 play_command[i + 1] = cd->audio_status[i + 2];
1043 play_command[i + 4] = PLAY_TO.fsm[i];
1044 }
1045 } else {
1046 update_toc_entry(from);
1047 update_toc_entry(to + 1);
1048 for (i = 0; i < 3; i++) {
1049 play_command[i + 1] = cd->toc[from].fsm[i];
1050 PLAY_TO.fsm[i] = play_command[i + 4] =
1051 cd->toc[to + 1].fsm[i];
1052 }
1053 PLAY_TO.track = to;
1054 }
1055 for (i = 0; i < 7; i++)
1056 type_0_command(play_command[i], 0);
1057 for (i = 0; i < 2; i++)
1058 type_0_command(0x2, 0); /* volume */
1059 cd->dsb = wait_dsb();
1060}
1061
1062int get_current_q(struct cdrom_subchnl *qp)
1063{
1064 int i;
1065 uch *q = cd->q;
1066 if (type_1_command(c_read_current_q, 10, q))
1067 return 0;
1068/* q[0] = bcdbin(q[0]); Don't think so! */
1069 for (i = 2; i < 6; i++)
1070 q[i] = bcdbin(q[i]);
1071 qp->cdsc_adr = q[0] & 0xf;
1072 qp->cdsc_ctrl = q[0] >> 4; /* from mcd.c */
1073 qp->cdsc_trk = q[1];
1074 qp->cdsc_ind = q[2];
1075 if (qp->cdsc_format == CDROM_MSF) {
1076 qp->cdsc_reladdr.msf.minute = q[3];
1077 qp->cdsc_reladdr.msf.second = q[4];
1078 qp->cdsc_reladdr.msf.frame = q[5];
1079 qp->cdsc_absaddr.msf.minute = q[7];
1080 qp->cdsc_absaddr.msf.second = q[8];
1081 qp->cdsc_absaddr.msf.frame = q[9];
1082 } else {
1083 qp->cdsc_reladdr.lba = f_s_m2lba(q[5], q[4], q[3]);
1084 qp->cdsc_absaddr.lba = f_s_m2lba(q[9], q[8], q[7]);
1085 }
1086 get_drive_status();
1087 if (cd->dsb & dsb_play_in_progress)
1088 qp->cdsc_audiostatus = CDROM_AUDIO_PLAY;
1089 else if (PAUSED)
1090 qp->cdsc_audiostatus = CDROM_AUDIO_PAUSED;
1091 else
1092 qp->cdsc_audiostatus = CDROM_AUDIO_NO_STATUS;
1093 return 0;
1094}
1095
1096void invalidate_toc(void)
1097{
1098 memset(cd->toc, 0, sizeof(cd->toc));
1099 memset(cd->disc_status, 0, sizeof(cd->disc_status));
1100}
1101
1102/* cdrom.c guarantees that cdte_format == CDROM_MSF */
1103void get_toc_entry(struct cdrom_tocentry *ep)
1104{
1105 uch track = normalize_track(ep->cdte_track);
1106 update_toc_entry(track);
1107 ep->cdte_addr.msf.frame = cd->toc[track].fsm[0];
1108 ep->cdte_addr.msf.second = cd->toc[track].fsm[1];
1109 ep->cdte_addr.msf.minute = cd->toc[track].fsm[2];
1110 ep->cdte_adr = cd->toc[track].q0 & 0xf;
1111 ep->cdte_ctrl = cd->toc[track].q0 >> 4;
1112 ep->cdte_datamode = 0;
1113}
1114
1115/* Audio ioctl. Ioctl commands connected to audio are in such an
1116 * idiosyncratic i/o format, that we leave these untouched. Return 0
1117 * upon success. Memory checking has been done by cdrom_ioctl(), the
1118 * calling function, as well as LBA/MSF sanitization.
1119*/
1120int cm206_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
1121 void *arg)
1122{
1123 switch (cmd) {
1124 case CDROMREADTOCHDR:
1125 return read_toc_header((struct cdrom_tochdr *) arg);
1126 case CDROMREADTOCENTRY:
1127 get_toc_entry((struct cdrom_tocentry *) arg);
1128 return 0;
1129 case CDROMPLAYMSF:
1130 play_from_to_msf((struct cdrom_msf *) arg);
1131 return 0;
1132 case CDROMPLAYTRKIND: /* admittedly, not particularly beautiful */
1133 play_from_to_track(((struct cdrom_ti *) arg)->cdti_trk0,
1134 ((struct cdrom_ti *) arg)->cdti_trk1);
1135 return 0;
1136 case CDROMSTOP:
1137 PAUSED = 0;
1138 if (cd->dsb & dsb_play_in_progress)
1139 return type_0_command(c_stop, 1);
1140 else
1141 return 0;
1142 case CDROMPAUSE:
1143 get_drive_status();
1144 if (cd->dsb & dsb_play_in_progress) {
1145 type_0_command(c_stop, 1);
1146 type_1_command(c_audio_status, 5,
1147 cd->audio_status);
1148 PAUSED = 1; /* say we're paused */
1149 }
1150 return 0;
1151 case CDROMRESUME:
1152 if (PAUSED)
1153 play_from_to_track(0, 0);
1154 PAUSED = 0;
1155 return 0;
1156 case CDROMSTART:
1157 case CDROMVOLCTRL:
1158 return 0;
1159 case CDROMSUBCHNL:
1160 return get_current_q((struct cdrom_subchnl *) arg);
1161 default:
1162 return -EINVAL;
1163 }
1164}
1165
1166/* Ioctl. These ioctls are specific to the cm206 driver. I have made
1167 some driver statistics accessible through ioctl calls.
1168 */
1169
1170static int cm206_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
1171 unsigned long arg)
1172{
1173 switch (cmd) {
1174#ifdef STATISTICS
1175 case CM206CTL_GET_STAT:
1176 if (arg >= NR_STATS)
1177 return -EINVAL;
1178 else
1179 return cd->stats[arg];
1180 case CM206CTL_GET_LAST_STAT:
1181 if (arg >= NR_STATS)
1182 return -EINVAL;
1183 else
1184 return cd->last_stat[arg];
1185#endif
1186 default:
1187 debug(("Unknown ioctl call 0x%x\n", cmd));
1188 return -EINVAL;
1189 }
1190}
1191
1192int cm206_media_changed(struct cdrom_device_info *cdi, int disc_nr)
1193{
1194 if (cd != NULL) {
1195 int r;
1196 get_drive_status(); /* ensure cd->media_changed OK */
1197 r = cd->media_changed;
1198 cd->media_changed = 0; /* clear bit */
1199 return r;
1200 } else
1201 return -EIO;
1202}
1203
1204/* The new generic cdrom support. Routines should be concise, most of
1205 the logic should be in cdrom.c */
1206
1207/* returns number of times device is in use */
1208int cm206_open_files(struct cdrom_device_info *cdi)
1209{
1210 if (cd)
1211 return cd->openfiles;
1212 return -1;
1213}
1214
1215/* controls tray movement */
1216int cm206_tray_move(struct cdrom_device_info *cdi, int position)
1217{
1218 if (position) { /* 1: eject */
1219 type_0_command(c_open_tray, 1);
1220 invalidate_toc();
1221 } else
1222 type_0_command(c_close_tray, 1); /* 0: close */
1223 return 0;
1224}
1225
1226/* gives current state of the drive */
1227int cm206_drive_status(struct cdrom_device_info *cdi, int slot_nr)
1228{
1229 get_drive_status();
1230 if (cd->dsb & dsb_tray_not_closed)
1231 return CDS_TRAY_OPEN;
1232 if (!(cd->dsb & dsb_disc_present))
1233 return CDS_NO_DISC;
1234 if (cd->dsb & dsb_drive_not_ready)
1235 return CDS_DRIVE_NOT_READY;
1236 return CDS_DISC_OK;
1237}
1238
1239/* locks or unlocks door lock==1: lock; return 0 upon success */
1240int cm206_lock_door(struct cdrom_device_info *cdi, int lock)
1241{
1242 uch command = (lock) ? c_lock_tray : c_unlock_tray;
1243 type_0_command(command, 1); /* wait and get dsb */
1244 /* the logic calculates the success, 0 means successful */
1245 return lock ^ ((cd->dsb & dsb_tray_locked) != 0);
1246}
1247
1248/* Although a session start should be in LBA format, we return it in
1249 MSF format because it is slightly easier, and the new generic ioctl
1250 will take care of the necessary conversion. */
1251int cm206_get_last_session(struct cdrom_device_info *cdi,
1252 struct cdrom_multisession *mssp)
1253{
1254 if (!FIRST_TRACK)
1255 get_disc_status();
1256 if (mssp != NULL) {
1257 if (DISC_STATUS & cds_multi_session) { /* multi-session */
1258 mssp->addr.msf.frame = cd->disc_status[3];
1259 mssp->addr.msf.second = cd->disc_status[4];
1260 mssp->addr.msf.minute = cd->disc_status[5];
1261 mssp->addr_format = CDROM_MSF;
1262 mssp->xa_flag = 1;
1263 } else {
1264 mssp->xa_flag = 0;
1265 }
1266 return 1;
1267 }
1268 return 0;
1269}
1270
1271int cm206_get_upc(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn)
1272{
1273 uch upc[10];
1274 char *ret = mcn->medium_catalog_number;
1275 int i;
1276
1277 if (type_1_command(c_read_upc, 10, upc))
1278 return -EIO;
1279 for (i = 0; i < 13; i++) {
1280 int w = i / 2 + 1, r = i % 2;
1281 if (r)
1282 ret[i] = 0x30 | (upc[w] & 0x0f);
1283 else
1284 ret[i] = 0x30 | ((upc[w] >> 4) & 0x0f);
1285 }
1286 ret[13] = '\0';
1287 return 0;
1288}
1289
1290int cm206_reset(struct cdrom_device_info *cdi)
1291{
1292 stop_read();
1293 reset_cm260();
1294 outw(dc_normal | dc_break | READ_AHEAD, r_data_control);
1295 mdelay(1); /* 750 musec minimum */
1296 outw(dc_normal | READ_AHEAD, r_data_control);
1297 cd->sector_last = -1; /* flag no data buffered */
1298 cd->adapter_last = -1;
1299 invalidate_toc();
1300 return 0;
1301}
1302
1303int cm206_select_speed(struct cdrom_device_info *cdi, int speed)
1304{
1305 int r;
1306 switch (speed) {
1307 case 0:
1308 r = type_0_command(c_auto_mode, 1);
1309 break;
1310 case 1:
1311 r = type_0_command(c_force_1x, 1);
1312 break;
1313 case 2:
1314 r = type_0_command(c_force_2x, 1);
1315 break;
1316 default:
1317 return -1;
1318 }
1319 if (r < 0)
1320 return r;
1321 else
1322 return 1;
1323}
1324
1325static struct cdrom_device_ops cm206_dops = {
1326 .open = cm206_open,
1327 .release = cm206_release,
1328 .drive_status = cm206_drive_status,
1329 .media_changed = cm206_media_changed,
1330 .tray_move = cm206_tray_move,
1331 .lock_door = cm206_lock_door,
1332 .select_speed = cm206_select_speed,
1333 .get_last_session = cm206_get_last_session,
1334 .get_mcn = cm206_get_upc,
1335 .reset = cm206_reset,
1336 .audio_ioctl = cm206_audio_ioctl,
1337 .dev_ioctl = cm206_ioctl,
1338 .capability = CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK |
1339 CDC_MULTI_SESSION | CDC_MEDIA_CHANGED |
1340 CDC_MCN | CDC_PLAY_AUDIO | CDC_SELECT_SPEED |
1341 CDC_IOCTLS | CDC_DRIVE_STATUS,
1342 .n_minors = 1,
1343};
1344
1345
1346static struct cdrom_device_info cm206_info = {
1347 .ops = &cm206_dops,
1348 .speed = 2,
1349 .capacity = 1,
1350 .name = "cm206",
1351};
1352
1353static int cm206_block_open(struct inode *inode, struct file *file)
1354{
1355 return cdrom_open(&cm206_info, inode, file);
1356}
1357
1358static int cm206_block_release(struct inode *inode, struct file *file)
1359{
1360 return cdrom_release(&cm206_info, file);
1361}
1362
1363static int cm206_block_ioctl(struct inode *inode, struct file *file,
1364 unsigned cmd, unsigned long arg)
1365{
1366 return cdrom_ioctl(file, &cm206_info, inode, cmd, arg);
1367}
1368
1369static int cm206_block_media_changed(struct gendisk *disk)
1370{
1371 return cdrom_media_changed(&cm206_info);
1372}
1373
1374static struct block_device_operations cm206_bdops =
1375{
1376 .owner = THIS_MODULE,
1377 .open = cm206_block_open,
1378 .release = cm206_block_release,
1379 .ioctl = cm206_block_ioctl,
1380 .media_changed = cm206_block_media_changed,
1381};
1382
1383static struct gendisk *cm206_gendisk;
1384
1385/* This function probes for the adapter card. It returns the base
1386 address if it has found the adapter card. One can specify a base
1387 port to probe specifically, or 0 which means span all possible
1388 bases.
1389
1390 Linus says it is too dangerous to use writes for probing, so we
1391 stick with pure reads for a while. Hope that 8 possible ranges,
1392 request_region, 15 bits of one port and 6 of another make things
1393 likely enough to accept the region on the first hit...
1394 */
1395int __init probe_base_port(int base)
1396{
1397 int b = 0x300, e = 0x370; /* this is the range of start addresses */
1398 volatile int fool, i;
1399
1400 if (base)
1401 b = e = base;
1402 for (base = b; base <= e; base += 0x10) {
1403 if (!request_region(base, 0x10,"cm206"))
1404 continue;
1405 for (i = 0; i < 3; i++)
1406 fool = inw(base + 2); /* empty possibly uart_receive_buffer */
1407 if ((inw(base + 6) & 0xffef) != 0x0001 || /* line_status */
1408 (inw(base) & 0xad00) != 0) { /* data status */
1409 release_region(base,0x10);
1410 continue;
1411 }
1412 return (base);
1413 }
1414 return 0;
1415}
1416
1417#if !defined(MODULE) || defined(AUTO_PROBE_MODULE)
1418/* Probe for irq# nr. If nr==0, probe for all possible irq's. */
1419int __init probe_irq(int nr)
1420{
1421 int irqs, irq;
1422 outw(dc_normal | READ_AHEAD, r_data_control); /* disable irq-generation */
1423 sti();
1424 irqs = probe_irq_on();
1425 reset_cm260(); /* causes interrupt */
1426 udelay(100); /* wait for it */
1427 irq = probe_irq_off(irqs);
1428 outw(dc_normal | READ_AHEAD, r_data_control); /* services interrupt */
1429 if (nr && irq != nr && irq > 0)
1430 return 0; /* wrong interrupt happened */
1431 else
1432 return irq;
1433}
1434#endif
1435
1436int __init cm206_init(void)
1437{
1438 uch e = 0;
1439 long int size = sizeof(struct cm206_struct);
1440 struct gendisk *disk;
1441
1442 printk(KERN_INFO "cm206 cdrom driver " REVISION);
1443 cm206_base = probe_base_port(auto_probe ? 0 : cm206_base);
1444 if (!cm206_base) {
1445 printk(" can't find adapter!\n");
1446 return -EIO;
1447 }
1448 printk(" adapter at 0x%x", cm206_base);
1449 cd = (struct cm206_struct *) kmalloc(size, GFP_KERNEL);
1450 if (!cd)
1451 goto out_base;
1452 /* Now we have found the adaptor card, try to reset it. As we have
1453 * found out earlier, this process generates an interrupt as well,
1454 * so we might just exploit that fact for irq probing! */
1455#if !defined(MODULE) || defined(AUTO_PROBE_MODULE)
1456 cm206_irq = probe_irq(auto_probe ? 0 : cm206_irq);
1457 if (cm206_irq <= 0) {
1458 printk("can't find IRQ!\n");
1459 goto out_probe;
1460 } else
1461 printk(" IRQ %d found\n", cm206_irq);
1462#else
1463 cli();
1464 reset_cm260();
1465 /* Now, the problem here is that reset_cm260 can generate an
1466 interrupt. It seems that this can cause a kernel oops some time
1467 later. So we wait a while and `service' this interrupt. */
1468 mdelay(1);
1469 outw(dc_normal | READ_AHEAD, r_data_control);
1470 sti();
1471 printk(" using IRQ %d\n", cm206_irq);
1472#endif
1473 if (send_receive_polled(c_drive_configuration) !=
1474 c_drive_configuration) {
1475 printk(KERN_INFO " drive not there\n");
1476 goto out_probe;
1477 }
1478 e = send_receive_polled(c_gimme);
1479 printk(KERN_INFO "Firmware revision %d", e & dcf_revision_code);
1480 if (e & dcf_transfer_rate)
1481 printk(" double");
1482 else
1483 printk(" single");
1484 printk(" speed drive");
1485 if (e & dcf_motorized_tray)
1486 printk(", motorized tray");
1487 if (request_irq(cm206_irq, cm206_interrupt, 0, "cm206", NULL)) {
1488 printk("\nUnable to reserve IRQ---aborted\n");
1489 goto out_probe;
1490 }
1491 printk(".\n");
1492
1493 if (register_blkdev(MAJOR_NR, "cm206"))
1494 goto out_blkdev;
1495
1496 disk = alloc_disk(1);
1497 if (!disk)
1498 goto out_disk;
1499 disk->major = MAJOR_NR;
1500 disk->first_minor = 0;
1501 sprintf(disk->disk_name, "cm206cd");
1502 disk->fops = &cm206_bdops;
1503 disk->flags = GENHD_FL_CD;
1504 cm206_gendisk = disk;
1505 if (register_cdrom(&cm206_info) != 0) {
1506 printk(KERN_INFO "Cannot register for cdrom %d!\n", MAJOR_NR);
1507 goto out_cdrom;
1508 }
1509 cm206_queue = blk_init_queue(do_cm206_request, &cm206_lock);
1510 if (!cm206_queue)
1511 goto out_queue;
1512
1513 blk_queue_hardsect_size(cm206_queue, 2048);
1514 disk->queue = cm206_queue;
1515 add_disk(disk);
1516
1517 memset(cd, 0, sizeof(*cd)); /* give'm some reasonable value */
1518 cd->sector_last = -1; /* flag no data buffered */
1519 cd->adapter_last = -1;
1520 init_timer(&cd->timer);
1521 cd->timer.function = cm206_timeout;
1522 cd->max_sectors = (inw(r_data_status) & ds_ram_size) ? 24 : 97;
1523 printk(KERN_INFO "%d kB adapter memory available, "
1524 " %ld bytes kernel memory used.\n", cd->max_sectors * 2,
1525 size);
1526 return 0;
1527
1528out_queue:
1529 unregister_cdrom(&cm206_info);
1530out_cdrom:
1531 put_disk(disk);
1532out_disk:
1533 unregister_blkdev(MAJOR_NR, "cm206");
1534out_blkdev:
1535 free_irq(cm206_irq, NULL);
1536out_probe:
1537 kfree(cd);
1538out_base:
1539 release_region(cm206_base, 16);
1540 return -EIO;
1541}
1542
1543#ifdef MODULE
1544
1545
1546static void __init parse_options(void)
1547{
1548 int i;
1549 for (i = 0; i < 2; i++) {
1550 if (0x300 <= cm206[i] && i <= 0x370
1551 && cm206[i] % 0x10 == 0) {
1552 cm206_base = cm206[i];
1553 auto_probe = 0;
1554 } else if (3 <= cm206[i] && cm206[i] <= 15) {
1555 cm206_irq = cm206[i];
1556 auto_probe = 0;
1557 }
1558 }
1559}
1560
1561int __cm206_init(void)
1562{
1563 parse_options();
1564#if !defined(AUTO_PROBE_MODULE)
1565 auto_probe = 0;
1566#endif
1567 return cm206_init();
1568}
1569
1570void __exit cm206_exit(void)
1571{
1572 del_gendisk(cm206_gendisk);
1573 put_disk(cm206_gendisk);
1574 if (unregister_cdrom(&cm206_info)) {
1575 printk("Can't unregister cdrom cm206\n");
1576 return;
1577 }
1578 if (unregister_blkdev(MAJOR_NR, "cm206")) {
1579 printk("Can't unregister major cm206\n");
1580 return;
1581 }
1582 blk_cleanup_queue(cm206_queue);
1583 free_irq(cm206_irq, NULL);
1584 kfree(cd);
1585 release_region(cm206_base, 16);
1586 printk(KERN_INFO "cm206 removed\n");
1587}
1588
1589module_init(__cm206_init);
1590module_exit(cm206_exit);
1591
1592#else /* !MODULE */
1593
1594/* This setup function accepts either `auto' or numbers in the range
1595 * 3--11 (for irq) or 0x300--0x370 (for base port) or both. */
1596
1597static int __init cm206_setup(char *s)
1598{
1599 int i, p[4];
1600
1601 (void) get_options(s, ARRAY_SIZE(p), p);
1602
1603 if (!strcmp(s, "auto"))
1604 auto_probe = 1;
1605 for (i = 1; i <= p[0]; i++) {
1606 if (0x300 <= p[i] && i <= 0x370 && p[i] % 0x10 == 0) {
1607 cm206_base = p[i];
1608 auto_probe = 0;
1609 } else if (3 <= p[i] && p[i] <= 15) {
1610 cm206_irq = p[i];
1611 auto_probe = 0;
1612 }
1613 }
1614 return 1;
1615}
1616
1617__setup("cm206=", cm206_setup);
1618
1619#endif /* !MODULE */
1620MODULE_ALIAS_BLOCKDEV_MAJOR(CM206_CDROM_MAJOR);
1621
1622/*
1623 * Local variables:
1624 * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/include -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -pipe -fno-strength-reduce -m486 -DMODULE -DMODVERSIONS -include /usr/src/linux/include/linux/modversions.h -c -o cm206.o cm206.c"
1625 * End:
1626 */
diff --git a/drivers/cdrom/cm206.h b/drivers/cdrom/cm206.h
new file mode 100644
index 000000000000..0ae51c1a0dac
--- /dev/null
+++ b/drivers/cdrom/cm206.h
@@ -0,0 +1,171 @@
1/* cm206.h Header file for cm206.c.
2 Copyright (c) 1995 David van Leeuwen
3*/
4
5#ifndef LINUX_CM206_H
6#define LINUX_CM206_H
7
8#include <linux/ioctl.h>
9
10/* First, the cm260 stuff */
11/* The ports and irq used. Although CM206_BASE and CM206_IRQ are defined
12 below, the values are not used unless autoprobing is turned off and
13 no LILO boot options or module command line options are given. Change
14 these values to your own as last resort if autoprobing and options
15 don't work. */
16
17#define CM206_BASE 0x340
18#define CM206_IRQ 11
19
20#define r_data_status (cm206_base)
21#define r_uart_receive (cm206_base+0x2)
22#define r_fifo_output_buffer (cm206_base+0x4)
23#define r_line_status (cm206_base+0x6)
24#define r_data_control (cm206_base+0x8)
25#define r_uart_transmit (cm206_base+0xa)
26#define r_test_clock (cm206_base+0xc)
27#define r_test_control (cm206_base+0xe)
28
29/* the data_status flags */
30#define ds_ram_size 0x4000
31#define ds_toc_ready 0x2000
32#define ds_fifo_empty 0x1000
33#define ds_sync_error 0x800
34#define ds_crc_error 0x400
35#define ds_data_error 0x200
36#define ds_fifo_overflow 0x100
37#define ds_data_ready 0x80
38
39/* the line_status flags */
40#define ls_attention 0x10
41#define ls_parity_error 0x8
42#define ls_overrun 0x4
43#define ls_receive_buffer_full 0x2
44#define ls_transmitter_buffer_empty 0x1
45
46/* the data control register flags */
47#define dc_read_q_channel 0x4000
48#define dc_mask_sync_error 0x2000
49#define dc_toc_enable 0x1000
50#define dc_no_stop_on_error 0x800
51#define dc_break 0x400
52#define dc_initialize 0x200
53#define dc_mask_transmit_ready 0x100
54#define dc_flag_enable 0x80
55
56/* Define the default data control register flags here */
57#define dc_normal (dc_mask_sync_error | dc_no_stop_on_error | \
58 dc_mask_transmit_ready)
59
60/* now some constants related to the cm206 */
61/* another drive status byte, echoed by the cm206 on most commands */
62
63#define dsb_error_condition 0x1
64#define dsb_play_in_progress 0x4
65#define dsb_possible_media_change 0x8
66#define dsb_disc_present 0x10
67#define dsb_drive_not_ready 0x20
68#define dsb_tray_locked 0x40
69#define dsb_tray_not_closed 0x80
70
71#define dsb_not_useful (dsb_drive_not_ready | dsb_tray_not_closed)
72
73/* the cm206 command set */
74
75#define c_close_tray 0
76#define c_lock_tray 0x01
77#define c_unlock_tray 0x04
78#define c_open_tray 0x05
79#define c_seek 0x10
80#define c_read_data 0x20
81#define c_force_1x 0x21
82#define c_force_2x 0x22
83#define c_auto_mode 0x23
84#define c_play 0x30
85#define c_set_audio_mode 0x31
86#define c_read_current_q 0x41
87#define c_stream_q 0x42
88#define c_drive_status 0x50
89#define c_disc_status 0x51
90#define c_audio_status 0x52
91#define c_drive_configuration 0x53
92#define c_read_upc 0x60
93#define c_stop 0x70
94#define c_calc_checksum 0xe5
95
96#define c_gimme 0xf8
97
98/* finally, the (error) condition that the drive can be in *
99 * OK, this is not always an error, but let's prefix it with e_ */
100
101#define e_none 0
102#define e_illegal_command 0x01
103#define e_sync 0x02
104#define e_seek 0x03
105#define e_parity 0x04
106#define e_focus 0x05
107#define e_header_sync 0x06
108#define e_code_incompatibility 0x07
109#define e_reset_done 0x08
110#define e_bad_parameter 0x09
111#define e_radial 0x0a
112#define e_sub_code 0x0b
113#define e_no_data_track 0x0c
114#define e_scan 0x0d
115#define e_tray_open 0x0f
116#define e_no_disc 0x10
117#define e_tray stalled 0x11
118
119/* drive configuration masks */
120
121#define dcf_revision_code 0x7
122#define dcf_transfer_rate 0x60
123#define dcf_motorized_tray 0x80
124
125/* disc status byte */
126
127#define cds_multi_session 0x2
128#define cds_all_audio 0x8
129#define cds_xa_mode 0xf0
130
131/* finally some ioctls for the driver */
132
133#define CM206CTL_GET_STAT _IO( 0x20, 0 )
134#define CM206CTL_GET_LAST_STAT _IO( 0x20, 1 )
135
136#ifdef STATISTICS
137
138/* This is an ugly way to guarantee that the names of the statistics
139 * are the same in the code and in the diagnostics program. */
140
141#ifdef __KERNEL__
142#define x(a) st_ ## a
143#define y enum
144#else
145#define x(a) #a
146#define y char * stats_name[] =
147#endif
148
149y {x(interrupt), x(data_ready), x(fifo_overflow), x(data_error),
150 x(crc_error), x(sync_error), x(lost_intr), x(echo),
151 x(write_timeout), x(receive_timeout), x(read_timeout),
152 x(dsb_timeout), x(stop_0xff), x(back_read_timeout),
153 x(sector_transferred), x(read_restarted), x(read_background),
154 x(bh), x(open), x(ioctl_multisession), x(attention)
155#ifdef __KERNEL__
156 , x(last_entry)
157#endif
158 };
159
160#ifdef __KERNEL__
161#define NR_STATS st_last_entry
162#else
163#define NR_STATS (sizeof(stats_name)/sizeof(char*))
164#endif
165
166#undef y
167#undef x
168
169#endif /* STATISTICS */
170
171#endif /* LINUX_CM206_H */
diff --git a/drivers/cdrom/gscd.c b/drivers/cdrom/gscd.c
new file mode 100644
index 000000000000..7eac10e63b23
--- /dev/null
+++ b/drivers/cdrom/gscd.c
@@ -0,0 +1,1031 @@
1#define GSCD_VERSION "0.4a Oliver Raupach <raupach@nwfs1.rz.fh-hannover.de>"
2
3/*
4 linux/drivers/block/gscd.c - GoldStar R420 CDROM driver
5
6 Copyright (C) 1995 Oliver Raupach <raupach@nwfs1.rz.fh-hannover.de>
7 based upon pre-works by Eberhard Moenkeberg <emoenke@gwdg.de>
8
9
10 For all kind of other information about the GoldStar CDROM
11 and this Linux device driver I installed a WWW-URL:
12 http://linux.rz.fh-hannover.de/~raupach
13
14
15 If you are the editor of a Linux CD, you should
16 enable gscd.c within your boot floppy kernel and
17 send me one of your CDs for free.
18
19
20 --------------------------------------------------------------------
21 This program is free software; you can redistribute it and/or modify
22 it under the terms of the GNU General Public License as published by
23 the Free Software Foundation; either version 2, or (at your option)
24 any later version.
25
26 This program is distributed in the hope that it will be useful,
27 but WITHOUT ANY WARRANTY; without even the implied warranty of
28 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29 GNU General Public License for more details.
30
31 You should have received a copy of the GNU General Public License
32 along with this program; if not, write to the Free Software
33 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
34
35 --------------------------------------------------------------------
36
37 9 November 1999 -- Make kernel-parameter implementation work with 2.3.x
38 Removed init_module & cleanup_module in favor of
39 module_init & module_exit.
40 Torben Mathiasen <tmm@image.dk>
41
42*/
43
44/* These settings are for various debug-level. Leave they untouched ... */
45#define NO_GSCD_DEBUG
46#define NO_IOCTL_DEBUG
47#define NO_MODULE_DEBUG
48#define NO_FUTURE_WORK
49/*------------------------*/
50
51#include <linux/module.h>
52
53#include <linux/slab.h>
54#include <linux/errno.h>
55#include <linux/signal.h>
56#include <linux/sched.h>
57#include <linux/timer.h>
58#include <linux/fs.h>
59#include <linux/mm.h>
60#include <linux/kernel.h>
61#include <linux/cdrom.h>
62#include <linux/ioport.h>
63#include <linux/major.h>
64#include <linux/string.h>
65#include <linux/init.h>
66
67#include <asm/system.h>
68#include <asm/io.h>
69#include <asm/uaccess.h>
70
71#define MAJOR_NR GOLDSTAR_CDROM_MAJOR
72#include <linux/blkdev.h>
73#include "gscd.h"
74
75static int gscdPresent = 0;
76
77static unsigned char gscd_buf[2048]; /* buffer for block size conversion */
78static int gscd_bn = -1;
79static short gscd_port = GSCD_BASE_ADDR;
80module_param_named(gscd, gscd_port, short, 0);
81
82/* Kommt spaeter vielleicht noch mal dran ...
83 * static DECLARE_WAIT_QUEUE_HEAD(gscd_waitq);
84 */
85
86static void gscd_read_cmd(struct request *req);
87static void gscd_hsg2msf(long hsg, struct msf *msf);
88static void gscd_bin2bcd(unsigned char *p);
89
90/* Schnittstellen zum Kern/FS */
91
92static void __do_gscd_request(unsigned long dummy);
93static int gscd_ioctl(struct inode *, struct file *, unsigned int,
94 unsigned long);
95static int gscd_open(struct inode *, struct file *);
96static int gscd_release(struct inode *, struct file *);
97static int check_gscd_med_chg(struct gendisk *disk);
98
99/* GoldStar Funktionen */
100
101static void cmd_out(int, char *, char *, int);
102static void cmd_status(void);
103static void init_cd_drive(int);
104
105static int get_status(void);
106static void clear_Audio(void);
107static void cc_invalidate(void);
108
109/* some things for the next version */
110#ifdef FUTURE_WORK
111static void update_state(void);
112static long gscd_msf2hsg(struct msf *mp);
113static int gscd_bcd2bin(unsigned char bcd);
114#endif
115
116
117/* lo-level cmd-Funktionen */
118
119static void cmd_info_in(char *, int);
120static void cmd_end(void);
121static void cmd_read_b(char *, int, int);
122static void cmd_read_w(char *, int, int);
123static int cmd_unit_alive(void);
124static void cmd_write_cmd(char *);
125
126
127/* GoldStar Variablen */
128
129static int curr_drv_state;
130static int drv_states[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
131static int drv_mode;
132static int disk_state;
133static int speed;
134static int ndrives;
135
136static unsigned char drv_num_read;
137static unsigned char f_dsk_valid;
138static unsigned char current_drive;
139static unsigned char f_drv_ok;
140
141
142static char f_AudioPlay;
143static char f_AudioPause;
144static int AudioStart_m;
145static int AudioStart_f;
146static int AudioEnd_m;
147static int AudioEnd_f;
148
149static struct timer_list gscd_timer = TIMER_INITIALIZER(NULL, 0, 0);
150static DEFINE_SPINLOCK(gscd_lock);
151static struct request_queue *gscd_queue;
152
153static struct block_device_operations gscd_fops = {
154 .owner = THIS_MODULE,
155 .open = gscd_open,
156 .release = gscd_release,
157 .ioctl = gscd_ioctl,
158 .media_changed = check_gscd_med_chg,
159};
160
161/*
162 * Checking if the media has been changed
163 * (not yet implemented)
164 */
165static int check_gscd_med_chg(struct gendisk *disk)
166{
167#ifdef GSCD_DEBUG
168 printk("gscd: check_med_change\n");
169#endif
170 return 0;
171}
172
173
174#ifndef MODULE
175/* Using new interface for kernel-parameters */
176
177static int __init gscd_setup(char *str)
178{
179 int ints[2];
180 (void) get_options(str, ARRAY_SIZE(ints), ints);
181
182 if (ints[0] > 0) {
183 gscd_port = ints[1];
184 }
185 return 1;
186}
187
188__setup("gscd=", gscd_setup);
189
190#endif
191
192static int gscd_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
193 unsigned long arg)
194{
195 unsigned char to_do[10];
196 unsigned char dummy;
197
198
199 switch (cmd) {
200 case CDROMSTART: /* Spin up the drive */
201 /* Don't think we can do this. Even if we could,
202 * I think the drive times out and stops after a while
203 * anyway. For now, ignore it.
204 */
205 return 0;
206
207 case CDROMRESUME: /* keine Ahnung was das ist */
208 return 0;
209
210
211 case CDROMEJECT:
212 cmd_status();
213 to_do[0] = CMD_TRAY_CTL;
214 cmd_out(TYPE_INFO, (char *) &to_do, (char *) &dummy, 0);
215
216 return 0;
217
218 default:
219 return -EINVAL;
220 }
221
222}
223
224
225/*
226 * Take care of the different block sizes between cdrom and Linux.
227 * When Linux gets variable block sizes this will probably go away.
228 */
229
230static void gscd_transfer(struct request *req)
231{
232 while (req->nr_sectors > 0 && gscd_bn == req->sector / 4) {
233 long offs = (req->sector & 3) * 512;
234 memcpy(req->buffer, gscd_buf + offs, 512);
235 req->nr_sectors--;
236 req->sector++;
237 req->buffer += 512;
238 }
239}
240
241
242/*
243 * I/O request routine called from Linux kernel.
244 */
245
246static void do_gscd_request(request_queue_t * q)
247{
248 __do_gscd_request(0);
249}
250
251static void __do_gscd_request(unsigned long dummy)
252{
253 struct request *req;
254 unsigned int block;
255 unsigned int nsect;
256
257repeat:
258 req = elv_next_request(gscd_queue);
259 if (!req)
260 return;
261
262 block = req->sector;
263 nsect = req->nr_sectors;
264
265 if (req->sector == -1)
266 goto out;
267
268 if (req->cmd != READ) {
269 printk("GSCD: bad cmd %lu\n", rq_data_dir(req));
270 end_request(req, 0);
271 goto repeat;
272 }
273
274 gscd_transfer(req);
275
276 /* if we satisfied the request from the buffer, we're done. */
277
278 if (req->nr_sectors == 0) {
279 end_request(req, 1);
280 goto repeat;
281 }
282#ifdef GSCD_DEBUG
283 printk("GSCD: block %d, nsect %d\n", block, nsect);
284#endif
285 gscd_read_cmd(req);
286out:
287 return;
288}
289
290
291
292/*
293 * Check the result of the set-mode command. On success, send the
294 * read-data command.
295 */
296
297static void gscd_read_cmd(struct request *req)
298{
299 long block;
300 struct gscd_Play_msf gscdcmd;
301 char cmd[] = { CMD_READ, 0x80, 0, 0, 0, 0, 1 }; /* cmd mode M-S-F secth sectl */
302
303 cmd_status();
304 if (disk_state & (ST_NO_DISK | ST_DOOR_OPEN)) {
305 printk("GSCD: no disk or door open\n");
306 end_request(req, 0);
307 } else {
308 if (disk_state & ST_INVALID) {
309 printk("GSCD: disk invalid\n");
310 end_request(req, 0);
311 } else {
312 gscd_bn = -1; /* purge our buffer */
313 block = req->sector / 4;
314 gscd_hsg2msf(block, &gscdcmd.start); /* cvt to msf format */
315
316 cmd[2] = gscdcmd.start.min;
317 cmd[3] = gscdcmd.start.sec;
318 cmd[4] = gscdcmd.start.frame;
319
320#ifdef GSCD_DEBUG
321 printk("GSCD: read msf %d:%d:%d\n", cmd[2], cmd[3],
322 cmd[4]);
323#endif
324 cmd_out(TYPE_DATA, (char *) &cmd,
325 (char *) &gscd_buf[0], 1);
326
327 gscd_bn = req->sector / 4;
328 gscd_transfer(req);
329 end_request(req, 1);
330 }
331 }
332 SET_TIMER(__do_gscd_request, 1);
333}
334
335
336/*
337 * Open the device special file. Check that a disk is in.
338 */
339
340static int gscd_open(struct inode *ip, struct file *fp)
341{
342 int st;
343
344#ifdef GSCD_DEBUG
345 printk("GSCD: open\n");
346#endif
347
348 if (gscdPresent == 0)
349 return -ENXIO; /* no hardware */
350
351 get_status();
352 st = disk_state & (ST_NO_DISK | ST_DOOR_OPEN);
353 if (st) {
354 printk("GSCD: no disk or door open\n");
355 return -ENXIO;
356 }
357
358/* if (updateToc() < 0)
359 return -EIO;
360*/
361
362 return 0;
363}
364
365
366/*
367 * On close, we flush all gscd blocks from the buffer cache.
368 */
369
370static int gscd_release(struct inode *inode, struct file *file)
371{
372
373#ifdef GSCD_DEBUG
374 printk("GSCD: release\n");
375#endif
376
377 gscd_bn = -1;
378
379 return 0;
380}
381
382
383static int get_status(void)
384{
385 int status;
386
387 cmd_status();
388 status = disk_state & (ST_x08 | ST_x04 | ST_INVALID | ST_x01);
389
390 if (status == (ST_x08 | ST_x04 | ST_INVALID | ST_x01)) {
391 cc_invalidate();
392 return 1;
393 } else {
394 return 0;
395 }
396}
397
398
399static void cc_invalidate(void)
400{
401 drv_num_read = 0xFF;
402 f_dsk_valid = 0xFF;
403 current_drive = 0xFF;
404 f_drv_ok = 0xFF;
405
406 clear_Audio();
407
408}
409
410static void clear_Audio(void)
411{
412
413 f_AudioPlay = 0;
414 f_AudioPause = 0;
415 AudioStart_m = 0;
416 AudioStart_f = 0;
417 AudioEnd_m = 0;
418 AudioEnd_f = 0;
419
420}
421
422/*
423 * waiting ?
424 */
425
426static int wait_drv_ready(void)
427{
428 int found, read;
429
430 do {
431 found = inb(GSCDPORT(0));
432 found &= 0x0f;
433 read = inb(GSCDPORT(0));
434 read &= 0x0f;
435 } while (read != found);
436
437#ifdef GSCD_DEBUG
438 printk("Wait for: %d\n", read);
439#endif
440
441 return read;
442}
443
444static void cc_Ident(char *respons)
445{
446 char to_do[] = { CMD_IDENT, 0, 0 };
447
448 cmd_out(TYPE_INFO, (char *) &to_do, (char *) respons, (int) 0x1E);
449
450}
451
452static void cc_SetSpeed(void)
453{
454 char to_do[] = { CMD_SETSPEED, 0, 0 };
455 char dummy;
456
457 if (speed > 0) {
458 to_do[1] = speed & 0x0F;
459 cmd_out(TYPE_INFO, (char *) &to_do, (char *) &dummy, 0);
460 }
461}
462
463static void cc_Reset(void)
464{
465 char to_do[] = { CMD_RESET, 0 };
466 char dummy;
467
468 cmd_out(TYPE_INFO, (char *) &to_do, (char *) &dummy, 0);
469}
470
471static void cmd_status(void)
472{
473 char to_do[] = { CMD_STATUS, 0 };
474 char dummy;
475
476 cmd_out(TYPE_INFO, (char *) &to_do, (char *) &dummy, 0);
477
478#ifdef GSCD_DEBUG
479 printk("GSCD: Status: %d\n", disk_state);
480#endif
481
482}
483
484static void cmd_out(int cmd_type, char *cmd, char *respo_buf, int respo_count)
485{
486 int result;
487
488
489 result = wait_drv_ready();
490 if (result != drv_mode) {
491 unsigned long test_loops = 0xFFFF;
492 int i, dummy;
493
494 outb(curr_drv_state, GSCDPORT(0));
495
496 /* LOCLOOP_170 */
497 do {
498 result = wait_drv_ready();
499 test_loops--;
500 } while ((result != drv_mode) && (test_loops > 0));
501
502 if (result != drv_mode) {
503 disk_state = ST_x08 | ST_x04 | ST_INVALID;
504 return;
505 }
506
507 /* ...and waiting */
508 for (i = 1, dummy = 1; i < 0xFFFF; i++) {
509 dummy *= i;
510 }
511 }
512
513 /* LOC_172 */
514 /* check the unit */
515 /* and wake it up */
516 if (cmd_unit_alive() != 0x08) {
517 /* LOC_174 */
518 /* game over for this unit */
519 disk_state = ST_x08 | ST_x04 | ST_INVALID;
520 return;
521 }
522
523 /* LOC_176 */
524#ifdef GSCD_DEBUG
525 printk("LOC_176 ");
526#endif
527 if (drv_mode == 0x09) {
528 /* magic... */
529 printk("GSCD: magic ...\n");
530 outb(result, GSCDPORT(2));
531 }
532
533 /* write the command to the drive */
534 cmd_write_cmd(cmd);
535
536 /* LOC_178 */
537 for (;;) {
538 result = wait_drv_ready();
539 if (result != drv_mode) {
540 /* LOC_179 */
541 if (result == 0x04) { /* Mode 4 */
542 /* LOC_205 */
543#ifdef GSCD_DEBUG
544 printk("LOC_205 ");
545#endif
546 disk_state = inb(GSCDPORT(2));
547
548 do {
549 result = wait_drv_ready();
550 } while (result != drv_mode);
551 return;
552
553 } else {
554 if (result == 0x06) { /* Mode 6 */
555 /* LOC_181 */
556#ifdef GSCD_DEBUG
557 printk("LOC_181 ");
558#endif
559
560 if (cmd_type == TYPE_DATA) {
561 /* read data */
562 /* LOC_184 */
563 if (drv_mode == 9) {
564 /* read the data to the buffer (word) */
565
566 /* (*(cmd+1))?(CD_FRAMESIZE/2):(CD_FRAMESIZE_RAW/2) */
567 cmd_read_w
568 (respo_buf,
569 respo_count,
570 CD_FRAMESIZE /
571 2);
572 return;
573 } else {
574 /* read the data to the buffer (byte) */
575
576 /* (*(cmd+1))?(CD_FRAMESIZE):(CD_FRAMESIZE_RAW) */
577 cmd_read_b
578 (respo_buf,
579 respo_count,
580 CD_FRAMESIZE);
581 return;
582 }
583 } else {
584 /* read the info to the buffer */
585 cmd_info_in(respo_buf,
586 respo_count);
587 return;
588 }
589
590 return;
591 }
592 }
593
594 } else {
595 disk_state = ST_x08 | ST_x04 | ST_INVALID;
596 return;
597 }
598 } /* for (;;) */
599
600
601#ifdef GSCD_DEBUG
602 printk("\n");
603#endif
604}
605
606
607static void cmd_write_cmd(char *pstr)
608{
609 int i, j;
610
611 /* LOC_177 */
612#ifdef GSCD_DEBUG
613 printk("LOC_177 ");
614#endif
615
616 /* calculate the number of parameter */
617 j = *pstr & 0x0F;
618
619 /* shift it out */
620 for (i = 0; i < j; i++) {
621 outb(*pstr, GSCDPORT(2));
622 pstr++;
623 }
624}
625
626
627static int cmd_unit_alive(void)
628{
629 int result;
630 unsigned long max_test_loops;
631
632
633 /* LOC_172 */
634#ifdef GSCD_DEBUG
635 printk("LOC_172 ");
636#endif
637
638 outb(curr_drv_state, GSCDPORT(0));
639 max_test_loops = 0xFFFF;
640
641 do {
642 result = wait_drv_ready();
643 max_test_loops--;
644 } while ((result != 0x08) && (max_test_loops > 0));
645
646 return result;
647}
648
649
650static void cmd_info_in(char *pb, int count)
651{
652 int result;
653 char read;
654
655
656 /* read info */
657 /* LOC_182 */
658#ifdef GSCD_DEBUG
659 printk("LOC_182 ");
660#endif
661
662 do {
663 read = inb(GSCDPORT(2));
664 if (count > 0) {
665 *pb = read;
666 pb++;
667 count--;
668 }
669
670 /* LOC_183 */
671 do {
672 result = wait_drv_ready();
673 } while (result == 0x0E);
674 } while (result == 6);
675
676 cmd_end();
677 return;
678}
679
680
681static void cmd_read_b(char *pb, int count, int size)
682{
683 int result;
684 int i;
685
686
687 /* LOC_188 */
688 /* LOC_189 */
689#ifdef GSCD_DEBUG
690 printk("LOC_189 ");
691#endif
692
693 do {
694 do {
695 result = wait_drv_ready();
696 } while (result != 6 || result == 0x0E);
697
698 if (result != 6) {
699 cmd_end();
700 return;
701 }
702#ifdef GSCD_DEBUG
703 printk("LOC_191 ");
704#endif
705
706 for (i = 0; i < size; i++) {
707 *pb = inb(GSCDPORT(2));
708 pb++;
709 }
710 count--;
711 } while (count > 0);
712
713 cmd_end();
714 return;
715}
716
717
718static void cmd_end(void)
719{
720 int result;
721
722
723 /* LOC_204 */
724#ifdef GSCD_DEBUG
725 printk("LOC_204 ");
726#endif
727
728 do {
729 result = wait_drv_ready();
730 if (result == drv_mode) {
731 return;
732 }
733 } while (result != 4);
734
735 /* LOC_205 */
736#ifdef GSCD_DEBUG
737 printk("LOC_205 ");
738#endif
739
740 disk_state = inb(GSCDPORT(2));
741
742 do {
743 result = wait_drv_ready();
744 } while (result != drv_mode);
745 return;
746
747}
748
749
750static void cmd_read_w(char *pb, int count, int size)
751{
752 int result;
753 int i;
754
755
756#ifdef GSCD_DEBUG
757 printk("LOC_185 ");
758#endif
759
760 do {
761 /* LOC_185 */
762 do {
763 result = wait_drv_ready();
764 } while (result != 6 || result == 0x0E);
765
766 if (result != 6) {
767 cmd_end();
768 return;
769 }
770
771 for (i = 0; i < size; i++) {
772 /* na, hier muss ich noch mal drueber nachdenken */
773 *pb = inw(GSCDPORT(2));
774 pb++;
775 }
776 count--;
777 } while (count > 0);
778
779 cmd_end();
780 return;
781}
782
783static int __init find_drives(void)
784{
785 int *pdrv;
786 int drvnum;
787 int subdrv;
788 int i;
789
790 speed = 0;
791 pdrv = (int *) &drv_states;
792 curr_drv_state = 0xFE;
793 subdrv = 0;
794 drvnum = 0;
795
796 for (i = 0; i < 8; i++) {
797 subdrv++;
798 cmd_status();
799 disk_state &= ST_x08 | ST_x04 | ST_INVALID | ST_x01;
800 if (disk_state != (ST_x08 | ST_x04 | ST_INVALID)) {
801 /* LOC_240 */
802 *pdrv = curr_drv_state;
803 init_cd_drive(drvnum);
804 pdrv++;
805 drvnum++;
806 } else {
807 if (subdrv < 2) {
808 continue;
809 } else {
810 subdrv = 0;
811 }
812 }
813
814/* curr_drv_state<<1; <-- das geht irgendwie nicht */
815/* muss heissen: curr_drv_state <<= 1; (ist ja Wert-Zuweisung) */
816 curr_drv_state *= 2;
817 curr_drv_state |= 1;
818#ifdef GSCD_DEBUG
819 printk("DriveState: %d\n", curr_drv_state);
820#endif
821 }
822
823 ndrives = drvnum;
824 return drvnum;
825}
826
827static void __init init_cd_drive(int num)
828{
829 char resp[50];
830 int i;
831
832 printk("GSCD: init unit %d\n", num);
833 cc_Ident((char *) &resp);
834
835 printk("GSCD: identification: ");
836 for (i = 0; i < 0x1E; i++) {
837 printk("%c", resp[i]);
838 }
839 printk("\n");
840
841 cc_SetSpeed();
842
843}
844
845#ifdef FUTURE_WORK
846/* return_done */
847static void update_state(void)
848{
849 unsigned int AX;
850
851
852 if ((disk_state & (ST_x08 | ST_x04 | ST_INVALID | ST_x01)) == 0) {
853 if (disk_state == (ST_x08 | ST_x04 | ST_INVALID)) {
854 AX = ST_INVALID;
855 }
856
857 if ((disk_state & (ST_x08 | ST_x04 | ST_INVALID | ST_x01))
858 == 0) {
859 invalidate();
860 f_drv_ok = 0;
861 }
862
863 AX |= 0x8000;
864 }
865
866 if (disk_state & ST_PLAYING) {
867 AX |= 0x200;
868 }
869
870 AX |= 0x100;
871 /* pkt_esbx = AX; */
872
873 disk_state = 0;
874
875}
876#endif
877
878static struct gendisk *gscd_disk;
879
880static void __exit gscd_exit(void)
881{
882 CLEAR_TIMER;
883
884 del_gendisk(gscd_disk);
885 put_disk(gscd_disk);
886 if ((unregister_blkdev(MAJOR_NR, "gscd") == -EINVAL)) {
887 printk("What's that: can't unregister GoldStar-module\n");
888 return;
889 }
890 blk_cleanup_queue(gscd_queue);
891 release_region(gscd_port, GSCD_IO_EXTENT);
892 printk(KERN_INFO "GoldStar-module released.\n");
893}
894
895/* This is the common initialisation for the GoldStar drive. */
896/* It is called at boot time AND for module init. */
897static int __init gscd_init(void)
898{
899 int i;
900 int result;
901 int ret=0;
902
903 printk(KERN_INFO "GSCD: version %s\n", GSCD_VERSION);
904 printk(KERN_INFO
905 "GSCD: Trying to detect a Goldstar R420 CD-ROM drive at 0x%X.\n",
906 gscd_port);
907
908 if (!request_region(gscd_port, GSCD_IO_EXTENT, "gscd")) {
909 printk(KERN_WARNING "GSCD: Init failed, I/O port (%X) already"
910 " in use.\n", gscd_port);
911 return -EIO;
912 }
913
914
915 /* check for card */
916 result = wait_drv_ready();
917 if (result == 0x09) {
918 printk(KERN_WARNING "GSCD: DMA kann ich noch nicht!\n");
919 ret = -EIO;
920 goto err_out1;
921 }
922
923 if (result == 0x0b) {
924 drv_mode = result;
925 i = find_drives();
926 if (i == 0) {
927 printk(KERN_WARNING "GSCD: GoldStar CD-ROM Drive is"
928 " not found.\n");
929 ret = -EIO;
930 goto err_out1;
931 }
932 }
933
934 if ((result != 0x0b) && (result != 0x09)) {
935 printk(KERN_WARNING "GSCD: GoldStar Interface Adapter does not "
936 "exist or H/W error\n");
937 ret = -EIO;
938 goto err_out1;
939 }
940
941 /* reset all drives */
942 i = 0;
943 while (drv_states[i] != 0) {
944 curr_drv_state = drv_states[i];
945 printk(KERN_INFO "GSCD: Reset unit %d ... ", i);
946 cc_Reset();
947 printk("done\n");
948 i++;
949 }
950
951 gscd_disk = alloc_disk(1);
952 if (!gscd_disk)
953 goto err_out1;
954 gscd_disk->major = MAJOR_NR;
955 gscd_disk->first_minor = 0;
956 gscd_disk->fops = &gscd_fops;
957 sprintf(gscd_disk->disk_name, "gscd");
958 sprintf(gscd_disk->devfs_name, "gscd");
959
960 if (register_blkdev(MAJOR_NR, "gscd")) {
961 ret = -EIO;
962 goto err_out2;
963 }
964
965 gscd_queue = blk_init_queue(do_gscd_request, &gscd_lock);
966 if (!gscd_queue) {
967 ret = -ENOMEM;
968 goto err_out3;
969 }
970
971 disk_state = 0;
972 gscdPresent = 1;
973
974 gscd_disk->queue = gscd_queue;
975 add_disk(gscd_disk);
976
977 printk(KERN_INFO "GSCD: GoldStar CD-ROM Drive found.\n");
978 return 0;
979
980err_out3:
981 unregister_blkdev(MAJOR_NR, "gscd");
982err_out2:
983 put_disk(gscd_disk);
984err_out1:
985 release_region(gscd_port, GSCD_IO_EXTENT);
986 return ret;
987}
988
989static void gscd_hsg2msf(long hsg, struct msf *msf)
990{
991 hsg += CD_MSF_OFFSET;
992 msf->min = hsg / (CD_FRAMES * CD_SECS);
993 hsg %= CD_FRAMES * CD_SECS;
994 msf->sec = hsg / CD_FRAMES;
995 msf->frame = hsg % CD_FRAMES;
996
997 gscd_bin2bcd(&msf->min); /* convert to BCD */
998 gscd_bin2bcd(&msf->sec);
999 gscd_bin2bcd(&msf->frame);
1000}
1001
1002
1003static void gscd_bin2bcd(unsigned char *p)
1004{
1005 int u, t;
1006
1007 u = *p % 10;
1008 t = *p / 10;
1009 *p = u | (t << 4);
1010}
1011
1012
1013#ifdef FUTURE_WORK
1014static long gscd_msf2hsg(struct msf *mp)
1015{
1016 return gscd_bcd2bin(mp->frame)
1017 + gscd_bcd2bin(mp->sec) * CD_FRAMES
1018 + gscd_bcd2bin(mp->min) * CD_FRAMES * CD_SECS - CD_MSF_OFFSET;
1019}
1020
1021static int gscd_bcd2bin(unsigned char bcd)
1022{
1023 return (bcd >> 4) * 10 + (bcd & 0xF);
1024}
1025#endif
1026
1027MODULE_AUTHOR("Oliver Raupach <raupach@nwfs1.rz.fh-hannover.de>");
1028MODULE_LICENSE("GPL");
1029module_init(gscd_init);
1030module_exit(gscd_exit);
1031MODULE_ALIAS_BLOCKDEV_MAJOR(GOLDSTAR_CDROM_MAJOR);
diff --git a/drivers/cdrom/gscd.h b/drivers/cdrom/gscd.h
new file mode 100644
index 000000000000..a41e64bfc061
--- /dev/null
+++ b/drivers/cdrom/gscd.h
@@ -0,0 +1,108 @@
1/*
2 * Definitions for a GoldStar R420 CD-ROM interface
3 *
4 * Copyright (C) 1995 Oliver Raupach <raupach@nwfs1.rz.fh-hannover.de>
5 * Eberhard Moenkeberg <emoenke@gwdg.de>
6 *
7 * Published under the GPL.
8 *
9 */
10
11
12/* The Interface Card default address is 0x340. This will work for most
13 applications. Address selection is accomplished by jumpers PN801-1 to
14 PN801-4 on the GoldStar Interface Card.
15 Appropriate settings are: 0x300, 0x310, 0x320, 0x330, 0x340, 0x350, 0x360
16 0x370, 0x380, 0x390, 0x3A0, 0x3B0, 0x3C0, 0x3D0, 0x3E0, 0x3F0 */
17
18/* insert here the I/O port address and extent */
19#define GSCD_BASE_ADDR 0x340
20#define GSCD_IO_EXTENT 4
21
22
23/************** nothing to set up below here *********************/
24
25/* port access macro */
26#define GSCDPORT(x) (gscd_port + (x))
27
28/*
29 * commands
30 * the lower nibble holds the command length
31 */
32#define CMD_STATUS 0x01
33#define CMD_READSUBQ 0x02 /* 1: ?, 2: UPC, 5: ? */
34#define CMD_SEEK 0x05 /* read_mode M-S-F */
35#define CMD_READ 0x07 /* read_mode M-S-F nsec_h nsec_l */
36#define CMD_RESET 0x11
37#define CMD_SETMODE 0x15
38#define CMD_PLAY 0x17 /* M-S-F M-S-F */
39#define CMD_LOCK_CTL 0x22 /* 0: unlock, 1: lock */
40#define CMD_IDENT 0x31
41#define CMD_SETSPEED 0x32 /* 0: auto */ /* ??? */
42#define CMD_GETMODE 0x41
43#define CMD_PAUSE 0x51
44#define CMD_READTOC 0x61
45#define CMD_DISKINFO 0x71
46#define CMD_TRAY_CTL 0x81
47
48/*
49 * disk_state:
50 */
51#define ST_PLAYING 0x80
52#define ST_UNLOCKED 0x40
53#define ST_NO_DISK 0x20
54#define ST_DOOR_OPEN 0x10
55#define ST_x08 0x08
56#define ST_x04 0x04
57#define ST_INVALID 0x02
58#define ST_x01 0x01
59
60/*
61 * cmd_type:
62 */
63#define TYPE_INFO 0x01
64#define TYPE_DATA 0x02
65
66/*
67 * read_mode:
68 */
69#define MOD_POLLED 0x80
70#define MOD_x08 0x08
71#define MOD_RAW 0x04
72
73#define READ_DATA(port, buf, nr) insb(port, buf, nr)
74
75#define SET_TIMER(func, jifs) \
76 ((mod_timer(&gscd_timer, jiffies + jifs)), \
77 (gscd_timer.function = func))
78
79#define CLEAR_TIMER del_timer_sync(&gscd_timer)
80
81#define MAX_TRACKS 104
82
83struct msf {
84 unsigned char min;
85 unsigned char sec;
86 unsigned char frame;
87};
88
89struct gscd_Play_msf {
90 struct msf start;
91 struct msf end;
92};
93
94struct gscd_DiskInfo {
95 unsigned char first;
96 unsigned char last;
97 struct msf diskLength;
98 struct msf firstTrack;
99};
100
101struct gscd_Toc {
102 unsigned char ctrl_addr;
103 unsigned char track;
104 unsigned char pointIndex;
105 struct msf trackTime;
106 struct msf diskTime;
107};
108
diff --git a/drivers/cdrom/isp16.c b/drivers/cdrom/isp16.c
new file mode 100644
index 000000000000..8e68d858ce64
--- /dev/null
+++ b/drivers/cdrom/isp16.c
@@ -0,0 +1,374 @@
1/* -- ISP16 cdrom detection and configuration
2 *
3 * Copyright (c) 1995,1996 Eric van der Maarel <H.T.M.v.d.Maarel@marin.nl>
4 *
5 * Version 0.6
6 *
7 * History:
8 * 0.5 First release.
9 * Was included in the sjcd and optcd cdrom drivers.
10 * 0.6 First "stand-alone" version.
11 * Removed sound configuration.
12 * Added "module" support.
13 *
14 * 9 November 1999 -- Make kernel-parameter implementation work with 2.3.x
15 * Removed init_module & cleanup_module in favor of
16 * module_init & module_exit.
17 * Torben Mathiasen <tmm@image.dk>
18 *
19 * 19 June 2004 -- check_region() converted to request_region()
20 * and return statement cleanups.
21 * Jesper Juhl <juhl-lkml@dif.dk>
22 *
23 * Detect cdrom interface on ISP16 sound card.
24 * Configure cdrom interface.
25 *
26 * Algorithm for the card with OPTi 82C928 taken
27 * from the CDSETUP.SYS driver for MSDOS,
28 * by OPTi Computers, version 2.03.
29 * Algorithm for the card with OPTi 82C929 as communicated
30 * to me by Vadim Model and Leo Spiekman.
31 *
32 * This program is free software; you can redistribute it and/or modify
33 * it under the terms of the GNU General Public License as published by
34 * the Free Software Foundation; either version 2 of the License, or
35 * (at your option) any later version.
36 *
37 * This program is distributed in the hope that it will be useful,
38 * but WITHOUT ANY WARRANTY; without even the implied warranty of
39 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
40 * GNU General Public License for more details.
41 *
42 * You should have received a copy of the GNU General Public License
43 * along with this program; if not, write to the Free Software
44 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
45 *
46 */
47
48#define ISP16_VERSION_MAJOR 0
49#define ISP16_VERSION_MINOR 6
50
51#include <linux/module.h>
52
53#include <linux/fs.h>
54#include <linux/kernel.h>
55#include <linux/string.h>
56#include <linux/ioport.h>
57#include <linux/init.h>
58#include <asm/io.h>
59#include "isp16.h"
60
61static short isp16_detect(void);
62static short isp16_c928__detect(void);
63static short isp16_c929__detect(void);
64static short isp16_cdi_config(int base, u_char drive_type, int irq,
65 int dma);
66static short isp16_type; /* dependent on type of interface card */
67static u_char isp16_ctrl;
68static u_short isp16_enable_port;
69
70static int isp16_cdrom_base = ISP16_CDROM_IO_BASE;
71static int isp16_cdrom_irq = ISP16_CDROM_IRQ;
72static int isp16_cdrom_dma = ISP16_CDROM_DMA;
73static char *isp16_cdrom_type = ISP16_CDROM_TYPE;
74
75module_param(isp16_cdrom_base, int, 0);
76module_param(isp16_cdrom_irq, int, 0);
77module_param(isp16_cdrom_dma, int, 0);
78module_param(isp16_cdrom_type, charp, 0);
79
80#define ISP16_IN(p) (outb(isp16_ctrl,ISP16_CTRL_PORT), inb(p))
81#define ISP16_OUT(p,b) (outb(isp16_ctrl,ISP16_CTRL_PORT), outb(b,p))
82
83#ifndef MODULE
84
85static int
86__init isp16_setup(char *str)
87{
88 int ints[4];
89
90 (void) get_options(str, ARRAY_SIZE(ints), ints);
91 if (ints[0] > 0)
92 isp16_cdrom_base = ints[1];
93 if (ints[0] > 1)
94 isp16_cdrom_irq = ints[2];
95 if (ints[0] > 2)
96 isp16_cdrom_dma = ints[3];
97 if (str)
98 isp16_cdrom_type = str;
99
100 return 1;
101}
102
103__setup("isp16=", isp16_setup);
104
105#endif /* MODULE */
106
107/*
108 * ISP16 initialisation.
109 *
110 */
111static int __init isp16_init(void)
112{
113 u_char expected_drive;
114
115 printk(KERN_INFO
116 "ISP16: configuration cdrom interface, version %d.%d.\n",
117 ISP16_VERSION_MAJOR, ISP16_VERSION_MINOR);
118
119 if (!strcmp(isp16_cdrom_type, "noisp16")) {
120 printk("ISP16: no cdrom interface configured.\n");
121 return 0;
122 }
123
124 if (!request_region(ISP16_IO_BASE, ISP16_IO_SIZE, "isp16")) {
125 printk("ISP16: i/o ports already in use.\n");
126 goto out;
127 }
128
129 if ((isp16_type = isp16_detect()) < 0) {
130 printk("ISP16: no cdrom interface found.\n");
131 goto cleanup_out;
132 }
133
134 printk(KERN_INFO
135 "ISP16: cdrom interface (with OPTi 82C92%d chip) detected.\n",
136 (isp16_type == 2) ? 9 : 8);
137
138 if (!strcmp(isp16_cdrom_type, "Sanyo"))
139 expected_drive =
140 (isp16_type ? ISP16_SANYO1 : ISP16_SANYO0);
141 else if (!strcmp(isp16_cdrom_type, "Sony"))
142 expected_drive = ISP16_SONY;
143 else if (!strcmp(isp16_cdrom_type, "Panasonic"))
144 expected_drive =
145 (isp16_type ? ISP16_PANASONIC1 : ISP16_PANASONIC0);
146 else if (!strcmp(isp16_cdrom_type, "Mitsumi"))
147 expected_drive = ISP16_MITSUMI;
148 else {
149 printk("ISP16: %s not supported by cdrom interface.\n",
150 isp16_cdrom_type);
151 goto cleanup_out;
152 }
153
154 if (isp16_cdi_config(isp16_cdrom_base, expected_drive,
155 isp16_cdrom_irq, isp16_cdrom_dma) < 0) {
156 printk
157 ("ISP16: cdrom interface has not been properly configured.\n");
158 goto cleanup_out;
159 }
160 printk(KERN_INFO
161 "ISP16: cdrom interface set up with io base 0x%03X, irq %d, dma %d,"
162 " type %s.\n", isp16_cdrom_base, isp16_cdrom_irq,
163 isp16_cdrom_dma, isp16_cdrom_type);
164 return 0;
165
166cleanup_out:
167 release_region(ISP16_IO_BASE, ISP16_IO_SIZE);
168out:
169 return -EIO;
170}
171
172static short __init isp16_detect(void)
173{
174
175 if (isp16_c929__detect() >= 0)
176 return 2;
177 else
178 return (isp16_c928__detect());
179}
180
181static short __init isp16_c928__detect(void)
182{
183 u_char ctrl;
184 u_char enable_cdrom;
185 u_char io;
186 short i = -1;
187
188 isp16_ctrl = ISP16_C928__CTRL;
189 isp16_enable_port = ISP16_C928__ENABLE_PORT;
190
191 /* read' and write' are a special read and write, respectively */
192
193 /* read' ISP16_CTRL_PORT, clear last two bits and write' back the result */
194 ctrl = ISP16_IN(ISP16_CTRL_PORT) & 0xFC;
195 ISP16_OUT(ISP16_CTRL_PORT, ctrl);
196
197 /* read' 3,4 and 5-bit from the cdrom enable port */
198 enable_cdrom = ISP16_IN(ISP16_C928__ENABLE_PORT) & 0x38;
199
200 if (!(enable_cdrom & 0x20)) { /* 5-bit not set */
201 /* read' last 2 bits of ISP16_IO_SET_PORT */
202 io = ISP16_IN(ISP16_IO_SET_PORT) & 0x03;
203 if (((io & 0x01) << 1) == (io & 0x02)) { /* bits are the same */
204 if (io == 0) { /* ...the same and 0 */
205 i = 0;
206 enable_cdrom |= 0x20;
207 } else { /* ...the same and 1 *//* my card, first time 'round */
208 i = 1;
209 enable_cdrom |= 0x28;
210 }
211 ISP16_OUT(ISP16_C928__ENABLE_PORT, enable_cdrom);
212 } else { /* bits are not the same */
213 ISP16_OUT(ISP16_CTRL_PORT, ctrl);
214 return i; /* -> not detected: possibly incorrect conclusion */
215 }
216 } else if (enable_cdrom == 0x20)
217 i = 0;
218 else if (enable_cdrom == 0x28) /* my card, already initialised */
219 i = 1;
220
221 ISP16_OUT(ISP16_CTRL_PORT, ctrl);
222
223 return i;
224}
225
226static short __init isp16_c929__detect(void)
227{
228 u_char ctrl;
229 u_char tmp;
230
231 isp16_ctrl = ISP16_C929__CTRL;
232 isp16_enable_port = ISP16_C929__ENABLE_PORT;
233
234 /* read' and write' are a special read and write, respectively */
235
236 /* read' ISP16_CTRL_PORT and save */
237 ctrl = ISP16_IN(ISP16_CTRL_PORT);
238
239 /* write' zero to the ctrl port and get response */
240 ISP16_OUT(ISP16_CTRL_PORT, 0);
241 tmp = ISP16_IN(ISP16_CTRL_PORT);
242
243 if (tmp != 2) /* isp16 with 82C929 not detected */
244 return -1;
245
246 /* restore ctrl port value */
247 ISP16_OUT(ISP16_CTRL_PORT, ctrl);
248
249 return 2;
250}
251
252static short __init
253isp16_cdi_config(int base, u_char drive_type, int irq, int dma)
254{
255 u_char base_code;
256 u_char irq_code;
257 u_char dma_code;
258 u_char i;
259
260 if ((drive_type == ISP16_MITSUMI) && (dma != 0))
261 printk("ISP16: Mitsumi cdrom drive has no dma support.\n");
262
263 switch (base) {
264 case 0x340:
265 base_code = ISP16_BASE_340;
266 break;
267 case 0x330:
268 base_code = ISP16_BASE_330;
269 break;
270 case 0x360:
271 base_code = ISP16_BASE_360;
272 break;
273 case 0x320:
274 base_code = ISP16_BASE_320;
275 break;
276 default:
277 printk
278 ("ISP16: base address 0x%03X not supported by cdrom interface.\n",
279 base);
280 return -1;
281 }
282 switch (irq) {
283 case 0:
284 irq_code = ISP16_IRQ_X;
285 break; /* disable irq */
286 case 5:
287 irq_code = ISP16_IRQ_5;
288 printk("ISP16: irq 5 shouldn't be used by cdrom interface,"
289 " due to possible conflicts with the sound card.\n");
290 break;
291 case 7:
292 irq_code = ISP16_IRQ_7;
293 printk("ISP16: irq 7 shouldn't be used by cdrom interface,"
294 " due to possible conflicts with the sound card.\n");
295 break;
296 case 3:
297 irq_code = ISP16_IRQ_3;
298 break;
299 case 9:
300 irq_code = ISP16_IRQ_9;
301 break;
302 case 10:
303 irq_code = ISP16_IRQ_10;
304 break;
305 case 11:
306 irq_code = ISP16_IRQ_11;
307 break;
308 default:
309 printk("ISP16: irq %d not supported by cdrom interface.\n",
310 irq);
311 return -1;
312 }
313 switch (dma) {
314 case 0:
315 dma_code = ISP16_DMA_X;
316 break; /* disable dma */
317 case 1:
318 printk("ISP16: dma 1 cannot be used by cdrom interface,"
319 " due to conflict with the sound card.\n");
320 return -1;
321 break;
322 case 3:
323 dma_code = ISP16_DMA_3;
324 break;
325 case 5:
326 dma_code = ISP16_DMA_5;
327 break;
328 case 6:
329 dma_code = ISP16_DMA_6;
330 break;
331 case 7:
332 dma_code = ISP16_DMA_7;
333 break;
334 default:
335 printk("ISP16: dma %d not supported by cdrom interface.\n",
336 dma);
337 return -1;
338 }
339
340 if (drive_type != ISP16_SONY && drive_type != ISP16_PANASONIC0 &&
341 drive_type != ISP16_PANASONIC1 && drive_type != ISP16_SANYO0 &&
342 drive_type != ISP16_SANYO1 && drive_type != ISP16_MITSUMI &&
343 drive_type != ISP16_DRIVE_X) {
344 printk
345 ("ISP16: drive type (code 0x%02X) not supported by cdrom"
346 " interface.\n", drive_type);
347 return -1;
348 }
349
350 /* set type of interface */
351 i = ISP16_IN(ISP16_DRIVE_SET_PORT) & ISP16_DRIVE_SET_MASK; /* clear some bits */
352 ISP16_OUT(ISP16_DRIVE_SET_PORT, i | drive_type);
353
354 /* enable cdrom on interface with 82C929 chip */
355 if (isp16_type > 1)
356 ISP16_OUT(isp16_enable_port, ISP16_ENABLE_CDROM);
357
358 /* set base address, irq and dma */
359 i = ISP16_IN(ISP16_IO_SET_PORT) & ISP16_IO_SET_MASK; /* keep some bits */
360 ISP16_OUT(ISP16_IO_SET_PORT, i | base_code | irq_code | dma_code);
361
362 return 0;
363}
364
365static void __exit isp16_exit(void)
366{
367 release_region(ISP16_IO_BASE, ISP16_IO_SIZE);
368 printk(KERN_INFO "ISP16: module released.\n");
369}
370
371module_init(isp16_init);
372module_exit(isp16_exit);
373
374MODULE_LICENSE("GPL");
diff --git a/drivers/cdrom/isp16.h b/drivers/cdrom/isp16.h
new file mode 100644
index 000000000000..5bd22c8f7a96
--- /dev/null
+++ b/drivers/cdrom/isp16.h
@@ -0,0 +1,72 @@
1/* -- isp16.h
2 *
3 * Header for detection and initialisation of cdrom interface (only) on
4 * ISP16 (MAD16, Mozart) sound card.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 */
21
22/* These are the default values */
23#define ISP16_CDROM_TYPE "Sanyo"
24#define ISP16_CDROM_IO_BASE 0x340
25#define ISP16_CDROM_IRQ 0
26#define ISP16_CDROM_DMA 0
27
28/* Some (Media)Magic */
29/* define types of drive the interface on an ISP16 card may be looking at */
30#define ISP16_DRIVE_X 0x00
31#define ISP16_SONY 0x02
32#define ISP16_PANASONIC0 0x02
33#define ISP16_SANYO0 0x02
34#define ISP16_MITSUMI 0x04
35#define ISP16_PANASONIC1 0x06
36#define ISP16_SANYO1 0x06
37#define ISP16_DRIVE_NOT_USED 0x08 /* not used */
38#define ISP16_DRIVE_SET_MASK 0xF1 /* don't change 0-bit or 4-7-bits*/
39/* ...for port */
40#define ISP16_DRIVE_SET_PORT 0xF8D
41/* set io parameters */
42#define ISP16_BASE_340 0x00
43#define ISP16_BASE_330 0x40
44#define ISP16_BASE_360 0x80
45#define ISP16_BASE_320 0xC0
46#define ISP16_IRQ_X 0x00
47#define ISP16_IRQ_5 0x04 /* shouldn't be used to avoid sound card conflicts */
48#define ISP16_IRQ_7 0x08 /* shouldn't be used to avoid sound card conflicts */
49#define ISP16_IRQ_3 0x0C
50#define ISP16_IRQ_9 0x10
51#define ISP16_IRQ_10 0x14
52#define ISP16_IRQ_11 0x18
53#define ISP16_DMA_X 0x03
54#define ISP16_DMA_3 0x00
55#define ISP16_DMA_5 0x00
56#define ISP16_DMA_6 0x01
57#define ISP16_DMA_7 0x02
58#define ISP16_IO_SET_MASK 0x20 /* don't change 5-bit */
59/* ...for port */
60#define ISP16_IO_SET_PORT 0xF8E
61/* enable the card */
62#define ISP16_C928__ENABLE_PORT 0xF90 /* ISP16 with OPTi 82C928 chip */
63#define ISP16_C929__ENABLE_PORT 0xF91 /* ISP16 with OPTi 82C929 chip */
64#define ISP16_ENABLE_CDROM 0x80 /* seven bit */
65
66/* the magic stuff */
67#define ISP16_CTRL_PORT 0xF8F
68#define ISP16_C928__CTRL 0xE2 /* ISP16 with OPTi 82C928 chip */
69#define ISP16_C929__CTRL 0xE3 /* ISP16 with OPTi 82C929 chip */
70
71#define ISP16_IO_BASE 0xF8D
72#define ISP16_IO_SIZE 5 /* ports used from 0xF8D up to 0xF91 */
diff --git a/drivers/cdrom/mcdx.c b/drivers/cdrom/mcdx.c
new file mode 100644
index 000000000000..ccde7ab491d4
--- /dev/null
+++ b/drivers/cdrom/mcdx.c
@@ -0,0 +1,1952 @@
1/*
2 * The Mitsumi CDROM interface
3 * Copyright (C) 1995 1996 Heiko Schlittermann <heiko@lotte.sax.de>
4 * VERSION: 2.14(hs)
5 *
6 * ... anyway, I'm back again, thanks to Marcin, he adopted
7 * large portions of my code (at least the parts containing
8 * my main thoughts ...)
9 *
10 ****************** H E L P *********************************
11 * If you ever plan to update your CD ROM drive and perhaps
12 * want to sell or simply give away your Mitsumi FX-001[DS]
13 * -- Please --
14 * mail me (heiko@lotte.sax.de). When my last drive goes
15 * ballistic no more driver support will be available from me!
16 *************************************************************
17 *
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation; either version 2, or (at your option)
21 * any later version.
22 *
23 * This program is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
27 *
28 * You should have received a copy of the GNU General Public License
29 * along with this program; see the file COPYING. If not, write to
30 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
31 *
32 * Thanks to
33 * The Linux Community at all and ...
34 * Martin Harriss (he wrote the first Mitsumi Driver)
35 * Eberhard Moenkeberg (he gave me much support and the initial kick)
36 * Bernd Huebner, Ruediger Helsch (Unifix-Software GmbH, they
37 * improved the original driver)
38 * Jon Tombs, Bjorn Ekwall (module support)
39 * Daniel v. Mosnenck (he sent me the Technical and Programming Reference)
40 * Gerd Knorr (he lent me his PhotoCD)
41 * Nils Faerber and Roger E. Wolff (extensively tested the LU portion)
42 * Andreas Kies (testing the mysterious hang-ups)
43 * Heiko Eissfeldt (VERIFY_READ/WRITE)
44 * Marcin Dalecki (improved performance, shortened code)
45 * ... somebody forgotten?
46 *
47 * 9 November 1999 -- Make kernel-parameter implementation work with 2.3.x
48 * Removed init_module & cleanup_module in favor of
49 * module_init & module_exit.
50 * Torben Mathiasen <tmm@image.dk>
51 */
52
53
54#if RCS
55static const char *mcdx_c_version
56 = "$Id: mcdx.c,v 1.21 1997/01/26 07:12:59 davem Exp $";
57#endif
58
59#include <linux/module.h>
60
61#include <linux/errno.h>
62#include <linux/interrupt.h>
63#include <linux/fs.h>
64#include <linux/kernel.h>
65#include <linux/cdrom.h>
66#include <linux/ioport.h>
67#include <linux/mm.h>
68#include <linux/slab.h>
69#include <linux/init.h>
70#include <asm/io.h>
71#include <asm/current.h>
72#include <asm/uaccess.h>
73
74#include <linux/major.h>
75#define MAJOR_NR MITSUMI_X_CDROM_MAJOR
76#include <linux/blkdev.h>
77#include <linux/devfs_fs_kernel.h>
78
79#include "mcdx.h"
80
81#ifndef HZ
82#error HZ not defined
83#endif
84
85#define xwarn(fmt, args...) printk(KERN_WARNING MCDX " " fmt, ## args)
86
87#if !MCDX_QUIET
88#define xinfo(fmt, args...) printk(KERN_INFO MCDX " " fmt, ## args)
89#else
90#define xinfo(fmt, args...) { ; }
91#endif
92
93#if MCDX_DEBUG
94#define xtrace(lvl, fmt, args...) \
95 { if (lvl > 0) \
96 { printk(KERN_DEBUG MCDX ":: " fmt, ## args); } }
97#define xdebug(fmt, args...) printk(KERN_DEBUG MCDX ":: " fmt, ## args)
98#else
99#define xtrace(lvl, fmt, args...) { ; }
100#define xdebug(fmt, args...) { ; }
101#endif
102
103/* CONSTANTS *******************************************************/
104
105/* Following are the number of sectors we _request_ from the drive
106 every time an access outside the already requested range is done.
107 The _direct_ size is the number of sectors we're allowed to skip
108 directly (performing a read instead of requesting the new sector
109 needed */
110const int REQUEST_SIZE = 800; /* should be less then 255 * 4 */
111const int DIRECT_SIZE = 400; /* should be less then REQUEST_SIZE */
112
113enum drivemodes { TOC, DATA, RAW, COOKED };
114enum datamodes { MODE0, MODE1, MODE2 };
115enum resetmodes { SOFT, HARD };
116
117const int SINGLE = 0x01; /* single speed drive (FX001S, LU) */
118const int DOUBLE = 0x02; /* double speed drive (FX001D, ..? */
119const int DOOR = 0x04; /* door locking capability */
120const int MULTI = 0x08; /* multi session capability */
121
122const unsigned char READ1X = 0xc0;
123const unsigned char READ2X = 0xc1;
124
125
126/* DECLARATIONS ****************************************************/
127struct s_subqcode {
128 unsigned char control;
129 unsigned char tno;
130 unsigned char index;
131 struct cdrom_msf0 tt;
132 struct cdrom_msf0 dt;
133};
134
135struct s_diskinfo {
136 unsigned int n_first;
137 unsigned int n_last;
138 struct cdrom_msf0 msf_leadout;
139 struct cdrom_msf0 msf_first;
140};
141
142struct s_multi {
143 unsigned char multi;
144 struct cdrom_msf0 msf_last;
145};
146
147struct s_version {
148 unsigned char code;
149 unsigned char ver;
150};
151
152/* Per drive/controller stuff **************************************/
153
154struct s_drive_stuff {
155 /* waitqueues */
156 wait_queue_head_t busyq;
157 wait_queue_head_t lockq;
158 wait_queue_head_t sleepq;
159
160 /* flags */
161 volatile int introk; /* status of last irq operation */
162 volatile int busy; /* drive performs an operation */
163 volatile int lock; /* exclusive usage */
164
165 /* cd infos */
166 struct s_diskinfo di;
167 struct s_multi multi;
168 struct s_subqcode *toc; /* first entry of the toc array */
169 struct s_subqcode start;
170 struct s_subqcode stop;
171 int xa; /* 1 if xa disk */
172 int audio; /* 1 if audio disk */
173 int audiostatus;
174
175 /* `buffer' control */
176 volatile int valid; /* pending, ..., values are valid */
177 volatile int pending; /* next sector to be read */
178 volatile int low_border; /* first sector not to be skipped direct */
179 volatile int high_border; /* first sector `out of area' */
180#ifdef AK2
181 volatile int int_err;
182#endif /* AK2 */
183
184 /* adds and odds */
185 unsigned wreg_data; /* w data */
186 unsigned wreg_reset; /* w hardware reset */
187 unsigned wreg_hcon; /* w hardware conf */
188 unsigned wreg_chn; /* w channel */
189 unsigned rreg_data; /* r data */
190 unsigned rreg_status; /* r status */
191
192 int irq; /* irq used by this drive */
193 int present; /* drive present and its capabilities */
194 unsigned char readcmd; /* read cmd depends on single/double speed */
195 unsigned char playcmd; /* play should always be single speed */
196 unsigned int xxx; /* set if changed, reset while open */
197 unsigned int yyy; /* set if changed, reset by media_changed */
198 int users; /* keeps track of open/close */
199 int lastsector; /* last block accessible */
200 int status; /* last operation's error / status */
201 int readerrs; /* # of blocks read w/o error */
202 struct cdrom_device_info info;
203 struct gendisk *disk;
204};
205
206
207/* Prototypes ******************************************************/
208
209/* The following prototypes are already declared elsewhere. They are
210 repeated here to show what's going on. And to sense, if they're
211 changed elsewhere. */
212
213/* declared in blk.h */
214int mcdx_init(void);
215void do_mcdx_request(request_queue_t * q);
216
217static int mcdx_block_open(struct inode *inode, struct file *file)
218{
219 struct s_drive_stuff *p = inode->i_bdev->bd_disk->private_data;
220 return cdrom_open(&p->info, inode, file);
221}
222
223static int mcdx_block_release(struct inode *inode, struct file *file)
224{
225 struct s_drive_stuff *p = inode->i_bdev->bd_disk->private_data;
226 return cdrom_release(&p->info, file);
227}
228
229static int mcdx_block_ioctl(struct inode *inode, struct file *file,
230 unsigned cmd, unsigned long arg)
231{
232 struct s_drive_stuff *p = inode->i_bdev->bd_disk->private_data;
233 return cdrom_ioctl(file, &p->info, inode, cmd, arg);
234}
235
236static int mcdx_block_media_changed(struct gendisk *disk)
237{
238 struct s_drive_stuff *p = disk->private_data;
239 return cdrom_media_changed(&p->info);
240}
241
242static struct block_device_operations mcdx_bdops =
243{
244 .owner = THIS_MODULE,
245 .open = mcdx_block_open,
246 .release = mcdx_block_release,
247 .ioctl = mcdx_block_ioctl,
248 .media_changed = mcdx_block_media_changed,
249};
250
251
252/* Indirect exported functions. These functions are exported by their
253 addresses, such as mcdx_open and mcdx_close in the
254 structure mcdx_dops. */
255
256/* exported by file_ops */
257static int mcdx_open(struct cdrom_device_info *cdi, int purpose);
258static void mcdx_close(struct cdrom_device_info *cdi);
259static int mcdx_media_changed(struct cdrom_device_info *cdi, int disc_nr);
260static int mcdx_tray_move(struct cdrom_device_info *cdi, int position);
261static int mcdx_lockdoor(struct cdrom_device_info *cdi, int lock);
262static int mcdx_audio_ioctl(struct cdrom_device_info *cdi,
263 unsigned int cmd, void *arg);
264
265/* misc internal support functions */
266static void log2msf(unsigned int, struct cdrom_msf0 *);
267static unsigned int msf2log(const struct cdrom_msf0 *);
268static unsigned int uint2bcd(unsigned int);
269static unsigned int bcd2uint(unsigned char);
270static unsigned port(int *);
271static int irq(int *);
272static void mcdx_delay(struct s_drive_stuff *, long jifs);
273static int mcdx_transfer(struct s_drive_stuff *, char *buf, int sector,
274 int nr_sectors);
275static int mcdx_xfer(struct s_drive_stuff *, char *buf, int sector,
276 int nr_sectors);
277
278static int mcdx_config(struct s_drive_stuff *, int);
279static int mcdx_requestversion(struct s_drive_stuff *, struct s_version *,
280 int);
281static int mcdx_stop(struct s_drive_stuff *, int);
282static int mcdx_hold(struct s_drive_stuff *, int);
283static int mcdx_reset(struct s_drive_stuff *, enum resetmodes, int);
284static int mcdx_setdrivemode(struct s_drive_stuff *, enum drivemodes, int);
285static int mcdx_setdatamode(struct s_drive_stuff *, enum datamodes, int);
286static int mcdx_requestsubqcode(struct s_drive_stuff *,
287 struct s_subqcode *, int);
288static int mcdx_requestmultidiskinfo(struct s_drive_stuff *,
289 struct s_multi *, int);
290static int mcdx_requesttocdata(struct s_drive_stuff *, struct s_diskinfo *,
291 int);
292static int mcdx_getstatus(struct s_drive_stuff *, int);
293static int mcdx_getval(struct s_drive_stuff *, int to, int delay, char *);
294static int mcdx_talk(struct s_drive_stuff *,
295 const unsigned char *cmd, size_t,
296 void *buffer, size_t size, unsigned int timeout, int);
297static int mcdx_readtoc(struct s_drive_stuff *);
298static int mcdx_playtrk(struct s_drive_stuff *, const struct cdrom_ti *);
299static int mcdx_playmsf(struct s_drive_stuff *, const struct cdrom_msf *);
300static int mcdx_setattentuator(struct s_drive_stuff *,
301 struct cdrom_volctrl *, int);
302
303/* static variables ************************************************/
304
305static int mcdx_drive_map[][2] = MCDX_DRIVEMAP;
306static struct s_drive_stuff *mcdx_stuffp[MCDX_NDRIVES];
307static DEFINE_SPINLOCK(mcdx_lock);
308static struct request_queue *mcdx_queue;
309
310/* You can only set the first two pairs, from old MODULE_PARM code. */
311static int mcdx_set(const char *val, struct kernel_param *kp)
312{
313 get_options((char *)val, 4, (int *)mcdx_drive_map);
314 return 0;
315}
316module_param_call(mcdx, mcdx_set, NULL, NULL, 0);
317
318static struct cdrom_device_ops mcdx_dops = {
319 .open = mcdx_open,
320 .release = mcdx_close,
321 .media_changed = mcdx_media_changed,
322 .tray_move = mcdx_tray_move,
323 .lock_door = mcdx_lockdoor,
324 .audio_ioctl = mcdx_audio_ioctl,
325 .capability = CDC_OPEN_TRAY | CDC_LOCK | CDC_MEDIA_CHANGED |
326 CDC_PLAY_AUDIO | CDC_DRIVE_STATUS,
327};
328
329/* KERNEL INTERFACE FUNCTIONS **************************************/
330
331
332static int mcdx_audio_ioctl(struct cdrom_device_info *cdi,
333 unsigned int cmd, void *arg)
334{
335 struct s_drive_stuff *stuffp = cdi->handle;
336
337 if (!stuffp->present)
338 return -ENXIO;
339
340 if (stuffp->xxx) {
341 if (-1 == mcdx_requesttocdata(stuffp, &stuffp->di, 1)) {
342 stuffp->lastsector = -1;
343 } else {
344 stuffp->lastsector = (CD_FRAMESIZE / 512)
345 * msf2log(&stuffp->di.msf_leadout) - 1;
346 }
347
348 if (stuffp->toc) {
349 kfree(stuffp->toc);
350 stuffp->toc = NULL;
351 if (-1 == mcdx_readtoc(stuffp))
352 return -1;
353 }
354
355 stuffp->xxx = 0;
356 }
357
358 switch (cmd) {
359 case CDROMSTART:{
360 xtrace(IOCTL, "ioctl() START\n");
361 /* Spin up the drive. Don't think we can do this.
362 * For now, ignore it.
363 */
364 return 0;
365 }
366
367 case CDROMSTOP:{
368 xtrace(IOCTL, "ioctl() STOP\n");
369 stuffp->audiostatus = CDROM_AUDIO_INVALID;
370 if (-1 == mcdx_stop(stuffp, 1))
371 return -EIO;
372 return 0;
373 }
374
375 case CDROMPLAYTRKIND:{
376 struct cdrom_ti *ti = (struct cdrom_ti *) arg;
377
378 xtrace(IOCTL, "ioctl() PLAYTRKIND\n");
379 if ((ti->cdti_trk0 < stuffp->di.n_first)
380 || (ti->cdti_trk0 > stuffp->di.n_last)
381 || (ti->cdti_trk1 < stuffp->di.n_first))
382 return -EINVAL;
383 if (ti->cdti_trk1 > stuffp->di.n_last)
384 ti->cdti_trk1 = stuffp->di.n_last;
385 xtrace(PLAYTRK, "ioctl() track %d to %d\n",
386 ti->cdti_trk0, ti->cdti_trk1);
387 return mcdx_playtrk(stuffp, ti);
388 }
389
390 case CDROMPLAYMSF:{
391 struct cdrom_msf *msf = (struct cdrom_msf *) arg;
392
393 xtrace(IOCTL, "ioctl() PLAYMSF\n");
394
395 if ((stuffp->audiostatus == CDROM_AUDIO_PLAY)
396 && (-1 == mcdx_hold(stuffp, 1)))
397 return -EIO;
398
399 msf->cdmsf_min0 = uint2bcd(msf->cdmsf_min0);
400 msf->cdmsf_sec0 = uint2bcd(msf->cdmsf_sec0);
401 msf->cdmsf_frame0 = uint2bcd(msf->cdmsf_frame0);
402
403 msf->cdmsf_min1 = uint2bcd(msf->cdmsf_min1);
404 msf->cdmsf_sec1 = uint2bcd(msf->cdmsf_sec1);
405 msf->cdmsf_frame1 = uint2bcd(msf->cdmsf_frame1);
406
407 stuffp->stop.dt.minute = msf->cdmsf_min1;
408 stuffp->stop.dt.second = msf->cdmsf_sec1;
409 stuffp->stop.dt.frame = msf->cdmsf_frame1;
410
411 return mcdx_playmsf(stuffp, msf);
412 }
413
414 case CDROMRESUME:{
415 xtrace(IOCTL, "ioctl() RESUME\n");
416 return mcdx_playtrk(stuffp, NULL);
417 }
418
419 case CDROMREADTOCENTRY:{
420 struct cdrom_tocentry *entry =
421 (struct cdrom_tocentry *) arg;
422 struct s_subqcode *tp = NULL;
423 xtrace(IOCTL, "ioctl() READTOCENTRY\n");
424
425 if (-1 == mcdx_readtoc(stuffp))
426 return -1;
427 if (entry->cdte_track == CDROM_LEADOUT)
428 tp = &stuffp->toc[stuffp->di.n_last -
429 stuffp->di.n_first + 1];
430 else if (entry->cdte_track > stuffp->di.n_last
431 || entry->cdte_track < stuffp->di.n_first)
432 return -EINVAL;
433 else
434 tp = &stuffp->toc[entry->cdte_track -
435 stuffp->di.n_first];
436
437 if (NULL == tp)
438 return -EIO;
439 entry->cdte_adr = tp->control;
440 entry->cdte_ctrl = tp->control >> 4;
441 /* Always return stuff in MSF, and let the Uniform cdrom driver
442 worry about what the user actually wants */
443 entry->cdte_addr.msf.minute =
444 bcd2uint(tp->dt.minute);
445 entry->cdte_addr.msf.second =
446 bcd2uint(tp->dt.second);
447 entry->cdte_addr.msf.frame =
448 bcd2uint(tp->dt.frame);
449 return 0;
450 }
451
452 case CDROMSUBCHNL:{
453 struct cdrom_subchnl *sub =
454 (struct cdrom_subchnl *) arg;
455 struct s_subqcode q;
456
457 xtrace(IOCTL, "ioctl() SUBCHNL\n");
458
459 if (-1 == mcdx_requestsubqcode(stuffp, &q, 2))
460 return -EIO;
461
462 xtrace(SUBCHNL, "audiostatus: %x\n",
463 stuffp->audiostatus);
464 sub->cdsc_audiostatus = stuffp->audiostatus;
465 sub->cdsc_adr = q.control;
466 sub->cdsc_ctrl = q.control >> 4;
467 sub->cdsc_trk = bcd2uint(q.tno);
468 sub->cdsc_ind = bcd2uint(q.index);
469
470 xtrace(SUBCHNL, "trk %d, ind %d\n",
471 sub->cdsc_trk, sub->cdsc_ind);
472 /* Always return stuff in MSF, and let the Uniform cdrom driver
473 worry about what the user actually wants */
474 sub->cdsc_absaddr.msf.minute =
475 bcd2uint(q.dt.minute);
476 sub->cdsc_absaddr.msf.second =
477 bcd2uint(q.dt.second);
478 sub->cdsc_absaddr.msf.frame = bcd2uint(q.dt.frame);
479 sub->cdsc_reladdr.msf.minute =
480 bcd2uint(q.tt.minute);
481 sub->cdsc_reladdr.msf.second =
482 bcd2uint(q.tt.second);
483 sub->cdsc_reladdr.msf.frame = bcd2uint(q.tt.frame);
484 xtrace(SUBCHNL,
485 "msf: abs %02d:%02d:%02d, rel %02d:%02d:%02d\n",
486 sub->cdsc_absaddr.msf.minute,
487 sub->cdsc_absaddr.msf.second,
488 sub->cdsc_absaddr.msf.frame,
489 sub->cdsc_reladdr.msf.minute,
490 sub->cdsc_reladdr.msf.second,
491 sub->cdsc_reladdr.msf.frame);
492
493 return 0;
494 }
495
496 case CDROMREADTOCHDR:{
497 struct cdrom_tochdr *toc =
498 (struct cdrom_tochdr *) arg;
499
500 xtrace(IOCTL, "ioctl() READTOCHDR\n");
501 toc->cdth_trk0 = stuffp->di.n_first;
502 toc->cdth_trk1 = stuffp->di.n_last;
503 xtrace(TOCHDR,
504 "ioctl() track0 = %d, track1 = %d\n",
505 stuffp->di.n_first, stuffp->di.n_last);
506 return 0;
507 }
508
509 case CDROMPAUSE:{
510 xtrace(IOCTL, "ioctl() PAUSE\n");
511 if (stuffp->audiostatus != CDROM_AUDIO_PLAY)
512 return -EINVAL;
513 if (-1 == mcdx_stop(stuffp, 1))
514 return -EIO;
515 stuffp->audiostatus = CDROM_AUDIO_PAUSED;
516 if (-1 ==
517 mcdx_requestsubqcode(stuffp, &stuffp->start,
518 1))
519 return -EIO;
520 return 0;
521 }
522
523 case CDROMMULTISESSION:{
524 struct cdrom_multisession *ms =
525 (struct cdrom_multisession *) arg;
526 xtrace(IOCTL, "ioctl() MULTISESSION\n");
527 /* Always return stuff in LBA, and let the Uniform cdrom driver
528 worry about what the user actually wants */
529 ms->addr.lba = msf2log(&stuffp->multi.msf_last);
530 ms->xa_flag = !!stuffp->multi.multi;
531 xtrace(MS,
532 "ioctl() (%d, 0x%08x [%02x:%02x.%02x])\n",
533 ms->xa_flag, ms->addr.lba,
534 stuffp->multi.msf_last.minute,
535 stuffp->multi.msf_last.second,
536 stuffp->multi.msf_last.frame);
537
538 return 0;
539 }
540
541 case CDROMEJECT:{
542 xtrace(IOCTL, "ioctl() EJECT\n");
543 if (stuffp->users > 1)
544 return -EBUSY;
545 return (mcdx_tray_move(cdi, 1));
546 }
547
548 case CDROMCLOSETRAY:{
549 xtrace(IOCTL, "ioctl() CDROMCLOSETRAY\n");
550 return (mcdx_tray_move(cdi, 0));
551 }
552
553 case CDROMVOLCTRL:{
554 struct cdrom_volctrl *volctrl =
555 (struct cdrom_volctrl *) arg;
556 xtrace(IOCTL, "ioctl() VOLCTRL\n");
557
558#if 0 /* not tested! */
559 /* adjust for the weirdness of workman (md) */
560 /* can't test it (hs) */
561 volctrl.channel2 = volctrl.channel1;
562 volctrl.channel1 = volctrl.channel3 = 0x00;
563#endif
564 return mcdx_setattentuator(stuffp, volctrl, 2);
565 }
566
567 default:
568 return -EINVAL;
569 }
570}
571
572void do_mcdx_request(request_queue_t * q)
573{
574 struct s_drive_stuff *stuffp;
575 struct request *req;
576
577 again:
578
579 req = elv_next_request(q);
580 if (!req)
581 return;
582
583 stuffp = req->rq_disk->private_data;
584
585 if (!stuffp->present) {
586 xwarn("do_request(): bad device: %s\n",req->rq_disk->disk_name);
587 xtrace(REQUEST, "end_request(0): bad device\n");
588 end_request(req, 0);
589 return;
590 }
591
592 if (stuffp->audio) {
593 xwarn("do_request() attempt to read from audio cd\n");
594 xtrace(REQUEST, "end_request(0): read from audio\n");
595 end_request(req, 0);
596 return;
597 }
598
599 xtrace(REQUEST, "do_request() (%lu + %lu)\n",
600 req->sector, req->nr_sectors);
601
602 if (req->cmd != READ) {
603 xwarn("do_request(): non-read command to cd!!\n");
604 xtrace(REQUEST, "end_request(0): write\n");
605 end_request(req, 0);
606 return;
607 }
608 else {
609 stuffp->status = 0;
610 while (req->nr_sectors) {
611 int i;
612
613 i = mcdx_transfer(stuffp,
614 req->buffer,
615 req->sector,
616 req->nr_sectors);
617
618 if (i == -1) {
619 end_request(req, 0);
620 goto again;
621 }
622 req->sector += i;
623 req->nr_sectors -= i;
624 req->buffer += (i * 512);
625 }
626 end_request(req, 1);
627 goto again;
628
629 xtrace(REQUEST, "end_request(1)\n");
630 end_request(req, 1);
631 }
632
633 goto again;
634}
635
636static int mcdx_open(struct cdrom_device_info *cdi, int purpose)
637{
638 struct s_drive_stuff *stuffp;
639 xtrace(OPENCLOSE, "open()\n");
640 stuffp = cdi->handle;
641 if (!stuffp->present)
642 return -ENXIO;
643
644 /* Make the modules looking used ... (thanx bjorn).
645 * But we shouldn't forget to decrement the module counter
646 * on error return */
647
648 /* this is only done to test if the drive talks with us */
649 if (-1 == mcdx_getstatus(stuffp, 1))
650 return -EIO;
651
652 if (stuffp->xxx) {
653
654 xtrace(OPENCLOSE, "open() media changed\n");
655 stuffp->audiostatus = CDROM_AUDIO_INVALID;
656 stuffp->readcmd = 0;
657 xtrace(OPENCLOSE, "open() Request multisession info\n");
658 if (-1 ==
659 mcdx_requestmultidiskinfo(stuffp, &stuffp->multi, 6))
660 xinfo("No multidiskinfo\n");
661 } else {
662 /* multisession ? */
663 if (!stuffp->multi.multi)
664 stuffp->multi.msf_last.second = 2;
665
666 xtrace(OPENCLOSE, "open() MS: %d, last @ %02x:%02x.%02x\n",
667 stuffp->multi.multi,
668 stuffp->multi.msf_last.minute,
669 stuffp->multi.msf_last.second,
670 stuffp->multi.msf_last.frame);
671
672 {;
673 } /* got multisession information */
674 /* request the disks table of contents (aka diskinfo) */
675 if (-1 == mcdx_requesttocdata(stuffp, &stuffp->di, 1)) {
676
677 stuffp->lastsector = -1;
678
679 } else {
680
681 stuffp->lastsector = (CD_FRAMESIZE / 512)
682 * msf2log(&stuffp->di.msf_leadout) - 1;
683
684 xtrace(OPENCLOSE,
685 "open() start %d (%02x:%02x.%02x) %d\n",
686 stuffp->di.n_first,
687 stuffp->di.msf_first.minute,
688 stuffp->di.msf_first.second,
689 stuffp->di.msf_first.frame,
690 msf2log(&stuffp->di.msf_first));
691 xtrace(OPENCLOSE,
692 "open() last %d (%02x:%02x.%02x) %d\n",
693 stuffp->di.n_last,
694 stuffp->di.msf_leadout.minute,
695 stuffp->di.msf_leadout.second,
696 stuffp->di.msf_leadout.frame,
697 msf2log(&stuffp->di.msf_leadout));
698 }
699
700 if (stuffp->toc) {
701 xtrace(MALLOC, "open() free old toc @ %p\n",
702 stuffp->toc);
703 kfree(stuffp->toc);
704
705 stuffp->toc = NULL;
706 }
707
708 xtrace(OPENCLOSE, "open() init irq generation\n");
709 if (-1 == mcdx_config(stuffp, 1))
710 return -EIO;
711#if FALLBACK
712 /* Set the read speed */
713 xwarn("AAA %x AAA\n", stuffp->readcmd);
714 if (stuffp->readerrs)
715 stuffp->readcmd = READ1X;
716 else
717 stuffp->readcmd =
718 stuffp->present | SINGLE ? READ1X : READ2X;
719 xwarn("XXX %x XXX\n", stuffp->readcmd);
720#else
721 stuffp->readcmd =
722 stuffp->present | SINGLE ? READ1X : READ2X;
723#endif
724
725 /* try to get the first sector, iff any ... */
726 if (stuffp->lastsector >= 0) {
727 char buf[512];
728 int ans;
729 int tries;
730
731 stuffp->xa = 0;
732 stuffp->audio = 0;
733
734 for (tries = 6; tries; tries--) {
735
736 stuffp->introk = 1;
737
738 xtrace(OPENCLOSE, "open() try as %s\n",
739 stuffp->xa ? "XA" : "normal");
740 /* set data mode */
741 if (-1 == (ans = mcdx_setdatamode(stuffp,
742 stuffp->
743 xa ?
744 MODE2 :
745 MODE1,
746 1))) {
747 /* return -EIO; */
748 stuffp->xa = 0;
749 break;
750 }
751
752 if ((stuffp->audio = e_audio(ans)))
753 break;
754
755 while (0 ==
756 (ans =
757 mcdx_transfer(stuffp, buf, 0, 1)));
758
759 if (ans == 1)
760 break;
761 stuffp->xa = !stuffp->xa;
762 }
763 }
764 /* xa disks will be read in raw mode, others not */
765 if (-1 == mcdx_setdrivemode(stuffp,
766 stuffp->xa ? RAW : COOKED,
767 1))
768 return -EIO;
769 if (stuffp->audio) {
770 xinfo("open() audio disk found\n");
771 } else if (stuffp->lastsector >= 0) {
772 xinfo("open() %s%s disk found\n",
773 stuffp->xa ? "XA / " : "",
774 stuffp->multi.
775 multi ? "Multi Session" : "Single Session");
776 }
777 }
778 stuffp->xxx = 0;
779 stuffp->users++;
780 return 0;
781}
782
783static void mcdx_close(struct cdrom_device_info *cdi)
784{
785 struct s_drive_stuff *stuffp;
786
787 xtrace(OPENCLOSE, "close()\n");
788
789 stuffp = cdi->handle;
790
791 --stuffp->users;
792}
793
794static int mcdx_media_changed(struct cdrom_device_info *cdi, int disc_nr)
795/* Return: 1 if media changed since last call to this function
796 0 otherwise */
797{
798 struct s_drive_stuff *stuffp;
799
800 xinfo("mcdx_media_changed called for device %s\n", cdi->name);
801
802 stuffp = cdi->handle;
803 mcdx_getstatus(stuffp, 1);
804
805 if (stuffp->yyy == 0)
806 return 0;
807
808 stuffp->yyy = 0;
809 return 1;
810}
811
812#ifndef MODULE
813static int __init mcdx_setup(char *str)
814{
815 int pi[4];
816 (void) get_options(str, ARRAY_SIZE(pi), pi);
817
818 if (pi[0] > 0)
819 mcdx_drive_map[0][0] = pi[1];
820 if (pi[0] > 1)
821 mcdx_drive_map[0][1] = pi[2];
822 return 1;
823}
824
825__setup("mcdx=", mcdx_setup);
826
827#endif
828
829/* DIRTY PART ******************************************************/
830
831static void mcdx_delay(struct s_drive_stuff *stuff, long jifs)
832/* This routine is used for sleeping.
833 * A jifs value <0 means NO sleeping,
834 * =0 means minimal sleeping (let the kernel
835 * run for other processes)
836 * >0 means at least sleep for that amount.
837 * May be we could use a simple count loop w/ jumps to itself, but
838 * I wanna make this independent of cpu speed. [1 jiffy is 1/HZ] sec */
839{
840 if (jifs < 0)
841 return;
842
843 xtrace(SLEEP, "*** delay: sleepq\n");
844 interruptible_sleep_on_timeout(&stuff->sleepq, jifs);
845 xtrace(SLEEP, "delay awoken\n");
846 if (signal_pending(current)) {
847 xtrace(SLEEP, "got signal\n");
848 }
849}
850
851static irqreturn_t mcdx_intr(int irq, void *dev_id, struct pt_regs *regs)
852{
853 struct s_drive_stuff *stuffp = dev_id;
854 unsigned char b;
855
856 if (stuffp == NULL) {
857 xwarn("mcdx: no device for intr %d\n", irq);
858 return IRQ_NONE;
859 }
860#ifdef AK2
861 if (!stuffp->busy && stuffp->pending)
862 stuffp->int_err = 1;
863
864#endif /* AK2 */
865 /* get the interrupt status */
866 b = inb(stuffp->rreg_status);
867 stuffp->introk = ~b & MCDX_RBIT_DTEN;
868
869 /* NOTE: We only should get interrupts if the data we
870 * requested are ready to transfer.
871 * But the drive seems to generate ``asynchronous'' interrupts
872 * on several error conditions too. (Despite the err int enable
873 * setting during initialisation) */
874
875 /* if not ok, read the next byte as the drives status */
876 if (!stuffp->introk) {
877 xtrace(IRQ, "intr() irq %d hw status 0x%02x\n", irq, b);
878 if (~b & MCDX_RBIT_STEN) {
879 xinfo("intr() irq %d status 0x%02x\n",
880 irq, inb(stuffp->rreg_data));
881 } else {
882 xinfo("intr() irq %d ambiguous hw status\n", irq);
883 }
884 } else {
885 xtrace(IRQ, "irq() irq %d ok, status %02x\n", irq, b);
886 }
887
888 stuffp->busy = 0;
889 wake_up_interruptible(&stuffp->busyq);
890 return IRQ_HANDLED;
891}
892
893
894static int mcdx_talk(struct s_drive_stuff *stuffp,
895 const unsigned char *cmd, size_t cmdlen,
896 void *buffer, size_t size, unsigned int timeout, int tries)
897/* Send a command to the drive, wait for the result.
898 * returns -1 on timeout, drive status otherwise
899 * If buffer is not zero, the result (length size) is stored there.
900 * If buffer is zero the size should be the number of bytes to read
901 * from the drive. These bytes are discarded.
902 */
903{
904 int st;
905 char c;
906 int discard;
907
908 /* Somebody wants the data read? */
909 if ((discard = (buffer == NULL)))
910 buffer = &c;
911
912 while (stuffp->lock) {
913 xtrace(SLEEP, "*** talk: lockq\n");
914 interruptible_sleep_on(&stuffp->lockq);
915 xtrace(SLEEP, "talk: awoken\n");
916 }
917
918 stuffp->lock = 1;
919
920 /* An operation other then reading data destroys the
921 * data already requested and remembered in stuffp->request, ... */
922 stuffp->valid = 0;
923
924#if MCDX_DEBUG & TALK
925 {
926 unsigned char i;
927 xtrace(TALK,
928 "talk() %d / %d tries, res.size %d, command 0x%02x",
929 tries, timeout, size, (unsigned char) cmd[0]);
930 for (i = 1; i < cmdlen; i++)
931 xtrace(TALK, " 0x%02x", cmd[i]);
932 xtrace(TALK, "\n");
933 }
934#endif
935
936 /* give up if all tries are done (bad) or if the status
937 * st != -1 (good) */
938 for (st = -1; st == -1 && tries; tries--) {
939
940 char *bp = (char *) buffer;
941 size_t sz = size;
942
943 outsb(stuffp->wreg_data, cmd, cmdlen);
944 xtrace(TALK, "talk() command sent\n");
945
946 /* get the status byte */
947 if (-1 == mcdx_getval(stuffp, timeout, 0, bp)) {
948 xinfo("talk() %02x timed out (status), %d tr%s left\n",
949 cmd[0], tries - 1, tries == 2 ? "y" : "ies");
950 continue;
951 }
952 st = *bp;
953 sz--;
954 if (!discard)
955 bp++;
956
957 xtrace(TALK, "talk() got status 0x%02x\n", st);
958
959 /* command error? */
960 if (e_cmderr(st)) {
961 xwarn("command error cmd = %02x %s \n",
962 cmd[0], cmdlen > 1 ? "..." : "");
963 st = -1;
964 continue;
965 }
966
967 /* audio status? */
968 if (stuffp->audiostatus == CDROM_AUDIO_INVALID)
969 stuffp->audiostatus =
970 e_audiobusy(st) ? CDROM_AUDIO_PLAY :
971 CDROM_AUDIO_NO_STATUS;
972 else if (stuffp->audiostatus == CDROM_AUDIO_PLAY
973 && e_audiobusy(st) == 0)
974 stuffp->audiostatus = CDROM_AUDIO_COMPLETED;
975
976 /* media change? */
977 if (e_changed(st)) {
978 xinfo("talk() media changed\n");
979 stuffp->xxx = stuffp->yyy = 1;
980 }
981
982 /* now actually get the data */
983 while (sz--) {
984 if (-1 == mcdx_getval(stuffp, timeout, 0, bp)) {
985 xinfo("talk() %02x timed out (data), %d tr%s left\n",
986 cmd[0], tries - 1,
987 tries == 2 ? "y" : "ies");
988 st = -1;
989 break;
990 }
991 if (!discard)
992 bp++;
993 xtrace(TALK, "talk() got 0x%02x\n", *(bp - 1));
994 }
995 }
996
997#if !MCDX_QUIET
998 if (!tries && st == -1)
999 xinfo("talk() giving up\n");
1000#endif
1001
1002 stuffp->lock = 0;
1003 wake_up_interruptible(&stuffp->lockq);
1004
1005 xtrace(TALK, "talk() done with 0x%02x\n", st);
1006 return st;
1007}
1008
1009/* MODULE STUFF ***********************************************************/
1010
1011int __mcdx_init(void)
1012{
1013 int i;
1014 int drives = 0;
1015
1016 mcdx_init();
1017 for (i = 0; i < MCDX_NDRIVES; i++) {
1018 if (mcdx_stuffp[i]) {
1019 xtrace(INIT, "init_module() drive %d stuff @ %p\n",
1020 i, mcdx_stuffp[i]);
1021 drives++;
1022 }
1023 }
1024
1025 if (!drives)
1026 return -EIO;
1027
1028 return 0;
1029}
1030
1031void __exit mcdx_exit(void)
1032{
1033 int i;
1034
1035 xinfo("cleanup_module called\n");
1036
1037 for (i = 0; i < MCDX_NDRIVES; i++) {
1038 struct s_drive_stuff *stuffp = mcdx_stuffp[i];
1039 if (!stuffp)
1040 continue;
1041 del_gendisk(stuffp->disk);
1042 if (unregister_cdrom(&stuffp->info)) {
1043 printk(KERN_WARNING "Can't unregister cdrom mcdx\n");
1044 continue;
1045 }
1046 put_disk(stuffp->disk);
1047 release_region(stuffp->wreg_data, MCDX_IO_SIZE);
1048 free_irq(stuffp->irq, NULL);
1049 if (stuffp->toc) {
1050 xtrace(MALLOC, "cleanup_module() free toc @ %p\n",
1051 stuffp->toc);
1052 kfree(stuffp->toc);
1053 }
1054 xtrace(MALLOC, "cleanup_module() free stuffp @ %p\n",
1055 stuffp);
1056 mcdx_stuffp[i] = NULL;
1057 kfree(stuffp);
1058 }
1059
1060 if (unregister_blkdev(MAJOR_NR, "mcdx") != 0) {
1061 xwarn("cleanup() unregister_blkdev() failed\n");
1062 }
1063 blk_cleanup_queue(mcdx_queue);
1064#if !MCDX_QUIET
1065 else
1066 xinfo("cleanup() succeeded\n");
1067#endif
1068}
1069
1070#ifdef MODULE
1071module_init(__mcdx_init);
1072#endif
1073module_exit(mcdx_exit);
1074
1075
1076/* Support functions ************************************************/
1077
1078int __init mcdx_init_drive(int drive)
1079{
1080 struct s_version version;
1081 struct gendisk *disk;
1082 struct s_drive_stuff *stuffp;
1083 int size = sizeof(*stuffp);
1084 char msg[80];
1085
1086 xtrace(INIT, "init() try drive %d\n", drive);
1087
1088 xtrace(INIT, "kmalloc space for stuffpt's\n");
1089 xtrace(MALLOC, "init() malloc %d bytes\n", size);
1090 if (!(stuffp = kmalloc(size, GFP_KERNEL))) {
1091 xwarn("init() malloc failed\n");
1092 return 1;
1093 }
1094
1095 disk = alloc_disk(1);
1096 if (!disk) {
1097 xwarn("init() malloc failed\n");
1098 kfree(stuffp);
1099 return 1;
1100 }
1101
1102 xtrace(INIT, "init() got %d bytes for drive stuff @ %p\n",
1103 sizeof(*stuffp), stuffp);
1104
1105 /* set default values */
1106 memset(stuffp, 0, sizeof(*stuffp));
1107
1108 stuffp->present = 0; /* this should be 0 already */
1109 stuffp->toc = NULL; /* this should be NULL already */
1110
1111 /* setup our irq and i/o addresses */
1112 stuffp->irq = irq(mcdx_drive_map[drive]);
1113 stuffp->wreg_data = stuffp->rreg_data = port(mcdx_drive_map[drive]);
1114 stuffp->wreg_reset = stuffp->rreg_status = stuffp->wreg_data + 1;
1115 stuffp->wreg_hcon = stuffp->wreg_reset + 1;
1116 stuffp->wreg_chn = stuffp->wreg_hcon + 1;
1117
1118 init_waitqueue_head(&stuffp->busyq);
1119 init_waitqueue_head(&stuffp->lockq);
1120 init_waitqueue_head(&stuffp->sleepq);
1121
1122 /* check if i/o addresses are available */
1123 if (!request_region(stuffp->wreg_data, MCDX_IO_SIZE, "mcdx")) {
1124 xwarn("0x%03x,%d: Init failed. "
1125 "I/O ports (0x%03x..0x%03x) already in use.\n",
1126 stuffp->wreg_data, stuffp->irq,
1127 stuffp->wreg_data,
1128 stuffp->wreg_data + MCDX_IO_SIZE - 1);
1129 xtrace(MALLOC, "init() free stuffp @ %p\n", stuffp);
1130 kfree(stuffp);
1131 put_disk(disk);
1132 xtrace(INIT, "init() continue at next drive\n");
1133 return 0; /* next drive */
1134 }
1135
1136 xtrace(INIT, "init() i/o port is available at 0x%03x\n"
1137 stuffp->wreg_data);
1138 xtrace(INIT, "init() hardware reset\n");
1139 mcdx_reset(stuffp, HARD, 1);
1140
1141 xtrace(INIT, "init() get version\n");
1142 if (-1 == mcdx_requestversion(stuffp, &version, 4)) {
1143 /* failed, next drive */
1144 release_region(stuffp->wreg_data, MCDX_IO_SIZE);
1145 xwarn("%s=0x%03x,%d: Init failed. Can't get version.\n",
1146 MCDX, stuffp->wreg_data, stuffp->irq);
1147 xtrace(MALLOC, "init() free stuffp @ %p\n", stuffp);
1148 kfree(stuffp);
1149 put_disk(disk);
1150 xtrace(INIT, "init() continue at next drive\n");
1151 return 0;
1152 }
1153
1154 switch (version.code) {
1155 case 'D':
1156 stuffp->readcmd = READ2X;
1157 stuffp->present = DOUBLE | DOOR | MULTI;
1158 break;
1159 case 'F':
1160 stuffp->readcmd = READ1X;
1161 stuffp->present = SINGLE | DOOR | MULTI;
1162 break;
1163 case 'M':
1164 stuffp->readcmd = READ1X;
1165 stuffp->present = SINGLE;
1166 break;
1167 default:
1168 stuffp->present = 0;
1169 break;
1170 }
1171
1172 stuffp->playcmd = READ1X;
1173
1174 if (!stuffp->present) {
1175 release_region(stuffp->wreg_data, MCDX_IO_SIZE);
1176 xwarn("%s=0x%03x,%d: Init failed. No Mitsumi CD-ROM?.\n",
1177 MCDX, stuffp->wreg_data, stuffp->irq);
1178 kfree(stuffp);
1179 put_disk(disk);
1180 return 0; /* next drive */
1181 }
1182
1183 xtrace(INIT, "init() register blkdev\n");
1184 if (register_blkdev(MAJOR_NR, "mcdx")) {
1185 release_region(stuffp->wreg_data, MCDX_IO_SIZE);
1186 kfree(stuffp);
1187 put_disk(disk);
1188 return 1;
1189 }
1190
1191 mcdx_queue = blk_init_queue(do_mcdx_request, &mcdx_lock);
1192 if (!mcdx_queue) {
1193 unregister_blkdev(MAJOR_NR, "mcdx");
1194 release_region(stuffp->wreg_data, MCDX_IO_SIZE);
1195 kfree(stuffp);
1196 put_disk(disk);
1197 return 1;
1198 }
1199
1200 xtrace(INIT, "init() subscribe irq and i/o\n");
1201 if (request_irq(stuffp->irq, mcdx_intr, SA_INTERRUPT, "mcdx", stuffp)) {
1202 release_region(stuffp->wreg_data, MCDX_IO_SIZE);
1203 xwarn("%s=0x%03x,%d: Init failed. Can't get irq (%d).\n",
1204 MCDX, stuffp->wreg_data, stuffp->irq, stuffp->irq);
1205 stuffp->irq = 0;
1206 blk_cleanup_queue(mcdx_queue);
1207 kfree(stuffp);
1208 put_disk(disk);
1209 return 0;
1210 }
1211
1212 xtrace(INIT, "init() get garbage\n");
1213 {
1214 int i;
1215 mcdx_delay(stuffp, HZ / 2);
1216 for (i = 100; i; i--)
1217 (void) inb(stuffp->rreg_status);
1218 }
1219
1220
1221#if WE_KNOW_WHY
1222 /* irq 11 -> channel register */
1223 outb(0x50, stuffp->wreg_chn);
1224#endif
1225
1226 xtrace(INIT, "init() set non dma but irq mode\n");
1227 mcdx_config(stuffp, 1);
1228
1229 stuffp->info.ops = &mcdx_dops;
1230 stuffp->info.speed = 2;
1231 stuffp->info.capacity = 1;
1232 stuffp->info.handle = stuffp;
1233 sprintf(stuffp->info.name, "mcdx%d", drive);
1234 disk->major = MAJOR_NR;
1235 disk->first_minor = drive;
1236 strcpy(disk->disk_name, stuffp->info.name);
1237 disk->fops = &mcdx_bdops;
1238 disk->flags = GENHD_FL_CD;
1239 stuffp->disk = disk;
1240
1241 sprintf(msg, " mcdx: Mitsumi CD-ROM installed at 0x%03x, irq %d."
1242 " (Firmware version %c %x)\n",
1243 stuffp->wreg_data, stuffp->irq, version.code, version.ver);
1244 mcdx_stuffp[drive] = stuffp;
1245 xtrace(INIT, "init() mcdx_stuffp[%d] = %p\n", drive, stuffp);
1246 if (register_cdrom(&stuffp->info) != 0) {
1247 printk("Cannot register Mitsumi CD-ROM!\n");
1248 free_irq(stuffp->irq, NULL);
1249 release_region(stuffp->wreg_data, MCDX_IO_SIZE);
1250 kfree(stuffp);
1251 put_disk(disk);
1252 if (unregister_blkdev(MAJOR_NR, "mcdx") != 0)
1253 xwarn("cleanup() unregister_blkdev() failed\n");
1254 blk_cleanup_queue(mcdx_queue);
1255 return 2;
1256 }
1257 disk->private_data = stuffp;
1258 disk->queue = mcdx_queue;
1259 add_disk(disk);
1260 printk(msg);
1261 return 0;
1262}
1263
1264int __init mcdx_init(void)
1265{
1266 int drive;
1267 xwarn("Version 2.14(hs) \n");
1268
1269 xwarn("$Id: mcdx.c,v 1.21 1997/01/26 07:12:59 davem Exp $\n");
1270
1271 /* zero the pointer array */
1272 for (drive = 0; drive < MCDX_NDRIVES; drive++)
1273 mcdx_stuffp[drive] = NULL;
1274
1275 /* do the initialisation */
1276 for (drive = 0; drive < MCDX_NDRIVES; drive++) {
1277 switch (mcdx_init_drive(drive)) {
1278 case 2:
1279 return -EIO;
1280 case 1:
1281 break;
1282 }
1283 }
1284 return 0;
1285}
1286
1287static int mcdx_transfer(struct s_drive_stuff *stuffp,
1288 char *p, int sector, int nr_sectors)
1289/* This seems to do the actually transfer. But it does more. It
1290 keeps track of errors occurred and will (if possible) fall back
1291 to single speed on error.
1292 Return: -1 on timeout or other error
1293 else status byte (as in stuff->st) */
1294{
1295 int ans;
1296
1297 ans = mcdx_xfer(stuffp, p, sector, nr_sectors);
1298 return ans;
1299#if FALLBACK
1300 if (-1 == ans)
1301 stuffp->readerrs++;
1302 else
1303 return ans;
1304
1305 if (stuffp->readerrs && stuffp->readcmd == READ1X) {
1306 xwarn("XXX Already reading 1x -- no chance\n");
1307 return -1;
1308 }
1309
1310 xwarn("XXX Fallback to 1x\n");
1311
1312 stuffp->readcmd = READ1X;
1313 return mcdx_transfer(stuffp, p, sector, nr_sectors);
1314#endif
1315
1316}
1317
1318
1319static int mcdx_xfer(struct s_drive_stuff *stuffp,
1320 char *p, int sector, int nr_sectors)
1321/* This does actually the transfer from the drive.
1322 Return: -1 on timeout or other error
1323 else status byte (as in stuff->st) */
1324{
1325 int border;
1326 int done = 0;
1327 long timeout;
1328
1329 if (stuffp->audio) {
1330 xwarn("Attempt to read from audio CD.\n");
1331 return -1;
1332 }
1333
1334 if (!stuffp->readcmd) {
1335 xinfo("Can't transfer from missing disk.\n");
1336 return -1;
1337 }
1338
1339 while (stuffp->lock) {
1340 interruptible_sleep_on(&stuffp->lockq);
1341 }
1342
1343 if (stuffp->valid && (sector >= stuffp->pending)
1344 && (sector < stuffp->low_border)) {
1345
1346 /* All (or at least a part of the sectors requested) seems
1347 * to be already requested, so we don't need to bother the
1348 * drive with new requests ...
1349 * Wait for the drive become idle, but first
1350 * check for possible occurred errors --- the drive
1351 * seems to report them asynchronously */
1352
1353
1354 border = stuffp->high_border < (border =
1355 sector + nr_sectors)
1356 ? stuffp->high_border : border;
1357
1358 stuffp->lock = current->pid;
1359
1360 do {
1361
1362 while (stuffp->busy) {
1363
1364 timeout =
1365 interruptible_sleep_on_timeout
1366 (&stuffp->busyq, 5 * HZ);
1367
1368 if (!stuffp->introk) {
1369 xtrace(XFER,
1370 "error via interrupt\n");
1371 } else if (!timeout) {
1372 xtrace(XFER, "timeout\n");
1373 } else if (signal_pending(current)) {
1374 xtrace(XFER, "signal\n");
1375 } else
1376 continue;
1377
1378 stuffp->lock = 0;
1379 stuffp->busy = 0;
1380 stuffp->valid = 0;
1381
1382 wake_up_interruptible(&stuffp->lockq);
1383 xtrace(XFER, "transfer() done (-1)\n");
1384 return -1;
1385 }
1386
1387 /* check if we need to set the busy flag (as we
1388 * expect an interrupt */
1389 stuffp->busy = (3 == (stuffp->pending & 3));
1390
1391 /* Test if it's the first sector of a block,
1392 * there we have to skip some bytes as we read raw data */
1393 if (stuffp->xa && (0 == (stuffp->pending & 3))) {
1394 const int HEAD =
1395 CD_FRAMESIZE_RAW - CD_XA_TAIL -
1396 CD_FRAMESIZE;
1397 insb(stuffp->rreg_data, p, HEAD);
1398 }
1399
1400 /* now actually read the data */
1401 insb(stuffp->rreg_data, p, 512);
1402
1403 /* test if it's the last sector of a block,
1404 * if so, we have to handle XA special */
1405 if ((3 == (stuffp->pending & 3)) && stuffp->xa) {
1406 char dummy[CD_XA_TAIL];
1407 insb(stuffp->rreg_data, &dummy[0], CD_XA_TAIL);
1408 }
1409
1410 if (stuffp->pending == sector) {
1411 p += 512;
1412 done++;
1413 sector++;
1414 }
1415 } while (++(stuffp->pending) < border);
1416
1417 stuffp->lock = 0;
1418 wake_up_interruptible(&stuffp->lockq);
1419
1420 } else {
1421
1422 /* The requested sector(s) is/are out of the
1423 * already requested range, so we have to bother the drive
1424 * with a new request. */
1425
1426 static unsigned char cmd[] = {
1427 0,
1428 0, 0, 0,
1429 0, 0, 0
1430 };
1431
1432 cmd[0] = stuffp->readcmd;
1433
1434 /* The numbers held in ->pending, ..., should be valid */
1435 stuffp->valid = 1;
1436 stuffp->pending = sector & ~3;
1437
1438 /* do some sanity checks */
1439 if (stuffp->pending > stuffp->lastsector) {
1440 xwarn
1441 ("transfer() sector %d from nirvana requested.\n",
1442 stuffp->pending);
1443 stuffp->status = MCDX_ST_EOM;
1444 stuffp->valid = 0;
1445 xtrace(XFER, "transfer() done (-1)\n");
1446 return -1;
1447 }
1448
1449 if ((stuffp->low_border = stuffp->pending + DIRECT_SIZE)
1450 > stuffp->lastsector + 1) {
1451 xtrace(XFER, "cut low_border\n");
1452 stuffp->low_border = stuffp->lastsector + 1;
1453 }
1454 if ((stuffp->high_border = stuffp->pending + REQUEST_SIZE)
1455 > stuffp->lastsector + 1) {
1456 xtrace(XFER, "cut high_border\n");
1457 stuffp->high_border = stuffp->lastsector + 1;
1458 }
1459
1460 { /* Convert the sector to be requested to MSF format */
1461 struct cdrom_msf0 pending;
1462 log2msf(stuffp->pending / 4, &pending);
1463 cmd[1] = pending.minute;
1464 cmd[2] = pending.second;
1465 cmd[3] = pending.frame;
1466 }
1467
1468 cmd[6] =
1469 (unsigned
1470 char) ((stuffp->high_border - stuffp->pending) / 4);
1471 xtrace(XFER, "[%2d]\n", cmd[6]);
1472
1473 stuffp->busy = 1;
1474 /* Now really issue the request command */
1475 outsb(stuffp->wreg_data, cmd, sizeof cmd);
1476
1477 }
1478#ifdef AK2
1479 if (stuffp->int_err) {
1480 stuffp->valid = 0;
1481 stuffp->int_err = 0;
1482 return -1;
1483 }
1484#endif /* AK2 */
1485
1486 stuffp->low_border = (stuffp->low_border +=
1487 done) <
1488 stuffp->high_border ? stuffp->low_border : stuffp->high_border;
1489
1490 return done;
1491}
1492
1493
1494/* Access to elements of the mcdx_drive_map members */
1495
1496static unsigned port(int *ip)
1497{
1498 return ip[0];
1499}
1500static int irq(int *ip)
1501{
1502 return ip[1];
1503}
1504
1505/* Misc number converters */
1506
1507static unsigned int bcd2uint(unsigned char c)
1508{
1509 return (c >> 4) * 10 + (c & 0x0f);
1510}
1511
1512static unsigned int uint2bcd(unsigned int ival)
1513{
1514 return ((ival / 10) << 4) | (ival % 10);
1515}
1516
1517static void log2msf(unsigned int l, struct cdrom_msf0 *pmsf)
1518{
1519 l += CD_MSF_OFFSET;
1520 pmsf->minute = uint2bcd(l / 4500), l %= 4500;
1521 pmsf->second = uint2bcd(l / 75);
1522 pmsf->frame = uint2bcd(l % 75);
1523}
1524
1525static unsigned int msf2log(const struct cdrom_msf0 *pmsf)
1526{
1527 return bcd2uint(pmsf->frame)
1528 + bcd2uint(pmsf->second) * 75
1529 + bcd2uint(pmsf->minute) * 4500 - CD_MSF_OFFSET;
1530}
1531
1532int mcdx_readtoc(struct s_drive_stuff *stuffp)
1533/* Read the toc entries from the CD,
1534 * Return: -1 on failure, else 0 */
1535{
1536
1537 if (stuffp->toc) {
1538 xtrace(READTOC, "ioctl() toc already read\n");
1539 return 0;
1540 }
1541
1542 xtrace(READTOC, "ioctl() readtoc for %d tracks\n",
1543 stuffp->di.n_last - stuffp->di.n_first + 1);
1544
1545 if (-1 == mcdx_hold(stuffp, 1))
1546 return -1;
1547
1548 xtrace(READTOC, "ioctl() tocmode\n");
1549 if (-1 == mcdx_setdrivemode(stuffp, TOC, 1))
1550 return -EIO;
1551
1552 /* all seems to be ok so far ... malloc */
1553 {
1554 int size;
1555 size =
1556 sizeof(struct s_subqcode) * (stuffp->di.n_last -
1557 stuffp->di.n_first + 2);
1558
1559 xtrace(MALLOC, "ioctl() malloc %d bytes\n", size);
1560 stuffp->toc = kmalloc(size, GFP_KERNEL);
1561 if (!stuffp->toc) {
1562 xwarn("Cannot malloc %d bytes for toc\n", size);
1563 mcdx_setdrivemode(stuffp, DATA, 1);
1564 return -EIO;
1565 }
1566 }
1567
1568 /* now read actually the index */
1569 {
1570 int trk;
1571 int retries;
1572
1573 for (trk = 0;
1574 trk < (stuffp->di.n_last - stuffp->di.n_first + 1);
1575 trk++)
1576 stuffp->toc[trk].index = 0;
1577
1578 for (retries = 300; retries; retries--) { /* why 300? */
1579 struct s_subqcode q;
1580 unsigned int idx;
1581
1582 if (-1 == mcdx_requestsubqcode(stuffp, &q, 1)) {
1583 mcdx_setdrivemode(stuffp, DATA, 1);
1584 return -EIO;
1585 }
1586
1587 idx = bcd2uint(q.index);
1588
1589 if ((idx > 0)
1590 && (idx <= stuffp->di.n_last)
1591 && (q.tno == 0)
1592 && (stuffp->toc[idx - stuffp->di.n_first].
1593 index == 0)) {
1594 stuffp->toc[idx - stuffp->di.n_first] = q;
1595 xtrace(READTOC,
1596 "ioctl() toc idx %d (trk %d)\n",
1597 idx, trk);
1598 trk--;
1599 }
1600 if (trk == 0)
1601 break;
1602 }
1603 memset(&stuffp->
1604 toc[stuffp->di.n_last - stuffp->di.n_first + 1], 0,
1605 sizeof(stuffp->toc[0]));
1606 stuffp->toc[stuffp->di.n_last - stuffp->di.n_first +
1607 1].dt = stuffp->di.msf_leadout;
1608 }
1609
1610 /* unset toc mode */
1611 xtrace(READTOC, "ioctl() undo toc mode\n");
1612 if (-1 == mcdx_setdrivemode(stuffp, DATA, 2))
1613 return -EIO;
1614
1615#if MCDX_DEBUG && READTOC
1616 {
1617 int trk;
1618 for (trk = 0;
1619 trk < (stuffp->di.n_last - stuffp->di.n_first + 2);
1620 trk++)
1621 xtrace(READTOC, "ioctl() %d readtoc %02x %02x %02x"
1622 " %02x:%02x.%02x %02x:%02x.%02x\n",
1623 trk + stuffp->di.n_first,
1624 stuffp->toc[trk].control,
1625 stuffp->toc[trk].tno,
1626 stuffp->toc[trk].index,
1627 stuffp->toc[trk].tt.minute,
1628 stuffp->toc[trk].tt.second,
1629 stuffp->toc[trk].tt.frame,
1630 stuffp->toc[trk].dt.minute,
1631 stuffp->toc[trk].dt.second,
1632 stuffp->toc[trk].dt.frame);
1633 }
1634#endif
1635
1636 return 0;
1637}
1638
1639static int
1640mcdx_playmsf(struct s_drive_stuff *stuffp, const struct cdrom_msf *msf)
1641{
1642 unsigned char cmd[7] = {
1643 0, 0, 0, 0, 0, 0, 0
1644 };
1645
1646 if (!stuffp->readcmd) {
1647 xinfo("Can't play from missing disk.\n");
1648 return -1;
1649 }
1650
1651 cmd[0] = stuffp->playcmd;
1652
1653 cmd[1] = msf->cdmsf_min0;
1654 cmd[2] = msf->cdmsf_sec0;
1655 cmd[3] = msf->cdmsf_frame0;
1656 cmd[4] = msf->cdmsf_min1;
1657 cmd[5] = msf->cdmsf_sec1;
1658 cmd[6] = msf->cdmsf_frame1;
1659
1660 xtrace(PLAYMSF, "ioctl(): play %x "
1661 "%02x:%02x:%02x -- %02x:%02x:%02x\n",
1662 cmd[0], cmd[1], cmd[2], cmd[3], cmd[4], cmd[5], cmd[6]);
1663
1664 outsb(stuffp->wreg_data, cmd, sizeof cmd);
1665
1666 if (-1 == mcdx_getval(stuffp, 3 * HZ, 0, NULL)) {
1667 xwarn("playmsf() timeout\n");
1668 return -1;
1669 }
1670
1671 stuffp->audiostatus = CDROM_AUDIO_PLAY;
1672 return 0;
1673}
1674
1675static int
1676mcdx_playtrk(struct s_drive_stuff *stuffp, const struct cdrom_ti *ti)
1677{
1678 struct s_subqcode *p;
1679 struct cdrom_msf msf;
1680
1681 if (-1 == mcdx_readtoc(stuffp))
1682 return -1;
1683
1684 if (ti)
1685 p = &stuffp->toc[ti->cdti_trk0 - stuffp->di.n_first];
1686 else
1687 p = &stuffp->start;
1688
1689 msf.cdmsf_min0 = p->dt.minute;
1690 msf.cdmsf_sec0 = p->dt.second;
1691 msf.cdmsf_frame0 = p->dt.frame;
1692
1693 if (ti) {
1694 p = &stuffp->toc[ti->cdti_trk1 - stuffp->di.n_first + 1];
1695 stuffp->stop = *p;
1696 } else
1697 p = &stuffp->stop;
1698
1699 msf.cdmsf_min1 = p->dt.minute;
1700 msf.cdmsf_sec1 = p->dt.second;
1701 msf.cdmsf_frame1 = p->dt.frame;
1702
1703 return mcdx_playmsf(stuffp, &msf);
1704}
1705
1706
1707/* Drive functions ************************************************/
1708
1709static int mcdx_tray_move(struct cdrom_device_info *cdi, int position)
1710{
1711 struct s_drive_stuff *stuffp = cdi->handle;
1712
1713 if (!stuffp->present)
1714 return -ENXIO;
1715 if (!(stuffp->present & DOOR))
1716 return -ENOSYS;
1717
1718 if (position) /* 1: eject */
1719 return mcdx_talk(stuffp, "\xf6", 1, NULL, 1, 5 * HZ, 3);
1720 else /* 0: close */
1721 return mcdx_talk(stuffp, "\xf8", 1, NULL, 1, 5 * HZ, 3);
1722 return 1;
1723}
1724
1725static int mcdx_stop(struct s_drive_stuff *stuffp, int tries)
1726{
1727 return mcdx_talk(stuffp, "\xf0", 1, NULL, 1, 2 * HZ, tries);
1728}
1729
1730static int mcdx_hold(struct s_drive_stuff *stuffp, int tries)
1731{
1732 return mcdx_talk(stuffp, "\x70", 1, NULL, 1, 2 * HZ, tries);
1733}
1734
1735static int mcdx_requestsubqcode(struct s_drive_stuff *stuffp,
1736 struct s_subqcode *sub, int tries)
1737{
1738 char buf[11];
1739 int ans;
1740
1741 if (-1 == (ans = mcdx_talk(stuffp, "\x20", 1, buf, sizeof(buf),
1742 2 * HZ, tries)))
1743 return -1;
1744 sub->control = buf[1];
1745 sub->tno = buf[2];
1746 sub->index = buf[3];
1747 sub->tt.minute = buf[4];
1748 sub->tt.second = buf[5];
1749 sub->tt.frame = buf[6];
1750 sub->dt.minute = buf[8];
1751 sub->dt.second = buf[9];
1752 sub->dt.frame = buf[10];
1753
1754 return ans;
1755}
1756
1757static int mcdx_requestmultidiskinfo(struct s_drive_stuff *stuffp,
1758 struct s_multi *multi, int tries)
1759{
1760 char buf[5];
1761 int ans;
1762
1763 if (stuffp->present & MULTI) {
1764 ans =
1765 mcdx_talk(stuffp, "\x11", 1, buf, sizeof(buf), 2 * HZ,
1766 tries);
1767 multi->multi = buf[1];
1768 multi->msf_last.minute = buf[2];
1769 multi->msf_last.second = buf[3];
1770 multi->msf_last.frame = buf[4];
1771 return ans;
1772 } else {
1773 multi->multi = 0;
1774 return 0;
1775 }
1776}
1777
1778static int mcdx_requesttocdata(struct s_drive_stuff *stuffp, struct s_diskinfo *info,
1779 int tries)
1780{
1781 char buf[9];
1782 int ans;
1783 ans =
1784 mcdx_talk(stuffp, "\x10", 1, buf, sizeof(buf), 2 * HZ, tries);
1785 if (ans == -1) {
1786 info->n_first = 0;
1787 info->n_last = 0;
1788 } else {
1789 info->n_first = bcd2uint(buf[1]);
1790 info->n_last = bcd2uint(buf[2]);
1791 info->msf_leadout.minute = buf[3];
1792 info->msf_leadout.second = buf[4];
1793 info->msf_leadout.frame = buf[5];
1794 info->msf_first.minute = buf[6];
1795 info->msf_first.second = buf[7];
1796 info->msf_first.frame = buf[8];
1797 }
1798 return ans;
1799}
1800
1801static int mcdx_setdrivemode(struct s_drive_stuff *stuffp, enum drivemodes mode,
1802 int tries)
1803{
1804 char cmd[2];
1805 int ans;
1806
1807 xtrace(HW, "setdrivemode() %d\n", mode);
1808
1809 if (-1 == (ans = mcdx_talk(stuffp, "\xc2", 1, cmd, sizeof(cmd), 5 * HZ, tries)))
1810 return -1;
1811
1812 switch (mode) {
1813 case TOC:
1814 cmd[1] |= 0x04;
1815 break;
1816 case DATA:
1817 cmd[1] &= ~0x04;
1818 break;
1819 case RAW:
1820 cmd[1] |= 0x40;
1821 break;
1822 case COOKED:
1823 cmd[1] &= ~0x40;
1824 break;
1825 default:
1826 break;
1827 }
1828 cmd[0] = 0x50;
1829 return mcdx_talk(stuffp, cmd, 2, NULL, 1, 5 * HZ, tries);
1830}
1831
1832static int mcdx_setdatamode(struct s_drive_stuff *stuffp, enum datamodes mode,
1833 int tries)
1834{
1835 unsigned char cmd[2] = { 0xa0 };
1836 xtrace(HW, "setdatamode() %d\n", mode);
1837 switch (mode) {
1838 case MODE0:
1839 cmd[1] = 0x00;
1840 break;
1841 case MODE1:
1842 cmd[1] = 0x01;
1843 break;
1844 case MODE2:
1845 cmd[1] = 0x02;
1846 break;
1847 default:
1848 return -EINVAL;
1849 }
1850 return mcdx_talk(stuffp, cmd, 2, NULL, 1, 5 * HZ, tries);
1851}
1852
1853static int mcdx_config(struct s_drive_stuff *stuffp, int tries)
1854{
1855 char cmd[4];
1856
1857 xtrace(HW, "config()\n");
1858
1859 cmd[0] = 0x90;
1860
1861 cmd[1] = 0x10; /* irq enable */
1862 cmd[2] = 0x05; /* pre, err irq enable */
1863
1864 if (-1 == mcdx_talk(stuffp, cmd, 3, NULL, 1, 1 * HZ, tries))
1865 return -1;
1866
1867 cmd[1] = 0x02; /* dma select */
1868 cmd[2] = 0x00; /* no dma */
1869
1870 return mcdx_talk(stuffp, cmd, 3, NULL, 1, 1 * HZ, tries);
1871}
1872
1873static int mcdx_requestversion(struct s_drive_stuff *stuffp, struct s_version *ver,
1874 int tries)
1875{
1876 char buf[3];
1877 int ans;
1878
1879 if (-1 == (ans = mcdx_talk(stuffp, "\xdc",
1880 1, buf, sizeof(buf), 2 * HZ, tries)))
1881 return ans;
1882
1883 ver->code = buf[1];
1884 ver->ver = buf[2];
1885
1886 return ans;
1887}
1888
1889static int mcdx_reset(struct s_drive_stuff *stuffp, enum resetmodes mode, int tries)
1890{
1891 if (mode == HARD) {
1892 outb(0, stuffp->wreg_chn); /* no dma, no irq -> hardware */
1893 outb(0, stuffp->wreg_reset); /* hw reset */
1894 return 0;
1895 } else
1896 return mcdx_talk(stuffp, "\x60", 1, NULL, 1, 5 * HZ, tries);
1897}
1898
1899static int mcdx_lockdoor(struct cdrom_device_info *cdi, int lock)
1900{
1901 struct s_drive_stuff *stuffp = cdi->handle;
1902 char cmd[2] = { 0xfe };
1903
1904 if (!(stuffp->present & DOOR))
1905 return -ENOSYS;
1906 if (stuffp->present & DOOR) {
1907 cmd[1] = lock ? 0x01 : 0x00;
1908 return mcdx_talk(stuffp, cmd, sizeof(cmd), NULL, 1, 5 * HZ, 3);
1909 } else
1910 return 0;
1911}
1912
1913static int mcdx_getstatus(struct s_drive_stuff *stuffp, int tries)
1914{
1915 return mcdx_talk(stuffp, "\x40", 1, NULL, 1, 5 * HZ, tries);
1916}
1917
1918static int
1919mcdx_getval(struct s_drive_stuff *stuffp, int to, int delay, char *buf)
1920{
1921 unsigned long timeout = to + jiffies;
1922 char c;
1923
1924 if (!buf)
1925 buf = &c;
1926
1927 while (inb(stuffp->rreg_status) & MCDX_RBIT_STEN) {
1928 if (time_after(jiffies, timeout))
1929 return -1;
1930 mcdx_delay(stuffp, delay);
1931 }
1932
1933 *buf = (unsigned char) inb(stuffp->rreg_data) & 0xff;
1934
1935 return 0;
1936}
1937
1938static int mcdx_setattentuator(struct s_drive_stuff *stuffp,
1939 struct cdrom_volctrl *vol, int tries)
1940{
1941 char cmd[5];
1942 cmd[0] = 0xae;
1943 cmd[1] = vol->channel0;
1944 cmd[2] = 0;
1945 cmd[3] = vol->channel1;
1946 cmd[4] = 0;
1947
1948 return mcdx_talk(stuffp, cmd, sizeof(cmd), NULL, 5, 200, tries);
1949}
1950
1951MODULE_LICENSE("GPL");
1952MODULE_ALIAS_BLOCKDEV_MAJOR(MITSUMI_X_CDROM_MAJOR);
diff --git a/drivers/cdrom/mcdx.h b/drivers/cdrom/mcdx.h
new file mode 100644
index 000000000000..83c364a74dc4
--- /dev/null
+++ b/drivers/cdrom/mcdx.h
@@ -0,0 +1,185 @@
1/*
2 * Definitions for the Mitsumi CDROM interface
3 * Copyright (C) 1995 1996 Heiko Schlittermann <heiko@lotte.sax.de>
4 * VERSION: @VERSION@
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; see the file COPYING. If not, write to
18 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 * Thanks to
21 * The Linux Community at all and ...
22 * Martin Harris (he wrote the first Mitsumi Driver)
23 * Eberhard Moenkeberg (he gave me much support and the initial kick)
24 * Bernd Huebner, Ruediger Helsch (Unifix-Software Gmbh, they
25 * improved the original driver)
26 * Jon Tombs, Bjorn Ekwall (module support)
27 * Daniel v. Mosnenck (he sent me the Technical and Programming Reference)
28 * Gerd Knorr (he lent me his PhotoCD)
29 * Nils Faerber and Roger E. Wolff (extensively tested the LU portion)
30 * Andreas Kies (testing the mysterious hang up's)
31 * ... somebody forgotten?
32 * Marcin Dalecki
33 *
34 */
35
36/*
37 * The following lines are for user configuration
38 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
39 *
40 * {0|1} -- 1 if you want the driver detect your drive, may crash and
41 * needs a long time to seek. The higher the address the longer the
42 * seek.
43 *
44 * WARNING: AUTOPROBE doesn't work.
45 */
46#define MCDX_AUTOPROBE 0
47
48/*
49 * Drive specific settings according to the jumpers on the controller
50 * board(s).
51 * o MCDX_NDRIVES : number of used entries of the following table
52 * o MCDX_DRIVEMAP : table of {i/o base, irq} per controller
53 *
54 * NOTE: I didn't get a drive at irq 9(2) working. Not even alone.
55 */
56#if MCDX_AUTOPROBE == 0
57 #define MCDX_NDRIVES 1
58 #define MCDX_DRIVEMAP { \
59 {0x300, 11}, \
60 {0x304, 05}, \
61 {0x000, 00}, \
62 {0x000, 00}, \
63 {0x000, 00}, \
64 }
65#else
66 #error Autoprobing is not implemented yet.
67#endif
68
69#ifndef MCDX_QUIET
70#define MCDX_QUIET 1
71#endif
72
73#ifndef MCDX_DEBUG
74#define MCDX_DEBUG 0
75#endif
76
77/* *** make the following line uncommented, if you're sure,
78 * *** all configuration is done */
79/* #define I_WAS_HERE */
80
81/* The name of the device */
82#define MCDX "mcdx"
83
84/* Flags for DEBUGGING */
85#define INIT 0
86#define MALLOC 0
87#define IOCTL 0
88#define PLAYTRK 0
89#define SUBCHNL 0
90#define TOCHDR 0
91#define MS 0
92#define PLAYMSF 0
93#define READTOC 0
94#define OPENCLOSE 0
95#define HW 0
96#define TALK 0
97#define IRQ 0
98#define XFER 0
99#define REQUEST 0
100#define SLEEP 0
101
102/* The following addresses are taken from the Mitsumi Reference
103 * and describe the possible i/o range for the controller.
104 */
105#define MCDX_IO_BEGIN ((char*) 0x300) /* first base of i/o addr */
106#define MCDX_IO_END ((char*) 0x3fc) /* last base of i/o addr */
107
108/* Per controller 4 bytes i/o are needed. */
109#define MCDX_IO_SIZE 4
110
111/*
112 * Bits
113 */
114
115/* The status byte, returned from every command, set if
116 * the description is true */
117#define MCDX_RBIT_OPEN 0x80 /* door is open */
118#define MCDX_RBIT_DISKSET 0x40 /* disk set (recognised) */
119#define MCDX_RBIT_CHANGED 0x20 /* disk was changed */
120#define MCDX_RBIT_CHECK 0x10 /* disk rotates, servo is on */
121#define MCDX_RBIT_AUDIOTR 0x08 /* current track is audio */
122#define MCDX_RBIT_RDERR 0x04 /* read error, refer SENSE KEY */
123#define MCDX_RBIT_AUDIOBS 0x02 /* currently playing audio */
124#define MCDX_RBIT_CMDERR 0x01 /* command, param or format error */
125
126/* The I/O Register holding the h/w status of the drive,
127 * can be read at i/o base + 1 */
128#define MCDX_RBIT_DOOR 0x10 /* door is open */
129#define MCDX_RBIT_STEN 0x04 /* if 0, i/o base contains drive status */
130#define MCDX_RBIT_DTEN 0x02 /* if 0, i/o base contains data */
131
132/*
133 * The commands.
134 */
135
136#define OPCODE 1 /* offset of opcode */
137#define MCDX_CMD_REQUEST_TOC 1, 0x10
138#define MCDX_CMD_REQUEST_STATUS 1, 0x40
139#define MCDX_CMD_RESET 1, 0x60
140#define MCDX_CMD_REQUEST_DRIVE_MODE 1, 0xc2
141#define MCDX_CMD_SET_INTERLEAVE 2, 0xc8, 0
142#define MCDX_CMD_DATAMODE_SET 2, 0xa0, 0
143 #define MCDX_DATAMODE1 0x01
144 #define MCDX_DATAMODE2 0x02
145#define MCDX_CMD_LOCK_DOOR 2, 0xfe, 0
146
147#define READ_AHEAD 4 /* 8 Sectors (4K) */
148
149/* Useful macros */
150#define e_door(x) ((x) & MCDX_RBIT_OPEN)
151#define e_check(x) (~(x) & MCDX_RBIT_CHECK)
152#define e_notset(x) (~(x) & MCDX_RBIT_DISKSET)
153#define e_changed(x) ((x) & MCDX_RBIT_CHANGED)
154#define e_audio(x) ((x) & MCDX_RBIT_AUDIOTR)
155#define e_audiobusy(x) ((x) & MCDX_RBIT_AUDIOBS)
156#define e_cmderr(x) ((x) & MCDX_RBIT_CMDERR)
157#define e_readerr(x) ((x) & MCDX_RBIT_RDERR)
158
159/** no drive specific */
160#define MCDX_CDBLK 2048 /* 2048 cooked data each blk */
161
162#define MCDX_DATA_TIMEOUT (HZ/10) /* 0.1 second */
163
164/*
165 * Access to the msf array
166 */
167#define MSF_MIN 0 /* minute */
168#define MSF_SEC 1 /* second */
169#define MSF_FRM 2 /* frame */
170
171/*
172 * Errors
173 */
174#define MCDX_E 1 /* unspec error */
175#define MCDX_ST_EOM 0x0100 /* end of media */
176#define MCDX_ST_DRV 0x00ff /* mask to query the drive status */
177
178#ifndef I_WAS_HERE
179#ifndef MODULE
180#warning You have not edited mcdx.h
181#warning Perhaps irq and i/o settings are wrong.
182#endif
183#endif
184
185/* ex:set ts=4 sw=4: */
diff --git a/drivers/cdrom/optcd.c b/drivers/cdrom/optcd.c
new file mode 100644
index 000000000000..7e69c54568bf
--- /dev/null
+++ b/drivers/cdrom/optcd.c
@@ -0,0 +1,2106 @@
1/* linux/drivers/cdrom/optcd.c - Optics Storage 8000 AT CDROM driver
2 $Id: optcd.c,v 1.11 1997/01/26 07:13:00 davem Exp $
3
4 Copyright (C) 1995 Leo Spiekman (spiekman@dutette.et.tudelft.nl)
5
6
7 Based on Aztech CD268 CDROM driver by Werner Zimmermann and preworks
8 by Eberhard Moenkeberg (emoenke@gwdg.de).
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2, or (at your option)
13 any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23*/
24
25/* Revision history
26
27
28 14-5-95 v0.0 Plays sound tracks. No reading of data CDs yet.
29 Detection of disk change doesn't work.
30 21-5-95 v0.1 First ALPHA version. CD can be mounted. The
31 device major nr is borrowed from the Aztech
32 driver. Speed is around 240 kb/s, as measured
33 with "time dd if=/dev/cdrom of=/dev/null \
34 bs=2048 count=4096".
35 24-6-95 v0.2 Reworked the #defines for the command codes
36 and the like, as well as the structure of
37 the hardware communication protocol, to
38 reflect the "official" documentation, kindly
39 supplied by C.K. Tan, Optics Storage Pte. Ltd.
40 Also tidied up the state machine somewhat.
41 28-6-95 v0.3 Removed the ISP-16 interface code, as this
42 should go into its own driver. The driver now
43 has its own major nr.
44 Disk change detection now seems to work, too.
45 This version became part of the standard
46 kernel as of version 1.3.7
47 24-9-95 v0.4 Re-inserted ISP-16 interface code which I
48 copied from sjcd.c, with a few changes.
49 Updated README.optcd. Submitted for
50 inclusion in 1.3.21
51 29-9-95 v0.4a Fixed bug that prevented compilation as module
52 25-10-95 v0.5 Started multisession code. Implementation
53 copied from Werner Zimmermann, who copied it
54 from Heiko Schlittermann's mcdx.
55 17-1-96 v0.6 Multisession works; some cleanup too.
56 18-4-96 v0.7 Increased some timing constants;
57 thanks to Luke McFarlane. Also tidied up some
58 printk behaviour. ISP16 initialization
59 is now handled by a separate driver.
60
61 09-11-99 Make kernel-parameter implementation work with 2.3.x
62 Removed init_module & cleanup_module in favor of
63 module_init & module_exit.
64 Torben Mathiasen <tmm@image.dk>
65*/
66
67/* Includes */
68
69
70#include <linux/module.h>
71#include <linux/mm.h>
72#include <linux/ioport.h>
73#include <linux/init.h>
74
75#include <asm/io.h>
76#include <linux/blkdev.h>
77
78#include <linux/cdrom.h>
79#include "optcd.h"
80
81#include <asm/uaccess.h>
82
83#define MAJOR_NR OPTICS_CDROM_MAJOR
84#define QUEUE (opt_queue)
85#define CURRENT elv_next_request(opt_queue)
86
87
88/* Debug support */
89
90
91/* Don't forget to add new debug flags here. */
92#if DEBUG_DRIVE_IF | DEBUG_VFS | DEBUG_CONV | DEBUG_TOC | \
93 DEBUG_BUFFERS | DEBUG_REQUEST | DEBUG_STATE | DEBUG_MULTIS
94#define DEBUG(x) debug x
95static void debug(int debug_this, const char* fmt, ...)
96{
97 char s[1024];
98 va_list args;
99
100 if (!debug_this)
101 return;
102
103 va_start(args, fmt);
104 vsprintf(s, fmt, args);
105 printk(KERN_DEBUG "optcd: %s\n", s);
106 va_end(args);
107}
108#else
109#define DEBUG(x)
110#endif
111
112
113/* Drive hardware/firmware characteristics
114 Identifiers in accordance with Optics Storage documentation */
115
116
117#define optcd_port optcd /* Needed for the modutils. */
118static short optcd_port = OPTCD_PORTBASE; /* I/O base of drive. */
119module_param(optcd_port, short, 0);
120/* Drive registers, read */
121#define DATA_PORT optcd_port /* Read data/status */
122#define STATUS_PORT optcd_port+1 /* Indicate data/status availability */
123
124/* Drive registers, write */
125#define COMIN_PORT optcd_port /* For passing command/parameter */
126#define RESET_PORT optcd_port+1 /* Write anything and wait 0.5 sec */
127#define HCON_PORT optcd_port+2 /* Host Xfer Configuration */
128
129
130/* Command completion/status read from DATA register */
131#define ST_DRVERR 0x80
132#define ST_DOOR_OPEN 0x40
133#define ST_MIXEDMODE_DISK 0x20
134#define ST_MODE_BITS 0x1c
135#define ST_M_STOP 0x00
136#define ST_M_READ 0x04
137#define ST_M_AUDIO 0x04
138#define ST_M_PAUSE 0x08
139#define ST_M_INITIAL 0x0c
140#define ST_M_ERROR 0x10
141#define ST_M_OTHERS 0x14
142#define ST_MODE2TRACK 0x02
143#define ST_DSK_CHG 0x01
144#define ST_L_LOCK 0x01
145#define ST_CMD_OK 0x00
146#define ST_OP_OK 0x01
147#define ST_PA_OK 0x02
148#define ST_OP_ERROR 0x05
149#define ST_PA_ERROR 0x06
150
151
152/* Error codes (appear as command completion code from DATA register) */
153/* Player related errors */
154#define ERR_ILLCMD 0x11 /* Illegal command to player module */
155#define ERR_ILLPARM 0x12 /* Illegal parameter to player module */
156#define ERR_SLEDGE 0x13
157#define ERR_FOCUS 0x14
158#define ERR_MOTOR 0x15
159#define ERR_RADIAL 0x16
160#define ERR_PLL 0x17 /* PLL lock error */
161#define ERR_SUB_TIM 0x18 /* Subcode timeout error */
162#define ERR_SUB_NF 0x19 /* Subcode not found error */
163#define ERR_TRAY 0x1a
164#define ERR_TOC 0x1b /* Table of Contents read error */
165#define ERR_JUMP 0x1c
166/* Data errors */
167#define ERR_MODE 0x21
168#define ERR_FORM 0x22
169#define ERR_HEADADDR 0x23 /* Header Address not found */
170#define ERR_CRC 0x24
171#define ERR_ECC 0x25 /* Uncorrectable ECC error */
172#define ERR_CRC_UNC 0x26 /* CRC error and uncorrectable error */
173#define ERR_ILLBSYNC 0x27 /* Illegal block sync error */
174#define ERR_VDST 0x28 /* VDST not found */
175/* Timeout errors */
176#define ERR_READ_TIM 0x31 /* Read timeout error */
177#define ERR_DEC_STP 0x32 /* Decoder stopped */
178#define ERR_DEC_TIM 0x33 /* Decoder interrupt timeout error */
179/* Function abort codes */
180#define ERR_KEY 0x41 /* Key -Detected abort */
181#define ERR_READ_FINISH 0x42 /* Read Finish */
182/* Second Byte diagnostic codes */
183#define ERR_NOBSYNC 0x01 /* No block sync */
184#define ERR_SHORTB 0x02 /* Short block */
185#define ERR_LONGB 0x03 /* Long block */
186#define ERR_SHORTDSP 0x04 /* Short DSP word */
187#define ERR_LONGDSP 0x05 /* Long DSP word */
188
189
190/* Status availability flags read from STATUS register */
191#define FL_EJECT 0x20
192#define FL_WAIT 0x10 /* active low */
193#define FL_EOP 0x08 /* active low */
194#define FL_STEN 0x04 /* Status available when low */
195#define FL_DTEN 0x02 /* Data available when low */
196#define FL_DRQ 0x01 /* active low */
197#define FL_RESET 0xde /* These bits are high after a reset */
198#define FL_STDT (FL_STEN|FL_DTEN)
199
200
201/* Transfer mode, written to HCON register */
202#define HCON_DTS 0x08
203#define HCON_SDRQB 0x04
204#define HCON_LOHI 0x02
205#define HCON_DMA16 0x01
206
207
208/* Drive command set, written to COMIN register */
209/* Quick response commands */
210#define COMDRVST 0x20 /* Drive Status Read */
211#define COMERRST 0x21 /* Error Status Read */
212#define COMIOCTLISTAT 0x22 /* Status Read; reset disk changed bit */
213#define COMINITSINGLE 0x28 /* Initialize Single Speed */
214#define COMINITDOUBLE 0x29 /* Initialize Double Speed */
215#define COMUNLOCK 0x30 /* Unlock */
216#define COMLOCK 0x31 /* Lock */
217#define COMLOCKST 0x32 /* Lock/Unlock Status */
218#define COMVERSION 0x40 /* Get Firmware Revision */
219#define COMVOIDREADMODE 0x50 /* Void Data Read Mode */
220/* Read commands */
221#define COMFETCH 0x60 /* Prefetch Data */
222#define COMREAD 0x61 /* Read */
223#define COMREADRAW 0x62 /* Read Raw Data */
224#define COMREADALL 0x63 /* Read All 2646 Bytes */
225/* Player control commands */
226#define COMLEADIN 0x70 /* Seek To Lead-in */
227#define COMSEEK 0x71 /* Seek */
228#define COMPAUSEON 0x80 /* Pause On */
229#define COMPAUSEOFF 0x81 /* Pause Off */
230#define COMSTOP 0x82 /* Stop */
231#define COMOPEN 0x90 /* Open Tray Door */
232#define COMCLOSE 0x91 /* Close Tray Door */
233#define COMPLAY 0xa0 /* Audio Play */
234#define COMPLAY_TNO 0xa2 /* Audio Play By Track Number */
235#define COMSUBQ 0xb0 /* Read Sub-q Code */
236#define COMLOCATION 0xb1 /* Read Head Position */
237/* Audio control commands */
238#define COMCHCTRL 0xc0 /* Audio Channel Control */
239/* Miscellaneous (test) commands */
240#define COMDRVTEST 0xd0 /* Write Test Bytes */
241#define COMTEST 0xd1 /* Diagnostic Test */
242
243/* Low level drive interface. Only here we do actual I/O
244 Waiting for status / data available */
245
246
247/* Busy wait until FLAG goes low. Return 0 on timeout. */
248inline static int flag_low(int flag, unsigned long timeout)
249{
250 int flag_high;
251 unsigned long count = 0;
252
253 while ((flag_high = (inb(STATUS_PORT) & flag)))
254 if (++count >= timeout)
255 break;
256
257 DEBUG((DEBUG_DRIVE_IF, "flag_low 0x%x count %ld%s",
258 flag, count, flag_high ? " timeout" : ""));
259 return !flag_high;
260}
261
262
263/* Timed waiting for status or data */
264static int sleep_timeout; /* max # of ticks to sleep */
265static DECLARE_WAIT_QUEUE_HEAD(waitq);
266static void sleep_timer(unsigned long data);
267static struct timer_list delay_timer = TIMER_INITIALIZER(sleep_timer, 0, 0);
268static DEFINE_SPINLOCK(optcd_lock);
269static struct request_queue *opt_queue;
270
271/* Timer routine: wake up when desired flag goes low,
272 or when timeout expires. */
273static void sleep_timer(unsigned long data)
274{
275 int flags = inb(STATUS_PORT) & FL_STDT;
276
277 if (flags == FL_STDT && --sleep_timeout > 0) {
278 mod_timer(&delay_timer, jiffies + HZ/100); /* multi-statement macro */
279 } else
280 wake_up(&waitq);
281}
282
283
284/* Sleep until FLAG goes low. Return 0 on timeout or wrong flag low. */
285static int sleep_flag_low(int flag, unsigned long timeout)
286{
287 int flag_high;
288
289 DEBUG((DEBUG_DRIVE_IF, "sleep_flag_low"));
290
291 sleep_timeout = timeout;
292 flag_high = inb(STATUS_PORT) & flag;
293 if (flag_high && sleep_timeout > 0) {
294 mod_timer(&delay_timer, jiffies + HZ/100);
295 sleep_on(&waitq);
296 flag_high = inb(STATUS_PORT) & flag;
297 }
298
299 DEBUG((DEBUG_DRIVE_IF, "flag 0x%x count %ld%s",
300 flag, timeout, flag_high ? " timeout" : ""));
301 return !flag_high;
302}
303
304/* Low level drive interface. Only here we do actual I/O
305 Sending commands and parameters */
306
307
308/* Errors in the command protocol */
309#define ERR_IF_CMD_TIMEOUT 0x100
310#define ERR_IF_ERR_TIMEOUT 0x101
311#define ERR_IF_RESP_TIMEOUT 0x102
312#define ERR_IF_DATA_TIMEOUT 0x103
313#define ERR_IF_NOSTAT 0x104
314
315
316/* Send command code. Return <0 indicates error */
317static int send_cmd(int cmd)
318{
319 unsigned char ack;
320
321 DEBUG((DEBUG_DRIVE_IF, "sending command 0x%02x\n", cmd));
322
323 outb(HCON_DTS, HCON_PORT); /* Enable Suspend Data Transfer */
324 outb(cmd, COMIN_PORT); /* Send command code */
325 if (!flag_low(FL_STEN, BUSY_TIMEOUT)) /* Wait for status */
326 return -ERR_IF_CMD_TIMEOUT;
327 ack = inb(DATA_PORT); /* read command acknowledge */
328 outb(HCON_SDRQB, HCON_PORT); /* Disable Suspend Data Transfer */
329 return ack==ST_OP_OK ? 0 : -ack;
330}
331
332
333/* Send command parameters. Return <0 indicates error */
334static int send_params(struct cdrom_msf *params)
335{
336 unsigned char ack;
337
338 DEBUG((DEBUG_DRIVE_IF, "sending parameters"
339 " %02x:%02x:%02x"
340 " %02x:%02x:%02x",
341 params->cdmsf_min0,
342 params->cdmsf_sec0,
343 params->cdmsf_frame0,
344 params->cdmsf_min1,
345 params->cdmsf_sec1,
346 params->cdmsf_frame1));
347
348 outb(params->cdmsf_min0, COMIN_PORT);
349 outb(params->cdmsf_sec0, COMIN_PORT);
350 outb(params->cdmsf_frame0, COMIN_PORT);
351 outb(params->cdmsf_min1, COMIN_PORT);
352 outb(params->cdmsf_sec1, COMIN_PORT);
353 outb(params->cdmsf_frame1, COMIN_PORT);
354 if (!flag_low(FL_STEN, BUSY_TIMEOUT)) /* Wait for status */
355 return -ERR_IF_CMD_TIMEOUT;
356 ack = inb(DATA_PORT); /* read command acknowledge */
357 return ack==ST_PA_OK ? 0 : -ack;
358}
359
360
361/* Send parameters for SEEK command. Return <0 indicates error */
362static int send_seek_params(struct cdrom_msf *params)
363{
364 unsigned char ack;
365
366 DEBUG((DEBUG_DRIVE_IF, "sending seek parameters"
367 " %02x:%02x:%02x",
368 params->cdmsf_min0,
369 params->cdmsf_sec0,
370 params->cdmsf_frame0));
371
372 outb(params->cdmsf_min0, COMIN_PORT);
373 outb(params->cdmsf_sec0, COMIN_PORT);
374 outb(params->cdmsf_frame0, COMIN_PORT);
375 if (!flag_low(FL_STEN, BUSY_TIMEOUT)) /* Wait for status */
376 return -ERR_IF_CMD_TIMEOUT;
377 ack = inb(DATA_PORT); /* read command acknowledge */
378 return ack==ST_PA_OK ? 0 : -ack;
379}
380
381
382/* Wait for command execution status. Choice between busy waiting
383 and sleeping. Return value <0 indicates timeout. */
384inline static int get_exec_status(int busy_waiting)
385{
386 unsigned char exec_status;
387
388 if (busy_waiting
389 ? !flag_low(FL_STEN, BUSY_TIMEOUT)
390 : !sleep_flag_low(FL_STEN, SLEEP_TIMEOUT))
391 return -ERR_IF_CMD_TIMEOUT;
392
393 exec_status = inb(DATA_PORT);
394 DEBUG((DEBUG_DRIVE_IF, "returned exec status 0x%02x", exec_status));
395 return exec_status;
396}
397
398
399/* Wait busy for extra byte of data that a command returns.
400 Return value <0 indicates timeout. */
401inline static int get_data(int short_timeout)
402{
403 unsigned char data;
404
405 if (!flag_low(FL_STEN, short_timeout ? FAST_TIMEOUT : BUSY_TIMEOUT))
406 return -ERR_IF_DATA_TIMEOUT;
407
408 data = inb(DATA_PORT);
409 DEBUG((DEBUG_DRIVE_IF, "returned data 0x%02x", data));
410 return data;
411}
412
413
414/* Returns 0 if failed */
415static int reset_drive(void)
416{
417 unsigned long count = 0;
418 int flags;
419
420 DEBUG((DEBUG_DRIVE_IF, "reset drive"));
421
422 outb(0, RESET_PORT);
423 while (++count < RESET_WAIT)
424 inb(DATA_PORT);
425
426 count = 0;
427 while ((flags = (inb(STATUS_PORT) & FL_RESET)) != FL_RESET)
428 if (++count >= BUSY_TIMEOUT)
429 break;
430
431 DEBUG((DEBUG_DRIVE_IF, "reset %s",
432 flags == FL_RESET ? "succeeded" : "failed"));
433
434 if (flags != FL_RESET)
435 return 0; /* Reset failed */
436 outb(HCON_SDRQB, HCON_PORT); /* Disable Suspend Data Transfer */
437 return 1; /* Reset succeeded */
438}
439
440
441/* Facilities for asynchronous operation */
442
443/* Read status/data availability flags FL_STEN and FL_DTEN */
444inline static int stdt_flags(void)
445{
446 return inb(STATUS_PORT) & FL_STDT;
447}
448
449
450/* Fetch status that has previously been waited for. <0 means not available */
451inline static int fetch_status(void)
452{
453 unsigned char status;
454
455 if (inb(STATUS_PORT) & FL_STEN)
456 return -ERR_IF_NOSTAT;
457
458 status = inb(DATA_PORT);
459 DEBUG((DEBUG_DRIVE_IF, "fetched exec status 0x%02x", status));
460 return status;
461}
462
463
464/* Fetch data that has previously been waited for. */
465inline static void fetch_data(char *buf, int n)
466{
467 insb(DATA_PORT, buf, n);
468 DEBUG((DEBUG_DRIVE_IF, "fetched 0x%x bytes", n));
469}
470
471
472/* Flush status and data fifos */
473inline static void flush_data(void)
474{
475 while ((inb(STATUS_PORT) & FL_STDT) != FL_STDT)
476 inb(DATA_PORT);
477 DEBUG((DEBUG_DRIVE_IF, "flushed fifos"));
478}
479
480/* Command protocol */
481
482
483/* Send a simple command and wait for response. Command codes < COMFETCH
484 are quick response commands */
485inline static int exec_cmd(int cmd)
486{
487 int ack = send_cmd(cmd);
488 if (ack < 0)
489 return ack;
490 return get_exec_status(cmd < COMFETCH);
491}
492
493
494/* Send a command with parameters. Don't wait for the response,
495 * which consists of data blocks read from the CD. */
496inline static int exec_read_cmd(int cmd, struct cdrom_msf *params)
497{
498 int ack = send_cmd(cmd);
499 if (ack < 0)
500 return ack;
501 return send_params(params);
502}
503
504
505/* Send a seek command with parameters and wait for response */
506inline static int exec_seek_cmd(int cmd, struct cdrom_msf *params)
507{
508 int ack = send_cmd(cmd);
509 if (ack < 0)
510 return ack;
511 ack = send_seek_params(params);
512 if (ack < 0)
513 return ack;
514 return 0;
515}
516
517
518/* Send a command with parameters and wait for response */
519inline static int exec_long_cmd(int cmd, struct cdrom_msf *params)
520{
521 int ack = exec_read_cmd(cmd, params);
522 if (ack < 0)
523 return ack;
524 return get_exec_status(0);
525}
526
527/* Address conversion routines */
528
529
530/* Binary to BCD (2 digits) */
531inline static void single_bin2bcd(u_char *p)
532{
533 DEBUG((DEBUG_CONV, "bin2bcd %02d", *p));
534 *p = (*p % 10) | ((*p / 10) << 4);
535}
536
537
538/* Convert entire msf struct */
539static void bin2bcd(struct cdrom_msf *msf)
540{
541 single_bin2bcd(&msf->cdmsf_min0);
542 single_bin2bcd(&msf->cdmsf_sec0);
543 single_bin2bcd(&msf->cdmsf_frame0);
544 single_bin2bcd(&msf->cdmsf_min1);
545 single_bin2bcd(&msf->cdmsf_sec1);
546 single_bin2bcd(&msf->cdmsf_frame1);
547}
548
549
550/* Linear block address to minute, second, frame form */
551#define CD_FPM (CD_SECS * CD_FRAMES) /* frames per minute */
552
553static void lba2msf(int lba, struct cdrom_msf *msf)
554{
555 DEBUG((DEBUG_CONV, "lba2msf %d", lba));
556 lba += CD_MSF_OFFSET;
557 msf->cdmsf_min0 = lba / CD_FPM; lba %= CD_FPM;
558 msf->cdmsf_sec0 = lba / CD_FRAMES;
559 msf->cdmsf_frame0 = lba % CD_FRAMES;
560 msf->cdmsf_min1 = 0;
561 msf->cdmsf_sec1 = 0;
562 msf->cdmsf_frame1 = 0;
563 bin2bcd(msf);
564}
565
566
567/* Two BCD digits to binary */
568inline static u_char bcd2bin(u_char bcd)
569{
570 DEBUG((DEBUG_CONV, "bcd2bin %x%02x", bcd));
571 return (bcd >> 4) * 10 + (bcd & 0x0f);
572}
573
574
575static void msf2lba(union cdrom_addr *addr)
576{
577 addr->lba = addr->msf.minute * CD_FPM
578 + addr->msf.second * CD_FRAMES
579 + addr->msf.frame - CD_MSF_OFFSET;
580}
581
582
583/* Minute, second, frame address BCD to binary or to linear address,
584 depending on MODE */
585static void msf_bcd2bin(union cdrom_addr *addr)
586{
587 addr->msf.minute = bcd2bin(addr->msf.minute);
588 addr->msf.second = bcd2bin(addr->msf.second);
589 addr->msf.frame = bcd2bin(addr->msf.frame);
590}
591
592/* High level drive commands */
593
594
595static int audio_status = CDROM_AUDIO_NO_STATUS;
596static char toc_uptodate = 0;
597static char disk_changed = 1;
598
599/* Get drive status, flagging completion of audio play and disk changes. */
600static int drive_status(void)
601{
602 int status;
603
604 status = exec_cmd(COMIOCTLISTAT);
605 DEBUG((DEBUG_DRIVE_IF, "IOCTLISTAT: %03x", status));
606 if (status < 0)
607 return status;
608 if (status == 0xff) /* No status available */
609 return -ERR_IF_NOSTAT;
610
611 if (((status & ST_MODE_BITS) != ST_M_AUDIO) &&
612 (audio_status == CDROM_AUDIO_PLAY)) {
613 audio_status = CDROM_AUDIO_COMPLETED;
614 }
615
616 if (status & ST_DSK_CHG) {
617 toc_uptodate = 0;
618 disk_changed = 1;
619 audio_status = CDROM_AUDIO_NO_STATUS;
620 }
621
622 return status;
623}
624
625
626/* Read the current Q-channel info. Also used for reading the
627 table of contents. qp->cdsc_format must be set on entry to
628 indicate the desired address format */
629static int get_q_channel(struct cdrom_subchnl *qp)
630{
631 int status, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10;
632
633 status = drive_status();
634 if (status < 0)
635 return status;
636 qp->cdsc_audiostatus = audio_status;
637
638 status = exec_cmd(COMSUBQ);
639 if (status < 0)
640 return status;
641
642 d1 = get_data(0);
643 if (d1 < 0)
644 return d1;
645 qp->cdsc_adr = d1;
646 qp->cdsc_ctrl = d1 >> 4;
647
648 d2 = get_data(0);
649 if (d2 < 0)
650 return d2;
651 qp->cdsc_trk = bcd2bin(d2);
652
653 d3 = get_data(0);
654 if (d3 < 0)
655 return d3;
656 qp->cdsc_ind = bcd2bin(d3);
657
658 d4 = get_data(0);
659 if (d4 < 0)
660 return d4;
661 qp->cdsc_reladdr.msf.minute = d4;
662
663 d5 = get_data(0);
664 if (d5 < 0)
665 return d5;
666 qp->cdsc_reladdr.msf.second = d5;
667
668 d6 = get_data(0);
669 if (d6 < 0)
670 return d6;
671 qp->cdsc_reladdr.msf.frame = d6;
672
673 d7 = get_data(0);
674 if (d7 < 0)
675 return d7;
676 /* byte not used */
677
678 d8 = get_data(0);
679 if (d8 < 0)
680 return d8;
681 qp->cdsc_absaddr.msf.minute = d8;
682
683 d9 = get_data(0);
684 if (d9 < 0)
685 return d9;
686 qp->cdsc_absaddr.msf.second = d9;
687
688 d10 = get_data(0);
689 if (d10 < 0)
690 return d10;
691 qp->cdsc_absaddr.msf.frame = d10;
692
693 DEBUG((DEBUG_TOC, "%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
694 d1, d2, d3, d4, d5, d6, d7, d8, d9, d10));
695
696 msf_bcd2bin(&qp->cdsc_absaddr);
697 msf_bcd2bin(&qp->cdsc_reladdr);
698 if (qp->cdsc_format == CDROM_LBA) {
699 msf2lba(&qp->cdsc_absaddr);
700 msf2lba(&qp->cdsc_reladdr);
701 }
702
703 return 0;
704}
705
706/* Table of contents handling */
707
708
709/* Errors in table of contents */
710#define ERR_TOC_MISSINGINFO 0x120
711#define ERR_TOC_MISSINGENTRY 0x121
712
713
714struct cdrom_disk_info {
715 unsigned char first;
716 unsigned char last;
717 struct cdrom_msf0 disk_length;
718 struct cdrom_msf0 first_track;
719 /* Multisession info: */
720 unsigned char next;
721 struct cdrom_msf0 next_session;
722 struct cdrom_msf0 last_session;
723 unsigned char multi;
724 unsigned char xa;
725 unsigned char audio;
726};
727static struct cdrom_disk_info disk_info;
728
729#define MAX_TRACKS 111
730static struct cdrom_subchnl toc[MAX_TRACKS];
731
732#define QINFO_FIRSTTRACK 100 /* bcd2bin(0xa0) */
733#define QINFO_LASTTRACK 101 /* bcd2bin(0xa1) */
734#define QINFO_DISKLENGTH 102 /* bcd2bin(0xa2) */
735#define QINFO_NEXTSESSION 110 /* bcd2bin(0xb0) */
736
737#define I_FIRSTTRACK 0x01
738#define I_LASTTRACK 0x02
739#define I_DISKLENGTH 0x04
740#define I_NEXTSESSION 0x08
741#define I_ALL (I_FIRSTTRACK | I_LASTTRACK | I_DISKLENGTH)
742
743
744#if DEBUG_TOC
745static void toc_debug_info(int i)
746{
747 printk(KERN_DEBUG "#%3d ctl %1x, adr %1x, track %2d index %3d"
748 " %2d:%02d.%02d %2d:%02d.%02d\n",
749 i, toc[i].cdsc_ctrl, toc[i].cdsc_adr,
750 toc[i].cdsc_trk, toc[i].cdsc_ind,
751 toc[i].cdsc_reladdr.msf.minute,
752 toc[i].cdsc_reladdr.msf.second,
753 toc[i].cdsc_reladdr.msf.frame,
754 toc[i].cdsc_absaddr.msf.minute,
755 toc[i].cdsc_absaddr.msf.second,
756 toc[i].cdsc_absaddr.msf.frame);
757}
758#endif
759
760
761static int read_toc(void)
762{
763 int status, limit, count;
764 unsigned char got_info = 0;
765 struct cdrom_subchnl q_info;
766#if DEBUG_TOC
767 int i;
768#endif
769
770 DEBUG((DEBUG_TOC, "starting read_toc"));
771
772 count = 0;
773 for (limit = 60; limit > 0; limit--) {
774 int index;
775
776 q_info.cdsc_format = CDROM_MSF;
777 status = get_q_channel(&q_info);
778 if (status < 0)
779 return status;
780
781 index = q_info.cdsc_ind;
782 if (index > 0 && index < MAX_TRACKS
783 && q_info.cdsc_trk == 0 && toc[index].cdsc_ind == 0) {
784 toc[index] = q_info;
785 DEBUG((DEBUG_TOC, "got %d", index));
786 if (index < 100)
787 count++;
788
789 switch (q_info.cdsc_ind) {
790 case QINFO_FIRSTTRACK:
791 got_info |= I_FIRSTTRACK;
792 break;
793 case QINFO_LASTTRACK:
794 got_info |= I_LASTTRACK;
795 break;
796 case QINFO_DISKLENGTH:
797 got_info |= I_DISKLENGTH;
798 break;
799 case QINFO_NEXTSESSION:
800 got_info |= I_NEXTSESSION;
801 break;
802 }
803 }
804
805 if ((got_info & I_ALL) == I_ALL
806 && toc[QINFO_FIRSTTRACK].cdsc_absaddr.msf.minute + count
807 >= toc[QINFO_LASTTRACK].cdsc_absaddr.msf.minute + 1)
808 break;
809 }
810
811 /* Construct disk_info from TOC */
812 if (disk_info.first == 0) {
813 disk_info.first = toc[QINFO_FIRSTTRACK].cdsc_absaddr.msf.minute;
814 disk_info.first_track.minute =
815 toc[disk_info.first].cdsc_absaddr.msf.minute;
816 disk_info.first_track.second =
817 toc[disk_info.first].cdsc_absaddr.msf.second;
818 disk_info.first_track.frame =
819 toc[disk_info.first].cdsc_absaddr.msf.frame;
820 }
821 disk_info.last = toc[QINFO_LASTTRACK].cdsc_absaddr.msf.minute;
822 disk_info.disk_length.minute =
823 toc[QINFO_DISKLENGTH].cdsc_absaddr.msf.minute;
824 disk_info.disk_length.second =
825 toc[QINFO_DISKLENGTH].cdsc_absaddr.msf.second-2;
826 disk_info.disk_length.frame =
827 toc[QINFO_DISKLENGTH].cdsc_absaddr.msf.frame;
828 disk_info.next_session.minute =
829 toc[QINFO_NEXTSESSION].cdsc_reladdr.msf.minute;
830 disk_info.next_session.second =
831 toc[QINFO_NEXTSESSION].cdsc_reladdr.msf.second;
832 disk_info.next_session.frame =
833 toc[QINFO_NEXTSESSION].cdsc_reladdr.msf.frame;
834 disk_info.next = toc[QINFO_FIRSTTRACK].cdsc_absaddr.msf.minute;
835 disk_info.last_session.minute =
836 toc[disk_info.next].cdsc_absaddr.msf.minute;
837 disk_info.last_session.second =
838 toc[disk_info.next].cdsc_absaddr.msf.second;
839 disk_info.last_session.frame =
840 toc[disk_info.next].cdsc_absaddr.msf.frame;
841 toc[disk_info.last + 1].cdsc_absaddr.msf.minute =
842 disk_info.disk_length.minute;
843 toc[disk_info.last + 1].cdsc_absaddr.msf.second =
844 disk_info.disk_length.second;
845 toc[disk_info.last + 1].cdsc_absaddr.msf.frame =
846 disk_info.disk_length.frame;
847#if DEBUG_TOC
848 for (i = 1; i <= disk_info.last + 1; i++)
849 toc_debug_info(i);
850 toc_debug_info(QINFO_FIRSTTRACK);
851 toc_debug_info(QINFO_LASTTRACK);
852 toc_debug_info(QINFO_DISKLENGTH);
853 toc_debug_info(QINFO_NEXTSESSION);
854#endif
855
856 DEBUG((DEBUG_TOC, "exiting read_toc, got_info %x, count %d",
857 got_info, count));
858 if ((got_info & I_ALL) != I_ALL
859 || toc[QINFO_FIRSTTRACK].cdsc_absaddr.msf.minute + count
860 < toc[QINFO_LASTTRACK].cdsc_absaddr.msf.minute + 1)
861 return -ERR_TOC_MISSINGINFO;
862 return 0;
863}
864
865
866#ifdef MULTISESSION
867static int get_multi_disk_info(void)
868{
869 int sessions, status;
870 struct cdrom_msf multi_index;
871
872
873 for (sessions = 2; sessions < 10 /* %%for now */; sessions++) {
874 int count;
875
876 for (count = 100; count < MAX_TRACKS; count++)
877 toc[count].cdsc_ind = 0;
878
879 multi_index.cdmsf_min0 = disk_info.next_session.minute;
880 multi_index.cdmsf_sec0 = disk_info.next_session.second;
881 multi_index.cdmsf_frame0 = disk_info.next_session.frame;
882 if (multi_index.cdmsf_sec0 >= 20)
883 multi_index.cdmsf_sec0 -= 20;
884 else {
885 multi_index.cdmsf_sec0 += 40;
886 multi_index.cdmsf_min0--;
887 }
888 DEBUG((DEBUG_MULTIS, "Try %d: %2d:%02d.%02d", sessions,
889 multi_index.cdmsf_min0,
890 multi_index.cdmsf_sec0,
891 multi_index.cdmsf_frame0));
892 bin2bcd(&multi_index);
893 multi_index.cdmsf_min1 = 0;
894 multi_index.cdmsf_sec1 = 0;
895 multi_index.cdmsf_frame1 = 1;
896
897 status = exec_read_cmd(COMREAD, &multi_index);
898 if (status < 0) {
899 DEBUG((DEBUG_TOC, "exec_read_cmd COMREAD: %02x",
900 -status));
901 break;
902 }
903 status = sleep_flag_low(FL_DTEN, MULTI_SEEK_TIMEOUT) ?
904 0 : -ERR_TOC_MISSINGINFO;
905 flush_data();
906 if (status < 0) {
907 DEBUG((DEBUG_TOC, "sleep_flag_low: %02x", -status));
908 break;
909 }
910
911 status = read_toc();
912 if (status < 0) {
913 DEBUG((DEBUG_TOC, "read_toc: %02x", -status));
914 break;
915 }
916
917 disk_info.multi = 1;
918 }
919
920 exec_cmd(COMSTOP);
921
922 if (status < 0)
923 return -EIO;
924 return 0;
925}
926#endif /* MULTISESSION */
927
928
929static int update_toc(void)
930{
931 int status, count;
932
933 if (toc_uptodate)
934 return 0;
935
936 DEBUG((DEBUG_TOC, "starting update_toc"));
937
938 disk_info.first = 0;
939 for (count = 0; count < MAX_TRACKS; count++)
940 toc[count].cdsc_ind = 0;
941
942 status = exec_cmd(COMLEADIN);
943 if (status < 0)
944 return -EIO;
945
946 status = read_toc();
947 if (status < 0) {
948 DEBUG((DEBUG_TOC, "read_toc: %02x", -status));
949 return -EIO;
950 }
951
952 /* Audio disk detection. Look at first track. */
953 disk_info.audio =
954 (toc[disk_info.first].cdsc_ctrl & CDROM_DATA_TRACK) ? 0 : 1;
955
956 /* XA detection */
957 disk_info.xa = drive_status() & ST_MODE2TRACK;
958
959 /* Multisession detection: if we want this, define MULTISESSION */
960 disk_info.multi = 0;
961#ifdef MULTISESSION
962 if (disk_info.xa)
963 get_multi_disk_info(); /* Here disk_info.multi is set */
964#endif /* MULTISESSION */
965 if (disk_info.multi)
966 printk(KERN_WARNING "optcd: Multisession support experimental, "
967 "see Documentation/cdrom/optcd\n");
968
969 DEBUG((DEBUG_TOC, "exiting update_toc"));
970
971 toc_uptodate = 1;
972 return 0;
973}
974
975/* Request handling */
976
977static int current_valid(void)
978{
979 return CURRENT &&
980 CURRENT->cmd == READ &&
981 CURRENT->sector != -1;
982}
983
984/* Buffers for block size conversion. */
985#define NOBUF -1
986
987static char buf[CD_FRAMESIZE * N_BUFS];
988static volatile int buf_bn[N_BUFS], next_bn;
989static volatile int buf_in = 0, buf_out = NOBUF;
990
991inline static void opt_invalidate_buffers(void)
992{
993 int i;
994
995 DEBUG((DEBUG_BUFFERS, "executing opt_invalidate_buffers"));
996
997 for (i = 0; i < N_BUFS; i++)
998 buf_bn[i] = NOBUF;
999 buf_out = NOBUF;
1000}
1001
1002
1003/* Take care of the different block sizes between cdrom and Linux.
1004 When Linux gets variable block sizes this will probably go away. */
1005static void transfer(void)
1006{
1007#if DEBUG_BUFFERS | DEBUG_REQUEST
1008 printk(KERN_DEBUG "optcd: executing transfer\n");
1009#endif
1010
1011 if (!current_valid())
1012 return;
1013 while (CURRENT -> nr_sectors) {
1014 int bn = CURRENT -> sector / 4;
1015 int i, offs, nr_sectors;
1016 for (i = 0; i < N_BUFS && buf_bn[i] != bn; ++i);
1017
1018 DEBUG((DEBUG_REQUEST, "found %d", i));
1019
1020 if (i >= N_BUFS) {
1021 buf_out = NOBUF;
1022 break;
1023 }
1024
1025 offs = (i * 4 + (CURRENT -> sector & 3)) * 512;
1026 nr_sectors = 4 - (CURRENT -> sector & 3);
1027
1028 if (buf_out != i) {
1029 buf_out = i;
1030 if (buf_bn[i] != bn) {
1031 buf_out = NOBUF;
1032 continue;
1033 }
1034 }
1035
1036 if (nr_sectors > CURRENT -> nr_sectors)
1037 nr_sectors = CURRENT -> nr_sectors;
1038 memcpy(CURRENT -> buffer, buf + offs, nr_sectors * 512);
1039 CURRENT -> nr_sectors -= nr_sectors;
1040 CURRENT -> sector += nr_sectors;
1041 CURRENT -> buffer += nr_sectors * 512;
1042 }
1043}
1044
1045
1046/* State machine for reading disk blocks */
1047
1048enum state_e {
1049 S_IDLE, /* 0 */
1050 S_START, /* 1 */
1051 S_READ, /* 2 */
1052 S_DATA, /* 3 */
1053 S_STOP, /* 4 */
1054 S_STOPPING /* 5 */
1055};
1056
1057static volatile enum state_e state = S_IDLE;
1058#if DEBUG_STATE
1059static volatile enum state_e state_old = S_STOP;
1060static volatile int flags_old = 0;
1061static volatile long state_n = 0;
1062#endif
1063
1064
1065/* Used as mutex to keep do_optcd_request (and other processes calling
1066 ioctl) out while some process is inside a VFS call.
1067 Reverse is accomplished by checking if state = S_IDLE upon entry
1068 of opt_ioctl and opt_media_change. */
1069static int in_vfs = 0;
1070
1071
1072static volatile int transfer_is_active = 0;
1073static volatile int error = 0; /* %% do something with this?? */
1074static int tries; /* ibid?? */
1075static int timeout = 0;
1076
1077static void poll(unsigned long data);
1078static struct timer_list req_timer = {.function = poll};
1079
1080
1081static void poll(unsigned long data)
1082{
1083 static volatile int read_count = 1;
1084 int flags;
1085 int loop_again = 1;
1086 int status = 0;
1087 int skip = 0;
1088
1089 if (error) {
1090 printk(KERN_ERR "optcd: I/O error 0x%02x\n", error);
1091 opt_invalidate_buffers();
1092 if (!tries--) {
1093 printk(KERN_ERR "optcd: read block %d failed;"
1094 " Giving up\n", next_bn);
1095 if (transfer_is_active)
1096 loop_again = 0;
1097 if (current_valid())
1098 end_request(CURRENT, 0);
1099 tries = 5;
1100 }
1101 error = 0;
1102 state = S_STOP;
1103 }
1104
1105 while (loop_again)
1106 {
1107 loop_again = 0; /* each case must flip this back to 1 if we want
1108 to come back up here */
1109
1110#if DEBUG_STATE
1111 if (state == state_old)
1112 state_n++;
1113 else {
1114 state_old = state;
1115 if (++state_n > 1)
1116 printk(KERN_DEBUG "optcd: %ld times "
1117 "in previous state\n", state_n);
1118 printk(KERN_DEBUG "optcd: state %d\n", state);
1119 state_n = 0;
1120 }
1121#endif
1122
1123 switch (state) {
1124 case S_IDLE:
1125 return;
1126 case S_START:
1127 if (in_vfs)
1128 break;
1129 if (send_cmd(COMDRVST)) {
1130 state = S_IDLE;
1131 while (current_valid())
1132 end_request(CURRENT, 0);
1133 return;
1134 }
1135 state = S_READ;
1136 timeout = READ_TIMEOUT;
1137 break;
1138 case S_READ: {
1139 struct cdrom_msf msf;
1140 if (!skip) {
1141 status = fetch_status();
1142 if (status < 0)
1143 break;
1144 if (status & ST_DSK_CHG) {
1145 toc_uptodate = 0;
1146 opt_invalidate_buffers();
1147 }
1148 }
1149 skip = 0;
1150 if ((status & ST_DOOR_OPEN) || (status & ST_DRVERR)) {
1151 toc_uptodate = 0;
1152 opt_invalidate_buffers();
1153 printk(KERN_WARNING "optcd: %s\n",
1154 (status & ST_DOOR_OPEN)
1155 ? "door open"
1156 : "disk removed");
1157 state = S_IDLE;
1158 while (current_valid())
1159 end_request(CURRENT, 0);
1160 return;
1161 }
1162 if (!current_valid()) {
1163 state = S_STOP;
1164 loop_again = 1;
1165 break;
1166 }
1167 next_bn = CURRENT -> sector / 4;
1168 lba2msf(next_bn, &msf);
1169 read_count = N_BUFS;
1170 msf.cdmsf_frame1 = read_count; /* Not BCD! */
1171
1172 DEBUG((DEBUG_REQUEST, "reading %x:%x.%x %x:%x.%x",
1173 msf.cdmsf_min0,
1174 msf.cdmsf_sec0,
1175 msf.cdmsf_frame0,
1176 msf.cdmsf_min1,
1177 msf.cdmsf_sec1,
1178 msf.cdmsf_frame1));
1179 DEBUG((DEBUG_REQUEST, "next_bn:%d buf_in:%d"
1180 " buf_out:%d buf_bn:%d",
1181 next_bn,
1182 buf_in,
1183 buf_out,
1184 buf_bn[buf_in]));
1185
1186 exec_read_cmd(COMREAD, &msf);
1187 state = S_DATA;
1188 timeout = READ_TIMEOUT;
1189 break;
1190 }
1191 case S_DATA:
1192 flags = stdt_flags() & (FL_STEN|FL_DTEN);
1193
1194#if DEBUG_STATE
1195 if (flags != flags_old) {
1196 flags_old = flags;
1197 printk(KERN_DEBUG "optcd: flags:%x\n", flags);
1198 }
1199 if (flags == FL_STEN)
1200 printk(KERN_DEBUG "timeout cnt: %d\n", timeout);
1201#endif
1202
1203 switch (flags) {
1204 case FL_DTEN: /* only STEN low */
1205 if (!tries--) {
1206 printk(KERN_ERR
1207 "optcd: read block %d failed; "
1208 "Giving up\n", next_bn);
1209 if (transfer_is_active) {
1210 tries = 0;
1211 break;
1212 }
1213 if (current_valid())
1214 end_request(CURRENT, 0);
1215 tries = 5;
1216 }
1217 state = S_START;
1218 timeout = READ_TIMEOUT;
1219 loop_again = 1;
1220 case (FL_STEN|FL_DTEN): /* both high */
1221 break;
1222 default: /* DTEN low */
1223 tries = 5;
1224 if (!current_valid() && buf_in == buf_out) {
1225 state = S_STOP;
1226 loop_again = 1;
1227 break;
1228 }
1229 if (read_count<=0)
1230 printk(KERN_WARNING
1231 "optcd: warning - try to read"
1232 " 0 frames\n");
1233 while (read_count) {
1234 buf_bn[buf_in] = NOBUF;
1235 if (!flag_low(FL_DTEN, BUSY_TIMEOUT)) {
1236 /* should be no waiting here!?? */
1237 printk(KERN_ERR
1238 "read_count:%d "
1239 "CURRENT->nr_sectors:%ld "
1240 "buf_in:%d\n",
1241 read_count,
1242 CURRENT->nr_sectors,
1243 buf_in);
1244 printk(KERN_ERR
1245 "transfer active: %x\n",
1246 transfer_is_active);
1247 read_count = 0;
1248 state = S_STOP;
1249 loop_again = 1;
1250 end_request(CURRENT, 0);
1251 break;
1252 }
1253 fetch_data(buf+
1254 CD_FRAMESIZE*buf_in,
1255 CD_FRAMESIZE);
1256 read_count--;
1257
1258 DEBUG((DEBUG_REQUEST,
1259 "S_DATA; ---I've read data- "
1260 "read_count: %d",
1261 read_count));
1262 DEBUG((DEBUG_REQUEST,
1263 "next_bn:%d buf_in:%d "
1264 "buf_out:%d buf_bn:%d",
1265 next_bn,
1266 buf_in,
1267 buf_out,
1268 buf_bn[buf_in]));
1269
1270 buf_bn[buf_in] = next_bn++;
1271 if (buf_out == NOBUF)
1272 buf_out = buf_in;
1273 buf_in = buf_in + 1 ==
1274 N_BUFS ? 0 : buf_in + 1;
1275 }
1276 if (!transfer_is_active) {
1277 while (current_valid()) {
1278 transfer();
1279 if (CURRENT -> nr_sectors == 0)
1280 end_request(CURRENT, 1);
1281 else
1282 break;
1283 }
1284 }
1285
1286 if (current_valid()
1287 && (CURRENT -> sector / 4 < next_bn ||
1288 CURRENT -> sector / 4 >
1289 next_bn + N_BUFS)) {
1290 state = S_STOP;
1291 loop_again = 1;
1292 break;
1293 }
1294 timeout = READ_TIMEOUT;
1295 if (read_count == 0) {
1296 state = S_STOP;
1297 loop_again = 1;
1298 break;
1299 }
1300 }
1301 break;
1302 case S_STOP:
1303 if (read_count != 0)
1304 printk(KERN_ERR
1305 "optcd: discard data=%x frames\n",
1306 read_count);
1307 flush_data();
1308 if (send_cmd(COMDRVST)) {
1309 state = S_IDLE;
1310 while (current_valid())
1311 end_request(CURRENT, 0);
1312 return;
1313 }
1314 state = S_STOPPING;
1315 timeout = STOP_TIMEOUT;
1316 break;
1317 case S_STOPPING:
1318 status = fetch_status();
1319 if (status < 0 && timeout)
1320 break;
1321 if ((status >= 0) && (status & ST_DSK_CHG)) {
1322 toc_uptodate = 0;
1323 opt_invalidate_buffers();
1324 }
1325 if (current_valid()) {
1326 if (status >= 0) {
1327 state = S_READ;
1328 loop_again = 1;
1329 skip = 1;
1330 break;
1331 } else {
1332 state = S_START;
1333 timeout = 1;
1334 }
1335 } else {
1336 state = S_IDLE;
1337 return;
1338 }
1339 break;
1340 default:
1341 printk(KERN_ERR "optcd: invalid state %d\n", state);
1342 return;
1343 } /* case */
1344 } /* while */
1345
1346 if (!timeout--) {
1347 printk(KERN_ERR "optcd: timeout in state %d\n", state);
1348 state = S_STOP;
1349 if (exec_cmd(COMSTOP) < 0) {
1350 state = S_IDLE;
1351 while (current_valid())
1352 end_request(CURRENT, 0);
1353 return;
1354 }
1355 }
1356
1357 mod_timer(&req_timer, jiffies + HZ/100);
1358}
1359
1360
1361static void do_optcd_request(request_queue_t * q)
1362{
1363 DEBUG((DEBUG_REQUEST, "do_optcd_request(%ld+%ld)",
1364 CURRENT -> sector, CURRENT -> nr_sectors));
1365
1366 if (disk_info.audio) {
1367 printk(KERN_WARNING "optcd: tried to mount an Audio CD\n");
1368 end_request(CURRENT, 0);
1369 return;
1370 }
1371
1372 transfer_is_active = 1;
1373 while (current_valid()) {
1374 transfer(); /* First try to transfer block from buffers */
1375 if (CURRENT -> nr_sectors == 0) {
1376 end_request(CURRENT, 1);
1377 } else { /* Want to read a block not in buffer */
1378 buf_out = NOBUF;
1379 if (state == S_IDLE) {
1380 /* %% Should this block the request queue?? */
1381 if (update_toc() < 0) {
1382 while (current_valid())
1383 end_request(CURRENT, 0);
1384 break;
1385 }
1386 /* Start state machine */
1387 state = S_START;
1388 timeout = READ_TIMEOUT;
1389 tries = 5;
1390 /* %% why not start right away?? */
1391 mod_timer(&req_timer, jiffies + HZ/100);
1392 }
1393 break;
1394 }
1395 }
1396 transfer_is_active = 0;
1397
1398 DEBUG((DEBUG_REQUEST, "next_bn:%d buf_in:%d buf_out:%d buf_bn:%d",
1399 next_bn, buf_in, buf_out, buf_bn[buf_in]));
1400 DEBUG((DEBUG_REQUEST, "do_optcd_request ends"));
1401}
1402
1403/* IOCTLs */
1404
1405
1406static char auto_eject = 0;
1407
1408static int cdrompause(void)
1409{
1410 int status;
1411
1412 if (audio_status != CDROM_AUDIO_PLAY)
1413 return -EINVAL;
1414
1415 status = exec_cmd(COMPAUSEON);
1416 if (status < 0) {
1417 DEBUG((DEBUG_VFS, "exec_cmd COMPAUSEON: %02x", -status));
1418 return -EIO;
1419 }
1420 audio_status = CDROM_AUDIO_PAUSED;
1421 return 0;
1422}
1423
1424
1425static int cdromresume(void)
1426{
1427 int status;
1428
1429 if (audio_status != CDROM_AUDIO_PAUSED)
1430 return -EINVAL;
1431
1432 status = exec_cmd(COMPAUSEOFF);
1433 if (status < 0) {
1434 DEBUG((DEBUG_VFS, "exec_cmd COMPAUSEOFF: %02x", -status));
1435 audio_status = CDROM_AUDIO_ERROR;
1436 return -EIO;
1437 }
1438 audio_status = CDROM_AUDIO_PLAY;
1439 return 0;
1440}
1441
1442
1443static int cdromplaymsf(void __user *arg)
1444{
1445 int status;
1446 struct cdrom_msf msf;
1447
1448 if (copy_from_user(&msf, arg, sizeof msf))
1449 return -EFAULT;
1450
1451 bin2bcd(&msf);
1452 status = exec_long_cmd(COMPLAY, &msf);
1453 if (status < 0) {
1454 DEBUG((DEBUG_VFS, "exec_long_cmd COMPLAY: %02x", -status));
1455 audio_status = CDROM_AUDIO_ERROR;
1456 return -EIO;
1457 }
1458
1459 audio_status = CDROM_AUDIO_PLAY;
1460 return 0;
1461}
1462
1463
1464static int cdromplaytrkind(void __user *arg)
1465{
1466 int status;
1467 struct cdrom_ti ti;
1468 struct cdrom_msf msf;
1469
1470 if (copy_from_user(&ti, arg, sizeof ti))
1471 return -EFAULT;
1472
1473 if (ti.cdti_trk0 < disk_info.first
1474 || ti.cdti_trk0 > disk_info.last
1475 || ti.cdti_trk1 < ti.cdti_trk0)
1476 return -EINVAL;
1477 if (ti.cdti_trk1 > disk_info.last)
1478 ti.cdti_trk1 = disk_info.last;
1479
1480 msf.cdmsf_min0 = toc[ti.cdti_trk0].cdsc_absaddr.msf.minute;
1481 msf.cdmsf_sec0 = toc[ti.cdti_trk0].cdsc_absaddr.msf.second;
1482 msf.cdmsf_frame0 = toc[ti.cdti_trk0].cdsc_absaddr.msf.frame;
1483 msf.cdmsf_min1 = toc[ti.cdti_trk1 + 1].cdsc_absaddr.msf.minute;
1484 msf.cdmsf_sec1 = toc[ti.cdti_trk1 + 1].cdsc_absaddr.msf.second;
1485 msf.cdmsf_frame1 = toc[ti.cdti_trk1 + 1].cdsc_absaddr.msf.frame;
1486
1487 DEBUG((DEBUG_VFS, "play %02d:%02d.%02d to %02d:%02d.%02d",
1488 msf.cdmsf_min0,
1489 msf.cdmsf_sec0,
1490 msf.cdmsf_frame0,
1491 msf.cdmsf_min1,
1492 msf.cdmsf_sec1,
1493 msf.cdmsf_frame1));
1494
1495 bin2bcd(&msf);
1496 status = exec_long_cmd(COMPLAY, &msf);
1497 if (status < 0) {
1498 DEBUG((DEBUG_VFS, "exec_long_cmd COMPLAY: %02x", -status));
1499 audio_status = CDROM_AUDIO_ERROR;
1500 return -EIO;
1501 }
1502
1503 audio_status = CDROM_AUDIO_PLAY;
1504 return 0;
1505}
1506
1507
1508static int cdromreadtochdr(void __user *arg)
1509{
1510 struct cdrom_tochdr tochdr;
1511
1512 tochdr.cdth_trk0 = disk_info.first;
1513 tochdr.cdth_trk1 = disk_info.last;
1514
1515 return copy_to_user(arg, &tochdr, sizeof tochdr) ? -EFAULT : 0;
1516}
1517
1518
1519static int cdromreadtocentry(void __user *arg)
1520{
1521 struct cdrom_tocentry entry;
1522 struct cdrom_subchnl *tocptr;
1523
1524 if (copy_from_user(&entry, arg, sizeof entry))
1525 return -EFAULT;
1526
1527 if (entry.cdte_track == CDROM_LEADOUT)
1528 tocptr = &toc[disk_info.last + 1];
1529 else if (entry.cdte_track > disk_info.last
1530 || entry.cdte_track < disk_info.first)
1531 return -EINVAL;
1532 else
1533 tocptr = &toc[entry.cdte_track];
1534
1535 entry.cdte_adr = tocptr->cdsc_adr;
1536 entry.cdte_ctrl = tocptr->cdsc_ctrl;
1537 entry.cdte_addr.msf.minute = tocptr->cdsc_absaddr.msf.minute;
1538 entry.cdte_addr.msf.second = tocptr->cdsc_absaddr.msf.second;
1539 entry.cdte_addr.msf.frame = tocptr->cdsc_absaddr.msf.frame;
1540 /* %% What should go into entry.cdte_datamode? */
1541
1542 if (entry.cdte_format == CDROM_LBA)
1543 msf2lba(&entry.cdte_addr);
1544 else if (entry.cdte_format != CDROM_MSF)
1545 return -EINVAL;
1546
1547 return copy_to_user(arg, &entry, sizeof entry) ? -EFAULT : 0;
1548}
1549
1550
1551static int cdromvolctrl(void __user *arg)
1552{
1553 int status;
1554 struct cdrom_volctrl volctrl;
1555 struct cdrom_msf msf;
1556
1557 if (copy_from_user(&volctrl, arg, sizeof volctrl))
1558 return -EFAULT;
1559
1560 msf.cdmsf_min0 = 0x10;
1561 msf.cdmsf_sec0 = 0x32;
1562 msf.cdmsf_frame0 = volctrl.channel0;
1563 msf.cdmsf_min1 = volctrl.channel1;
1564 msf.cdmsf_sec1 = volctrl.channel2;
1565 msf.cdmsf_frame1 = volctrl.channel3;
1566
1567 status = exec_long_cmd(COMCHCTRL, &msf);
1568 if (status < 0) {
1569 DEBUG((DEBUG_VFS, "exec_long_cmd COMCHCTRL: %02x", -status));
1570 return -EIO;
1571 }
1572 return 0;
1573}
1574
1575
1576static int cdromsubchnl(void __user *arg)
1577{
1578 int status;
1579 struct cdrom_subchnl subchnl;
1580
1581 if (copy_from_user(&subchnl, arg, sizeof subchnl))
1582 return -EFAULT;
1583
1584 if (subchnl.cdsc_format != CDROM_LBA
1585 && subchnl.cdsc_format != CDROM_MSF)
1586 return -EINVAL;
1587
1588 status = get_q_channel(&subchnl);
1589 if (status < 0) {
1590 DEBUG((DEBUG_VFS, "get_q_channel: %02x", -status));
1591 return -EIO;
1592 }
1593
1594 if (copy_to_user(arg, &subchnl, sizeof subchnl))
1595 return -EFAULT;
1596 return 0;
1597}
1598
1599
1600static struct gendisk *optcd_disk;
1601
1602
1603static int cdromread(void __user *arg, int blocksize, int cmd)
1604{
1605 int status;
1606 struct cdrom_msf msf;
1607
1608 if (copy_from_user(&msf, arg, sizeof msf))
1609 return -EFAULT;
1610
1611 bin2bcd(&msf);
1612 msf.cdmsf_min1 = 0;
1613 msf.cdmsf_sec1 = 0;
1614 msf.cdmsf_frame1 = 1; /* read only one frame */
1615 status = exec_read_cmd(cmd, &msf);
1616
1617 DEBUG((DEBUG_VFS, "read cmd status 0x%x", status));
1618
1619 if (!sleep_flag_low(FL_DTEN, SLEEP_TIMEOUT))
1620 return -EIO;
1621
1622 fetch_data(optcd_disk->private_data, blocksize);
1623
1624 if (copy_to_user(arg, optcd_disk->private_data, blocksize))
1625 return -EFAULT;
1626
1627 return 0;
1628}
1629
1630
1631static int cdromseek(void __user *arg)
1632{
1633 int status;
1634 struct cdrom_msf msf;
1635
1636 if (copy_from_user(&msf, arg, sizeof msf))
1637 return -EFAULT;
1638
1639 bin2bcd(&msf);
1640 status = exec_seek_cmd(COMSEEK, &msf);
1641
1642 DEBUG((DEBUG_VFS, "COMSEEK status 0x%x", status));
1643
1644 if (status < 0)
1645 return -EIO;
1646 return 0;
1647}
1648
1649
1650#ifdef MULTISESSION
1651static int cdrommultisession(void __user *arg)
1652{
1653 struct cdrom_multisession ms;
1654
1655 if (copy_from_user(&ms, arg, sizeof ms))
1656 return -EFAULT;
1657
1658 ms.addr.msf.minute = disk_info.last_session.minute;
1659 ms.addr.msf.second = disk_info.last_session.second;
1660 ms.addr.msf.frame = disk_info.last_session.frame;
1661
1662 if (ms.addr_format != CDROM_LBA
1663 && ms.addr_format != CDROM_MSF)
1664 return -EINVAL;
1665 if (ms.addr_format == CDROM_LBA)
1666 msf2lba(&ms.addr);
1667
1668 ms.xa_flag = disk_info.xa;
1669
1670 if (copy_to_user(arg, &ms, sizeof(struct cdrom_multisession)))
1671 return -EFAULT;
1672
1673#if DEBUG_MULTIS
1674 if (ms.addr_format == CDROM_MSF)
1675 printk(KERN_DEBUG
1676 "optcd: multisession xa:%d, msf:%02d:%02d.%02d\n",
1677 ms.xa_flag,
1678 ms.addr.msf.minute,
1679 ms.addr.msf.second,
1680 ms.addr.msf.frame);
1681 else
1682 printk(KERN_DEBUG
1683 "optcd: multisession %d, lba:0x%08x [%02d:%02d.%02d])\n",
1684 ms.xa_flag,
1685 ms.addr.lba,
1686 disk_info.last_session.minute,
1687 disk_info.last_session.second,
1688 disk_info.last_session.frame);
1689#endif /* DEBUG_MULTIS */
1690
1691 return 0;
1692}
1693#endif /* MULTISESSION */
1694
1695
1696static int cdromreset(void)
1697{
1698 if (state != S_IDLE) {
1699 error = 1;
1700 tries = 0;
1701 }
1702
1703 toc_uptodate = 0;
1704 disk_changed = 1;
1705 opt_invalidate_buffers();
1706 audio_status = CDROM_AUDIO_NO_STATUS;
1707
1708 if (!reset_drive())
1709 return -EIO;
1710 return 0;
1711}
1712
1713/* VFS calls */
1714
1715
1716static int opt_ioctl(struct inode *ip, struct file *fp,
1717 unsigned int cmd, unsigned long arg)
1718{
1719 int status, err, retval = 0;
1720 void __user *argp = (void __user *)arg;
1721
1722 DEBUG((DEBUG_VFS, "starting opt_ioctl"));
1723
1724 if (!ip)
1725 return -EINVAL;
1726
1727 if (cmd == CDROMRESET)
1728 return cdromreset();
1729
1730 /* is do_optcd_request or another ioctl busy? */
1731 if (state != S_IDLE || in_vfs)
1732 return -EBUSY;
1733
1734 in_vfs = 1;
1735
1736 status = drive_status();
1737 if (status < 0) {
1738 DEBUG((DEBUG_VFS, "drive_status: %02x", -status));
1739 in_vfs = 0;
1740 return -EIO;
1741 }
1742
1743 if (status & ST_DOOR_OPEN)
1744 switch (cmd) { /* Actions that can be taken with door open */
1745 case CDROMCLOSETRAY:
1746 /* We do this before trying to read the toc. */
1747 err = exec_cmd(COMCLOSE);
1748 if (err < 0) {
1749 DEBUG((DEBUG_VFS,
1750 "exec_cmd COMCLOSE: %02x", -err));
1751 in_vfs = 0;
1752 return -EIO;
1753 }
1754 break;
1755 default: in_vfs = 0;
1756 return -EBUSY;
1757 }
1758
1759 err = update_toc();
1760 if (err < 0) {
1761 DEBUG((DEBUG_VFS, "update_toc: %02x", -err));
1762 in_vfs = 0;
1763 return -EIO;
1764 }
1765
1766 DEBUG((DEBUG_VFS, "ioctl cmd 0x%x", cmd));
1767
1768 switch (cmd) {
1769 case CDROMPAUSE: retval = cdrompause(); break;
1770 case CDROMRESUME: retval = cdromresume(); break;
1771 case CDROMPLAYMSF: retval = cdromplaymsf(argp); break;
1772 case CDROMPLAYTRKIND: retval = cdromplaytrkind(argp); break;
1773 case CDROMREADTOCHDR: retval = cdromreadtochdr(argp); break;
1774 case CDROMREADTOCENTRY: retval = cdromreadtocentry(argp); break;
1775
1776 case CDROMSTOP: err = exec_cmd(COMSTOP);
1777 if (err < 0) {
1778 DEBUG((DEBUG_VFS,
1779 "exec_cmd COMSTOP: %02x",
1780 -err));
1781 retval = -EIO;
1782 } else
1783 audio_status = CDROM_AUDIO_NO_STATUS;
1784 break;
1785 case CDROMSTART: break; /* This is a no-op */
1786 case CDROMEJECT: err = exec_cmd(COMUNLOCK);
1787 if (err < 0) {
1788 DEBUG((DEBUG_VFS,
1789 "exec_cmd COMUNLOCK: %02x",
1790 -err));
1791 retval = -EIO;
1792 break;
1793 }
1794 err = exec_cmd(COMOPEN);
1795 if (err < 0) {
1796 DEBUG((DEBUG_VFS,
1797 "exec_cmd COMOPEN: %02x",
1798 -err));
1799 retval = -EIO;
1800 }
1801 break;
1802
1803 case CDROMVOLCTRL: retval = cdromvolctrl(argp); break;
1804 case CDROMSUBCHNL: retval = cdromsubchnl(argp); break;
1805
1806 /* The drive detects the mode and automatically delivers the
1807 correct 2048 bytes, so we don't need these IOCTLs */
1808 case CDROMREADMODE2: retval = -EINVAL; break;
1809 case CDROMREADMODE1: retval = -EINVAL; break;
1810
1811 /* Drive doesn't support reading audio */
1812 case CDROMREADAUDIO: retval = -EINVAL; break;
1813
1814 case CDROMEJECT_SW: auto_eject = (char) arg;
1815 break;
1816
1817#ifdef MULTISESSION
1818 case CDROMMULTISESSION: retval = cdrommultisession(argp); break;
1819#endif
1820
1821 case CDROM_GET_MCN: retval = -EINVAL; break; /* not implemented */
1822 case CDROMVOLREAD: retval = -EINVAL; break; /* not implemented */
1823
1824 case CDROMREADRAW:
1825 /* this drive delivers 2340 bytes in raw mode */
1826 retval = cdromread(argp, CD_FRAMESIZE_RAW1, COMREADRAW);
1827 break;
1828 case CDROMREADCOOKED:
1829 retval = cdromread(argp, CD_FRAMESIZE, COMREAD);
1830 break;
1831 case CDROMREADALL:
1832 retval = cdromread(argp, CD_FRAMESIZE_RAWER, COMREADALL);
1833 break;
1834
1835 case CDROMSEEK: retval = cdromseek(argp); break;
1836 case CDROMPLAYBLK: retval = -EINVAL; break; /* not implemented */
1837 case CDROMCLOSETRAY: break; /* The action was taken earlier */
1838 default: retval = -EINVAL;
1839 }
1840 in_vfs = 0;
1841 return retval;
1842}
1843
1844
1845static int open_count = 0;
1846
1847/* Open device special file; check that a disk is in. */
1848static int opt_open(struct inode *ip, struct file *fp)
1849{
1850 DEBUG((DEBUG_VFS, "starting opt_open"));
1851
1852 if (!open_count && state == S_IDLE) {
1853 int status;
1854 char *buf;
1855
1856 buf = kmalloc(CD_FRAMESIZE_RAWER, GFP_KERNEL);
1857 if (!buf) {
1858 printk(KERN_INFO "optcd: cannot allocate read buffer\n");
1859 return -ENOMEM;
1860 }
1861 optcd_disk->private_data = buf; /* save read buffer */
1862
1863 toc_uptodate = 0;
1864 opt_invalidate_buffers();
1865
1866 status = exec_cmd(COMCLOSE); /* close door */
1867 if (status < 0) {
1868 DEBUG((DEBUG_VFS, "exec_cmd COMCLOSE: %02x", -status));
1869 }
1870
1871 status = drive_status();
1872 if (status < 0) {
1873 DEBUG((DEBUG_VFS, "drive_status: %02x", -status));
1874 goto err_out;
1875 }
1876 DEBUG((DEBUG_VFS, "status: %02x", status));
1877 if ((status & ST_DOOR_OPEN) || (status & ST_DRVERR)) {
1878 printk(KERN_INFO "optcd: no disk or door open\n");
1879 goto err_out;
1880 }
1881 status = exec_cmd(COMLOCK); /* Lock door */
1882 if (status < 0) {
1883 DEBUG((DEBUG_VFS, "exec_cmd COMLOCK: %02x", -status));
1884 }
1885 status = update_toc(); /* Read table of contents */
1886 if (status < 0) {
1887 DEBUG((DEBUG_VFS, "update_toc: %02x", -status));
1888 status = exec_cmd(COMUNLOCK); /* Unlock door */
1889 if (status < 0) {
1890 DEBUG((DEBUG_VFS,
1891 "exec_cmd COMUNLOCK: %02x", -status));
1892 }
1893 goto err_out;
1894 }
1895 open_count++;
1896 }
1897
1898 DEBUG((DEBUG_VFS, "exiting opt_open"));
1899
1900 return 0;
1901
1902err_out:
1903 return -EIO;
1904}
1905
1906
1907/* Release device special file; flush all blocks from the buffer cache */
1908static int opt_release(struct inode *ip, struct file *fp)
1909{
1910 int status;
1911
1912 DEBUG((DEBUG_VFS, "executing opt_release"));
1913 DEBUG((DEBUG_VFS, "inode: %p, device: %s, file: %p\n",
1914 ip, ip->i_bdev->bd_disk->disk_name, fp));
1915
1916 if (!--open_count) {
1917 toc_uptodate = 0;
1918 opt_invalidate_buffers();
1919 status = exec_cmd(COMUNLOCK); /* Unlock door */
1920 if (status < 0) {
1921 DEBUG((DEBUG_VFS, "exec_cmd COMUNLOCK: %02x", -status));
1922 }
1923 if (auto_eject) {
1924 status = exec_cmd(COMOPEN);
1925 DEBUG((DEBUG_VFS, "exec_cmd COMOPEN: %02x", -status));
1926 }
1927 kfree(optcd_disk->private_data);
1928 del_timer(&delay_timer);
1929 del_timer(&req_timer);
1930 }
1931 return 0;
1932}
1933
1934
1935/* Check if disk has been changed */
1936static int opt_media_change(struct gendisk *disk)
1937{
1938 DEBUG((DEBUG_VFS, "executing opt_media_change"));
1939 DEBUG((DEBUG_VFS, "dev: %s; disk_changed = %d\n",
1940 disk->disk_name, disk_changed));
1941
1942 if (disk_changed) {
1943 disk_changed = 0;
1944 return 1;
1945 }
1946 return 0;
1947}
1948
1949/* Driver initialisation */
1950
1951
1952/* Returns 1 if a drive is detected with a version string
1953 starting with "DOLPHIN". Otherwise 0. */
1954static int __init version_ok(void)
1955{
1956 char devname[100];
1957 int count, i, ch, status;
1958
1959 status = exec_cmd(COMVERSION);
1960 if (status < 0) {
1961 DEBUG((DEBUG_VFS, "exec_cmd COMVERSION: %02x", -status));
1962 return 0;
1963 }
1964 if ((count = get_data(1)) < 0) {
1965 DEBUG((DEBUG_VFS, "get_data(1): %02x", -count));
1966 return 0;
1967 }
1968 for (i = 0, ch = -1; count > 0; count--) {
1969 if ((ch = get_data(1)) < 0) {
1970 DEBUG((DEBUG_VFS, "get_data(1): %02x", -ch));
1971 break;
1972 }
1973 if (i < 99)
1974 devname[i++] = ch;
1975 }
1976 devname[i] = '\0';
1977 if (ch < 0)
1978 return 0;
1979
1980 printk(KERN_INFO "optcd: Device %s detected\n", devname);
1981 return ((devname[0] == 'D')
1982 && (devname[1] == 'O')
1983 && (devname[2] == 'L')
1984 && (devname[3] == 'P')
1985 && (devname[4] == 'H')
1986 && (devname[5] == 'I')
1987 && (devname[6] == 'N'));
1988}
1989
1990
1991static struct block_device_operations opt_fops = {
1992 .owner = THIS_MODULE,
1993 .open = opt_open,
1994 .release = opt_release,
1995 .ioctl = opt_ioctl,
1996 .media_changed = opt_media_change,
1997};
1998
1999#ifndef MODULE
2000/* Get kernel parameter when used as a kernel driver */
2001static int optcd_setup(char *str)
2002{
2003 int ints[4];
2004 (void)get_options(str, ARRAY_SIZE(ints), ints);
2005
2006 if (ints[0] > 0)
2007 optcd_port = ints[1];
2008
2009 return 1;
2010}
2011
2012__setup("optcd=", optcd_setup);
2013
2014#endif /* MODULE */
2015
2016/* Test for presence of drive and initialize it. Called at boot time
2017 or during module initialisation. */
2018static int __init optcd_init(void)
2019{
2020 int status;
2021
2022 if (optcd_port <= 0) {
2023 printk(KERN_INFO
2024 "optcd: no Optics Storage CDROM Initialization\n");
2025 return -EIO;
2026 }
2027 optcd_disk = alloc_disk(1);
2028 if (!optcd_disk) {
2029 printk(KERN_ERR "optcd: can't allocate disk\n");
2030 return -ENOMEM;
2031 }
2032 optcd_disk->major = MAJOR_NR;
2033 optcd_disk->first_minor = 0;
2034 optcd_disk->fops = &opt_fops;
2035 sprintf(optcd_disk->disk_name, "optcd");
2036 sprintf(optcd_disk->devfs_name, "optcd");
2037
2038 if (!request_region(optcd_port, 4, "optcd")) {
2039 printk(KERN_ERR "optcd: conflict, I/O port 0x%x already used\n",
2040 optcd_port);
2041 put_disk(optcd_disk);
2042 return -EIO;
2043 }
2044
2045 if (!reset_drive()) {
2046 printk(KERN_ERR "optcd: drive at 0x%x not ready\n", optcd_port);
2047 release_region(optcd_port, 4);
2048 put_disk(optcd_disk);
2049 return -EIO;
2050 }
2051 if (!version_ok()) {
2052 printk(KERN_ERR "optcd: unknown drive detected; aborting\n");
2053 release_region(optcd_port, 4);
2054 put_disk(optcd_disk);
2055 return -EIO;
2056 }
2057 status = exec_cmd(COMINITDOUBLE);
2058 if (status < 0) {
2059 printk(KERN_ERR "optcd: cannot init double speed mode\n");
2060 release_region(optcd_port, 4);
2061 DEBUG((DEBUG_VFS, "exec_cmd COMINITDOUBLE: %02x", -status));
2062 put_disk(optcd_disk);
2063 return -EIO;
2064 }
2065 if (register_blkdev(MAJOR_NR, "optcd")) {
2066 release_region(optcd_port, 4);
2067 put_disk(optcd_disk);
2068 return -EIO;
2069 }
2070
2071
2072 opt_queue = blk_init_queue(do_optcd_request, &optcd_lock);
2073 if (!opt_queue) {
2074 unregister_blkdev(MAJOR_NR, "optcd");
2075 release_region(optcd_port, 4);
2076 put_disk(optcd_disk);
2077 return -ENOMEM;
2078 }
2079
2080 blk_queue_hardsect_size(opt_queue, 2048);
2081 optcd_disk->queue = opt_queue;
2082 add_disk(optcd_disk);
2083
2084 printk(KERN_INFO "optcd: DOLPHIN 8000 AT CDROM at 0x%x\n", optcd_port);
2085 return 0;
2086}
2087
2088
2089static void __exit optcd_exit(void)
2090{
2091 del_gendisk(optcd_disk);
2092 put_disk(optcd_disk);
2093 if (unregister_blkdev(MAJOR_NR, "optcd") == -EINVAL) {
2094 printk(KERN_ERR "optcd: what's that: can't unregister\n");
2095 return;
2096 }
2097 blk_cleanup_queue(opt_queue);
2098 release_region(optcd_port, 4);
2099 printk(KERN_INFO "optcd: module released.\n");
2100}
2101
2102module_init(optcd_init);
2103module_exit(optcd_exit);
2104
2105MODULE_LICENSE("GPL");
2106MODULE_ALIAS_BLOCKDEV_MAJOR(OPTICS_CDROM_MAJOR);
diff --git a/drivers/cdrom/optcd.h b/drivers/cdrom/optcd.h
new file mode 100644
index 000000000000..1911bb92ee28
--- /dev/null
+++ b/drivers/cdrom/optcd.h
@@ -0,0 +1,52 @@
1/* linux/include/linux/optcd.h - Optics Storage 8000 AT CDROM driver
2 $Id: optcd.h,v 1.2 1996/01/15 18:43:44 root Exp root $
3
4 Copyright (C) 1995 Leo Spiekman (spiekman@dutette.et.tudelft.nl)
5
6
7 Configuration file for linux/drivers/cdrom/optcd.c
8*/
9
10#ifndef _LINUX_OPTCD_H
11#define _LINUX_OPTCD_H
12
13
14/* I/O base of drive. Drive uses base to base+2.
15 This setting can be overridden with the kernel or insmod command
16 line option 'optcd=<portbase>'. Use address of 0 to disable driver. */
17#define OPTCD_PORTBASE 0x340
18
19
20/* enable / disable parts of driver by define / undef */
21#define MULTISESSION /* multisession support (ALPHA) */
22
23
24/* Change 0 to 1 to debug various parts of the driver */
25#define DEBUG_DRIVE_IF 0 /* Low level drive interface */
26#define DEBUG_CONV 0 /* Address conversions */
27#define DEBUG_BUFFERS 0 /* Buffering and block size conversion */
28#define DEBUG_REQUEST 0 /* Request mechanism */
29#define DEBUG_STATE 0 /* State machine */
30#define DEBUG_TOC 0 /* Q-channel and Table of Contents */
31#define DEBUG_MULTIS 0 /* Multisession code */
32#define DEBUG_VFS 0 /* VFS interface */
33
34
35/* Don't touch these unless you know what you're doing. */
36
37/* Various timeout loop repetition counts. */
38#define BUSY_TIMEOUT 10000000 /* for busy wait */
39#define FAST_TIMEOUT 100000 /* ibid. for probing */
40#define SLEEP_TIMEOUT 6000 /* for timer wait */
41#define MULTI_SEEK_TIMEOUT 1000 /* for timer wait */
42#define READ_TIMEOUT 6000 /* for poll wait */
43#define STOP_TIMEOUT 2000 /* for poll wait */
44#define RESET_WAIT 5000 /* busy wait at drive reset */
45
46/* # of buffers for block size conversion. 6 is optimal for my setup (P75),
47 giving 280 kb/s, with 0.4% CPU usage. Experiment to find your optimal
48 setting */
49#define N_BUFS 6
50
51
52#endif /* _LINUX_OPTCD_H */
diff --git a/drivers/cdrom/sbpcd.c b/drivers/cdrom/sbpcd.c
new file mode 100644
index 000000000000..fc2c433f6a29
--- /dev/null
+++ b/drivers/cdrom/sbpcd.c
@@ -0,0 +1,5978 @@
1/*
2 * sbpcd.c CD-ROM device driver for the whole family of traditional,
3 * non-ATAPI IDE-style Matsushita/Panasonic CR-5xx drives.
4 * Works with SoundBlaster compatible cards and with "no-sound"
5 * interface cards like Lasermate, Panasonic CI-101P, Teac, ...
6 * Also for the Longshine LCS-7260 drive.
7 * Also for the IBM "External ISA CD-Rom" drive.
8 * Also for the CreativeLabs CD200 drive.
9 * Also for the TEAC CD-55A drive.
10 * Also for the ECS-AT "Vertos 100" drive.
11 * Not for Sanyo drives (but for the H94A, sjcd is there...).
12 * Not for any other Funai drives than the CD200 types (sometimes
13 * labelled E2550UA or MK4015 or 2800F).
14 */
15
16#define VERSION "v4.63 Andrew J. Kroll <ag784@freenet.buffalo.edu> Wed Jul 26 04:24:10 EDT 2000"
17
18/* Copyright (C) 1993, 1994, 1995 Eberhard Moenkeberg <emoenke@gwdg.de>
19 *
20 * This program is free software; you can redistribute it and/or modify
21 * it under the terms of the GNU General Public License as published by
22 * the Free Software Foundation; either version 2, or (at your option)
23 * any later version.
24 *
25 * You should have received a copy of the GNU General Public License
26 * (for example /usr/src/linux/COPYING); if not, write to the Free
27 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 *
29 * If you change this software, you should mail a .diff file with some
30 * description lines to emoenke@gwdg.de. I want to know about it.
31 *
32 * If you are the editor of a Linux CD, you should enable sbpcd.c within
33 * your boot floppy kernel and send me one of your CDs for free.
34 *
35 * If you would like to port the driver to an other operating system (f.e.
36 * FreeBSD or NetBSD) or use it as an information source, you shall not be
37 * restricted by the GPL under the following conditions:
38 * a) the source code of your work is freely available
39 * b) my part of the work gets mentioned at all places where your
40 * authorship gets mentioned
41 * c) I receive a copy of your code together with a full installation
42 * package of your operating system for free.
43 *
44 *
45 * VERSION HISTORY
46 *
47 * 0.1 initial release, April/May 93, after mcd.c (Martin Harriss)
48 *
49 * 0.2 thek "repeat:"-loop in do_sbpcd_request did not check for
50 * end-of-request_queue (resulting in kernel panic).
51 * Flow control seems stable, but throughput is not better.
52 *
53 * 0.3 interrupt locking totally eliminated (maybe "inb" and "outb"
54 * are still locking) - 0.2 made keyboard-type-ahead losses.
55 * check_sbpcd_media_change added (to use by isofs/inode.c)
56 * - but it detects almost nothing.
57 *
58 * 0.4 use MAJOR 25 definitely.
59 * Almost total re-design to support double-speed drives and
60 * "naked" (no sound) interface cards ("LaserMate" interface type).
61 * Flow control should be exact now.
62 * Don't occupy the SbPro IRQ line (not needed either); will
63 * live together with Hannu Savolainen's sndkit now.
64 * Speeded up data transfer to 150 kB/sec, with help from Kai
65 * Makisara, the "provider" of the "mt" tape utility.
66 * Give "SpinUp" command if necessary.
67 * First steps to support up to 4 drives (but currently only one).
68 * Implemented audio capabilities - workman should work, xcdplayer
69 * gives some problems.
70 * This version is still consuming too much CPU time, and
71 * sleeping still has to be worked on.
72 * During "long" implied seeks, it seems possible that a
73 * ReadStatus command gets ignored. That gives the message
74 * "ResponseStatus timed out" (happens about 6 times here during
75 * a "ls -alR" of the YGGDRASIL LGX-Beta CD). Such a case is
76 * handled without data error, but it should get done better.
77 *
78 * 0.5 Free CPU during waits (again with help from Kai Makisara).
79 * Made it work together with the LILO/kernel setup standard.
80 * Included auto-probing code, as suggested by YGGDRASIL.
81 * Formal redesign to add DDI debugging.
82 * There are still flaws in IOCTL (workman with double speed drive).
83 *
84 * 1.0 Added support for all drive IDs (0...3, no longer only 0)
85 * and up to 4 drives on one controller.
86 * Added "#define MANY_SESSION" for "old" multi session CDs.
87 *
88 * 1.1 Do SpinUp for new drives, too.
89 * Revised for clean compile under "old" kernels (0.99pl9).
90 *
91 * 1.2 Found the "workman with double-speed drive" bug: use the driver's
92 * audio_state, not what the drive is reporting with ReadSubQ.
93 *
94 * 1.3 Minor cleanups.
95 * Refinements regarding Workman.
96 *
97 * 1.4 Read XA disks (PhotoCDs) with "old" drives, too (but only the first
98 * session - no chance to fully access a "multi-session" CD).
99 * This currently still is too slow (50 kB/sec) - but possibly
100 * the old drives won't do it faster.
101 * Implemented "door (un)lock" for new drives (still does not work
102 * as wanted - no lock possible after an unlock).
103 * Added some debugging printout for the UPC/EAN code - but my drives
104 * return only zeroes. Is there no UPC/EAN code written?
105 *
106 * 1.5 Laborate with UPC/EAN code (not better yet).
107 * Adapt to kernel 1.1.8 change (have to explicitly include
108 * <linux/string.h> now).
109 *
110 * 1.6 Trying to read audio frames as data. Impossible with the current
111 * drive firmware levels, as it seems. Awaiting any hint. ;-)
112 * Changed "door unlock": repeat it until success.
113 * Changed CDROMSTOP routine (stop somewhat "softer" so that Workman
114 * won't get confused).
115 * Added a third interface type: Sequoia S-1000, as used with the SPEA
116 * Media FX sound card. This interface (usable for Sony and Mitsumi
117 * drives, too) needs a special configuration setup and behaves like a
118 * LaserMate type after that. Still experimental - I do not have such
119 * an interface.
120 * Use the "variable BLOCK_SIZE" feature (2048). But it does only work
121 * if you give the mount option "block=2048".
122 * The media_check routine is currently disabled; now that it gets
123 * called as it should I fear it must get synchronized for not to
124 * disturb the normal driver's activity.
125 *
126 * 2.0 Version number bumped - two reasons:
127 * - reading audio tracks as data works now with CR-562 and CR-563. We
128 * currently do it by an IOCTL (yet has to get standardized), one frame
129 * at a time; that is pretty slow. But it works.
130 * - we are maintaining now up to 4 interfaces (each up to 4 drives):
131 * did it the easy way - a different MAJOR (25, 26, ...) and a different
132 * copy of the driver (sbpcd.c, sbpcd2.c, sbpcd3.c, sbpcd4.c - only
133 * distinguished by the value of SBPCD_ISSUE and the driver's name),
134 * and a common sbpcd.h file.
135 * Bettered the "ReadCapacity error" problem with old CR-52x drives (the
136 * drives sometimes need a manual "eject/insert" before work): just
137 * reset the drive and do again. Needs lots of resets here and sometimes
138 * that does not cure, so this can't be the solution.
139 *
140 * 2.1 Found bug with multisession CDs (accessing frame 16).
141 * "read audio" works now with address type CDROM_MSF, too.
142 * Bigger audio frame buffer: allows reading max. 4 frames at time; this
143 * gives a significant speedup, but reading more than one frame at once
144 * gives missing chunks at each single frame boundary.
145 *
146 * 2.2 Kernel interface cleanups: timers, init, setup, media check.
147 *
148 * 2.3 Let "door lock" and "eject" live together.
149 * Implemented "close tray" (done automatically during open).
150 *
151 * 2.4 Use different names for device registering.
152 *
153 * 2.5 Added "#if EJECT" code (default: enabled) to automatically eject
154 * the tray during last call to "sbpcd_release".
155 * Added "#if JUKEBOX" code (default: disabled) to automatically eject
156 * the tray during call to "sbpcd_open" if no disk is in.
157 * Turn on the CD volume of "compatible" sound cards, too; just define
158 * SOUND_BASE (in sbpcd.h) accordingly (default: disabled).
159 *
160 * 2.6 Nothing new.
161 *
162 * 2.7 Added CDROMEJECT_SW ioctl to set the "EJECT" behavior on the fly:
163 * 0 disables, 1 enables auto-ejecting. Useful to keep the tray in
164 * during shutdown.
165 *
166 * 2.8 Added first support (still BETA, I need feedback or a drive) for
167 * the Longshine LCS-7260 drives. They appear as double-speed drives
168 * using the "old" command scheme, extended by tray control and door
169 * lock functions.
170 * Found (and fixed preliminary) a flaw with some multisession CDs: we
171 * have to re-direct not only the accesses to frame 16 (the isofs
172 * routines drive it up to max. 100), but also those to the continuation
173 * (repetition) frames (as far as they exist - currently set fix as
174 * 16..20).
175 * Changed default of the "JUKEBOX" define. If you use this default,
176 * your tray will eject if you try to mount without a disk in. Next
177 * mount command will insert the tray - so, just fill in a disk. ;-)
178 *
179 * 2.9 Fulfilled the Longshine LCS-7260 support; with great help and
180 * experiments by Serge Robyns.
181 * First attempts to support the TEAC CD-55A drives; but still not
182 * usable yet.
183 * Implemented the CDROMMULTISESSION ioctl; this is an attempt to handle
184 * multi session CDs more "transparent" (redirection handling has to be
185 * done within the isofs routines, and only for the special purpose of
186 * obtaining the "right" volume descriptor; accesses to the raw device
187 * should not get redirected).
188 *
189 * 3.0 Just a "normal" increment, with some provisions to do it better. ;-)
190 * Introduced "#define READ_AUDIO" to specify the maximum number of
191 * audio frames to grab with one request. This defines a buffer size
192 * within kernel space; a value of 0 will reserve no such space and
193 * disable the CDROMREADAUDIO ioctl. A value of 75 enables the reading
194 * of a whole second with one command, but will use a buffer of more
195 * than 172 kB.
196 * Started CD200 support. Drive detection should work, but nothing
197 * more.
198 *
199 * 3.1 Working to support the CD200 and the Teac CD-55A drives.
200 * AT-BUS style device numbering no longer used: use SCSI style now.
201 * So, the first "found" device has MINOR 0, regardless of the
202 * jumpered drive ID. This implies modifications to the /dev/sbpcd*
203 * entries for some people, but will help the DAU (german TLA, english:
204 * "newbie", maybe ;-) to install his "first" system from a CD.
205 *
206 * 3.2 Still testing with CD200 and CD-55A drives.
207 *
208 * 3.3 Working with CD200 support.
209 *
210 * 3.4 Auto-probing stops if an address of 0 is seen (to be entered with
211 * the kernel command line).
212 * Made the driver "loadable". If used as a module, "audio copy" is
213 * disabled, and the internal read ahead data buffer has a reduced size
214 * of 4 kB; so, throughput may be reduced a little bit with slow CPUs.
215 *
216 * 3.5 Provisions to handle weird photoCDs which have an interrupted
217 * "formatting" immediately after the last frames of some files: simply
218 * never "read ahead" with MultiSession CDs. By this, CPU usage may be
219 * increased with those CDs, and there may be a loss in speed.
220 * Re-structured the messaging system.
221 * The "loadable" version no longer has a limited READ_AUDIO buffer
222 * size.
223 * Removed "MANY_SESSION" handling for "old" multi session CDs.
224 * Added "private" IOCTLs CDROMRESET and CDROMVOLREAD.
225 * Started again to support the TEAC CD-55A drives, now that I found
226 * the money for "my own" drive. ;-)
227 * The TEAC CD-55A support is fairly working now.
228 * I have measured that the drive "delivers" at 600 kB/sec (even with
229 * bigger requests than the drive's 64 kB buffer can satisfy), but
230 * the "real" rate does not exceed 520 kB/sec at the moment.
231 * Caused by the various changes to build in TEAC support, the timed
232 * loops are de-optimized at the moment (less throughput with CR-52x
233 * drives, and the TEAC will give speed only with SBP_BUFFER_FRAMES 64).
234 *
235 * 3.6 Fixed TEAC data read problems with SbPro interfaces.
236 * Initial size of the READ_AUDIO buffer is 0. Can get set to any size
237 * during runtime.
238 *
239 * 3.7 Introduced MAX_DRIVES for some poor interface cards (seen with TEAC
240 * drives) which allow only one drive (ID 0); this avoids repetitive
241 * detection under IDs 1..3.
242 * Elongated cmd_out_T response waiting; necessary for photo CDs with
243 * a lot of sessions.
244 * Bettered the sbpcd_open() behavior with TEAC drives.
245 *
246 * 3.8 Elongated max_latency for CR-56x drives.
247 *
248 * 3.9 Finally fixed the long-known SoundScape/SPEA/Sequoia S-1000 interface
249 * configuration bug.
250 * Now Corey, Heiko, Ken, Leo, Vadim/Eric & Werner are invited to copy
251 * the config_spea() routine into their drivers. ;-)
252 *
253 * 4.0 No "big step" - normal version increment.
254 * Adapted the benefits from 1.3.33.
255 * Fiddled with CDROMREADAUDIO flaws.
256 * Avoid ReadCapacity command with CD200 drives (the MKE 1.01 version
257 * seems not to support it).
258 * Fulfilled "read audio" for CD200 drives, with help of Pete Heist
259 * (heistp@rpi.edu).
260 *
261 * 4.1 Use loglevel KERN_INFO with printk().
262 * Added support for "Vertos 100" drive ("ECS-AT") - it is very similar
263 * to the Longshine LCS-7260. Give feedback if you can - I never saw
264 * such a drive, and I have no specs.
265 *
266 * 4.2 Support for Teac 16-bit interface cards. Can't get auto-detected,
267 * so you have to jumper your card to 0x2C0. Still not 100% - come
268 * in contact if you can give qualified feedback.
269 * Use loglevel KERN_NOTICE with printk(). If you get annoyed by a
270 * flood of unwanted messages and the accompanied delay, try to read
271 * my documentation. Especially the Linux CDROM drivers have to do an
272 * important job for the newcomers, so the "distributed" version has
273 * to fit some special needs. Since generations, the flood of messages
274 * is user-configurable (even at runtime), but to get aware of this, one
275 * needs a special mental quality: the ability to read.
276 *
277 * 4.3 CD200F does not like to receive a command while the drive is
278 * reading the ToC; still trying to solve it.
279 * Removed some redundant verify_area calls (yes, Heiko Eissfeldt
280 * is visiting all the Linux CDROM drivers ;-).
281 *
282 * 4.4 Adapted one idea from tiensivu@pilot.msu.edu's "stripping-down"
283 * experiments: "KLOGD_PAUSE".
284 * Inhibited "play audio" attempts with data CDs. Provisions for a
285 * "data-safe" handling of "mixed" (data plus audio) Cds.
286 *
287 * 4.5 Meanwhile Gonzalo Tornaria <tornaria@cmat.edu.uy> (GTL) built a
288 * special end_request routine: we seem to have to take care for not
289 * to have two processes working at the request list. My understanding
290 * was and is that ll_rw_blk should not call do_sbpcd_request as long
291 * as there is still one call active (the first call will care for all
292 * outstanding I/Os, and if a second call happens, that is a bug in
293 * ll_rw_blk.c).
294 * "Check media change" without touching any drive.
295 *
296 * 4.6 Use a semaphore to synchronize multi-activity; elaborated by Rob
297 * Riggs <rriggs@tesser.com>. At the moment, we simply block "read"
298 * against "ioctl" and vice versa. This could be refined further, but
299 * I guess with almost no performance increase.
300 * Experiments to speed up the CD-55A; again with help of Rob Riggs
301 * (to be true, he gave both, idea & code. ;-)
302 *
303 * 4.61 Ported to Uniform CD-ROM driver by
304 * Heiko Eissfeldt <heiko@colossus.escape.de> with additional
305 * changes by Erik Andersen <andersee@debian.org>
306 *
307 * 4.62 Fix a bug where playing audio left the drive in an unusable state.
308 * Heiko Eissfeldt <heiko@colossus.escape.de>
309 *
310 * November 1999 -- Make kernel-parameter implementation work with 2.3.x
311 * Removed init_module & cleanup_module in favor of
312 * module_init & module_exit.
313 * Torben Mathiasen <tmm@image.dk>
314 *
315 * 4.63 Bug fixes for audio annoyances, new legacy CDROM maintainer.
316 * Annoying things fixed:
317 * TOC reread on automated disk changes
318 * TOC reread on manual cd changes
319 * Play IOCTL tries to play CD before it's actually ready... sometimes.
320 * CD_AUDIO_COMPLETED state so workman (and other playes) can repeat play.
321 * Andrew J. Kroll <ag784@freenet.buffalo.edu> Wed Jul 26 04:24:10 EDT 2000
322 *
323 * 4.64 Fix module parameters - were being completely ignored.
324 * Can also specify max_drives=N as a setup int to get rid of
325 * "ghost" drives on crap hardware (aren't they all?) Paul Gortmaker
326 *
327 * TODO
328 * implement "read all subchannel data" (96 bytes per frame)
329 * remove alot of the virtual status bits and deal with hardware status
330 * move the change of cd for audio to a better place
331 * add debug levels to insmod parameters (trivial)
332 *
333 * special thanks to Kai Makisara (kai.makisara@vtt.fi) for his fine
334 * elaborated speed-up experiments (and the fabulous results!), for
335 * the "push" towards load-free wait loops, and for the extensive mail
336 * thread which brought additional hints and bug fixes.
337 *
338 */
339
340/*
341 * Trying to merge requests breaks this driver horribly (as in it goes
342 * boom and apparently has done so since 2.3.41). As it is a legacy
343 * driver for a horribly slow double speed CD on a hideous interface
344 * designed for polled operation, I won't lose any sleep in simply
345 * disallowing merging. Paul G. 02/2001
346 *
347 * Thu May 30 14:14:47 CEST 2002:
348 *
349 * I have presumably found the reson for the above - there was a bogous
350 * end_request substitute, which was manipulating the request queues
351 * incorrectly. If someone has access to the actual hardware, and it's
352 * still operations - well please free to test it.
353 *
354 * Marcin Dalecki
355 */
356
357/*
358 * Add bio/kdev_t changes for 2.5.x required to make it work again.
359 * Still room for improvement in the request handling here if anyone
360 * actually cares. Bring your own chainsaw. Paul G. 02/2002
361 */
362
363
364#include <linux/module.h>
365
366#include <linux/errno.h>
367#include <linux/sched.h>
368#include <linux/mm.h>
369#include <linux/timer.h>
370#include <linux/fs.h>
371#include <linux/kernel.h>
372#include <linux/cdrom.h>
373#include <linux/ioport.h>
374#include <linux/devfs_fs_kernel.h>
375#include <linux/major.h>
376#include <linux/string.h>
377#include <linux/vmalloc.h>
378#include <linux/init.h>
379#include <linux/interrupt.h>
380
381#include <asm/system.h>
382#include <asm/io.h>
383#include <asm/uaccess.h>
384#include <stdarg.h>
385#include <linux/config.h>
386#include "sbpcd.h"
387
388#define MAJOR_NR MATSUSHITA_CDROM_MAJOR
389#include <linux/blkdev.h>
390
391/*==========================================================================*/
392#if SBPCD_DIS_IRQ
393# define SBPCD_CLI cli()
394# define SBPCD_STI sti()
395#else
396# define SBPCD_CLI
397# define SBPCD_STI
398#endif
399
400/*==========================================================================*/
401/*
402 * auto-probing address list
403 * inspired by Adam J. Richter from Yggdrasil
404 *
405 * still not good enough - can cause a hang.
406 * example: a NE 2000 ethernet card at 300 will cause a hang probing 310.
407 * if that happens, reboot and use the LILO (kernel) command line.
408 * The possibly conflicting ethernet card addresses get NOT probed
409 * by default - to minimize the hang possibilities.
410 *
411 * The SB Pro addresses get "mirrored" at 0x6xx and some more locations - to
412 * avoid a type error, the 0x2xx-addresses must get checked before 0x6xx.
413 *
414 * send mail to emoenke@gwdg.de if your interface card is not FULLY
415 * represented here.
416 */
417static int sbpcd[] =
418{
419 CDROM_PORT, SBPRO, /* probe with user's setup first */
420#if DISTRIBUTION
421 0x230, 1, /* Soundblaster Pro and 16 (default) */
422#if 0
423 0x300, 0, /* CI-101P (default), WDH-7001C (default),
424 Galaxy (default), Reveal (one default) */
425 0x250, 1, /* OmniCD default, Soundblaster Pro and 16 */
426 0x2C0, 3, /* Teac 16-bit cards */
427 0x260, 1, /* OmniCD */
428 0x320, 0, /* Lasermate, CI-101P, WDH-7001C, Galaxy, Reveal (other default),
429 Longshine LCS-6853 (default) */
430 0x338, 0, /* Reveal Sound Wave 32 card model #SC600 */
431 0x340, 0, /* Mozart sound card (default), Lasermate, CI-101P */
432 0x360, 0, /* Lasermate, CI-101P */
433 0x270, 1, /* Soundblaster 16 */
434 0x670, 0, /* "sound card #9" */
435 0x690, 0, /* "sound card #9" */
436 0x338, 2, /* SPEA Media FX, Ensonic SoundScape (default) */
437 0x328, 2, /* SPEA Media FX */
438 0x348, 2, /* SPEA Media FX */
439 0x634, 0, /* some newer sound cards */
440 0x638, 0, /* some newer sound cards */
441 0x230, 1, /* some newer sound cards */
442 /* due to incomplete address decoding of the SbPro card, these must be last */
443 0x630, 0, /* "sound card #9" (default) */
444 0x650, 0, /* "sound card #9" */
445#ifdef MODULE
446 /*
447 * some "hazardous" locations (no harm with the loadable version)
448 * (will stop the bus if a NE2000 ethernet card resides at offset -0x10)
449 */
450 0x330, 0, /* Lasermate, CI-101P, WDH-7001C */
451 0x350, 0, /* Lasermate, CI-101P */
452 0x358, 2, /* SPEA Media FX */
453 0x370, 0, /* Lasermate, CI-101P */
454 0x290, 1, /* Soundblaster 16 */
455 0x310, 0, /* Lasermate, CI-101P, WDH-7001C */
456#endif /* MODULE */
457#endif
458#endif /* DISTRIBUTION */
459};
460
461/*
462 * Protects access to global structures etc.
463 */
464static __cacheline_aligned DEFINE_SPINLOCK(sbpcd_lock);
465static struct request_queue *sbpcd_queue;
466
467MODULE_PARM(sbpcd, "2i");
468MODULE_PARM(max_drives, "i");
469
470#define NUM_PROBE (sizeof(sbpcd) / sizeof(int))
471
472/*==========================================================================*/
473
474#define INLINE inline
475
476/*==========================================================================*/
477/*
478 * the forward references:
479 */
480static void sbp_sleep(u_int);
481static void mark_timeout_delay(u_long);
482static void mark_timeout_data(u_long);
483#if 0
484static void mark_timeout_audio(u_long);
485#endif
486static void sbp_read_cmd(struct request *req);
487static int sbp_data(struct request *req);
488static int cmd_out(void);
489static int DiskInfo(void);
490
491/*==========================================================================*/
492
493/*
494 * pattern for printk selection:
495 *
496 * (1<<DBG_INF) necessary information
497 * (1<<DBG_BSZ) BLOCK_SIZE trace
498 * (1<<DBG_REA) "read" status trace
499 * (1<<DBG_CHK) "media check" trace
500 * (1<<DBG_TIM) datarate timer test
501 * (1<<DBG_INI) initialization trace
502 * (1<<DBG_TOC) tell TocEntry values
503 * (1<<DBG_IOC) ioctl trace
504 * (1<<DBG_STA) "ResponseStatus" trace
505 * (1<<DBG_ERR) "cc_ReadError" trace
506 * (1<<DBG_CMD) "cmd_out" trace
507 * (1<<DBG_WRN) give explanation before auto-probing
508 * (1<<DBG_MUL) multi session code test
509 * (1<<DBG_IDX) "drive_id != 0" test code
510 * (1<<DBG_IOX) some special information
511 * (1<<DBG_DID) drive ID test
512 * (1<<DBG_RES) drive reset info
513 * (1<<DBG_SPI) SpinUp test info
514 * (1<<DBG_IOS) ioctl trace: "subchannel"
515 * (1<<DBG_IO2) ioctl trace: general
516 * (1<<DBG_UPC) show UPC info
517 * (1<<DBG_XA1) XA mode debugging
518 * (1<<DBG_LCK) door (un)lock info
519 * (1<<DBG_SQ1) dump SubQ frame
520 * (1<<DBG_AUD) "read audio" debugging
521 * (1<<DBG_SEQ) Sequoia interface configuration trace
522 * (1<<DBG_LCS) Longshine LCS-7260 debugging trace
523 * (1<<DBG_CD2) MKE/Funai CD200 debugging trace
524 * (1<<DBG_TEA) TEAC CD-55A debugging trace
525 * (1<<DBG_ECS) ECS-AT (Vertos-100) debugging trace
526 * (1<<DBG_000) unnecessary information
527 */
528#if DISTRIBUTION
529static int sbpcd_debug = (1<<DBG_INF);
530#else
531static int sbpcd_debug = 0 & ((1<<DBG_INF) |
532 (1<<DBG_TOC) |
533 (1<<DBG_MUL) |
534 (1<<DBG_UPC));
535#endif /* DISTRIBUTION */
536
537static int sbpcd_ioaddr = CDROM_PORT; /* default I/O base address */
538static int sbpro_type = SBPRO;
539static unsigned char f_16bit;
540static unsigned char do_16bit;
541static int CDo_command, CDo_reset;
542static int CDo_sel_i_d, CDo_enable;
543static int CDi_info, CDi_status, CDi_data;
544static struct cdrom_msf msf;
545static struct cdrom_ti ti;
546static struct cdrom_tochdr tochdr;
547static struct cdrom_tocentry tocentry;
548static struct cdrom_subchnl SC;
549static struct cdrom_volctrl volctrl;
550static struct cdrom_read_audio read_audio;
551
552static unsigned char msgnum;
553static char msgbuf[80];
554
555static int max_drives = MAX_DRIVES;
556#ifndef MODULE
557static unsigned char setup_done;
558static const char *str_sb_l = "soundblaster";
559static const char *str_sp_l = "spea";
560static const char *str_ss_l = "soundscape";
561static const char *str_t16_l = "teac16bit";
562static const char *str_ss = "SoundScape";
563#endif
564static const char *str_sb = "SoundBlaster";
565static const char *str_lm = "LaserMate";
566static const char *str_sp = "SPEA";
567static const char *str_t16 = "Teac16bit";
568static const char *type;
569static const char *major_name="sbpcd";
570
571/*==========================================================================*/
572
573#ifdef FUTURE
574static DECLARE_WAIT_QUEUE_HEAD(sbp_waitq);
575#endif /* FUTURE */
576
577static int teac=SBP_TEAC_SPEED;
578static int buffers=SBP_BUFFER_FRAMES;
579
580static u_char family0[]="MATSHITA"; /* MKE CR-521, CR-522, CR-523 */
581static u_char family1[]="CR-56"; /* MKE CR-562, CR-563 */
582static u_char family2[]="CD200"; /* MKE CD200, Funai CD200F */
583static u_char familyL[]="LCS-7260"; /* Longshine LCS-7260 */
584static u_char familyT[]="CD-55"; /* TEAC CD-55A */
585static u_char familyV[]="ECS-AT"; /* ECS Vertos 100 */
586
587static u_int recursion; /* internal testing only */
588static u_int fatal_err; /* internal testing only */
589static u_int response_count;
590static u_int flags_cmd_out;
591static u_char cmd_type;
592static u_char drvcmd[10];
593static u_char infobuf[20];
594static u_char xa_head_buf[CD_XA_HEAD];
595static u_char xa_tail_buf[CD_XA_TAIL];
596
597#if OLD_BUSY
598static volatile u_char busy_data;
599static volatile u_char busy_audio; /* true semaphores would be safer */
600#endif /* OLD_BUSY */
601static DECLARE_MUTEX(ioctl_read_sem);
602static u_long timeout;
603static volatile u_char timed_out_delay;
604static volatile u_char timed_out_data;
605#if 0
606static volatile u_char timed_out_audio;
607#endif
608static u_int datarate= 1000000;
609static u_int maxtim16=16000000;
610static u_int maxtim04= 4000000;
611static u_int maxtim02= 2000000;
612static u_int maxtim_8= 30000;
613#if LONG_TIMING
614static u_int maxtim_data= 9000;
615#else
616static u_int maxtim_data= 3000;
617#endif /* LONG_TIMING */
618#if DISTRIBUTION
619static int n_retries=6;
620#else
621static int n_retries=6;
622#endif
623/*==========================================================================*/
624
625static int ndrives;
626static u_char drv_pattern[NR_SBPCD]={speed_auto,speed_auto,speed_auto,speed_auto};
627
628/*==========================================================================*/
629/*
630 * drive space begins here (needed separate for each unit)
631 */
632static struct sbpcd_drive {
633 char drv_id; /* "jumpered" drive ID or -1 */
634 char drv_sel; /* drive select lines bits */
635
636 char drive_model[9];
637 u_char firmware_version[4];
638 char f_eject; /* auto-eject flag: 0 or 1 */
639 u_char *sbp_buf; /* Pointer to internal data buffer,
640 space allocated during sbpcd_init() */
641 u_int sbp_bufsiz; /* size of sbp_buf (# of frames) */
642 int sbp_first_frame; /* First frame in buffer */
643 int sbp_last_frame; /* Last frame in buffer */
644 int sbp_read_frames; /* Number of frames being read to buffer */
645 int sbp_current; /* Frame being currently read */
646
647 u_char mode; /* read_mode: READ_M1, READ_M2, READ_SC, READ_AU */
648 u_char *aud_buf; /* Pointer to audio data buffer,
649 space allocated during sbpcd_init() */
650 u_int sbp_audsiz; /* size of aud_buf (# of raw frames) */
651 u_int drv_type;
652 u_char drv_options;
653 int status_bits;
654 u_char diskstate_flags;
655 u_char sense_byte;
656
657 u_char CD_changed;
658 char open_count;
659 u_char error_byte;
660
661 u_char f_multisession;
662 u_int lba_multi;
663 int first_session;
664 int last_session;
665 int track_of_last_session;
666
667 u_char audio_state;
668 u_int pos_audio_start;
669 u_int pos_audio_end;
670 char vol_chan0;
671 u_char vol_ctrl0;
672 char vol_chan1;
673 u_char vol_ctrl1;
674#if 000 /* no supported drive has it */
675 char vol_chan2;
676 u_char vol_ctrl2;
677 char vol_chan3;
678 u_char vol_ctrl3;
679#endif /*000 */
680 u_char volume_control; /* TEAC on/off bits */
681
682 u_char SubQ_ctl_adr;
683 u_char SubQ_trk;
684 u_char SubQ_pnt_idx;
685 u_int SubQ_run_tot;
686 u_int SubQ_run_trk;
687 u_char SubQ_whatisthis;
688
689 u_char UPC_ctl_adr;
690 u_char UPC_buf[7];
691
692 int frame_size;
693 int CDsize_frm;
694
695 u_char xa_byte; /* 0x20: XA capabilities */
696 u_char n_first_track; /* binary */
697 u_char n_last_track; /* binary (not bcd), 0x01...0x63 */
698 u_int size_msf; /* time of whole CD, position of LeadOut track */
699 u_int size_blk;
700
701 u_char TocEnt_nixbyte; /* em */
702 u_char TocEnt_ctl_adr;
703 u_char TocEnt_number;
704 u_char TocEnt_format; /* em */
705 u_int TocEnt_address;
706#ifdef SAFE_MIXED
707 char has_data;
708#endif /* SAFE_MIXED */
709 u_char ored_ctl_adr; /* to detect if CDROM contains data tracks */
710
711 struct {
712 u_char nixbyte; /* em */
713 u_char ctl_adr; /* 0x4x: data, 0x0x: audio */
714 u_char number;
715 u_char format; /* em */ /* 0x00: lba, 0x01: msf */
716 u_int address;
717 } TocBuffer[MAX_TRACKS+1]; /* last entry faked */
718
719 int in_SpinUp; /* CR-52x test flag */
720 int n_bytes; /* TEAC awaited response count */
721 u_char error_state, b3, b4; /* TEAC command error state */
722 u_char f_drv_error; /* TEAC command error flag */
723 u_char speed_byte;
724 int frmsiz;
725 u_char f_XA; /* 1: XA */
726 u_char type_byte; /* 0, 1, 3 */
727 u_char mode_xb_6;
728 u_char mode_yb_7;
729 u_char mode_xb_8;
730 u_char delay;
731 struct cdrom_device_info *sbpcd_infop;
732 struct gendisk *disk;
733} D_S[NR_SBPCD];
734
735static struct sbpcd_drive *current_drive = D_S;
736
737/*
738 * drive space ends here (needed separate for each unit)
739 */
740/*==========================================================================*/
741#if 0
742unsigned long cli_sti; /* for saving the processor flags */
743#endif
744/*==========================================================================*/
745static struct timer_list delay_timer =
746 TIMER_INITIALIZER(mark_timeout_delay, 0, 0);
747static struct timer_list data_timer =
748 TIMER_INITIALIZER(mark_timeout_data, 0, 0);
749#if 0
750static struct timer_list audio_timer =
751 TIMER_INITIALIZER(mark_timeout_audio, 0, 0);
752#endif
753/*==========================================================================*/
754/*
755 * DDI interface
756 */
757static void msg(int level, const char *fmt, ...)
758{
759#if DISTRIBUTION
760#define MSG_LEVEL KERN_NOTICE
761#else
762#define MSG_LEVEL KERN_INFO
763#endif /* DISTRIBUTION */
764
765 char buf[256];
766 va_list args;
767
768 if (!(sbpcd_debug&(1<<level))) return;
769
770 msgnum++;
771 if (msgnum>99) msgnum=0;
772 sprintf(buf, MSG_LEVEL "%s-%d [%02d]: ", major_name, current_drive - D_S, msgnum);
773 va_start(args, fmt);
774 vsprintf(&buf[18], fmt, args);
775 va_end(args);
776 printk(buf);
777#if KLOGD_PAUSE
778 sbp_sleep(KLOGD_PAUSE); /* else messages get lost */
779#endif /* KLOGD_PAUSE */
780 return;
781}
782/*==========================================================================*/
783/*
784 * DDI interface: runtime trace bit pattern maintenance
785 */
786static int sbpcd_dbg_ioctl(unsigned long arg, int level)
787{
788 switch(arg)
789 {
790 case 0: /* OFF */
791 sbpcd_debug = DBG_INF;
792 break;
793
794 default:
795 if (arg>=128) sbpcd_debug &= ~(1<<(arg-128));
796 else sbpcd_debug |= (1<<arg);
797 }
798 return (arg);
799}
800/*==========================================================================*/
801static void mark_timeout_delay(u_long i)
802{
803 timed_out_delay=1;
804#if 0
805 msg(DBG_TIM,"delay timer expired.\n");
806#endif
807}
808/*==========================================================================*/
809static void mark_timeout_data(u_long i)
810{
811 timed_out_data=1;
812#if 0
813 msg(DBG_TIM,"data timer expired.\n");
814#endif
815}
816/*==========================================================================*/
817#if 0
818static void mark_timeout_audio(u_long i)
819{
820 timed_out_audio=1;
821#if 0
822 msg(DBG_TIM,"audio timer expired.\n");
823#endif
824}
825#endif
826/*==========================================================================*/
827/*
828 * Wait a little while (used for polling the drive).
829 */
830static void sbp_sleep(u_int time)
831{
832 sti();
833 current->state = TASK_INTERRUPTIBLE;
834 schedule_timeout(time);
835 sti();
836}
837/*==========================================================================*/
838#define RETURN_UP(rc) {up(&ioctl_read_sem); return(rc);}
839/*==========================================================================*/
840/*
841 * convert logical_block_address to m-s-f_number (3 bytes only)
842 */
843static INLINE void lba2msf(int lba, u_char *msf)
844{
845 lba += CD_MSF_OFFSET;
846 msf[0] = lba / (CD_SECS*CD_FRAMES);
847 lba %= CD_SECS*CD_FRAMES;
848 msf[1] = lba / CD_FRAMES;
849 msf[2] = lba % CD_FRAMES;
850}
851/*==========================================================================*/
852/*==========================================================================*/
853/*
854 * convert msf-bin to msf-bcd
855 */
856static INLINE void bin2bcdx(u_char *p) /* must work only up to 75 or 99 */
857{
858 *p=((*p/10)<<4)|(*p%10);
859}
860/*==========================================================================*/
861static INLINE u_int blk2msf(u_int blk)
862{
863 MSF msf;
864 u_int mm;
865
866 msf.c[3] = 0;
867 msf.c[2] = (blk + CD_MSF_OFFSET) / (CD_SECS * CD_FRAMES);
868 mm = (blk + CD_MSF_OFFSET) % (CD_SECS * CD_FRAMES);
869 msf.c[1] = mm / CD_FRAMES;
870 msf.c[0] = mm % CD_FRAMES;
871 return (msf.n);
872}
873/*==========================================================================*/
874static INLINE u_int make16(u_char rh, u_char rl)
875{
876 return ((rh<<8)|rl);
877}
878/*==========================================================================*/
879static INLINE u_int make32(u_int rh, u_int rl)
880{
881 return ((rh<<16)|rl);
882}
883/*==========================================================================*/
884static INLINE u_char swap_nibbles(u_char i)
885{
886 return ((i<<4)|(i>>4));
887}
888/*==========================================================================*/
889static INLINE u_char byt2bcd(u_char i)
890{
891 return (((i/10)<<4)+i%10);
892}
893/*==========================================================================*/
894static INLINE u_char bcd2bin(u_char bcd)
895{
896 return ((bcd>>4)*10+(bcd&0x0F));
897}
898/*==========================================================================*/
899static INLINE int msf2blk(int msfx)
900{
901 MSF msf;
902 int i;
903
904 msf.n=msfx;
905 i=(msf.c[2] * CD_SECS + msf.c[1]) * CD_FRAMES + msf.c[0] - CD_MSF_OFFSET;
906 if (i<0) return (0);
907 return (i);
908}
909/*==========================================================================*/
910/*
911 * convert m-s-f_number (3 bytes only) to logical_block_address
912 */
913static INLINE int msf2lba(u_char *msf)
914{
915 int i;
916
917 i=(msf[0] * CD_SECS + msf[1]) * CD_FRAMES + msf[2] - CD_MSF_OFFSET;
918 if (i<0) return (0);
919 return (i);
920}
921/*==========================================================================*/
922/* evaluate cc_ReadError code */
923static int sta2err(int sta)
924{
925 if (famT_drive)
926 {
927 if (sta==0x00) return (0);
928 if (sta==0x01) return (-604); /* CRC error */
929 if (sta==0x02) return (-602); /* drive not ready */
930 if (sta==0x03) return (-607); /* unknown media */
931 if (sta==0x04) return (-612); /* general failure */
932 if (sta==0x05) return (0);
933 if (sta==0x06) return (-ERR_DISKCHANGE); /* disk change */
934 if (sta==0x0b) return (-612); /* general failure */
935 if (sta==0xff) return (-612); /* general failure */
936 return (0);
937 }
938 else
939 {
940 if (sta<=2) return (sta);
941 if (sta==0x05) return (-604); /* CRC error */
942 if (sta==0x06) return (-606); /* seek error */
943 if (sta==0x0d) return (-606); /* seek error */
944 if (sta==0x0e) return (-603); /* unknown command */
945 if (sta==0x14) return (-603); /* unknown command */
946 if (sta==0x0c) return (-611); /* read fault */
947 if (sta==0x0f) return (-611); /* read fault */
948 if (sta==0x10) return (-611); /* read fault */
949 if (sta>=0x16) return (-612); /* general failure */
950 if (sta==0x11) return (-ERR_DISKCHANGE); /* disk change (LCS: removed) */
951 if (famL_drive)
952 if (sta==0x12) return (-ERR_DISKCHANGE); /* disk change (inserted) */
953 return (-602); /* drive not ready */
954 }
955}
956/*==========================================================================*/
957static INLINE void clr_cmdbuf(void)
958{
959 int i;
960
961 for (i=0;i<10;i++) drvcmd[i]=0;
962 cmd_type=0;
963}
964/*==========================================================================*/
965static void flush_status(void)
966{
967 int i;
968
969 sbp_sleep(15*HZ/10);
970 for (i=maxtim_data;i!=0;i--) inb(CDi_status);
971}
972/*====================================================================*/
973/*
974 * CDi status loop for Teac CD-55A (Rob Riggs)
975 *
976 * This is needed because for some strange reason
977 * the CD-55A can take a real long time to give a
978 * status response. This seems to happen after we
979 * issue a READ command where a long seek is involved.
980 *
981 * I tried to ensure that we get max throughput with
982 * minimal busy waiting. We busy wait at first, then
983 * "switch gears" and start sleeping. We sleep for
984 * longer periods of time the longer we wait.
985 *
986 */
987static int CDi_stat_loop_T(void)
988{
989 int i, gear=1;
990 u_long timeout_1, timeout_2, timeout_3, timeout_4;
991
992 timeout_1 = jiffies + HZ / 50; /* sbp_sleep(0) for a short period */
993 timeout_2 = jiffies + HZ / 5; /* nap for no more than 200ms */
994 timeout_3 = jiffies + 5 * HZ; /* sleep for up to 5s */
995 timeout_4 = jiffies + 45 * HZ; /* long sleep for up to 45s. */
996 do
997 {
998 i = inb(CDi_status);
999 if (!(i&s_not_data_ready)) return (i);
1000 if (!(i&s_not_result_ready)) return (i);
1001 switch(gear)
1002 {
1003 case 4:
1004 sbp_sleep(HZ);
1005 if (time_after(jiffies, timeout_4)) gear++;
1006 msg(DBG_TEA, "CDi_stat_loop_T: long sleep active.\n");
1007 break;
1008 case 3:
1009 sbp_sleep(HZ/10);
1010 if (time_after(jiffies, timeout_3)) gear++;
1011 break;
1012 case 2:
1013 sbp_sleep(HZ/100);
1014 if (time_after(jiffies, timeout_2)) gear++;
1015 break;
1016 case 1:
1017 sbp_sleep(0);
1018 if (time_after(jiffies, timeout_1)) gear++;
1019 }
1020 } while (gear < 5);
1021 return -1;
1022}
1023/*==========================================================================*/
1024static int CDi_stat_loop(void)
1025{
1026 int i,j;
1027
1028 for(timeout = jiffies + 10*HZ, i=maxtim_data; time_before(jiffies, timeout); )
1029 {
1030 for ( ;i!=0;i--)
1031 {
1032 j=inb(CDi_status);
1033 if (!(j&s_not_data_ready)) return (j);
1034 if (!(j&s_not_result_ready)) return (j);
1035 if (fam0L_drive) if (j&s_attention) return (j);
1036 }
1037 sbp_sleep(1);
1038 i = 1;
1039 }
1040 msg(DBG_LCS,"CDi_stat_loop failed in line %d\n", __LINE__);
1041 return (-1);
1042}
1043/*==========================================================================*/
1044#if 00000
1045/*==========================================================================*/
1046static int tst_DataReady(void)
1047{
1048 int i;
1049
1050 i=inb(CDi_status);
1051 if (i&s_not_data_ready) return (0);
1052 return (1);
1053}
1054/*==========================================================================*/
1055static int tst_ResultReady(void)
1056{
1057 int i;
1058
1059 i=inb(CDi_status);
1060 if (i&s_not_result_ready) return (0);
1061 return (1);
1062}
1063/*==========================================================================*/
1064static int tst_Attention(void)
1065{
1066 int i;
1067
1068 i=inb(CDi_status);
1069 if (i&s_attention) return (1);
1070 return (0);
1071}
1072/*==========================================================================*/
1073#endif
1074/*==========================================================================*/
1075static int ResponseInfo(void)
1076{
1077 int i,j,st=0;
1078 u_long timeout;
1079
1080 for (i=0,timeout=jiffies+HZ;i<response_count;i++)
1081 {
1082 for (j=maxtim_data; ; )
1083 {
1084 for ( ;j!=0;j-- )
1085 {
1086 st=inb(CDi_status);
1087 if (!(st&s_not_result_ready)) break;
1088 }
1089 if ((j!=0)||time_after_eq(jiffies, timeout)) break;
1090 sbp_sleep(1);
1091 j = 1;
1092 }
1093 if (time_after_eq(jiffies, timeout)) break;
1094 infobuf[i]=inb(CDi_info);
1095 }
1096#if 000
1097 while (!(inb(CDi_status)&s_not_result_ready))
1098 {
1099 infobuf[i++]=inb(CDi_info);
1100 }
1101 j=i-response_count;
1102 if (j>0) msg(DBG_INF,"ResponseInfo: got %d trailing bytes.\n",j);
1103#endif /* 000 */
1104 for (j=0;j<i;j++)
1105 sprintf(&msgbuf[j*3]," %02X",infobuf[j]);
1106 msgbuf[j*3]=0;
1107 msg(DBG_CMD,"ResponseInfo:%s (%d,%d)\n",msgbuf,response_count,i);
1108 j=response_count-i;
1109 if (j>0) return (-j);
1110 else return (i);
1111}
1112/*==========================================================================*/
1113static void EvaluateStatus(int st)
1114{
1115 current_drive->status_bits=0;
1116 if (fam1_drive) current_drive->status_bits=st|p_success;
1117 else if (fam0_drive)
1118 {
1119 if (st&p_caddin_old) current_drive->status_bits |= p_door_closed|p_caddy_in;
1120 if (st&p_spinning) current_drive->status_bits |= p_spinning;
1121 if (st&p_check) current_drive->status_bits |= p_check;
1122 if (st&p_success_old) current_drive->status_bits |= p_success;
1123 if (st&p_busy_old) current_drive->status_bits |= p_busy_new;
1124 if (st&p_disk_ok) current_drive->status_bits |= p_disk_ok;
1125 }
1126 else if (famLV_drive)
1127 {
1128 current_drive->status_bits |= p_success;
1129 if (st&p_caddin_old) current_drive->status_bits |= p_disk_ok|p_caddy_in;
1130 if (st&p_spinning) current_drive->status_bits |= p_spinning;
1131 if (st&p_check) current_drive->status_bits |= p_check;
1132 if (st&p_busy_old) current_drive->status_bits |= p_busy_new;
1133 if (st&p_lcs_door_closed) current_drive->status_bits |= p_door_closed;
1134 if (st&p_lcs_door_locked) current_drive->status_bits |= p_door_locked;
1135 }
1136 else if (fam2_drive)
1137 {
1138 current_drive->status_bits |= p_success;
1139 if (st&p2_check) current_drive->status_bits |= p1_check;
1140 if (st&p2_door_closed) current_drive->status_bits |= p1_door_closed;
1141 if (st&p2_disk_in) current_drive->status_bits |= p1_disk_in;
1142 if (st&p2_busy1) current_drive->status_bits |= p1_busy;
1143 if (st&p2_busy2) current_drive->status_bits |= p1_busy;
1144 if (st&p2_spinning) current_drive->status_bits |= p1_spinning;
1145 if (st&p2_door_locked) current_drive->status_bits |= p1_door_locked;
1146 if (st&p2_disk_ok) current_drive->status_bits |= p1_disk_ok;
1147 }
1148 else if (famT_drive)
1149 {
1150 return; /* still needs to get coded */
1151 current_drive->status_bits |= p_success;
1152 if (st&p2_check) current_drive->status_bits |= p1_check;
1153 if (st&p2_door_closed) current_drive->status_bits |= p1_door_closed;
1154 if (st&p2_disk_in) current_drive->status_bits |= p1_disk_in;
1155 if (st&p2_busy1) current_drive->status_bits |= p1_busy;
1156 if (st&p2_busy2) current_drive->status_bits |= p1_busy;
1157 if (st&p2_spinning) current_drive->status_bits |= p1_spinning;
1158 if (st&p2_door_locked) current_drive->status_bits |= p1_door_locked;
1159 if (st&p2_disk_ok) current_drive->status_bits |= p1_disk_ok;
1160 }
1161 return;
1162}
1163/*==========================================================================*/
1164static int cmd_out_T(void);
1165
1166static int get_state_T(void)
1167{
1168 int i;
1169
1170 clr_cmdbuf();
1171 current_drive->n_bytes=1;
1172 drvcmd[0]=CMDT_STATUS;
1173 i=cmd_out_T();
1174 if (i>=0) i=infobuf[0];
1175 else
1176 {
1177 msg(DBG_TEA,"get_state_T error %d\n", i);
1178 return (i);
1179 }
1180 if (i>=0)
1181 /* 2: closed, disk in */
1182 current_drive->status_bits=p1_door_closed|p1_disk_in|p1_spinning|p1_disk_ok;
1183 else if (current_drive->error_state==6)
1184 {
1185 /* 3: closed, disk in, changed ("06 xx xx") */
1186 current_drive->status_bits=p1_door_closed|p1_disk_in;
1187 current_drive->CD_changed=0xFF;
1188 current_drive->diskstate_flags &= ~toc_bit;
1189 }
1190 else if ((current_drive->error_state!=2)||(current_drive->b3!=0x3A)||(current_drive->b4==0x00))
1191 {
1192 /* 1: closed, no disk ("xx yy zz"or "02 3A 00") */
1193 current_drive->status_bits=p1_door_closed;
1194 current_drive->open_count=0;
1195 }
1196 else if (current_drive->b4==0x01)
1197 {
1198 /* 0: open ("02 3A 01") */
1199 current_drive->status_bits=0;
1200 current_drive->open_count=0;
1201 }
1202 else
1203 {
1204 /* 1: closed, no disk ("02 3A xx") */
1205 current_drive->status_bits=p1_door_closed;
1206 current_drive->open_count=0;
1207 }
1208 return (current_drive->status_bits);
1209}
1210/*==========================================================================*/
1211static int ResponseStatus(void)
1212{
1213 int i,j;
1214 u_long timeout;
1215
1216 msg(DBG_STA,"doing ResponseStatus...\n");
1217 if (famT_drive) return (get_state_T());
1218 if (flags_cmd_out & f_respo3) timeout = jiffies;
1219 else if (flags_cmd_out & f_respo2) timeout = jiffies + 16*HZ;
1220 else timeout = jiffies + 4*HZ;
1221 j=maxtim_8;
1222 do
1223 {
1224 for ( ;j!=0;j--)
1225 {
1226 i=inb(CDi_status);
1227 if (!(i&s_not_result_ready)) break;
1228 }
1229 if ((j!=0)||time_after(jiffies, timeout)) break;
1230 sbp_sleep(1);
1231 j = 1;
1232 }
1233 while (1);
1234 if (j==0)
1235 {
1236 if ((flags_cmd_out & f_respo3) == 0)
1237 msg(DBG_STA,"ResponseStatus: timeout.\n");
1238 current_drive->status_bits=0;
1239 return (-401);
1240 }
1241 i=inb(CDi_info);
1242 msg(DBG_STA,"ResponseStatus: response %02X.\n", i);
1243 EvaluateStatus(i);
1244 msg(DBG_STA,"status_bits=%02X, i=%02X\n",current_drive->status_bits,i);
1245 return (current_drive->status_bits);
1246}
1247/*==========================================================================*/
1248static void cc_ReadStatus(void)
1249{
1250 int i;
1251
1252 msg(DBG_STA,"giving cc_ReadStatus command\n");
1253 if (famT_drive) return;
1254 SBPCD_CLI;
1255 if (fam0LV_drive) OUT(CDo_command,CMD0_STATUS);
1256 else if (fam1_drive) OUT(CDo_command,CMD1_STATUS);
1257 else if (fam2_drive) OUT(CDo_command,CMD2_STATUS);
1258 if (!fam0LV_drive) for (i=0;i<6;i++) OUT(CDo_command,0);
1259 SBPCD_STI;
1260}
1261/*==========================================================================*/
1262static int cc_ReadError(void)
1263{
1264 int i;
1265
1266 clr_cmdbuf();
1267 msg(DBG_ERR,"giving cc_ReadError command.\n");
1268 if (fam1_drive)
1269 {
1270 drvcmd[0]=CMD1_READ_ERR;
1271 response_count=8;
1272 flags_cmd_out=f_putcmd|f_ResponseStatus;
1273 }
1274 else if (fam0LV_drive)
1275 {
1276 drvcmd[0]=CMD0_READ_ERR;
1277 response_count=6;
1278 if (famLV_drive)
1279 flags_cmd_out=f_putcmd;
1280 else
1281 flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus;
1282 }
1283 else if (fam2_drive)
1284 {
1285 drvcmd[0]=CMD2_READ_ERR;
1286 response_count=6;
1287 flags_cmd_out=f_putcmd;
1288 }
1289 else if (famT_drive)
1290 {
1291 response_count=5;
1292 drvcmd[0]=CMDT_READ_ERR;
1293 }
1294 i=cmd_out();
1295 current_drive->error_byte=0;
1296 msg(DBG_ERR,"cc_ReadError: cmd_out(CMDx_READ_ERR) returns %d (%02X)\n",i,i);
1297 if (i<0) return (i);
1298 if (fam0V_drive) i=1;
1299 else i=2;
1300 current_drive->error_byte=infobuf[i];
1301 msg(DBG_ERR,"cc_ReadError: infobuf[%d] is %d (%02X)\n",i,current_drive->error_byte,current_drive->error_byte);
1302 i=sta2err(infobuf[i]);
1303 if (i==-ERR_DISKCHANGE)
1304 {
1305 current_drive->CD_changed=0xFF;
1306 current_drive->diskstate_flags &= ~toc_bit;
1307 }
1308 return (i);
1309}
1310/*==========================================================================*/
1311static int cc_DriveReset(void);
1312
1313static int cmd_out_T(void)
1314{
1315#undef CMDT_TRIES
1316#define CMDT_TRIES 1000
1317#define TEST_FALSE_FF 1
1318
1319 int i, j, l=0, m, ntries;
1320 unsigned long flags;
1321
1322 current_drive->error_state=0;
1323 current_drive->b3=0;
1324 current_drive->b4=0;
1325 current_drive->f_drv_error=0;
1326 for (i=0;i<10;i++) sprintf(&msgbuf[i*3]," %02X",drvcmd[i]);
1327 msgbuf[i*3]=0;
1328 msg(DBG_CMD,"cmd_out_T:%s\n",msgbuf);
1329
1330 OUT(CDo_sel_i_d,0);
1331 OUT(CDo_enable,current_drive->drv_sel);
1332 i=inb(CDi_status);
1333 do_16bit=0;
1334 if ((f_16bit)&&(!(i&0x80)))
1335 {
1336 do_16bit=1;
1337 msg(DBG_TEA,"cmd_out_T: do_16bit set.\n");
1338 }
1339 if (!(i&s_not_result_ready))
1340 do
1341 {
1342 j=inb(CDi_info);
1343 i=inb(CDi_status);
1344 sbp_sleep(0);
1345 msg(DBG_TEA,"cmd_out_T: spurious !s_not_result_ready. (%02X)\n", j);
1346 }
1347 while (!(i&s_not_result_ready));
1348 save_flags(flags); cli();
1349 for (i=0;i<10;i++) OUT(CDo_command,drvcmd[i]);
1350 restore_flags(flags);
1351 for (ntries=CMDT_TRIES;ntries>0;ntries--)
1352 {
1353 if (drvcmd[0]==CMDT_READ_VER) sbp_sleep(HZ); /* fixme */
1354#if 01
1355 OUT(CDo_sel_i_d,1);
1356#endif /* 01 */
1357 if (teac==2)
1358 {
1359 if ((i=CDi_stat_loop_T()) == -1) break;
1360 }
1361 else
1362 {
1363#if 0
1364 OUT(CDo_sel_i_d,1);
1365#endif /* 0 */
1366 i=inb(CDi_status);
1367 }
1368 if (!(i&s_not_data_ready)) /* f.e. CMDT_DISKINFO */
1369 {
1370 OUT(CDo_sel_i_d,1);
1371 if (drvcmd[0]==CMDT_READ) return (0); /* handled elsewhere */
1372 if (drvcmd[0]==CMDT_DISKINFO)
1373 {
1374 l=0;
1375 do
1376 {
1377 if (do_16bit)
1378 {
1379 i=inw(CDi_data);
1380 infobuf[l++]=i&0x0ff;
1381 infobuf[l++]=i>>8;
1382#if TEST_FALSE_FF
1383 if ((l==2)&&(infobuf[0]==0x0ff))
1384 {
1385 infobuf[0]=infobuf[1];
1386 l=1;
1387 msg(DBG_TEA,"cmd_out_T: do_16bit: false first byte!\n");
1388 }
1389#endif /* TEST_FALSE_FF */
1390 }
1391 else infobuf[l++]=inb(CDi_data);
1392 i=inb(CDi_status);
1393 }
1394 while (!(i&s_not_data_ready));
1395 for (j=0;j<l;j++) sprintf(&msgbuf[j*3]," %02X",infobuf[j]);
1396 msgbuf[j*3]=0;
1397 msg(DBG_CMD,"cmd_out_T data response:%s\n", msgbuf);
1398 }
1399 else
1400 {
1401 msg(DBG_TEA,"cmd_out_T: data response with cmd_%02X!\n",
1402 drvcmd[0]);
1403 j=0;
1404 do
1405 {
1406 if (do_16bit) i=inw(CDi_data);
1407 else i=inb(CDi_data);
1408 j++;
1409 i=inb(CDi_status);
1410 }
1411 while (!(i&s_not_data_ready));
1412 msg(DBG_TEA,"cmd_out_T: data response: discarded %d bytes/words.\n", j);
1413 fatal_err++;
1414 }
1415 }
1416 i=inb(CDi_status);
1417 if (!(i&s_not_result_ready))
1418 {
1419 OUT(CDo_sel_i_d,0);
1420 if (drvcmd[0]==CMDT_DISKINFO) m=l;
1421 else m=0;
1422 do
1423 {
1424 infobuf[m++]=inb(CDi_info);
1425 i=inb(CDi_status);
1426 }
1427 while (!(i&s_not_result_ready));
1428 for (j=0;j<m;j++) sprintf(&msgbuf[j*3]," %02X",infobuf[j]);
1429 msgbuf[j*3]=0;
1430 msg(DBG_CMD,"cmd_out_T info response:%s\n", msgbuf);
1431 if (drvcmd[0]==CMDT_DISKINFO)
1432 {
1433 infobuf[0]=infobuf[l];
1434 if (infobuf[0]!=0x02) return (l); /* data length */
1435 }
1436 else if (infobuf[0]!=0x02) return (m); /* info length */
1437 do
1438 {
1439 ++recursion;
1440 if (recursion>1) msg(DBG_TEA,"cmd_out_T READ_ERR recursion (%02X): %d !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n", drvcmd[0], recursion);
1441 clr_cmdbuf();
1442 drvcmd[0]=CMDT_READ_ERR;
1443 j=cmd_out_T(); /* !!! recursive here !!! */
1444 --recursion;
1445 sbp_sleep(1);
1446 }
1447 while (j<0);
1448 current_drive->error_state=infobuf[2];
1449 current_drive->b3=infobuf[3];
1450 current_drive->b4=infobuf[4];
1451 if (current_drive->f_drv_error)
1452 {
1453 current_drive->f_drv_error=0;
1454 cc_DriveReset();
1455 current_drive->error_state=2;
1456 }
1457 return (-current_drive->error_state-400);
1458 }
1459 if (drvcmd[0]==CMDT_READ) return (0); /* handled elsewhere */
1460 if ((teac==0)||(ntries<(CMDT_TRIES-5))) sbp_sleep(HZ/10);
1461 else sbp_sleep(HZ/100);
1462 if (ntries>(CMDT_TRIES-50)) continue;
1463 msg(DBG_TEA,"cmd_out_T: next CMDT_TRIES (%02X): %d.\n", drvcmd[0], ntries-1);
1464 }
1465 current_drive->f_drv_error=1;
1466 cc_DriveReset();
1467 current_drive->error_state=2;
1468 return (-99);
1469}
1470/*==========================================================================*/
1471static int cmd_out(void)
1472{
1473 int i=0;
1474
1475 if (famT_drive) return(cmd_out_T());
1476
1477 if (flags_cmd_out&f_putcmd)
1478 {
1479 unsigned long flags;
1480 for (i=0;i<7;i++)
1481 sprintf(&msgbuf[i*3], " %02X", drvcmd[i]);
1482 msgbuf[i*3]=0;
1483 msg(DBG_CMD,"cmd_out:%s\n", msgbuf);
1484 save_flags(flags); cli();
1485 for (i=0;i<7;i++) OUT(CDo_command,drvcmd[i]);
1486 restore_flags(flags);
1487 }
1488 if (response_count!=0)
1489 {
1490 if (cmd_type!=0)
1491 {
1492 if (sbpro_type==1) OUT(CDo_sel_i_d,1);
1493 msg(DBG_INF,"misleaded to try ResponseData.\n");
1494 if (sbpro_type==1) OUT(CDo_sel_i_d,0);
1495 return (-22);
1496 }
1497 else i=ResponseInfo();
1498 if (i<0) return (i);
1499 }
1500 if (current_drive->in_SpinUp) msg(DBG_SPI,"in_SpinUp: to CDi_stat_loop.\n");
1501 if (flags_cmd_out&f_lopsta)
1502 {
1503 i=CDi_stat_loop();
1504 if ((i<0)||!(i&s_attention)) return (-8);
1505 }
1506 if (!(flags_cmd_out&f_getsta)) goto LOC_229;
1507
1508 LOC_228:
1509 if (current_drive->in_SpinUp) msg(DBG_SPI,"in_SpinUp: to cc_ReadStatus.\n");
1510 cc_ReadStatus();
1511
1512 LOC_229:
1513 if (flags_cmd_out&f_ResponseStatus)
1514 {
1515 if (current_drive->in_SpinUp) msg(DBG_SPI,"in_SpinUp: to ResponseStatus.\n");
1516 i=ResponseStatus();
1517 /* builds status_bits, returns orig. status or p_busy_new */
1518 if (i<0) return (i);
1519 if (flags_cmd_out&(f_bit1|f_wait_if_busy))
1520 {
1521 if (!st_check)
1522 {
1523 if ((flags_cmd_out&f_bit1)&&(i&p_success)) goto LOC_232;
1524 if ((!(flags_cmd_out&f_wait_if_busy))||(!st_busy)) goto LOC_228;
1525 }
1526 }
1527 }
1528 LOC_232:
1529 if (!(flags_cmd_out&f_obey_p_check)) return (0);
1530 if (!st_check) return (0);
1531 if (current_drive->in_SpinUp) msg(DBG_SPI,"in_SpinUp: to cc_ReadError.\n");
1532 i=cc_ReadError();
1533 if (current_drive->in_SpinUp) msg(DBG_SPI,"in_SpinUp: to cmd_out OK.\n");
1534 msg(DBG_000,"cmd_out: cc_ReadError=%d\n", i);
1535 return (i);
1536}
1537/*==========================================================================*/
1538static int cc_Seek(u_int pos, char f_blk_msf)
1539{
1540 int i;
1541
1542 clr_cmdbuf();
1543 if (f_blk_msf>1) return (-3);
1544 if (fam0V_drive)
1545 {
1546 drvcmd[0]=CMD0_SEEK;
1547 if (f_blk_msf==1) pos=msf2blk(pos);
1548 drvcmd[2]=(pos>>16)&0x00FF;
1549 drvcmd[3]=(pos>>8)&0x00FF;
1550 drvcmd[4]=pos&0x00FF;
1551 if (fam0_drive)
1552 flags_cmd_out = f_putcmd | f_respo2 | f_lopsta | f_getsta |
1553 f_ResponseStatus | f_obey_p_check | f_bit1;
1554 else
1555 flags_cmd_out = f_putcmd;
1556 }
1557 else if (fam1L_drive)
1558 {
1559 drvcmd[0]=CMD1_SEEK; /* same as CMD1_ and CMDL_ */
1560 if (f_blk_msf==0) pos=blk2msf(pos);
1561 drvcmd[1]=(pos>>16)&0x00FF;
1562 drvcmd[2]=(pos>>8)&0x00FF;
1563 drvcmd[3]=pos&0x00FF;
1564 if (famL_drive)
1565 flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta|f_ResponseStatus|f_obey_p_check|f_bit1;
1566 else
1567 flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
1568 }
1569 else if (fam2_drive)
1570 {
1571 drvcmd[0]=CMD2_SEEK;
1572 if (f_blk_msf==0) pos=blk2msf(pos);
1573 drvcmd[2]=(pos>>24)&0x00FF;
1574 drvcmd[3]=(pos>>16)&0x00FF;
1575 drvcmd[4]=(pos>>8)&0x00FF;
1576 drvcmd[5]=pos&0x00FF;
1577 flags_cmd_out=f_putcmd|f_ResponseStatus;
1578 }
1579 else if (famT_drive)
1580 {
1581 drvcmd[0]=CMDT_SEEK;
1582 if (f_blk_msf==1) pos=msf2blk(pos);
1583 drvcmd[2]=(pos>>24)&0x00FF;
1584 drvcmd[3]=(pos>>16)&0x00FF;
1585 drvcmd[4]=(pos>>8)&0x00FF;
1586 drvcmd[5]=pos&0x00FF;
1587 current_drive->n_bytes=1;
1588 }
1589 response_count=0;
1590 i=cmd_out();
1591 return (i);
1592}
1593/*==========================================================================*/
1594static int cc_SpinUp(void)
1595{
1596 int i;
1597
1598 msg(DBG_SPI,"SpinUp.\n");
1599 current_drive->in_SpinUp = 1;
1600 clr_cmdbuf();
1601 if (fam0LV_drive)
1602 {
1603 drvcmd[0]=CMD0_SPINUP;
1604 if (fam0L_drive)
1605 flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta|
1606 f_ResponseStatus|f_obey_p_check|f_bit1;
1607 else
1608 flags_cmd_out=f_putcmd;
1609 }
1610 else if (fam1_drive)
1611 {
1612 drvcmd[0]=CMD1_SPINUP;
1613 flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
1614 }
1615 else if (fam2_drive)
1616 {
1617 drvcmd[0]=CMD2_TRAY_CTL;
1618 drvcmd[4]=0x01; /* "spinup" */
1619 flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
1620 }
1621 else if (famT_drive)
1622 {
1623 drvcmd[0]=CMDT_TRAY_CTL;
1624 drvcmd[4]=0x03; /* "insert", it hopefully spins the drive up */
1625 }
1626 response_count=0;
1627 i=cmd_out();
1628 current_drive->in_SpinUp = 0;
1629 return (i);
1630}
1631/*==========================================================================*/
1632static int cc_SpinDown(void)
1633{
1634 int i;
1635
1636 if (fam0_drive) return (0);
1637 clr_cmdbuf();
1638 response_count=0;
1639 if (fam1_drive)
1640 {
1641 drvcmd[0]=CMD1_SPINDOWN;
1642 flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
1643 }
1644 else if (fam2_drive)
1645 {
1646 drvcmd[0]=CMD2_TRAY_CTL;
1647 drvcmd[4]=0x02; /* "eject" */
1648 flags_cmd_out=f_putcmd|f_ResponseStatus;
1649 }
1650 else if (famL_drive)
1651 {
1652 drvcmd[0]=CMDL_SPINDOWN;
1653 drvcmd[1]=1;
1654 flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta|f_ResponseStatus|f_obey_p_check|f_bit1;
1655 }
1656 else if (famV_drive)
1657 {
1658 drvcmd[0]=CMDV_SPINDOWN;
1659 flags_cmd_out=f_putcmd;
1660 }
1661 else if (famT_drive)
1662 {
1663 drvcmd[0]=CMDT_TRAY_CTL;
1664 drvcmd[4]=0x02; /* "eject" */
1665 }
1666 i=cmd_out();
1667 return (i);
1668}
1669/*==========================================================================*/
1670static int cc_get_mode_T(void)
1671{
1672 int i;
1673
1674 clr_cmdbuf();
1675 response_count=10;
1676 drvcmd[0]=CMDT_GETMODE;
1677 drvcmd[4]=response_count;
1678 i=cmd_out_T();
1679 return (i);
1680}
1681/*==========================================================================*/
1682static int cc_set_mode_T(void)
1683{
1684 int i;
1685
1686 clr_cmdbuf();
1687 response_count=1;
1688 drvcmd[0]=CMDT_SETMODE;
1689 drvcmd[1]=current_drive->speed_byte;
1690 drvcmd[2]=current_drive->frmsiz>>8;
1691 drvcmd[3]=current_drive->frmsiz&0x0FF;
1692 drvcmd[4]=current_drive->f_XA; /* 1: XA */
1693 drvcmd[5]=current_drive->type_byte; /* 0, 1, 3 */
1694 drvcmd[6]=current_drive->mode_xb_6;
1695 drvcmd[7]=current_drive->mode_yb_7|current_drive->volume_control;
1696 drvcmd[8]=current_drive->mode_xb_8;
1697 drvcmd[9]=current_drive->delay;
1698 i=cmd_out_T();
1699 return (i);
1700}
1701/*==========================================================================*/
1702static int cc_prep_mode_T(void)
1703{
1704 int i, j;
1705
1706 i=cc_get_mode_T();
1707 if (i<0) return (i);
1708 for (i=0;i<10;i++)
1709 sprintf(&msgbuf[i*3], " %02X", infobuf[i]);
1710 msgbuf[i*3]=0;
1711 msg(DBG_TEA,"CMDT_GETMODE:%s\n", msgbuf);
1712 current_drive->speed_byte=0x02; /* 0x02: auto quad, 0x82: quad, 0x81: double, 0x80: single */
1713 current_drive->frmsiz=make16(infobuf[2],infobuf[3]);
1714 current_drive->f_XA=infobuf[4];
1715 if (current_drive->f_XA==0) current_drive->type_byte=0;
1716 else current_drive->type_byte=1;
1717 current_drive->mode_xb_6=infobuf[6];
1718 current_drive->mode_yb_7=1;
1719 current_drive->mode_xb_8=infobuf[8];
1720 current_drive->delay=0; /* 0, 1, 2, 3 */
1721 j=cc_set_mode_T();
1722 i=cc_get_mode_T();
1723 for (i=0;i<10;i++)
1724 sprintf(&msgbuf[i*3], " %02X", infobuf[i]);
1725 msgbuf[i*3]=0;
1726 msg(DBG_TEA,"CMDT_GETMODE:%s\n", msgbuf);
1727 return (j);
1728}
1729/*==========================================================================*/
1730static int cc_SetSpeed(u_char speed, u_char x1, u_char x2)
1731{
1732 int i;
1733
1734 if (fam0LV_drive) return (0);
1735 clr_cmdbuf();
1736 response_count=0;
1737 if (fam1_drive)
1738 {
1739 drvcmd[0]=CMD1_SETMODE;
1740 drvcmd[1]=0x03;
1741 drvcmd[2]=speed;
1742 drvcmd[3]=x1;
1743 drvcmd[4]=x2;
1744 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
1745 }
1746 else if (fam2_drive)
1747 {
1748 drvcmd[0]=CMD2_SETSPEED;
1749 if (speed&speed_auto)
1750 {
1751 drvcmd[2]=0xFF;
1752 drvcmd[3]=0xFF;
1753 }
1754 else
1755 {
1756 drvcmd[2]=0;
1757 drvcmd[3]=150;
1758 }
1759 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
1760 }
1761 else if (famT_drive)
1762 {
1763 return (0);
1764 }
1765 i=cmd_out();
1766 return (i);
1767}
1768/*==========================================================================*/
1769static int cc_SetVolume(void)
1770{
1771 int i;
1772 u_char channel0,channel1,volume0,volume1;
1773 u_char control0,value0,control1,value1;
1774
1775 current_drive->diskstate_flags &= ~volume_bit;
1776 clr_cmdbuf();
1777 channel0=current_drive->vol_chan0;
1778 volume0=current_drive->vol_ctrl0;
1779 channel1=control1=current_drive->vol_chan1;
1780 volume1=value1=current_drive->vol_ctrl1;
1781 control0=value0=0;
1782
1783 if (famV_drive) return (0);
1784
1785 if (((current_drive->drv_options&audio_mono)!=0)&&(current_drive->drv_type>=drv_211))
1786 {
1787 if ((volume0!=0)&&(volume1==0))
1788 {
1789 volume1=volume0;
1790 channel1=channel0;
1791 }
1792 else if ((volume0==0)&&(volume1!=0))
1793 {
1794 volume0=volume1;
1795 channel0=channel1;
1796 }
1797 }
1798 if (channel0>1)
1799 {
1800 channel0=0;
1801 volume0=0;
1802 }
1803 if (channel1>1)
1804 {
1805 channel1=1;
1806 volume1=0;
1807 }
1808
1809 if (fam1_drive)
1810 {
1811 control0=channel0+1;
1812 control1=channel1+1;
1813 value0=(volume0>volume1)?volume0:volume1;
1814 value1=value0;
1815 if (volume0==0) control0=0;
1816 if (volume1==0) control1=0;
1817 drvcmd[0]=CMD1_SETMODE;
1818 drvcmd[1]=0x05;
1819 drvcmd[3]=control0;
1820 drvcmd[4]=value0;
1821 drvcmd[5]=control1;
1822 drvcmd[6]=value1;
1823 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
1824 }
1825 else if (fam2_drive)
1826 {
1827 control0=channel0+1;
1828 control1=channel1+1;
1829 value0=(volume0>volume1)?volume0:volume1;
1830 value1=value0;
1831 if (volume0==0) control0=0;
1832 if (volume1==0) control1=0;
1833 drvcmd[0]=CMD2_SETMODE;
1834 drvcmd[1]=0x0E;
1835 drvcmd[3]=control0;
1836 drvcmd[4]=value0;
1837 drvcmd[5]=control1;
1838 drvcmd[6]=value1;
1839 flags_cmd_out=f_putcmd|f_ResponseStatus;
1840 }
1841 else if (famL_drive)
1842 {
1843 if ((volume0==0)||(channel0!=0)) control0 |= 0x80;
1844 if ((volume1==0)||(channel1!=1)) control0 |= 0x40;
1845 if (volume0|volume1) value0=0x80;
1846 drvcmd[0]=CMDL_SETMODE;
1847 drvcmd[1]=0x03;
1848 drvcmd[4]=control0;
1849 drvcmd[5]=value0;
1850 flags_cmd_out=f_putcmd|f_lopsta|f_getsta|f_ResponseStatus|f_obey_p_check|f_bit1;
1851 }
1852 else if (fam0_drive) /* different firmware levels */
1853 {
1854 if (current_drive->drv_type>=drv_300)
1855 {
1856 control0=volume0&0xFC;
1857 value0=volume1&0xFC;
1858 if ((volume0!=0)&&(volume0<4)) control0 |= 0x04;
1859 if ((volume1!=0)&&(volume1<4)) value0 |= 0x04;
1860 if (channel0!=0) control0 |= 0x01;
1861 if (channel1==1) value0 |= 0x01;
1862 }
1863 else
1864 {
1865 value0=(volume0>volume1)?volume0:volume1;
1866 if (current_drive->drv_type<drv_211)
1867 {
1868 if (channel0!=0)
1869 {
1870 i=channel1;
1871 channel1=channel0;
1872 channel0=i;
1873 i=volume1;
1874 volume1=volume0;
1875 volume0=i;
1876 }
1877 if (channel0==channel1)
1878 {
1879 if (channel0==0)
1880 {
1881 channel1=1;
1882 volume1=0;
1883 volume0=value0;
1884 }
1885 else
1886 {
1887 channel0=0;
1888 volume0=0;
1889 volume1=value0;
1890 }
1891 }
1892 }
1893
1894 if ((volume0!=0)&&(volume1!=0))
1895 {
1896 if (volume0==0xFF) volume1=0xFF;
1897 else if (volume1==0xFF) volume0=0xFF;
1898 }
1899 else if (current_drive->drv_type<drv_201) volume0=volume1=value0;
1900
1901 if (current_drive->drv_type>=drv_201)
1902 {
1903 if (volume0==0) control0 |= 0x80;
1904 if (volume1==0) control0 |= 0x40;
1905 }
1906 if (current_drive->drv_type>=drv_211)
1907 {
1908 if (channel0!=0) control0 |= 0x20;
1909 if (channel1!=1) control0 |= 0x10;
1910 }
1911 }
1912 drvcmd[0]=CMD0_SETMODE;
1913 drvcmd[1]=0x83;
1914 drvcmd[4]=control0;
1915 drvcmd[5]=value0;
1916 flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
1917 }
1918 else if (famT_drive)
1919 {
1920 current_drive->volume_control=0;
1921 if (!volume0) current_drive->volume_control|=0x10;
1922 if (!volume1) current_drive->volume_control|=0x20;
1923 i=cc_prep_mode_T();
1924 if (i<0) return (i);
1925 }
1926 if (!famT_drive)
1927 {
1928 response_count=0;
1929 i=cmd_out();
1930 if (i<0) return (i);
1931 }
1932 current_drive->diskstate_flags |= volume_bit;
1933 return (0);
1934}
1935/*==========================================================================*/
1936static int GetStatus(void)
1937{
1938 int i;
1939
1940 if (famT_drive) return (0);
1941 flags_cmd_out=f_getsta|f_ResponseStatus|f_obey_p_check;
1942 response_count=0;
1943 cmd_type=0;
1944 i=cmd_out();
1945 return (i);
1946}
1947/*==========================================================================*/
1948static int cc_DriveReset(void)
1949{
1950 int i;
1951
1952 msg(DBG_RES,"cc_DriveReset called.\n");
1953 clr_cmdbuf();
1954 response_count=0;
1955 if (fam0LV_drive) OUT(CDo_reset,0x00);
1956 else if (fam1_drive)
1957 {
1958 drvcmd[0]=CMD1_RESET;
1959 flags_cmd_out=f_putcmd;
1960 i=cmd_out();
1961 }
1962 else if (fam2_drive)
1963 {
1964 drvcmd[0]=CMD2_RESET;
1965 flags_cmd_out=f_putcmd;
1966 i=cmd_out();
1967 OUT(CDo_reset,0x00);
1968 }
1969 else if (famT_drive)
1970 {
1971 OUT(CDo_sel_i_d,0);
1972 OUT(CDo_enable,current_drive->drv_sel);
1973 OUT(CDo_command,CMDT_RESET);
1974 for (i=1;i<10;i++) OUT(CDo_command,0);
1975 }
1976 if (fam0LV_drive) sbp_sleep(5*HZ); /* wait 5 seconds */
1977 else sbp_sleep(1*HZ); /* wait a second */
1978#if 1
1979 if (famT_drive)
1980 {
1981 msg(DBG_TEA, "================CMDT_RESET given=================.\n");
1982 sbp_sleep(3*HZ);
1983 }
1984#endif /* 1 */
1985 flush_status();
1986 i=GetStatus();
1987 if (i<0) return i;
1988 if (!famT_drive)
1989 if (current_drive->error_byte!=aud_12) return -501;
1990 return (0);
1991}
1992
1993/*==========================================================================*/
1994static int SetSpeed(void)
1995{
1996 int i, speed;
1997
1998 if (!(current_drive->drv_options&(speed_auto|speed_300|speed_150))) return (0);
1999 speed=speed_auto;
2000 if (!(current_drive->drv_options&speed_auto))
2001 {
2002 speed |= speed_300;
2003 if (!(current_drive->drv_options&speed_300)) speed=0;
2004 }
2005 i=cc_SetSpeed(speed,0,0);
2006 return (i);
2007}
2008
2009static void switch_drive(struct sbpcd_drive *);
2010
2011static int sbpcd_select_speed(struct cdrom_device_info *cdi, int speed)
2012{
2013 struct sbpcd_drive *p = cdi->handle;
2014 if (p != current_drive)
2015 switch_drive(p);
2016
2017 return cc_SetSpeed(speed == 2 ? speed_300 : speed_150, 0, 0);
2018}
2019
2020/*==========================================================================*/
2021static int DriveReset(void)
2022{
2023 int i;
2024
2025 i=cc_DriveReset();
2026 if (i<0) return (-22);
2027 do
2028 {
2029 i=GetStatus();
2030 if ((i<0)&&(i!=-ERR_DISKCHANGE)) {
2031 return (-2); /* from sta2err */
2032 }
2033 if (!st_caddy_in) break;
2034 sbp_sleep(1);
2035 }
2036 while (!st_diskok);
2037#if 000
2038 current_drive->CD_changed=1;
2039#endif
2040 if ((st_door_closed) && (st_caddy_in))
2041 {
2042 i=DiskInfo();
2043 if (i<0) return (-23);
2044 }
2045 return (0);
2046}
2047
2048static int sbpcd_reset(struct cdrom_device_info *cdi)
2049{
2050 struct sbpcd_drive *p = cdi->handle;
2051 if (p != current_drive)
2052 switch_drive(p);
2053 return DriveReset();
2054}
2055
2056/*==========================================================================*/
2057static int cc_PlayAudio(int pos_audio_start,int pos_audio_end)
2058{
2059 int i, j, n;
2060
2061 if (current_drive->audio_state==audio_playing) return (-EINVAL);
2062 clr_cmdbuf();
2063 response_count=0;
2064 if (famLV_drive)
2065 {
2066 drvcmd[0]=CMDL_PLAY;
2067 i=msf2blk(pos_audio_start);
2068 n=msf2blk(pos_audio_end)+1-i;
2069 drvcmd[1]=(i>>16)&0x00FF;
2070 drvcmd[2]=(i>>8)&0x00FF;
2071 drvcmd[3]=i&0x00FF;
2072 drvcmd[4]=(n>>16)&0x00FF;
2073 drvcmd[5]=(n>>8)&0x00FF;
2074 drvcmd[6]=n&0x00FF;
2075 if (famL_drive)
2076 flags_cmd_out = f_putcmd | f_respo2 | f_lopsta | f_getsta |
2077 f_ResponseStatus | f_obey_p_check | f_wait_if_busy;
2078 else
2079 flags_cmd_out = f_putcmd;
2080 }
2081 else
2082 {
2083 j=1;
2084 if (fam1_drive)
2085 {
2086 drvcmd[0]=CMD1_PLAY_MSF;
2087 flags_cmd_out = f_putcmd | f_respo2 | f_ResponseStatus |
2088 f_obey_p_check | f_wait_if_busy;
2089 }
2090 else if (fam2_drive)
2091 {
2092 drvcmd[0]=CMD2_PLAY_MSF;
2093 flags_cmd_out = f_putcmd | f_ResponseStatus | f_obey_p_check;
2094 }
2095 else if (famT_drive)
2096 {
2097 drvcmd[0]=CMDT_PLAY_MSF;
2098 j=3;
2099 response_count=1;
2100 }
2101 else if (fam0_drive)
2102 {
2103 drvcmd[0]=CMD0_PLAY_MSF;
2104 flags_cmd_out = f_putcmd | f_respo2 | f_lopsta | f_getsta |
2105 f_ResponseStatus | f_obey_p_check | f_wait_if_busy;
2106 }
2107 drvcmd[j]=(pos_audio_start>>16)&0x00FF;
2108 drvcmd[j+1]=(pos_audio_start>>8)&0x00FF;
2109 drvcmd[j+2]=pos_audio_start&0x00FF;
2110 drvcmd[j+3]=(pos_audio_end>>16)&0x00FF;
2111 drvcmd[j+4]=(pos_audio_end>>8)&0x00FF;
2112 drvcmd[j+5]=pos_audio_end&0x00FF;
2113 }
2114 i=cmd_out();
2115 return (i);
2116}
2117/*==========================================================================*/
2118static int cc_Pause_Resume(int pau_res)
2119{
2120 int i;
2121
2122 clr_cmdbuf();
2123 response_count=0;
2124 if (fam1_drive)
2125 {
2126 drvcmd[0]=CMD1_PAU_RES;
2127 if (pau_res!=1) drvcmd[1]=0x80;
2128 flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
2129 }
2130 else if (fam2_drive)
2131 {
2132 drvcmd[0]=CMD2_PAU_RES;
2133 if (pau_res!=1) drvcmd[2]=0x01;
2134 flags_cmd_out=f_putcmd|f_ResponseStatus;
2135 }
2136 else if (fam0LV_drive)
2137 {
2138 drvcmd[0]=CMD0_PAU_RES;
2139 if (pau_res!=1) drvcmd[1]=0x80;
2140 if (famL_drive)
2141 flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta|f_ResponseStatus|
2142 f_obey_p_check|f_bit1;
2143 else if (famV_drive)
2144 flags_cmd_out=f_putcmd;
2145 else
2146 flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta|f_ResponseStatus|
2147 f_obey_p_check;
2148 }
2149 else if (famT_drive)
2150 {
2151 if (pau_res==3) return (cc_PlayAudio(current_drive->pos_audio_start,current_drive->pos_audio_end));
2152 else if (pau_res==1) drvcmd[0]=CMDT_PAUSE;
2153 else return (-56);
2154 }
2155 i=cmd_out();
2156 return (i);
2157}
2158/*==========================================================================*/
2159static int cc_LockDoor(char lock)
2160{
2161 int i;
2162
2163 if (fam0_drive) return (0);
2164 msg(DBG_LCK,"cc_LockDoor: %d (drive %d)\n", lock, current_drive - D_S);
2165 msg(DBG_LCS,"p_door_locked bit %d before\n", st_door_locked);
2166 clr_cmdbuf();
2167 response_count=0;
2168 if (fam1_drive)
2169 {
2170 drvcmd[0]=CMD1_LOCK_CTL;
2171 if (lock==1) drvcmd[1]=0x01;
2172 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
2173 }
2174 else if (fam2_drive)
2175 {
2176 drvcmd[0]=CMD2_LOCK_CTL;
2177 if (lock==1) drvcmd[4]=0x01;
2178 flags_cmd_out=f_putcmd|f_ResponseStatus;
2179 }
2180 else if (famLV_drive)
2181 {
2182 drvcmd[0]=CMDL_LOCK_CTL;
2183 if (lock==1) drvcmd[1]=0x01;
2184 if (famL_drive)
2185 flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta|f_ResponseStatus|f_obey_p_check|f_bit1;
2186 else
2187 flags_cmd_out=f_putcmd;
2188 }
2189 else if (famT_drive)
2190 {
2191 drvcmd[0]=CMDT_LOCK_CTL;
2192 if (lock==1) drvcmd[4]=0x01;
2193 }
2194 i=cmd_out();
2195 msg(DBG_LCS,"p_door_locked bit %d after\n", st_door_locked);
2196 return (i);
2197}
2198/*==========================================================================*/
2199/*==========================================================================*/
2200static int UnLockDoor(void)
2201{
2202 int i,j;
2203
2204 j=20;
2205 do
2206 {
2207 i=cc_LockDoor(0);
2208 --j;
2209 sbp_sleep(1);
2210 }
2211 while ((i<0)&&(j));
2212 if (i<0)
2213 {
2214 cc_DriveReset();
2215 return -84;
2216 }
2217 return (0);
2218}
2219/*==========================================================================*/
2220static int LockDoor(void)
2221{
2222 int i,j;
2223
2224 j=20;
2225 do
2226 {
2227 i=cc_LockDoor(1);
2228 --j;
2229 sbp_sleep(1);
2230 }
2231 while ((i<0)&&(j));
2232 if (j==0)
2233 {
2234 cc_DriveReset();
2235 j=20;
2236 do
2237 {
2238 i=cc_LockDoor(1);
2239 --j;
2240 sbp_sleep(1);
2241 }
2242 while ((i<0)&&(j));
2243 }
2244 return (i);
2245}
2246
2247static int sbpcd_lock_door(struct cdrom_device_info *cdi, int lock)
2248{
2249 return lock ? LockDoor() : UnLockDoor();
2250}
2251
2252/*==========================================================================*/
2253static int cc_CloseTray(void)
2254{
2255 int i;
2256
2257 if (fam0_drive) return (0);
2258 msg(DBG_LCK,"cc_CloseTray (drive %d)\n", current_drive - D_S);
2259 msg(DBG_LCS,"p_door_closed bit %d before\n", st_door_closed);
2260
2261 clr_cmdbuf();
2262 response_count=0;
2263 if (fam1_drive)
2264 {
2265 drvcmd[0]=CMD1_TRAY_CTL;
2266 flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
2267 }
2268 else if (fam2_drive)
2269 {
2270 drvcmd[0]=CMD2_TRAY_CTL;
2271 drvcmd[1]=0x01;
2272 drvcmd[4]=0x03; /* "insert" */
2273 flags_cmd_out=f_putcmd|f_ResponseStatus;
2274 }
2275 else if (famLV_drive)
2276 {
2277 drvcmd[0]=CMDL_TRAY_CTL;
2278 if (famLV_drive)
2279 flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta|
2280 f_ResponseStatus|f_obey_p_check|f_bit1;
2281 else
2282 flags_cmd_out=f_putcmd;
2283 }
2284 else if (famT_drive)
2285 {
2286 drvcmd[0]=CMDT_TRAY_CTL;
2287 drvcmd[4]=0x03; /* "insert" */
2288 }
2289 i=cmd_out();
2290 msg(DBG_LCS,"p_door_closed bit %d after\n", st_door_closed);
2291
2292 i=cc_ReadError();
2293 flags_cmd_out |= f_respo2;
2294 cc_ReadStatus(); /* command: give 1-byte status */
2295 i=ResponseStatus();
2296 if (famT_drive&&(i<0))
2297 {
2298 cc_DriveReset();
2299 i=ResponseStatus();
2300#if 0
2301 sbp_sleep(HZ);
2302#endif /* 0 */
2303 i=ResponseStatus();
2304 }
2305 if (i<0)
2306 {
2307 msg(DBG_INF,"sbpcd cc_CloseTray: ResponseStatus timed out (%d).\n",i);
2308 }
2309 if (!(famT_drive))
2310 {
2311 if (!st_spinning)
2312 {
2313 cc_SpinUp();
2314 if (st_check) i=cc_ReadError();
2315 flags_cmd_out |= f_respo2;
2316 cc_ReadStatus();
2317 i=ResponseStatus();
2318 } else {
2319 }
2320 }
2321 i=DiskInfo();
2322 return (i);
2323}
2324
2325static int sbpcd_tray_move(struct cdrom_device_info *cdi, int position)
2326{
2327 int retval=0;
2328 switch_drive(cdi->handle);
2329 /* DUH! --AJK */
2330 if(current_drive->CD_changed != 0xFF) {
2331 current_drive->CD_changed=0xFF;
2332 current_drive->diskstate_flags &= ~cd_size_bit;
2333 }
2334 if (position == 1) {
2335 cc_SpinDown();
2336 } else {
2337 retval=cc_CloseTray();
2338 }
2339 return retval;
2340}
2341
2342/*==========================================================================*/
2343static int cc_ReadSubQ(void)
2344{
2345 int i,j;
2346
2347 current_drive->diskstate_flags &= ~subq_bit;
2348 for (j=255;j>0;j--)
2349 {
2350 clr_cmdbuf();
2351 if (fam1_drive)
2352 {
2353 drvcmd[0]=CMD1_READSUBQ;
2354 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
2355 response_count=11;
2356 }
2357 else if (fam2_drive)
2358 {
2359 drvcmd[0]=CMD2_READSUBQ;
2360 drvcmd[1]=0x02;
2361 drvcmd[3]=0x01;
2362 flags_cmd_out=f_putcmd;
2363 response_count=10;
2364 }
2365 else if (fam0LV_drive)
2366 {
2367 drvcmd[0]=CMD0_READSUBQ;
2368 drvcmd[1]=0x02;
2369 if (famLV_drive)
2370 flags_cmd_out=f_putcmd;
2371 else
2372 flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
2373 response_count=13;
2374 }
2375 else if (famT_drive)
2376 {
2377 response_count=12;
2378 drvcmd[0]=CMDT_READSUBQ;
2379 drvcmd[1]=0x02;
2380 drvcmd[2]=0x40;
2381 drvcmd[3]=0x01;
2382 drvcmd[8]=response_count;
2383 }
2384 i=cmd_out();
2385 if (i<0) return (i);
2386 for (i=0;i<response_count;i++)
2387 {
2388 sprintf(&msgbuf[i*3], " %02X", infobuf[i]);
2389 msgbuf[i*3]=0;
2390 msg(DBG_SQ1,"cc_ReadSubQ:%s\n", msgbuf);
2391 }
2392 if (famT_drive) break;
2393 if (infobuf[0]!=0) break;
2394 if ((!st_spinning) || (j==1))
2395 {
2396 current_drive->SubQ_ctl_adr=current_drive->SubQ_trk=current_drive->SubQ_pnt_idx=current_drive->SubQ_whatisthis=0;
2397 current_drive->SubQ_run_tot=current_drive->SubQ_run_trk=0;
2398 return (0);
2399 }
2400 }
2401 if (famT_drive) current_drive->SubQ_ctl_adr=infobuf[1];
2402 else current_drive->SubQ_ctl_adr=swap_nibbles(infobuf[1]);
2403 current_drive->SubQ_trk=byt2bcd(infobuf[2]);
2404 current_drive->SubQ_pnt_idx=byt2bcd(infobuf[3]);
2405 if (fam0LV_drive) i=5;
2406 else if (fam12_drive) i=4;
2407 else if (famT_drive) i=8;
2408 current_drive->SubQ_run_tot=make32(make16(0,infobuf[i]),make16(infobuf[i+1],infobuf[i+2])); /* msf-bin */
2409 i=7;
2410 if (fam0LV_drive) i=9;
2411 else if (fam12_drive) i=7;
2412 else if (famT_drive) i=4;
2413 current_drive->SubQ_run_trk=make32(make16(0,infobuf[i]),make16(infobuf[i+1],infobuf[i+2])); /* msf-bin */
2414 current_drive->SubQ_whatisthis=infobuf[i+3];
2415 current_drive->diskstate_flags |= subq_bit;
2416 return (0);
2417}
2418/*==========================================================================*/
2419static int cc_ModeSense(void)
2420{
2421 int i;
2422
2423 if (fam2_drive) return (0);
2424 if (famV_drive) return (0);
2425 current_drive->diskstate_flags &= ~frame_size_bit;
2426 clr_cmdbuf();
2427 if (fam1_drive)
2428 {
2429 response_count=5;
2430 drvcmd[0]=CMD1_GETMODE;
2431 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
2432 }
2433 else if (fam0L_drive)
2434 {
2435 response_count=2;
2436 drvcmd[0]=CMD0_GETMODE;
2437 if (famL_drive) flags_cmd_out=f_putcmd;
2438 else flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
2439 }
2440 else if (famT_drive)
2441 {
2442 response_count=10;
2443 drvcmd[0]=CMDT_GETMODE;
2444 drvcmd[4]=response_count;
2445 }
2446 i=cmd_out();
2447 if (i<0) return (i);
2448 i=0;
2449 current_drive->sense_byte=0;
2450 if (fam1_drive) current_drive->sense_byte=infobuf[i++];
2451 else if (famT_drive)
2452 {
2453 if (infobuf[4]==0x01) current_drive->xa_byte=0x20;
2454 else current_drive->xa_byte=0;
2455 i=2;
2456 }
2457 current_drive->frame_size=make16(infobuf[i],infobuf[i+1]);
2458 for (i=0;i<response_count;i++)
2459 sprintf(&msgbuf[i*3], " %02X", infobuf[i]);
2460 msgbuf[i*3]=0;
2461 msg(DBG_XA1,"cc_ModeSense:%s\n", msgbuf);
2462
2463 current_drive->diskstate_flags |= frame_size_bit;
2464 return (0);
2465}
2466/*==========================================================================*/
2467/*==========================================================================*/
2468static int cc_ModeSelect(int framesize)
2469{
2470 int i;
2471
2472 if (fam2_drive) return (0);
2473 if (famV_drive) return (0);
2474 current_drive->diskstate_flags &= ~frame_size_bit;
2475 clr_cmdbuf();
2476 current_drive->frame_size=framesize;
2477 if (framesize==CD_FRAMESIZE_RAW) current_drive->sense_byte=0x82;
2478 else current_drive->sense_byte=0x00;
2479
2480 msg(DBG_XA1,"cc_ModeSelect: %02X %04X\n",
2481 current_drive->sense_byte, current_drive->frame_size);
2482
2483 if (fam1_drive)
2484 {
2485 drvcmd[0]=CMD1_SETMODE;
2486 drvcmd[1]=0x00;
2487 drvcmd[2]=current_drive->sense_byte;
2488 drvcmd[3]=(current_drive->frame_size>>8)&0xFF;
2489 drvcmd[4]=current_drive->frame_size&0xFF;
2490 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
2491 }
2492 else if (fam0L_drive)
2493 {
2494 drvcmd[0]=CMD0_SETMODE;
2495 drvcmd[1]=0x00;
2496 drvcmd[2]=(current_drive->frame_size>>8)&0xFF;
2497 drvcmd[3]=current_drive->frame_size&0xFF;
2498 drvcmd[4]=0x00;
2499 if(famL_drive)
2500 flags_cmd_out=f_putcmd|f_lopsta|f_getsta|f_ResponseStatus|f_obey_p_check;
2501 else
2502 flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
2503 }
2504 else if (famT_drive)
2505 {
2506 return (-1);
2507 }
2508 response_count=0;
2509 i=cmd_out();
2510 if (i<0) return (i);
2511 current_drive->diskstate_flags |= frame_size_bit;
2512 return (0);
2513}
2514/*==========================================================================*/
2515static int cc_GetVolume(void)
2516{
2517 int i;
2518 u_char switches;
2519 u_char chan0=0;
2520 u_char vol0=0;
2521 u_char chan1=1;
2522 u_char vol1=0;
2523
2524 if (famV_drive) return (0);
2525 current_drive->diskstate_flags &= ~volume_bit;
2526 clr_cmdbuf();
2527 if (fam1_drive)
2528 {
2529 drvcmd[0]=CMD1_GETMODE;
2530 drvcmd[1]=0x05;
2531 response_count=5;
2532 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
2533 }
2534 else if (fam2_drive)
2535 {
2536 drvcmd[0]=CMD2_GETMODE;
2537 drvcmd[1]=0x0E;
2538 response_count=5;
2539 flags_cmd_out=f_putcmd;
2540 }
2541 else if (fam0L_drive)
2542 {
2543 drvcmd[0]=CMD0_GETMODE;
2544 drvcmd[1]=0x03;
2545 response_count=2;
2546 if(famL_drive)
2547 flags_cmd_out=f_putcmd;
2548 else
2549 flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
2550 }
2551 else if (famT_drive)
2552 {
2553 i=cc_get_mode_T();
2554 if (i<0) return (i);
2555 }
2556 if (!famT_drive)
2557 {
2558 i=cmd_out();
2559 if (i<0) return (i);
2560 }
2561 if (fam1_drive)
2562 {
2563 chan0=infobuf[1]&0x0F;
2564 vol0=infobuf[2];
2565 chan1=infobuf[3]&0x0F;
2566 vol1=infobuf[4];
2567 if (chan0==0)
2568 {
2569 chan0=1;
2570 vol0=0;
2571 }
2572 if (chan1==0)
2573 {
2574 chan1=2;
2575 vol1=0;
2576 }
2577 chan0 >>= 1;
2578 chan1 >>= 1;
2579 }
2580 else if (fam2_drive)
2581 {
2582 chan0=infobuf[1];
2583 vol0=infobuf[2];
2584 chan1=infobuf[3];
2585 vol1=infobuf[4];
2586 }
2587 else if (famL_drive)
2588 {
2589 chan0=0;
2590 chan1=1;
2591 vol0=vol1=infobuf[1];
2592 switches=infobuf[0];
2593 if ((switches&0x80)!=0) chan0=1;
2594 if ((switches&0x40)!=0) chan1=0;
2595 }
2596 else if (fam0_drive) /* different firmware levels */
2597 {
2598 chan0=0;
2599 chan1=1;
2600 vol0=vol1=infobuf[1];
2601 if (current_drive->drv_type>=drv_201)
2602 {
2603 if (current_drive->drv_type<drv_300)
2604 {
2605 switches=infobuf[0];
2606 if ((switches&0x80)!=0) vol0=0;
2607 if ((switches&0x40)!=0) vol1=0;
2608 if (current_drive->drv_type>=drv_211)
2609 {
2610 if ((switches&0x20)!=0) chan0=1;
2611 if ((switches&0x10)!=0) chan1=0;
2612 }
2613 }
2614 else
2615 {
2616 vol0=infobuf[0];
2617 if ((vol0&0x01)!=0) chan0=1;
2618 if ((vol1&0x01)==0) chan1=0;
2619 vol0 &= 0xFC;
2620 vol1 &= 0xFC;
2621 if (vol0!=0) vol0 += 3;
2622 if (vol1!=0) vol1 += 3;
2623 }
2624 }
2625 }
2626 else if (famT_drive)
2627 {
2628 current_drive->volume_control=infobuf[7];
2629 chan0=0;
2630 chan1=1;
2631 if (current_drive->volume_control&0x10) vol0=0;
2632 else vol0=0xff;
2633 if (current_drive->volume_control&0x20) vol1=0;
2634 else vol1=0xff;
2635 }
2636 current_drive->vol_chan0=chan0;
2637 current_drive->vol_ctrl0=vol0;
2638 current_drive->vol_chan1=chan1;
2639 current_drive->vol_ctrl1=vol1;
2640#if 000
2641 current_drive->vol_chan2=2;
2642 current_drive->vol_ctrl2=0xFF;
2643 current_drive->vol_chan3=3;
2644 current_drive->vol_ctrl3=0xFF;
2645#endif /* 000 */
2646 current_drive->diskstate_flags |= volume_bit;
2647 return (0);
2648}
2649/*==========================================================================*/
2650static int cc_ReadCapacity(void)
2651{
2652 int i, j;
2653
2654 if (fam2_drive) return (0); /* some firmware lacks this command */
2655 if (famLV_drive) return (0); /* some firmware lacks this command */
2656 if (famT_drive) return (0); /* done with cc_ReadTocDescr() */
2657 current_drive->diskstate_flags &= ~cd_size_bit;
2658 for (j=3;j>0;j--)
2659 {
2660 clr_cmdbuf();
2661 if (fam1_drive)
2662 {
2663 drvcmd[0]=CMD1_CAPACITY;
2664 response_count=5;
2665 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
2666 }
2667#if 00
2668 else if (fam2_drive)
2669 {
2670 drvcmd[0]=CMD2_CAPACITY;
2671 response_count=8;
2672 flags_cmd_out=f_putcmd;
2673 }
2674#endif
2675 else if (fam0_drive)
2676 {
2677 drvcmd[0]=CMD0_CAPACITY;
2678 response_count=5;
2679 flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
2680 }
2681 i=cmd_out();
2682 if (i>=0) break;
2683 msg(DBG_000,"cc_ReadCapacity: cmd_out: err %d\n", i);
2684 cc_ReadError();
2685 }
2686 if (j==0) return (i);
2687 if (fam1_drive) current_drive->CDsize_frm=msf2blk(make32(make16(0,infobuf[0]),make16(infobuf[1],infobuf[2])))+CD_MSF_OFFSET;
2688 else if (fam0_drive) current_drive->CDsize_frm=make32(make16(0,infobuf[0]),make16(infobuf[1],infobuf[2]));
2689#if 00
2690 else if (fam2_drive) current_drive->CDsize_frm=make32(make16(infobuf[0],infobuf[1]),make16(infobuf[2],infobuf[3]));
2691#endif
2692 current_drive->diskstate_flags |= cd_size_bit;
2693 msg(DBG_000,"cc_ReadCapacity: %d frames.\n", current_drive->CDsize_frm);
2694 return (0);
2695}
2696/*==========================================================================*/
2697static int cc_ReadTocDescr(void)
2698{
2699 int i;
2700
2701 current_drive->diskstate_flags &= ~toc_bit;
2702 clr_cmdbuf();
2703 if (fam1_drive)
2704 {
2705 drvcmd[0]=CMD1_DISKINFO;
2706 response_count=6;
2707 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
2708 }
2709 else if (fam0LV_drive)
2710 {
2711 drvcmd[0]=CMD0_DISKINFO;
2712 response_count=6;
2713 if(famLV_drive)
2714 flags_cmd_out=f_putcmd;
2715 else
2716 flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
2717 }
2718 else if (fam2_drive)
2719 {
2720 /* possibly longer timeout periods necessary */
2721 current_drive->f_multisession=0;
2722 drvcmd[0]=CMD2_DISKINFO;
2723 drvcmd[1]=0x02;
2724 drvcmd[2]=0xAB;
2725 drvcmd[3]=0xFF; /* session */
2726 response_count=8;
2727 flags_cmd_out=f_putcmd;
2728 }
2729 else if (famT_drive)
2730 {
2731 current_drive->f_multisession=0;
2732 response_count=12;
2733 drvcmd[0]=CMDT_DISKINFO;
2734 drvcmd[1]=0x02;
2735 drvcmd[6]=CDROM_LEADOUT;
2736 drvcmd[8]=response_count;
2737 drvcmd[9]=0x00;
2738 }
2739 i=cmd_out();
2740 if (i<0) return (i);
2741 if ((famT_drive)&&(i<response_count)) return (-100-i);
2742 if ((fam1_drive)||(fam2_drive)||(fam0LV_drive))
2743 current_drive->xa_byte=infobuf[0];
2744 if (fam2_drive)
2745 {
2746 current_drive->first_session=infobuf[1];
2747 current_drive->last_session=infobuf[2];
2748 current_drive->n_first_track=infobuf[3];
2749 current_drive->n_last_track=infobuf[4];
2750 if (current_drive->first_session!=current_drive->last_session)
2751 {
2752 current_drive->f_multisession=1;
2753 current_drive->lba_multi=msf2blk(make32(make16(0,infobuf[5]),make16(infobuf[6],infobuf[7])));
2754 }
2755#if 0
2756 if (current_drive->first_session!=current_drive->last_session)
2757 {
2758 if (current_drive->last_session<=20)
2759 zwanzig=current_drive->last_session+1;
2760 else zwanzig=20;
2761 for (count=current_drive->first_session;count<zwanzig;count++)
2762 {
2763 drvcmd[0]=CMD2_DISKINFO;
2764 drvcmd[1]=0x02;
2765 drvcmd[2]=0xAB;
2766 drvcmd[3]=count;
2767 response_count=8;
2768 flags_cmd_out=f_putcmd;
2769 i=cmd_out();
2770 if (i<0) return (i);
2771 current_drive->msf_multi_n[count]=make32(make16(0,infobuf[5]),make16(infobuf[6],infobuf[7]));
2772 }
2773 current_drive->diskstate_flags |= multisession_bit;
2774 }
2775#endif
2776 drvcmd[0]=CMD2_DISKINFO;
2777 drvcmd[1]=0x02;
2778 drvcmd[2]=0xAA;
2779 drvcmd[3]=0xFF;
2780 response_count=5;
2781 flags_cmd_out=f_putcmd;
2782 i=cmd_out();
2783 if (i<0) return (i);
2784 current_drive->size_msf=make32(make16(0,infobuf[2]),make16(infobuf[3],infobuf[4]));
2785 current_drive->size_blk=msf2blk(current_drive->size_msf);
2786 current_drive->CDsize_frm=current_drive->size_blk+1;
2787 }
2788 else if (famT_drive)
2789 {
2790 current_drive->size_msf=make32(make16(infobuf[8],infobuf[9]),make16(infobuf[10],infobuf[11]));
2791 current_drive->size_blk=msf2blk(current_drive->size_msf);
2792 current_drive->CDsize_frm=current_drive->size_blk+1;
2793 current_drive->n_first_track=infobuf[2];
2794 current_drive->n_last_track=infobuf[3];
2795 }
2796 else
2797 {
2798 current_drive->n_first_track=infobuf[1];
2799 current_drive->n_last_track=infobuf[2];
2800 current_drive->size_msf=make32(make16(0,infobuf[3]),make16(infobuf[4],infobuf[5]));
2801 current_drive->size_blk=msf2blk(current_drive->size_msf);
2802 if (famLV_drive) current_drive->CDsize_frm=current_drive->size_blk+1;
2803 }
2804 current_drive->diskstate_flags |= toc_bit;
2805 msg(DBG_TOC,"TocDesc: xa %02X firstt %02X lastt %02X size %08X firstses %02X lastsess %02X\n",
2806 current_drive->xa_byte,
2807 current_drive->n_first_track,
2808 current_drive->n_last_track,
2809 current_drive->size_msf,
2810 current_drive->first_session,
2811 current_drive->last_session);
2812 return (0);
2813}
2814/*==========================================================================*/
2815static int cc_ReadTocEntry(int num)
2816{
2817 int i;
2818
2819 clr_cmdbuf();
2820 if (fam1_drive)
2821 {
2822 drvcmd[0]=CMD1_READTOC;
2823 drvcmd[2]=num;
2824 response_count=8;
2825 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
2826 }
2827 else if (fam2_drive)
2828 {
2829 /* possibly longer timeout periods necessary */
2830 drvcmd[0]=CMD2_DISKINFO;
2831 drvcmd[1]=0x02;
2832 drvcmd[2]=num;
2833 response_count=5;
2834 flags_cmd_out=f_putcmd;
2835 }
2836 else if (fam0LV_drive)
2837 {
2838 drvcmd[0]=CMD0_READTOC;
2839 drvcmd[1]=0x02;
2840 drvcmd[2]=num;
2841 response_count=8;
2842 if (famLV_drive)
2843 flags_cmd_out=f_putcmd;
2844 else
2845 flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
2846 }
2847 else if (famT_drive)
2848 {
2849 response_count=12;
2850 drvcmd[0]=CMDT_DISKINFO;
2851 drvcmd[1]=0x02;
2852 drvcmd[6]=num;
2853 drvcmd[8]=response_count;
2854 drvcmd[9]=0x00;
2855 }
2856 i=cmd_out();
2857 if (i<0) return (i);
2858 if ((famT_drive)&&(i<response_count)) return (-100-i);
2859 if ((fam1_drive)||(fam0LV_drive))
2860 {
2861 current_drive->TocEnt_nixbyte=infobuf[0];
2862 i=1;
2863 }
2864 else if (fam2_drive) i=0;
2865 else if (famT_drive) i=5;
2866 current_drive->TocEnt_ctl_adr=swap_nibbles(infobuf[i++]);
2867 if ((fam1_drive)||(fam0L_drive))
2868 {
2869 current_drive->TocEnt_number=infobuf[i++];
2870 current_drive->TocEnt_format=infobuf[i];
2871 }
2872 else
2873 {
2874 current_drive->TocEnt_number=num;
2875 current_drive->TocEnt_format=0;
2876 }
2877 if (fam1_drive) i=4;
2878 else if (fam0LV_drive) i=5;
2879 else if (fam2_drive) i=2;
2880 else if (famT_drive) i=9;
2881 current_drive->TocEnt_address=make32(make16(0,infobuf[i]),
2882 make16(infobuf[i+1],infobuf[i+2]));
2883 for (i=0;i<response_count;i++)
2884 sprintf(&msgbuf[i*3], " %02X", infobuf[i]);
2885 msgbuf[i*3]=0;
2886 msg(DBG_ECS,"TocEntry:%s\n", msgbuf);
2887 msg(DBG_TOC,"TocEntry: %02X %02X %02X %02X %08X\n",
2888 current_drive->TocEnt_nixbyte, current_drive->TocEnt_ctl_adr,
2889 current_drive->TocEnt_number, current_drive->TocEnt_format,
2890 current_drive->TocEnt_address);
2891 return (0);
2892}
2893/*==========================================================================*/
2894static int cc_ReadPacket(void)
2895{
2896 int i;
2897
2898 clr_cmdbuf();
2899 drvcmd[0]=CMD0_PACKET;
2900 drvcmd[1]=response_count;
2901 if(famL_drive) flags_cmd_out=f_putcmd;
2902 else if (fam01_drive)
2903 flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
2904 else if (fam2_drive) return (-1); /* not implemented yet */
2905 else if (famT_drive)
2906 {
2907 return (-1);
2908 }
2909 i=cmd_out();
2910 return (i);
2911}
2912/*==========================================================================*/
2913static int convert_UPC(u_char *p)
2914{
2915 int i;
2916
2917 p++;
2918 if (fam0L_drive) p[13]=0;
2919 for (i=0;i<7;i++)
2920 {
2921 if (fam1_drive) current_drive->UPC_buf[i]=swap_nibbles(*p++);
2922 else if (fam0L_drive)
2923 {
2924 current_drive->UPC_buf[i]=((*p++)<<4)&0xFF;
2925 current_drive->UPC_buf[i] |= *p++;
2926 }
2927 else if (famT_drive)
2928 {
2929 return (-1);
2930 }
2931 else /* CD200 */
2932 {
2933 return (-1);
2934 }
2935 }
2936 current_drive->UPC_buf[6] &= 0xF0;
2937 return (0);
2938}
2939/*==========================================================================*/
2940static int cc_ReadUPC(void)
2941{
2942 int i;
2943#if TEST_UPC
2944 int block, checksum;
2945#endif /* TEST_UPC */
2946
2947 if (fam2_drive) return (0); /* not implemented yet */
2948 if (famT_drive) return (0); /* not implemented yet */
2949 if (famV_drive) return (0); /* not implemented yet */
2950#if 1
2951 if (fam0_drive) return (0); /* but it should work */
2952#endif
2953
2954 current_drive->diskstate_flags &= ~upc_bit;
2955#if TEST_UPC
2956 for (block=CD_MSF_OFFSET+1;block<CD_MSF_OFFSET+200;block++)
2957 {
2958#endif /* TEST_UPC */
2959 clr_cmdbuf();
2960 if (fam1_drive)
2961 {
2962 drvcmd[0]=CMD1_READ_UPC;
2963#if TEST_UPC
2964 drvcmd[1]=(block>>16)&0xFF;
2965 drvcmd[2]=(block>>8)&0xFF;
2966 drvcmd[3]=block&0xFF;
2967#endif /* TEST_UPC */
2968 response_count=8;
2969 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
2970 }
2971 else if (fam0L_drive)
2972 {
2973 drvcmd[0]=CMD0_READ_UPC;
2974#if TEST_UPC
2975 drvcmd[2]=(block>>16)&0xFF;
2976 drvcmd[3]=(block>>8)&0xFF;
2977 drvcmd[4]=block&0xFF;
2978#endif /* TEST_UPC */
2979 response_count=0;
2980 flags_cmd_out=f_putcmd|f_lopsta|f_getsta|f_ResponseStatus|f_obey_p_check|f_bit1;
2981 }
2982 else if (fam2_drive)
2983 {
2984 return (-1);
2985 }
2986 else if (famT_drive)
2987 {
2988 return (-1);
2989 }
2990 i=cmd_out();
2991 if (i<0)
2992 {
2993 msg(DBG_000,"cc_ReadUPC cmd_out: err %d\n", i);
2994 return (i);
2995 }
2996 if (fam0L_drive)
2997 {
2998 response_count=16;
2999 if (famL_drive) flags_cmd_out=f_putcmd;
3000 i=cc_ReadPacket();
3001 if (i<0)
3002 {
3003 msg(DBG_000,"cc_ReadUPC ReadPacket: err %d\n", i);
3004 return (i);
3005 }
3006 }
3007#if TEST_UPC
3008 checksum=0;
3009#endif /* TEST_UPC */
3010 for (i=0;i<(fam1_drive?8:16);i++)
3011 {
3012#if TEST_UPC
3013 checksum |= infobuf[i];
3014#endif /* TEST_UPC */
3015 sprintf(&msgbuf[i*3], " %02X", infobuf[i]);
3016 }
3017 msgbuf[i*3]=0;
3018 msg(DBG_UPC,"UPC info:%s\n", msgbuf);
3019#if TEST_UPC
3020 if ((checksum&0x7F)!=0) break;
3021 }
3022#endif /* TEST_UPC */
3023 current_drive->UPC_ctl_adr=0;
3024 if (fam1_drive) i=0;
3025 else i=2;
3026 if ((infobuf[i]&0x80)!=0)
3027 {
3028 convert_UPC(&infobuf[i]);
3029 current_drive->UPC_ctl_adr = (current_drive->TocEnt_ctl_adr & 0xF0) | 0x02;
3030 }
3031 for (i=0;i<7;i++)
3032 sprintf(&msgbuf[i*3], " %02X", current_drive->UPC_buf[i]);
3033 sprintf(&msgbuf[i*3], " (%02X)", current_drive->UPC_ctl_adr);
3034 msgbuf[i*3+5]=0;
3035 msg(DBG_UPC,"UPC code:%s\n", msgbuf);
3036 current_drive->diskstate_flags |= upc_bit;
3037 return (0);
3038}
3039
3040static int sbpcd_get_mcn(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn)
3041{
3042 int i;
3043 unsigned char *mcnp = mcn->medium_catalog_number;
3044 unsigned char *resp;
3045
3046 current_drive->diskstate_flags &= ~upc_bit;
3047 clr_cmdbuf();
3048 if (fam1_drive)
3049 {
3050 drvcmd[0]=CMD1_READ_UPC;
3051 response_count=8;
3052 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
3053 }
3054 else if (fam0L_drive)
3055 {
3056 drvcmd[0]=CMD0_READ_UPC;
3057 response_count=0;
3058 flags_cmd_out=f_putcmd|f_lopsta|f_getsta|f_ResponseStatus|f_obey_p_check|f_bit1;
3059 }
3060 else if (fam2_drive)
3061 {
3062 return (-1);
3063 }
3064 else if (famT_drive)
3065 {
3066 return (-1);
3067 }
3068 i=cmd_out();
3069 if (i<0)
3070 {
3071 msg(DBG_000,"cc_ReadUPC cmd_out: err %d\n", i);
3072 return (i);
3073 }
3074 if (fam0L_drive)
3075 {
3076 response_count=16;
3077 if (famL_drive) flags_cmd_out=f_putcmd;
3078 i=cc_ReadPacket();
3079 if (i<0)
3080 {
3081 msg(DBG_000,"cc_ReadUPC ReadPacket: err %d\n", i);
3082 return (i);
3083 }
3084 }
3085 current_drive->UPC_ctl_adr=0;
3086 if (fam1_drive) i=0;
3087 else i=2;
3088
3089 resp = infobuf + i;
3090 if (*resp++ == 0x80) {
3091 /* packed bcd to single ASCII digits */
3092 *mcnp++ = (*resp >> 4) + '0';
3093 *mcnp++ = (*resp++ & 0x0f) + '0';
3094 *mcnp++ = (*resp >> 4) + '0';
3095 *mcnp++ = (*resp++ & 0x0f) + '0';
3096 *mcnp++ = (*resp >> 4) + '0';
3097 *mcnp++ = (*resp++ & 0x0f) + '0';
3098 *mcnp++ = (*resp >> 4) + '0';
3099 *mcnp++ = (*resp++ & 0x0f) + '0';
3100 *mcnp++ = (*resp >> 4) + '0';
3101 *mcnp++ = (*resp++ & 0x0f) + '0';
3102 *mcnp++ = (*resp >> 4) + '0';
3103 *mcnp++ = (*resp++ & 0x0f) + '0';
3104 *mcnp++ = (*resp >> 4) + '0';
3105 }
3106 *mcnp = '\0';
3107
3108 current_drive->diskstate_flags |= upc_bit;
3109 return (0);
3110}
3111
3112/*==========================================================================*/
3113static int cc_CheckMultiSession(void)
3114{
3115 int i;
3116
3117 if (fam2_drive) return (0);
3118 current_drive->f_multisession=0;
3119 current_drive->lba_multi=0;
3120 if (fam0_drive) return (0);
3121 clr_cmdbuf();
3122 if (fam1_drive)
3123 {
3124 drvcmd[0]=CMD1_MULTISESS;
3125 response_count=6;
3126 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
3127 i=cmd_out();
3128 if (i<0) return (i);
3129 if ((infobuf[0]&0x80)!=0)
3130 {
3131 current_drive->f_multisession=1;
3132 current_drive->lba_multi=msf2blk(make32(make16(0,infobuf[1]),
3133 make16(infobuf[2],infobuf[3])));
3134 }
3135 }
3136 else if (famLV_drive)
3137 {
3138 drvcmd[0]=CMDL_MULTISESS;
3139 drvcmd[1]=3;
3140 drvcmd[2]=1;
3141 response_count=8;
3142 flags_cmd_out=f_putcmd;
3143 i=cmd_out();
3144 if (i<0) return (i);
3145 current_drive->lba_multi=msf2blk(make32(make16(0,infobuf[5]),
3146 make16(infobuf[6],infobuf[7])));
3147 }
3148 else if (famT_drive)
3149 {
3150 response_count=12;
3151 drvcmd[0]=CMDT_DISKINFO;
3152 drvcmd[1]=0x02;
3153 drvcmd[6]=0;
3154 drvcmd[8]=response_count;
3155 drvcmd[9]=0x40;
3156 i=cmd_out();
3157 if (i<0) return (i);
3158 if (i<response_count) return (-100-i);
3159 current_drive->first_session=infobuf[2];
3160 current_drive->last_session=infobuf[3];
3161 current_drive->track_of_last_session=infobuf[6];
3162 if (current_drive->first_session!=current_drive->last_session)
3163 {
3164 current_drive->f_multisession=1;
3165 current_drive->lba_multi=msf2blk(make32(make16(0,infobuf[9]),make16(infobuf[10],infobuf[11])));
3166 }
3167 }
3168 for (i=0;i<response_count;i++)
3169 sprintf(&msgbuf[i*3], " %02X", infobuf[i]);
3170 msgbuf[i*3]=0;
3171 msg(DBG_MUL,"MultiSession Info:%s (%d)\n", msgbuf, current_drive->lba_multi);
3172 if (current_drive->lba_multi>200)
3173 {
3174 current_drive->f_multisession=1;
3175 msg(DBG_MUL,"MultiSession base: %06X\n", current_drive->lba_multi);
3176 }
3177 return (0);
3178}
3179/*==========================================================================*/
3180#ifdef FUTURE
3181static int cc_SubChanInfo(int frame, int count, u_char *buffer)
3182 /* "frame" is a RED BOOK (msf-bin) address */
3183{
3184 int i;
3185
3186 if (fam0LV_drive) return (-ENOSYS); /* drive firmware lacks it */
3187 if (famT_drive)
3188 {
3189 return (-1);
3190 }
3191#if 0
3192 if (current_drive->audio_state!=audio_playing) return (-ENODATA);
3193#endif
3194 clr_cmdbuf();
3195 drvcmd[0]=CMD1_SUBCHANINF;
3196 drvcmd[1]=(frame>>16)&0xFF;
3197 drvcmd[2]=(frame>>8)&0xFF;
3198 drvcmd[3]=frame&0xFF;
3199 drvcmd[5]=(count>>8)&0xFF;
3200 drvcmd[6]=count&0xFF;
3201 flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
3202 cmd_type=READ_SC;
3203 current_drive->frame_size=CD_FRAMESIZE_SUB;
3204 i=cmd_out(); /* which buffer to use? */
3205 return (i);
3206}
3207#endif /* FUTURE */
3208/*==========================================================================*/
3209static void __init check_datarate(void)
3210{
3211 int i=0;
3212
3213 msg(DBG_IOX,"check_datarate entered.\n");
3214 datarate=0;
3215#if TEST_STI
3216 for (i=0;i<=1000;i++) printk(".");
3217#endif
3218 /* set a timer to make (timed_out_delay!=0) after 1.1 seconds */
3219#if 1
3220 del_timer(&delay_timer);
3221#endif
3222 delay_timer.expires=jiffies+11*HZ/10;
3223 timed_out_delay=0;
3224 add_timer(&delay_timer);
3225#if 0
3226 msg(DBG_TIM,"delay timer started (11*HZ/10).\n");
3227#endif
3228 do
3229 {
3230 i=inb(CDi_status);
3231 datarate++;
3232#if 1
3233 if (datarate>0x6FFFFFFF) break;
3234#endif
3235 }
3236 while (!timed_out_delay);
3237 del_timer(&delay_timer);
3238#if 0
3239 msg(DBG_TIM,"datarate: %04X\n", datarate);
3240#endif
3241 if (datarate<65536) datarate=65536;
3242 maxtim16=datarate*16;
3243 maxtim04=datarate*4;
3244 maxtim02=datarate*2;
3245 maxtim_8=datarate/32;
3246#if LONG_TIMING
3247 maxtim_data=datarate/100;
3248#else
3249 maxtim_data=datarate/300;
3250#endif /* LONG_TIMING */
3251#if 0
3252 msg(DBG_TIM,"maxtim_8 %d, maxtim_data %d.\n", maxtim_8, maxtim_data);
3253#endif
3254}
3255/*==========================================================================*/
3256#if 0
3257static int c2_ReadError(int fam)
3258{
3259 int i;
3260
3261 clr_cmdbuf();
3262 response_count=9;
3263 clr_respo_buf(9);
3264 if (fam==1)
3265 {
3266 drvcmd[0]=CMD0_READ_ERR; /* same as CMD1_ and CMDL_ */
3267 i=do_cmd(f_putcmd|f_lopsta|f_getsta|f_ResponseStatus);
3268 }
3269 else if (fam==2)
3270 {
3271 drvcmd[0]=CMD2_READ_ERR;
3272 i=do_cmd(f_putcmd);
3273 }
3274 else return (-1);
3275 return (i);
3276}
3277#endif
3278/*==========================================================================*/
3279static void __init ask_mail(void)
3280{
3281 int i;
3282
3283 msg(DBG_INF, "please mail the following lines to emoenke@gwdg.de\n");
3284 msg(DBG_INF, "(don't mail if you are not using the actual kernel):\n");
3285 msg(DBG_INF, "%s\n", VERSION);
3286 msg(DBG_INF, "address %03X, type %s, drive %s (ID %d)\n",
3287 CDo_command, type, current_drive->drive_model, current_drive->drv_id);
3288 for (i=0;i<12;i++)
3289 sprintf(&msgbuf[i*3], " %02X", infobuf[i]);
3290 msgbuf[i*3]=0;
3291 msg(DBG_INF,"infobuf =%s\n", msgbuf);
3292 for (i=0;i<12;i++)
3293 sprintf(&msgbuf[i*3], " %c ", infobuf[i]);
3294 msgbuf[i*3]=0;
3295 msg(DBG_INF,"infobuf =%s\n", msgbuf);
3296}
3297/*==========================================================================*/
3298static int __init check_version(void)
3299{
3300 int i, j, l;
3301 int teac_possible=0;
3302
3303 msg(DBG_INI,"check_version: id=%d, d=%d.\n", current_drive->drv_id, current_drive - D_S);
3304 current_drive->drv_type=0;
3305
3306 /* check for CR-52x, CR-56x, LCS-7260 and ECS-AT */
3307 /* clear any pending error state */
3308 clr_cmdbuf();
3309 drvcmd[0]=CMD0_READ_ERR; /* same as CMD1_ and CMDL_ */
3310 response_count=9;
3311 flags_cmd_out=f_putcmd;
3312 i=cmd_out();
3313 if (i<0) msg(DBG_INI,"CMD0_READ_ERR returns %d (ok anyway).\n",i);
3314 /* read drive version */
3315 clr_cmdbuf();
3316 for (i=0;i<12;i++) infobuf[i]=0;
3317 drvcmd[0]=CMD0_READ_VER; /* same as CMD1_ and CMDL_ */
3318 response_count=12; /* fam1: only 11 */
3319 flags_cmd_out=f_putcmd;
3320 i=cmd_out();
3321 if (i<-1) msg(DBG_INI,"CMD0_READ_VER returns %d\n",i);
3322 if (i==-11) teac_possible++;
3323 j=0;
3324 for (i=0;i<12;i++) j+=infobuf[i];
3325 if (j)
3326 {
3327 for (i=0;i<12;i++)
3328 sprintf(&msgbuf[i*3], " %02X", infobuf[i]);
3329 msgbuf[i*3]=0;
3330 msg(DBG_ECS,"infobuf =%s\n", msgbuf);
3331 for (i=0;i<12;i++)
3332 sprintf(&msgbuf[i*3], " %c ", infobuf[i]);
3333 msgbuf[i*3]=0;
3334 msg(DBG_ECS,"infobuf =%s\n", msgbuf);
3335 }
3336 for (i=0;i<4;i++) if (infobuf[i]!=family1[i]) break;
3337 if (i==4)
3338 {
3339 current_drive->drive_model[0]='C';
3340 current_drive->drive_model[1]='R';
3341 current_drive->drive_model[2]='-';
3342 current_drive->drive_model[3]='5';
3343 current_drive->drive_model[4]=infobuf[i++];
3344 current_drive->drive_model[5]=infobuf[i++];
3345 current_drive->drive_model[6]=0;
3346 current_drive->drv_type=drv_fam1;
3347 }
3348 if (!current_drive->drv_type)
3349 {
3350 for (i=0;i<8;i++) if (infobuf[i]!=family0[i]) break;
3351 if (i==8)
3352 {
3353 current_drive->drive_model[0]='C';
3354 current_drive->drive_model[1]='R';
3355 current_drive->drive_model[2]='-';
3356 current_drive->drive_model[3]='5';
3357 current_drive->drive_model[4]='2';
3358 current_drive->drive_model[5]='x';
3359 current_drive->drive_model[6]=0;
3360 current_drive->drv_type=drv_fam0;
3361 }
3362 }
3363 if (!current_drive->drv_type)
3364 {
3365 for (i=0;i<8;i++) if (infobuf[i]!=familyL[i]) break;
3366 if (i==8)
3367 {
3368 for (j=0;j<8;j++)
3369 current_drive->drive_model[j]=infobuf[j];
3370 current_drive->drive_model[8]=0;
3371 current_drive->drv_type=drv_famL;
3372 }
3373 }
3374 if (!current_drive->drv_type)
3375 {
3376 for (i=0;i<6;i++) if (infobuf[i]!=familyV[i]) break;
3377 if (i==6)
3378 {
3379 for (j=0;j<6;j++)
3380 current_drive->drive_model[j]=infobuf[j];
3381 current_drive->drive_model[6]=0;
3382 current_drive->drv_type=drv_famV;
3383 i+=2; /* 2 blanks before version */
3384 }
3385 }
3386 if (!current_drive->drv_type)
3387 {
3388 /* check for CD200 */
3389 clr_cmdbuf();
3390 drvcmd[0]=CMD2_READ_ERR;
3391 response_count=9;
3392 flags_cmd_out=f_putcmd;
3393 i=cmd_out();
3394 if (i<0) msg(DBG_INI,"CMD2_READERR returns %d (ok anyway).\n",i);
3395 if (i<0) msg(DBG_000,"CMD2_READERR returns %d (ok anyway).\n",i);
3396 /* read drive version */
3397 clr_cmdbuf();
3398 for (i=0;i<12;i++) infobuf[i]=0;
3399 if (sbpro_type==1) OUT(CDo_sel_i_d,0);
3400#if 0
3401 OUT(CDo_reset,0);
3402 sbp_sleep(6*HZ);
3403 OUT(CDo_enable,current_drive->drv_sel);
3404#endif
3405 drvcmd[0]=CMD2_READ_VER;
3406 response_count=12;
3407 flags_cmd_out=f_putcmd;
3408 i=cmd_out();
3409 if (i<0) msg(DBG_INI,"CMD2_READ_VER returns %d\n",i);
3410 if (i==-7) teac_possible++;
3411 j=0;
3412 for (i=0;i<12;i++) j+=infobuf[i];
3413 if (j)
3414 {
3415 for (i=0;i<12;i++)
3416 sprintf(&msgbuf[i*3], " %02X", infobuf[i]);
3417 msgbuf[i*3]=0;
3418 msg(DBG_IDX,"infobuf =%s\n", msgbuf);
3419 for (i=0;i<12;i++)
3420 sprintf(&msgbuf[i*3], " %c ", infobuf[i]);
3421 msgbuf[i*3]=0;
3422 msg(DBG_IDX,"infobuf =%s\n", msgbuf);
3423 }
3424 if (i>=0)
3425 {
3426 for (i=0;i<5;i++) if (infobuf[i]!=family2[i]) break;
3427 if (i==5)
3428 {
3429 current_drive->drive_model[0]='C';
3430 current_drive->drive_model[1]='D';
3431 current_drive->drive_model[2]='2';
3432 current_drive->drive_model[3]='0';
3433 current_drive->drive_model[4]='0';
3434 current_drive->drive_model[5]=infobuf[i++];
3435 current_drive->drive_model[6]=infobuf[i++];
3436 current_drive->drive_model[7]=0;
3437 current_drive->drv_type=drv_fam2;
3438 }
3439 }
3440 }
3441 if (!current_drive->drv_type)
3442 {
3443 /* check for TEAC CD-55A */
3444 msg(DBG_TEA,"teac_possible: %d\n",teac_possible);
3445 for (j=1;j<=((current_drive->drv_id==0)?3:1);j++)
3446 {
3447 for (l=1;l<=((current_drive->drv_id==0)?10:1);l++)
3448 {
3449 msg(DBG_TEA,"TEAC reset #%d-%d.\n", j, l);
3450 if (sbpro_type==1) OUT(CDo_reset,0);
3451 else
3452 {
3453 OUT(CDo_enable,current_drive->drv_sel);
3454 OUT(CDo_sel_i_d,0);
3455 OUT(CDo_command,CMDT_RESET);
3456 for (i=0;i<9;i++) OUT(CDo_command,0);
3457 }
3458 sbp_sleep(5*HZ/10);
3459 OUT(CDo_enable,current_drive->drv_sel);
3460 OUT(CDo_sel_i_d,0);
3461 i=inb(CDi_status);
3462 msg(DBG_TEA,"TEAC CDi_status: %02X.\n",i);
3463#if 0
3464 if (i&s_not_result_ready) continue; /* drive not present or ready */
3465#endif
3466 i=inb(CDi_info);
3467 msg(DBG_TEA,"TEAC CDi_info: %02X.\n",i);
3468 if (i==0x55) break; /* drive found */
3469 }
3470 if (i==0x55) break; /* drive found */
3471 }
3472 if (i==0x55) /* drive found */
3473 {
3474 msg(DBG_TEA,"TEAC drive found.\n");
3475 clr_cmdbuf();
3476 flags_cmd_out=f_putcmd;
3477 response_count=12;
3478 drvcmd[0]=CMDT_READ_VER;
3479 drvcmd[4]=response_count;
3480 for (i=0;i<12;i++) infobuf[i]=0;
3481 i=cmd_out_T();
3482 if (i!=0) msg(DBG_TEA,"cmd_out_T(CMDT_READ_VER) returns %d.\n",i);
3483 for (i=1;i<6;i++) if (infobuf[i]!=familyT[i-1]) break;
3484 if (i==6)
3485 {
3486 current_drive->drive_model[0]='C';
3487 current_drive->drive_model[1]='D';
3488 current_drive->drive_model[2]='-';
3489 current_drive->drive_model[3]='5';
3490 current_drive->drive_model[4]='5';
3491 current_drive->drive_model[5]=0;
3492 current_drive->drv_type=drv_famT;
3493 }
3494 }
3495 }
3496 if (!current_drive->drv_type)
3497 {
3498 msg(DBG_TEA,"no drive found at address %03X under ID %d.\n",CDo_command,current_drive->drv_id);
3499 return (-522);
3500 }
3501 for (j=0;j<4;j++) current_drive->firmware_version[j]=infobuf[i+j];
3502 if (famL_drive)
3503 {
3504 u_char lcs_firm_e1[]="A E1";
3505 u_char lcs_firm_f4[]="A4F4";
3506
3507 for (j=0;j<4;j++)
3508 if (current_drive->firmware_version[j]!=lcs_firm_e1[j]) break;
3509 if (j==4) current_drive->drv_type=drv_e1;
3510
3511 for (j=0;j<4;j++)
3512 if (current_drive->firmware_version[j]!=lcs_firm_f4[j]) break;
3513 if (j==4) current_drive->drv_type=drv_f4;
3514
3515 if (current_drive->drv_type==drv_famL) ask_mail();
3516 }
3517 else if (famT_drive)
3518 {
3519 j=infobuf[4]; /* one-byte version??? - here: 0x15 */
3520 if (j=='5')
3521 {
3522 current_drive->firmware_version[0]=infobuf[7];
3523 current_drive->firmware_version[1]=infobuf[8];
3524 current_drive->firmware_version[2]=infobuf[10];
3525 current_drive->firmware_version[3]=infobuf[11];
3526 }
3527 else
3528 {
3529 if (j!=0x15) ask_mail();
3530 current_drive->firmware_version[0]='0';
3531 current_drive->firmware_version[1]='.';
3532 current_drive->firmware_version[2]='0'+(j>>4);
3533 current_drive->firmware_version[3]='0'+(j&0x0f);
3534 }
3535 }
3536 else /* CR-52x, CR-56x, CD200, ECS-AT */
3537 {
3538 j = (current_drive->firmware_version[0] & 0x0F) * 100 +
3539 (current_drive->firmware_version[2] & 0x0F) *10 +
3540 (current_drive->firmware_version[3] & 0x0F);
3541 if (fam0_drive)
3542 {
3543 if (j<200) current_drive->drv_type=drv_199;
3544 else if (j<201) current_drive->drv_type=drv_200;
3545 else if (j<210) current_drive->drv_type=drv_201;
3546 else if (j<211) current_drive->drv_type=drv_210;
3547 else if (j<300) current_drive->drv_type=drv_211;
3548 else if (j>=300) current_drive->drv_type=drv_300;
3549 }
3550 else if (fam1_drive)
3551 {
3552 if (j<100) current_drive->drv_type=drv_099;
3553 else
3554 {
3555 current_drive->drv_type=drv_100;
3556 if ((j!=500)&&(j!=102)) ask_mail();
3557 }
3558 }
3559 else if (fam2_drive)
3560 {
3561 if (current_drive->drive_model[5]=='F')
3562 {
3563 if ((j!=1)&&(j!=35)&&(j!=200)&&(j!=210))
3564 ask_mail(); /* unknown version at time */
3565 }
3566 else
3567 {
3568 msg(DBG_INF,"this CD200 drive is not fully supported yet - only audio will work.\n");
3569 if ((j!=101)&&(j!=35))
3570 ask_mail(); /* unknown version at time */
3571 }
3572 }
3573 else if (famV_drive)
3574 {
3575 if ((j==100)||(j==150)) current_drive->drv_type=drv_at;
3576 ask_mail(); /* hopefully we get some feedback by this */
3577 }
3578 }
3579 msg(DBG_LCS,"drive type %02X\n",current_drive->drv_type);
3580 msg(DBG_INI,"check_version done.\n");
3581 return (0);
3582}
3583/*==========================================================================*/
3584static void switch_drive(struct sbpcd_drive *p)
3585{
3586 current_drive = p;
3587 OUT(CDo_enable,current_drive->drv_sel);
3588 msg(DBG_DID,"drive %d (ID=%d) activated.\n",
3589 current_drive - D_S, current_drive->drv_id);
3590 return;
3591}
3592/*==========================================================================*/
3593#ifdef PATH_CHECK
3594/*
3595 * probe for the presence of an interface card
3596 */
3597static int __init check_card(int port)
3598{
3599#undef N_RESPO
3600#define N_RESPO 20
3601 int i, j, k;
3602 u_char response[N_RESPO];
3603 u_char save_port0;
3604 u_char save_port3;
3605
3606 msg(DBG_INI,"check_card entered.\n");
3607 save_port0=inb(port+0);
3608 save_port3=inb(port+3);
3609
3610 for (j=0;j<NR_SBPCD;j++)
3611 {
3612 OUT(port+3,j) ; /* enable drive #j */
3613 OUT(port+0,CMD0_PATH_CHECK);
3614 for (i=10;i>0;i--) OUT(port+0,0);
3615 for (k=0;k<N_RESPO;k++) response[k]=0;
3616 for (k=0;k<N_RESPO;k++)
3617 {
3618 for (i=10000;i>0;i--)
3619 {
3620 if (inb(port+1)&s_not_result_ready) continue;
3621 response[k]=inb(port+0);
3622 break;
3623 }
3624 }
3625 for (i=0;i<N_RESPO;i++)
3626 sprintf(&msgbuf[i*3], " %02X", response[i]);
3627 msgbuf[i*3]=0;
3628 msg(DBG_TEA,"path check 00 (%d): %s\n", j, msgbuf);
3629 OUT(port+0,CMD0_PATH_CHECK);
3630 for (i=10;i>0;i--) OUT(port+0,0);
3631 for (k=0;k<N_RESPO;k++) response[k]=0xFF;
3632 for (k=0;k<N_RESPO;k++)
3633 {
3634 for (i=10000;i>0;i--)
3635 {
3636 if (inb(port+1)&s_not_result_ready) continue;
3637 response[k]=inb(port+0);
3638 break;
3639 }
3640 }
3641 for (i=0;i<N_RESPO;i++)
3642 sprintf(&msgbuf[i*3], " %02X", response[i]);
3643 msgbuf[i*3]=0;
3644 msg(DBG_TEA,"path check 00 (%d): %s\n", j, msgbuf);
3645
3646 if (response[0]==0xAA)
3647 if (response[1]==0x55)
3648 return (0);
3649 }
3650 for (j=0;j<NR_SBPCD;j++)
3651 {
3652 OUT(port+3,j) ; /* enable drive #j */
3653 OUT(port+0,CMD2_READ_VER);
3654 for (i=10;i>0;i--) OUT(port+0,0);
3655 for (k=0;k<N_RESPO;k++) response[k]=0;
3656 for (k=0;k<N_RESPO;k++)
3657 {
3658 for (i=1000000;i>0;i--)
3659 {
3660 if (inb(port+1)&s_not_result_ready) continue;
3661 response[k]=inb(port+0);
3662 break;
3663 }
3664 }
3665 for (i=0;i<N_RESPO;i++)
3666 sprintf(&msgbuf[i*3], " %02X", response[i]);
3667 msgbuf[i*3]=0;
3668 msg(DBG_TEA,"path check 12 (%d): %s\n", j, msgbuf);
3669
3670 OUT(port+0,CMD2_READ_VER);
3671 for (i=10;i>0;i--) OUT(port+0,0);
3672 for (k=0;k<N_RESPO;k++) response[k]=0xFF;
3673 for (k=0;k<N_RESPO;k++)
3674 {
3675 for (i=1000000;i>0;i--)
3676 {
3677 if (inb(port+1)&s_not_result_ready) continue;
3678 response[k]=inb(port+0);
3679 break;
3680 }
3681 }
3682 for (i=0;i<N_RESPO;i++)
3683 sprintf(&msgbuf[i*3], " %02X", response[i]);
3684 msgbuf[i*3]=0;
3685 msg(DBG_TEA,"path check 12 (%d): %s\n", j, msgbuf);
3686
3687 if (response[0]==0xAA)
3688 if (response[1]==0x55)
3689 return (0);
3690 }
3691 OUT(port+0,save_port0);
3692 OUT(port+3,save_port3);
3693 return (0); /* in any case - no real "function" at time */
3694}
3695#endif /* PATH_CHECK */
3696/*==========================================================================*/
3697/*==========================================================================*/
3698/*
3699 * probe for the presence of drives on the selected controller
3700 */
3701static int __init check_drives(void)
3702{
3703 int i, j;
3704
3705 msg(DBG_INI,"check_drives entered.\n");
3706 ndrives=0;
3707 for (j=0;j<max_drives;j++)
3708 {
3709 struct sbpcd_drive *p = D_S + ndrives;
3710 p->drv_id=j;
3711 if (sbpro_type==1) p->drv_sel=(j&0x01)<<1|(j&0x02)>>1;
3712 else p->drv_sel=j;
3713 switch_drive(p);
3714 msg(DBG_INI,"check_drives: drive %d (ID=%d) activated.\n",ndrives,j);
3715 msg(DBG_000,"check_drives: drive %d (ID=%d) activated.\n",ndrives,j);
3716 i=check_version();
3717 if (i<0) msg(DBG_INI,"check_version returns %d.\n",i);
3718 else
3719 {
3720 current_drive->drv_options=drv_pattern[j];
3721 if (fam0L_drive) current_drive->drv_options&=~(speed_auto|speed_300|speed_150);
3722 msg(DBG_INF, "Drive %d (ID=%d): %.9s (%.4s) at 0x%03X (type %d)\n",
3723 current_drive - D_S,
3724 current_drive->drv_id,
3725 current_drive->drive_model,
3726 current_drive->firmware_version,
3727 CDo_command,
3728 sbpro_type);
3729 ndrives++;
3730 }
3731 }
3732 for (j=ndrives;j<NR_SBPCD;j++) D_S[j].drv_id=-1;
3733 if (ndrives==0) return (-1);
3734 return (0);
3735}
3736/*==========================================================================*/
3737#ifdef FUTURE
3738/*
3739 * obtain if requested service disturbs current audio state
3740 */
3741static int obey_audio_state(u_char audio_state, u_char func,u_char subfunc)
3742{
3743 switch (audio_state) /* audio status from controller */
3744 {
3745 case aud_11: /* "audio play in progress" */
3746 case audx11:
3747 switch (func) /* DOS command code */
3748 {
3749 case cmd_07: /* input flush */
3750 case cmd_0d: /* open device */
3751 case cmd_0e: /* close device */
3752 case cmd_0c: /* ioctl output */
3753 return (1);
3754 case cmd_03: /* ioctl input */
3755 switch (subfunc)
3756 /* DOS ioctl input subfunction */
3757 {
3758 case cxi_00:
3759 case cxi_06:
3760 case cxi_09:
3761 return (1);
3762 default:
3763 return (ERROR15);
3764 }
3765 return (1);
3766 default:
3767 return (ERROR15);
3768 }
3769 return (1);
3770 case aud_12: /* "audio play paused" */
3771 case audx12:
3772 return (1);
3773 default:
3774 return (2);
3775 }
3776}
3777/*==========================================================================*/
3778/* allowed is only
3779 * ioctl_o, flush_input, open_device, close_device,
3780 * tell_address, tell_volume, tell_capabiliti,
3781 * tell_framesize, tell_CD_changed, tell_audio_posi
3782 */
3783static int check_allowed1(u_char func1, u_char func2)
3784{
3785#if 000
3786 if (func1==ioctl_o) return (0);
3787 if (func1==read_long) return (-1);
3788 if (func1==read_long_prefetch) return (-1);
3789 if (func1==seek) return (-1);
3790 if (func1==audio_play) return (-1);
3791 if (func1==audio_pause) return (-1);
3792 if (func1==audio_resume) return (-1);
3793 if (func1!=ioctl_i) return (0);
3794 if (func2==tell_SubQ_run_tot) return (-1);
3795 if (func2==tell_cdsize) return (-1);
3796 if (func2==tell_TocDescrip) return (-1);
3797 if (func2==tell_TocEntry) return (-1);
3798 if (func2==tell_subQ_info) return (-1);
3799 if (fam1_drive) if (func2==tell_SubChanInfo) return (-1);
3800 if (func2==tell_UPC) return (-1);
3801#else
3802 return (0);
3803#endif
3804}
3805/*==========================================================================*/
3806static int check_allowed2(u_char func1, u_char func2)
3807{
3808#if 000
3809 if (func1==read_long) return (-1);
3810 if (func1==read_long_prefetch) return (-1);
3811 if (func1==seek) return (-1);
3812 if (func1==audio_play) return (-1);
3813 if (func1!=ioctl_o) return (0);
3814 if (fam1_drive)
3815 {
3816 if (func2==EjectDisk) return (-1);
3817 if (func2==CloseTray) return (-1);
3818 }
3819#else
3820 return (0);
3821#endif
3822}
3823/*==========================================================================*/
3824static int check_allowed3(u_char func1, u_char func2)
3825{
3826#if 000
3827 if (func1==ioctl_i)
3828 {
3829 if (func2==tell_address) return (0);
3830 if (func2==tell_capabiliti) return (0);
3831 if (func2==tell_CD_changed) return (0);
3832 if (fam0L_drive) if (func2==tell_SubChanInfo) return (0);
3833 return (-1);
3834 }
3835 if (func1==ioctl_o)
3836 {
3837 if (func2==DriveReset) return (0);
3838 if (fam0L_drive)
3839 {
3840 if (func2==EjectDisk) return (0);
3841 if (func2==LockDoor) return (0);
3842 if (func2==CloseTray) return (0);
3843 }
3844 return (-1);
3845 }
3846 if (func1==flush_input) return (-1);
3847 if (func1==read_long) return (-1);
3848 if (func1==read_long_prefetch) return (-1);
3849 if (func1==seek) return (-1);
3850 if (func1==audio_play) return (-1);
3851 if (func1==audio_pause) return (-1);
3852 if (func1==audio_resume) return (-1);
3853#else
3854 return (0);
3855#endif
3856}
3857/*==========================================================================*/
3858static int seek_pos_audio_end(void)
3859{
3860 int i;
3861
3862 i=msf2blk(current_drive->pos_audio_end)-1;
3863 if (i<0) return (-1);
3864 i=cc_Seek(i,0);
3865 return (i);
3866}
3867#endif /* FUTURE */
3868/*==========================================================================*/
3869static int ReadToC(void)
3870{
3871 int i, j;
3872 current_drive->diskstate_flags &= ~toc_bit;
3873 current_drive->ored_ctl_adr=0;
3874 /* special handling of CD-I HE */
3875 if ((current_drive->n_first_track == 2 && current_drive->n_last_track == 2) ||
3876 current_drive->xa_byte == 0x10)
3877 {
3878 current_drive->TocBuffer[1].nixbyte=0;
3879 current_drive->TocBuffer[1].ctl_adr=0x40;
3880 current_drive->TocBuffer[1].number=1;
3881 current_drive->TocBuffer[1].format=0;
3882 current_drive->TocBuffer[1].address=blk2msf(0);
3883 current_drive->ored_ctl_adr |= 0x40;
3884 current_drive->n_first_track = 1;
3885 current_drive->n_last_track = 1;
3886 current_drive->xa_byte = 0x10;
3887 j = 2;
3888 } else
3889 for (j=current_drive->n_first_track;j<=current_drive->n_last_track;j++)
3890 {
3891 i=cc_ReadTocEntry(j);
3892 if (i<0)
3893 {
3894 msg(DBG_INF,"cc_ReadTocEntry(%d) returns %d.\n",j,i);
3895 return (i);
3896 }
3897 current_drive->TocBuffer[j].nixbyte=current_drive->TocEnt_nixbyte;
3898 current_drive->TocBuffer[j].ctl_adr=current_drive->TocEnt_ctl_adr;
3899 current_drive->TocBuffer[j].number=current_drive->TocEnt_number;
3900 current_drive->TocBuffer[j].format=current_drive->TocEnt_format;
3901 current_drive->TocBuffer[j].address=current_drive->TocEnt_address;
3902 current_drive->ored_ctl_adr |= current_drive->TocEnt_ctl_adr;
3903 }
3904 /* fake entry for LeadOut Track */
3905 current_drive->TocBuffer[j].nixbyte=0;
3906 current_drive->TocBuffer[j].ctl_adr=0;
3907 current_drive->TocBuffer[j].number=CDROM_LEADOUT;
3908 current_drive->TocBuffer[j].format=0;
3909 current_drive->TocBuffer[j].address=current_drive->size_msf;
3910
3911 current_drive->diskstate_flags |= toc_bit;
3912 return (0);
3913}
3914/*==========================================================================*/
3915static int DiskInfo(void)
3916{
3917 int i, j;
3918
3919 current_drive->mode=READ_M1;
3920
3921#undef LOOP_COUNT
3922#define LOOP_COUNT 10 /* needed for some "old" drives */
3923
3924 msg(DBG_000,"DiskInfo entered.\n");
3925 for (j=1;j<LOOP_COUNT;j++)
3926 {
3927#if 0
3928 i=SetSpeed();
3929 if (i<0)
3930 {
3931 msg(DBG_INF,"DiskInfo: SetSpeed returns %d\n", i);
3932 continue;
3933 }
3934 i=cc_ModeSense();
3935 if (i<0)
3936 {
3937 msg(DBG_INF,"DiskInfo: cc_ModeSense returns %d\n", i);
3938 continue;
3939 }
3940#endif
3941 i=cc_ReadCapacity();
3942 if (i>=0) break;
3943 msg(DBG_INF,"DiskInfo: ReadCapacity #%d returns %d\n", j, i);
3944#if 0
3945 i=cc_DriveReset();
3946#endif
3947 if (!fam0_drive && j == 2) break;
3948 }
3949 if (j==LOOP_COUNT) return (-33); /* give up */
3950
3951 i=cc_ReadTocDescr();
3952 if (i<0)
3953 {
3954 msg(DBG_INF,"DiskInfo: ReadTocDescr returns %d\n", i);
3955 return (i);
3956 }
3957 i=ReadToC();
3958 if (i<0)
3959 {
3960 msg(DBG_INF,"DiskInfo: ReadToC returns %d\n", i);
3961 return (i);
3962 }
3963 i=cc_CheckMultiSession();
3964 if (i<0)
3965 {
3966 msg(DBG_INF,"DiskInfo: cc_CheckMultiSession returns %d\n", i);
3967 return (i);
3968 }
3969 if (current_drive->f_multisession) current_drive->sbp_bufsiz=1; /* possibly a weird PhotoCD */
3970 else current_drive->sbp_bufsiz=buffers;
3971 i=cc_ReadTocEntry(current_drive->n_first_track);
3972 if (i<0)
3973 {
3974 msg(DBG_INF,"DiskInfo: cc_ReadTocEntry(1) returns %d\n", i);
3975 return (i);
3976 }
3977 i=cc_ReadUPC();
3978 if (i<0) msg(DBG_INF,"DiskInfo: cc_ReadUPC returns %d\n", i);
3979 if ((fam0L_drive) && (current_drive->xa_byte==0x20 || current_drive->xa_byte == 0x10))
3980 {
3981 /* XA disk with old drive */
3982 cc_ModeSelect(CD_FRAMESIZE_RAW1);
3983 cc_ModeSense();
3984 }
3985 if (famT_drive) cc_prep_mode_T();
3986 msg(DBG_000,"DiskInfo done.\n");
3987 return (0);
3988}
3989
3990static int sbpcd_drive_status(struct cdrom_device_info *cdi, int slot_nr)
3991{
3992 struct sbpcd_drive *p = cdi->handle;
3993 int st;
3994
3995 if (CDSL_CURRENT != slot_nr) {
3996 /* we have no changer support */
3997 return -EINVAL;
3998 }
3999
4000 cc_ReadStatus();
4001 st=ResponseStatus();
4002 if (st<0)
4003 {
4004 msg(DBG_INF,"sbpcd_drive_status: timeout.\n");
4005 return (0);
4006 }
4007 msg(DBG_000,"Drive Status: door_locked =%d.\n", st_door_locked);
4008 msg(DBG_000,"Drive Status: door_closed =%d.\n", st_door_closed);
4009 msg(DBG_000,"Drive Status: caddy_in =%d.\n", st_caddy_in);
4010 msg(DBG_000,"Drive Status: disk_ok =%d.\n", st_diskok);
4011 msg(DBG_000,"Drive Status: spinning =%d.\n", st_spinning);
4012 msg(DBG_000,"Drive Status: busy =%d.\n", st_busy);
4013
4014#if 0
4015 if (!(p->status_bits & p_door_closed)) return CDS_TRAY_OPEN;
4016 if (p->status_bits & p_disk_ok) return CDS_DISC_OK;
4017 if (p->status_bits & p_disk_in) return CDS_DRIVE_NOT_READY;
4018
4019 return CDS_NO_DISC;
4020#else
4021 if (p->status_bits & p_spinning) return CDS_DISC_OK;
4022/* return CDS_TRAY_OPEN; */
4023 return CDS_NO_DISC;
4024
4025#endif
4026
4027}
4028
4029
4030/*==========================================================================*/
4031#ifdef FUTURE
4032/*
4033 * called always if driver gets entered
4034 * returns 0 or ERROR2 or ERROR15
4035 */
4036static int prepare(u_char func, u_char subfunc)
4037{
4038 int i;
4039
4040 if (fam0L_drive)
4041 {
4042 i=inb(CDi_status);
4043 if (i&s_attention) GetStatus();
4044 }
4045 else if (fam1_drive) GetStatus();
4046 else if (fam2_drive) GetStatus();
4047 else if (famT_drive) GetStatus();
4048 if (current_drive->CD_changed==0xFF)
4049 {
4050 current_drive->diskstate_flags=0;
4051 current_drive->audio_state=0;
4052 if (!st_diskok)
4053 {
4054 i=check_allowed1(func,subfunc);
4055 if (i<0) return (-2);
4056 }
4057 else
4058 {
4059 i=check_allowed3(func,subfunc);
4060 if (i<0)
4061 {
4062 current_drive->CD_changed=1;
4063 return (-15);
4064 }
4065 }
4066 }
4067 else
4068 {
4069 if (!st_diskok)
4070 {
4071 current_drive->diskstate_flags=0;
4072 current_drive->audio_state=0;
4073 i=check_allowed1(func,subfunc);
4074 if (i<0) return (-2);
4075 }
4076 else
4077 {
4078 if (st_busy)
4079 {
4080 if (current_drive->audio_state!=audio_pausing)
4081 {
4082 i=check_allowed2(func,subfunc);
4083 if (i<0) return (-2);
4084 }
4085 }
4086 else
4087 {
4088 if (current_drive->audio_state==audio_playing) seek_pos_audio_end();
4089 current_drive->audio_state=0;
4090 }
4091 if (!frame_size_valid)
4092 {
4093 i=DiskInfo();
4094 if (i<0)
4095 {
4096 current_drive->diskstate_flags=0;
4097 current_drive->audio_state=0;
4098 i=check_allowed1(func,subfunc);
4099 if (i<0) return (-2);
4100 }
4101 }
4102 }
4103 }
4104 return (0);
4105}
4106#endif /* FUTURE */
4107/*==========================================================================*/
4108/*==========================================================================*/
4109/*
4110 * Check the results of the "get status" command.
4111 */
4112static int sbp_status(void)
4113{
4114 int st;
4115
4116 st=ResponseStatus();
4117 if (st<0)
4118 {
4119 msg(DBG_INF,"sbp_status: timeout.\n");
4120 return (0);
4121 }
4122
4123 if (!st_spinning) msg(DBG_SPI,"motor got off - ignoring.\n");
4124
4125 if (st_check)
4126 {
4127 msg(DBG_INF,"st_check detected - retrying.\n");
4128 return (0);
4129 }
4130 if (!st_door_closed)
4131 {
4132 msg(DBG_INF,"door is open - retrying.\n");
4133 return (0);
4134 }
4135 if (!st_caddy_in)
4136 {
4137 msg(DBG_INF,"disk removed - retrying.\n");
4138 return (0);
4139 }
4140 if (!st_diskok)
4141 {
4142 msg(DBG_INF,"!st_diskok detected - retrying.\n");
4143 return (0);
4144 }
4145 if (st_busy)
4146 {
4147 msg(DBG_INF,"st_busy detected - retrying.\n");
4148 return (0);
4149 }
4150 return (1);
4151}
4152/*==========================================================================*/
4153
4154static int sbpcd_get_last_session(struct cdrom_device_info *cdi, struct cdrom_multisession *ms_infp)
4155{
4156 struct sbpcd_drive *p = cdi->handle;
4157 ms_infp->addr_format = CDROM_LBA;
4158 ms_infp->addr.lba = p->lba_multi;
4159 if (p->f_multisession)
4160 ms_infp->xa_flag=1; /* valid redirection address */
4161 else
4162 ms_infp->xa_flag=0; /* invalid redirection address */
4163
4164 return 0;
4165}
4166
4167/*==========================================================================*/
4168/*==========================================================================*/
4169/*
4170 * ioctl support
4171 */
4172static int sbpcd_dev_ioctl(struct cdrom_device_info *cdi, u_int cmd,
4173 u_long arg)
4174{
4175 struct sbpcd_drive *p = cdi->handle;
4176 int i;
4177
4178 msg(DBG_IO2,"ioctl(%s, 0x%08lX, 0x%08lX)\n", cdi->name, cmd, arg);
4179 if (p->drv_id==-1) {
4180 msg(DBG_INF, "ioctl: bad device: %s\n", cdi->name);
4181 return (-ENXIO); /* no such drive */
4182 }
4183 down(&ioctl_read_sem);
4184 if (p != current_drive)
4185 switch_drive(p);
4186
4187 msg(DBG_IO2,"ioctl: device %s, request %04X\n",cdi->name,cmd);
4188 switch (cmd) /* Sun-compatible */
4189 {
4190 case DDIOCSDBG: /* DDI Debug */
4191 if (!capable(CAP_SYS_ADMIN)) RETURN_UP(-EPERM);
4192 i=sbpcd_dbg_ioctl(arg,1);
4193 RETURN_UP(i);
4194 case CDROMRESET: /* hard reset the drive */
4195 msg(DBG_IOC,"ioctl: CDROMRESET entered.\n");
4196 i=DriveReset();
4197 current_drive->audio_state=0;
4198 RETURN_UP(i);
4199
4200 case CDROMREADMODE1:
4201 msg(DBG_IOC,"ioctl: CDROMREADMODE1 requested.\n");
4202#ifdef SAFE_MIXED
4203 if (current_drive->has_data>1) RETURN_UP(-EBUSY);
4204#endif /* SAFE_MIXED */
4205 cc_ModeSelect(CD_FRAMESIZE);
4206 cc_ModeSense();
4207 current_drive->mode=READ_M1;
4208 RETURN_UP(0);
4209
4210 case CDROMREADMODE2: /* not usable at the moment */
4211 msg(DBG_IOC,"ioctl: CDROMREADMODE2 requested.\n");
4212#ifdef SAFE_MIXED
4213 if (current_drive->has_data>1) RETURN_UP(-EBUSY);
4214#endif /* SAFE_MIXED */
4215 cc_ModeSelect(CD_FRAMESIZE_RAW1);
4216 cc_ModeSense();
4217 current_drive->mode=READ_M2;
4218 RETURN_UP(0);
4219
4220 case CDROMAUDIOBUFSIZ: /* configure the audio buffer size */
4221 msg(DBG_IOC,"ioctl: CDROMAUDIOBUFSIZ entered.\n");
4222 if (current_drive->sbp_audsiz>0) vfree(current_drive->aud_buf);
4223 current_drive->aud_buf=NULL;
4224 current_drive->sbp_audsiz=arg;
4225
4226 if (current_drive->sbp_audsiz>16)
4227 {
4228 current_drive->sbp_audsiz = 0;
4229 RETURN_UP(current_drive->sbp_audsiz);
4230 }
4231
4232 if (current_drive->sbp_audsiz>0)
4233 {
4234 current_drive->aud_buf=(u_char *) vmalloc(current_drive->sbp_audsiz*CD_FRAMESIZE_RAW);
4235 if (current_drive->aud_buf==NULL)
4236 {
4237 msg(DBG_INF,"audio buffer (%d frames) not available.\n",current_drive->sbp_audsiz);
4238 current_drive->sbp_audsiz=0;
4239 }
4240 else msg(DBG_INF,"audio buffer size: %d frames.\n",current_drive->sbp_audsiz);
4241 }
4242 RETURN_UP(current_drive->sbp_audsiz);
4243
4244 case CDROMREADAUDIO:
4245 { /* start of CDROMREADAUDIO */
4246 int i=0, j=0, frame, block=0;
4247 u_int try=0;
4248 u_long timeout;
4249 u_char *p;
4250 u_int data_tries = 0;
4251 u_int data_waits = 0;
4252 u_int data_retrying = 0;
4253 int status_tries;
4254 int error_flag;
4255
4256 msg(DBG_IOC,"ioctl: CDROMREADAUDIO entered.\n");
4257 if (fam0_drive) RETURN_UP(-EINVAL);
4258 if (famL_drive) RETURN_UP(-EINVAL);
4259 if (famV_drive) RETURN_UP(-EINVAL);
4260 if (famT_drive) RETURN_UP(-EINVAL);
4261#ifdef SAFE_MIXED
4262 if (current_drive->has_data>1) RETURN_UP(-EBUSY);
4263#endif /* SAFE_MIXED */
4264 if (current_drive->aud_buf==NULL) RETURN_UP(-EINVAL);
4265 if (copy_from_user(&read_audio, (void __user *)arg,
4266 sizeof(struct cdrom_read_audio)))
4267 RETURN_UP(-EFAULT);
4268 if (read_audio.nframes < 0 || read_audio.nframes>current_drive->sbp_audsiz) RETURN_UP(-EINVAL);
4269 if (!access_ok(VERIFY_WRITE, read_audio.buf,
4270 read_audio.nframes*CD_FRAMESIZE_RAW))
4271 RETURN_UP(-EFAULT);
4272
4273 if (read_audio.addr_format==CDROM_MSF) /* MSF-bin specification of where to start */
4274 block=msf2lba(&read_audio.addr.msf.minute);
4275 else if (read_audio.addr_format==CDROM_LBA) /* lba specification of where to start */
4276 block=read_audio.addr.lba;
4277 else RETURN_UP(-EINVAL);
4278#if 000
4279 i=cc_SetSpeed(speed_150,0,0);
4280 if (i) msg(DBG_AUD,"read_audio: SetSpeed error %d\n", i);
4281#endif
4282 msg(DBG_AUD,"read_audio: lba: %d, msf: %06X\n",
4283 block, blk2msf(block));
4284 msg(DBG_AUD,"read_audio: before cc_ReadStatus.\n");
4285#if OLD_BUSY
4286 while (busy_data) sbp_sleep(HZ/10); /* wait a bit */
4287 busy_audio=1;
4288#endif /* OLD_BUSY */
4289 error_flag=0;
4290 for (data_tries=5; data_tries>0; data_tries--)
4291 {
4292 msg(DBG_AUD,"data_tries=%d ...\n", data_tries);
4293 current_drive->mode=READ_AU;
4294 cc_ModeSelect(CD_FRAMESIZE_RAW);
4295 cc_ModeSense();
4296 for (status_tries=3; status_tries > 0; status_tries--)
4297 {
4298 flags_cmd_out |= f_respo3;
4299 cc_ReadStatus();
4300 if (sbp_status() != 0) break;
4301 if (st_check) cc_ReadError();
4302 sbp_sleep(1); /* wait a bit, try again */
4303 }
4304 if (status_tries == 0)
4305 {
4306 msg(DBG_AUD,"read_audio: sbp_status: failed after 3 tries in line %d.\n", __LINE__);
4307 continue;
4308 }
4309 msg(DBG_AUD,"read_audio: sbp_status: ok.\n");
4310
4311 flags_cmd_out = f_putcmd | f_respo2 | f_ResponseStatus | f_obey_p_check;
4312 if (fam0L_drive)
4313 {
4314 flags_cmd_out |= f_lopsta | f_getsta | f_bit1;
4315 cmd_type=READ_M2;
4316 drvcmd[0]=CMD0_READ_XA; /* "read XA frames", old drives */
4317 drvcmd[1]=(block>>16)&0x000000ff;
4318 drvcmd[2]=(block>>8)&0x000000ff;
4319 drvcmd[3]=block&0x000000ff;
4320 drvcmd[4]=0;
4321 drvcmd[5]=read_audio.nframes; /* # of frames */
4322 drvcmd[6]=0;
4323 }
4324 else if (fam1_drive)
4325 {
4326 drvcmd[0]=CMD1_READ; /* "read frames", new drives */
4327 lba2msf(block,&drvcmd[1]); /* msf-bin format required */
4328 drvcmd[4]=0;
4329 drvcmd[5]=0;
4330 drvcmd[6]=read_audio.nframes; /* # of frames */
4331 }
4332 else if (fam2_drive)
4333 {
4334 drvcmd[0]=CMD2_READ_XA2;
4335 lba2msf(block,&drvcmd[1]); /* msf-bin format required */
4336 drvcmd[4]=0;
4337 drvcmd[5]=read_audio.nframes; /* # of frames */
4338 drvcmd[6]=0x11; /* raw mode */
4339 }
4340 else if (famT_drive) /* CD-55A: not tested yet */
4341 {
4342 }
4343 msg(DBG_AUD,"read_audio: before giving \"read\" command.\n");
4344 flags_cmd_out=f_putcmd;
4345 response_count=0;
4346 i=cmd_out();
4347 if (i<0) msg(DBG_INF,"error giving READ AUDIO command: %0d\n", i);
4348 sbp_sleep(0);
4349 msg(DBG_AUD,"read_audio: after giving \"read\" command.\n");
4350 for (frame=1;frame<2 && !error_flag; frame++)
4351 {
4352 try=maxtim_data;
4353 for (timeout=jiffies+9*HZ; ; )
4354 {
4355 for ( ; try!=0;try--)
4356 {
4357 j=inb(CDi_status);
4358 if (!(j&s_not_data_ready)) break;
4359 if (!(j&s_not_result_ready)) break;
4360 if (fam0L_drive) if (j&s_attention) break;
4361 }
4362 if (try != 0 || time_after_eq(jiffies, timeout)) break;
4363 if (data_retrying == 0) data_waits++;
4364 data_retrying = 1;
4365 sbp_sleep(1);
4366 try = 1;
4367 }
4368 if (try==0)
4369 {
4370 msg(DBG_INF,"read_audio: sbp_data: CDi_status timeout.\n");
4371 error_flag++;
4372 break;
4373 }
4374 msg(DBG_AUD,"read_audio: sbp_data: CDi_status ok.\n");
4375 if (j&s_not_data_ready)
4376 {
4377 msg(DBG_INF, "read_audio: sbp_data: DATA_READY timeout.\n");
4378 error_flag++;
4379 break;
4380 }
4381 msg(DBG_AUD,"read_audio: before reading data.\n");
4382 error_flag=0;
4383 p = current_drive->aud_buf;
4384 if (sbpro_type==1) OUT(CDo_sel_i_d,1);
4385 if (do_16bit)
4386 {
4387 u_short *p2 = (u_short *) p;
4388
4389 for (; (u_char *) p2 < current_drive->aud_buf + read_audio.nframes*CD_FRAMESIZE_RAW;)
4390 {
4391 if ((inb_p(CDi_status)&s_not_data_ready)) continue;
4392
4393 /* get one sample */
4394 *p2++ = inw_p(CDi_data);
4395 *p2++ = inw_p(CDi_data);
4396 }
4397 } else {
4398 for (; p < current_drive->aud_buf + read_audio.nframes*CD_FRAMESIZE_RAW;)
4399 {
4400 if ((inb_p(CDi_status)&s_not_data_ready)) continue;
4401
4402 /* get one sample */
4403 *p++ = inb_p(CDi_data);
4404 *p++ = inb_p(CDi_data);
4405 *p++ = inb_p(CDi_data);
4406 *p++ = inb_p(CDi_data);
4407 }
4408 }
4409 if (sbpro_type==1) OUT(CDo_sel_i_d,0);
4410 data_retrying = 0;
4411 }
4412 msg(DBG_AUD,"read_audio: after reading data.\n");
4413 if (error_flag) /* must have been spurious D_RDY or (ATTN&&!D_RDY) */
4414 {
4415 msg(DBG_AUD,"read_audio: read aborted by drive\n");
4416#if 0000
4417 i=cc_DriveReset(); /* ugly fix to prevent a hang */
4418#else
4419 i=cc_ReadError();
4420#endif
4421 continue;
4422 }
4423 if (fam0L_drive)
4424 {
4425 i=maxtim_data;
4426 for (timeout=jiffies+9*HZ; time_before(jiffies, timeout); timeout--)
4427 {
4428 for ( ;i!=0;i--)
4429 {
4430 j=inb(CDi_status);
4431 if (!(j&s_not_data_ready)) break;
4432 if (!(j&s_not_result_ready)) break;
4433 if (j&s_attention) break;
4434 }
4435 if (i != 0 || time_after_eq(jiffies, timeout)) break;
4436 sbp_sleep(0);
4437 i = 1;
4438 }
4439 if (i==0) msg(DBG_AUD,"read_audio: STATUS TIMEOUT AFTER READ");
4440 if (!(j&s_attention))
4441 {
4442 msg(DBG_AUD,"read_audio: sbp_data: timeout waiting DRV_ATTN - retrying\n");
4443 i=cc_DriveReset(); /* ugly fix to prevent a hang */
4444 continue;
4445 }
4446 }
4447 do
4448 {
4449 if (fam0L_drive) cc_ReadStatus();
4450 i=ResponseStatus(); /* builds status_bits, returns orig. status (old) or faked p_success (new) */
4451 if (i<0) { msg(DBG_AUD,
4452 "read_audio: cc_ReadStatus error after read: %02X\n",
4453 current_drive->status_bits);
4454 continue; /* FIXME */
4455 }
4456 }
4457 while ((fam0L_drive)&&(!st_check)&&(!(i&p_success)));
4458 if (st_check)
4459 {
4460 i=cc_ReadError();
4461 msg(DBG_AUD,"read_audio: cc_ReadError was necessary after read: %02X\n",i);
4462 continue;
4463 }
4464 if (copy_to_user(read_audio.buf,
4465 current_drive->aud_buf,
4466 read_audio.nframes * CD_FRAMESIZE_RAW))
4467 RETURN_UP(-EFAULT);
4468 msg(DBG_AUD,"read_audio: copy_to_user done.\n");
4469 break;
4470 }
4471 cc_ModeSelect(CD_FRAMESIZE);
4472 cc_ModeSense();
4473 current_drive->mode=READ_M1;
4474#if OLD_BUSY
4475 busy_audio=0;
4476#endif /* OLD_BUSY */
4477 if (data_tries == 0)
4478 {
4479 msg(DBG_AUD,"read_audio: failed after 5 tries in line %d.\n", __LINE__);
4480 RETURN_UP(-EIO);
4481 }
4482 msg(DBG_AUD,"read_audio: successful return.\n");
4483 RETURN_UP(0);
4484 } /* end of CDROMREADAUDIO */
4485
4486 default:
4487 msg(DBG_IOC,"ioctl: unknown function request %04X\n", cmd);
4488 RETURN_UP(-EINVAL);
4489 } /* end switch(cmd) */
4490}
4491
4492static int sbpcd_audio_ioctl(struct cdrom_device_info *cdi, u_int cmd,
4493 void * arg)
4494{
4495 struct sbpcd_drive *p = cdi->handle;
4496 int i, st, j;
4497
4498 msg(DBG_IO2,"ioctl(%s, 0x%08lX, 0x%08p)\n", cdi->name, cmd, arg);
4499 if (p->drv_id==-1) {
4500 msg(DBG_INF, "ioctl: bad device: %s\n", cdi->name);
4501 return (-ENXIO); /* no such drive */
4502 }
4503 down(&ioctl_read_sem);
4504 if (p != current_drive)
4505 switch_drive(p);
4506
4507 msg(DBG_IO2,"ioctl: device %s, request %04X\n",cdi->name,cmd);
4508 switch (cmd) /* Sun-compatible */
4509 {
4510
4511 case CDROMPAUSE: /* Pause the drive */
4512 msg(DBG_IOC,"ioctl: CDROMPAUSE entered.\n");
4513 /* pause the drive unit when it is currently in PLAY mode, */
4514 /* or reset the starting and ending locations when in PAUSED mode. */
4515 /* If applicable, at the next stopping point it reaches */
4516 /* the drive will discontinue playing. */
4517 switch (current_drive->audio_state)
4518 {
4519 case audio_playing:
4520 if (famL_drive) i=cc_ReadSubQ();
4521 else i=cc_Pause_Resume(1);
4522 if (i<0) RETURN_UP(-EIO);
4523 if (famL_drive) i=cc_Pause_Resume(1);
4524 else i=cc_ReadSubQ();
4525 if (i<0) RETURN_UP(-EIO);
4526 current_drive->pos_audio_start=current_drive->SubQ_run_tot;
4527 current_drive->audio_state=audio_pausing;
4528 RETURN_UP(0);
4529 case audio_pausing:
4530 i=cc_Seek(current_drive->pos_audio_start,1);
4531 if (i<0) RETURN_UP(-EIO);
4532 RETURN_UP(0);
4533 default:
4534 RETURN_UP(-EINVAL);
4535 }
4536
4537 case CDROMRESUME: /* resume paused audio play */
4538 msg(DBG_IOC,"ioctl: CDROMRESUME entered.\n");
4539 /* resume playing audio tracks when a previous PLAY AUDIO call has */
4540 /* been paused with a PAUSE command. */
4541 /* It will resume playing from the location saved in SubQ_run_tot. */
4542 if (current_drive->audio_state!=audio_pausing) RETURN_UP(-EINVAL);
4543 if (famL_drive)
4544 i=cc_PlayAudio(current_drive->pos_audio_start,
4545 current_drive->pos_audio_end);
4546 else i=cc_Pause_Resume(3);
4547 if (i<0) RETURN_UP(-EIO);
4548 current_drive->audio_state=audio_playing;
4549 RETURN_UP(0);
4550
4551 case CDROMPLAYMSF:
4552 msg(DBG_IOC,"ioctl: CDROMPLAYMSF entered.\n");
4553#ifdef SAFE_MIXED
4554 if (current_drive->has_data>1) RETURN_UP(-EBUSY);
4555#endif /* SAFE_MIXED */
4556 if (current_drive->audio_state==audio_playing)
4557 {
4558 i=cc_Pause_Resume(1);
4559 if (i<0) RETURN_UP(-EIO);
4560 i=cc_ReadSubQ();
4561 if (i<0) RETURN_UP(-EIO);
4562 current_drive->pos_audio_start=current_drive->SubQ_run_tot;
4563 i=cc_Seek(current_drive->pos_audio_start,1);
4564 }
4565 memcpy(&msf, (void *) arg, sizeof(struct cdrom_msf));
4566 /* values come as msf-bin */
4567 current_drive->pos_audio_start = (msf.cdmsf_min0<<16) |
4568 (msf.cdmsf_sec0<<8) |
4569 msf.cdmsf_frame0;
4570 current_drive->pos_audio_end = (msf.cdmsf_min1<<16) |
4571 (msf.cdmsf_sec1<<8) |
4572 msf.cdmsf_frame1;
4573 msg(DBG_IOX,"ioctl: CDROMPLAYMSF %08X %08X\n",
4574 current_drive->pos_audio_start,current_drive->pos_audio_end);
4575 i=cc_PlayAudio(current_drive->pos_audio_start,current_drive->pos_audio_end);
4576 if (i<0)
4577 {
4578 msg(DBG_INF,"ioctl: cc_PlayAudio returns %d\n",i);
4579 DriveReset();
4580 current_drive->audio_state=0;
4581 RETURN_UP(-EIO);
4582 }
4583 current_drive->audio_state=audio_playing;
4584 RETURN_UP(0);
4585
4586 case CDROMPLAYTRKIND: /* Play a track. This currently ignores index. */
4587 msg(DBG_IOC,"ioctl: CDROMPLAYTRKIND entered.\n");
4588#ifdef SAFE_MIXED
4589 if (current_drive->has_data>1) RETURN_UP(-EBUSY);
4590#endif /* SAFE_MIXED */
4591 if (current_drive->audio_state==audio_playing)
4592 {
4593 msg(DBG_IOX,"CDROMPLAYTRKIND: already audio_playing.\n");
4594#if 1
4595 RETURN_UP(0); /* just let us play on */
4596#else
4597 RETURN_UP(-EINVAL); /* play on, but say "error" */
4598#endif
4599 }
4600 memcpy(&ti,(void *) arg,sizeof(struct cdrom_ti));
4601 msg(DBG_IOX,"ioctl: trk0: %d, ind0: %d, trk1:%d, ind1:%d\n",
4602 ti.cdti_trk0,ti.cdti_ind0,ti.cdti_trk1,ti.cdti_ind1);
4603 if (ti.cdti_trk0<current_drive->n_first_track) RETURN_UP(-EINVAL);
4604 if (ti.cdti_trk0>current_drive->n_last_track) RETURN_UP(-EINVAL);
4605 if (ti.cdti_trk1<ti.cdti_trk0) ti.cdti_trk1=ti.cdti_trk0;
4606 if (ti.cdti_trk1>current_drive->n_last_track) ti.cdti_trk1=current_drive->n_last_track;
4607 current_drive->pos_audio_start=current_drive->TocBuffer[ti.cdti_trk0].address;
4608 current_drive->pos_audio_end=current_drive->TocBuffer[ti.cdti_trk1+1].address;
4609 i=cc_PlayAudio(current_drive->pos_audio_start,current_drive->pos_audio_end);
4610 if (i<0)
4611 {
4612 msg(DBG_INF,"ioctl: cc_PlayAudio returns %d\n",i);
4613 DriveReset();
4614 current_drive->audio_state=0;
4615 RETURN_UP(-EIO);
4616 }
4617 current_drive->audio_state=audio_playing;
4618 RETURN_UP(0);
4619
4620 case CDROMREADTOCHDR: /* Read the table of contents header */
4621 msg(DBG_IOC,"ioctl: CDROMREADTOCHDR entered.\n");
4622 tochdr.cdth_trk0=current_drive->n_first_track;
4623 tochdr.cdth_trk1=current_drive->n_last_track;
4624 memcpy((void *) arg, &tochdr, sizeof(struct cdrom_tochdr));
4625 RETURN_UP(0);
4626
4627 case CDROMREADTOCENTRY: /* Read an entry in the table of contents */
4628 msg(DBG_IOC,"ioctl: CDROMREADTOCENTRY entered.\n");
4629 memcpy(&tocentry, (void *) arg, sizeof(struct cdrom_tocentry));
4630 i=tocentry.cdte_track;
4631 if (i==CDROM_LEADOUT) i=current_drive->n_last_track+1;
4632 else if (i<current_drive->n_first_track||i>current_drive->n_last_track)
4633 RETURN_UP(-EINVAL);
4634 tocentry.cdte_adr=current_drive->TocBuffer[i].ctl_adr&0x0F;
4635 tocentry.cdte_ctrl=(current_drive->TocBuffer[i].ctl_adr>>4)&0x0F;
4636 tocentry.cdte_datamode=current_drive->TocBuffer[i].format;
4637 if (tocentry.cdte_format==CDROM_MSF) /* MSF-bin required */
4638 {
4639 tocentry.cdte_addr.msf.minute=(current_drive->TocBuffer[i].address>>16)&0x00FF;
4640 tocentry.cdte_addr.msf.second=(current_drive->TocBuffer[i].address>>8)&0x00FF;
4641 tocentry.cdte_addr.msf.frame=current_drive->TocBuffer[i].address&0x00FF;
4642 }
4643 else if (tocentry.cdte_format==CDROM_LBA) /* blk required */
4644 tocentry.cdte_addr.lba=msf2blk(current_drive->TocBuffer[i].address);
4645 else RETURN_UP(-EINVAL);
4646 memcpy((void *) arg, &tocentry, sizeof(struct cdrom_tocentry));
4647 RETURN_UP(0);
4648
4649 case CDROMSTOP: /* Spin down the drive */
4650 msg(DBG_IOC,"ioctl: CDROMSTOP entered.\n");
4651#ifdef SAFE_MIXED
4652 if (current_drive->has_data>1) RETURN_UP(-EBUSY);
4653#endif /* SAFE_MIXED */
4654 i=cc_Pause_Resume(1);
4655 current_drive->audio_state=0;
4656#if 0
4657 cc_DriveReset();
4658#endif
4659 RETURN_UP(i);
4660
4661 case CDROMSTART: /* Spin up the drive */
4662 msg(DBG_IOC,"ioctl: CDROMSTART entered.\n");
4663 cc_SpinUp();
4664 current_drive->audio_state=0;
4665 RETURN_UP(0);
4666
4667 case CDROMVOLCTRL: /* Volume control */
4668 msg(DBG_IOC,"ioctl: CDROMVOLCTRL entered.\n");
4669 memcpy(&volctrl,(char *) arg,sizeof(volctrl));
4670 current_drive->vol_chan0=0;
4671 current_drive->vol_ctrl0=volctrl.channel0;
4672 current_drive->vol_chan1=1;
4673 current_drive->vol_ctrl1=volctrl.channel1;
4674 i=cc_SetVolume();
4675 RETURN_UP(0);
4676
4677 case CDROMVOLREAD: /* read Volume settings from drive */
4678 msg(DBG_IOC,"ioctl: CDROMVOLREAD entered.\n");
4679 st=cc_GetVolume();
4680 if (st<0) RETURN_UP(st);
4681 volctrl.channel0=current_drive->vol_ctrl0;
4682 volctrl.channel1=current_drive->vol_ctrl1;
4683 volctrl.channel2=0;
4684 volctrl.channel2=0;
4685 memcpy((void *)arg,&volctrl,sizeof(volctrl));
4686 RETURN_UP(0);
4687
4688 case CDROMSUBCHNL: /* Get subchannel info */
4689 msg(DBG_IOS,"ioctl: CDROMSUBCHNL entered.\n");
4690 /* Bogus, I can do better than this! --AJK
4691 if ((st_spinning)||(!subq_valid)) {
4692 i=cc_ReadSubQ();
4693 if (i<0) RETURN_UP(-EIO);
4694 }
4695 */
4696 i=cc_ReadSubQ();
4697 if (i<0) {
4698 j=cc_ReadError(); /* clear out error status from drive */
4699 current_drive->audio_state=CDROM_AUDIO_NO_STATUS;
4700 /* get and set the disk state here,
4701 probably not the right place, but who cares!
4702 It makes it work properly! --AJK */
4703 if (current_drive->CD_changed==0xFF) {
4704 msg(DBG_000,"Disk changed detect\n");
4705 current_drive->diskstate_flags &= ~cd_size_bit;
4706 }
4707 RETURN_UP(-EIO);
4708 }
4709 if (current_drive->CD_changed==0xFF) {
4710 /* reread the TOC because the disk has changed! --AJK */
4711 msg(DBG_000,"Disk changed STILL detected, rereading TOC!\n");
4712 i=DiskInfo();
4713 if(i==0) {
4714 current_drive->CD_changed=0x00; /* cd has changed, procede, */
4715 RETURN_UP(-EIO); /* and get TOC, etc on next try! --AJK */
4716 } else {
4717 RETURN_UP(-EIO); /* we weren't ready yet! --AJK */
4718 }
4719 }
4720 memcpy(&SC, (void *) arg, sizeof(struct cdrom_subchnl));
4721 /*
4722 This virtual crap is very bogus!
4723 It doesn't detect when the cd is done playing audio!
4724 Lets do this right with proper hardware register reading!
4725 */
4726 cc_ReadStatus();
4727 i=ResponseStatus();
4728 msg(DBG_000,"Drive Status: door_locked =%d.\n", st_door_locked);
4729 msg(DBG_000,"Drive Status: door_closed =%d.\n", st_door_closed);
4730 msg(DBG_000,"Drive Status: caddy_in =%d.\n", st_caddy_in);
4731 msg(DBG_000,"Drive Status: disk_ok =%d.\n", st_diskok);
4732 msg(DBG_000,"Drive Status: spinning =%d.\n", st_spinning);
4733 msg(DBG_000,"Drive Status: busy =%d.\n", st_busy);
4734 /* st_busy indicates if it's _ACTUALLY_ playing audio */
4735 switch (current_drive->audio_state)
4736 {
4737 case audio_playing:
4738 if(st_busy==0) {
4739 /* CD has stopped playing audio --AJK */
4740 current_drive->audio_state=audio_completed;
4741 SC.cdsc_audiostatus=CDROM_AUDIO_COMPLETED;
4742 } else {
4743 SC.cdsc_audiostatus=CDROM_AUDIO_PLAY;
4744 }
4745 break;
4746 case audio_pausing:
4747 SC.cdsc_audiostatus=CDROM_AUDIO_PAUSED;
4748 break;
4749 case audio_completed:
4750 SC.cdsc_audiostatus=CDROM_AUDIO_COMPLETED;
4751 break;
4752 default:
4753 SC.cdsc_audiostatus=CDROM_AUDIO_NO_STATUS;
4754 break;
4755 }
4756 SC.cdsc_adr=current_drive->SubQ_ctl_adr;
4757 SC.cdsc_ctrl=current_drive->SubQ_ctl_adr>>4;
4758 SC.cdsc_trk=bcd2bin(current_drive->SubQ_trk);
4759 SC.cdsc_ind=bcd2bin(current_drive->SubQ_pnt_idx);
4760 if (SC.cdsc_format==CDROM_LBA)
4761 {
4762 SC.cdsc_absaddr.lba=msf2blk(current_drive->SubQ_run_tot);
4763 SC.cdsc_reladdr.lba=msf2blk(current_drive->SubQ_run_trk);
4764 }
4765 else /* not only if (SC.cdsc_format==CDROM_MSF) */
4766 {
4767 SC.cdsc_absaddr.msf.minute=(current_drive->SubQ_run_tot>>16)&0x00FF;
4768 SC.cdsc_absaddr.msf.second=(current_drive->SubQ_run_tot>>8)&0x00FF;
4769 SC.cdsc_absaddr.msf.frame=current_drive->SubQ_run_tot&0x00FF;
4770 SC.cdsc_reladdr.msf.minute=(current_drive->SubQ_run_trk>>16)&0x00FF;
4771 SC.cdsc_reladdr.msf.second=(current_drive->SubQ_run_trk>>8)&0x00FF;
4772 SC.cdsc_reladdr.msf.frame=current_drive->SubQ_run_trk&0x00FF;
4773 }
4774 memcpy((void *) arg, &SC, sizeof(struct cdrom_subchnl));
4775 msg(DBG_IOS,"CDROMSUBCHNL: %1X %02X %08X %08X %02X %02X %06X %06X\n",
4776 SC.cdsc_format,SC.cdsc_audiostatus,
4777 SC.cdsc_adr,SC.cdsc_ctrl,
4778 SC.cdsc_trk,SC.cdsc_ind,
4779 SC.cdsc_absaddr,SC.cdsc_reladdr);
4780 RETURN_UP(0);
4781
4782 default:
4783 msg(DBG_IOC,"ioctl: unknown function request %04X\n", cmd);
4784 RETURN_UP(-EINVAL);
4785 } /* end switch(cmd) */
4786}
4787/*==========================================================================*/
4788/*
4789 * Take care of the different block sizes between cdrom and Linux.
4790 */
4791static void sbp_transfer(struct request *req)
4792{
4793 long offs;
4794
4795 while ( (req->nr_sectors > 0) &&
4796 (req->sector/4 >= current_drive->sbp_first_frame) &&
4797 (req->sector/4 <= current_drive->sbp_last_frame) )
4798 {
4799 offs = (req->sector - current_drive->sbp_first_frame * 4) * 512;
4800 memcpy(req->buffer, current_drive->sbp_buf + offs, 512);
4801 req->nr_sectors--;
4802 req->sector++;
4803 req->buffer += 512;
4804 }
4805}
4806/*==========================================================================*/
4807/*
4808 * special end_request for sbpcd to solve CURRENT==NULL bug. (GTL)
4809 * GTL = Gonzalo Tornaria <tornaria@cmat.edu.uy>
4810 *
4811 * This is a kludge so we don't need to modify end_request.
4812 * We put the req we take out after INIT_REQUEST in the requests list,
4813 * so that end_request will discard it.
4814 *
4815 * The bug could be present in other block devices, perhaps we
4816 * should modify INIT_REQUEST and end_request instead, and
4817 * change every block device..
4818 *
4819 * Could be a race here?? Could e.g. a timer interrupt schedule() us?
4820 * If so, we should copy end_request here, and do it right.. (or
4821 * modify end_request and the block devices).
4822 *
4823 * In any case, the race here would be much small than it was, and
4824 * I couldn't reproduce..
4825 *
4826 * The race could be: suppose CURRENT==NULL. We put our req in the list,
4827 * and we are scheduled. Other process takes over, and gets into
4828 * do_sbpcd_request. It sees CURRENT!=NULL (it is == to our req), so
4829 * proceeds. It ends, so CURRENT is now NULL.. Now we awake somewhere in
4830 * end_request, but now CURRENT==NULL... oops!
4831 *
4832 */
4833#undef DEBUG_GTL
4834
4835/*==========================================================================*/
4836/*
4837 * I/O request routine, called from Linux kernel.
4838 */
4839static void do_sbpcd_request(request_queue_t * q)
4840{
4841 u_int block;
4842 u_int nsect;
4843 int status_tries, data_tries;
4844 struct request *req;
4845 struct sbpcd_drive *p;
4846#ifdef DEBUG_GTL
4847 static int xx_nr=0;
4848 int xnr;
4849#endif
4850
4851 request_loop:
4852#ifdef DEBUG_GTL
4853 xnr=++xx_nr;
4854
4855 req = elv_next_request(q);
4856
4857 if (!req)
4858 {
4859 printk( "do_sbpcd_request[%di](NULL), Pid:%d, Time:%li\n",
4860 xnr, current->pid, jiffies);
4861 printk( "do_sbpcd_request[%do](NULL) end 0 (null), Time:%li\n",
4862 xnr, jiffies);
4863 return;
4864 }
4865
4866 printk(" do_sbpcd_request[%di](%p:%ld+%ld), Pid:%d, Time:%li\n",
4867 xnr, req, req->sector, req->nr_sectors, current->pid, jiffies);
4868#endif
4869
4870 req = elv_next_request(q); /* take out our request so no other */
4871 if (!req)
4872 return;
4873
4874 if (req -> sector == -1)
4875 end_request(req, 0);
4876 spin_unlock_irq(q->queue_lock);
4877
4878 down(&ioctl_read_sem);
4879 if (rq_data_dir(elv_next_request(q)) != READ)
4880 {
4881 msg(DBG_INF, "bad cmd %d\n", req->cmd[0]);
4882 goto err_done;
4883 }
4884 p = req->rq_disk->private_data;
4885#if OLD_BUSY
4886 while (busy_audio) sbp_sleep(HZ); /* wait a bit */
4887 busy_data=1;
4888#endif /* OLD_BUSY */
4889
4890 if (p->audio_state==audio_playing) goto err_done;
4891 if (p != current_drive)
4892 switch_drive(p);
4893
4894 block = req->sector; /* always numbered as 512-byte-pieces */
4895 nsect = req->nr_sectors; /* always counted as 512-byte-pieces */
4896
4897 msg(DBG_BSZ,"read sector %d (%d sectors)\n", block, nsect);
4898#if 0
4899 msg(DBG_MUL,"read LBA %d\n", block/4);
4900#endif
4901
4902 sbp_transfer(req);
4903 /* if we satisfied the request from the buffer, we're done. */
4904 if (req->nr_sectors == 0)
4905 {
4906#ifdef DEBUG_GTL
4907 printk(" do_sbpcd_request[%do](%p:%ld+%ld) end 2, Time:%li\n",
4908 xnr, req, req->sector, req->nr_sectors, jiffies);
4909#endif
4910 up(&ioctl_read_sem);
4911 spin_lock_irq(q->queue_lock);
4912 end_request(req, 1);
4913 goto request_loop;
4914 }
4915
4916#ifdef FUTURE
4917 i=prepare(0,0); /* at moment not really a hassle check, but ... */
4918 if (i!=0)
4919 msg(DBG_INF,"\"prepare\" tells error %d -- ignored\n", i);
4920#endif /* FUTURE */
4921
4922 if (!st_spinning) cc_SpinUp();
4923
4924 for (data_tries=n_retries; data_tries > 0; data_tries--)
4925 {
4926 for (status_tries=3; status_tries > 0; status_tries--)
4927 {
4928 flags_cmd_out |= f_respo3;
4929 cc_ReadStatus();
4930 if (sbp_status() != 0) break;
4931 if (st_check) cc_ReadError();
4932 sbp_sleep(1); /* wait a bit, try again */
4933 }
4934 if (status_tries == 0)
4935 {
4936 msg(DBG_INF,"sbp_status: failed after 3 tries in line %d\n", __LINE__);
4937 break;
4938 }
4939
4940 sbp_read_cmd(req);
4941 sbp_sleep(0);
4942 if (sbp_data(req) != 0)
4943 {
4944#ifdef SAFE_MIXED
4945 current_drive->has_data=2; /* is really a data disk */
4946#endif /* SAFE_MIXED */
4947#ifdef DEBUG_GTL
4948 printk(" do_sbpcd_request[%do](%p:%ld+%ld) end 3, Time:%li\n",
4949 xnr, req, req->sector, req->nr_sectors, jiffies);
4950#endif
4951 up(&ioctl_read_sem);
4952 spin_lock_irq(q->queue_lock);
4953 end_request(req, 1);
4954 goto request_loop;
4955 }
4956 }
4957
4958 err_done:
4959#if OLD_BUSY
4960 busy_data=0;
4961#endif /* OLD_BUSY */
4962#ifdef DEBUG_GTL
4963 printk(" do_sbpcd_request[%do](%p:%ld+%ld) end 4 (error), Time:%li\n",
4964 xnr, req, req->sector, req->nr_sectors, jiffies);
4965#endif
4966 up(&ioctl_read_sem);
4967 sbp_sleep(0); /* wait a bit, try again */
4968 spin_lock_irq(q->queue_lock);
4969 end_request(req, 0);
4970 goto request_loop;
4971}
4972/*==========================================================================*/
4973/*
4974 * build and send the READ command.
4975 */
4976static void sbp_read_cmd(struct request *req)
4977{
4978#undef OLD
4979
4980 int i;
4981 int block;
4982
4983 current_drive->sbp_first_frame=current_drive->sbp_last_frame=-1; /* purge buffer */
4984 current_drive->sbp_current = 0;
4985 block=req->sector/4;
4986 if (block+current_drive->sbp_bufsiz <= current_drive->CDsize_frm)
4987 current_drive->sbp_read_frames = current_drive->sbp_bufsiz;
4988 else
4989 {
4990 current_drive->sbp_read_frames=current_drive->CDsize_frm-block;
4991 /* avoid reading past end of data */
4992 if (current_drive->sbp_read_frames < 1)
4993 {
4994 msg(DBG_INF,"requested frame %d, CD size %d ???\n",
4995 block, current_drive->CDsize_frm);
4996 current_drive->sbp_read_frames=1;
4997 }
4998 }
4999
5000 flags_cmd_out = f_putcmd | f_respo2 | f_ResponseStatus | f_obey_p_check;
5001 clr_cmdbuf();
5002 if (famV_drive)
5003 {
5004 drvcmd[0]=CMDV_READ;
5005 lba2msf(block,&drvcmd[1]); /* msf-bcd format required */
5006 bin2bcdx(&drvcmd[1]);
5007 bin2bcdx(&drvcmd[2]);
5008 bin2bcdx(&drvcmd[3]);
5009 drvcmd[4]=current_drive->sbp_read_frames>>8;
5010 drvcmd[5]=current_drive->sbp_read_frames&0xff;
5011 drvcmd[6]=0x02; /* flag "msf-bcd" */
5012 }
5013 else if (fam0L_drive)
5014 {
5015 flags_cmd_out |= f_lopsta | f_getsta | f_bit1;
5016 if (current_drive->xa_byte==0x20)
5017 {
5018 cmd_type=READ_M2;
5019 drvcmd[0]=CMD0_READ_XA; /* "read XA frames", old drives */
5020 drvcmd[1]=(block>>16)&0x0ff;
5021 drvcmd[2]=(block>>8)&0x0ff;
5022 drvcmd[3]=block&0x0ff;
5023 drvcmd[4]=(current_drive->sbp_read_frames>>8)&0x0ff;
5024 drvcmd[5]=current_drive->sbp_read_frames&0x0ff;
5025 }
5026 else
5027 {
5028 drvcmd[0]=CMD0_READ; /* "read frames", old drives */
5029 if (current_drive->drv_type>=drv_201)
5030 {
5031 lba2msf(block,&drvcmd[1]); /* msf-bcd format required */
5032 bin2bcdx(&drvcmd[1]);
5033 bin2bcdx(&drvcmd[2]);
5034 bin2bcdx(&drvcmd[3]);
5035 }
5036 else
5037 {
5038 drvcmd[1]=(block>>16)&0x0ff;
5039 drvcmd[2]=(block>>8)&0x0ff;
5040 drvcmd[3]=block&0x0ff;
5041 }
5042 drvcmd[4]=(current_drive->sbp_read_frames>>8)&0x0ff;
5043 drvcmd[5]=current_drive->sbp_read_frames&0x0ff;
5044 drvcmd[6]=(current_drive->drv_type<drv_201)?0:2; /* flag "lba or msf-bcd format" */
5045 }
5046 }
5047 else if (fam1_drive)
5048 {
5049 drvcmd[0]=CMD1_READ;
5050 lba2msf(block,&drvcmd[1]); /* msf-bin format required */
5051 drvcmd[5]=(current_drive->sbp_read_frames>>8)&0x0ff;
5052 drvcmd[6]=current_drive->sbp_read_frames&0x0ff;
5053 }
5054 else if (fam2_drive)
5055 {
5056 drvcmd[0]=CMD2_READ;
5057 lba2msf(block,&drvcmd[1]); /* msf-bin format required */
5058 drvcmd[4]=(current_drive->sbp_read_frames>>8)&0x0ff;
5059 drvcmd[5]=current_drive->sbp_read_frames&0x0ff;
5060 drvcmd[6]=0x02;
5061 }
5062 else if (famT_drive)
5063 {
5064 drvcmd[0]=CMDT_READ;
5065 drvcmd[2]=(block>>24)&0x0ff;
5066 drvcmd[3]=(block>>16)&0x0ff;
5067 drvcmd[4]=(block>>8)&0x0ff;
5068 drvcmd[5]=block&0x0ff;
5069 drvcmd[7]=(current_drive->sbp_read_frames>>8)&0x0ff;
5070 drvcmd[8]=current_drive->sbp_read_frames&0x0ff;
5071 }
5072 flags_cmd_out=f_putcmd;
5073 response_count=0;
5074 i=cmd_out();
5075 if (i<0) msg(DBG_INF,"error giving READ command: %0d\n", i);
5076 return;
5077}
5078/*==========================================================================*/
5079/*
5080 * Check the completion of the read-data command. On success, read
5081 * the current_drive->sbp_bufsiz * 2048 bytes of data from the disk into buffer.
5082 */
5083static int sbp_data(struct request *req)
5084{
5085 int i=0, j=0, l, frame;
5086 u_int try=0;
5087 u_long timeout;
5088 u_char *p;
5089 u_int data_tries = 0;
5090 u_int data_waits = 0;
5091 u_int data_retrying = 0;
5092 int error_flag;
5093 int xa_count;
5094 int max_latency;
5095 int success;
5096 int wait;
5097 int duration;
5098
5099 error_flag=0;
5100 success=0;
5101#if LONG_TIMING
5102 max_latency=9*HZ;
5103#else
5104 if (current_drive->f_multisession) max_latency=15*HZ;
5105 else max_latency=5*HZ;
5106#endif
5107 duration=jiffies;
5108 for (frame=0;frame<current_drive->sbp_read_frames&&!error_flag; frame++)
5109 {
5110 SBPCD_CLI;
5111
5112 del_timer(&data_timer);
5113 data_timer.expires=jiffies+max_latency;
5114 timed_out_data=0;
5115 add_timer(&data_timer);
5116 while (!timed_out_data)
5117 {
5118 if (current_drive->f_multisession) try=maxtim_data*4;
5119 else try=maxtim_data;
5120 msg(DBG_000,"sbp_data: CDi_status loop: try=%d.\n",try);
5121 for ( ; try!=0;try--)
5122 {
5123 j=inb(CDi_status);
5124 if (!(j&s_not_data_ready)) break;
5125 if (!(j&s_not_result_ready)) break;
5126 if (fam0LV_drive) if (j&s_attention) break;
5127 }
5128 if (!(j&s_not_data_ready)) goto data_ready;
5129 if (try==0)
5130 {
5131 if (data_retrying == 0) data_waits++;
5132 data_retrying = 1;
5133 msg(DBG_000,"sbp_data: CDi_status loop: sleeping.\n");
5134 sbp_sleep(1);
5135 try = 1;
5136 }
5137 }
5138 msg(DBG_INF,"sbp_data: CDi_status loop expired.\n");
5139 data_ready:
5140 del_timer(&data_timer);
5141
5142 if (timed_out_data)
5143 {
5144 msg(DBG_INF,"sbp_data: CDi_status timeout (timed_out_data) (%02X).\n", j);
5145 error_flag++;
5146 }
5147 if (try==0)
5148 {
5149 msg(DBG_INF,"sbp_data: CDi_status timeout (try=0) (%02X).\n", j);
5150 error_flag++;
5151 }
5152 if (!(j&s_not_result_ready))
5153 {
5154 msg(DBG_INF, "sbp_data: RESULT_READY where DATA_READY awaited (%02X).\n", j);
5155 response_count=20;
5156 j=ResponseInfo();
5157 j=inb(CDi_status);
5158 }
5159 if (j&s_not_data_ready)
5160 {
5161 if ((current_drive->ored_ctl_adr&0x40)==0)
5162 msg(DBG_INF, "CD contains no data tracks.\n");
5163 else msg(DBG_INF, "sbp_data: DATA_READY timeout (%02X).\n", j);
5164 error_flag++;
5165 }
5166 SBPCD_STI;
5167 if (error_flag) break;
5168
5169 msg(DBG_000, "sbp_data: beginning to read.\n");
5170 p = current_drive->sbp_buf + frame * CD_FRAMESIZE;
5171 if (sbpro_type==1) OUT(CDo_sel_i_d,1);
5172 if (cmd_type==READ_M2) {
5173 if (do_16bit) insw(CDi_data, xa_head_buf, CD_XA_HEAD>>1);
5174 else insb(CDi_data, xa_head_buf, CD_XA_HEAD);
5175 }
5176 if (do_16bit) insw(CDi_data, p, CD_FRAMESIZE>>1);
5177 else insb(CDi_data, p, CD_FRAMESIZE);
5178 if (cmd_type==READ_M2) {
5179 if (do_16bit) insw(CDi_data, xa_tail_buf, CD_XA_TAIL>>1);
5180 else insb(CDi_data, xa_tail_buf, CD_XA_TAIL);
5181 }
5182 current_drive->sbp_current++;
5183 if (sbpro_type==1) OUT(CDo_sel_i_d,0);
5184 if (cmd_type==READ_M2)
5185 {
5186 for (xa_count=0;xa_count<CD_XA_HEAD;xa_count++)
5187 sprintf(&msgbuf[xa_count*3], " %02X", xa_head_buf[xa_count]);
5188 msgbuf[xa_count*3]=0;
5189 msg(DBG_XA1,"xa head:%s\n", msgbuf);
5190 }
5191 data_retrying = 0;
5192 data_tries++;
5193 if (data_tries >= 1000)
5194 {
5195 msg(DBG_INF,"sbp_data() statistics: %d waits in %d frames.\n", data_waits, data_tries);
5196 data_waits = data_tries = 0;
5197 }
5198 }
5199 duration=jiffies-duration;
5200 msg(DBG_TEA,"time to read %d frames: %d jiffies .\n",frame,duration);
5201 if (famT_drive)
5202 {
5203 wait=8;
5204 do
5205 {
5206 if (teac==2)
5207 {
5208 if ((i=CDi_stat_loop_T()) == -1) break;
5209 }
5210 else
5211 {
5212 sbp_sleep(1);
5213 OUT(CDo_sel_i_d,0);
5214 i=inb(CDi_status);
5215 }
5216 if (!(i&s_not_data_ready))
5217 {
5218 OUT(CDo_sel_i_d,1);
5219 j=0;
5220 do
5221 {
5222 if (do_16bit) i=inw(CDi_data);
5223 else i=inb(CDi_data);
5224 j++;
5225 i=inb(CDi_status);
5226 }
5227 while (!(i&s_not_data_ready));
5228 msg(DBG_TEA, "==========too much data (%d bytes/words)==============.\n", j);
5229 }
5230 if (!(i&s_not_result_ready))
5231 {
5232 OUT(CDo_sel_i_d,0);
5233 l=0;
5234 do
5235 {
5236 infobuf[l++]=inb(CDi_info);
5237 i=inb(CDi_status);
5238 }
5239 while (!(i&s_not_result_ready));
5240 if (infobuf[0]==0x00) success=1;
5241#if 1
5242 for (j=0;j<l;j++) sprintf(&msgbuf[j*3], " %02X", infobuf[j]);
5243 msgbuf[j*3]=0;
5244 msg(DBG_TEA,"sbp_data info response:%s\n", msgbuf);
5245#endif
5246 if (infobuf[0]==0x02)
5247 {
5248 error_flag++;
5249 do
5250 {
5251 ++recursion;
5252 if (recursion>1) msg(DBG_TEA,"cmd_out_T READ_ERR recursion (sbp_data): %d !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n",recursion);
5253 else msg(DBG_TEA,"sbp_data: CMDT_READ_ERR necessary.\n");
5254 clr_cmdbuf();
5255 drvcmd[0]=CMDT_READ_ERR;
5256 j=cmd_out_T(); /* !!! recursive here !!! */
5257 --recursion;
5258 sbp_sleep(1);
5259 }
5260 while (j<0);
5261 current_drive->error_state=infobuf[2];
5262 current_drive->b3=infobuf[3];
5263 current_drive->b4=infobuf[4];
5264 }
5265 break;
5266 }
5267 else
5268 {
5269#if 0
5270 msg(DBG_TEA, "============= waiting for result=================.\n");
5271 sbp_sleep(1);
5272#endif
5273 }
5274 }
5275 while (wait--);
5276 }
5277
5278 if (error_flag) /* must have been spurious D_RDY or (ATTN&&!D_RDY) */
5279 {
5280 msg(DBG_TEA, "================error flag: %d=================.\n", error_flag);
5281 msg(DBG_INF,"sbp_data: read aborted by drive.\n");
5282#if 1
5283 i=cc_DriveReset(); /* ugly fix to prevent a hang */
5284#else
5285 i=cc_ReadError();
5286#endif
5287 return (0);
5288 }
5289
5290 if (fam0LV_drive)
5291 {
5292 SBPCD_CLI;
5293 i=maxtim_data;
5294 for (timeout=jiffies+HZ; time_before(jiffies, timeout); timeout--)
5295 {
5296 for ( ;i!=0;i--)
5297 {
5298 j=inb(CDi_status);
5299 if (!(j&s_not_data_ready)) break;
5300 if (!(j&s_not_result_ready)) break;
5301 if (j&s_attention) break;
5302 }
5303 if (i != 0 || time_after_eq(jiffies, timeout)) break;
5304 sbp_sleep(0);
5305 i = 1;
5306 }
5307 if (i==0) msg(DBG_INF,"status timeout after READ.\n");
5308 if (!(j&s_attention))
5309 {
5310 msg(DBG_INF,"sbp_data: timeout waiting DRV_ATTN - retrying.\n");
5311 i=cc_DriveReset(); /* ugly fix to prevent a hang */
5312 SBPCD_STI;
5313 return (0);
5314 }
5315 SBPCD_STI;
5316 }
5317
5318#if 0
5319 if (!success)
5320#endif
5321 do
5322 {
5323 if (fam0LV_drive) cc_ReadStatus();
5324#if 1
5325 if (famT_drive) msg(DBG_TEA, "================before ResponseStatus=================.\n", i);
5326#endif
5327 i=ResponseStatus(); /* builds status_bits, returns orig. status (old) or faked p_success (new) */
5328#if 1
5329 if (famT_drive) msg(DBG_TEA, "================ResponseStatus: %d=================.\n", i);
5330#endif
5331 if (i<0)
5332 {
5333 msg(DBG_INF,"bad cc_ReadStatus after read: %02X\n", current_drive->status_bits);
5334 return (0);
5335 }
5336 }
5337 while ((fam0LV_drive)&&(!st_check)&&(!(i&p_success)));
5338 if (st_check)
5339 {
5340 i=cc_ReadError();
5341 msg(DBG_INF,"cc_ReadError was necessary after read: %d\n",i);
5342 return (0);
5343 }
5344 if (fatal_err)
5345 {
5346 fatal_err=0;
5347 current_drive->sbp_first_frame=current_drive->sbp_last_frame=-1; /* purge buffer */
5348 current_drive->sbp_current = 0;
5349 msg(DBG_INF,"sbp_data: fatal_err - retrying.\n");
5350 return (0);
5351 }
5352
5353 current_drive->sbp_first_frame = req -> sector / 4;
5354 current_drive->sbp_last_frame = current_drive->sbp_first_frame + current_drive->sbp_read_frames - 1;
5355 sbp_transfer(req);
5356 return (1);
5357}
5358/*==========================================================================*/
5359
5360static int sbpcd_block_open(struct inode *inode, struct file *file)
5361{
5362 struct sbpcd_drive *p = inode->i_bdev->bd_disk->private_data;
5363 return cdrom_open(p->sbpcd_infop, inode, file);
5364}
5365
5366static int sbpcd_block_release(struct inode *inode, struct file *file)
5367{
5368 struct sbpcd_drive *p = inode->i_bdev->bd_disk->private_data;
5369 return cdrom_release(p->sbpcd_infop, file);
5370}
5371
5372static int sbpcd_block_ioctl(struct inode *inode, struct file *file,
5373 unsigned cmd, unsigned long arg)
5374{
5375 struct sbpcd_drive *p = inode->i_bdev->bd_disk->private_data;
5376 return cdrom_ioctl(file, p->sbpcd_infop, inode, cmd, arg);
5377}
5378
5379static int sbpcd_block_media_changed(struct gendisk *disk)
5380{
5381 struct sbpcd_drive *p = disk->private_data;
5382 return cdrom_media_changed(p->sbpcd_infop);
5383}
5384
5385static struct block_device_operations sbpcd_bdops =
5386{
5387 .owner = THIS_MODULE,
5388 .open = sbpcd_block_open,
5389 .release = sbpcd_block_release,
5390 .ioctl = sbpcd_block_ioctl,
5391 .media_changed = sbpcd_block_media_changed,
5392};
5393/*==========================================================================*/
5394/*
5395 * Open the device special file. Check that a disk is in. Read TOC.
5396 */
5397static int sbpcd_open(struct cdrom_device_info *cdi, int purpose)
5398{
5399 struct sbpcd_drive *p = cdi->handle;
5400
5401 down(&ioctl_read_sem);
5402 switch_drive(p);
5403
5404 /*
5405 * try to keep an "open" counter here and lock the door if 0->1.
5406 */
5407 msg(DBG_LCK,"open_count: %d -> %d\n",
5408 current_drive->open_count,current_drive->open_count+1);
5409 if (++current_drive->open_count<=1)
5410 {
5411 int i;
5412 i=LockDoor();
5413 current_drive->open_count=1;
5414 if (famT_drive) msg(DBG_TEA,"sbpcd_open: before i=DiskInfo();.\n");
5415 i=DiskInfo();
5416 if (famT_drive) msg(DBG_TEA,"sbpcd_open: after i=DiskInfo();.\n");
5417 if ((current_drive->ored_ctl_adr&0x40)==0)
5418 {
5419 msg(DBG_INF,"CD contains no data tracks.\n");
5420#ifdef SAFE_MIXED
5421 current_drive->has_data=0;
5422#endif /* SAFE_MIXED */
5423 }
5424#ifdef SAFE_MIXED
5425 else if (current_drive->has_data<1) current_drive->has_data=1;
5426#endif /* SAFE_MIXED */
5427 }
5428 if (!st_spinning) cc_SpinUp();
5429 RETURN_UP(0);
5430}
5431/*==========================================================================*/
5432/*
5433 * On close, we flush all sbp blocks from the buffer cache.
5434 */
5435static void sbpcd_release(struct cdrom_device_info * cdi)
5436{
5437 struct sbpcd_drive *p = cdi->handle;
5438
5439 if (p->drv_id==-1) {
5440 msg(DBG_INF, "release: bad device: %s\n", cdi->name);
5441 return;
5442 }
5443 down(&ioctl_read_sem);
5444 switch_drive(p);
5445 /*
5446 * try to keep an "open" counter here and unlock the door if 1->0.
5447 */
5448 msg(DBG_LCK,"open_count: %d -> %d\n",
5449 p->open_count,p->open_count-1);
5450 if (p->open_count>-2) /* CDROMEJECT may have been done */
5451 {
5452 if (--p->open_count<=0)
5453 {
5454 p->sbp_first_frame=p->sbp_last_frame=-1;
5455 if (p->audio_state!=audio_playing)
5456 if (p->f_eject) cc_SpinDown();
5457 p->diskstate_flags &= ~cd_size_bit;
5458 p->open_count=0;
5459#ifdef SAFE_MIXED
5460 p->has_data=0;
5461#endif /* SAFE_MIXED */
5462 }
5463 }
5464 up(&ioctl_read_sem);
5465 return ;
5466}
5467/*==========================================================================*/
5468/*
5469 *
5470 */
5471static int sbpcd_media_changed( struct cdrom_device_info *cdi, int disc_nr);
5472static struct cdrom_device_ops sbpcd_dops = {
5473 .open = sbpcd_open,
5474 .release = sbpcd_release,
5475 .drive_status = sbpcd_drive_status,
5476 .media_changed = sbpcd_media_changed,
5477 .tray_move = sbpcd_tray_move,
5478 .lock_door = sbpcd_lock_door,
5479 .select_speed = sbpcd_select_speed,
5480 .get_last_session = sbpcd_get_last_session,
5481 .get_mcn = sbpcd_get_mcn,
5482 .reset = sbpcd_reset,
5483 .audio_ioctl = sbpcd_audio_ioctl,
5484 .dev_ioctl = sbpcd_dev_ioctl,
5485 .capability = CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK |
5486 CDC_MULTI_SESSION | CDC_MEDIA_CHANGED |
5487 CDC_MCN | CDC_PLAY_AUDIO | CDC_IOCTLS,
5488 .n_minors = 1,
5489};
5490
5491/*==========================================================================*/
5492/*
5493 * accept "kernel command line" parameters
5494 * (suggested by Peter MacDonald with SLS 1.03)
5495 *
5496 * This is only implemented for the first controller. Should be enough to
5497 * allow installing with a "strange" distribution kernel.
5498 *
5499 * use: tell LILO:
5500 * sbpcd=0x230,SoundBlaster
5501 * or
5502 * sbpcd=0x300,LaserMate
5503 * or
5504 * sbpcd=0x338,SoundScape
5505 * or
5506 * sbpcd=0x2C0,Teac16bit
5507 *
5508 * (upper/lower case sensitive here - but all-lowercase is ok!!!).
5509 *
5510 * the address value has to be the CDROM PORT ADDRESS -
5511 * not the soundcard base address.
5512 * For the SPEA/SoundScape setup, DO NOT specify the "configuration port"
5513 * address, but the address which is really used for the CDROM (usually 8
5514 * bytes above).
5515 *
5516 */
5517
5518int sbpcd_setup(char *s)
5519{
5520#ifndef MODULE
5521 int p[4];
5522 (void)get_options(s, ARRAY_SIZE(p), p);
5523 setup_done++;
5524 msg(DBG_INI,"sbpcd_setup called with %04X,%s\n",p[1], s);
5525 sbpro_type=0; /* default: "LaserMate" */
5526 if (p[0]>1) sbpro_type=p[2];
5527 else if (!strcmp(s,str_sb)) sbpro_type=1;
5528 else if (!strcmp(s,str_sb_l)) sbpro_type=1;
5529 else if (!strcmp(s,str_sp)) sbpro_type=2;
5530 else if (!strcmp(s,str_sp_l)) sbpro_type=2;
5531 else if (!strcmp(s,str_ss)) sbpro_type=2;
5532 else if (!strcmp(s,str_ss_l)) sbpro_type=2;
5533 else if (!strcmp(s,str_t16)) sbpro_type=3;
5534 else if (!strcmp(s,str_t16_l)) sbpro_type=3;
5535 if (p[0]>0) sbpcd_ioaddr=p[1];
5536 if (p[0]>2) max_drives=p[3];
5537#else
5538 sbpcd_ioaddr = sbpcd[0];
5539 sbpro_type = sbpcd[1];
5540#endif
5541
5542 CDo_command=sbpcd_ioaddr;
5543 CDi_info=sbpcd_ioaddr;
5544 CDi_status=sbpcd_ioaddr+1;
5545 CDo_sel_i_d=sbpcd_ioaddr+1;
5546 CDo_reset=sbpcd_ioaddr+2;
5547 CDo_enable=sbpcd_ioaddr+3;
5548 f_16bit=0;
5549 if ((sbpro_type==1)||(sbpro_type==3))
5550 {
5551 CDi_data=sbpcd_ioaddr;
5552 if (sbpro_type==3)
5553 {
5554 f_16bit=1;
5555 sbpro_type=1;
5556 }
5557 }
5558 else CDi_data=sbpcd_ioaddr+2;
5559
5560 return 1;
5561}
5562
5563__setup("sbpcd=", sbpcd_setup);
5564
5565
5566/*==========================================================================*/
5567/*
5568 * Sequoia S-1000 CD-ROM Interface Configuration
5569 * as used within SPEA Media FX, Ensonic SoundScape and some Reveal cards
5570 * The soundcard has to get jumpered for the interface type "Panasonic"
5571 * (not Sony or Mitsumi) and to get soft-configured for
5572 * -> configuration port address
5573 * -> CDROM port offset (num_ports): has to be 8 here. Possibly this
5574 * offset value determines the interface type (none, Panasonic,
5575 * Mitsumi, Sony).
5576 * The interface uses a configuration port (0x320, 0x330, 0x340, 0x350)
5577 * some bytes below the real CDROM address.
5578 *
5579 * For the Panasonic style (LaserMate) interface and the configuration
5580 * port 0x330, we have to use an offset of 8; so, the real CDROM port
5581 * address is 0x338.
5582 */
5583static int __init config_spea(void)
5584{
5585 /*
5586 * base address offset between configuration port and CDROM port,
5587 * this probably defines the interface type
5588 * 2 (type=??): 0x00
5589 * 8 (type=LaserMate):0x10
5590 * 16 (type=??):0x20
5591 * 32 (type=??):0x30
5592 */
5593 int n_ports=0x10;
5594
5595 int irq_number=0; /* off:0x00, 2/9:0x01, 7:0x03, 12:0x05, 15:0x07 */
5596 int dma_channel=0; /* off: 0x00, 0:0x08, 1:0x18, 3:0x38, 5:0x58, 6:0x68 */
5597 int dack_polarity=0; /* L:0x00, H:0x80 */
5598 int drq_polarity=0x40; /* L:0x00, H:0x40 */
5599 int i;
5600
5601#define SPEA_REG_1 sbpcd_ioaddr-0x08+4
5602#define SPEA_REG_2 sbpcd_ioaddr-0x08+5
5603
5604 OUT(SPEA_REG_1,0xFF);
5605 i=inb(SPEA_REG_1);
5606 if (i!=0x0F)
5607 {
5608 msg(DBG_SEQ,"no SPEA interface at %04X present.\n", sbpcd_ioaddr);
5609 return (-1); /* no interface found */
5610 }
5611 OUT(SPEA_REG_1,0x04);
5612 OUT(SPEA_REG_2,0xC0);
5613
5614 OUT(SPEA_REG_1,0x05);
5615 OUT(SPEA_REG_2,0x10|drq_polarity|dack_polarity);
5616
5617#if 1
5618#define SPEA_PATTERN 0x80
5619#else
5620#define SPEA_PATTERN 0x00
5621#endif
5622 OUT(SPEA_REG_1,0x06);
5623 OUT(SPEA_REG_2,dma_channel|irq_number|SPEA_PATTERN);
5624 OUT(SPEA_REG_2,dma_channel|irq_number|SPEA_PATTERN);
5625
5626 OUT(SPEA_REG_1,0x09);
5627 i=(inb(SPEA_REG_2)&0xCF)|n_ports;
5628 OUT(SPEA_REG_2,i);
5629
5630 sbpro_type = 0; /* acts like a LaserMate interface now */
5631 msg(DBG_SEQ,"found SoundScape interface at %04X.\n", sbpcd_ioaddr);
5632 return (0);
5633}
5634
5635/*==========================================================================*/
5636/*
5637 * Test for presence of drive and initialize it.
5638 * Called once at boot or load time.
5639 */
5640
5641/* FIXME: cleanups after failed allocations are too ugly for words */
5642#ifdef MODULE
5643int __init __sbpcd_init(void)
5644#else
5645int __init sbpcd_init(void)
5646#endif
5647{
5648 int i=0, j=0;
5649 int addr[2]={1, CDROM_PORT};
5650 int port_index;
5651
5652 sti();
5653
5654 msg(DBG_INF,"sbpcd.c %s\n", VERSION);
5655#ifndef MODULE
5656#if DISTRIBUTION
5657 if (!setup_done)
5658 {
5659 msg(DBG_INF,"Looking for Matsushita/Panasonic, CreativeLabs, Longshine, TEAC CD-ROM drives\n");
5660 msg(DBG_INF,"= = = = = = = = = = W A R N I N G = = = = = = = = = =\n");
5661 msg(DBG_INF,"Auto-Probing can cause a hang (f.e. touching an NE2000 card).\n");
5662 msg(DBG_INF,"If that happens, you have to reboot and use the\n");
5663 msg(DBG_INF,"LILO (kernel) command line feature like:\n");
5664 msg(DBG_INF," LILO boot: ... sbpcd=0x230,SoundBlaster\n");
5665 msg(DBG_INF,"or like:\n");
5666 msg(DBG_INF," LILO boot: ... sbpcd=0x300,LaserMate\n");
5667 msg(DBG_INF,"or like:\n");
5668 msg(DBG_INF," LILO boot: ... sbpcd=0x338,SoundScape\n");
5669 msg(DBG_INF,"with your REAL address.\n");
5670 msg(DBG_INF,"= = = = = = = = = = END of WARNING = = = = = == = = =\n");
5671 }
5672#endif /* DISTRIBUTION */
5673 sbpcd[0]=sbpcd_ioaddr; /* possibly changed by kernel command line */
5674 sbpcd[1]=sbpro_type; /* possibly changed by kernel command line */
5675#endif /* MODULE */
5676
5677 for (port_index=0;port_index<NUM_PROBE;port_index+=2)
5678 {
5679 addr[1]=sbpcd[port_index];
5680 if (addr[1]==0) break;
5681 if (check_region(addr[1],4))
5682 {
5683 msg(DBG_INF,"check_region: %03X is not free.\n",addr[1]);
5684 continue;
5685 }
5686 if (sbpcd[port_index+1]==2) type=str_sp;
5687 else if (sbpcd[port_index+1]==1) type=str_sb;
5688 else if (sbpcd[port_index+1]==3) type=str_t16;
5689 else type=str_lm;
5690 sbpcd_setup((char *)type);
5691#if DISTRIBUTION
5692 msg(DBG_INF,"Scanning 0x%X (%s)...\n", CDo_command, type);
5693#endif /* DISTRIBUTION */
5694 if (sbpcd[port_index+1]==2)
5695 {
5696 i=config_spea();
5697 if (i<0) continue;
5698 }
5699#ifdef PATH_CHECK
5700 if (check_card(addr[1])) continue;
5701#endif /* PATH_CHECK */
5702 i=check_drives();
5703 msg(DBG_INI,"check_drives done.\n");
5704 if (i>=0) break; /* drive found */
5705 } /* end of cycling through the set of possible I/O port addresses */
5706
5707 if (ndrives==0)
5708 {
5709 msg(DBG_INF, "No drive found.\n");
5710#ifdef MODULE
5711 return -EIO;
5712#else
5713 goto init_done;
5714#endif /* MODULE */
5715 }
5716
5717 if (port_index>0)
5718 {
5719 msg(DBG_INF, "You should read Documentation/cdrom/sbpcd\n");
5720 msg(DBG_INF, "and then configure sbpcd.h for your hardware.\n");
5721 }
5722 check_datarate();
5723 msg(DBG_INI,"check_datarate done.\n");
5724
5725 for (j=0;j<NR_SBPCD;j++)
5726 {
5727 struct sbpcd_drive *p = D_S + j;
5728 if (p->drv_id==-1)
5729 continue;
5730 switch_drive(p);
5731#if 1
5732 if (!famL_drive) cc_DriveReset();
5733#endif
5734 if (!st_spinning) cc_SpinUp();
5735 p->sbp_first_frame = -1; /* First frame in buffer */
5736 p->sbp_last_frame = -1; /* Last frame in buffer */
5737 p->sbp_read_frames = 0; /* Number of frames being read to buffer */
5738 p->sbp_current = 0; /* Frame being currently read */
5739 p->CD_changed=1;
5740 p->frame_size=CD_FRAMESIZE;
5741 p->f_eject=0;
5742#if EJECT
5743 if (!fam0_drive) p->f_eject=1;
5744#endif /* EJECT */
5745 cc_ReadStatus();
5746 i=ResponseStatus(); /* returns orig. status or p_busy_new */
5747 if (famT_drive) i=ResponseStatus(); /* returns orig. status or p_busy_new */
5748 if (i<0)
5749 {
5750 if (i!=-402)
5751 msg(DBG_INF,"init: ResponseStatus returns %d.\n",i);
5752 }
5753 else
5754 {
5755 if (st_check)
5756 {
5757 i=cc_ReadError();
5758 msg(DBG_INI,"init: cc_ReadError returns %d\n",i);
5759 }
5760 }
5761 msg(DBG_INI,"init: first GetStatus: %d\n",i);
5762 msg(DBG_LCS,"init: first GetStatus: error_byte=%d\n",
5763 p->error_byte);
5764 if (p->error_byte==aud_12)
5765 {
5766 timeout=jiffies+2*HZ;
5767 do
5768 {
5769 i=GetStatus();
5770 msg(DBG_INI,"init: second GetStatus: %02X\n",i);
5771 msg(DBG_LCS,
5772 "init: second GetStatus: error_byte=%d\n",
5773 p->error_byte);
5774 if (i<0) break;
5775 if (!st_caddy_in) break;
5776 }
5777 while ((!st_diskok)||time_after(jiffies, timeout));
5778 }
5779 i=SetSpeed();
5780 if (i>=0) p->CD_changed=1;
5781 }
5782
5783 if (!request_region(CDo_command,4,major_name))
5784 {
5785 printk(KERN_WARNING "sbpcd: Unable to request region 0x%x\n", CDo_command);
5786 return -EIO;
5787 }
5788
5789 /*
5790 * Turn on the CD audio channels.
5791 * The addresses are obtained from SOUND_BASE (see sbpcd.h).
5792 */
5793#if SOUND_BASE
5794 OUT(MIXER_addr,MIXER_CD_Volume); /* select SB Pro mixer register */
5795 OUT(MIXER_data,0xCC); /* one nibble per channel, max. value: 0xFF */
5796#endif /* SOUND_BASE */
5797
5798 if (register_blkdev(MAJOR_NR, major_name)) {
5799#ifdef MODULE
5800 return -EIO;
5801#else
5802 goto init_done;
5803#endif /* MODULE */
5804 }
5805
5806 /*
5807 * init error handling is broken beyond belief in this driver...
5808 */
5809 sbpcd_queue = blk_init_queue(do_sbpcd_request, &sbpcd_lock);
5810 if (!sbpcd_queue) {
5811 release_region(CDo_command,4);
5812 unregister_blkdev(MAJOR_NR, major_name);
5813 return -ENOMEM;
5814 }
5815
5816 devfs_mk_dir("sbp");
5817
5818 for (j=0;j<NR_SBPCD;j++)
5819 {
5820 struct cdrom_device_info * sbpcd_infop;
5821 struct gendisk *disk;
5822 struct sbpcd_drive *p = D_S + j;
5823
5824 if (p->drv_id==-1) continue;
5825 switch_drive(p);
5826#ifdef SAFE_MIXED
5827 p->has_data=0;
5828#endif /* SAFE_MIXED */
5829 /*
5830 * allocate memory for the frame buffers
5831 */
5832 p->aud_buf=NULL;
5833 p->sbp_audsiz=0;
5834 p->sbp_bufsiz=buffers;
5835 if (p->drv_type&drv_fam1)
5836 if (READ_AUDIO>0)
5837 p->sbp_audsiz = READ_AUDIO;
5838 p->sbp_buf=(u_char *) vmalloc(buffers*CD_FRAMESIZE);
5839 if (!p->sbp_buf) {
5840 msg(DBG_INF,"data buffer (%d frames) not available.\n",
5841 buffers);
5842 if ((unregister_blkdev(MAJOR_NR, major_name) == -EINVAL))
5843 {
5844 printk("Can't unregister %s\n", major_name);
5845 }
5846 release_region(CDo_command,4);
5847 blk_cleanup_queue(sbpcd_queue);
5848 return -EIO;
5849 }
5850#ifdef MODULE
5851 msg(DBG_INF,"data buffer size: %d frames.\n",buffers);
5852#endif /* MODULE */
5853 if (p->sbp_audsiz>0)
5854 {
5855 p->aud_buf=(u_char *) vmalloc(p->sbp_audsiz*CD_FRAMESIZE_RAW);
5856 if (p->aud_buf==NULL) msg(DBG_INF,"audio buffer (%d frames) not available.\n",p->sbp_audsiz);
5857 else msg(DBG_INF,"audio buffer size: %d frames.\n",p->sbp_audsiz);
5858 }
5859 sbpcd_infop = vmalloc(sizeof (struct cdrom_device_info));
5860 if (sbpcd_infop == NULL)
5861 {
5862 release_region(CDo_command,4);
5863 blk_cleanup_queue(sbpcd_queue);
5864 return -ENOMEM;
5865 }
5866 memset(sbpcd_infop, 0, sizeof(struct cdrom_device_info));
5867 sbpcd_infop->ops = &sbpcd_dops;
5868 sbpcd_infop->speed = 2;
5869 sbpcd_infop->capacity = 1;
5870 sprintf(sbpcd_infop->name, "sbpcd%d", j);
5871 sbpcd_infop->handle = p;
5872 p->sbpcd_infop = sbpcd_infop;
5873 disk = alloc_disk(1);
5874 disk->major = MAJOR_NR;
5875 disk->first_minor = j;
5876 disk->fops = &sbpcd_bdops;
5877 strcpy(disk->disk_name, sbpcd_infop->name);
5878 disk->flags = GENHD_FL_CD;
5879 sprintf(disk->devfs_name, "sbp/c0t%d", p->drv_id);
5880 p->disk = disk;
5881 if (register_cdrom(sbpcd_infop))
5882 {
5883 printk(" sbpcd: Unable to register with Uniform CD-ROm driver\n");
5884 }
5885 disk->private_data = p;
5886 disk->queue = sbpcd_queue;
5887 add_disk(disk);
5888 }
5889 blk_queue_hardsect_size(sbpcd_queue, CD_FRAMESIZE);
5890
5891#ifndef MODULE
5892 init_done:
5893#endif
5894 return 0;
5895}
5896/*==========================================================================*/
5897#ifdef MODULE
5898void sbpcd_exit(void)
5899{
5900 int j;
5901
5902 if ((unregister_blkdev(MAJOR_NR, major_name) == -EINVAL))
5903 {
5904 msg(DBG_INF, "What's that: can't unregister %s.\n", major_name);
5905 return;
5906 }
5907 release_region(CDo_command,4);
5908 blk_cleanup_queue(sbpcd_queue);
5909 for (j=0;j<NR_SBPCD;j++)
5910 {
5911 if (D_S[j].drv_id==-1) continue;
5912 del_gendisk(D_S[j].disk);
5913 put_disk(D_S[j].disk);
5914 devfs_remove("sbp/c0t%d", j);
5915 vfree(D_S[j].sbp_buf);
5916 if (D_S[j].sbp_audsiz>0) vfree(D_S[j].aud_buf);
5917 if ((unregister_cdrom(D_S[j].sbpcd_infop) == -EINVAL))
5918 {
5919 msg(DBG_INF, "What's that: can't unregister info %s.\n", major_name);
5920 return;
5921 }
5922 vfree(D_S[j].sbpcd_infop);
5923 }
5924 devfs_remove("sbp");
5925 msg(DBG_INF, "%s module released.\n", major_name);
5926}
5927
5928
5929module_init(__sbpcd_init) /*HACK!*/;
5930module_exit(sbpcd_exit);
5931
5932
5933#endif /* MODULE */
5934static int sbpcd_media_changed(struct cdrom_device_info *cdi, int disc_nr)
5935{
5936 struct sbpcd_drive *p = cdi->handle;
5937 msg(DBG_CHK,"media_check (%s) called\n", cdi->name);
5938
5939 if (p->CD_changed==0xFF)
5940 {
5941 p->CD_changed=0;
5942 msg(DBG_CHK,"medium changed (drive %s)\n", cdi->name);
5943 current_drive->diskstate_flags &= ~toc_bit;
5944 /* we *don't* need invalidate here, it's done by caller */
5945 current_drive->diskstate_flags &= ~cd_size_bit;
5946#ifdef SAFE_MIXED
5947 current_drive->has_data=0;
5948#endif /* SAFE_MIXED */
5949
5950 return (1);
5951 }
5952 else
5953 return (0);
5954}
5955
5956MODULE_LICENSE("GPL");
5957/* FIXME: Old modules.conf claims MATSUSHITA_CDROM2_MAJOR and CDROM3, but
5958 AFAICT this doesn't support those majors, so why? --RR 30 Jul 2003 */
5959MODULE_ALIAS_BLOCKDEV_MAJOR(MATSUSHITA_CDROM_MAJOR);
5960
5961/*==========================================================================*/
5962/*
5963 * Overrides for Emacs so that we follow Linus's tabbing style.
5964 * Emacs will notice this stuff at the end of the file and automatically
5965 * adjust the settings for this buffer only. This must remain at the end
5966 * of the file.
5967 * ---------------------------------------------------------------------------
5968 * Local variables:
5969 * c-indent-level: 8
5970 * c-brace-imaginary-offset: 0
5971 * c-brace-offset: -8
5972 * c-argdecl-indent: 8
5973 * c-label-offset: -8
5974 * c-continued-statement-offset: 8
5975 * c-continued-brace-offset: 0
5976 * End:
5977 */
5978
diff --git a/drivers/cdrom/sbpcd.h b/drivers/cdrom/sbpcd.h
new file mode 100644
index 000000000000..2f2225f13c6f
--- /dev/null
+++ b/drivers/cdrom/sbpcd.h
@@ -0,0 +1,839 @@
1/*
2 * sbpcd.h Specify interface address and interface type here.
3 */
4
5/*
6 * Attention! This file contains user-serviceable parts!
7 * I recommend to make use of it...
8 * If you feel helpless, look into Documentation/cdrom/sbpcd
9 * (good idea anyway, at least before mailing me).
10 *
11 * The definitions for the first controller can get overridden by
12 * the kernel command line ("lilo boot option").
13 * Examples:
14 * sbpcd=0x300,LaserMate
15 * or
16 * sbpcd=0x230,SoundBlaster
17 * or
18 * sbpcd=0x338,SoundScape
19 * or
20 * sbpcd=0x2C0,Teac16bit
21 *
22 * If sbpcd gets used as a module, you can load it with
23 * insmod sbpcd.o sbpcd=0x300,0
24 * or
25 * insmod sbpcd.o sbpcd=0x230,1
26 * or
27 * insmod sbpcd.o sbpcd=0x338,2
28 * or
29 * insmod sbpcd.o sbpcd=0x2C0,3
30 * respective to override the configured address and type.
31 */
32
33/*
34 * define your CDROM port base address as CDROM_PORT
35 * and specify the type of your interface card as SBPRO.
36 *
37 * address:
38 * ========
39 * SBPRO type addresses typically are 0x0230 (=0x220+0x10), 0x0250, ...
40 * LASERMATE type (CI-101P, WDH-7001C) addresses typically are 0x0300, ...
41 * SOUNDSCAPE addresses are from the LASERMATE type and range. You have to
42 * specify the REAL address here, not the configuration port address. Look
43 * at the CDROM driver's invoking line within your DOS CONFIG.SYS, or let
44 * sbpcd auto-probe, if you are not firm with the address.
45 * There are some soundcards on the market with 0x0630, 0x0650, ...; their
46 * type is not obvious (both types are possible).
47 *
48 * example: if your SBPRO audio address is 0x220, specify 0x230 and SBPRO 1.
49 * if your soundcard has its CDROM port above 0x300, specify
50 * that address and try SBPRO 0 first.
51 * if your SoundScape configuration port is at 0x330, specify
52 * 0x338 and SBPRO 2.
53 *
54 * interface type:
55 * ===============
56 * set SBPRO to 1 for "true" SoundBlaster card
57 * set SBPRO to 0 for "compatible" soundcards and
58 * for "poor" (no sound) interface cards.
59 * set SBPRO to 2 for Ensonic SoundScape or SPEA Media FX cards
60 * set SBPRO to 3 for Teac 16bit interface cards
61 *
62 * Almost all "compatible" sound boards need to set SBPRO to 0.
63 * If SBPRO is set wrong, the drives will get found - but any
64 * data access will give errors (audio access will work).
65 * The "OmniCD" no-sound interface card from CreativeLabs and most Teac
66 * interface cards need SBPRO 1.
67 *
68 * sound base:
69 * ===========
70 * The SOUND_BASE definition tells if we should try to turn the CD sound
71 * channels on. It will only be of use regarding soundcards with a SbPro
72 * compatible mixer.
73 *
74 * Example: #define SOUND_BASE 0x220 enables the sound card's CD channels
75 * #define SOUND_BASE 0 leaves the soundcard untouched
76 */
77#define CDROM_PORT 0x340 /* <-----------<< port address */
78#define SBPRO 0 /* <-----------<< interface type */
79#define MAX_DRIVES 4 /* set to 1 if the card does not use "drive select" */
80#define SOUND_BASE 0x220 /* <-----------<< sound address of this card or 0 */
81
82/*
83 * some more or less user dependent definitions - service them!
84 */
85
86/* Set this to 0 once you have configured your interface definitions right. */
87#define DISTRIBUTION 1
88
89/*
90 * Time to wait after giving a message.
91 * This gets important if you enable non-standard DBG_xxx flags.
92 * You will see what happens if you omit the pause or make it
93 * too short. Be warned!
94 */
95#define KLOGD_PAUSE 1
96
97/* tray control: eject tray if no disk is in */
98#if DISTRIBUTION
99#define JUKEBOX 0
100#else
101#define JUKEBOX 1
102#endif /* DISTRIBUTION */
103
104/* tray control: eject tray after last use */
105#if DISTRIBUTION
106#define EJECT 0
107#else
108#define EJECT 1
109#endif /* DISTRIBUTION */
110
111/* max. number of audio frames to read with one */
112/* request (allocates n* 2352 bytes kernel memory!) */
113/* may be freely adjusted, f.e. 75 (= 1 sec.), at */
114/* runtime by use of the CDROMAUDIOBUFSIZ ioctl. */
115#define READ_AUDIO 0
116
117/* Optimizations for the Teac CD-55A drive read performance.
118 * SBP_TEAC_SPEED can be changed here, or one can set the
119 * variable "teac" when loading as a module.
120 * Valid settings are:
121 * 0 - very slow - the recommended "DISTRIBUTION 1" setup.
122 * 1 - 2x performance with little overhead. No busy waiting.
123 * 2 - 4x performance with 5ms overhead per read. Busy wait.
124 *
125 * Setting SBP_TEAC_SPEED or the variable 'teac' to anything
126 * other than 0 may cause problems. If you run into them, first
127 * change SBP_TEAC_SPEED back to 0 and see if your drive responds
128 * normally. If yes, you are "allowed" to report your case - to help
129 * me with the driver, not to solve your hassle. Don´t mail if you
130 * simply are stuck into your own "tuning" experiments, you know?
131 */
132#define SBP_TEAC_SPEED 1
133
134/*==========================================================================*/
135/*==========================================================================*/
136/*
137 * nothing to change below here if you are not fully aware what you're doing
138 */
139#ifndef _LINUX_SBPCD_H
140
141#define _LINUX_SBPCD_H
142/*==========================================================================*/
143/*==========================================================================*/
144/*
145 * driver's own read_ahead, data mode
146 */
147#define SBP_BUFFER_FRAMES 8
148
149#define LONG_TIMING 0 /* test against timeouts with "gold" CDs on CR-521 */
150#undef FUTURE
151#undef SAFE_MIXED
152
153#define TEST_UPC 0
154#define SPEA_TEST 0
155#define TEST_STI 0
156#define OLD_BUSY 0
157#undef PATH_CHECK
158#ifndef SOUND_BASE
159#define SOUND_BASE 0
160#endif
161#if DISTRIBUTION
162#undef SBP_TEAC_SPEED
163#define SBP_TEAC_SPEED 0
164#endif
165/*==========================================================================*/
166/*
167 * DDI interface definitions
168 * "invented" by Fred N. van Kempen..
169 */
170#define DDIOCSDBG 0x9000
171
172/*==========================================================================*/
173/*
174 * "private" IOCTL functions
175 */
176#define CDROMAUDIOBUFSIZ 0x5382 /* set the audio buffer size */
177
178/*==========================================================================*/
179/*
180 * Debug output levels
181 */
182#define DBG_INF 1 /* necessary information */
183#define DBG_BSZ 2 /* BLOCK_SIZE trace */
184#define DBG_REA 3 /* READ status trace */
185#define DBG_CHK 4 /* MEDIA CHECK trace */
186#define DBG_TIM 5 /* datarate timer test */
187#define DBG_INI 6 /* initialization trace */
188#define DBG_TOC 7 /* tell TocEntry values */
189#define DBG_IOC 8 /* ioctl trace */
190#define DBG_STA 9 /* ResponseStatus() trace */
191#define DBG_ERR 10 /* cc_ReadError() trace */
192#define DBG_CMD 11 /* cmd_out() trace */
193#define DBG_WRN 12 /* give explanation before auto-probing */
194#define DBG_MUL 13 /* multi session code test */
195#define DBG_IDX 14 /* test code for drive_id !=0 */
196#define DBG_IOX 15 /* some special information */
197#define DBG_DID 16 /* drive ID test */
198#define DBG_RES 17 /* drive reset info */
199#define DBG_SPI 18 /* SpinUp test */
200#define DBG_IOS 19 /* ioctl trace: subchannel functions */
201#define DBG_IO2 20 /* ioctl trace: general */
202#define DBG_UPC 21 /* show UPC information */
203#define DBG_XA1 22 /* XA mode debugging */
204#define DBG_LCK 23 /* door (un)lock info */
205#define DBG_SQ1 24 /* dump SubQ frame */
206#define DBG_AUD 25 /* READ AUDIO debugging */
207#define DBG_SEQ 26 /* Sequoia interface configuration trace */
208#define DBG_LCS 27 /* Longshine LCS-7260 debugging trace */
209#define DBG_CD2 28 /* MKE/Funai CD200 debugging trace */
210#define DBG_TEA 29 /* TEAC CD-55A debugging trace */
211#define DBG_ECS 30 /* ECS-AT (Vertos 100) debugging trace */
212#define DBG_000 31 /* unnecessary information */
213
214/*==========================================================================*/
215/*==========================================================================*/
216
217/*
218 * bits of flags_cmd_out:
219 */
220#define f_respo3 0x100
221#define f_putcmd 0x80
222#define f_respo2 0x40
223#define f_lopsta 0x20
224#define f_getsta 0x10
225#define f_ResponseStatus 0x08
226#define f_obey_p_check 0x04
227#define f_bit1 0x02
228#define f_wait_if_busy 0x01
229
230/*
231 * diskstate_flags:
232 */
233#define x80_bit 0x80
234#define upc_bit 0x40
235#define volume_bit 0x20
236#define toc_bit 0x10
237#define multisession_bit 0x08
238#define cd_size_bit 0x04
239#define subq_bit 0x02
240#define frame_size_bit 0x01
241
242/*
243 * disk states (bits of diskstate_flags):
244 */
245#define upc_valid (current_drive->diskstate_flags&upc_bit)
246#define volume_valid (current_drive->diskstate_flags&volume_bit)
247#define toc_valid (current_drive->diskstate_flags&toc_bit)
248#define cd_size_valid (current_drive->diskstate_flags&cd_size_bit)
249#define subq_valid (current_drive->diskstate_flags&subq_bit)
250#define frame_size_valid (current_drive->diskstate_flags&frame_size_bit)
251
252/*
253 * the status_bits variable
254 */
255#define p_success 0x100
256#define p_door_closed 0x80
257#define p_caddy_in 0x40
258#define p_spinning 0x20
259#define p_check 0x10
260#define p_busy_new 0x08
261#define p_door_locked 0x04
262#define p_disk_ok 0x01
263
264/*
265 * LCS-7260 special status result bits:
266 */
267#define p_lcs_door_locked 0x02
268#define p_lcs_door_closed 0x01 /* probably disk_in */
269
270/*
271 * CR-52x special status result bits:
272 */
273#define p_caddin_old 0x40
274#define p_success_old 0x08
275#define p_busy_old 0x04
276#define p_bit_1 0x02 /* hopefully unused now */
277
278/*
279 * "generation specific" defs of the status result bits:
280 */
281#define p0_door_closed 0x80
282#define p0_caddy_in 0x40
283#define p0_spinning 0x20
284#define p0_check 0x10
285#define p0_success 0x08 /* unused */
286#define p0_busy 0x04
287#define p0_bit_1 0x02 /* unused */
288#define p0_disk_ok 0x01
289
290#define pL_disk_in 0x40
291#define pL_spinning 0x20
292#define pL_check 0x10
293#define pL_success 0x08 /* unused ?? */
294#define pL_busy 0x04
295#define pL_door_locked 0x02
296#define pL_door_closed 0x01
297
298#define pV_door_closed 0x40
299#define pV_spinning 0x20
300#define pV_check 0x10
301#define pV_success 0x08
302#define pV_busy 0x04
303#define pV_door_locked 0x02
304#define pV_disk_ok 0x01
305
306#define p1_door_closed 0x80
307#define p1_disk_in 0x40
308#define p1_spinning 0x20
309#define p1_check 0x10
310#define p1_busy 0x08
311#define p1_door_locked 0x04
312#define p1_bit_1 0x02 /* unused */
313#define p1_disk_ok 0x01
314
315#define p2_disk_ok 0x80
316#define p2_door_locked 0x40
317#define p2_spinning 0x20
318#define p2_busy2 0x10
319#define p2_busy1 0x08
320#define p2_door_closed 0x04
321#define p2_disk_in 0x02
322#define p2_check 0x01
323
324/*
325 * used drive states:
326 */
327#define st_door_closed (current_drive->status_bits&p_door_closed)
328#define st_caddy_in (current_drive->status_bits&p_caddy_in)
329#define st_spinning (current_drive->status_bits&p_spinning)
330#define st_check (current_drive->status_bits&p_check)
331#define st_busy (current_drive->status_bits&p_busy_new)
332#define st_door_locked (current_drive->status_bits&p_door_locked)
333#define st_diskok (current_drive->status_bits&p_disk_ok)
334
335/*
336 * bits of the CDi_status register:
337 */
338#define s_not_result_ready 0x04 /* 0: "result ready" */
339#define s_not_data_ready 0x02 /* 0: "data ready" */
340#define s_attention 0x01 /* 1: "attention required" */
341/*
342 * usable as:
343 */
344#define DRV_ATTN ((inb(CDi_status)&s_attention)!=0)
345#define DATA_READY ((inb(CDi_status)&s_not_data_ready)==0)
346#define RESULT_READY ((inb(CDi_status)&s_not_result_ready)==0)
347
348/*
349 * drive families and types (firmware versions):
350 */
351#define drv_fam0 0x0100 /* CR-52x family */
352#define drv_199 (drv_fam0+0x01) /* <200 */
353#define drv_200 (drv_fam0+0x02) /* <201 */
354#define drv_201 (drv_fam0+0x03) /* <210 */
355#define drv_210 (drv_fam0+0x04) /* <211 */
356#define drv_211 (drv_fam0+0x05) /* <300 */
357#define drv_300 (drv_fam0+0x06) /* >=300 */
358
359#define drv_fam1 0x0200 /* CR-56x family */
360#define drv_099 (drv_fam1+0x01) /* <100 */
361#define drv_100 (drv_fam1+0x02) /* >=100, only 1.02 and 5.00 known */
362
363#define drv_fam2 0x0400 /* CD200 family */
364
365#define drv_famT 0x0800 /* TEAC CD-55A */
366
367#define drv_famL 0x1000 /* Longshine family */
368#define drv_260 (drv_famL+0x01) /* LCS-7260 */
369#define drv_e1 (drv_famL+0x01) /* LCS-7260, firmware "A E1" */
370#define drv_f4 (drv_famL+0x02) /* LCS-7260, firmware "A4F4" */
371
372#define drv_famV 0x2000 /* ECS-AT (vertos-100) family */
373#define drv_at (drv_famV+0x01) /* ECS-AT, firmware "1.00" */
374
375#define fam0_drive (current_drive->drv_type&drv_fam0)
376#define famL_drive (current_drive->drv_type&drv_famL)
377#define famV_drive (current_drive->drv_type&drv_famV)
378#define fam1_drive (current_drive->drv_type&drv_fam1)
379#define fam2_drive (current_drive->drv_type&drv_fam2)
380#define famT_drive (current_drive->drv_type&drv_famT)
381#define fam0L_drive (current_drive->drv_type&(drv_fam0|drv_famL))
382#define fam0V_drive (current_drive->drv_type&(drv_fam0|drv_famV))
383#define famLV_drive (current_drive->drv_type&(drv_famL|drv_famV))
384#define fam0LV_drive (current_drive->drv_type&(drv_fam0|drv_famL|drv_famV))
385#define fam1L_drive (current_drive->drv_type&(drv_fam1|drv_famL))
386#define fam1V_drive (current_drive->drv_type&(drv_fam1|drv_famV))
387#define fam1LV_drive (current_drive->drv_type&(drv_fam1|drv_famL|drv_famV))
388#define fam01_drive (current_drive->drv_type&(drv_fam0|drv_fam1))
389#define fam12_drive (current_drive->drv_type&(drv_fam1|drv_fam2))
390#define fam2T_drive (current_drive->drv_type&(drv_fam2|drv_famT))
391
392/*
393 * audio states:
394 */
395#define audio_completed 3 /* Forgot this one! --AJK */
396#define audio_playing 2
397#define audio_pausing 1
398
399/*
400 * drv_pattern, drv_options:
401 */
402#define speed_auto 0x80
403#define speed_300 0x40
404#define speed_150 0x20
405#define audio_mono 0x04
406
407/*
408 * values of cmd_type (0 else):
409 */
410#define READ_M1 0x01 /* "data mode 1": 2048 bytes per frame */
411#define READ_M2 0x02 /* "data mode 2": 12+2048+280 bytes per frame */
412#define READ_SC 0x04 /* "subchannel info": 96 bytes per frame */
413#define READ_AU 0x08 /* "audio frame": 2352 bytes per frame */
414
415/*
416 * sense_byte:
417 *
418 * values: 00
419 * 01
420 * 81
421 * 82 "raw audio" mode
422 * xx from infobuf[0] after 85 00 00 00 00 00 00
423 */
424
425/* audio status (bin) */
426#define aud_00 0x00 /* Audio status byte not supported or not valid */
427#define audx11 0x0b /* Audio play operation in progress */
428#define audx12 0x0c /* Audio play operation paused */
429#define audx13 0x0d /* Audio play operation successfully completed */
430#define audx14 0x0e /* Audio play operation stopped due to error */
431#define audx15 0x0f /* No current audio status to return */
432/* audio status (bcd) */
433#define aud_11 0x11 /* Audio play operation in progress */
434#define aud_12 0x12 /* Audio play operation paused */
435#define aud_13 0x13 /* Audio play operation successfully completed */
436#define aud_14 0x14 /* Audio play operation stopped due to error */
437#define aud_15 0x15 /* No current audio status to return */
438
439/*
440 * highest allowed drive number (MINOR+1)
441 */
442#define NR_SBPCD 4
443
444/*
445 * we try to never disable interrupts - seems to work
446 */
447#define SBPCD_DIS_IRQ 0
448
449/*
450 * "write byte to port"
451 */
452#define OUT(x,y) outb(y,x)
453
454/*==========================================================================*/
455
456#define MIXER_addr SOUND_BASE+4 /* sound card's address register */
457#define MIXER_data SOUND_BASE+5 /* sound card's data register */
458#define MIXER_CD_Volume 0x28 /* internal SB Pro register address */
459
460/*==========================================================================*/
461
462#define MAX_TRACKS 99
463
464#define ERR_DISKCHANGE 615
465
466/*==========================================================================*/
467/*
468 * To make conversions easier (machine dependent!)
469 */
470typedef union _msf
471{
472 u_int n;
473 u_char c[4];
474} MSF;
475
476typedef union _blk
477{
478 u_int n;
479 u_char c[4];
480} BLK;
481
482/*==========================================================================*/
483
484/*============================================================================
485==============================================================================
486
487COMMAND SET of "old" drives like CR-521, CR-522
488 (the CR-562 family is different):
489
490No. Command Code
491--------------------------------------------
492
493Drive Commands:
494 1 Seek 01
495 2 Read Data 02
496 3 Read XA-Data 03
497 4 Read Header 04
498 5 Spin Up 05
499 6 Spin Down 06
500 7 Diagnostic 07
501 8 Read UPC 08
502 9 Read ISRC 09
50310 Play Audio 0A
50411 Play Audio MSF 0B
50512 Play Audio Track/Index 0C
506
507Status Commands:
50813 Read Status 81
50914 Read Error 82
51015 Read Drive Version 83
51116 Mode Select 84
51217 Mode Sense 85
51318 Set XA Parameter 86
51419 Read XA Parameter 87
51520 Read Capacity 88
51621 Read SUB_Q 89
51722 Read Disc Code 8A
51823 Read Disc Information 8B
51924 Read TOC 8C
52025 Pause/Resume 8D
52126 Read Packet 8E
52227 Read Path Check 00
523
524
525all numbers (lba, msf-bin, msf-bcd, counts) to transfer high byte first
526
527mnemo 7-byte command #bytes response (r0...rn)
528________ ____________________ ____
529
530Read Status:
531status: 81. (1) one-byte command, gives the main
532 status byte
533Read Error:
534check1: 82 00 00 00 00 00 00. (6) r1: audio status
535
536Read Packet:
537check2: 8e xx 00 00 00 00 00. (xx) gets xx bytes response, relating
538 to commands 01 04 05 07 08 09
539
540Play Audio:
541play: 0a ll-bb-aa nn-nn-nn. (0) play audio, ll-bb-aa: starting block (lba),
542 nn-nn-nn: #blocks
543Play Audio MSF:
544 0b mm-ss-ff mm-ss-ff (0) play audio from/to
545
546Play Audio Track/Index:
547 0c ...
548
549Pause/Resume:
550pause: 8d pr 00 00 00 00 00. (0) pause (pr=00)
551 resume (pr=80) audio playing
552
553Mode Select:
554 84 00 nn-nn ??.?? 00 (0) nn-nn: 2048 or 2340
555 possibly defines transfer size
556
557set_vol: 84 83 00 00 sw le 00. (0) sw(itch): lrxxxxxx (off=1)
558 le(vel): min=0, max=FF, else half
559 (firmware 2.11)
560
561Mode Sense:
562get_vol: 85 03 00 00 00 00 00. (2) tell current audio volume setting
563
564Read Disc Information:
565tocdesc: 8b 00 00 00 00 00 00. (6) read the toc descriptor ("msf-bin"-format)
566
567Read TOC:
568tocent: 8c fl nn 00 00 00 00. (8) read toc entry #nn
569 (fl=0:"lba"-, =2:"msf-bin"-format)
570
571Read Capacity:
572capacit: 88 00 00 00 00 00 00. (5) "read CD-ROM capacity"
573
574
575Read Path Check:
576ping: 00 00 00 00 00 00 00. (2) r0=AA, r1=55
577 ("ping" if the drive is connected)
578
579Read Drive Version:
580ident: 83 00 00 00 00 00 00. (12) gives "MATSHITAn.nn"
581 (n.nn = 2.01, 2.11., 3.00, ...)
582
583Seek:
584seek: 01 00 ll-bb-aa 00 00. (0)
585seek: 01 02 mm-ss-ff 00 00. (0)
586
587Read Data:
588read: 02 xx-xx-xx nn-nn fl. (?) read nn-nn blocks of 2048 bytes,
589 starting at block xx-xx-xx
590 fl=0: "lba"-, =2:"msf-bcd"-coded xx-xx-xx
591
592Read XA-Data:
593read: 03 xx-xx-xx nn-nn fl. (?) read nn-nn blocks of 2340 bytes,
594 starting at block xx-xx-xx
595 fl=0: "lba"-, =2:"msf-bcd"-coded xx-xx-xx
596
597Read SUB_Q:
598 89 fl 00 00 00 00 00. (13) r0: audio status, r4-r7: lba/msf,
599 fl=0: "lba", fl=2: "msf"
600
601Read Disc Code:
602 8a 00 00 00 00 00 00. (14) possibly extended "check condition"-info
603
604Read Header:
605 04 00 ll-bb-aa 00 00. (0) 4 bytes response with "check2"
606 04 02 mm-ss-ff 00 00. (0) 4 bytes response with "check2"
607
608Spin Up:
609 05 00 ll-bb-aa 00 00. (0) possibly implies a "seek"
610
611Spin Down:
612 06 ...
613
614Diagnostic:
615 07 00 ll-bb-aa 00 00. (2) 2 bytes response with "check2"
616 07 02 mm-ss-ff 00 00. (2) 2 bytes response with "check2"
617
618Read UPC:
619 08 00 ll-bb-aa 00 00. (16)
620 08 02 mm-ss-ff 00 00. (16)
621
622Read ISRC:
623 09 00 ll-bb-aa 00 00. (15) 15 bytes response with "check2"
624 09 02 mm-ss-ff 00 00. (15) 15 bytes response with "check2"
625
626Set XA Parameter:
627 86 ...
628
629Read XA Parameter:
630 87 ...
631
632==============================================================================
633============================================================================*/
634
635/*
636 * commands
637 *
638 * CR-52x: CMD0_
639 * CR-56x: CMD1_
640 * CD200: CMD2_
641 * LCS-7260: CMDL_
642 * TEAC CD-55A: CMDT_
643 * ECS-AT: CMDV_
644 */
645#define CMD1_RESET 0x0a
646#define CMD2_RESET 0x01
647#define CMDT_RESET 0xc0
648
649#define CMD1_LOCK_CTL 0x0c
650#define CMD2_LOCK_CTL 0x1e
651#define CMDT_LOCK_CTL CMD2_LOCK_CTL
652#define CMDL_LOCK_CTL 0x0e
653#define CMDV_LOCK_CTL CMDL_LOCK_CTL
654
655#define CMD1_TRAY_CTL 0x07
656#define CMD2_TRAY_CTL 0x1b
657#define CMDT_TRAY_CTL CMD2_TRAY_CTL
658#define CMDL_TRAY_CTL 0x0d
659#define CMDV_TRAY_CTL CMDL_TRAY_CTL
660
661#define CMD1_MULTISESS 0x8d
662#define CMDL_MULTISESS 0x8c
663#define CMDV_MULTISESS CMDL_MULTISESS
664
665#define CMD1_SUBCHANINF 0x11
666#define CMD2_SUBCHANINF 0x??
667
668#define CMD1_ABORT 0x08
669#define CMD2_ABORT 0x08
670#define CMDT_ABORT 0x08
671
672#define CMD2_x02 0x02
673
674#define CMD2_SETSPEED 0xda
675
676#define CMD0_PATH_CHECK 0x00
677#define CMD1_PATH_CHECK 0x???
678#define CMD2_PATH_CHECK 0x???
679#define CMDT_PATH_CHECK 0x???
680#define CMDL_PATH_CHECK CMD0_PATH_CHECK
681#define CMDV_PATH_CHECK CMD0_PATH_CHECK
682
683#define CMD0_SEEK 0x01
684#define CMD1_SEEK CMD0_SEEK
685#define CMD2_SEEK 0x2b
686#define CMDT_SEEK CMD2_SEEK
687#define CMDL_SEEK CMD0_SEEK
688#define CMDV_SEEK CMD0_SEEK
689
690#define CMD0_READ 0x02
691#define CMD1_READ 0x10
692#define CMD2_READ 0x28
693#define CMDT_READ CMD2_READ
694#define CMDL_READ CMD0_READ
695#define CMDV_READ CMD0_READ
696
697#define CMD0_READ_XA 0x03
698#define CMD2_READ_XA 0xd4
699#define CMD2_READ_XA2 0xd5
700#define CMDL_READ_XA CMD0_READ_XA /* really ?? */
701#define CMDV_READ_XA CMD0_READ_XA
702
703#define CMD0_READ_HEAD 0x04
704
705#define CMD0_SPINUP 0x05
706#define CMD1_SPINUP 0x02
707#define CMD2_SPINUP CMD2_TRAY_CTL
708#define CMDL_SPINUP CMD0_SPINUP
709#define CMDV_SPINUP CMD0_SPINUP
710
711#define CMD0_SPINDOWN 0x06 /* really??? */
712#define CMD1_SPINDOWN 0x06
713#define CMD2_SPINDOWN CMD2_TRAY_CTL
714#define CMDL_SPINDOWN 0x0d
715#define CMDV_SPINDOWN CMD0_SPINDOWN
716
717#define CMD0_DIAG 0x07
718
719#define CMD0_READ_UPC 0x08
720#define CMD1_READ_UPC 0x88
721#define CMD2_READ_UPC 0x???
722#define CMDL_READ_UPC CMD0_READ_UPC
723#define CMDV_READ_UPC 0x8f
724
725#define CMD0_READ_ISRC 0x09
726
727#define CMD0_PLAY 0x0a
728#define CMD1_PLAY 0x???
729#define CMD2_PLAY 0x???
730#define CMDL_PLAY CMD0_PLAY
731#define CMDV_PLAY CMD0_PLAY
732
733#define CMD0_PLAY_MSF 0x0b
734#define CMD1_PLAY_MSF 0x0e
735#define CMD2_PLAY_MSF 0x47
736#define CMDT_PLAY_MSF CMD2_PLAY_MSF
737#define CMDL_PLAY_MSF 0x???
738
739#define CMD0_PLAY_TI 0x0c
740#define CMD1_PLAY_TI 0x0f
741
742#define CMD0_STATUS 0x81
743#define CMD1_STATUS 0x05
744#define CMD2_STATUS 0x00
745#define CMDT_STATUS CMD2_STATUS
746#define CMDL_STATUS CMD0_STATUS
747#define CMDV_STATUS CMD0_STATUS
748#define CMD2_SEEK_LEADIN 0x00
749
750#define CMD0_READ_ERR 0x82
751#define CMD1_READ_ERR CMD0_READ_ERR
752#define CMD2_READ_ERR 0x03
753#define CMDT_READ_ERR CMD2_READ_ERR /* get audio status */
754#define CMDL_READ_ERR CMD0_READ_ERR
755#define CMDV_READ_ERR CMD0_READ_ERR
756
757#define CMD0_READ_VER 0x83
758#define CMD1_READ_VER CMD0_READ_VER
759#define CMD2_READ_VER 0x12
760#define CMDT_READ_VER CMD2_READ_VER /* really ?? */
761#define CMDL_READ_VER CMD0_READ_VER
762#define CMDV_READ_VER CMD0_READ_VER
763
764#define CMD0_SETMODE 0x84
765#define CMD1_SETMODE 0x09
766#define CMD2_SETMODE 0x55
767#define CMDT_SETMODE CMD2_SETMODE
768#define CMDL_SETMODE CMD0_SETMODE
769
770#define CMD0_GETMODE 0x85
771#define CMD1_GETMODE 0x84
772#define CMD2_GETMODE 0x5a
773#define CMDT_GETMODE CMD2_GETMODE
774#define CMDL_GETMODE CMD0_GETMODE
775
776#define CMD0_SET_XA 0x86
777
778#define CMD0_GET_XA 0x87
779
780#define CMD0_CAPACITY 0x88
781#define CMD1_CAPACITY 0x85
782#define CMD2_CAPACITY 0x25
783#define CMDL_CAPACITY CMD0_CAPACITY /* missing in some firmware versions */
784
785#define CMD0_READSUBQ 0x89
786#define CMD1_READSUBQ 0x87
787#define CMD2_READSUBQ 0x42
788#define CMDT_READSUBQ CMD2_READSUBQ
789#define CMDL_READSUBQ CMD0_READSUBQ
790#define CMDV_READSUBQ CMD0_READSUBQ
791
792#define CMD0_DISKCODE 0x8a
793
794#define CMD0_DISKINFO 0x8b
795#define CMD1_DISKINFO CMD0_DISKINFO
796#define CMD2_DISKINFO 0x43
797#define CMDT_DISKINFO CMD2_DISKINFO
798#define CMDL_DISKINFO CMD0_DISKINFO
799#define CMDV_DISKINFO CMD0_DISKINFO
800
801#define CMD0_READTOC 0x8c
802#define CMD1_READTOC CMD0_READTOC
803#define CMD2_READTOC 0x???
804#define CMDL_READTOC CMD0_READTOC
805#define CMDV_READTOC CMD0_READTOC
806
807#define CMD0_PAU_RES 0x8d
808#define CMD1_PAU_RES 0x0d
809#define CMD2_PAU_RES 0x4b
810#define CMDT_PAUSE CMD2_PAU_RES
811#define CMDL_PAU_RES CMD0_PAU_RES
812#define CMDV_PAUSE CMD0_PAU_RES
813
814#define CMD0_PACKET 0x8e
815#define CMD1_PACKET CMD0_PACKET
816#define CMD2_PACKET 0x???
817#define CMDL_PACKET CMD0_PACKET
818#define CMDV_PACKET 0x???
819
820/*==========================================================================*/
821/*==========================================================================*/
822#endif /* _LINUX_SBPCD_H */
823/*==========================================================================*/
824/*
825 * Overrides for Emacs so that we follow Linus's tabbing style.
826 * Emacs will notice this stuff at the end of the file and automatically
827 * adjust the settings for this buffer only. This must remain at the end
828 * of the file.
829 * ---------------------------------------------------------------------------
830 * Local variables:
831 * c-indent-level: 8
832 * c-brace-imaginary-offset: 0
833 * c-brace-offset: -8
834 * c-argdecl-indent: 8
835 * c-label-offset: -8
836 * c-continued-statement-offset: 8
837 * c-continued-brace-offset: 0
838 * End:
839 */
diff --git a/drivers/cdrom/sjcd.c b/drivers/cdrom/sjcd.c
new file mode 100644
index 000000000000..4e7a342ec36f
--- /dev/null
+++ b/drivers/cdrom/sjcd.c
@@ -0,0 +1,1817 @@
1/* -- sjcd.c
2 *
3 * Sanyo CD-ROM device driver implementation, Version 1.6
4 * Copyright (C) 1995 Vadim V. Model
5 *
6 * model@cecmow.enet.dec.com
7 * vadim@rbrf.ru
8 * vadim@ipsun.ras.ru
9 *
10 *
11 * This driver is based on pre-works by Eberhard Moenkeberg (emoenke@gwdg.de);
12 * it was developed under use of mcd.c from Martin Harriss, with help of
13 * Eric van der Maarel (H.T.M.v.d.Maarel@marin.nl).
14 *
15 * It is planned to include these routines into sbpcd.c later - to make
16 * a "mixed use" on one cable possible for all kinds of drives which use
17 * the SoundBlaster/Panasonic style CDROM interface. But today, the
18 * ability to install directly from CDROM is more important than flexibility.
19 *
20 * This program is free software; you can redistribute it and/or modify
21 * it under the terms of the GNU General Public License as published by
22 * the Free Software Foundation; either version 2 of the License, or
23 * (at your option) any later version.
24 *
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
29 *
30 * You should have received a copy of the GNU General Public License
31 * along with this program; if not, write to the Free Software
32 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
33 *
34 * History:
35 * 1.1 First public release with kernel version 1.3.7.
36 * Written by Vadim Model.
37 * 1.2 Added detection and configuration of cdrom interface
38 * on ISP16 soundcard.
39 * Allow for command line options: sjcd=<io_base>,<irq>,<dma>
40 * 1.3 Some minor changes to README.sjcd.
41 * 1.4 MSS Sound support!! Listen to a CD through the speakers.
42 * 1.5 Module support and bugfixes.
43 * Tray locking.
44 * 1.6 Removed ISP16 code from this driver.
45 * Allow only to set io base address on command line: sjcd=<io_base>
46 * Changes to Documentation/cdrom/sjcd
47 * Added cleanup after any error in the initialisation.
48 * 1.7 Added code to set the sector size tables to prevent the bug present in
49 * the previous version of this driver. Coded added by Anthony Barbachan
50 * from bugfix tip originally suggested by Alan Cox.
51 *
52 * November 1999 -- Make kernel-parameter implementation work with 2.3.x
53 * Removed init_module & cleanup_module in favor of
54 * module_init & module_exit.
55 * Torben Mathiasen <tmm@image.dk>
56 */
57
58#define SJCD_VERSION_MAJOR 1
59#define SJCD_VERSION_MINOR 7
60
61#include <linux/module.h>
62#include <linux/errno.h>
63#include <linux/sched.h>
64#include <linux/mm.h>
65#include <linux/timer.h>
66#include <linux/fs.h>
67#include <linux/kernel.h>
68#include <linux/cdrom.h>
69#include <linux/ioport.h>
70#include <linux/string.h>
71#include <linux/major.h>
72#include <linux/init.h>
73
74#include <asm/system.h>
75#include <asm/io.h>
76#include <asm/uaccess.h>
77#include <linux/blkdev.h>
78#include "sjcd.h"
79
80static int sjcd_present = 0;
81static struct request_queue *sjcd_queue;
82
83#define MAJOR_NR SANYO_CDROM_MAJOR
84#define QUEUE (sjcd_queue)
85#define CURRENT elv_next_request(sjcd_queue)
86
87#define SJCD_BUF_SIZ 32 /* cdr-h94a has internal 64K buffer */
88
89/*
90 * buffer for block size conversion
91 */
92static char sjcd_buf[2048 * SJCD_BUF_SIZ];
93static volatile int sjcd_buf_bn[SJCD_BUF_SIZ], sjcd_next_bn;
94static volatile int sjcd_buf_in, sjcd_buf_out = -1;
95
96/*
97 * Status.
98 */
99static unsigned short sjcd_status_valid = 0;
100static unsigned short sjcd_door_closed;
101static unsigned short sjcd_door_was_open;
102static unsigned short sjcd_media_is_available;
103static unsigned short sjcd_media_is_changed;
104static unsigned short sjcd_toc_uptodate = 0;
105static unsigned short sjcd_command_failed;
106static volatile unsigned char sjcd_completion_status = 0;
107static volatile unsigned char sjcd_completion_error = 0;
108static unsigned short sjcd_command_is_in_progress = 0;
109static unsigned short sjcd_error_reported = 0;
110static DEFINE_SPINLOCK(sjcd_lock);
111
112static int sjcd_open_count;
113
114static int sjcd_audio_status;
115static struct sjcd_play_msf sjcd_playing;
116
117static int sjcd_base = SJCD_BASE_ADDR;
118
119module_param(sjcd_base, int, 0);
120
121static DECLARE_WAIT_QUEUE_HEAD(sjcd_waitq);
122
123/*
124 * Data transfer.
125 */
126static volatile unsigned short sjcd_transfer_is_active = 0;
127
128enum sjcd_transfer_state {
129 SJCD_S_IDLE = 0,
130 SJCD_S_START = 1,
131 SJCD_S_MODE = 2,
132 SJCD_S_READ = 3,
133 SJCD_S_DATA = 4,
134 SJCD_S_STOP = 5,
135 SJCD_S_STOPPING = 6
136};
137static enum sjcd_transfer_state sjcd_transfer_state = SJCD_S_IDLE;
138static long sjcd_transfer_timeout = 0;
139static int sjcd_read_count = 0;
140static unsigned char sjcd_mode = 0;
141
142#define SJCD_READ_TIMEOUT 5000
143
144#if defined( SJCD_GATHER_STAT )
145/*
146 * Statistic.
147 */
148static struct sjcd_stat statistic;
149#endif
150
151/*
152 * Timer.
153 */
154static struct timer_list sjcd_delay_timer = TIMER_INITIALIZER(NULL, 0, 0);
155
156#define SJCD_SET_TIMER( func, tmout ) \
157 ( sjcd_delay_timer.expires = jiffies+tmout, \
158 sjcd_delay_timer.function = ( void * )func, \
159 add_timer( &sjcd_delay_timer ) )
160
161#define CLEAR_TIMER del_timer( &sjcd_delay_timer )
162
163/*
164 * Set up device, i.e., use command line data to set
165 * base address.
166 */
167#ifndef MODULE
168static int __init sjcd_setup(char *str)
169{
170 int ints[2];
171 (void) get_options(str, ARRAY_SIZE(ints), ints);
172 if (ints[0] > 0)
173 sjcd_base = ints[1];
174
175 return 1;
176}
177
178__setup("sjcd=", sjcd_setup);
179
180#endif
181
182/*
183 * Special converters.
184 */
185static unsigned char bin2bcd(int bin)
186{
187 int u, v;
188
189 u = bin % 10;
190 v = bin / 10;
191 return (u | (v << 4));
192}
193
194static int bcd2bin(unsigned char bcd)
195{
196 return ((bcd >> 4) * 10 + (bcd & 0x0F));
197}
198
199static long msf2hsg(struct msf *mp)
200{
201 return (bcd2bin(mp->frame) + bcd2bin(mp->sec) * 75
202 + bcd2bin(mp->min) * 4500 - 150);
203}
204
205static void hsg2msf(long hsg, struct msf *msf)
206{
207 hsg += 150;
208 msf->min = hsg / 4500;
209 hsg %= 4500;
210 msf->sec = hsg / 75;
211 msf->frame = hsg % 75;
212 msf->min = bin2bcd(msf->min); /* convert to BCD */
213 msf->sec = bin2bcd(msf->sec);
214 msf->frame = bin2bcd(msf->frame);
215}
216
217/*
218 * Send a command to cdrom. Invalidate status.
219 */
220static void sjcd_send_cmd(unsigned char cmd)
221{
222#if defined( SJCD_TRACE )
223 printk("SJCD: send_cmd( 0x%x )\n", cmd);
224#endif
225 outb(cmd, SJCDPORT(0));
226 sjcd_command_is_in_progress = 1;
227 sjcd_status_valid = 0;
228 sjcd_command_failed = 0;
229}
230
231/*
232 * Send a command with one arg to cdrom. Invalidate status.
233 */
234static void sjcd_send_1_cmd(unsigned char cmd, unsigned char a)
235{
236#if defined( SJCD_TRACE )
237 printk("SJCD: send_1_cmd( 0x%x, 0x%x )\n", cmd, a);
238#endif
239 outb(cmd, SJCDPORT(0));
240 outb(a, SJCDPORT(0));
241 sjcd_command_is_in_progress = 1;
242 sjcd_status_valid = 0;
243 sjcd_command_failed = 0;
244}
245
246/*
247 * Send a command with four args to cdrom. Invalidate status.
248 */
249static void sjcd_send_4_cmd(unsigned char cmd, unsigned char a,
250 unsigned char b, unsigned char c,
251 unsigned char d)
252{
253#if defined( SJCD_TRACE )
254 printk("SJCD: send_4_cmd( 0x%x )\n", cmd);
255#endif
256 outb(cmd, SJCDPORT(0));
257 outb(a, SJCDPORT(0));
258 outb(b, SJCDPORT(0));
259 outb(c, SJCDPORT(0));
260 outb(d, SJCDPORT(0));
261 sjcd_command_is_in_progress = 1;
262 sjcd_status_valid = 0;
263 sjcd_command_failed = 0;
264}
265
266/*
267 * Send a play or read command to cdrom. Invalidate Status.
268 */
269static void sjcd_send_6_cmd(unsigned char cmd, struct sjcd_play_msf *pms)
270{
271#if defined( SJCD_TRACE )
272 printk("SJCD: send_long_cmd( 0x%x )\n", cmd);
273#endif
274 outb(cmd, SJCDPORT(0));
275 outb(pms->start.min, SJCDPORT(0));
276 outb(pms->start.sec, SJCDPORT(0));
277 outb(pms->start.frame, SJCDPORT(0));
278 outb(pms->end.min, SJCDPORT(0));
279 outb(pms->end.sec, SJCDPORT(0));
280 outb(pms->end.frame, SJCDPORT(0));
281 sjcd_command_is_in_progress = 1;
282 sjcd_status_valid = 0;
283 sjcd_command_failed = 0;
284}
285
286/*
287 * Get a value from the data port. Should not block, so we use a little
288 * wait for a while. Returns 0 if OK.
289 */
290static int sjcd_load_response(void *buf, int len)
291{
292 unsigned char *resp = (unsigned char *) buf;
293
294 for (; len; --len) {
295 int i;
296 for (i = 200;
297 i-- && !SJCD_STATUS_AVAILABLE(inb(SJCDPORT(1))););
298 if (i > 0)
299 *resp++ = (unsigned char) inb(SJCDPORT(0));
300 else
301 break;
302 }
303 return (len);
304}
305
306/*
307 * Load and parse command completion status (drive info byte and maybe error).
308 * Sorry, no error classification yet.
309 */
310static void sjcd_load_status(void)
311{
312 sjcd_media_is_changed = 0;
313 sjcd_completion_error = 0;
314 sjcd_completion_status = inb(SJCDPORT(0));
315 if (sjcd_completion_status & SST_DOOR_OPENED) {
316 sjcd_door_closed = sjcd_media_is_available = 0;
317 } else {
318 sjcd_door_closed = 1;
319 if (sjcd_completion_status & SST_MEDIA_CHANGED)
320 sjcd_media_is_available = sjcd_media_is_changed =
321 1;
322 else if (sjcd_completion_status & 0x0F) {
323 /*
324 * OK, we seem to catch an error ...
325 */
326 while (!SJCD_STATUS_AVAILABLE(inb(SJCDPORT(1))));
327 sjcd_completion_error = inb(SJCDPORT(0));
328 if ((sjcd_completion_status & 0x08) &&
329 (sjcd_completion_error & 0x40))
330 sjcd_media_is_available = 0;
331 else
332 sjcd_command_failed = 1;
333 } else
334 sjcd_media_is_available = 1;
335 }
336 /*
337 * Ok, status loaded successfully.
338 */
339 sjcd_status_valid = 1, sjcd_error_reported = 0;
340 sjcd_command_is_in_progress = 0;
341
342 /*
343 * If the disk is changed, the TOC is not valid.
344 */
345 if (sjcd_media_is_changed)
346 sjcd_toc_uptodate = 0;
347#if defined( SJCD_TRACE )
348 printk("SJCD: status %02x.%02x loaded.\n",
349 (int) sjcd_completion_status, (int) sjcd_completion_error);
350#endif
351}
352
353/*
354 * Read status from cdrom. Check to see if the status is available.
355 */
356static int sjcd_check_status(void)
357{
358 /*
359 * Try to load the response from cdrom into buffer.
360 */
361 if (SJCD_STATUS_AVAILABLE(inb(SJCDPORT(1)))) {
362 sjcd_load_status();
363 return (1);
364 } else {
365 /*
366 * No status is available.
367 */
368 return (0);
369 }
370}
371
372/*
373 * This is just timeout counter, and nothing more. Surprised ? :-)
374 */
375static volatile long sjcd_status_timeout;
376
377/*
378 * We need about 10 seconds to wait. The longest command takes about 5 seconds
379 * to probe the disk (usually after tray closed or drive reset). Other values
380 * should be thought of for other commands.
381 */
382#define SJCD_WAIT_FOR_STATUS_TIMEOUT 1000
383
384static void sjcd_status_timer(void)
385{
386 if (sjcd_check_status()) {
387 /*
388 * The command completed and status is loaded, stop waiting.
389 */
390 wake_up(&sjcd_waitq);
391 } else if (--sjcd_status_timeout <= 0) {
392 /*
393 * We are timed out.
394 */
395 wake_up(&sjcd_waitq);
396 } else {
397 /*
398 * We have still some time to wait. Try again.
399 */
400 SJCD_SET_TIMER(sjcd_status_timer, 1);
401 }
402}
403
404/*
405 * Wait for status for 10 sec approx. Returns non-positive when timed out.
406 * Should not be used while reading data CDs.
407 */
408static int sjcd_wait_for_status(void)
409{
410 sjcd_status_timeout = SJCD_WAIT_FOR_STATUS_TIMEOUT;
411 SJCD_SET_TIMER(sjcd_status_timer, 1);
412 sleep_on(&sjcd_waitq);
413#if defined( SJCD_DIAGNOSTIC ) || defined ( SJCD_TRACE )
414 if (sjcd_status_timeout <= 0)
415 printk("SJCD: Error Wait For Status.\n");
416#endif
417 return (sjcd_status_timeout);
418}
419
420static int sjcd_receive_status(void)
421{
422 int i;
423#if defined( SJCD_TRACE )
424 printk("SJCD: receive_status\n");
425#endif
426 /*
427 * Wait a bit for status available.
428 */
429 for (i = 200; i-- && (sjcd_check_status() == 0););
430 if (i < 0) {
431#if defined( SJCD_TRACE )
432 printk("SJCD: long wait for status\n");
433#endif
434 if (sjcd_wait_for_status() <= 0)
435 printk("SJCD: Timeout when read status.\n");
436 else
437 i = 0;
438 }
439 return (i);
440}
441
442/*
443 * Load the status. Issue get status command and wait for status available.
444 */
445static void sjcd_get_status(void)
446{
447#if defined( SJCD_TRACE )
448 printk("SJCD: get_status\n");
449#endif
450 sjcd_send_cmd(SCMD_GET_STATUS);
451 sjcd_receive_status();
452}
453
454/*
455 * Check the drive if the disk is changed. Should be revised.
456 */
457static int sjcd_disk_change(struct gendisk *disk)
458{
459#if 0
460 printk("SJCD: sjcd_disk_change(%s)\n", disk->disk_name);
461#endif
462 if (!sjcd_command_is_in_progress)
463 sjcd_get_status();
464 return (sjcd_status_valid ? sjcd_media_is_changed : 0);
465}
466
467/*
468 * Read the table of contents (TOC) and TOC header if necessary.
469 * We assume that the drive contains no more than 99 toc entries.
470 */
471static struct sjcd_hw_disk_info sjcd_table_of_contents[SJCD_MAX_TRACKS];
472static unsigned char sjcd_first_track_no, sjcd_last_track_no;
473#define sjcd_disk_length sjcd_table_of_contents[0].un.track_msf
474
475static int sjcd_update_toc(void)
476{
477 struct sjcd_hw_disk_info info;
478 int i;
479#if defined( SJCD_TRACE )
480 printk("SJCD: update toc:\n");
481#endif
482 /*
483 * check to see if we need to do anything
484 */
485 if (sjcd_toc_uptodate)
486 return (0);
487
488 /*
489 * Get the TOC start information.
490 */
491 sjcd_send_1_cmd(SCMD_GET_DISK_INFO, SCMD_GET_1_TRACK);
492 sjcd_receive_status();
493
494 if (!sjcd_status_valid) {
495 printk("SJCD: cannot load status.\n");
496 return (-1);
497 }
498
499 if (!sjcd_media_is_available) {
500 printk("SJCD: no disk in drive\n");
501 return (-1);
502 }
503
504 if (!sjcd_command_failed) {
505 if (sjcd_load_response(&info, sizeof(info)) != 0) {
506 printk
507 ("SJCD: cannot load response about TOC start.\n");
508 return (-1);
509 }
510 sjcd_first_track_no = bcd2bin(info.un.track_no);
511 } else {
512 printk("SJCD: get first failed\n");
513 return (-1);
514 }
515#if defined( SJCD_TRACE )
516 printk("SJCD: TOC start 0x%02x ", sjcd_first_track_no);
517#endif
518 /*
519 * Get the TOC finish information.
520 */
521 sjcd_send_1_cmd(SCMD_GET_DISK_INFO, SCMD_GET_L_TRACK);
522 sjcd_receive_status();
523
524 if (!sjcd_status_valid) {
525 printk("SJCD: cannot load status.\n");
526 return (-1);
527 }
528
529 if (!sjcd_media_is_available) {
530 printk("SJCD: no disk in drive\n");
531 return (-1);
532 }
533
534 if (!sjcd_command_failed) {
535 if (sjcd_load_response(&info, sizeof(info)) != 0) {
536 printk
537 ("SJCD: cannot load response about TOC finish.\n");
538 return (-1);
539 }
540 sjcd_last_track_no = bcd2bin(info.un.track_no);
541 } else {
542 printk("SJCD: get last failed\n");
543 return (-1);
544 }
545#if defined( SJCD_TRACE )
546 printk("SJCD: TOC finish 0x%02x ", sjcd_last_track_no);
547#endif
548 for (i = sjcd_first_track_no; i <= sjcd_last_track_no; i++) {
549 /*
550 * Get the first track information.
551 */
552 sjcd_send_1_cmd(SCMD_GET_DISK_INFO, bin2bcd(i));
553 sjcd_receive_status();
554
555 if (!sjcd_status_valid) {
556 printk("SJCD: cannot load status.\n");
557 return (-1);
558 }
559
560 if (!sjcd_media_is_available) {
561 printk("SJCD: no disk in drive\n");
562 return (-1);
563 }
564
565 if (!sjcd_command_failed) {
566 if (sjcd_load_response(&sjcd_table_of_contents[i],
567 sizeof(struct
568 sjcd_hw_disk_info))
569 != 0) {
570 printk
571 ("SJCD: cannot load info for %d track\n",
572 i);
573 return (-1);
574 }
575 } else {
576 printk("SJCD: get info %d failed\n", i);
577 return (-1);
578 }
579 }
580
581 /*
582 * Get the disk length info.
583 */
584 sjcd_send_1_cmd(SCMD_GET_DISK_INFO, SCMD_GET_D_SIZE);
585 sjcd_receive_status();
586
587 if (!sjcd_status_valid) {
588 printk("SJCD: cannot load status.\n");
589 return (-1);
590 }
591
592 if (!sjcd_media_is_available) {
593 printk("SJCD: no disk in drive\n");
594 return (-1);
595 }
596
597 if (!sjcd_command_failed) {
598 if (sjcd_load_response(&info, sizeof(info)) != 0) {
599 printk
600 ("SJCD: cannot load response about disk size.\n");
601 return (-1);
602 }
603 sjcd_disk_length.min = info.un.track_msf.min;
604 sjcd_disk_length.sec = info.un.track_msf.sec;
605 sjcd_disk_length.frame = info.un.track_msf.frame;
606 } else {
607 printk("SJCD: get size failed\n");
608 return (1);
609 }
610#if defined( SJCD_TRACE )
611 printk("SJCD: (%02x:%02x.%02x)\n", sjcd_disk_length.min,
612 sjcd_disk_length.sec, sjcd_disk_length.frame);
613#endif
614 return (0);
615}
616
617/*
618 * Load subchannel information.
619 */
620static int sjcd_get_q_info(struct sjcd_hw_qinfo *qp)
621{
622 int s;
623#if defined( SJCD_TRACE )
624 printk("SJCD: load sub q\n");
625#endif
626 sjcd_send_cmd(SCMD_GET_QINFO);
627 s = sjcd_receive_status();
628 if (s < 0 || sjcd_command_failed || !sjcd_status_valid) {
629 sjcd_send_cmd(0xF2);
630 s = sjcd_receive_status();
631 if (s < 0 || sjcd_command_failed || !sjcd_status_valid)
632 return (-1);
633 sjcd_send_cmd(SCMD_GET_QINFO);
634 s = sjcd_receive_status();
635 if (s < 0 || sjcd_command_failed || !sjcd_status_valid)
636 return (-1);
637 }
638 if (sjcd_media_is_available)
639 if (sjcd_load_response(qp, sizeof(*qp)) == 0)
640 return (0);
641 return (-1);
642}
643
644/*
645 * Start playing from the specified position.
646 */
647static int sjcd_play(struct sjcd_play_msf *mp)
648{
649 struct sjcd_play_msf msf;
650
651 /*
652 * Turn the device to play mode.
653 */
654 sjcd_send_1_cmd(SCMD_SET_MODE, SCMD_MODE_PLAY);
655 if (sjcd_receive_status() < 0)
656 return (-1);
657
658 /*
659 * Seek to the starting point.
660 */
661 msf.start = mp->start;
662 msf.end.min = msf.end.sec = msf.end.frame = 0x00;
663 sjcd_send_6_cmd(SCMD_SEEK, &msf);
664 if (sjcd_receive_status() < 0)
665 return (-1);
666
667 /*
668 * Start playing.
669 */
670 sjcd_send_6_cmd(SCMD_PLAY, mp);
671 return (sjcd_receive_status());
672}
673
674/*
675 * Tray control functions.
676 */
677static int sjcd_tray_close(void)
678{
679#if defined( SJCD_TRACE )
680 printk("SJCD: tray_close\n");
681#endif
682 sjcd_send_cmd(SCMD_CLOSE_TRAY);
683 return (sjcd_receive_status());
684}
685
686static int sjcd_tray_lock(void)
687{
688#if defined( SJCD_TRACE )
689 printk("SJCD: tray_lock\n");
690#endif
691 sjcd_send_cmd(SCMD_LOCK_TRAY);
692 return (sjcd_receive_status());
693}
694
695static int sjcd_tray_unlock(void)
696{
697#if defined( SJCD_TRACE )
698 printk("SJCD: tray_unlock\n");
699#endif
700 sjcd_send_cmd(SCMD_UNLOCK_TRAY);
701 return (sjcd_receive_status());
702}
703
704static int sjcd_tray_open(void)
705{
706#if defined( SJCD_TRACE )
707 printk("SJCD: tray_open\n");
708#endif
709 sjcd_send_cmd(SCMD_EJECT_TRAY);
710 return (sjcd_receive_status());
711}
712
713/*
714 * Do some user commands.
715 */
716static int sjcd_ioctl(struct inode *ip, struct file *fp,
717 unsigned int cmd, unsigned long arg)
718{
719 void __user *argp = (void __user *)arg;
720#if defined( SJCD_TRACE )
721 printk("SJCD:ioctl\n");
722#endif
723
724 sjcd_get_status();
725 if (!sjcd_status_valid)
726 return (-EIO);
727 if (sjcd_update_toc() < 0)
728 return (-EIO);
729
730 switch (cmd) {
731 case CDROMSTART:{
732#if defined( SJCD_TRACE )
733 printk("SJCD: ioctl: start\n");
734#endif
735 return (0);
736 }
737
738 case CDROMSTOP:{
739#if defined( SJCD_TRACE )
740 printk("SJCD: ioctl: stop\n");
741#endif
742 sjcd_send_cmd(SCMD_PAUSE);
743 (void) sjcd_receive_status();
744 sjcd_audio_status = CDROM_AUDIO_NO_STATUS;
745 return (0);
746 }
747
748 case CDROMPAUSE:{
749 struct sjcd_hw_qinfo q_info;
750#if defined( SJCD_TRACE )
751 printk("SJCD: ioctl: pause\n");
752#endif
753 if (sjcd_audio_status == CDROM_AUDIO_PLAY) {
754 sjcd_send_cmd(SCMD_PAUSE);
755 (void) sjcd_receive_status();
756 if (sjcd_get_q_info(&q_info) < 0) {
757 sjcd_audio_status =
758 CDROM_AUDIO_NO_STATUS;
759 } else {
760 sjcd_audio_status =
761 CDROM_AUDIO_PAUSED;
762 sjcd_playing.start = q_info.abs;
763 }
764 return (0);
765 } else
766 return (-EINVAL);
767 }
768
769 case CDROMRESUME:{
770#if defined( SJCD_TRACE )
771 printk("SJCD: ioctl: resume\n");
772#endif
773 if (sjcd_audio_status == CDROM_AUDIO_PAUSED) {
774 /*
775 * continue play starting at saved location
776 */
777 if (sjcd_play(&sjcd_playing) < 0) {
778 sjcd_audio_status =
779 CDROM_AUDIO_ERROR;
780 return (-EIO);
781 } else {
782 sjcd_audio_status =
783 CDROM_AUDIO_PLAY;
784 return (0);
785 }
786 } else
787 return (-EINVAL);
788 }
789
790 case CDROMPLAYTRKIND:{
791 struct cdrom_ti ti;
792 int s = -EFAULT;
793#if defined( SJCD_TRACE )
794 printk("SJCD: ioctl: playtrkind\n");
795#endif
796 if (!copy_from_user(&ti, argp, sizeof(ti))) {
797 s = 0;
798 if (ti.cdti_trk0 < sjcd_first_track_no)
799 return (-EINVAL);
800 if (ti.cdti_trk1 > sjcd_last_track_no)
801 ti.cdti_trk1 = sjcd_last_track_no;
802 if (ti.cdti_trk0 > ti.cdti_trk1)
803 return (-EINVAL);
804
805 sjcd_playing.start =
806 sjcd_table_of_contents[ti.cdti_trk0].
807 un.track_msf;
808 sjcd_playing.end =
809 (ti.cdti_trk1 <
810 sjcd_last_track_no) ?
811 sjcd_table_of_contents[ti.cdti_trk1 +
812 1].un.
813 track_msf : sjcd_table_of_contents[0].
814 un.track_msf;
815
816 if (sjcd_play(&sjcd_playing) < 0) {
817 sjcd_audio_status =
818 CDROM_AUDIO_ERROR;
819 return (-EIO);
820 } else
821 sjcd_audio_status =
822 CDROM_AUDIO_PLAY;
823 }
824 return (s);
825 }
826
827 case CDROMPLAYMSF:{
828 struct cdrom_msf sjcd_msf;
829 int s;
830#if defined( SJCD_TRACE )
831 printk("SJCD: ioctl: playmsf\n");
832#endif
833 if ((s =
834 access_ok(VERIFY_READ, argp, sizeof(sjcd_msf))
835 ? 0 : -EFAULT) == 0) {
836 if (sjcd_audio_status == CDROM_AUDIO_PLAY) {
837 sjcd_send_cmd(SCMD_PAUSE);
838 (void) sjcd_receive_status();
839 sjcd_audio_status =
840 CDROM_AUDIO_NO_STATUS;
841 }
842
843 if (copy_from_user(&sjcd_msf, argp,
844 sizeof(sjcd_msf)))
845 return (-EFAULT);
846
847 sjcd_playing.start.min =
848 bin2bcd(sjcd_msf.cdmsf_min0);
849 sjcd_playing.start.sec =
850 bin2bcd(sjcd_msf.cdmsf_sec0);
851 sjcd_playing.start.frame =
852 bin2bcd(sjcd_msf.cdmsf_frame0);
853 sjcd_playing.end.min =
854 bin2bcd(sjcd_msf.cdmsf_min1);
855 sjcd_playing.end.sec =
856 bin2bcd(sjcd_msf.cdmsf_sec1);
857 sjcd_playing.end.frame =
858 bin2bcd(sjcd_msf.cdmsf_frame1);
859
860 if (sjcd_play(&sjcd_playing) < 0) {
861 sjcd_audio_status =
862 CDROM_AUDIO_ERROR;
863 return (-EIO);
864 } else
865 sjcd_audio_status =
866 CDROM_AUDIO_PLAY;
867 }
868 return (s);
869 }
870
871 case CDROMREADTOCHDR:{
872 struct cdrom_tochdr toc_header;
873#if defined (SJCD_TRACE )
874 printk("SJCD: ioctl: readtocheader\n");
875#endif
876 toc_header.cdth_trk0 = sjcd_first_track_no;
877 toc_header.cdth_trk1 = sjcd_last_track_no;
878 if (copy_to_user(argp, &toc_header,
879 sizeof(toc_header)))
880 return -EFAULT;
881 return 0;
882 }
883
884 case CDROMREADTOCENTRY:{
885 struct cdrom_tocentry toc_entry;
886 int s;
887#if defined( SJCD_TRACE )
888 printk("SJCD: ioctl: readtocentry\n");
889#endif
890 if ((s =
891 access_ok(VERIFY_WRITE, argp, sizeof(toc_entry))
892 ? 0 : -EFAULT) == 0) {
893 struct sjcd_hw_disk_info *tp;
894
895 if (copy_from_user(&toc_entry, argp,
896 sizeof(toc_entry)))
897 return (-EFAULT);
898 if (toc_entry.cdte_track == CDROM_LEADOUT)
899 tp = &sjcd_table_of_contents[0];
900 else if (toc_entry.cdte_track <
901 sjcd_first_track_no)
902 return (-EINVAL);
903 else if (toc_entry.cdte_track >
904 sjcd_last_track_no)
905 return (-EINVAL);
906 else
907 tp = &sjcd_table_of_contents
908 [toc_entry.cdte_track];
909
910 toc_entry.cdte_adr =
911 tp->track_control & 0x0F;
912 toc_entry.cdte_ctrl =
913 tp->track_control >> 4;
914
915 switch (toc_entry.cdte_format) {
916 case CDROM_LBA:
917 toc_entry.cdte_addr.lba =
918 msf2hsg(&(tp->un.track_msf));
919 break;
920 case CDROM_MSF:
921 toc_entry.cdte_addr.msf.minute =
922 bcd2bin(tp->un.track_msf.min);
923 toc_entry.cdte_addr.msf.second =
924 bcd2bin(tp->un.track_msf.sec);
925 toc_entry.cdte_addr.msf.frame =
926 bcd2bin(tp->un.track_msf.
927 frame);
928 break;
929 default:
930 return (-EINVAL);
931 }
932 if (copy_to_user(argp, &toc_entry,
933 sizeof(toc_entry)))
934 s = -EFAULT;
935 }
936 return (s);
937 }
938
939 case CDROMSUBCHNL:{
940 struct cdrom_subchnl subchnl;
941 int s;
942#if defined( SJCD_TRACE )
943 printk("SJCD: ioctl: subchnl\n");
944#endif
945 if ((s =
946 access_ok(VERIFY_WRITE, argp, sizeof(subchnl))
947 ? 0 : -EFAULT) == 0) {
948 struct sjcd_hw_qinfo q_info;
949
950 if (copy_from_user(&subchnl, argp,
951 sizeof(subchnl)))
952 return (-EFAULT);
953
954 if (sjcd_get_q_info(&q_info) < 0)
955 return (-EIO);
956
957 subchnl.cdsc_audiostatus =
958 sjcd_audio_status;
959 subchnl.cdsc_adr =
960 q_info.track_control & 0x0F;
961 subchnl.cdsc_ctrl =
962 q_info.track_control >> 4;
963 subchnl.cdsc_trk =
964 bcd2bin(q_info.track_no);
965 subchnl.cdsc_ind = bcd2bin(q_info.x);
966
967 switch (subchnl.cdsc_format) {
968 case CDROM_LBA:
969 subchnl.cdsc_absaddr.lba =
970 msf2hsg(&(q_info.abs));
971 subchnl.cdsc_reladdr.lba =
972 msf2hsg(&(q_info.rel));
973 break;
974 case CDROM_MSF:
975 subchnl.cdsc_absaddr.msf.minute =
976 bcd2bin(q_info.abs.min);
977 subchnl.cdsc_absaddr.msf.second =
978 bcd2bin(q_info.abs.sec);
979 subchnl.cdsc_absaddr.msf.frame =
980 bcd2bin(q_info.abs.frame);
981 subchnl.cdsc_reladdr.msf.minute =
982 bcd2bin(q_info.rel.min);
983 subchnl.cdsc_reladdr.msf.second =
984 bcd2bin(q_info.rel.sec);
985 subchnl.cdsc_reladdr.msf.frame =
986 bcd2bin(q_info.rel.frame);
987 break;
988 default:
989 return (-EINVAL);
990 }
991 if (copy_to_user(argp, &subchnl,
992 sizeof(subchnl)))
993 s = -EFAULT;
994 }
995 return (s);
996 }
997
998 case CDROMVOLCTRL:{
999 struct cdrom_volctrl vol_ctrl;
1000 int s;
1001#if defined( SJCD_TRACE )
1002 printk("SJCD: ioctl: volctrl\n");
1003#endif
1004 if ((s =
1005 access_ok(VERIFY_READ, argp, sizeof(vol_ctrl))
1006 ? 0 : -EFAULT) == 0) {
1007 unsigned char dummy[4];
1008
1009 if (copy_from_user(&vol_ctrl, argp,
1010 sizeof(vol_ctrl)))
1011 return (-EFAULT);
1012 sjcd_send_4_cmd(SCMD_SET_VOLUME,
1013 vol_ctrl.channel0, 0xFF,
1014 vol_ctrl.channel1, 0xFF);
1015 if (sjcd_receive_status() < 0)
1016 return (-EIO);
1017 (void) sjcd_load_response(dummy, 4);
1018 }
1019 return (s);
1020 }
1021
1022 case CDROMEJECT:{
1023#if defined( SJCD_TRACE )
1024 printk("SJCD: ioctl: eject\n");
1025#endif
1026 if (!sjcd_command_is_in_progress) {
1027 sjcd_tray_unlock();
1028 sjcd_send_cmd(SCMD_EJECT_TRAY);
1029 (void) sjcd_receive_status();
1030 }
1031 return (0);
1032 }
1033
1034#if defined( SJCD_GATHER_STAT )
1035 case 0xABCD:{
1036#if defined( SJCD_TRACE )
1037 printk("SJCD: ioctl: statistic\n");
1038#endif
1039 if (copy_to_user(argp, &statistic, sizeof(statistic)))
1040 return -EFAULT;
1041 return 0;
1042 }
1043#endif
1044
1045 default:
1046 return (-EINVAL);
1047 }
1048}
1049
1050/*
1051 * Invalidate internal buffers of the driver.
1052 */
1053static void sjcd_invalidate_buffers(void)
1054{
1055 int i;
1056 for (i = 0; i < SJCD_BUF_SIZ; sjcd_buf_bn[i++] = -1);
1057 sjcd_buf_out = -1;
1058}
1059
1060/*
1061 * Take care of the different block sizes between cdrom and Linux.
1062 * When Linux gets variable block sizes this will probably go away.
1063 */
1064
1065static int current_valid(void)
1066{
1067 return CURRENT &&
1068 CURRENT->cmd == READ &&
1069 CURRENT->sector != -1;
1070}
1071
1072static void sjcd_transfer(void)
1073{
1074#if defined( SJCD_TRACE )
1075 printk("SJCD: transfer:\n");
1076#endif
1077 if (current_valid()) {
1078 while (CURRENT->nr_sectors) {
1079 int i, bn = CURRENT->sector / 4;
1080 for (i = 0;
1081 i < SJCD_BUF_SIZ && sjcd_buf_bn[i] != bn;
1082 i++);
1083 if (i < SJCD_BUF_SIZ) {
1084 int offs =
1085 (i * 4 + (CURRENT->sector & 3)) * 512;
1086 int nr_sectors = 4 - (CURRENT->sector & 3);
1087 if (sjcd_buf_out != i) {
1088 sjcd_buf_out = i;
1089 if (sjcd_buf_bn[i] != bn) {
1090 sjcd_buf_out = -1;
1091 continue;
1092 }
1093 }
1094 if (nr_sectors > CURRENT->nr_sectors)
1095 nr_sectors = CURRENT->nr_sectors;
1096#if defined( SJCD_TRACE )
1097 printk("SJCD: copy out\n");
1098#endif
1099 memcpy(CURRENT->buffer, sjcd_buf + offs,
1100 nr_sectors * 512);
1101 CURRENT->nr_sectors -= nr_sectors;
1102 CURRENT->sector += nr_sectors;
1103 CURRENT->buffer += nr_sectors * 512;
1104 } else {
1105 sjcd_buf_out = -1;
1106 break;
1107 }
1108 }
1109 }
1110#if defined( SJCD_TRACE )
1111 printk("SJCD: transfer: done\n");
1112#endif
1113}
1114
1115static void sjcd_poll(void)
1116{
1117#if defined( SJCD_GATHER_STAT )
1118 /*
1119 * Update total number of ticks.
1120 */
1121 statistic.ticks++;
1122 statistic.tticks[sjcd_transfer_state]++;
1123#endif
1124
1125 ReSwitch:switch (sjcd_transfer_state) {
1126
1127 case SJCD_S_IDLE:{
1128#if defined( SJCD_GATHER_STAT )
1129 statistic.idle_ticks++;
1130#endif
1131#if defined( SJCD_TRACE )
1132 printk("SJCD_S_IDLE\n");
1133#endif
1134 return;
1135 }
1136
1137 case SJCD_S_START:{
1138#if defined( SJCD_GATHER_STAT )
1139 statistic.start_ticks++;
1140#endif
1141 sjcd_send_cmd(SCMD_GET_STATUS);
1142 sjcd_transfer_state =
1143 sjcd_mode ==
1144 SCMD_MODE_COOKED ? SJCD_S_READ : SJCD_S_MODE;
1145 sjcd_transfer_timeout = 500;
1146#if defined( SJCD_TRACE )
1147 printk("SJCD_S_START: goto SJCD_S_%s mode\n",
1148 sjcd_transfer_state ==
1149 SJCD_S_READ ? "READ" : "MODE");
1150#endif
1151 break;
1152 }
1153
1154 case SJCD_S_MODE:{
1155 if (sjcd_check_status()) {
1156 /*
1157 * Previous command is completed.
1158 */
1159 if (!sjcd_status_valid
1160 || sjcd_command_failed) {
1161#if defined( SJCD_TRACE )
1162 printk
1163 ("SJCD_S_MODE: pre-cmd failed: goto to SJCD_S_STOP mode\n");
1164#endif
1165 sjcd_transfer_state = SJCD_S_STOP;
1166 goto ReSwitch;
1167 }
1168
1169 sjcd_mode = 0; /* unknown mode; should not be valid when failed */
1170 sjcd_send_1_cmd(SCMD_SET_MODE,
1171 SCMD_MODE_COOKED);
1172 sjcd_transfer_state = SJCD_S_READ;
1173 sjcd_transfer_timeout = 1000;
1174#if defined( SJCD_TRACE )
1175 printk
1176 ("SJCD_S_MODE: goto SJCD_S_READ mode\n");
1177#endif
1178 }
1179#if defined( SJCD_GATHER_STAT )
1180 else
1181 statistic.mode_ticks++;
1182#endif
1183 break;
1184 }
1185
1186 case SJCD_S_READ:{
1187 if (sjcd_status_valid ? 1 : sjcd_check_status()) {
1188 /*
1189 * Previous command is completed.
1190 */
1191 if (!sjcd_status_valid
1192 || sjcd_command_failed) {
1193#if defined( SJCD_TRACE )
1194 printk
1195 ("SJCD_S_READ: pre-cmd failed: goto to SJCD_S_STOP mode\n");
1196#endif
1197 sjcd_transfer_state = SJCD_S_STOP;
1198 goto ReSwitch;
1199 }
1200 if (!sjcd_media_is_available) {
1201#if defined( SJCD_TRACE )
1202 printk
1203 ("SJCD_S_READ: no disk: goto to SJCD_S_STOP mode\n");
1204#endif
1205 sjcd_transfer_state = SJCD_S_STOP;
1206 goto ReSwitch;
1207 }
1208 if (sjcd_mode != SCMD_MODE_COOKED) {
1209 /*
1210 * We seem to come from set mode. So discard one byte of result.
1211 */
1212 if (sjcd_load_response
1213 (&sjcd_mode, 1) != 0) {
1214#if defined( SJCD_TRACE )
1215 printk
1216 ("SJCD_S_READ: load failed: goto to SJCD_S_STOP mode\n");
1217#endif
1218 sjcd_transfer_state =
1219 SJCD_S_STOP;
1220 goto ReSwitch;
1221 }
1222 if (sjcd_mode != SCMD_MODE_COOKED) {
1223#if defined( SJCD_TRACE )
1224 printk
1225 ("SJCD_S_READ: mode failed: goto to SJCD_S_STOP mode\n");
1226#endif
1227 sjcd_transfer_state =
1228 SJCD_S_STOP;
1229 goto ReSwitch;
1230 }
1231 }
1232
1233 if (current_valid()) {
1234 struct sjcd_play_msf msf;
1235
1236 sjcd_next_bn = CURRENT->sector / 4;
1237 hsg2msf(sjcd_next_bn, &msf.start);
1238 msf.end.min = 0;
1239 msf.end.sec = 0;
1240 msf.end.frame = sjcd_read_count =
1241 SJCD_BUF_SIZ;
1242#if defined( SJCD_TRACE )
1243 printk
1244 ("SJCD: ---reading msf-address %x:%x:%x %x:%x:%x\n",
1245 msf.start.min, msf.start.sec,
1246 msf.start.frame, msf.end.min,
1247 msf.end.sec, msf.end.frame);
1248 printk
1249 ("sjcd_next_bn:%x buf_in:%x buf_out:%x buf_bn:%x\n",
1250 sjcd_next_bn, sjcd_buf_in,
1251 sjcd_buf_out,
1252 sjcd_buf_bn[sjcd_buf_in]);
1253#endif
1254 sjcd_send_6_cmd(SCMD_DATA_READ,
1255 &msf);
1256 sjcd_transfer_state = SJCD_S_DATA;
1257 sjcd_transfer_timeout = 500;
1258#if defined( SJCD_TRACE )
1259 printk
1260 ("SJCD_S_READ: go to SJCD_S_DATA mode\n");
1261#endif
1262 } else {
1263#if defined( SJCD_TRACE )
1264 printk
1265 ("SJCD_S_READ: nothing to read: go to SJCD_S_STOP mode\n");
1266#endif
1267 sjcd_transfer_state = SJCD_S_STOP;
1268 goto ReSwitch;
1269 }
1270 }
1271#if defined( SJCD_GATHER_STAT )
1272 else
1273 statistic.read_ticks++;
1274#endif
1275 break;
1276 }
1277
1278 case SJCD_S_DATA:{
1279 unsigned char stat;
1280
1281 sjcd_s_data:stat =
1282 inb(SJCDPORT
1283 (1));
1284#if defined( SJCD_TRACE )
1285 printk("SJCD_S_DATA: status = 0x%02x\n", stat);
1286#endif
1287 if (SJCD_STATUS_AVAILABLE(stat)) {
1288 /*
1289 * No data is waiting for us in the drive buffer. Status of operation
1290 * completion is available. Read and parse it.
1291 */
1292 sjcd_load_status();
1293
1294 if (!sjcd_status_valid
1295 || sjcd_command_failed) {
1296#if defined( SJCD_TRACE )
1297 printk
1298 ("SJCD: read block %d failed, maybe audio disk? Giving up\n",
1299 sjcd_next_bn);
1300#endif
1301 if (current_valid())
1302 end_request(CURRENT, 0);
1303#if defined( SJCD_TRACE )
1304 printk
1305 ("SJCD_S_DATA: pre-cmd failed: go to SJCD_S_STOP mode\n");
1306#endif
1307 sjcd_transfer_state = SJCD_S_STOP;
1308 goto ReSwitch;
1309 }
1310
1311 if (!sjcd_media_is_available) {
1312 printk
1313 ("SJCD_S_DATA: no disk: go to SJCD_S_STOP mode\n");
1314 sjcd_transfer_state = SJCD_S_STOP;
1315 goto ReSwitch;
1316 }
1317
1318 sjcd_transfer_state = SJCD_S_READ;
1319 goto ReSwitch;
1320 } else if (SJCD_DATA_AVAILABLE(stat)) {
1321 /*
1322 * One frame is read into device buffer. We must copy it to our memory.
1323 * Otherwise cdrom hangs up. Check to see if we have something to copy
1324 * to.
1325 */
1326 if (!current_valid()
1327 && sjcd_buf_in == sjcd_buf_out) {
1328#if defined( SJCD_TRACE )
1329 printk
1330 ("SJCD_S_DATA: nothing to read: go to SJCD_S_STOP mode\n");
1331 printk
1332 (" ... all the date would be discarded\n");
1333#endif
1334 sjcd_transfer_state = SJCD_S_STOP;
1335 goto ReSwitch;
1336 }
1337
1338 /*
1339 * Everything seems to be OK. Just read the frame and recalculate
1340 * indices.
1341 */
1342 sjcd_buf_bn[sjcd_buf_in] = -1; /* ??? */
1343 insb(SJCDPORT(2),
1344 sjcd_buf + 2048 * sjcd_buf_in, 2048);
1345#if defined( SJCD_TRACE )
1346 printk
1347 ("SJCD_S_DATA: next_bn=%d, buf_in=%d, buf_out=%d, buf_bn=%d\n",
1348 sjcd_next_bn, sjcd_buf_in,
1349 sjcd_buf_out,
1350 sjcd_buf_bn[sjcd_buf_in]);
1351#endif
1352 sjcd_buf_bn[sjcd_buf_in] = sjcd_next_bn++;
1353 if (sjcd_buf_out == -1)
1354 sjcd_buf_out = sjcd_buf_in;
1355 if (++sjcd_buf_in == SJCD_BUF_SIZ)
1356 sjcd_buf_in = 0;
1357
1358 /*
1359 * Only one frame is ready at time. So we should turn over to wait for
1360 * another frame. If we need that, of course.
1361 */
1362 if (--sjcd_read_count == 0) {
1363 /*
1364 * OK, request seems to be precessed. Continue transferring...
1365 */
1366 if (!sjcd_transfer_is_active) {
1367 while (current_valid()) {
1368 /*
1369 * Continue transferring.
1370 */
1371 sjcd_transfer();
1372 if (CURRENT->
1373 nr_sectors ==
1374 0)
1375 end_request
1376 (CURRENT, 1);
1377 else
1378 break;
1379 }
1380 }
1381 if (current_valid() &&
1382 (CURRENT->sector / 4 <
1383 sjcd_next_bn
1384 || CURRENT->sector / 4 >
1385 sjcd_next_bn +
1386 SJCD_BUF_SIZ)) {
1387#if defined( SJCD_TRACE )
1388 printk
1389 ("SJCD_S_DATA: can't read: go to SJCD_S_STOP mode\n");
1390#endif
1391 sjcd_transfer_state =
1392 SJCD_S_STOP;
1393 goto ReSwitch;
1394 }
1395 }
1396 /*
1397 * Now we should turn around rather than wait for while.
1398 */
1399 goto sjcd_s_data;
1400 }
1401#if defined( SJCD_GATHER_STAT )
1402 else
1403 statistic.data_ticks++;
1404#endif
1405 break;
1406 }
1407
1408 case SJCD_S_STOP:{
1409 sjcd_read_count = 0;
1410 sjcd_send_cmd(SCMD_STOP);
1411 sjcd_transfer_state = SJCD_S_STOPPING;
1412 sjcd_transfer_timeout = 500;
1413#if defined( SJCD_GATHER_STAT )
1414 statistic.stop_ticks++;
1415#endif
1416 break;
1417 }
1418
1419 case SJCD_S_STOPPING:{
1420 unsigned char stat;
1421
1422 stat = inb(SJCDPORT(1));
1423#if defined( SJCD_TRACE )
1424 printk("SJCD_S_STOP: status = 0x%02x\n", stat);
1425#endif
1426 if (SJCD_DATA_AVAILABLE(stat)) {
1427 int i;
1428#if defined( SJCD_TRACE )
1429 printk("SJCD_S_STOP: discard data\n");
1430#endif
1431 /*
1432 * Discard all the data from the pipe. Foolish method.
1433 */
1434 for (i = 2048; i--;
1435 (void) inb(SJCDPORT(2)));
1436 sjcd_transfer_timeout = 500;
1437 } else if (SJCD_STATUS_AVAILABLE(stat)) {
1438 sjcd_load_status();
1439 if (sjcd_status_valid
1440 && sjcd_media_is_changed) {
1441 sjcd_toc_uptodate = 0;
1442 sjcd_invalidate_buffers();
1443 }
1444 if (current_valid()) {
1445 if (sjcd_status_valid)
1446 sjcd_transfer_state =
1447 SJCD_S_READ;
1448 else
1449 sjcd_transfer_state =
1450 SJCD_S_START;
1451 } else
1452 sjcd_transfer_state = SJCD_S_IDLE;
1453 goto ReSwitch;
1454 }
1455#if defined( SJCD_GATHER_STAT )
1456 else
1457 statistic.stopping_ticks++;
1458#endif
1459 break;
1460 }
1461
1462 default:
1463 printk("SJCD: poll: invalid state %d\n",
1464 sjcd_transfer_state);
1465 return;
1466 }
1467
1468 if (--sjcd_transfer_timeout == 0) {
1469 printk("SJCD: timeout in state %d\n", sjcd_transfer_state);
1470 while (current_valid())
1471 end_request(CURRENT, 0);
1472 sjcd_send_cmd(SCMD_STOP);
1473 sjcd_transfer_state = SJCD_S_IDLE;
1474 goto ReSwitch;
1475 }
1476
1477 /*
1478 * Get back in some time. 1 should be replaced with count variable to
1479 * avoid unnecessary testings.
1480 */
1481 SJCD_SET_TIMER(sjcd_poll, 1);
1482}
1483
1484static void do_sjcd_request(request_queue_t * q)
1485{
1486#if defined( SJCD_TRACE )
1487 printk("SJCD: do_sjcd_request(%ld+%ld)\n",
1488 CURRENT->sector, CURRENT->nr_sectors);
1489#endif
1490 sjcd_transfer_is_active = 1;
1491 while (current_valid()) {
1492 sjcd_transfer();
1493 if (CURRENT->nr_sectors == 0)
1494 end_request(CURRENT, 1);
1495 else {
1496 sjcd_buf_out = -1; /* Want to read a block not in buffer */
1497 if (sjcd_transfer_state == SJCD_S_IDLE) {
1498 if (!sjcd_toc_uptodate) {
1499 if (sjcd_update_toc() < 0) {
1500 printk
1501 ("SJCD: transfer: discard\n");
1502 while (current_valid())
1503 end_request(CURRENT, 0);
1504 break;
1505 }
1506 }
1507 sjcd_transfer_state = SJCD_S_START;
1508 SJCD_SET_TIMER(sjcd_poll, HZ / 100);
1509 }
1510 break;
1511 }
1512 }
1513 sjcd_transfer_is_active = 0;
1514#if defined( SJCD_TRACE )
1515 printk
1516 ("sjcd_next_bn:%x sjcd_buf_in:%x sjcd_buf_out:%x sjcd_buf_bn:%x\n",
1517 sjcd_next_bn, sjcd_buf_in, sjcd_buf_out,
1518 sjcd_buf_bn[sjcd_buf_in]);
1519 printk("do_sjcd_request ends\n");
1520#endif
1521}
1522
1523/*
1524 * Open the device special file. Check disk is in.
1525 */
1526static int sjcd_open(struct inode *ip, struct file *fp)
1527{
1528 /*
1529 * Check the presence of device.
1530 */
1531 if (!sjcd_present)
1532 return (-ENXIO);
1533
1534 /*
1535 * Only read operations are allowed. Really? (:-)
1536 */
1537 if (fp->f_mode & 2)
1538 return (-EROFS);
1539
1540 if (sjcd_open_count == 0) {
1541 int s, sjcd_open_tries;
1542/* We don't know that, do we? */
1543/*
1544 sjcd_audio_status = CDROM_AUDIO_NO_STATUS;
1545*/
1546 sjcd_mode = 0;
1547 sjcd_door_was_open = 0;
1548 sjcd_transfer_state = SJCD_S_IDLE;
1549 sjcd_invalidate_buffers();
1550 sjcd_status_valid = 0;
1551
1552 /*
1553 * Strict status checking.
1554 */
1555 for (sjcd_open_tries = 4; --sjcd_open_tries;) {
1556 if (!sjcd_status_valid)
1557 sjcd_get_status();
1558 if (!sjcd_status_valid) {
1559#if defined( SJCD_DIAGNOSTIC )
1560 printk
1561 ("SJCD: open: timed out when check status.\n");
1562#endif
1563 goto err_out;
1564 } else if (!sjcd_media_is_available) {
1565#if defined( SJCD_DIAGNOSTIC )
1566 printk("SJCD: open: no disk in drive\n");
1567#endif
1568 if (!sjcd_door_closed) {
1569 sjcd_door_was_open = 1;
1570#if defined( SJCD_TRACE )
1571 printk
1572 ("SJCD: open: close the tray\n");
1573#endif
1574 s = sjcd_tray_close();
1575 if (s < 0 || !sjcd_status_valid
1576 || sjcd_command_failed) {
1577#if defined( SJCD_DIAGNOSTIC )
1578 printk
1579 ("SJCD: open: tray close attempt failed\n");
1580#endif
1581 goto err_out;
1582 }
1583 continue;
1584 } else
1585 goto err_out;
1586 }
1587 break;
1588 }
1589 s = sjcd_tray_lock();
1590 if (s < 0 || !sjcd_status_valid || sjcd_command_failed) {
1591#if defined( SJCD_DIAGNOSTIC )
1592 printk("SJCD: open: tray lock attempt failed\n");
1593#endif
1594 goto err_out;
1595 }
1596#if defined( SJCD_TRACE )
1597 printk("SJCD: open: done\n");
1598#endif
1599 }
1600
1601 ++sjcd_open_count;
1602 return (0);
1603
1604 err_out:
1605 return (-EIO);
1606}
1607
1608/*
1609 * On close, we flush all sjcd blocks from the buffer cache.
1610 */
1611static int sjcd_release(struct inode *inode, struct file *file)
1612{
1613 int s;
1614
1615#if defined( SJCD_TRACE )
1616 printk("SJCD: release\n");
1617#endif
1618 if (--sjcd_open_count == 0) {
1619 sjcd_invalidate_buffers();
1620 s = sjcd_tray_unlock();
1621 if (s < 0 || !sjcd_status_valid || sjcd_command_failed) {
1622#if defined( SJCD_DIAGNOSTIC )
1623 printk
1624 ("SJCD: release: tray unlock attempt failed.\n");
1625#endif
1626 }
1627 if (sjcd_door_was_open) {
1628 s = sjcd_tray_open();
1629 if (s < 0 || !sjcd_status_valid
1630 || sjcd_command_failed) {
1631#if defined( SJCD_DIAGNOSTIC )
1632 printk
1633 ("SJCD: release: tray unload attempt failed.\n");
1634#endif
1635 }
1636 }
1637 }
1638 return 0;
1639}
1640
1641/*
1642 * A list of file operations allowed for this cdrom.
1643 */
1644static struct block_device_operations sjcd_fops = {
1645 .owner = THIS_MODULE,
1646 .open = sjcd_open,
1647 .release = sjcd_release,
1648 .ioctl = sjcd_ioctl,
1649 .media_changed = sjcd_disk_change,
1650};
1651
1652/*
1653 * Following stuff is intended for initialization of the cdrom. It
1654 * first looks for presence of device. If the device is present, it
1655 * will be reset. Then read the version of the drive and load status.
1656 * The version is two BCD-coded bytes.
1657 */
1658static struct {
1659 unsigned char major, minor;
1660} sjcd_version;
1661
1662static struct gendisk *sjcd_disk;
1663
1664/*
1665 * Test for presence of drive and initialize it. Called at boot time.
1666 * Probe cdrom, find out version and status.
1667 */
1668static int __init sjcd_init(void)
1669{
1670 int i;
1671
1672 printk(KERN_INFO
1673 "SJCD: Sanyo CDR-H94A cdrom driver version %d.%d.\n",
1674 SJCD_VERSION_MAJOR, SJCD_VERSION_MINOR);
1675
1676#if defined( SJCD_TRACE )
1677 printk("SJCD: sjcd=0x%x: ", sjcd_base);
1678#endif
1679
1680 if (register_blkdev(MAJOR_NR, "sjcd"))
1681 return -EIO;
1682
1683 sjcd_queue = blk_init_queue(do_sjcd_request, &sjcd_lock);
1684 if (!sjcd_queue)
1685 goto out0;
1686
1687 blk_queue_hardsect_size(sjcd_queue, 2048);
1688
1689 sjcd_disk = alloc_disk(1);
1690 if (!sjcd_disk) {
1691 printk(KERN_ERR "SJCD: can't allocate disk");
1692 goto out1;
1693 }
1694 sjcd_disk->major = MAJOR_NR,
1695 sjcd_disk->first_minor = 0,
1696 sjcd_disk->fops = &sjcd_fops,
1697 sprintf(sjcd_disk->disk_name, "sjcd");
1698 sprintf(sjcd_disk->devfs_name, "sjcd");
1699
1700 if (!request_region(sjcd_base, 4,"sjcd")) {
1701 printk
1702 ("SJCD: Init failed, I/O port (%X) is already in use\n",
1703 sjcd_base);
1704 goto out2;
1705 }
1706
1707 /*
1708 * Check for card. Since we are booting now, we can't use standard
1709 * wait algorithm.
1710 */
1711 printk(KERN_INFO "SJCD: Resetting: ");
1712 sjcd_send_cmd(SCMD_RESET);
1713 for (i = 1000; i > 0 && !sjcd_status_valid; --i) {
1714 unsigned long timer;
1715
1716 /*
1717 * Wait 10ms approx.
1718 */
1719 for (timer = jiffies; time_before_eq(jiffies, timer););
1720 if ((i % 100) == 0)
1721 printk(".");
1722 (void) sjcd_check_status();
1723 }
1724 if (i == 0 || sjcd_command_failed) {
1725 printk(" reset failed, no drive found.\n");
1726 goto out3;
1727 } else
1728 printk("\n");
1729
1730 /*
1731 * Get and print out cdrom version.
1732 */
1733 printk(KERN_INFO "SJCD: Getting version: ");
1734 sjcd_send_cmd(SCMD_GET_VERSION);
1735 for (i = 1000; i > 0 && !sjcd_status_valid; --i) {
1736 unsigned long timer;
1737
1738 /*
1739 * Wait 10ms approx.
1740 */
1741 for (timer = jiffies; time_before_eq(jiffies, timer););
1742 if ((i % 100) == 0)
1743 printk(".");
1744 (void) sjcd_check_status();
1745 }
1746 if (i == 0 || sjcd_command_failed) {
1747 printk(" get version failed, no drive found.\n");
1748 goto out3;
1749 }
1750
1751 if (sjcd_load_response(&sjcd_version, sizeof(sjcd_version)) == 0) {
1752 printk(" %1x.%02x\n", (int) sjcd_version.major,
1753 (int) sjcd_version.minor);
1754 } else {
1755 printk(" read version failed, no drive found.\n");
1756 goto out3;
1757 }
1758
1759 /*
1760 * Check and print out the tray state. (if it is needed?).
1761 */
1762 if (!sjcd_status_valid) {
1763 printk(KERN_INFO "SJCD: Getting status: ");
1764 sjcd_send_cmd(SCMD_GET_STATUS);
1765 for (i = 1000; i > 0 && !sjcd_status_valid; --i) {
1766 unsigned long timer;
1767
1768 /*
1769 * Wait 10ms approx.
1770 */
1771 for (timer = jiffies;
1772 time_before_eq(jiffies, timer););
1773 if ((i % 100) == 0)
1774 printk(".");
1775 (void) sjcd_check_status();
1776 }
1777 if (i == 0 || sjcd_command_failed) {
1778 printk(" get status failed, no drive found.\n");
1779 goto out3;
1780 } else
1781 printk("\n");
1782 }
1783
1784 printk(KERN_INFO "SJCD: Status: port=0x%x.\n", sjcd_base);
1785 sjcd_disk->queue = sjcd_queue;
1786 add_disk(sjcd_disk);
1787
1788 sjcd_present++;
1789 return (0);
1790out3:
1791 release_region(sjcd_base, 4);
1792out2:
1793 put_disk(sjcd_disk);
1794out1:
1795 blk_cleanup_queue(sjcd_queue);
1796out0:
1797 if ((unregister_blkdev(MAJOR_NR, "sjcd") == -EINVAL))
1798 printk("SJCD: cannot unregister device.\n");
1799 return (-EIO);
1800}
1801
1802static void __exit sjcd_exit(void)
1803{
1804 del_gendisk(sjcd_disk);
1805 put_disk(sjcd_disk);
1806 release_region(sjcd_base, 4);
1807 blk_cleanup_queue(sjcd_queue);
1808 if ((unregister_blkdev(MAJOR_NR, "sjcd") == -EINVAL))
1809 printk("SJCD: cannot unregister device.\n");
1810 printk(KERN_INFO "SJCD: module: removed.\n");
1811}
1812
1813module_init(sjcd_init);
1814module_exit(sjcd_exit);
1815
1816MODULE_LICENSE("GPL");
1817MODULE_ALIAS_BLOCKDEV_MAJOR(SANYO_CDROM_MAJOR);
diff --git a/drivers/cdrom/sjcd.h b/drivers/cdrom/sjcd.h
new file mode 100644
index 000000000000..0aa5e714659d
--- /dev/null
+++ b/drivers/cdrom/sjcd.h
@@ -0,0 +1,181 @@
1/*
2 * Definitions for a Sanyo CD-ROM interface.
3 *
4 * Copyright (C) 1995 Vadim V. Model
5 * model@cecmow.enet.dec.com
6 * vadim@rbrf.msk.su
7 * vadim@ipsun.ras.ru
8 * Eric van der Maarel
9 * H.T.M.v.d.Maarel@marin.nl
10 *
11 * This information is based on mcd.c from M. Harriss and sjcd102.lst from
12 * E. Moenkeberg.
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 */
28
29#ifndef __SJCD_H__
30#define __SJCD_H__
31
32/*
33 * Change this to set the I/O port address as default. More flexibility
34 * come with setup implementation.
35 */
36#define SJCD_BASE_ADDR 0x340
37
38/*
39 * Change this to set the irq as default. Really SANYO do not use interrupts
40 * at all.
41 */
42#define SJCD_INTR_NR 0
43
44/*
45 * Change this to set the dma as default value. really SANYO does not use
46 * direct memory access at all.
47 */
48#define SJCD_DMA_NR 0
49
50/*
51 * Macros which allow us to find out the status of the drive.
52 */
53#define SJCD_STATUS_AVAILABLE( x ) (((x)&0x02)==0)
54#define SJCD_DATA_AVAILABLE( x ) (((x)&0x01)==0)
55
56/*
57 * Port access macro. Three ports are available: S-data port (command port),
58 * status port (read only) and D-data port (read only).
59 */
60#define SJCDPORT( x ) ( sjcd_base + ( x ) )
61#define SJCD_STATUS_PORT SJCDPORT( 1 )
62#define SJCD_S_DATA_PORT SJCDPORT( 0 )
63#define SJCD_COMMAND_PORT SJCDPORT( 0 )
64#define SJCD_D_DATA_PORT SJCDPORT( 2 )
65
66/*
67 * Drive info bits. Drive info available as first (mandatory) byte of
68 * command completion status.
69 */
70#define SST_NOT_READY 0x10 /* no disk in the drive (???) */
71#define SST_MEDIA_CHANGED 0x20 /* disk is changed */
72#define SST_DOOR_OPENED 0x40 /* door is open */
73
74/* commands */
75
76#define SCMD_EJECT_TRAY 0xD0 /* eject tray if not locked */
77#define SCMD_LOCK_TRAY 0xD2 /* lock tray when in */
78#define SCMD_UNLOCK_TRAY 0xD4 /* unlock tray when in */
79#define SCMD_CLOSE_TRAY 0xD6 /* load tray in */
80
81#define SCMD_RESET 0xFA /* soft reset */
82#define SCMD_GET_STATUS 0x80
83#define SCMD_GET_VERSION 0xCC
84
85#define SCMD_DATA_READ 0xA0 /* are the same, depend on mode&args */
86#define SCMD_SEEK 0xA0
87#define SCMD_PLAY 0xA0
88
89#define SCMD_GET_QINFO 0xA8
90
91#define SCMD_SET_MODE 0xC4
92#define SCMD_MODE_PLAY 0xE0
93#define SCMD_MODE_COOKED (0xF8 & ~0x20)
94#define SCMD_MODE_RAW 0xF9
95#define SCMD_MODE_x20_BIT 0x20 /* What is it for ? */
96
97#define SCMD_SET_VOLUME 0xAE
98#define SCMD_PAUSE 0xE0
99#define SCMD_STOP 0xE0
100
101#define SCMD_GET_DISK_INFO 0xAA
102
103/*
104 * Some standard arguments for SCMD_GET_DISK_INFO.
105 */
106#define SCMD_GET_1_TRACK 0xA0 /* get the first track information */
107#define SCMD_GET_L_TRACK 0xA1 /* get the last track information */
108#define SCMD_GET_D_SIZE 0xA2 /* get the whole disk information */
109
110/*
111 * Borrowed from hd.c. Allows to optimize multiple port read commands.
112 */
113#define S_READ_DATA( port, buf, nr ) insb( port, buf, nr )
114
115/*
116 * We assume that there are no audio disks with TOC length more than this
117 * number (I personally have never seen disks with more than 20 fragments).
118 */
119#define SJCD_MAX_TRACKS 100
120
121struct msf {
122 unsigned char min;
123 unsigned char sec;
124 unsigned char frame;
125};
126
127struct sjcd_hw_disk_info {
128 unsigned char track_control;
129 unsigned char track_no;
130 unsigned char x, y, z;
131 union {
132 unsigned char track_no;
133 struct msf track_msf;
134 } un;
135};
136
137struct sjcd_hw_qinfo {
138 unsigned char track_control;
139 unsigned char track_no;
140 unsigned char x;
141 struct msf rel;
142 struct msf abs;
143};
144
145struct sjcd_play_msf {
146 struct msf start;
147 struct msf end;
148};
149
150struct sjcd_disk_info {
151 unsigned char first;
152 unsigned char last;
153 struct msf disk_length;
154 struct msf first_track;
155};
156
157struct sjcd_toc {
158 unsigned char ctrl_addr;
159 unsigned char track;
160 unsigned char point_index;
161 struct msf track_time;
162 struct msf disk_time;
163};
164
165#if defined( SJCD_GATHER_STAT )
166
167struct sjcd_stat {
168 int ticks;
169 int tticks[ 8 ];
170 int idle_ticks;
171 int start_ticks;
172 int mode_ticks;
173 int read_ticks;
174 int data_ticks;
175 int stop_ticks;
176 int stopping_ticks;
177};
178
179#endif
180
181#endif
diff --git a/drivers/cdrom/sonycd535.c b/drivers/cdrom/sonycd535.c
new file mode 100644
index 000000000000..f4be7bfd6675
--- /dev/null
+++ b/drivers/cdrom/sonycd535.c
@@ -0,0 +1,1692 @@
1/*
2 * Sony CDU-535 interface device driver
3 *
4 * This is a modified version of the CDU-31A device driver (see below).
5 * Changes were made using documentation for the CDU-531 (which Sony
6 * assures me is very similar to the 535) and partial disassembly of the
7 * DOS driver. I used Minyard's driver and replaced the CDU-31A
8 * commands with the CDU-531 commands. This was complicated by a different
9 * interface protocol with the drive. The driver is still polled.
10 *
11 * Data transfer rate is about 110 Kb/sec, theoretical maximum is 150 Kb/sec.
12 * I tried polling without the sony_sleep during the data transfers but
13 * it did not speed things up any.
14 *
15 * 1993-05-23 (rgj) changed the major number to 21 to get rid of conflict
16 * with CDU-31A driver. This is the also the number from the Linux
17 * Device Driver Registry for the Sony Drive. Hope nobody else is using it.
18 *
19 * 1993-08-29 (rgj) remove the configuring of the interface board address
20 * from the top level configuration, you have to modify it in this file.
21 *
22 * 1995-01-26 Made module-capable (Joel Katz <Stimpson@Panix.COM>)
23 *
24 * 1995-05-20
25 * Modified to support CDU-510/515 series
26 * (Claudio Porfiri<C.Porfiri@nisms.tei.ericsson.se>)
27 * Fixed to report verify_area() failures
28 * (Heiko Eissfeldt <heiko@colossus.escape.de>)
29 *
30 * 1995-06-01
31 * More changes to support CDU-510/515 series
32 * (Claudio Porfiri<C.Porfiri@nisms.tei.ericsson.se>)
33 *
34 * November 1999 -- Make kernel-parameter implementation work with 2.3.x
35 * Removed init_module & cleanup_module in favor of
36 * module_init & module_exit.
37 * Torben Mathiasen <tmm@image.dk>
38 *
39 * September 2003 - Fix SMP support by removing cli/sti calls.
40 * Using spinlocks with a wait_queue instead.
41 * Felipe Damasio <felipewd@terra.com.br>
42 *
43 * Things to do:
44 * - handle errors and status better, put everything into a single word
45 * - use interrupts (code mostly there, but a big hole still missing)
46 * - handle multi-session CDs?
47 * - use DMA?
48 *
49 * Known Bugs:
50 * -
51 *
52 * Ken Pizzini (ken@halcyon.com)
53 *
54 * Original by:
55 * Ron Jeppesen (ronj.an@site007.saic.com)
56 *
57 *
58 *------------------------------------------------------------------------
59 * Sony CDROM interface device driver.
60 *
61 * Corey Minyard (minyard@wf-rch.cirr.com) (CDU-535 complaints to Ken above)
62 *
63 * Colossians 3:17
64 *
65 * The Sony interface device driver handles Sony interface CDROM
66 * drives and provides a complete block-level interface as well as an
67 * ioctl() interface compatible with the Sun (as specified in
68 * include/linux/cdrom.h). With this interface, CDROMs can be
69 * accessed and standard audio CDs can be played back normally.
70 *
71 * This interface is (unfortunately) a polled interface. This is
72 * because most Sony interfaces are set up with DMA and interrupts
73 * disables. Some (like mine) do not even have the capability to
74 * handle interrupts or DMA. For this reason you will see a bit of
75 * the following:
76 *
77 * snap = jiffies;
78 * while (jiffies-snap < SONY_JIFFIES_TIMEOUT)
79 * {
80 * if (some_condition())
81 * break;
82 * sony_sleep();
83 * }
84 * if (some_condition not met)
85 * {
86 * return an_error;
87 * }
88 *
89 * This ugly hack waits for something to happen, sleeping a little
90 * between every try. (The conditional is written so that jiffies
91 * wrap-around is handled properly.)
92 *
93 * One thing about these drives: They talk in MSF (Minute Second Frame) format.
94 * There are 75 frames a second, 60 seconds a minute, and up to 75 minutes on a
95 * disk. The funny thing is that these are sent to the drive in BCD, but the
96 * interface wants to see them in decimal. A lot of conversion goes on.
97 *
98 * Copyright (C) 1993 Corey Minyard
99 *
100 * This program is free software; you can redistribute it and/or modify
101 * it under the terms of the GNU General Public License as published by
102 * the Free Software Foundation; either version 2 of the License, or
103 * (at your option) any later version.
104 *
105 * This program is distributed in the hope that it will be useful,
106 * but WITHOUT ANY WARRANTY; without even the implied warranty of
107 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
108 * GNU General Public License for more details.
109 *
110 * You should have received a copy of the GNU General Public License
111 * along with this program; if not, write to the Free Software
112 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
113 *
114 */
115
116
117# include <linux/module.h>
118
119#include <linux/errno.h>
120#include <linux/signal.h>
121#include <linux/sched.h>
122#include <linux/timer.h>
123#include <linux/fs.h>
124#include <linux/kernel.h>
125#include <linux/interrupt.h>
126#include <linux/ioport.h>
127#include <linux/hdreg.h>
128#include <linux/genhd.h>
129#include <linux/mm.h>
130#include <linux/slab.h>
131#include <linux/init.h>
132
133#define REALLY_SLOW_IO
134#include <asm/system.h>
135#include <asm/io.h>
136#include <asm/uaccess.h>
137
138#include <linux/cdrom.h>
139
140#define MAJOR_NR CDU535_CDROM_MAJOR
141#include <linux/blkdev.h>
142
143#define sony535_cd_base_io sonycd535 /* for compatible parameter passing with "insmod" */
144#include "sonycd535.h"
145
146/*
147 * this is the base address of the interface card for the Sony CDU-535
148 * CDROM drive. If your jumpers are set for an address other than
149 * this one (the default), change the following line to the
150 * proper address.
151 */
152#ifndef CDU535_ADDRESS
153# define CDU535_ADDRESS 0x340
154#endif
155#ifndef CDU535_INTERRUPT
156# define CDU535_INTERRUPT 0
157#endif
158#ifndef CDU535_HANDLE
159# define CDU535_HANDLE "cdu535"
160#endif
161#ifndef CDU535_MESSAGE_NAME
162# define CDU535_MESSAGE_NAME "Sony CDU-535"
163#endif
164
165#define CDU535_BLOCK_SIZE 2048
166
167#ifndef MAX_SPINUP_RETRY
168# define MAX_SPINUP_RETRY 3 /* 1 is sufficient for most drives... */
169#endif
170#ifndef RETRY_FOR_BAD_STATUS
171# define RETRY_FOR_BAD_STATUS 100 /* in 10th of second */
172#endif
173
174#ifndef DEBUG
175# define DEBUG 1
176#endif
177
178/*
179 * SONY535_BUFFER_SIZE determines the size of internal buffer used
180 * by the drive. It must be at least 2K and the larger the buffer
181 * the better the transfer rate. It does however take system memory.
182 * On my system I get the following transfer rates using dd to read
183 * 10 Mb off /dev/cdrom.
184 *
185 * 8K buffer 43 Kb/sec
186 * 16K buffer 66 Kb/sec
187 * 32K buffer 91 Kb/sec
188 * 64K buffer 111 Kb/sec
189 * 128K buffer 123 Kb/sec
190 * 512K buffer 123 Kb/sec
191 */
192#define SONY535_BUFFER_SIZE (64*1024)
193
194/*
195 * if LOCK_DOORS is defined then the eject button is disabled while
196 * the device is open.
197 */
198#ifndef NO_LOCK_DOORS
199# define LOCK_DOORS
200#endif
201
202static int read_subcode(void);
203static void sony_get_toc(void);
204static int cdu_open(struct inode *inode, struct file *filp);
205static inline unsigned int int_to_bcd(unsigned int val);
206static unsigned int bcd_to_int(unsigned int bcd);
207static int do_sony_cmd(Byte * cmd, int nCmd, Byte status[2],
208 Byte * response, int n_response, int ignoreStatusBit7);
209
210/* The base I/O address of the Sony Interface. This is a variable (not a
211 #define) so it can be easily changed via some future ioctl() */
212static unsigned int sony535_cd_base_io = CDU535_ADDRESS;
213module_param(sony535_cd_base_io, int, 0);
214
215/*
216 * The following are I/O addresses of the various registers for the drive. The
217 * comment for the base address also applies here.
218 */
219static unsigned short select_unit_reg;
220static unsigned short result_reg;
221static unsigned short command_reg;
222static unsigned short read_status_reg;
223static unsigned short data_reg;
224
225static DEFINE_SPINLOCK(sonycd535_lock); /* queue lock */
226static struct request_queue *sonycd535_queue;
227
228static int initialized; /* Has the drive been initialized? */
229static int sony_disc_changed = 1; /* Has the disk been changed
230 since the last check? */
231static int sony_toc_read; /* Has the table of contents been
232 read? */
233static unsigned int sony_buffer_size; /* Size in bytes of the read-ahead
234 buffer. */
235static unsigned int sony_buffer_sectors; /* Size (in 2048 byte records) of
236 the read-ahead buffer. */
237static unsigned int sony_usage; /* How many processes have the
238 drive open. */
239
240static int sony_first_block = -1; /* First OS block (512 byte) in
241 the read-ahead buffer */
242static int sony_last_block = -1; /* Last OS block (512 byte) in
243 the read-ahead buffer */
244
245static struct s535_sony_toc *sony_toc; /* Points to the table of
246 contents. */
247
248static struct s535_sony_subcode *last_sony_subcode; /* Points to the last
249 subcode address read */
250static Byte **sony_buffer; /* Points to the pointers
251 to the sector buffers */
252
253static int sony_inuse; /* is the drive in use? Only one
254 open at a time allowed */
255
256/*
257 * The audio status uses the values from read subchannel data as specified
258 * in include/linux/cdrom.h.
259 */
260static int sony_audio_status = CDROM_AUDIO_NO_STATUS;
261
262/*
263 * The following are a hack for pausing and resuming audio play. The drive
264 * does not work as I would expect it, if you stop it then start it again,
265 * the drive seeks back to the beginning and starts over. This holds the
266 * position during a pause so a resume can restart it. It uses the
267 * audio status variable above to tell if it is paused.
268 * I just kept the CDU-31A driver behavior rather than using the PAUSE
269 * command on the CDU-535.
270 */
271static Byte cur_pos_msf[3];
272static Byte final_pos_msf[3];
273
274/* What IRQ is the drive using? 0 if none. */
275static int sony535_irq_used = CDU535_INTERRUPT;
276
277/* The interrupt handler will wake this queue up when it gets an interrupt. */
278static DECLARE_WAIT_QUEUE_HEAD(cdu535_irq_wait);
279
280
281/*
282 * This routine returns 1 if the disk has been changed since the last
283 * check or 0 if it hasn't. Setting flag to 0 resets the changed flag.
284 */
285static int
286cdu535_check_media_change(struct gendisk *disk)
287{
288 /* if driver is not initialized, always return 0 */
289 int retval = initialized ? sony_disc_changed : 0;
290 sony_disc_changed = 0;
291 return retval;
292}
293
294static inline void
295enable_interrupts(void)
296{
297#ifdef USE_IRQ
298 /*
299 * This code was taken from cdu31a.c; it will not
300 * directly work for the cdu535 as written...
301 */
302 curr_control_reg |= ( SONY_ATTN_INT_EN_BIT
303 | SONY_RES_RDY_INT_EN_BIT
304 | SONY_DATA_RDY_INT_EN_BIT);
305 outb(curr_control_reg, sony_cd_control_reg);
306#endif
307}
308
309static inline void
310disable_interrupts(void)
311{
312#ifdef USE_IRQ
313 /*
314 * This code was taken from cdu31a.c; it will not
315 * directly work for the cdu535 as written...
316 */
317 curr_control_reg &= ~(SONY_ATTN_INT_EN_BIT
318 | SONY_RES_RDY_INT_EN_BIT
319 | SONY_DATA_RDY_INT_EN_BIT);
320 outb(curr_control_reg, sony_cd_control_reg);
321#endif
322}
323
324static irqreturn_t
325cdu535_interrupt(int irq, void *dev_id, struct pt_regs *regs)
326{
327 disable_interrupts();
328 if (waitqueue_active(&cdu535_irq_wait)) {
329 wake_up(&cdu535_irq_wait);
330 return IRQ_HANDLED;
331 }
332 printk(CDU535_MESSAGE_NAME
333 ": Got an interrupt but nothing was waiting\n");
334 return IRQ_NONE;
335}
336
337
338/*
339 * Wait a little while.
340 */
341static inline void
342sony_sleep(void)
343{
344 if (sony535_irq_used <= 0) { /* poll */
345 yield();
346 } else { /* Interrupt driven */
347 DEFINE_WAIT(wait);
348
349 spin_lock_irq(&sonycd535_lock);
350 enable_interrupts();
351 prepare_to_wait(&cdu535_irq_wait, &wait, TASK_INTERRUPTIBLE);
352 spin_unlock_irq(&sonycd535_lock);
353 schedule();
354 finish_wait(&cdu535_irq_wait, &wait);
355 }
356}
357
358/*------------------start of SONY CDU535 very specific ---------------------*/
359
360/****************************************************************************
361 * void select_unit( int unit_no )
362 *
363 * Select the specified unit (0-3) so that subsequent commands reference it
364 ****************************************************************************/
365static void
366select_unit(int unit_no)
367{
368 unsigned int select_mask = ~(1 << unit_no);
369 outb(select_mask, select_unit_reg);
370}
371
372/***************************************************************************
373 * int read_result_reg( Byte *data_ptr )
374 *
375 * Read a result byte from the Sony CDU controller, store in location pointed
376 * to by data_ptr. Return zero on success, TIME_OUT if we did not receive
377 * data.
378 ***************************************************************************/
379static int
380read_result_reg(Byte *data_ptr)
381{
382 unsigned long snap;
383 int read_status;
384
385 snap = jiffies;
386 while (jiffies-snap < SONY_JIFFIES_TIMEOUT) {
387 read_status = inb(read_status_reg);
388 if ((read_status & SONY535_RESULT_NOT_READY_BIT) == 0) {
389#if DEBUG > 1
390 printk(CDU535_MESSAGE_NAME
391 ": read_result_reg(): readStatReg = 0x%x\n", read_status);
392#endif
393 *data_ptr = inb(result_reg);
394 return 0;
395 } else {
396 sony_sleep();
397 }
398 }
399 printk(CDU535_MESSAGE_NAME " read_result_reg: TIME OUT!\n");
400 return TIME_OUT;
401}
402
403/****************************************************************************
404 * int read_exec_status( Byte status[2] )
405 *
406 * Read the execution status of the last command and put into status.
407 * Handles reading second status word if available. Returns 0 on success,
408 * TIME_OUT on failure.
409 ****************************************************************************/
410static int
411read_exec_status(Byte status[2])
412{
413 status[1] = 0;
414 if (read_result_reg(&(status[0])) != 0)
415 return TIME_OUT;
416 if ((status[0] & 0x80) != 0) { /* byte two follows */
417 if (read_result_reg(&(status[1])) != 0)
418 return TIME_OUT;
419 }
420#if DEBUG > 1
421 printk(CDU535_MESSAGE_NAME ": read_exec_status: read 0x%x 0x%x\n",
422 status[0], status[1]);
423#endif
424 return 0;
425}
426
427/****************************************************************************
428 * int check_drive_status( void )
429 *
430 * Check the current drive status. Using this before executing a command
431 * takes care of the problem of unsolicited drive status-2 messages.
432 * Add a check of the audio status if we think the disk is playing.
433 ****************************************************************************/
434static int
435check_drive_status(void)
436{
437 Byte status, e_status[2];
438 int CDD, ATN;
439 Byte cmd;
440
441 select_unit(0);
442 if (sony_audio_status == CDROM_AUDIO_PLAY) { /* check status */
443 outb(SONY535_REQUEST_AUDIO_STATUS, command_reg);
444 if (read_result_reg(&status) == 0) {
445 switch (status) {
446 case 0x0:
447 break; /* play in progress */
448 case 0x1:
449 break; /* paused */
450 case 0x3: /* audio play completed */
451 case 0x5: /* play not requested */
452 sony_audio_status = CDROM_AUDIO_COMPLETED;
453 read_subcode();
454 break;
455 case 0x4: /* error during play */
456 sony_audio_status = CDROM_AUDIO_ERROR;
457 break;
458 }
459 }
460 }
461 /* now check drive status */
462 outb(SONY535_REQUEST_DRIVE_STATUS_2, command_reg);
463 if (read_result_reg(&status) != 0)
464 return TIME_OUT;
465
466#if DEBUG > 1
467 printk(CDU535_MESSAGE_NAME ": check_drive_status() got 0x%x\n", status);
468#endif
469
470 if (status == 0)
471 return 0;
472
473 ATN = status & 0xf;
474 CDD = (status >> 4) & 0xf;
475
476 switch (ATN) {
477 case 0x0:
478 break; /* go on to CDD stuff */
479 case SONY535_ATN_BUSY:
480 if (initialized)
481 printk(CDU535_MESSAGE_NAME " error: drive busy\n");
482 return CD_BUSY;
483 case SONY535_ATN_EJECT_IN_PROGRESS:
484 printk(CDU535_MESSAGE_NAME " error: eject in progress\n");
485 sony_audio_status = CDROM_AUDIO_INVALID;
486 return CD_BUSY;
487 case SONY535_ATN_RESET_OCCURRED:
488 case SONY535_ATN_DISC_CHANGED:
489 case SONY535_ATN_RESET_AND_DISC_CHANGED:
490#if DEBUG > 0
491 printk(CDU535_MESSAGE_NAME " notice: reset occurred or disc changed\n");
492#endif
493 sony_disc_changed = 1;
494 sony_toc_read = 0;
495 sony_audio_status = CDROM_AUDIO_NO_STATUS;
496 sony_first_block = -1;
497 sony_last_block = -1;
498 if (initialized) {
499 cmd = SONY535_SPIN_UP;
500 do_sony_cmd(&cmd, 1, e_status, NULL, 0, 0);
501 sony_get_toc();
502 }
503 return 0;
504 default:
505 printk(CDU535_MESSAGE_NAME " error: drive busy (ATN=0x%x)\n", ATN);
506 return CD_BUSY;
507 }
508 switch (CDD) { /* the 531 docs are not helpful in decoding this */
509 case 0x0: /* just use the values from the DOS driver */
510 case 0x2:
511 case 0xa:
512 break; /* no error */
513 case 0xc:
514 printk(CDU535_MESSAGE_NAME
515 ": check_drive_status(): CDD = 0xc! Not properly handled!\n");
516 return CD_BUSY; /* ? */
517 default:
518 return CD_BUSY;
519 }
520 return 0;
521} /* check_drive_status() */
522
523/*****************************************************************************
524 * int do_sony_cmd( Byte *cmd, int n_cmd, Byte status[2],
525 * Byte *response, int n_response, int ignore_status_bit7 )
526 *
527 * Generic routine for executing commands. The command and its parameters
528 * should be placed in the cmd[] array, number of bytes in the command is
529 * stored in nCmd. The response from the command will be stored in the
530 * response array. The number of bytes you expect back (excluding status)
531 * should be passed in n_response. Finally, some
532 * commands set bit 7 of the return status even when there is no second
533 * status byte, on these commands set ignoreStatusBit7 TRUE.
534 * If the command was sent and data received back, then we return 0,
535 * else we return TIME_OUT. You still have to check the status yourself.
536 * You should call check_drive_status() before calling this routine
537 * so that you do not lose notifications of disk changes, etc.
538 ****************************************************************************/
539static int
540do_sony_cmd(Byte * cmd, int n_cmd, Byte status[2],
541 Byte * response, int n_response, int ignore_status_bit7)
542{
543 int i;
544
545 /* write out the command */
546 for (i = 0; i < n_cmd; i++)
547 outb(cmd[i], command_reg);
548
549 /* read back the status */
550 if (read_result_reg(status) != 0)
551 return TIME_OUT;
552 if (!ignore_status_bit7 && ((status[0] & 0x80) != 0)) {
553 /* get second status byte */
554 if (read_result_reg(status + 1) != 0)
555 return TIME_OUT;
556 } else {
557 status[1] = 0;
558 }
559#if DEBUG > 2
560 printk(CDU535_MESSAGE_NAME ": do_sony_cmd %x: %x %x\n",
561 *cmd, status[0], status[1]);
562#endif
563
564 /* do not know about when I should read set of data and when not to */
565 if ((status[0] & ((ignore_status_bit7 ? 0x7f : 0xff) & 0x8f)) != 0)
566 return 0;
567
568 /* else, read in rest of data */
569 for (i = 0; 0 < n_response; n_response--, i++)
570 if (read_result_reg(response + i) != 0)
571 return TIME_OUT;
572 return 0;
573} /* do_sony_cmd() */
574
575/**************************************************************************
576 * int set_drive_mode( int mode, Byte status[2] )
577 *
578 * Set the drive mode to the specified value (mode=0 is audio, mode=e0
579 * is mode-1 CDROM
580 **************************************************************************/
581static int
582set_drive_mode(int mode, Byte status[2])
583{
584 Byte cmd_buff[2];
585 Byte ret_buff[1];
586
587 cmd_buff[0] = SONY535_SET_DRIVE_MODE;
588 cmd_buff[1] = mode;
589 return do_sony_cmd(cmd_buff, 2, status, ret_buff, 1, 1);
590}
591
592/***************************************************************************
593 * int seek_and_read_N_blocks( Byte params[], int n_blocks, Byte status[2],
594 * Byte *data_buff, int buff_size )
595 *
596 * Read n_blocks of data from the CDROM starting at position params[0:2],
597 * number of blocks in stored in params[3:5] -- both these are already
598 * int bcd format.
599 * Transfer the data into the buffer pointed at by data_buff. buff_size
600 * gives the number of bytes available in the buffer.
601 * The routine returns number of bytes read in if successful, otherwise
602 * it returns one of the standard error returns.
603 ***************************************************************************/
604static int
605seek_and_read_N_blocks(Byte params[], int n_blocks, Byte status[2],
606 Byte **buff, int buf_size)
607{
608 Byte cmd_buff[7];
609 int i;
610 int read_status;
611 unsigned long snap;
612 Byte *data_buff;
613 int sector_count = 0;
614
615 if (buf_size < CDU535_BLOCK_SIZE * n_blocks)
616 return NO_ROOM;
617
618 set_drive_mode(SONY535_CDROM_DRIVE_MODE, status);
619
620 /* send command to read the data */
621 cmd_buff[0] = SONY535_SEEK_AND_READ_N_BLOCKS_1;
622 for (i = 0; i < 6; i++)
623 cmd_buff[i + 1] = params[i];
624 for (i = 0; i < 7; i++)
625 outb(cmd_buff[i], command_reg);
626
627 /* read back the data one block at a time */
628 while (0 < n_blocks--) {
629 /* wait for data to be ready */
630 int data_valid = 0;
631 snap = jiffies;
632 while (jiffies-snap < SONY_JIFFIES_TIMEOUT) {
633 read_status = inb(read_status_reg);
634 if ((read_status & SONY535_RESULT_NOT_READY_BIT) == 0) {
635 read_exec_status(status);
636 return BAD_STATUS;
637 }
638 if ((read_status & SONY535_DATA_NOT_READY_BIT) == 0) {
639 /* data is ready, read it */
640 data_buff = buff[sector_count++];
641 for (i = 0; i < CDU535_BLOCK_SIZE; i++)
642 *data_buff++ = inb(data_reg); /* unrolling this loop does not seem to help */
643 data_valid = 1;
644 break; /* exit the timeout loop */
645 }
646 sony_sleep(); /* data not ready, sleep a while */
647 }
648 if (!data_valid)
649 return TIME_OUT; /* if we reach this stage */
650 }
651
652 /* read all the data, now read the status */
653 if ((i = read_exec_status(status)) != 0)
654 return i;
655 return CDU535_BLOCK_SIZE * sector_count;
656} /* seek_and_read_N_blocks() */
657
658/****************************************************************************
659 * int request_toc_data( Byte status[2], struct s535_sony_toc *toc )
660 *
661 * Read in the table of contents data. Converts all the bcd data
662 * into integers in the toc structure.
663 ****************************************************************************/
664static int
665request_toc_data(Byte status[2], struct s535_sony_toc *toc)
666{
667 int to_status;
668 int i, j, n_tracks, track_no;
669 int first_track_num, last_track_num;
670 Byte cmd_no = 0xb2;
671 Byte track_address_buffer[5];
672
673 /* read the fixed portion of the table of contents */
674 if ((to_status = do_sony_cmd(&cmd_no, 1, status, (Byte *) toc, 15, 1)) != 0)
675 return to_status;
676
677 /* convert the data into integers so we can use them */
678 first_track_num = bcd_to_int(toc->first_track_num);
679 last_track_num = bcd_to_int(toc->last_track_num);
680 n_tracks = last_track_num - first_track_num + 1;
681
682 /* read each of the track address descriptors */
683 for (i = 0; i < n_tracks; i++) {
684 /* read the descriptor into a temporary buffer */
685 for (j = 0; j < 5; j++) {
686 if (read_result_reg(track_address_buffer + j) != 0)
687 return TIME_OUT;
688 if (j == 1) /* need to convert from bcd */
689 track_no = bcd_to_int(track_address_buffer[j]);
690 }
691 /* copy the descriptor to proper location - sonycd.c just fills */
692 memcpy(toc->tracks + i, track_address_buffer, 5);
693 }
694 return 0;
695} /* request_toc_data() */
696
697/***************************************************************************
698 * int spin_up_drive( Byte status[2] )
699 *
700 * Spin up the drive (unless it is already spinning).
701 ***************************************************************************/
702static int
703spin_up_drive(Byte status[2])
704{
705 Byte cmd;
706
707 /* first see if the drive is already spinning */
708 cmd = SONY535_REQUEST_DRIVE_STATUS_1;
709 if (do_sony_cmd(&cmd, 1, status, NULL, 0, 0) != 0)
710 return TIME_OUT;
711 if ((status[0] & SONY535_STATUS1_NOT_SPINNING) == 0)
712 return 0; /* it's already spinning */
713
714 /* otherwise, give the spin-up command */
715 cmd = SONY535_SPIN_UP;
716 return do_sony_cmd(&cmd, 1, status, NULL, 0, 0);
717}
718
719/*--------------------end of SONY CDU535 very specific ---------------------*/
720
721/* Convert from an integer 0-99 to BCD */
722static inline unsigned int
723int_to_bcd(unsigned int val)
724{
725 int retval;
726
727 retval = (val / 10) << 4;
728 retval = retval | val % 10;
729 return retval;
730}
731
732
733/* Convert from BCD to an integer from 0-99 */
734static unsigned int
735bcd_to_int(unsigned int bcd)
736{
737 return (((bcd >> 4) & 0x0f) * 10) + (bcd & 0x0f);
738}
739
740
741/*
742 * Convert a logical sector value (like the OS would want to use for
743 * a block device) to an MSF format.
744 */
745static void
746log_to_msf(unsigned int log, Byte *msf)
747{
748 log = log + LOG_START_OFFSET;
749 msf[0] = int_to_bcd(log / 4500);
750 log = log % 4500;
751 msf[1] = int_to_bcd(log / 75);
752 msf[2] = int_to_bcd(log % 75);
753}
754
755
756/*
757 * Convert an MSF format to a logical sector.
758 */
759static unsigned int
760msf_to_log(Byte *msf)
761{
762 unsigned int log;
763
764
765 log = bcd_to_int(msf[2]);
766 log += bcd_to_int(msf[1]) * 75;
767 log += bcd_to_int(msf[0]) * 4500;
768 log = log - LOG_START_OFFSET;
769
770 return log;
771}
772
773
774/*
775 * Take in integer size value and put it into a buffer like
776 * the drive would want to see a number-of-sector value.
777 */
778static void
779size_to_buf(unsigned int size, Byte *buf)
780{
781 buf[0] = size / 65536;
782 size = size % 65536;
783 buf[1] = size / 256;
784 buf[2] = size % 256;
785}
786
787
788/*
789 * The OS calls this to perform a read or write operation to the drive.
790 * Write obviously fail. Reads to a read ahead of sony_buffer_size
791 * bytes to help speed operations. This especially helps since the OS
792 * may use 1024 byte blocks and the drive uses 2048 byte blocks. Since most
793 * data access on a CD is done sequentially, this saves a lot of operations.
794 */
795static void
796do_cdu535_request(request_queue_t * q)
797{
798 struct request *req;
799 unsigned int read_size;
800 int block;
801 int nsect;
802 int copyoff;
803 int spin_up_retry;
804 Byte params[10];
805 Byte status[2];
806 Byte cmd[2];
807
808 while (1) {
809 req = elv_next_request(q);
810 if (!req)
811 return;
812
813 block = req->sector;
814 nsect = req->nr_sectors;
815 if (!blk_fs_request(req)) {
816 end_request(req, 0);
817 continue;
818 }
819 if (rq_data_dir(req) == WRITE) {
820 end_request(req, 0);
821 continue;
822 }
823 /*
824 * If the block address is invalid or the request goes beyond
825 * the end of the media, return an error.
826 */
827 if (sony_toc->lead_out_start_lba <= (block/4)) {
828 end_request(req, 0);
829 return;
830 }
831 if (sony_toc->lead_out_start_lba <= ((block + nsect) / 4)) {
832 end_request(req, 0);
833 return;
834 }
835 while (0 < nsect) {
836 /*
837 * If the requested sector is not currently in
838 * the read-ahead buffer, it must be read in.
839 */
840 if ((block < sony_first_block) || (sony_last_block < block)) {
841 sony_first_block = (block / 4) * 4;
842 log_to_msf(block / 4, params);
843
844 /*
845 * If the full read-ahead would go beyond the end of the media, trim
846 * it back to read just till the end of the media.
847 */
848 if (sony_toc->lead_out_start_lba <= ((block / 4) + sony_buffer_sectors)) {
849 sony_last_block = (sony_toc->lead_out_start_lba * 4) - 1;
850 read_size = sony_toc->lead_out_start_lba - (block / 4);
851 } else {
852 sony_last_block = sony_first_block + (sony_buffer_sectors * 4) - 1;
853 read_size = sony_buffer_sectors;
854 }
855 size_to_buf(read_size, &params[3]);
856
857 /*
858 * Read the data. If the drive was not spinning,
859 * spin it up and try some more.
860 */
861 for (spin_up_retry=0 ;; ++spin_up_retry) {
862 /* This loop has been modified to support the Sony
863 * CDU-510/515 series, thanks to Claudio Porfiri
864 * <C.Porfiri@nisms.tei.ericsson.se>.
865 */
866 /*
867 * This part is to deal with very slow hardware. We
868 * try at most MAX_SPINUP_RETRY times to read the same
869 * block. A check for seek_and_read_N_blocks' result is
870 * performed; if the result is wrong, the CDROM's engine
871 * is restarted and the operation is tried again.
872 */
873 /*
874 * 1995-06-01: The system got problems when downloading
875 * from Slackware CDROM, the problem seems to be:
876 * seek_and_read_N_blocks returns BAD_STATUS and we
877 * should wait for a while before retrying, so a new
878 * part was added to discriminate the return value from
879 * seek_and_read_N_blocks for the various cases.
880 */
881 int readStatus = seek_and_read_N_blocks(params, read_size,
882 status, sony_buffer, (read_size * CDU535_BLOCK_SIZE));
883 if (0 <= readStatus) /* Good data; common case, placed first */
884 break;
885 if (readStatus == NO_ROOM || spin_up_retry == MAX_SPINUP_RETRY) {
886 /* give up */
887 if (readStatus == NO_ROOM)
888 printk(CDU535_MESSAGE_NAME " No room to read from CD\n");
889 else
890 printk(CDU535_MESSAGE_NAME " Read error: 0x%.2x\n",
891 status[0]);
892 sony_first_block = -1;
893 sony_last_block = -1;
894 end_request(req, 0);
895 return;
896 }
897 if (readStatus == BAD_STATUS) {
898 /* Sleep for a while, then retry */
899 set_current_state(TASK_INTERRUPTIBLE);
900 spin_unlock_irq(&sonycd535_lock);
901 schedule_timeout(RETRY_FOR_BAD_STATUS*HZ/10);
902 spin_lock_irq(&sonycd535_lock);
903 }
904#if DEBUG > 0
905 printk(CDU535_MESSAGE_NAME
906 " debug: calling spin up when reading data!\n");
907#endif
908 cmd[0] = SONY535_SPIN_UP;
909 do_sony_cmd(cmd, 1, status, NULL, 0, 0);
910 }
911 }
912 /*
913 * The data is in memory now, copy it to the buffer and advance to the
914 * next block to read.
915 */
916 copyoff = block - sony_first_block;
917 memcpy(req->buffer,
918 sony_buffer[copyoff / 4] + 512 * (copyoff % 4), 512);
919
920 block += 1;
921 nsect -= 1;
922 req->buffer += 512;
923 }
924
925 end_request(req, 1);
926 }
927}
928
929/*
930 * Read the table of contents from the drive and set sony_toc_read if
931 * successful.
932 */
933static void
934sony_get_toc(void)
935{
936 Byte status[2];
937 if (!sony_toc_read) {
938 /* do not call check_drive_status() from here since it can call this routine */
939 if (request_toc_data(status, sony_toc) < 0)
940 return;
941 sony_toc->lead_out_start_lba = msf_to_log(sony_toc->lead_out_start_msf);
942 sony_toc_read = 1;
943 }
944}
945
946
947/*
948 * Search for a specific track in the table of contents. track is
949 * passed in bcd format
950 */
951static int
952find_track(int track)
953{
954 int i;
955 int num_tracks;
956
957
958 num_tracks = bcd_to_int(sony_toc->last_track_num) -
959 bcd_to_int(sony_toc->first_track_num) + 1;
960 for (i = 0; i < num_tracks; i++) {
961 if (sony_toc->tracks[i].track == track) {
962 return i;
963 }
964 }
965
966 return -1;
967}
968
969/*
970 * Read the subcode and put it int last_sony_subcode for future use.
971 */
972static int
973read_subcode(void)
974{
975 Byte cmd = SONY535_REQUEST_SUB_Q_DATA;
976 Byte status[2];
977 int dsc_status;
978
979 if (check_drive_status() != 0)
980 return -EIO;
981
982 if ((dsc_status = do_sony_cmd(&cmd, 1, status, (Byte *) last_sony_subcode,
983 sizeof(struct s535_sony_subcode), 1)) != 0) {
984 printk(CDU535_MESSAGE_NAME " error 0x%.2x, %d (read_subcode)\n",
985 status[0], dsc_status);
986 return -EIO;
987 }
988 return 0;
989}
990
991
992/*
993 * Get the subchannel info like the CDROMSUBCHNL command wants to see it. If
994 * the drive is playing, the subchannel needs to be read (since it would be
995 * changing). If the drive is paused or completed, the subcode information has
996 * already been stored, just use that. The ioctl call wants things in decimal
997 * (not BCD), so all the conversions are done.
998 */
999static int
1000sony_get_subchnl_info(void __user *arg)
1001{
1002 struct cdrom_subchnl schi;
1003
1004 /* Get attention stuff */
1005 if (check_drive_status() != 0)
1006 return -EIO;
1007
1008 sony_get_toc();
1009 if (!sony_toc_read) {
1010 return -EIO;
1011 }
1012 if (copy_from_user(&schi, arg, sizeof schi))
1013 return -EFAULT;
1014
1015 switch (sony_audio_status) {
1016 case CDROM_AUDIO_PLAY:
1017 if (read_subcode() < 0) {
1018 return -EIO;
1019 }
1020 break;
1021
1022 case CDROM_AUDIO_PAUSED:
1023 case CDROM_AUDIO_COMPLETED:
1024 break;
1025
1026 case CDROM_AUDIO_NO_STATUS:
1027 schi.cdsc_audiostatus = sony_audio_status;
1028 if (copy_to_user(arg, &schi, sizeof schi))
1029 return -EFAULT;
1030 return 0;
1031 break;
1032
1033 case CDROM_AUDIO_INVALID:
1034 case CDROM_AUDIO_ERROR:
1035 default:
1036 return -EIO;
1037 }
1038
1039 schi.cdsc_audiostatus = sony_audio_status;
1040 schi.cdsc_adr = last_sony_subcode->address;
1041 schi.cdsc_ctrl = last_sony_subcode->control;
1042 schi.cdsc_trk = bcd_to_int(last_sony_subcode->track_num);
1043 schi.cdsc_ind = bcd_to_int(last_sony_subcode->index_num);
1044 if (schi.cdsc_format == CDROM_MSF) {
1045 schi.cdsc_absaddr.msf.minute = bcd_to_int(last_sony_subcode->abs_msf[0]);
1046 schi.cdsc_absaddr.msf.second = bcd_to_int(last_sony_subcode->abs_msf[1]);
1047 schi.cdsc_absaddr.msf.frame = bcd_to_int(last_sony_subcode->abs_msf[2]);
1048
1049 schi.cdsc_reladdr.msf.minute = bcd_to_int(last_sony_subcode->rel_msf[0]);
1050 schi.cdsc_reladdr.msf.second = bcd_to_int(last_sony_subcode->rel_msf[1]);
1051 schi.cdsc_reladdr.msf.frame = bcd_to_int(last_sony_subcode->rel_msf[2]);
1052 } else if (schi.cdsc_format == CDROM_LBA) {
1053 schi.cdsc_absaddr.lba = msf_to_log(last_sony_subcode->abs_msf);
1054 schi.cdsc_reladdr.lba = msf_to_log(last_sony_subcode->rel_msf);
1055 }
1056 return copy_to_user(arg, &schi, sizeof schi) ? -EFAULT : 0;
1057}
1058
1059
1060/*
1061 * The big ugly ioctl handler.
1062 */
1063static int
1064cdu_ioctl(struct inode *inode,
1065 struct file *file,
1066 unsigned int cmd,
1067 unsigned long arg)
1068{
1069 Byte status[2];
1070 Byte cmd_buff[10], params[10];
1071 int i;
1072 int dsc_status;
1073 void __user *argp = (void __user *)arg;
1074
1075 if (check_drive_status() != 0)
1076 return -EIO;
1077
1078 switch (cmd) {
1079 case CDROMSTART: /* Spin up the drive */
1080 if (spin_up_drive(status) < 0) {
1081 printk(CDU535_MESSAGE_NAME " error 0x%.2x (CDROMSTART)\n",
1082 status[0]);
1083 return -EIO;
1084 }
1085 return 0;
1086 break;
1087
1088 case CDROMSTOP: /* Spin down the drive */
1089 cmd_buff[0] = SONY535_HOLD;
1090 do_sony_cmd(cmd_buff, 1, status, NULL, 0, 0);
1091
1092 /*
1093 * Spin the drive down, ignoring the error if the disk was
1094 * already not spinning.
1095 */
1096 sony_audio_status = CDROM_AUDIO_NO_STATUS;
1097 cmd_buff[0] = SONY535_SPIN_DOWN;
1098 dsc_status = do_sony_cmd(cmd_buff, 1, status, NULL, 0, 0);
1099 if (((dsc_status < 0) && (dsc_status != BAD_STATUS)) ||
1100 ((status[0] & ~(SONY535_STATUS1_NOT_SPINNING)) != 0)) {
1101 printk(CDU535_MESSAGE_NAME " error 0x%.2x (CDROMSTOP)\n",
1102 status[0]);
1103 return -EIO;
1104 }
1105 return 0;
1106 break;
1107
1108 case CDROMPAUSE: /* Pause the drive */
1109 cmd_buff[0] = SONY535_HOLD; /* CDU-31 driver uses AUDIO_STOP, not pause */
1110 if (do_sony_cmd(cmd_buff, 1, status, NULL, 0, 0) != 0) {
1111 printk(CDU535_MESSAGE_NAME " error 0x%.2x (CDROMPAUSE)\n",
1112 status[0]);
1113 return -EIO;
1114 }
1115 /* Get the current position and save it for resuming */
1116 if (read_subcode() < 0) {
1117 return -EIO;
1118 }
1119 cur_pos_msf[0] = last_sony_subcode->abs_msf[0];
1120 cur_pos_msf[1] = last_sony_subcode->abs_msf[1];
1121 cur_pos_msf[2] = last_sony_subcode->abs_msf[2];
1122 sony_audio_status = CDROM_AUDIO_PAUSED;
1123 return 0;
1124 break;
1125
1126 case CDROMRESUME: /* Start the drive after being paused */
1127 set_drive_mode(SONY535_AUDIO_DRIVE_MODE, status);
1128
1129 if (sony_audio_status != CDROM_AUDIO_PAUSED) {
1130 return -EINVAL;
1131 }
1132 spin_up_drive(status);
1133
1134 /* Start the drive at the saved position. */
1135 cmd_buff[0] = SONY535_PLAY_AUDIO;
1136 cmd_buff[1] = 0; /* play back starting at this address */
1137 cmd_buff[2] = cur_pos_msf[0];
1138 cmd_buff[3] = cur_pos_msf[1];
1139 cmd_buff[4] = cur_pos_msf[2];
1140 cmd_buff[5] = SONY535_PLAY_AUDIO;
1141 cmd_buff[6] = 2; /* set ending address */
1142 cmd_buff[7] = final_pos_msf[0];
1143 cmd_buff[8] = final_pos_msf[1];
1144 cmd_buff[9] = final_pos_msf[2];
1145 if ((do_sony_cmd(cmd_buff, 5, status, NULL, 0, 0) != 0) ||
1146 (do_sony_cmd(cmd_buff + 5, 5, status, NULL, 0, 0) != 0)) {
1147 printk(CDU535_MESSAGE_NAME " error 0x%.2x (CDROMRESUME)\n",
1148 status[0]);
1149 return -EIO;
1150 }
1151 sony_audio_status = CDROM_AUDIO_PLAY;
1152 return 0;
1153 break;
1154
1155 case CDROMPLAYMSF: /* Play starting at the given MSF address. */
1156 if (copy_from_user(params, argp, 6))
1157 return -EFAULT;
1158 spin_up_drive(status);
1159 set_drive_mode(SONY535_AUDIO_DRIVE_MODE, status);
1160
1161 /* The parameters are given in int, must be converted */
1162 for (i = 0; i < 3; i++) {
1163 cmd_buff[2 + i] = int_to_bcd(params[i]);
1164 cmd_buff[7 + i] = int_to_bcd(params[i + 3]);
1165 }
1166 cmd_buff[0] = SONY535_PLAY_AUDIO;
1167 cmd_buff[1] = 0; /* play back starting at this address */
1168 /* cmd_buff[2-4] are filled in for loop above */
1169 cmd_buff[5] = SONY535_PLAY_AUDIO;
1170 cmd_buff[6] = 2; /* set ending address */
1171 /* cmd_buff[7-9] are filled in for loop above */
1172 if ((do_sony_cmd(cmd_buff, 5, status, NULL, 0, 0) != 0) ||
1173 (do_sony_cmd(cmd_buff + 5, 5, status, NULL, 0, 0) != 0)) {
1174 printk(CDU535_MESSAGE_NAME " error 0x%.2x (CDROMPLAYMSF)\n",
1175 status[0]);
1176 return -EIO;
1177 }
1178 /* Save the final position for pauses and resumes */
1179 final_pos_msf[0] = cmd_buff[7];
1180 final_pos_msf[1] = cmd_buff[8];
1181 final_pos_msf[2] = cmd_buff[9];
1182 sony_audio_status = CDROM_AUDIO_PLAY;
1183 return 0;
1184 break;
1185
1186 case CDROMREADTOCHDR: /* Read the table of contents header */
1187 {
1188 struct cdrom_tochdr __user *hdr = argp;
1189 struct cdrom_tochdr loc_hdr;
1190
1191 sony_get_toc();
1192 if (!sony_toc_read)
1193 return -EIO;
1194 loc_hdr.cdth_trk0 = bcd_to_int(sony_toc->first_track_num);
1195 loc_hdr.cdth_trk1 = bcd_to_int(sony_toc->last_track_num);
1196 if (copy_to_user(hdr, &loc_hdr, sizeof *hdr))
1197 return -EFAULT;
1198 }
1199 return 0;
1200 break;
1201
1202 case CDROMREADTOCENTRY: /* Read a given table of contents entry */
1203 {
1204 struct cdrom_tocentry __user *entry = argp;
1205 struct cdrom_tocentry loc_entry;
1206 int track_idx;
1207 Byte *msf_val = NULL;
1208
1209 sony_get_toc();
1210 if (!sony_toc_read) {
1211 return -EIO;
1212 }
1213
1214 if (copy_from_user(&loc_entry, entry, sizeof loc_entry))
1215 return -EFAULT;
1216
1217 /* Lead out is handled separately since it is special. */
1218 if (loc_entry.cdte_track == CDROM_LEADOUT) {
1219 loc_entry.cdte_adr = 0 /*sony_toc->address2 */ ;
1220 loc_entry.cdte_ctrl = sony_toc->control2;
1221 msf_val = sony_toc->lead_out_start_msf;
1222 } else {
1223 track_idx = find_track(int_to_bcd(loc_entry.cdte_track));
1224 if (track_idx < 0)
1225 return -EINVAL;
1226 loc_entry.cdte_adr = 0 /*sony_toc->tracks[track_idx].address */ ;
1227 loc_entry.cdte_ctrl = sony_toc->tracks[track_idx].control;
1228 msf_val = sony_toc->tracks[track_idx].track_start_msf;
1229 }
1230
1231 /* Logical buffer address or MSF format requested? */
1232 if (loc_entry.cdte_format == CDROM_LBA) {
1233 loc_entry.cdte_addr.lba = msf_to_log(msf_val);
1234 } else if (loc_entry.cdte_format == CDROM_MSF) {
1235 loc_entry.cdte_addr.msf.minute = bcd_to_int(*msf_val);
1236 loc_entry.cdte_addr.msf.second = bcd_to_int(*(msf_val + 1));
1237 loc_entry.cdte_addr.msf.frame = bcd_to_int(*(msf_val + 2));
1238 }
1239 if (copy_to_user(entry, &loc_entry, sizeof *entry))
1240 return -EFAULT;
1241 }
1242 return 0;
1243 break;
1244
1245 case CDROMPLAYTRKIND: /* Play a track. This currently ignores index. */
1246 {
1247 struct cdrom_ti ti;
1248 int track_idx;
1249
1250 sony_get_toc();
1251 if (!sony_toc_read)
1252 return -EIO;
1253
1254 if (copy_from_user(&ti, argp, sizeof ti))
1255 return -EFAULT;
1256 if ((ti.cdti_trk0 < sony_toc->first_track_num)
1257 || (sony_toc->last_track_num < ti.cdti_trk0)
1258 || (ti.cdti_trk1 < ti.cdti_trk0)) {
1259 return -EINVAL;
1260 }
1261 track_idx = find_track(int_to_bcd(ti.cdti_trk0));
1262 if (track_idx < 0)
1263 return -EINVAL;
1264 params[1] = sony_toc->tracks[track_idx].track_start_msf[0];
1265 params[2] = sony_toc->tracks[track_idx].track_start_msf[1];
1266 params[3] = sony_toc->tracks[track_idx].track_start_msf[2];
1267 /*
1268 * If we want to stop after the last track, use the lead-out
1269 * MSF to do that.
1270 */
1271 if (bcd_to_int(sony_toc->last_track_num) <= ti.cdti_trk1) {
1272 log_to_msf(msf_to_log(sony_toc->lead_out_start_msf) - 1,
1273 &(params[4]));
1274 } else {
1275 track_idx = find_track(int_to_bcd(ti.cdti_trk1 + 1));
1276 if (track_idx < 0)
1277 return -EINVAL;
1278 log_to_msf(msf_to_log(sony_toc->tracks[track_idx].track_start_msf) - 1,
1279 &(params[4]));
1280 }
1281 params[0] = 0x03;
1282
1283 spin_up_drive(status);
1284
1285 set_drive_mode(SONY535_AUDIO_DRIVE_MODE, status);
1286
1287 /* Start the drive at the saved position. */
1288 cmd_buff[0] = SONY535_PLAY_AUDIO;
1289 cmd_buff[1] = 0; /* play back starting at this address */
1290 cmd_buff[2] = params[1];
1291 cmd_buff[3] = params[2];
1292 cmd_buff[4] = params[3];
1293 cmd_buff[5] = SONY535_PLAY_AUDIO;
1294 cmd_buff[6] = 2; /* set ending address */
1295 cmd_buff[7] = params[4];
1296 cmd_buff[8] = params[5];
1297 cmd_buff[9] = params[6];
1298 if ((do_sony_cmd(cmd_buff, 5, status, NULL, 0, 0) != 0) ||
1299 (do_sony_cmd(cmd_buff + 5, 5, status, NULL, 0, 0) != 0)) {
1300 printk(CDU535_MESSAGE_NAME " error 0x%.2x (CDROMPLAYTRKIND)\n",
1301 status[0]);
1302 printk("... Params: %x %x %x %x %x %x %x\n",
1303 params[0], params[1], params[2],
1304 params[3], params[4], params[5], params[6]);
1305 return -EIO;
1306 }
1307 /* Save the final position for pauses and resumes */
1308 final_pos_msf[0] = params[4];
1309 final_pos_msf[1] = params[5];
1310 final_pos_msf[2] = params[6];
1311 sony_audio_status = CDROM_AUDIO_PLAY;
1312 return 0;
1313 }
1314
1315 case CDROMSUBCHNL: /* Get subchannel info */
1316 return sony_get_subchnl_info(argp);
1317
1318 case CDROMVOLCTRL: /* Volume control. What volume does this change, anyway? */
1319 {
1320 struct cdrom_volctrl volctrl;
1321
1322 if (copy_from_user(&volctrl, argp, sizeof volctrl))
1323 return -EFAULT;
1324 cmd_buff[0] = SONY535_SET_VOLUME;
1325 cmd_buff[1] = volctrl.channel0;
1326 cmd_buff[2] = volctrl.channel1;
1327 if (do_sony_cmd(cmd_buff, 3, status, NULL, 0, 0) != 0) {
1328 printk(CDU535_MESSAGE_NAME " error 0x%.2x (CDROMVOLCTRL)\n",
1329 status[0]);
1330 return -EIO;
1331 }
1332 }
1333 return 0;
1334
1335 case CDROMEJECT: /* Eject the drive */
1336 cmd_buff[0] = SONY535_STOP;
1337 do_sony_cmd(cmd_buff, 1, status, NULL, 0, 0);
1338 cmd_buff[0] = SONY535_SPIN_DOWN;
1339 do_sony_cmd(cmd_buff, 1, status, NULL, 0, 0);
1340
1341 sony_audio_status = CDROM_AUDIO_INVALID;
1342 cmd_buff[0] = SONY535_EJECT_CADDY;
1343 if (do_sony_cmd(cmd_buff, 1, status, NULL, 0, 0) != 0) {
1344 printk(CDU535_MESSAGE_NAME " error 0x%.2x (CDROMEJECT)\n",
1345 status[0]);
1346 return -EIO;
1347 }
1348 return 0;
1349 break;
1350
1351 default:
1352 return -EINVAL;
1353 }
1354}
1355
1356
1357/*
1358 * Open the drive for operations. Spin the drive up and read the table of
1359 * contents if these have not already been done.
1360 */
1361static int
1362cdu_open(struct inode *inode,
1363 struct file *filp)
1364{
1365 Byte status[2], cmd_buff[2];
1366
1367 if (sony_inuse)
1368 return -EBUSY;
1369 if (check_drive_status() != 0)
1370 return -EIO;
1371 sony_inuse = 1;
1372
1373 if (spin_up_drive(status) != 0) {
1374 printk(CDU535_MESSAGE_NAME " error 0x%.2x (cdu_open, spin up)\n",
1375 status[0]);
1376 sony_inuse = 0;
1377 return -EIO;
1378 }
1379 sony_get_toc();
1380 if (!sony_toc_read) {
1381 cmd_buff[0] = SONY535_SPIN_DOWN;
1382 do_sony_cmd(cmd_buff, 1, status, NULL, 0, 0);
1383 sony_inuse = 0;
1384 return -EIO;
1385 }
1386 check_disk_change(inode->i_bdev);
1387 sony_usage++;
1388
1389#ifdef LOCK_DOORS
1390 /* disable the eject button while mounted */
1391 cmd_buff[0] = SONY535_DISABLE_EJECT_BUTTON;
1392 do_sony_cmd(cmd_buff, 1, status, NULL, 0, 0);
1393#endif
1394
1395 return 0;
1396}
1397
1398
1399/*
1400 * Close the drive. Spin it down if no task is using it. The spin
1401 * down will fail if playing audio, so audio play is OK.
1402 */
1403static int
1404cdu_release(struct inode *inode,
1405 struct file *filp)
1406{
1407 Byte status[2], cmd_no;
1408
1409 sony_inuse = 0;
1410
1411 if (0 < sony_usage) {
1412 sony_usage--;
1413 }
1414 if (sony_usage == 0) {
1415 check_drive_status();
1416
1417 if (sony_audio_status != CDROM_AUDIO_PLAY) {
1418 cmd_no = SONY535_SPIN_DOWN;
1419 do_sony_cmd(&cmd_no, 1, status, NULL, 0, 0);
1420 }
1421#ifdef LOCK_DOORS
1422 /* enable the eject button after umount */
1423 cmd_no = SONY535_ENABLE_EJECT_BUTTON;
1424 do_sony_cmd(&cmd_no, 1, status, NULL, 0, 0);
1425#endif
1426 }
1427 return 0;
1428}
1429
1430static struct block_device_operations cdu_fops =
1431{
1432 .owner = THIS_MODULE,
1433 .open = cdu_open,
1434 .release = cdu_release,
1435 .ioctl = cdu_ioctl,
1436 .media_changed = cdu535_check_media_change,
1437};
1438
1439static struct gendisk *cdu_disk;
1440
1441/*
1442 * Initialize the driver.
1443 */
1444static int __init sony535_init(void)
1445{
1446 struct s535_sony_drive_config drive_config;
1447 Byte cmd_buff[3];
1448 Byte ret_buff[2];
1449 Byte status[2];
1450 unsigned long snap;
1451 int got_result = 0;
1452 int tmp_irq;
1453 int i;
1454 int err;
1455
1456 /* Setting the base I/O address to 0 will disable it. */
1457 if ((sony535_cd_base_io == 0xffff)||(sony535_cd_base_io == 0))
1458 return 0;
1459
1460 /* Set up all the register locations */
1461 result_reg = sony535_cd_base_io;
1462 command_reg = sony535_cd_base_io;
1463 data_reg = sony535_cd_base_io + 1;
1464 read_status_reg = sony535_cd_base_io + 2;
1465 select_unit_reg = sony535_cd_base_io + 3;
1466
1467#ifndef USE_IRQ
1468 sony535_irq_used = 0; /* polling only until this is ready... */
1469#endif
1470 /* we need to poll until things get initialized */
1471 tmp_irq = sony535_irq_used;
1472 sony535_irq_used = 0;
1473
1474#if DEBUG > 0
1475 printk(KERN_INFO CDU535_MESSAGE_NAME ": probing base address %03X\n",
1476 sony535_cd_base_io);
1477#endif
1478 /* look for the CD-ROM, follows the procedure in the DOS driver */
1479 inb(select_unit_reg);
1480 /* wait for 40 18 Hz ticks (reverse-engineered from DOS driver) */
1481 set_current_state(TASK_INTERRUPTIBLE);
1482 schedule_timeout((HZ+17)*40/18);
1483 inb(result_reg);
1484
1485 outb(0, read_status_reg); /* does a reset? */
1486 snap = jiffies;
1487 while (jiffies-snap < SONY_JIFFIES_TIMEOUT) {
1488 select_unit(0);
1489 if (inb(result_reg) != 0xff) {
1490 got_result = 1;
1491 break;
1492 }
1493 sony_sleep();
1494 }
1495
1496 if (!got_result || check_drive_status() == TIME_OUT)
1497 goto Enodev;
1498
1499 /* CD-ROM drive responded -- get the drive configuration */
1500 cmd_buff[0] = SONY535_INQUIRY;
1501 if (do_sony_cmd(cmd_buff, 1, status, (Byte *)&drive_config, 28, 1) != 0)
1502 goto Enodev;
1503
1504 /* was able to get the configuration,
1505 * set drive mode as rest of init
1506 */
1507#if DEBUG > 0
1508 /* 0x50 == CADDY_NOT_INSERTED | NOT_SPINNING */
1509 if ( (status[0] & 0x7f) != 0 && (status[0] & 0x7f) != 0x50 )
1510 printk(CDU535_MESSAGE_NAME
1511 "Inquiry command returned status = 0x%x\n", status[0]);
1512#endif
1513 /* now ready to use interrupts, if available */
1514 sony535_irq_used = tmp_irq;
1515
1516 /* A negative sony535_irq_used will attempt an autoirq. */
1517 if (sony535_irq_used < 0) {
1518 unsigned long irq_mask, delay;
1519
1520 irq_mask = probe_irq_on();
1521 enable_interrupts();
1522 outb(0, read_status_reg); /* does a reset? */
1523 delay = jiffies + HZ/10;
1524 while (time_before(jiffies, delay)) ;
1525
1526 sony535_irq_used = probe_irq_off(irq_mask);
1527 disable_interrupts();
1528 }
1529 if (sony535_irq_used > 0) {
1530 if (request_irq(sony535_irq_used, cdu535_interrupt,
1531 SA_INTERRUPT, CDU535_HANDLE, NULL)) {
1532 printk("Unable to grab IRQ%d for the " CDU535_MESSAGE_NAME
1533 " driver; polling instead.\n", sony535_irq_used);
1534 sony535_irq_used = 0;
1535 }
1536 }
1537 cmd_buff[0] = SONY535_SET_DRIVE_MODE;
1538 cmd_buff[1] = 0x0; /* default audio */
1539 if (do_sony_cmd(cmd_buff, 2, status, ret_buff, 1, 1) != 0)
1540 goto Enodev_irq;
1541
1542 /* set the drive mode successful, we are set! */
1543 sony_buffer_size = SONY535_BUFFER_SIZE;
1544 sony_buffer_sectors = sony_buffer_size / CDU535_BLOCK_SIZE;
1545
1546 printk(KERN_INFO CDU535_MESSAGE_NAME " I/F CDROM : %8.8s %16.16s %4.4s",
1547 drive_config.vendor_id,
1548 drive_config.product_id,
1549 drive_config.product_rev_level);
1550 printk(" base address %03X, ", sony535_cd_base_io);
1551 if (tmp_irq > 0)
1552 printk("IRQ%d, ", tmp_irq);
1553 printk("using %d byte buffer\n", sony_buffer_size);
1554
1555 if (register_blkdev(MAJOR_NR, CDU535_HANDLE)) {
1556 err = -EIO;
1557 goto out1;
1558 }
1559 sonycd535_queue = blk_init_queue(do_cdu535_request, &sonycd535_lock);
1560 if (!sonycd535_queue) {
1561 err = -ENOMEM;
1562 goto out1a;
1563 }
1564
1565 blk_queue_hardsect_size(sonycd535_queue, CDU535_BLOCK_SIZE);
1566 sony_toc = kmalloc(sizeof(struct s535_sony_toc), GFP_KERNEL);
1567 err = -ENOMEM;
1568 if (!sony_toc)
1569 goto out2;
1570 last_sony_subcode = kmalloc(sizeof(struct s535_sony_subcode), GFP_KERNEL);
1571 if (!last_sony_subcode)
1572 goto out3;
1573 sony_buffer = kmalloc(sizeof(Byte *) * sony_buffer_sectors, GFP_KERNEL);
1574 if (!sony_buffer)
1575 goto out4;
1576 for (i = 0; i < sony_buffer_sectors; i++) {
1577 sony_buffer[i] = kmalloc(CDU535_BLOCK_SIZE, GFP_KERNEL);
1578 if (!sony_buffer[i]) {
1579 while (--i>=0)
1580 kfree(sony_buffer[i]);
1581 goto out5;
1582 }
1583 }
1584 initialized = 1;
1585
1586 cdu_disk = alloc_disk(1);
1587 if (!cdu_disk)
1588 goto out6;
1589 cdu_disk->major = MAJOR_NR;
1590 cdu_disk->first_minor = 0;
1591 cdu_disk->fops = &cdu_fops;
1592 sprintf(cdu_disk->disk_name, "cdu");
1593 sprintf(cdu_disk->devfs_name, "cdu535");
1594
1595 if (!request_region(sony535_cd_base_io, 4, CDU535_HANDLE)) {
1596 printk(KERN_WARNING"sonycd535: Unable to request region 0x%x\n",
1597 sony535_cd_base_io);
1598 goto out7;
1599 }
1600 cdu_disk->queue = sonycd535_queue;
1601 add_disk(cdu_disk);
1602 return 0;
1603
1604out7:
1605 put_disk(cdu_disk);
1606out6:
1607 for (i = 0; i < sony_buffer_sectors; i++)
1608 if (sony_buffer[i])
1609 kfree(sony_buffer[i]);
1610out5:
1611 kfree(sony_buffer);
1612out4:
1613 kfree(last_sony_subcode);
1614out3:
1615 kfree(sony_toc);
1616out2:
1617 blk_cleanup_queue(sonycd535_queue);
1618out1a:
1619 unregister_blkdev(MAJOR_NR, CDU535_HANDLE);
1620out1:
1621 if (sony535_irq_used)
1622 free_irq(sony535_irq_used, NULL);
1623 return err;
1624Enodev_irq:
1625 if (sony535_irq_used)
1626 free_irq(sony535_irq_used, NULL);
1627Enodev:
1628 printk("Did not find a " CDU535_MESSAGE_NAME " drive\n");
1629 return -EIO;
1630}
1631
1632#ifndef MODULE
1633
1634/*
1635 * accept "kernel command line" parameters
1636 * (added by emoenke@gwdg.de)
1637 *
1638 * use: tell LILO:
1639 * sonycd535=0x320
1640 *
1641 * the address value has to be the existing CDROM port address.
1642 */
1643static int __init
1644sonycd535_setup(char *strings)
1645{
1646 int ints[3];
1647 (void)get_options(strings, ARRAY_SIZE(ints), ints);
1648 /* if IRQ change and default io base desired,
1649 * then call with io base of 0
1650 */
1651 if (ints[0] > 0)
1652 if (ints[1] != 0)
1653 sony535_cd_base_io = ints[1];
1654 if (ints[0] > 1)
1655 sony535_irq_used = ints[2];
1656 if ((strings != NULL) && (*strings != '\0'))
1657 printk(CDU535_MESSAGE_NAME
1658 ": Warning: Unknown interface type: %s\n", strings);
1659
1660 return 1;
1661}
1662
1663__setup("sonycd535=", sonycd535_setup);
1664
1665#endif /* MODULE */
1666
1667static void __exit
1668sony535_exit(void)
1669{
1670 int i;
1671
1672 release_region(sony535_cd_base_io, 4);
1673 for (i = 0; i < sony_buffer_sectors; i++)
1674 kfree(sony_buffer[i]);
1675 kfree(sony_buffer);
1676 kfree(last_sony_subcode);
1677 kfree(sony_toc);
1678 del_gendisk(cdu_disk);
1679 put_disk(cdu_disk);
1680 blk_cleanup_queue(sonycd535_queue);
1681 if (unregister_blkdev(MAJOR_NR, CDU535_HANDLE) == -EINVAL)
1682 printk("Uh oh, couldn't unregister " CDU535_HANDLE "\n");
1683 else
1684 printk(KERN_INFO CDU535_HANDLE " module released\n");
1685}
1686
1687module_init(sony535_init);
1688module_exit(sony535_exit);
1689
1690
1691MODULE_LICENSE("GPL");
1692MODULE_ALIAS_BLOCKDEV_MAJOR(CDU535_CDROM_MAJOR);
diff --git a/drivers/cdrom/sonycd535.h b/drivers/cdrom/sonycd535.h
new file mode 100644
index 000000000000..5dea1ef168d6
--- /dev/null
+++ b/drivers/cdrom/sonycd535.h
@@ -0,0 +1,183 @@
1#ifndef SONYCD535_H
2#define SONYCD535_H
3
4/*
5 * define all the commands recognized by the CDU-531/5
6 */
7#define SONY535_REQUEST_DRIVE_STATUS_1 (0x80)
8#define SONY535_REQUEST_SENSE (0x82)
9#define SONY535_REQUEST_DRIVE_STATUS_2 (0x84)
10#define SONY535_REQUEST_ERROR_STATUS (0x86)
11#define SONY535_REQUEST_AUDIO_STATUS (0x88)
12#define SONY535_INQUIRY (0x8a)
13
14#define SONY535_SET_INACTIVITY_TIME (0x90)
15
16#define SONY535_SEEK_AND_READ_N_BLOCKS_1 (0xa0)
17#define SONY535_SEEK_AND_READ_N_BLOCKS_2 (0xa4)
18#define SONY535_PLAY_AUDIO (0xa6)
19
20#define SONY535_REQUEST_DISC_CAPACITY (0xb0)
21#define SONY535_REQUEST_TOC_DATA (0xb2)
22#define SONY535_REQUEST_SUB_Q_DATA (0xb4)
23#define SONY535_REQUEST_ISRC (0xb6)
24#define SONY535_REQUEST_UPC_EAN (0xb8)
25
26#define SONY535_SET_DRIVE_MODE (0xc0)
27#define SONY535_REQUEST_DRIVE_MODE (0xc2)
28#define SONY535_SET_RETRY_COUNT (0xc4)
29
30#define SONY535_DIAGNOSTIC_1 (0xc6)
31#define SONY535_DIAGNOSTIC_4 (0xcc)
32#define SONY535_DIAGNOSTIC_5 (0xce)
33
34#define SONY535_EJECT_CADDY (0xd0)
35#define SONY535_DISABLE_EJECT_BUTTON (0xd2)
36#define SONY535_ENABLE_EJECT_BUTTON (0xd4)
37
38#define SONY535_HOLD (0xe0)
39#define SONY535_AUDIO_PAUSE_ON_OFF (0xe2)
40#define SONY535_SET_VOLUME (0xe8)
41
42#define SONY535_STOP (0xf0)
43#define SONY535_SPIN_UP (0xf2)
44#define SONY535_SPIN_DOWN (0xf4)
45
46#define SONY535_CLEAR_PARAMETERS (0xf6)
47#define SONY535_CLEAR_ENDING_ADDRESS (0xf8)
48
49/*
50 * define some masks
51 */
52#define SONY535_DATA_NOT_READY_BIT (0x1)
53#define SONY535_RESULT_NOT_READY_BIT (0x2)
54
55/*
56 * drive status 1
57 */
58#define SONY535_STATUS1_COMMAND_ERROR (0x1)
59#define SONY535_STATUS1_DATA_ERROR (0x2)
60#define SONY535_STATUS1_SEEK_ERROR (0x4)
61#define SONY535_STATUS1_DISC_TYPE_ERROR (0x8)
62#define SONY535_STATUS1_NOT_SPINNING (0x10)
63#define SONY535_STATUS1_EJECT_BUTTON_PRESSED (0x20)
64#define SONY535_STATUS1_CADDY_NOT_INSERTED (0x40)
65#define SONY535_STATUS1_BYTE_TWO_FOLLOWS (0x80)
66
67/*
68 * drive status 2
69 */
70#define SONY535_CDD_LOADING_ERROR (0x7)
71#define SONY535_CDD_NO_DISC (0x8)
72#define SONY535_CDD_UNLOADING_ERROR (0x9)
73#define SONY535_CDD_CADDY_NOT_INSERTED (0xd)
74#define SONY535_ATN_RESET_OCCURRED (0x2)
75#define SONY535_ATN_DISC_CHANGED (0x4)
76#define SONY535_ATN_RESET_AND_DISC_CHANGED (0x6)
77#define SONY535_ATN_EJECT_IN_PROGRESS (0xe)
78#define SONY535_ATN_BUSY (0xf)
79
80/*
81 * define some parameters
82 */
83#define SONY535_AUDIO_DRIVE_MODE (0)
84#define SONY535_CDROM_DRIVE_MODE (0xe0)
85
86#define SONY535_PLAY_OP_PLAYBACK (0)
87#define SONY535_PLAY_OP_ENTER_HOLD (1)
88#define SONY535_PLAY_OP_SET_AUDIO_ENDING_ADDR (2)
89#define SONY535_PLAY_OP_SCAN_FORWARD (3)
90#define SONY535_PLAY_OP_SCAN_BACKWARD (4)
91
92/*
93 * convert from msf format to block number
94 */
95#define SONY_BLOCK_NUMBER(m,s,f) (((m)*60L+(s))*75L+(f))
96#define SONY_BLOCK_NUMBER_MSF(x) (((x)[0]*60L+(x)[1])*75L+(x)[2])
97
98/*
99 * error return values from the doSonyCmd() routines
100 */
101#define TIME_OUT (-1)
102#define NO_CDROM (-2)
103#define BAD_STATUS (-3)
104#define CD_BUSY (-4)
105#define NOT_DATA_CD (-5)
106#define NO_ROOM (-6)
107
108#define LOG_START_OFFSET 150 /* Offset of first logical sector */
109
110#define SONY_JIFFIES_TIMEOUT (5*HZ) /* Maximum time
111 the drive will wait/try for an
112 operation */
113#define SONY_READY_RETRIES (50000) /* How many times to retry a
114 spin waiting for a register
115 to come ready */
116#define SONY535_FAST_POLLS (10000) /* how many times recheck
117 status waiting for a data
118 to become ready */
119
120typedef unsigned char Byte;
121
122/*
123 * This is the complete status returned from the drive configuration request
124 * command.
125 */
126struct s535_sony_drive_config
127{
128 char vendor_id[8];
129 char product_id[16];
130 char product_rev_level[4];
131};
132
133/* The following is returned from the request sub-q data command */
134struct s535_sony_subcode
135{
136 unsigned char address :4;
137 unsigned char control :4;
138 unsigned char track_num;
139 unsigned char index_num;
140 unsigned char rel_msf[3];
141 unsigned char abs_msf[3];
142};
143
144struct s535_sony_disc_capacity
145{
146 Byte mFirstTrack, sFirstTrack, fFirstTrack;
147 Byte mLeadOut, sLeadOut, fLeadOut;
148};
149
150/*
151 * The following is returned from the request TOC (Table Of Contents) command.
152 * (last_track_num-first_track_num+1) values are valid in tracks.
153 */
154struct s535_sony_toc
155{
156 unsigned char reserved0 :4;
157 unsigned char control0 :4;
158 unsigned char point0;
159 unsigned char first_track_num;
160 unsigned char reserved0a;
161 unsigned char reserved0b;
162 unsigned char reserved1 :4;
163 unsigned char control1 :4;
164 unsigned char point1;
165 unsigned char last_track_num;
166 unsigned char dummy1;
167 unsigned char dummy2;
168 unsigned char reserved2 :4;
169 unsigned char control2 :4;
170 unsigned char point2;
171 unsigned char lead_out_start_msf[3];
172 struct
173 {
174 unsigned char reserved :4;
175 unsigned char control :4;
176 unsigned char track;
177 unsigned char track_start_msf[3];
178 } tracks[100];
179
180 unsigned int lead_out_start_lba;
181};
182
183#endif /* SONYCD535_H */
diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c
new file mode 100644
index 000000000000..fcca26c89bbc
--- /dev/null
+++ b/drivers/cdrom/viocd.c
@@ -0,0 +1,809 @@
1/* -*- linux-c -*-
2 * drivers/cdrom/viocd.c
3 *
4 * iSeries Virtual CD Rom
5 *
6 * Authors: Dave Boutcher <boutcher@us.ibm.com>
7 * Ryan Arnold <ryanarn@us.ibm.com>
8 * Colin Devilbiss <devilbis@us.ibm.com>
9 * Stephen Rothwell <sfr@au1.ibm.com>
10 *
11 * (C) Copyright 2000-2004 IBM Corporation
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License as
15 * published by the Free Software Foundation; either version 2 of the
16 * License, or (at your option) anyu later version.
17 *
18 * This program is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 * General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software Foundation,
25 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 *
27 * This routine provides access to CD ROM drives owned and managed by an
28 * OS/400 partition running on the same box as this Linux partition.
29 *
30 * All operations are performed by sending messages back and forth to
31 * the OS/400 partition.
32 */
33
34#include <linux/major.h>
35#include <linux/blkdev.h>
36#include <linux/cdrom.h>
37#include <linux/errno.h>
38#include <linux/init.h>
39#include <linux/dma-mapping.h>
40#include <linux/module.h>
41#include <linux/completion.h>
42#include <linux/proc_fs.h>
43#include <linux/seq_file.h>
44
45#include <asm/bug.h>
46
47#include <asm/vio.h>
48#include <asm/scatterlist.h>
49#include <asm/iSeries/HvTypes.h>
50#include <asm/iSeries/HvLpEvent.h>
51#include <asm/iSeries/vio.h>
52
53#define VIOCD_DEVICE "iseries/vcd"
54#define VIOCD_DEVICE_DEVFS "iseries/vcd"
55
56#define VIOCD_VERS "1.06"
57
58#define VIOCD_KERN_WARNING KERN_WARNING "viocd: "
59#define VIOCD_KERN_INFO KERN_INFO "viocd: "
60
61struct viocdlpevent {
62 struct HvLpEvent event;
63 u32 reserved;
64 u16 version;
65 u16 sub_result;
66 u16 disk;
67 u16 flags;
68 u32 token;
69 u64 offset; /* On open, max number of disks */
70 u64 len; /* On open, size of the disk */
71 u32 block_size; /* Only set on open */
72 u32 media_size; /* Only set on open */
73};
74
75enum viocdsubtype {
76 viocdopen = 0x0001,
77 viocdclose = 0x0002,
78 viocdread = 0x0003,
79 viocdwrite = 0x0004,
80 viocdlockdoor = 0x0005,
81 viocdgetinfo = 0x0006,
82 viocdcheck = 0x0007
83};
84
85/*
86 * Should probably make this a module parameter....sigh
87 */
88#define VIOCD_MAX_CD HVMAXARCHITECTEDVIRTUALCDROMS
89
90static const struct vio_error_entry viocd_err_table[] = {
91 {0x0201, EINVAL, "Invalid Range"},
92 {0x0202, EINVAL, "Invalid Token"},
93 {0x0203, EIO, "DMA Error"},
94 {0x0204, EIO, "Use Error"},
95 {0x0205, EIO, "Release Error"},
96 {0x0206, EINVAL, "Invalid CD"},
97 {0x020C, EROFS, "Read Only Device"},
98 {0x020D, ENOMEDIUM, "Changed or Missing Volume (or Varied Off?)"},
99 {0x020E, EIO, "Optical System Error (Varied Off?)"},
100 {0x02FF, EIO, "Internal Error"},
101 {0x3010, EIO, "Changed Volume"},
102 {0xC100, EIO, "Optical System Error"},
103 {0x0000, 0, NULL},
104};
105
106/*
107 * This is the structure we use to exchange info between driver and interrupt
108 * handler
109 */
110struct viocd_waitevent {
111 struct completion com;
112 int rc;
113 u16 sub_result;
114 int changed;
115};
116
117/* this is a lookup table for the true capabilities of a device */
118struct capability_entry {
119 char *type;
120 int capability;
121};
122
123static struct capability_entry capability_table[] __initdata = {
124 { "6330", CDC_LOCK | CDC_DVD_RAM | CDC_RAM },
125 { "6331", CDC_LOCK | CDC_DVD_RAM | CDC_RAM },
126 { "6333", CDC_LOCK | CDC_DVD_RAM | CDC_RAM },
127 { "632A", CDC_LOCK | CDC_DVD_RAM | CDC_RAM },
128 { "6321", CDC_LOCK },
129 { "632B", 0 },
130 { NULL , CDC_LOCK },
131};
132
133/* These are our internal structures for keeping track of devices */
134static int viocd_numdev;
135
136struct cdrom_info {
137 char rsrcname[10];
138 char type[4];
139 char model[3];
140};
141/*
142 * This needs to be allocated since it is passed to the
143 * Hypervisor and we may be a module.
144 */
145static struct cdrom_info *viocd_unitinfo;
146static dma_addr_t unitinfo_dmaaddr;
147
148struct disk_info {
149 struct gendisk *viocd_disk;
150 struct cdrom_device_info viocd_info;
151 struct device *dev;
152};
153static struct disk_info viocd_diskinfo[VIOCD_MAX_CD];
154
155#define DEVICE_NR(di) ((di) - &viocd_diskinfo[0])
156
157static spinlock_t viocd_reqlock;
158
159#define MAX_CD_REQ 1
160
161/* procfs support */
162static int proc_viocd_show(struct seq_file *m, void *v)
163{
164 int i;
165
166 for (i = 0; i < viocd_numdev; i++) {
167 seq_printf(m, "viocd device %d is iSeries resource %10.10s"
168 "type %4.4s, model %3.3s\n",
169 i, viocd_unitinfo[i].rsrcname,
170 viocd_unitinfo[i].type,
171 viocd_unitinfo[i].model);
172 }
173 return 0;
174}
175
176static int proc_viocd_open(struct inode *inode, struct file *file)
177{
178 return single_open(file, proc_viocd_show, NULL);
179}
180
181static struct file_operations proc_viocd_operations = {
182 .open = proc_viocd_open,
183 .read = seq_read,
184 .llseek = seq_lseek,
185 .release = single_release,
186};
187
188static int viocd_blk_open(struct inode *inode, struct file *file)
189{
190 struct disk_info *di = inode->i_bdev->bd_disk->private_data;
191 return cdrom_open(&di->viocd_info, inode, file);
192}
193
194static int viocd_blk_release(struct inode *inode, struct file *file)
195{
196 struct disk_info *di = inode->i_bdev->bd_disk->private_data;
197 return cdrom_release(&di->viocd_info, file);
198}
199
200static int viocd_blk_ioctl(struct inode *inode, struct file *file,
201 unsigned cmd, unsigned long arg)
202{
203 struct disk_info *di = inode->i_bdev->bd_disk->private_data;
204 return cdrom_ioctl(file, &di->viocd_info, inode, cmd, arg);
205}
206
207static int viocd_blk_media_changed(struct gendisk *disk)
208{
209 struct disk_info *di = disk->private_data;
210 return cdrom_media_changed(&di->viocd_info);
211}
212
213struct block_device_operations viocd_fops = {
214 .owner = THIS_MODULE,
215 .open = viocd_blk_open,
216 .release = viocd_blk_release,
217 .ioctl = viocd_blk_ioctl,
218 .media_changed = viocd_blk_media_changed,
219};
220
221/* Get info on CD devices from OS/400 */
222static void __init get_viocd_info(void)
223{
224 HvLpEvent_Rc hvrc;
225 int i;
226 struct viocd_waitevent we;
227
228 viocd_unitinfo = dma_alloc_coherent(iSeries_vio_dev,
229 sizeof(*viocd_unitinfo) * VIOCD_MAX_CD,
230 &unitinfo_dmaaddr, GFP_ATOMIC);
231 if (viocd_unitinfo == NULL) {
232 printk(VIOCD_KERN_WARNING "error allocating unitinfo\n");
233 return;
234 }
235
236 memset(viocd_unitinfo, 0, sizeof(*viocd_unitinfo) * VIOCD_MAX_CD);
237
238 init_completion(&we.com);
239
240 hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
241 HvLpEvent_Type_VirtualIo,
242 viomajorsubtype_cdio | viocdgetinfo,
243 HvLpEvent_AckInd_DoAck, HvLpEvent_AckType_ImmediateAck,
244 viopath_sourceinst(viopath_hostLp),
245 viopath_targetinst(viopath_hostLp),
246 (u64)&we, VIOVERSION << 16, unitinfo_dmaaddr, 0,
247 sizeof(*viocd_unitinfo) * VIOCD_MAX_CD, 0);
248 if (hvrc != HvLpEvent_Rc_Good) {
249 printk(VIOCD_KERN_WARNING "cdrom error sending event. rc %d\n",
250 (int)hvrc);
251 goto error_ret;
252 }
253
254 wait_for_completion(&we.com);
255
256 if (we.rc) {
257 const struct vio_error_entry *err =
258 vio_lookup_rc(viocd_err_table, we.sub_result);
259 printk(VIOCD_KERN_WARNING "bad rc %d:0x%04X on getinfo: %s\n",
260 we.rc, we.sub_result, err->msg);
261 goto error_ret;
262 }
263
264 for (i = 0; (i < VIOCD_MAX_CD) && viocd_unitinfo[i].rsrcname[0]; i++)
265 viocd_numdev++;
266
267error_ret:
268 if (viocd_numdev == 0) {
269 dma_free_coherent(iSeries_vio_dev,
270 sizeof(*viocd_unitinfo) * VIOCD_MAX_CD,
271 viocd_unitinfo, unitinfo_dmaaddr);
272 viocd_unitinfo = NULL;
273 }
274}
275
276static int viocd_open(struct cdrom_device_info *cdi, int purpose)
277{
278 struct disk_info *diskinfo = cdi->handle;
279 int device_no = DEVICE_NR(diskinfo);
280 HvLpEvent_Rc hvrc;
281 struct viocd_waitevent we;
282
283 init_completion(&we.com);
284 hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
285 HvLpEvent_Type_VirtualIo,
286 viomajorsubtype_cdio | viocdopen,
287 HvLpEvent_AckInd_DoAck, HvLpEvent_AckType_ImmediateAck,
288 viopath_sourceinst(viopath_hostLp),
289 viopath_targetinst(viopath_hostLp),
290 (u64)&we, VIOVERSION << 16, ((u64)device_no << 48),
291 0, 0, 0);
292 if (hvrc != 0) {
293 printk(VIOCD_KERN_WARNING
294 "bad rc on HvCallEvent_signalLpEventFast %d\n",
295 (int)hvrc);
296 return -EIO;
297 }
298
299 wait_for_completion(&we.com);
300
301 if (we.rc) {
302 const struct vio_error_entry *err =
303 vio_lookup_rc(viocd_err_table, we.sub_result);
304 printk(VIOCD_KERN_WARNING "bad rc %d:0x%04X on open: %s\n",
305 we.rc, we.sub_result, err->msg);
306 return -err->errno;
307 }
308
309 return 0;
310}
311
312static void viocd_release(struct cdrom_device_info *cdi)
313{
314 int device_no = DEVICE_NR((struct disk_info *)cdi->handle);
315 HvLpEvent_Rc hvrc;
316
317 hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
318 HvLpEvent_Type_VirtualIo,
319 viomajorsubtype_cdio | viocdclose,
320 HvLpEvent_AckInd_NoAck, HvLpEvent_AckType_ImmediateAck,
321 viopath_sourceinst(viopath_hostLp),
322 viopath_targetinst(viopath_hostLp), 0,
323 VIOVERSION << 16, ((u64)device_no << 48), 0, 0, 0);
324 if (hvrc != 0)
325 printk(VIOCD_KERN_WARNING
326 "bad rc on HvCallEvent_signalLpEventFast %d\n",
327 (int)hvrc);
328}
329
330/* Send a read or write request to OS/400 */
331static int send_request(struct request *req)
332{
333 HvLpEvent_Rc hvrc;
334 struct disk_info *diskinfo = req->rq_disk->private_data;
335 u64 len;
336 dma_addr_t dmaaddr;
337 int direction;
338 u16 cmd;
339 struct scatterlist sg;
340
341 BUG_ON(req->nr_phys_segments > 1);
342
343 if (rq_data_dir(req) == READ) {
344 direction = DMA_FROM_DEVICE;
345 cmd = viomajorsubtype_cdio | viocdread;
346 } else {
347 direction = DMA_TO_DEVICE;
348 cmd = viomajorsubtype_cdio | viocdwrite;
349 }
350
351 if (blk_rq_map_sg(req->q, req, &sg) == 0) {
352 printk(VIOCD_KERN_WARNING
353 "error setting up scatter/gather list\n");
354 return -1;
355 }
356
357 if (dma_map_sg(diskinfo->dev, &sg, 1, direction) == 0) {
358 printk(VIOCD_KERN_WARNING "error allocating sg tce\n");
359 return -1;
360 }
361 dmaaddr = sg_dma_address(&sg);
362 len = sg_dma_len(&sg);
363
364 hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
365 HvLpEvent_Type_VirtualIo, cmd,
366 HvLpEvent_AckInd_DoAck,
367 HvLpEvent_AckType_ImmediateAck,
368 viopath_sourceinst(viopath_hostLp),
369 viopath_targetinst(viopath_hostLp),
370 (u64)req, VIOVERSION << 16,
371 ((u64)DEVICE_NR(diskinfo) << 48) | dmaaddr,
372 (u64)req->sector * 512, len, 0);
373 if (hvrc != HvLpEvent_Rc_Good) {
374 printk(VIOCD_KERN_WARNING "hv error on op %d\n", (int)hvrc);
375 return -1;
376 }
377
378 return 0;
379}
380
381
382static int rwreq;
383
384static void do_viocd_request(request_queue_t *q)
385{
386 struct request *req;
387
388 while ((rwreq == 0) && ((req = elv_next_request(q)) != NULL)) {
389 if (!blk_fs_request(req))
390 end_request(req, 0);
391 else if (send_request(req) < 0) {
392 printk(VIOCD_KERN_WARNING
393 "unable to send message to OS/400!");
394 end_request(req, 0);
395 } else
396 rwreq++;
397 }
398}
399
400static int viocd_media_changed(struct cdrom_device_info *cdi, int disc_nr)
401{
402 struct viocd_waitevent we;
403 HvLpEvent_Rc hvrc;
404 int device_no = DEVICE_NR((struct disk_info *)cdi->handle);
405
406 init_completion(&we.com);
407
408 /* Send the open event to OS/400 */
409 hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
410 HvLpEvent_Type_VirtualIo,
411 viomajorsubtype_cdio | viocdcheck,
412 HvLpEvent_AckInd_DoAck, HvLpEvent_AckType_ImmediateAck,
413 viopath_sourceinst(viopath_hostLp),
414 viopath_targetinst(viopath_hostLp),
415 (u64)&we, VIOVERSION << 16, ((u64)device_no << 48),
416 0, 0, 0);
417 if (hvrc != 0) {
418 printk(VIOCD_KERN_WARNING "bad rc on HvCallEvent_signalLpEventFast %d\n",
419 (int)hvrc);
420 return -EIO;
421 }
422
423 wait_for_completion(&we.com);
424
425 /* Check the return code. If bad, assume no change */
426 if (we.rc) {
427 const struct vio_error_entry *err =
428 vio_lookup_rc(viocd_err_table, we.sub_result);
429 printk(VIOCD_KERN_WARNING
430 "bad rc %d:0x%04X on check_change: %s; Assuming no change\n",
431 we.rc, we.sub_result, err->msg);
432 return 0;
433 }
434
435 return we.changed;
436}
437
438static int viocd_lock_door(struct cdrom_device_info *cdi, int locking)
439{
440 HvLpEvent_Rc hvrc;
441 u64 device_no = DEVICE_NR((struct disk_info *)cdi->handle);
442 /* NOTE: flags is 1 or 0 so it won't overwrite the device_no */
443 u64 flags = !!locking;
444 struct viocd_waitevent we;
445
446 init_completion(&we.com);
447
448 /* Send the lockdoor event to OS/400 */
449 hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
450 HvLpEvent_Type_VirtualIo,
451 viomajorsubtype_cdio | viocdlockdoor,
452 HvLpEvent_AckInd_DoAck, HvLpEvent_AckType_ImmediateAck,
453 viopath_sourceinst(viopath_hostLp),
454 viopath_targetinst(viopath_hostLp),
455 (u64)&we, VIOVERSION << 16,
456 (device_no << 48) | (flags << 32), 0, 0, 0);
457 if (hvrc != 0) {
458 printk(VIOCD_KERN_WARNING "bad rc on HvCallEvent_signalLpEventFast %d\n",
459 (int)hvrc);
460 return -EIO;
461 }
462
463 wait_for_completion(&we.com);
464
465 if (we.rc != 0)
466 return -EIO;
467 return 0;
468}
469
470static int viocd_packet(struct cdrom_device_info *cdi,
471 struct packet_command *cgc)
472{
473 unsigned int buflen = cgc->buflen;
474 int ret = -EIO;
475
476 switch (cgc->cmd[0]) {
477 case GPCMD_READ_DISC_INFO:
478 {
479 disc_information *di = (disc_information *)cgc->buffer;
480
481 if (buflen >= 2) {
482 di->disc_information_length = cpu_to_be16(1);
483 ret = 0;
484 }
485 if (buflen >= 3)
486 di->erasable =
487 (cdi->ops->capability & ~cdi->mask
488 & (CDC_DVD_RAM | CDC_RAM)) != 0;
489 }
490 break;
491 default:
492 if (cgc->sense) {
493 /* indicate Unknown code */
494 cgc->sense->sense_key = 0x05;
495 cgc->sense->asc = 0x20;
496 cgc->sense->ascq = 0x00;
497 }
498 break;
499 }
500
501 cgc->stat = ret;
502 return ret;
503}
504
505static void restart_all_queues(int first_index)
506{
507 int i;
508
509 for (i = first_index + 1; i < viocd_numdev; i++)
510 if (viocd_diskinfo[i].viocd_disk)
511 blk_run_queue(viocd_diskinfo[i].viocd_disk->queue);
512 for (i = 0; i <= first_index; i++)
513 if (viocd_diskinfo[i].viocd_disk)
514 blk_run_queue(viocd_diskinfo[i].viocd_disk->queue);
515}
516
517/* This routine handles incoming CD LP events */
518static void vio_handle_cd_event(struct HvLpEvent *event)
519{
520 struct viocdlpevent *bevent;
521 struct viocd_waitevent *pwe;
522 struct disk_info *di;
523 unsigned long flags;
524 struct request *req;
525
526
527 if (event == NULL)
528 /* Notification that a partition went away! */
529 return;
530 /* First, we should NEVER get an int here...only acks */
531 if (event->xFlags.xFunction == HvLpEvent_Function_Int) {
532 printk(VIOCD_KERN_WARNING
533 "Yikes! got an int in viocd event handler!\n");
534 if (event->xFlags.xAckInd == HvLpEvent_AckInd_DoAck) {
535 event->xRc = HvLpEvent_Rc_InvalidSubtype;
536 HvCallEvent_ackLpEvent(event);
537 }
538 }
539
540 bevent = (struct viocdlpevent *)event;
541
542 switch (event->xSubtype & VIOMINOR_SUBTYPE_MASK) {
543 case viocdopen:
544 if (event->xRc == 0) {
545 di = &viocd_diskinfo[bevent->disk];
546 blk_queue_hardsect_size(di->viocd_disk->queue,
547 bevent->block_size);
548 set_capacity(di->viocd_disk,
549 bevent->media_size *
550 bevent->block_size / 512);
551 }
552 /* FALLTHROUGH !! */
553 case viocdgetinfo:
554 case viocdlockdoor:
555 pwe = (struct viocd_waitevent *)event->xCorrelationToken;
556return_complete:
557 pwe->rc = event->xRc;
558 pwe->sub_result = bevent->sub_result;
559 complete(&pwe->com);
560 break;
561
562 case viocdcheck:
563 pwe = (struct viocd_waitevent *)event->xCorrelationToken;
564 pwe->changed = bevent->flags;
565 goto return_complete;
566
567 case viocdclose:
568 break;
569
570 case viocdwrite:
571 case viocdread:
572 /*
573 * Since this is running in interrupt mode, we need to
574 * make sure we're not stepping on any global I/O operations
575 */
576 di = &viocd_diskinfo[bevent->disk];
577 spin_lock_irqsave(&viocd_reqlock, flags);
578 dma_unmap_single(di->dev, bevent->token, bevent->len,
579 ((event->xSubtype & VIOMINOR_SUBTYPE_MASK) == viocdread)
580 ? DMA_FROM_DEVICE : DMA_TO_DEVICE);
581 req = (struct request *)bevent->event.xCorrelationToken;
582 rwreq--;
583
584 if (event->xRc != HvLpEvent_Rc_Good) {
585 const struct vio_error_entry *err =
586 vio_lookup_rc(viocd_err_table,
587 bevent->sub_result);
588 printk(VIOCD_KERN_WARNING "request %p failed "
589 "with rc %d:0x%04X: %s\n",
590 req, event->xRc,
591 bevent->sub_result, err->msg);
592 end_request(req, 0);
593 } else
594 end_request(req, 1);
595
596 /* restart handling of incoming requests */
597 spin_unlock_irqrestore(&viocd_reqlock, flags);
598 restart_all_queues(bevent->disk);
599 break;
600
601 default:
602 printk(VIOCD_KERN_WARNING
603 "message with invalid subtype %0x04X!\n",
604 event->xSubtype & VIOMINOR_SUBTYPE_MASK);
605 if (event->xFlags.xAckInd == HvLpEvent_AckInd_DoAck) {
606 event->xRc = HvLpEvent_Rc_InvalidSubtype;
607 HvCallEvent_ackLpEvent(event);
608 }
609 }
610}
611
612static struct cdrom_device_ops viocd_dops = {
613 .open = viocd_open,
614 .release = viocd_release,
615 .media_changed = viocd_media_changed,
616 .lock_door = viocd_lock_door,
617 .generic_packet = viocd_packet,
618 .capability = CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK | CDC_SELECT_SPEED | CDC_SELECT_DISC | CDC_MULTI_SESSION | CDC_MCN | CDC_MEDIA_CHANGED | CDC_PLAY_AUDIO | CDC_RESET | CDC_IOCTLS | CDC_DRIVE_STATUS | CDC_GENERIC_PACKET | CDC_CD_R | CDC_CD_RW | CDC_DVD | CDC_DVD_R | CDC_DVD_RAM | CDC_RAM
619};
620
621static int __init find_capability(const char *type)
622{
623 struct capability_entry *entry;
624
625 for(entry = capability_table; entry->type; ++entry)
626 if(!strncmp(entry->type, type, 4))
627 break;
628 return entry->capability;
629}
630
631static int viocd_probe(struct vio_dev *vdev, const struct vio_device_id *id)
632{
633 struct gendisk *gendisk;
634 int deviceno;
635 struct disk_info *d;
636 struct cdrom_device_info *c;
637 struct cdrom_info *ci;
638 struct request_queue *q;
639
640 deviceno = vdev->unit_address;
641 if (deviceno >= viocd_numdev)
642 return -ENODEV;
643
644 d = &viocd_diskinfo[deviceno];
645 c = &d->viocd_info;
646 ci = &viocd_unitinfo[deviceno];
647
648 c->ops = &viocd_dops;
649 c->speed = 4;
650 c->capacity = 1;
651 c->handle = d;
652 c->mask = ~find_capability(ci->type);
653 sprintf(c->name, VIOCD_DEVICE "%c", 'a' + deviceno);
654
655 if (register_cdrom(c) != 0) {
656 printk(VIOCD_KERN_WARNING "Cannot register viocd CD-ROM %s!\n",
657 c->name);
658 goto out;
659 }
660 printk(VIOCD_KERN_INFO "cd %s is iSeries resource %10.10s "
661 "type %4.4s, model %3.3s\n",
662 c->name, ci->rsrcname, ci->type, ci->model);
663 q = blk_init_queue(do_viocd_request, &viocd_reqlock);
664 if (q == NULL) {
665 printk(VIOCD_KERN_WARNING "Cannot allocate queue for %s!\n",
666 c->name);
667 goto out_unregister_cdrom;
668 }
669 gendisk = alloc_disk(1);
670 if (gendisk == NULL) {
671 printk(VIOCD_KERN_WARNING "Cannot create gendisk for %s!\n",
672 c->name);
673 goto out_cleanup_queue;
674 }
675 gendisk->major = VIOCD_MAJOR;
676 gendisk->first_minor = deviceno;
677 strncpy(gendisk->disk_name, c->name,
678 sizeof(gendisk->disk_name));
679 snprintf(gendisk->devfs_name, sizeof(gendisk->devfs_name),
680 VIOCD_DEVICE_DEVFS "%d", deviceno);
681 blk_queue_max_hw_segments(q, 1);
682 blk_queue_max_phys_segments(q, 1);
683 blk_queue_max_sectors(q, 4096 / 512);
684 gendisk->queue = q;
685 gendisk->fops = &viocd_fops;
686 gendisk->flags = GENHD_FL_CD|GENHD_FL_REMOVABLE;
687 set_capacity(gendisk, 0);
688 gendisk->private_data = d;
689 d->viocd_disk = gendisk;
690 d->dev = &vdev->dev;
691 gendisk->driverfs_dev = d->dev;
692 add_disk(gendisk);
693 return 0;
694
695out_cleanup_queue:
696 blk_cleanup_queue(q);
697out_unregister_cdrom:
698 unregister_cdrom(c);
699out:
700 return -ENODEV;
701}
702
703static int viocd_remove(struct vio_dev *vdev)
704{
705 struct disk_info *d = &viocd_diskinfo[vdev->unit_address];
706
707 if (unregister_cdrom(&d->viocd_info) != 0)
708 printk(VIOCD_KERN_WARNING
709 "Cannot unregister viocd CD-ROM %s!\n",
710 d->viocd_info.name);
711 del_gendisk(d->viocd_disk);
712 blk_cleanup_queue(d->viocd_disk->queue);
713 put_disk(d->viocd_disk);
714 return 0;
715}
716
717/**
718 * viocd_device_table: Used by vio.c to match devices that we
719 * support.
720 */
721static struct vio_device_id viocd_device_table[] __devinitdata = {
722 { "viocd", "" },
723 { 0, }
724};
725
726MODULE_DEVICE_TABLE(vio, viocd_device_table);
727static struct vio_driver viocd_driver = {
728 .name = "viocd",
729 .id_table = viocd_device_table,
730 .probe = viocd_probe,
731 .remove = viocd_remove
732};
733
734static int __init viocd_init(void)
735{
736 struct proc_dir_entry *e;
737 int ret = 0;
738
739 if (viopath_hostLp == HvLpIndexInvalid) {
740 vio_set_hostlp();
741 /* If we don't have a host, bail out */
742 if (viopath_hostLp == HvLpIndexInvalid)
743 return -ENODEV;
744 }
745
746 printk(VIOCD_KERN_INFO "vers " VIOCD_VERS ", hosting partition %d\n",
747 viopath_hostLp);
748
749 if (register_blkdev(VIOCD_MAJOR, VIOCD_DEVICE) != 0) {
750 printk(VIOCD_KERN_WARNING "Unable to get major %d for %s\n",
751 VIOCD_MAJOR, VIOCD_DEVICE);
752 return -EIO;
753 }
754
755 ret = viopath_open(viopath_hostLp, viomajorsubtype_cdio,
756 MAX_CD_REQ + 2);
757 if (ret) {
758 printk(VIOCD_KERN_WARNING
759 "error opening path to host partition %d\n",
760 viopath_hostLp);
761 goto out_unregister;
762 }
763
764 /* Initialize our request handler */
765 vio_setHandler(viomajorsubtype_cdio, vio_handle_cd_event);
766
767 get_viocd_info();
768
769 spin_lock_init(&viocd_reqlock);
770
771 ret = vio_register_driver(&viocd_driver);
772 if (ret)
773 goto out_free_info;
774
775 e = create_proc_entry("iSeries/viocd", S_IFREG|S_IRUGO, NULL);
776 if (e) {
777 e->owner = THIS_MODULE;
778 e->proc_fops = &proc_viocd_operations;
779 }
780
781 return 0;
782
783out_free_info:
784 dma_free_coherent(iSeries_vio_dev,
785 sizeof(*viocd_unitinfo) * VIOCD_MAX_CD,
786 viocd_unitinfo, unitinfo_dmaaddr);
787 vio_clearHandler(viomajorsubtype_cdio);
788 viopath_close(viopath_hostLp, viomajorsubtype_cdio, MAX_CD_REQ + 2);
789out_unregister:
790 unregister_blkdev(VIOCD_MAJOR, VIOCD_DEVICE);
791 return ret;
792}
793
794static void __exit viocd_exit(void)
795{
796 remove_proc_entry("iSeries/viocd", NULL);
797 vio_unregister_driver(&viocd_driver);
798 if (viocd_unitinfo != NULL)
799 dma_free_coherent(iSeries_vio_dev,
800 sizeof(*viocd_unitinfo) * VIOCD_MAX_CD,
801 viocd_unitinfo, unitinfo_dmaaddr);
802 viopath_close(viopath_hostLp, viomajorsubtype_cdio, MAX_CD_REQ + 2);
803 vio_clearHandler(viomajorsubtype_cdio);
804 unregister_blkdev(VIOCD_MAJOR, VIOCD_DEVICE);
805}
806
807module_init(viocd_init);
808module_exit(viocd_exit);
809MODULE_LICENSE("GPL");