blob: 332c3aee134685edbd20bfb59a723f0deb378951 [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
Linus Torvalds1da177e2005-04-16 15:20:36 -0700268#include <linux/module.h>
269#include <linux/fs.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -0700270#include <linux/major.h>
271#include <linux/types.h>
272#include <linux/errno.h>
273#include <linux/kernel.h>
274#include <linux/mm.h>
275#include <linux/slab.h>
276#include <linux/cdrom.h>
277#include <linux/sysctl.h>
278#include <linux/proc_fs.h>
279#include <linux/blkpg.h>
280#include <linux/init.h>
281#include <linux/fcntl.h>
282#include <linux/blkdev.h>
283#include <linux/times.h>
284
285#include <asm/uaccess.h>
286
287/* used to tell the module to turn on full debugging messages */
Rusty Russell90ab5ee2012-01-13 09:32:20 +1030288static bool debug;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700289/* default compatibility mode */
Rusty Russell90ab5ee2012-01-13 09:32:20 +1030290static bool autoclose=1;
291static bool autoeject;
292static bool lockdoor = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700293/* will we ever get to use this... sigh. */
Rusty Russell90ab5ee2012-01-13 09:32:20 +1030294static bool check_media_type;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700295/* automatically restart mrw format */
Rusty Russell90ab5ee2012-01-13 09:32:20 +1030296static bool mrw_format_restart = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700297module_param(debug, bool, 0);
298module_param(autoclose, bool, 0);
299module_param(autoeject, bool, 0);
300module_param(lockdoor, bool, 0);
301module_param(check_media_type, bool, 0);
302module_param(mrw_format_restart, bool, 0);
303
Dave Young554988d2007-06-19 09:14:26 +0200304static DEFINE_MUTEX(cdrom_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700305
306static const char *mrw_format_status[] = {
307 "not mrw",
308 "bgformat inactive",
309 "bgformat active",
310 "mrw complete",
311};
312
313static const char *mrw_address_space[] = { "DMA", "GAA" };
314
Joe Perches5944b2c2014-05-04 17:05:02 -0700315#if (ERRLOGMASK != CD_NOTHING)
316#define cd_dbg(type, fmt, ...) \
Joe Perchese597cd02010-07-01 08:24:32 +0200317do { \
318 if ((ERRLOGMASK & type) || debug == 1) \
Joe Perches5944b2c2014-05-04 17:05:02 -0700319 pr_debug(fmt, ##__VA_ARGS__); \
Joe Perchese597cd02010-07-01 08:24:32 +0200320} while (0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700321#else
Joe Perches5944b2c2014-05-04 17:05:02 -0700322#define cd_dbg(type, fmt, ...) \
Joe Perchese597cd02010-07-01 08:24:32 +0200323do { \
324 if (0 && (ERRLOGMASK & type) || debug == 1) \
Joe Perches5944b2c2014-05-04 17:05:02 -0700325 pr_debug(fmt, ##__VA_ARGS__); \
Joe Perchese597cd02010-07-01 08:24:32 +0200326} while (0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700327#endif
328
Linus Torvalds1da177e2005-04-16 15:20:36 -0700329/* The (cdo->capability & ~cdi->mask & CDC_XXX) construct was used in
330 a lot of places. This macro makes the code more clear. */
331#define CDROM_CAN(type) (cdi->ops->capability & ~cdi->mask & (type))
332
Jens Axboe2e11c202007-01-03 08:10:35 +0100333/*
334 * Another popular OS uses 7 seconds as the hard timeout for default
335 * commands, so it is a good choice for us as well.
336 */
337#define CDROM_DEF_TIMEOUT (7 * HZ)
338
Linus Torvalds1da177e2005-04-16 15:20:36 -0700339/* Not-exported routines. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700340
341int cdrom_get_last_written(struct cdrom_device_info *, long *);
342static int cdrom_get_next_writable(struct cdrom_device_info *, long *);
343static void cdrom_count_tracks(struct cdrom_device_info *, tracktype*);
344
345static int cdrom_mrw_exit(struct cdrom_device_info *cdi);
346
347static int cdrom_get_disc_info(struct cdrom_device_info *cdi, disc_information *di);
348
Linus Torvalds1da177e2005-04-16 15:20:36 -0700349static void cdrom_sysctl_register(void);
Akinobu Mita17672cf2008-03-26 12:08:59 +0100350
Akinobu Mita7fd097d2008-03-26 12:09:02 +0100351static LIST_HEAD(cdrom_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700352
353static int cdrom_dummy_generic_packet(struct cdrom_device_info *cdi,
354 struct packet_command *cgc)
355{
356 if (cgc->sense) {
357 cgc->sense->sense_key = 0x05;
358 cgc->sense->asc = 0x20;
359 cgc->sense->ascq = 0x00;
360 }
361
362 cgc->stat = -EIO;
363 return -EIO;
364}
365
366/* This macro makes sure we don't have to check on cdrom_device_ops
367 * existence in the run-time routines below. Change_capability is a
368 * hack to have the capability flags defined const, while we can still
369 * change it here without gcc complaining at every line.
370 */
371#define ENSURE(call, bits) if (cdo->call == NULL) *change_capability &= ~(bits)
372
373int register_cdrom(struct cdrom_device_info *cdi)
374{
375 static char banner_printed;
376 struct cdrom_device_ops *cdo = cdi->ops;
377 int *change_capability = (int *)&cdo->capability; /* hack */
378
Joe Perches5944b2c2014-05-04 17:05:02 -0700379 cd_dbg(CD_OPEN, "entering register_cdrom\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700380
381 if (cdo->open == NULL || cdo->release == NULL)
Akinobu Mita3c3f4e02008-03-26 12:09:00 +0100382 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700383 if (!banner_printed) {
Joe Perchese597cd02010-07-01 08:24:32 +0200384 pr_info("Uniform CD-ROM driver " REVISION "\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700385 banner_printed = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700386 cdrom_sysctl_register();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700387 }
388
389 ENSURE(drive_status, CDC_DRIVE_STATUS );
Simon Arlottb8cf0e02011-02-09 14:21:07 +0100390 if (cdo->check_events == NULL && cdo->media_changed == NULL)
391 *change_capability = ~(CDC_MEDIA_CHANGED | CDC_SELECT_DISC);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700392 ENSURE(tray_move, CDC_CLOSE_TRAY | CDC_OPEN_TRAY);
393 ENSURE(lock_door, CDC_LOCK);
394 ENSURE(select_speed, CDC_SELECT_SPEED);
395 ENSURE(get_last_session, CDC_MULTI_SESSION);
396 ENSURE(get_mcn, CDC_MCN);
397 ENSURE(reset, CDC_RESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700398 ENSURE(generic_packet, CDC_GENERIC_PACKET);
399 cdi->mc_flags = 0;
400 cdo->n_minors = 0;
401 cdi->options = CDO_USE_FFLAGS;
402
403 if (autoclose==1 && CDROM_CAN(CDC_CLOSE_TRAY))
404 cdi->options |= (int) CDO_AUTO_CLOSE;
405 if (autoeject==1 && CDROM_CAN(CDC_OPEN_TRAY))
406 cdi->options |= (int) CDO_AUTO_EJECT;
407 if (lockdoor==1)
408 cdi->options |= (int) CDO_LOCK;
409 if (check_media_type==1)
410 cdi->options |= (int) CDO_CHECK_TYPE;
411
412 if (CDROM_CAN(CDC_MRW_W))
413 cdi->exit = cdrom_mrw_exit;
414
415 if (cdi->disk)
416 cdi->cdda_method = CDDA_BPC_FULL;
417 else
418 cdi->cdda_method = CDDA_OLD;
419
420 if (!cdo->generic_packet)
421 cdo->generic_packet = cdrom_dummy_generic_packet;
422
Joe Perches5944b2c2014-05-04 17:05:02 -0700423 cd_dbg(CD_REG_UNREG, "drive \"/dev/%s\" registered\n", cdi->name);
Dave Young554988d2007-06-19 09:14:26 +0200424 mutex_lock(&cdrom_mutex);
Akinobu Mita7fd097d2008-03-26 12:09:02 +0100425 list_add(&cdi->list, &cdrom_list);
Dave Young554988d2007-06-19 09:14:26 +0200426 mutex_unlock(&cdrom_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700427 return 0;
428}
429#undef ENSURE
430
Akinobu Mita0a0c4112008-03-26 12:09:02 +0100431void unregister_cdrom(struct cdrom_device_info *cdi)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700432{
Joe Perches5944b2c2014-05-04 17:05:02 -0700433 cd_dbg(CD_OPEN, "entering unregister_cdrom\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700434
Dave Young554988d2007-06-19 09:14:26 +0200435 mutex_lock(&cdrom_mutex);
Akinobu Mita7fd097d2008-03-26 12:09:02 +0100436 list_del(&cdi->list);
Dave Young554988d2007-06-19 09:14:26 +0200437 mutex_unlock(&cdrom_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700438
439 if (cdi->exit)
440 cdi->exit(cdi);
441
442 cdi->ops->n_minors--;
Joe Perches5944b2c2014-05-04 17:05:02 -0700443 cd_dbg(CD_REG_UNREG, "drive \"/dev/%s\" unregistered\n", cdi->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700444}
445
446int cdrom_get_media_event(struct cdrom_device_info *cdi,
447 struct media_event_desc *med)
448{
449 struct packet_command cgc;
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200450 unsigned char buffer[8];
451 struct event_header *eh = (struct event_header *) buffer;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700452
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200453 init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700454 cgc.cmd[0] = GPCMD_GET_EVENT_STATUS_NOTIFICATION;
455 cgc.cmd[1] = 1; /* IMMED */
456 cgc.cmd[4] = 1 << 4; /* media event */
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200457 cgc.cmd[8] = sizeof(buffer);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700458 cgc.quiet = 1;
459
460 if (cdi->ops->generic_packet(cdi, &cgc))
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200461 return 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700462
463 if (be16_to_cpu(eh->data_len) < sizeof(*med))
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200464 return 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700465
466 if (eh->nea || eh->notification_class != 0x4)
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200467 return 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700468
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200469 memcpy(med, &buffer[sizeof(*eh)], sizeof(*med));
470 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700471}
472
473/*
474 * the first prototypes used 0x2c as the page code for the mrw mode page,
475 * subsequently this was changed to 0x03. probe the one used by this drive
476 */
477static int cdrom_mrw_probe_pc(struct cdrom_device_info *cdi)
478{
479 struct packet_command cgc;
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200480 char buffer[16];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700481
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200482 init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700483
484 cgc.timeout = HZ;
485 cgc.quiet = 1;
486
487 if (!cdrom_mode_sense(cdi, &cgc, MRW_MODE_PC, 0)) {
488 cdi->mrw_mode_page = MRW_MODE_PC;
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200489 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700490 } else if (!cdrom_mode_sense(cdi, &cgc, MRW_MODE_PC_PRE1, 0)) {
491 cdi->mrw_mode_page = MRW_MODE_PC_PRE1;
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200492 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700493 }
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200494
495 return 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700496}
497
498static int cdrom_is_mrw(struct cdrom_device_info *cdi, int *write)
499{
500 struct packet_command cgc;
501 struct mrw_feature_desc *mfd;
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200502 unsigned char buffer[16];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700503 int ret;
504
505 *write = 0;
506
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200507 init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700508
509 cgc.cmd[0] = GPCMD_GET_CONFIGURATION;
510 cgc.cmd[3] = CDF_MRW;
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200511 cgc.cmd[8] = sizeof(buffer);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700512 cgc.quiet = 1;
513
514 if ((ret = cdi->ops->generic_packet(cdi, &cgc)))
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200515 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700516
517 mfd = (struct mrw_feature_desc *)&buffer[sizeof(struct feature_header)];
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200518 if (be16_to_cpu(mfd->feature_code) != CDF_MRW)
519 return 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700520 *write = mfd->write;
521
522 if ((ret = cdrom_mrw_probe_pc(cdi))) {
523 *write = 0;
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200524 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700525 }
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200526
527 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700528}
529
530static int cdrom_mrw_bgformat(struct cdrom_device_info *cdi, int cont)
531{
532 struct packet_command cgc;
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200533 unsigned char buffer[12];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700534 int ret;
535
Joe Perchese597cd02010-07-01 08:24:32 +0200536 pr_info("%sstarting format\n", cont ? "Re" : "");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700537
538 /*
539 * FmtData bit set (bit 4), format type is 1
540 */
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200541 init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_WRITE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700542 cgc.cmd[0] = GPCMD_FORMAT_UNIT;
543 cgc.cmd[1] = (1 << 4) | 1;
544
545 cgc.timeout = 5 * 60 * HZ;
546
547 /*
548 * 4 byte format list header, 8 byte format list descriptor
549 */
550 buffer[1] = 1 << 1;
551 buffer[3] = 8;
552
553 /*
554 * nr_blocks field
555 */
556 buffer[4] = 0xff;
557 buffer[5] = 0xff;
558 buffer[6] = 0xff;
559 buffer[7] = 0xff;
560
561 buffer[8] = 0x24 << 2;
562 buffer[11] = cont;
563
564 ret = cdi->ops->generic_packet(cdi, &cgc);
565 if (ret)
Joe Perchese597cd02010-07-01 08:24:32 +0200566 pr_info("bgformat failed\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700567
568 return ret;
569}
570
571static int cdrom_mrw_bgformat_susp(struct cdrom_device_info *cdi, int immed)
572{
573 struct packet_command cgc;
574
575 init_cdrom_command(&cgc, NULL, 0, CGC_DATA_NONE);
576 cgc.cmd[0] = GPCMD_CLOSE_TRACK;
577
578 /*
579 * Session = 1, Track = 0
580 */
581 cgc.cmd[1] = !!immed;
582 cgc.cmd[2] = 1 << 1;
583
584 cgc.timeout = 5 * 60 * HZ;
585
586 return cdi->ops->generic_packet(cdi, &cgc);
587}
588
589static int cdrom_flush_cache(struct cdrom_device_info *cdi)
590{
591 struct packet_command cgc;
592
593 init_cdrom_command(&cgc, NULL, 0, CGC_DATA_NONE);
594 cgc.cmd[0] = GPCMD_FLUSH_CACHE;
595
596 cgc.timeout = 5 * 60 * HZ;
597
598 return cdi->ops->generic_packet(cdi, &cgc);
599}
600
601static int cdrom_mrw_exit(struct cdrom_device_info *cdi)
602{
603 disc_information di;
604 int ret;
605
606 ret = cdrom_get_disc_info(cdi, &di);
607 if (ret < 0 || ret < (int)offsetof(typeof(di),disc_type))
608 return 1;
609
610 ret = 0;
611 if (di.mrw_status == CDM_MRW_BGFORMAT_ACTIVE) {
Joe Perchese597cd02010-07-01 08:24:32 +0200612 pr_info("issuing MRW background format suspend\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700613 ret = cdrom_mrw_bgformat_susp(cdi, 0);
614 }
615
Jens Axboe7da21a02005-05-01 12:12:52 -0700616 if (!ret && cdi->media_written)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700617 ret = cdrom_flush_cache(cdi);
618
619 return ret;
620}
621
622static int cdrom_mrw_set_lba_space(struct cdrom_device_info *cdi, int space)
623{
624 struct packet_command cgc;
625 struct mode_page_header *mph;
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200626 char buffer[16];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700627 int ret, offset, size;
628
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200629 init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700630
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200631 cgc.buffer = buffer;
632 cgc.buflen = sizeof(buffer);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700633
634 if ((ret = cdrom_mode_sense(cdi, &cgc, cdi->mrw_mode_page, 0)))
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200635 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700636
637 mph = (struct mode_page_header *) buffer;
638 offset = be16_to_cpu(mph->desc_length);
639 size = be16_to_cpu(mph->mode_data_length) + 2;
640
641 buffer[offset + 3] = space;
642 cgc.buflen = size;
643
644 if ((ret = cdrom_mode_select(cdi, &cgc)))
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200645 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700646
Joe Perchese597cd02010-07-01 08:24:32 +0200647 pr_info("%s: mrw address space %s selected\n",
648 cdi->name, mrw_address_space[space]);
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200649 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700650}
651
652static int cdrom_get_random_writable(struct cdrom_device_info *cdi,
653 struct rwrt_feature_desc *rfd)
654{
655 struct packet_command cgc;
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200656 char buffer[24];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700657 int ret;
658
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200659 init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700660
661 cgc.cmd[0] = GPCMD_GET_CONFIGURATION; /* often 0x46 */
662 cgc.cmd[3] = CDF_RWRT; /* often 0x0020 */
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200663 cgc.cmd[8] = sizeof(buffer); /* often 0x18 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700664 cgc.quiet = 1;
665
666 if ((ret = cdi->ops->generic_packet(cdi, &cgc)))
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200667 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700668
669 memcpy(rfd, &buffer[sizeof(struct feature_header)], sizeof (*rfd));
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200670 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700671}
672
673static int cdrom_has_defect_mgt(struct cdrom_device_info *cdi)
674{
675 struct packet_command cgc;
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200676 char buffer[16];
Alexey Dobriyan56052d52005-12-01 17:10:40 -0500677 __be16 *feature_code;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700678 int ret;
679
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200680 init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700681
682 cgc.cmd[0] = GPCMD_GET_CONFIGURATION;
683 cgc.cmd[3] = CDF_HWDM;
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200684 cgc.cmd[8] = sizeof(buffer);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700685 cgc.quiet = 1;
686
687 if ((ret = cdi->ops->generic_packet(cdi, &cgc)))
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200688 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700689
Alexey Dobriyan56052d52005-12-01 17:10:40 -0500690 feature_code = (__be16 *) &buffer[sizeof(struct feature_header)];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700691 if (be16_to_cpu(*feature_code) == CDF_HWDM)
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200692 return 0;
693
694 return 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700695}
696
697
698static int cdrom_is_random_writable(struct cdrom_device_info *cdi, int *write)
699{
700 struct rwrt_feature_desc rfd;
701 int ret;
702
703 *write = 0;
704
705 if ((ret = cdrom_get_random_writable(cdi, &rfd)))
706 return ret;
707
708 if (CDF_RWRT == be16_to_cpu(rfd.feature_code))
709 *write = 1;
710
711 return 0;
712}
713
714static int cdrom_media_erasable(struct cdrom_device_info *cdi)
715{
716 disc_information di;
717 int ret;
718
719 ret = cdrom_get_disc_info(cdi, &di);
720 if (ret < 0 || ret < offsetof(typeof(di), n_first_track))
721 return -1;
722
723 return di.erasable;
724}
725
726/*
727 * FIXME: check RO bit
728 */
729static int cdrom_dvdram_open_write(struct cdrom_device_info *cdi)
730{
731 int ret = cdrom_media_erasable(cdi);
732
733 /*
734 * allow writable open if media info read worked and media is
735 * erasable, _or_ if it fails since not all drives support it
736 */
737 if (!ret)
738 return 1;
739
740 return 0;
741}
742
743static int cdrom_mrw_open_write(struct cdrom_device_info *cdi)
744{
745 disc_information di;
746 int ret;
747
748 /*
749 * always reset to DMA lba space on open
750 */
751 if (cdrom_mrw_set_lba_space(cdi, MRW_LBA_DMA)) {
Joe Perchese597cd02010-07-01 08:24:32 +0200752 pr_err("failed setting lba address space\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700753 return 1;
754 }
755
756 ret = cdrom_get_disc_info(cdi, &di);
757 if (ret < 0 || ret < offsetof(typeof(di),disc_type))
758 return 1;
759
760 if (!di.erasable)
761 return 1;
762
763 /*
764 * mrw_status
765 * 0 - not MRW formatted
766 * 1 - MRW bgformat started, but not running or complete
767 * 2 - MRW bgformat in progress
768 * 3 - MRW formatting complete
769 */
770 ret = 0;
Joe Perchese597cd02010-07-01 08:24:32 +0200771 pr_info("open: mrw_status '%s'\n", mrw_format_status[di.mrw_status]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700772 if (!di.mrw_status)
773 ret = 1;
774 else if (di.mrw_status == CDM_MRW_BGFORMAT_INACTIVE &&
775 mrw_format_restart)
776 ret = cdrom_mrw_bgformat(cdi, 1);
777
778 return ret;
779}
780
781static int mo_open_write(struct cdrom_device_info *cdi)
782{
783 struct packet_command cgc;
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200784 char buffer[255];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700785 int ret;
786
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200787 init_cdrom_command(&cgc, &buffer, 4, CGC_DATA_READ);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700788 cgc.quiet = 1;
789
790 /*
791 * obtain write protect information as per
792 * drivers/scsi/sd.c:sd_read_write_protect_flag
793 */
794
795 ret = cdrom_mode_sense(cdi, &cgc, GPMODE_ALL_PAGES, 0);
796 if (ret)
797 ret = cdrom_mode_sense(cdi, &cgc, GPMODE_VENDOR_PAGE, 0);
798 if (ret) {
799 cgc.buflen = 255;
800 ret = cdrom_mode_sense(cdi, &cgc, GPMODE_ALL_PAGES, 0);
801 }
802
803 /* drive gave us no info, let the user go ahead */
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200804 if (ret)
805 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700806
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200807 return buffer[3] & 0x80;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700808}
809
810static int cdrom_ram_open_write(struct cdrom_device_info *cdi)
811{
812 struct rwrt_feature_desc rfd;
813 int ret;
814
815 if ((ret = cdrom_has_defect_mgt(cdi)))
816 return ret;
817
818 if ((ret = cdrom_get_random_writable(cdi, &rfd)))
819 return ret;
820 else if (CDF_RWRT == be16_to_cpu(rfd.feature_code))
821 ret = !rfd.curr;
822
Joe Perches5944b2c2014-05-04 17:05:02 -0700823 cd_dbg(CD_OPEN, "can open for random write\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700824 return ret;
825}
826
827static void cdrom_mmc3_profile(struct cdrom_device_info *cdi)
828{
829 struct packet_command cgc;
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200830 char buffer[32];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700831 int ret, mmc3_profile;
832
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200833 init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700834
835 cgc.cmd[0] = GPCMD_GET_CONFIGURATION;
836 cgc.cmd[1] = 0;
837 cgc.cmd[2] = cgc.cmd[3] = 0; /* Starting Feature Number */
FUJITA Tomonorifce53842008-07-04 09:33:01 +0200838 cgc.cmd[8] = sizeof(buffer); /* Allocation Length */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700839 cgc.quiet = 1;
840
841 if ((ret = cdi->ops->generic_packet(cdi, &cgc)))
842 mmc3_profile = 0xffff;
843 else
844 mmc3_profile = (buffer[6] << 8) | buffer[7];
845
846 cdi->mmc3_profile = mmc3_profile;
847}
848
849static int cdrom_is_dvd_rw(struct cdrom_device_info *cdi)
850{
851 switch (cdi->mmc3_profile) {
852 case 0x12: /* DVD-RAM */
853 case 0x1A: /* DVD+RW */
854 return 0;
855 default:
856 return 1;
857 }
858}
859
860/*
861 * returns 0 for ok to open write, non-0 to disallow
862 */
863static int cdrom_open_write(struct cdrom_device_info *cdi)
864{
865 int mrw, mrw_write, ram_write;
866 int ret = 1;
867
868 mrw = 0;
869 if (!cdrom_is_mrw(cdi, &mrw_write))
870 mrw = 1;
871
872 if (CDROM_CAN(CDC_MO_DRIVE))
873 ram_write = 1;
874 else
875 (void) cdrom_is_random_writable(cdi, &ram_write);
876
877 if (mrw)
878 cdi->mask &= ~CDC_MRW;
879 else
880 cdi->mask |= CDC_MRW;
881
882 if (mrw_write)
883 cdi->mask &= ~CDC_MRW_W;
884 else
885 cdi->mask |= CDC_MRW_W;
886
887 if (ram_write)
888 cdi->mask &= ~CDC_RAM;
889 else
890 cdi->mask |= CDC_RAM;
891
892 if (CDROM_CAN(CDC_MRW_W))
893 ret = cdrom_mrw_open_write(cdi);
894 else if (CDROM_CAN(CDC_DVD_RAM))
895 ret = cdrom_dvdram_open_write(cdi);
896 else if (CDROM_CAN(CDC_RAM) &&
897 !CDROM_CAN(CDC_CD_R|CDC_CD_RW|CDC_DVD|CDC_DVD_R|CDC_MRW|CDC_MO_DRIVE))
898 ret = cdrom_ram_open_write(cdi);
899 else if (CDROM_CAN(CDC_MO_DRIVE))
900 ret = mo_open_write(cdi);
901 else if (!cdrom_is_dvd_rw(cdi))
902 ret = 0;
903
904 return ret;
905}
906
907static void cdrom_dvd_rw_close_write(struct cdrom_device_info *cdi)
908{
909 struct packet_command cgc;
910
911 if (cdi->mmc3_profile != 0x1a) {
Joe Perches5944b2c2014-05-04 17:05:02 -0700912 cd_dbg(CD_CLOSE, "%s: No DVD+RW\n", cdi->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700913 return;
914 }
915
916 if (!cdi->media_written) {
Joe Perches5944b2c2014-05-04 17:05:02 -0700917 cd_dbg(CD_CLOSE, "%s: DVD+RW media clean\n", cdi->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700918 return;
919 }
920
Joe Perchese597cd02010-07-01 08:24:32 +0200921 pr_info("%s: dirty DVD+RW media, \"finalizing\"\n", cdi->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700922
923 init_cdrom_command(&cgc, NULL, 0, CGC_DATA_NONE);
924 cgc.cmd[0] = GPCMD_FLUSH_CACHE;
925 cgc.timeout = 30*HZ;
926 cdi->ops->generic_packet(cdi, &cgc);
927
928 init_cdrom_command(&cgc, NULL, 0, CGC_DATA_NONE);
929 cgc.cmd[0] = GPCMD_CLOSE_TRACK;
930 cgc.timeout = 3000*HZ;
931 cgc.quiet = 1;
932 cdi->ops->generic_packet(cdi, &cgc);
933
934 init_cdrom_command(&cgc, NULL, 0, CGC_DATA_NONE);
935 cgc.cmd[0] = GPCMD_CLOSE_TRACK;
936 cgc.cmd[2] = 2; /* Close session */
937 cgc.quiet = 1;
938 cgc.timeout = 3000*HZ;
939 cdi->ops->generic_packet(cdi, &cgc);
940
941 cdi->media_written = 0;
942}
943
944static int cdrom_close_write(struct cdrom_device_info *cdi)
945{
946#if 0
947 return cdrom_flush_cache(cdi);
948#else
949 return 0;
950#endif
951}
952
Linus Torvalds1da177e2005-04-16 15:20:36 -0700953static
Joe Perches82b91542014-05-04 17:05:05 -0700954int open_for_data(struct cdrom_device_info *cdi)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700955{
956 int ret;
957 struct cdrom_device_ops *cdo = cdi->ops;
958 tracktype tracks;
Joe Perches5944b2c2014-05-04 17:05:02 -0700959 cd_dbg(CD_OPEN, "entering open_for_data\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700960 /* Check if the driver can report drive status. If it can, we
961 can do clever things. If it can't, well, we at least tried! */
962 if (cdo->drive_status != NULL) {
963 ret = cdo->drive_status(cdi, CDSL_CURRENT);
Joe Perches5944b2c2014-05-04 17:05:02 -0700964 cd_dbg(CD_OPEN, "drive_status=%d\n", ret);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700965 if (ret == CDS_TRAY_OPEN) {
Joe Perches5944b2c2014-05-04 17:05:02 -0700966 cd_dbg(CD_OPEN, "the tray is open...\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700967 /* can/may i close it? */
968 if (CDROM_CAN(CDC_CLOSE_TRAY) &&
969 cdi->options & CDO_AUTO_CLOSE) {
Joe Perches5944b2c2014-05-04 17:05:02 -0700970 cd_dbg(CD_OPEN, "trying to close the tray\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700971 ret=cdo->tray_move(cdi,0);
972 if (ret) {
Joe Perches5944b2c2014-05-04 17:05:02 -0700973 cd_dbg(CD_OPEN, "bummer. tried to close the tray but failed.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700974 /* Ignore the error from the low
975 level driver. We don't care why it
976 couldn't close the tray. We only care
977 that there is no disc in the drive,
978 since that is the _REAL_ problem here.*/
979 ret=-ENOMEDIUM;
980 goto clean_up_and_return;
981 }
982 } else {
Joe Perches5944b2c2014-05-04 17:05:02 -0700983 cd_dbg(CD_OPEN, "bummer. this drive can't close the tray.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700984 ret=-ENOMEDIUM;
985 goto clean_up_and_return;
986 }
987 /* Ok, the door should be closed now.. Check again */
988 ret = cdo->drive_status(cdi, CDSL_CURRENT);
989 if ((ret == CDS_NO_DISC) || (ret==CDS_TRAY_OPEN)) {
Joe Perches5944b2c2014-05-04 17:05:02 -0700990 cd_dbg(CD_OPEN, "bummer. the tray is still not closed.\n");
991 cd_dbg(CD_OPEN, "tray might not contain a medium\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700992 ret=-ENOMEDIUM;
993 goto clean_up_and_return;
994 }
Joe Perches5944b2c2014-05-04 17:05:02 -0700995 cd_dbg(CD_OPEN, "the tray is now closed\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700996 }
997 /* the door should be closed now, check for the disc */
998 ret = cdo->drive_status(cdi, CDSL_CURRENT);
999 if (ret!=CDS_DISC_OK) {
1000 ret = -ENOMEDIUM;
1001 goto clean_up_and_return;
1002 }
1003 }
1004 cdrom_count_tracks(cdi, &tracks);
1005 if (tracks.error == CDS_NO_DISC) {
Joe Perches5944b2c2014-05-04 17:05:02 -07001006 cd_dbg(CD_OPEN, "bummer. no disc.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001007 ret=-ENOMEDIUM;
1008 goto clean_up_and_return;
1009 }
1010 /* CD-Players which don't use O_NONBLOCK, workman
1011 * for example, need bit CDO_CHECK_TYPE cleared! */
1012 if (tracks.data==0) {
1013 if (cdi->options & CDO_CHECK_TYPE) {
1014 /* give people a warning shot, now that CDO_CHECK_TYPE
1015 is the default case! */
Joe Perches5944b2c2014-05-04 17:05:02 -07001016 cd_dbg(CD_OPEN, "bummer. wrong media type.\n");
1017 cd_dbg(CD_WARNING, "pid %d must open device O_NONBLOCK!\n",
1018 (unsigned int)task_pid_nr(current));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001019 ret=-EMEDIUMTYPE;
1020 goto clean_up_and_return;
1021 }
1022 else {
Joe Perches5944b2c2014-05-04 17:05:02 -07001023 cd_dbg(CD_OPEN, "wrong media type, but CDO_CHECK_TYPE not set\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001024 }
1025 }
1026
Joe Perches5944b2c2014-05-04 17:05:02 -07001027 cd_dbg(CD_OPEN, "all seems well, opening the devicen");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001028
1029 /* all seems well, we can open the device */
1030 ret = cdo->open(cdi, 0); /* open for data */
Joe Perches5944b2c2014-05-04 17:05:02 -07001031 cd_dbg(CD_OPEN, "opening the device gave me %d\n", ret);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001032 /* After all this careful checking, we shouldn't have problems
1033 opening the device, but we don't want the device locked if
1034 this somehow fails... */
1035 if (ret) {
Joe Perches5944b2c2014-05-04 17:05:02 -07001036 cd_dbg(CD_OPEN, "open device failed\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001037 goto clean_up_and_return;
1038 }
1039 if (CDROM_CAN(CDC_LOCK) && (cdi->options & CDO_LOCK)) {
1040 cdo->lock_door(cdi, 1);
Joe Perches5944b2c2014-05-04 17:05:02 -07001041 cd_dbg(CD_OPEN, "door locked\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001042 }
Joe Perches5944b2c2014-05-04 17:05:02 -07001043 cd_dbg(CD_OPEN, "device opened successfully\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001044 return ret;
1045
1046 /* Something failed. Try to unlock the drive, because some drivers
1047 (notably ide-cd) lock the drive after every command. This produced
1048 a nasty bug where after mount failed, the drive would remain locked!
1049 This ensures that the drive gets unlocked after a mount fails. This
1050 is a goto to avoid bloating the driver with redundant code. */
1051clean_up_and_return:
Joe Perches5944b2c2014-05-04 17:05:02 -07001052 cd_dbg(CD_OPEN, "open failed\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001053 if (CDROM_CAN(CDC_LOCK) && cdi->options & CDO_LOCK) {
1054 cdo->lock_door(cdi, 0);
Joe Perches5944b2c2014-05-04 17:05:02 -07001055 cd_dbg(CD_OPEN, "door unlocked\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001056 }
1057 return ret;
1058}
1059
Joe Perches82b91542014-05-04 17:05:05 -07001060/* We use the open-option O_NONBLOCK to indicate that the
1061 * purpose of opening is only for subsequent ioctl() calls; no device
1062 * integrity checks are performed.
1063 *
1064 * We hope that all cd-player programs will adopt this convention. It
1065 * is in their own interest: device control becomes a lot easier
1066 * this way.
1067 */
1068int cdrom_open(struct cdrom_device_info *cdi, struct block_device *bdev,
1069 fmode_t mode)
1070{
1071 int ret;
1072
1073 cd_dbg(CD_OPEN, "entering cdrom_open\n");
1074
1075 /* open is event synchronization point, check events first */
1076 check_disk_change(bdev);
1077
1078 /* if this was a O_NONBLOCK open and we should honor the flags,
1079 * do a quick open without drive/disc integrity checks. */
1080 cdi->use_count++;
1081 if ((mode & FMODE_NDELAY) && (cdi->options & CDO_USE_FFLAGS)) {
1082 ret = cdi->ops->open(cdi, 1);
1083 } else {
1084 ret = open_for_data(cdi);
1085 if (ret)
1086 goto err;
1087 cdrom_mmc3_profile(cdi);
1088 if (mode & FMODE_WRITE) {
1089 ret = -EROFS;
1090 if (cdrom_open_write(cdi))
1091 goto err_release;
1092 if (!CDROM_CAN(CDC_RAM))
1093 goto err_release;
1094 ret = 0;
1095 cdi->media_written = 0;
1096 }
1097 }
1098
1099 if (ret)
1100 goto err;
1101
1102 cd_dbg(CD_OPEN, "Use count for \"/dev/%s\" now %d\n",
1103 cdi->name, cdi->use_count);
1104 return 0;
1105err_release:
1106 if (CDROM_CAN(CDC_LOCK) && cdi->options & CDO_LOCK) {
1107 cdi->ops->lock_door(cdi, 0);
1108 cd_dbg(CD_OPEN, "door unlocked\n");
1109 }
1110 cdi->ops->release(cdi);
1111err:
1112 cdi->use_count--;
1113 return ret;
1114}
1115
Linus Torvalds1da177e2005-04-16 15:20:36 -07001116/* This code is similar to that in open_for_data. The routine is called
1117 whenever an audio play operation is requested.
1118*/
Adrian Bunkecb80c62008-03-04 11:23:51 +01001119static int check_for_audio_disc(struct cdrom_device_info * cdi,
1120 struct cdrom_device_ops * cdo)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001121{
1122 int ret;
1123 tracktype tracks;
Joe Perches5944b2c2014-05-04 17:05:02 -07001124 cd_dbg(CD_OPEN, "entering check_for_audio_disc\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001125 if (!(cdi->options & CDO_CHECK_TYPE))
1126 return 0;
1127 if (cdo->drive_status != NULL) {
1128 ret = cdo->drive_status(cdi, CDSL_CURRENT);
Joe Perches5944b2c2014-05-04 17:05:02 -07001129 cd_dbg(CD_OPEN, "drive_status=%d\n", ret);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001130 if (ret == CDS_TRAY_OPEN) {
Joe Perches5944b2c2014-05-04 17:05:02 -07001131 cd_dbg(CD_OPEN, "the tray is open...\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001132 /* can/may i close it? */
1133 if (CDROM_CAN(CDC_CLOSE_TRAY) &&
1134 cdi->options & CDO_AUTO_CLOSE) {
Joe Perches5944b2c2014-05-04 17:05:02 -07001135 cd_dbg(CD_OPEN, "trying to close the tray\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001136 ret=cdo->tray_move(cdi,0);
1137 if (ret) {
Joe Perches5944b2c2014-05-04 17:05:02 -07001138 cd_dbg(CD_OPEN, "bummer. tried to close tray but failed.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001139 /* Ignore the error from the low
1140 level driver. We don't care why it
1141 couldn't close the tray. We only care
1142 that there is no disc in the drive,
1143 since that is the _REAL_ problem here.*/
1144 return -ENOMEDIUM;
1145 }
1146 } else {
Joe Perches5944b2c2014-05-04 17:05:02 -07001147 cd_dbg(CD_OPEN, "bummer. this driver can't close the tray.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001148 return -ENOMEDIUM;
1149 }
1150 /* Ok, the door should be closed now.. Check again */
1151 ret = cdo->drive_status(cdi, CDSL_CURRENT);
1152 if ((ret == CDS_NO_DISC) || (ret==CDS_TRAY_OPEN)) {
Joe Perches5944b2c2014-05-04 17:05:02 -07001153 cd_dbg(CD_OPEN, "bummer. the tray is still not closed.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001154 return -ENOMEDIUM;
1155 }
1156 if (ret!=CDS_DISC_OK) {
Joe Perches5944b2c2014-05-04 17:05:02 -07001157 cd_dbg(CD_OPEN, "bummer. disc isn't ready.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001158 return -EIO;
1159 }
Joe Perches5944b2c2014-05-04 17:05:02 -07001160 cd_dbg(CD_OPEN, "the tray is now closed\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001161 }
1162 }
1163 cdrom_count_tracks(cdi, &tracks);
1164 if (tracks.error)
1165 return(tracks.error);
1166
1167 if (tracks.audio==0)
1168 return -EMEDIUMTYPE;
1169
1170 return 0;
1171}
1172
Al Virobbc1cc92007-10-07 17:54:28 -04001173void cdrom_release(struct cdrom_device_info *cdi, fmode_t mode)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001174{
1175 struct cdrom_device_ops *cdo = cdi->ops;
1176 int opened_for_data;
1177
Joe Perches5944b2c2014-05-04 17:05:02 -07001178 cd_dbg(CD_CLOSE, "entering cdrom_release\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001179
1180 if (cdi->use_count > 0)
1181 cdi->use_count--;
Borislav Petkov35841f72008-02-06 01:38:08 -08001182
1183 if (cdi->use_count == 0) {
Joe Perches5944b2c2014-05-04 17:05:02 -07001184 cd_dbg(CD_CLOSE, "Use count for \"/dev/%s\" now zero\n",
1185 cdi->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001186 cdrom_dvd_rw_close_write(cdi);
Borislav Petkov35841f72008-02-06 01:38:08 -08001187
Paolo Bonzinicdccaa92012-02-08 20:03:14 +01001188 if ((cdo->capability & CDC_LOCK) && !cdi->keeplocked) {
Joe Perches5944b2c2014-05-04 17:05:02 -07001189 cd_dbg(CD_CLOSE, "Unlocking door!\n");
Borislav Petkov35841f72008-02-06 01:38:08 -08001190 cdo->lock_door(cdi, 0);
1191 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001192 }
Borislav Petkov35841f72008-02-06 01:38:08 -08001193
Linus Torvalds1da177e2005-04-16 15:20:36 -07001194 opened_for_data = !(cdi->options & CDO_USE_FFLAGS) ||
Al Virobbc1cc92007-10-07 17:54:28 -04001195 !(mode & FMODE_NDELAY);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001196
1197 /*
1198 * flush cache on last write release
1199 */
1200 if (CDROM_CAN(CDC_RAM) && !cdi->use_count && cdi->for_data)
1201 cdrom_close_write(cdi);
1202
1203 cdo->release(cdi);
1204 if (cdi->use_count == 0) { /* last process that closes dev*/
1205 if (opened_for_data &&
1206 cdi->options & CDO_AUTO_EJECT && CDROM_CAN(CDC_OPEN_TRAY))
1207 cdo->tray_move(cdi, 1);
1208 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001209}
1210
1211static int cdrom_read_mech_status(struct cdrom_device_info *cdi,
1212 struct cdrom_changer_info *buf)
1213{
1214 struct packet_command cgc;
1215 struct cdrom_device_ops *cdo = cdi->ops;
1216 int length;
1217
1218 /*
1219 * Sanyo changer isn't spec compliant (doesn't use regular change
1220 * LOAD_UNLOAD command, and it doesn't implement the mech status
1221 * command below
1222 */
1223 if (cdi->sanyo_slot) {
1224 buf->hdr.nslots = 3;
1225 buf->hdr.curslot = cdi->sanyo_slot == 3 ? 0 : cdi->sanyo_slot;
1226 for (length = 0; length < 3; length++) {
1227 buf->slots[length].disc_present = 1;
1228 buf->slots[length].change = 0;
1229 }
1230 return 0;
1231 }
1232
1233 length = sizeof(struct cdrom_mechstat_header) +
1234 cdi->capacity * sizeof(struct cdrom_slot);
1235
1236 init_cdrom_command(&cgc, buf, length, CGC_DATA_READ);
1237 cgc.cmd[0] = GPCMD_MECHANISM_STATUS;
1238 cgc.cmd[8] = (length >> 8) & 0xff;
1239 cgc.cmd[9] = length & 0xff;
1240 return cdo->generic_packet(cdi, &cgc);
1241}
1242
1243static int cdrom_slot_status(struct cdrom_device_info *cdi, int slot)
1244{
1245 struct cdrom_changer_info *info;
1246 int ret;
1247
Joe Perches5944b2c2014-05-04 17:05:02 -07001248 cd_dbg(CD_CHANGER, "entering cdrom_slot_status()\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001249 if (cdi->sanyo_slot)
1250 return CDS_NO_INFO;
1251
1252 info = kmalloc(sizeof(*info), GFP_KERNEL);
1253 if (!info)
1254 return -ENOMEM;
1255
1256 if ((ret = cdrom_read_mech_status(cdi, info)))
1257 goto out_free;
1258
1259 if (info->slots[slot].disc_present)
1260 ret = CDS_DISC_OK;
1261 else
1262 ret = CDS_NO_DISC;
1263
1264out_free:
1265 kfree(info);
1266 return ret;
1267}
1268
1269/* Return the number of slots for an ATAPI/SCSI cdrom,
1270 * return 1 if not a changer.
1271 */
1272int cdrom_number_of_slots(struct cdrom_device_info *cdi)
1273{
1274 int status;
1275 int nslots = 1;
1276 struct cdrom_changer_info *info;
1277
Joe Perches5944b2c2014-05-04 17:05:02 -07001278 cd_dbg(CD_CHANGER, "entering cdrom_number_of_slots()\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001279 /* cdrom_read_mech_status requires a valid value for capacity: */
1280 cdi->capacity = 0;
1281
1282 info = kmalloc(sizeof(*info), GFP_KERNEL);
1283 if (!info)
1284 return -ENOMEM;
1285
1286 if ((status = cdrom_read_mech_status(cdi, info)) == 0)
1287 nslots = info->hdr.nslots;
1288
1289 kfree(info);
1290 return nslots;
1291}
1292
1293
1294/* If SLOT < 0, unload the current slot. Otherwise, try to load SLOT. */
1295static int cdrom_load_unload(struct cdrom_device_info *cdi, int slot)
1296{
1297 struct packet_command cgc;
1298
Joe Perches5944b2c2014-05-04 17:05:02 -07001299 cd_dbg(CD_CHANGER, "entering cdrom_load_unload()\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001300 if (cdi->sanyo_slot && slot < 0)
1301 return 0;
1302
1303 init_cdrom_command(&cgc, NULL, 0, CGC_DATA_NONE);
1304 cgc.cmd[0] = GPCMD_LOAD_UNLOAD;
1305 cgc.cmd[4] = 2 + (slot >= 0);
1306 cgc.cmd[8] = slot;
1307 cgc.timeout = 60 * HZ;
1308
1309 /* The Sanyo 3 CD changer uses byte 7 of the
1310 GPCMD_TEST_UNIT_READY to command to switch CDs instead of
1311 using the GPCMD_LOAD_UNLOAD opcode. */
1312 if (cdi->sanyo_slot && -1 < slot) {
1313 cgc.cmd[0] = GPCMD_TEST_UNIT_READY;
1314 cgc.cmd[7] = slot;
1315 cgc.cmd[4] = cgc.cmd[8] = 0;
1316 cdi->sanyo_slot = slot ? slot : 3;
1317 }
1318
1319 return cdi->ops->generic_packet(cdi, &cgc);
1320}
1321
1322static int cdrom_select_disc(struct cdrom_device_info *cdi, int slot)
1323{
1324 struct cdrom_changer_info *info;
1325 int curslot;
1326 int ret;
1327
Joe Perches5944b2c2014-05-04 17:05:02 -07001328 cd_dbg(CD_CHANGER, "entering cdrom_select_disc()\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001329 if (!CDROM_CAN(CDC_SELECT_DISC))
1330 return -EDRIVE_CANT_DO_THIS;
1331
Tejun Heo2d921722010-12-08 20:57:38 +01001332 if (cdi->ops->check_events)
1333 cdi->ops->check_events(cdi, 0, slot);
1334 else
1335 cdi->ops->media_changed(cdi, slot);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001336
1337 if (slot == CDSL_NONE) {
1338 /* set media changed bits, on both queues */
1339 cdi->mc_flags = 0x3;
1340 return cdrom_load_unload(cdi, -1);
1341 }
1342
1343 info = kmalloc(sizeof(*info), GFP_KERNEL);
1344 if (!info)
1345 return -ENOMEM;
1346
1347 if ((ret = cdrom_read_mech_status(cdi, info))) {
1348 kfree(info);
1349 return ret;
1350 }
1351
1352 curslot = info->hdr.curslot;
1353 kfree(info);
1354
Paolo Bonzinicdccaa92012-02-08 20:03:14 +01001355 if (cdi->use_count > 1 || cdi->keeplocked) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001356 if (slot == CDSL_CURRENT) {
1357 return curslot;
1358 } else {
1359 return -EBUSY;
1360 }
1361 }
1362
1363 /* Specifying CDSL_CURRENT will attempt to load the currnet slot,
1364 which is useful if it had been previously unloaded.
1365 Whether it can or not, it returns the current slot.
1366 Similarly, if slot happens to be the current one, we still
1367 try and load it. */
1368 if (slot == CDSL_CURRENT)
1369 slot = curslot;
1370
1371 /* set media changed bits on both queues */
1372 cdi->mc_flags = 0x3;
1373 if ((ret = cdrom_load_unload(cdi, slot)))
1374 return ret;
1375
1376 return slot;
1377}
1378
Tejun Heo2d921722010-12-08 20:57:38 +01001379/*
1380 * As cdrom implements an extra ioctl consumer for media changed
1381 * event, it needs to buffer ->check_events() output, such that event
1382 * is not lost for both the usual VFS and ioctl paths.
1383 * cdi->{vfs|ioctl}_events are used to buffer pending events for each
1384 * path.
1385 *
1386 * XXX: Locking is non-existent. cdi->ops->check_events() can be
1387 * called in parallel and buffering fields are accessed without any
1388 * exclusion. The original media_changed code had the same problem.
1389 * It might be better to simply deprecate CDROM_MEDIA_CHANGED ioctl
1390 * and remove this cruft altogether. It doesn't have much usefulness
1391 * at this point.
1392 */
1393static void cdrom_update_events(struct cdrom_device_info *cdi,
1394 unsigned int clearing)
1395{
1396 unsigned int events;
1397
1398 events = cdi->ops->check_events(cdi, clearing, CDSL_CURRENT);
1399 cdi->vfs_events |= events;
1400 cdi->ioctl_events |= events;
1401}
1402
1403unsigned int cdrom_check_events(struct cdrom_device_info *cdi,
1404 unsigned int clearing)
1405{
1406 unsigned int events;
1407
1408 cdrom_update_events(cdi, clearing);
1409 events = cdi->vfs_events;
1410 cdi->vfs_events = 0;
1411 return events;
1412}
Jens Axboe30a7caa2010-12-16 17:58:50 +01001413EXPORT_SYMBOL(cdrom_check_events);
Tejun Heo2d921722010-12-08 20:57:38 +01001414
Linus Torvalds1da177e2005-04-16 15:20:36 -07001415/* We want to make media_changed accessible to the user through an
1416 * ioctl. The main problem now is that we must double-buffer the
1417 * low-level implementation, to assure that the VFS and the user both
1418 * see a medium change once.
1419 */
1420
1421static
1422int media_changed(struct cdrom_device_info *cdi, int queue)
1423{
1424 unsigned int mask = (1 << (queue & 1));
1425 int ret = !!(cdi->mc_flags & mask);
Tejun Heo2d921722010-12-08 20:57:38 +01001426 bool changed;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001427
1428 if (!CDROM_CAN(CDC_MEDIA_CHANGED))
Tejun Heo2d921722010-12-08 20:57:38 +01001429 return ret;
1430
Linus Torvalds1da177e2005-04-16 15:20:36 -07001431 /* changed since last call? */
Tejun Heo2d921722010-12-08 20:57:38 +01001432 if (cdi->ops->check_events) {
1433 BUG_ON(!queue); /* shouldn't be called from VFS path */
1434 cdrom_update_events(cdi, DISK_EVENT_MEDIA_CHANGE);
1435 changed = cdi->ioctl_events & DISK_EVENT_MEDIA_CHANGE;
1436 cdi->ioctl_events = 0;
1437 } else
1438 changed = cdi->ops->media_changed(cdi, CDSL_CURRENT);
1439
1440 if (changed) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001441 cdi->mc_flags = 0x3; /* set bit on both queues */
1442 ret |= 1;
1443 cdi->media_written = 0;
1444 }
Tejun Heo2d921722010-12-08 20:57:38 +01001445
Linus Torvalds1da177e2005-04-16 15:20:36 -07001446 cdi->mc_flags &= ~mask; /* clear bit */
1447 return ret;
1448}
1449
1450int cdrom_media_changed(struct cdrom_device_info *cdi)
1451{
1452 /* This talks to the VFS, which doesn't like errors - just 1 or 0.
1453 * Returning "0" is always safe (media hasn't been changed). Do that
1454 * if the low-level cdrom driver dosn't support media changed. */
1455 if (cdi == NULL || cdi->ops->media_changed == NULL)
1456 return 0;
1457 if (!CDROM_CAN(CDC_MEDIA_CHANGED))
1458 return 0;
1459 return media_changed(cdi, 0);
1460}
1461
1462/* badly broken, I know. Is due for a fixup anytime. */
1463static void cdrom_count_tracks(struct cdrom_device_info *cdi, tracktype* tracks)
1464{
1465 struct cdrom_tochdr header;
1466 struct cdrom_tocentry entry;
1467 int ret, i;
1468 tracks->data=0;
1469 tracks->audio=0;
1470 tracks->cdi=0;
1471 tracks->xa=0;
1472 tracks->error=0;
Joe Perches5944b2c2014-05-04 17:05:02 -07001473 cd_dbg(CD_COUNT_TRACKS, "entering cdrom_count_tracks\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001474 /* Grab the TOC header so we can see how many tracks there are */
1475 if ((ret = cdi->ops->audio_ioctl(cdi, CDROMREADTOCHDR, &header))) {
1476 if (ret == -ENOMEDIUM)
1477 tracks->error = CDS_NO_DISC;
1478 else
1479 tracks->error = CDS_NO_INFO;
1480 return;
1481 }
1482 /* check what type of tracks are on this disc */
1483 entry.cdte_format = CDROM_MSF;
1484 for (i = header.cdth_trk0; i <= header.cdth_trk1; i++) {
1485 entry.cdte_track = i;
1486 if (cdi->ops->audio_ioctl(cdi, CDROMREADTOCENTRY, &entry)) {
1487 tracks->error=CDS_NO_INFO;
1488 return;
1489 }
1490 if (entry.cdte_ctrl & CDROM_DATA_TRACK) {
1491 if (entry.cdte_format == 0x10)
1492 tracks->cdi++;
1493 else if (entry.cdte_format == 0x20)
1494 tracks->xa++;
1495 else
1496 tracks->data++;
1497 } else
1498 tracks->audio++;
Joe Perches5944b2c2014-05-04 17:05:02 -07001499 cd_dbg(CD_COUNT_TRACKS, "track %d: format=%d, ctrl=%d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001500 i, entry.cdte_format, entry.cdte_ctrl);
1501 }
Joe Perches5944b2c2014-05-04 17:05:02 -07001502 cd_dbg(CD_COUNT_TRACKS, "disc has %d tracks: %d=audio %d=data %d=Cd-I %d=XA\n",
1503 header.cdth_trk1, tracks->audio, tracks->data,
1504 tracks->cdi, tracks->xa);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001505}
1506
1507/* Requests to the low-level drivers will /always/ be done in the
1508 following format convention:
1509
1510 CDROM_LBA: all data-related requests.
1511 CDROM_MSF: all audio-related requests.
1512
1513 However, a low-level implementation is allowed to refuse this
1514 request, and return information in its own favorite format.
1515
1516 It doesn't make sense /at all/ to ask for a play_audio in LBA
1517 format, or ask for multi-session info in MSF format. However, for
1518 backward compatibility these format requests will be satisfied, but
1519 the requests to the low-level drivers will be sanitized in the more
1520 meaningful format indicated above.
1521 */
1522
1523static
1524void sanitize_format(union cdrom_addr *addr,
1525 u_char * curr, u_char requested)
1526{
1527 if (*curr == requested)
1528 return; /* nothing to be done! */
1529 if (requested == CDROM_LBA) {
1530 addr->lba = (int) addr->msf.frame +
1531 75 * (addr->msf.second - 2 + 60 * addr->msf.minute);
1532 } else { /* CDROM_MSF */
1533 int lba = addr->lba;
1534 addr->msf.frame = lba % 75;
1535 lba /= 75;
1536 lba += 2;
1537 addr->msf.second = lba % 60;
1538 addr->msf.minute = lba / 60;
1539 }
1540 *curr = requested;
1541}
1542
1543void init_cdrom_command(struct packet_command *cgc, void *buf, int len,
1544 int type)
1545{
1546 memset(cgc, 0, sizeof(struct packet_command));
1547 if (buf)
1548 memset(buf, 0, len);
1549 cgc->buffer = (char *) buf;
1550 cgc->buflen = len;
1551 cgc->data_direction = type;
Jens Axboe2e11c202007-01-03 08:10:35 +01001552 cgc->timeout = CDROM_DEF_TIMEOUT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001553}
1554
1555/* DVD handling */
1556
1557#define copy_key(dest,src) memcpy((dest), (src), sizeof(dvd_key))
1558#define copy_chal(dest,src) memcpy((dest), (src), sizeof(dvd_challenge))
1559
1560static void setup_report_key(struct packet_command *cgc, unsigned agid, unsigned type)
1561{
1562 cgc->cmd[0] = GPCMD_REPORT_KEY;
1563 cgc->cmd[10] = type | (agid << 6);
1564 switch (type) {
1565 case 0: case 8: case 5: {
1566 cgc->buflen = 8;
1567 break;
1568 }
1569 case 1: {
1570 cgc->buflen = 16;
1571 break;
1572 }
1573 case 2: case 4: {
1574 cgc->buflen = 12;
1575 break;
1576 }
1577 }
1578 cgc->cmd[9] = cgc->buflen;
1579 cgc->data_direction = CGC_DATA_READ;
1580}
1581
1582static void setup_send_key(struct packet_command *cgc, unsigned agid, unsigned type)
1583{
1584 cgc->cmd[0] = GPCMD_SEND_KEY;
1585 cgc->cmd[10] = type | (agid << 6);
1586 switch (type) {
1587 case 1: {
1588 cgc->buflen = 16;
1589 break;
1590 }
1591 case 3: {
1592 cgc->buflen = 12;
1593 break;
1594 }
1595 case 6: {
1596 cgc->buflen = 8;
1597 break;
1598 }
1599 }
1600 cgc->cmd[9] = cgc->buflen;
1601 cgc->data_direction = CGC_DATA_WRITE;
1602}
1603
1604static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai)
1605{
1606 int ret;
FUJITA Tomonorifce53842008-07-04 09:33:01 +02001607 u_char buf[20];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001608 struct packet_command cgc;
1609 struct cdrom_device_ops *cdo = cdi->ops;
FUJITA Tomonorifce53842008-07-04 09:33:01 +02001610 rpc_state_t rpc_state;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001611
FUJITA Tomonorifce53842008-07-04 09:33:01 +02001612 memset(buf, 0, sizeof(buf));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001613 init_cdrom_command(&cgc, buf, 0, CGC_DATA_READ);
1614
1615 switch (ai->type) {
1616 /* LU data send */
1617 case DVD_LU_SEND_AGID:
Joe Perches5944b2c2014-05-04 17:05:02 -07001618 cd_dbg(CD_DVD, "entering DVD_LU_SEND_AGID\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001619 cgc.quiet = 1;
1620 setup_report_key(&cgc, ai->lsa.agid, 0);
1621
1622 if ((ret = cdo->generic_packet(cdi, &cgc)))
FUJITA Tomonorifce53842008-07-04 09:33:01 +02001623 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001624
1625 ai->lsa.agid = buf[7] >> 6;
1626 /* Returning data, let host change state */
1627 break;
1628
1629 case DVD_LU_SEND_KEY1:
Joe Perches5944b2c2014-05-04 17:05:02 -07001630 cd_dbg(CD_DVD, "entering DVD_LU_SEND_KEY1\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001631 setup_report_key(&cgc, ai->lsk.agid, 2);
1632
1633 if ((ret = cdo->generic_packet(cdi, &cgc)))
FUJITA Tomonorifce53842008-07-04 09:33:01 +02001634 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001635
1636 copy_key(ai->lsk.key, &buf[4]);
1637 /* Returning data, let host change state */
1638 break;
1639
1640 case DVD_LU_SEND_CHALLENGE:
Joe Perches5944b2c2014-05-04 17:05:02 -07001641 cd_dbg(CD_DVD, "entering DVD_LU_SEND_CHALLENGE\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001642 setup_report_key(&cgc, ai->lsc.agid, 1);
1643
1644 if ((ret = cdo->generic_packet(cdi, &cgc)))
FUJITA Tomonorifce53842008-07-04 09:33:01 +02001645 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001646
1647 copy_chal(ai->lsc.chal, &buf[4]);
1648 /* Returning data, let host change state */
1649 break;
1650
1651 /* Post-auth key */
1652 case DVD_LU_SEND_TITLE_KEY:
Joe Perches5944b2c2014-05-04 17:05:02 -07001653 cd_dbg(CD_DVD, "entering DVD_LU_SEND_TITLE_KEY\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001654 cgc.quiet = 1;
1655 setup_report_key(&cgc, ai->lstk.agid, 4);
1656 cgc.cmd[5] = ai->lstk.lba;
1657 cgc.cmd[4] = ai->lstk.lba >> 8;
1658 cgc.cmd[3] = ai->lstk.lba >> 16;
1659 cgc.cmd[2] = ai->lstk.lba >> 24;
1660
1661 if ((ret = cdo->generic_packet(cdi, &cgc)))
FUJITA Tomonorifce53842008-07-04 09:33:01 +02001662 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001663
1664 ai->lstk.cpm = (buf[4] >> 7) & 1;
1665 ai->lstk.cp_sec = (buf[4] >> 6) & 1;
1666 ai->lstk.cgms = (buf[4] >> 4) & 3;
1667 copy_key(ai->lstk.title_key, &buf[5]);
1668 /* Returning data, let host change state */
1669 break;
1670
1671 case DVD_LU_SEND_ASF:
Joe Perches5944b2c2014-05-04 17:05:02 -07001672 cd_dbg(CD_DVD, "entering DVD_LU_SEND_ASF\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001673 setup_report_key(&cgc, ai->lsasf.agid, 5);
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 ai->lsasf.asf = buf[7] & 1;
1679 break;
1680
1681 /* LU data receive (LU changes state) */
1682 case DVD_HOST_SEND_CHALLENGE:
Joe Perches5944b2c2014-05-04 17:05:02 -07001683 cd_dbg(CD_DVD, "entering DVD_HOST_SEND_CHALLENGE\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001684 setup_send_key(&cgc, ai->hsc.agid, 1);
1685 buf[1] = 0xe;
1686 copy_chal(&buf[4], ai->hsc.chal);
1687
1688 if ((ret = cdo->generic_packet(cdi, &cgc)))
FUJITA Tomonorifce53842008-07-04 09:33:01 +02001689 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001690
1691 ai->type = DVD_LU_SEND_KEY1;
1692 break;
1693
1694 case DVD_HOST_SEND_KEY2:
Joe Perches5944b2c2014-05-04 17:05:02 -07001695 cd_dbg(CD_DVD, "entering DVD_HOST_SEND_KEY2\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001696 setup_send_key(&cgc, ai->hsk.agid, 3);
1697 buf[1] = 0xa;
1698 copy_key(&buf[4], ai->hsk.key);
1699
1700 if ((ret = cdo->generic_packet(cdi, &cgc))) {
1701 ai->type = DVD_AUTH_FAILURE;
FUJITA Tomonorifce53842008-07-04 09:33:01 +02001702 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001703 }
1704 ai->type = DVD_AUTH_ESTABLISHED;
1705 break;
1706
1707 /* Misc */
1708 case DVD_INVALIDATE_AGID:
1709 cgc.quiet = 1;
Joe Perches5944b2c2014-05-04 17:05:02 -07001710 cd_dbg(CD_DVD, "entering DVD_INVALIDATE_AGID\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001711 setup_report_key(&cgc, ai->lsa.agid, 0x3f);
1712 if ((ret = cdo->generic_packet(cdi, &cgc)))
FUJITA Tomonorifce53842008-07-04 09:33:01 +02001713 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001714 break;
1715
1716 /* Get region settings */
1717 case DVD_LU_SEND_RPC_STATE:
Joe Perches5944b2c2014-05-04 17:05:02 -07001718 cd_dbg(CD_DVD, "entering DVD_LU_SEND_RPC_STATE\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001719 setup_report_key(&cgc, 0, 8);
FUJITA Tomonorifce53842008-07-04 09:33:01 +02001720 memset(&rpc_state, 0, sizeof(rpc_state_t));
1721 cgc.buffer = (char *) &rpc_state;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001722
1723 if ((ret = cdo->generic_packet(cdi, &cgc)))
FUJITA Tomonorifce53842008-07-04 09:33:01 +02001724 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001725
FUJITA Tomonorifce53842008-07-04 09:33:01 +02001726 ai->lrpcs.type = rpc_state.type_code;
1727 ai->lrpcs.vra = rpc_state.vra;
1728 ai->lrpcs.ucca = rpc_state.ucca;
1729 ai->lrpcs.region_mask = rpc_state.region_mask;
1730 ai->lrpcs.rpc_scheme = rpc_state.rpc_scheme;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001731 break;
1732
1733 /* Set region settings */
1734 case DVD_HOST_SEND_RPC_STATE:
Joe Perches5944b2c2014-05-04 17:05:02 -07001735 cd_dbg(CD_DVD, "entering DVD_HOST_SEND_RPC_STATE\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001736 setup_send_key(&cgc, 0, 6);
1737 buf[1] = 6;
1738 buf[4] = ai->hrpcs.pdrc;
1739
1740 if ((ret = cdo->generic_packet(cdi, &cgc)))
FUJITA Tomonorifce53842008-07-04 09:33:01 +02001741 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001742 break;
1743
1744 default:
Joe Perches5944b2c2014-05-04 17:05:02 -07001745 cd_dbg(CD_WARNING, "Invalid DVD key ioctl (%d)\n", ai->type);
FUJITA Tomonorifce53842008-07-04 09:33:01 +02001746 return -ENOTTY;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001747 }
FUJITA Tomonorifce53842008-07-04 09:33:01 +02001748
1749 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001750}
1751
Marcin Slusarzd1941392008-11-16 19:06:37 +01001752static int dvd_read_physical(struct cdrom_device_info *cdi, dvd_struct *s,
1753 struct packet_command *cgc)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001754{
FUJITA Tomonorifce53842008-07-04 09:33:01 +02001755 unsigned char buf[21], *base;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001756 struct dvd_layer *layer;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001757 struct cdrom_device_ops *cdo = cdi->ops;
1758 int ret, layer_num = s->physical.layer_num;
1759
1760 if (layer_num >= DVD_LAYERS)
1761 return -EINVAL;
1762
Marcin Slusarzd1941392008-11-16 19:06:37 +01001763 init_cdrom_command(cgc, buf, sizeof(buf), CGC_DATA_READ);
1764 cgc->cmd[0] = GPCMD_READ_DVD_STRUCTURE;
1765 cgc->cmd[6] = layer_num;
1766 cgc->cmd[7] = s->type;
1767 cgc->cmd[9] = cgc->buflen & 0xff;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001768
1769 /*
1770 * refrain from reporting errors on non-existing layers (mainly)
1771 */
Marcin Slusarzd1941392008-11-16 19:06:37 +01001772 cgc->quiet = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001773
Marcin Slusarzd1941392008-11-16 19:06:37 +01001774 ret = cdo->generic_packet(cdi, cgc);
1775 if (ret)
FUJITA Tomonorifce53842008-07-04 09:33:01 +02001776 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001777
1778 base = &buf[4];
1779 layer = &s->physical.layer[layer_num];
1780
1781 /*
1782 * place the data... really ugly, but at least we won't have to
1783 * worry about endianess in userspace.
1784 */
1785 memset(layer, 0, sizeof(*layer));
1786 layer->book_version = base[0] & 0xf;
1787 layer->book_type = base[0] >> 4;
1788 layer->min_rate = base[1] & 0xf;
1789 layer->disc_size = base[1] >> 4;
1790 layer->layer_type = base[2] & 0xf;
1791 layer->track_path = (base[2] >> 4) & 1;
1792 layer->nlayers = (base[2] >> 5) & 3;
1793 layer->track_density = base[3] & 0xf;
1794 layer->linear_density = base[3] >> 4;
1795 layer->start_sector = base[5] << 16 | base[6] << 8 | base[7];
1796 layer->end_sector = base[9] << 16 | base[10] << 8 | base[11];
1797 layer->end_sector_l0 = base[13] << 16 | base[14] << 8 | base[15];
1798 layer->bca = base[16] >> 7;
1799
FUJITA Tomonorifce53842008-07-04 09:33:01 +02001800 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001801}
1802
Marcin Slusarzd1941392008-11-16 19:06:37 +01001803static int dvd_read_copyright(struct cdrom_device_info *cdi, dvd_struct *s,
1804 struct packet_command *cgc)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001805{
1806 int ret;
FUJITA Tomonorifce53842008-07-04 09:33:01 +02001807 u_char buf[8];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001808 struct cdrom_device_ops *cdo = cdi->ops;
1809
Marcin Slusarzd1941392008-11-16 19:06:37 +01001810 init_cdrom_command(cgc, buf, sizeof(buf), CGC_DATA_READ);
1811 cgc->cmd[0] = GPCMD_READ_DVD_STRUCTURE;
1812 cgc->cmd[6] = s->copyright.layer_num;
1813 cgc->cmd[7] = s->type;
1814 cgc->cmd[8] = cgc->buflen >> 8;
1815 cgc->cmd[9] = cgc->buflen & 0xff;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001816
Marcin Slusarzd1941392008-11-16 19:06:37 +01001817 ret = cdo->generic_packet(cdi, cgc);
1818 if (ret)
FUJITA Tomonorifce53842008-07-04 09:33:01 +02001819 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001820
1821 s->copyright.cpst = buf[4];
1822 s->copyright.rmi = buf[5];
1823
FUJITA Tomonorifce53842008-07-04 09:33:01 +02001824 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001825}
1826
Marcin Slusarzd1941392008-11-16 19:06:37 +01001827static int dvd_read_disckey(struct cdrom_device_info *cdi, dvd_struct *s,
1828 struct packet_command *cgc)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001829{
1830 int ret, size;
1831 u_char *buf;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001832 struct cdrom_device_ops *cdo = cdi->ops;
1833
1834 size = sizeof(s->disckey.value) + 4;
1835
Marcin Slusarzd1941392008-11-16 19:06:37 +01001836 buf = kmalloc(size, GFP_KERNEL);
1837 if (!buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001838 return -ENOMEM;
1839
Marcin Slusarzd1941392008-11-16 19:06:37 +01001840 init_cdrom_command(cgc, buf, size, CGC_DATA_READ);
1841 cgc->cmd[0] = GPCMD_READ_DVD_STRUCTURE;
1842 cgc->cmd[7] = s->type;
1843 cgc->cmd[8] = size >> 8;
1844 cgc->cmd[9] = size & 0xff;
1845 cgc->cmd[10] = s->disckey.agid << 6;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001846
Marcin Slusarzd1941392008-11-16 19:06:37 +01001847 ret = cdo->generic_packet(cdi, cgc);
1848 if (!ret)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001849 memcpy(s->disckey.value, &buf[4], sizeof(s->disckey.value));
1850
1851 kfree(buf);
1852 return ret;
1853}
1854
Marcin Slusarzd1941392008-11-16 19:06:37 +01001855static int dvd_read_bca(struct cdrom_device_info *cdi, dvd_struct *s,
1856 struct packet_command *cgc)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001857{
Marcin Slusarzd1941392008-11-16 19:06:37 +01001858 int ret, size = 4 + 188;
1859 u_char *buf;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001860 struct cdrom_device_ops *cdo = cdi->ops;
1861
Marcin Slusarzd1941392008-11-16 19:06:37 +01001862 buf = kmalloc(size, GFP_KERNEL);
1863 if (!buf)
1864 return -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001865
Marcin Slusarzd1941392008-11-16 19:06:37 +01001866 init_cdrom_command(cgc, buf, size, CGC_DATA_READ);
1867 cgc->cmd[0] = GPCMD_READ_DVD_STRUCTURE;
1868 cgc->cmd[7] = s->type;
1869 cgc->cmd[9] = cgc->buflen & 0xff;
1870
1871 ret = cdo->generic_packet(cdi, cgc);
1872 if (ret)
1873 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001874
1875 s->bca.len = buf[0] << 8 | buf[1];
1876 if (s->bca.len < 12 || s->bca.len > 188) {
Joe Perches5944b2c2014-05-04 17:05:02 -07001877 cd_dbg(CD_WARNING, "Received invalid BCA length (%d)\n",
1878 s->bca.len);
Marcin Slusarzd1941392008-11-16 19:06:37 +01001879 ret = -EIO;
1880 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001881 }
1882 memcpy(s->bca.value, &buf[4], s->bca.len);
Marcin Slusarzd1941392008-11-16 19:06:37 +01001883 ret = 0;
1884out:
1885 kfree(buf);
1886 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001887}
1888
Marcin Slusarzd1941392008-11-16 19:06:37 +01001889static int dvd_read_manufact(struct cdrom_device_info *cdi, dvd_struct *s,
1890 struct packet_command *cgc)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001891{
1892 int ret = 0, size;
1893 u_char *buf;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001894 struct cdrom_device_ops *cdo = cdi->ops;
1895
1896 size = sizeof(s->manufact.value) + 4;
1897
Marcin Slusarzd1941392008-11-16 19:06:37 +01001898 buf = kmalloc(size, GFP_KERNEL);
1899 if (!buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001900 return -ENOMEM;
1901
Marcin Slusarzd1941392008-11-16 19:06:37 +01001902 init_cdrom_command(cgc, buf, size, CGC_DATA_READ);
1903 cgc->cmd[0] = GPCMD_READ_DVD_STRUCTURE;
1904 cgc->cmd[7] = s->type;
1905 cgc->cmd[8] = size >> 8;
1906 cgc->cmd[9] = size & 0xff;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001907
Marcin Slusarzd1941392008-11-16 19:06:37 +01001908 ret = cdo->generic_packet(cdi, cgc);
1909 if (ret)
1910 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001911
1912 s->manufact.len = buf[0] << 8 | buf[1];
Andrew Mortonaec9f372011-08-02 12:43:50 +02001913 if (s->manufact.len < 0) {
Joe Perches5944b2c2014-05-04 17:05:02 -07001914 cd_dbg(CD_WARNING, "Received invalid manufacture info length (%d)\n",
1915 s->manufact.len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001916 ret = -EIO;
1917 } else {
Andrew Mortonaec9f372011-08-02 12:43:50 +02001918 if (s->manufact.len > 2048) {
Joe Perches5944b2c2014-05-04 17:05:02 -07001919 cd_dbg(CD_WARNING, "Received invalid manufacture info length (%d): truncating to 2048\n",
1920 s->manufact.len);
Andrew Mortonaec9f372011-08-02 12:43:50 +02001921 s->manufact.len = 2048;
1922 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001923 memcpy(s->manufact.value, &buf[4], s->manufact.len);
1924 }
1925
Marcin Slusarzd1941392008-11-16 19:06:37 +01001926out:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001927 kfree(buf);
1928 return ret;
1929}
1930
Marcin Slusarzd1941392008-11-16 19:06:37 +01001931static int dvd_read_struct(struct cdrom_device_info *cdi, dvd_struct *s,
1932 struct packet_command *cgc)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001933{
1934 switch (s->type) {
1935 case DVD_STRUCT_PHYSICAL:
Marcin Slusarzd1941392008-11-16 19:06:37 +01001936 return dvd_read_physical(cdi, s, cgc);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001937
1938 case DVD_STRUCT_COPYRIGHT:
Marcin Slusarzd1941392008-11-16 19:06:37 +01001939 return dvd_read_copyright(cdi, s, cgc);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001940
1941 case DVD_STRUCT_DISCKEY:
Marcin Slusarzd1941392008-11-16 19:06:37 +01001942 return dvd_read_disckey(cdi, s, cgc);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001943
1944 case DVD_STRUCT_BCA:
Marcin Slusarzd1941392008-11-16 19:06:37 +01001945 return dvd_read_bca(cdi, s, cgc);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001946
1947 case DVD_STRUCT_MANUFACT:
Marcin Slusarzd1941392008-11-16 19:06:37 +01001948 return dvd_read_manufact(cdi, s, cgc);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001949
1950 default:
Joe Perches5944b2c2014-05-04 17:05:02 -07001951 cd_dbg(CD_WARNING, ": Invalid DVD structure read requested (%d)\n",
1952 s->type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001953 return -EINVAL;
1954 }
1955}
1956
1957int cdrom_mode_sense(struct cdrom_device_info *cdi,
1958 struct packet_command *cgc,
1959 int page_code, int page_control)
1960{
1961 struct cdrom_device_ops *cdo = cdi->ops;
1962
1963 memset(cgc->cmd, 0, sizeof(cgc->cmd));
1964
1965 cgc->cmd[0] = GPCMD_MODE_SENSE_10;
1966 cgc->cmd[2] = page_code | (page_control << 6);
1967 cgc->cmd[7] = cgc->buflen >> 8;
1968 cgc->cmd[8] = cgc->buflen & 0xff;
1969 cgc->data_direction = CGC_DATA_READ;
1970 return cdo->generic_packet(cdi, cgc);
1971}
1972
1973int cdrom_mode_select(struct cdrom_device_info *cdi,
1974 struct packet_command *cgc)
1975{
1976 struct cdrom_device_ops *cdo = cdi->ops;
1977
1978 memset(cgc->cmd, 0, sizeof(cgc->cmd));
1979 memset(cgc->buffer, 0, 2);
1980 cgc->cmd[0] = GPCMD_MODE_SELECT_10;
1981 cgc->cmd[1] = 0x10; /* PF */
1982 cgc->cmd[7] = cgc->buflen >> 8;
1983 cgc->cmd[8] = cgc->buflen & 0xff;
1984 cgc->data_direction = CGC_DATA_WRITE;
1985 return cdo->generic_packet(cdi, cgc);
1986}
1987
1988static int cdrom_read_subchannel(struct cdrom_device_info *cdi,
1989 struct cdrom_subchnl *subchnl, int mcn)
1990{
1991 struct cdrom_device_ops *cdo = cdi->ops;
1992 struct packet_command cgc;
FUJITA Tomonorifce53842008-07-04 09:33:01 +02001993 char buffer[32];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001994 int ret;
1995
1996 init_cdrom_command(&cgc, buffer, 16, CGC_DATA_READ);
1997 cgc.cmd[0] = GPCMD_READ_SUBCHANNEL;
1998 cgc.cmd[1] = 2; /* MSF addressing */
1999 cgc.cmd[2] = 0x40; /* request subQ data */
2000 cgc.cmd[3] = mcn ? 2 : 1;
2001 cgc.cmd[8] = 16;
2002
2003 if ((ret = cdo->generic_packet(cdi, &cgc)))
FUJITA Tomonorifce53842008-07-04 09:33:01 +02002004 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002005
2006 subchnl->cdsc_audiostatus = cgc.buffer[1];
2007 subchnl->cdsc_format = CDROM_MSF;
2008 subchnl->cdsc_ctrl = cgc.buffer[5] & 0xf;
2009 subchnl->cdsc_trk = cgc.buffer[6];
2010 subchnl->cdsc_ind = cgc.buffer[7];
2011
2012 subchnl->cdsc_reladdr.msf.minute = cgc.buffer[13];
2013 subchnl->cdsc_reladdr.msf.second = cgc.buffer[14];
2014 subchnl->cdsc_reladdr.msf.frame = cgc.buffer[15];
2015 subchnl->cdsc_absaddr.msf.minute = cgc.buffer[9];
2016 subchnl->cdsc_absaddr.msf.second = cgc.buffer[10];
2017 subchnl->cdsc_absaddr.msf.frame = cgc.buffer[11];
2018
FUJITA Tomonorifce53842008-07-04 09:33:01 +02002019 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002020}
2021
2022/*
2023 * Specific READ_10 interface
2024 */
2025static int cdrom_read_cd(struct cdrom_device_info *cdi,
2026 struct packet_command *cgc, int lba,
2027 int blocksize, int nblocks)
2028{
2029 struct cdrom_device_ops *cdo = cdi->ops;
2030
2031 memset(&cgc->cmd, 0, sizeof(cgc->cmd));
2032 cgc->cmd[0] = GPCMD_READ_10;
2033 cgc->cmd[2] = (lba >> 24) & 0xff;
2034 cgc->cmd[3] = (lba >> 16) & 0xff;
2035 cgc->cmd[4] = (lba >> 8) & 0xff;
2036 cgc->cmd[5] = lba & 0xff;
2037 cgc->cmd[6] = (nblocks >> 16) & 0xff;
2038 cgc->cmd[7] = (nblocks >> 8) & 0xff;
2039 cgc->cmd[8] = nblocks & 0xff;
2040 cgc->buflen = blocksize * nblocks;
2041 return cdo->generic_packet(cdi, cgc);
2042}
2043
2044/* very generic interface for reading the various types of blocks */
2045static int cdrom_read_block(struct cdrom_device_info *cdi,
2046 struct packet_command *cgc,
2047 int lba, int nblocks, int format, int blksize)
2048{
2049 struct cdrom_device_ops *cdo = cdi->ops;
2050
2051 memset(&cgc->cmd, 0, sizeof(cgc->cmd));
2052 cgc->cmd[0] = GPCMD_READ_CD;
2053 /* expected sector size - cdda,mode1,etc. */
2054 cgc->cmd[1] = format << 2;
2055 /* starting address */
2056 cgc->cmd[2] = (lba >> 24) & 0xff;
2057 cgc->cmd[3] = (lba >> 16) & 0xff;
2058 cgc->cmd[4] = (lba >> 8) & 0xff;
2059 cgc->cmd[5] = lba & 0xff;
2060 /* number of blocks */
2061 cgc->cmd[6] = (nblocks >> 16) & 0xff;
2062 cgc->cmd[7] = (nblocks >> 8) & 0xff;
2063 cgc->cmd[8] = nblocks & 0xff;
2064 cgc->buflen = blksize * nblocks;
2065
2066 /* set the header info returned */
2067 switch (blksize) {
2068 case CD_FRAMESIZE_RAW0 : cgc->cmd[9] = 0x58; break;
2069 case CD_FRAMESIZE_RAW1 : cgc->cmd[9] = 0x78; break;
2070 case CD_FRAMESIZE_RAW : cgc->cmd[9] = 0xf8; break;
2071 default : cgc->cmd[9] = 0x10;
2072 }
2073
2074 return cdo->generic_packet(cdi, cgc);
2075}
2076
2077static int cdrom_read_cdda_old(struct cdrom_device_info *cdi, __u8 __user *ubuf,
2078 int lba, int nframes)
2079{
2080 struct packet_command cgc;
2081 int ret = 0;
2082 int nr;
2083
2084 cdi->last_sense = 0;
2085
2086 memset(&cgc, 0, sizeof(cgc));
2087
2088 /*
2089 * start with will ra.nframes size, back down if alloc fails
2090 */
2091 nr = nframes;
2092 do {
2093 cgc.buffer = kmalloc(CD_FRAMESIZE_RAW * nr, GFP_KERNEL);
2094 if (cgc.buffer)
2095 break;
2096
2097 nr >>= 1;
2098 } while (nr);
2099
2100 if (!nr)
2101 return -ENOMEM;
2102
Linus Torvalds1da177e2005-04-16 15:20:36 -07002103 cgc.data_direction = CGC_DATA_READ;
2104 while (nframes > 0) {
2105 if (nr > nframes)
2106 nr = nframes;
2107
2108 ret = cdrom_read_block(cdi, &cgc, lba, nr, 1, CD_FRAMESIZE_RAW);
2109 if (ret)
2110 break;
Dan Carpenter822bfa52012-02-06 10:20:45 +01002111 if (copy_to_user(ubuf, cgc.buffer, CD_FRAMESIZE_RAW * nr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002112 ret = -EFAULT;
2113 break;
2114 }
2115 ubuf += CD_FRAMESIZE_RAW * nr;
2116 nframes -= nr;
2117 lba += nr;
2118 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002119 kfree(cgc.buffer);
2120 return ret;
2121}
2122
2123static int cdrom_read_cdda_bpc(struct cdrom_device_info *cdi, __u8 __user *ubuf,
2124 int lba, int nframes)
2125{
Jens Axboe165125e2007-07-24 09:28:11 +02002126 struct request_queue *q = cdi->disk->queue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002127 struct request *rq;
2128 struct bio *bio;
2129 unsigned int len;
2130 int nr, ret = 0;
2131
2132 if (!q)
2133 return -ENXIO;
2134
2135 cdi->last_sense = 0;
2136
2137 while (nframes) {
2138 nr = nframes;
2139 if (cdi->cdda_method == CDDA_BPC_SINGLE)
2140 nr = 1;
Martin K. Petersenae03bf62009-05-22 17:17:50 -04002141 if (nr * CD_FRAMESIZE_RAW > (queue_max_sectors(q) << 9))
2142 nr = (queue_max_sectors(q) << 9) / CD_FRAMESIZE_RAW;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002143
2144 len = nr * CD_FRAMESIZE_RAW;
2145
Alan D. Brunellefebd7a52008-12-09 15:52:15 +01002146 rq = blk_get_request(q, READ, GFP_KERNEL);
2147 if (!rq) {
2148 ret = -ENOMEM;
Jens Axboedd1cab92005-06-20 14:06:01 +02002149 break;
Alan D. Brunellefebd7a52008-12-09 15:52:15 +01002150 }
2151
2152 ret = blk_rq_map_user(q, rq, NULL, ubuf, len, GFP_KERNEL);
2153 if (ret) {
2154 blk_put_request(rq);
2155 break;
2156 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002157
Linus Torvalds1da177e2005-04-16 15:20:36 -07002158 rq->cmd[0] = GPCMD_READ_CD;
2159 rq->cmd[1] = 1 << 2;
2160 rq->cmd[2] = (lba >> 24) & 0xff;
2161 rq->cmd[3] = (lba >> 16) & 0xff;
2162 rq->cmd[4] = (lba >> 8) & 0xff;
2163 rq->cmd[5] = lba & 0xff;
2164 rq->cmd[6] = (nr >> 16) & 0xff;
2165 rq->cmd[7] = (nr >> 8) & 0xff;
2166 rq->cmd[8] = nr & 0xff;
2167 rq->cmd[9] = 0xf8;
2168
2169 rq->cmd_len = 12;
Jens Axboe4aff5e22006-08-10 08:44:47 +02002170 rq->cmd_type = REQ_TYPE_BLOCK_PC;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002171 rq->timeout = 60 * HZ;
2172 bio = rq->bio;
2173
James Bottomley 994ca9a2005-06-20 14:11:09 +02002174 if (blk_execute_rq(q, cdi->disk, rq, 0)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002175 struct request_sense *s = rq->sense;
2176 ret = -EIO;
2177 cdi->last_sense = s->sense_key;
2178 }
2179
Jens Axboe8e5cfc42006-12-19 11:12:46 +01002180 if (blk_rq_unmap_user(bio))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002181 ret = -EFAULT;
Alan D. Brunellefebd7a52008-12-09 15:52:15 +01002182 blk_put_request(rq);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002183
2184 if (ret)
2185 break;
2186
2187 nframes -= nr;
2188 lba += nr;
2189 ubuf += len;
2190 }
2191
Linus Torvalds1da177e2005-04-16 15:20:36 -07002192 return ret;
2193}
2194
2195static int cdrom_read_cdda(struct cdrom_device_info *cdi, __u8 __user *ubuf,
2196 int lba, int nframes)
2197{
2198 int ret;
2199
2200 if (cdi->cdda_method == CDDA_OLD)
2201 return cdrom_read_cdda_old(cdi, ubuf, lba, nframes);
2202
2203retry:
2204 /*
2205 * for anything else than success and io error, we need to retry
2206 */
2207 ret = cdrom_read_cdda_bpc(cdi, ubuf, lba, nframes);
2208 if (!ret || ret != -EIO)
2209 return ret;
2210
2211 /*
2212 * I've seen drives get sense 4/8/3 udma crc errors on multi
2213 * frame dma, so drop to single frame dma if we need to
2214 */
2215 if (cdi->cdda_method == CDDA_BPC_FULL && nframes > 1) {
Joe Perchese597cd02010-07-01 08:24:32 +02002216 pr_info("dropping to single frame dma\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002217 cdi->cdda_method = CDDA_BPC_SINGLE;
2218 goto retry;
2219 }
2220
2221 /*
2222 * so we have an io error of some sort with multi frame dma. if the
2223 * condition wasn't a hardware error
2224 * problems, not for any error
2225 */
2226 if (cdi->last_sense != 0x04 && cdi->last_sense != 0x0b)
2227 return ret;
2228
Joe Perchese597cd02010-07-01 08:24:32 +02002229 pr_info("dropping to old style cdda (sense=%x)\n", cdi->last_sense);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002230 cdi->cdda_method = CDDA_OLD;
2231 return cdrom_read_cdda_old(cdi, ubuf, lba, nframes);
2232}
2233
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002234static int cdrom_ioctl_multisession(struct cdrom_device_info *cdi,
2235 void __user *argp)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002236{
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002237 struct cdrom_multisession ms_info;
2238 u8 requested_format;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002239 int ret;
2240
Joe Perches5944b2c2014-05-04 17:05:02 -07002241 cd_dbg(CD_DO_IOCTL, "entering CDROMMULTISESSION\n");
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002242
2243 if (!(cdi->ops->capability & CDC_MULTI_SESSION))
2244 return -ENOSYS;
2245
2246 if (copy_from_user(&ms_info, argp, sizeof(ms_info)))
2247 return -EFAULT;
2248
2249 requested_format = ms_info.addr_format;
2250 if (requested_format != CDROM_MSF && requested_format != CDROM_LBA)
2251 return -EINVAL;
2252 ms_info.addr_format = CDROM_LBA;
2253
2254 ret = cdi->ops->get_last_session(cdi, &ms_info);
2255 if (ret)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002256 return ret;
2257
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002258 sanitize_format(&ms_info.addr, &ms_info.addr_format, requested_format);
2259
2260 if (copy_to_user(argp, &ms_info, sizeof(ms_info)))
2261 return -EFAULT;
2262
Joe Perches5944b2c2014-05-04 17:05:02 -07002263 cd_dbg(CD_DO_IOCTL, "CDROMMULTISESSION successful\n");
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002264 return 0;
2265}
2266
2267static int cdrom_ioctl_eject(struct cdrom_device_info *cdi)
2268{
Joe Perches5944b2c2014-05-04 17:05:02 -07002269 cd_dbg(CD_DO_IOCTL, "entering CDROMEJECT\n");
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002270
2271 if (!CDROM_CAN(CDC_OPEN_TRAY))
2272 return -ENOSYS;
Paolo Bonzinicdccaa92012-02-08 20:03:14 +01002273 if (cdi->use_count != 1 || cdi->keeplocked)
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002274 return -EBUSY;
2275 if (CDROM_CAN(CDC_LOCK)) {
2276 int ret = cdi->ops->lock_door(cdi, 0);
2277 if (ret)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002278 return ret;
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002279 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002280
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002281 return cdi->ops->tray_move(cdi, 1);
2282}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002283
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002284static int cdrom_ioctl_closetray(struct cdrom_device_info *cdi)
2285{
Joe Perches5944b2c2014-05-04 17:05:02 -07002286 cd_dbg(CD_DO_IOCTL, "entering CDROMCLOSETRAY\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002287
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002288 if (!CDROM_CAN(CDC_CLOSE_TRAY))
2289 return -ENOSYS;
2290 return cdi->ops->tray_move(cdi, 0);
2291}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002292
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002293static int cdrom_ioctl_eject_sw(struct cdrom_device_info *cdi,
2294 unsigned long arg)
2295{
Joe Perches5944b2c2014-05-04 17:05:02 -07002296 cd_dbg(CD_DO_IOCTL, "entering CDROMEJECT_SW\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002297
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002298 if (!CDROM_CAN(CDC_OPEN_TRAY))
2299 return -ENOSYS;
Paolo Bonzinicdccaa92012-02-08 20:03:14 +01002300 if (cdi->keeplocked)
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002301 return -EBUSY;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002302
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002303 cdi->options &= ~(CDO_AUTO_CLOSE | CDO_AUTO_EJECT);
2304 if (arg)
2305 cdi->options |= CDO_AUTO_CLOSE | CDO_AUTO_EJECT;
2306 return 0;
2307}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002308
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002309static int cdrom_ioctl_media_changed(struct cdrom_device_info *cdi,
2310 unsigned long arg)
2311{
2312 struct cdrom_changer_info *info;
2313 int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002314
Joe Perches5944b2c2014-05-04 17:05:02 -07002315 cd_dbg(CD_DO_IOCTL, "entering CDROM_MEDIA_CHANGED\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002316
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002317 if (!CDROM_CAN(CDC_MEDIA_CHANGED))
2318 return -ENOSYS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002319
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002320 /* cannot select disc or select current disc */
2321 if (!CDROM_CAN(CDC_SELECT_DISC) || arg == CDSL_CURRENT)
2322 return media_changed(cdi, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002323
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002324 if ((unsigned int)arg >= cdi->capacity)
2325 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002326
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002327 info = kmalloc(sizeof(*info), GFP_KERNEL);
2328 if (!info)
2329 return -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002330
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002331 ret = cdrom_read_mech_status(cdi, info);
2332 if (!ret)
2333 ret = info->slots[arg].change;
2334 kfree(info);
2335 return ret;
2336}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002337
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002338static int cdrom_ioctl_set_options(struct cdrom_device_info *cdi,
2339 unsigned long arg)
2340{
Joe Perches5944b2c2014-05-04 17:05:02 -07002341 cd_dbg(CD_DO_IOCTL, "entering CDROM_SET_OPTIONS\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002342
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002343 /*
2344 * Options need to be in sync with capability.
2345 * Too late for that, so we have to check each one separately.
2346 */
2347 switch (arg) {
2348 case CDO_USE_FFLAGS:
2349 case CDO_CHECK_TYPE:
2350 break;
2351 case CDO_LOCK:
Linus Torvalds1da177e2005-04-16 15:20:36 -07002352 if (!CDROM_CAN(CDC_LOCK))
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002353 return -ENOSYS;
2354 break;
2355 case 0:
2356 return cdi->options;
2357 /* default is basically CDO_[AUTO_CLOSE|AUTO_EJECT] */
2358 default:
2359 if (!CDROM_CAN(arg))
2360 return -ENOSYS;
2361 }
2362 cdi->options |= (int) arg;
2363 return cdi->options;
2364}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002365
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002366static int cdrom_ioctl_clear_options(struct cdrom_device_info *cdi,
2367 unsigned long arg)
2368{
Joe Perches5944b2c2014-05-04 17:05:02 -07002369 cd_dbg(CD_DO_IOCTL, "entering CDROM_CLEAR_OPTIONS\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002370
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002371 cdi->options &= ~(int) arg;
2372 return cdi->options;
2373}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002374
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002375static int cdrom_ioctl_select_speed(struct cdrom_device_info *cdi,
2376 unsigned long arg)
2377{
Joe Perches5944b2c2014-05-04 17:05:02 -07002378 cd_dbg(CD_DO_IOCTL, "entering CDROM_SELECT_SPEED\n");
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002379
2380 if (!CDROM_CAN(CDC_SELECT_SPEED))
2381 return -ENOSYS;
2382 return cdi->ops->select_speed(cdi, arg);
2383}
2384
2385static int cdrom_ioctl_select_disc(struct cdrom_device_info *cdi,
2386 unsigned long arg)
2387{
Joe Perches5944b2c2014-05-04 17:05:02 -07002388 cd_dbg(CD_DO_IOCTL, "entering CDROM_SELECT_DISC\n");
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002389
2390 if (!CDROM_CAN(CDC_SELECT_DISC))
2391 return -ENOSYS;
2392
2393 if (arg != CDSL_CURRENT && arg != CDSL_NONE) {
2394 if ((int)arg >= cdi->capacity)
2395 return -EINVAL;
2396 }
2397
2398 /*
2399 * ->select_disc is a hook to allow a driver-specific way of
2400 * seleting disc. However, since there is no equivalent hook for
2401 * cdrom_slot_status this may not actually be useful...
2402 */
2403 if (cdi->ops->select_disc)
2404 return cdi->ops->select_disc(cdi, arg);
2405
Joe Perches5944b2c2014-05-04 17:05:02 -07002406 cd_dbg(CD_CHANGER, "Using generic cdrom_select_disc()\n");
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002407 return cdrom_select_disc(cdi, arg);
2408}
2409
2410static int cdrom_ioctl_reset(struct cdrom_device_info *cdi,
2411 struct block_device *bdev)
2412{
Joe Perches5944b2c2014-05-04 17:05:02 -07002413 cd_dbg(CD_DO_IOCTL, "entering CDROM_RESET\n");
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002414
2415 if (!capable(CAP_SYS_ADMIN))
2416 return -EACCES;
2417 if (!CDROM_CAN(CDC_RESET))
2418 return -ENOSYS;
Peter Zijlstraf98393a2007-05-06 14:49:54 -07002419 invalidate_bdev(bdev);
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002420 return cdi->ops->reset(cdi);
2421}
2422
2423static int cdrom_ioctl_lock_door(struct cdrom_device_info *cdi,
2424 unsigned long arg)
2425{
Joe Perches5944b2c2014-05-04 17:05:02 -07002426 cd_dbg(CD_DO_IOCTL, "%socking door\n", arg ? "L" : "Unl");
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002427
2428 if (!CDROM_CAN(CDC_LOCK))
2429 return -EDRIVE_CANT_DO_THIS;
2430
Paolo Bonzinicdccaa92012-02-08 20:03:14 +01002431 cdi->keeplocked = arg ? 1 : 0;
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002432
2433 /*
2434 * Don't unlock the door on multiple opens by default, but allow
2435 * root to do so.
2436 */
2437 if (cdi->use_count != 1 && !arg && !capable(CAP_SYS_ADMIN))
2438 return -EBUSY;
2439 return cdi->ops->lock_door(cdi, arg);
2440}
2441
2442static int cdrom_ioctl_debug(struct cdrom_device_info *cdi,
2443 unsigned long arg)
2444{
Joe Perches5944b2c2014-05-04 17:05:02 -07002445 cd_dbg(CD_DO_IOCTL, "%sabling debug\n", arg ? "En" : "Dis");
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002446
2447 if (!capable(CAP_SYS_ADMIN))
2448 return -EACCES;
2449 debug = arg ? 1 : 0;
2450 return debug;
2451}
2452
2453static int cdrom_ioctl_get_capability(struct cdrom_device_info *cdi)
2454{
Joe Perches5944b2c2014-05-04 17:05:02 -07002455 cd_dbg(CD_DO_IOCTL, "entering CDROM_GET_CAPABILITY\n");
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002456 return (cdi->ops->capability & ~cdi->mask);
2457}
2458
2459/*
2460 * The following function is implemented, although very few audio
Linus Torvalds1da177e2005-04-16 15:20:36 -07002461 * discs give Universal Product Code information, which should just be
2462 * the Medium Catalog Number on the box. Note, that the way the code
2463 * is written on the CD is /not/ uniform across all discs!
2464 */
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002465static int cdrom_ioctl_get_mcn(struct cdrom_device_info *cdi,
2466 void __user *argp)
2467{
2468 struct cdrom_mcn mcn;
2469 int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002470
Joe Perches5944b2c2014-05-04 17:05:02 -07002471 cd_dbg(CD_DO_IOCTL, "entering CDROM_GET_MCN\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002472
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002473 if (!(cdi->ops->capability & CDC_MCN))
2474 return -ENOSYS;
2475 ret = cdi->ops->get_mcn(cdi, &mcn);
2476 if (ret)
2477 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002478
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002479 if (copy_to_user(argp, &mcn, sizeof(mcn)))
2480 return -EFAULT;
Joe Perches5944b2c2014-05-04 17:05:02 -07002481 cd_dbg(CD_DO_IOCTL, "CDROM_GET_MCN successful\n");
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002482 return 0;
2483}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002484
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002485static int cdrom_ioctl_drive_status(struct cdrom_device_info *cdi,
2486 unsigned long arg)
2487{
Joe Perches5944b2c2014-05-04 17:05:02 -07002488 cd_dbg(CD_DO_IOCTL, "entering CDROM_DRIVE_STATUS\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002489
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002490 if (!(cdi->ops->capability & CDC_DRIVE_STATUS))
2491 return -ENOSYS;
2492 if (!CDROM_CAN(CDC_SELECT_DISC) ||
2493 (arg == CDSL_CURRENT || arg == CDSL_NONE))
2494 return cdi->ops->drive_status(cdi, CDSL_CURRENT);
2495 if (((int)arg >= cdi->capacity))
2496 return -EINVAL;
2497 return cdrom_slot_status(cdi, arg);
2498}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002499
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002500/*
2501 * Ok, this is where problems start. The current interface for the
2502 * CDROM_DISC_STATUS ioctl is flawed. It makes the false assumption that
Lucas De Marchi25985ed2011-03-30 22:57:33 -03002503 * CDs are all CDS_DATA_1 or all CDS_AUDIO, etc. Unfortunately, while this
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002504 * is often the case, it is also very common for CDs to have some tracks
2505 * with data, and some tracks with audio. Just because I feel like it,
2506 * I declare the following to be the best way to cope. If the CD has ANY
2507 * data tracks on it, it will be returned as a data CD. If it has any XA
2508 * tracks, I will return it as that. Now I could simplify this interface
2509 * by combining these returns with the above, but this more clearly
2510 * demonstrates the problem with the current interface. Too bad this
2511 * wasn't designed to use bitmasks... -Erik
2512 *
2513 * Well, now we have the option CDS_MIXED: a mixed-type CD.
2514 * User level programmers might feel the ioctl is not very useful.
2515 * ---david
2516 */
2517static int cdrom_ioctl_disc_status(struct cdrom_device_info *cdi)
2518{
2519 tracktype tracks;
2520
Joe Perches5944b2c2014-05-04 17:05:02 -07002521 cd_dbg(CD_DO_IOCTL, "entering CDROM_DISC_STATUS\n");
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002522
2523 cdrom_count_tracks(cdi, &tracks);
2524 if (tracks.error)
2525 return tracks.error;
2526
2527 /* Policy mode on */
2528 if (tracks.audio > 0) {
2529 if (!tracks.data && !tracks.cdi && !tracks.xa)
2530 return CDS_AUDIO;
2531 else
2532 return CDS_MIXED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002533 }
2534
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002535 if (tracks.cdi > 0)
2536 return CDS_XA_2_2;
2537 if (tracks.xa > 0)
2538 return CDS_XA_2_1;
2539 if (tracks.data > 0)
2540 return CDS_DATA_1;
2541 /* Policy mode off */
2542
Joe Perches5944b2c2014-05-04 17:05:02 -07002543 cd_dbg(CD_WARNING, "This disc doesn't have any tracks I recognize!\n");
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002544 return CDS_NO_INFO;
2545}
2546
2547static int cdrom_ioctl_changer_nslots(struct cdrom_device_info *cdi)
2548{
Joe Perches5944b2c2014-05-04 17:05:02 -07002549 cd_dbg(CD_DO_IOCTL, "entering CDROM_CHANGER_NSLOTS\n");
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002550 return cdi->capacity;
2551}
2552
2553static int cdrom_ioctl_get_subchnl(struct cdrom_device_info *cdi,
2554 void __user *argp)
2555{
2556 struct cdrom_subchnl q;
2557 u8 requested, back;
2558 int ret;
2559
Joe Perches5944b2c2014-05-04 17:05:02 -07002560 /* cd_dbg(CD_DO_IOCTL,"entering CDROMSUBCHNL\n");*/
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002561
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002562 if (copy_from_user(&q, argp, sizeof(q)))
2563 return -EFAULT;
2564
2565 requested = q.cdsc_format;
2566 if (requested != CDROM_MSF && requested != CDROM_LBA)
2567 return -EINVAL;
2568 q.cdsc_format = CDROM_MSF;
2569
2570 ret = cdi->ops->audio_ioctl(cdi, CDROMSUBCHNL, &q);
2571 if (ret)
2572 return ret;
2573
2574 back = q.cdsc_format; /* local copy */
2575 sanitize_format(&q.cdsc_absaddr, &back, requested);
2576 sanitize_format(&q.cdsc_reladdr, &q.cdsc_format, requested);
2577
2578 if (copy_to_user(argp, &q, sizeof(q)))
2579 return -EFAULT;
Joe Perches5944b2c2014-05-04 17:05:02 -07002580 /* cd_dbg(CD_DO_IOCTL, "CDROMSUBCHNL successful\n"); */
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002581 return 0;
2582}
2583
2584static int cdrom_ioctl_read_tochdr(struct cdrom_device_info *cdi,
2585 void __user *argp)
2586{
2587 struct cdrom_tochdr header;
2588 int ret;
2589
Joe Perches5944b2c2014-05-04 17:05:02 -07002590 /* cd_dbg(CD_DO_IOCTL, "entering CDROMREADTOCHDR\n"); */
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002591
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002592 if (copy_from_user(&header, argp, sizeof(header)))
2593 return -EFAULT;
2594
2595 ret = cdi->ops->audio_ioctl(cdi, CDROMREADTOCHDR, &header);
2596 if (ret)
2597 return ret;
2598
2599 if (copy_to_user(argp, &header, sizeof(header)))
2600 return -EFAULT;
Joe Perches5944b2c2014-05-04 17:05:02 -07002601 /* cd_dbg(CD_DO_IOCTL, "CDROMREADTOCHDR successful\n"); */
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002602 return 0;
2603}
2604
2605static int cdrom_ioctl_read_tocentry(struct cdrom_device_info *cdi,
2606 void __user *argp)
2607{
2608 struct cdrom_tocentry entry;
2609 u8 requested_format;
2610 int ret;
2611
Joe Perches5944b2c2014-05-04 17:05:02 -07002612 /* cd_dbg(CD_DO_IOCTL, "entering CDROMREADTOCENTRY\n"); */
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002613
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002614 if (copy_from_user(&entry, argp, sizeof(entry)))
2615 return -EFAULT;
2616
2617 requested_format = entry.cdte_format;
2618 if (requested_format != CDROM_MSF && requested_format != CDROM_LBA)
2619 return -EINVAL;
2620 /* make interface to low-level uniform */
2621 entry.cdte_format = CDROM_MSF;
2622 ret = cdi->ops->audio_ioctl(cdi, CDROMREADTOCENTRY, &entry);
2623 if (ret)
2624 return ret;
2625 sanitize_format(&entry.cdte_addr, &entry.cdte_format, requested_format);
2626
2627 if (copy_to_user(argp, &entry, sizeof(entry)))
2628 return -EFAULT;
Joe Perches5944b2c2014-05-04 17:05:02 -07002629 /* cd_dbg(CD_DO_IOCTL, "CDROMREADTOCENTRY successful\n"); */
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002630 return 0;
2631}
2632
2633static int cdrom_ioctl_play_msf(struct cdrom_device_info *cdi,
2634 void __user *argp)
2635{
2636 struct cdrom_msf msf;
2637
Joe Perches5944b2c2014-05-04 17:05:02 -07002638 cd_dbg(CD_DO_IOCTL, "entering CDROMPLAYMSF\n");
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002639
2640 if (!CDROM_CAN(CDC_PLAY_AUDIO))
2641 return -ENOSYS;
2642 if (copy_from_user(&msf, argp, sizeof(msf)))
2643 return -EFAULT;
2644 return cdi->ops->audio_ioctl(cdi, CDROMPLAYMSF, &msf);
2645}
2646
2647static int cdrom_ioctl_play_trkind(struct cdrom_device_info *cdi,
2648 void __user *argp)
2649{
2650 struct cdrom_ti ti;
2651 int ret;
2652
Joe Perches5944b2c2014-05-04 17:05:02 -07002653 cd_dbg(CD_DO_IOCTL, "entering CDROMPLAYTRKIND\n");
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002654
2655 if (!CDROM_CAN(CDC_PLAY_AUDIO))
2656 return -ENOSYS;
2657 if (copy_from_user(&ti, argp, sizeof(ti)))
2658 return -EFAULT;
2659
2660 ret = check_for_audio_disc(cdi, cdi->ops);
2661 if (ret)
2662 return ret;
2663 return cdi->ops->audio_ioctl(cdi, CDROMPLAYTRKIND, &ti);
2664}
2665static int cdrom_ioctl_volctrl(struct cdrom_device_info *cdi,
2666 void __user *argp)
2667{
2668 struct cdrom_volctrl volume;
2669
Joe Perches5944b2c2014-05-04 17:05:02 -07002670 cd_dbg(CD_DO_IOCTL, "entering CDROMVOLCTRL\n");
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002671
2672 if (!CDROM_CAN(CDC_PLAY_AUDIO))
2673 return -ENOSYS;
2674 if (copy_from_user(&volume, argp, sizeof(volume)))
2675 return -EFAULT;
2676 return cdi->ops->audio_ioctl(cdi, CDROMVOLCTRL, &volume);
2677}
2678
2679static int cdrom_ioctl_volread(struct cdrom_device_info *cdi,
2680 void __user *argp)
2681{
2682 struct cdrom_volctrl volume;
2683 int ret;
2684
Joe Perches5944b2c2014-05-04 17:05:02 -07002685 cd_dbg(CD_DO_IOCTL, "entering CDROMVOLREAD\n");
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002686
2687 if (!CDROM_CAN(CDC_PLAY_AUDIO))
2688 return -ENOSYS;
2689
2690 ret = cdi->ops->audio_ioctl(cdi, CDROMVOLREAD, &volume);
2691 if (ret)
2692 return ret;
2693
2694 if (copy_to_user(argp, &volume, sizeof(volume)))
2695 return -EFAULT;
2696 return 0;
2697}
2698
2699static int cdrom_ioctl_audioctl(struct cdrom_device_info *cdi,
2700 unsigned int cmd)
2701{
2702 int ret;
2703
Joe Perches5944b2c2014-05-04 17:05:02 -07002704 cd_dbg(CD_DO_IOCTL, "doing audio ioctl (start/stop/pause/resume)\n");
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08002705
2706 if (!CDROM_CAN(CDC_PLAY_AUDIO))
2707 return -ENOSYS;
2708 ret = check_for_audio_disc(cdi, cdi->ops);
2709 if (ret)
2710 return ret;
2711 return cdi->ops->audio_ioctl(cdi, cmd, NULL);
2712}
2713
2714/*
Joe Perches2e9aa082014-05-04 17:05:08 -07002715 * Required when we need to use READ_10 to issue other than 2048 block
2716 * reads
2717 */
2718static int cdrom_switch_blocksize(struct cdrom_device_info *cdi, int size)
2719{
2720 struct cdrom_device_ops *cdo = cdi->ops;
2721 struct packet_command cgc;
2722 struct modesel_head mh;
2723
2724 memset(&mh, 0, sizeof(mh));
2725 mh.block_desc_length = 0x08;
2726 mh.block_length_med = (size >> 8) & 0xff;
2727 mh.block_length_lo = size & 0xff;
2728
2729 memset(&cgc, 0, sizeof(cgc));
2730 cgc.cmd[0] = 0x15;
2731 cgc.cmd[1] = 1 << 4;
2732 cgc.cmd[4] = 12;
2733 cgc.buflen = sizeof(mh);
2734 cgc.buffer = (char *) &mh;
2735 cgc.data_direction = CGC_DATA_WRITE;
2736 mh.block_desc_length = 0x08;
2737 mh.block_length_med = (size >> 8) & 0xff;
2738 mh.block_length_lo = size & 0xff;
2739
2740 return cdo->generic_packet(cdi, &cgc);
2741}
2742
2743static noinline int mmc_ioctl_cdrom_read_data(struct cdrom_device_info *cdi,
2744 void __user *arg,
2745 struct packet_command *cgc,
2746 int cmd)
2747{
2748 struct request_sense sense;
2749 struct cdrom_msf msf;
2750 int blocksize = 0, format = 0, lba;
2751 int ret;
2752
2753 switch (cmd) {
2754 case CDROMREADRAW:
2755 blocksize = CD_FRAMESIZE_RAW;
2756 break;
2757 case CDROMREADMODE1:
2758 blocksize = CD_FRAMESIZE;
2759 format = 2;
2760 break;
2761 case CDROMREADMODE2:
2762 blocksize = CD_FRAMESIZE_RAW0;
2763 break;
2764 }
2765 if (copy_from_user(&msf, (struct cdrom_msf __user *)arg, sizeof(msf)))
2766 return -EFAULT;
2767 lba = msf_to_lba(msf.cdmsf_min0, msf.cdmsf_sec0, msf.cdmsf_frame0);
2768 /* FIXME: we need upper bound checking, too!! */
2769 if (lba < 0)
2770 return -EINVAL;
2771
2772 cgc->buffer = kzalloc(blocksize, GFP_KERNEL);
2773 if (cgc->buffer == NULL)
2774 return -ENOMEM;
2775
2776 memset(&sense, 0, sizeof(sense));
2777 cgc->sense = &sense;
2778 cgc->data_direction = CGC_DATA_READ;
2779 ret = cdrom_read_block(cdi, cgc, lba, 1, format, blocksize);
2780 if (ret && sense.sense_key == 0x05 &&
2781 sense.asc == 0x20 &&
2782 sense.ascq == 0x00) {
2783 /*
2784 * SCSI-II devices are not required to support
2785 * READ_CD, so let's try switching block size
2786 */
2787 /* FIXME: switch back again... */
2788 ret = cdrom_switch_blocksize(cdi, blocksize);
2789 if (ret)
2790 goto out;
2791 cgc->sense = NULL;
2792 ret = cdrom_read_cd(cdi, cgc, lba, blocksize, 1);
2793 ret |= cdrom_switch_blocksize(cdi, blocksize);
2794 }
2795 if (!ret && copy_to_user(arg, cgc->buffer, blocksize))
2796 ret = -EFAULT;
2797out:
2798 kfree(cgc->buffer);
2799 return ret;
2800}
2801
2802static noinline int mmc_ioctl_cdrom_read_audio(struct cdrom_device_info *cdi,
2803 void __user *arg)
2804{
2805 struct cdrom_read_audio ra;
2806 int lba;
2807
2808 if (copy_from_user(&ra, (struct cdrom_read_audio __user *)arg,
2809 sizeof(ra)))
2810 return -EFAULT;
2811
2812 if (ra.addr_format == CDROM_MSF)
2813 lba = msf_to_lba(ra.addr.msf.minute,
2814 ra.addr.msf.second,
2815 ra.addr.msf.frame);
2816 else if (ra.addr_format == CDROM_LBA)
2817 lba = ra.addr.lba;
2818 else
2819 return -EINVAL;
2820
2821 /* FIXME: we need upper bound checking, too!! */
2822 if (lba < 0 || ra.nframes <= 0 || ra.nframes > CD_FRAMES)
2823 return -EINVAL;
2824
2825 return cdrom_read_cdda(cdi, ra.buf, lba, ra.nframes);
2826}
2827
2828static noinline int mmc_ioctl_cdrom_subchannel(struct cdrom_device_info *cdi,
2829 void __user *arg)
2830{
2831 int ret;
2832 struct cdrom_subchnl q;
2833 u_char requested, back;
2834 if (copy_from_user(&q, (struct cdrom_subchnl __user *)arg, sizeof(q)))
2835 return -EFAULT;
2836 requested = q.cdsc_format;
2837 if (!((requested == CDROM_MSF) ||
2838 (requested == CDROM_LBA)))
2839 return -EINVAL;
2840 q.cdsc_format = CDROM_MSF;
2841 ret = cdrom_read_subchannel(cdi, &q, 0);
2842 if (ret)
2843 return ret;
2844 back = q.cdsc_format; /* local copy */
2845 sanitize_format(&q.cdsc_absaddr, &back, requested);
2846 sanitize_format(&q.cdsc_reladdr, &q.cdsc_format, requested);
2847 if (copy_to_user((struct cdrom_subchnl __user *)arg, &q, sizeof(q)))
2848 return -EFAULT;
2849 /* cd_dbg(CD_DO_IOCTL, "CDROMSUBCHNL successful\n"); */
2850 return 0;
2851}
2852
2853static noinline int mmc_ioctl_cdrom_play_msf(struct cdrom_device_info *cdi,
2854 void __user *arg,
2855 struct packet_command *cgc)
2856{
2857 struct cdrom_device_ops *cdo = cdi->ops;
2858 struct cdrom_msf msf;
2859 cd_dbg(CD_DO_IOCTL, "entering CDROMPLAYMSF\n");
2860 if (copy_from_user(&msf, (struct cdrom_msf __user *)arg, sizeof(msf)))
2861 return -EFAULT;
2862 cgc->cmd[0] = GPCMD_PLAY_AUDIO_MSF;
2863 cgc->cmd[3] = msf.cdmsf_min0;
2864 cgc->cmd[4] = msf.cdmsf_sec0;
2865 cgc->cmd[5] = msf.cdmsf_frame0;
2866 cgc->cmd[6] = msf.cdmsf_min1;
2867 cgc->cmd[7] = msf.cdmsf_sec1;
2868 cgc->cmd[8] = msf.cdmsf_frame1;
2869 cgc->data_direction = CGC_DATA_NONE;
2870 return cdo->generic_packet(cdi, cgc);
2871}
2872
2873static noinline int mmc_ioctl_cdrom_play_blk(struct cdrom_device_info *cdi,
2874 void __user *arg,
2875 struct packet_command *cgc)
2876{
2877 struct cdrom_device_ops *cdo = cdi->ops;
2878 struct cdrom_blk blk;
2879 cd_dbg(CD_DO_IOCTL, "entering CDROMPLAYBLK\n");
2880 if (copy_from_user(&blk, (struct cdrom_blk __user *)arg, sizeof(blk)))
2881 return -EFAULT;
2882 cgc->cmd[0] = GPCMD_PLAY_AUDIO_10;
2883 cgc->cmd[2] = (blk.from >> 24) & 0xff;
2884 cgc->cmd[3] = (blk.from >> 16) & 0xff;
2885 cgc->cmd[4] = (blk.from >> 8) & 0xff;
2886 cgc->cmd[5] = blk.from & 0xff;
2887 cgc->cmd[7] = (blk.len >> 8) & 0xff;
2888 cgc->cmd[8] = blk.len & 0xff;
2889 cgc->data_direction = CGC_DATA_NONE;
2890 return cdo->generic_packet(cdi, cgc);
2891}
2892
2893static noinline int mmc_ioctl_cdrom_volume(struct cdrom_device_info *cdi,
2894 void __user *arg,
2895 struct packet_command *cgc,
2896 unsigned int cmd)
2897{
2898 struct cdrom_volctrl volctrl;
2899 unsigned char buffer[32];
2900 char mask[sizeof(buffer)];
2901 unsigned short offset;
2902 int ret;
2903
2904 cd_dbg(CD_DO_IOCTL, "entering CDROMVOLUME\n");
2905
2906 if (copy_from_user(&volctrl, (struct cdrom_volctrl __user *)arg,
2907 sizeof(volctrl)))
2908 return -EFAULT;
2909
2910 cgc->buffer = buffer;
2911 cgc->buflen = 24;
2912 ret = cdrom_mode_sense(cdi, cgc, GPMODE_AUDIO_CTL_PAGE, 0);
2913 if (ret)
2914 return ret;
2915
2916 /* originally the code depended on buffer[1] to determine
2917 how much data is available for transfer. buffer[1] is
2918 unfortunately ambigious and the only reliable way seem
2919 to be to simply skip over the block descriptor... */
2920 offset = 8 + be16_to_cpu(*(__be16 *)(buffer + 6));
2921
2922 if (offset + 16 > sizeof(buffer))
2923 return -E2BIG;
2924
2925 if (offset + 16 > cgc->buflen) {
2926 cgc->buflen = offset + 16;
2927 ret = cdrom_mode_sense(cdi, cgc,
2928 GPMODE_AUDIO_CTL_PAGE, 0);
2929 if (ret)
2930 return ret;
2931 }
2932
2933 /* sanity check */
2934 if ((buffer[offset] & 0x3f) != GPMODE_AUDIO_CTL_PAGE ||
2935 buffer[offset + 1] < 14)
2936 return -EINVAL;
2937
2938 /* now we have the current volume settings. if it was only
2939 a CDROMVOLREAD, return these values */
2940 if (cmd == CDROMVOLREAD) {
2941 volctrl.channel0 = buffer[offset+9];
2942 volctrl.channel1 = buffer[offset+11];
2943 volctrl.channel2 = buffer[offset+13];
2944 volctrl.channel3 = buffer[offset+15];
2945 if (copy_to_user((struct cdrom_volctrl __user *)arg, &volctrl,
2946 sizeof(volctrl)))
2947 return -EFAULT;
2948 return 0;
2949 }
2950
2951 /* get the volume mask */
2952 cgc->buffer = mask;
2953 ret = cdrom_mode_sense(cdi, cgc, GPMODE_AUDIO_CTL_PAGE, 1);
2954 if (ret)
2955 return ret;
2956
2957 buffer[offset + 9] = volctrl.channel0 & mask[offset + 9];
2958 buffer[offset + 11] = volctrl.channel1 & mask[offset + 11];
2959 buffer[offset + 13] = volctrl.channel2 & mask[offset + 13];
2960 buffer[offset + 15] = volctrl.channel3 & mask[offset + 15];
2961
2962 /* set volume */
2963 cgc->buffer = buffer + offset - 8;
2964 memset(cgc->buffer, 0, 8);
2965 return cdrom_mode_select(cdi, cgc);
2966}
2967
2968static noinline int mmc_ioctl_cdrom_start_stop(struct cdrom_device_info *cdi,
2969 struct packet_command *cgc,
2970 int cmd)
2971{
2972 struct cdrom_device_ops *cdo = cdi->ops;
2973 cd_dbg(CD_DO_IOCTL, "entering CDROMSTART/CDROMSTOP\n");
2974 cgc->cmd[0] = GPCMD_START_STOP_UNIT;
2975 cgc->cmd[1] = 1;
2976 cgc->cmd[4] = (cmd == CDROMSTART) ? 1 : 0;
2977 cgc->data_direction = CGC_DATA_NONE;
2978 return cdo->generic_packet(cdi, cgc);
2979}
2980
2981static noinline int mmc_ioctl_cdrom_pause_resume(struct cdrom_device_info *cdi,
2982 struct packet_command *cgc,
2983 int cmd)
2984{
2985 struct cdrom_device_ops *cdo = cdi->ops;
2986 cd_dbg(CD_DO_IOCTL, "entering CDROMPAUSE/CDROMRESUME\n");
2987 cgc->cmd[0] = GPCMD_PAUSE_RESUME;
2988 cgc->cmd[8] = (cmd == CDROMRESUME) ? 1 : 0;
2989 cgc->data_direction = CGC_DATA_NONE;
2990 return cdo->generic_packet(cdi, cgc);
2991}
2992
2993static noinline int mmc_ioctl_dvd_read_struct(struct cdrom_device_info *cdi,
2994 void __user *arg,
2995 struct packet_command *cgc)
2996{
2997 int ret;
2998 dvd_struct *s;
2999 int size = sizeof(dvd_struct);
3000
3001 if (!CDROM_CAN(CDC_DVD))
3002 return -ENOSYS;
3003
3004 s = kmalloc(size, GFP_KERNEL);
3005 if (!s)
3006 return -ENOMEM;
3007
3008 cd_dbg(CD_DO_IOCTL, "entering DVD_READ_STRUCT\n");
3009 if (copy_from_user(s, arg, size)) {
3010 kfree(s);
3011 return -EFAULT;
3012 }
3013
3014 ret = dvd_read_struct(cdi, s, cgc);
3015 if (ret)
3016 goto out;
3017
3018 if (copy_to_user(arg, s, size))
3019 ret = -EFAULT;
3020out:
3021 kfree(s);
3022 return ret;
3023}
3024
3025static noinline int mmc_ioctl_dvd_auth(struct cdrom_device_info *cdi,
3026 void __user *arg)
3027{
3028 int ret;
3029 dvd_authinfo ai;
3030 if (!CDROM_CAN(CDC_DVD))
3031 return -ENOSYS;
3032 cd_dbg(CD_DO_IOCTL, "entering DVD_AUTH\n");
3033 if (copy_from_user(&ai, (dvd_authinfo __user *)arg, sizeof(ai)))
3034 return -EFAULT;
3035 ret = dvd_do_auth(cdi, &ai);
3036 if (ret)
3037 return ret;
3038 if (copy_to_user((dvd_authinfo __user *)arg, &ai, sizeof(ai)))
3039 return -EFAULT;
3040 return 0;
3041}
3042
3043static noinline int mmc_ioctl_cdrom_next_writable(struct cdrom_device_info *cdi,
3044 void __user *arg)
3045{
3046 int ret;
3047 long next = 0;
3048 cd_dbg(CD_DO_IOCTL, "entering CDROM_NEXT_WRITABLE\n");
3049 ret = cdrom_get_next_writable(cdi, &next);
3050 if (ret)
3051 return ret;
3052 if (copy_to_user((long __user *)arg, &next, sizeof(next)))
3053 return -EFAULT;
3054 return 0;
3055}
3056
3057static noinline int mmc_ioctl_cdrom_last_written(struct cdrom_device_info *cdi,
3058 void __user *arg)
3059{
3060 int ret;
3061 long last = 0;
3062 cd_dbg(CD_DO_IOCTL, "entering CDROM_LAST_WRITTEN\n");
3063 ret = cdrom_get_last_written(cdi, &last);
3064 if (ret)
3065 return ret;
3066 if (copy_to_user((long __user *)arg, &last, sizeof(last)))
3067 return -EFAULT;
3068 return 0;
3069}
3070
3071static int mmc_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
3072 unsigned long arg)
3073{
3074 struct packet_command cgc;
3075 void __user *userptr = (void __user *)arg;
3076
3077 memset(&cgc, 0, sizeof(cgc));
3078
3079 /* build a unified command and queue it through
3080 cdo->generic_packet() */
3081 switch (cmd) {
3082 case CDROMREADRAW:
3083 case CDROMREADMODE1:
3084 case CDROMREADMODE2:
3085 return mmc_ioctl_cdrom_read_data(cdi, userptr, &cgc, cmd);
3086 case CDROMREADAUDIO:
3087 return mmc_ioctl_cdrom_read_audio(cdi, userptr);
3088 case CDROMSUBCHNL:
3089 return mmc_ioctl_cdrom_subchannel(cdi, userptr);
3090 case CDROMPLAYMSF:
3091 return mmc_ioctl_cdrom_play_msf(cdi, userptr, &cgc);
3092 case CDROMPLAYBLK:
3093 return mmc_ioctl_cdrom_play_blk(cdi, userptr, &cgc);
3094 case CDROMVOLCTRL:
3095 case CDROMVOLREAD:
3096 return mmc_ioctl_cdrom_volume(cdi, userptr, &cgc, cmd);
3097 case CDROMSTART:
3098 case CDROMSTOP:
3099 return mmc_ioctl_cdrom_start_stop(cdi, &cgc, cmd);
3100 case CDROMPAUSE:
3101 case CDROMRESUME:
3102 return mmc_ioctl_cdrom_pause_resume(cdi, &cgc, cmd);
3103 case DVD_READ_STRUCT:
3104 return mmc_ioctl_dvd_read_struct(cdi, userptr, &cgc);
3105 case DVD_AUTH:
3106 return mmc_ioctl_dvd_auth(cdi, userptr);
3107 case CDROM_NEXT_WRITABLE:
3108 return mmc_ioctl_cdrom_next_writable(cdi, userptr);
3109 case CDROM_LAST_WRITTEN:
3110 return mmc_ioctl_cdrom_last_written(cdi, userptr);
3111 }
3112
3113 return -ENOTTY;
3114}
3115
3116/*
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08003117 * Just about every imaginable ioctl is supported in the Uniform layer
3118 * these days.
3119 * ATAPI / SCSI specific code now mainly resides in mmc_ioctl().
3120 */
Al Virobbc1cc92007-10-07 17:54:28 -04003121int cdrom_ioctl(struct cdrom_device_info *cdi, struct block_device *bdev,
3122 fmode_t mode, unsigned int cmd, unsigned long arg)
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08003123{
3124 void __user *argp = (void __user *)arg;
3125 int ret;
3126
3127 /*
3128 * Try the generic SCSI command ioctl's first.
3129 */
Paolo Bonzini577ebb32012-01-12 16:01:27 +01003130 ret = scsi_cmd_blk_ioctl(bdev, mode, cmd, argp);
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08003131 if (ret != -ENOTTY)
3132 return ret;
3133
3134 switch (cmd) {
3135 case CDROMMULTISESSION:
3136 return cdrom_ioctl_multisession(cdi, argp);
3137 case CDROMEJECT:
3138 return cdrom_ioctl_eject(cdi);
3139 case CDROMCLOSETRAY:
3140 return cdrom_ioctl_closetray(cdi);
3141 case CDROMEJECT_SW:
3142 return cdrom_ioctl_eject_sw(cdi, arg);
3143 case CDROM_MEDIA_CHANGED:
3144 return cdrom_ioctl_media_changed(cdi, arg);
3145 case CDROM_SET_OPTIONS:
3146 return cdrom_ioctl_set_options(cdi, arg);
3147 case CDROM_CLEAR_OPTIONS:
3148 return cdrom_ioctl_clear_options(cdi, arg);
3149 case CDROM_SELECT_SPEED:
3150 return cdrom_ioctl_select_speed(cdi, arg);
3151 case CDROM_SELECT_DISC:
3152 return cdrom_ioctl_select_disc(cdi, arg);
3153 case CDROMRESET:
Al Virobbc1cc92007-10-07 17:54:28 -04003154 return cdrom_ioctl_reset(cdi, bdev);
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08003155 case CDROM_LOCKDOOR:
3156 return cdrom_ioctl_lock_door(cdi, arg);
3157 case CDROM_DEBUG:
3158 return cdrom_ioctl_debug(cdi, arg);
3159 case CDROM_GET_CAPABILITY:
3160 return cdrom_ioctl_get_capability(cdi);
3161 case CDROM_GET_MCN:
3162 return cdrom_ioctl_get_mcn(cdi, argp);
3163 case CDROM_DRIVE_STATUS:
3164 return cdrom_ioctl_drive_status(cdi, arg);
3165 case CDROM_DISC_STATUS:
3166 return cdrom_ioctl_disc_status(cdi);
3167 case CDROM_CHANGER_NSLOTS:
3168 return cdrom_ioctl_changer_nslots(cdi);
3169 }
3170
3171 /*
3172 * Use the ioctls that are implemented through the generic_packet()
3173 * interface. this may look at bit funny, but if -ENOTTY is
3174 * returned that particular ioctl is not implemented and we
3175 * let it go through the device specific ones.
3176 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003177 if (CDROM_CAN(CDC_GENERIC_PACKET)) {
3178 ret = mmc_ioctl(cdi, cmd, arg);
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08003179 if (ret != -ENOTTY)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003180 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003181 }
3182
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08003183 /*
Joe Perches5944b2c2014-05-04 17:05:02 -07003184 * Note: most of the cd_dbg() calls are commented out here,
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08003185 * because they fill up the sys log when CD players poll
3186 * the drive.
3187 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003188 switch (cmd) {
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08003189 case CDROMSUBCHNL:
3190 return cdrom_ioctl_get_subchnl(cdi, argp);
3191 case CDROMREADTOCHDR:
3192 return cdrom_ioctl_read_tochdr(cdi, argp);
3193 case CDROMREADTOCENTRY:
3194 return cdrom_ioctl_read_tocentry(cdi, argp);
3195 case CDROMPLAYMSF:
3196 return cdrom_ioctl_play_msf(cdi, argp);
3197 case CDROMPLAYTRKIND:
3198 return cdrom_ioctl_play_trkind(cdi, argp);
3199 case CDROMVOLCTRL:
3200 return cdrom_ioctl_volctrl(cdi, argp);
3201 case CDROMVOLREAD:
3202 return cdrom_ioctl_volread(cdi, argp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003203 case CDROMSTART:
3204 case CDROMSTOP:
3205 case CDROMPAUSE:
Christoph Hellwigd2c5d4f2006-03-23 03:00:14 -08003206 case CDROMRESUME:
3207 return cdrom_ioctl_audioctl(cdi, cmd);
3208 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003209
Linus Torvalds1da177e2005-04-16 15:20:36 -07003210 return -ENOSYS;
3211}
3212
Linus Torvalds1da177e2005-04-16 15:20:36 -07003213static int cdrom_get_track_info(struct cdrom_device_info *cdi, __u16 track, __u8 type,
3214 track_information *ti)
3215{
3216 struct cdrom_device_ops *cdo = cdi->ops;
3217 struct packet_command cgc;
3218 int ret, buflen;
3219
3220 init_cdrom_command(&cgc, ti, 8, CGC_DATA_READ);
3221 cgc.cmd[0] = GPCMD_READ_TRACK_RZONE_INFO;
3222 cgc.cmd[1] = type & 3;
3223 cgc.cmd[4] = (track & 0xff00) >> 8;
3224 cgc.cmd[5] = track & 0xff;
3225 cgc.cmd[8] = 8;
3226 cgc.quiet = 1;
3227
3228 if ((ret = cdo->generic_packet(cdi, &cgc)))
3229 return ret;
3230
3231 buflen = be16_to_cpu(ti->track_information_length) +
3232 sizeof(ti->track_information_length);
3233
3234 if (buflen > sizeof(track_information))
3235 buflen = sizeof(track_information);
3236
3237 cgc.cmd[8] = cgc.buflen = buflen;
3238 if ((ret = cdo->generic_packet(cdi, &cgc)))
3239 return ret;
3240
3241 /* return actual fill size */
3242 return buflen;
3243}
3244
3245/* requires CD R/RW */
3246static int cdrom_get_disc_info(struct cdrom_device_info *cdi, disc_information *di)
3247{
3248 struct cdrom_device_ops *cdo = cdi->ops;
3249 struct packet_command cgc;
3250 int ret, buflen;
3251
3252 /* set up command and get the disc info */
3253 init_cdrom_command(&cgc, di, sizeof(*di), CGC_DATA_READ);
3254 cgc.cmd[0] = GPCMD_READ_DISC_INFO;
3255 cgc.cmd[8] = cgc.buflen = 2;
3256 cgc.quiet = 1;
3257
3258 if ((ret = cdo->generic_packet(cdi, &cgc)))
3259 return ret;
3260
3261 /* not all drives have the same disc_info length, so requeue
3262 * packet with the length the drive tells us it can supply
3263 */
3264 buflen = be16_to_cpu(di->disc_information_length) +
3265 sizeof(di->disc_information_length);
3266
3267 if (buflen > sizeof(disc_information))
3268 buflen = sizeof(disc_information);
3269
3270 cgc.cmd[8] = cgc.buflen = buflen;
3271 if ((ret = cdo->generic_packet(cdi, &cgc)))
3272 return ret;
3273
3274 /* return actual fill size */
3275 return buflen;
3276}
3277
3278/* return the last written block on the CD-R media. this is for the udf
3279 file system. */
3280int cdrom_get_last_written(struct cdrom_device_info *cdi, long *last_written)
3281{
3282 struct cdrom_tocentry toc;
3283 disc_information di;
3284 track_information ti;
3285 __u32 last_track;
3286 int ret = -1, ti_size;
3287
3288 if (!CDROM_CAN(CDC_GENERIC_PACKET))
3289 goto use_toc;
3290
3291 ret = cdrom_get_disc_info(cdi, &di);
3292 if (ret < (int)(offsetof(typeof(di), last_track_lsb)
3293 + sizeof(di.last_track_lsb)))
3294 goto use_toc;
3295
3296 /* if unit didn't return msb, it's zeroed by cdrom_get_disc_info */
3297 last_track = (di.last_track_msb << 8) | di.last_track_lsb;
3298 ti_size = cdrom_get_track_info(cdi, last_track, 1, &ti);
3299 if (ti_size < (int)offsetof(typeof(ti), track_start))
3300 goto use_toc;
3301
3302 /* if this track is blank, try the previous. */
3303 if (ti.blank) {
3304 if (last_track==1)
3305 goto use_toc;
3306 last_track--;
3307 ti_size = cdrom_get_track_info(cdi, last_track, 1, &ti);
3308 }
3309
3310 if (ti_size < (int)(offsetof(typeof(ti), track_size)
3311 + sizeof(ti.track_size)))
3312 goto use_toc;
3313
3314 /* if last recorded field is valid, return it. */
3315 if (ti.lra_v && ti_size >= (int)(offsetof(typeof(ti), last_rec_address)
3316 + sizeof(ti.last_rec_address))) {
3317 *last_written = be32_to_cpu(ti.last_rec_address);
3318 } else {
3319 /* make it up instead */
3320 *last_written = be32_to_cpu(ti.track_start) +
3321 be32_to_cpu(ti.track_size);
3322 if (ti.free_blocks)
3323 *last_written -= (be32_to_cpu(ti.free_blocks) + 7);
3324 }
3325 return 0;
3326
3327 /* this is where we end up if the drive either can't do a
3328 GPCMD_READ_DISC_INFO or GPCMD_READ_TRACK_RZONE_INFO or if
3329 it doesn't give enough information or fails. then we return
3330 the toc contents. */
3331use_toc:
3332 toc.cdte_format = CDROM_MSF;
3333 toc.cdte_track = CDROM_LEADOUT;
3334 if ((ret = cdi->ops->audio_ioctl(cdi, CDROMREADTOCENTRY, &toc)))
3335 return ret;
3336 sanitize_format(&toc.cdte_addr, &toc.cdte_format, CDROM_LBA);
3337 *last_written = toc.cdte_addr.lba;
3338 return 0;
3339}
3340
3341/* return the next writable block. also for udf file system. */
3342static int cdrom_get_next_writable(struct cdrom_device_info *cdi, long *next_writable)
3343{
3344 disc_information di;
3345 track_information ti;
3346 __u16 last_track;
3347 int ret, ti_size;
3348
3349 if (!CDROM_CAN(CDC_GENERIC_PACKET))
3350 goto use_last_written;
3351
3352 ret = cdrom_get_disc_info(cdi, &di);
3353 if (ret < 0 || ret < offsetof(typeof(di), last_track_lsb)
3354 + sizeof(di.last_track_lsb))
3355 goto use_last_written;
3356
3357 /* if unit didn't return msb, it's zeroed by cdrom_get_disc_info */
3358 last_track = (di.last_track_msb << 8) | di.last_track_lsb;
3359 ti_size = cdrom_get_track_info(cdi, last_track, 1, &ti);
3360 if (ti_size < 0 || ti_size < offsetof(typeof(ti), track_start))
3361 goto use_last_written;
3362
3363 /* if this track is blank, try the previous. */
3364 if (ti.blank) {
3365 if (last_track == 1)
3366 goto use_last_written;
3367 last_track--;
3368 ti_size = cdrom_get_track_info(cdi, last_track, 1, &ti);
3369 if (ti_size < 0)
3370 goto use_last_written;
3371 }
3372
3373 /* if next recordable address field is valid, use it. */
3374 if (ti.nwa_v && ti_size >= offsetof(typeof(ti), next_writable)
3375 + sizeof(ti.next_writable)) {
3376 *next_writable = be32_to_cpu(ti.next_writable);
3377 return 0;
3378 }
3379
3380use_last_written:
3381 if ((ret = cdrom_get_last_written(cdi, next_writable))) {
3382 *next_writable = 0;
3383 return ret;
3384 } else {
3385 *next_writable += 7;
3386 return 0;
3387 }
3388}
3389
3390EXPORT_SYMBOL(cdrom_get_last_written);
3391EXPORT_SYMBOL(register_cdrom);
3392EXPORT_SYMBOL(unregister_cdrom);
3393EXPORT_SYMBOL(cdrom_open);
3394EXPORT_SYMBOL(cdrom_release);
3395EXPORT_SYMBOL(cdrom_ioctl);
3396EXPORT_SYMBOL(cdrom_media_changed);
3397EXPORT_SYMBOL(cdrom_number_of_slots);
3398EXPORT_SYMBOL(cdrom_mode_select);
3399EXPORT_SYMBOL(cdrom_mode_sense);
3400EXPORT_SYMBOL(init_cdrom_command);
3401EXPORT_SYMBOL(cdrom_get_media_event);
3402
3403#ifdef CONFIG_SYSCTL
3404
3405#define CDROM_STR_SIZE 1000
3406
3407static struct cdrom_sysctl_settings {
3408 char info[CDROM_STR_SIZE]; /* general info */
3409 int autoclose; /* close tray upon mount, etc */
3410 int autoeject; /* eject on umount */
3411 int debug; /* turn on debugging messages */
3412 int lock; /* lock the door on device open */
3413 int check; /* check media type */
3414} cdrom_sysctl_settings;
3415
Dave Young554988d2007-06-19 09:14:26 +02003416enum cdrom_print_option {
3417 CTL_NAME,
3418 CTL_SPEED,
3419 CTL_SLOTS,
3420 CTL_CAPABILITY
3421};
3422
3423static int cdrom_print_info(const char *header, int val, char *info,
3424 int *pos, enum cdrom_print_option option)
3425{
3426 const int max_size = sizeof(cdrom_sysctl_settings.info);
3427 struct cdrom_device_info *cdi;
3428 int ret;
3429
3430 ret = scnprintf(info + *pos, max_size - *pos, header);
3431 if (!ret)
3432 return 1;
3433
3434 *pos += ret;
3435
Akinobu Mita7fd097d2008-03-26 12:09:02 +01003436 list_for_each_entry(cdi, &cdrom_list, list) {
Dave Young554988d2007-06-19 09:14:26 +02003437 switch (option) {
3438 case CTL_NAME:
3439 ret = scnprintf(info + *pos, max_size - *pos,
3440 "\t%s", cdi->name);
3441 break;
3442 case CTL_SPEED:
3443 ret = scnprintf(info + *pos, max_size - *pos,
3444 "\t%d", cdi->speed);
3445 break;
3446 case CTL_SLOTS:
3447 ret = scnprintf(info + *pos, max_size - *pos,
3448 "\t%d", cdi->capacity);
3449 break;
3450 case CTL_CAPABILITY:
3451 ret = scnprintf(info + *pos, max_size - *pos,
3452 "\t%d", CDROM_CAN(val) != 0);
3453 break;
3454 default:
Joe Perchese597cd02010-07-01 08:24:32 +02003455 pr_info("invalid option%d\n", option);
Dave Young554988d2007-06-19 09:14:26 +02003456 return 1;
3457 }
3458 if (!ret)
3459 return 1;
3460 *pos += ret;
3461 }
3462
3463 return 0;
3464}
3465
Alexey Dobriyan8d65af72009-09-23 15:57:19 -07003466static int cdrom_sysctl_info(ctl_table *ctl, int write,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003467 void __user *buffer, size_t *lenp, loff_t *ppos)
3468{
Dave Young554988d2007-06-19 09:14:26 +02003469 int pos;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003470 char *info = cdrom_sysctl_settings.info;
Dave Young554988d2007-06-19 09:14:26 +02003471 const int max_size = sizeof(cdrom_sysctl_settings.info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003472
3473 if (!*lenp || (*ppos && !write)) {
3474 *lenp = 0;
3475 return 0;
3476 }
3477
Dave Young554988d2007-06-19 09:14:26 +02003478 mutex_lock(&cdrom_mutex);
3479
Linus Torvalds1da177e2005-04-16 15:20:36 -07003480 pos = sprintf(info, "CD-ROM information, " VERSION "\n");
3481
Dave Young554988d2007-06-19 09:14:26 +02003482 if (cdrom_print_info("\ndrive name:\t", 0, info, &pos, CTL_NAME))
3483 goto done;
3484 if (cdrom_print_info("\ndrive speed:\t", 0, info, &pos, CTL_SPEED))
3485 goto done;
3486 if (cdrom_print_info("\ndrive # of slots:", 0, info, &pos, CTL_SLOTS))
3487 goto done;
3488 if (cdrom_print_info("\nCan close tray:\t",
3489 CDC_CLOSE_TRAY, info, &pos, CTL_CAPABILITY))
3490 goto done;
3491 if (cdrom_print_info("\nCan open tray:\t",
3492 CDC_OPEN_TRAY, info, &pos, CTL_CAPABILITY))
3493 goto done;
3494 if (cdrom_print_info("\nCan lock tray:\t",
3495 CDC_LOCK, info, &pos, CTL_CAPABILITY))
3496 goto done;
3497 if (cdrom_print_info("\nCan change speed:",
3498 CDC_SELECT_SPEED, info, &pos, CTL_CAPABILITY))
3499 goto done;
3500 if (cdrom_print_info("\nCan select disk:",
3501 CDC_SELECT_DISC, info, &pos, CTL_CAPABILITY))
3502 goto done;
3503 if (cdrom_print_info("\nCan read multisession:",
3504 CDC_MULTI_SESSION, info, &pos, CTL_CAPABILITY))
3505 goto done;
3506 if (cdrom_print_info("\nCan read MCN:\t",
3507 CDC_MCN, info, &pos, CTL_CAPABILITY))
3508 goto done;
3509 if (cdrom_print_info("\nReports media changed:",
3510 CDC_MEDIA_CHANGED, info, &pos, CTL_CAPABILITY))
3511 goto done;
3512 if (cdrom_print_info("\nCan play audio:\t",
3513 CDC_PLAY_AUDIO, info, &pos, CTL_CAPABILITY))
3514 goto done;
3515 if (cdrom_print_info("\nCan write CD-R:\t",
3516 CDC_CD_R, info, &pos, CTL_CAPABILITY))
3517 goto done;
3518 if (cdrom_print_info("\nCan write CD-RW:",
3519 CDC_CD_RW, info, &pos, CTL_CAPABILITY))
3520 goto done;
3521 if (cdrom_print_info("\nCan read DVD:\t",
3522 CDC_DVD, info, &pos, CTL_CAPABILITY))
3523 goto done;
3524 if (cdrom_print_info("\nCan write DVD-R:",
3525 CDC_DVD_R, info, &pos, CTL_CAPABILITY))
3526 goto done;
3527 if (cdrom_print_info("\nCan write DVD-RAM:",
3528 CDC_DVD_RAM, info, &pos, CTL_CAPABILITY))
3529 goto done;
3530 if (cdrom_print_info("\nCan read MRW:\t",
3531 CDC_MRW, info, &pos, CTL_CAPABILITY))
3532 goto done;
3533 if (cdrom_print_info("\nCan write MRW:\t",
3534 CDC_MRW_W, info, &pos, CTL_CAPABILITY))
3535 goto done;
3536 if (cdrom_print_info("\nCan write RAM:\t",
3537 CDC_RAM, info, &pos, CTL_CAPABILITY))
3538 goto done;
3539 if (!scnprintf(info + pos, max_size - pos, "\n\n"))
3540 goto done;
3541doit:
3542 mutex_unlock(&cdrom_mutex);
Alexey Dobriyan8d65af72009-09-23 15:57:19 -07003543 return proc_dostring(ctl, write, buffer, lenp, ppos);
Dave Young554988d2007-06-19 09:14:26 +02003544done:
Joe Perchese597cd02010-07-01 08:24:32 +02003545 pr_info("info buffer too small\n");
Dave Young554988d2007-06-19 09:14:26 +02003546 goto doit;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003547}
3548
3549/* Unfortunately, per device settings are not implemented through
3550 procfs/sysctl yet. When they are, this will naturally disappear. For now
3551 just update all drives. Later this will become the template on which
3552 new registered drives will be based. */
3553static void cdrom_update_settings(void)
3554{
3555 struct cdrom_device_info *cdi;
3556
Akinobu Mita032d8d92008-03-26 12:09:01 +01003557 mutex_lock(&cdrom_mutex);
Akinobu Mita7fd097d2008-03-26 12:09:02 +01003558 list_for_each_entry(cdi, &cdrom_list, list) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003559 if (autoclose && CDROM_CAN(CDC_CLOSE_TRAY))
3560 cdi->options |= CDO_AUTO_CLOSE;
3561 else if (!autoclose)
3562 cdi->options &= ~CDO_AUTO_CLOSE;
3563 if (autoeject && CDROM_CAN(CDC_OPEN_TRAY))
3564 cdi->options |= CDO_AUTO_EJECT;
3565 else if (!autoeject)
3566 cdi->options &= ~CDO_AUTO_EJECT;
3567 if (lockdoor && CDROM_CAN(CDC_LOCK))
3568 cdi->options |= CDO_LOCK;
3569 else if (!lockdoor)
3570 cdi->options &= ~CDO_LOCK;
3571 if (check_media_type)
3572 cdi->options |= CDO_CHECK_TYPE;
3573 else
3574 cdi->options &= ~CDO_CHECK_TYPE;
3575 }
Akinobu Mita032d8d92008-03-26 12:09:01 +01003576 mutex_unlock(&cdrom_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003577}
3578
Alexey Dobriyan8d65af72009-09-23 15:57:19 -07003579static int cdrom_sysctl_handler(ctl_table *ctl, int write,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003580 void __user *buffer, size_t *lenp, loff_t *ppos)
3581{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003582 int ret;
3583
Alexey Dobriyan8d65af72009-09-23 15:57:19 -07003584 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003585
Eric W. Biederman06489b42007-10-18 03:05:28 -07003586 if (write) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003587
3588 /* we only care for 1 or 0. */
Eric W. Biederman06489b42007-10-18 03:05:28 -07003589 autoclose = !!cdrom_sysctl_settings.autoclose;
3590 autoeject = !!cdrom_sysctl_settings.autoeject;
3591 debug = !!cdrom_sysctl_settings.debug;
3592 lockdoor = !!cdrom_sysctl_settings.lock;
3593 check_media_type = !!cdrom_sysctl_settings.check;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003594
Linus Torvalds1da177e2005-04-16 15:20:36 -07003595 /* update the option flags according to the changes. we
3596 don't have per device options through sysctl yet,
3597 but we will have and then this will disappear. */
3598 cdrom_update_settings();
3599 }
3600
3601 return ret;
3602}
3603
3604/* Place files in /proc/sys/dev/cdrom */
3605static ctl_table cdrom_table[] = {
3606 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003607 .procname = "info",
3608 .data = &cdrom_sysctl_settings.info,
3609 .maxlen = CDROM_STR_SIZE,
3610 .mode = 0444,
Eric W. Biederman6d456112009-11-16 03:11:48 -08003611 .proc_handler = cdrom_sysctl_info,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003612 },
3613 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003614 .procname = "autoclose",
3615 .data = &cdrom_sysctl_settings.autoclose,
3616 .maxlen = sizeof(int),
3617 .mode = 0644,
Eric W. Biederman6d456112009-11-16 03:11:48 -08003618 .proc_handler = cdrom_sysctl_handler,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003619 },
3620 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003621 .procname = "autoeject",
3622 .data = &cdrom_sysctl_settings.autoeject,
3623 .maxlen = sizeof(int),
3624 .mode = 0644,
Eric W. Biederman6d456112009-11-16 03:11:48 -08003625 .proc_handler = cdrom_sysctl_handler,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003626 },
3627 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003628 .procname = "debug",
3629 .data = &cdrom_sysctl_settings.debug,
3630 .maxlen = sizeof(int),
3631 .mode = 0644,
Eric W. Biederman6d456112009-11-16 03:11:48 -08003632 .proc_handler = cdrom_sysctl_handler,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003633 },
3634 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003635 .procname = "lock",
3636 .data = &cdrom_sysctl_settings.lock,
3637 .maxlen = sizeof(int),
3638 .mode = 0644,
Eric W. Biederman6d456112009-11-16 03:11:48 -08003639 .proc_handler = cdrom_sysctl_handler,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003640 },
3641 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003642 .procname = "check_media",
3643 .data = &cdrom_sysctl_settings.check,
3644 .maxlen = sizeof(int),
3645 .mode = 0644,
Eric W. Biederman6d456112009-11-16 03:11:48 -08003646 .proc_handler = cdrom_sysctl_handler
Linus Torvalds1da177e2005-04-16 15:20:36 -07003647 },
Eric W. Biederman894d2492009-11-05 14:34:02 -08003648 { }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003649};
3650
3651static ctl_table cdrom_cdrom_table[] = {
3652 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003653 .procname = "cdrom",
3654 .maxlen = 0,
3655 .mode = 0555,
3656 .child = cdrom_table,
3657 },
Eric W. Biederman894d2492009-11-05 14:34:02 -08003658 { }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003659};
3660
3661/* Make sure that /proc/sys/dev is there */
3662static ctl_table cdrom_root_table[] = {
3663 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003664 .procname = "dev",
3665 .maxlen = 0,
3666 .mode = 0555,
3667 .child = cdrom_cdrom_table,
3668 },
Eric W. Biederman894d2492009-11-05 14:34:02 -08003669 { }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003670};
3671static struct ctl_table_header *cdrom_sysctl_header;
3672
3673static void cdrom_sysctl_register(void)
3674{
3675 static int initialized;
3676
3677 if (initialized == 1)
3678 return;
3679
Eric W. Biederman0b4d4142007-02-14 00:34:09 -08003680 cdrom_sysctl_header = register_sysctl_table(cdrom_root_table);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003681
3682 /* set the defaults */
3683 cdrom_sysctl_settings.autoclose = autoclose;
3684 cdrom_sysctl_settings.autoeject = autoeject;
3685 cdrom_sysctl_settings.debug = debug;
3686 cdrom_sysctl_settings.lock = lockdoor;
3687 cdrom_sysctl_settings.check = check_media_type;
3688
3689 initialized = 1;
3690}
3691
3692static void cdrom_sysctl_unregister(void)
3693{
3694 if (cdrom_sysctl_header)
3695 unregister_sysctl_table(cdrom_sysctl_header);
3696}
3697
Akinobu Mita17672cf2008-03-26 12:08:59 +01003698#else /* CONFIG_SYSCTL */
3699
3700static void cdrom_sysctl_register(void)
3701{
3702}
3703
3704static void cdrom_sysctl_unregister(void)
3705{
3706}
3707
Linus Torvalds1da177e2005-04-16 15:20:36 -07003708#endif /* CONFIG_SYSCTL */
3709
3710static int __init cdrom_init(void)
3711{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003712 cdrom_sysctl_register();
Akinobu Mita17672cf2008-03-26 12:08:59 +01003713
Linus Torvalds1da177e2005-04-16 15:20:36 -07003714 return 0;
3715}
3716
3717static void __exit cdrom_exit(void)
3718{
Joe Perchese597cd02010-07-01 08:24:32 +02003719 pr_info("Uniform CD-ROM driver unloaded\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003720 cdrom_sysctl_unregister();
Linus Torvalds1da177e2005-04-16 15:20:36 -07003721}
3722
3723module_init(cdrom_init);
3724module_exit(cdrom_exit);
3725MODULE_LICENSE("GPL");