blob: 782dbab5ad56afeb151f8e12fd9de98c66e4656a [file] [log] [blame]
Uwe Zeisbergerf30c2262006-10-03 23:01:26 +02001/* linux/drivers/cdrom/cdrom.c
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 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>
Lucas De Marchi25985ed2011-03-30 22:57:33 -030033 -- New maintainer! As David A. van Leeuwen has been too busy to actively
Linus Torvalds1da177e2005-04-16 15:20:36 -070034 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
Joe Perchese597cd02010-07-01 08:24:32 +0200245#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
246
Linus Torvalds1da177e2005-04-16 15:20:36 -0700247#define REVISION "Revision: 3.20"
248#define VERSION "Id: cdrom.c 3.20 2003/12/17"
249
250/* I use an error-log mask to give fine grain control over the type of
251 messages dumped to the system logs. The available masks include: */
252#define CD_NOTHING 0x0
253#define CD_WARNING 0x1
254#define CD_REG_UNREG 0x2
255#define CD_DO_IOCTL 0x4
256#define CD_OPEN 0x8
257#define CD_CLOSE 0x10
258#define CD_COUNT_TRACKS 0x20
259#define CD_CHANGER 0x40
260#define CD_DVD 0x80
261
262/* Define this to remove _all_ the debugging messages */
263/* #define ERRLOGMASK CD_NOTHING */
264#define ERRLOGMASK CD_WARNING
265/* #define ERRLOGMASK (CD_WARNING|CD_OPEN|CD_COUNT_TRACKS|CD_CLOSE) */
266/* #define ERRLOGMASK (CD_WARNING|CD_REG_UNREG|CD_DO_IOCTL|CD_OPEN|CD_CLOSE|CD_COUNT_TRACKS) */
267
Guenter Roeckf04b47a2019-02-06 21:13:49 -0800268#include <linux/atomic.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -0700269#include <linux/module.h>
270#include <linux/fs.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -0700271#include <linux/major.h>
272#include <linux/types.h>
273#include <linux/errno.h>
274#include <linux/kernel.h>
275#include <linux/mm.h>
276#include <linux/slab.h>
277#include <linux/cdrom.h>
278#include <linux/sysctl.h>
279#include <linux/proc_fs.h>
280#include <linux/blkpg.h>
281#include <linux/init.h>
282#include <linux/fcntl.h>
283#include <linux/blkdev.h>
284#include <linux/times.h>
285
286#include <asm/uaccess.h>
287
288/* used to tell the module to turn on full debugging messages */
Rusty Russell90ab5ee2012-01-13 09:32:20 +1030289static bool debug;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700290/* default compatibility mode */
Rusty Russell90ab5ee2012-01-13 09:32:20 +1030291static bool autoclose=1;
292static bool autoeject;
293static bool lockdoor = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700294/* will we ever get to use this... sigh. */
Rusty Russell90ab5ee2012-01-13 09:32:20 +1030295static bool check_media_type;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700296/* automatically restart mrw format */
Rusty Russell90ab5ee2012-01-13 09:32:20 +1030297static bool mrw_format_restart = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700298module_param(debug, bool, 0);
299module_param(autoclose, bool, 0);
300module_param(autoeject, bool, 0);
301module_param(lockdoor, bool, 0);
302module_param(check_media_type, bool, 0);
303module_param(mrw_format_restart, bool, 0);
304
Dave Young554988d2007-06-19 09:14:26 +0200305static DEFINE_MUTEX(cdrom_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700306
307static const char *mrw_format_status[] = {
308 "not mrw",
309 "bgformat inactive",
310 "bgformat active",
311 "mrw complete",
312};
313
314static const char *mrw_address_space[] = { "DMA", "GAA" };
315
Joe Perches5944b2c2014-05-04 17:05:02 -0700316#if (ERRLOGMASK != CD_NOTHING)
317#define cd_dbg(type, fmt, ...) \
Joe Perchese597cd02010-07-01 08:24:32 +0200318do { \
319 if ((ERRLOGMASK & type) || debug == 1) \
Joe Perches5944b2c2014-05-04 17:05:02 -0700320 pr_debug(fmt, ##__VA_ARGS__); \
Joe Perchese597cd02010-07-01 08:24:32 +0200321} while (0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700322#else
Joe Perches5944b2c2014-05-04 17:05:02 -0700323#define cd_dbg(type, fmt, ...) \
Joe Perchese597cd02010-07-01 08:24:32 +0200324do { \
325 if (0 && (ERRLOGMASK & type) || debug == 1) \
Joe Perches5944b2c2014-05-04 17:05:02 -0700326 pr_debug(fmt, ##__VA_ARGS__); \
Joe Perchese597cd02010-07-01 08:24:32 +0200327} while (0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700328#endif
329
Linus Torvalds1da177e2005-04-16 15:20:36 -0700330/* The (cdo->capability & ~cdi->mask & CDC_XXX) construct was used in
331 a lot of places. This macro makes the code more clear. */
332#define CDROM_CAN(type) (cdi->ops->capability & ~cdi->mask & (type))
333
Jens Axboe2e11c202007-01-03 08:10:35 +0100334/*
335 * Another popular OS uses 7 seconds as the hard timeout for default
336 * commands, so it is a good choice for us as well.
337 */
338#define CDROM_DEF_TIMEOUT (7 * HZ)
339
Linus Torvalds1da177e2005-04-16 15:20:36 -0700340/* Not-exported routines. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700341
Linus Torvalds1da177e2005-04-16 15:20:36 -0700342static void cdrom_sysctl_register(void);
Akinobu Mita17672cf2008-03-26 12:08:59 +0100343
Akinobu Mita7fd097d2008-03-26 12:09:02 +0100344static LIST_HEAD(cdrom_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700345
346static int cdrom_dummy_generic_packet(struct cdrom_device_info *cdi,
347 struct packet_command *cgc)
348{
349 if (cgc->sense) {
350 cgc->sense->sense_key = 0x05;
351 cgc->sense->asc = 0x20;
352 cgc->sense->ascq = 0x00;
353 }
354
355 cgc->stat = -EIO;
356 return -EIO;
357}
358
Joe Perches40569c62014-05-04 17:05:12 -0700359static int cdrom_flush_cache(struct cdrom_device_info *cdi)
360{
361 struct packet_command cgc;
362
363 init_cdrom_command(&cgc, NULL, 0, CGC_DATA_NONE);
364 cgc.cmd[0] = GPCMD_FLUSH_CACHE;
365
366 cgc.timeout = 5 * 60 * HZ;
367
368 return cdi->ops->generic_packet(cdi, &cgc);
369}
370
Joe Perchesbd6f0bb2014-05-04 17:05:13 -0700371/* requires CD R/RW */
372static int cdrom_get_disc_info(struct cdrom_device_info *cdi,
373 disc_information *di)
374{
375 struct cdrom_device_ops *cdo = cdi->ops;
376 struct packet_command cgc;
377 int ret, buflen;
378
379 /* set up command and get the disc info */
380 init_cdrom_command(&cgc, di, sizeof(*di), CGC_DATA_READ);
381 cgc.cmd[0] = GPCMD_READ_DISC_INFO;
382 cgc.cmd[8] = cgc.buflen = 2;
383 cgc.quiet = 1;
384
385 ret = cdo->generic_packet(cdi, &cgc);
386 if (ret)
387 return ret;
388
389 /* not all drives have the same disc_info length, so requeue
390 * packet with the length the drive tells us it can supply
391 */
392 buflen = be16_to_cpu(di->disc_information_length) +
393 sizeof(di->disc_information_length);
394
395 if (buflen > sizeof(disc_information))
396 buflen = sizeof(disc_information);
397
398 cgc.cmd[8] = cgc.buflen = buflen;
399 ret = cdo->generic_packet(cdi, &cgc);
400 if (ret)
401 return ret;
402
403 /* return actual fill size */
404 return buflen;
405}
406
Linus Torvalds1da177e2005-04-16 15:20:36 -0700407/* This macro makes sure we don't have to check on cdrom_device_ops
408 * existence in the run-time routines below. Change_capability is a
409 * hack to have the capability flags defined const, while we can still
410 * change it here without gcc complaining at every line.
411 */
Joe Perches40569c62014-05-04 17:05:12 -0700412#define ENSURE(call, bits) \
413do { \
414 if (cdo->call == NULL) \
415 *change_capability &= ~(bits); \
416} while (0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700417
418/*
419 * the first prototypes used 0x2c as the page code for the mrw mode page,
420 * subsequently this was changed to 0x03. probe the one used by this drive
421 */
422static int cdrom_mrw_probe_pc(struct cdrom_device_info *cdi)
423{
424 struct packet_command cgc;
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200425 char buffer[16];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700426
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200427 init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700428
429 cgc.timeout = HZ;
430 cgc.quiet = 1;
431
432 if (!cdrom_mode_sense(cdi, &cgc, MRW_MODE_PC, 0)) {
433 cdi->mrw_mode_page = MRW_MODE_PC;
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200434 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700435 } else if (!cdrom_mode_sense(cdi, &cgc, MRW_MODE_PC_PRE1, 0)) {
436 cdi->mrw_mode_page = MRW_MODE_PC_PRE1;
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200437 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700438 }
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200439
440 return 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700441}
442
443static int cdrom_is_mrw(struct cdrom_device_info *cdi, int *write)
444{
445 struct packet_command cgc;
446 struct mrw_feature_desc *mfd;
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200447 unsigned char buffer[16];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700448 int ret;
449
450 *write = 0;
451
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200452 init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700453
454 cgc.cmd[0] = GPCMD_GET_CONFIGURATION;
455 cgc.cmd[3] = CDF_MRW;
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200456 cgc.cmd[8] = sizeof(buffer);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700457 cgc.quiet = 1;
458
459 if ((ret = cdi->ops->generic_packet(cdi, &cgc)))
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200460 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700461
462 mfd = (struct mrw_feature_desc *)&buffer[sizeof(struct feature_header)];
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200463 if (be16_to_cpu(mfd->feature_code) != CDF_MRW)
464 return 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700465 *write = mfd->write;
466
467 if ((ret = cdrom_mrw_probe_pc(cdi))) {
468 *write = 0;
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200469 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700470 }
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200471
472 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700473}
474
475static int cdrom_mrw_bgformat(struct cdrom_device_info *cdi, int cont)
476{
477 struct packet_command cgc;
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200478 unsigned char buffer[12];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700479 int ret;
480
Joe Perchese597cd02010-07-01 08:24:32 +0200481 pr_info("%sstarting format\n", cont ? "Re" : "");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700482
483 /*
484 * FmtData bit set (bit 4), format type is 1
485 */
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200486 init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_WRITE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700487 cgc.cmd[0] = GPCMD_FORMAT_UNIT;
488 cgc.cmd[1] = (1 << 4) | 1;
489
490 cgc.timeout = 5 * 60 * HZ;
491
492 /*
493 * 4 byte format list header, 8 byte format list descriptor
494 */
495 buffer[1] = 1 << 1;
496 buffer[3] = 8;
497
498 /*
499 * nr_blocks field
500 */
501 buffer[4] = 0xff;
502 buffer[5] = 0xff;
503 buffer[6] = 0xff;
504 buffer[7] = 0xff;
505
506 buffer[8] = 0x24 << 2;
507 buffer[11] = cont;
508
509 ret = cdi->ops->generic_packet(cdi, &cgc);
510 if (ret)
Joe Perchese597cd02010-07-01 08:24:32 +0200511 pr_info("bgformat failed\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700512
513 return ret;
514}
515
516static int cdrom_mrw_bgformat_susp(struct cdrom_device_info *cdi, int immed)
517{
518 struct packet_command cgc;
519
520 init_cdrom_command(&cgc, NULL, 0, CGC_DATA_NONE);
521 cgc.cmd[0] = GPCMD_CLOSE_TRACK;
522
523 /*
524 * Session = 1, Track = 0
525 */
526 cgc.cmd[1] = !!immed;
527 cgc.cmd[2] = 1 << 1;
528
529 cgc.timeout = 5 * 60 * HZ;
530
531 return cdi->ops->generic_packet(cdi, &cgc);
532}
533
Linus Torvalds1da177e2005-04-16 15:20:36 -0700534static int cdrom_mrw_exit(struct cdrom_device_info *cdi)
535{
536 disc_information di;
537 int ret;
538
539 ret = cdrom_get_disc_info(cdi, &di);
540 if (ret < 0 || ret < (int)offsetof(typeof(di),disc_type))
541 return 1;
542
543 ret = 0;
544 if (di.mrw_status == CDM_MRW_BGFORMAT_ACTIVE) {
Joe Perchese597cd02010-07-01 08:24:32 +0200545 pr_info("issuing MRW background format suspend\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700546 ret = cdrom_mrw_bgformat_susp(cdi, 0);
547 }
548
Jens Axboe7da21a02005-05-01 12:12:52 -0700549 if (!ret && cdi->media_written)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700550 ret = cdrom_flush_cache(cdi);
551
552 return ret;
553}
554
555static int cdrom_mrw_set_lba_space(struct cdrom_device_info *cdi, int space)
556{
557 struct packet_command cgc;
558 struct mode_page_header *mph;
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200559 char buffer[16];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700560 int ret, offset, size;
561
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200562 init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700563
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200564 cgc.buffer = buffer;
565 cgc.buflen = sizeof(buffer);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700566
Joe Perches40569c62014-05-04 17:05:12 -0700567 ret = cdrom_mode_sense(cdi, &cgc, cdi->mrw_mode_page, 0);
568 if (ret)
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200569 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700570
Joe Perches40569c62014-05-04 17:05:12 -0700571 mph = (struct mode_page_header *)buffer;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700572 offset = be16_to_cpu(mph->desc_length);
573 size = be16_to_cpu(mph->mode_data_length) + 2;
574
575 buffer[offset + 3] = space;
576 cgc.buflen = size;
577
Joe Perches40569c62014-05-04 17:05:12 -0700578 ret = cdrom_mode_select(cdi, &cgc);
579 if (ret)
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200580 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700581
Joe Perchese597cd02010-07-01 08:24:32 +0200582 pr_info("%s: mrw address space %s selected\n",
583 cdi->name, mrw_address_space[space]);
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200584 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700585}
586
Joe Perches40569c62014-05-04 17:05:12 -0700587int register_cdrom(struct cdrom_device_info *cdi)
588{
589 static char banner_printed;
590 struct cdrom_device_ops *cdo = cdi->ops;
591 int *change_capability = (int *)&cdo->capability; /* hack */
592
593 cd_dbg(CD_OPEN, "entering register_cdrom\n");
594
595 if (cdo->open == NULL || cdo->release == NULL)
596 return -EINVAL;
597 if (!banner_printed) {
598 pr_info("Uniform CD-ROM driver " REVISION "\n");
599 banner_printed = 1;
600 cdrom_sysctl_register();
601 }
602
603 ENSURE(drive_status, CDC_DRIVE_STATUS);
604 if (cdo->check_events == NULL && cdo->media_changed == NULL)
605 *change_capability = ~(CDC_MEDIA_CHANGED | CDC_SELECT_DISC);
606 ENSURE(tray_move, CDC_CLOSE_TRAY | CDC_OPEN_TRAY);
607 ENSURE(lock_door, CDC_LOCK);
608 ENSURE(select_speed, CDC_SELECT_SPEED);
609 ENSURE(get_last_session, CDC_MULTI_SESSION);
610 ENSURE(get_mcn, CDC_MCN);
611 ENSURE(reset, CDC_RESET);
612 ENSURE(generic_packet, CDC_GENERIC_PACKET);
613 cdi->mc_flags = 0;
614 cdo->n_minors = 0;
615 cdi->options = CDO_USE_FFLAGS;
616
617 if (autoclose == 1 && CDROM_CAN(CDC_CLOSE_TRAY))
618 cdi->options |= (int) CDO_AUTO_CLOSE;
619 if (autoeject == 1 && CDROM_CAN(CDC_OPEN_TRAY))
620 cdi->options |= (int) CDO_AUTO_EJECT;
621 if (lockdoor == 1)
622 cdi->options |= (int) CDO_LOCK;
623 if (check_media_type == 1)
624 cdi->options |= (int) CDO_CHECK_TYPE;
625
626 if (CDROM_CAN(CDC_MRW_W))
627 cdi->exit = cdrom_mrw_exit;
628
629 if (cdi->disk)
630 cdi->cdda_method = CDDA_BPC_FULL;
631 else
632 cdi->cdda_method = CDDA_OLD;
633
634 if (!cdo->generic_packet)
635 cdo->generic_packet = cdrom_dummy_generic_packet;
636
637 cd_dbg(CD_REG_UNREG, "drive \"/dev/%s\" registered\n", cdi->name);
638 mutex_lock(&cdrom_mutex);
639 list_add(&cdi->list, &cdrom_list);
640 mutex_unlock(&cdrom_mutex);
641 return 0;
642}
643#undef ENSURE
644
645void unregister_cdrom(struct cdrom_device_info *cdi)
646{
647 cd_dbg(CD_OPEN, "entering unregister_cdrom\n");
648
649 mutex_lock(&cdrom_mutex);
650 list_del(&cdi->list);
651 mutex_unlock(&cdrom_mutex);
652
653 if (cdi->exit)
654 cdi->exit(cdi);
655
656 cdi->ops->n_minors--;
657 cd_dbg(CD_REG_UNREG, "drive \"/dev/%s\" unregistered\n", cdi->name);
658}
659
660int cdrom_get_media_event(struct cdrom_device_info *cdi,
661 struct media_event_desc *med)
662{
663 struct packet_command cgc;
664 unsigned char buffer[8];
665 struct event_header *eh = (struct event_header *)buffer;
666
667 init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ);
668 cgc.cmd[0] = GPCMD_GET_EVENT_STATUS_NOTIFICATION;
669 cgc.cmd[1] = 1; /* IMMED */
670 cgc.cmd[4] = 1 << 4; /* media event */
671 cgc.cmd[8] = sizeof(buffer);
672 cgc.quiet = 1;
673
674 if (cdi->ops->generic_packet(cdi, &cgc))
675 return 1;
676
677 if (be16_to_cpu(eh->data_len) < sizeof(*med))
678 return 1;
679
680 if (eh->nea || eh->notification_class != 0x4)
681 return 1;
682
683 memcpy(med, &buffer[sizeof(*eh)], sizeof(*med));
684 return 0;
685}
686
Linus Torvalds1da177e2005-04-16 15:20:36 -0700687static int cdrom_get_random_writable(struct cdrom_device_info *cdi,
688 struct rwrt_feature_desc *rfd)
689{
690 struct packet_command cgc;
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200691 char buffer[24];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700692 int ret;
693
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200694 init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700695
696 cgc.cmd[0] = GPCMD_GET_CONFIGURATION; /* often 0x46 */
697 cgc.cmd[3] = CDF_RWRT; /* often 0x0020 */
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200698 cgc.cmd[8] = sizeof(buffer); /* often 0x18 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700699 cgc.quiet = 1;
700
701 if ((ret = cdi->ops->generic_packet(cdi, &cgc)))
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200702 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700703
704 memcpy(rfd, &buffer[sizeof(struct feature_header)], sizeof (*rfd));
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200705 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700706}
707
708static int cdrom_has_defect_mgt(struct cdrom_device_info *cdi)
709{
710 struct packet_command cgc;
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200711 char buffer[16];
Alexey Dobriyan56052d52005-12-01 17:10:40 -0500712 __be16 *feature_code;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700713 int ret;
714
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200715 init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700716
717 cgc.cmd[0] = GPCMD_GET_CONFIGURATION;
718 cgc.cmd[3] = CDF_HWDM;
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200719 cgc.cmd[8] = sizeof(buffer);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700720 cgc.quiet = 1;
721
722 if ((ret = cdi->ops->generic_packet(cdi, &cgc)))
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200723 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700724
Alexey Dobriyan56052d52005-12-01 17:10:40 -0500725 feature_code = (__be16 *) &buffer[sizeof(struct feature_header)];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700726 if (be16_to_cpu(*feature_code) == CDF_HWDM)
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200727 return 0;
728
729 return 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700730}
731
732
733static int cdrom_is_random_writable(struct cdrom_device_info *cdi, int *write)
734{
735 struct rwrt_feature_desc rfd;
736 int ret;
737
738 *write = 0;
739
740 if ((ret = cdrom_get_random_writable(cdi, &rfd)))
741 return ret;
742
743 if (CDF_RWRT == be16_to_cpu(rfd.feature_code))
744 *write = 1;
745
746 return 0;
747}
748
749static int cdrom_media_erasable(struct cdrom_device_info *cdi)
750{
751 disc_information di;
752 int ret;
753
754 ret = cdrom_get_disc_info(cdi, &di);
755 if (ret < 0 || ret < offsetof(typeof(di), n_first_track))
756 return -1;
757
758 return di.erasable;
759}
760
761/*
762 * FIXME: check RO bit
763 */
764static int cdrom_dvdram_open_write(struct cdrom_device_info *cdi)
765{
766 int ret = cdrom_media_erasable(cdi);
767
768 /*
769 * allow writable open if media info read worked and media is
770 * erasable, _or_ if it fails since not all drives support it
771 */
772 if (!ret)
773 return 1;
774
775 return 0;
776}
777
778static int cdrom_mrw_open_write(struct cdrom_device_info *cdi)
779{
780 disc_information di;
781 int ret;
782
783 /*
784 * always reset to DMA lba space on open
785 */
786 if (cdrom_mrw_set_lba_space(cdi, MRW_LBA_DMA)) {
Joe Perchese597cd02010-07-01 08:24:32 +0200787 pr_err("failed setting lba address space\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700788 return 1;
789 }
790
791 ret = cdrom_get_disc_info(cdi, &di);
792 if (ret < 0 || ret < offsetof(typeof(di),disc_type))
793 return 1;
794
795 if (!di.erasable)
796 return 1;
797
798 /*
799 * mrw_status
800 * 0 - not MRW formatted
801 * 1 - MRW bgformat started, but not running or complete
802 * 2 - MRW bgformat in progress
803 * 3 - MRW formatting complete
804 */
805 ret = 0;
Joe Perchese597cd02010-07-01 08:24:32 +0200806 pr_info("open: mrw_status '%s'\n", mrw_format_status[di.mrw_status]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700807 if (!di.mrw_status)
808 ret = 1;
809 else if (di.mrw_status == CDM_MRW_BGFORMAT_INACTIVE &&
810 mrw_format_restart)
811 ret = cdrom_mrw_bgformat(cdi, 1);
812
813 return ret;
814}
815
816static int mo_open_write(struct cdrom_device_info *cdi)
817{
818 struct packet_command cgc;
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200819 char buffer[255];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700820 int ret;
821
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200822 init_cdrom_command(&cgc, &buffer, 4, CGC_DATA_READ);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700823 cgc.quiet = 1;
824
825 /*
826 * obtain write protect information as per
827 * drivers/scsi/sd.c:sd_read_write_protect_flag
828 */
829
830 ret = cdrom_mode_sense(cdi, &cgc, GPMODE_ALL_PAGES, 0);
831 if (ret)
832 ret = cdrom_mode_sense(cdi, &cgc, GPMODE_VENDOR_PAGE, 0);
833 if (ret) {
834 cgc.buflen = 255;
835 ret = cdrom_mode_sense(cdi, &cgc, GPMODE_ALL_PAGES, 0);
836 }
837
838 /* drive gave us no info, let the user go ahead */
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200839 if (ret)
840 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700841
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200842 return buffer[3] & 0x80;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700843}
844
845static int cdrom_ram_open_write(struct cdrom_device_info *cdi)
846{
847 struct rwrt_feature_desc rfd;
848 int ret;
849
850 if ((ret = cdrom_has_defect_mgt(cdi)))
851 return ret;
852
853 if ((ret = cdrom_get_random_writable(cdi, &rfd)))
854 return ret;
855 else if (CDF_RWRT == be16_to_cpu(rfd.feature_code))
856 ret = !rfd.curr;
857
Joe Perches5944b2c2014-05-04 17:05:02 -0700858 cd_dbg(CD_OPEN, "can open for random write\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700859 return ret;
860}
861
862static void cdrom_mmc3_profile(struct cdrom_device_info *cdi)
863{
864 struct packet_command cgc;
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200865 char buffer[32];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700866 int ret, mmc3_profile;
867
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200868 init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700869
870 cgc.cmd[0] = GPCMD_GET_CONFIGURATION;
871 cgc.cmd[1] = 0;
872 cgc.cmd[2] = cgc.cmd[3] = 0; /* Starting Feature Number */
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200873 cgc.cmd[8] = sizeof(buffer); /* Allocation Length */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700874 cgc.quiet = 1;
875
876 if ((ret = cdi->ops->generic_packet(cdi, &cgc)))
877 mmc3_profile = 0xffff;
878 else
879 mmc3_profile = (buffer[6] << 8) | buffer[7];
880
881 cdi->mmc3_profile = mmc3_profile;
882}
883
884static int cdrom_is_dvd_rw(struct cdrom_device_info *cdi)
885{
886 switch (cdi->mmc3_profile) {
887 case 0x12: /* DVD-RAM */
888 case 0x1A: /* DVD+RW */
Georgios Toptsidisf7e78682015-09-25 10:50:08 +0300889 case 0x43: /* BD-RE */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700890 return 0;
891 default:
892 return 1;
893 }
894}
895
896/*
897 * returns 0 for ok to open write, non-0 to disallow
898 */
899static int cdrom_open_write(struct cdrom_device_info *cdi)
900{
901 int mrw, mrw_write, ram_write;
902 int ret = 1;
903
904 mrw = 0;
905 if (!cdrom_is_mrw(cdi, &mrw_write))
906 mrw = 1;
907
908 if (CDROM_CAN(CDC_MO_DRIVE))
909 ram_write = 1;
910 else
911 (void) cdrom_is_random_writable(cdi, &ram_write);
912
913 if (mrw)
914 cdi->mask &= ~CDC_MRW;
915 else
916 cdi->mask |= CDC_MRW;
917
918 if (mrw_write)
919 cdi->mask &= ~CDC_MRW_W;
920 else
921 cdi->mask |= CDC_MRW_W;
922
923 if (ram_write)
924 cdi->mask &= ~CDC_RAM;
925 else
926 cdi->mask |= CDC_RAM;
927
928 if (CDROM_CAN(CDC_MRW_W))
929 ret = cdrom_mrw_open_write(cdi);
930 else if (CDROM_CAN(CDC_DVD_RAM))
931 ret = cdrom_dvdram_open_write(cdi);
932 else if (CDROM_CAN(CDC_RAM) &&
933 !CDROM_CAN(CDC_CD_R|CDC_CD_RW|CDC_DVD|CDC_DVD_R|CDC_MRW|CDC_MO_DRIVE))
934 ret = cdrom_ram_open_write(cdi);
935 else if (CDROM_CAN(CDC_MO_DRIVE))
936 ret = mo_open_write(cdi);
937 else if (!cdrom_is_dvd_rw(cdi))
938 ret = 0;
939
940 return ret;
941}
942
943static void cdrom_dvd_rw_close_write(struct cdrom_device_info *cdi)
944{
945 struct packet_command cgc;
946
947 if (cdi->mmc3_profile != 0x1a) {
Joe Perches5944b2c2014-05-04 17:05:02 -0700948 cd_dbg(CD_CLOSE, "%s: No DVD+RW\n", cdi->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700949 return;
950 }
951
952 if (!cdi->media_written) {
Joe Perches5944b2c2014-05-04 17:05:02 -0700953 cd_dbg(CD_CLOSE, "%s: DVD+RW media clean\n", cdi->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700954 return;
955 }
956
Joe Perchese597cd02010-07-01 08:24:32 +0200957 pr_info("%s: dirty DVD+RW media, \"finalizing\"\n", cdi->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700958
959 init_cdrom_command(&cgc, NULL, 0, CGC_DATA_NONE);
960 cgc.cmd[0] = GPCMD_FLUSH_CACHE;
961 cgc.timeout = 30*HZ;
962 cdi->ops->generic_packet(cdi, &cgc);
963
964 init_cdrom_command(&cgc, NULL, 0, CGC_DATA_NONE);
965 cgc.cmd[0] = GPCMD_CLOSE_TRACK;
966 cgc.timeout = 3000*HZ;
967 cgc.quiet = 1;
968 cdi->ops->generic_packet(cdi, &cgc);
969
970 init_cdrom_command(&cgc, NULL, 0, CGC_DATA_NONE);
971 cgc.cmd[0] = GPCMD_CLOSE_TRACK;
972 cgc.cmd[2] = 2; /* Close session */
973 cgc.quiet = 1;
974 cgc.timeout = 3000*HZ;
975 cdi->ops->generic_packet(cdi, &cgc);
976
977 cdi->media_written = 0;
978}
979
980static int cdrom_close_write(struct cdrom_device_info *cdi)
981{
982#if 0
983 return cdrom_flush_cache(cdi);
984#else
985 return 0;
986#endif
987}
988
Joe Perchesa8033932014-05-04 17:05:11 -0700989/* badly broken, I know. Is due for a fixup anytime. */
990static void cdrom_count_tracks(struct cdrom_device_info *cdi, tracktype *tracks)
991{
992 struct cdrom_tochdr header;
993 struct cdrom_tocentry entry;
994 int ret, i;
995 tracks->data = 0;
996 tracks->audio = 0;
997 tracks->cdi = 0;
998 tracks->xa = 0;
999 tracks->error = 0;
1000 cd_dbg(CD_COUNT_TRACKS, "entering cdrom_count_tracks\n");
Diego Elio Pettenò3f58a3f2019-11-19 21:37:08 +00001001
1002 if (!CDROM_CAN(CDC_PLAY_AUDIO)) {
1003 tracks->error = CDS_NO_INFO;
1004 return;
1005 }
1006
Joe Perchesa8033932014-05-04 17:05:11 -07001007 /* Grab the TOC header so we can see how many tracks there are */
1008 ret = cdi->ops->audio_ioctl(cdi, CDROMREADTOCHDR, &header);
1009 if (ret) {
1010 if (ret == -ENOMEDIUM)
1011 tracks->error = CDS_NO_DISC;
1012 else
1013 tracks->error = CDS_NO_INFO;
1014 return;
1015 }
1016 /* check what type of tracks are on this disc */
1017 entry.cdte_format = CDROM_MSF;
1018 for (i = header.cdth_trk0; i <= header.cdth_trk1; i++) {
1019 entry.cdte_track = i;
1020 if (cdi->ops->audio_ioctl(cdi, CDROMREADTOCENTRY, &entry)) {
1021 tracks->error = CDS_NO_INFO;
1022 return;
1023 }
1024 if (entry.cdte_ctrl & CDROM_DATA_TRACK) {
1025 if (entry.cdte_format == 0x10)
1026 tracks->cdi++;
1027 else if (entry.cdte_format == 0x20)
1028 tracks->xa++;
1029 else
1030 tracks->data++;
1031 } else {
1032 tracks->audio++;
1033 }
1034 cd_dbg(CD_COUNT_TRACKS, "track %d: format=%d, ctrl=%d\n",
1035 i, entry.cdte_format, entry.cdte_ctrl);
1036 }
1037 cd_dbg(CD_COUNT_TRACKS, "disc has %d tracks: %d=audio %d=data %d=Cd-I %d=XA\n",
1038 header.cdth_trk1, tracks->audio, tracks->data,
1039 tracks->cdi, tracks->xa);
1040}
1041
Linus Torvalds1da177e2005-04-16 15:20:36 -07001042static
Joe Perches82b91542014-05-04 17:05:05 -07001043int open_for_data(struct cdrom_device_info *cdi)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001044{
1045 int ret;
1046 struct cdrom_device_ops *cdo = cdi->ops;
1047 tracktype tracks;
Joe Perches5944b2c2014-05-04 17:05:02 -07001048 cd_dbg(CD_OPEN, "entering open_for_data\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001049 /* Check if the driver can report drive status. If it can, we
1050 can do clever things. If it can't, well, we at least tried! */
1051 if (cdo->drive_status != NULL) {
1052 ret = cdo->drive_status(cdi, CDSL_CURRENT);
Joe Perches5944b2c2014-05-04 17:05:02 -07001053 cd_dbg(CD_OPEN, "drive_status=%d\n", ret);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001054 if (ret == CDS_TRAY_OPEN) {
Joe Perches5944b2c2014-05-04 17:05:02 -07001055 cd_dbg(CD_OPEN, "the tray is open...\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001056 /* can/may i close it? */
1057 if (CDROM_CAN(CDC_CLOSE_TRAY) &&
1058 cdi->options & CDO_AUTO_CLOSE) {
Joe Perches5944b2c2014-05-04 17:05:02 -07001059 cd_dbg(CD_OPEN, "trying to close the tray\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001060 ret=cdo->tray_move(cdi,0);
1061 if (ret) {
Joe Perches5944b2c2014-05-04 17:05:02 -07001062 cd_dbg(CD_OPEN, "bummer. tried to close the tray but failed.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001063 /* Ignore the error from the low
1064 level driver. We don't care why it
1065 couldn't close the tray. We only care
1066 that there is no disc in the drive,
1067 since that is the _REAL_ problem here.*/
1068 ret=-ENOMEDIUM;
1069 goto clean_up_and_return;
1070 }
1071 } else {
Joe Perches5944b2c2014-05-04 17:05:02 -07001072 cd_dbg(CD_OPEN, "bummer. this drive can't close the tray.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001073 ret=-ENOMEDIUM;
1074 goto clean_up_and_return;
1075 }
1076 /* Ok, the door should be closed now.. Check again */
1077 ret = cdo->drive_status(cdi, CDSL_CURRENT);
1078 if ((ret == CDS_NO_DISC) || (ret==CDS_TRAY_OPEN)) {
Joe Perches5944b2c2014-05-04 17:05:02 -07001079 cd_dbg(CD_OPEN, "bummer. the tray is still not closed.\n");
1080 cd_dbg(CD_OPEN, "tray might not contain a medium\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001081 ret=-ENOMEDIUM;
1082 goto clean_up_and_return;
1083 }
Joe Perches5944b2c2014-05-04 17:05:02 -07001084 cd_dbg(CD_OPEN, "the tray is now closed\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001085 }
1086 /* the door should be closed now, check for the disc */
1087 ret = cdo->drive_status(cdi, CDSL_CURRENT);
1088 if (ret!=CDS_DISC_OK) {
1089 ret = -ENOMEDIUM;
1090 goto clean_up_and_return;
1091 }
1092 }
1093 cdrom_count_tracks(cdi, &tracks);
1094 if (tracks.error == CDS_NO_DISC) {
Joe Perches5944b2c2014-05-04 17:05:02 -07001095 cd_dbg(CD_OPEN, "bummer. no disc.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001096 ret=-ENOMEDIUM;
1097 goto clean_up_and_return;
1098 }
1099 /* CD-Players which don't use O_NONBLOCK, workman
1100 * for example, need bit CDO_CHECK_TYPE cleared! */
1101 if (tracks.data==0) {
1102 if (cdi->options & CDO_CHECK_TYPE) {
1103 /* give people a warning shot, now that CDO_CHECK_TYPE
1104 is the default case! */
Joe Perches5944b2c2014-05-04 17:05:02 -07001105 cd_dbg(CD_OPEN, "bummer. wrong media type.\n");
1106 cd_dbg(CD_WARNING, "pid %d must open device O_NONBLOCK!\n",
1107 (unsigned int)task_pid_nr(current));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001108 ret=-EMEDIUMTYPE;
1109 goto clean_up_and_return;
1110 }
1111 else {
Joe Perches5944b2c2014-05-04 17:05:02 -07001112 cd_dbg(CD_OPEN, "wrong media type, but CDO_CHECK_TYPE not set\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001113 }
1114 }
1115
Joe Perches5944b2c2014-05-04 17:05:02 -07001116 cd_dbg(CD_OPEN, "all seems well, opening the devicen");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001117
1118 /* all seems well, we can open the device */
1119 ret = cdo->open(cdi, 0); /* open for data */
Joe Perches5944b2c2014-05-04 17:05:02 -07001120 cd_dbg(CD_OPEN, "opening the device gave me %d\n", ret);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001121 /* After all this careful checking, we shouldn't have problems
1122 opening the device, but we don't want the device locked if
1123 this somehow fails... */
1124 if (ret) {
Joe Perches5944b2c2014-05-04 17:05:02 -07001125 cd_dbg(CD_OPEN, "open device failed\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001126 goto clean_up_and_return;
1127 }
1128 if (CDROM_CAN(CDC_LOCK) && (cdi->options & CDO_LOCK)) {
1129 cdo->lock_door(cdi, 1);
Joe Perches5944b2c2014-05-04 17:05:02 -07001130 cd_dbg(CD_OPEN, "door locked\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001131 }
Joe Perches5944b2c2014-05-04 17:05:02 -07001132 cd_dbg(CD_OPEN, "device opened successfully\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001133 return ret;
1134
1135 /* Something failed. Try to unlock the drive, because some drivers
1136 (notably ide-cd) lock the drive after every command. This produced
1137 a nasty bug where after mount failed, the drive would remain locked!
1138 This ensures that the drive gets unlocked after a mount fails. This
1139 is a goto to avoid bloating the driver with redundant code. */
1140clean_up_and_return:
Joe Perches5944b2c2014-05-04 17:05:02 -07001141 cd_dbg(CD_OPEN, "open failed\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001142 if (CDROM_CAN(CDC_LOCK) && cdi->options & CDO_LOCK) {
1143 cdo->lock_door(cdi, 0);
Joe Perches5944b2c2014-05-04 17:05:02 -07001144 cd_dbg(CD_OPEN, "door unlocked\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001145 }
1146 return ret;
1147}
1148
Joe Perches82b91542014-05-04 17:05:05 -07001149/* We use the open-option O_NONBLOCK to indicate that the
1150 * purpose of opening is only for subsequent ioctl() calls; no device
1151 * integrity checks are performed.
1152 *
1153 * We hope that all cd-player programs will adopt this convention. It
1154 * is in their own interest: device control becomes a lot easier
1155 * this way.
1156 */
1157int cdrom_open(struct cdrom_device_info *cdi, struct block_device *bdev,
1158 fmode_t mode)
1159{
1160 int ret;
1161
1162 cd_dbg(CD_OPEN, "entering cdrom_open\n");
1163
Joe Perches82b91542014-05-04 17:05:05 -07001164 /* if this was a O_NONBLOCK open and we should honor the flags,
1165 * do a quick open without drive/disc integrity checks. */
1166 cdi->use_count++;
1167 if ((mode & FMODE_NDELAY) && (cdi->options & CDO_USE_FFLAGS)) {
1168 ret = cdi->ops->open(cdi, 1);
1169 } else {
1170 ret = open_for_data(cdi);
1171 if (ret)
1172 goto err;
Diego Elio Pettenò3f58a3f2019-11-19 21:37:08 +00001173 if (CDROM_CAN(CDC_GENERIC_PACKET))
1174 cdrom_mmc3_profile(cdi);
Joe Perches82b91542014-05-04 17:05:05 -07001175 if (mode & FMODE_WRITE) {
1176 ret = -EROFS;
1177 if (cdrom_open_write(cdi))
1178 goto err_release;
1179 if (!CDROM_CAN(CDC_RAM))
1180 goto err_release;
1181 ret = 0;
1182 cdi->media_written = 0;
1183 }
1184 }
1185
1186 if (ret)
1187 goto err;
1188
1189 cd_dbg(CD_OPEN, "Use count for \"/dev/%s\" now %d\n",
1190 cdi->name, cdi->use_count);
1191 return 0;
1192err_release:
1193 if (CDROM_CAN(CDC_LOCK) && cdi->options & CDO_LOCK) {
1194 cdi->ops->lock_door(cdi, 0);
1195 cd_dbg(CD_OPEN, "door unlocked\n");
1196 }
1197 cdi->ops->release(cdi);
1198err:
1199 cdi->use_count--;
1200 return ret;
1201}
1202
Linus Torvalds1da177e2005-04-16 15:20:36 -07001203/* This code is similar to that in open_for_data. The routine is called
1204 whenever an audio play operation is requested.
1205*/
Adrian Bunkecb80c62008-03-04 11:23:51 +01001206static int check_for_audio_disc(struct cdrom_device_info * cdi,
1207 struct cdrom_device_ops * cdo)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001208{
1209 int ret;
1210 tracktype tracks;
Joe Perches5944b2c2014-05-04 17:05:02 -07001211 cd_dbg(CD_OPEN, "entering check_for_audio_disc\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001212 if (!(cdi->options & CDO_CHECK_TYPE))
1213 return 0;
1214 if (cdo->drive_status != NULL) {
1215 ret = cdo->drive_status(cdi, CDSL_CURRENT);
Joe Perches5944b2c2014-05-04 17:05:02 -07001216 cd_dbg(CD_OPEN, "drive_status=%d\n", ret);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001217 if (ret == CDS_TRAY_OPEN) {
Joe Perches5944b2c2014-05-04 17:05:02 -07001218 cd_dbg(CD_OPEN, "the tray is open...\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001219 /* can/may i close it? */
1220 if (CDROM_CAN(CDC_CLOSE_TRAY) &&
1221 cdi->options & CDO_AUTO_CLOSE) {
Joe Perches5944b2c2014-05-04 17:05:02 -07001222 cd_dbg(CD_OPEN, "trying to close the tray\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001223 ret=cdo->tray_move(cdi,0);
1224 if (ret) {
Joe Perches5944b2c2014-05-04 17:05:02 -07001225 cd_dbg(CD_OPEN, "bummer. tried to close tray but failed.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001226 /* Ignore the error from the low
1227 level driver. We don't care why it
1228 couldn't close the tray. We only care
1229 that there is no disc in the drive,
1230 since that is the _REAL_ problem here.*/
1231 return -ENOMEDIUM;
1232 }
1233 } else {
Joe Perches5944b2c2014-05-04 17:05:02 -07001234 cd_dbg(CD_OPEN, "bummer. this driver can't close the tray.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001235 return -ENOMEDIUM;
1236 }
1237 /* Ok, the door should be closed now.. Check again */
1238 ret = cdo->drive_status(cdi, CDSL_CURRENT);
1239 if ((ret == CDS_NO_DISC) || (ret==CDS_TRAY_OPEN)) {
Joe Perches5944b2c2014-05-04 17:05:02 -07001240 cd_dbg(CD_OPEN, "bummer. the tray is still not closed.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001241 return -ENOMEDIUM;
1242 }
1243 if (ret!=CDS_DISC_OK) {
Joe Perches5944b2c2014-05-04 17:05:02 -07001244 cd_dbg(CD_OPEN, "bummer. disc isn't ready.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001245 return -EIO;
1246 }
Joe Perches5944b2c2014-05-04 17:05:02 -07001247 cd_dbg(CD_OPEN, "the tray is now closed\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001248 }
1249 }
1250 cdrom_count_tracks(cdi, &tracks);
1251 if (tracks.error)
1252 return(tracks.error);
1253
1254 if (tracks.audio==0)
1255 return -EMEDIUMTYPE;
1256
1257 return 0;
1258}
1259
Al Virobbc1cc92007-10-07 17:54:28 -04001260void cdrom_release(struct cdrom_device_info *cdi, fmode_t mode)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001261{
1262 struct cdrom_device_ops *cdo = cdi->ops;
1263 int opened_for_data;
1264
Joe Perches5944b2c2014-05-04 17:05:02 -07001265 cd_dbg(CD_CLOSE, "entering cdrom_release\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001266
1267 if (cdi->use_count > 0)
1268 cdi->use_count--;
Borislav Petkov35841f72008-02-06 01:38:08 -08001269
1270 if (cdi->use_count == 0) {
Joe Perches5944b2c2014-05-04 17:05:02 -07001271 cd_dbg(CD_CLOSE, "Use count for \"/dev/%s\" now zero\n",
1272 cdi->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001273 cdrom_dvd_rw_close_write(cdi);
Borislav Petkov35841f72008-02-06 01:38:08 -08001274
Paolo Bonzinicdccaa92012-02-08 20:03:14 +01001275 if ((cdo->capability & CDC_LOCK) && !cdi->keeplocked) {
Joe Perches5944b2c2014-05-04 17:05:02 -07001276 cd_dbg(CD_CLOSE, "Unlocking door!\n");
Borislav Petkov35841f72008-02-06 01:38:08 -08001277 cdo->lock_door(cdi, 0);
1278 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001279 }
Borislav Petkov35841f72008-02-06 01:38:08 -08001280
Linus Torvalds1da177e2005-04-16 15:20:36 -07001281 opened_for_data = !(cdi->options & CDO_USE_FFLAGS) ||
Al Virobbc1cc92007-10-07 17:54:28 -04001282 !(mode & FMODE_NDELAY);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001283
1284 /*
1285 * flush cache on last write release
1286 */
1287 if (CDROM_CAN(CDC_RAM) && !cdi->use_count && cdi->for_data)
1288 cdrom_close_write(cdi);
1289
1290 cdo->release(cdi);
1291 if (cdi->use_count == 0) { /* last process that closes dev*/
1292 if (opened_for_data &&
1293 cdi->options & CDO_AUTO_EJECT && CDROM_CAN(CDC_OPEN_TRAY))
1294 cdo->tray_move(cdi, 1);
1295 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001296}
1297
1298static int cdrom_read_mech_status(struct cdrom_device_info *cdi,
1299 struct cdrom_changer_info *buf)
1300{
1301 struct packet_command cgc;
1302 struct cdrom_device_ops *cdo = cdi->ops;
1303 int length;
1304
1305 /*
1306 * Sanyo changer isn't spec compliant (doesn't use regular change
1307 * LOAD_UNLOAD command, and it doesn't implement the mech status
1308 * command below
1309 */
1310 if (cdi->sanyo_slot) {
1311 buf->hdr.nslots = 3;
1312 buf->hdr.curslot = cdi->sanyo_slot == 3 ? 0 : cdi->sanyo_slot;
1313 for (length = 0; length < 3; length++) {
1314 buf->slots[length].disc_present = 1;
1315 buf->slots[length].change = 0;
1316 }
1317 return 0;
1318 }
1319
1320 length = sizeof(struct cdrom_mechstat_header) +
1321 cdi->capacity * sizeof(struct cdrom_slot);
1322
1323 init_cdrom_command(&cgc, buf, length, CGC_DATA_READ);
1324 cgc.cmd[0] = GPCMD_MECHANISM_STATUS;
1325 cgc.cmd[8] = (length >> 8) & 0xff;
1326 cgc.cmd[9] = length & 0xff;
1327 return cdo->generic_packet(cdi, &cgc);
1328}
1329
1330static int cdrom_slot_status(struct cdrom_device_info *cdi, int slot)
1331{
1332 struct cdrom_changer_info *info;
1333 int ret;
1334
Joe Perches5944b2c2014-05-04 17:05:02 -07001335 cd_dbg(CD_CHANGER, "entering cdrom_slot_status()\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001336 if (cdi->sanyo_slot)
1337 return CDS_NO_INFO;
1338
1339 info = kmalloc(sizeof(*info), GFP_KERNEL);
1340 if (!info)
1341 return -ENOMEM;
1342
1343 if ((ret = cdrom_read_mech_status(cdi, info)))
1344 goto out_free;
1345
1346 if (info->slots[slot].disc_present)
1347 ret = CDS_DISC_OK;
1348 else
1349 ret = CDS_NO_DISC;
1350
1351out_free:
1352 kfree(info);
1353 return ret;
1354}
1355
1356/* Return the number of slots for an ATAPI/SCSI cdrom,
1357 * return 1 if not a changer.
1358 */
1359int cdrom_number_of_slots(struct cdrom_device_info *cdi)
1360{
1361 int status;
1362 int nslots = 1;
1363 struct cdrom_changer_info *info;
1364
Joe Perches5944b2c2014-05-04 17:05:02 -07001365 cd_dbg(CD_CHANGER, "entering cdrom_number_of_slots()\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001366 /* cdrom_read_mech_status requires a valid value for capacity: */
1367 cdi->capacity = 0;
1368
1369 info = kmalloc(sizeof(*info), GFP_KERNEL);
1370 if (!info)
1371 return -ENOMEM;
1372
1373 if ((status = cdrom_read_mech_status(cdi, info)) == 0)
1374 nslots = info->hdr.nslots;
1375
1376 kfree(info);
1377 return nslots;
1378}
1379
1380
1381/* If SLOT < 0, unload the current slot. Otherwise, try to load SLOT. */
1382static int cdrom_load_unload(struct cdrom_device_info *cdi, int slot)
1383{
1384 struct packet_command cgc;
1385
Joe Perches5944b2c2014-05-04 17:05:02 -07001386 cd_dbg(CD_CHANGER, "entering cdrom_load_unload()\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001387 if (cdi->sanyo_slot && slot < 0)
1388 return 0;
1389
1390 init_cdrom_command(&cgc, NULL, 0, CGC_DATA_NONE);
1391 cgc.cmd[0] = GPCMD_LOAD_UNLOAD;
1392 cgc.cmd[4] = 2 + (slot >= 0);
1393 cgc.cmd[8] = slot;
1394 cgc.timeout = 60 * HZ;
1395
1396 /* The Sanyo 3 CD changer uses byte 7 of the
1397 GPCMD_TEST_UNIT_READY to command to switch CDs instead of
1398 using the GPCMD_LOAD_UNLOAD opcode. */
1399 if (cdi->sanyo_slot && -1 < slot) {
1400 cgc.cmd[0] = GPCMD_TEST_UNIT_READY;
1401 cgc.cmd[7] = slot;
1402 cgc.cmd[4] = cgc.cmd[8] = 0;
1403 cdi->sanyo_slot = slot ? slot : 3;
1404 }
1405
1406 return cdi->ops->generic_packet(cdi, &cgc);
1407}
1408
1409static int cdrom_select_disc(struct cdrom_device_info *cdi, int slot)
1410{
1411 struct cdrom_changer_info *info;
1412 int curslot;
1413 int ret;
1414
Joe Perches5944b2c2014-05-04 17:05:02 -07001415 cd_dbg(CD_CHANGER, "entering cdrom_select_disc()\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001416 if (!CDROM_CAN(CDC_SELECT_DISC))
1417 return -EDRIVE_CANT_DO_THIS;
1418
Tejun Heo2d921722010-12-08 20:57:38 +01001419 if (cdi->ops->check_events)
1420 cdi->ops->check_events(cdi, 0, slot);
1421 else
1422 cdi->ops->media_changed(cdi, slot);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001423
1424 if (slot == CDSL_NONE) {
1425 /* set media changed bits, on both queues */
1426 cdi->mc_flags = 0x3;
1427 return cdrom_load_unload(cdi, -1);
1428 }
1429
1430 info = kmalloc(sizeof(*info), GFP_KERNEL);
1431 if (!info)
1432 return -ENOMEM;
1433
1434 if ((ret = cdrom_read_mech_status(cdi, info))) {
1435 kfree(info);
1436 return ret;
1437 }
1438
1439 curslot = info->hdr.curslot;
1440 kfree(info);
1441
Paolo Bonzinicdccaa92012-02-08 20:03:14 +01001442 if (cdi->use_count > 1 || cdi->keeplocked) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001443 if (slot == CDSL_CURRENT) {
1444 return curslot;
1445 } else {
1446 return -EBUSY;
1447 }
1448 }
1449
1450 /* Specifying CDSL_CURRENT will attempt to load the currnet slot,
1451 which is useful if it had been previously unloaded.
1452 Whether it can or not, it returns the current slot.
1453 Similarly, if slot happens to be the current one, we still
1454 try and load it. */
1455 if (slot == CDSL_CURRENT)
1456 slot = curslot;
1457
1458 /* set media changed bits on both queues */
1459 cdi->mc_flags = 0x3;
1460 if ((ret = cdrom_load_unload(cdi, slot)))
1461 return ret;
1462
1463 return slot;
1464}
1465
Tejun Heo2d921722010-12-08 20:57:38 +01001466/*
1467 * As cdrom implements an extra ioctl consumer for media changed
1468 * event, it needs to buffer ->check_events() output, such that event
1469 * is not lost for both the usual VFS and ioctl paths.
1470 * cdi->{vfs|ioctl}_events are used to buffer pending events for each
1471 * path.
1472 *
1473 * XXX: Locking is non-existent. cdi->ops->check_events() can be
1474 * called in parallel and buffering fields are accessed without any
1475 * exclusion. The original media_changed code had the same problem.
1476 * It might be better to simply deprecate CDROM_MEDIA_CHANGED ioctl
1477 * and remove this cruft altogether. It doesn't have much usefulness
1478 * at this point.
1479 */
1480static void cdrom_update_events(struct cdrom_device_info *cdi,
1481 unsigned int clearing)
1482{
1483 unsigned int events;
1484
1485 events = cdi->ops->check_events(cdi, clearing, CDSL_CURRENT);
1486 cdi->vfs_events |= events;
1487 cdi->ioctl_events |= events;
1488}
1489
1490unsigned int cdrom_check_events(struct cdrom_device_info *cdi,
1491 unsigned int clearing)
1492{
1493 unsigned int events;
1494
1495 cdrom_update_events(cdi, clearing);
1496 events = cdi->vfs_events;
1497 cdi->vfs_events = 0;
1498 return events;
1499}
Jens Axboe30a7caa2010-12-16 17:58:50 +01001500EXPORT_SYMBOL(cdrom_check_events);
Tejun Heo2d921722010-12-08 20:57:38 +01001501
Linus Torvalds1da177e2005-04-16 15:20:36 -07001502/* We want to make media_changed accessible to the user through an
1503 * ioctl. The main problem now is that we must double-buffer the
1504 * low-level implementation, to assure that the VFS and the user both
1505 * see a medium change once.
1506 */
1507
1508static
1509int media_changed(struct cdrom_device_info *cdi, int queue)
1510{
1511 unsigned int mask = (1 << (queue & 1));
1512 int ret = !!(cdi->mc_flags & mask);
Tejun Heo2d921722010-12-08 20:57:38 +01001513 bool changed;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001514
1515 if (!CDROM_CAN(CDC_MEDIA_CHANGED))
Tejun Heo2d921722010-12-08 20:57:38 +01001516 return ret;
1517
Linus Torvalds1da177e2005-04-16 15:20:36 -07001518 /* changed since last call? */
Tejun Heo2d921722010-12-08 20:57:38 +01001519 if (cdi->ops->check_events) {
1520 BUG_ON(!queue); /* shouldn't be called from VFS path */
1521 cdrom_update_events(cdi, DISK_EVENT_MEDIA_CHANGE);
1522 changed = cdi->ioctl_events & DISK_EVENT_MEDIA_CHANGE;
1523 cdi->ioctl_events = 0;
1524 } else
1525 changed = cdi->ops->media_changed(cdi, CDSL_CURRENT);
1526
1527 if (changed) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001528 cdi->mc_flags = 0x3; /* set bit on both queues */
1529 ret |= 1;
1530 cdi->media_written = 0;
1531 }
Tejun Heo2d921722010-12-08 20:57:38 +01001532
Linus Torvalds1da177e2005-04-16 15:20:36 -07001533 cdi->mc_flags &= ~mask; /* clear bit */
1534 return ret;
1535}
1536
1537int cdrom_media_changed(struct cdrom_device_info *cdi)
1538{
1539 /* This talks to the VFS, which doesn't like errors - just 1 or 0.
1540 * Returning "0" is always safe (media hasn't been changed). Do that
1541 * if the low-level cdrom driver dosn't support media changed. */
1542 if (cdi == NULL || cdi->ops->media_changed == NULL)
1543 return 0;
1544 if (!CDROM_CAN(CDC_MEDIA_CHANGED))
1545 return 0;
1546 return media_changed(cdi, 0);
1547}
1548
Linus Torvalds1da177e2005-04-16 15:20:36 -07001549/* Requests to the low-level drivers will /always/ be done in the
1550 following format convention:
1551
1552 CDROM_LBA: all data-related requests.
1553 CDROM_MSF: all audio-related requests.
1554
1555 However, a low-level implementation is allowed to refuse this
1556 request, and return information in its own favorite format.
1557
1558 It doesn't make sense /at all/ to ask for a play_audio in LBA
1559 format, or ask for multi-session info in MSF format. However, for
1560 backward compatibility these format requests will be satisfied, but
1561 the requests to the low-level drivers will be sanitized in the more
1562 meaningful format indicated above.
1563 */
1564
1565static
1566void sanitize_format(union cdrom_addr *addr,
1567 u_char * curr, u_char requested)
1568{
1569 if (*curr == requested)
1570 return; /* nothing to be done! */
1571 if (requested == CDROM_LBA) {
1572 addr->lba = (int) addr->msf.frame +
1573 75 * (addr->msf.second - 2 + 60 * addr->msf.minute);
1574 } else { /* CDROM_MSF */
1575 int lba = addr->lba;
1576 addr->msf.frame = lba % 75;
1577 lba /= 75;
1578 lba += 2;
1579 addr->msf.second = lba % 60;
1580 addr->msf.minute = lba / 60;
1581 }
1582 *curr = requested;
1583}
1584
1585void init_cdrom_command(struct packet_command *cgc, void *buf, int len,
1586 int type)
1587{
1588 memset(cgc, 0, sizeof(struct packet_command));
1589 if (buf)
1590 memset(buf, 0, len);
1591 cgc->buffer = (char *) buf;
1592 cgc->buflen = len;
1593 cgc->data_direction = type;
Jens Axboe2e11c202007-01-03 08:10:35 +01001594 cgc->timeout = CDROM_DEF_TIMEOUT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001595}
1596
1597/* DVD handling */
1598
1599#define copy_key(dest,src) memcpy((dest), (src), sizeof(dvd_key))
1600#define copy_chal(dest,src) memcpy((dest), (src), sizeof(dvd_challenge))
1601
1602static void setup_report_key(struct packet_command *cgc, unsigned agid, unsigned type)
1603{
1604 cgc->cmd[0] = GPCMD_REPORT_KEY;
1605 cgc->cmd[10] = type | (agid << 6);
1606 switch (type) {
1607 case 0: case 8: case 5: {
1608 cgc->buflen = 8;
1609 break;
1610 }
1611 case 1: {
1612 cgc->buflen = 16;
1613 break;
1614 }
1615 case 2: case 4: {
1616 cgc->buflen = 12;
1617 break;
1618 }
1619 }
1620 cgc->cmd[9] = cgc->buflen;
1621 cgc->data_direction = CGC_DATA_READ;
1622}
1623
1624static void setup_send_key(struct packet_command *cgc, unsigned agid, unsigned type)
1625{
1626 cgc->cmd[0] = GPCMD_SEND_KEY;
1627 cgc->cmd[10] = type | (agid << 6);
1628 switch (type) {
1629 case 1: {
1630 cgc->buflen = 16;
1631 break;
1632 }
1633 case 3: {
1634 cgc->buflen = 12;
1635 break;
1636 }
1637 case 6: {
1638 cgc->buflen = 8;
1639 break;
1640 }
1641 }
1642 cgc->cmd[9] = cgc->buflen;
1643 cgc->data_direction = CGC_DATA_WRITE;
1644}
1645
1646static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai)
1647{
1648 int ret;
FUJITA Tomonorifce53842008-07-04 09:33:01 +02001649 u_char buf[20];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001650 struct packet_command cgc;
1651 struct cdrom_device_ops *cdo = cdi->ops;
FUJITA Tomonorifce53842008-07-04 09:33:01 +02001652 rpc_state_t rpc_state;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001653
FUJITA Tomonorifce53842008-07-04 09:33:01 +02001654 memset(buf, 0, sizeof(buf));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001655 init_cdrom_command(&cgc, buf, 0, CGC_DATA_READ);
1656
1657 switch (ai->type) {
1658 /* LU data send */
1659 case DVD_LU_SEND_AGID:
Joe Perches5944b2c2014-05-04 17:05:02 -07001660 cd_dbg(CD_DVD, "entering DVD_LU_SEND_AGID\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001661 cgc.quiet = 1;
1662 setup_report_key(&cgc, ai->lsa.agid, 0);
1663
1664 if ((ret = cdo->generic_packet(cdi, &cgc)))
FUJITA Tomonorifce53842008-07-04 09:33:01 +02001665 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001666
1667 ai->lsa.agid = buf[7] >> 6;
1668 /* Returning data, let host change state */
1669 break;
1670
1671 case DVD_LU_SEND_KEY1:
Joe Perches5944b2c2014-05-04 17:05:02 -07001672 cd_dbg(CD_DVD, "entering DVD_LU_SEND_KEY1\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001673 setup_report_key(&cgc, ai->lsk.agid, 2);
1674
1675 if ((ret = cdo->generic_packet(cdi, &cgc)))
FUJITA Tomonorifce53842008-07-04 09:33:01 +02001676 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001677
1678 copy_key(ai->lsk.key, &buf[4]);
1679 /* Returning data, let host change state */
1680 break;
1681
1682 case DVD_LU_SEND_CHALLENGE:
Joe Perches5944b2c2014-05-04 17:05:02 -07001683 cd_dbg(CD_DVD, "entering DVD_LU_SEND_CHALLENGE\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001684 setup_report_key(&cgc, ai->lsc.agid, 1);
1685
1686 if ((ret = cdo->generic_packet(cdi, &cgc)))
FUJITA Tomonorifce53842008-07-04 09:33:01 +02001687 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001688
1689 copy_chal(ai->lsc.chal, &buf[4]);
1690 /* Returning data, let host change state */
1691 break;
1692
1693 /* Post-auth key */
1694 case DVD_LU_SEND_TITLE_KEY:
Joe Perches5944b2c2014-05-04 17:05:02 -07001695 cd_dbg(CD_DVD, "entering DVD_LU_SEND_TITLE_KEY\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001696 cgc.quiet = 1;
1697 setup_report_key(&cgc, ai->lstk.agid, 4);
1698 cgc.cmd[5] = ai->lstk.lba;
1699 cgc.cmd[4] = ai->lstk.lba >> 8;
1700 cgc.cmd[3] = ai->lstk.lba >> 16;
1701 cgc.cmd[2] = ai->lstk.lba >> 24;
1702
1703 if ((ret = cdo->generic_packet(cdi, &cgc)))
FUJITA Tomonorifce53842008-07-04 09:33:01 +02001704 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001705
1706 ai->lstk.cpm = (buf[4] >> 7) & 1;
1707 ai->lstk.cp_sec = (buf[4] >> 6) & 1;
1708 ai->lstk.cgms = (buf[4] >> 4) & 3;
1709 copy_key(ai->lstk.title_key, &buf[5]);
1710 /* Returning data, let host change state */
1711 break;
1712
1713 case DVD_LU_SEND_ASF:
Joe Perches5944b2c2014-05-04 17:05:02 -07001714 cd_dbg(CD_DVD, "entering DVD_LU_SEND_ASF\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001715 setup_report_key(&cgc, ai->lsasf.agid, 5);
1716
1717 if ((ret = cdo->generic_packet(cdi, &cgc)))
FUJITA Tomonorifce53842008-07-04 09:33:01 +02001718 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001719
1720 ai->lsasf.asf = buf[7] & 1;
1721 break;
1722
1723 /* LU data receive (LU changes state) */
1724 case DVD_HOST_SEND_CHALLENGE:
Joe Perches5944b2c2014-05-04 17:05:02 -07001725 cd_dbg(CD_DVD, "entering DVD_HOST_SEND_CHALLENGE\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001726 setup_send_key(&cgc, ai->hsc.agid, 1);
1727 buf[1] = 0xe;
1728 copy_chal(&buf[4], ai->hsc.chal);
1729
1730 if ((ret = cdo->generic_packet(cdi, &cgc)))
FUJITA Tomonorifce53842008-07-04 09:33:01 +02001731 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001732
1733 ai->type = DVD_LU_SEND_KEY1;
1734 break;
1735
1736 case DVD_HOST_SEND_KEY2:
Joe Perches5944b2c2014-05-04 17:05:02 -07001737 cd_dbg(CD_DVD, "entering DVD_HOST_SEND_KEY2\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001738 setup_send_key(&cgc, ai->hsk.agid, 3);
1739 buf[1] = 0xa;
1740 copy_key(&buf[4], ai->hsk.key);
1741
1742 if ((ret = cdo->generic_packet(cdi, &cgc))) {
1743 ai->type = DVD_AUTH_FAILURE;
FUJITA Tomonorifce53842008-07-04 09:33:01 +02001744 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001745 }
1746 ai->type = DVD_AUTH_ESTABLISHED;
1747 break;
1748
1749 /* Misc */
1750 case DVD_INVALIDATE_AGID:
1751 cgc.quiet = 1;
Joe Perches5944b2c2014-05-04 17:05:02 -07001752 cd_dbg(CD_DVD, "entering DVD_INVALIDATE_AGID\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001753 setup_report_key(&cgc, ai->lsa.agid, 0x3f);
1754 if ((ret = cdo->generic_packet(cdi, &cgc)))
FUJITA Tomonorifce53842008-07-04 09:33:01 +02001755 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001756 break;
1757
1758 /* Get region settings */
1759 case DVD_LU_SEND_RPC_STATE:
Joe Perches5944b2c2014-05-04 17:05:02 -07001760 cd_dbg(CD_DVD, "entering DVD_LU_SEND_RPC_STATE\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001761 setup_report_key(&cgc, 0, 8);
FUJITA Tomonorifce53842008-07-04 09:33:01 +02001762 memset(&rpc_state, 0, sizeof(rpc_state_t));
1763 cgc.buffer = (char *) &rpc_state;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001764
1765 if ((ret = cdo->generic_packet(cdi, &cgc)))
FUJITA Tomonorifce53842008-07-04 09:33:01 +02001766 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001767
FUJITA Tomonorifce53842008-07-04 09:33:01 +02001768 ai->lrpcs.type = rpc_state.type_code;
1769 ai->lrpcs.vra = rpc_state.vra;
1770 ai->lrpcs.ucca = rpc_state.ucca;
1771 ai->lrpcs.region_mask = rpc_state.region_mask;
1772 ai->lrpcs.rpc_scheme = rpc_state.rpc_scheme;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001773 break;
1774
1775 /* Set region settings */
1776 case DVD_HOST_SEND_RPC_STATE:
Joe Perches5944b2c2014-05-04 17:05:02 -07001777 cd_dbg(CD_DVD, "entering DVD_HOST_SEND_RPC_STATE\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001778 setup_send_key(&cgc, 0, 6);
1779 buf[1] = 6;
1780 buf[4] = ai->hrpcs.pdrc;
1781
1782 if ((ret = cdo->generic_packet(cdi, &cgc)))
FUJITA Tomonorifce53842008-07-04 09:33:01 +02001783 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001784 break;
1785
1786 default:
Joe Perches5944b2c2014-05-04 17:05:02 -07001787 cd_dbg(CD_WARNING, "Invalid DVD key ioctl (%d)\n", ai->type);
FUJITA Tomonorifce53842008-07-04 09:33:01 +02001788 return -ENOTTY;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001789 }
FUJITA Tomonorifce53842008-07-04 09:33:01 +02001790
1791 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001792}
1793
Marcin Slusarzd1941392008-11-16 19:06:37 +01001794static int dvd_read_physical(struct cdrom_device_info *cdi, dvd_struct *s,
1795 struct packet_command *cgc)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001796{
FUJITA Tomonorifce53842008-07-04 09:33:01 +02001797 unsigned char buf[21], *base;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001798 struct dvd_layer *layer;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001799 struct cdrom_device_ops *cdo = cdi->ops;
1800 int ret, layer_num = s->physical.layer_num;
1801
1802 if (layer_num >= DVD_LAYERS)
1803 return -EINVAL;
1804
Marcin Slusarzd1941392008-11-16 19:06:37 +01001805 init_cdrom_command(cgc, buf, sizeof(buf), CGC_DATA_READ);
1806 cgc->cmd[0] = GPCMD_READ_DVD_STRUCTURE;
1807 cgc->cmd[6] = layer_num;
1808 cgc->cmd[7] = s->type;
1809 cgc->cmd[9] = cgc->buflen & 0xff;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001810
1811 /*
1812 * refrain from reporting errors on non-existing layers (mainly)
1813 */
Marcin Slusarzd1941392008-11-16 19:06:37 +01001814 cgc->quiet = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001815
Marcin Slusarzd1941392008-11-16 19:06:37 +01001816 ret = cdo->generic_packet(cdi, cgc);
1817 if (ret)
FUJITA Tomonorifce53842008-07-04 09:33:01 +02001818 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001819
1820 base = &buf[4];
1821 layer = &s->physical.layer[layer_num];
1822
1823 /*
1824 * place the data... really ugly, but at least we won't have to
1825 * worry about endianess in userspace.
1826 */
1827 memset(layer, 0, sizeof(*layer));
1828 layer->book_version = base[0] & 0xf;
1829 layer->book_type = base[0] >> 4;
1830 layer->min_rate = base[1] & 0xf;
1831 layer->disc_size = base[1] >> 4;
1832 layer->layer_type = base[2] & 0xf;
1833 layer->track_path = (base[2] >> 4) & 1;
1834 layer->nlayers = (base[2] >> 5) & 3;
1835 layer->track_density = base[3] & 0xf;
1836 layer->linear_density = base[3] >> 4;
1837 layer->start_sector = base[5] << 16 | base[6] << 8 | base[7];
1838 layer->end_sector = base[9] << 16 | base[10] << 8 | base[11];
1839 layer->end_sector_l0 = base[13] << 16 | base[14] << 8 | base[15];
1840 layer->bca = base[16] >> 7;
1841
FUJITA Tomonorifce53842008-07-04 09:33:01 +02001842 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001843}
1844
Marcin Slusarzd1941392008-11-16 19:06:37 +01001845static int dvd_read_copyright(struct cdrom_device_info *cdi, dvd_struct *s,
1846 struct packet_command *cgc)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001847{
1848 int ret;
FUJITA Tomonorifce53842008-07-04 09:33:01 +02001849 u_char buf[8];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001850 struct cdrom_device_ops *cdo = cdi->ops;
1851
Marcin Slusarzd1941392008-11-16 19:06:37 +01001852 init_cdrom_command(cgc, buf, sizeof(buf), CGC_DATA_READ);
1853 cgc->cmd[0] = GPCMD_READ_DVD_STRUCTURE;
1854 cgc->cmd[6] = s->copyright.layer_num;
1855 cgc->cmd[7] = s->type;
1856 cgc->cmd[8] = cgc->buflen >> 8;
1857 cgc->cmd[9] = cgc->buflen & 0xff;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001858
Marcin Slusarzd1941392008-11-16 19:06:37 +01001859 ret = cdo->generic_packet(cdi, cgc);
1860 if (ret)
FUJITA Tomonorifce53842008-07-04 09:33:01 +02001861 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001862
1863 s->copyright.cpst = buf[4];
1864 s->copyright.rmi = buf[5];
1865
FUJITA Tomonorifce53842008-07-04 09:33:01 +02001866 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001867}
1868
Marcin Slusarzd1941392008-11-16 19:06:37 +01001869static int dvd_read_disckey(struct cdrom_device_info *cdi, dvd_struct *s,
1870 struct packet_command *cgc)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001871{
1872 int ret, size;
1873 u_char *buf;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001874 struct cdrom_device_ops *cdo = cdi->ops;
1875
1876 size = sizeof(s->disckey.value) + 4;
1877
Marcin Slusarzd1941392008-11-16 19:06:37 +01001878 buf = kmalloc(size, GFP_KERNEL);
1879 if (!buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001880 return -ENOMEM;
1881
Marcin Slusarzd1941392008-11-16 19:06:37 +01001882 init_cdrom_command(cgc, buf, size, CGC_DATA_READ);
1883 cgc->cmd[0] = GPCMD_READ_DVD_STRUCTURE;
1884 cgc->cmd[7] = s->type;
1885 cgc->cmd[8] = size >> 8;
1886 cgc->cmd[9] = size & 0xff;
1887 cgc->cmd[10] = s->disckey.agid << 6;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001888
Marcin Slusarzd1941392008-11-16 19:06:37 +01001889 ret = cdo->generic_packet(cdi, cgc);
1890 if (!ret)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001891 memcpy(s->disckey.value, &buf[4], sizeof(s->disckey.value));
1892
1893 kfree(buf);
1894 return ret;
1895}
1896
Marcin Slusarzd1941392008-11-16 19:06:37 +01001897static int dvd_read_bca(struct cdrom_device_info *cdi, dvd_struct *s,
1898 struct packet_command *cgc)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001899{
Marcin Slusarzd1941392008-11-16 19:06:37 +01001900 int ret, size = 4 + 188;
1901 u_char *buf;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001902 struct cdrom_device_ops *cdo = cdi->ops;
1903
Marcin Slusarzd1941392008-11-16 19:06:37 +01001904 buf = kmalloc(size, GFP_KERNEL);
1905 if (!buf)
1906 return -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001907
Marcin Slusarzd1941392008-11-16 19:06:37 +01001908 init_cdrom_command(cgc, buf, size, CGC_DATA_READ);
1909 cgc->cmd[0] = GPCMD_READ_DVD_STRUCTURE;
1910 cgc->cmd[7] = s->type;
1911 cgc->cmd[9] = cgc->buflen & 0xff;
1912
1913 ret = cdo->generic_packet(cdi, cgc);
1914 if (ret)
1915 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001916
1917 s->bca.len = buf[0] << 8 | buf[1];
1918 if (s->bca.len < 12 || s->bca.len > 188) {
Joe Perches5944b2c2014-05-04 17:05:02 -07001919 cd_dbg(CD_WARNING, "Received invalid BCA length (%d)\n",
1920 s->bca.len);
Marcin Slusarzd1941392008-11-16 19:06:37 +01001921 ret = -EIO;
1922 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001923 }
1924 memcpy(s->bca.value, &buf[4], s->bca.len);
Marcin Slusarzd1941392008-11-16 19:06:37 +01001925 ret = 0;
1926out:
1927 kfree(buf);
1928 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001929}
1930
Marcin Slusarzd1941392008-11-16 19:06:37 +01001931static int dvd_read_manufact(struct cdrom_device_info *cdi, dvd_struct *s,
1932 struct packet_command *cgc)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001933{
1934 int ret = 0, size;
1935 u_char *buf;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001936 struct cdrom_device_ops *cdo = cdi->ops;
1937
1938 size = sizeof(s->manufact.value) + 4;
1939
Marcin Slusarzd1941392008-11-16 19:06:37 +01001940 buf = kmalloc(size, GFP_KERNEL);
1941 if (!buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001942 return -ENOMEM;
1943
Marcin Slusarzd1941392008-11-16 19:06:37 +01001944 init_cdrom_command(cgc, buf, size, CGC_DATA_READ);
1945 cgc->cmd[0] = GPCMD_READ_DVD_STRUCTURE;
1946 cgc->cmd[7] = s->type;
1947 cgc->cmd[8] = size >> 8;
1948 cgc->cmd[9] = size & 0xff;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001949
Marcin Slusarzd1941392008-11-16 19:06:37 +01001950 ret = cdo->generic_packet(cdi, cgc);
1951 if (ret)
1952 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001953
1954 s->manufact.len = buf[0] << 8 | buf[1];
Andrew Mortonaec9f372011-08-02 12:43:50 +02001955 if (s->manufact.len < 0) {
Joe Perches5944b2c2014-05-04 17:05:02 -07001956 cd_dbg(CD_WARNING, "Received invalid manufacture info length (%d)\n",
1957 s->manufact.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001958 ret = -EIO;
1959 } else {
Andrew Mortonaec9f372011-08-02 12:43:50 +02001960 if (s->manufact.len > 2048) {
Joe Perches5944b2c2014-05-04 17:05:02 -07001961 cd_dbg(CD_WARNING, "Received invalid manufacture info length (%d): truncating to 2048\n",
1962 s->manufact.len);
Andrew Mortonaec9f372011-08-02 12:43:50 +02001963 s->manufact.len = 2048;
1964 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001965 memcpy(s->manufact.value, &buf[4], s->manufact.len);
1966 }
1967
Marcin Slusarzd1941392008-11-16 19:06:37 +01001968out:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001969 kfree(buf);
1970 return ret;
1971}
1972
Marcin Slusarzd1941392008-11-16 19:06:37 +01001973static int dvd_read_struct(struct cdrom_device_info *cdi, dvd_struct *s,
1974 struct packet_command *cgc)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001975{
1976 switch (s->type) {
1977 case DVD_STRUCT_PHYSICAL:
Marcin Slusarzd1941392008-11-16 19:06:37 +01001978 return dvd_read_physical(cdi, s, cgc);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001979
1980 case DVD_STRUCT_COPYRIGHT:
Marcin Slusarzd1941392008-11-16 19:06:37 +01001981 return dvd_read_copyright(cdi, s, cgc);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001982
1983 case DVD_STRUCT_DISCKEY:
Marcin Slusarzd1941392008-11-16 19:06:37 +01001984 return dvd_read_disckey(cdi, s, cgc);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001985
1986 case DVD_STRUCT_BCA:
Marcin Slusarzd1941392008-11-16 19:06:37 +01001987 return dvd_read_bca(cdi, s, cgc);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001988
1989 case DVD_STRUCT_MANUFACT:
Marcin Slusarzd1941392008-11-16 19:06:37 +01001990 return dvd_read_manufact(cdi, s, cgc);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001991
1992 default:
Joe Perches5944b2c2014-05-04 17:05:02 -07001993 cd_dbg(CD_WARNING, ": Invalid DVD structure read requested (%d)\n",
1994 s->type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001995 return -EINVAL;
1996 }
1997}
1998
1999int cdrom_mode_sense(struct cdrom_device_info *cdi,
2000 struct packet_command *cgc,
2001 int page_code, int page_control)
2002{
2003 struct cdrom_device_ops *cdo = cdi->ops;
2004
2005 memset(cgc->cmd, 0, sizeof(cgc->cmd));
2006
2007 cgc->cmd[0] = GPCMD_MODE_SENSE_10;
2008 cgc->cmd[2] = page_code | (page_control << 6);
2009 cgc->cmd[7] = cgc->buflen >> 8;
2010 cgc->cmd[8] = cgc->buflen & 0xff;
2011 cgc->data_direction = CGC_DATA_READ;
2012 return cdo->generic_packet(cdi, cgc);
2013}
2014
2015int cdrom_mode_select(struct cdrom_device_info *cdi,
2016 struct packet_command *cgc)
2017{
2018 struct cdrom_device_ops *cdo = cdi->ops;
2019
2020 memset(cgc->cmd, 0, sizeof(cgc->cmd));
2021 memset(cgc->buffer, 0, 2);
2022 cgc->cmd[0] = GPCMD_MODE_SELECT_10;
2023 cgc->cmd[1] = 0x10; /* PF */
2024 cgc->cmd[7] = cgc->buflen >> 8;
2025 cgc->cmd[8] = cgc->buflen & 0xff;
2026 cgc->data_direction = CGC_DATA_WRITE;
2027 return cdo->generic_packet(cdi, cgc);
2028}
2029
2030static int cdrom_read_subchannel(struct cdrom_device_info *cdi,
2031 struct cdrom_subchnl *subchnl, int mcn)
2032{
2033 struct cdrom_device_ops *cdo = cdi->ops;
2034 struct packet_command cgc;
FUJITA Tomonorifce53842008-07-04 09:33:01 +02002035 char buffer[32];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002036 int ret;
2037
2038 init_cdrom_command(&cgc, buffer, 16, CGC_DATA_READ);
2039 cgc.cmd[0] = GPCMD_READ_SUBCHANNEL;
vchannaiahbf294e82016-06-29 08:18:25 -04002040 cgc.cmd[1] = subchnl->cdsc_format;/* MSF or LBA addressing */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002041 cgc.cmd[2] = 0x40; /* request subQ data */
2042 cgc.cmd[3] = mcn ? 2 : 1;
2043 cgc.cmd[8] = 16;
2044
2045 if ((ret = cdo->generic_packet(cdi, &cgc)))
FUJITA Tomonorifce53842008-07-04 09:33:01 +02002046 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002047
2048 subchnl->cdsc_audiostatus = cgc.buffer[1];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002049 subchnl->cdsc_ctrl = cgc.buffer[5] & 0xf;
2050 subchnl->cdsc_trk = cgc.buffer[6];
2051 subchnl->cdsc_ind = cgc.buffer[7];
2052
vchannaiahbf294e82016-06-29 08:18:25 -04002053 if (subchnl->cdsc_format == CDROM_LBA) {
2054 subchnl->cdsc_absaddr.lba = ((cgc.buffer[8] << 24) |
2055 (cgc.buffer[9] << 16) |
2056 (cgc.buffer[10] << 8) |
2057 (cgc.buffer[11]));
2058 subchnl->cdsc_reladdr.lba = ((cgc.buffer[12] << 24) |
2059 (cgc.buffer[13] << 16) |
2060 (cgc.buffer[14] << 8) |
2061 (cgc.buffer[15]));
2062 } else {
2063 subchnl->cdsc_reladdr.msf.minute = cgc.buffer[13];
2064 subchnl->cdsc_reladdr.msf.second = cgc.buffer[14];
2065 subchnl->cdsc_reladdr.msf.frame = cgc.buffer[15];
2066 subchnl->cdsc_absaddr.msf.minute = cgc.buffer[9];
2067 subchnl->cdsc_absaddr.msf.second = cgc.buffer[10];
2068 subchnl->cdsc_absaddr.msf.frame = cgc.buffer[11];
2069 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002070
FUJITA Tomonorifce53842008-07-04 09:33:01 +02002071 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002072}
2073
2074/*
2075 * Specific READ_10 interface
2076 */
2077static int cdrom_read_cd(struct cdrom_device_info *cdi,
2078 struct packet_command *cgc, int lba,
2079 int blocksize, int nblocks)
2080{
2081 struct cdrom_device_ops *cdo = cdi->ops;
2082
2083 memset(&cgc->cmd, 0, sizeof(cgc->cmd));
2084 cgc->cmd[0] = GPCMD_READ_10;
2085 cgc->cmd[2] = (lba >> 24) & 0xff;
2086 cgc->cmd[3] = (lba >> 16) & 0xff;
2087 cgc->cmd[4] = (lba >> 8) & 0xff;
2088 cgc->cmd[5] = lba & 0xff;
2089 cgc->cmd[6] = (nblocks >> 16) & 0xff;
2090 cgc->cmd[7] = (nblocks >> 8) & 0xff;
2091 cgc->cmd[8] = nblocks & 0xff;
2092 cgc->buflen = blocksize * nblocks;
2093 return cdo->generic_packet(cdi, cgc);
2094}
2095
2096/* very generic interface for reading the various types of blocks */
2097static int cdrom_read_block(struct cdrom_device_info *cdi,
2098 struct packet_command *cgc,
2099 int lba, int nblocks, int format, int blksize)
2100{
2101 struct cdrom_device_ops *cdo = cdi->ops;
2102
2103 memset(&cgc->cmd, 0, sizeof(cgc->cmd));
2104 cgc->cmd[0] = GPCMD_READ_CD;
2105 /* expected sector size - cdda,mode1,etc. */
2106 cgc->cmd[1] = format << 2;
2107 /* starting address */
2108 cgc->cmd[2] = (lba >> 24) & 0xff;
2109 cgc->cmd[3] = (lba >> 16) & 0xff;
2110 cgc->cmd[4] = (lba >> 8) & 0xff;
2111 cgc->cmd[5] = lba & 0xff;
2112 /* number of blocks */
2113 cgc->cmd[6] = (nblocks >> 16) & 0xff;
2114 cgc->cmd[7] = (nblocks >> 8) & 0xff;
2115 cgc->cmd[8] = nblocks & 0xff;
2116 cgc->buflen = blksize * nblocks;
2117
2118 /* set the header info returned */
2119 switch (blksize) {
2120 case CD_FRAMESIZE_RAW0 : cgc->cmd[9] = 0x58; break;
2121 case CD_FRAMESIZE_RAW1 : cgc->cmd[9] = 0x78; break;
2122 case CD_FRAMESIZE_RAW : cgc->cmd[9] = 0xf8; break;
2123 default : cgc->cmd[9] = 0x10;
2124 }
2125
2126 return cdo->generic_packet(cdi, cgc);
2127}
2128
2129static int cdrom_read_cdda_old(struct cdrom_device_info *cdi, __u8 __user *ubuf,
2130 int lba, int nframes)
2131{
2132 struct packet_command cgc;
2133 int ret = 0;
2134 int nr;
2135
2136 cdi->last_sense = 0;
2137
2138 memset(&cgc, 0, sizeof(cgc));
2139
2140 /*
2141 * start with will ra.nframes size, back down if alloc fails
2142 */
2143 nr = nframes;
2144 do {
2145 cgc.buffer = kmalloc(CD_FRAMESIZE_RAW * nr, GFP_KERNEL);
2146 if (cgc.buffer)
2147 break;
2148
2149 nr >>= 1;
2150 } while (nr);
2151
2152 if (!nr)
2153 return -ENOMEM;
2154
Linus Torvalds1da177e2005-04-16 15:20:36 -07002155 cgc.data_direction = CGC_DATA_READ;
2156 while (nframes > 0) {
2157 if (nr > nframes)
2158 nr = nframes;
2159
2160 ret = cdrom_read_block(cdi, &cgc, lba, nr, 1, CD_FRAMESIZE_RAW);
2161 if (ret)
2162 break;
Dan Carpenter822bfa52012-02-06 10:20:45 +01002163 if (copy_to_user(ubuf, cgc.buffer, CD_FRAMESIZE_RAW * nr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002164 ret = -EFAULT;
2165 break;
2166 }
2167 ubuf += CD_FRAMESIZE_RAW * nr;
2168 nframes -= nr;
2169 lba += nr;
2170 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002171 kfree(cgc.buffer);
2172 return ret;
2173}
2174
2175static int cdrom_read_cdda_bpc(struct cdrom_device_info *cdi, __u8 __user *ubuf,
2176 int lba, int nframes)
2177{
Jens Axboe165125e2007-07-24 09:28:11 +02002178 struct request_queue *q = cdi->disk->queue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002179 struct request *rq;
2180 struct bio *bio;
2181 unsigned int len;
2182 int nr, ret = 0;
2183
2184 if (!q)
2185 return -ENXIO;
2186
2187 cdi->last_sense = 0;
2188
2189 while (nframes) {
2190 nr = nframes;
2191 if (cdi->cdda_method == CDDA_BPC_SINGLE)
2192 nr = 1;
Martin K. Petersenae03bf62009-05-22 17:17:50 -04002193 if (nr * CD_FRAMESIZE_RAW > (queue_max_sectors(q) << 9))
2194 nr = (queue_max_sectors(q) << 9) / CD_FRAMESIZE_RAW;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002195
2196 len = nr * CD_FRAMESIZE_RAW;
2197
Alan D. Brunellefebd7a52008-12-09 15:52:15 +01002198 rq = blk_get_request(q, READ, GFP_KERNEL);
Joe Lawrencea492f072014-08-28 08:15:21 -06002199 if (IS_ERR(rq)) {
2200 ret = PTR_ERR(rq);
Jens Axboedd1cab92005-06-20 14:06:01 +02002201 break;
Alan D. Brunellefebd7a52008-12-09 15:52:15 +01002202 }
Jens Axboef27b0872014-06-06 07:57:37 -06002203 blk_rq_set_block_pc(rq);
Alan D. Brunellefebd7a52008-12-09 15:52:15 +01002204
2205 ret = blk_rq_map_user(q, rq, NULL, ubuf, len, GFP_KERNEL);
2206 if (ret) {
2207 blk_put_request(rq);
2208 break;
2209 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002210
Linus Torvalds1da177e2005-04-16 15:20:36 -07002211 rq->cmd[0] = GPCMD_READ_CD;
2212 rq->cmd[1] = 1 << 2;
2213 rq->cmd[2] = (lba >> 24) & 0xff;
2214 rq->cmd[3] = (lba >> 16) & 0xff;
2215 rq->cmd[4] = (lba >> 8) & 0xff;
2216 rq->cmd[5] = lba & 0xff;
2217 rq->cmd[6] = (nr >> 16) & 0xff;
2218 rq->cmd[7] = (nr >> 8) & 0xff;
2219 rq->cmd[8] = nr & 0xff;
2220 rq->cmd[9] = 0xf8;
2221
2222 rq->cmd_len = 12;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002223 rq->timeout = 60 * HZ;
2224 bio = rq->bio;
2225
James Bottomley 994ca9a2005-06-20 14:11:09 +02002226 if (blk_execute_rq(q, cdi->disk, rq, 0)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002227 struct request_sense *s = rq->sense;
2228 ret = -EIO;
2229 cdi->last_sense = s->sense_key;
2230 }
2231
Jens Axboe8e5cfc42006-12-19 11:12:46 +01002232 if (blk_rq_unmap_user(bio))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002233 ret = -EFAULT;
Alan D. Brunellefebd7a52008-12-09 15:52:15 +01002234 blk_put_request(rq);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002235
2236 if (ret)
2237 break;
2238
2239 nframes -= nr;
2240 lba += nr;
2241 ubuf += len;
2242 }
2243
Linus Torvalds1da177e2005-04-16 15:20:36 -07002244 return ret;
2245}
2246
2247static int cdrom_read_cdda(struct cdrom_device_info *cdi, __u8 __user *ubuf,
2248 int lba, int nframes)
2249{
2250 int ret;
2251
2252 if (cdi->cdda_method == CDDA_OLD)
2253 return cdrom_read_cdda_old(cdi, ubuf, lba, nframes);
2254
2255retry:
2256 /*
2257 * for anything else than success and io error, we need to retry
2258 */
2259 ret = cdrom_read_cdda_bpc(cdi, ubuf, lba, nframes);
2260 if (!ret || ret != -EIO)
2261 return ret;
2262
2263 /*
2264 * I've seen drives get sense 4/8/3 udma crc errors on multi
2265 * frame dma, so drop to single frame dma if we need to
2266 */
2267 if (cdi->cdda_method == CDDA_BPC_FULL && nframes > 1) {
Joe Perchese597cd02010-07-01 08:24:32 +02002268 pr_info("dropping to single frame dma\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002269 cdi->cdda_method = CDDA_BPC_SINGLE;
2270 goto retry;
2271 }
2272
2273 /*
2274 * so we have an io error of some sort with multi frame dma. if the
2275 * condition wasn't a hardware error
2276 * problems, not for any error
2277 */
2278 if (cdi->last_sense != 0x04 && cdi->last_sense != 0x0b)
2279 return ret;
2280
Joe Perchese597cd02010-07-01 08:24:32 +02002281 pr_info("dropping to old style cdda (sense=%x)\n", cdi->last_sense);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002282 cdi->cdda_method = CDDA_OLD;
2283 return cdrom_read_cdda_old(cdi, ubuf, lba, nframes);
2284}
2285
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002286static int cdrom_ioctl_multisession(struct cdrom_device_info *cdi,
2287 void __user *argp)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002288{
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002289 struct cdrom_multisession ms_info;
2290 u8 requested_format;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002291 int ret;
2292
Joe Perches5944b2c2014-05-04 17:05:02 -07002293 cd_dbg(CD_DO_IOCTL, "entering CDROMMULTISESSION\n");
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002294
2295 if (!(cdi->ops->capability & CDC_MULTI_SESSION))
2296 return -ENOSYS;
2297
2298 if (copy_from_user(&ms_info, argp, sizeof(ms_info)))
2299 return -EFAULT;
2300
2301 requested_format = ms_info.addr_format;
2302 if (requested_format != CDROM_MSF && requested_format != CDROM_LBA)
2303 return -EINVAL;
2304 ms_info.addr_format = CDROM_LBA;
2305
2306 ret = cdi->ops->get_last_session(cdi, &ms_info);
2307 if (ret)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002308 return ret;
2309
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002310 sanitize_format(&ms_info.addr, &ms_info.addr_format, requested_format);
2311
2312 if (copy_to_user(argp, &ms_info, sizeof(ms_info)))
2313 return -EFAULT;
2314
Joe Perches5944b2c2014-05-04 17:05:02 -07002315 cd_dbg(CD_DO_IOCTL, "CDROMMULTISESSION successful\n");
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002316 return 0;
2317}
2318
2319static int cdrom_ioctl_eject(struct cdrom_device_info *cdi)
2320{
Joe Perches5944b2c2014-05-04 17:05:02 -07002321 cd_dbg(CD_DO_IOCTL, "entering CDROMEJECT\n");
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002322
2323 if (!CDROM_CAN(CDC_OPEN_TRAY))
2324 return -ENOSYS;
Paolo Bonzinicdccaa92012-02-08 20:03:14 +01002325 if (cdi->use_count != 1 || cdi->keeplocked)
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002326 return -EBUSY;
2327 if (CDROM_CAN(CDC_LOCK)) {
2328 int ret = cdi->ops->lock_door(cdi, 0);
2329 if (ret)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002330 return ret;
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002331 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002332
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002333 return cdi->ops->tray_move(cdi, 1);
2334}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002335
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002336static int cdrom_ioctl_closetray(struct cdrom_device_info *cdi)
2337{
Joe Perches5944b2c2014-05-04 17:05:02 -07002338 cd_dbg(CD_DO_IOCTL, "entering CDROMCLOSETRAY\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002339
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002340 if (!CDROM_CAN(CDC_CLOSE_TRAY))
2341 return -ENOSYS;
2342 return cdi->ops->tray_move(cdi, 0);
2343}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002344
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002345static int cdrom_ioctl_eject_sw(struct cdrom_device_info *cdi,
2346 unsigned long arg)
2347{
Joe Perches5944b2c2014-05-04 17:05:02 -07002348 cd_dbg(CD_DO_IOCTL, "entering CDROMEJECT_SW\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002349
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002350 if (!CDROM_CAN(CDC_OPEN_TRAY))
2351 return -ENOSYS;
Paolo Bonzinicdccaa92012-02-08 20:03:14 +01002352 if (cdi->keeplocked)
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002353 return -EBUSY;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002354
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002355 cdi->options &= ~(CDO_AUTO_CLOSE | CDO_AUTO_EJECT);
2356 if (arg)
2357 cdi->options |= CDO_AUTO_CLOSE | CDO_AUTO_EJECT;
2358 return 0;
2359}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002360
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002361static int cdrom_ioctl_media_changed(struct cdrom_device_info *cdi,
2362 unsigned long arg)
2363{
2364 struct cdrom_changer_info *info;
2365 int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002366
Joe Perches5944b2c2014-05-04 17:05:02 -07002367 cd_dbg(CD_DO_IOCTL, "entering CDROM_MEDIA_CHANGED\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002368
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002369 if (!CDROM_CAN(CDC_MEDIA_CHANGED))
2370 return -ENOSYS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002371
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002372 /* cannot select disc or select current disc */
2373 if (!CDROM_CAN(CDC_SELECT_DISC) || arg == CDSL_CURRENT)
2374 return media_changed(cdi, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002375
Dan Carpenter4bd744b2018-04-18 12:51:31 +03002376 if (arg >= cdi->capacity)
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002377 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002378
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002379 info = kmalloc(sizeof(*info), GFP_KERNEL);
2380 if (!info)
2381 return -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002382
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002383 ret = cdrom_read_mech_status(cdi, info);
2384 if (!ret)
2385 ret = info->slots[arg].change;
2386 kfree(info);
2387 return ret;
2388}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002389
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002390static int cdrom_ioctl_set_options(struct cdrom_device_info *cdi,
2391 unsigned long arg)
2392{
Joe Perches5944b2c2014-05-04 17:05:02 -07002393 cd_dbg(CD_DO_IOCTL, "entering CDROM_SET_OPTIONS\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002394
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002395 /*
2396 * Options need to be in sync with capability.
2397 * Too late for that, so we have to check each one separately.
2398 */
2399 switch (arg) {
2400 case CDO_USE_FFLAGS:
2401 case CDO_CHECK_TYPE:
2402 break;
2403 case CDO_LOCK:
Linus Torvalds1da177e2005-04-16 15:20:36 -07002404 if (!CDROM_CAN(CDC_LOCK))
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002405 return -ENOSYS;
2406 break;
2407 case 0:
2408 return cdi->options;
2409 /* default is basically CDO_[AUTO_CLOSE|AUTO_EJECT] */
2410 default:
2411 if (!CDROM_CAN(arg))
2412 return -ENOSYS;
2413 }
2414 cdi->options |= (int) arg;
2415 return cdi->options;
2416}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002417
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002418static int cdrom_ioctl_clear_options(struct cdrom_device_info *cdi,
2419 unsigned long arg)
2420{
Joe Perches5944b2c2014-05-04 17:05:02 -07002421 cd_dbg(CD_DO_IOCTL, "entering CDROM_CLEAR_OPTIONS\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002422
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002423 cdi->options &= ~(int) arg;
2424 return cdi->options;
2425}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002426
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002427static int cdrom_ioctl_select_speed(struct cdrom_device_info *cdi,
2428 unsigned long arg)
2429{
Joe Perches5944b2c2014-05-04 17:05:02 -07002430 cd_dbg(CD_DO_IOCTL, "entering CDROM_SELECT_SPEED\n");
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002431
2432 if (!CDROM_CAN(CDC_SELECT_SPEED))
2433 return -ENOSYS;
2434 return cdi->ops->select_speed(cdi, arg);
2435}
2436
2437static int cdrom_ioctl_select_disc(struct cdrom_device_info *cdi,
2438 unsigned long arg)
2439{
Joe Perches5944b2c2014-05-04 17:05:02 -07002440 cd_dbg(CD_DO_IOCTL, "entering CDROM_SELECT_DISC\n");
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002441
2442 if (!CDROM_CAN(CDC_SELECT_DISC))
2443 return -ENOSYS;
2444
2445 if (arg != CDSL_CURRENT && arg != CDSL_NONE) {
Young_X8dd745a2018-10-03 12:54:29 +00002446 if (arg >= cdi->capacity)
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002447 return -EINVAL;
2448 }
2449
2450 /*
2451 * ->select_disc is a hook to allow a driver-specific way of
2452 * seleting disc. However, since there is no equivalent hook for
2453 * cdrom_slot_status this may not actually be useful...
2454 */
2455 if (cdi->ops->select_disc)
2456 return cdi->ops->select_disc(cdi, arg);
2457
Joe Perches5944b2c2014-05-04 17:05:02 -07002458 cd_dbg(CD_CHANGER, "Using generic cdrom_select_disc()\n");
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002459 return cdrom_select_disc(cdi, arg);
2460}
2461
2462static int cdrom_ioctl_reset(struct cdrom_device_info *cdi,
2463 struct block_device *bdev)
2464{
Joe Perches5944b2c2014-05-04 17:05:02 -07002465 cd_dbg(CD_DO_IOCTL, "entering CDROM_RESET\n");
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002466
2467 if (!capable(CAP_SYS_ADMIN))
2468 return -EACCES;
2469 if (!CDROM_CAN(CDC_RESET))
2470 return -ENOSYS;
Peter Zijlstraf98393a2007-05-06 14:49:54 -07002471 invalidate_bdev(bdev);
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002472 return cdi->ops->reset(cdi);
2473}
2474
2475static int cdrom_ioctl_lock_door(struct cdrom_device_info *cdi,
2476 unsigned long arg)
2477{
Joe Perches5944b2c2014-05-04 17:05:02 -07002478 cd_dbg(CD_DO_IOCTL, "%socking door\n", arg ? "L" : "Unl");
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002479
2480 if (!CDROM_CAN(CDC_LOCK))
2481 return -EDRIVE_CANT_DO_THIS;
2482
Paolo Bonzinicdccaa92012-02-08 20:03:14 +01002483 cdi->keeplocked = arg ? 1 : 0;
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002484
2485 /*
2486 * Don't unlock the door on multiple opens by default, but allow
2487 * root to do so.
2488 */
2489 if (cdi->use_count != 1 && !arg && !capable(CAP_SYS_ADMIN))
2490 return -EBUSY;
2491 return cdi->ops->lock_door(cdi, arg);
2492}
2493
2494static int cdrom_ioctl_debug(struct cdrom_device_info *cdi,
2495 unsigned long arg)
2496{
Joe Perches5944b2c2014-05-04 17:05:02 -07002497 cd_dbg(CD_DO_IOCTL, "%sabling debug\n", arg ? "En" : "Dis");
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002498
2499 if (!capable(CAP_SYS_ADMIN))
2500 return -EACCES;
2501 debug = arg ? 1 : 0;
2502 return debug;
2503}
2504
2505static int cdrom_ioctl_get_capability(struct cdrom_device_info *cdi)
2506{
Joe Perches5944b2c2014-05-04 17:05:02 -07002507 cd_dbg(CD_DO_IOCTL, "entering CDROM_GET_CAPABILITY\n");
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002508 return (cdi->ops->capability & ~cdi->mask);
2509}
2510
2511/*
2512 * The following function is implemented, although very few audio
Linus Torvalds1da177e2005-04-16 15:20:36 -07002513 * discs give Universal Product Code information, which should just be
2514 * the Medium Catalog Number on the box. Note, that the way the code
2515 * is written on the CD is /not/ uniform across all discs!
2516 */
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002517static int cdrom_ioctl_get_mcn(struct cdrom_device_info *cdi,
2518 void __user *argp)
2519{
2520 struct cdrom_mcn mcn;
2521 int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002522
Joe Perches5944b2c2014-05-04 17:05:02 -07002523 cd_dbg(CD_DO_IOCTL, "entering CDROM_GET_MCN\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002524
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002525 if (!(cdi->ops->capability & CDC_MCN))
2526 return -ENOSYS;
2527 ret = cdi->ops->get_mcn(cdi, &mcn);
2528 if (ret)
2529 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002530
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002531 if (copy_to_user(argp, &mcn, sizeof(mcn)))
2532 return -EFAULT;
Joe Perches5944b2c2014-05-04 17:05:02 -07002533 cd_dbg(CD_DO_IOCTL, "CDROM_GET_MCN successful\n");
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002534 return 0;
2535}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002536
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002537static int cdrom_ioctl_drive_status(struct cdrom_device_info *cdi,
2538 unsigned long arg)
2539{
Joe Perches5944b2c2014-05-04 17:05:02 -07002540 cd_dbg(CD_DO_IOCTL, "entering CDROM_DRIVE_STATUS\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002541
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002542 if (!(cdi->ops->capability & CDC_DRIVE_STATUS))
2543 return -ENOSYS;
2544 if (!CDROM_CAN(CDC_SELECT_DISC) ||
2545 (arg == CDSL_CURRENT || arg == CDSL_NONE))
2546 return cdi->ops->drive_status(cdi, CDSL_CURRENT);
Scott Bauerb8c0e152018-04-26 11:51:08 -06002547 if (arg >= cdi->capacity)
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002548 return -EINVAL;
2549 return cdrom_slot_status(cdi, arg);
2550}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002551
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002552/*
2553 * Ok, this is where problems start. The current interface for the
2554 * CDROM_DISC_STATUS ioctl is flawed. It makes the false assumption that
Lucas De Marchi25985ed2011-03-30 22:57:33 -03002555 * CDs are all CDS_DATA_1 or all CDS_AUDIO, etc. Unfortunately, while this
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002556 * is often the case, it is also very common for CDs to have some tracks
2557 * with data, and some tracks with audio. Just because I feel like it,
2558 * I declare the following to be the best way to cope. If the CD has ANY
2559 * data tracks on it, it will be returned as a data CD. If it has any XA
2560 * tracks, I will return it as that. Now I could simplify this interface
2561 * by combining these returns with the above, but this more clearly
2562 * demonstrates the problem with the current interface. Too bad this
2563 * wasn't designed to use bitmasks... -Erik
2564 *
2565 * Well, now we have the option CDS_MIXED: a mixed-type CD.
2566 * User level programmers might feel the ioctl is not very useful.
2567 * ---david
2568 */
2569static int cdrom_ioctl_disc_status(struct cdrom_device_info *cdi)
2570{
2571 tracktype tracks;
2572
Joe Perches5944b2c2014-05-04 17:05:02 -07002573 cd_dbg(CD_DO_IOCTL, "entering CDROM_DISC_STATUS\n");
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002574
2575 cdrom_count_tracks(cdi, &tracks);
2576 if (tracks.error)
2577 return tracks.error;
2578
2579 /* Policy mode on */
2580 if (tracks.audio > 0) {
2581 if (!tracks.data && !tracks.cdi && !tracks.xa)
2582 return CDS_AUDIO;
2583 else
2584 return CDS_MIXED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002585 }
2586
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002587 if (tracks.cdi > 0)
2588 return CDS_XA_2_2;
2589 if (tracks.xa > 0)
2590 return CDS_XA_2_1;
2591 if (tracks.data > 0)
2592 return CDS_DATA_1;
2593 /* Policy mode off */
2594
Joe Perches5944b2c2014-05-04 17:05:02 -07002595 cd_dbg(CD_WARNING, "This disc doesn't have any tracks I recognize!\n");
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002596 return CDS_NO_INFO;
2597}
2598
2599static int cdrom_ioctl_changer_nslots(struct cdrom_device_info *cdi)
2600{
Joe Perches5944b2c2014-05-04 17:05:02 -07002601 cd_dbg(CD_DO_IOCTL, "entering CDROM_CHANGER_NSLOTS\n");
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002602 return cdi->capacity;
2603}
2604
2605static int cdrom_ioctl_get_subchnl(struct cdrom_device_info *cdi,
2606 void __user *argp)
2607{
2608 struct cdrom_subchnl q;
2609 u8 requested, back;
2610 int ret;
2611
Joe Perches5944b2c2014-05-04 17:05:02 -07002612 /* cd_dbg(CD_DO_IOCTL,"entering CDROMSUBCHNL\n");*/
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002613
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002614 if (copy_from_user(&q, argp, sizeof(q)))
2615 return -EFAULT;
2616
2617 requested = q.cdsc_format;
2618 if (requested != CDROM_MSF && requested != CDROM_LBA)
2619 return -EINVAL;
2620 q.cdsc_format = CDROM_MSF;
2621
2622 ret = cdi->ops->audio_ioctl(cdi, CDROMSUBCHNL, &q);
2623 if (ret)
2624 return ret;
2625
2626 back = q.cdsc_format; /* local copy */
2627 sanitize_format(&q.cdsc_absaddr, &back, requested);
2628 sanitize_format(&q.cdsc_reladdr, &q.cdsc_format, requested);
2629
2630 if (copy_to_user(argp, &q, sizeof(q)))
2631 return -EFAULT;
Joe Perches5944b2c2014-05-04 17:05:02 -07002632 /* cd_dbg(CD_DO_IOCTL, "CDROMSUBCHNL successful\n"); */
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002633 return 0;
2634}
2635
2636static int cdrom_ioctl_read_tochdr(struct cdrom_device_info *cdi,
2637 void __user *argp)
2638{
2639 struct cdrom_tochdr header;
2640 int ret;
2641
Joe Perches5944b2c2014-05-04 17:05:02 -07002642 /* cd_dbg(CD_DO_IOCTL, "entering CDROMREADTOCHDR\n"); */
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002643
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002644 if (copy_from_user(&header, argp, sizeof(header)))
2645 return -EFAULT;
2646
2647 ret = cdi->ops->audio_ioctl(cdi, CDROMREADTOCHDR, &header);
2648 if (ret)
2649 return ret;
2650
2651 if (copy_to_user(argp, &header, sizeof(header)))
2652 return -EFAULT;
Joe Perches5944b2c2014-05-04 17:05:02 -07002653 /* cd_dbg(CD_DO_IOCTL, "CDROMREADTOCHDR successful\n"); */
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002654 return 0;
2655}
2656
2657static int cdrom_ioctl_read_tocentry(struct cdrom_device_info *cdi,
2658 void __user *argp)
2659{
2660 struct cdrom_tocentry entry;
2661 u8 requested_format;
2662 int ret;
2663
Joe Perches5944b2c2014-05-04 17:05:02 -07002664 /* cd_dbg(CD_DO_IOCTL, "entering CDROMREADTOCENTRY\n"); */
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002665
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002666 if (copy_from_user(&entry, argp, sizeof(entry)))
2667 return -EFAULT;
2668
2669 requested_format = entry.cdte_format;
2670 if (requested_format != CDROM_MSF && requested_format != CDROM_LBA)
2671 return -EINVAL;
2672 /* make interface to low-level uniform */
2673 entry.cdte_format = CDROM_MSF;
2674 ret = cdi->ops->audio_ioctl(cdi, CDROMREADTOCENTRY, &entry);
2675 if (ret)
2676 return ret;
2677 sanitize_format(&entry.cdte_addr, &entry.cdte_format, requested_format);
2678
2679 if (copy_to_user(argp, &entry, sizeof(entry)))
2680 return -EFAULT;
Joe Perches5944b2c2014-05-04 17:05:02 -07002681 /* cd_dbg(CD_DO_IOCTL, "CDROMREADTOCENTRY successful\n"); */
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002682 return 0;
2683}
2684
2685static int cdrom_ioctl_play_msf(struct cdrom_device_info *cdi,
2686 void __user *argp)
2687{
2688 struct cdrom_msf msf;
2689
Joe Perches5944b2c2014-05-04 17:05:02 -07002690 cd_dbg(CD_DO_IOCTL, "entering CDROMPLAYMSF\n");
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002691
2692 if (!CDROM_CAN(CDC_PLAY_AUDIO))
2693 return -ENOSYS;
2694 if (copy_from_user(&msf, argp, sizeof(msf)))
2695 return -EFAULT;
2696 return cdi->ops->audio_ioctl(cdi, CDROMPLAYMSF, &msf);
2697}
2698
2699static int cdrom_ioctl_play_trkind(struct cdrom_device_info *cdi,
2700 void __user *argp)
2701{
2702 struct cdrom_ti ti;
2703 int ret;
2704
Joe Perches5944b2c2014-05-04 17:05:02 -07002705 cd_dbg(CD_DO_IOCTL, "entering CDROMPLAYTRKIND\n");
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002706
2707 if (!CDROM_CAN(CDC_PLAY_AUDIO))
2708 return -ENOSYS;
2709 if (copy_from_user(&ti, argp, sizeof(ti)))
2710 return -EFAULT;
2711
2712 ret = check_for_audio_disc(cdi, cdi->ops);
2713 if (ret)
2714 return ret;
2715 return cdi->ops->audio_ioctl(cdi, CDROMPLAYTRKIND, &ti);
2716}
2717static int cdrom_ioctl_volctrl(struct cdrom_device_info *cdi,
2718 void __user *argp)
2719{
2720 struct cdrom_volctrl volume;
2721
Joe Perches5944b2c2014-05-04 17:05:02 -07002722 cd_dbg(CD_DO_IOCTL, "entering CDROMVOLCTRL\n");
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002723
2724 if (!CDROM_CAN(CDC_PLAY_AUDIO))
2725 return -ENOSYS;
2726 if (copy_from_user(&volume, argp, sizeof(volume)))
2727 return -EFAULT;
2728 return cdi->ops->audio_ioctl(cdi, CDROMVOLCTRL, &volume);
2729}
2730
2731static int cdrom_ioctl_volread(struct cdrom_device_info *cdi,
2732 void __user *argp)
2733{
2734 struct cdrom_volctrl volume;
2735 int ret;
2736
Joe Perches5944b2c2014-05-04 17:05:02 -07002737 cd_dbg(CD_DO_IOCTL, "entering CDROMVOLREAD\n");
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002738
2739 if (!CDROM_CAN(CDC_PLAY_AUDIO))
2740 return -ENOSYS;
2741
2742 ret = cdi->ops->audio_ioctl(cdi, CDROMVOLREAD, &volume);
2743 if (ret)
2744 return ret;
2745
2746 if (copy_to_user(argp, &volume, sizeof(volume)))
2747 return -EFAULT;
2748 return 0;
2749}
2750
2751static int cdrom_ioctl_audioctl(struct cdrom_device_info *cdi,
2752 unsigned int cmd)
2753{
2754 int ret;
2755
Joe Perches5944b2c2014-05-04 17:05:02 -07002756 cd_dbg(CD_DO_IOCTL, "doing audio ioctl (start/stop/pause/resume)\n");
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002757
2758 if (!CDROM_CAN(CDC_PLAY_AUDIO))
2759 return -ENOSYS;
2760 ret = check_for_audio_disc(cdi, cdi->ops);
2761 if (ret)
2762 return ret;
2763 return cdi->ops->audio_ioctl(cdi, cmd, NULL);
2764}
2765
2766/*
Joe Perches2e9aa082014-05-04 17:05:08 -07002767 * Required when we need to use READ_10 to issue other than 2048 block
2768 * reads
2769 */
2770static int cdrom_switch_blocksize(struct cdrom_device_info *cdi, int size)
2771{
2772 struct cdrom_device_ops *cdo = cdi->ops;
2773 struct packet_command cgc;
2774 struct modesel_head mh;
2775
2776 memset(&mh, 0, sizeof(mh));
2777 mh.block_desc_length = 0x08;
2778 mh.block_length_med = (size >> 8) & 0xff;
2779 mh.block_length_lo = size & 0xff;
2780
2781 memset(&cgc, 0, sizeof(cgc));
2782 cgc.cmd[0] = 0x15;
2783 cgc.cmd[1] = 1 << 4;
2784 cgc.cmd[4] = 12;
2785 cgc.buflen = sizeof(mh);
2786 cgc.buffer = (char *) &mh;
2787 cgc.data_direction = CGC_DATA_WRITE;
2788 mh.block_desc_length = 0x08;
2789 mh.block_length_med = (size >> 8) & 0xff;
2790 mh.block_length_lo = size & 0xff;
2791
2792 return cdo->generic_packet(cdi, &cgc);
2793}
2794
Joe Perchese1e60fd2014-05-04 17:05:09 -07002795static int cdrom_get_track_info(struct cdrom_device_info *cdi,
2796 __u16 track, __u8 type, track_information *ti)
2797{
2798 struct cdrom_device_ops *cdo = cdi->ops;
2799 struct packet_command cgc;
2800 int ret, buflen;
2801
2802 init_cdrom_command(&cgc, ti, 8, CGC_DATA_READ);
2803 cgc.cmd[0] = GPCMD_READ_TRACK_RZONE_INFO;
2804 cgc.cmd[1] = type & 3;
2805 cgc.cmd[4] = (track & 0xff00) >> 8;
2806 cgc.cmd[5] = track & 0xff;
2807 cgc.cmd[8] = 8;
2808 cgc.quiet = 1;
2809
2810 ret = cdo->generic_packet(cdi, &cgc);
2811 if (ret)
2812 return ret;
2813
2814 buflen = be16_to_cpu(ti->track_information_length) +
2815 sizeof(ti->track_information_length);
2816
2817 if (buflen > sizeof(track_information))
2818 buflen = sizeof(track_information);
2819
2820 cgc.cmd[8] = cgc.buflen = buflen;
2821 ret = cdo->generic_packet(cdi, &cgc);
2822 if (ret)
2823 return ret;
2824
2825 /* return actual fill size */
2826 return buflen;
2827}
2828
2829/* return the last written block on the CD-R media. this is for the udf
2830 file system. */
2831int cdrom_get_last_written(struct cdrom_device_info *cdi, long *last_written)
2832{
2833 struct cdrom_tocentry toc;
2834 disc_information di;
2835 track_information ti;
2836 __u32 last_track;
2837 int ret = -1, ti_size;
2838
2839 if (!CDROM_CAN(CDC_GENERIC_PACKET))
2840 goto use_toc;
2841
2842 ret = cdrom_get_disc_info(cdi, &di);
2843 if (ret < (int)(offsetof(typeof(di), last_track_lsb)
2844 + sizeof(di.last_track_lsb)))
2845 goto use_toc;
2846
2847 /* if unit didn't return msb, it's zeroed by cdrom_get_disc_info */
2848 last_track = (di.last_track_msb << 8) | di.last_track_lsb;
2849 ti_size = cdrom_get_track_info(cdi, last_track, 1, &ti);
2850 if (ti_size < (int)offsetof(typeof(ti), track_start))
2851 goto use_toc;
2852
2853 /* if this track is blank, try the previous. */
2854 if (ti.blank) {
2855 if (last_track == 1)
2856 goto use_toc;
2857 last_track--;
2858 ti_size = cdrom_get_track_info(cdi, last_track, 1, &ti);
2859 }
2860
2861 if (ti_size < (int)(offsetof(typeof(ti), track_size)
2862 + sizeof(ti.track_size)))
2863 goto use_toc;
2864
2865 /* if last recorded field is valid, return it. */
2866 if (ti.lra_v && ti_size >= (int)(offsetof(typeof(ti), last_rec_address)
2867 + sizeof(ti.last_rec_address))) {
2868 *last_written = be32_to_cpu(ti.last_rec_address);
2869 } else {
2870 /* make it up instead */
2871 *last_written = be32_to_cpu(ti.track_start) +
2872 be32_to_cpu(ti.track_size);
2873 if (ti.free_blocks)
2874 *last_written -= (be32_to_cpu(ti.free_blocks) + 7);
2875 }
2876 return 0;
2877
2878 /* this is where we end up if the drive either can't do a
2879 GPCMD_READ_DISC_INFO or GPCMD_READ_TRACK_RZONE_INFO or if
2880 it doesn't give enough information or fails. then we return
2881 the toc contents. */
2882use_toc:
Diego Elio Pettenò3f58a3f2019-11-19 21:37:08 +00002883 if (!CDROM_CAN(CDC_PLAY_AUDIO))
2884 return -ENOSYS;
2885
Joe Perchese1e60fd2014-05-04 17:05:09 -07002886 toc.cdte_format = CDROM_MSF;
2887 toc.cdte_track = CDROM_LEADOUT;
2888 if ((ret = cdi->ops->audio_ioctl(cdi, CDROMREADTOCENTRY, &toc)))
2889 return ret;
2890 sanitize_format(&toc.cdte_addr, &toc.cdte_format, CDROM_LBA);
2891 *last_written = toc.cdte_addr.lba;
2892 return 0;
2893}
2894
Joe Perchesdac1c5c2014-05-04 17:05:10 -07002895/* return the next writable block. also for udf file system. */
2896static int cdrom_get_next_writable(struct cdrom_device_info *cdi,
2897 long *next_writable)
2898{
2899 disc_information di;
2900 track_information ti;
2901 __u16 last_track;
2902 int ret, ti_size;
2903
2904 if (!CDROM_CAN(CDC_GENERIC_PACKET))
2905 goto use_last_written;
2906
2907 ret = cdrom_get_disc_info(cdi, &di);
2908 if (ret < 0 || ret < offsetof(typeof(di), last_track_lsb)
2909 + sizeof(di.last_track_lsb))
2910 goto use_last_written;
2911
2912 /* if unit didn't return msb, it's zeroed by cdrom_get_disc_info */
2913 last_track = (di.last_track_msb << 8) | di.last_track_lsb;
2914 ti_size = cdrom_get_track_info(cdi, last_track, 1, &ti);
2915 if (ti_size < 0 || ti_size < offsetof(typeof(ti), track_start))
2916 goto use_last_written;
2917
2918 /* if this track is blank, try the previous. */
2919 if (ti.blank) {
2920 if (last_track == 1)
2921 goto use_last_written;
2922 last_track--;
2923 ti_size = cdrom_get_track_info(cdi, last_track, 1, &ti);
2924 if (ti_size < 0)
2925 goto use_last_written;
2926 }
2927
2928 /* if next recordable address field is valid, use it. */
2929 if (ti.nwa_v && ti_size >= offsetof(typeof(ti), next_writable)
2930 + sizeof(ti.next_writable)) {
2931 *next_writable = be32_to_cpu(ti.next_writable);
2932 return 0;
2933 }
2934
2935use_last_written:
2936 ret = cdrom_get_last_written(cdi, next_writable);
2937 if (ret) {
2938 *next_writable = 0;
2939 return ret;
2940 } else {
2941 *next_writable += 7;
2942 return 0;
2943 }
2944}
2945
Joe Perches2e9aa082014-05-04 17:05:08 -07002946static noinline int mmc_ioctl_cdrom_read_data(struct cdrom_device_info *cdi,
2947 void __user *arg,
2948 struct packet_command *cgc,
2949 int cmd)
2950{
2951 struct request_sense sense;
2952 struct cdrom_msf msf;
2953 int blocksize = 0, format = 0, lba;
2954 int ret;
2955
2956 switch (cmd) {
2957 case CDROMREADRAW:
2958 blocksize = CD_FRAMESIZE_RAW;
2959 break;
2960 case CDROMREADMODE1:
2961 blocksize = CD_FRAMESIZE;
2962 format = 2;
2963 break;
2964 case CDROMREADMODE2:
2965 blocksize = CD_FRAMESIZE_RAW0;
2966 break;
2967 }
2968 if (copy_from_user(&msf, (struct cdrom_msf __user *)arg, sizeof(msf)))
2969 return -EFAULT;
2970 lba = msf_to_lba(msf.cdmsf_min0, msf.cdmsf_sec0, msf.cdmsf_frame0);
2971 /* FIXME: we need upper bound checking, too!! */
2972 if (lba < 0)
2973 return -EINVAL;
2974
2975 cgc->buffer = kzalloc(blocksize, GFP_KERNEL);
2976 if (cgc->buffer == NULL)
2977 return -ENOMEM;
2978
2979 memset(&sense, 0, sizeof(sense));
2980 cgc->sense = &sense;
2981 cgc->data_direction = CGC_DATA_READ;
2982 ret = cdrom_read_block(cdi, cgc, lba, 1, format, blocksize);
2983 if (ret && sense.sense_key == 0x05 &&
2984 sense.asc == 0x20 &&
2985 sense.ascq == 0x00) {
2986 /*
2987 * SCSI-II devices are not required to support
2988 * READ_CD, so let's try switching block size
2989 */
2990 /* FIXME: switch back again... */
2991 ret = cdrom_switch_blocksize(cdi, blocksize);
2992 if (ret)
2993 goto out;
2994 cgc->sense = NULL;
2995 ret = cdrom_read_cd(cdi, cgc, lba, blocksize, 1);
2996 ret |= cdrom_switch_blocksize(cdi, blocksize);
2997 }
2998 if (!ret && copy_to_user(arg, cgc->buffer, blocksize))
2999 ret = -EFAULT;
3000out:
3001 kfree(cgc->buffer);
3002 return ret;
3003}
3004
3005static noinline int mmc_ioctl_cdrom_read_audio(struct cdrom_device_info *cdi,
3006 void __user *arg)
3007{
3008 struct cdrom_read_audio ra;
3009 int lba;
3010
3011 if (copy_from_user(&ra, (struct cdrom_read_audio __user *)arg,
3012 sizeof(ra)))
3013 return -EFAULT;
3014
3015 if (ra.addr_format == CDROM_MSF)
3016 lba = msf_to_lba(ra.addr.msf.minute,
3017 ra.addr.msf.second,
3018 ra.addr.msf.frame);
3019 else if (ra.addr_format == CDROM_LBA)
3020 lba = ra.addr.lba;
3021 else
3022 return -EINVAL;
3023
3024 /* FIXME: we need upper bound checking, too!! */
3025 if (lba < 0 || ra.nframes <= 0 || ra.nframes > CD_FRAMES)
3026 return -EINVAL;
3027
3028 return cdrom_read_cdda(cdi, ra.buf, lba, ra.nframes);
3029}
3030
3031static noinline int mmc_ioctl_cdrom_subchannel(struct cdrom_device_info *cdi,
3032 void __user *arg)
3033{
3034 int ret;
3035 struct cdrom_subchnl q;
3036 u_char requested, back;
3037 if (copy_from_user(&q, (struct cdrom_subchnl __user *)arg, sizeof(q)))
3038 return -EFAULT;
3039 requested = q.cdsc_format;
3040 if (!((requested == CDROM_MSF) ||
3041 (requested == CDROM_LBA)))
3042 return -EINVAL;
vchannaiahbf294e82016-06-29 08:18:25 -04003043
Joe Perches2e9aa082014-05-04 17:05:08 -07003044 ret = cdrom_read_subchannel(cdi, &q, 0);
3045 if (ret)
3046 return ret;
3047 back = q.cdsc_format; /* local copy */
3048 sanitize_format(&q.cdsc_absaddr, &back, requested);
3049 sanitize_format(&q.cdsc_reladdr, &q.cdsc_format, requested);
3050 if (copy_to_user((struct cdrom_subchnl __user *)arg, &q, sizeof(q)))
3051 return -EFAULT;
3052 /* cd_dbg(CD_DO_IOCTL, "CDROMSUBCHNL successful\n"); */
3053 return 0;
3054}
3055
3056static noinline int mmc_ioctl_cdrom_play_msf(struct cdrom_device_info *cdi,
3057 void __user *arg,
3058 struct packet_command *cgc)
3059{
3060 struct cdrom_device_ops *cdo = cdi->ops;
3061 struct cdrom_msf msf;
3062 cd_dbg(CD_DO_IOCTL, "entering CDROMPLAYMSF\n");
3063 if (copy_from_user(&msf, (struct cdrom_msf __user *)arg, sizeof(msf)))
3064 return -EFAULT;
3065 cgc->cmd[0] = GPCMD_PLAY_AUDIO_MSF;
3066 cgc->cmd[3] = msf.cdmsf_min0;
3067 cgc->cmd[4] = msf.cdmsf_sec0;
3068 cgc->cmd[5] = msf.cdmsf_frame0;
3069 cgc->cmd[6] = msf.cdmsf_min1;
3070 cgc->cmd[7] = msf.cdmsf_sec1;
3071 cgc->cmd[8] = msf.cdmsf_frame1;
3072 cgc->data_direction = CGC_DATA_NONE;
3073 return cdo->generic_packet(cdi, cgc);
3074}
3075
3076static noinline int mmc_ioctl_cdrom_play_blk(struct cdrom_device_info *cdi,
3077 void __user *arg,
3078 struct packet_command *cgc)
3079{
3080 struct cdrom_device_ops *cdo = cdi->ops;
3081 struct cdrom_blk blk;
3082 cd_dbg(CD_DO_IOCTL, "entering CDROMPLAYBLK\n");
3083 if (copy_from_user(&blk, (struct cdrom_blk __user *)arg, sizeof(blk)))
3084 return -EFAULT;
3085 cgc->cmd[0] = GPCMD_PLAY_AUDIO_10;
3086 cgc->cmd[2] = (blk.from >> 24) & 0xff;
3087 cgc->cmd[3] = (blk.from >> 16) & 0xff;
3088 cgc->cmd[4] = (blk.from >> 8) & 0xff;
3089 cgc->cmd[5] = blk.from & 0xff;
3090 cgc->cmd[7] = (blk.len >> 8) & 0xff;
3091 cgc->cmd[8] = blk.len & 0xff;
3092 cgc->data_direction = CGC_DATA_NONE;
3093 return cdo->generic_packet(cdi, cgc);
3094}
3095
3096static noinline int mmc_ioctl_cdrom_volume(struct cdrom_device_info *cdi,
3097 void __user *arg,
3098 struct packet_command *cgc,
3099 unsigned int cmd)
3100{
3101 struct cdrom_volctrl volctrl;
3102 unsigned char buffer[32];
3103 char mask[sizeof(buffer)];
3104 unsigned short offset;
3105 int ret;
3106
3107 cd_dbg(CD_DO_IOCTL, "entering CDROMVOLUME\n");
3108
3109 if (copy_from_user(&volctrl, (struct cdrom_volctrl __user *)arg,
3110 sizeof(volctrl)))
3111 return -EFAULT;
3112
3113 cgc->buffer = buffer;
3114 cgc->buflen = 24;
3115 ret = cdrom_mode_sense(cdi, cgc, GPMODE_AUDIO_CTL_PAGE, 0);
3116 if (ret)
3117 return ret;
3118
3119 /* originally the code depended on buffer[1] to determine
3120 how much data is available for transfer. buffer[1] is
3121 unfortunately ambigious and the only reliable way seem
3122 to be to simply skip over the block descriptor... */
3123 offset = 8 + be16_to_cpu(*(__be16 *)(buffer + 6));
3124
3125 if (offset + 16 > sizeof(buffer))
3126 return -E2BIG;
3127
3128 if (offset + 16 > cgc->buflen) {
3129 cgc->buflen = offset + 16;
3130 ret = cdrom_mode_sense(cdi, cgc,
3131 GPMODE_AUDIO_CTL_PAGE, 0);
3132 if (ret)
3133 return ret;
3134 }
3135
3136 /* sanity check */
3137 if ((buffer[offset] & 0x3f) != GPMODE_AUDIO_CTL_PAGE ||
3138 buffer[offset + 1] < 14)
3139 return -EINVAL;
3140
3141 /* now we have the current volume settings. if it was only
3142 a CDROMVOLREAD, return these values */
3143 if (cmd == CDROMVOLREAD) {
3144 volctrl.channel0 = buffer[offset+9];
3145 volctrl.channel1 = buffer[offset+11];
3146 volctrl.channel2 = buffer[offset+13];
3147 volctrl.channel3 = buffer[offset+15];
3148 if (copy_to_user((struct cdrom_volctrl __user *)arg, &volctrl,
3149 sizeof(volctrl)))
3150 return -EFAULT;
3151 return 0;
3152 }
3153
3154 /* get the volume mask */
3155 cgc->buffer = mask;
3156 ret = cdrom_mode_sense(cdi, cgc, GPMODE_AUDIO_CTL_PAGE, 1);
3157 if (ret)
3158 return ret;
3159
3160 buffer[offset + 9] = volctrl.channel0 & mask[offset + 9];
3161 buffer[offset + 11] = volctrl.channel1 & mask[offset + 11];
3162 buffer[offset + 13] = volctrl.channel2 & mask[offset + 13];
3163 buffer[offset + 15] = volctrl.channel3 & mask[offset + 15];
3164
3165 /* set volume */
3166 cgc->buffer = buffer + offset - 8;
3167 memset(cgc->buffer, 0, 8);
3168 return cdrom_mode_select(cdi, cgc);
3169}
3170
3171static noinline int mmc_ioctl_cdrom_start_stop(struct cdrom_device_info *cdi,
3172 struct packet_command *cgc,
3173 int cmd)
3174{
3175 struct cdrom_device_ops *cdo = cdi->ops;
3176 cd_dbg(CD_DO_IOCTL, "entering CDROMSTART/CDROMSTOP\n");
3177 cgc->cmd[0] = GPCMD_START_STOP_UNIT;
3178 cgc->cmd[1] = 1;
3179 cgc->cmd[4] = (cmd == CDROMSTART) ? 1 : 0;
3180 cgc->data_direction = CGC_DATA_NONE;
3181 return cdo->generic_packet(cdi, cgc);
3182}
3183
3184static noinline int mmc_ioctl_cdrom_pause_resume(struct cdrom_device_info *cdi,
3185 struct packet_command *cgc,
3186 int cmd)
3187{
3188 struct cdrom_device_ops *cdo = cdi->ops;
3189 cd_dbg(CD_DO_IOCTL, "entering CDROMPAUSE/CDROMRESUME\n");
3190 cgc->cmd[0] = GPCMD_PAUSE_RESUME;
3191 cgc->cmd[8] = (cmd == CDROMRESUME) ? 1 : 0;
3192 cgc->data_direction = CGC_DATA_NONE;
3193 return cdo->generic_packet(cdi, cgc);
3194}
3195
3196static noinline int mmc_ioctl_dvd_read_struct(struct cdrom_device_info *cdi,
3197 void __user *arg,
3198 struct packet_command *cgc)
3199{
3200 int ret;
3201 dvd_struct *s;
3202 int size = sizeof(dvd_struct);
3203
3204 if (!CDROM_CAN(CDC_DVD))
3205 return -ENOSYS;
3206
Al Viroabb0f6a2016-01-02 14:59:38 -05003207 s = memdup_user(arg, size);
3208 if (IS_ERR(s))
3209 return PTR_ERR(s);
Joe Perches2e9aa082014-05-04 17:05:08 -07003210
3211 cd_dbg(CD_DO_IOCTL, "entering DVD_READ_STRUCT\n");
Joe Perches2e9aa082014-05-04 17:05:08 -07003212
3213 ret = dvd_read_struct(cdi, s, cgc);
3214 if (ret)
3215 goto out;
3216
3217 if (copy_to_user(arg, s, size))
3218 ret = -EFAULT;
3219out:
3220 kfree(s);
3221 return ret;
3222}
3223
3224static noinline int mmc_ioctl_dvd_auth(struct cdrom_device_info *cdi,
3225 void __user *arg)
3226{
3227 int ret;
3228 dvd_authinfo ai;
3229 if (!CDROM_CAN(CDC_DVD))
3230 return -ENOSYS;
3231 cd_dbg(CD_DO_IOCTL, "entering DVD_AUTH\n");
3232 if (copy_from_user(&ai, (dvd_authinfo __user *)arg, sizeof(ai)))
3233 return -EFAULT;
3234 ret = dvd_do_auth(cdi, &ai);
3235 if (ret)
3236 return ret;
3237 if (copy_to_user((dvd_authinfo __user *)arg, &ai, sizeof(ai)))
3238 return -EFAULT;
3239 return 0;
3240}
3241
3242static noinline int mmc_ioctl_cdrom_next_writable(struct cdrom_device_info *cdi,
3243 void __user *arg)
3244{
3245 int ret;
3246 long next = 0;
3247 cd_dbg(CD_DO_IOCTL, "entering CDROM_NEXT_WRITABLE\n");
3248 ret = cdrom_get_next_writable(cdi, &next);
3249 if (ret)
3250 return ret;
3251 if (copy_to_user((long __user *)arg, &next, sizeof(next)))
3252 return -EFAULT;
3253 return 0;
3254}
3255
3256static noinline int mmc_ioctl_cdrom_last_written(struct cdrom_device_info *cdi,
3257 void __user *arg)
3258{
3259 int ret;
3260 long last = 0;
3261 cd_dbg(CD_DO_IOCTL, "entering CDROM_LAST_WRITTEN\n");
3262 ret = cdrom_get_last_written(cdi, &last);
3263 if (ret)
3264 return ret;
3265 if (copy_to_user((long __user *)arg, &last, sizeof(last)))
3266 return -EFAULT;
3267 return 0;
3268}
3269
3270static int mmc_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
3271 unsigned long arg)
3272{
3273 struct packet_command cgc;
3274 void __user *userptr = (void __user *)arg;
3275
3276 memset(&cgc, 0, sizeof(cgc));
3277
3278 /* build a unified command and queue it through
3279 cdo->generic_packet() */
3280 switch (cmd) {
3281 case CDROMREADRAW:
3282 case CDROMREADMODE1:
3283 case CDROMREADMODE2:
3284 return mmc_ioctl_cdrom_read_data(cdi, userptr, &cgc, cmd);
3285 case CDROMREADAUDIO:
3286 return mmc_ioctl_cdrom_read_audio(cdi, userptr);
3287 case CDROMSUBCHNL:
3288 return mmc_ioctl_cdrom_subchannel(cdi, userptr);
3289 case CDROMPLAYMSF:
3290 return mmc_ioctl_cdrom_play_msf(cdi, userptr, &cgc);
3291 case CDROMPLAYBLK:
3292 return mmc_ioctl_cdrom_play_blk(cdi, userptr, &cgc);
3293 case CDROMVOLCTRL:
3294 case CDROMVOLREAD:
3295 return mmc_ioctl_cdrom_volume(cdi, userptr, &cgc, cmd);
3296 case CDROMSTART:
3297 case CDROMSTOP:
3298 return mmc_ioctl_cdrom_start_stop(cdi, &cgc, cmd);
3299 case CDROMPAUSE:
3300 case CDROMRESUME:
3301 return mmc_ioctl_cdrom_pause_resume(cdi, &cgc, cmd);
3302 case DVD_READ_STRUCT:
3303 return mmc_ioctl_dvd_read_struct(cdi, userptr, &cgc);
3304 case DVD_AUTH:
3305 return mmc_ioctl_dvd_auth(cdi, userptr);
3306 case CDROM_NEXT_WRITABLE:
3307 return mmc_ioctl_cdrom_next_writable(cdi, userptr);
3308 case CDROM_LAST_WRITTEN:
3309 return mmc_ioctl_cdrom_last_written(cdi, userptr);
3310 }
3311
3312 return -ENOTTY;
3313}
3314
3315/*
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08003316 * Just about every imaginable ioctl is supported in the Uniform layer
3317 * these days.
3318 * ATAPI / SCSI specific code now mainly resides in mmc_ioctl().
3319 */
Al Virobbc1cc92007-10-07 17:54:28 -04003320int cdrom_ioctl(struct cdrom_device_info *cdi, struct block_device *bdev,
3321 fmode_t mode, unsigned int cmd, unsigned long arg)
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08003322{
3323 void __user *argp = (void __user *)arg;
3324 int ret;
3325
3326 /*
3327 * Try the generic SCSI command ioctl's first.
3328 */
Paolo Bonzini577ebb32012-01-12 16:01:27 +01003329 ret = scsi_cmd_blk_ioctl(bdev, mode, cmd, argp);
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08003330 if (ret != -ENOTTY)
3331 return ret;
3332
3333 switch (cmd) {
3334 case CDROMMULTISESSION:
3335 return cdrom_ioctl_multisession(cdi, argp);
3336 case CDROMEJECT:
3337 return cdrom_ioctl_eject(cdi);
3338 case CDROMCLOSETRAY:
3339 return cdrom_ioctl_closetray(cdi);
3340 case CDROMEJECT_SW:
3341 return cdrom_ioctl_eject_sw(cdi, arg);
3342 case CDROM_MEDIA_CHANGED:
3343 return cdrom_ioctl_media_changed(cdi, arg);
3344 case CDROM_SET_OPTIONS:
3345 return cdrom_ioctl_set_options(cdi, arg);
3346 case CDROM_CLEAR_OPTIONS:
3347 return cdrom_ioctl_clear_options(cdi, arg);
3348 case CDROM_SELECT_SPEED:
3349 return cdrom_ioctl_select_speed(cdi, arg);
3350 case CDROM_SELECT_DISC:
3351 return cdrom_ioctl_select_disc(cdi, arg);
3352 case CDROMRESET:
Al Virobbc1cc92007-10-07 17:54:28 -04003353 return cdrom_ioctl_reset(cdi, bdev);
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08003354 case CDROM_LOCKDOOR:
3355 return cdrom_ioctl_lock_door(cdi, arg);
3356 case CDROM_DEBUG:
3357 return cdrom_ioctl_debug(cdi, arg);
3358 case CDROM_GET_CAPABILITY:
3359 return cdrom_ioctl_get_capability(cdi);
3360 case CDROM_GET_MCN:
3361 return cdrom_ioctl_get_mcn(cdi, argp);
3362 case CDROM_DRIVE_STATUS:
3363 return cdrom_ioctl_drive_status(cdi, arg);
3364 case CDROM_DISC_STATUS:
3365 return cdrom_ioctl_disc_status(cdi);
3366 case CDROM_CHANGER_NSLOTS:
3367 return cdrom_ioctl_changer_nslots(cdi);
3368 }
3369
3370 /*
3371 * Use the ioctls that are implemented through the generic_packet()
3372 * interface. this may look at bit funny, but if -ENOTTY is
3373 * returned that particular ioctl is not implemented and we
3374 * let it go through the device specific ones.
3375 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003376 if (CDROM_CAN(CDC_GENERIC_PACKET)) {
3377 ret = mmc_ioctl(cdi, cmd, arg);
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08003378 if (ret != -ENOTTY)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003379 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003380 }
3381
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08003382 /*
Joe Perches5944b2c2014-05-04 17:05:02 -07003383 * Note: most of the cd_dbg() calls are commented out here,
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08003384 * because they fill up the sys log when CD players poll
3385 * the drive.
3386 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003387 switch (cmd) {
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08003388 case CDROMSUBCHNL:
3389 return cdrom_ioctl_get_subchnl(cdi, argp);
3390 case CDROMREADTOCHDR:
3391 return cdrom_ioctl_read_tochdr(cdi, argp);
3392 case CDROMREADTOCENTRY:
3393 return cdrom_ioctl_read_tocentry(cdi, argp);
3394 case CDROMPLAYMSF:
3395 return cdrom_ioctl_play_msf(cdi, argp);
3396 case CDROMPLAYTRKIND:
3397 return cdrom_ioctl_play_trkind(cdi, argp);
3398 case CDROMVOLCTRL:
3399 return cdrom_ioctl_volctrl(cdi, argp);
3400 case CDROMVOLREAD:
3401 return cdrom_ioctl_volread(cdi, argp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003402 case CDROMSTART:
3403 case CDROMSTOP:
3404 case CDROMPAUSE:
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08003405 case CDROMRESUME:
3406 return cdrom_ioctl_audioctl(cdi, cmd);
3407 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003408
Linus Torvalds1da177e2005-04-16 15:20:36 -07003409 return -ENOSYS;
3410}
3411
Linus Torvalds1da177e2005-04-16 15:20:36 -07003412EXPORT_SYMBOL(cdrom_get_last_written);
3413EXPORT_SYMBOL(register_cdrom);
3414EXPORT_SYMBOL(unregister_cdrom);
3415EXPORT_SYMBOL(cdrom_open);
3416EXPORT_SYMBOL(cdrom_release);
3417EXPORT_SYMBOL(cdrom_ioctl);
3418EXPORT_SYMBOL(cdrom_media_changed);
3419EXPORT_SYMBOL(cdrom_number_of_slots);
3420EXPORT_SYMBOL(cdrom_mode_select);
3421EXPORT_SYMBOL(cdrom_mode_sense);
3422EXPORT_SYMBOL(init_cdrom_command);
3423EXPORT_SYMBOL(cdrom_get_media_event);
3424
3425#ifdef CONFIG_SYSCTL
3426
3427#define CDROM_STR_SIZE 1000
3428
3429static struct cdrom_sysctl_settings {
3430 char info[CDROM_STR_SIZE]; /* general info */
3431 int autoclose; /* close tray upon mount, etc */
3432 int autoeject; /* eject on umount */
3433 int debug; /* turn on debugging messages */
3434 int lock; /* lock the door on device open */
3435 int check; /* check media type */
3436} cdrom_sysctl_settings;
3437
Dave Young554988d2007-06-19 09:14:26 +02003438enum cdrom_print_option {
3439 CTL_NAME,
3440 CTL_SPEED,
3441 CTL_SLOTS,
3442 CTL_CAPABILITY
3443};
3444
3445static int cdrom_print_info(const char *header, int val, char *info,
3446 int *pos, enum cdrom_print_option option)
3447{
3448 const int max_size = sizeof(cdrom_sysctl_settings.info);
3449 struct cdrom_device_info *cdi;
3450 int ret;
3451
3452 ret = scnprintf(info + *pos, max_size - *pos, header);
3453 if (!ret)
3454 return 1;
3455
3456 *pos += ret;
3457
Akinobu Mita7fd097d2008-03-26 12:09:02 +01003458 list_for_each_entry(cdi, &cdrom_list, list) {
Dave Young554988d2007-06-19 09:14:26 +02003459 switch (option) {
3460 case CTL_NAME:
3461 ret = scnprintf(info + *pos, max_size - *pos,
3462 "\t%s", cdi->name);
3463 break;
3464 case CTL_SPEED:
3465 ret = scnprintf(info + *pos, max_size - *pos,
3466 "\t%d", cdi->speed);
3467 break;
3468 case CTL_SLOTS:
3469 ret = scnprintf(info + *pos, max_size - *pos,
3470 "\t%d", cdi->capacity);
3471 break;
3472 case CTL_CAPABILITY:
3473 ret = scnprintf(info + *pos, max_size - *pos,
3474 "\t%d", CDROM_CAN(val) != 0);
3475 break;
3476 default:
Joe Perchese597cd02010-07-01 08:24:32 +02003477 pr_info("invalid option%d\n", option);
Dave Young554988d2007-06-19 09:14:26 +02003478 return 1;
3479 }
3480 if (!ret)
3481 return 1;
3482 *pos += ret;
3483 }
3484
3485 return 0;
3486}
3487
Joe Perches90a3b892014-06-06 14:37:57 -07003488static int cdrom_sysctl_info(struct ctl_table *ctl, int write,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003489 void __user *buffer, size_t *lenp, loff_t *ppos)
3490{
Dave Young554988d2007-06-19 09:14:26 +02003491 int pos;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003492 char *info = cdrom_sysctl_settings.info;
Dave Young554988d2007-06-19 09:14:26 +02003493 const int max_size = sizeof(cdrom_sysctl_settings.info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003494
3495 if (!*lenp || (*ppos && !write)) {
3496 *lenp = 0;
3497 return 0;
3498 }
3499
Dave Young554988d2007-06-19 09:14:26 +02003500 mutex_lock(&cdrom_mutex);
3501
Linus Torvalds1da177e2005-04-16 15:20:36 -07003502 pos = sprintf(info, "CD-ROM information, " VERSION "\n");
3503
Dave Young554988d2007-06-19 09:14:26 +02003504 if (cdrom_print_info("\ndrive name:\t", 0, info, &pos, CTL_NAME))
3505 goto done;
3506 if (cdrom_print_info("\ndrive speed:\t", 0, info, &pos, CTL_SPEED))
3507 goto done;
3508 if (cdrom_print_info("\ndrive # of slots:", 0, info, &pos, CTL_SLOTS))
3509 goto done;
3510 if (cdrom_print_info("\nCan close tray:\t",
3511 CDC_CLOSE_TRAY, info, &pos, CTL_CAPABILITY))
3512 goto done;
3513 if (cdrom_print_info("\nCan open tray:\t",
3514 CDC_OPEN_TRAY, info, &pos, CTL_CAPABILITY))
3515 goto done;
3516 if (cdrom_print_info("\nCan lock tray:\t",
3517 CDC_LOCK, info, &pos, CTL_CAPABILITY))
3518 goto done;
3519 if (cdrom_print_info("\nCan change speed:",
3520 CDC_SELECT_SPEED, info, &pos, CTL_CAPABILITY))
3521 goto done;
3522 if (cdrom_print_info("\nCan select disk:",
3523 CDC_SELECT_DISC, info, &pos, CTL_CAPABILITY))
3524 goto done;
3525 if (cdrom_print_info("\nCan read multisession:",
3526 CDC_MULTI_SESSION, info, &pos, CTL_CAPABILITY))
3527 goto done;
3528 if (cdrom_print_info("\nCan read MCN:\t",
3529 CDC_MCN, info, &pos, CTL_CAPABILITY))
3530 goto done;
3531 if (cdrom_print_info("\nReports media changed:",
3532 CDC_MEDIA_CHANGED, info, &pos, CTL_CAPABILITY))
3533 goto done;
3534 if (cdrom_print_info("\nCan play audio:\t",
3535 CDC_PLAY_AUDIO, info, &pos, CTL_CAPABILITY))
3536 goto done;
3537 if (cdrom_print_info("\nCan write CD-R:\t",
3538 CDC_CD_R, info, &pos, CTL_CAPABILITY))
3539 goto done;
3540 if (cdrom_print_info("\nCan write CD-RW:",
3541 CDC_CD_RW, info, &pos, CTL_CAPABILITY))
3542 goto done;
3543 if (cdrom_print_info("\nCan read DVD:\t",
3544 CDC_DVD, info, &pos, CTL_CAPABILITY))
3545 goto done;
3546 if (cdrom_print_info("\nCan write DVD-R:",
3547 CDC_DVD_R, info, &pos, CTL_CAPABILITY))
3548 goto done;
3549 if (cdrom_print_info("\nCan write DVD-RAM:",
3550 CDC_DVD_RAM, info, &pos, CTL_CAPABILITY))
3551 goto done;
3552 if (cdrom_print_info("\nCan read MRW:\t",
3553 CDC_MRW, info, &pos, CTL_CAPABILITY))
3554 goto done;
3555 if (cdrom_print_info("\nCan write MRW:\t",
3556 CDC_MRW_W, info, &pos, CTL_CAPABILITY))
3557 goto done;
3558 if (cdrom_print_info("\nCan write RAM:\t",
3559 CDC_RAM, info, &pos, CTL_CAPABILITY))
3560 goto done;
3561 if (!scnprintf(info + pos, max_size - pos, "\n\n"))
3562 goto done;
3563doit:
3564 mutex_unlock(&cdrom_mutex);
Alexey Dobriyan8d65af72009-09-23 15:57:19 -07003565 return proc_dostring(ctl, write, buffer, lenp, ppos);
Dave Young554988d2007-06-19 09:14:26 +02003566done:
Joe Perchese597cd02010-07-01 08:24:32 +02003567 pr_info("info buffer too small\n");
Dave Young554988d2007-06-19 09:14:26 +02003568 goto doit;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003569}
3570
3571/* Unfortunately, per device settings are not implemented through
3572 procfs/sysctl yet. When they are, this will naturally disappear. For now
3573 just update all drives. Later this will become the template on which
3574 new registered drives will be based. */
3575static void cdrom_update_settings(void)
3576{
3577 struct cdrom_device_info *cdi;
3578
Akinobu Mita032d8d92008-03-26 12:09:01 +01003579 mutex_lock(&cdrom_mutex);
Akinobu Mita7fd097d2008-03-26 12:09:02 +01003580 list_for_each_entry(cdi, &cdrom_list, list) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003581 if (autoclose && CDROM_CAN(CDC_CLOSE_TRAY))
3582 cdi->options |= CDO_AUTO_CLOSE;
3583 else if (!autoclose)
3584 cdi->options &= ~CDO_AUTO_CLOSE;
3585 if (autoeject && CDROM_CAN(CDC_OPEN_TRAY))
3586 cdi->options |= CDO_AUTO_EJECT;
3587 else if (!autoeject)
3588 cdi->options &= ~CDO_AUTO_EJECT;
3589 if (lockdoor && CDROM_CAN(CDC_LOCK))
3590 cdi->options |= CDO_LOCK;
3591 else if (!lockdoor)
3592 cdi->options &= ~CDO_LOCK;
3593 if (check_media_type)
3594 cdi->options |= CDO_CHECK_TYPE;
3595 else
3596 cdi->options &= ~CDO_CHECK_TYPE;
3597 }
Akinobu Mita032d8d92008-03-26 12:09:01 +01003598 mutex_unlock(&cdrom_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003599}
3600
Joe Perches90a3b892014-06-06 14:37:57 -07003601static int cdrom_sysctl_handler(struct ctl_table *ctl, int write,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003602 void __user *buffer, size_t *lenp, loff_t *ppos)
3603{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003604 int ret;
3605
Alexey Dobriyan8d65af72009-09-23 15:57:19 -07003606 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003607
Eric W. Biederman06489b42007-10-18 03:05:28 -07003608 if (write) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003609
3610 /* we only care for 1 or 0. */
Eric W. Biederman06489b42007-10-18 03:05:28 -07003611 autoclose = !!cdrom_sysctl_settings.autoclose;
3612 autoeject = !!cdrom_sysctl_settings.autoeject;
3613 debug = !!cdrom_sysctl_settings.debug;
3614 lockdoor = !!cdrom_sysctl_settings.lock;
3615 check_media_type = !!cdrom_sysctl_settings.check;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003616
Linus Torvalds1da177e2005-04-16 15:20:36 -07003617 /* update the option flags according to the changes. we
3618 don't have per device options through sysctl yet,
3619 but we will have and then this will disappear. */
3620 cdrom_update_settings();
3621 }
3622
3623 return ret;
3624}
3625
3626/* Place files in /proc/sys/dev/cdrom */
Joe Perches90a3b892014-06-06 14:37:57 -07003627static struct ctl_table cdrom_table[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003628 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003629 .procname = "info",
3630 .data = &cdrom_sysctl_settings.info,
3631 .maxlen = CDROM_STR_SIZE,
3632 .mode = 0444,
Eric W. Biederman6d456112009-11-16 03:11:48 -08003633 .proc_handler = cdrom_sysctl_info,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003634 },
3635 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003636 .procname = "autoclose",
3637 .data = &cdrom_sysctl_settings.autoclose,
3638 .maxlen = sizeof(int),
3639 .mode = 0644,
Eric W. Biederman6d456112009-11-16 03:11:48 -08003640 .proc_handler = cdrom_sysctl_handler,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003641 },
3642 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003643 .procname = "autoeject",
3644 .data = &cdrom_sysctl_settings.autoeject,
3645 .maxlen = sizeof(int),
3646 .mode = 0644,
Eric W. Biederman6d456112009-11-16 03:11:48 -08003647 .proc_handler = cdrom_sysctl_handler,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003648 },
3649 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003650 .procname = "debug",
3651 .data = &cdrom_sysctl_settings.debug,
3652 .maxlen = sizeof(int),
3653 .mode = 0644,
Eric W. Biederman6d456112009-11-16 03:11:48 -08003654 .proc_handler = cdrom_sysctl_handler,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003655 },
3656 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003657 .procname = "lock",
3658 .data = &cdrom_sysctl_settings.lock,
3659 .maxlen = sizeof(int),
3660 .mode = 0644,
Eric W. Biederman6d456112009-11-16 03:11:48 -08003661 .proc_handler = cdrom_sysctl_handler,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003662 },
3663 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003664 .procname = "check_media",
3665 .data = &cdrom_sysctl_settings.check,
3666 .maxlen = sizeof(int),
3667 .mode = 0644,
Eric W. Biederman6d456112009-11-16 03:11:48 -08003668 .proc_handler = cdrom_sysctl_handler
Linus Torvalds1da177e2005-04-16 15:20:36 -07003669 },
Eric W. Biederman894d2492009-11-05 14:34:02 -08003670 { }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003671};
3672
Joe Perches90a3b892014-06-06 14:37:57 -07003673static struct ctl_table cdrom_cdrom_table[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003674 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003675 .procname = "cdrom",
3676 .maxlen = 0,
3677 .mode = 0555,
3678 .child = cdrom_table,
3679 },
Eric W. Biederman894d2492009-11-05 14:34:02 -08003680 { }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003681};
3682
3683/* Make sure that /proc/sys/dev is there */
Joe Perches90a3b892014-06-06 14:37:57 -07003684static struct ctl_table cdrom_root_table[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003685 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003686 .procname = "dev",
3687 .maxlen = 0,
3688 .mode = 0555,
3689 .child = cdrom_cdrom_table,
3690 },
Eric W. Biederman894d2492009-11-05 14:34:02 -08003691 { }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003692};
3693static struct ctl_table_header *cdrom_sysctl_header;
3694
3695static void cdrom_sysctl_register(void)
3696{
Guenter Roeckf04b47a2019-02-06 21:13:49 -08003697 static atomic_t initialized = ATOMIC_INIT(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003698
Guenter Roeckf04b47a2019-02-06 21:13:49 -08003699 if (!atomic_add_unless(&initialized, 1, 1))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003700 return;
3701
Eric W. Biederman0b4d4142007-02-14 00:34:09 -08003702 cdrom_sysctl_header = register_sysctl_table(cdrom_root_table);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003703
3704 /* set the defaults */
3705 cdrom_sysctl_settings.autoclose = autoclose;
3706 cdrom_sysctl_settings.autoeject = autoeject;
3707 cdrom_sysctl_settings.debug = debug;
3708 cdrom_sysctl_settings.lock = lockdoor;
3709 cdrom_sysctl_settings.check = check_media_type;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003710}
3711
3712static void cdrom_sysctl_unregister(void)
3713{
3714 if (cdrom_sysctl_header)
3715 unregister_sysctl_table(cdrom_sysctl_header);
3716}
3717
Akinobu Mita17672cf2008-03-26 12:08:59 +01003718#else /* CONFIG_SYSCTL */
3719
3720static void cdrom_sysctl_register(void)
3721{
3722}
3723
3724static void cdrom_sysctl_unregister(void)
3725{
3726}
3727
Linus Torvalds1da177e2005-04-16 15:20:36 -07003728#endif /* CONFIG_SYSCTL */
3729
3730static int __init cdrom_init(void)
3731{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003732 cdrom_sysctl_register();
Akinobu Mita17672cf2008-03-26 12:08:59 +01003733
Linus Torvalds1da177e2005-04-16 15:20:36 -07003734 return 0;
3735}
3736
3737static void __exit cdrom_exit(void)
3738{
Joe Perchese597cd02010-07-01 08:24:32 +02003739 pr_info("Uniform CD-ROM driver unloaded\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003740 cdrom_sysctl_unregister();
Linus Torvalds1da177e2005-04-16 15:20:36 -07003741}
3742
3743module_init(cdrom_init);
3744module_exit(cdrom_exit);
3745MODULE_LICENSE("GPL");